]> git.proxmox.com Git - grub2.git/commitdiff
automake commit without merge history
authorBVK Chaitanya <bvk.groups@gmail.com>
Thu, 6 May 2010 06:04:04 +0000 (11:34 +0530)
committerBVK Chaitanya <bvk.groups@gmail.com>
Thu, 6 May 2010 06:04:04 +0000 (11:34 +0530)
1569 files changed:
.bzrignore
ABOUT-NLS [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
Makefile.in [deleted file]
autogen.sh
boot/i386/pc/boot.S [deleted file]
boot/i386/pc/cdboot.S [deleted file]
boot/i386/pc/diskboot.S [deleted file]
boot/i386/pc/lnxboot.S [deleted file]
boot/i386/pc/pxeboot.S [deleted file]
boot/i386/qemu/boot.S [deleted file]
boot/sparc64/ieee1275/boot.S [deleted file]
boot/sparc64/ieee1275/diskboot.S [deleted file]
bus/bonito.c [deleted file]
bus/pci.c [deleted file]
bus/usb/ohci.c [deleted file]
bus/usb/uhci.c [deleted file]
bus/usb/usb.c [deleted file]
bus/usb/usbhub.c [deleted file]
bus/usb/usbtrans.c [deleted file]
commands/acpi.c [deleted file]
commands/blocklist.c [deleted file]
commands/boot.c [deleted file]
commands/cat.c [deleted file]
commands/cmp.c [deleted file]
commands/configfile.c [deleted file]
commands/crc.c [deleted file]
commands/date.c [deleted file]
commands/echo.c [deleted file]
commands/efi/acpi.c [deleted file]
commands/efi/fixvideo.c [deleted file]
commands/efi/loadbios.c [deleted file]
commands/extcmd.c [deleted file]
commands/gptsync.c [deleted file]
commands/halt.c [deleted file]
commands/handler.c [deleted file]
commands/hashsum.c [deleted file]
commands/hdparm.c [deleted file]
commands/help.c [deleted file]
commands/hexdump.c [deleted file]
commands/i386/cpuid.c [deleted file]
commands/i386/pc/acpi.c [deleted file]
commands/i386/pc/drivemap.c [deleted file]
commands/i386/pc/drivemap_int13h.S [deleted file]
commands/i386/pc/halt.c [deleted file]
commands/i386/pc/play.c [deleted file]
commands/i386/pc/pxecmd.c [deleted file]
commands/i386/pc/vbeinfo.c [deleted file]
commands/i386/pc/vbetest.c [deleted file]
commands/ieee1275/suspend.c [deleted file]
commands/iorw.c [deleted file]
commands/keystatus.c [deleted file]
commands/loadenv.c [deleted file]
commands/ls.c [deleted file]
commands/lsmmap.c [deleted file]
commands/lspci.c [deleted file]
commands/memrw.c [deleted file]
commands/minicmd.c [deleted file]
commands/parttool.c [deleted file]
commands/password.c [deleted file]
commands/password_pbkdf2.c [deleted file]
commands/probe.c [deleted file]
commands/read.c [deleted file]
commands/reboot.c [deleted file]
commands/regexp.c [deleted file]
commands/search.c [deleted file]
commands/search_file.c [deleted file]
commands/search_label.c [deleted file]
commands/search_uuid.c [deleted file]
commands/search_wrap.c [deleted file]
commands/setpci.c [deleted file]
commands/sleep.c [deleted file]
commands/terminal.c [deleted file]
commands/test.c [deleted file]
commands/true.c [deleted file]
commands/usbtest.c [deleted file]
commands/videotest.c [deleted file]
commands/xnu_uuid.c [deleted file]
conf/any-emu.rmk [deleted file]
conf/common.rmk [deleted file]
conf/i386-coreboot.rmk [deleted file]
conf/i386-efi.rmk [deleted file]
conf/i386-ieee1275.rmk [deleted file]
conf/i386-multiboot.rmk [deleted file]
conf/i386-pc-cygwin-img-ld.sc [deleted file]
conf/i386-pc.rmk [deleted file]
conf/i386-qemu.rmk [deleted file]
conf/i386.rmk [deleted file]
conf/mips-qemu-mips.rmk [deleted file]
conf/mips-yeeloong.rmk [deleted file]
conf/mips.rmk [deleted file]
conf/powerpc-ieee1275.rmk [deleted file]
conf/sparc64-ieee1275.rmk [deleted file]
conf/tests.rmk [deleted file]
conf/x86-efi.rmk [deleted file]
conf/x86_64-efi.rmk [deleted file]
configure.ac
configure.common [new file with mode: 0644]
disk/ata.c [deleted file]
disk/ata_pthru.c [deleted file]
disk/dmraid_nvidia.c [deleted file]
disk/efi/efidisk.c [deleted file]
disk/host.c [deleted file]
disk/i386/pc/biosdisk.c [deleted file]
disk/ieee1275/nand.c [deleted file]
disk/ieee1275/ofdisk.c [deleted file]
disk/loopback.c [deleted file]
disk/lvm.c [deleted file]
disk/mdraid_linux.c [deleted file]
disk/memdisk.c [deleted file]
disk/raid.c [deleted file]
disk/raid5_recover.c [deleted file]
disk/raid6_recover.c [deleted file]
disk/scsi.c [deleted file]
disk/usbms.c [deleted file]
docs/Makefile.am [new file with mode: 0644]
efiemu/i386/coredetect.c [deleted file]
efiemu/i386/loadcore32.c [deleted file]
efiemu/i386/loadcore64.c [deleted file]
efiemu/i386/pc/cfgtables.c [deleted file]
efiemu/loadcore.c [deleted file]
efiemu/loadcore32.c [deleted file]
efiemu/loadcore64.c [deleted file]
efiemu/loadcore_common.c [deleted file]
efiemu/main.c [deleted file]
efiemu/mm.c [deleted file]
efiemu/pnvram.c [deleted file]
efiemu/prepare.c [deleted file]
efiemu/prepare32.c [deleted file]
efiemu/prepare64.c [deleted file]
efiemu/runtime/config.h [deleted file]
efiemu/runtime/efiemu.S [deleted file]
efiemu/runtime/efiemu.c [deleted file]
efiemu/runtime/efiemu.sh [deleted file]
efiemu/symbols.c [deleted file]
font/font.c [deleted file]
font/font_cmd.c [deleted file]
fs/affs.c [deleted file]
fs/afs.c [deleted file]
fs/afs_be.c [deleted file]
fs/befs.c [deleted file]
fs/befs_be.c [deleted file]
fs/cpio.c [deleted file]
fs/ext2.c [deleted file]
fs/fat.c [deleted file]
fs/fshelp.c [deleted file]
fs/hfs.c [deleted file]
fs/hfsplus.c [deleted file]
fs/i386/pc/pxe.c [deleted file]
fs/iso9660.c [deleted file]
fs/jfs.c [deleted file]
fs/minix.c [deleted file]
fs/nilfs2.c [deleted file]
fs/ntfs.c [deleted file]
fs/ntfscomp.c [deleted file]
fs/reiserfs.c [deleted file]
fs/sfs.c [deleted file]
fs/tar.c [deleted file]
fs/udf.c [deleted file]
fs/ufs.c [deleted file]
fs/ufs2.c [deleted file]
fs/xfs.c [deleted file]
gencmdlist.sh [deleted file]
gendistlist.sh [deleted file]
genemuinit.sh [deleted file]
genemuinitheader.sh [deleted file]
genfslist.sh [deleted file]
genhandlerlist.sh [deleted file]
geninit.sh
geninitheader.sh [deleted file]
genkernsyms.sh.in [deleted file]
genmk.rb [deleted file]
genmoddep.awk [deleted file]
genmodsrc.sh [deleted file]
genpartmaplist.sh [deleted file]
genparttoollist.sh [deleted file]
gensymlist.sh.in [deleted file]
genterminallist.sh [deleted file]
gentpl.py [new file with mode: 0644]
gentrigtables.c [deleted file]
genvideolist.sh [deleted file]
gettext/gettext.c [deleted file]
gfxmenu/gfxmenu.c [deleted file]
gfxmenu/gui_box.c [deleted file]
gfxmenu/gui_canvas.c [deleted file]
gfxmenu/gui_circular_progress.c [deleted file]
gfxmenu/gui_image.c [deleted file]
gfxmenu/gui_label.c [deleted file]
gfxmenu/gui_list.c [deleted file]
gfxmenu/gui_progress_bar.c [deleted file]
gfxmenu/gui_string_util.c [deleted file]
gfxmenu/gui_util.c [deleted file]
gfxmenu/icon_manager.c [deleted file]
gfxmenu/model.c [deleted file]
gfxmenu/named_colors.c [deleted file]
gfxmenu/theme_loader.c [deleted file]
gfxmenu/view.c [deleted file]
gfxmenu/widget-box.c [deleted file]
gnulib/alloca.h [deleted file]
gnulib/argp-ba.c [deleted file]
gnulib/argp-eexst.c [deleted file]
gnulib/argp-fmtstream.c [deleted file]
gnulib/argp-fmtstream.h [deleted file]
gnulib/argp-fs-xinl.c [deleted file]
gnulib/argp-help.c [deleted file]
gnulib/argp-namefrob.h [deleted file]
gnulib/argp-parse.c [deleted file]
gnulib/argp-pin.c [deleted file]
gnulib/argp-pv.c [deleted file]
gnulib/argp-pvh.c [deleted file]
gnulib/argp-version-etc.c [deleted file]
gnulib/argp-version-etc.h [deleted file]
gnulib/argp-xinl.c [deleted file]
gnulib/argp.h [deleted file]
gnulib/error.c [deleted file]
gnulib/error.h [deleted file]
gnulib/fnmatch.c [deleted file]
gnulib/fnmatch.h [deleted file]
gnulib/fnmatch_loop.c [deleted file]
gnulib/getdelim.c [deleted file]
gnulib/getline.c [deleted file]
gnulib/getopt.c [deleted file]
gnulib/getopt.h [deleted file]
gnulib/getopt1.c [deleted file]
gnulib/getopt_int.h [deleted file]
gnulib/gettext.h [deleted file]
gnulib/progname.c [deleted file]
gnulib/progname.h [deleted file]
gnulib/regcomp.c [deleted file]
gnulib/regex.c [deleted file]
gnulib/regex.h [deleted file]
gnulib/regex_internal.c [deleted file]
gnulib/regex_internal.h [deleted file]
gnulib/regexec.c [deleted file]
grub-core/Makefile.am [new file with mode: 0644]
grub-core/Makefile.extra-dist [new file with mode: 0644]
grub-core/Makefile.kernel [new file with mode: 0644]
grub-core/Makefile.vars [new file with mode: 0644]
grub-core/boot/i386/pc/boot.S [new file with mode: 0644]
grub-core/boot/i386/pc/cdboot.S [new file with mode: 0644]
grub-core/boot/i386/pc/diskboot.S [new file with mode: 0644]
grub-core/boot/i386/pc/lnxboot.S [new file with mode: 0644]
grub-core/boot/i386/pc/pxeboot.S [new file with mode: 0644]
grub-core/boot/i386/qemu/boot.S [new file with mode: 0644]
grub-core/boot/sparc64/ieee1275/boot.S [new file with mode: 0644]
grub-core/boot/sparc64/ieee1275/diskboot.S [new file with mode: 0644]
grub-core/bus/bonito.c [new file with mode: 0644]
grub-core/bus/emu/pci.c [new file with mode: 0644]
grub-core/bus/pci.c [new file with mode: 0644]
grub-core/bus/usb/emu/usb.c [new file with mode: 0644]
grub-core/bus/usb/ohci.c [new file with mode: 0644]
grub-core/bus/usb/uhci.c [new file with mode: 0644]
grub-core/bus/usb/usb.c [new file with mode: 0644]
grub-core/bus/usb/usbhub.c [new file with mode: 0644]
grub-core/bus/usb/usbtrans.c [new file with mode: 0644]
grub-core/commands/acpi.c [new file with mode: 0644]
grub-core/commands/blocklist.c [new file with mode: 0644]
grub-core/commands/boot.c [new file with mode: 0644]
grub-core/commands/cat.c [new file with mode: 0644]
grub-core/commands/cmp.c [new file with mode: 0644]
grub-core/commands/configfile.c [new file with mode: 0644]
grub-core/commands/crc.c [new file with mode: 0644]
grub-core/commands/date.c [new file with mode: 0644]
grub-core/commands/echo.c [new file with mode: 0644]
grub-core/commands/efi/acpi.c [new file with mode: 0644]
grub-core/commands/efi/fixvideo.c [new file with mode: 0644]
grub-core/commands/efi/loadbios.c [new file with mode: 0644]
grub-core/commands/extcmd.c [new file with mode: 0644]
grub-core/commands/gptsync.c [new file with mode: 0644]
grub-core/commands/halt.c [new file with mode: 0644]
grub-core/commands/handler.c [new file with mode: 0644]
grub-core/commands/hashsum.c [new file with mode: 0644]
grub-core/commands/hdparm.c [new file with mode: 0644]
grub-core/commands/help.c [new file with mode: 0644]
grub-core/commands/hexdump.c [new file with mode: 0644]
grub-core/commands/i386/cpuid.c [new file with mode: 0644]
grub-core/commands/i386/pc/acpi.c [new file with mode: 0644]
grub-core/commands/i386/pc/drivemap.c [new file with mode: 0644]
grub-core/commands/i386/pc/drivemap_int13h.S [new file with mode: 0644]
grub-core/commands/i386/pc/halt.c [new file with mode: 0644]
grub-core/commands/i386/pc/play.c [new file with mode: 0644]
grub-core/commands/i386/pc/pxecmd.c [new file with mode: 0644]
grub-core/commands/i386/pc/vbeinfo.c [new file with mode: 0644]
grub-core/commands/i386/pc/vbetest.c [new file with mode: 0644]
grub-core/commands/ieee1275/suspend.c [new file with mode: 0644]
grub-core/commands/iorw.c [new file with mode: 0644]
grub-core/commands/keystatus.c [new file with mode: 0644]
grub-core/commands/loadenv.c [new file with mode: 0644]
grub-core/commands/ls.c [new file with mode: 0644]
grub-core/commands/lsmmap.c [new file with mode: 0644]
grub-core/commands/lspci.c [new file with mode: 0644]
grub-core/commands/memrw.c [new file with mode: 0644]
grub-core/commands/minicmd.c [new file with mode: 0644]
grub-core/commands/parttool.c [new file with mode: 0644]
grub-core/commands/password.c [new file with mode: 0644]
grub-core/commands/password_pbkdf2.c [new file with mode: 0644]
grub-core/commands/probe.c [new file with mode: 0644]
grub-core/commands/read.c [new file with mode: 0644]
grub-core/commands/reboot.c [new file with mode: 0644]
grub-core/commands/regexp.c [new file with mode: 0644]
grub-core/commands/search.c [new file with mode: 0644]
grub-core/commands/search_file.c [new file with mode: 0644]
grub-core/commands/search_label.c [new file with mode: 0644]
grub-core/commands/search_uuid.c [new file with mode: 0644]
grub-core/commands/search_wrap.c [new file with mode: 0644]
grub-core/commands/setpci.c [new file with mode: 0644]
grub-core/commands/sleep.c [new file with mode: 0644]
grub-core/commands/terminal.c [new file with mode: 0644]
grub-core/commands/test.c [new file with mode: 0644]
grub-core/commands/true.c [new file with mode: 0644]
grub-core/commands/usbtest.c [new file with mode: 0644]
grub-core/commands/videotest.c [new file with mode: 0644]
grub-core/commands/xnu_uuid.c [new file with mode: 0644]
grub-core/conf/any-emu.rmk [new file with mode: 0644]
grub-core/conf/common.rmk [new file with mode: 0644]
grub-core/conf/i386-coreboot.rmk [new file with mode: 0644]
grub-core/conf/i386-efi.rmk [new file with mode: 0644]
grub-core/conf/i386-ieee1275.rmk [new file with mode: 0644]
grub-core/conf/i386-multiboot.rmk [new file with mode: 0644]
grub-core/conf/i386-pc-cygwin-img-ld.sc [new file with mode: 0644]
grub-core/conf/i386-pc.rmk [new file with mode: 0644]
grub-core/conf/i386-qemu.rmk [new file with mode: 0644]
grub-core/conf/i386.rmk [new file with mode: 0644]
grub-core/conf/mips-qemu-mips.rmk [new file with mode: 0644]
grub-core/conf/mips-yeeloong.rmk [new file with mode: 0644]
grub-core/conf/mips.rmk [new file with mode: 0644]
grub-core/conf/powerpc-ieee1275.rmk [new file with mode: 0644]
grub-core/conf/sparc64-ieee1275.rmk [new file with mode: 0644]
grub-core/conf/tests.rmk [new file with mode: 0644]
grub-core/conf/x86-efi.rmk [new file with mode: 0644]
grub-core/conf/x86_64-efi.rmk [new file with mode: 0644]
grub-core/configure.ac [new file with mode: 0644]
grub-core/disk/ata.c [new file with mode: 0644]
grub-core/disk/ata_pthru.c [new file with mode: 0644]
grub-core/disk/dmraid_nvidia.c [new file with mode: 0644]
grub-core/disk/efi/efidisk.c [new file with mode: 0644]
grub-core/disk/host.c [new file with mode: 0644]
grub-core/disk/i386/pc/biosdisk.c [new file with mode: 0644]
grub-core/disk/ieee1275/nand.c [new file with mode: 0644]
grub-core/disk/ieee1275/ofdisk.c [new file with mode: 0644]
grub-core/disk/loopback.c [new file with mode: 0644]
grub-core/disk/lvm.c [new file with mode: 0644]
grub-core/disk/mdraid_linux.c [new file with mode: 0644]
grub-core/disk/memdisk.c [new file with mode: 0644]
grub-core/disk/raid.c [new file with mode: 0644]
grub-core/disk/raid5_recover.c [new file with mode: 0644]
grub-core/disk/raid6_recover.c [new file with mode: 0644]
grub-core/disk/scsi.c [new file with mode: 0644]
grub-core/disk/usbms.c [new file with mode: 0644]
grub-core/efiemu/i386/coredetect.c [new file with mode: 0644]
grub-core/efiemu/i386/loadcore32.c [new file with mode: 0644]
grub-core/efiemu/i386/loadcore64.c [new file with mode: 0644]
grub-core/efiemu/i386/pc/cfgtables.c [new file with mode: 0644]
grub-core/efiemu/loadcore.c [new file with mode: 0644]
grub-core/efiemu/loadcore32.c [new file with mode: 0644]
grub-core/efiemu/loadcore64.c [new file with mode: 0644]
grub-core/efiemu/loadcore_common.c [new file with mode: 0644]
grub-core/efiemu/main.c [new file with mode: 0644]
grub-core/efiemu/mm.c [new file with mode: 0644]
grub-core/efiemu/pnvram.c [new file with mode: 0644]
grub-core/efiemu/prepare.c [new file with mode: 0644]
grub-core/efiemu/prepare32.c [new file with mode: 0644]
grub-core/efiemu/prepare64.c [new file with mode: 0644]
grub-core/efiemu/runtime/config.h [new file with mode: 0644]
grub-core/efiemu/runtime/efiemu.S [new file with mode: 0644]
grub-core/efiemu/runtime/efiemu.c [new file with mode: 0644]
grub-core/efiemu/runtime/efiemu.sh [new file with mode: 0644]
grub-core/efiemu/symbols.c [new file with mode: 0644]
grub-core/font/font.c [new file with mode: 0644]
grub-core/font/font_cmd.c [new file with mode: 0644]
grub-core/fs/affs.c [new file with mode: 0644]
grub-core/fs/afs.c [new file with mode: 0644]
grub-core/fs/afs_be.c [new file with mode: 0644]
grub-core/fs/befs.c [new file with mode: 0644]
grub-core/fs/befs_be.c [new file with mode: 0644]
grub-core/fs/cpio.c [new file with mode: 0644]
grub-core/fs/ext2.c [new file with mode: 0644]
grub-core/fs/fat.c [new file with mode: 0644]
grub-core/fs/fshelp.c [new file with mode: 0644]
grub-core/fs/hfs.c [new file with mode: 0644]
grub-core/fs/hfsplus.c [new file with mode: 0644]
grub-core/fs/i386/pc/pxe.c [new file with mode: 0644]
grub-core/fs/iso9660.c [new file with mode: 0644]
grub-core/fs/jfs.c [new file with mode: 0644]
grub-core/fs/minix.c [new file with mode: 0644]
grub-core/fs/nilfs2.c [new file with mode: 0644]
grub-core/fs/ntfs.c [new file with mode: 0644]
grub-core/fs/ntfscomp.c [new file with mode: 0644]
grub-core/fs/reiserfs.c [new file with mode: 0644]
grub-core/fs/sfs.c [new file with mode: 0644]
grub-core/fs/tar.c [new file with mode: 0644]
grub-core/fs/udf.c [new file with mode: 0644]
grub-core/fs/ufs.c [new file with mode: 0644]
grub-core/fs/ufs2.c [new file with mode: 0644]
grub-core/fs/xfs.c [new file with mode: 0644]
grub-core/gencmdlist.sh [new file with mode: 0644]
grub-core/gendistlist.sh [new file with mode: 0755]
grub-core/genemuinit.sh [new file with mode: 0644]
grub-core/genemuinitheader.sh [new file with mode: 0644]
grub-core/genfslist.sh [new file with mode: 0644]
grub-core/genhandlerlist.sh [new file with mode: 0644]
grub-core/genmoddep.awk [new file with mode: 0644]
grub-core/genmodsrc.sh [new file with mode: 0644]
grub-core/genpartmaplist.sh [new file with mode: 0644]
grub-core/genparttoollist.sh [new file with mode: 0644]
grub-core/gensymlist.sh [new file with mode: 0644]
grub-core/genterminallist.sh [new file with mode: 0644]
grub-core/gentrigtables.c [new file with mode: 0644]
grub-core/genvideolist.sh [new file with mode: 0644]
grub-core/gettext/gettext.c [new file with mode: 0644]
grub-core/gfxmenu/gfxmenu.c [new file with mode: 0644]
grub-core/gfxmenu/gui_box.c [new file with mode: 0644]
grub-core/gfxmenu/gui_canvas.c [new file with mode: 0644]
grub-core/gfxmenu/gui_circular_progress.c [new file with mode: 0644]
grub-core/gfxmenu/gui_image.c [new file with mode: 0644]
grub-core/gfxmenu/gui_label.c [new file with mode: 0644]
grub-core/gfxmenu/gui_list.c [new file with mode: 0644]
grub-core/gfxmenu/gui_progress_bar.c [new file with mode: 0644]
grub-core/gfxmenu/gui_string_util.c [new file with mode: 0644]
grub-core/gfxmenu/gui_util.c [new file with mode: 0644]
grub-core/gfxmenu/icon_manager.c [new file with mode: 0644]
grub-core/gfxmenu/model.c [new file with mode: 0644]
grub-core/gfxmenu/named_colors.c [new file with mode: 0644]
grub-core/gfxmenu/theme_loader.c [new file with mode: 0644]
grub-core/gfxmenu/view.c [new file with mode: 0644]
grub-core/gfxmenu/widget-box.c [new file with mode: 0644]
grub-core/gnulib/alloca.h [new file with mode: 0644]
grub-core/gnulib/argp-ba.c [new file with mode: 0644]
grub-core/gnulib/argp-eexst.c [new file with mode: 0644]
grub-core/gnulib/argp-fmtstream.c [new file with mode: 0644]
grub-core/gnulib/argp-fmtstream.h [new file with mode: 0644]
grub-core/gnulib/argp-fs-xinl.c [new file with mode: 0644]
grub-core/gnulib/argp-help.c [new file with mode: 0644]
grub-core/gnulib/argp-namefrob.h [new file with mode: 0644]
grub-core/gnulib/argp-parse.c [new file with mode: 0644]
grub-core/gnulib/argp-pin.c [new file with mode: 0644]
grub-core/gnulib/argp-pv.c [new file with mode: 0644]
grub-core/gnulib/argp-pvh.c [new file with mode: 0644]
grub-core/gnulib/argp-version-etc.c [new file with mode: 0644]
grub-core/gnulib/argp-version-etc.h [new file with mode: 0644]
grub-core/gnulib/argp-xinl.c [new file with mode: 0644]
grub-core/gnulib/argp.h [new file with mode: 0644]
grub-core/gnulib/error.c [new file with mode: 0644]
grub-core/gnulib/error.h [new file with mode: 0644]
grub-core/gnulib/fnmatch.c [new file with mode: 0644]
grub-core/gnulib/fnmatch.h [new file with mode: 0644]
grub-core/gnulib/fnmatch_loop.c [new file with mode: 0644]
grub-core/gnulib/getdelim.c [new file with mode: 0644]
grub-core/gnulib/getline.c [new file with mode: 0644]
grub-core/gnulib/getopt.c [new file with mode: 0644]
grub-core/gnulib/getopt.h [new file with mode: 0644]
grub-core/gnulib/getopt1.c [new file with mode: 0644]
grub-core/gnulib/getopt_int.h [new file with mode: 0644]
grub-core/gnulib/gettext.h [new file with mode: 0644]
grub-core/gnulib/progname.c [new file with mode: 0644]
grub-core/gnulib/progname.h [new file with mode: 0644]
grub-core/gnulib/regcomp.c [new file with mode: 0644]
grub-core/gnulib/regex.c [new file with mode: 0644]
grub-core/gnulib/regex.h [new file with mode: 0644]
grub-core/gnulib/regex_internal.c [new file with mode: 0644]
grub-core/gnulib/regex_internal.h [new file with mode: 0644]
grub-core/gnulib/regexec.c [new file with mode: 0644]
grub-core/hello/hello.c [new file with mode: 0644]
grub-core/hook/datehook.c [new file with mode: 0644]
grub-core/import_gcry.py [new file with mode: 0644]
grub-core/include/grub/acorn_filecore.h [new file with mode: 0644]
grub-core/include/grub/acpi.h [new file with mode: 0644]
grub-core/include/grub/aout.h [new file with mode: 0644]
grub-core/include/grub/at_keyboard.h [new file with mode: 0644]
grub-core/include/grub/ata.h [new file with mode: 0644]
grub-core/include/grub/auth.h [new file with mode: 0644]
grub-core/include/grub/autoefi.h [new file with mode: 0644]
grub-core/include/grub/bitmap.h [new file with mode: 0644]
grub-core/include/grub/bitmap_scale.h [new file with mode: 0644]
grub-core/include/grub/boot.h [new file with mode: 0644]
grub-core/include/grub/bsdlabel.h [new file with mode: 0644]
grub-core/include/grub/bufio.h [new file with mode: 0644]
grub-core/include/grub/cache.h [new file with mode: 0644]
grub-core/include/grub/charset.h [new file with mode: 0644]
grub-core/include/grub/cmos.h [new file with mode: 0644]
grub-core/include/grub/command.h [new file with mode: 0644]
grub-core/include/grub/crypto.h [new file with mode: 0644]
grub-core/include/grub/datetime.h [new file with mode: 0644]
grub-core/include/grub/device.h [new file with mode: 0644]
grub-core/include/grub/disk.h [new file with mode: 0644]
grub-core/include/grub/dl.h [new file with mode: 0644]
grub-core/include/grub/efi/api.h [new file with mode: 0644]
grub-core/include/grub/efi/console.h [new file with mode: 0644]
grub-core/include/grub/efi/console_control.h [new file with mode: 0644]
grub-core/include/grub/efi/disk.h [new file with mode: 0644]
grub-core/include/grub/efi/efi.h [new file with mode: 0644]
grub-core/include/grub/efi/graphics_output.h [new file with mode: 0644]
grub-core/include/grub/efi/memory.h [new file with mode: 0644]
grub-core/include/grub/efi/pe32.h [new file with mode: 0644]
grub-core/include/grub/efi/time.h [new file with mode: 0644]
grub-core/include/grub/efi/uga_draw.h [new file with mode: 0644]
grub-core/include/grub/efiemu/efiemu.h [new file with mode: 0644]
grub-core/include/grub/efiemu/runtime.h [new file with mode: 0644]
grub-core/include/grub/elf.h [new file with mode: 0644]
grub-core/include/grub/elfload.h [new file with mode: 0644]
grub-core/include/grub/emu/console.h [new file with mode: 0644]
grub-core/include/grub/emu/getroot.h [new file with mode: 0644]
grub-core/include/grub/emu/hostdisk.h [new file with mode: 0644]
grub-core/include/grub/emu/misc.h [new file with mode: 0644]
grub-core/include/grub/env.h [new file with mode: 0644]
grub-core/include/grub/env_private.h [new file with mode: 0644]
grub-core/include/grub/err.h [new file with mode: 0644]
grub-core/include/grub/extcmd.h [new file with mode: 0644]
grub-core/include/grub/fbblit.h [new file with mode: 0644]
grub-core/include/grub/fbfill.h [new file with mode: 0644]
grub-core/include/grub/fbutil.h [new file with mode: 0644]
grub-core/include/grub/file.h [new file with mode: 0644]
grub-core/include/grub/font.h [new file with mode: 0644]
grub-core/include/grub/fontformat.h [new file with mode: 0644]
grub-core/include/grub/fs.h [new file with mode: 0644]
grub-core/include/grub/fshelp.h [new file with mode: 0644]
grub-core/include/grub/gfxmenu_model.h [new file with mode: 0644]
grub-core/include/grub/gfxmenu_view.h [new file with mode: 0644]
grub-core/include/grub/gfxterm.h [new file with mode: 0644]
grub-core/include/grub/gfxwidgets.h [new file with mode: 0644]
grub-core/include/grub/gpt_partition.h [new file with mode: 0644]
grub-core/include/grub/gui.h [new file with mode: 0644]
grub-core/include/grub/gui_string_util.h [new file with mode: 0644]
grub-core/include/grub/gzio.h [new file with mode: 0644]
grub-core/include/grub/handler.h [new file with mode: 0644]
grub-core/include/grub/hfs.h [new file with mode: 0644]
grub-core/include/grub/i18n.h [new file with mode: 0644]
grub-core/include/grub/i386/at_keyboard.h [new file with mode: 0644]
grub-core/include/grub/i386/bsd.h [new file with mode: 0644]
grub-core/include/grub/i386/cmos.h [new file with mode: 0644]
grub-core/include/grub/i386/coreboot/boot.h [new file with mode: 0644]
grub-core/include/grub/i386/coreboot/console.h [new file with mode: 0644]
grub-core/include/grub/i386/coreboot/init.h [new file with mode: 0644]
grub-core/include/grub/i386/coreboot/kernel.h [new file with mode: 0644]
grub-core/include/grub/i386/coreboot/loader.h [new file with mode: 0644]
grub-core/include/grub/i386/coreboot/memory.h [new file with mode: 0644]
grub-core/include/grub/i386/coreboot/serial.h [new file with mode: 0644]
grub-core/include/grub/i386/coreboot/time.h [new file with mode: 0644]
grub-core/include/grub/i386/cpuid.h [new file with mode: 0644]
grub-core/include/grub/i386/efi/kernel.h [new file with mode: 0644]
grub-core/include/grub/i386/efi/loader.h [new file with mode: 0644]
grub-core/include/grub/i386/efi/memory.h [new file with mode: 0644]
grub-core/include/grub/i386/efi/serial.h [new file with mode: 0644]
grub-core/include/grub/i386/efi/time.h [new file with mode: 0644]
grub-core/include/grub/i386/efiemu.h [new file with mode: 0644]
grub-core/include/grub/i386/freebsd_linker.h [new file with mode: 0644]
grub-core/include/grub/i386/freebsd_reboot.h [new file with mode: 0644]
grub-core/include/grub/i386/ieee1275/console.h [new file with mode: 0644]
grub-core/include/grub/i386/ieee1275/ieee1275.h [new file with mode: 0644]
grub-core/include/grub/i386/ieee1275/kernel.h [new file with mode: 0644]
grub-core/include/grub/i386/ieee1275/loader.h [new file with mode: 0644]
grub-core/include/grub/i386/ieee1275/memory.h [new file with mode: 0644]
grub-core/include/grub/i386/ieee1275/serial.h [new file with mode: 0644]
grub-core/include/grub/i386/ieee1275/time.h [new file with mode: 0644]
grub-core/include/grub/i386/io.h [new file with mode: 0644]
grub-core/include/grub/i386/kernel.h [new file with mode: 0644]
grub-core/include/grub/i386/linux.h [new file with mode: 0644]
grub-core/include/grub/i386/loader.h [new file with mode: 0644]
grub-core/include/grub/i386/macho.h [new file with mode: 0644]
grub-core/include/grub/i386/memory.h [new file with mode: 0644]
grub-core/include/grub/i386/multiboot.h [new file with mode: 0644]
grub-core/include/grub/i386/multiboot/boot.h [new file with mode: 0644]
grub-core/include/grub/i386/multiboot/console.h [new file with mode: 0644]
grub-core/include/grub/i386/multiboot/init.h [new file with mode: 0644]
grub-core/include/grub/i386/multiboot/kernel.h [new file with mode: 0644]
grub-core/include/grub/i386/multiboot/loader.h [new file with mode: 0644]
grub-core/include/grub/i386/multiboot/memory.h [new file with mode: 0644]
grub-core/include/grub/i386/multiboot/serial.h [new file with mode: 0644]
grub-core/include/grub/i386/multiboot/time.h [new file with mode: 0644]
grub-core/include/grub/i386/netbsd_bootinfo.h [new file with mode: 0644]
grub-core/include/grub/i386/netbsd_reboot.h [new file with mode: 0644]
grub-core/include/grub/i386/openbsd_bootarg.h [new file with mode: 0644]
grub-core/include/grub/i386/openbsd_reboot.h [new file with mode: 0644]
grub-core/include/grub/i386/pc/biosdisk.h [new file with mode: 0644]
grub-core/include/grub/i386/pc/biosnum.h [new file with mode: 0644]
grub-core/include/grub/i386/pc/boot.h [new file with mode: 0644]
grub-core/include/grub/i386/pc/chainloader.h [new file with mode: 0644]
grub-core/include/grub/i386/pc/console.h [new file with mode: 0644]
grub-core/include/grub/i386/pc/efiemu.h [new file with mode: 0644]
grub-core/include/grub/i386/pc/init.h [new file with mode: 0644]
grub-core/include/grub/i386/pc/kernel.h [new file with mode: 0644]
grub-core/include/grub/i386/pc/loader.h [new file with mode: 0644]
grub-core/include/grub/i386/pc/memory.h [new file with mode: 0644]
grub-core/include/grub/i386/pc/pxe.h [new file with mode: 0644]
grub-core/include/grub/i386/pc/time.h [new file with mode: 0644]
grub-core/include/grub/i386/pc/vbe.h [new file with mode: 0644]
grub-core/include/grub/i386/pc/vga.h [new file with mode: 0644]
grub-core/include/grub/i386/pci.h [new file with mode: 0644]
grub-core/include/grub/i386/pit.h [new file with mode: 0644]
grub-core/include/grub/i386/qemu/boot.h [new file with mode: 0644]
grub-core/include/grub/i386/qemu/console.h [new file with mode: 0644]
grub-core/include/grub/i386/qemu/init.h [new file with mode: 0644]
grub-core/include/grub/i386/qemu/kernel.h [new file with mode: 0644]
grub-core/include/grub/i386/qemu/loader.h [new file with mode: 0644]
grub-core/include/grub/i386/qemu/memory.h [new file with mode: 0644]
grub-core/include/grub/i386/qemu/serial.h [new file with mode: 0644]
grub-core/include/grub/i386/qemu/time.h [new file with mode: 0644]
grub-core/include/grub/i386/relocator.h [new file with mode: 0644]
grub-core/include/grub/i386/setjmp.h [new file with mode: 0644]
grub-core/include/grub/i386/time.h [new file with mode: 0644]
grub-core/include/grub/i386/tsc.h [new file with mode: 0644]
grub-core/include/grub/i386/types.h [new file with mode: 0644]
grub-core/include/grub/i386/vga_common.h [new file with mode: 0644]
grub-core/include/grub/i386/xnu.h [new file with mode: 0644]
grub-core/include/grub/icon_manager.h [new file with mode: 0644]
grub-core/include/grub/ieee1275/ieee1275.h [new file with mode: 0644]
grub-core/include/grub/ieee1275/ofdisk.h [new file with mode: 0644]
grub-core/include/grub/kernel.h [new file with mode: 0644]
grub-core/include/grub/lib/LzFind.h [new file with mode: 0644]
grub-core/include/grub/lib/LzHash.h [new file with mode: 0644]
grub-core/include/grub/lib/LzmaDec.h [new file with mode: 0644]
grub-core/include/grub/lib/LzmaEnc.h [new file with mode: 0644]
grub-core/include/grub/lib/LzmaTypes.h [new file with mode: 0644]
grub-core/include/grub/lib/arg.h [new file with mode: 0644]
grub-core/include/grub/lib/crc.h [new file with mode: 0644]
grub-core/include/grub/lib/envblk.h [new file with mode: 0644]
grub-core/include/grub/lib/hexdump.h [new file with mode: 0644]
grub-core/include/grub/libgcc.h [new file with mode: 0644]
grub-core/include/grub/libpciaccess.h [new file with mode: 0644]
grub-core/include/grub/libusb.h [new file with mode: 0644]
grub-core/include/grub/list.h [new file with mode: 0644]
grub-core/include/grub/loader.h [new file with mode: 0644]
grub-core/include/grub/lvm.h [new file with mode: 0644]
grub-core/include/grub/macho.h [new file with mode: 0644]
grub-core/include/grub/machoload.h [new file with mode: 0644]
grub-core/include/grub/memory.h [new file with mode: 0644]
grub-core/include/grub/menu.h [new file with mode: 0644]
grub-core/include/grub/menu_viewer.h [new file with mode: 0644]
grub-core/include/grub/mips/at_keyboard.h [new file with mode: 0644]
grub-core/include/grub/mips/cache.h [new file with mode: 0644]
grub-core/include/grub/mips/cmos.h [new file with mode: 0644]
grub-core/include/grub/mips/io.h [new file with mode: 0644]
grub-core/include/grub/mips/kernel.h [new file with mode: 0644]
grub-core/include/grub/mips/multiboot.h [new file with mode: 0644]
grub-core/include/grub/mips/pci.h [new file with mode: 0644]
grub-core/include/grub/mips/qemu-mips/boot.h [new file with mode: 0644]
grub-core/include/grub/mips/qemu-mips/kernel.h [new file with mode: 0644]
grub-core/include/grub/mips/qemu-mips/loader.h [new file with mode: 0644]
grub-core/include/grub/mips/qemu-mips/memory.h [new file with mode: 0644]
grub-core/include/grub/mips/qemu-mips/serial.h [new file with mode: 0644]
grub-core/include/grub/mips/qemu-mips/time.h [new file with mode: 0644]
grub-core/include/grub/mips/relocator.h [new file with mode: 0644]
grub-core/include/grub/mips/setjmp.h [new file with mode: 0644]
grub-core/include/grub/mips/time.h [new file with mode: 0644]
grub-core/include/grub/mips/types.h [new file with mode: 0644]
grub-core/include/grub/mips/yeeloong/at_keyboard.h [new file with mode: 0644]
grub-core/include/grub/mips/yeeloong/boot.h [new file with mode: 0644]
grub-core/include/grub/mips/yeeloong/cmos.h [new file with mode: 0644]
grub-core/include/grub/mips/yeeloong/kernel.h [new file with mode: 0644]
grub-core/include/grub/mips/yeeloong/loader.h [new file with mode: 0644]
grub-core/include/grub/mips/yeeloong/memory.h [new file with mode: 0644]
grub-core/include/grub/mips/yeeloong/pci.h [new file with mode: 0644]
grub-core/include/grub/mips/yeeloong/serial.h [new file with mode: 0644]
grub-core/include/grub/mips/yeeloong/time.h [new file with mode: 0644]
grub-core/include/grub/misc.h [new file with mode: 0644]
grub-core/include/grub/mm.h [new file with mode: 0644]
grub-core/include/grub/msdos_partition.h [new file with mode: 0644]
grub-core/include/grub/multiboot.h [new file with mode: 0644]
grub-core/include/grub/multiboot_loader.h [new file with mode: 0644]
grub-core/include/grub/net.h [new file with mode: 0644]
grub-core/include/grub/normal.h [new file with mode: 0644]
grub-core/include/grub/ntfs.h [new file with mode: 0644]
grub-core/include/grub/parser.h [new file with mode: 0644]
grub-core/include/grub/partition.h [new file with mode: 0644]
grub-core/include/grub/parttool.h [new file with mode: 0644]
grub-core/include/grub/pci.h [new file with mode: 0644]
grub-core/include/grub/pciutils.h [new file with mode: 0644]
grub-core/include/grub/powerpc/ieee1275/biosdisk.h [new file with mode: 0644]
grub-core/include/grub/powerpc/ieee1275/console.h [new file with mode: 0644]
grub-core/include/grub/powerpc/ieee1275/ieee1275.h [new file with mode: 0644]
grub-core/include/grub/powerpc/ieee1275/kernel.h [new file with mode: 0644]
grub-core/include/grub/powerpc/ieee1275/loader.h [new file with mode: 0644]
grub-core/include/grub/powerpc/ieee1275/memory.h [new file with mode: 0644]
grub-core/include/grub/powerpc/ieee1275/time.h [new file with mode: 0644]
grub-core/include/grub/powerpc/ieee1275/util/biosdisk.h [new file with mode: 0644]
grub-core/include/grub/powerpc/kernel.h [new file with mode: 0644]
grub-core/include/grub/powerpc/setjmp.h [new file with mode: 0644]
grub-core/include/grub/powerpc/time.h [new file with mode: 0644]
grub-core/include/grub/powerpc/types.h [new file with mode: 0644]
grub-core/include/grub/raid.h [new file with mode: 0644]
grub-core/include/grub/reader.h [new file with mode: 0644]
grub-core/include/grub/script_sh.h [new file with mode: 0644]
grub-core/include/grub/scsi.h [new file with mode: 0644]
grub-core/include/grub/scsicmd.h [new file with mode: 0644]
grub-core/include/grub/sdl.h [new file with mode: 0644]
grub-core/include/grub/search.h [new file with mode: 0644]
grub-core/include/grub/serial.h [new file with mode: 0644]
grub-core/include/grub/setjmp.h [new file with mode: 0644]
grub-core/include/grub/sparc64/ieee1275/boot.h [new file with mode: 0644]
grub-core/include/grub/sparc64/ieee1275/console.h [new file with mode: 0644]
grub-core/include/grub/sparc64/ieee1275/ieee1275.h [new file with mode: 0644]
grub-core/include/grub/sparc64/ieee1275/kernel.h [new file with mode: 0644]
grub-core/include/grub/sparc64/ieee1275/loader.h [new file with mode: 0644]
grub-core/include/grub/sparc64/ieee1275/memory.h [new file with mode: 0644]
grub-core/include/grub/sparc64/ieee1275/time.h [new file with mode: 0644]
grub-core/include/grub/sparc64/kernel.h [new file with mode: 0644]
grub-core/include/grub/sparc64/setjmp.h [new file with mode: 0644]
grub-core/include/grub/sparc64/time.h [new file with mode: 0644]
grub-core/include/grub/sparc64/types.h [new file with mode: 0644]
grub-core/include/grub/symbol.h [new file with mode: 0644]
grub-core/include/grub/term.h [new file with mode: 0644]
grub-core/include/grub/terminfo.h [new file with mode: 0644]
grub-core/include/grub/test.h [new file with mode: 0644]
grub-core/include/grub/time.h [new file with mode: 0644]
grub-core/include/grub/tparm.h [new file with mode: 0644]
grub-core/include/grub/trig.h [new file with mode: 0644]
grub-core/include/grub/types.h [new file with mode: 0644]
grub-core/include/grub/usb.h [new file with mode: 0644]
grub-core/include/grub/usbdesc.h [new file with mode: 0644]
grub-core/include/grub/usbtrans.h [new file with mode: 0644]
grub-core/include/grub/util/deviceiter.h [new file with mode: 0644]
grub-core/include/grub/util/lvm.h [new file with mode: 0644]
grub-core/include/grub/util/misc.h [new file with mode: 0644]
grub-core/include/grub/util/ofpath.h [new file with mode: 0644]
grub-core/include/grub/util/raid.h [new file with mode: 0644]
grub-core/include/grub/util/resolve.h [new file with mode: 0644]
grub-core/include/grub/video.h [new file with mode: 0644]
grub-core/include/grub/video_fb.h [new file with mode: 0644]
grub-core/include/grub/x86_64/at_keyboard.h [new file with mode: 0644]
grub-core/include/grub/x86_64/efi/kernel.h [new file with mode: 0644]
grub-core/include/grub/x86_64/efi/loader.h [new file with mode: 0644]
grub-core/include/grub/x86_64/efi/memory.h [new file with mode: 0644]
grub-core/include/grub/x86_64/efi/serial.h [new file with mode: 0644]
grub-core/include/grub/x86_64/efi/time.h [new file with mode: 0644]
grub-core/include/grub/x86_64/io.h [new file with mode: 0644]
grub-core/include/grub/x86_64/kernel.h [new file with mode: 0644]
grub-core/include/grub/x86_64/linux.h [new file with mode: 0644]
grub-core/include/grub/x86_64/macho.h [new file with mode: 0644]
grub-core/include/grub/x86_64/multiboot.h [new file with mode: 0644]
grub-core/include/grub/x86_64/pci.h [new file with mode: 0644]
grub-core/include/grub/x86_64/relocator.h [new file with mode: 0644]
grub-core/include/grub/x86_64/setjmp.h [new file with mode: 0644]
grub-core/include/grub/x86_64/time.h [new file with mode: 0644]
grub-core/include/grub/x86_64/types.h [new file with mode: 0644]
grub-core/include/grub/x86_64/xnu.h [new file with mode: 0644]
grub-core/include/grub/xnu.h [new file with mode: 0644]
grub-core/include/multiboot.h [new file with mode: 0644]
grub-core/include/multiboot2.h [new file with mode: 0644]
grub-core/io/bufio.c [new file with mode: 0644]
grub-core/io/gzio.c [new file with mode: 0644]
grub-core/kern/command.c [new file with mode: 0644]
grub-core/kern/corecmd.c [new file with mode: 0644]
grub-core/kern/device.c [new file with mode: 0644]
grub-core/kern/disk.c [new file with mode: 0644]
grub-core/kern/dl.c [new file with mode: 0644]
grub-core/kern/efi/efi.c [new file with mode: 0644]
grub-core/kern/efi/init.c [new file with mode: 0644]
grub-core/kern/efi/mm.c [new file with mode: 0644]
grub-core/kern/elf.c [new file with mode: 0644]
grub-core/kern/emu/cache.S [new file with mode: 0644]
grub-core/kern/emu/console.c [new file with mode: 0644]
grub-core/kern/emu/dl.c [new file with mode: 0644]
grub-core/kern/emu/dummy/dl.c [new file with mode: 0644]
grub-core/kern/emu/dummy/symlist.c [new file with mode: 0644]
grub-core/kern/emu/getroot.c [new file with mode: 0644]
grub-core/kern/emu/hostdisk.c [new file with mode: 0644]
grub-core/kern/emu/hostfs.c [new file with mode: 0644]
grub-core/kern/emu/lite.c [new file with mode: 0644]
grub-core/kern/emu/main.c [new file with mode: 0644]
grub-core/kern/emu/misc.c [new file with mode: 0644]
grub-core/kern/emu/time.c [new file with mode: 0644]
grub-core/kern/env.c [new file with mode: 0644]
grub-core/kern/err.c [new file with mode: 0644]
grub-core/kern/file.c [new file with mode: 0644]
grub-core/kern/fs.c [new file with mode: 0644]
grub-core/kern/generic/millisleep.c [new file with mode: 0644]
grub-core/kern/generic/rtc_get_time_ms.c [new file with mode: 0644]
grub-core/kern/handler.c [new file with mode: 0644]
grub-core/kern/i386/coreboot/init.c [new file with mode: 0644]
grub-core/kern/i386/coreboot/mmap.c [new file with mode: 0644]
grub-core/kern/i386/coreboot/startup.S [new file with mode: 0644]
grub-core/kern/i386/dl.c [new file with mode: 0644]
grub-core/kern/i386/efi/init.c [new file with mode: 0644]
grub-core/kern/i386/efi/startup.S [new file with mode: 0644]
grub-core/kern/i386/halt.c [new file with mode: 0644]
grub-core/kern/i386/ieee1275/init.c [new file with mode: 0644]
grub-core/kern/i386/ieee1275/startup.S [new file with mode: 0644]
grub-core/kern/i386/loader.S [new file with mode: 0644]
grub-core/kern/i386/misc.S [new file with mode: 0644]
grub-core/kern/i386/multiboot_mmap.c [new file with mode: 0644]
grub-core/kern/i386/pc/init.c [new file with mode: 0644]
grub-core/kern/i386/pc/lzma_decode.S [new file with mode: 0644]
grub-core/kern/i386/pc/mmap.c [new file with mode: 0644]
grub-core/kern/i386/pc/startup.S [new file with mode: 0644]
grub-core/kern/i386/pit.c [new file with mode: 0644]
grub-core/kern/i386/qemu/mmap.c [new file with mode: 0644]
grub-core/kern/i386/qemu/startup.S [new file with mode: 0644]
grub-core/kern/i386/realmode.S [new file with mode: 0644]
grub-core/kern/i386/tsc.c [new file with mode: 0644]
grub-core/kern/ieee1275/cmain.c [new file with mode: 0644]
grub-core/kern/ieee1275/ieee1275.c [new file with mode: 0644]
grub-core/kern/ieee1275/init.c [new file with mode: 0644]
grub-core/kern/ieee1275/mmap.c [new file with mode: 0644]
grub-core/kern/ieee1275/openfw.c [new file with mode: 0644]
grub-core/kern/list.c [new file with mode: 0644]
grub-core/kern/main.c [new file with mode: 0644]
grub-core/kern/mips/cache.S [new file with mode: 0644]
grub-core/kern/mips/cache_flush.S [new file with mode: 0644]
grub-core/kern/mips/dl.c [new file with mode: 0644]
grub-core/kern/mips/init.c [new file with mode: 0644]
grub-core/kern/mips/qemu-mips/init.c [new file with mode: 0644]
grub-core/kern/mips/startup.S [new file with mode: 0644]
grub-core/kern/mips/yeeloong/init.c [new file with mode: 0644]
grub-core/kern/misc.c [new file with mode: 0644]
grub-core/kern/mm.c [new file with mode: 0644]
grub-core/kern/parser.c [new file with mode: 0644]
grub-core/kern/partition.c [new file with mode: 0644]
grub-core/kern/powerpc/cache.S [new file with mode: 0644]
grub-core/kern/powerpc/dl.c [new file with mode: 0644]
grub-core/kern/powerpc/ieee1275/startup.S [new file with mode: 0644]
grub-core/kern/rescue_parser.c [new file with mode: 0644]
grub-core/kern/rescue_reader.c [new file with mode: 0644]
grub-core/kern/sparc64/cache.S [new file with mode: 0644]
grub-core/kern/sparc64/dl.c [new file with mode: 0644]
grub-core/kern/sparc64/ieee1275/crt0.S [new file with mode: 0644]
grub-core/kern/sparc64/ieee1275/ieee1275.c [new file with mode: 0644]
grub-core/kern/sparc64/ieee1275/init.c [new file with mode: 0644]
grub-core/kern/term.c [new file with mode: 0644]
grub-core/kern/time.c [new file with mode: 0644]
grub-core/kern/x86_64/dl.c [new file with mode: 0644]
grub-core/kern/x86_64/efi/callwrap.S [new file with mode: 0644]
grub-core/kern/x86_64/efi/startup.S [new file with mode: 0644]
grub-core/lib/LzFind.c [new file with mode: 0644]
grub-core/lib/LzmaDec.c [new file with mode: 0644]
grub-core/lib/LzmaEnc.c [new file with mode: 0644]
grub-core/lib/arg.c [new file with mode: 0644]
grub-core/lib/charset.c [new file with mode: 0644]
grub-core/lib/cmos_datetime.c [new file with mode: 0644]
grub-core/lib/crc.c [new file with mode: 0644]
grub-core/lib/crypto.c [new file with mode: 0644]
grub-core/lib/efi/datetime.c [new file with mode: 0644]
grub-core/lib/envblk.c [new file with mode: 0644]
grub-core/lib/hexdump.c [new file with mode: 0644]
grub-core/lib/i386/pc/biosnum.c [new file with mode: 0644]
grub-core/lib/i386/relocator.c [new file with mode: 0644]
grub-core/lib/i386/relocator_asm.S [new file with mode: 0644]
grub-core/lib/i386/relocator_backward.S [new file with mode: 0644]
grub-core/lib/i386/setjmp.S [new file with mode: 0644]
grub-core/lib/ieee1275/datetime.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/ChangeLog [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/ac.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/arcfour.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/bithelp.h [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/blowfish.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/camellia-glue.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/camellia.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/camellia.h [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/cast5.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/cipher.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/crc.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/des.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/dsa.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/ecc.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/elgamal.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/hash-common.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/hash-common.h [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/hmac-tests.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/md.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/md4.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/md5.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/primegen.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/pubkey.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/rfc2268.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/rijndael-tables.h [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/rijndael.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/rmd.h [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/rmd160.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/rsa.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/seed.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/serpent.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/sha1.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/sha256.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/sha512.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/tiger.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/twofish.c [new file with mode: 0644]
grub-core/lib/libgcrypt/cipher/whirlpool.c [new file with mode: 0644]
grub-core/lib/libgcrypt_wrap/cipher_wrap.h [new file with mode: 0644]
grub-core/lib/mips/relocator.c [new file with mode: 0644]
grub-core/lib/mips/relocator_asm.S [new file with mode: 0644]
grub-core/lib/mips/setjmp.S [new file with mode: 0644]
grub-core/lib/pbkdf2.c [new file with mode: 0644]
grub-core/lib/posix_wrap/assert.h [new file with mode: 0644]
grub-core/lib/posix_wrap/ctype.h [new file with mode: 0644]
grub-core/lib/posix_wrap/errno.h [new file with mode: 0644]
grub-core/lib/posix_wrap/langinfo.h [new file with mode: 0644]
grub-core/lib/posix_wrap/limits.h [new file with mode: 0644]
grub-core/lib/posix_wrap/localcharset.h [new file with mode: 0644]
grub-core/lib/posix_wrap/locale.h [new file with mode: 0644]
grub-core/lib/posix_wrap/stdint.h [new file with mode: 0644]
grub-core/lib/posix_wrap/stdio.h [new file with mode: 0644]
grub-core/lib/posix_wrap/stdlib.h [new file with mode: 0644]
grub-core/lib/posix_wrap/string.h [new file with mode: 0644]
grub-core/lib/posix_wrap/sys/types.h [new file with mode: 0644]
grub-core/lib/posix_wrap/unistd.h [new file with mode: 0644]
grub-core/lib/posix_wrap/wchar.h [new file with mode: 0644]
grub-core/lib/posix_wrap/wctype.h [new file with mode: 0644]
grub-core/lib/powerpc/setjmp.S [new file with mode: 0644]
grub-core/lib/relocator.c [new file with mode: 0644]
grub-core/lib/sparc64/setjmp.S [new file with mode: 0644]
grub-core/lib/x86_64/setjmp.S [new file with mode: 0644]
grub-core/loader/aout.c [new file with mode: 0644]
grub-core/loader/efi/appleloader.c [new file with mode: 0644]
grub-core/loader/efi/chainloader.c [new file with mode: 0644]
grub-core/loader/i386/bsd.c [new file with mode: 0644]
grub-core/loader/i386/bsd32.c [new file with mode: 0644]
grub-core/loader/i386/bsd64.c [new file with mode: 0644]
grub-core/loader/i386/bsdXX.c [new file with mode: 0644]
grub-core/loader/i386/bsd_helper.S [new file with mode: 0644]
grub-core/loader/i386/bsd_pagetable.c [new file with mode: 0644]
grub-core/loader/i386/bsd_trampoline.S [new file with mode: 0644]
grub-core/loader/i386/efi/linux.c [new file with mode: 0644]
grub-core/loader/i386/efi/xnu.c [new file with mode: 0644]
grub-core/loader/i386/ieee1275/linux.c [new file with mode: 0644]
grub-core/loader/i386/linux.c [new file with mode: 0644]
grub-core/loader/i386/linux_trampoline.S [new file with mode: 0644]
grub-core/loader/i386/multiboot_mbi.c [new file with mode: 0644]
grub-core/loader/i386/pc/chainloader.c [new file with mode: 0644]
grub-core/loader/i386/pc/linux.c [new file with mode: 0644]
grub-core/loader/i386/pc/xnu.c [new file with mode: 0644]
grub-core/loader/i386/xnu.c [new file with mode: 0644]
grub-core/loader/macho.c [new file with mode: 0644]
grub-core/loader/macho32.c [new file with mode: 0644]
grub-core/loader/macho64.c [new file with mode: 0644]
grub-core/loader/machoXX.c [new file with mode: 0644]
grub-core/loader/mips/linux.c [new file with mode: 0644]
grub-core/loader/multiboot.c [new file with mode: 0644]
grub-core/loader/multiboot_elfxx.c [new file with mode: 0644]
grub-core/loader/multiboot_mbi2.c [new file with mode: 0644]
grub-core/loader/powerpc/ieee1275/linux.c [new file with mode: 0644]
grub-core/loader/sparc64/ieee1275/linux.c [new file with mode: 0644]
grub-core/loader/xnu.c [new file with mode: 0644]
grub-core/loader/xnu_resume.c [new file with mode: 0644]
grub-core/mmap/efi/mmap.c [new file with mode: 0644]
grub-core/mmap/i386/mmap.c [new file with mode: 0644]
grub-core/mmap/i386/pc/mmap.c [new file with mode: 0644]
grub-core/mmap/i386/pc/mmap_helper.S [new file with mode: 0644]
grub-core/mmap/i386/uppermem.c [new file with mode: 0644]
grub-core/mmap/mips/yeeloong/uppermem.c [new file with mode: 0644]
grub-core/mmap/mmap.c [new file with mode: 0644]
grub-core/modules.def [new file with mode: 0644]
grub-core/normal/auth.c [new file with mode: 0644]
grub-core/normal/autofs.c [new file with mode: 0644]
grub-core/normal/cmdline.c [new file with mode: 0644]
grub-core/normal/color.c [new file with mode: 0644]
grub-core/normal/completion.c [new file with mode: 0644]
grub-core/normal/context.c [new file with mode: 0644]
grub-core/normal/crypto.c [new file with mode: 0644]
grub-core/normal/datetime.c [new file with mode: 0644]
grub-core/normal/dyncmd.c [new file with mode: 0644]
grub-core/normal/handler.c [new file with mode: 0644]
grub-core/normal/main.c [new file with mode: 0644]
grub-core/normal/menu.c [new file with mode: 0644]
grub-core/normal/menu_entry.c [new file with mode: 0644]
grub-core/normal/menu_text.c [new file with mode: 0644]
grub-core/normal/misc.c [new file with mode: 0644]
grub-core/normal/term.c [new file with mode: 0644]
grub-core/partmap/acorn.c [new file with mode: 0644]
grub-core/partmap/amiga.c [new file with mode: 0644]
grub-core/partmap/apple.c [new file with mode: 0644]
grub-core/partmap/bsdlabel.c [new file with mode: 0644]
grub-core/partmap/gpt.c [new file with mode: 0644]
grub-core/partmap/msdos.c [new file with mode: 0644]
grub-core/partmap/sun.c [new file with mode: 0644]
grub-core/partmap/sunpc.c [new file with mode: 0644]
grub-core/parttool/msdospart.c [new file with mode: 0644]
grub-core/po/Makefile.am [new file with mode: 0644]
grub-core/po/POTFILES [new file with mode: 0644]
grub-core/po/POTFILES-shell [new file with mode: 0644]
grub-core/po/README [new file with mode: 0644]
grub-core/script/execute.c [new file with mode: 0644]
grub-core/script/function.c [new file with mode: 0644]
grub-core/script/lexer.c [new file with mode: 0644]
grub-core/script/main.c [new file with mode: 0644]
grub-core/script/parser.y [new file with mode: 0644]
grub-core/script/script.c [new file with mode: 0644]
grub-core/script/yylex.l [new file with mode: 0644]
grub-core/term/at_keyboard.c [new file with mode: 0644]
grub-core/term/efi/console.c [new file with mode: 0644]
grub-core/term/gfxterm.c [new file with mode: 0644]
grub-core/term/i386/pc/console.c [new file with mode: 0644]
grub-core/term/i386/pc/vga.c [new file with mode: 0644]
grub-core/term/i386/pc/vga_text.c [new file with mode: 0644]
grub-core/term/i386/vga_common.c [new file with mode: 0644]
grub-core/term/ieee1275/ofconsole.c [new file with mode: 0644]
grub-core/term/serial.c [new file with mode: 0644]
grub-core/term/terminfo.c [new file with mode: 0644]
grub-core/term/tparm.c [new file with mode: 0644]
grub-core/term/usb_keyboard.c [new file with mode: 0644]
grub-core/tests/example_functional_test.c [new file with mode: 0644]
grub-core/tests/lib/functional_test.c [new file with mode: 0644]
grub-core/tests/lib/test.c [new file with mode: 0644]
grub-core/video/bitmap.c [new file with mode: 0644]
grub-core/video/bitmap_scale.c [new file with mode: 0644]
grub-core/video/efi_gop.c [new file with mode: 0644]
grub-core/video/efi_uga.c [new file with mode: 0644]
grub-core/video/emu/sdl.c [new file with mode: 0644]
grub-core/video/fb/fbblit.c [new file with mode: 0644]
grub-core/video/fb/fbfill.c [new file with mode: 0644]
grub-core/video/fb/fbutil.c [new file with mode: 0644]
grub-core/video/fb/video_fb.c [new file with mode: 0644]
grub-core/video/i386/pc/vbe.c [new file with mode: 0644]
grub-core/video/ieee1275.c [new file with mode: 0644]
grub-core/video/readers/jpeg.c [new file with mode: 0644]
grub-core/video/readers/png.c [new file with mode: 0644]
grub-core/video/readers/tga.c [new file with mode: 0644]
grub-core/video/sm712.c [new file with mode: 0644]
grub-core/video/video.c [new file with mode: 0644]
hello/hello.c [deleted file]
hook/datehook.c [deleted file]
include/grub/acorn_filecore.h [deleted file]
include/grub/acpi.h [deleted file]
include/grub/aout.h [deleted file]
include/grub/at_keyboard.h [deleted file]
include/grub/ata.h [deleted file]
include/grub/auth.h [deleted file]
include/grub/autoefi.h [deleted file]
include/grub/bitmap.h [deleted file]
include/grub/bitmap_scale.h [deleted file]
include/grub/boot.h [deleted file]
include/grub/bsdlabel.h [deleted file]
include/grub/bufio.h [deleted file]
include/grub/cache.h [deleted file]
include/grub/charset.h [deleted file]
include/grub/cmos.h [deleted file]
include/grub/command.h [deleted file]
include/grub/crypto.h [deleted file]
include/grub/datetime.h [deleted file]
include/grub/device.h [deleted file]
include/grub/disk.h [deleted file]
include/grub/dl.h [deleted file]
include/grub/efi/api.h [deleted file]
include/grub/efi/console.h [deleted file]
include/grub/efi/console_control.h [deleted file]
include/grub/efi/disk.h [deleted file]
include/grub/efi/efi.h [deleted file]
include/grub/efi/graphics_output.h [deleted file]
include/grub/efi/memory.h [deleted file]
include/grub/efi/pe32.h [deleted file]
include/grub/efi/time.h [deleted file]
include/grub/efi/uga_draw.h [deleted file]
include/grub/efiemu/efiemu.h [deleted file]
include/grub/efiemu/runtime.h [deleted file]
include/grub/elf.h [deleted file]
include/grub/elfload.h [deleted file]
include/grub/env.h [deleted file]
include/grub/env_private.h [deleted file]
include/grub/err.h [deleted file]
include/grub/extcmd.h [deleted file]
include/grub/fbblit.h [deleted file]
include/grub/fbfill.h [deleted file]
include/grub/fbutil.h [deleted file]
include/grub/file.h [deleted file]
include/grub/font.h [deleted file]
include/grub/fontformat.h [deleted file]
include/grub/fs.h [deleted file]
include/grub/fshelp.h [deleted file]
include/grub/gfxmenu_model.h [deleted file]
include/grub/gfxmenu_view.h [deleted file]
include/grub/gfxterm.h [deleted file]
include/grub/gfxwidgets.h [deleted file]
include/grub/gpt_partition.h [deleted file]
include/grub/gui.h [deleted file]
include/grub/gui_string_util.h [deleted file]
include/grub/gzio.h [deleted file]
include/grub/handler.h [deleted file]
include/grub/hfs.h [deleted file]
include/grub/i18n.h [deleted file]
include/grub/i386/at_keyboard.h [deleted file]
include/grub/i386/bsd.h [deleted file]
include/grub/i386/cmos.h [deleted file]
include/grub/i386/coreboot/boot.h [deleted file]
include/grub/i386/coreboot/console.h [deleted file]
include/grub/i386/coreboot/init.h [deleted file]
include/grub/i386/coreboot/kernel.h [deleted file]
include/grub/i386/coreboot/loader.h [deleted file]
include/grub/i386/coreboot/memory.h [deleted file]
include/grub/i386/coreboot/serial.h [deleted file]
include/grub/i386/coreboot/time.h [deleted file]
include/grub/i386/cpuid.h [deleted file]
include/grub/i386/efi/kernel.h [deleted file]
include/grub/i386/efi/loader.h [deleted file]
include/grub/i386/efi/memory.h [deleted file]
include/grub/i386/efi/serial.h [deleted file]
include/grub/i386/efi/time.h [deleted file]
include/grub/i386/efiemu.h [deleted file]
include/grub/i386/freebsd_linker.h [deleted file]
include/grub/i386/freebsd_reboot.h [deleted file]
include/grub/i386/ieee1275/console.h [deleted file]
include/grub/i386/ieee1275/ieee1275.h [deleted file]
include/grub/i386/ieee1275/kernel.h [deleted file]
include/grub/i386/ieee1275/loader.h [deleted file]
include/grub/i386/ieee1275/memory.h [deleted file]
include/grub/i386/ieee1275/serial.h [deleted file]
include/grub/i386/ieee1275/time.h [deleted file]
include/grub/i386/io.h [deleted file]
include/grub/i386/kernel.h [deleted file]
include/grub/i386/linux.h [deleted file]
include/grub/i386/loader.h [deleted file]
include/grub/i386/macho.h [deleted file]
include/grub/i386/memory.h [deleted file]
include/grub/i386/multiboot.h [deleted file]
include/grub/i386/multiboot/boot.h [deleted file]
include/grub/i386/multiboot/console.h [deleted file]
include/grub/i386/multiboot/init.h [deleted file]
include/grub/i386/multiboot/kernel.h [deleted file]
include/grub/i386/multiboot/loader.h [deleted file]
include/grub/i386/multiboot/memory.h [deleted file]
include/grub/i386/multiboot/serial.h [deleted file]
include/grub/i386/multiboot/time.h [deleted file]
include/grub/i386/netbsd_bootinfo.h [deleted file]
include/grub/i386/netbsd_reboot.h [deleted file]
include/grub/i386/openbsd_bootarg.h [deleted file]
include/grub/i386/openbsd_reboot.h [deleted file]
include/grub/i386/pc/biosdisk.h [deleted file]
include/grub/i386/pc/biosnum.h [deleted file]
include/grub/i386/pc/boot.h [deleted file]
include/grub/i386/pc/chainloader.h [deleted file]
include/grub/i386/pc/console.h [deleted file]
include/grub/i386/pc/efiemu.h [deleted file]
include/grub/i386/pc/init.h [deleted file]
include/grub/i386/pc/kernel.h [deleted file]
include/grub/i386/pc/loader.h [deleted file]
include/grub/i386/pc/memory.h [deleted file]
include/grub/i386/pc/pxe.h [deleted file]
include/grub/i386/pc/time.h [deleted file]
include/grub/i386/pc/vbe.h [deleted file]
include/grub/i386/pc/vga.h [deleted file]
include/grub/i386/pci.h [deleted file]
include/grub/i386/pit.h [deleted file]
include/grub/i386/qemu/boot.h [deleted file]
include/grub/i386/qemu/console.h [deleted file]
include/grub/i386/qemu/init.h [deleted file]
include/grub/i386/qemu/kernel.h [deleted file]
include/grub/i386/qemu/loader.h [deleted file]
include/grub/i386/qemu/memory.h [deleted file]
include/grub/i386/qemu/serial.h [deleted file]
include/grub/i386/qemu/time.h [deleted file]
include/grub/i386/relocator.h [deleted file]
include/grub/i386/setjmp.h [deleted file]
include/grub/i386/time.h [deleted file]
include/grub/i386/tsc.h [deleted file]
include/grub/i386/types.h [deleted file]
include/grub/i386/vga_common.h [deleted file]
include/grub/i386/xnu.h [deleted file]
include/grub/icon_manager.h [deleted file]
include/grub/ieee1275/ieee1275.h [deleted file]
include/grub/ieee1275/ofdisk.h [deleted file]
include/grub/kernel.h [deleted file]
include/grub/lib/LzFind.h [deleted file]
include/grub/lib/LzHash.h [deleted file]
include/grub/lib/LzmaDec.h [deleted file]
include/grub/lib/LzmaEnc.h [deleted file]
include/grub/lib/LzmaTypes.h [deleted file]
include/grub/lib/arg.h [deleted file]
include/grub/lib/crc.h [deleted file]
include/grub/lib/envblk.h [deleted file]
include/grub/lib/hexdump.h [deleted file]
include/grub/libgcc.h [deleted file]
include/grub/libpciaccess.h [deleted file]
include/grub/libusb.h [deleted file]
include/grub/list.h [deleted file]
include/grub/loader.h [deleted file]
include/grub/lvm.h [deleted file]
include/grub/macho.h [deleted file]
include/grub/machoload.h [deleted file]
include/grub/memory.h [deleted file]
include/grub/menu.h [deleted file]
include/grub/menu_viewer.h [deleted file]
include/grub/mips/at_keyboard.h [deleted file]
include/grub/mips/cache.h [deleted file]
include/grub/mips/cmos.h [deleted file]
include/grub/mips/io.h [deleted file]
include/grub/mips/kernel.h [deleted file]
include/grub/mips/multiboot.h [deleted file]
include/grub/mips/pci.h [deleted file]
include/grub/mips/qemu-mips/boot.h [deleted file]
include/grub/mips/qemu-mips/kernel.h [deleted file]
include/grub/mips/qemu-mips/loader.h [deleted file]
include/grub/mips/qemu-mips/memory.h [deleted file]
include/grub/mips/qemu-mips/serial.h [deleted file]
include/grub/mips/qemu-mips/time.h [deleted file]
include/grub/mips/relocator.h [deleted file]
include/grub/mips/setjmp.h [deleted file]
include/grub/mips/time.h [deleted file]
include/grub/mips/types.h [deleted file]
include/grub/mips/yeeloong/at_keyboard.h [deleted file]
include/grub/mips/yeeloong/boot.h [deleted file]
include/grub/mips/yeeloong/cmos.h [deleted file]
include/grub/mips/yeeloong/kernel.h [deleted file]
include/grub/mips/yeeloong/loader.h [deleted file]
include/grub/mips/yeeloong/memory.h [deleted file]
include/grub/mips/yeeloong/pci.h [deleted file]
include/grub/mips/yeeloong/serial.h [deleted file]
include/grub/mips/yeeloong/time.h [deleted file]
include/grub/misc.h [deleted file]
include/grub/mm.h [deleted file]
include/grub/msdos_partition.h [deleted file]
include/grub/multiboot.h [deleted file]
include/grub/multiboot_loader.h [deleted file]
include/grub/net.h [deleted file]
include/grub/normal.h [deleted file]
include/grub/ntfs.h [deleted file]
include/grub/parser.h [deleted file]
include/grub/partition.h [deleted file]
include/grub/parttool.h [deleted file]
include/grub/pci.h [deleted file]
include/grub/pciutils.h [deleted file]
include/grub/powerpc/ieee1275/biosdisk.h [deleted file]
include/grub/powerpc/ieee1275/console.h [deleted file]
include/grub/powerpc/ieee1275/ieee1275.h [deleted file]
include/grub/powerpc/ieee1275/kernel.h [deleted file]
include/grub/powerpc/ieee1275/loader.h [deleted file]
include/grub/powerpc/ieee1275/memory.h [deleted file]
include/grub/powerpc/ieee1275/time.h [deleted file]
include/grub/powerpc/ieee1275/util/biosdisk.h [deleted file]
include/grub/powerpc/kernel.h [deleted file]
include/grub/powerpc/setjmp.h [deleted file]
include/grub/powerpc/time.h [deleted file]
include/grub/powerpc/types.h [deleted file]
include/grub/raid.h [deleted file]
include/grub/reader.h [deleted file]
include/grub/script_sh.h [deleted file]
include/grub/scsi.h [deleted file]
include/grub/scsicmd.h [deleted file]
include/grub/sdl.h [deleted file]
include/grub/search.h [deleted file]
include/grub/serial.h [deleted file]
include/grub/setjmp.h [deleted file]
include/grub/sparc64/ieee1275/boot.h [deleted file]
include/grub/sparc64/ieee1275/console.h [deleted file]
include/grub/sparc64/ieee1275/ieee1275.h [deleted file]
include/grub/sparc64/ieee1275/kernel.h [deleted file]
include/grub/sparc64/ieee1275/loader.h [deleted file]
include/grub/sparc64/ieee1275/memory.h [deleted file]
include/grub/sparc64/ieee1275/time.h [deleted file]
include/grub/sparc64/kernel.h [deleted file]
include/grub/sparc64/setjmp.h [deleted file]
include/grub/sparc64/time.h [deleted file]
include/grub/sparc64/types.h [deleted file]
include/grub/symbol.h [deleted file]
include/grub/term.h [deleted file]
include/grub/terminfo.h [deleted file]
include/grub/test.h [deleted file]
include/grub/time.h [deleted file]
include/grub/tparm.h [deleted file]
include/grub/trig.h [deleted file]
include/grub/types.h [deleted file]
include/grub/usb.h [deleted file]
include/grub/usbdesc.h [deleted file]
include/grub/usbtrans.h [deleted file]
include/grub/util/console.h [deleted file]
include/grub/util/deviceiter.h [deleted file]
include/grub/util/getroot.h [deleted file]
include/grub/util/hostdisk.h [deleted file]
include/grub/util/lvm.h [deleted file]
include/grub/util/misc.h [deleted file]
include/grub/util/ofpath.h [deleted file]
include/grub/util/raid.h [deleted file]
include/grub/util/resolve.h [deleted file]
include/grub/video.h [deleted file]
include/grub/video_fb.h [deleted file]
include/grub/x86_64/at_keyboard.h [deleted file]
include/grub/x86_64/efi/kernel.h [deleted file]
include/grub/x86_64/efi/loader.h [deleted file]
include/grub/x86_64/efi/memory.h [deleted file]
include/grub/x86_64/efi/serial.h [deleted file]
include/grub/x86_64/efi/time.h [deleted file]
include/grub/x86_64/io.h [deleted file]
include/grub/x86_64/kernel.h [deleted file]
include/grub/x86_64/linux.h [deleted file]
include/grub/x86_64/macho.h [deleted file]
include/grub/x86_64/multiboot.h [deleted file]
include/grub/x86_64/pci.h [deleted file]
include/grub/x86_64/relocator.h [deleted file]
include/grub/x86_64/setjmp.h [deleted file]
include/grub/x86_64/time.h [deleted file]
include/grub/x86_64/types.h [deleted file]
include/grub/x86_64/xnu.h [deleted file]
include/grub/xnu.h [deleted file]
include/multiboot.h [deleted file]
include/multiboot2.h [deleted file]
io/bufio.c [deleted file]
io/gzio.c [deleted file]
kern/command.c [deleted file]
kern/corecmd.c [deleted file]
kern/device.c [deleted file]
kern/disk.c [deleted file]
kern/dl.c [deleted file]
kern/efi/efi.c [deleted file]
kern/efi/init.c [deleted file]
kern/efi/mm.c [deleted file]
kern/elf.c [deleted file]
kern/env.c [deleted file]
kern/err.c [deleted file]
kern/file.c [deleted file]
kern/fs.c [deleted file]
kern/generic/millisleep.c [deleted file]
kern/generic/rtc_get_time_ms.c [deleted file]
kern/handler.c [deleted file]
kern/i386/coreboot/init.c [deleted file]
kern/i386/coreboot/mmap.c [deleted file]
kern/i386/coreboot/startup.S [deleted file]
kern/i386/dl.c [deleted file]
kern/i386/efi/init.c [deleted file]
kern/i386/efi/startup.S [deleted file]
kern/i386/halt.c [deleted file]
kern/i386/ieee1275/init.c [deleted file]
kern/i386/ieee1275/startup.S [deleted file]
kern/i386/loader.S [deleted file]
kern/i386/misc.S [deleted file]
kern/i386/multiboot_mmap.c [deleted file]
kern/i386/pc/init.c [deleted file]
kern/i386/pc/lzma_decode.S [deleted file]
kern/i386/pc/mmap.c [deleted file]
kern/i386/pc/startup.S [deleted file]
kern/i386/pit.c [deleted file]
kern/i386/qemu/mmap.c [deleted file]
kern/i386/qemu/startup.S [deleted file]
kern/i386/realmode.S [deleted file]
kern/i386/tsc.c [deleted file]
kern/ieee1275/cmain.c [deleted file]
kern/ieee1275/ieee1275.c [deleted file]
kern/ieee1275/init.c [deleted file]
kern/ieee1275/mmap.c [deleted file]
kern/ieee1275/openfw.c [deleted file]
kern/list.c [deleted file]
kern/main.c [deleted file]
kern/mips/cache.S [deleted file]
kern/mips/cache_flush.S [deleted file]
kern/mips/dl.c [deleted file]
kern/mips/init.c [deleted file]
kern/mips/qemu-mips/init.c [deleted file]
kern/mips/startup.S [deleted file]
kern/mips/yeeloong/init.c [deleted file]
kern/misc.c [deleted file]
kern/mm.c [deleted file]
kern/parser.c [deleted file]
kern/partition.c [deleted file]
kern/powerpc/cache.S [deleted file]
kern/powerpc/dl.c [deleted file]
kern/powerpc/ieee1275/startup.S [deleted file]
kern/rescue_parser.c [deleted file]
kern/rescue_reader.c [deleted file]
kern/sparc64/cache.S [deleted file]
kern/sparc64/dl.c [deleted file]
kern/sparc64/ieee1275/crt0.S [deleted file]
kern/sparc64/ieee1275/ieee1275.c [deleted file]
kern/sparc64/ieee1275/init.c [deleted file]
kern/term.c [deleted file]
kern/time.c [deleted file]
kern/x86_64/dl.c [deleted file]
kern/x86_64/efi/callwrap.S [deleted file]
kern/x86_64/efi/startup.S [deleted file]
lib/LzFind.c [deleted file]
lib/LzmaDec.c [deleted file]
lib/LzmaEnc.c [deleted file]
lib/arg.c [deleted file]
lib/charset.c [deleted file]
lib/cmos_datetime.c [deleted file]
lib/crc.c [deleted file]
lib/crypto.c [deleted file]
lib/efi/datetime.c [deleted file]
lib/envblk.c [deleted file]
lib/hexdump.c [deleted file]
lib/i386/pc/biosnum.c [deleted file]
lib/i386/relocator.c [deleted file]
lib/i386/relocator_asm.S [deleted file]
lib/i386/relocator_backward.S [deleted file]
lib/i386/setjmp.S [deleted file]
lib/ieee1275/datetime.c [deleted file]
lib/libgcrypt/cipher/ChangeLog [deleted file]
lib/libgcrypt/cipher/ac.c [deleted file]
lib/libgcrypt/cipher/arcfour.c [deleted file]
lib/libgcrypt/cipher/bithelp.h [deleted file]
lib/libgcrypt/cipher/blowfish.c [deleted file]
lib/libgcrypt/cipher/camellia-glue.c [deleted file]
lib/libgcrypt/cipher/camellia.c [deleted file]
lib/libgcrypt/cipher/camellia.h [deleted file]
lib/libgcrypt/cipher/cast5.c [deleted file]
lib/libgcrypt/cipher/cipher.c [deleted file]
lib/libgcrypt/cipher/crc.c [deleted file]
lib/libgcrypt/cipher/des.c [deleted file]
lib/libgcrypt/cipher/dsa.c [deleted file]
lib/libgcrypt/cipher/ecc.c [deleted file]
lib/libgcrypt/cipher/elgamal.c [deleted file]
lib/libgcrypt/cipher/hash-common.c [deleted file]
lib/libgcrypt/cipher/hash-common.h [deleted file]
lib/libgcrypt/cipher/hmac-tests.c [deleted file]
lib/libgcrypt/cipher/md.c [deleted file]
lib/libgcrypt/cipher/md4.c [deleted file]
lib/libgcrypt/cipher/md5.c [deleted file]
lib/libgcrypt/cipher/primegen.c [deleted file]
lib/libgcrypt/cipher/pubkey.c [deleted file]
lib/libgcrypt/cipher/rfc2268.c [deleted file]
lib/libgcrypt/cipher/rijndael-tables.h [deleted file]
lib/libgcrypt/cipher/rijndael.c [deleted file]
lib/libgcrypt/cipher/rmd.h [deleted file]
lib/libgcrypt/cipher/rmd160.c [deleted file]
lib/libgcrypt/cipher/rsa.c [deleted file]
lib/libgcrypt/cipher/seed.c [deleted file]
lib/libgcrypt/cipher/serpent.c [deleted file]
lib/libgcrypt/cipher/sha1.c [deleted file]
lib/libgcrypt/cipher/sha256.c [deleted file]
lib/libgcrypt/cipher/sha512.c [deleted file]
lib/libgcrypt/cipher/tiger.c [deleted file]
lib/libgcrypt/cipher/twofish.c [deleted file]
lib/libgcrypt/cipher/whirlpool.c [deleted file]
lib/libgcrypt_wrap/cipher_wrap.h [deleted file]
lib/mips/relocator.c [deleted file]
lib/mips/relocator_asm.S [deleted file]
lib/mips/setjmp.S [deleted file]
lib/pbkdf2.c [deleted file]
lib/posix_wrap/assert.h [deleted file]
lib/posix_wrap/ctype.h [deleted file]
lib/posix_wrap/errno.h [deleted file]
lib/posix_wrap/langinfo.h [deleted file]
lib/posix_wrap/limits.h [deleted file]
lib/posix_wrap/localcharset.h [deleted file]
lib/posix_wrap/locale.h [deleted file]
lib/posix_wrap/stdint.h [deleted file]
lib/posix_wrap/stdio.h [deleted file]
lib/posix_wrap/stdlib.h [deleted file]
lib/posix_wrap/string.h [deleted file]
lib/posix_wrap/sys/types.h [deleted file]
lib/posix_wrap/unistd.h [deleted file]
lib/posix_wrap/wchar.h [deleted file]
lib/posix_wrap/wctype.h [deleted file]
lib/powerpc/setjmp.S [deleted file]
lib/relocator.c [deleted file]
lib/sparc64/setjmp.S [deleted file]
lib/x86_64/setjmp.S [deleted file]
loader/aout.c [deleted file]
loader/efi/appleloader.c [deleted file]
loader/efi/chainloader.c [deleted file]
loader/i386/bsd.c [deleted file]
loader/i386/bsd32.c [deleted file]
loader/i386/bsd64.c [deleted file]
loader/i386/bsdXX.c [deleted file]
loader/i386/bsd_helper.S [deleted file]
loader/i386/bsd_pagetable.c [deleted file]
loader/i386/bsd_trampoline.S [deleted file]
loader/i386/efi/linux.c [deleted file]
loader/i386/efi/xnu.c [deleted file]
loader/i386/ieee1275/linux.c [deleted file]
loader/i386/linux.c [deleted file]
loader/i386/linux_trampoline.S [deleted file]
loader/i386/multiboot_mbi.c [deleted file]
loader/i386/pc/chainloader.c [deleted file]
loader/i386/pc/linux.c [deleted file]
loader/i386/pc/xnu.c [deleted file]
loader/i386/xnu.c [deleted file]
loader/macho.c [deleted file]
loader/macho32.c [deleted file]
loader/macho64.c [deleted file]
loader/machoXX.c [deleted file]
loader/mips/linux.c [deleted file]
loader/multiboot.c [deleted file]
loader/multiboot_elfxx.c [deleted file]
loader/multiboot_mbi2.c [deleted file]
loader/powerpc/ieee1275/linux.c [deleted file]
loader/sparc64/ieee1275/linux.c [deleted file]
loader/xnu.c [deleted file]
loader/xnu_resume.c [deleted file]
mmap/efi/mmap.c [deleted file]
mmap/i386/mmap.c [deleted file]
mmap/i386/pc/mmap.c [deleted file]
mmap/i386/pc/mmap_helper.S [deleted file]
mmap/i386/uppermem.c [deleted file]
mmap/mips/yeeloong/uppermem.c [deleted file]
mmap/mmap.c [deleted file]
modules.def [new file with mode: 0644]
normal/auth.c [deleted file]
normal/autofs.c [deleted file]
normal/cmdline.c [deleted file]
normal/color.c [deleted file]
normal/completion.c [deleted file]
normal/context.c [deleted file]
normal/crypto.c [deleted file]
normal/datetime.c [deleted file]
normal/dyncmd.c [deleted file]
normal/handler.c [deleted file]
normal/main.c [deleted file]
normal/menu.c [deleted file]
normal/menu_entry.c [deleted file]
normal/menu_text.c [deleted file]
normal/misc.c [deleted file]
normal/term.c [deleted file]
partmap/acorn.c [deleted file]
partmap/amiga.c [deleted file]
partmap/apple.c [deleted file]
partmap/bsdlabel.c [deleted file]
partmap/gpt.c [deleted file]
partmap/msdos.c [deleted file]
partmap/sun.c [deleted file]
partmap/sunpc.c [deleted file]
parttool/msdospart.c [deleted file]
po/Makefile.am [new file with mode: 0644]
po/POTFILES [deleted file]
po/POTFILES-shell [deleted file]
po/README [deleted file]
script/execute.c [deleted file]
script/function.c [deleted file]
script/lexer.c [deleted file]
script/main.c [deleted file]
script/parser.y [deleted file]
script/script.c [deleted file]
script/yylex.l [deleted file]
term/at_keyboard.c [deleted file]
term/efi/console.c [deleted file]
term/gfxterm.c [deleted file]
term/i386/pc/console.c [deleted file]
term/i386/pc/vga.c [deleted file]
term/i386/pc/vga_text.c [deleted file]
term/i386/vga_common.c [deleted file]
term/ieee1275/ofconsole.c [deleted file]
term/serial.c [deleted file]
term/terminfo.c [deleted file]
term/tparm.c [deleted file]
term/usb_keyboard.c [deleted file]
tests/example_functional_test.c [deleted file]
tests/example_grub_script_test.in
tests/lib/functional_test.c [deleted file]
tests/lib/test.c [deleted file]
tests/lib/unit_test.c
tests/util/grub-shell-tester.in
tests/util/grub-shell.in
util/console.c [deleted file]
util/elf/grub-mkimage.c
util/getroot.c [deleted file]
util/grub-editenv.c
util/grub-emu.c [deleted file]
util/grub-fstest.c
util/grub-mkdevicemap.c
util/grub-mkfont.c
util/grub-mkpasswd-pbkdf2.c
util/grub-mkrawimage.c
util/grub-mkrelpath.c
util/grub-mkrescue.in
util/grub-probe.c
util/grub-script-check.c
util/hostdisk.c [deleted file]
util/hostfs.c [deleted file]
util/i386/efi/grub-mkimage.c
util/i386/pc/grub-setup.c
util/import_gcry.py [deleted file]
util/lvm.c
util/misc.c
util/pci.c [deleted file]
util/raid.c
util/resolve.c
util/sdl.c [deleted file]
util/sparc64/ieee1275/grub-setup.c
util/time.c [deleted file]
util/usb.c [deleted file]
video/bitmap.c [deleted file]
video/bitmap_scale.c [deleted file]
video/efi_gop.c [deleted file]
video/efi_uga.c [deleted file]
video/fb/fbblit.c [deleted file]
video/fb/fbfill.c [deleted file]
video/fb/fbutil.c [deleted file]
video/fb/video_fb.c [deleted file]
video/i386/pc/vbe.c [deleted file]
video/ieee1275.c [deleted file]
video/readers/jpeg.c [deleted file]
video/readers/png.c [deleted file]
video/readers/tga.c [deleted file]
video/sm712.c [deleted file]
video/video.c [deleted file]

index 46e8637b620652c5ce5298f8877d569c2e7abf4c..f91e72efa20e583e4c012313856916ca35b82757 100644 (file)
@@ -71,3 +71,9 @@ stamp-h.in
 symlist.c
 trigtables.c
 update-grub_lib
+Makefile.in
+modules.am
+GPATH
+GRTAGS
+GSYMS
+GTAGS
\ No newline at end of file
diff --git a/ABOUT-NLS b/ABOUT-NLS
new file mode 100644 (file)
index 0000000..866b904
--- /dev/null
+++ b/ABOUT-NLS
@@ -0,0 +1,223 @@
+1 Notes on the Free Translation Project
+***************************************
+
+Free software is going international!  The Free Translation Project is
+a way to get maintainers of free software, translators, and users all
+together, so that free software will gradually become able to speak many
+languages.  A few packages already provide translations for their
+messages.
+
+   If you found this `ABOUT-NLS' file inside a distribution, you may
+assume that the distributed package does use GNU `gettext' internally,
+itself available at your nearest GNU archive site.  But you do _not_
+need to install GNU `gettext' prior to configuring, installing or using
+this package with messages translated.
+
+   Installers will find here some useful hints.  These notes also
+explain how users should proceed for getting the programs to use the
+available translations.  They tell how people wanting to contribute and
+work on translations can contact the appropriate team.
+
+   When reporting bugs in the `intl/' directory or bugs which may be
+related to internationalization, you should tell about the version of
+`gettext' which is used.  The information can be found in the
+`intl/VERSION' file, in internationalized packages.
+
+1.1 Quick configuration advice
+==============================
+
+If you want to exploit the full power of internationalization, you
+should configure it using
+
+     ./configure --with-included-gettext
+
+to force usage of internationalizing routines provided within this
+package, despite the existence of internationalizing capabilities in the
+operating system where this package is being installed.  So far, only
+the `gettext' implementation in the GNU C library version 2 provides as
+many features (such as locale alias, message inheritance, automatic
+charset conversion or plural form handling) as the implementation here.
+It is also not possible to offer this additional functionality on top
+of a `catgets' implementation.  Future versions of GNU `gettext' will
+very likely convey even more functionality.  So it might be a good idea
+to change to GNU `gettext' as soon as possible.
+
+   So you need _not_ provide this option if you are using GNU libc 2 or
+you have installed a recent copy of the GNU gettext package with the
+included `libintl'.
+
+1.2 INSTALL Matters
+===================
+
+Some packages are "localizable" when properly installed; the programs
+they contain can be made to speak your own native language.  Most such
+packages use GNU `gettext'.  Other packages have their own ways to
+internationalization, predating GNU `gettext'.
+
+   By default, this package will be installed to allow translation of
+messages.  It will automatically detect whether the system already
+provides the GNU `gettext' functions.  If not, the included GNU
+`gettext' library will be used.  This library is wholly contained
+within this package, usually in the `intl/' subdirectory, so prior
+installation of the GNU `gettext' package is _not_ required.
+Installers may use special options at configuration time for changing
+the default behaviour.  The commands:
+
+     ./configure --with-included-gettext
+     ./configure --disable-nls
+
+will, respectively, bypass any pre-existing `gettext' to use the
+internationalizing routines provided within this package, or else,
+_totally_ disable translation of messages.
+
+   When you already have GNU `gettext' installed on your system and run
+configure without an option for your new package, `configure' will
+probably detect the previously built and installed `libintl.a' file and
+will decide to use this.  This might not be desirable.  You should use
+the more recent version of the GNU `gettext' library.  I.e. if the file
+`intl/VERSION' shows that the library which comes with this package is
+more recent, you should use
+
+     ./configure --with-included-gettext
+
+to prevent auto-detection.
+
+   The configuration process will not test for the `catgets' function
+and therefore it will not be used.  The reason is that even an
+emulation of `gettext' on top of `catgets' could not provide all the
+extensions of the GNU `gettext' library.
+
+   Internationalized packages usually have many `po/LL.po' files, where
+LL gives an ISO 639 two-letter code identifying the language.  Unless
+translations have been forbidden at `configure' time by using the
+`--disable-nls' switch, all available translations are installed
+together with the package.  However, the environment variable `LINGUAS'
+may be set, prior to configuration, to limit the installed set.
+`LINGUAS' should then contain a space separated list of two-letter
+codes, stating which languages are allowed.
+
+1.3 Using This Package
+======================
+
+As a user, if your language has been installed for this package, you
+only have to set the `LANG' environment variable to the appropriate
+`LL_CC' combination.  Here `LL' is an ISO 639 two-letter language code,
+and `CC' is an ISO 3166 two-letter country code.  For example, let's
+suppose that you speak German and live in Germany.  At the shell
+prompt, merely execute `setenv LANG de_DE' (in `csh'),
+`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash').
+This can be done from your `.login' or `.profile' file, once and for
+all.
+
+   You might think that the country code specification is redundant.
+But in fact, some languages have dialects in different countries.  For
+example, `de_AT' is used for Austria, and `pt_BR' for Brazil.  The
+country code serves to distinguish the dialects.
+
+   The locale naming convention of `LL_CC', with `LL' denoting the
+language and `CC' denoting the country, is the one use on systems based
+on GNU libc.  On other systems, some variations of this scheme are
+used, such as `LL' or `LL_CC.ENCODING'.  You can get the list of
+locales supported by your system for your language by running the
+command `locale -a | grep '^LL''.
+
+   Not all programs have translations for all languages.  By default, an
+English message is shown in place of a nonexistent translation.  If you
+understand other languages, you can set up a priority list of languages.
+This is done through a different environment variable, called
+`LANGUAGE'.  GNU `gettext' gives preference to `LANGUAGE' over `LANG'
+for the purpose of message handling, but you still need to have `LANG'
+set to the primary language; this is required by other parts of the
+system libraries.  For example, some Swedish users who would rather
+read translations in German than English for when Swedish is not
+available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'.
+
+   Special advice for Norwegian users: The language code for Norwegian
+bokma*l changed from `no' to `nb' recently (in 2003).  During the
+transition period, while some message catalogs for this language are
+installed under `nb' and some older ones under `no', it's recommended
+for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and
+older translations are used.
+
+   In the `LANGUAGE' environment variable, but not in the `LANG'
+environment variable, `LL_CC' combinations can be abbreviated as `LL'
+to denote the language's main dialect.  For example, `de' is equivalent
+to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT'
+(Portuguese as spoken in Portugal) in this context.
+
+1.4 Translating Teams
+=====================
+
+For the Free Translation Project to be a success, we need interested
+people who like their own language and write it well, and who are also
+able to synergize with other translators speaking the same language.
+Each translation team has its own mailing list.  The up-to-date list of
+teams can be found at the Free Translation Project's homepage,
+`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams"
+area.
+
+   If you'd like to volunteer to _work_ at translating messages, you
+should become a member of the translating team for your own language.
+The subscribing address is _not_ the same as the list itself, it has
+`-request' appended.  For example, speakers of Swedish can send a
+message to `sv-request@li.org', having this message body:
+
+     subscribe
+
+   Keep in mind that team members are expected to participate
+_actively_ in translations, or at solving translational difficulties,
+rather than merely lurking around.  If your team does not exist yet and
+you want to start one, or if you are unsure about what to do or how to
+get started, please write to `translation@iro.umontreal.ca' to reach the
+coordinator for all translator teams.
+
+   The English team is special.  It works at improving and uniformizing
+the terminology in use.  Proven linguistic skills are praised more than
+programming skills, here.
+
+1.5 Available Packages
+======================
+
+Languages are not equally supported in all packages.  The following
+matrix shows the current state of internationalization, as of October
+2006.  The matrix shows, in regard of each package, for which languages
+PO files have been submitted to translation coordination, with a
+translation percentage of at least 50%.
+
+# Matrix here is removed!
+
+   Some counters in the preceding matrix are higher than the number of
+visible blocks let us expect.  This is because a few extra PO files are
+used for implementing regional variants of languages, or language
+dialects.
+
+   For a PO file in the matrix above to be effective, the package to
+which it applies should also have been internationalized and
+distributed as such by its maintainer.  There might be an observable
+lag between the mere existence a PO file and its wide availability in a
+distribution.
+
+   If October 2006 seems to be old, you may fetch a more recent copy of
+this `ABOUT-NLS' file on most GNU archive sites.  The most up-to-date
+matrix with full percentage details can be found at
+`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'.
+
+1.6 Using `gettext' in new packages
+===================================
+
+If you are writing a freely available program and want to
+internationalize it you are welcome to use GNU `gettext' in your
+package.  Of course you have to respect the GNU Library General Public
+License which covers the use of the GNU `gettext' library.  This means
+in particular that even non-free programs can use `libintl' as a shared
+library, whereas only free software can use `libintl' as a static
+library or use modified versions of `libintl'.
+
+   Once the sources are changed appropriately and the setup can handle
+the use of `gettext' the only thing missing are the translations.  The
+Free Translation Project is also available for packages which are not
+developed inside the GNU project.  Therefore the information given above
+applies also for every other Free Software Project.  Contact
+`translation@iro.umontreal.ca' to make the `.pot' files available to
+the translation teams.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..d962963
--- /dev/null
@@ -0,0 +1,87 @@
+AUTOMAKE_OPTIONS = subdir-objects
+DEPDIR = .deps-util
+
+EXTRA_DIST = autogen.sh gentpl.py Makefile.tpl modules.def             \
+                                                                       \
+       geninit.sh                                                      \
+                                                                       \
+       gnulib/progname.h gnulib/fnmatch_loop.c gnulib/alloca.h         \
+       gnulib/error.h gnulib/fnmatch.h gnulib/getopt.h                 \
+       gnulib/getopt_int.h gnulib/gettext.h gnulib/progname.h          \
+                                                                       \
+       util/mkisofs/mkisofs.h util/mkisofs/iso9660.h                   \
+       util/mkisofs/include/prototyp.h util/mkisofs/defaults.h         \
+       util/mkisofs/match.h util/mkisofs/exclude.h                     \
+       util/mkisofs/msdos_partition.h util/mkisofs/include/fctldefs.h  \
+       util/mkisofs/include/mconfig.h util/mkisofs/include/statdefs.h
+
+SUBDIRS = . grub-core po docs
+
+include $(top_srcdir)/grub-core/Makefile.vars
+
+CFLAGS_PROGRAM = $(HOST_CFLAGS) $(CFLAGS_GNULIB)
+LDFLAGS_PROGRAM = $(HOST_LDFLAGS) $(LDFLAGS_GNULIB) $(LIBINTL)
+CPPFLAGS_PROGRAM = $(HOST_CPPFLAGS) $(CPPFLAGS_GNULIB)
+CCASFLAGS_PROGRAM = $(HOST_CCASFLAGS) $(CCASFLAGS_GNULIB)
+
+CFLAGS_LIBRARY = $(CFLAGS_PROGRAM)
+CPPFLAGS_LIBRARY = $(CPPFLAGS_PROGRAM)
+CCASFLAGS_LIBRARY = $(CCASFLAGS_PROGRAM)
+
+AM_CFLAGS =
+AM_LDFLAGS =
+AM_CPPFLAGS = $(CPPFLAGS_GRUB) -DGRUB_FILE=\"$(subst $(top_srcdir)/,,$<)\"
+AM_CCASFLAGS = -DASM_FILE=1
+
+# XXX Use Automake's LEX & YACC support
+grub_script.tab.c grub_script.tab.h: $(top_srcdir)/grub-core/script/parser.y
+       $(YACC) -d -p grub_script_yy -b grub_script $(top_srcdir)/grub-core/script/parser.y
+CLEANFILES += grub_script.tab.c grub_script.tab.h
+
+# For the lexer.
+grub_script.yy.c grub_script.yy.h: $(top_srcdir)/grub-core/script/yylex.l
+       $(LEX) -o grub_script.yy.c --header-file=grub_script.yy.h $(top_srcdir)/grub-core/script/yylex.l
+CLEANFILES += grub_script.yy.c grub_script.yy.h
+
+# For libutil.a
+libutil_a_init.lst: grub_script.tab.h grub_script.yy.h $(libutil_a_SOURCES)
+       rm -f $@
+       $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libutil_a_CPPFLAGS) $(CPPFLAGS) \
+         -D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ \
+         | grep '@MARKER@' | sed 's/@MARKER@\(.*\)@/\1/g' | sort -u > $@ || (rm -f $@; exit 1)
+CLEANFILES += libutil_a_init.lst
+
+libutil_a_init.c: libutil_a_init.lst $(top_srcdir)/geninit.sh
+       rm -f $@; sh $(top_srcdir)/geninit.sh `cat $<` > $@ || (rm -f $@; exit 1)
+CLEANFILES += libutil_a_init.c
+
+if COND_GRUB_MKFONT
+if COND_HAVE_FONT_SOURCE
+pkgdata_DATA = unicode.pf2 ascii.pf2 ascii.h
+endif
+endif
+
+unicode.pf2: $(FONT_SOURCE) grub-mkfont
+       $(builddir)/grub-mkfont -o $@ $(FONT_SOURCE)
+CLEANFILES += unicode.pf2
+
+# Arrows and lines are needed to draw the menu, so always include them
+UNICODE_ARROWS=0x2190-0x2193
+UNICODE_LINES=0x2501-0x251B
+
+ascii.pf2: $(FONT_SOURCE) grub-mkfont
+       $(builddir)/grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES)
+CLEANFILES += ascii.pf2
+
+ascii.bitmaps: $(FONT_SOURCE) grub-mkfont
+       $(builddir)/grub-mkfont --ascii-bitmaps -o $@ $(FONT_SOURCE)
+CLEANFILES += ascii.bitmaps
+
+ascii.h: ascii.bitmaps grub-bin2h
+       $(builddir)/grub-bin2h ascii_bitmaps < $< > $@
+       cp $@ $(top_builddir)/grub-core/include
+CLEANFILES += ascii.h $(top_builddir)/grub-core/include/ascii.h
+
+platform_HEADERS = config.h
+
+include $(srcdir)/modules.am
diff --git a/Makefile.in b/Makefile.in
deleted file mode 100644 (file)
index 822a087..0000000
+++ /dev/null
@@ -1,564 +0,0 @@
-# -*- makefile -*-
-#
-# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,2002,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
-#
-# This Makefile.in is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-### The configure script will replace these variables.
-
-SHELL = /bin/sh
-
-@SET_MAKE@
-
-transform = @program_transform_name@
-
-srcdir = @srcdir@
-builddir = @builddir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-
-bindir = @bindir@
-sbindir = @sbindir@
-libexecdir = @libexecdir@
-datarootdir = @datarootdir@
-datadir = @datadir@
-sysconfdir = @sysconfdir@
-sharedstatedir = @sharedstatedir@
-localstatedir = @localstatedir@
-libdir = @libdir@
-localedir = @localedir@
-infodir = @infodir@
-mandir = @mandir@
-includedir = @includedir@
-pkgdatadir = $(datadir)/`echo @PACKAGE_TARNAME@ | sed '$(transform)'`
-pkglibdir =  $(libdir)/`echo @PACKAGE_TARNAME@/$(target_cpu)-$(platform) | sed '$(transform)'`
-
-# Internationalization library.
-LIBINTL = @LIBINTL@
-TARGET_NO_MODULES = @TARGET_NO_MODULES@
-
-# Util library.
-LIBUTIL = @LIBUTIL@
-
-XGETTEXT = @XGETTEXT@
-MSGMERGE = @MSGMERGE@
-MSGFMT = @MSGFMT@
-
-LINGUAS = $(shell for i in $(srcdir)/po/*.po ; do \
-                       if test -e $$i ; then echo $$i ; fi ; \
-               done | sed -e "s,.*/po/\(.*\)\.po$$,\1,")
-
-PACKAGE = @PACKAGE@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-
-host_os = @host_os@
-host_kernel = @host_kernel@
-host_cpu = @host_cpu@
-
-target_cpu = @target_cpu@
-platform = @platform@
-
-INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-MKDIR_P = @MKDIR_P@
-
-mkinstalldirs = $(srcdir)/mkinstalldirs
-
-LIBS = @LIBS@ $(LIBINTL) $(LIBUTIL)
-
-CC = @CC@
-CFLAGS = @CFLAGS@
-POSIX_CFLAGS = -I$(srcdir)/lib/posix_wrap 
-GNULIB_UTIL_CFLAGS = -Wno-undef -Wno-sign-compare -Wno-unused -D_GL_UNUSED="__attribute__ ((unused))" -I$(srcdir)/gnulib
-GNULIB_CFLAGS = $(GNULIB_UTIL_CFLAGS) $(POSIX_CFLAGS)
-ASFLAGS = @ASFLAGS@
-LDFLAGS = @LDFLAGS@ $(LIBS)
-CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/gnulib -I$(srcdir)/include -Wall -W \
-        -DGRUB_LIBDIR=\"$(pkglibdir)\" -DLOCALEDIR=\"$(localedir)\"
-TARGET_CC = @TARGET_CC@
-TARGET_CFLAGS = -ffreestanding @TARGET_CFLAGS@
-TARGET_ASFLAGS = -nostdinc -fno-builtin @TARGET_ASFLAGS@
-TARGET_MODULE_FORMAT = @TARGET_MODULE_FORMAT@
-TARGET_APPLE_CC = @TARGET_APPLE_CC@
-OBJCONV = @OBJCONV@
-TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I$(srcdir)/include -I$(builddir) -I$(builddir)/include \
-       -Wall -W
-TARGET_LDFLAGS = -nostdlib -static-libgcc @TARGET_LDFLAGS@
-TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@
-TARGET_IMG_LDFLAGS = -nostdlib @TARGET_IMG_LDFLAGS@
-TARGET_IMG_CFLAGS = @TARGET_IMG_CFLAGS@
-TARGET_OBJ2ELF = @TARGET_OBJ2ELF@
-kernel_img_LDFLAGS = -lgcc
-EXEEXT = @EXEEXT@
-OBJCOPY = @OBJCOPY@
-STRIP = @STRIP@
-NM = @NM@
-RUBY = @RUBY@
-MAKEINFO = @MAKEINFO@
-ifeq (, $(MAKEINFO))
-MAKEINFO = true
-endif
-HELP2MAN = @HELP2MAN@
-ifeq (, $(HELP2MAN))
-HELP2MAN = true
-else
-HELP2MAN := LANG=C $(HELP2MAN) --no-info --source=FSF
-endif
-AWK = @AWK@
-LIBCURSES = @LIBCURSES@
-LIBUSB = @LIBUSB@
-LIBSDL = @LIBSDL@
-LIBPCIACCESS = @LIBPCIACCESS@
-LEX = @LEX@
-YACC = @YACC@
-FONT_SOURCE = @FONT_SOURCE@
-
-# Options.
-enable_grub_emu_usb = @enable_grub_emu_usb@
-enable_grub_emu_sdl = @enable_grub_emu_sdl@
-enable_grub_emu_pci = @enable_grub_emu_pci@
-enable_grub_fstest = @enable_grub_fstest@
-enable_grub_pe2elf = @enable_grub_pe2elf@
-enable_grub_mkfont = @enable_grub_mkfont@
-freetype_cflags = @freetype_cflags@
-freetype_libs = @freetype_libs@
-enable_efiemu = @enable_efiemu@
-
-### General variables.
-
-RMKFILES = $(wildcard $(srcdir)/conf/*.rmk)
-
-MKFILES = $(patsubst %.rmk,%.mk,$(RMKFILES))
-
-PKGLIB = $(pkglib_IMAGES) $(pkglib_MODULES) $(pkglib_PROGRAMS) \
-       $(pkglib_DATA) $(pkglib_BUILDDIR)
-PKGDATA = $(pkgdata_DATA)
-PROGRAMS = $(bin_UTILITIES) $(sbin_UTILITIES)
-SCRIPTS = $(bin_SCRIPTS) $(sbin_SCRIPTS) $(grub-mkconfig_SCRIPTS) \
-       $(lib_SCRIPTS)
-INFOS = $(info_INFOS)
-
-CLEANFILES =
-MOSTLYCLEANFILES =
-DISTCLEANFILES = config.status config.cache config.log config.h \
-       Makefile stamp-h stamp-h1 include/grub/cpu include/grub/machine \
-       gensymlist.sh genkernsyms.sh build_env.mk \
-       docs/grub.info docs/version.texi docs/stamp-vti
-
-MAINTAINER_CLEANFILES = $(srcdir)/configure $(srcdir)/aclocal.m4 \
-       $(MKFILES) $(srcdir)/config.guess \
-       $(srcdir)/config.sub $(srcdir)/install-sh $(srcdir)/missing \
-       $(srcdir)/DISTLIST $(srcdir)/config.h.in $(srcdir)/stamp-h.in $(INFOS)
-
-# The default target.
-all: all-local
-
-### Include an arch-specific Makefile.
-$(addprefix $(srcdir)/,$(MKFILES)): %.mk: %.rmk genmk.rb
-       if test "x$(RUBY)" = x; then \
-         touch $@; \
-       else \
-         $(RUBY) $(srcdir)/genmk.rb < $< > $@; \
-       fi
-
-ifeq ($(platform), emu)
-include $(srcdir)/conf/any-emu.mk
-else
-include $(srcdir)/conf/$(target_cpu)-$(platform).mk
-# For tests.
-include $(srcdir)/conf/tests.mk
-# For external modules.
--include $(wildcard $(GRUB_CONTRIB)/*/conf/common.mk)
-endif
-
-ifeq ($(TARGET_NO_MODULES), yes)
-       TARGET_CFLAGS += -DGRUB_TARGET_NO_MODULES=1
-       CFLAGS += -DGRUB_TARGET_NO_MODULES=1
-endif
-
-### General targets.
-
-CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA) po/*.mo
-ifneq ($(TARGET_NO_MODULES), yes)
-pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst
-endif
-moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep.awk
-       cat $(DEFSYMFILES) /dev/null \
-         | $(AWK) -f $(srcdir)/genmoddep.awk $(UNDSYMFILES) > $@ \
-         || (rm -f $@; exit 1)
-
-command.lst: $(COMMANDFILES)
-       cat $^ /dev/null | sort > $@
-
-fs.lst: $(FSFILES)
-       cat $^ /dev/null | sort > $@
-
-partmap.lst: $(PARTMAPFILES)
-       cat $^ /dev/null | sort > $@
-
-handler.lst: $(HANDLERFILES)
-       cat $^ /dev/null | sort > $@
-
-terminal.lst: $(TERMINALFILES)
-       cat $^ /dev/null | sort > $@
-
-parttool.lst: $(PARTTOOLFILES)
-       cat $^ /dev/null | sort | uniq > $@
-
-video.lst: $(VIDEOFILES)
-       cat $^ /dev/null | sort | uniq > $@
-
-crypto.lst: lib/libgcrypt-grub/cipher/crypto.lst
-       cp $^ $@
-
-ifneq (true, $(MAKEINFO))
-info_INFOS += docs/grub.info
-endif
-
-MOSTLYCLEANFILES += vti.tmp
-MAINTAINER_CLEANFILES += docs/stamp-vti docs/version.texi
-docs/version.texi: docs/stamp-vti
-docs/stamp-vti: docs/grub.texi configure.ac
-       $(MKDIR_P) docs
-       (set `$(SHELL) $(srcdir)/docs/mdate-sh $<`; \
-       echo "@set UPDATED $$1 $$2 $$3"; \
-       echo "@set UPDATED-MONTH $$2 $$3"; \
-       echo "@set EDITION $(PACKAGE_VERSION)"; \
-       echo "@set VERSION $(PACKAGE_VERSION)") > vti.tmp
-       @cmp -s vti.tmp $(builddir)/docs/version.texi \
-         || (echo "Updating $(builddir)/docs/version.texi"; \
-             cp vti.tmp $(builddir)/docs/version.texi)
-       -@rm -f vti.tmp
-       @cp $(builddir)/docs/version.texi $@
-
-# Use --force until such time as the documentation is cleaned up.
-docs/grub.info: docs/grub.texi docs/version.texi docs/fdl.texi
-       $(MKDIR_P) docs
-       -$(MAKEINFO) -P $(builddir)/docs --no-split --force $< -o $@
-
-ifeq (, $(FONT_SOURCE))
-else
-
-ifeq ($(enable_grub_mkfont),yes)
-
-pkgdata_DATA += unicode.pf2 ascii.pf2 ascii.h
-CLEANFILES += ascii.bitmaps
-
-# Arrows and lines are needed to draw the menu, so we always include them
-UNICODE_ARROWS=0x2190-0x2193
-UNICODE_LINES=0x2501-0x251B
-
-unicode.pf2: $(FONT_SOURCE) grub-mkfont
-       $(builddir)/grub-mkfont -o $@ $(FONT_SOURCE)
-
-ascii.pf2: $(FONT_SOURCE) grub-mkfont
-       $(builddir)/grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES)
-
-ascii.bitmaps: $(FONT_SOURCE) grub-mkfont
-       $(builddir)/grub-mkfont --ascii-bitmaps -o $@ $(FONT_SOURCE)
-
-ascii.h: ascii.bitmaps grub-bin2h
-       $(builddir)/grub-bin2h ascii_bitmaps < $< > $@
-
-TARGET_CFLAGS += -DUSE_ASCII_FAILBACK=1
-endif
-endif
-
-# Used for building modules externally
-pkglib_BUILDDIR += build_env.mk
-build_env.mk: Makefile
-       (\
-       echo "TARGET_CC=$(TARGET_CC)" ; \
-       echo "TARGET_CFLAGS=$(TARGET_CFLAGS)" ; \
-       echo "TARGET_ASFLAGS=$(TARGET_ASFLAGS)" ; \
-       echo "TARGET_CPPFLAGS=$(TARGET_CPPFLAGS) -I$(pkglibdir) -I$(includedir)" ; \
-       echo "STRIP=$(STRIP)" ; \
-       echo "OBJCONV=$(OBJCONV)" ; \
-       echo "TARGET_MODULE_FORMAT=$(TARGET_MODULE_FORMAT)" ; \
-       echo "TARGET_APPLE_CC=$(TARGET_APPLE_CC)" ; \
-       echo "COMMON_ASFLAGS=$(COMMON_ASFLAGS)" ; \
-       echo "COMMON_CFLAGS=$(COMMON_CFLAGS)" ; \
-       echo "COMMON_LDFLAGS=$(COMMON_LDFLAGS)"\
-       ) > $@
-pkglib_BUILDDIR += config.h grub_script.tab.h
-
-all-local: $(PROGRAMS) $(GRUB_EMU) $(PKGLIB) $(PKGDATA) $(SCRIPTS) $(INFOS) $(MKFILES) $(foreach lang, $(LINGUAS), po/$(lang).mo)
-
-install: install-local
-
-install-local: all
-       $(SHELL) $(mkinstalldirs) $(DESTDIR)$(pkglibdir)
-       rm -f $(DESTDIR)$(pkglibdir)/*
-       @list='$(PKGLIB)'; \
-       for file in $$list; do \
-         if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
-         dest="`echo $$file | sed 's,.*/,,'`"; \
-         $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(pkglibdir)/$$dest; \
-       done
-       $(SHELL) $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
-       @list='$(PKGDATA)'; \
-       for file in $$list; do \
-         if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
-         dest="`echo $$file | sed 's,.*/,,'`"; \
-         $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(pkgdatadir)/$$dest; \
-       done
-       $(SHELL) $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man1
-       @list='$(bin_UTILITIES) $(GRUB_EMU)'; for file in $$list; do \
-         if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
-         dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
-         $(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \
-         $(HELP2MAN) --section=1 -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \
-       done
-       $(SHELL) $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8
-       @list='$(sbin_UTILITIES)'; for file in $$list; do \
-         if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
-         dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
-         $(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \
-         $(HELP2MAN) --section=8 -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \
-       done
-       @list='$(bin_SCRIPTS)'; for file in $$list; do \
-         if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
-         dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
-         $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \
-         $(HELP2MAN) --section=1 -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \
-       done
-       @list='$(sbin_SCRIPTS)'; for file in $$list; do \
-         if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
-         dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
-         $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \
-         $(HELP2MAN) --section=8 -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \
-       done
-       $(SHELL) $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/grub.d
-       @list='$(grub-mkconfig_SCRIPTS)'; for file in $$list; do \
-         if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
-         dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
-         $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(sysconfdir)/grub.d/$$dest; \
-       done
-       @list='$(grub-mkconfig_DATA)'; for file in $$list; do \
-         if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
-         dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
-         $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(sysconfdir)/grub.d/$$dest; \
-       done
-       $(SHELL) $(mkinstalldirs) $(DESTDIR)$(libdir)/grub
-       @list='$(lib_SCRIPTS)'; \
-       for file in $$list; do \
-         if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
-         dest="`echo $$file | sed 's,.*/,,'`"; \
-         $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(libdir)/grub/$$dest; \
-       done
-       @langs='$(LINGUAS)'; \
-       for lang in $$langs; do \
-         $(SHELL) $(mkinstalldirs) $(DESTDIR)/$(datadir)/locale/$$lang/LC_MESSAGES; \
-         file="po/$$lang.mo"; \
-         if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
-         $(INSTALL_DATA) $$dir$$file $(DESTDIR)/$(datadir)/locale/$$lang/LC_MESSAGES/$(PACKAGE).mo; \
-       done
-       $(SHELL) $(mkinstalldirs) $(DESTDIR)$(infodir)
-       @list='$(info_INFOS)'; \
-       for file in $$list; do \
-         if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \
-         dest="`echo $$file | sed 's,.*/,,'`"; \
-         $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(infodir); \
-         if (install-info --version && \
-              install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
-           install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$dest" || :; \
-         fi; \
-       done
-
-install-strip:
-       $(MAKE) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" install
-
-uninstall:
-       @list='$(PKGLIB)'; \
-       for file in $$list; do \
-         dest="`echo $$file | sed 's,.*/,,'`"; \
-         rm -f $(DESTDIR)$(pkglibdir)/$$dest; \
-       done
-       @list='$(PKGDATA)'; \
-       for file in $$list; do \
-         dest="`echo $$file | sed 's,.*/,,'`"; \
-         rm -f $(DESTDIR)$(pkgdatadir)/$$dest; \
-       done
-       @list='$(bin_UTILITIES) $(bin_SCRIPTS) $(GRUB_EMU)'; for file in $$list; do \
-         dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
-         rm -f $(DESTDIR)$(bindir)/$$dest; \
-         rm -f $(DESTDIR)$(mandir)/man1/$$dest.1; \
-       done
-       @list='$(sbin_UTILITIES) $(sbin_SCRIPTS)'; for file in $$list; do \
-         dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
-         rm -f $(DESTDIR)$(sbindir)/$$dest; \
-         rm -f $(DESTDIR)$(mandir)/man8/$$dest.8; \
-       done
-       @list='$(grub-mkconfig_SCRIPTS) $(grub-mkconfig_DATA)'; for file in $$list; do \
-         dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \
-         rm -f $(DESTDIR)$(sysconfdir)/grub.d/$$dest; \
-       done
-       @list='$(lib_SCRIPTS)'; \
-       for file in $$list; do \
-         dest="`echo $$file | sed 's,.*/,,'`"; \
-         rm -f $(DESTDIR)$(libdir)/grub/$$dest; \
-       done
-       @list='$(info_INFOS)'; \
-       for file in $$list; do \
-         dest="`echo $$file | sed 's,.*/,,'`"; \
-         if (install-info --version && \
-              install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
-           if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$dest"; then \
-             :; \
-           else \
-             test ! -f "$(DESTDIR)$(infodir)/$$dest" || exit 1; \
-           fi; \
-         fi; \
-         rm -f $(DESTDIR)$(infodir)/$$dest; \
-       done
-
-clean: $(CLEAN_IMAGE_TARGETS) $(CLEAN_MODULE_TARGETS) $(CLEAN_UTILITY_TARGETS)
-       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-
-mostlyclean: clean $(MOSTLYCLEAN_IMAGE_TARGETS) $(MOSTLYCLEAN_MODULE_TARGETS) $(MOSTLYCLEAN_UTILITY_TARGETS)
-       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
-
-distclean: mostlyclean
-       -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
-       -rm -rf $(srcdir)/autom4te.cache
-
-maintainer-clean: distclean
-       -test -z "$(MAINTAINER_CLEANFILES)" || rm -f $(MAINTAINER_CLEANFILES)
-       -rmdir $(srcdir)/lib/libgcrypt-grub/cipher
-       -rmdir $(srcdir)/lib/libgcrypt-grub
-
-info:
-
-dvi:
-
-distdir=$(PACKAGE_TARNAME)-$(PACKAGE_VERSION)
-
-DISTLIST: gendistlist.sh
-       $(SHELL) $(srcdir)/gendistlist.sh > $(srcdir)/DISTLIST
-
-distdir: DISTLIST
-       -chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir)
-       $(SHELL) $(mkinstalldirs) $(distdir)
-       for i in `cat $(srcdir)/DISTLIST`; do \
-         dir=`echo "$$i" | sed 's:/[^/]*$$::'`; \
-         if test -d $(srcdir)/$$dir; then \
-           $(SHELL) $(mkinstalldirs) $(distdir)/$$dir; \
-         fi; \
-         cp -p $(srcdir)/$$i $(distdir)/$$i || exit 1; \
-       done
-       chmod -R a+r $(distdir)
-
-GZIP_ENV = --best
-
-dist: distdir
-       tar chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
-       -chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir)
-
-distcheck: dist
-       -chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir)
-       GZIP=$(GZIP_ENV) gzip -cd $(distdir).tar.gz | tar xf -
-       chmod -R a-w $(distdir)
-       chmod a+w $(distdir)
-       mkdir $(distdir)/=build
-       mkdir $(distdir)/=inst
-       chmod a-w $(distdir)
-       dc_instdir=`CDPATH=: && cd $(distdir)/=inst && pwd` \
-         && cd $(distdir)/=build \
-         && $(SHELL) ../configure --srcdir=.. --prefix=$$dc_instdir \
-         && $(MAKE) all dvi check install && $(MAKE) uninstall \
-         && (test `find $$dc_instdir -type f -print | wc -l` -le 1 \
-            || (echo "Error: files left after uninstall" 1>&2; \
-                exit 1)) \
-         && $(MAKE) dist && $(MAKE) distclean \
-         && rm -f $(distdir).tar.gz \
-         && (test `find . -type f -print | wc -l` -eq 0 \
-            || (echo "Error: files left after distclean" 1>&2; \
-                exit 1))
-       -chmod -R a+w $(distdir) > /dev/null 2>&1; rm -rf $(distdir)
-       @echo "$(distdir).tar.gz is ready for distribution" | \
-         sed 'h;s/./=/g;p;x;p;x'
-
-check: all $(UNIT_TESTS) $(FUNCTIONAL_TESTS) $(SCRIPTED_TESTS)
-       @list="$(UNIT_TESTS)"; \
-       set -e; \
-       for file in $$list; do \
-         $(builddir)/$$file; \
-       done
-       @list="$(FUNCTIONAL_TESTS)"; \
-       set -e; \
-       for file in $$list; do \
-         mod=`basename $$file .mod`; \
-         echo "insmod functional_test; insmod $$mod; functional_test" \
-           | $(builddir)/grub-shell; \
-       done
-       @list="$(SCRIPTED_TESTS)"; \
-       set -e; \
-       for file in $$list; do \
-         $(builddir)/$$file; \
-       done
-
-.SUFFIX:
-.SUFFIX: .c .o .S .d
-
-# Regenerate configure and Makefile automatically.
-$(srcdir)/aclocal.m4: configure.ac acinclude.m4
-       cd $(srcdir) && aclocal
-
-$(srcdir)/configure: configure.ac aclocal.m4
-       cd $(srcdir) && autoconf
-
-$(srcdir)/config.h.in: stamp-h.in
-$(srcdir)/stamp-h.in: configure.ac aclocal.m4
-       cd $(srcdir) && autoheader
-       echo timestamp > $(srcdir)/stamp-h.in
-
-config.h: stamp-h
-stamp-h: config.h.in config.status
-       $(SHELL) ./config.status
-
-Makefile: Makefile.in config.status
-       $(SHELL) ./config.status
-
-config.status: configure
-       $(SHELL) ./config.status --recheck
-
-gensymlist.sh: gensymlist.sh.in config.status
-       $(SHELL) ./config.status
-
-genkernsyms.sh: genkernsyms.sh.in config.status
-       $(SHELL) ./config.status
-
-$(srcdir)/po/$(PACKAGE).pot: po/POTFILES po/POTFILES-shell
-       cd $(srcdir) && $(XGETTEXT) -ctranslate --from-code=utf-8 -o po/$(PACKAGE).pot -f po/POTFILES --keyword=_ --keyword=N_
-       cd $(srcdir) && $(XGETTEXT) -ctranslate --from-code=utf-8 -o po/$(PACKAGE).pot -f po/POTFILES-shell -j --language=Shell
-
-$(foreach lang, $(LINGUAS), $(srcdir)/po/$(lang).po): po/$(PACKAGE).pot
-       $(MSGMERGE) -U $@ $^
-
-po/%.mo: po/%.po
-       $(MKDIR_P) $$(dirname $@)
-       $(MSGFMT) -c --statistics -o $@ $^
-
-.PHONY: all install install-strip uninstall clean mostlyclean distclean
-.PHONY: maintainer-clean info dvi dist check
-
-# Prevent an overflow.
-.NOEXPORT:
-
-.DELETE_ON_ERROR:
index eb251f9f08575942c4592aa860c84f2c0fb4a0dc..5358d45f1eb9b5277d22b352a827617133d3ed96 100755 (executable)
@@ -2,22 +2,33 @@
 
 set -e
 
-aclocal
-autoconf
-autoheader
+ln -sf ../NEWS             grub-core/
+ln -sf ../README           grub-core/
+ln -sf ../INSTALL          grub-core/
+ln -sf ../AUTHORS          grub-core/
+ln -sf ../COPYING          grub-core/
+ln -sf ../ABOUT-NLS        grub-core/
+ln -sf ../ChangeLog        grub-core/
+ln -sf ../aclocal.m4       grub-core/
+ln -sf ../acinclude.m4     grub-core/
+ln -sf ../config.rpath     grub-core/
+ln -sf ../gentpl.py        grub-core/
+ln -sf ../configure.common grub-core/
 
-# FIXME: automake doesn't like that there's no Makefile.am
-automake -a -c -f || true
+ln -sf grub-core/include .
+ln -sf grub-core/gnulib .
+ln -sf grub-core/lib .
 
-echo timestamp > stamp-h.in
+python gentpl.py | sed -e '/^$/{N;/^\n$/D;}' > Makefile.tpl
+autogen -T Makefile.tpl modules.def | sed -e '/^$/{N;/^\n$/D;}' > modules.am
+
+(cd grub-core && python gentpl.py | sed -e '/^$/{N;/^\n$/D;}' > Makefile.tpl)
+(cd grub-core && autogen -T Makefile.tpl modules.def | sed -e '/^$/{N;/^\n$/D;}' > modules.am)
 
-python util/import_gcry.py lib/libgcrypt/ .
+(cd grub-core && echo timestamp > stamp-h.in)
+(cd grub-core && python import_gcry.py lib/libgcrypt/ .)
 
-for rmk in conf/*.rmk ${GRUB_CONTRIB}/*/conf/*.rmk; do
-  if test -e $rmk ; then
-    ruby genmk.rb < $rmk > `echo $rmk | sed 's/\.rmk$/.mk/'`
-  fi
-done
-sh gendistlist.sh > DISTLIST
+echo timestamp > stamp-h.in
+autoreconf -vi
 
 exit 0
diff --git a/boot/i386/pc/boot.S b/boot/i386/pc/boot.S
deleted file mode 100644 (file)
index 4afc573..0000000
+++ /dev/null
@@ -1,479 +0,0 @@
-/* -*-Asm-*- */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-#include <grub/boot.h>
-#include <grub/machine/boot.h>
-
-/*
- *  defines for the code go here
- */
-
-       /* Print message string */
-#define MSG(x) movw $x, %si; call LOCAL(message)
-#define ERR(x) movw $x, %si; jmp LOCAL(error_message)
-
-       .file   "boot.S"
-
-       .text
-
-       /* Tell GAS to generate 16-bit instructions so that this code works
-          in real mode. */
-       .code16
-
-.globl _start, start;
-_start:
-start:
-       /*
-        * _start is loaded at 0x7c00 and is jumped to with CS:IP 0:0x7c00
-        */
-
-       /*
-        * Beginning of the sector is compatible with the FAT/HPFS BIOS
-        * parameter block.
-        */
-
-       jmp     LOCAL(after_BPB)
-       nop     /* do I care about this ??? */
-
-       /*
-        * This space is for the BIOS parameter block!!!!  Don't change
-        * the first jump, nor start the code anywhere but right after
-        * this area.
-        */
-
-       . = _start + GRUB_BOOT_MACHINE_BPB_START
-       . = _start + 4
-
-       /* scratch space */
-mode:
-       .byte   0
-disk_address_packet:
-sectors:
-       .long   0
-heads:
-       .long   0
-cylinders:
-       .word   0
-sector_start:
-       .byte   0
-head_start:
-       .byte   0
-cylinder_start:
-       .word   0
-       /* more space... */
-
-       . = _start + GRUB_BOOT_MACHINE_BPB_END
-
-       /*
-        * End of BIOS parameter block.
-        */
-
-kernel_address:
-       .word   GRUB_BOOT_MACHINE_KERNEL_ADDR
-
-       . = _start + GRUB_BOOT_MACHINE_KERNEL_SECTOR
-kernel_sector:
-       .long   1, 0
-
-       . = _start + GRUB_BOOT_MACHINE_BOOT_DRIVE
-boot_drive:
-       .byte 0xff      /* the disk to load kernel from */
-                       /* 0xff means use the boot drive */
-
-LOCAL(after_BPB):
-
-/* general setup */
-       cli             /* we're not safe here! */
-
-        /*
-         * This is a workaround for buggy BIOSes which don't pass boot
-         * drive correctly. If GRUB is installed into a HDD, check if
-         * DL is masked correctly. If not, assume that the BIOS passed
-         * a bogus value and set DL to 0x80, since this is the only
-         * possible boot drive. If GRUB is installed into a floppy,
-         * this does nothing (only jump).
-         */
-       . = _start + GRUB_BOOT_MACHINE_DRIVE_CHECK
-boot_drive_check:
-        jmp     1f     /* grub-setup may overwrite this jump */
-        testb   $0x80, %dl
-        jnz     1f
-        movb    $0x80, %dl
-1:
-
-       /*
-        * ljmp to the next instruction because some bogus BIOSes
-        * jump to 07C0:0000 instead of 0000:7C00.
-        */
-       ljmp    $0, $real_start
-
-real_start:
-
-       /* set up %ds and %ss as offset from 0 */
-       xorw    %ax, %ax
-       movw    %ax, %ds
-       movw    %ax, %ss
-
-       /* set up the REAL stack */
-       movw    $GRUB_BOOT_MACHINE_STACK_SEG, %sp
-
-       sti             /* we're safe again */
-
-       /*
-        *  Check if we have a forced disk reference here
-        */
-       movb   boot_drive, %al
-       cmpb    $0xff, %al
-       je      1f
-       movb    %al, %dl
-1:
-       /* save drive reference first thing! */
-       pushw   %dx
-
-       /* print a notification message on the screen */
-       MSG(notification_string)
-
-       /* set %si to the disk address packet */
-       movw    $disk_address_packet, %si
-
-       /* do not probe LBA if the drive is a floppy */
-       testb   $GRUB_BOOT_MACHINE_BIOS_HD_FLAG, %dl
-       jz      LOCAL(chs_mode)
-
-       /* check if LBA is supported */
-       movb    $0x41, %ah
-       movw    $0x55aa, %bx
-       int     $0x13
-
-       /*
-        *  %dl may have been clobbered by INT 13, AH=41H.
-        *  This happens, for example, with AST BIOS 1.04.
-        */
-       popw    %dx
-       pushw   %dx
-
-       /* use CHS if fails */
-       jc      LOCAL(chs_mode)
-       cmpw    $0xaa55, %bx
-       jne     LOCAL(chs_mode)
-
-       andw    $1, %cx
-       jz      LOCAL(chs_mode)
-
-lba_mode:
-       xorw    %ax, %ax
-       movw    %ax, 4(%si)
-
-       incw    %ax
-       /* set the mode to non-zero */
-       movb    %al, -1(%si)
-
-       /* the blocks */
-       movw    %ax, 2(%si)
-
-       /* the size and the reserved byte */
-       movw    $0x0010, (%si)
-
-       /* the absolute address */
-       movl    kernel_sector, %ebx
-       movl    %ebx, 8(%si)
-       movl    kernel_sector + 4, %ebx
-       movl    %ebx, 12(%si)
-
-       /* the segment of buffer address */
-       movw    $GRUB_BOOT_MACHINE_BUFFER_SEG, 6(%si)
-
-/*
- * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
- *     Call with       %ah = 0x42
- *                     %dl = drive number
- *                     %ds:%si = segment:offset of disk address packet
- *     Return:
- *                     %al = 0x0 on success; err code on failure
- */
-
-       movb    $0x42, %ah
-       int     $0x13
-
-       /* LBA read is not supported, so fallback to CHS.  */
-       jc      LOCAL(chs_mode)
-
-       movw    $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
-       jmp     LOCAL(copy_buffer)
-
-LOCAL(chs_mode):
-       /*
-        *  Determine the hard disk geometry from the BIOS!
-        *  We do this first, so that LS-120 IDE floppies work correctly.
-        */
-       movb    $8, %ah
-       int     $0x13
-       jnc     LOCAL(final_init)
-
-       /*
-        *  The call failed, so maybe use the floppy probe instead.
-        */
-       testb   $GRUB_BOOT_MACHINE_BIOS_HD_FLAG, %dl
-       jz      LOCAL(floppy_probe)
-
-       /* Nope, we definitely have a hard disk, and we're screwed. */
-       ERR(hd_probe_error_string)
-
-LOCAL(final_init):
-       /* set the mode to zero */
-       movzbl  %dh, %eax
-       movb    %ah, -1(%si)
-
-       /* save number of heads */
-       incw    %ax
-       movl    %eax, 4(%si)
-
-       movzbw  %cl, %dx
-       shlw    $2, %dx
-       movb    %ch, %al
-       movb    %dh, %ah
-
-       /* save number of cylinders */
-       incw    %ax
-       movw    %ax, 8(%si)
-
-       movzbw  %dl, %ax
-       shrb    $2, %al
-
-       /* save number of sectors */
-       movl    %eax, (%si)
-
-setup_sectors:
-       /* load logical sector start (top half) */
-       movl    kernel_sector + 4, %eax
-
-       orl     %eax, %eax
-       jnz     LOCAL(geometry_error)
-
-       /* load logical sector start (bottom half) */
-       movl    kernel_sector, %eax
-
-       /* zero %edx */
-       xorl    %edx, %edx
-
-       /* divide by number of sectors */
-       divl    (%si)
-
-       /* save sector start */
-       movb    %dl, %cl
-
-       xorw    %dx, %dx        /* zero %edx */
-       divl    4(%si)          /* divide by number of heads */
-
-       /* do we need too many cylinders? */
-       cmpw    8(%si), %ax
-       jge     LOCAL(geometry_error)
-
-       /* normalize sector start (1-based) */
-       incb    %cl
-
-       /* low bits of cylinder start */
-       movb    %al, %ch
-
-       /* high bits of cylinder start */
-       xorb    %al, %al
-       shrw    $2, %ax
-       orb     %al, %cl
-
-       /* save head start */
-       movb    %dl, %al
-
-       /* restore %dl */
-       popw    %dx
-
-       /* head start */
-       movb    %al, %dh
-
-/*
- * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
- *     Call with       %ah = 0x2
- *                     %al = number of sectors
- *                     %ch = cylinder
- *                     %cl = sector (bits 6-7 are high bits of "cylinder")
- *                     %dh = head
- *                     %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
- *                     %es:%bx = segment:offset of buffer
- *     Return:
- *                     %al = 0x0 on success; err code on failure
- */
-
-       movw    $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
-       movw    %bx, %es        /* load %es segment with disk buffer */
-
-       xorw    %bx, %bx        /* %bx = 0, put it at 0 in the segment */
-       movw    $0x0201, %ax    /* function 2 */
-       int     $0x13
-
-       jc      LOCAL(read_error)
-
-       movw    %es, %bx
-
-LOCAL(copy_buffer):
-       /*
-        * We need to save %cx and %si because the startup code in
-        * kernel uses them without initializing them.
-        */
-       pusha
-       pushw   %ds
-
-       movw    $0x100, %cx
-       movw    %bx, %ds
-       xorw    %si, %si
-       movw    $GRUB_BOOT_MACHINE_KERNEL_ADDR, %di
-       movw    %si, %es
-
-       cld
-
-       rep
-       movsw
-
-       popw    %ds
-       popa
-
-       /* boot kernel */
-       jmp     *(kernel_address)
-
-/* END OF MAIN LOOP */
-
-/*
- * BIOS Geometry translation error (past the end of the disk geometry!).
- */
-LOCAL(geometry_error):
-       ERR(geometry_error_string)
-
-/*
- * Read error on the disk.
- */
-LOCAL(read_error):
-       movw    $read_error_string, %si
-LOCAL(error_message):
-       call    LOCAL(message)
-LOCAL(general_error):
-       MSG(general_error_string)
-
-/* go here when you need to stop the machine hard after an error condition */
-        /* tell the BIOS a boot failure, which may result in no effect */
-        int    $0x18
-LOCAL(stop):
-       jmp     LOCAL(stop)
-
-notification_string:   .asciz "GRUB "
-geometry_error_string: .asciz "Geom"
-hd_probe_error_string: .asciz "Hard Disk"
-read_error_string:     .asciz "Read"
-general_error_string:  .asciz " Error\r\n"
-
-/*
- * message: write the string pointed to by %si
- *
- *   WARNING: trashes %si, %ax, and %bx
- */
-
-       /*
-        * Use BIOS "int 10H Function 0Eh" to write character in teletype mode
-        *      %ah = 0xe       %al = character
-        *      %bh = page      %bl = foreground color (graphics modes)
-        */
-1:
-       movw    $0x0001, %bx
-       movb    $0xe, %ah
-       int     $0x10           /* display a byte */
-LOCAL(message):
-       lodsb
-       cmpb    $0, %al
-       jne     1b      /* if not end of string, jmp to display */
-       ret
-
-       /*
-        *  Windows NT breaks compatibility by embedding a magic
-        *  number here.
-        */
-
-       . = _start + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC
-nt_magic:
-       .long 0
-       .word 0
-
-       /*
-        *  This is where an MBR would go if on a hard disk.  The code
-        *  here isn't even referenced unless we're on a floppy.  Kinda
-        *  sneaky, huh?
-        */
-
-       . = _start + GRUB_BOOT_MACHINE_PART_START
-part_start:
-
-probe_values:
-       .byte   36, 18, 15, 9, 0
-
-LOCAL(floppy_probe):
-/*
- *  Perform floppy probe.
- */
-
-       movw    $probe_values - 1, %si
-
-LOCAL(probe_loop):
-       /* reset floppy controller INT 13h AH=0 */
-       xorw    %ax, %ax
-       int     $0x13
-
-       incw    %si
-       movb    (%si), %cl
-
-       /* if number of sectors is 0, display error and die */
-       cmpb    $0, %cl
-       jne     1f
-
-/*
- * Floppy disk probe failure.
- */
-       MSG(fd_probe_error_string)
-       jmp     LOCAL(general_error)
-
-/* "Floppy" */
-fd_probe_error_string: .asciz "Floppy"
-
-1:
-       /* perform read */
-       movw    $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
-       movw    $0x201, %ax
-       movb    $0, %ch
-       movb    $0, %dh
-       int     $0x13
-
-       /* if error, jump to "LOCAL(probe_loop)" */
-       jc      LOCAL(probe_loop)
-
-       /* %cl is already the correct value! */
-       movb    $1, %dh
-       movb    $79, %ch
-
-       jmp     LOCAL(final_init)
-
-       . = _start + GRUB_BOOT_MACHINE_PART_END
-
-/* the last 2 bytes in the sector 0 contain the signature */
-       .word   GRUB_BOOT_MACHINE_SIGNATURE
diff --git a/boot/i386/pc/cdboot.S b/boot/i386/pc/cdboot.S
deleted file mode 100644 (file)
index 33569ce..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/* -*-Asm-*- */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-#include <grub/boot.h>
-#include <grub/machine/boot.h>
-#include <grub/machine/kernel.h>
-#include <multiboot.h>
-
-        .file   "cdboot.S"
-
-#define CODE_ADDR      0x6000
-#define DATA_ADDR      ((GRUB_BOOT_MACHINE_KERNEL_ADDR) + 0x200)
-
-#define CDSEC_SHIFT    11
-#define CDBLK_LENG     16
-
-       .text
-
-        .code16
-
-        .globl  start, _start
-
-start:
-_start:
-       call    LOCAL(next)
-
-LOCAL(next):
-       jmp     1f
-
-       . = start + 8
-
-bi_pvd:
-       .long 0         /* LBA of primary volume descriptor.  */
-bi_file:
-       .long 0         /* LBA of boot file. */
-bi_length:
-       .long 0         /* Length of boot file. */
-bi_csum:
-       .long 0         /* Checksum of boot file */
-bi_reserved:
-       .space (10*4)   /* Reserved */
-
-1:
-       popw    %bx
-
-       /* Boot from CDROM.  */
-
-       xorw    %ax, %ax
-       movw    %ax, %ss
-       movw    $(CODE_ADDR), %sp
-       movw    %ax, %ds
-       movw    %ax, %es
-
-       movw    $(0x7C00 + err_noboot_msg - start), %si
-       movl    %cs: bi_length - LOCAL(next)(%bx), %ecx
-       orl     %ecx, %ecx
-       jz      LOCAL(fail)
-
-       addl    $((1 << CDSEC_SHIFT) - 1), %ecx
-       shrl    $CDSEC_SHIFT, %ecx
-
-       movl    %cs: bi_file - LOCAL(next)(%bx), %esi
-
-       call    LOCAL(read_cdrom)
-
-       ljmp    $(DATA_ADDR >> 4), $0
-
-/*
- * Parameters:
- *   esi: start sector
- *   ecx: number of sectors
- */
-LOCAL(read_cdrom):
-       xorl    %eax, %eax
-
-       /* Number of blocks to read.  */
-       pushw   $CDBLK_LENG
-
-       /* Block number.  */
-       pushl   %eax
-       pushl   %esi
-
-       /* Buffer address.  */
-       pushw   $((DATA_ADDR - 0x400)>> 4)
-       pushl   %eax
-       pushw   $0x10
-
-       xorl    %edi, %edi
-       movw    %sp, %si
-
-1:
-       movw    0x10(%si), %di
-       cmpl    %ecx, %edi
-       jbe     2f
-       movl    %ecx, %edi
-
-2:
-       mov     %di, 2(%si)
-
-       pushl   %ecx
-
-       movb    $0x42, %ah
-       int     $0x13
-
-       jnc     3f
-
-       movb    $0x42, %ah              /* Try again.  */
-       int     $0x13
-
-       jnc     3f
-
-2:
-       shrw    $1, %di                 /* Reduce transfer size.  */
-       jz      LOCAL(cdrom_fail)
-       movw    %di, 0x10(%si)
-       movw    %di, 2(%si)
-       movb    $0x42, %ah
-       int     $0x13
-       jc      2b
-
-3:
-
-       movw    %di, %ax
-       shlw    $(CDSEC_SHIFT - 4), %ax
-       addw    %ax, 6(%si)
-       addl    %edi, 8(%si)
-
-       popl    %ecx
-       subl    %edi, %ecx
-       jnz     1b
-
-       addw    $0x12, %sp
-       ret
-
-LOCAL(cdrom_fail):
-       movw    $(0x7C00 + err_cdfail_msg - start), %si
-
-LOCAL(fail):
-       movb    $0x0e, %ah
-       xorw    %bx, %bx
-1:
-       lodsb   (%si), %al
-       int     $0x10
-       cmpb    $0, %al
-       jne     1b
-1:     jmp     1b
-
-err_noboot_msg:
-       .ascii  "no boot info\0"
-
-err_cdfail_msg:
-       .ascii  "cdrom read fails\0"
-
-       . = start + 0x1FF
-
-       .byte   0
diff --git a/boot/i386/pc/diskboot.S b/boot/i386/pc/diskboot.S
deleted file mode 100644 (file)
index 92f223f..0000000
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2006,2007,2009,2010   Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-#include <grub/machine/boot.h>
-
-/*
- *  defines for the code go here
- */
-
-#define MSG(x) movw $x, %si; call LOCAL(message)
-
-       .file   "diskboot.S"
-
-       .text
-
-       /* Tell GAS to generate 16-bit instructions so that this code works
-          in real mode. */
-       .code16
-
-       .globl  start, _start
-start:
-_start:
-       /*
-        * _start is loaded at 0x2000 and is jumped to with
-        * CS:IP 0:0x2000 in kernel.
-        */
-
-       /*
-        * we continue to use the stack for boot.img and assume that
-        * some registers are set to correct values. See boot.S
-        * for more information.
-        */
-
-       /* save drive reference first thing! */
-       pushw   %dx
-
-       /* print a notification message on the screen */
-       pushw   %si
-       MSG(notification_string)
-       popw    %si
-
-       /* this sets up for the first run through "bootloop" */
-       movw    $(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE), %di
-
-       /* save the sector number of the second sector in %ebp */
-       movl    (%di), %ebp
-
-        /* this is the loop for reading the rest of the kernel in */
-LOCAL(bootloop):
-
-       /* check the number of sectors to read */
-       cmpw    $0, 8(%di)
-
-       /* if zero, go to the start function */
-       je      LOCAL(bootit)
-
-LOCAL(setup_sectors):
-       /* check if we use LBA or CHS */
-       cmpb    $0, -1(%si)
-
-       /* use CHS if zero, LBA otherwise */
-       je      LOCAL(chs_mode)
-
-       /* load logical sector start */
-       movl    (%di), %ebx
-       movl    4(%di), %ecx
-
-       /* the maximum is limited to 0x7f because of Phoenix EDD */
-       xorl    %eax, %eax
-       movb    $0x7f, %al
-
-       /* how many do we really want to read? */
-       cmpw    %ax, 8(%di)     /* compare against total number of sectors */
-
-       /* which is greater? */
-       jg      1f
-
-       /* if less than, set to total */
-       movw    8(%di), %ax
-
-1:
-       /* subtract from total */
-       subw    %ax, 8(%di)
-
-       /* add into logical sector start */
-       addl    %eax, (%di)
-       adcl    $0, 4(%di)
-
-       /* set up disk address packet */
-
-       /* the size and the reserved byte */
-       movw    $0x0010, (%si)
-
-       /* the number of sectors */
-       movw    %ax, 2(%si)
-
-       /* the absolute address */
-       movl    %ebx, 8(%si)
-       movl    %ecx, 12(%si)
-
-       /* the segment of buffer address */
-       movw    $GRUB_BOOT_MACHINE_BUFFER_SEG, 6(%si)
-
-       /* save %ax from destruction! */
-       pushw   %ax
-
-       /* the offset of buffer address */
-       movw    $0, 4(%si)
-
-/*
- * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
- *     Call with       %ah = 0x42
- *                     %dl = drive number
- *                     %ds:%si = segment:offset of disk address packet
- *     Return:
- *                     %al = 0x0 on success; err code on failure
- */
-
-       movb    $0x42, %ah
-       int     $0x13
-
-       jc      LOCAL(read_error)
-
-       movw    $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
-       jmp     LOCAL(copy_buffer)
-
-LOCAL(chs_mode):
-       /* load logical sector start (top half) */
-       movl    4(%di), %eax
-       orl     %eax, %eax
-       jnz     LOCAL(geometry_error)
-
-       /* load logical sector start (bottom half) */
-       movl    (%di), %eax
-
-       /* zero %edx */
-       xorl    %edx, %edx
-
-       /* divide by number of sectors */
-       divl    (%si)
-
-       /* save sector start */
-       movb    %dl, 10(%si)
-
-       xorl    %edx, %edx      /* zero %edx */
-       divl    4(%si)          /* divide by number of heads */
-
-       /* save head start */
-       movb    %dl, 11(%si)
-
-       /* save cylinder start */
-       movw    %ax, 12(%si)
-
-       /* do we need too many cylinders? */
-       cmpw    8(%si), %ax
-       jge     LOCAL(geometry_error)
-
-       /* determine the maximum sector length of this read */
-       movw    (%si), %ax      /* get number of sectors per track/head */
-
-       /* subtract sector start */
-       subb    10(%si), %al
-
-       /* how many do we really want to read? */
-       cmpw    %ax, 8(%di)     /* compare against total number of sectors */
-
-
-       /* which is greater? */
-       jg      2f
-
-       /* if less than, set to total */
-       movw    8(%di), %ax
-
-2:
-       /* subtract from total */
-       subw    %ax, 8(%di)
-
-       /* add into logical sector start */
-       addl    %eax, (%di)
-       adcl    $0, 4(%di)
-
-/*
- *  This is the loop for taking care of BIOS geometry translation (ugh!)
- */
-
-       /* get high bits of cylinder */
-       movb    13(%si), %dl
-
-       shlb    $6, %dl         /* shift left by 6 bits */
-       movb    10(%si), %cl    /* get sector */
-
-       incb    %cl             /* normalize sector (sectors go
-                                       from 1-N, not 0-(N-1) ) */
-       orb     %dl, %cl        /* composite together */
-       movb    12(%si), %ch    /* sector+hcyl in cl, cylinder in ch */
-
-       /* restore %dx */
-       popw    %dx
-       pushw   %dx
-
-       /* head number */
-       movb    11(%si), %dh
-
-       pushw   %ax     /* save %ax from destruction! */
-
-/*
- * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
- *     Call with       %ah = 0x2
- *                     %al = number of sectors
- *                     %ch = cylinder
- *                     %cl = sector (bits 6-7 are high bits of "cylinder")
- *                     %dh = head
- *                     %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
- *                     %es:%bx = segment:offset of buffer
- *     Return:
- *                     %al = 0x0 on success; err code on failure
- */
-
-       movw    $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
-       movw    %bx, %es        /* load %es segment with disk buffer */
-
-       xorw    %bx, %bx        /* %bx = 0, put it at 0 in the segment */
-       movb    $0x2, %ah       /* function 2 */
-       int     $0x13
-
-       jc      LOCAL(read_error)
-
-       /* save source segment */
-       movw    %es, %bx
-
-LOCAL(copy_buffer):
-
-       /* load addresses for copy from disk buffer to destination */
-       movw    10(%di), %es    /* load destination segment */
-
-       /* restore %ax */
-       popw    %ax
-
-       /* determine the next possible destination address (presuming
-               512 byte sectors!) */
-       shlw    $5, %ax         /* shift %ax five bits to the left */
-       addw    %ax, 10(%di)    /* add the corrected value to the destination
-                                  address for next time */
-
-       /* save addressing regs */
-       pusha
-       pushw   %ds
-
-       /* get the copy length */
-       shlw    $3, %ax
-       movw    %ax, %cx
-
-       xorw    %di, %di        /* zero offset of destination addresses */
-       xorw    %si, %si        /* zero offset of source addresses */
-       movw    %bx, %ds        /* restore the source segment */
-
-       cld             /* sets the copy direction to forward */
-
-       /* perform copy */
-       rep             /* sets a repeat */
-       movsw           /* this runs the actual copy */
-
-       /* restore addressing regs and print a dot with correct DS
-          (MSG modifies SI, which is saved, and unused AX and BX) */
-       popw    %ds
-       MSG(notification_step)
-       popa
-
-       /* check if finished with this dataset */
-       cmpw    $0, 8(%di)
-       jne     LOCAL(setup_sectors)
-
-       /* update position to load from */
-       subw    $GRUB_BOOT_MACHINE_LIST_SIZE, %di
-
-       /* jump to bootloop */
-       jmp     LOCAL(bootloop)
-
-/* END OF MAIN LOOP */
-
-LOCAL(bootit):
-       /* print a newline */
-       MSG(notification_done)
-       popw    %dx     /* this makes sure %dl is our "boot" drive */
-       ljmp    $0, $(GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200)
-
-
-/*
- * BIOS Geometry translation error (past the end of the disk geometry!).
- */
-LOCAL(geometry_error):
-       MSG(geometry_error_string)
-       jmp     LOCAL(general_error)
-
-/*
- * Read error on the disk.
- */
-LOCAL(read_error):
-       MSG(read_error_string)
-
-LOCAL(general_error):
-       MSG(general_error_string)
-
-/* go here when you need to stop the machine hard after an error condition */
-LOCAL(stop):   jmp     LOCAL(stop)
-
-notification_string:   .asciz "loading"
-
-notification_step:     .asciz "."
-notification_done:     .asciz "\r\n"
-
-geometry_error_string: .asciz "Geom"
-read_error_string:     .asciz "Read"
-general_error_string:  .asciz " Error"
-
-/*
- * message: write the string pointed to by %si
- *
- *   WARNING: trashes %si, %ax, and %bx
- */
-
-       /*
-        * Use BIOS "int 10H Function 0Eh" to write character in teletype mode
-        *      %ah = 0xe       %al = character
-        *      %bh = page      %bl = foreground color (graphics modes)
-        */
-1:
-       movw    $0x0001, %bx
-       movb    $0xe, %ah
-       int     $0x10           /* display a byte */
-
-       incw    %si
-LOCAL(message):
-       movb    (%si), %al
-       cmpb    $0, %al
-       jne     1b      /* if not end of string, jmp to display */
-       ret
-
-/*
- *  This area is an empty space between the main body of code below which
- *  grows up (fixed after compilation, but between releases it may change
- *  in size easily), and the lists of sectors to read, which grows down
- *  from a fixed top location.
- */
-
-       .word 0
-       .word 0
-
-       . = _start + 0x200 - GRUB_BOOT_MACHINE_LIST_SIZE
-
-        /* fill the first data listing with the default */
-blocklist_default_start:
-       /* this is the sector start parameter, in logical sectors from
-          the start of the disk, sector 0 */
-       .long 2, 0
-blocklist_default_len:
-       /* this is the number of sectors to read.  grub-mkimage
-          will fill this up */
-       .word 0
-blocklist_default_seg:
-       /* this is the segment of the starting address to load the data into */
-       .word (GRUB_BOOT_MACHINE_KERNEL_SEG + 0x20)
-
-firstlist:     /* this label has to be after the list data!!! */
diff --git a/boot/i386/pc/lnxboot.S b/boot/i386/pc/lnxboot.S
deleted file mode 100644 (file)
index b4f0030..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-/* -*-Asm-*- */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <grub/symbol.h>
-#include <grub/boot.h>
-#include <grub/machine/boot.h>
-#include <grub/machine/kernel.h>
-#include <multiboot.h>
-
-        .file   "lnxboot.S"
-
-#define CODE_ADDR      0x6000
-#define CODE_SECTORS   1
-#define DATA_ADDR      ((GRUB_BOOT_MACHINE_KERNEL_ADDR) + 0x200)
-
-#define BLCK_LENG      0x4000
-
-       .text
-
-        .code16
-
-        .globl  start, _start
-
-data_start:
-       xorl    %ebp, %ebp
-       jmp     LOCAL(linux_next)
-
-       . = data_start + 0x1F1
-
-setup_sects:
-       .byte   CODE_SECTORS
-root_flags:
-       .word   0
-syssize:
-       .word   0
-swap_dev:
-       .word   0
-ram_size:
-       .word   0
-vid_mode:
-       .word   0
-root_dev:
-       .word   0
-boot_flag:
-       .word   0xAA55
-
-start:
-_start:
-
-       jmp LOCAL(linux_init)
-
-       .ascii  "HdrS"                  /* Header signature.  */
-       .word   0x0203                  /* Header version number.  */
-
-realmode_swtch:
-       .word   0, 0                    /* default_switch, SETUPSEG.  */
-start_sys_seg:
-       .word   0x1000                  /* Obsolete.  */
-version_ptr:
-       .word   0                       /* Version string ptr.  */
-type_of_loader:
-       .byte   0                       /* Filled in by boot loader.  */
-loadflags:
-       .byte   1                       /* Please load high.  */
-setup_move_size:
-       .word   0                       /* Unused.  */
-code32_start:
-       .long   0x100000                /* 32-bit start address.  */
-ramdisk_image:
-       .long   0                       /* Loaded ramdisk image address.  */
-ramdisk_size:
-       .long   0                       /* Size of loaded ramdisk.  */
-bootsect_kludge:
-       .word   0, 0
-heap_end_ptr:
-       .word   0
-pad1:
-       .word   0
-cmd_line_ptr:
-       .long   0                       /* Command line.  */
-ramdisk_max:
-       .long   0xffffffff              /* Highest allowed ramdisk address.  */
-
-gdt:
-       .long   0, 0, 0, 0              /* Must be zero.  */
-       .word   0xffff                  /* 64 K segment size.  */
-gdt_src1:
-       .byte   0, 0 ,0                 /* Low 24 bits of source address.  */
-       .byte   0x93                    /* Access rights.  */
-       .byte   0                       /* Extended access rights.  */
-gdt_src2:
-       .byte   0                       /* High 8 bits of source address.  */
-       .word   0xffff                  /* 64 K segment size.  */
-gdt_dst1:
-       .byte   0, 0, 0                 /* Low 24 bits of target address.  */
-       .byte   0x93                    /* Access rights.  */
-       .byte   0                       /* Extended access rights.  */
-gdt_dst2:
-       .byte   0                       /* High 8 bits of source address.  */
-       .long   0, 0, 0, 0              /* More space for the BIOS.  */
-
-reg_edx:
-       .byte   0x80, 0, 0xFF, 0xFF
-
-data_leng:
-       .long   0
-
-LOCAL(linux_init):
-       movw    %cs:(reg_edx - start), %dx
-       movl    %cs:(code32_start - start), %ebp
-
-LOCAL(linux_next):
-
-       call    LOCAL(normalize)
-
-LOCAL(normalize):
-       popw    %bx
-       subw    $(LOCAL(normalize) - start), %bx
-       shrw    $4, %bx
-       movw    %cs, %ax
-       addw    %bx, %ax
-       pushw   %ax
-       pushw   $(real_code - start)
-       lret                            /* Jump to real_code.  */
-
-real_code:
-       subw    $0x20, %ax
-       movw    %ax, %ds
-       movw    (setup_sects - data_start), %cx
-       shlw    $7, %cx
-
-       /* Setup stack.  */
-
-       xorw    %si, %si
-       movw    %si, %ss
-       movw    $(CODE_ADDR), %sp
-
-       /* Move itself to 0:CODE_ADDR.  */
-
-       cld
-       movw    %cs, %ax
-       movw    %ax, %ds
-       movw    $(CODE_ADDR >> 4), %ax
-       movw    %ax, %es
-       movw    %si, %di
-
-       rep
-       movsl
-       ljmp    $(CODE_ADDR >> 4), $(real_code_2  - start)
-
-real_code_2:
-
-       xchgl   %ebp, %esi
-       orl     %esi, %esi
-       jnz     1f
-       movw    %ds, %si
-       shll    $4, %esi
-       addl    %ebp, %esi
-1:
-
-       pushw   %es
-       popw    %ds
-
-       movl    $0x200, %ecx
-       addl    %ecx, %esi
-       movl    $DATA_ADDR, %edi
-
-       call    LOCAL(move_memory)
-
-       /* Check for multiboot signature.  */
-       cmpl    $MULTIBOOT_HEADER_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_DATA_END)
-       jz      1f
-
-       movl    (ramdisk_image - start), %esi
-       movl    (ramdisk_size - start), %ecx
-       movl    $(DATA_ADDR - 0x200), %edi
-       jmp     2f
-
-1:
-
-       movl    %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx
-       addl    $(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx
-
-2:
-       call    LOCAL(move_memory)
-
-       movsbl  %dh, %eax
-       movl    %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)
-       movsbl  (reg_edx + 2 - start), %eax
-       movl    %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)
-
-       movb    $0xFF, %dh
-
-       ljmp    $(DATA_ADDR >> 4), $0
-
-/*
- * Parameters:
- *   esi: source address
- *   edi: target address
- *   ecx: number of bytes
- */
-
-LOCAL(move_memory):
-       incl    %ecx
-       andb    $0xFE, %cl
-       pushw   %dx
-1:
-       pushl   %esi
-       pushl   %edi
-       pushl   %ecx
-       cmpl    $BLCK_LENG, %ecx
-       jbe     2f
-       movl    $BLCK_LENG, %ecx
-2:
-       pushl   %ecx
-
-       movl    %esi, %eax
-       movw    %si, (gdt_src1 - start)
-       shrl    $16, %eax
-       movb    %al, (gdt_src1 + 2 - start)
-       movb    %ah, (gdt_src2 - start)
-
-       movl    %edi, %eax
-       movw    %di, (gdt_dst1 - start)
-       shrl    $16, %eax
-       movb    %al, (gdt_dst1 + 2 - start)
-       movb    %ah, (gdt_dst2 - start)
-
-       movw    $(gdt - start), %si
-       movb    $0x87, %ah
-       shrw    $1, %cx
-
-       int     $0x15
-
-       popl    %eax
-       popl    %ecx
-       popl    %edi
-       popl    %esi
-
-       jnc     2f
-       movw    $(err_int15_msg - start), %si
-       jmp     LOCAL(fail)
-
-2:
-
-       addl    %eax, %esi
-       addl    %eax, %edi
-       subl    %eax, %ecx
-       jnz     1b
-
-
-       popw    %dx
-       ret
-
-/*
- * Parameters:
- *   si: message
- */
-
-LOCAL(fail):
-       movb    $0x0e, %ah
-       xorw    %bx, %bx
-1:
-       lodsb   (%si), %al
-       int     $0x10
-       cmpb    $0, %al
-       jne     1b
-1:     jmp     1b
-
-err_int15_msg:
-       .ascii  "move memory fails\0"
-
-       . = _start + CODE_SECTORS * 512
diff --git a/boot/i386/pc/pxeboot.S b/boot/i386/pc/pxeboot.S
deleted file mode 100644 (file)
index 446bfc7..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2000,2005,2007,2008,2009,2010   Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/machine/boot.h>
-
-       .file   "pxeboot.S"
-       .text
-
-       /* Start with the prehistoric environment... */
-       .code16
-
-       /* Let's go */
-.globl start, _start;
-_start:
-start:
-
-       /* Use drive number 0x7F for PXE */
-        movb   $GRUB_BOOT_MACHINE_PXE_DL, %dl
-
-       /* Jump to the real world */
-       ljmp    $0, $0x8200
-
-       /* This region is a junk. Do you say that this is wasteful?
-          But I like that the memory layout of the body is consistent
-          among different kernels rather than scamping just for 1.5KB. */
-       . = _start + 0x8200 - 0x7C00 - 0x200 - 1
-       .byte   0
diff --git a/boot/i386/qemu/boot.S b/boot/i386/qemu/boot.S
deleted file mode 100644 (file)
index 03631a2..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <grub/symbol.h>
-#include <grub/machine/memory.h>
-#include <grub/machine/boot.h>
-#include <grub/machine/kernel.h>
-
-       .text
-       .code16
-       .globl _start
-_start:
-       /* Disable interrupts.  */
-       cli
-
-       jmp     1f
-
-       . = _start + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR
-VARIABLE(grub_core_entry_addr)
-       .long   0
-1:
-
-       /* Process VGA rom.  */
-       call    $0xc000, $0x3
-
-       /* Set up %ds, %ss, and %es.  */
-       xorw    %ax, %ax
-       movw    %ax, %ds
-       movw    %ax, %ss
-       movw    %ax, %es
-
-       /* Set up the real mode stack.  */
-       movl    $GRUB_MEMORY_MACHINE_REAL_STACK, %esp
-
-       /* Transition to protected mode.  We use pushl to force generation
-          of a flat return address.  */
-       pushl   $1f
-       DATA32  jmp real_to_prot
-       .code32
-1:
-       movl    grub_core_entry_addr, %edx
-       jmp     *%edx
-
-#include "../../../kern/i386/realmode.S"
-
-       /* Intel, in its infinite wisdom, decided to put the i8086 entry point
-          *right here* and this is why we need this kludge.  */
-
-       . = GRUB_BOOT_MACHINE_SIZE - 16
-
-       .code16
-       
-       jmp     _start
-       . = GRUB_BOOT_MACHINE_SIZE
diff --git a/boot/sparc64/ieee1275/boot.S b/boot/sparc64/ieee1275/boot.S
deleted file mode 100644 (file)
index f08258f..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/* -*-Asm-*- */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/boot.h>
-#include <grub/machine/boot.h>
-
-       .text
-       .align  4
-       .globl  _start
-_start:
-       /* OF CIF entry point arrives in %o4 */
-pic_base:
-       call    boot_continue
-        mov    %o4, CIF_REG
-
-       . = _start + GRUB_BOOT_MACHINE_VER_MAJ
-boot_version:          .byte   GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
-
-       /* The offsets to these locations are defined by the
-        * GRUB_BOOT_MACHINE_foo macros in include/grub/sparc/ieee1275/boot.h,
-        * and grub-setup uses this to patch these next three values as needed.
-        *
-        * The boot_path will be the OF device path of the partition where the
-        * rest of the GRUB kernel image resides.  kernel_sector will be set to
-        * the location of the first block of the GRUB kernel, and
-        * kernel_address is the location where we should load that first block.
-        *
-        * After loading in that block we will execute it by jumping to the
-        * load address plus the size of the prepended A.OUT header (32 bytes).
-        */
-boot_path:
-       . = _start + GRUB_BOOT_MACHINE_KERNEL_BYTE
-boot_path_end:
-kernel_byte:           .xword (2 << 9)
-kernel_address:                .word  GRUB_BOOT_MACHINE_KERNEL_ADDR
-
-prom_finddev_name:     .asciz "finddevice"
-prom_chosen_path:      .asciz "/chosen"
-prom_getprop_name:     .asciz "getprop"
-prom_stdout_name:      .asciz "stdout"
-prom_write_name:       .asciz "write"
-prom_bootpath_name:    .asciz "bootpath"
-prom_open_name:                .asciz "open"
-prom_seek_name:                .asciz "seek"
-prom_read_name:                .asciz "read"
-prom_exit_name:                .asciz "exit"
-grub_name:             .asciz "GRUB "
-#define GRUB_NAME_LEN  5
-
-       .align  4
-
-prom_open_error:
-       GET_ABS(prom_open_name, %o2)
-       call    console_write
-        mov    4, %o3
-       /* fallthru */
-
-prom_error:
-       GET_ABS(prom_exit_name, %o0)
-       /* fallthru */
-
-       /* %o0: OF call name
-        * %o1: input arg 1
-        */
-prom_call_1_1_o2:
-       clr     %o2
-       ba      prom_call_x_1
-        mov    1, %g1
-
-prom_call_getprop:
-       mov     4, %g1
-       stx     %g1, [%l1 + 256]
-       mov     CHOSEN_NODE_REG, %o1
-       ba      prom_call_x_1
-        GET_ABS(prom_getprop_name, %o0)
-
-prom_call_3_1_o1:
-       ba prom_call_3_1
-        mov    BOOTDEV_REG, %o1
-
-       
-       /* %o2: message string
-        * %o3: message length
-        */
-console_write:
-       GET_ABS(prom_write_name, %o0)
-       mov     STDOUT_NODE_REG, %o1
-       /* fallthru */
-
-       /* %o0: OF call name
-        * %o1: input arg 1
-        * %o2: input arg 2
-        * %o3: input arg 3
-        */
-prom_call_3_1: 
-       mov     3, %g1
-prom_call_x_1:
-       mov     1, %o5
-       /* fallthru */
-
-       /* %o0: OF call name
-        * %g1: num inputs
-        * %o5: num outputs
-        * %o1-%o4: inputs
-        */
-prom_call:
-       stx     %o0, [%l1 + 0x00]
-       stx     %g1, [%l1 + 0x08]
-       stx     %o5, [%l1 + 0x10]
-       stx     %o1, [%l1 + 0x18]
-       stx     %o2, [%l1 + 0x20]
-       stx     %o3, [%l1 + 0x28]
-       stx     %o4, [%l1 + 0x30]
-       jmpl    CIF_REG, %g0
-        mov    %l1, %o0
-
-boot_continue:
-       mov     %o7, PIC_REG            /* PIC base */
-       sethi   %hi(SCRATCH_PAD_BOOT), %l1      /* OF argument slots */
-
-       /* Find the /chosen node so we can fetch the stdout handle,
-        * and thus perform console output.
-        *
-        * chosen_node = prom_finddevice("/chosen")
-        */
-       GET_ABS(prom_finddev_name, %o0)
-       call    prom_call_1_1_o2
-        GET_ABS(prom_chosen_path, %o1)
-
-       ldx     [%l1 + 0x20], CHOSEN_NODE_REG
-       brz     CHOSEN_NODE_REG, prom_error
-
-       /* getprop(chosen_node, "stdout", &buffer, buffer_size) */
-        GET_ABS(prom_stdout_name, %o2)
-       add     %l1, 256, %o3
-       call    prom_call_getprop
-        mov    1024, %o4
-
-       lduw    [%l1 + 256], STDOUT_NODE_REG
-       brz,pn  STDOUT_NODE_REG, prom_error
-
-       /* write(stdout_node, "GRUB ", strlen("GRUB ")) */
-        GET_ABS(grub_name, %o2)
-       call    console_write
-        mov    GRUB_NAME_LEN, %o3
-
-       GET_ABS(boot_path, %o3)
-       ldub    [%o3], %o1
-       brnz,pn %o1, bootpath_known
-
-       /* getprop(chosen_node, "bootpath", &buffer, buffer_size) */
-        GET_ABS(prom_bootpath_name, %o2)
-       call    prom_call_getprop
-        mov    (boot_path_end - boot_path), %o4
-
-bootpath_known:        
-
-       /* Open up the boot_path, and use that handle to read the
-        * first block of the GRUB kernel image.
-        *
-        * bootdev_handle = open(boot_path)
-        */
-       GET_ABS(prom_open_name, %o0)
-       call    prom_call_1_1_o2
-        GET_ABS(boot_path, %o1)
-
-       ldx     [%l1 + 0x20], BOOTDEV_REG
-       brz,pn  BOOTDEV_REG, prom_open_error
-
-       /* Since we have 64-bit cells, the high cell of the seek offset
-        * is zero and the low cell is the entire value.
-        *
-        * seek(bootdev, 0, *kernel_byte)
-        */
-        GET_ABS(prom_seek_name, %o0)
-       clr     %o2
-       call    prom_call_3_1_o1
-        LDX_ABS(kernel_byte, 0x00, %o3)
-
-       /* read(bootdev, *kernel_address, 512) */
-       GET_ABS(prom_read_name, %o0)
-       LDUW_ABS(kernel_address, 0x00, %o2)
-       call    prom_call_3_1_o1
-        mov    512, %o3
-
-       LDUW_ABS(kernel_address, 0x00, %o2)
-       jmpl    %o2, %o7
-        nop
-
-       . = _start + GRUB_BOOT_MACHINE_CODE_END
-
-/* the last 4 bytes in the sector 0 contain the signature */
-       .word   GRUB_BOOT_MACHINE_SIGNATURE
diff --git a/boot/sparc64/ieee1275/diskboot.S b/boot/sparc64/ieee1275/diskboot.S
deleted file mode 100644 (file)
index a4d4b5b..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/* -*-Asm-*- */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/boot.h>
-#include <grub/machine/boot.h>
-
-       .text
-       .align  4
-       .globl  _start
-_start:
-       /* First stage boot block jumps to us here.  */
-pic_base:
-       call    after_info_block
-        mov    %o7, PIC_REG
-
-prom_write_name:               .asciz "write"
-prom_seek_name:                        .asciz "seek"
-prom_read_name:                        .asciz "read"
-prom_close_name:               .asciz "close"
-
-notification_string:           .asciz "Loading kernel"
-#define NOTIFICATION_STRING_LEN        14
-
-notification_step:             .asciz "."
-#define NOTIFICATION_STEP_LEN  1
-
-notification_done:             .asciz "\r\n"
-#define NOTIFICATION_DONE_LEN  2
-
-       .align  4
-
-       /* %o2: message string
-        * %o3: message length
-        */
-console_write:
-       GET_ABS(prom_write_name, %o0)
-       mov     STDOUT_NODE_REG, %o1
-       /* fallthru */
-
-       /* %o0: OF call name
-        * %o1: input arg 1
-        * %o2: input arg 2
-        * %o3: input arg 3
-        */
-prom_call_3_1:
-       mov     3, %g1
-       mov     1, %o5
-       /* fallthru */
-
-       /* %o0: OF call name
-        * %g1: num inputs
-        * %o5: num outputs
-        * %o1-%o4: inputs
-        */
-prom_call:
-       stx     %o0, [%l1 + 0x00]
-       stx     %g1, [%l1 + 0x08]
-       stx     %o5, [%l1 + 0x10]
-       stx     %o1, [%l1 + 0x18]
-       stx     %o2, [%l1 + 0x20]
-       stx     %o3, [%l1 + 0x28]
-       stx     %o4, [%l1 + 0x30]
-       jmpl    CIF_REG, %g0
-        mov    %l1, %o0
-
-
-after_info_block:
-       sethi   %hi(SCRATCH_PAD_DISKBOOT), %l1  /* OF argument slots */
-
-       GET_ABS(notification_string, %o2)
-       call    console_write
-        mov    NOTIFICATION_STRING_LEN, %o3
-
-       GET_ABS(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE, %l2)
-       set     GRUB_BOOT_MACHINE_IMAGE_ADDRESS, %l3
-bootloop:
-       lduw    [%l2 + 0x08], %o0
-       brz     %o0, bootit
-        lduw   [%l2 + 0x00], %o3
-       sllx    %o3, 32, %o3
-       lduw    [%l2 + 0x04], %o4
-       or      %o3, %o4, %o3
-       GET_ABS(prom_seek_name, %o0)
-       mov     BOOTDEV_REG, %o1
-       clr     %o2
-       call    prom_call_3_1
-        sllx   %o3, 9, %o3
-
-       GET_ABS(prom_read_name, %o0)
-       mov     BOOTDEV_REG, %o1
-       lduw    [%l2 + 0x08], %o3
-       sllx    %o3, 9, %o3
-       mov     %l3, %o2
-       call    prom_call_3_1
-        add    %l3, %o3, %l3
-
-       GET_ABS(notification_step, %o2)
-       call    console_write
-        mov    NOTIFICATION_STEP_LEN, %o3
-
-       ba      bootloop
-        sub    %l2, GRUB_BOOT_MACHINE_LIST_SIZE, %l2
-
-bootit:
-       GET_ABS(prom_close_name, %o0)
-       mov     1, %g1
-       mov     0, %o5
-       call    prom_call
-        mov    BOOTDEV_REG, %o1
-
-       GET_ABS(notification_done, %o2)
-       call    console_write
-        mov    NOTIFICATION_DONE_LEN, %o3
-       sethi   %hi(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o2
-       jmpl    %o2 + %lo(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o7
-        mov    CIF_REG, %o4
-1:     ba,a    1b
-
-lastlist:
-       .word   0
-       .word   0
-
-       . = _start + (0x200 - GRUB_BOOT_MACHINE_LIST_SIZE)
-blocklist_default_start:
-       .word   0
-       .word   2
-blocklist_default_len:
-       .word   0
-firstlist:
diff --git a/bus/bonito.c b/bus/bonito.c
deleted file mode 100644 (file)
index 3f794c4..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/* bonito.c - PCI bonito interface.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/pci.h>
-#include <grub/misc.h>
-
-static grub_uint32_t base_win[GRUB_MACHINE_PCI_NUM_WIN];
-static const grub_size_t sizes_win[GRUB_MACHINE_PCI_NUM_WIN] = 
-  {GRUB_MACHINE_PCI_WIN1_SIZE, GRUB_MACHINE_PCI_WIN_SIZE, 
-   GRUB_MACHINE_PCI_WIN_SIZE};
-/* Usage counters.  */
-static int usage_win[GRUB_MACHINE_PCI_NUM_WIN];
-static grub_addr_t addr_win[GRUB_MACHINE_PCI_NUM_WIN] = 
-  {GRUB_MACHINE_PCI_WIN1_ADDR, GRUB_MACHINE_PCI_WIN2_ADDR,
-   GRUB_MACHINE_PCI_WIN3_ADDR};
-
-static inline void
-write_bases (void)
-{
-  int i;
-  grub_uint32_t reg = 0;
-  for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) 
-    reg |= (((base_win[i] >> GRUB_MACHINE_PCI_WIN_SHIFT) 
-            & GRUB_MACHINE_PCI_WIN_MASK) 
-           >> (i * GRUB_MACHINE_PCI_WIN_MASK_SIZE));
-  GRUB_MACHINE_PCI_IO_CTRL_REG = reg;
-}
-
-volatile void *
-grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)),
-                          grub_addr_t base, grub_size_t size)
-{
-  int i;
-  grub_addr_t newbase;
-
-  /* First try already used registers. */
-  for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++)
-    if (usage_win[i] && base_win[i] <= base 
-       && base_win[i] + sizes_win[i] > base + size)
-      {
-       usage_win[i]++;
-       return (void *) 
-         (addr_win[i] | (base & GRUB_MACHINE_PCI_WIN_OFFSET_MASK));
-      }
-  /* Map new register.  */
-  newbase = base & ~GRUB_MACHINE_PCI_WIN_OFFSET_MASK;
-  for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++)
-    if (!usage_win[i] && newbase <= base 
-       && newbase + sizes_win[i] > base + size)
-      {
-       usage_win[i]++;
-       base_win[i] = newbase;
-       write_bases ();
-       return (void *) 
-         (addr_win[i] | (base & GRUB_MACHINE_PCI_WIN_OFFSET_MASK));
-      }
-  grub_fatal ("Out of PCI windows.");
-}
-
-void
-grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)),
-                            volatile void *mem __attribute__ ((unused)),
-                            grub_size_t size __attribute__ ((unused)))
-{
-  int i;
-  for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++)
-    if (usage_win[i] && addr_win[i] 
-       == (((grub_addr_t) mem) & ~GRUB_MACHINE_PCI_WIN_OFFSET_MASK))
-      {
-       usage_win[i]--;
-       return;
-      }
-  grub_fatal ("Tried to unmap not mapped region");
-}
diff --git a/bus/pci.c b/bus/pci.c
deleted file mode 100644 (file)
index a08e534..0000000
--- a/bus/pci.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* pci.c - Generic PCI interfaces.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/pci.h>
-
-grub_pci_address_t
-grub_pci_make_address (grub_pci_device_t dev, int reg)
-{
-  return (1 << 31) | (dev.bus << 16) | (dev.device << 11)
-    | (dev.function << 8) | reg;
-}
-
-void
-grub_pci_iterate (grub_pci_iteratefunc_t hook)
-{
-  grub_pci_device_t dev;
-  grub_pci_address_t addr;
-  grub_pci_id_t id;
-  grub_uint32_t hdr;
-
-  for (dev.bus = 0; dev.bus < GRUB_PCI_NUM_BUS; dev.bus++)
-    {
-      for (dev.device = 0; dev.device < GRUB_PCI_NUM_DEVICES; dev.device++)
-       {
-         for (dev.function = 0; dev.function < 8; dev.function++)
-           {
-             addr = grub_pci_make_address (dev, GRUB_PCI_REG_PCI_ID);
-             id = grub_pci_read (addr);
-
-             /* Check if there is a device present.  */
-             if (id >> 16 == 0xFFFF)
-               continue;
-
-             if (hook (dev, id))
-               return;
-
-             /* Probe only func = 0 if the device if not multifunction */
-             if (dev.function == 0)
-               {
-                 addr = grub_pci_make_address (dev, GRUB_PCI_REG_CACHELINE);
-                 hdr = grub_pci_read (addr);
-                 if (!(hdr & 0x800000))
-                   break;
-               }
-           }
-       }
-    }
-}
diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c
deleted file mode 100644 (file)
index 6d185bc..0000000
+++ /dev/null
@@ -1,611 +0,0 @@
-/* ohci.c - OHCI Support.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/usb.h>
-#include <grub/usbtrans.h>
-#include <grub/misc.h>
-#include <grub/pci.h>
-#include <grub/cpu/pci.h>
-#include <grub/i386/io.h>
-#include <grub/time.h>
-
-struct grub_ohci_hcca
-{
-  /* Pointers to Interrupt Endpoint Descriptors.  Not used by
-     GRUB.  */
-  grub_uint32_t inttable[32];
-
-  /* Current frame number.  */
-  grub_uint16_t framenumber;
-
-  grub_uint16_t pad;
-
-  /* List of completed TDs.  */
-  grub_uint32_t donehead;
-
-  grub_uint8_t reserved[116];
-} __attribute__((packed));
-
-/* OHCI Endpoint Descriptor.  */
-struct grub_ohci_ed
-{
-  grub_uint32_t target;
-  grub_uint32_t td_tail;
-  grub_uint32_t td_head;
-  grub_uint32_t next_ed;
-} __attribute__((packed));
-
-struct grub_ohci_td
-{
-  /* Information used to construct the TOKEN packet.  */
-  grub_uint32_t token;
-
-  grub_uint32_t buffer;
-  grub_uint32_t next_td;
-  grub_uint32_t buffer_end;
-} __attribute__((packed));
-
-typedef struct grub_ohci_td *grub_ohci_td_t;
-typedef struct grub_ohci_ed *grub_ohci_ed_t;
-
-struct grub_ohci
-{
-  volatile grub_uint32_t *iobase;
-  volatile struct grub_ohci_hcca *hcca;
-  struct grub_ohci *next;
-};
-
-static struct grub_ohci *ohci;
-
-typedef enum
-{
-  GRUB_OHCI_REG_REVISION = 0x00,
-  GRUB_OHCI_REG_CONTROL,
-  GRUB_OHCI_REG_CMDSTATUS,
-  GRUB_OHCI_REG_INTSTATUS,
-  GRUB_OHCI_REG_INTENA,
-  GRUB_OHCI_REG_INTDIS,
-  GRUB_OHCI_REG_HCCA,
-  GRUB_OHCI_REG_PERIODIC,
-  GRUB_OHCI_REG_CONTROLHEAD,
-  GRUB_OHCI_REG_CONTROLCURR,
-  GRUB_OHCI_REG_BULKHEAD,
-  GRUB_OHCI_REG_BULKCURR,
-  GRUB_OHCI_REG_DONEHEAD,
-  GRUB_OHCI_REG_FRAME_INTERVAL,
-  GRUB_OHCI_REG_RHUBA = 18,
-  GRUB_OHCI_REG_RHUBPORT = 21
-} grub_ohci_reg_t;
-
-static grub_uint32_t
-grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg)
-{
-  return grub_le_to_cpu32 (*(o->iobase + reg));
-}
-
-static void
-grub_ohci_writereg32 (struct grub_ohci *o,
-                     grub_ohci_reg_t reg, grub_uint32_t val)
-{
-  *(o->iobase + reg) = grub_cpu_to_le32 (val);
-}
-
-\f
-
-/* Iterate over all PCI devices.  Determine if a device is an OHCI
-   controller.  If this is the case, initialize it.  */
-static int NESTED_FUNC_ATTR
-grub_ohci_pci_iter (grub_pci_device_t dev,
-                   grub_pci_id_t pciid __attribute__((unused)))
-{
-  grub_uint32_t class_code;
-  grub_uint32_t class;
-  grub_uint32_t subclass;
-  grub_uint32_t interf;
-  grub_uint32_t base;
-  grub_pci_address_t addr;
-  struct grub_ohci *o;
-  grub_uint32_t revision;
-  grub_uint32_t frame_interval;
-
-  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
-  class_code = grub_pci_read (addr) >> 8;
-
-  interf = class_code & 0xFF;
-  subclass = (class_code >> 8) & 0xFF;
-  class = class_code >> 16;
-
-  /* If this is not an OHCI controller, just return.  */
-  if (class != 0x0c || subclass != 0x03 || interf != 0x10)
-    return 0;
-
-  /* Determine IO base address.  */
-  addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
-  base = grub_pci_read (addr);
-
-#if 0
-  /* Stop if there is no IO space base address defined.  */
-  if (! (base & 1))
-    return 0;
-#endif
-
-  /* Allocate memory for the controller and register it.  */
-  o = grub_malloc (sizeof (*o));
-  if (! o)
-    return 1;
-
-  o->iobase = (grub_uint32_t *) base;
-
-  /* Reserve memory for the HCCA.  */
-  o->hcca = (struct grub_ohci_hcca *) grub_memalign (256, 256);
-
-  grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x base=%p\n",
-               class, subclass, interf, o->iobase);
-
-  /* Check if the OHCI revision is actually 1.0 as supported.  */
-  revision = grub_ohci_readreg32 (o, GRUB_OHCI_REG_REVISION);
-  grub_dprintf ("ohci", "OHCI revision=0x%02x\n", revision & 0xFF);
-  if ((revision & 0xFF) != 0x10)
-    goto fail;
-
-  /* Backup the frame interval register.  */
-  frame_interval = grub_ohci_readreg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL);
-
-  /* Suspend the OHCI by issuing a reset.  */
-  grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic.  */
-  grub_millisleep (1);
-  grub_dprintf ("ohci", "OHCI reset\n");
-
-  /* Restore the frame interval register.  */
-  grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, frame_interval);
-
-  /* Setup the HCCA.  */
-  grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, (grub_uint32_t) o->hcca);
-  grub_dprintf ("ohci", "OHCI HCCA\n");
-
-  /* Enable the OHCI.  */
-  grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL,
-                       (2 << 6));
-  grub_dprintf ("ohci", "OHCI enable: 0x%02x\n",
-               (grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) >> 6) & 3);
-
-  /* Link to ohci now that initialisation is successful.  */
-  o->next = ohci;
-  ohci = o;
-
-  return 0;
-
- fail:
-  if (o)
-    grub_free ((void *) o->hcca);
-  grub_free (o);
-
-  return 1;
-}
-
-
-static void
-grub_ohci_inithw (void)
-{
-  grub_pci_iterate (grub_ohci_pci_iter);
-}
-
-\f
-
-static int
-grub_ohci_iterate (int (*hook) (grub_usb_controller_t dev))
-{
-  struct grub_ohci *o;
-  struct grub_usb_controller dev;
-
-  for (o = ohci; o; o = o->next)
-    {
-      dev.data = o;
-      if (hook (&dev))
-       return 1;
-    }
-
-  return 0;
-}
-
-static void
-grub_ohci_transaction (grub_ohci_td_t td,
-                      grub_transfer_type_t type, unsigned int toggle,
-                      grub_size_t size, char *data)
-{
-  grub_uint32_t token;
-  grub_uint32_t buffer;
-  grub_uint32_t buffer_end;
-
-  grub_dprintf ("ohci", "OHCI transaction td=%p type=%d, toggle=%d, size=%d\n",
-               td, type, toggle, size);
-
-  switch (type)
-    {
-    case GRUB_USB_TRANSFER_TYPE_SETUP:
-      token = 0 << 19;
-      break;
-    case GRUB_USB_TRANSFER_TYPE_IN:
-      token = 2 << 19;
-      break;
-    case GRUB_USB_TRANSFER_TYPE_OUT:
-      token = 1 << 19;
-      break;
-    default:
-      token = 0;
-      break;
-    }
-
-  /* Generate no interrupts.  */
-  token |= 7 << 21;
-
-  /* Set the token.  */
-  token |= toggle << 24;
-  token |= 1 << 25;
-
-  buffer = (grub_uint32_t) data;
-  buffer_end = buffer + size - 1;
-
-  td->token = grub_cpu_to_le32 (token);
-  td->buffer = grub_cpu_to_le32 (buffer);
-  td->next_td = 0;
-  td->buffer_end = grub_cpu_to_le32 (buffer_end);
-}
-
-static grub_usb_err_t
-grub_ohci_transfer (grub_usb_controller_t dev,
-                   grub_usb_transfer_t transfer)
-{
-  struct grub_ohci *o = (struct grub_ohci *) dev->data;
-  grub_ohci_ed_t ed;
-  grub_ohci_td_t td_list;
-  grub_uint32_t target;
-  grub_uint32_t td_tail;
-  grub_uint32_t td_head;
-  grub_uint32_t status;
-  grub_uint32_t control;
-  grub_usb_err_t err;
-  int i;
-
-  /* Allocate an Endpoint Descriptor.  */
-  ed = grub_memalign (16, sizeof (*ed));
-  if (! ed)
-    return GRUB_USB_ERR_INTERNAL;
-
-  td_list = grub_memalign (16, sizeof (*td_list) * (transfer->transcnt + 1));
-  if (! td_list)
-    {
-      grub_free ((void *) ed);
-      return GRUB_USB_ERR_INTERNAL;
-    }
-
-  grub_dprintf ("ohci", "alloc=%p\n", td_list);
-
-  /* Setup all Transfer Descriptors.  */
-  for (i = 0; i < transfer->transcnt; i++)
-    {
-      grub_usb_transaction_t tr = &transfer->transactions[i];
-
-      grub_ohci_transaction (&td_list[i], tr->pid, tr->toggle,
-                            tr->size, tr->data);
-
-      td_list[i].next_td = grub_cpu_to_le32 (&td_list[i + 1]);
-    }
-
-  /* Setup the Endpoint Descriptor.  */
-
-  /* Set the device address.  */
-  target = transfer->devaddr;
-
-  /* Set the endpoint.  */
-  target |= transfer->endpoint << 7;
-
-  /* Set the device speed.  */
-  target |= (transfer->dev->speed == GRUB_USB_SPEED_LOW) << 13;
-
-  /* Set the maximum packet size.  */
-  target |= transfer->max << 16;
-
-  td_head = (grub_uint32_t) td_list;
-
-  td_tail = (grub_uint32_t) &td_list[transfer->transcnt];
-
-  ed->target = grub_cpu_to_le32 (target);
-  ed->td_head = grub_cpu_to_le32 (td_head);
-  ed->td_tail = grub_cpu_to_le32 (td_tail);
-  ed->next_ed = grub_cpu_to_le32 (0);
-
-  grub_dprintf ("ohci", "program OHCI\n");
-
-  /* Program the OHCI to actually transfer.  */
-  switch (transfer->type)
-    {
-    case GRUB_USB_TRANSACTION_TYPE_BULK:
-      {
-       grub_dprintf ("ohci", "add to bulk list\n");
-
-       status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
-       control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
-
-       /* Disable the Control and Bulk lists.  */
-       control &= ~(3 << 4);
-       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
-
-       /* Clear BulkListFilled.  */
-       status &= ~(1 << 2);
-       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
-
-       grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, (grub_uint32_t) ed);
-
-       /* Enable the Bulk list.  */
-       control |= 1 << 5;
-       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
-
-       /* Set BulkListFilled.  */
-       status |= 1 << 2;
-       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
-
-       break;
-      }
-
-    case GRUB_USB_TRANSACTION_TYPE_CONTROL:
-      {
-       grub_dprintf ("ohci", "add to control list\n");
-       status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
-       control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
-
-       /* Disable the Control and Bulk lists.  */
-       control &= ~(3 << 4);
-       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
-
-       /* Clear ControlListFilled.  */
-       status &= ~(1 << 1);
-       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
-
-       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD,
-                             (grub_uint32_t) ed);
-       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD+1,
-                             (grub_uint32_t) ed);
-
-       /* Enable the Control list.  */
-       control |= 1 << 4;
-       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
-
-       /* Set ControlListFilled.  */
-       status |= 1 << 1;
-       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
-       break;
-      }
-    }
-
-  grub_dprintf ("ohci", "wait for completion\n");
-  grub_dprintf ("ohci", "control=0x%02x status=0x%02x\n",
-               grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL),
-               grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS));
-
-  /* Wait until the transfer is completed or STALLs.  */
-  while ((ed->td_head & ~0xf) != (ed->td_tail & ~0xf))
-    {
-      grub_cpu_idle ();
-
-      grub_dprintf ("ohci", "head=0x%02x tail=0x%02x\n", ed->td_head, ed->td_tail);
-
-      /* Detected a STALL.  */
-      if (ed->td_head & 1)
-       break;
-    }
-
-  grub_dprintf ("ohci", "complete\n");
-
-/*   if (ed->td_head & 1) */
-/*     err = GRUB_USB_ERR_STALL; */
-/*   else if (ed->td */
-
-
-  if (ed->td_head & 1)
-    {
-      grub_uint8_t errcode;
-      grub_ohci_td_t tderr;
-
-      tderr = (grub_ohci_td_t) grub_ohci_readreg32 (o,
-                                                   GRUB_OHCI_REG_DONEHEAD);
-      errcode = tderr->token >> 28;
-
-      switch (errcode)
-       {
-       case 0:
-         /* XXX: Should not happen!  */
-         grub_error (GRUB_ERR_IO, "OHCI without reporting the reason");
-         err = GRUB_USB_ERR_INTERNAL;
-         break;
-
-       case 1:
-         /* XXX: CRC error.  */
-         err = GRUB_USB_ERR_TIMEOUT;
-         break;
-
-       case 2:
-         err = GRUB_USB_ERR_BITSTUFF;
-         break;
-
-       case 3:
-         /* XXX: Data Toggle error.  */
-         err = GRUB_USB_ERR_DATA;
-         break;
-
-       case 4:
-         err = GRUB_USB_ERR_STALL;
-         break;
-
-       case 5:
-         /* XXX: Not responding.  */
-         err = GRUB_USB_ERR_TIMEOUT;
-         break;
-
-       case 6:
-         /* XXX: PID Check bits failed.  */
-         err = GRUB_USB_ERR_BABBLE;
-         break;
-
-       case 7:
-         /* XXX: PID unexpected failed.  */
-         err = GRUB_USB_ERR_BABBLE;
-         break;
-
-       case 8:
-         /* XXX: Data overrun error.  */
-         err = GRUB_USB_ERR_DATA;
-         break;
-
-       case 9:
-         /* XXX: Data underrun error.  */
-         err = GRUB_USB_ERR_DATA;
-         break;
-
-       case 10:
-         /* XXX: Reserved.  */
-         err = GRUB_USB_ERR_NAK;
-         break;
-
-       case 11:
-         /* XXX: Reserved.  */
-         err = GRUB_USB_ERR_NAK;
-         break;
-
-       case 12:
-         /* XXX: Buffer overrun.  */
-         err = GRUB_USB_ERR_DATA;
-         break;
-
-       case 13:
-         /* XXX: Buffer underrun.  */
-         err = GRUB_USB_ERR_DATA;
-         break;
-
-       default:
-         err = GRUB_USB_ERR_NAK;
-         break;
-       }
-    }
-  else
-    err = GRUB_USB_ERR_NONE;
-
-  /* Disable the Control and Bulk lists.  */
-  control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
-  control &= ~(3 << 4);
-  grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
-
-  /* Clear BulkListFilled and ControlListFilled.  */
-  status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
-  status &= ~((1 << 2) | (1 << 3));
-  grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
-
-  /* XXX */
-  grub_free (td_list);
-  grub_free (ed);
-
-  return err;
-}
-
-static grub_err_t
-grub_ohci_portstatus (grub_usb_controller_t dev,
-                     unsigned int port, unsigned int enable)
-{
-   struct grub_ohci *o = (struct grub_ohci *) dev->data;
-   grub_uint32_t status;
-
-   /* Reset the port.  */
-   status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
-   status |= (1 << 4); /* XXX: Magic.  */
-   grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status);
-   grub_millisleep (100);
-
-   /* End the reset signaling.  */
-   status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
-   status |= (1 << 20); /* XXX: Magic.  */
-   grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status);
-   grub_millisleep (10);
-
-   /* Enable the port.  */
-   status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
-   status |= (enable << 1); /* XXX: Magic.  */
-   grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status);
-
-   status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
-   grub_dprintf ("ohci", "portstatus=0x%02x\n", status);
-
-   return GRUB_ERR_NONE;
-}
-
-static grub_usb_speed_t
-grub_ohci_detect_dev (grub_usb_controller_t dev, int port)
-{
-   struct grub_ohci *o = (struct grub_ohci *) dev->data;
-   grub_uint32_t status;
-
-   status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
-
-   grub_dprintf ("ohci", "detect_dev status=0x%02x\n", status);
-
-   if (! (status & 1))
-     return GRUB_USB_SPEED_NONE;
-   else if (status & (1 << 9))
-     return GRUB_USB_SPEED_LOW;
-   else
-     return GRUB_USB_SPEED_FULL;
-}
-
-static int
-grub_ohci_hubports (grub_usb_controller_t dev)
-{
-  struct grub_ohci *o = (struct grub_ohci *) dev->data;
-  grub_uint32_t portinfo;
-
-  portinfo = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA);
-
-  grub_dprintf ("ohci", "root hub ports=%d\n", portinfo & 0xFF);
-
-  /* The root hub has exactly two ports.  */
-  return portinfo & 0xFF;
-}
-
-
-\f
-static struct grub_usb_controller_dev usb_controller =
-{
-  .name = "ohci",
-  .iterate = grub_ohci_iterate,
-  .transfer = grub_ohci_transfer,
-  .hubports = grub_ohci_hubports,
-  .portstatus = grub_ohci_portstatus,
-  .detect_dev = grub_ohci_detect_dev
-};
-
-GRUB_MOD_INIT(ohci)
-{
-  grub_ohci_inithw ();
-  grub_usb_controller_dev_register (&usb_controller);
-}
-
-GRUB_MOD_FINI(ohci)
-{
-  grub_usb_controller_dev_unregister (&usb_controller);
-}
diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c
deleted file mode 100644 (file)
index 947f236..0000000
+++ /dev/null
@@ -1,689 +0,0 @@
-/* uhci.c - UHCI Support.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/usb.h>
-#include <grub/usbtrans.h>
-#include <grub/pci.h>
-#include <grub/i386/io.h>
-#include <grub/time.h>
-
-#define GRUB_UHCI_IOMASK       (0x7FF << 5)
-
-typedef enum
-  {
-    GRUB_UHCI_REG_USBCMD = 0x00,
-    GRUB_UHCI_REG_FLBASEADD = 0x08,
-    GRUB_UHCI_REG_PORTSC1 = 0x10,
-    GRUB_UHCI_REG_PORTSC2 = 0x12
-  } grub_uhci_reg_t;
-
-#define GRUB_UHCI_LINK_TERMINATE       1
-#define GRUB_UHCI_LINK_QUEUE_HEAD      2
-
-
-/* UHCI Queue Head.  */
-struct grub_uhci_qh
-{
-  /* Queue head link pointer which points to the next queue head.  */
-  grub_uint32_t linkptr;
-
-  /* Queue element link pointer which points to the first data object
-     within the queue.  */
-  grub_uint32_t elinkptr;
-
-  /* Queue heads are aligned on 16 bytes, pad so a queue head is 16
-     bytes so we can store many in a 4K page.  */
-  grub_uint8_t pad[8];
-} __attribute__ ((packed));
-
-/* UHCI Transfer Descriptor.  */
-struct grub_uhci_td
-{
-  /* Pointer to the next TD in the list.  */
-  grub_uint32_t linkptr;
-
-  /* Control and status bits.  */
-  grub_uint32_t ctrl_status;
-
-  /* All information required to transfer the Token packet.  */
-  grub_uint32_t token;
-
-  /* A pointer to the data buffer, UHCI requires this pointer to be 32
-     bits.  */
-  grub_uint32_t buffer;
-
-  /* Another linkptr that is not overwritten by the Host Controller.
-     This is GRUB specific.  */
-  grub_uint32_t linkptr2;
-
-  /* 3 additional 32 bits words reserved for the Host Controller Driver.  */
-  grub_uint32_t data[3];
-} __attribute__ ((packed));
-
-typedef volatile struct grub_uhci_td *grub_uhci_td_t;
-typedef volatile struct grub_uhci_qh *grub_uhci_qh_t;
-
-struct grub_uhci
-{
-  int iobase;
-  grub_uint32_t *framelist;
-
-  /* 256 Queue Heads.  */
-  grub_uhci_qh_t qh;
-
-  /* 256 Transfer Descriptors.  */
-  grub_uhci_td_t td;
-
-  /* Free Transfer Descriptors.  */
-  grub_uhci_td_t tdfree;
-
-  struct grub_uhci *next;
-};
-
-static struct grub_uhci *uhci;
-
-static grub_uint16_t
-grub_uhci_readreg16 (struct grub_uhci *u, grub_uhci_reg_t reg)
-{
-  return grub_inw (u->iobase + reg);
-}
-
-#if 0
-static grub_uint32_t
-grub_uhci_readreg32 (struct grub_uhci *u, grub_uhci_reg_t reg)
-{
-  return grub_inl (u->iobase + reg);
-}
-#endif
-
-static void
-grub_uhci_writereg16 (struct grub_uhci *u,
-                     grub_uhci_reg_t reg, grub_uint16_t val)
-{
-  grub_outw (val, u->iobase + reg);
-}
-
-static void
-grub_uhci_writereg32 (struct grub_uhci *u,
-                   grub_uhci_reg_t reg, grub_uint32_t val)
-{
-  grub_outl (val, u->iobase + reg);
-}
-
-static grub_err_t
-grub_uhci_portstatus (grub_usb_controller_t dev,
-                     unsigned int port, unsigned int enable);
-
-
-/* Iterate over all PCI devices.  Determine if a device is an UHCI
-   controller.  If this is the case, initialize it.  */
-static int NESTED_FUNC_ATTR
-grub_uhci_pci_iter (grub_pci_device_t dev,
-                   grub_pci_id_t pciid __attribute__((unused)))
-{
-  grub_uint32_t class_code;
-  grub_uint32_t class;
-  grub_uint32_t subclass;
-  grub_uint32_t interf;
-  grub_uint32_t base;
-  grub_uint32_t fp;
-  grub_pci_address_t addr;
-  struct grub_uhci *u;
-  int i;
-
-  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
-  class_code = grub_pci_read (addr) >> 8;
-
-  interf = class_code & 0xFF;
-  subclass = (class_code >> 8) & 0xFF;
-  class = class_code >> 16;
-
-  /* If this is not an UHCI controller, just return.  */
-  if (class != 0x0c || subclass != 0x03 || interf != 0x00)
-    return 0;
-
-  /* Determine IO base address.  */
-  addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG4);
-  base = grub_pci_read (addr);
-  /* Stop if there is no IO space base address defined.  */
-  if (! (base & 1))
-    return 0;
-
-  /* Allocate memory for the controller and register it.  */
-  u = grub_zalloc (sizeof (*u));
-  if (! u)
-    return 1;
-
-  u->iobase = base & GRUB_UHCI_IOMASK;
-  grub_dprintf ("uhci", "class=0x%02x 0x%02x interface 0x%02x base=0x%x\n",
-               class, subclass, interf, u->iobase);
-
-  /* Reserve a page for the frame list.  */
-  u->framelist = grub_memalign (4096, 4096);
-  if (! u->framelist)
-    goto fail;
-
-  /* The framelist pointer of UHCI is only 32 bits, make sure this
-     code works on on 64 bits architectures.  */
-#if GRUB_CPU_SIZEOF_VOID_P == 8
-  if ((grub_uint64_t) u->framelist >> 32)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                 "allocated frame list memory not <4GB");
-      goto fail;
-    }
-#endif
-
-  /* The QH pointer of UHCI is only 32 bits, make sure this
-     code works on on 64 bits architectures.  */
-  u->qh = (grub_uhci_qh_t) grub_memalign (4096, 4096);
-  if (! u->qh)
-    goto fail;
-
-#if GRUB_CPU_SIZEOF_VOID_P == 8
-  if ((grub_uint64_t) u->qh >> 32)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "allocated QH memory not <4GB");
-      goto fail;
-    }
-#endif
-
-  /* The TD pointer of UHCI is only 32 bits, make sure this
-     code works on on 64 bits architectures.  */
-  u->td = (grub_uhci_td_t) grub_memalign (4096, 4096*2);
-  if (! u->td)
-    goto fail;
-
-#if GRUB_CPU_SIZEOF_VOID_P == 8
-  if ((grub_uint64_t) u->td >> 32)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "allocated TD memory not <4GB");
-      goto fail;
-    }
-#endif
-
-  /* Link all Transfer Descriptors in a list of available Transfer
-     Descriptors.  */
-  for (i = 0; i < 256; i++)
-    u->td[i].linkptr = (grub_uint32_t) &u->td[i + 1];
-  u->td[255 - 1].linkptr = 0;
-  u->tdfree = u->td;
-
-  /* Make sure UHCI is disabled!  */
-  grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 0);
-
-  /* Setup the frame list pointers.  Since no isochronous transfers
-     are and will be supported, they all point to the (same!) queue
-     head.  */
-  fp = (grub_uint32_t) u->qh & (~15);
-  /* Mark this as a queue head.  */
-  fp |= 2;
-  for (i = 0; i < 1024; i++)
-    u->framelist[i] = fp;
-  /* Program the framelist address into the UHCI controller.  */
-  grub_uhci_writereg32 (u, GRUB_UHCI_REG_FLBASEADD,
-                       (grub_uint32_t) u->framelist);
-
-  /* Make the Queue Heads point to each other.  */
-  for (i = 0; i < 256; i++)
-    {
-      /* Point to the next QH.  */
-      u->qh[i].linkptr = (grub_uint32_t) (&u->qh[i + 1]) & (~15);
-
-      /* This is a QH.  */
-      u->qh[i].linkptr |= GRUB_UHCI_LINK_QUEUE_HEAD;
-
-      /* For the moment, do not point to a Transfer Descriptor.  These
-        are set at transfer time, so just terminate it.  */
-      u->qh[i].elinkptr = 1;
-    }
-
-  /* The last Queue Head should terminate.  256 are too many QHs so
-     just use 50.  */
-  u->qh[50 - 1].linkptr = 1;
-
-  /* Enable UHCI again.  */
-  grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 1 | (1 << 7));
-
-  /* UHCI is initialized and ready for transfers.  */
-  grub_dprintf ("uhci", "UHCI initialized\n");
-
-
-#if 0
-  {
-    int i;
-    for (i = 0; i < 10; i++)
-      {
-       grub_uint16_t frnum;
-
-       frnum = grub_uhci_readreg16 (u, 6);
-       grub_dprintf ("uhci", "Framenum=%d\n", frnum);
-       grub_millisleep (100);
-      }
-  }
-#endif
-
-  /* Link to uhci now that initialisation is successful.  */
-  u->next = uhci;
-  uhci = u;
-
-  return 0;
-
- fail:
-  if (u)
-    {
-      grub_free ((void *) u->qh);
-      grub_free (u->framelist);
-    }
-  grub_free (u);
-
-  return 1;
-}
-
-static void
-grub_uhci_inithw (void)
-{
-  grub_pci_iterate (grub_uhci_pci_iter);
-}
-
-static grub_uhci_td_t
-grub_alloc_td (struct grub_uhci *u)
-{
-  grub_uhci_td_t ret;
-
-  /* Check if there is a Transfer Descriptor available.  */
-  if (! u->tdfree)
-    return NULL;
-
-  ret = u->tdfree;
-  u->tdfree = (grub_uhci_td_t) u->tdfree->linkptr;
-
-  return ret;
-}
-
-static void
-grub_free_td (struct grub_uhci *u, grub_uhci_td_t td)
-{
-  td->linkptr = (grub_uint32_t) u->tdfree;
-  u->tdfree = td;
-}
-
-static void
-grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td)
-{
-  /* Free the TDs in this queue.  */
-  while (td)
-    {
-      grub_uhci_td_t tdprev;
-
-      /* Unlink the queue.  */
-      tdprev = td;
-      td = (grub_uhci_td_t) td->linkptr2;
-
-      /* Free the TD.  */
-      grub_free_td (u, tdprev);
-    }
-}
-
-static grub_uhci_qh_t
-grub_alloc_qh (struct grub_uhci *u,
-              grub_transaction_type_t tr __attribute__((unused)))
-{
-  int i;
-  grub_uhci_qh_t qh;
-
-  /* Look for a Queue Head for this transfer.  Skip the first QH if
-     this is a Interrupt Transfer.  */
-#if 0
-  if (tr == GRUB_USB_TRANSACTION_TYPE_INTERRUPT)
-    i = 0;
-  else
-#endif
-    i = 1;
-
-  for (; i < 255; i++)
-    {
-      if (u->qh[i].elinkptr & 1)
-       break;
-    }
-  qh = &u->qh[i];
-  if (! (qh->elinkptr & 1))
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                 "no free queue heads available");
-      return NULL;
-    }
-
-  return qh;
-}
-
-static grub_uhci_td_t
-grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
-                      grub_transfer_type_t type, unsigned int addr,
-                      unsigned int toggle, grub_size_t size,
-                      char *data)
-{
-  grub_uhci_td_t td;
-  static const unsigned int tf[] = { 0x69, 0xE1, 0x2D };
-
-  /* XXX: Check if data is <4GB.  If it isn't, just copy stuff around.
-     This is only relevant for 64 bits architectures.  */
-
-  /* Grab a free Transfer Descriptor and initialize it.  */
-  td = grub_alloc_td (u);
-  if (! td)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                 "no transfer descriptors available for UHCI transfer");
-      return 0;
-    }
-
-  grub_dprintf ("uhci",
-               "transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=%p td=%p\n",
-               endp, type, addr, toggle, size, data, td);
-
-  /* Don't point to any TD, just terminate.  */
-  td->linkptr = 1;
-
-  /* Active!  Only retry a transfer 3 times.  */
-  td->ctrl_status = (1 << 23) | (3 << 27);
-
-  /* If zero bytes are transmitted, size is 0x7FF.  Otherwise size is
-     size-1.  */
-  if (size == 0)
-    size = 0x7FF;
-  else
-    size = size - 1;
-
-  /* Setup whatever is required for the token packet.  */
-  td->token = ((size << 21) | (toggle << 19) | (endp << 15)
-              | (addr << 8) | tf[type]);
-
-  td->buffer = (grub_uint32_t) data;
-
-  return td;
-}
-
-static grub_usb_err_t
-grub_uhci_transfer (grub_usb_controller_t dev,
-                   grub_usb_transfer_t transfer)
-{
-  struct grub_uhci *u = (struct grub_uhci *) dev->data;
-  grub_uhci_qh_t qh;
-  grub_uhci_td_t td;
-  grub_uhci_td_t td_first = NULL;
-  grub_uhci_td_t td_prev = NULL;
-  grub_usb_err_t err = GRUB_USB_ERR_NONE;
-  int i;
-  grub_uint64_t endtime;
-
-  /* Allocate a queue head for the transfer queue.  */
-  qh = grub_alloc_qh (u, GRUB_USB_TRANSACTION_TYPE_CONTROL);
-  if (! qh)
-    return grub_errno;
-
-  for (i = 0; i < transfer->transcnt; i++)
-    {
-      grub_usb_transaction_t tr = &transfer->transactions[i];
-
-      td = grub_uhci_transaction (u, transfer->endpoint, tr->pid,
-                                 transfer->devaddr, tr->toggle,
-                                 tr->size, tr->data);
-      if (! td)
-       {
-         /* Terminate and free.  */
-         td_prev->linkptr2 = 0;
-         td_prev->linkptr = 1;
-
-         if (td_first)
-           grub_free_queue (u, td_first);
-
-         return GRUB_USB_ERR_INTERNAL;
-       }
-
-      if (! td_first)
-       td_first = td;
-      else
-       {
-         td_prev->linkptr2 = (grub_uint32_t) td;
-         td_prev->linkptr = (grub_uint32_t) td;
-         td_prev->linkptr |= 4;
-       }
-      td_prev = td;
-    }
-  td_prev->linkptr2 = 0;
-  td_prev->linkptr = 1;
-
-  grub_dprintf ("uhci", "setup transaction %d\n", transfer->type);
-
-  /* Link it into the queue and terminate.  Now the transaction can
-     take place.  */
-  qh->elinkptr = (grub_uint32_t) td_first;
-
-  grub_dprintf ("uhci", "initiate transaction\n");
-
-  /* Wait until either the transaction completed or an error
-     occurred.  */
-  endtime = grub_get_time_ms () + 1000;
-  for (;;)
-    {
-      grub_uhci_td_t errtd;
-
-      errtd = (grub_uhci_td_t) (qh->elinkptr & ~0x0f);
-
-      grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p\n",
-                   errtd->ctrl_status, errtd->buffer & (~15), errtd);
-
-      /* Check if the transaction completed.  */
-      if (qh->elinkptr & 1)
-       break;
-
-      grub_dprintf ("uhci", "t status=0x%02x\n", errtd->ctrl_status);
-
-      /* Check if the TD is not longer active.  */
-      if (! (errtd->ctrl_status & (1 << 23)))
-       {
-         grub_dprintf ("uhci", ">>t status=0x%02x\n", errtd->ctrl_status);
-
-         /* Check if the endpoint is stalled.  */
-         if (errtd->ctrl_status & (1 << 22))
-           err = GRUB_USB_ERR_STALL;
-
-         /* Check if an error related to the data buffer occurred.  */
-         if (errtd->ctrl_status & (1 << 21))
-           err = GRUB_USB_ERR_DATA;
-
-         /* Check if a babble error occurred.  */
-         if (errtd->ctrl_status & (1 << 20))
-           err = GRUB_USB_ERR_BABBLE;
-
-         /* Check if a NAK occurred.  */
-         if (errtd->ctrl_status & (1 << 19))
-           err = GRUB_USB_ERR_NAK;
-
-         /* Check if a timeout occurred.  */
-         if (errtd->ctrl_status & (1 << 18))
-           err = GRUB_USB_ERR_TIMEOUT;
-
-         /* Check if a bitstuff error occurred.  */
-         if (errtd->ctrl_status & (1 << 17))
-           err = GRUB_USB_ERR_BITSTUFF;
-
-         if (err)
-           goto fail;
-
-         /* Fall through, no errors occurred, so the QH might be
-            updated.  */
-         grub_dprintf ("uhci", "transaction fallthrough\n");
-       }
-      if (grub_get_time_ms () > endtime)
-       {
-         err = GRUB_USB_ERR_STALL;
-         grub_dprintf ("uhci", "transaction timed out\n");
-         goto fail;
-       }
-      grub_cpu_idle ();
-    }
-
-  grub_dprintf ("uhci", "transaction complete\n");
-
- fail:
-
-  grub_dprintf ("uhci", "transaction failed\n");
-
-  /* Place the QH back in the free list and deallocate the associated
-     TDs.  */
-  qh->elinkptr = 1;
-  grub_free_queue (u, td_first);
-
-  return err;
-}
-
-static int
-grub_uhci_iterate (int (*hook) (grub_usb_controller_t dev))
-{
-  struct grub_uhci *u;
-  struct grub_usb_controller dev;
-
-  for (u = uhci; u; u = u->next)
-    {
-      dev.data = u;
-      if (hook (&dev))
-       return 1;
-    }
-
-  return 0;
-}
-
-static grub_err_t
-grub_uhci_portstatus (grub_usb_controller_t dev,
-                     unsigned int port, unsigned int enable)
-{
-  struct grub_uhci *u = (struct grub_uhci *) dev->data;
-  int reg;
-  unsigned int status;
-  grub_uint64_t endtime;
-
-  grub_dprintf ("uhci", "enable=%d port=%d\n", enable, port);
-
-  if (port == 0)
-    reg = GRUB_UHCI_REG_PORTSC1;
-  else if (port == 1)
-    reg = GRUB_UHCI_REG_PORTSC2;
-  else
-    return grub_error (GRUB_ERR_OUT_OF_RANGE,
-                      "UHCI Root Hub port does not exist");
-
-  status = grub_uhci_readreg16 (u, reg);
-  grub_dprintf ("uhci", "detect=0x%02x\n", status);
-
-  /* Reset the port.  */
-  grub_uhci_writereg16 (u, reg, enable << 9);
-
-  /* Wait for the reset to complete.  XXX: How long exactly?  */
-  grub_millisleep (10);
-  status = grub_uhci_readreg16 (u, reg);
-  grub_uhci_writereg16 (u, reg, status & ~(1 << 9));
-  grub_dprintf ("uhci", "reset completed\n");
-  grub_millisleep (10);
-
-  /* Enable the port.  */
-  grub_uhci_writereg16 (u, reg, enable << 2);
-  grub_millisleep (10);
-
-  grub_dprintf ("uhci", "waiting for the port to be enabled\n");
-
-  endtime = grub_get_time_ms () + 1000;
-  while (! (grub_uhci_readreg16 (u, reg) & (1 << 2)))
-    if (grub_get_time_ms () > endtime)
-      return grub_error (GRUB_ERR_IO, "UHCI Timed out");
-
-  status = grub_uhci_readreg16 (u, reg);
-  grub_dprintf ("uhci", ">3detect=0x%02x\n", status);
-
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_usb_speed_t
-grub_uhci_detect_dev (grub_usb_controller_t dev, int port)
-{
-  struct grub_uhci *u = (struct grub_uhci *) dev->data;
-  int reg;
-  unsigned int status;
-
-  if (port == 0)
-    reg = GRUB_UHCI_REG_PORTSC1;
-  else if (port == 1)
-    reg = GRUB_UHCI_REG_PORTSC2;
-  else
-    return grub_error (GRUB_ERR_OUT_OF_RANGE,
-                      "UHCI Root Hub port does not exist");
-
-  status = grub_uhci_readreg16 (u, reg);
-
-  grub_dprintf ("uhci", "detect=0x%02x port=%d\n", status, port);
-
-  if (! (status & 1))
-    return GRUB_USB_SPEED_NONE;
-  else if (status & (1 << 8))
-    return GRUB_USB_SPEED_LOW;
-  else
-    return GRUB_USB_SPEED_FULL;
-}
-
-static int
-grub_uhci_hubports (grub_usb_controller_t dev __attribute__((unused)))
-{
-  /* The root hub has exactly two ports.  */
-  return 2;
-}
-
-\f
-static struct grub_usb_controller_dev usb_controller =
-{
-  .name = "uhci",
-  .iterate = grub_uhci_iterate,
-  .transfer = grub_uhci_transfer,
-  .hubports = grub_uhci_hubports,
-  .portstatus = grub_uhci_portstatus,
-  .detect_dev = grub_uhci_detect_dev
-};
-
-GRUB_MOD_INIT(uhci)
-{
-  grub_uhci_inithw ();
-  grub_usb_controller_dev_register (&usb_controller);
-  grub_dprintf ("uhci", "registered\n");
-}
-
-GRUB_MOD_FINI(uhci)
-{
-  struct grub_uhci *u;
-
-  /* Disable all UHCI controllers.  */
-  for (u = uhci; u; u = u->next)
-    grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 0);
-
-  /* Unregister the controller.  */
-  grub_usb_controller_dev_unregister (&usb_controller);
-}
diff --git a/bus/usb/usb.c b/bus/usb/usb.c
deleted file mode 100644 (file)
index 8289185..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-/* usb.c - Generic USB interfaces.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/usb.h>
-#include <grub/misc.h>
-
-static grub_usb_controller_dev_t grub_usb_list;
-
-void
-grub_usb_controller_dev_register (grub_usb_controller_dev_t usb)
-{
-  auto int iterate_hook (grub_usb_controller_t dev);
-
-  /* Iterate over all controllers found by the driver.  */
-  int iterate_hook (grub_usb_controller_t dev)
-    {
-      dev->dev = usb;
-
-      /* Enable the ports of the USB Root Hub.  */
-      grub_usb_root_hub (dev);
-
-      return 0;
-    }
-
-  usb->next = grub_usb_list;
-  grub_usb_list = usb;
-
-  if (usb->iterate)
-    usb->iterate (iterate_hook);
-}
-
-void
-grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb)
-{
-  grub_usb_controller_dev_t *p, q;
-
-  for (p = &grub_usb_list, q = *p; q; p = &(q->next), q = q->next)
-    if (q == usb)
-      {
-       *p = q->next;
-       break;
-      }
-}
-
-#if 0
-int
-grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev))
-{
-  grub_usb_controller_dev_t p;
-
-  auto int iterate_hook (grub_usb_controller_t dev);
-
-  int iterate_hook (grub_usb_controller_t dev)
-    {
-      dev->dev = p;
-      if (hook (dev))
-       return 1;
-      return 0;
-    }
-
-  /* Iterate over all controller drivers.  */
-  for (p = grub_usb_list; p; p = p->next)
-    {
-      /* Iterate over the busses of the controllers.  XXX: Actually, a
-        hub driver should do this.  */
-      if (p->iterate (iterate_hook))
-       return 1;
-    }
-
-  return 0;
-}
-#endif
-
-\f
-grub_usb_err_t
-grub_usb_clear_halt (grub_usb_device_t dev, int endpoint)
-{
-  dev->toggle[endpoint] = 0;
-  return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
-                                    | GRUB_USB_REQTYPE_STANDARD
-                                    | GRUB_USB_REQTYPE_TARGET_ENDP),
-                              GRUB_USB_REQ_CLEAR_FEATURE,
-                              GRUB_USB_FEATURE_ENDP_HALT,
-                              endpoint, 0, 0);
-}
-
-grub_usb_err_t
-grub_usb_set_configuration (grub_usb_device_t dev, int configuration)
-{
-  int i;
-
-  for (i = 0; i < 16; i++)
-    dev->toggle[i] = 0;
-
-  return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
-                                    | GRUB_USB_REQTYPE_STANDARD
-                                    | GRUB_USB_REQTYPE_TARGET_DEV),
-                              GRUB_USB_REQ_SET_CONFIGURATION, configuration,
-                              0, 0, NULL);
-}
-
-grub_usb_err_t
-grub_usb_get_descriptor (grub_usb_device_t dev,
-                        grub_uint8_t type, grub_uint8_t index,
-                        grub_size_t size, char *data)
-{
-  return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
-                                    | GRUB_USB_REQTYPE_STANDARD
-                                    | GRUB_USB_REQTYPE_TARGET_DEV),
-                              GRUB_USB_REQ_GET_DESCRIPTOR,
-                              (type << 8) | index,
-                              0, size, data);
-}
-
-struct grub_usb_desc_endp *
-grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr)
-{
-  int i;
-
-  for (i = 0; i < usbdev->config[0].descconf->numif; i++)
-    {
-      struct grub_usb_desc_if *interf;
-      int j;
-
-      interf = usbdev->config[0].interf[i].descif;
-
-      for (j = 0; j < interf->endpointcnt; j++)
-       {
-         struct grub_usb_desc_endp *endp;
-         endp = &usbdev->config[0].interf[i].descendp[j];
-
-         if (endp->endp_addr == addr)
-           return endp;
-       }
-    }
-
-  return NULL;
-}
-
-grub_usb_err_t
-grub_usb_device_initialize (grub_usb_device_t dev)
-{
-  struct grub_usb_desc_device *descdev;
-  struct grub_usb_desc_config config;
-  grub_usb_err_t err;
-  int i;
-
-  err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE,
-                                0, sizeof (struct grub_usb_desc_device),
-                                (char *) &dev->descdev);
-  if (err)
-    return err;
-  descdev = &dev->descdev;
-
-  for (i = 0; i < 8; i++)
-    dev->config[i].descconf = NULL;
-
-  for (i = 0; i < descdev->configcnt; i++)
-    {
-      int pos;
-      int currif;
-      char *data;
-
-      /* First just read the first 4 bytes of the configuration
-        descriptor, after that it is known how many bytes really have
-        to be read.  */
-      err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i, 4,
-                                    (char *) &config);
-
-      data = grub_malloc (config.totallen);
-      if (! data)
-       {
-         err = GRUB_USB_ERR_INTERNAL;
-         goto fail;
-       }
-
-      dev->config[i].descconf = (struct grub_usb_desc_config *) data;
-      err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i,
-                                    config.totallen, data);
-      if (err)
-       goto fail;
-
-      /* Skip the configuration descriptor.  */
-      pos = sizeof (struct grub_usb_desc_config);
-
-      /* Read all interfaces.  */
-      for (currif = 0; currif < dev->config[i].descconf->numif; currif++)
-       {
-         dev->config[i].interf[currif].descif
-           = (struct grub_usb_desc_if *) &data[pos];
-         pos += sizeof (struct grub_usb_desc_if);
-
-         /* Point to the first endpoint.  */
-         dev->config[i].interf[currif].descendp
-           = (struct grub_usb_desc_endp *) &data[pos];
-         pos += (sizeof (struct grub_usb_desc_endp)
-                 * dev->config[i].interf[currif].descif->endpointcnt);
-       }
-    }
-
-  return GRUB_USB_ERR_NONE;
-
- fail:
-
-  for (i = 0; i < 8; i++)
-    grub_free (dev->config[i].descconf);
-
-  return err;
-}
diff --git a/bus/usb/usbhub.c b/bus/usb/usbhub.c
deleted file mode 100644 (file)
index 523abf9..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/* usb.c - USB Hub Support.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/usb.h>
-#include <grub/misc.h>
-
-/* USB Supports 127 devices, with device 0 as special case.  */
-static struct grub_usb_device *grub_usb_devs[128];
-
-/* Add a device that currently has device number 0 and resides on
-   CONTROLLER, the Hub reported that the device speed is SPEED.  */
-static grub_usb_device_t
-grub_usb_hub_add_dev (grub_usb_controller_t controller, grub_usb_speed_t speed)
-{
-  grub_usb_device_t dev;
-  int i;
-
-  dev = grub_zalloc (sizeof (struct grub_usb_device));
-  if (! dev)
-    return NULL;
-
-  dev->controller = *controller;
-  dev->speed = speed;
-
-  grub_usb_device_initialize (dev);
-
-  /* Assign a new address to the device.  */
-  for (i = 1; i < 128; i++)
-    {
-      if (! grub_usb_devs[i])
-       break;
-    }
-  if (i == 128)
-    {
-      grub_error (GRUB_ERR_IO, "can't assign address to USB device");
-      return NULL;
-    }
-
-  grub_usb_control_msg (dev,
-                       (GRUB_USB_REQTYPE_OUT
-                        | GRUB_USB_REQTYPE_STANDARD
-                        | GRUB_USB_REQTYPE_TARGET_DEV),
-                       GRUB_USB_REQ_SET_ADDRESS,
-                       i, 0, 0, NULL);
-
-  dev->addr = i;
-  dev->initialized = 1;
-  grub_usb_devs[i] = dev;
-
-  return dev;
-}
-
-\f
-static grub_err_t
-grub_usb_add_hub (grub_usb_device_t dev)
-{
-  struct grub_usb_usb_hubdesc hubdesc;
-  grub_err_t err;
-  int i;
-
-  grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
-                             | GRUB_USB_REQTYPE_CLASS
-                             | GRUB_USB_REQTYPE_TARGET_DEV),
-                       GRUB_USB_REQ_GET_DESCRIPTOR,
-                       (GRUB_USB_DESCRIPTOR_HUB << 8) | 0,
-                       0, sizeof (hubdesc), (char *) &hubdesc);
-
-  /* Iterate over the Hub ports.  */
-  for (i = 1; i <= hubdesc.portcnt; i++)
-    {
-      grub_uint32_t status;
-
-      /* Get the port status.  */
-      err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
-                                       | GRUB_USB_REQTYPE_CLASS
-                                       | GRUB_USB_REQTYPE_TARGET_OTHER),
-                                 GRUB_USB_REQ_HUB_GET_PORT_STATUS,
-                                 0, i, sizeof (status), (char *) &status);
-
-      /* Just ignore the device if the Hub does not report the
-        status.  */
-      if (err)
-       continue;
-
-      /* If connected, reset and enable the port.  */
-      if (status & GRUB_USB_HUB_STATUS_CONNECTED)
-       {
-         grub_usb_speed_t speed;
-
-         /* Determine the device speed.  */
-         if (status & GRUB_USB_HUB_STATUS_LOWSPEED)
-           speed = GRUB_USB_SPEED_LOW;
-         else
-           {
-             if (status & GRUB_USB_HUB_STATUS_HIGHSPEED)
-               speed = GRUB_USB_SPEED_HIGH;
-             else
-               speed = GRUB_USB_SPEED_FULL;
-           }
-
-         /* A device is actually connected to this port, not enable
-            the port.  XXX: Why 0x03?  According to some docs it
-            should be 0x0.  Check the specification!  */
-         err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
-                                           | GRUB_USB_REQTYPE_CLASS
-                                           | GRUB_USB_REQTYPE_TARGET_OTHER),
-                                     0x3, 0x4, i, 0, 0);
-
-         /* If the Hub does not cooperate for this port, just skip
-            the port.  */
-         if (err)
-           continue;
-
-         /* Add the device and assign a device address to it.  */
-         grub_usb_hub_add_dev (&dev->controller, speed);
-       }
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-grub_usb_err_t
-grub_usb_root_hub (grub_usb_controller_t controller)
-{
-  grub_err_t err;
-  int ports;
-  int i;
-
-  /* Query the number of ports the root Hub has.  */
-  ports = controller->dev->hubports (controller);
-
-  for (i = 0; i < ports; i++)
-    {
-      grub_usb_speed_t speed = controller->dev->detect_dev (controller, i);
-
-      if (speed != GRUB_USB_SPEED_NONE)
-       {
-         grub_usb_device_t dev;
-
-         /* Enable the port.  */
-         err = controller->dev->portstatus (controller, i, 1);
-         if (err)
-           continue;
-
-         /* Enable the port and create a device.  */
-         dev = grub_usb_hub_add_dev (controller, speed);
-         if (! dev)
-           continue;
-
-         /* If the device is a Hub, scan it for more devices.  */
-         if (dev->descdev.class == 0x09)
-           grub_usb_add_hub (dev);
-       }
-    }
-
-  return GRUB_USB_ERR_NONE;
-}
-
-int
-grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
-{
-  int i;
-
-  for (i = 0; i < 128; i++)
-    {
-      if (grub_usb_devs[i])
-       {
-         if (hook (grub_usb_devs[i]))
-             return 1;
-       }
-    }
-
-  return 0;
-}
diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c
deleted file mode 100644 (file)
index 09e7af8..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/* usbtrans.c - USB Transfers and Transactions.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/usb.h>
-#include <grub/usbtrans.h>
-
-grub_usb_err_t
-grub_usb_control_msg (grub_usb_device_t dev,
-                     grub_uint8_t reqtype,
-                     grub_uint8_t request,
-                     grub_uint16_t value,
-                     grub_uint16_t index,
-                     grub_size_t size, char *data)
-{
-  int i;
-  grub_usb_transfer_t transfer;
-  int datablocks;
-  struct grub_usb_packet_setup setupdata;
-  grub_usb_err_t err;
-  unsigned int max;
-
-  grub_dprintf ("usb",
-               "control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%d\n",
-               reqtype, request,  value, index, size);
-
-  /* Create a transfer.  */
-  transfer = grub_malloc (sizeof (struct grub_usb_transfer));
-  if (! transfer)
-    return grub_errno;
-
-  /* Determine the maximum packet size.  */
-  if (dev->initialized)
-    max = dev->descdev.maxsize0;
-  else
-    max = 64;
-
-  datablocks = (size + max - 1) / max;
-
-  /* XXX: Discriminate between different types of control
-     messages.  */
-  transfer->transcnt = datablocks + 2;
-  transfer->size = size; /* XXX ? */
-  transfer->endpoint = 0;
-  transfer->devaddr = dev->addr;
-  transfer->type = GRUB_USB_TRANSACTION_TYPE_CONTROL;
-  transfer->max = max;
-  transfer->dev = dev;
-
-  /* Allocate an array of transfer data structures.  */
-  transfer->transactions = grub_malloc (transfer->transcnt
-                                       * sizeof (struct grub_usb_transfer));
-  if (! transfer->transactions)
-    {
-      grub_free (transfer);
-      return grub_errno;
-    }
-
-  /* Build a Setup packet.  XXX: Endianness.  */
-  setupdata.reqtype = reqtype;
-  setupdata.request = request;
-  setupdata.value = value;
-  setupdata.index = index;
-  setupdata.length = size;
-  transfer->transactions[0].size = sizeof (setupdata);
-  transfer->transactions[0].pid = GRUB_USB_TRANSFER_TYPE_SETUP;
-  transfer->transactions[0].data = (char *) &setupdata;
-  transfer->transactions[0].toggle = 0;
-
-  /* Now the data...  XXX: Is this the right way to transfer control
-     transfers?  */
-  for (i = 0; i < datablocks; i++)
-    {
-      grub_usb_transaction_t tr = &transfer->transactions[i + 1];
-
-      tr->size = (size > max) ? max : size;
-      /* Use the right most bit as the data toggle.  Simple and
-        effective.  */
-      tr->toggle = !(i & 1);
-      if (reqtype & 128)
-       tr->pid = GRUB_USB_TRANSFER_TYPE_IN;
-      else
-       tr->pid = GRUB_USB_TRANSFER_TYPE_OUT;
-      tr->data = &data[i * max];
-      size -= max;
-    }
-
-  /* End with an empty OUT transaction.  */
-  transfer->transactions[datablocks + 1].size = 0;
-  transfer->transactions[datablocks + 1].data = NULL;
-  if (reqtype & 128)
-    transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT;
-  else
-    transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_IN;
-
-  transfer->transactions[datablocks + 1].toggle = 1;
-
-  err = dev->controller.dev->transfer (&dev->controller, transfer);
-
-  grub_free (transfer->transactions);
-  grub_free (transfer);
-
-  return err;
-}
-
-static grub_usb_err_t
-grub_usb_bulk_readwrite (grub_usb_device_t dev,
-                        int endpoint, grub_size_t size, char *data,
-                        grub_transfer_type_t type)
-{
-  int i;
-  grub_usb_transfer_t transfer;
-  int datablocks;
-  unsigned int max;
-  grub_usb_err_t err;
-  int toggle = dev->toggle[endpoint];
-
-  /* Use the maximum packet size given in the endpoint descriptor.  */
-  if (dev->initialized)
-    {
-      struct grub_usb_desc_endp *endpdesc;
-      endpdesc = grub_usb_get_endpdescriptor (dev, 0);
-
-      if (endpdesc)
-       max = endpdesc->maxpacket;
-      else
-       max = 64;
-    }
-  else
-    max = 64;
-
-  /* Create a transfer.  */
-  transfer = grub_malloc (sizeof (struct grub_usb_transfer));
-  if (! transfer)
-    return grub_errno;
-
-  datablocks = ((size + max - 1) / max);
-  transfer->transcnt = datablocks;
-  transfer->size = size - 1;
-  transfer->endpoint = endpoint;
-  transfer->devaddr = dev->addr;
-  transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK;
-  transfer->max = max;
-  transfer->dev = dev;
-
-  /* Allocate an array of transfer data structures.  */
-  transfer->transactions = grub_malloc (transfer->transcnt
-                                       * sizeof (struct grub_usb_transfer));
-  if (! transfer->transactions)
-    {
-      grub_free (transfer);
-      return grub_errno;
-    }
-
-  /* Set up all transfers.  */
-  for (i = 0; i < datablocks; i++)
-    {
-      grub_usb_transaction_t tr = &transfer->transactions[i];
-
-      tr->size = (size > max) ? max : size;
-      /* XXX: Use the right most bit as the data toggle.  Simple and
-        effective.  */
-      tr->toggle = toggle;
-      toggle = toggle ? 0 : 1;
-      tr->pid = type;
-      tr->data = &data[i * max];
-      size -= tr->size;
-    }
-
-  err = dev->controller.dev->transfer (&dev->controller, transfer);
-  grub_dprintf ("usb", "toggle=%d\n", toggle);
-  dev->toggle[endpoint] = toggle;
-
-  grub_free (transfer->transactions);
-  grub_free (transfer);
-
-  return err;
-}
-
-grub_usb_err_t
-grub_usb_bulk_write (grub_usb_device_t dev,
-                    int endpoint, grub_size_t size, char *data)
-{
-  return grub_usb_bulk_readwrite (dev, endpoint, size, data,
-                                 GRUB_USB_TRANSFER_TYPE_OUT);
-}
-
-grub_usb_err_t
-grub_usb_bulk_read (grub_usb_device_t dev,
-                   int endpoint, grub_size_t size, char *data)
-{
-  return grub_usb_bulk_readwrite (dev, endpoint, size, data,
-                                 GRUB_USB_TRANSFER_TYPE_IN);
-}
diff --git a/commands/acpi.c b/commands/acpi.c
deleted file mode 100644 (file)
index 5bbfd00..0000000
+++ /dev/null
@@ -1,774 +0,0 @@
-/* acpi.c - modify acpi tables. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/extcmd.h>
-#include <grub/file.h>
-#include <grub/disk.h>
-#include <grub/term.h>
-#include <grub/misc.h>
-#include <grub/gzio.h>
-#include <grub/acpi.h>
-#include <grub/mm.h>
-#include <grub/machine/memory.h>
-#include <grub/memory.h>
-#include <grub/i18n.h>
-
-#ifdef GRUB_MACHINE_EFI
-#include <grub/efi/efi.h>
-#include <grub/efi/api.h>
-#endif
-
-static const struct grub_arg_option options[] = {
-  {"exclude", 'x', 0,
-   N_("Don't load host tables specified by comma-separated list."),
-   0, ARG_TYPE_STRING},
-  {"load-only", 'n', 0,
-   N_("Load only tables specified by comma-separated list."), 0, ARG_TYPE_STRING},
-  {"v1", '1', 0, N_("Expose v1 tables."), 0, ARG_TYPE_NONE},
-  {"v2", '2', 0, N_("Expose v2 and v3 tables."), 0, ARG_TYPE_NONE},
-  {"oemid", 'o', 0, N_("Set OEMID of RSDP, XSDT and RSDT."), 0, ARG_TYPE_STRING},
-  {"oemtable", 't', 0,
-   N_("Set OEMTABLE ID of RSDP, XSDT and RSDT."), 0, ARG_TYPE_STRING},
-  {"oemtablerev", 'r', 0,
-   N_("Set OEMTABLE revision of RSDP, XSDT and RSDT."), 0, ARG_TYPE_INT},
-  {"oemtablecreator", 'c', 0,
-   N_("Set creator field of RSDP, XSDT and RSDT."), 0, ARG_TYPE_STRING},
-  {"oemtablecreatorrev", 'd', 0,
-   N_("Set creator revision of RSDP, XSDT and RSDT."), 0, ARG_TYPE_INT},
-  {"no-ebda", 'e', 0, N_("Don't update EBDA. May fix failures or hangs on some."
-   " BIOSes but makes it ineffective with OS not receiving RSDP from GRUB."),
-   0, ARG_TYPE_NONE},
-  {0, 0, 0, 0, 0, 0}
-};
-
-/* Simple checksum by summing all bytes. Used by ACPI and SMBIOS. */
-grub_uint8_t
-grub_byte_checksum (void *base, grub_size_t size)
-{
-  grub_uint8_t *ptr;
-  grub_uint8_t ret = 0;
-  for (ptr = (grub_uint8_t *) base; ptr < ((grub_uint8_t *) base) + size;
-       ptr++)
-    ret += *ptr;
-  return ret;
-}
-
-/* rev1 is 1 if ACPIv1 is to be generated, 0 otherwise.
-   rev2 contains the revision of ACPIv2+ to generate or 0 if none. */
-static int rev1, rev2;
-/* OEMID of RSDP, RSDT and XSDT. */
-static char root_oemid[6];
-/* OEMTABLE of the same tables. */
-static char root_oemtable[8];
-/* OEMREVISION of the same tables. */
-static grub_uint32_t root_oemrev;
-/* CreatorID of the same tables. */
-static char root_creator_id[4];
-/* CreatorRevision of the same tables. */
-static grub_uint32_t root_creator_rev;
-static struct grub_acpi_rsdp_v10 *rsdpv1_new = 0;
-static struct grub_acpi_rsdp_v20 *rsdpv2_new = 0;
-static char *playground = 0, *playground_ptr = 0;
-static int playground_size = 0;
-
-/* Linked list of ACPI tables. */
-struct efiemu_acpi_table
-{
-  void *addr;
-  grub_size_t size;
-  struct efiemu_acpi_table *next;
-};
-static struct efiemu_acpi_table *acpi_tables = 0;
-
-/* DSDT isn't in RSDT. So treat it specially. */
-static void *table_dsdt = 0;
-/* Pointer to recreated RSDT. */
-static void *rsdt_addr = 0;
-
-/* Allocation handles for different tables. */
-static grub_size_t dsdt_size = 0;
-
-/* Address of original FACS. */
-static grub_uint32_t facs_addr = 0;
-
-struct grub_acpi_rsdp_v20 *
-grub_acpi_get_rsdpv2 (void)
-{
-  if (rsdpv2_new)
-    return rsdpv2_new;
-  if (rsdpv1_new)
-    return 0;
-  return grub_machine_acpi_get_rsdpv2 ();
-}
-
-struct grub_acpi_rsdp_v10 *
-grub_acpi_get_rsdpv1 (void)
-{
-  if (rsdpv1_new)
-    return rsdpv1_new;
-  if (rsdpv2_new)
-    return 0;
-  return grub_machine_acpi_get_rsdpv1 ();
-}
-
-static inline int
-iszero (grub_uint8_t *reg, int size)
-{
-  int i;
-  for (i = 0; i < size; i++)
-    if (reg[i])
-      return 0;
-  return 1;
-}
-
-grub_err_t
-grub_acpi_create_ebda (void)
-{
-  int ebda_kb_len;
-  int ebda_len;
-  int mmapregion = 0;
-  grub_uint8_t *ebda, *v1inebda = 0, *v2inebda = 0;
-  grub_uint64_t highestlow = 0;
-  grub_uint8_t *targetebda, *target;
-  struct grub_acpi_rsdp_v10 *v1;
-  struct grub_acpi_rsdp_v20 *v2;
-  auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t,
-                                      grub_uint32_t);
-  int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t size,
-                                 grub_uint32_t type)
-  {
-    grub_uint64_t end = start + size;
-    if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
-      return 0;
-    if (end > 0x100000)
-      end = 0x100000;
-    if (end > start + ebda_len
-       && highestlow < ((end - ebda_len) & (~0xf)) )
-      highestlow = (end - ebda_len) & (~0xf);
-    return 0;
-  }
-
-  ebda = (grub_uint8_t *) UINT_TO_PTR ((*((grub_uint16_t *)0x40e)) << 4);
-  ebda_kb_len = *(grub_uint16_t *) ebda;
-  if (! ebda || ebda_kb_len > 16)
-    ebda_kb_len = 0;
-  ebda_len = (ebda_kb_len + 1) << 10;
-
-  /* FIXME: use low-memory mm allocation once it's available. */
-  grub_mmap_iterate (find_hook);
-  targetebda = (grub_uint8_t *) UINT_TO_PTR (highestlow);
-  grub_dprintf ("acpi", "creating ebda @%llx\n",
-               (unsigned long long) highestlow);
-  if (! highestlow)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                      "couldn't find space for the new EBDA");
-
-  mmapregion = grub_mmap_register (PTR_TO_UINT64 (targetebda), ebda_len,
-                                  GRUB_MACHINE_MEMORY_RESERVED);
-  if (! mmapregion)
-    return grub_errno;
-
-  /* XXX: EBDA is unstandardized, so this implementation is heuristical. */
-  if (ebda_kb_len)
-    grub_memcpy (targetebda, ebda, 0x400);
-  else
-    grub_memset (targetebda, 0, 0x400);
-  *((grub_uint16_t *) targetebda) = ebda_kb_len + 1;
-  target = targetebda;
-
-  v1 = grub_acpi_get_rsdpv1 ();
-  v2 = grub_acpi_get_rsdpv2 ();
-  if (v2 && v2->length > 40)
-    v2 = 0;
-
-  /* First try to replace already existing rsdp. */
-  if (v2)
-    {
-      grub_dprintf ("acpi", "Scanning EBDA for old rsdpv2\n");
-      for (; target < targetebda + 0x400 - v2->length; target += 0x10)
-       if (grub_memcmp (target, "RSD PTR ", 8) == 0
-           && grub_byte_checksum (target,
-                                  sizeof (struct grub_acpi_rsdp_v10)) == 0
-           && ((struct grub_acpi_rsdp_v10 *) target)->revision != 0
-           && ((struct grub_acpi_rsdp_v20 *) target)->length <= v2->length)
-         {
-           grub_memcpy (target, v2, v2->length);
-           grub_dprintf ("acpi", "Copying rsdpv2 to %p\n", target);
-           v2inebda = target;
-           target += v2->length;
-           target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1);
-           v2 = 0;
-           break;
-         }
-    }
-
-  if (v1)
-    {
-      grub_dprintf ("acpi", "Scanning EBDA for old rsdpv1\n");
-      for (; target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10);
-          target += 0x10)
-       if (grub_memcmp (target, "RSD PTR ", 8) == 0
-           && grub_byte_checksum (target,
-                                  sizeof (struct grub_acpi_rsdp_v10)) == 0)
-         {
-           grub_memcpy (target, v1, sizeof (struct grub_acpi_rsdp_v10));
-           grub_dprintf ("acpi", "Copying rsdpv1 to %p\n", target);
-           v1inebda = target;
-           target += sizeof (struct grub_acpi_rsdp_v10);
-           target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1);
-           v1 = 0;
-           break;
-         }
-    }
-
-  target = targetebda + 0x100;
-
-  /* Try contiguous zeros. */
-  if (v2)
-    {
-      grub_dprintf ("acpi", "Scanning EBDA for block of zeros\n");
-      for (; target < targetebda + 0x400 - v2->length; target += 0x10)
-       if (iszero (target, v2->length))
-         {
-           grub_dprintf ("acpi", "Copying rsdpv2 to %p\n", target);
-           grub_memcpy (target, v2, v2->length);
-           v2inebda = target;
-           target += v2->length;
-           target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1);
-           v2 = 0;
-           break;
-         }
-    }
-
-  if (v1)
-    {
-      grub_dprintf ("acpi", "Scanning EBDA for block of zeros\n");
-      for (; target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10);
-          target += 0x10)
-       if (iszero (target, sizeof (struct grub_acpi_rsdp_v10)))
-         {
-           grub_dprintf ("acpi", "Copying rsdpv1 to %p\n", target);
-           grub_memcpy (target, v1, sizeof (struct grub_acpi_rsdp_v10));
-           v1inebda = target;
-           target += sizeof (struct grub_acpi_rsdp_v10);
-           target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1);
-           v1 = 0;
-           break;
-         }
-    }
-
-  if (v1 || v2)
-    {
-      grub_mmap_unregister (mmapregion);
-      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                        "couldn't find suitable spot in EBDA");
-    }
-
-  /* Remove any other RSDT. */
-  for (target = targetebda;
-       target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10);
-       target += 0x10)
-    if (grub_memcmp (target, "RSD PTR ", 8) == 0
-       && grub_byte_checksum (target,
-                              sizeof (struct grub_acpi_rsdp_v10)) == 0
-       && target != v1inebda && target != v2inebda)
-      *target = 0;
-
-  grub_dprintf ("acpi", "Switching EBDA\n");
-  (*((grub_uint16_t *) 0x40e)) = ((long)targetebda) >> 4;
-  grub_dprintf ("acpi", "EBDA switched\n");
-
-  return GRUB_ERR_NONE;
-}
-
-/* Create tables common to ACPIv1 and ACPIv2+ */
-static void
-setup_common_tables (void)
-{
-  struct efiemu_acpi_table *cur;
-  struct grub_acpi_table_header *rsdt;
-  grub_uint32_t *rsdt_entry;
-  int numoftables;
-
-  /* Treat DSDT. */
-  grub_memcpy (playground_ptr, table_dsdt, dsdt_size);
-  grub_free (table_dsdt);
-  table_dsdt = playground_ptr;
-  playground_ptr += dsdt_size;
-
-  /* Treat other tables. */
-  for (cur = acpi_tables; cur; cur = cur->next)
-    {
-      struct grub_acpi_fadt *fadt;
-
-      grub_memcpy (playground_ptr, cur->addr, cur->size);
-      grub_free (cur->addr);
-      cur->addr = playground_ptr;
-      playground_ptr += cur->size;
-
-      /* If it's FADT correct DSDT and FACS addresses. */
-      fadt = (struct grub_acpi_fadt *) cur->addr;
-      if (grub_memcmp (fadt->hdr.signature, "FACP", 4) == 0)
-       {
-         fadt->dsdt_addr = PTR_TO_UINT32 (table_dsdt);
-         fadt->facs_addr = facs_addr;
-
-         /* Does a revision 2 exist at all? */
-         if (fadt->hdr.revision >= 3)
-           {
-             fadt->dsdt_xaddr = PTR_TO_UINT64 (table_dsdt);
-             fadt->facs_xaddr = facs_addr;
-           }
-
-         /* Recompute checksum. */
-         fadt->hdr.checksum = 0;
-         fadt->hdr.checksum = 1 + ~grub_byte_checksum (fadt, fadt->hdr.length);
-       }
-    }
-
-  /* Fill RSDT entries. */
-  numoftables = 0;
-  for (cur = acpi_tables; cur; cur = cur->next)
-    numoftables++;
-
-  rsdt_addr = rsdt = (struct grub_acpi_table_header *) playground_ptr;
-  playground_ptr += sizeof (struct grub_acpi_table_header) + 4 * numoftables;
-
-  rsdt_entry = (grub_uint32_t *)(rsdt + 1);
-
-  /* Fill RSDT header. */
-  grub_memcpy (&(rsdt->signature), "RSDT", 4);
-  rsdt->length = sizeof (struct grub_acpi_table_header) + 4 * numoftables;
-  rsdt->revision = 1;
-  grub_memcpy (&(rsdt->oemid), root_oemid, 6);
-  grub_memcpy (&(rsdt->oemtable), root_oemtable, 4);
-  rsdt->oemrev = root_oemrev;
-  grub_memcpy (&(rsdt->creator_id), root_creator_id, 6);
-  rsdt->creator_rev = root_creator_rev;
-
-  for (cur = acpi_tables; cur; cur = cur->next)
-    *(rsdt_entry++) = PTR_TO_UINT32 (cur->addr);
-
-  /* Recompute checksum. */
-  rsdt->checksum = 0;
-  rsdt->checksum = 1 + ~grub_byte_checksum (rsdt, rsdt->length);
-}
-
-/* Regenerate ACPIv1 RSDP */
-static void
-setv1table (void)
-{
-  /* Create RSDP. */
-  rsdpv1_new = (struct grub_acpi_rsdp_v10 *) playground_ptr;
-  playground_ptr += sizeof (struct grub_acpi_rsdp_v10);
-  grub_memcpy (&(rsdpv1_new->signature), "RSD PTR ", 8);
-  grub_memcpy (&(rsdpv1_new->oemid), root_oemid, sizeof  (rsdpv1_new->oemid));
-  rsdpv1_new->revision = 0;
-  rsdpv1_new->rsdt_addr = PTR_TO_UINT32 (rsdt_addr);
-  rsdpv1_new->checksum = 0;
-  rsdpv1_new->checksum = 1 + ~grub_byte_checksum (rsdpv1_new,
-                                                 sizeof (*rsdpv1_new));
-  grub_dprintf ("acpi", "Generated ACPIv1 tables\n");
-}
-
-static void
-setv2table (void)
-{
-  struct grub_acpi_table_header *xsdt;
-  struct efiemu_acpi_table *cur;
-  grub_uint64_t *xsdt_entry;
-  int numoftables;
-
-  numoftables = 0;
-  for (cur = acpi_tables; cur; cur = cur->next)
-    numoftables++;
-
-  /* Create XSDT. */
-  xsdt = (struct grub_acpi_table_header *) playground_ptr;
-  playground_ptr += sizeof (struct grub_acpi_table_header) + 8 * numoftables;
-
-  xsdt_entry = (grub_uint64_t *)(xsdt + 1);
-  for (cur = acpi_tables; cur; cur = cur->next)
-    *(xsdt_entry++) = PTR_TO_UINT64 (cur->addr);
-  grub_memcpy (&(xsdt->signature), "XSDT", 4);
-  xsdt->length = sizeof (struct grub_acpi_table_header) + 8 * numoftables;
-  xsdt->revision = 1;
-  grub_memcpy (&(xsdt->oemid), root_oemid, sizeof (xsdt->oemid));
-  grub_memcpy (&(xsdt->oemtable), root_oemtable, sizeof (xsdt->oemtable));
-  xsdt->oemrev = root_oemrev;
-  grub_memcpy (&(xsdt->creator_id), root_creator_id, sizeof (xsdt->creator_id));
-  xsdt->creator_rev = root_creator_rev;
-  xsdt->checksum = 0;
-  xsdt->checksum = 1 + ~grub_byte_checksum (xsdt, xsdt->length);
-
-  /* Create RSDPv2. */
-  rsdpv2_new = (struct grub_acpi_rsdp_v20 *) playground_ptr;
-  playground_ptr += sizeof (struct grub_acpi_rsdp_v20);
-  grub_memcpy (&(rsdpv2_new->rsdpv1.signature), "RSD PTR ",
-              sizeof (rsdpv2_new->rsdpv1.signature));
-  grub_memcpy (&(rsdpv2_new->rsdpv1.oemid), root_oemid,
-              sizeof (rsdpv2_new->rsdpv1.oemid));
-  rsdpv2_new->rsdpv1.revision = rev2;
-  rsdpv2_new->rsdpv1.rsdt_addr = PTR_TO_UINT32 (rsdt_addr);
-  rsdpv2_new->rsdpv1.checksum = 0;
-  rsdpv2_new->rsdpv1.checksum = 1 + ~grub_byte_checksum
-    (&(rsdpv2_new->rsdpv1), sizeof (rsdpv2_new->rsdpv1));
-  rsdpv2_new->length = sizeof (*rsdpv2_new);
-  rsdpv2_new->xsdt_addr = PTR_TO_UINT64 (xsdt);
-  rsdpv2_new->checksum = 0;
-  rsdpv2_new->checksum = 1 + ~grub_byte_checksum (rsdpv2_new,
-                                                 rsdpv2_new->length);
-  grub_dprintf ("acpi", "Generated ACPIv2 tables\n");
-}
-
-static void
-free_tables (void)
-{
-  struct efiemu_acpi_table *cur, *t;
-  if (table_dsdt)
-    grub_free (table_dsdt);
-  for (cur = acpi_tables; cur;)
-    {
-      t = cur;
-      grub_free (cur->addr);
-      cur = cur->next;
-      grub_free (t);
-    }
-  acpi_tables = 0;
-  table_dsdt = 0;
-}
-
-static grub_err_t
-grub_cmd_acpi (struct grub_extcmd *cmd,
-                     int argc, char **args)
-{
-  struct grub_arg_list *state = cmd->state;
-  struct grub_acpi_rsdp_v10 *rsdp;
-  struct efiemu_acpi_table *cur, *t;
-  grub_err_t err;
-  int i, mmapregion;
-  int numoftables;
-
-  /* Default values if no RSDP is found. */
-  rev1 = 1;
-  rev2 = 3;
-
-  facs_addr = 0;
-  playground = playground_ptr = 0;
-  playground_size = 0;
-
-  rsdp = (struct grub_acpi_rsdp_v10 *) grub_machine_acpi_get_rsdpv2 ();
-
-  if (! rsdp)
-    rsdp = grub_machine_acpi_get_rsdpv1 ();
-
-  if (rsdp)
-    {
-      grub_uint32_t *entry_ptr;
-      char *exclude = 0;
-      char *load_only = 0;
-      char *ptr;
-      /* RSDT consists of header and an array of 32-bit pointers. */
-      struct grub_acpi_table_header *rsdt;
-
-      exclude = state[0].set ? grub_strdup (state[0].arg) : 0;
-      if (exclude)
-       {
-         for (ptr = exclude; *ptr; ptr++)
-           *ptr = grub_tolower (*ptr);
-       }
-
-      load_only = state[1].set ? grub_strdup (state[1].arg) : 0;
-      if (load_only)
-       {
-         for (ptr = load_only; *ptr; ptr++)
-           *ptr = grub_tolower (*ptr);
-       }
-
-      /* Set revision variables to replicate the same version as host. */
-      rev1 = ! rsdp->revision;
-      rev2 = rsdp->revision;
-      rsdt = (struct grub_acpi_table_header *) UINT_TO_PTR (rsdp->rsdt_addr);
-      /* Load host tables. */
-      for (entry_ptr = (grub_uint32_t *) (rsdt + 1);
-          entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt)
-                                         + rsdt->length);
-          entry_ptr++)
-       {
-         char signature[5];
-         struct efiemu_acpi_table *table;
-         struct grub_acpi_table_header *curtable
-           = (struct grub_acpi_table_header *) UINT_TO_PTR (*entry_ptr);
-         signature[4] = 0;
-         for (i = 0; i < 4;i++)
-           signature[i] = grub_tolower (curtable->signature[i]);
-
-         /* If it's FADT it contains addresses of DSDT and FACS. */
-         if (grub_strcmp (signature, "facp") == 0)
-           {
-             struct grub_acpi_table_header *dsdt;
-             struct grub_acpi_fadt *fadt = (struct grub_acpi_fadt *) curtable;
-
-             /* Set root header variables to the same values
-                as FACP by default. */
-             grub_memcpy (&root_oemid, &(fadt->hdr.oemid),
-                          sizeof (root_oemid));
-             grub_memcpy (&root_oemtable, &(fadt->hdr.oemtable),
-                          sizeof (root_oemtable));
-             root_oemrev = fadt->hdr.oemrev;
-             grub_memcpy (&root_creator_id, &(fadt->hdr.creator_id),
-                          sizeof (root_creator_id));
-             root_creator_rev = fadt->hdr.creator_rev;
-
-             /* Load DSDT if not excluded. */
-             dsdt = (struct grub_acpi_table_header *)
-               UINT_TO_PTR (fadt->dsdt_addr);
-             if (dsdt && (! exclude || ! grub_strword (exclude, "dsdt"))
-                 && (! load_only || grub_strword (load_only, "dsdt"))
-                 && dsdt->length >= sizeof (*dsdt))
-               {
-                 dsdt_size = dsdt->length;
-                 table_dsdt = grub_malloc (dsdt->length);
-                 if (! table_dsdt)
-                   {
-                     free_tables ();
-                     grub_free (exclude);
-                     grub_free (load_only);
-                     return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                                        "couldn't allocate table");
-                   }
-                 grub_memcpy (table_dsdt, dsdt, dsdt->length);
-               }
-
-             /* Save FACS address. FACS shouldn't be overridden. */
-             facs_addr = fadt->facs_addr;
-           }
-
-         /* Skip excluded tables. */
-         if (exclude && grub_strword (exclude, signature))
-           continue;
-         if (load_only && ! grub_strword (load_only, signature))
-           continue;
-
-         /* Sanity check. */
-         if (curtable->length < sizeof (*curtable))
-           continue;
-
-         table = (struct efiemu_acpi_table *) grub_malloc
-           (sizeof (struct efiemu_acpi_table));
-         if (! table)
-           {
-             free_tables ();
-             grub_free (exclude);
-             grub_free (load_only);
-             return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                                "couldn't allocate table structure");
-           }
-         table->size = curtable->length;
-         table->addr = grub_malloc (table->size);
-         playground_size += table->size;
-         if (! table->addr)
-           {
-             free_tables ();
-             return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                                "couldn't allocate table");
-           }
-         table->next = acpi_tables;
-         acpi_tables = table;
-         grub_memcpy (table->addr, curtable, table->size);
-       }
-      grub_free (exclude);
-      grub_free (load_only);
-    }
-
-  /* Does user specify versions to generate? */
-  if (state[2].set || state[3].set)
-    {
-      rev1 = state[2].set;
-      if (state[3].set)
-       rev2 = rev2 ? : 2;
-      else
-       rev2 = 0;
-    }
-
-  /* Does user override root header information? */
-  if (state[4].set)
-    grub_strncpy (root_oemid, state[4].arg, sizeof (root_oemid));
-  if (state[5].set)
-    grub_strncpy (root_oemtable, state[5].arg, sizeof (root_oemtable));
-  if (state[6].set)
-    root_oemrev = grub_strtoul (state[6].arg, 0, 0);
-  if (state[7].set)
-    grub_strncpy (root_creator_id, state[7].arg, sizeof (root_creator_id));
-  if (state[8].set)
-    root_creator_rev = grub_strtoul (state[8].arg, 0, 0);
-
-  /* Load user tables */
-  for (i = 0; i < argc; i++)
-    {
-      grub_file_t file;
-      grub_size_t size;
-      char *buf;
-
-      file = grub_gzfile_open (args[i], 1);
-      if (! file)
-       {
-         free_tables ();
-         return grub_error (GRUB_ERR_BAD_OS, "couldn't open file %s", args[i]);
-       }
-
-      size = grub_file_size (file);
-      if (size < sizeof (struct grub_acpi_table_header))
-       {
-         grub_file_close (file);
-         free_tables ();
-         return grub_error (GRUB_ERR_BAD_OS, "file %s is too small", args[i]);
-       }
-
-      buf = (char *) grub_malloc (size);
-      if (! buf)
-       {
-         grub_file_close (file);
-         free_tables ();
-         return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                            "couldn't read file %s", args[i]);
-       }
-
-      if (grub_file_read (file, buf, size) != (int) size)
-       {
-         grub_file_close (file);
-         free_tables ();
-         return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[i]);
-       }
-      grub_file_close (file);
-
-      if (grub_memcmp (((struct grub_acpi_table_header *) buf)->signature,
-                      "DSDT", 4) == 0)
-       {
-         grub_free (table_dsdt);
-         table_dsdt = buf;
-         dsdt_size = size;
-       }
-      else
-       {
-         struct efiemu_acpi_table *table;
-         table = (struct efiemu_acpi_table *) grub_malloc
-           (sizeof (struct efiemu_acpi_table));
-         if (! table)
-           {
-             free_tables ();
-             return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                                "couldn't allocate table structure");
-           }
-
-         table->size = size;
-         table->addr = buf;
-         playground_size += table->size;
-
-         table->next = acpi_tables;
-         acpi_tables = table;
-       }
-    }
-
-  numoftables = 0;
-  for (cur = acpi_tables; cur; cur = cur->next)
-    numoftables++;
-
-  /* DSDT. */
-  playground_size += dsdt_size;
-  /* RSDT. */
-  playground_size += sizeof (struct grub_acpi_table_header) + 4 * numoftables;
-  /* RSDPv1. */
-  playground_size += sizeof (struct grub_acpi_rsdp_v10);
-  /* XSDT. */
-  playground_size += sizeof (struct grub_acpi_table_header) + 8 * numoftables;
-  /* RSDPv2. */
-  playground_size += sizeof (struct grub_acpi_rsdp_v20);
-
-  playground = playground_ptr
-    = grub_mmap_malign_and_register (1, playground_size, &mmapregion,
-                                    GRUB_MACHINE_MEMORY_ACPI, 0);
-
-  if (! playground)
-    {
-      free_tables ();
-      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                        "couldn't allocate space for ACPI tables");
-    }
-
-  setup_common_tables ();
-
-  /* Request space for RSDPv1. */
-  if (rev1)
-    setv1table ();
-
-  /* Request space for RSDPv2+ and XSDT. */
-  if (rev2)
-    setv2table ();
-
-  for (cur = acpi_tables; cur;)
-    {
-      t = cur;
-      cur = cur->next;
-      grub_free (t);
-    }
-  acpi_tables = 0;
-
-  if (! state[9].set && (err = grub_acpi_create_ebda ()))
-    {
-      rsdpv1_new = 0;
-      rsdpv2_new = 0;
-      grub_mmap_free_and_unregister (mmapregion);
-      return err;
-    }
-
-#ifdef GRUB_MACHINE_EFI
-  {
-    struct grub_efi_guid acpi = GRUB_EFI_ACPI_TABLE_GUID;
-    struct grub_efi_guid acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
-
-    grub_efi_system_table->boot_services->install_configuration_table
-      (&acpi20, grub_acpi_get_rsdpv2 ());
-    grub_efi_system_table->boot_services->install_configuration_table
-      (&acpi, grub_acpi_get_rsdpv1 ());
-  }
-#endif
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_extcmd_t cmd;
-
-GRUB_MOD_INIT(acpi)
-{
-  cmd = grub_register_extcmd ("acpi", grub_cmd_acpi,
-                             GRUB_COMMAND_FLAG_BOTH,
-                             N_("[-1|-2] [--exclude=TABLE1,TABLE2|"
-                             "--load-only=table1,table2] FILE1"
-                             " [FILE2] [...]"),
-                             N_("Load host ACPI tables and tables "
-                             "specified by arguments."),
-                             options);
-}
-
-GRUB_MOD_FINI(acpi)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/commands/blocklist.c b/commands/blocklist.c
deleted file mode 100644 (file)
index cace311..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/* blocklist.c - print the block list of a file */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/disk.h>
-#include <grub/partition.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)),
-                   int argc, char **args)
-{
-  grub_file_t file;
-  char buf[GRUB_DISK_SECTOR_SIZE];
-  unsigned long start_sector = 0;
-  unsigned num_sectors = 0;
-  int num_entries = 0;
-  grub_disk_addr_t part_start = 0;
-  auto void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned offset,
-                           unsigned length);
-  auto void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num,
-                            unsigned offset, unsigned length);
-
-  void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned offset,
-                      unsigned length)
-    {
-      if (num_sectors > 0)
-       {
-         if (start_sector + num_sectors == sector
-             && offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
-           {
-             num_sectors++;
-             return;
-           }
-
-         print_blocklist (start_sector, num_sectors, 0, 0);
-         num_sectors = 0;
-       }
-
-      if (offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
-       {
-         start_sector = sector;
-         num_sectors++;
-       }
-      else
-       print_blocklist (sector, 0, offset, length);
-    }
-
-  void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num,
-                       unsigned offset, unsigned length)
-    {
-      if (num_entries++)
-       grub_printf (",");
-
-      grub_printf ("%llu", (unsigned long long) (sector - part_start));
-      if (num > 0)
-       grub_printf ("+%u", num);
-      if (offset != 0 || length != 0)
-       grub_printf ("[%u-%u]", offset, offset + length);
-    }
-
-  if (argc < 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
-
-  file = grub_file_open (args[0]);
-  if (! file)
-    return grub_errno;
-
-  if (! file->device->disk)
-    return grub_error (GRUB_ERR_BAD_DEVICE,
-                      "this command is available only for disk devices");
-
-  part_start = grub_partition_get_start (file->device->disk->partition);
-
-  file->read_hook = read_blocklist;
-
-  while (grub_file_read (file, buf, sizeof (buf)) > 0)
-    ;
-
-  if (num_sectors > 0)
-    print_blocklist (start_sector, num_sectors, 0, 0);
-
-  grub_file_close (file);
-
-  return grub_errno;
-}
-
-static grub_command_t cmd;
-\f
-GRUB_MOD_INIT(blocklist)
-{
-  cmd = grub_register_command ("blocklist", grub_cmd_blocklist,
-                              N_("FILE"), N_("Print a block list."));
-}
-
-GRUB_MOD_FINI(blocklist)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/boot.c b/commands/boot.c
deleted file mode 100644 (file)
index 1ec1e6f..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-/* boot.c - command to boot an operating system */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/normal.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/loader.h>
-#include <grub/kernel.h>
-#include <grub/mm.h>
-#include <grub/i18n.h>
-
-static grub_err_t (*grub_loader_boot_func) (void);
-static grub_err_t (*grub_loader_unload_func) (void);
-static int grub_loader_noreturn;
-
-struct grub_preboot_t
-{
-  grub_err_t (*preboot_func) (int);
-  grub_err_t (*preboot_rest_func) (void);
-  grub_loader_preboot_hook_prio_t prio;
-  struct grub_preboot_t *next;
-  struct grub_preboot_t *prev;
-};
-
-static int grub_loader_loaded;
-static struct grub_preboot_t *preboots_head = 0,
-  *preboots_tail = 0;
-
-int
-grub_loader_is_loaded (void)
-{
-  return grub_loader_loaded;
-}
-
-/* Register a preboot hook. */
-void *
-grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noreturn),
-                                  grub_err_t (*preboot_rest_func) (void),
-                                  grub_loader_preboot_hook_prio_t prio)
-{
-  struct grub_preboot_t *cur, *new_preboot;
-
-  if (! preboot_func && ! preboot_rest_func)
-    return 0;
-
-  new_preboot = (struct grub_preboot_t *)
-    grub_malloc (sizeof (struct grub_preboot_t));
-  if (! new_preboot)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "hook not added");
-      return 0;
-    }
-
-  new_preboot->preboot_func = preboot_func;
-  new_preboot->preboot_rest_func = preboot_rest_func;
-  new_preboot->prio = prio;
-
-  for (cur = preboots_head; cur && cur->prio > prio; cur = cur->next);
-
-  if (cur)
-    {
-      new_preboot->next = cur;
-      new_preboot->prev = cur->prev;
-      cur->prev = new_preboot;
-    }
-  else
-    {
-      new_preboot->next = 0;
-      new_preboot->prev = preboots_tail;
-      preboots_tail = new_preboot;
-    }
-  if (new_preboot->prev)
-    new_preboot->prev->next = new_preboot;
-  else
-    preboots_head = new_preboot;
-
-  return new_preboot;
-}
-
-void
-grub_loader_unregister_preboot_hook (void *hnd)
-{
-  struct grub_preboot_t *preb = hnd;
-
-  if (preb->next)
-    preb->next->prev = preb->prev;
-  else
-    preboots_tail = preb->prev;
-  if (preb->prev)
-    preb->prev->next = preb->next;
-  else
-    preboots_head = preb->next;
-
-  grub_free (preb);
-}
-
-void
-grub_loader_set (grub_err_t (*boot) (void),
-                grub_err_t (*unload) (void),
-                int noreturn)
-{
-  if (grub_loader_loaded && grub_loader_unload_func)
-    grub_loader_unload_func ();
-
-  grub_loader_boot_func = boot;
-  grub_loader_unload_func = unload;
-  grub_loader_noreturn = noreturn;
-
-  grub_loader_loaded = 1;
-}
-
-void
-grub_loader_unset(void)
-{
-  if (grub_loader_loaded && grub_loader_unload_func)
-    grub_loader_unload_func ();
-
-  grub_loader_boot_func = 0;
-  grub_loader_unload_func = 0;
-
-  grub_loader_loaded = 0;
-}
-
-grub_err_t
-grub_loader_boot (void)
-{
-  grub_err_t err = GRUB_ERR_NONE;
-  struct grub_preboot_t *cur;
-
-  if (! grub_loader_loaded)
-    return grub_error (GRUB_ERR_NO_KERNEL, "no loaded kernel");
-
-  if (grub_loader_noreturn)
-    grub_machine_fini ();
-
-  for (cur = preboots_head; cur; cur = cur->next)
-    {
-      err = cur->preboot_func (grub_loader_noreturn);
-      if (err)
-       {
-         for (cur = cur->prev; cur; cur = cur->prev)
-           cur->preboot_rest_func ();
-         return err;
-       }
-    }
-  err = (grub_loader_boot_func) ();
-
-  for (cur = preboots_tail; cur; cur = cur->prev)
-    if (! err)
-      err = cur->preboot_rest_func ();
-    else
-      cur->preboot_rest_func ();
-
-  return err;
-}
-
-/* boot */
-static grub_err_t
-grub_cmd_boot (struct grub_command *cmd __attribute__ ((unused)),
-                   int argc __attribute__ ((unused)),
-                   char *argv[] __attribute__ ((unused)))
-{
-  return grub_loader_boot ();
-}
-
-\f
-
-static grub_command_t cmd_boot;
-
-GRUB_MOD_INIT(boot)
-{
-  cmd_boot =
-    grub_register_command ("boot", grub_cmd_boot,
-                          0, N_("Boot an operating system."));
-}
-
-GRUB_MOD_FINI(boot)
-{
-  grub_unregister_command (cmd_boot);
-}
diff --git a/commands/cat.c b/commands/cat.c
deleted file mode 100644 (file)
index 3bdafc4..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/* cat.c - command to show the contents of a file  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2005,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/file.h>
-#include <grub/disk.h>
-#include <grub/term.h>
-#include <grub/misc.h>
-#include <grub/gzio.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)),
-             int argc, char **args)
-
-{
-  grub_file_t file;
-  char buf[GRUB_DISK_SECTOR_SIZE];
-  grub_ssize_t size;
-  int key = 0;
-
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
-  file = grub_gzfile_open (args[0], 1);
-  if (! file)
-    return grub_errno;
-
-  while ((size = grub_file_read (file, buf, sizeof (buf))) > 0
-        && key != GRUB_TERM_ESC)
-    {
-      int i;
-
-      for (i = 0; i < size; i++)
-       {
-         unsigned char c = buf[i];
-
-         if ((grub_isprint (c) || grub_isspace (c)) && c != '\r')
-           grub_putchar (c);
-         else
-           {
-             grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
-             grub_printf ("<%x>", (int) c);
-             grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
-           }
-       }
-
-      while (grub_checkkey () >= 0 &&
-            (key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != GRUB_TERM_ESC)
-       ;
-    }
-
-  grub_putchar ('\n');
-  grub_refresh ();
-  grub_file_close (file);
-
-  return 0;
-}
-
-static grub_command_t cmd;
-\f
-GRUB_MOD_INIT(cat)
-{
-  cmd = grub_register_command_p1 ("cat", grub_cmd_cat,
-                                 N_("FILE"), N_("Show the contents of a file."));
-}
-
-GRUB_MOD_FINI(cat)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/cmp.c b/commands/cmp.c
deleted file mode 100644 (file)
index 626e1d0..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/* cmd.c - command to cmp an operating system */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2005,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/gzio.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-#define BUFFER_SIZE 512
-
-static grub_err_t
-grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)),
-             int argc, char **args)
-{
-  grub_ssize_t rd1, rd2;
-  grub_off_t pos;
-  grub_file_t file1 = 0;
-  grub_file_t file2 = 0;
-  char *buf1 = 0;
-  char *buf2 = 0;
-
-  if (argc != 2)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required");
-
-  grub_printf ("Compare file `%s' with `%s':\n", args[0],
-              args[1]);
-
-  file1 = grub_gzfile_open (args[0], 1);
-  file2 = grub_gzfile_open (args[1], 1);
-  if (! file1 || ! file2)
-    goto cleanup;
-
-  if (grub_file_size (file1) != grub_file_size (file2))
-    grub_printf ("Files differ in size: %llu [%s], %llu [%s]\n",
-                (unsigned long long) grub_file_size (file1), args[0],
-                (unsigned long long) grub_file_size (file2), args[1]);
-  else
-    {
-      pos = 0;
-
-      buf1 = grub_malloc (BUFFER_SIZE);
-      buf2 = grub_malloc (BUFFER_SIZE);
-
-      if (! buf1 || ! buf2)
-        goto cleanup;
-
-      do
-       {
-         int i;
-
-         rd1 = grub_file_read (file1, buf1, BUFFER_SIZE);
-         rd2 = grub_file_read (file2, buf2, BUFFER_SIZE);
-
-         if (rd1 != rd2)
-           goto cleanup;
-
-         for (i = 0; i < rd2; i++)
-           {
-             if (buf1[i] != buf2[i])
-               {
-                 grub_printf ("Files differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n",
-                              (unsigned long long) (i + pos), buf1[i], args[0],
-                              buf2[i], args[1]);
-                 goto cleanup;
-               }
-           }
-         pos += BUFFER_SIZE;
-
-       }
-      while (rd2);
-
-      grub_printf ("The files are identical.\n");
-    }
-
-cleanup:
-
-  if (buf1)
-    grub_free (buf1);
-  if (buf2)
-    grub_free (buf2);
-  if (file1)
-    grub_file_close (file1);
-  if (file2)
-    grub_file_close (file2);
-
-  return grub_errno;
-}
-
-static grub_command_t cmd;
-\f
-GRUB_MOD_INIT(cmp)
-{
-  cmd = grub_register_command ("cmp", grub_cmd_cmp,
-                              N_("FILE1 FILE2"), N_("Compare two files."));
-}
-
-GRUB_MOD_FINI(cmp)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/configfile.c b/commands/configfile.c
deleted file mode 100644 (file)
index 4694477..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* configfile.c - command to manually load config file  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/term.h>
-#include <grub/env.h>
-#include <grub/normal.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-grub_cmd_source (grub_command_t cmd, int argc, char **args)
-{
-  int new_env;
-
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
-  new_env = (cmd->name[0] == 'c');
-
-  if (new_env)
-    {
-      grub_cls ();
-      grub_env_context_open (1);
-    }
-
-  grub_normal_execute (args[0], 1, ! new_env);
-
-  if (new_env)
-    grub_env_context_close ();
-
-  return 0;
-}
-
-static grub_command_t cmd_configfile, cmd_source, cmd_dot;
-\f
-GRUB_MOD_INIT(configfile)
-{
-  cmd_configfile =
-    grub_register_command ("configfile", grub_cmd_source,
-                          N_("FILE"), N_("Load another config file."));
-  cmd_source =
-    grub_register_command ("source", grub_cmd_source,
-                          N_("FILE"),
-                          N_("Load another config file without changing context.")
-                          );
-  cmd_dot =
-    grub_register_command (".", grub_cmd_source,
-                          N_("FILE"),
-                          N_("Load another config file without changing context.")
-                          );
-}
-
-GRUB_MOD_FINI(configfile)
-{
-  grub_unregister_command (cmd_configfile);
-  grub_unregister_command (cmd_source);
-  grub_unregister_command (cmd_dot);
-}
diff --git a/commands/crc.c b/commands/crc.c
deleted file mode 100644 (file)
index 1c1a690..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/* crc.c - command to calculate the crc32 checksum of a file  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/disk.h>
-#include <grub/file.h>
-#include <grub/misc.h>
-#include <grub/lib/crc.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-grub_cmd_crc (grub_command_t cmd __attribute__ ((unused)),
-             int argc, char **args)
-
-{
-  grub_file_t file;
-  char buf[GRUB_DISK_SECTOR_SIZE];
-  grub_ssize_t size;
-  grub_uint32_t crc;
-
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
-  file = grub_file_open (args[0]);
-  if (! file)
-    return 0;
-
-  crc = 0;
-  while ((size = grub_file_read (file, buf, sizeof (buf))) > 0)
-    crc = grub_getcrc32 (crc, buf, size);
-
-  if (grub_errno)
-    goto fail;
-
-  grub_printf ("%08x\n", crc);
-
- fail:
-  grub_file_close (file);
-  return 0;
-}
-
-static grub_command_t cmd;
-
-GRUB_MOD_INIT(crc)
-{
-  cmd = grub_register_command ("crc", grub_cmd_crc,
-                              N_("FILE"),
-                              N_("Calculate the crc32 checksum of a file."));
-}
-
-GRUB_MOD_FINI(crc)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/date.c b/commands/date.c
deleted file mode 100644 (file)
index 623db49..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/* date.c - command to display/set current datetime.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/datetime.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-#define GRUB_DATETIME_SET_YEAR         1
-#define GRUB_DATETIME_SET_MONTH                2
-#define GRUB_DATETIME_SET_DAY          4
-#define GRUB_DATETIME_SET_HOUR         8
-#define GRUB_DATETIME_SET_MINUTE       16
-#define GRUB_DATETIME_SET_SECOND       32
-
-static grub_err_t
-grub_cmd_date (grub_command_t cmd __attribute__ ((unused)),
-               int argc, char **args)
-{
-  struct grub_datetime datetime;
-  int limit[6][2] = {{1980, 2079}, {1, 12}, {1, 31}, {0, 23}, {0, 59}, {0, 59}};
-  int value[6], mask;
-
-  if (argc == 0)
-    {
-      if (grub_get_datetime (&datetime))
-        return grub_errno;
-
-      grub_printf ("%d-%02d-%02d %02d:%02d:%02d %s\n",
-                   datetime.year, datetime.month, datetime.day,
-                   datetime.hour, datetime.minute, datetime.second,
-                   grub_get_weekday_name (&datetime));
-
-      return 0;
-    }
-
-  grub_memset (&value, 0, sizeof (value));
-  mask = 0;
-
-  for (; argc; argc--, args++)
-    {
-      char *p, c;
-      int m1, ofs, n, cur_mask;
-
-      p = args[0];
-      m1 = grub_strtoul (p, &p, 10);
-
-      c = *p;
-      if (c == '-')
-        ofs = 0;
-      else if (c == ':')
-        ofs = 3;
-      else
-        goto fail;
-
-      value[ofs] = m1;
-      cur_mask = (1 << ofs);
-      mask &= ~(cur_mask * (1 + 2 + 4));
-
-      for (n = 1; (n < 3) && (*p); n++)
-        {
-          if (*p != c)
-            goto fail;
-
-          value[ofs + n] = grub_strtoul (p + 1, &p, 10);
-          cur_mask |= (1 << (ofs + n));
-        }
-
-      if (*p)
-        goto fail;
-
-      if ((ofs == 0) && (n == 2))
-        {
-          value[ofs + 2] = value[ofs + 1];
-          value[ofs + 1] = value[ofs];
-          ofs++;
-          cur_mask <<= 1;
-        }
-
-      for (; n; n--, ofs++)
-        if ((value [ofs] < limit[ofs][0]) ||
-            (value [ofs] > limit[ofs][1]))
-          goto fail;
-
-      mask |= cur_mask;
-    }
-
-  if (grub_get_datetime (&datetime))
-    return grub_errno;
-
-  if (mask & GRUB_DATETIME_SET_YEAR)
-    datetime.year = value[0];
-
-  if (mask & GRUB_DATETIME_SET_MONTH)
-    datetime.month = value[1];
-
-  if (mask & GRUB_DATETIME_SET_DAY)
-    datetime.day = value[2];
-
-  if (mask & GRUB_DATETIME_SET_HOUR)
-    datetime.hour = value[3];
-
-  if (mask & GRUB_DATETIME_SET_MINUTE)
-    datetime.minute = value[4];
-
-  if (mask & GRUB_DATETIME_SET_SECOND)
-    datetime.second = value[5];
-
-  return grub_set_datetime (&datetime);
-
-fail:
-  return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid datetime");
-}
-
-static grub_command_t cmd;
-
-GRUB_MOD_INIT(date)
-{
-  cmd =
-    grub_register_command ("date", grub_cmd_date,
-                          N_("[[year-]month-day] [hour:minute[:second]]"),
-                          N_("Command to display/set current datetime."));
-}
-
-GRUB_MOD_FINI(date)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/echo.c b/commands/echo.c
deleted file mode 100644 (file)
index 4fea091..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* echo.c - Command to display a line of text  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/extcmd.h>
-#include <grub/i18n.h>
-
-static const struct grub_arg_option options[] =
-  {
-    {0, 'n', 0, N_("Do not output the trailing newline."), 0, 0},
-    {0, 'e', 0, N_("Enable interpretation of backslash escapes."), 0, 0},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-static grub_err_t
-grub_cmd_echo (grub_extcmd_t cmd, int argc, char **args)
-{
-  struct grub_arg_list *state = cmd->state;
-  int newline = 1;
-  int i;
-
-  /* Check if `-n' was used.  */
-  if (state[0].set)
-    newline = 0;
-
-  for (i = 0; i < argc; i++)
-    {
-      char *arg = *args;
-      args++;
-
-      while (*arg)
-       {
-         /* In case `-e' is used, parse backslashes.  */
-         if (*arg == '\\' && state[1].set)
-           {
-             arg++;
-             if (*arg == '\0')
-               break;
-
-             switch (*arg)
-               {
-               case '\\':
-                 grub_printf ("\\");
-                 break;
-
-               case 'a':
-                 grub_printf ("\a");
-                 break;
-
-               case 'c':
-                 newline = 0;
-                 break;
-
-               case 'f':
-                 grub_printf ("\f");
-                 break;
-
-               case 'n':
-                 grub_printf ("\n");
-                 break;
-
-               case 'r':
-                 grub_printf ("\r");
-                 break;
-
-               case 't':
-                 grub_printf ("\t");
-                 break;
-
-               case 'v':
-                 grub_printf ("\v");
-                 break;
-               }
-             arg++;
-             continue;
-           }
-
-         /* This was not an escaped character, or escaping is not
-            enabled.  */
-         grub_printf ("%c", *arg);
-         arg++;
-       }
-
-      /* If another argument follows, insert a space.  */
-      if (i != argc - 1)
-       grub_printf (" " );
-    }
-
-  if (newline)
-    grub_printf ("\n");
-
-  return 0;
-}
-
-static grub_extcmd_t cmd;
-\f
-GRUB_MOD_INIT(echo)
-{
-  cmd = grub_register_extcmd ("echo", grub_cmd_echo, GRUB_COMMAND_FLAG_BOTH,
-                             N_("[-e|-n] STRING"), N_("Display a line of text."),
-                             options);
-}
-
-GRUB_MOD_FINI(echo)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/commands/efi/acpi.c b/commands/efi/acpi.c
deleted file mode 100644 (file)
index 93a560d..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* acpi.c - get acpi tables. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/acpi.h>
-#include <grub/misc.h>
-#include <grub/efi/efi.h>
-#include <grub/efi/api.h>
-
-struct grub_acpi_rsdp_v10 *
-grub_machine_acpi_get_rsdpv1 (void)
-{
-  unsigned i;
-  static grub_efi_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID;
-
-  for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
-    {
-      grub_efi_guid_t *guid =
-       &grub_efi_system_table->configuration_table[i].vendor_guid;
-
-      if (! grub_memcmp (guid, &acpi_guid, sizeof (grub_efi_guid_t)))
-       return (struct grub_acpi_rsdp_v10 *)
-         grub_efi_system_table->configuration_table[i].vendor_table;
-    }
-  return 0;
-}
-
-struct grub_acpi_rsdp_v20 *
-grub_machine_acpi_get_rsdpv2 (void)
-{
-  unsigned i;
-  static grub_efi_guid_t acpi20_guid = GRUB_EFI_ACPI_20_TABLE_GUID;
-
-  for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
-    {
-      grub_efi_guid_t *guid =
-       &grub_efi_system_table->configuration_table[i].vendor_guid;
-
-      if (! grub_memcmp (guid, &acpi20_guid, sizeof (grub_efi_guid_t)))
-       return (struct grub_acpi_rsdp_v20 *)
-         grub_efi_system_table->configuration_table[i].vendor_table;
-    }
-  return 0;
-}
diff --git a/commands/efi/fixvideo.c b/commands/efi/fixvideo.c
deleted file mode 100644 (file)
index 6430be5..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/* fixvideo.c - fix video problem in efi */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/file.h>
-#include <grub/pci.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static struct grub_video_patch
-{
-  const char *name;
-  grub_uint32_t pci_id;
-  grub_uint32_t mmio_bar;
-  grub_uint32_t mmio_reg;
-  grub_uint32_t mmio_old;
-} video_patches[] =
-  {
-    {"Intel 945GM", 0x27a28086, 0, 0x71184, 0x1000000}, /* DSPBBASE  */
-    {"Intel 965GM", 0x2a028086, 0, 0x7119C, 0x1000000}, /* DSPBSURF  */
-    {0, 0, 0, 0, 0}
-  };
-
-static int NESTED_FUNC_ATTR
-scan_card (grub_pci_device_t dev, grub_pci_id_t pciid)
-{
-  grub_pci_address_t addr;
-
-  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
-  if (grub_pci_read_byte (addr + 3) == 0x3)
-    {
-      struct grub_video_patch *p = video_patches;
-
-      while (p->name)
-       {
-         if (p->pci_id == pciid)
-           {
-             grub_target_addr_t base;
-
-             grub_printf ("Found graphic card: %s\n", p->name);
-             addr += 8 + p->mmio_bar * 4;
-             base = grub_pci_read (addr);
-             if ((! base) || (base & GRUB_PCI_ADDR_SPACE_IO) ||
-                 (base & GRUB_PCI_ADDR_MEM_PREFETCH))
-               grub_printf ("Invalid MMIO bar %d\n", p->mmio_bar);
-             else
-               {
-                 base &= GRUB_PCI_ADDR_MEM_MASK;
-                 base += p->mmio_reg;
-
-                 if (*((volatile grub_uint32_t *) base) != p->mmio_old)
-                   grub_printf ("Old value don't match\n");
-                 else
-                   {
-                     *((volatile grub_uint32_t *) base) = 0;
-                     if (*((volatile grub_uint32_t *) base))
-                       grub_printf ("Set MMIO fails\n");
-                   }
-               }
-
-             return 1;
-           }
-         p++;
-       }
-
-      grub_printf ("Unknown graphic card: %x\n", pciid);
-    }
-
-  return 0;
-}
-
-static grub_err_t
-grub_cmd_fixvideo (grub_command_t cmd __attribute__ ((unused)),
-                  int argc __attribute__ ((unused)),
-                  char *argv[] __attribute__ ((unused)))
-{
-  grub_pci_iterate (scan_card);
-  return 0;
-}
-
-static grub_command_t cmd_fixvideo;
-
-GRUB_MOD_INIT(fixvideo)
-{
-  cmd_fixvideo = grub_register_command ("fix_video", grub_cmd_fixvideo,
-                                       0, N_("Fix video problem."));
-
-}
-
-GRUB_MOD_FINI(fixvideo)
-{
-  grub_unregister_command (cmd_fixvideo);
-}
diff --git a/commands/efi/loadbios.c b/commands/efi/loadbios.c
deleted file mode 100644 (file)
index 8c7c25a..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-/* loadbios.c - command to load a bios dump  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/file.h>
-#include <grub/efi/efi.h>
-#include <grub/pci.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static grub_efi_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID;
-static grub_efi_guid_t acpi2_guid = GRUB_EFI_ACPI_20_TABLE_GUID;
-static grub_efi_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID;
-
-#define EBDA_SEG_ADDR  0x40e
-#define LOW_MEM_ADDR   0x413
-#define FAKE_EBDA_SEG  0x9fc0
-
-#define BLANK_MEM      0xffffffff
-#define VBIOS_ADDR     0xc0000
-#define SBIOS_ADDR     0xf0000
-
-static int
-enable_rom_area (void)
-{
-  grub_pci_address_t addr;
-  grub_uint32_t *rom_ptr;
-  grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0};
-
-  rom_ptr = (grub_uint32_t *) VBIOS_ADDR;
-  if (*rom_ptr != BLANK_MEM)
-    {
-      grub_printf ("ROM image is present.\n");
-      return 0;
-    }
-
-  /* FIXME: should be macroified.  */
-  addr = grub_pci_make_address (dev, 144);
-  grub_pci_write_byte (addr++, 0x30);
-  grub_pci_write_byte (addr++, 0x33);
-  grub_pci_write_byte (addr++, 0x33);
-  grub_pci_write_byte (addr++, 0x33);
-  grub_pci_write_byte (addr++, 0x33);
-  grub_pci_write_byte (addr++, 0x33);
-  grub_pci_write_byte (addr++, 0x33);
-  grub_pci_write_byte (addr, 0);
-
-  *rom_ptr = 0;
-  if (*rom_ptr != 0)
-    {
-      grub_printf ("Can\'t enable ROM area.\n");
-      return 0;
-    }
-
-  return 1;
-}
-
-static void
-lock_rom_area (void)
-{
-  grub_pci_address_t addr;
-  grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0};
-
-  /* FIXME: should be macroified.  */
-  addr = grub_pci_make_address (dev, 144);
-  grub_pci_write_byte (addr++, 0x10);
-  grub_pci_write_byte (addr++, 0x11);
-  grub_pci_write_byte (addr++, 0x11);
-  grub_pci_write_byte (addr++, 0x11);
-  grub_pci_write_byte (addr, 0x11);
-}
-
-static void
-fake_bios_data (int use_rom)
-{
-  unsigned i;
-  void *acpi, *smbios;
-  grub_uint16_t *ebda_seg_ptr, *low_mem_ptr;
-
-  ebda_seg_ptr = (grub_uint16_t *) EBDA_SEG_ADDR;
-  low_mem_ptr = (grub_uint16_t *) LOW_MEM_ADDR;
-  if ((*ebda_seg_ptr) || (*low_mem_ptr))
-    return;
-
-  acpi = 0;
-  smbios = 0;
-  for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
-    {
-      grub_efi_guid_t *guid =
-       &grub_efi_system_table->configuration_table[i].vendor_guid;
-
-      if (! grub_memcmp (guid, &acpi2_guid, sizeof (grub_efi_guid_t)))
-       {
-         acpi = grub_efi_system_table->configuration_table[i].vendor_table;
-         grub_dprintf ("efi", "ACPI2: %p\n", acpi);
-       }
-      else if (! grub_memcmp (guid, &acpi_guid, sizeof (grub_efi_guid_t)))
-       {
-         void *t;
-
-         t = grub_efi_system_table->configuration_table[i].vendor_table;
-         if (! acpi)
-           acpi = t;
-         grub_dprintf ("efi", "ACPI: %p\n", t);
-       }
-      else if (! grub_memcmp (guid, &smbios_guid, sizeof (grub_efi_guid_t)))
-       {
-         smbios = grub_efi_system_table->configuration_table[i].vendor_table;
-         grub_dprintf ("efi", "SMBIOS: %p\n", smbios);
-       }
-    }
-
-  *ebda_seg_ptr = FAKE_EBDA_SEG;
-  *low_mem_ptr = (FAKE_EBDA_SEG >> 6);
-
-  *((grub_uint16_t *) (FAKE_EBDA_SEG << 4)) = 640 - *low_mem_ptr;
-
-  if (acpi)
-    grub_memcpy ((char *) ((FAKE_EBDA_SEG << 4) + 16), acpi, 1024 - 16);
-
-  if ((use_rom) && (smbios))
-    grub_memcpy ((char *) SBIOS_ADDR, (char *) smbios + 16, 16);
-}
-
-static grub_err_t
-grub_cmd_fakebios (struct grub_command *cmd __attribute__ ((unused)),
-                  int argc __attribute__ ((unused)),
-                  char *argv[] __attribute__ ((unused)))
-{
-  if (enable_rom_area ())
-    {
-      fake_bios_data (1);
-      lock_rom_area ();
-    }
-  else
-    fake_bios_data (0);
-
-  return 0;
-}
-
-static grub_err_t
-grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)),
-                  int argc, char *argv[])
-{
-  grub_file_t file;
-  int size;
-
-  if (argc == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no ROM image specified");
-
-  if (argc > 1)
-    {
-      file = grub_file_open (argv[1]);
-      if (! file)
-       return grub_errno;
-
-      if (file->size != 4)
-       grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid int10 dump size");
-      else
-       grub_file_read (file, (void *) 0x40, 4);
-
-      grub_file_close (file);
-      if (grub_errno)
-       return grub_errno;
-    }
-
-  file = grub_file_open (argv[0]);
-  if (! file)
-    return grub_errno;
-
-  size = file->size;
-  if ((size < 0x10000) || (size > 0x40000))
-    grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid bios dump size");
-  else if (enable_rom_area ())
-    {
-      grub_file_read (file, (void *) VBIOS_ADDR, size);
-      fake_bios_data (size <= 0x40000);
-      lock_rom_area ();
-    }
-
-  grub_file_close (file);
-  return grub_errno;
-}
-
-static grub_command_t cmd_fakebios, cmd_loadbios;
-
-GRUB_MOD_INIT(loadbios)
-{
-  cmd_fakebios = grub_register_command ("fakebios", grub_cmd_fakebios,
-                                       0, N_("Fake BIOS."));
-
-  cmd_loadbios = grub_register_command ("loadbios", grub_cmd_loadbios,
-                                       "BIOS_DUMP [INT10_DUMP]",
-                                       N_("Load BIOS dump."));
-}
-
-GRUB_MOD_FINI(loadbios)
-{
-  grub_unregister_command (cmd_fakebios);
-  grub_unregister_command (cmd_loadbios);
-}
diff --git a/commands/extcmd.c b/commands/extcmd.c
deleted file mode 100644 (file)
index 16796fe..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* extcmd.c - support extended command */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/list.h>
-#include <grub/misc.h>
-#include <grub/extcmd.h>
-
-static grub_err_t
-grub_extcmd_dispatcher (struct grub_command *cmd,
-                       int argc, char **args)
-{
-  int new_argc;
-  char **new_args;
-  struct grub_arg_option *parser;
-  struct grub_arg_list *state;
-  int maxargs = 0;
-  grub_err_t ret;
-  grub_extcmd_t ext;
-
-  ext = cmd->data;
-  parser = (struct grub_arg_option *) ext->options;
-  while (parser && (parser++)->doc)
-    maxargs++;
-
-  /* Set up the option state.  */
-  state = grub_zalloc (sizeof (struct grub_arg_list) * maxargs);
-
-  if (grub_arg_parse (ext, argc, args, state, &new_args, &new_argc))
-    {
-      ext->state = state;
-      ret = (ext->func) (ext, new_argc, new_args);
-      grub_free (new_args);
-    }
-  else
-    ret = grub_errno;
-
-  grub_free (state);
-
-  return ret;
-}
-
-grub_extcmd_t
-grub_register_extcmd (const char *name, grub_extcmd_func_t func,
-                     unsigned flags, const char *summary,
-                     const char *description,
-                     const struct grub_arg_option *parser)
-{
-  grub_extcmd_t ext;
-  grub_command_t cmd;
-
-  ext = (grub_extcmd_t) grub_malloc (sizeof (*ext));
-  if (! ext)
-    return 0;
-
-  cmd = grub_register_command_prio (name, grub_extcmd_dispatcher,
-                                   summary, description, 1);
-  if (! cmd)
-    {
-      grub_free (ext);
-      return 0;
-    }
-
-  cmd->flags = (flags | GRUB_COMMAND_FLAG_EXTCMD);
-  cmd->data = ext;
-
-  ext->cmd = cmd;
-  ext->func = func;
-  ext->options = parser;
-  ext->data = 0;
-
-  return ext;
-}
-
-void
-grub_unregister_extcmd (grub_extcmd_t ext)
-{
-  grub_unregister_command (ext->cmd);
-  grub_free (ext);
-}
diff --git a/commands/gptsync.c b/commands/gptsync.c
deleted file mode 100644 (file)
index d217b5d..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/* gptsync.c - fill the mbr based on gpt entries  */
-/* XXX: I don't know what to do if sector size isn't 512 bytes */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/command.h>
-#include <grub/dl.h>
-#include <grub/device.h>
-#include <grub/disk.h>
-#include <grub/msdos_partition.h>
-#include <grub/partition.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/fs.h>
-#include <grub/i18n.h>
-
-/* Convert a LBA address to a CHS address in the INT 13 format.  */
-/* Taken from grub1. */
-/* XXX: use hardcoded geometry of C = 1024, H = 255, S = 63.
-   Is it a problem?
-*/
-static void
-lba_to_chs (int lba, grub_uint8_t *cl, grub_uint8_t *ch,
-           grub_uint8_t *dh)
-{
-  int cylinder, head, sector;
-  int sectors = 63, heads = 255, cylinders = 1024;
-
-  sector = lba % sectors + 1;
-  head = (lba / sectors) % heads;
-  cylinder = lba / (sectors * heads);
-
-  if (cylinder >= cylinders)
-    {
-      *cl = *ch = *dh = 0xff;
-      return;
-    }
-
-  *cl = sector | ((cylinder & 0x300) >> 2);
-  *ch = cylinder & 0xFF;
-  *dh = head;
-}
-
-static grub_err_t
-grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)),
-                 int argc, char **args)
-{
-  grub_device_t dev;
-  struct grub_msdos_partition_mbr mbr;
-  struct grub_partition *partition;
-  grub_disk_addr_t first_sector;
-  int numactive = 0;
-
-  if (argc < 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
-  if (argc > 4)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "only 3 partitions can be "
-                      "in hybrid MBR");
-
-  if (args[0][0] == '(' && args[0][grub_strlen (args[0]) - 1] == ')')
-    {
-      args[0][grub_strlen (args[0]) - 1] = 0;
-      dev = grub_device_open (args[0] + 1);
-      args[0][grub_strlen (args[0])] = ')';
-    }
-  else
-    dev = grub_device_open (args[0]);
-
-  if (! dev)
-    return grub_errno;
-
-  if (! dev->disk)
-    {
-      grub_device_close (dev);
-      return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a disk");
-    }
-
-  /* Read the protective MBR.  */
-  if (grub_disk_read (dev->disk, 0, 0, sizeof (mbr), &mbr))
-    {
-      grub_device_close (dev);
-      return grub_errno;
-    }
-
-  /* Check if it is valid.  */
-  if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE))
-    {
-      grub_device_close (dev);
-      return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
-    }
-
-  /* Make sure the MBR is a protective MBR and not a normal MBR.  */
-  if (mbr.entries[0].type != GRUB_PC_PARTITION_TYPE_GPT_DISK)
-    {
-      grub_device_close (dev);
-      return grub_error (GRUB_ERR_BAD_PART_TABLE, "no GPT partition map found");
-    }
-
-  int i;
-  first_sector = dev->disk->total_sectors;
-  for (i = 1; i < argc; i++)
-    {
-      char *separator, csep = 0;
-      grub_uint8_t type;
-      separator = grub_strchr (args[i], '+');
-      if (! separator)
-       separator = grub_strchr (args[i], '-');
-      if (separator)
-       {
-         csep = *separator;
-         *separator = 0;
-       }
-      partition = grub_partition_probe (dev->disk, args[i]);
-      if (separator)
-       *separator = csep;
-      if (! partition)
-       {
-         grub_device_close (dev);
-         return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such partition");
-       }
-
-      if (partition->start + partition->len > 0xffffffff)
-       {
-         grub_device_close (dev);
-         return grub_error (GRUB_ERR_OUT_OF_RANGE,
-                            "only partitions resding in the first 2TB "
-                            "can be presen in hybrid MBR");
-       }
-
-
-      if (first_sector > partition->start)
-       first_sector = partition->start;
-
-      if (separator && *(separator + 1))
-       type = grub_strtoul (separator + 1, 0, 0);
-      else
-       {
-         grub_fs_t fs = 0;
-         dev->disk->partition = partition;
-         fs = grub_fs_probe (dev);
-
-         /* Unknown filesystem isn't fatal. */
-         if (grub_errno == GRUB_ERR_UNKNOWN_FS)
-           {
-             fs = 0;
-             grub_errno = GRUB_ERR_NONE;
-           }
-
-         if (fs && grub_strcmp (fs->name, "ntfs") == 0)
-           type = GRUB_PC_PARTITION_TYPE_NTFS;
-         else if (fs && grub_strcmp (fs->name, "fat") == 0)
-           /* FIXME: detect FAT16. */
-           type = GRUB_PC_PARTITION_TYPE_FAT32_LBA;
-         else if (fs && (grub_strcmp (fs->name, "hfsplus") == 0
-                         || grub_strcmp (fs->name, "hfs") == 0))
-           type = GRUB_PC_PARTITION_TYPE_HFS;
-         else
-           /* FIXME: detect more types. */
-           type = GRUB_PC_PARTITION_TYPE_EXT2FS;
-
-         dev->disk->partition = 0;
-       }
-
-      mbr.entries[i].flag = (csep == '+') ? 0x80 : 0;
-      if (csep == '+')
-       {
-         numactive++;
-         if (numactive == 2)
-           {
-             grub_device_close (dev);
-             return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                                "only one partition can be active");
-           }
-       }
-      mbr.entries[i].type = type;
-      mbr.entries[i].start = grub_cpu_to_le32 (partition->start);
-      lba_to_chs (partition->start,
-                 &(mbr.entries[i].start_sector),
-                 &(mbr.entries[i].start_cylinder),
-                 &(mbr.entries[i].start_head));
-      lba_to_chs (partition->start + partition->len - 1,
-                 &(mbr.entries[i].end_sector),
-                 &(mbr.entries[i].end_cylinder),
-                 &(mbr.entries[i].end_head));
-      mbr.entries[i].length = grub_cpu_to_le32 (partition->len);
-      grub_free (partition);
-    }
-  for (; i < 4; i++)
-    grub_memset (&(mbr.entries[i]), 0, sizeof (mbr.entries[i]));
-
-  /* The protective partition. */
-  if (first_sector > 0xffffffff)
-    first_sector = 0xffffffff;
-  else
-    first_sector--;
-  mbr.entries[0].flag = 0;
-  mbr.entries[0].type = GRUB_PC_PARTITION_TYPE_GPT_DISK;
-  mbr.entries[0].start = grub_cpu_to_le32 (1);
-  lba_to_chs (1,
-             &(mbr.entries[0].start_sector),
-             &(mbr.entries[0].start_cylinder),
-             &(mbr.entries[0].start_head));
-  lba_to_chs (first_sector,
-             &(mbr.entries[0].end_sector),
-             &(mbr.entries[0].end_cylinder),
-             &(mbr.entries[0].end_head));
-  mbr.entries[0].length = grub_cpu_to_le32 (first_sector);
-
-  mbr.signature = grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE);
-
-  if (grub_disk_write (dev->disk, 0, 0, sizeof (mbr), &mbr))
-    {
-      grub_device_close (dev);
-      return grub_errno;
-    }
-
-  grub_printf ("New MBR is written to '%s'\n", args[0]);
-
-  return GRUB_ERR_NONE;
-}
-
-
-static grub_command_t cmd;
-\f
-GRUB_MOD_INIT(gptsync)
-{
-  (void) mod;                  /* To stop warning. */
-  cmd = grub_register_command ("gptsync", grub_cmd_gptsync,
-                              N_("DEVICE [PARTITION[+/-[TYPE]]] ..."),
-                              N_("Fill hybrid MBR of GPT drive DEVICE. "
-                              "specified partitions will be a part "
-                              "of hybrid mbr. Up to 3 partitions are "
-                              "allowed. TYPE is an MBR type. "
-                              "+ means that partition is active. "
-                              "Only one partition can be active."));
-}
-
-GRUB_MOD_FINI(gptsync)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/halt.c b/commands/halt.c
deleted file mode 100644 (file)
index 3400115..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/* halt.c - command to halt the computer.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/command.h>
-#include <grub/misc.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-grub_cmd_halt (grub_command_t cmd __attribute__ ((unused)),
-              int argc __attribute__ ((unused)),
-              char **args __attribute__ ((unused)))
-{
-  grub_halt ();
-  return 0;
-}
-
-static grub_command_t cmd;
-\f
-GRUB_MOD_INIT(halt)
-{
-  cmd = grub_register_command ("halt", grub_cmd_halt,
-                              0, N_("Halts the computer.  This command does" 
-                              " not work on all firmware implementations."));
-}
-
-GRUB_MOD_FINI(halt)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/handler.c b/commands/handler.c
deleted file mode 100644 (file)
index f927097..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/* handler.c - commands to list or select handlers */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/term.h>
-#include <grub/handler.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)),
-                 int argc, char **args)
-{
-  void *curr_item = 0;
-  grub_handler_class_t head;
-
-  auto int list_item (grub_named_list_t item);
-  int list_item (grub_named_list_t item)
-    {
-      if (item == curr_item)
-       grub_putchar ('*');
-
-      grub_printf ("%s\n", item->name);
-
-      return 0;
-    }
-
-  head = grub_handler_class_list;
-  if (argc == 0)
-    {
-      grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_item);
-    }
-  else
-    {
-      char *class_name;
-      grub_handler_class_t class;
-
-      class_name = args[0];
-      argc--;
-      args++;
-
-      class = grub_named_list_find (GRUB_AS_NAMED_LIST (head), class_name);
-      if (! class)
-       return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found");
-
-      if (argc == 0)
-       {
-         curr_item = class->cur_handler;
-         grub_list_iterate (GRUB_AS_LIST (class->handler_list),
-                            (grub_list_hook_t) list_item);
-       }
-      else
-       {
-         grub_handler_t handler;
-
-         handler =
-           grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list),
-                                 args[0]);
-
-         if (! handler)
-           return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found");
-
-         grub_handler_set_current (class, handler);
-       }
-    }
-
-  return 0;
-}
-
-static grub_command_t cmd_handler;
-
-GRUB_MOD_INIT(handler)
-{
-  cmd_handler =
-    grub_register_command ("handler", grub_cmd_handler,
-                          N_("[class [handler]]"),
-                          N_("List or select a handler."));
-}
-
-GRUB_MOD_FINI(handler)
-{
-  grub_unregister_command (cmd_handler);
-}
diff --git a/commands/hashsum.c b/commands/hashsum.c
deleted file mode 100644 (file)
index d5f551d..0000000
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/extcmd.h>
-#include <grub/file.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/crypto.h>
-#include <grub/normal.h>
-#include <grub/i18n.h>
-
-static const struct grub_arg_option options[] = {
-  {"hash", 'h', 0, N_("Specify hash to use."), N_("HASH"), ARG_TYPE_STRING},
-  {"check", 'c', 0, N_("Check hash list file."), N_("FILE"), ARG_TYPE_STRING},
-  {"prefix", 'p', 0, N_("Base directory for hash list."), N_("DIRECTORY"),
-   ARG_TYPE_STRING},
-  {"keep-going", 'k', 0, N_("Don't stop after first error."), 0, 0},
-  {0, 0, 0, 0, 0, 0}
-};
-
-struct { const char *name; const char *hashname; } aliases[] = 
-  {
-    {"sha256sum", "sha256"},
-    {"sha512sum", "sha512"},
-    {"md5sum", "md5"},
-  };
-
-static inline int
-hextoval (char c)
-{
-  if (c >= '0' && c <= '9')
-    return c - '0';
-  if (c >= 'a' && c <= 'f')
-    return c - 'a' + 10;
-  if (c >= 'A' && c <= 'F')
-    return c - 'A' + 10;
-  return -1;
-}
-
-static grub_err_t
-hash_file (grub_file_t file, const gcry_md_spec_t *hash, void *result)
-{
-  grub_uint8_t context[hash->contextsize];
-  grub_uint8_t readbuf[4096];
-
-  grub_memset (context, 0, sizeof (context));
-  hash->init (context);
-  while (1)
-    {
-      grub_ssize_t r;
-      r = grub_file_read (file, readbuf, sizeof (readbuf));
-      if (r < 0)
-       return grub_errno;
-      if (r == 0)
-       break;
-      hash->write (context, readbuf, r);
-    }
-  hash->final (context);
-  grub_memcpy (result, hash->read (context), hash->mdlen);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-check_list (const gcry_md_spec_t *hash, const char *hashfilename,
-           const char *prefix, int keep)
-{
-  grub_file_t hashlist, file;
-  char *buf = NULL;
-  grub_uint8_t expected[hash->mdlen];
-  grub_uint8_t actual[hash->mdlen];
-  grub_err_t err;
-  unsigned i;
-  unsigned unread = 0, mismatch = 0;
-
-  hashlist = grub_file_open (hashfilename);
-  if (!hashlist)
-    return grub_errno;
-  
-  while (grub_free (buf), (buf = grub_file_getline (hashlist)))
-    {
-      const char *p = buf;
-      for (i = 0; i < hash->mdlen; i++)
-       {
-         int high, low;
-         high = hextoval (*p++);
-         low = hextoval (*p++);
-         if (high < 0 || low < 0)
-           return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list");
-         expected[i] = (high << 4) | low;
-       }
-      if (*p++ != ' ' || *p++ != ' ')
-       return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list");
-      if (prefix)
-       {
-         char *filename;
-         
-         filename = grub_xasprintf ("%s/%s", prefix, p);
-         if (!filename)
-           return grub_errno;
-         file = grub_file_open (filename);
-         grub_free (filename);
-       }
-      else
-       file = grub_file_open (p);
-      if (!file)
-       {
-         grub_file_close (hashlist);
-         grub_free (buf);
-         return grub_errno;
-       }
-      err = hash_file (file, hash, actual);
-      grub_file_close (file);
-      if (err)
-       {
-         grub_printf ("%s: READ ERROR\n", p);
-         if (!keep)
-           {
-             grub_file_close (hashlist);
-             grub_free (buf);
-             return err;
-           }
-         grub_print_error ();
-         grub_errno = GRUB_ERR_NONE;
-         unread++;
-         continue;
-       }
-      if (grub_crypto_memcmp (expected, actual, hash->mdlen) != 0)
-       {
-         grub_printf ("%s: HASH MISMATCH\n", p);
-         if (!keep)
-           {
-             grub_file_close (hashlist);
-             grub_free (buf);
-             return grub_error (GRUB_ERR_TEST_FAILURE,
-                                "hash of '%s' mismatches", p);
-           }
-         mismatch++;
-         continue;       
-       }
-      grub_printf ("%s: OK\n", p);
-    }
-  if (mismatch || unread)
-    return grub_error (GRUB_ERR_TEST_FAILURE,
-                      "%d files couldn't be read and hash "
-                      "of %d files mismatches", unread, mismatch);
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_cmd_hashsum (struct grub_extcmd *cmd,
-                 int argc, char **args)
-{
-  struct grub_arg_list *state = cmd->state;
-  const char *hashname = NULL;
-  const char *prefix = NULL;
-  const gcry_md_spec_t *hash;
-  unsigned i;
-  int keep = state[3].set;
-  unsigned unread = 0;
-
-  for (i = 0; i < ARRAY_SIZE (aliases); i++)
-    if (grub_strcmp (cmd->cmd->name, aliases[i].name) == 0)
-      hashname = aliases[i].hashname;
-  if (state[0].set)
-    hashname = state[0].arg;
-
-  if (!hashname)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no hash specified");
-
-  hash = grub_crypto_lookup_md_by_name (hashname);
-  if (!hash)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown hash");
-
-  if (state[2].set)
-    prefix = state[2].arg;
-
-  if (state[1].set)
-    {
-      if (argc != 0)
-       return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                          "--check is incompatible with file list");
-      return check_list (hash, state[1].arg, prefix, keep);
-    }
-
-  for (i = 0; i < (unsigned) argc; i++)
-    {
-      grub_uint8_t result[hash->mdlen];
-      grub_file_t file;
-      grub_err_t err;
-      unsigned j;
-      file = grub_file_open (args[i]);
-      if (!file)
-       {
-         if (!keep)
-           return grub_errno;
-         grub_print_error ();
-         grub_errno = GRUB_ERR_NONE;
-         unread++;
-         continue;
-       }
-      err = hash_file (file, hash, result);
-      grub_file_close (file);
-      if (err)
-       {
-         if (!keep)
-           return err;
-         grub_print_error ();
-         grub_errno = GRUB_ERR_NONE;
-         unread++;
-         continue;
-       }
-      for (j = 0; j < hash->mdlen; j++)
-       grub_printf ("%02x", result[j]);
-      grub_printf ("  %s\n", args[i]);
-    }
-
-  if (unread)
-    return grub_error (GRUB_ERR_TEST_FAILURE, "%d files couldn't be read.",
-                      unread);
-  return GRUB_ERR_NONE;
-}
-
-static grub_extcmd_t cmd, cmd_md5, cmd_sha256, cmd_sha512;
-
-GRUB_MOD_INIT(hashsum)
-{
-  cmd = grub_register_extcmd ("hashsum", grub_cmd_hashsum,
-                             GRUB_COMMAND_FLAG_BOTH,
-                             "hashsum -h HASH [-c FILE [-p PREFIX]] "
-                             "[FILE1 [FILE2 ...]]",
-                             "Compute or check hash checksum.",
-                             options);
-  cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum,
-                                 GRUB_COMMAND_FLAG_BOTH,
-                                 N_("[-c FILE [-p PREFIX]] "
-                                    "[FILE1 [FILE2 ...]]"),
-                                 N_("Compute or check hash checksum."),
-                                 options);
-  cmd_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum,
-                                    GRUB_COMMAND_FLAG_BOTH,
-                                    N_("[-c FILE [-p PREFIX]] "
-                                       "[FILE1 [FILE2 ...]]"),
-                                    "Compute or check hash checksum.",
-                                    options);
-  cmd_sha512 = grub_register_extcmd ("sha512sum", grub_cmd_hashsum,
-                                    GRUB_COMMAND_FLAG_BOTH,
-                                    N_("[-c FILE [-p PREFIX]] "
-                                       "[FILE1 [FILE2 ...]]"),
-                                    N_("Compute or check hash checksum."),
-                                    options);
-}
-
-GRUB_MOD_FINI(hashsum)
-{
-  grub_unregister_extcmd (cmd);
-  grub_unregister_extcmd (cmd_md5);
-  grub_unregister_extcmd (cmd_sha256);
-  grub_unregister_extcmd (cmd_sha512);
-}
diff --git a/commands/hdparm.c b/commands/hdparm.c
deleted file mode 100644 (file)
index a3f8bbf..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
-/* hdparm.c - command to get/set ATA disk parameters.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/ata.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/lib/hexdump.h>
-#include <grub/extcmd.h>
-#include <grub/i18n.h>
-
-static const struct grub_arg_option options[] = {
-  {"apm",             'B', 0, N_("Set Advanced Power Management\n"
-                             "(1=low, ..., 254=high, 255=off)."),
-                             0, ARG_TYPE_INT},
-  {"power",           'C', 0, N_("Check power mode."), 0, ARG_TYPE_NONE},
-  {"security-freeze", 'F', 0, N_("Freeze ATA security settings until reset."),
-                             0, ARG_TYPE_NONE},
-  {"health",          'H', 0, N_("Check SMART health status."), 0, ARG_TYPE_NONE},
-  {"aam",             'M', 0, N_("Set Automatic Acoustic Management\n"
-                             "(0=off, 128=quiet, ..., 254=fast)."),
-                             0, ARG_TYPE_INT},
-  {"standby-timeout", 'S', 0, N_("Set standby timeout\n"
-                             "(0=off, 1=5s, 2=10s, ..., 240=20m, 241=30m, ...)."),
-                             0, ARG_TYPE_INT},
-  {"standby",         'y', 0, N_("Set drive to standby mode."), 0, ARG_TYPE_NONE},
-  {"sleep",           'Y', 0, N_("Set drive to sleep mode."), 0, ARG_TYPE_NONE},
-  {"identify",        'i', 0, N_("Print drive identity and settings."),
-                             0, ARG_TYPE_NONE},
-  {"dumpid",          'I', 0, N_("Dump contents of ATA IDENTIFY sector."),
-                              0, ARG_TYPE_NONE},
-  {"smart",            -1, 0, N_("Disable/enable SMART (0/1)."), 0, ARG_TYPE_INT},
-  {"quiet",           'q', 0, N_("Do not print messages."), 0, ARG_TYPE_NONE},
-  {0, 0, 0, 0, 0, 0}
-};
-
-enum grub_ata_smart_commands
-  {
-    GRUB_ATA_FEAT_SMART_ENABLE  = 0xd8,
-    GRUB_ATA_FEAT_SMART_DISABLE = 0xd9,
-    GRUB_ATA_FEAT_SMART_STATUS  = 0xda,
-  };
-
-static int quiet = 0;
-
-static grub_err_t
-grub_hdparm_do_ata_cmd (grub_disk_t disk, grub_uint8_t cmd,
-                       grub_uint8_t features, grub_uint8_t sectors,
-                       void * buffer, int size)
-{
-  struct grub_disk_ata_pass_through_parms apt;
-  grub_memset (&apt, 0, sizeof (apt));
-
-  apt.taskfile[GRUB_ATA_REG_CMD] = cmd;
-  apt.taskfile[GRUB_ATA_REG_FEATURES] = features;
-  apt.taskfile[GRUB_ATA_REG_SECTORS] = sectors;
-  apt.buffer = buffer;
-  apt.size = size;
-
-  if (grub_disk_ata_pass_through (disk, &apt))
-    return grub_errno;
-
-  return GRUB_ERR_NONE;
-}
-
-static int
-grub_hdparm_do_check_powermode_cmd (grub_disk_t disk)
-{
-  struct grub_disk_ata_pass_through_parms apt;
-  grub_memset (&apt, 0, sizeof (apt));
-
-  apt.taskfile[GRUB_ATA_REG_CMD] = GRUB_ATA_CMD_CHECK_POWER_MODE;
-
-  if (grub_disk_ata_pass_through (disk, &apt))
-    return -1;
-
-  return apt.taskfile[GRUB_ATA_REG_SECTORS];
-}
-
-static int
-grub_hdparm_do_smart_cmd (grub_disk_t disk, grub_uint8_t features)
-{
-  struct grub_disk_ata_pass_through_parms apt;
-  grub_memset (&apt, 0, sizeof (apt));
-
-  apt.taskfile[GRUB_ATA_REG_CMD] = GRUB_ATA_CMD_SMART;
-  apt.taskfile[GRUB_ATA_REG_FEATURES] = features;
-  apt.taskfile[GRUB_ATA_REG_LBAMID]  = 0x4f;
-  apt.taskfile[GRUB_ATA_REG_LBAHIGH] = 0xc2;
-
-  if (grub_disk_ata_pass_through (disk, &apt))
-    return -1;
-
-  if (features == GRUB_ATA_FEAT_SMART_STATUS)
-    {
-      if (   apt.taskfile[GRUB_ATA_REG_LBAMID]  == 0x4f
-          && apt.taskfile[GRUB_ATA_REG_LBAHIGH] == 0xc2)
-       return 0; /* Good SMART status.  */
-      else if (   apt.taskfile[GRUB_ATA_REG_LBAMID]  == 0xf4
-              && apt.taskfile[GRUB_ATA_REG_LBAHIGH] == 0x2c)
-       return 1; /* Bad SMART status.  */
-      else
-       return -1;
-    }
-  return 0;
-}
-
-static grub_err_t
-grub_hdparm_simple_cmd (const char * msg,
-                       grub_disk_t disk, grub_uint8_t cmd)
-{
-  if (! quiet && msg)
-    grub_printf ("%s", msg);
-
-  grub_err_t err = grub_hdparm_do_ata_cmd (disk, cmd, 0, 0, NULL, 0);
-
-  if (! quiet && msg)
-    grub_printf ("%s\n", ! err ? "" : ": not supported");
-  return err;
-}
-
-static grub_err_t
-grub_hdparm_set_val_cmd (const char * msg, int val,
-                        grub_disk_t disk, grub_uint8_t cmd,
-                        grub_uint8_t features, grub_uint8_t sectors)
-{
-  if (! quiet && msg && *msg)
-    {
-      if (val >= 0)
-       grub_printf ("Set %s to %d", msg, val);
-      else
-       grub_printf ("Disable %s", msg);
-    }
-
-  grub_err_t err = grub_hdparm_do_ata_cmd (disk, cmd, features, sectors,
-                                          NULL, 0);
-
-  if (! quiet && msg)
-    grub_printf ("%s\n", ! err ? "" : ": not supported");
-  return err;
-}
-
-static const char *
-le16_to_char (char *dest, const grub_uint16_t * src16, unsigned bytes)
-{
-  grub_uint16_t * dest16 = (grub_uint16_t *) dest;
-  unsigned i;
-  for (i = 0; i < bytes / 2; i++)
-    dest16[i] = grub_be_to_cpu16 (src16[i]);
-  return dest;
-}
-
-static void
-grub_hdparm_print_identify (const char * idbuf)
-{
-  const grub_uint16_t * idw = (const grub_uint16_t *) idbuf;
-
-  /* Print identity strings.  */
-  char tmp[40];
-  grub_printf ("Model:    \"%.40s\"\n", le16_to_char (tmp, &idw[27], 40));
-  grub_printf ("Firmware: \"%.8s\"\n",  le16_to_char (tmp, &idw[23], 8));
-  grub_printf ("Serial:   \"%.20s\"\n", le16_to_char (tmp, &idw[10], 20));
-
-  /* Print AAM, APM and SMART settings.  */
-  grub_uint16_t features1 = grub_le_to_cpu16 (idw[82]);
-  grub_uint16_t features2 = grub_le_to_cpu16 (idw[83]);
-  grub_uint16_t enabled1  = grub_le_to_cpu16 (idw[85]);
-  grub_uint16_t enabled2  = grub_le_to_cpu16 (idw[86]);
-
-  grub_printf ("Automatic Acoustic Management: ");
-  if (features2 & 0x0200)
-    {
-      if (enabled2 & 0x0200)
-       {
-         grub_uint16_t aam = grub_le_to_cpu16 (idw[94]);
-         grub_printf ("%u (128=quiet, ..., 254=fast, recommended=%u)\n",
-                      aam & 0xff, (aam >> 8) & 0xff);
-       }
-      else
-       grub_printf ("disabled\n");
-    }
-  else
-    grub_printf ("not supported\n");
-
-  grub_printf ("Advanced Power Management: ");
-  if (features2 & 0x0008)
-    {
-      if (enabled2 & 0x0008)
-       grub_printf ("%u (1=low, ..., 254=high)\n",
-                    grub_le_to_cpu16 (idw[91]) & 0xff);
-      else
-       grub_printf ("disabled\n");
-    }
-  else
-    grub_printf ("not supported\n");
-
-  grub_printf ("SMART Feature Set: ");
-  if (features1 & 0x0001)
-    grub_printf ("%sabled\n", (enabled1 & 0x0001 ? "en" : "dis"));
-  else
-    grub_printf ("not supported\n");
-
-  /* Print security settings.  */
-  grub_uint16_t security = grub_le_to_cpu16 (idw[128]);
-
-  grub_printf ("ATA Security: ");
-  if (security & 0x0001)
-    grub_printf ("%s, %s, %s, %s\n",
-                (security & 0x0002 ? "ENABLED" : "disabled"),
-                (security & 0x0004 ? "**LOCKED**"  : "not locked"),
-                (security & 0x0008 ? "frozen" : "NOT FROZEN"),
-                (security & 0x0010 ? "COUNT EXPIRED" : "count not expired"));
-  else
-    grub_printf ("not supported\n");
-}
-
-static void
-grub_hdparm_print_standby_tout (int timeout)
-{
-  if (timeout == 0)
-    grub_printf ("off");
-  else if (timeout <= 252 || timeout == 255)
-    {
-      int h = 0, m = 0 , s = 0;
-      if (timeout == 255)
-       {
-         m = 21;
-         s = 15;
-       }
-      else if (timeout == 252)
-       m = 21;
-      else if (timeout <= 240)
-       {
-         s = timeout * 5;
-         m = s / 60;
-         s %= 60;
-       }
-      else
-       {
-         m = (timeout - 240) * 30;
-         h  = m / 60;
-         m %= 60;
-       }
-      grub_printf ("%02d:%02d:%02d", h, m, s);
-    }
-  else
-    grub_printf ("invalid or vendor-specific");
-}
-
-static int get_int_arg (const struct grub_arg_list *state)
-{
-  return (state->set ? (int)grub_strtoul (state->arg, 0, 0) : -1);
-}
-
-static grub_err_t
-grub_cmd_hdparm (grub_extcmd_t cmd, int argc, char **args) // state????
-{
-  struct grub_arg_list *state = cmd->state;
-
-  /* Check command line.  */
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing device name argument");
-
-  grub_size_t len = grub_strlen (args[0]);
-  if (! (args[0][0] == '(' && args[0][len - 1] == ')'))
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "argument is not a device name");
-  args[0][len - 1] = 0;
-
-  if (! grub_disk_ata_pass_through)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "ATA pass through not available");
-
-  int i = 0;
-  int apm          = get_int_arg (&state[i++]);
-  int power        = state[i++].set;
-  int sec_freeze   = state[i++].set;
-  int health       = state[i++].set;
-  int aam          = get_int_arg (&state[i++]);
-  int standby_tout = get_int_arg (&state[i++]);
-  int standby_now  = state[i++].set;
-  int sleep_now    = state[i++].set;
-  int ident        = state[i++].set;
-  int dumpid       = state[i++].set;
-  int enable_smart = get_int_arg (&state[i++]);
-  quiet            = state[i++].set;
-
-  /* Open disk.  */
-  grub_disk_t disk = grub_disk_open (&args[0][1]);
-  if (! disk)
-    return grub_errno;
-
-  if (disk->partition)
-    {
-      grub_disk_close (disk);
-      return grub_error (GRUB_ERR_BAD_ARGUMENT, "partition not allowed");
-    }
-
-  /* Change settings.  */
-  if (aam >= 0)
-    grub_hdparm_set_val_cmd ("Automatic Acoustic Management", (aam ? aam : -1),
-      disk, GRUB_ATA_CMD_SET_FEATURES, (aam ? 0x42 : 0xc2), aam);
-
-  if (apm >= 0)
-    grub_hdparm_set_val_cmd ("Advanced Power Management",
-      (apm != 255 ? apm : -1), disk, GRUB_ATA_CMD_SET_FEATURES,
-      (apm != 255 ? 0x05 : 0x85), (apm != 255 ? apm : 0));
-
-  if (standby_tout >= 0)
-    {
-      if (! quiet)
-       {
-         grub_printf ("Set standby timeout to %d (", standby_tout);
-         grub_hdparm_print_standby_tout (standby_tout);
-         grub_printf (")");
-       }
-      /* The IDLE cmd sets disk to idle mode and configures standby timer.  */
-      grub_hdparm_set_val_cmd ("", -1, disk, GRUB_ATA_CMD_IDLE, 0, standby_tout);
-    }
-
-  if (enable_smart >= 0)
-    {
-      if (! quiet)
-       grub_printf ("%sable SMART operations", (enable_smart ? "En" : "Dis"));
-      int err = grub_hdparm_do_smart_cmd (disk, (enable_smart ?
-                 GRUB_ATA_FEAT_SMART_ENABLE : GRUB_ATA_FEAT_SMART_DISABLE));
-      if (! quiet)
-       grub_printf ("%s\n", err ? ": not supported" : "");
-    }
-
-  if (sec_freeze)
-    grub_hdparm_simple_cmd ("Freeze security settings", disk,
-                            GRUB_ATA_CMD_SECURITY_FREEZE_LOCK);
-
-  /* Print/dump IDENTIFY.  */
-  if (ident || dumpid)
-    {
-      char buf[GRUB_DISK_SECTOR_SIZE];
-      if (grub_hdparm_do_ata_cmd (disk, GRUB_ATA_CMD_IDENTIFY_DEVICE,
-          0, 0, buf, sizeof (buf)))
-       grub_printf ("Cannot read ATA IDENTIFY data\n");
-      else
-       {
-         if (ident)
-           grub_hdparm_print_identify (buf);
-         if (dumpid)
-           hexdump (0, buf, sizeof (buf));
-       }
-    }
-
-  /* Check power mode.  */
-  if (power)
-    {
-      grub_printf ("Disk power mode is: ");
-      int mode = grub_hdparm_do_check_powermode_cmd (disk);
-      if (mode < 0)
-        grub_printf ("unknown\n");
-      else
-       grub_printf ("%s (0x%02x)\n",
-                    (mode == 0xff ? "active/idle" :
-                     mode == 0x80 ? "idle" :
-                     mode == 0x00 ? "standby" : "unknown"), mode);
-    }
-
-  /* Check health.  */
-  int status = 0;
-  if (health)
-    {
-      if (! quiet)
-       grub_printf ("SMART status is: ");
-      int err = grub_hdparm_do_smart_cmd (disk, GRUB_ATA_FEAT_SMART_STATUS);
-      if (! quiet)
-       grub_printf ("%s\n", (err  < 0 ? "unknown" :
-                             err == 0 ? "OK" : "*BAD*"));
-      status = (err > 0);
-    }
-
-  /* Change power mode.  */
-  if (standby_now)
-    grub_hdparm_simple_cmd ("Set disk to standby mode", disk,
-                           GRUB_ATA_CMD_STANDBY_IMMEDIATE);
-
-  if (sleep_now)
-    grub_hdparm_simple_cmd ("Set disk to sleep mode", disk,
-                           GRUB_ATA_CMD_SLEEP);
-
-  grub_disk_close (disk);
-
-  grub_errno = GRUB_ERR_NONE;
-  return status;
-}
-
-static grub_extcmd_t cmd;
-
-GRUB_MOD_INIT(hdparm)
-{
-  cmd = grub_register_extcmd ("hdparm", grub_cmd_hdparm,
-                             GRUB_COMMAND_FLAG_BOTH,
-                             N_("[OPTIONS] DISK"),
-                             N_("Get/set ATA disk parameters."), options);
-}
-
-GRUB_MOD_FINI(hdparm)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/commands/help.c b/commands/help.c
deleted file mode 100644 (file)
index c2aad03..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/* help.c - command to show a help text.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/term.h>
-#include <grub/extcmd.h>
-#include <grub/i18n.h>
-#include <grub/mm.h>
-#include <grub/normal.h>
-#include <grub/charset.h>
-
-static grub_err_t
-grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
-              char **args)
-{
-  int cnt = 0;
-  char *currarg;
-
-  auto int print_command_info (grub_command_t cmd);
-  auto int print_command_help (grub_command_t cmd);
-
-  int print_command_info (grub_command_t cmd)
-    {
-      if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) &&
-         (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE))
-       {
-         struct grub_term_output *term;
-         const char *summary_translated = _(cmd->summary);
-         char *command_help;
-         grub_uint32_t *unicode_command_help;
-         grub_uint32_t *unicode_last_position;
-                                     
-         command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated);
-         if (!command_help)
-           return 1;
-
-         grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help,
-                                  &unicode_last_position);
-
-         FOR_ACTIVE_TERM_OUTPUTS(term)
-         {
-           unsigned stringwidth;
-           grub_uint32_t *unicode_last_screen_position;
-
-           unicode_last_screen_position = unicode_command_help;
-
-           stringwidth = 0;
-
-           while (unicode_last_screen_position < unicode_last_position && 
-                  stringwidth < ((grub_term_width (term) / 2) - 2))
-             {
-               stringwidth
-                 += grub_term_getcharwidth (term,
-                                            *unicode_last_screen_position);
-               unicode_last_screen_position++;
-             }
-
-           grub_print_ucs4 (unicode_command_help,
-                            unicode_last_screen_position, term);
-           if (!(cnt % 2))
-             grub_print_spaces (term, grub_term_width (term) / 2
-                                - stringwidth);
-         }
-         if (cnt % 2)
-           grub_printf ("\n");
-         cnt++;
-         
-         grub_free (command_help);
-         grub_free (unicode_command_help);
-       }
-      return 0;
-    }
-
-  int print_command_help (grub_command_t cmd)
-    {
-      if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE)
-       {
-         if (! grub_strncmp (cmd->name, currarg, grub_strlen (currarg)))
-           {
-             if (cnt++ > 0)
-               grub_printf ("\n\n");
-
-             if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD)
-               grub_arg_show_help ((grub_extcmd_t) cmd->data);
-             else
-               grub_printf ("%s %s %s\n%s\n", _("Usage:"), cmd->name, _(cmd->summary),
-                            _(cmd->description));
-           }
-       }
-      return 0;
-    }
-
-  if (argc == 0)
-    {
-      grub_command_iterate (print_command_info);
-      if (!(cnt % 2))
-       grub_printf ("\n");
-    }
-  else
-    {
-      int i;
-
-      for (i = 0; i < argc; i++)
-       {
-         currarg = args[i];
-         grub_command_iterate (print_command_help);
-       }
-    }
-
-  return 0;
-}
-
-static grub_extcmd_t cmd;
-\f
-GRUB_MOD_INIT(help)
-{
-  cmd = grub_register_extcmd ("help", grub_cmd_help,
-                             GRUB_COMMAND_FLAG_CMDLINE,
-                             N_("[PATTERN ...]"),
-                             N_("Show a help message."), 0);
-}
-
-GRUB_MOD_FINI(help)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/commands/hexdump.c b/commands/hexdump.c
deleted file mode 100644 (file)
index c1d4ecb..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/* hexdump.c - command to dump the contents of a file or memory */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/file.h>
-#include <grub/disk.h>
-#include <grub/misc.h>
-#include <grub/gzio.h>
-#include <grub/lib/hexdump.h>
-#include <grub/extcmd.h>
-#include <grub/i18n.h>
-
-static const struct grub_arg_option options[] = {
-  {"skip", 's', 0, N_("Skip offset bytes from the beginning of file."), 0,
-   ARG_TYPE_INT},
-  {"length", 'n', 0, N_("Read only LENGTH bytes."), 0, ARG_TYPE_INT},
-  {0, 0, 0, 0, 0, 0}
-};
-
-static grub_err_t
-grub_cmd_hexdump (grub_extcmd_t cmd, int argc, char **args)
-{
-  struct grub_arg_list *state = cmd->state;
-  char buf[GRUB_DISK_SECTOR_SIZE * 4];
-  grub_ssize_t size, length;
-  grub_disk_addr_t skip;
-  int namelen;
-
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
-  namelen = grub_strlen (args[0]);
-  skip = (state[0].set) ? grub_strtoull (state[0].arg, 0, 0) : 0;
-  length = (state[1].set) ? grub_strtoul (state[1].arg, 0, 0) : 256;
-
-  if (!grub_strcmp (args[0], "(mem)"))
-    hexdump (skip, (char *) (grub_addr_t) skip, length);
-  else if ((args[0][0] == '(') && (args[0][namelen - 1] == ')'))
-    {
-      grub_disk_t disk;
-      grub_disk_addr_t sector;
-      grub_size_t ofs;
-
-      args[0][namelen - 1] = 0;
-      disk = grub_disk_open (&args[0][1]);
-      if (! disk)
-        return 0;
-
-      sector = (skip >> (GRUB_DISK_SECTOR_BITS + 2)) * 4;
-      ofs = skip & (GRUB_DISK_SECTOR_SIZE * 4 - 1);
-      while (length)
-        {
-          grub_size_t len;
-
-          len = length;
-          if (len > sizeof (buf))
-            len = sizeof (buf);
-
-          if (grub_disk_read (disk, sector, ofs, len, buf))
-            break;
-
-          hexdump (skip, buf, len);
-
-          ofs = 0;
-          skip += len;
-          length -= len;
-          sector += 4;
-        }
-
-      grub_disk_close (disk);
-    }
-  else
-    {
-      grub_file_t file;
-
-      file = grub_gzfile_open (args[0], 1);
-      if (! file)
-       return 0;
-
-      file->offset = skip;
-
-      while ((size = grub_file_read (file, buf, sizeof (buf))) > 0)
-       {
-         unsigned long len;
-
-         len = ((length) && (size > length)) ? length : size;
-         hexdump (skip, buf, len);
-         skip += len;
-         if (length)
-           {
-             length -= len;
-             if (!length)
-               break;
-           }
-       }
-
-      grub_file_close (file);
-    }
-
-  return 0;
-}
-\f
-static grub_extcmd_t cmd;
-
-GRUB_MOD_INIT (hexdump)
-{
-  cmd = grub_register_extcmd ("hexdump", grub_cmd_hexdump,
-                             GRUB_COMMAND_FLAG_BOTH,
-                             N_("[OPTIONS] FILE_OR_DEVICE"),
-                             N_("Dump the contents of a file or memory."),
-                             options);
-}
-
-GRUB_MOD_FINI (hexdump)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/commands/i386/cpuid.c b/commands/i386/cpuid.c
deleted file mode 100644 (file)
index 6eebf91..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/* cpuid.c - test for CPU features */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006, 2007, 2009  Free Software Foundation, Inc.
- *  Based on gcc/gcc/config/i386/driver-i386.c
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/env.h>
-#include <grub/command.h>
-#include <grub/extcmd.h>
-#include <grub/i386/cpuid.h>
-#include <grub/i18n.h>
-
-#define cpuid(num,a,b,c,d) \
-  asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
-               : "=a" (a), "=r" (b), "=c" (c), "=d" (d)  \
-               : "0" (num))
-
-static const struct grub_arg_option options[] =
-  {
-    {"long-mode", 'l', 0, N_("Check for long mode flag (default)."), 0, 0},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-#define bit_LM (1 << 29)
-
-unsigned char grub_cpuid_has_longmode = 0;
-
-static grub_err_t
-grub_cmd_cpuid (grub_extcmd_t cmd __attribute__ ((unused)),
-               int argc __attribute__ ((unused)),
-               char **args __attribute__ ((unused)))
-{
-  return grub_cpuid_has_longmode ? GRUB_ERR_NONE
-    : grub_error (GRUB_ERR_TEST_FAILURE, "false");
-}
-
-static grub_extcmd_t cmd;
-
-GRUB_MOD_INIT(cpuid)
-{
-#ifdef __x86_64__
-  /* grub-emu */
-  grub_cpuid_has_longmode = 1;
-#else
-  unsigned int eax, ebx, ecx, edx;
-  unsigned int max_level;
-  unsigned int ext_level;
-
-  /* See if we can use cpuid.  */
-  asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
-               "pushl %0; popfl; pushfl; popl %0; popfl"
-               : "=&r" (eax), "=&r" (ebx)
-               : "i" (0x00200000));
-  if (((eax ^ ebx) & 0x00200000) == 0)
-    goto done;
-
-  /* Check the highest input value for eax.  */
-  cpuid (0, eax, ebx, ecx, edx);
-  /* We only look at the first four characters.  */
-  max_level = eax;
-  if (max_level == 0)
-    goto done;
-
-  cpuid (0x80000000, eax, ebx, ecx, edx);
-  ext_level = eax;
-  if (ext_level < 0x80000000)
-    goto done;
-
-  cpuid (0x80000001, eax, ebx, ecx, edx);
-  grub_cpuid_has_longmode = !!(edx & bit_LM);
-done:
-#endif
-
-  cmd = grub_register_extcmd ("cpuid", grub_cmd_cpuid, GRUB_COMMAND_FLAG_BOTH,
-                             "[-l]", N_("Check for CPU features."), options);
-}
-
-GRUB_MOD_FINI(cpuid)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/commands/i386/pc/acpi.c b/commands/i386/pc/acpi.c
deleted file mode 100644 (file)
index 88e4f55..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/* acpi.c - get acpi tables. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/acpi.h>
-#include <grub/misc.h>
-
-struct grub_acpi_rsdp_v10 *
-grub_machine_acpi_get_rsdpv1 (void)
-{
-  int ebda_len;
-  grub_uint8_t *ebda, *ptr;
-
-  grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
-  ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
-  ebda_len = * (grub_uint16_t *) ebda;
-  if (! ebda_len)
-    return 0;
-  for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
-    if (grub_memcmp (ptr, "RSD PTR ", 8) == 0
-       && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
-       && ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
-      return (struct grub_acpi_rsdp_v10 *) ptr;
-
-  grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
-  for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
-       ptr += 16)
-    if (grub_memcmp (ptr, "RSD PTR ", 8) == 0
-       && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
-       && ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
-      return (struct grub_acpi_rsdp_v10 *) ptr;
-  return 0;
-}
-
-struct grub_acpi_rsdp_v20 *
-grub_machine_acpi_get_rsdpv2 (void)
-{
-  int ebda_len;
-  grub_uint8_t *ebda, *ptr;
-
-  grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
-  ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
-  ebda_len = * (grub_uint16_t *) ebda;
-  if (! ebda_len)
-    return 0;
-  for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
-    if (grub_memcmp (ptr, "RSD PTR ", 8) == 0
-       && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
-       && ((struct grub_acpi_rsdp_v10 *) ptr)->revision != 0
-       && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024
-       && grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length)
-       == 0)
-      return (struct grub_acpi_rsdp_v20 *) ptr;
-
-  grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
-  for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
-       ptr += 16)
-    if (grub_memcmp (ptr, "RSD PTR ", 8) == 0
-       && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
-       && ((struct grub_acpi_rsdp_v10 *) ptr)->revision != 0
-       && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024
-       && grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length)
-       == 0)
-      return (struct grub_acpi_rsdp_v20 *) ptr;
-  return 0;
-}
diff --git a/commands/i386/pc/drivemap.c b/commands/i386/pc/drivemap.c
deleted file mode 100644 (file)
index 4afc433..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
-/* drivemap.c - command to manage the BIOS drive mappings.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/extcmd.h>
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/loader.h>
-#include <grub/env.h>
-#include <grub/machine/memory.h>
-#include <grub/machine/biosnum.h>
-#include <grub/i18n.h>
-
-
-/* Real mode IVT slot (seg:off far pointer) for interrupt 0x13.  */
-static grub_uint32_t *const int13slot = UINT_TO_PTR (4 * 0x13);
-
-/* Remember to update enum opt_idxs accordingly.  */
-static const struct grub_arg_option options[] = {
-  {"list", 'l', 0, N_("Show the current mappings."), 0, 0},
-  {"reset", 'r', 0, N_("Reset all mappings to the default values."), 0, 0},
-  {"swap", 's', 0, N_("Perform both direct and reverse mappings."), 0, 0},
-  {0, 0, 0, 0, 0, 0}
-};
-
-/* Remember to update options[] accordingly.  */
-enum opt_idxs
-{
-  OPTIDX_LIST = 0,
-  OPTIDX_RESET,
-  OPTIDX_SWAP,
-};
-
-/* Realmode far ptr (2 * 16b) to the previous INT13h handler.  */
-extern grub_uint32_t grub_drivemap_oldhandler;
-
-/* The type "void" is used for imported assembly labels, takes no storage and
-   serves just to take the address with &label.  */
-
-/* The assembly function to replace the old INT13h handler. It does not follow
-   any C callspecs and returns with IRET.  */
-extern const void grub_drivemap_handler;
-
-/* Start of the drive mappings area (space reserved at runtime).  */
-extern const void grub_drivemap_mapstart;
-
-typedef struct drivemap_node
-{
-  struct drivemap_node *next;
-  grub_uint8_t newdrive;
-  grub_uint8_t redirto;
-} drivemap_node_t;
-
-typedef struct __attribute__ ((packed)) int13map_node
-{
-  grub_uint8_t disknum;
-  grub_uint8_t mapto;
-} int13map_node_t;
-
-#define INT13H_OFFSET(x) \
-       (((grub_uint8_t *)(x)) - ((grub_uint8_t *)&grub_drivemap_handler))
-
-static drivemap_node_t *map_head;
-static void *drivemap_hook;
-static int drivemap_mmap;
-
-/* Puts the specified mapping into the table, replacing an existing mapping
-   for newdrive or adding a new one if required.  */
-static grub_err_t
-drivemap_set (grub_uint8_t newdrive, grub_uint8_t redirto)
-{
-  drivemap_node_t *mapping = 0;
-  drivemap_node_t *search = map_head;
-  while (search)
-    {
-      if (search->newdrive == newdrive)
-       {
-         mapping = search;
-         break;
-       }
-      search = search->next;
-    }
-
-  /* Check for pre-existing mappings to modify before creating a new one.  */
-  if (mapping)
-    mapping->redirto = redirto;
-  else
-    {
-      mapping = grub_malloc (sizeof (drivemap_node_t));
-      if (! mapping)
-       return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                          "cannot allocate map entry, not enough memory");
-      mapping->newdrive = newdrive;
-      mapping->redirto = redirto;
-      mapping->next = map_head;
-      map_head = mapping;
-    }
-  return GRUB_ERR_NONE;
-}
-
-/* Removes the mapping for newdrive from the table.  If there is no mapping,
-   then this function behaves like a no-op on the map.  */
-static void
-drivemap_remove (grub_uint8_t newdrive)
-{
-  drivemap_node_t *mapping = 0;
-  drivemap_node_t *search = map_head;
-  drivemap_node_t *previous = 0;
-
-  while (search)
-    {
-      if (search->newdrive == newdrive)
-       {
-         mapping = search;
-         break;
-       }
-      previous = search;
-      search = search->next;
-    }
-
-  if (mapping)
-    {
-      if (previous)
-       previous->next = mapping->next;
-      else
-       map_head = mapping->next;
-      grub_free (mapping);
-    }
-}
-
-/* Given a GRUB-like device name and a convenient location, stores the
-   related BIOS disk number.  Accepts devices like \((f|h)dN\), with
-   0 <= N < 128.  */
-static grub_err_t
-tryparse_diskstring (const char *str, grub_uint8_t *output)
-{
-  /* Skip opening paren in order to allow both (hd0) and hd0.  */
-  if (*str == '(')
-    str++;
-  if ((str[0] == 'f' || str[0] == 'h') && str[1] == 'd')
-    {
-      grub_uint8_t bios_num = (str[0] == 'h') ? 0x80 : 0x00;
-      unsigned long drivenum = grub_strtoul (str + 2, 0, 0);
-      if (grub_errno == GRUB_ERR_NONE && drivenum < 128)
-       {
-         bios_num |= drivenum;
-         if (output)
-           *output = bios_num;
-         return GRUB_ERR_NONE;
-       }
-    }
-  return grub_error (GRUB_ERR_BAD_ARGUMENT, "device format \"%s\" "
-                    "invalid: must be (f|h)dN, with 0 <= N < 128", str);
-}
-
-static grub_err_t
-list_mappings (void)
-{
-  /* Show: list mappings.  */
-  if (! map_head)
-    {
-      grub_printf ("No drives have been remapped\n");
-      return GRUB_ERR_NONE;
-    }
-
-  grub_printf ("OS disk #num ------> GRUB/BIOS device\n");
-  drivemap_node_t *curnode = map_head;
-  while (curnode)
-    {
-      grub_printf ("%cD #%-3u (0x%02x)       %cd%d\n",
-                  (curnode->newdrive & 0x80) ? 'H' : 'F',
-                  curnode->newdrive & 0x7F, curnode->newdrive,
-                  (curnode->redirto & 0x80) ? 'h' : 'f',
-                  curnode->redirto & 0x7F
-                  );
-      curnode = curnode->next;
-    }
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_cmd_drivemap (struct grub_extcmd *cmd, int argc, char **args)
-{
-  if (cmd->state[OPTIDX_LIST].set)
-    {
-      return list_mappings ();
-    }
-  else if (cmd->state[OPTIDX_RESET].set)
-    {
-      /* Reset: just delete all mappings, freeing their memory.  */
-      drivemap_node_t *curnode = map_head;
-      drivemap_node_t *prevnode = 0;
-      while (curnode)
-       {
-         prevnode = curnode;
-         curnode = curnode->next;
-         grub_free (prevnode);
-       }
-      map_head = 0;
-      return GRUB_ERR_NONE;
-    }
-  else if (!cmd->state[OPTIDX_SWAP].set && argc == 0)
-    {
-      /* No arguments */
-      return list_mappings ();
-    }
-
-  /* Neither flag: put mapping.  */
-  grub_uint8_t mapfrom = 0;
-  grub_uint8_t mapto = 0xFF;
-  grub_err_t err;
-
-  if (argc != 2)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required");
-
-  err = tryparse_diskstring (args[0], &mapfrom);
-  if (err != GRUB_ERR_NONE)
-    return err;
-
-  err = tryparse_diskstring (args[1], &mapto);
-  if (err != GRUB_ERR_NONE)
-    return err;
-
-  if (mapto == mapfrom)
-    {
-      /* Reset to default.  */
-      grub_dprintf ("drivemap", "Removing mapping for %s (%02x)\n",
-                   args[0], mapfrom);
-      drivemap_remove (mapfrom);
-      return GRUB_ERR_NONE;
-    }
-  /* Set the mapping for the disk (overwrites any existing mapping).  */
-  grub_dprintf ("drivemap", "%s %s (%02x) = %s (%02x)\n",
-               cmd->state[OPTIDX_SWAP].set ? "Swapping" : "Mapping",
-               args[1], mapto, args[0], mapfrom);
-  err = drivemap_set (mapto, mapfrom);
-  /* If -s, perform the reverse mapping too (only if the first was OK).  */
-  if (cmd->state[OPTIDX_SWAP].set && err == GRUB_ERR_NONE)
-    err = drivemap_set (mapfrom, mapto);
-  return err;
-}
-
-/* Int13h handler installer - reserves conventional memory for the handler,
-   copies it over and sets the IVT entry for int13h.
-   This code rests on the assumption that GRUB does not activate any kind
-   of memory mapping apart from identity paging, since it accesses
-   realmode structures by their absolute addresses, like the IVT at 0;
-   and transforms a pmode pointer into a rmode seg:off far ptr.  */
-static grub_err_t
-install_int13_handler (int noret __attribute__ ((unused)))
-{
-  /* Size of the full int13 handler "bundle", including code and map.  */
-  grub_uint32_t total_size;
-  /* Base address of the space reserved for the handler bundle.  */
-  grub_uint8_t *handler_base = 0;
-  /* Address of the map within the deployed bundle.  */
-  int13map_node_t *handler_map;
-
-  int i;
-  int entries = 0;
-  drivemap_node_t *curentry = map_head;
-
-  /* Count entries to prepare a contiguous map block.  */
-  while (curentry)
-    {
-      entries++;
-      curentry = curentry->next;
-    }
-  if (entries == 0)
-    {
-      /* No need to install the int13h handler.  */
-      grub_dprintf ("drivemap", "No drives marked as remapped, not installing "
-                   "our int13h handler.\n");
-      return GRUB_ERR_NONE;
-    }
-
-  grub_dprintf ("drivemap", "Installing our int13h handler\n");
-
-  /* Save the pointer to the old handler.  */
-  grub_drivemap_oldhandler = *int13slot;
-  grub_dprintf ("drivemap", "Original int13 handler: %04x:%04x\n",
-               (grub_drivemap_oldhandler >> 16) & 0x0ffff,
-               grub_drivemap_oldhandler & 0x0ffff);
-
-  /* Find a rmode-segment-aligned zone in conventional memory big
-     enough to hold the handler and its data.  */
-  total_size = INT13H_OFFSET (&grub_drivemap_mapstart)
-    + (entries + 1) * sizeof (int13map_node_t);
-  grub_dprintf ("drivemap", "Payload is %u bytes long\n", total_size);
-  handler_base = grub_mmap_malign_and_register (16, total_size,
-                                               &drivemap_mmap,
-                                               GRUB_MACHINE_MEMORY_RESERVED,
-                                               GRUB_MMAP_MALLOC_LOW);
-  if (! handler_base)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't reserve "
-                      "memory for the int13h handler");
-
-  /* Copy int13h handler bundle to reserved area.  */
-  grub_dprintf ("drivemap", "Reserved memory at %p, copying handler\n",
-               handler_base);
-  grub_memcpy (handler_base, &grub_drivemap_handler,
-              INT13H_OFFSET (&grub_drivemap_mapstart));
-
-  /* Copy the mappings to the reserved area.  */
-  curentry = map_head;
-  handler_map = (int13map_node_t *) (handler_base +
-                                    INT13H_OFFSET (&grub_drivemap_mapstart));
-  grub_dprintf ("drivemap", "Target map at %p, copying mappings\n", handler_map);
-  for (i = 0; i < entries; ++i, curentry = curentry->next)
-    {
-      handler_map[i].disknum = curentry->newdrive;
-      handler_map[i].mapto = curentry->redirto;
-      grub_dprintf ("drivemap", "\t#%d: 0x%02x <- 0x%02x\n", i,
-                   handler_map[i].disknum, handler_map[i].mapto);
-    }
-  /* Signal end-of-map.  */
-  handler_map[i].disknum = 0;
-  handler_map[i].mapto = 0;
-  grub_dprintf ("drivemap", "\t#%d: 0x00 <- 0x00 (end)\n", i);
-
-  /* Install our function as the int13h handler in the IVT.  */
-  *int13slot = ((grub_uint32_t) handler_base) << 12;   /* Segment address.  */
-  grub_dprintf ("drivemap", "New int13 handler: %04x:%04x\n",
-               (*int13slot >> 16) & 0x0ffff, *int13slot & 0x0ffff);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-uninstall_int13_handler (void)
-{
-  if (! grub_drivemap_oldhandler)
-    return GRUB_ERR_NONE;
-
-  *int13slot = grub_drivemap_oldhandler;
-  grub_mmap_free_and_unregister (drivemap_mmap);
-  grub_drivemap_oldhandler = 0;
-  grub_dprintf ("drivemap", "Restored int13 handler: %04x:%04x\n",
-               (*int13slot >> 16) & 0x0ffff, *int13slot & 0x0ffff);
-
-  return GRUB_ERR_NONE;
-}
-
-static int
-grub_get_root_biosnumber_drivemap (void)
-{
-  char *biosnum;
-  int ret = -1;
-  grub_device_t dev;
-
-  biosnum = grub_env_get ("biosnum");
-
-  if (biosnum)
-    return grub_strtoul (biosnum, 0, 0);
-
-  dev = grub_device_open (0);
-  if (dev && dev->disk && dev->disk->dev
-      && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID)
-    {
-      drivemap_node_t *curnode = map_head;
-      ret = (int) dev->disk->id;
-      while (curnode)
-       {
-         if (curnode->redirto == ret)
-           {
-             ret = curnode->newdrive;
-             break;
-           }
-         curnode = curnode->next;
-       }
-
-    }
-
-  if (dev)
-    grub_device_close (dev);
-
-  return ret;
-}
-
-static grub_extcmd_t cmd;
-static int (*grub_get_root_biosnumber_saved) (void);
-
-GRUB_MOD_INIT (drivemap)
-{
-  grub_get_root_biosnumber_saved = grub_get_root_biosnumber;
-  grub_get_root_biosnumber = grub_get_root_biosnumber_drivemap;
-  cmd = grub_register_extcmd ("drivemap", grub_cmd_drivemap,
-                             GRUB_COMMAND_FLAG_BOTH,
-                             N_("-l | -r | [-s] grubdev osdisk."),
-                             N_("Manage the BIOS drive mappings."),
-                             options);
-  drivemap_hook =
-    grub_loader_register_preboot_hook (&install_int13_handler,
-                                      &uninstall_int13_handler,
-                                      GRUB_LOADER_PREBOOT_HOOK_PRIO_NORMAL);
-}
-
-GRUB_MOD_FINI (drivemap)
-{
-  grub_get_root_biosnumber = grub_get_root_biosnumber_saved;
-  grub_loader_unregister_preboot_hook (drivemap_hook);
-  drivemap_hook = 0;
-  grub_unregister_extcmd (cmd);
-}
diff --git a/commands/i386/pc/drivemap_int13h.S b/commands/i386/pc/drivemap_int13h.S
deleted file mode 100644 (file)
index b460cd7..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/* drivemap_int13h.S - interrupt handler for the BIOS drive remapper */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-
-#define INT13H_OFFSET(x) ((x) - LOCAL (base))
-
-.code16
-
-/* Copy starts here.  When deployed, this code must be segment-aligned.  */
-
-/* The replacement int13 handler.   Preserve all registers.  */
-FUNCTION(grub_drivemap_handler)
-LOCAL (base):
-       /* Save %dx for future restore. */
-       push    %dx
-       /* Push flags. Used to simulate interrupt with original flags. */
-       pushf
-
-       /* Map the drive number (always in DL).  */
-       push    %ax
-       push    %bx
-       movw    $INT13H_OFFSET(LOCAL (mapstart)), %bx
-
-more_remaining:
-       movw    %cs:(%bx), %ax
-       cmpb    %ah, %al
-       jz      not_found /* DRV=DST => map end - drive not remapped, keep DL.  */
-       inc     %bx
-       inc     %bx
-       cmpb    %dl, %al
-       jnz     more_remaining /* Not found, but more remaining, loop.  */
-       movb    %ah, %dl /* Found - drive remapped, modify DL.  */
-
-not_found:
-       pop     %bx
-       pop     %ax
-
-       /* If the call isn't ah=0x8 or ah=0x15 we must restore %dx.  */
-       cmpb    $0x8, %ah
-       jz      norestore
-       cmpb    $0x15, %ah
-       jz      norestore
-
-       /* Restore flags.  */
-       popf
-       pushf
-
-       lcall *%cs:INT13H_OFFSET (LOCAL (oldhandler))
-
-       push    %bp
-       mov     %sp, %bp
-
-tail:
-       /* Save new flags below %esp so the caller will recieve new flags.  */
-       pushf
-       pop     %dx
-       mov     %dx, 8(%bp)
-
-       pop     %bp
-
-       /* Restore %dx.  */
-       pop     %dx
-       iret
-
-norestore:
-
-       /* Restore flags.  */
-       popf
-       pushf
-
-       lcall *%cs:INT13H_OFFSET (LOCAL (oldhandler))
-
-       push    %bp
-       mov     %sp, %bp
-
-       /* Save %dx. So it won't be restored to original value.  */
-       mov     %dx, 2(%bp)
-
-       jmp tail
-
-/* Far pointer to the old handler.  Stored as a CS:IP in the style of real-mode
-   IVT entries (thus PI:SC in mem).  */
-VARIABLE(grub_drivemap_oldhandler)
-LOCAL (oldhandler):
-       .word 0x0, 0x0
-
-/* This label MUST be at the end of the copied block, since the installer code
-   reserves additional space for mappings at runtime and copies them over it.  */
-       .align 2
-       
-VARIABLE(grub_drivemap_mapstart)
-LOCAL (mapstart):
-       .byte 0
diff --git a/commands/i386/pc/halt.c b/commands/i386/pc/halt.c
deleted file mode 100644 (file)
index 4c39612..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* halt.c - command to halt the computer.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/extcmd.h>
-#include <grub/i18n.h>
-
-static const struct grub_arg_option options[] =
-  {
-    {"no-apm", 'n', 0, N_("Do not use APM to halt the computer."), 0, 0},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-static grub_err_t
-grub_cmd_halt (grub_extcmd_t cmd,
-              int argc __attribute__ ((unused)),
-              char **args __attribute__ ((unused)))
-
-{
-  struct grub_arg_list *state = cmd->state;
-  int no_apm = 0;
-  if (state[0].set)
-    no_apm = 1;
-  grub_halt (no_apm);
-  return 0;
-}
-
-static grub_extcmd_t cmd;
-\f
-GRUB_MOD_INIT(halt)
-{
-  cmd = grub_register_extcmd ("halt", grub_cmd_halt, GRUB_COMMAND_FLAG_BOTH,
-                             "[-n]",
-                             N_("Halt the system, if possible using APM."),
-                             options);
-}
-
-GRUB_MOD_FINI(halt)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/commands/i386/pc/play.c b/commands/i386/pc/play.c
deleted file mode 100644 (file)
index 4ed937d..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-/* play.c - command to play a tune  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Lots of this file is borrowed from GNU/Hurd generic-speaker driver.  */
-
-#include <grub/dl.h>
-#include <grub/file.h>
-#include <grub/disk.h>
-#include <grub/term.h>
-#include <grub/misc.h>
-#include <grub/machine/time.h>
-#include <grub/cpu/io.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-#define BASE_TEMPO (60 * GRUB_TICKS_PER_SECOND)
-
-/* The speaker port.  */
-#define SPEAKER                        0x61
-
-/* If 0, follow state of SPEAKER_DATA bit, otherwise enable output
-   from timer 2.  */
-#define SPEAKER_TMR2           0x01
-
-/* If SPEAKER_TMR2 is not set, this provides direct input into the
-   speaker.  Otherwise, this enables or disables the output from the
-   timer.  */
-#define SPEAKER_DATA           0x02
-
-/* The PIT channel value ports.  You can write to and read from them.
-   Do not mess with timer 0 or 1.  */
-#define PIT_COUNTER_0          0x40
-#define PIT_COUNTER_1          0x41
-#define PIT_COUNTER_2          0x42
-
-/* The frequency of the PIT clock.  */
-#define PIT_FREQUENCY          0x1234dd
-
-/* The PIT control port.  You can only write to it.  Do not mess with
-   timer 0 or 1.  */
-#define PIT_CTRL               0x43
-#define PIT_CTRL_SELECT_MASK   0xc0
-#define PIT_CTRL_SELECT_0      0x00
-#define PIT_CTRL_SELECT_1      0x40
-#define PIT_CTRL_SELECT_2      0x80
-
-/* Read and load control.  */
-#define PIT_CTRL_READLOAD_MASK 0x30
-#define PIT_CTRL_COUNTER_LATCH 0x00    /* Hold timer value until read.  */
-#define PIT_CTRL_READLOAD_LSB  0x10    /* Read/load the LSB.  */
-#define PIT_CTRL_READLOAD_MSB  0x20    /* Read/load the MSB.  */
-#define PIT_CTRL_READLOAD_WORD 0x30    /* Read/load the LSB then the MSB.  */
-
-/* Mode control.  */
-#define PIT_CTRL_MODE_MASK     0x0e
-
-/* Interrupt on terminal count.  Setting the mode sets output to low.
-   When counter is set and terminated, output is set to high.  */
-#define PIT_CTRL_INTR_ON_TERM  0x00
-
-/* Programmable one-shot.  When loading counter, output is set to
-   high.  When counter terminated, output is set to low.  Can be
-   triggered again from that point on by setting the gate pin to
-   high.  */
-#define PIT_CTRL_PROGR_ONE_SHOT        0x02
-
-/* Rate generator.  Output is low for one period of the counter, and
-   high for the other.  */
-#define PIT_CTRL_RATE_GEN      0x04
-
-/* Square wave generator.  Output is low for one half of the period,
-   and high for the other half.  */
-#define PIT_CTRL_SQUAREWAVE_GEN        0x06
-
-/* Software triggered strobe.  Setting the mode sets output to high.
-   When counter is set and terminated, output is set to low.  */
-#define PIT_CTRL_SOFTSTROBE    0x08
-
-/* Hardware triggered strobe.  Like software triggered strobe, but
-   only starts the counter when the gate pin is set to high.  */
-#define PIT_CTRL_HARDSTROBE    0x0a
-
-/* Count mode.  */
-#define PIT_CTRL_COUNT_MASK    0x01
-#define PIT_CTRL_COUNT_BINARY  0x00    /* 16-bit binary counter.  */
-#define PIT_CTRL_COUNT_BCD     0x01    /* 4-decade BCD counter.  */
-
-#define T_REST                 ((grub_uint16_t) 0)
-#define T_FINE                 ((grub_uint16_t) -1)
-
-struct note
-{
-  grub_uint16_t pitch;
-  grub_uint16_t duration;
-};
-
-static void
-beep_off (void)
-{
-  unsigned char status;
-
-  status = grub_inb (SPEAKER);
-  grub_outb (status & ~(SPEAKER_TMR2 | SPEAKER_DATA), SPEAKER);
-}
-
-static void
-beep_on (grub_uint16_t pitch)
-{
-  unsigned char status;
-  unsigned int counter;
-
-  if (pitch < 20)
-    pitch = 20;
-  else if (pitch > 20000)
-    pitch = 20000;
-
-  counter = PIT_FREQUENCY / pitch;
-
-  /* Program timer 2.  */
-  grub_outb (PIT_CTRL_SELECT_2 | PIT_CTRL_READLOAD_WORD
-       | PIT_CTRL_SQUAREWAVE_GEN | PIT_CTRL_COUNT_BINARY, PIT_CTRL);
-  grub_outb (counter & 0xff, PIT_COUNTER_2);           /* LSB */
-  grub_outb ((counter >> 8) & 0xff, PIT_COUNTER_2);    /* MSB */
-
-  /* Start speaker.  */
-  status = grub_inb (SPEAKER);
-  grub_outb (status | SPEAKER_TMR2 | SPEAKER_DATA, SPEAKER);
-}
-
-/* Returns whether playing should continue.  */
-static int
-play (unsigned tempo, struct note *note)
-{
-  unsigned int to;
-
-  if (note->pitch == T_FINE || grub_checkkey () >= 0)
-    return 1;
-
-  grub_dprintf ("play", "pitch = %d, duration = %d\n", note->pitch,
-                note->duration);
-
-  switch (note->pitch)
-    {
-      case T_REST:
-        beep_off ();
-        break;
-
-      default:
-        beep_on (note->pitch);
-        break;
-    }
-
-  to = grub_get_rtc () + BASE_TEMPO * note->duration / tempo;
-  while (((unsigned int) grub_get_rtc () <= to) && (grub_checkkey () < 0))
-    ;
-
-  return 0;
-}
-
-static grub_err_t
-grub_cmd_play (grub_command_t cmd __attribute__ ((unused)),
-              int argc, char **args)
-{
-
-  if (argc < 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name or tempo and notes required");
-
-  if (argc == 1)
-    {
-      struct note buf;
-      grub_uint32_t tempo;
-      grub_file_t file;
-
-      file = grub_file_open (args[0]);
-
-      if (! file)
-        return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
-
-      if (grub_file_read (file, &tempo, sizeof (tempo)) != sizeof (tempo))
-        {
-          grub_file_close (file);
-          return grub_error (GRUB_ERR_FILE_READ_ERROR,
-                             "file doesn't even contains a full tempo record");
-        }
-
-      tempo = grub_le_to_cpu32 (tempo);
-      grub_dprintf ("play","tempo = %d\n", tempo);
-
-      while (grub_file_read (file, &buf,
-                             sizeof (struct note)) == sizeof (struct note))
-        {
-          buf.pitch = grub_le_to_cpu16 (buf.pitch);
-          buf.duration = grub_le_to_cpu16 (buf.duration);
-
-          if (play (tempo, &buf))
-            break;
-        }
-
-      grub_file_close (file);
-    }
-  else
-    {
-      char *end;
-      unsigned tempo;
-      struct note note;
-      int i;
-
-      tempo = grub_strtoul (args[0], &end, 0);
-
-      if (*end)
-        /* Was not a number either, assume it was supposed to be a file name.  */
-        return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
-
-      grub_dprintf ("play","tempo = %d\n", tempo);
-
-      for (i = 1; i + 1 < argc; i += 2)
-        {
-          note.pitch = grub_strtoul (args[i], &end, 0);
-          if (*end)
-            {
-              grub_error (GRUB_ERR_BAD_NUMBER, "bogus pitch number");
-              break;
-            }
-
-          note.duration = grub_strtoul (args[i + 1], &end, 0);
-          if (*end)
-            {
-              grub_error (GRUB_ERR_BAD_NUMBER, "bogus duration number");
-              break;
-            }
-
-          if (play (tempo, &note))
-            break;
-        }
-    }
-
-  beep_off ();
-
-  while (grub_checkkey () > 0)
-    grub_getkey ();
-
-  return 0;
-}
-
-static grub_command_t cmd;
-\f
-GRUB_MOD_INIT(play)
-{
-  cmd = grub_register_command ("play", grub_cmd_play,
-                              N_("FILE | TEMPO [PITCH1 DURATION1] [PITCH2 DURATION2] ... "),
-                              N_("Play a tune."));
-}
-
-GRUB_MOD_FINI(play)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/i386/pc/pxecmd.c b/commands/i386/pc/pxecmd.c
deleted file mode 100644 (file)
index b576a8e..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* pxe.c - command to control the pxe driver  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/machine/pxe.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-grub_cmd_pxe_unload (grub_command_t cmd __attribute__ ((unused)),
-                    int argc __attribute__ ((unused)),
-                    char **args __attribute__ ((unused)))
-{
-  if (! grub_pxe_pxenv)
-    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no pxe environment");
-
-  grub_pxe_unload ();
-
-  return 0;
-}
-
-static grub_command_t cmd;
-
-GRUB_MOD_INIT(pxecmd)
-{
-  cmd = grub_register_command ("pxe_unload", grub_cmd_pxe_unload,
-                              0,
-                              N_("Unload PXE environment."));
-}
-
-GRUB_MOD_FINI(pxecmd)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/i386/pc/vbeinfo.c b/commands/i386/pc/vbeinfo.c
deleted file mode 100644 (file)
index c266bbf..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/* vbeinfo.c - command to list compatible VBE video modes.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/env.h>
-#include <grub/misc.h>
-#include <grub/machine/init.h>
-#include <grub/machine/vbe.h>
-#include <grub/mm.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static void *
-real2pm (grub_vbe_farptr_t ptr)
-{
-  return (void *) ((((unsigned long) ptr & 0xFFFF0000) >> 12UL)
-                  + ((unsigned long) ptr & 0x0000FFFF));
-}
-
-static grub_err_t
-grub_cmd_vbeinfo (grub_command_t cmd __attribute__ ((unused)),
-                 int argc __attribute__ ((unused)),
-                 char **args __attribute__ ((unused)))
-{
-  struct grub_vbe_info_block controller_info;
-  struct grub_vbe_mode_info_block mode_info_tmp;
-  grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE;
-  grub_uint16_t *video_mode_list;
-  grub_uint16_t *p;
-  grub_uint16_t *saved_video_mode_list;
-  grub_size_t video_mode_list_size;
-  grub_err_t err;
-  char *modevar;
-
-  err = grub_vbe_probe (&controller_info);
-  if (err != GRUB_ERR_NONE)
-    return err;
-
-  grub_printf ("VBE info:   version: %d.%d  OEM software rev: %d.%d\n",
-              controller_info.version >> 8,
-               controller_info.version & 0xFF,
-               controller_info.oem_software_rev >> 8,
-               controller_info.oem_software_rev & 0xFF);
-
-  /* The total_memory field is in 64 KiB units.  */
-  grub_printf ("            total memory: %d KiB\n",
-               (controller_info.total_memory << 16) / 1024);
-
-  /* Because the information on video modes is stored in a temporary place,
-     it is better to copy it to somewhere safe.  */
-  p = video_mode_list = real2pm (controller_info.video_mode_ptr);
-  while (*p++ != 0xFFFF)
-    ;
-
-  video_mode_list_size = (grub_addr_t) p - (grub_addr_t) video_mode_list;
-  saved_video_mode_list = grub_malloc (video_mode_list_size);
-  if (! saved_video_mode_list)
-    return grub_errno;
-
-  grub_memcpy (saved_video_mode_list, video_mode_list, video_mode_list_size);
-
-  grub_printf ("List of compatible video modes:\n");
-  grub_printf ("Legend: P=Packed pixel, D=Direct color, "
-              "mask/pos=R/G/B/reserved\n");
-
-  /* Walk through all video modes listed.  */
-  for (p = saved_video_mode_list; *p != 0xFFFF; p++)
-    {
-      const char *memory_model = 0;
-      grub_uint32_t mode = (grub_uint32_t) *p;
-
-      err = grub_vbe_get_video_mode_info (mode, &mode_info_tmp);
-      if (err != GRUB_ERR_NONE)
-       {
-         grub_errno = GRUB_ERR_NONE;
-         continue;
-       }
-
-      if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_SUPPORTED) == 0)
-       /* If not available, skip it.  */
-       continue;
-
-      if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_RESERVED_1) == 0)
-       /* Not enough information.  */
-       continue;
-
-      if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_COLOR) == 0)
-       /* Monochrome is unusable.  */
-       continue;
-
-      if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_LFB_AVAIL) == 0)
-       /* We support only linear frame buffer modes.  */
-       continue;
-
-      if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_GRAPHICS) == 0)
-       /* We allow only graphical modes.  */
-       continue;
-
-      switch (mode_info_tmp.memory_model)
-       {
-       case GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL:
-         memory_model = "Packed";
-         break;
-       case GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR:
-         memory_model = "Direct";
-         break;
-
-       default:
-         break;
-       }
-
-      if (! memory_model)
-       continue;
-
-      grub_printf ("0x%03x:  %4d x %4d x %2d  %s",
-                   mode,
-                   mode_info_tmp.x_resolution,
-                   mode_info_tmp.y_resolution,
-                   mode_info_tmp.bits_per_pixel,
-                   memory_model);
-
-      /* Show mask and position details for direct color modes.  */
-      if (mode_info_tmp.memory_model == GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR)
-        grub_printf (", mask: %d/%d/%d/%d  pos: %d/%d/%d/%d",
-                     mode_info_tmp.red_mask_size,
-                     mode_info_tmp.green_mask_size,
-                     mode_info_tmp.blue_mask_size,
-                     mode_info_tmp.rsvd_mask_size,
-                     mode_info_tmp.red_field_position,
-                     mode_info_tmp.green_field_position,
-                     mode_info_tmp.blue_field_position,
-                     mode_info_tmp.rsvd_field_position);
-      grub_printf ("\n");
-    }
-
-  grub_free (saved_video_mode_list);
-
-  /* Check existence of vbe_mode environment variable.  */
-  modevar = grub_env_get ("vbe_mode");
-
-  if (modevar != 0)
-    {
-      unsigned long value;
-
-      value = grub_strtoul (modevar, 0, 0);
-      if (grub_errno == GRUB_ERR_NONE)
-       use_mode = value;
-      else
-       grub_errno = GRUB_ERR_NONE;
-    }
-
-  grub_printf ("Configured VBE mode (vbe_mode) = 0x%03x\n", use_mode);
-
-  return 0;
-}
-
-static grub_command_t cmd;
-
-GRUB_MOD_INIT(vbeinfo)
-{
-  cmd =
-    grub_register_command ("vbeinfo", grub_cmd_vbeinfo, 0,
-                          N_("List compatible VESA BIOS extension video modes."));
-}
-
-GRUB_MOD_FINI(vbeinfo)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/i386/pc/vbetest.c b/commands/i386/pc/vbetest.c
deleted file mode 100644 (file)
index d2921c0..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/* vbetest.c - command to test VESA BIOS Extension 2.0+ support.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/normal.h>
-#include <grub/dl.h>
-#include <grub/env.h>
-#include <grub/misc.h>
-#include <grub/term.h>
-#include <grub/machine/init.h>
-#include <grub/machine/vbe.h>
-#include <grub/video.h>
-#include <grub/err.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-grub_cmd_vbetest (grub_command_t cmd __attribute__ ((unused)),
-                 int argc __attribute__ ((unused)),
-                 char **args __attribute__ ((unused)))
-{
-  grub_err_t err;
-  char *modevar;
-  struct grub_vbe_mode_info_block mode_info;
-  struct grub_vbe_info_block controller_info;
-  grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE;
-  grub_uint32_t old_mode;
-  grub_uint8_t *framebuffer = 0;
-  grub_uint32_t bytes_per_scan_line = 0;
-  unsigned char *ptr;
-  int i;
-
-  grub_printf ("Probing for VESA BIOS Extension ... ");
-
-  /* Check if VESA BIOS exists.  */
-  err = grub_vbe_probe (&controller_info);
-  if (err != GRUB_ERR_NONE)
-    return err;
-
-  grub_printf ("found!\n");
-
-  /* Dump out controller information.  */
-  grub_printf ("VBE signature = %c%c%c%c\n",
-              controller_info.signature[0],
-              controller_info.signature[1],
-              controller_info.signature[2],
-              controller_info.signature[3]);
-
-  grub_printf ("VBE version = %d.%d\n",
-              controller_info.version >> 8,
-              controller_info.version & 0xFF);
-  grub_printf ("OEM string ptr = %08x\n",
-              controller_info.oem_string_ptr);
-  grub_printf ("Total memory = %d\n",
-              controller_info.total_memory);
-
-  err = grub_vbe_get_video_mode (&old_mode);
-  grub_printf ("Get video mode err = %04x\n", err);
-
-  if (err == GRUB_ERR_NONE)
-    grub_printf ("Old video mode = %04x\n", old_mode);
-  else
-    grub_errno = GRUB_ERR_NONE;
-
-  /* Check existence of vbe_mode environment variable.  */
-  modevar = grub_env_get ("vbe_mode");
-  if (modevar != 0)
-    {
-      unsigned long value;
-
-      value = grub_strtoul (modevar, 0, 0);
-      if (grub_errno == GRUB_ERR_NONE)
-       use_mode = value;
-      else
-       grub_errno = GRUB_ERR_NONE;
-    }
-
-  err = grub_vbe_get_video_mode_info (use_mode, &mode_info);
-  if (err != GRUB_ERR_NONE)
-    return err;
-
-  /* Dump out details about the mode being tested.  */
-  grub_printf ("mode: 0x%03x\n",
-               use_mode);
-  grub_printf ("width : %d\n",
-               mode_info.x_resolution);
-  grub_printf ("height: %d\n",
-               mode_info.y_resolution);
-  grub_printf ("memory model: %02x\n",
-               mode_info.memory_model);
-  grub_printf ("bytes/scanline: %d\n",
-               mode_info.bytes_per_scan_line);
-  grub_printf ("bytes/scanline (lin): %d\n",
-               mode_info.lin_bytes_per_scan_line);
-  grub_printf ("base address: %08x\n",
-               mode_info.phys_base_addr);
-  grub_printf ("red mask/pos: %d/%d\n",
-               mode_info.red_mask_size,
-               mode_info.red_field_position);
-  grub_printf ("green mask/pos: %d/%d\n",
-               mode_info.green_mask_size,
-               mode_info.green_field_position);
-  grub_printf ("blue mask/pos: %d/%d\n",
-               mode_info.blue_mask_size,
-               mode_info.blue_field_position);
-
-  grub_printf ("Press any key to continue.\n");
-
-  grub_getkey ();
-
-  /* Setup GFX mode.  */
-  err = grub_vbe_set_video_mode (use_mode, &mode_info);
-  if (err != GRUB_ERR_NONE)
-    return err;
-
-  /* Determine framebuffer address and how many bytes are in scan line.  */
-  framebuffer = (grub_uint8_t *) mode_info.phys_base_addr;
-  ptr = framebuffer;
-
-  if (controller_info.version >= 0x300)
-    {
-      bytes_per_scan_line = mode_info.lin_bytes_per_scan_line;
-    }
-  else
-    {
-      bytes_per_scan_line = mode_info.bytes_per_scan_line;
-    }
-
-  /* Draw some random data to screen.  */
-  for (i = 0; i < 256 * 256; i++)
-    {
-      ptr[i] = i & 0x0F;
-    }
-
-  /* Draw white line to screen.  */
-  for (i = 0; i < 100; i++)
-    {
-      ptr[mode_info.bytes_per_scan_line * 50 + i] = 0x0F;
-    }
-
-  /* Draw another white line to screen.  */
-  grub_memset (ptr + bytes_per_scan_line * 51, 0x0f, bytes_per_scan_line);
-
-  grub_getkey ();
-
-  grub_video_restore ();
-
-  /* Restore old video mode.  */
-  grub_vbe_set_video_mode (old_mode, 0);
-
-  return grub_errno;
-}
-
-static grub_command_t cmd;
-
-GRUB_MOD_INIT(vbetest)
-{
-  cmd = grub_register_command ("vbetest", grub_cmd_vbetest,
-                              0, N_("Test VESA BIOS Extension 2.0+ support."));
-}
-
-GRUB_MOD_FINI(vbetest)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/ieee1275/suspend.c b/commands/ieee1275/suspend.c
deleted file mode 100644 (file)
index f096cc9..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/* suspend.c - command to suspend GRUB and return to Open Firmware  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/term.h>
-#include <grub/ieee1275/ieee1275.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-grub_cmd_suspend (grub_command_t cmd __attribute__ ((unused)),
-                 int argc __attribute__ ((unused)),
-                 char **args __attribute__ ((unused)))
-{
-  grub_printf ("Run 'go' to resume GRUB.\n");
-  grub_ieee1275_enter ();
-  grub_cls ();
-  return 0;
-}
-
-static grub_command_t cmd;
-\f
-GRUB_MOD_INIT(ieee1275_suspend)
-{
-  cmd = grub_register_command ("suspend", grub_cmd_suspend,
-                              0, N_("Return to Open Firmware prompt."));
-}
-
-GRUB_MOD_FINI(ieee1275_suspend)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/iorw.c b/commands/iorw.c
deleted file mode 100644 (file)
index 474c871..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/* memrw.c - command to read / write physical memory  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/extcmd.h>
-#include <grub/env.h>
-#include <grub/cpu/io.h>
-#include <grub/i18n.h>
-
-static grub_extcmd_t cmd_read_byte, cmd_read_word, cmd_read_dword;
-static grub_command_t cmd_write_byte, cmd_write_word, cmd_write_dword;
-
-static const struct grub_arg_option options[] =
-  {
-    {0, 'v', 0, N_("Save read value into variable VARNAME."),
-     N_("VARNAME"), ARG_TYPE_STRING},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-
-static grub_err_t
-grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
-{
-  grub_target_addr_t addr;
-  grub_uint32_t value = 0;
-  char buf[sizeof ("XXXXXXXX")];
-
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments");
-
-  addr = grub_strtoul (argv[0], 0, 0);
-  switch (cmd->cmd->name[sizeof ("in") - 1])
-    {
-    case 'l':
-      value = grub_inl (addr);
-      break;
-
-    case 'w':
-      value = grub_inw (addr);
-      break;
-
-    case 'b':
-      value = grub_inb (addr);
-      break;
-    }
-
-  if (cmd->state[0].set)
-    {
-      grub_snprintf (buf, sizeof (buf), "%x", value);
-      grub_env_set (cmd->state[0].arg, buf);
-    }
-  else
-    grub_printf ("0x%x\n", value);
-
-  return 0;
-}
-
-static grub_err_t
-grub_cmd_write (grub_command_t cmd, int argc, char **argv)
-{
-  grub_target_addr_t addr;
-  grub_uint32_t value;
-  grub_uint32_t mask = 0xffffffff;
-
-  if (argc != 2 && argc != 3)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments");
-
-  addr = grub_strtoul (argv[0], 0, 0);
-  value = grub_strtoul (argv[1], 0, 0);
-  if (argc == 3)
-    mask = grub_strtoul (argv[2], 0, 0);
-  value &= mask;
-  switch (cmd->name[sizeof ("out") - 1])
-    {
-    case 'l':
-      if (mask != 0xffffffff)
-       grub_outl ((grub_inl (addr) & ~mask) | value, addr);
-      else
-       grub_outl (value, addr);
-      break;
-
-    case 'w':
-      if ((mask & 0xffff) != 0xffff)
-       grub_outw ((grub_inw (addr) & ~mask) | value, addr);
-      else
-       grub_outw (value, addr);
-      break;
-
-    case 'b':
-      if ((mask & 0xff) != 0xff)
-       grub_outb ((grub_inb (addr) & ~mask) | value, addr);
-      else
-       grub_outb (value, addr);
-      break;
-    }
-
-  return 0;
-}
-
-GRUB_MOD_INIT(memrw)
-{
-  cmd_read_byte =
-    grub_register_extcmd ("inb", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
-                         N_("PORT"), N_("Read byte from PORT."), options);
-  cmd_read_word =
-    grub_register_extcmd ("inw", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
-                         N_("PORT"), N_("Read word from PORT."), options);
-  cmd_read_dword =
-    grub_register_extcmd ("inl", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
-                         N_("PORT"), N_("Read dword from PORT."), options);
-  cmd_write_byte =
-    grub_register_command ("outb", grub_cmd_write,
-                          N_("PORT VALUE [MASK]"),
-                          N_("Write byte VALUE to PORT."));
-  cmd_write_word =
-    grub_register_command ("outw", grub_cmd_write,
-                          N_("PORT VALUE [MASK]"),
-                          N_("Write word VALUE to PORT."));
-  cmd_write_dword =
-    grub_register_command ("outl", grub_cmd_write,
-                          N_("ADDR VALUE [MASK]"),
-                          N_("Write dword VALUE to PORT."));
-}
-
-GRUB_MOD_FINI(memrw)
-{
-  grub_unregister_extcmd (cmd_read_byte);
-  grub_unregister_extcmd (cmd_read_word);
-  grub_unregister_extcmd (cmd_read_dword);
-  grub_unregister_command (cmd_write_byte);
-  grub_unregister_command (cmd_write_word);
-  grub_unregister_command (cmd_write_dword);
-}
diff --git a/commands/keystatus.c b/commands/keystatus.c
deleted file mode 100644 (file)
index 8387928..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/* keystatus.c - Command to check key modifier status.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/extcmd.h>
-#include <grub/term.h>
-#include <grub/i18n.h>
-
-static const struct grub_arg_option options[] =
-  {
-    {"shift", 's', 0, N_("Check Shift key."), 0, 0},
-    {"ctrl", 'c', 0, N_("Check Control key."), 0, 0},
-    {"alt", 'a', 0, N_("Check Alt key."), 0, 0},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-#define grub_cur_term_input    grub_term_get_current_input ()
-
-static grub_err_t
-grub_cmd_keystatus (grub_extcmd_t cmd,
-                   int argc __attribute__ ((unused)),
-                   char **args __attribute__ ((unused)))
-{
-  struct grub_arg_list *state = cmd->state;
-  int expect_mods = 0;
-  int mods;
-
-  if (state[0].set)
-    expect_mods |= GRUB_TERM_STATUS_SHIFT;
-  if (state[1].set)
-    expect_mods |= GRUB_TERM_STATUS_CTRL;
-  if (state[2].set)
-    expect_mods |= GRUB_TERM_STATUS_ALT;
-
-  grub_dprintf ("keystatus", "expect_mods: %d\n", expect_mods);
-
-  /* Without arguments, just check whether getkeystatus is supported at
-     all.  */
-  if (expect_mods == 0)
-    {
-      grub_term_input_t term;
-      int nterms = 0;
-
-      FOR_ACTIVE_TERM_INPUTS (term)
-       if (!term->getkeystatus)
-         return grub_error (GRUB_ERR_TEST_FAILURE, "false");
-       else
-         nterms++;
-      if (!nterms)
-       return grub_error (GRUB_ERR_TEST_FAILURE, "false");
-      return 0;
-    }
-
-  mods = grub_getkeystatus ();
-  grub_dprintf ("keystatus", "mods: %d\n", mods);
-  if (mods >= 0 && (mods & expect_mods) != 0)
-    return 0;
-  else
-    return grub_error (GRUB_ERR_TEST_FAILURE, "false");
-}
-
-static grub_extcmd_t cmd;
-\f
-GRUB_MOD_INIT(keystatus)
-{
-  cmd = grub_register_extcmd ("keystatus", grub_cmd_keystatus,
-                             GRUB_COMMAND_FLAG_BOTH,
-                             N_("[--shift] [--ctrl] [--alt]"),
-                             N_("Check key modifier status."),
-                             options);
-}
-
-GRUB_MOD_FINI(keystatus)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/commands/loadenv.c b/commands/loadenv.c
deleted file mode 100644 (file)
index d763b2d..0000000
+++ /dev/null
@@ -1,400 +0,0 @@
-/* loadenv.c - command to load/save environment variable.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/file.h>
-#include <grub/disk.h>
-#include <grub/misc.h>
-#include <grub/env.h>
-#include <grub/partition.h>
-#include <grub/lib/envblk.h>
-#include <grub/extcmd.h>
-#include <grub/i18n.h>
-
-static const struct grub_arg_option options[] =
-  {
-    {"file", 'f', 0, N_("Specify filename."), 0, ARG_TYPE_PATHNAME},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-static grub_file_t
-open_envblk_file (char *filename)
-{
-  grub_file_t file;
-
-  if (! filename)
-    {
-      char *prefix;
-
-      prefix = grub_env_get ("prefix");
-      if (prefix)
-        {
-          int len;
-
-          len = grub_strlen (prefix);
-          filename = grub_malloc (len + 1 + sizeof (GRUB_ENVBLK_DEFCFG));
-          if (! filename)
-            return 0;
-
-          grub_strcpy (filename, prefix);
-          filename[len] = '/';
-          grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG);
-          file = grub_file_open (filename);
-          grub_free (filename);
-          return file;
-        }
-      else
-        {
-          grub_error (GRUB_ERR_FILE_NOT_FOUND, "prefix is not found");
-          return 0;
-        }
-    }
-
-  return grub_file_open (filename);
-}
-
-static grub_envblk_t
-read_envblk_file (grub_file_t file)
-{
-  grub_off_t offset = 0;
-  char *buf;
-  grub_size_t size = grub_file_size (file);
-  grub_envblk_t envblk;
-
-  buf = grub_malloc (size);
-  if (! buf)
-    return 0;
-
-  while (size > 0)
-    {
-      grub_ssize_t ret;
-
-      ret = grub_file_read (file, buf + offset, size);
-      if (ret <= 0)
-        {
-          if (grub_errno == GRUB_ERR_NONE)
-            grub_error (GRUB_ERR_FILE_READ_ERROR, "cannot read");
-          grub_free (buf);
-          return 0;
-        }
-
-      size -= ret;
-      offset += ret;
-    }
-
-  envblk = grub_envblk_open (buf, offset);
-  if (! envblk)
-    {
-      grub_free (buf);
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block");
-      return 0;
-    }
-
-  return envblk;
-}
-
-static grub_err_t
-grub_cmd_load_env (grub_extcmd_t cmd,
-                  int argc __attribute__ ((unused)),
-                  char **args __attribute__ ((unused)))
-{
-  struct grub_arg_list *state = cmd->state;
-  grub_file_t file;
-  grub_envblk_t envblk;
-
-  auto int set_var (const char *name, const char *value);
-  int set_var (const char *name, const char *value)
-  {
-    grub_env_set (name, value);
-    return 0;
-  }
-
-  file = open_envblk_file ((state[0].set) ? state[0].arg : 0);
-  if (! file)
-    return grub_errno;
-
-  envblk = read_envblk_file (file);
-  if (! envblk)
-    goto fail;
-
-  grub_envblk_iterate (envblk, set_var);
-  grub_envblk_close (envblk);
-
- fail:
-  grub_file_close (file);
-  return grub_errno;
-}
-
-static grub_err_t
-grub_cmd_list_env (grub_extcmd_t cmd,
-                  int argc __attribute__ ((unused)),
-                  char **args __attribute__ ((unused)))
-{
-  struct grub_arg_list *state = cmd->state;
-  grub_file_t file;
-  grub_envblk_t envblk;
-
-  /* Print all variables in current context.  */
-  auto int print_var (const char *name, const char *value);
-  int print_var (const char *name, const char *value)
-    {
-      grub_printf ("%s=%s\n", name, value);
-      return 0;
-    }
-
-  file = open_envblk_file ((state[0].set) ? state[0].arg : 0);
-  if (! file)
-    return grub_errno;
-
-  envblk = read_envblk_file (file);
-  if (! envblk)
-    goto fail;
-
-  grub_envblk_iterate (envblk, print_var);
-  grub_envblk_close (envblk);
-
- fail:
-  grub_file_close (file);
-  return grub_errno;
-}
-
-/* Used to maintain a variable length of blocklists internally.  */
-struct blocklist
-{
-  grub_disk_addr_t sector;
-  unsigned offset;
-  unsigned length;
-  struct blocklist *next;
-};
-
-static void
-free_blocklists (struct blocklist *p)
-{
-  struct blocklist *q;
-
-  for (; p; p = q)
-    {
-      q = p->next;
-      grub_free (p);
-    }
-}
-
-static grub_err_t
-check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists,
-                  grub_file_t file)
-{
-  grub_size_t total_length;
-  grub_size_t index;
-  grub_disk_t disk;
-  grub_disk_addr_t part_start;
-  struct blocklist *p;
-  char *buf;
-
-  /* Sanity checks.  */
-  total_length = 0;
-  for (p = blocklists; p; p = p->next)
-    {
-      struct blocklist *q;
-      for (q = p->next; q; q = q->next)
-        {
-          /* Check if any pair of blocks overlap.  */
-          if (p->sector == q->sector)
-            {
-              /* This might be actually valid, but it is unbelievable that
-                 any filesystem makes such a silly allocation.  */
-              return grub_error (GRUB_ERR_BAD_FS, "malformed file");
-            }
-        }
-
-      total_length += p->length;
-    }
-
-  if (total_length != grub_file_size (file))
-    {
-      /* Maybe sparse, unallocated sectors. No way in GRUB.  */
-      return grub_error (GRUB_ERR_BAD_FILE_TYPE, "sparse file not allowed");
-    }
-
-  /* One more sanity check. Re-read all sectors by blocklists, and compare
-     those with the data read via a file.  */
-  disk = file->device->disk;
-
-  part_start = grub_partition_get_start (disk->partition);
-
-  buf = grub_envblk_buffer (envblk);
-  for (p = blocklists, index = 0; p; index += p->length, p = p->next)
-    {
-      char blockbuf[GRUB_DISK_SECTOR_SIZE];
-
-      if (grub_disk_read (disk, p->sector - part_start,
-                          p->offset, p->length, blockbuf))
-        return grub_errno;
-
-      if (grub_memcmp (buf + index, blockbuf, p->length) != 0)
-       return grub_error (GRUB_ERR_FILE_READ_ERROR, "invalid blocklist");
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-static int
-write_blocklists (grub_envblk_t envblk, struct blocklist *blocklists,
-                  grub_file_t file)
-{
-  char *buf;
-  grub_disk_t disk;
-  grub_disk_addr_t part_start;
-  struct blocklist *p;
-  grub_size_t index;
-
-  buf = grub_envblk_buffer (envblk);
-  disk = file->device->disk;
-  part_start = grub_partition_get_start (disk->partition);
-
-  index = 0;
-  for (p = blocklists; p; index += p->length, p = p->next)
-    {
-      if (grub_disk_write (disk, p->sector - part_start,
-                           p->offset, p->length, buf + index))
-        return 0;
-    }
-
-  return 1;
-}
-
-static grub_err_t
-grub_cmd_save_env (grub_extcmd_t cmd, int argc, char **args)
-{
-  struct grub_arg_list *state = cmd->state;
-  grub_file_t file;
-  grub_envblk_t envblk;
-  struct blocklist *head = 0;
-  struct blocklist *tail = 0;
-
-  /* Store blocklists in a linked list.  */
-  auto void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector,
-                                        unsigned offset,
-                                        unsigned length);
-  void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector,
-                                   unsigned offset, unsigned length)
-    {
-      struct blocklist *block;
-
-      if (offset + length > GRUB_DISK_SECTOR_SIZE)
-        /* Seemingly a bug.  */
-        return;
-
-      block = grub_malloc (sizeof (*block));
-      if (! block)
-        return;
-
-      block->sector = sector;
-      block->offset = offset;
-      block->length = length;
-
-      /* Slightly complicated, because the list should be FIFO.  */
-      block->next = 0;
-      if (tail)
-        tail->next = block;
-      tail = block;
-      if (! head)
-        head = block;
-    }
-
-  if (! argc)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no variable is specified");
-
-  file = open_envblk_file ((state[0].set) ? state[0].arg : 0);
-  if (! file)
-    return grub_errno;
-
-  if (! file->device->disk)
-    {
-      grub_file_close (file);
-      return grub_error (GRUB_ERR_BAD_DEVICE, "disk device required");
-    }
-
-  file->read_hook = read_hook;
-  envblk = read_envblk_file (file);
-  file->read_hook = 0;
-  if (! envblk)
-    goto fail;
-
-  if (check_blocklists (envblk, head, file))
-    goto fail;
-
-  while (argc)
-    {
-      char *value;
-
-      value = grub_env_get (args[0]);
-      if (value)
-        {
-          if (! grub_envblk_set (envblk, args[0], value))
-            {
-              grub_error (GRUB_ERR_BAD_ARGUMENT, "environment block too small");
-              goto fail;
-            }
-        }
-
-      argc--;
-      args++;
-    }
-
-  write_blocklists (envblk, head, file);
-
- fail:
-  if (envblk)
-    grub_envblk_close (envblk);
-  free_blocklists (head);
-  grub_file_close (file);
-  return grub_errno;
-}
-
-static grub_extcmd_t cmd_load, cmd_list, cmd_save;
-
-GRUB_MOD_INIT(loadenv)
-{
-  cmd_load =
-    grub_register_extcmd ("load_env", grub_cmd_load_env,
-                         GRUB_COMMAND_FLAG_BOTH,
-                         N_("[-f FILE]"),
-                         N_("Load variables from environment block file."),
-                         options);
-  cmd_list =
-    grub_register_extcmd ("list_env", grub_cmd_list_env,
-                         GRUB_COMMAND_FLAG_BOTH,
-                         N_("[-f FILE]"),
-                         N_("List variables from environment block file."),
-                         options);
-  cmd_save =
-    grub_register_extcmd ("save_env", grub_cmd_save_env,
-                         GRUB_COMMAND_FLAG_BOTH,
-                         N_("[-f FILE] variable_name [...]"),
-                         N_("Save variables to environment block file."),
-                         options);
-}
-
-GRUB_MOD_FINI(loadenv)
-{
-  grub_unregister_extcmd (cmd_load);
-  grub_unregister_extcmd (cmd_list);
-  grub_unregister_extcmd (cmd_save);
-}
diff --git a/commands/ls.c b/commands/ls.c
deleted file mode 100644 (file)
index eb10496..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/* ls.c - command to list files and devices */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/disk.h>
-#include <grub/device.h>
-#include <grub/term.h>
-#include <grub/partition.h>
-#include <grub/file.h>
-#include <grub/normal.h>
-#include <grub/extcmd.h>
-#include <grub/datetime.h>
-#include <grub/i18n.h>
-
-static const struct grub_arg_option options[] =
-  {
-    {"long", 'l', 0, N_("Show a long list with more detailed information."), 0, 0},
-    {"human-readable", 'h', 0, N_("Print sizes in a human readable format."), 0, 0},
-    {"all", 'a', 0, N_("List all files."), 0, 0},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-static const char grub_human_sizes[] = {' ', 'K', 'M', 'G', 'T'};
-
-static grub_err_t
-grub_ls_list_devices (int longlist)
-{
-  auto int grub_ls_print_devices (const char *name);
-  int grub_ls_print_devices (const char *name)
-    {
-      if (longlist)
-       grub_normal_print_device_info (name);
-      else
-       grub_printf ("(%s) ", name);
-
-      return 0;
-    }
-
-  grub_device_iterate (grub_ls_print_devices);
-  grub_putchar ('\n');
-  grub_refresh ();
-
-  return 0;
-}
-
-static grub_err_t
-grub_ls_list_files (char *dirname, int longlist, int all, int human)
-{
-  char *device_name;
-  grub_fs_t fs;
-  const char *path;
-  grub_device_t dev;
-
-  auto int print_files (const char *filename,
-                       const struct grub_dirhook_info *info);
-  auto int print_files_long (const char *filename,
-                            const struct grub_dirhook_info *info);
-
-  int print_files (const char *filename, const struct grub_dirhook_info *info)
-    {
-      if (all || filename[0] != '.')
-       grub_printf ("%s%s ", filename, info->dir ? "/" : "");
-
-      return 0;
-    }
-
-  int print_files_long (const char *filename,
-                       const struct grub_dirhook_info *info)
-    {
-      if ((! all) && (filename[0] == '.'))
-       return 0;
-
-      if (! info->dir)
-       {
-         grub_file_t file;
-         char *pathname;
-
-         if (dirname[grub_strlen (dirname) - 1] == '/')
-           pathname = grub_xasprintf ("%s%s", dirname, filename);
-         else
-           pathname = grub_xasprintf ("%s/%s", dirname, filename);
-
-         if (!pathname)
-           return 1;
-
-         /* XXX: For ext2fs symlinks are detected as files while they
-            should be reported as directories.  */
-         file = grub_file_open (pathname);
-         if (! file)
-           {
-             grub_errno = 0;
-             grub_free (pathname);
-             return 0;
-           }
-
-         if (! human)
-           grub_printf ("%-12llu", (unsigned long long) file->size);
-         else
-           {
-             grub_uint64_t fsize = file->size * 100ULL;
-             int fsz = file->size;
-             int units = 0;
-             char buf[20];
-
-             while (fsz / 1024)
-               {
-                 fsize = (fsize + 512) / 1024;
-                 fsz /= 1024;
-                 units++;
-               }
-
-             if (units)
-               {
-                 grub_uint32_t whole, fraction;
-
-                 whole = grub_divmod64 (fsize, 100, &fraction);
-                 grub_snprintf (buf, sizeof (buf),
-                                "%u.%02u%c", whole, fraction,
-                                grub_human_sizes[units]);
-                 grub_printf ("%-12s", buf);
-               }
-             else
-               grub_printf ("%-12llu", (unsigned long long) file->size);
-
-           }
-         grub_file_close (file);
-         grub_free (pathname);
-       }
-      else
-       grub_printf ("%-12s", "DIR");
-
-      if (info->mtimeset)
-       {
-         struct grub_datetime datetime;
-         grub_unixtime2datetime (info->mtime, &datetime);
-         if (human)
-           grub_printf (" %d-%02d-%02d %02d:%02d:%02d %-11s ",
-                        datetime.year, datetime.month, datetime.day,
-                        datetime.hour, datetime.minute,
-                        datetime.second,
-                        grub_get_weekday_name (&datetime));
-         else
-           grub_printf (" %04d%02d%02d%02d%02d%02d ",
-                        datetime.year, datetime.month,
-                        datetime.day, datetime.hour,
-                        datetime.minute, datetime.second);
-       }
-      grub_printf ("%s%s\n", filename, info->dir ? "/" : "");
-
-      return 0;
-    }
-
-  device_name = grub_file_get_device_name (dirname);
-  dev = grub_device_open (device_name);
-  if (! dev)
-    goto fail;
-
-  fs = grub_fs_probe (dev);
-  path = grub_strchr (dirname, ')');
-  if (! path)
-    path = dirname;
-  else
-    path++;
-
-  if (! path && ! device_name)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
-      goto fail;
-    }
-
-  if (! *path)
-    {
-      if (grub_errno == GRUB_ERR_UNKNOWN_FS)
-       grub_errno = GRUB_ERR_NONE;
-
-      grub_normal_print_device_info (device_name);
-    }
-  else if (fs)
-    {
-      if (longlist)
-       (fs->dir) (dev, path, print_files_long);
-      else
-       (fs->dir) (dev, path, print_files);
-
-      if (grub_errno == GRUB_ERR_BAD_FILE_TYPE
-         && path[grub_strlen (path) - 1] != '/')
-       {
-         /* PATH might be a regular file.  */
-         char *p;
-         grub_file_t file;
-         struct grub_dirhook_info info;
-         grub_errno = 0;
-
-         file = grub_file_open (dirname);
-         if (! file)
-           goto fail;
-
-         grub_file_close (file);
-
-         p = grub_strrchr (dirname, '/') + 1;
-         dirname = grub_strndup (dirname, p - dirname);
-         if (! dirname)
-           goto fail;
-
-         all = 1;
-         grub_memset (&info, 0, sizeof (info));
-         if (longlist)
-           print_files_long (p, &info);
-         else
-           print_files (p, &info);
-
-         grub_free (dirname);
-       }
-
-      if (grub_errno == GRUB_ERR_NONE)
-       grub_putchar ('\n');
-
-      grub_refresh ();
-    }
-
- fail:
-  if (dev)
-    grub_device_close (dev);
-
-  grub_free (device_name);
-
-  return 0;
-}
-
-static grub_err_t
-grub_cmd_ls (grub_extcmd_t cmd, int argc, char **args)
-{
-  struct grub_arg_list *state = cmd->state;
-
-  if (argc == 0)
-    grub_ls_list_devices (state[0].set);
-  else
-    grub_ls_list_files (args[0], state[0].set, state[2].set,
-                       state[1].set);
-
-  return 0;
-}
-
-static grub_extcmd_t cmd;
-
-GRUB_MOD_INIT(ls)
-{
-  cmd = grub_register_extcmd ("ls", grub_cmd_ls, GRUB_COMMAND_FLAG_BOTH,
-                             N_("[-l|-h|-a] [FILE]"),
-                             N_("List devices and files."), options);
-}
-
-GRUB_MOD_FINI(ls)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/commands/lsmmap.c b/commands/lsmmap.c
deleted file mode 100644 (file)
index 2755df9..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MACHINE_EMU
-#include <grub/machine/memory.h>
-#endif
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-grub_cmd_lsmmap (grub_command_t cmd __attribute__ ((unused)),
-                int argc __attribute__ ((unused)), char **args __attribute__ ((unused)))
-
-{
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
-    {
-      grub_printf ("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n",
-                  (long long) addr, (long long) size, type);
-      return 0;
-    }
-#ifndef GRUB_MACHINE_EMU
-  grub_machine_mmap_iterate (hook);
-#endif
-
-  return 0;
-}
-
-static grub_command_t cmd;
-\f
-GRUB_MOD_INIT(lsmmap)
-{
-  cmd = grub_register_command ("lsmmap", grub_cmd_lsmmap,
-                              0, N_("List memory map provided by firmware."));
-}
-
-GRUB_MOD_FINI(lsmmap)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/lspci.c b/commands/lspci.c
deleted file mode 100644 (file)
index a69bb35..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-/* lspci.c - List PCI devices.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/pci.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/extcmd.h>
-#include <grub/i18n.h>
-
-struct grub_pci_classname
-{
-  int class;
-  int subclass;
-  char *desc;
-};
-
-static const struct grub_pci_classname grub_pci_classes[] =
-  {
-    { 0, 0, "" },
-    { 1, 0, "SCSI Controller" },
-    { 1, 1, "IDE Controller" },
-    { 1, 2, "Floppy Controller" },
-    { 1, 3, "IPI Controller" },
-    { 1, 4, "RAID Controller" },
-    { 1, 6, "SATA Controller" },
-    { 1, 0x80, "Mass storage Controller" },
-    { 2, 0, "Ethernet Controller" },
-    { 2, 1, "Token Ring Controller" },
-    { 2, 2, "FDDI Controller" },
-    { 2, 3, "ATM Controller" },
-    { 2, 4, "ISDN Controller" },
-    { 2, 0x80, "Network controller" },
-    { 3, 0, "VGA Controller" },
-    { 3, 1, "XGA Controller" },
-    { 3, 2, "3D Controller" },
-    { 3, 0x80, "Display Controller" },
-    { 4, 0, "Multimedia Video Device" },
-    { 4, 1, "Multimedia Audio Device" },
-    { 4, 2, "Multimedia Telephony Device" },
-    { 4, 0x80, "Multimedia device" },
-    { 5, 0, "RAM Controller" },
-    { 5, 1, "Flash Memory Controller" },
-    { 5, 0x80, "Memory Controller" },
-    { 6, 0, "Host Bridge" },
-    { 6, 1, "ISA Bridge" },
-    { 6, 2, "EISA Bride" },
-    { 6, 3, "MCA Bridge" },
-    { 6, 4, "PCI-PCI Bridge" },
-    { 6, 5, "PCMCIA Bridge" },
-    { 6, 6, "NuBus Bridge" },
-    { 6, 7, "CardBus Bridge" },
-    { 6, 8, "Raceway Bridge" },
-    { 6, 0x80, "Unknown Bridge" },
-    { 7, 0x80, "Communication controller" },
-    { 8, 0x80, "System hardware" },
-    { 9, 0, "Keyboard Controller" },
-    { 9, 1, "Digitizer" },
-    { 9, 2, "Mouse Controller" },
-    { 9, 3, "Scanner Controller" },
-    { 9, 4, "Gameport Controller" },
-    { 9, 0x80, "Unknown Input Device" },
-    { 10, 0, "Generic Docking Station" },
-    { 10, 0x80, "Unknown Docking Station" },
-    { 11, 0, "80386 Processor" },
-    { 11, 1, "80486 Processor" },
-    { 11, 2, "Pentium Processor" },
-    { 11, 0x10, "Alpha Processor" },
-    { 11, 0x20, "PowerPC Processor" },
-    { 11, 0x30, "MIPS Processor" },
-    { 11, 0x40, "Co-Processor" },
-    { 11, 0x80, "Unknown Processor" },
-    { 12, 3, "USB Controller" },
-    { 12, 0x80, "Serial Bus Controller" },
-    { 13, 0x80, "Wireless Controller" },
-    { 14, 0, "I2O" },
-    { 15, 0, "IrDA Controller" },
-    { 15, 1, "Consumer IR" },
-    { 15, 0x10, "RF-Controller" },
-    { 15, 0x80, "Satellite Communication Controller" },
-    { 16, 0, "Network Decryption" },
-    { 16, 1, "Entertainment Decryption" },
-    { 16, 0x80, "Unknown Decryption Controller" },
-    { 17, 0, "Digital IO Module" },
-    { 17, 0x80, "Unknown Data Input System" },
-    { 0, 0, 0 },
-  };
-
-static const char *
-grub_pci_get_class (int class, int subclass)
-{
-  const struct grub_pci_classname *curr = grub_pci_classes;
-
-  while (curr->desc)
-    {
-      if (curr->class == class && curr->subclass == subclass)
-       return curr->desc;
-      curr++;
-    }
-
-  return 0;
-}
-
-static const struct grub_arg_option options[] =
-  {
-    {"iospace", 'i', 0, "show I/O spaces", 0, 0},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-static int iospace;
-
-static int NESTED_FUNC_ATTR
-grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid)
-{
-  grub_uint32_t class;
-  const char *sclass;
-  grub_pci_address_t addr;
-  int reg;
-
-  grub_printf ("%02x:%02x.%x %04x:%04x", grub_pci_get_bus (dev),
-              grub_pci_get_device (dev), grub_pci_get_function (dev),
-              pciid & 0xFFFF, pciid >> 16);
-  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
-  class = grub_pci_read (addr);
-
-  /* Lookup the class name, if there isn't a specific one,
-     retry with 0x80 to get the generic class name.  */
-  sclass = grub_pci_get_class (class >> 24, (class >> 16) & 0xFF);
-  if (! sclass)
-    sclass = grub_pci_get_class (class >> 24, 0x80);
-  if (! sclass)
-    sclass = "";
-
-  grub_printf (" [%04x] %s", (class >> 16) & 0xffff, sclass);
-
-  grub_uint8_t pi = (class >> 8) & 0xff;
-  if (pi)
-    grub_printf (" [PI %02x]", pi);
-
-  grub_printf ("\n");
-
-  if (iospace)
-    {
-      reg = GRUB_PCI_REG_ADDRESSES;
-      while (reg < GRUB_PCI_REG_CIS_POINTER)
-       {
-         grub_uint64_t space;
-         addr = grub_pci_make_address (dev, reg);
-         space = grub_pci_read (addr);
-
-         reg += sizeof (grub_uint32_t);
-
-         if (space == 0)
-           continue;
-        
-         switch (space & GRUB_PCI_ADDR_SPACE_MASK)
-           {
-           case GRUB_PCI_ADDR_SPACE_IO:
-             grub_printf ("\tIO space %d at 0x%llx\n",
-                          (unsigned) ((reg - GRUB_PCI_REG_ADDRESSES)
-                           / sizeof (grub_uint32_t)) - 1,
-                          (unsigned long long)
-                          (space & GRUB_PCI_ADDR_IO_MASK));
-             break;
-           case GRUB_PCI_ADDR_SPACE_MEMORY:
-             if ((space & GRUB_PCI_ADDR_MEM_TYPE_MASK)
-                 == GRUB_PCI_ADDR_MEM_TYPE_64)
-               {
-                 addr = grub_pci_make_address (dev, reg);
-                 space |= ((grub_uint64_t) grub_pci_read (addr)) << 32;
-                 reg += sizeof (grub_uint32_t);
-                 grub_printf ("\t64-bit memory space %d at 0x%016llx [%s]\n",
-                              (unsigned) ((reg - GRUB_PCI_REG_ADDRESSES)
-                               / sizeof (grub_uint32_t)) - 2,
-                              (unsigned long long)
-                              (space & GRUB_PCI_ADDR_MEM_MASK),
-                              space & GRUB_PCI_ADDR_MEM_PREFETCH
-                              ? "prefetchable" : "non-prefetchable");
-                
-               }
-             else
-               grub_printf ("\t32-bit memory space %d at 0x%016llx [%s]\n",
-                            (unsigned) ((reg - GRUB_PCI_REG_ADDRESSES)
-                             / sizeof (grub_uint32_t)) - 1,
-                            (unsigned long long) 
-                            (space & GRUB_PCI_ADDR_MEM_MASK),
-                            space & GRUB_PCI_ADDR_MEM_PREFETCH
-                            ? "prefetchable" : "non-prefetchable");
-             break;
-           }
-       }
-    }
-
-
-  return 0;
-}
-
-static grub_err_t
-grub_cmd_lspci (grub_extcmd_t cmd,
-               int argc __attribute__ ((unused)),
-               char **args __attribute__ ((unused)))
-{
-  iospace = cmd->state[0].set;
-  grub_pci_iterate (grub_lspci_iter);
-  return GRUB_ERR_NONE;
-}
-
-static grub_extcmd_t cmd;
-
-GRUB_MOD_INIT(lspci)
-{
-  cmd = grub_register_extcmd ("lspci", grub_cmd_lspci, GRUB_COMMAND_FLAG_BOTH,
-                             "[-i]", N_("List PCI devices."), options);
-}
-
-GRUB_MOD_FINI(lspci)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/commands/memrw.c b/commands/memrw.c
deleted file mode 100644 (file)
index 6a4d43b..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/* memrw.c - command to read / write physical memory  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/extcmd.h>
-#include <grub/env.h>
-#include <grub/i18n.h>
-
-static grub_extcmd_t cmd_read_byte, cmd_read_word, cmd_read_dword;
-static grub_command_t cmd_write_byte, cmd_write_word, cmd_write_dword;
-
-static const struct grub_arg_option options[] =
-  {
-    {0, 'v', 0, N_("Save read value into variable VARNAME."),
-     "VARNAME", ARG_TYPE_STRING},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-
-static grub_err_t
-grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
-{
-  grub_target_addr_t addr;
-  grub_uint32_t value = 0;
-  char buf[sizeof ("XXXXXXXX")];
-
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid number of arguments");
-
-  addr = grub_strtoul (argv[0], 0, 0);
-  switch (cmd->cmd->name[sizeof ("read_") - 1])
-    {
-    case 'd':
-      value = *((volatile grub_uint32_t *) addr);
-      break;
-
-    case 'w':
-      value = *((volatile grub_uint16_t *) addr);
-      break;
-
-    case 'b':
-      value = *((volatile grub_uint8_t *) addr);
-      break;
-    }
-
-  if (cmd->state[0].set)
-    {
-      grub_snprintf (buf, sizeof (buf), "%x", value);
-      grub_env_set (cmd->state[0].arg, buf);
-    }
-  else
-    grub_printf ("0x%x\n", value);
-
-  return 0;
-}
-
-static grub_err_t
-grub_cmd_write (grub_command_t cmd, int argc, char **argv)
-{
-  grub_target_addr_t addr;
-  grub_uint32_t value;
-  grub_uint32_t mask = 0xffffffff;
-
-  if (argc != 2 && argc != 3)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid number of arguments");
-
-  addr = grub_strtoul (argv[0], 0, 0);
-  value = grub_strtoul (argv[1], 0, 0);
-  if (argc == 3)
-    mask = grub_strtoul (argv[2], 0, 0);
-  value &= mask;
-  switch (cmd->name[sizeof ("write_") - 1])
-    {
-    case 'd':
-      if (mask != 0xffffffff)
-       *((volatile grub_uint32_t *) addr)
-         = (*((volatile grub_uint32_t *) addr) & ~mask) | value;
-      else
-       *((volatile grub_uint32_t *) addr) = value;
-      break;
-
-    case 'w':
-      if ((mask & 0xffff) != 0xffff)
-       *((volatile grub_uint16_t *) addr)
-         = (*((volatile grub_uint16_t *) addr) & ~mask) | value;
-      else
-       *((volatile grub_uint16_t *) addr) = value;
-      break;
-
-    case 'b':
-      if ((mask & 0xff) != 0xff)
-       *((volatile grub_uint8_t *) addr)
-         = (*((volatile grub_uint8_t *) addr) & ~mask) | value;
-      else
-       *((volatile grub_uint8_t *) addr) = value;
-      break;
-    }
-
-  return 0;
-}
-
-GRUB_MOD_INIT(memrw)
-{
-  cmd_read_byte =
-    grub_register_extcmd ("read_byte", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
-                         N_("ADDR"), N_("Read byte from ADDR."), options);
-  cmd_read_word =
-    grub_register_extcmd ("read_word", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
-                         N_("ADDR"), N_("Read word from ADDR."), options);
-  cmd_read_dword =
-    grub_register_extcmd ("read_dword", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
-                         N_("ADDR"), N_("Read dword from ADDR."), options);
-  cmd_write_byte =
-    grub_register_command ("write_byte", grub_cmd_write,
-                          N_("ADDR VALUE [MASK]"), N_("Write byte VALUE to ADDR."));
-  cmd_write_word =
-    grub_register_command ("write_word", grub_cmd_write,
-                          N_("ADDR VALUE [MASK]"), N_("Write word VALUE to ADDR."));
-  cmd_write_dword =
-    grub_register_command ("write_dword", grub_cmd_write,
-                          N_("ADDR VALUE [MASK]"), N_("Write dword VALUE to ADDR."));
-}
-
-GRUB_MOD_FINI(memrw)
-{
-  grub_unregister_extcmd (cmd_read_byte);
-  grub_unregister_extcmd (cmd_read_word);
-  grub_unregister_extcmd (cmd_read_dword);
-  grub_unregister_command (cmd_write_byte);
-  grub_unregister_command (cmd_write_word);
-  grub_unregister_command (cmd_write_dword);
-}
diff --git a/commands/minicmd.c b/commands/minicmd.c
deleted file mode 100644 (file)
index 4ea9efe..0000000
+++ /dev/null
@@ -1,391 +0,0 @@
-/* minicmd.c - commands for the rescue mode */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2005,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/env.h>
-#include <grub/misc.h>
-#include <grub/file.h>
-#include <grub/disk.h>
-#include <grub/term.h>
-#include <grub/loader.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-/* cat FILE */
-static grub_err_t
-grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)),
-                  int argc, char *argv[])
-{
-  grub_file_t file;
-  char buf[GRUB_DISK_SECTOR_SIZE];
-  grub_ssize_t size;
-
-  if (argc < 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
-
-  file = grub_file_open (argv[0]);
-  if (! file)
-    return grub_errno;
-
-  while ((size = grub_file_read (file, buf, sizeof (buf))) > 0)
-    {
-      int i;
-
-      for (i = 0; i < size; i++)
-       {
-         unsigned char c = buf[i];
-
-         if ((grub_isprint (c) || grub_isspace (c)) && c != '\r')
-           grub_putchar (c);
-         else
-           {
-             grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
-             grub_printf ("<%x>", (int) c);
-             grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
-           }
-       }
-    }
-
-  grub_putchar ('\n');
-  grub_refresh ();
-  grub_file_close (file);
-
-  return 0;
-}
-
-/* help */
-static grub_err_t
-grub_mini_cmd_help (struct grub_command *cmd __attribute__ ((unused)),
-                   int argc __attribute__ ((unused)),
-                   char *argv[] __attribute__ ((unused)))
-{
-  grub_command_t p;
-
-  for (p = grub_command_list; p; p = p->next)
-    grub_printf ("%s (%d%c)\t%s\n", p->name,
-                p->prio & GRUB_PRIO_LIST_PRIO_MASK,
-                (p->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) ? '+' : '-',
-                p->description);
-
-  return 0;
-}
-
-#if 0
-static void
-grub_rescue_cmd_info (void)
-{
-  extern void grub_disk_cache_get_performance (unsigned long *,
-                                              unsigned long *);
-  unsigned long hits, misses;
-
-  grub_disk_cache_get_performance (&hits, &misses);
-  grub_printf ("Disk cache: hits = %u, misses = %u ", hits, misses);
-  if (hits + misses)
-    {
-      unsigned long ratio = hits * 10000 / (hits + misses);
-      grub_printf ("(%u.%u%%)\n", ratio / 100, ratio % 100);
-    }
-  else
-    grub_printf ("(N/A)\n");
-}
-#endif
-
-/* root [DEVICE] */
-static grub_err_t
-grub_mini_cmd_root (struct grub_command *cmd __attribute__ ((unused)),
-                   int argc, char *argv[])
-{
-  grub_device_t dev;
-  grub_fs_t fs;
-
-  if (argc > 0)
-    {
-      char *device_name = grub_file_get_device_name (argv[0]);
-      if (! device_name)
-       return grub_errno;
-
-      grub_env_set ("root", device_name);
-      grub_free (device_name);
-    }
-
-  dev = grub_device_open (0);
-  if (! dev)
-    return grub_errno;
-
-  fs = grub_fs_probe (dev);
-  if (grub_errno == GRUB_ERR_UNKNOWN_FS)
-    grub_errno = GRUB_ERR_NONE;
-
-  grub_printf ("(%s): Filesystem is %s.\n",
-              grub_env_get ("root"), fs ? fs->name : "unknown");
-
-  grub_device_close (dev);
-
-  return 0;
-}
-
-#if 0
-static void
-grub_rescue_cmd_testload (int argc, char *argv[])
-{
-  grub_file_t file;
-  char *buf;
-  grub_ssize_t size;
-  grub_ssize_t pos;
-  auto void read_func (unsigned long sector, unsigned offset, unsigned len);
-
-  void read_func (unsigned long sector __attribute__ ((unused)),
-                 unsigned offset __attribute__ ((unused)),
-                 unsigned len __attribute__ ((unused)))
-    {
-      grub_putchar ('.');
-      grub_refresh ();
-    }
-
-  if (argc < 1)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
-      return;
-    }
-
-  file = grub_file_open (argv[0]);
-  if (! file)
-    return;
-
-  size = grub_file_size (file) & ~(GRUB_DISK_SECTOR_SIZE - 1);
-  if (size == 0)
-    {
-      grub_file_close (file);
-      return;
-    }
-
-  buf = grub_malloc (size);
-  if (! buf)
-    goto fail;
-
-  grub_printf ("Reading %s sequentially", argv[0]);
-  file->read_hook = read_func;
-  if (grub_file_read (file, buf, size) != size)
-    goto fail;
-  grub_printf (" Done.\n");
-
-  /* Read sequentially again.  */
-  grub_printf ("Reading %s sequentially again", argv[0]);
-  if (grub_file_seek (file, 0) < 0)
-    goto fail;
-
-  for (pos = 0; pos < size; pos += GRUB_DISK_SECTOR_SIZE)
-    {
-      char sector[GRUB_DISK_SECTOR_SIZE];
-
-      if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE)
-         != GRUB_DISK_SECTOR_SIZE)
-       goto fail;
-
-      if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0)
-       {
-         grub_printf ("\nDiffers in %d\n", pos);
-         goto fail;
-       }
-    }
-  grub_printf (" Done.\n");
-
-  /* Read backwards and compare.  */
-  grub_printf ("Reading %s backwards", argv[0]);
-  pos = size;
-  while (pos > 0)
-    {
-      char sector[GRUB_DISK_SECTOR_SIZE];
-
-      pos -= GRUB_DISK_SECTOR_SIZE;
-
-      if (grub_file_seek (file, pos) < 0)
-       goto fail;
-
-      if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE)
-         != GRUB_DISK_SECTOR_SIZE)
-       goto fail;
-
-      if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0)
-       {
-         int i;
-
-         grub_printf ("\nDiffers in %d\n", pos);
-
-         for (i = 0; i < GRUB_DISK_SECTOR_SIZE; i++)
-           grub_putchar (buf[pos + i]);
-
-         if (i)
-           grub_refresh ();
-
-         goto fail;
-       }
-    }
-  grub_printf (" Done.\n");
-
- fail:
-
-  grub_file_close (file);
-  grub_free (buf);
-}
-#endif
-
-/* dump ADDRESS [SIZE] */
-static grub_err_t
-grub_mini_cmd_dump (struct grub_command *cmd __attribute__ ((unused)),
-                   int argc, char *argv[])
-{
-  grub_uint8_t *addr;
-  grub_size_t size = 4;
-
-  if (argc == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no address specified");
-
-  addr = (grub_uint8_t *) grub_strtoul (argv[0], 0, 0);
-  if (grub_errno)
-    return grub_errno;
-
-  if (argc > 1)
-    size = (grub_size_t) grub_strtoul (argv[1], 0, 0);
-
-  while (size--)
-    {
-      grub_printf ("%x%x ", *addr >> 4, *addr & 0xf);
-      addr++;
-    }
-
-  return 0;
-}
-
-/* rmmod MODULE */
-static grub_err_t
-grub_mini_cmd_rmmod (struct grub_command *cmd __attribute__ ((unused)),
-                    int argc, char *argv[])
-{
-  grub_dl_t mod;
-
-  if (argc == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
-
-  mod = grub_dl_get (argv[0]);
-  if (! mod)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such module");
-
-  if (grub_dl_unref (mod) <= 0)
-    grub_dl_unload (mod);
-
-  return 0;
-}
-
-/* lsmod */
-static grub_err_t
-grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)),
-                    int argc __attribute__ ((unused)),
-                    char *argv[] __attribute__ ((unused)))
-{
-  auto int print_module (grub_dl_t mod);
-
-  int print_module (grub_dl_t mod)
-    {
-      grub_dl_dep_t dep;
-
-      grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count);
-      for (dep = mod->dep; dep; dep = dep->next)
-       {
-         if (dep != mod->dep)
-           grub_putchar (',');
-
-         grub_printf ("%s", dep->mod->name);
-       }
-      grub_putchar ('\n');
-
-      return 0;
-    }
-
-  grub_printf ("Name\tRef Count\tDependencies\n");
-  grub_dl_iterate (print_module);
-
-  return 0;
-}
-
-/* exit */
-static grub_err_t
-grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
-                   int argc __attribute__ ((unused)),
-                   char *argv[] __attribute__ ((unused)))
-{
-  grub_exit ();
-  return 0;
-}
-
-/* clear */
-static grub_err_t
-grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)),
-                  int argc __attribute__ ((unused)),
-                  char *argv[] __attribute__ ((unused)))
-{
-  grub_cls ();
-  return 0;
-}
-
-static grub_command_t cmd_cat, cmd_help, cmd_root;
-static grub_command_t cmd_dump, cmd_rmmod, cmd_lsmod, cmd_exit;
-static grub_command_t cmd_clear;
-
-GRUB_MOD_INIT(minicmd)
-{
-  cmd_cat =
-    grub_register_command ("cat", grub_mini_cmd_cat,
-                          N_("FILE"), N_("Show the contents of a file."));
-  cmd_help =
-    grub_register_command ("help", grub_mini_cmd_help,
-                          0, N_("Show this message."));
-  cmd_root =
-    grub_register_command ("root", grub_mini_cmd_root,
-                          N_("[DEVICE]"), N_("Set the root device."));
-  cmd_dump =
-    grub_register_command ("dump", grub_mini_cmd_dump,
-                          N_("ADDR"), N_("Dump memory."));
-  cmd_rmmod =
-    grub_register_command ("rmmod", grub_mini_cmd_rmmod,
-                          N_("MODULE"), N_("Remove a module."));
-  cmd_lsmod =
-    grub_register_command ("lsmod", grub_mini_cmd_lsmod,
-                          0, N_("Show loaded modules."));
-  cmd_exit =
-    grub_register_command ("exit", grub_mini_cmd_exit,
-                          0, N_("Exit from GRUB."));
-  cmd_clear =
-    grub_register_command ("clear", grub_mini_cmd_clear,
-                          0, N_("Clear the screen."));
-}
-
-GRUB_MOD_FINI(minicmd)
-{
-  grub_unregister_command (cmd_cat);
-  grub_unregister_command (cmd_help);
-  grub_unregister_command (cmd_root);
-  grub_unregister_command (cmd_dump);
-  grub_unregister_command (cmd_rmmod);
-  grub_unregister_command (cmd_lsmod);
-  grub_unregister_command (cmd_exit);
-  grub_unregister_command (cmd_clear);
-}
diff --git a/commands/parttool.c b/commands/parttool.c
deleted file mode 100644 (file)
index 528cf43..0000000
+++ /dev/null
@@ -1,332 +0,0 @@
-/* parttool.c - common dispatcher and parser for partition operations */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  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/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/normal.h>
-#include <grub/device.h>
-#include <grub/disk.h>
-#include <grub/partition.h>
-#include <grub/parttool.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static struct grub_parttool *parts = 0;
-static int curhandle = 0;
-static grub_dl_t mymod;
-static char helpmsg[] =
-  "Perform COMMANDS on partition.\n"
-  "Use \"parttool PARTITION help\" for the list "
-  "of available commands.";
-
-int
-grub_parttool_register(const char *part_name,
-                      const grub_parttool_function_t func,
-                      const struct grub_parttool_argdesc *args)
-{
-  struct grub_parttool *cur;
-  int nargs = 0;
-
-  if (! parts)
-    grub_dl_ref (mymod);
-
-  cur = (struct grub_parttool *) grub_malloc (sizeof (struct grub_parttool));
-  cur->next = parts;
-  cur->name = grub_strdup (part_name);
-  cur->handle = curhandle++;
-  for (nargs = 0; args[nargs].name != 0; nargs++);
-  cur->nargs = nargs;
-  cur->args = (struct grub_parttool_argdesc *)
-    grub_malloc ((nargs + 1) * sizeof (struct grub_parttool_argdesc));
-  grub_memcpy (cur->args, args,
-              (nargs + 1) * sizeof (struct grub_parttool_argdesc));
-
-  cur->func = func;
-  parts = cur;
-  return cur->handle;
-}
-
-void
-grub_parttool_unregister (int handle)
-{
-  struct grub_parttool *prev = 0, *cur, *t;
-  for (cur = parts; cur; )
-    if (cur->handle == handle)
-      {
-       grub_free (cur->args);
-       grub_free (cur->name);
-       if (prev)
-         prev->next = cur->next;
-       else
-         parts = cur->next;
-       t = cur;
-       cur = cur->next;
-       grub_free (t);
-      }
-    else
-      {
-       prev = cur;
-       cur = cur->next;
-      }
-  if (! parts)
-    grub_dl_unref (mymod);
-}
-
-static grub_err_t
-grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
-                  int argc, char **args)
-{
-  grub_device_t dev;
-  struct grub_parttool *cur, *ptool;
-  int *parsed;
-  int i, j;
-  grub_err_t err = GRUB_ERR_NONE;
-
-  auto grub_err_t show_help (void);
-  grub_err_t show_help (void)
-  {
-    int found = 0;
-    for (cur = parts; cur; cur = cur->next)
-      if (grub_strcmp (dev->disk->partition->partmap->name, cur->name) == 0)
-       {
-         struct grub_parttool_argdesc *curarg;
-         found = 1;
-         for (curarg = cur->args; curarg->name; curarg++)
-           {
-             int spacing = 20;
-
-             spacing -= grub_strlen (curarg->name);
-             grub_printf ("%s", curarg->name);
-
-             switch (curarg->type)
-               {
-               case GRUB_PARTTOOL_ARG_BOOL:
-                 grub_printf ("+/-");
-                 spacing -= 3;
-                 break;
-
-               case GRUB_PARTTOOL_ARG_VAL:
-                 grub_printf ("=VAL");
-                 spacing -= 4;
-                 break;
-
-                   case GRUB_PARTTOOL_ARG_END:
-                     break;
-               }
-             while (spacing-- > 0)
-               grub_printf (" ");
-             grub_printf ("%s\n", curarg->desc);
-           }
-       }
-    if (! found)
-      grub_printf ("Sorry no parttool is available for %s\n",
-                  dev->disk->partition->partmap->name);
-    return GRUB_ERR_NONE;
-  }
-
-  if (argc < 1)
-    {
-      grub_printf ("%s\n", helpmsg);
-      return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few arguments");
-    }
-
-  if (args[0][0] == '(' && args[0][grub_strlen (args[0]) - 1] == ')')
-    {
-      args[0][grub_strlen (args[0]) - 1] = 0;
-      dev = grub_device_open (args[0] + 1);
-      args[0][grub_strlen (args[0]) - 1] = ')';
-    }
-  else
-    dev = grub_device_open (args[0]);
-
-  if (! dev)
-    return grub_errno;
-
-  if (! dev->disk)
-    {
-      grub_device_close (dev);
-      return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a disk");
-    }
-
-  if (! dev->disk->partition)
-    {
-      grub_device_close (dev);
-      return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a partition");
-    }
-
-  /* Load modules. */
-#if !GRUB_NO_MODULES
-  {
-    const char *prefix;
-    prefix = grub_env_get ("prefix");
-    if (prefix)
-      {
-       char *filename;
-
-       filename = grub_xasprintf ("%s/parttool.lst", prefix);
-       if (filename)
-         {
-           grub_file_t file;
-
-           file = grub_file_open (filename);
-           if (file)
-             {
-               char *buf = 0;
-               for (;; grub_free(buf))
-                 {
-                   char *p, *name;
-
-                   buf = grub_file_getline (file);
-
-                   if (! buf)
-                     break;
-
-                   name = buf;
-
-                   if (! grub_isgraph (name[0]))
-                     continue;
-
-                   p = grub_strchr (name, ':');
-                   if (! p)
-                     continue;
-
-                   *p = '\0';
-                   while (*++p == ' ')
-                     ;
-
-                   if (! grub_isgraph (*p))
-                     continue;
-
-                   if (grub_strcmp (name, dev->disk->partition->partmap->name)
-                       != 0)
-                     continue;
-
-                   grub_dl_load (p);
-                 }
-
-               grub_file_close (file);
-             }
-
-           grub_free (filename);
-         }
-      }
-    /* Ignore errors.  */
-    grub_errno = GRUB_ERR_NONE;
-  }
-#endif
-
-  if (argc == 1)
-    return show_help ();
-
-  for (i = 1; i < argc; i++)
-    if (grub_strcmp (args[i], "help") == 0)
-      return show_help ();
-
-  parsed = (int *) grub_zalloc (argc * sizeof (int));
-
-  for (i = 1; i < argc; i++)
-    if (! parsed[i])
-      {
-       struct grub_parttool_argdesc *curarg;
-       struct grub_parttool_args *pargs;
-       for (cur = parts; cur; cur = cur->next)
-         if (grub_strcmp (dev->disk->partition->partmap->name, cur->name) == 0)
-           {
-             for (curarg = cur->args; curarg->name; curarg++)
-               if (grub_strncmp (curarg->name, args[i],
-                                 grub_strlen (curarg->name)) == 0
-                   && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL
-                        && (args[i][grub_strlen (curarg->name)] == '+'
-                            || args[i][grub_strlen (curarg->name)] == '-'
-                            || args[i][grub_strlen (curarg->name)] == 0))
-                       || (curarg->type == GRUB_PARTTOOL_ARG_VAL
-                           && args[i][grub_strlen (curarg->name)] == '=')))
-
-                 break;
-             if (curarg->name)
-               break;
-           }
-       if (! cur)
-         return grub_error (GRUB_ERR_BAD_ARGUMENT, "unrecognised argument %s",
-                            args[i]);
-       ptool = cur;
-       pargs = (struct grub_parttool_args *)
-         grub_zalloc (ptool->nargs * sizeof (struct grub_parttool_args));
-       for (j = i; j < argc; j++)
-         if (! parsed[j])
-           {
-             for (curarg = ptool->args; curarg->name; curarg++)
-               if (grub_strncmp (curarg->name, args[i],
-                                  grub_strlen (curarg->name)) == 0
-                   && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL
-                        && (args[j][grub_strlen (curarg->name)] == '+'
-                            || args[j][grub_strlen (curarg->name)] == '-'
-                            || args[j][grub_strlen (curarg->name)] == 0))
-                       || (curarg->type == GRUB_PARTTOOL_ARG_VAL
-                           && args[j][grub_strlen (curarg->name)] == '=')))
-                 {
-                   parsed[j] = 1;
-                   pargs[curarg - ptool->args].set = 1;
-                   switch (curarg->type)
-                     {
-                     case GRUB_PARTTOOL_ARG_BOOL:
-                       pargs[curarg - ptool->args].bool
-                         = (args[j][grub_strlen (curarg->name)] != '-');
-                       break;
-
-                     case GRUB_PARTTOOL_ARG_VAL:
-                       pargs[curarg - ptool->args].str
-                         = (args[j] + grub_strlen (curarg->name) + 1);
-                       break;
-
-                     case GRUB_PARTTOOL_ARG_END:
-                       break;
-                     }
-                 }
-           }
-
-       err = ptool->func (dev, pargs);
-       grub_free (pargs);
-       if (err)
-         break;
-      }
-
-  grub_free (parsed);
-  grub_device_close (dev);
-  return err;
-}
-
-static grub_command_t cmd;
-
-GRUB_MOD_INIT(parttool)
-{
-  mymod = mod;
-  cmd = grub_register_command ("parttool", grub_cmd_parttool,
-                              N_("PARTITION COMMANDS"),
-                              helpmsg);
-}
-
-GRUB_MOD_FINI(parttool)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/password.c b/commands/password.c
deleted file mode 100644 (file)
index 0428525..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/auth.h>
-#include <grub/crypto.h>
-#include <grub/list.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/env.h>
-#include <grub/normal.h>
-#include <grub/dl.h>
-#include <grub/i18n.h>
-
-static grub_dl_t my_mod;
-
-static grub_err_t
-check_password (const char *user, const char *entered,
-               void *password)
-{
-  if (grub_crypto_memcmp (entered, password, GRUB_AUTH_MAX_PASSLEN) != 0)
-    return GRUB_ACCESS_DENIED;
-
-  grub_auth_authenticate (user);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
-                  int argc, char **args)
-{
-  grub_err_t err;
-  char *pass;
-  int copylen;
-
-  if (argc != 2)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments expected");
-
-  pass = grub_zalloc (GRUB_AUTH_MAX_PASSLEN);
-  if (!pass)
-    return grub_errno;
-  copylen = grub_strlen (args[1]);
-  if (copylen >= GRUB_AUTH_MAX_PASSLEN)
-    copylen = GRUB_AUTH_MAX_PASSLEN - 1;
-  grub_memcpy (pass, args[1], copylen);
-
-  err = grub_auth_register_authentication (args[0], check_password, pass);
-  if (err)
-    {
-      grub_free (pass);
-      return err;
-    }
-  grub_dl_ref (my_mod);
-  return GRUB_ERR_NONE;
-}
-
-static grub_command_t cmd;
-\f
-GRUB_MOD_INIT(password)
-{
-  my_mod = mod;
-  cmd = grub_register_command ("password", grub_cmd_password,
-                              N_("USER PASSWORD"),
-                              N_("Set user password (plaintext). "
-                              "Unrecommended and insecure."));
-}
-
-GRUB_MOD_FINI(password)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/password_pbkdf2.c b/commands/password_pbkdf2.c
deleted file mode 100644 (file)
index 6886987..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/auth.h>
-#include <grub/crypto.h>
-#include <grub/list.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/env.h>
-#include <grub/normal.h>
-#include <grub/dl.h>
-#include <grub/i18n.h>
-
-static grub_dl_t my_mod;
-
-struct pbkdf2_password
-{
-  grub_uint8_t *salt;
-  grub_size_t saltlen;
-  unsigned int c;
-  grub_uint8_t *expected;
-  grub_size_t buflen;
-};
-
-static grub_err_t
-check_password (const char *user, const char *entered, void *pin)
-{
-  grub_uint8_t *buf;
-  struct pbkdf2_password *pass = pin;
-  gcry_err_code_t err;
-
-  buf = grub_malloc (pass->buflen);
-  if (!buf)
-    return grub_crypto_gcry_error (GPG_ERR_OUT_OF_MEMORY);
-
-  err = grub_crypto_pbkdf2 (GRUB_MD_SHA512, (grub_uint8_t *) entered,
-                           grub_strlen (entered),
-                           pass->salt, pass->saltlen, pass->c,
-                           buf, pass->buflen);
-  if (err)
-    {
-      grub_free (buf);
-      return grub_crypto_gcry_error (err);
-    }
-
-  if (grub_crypto_memcmp (buf, pass->expected, pass->buflen) != 0)
-    return GRUB_ACCESS_DENIED;
-
-  grub_auth_authenticate (user);
-
-  return GRUB_ERR_NONE;
-}
-
-static inline int
-hex2val (char hex)
-{
-  if ('0' <= hex && hex <= '9')
-    return hex - '0';
-  if ('a' <= hex && hex <= 'f')
-    return hex - 'a' + 10;
-  if ('A' <= hex && hex <= 'F')
-    return hex - 'A' + 10;
-  return -1;
-}
-
-static grub_err_t
-grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
-                  int argc, char **args)
-{
-  grub_err_t err;
-  char *ptr, *ptr2;
-  grub_uint8_t *ptro;
-  struct pbkdf2_password *pass;
-
-  if (argc != 2)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Two arguments expected.");
-
-  if (grub_memcmp (args[1], "grub.pbkdf2.sha512.",
-                  sizeof ("grub.pbkdf2.sha512.") - 1) != 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Incorrect PBKDF2 password.");
-
-  ptr = args[1] + sizeof ("grub.pbkdf2.sha512.") - 1;
-
-  pass = grub_malloc (sizeof (*pass));
-  if (!pass)
-    return grub_errno;
-
-  pass->c = grub_strtoul (ptr, &ptr, 0);
-  if (*ptr != '.')
-    {
-      grub_free (pass);
-      return grub_error (GRUB_ERR_BAD_ARGUMENT, "Incorrect PBKDF2 password.");
-    }
-  ptr++;
-
-  ptr2 = grub_strchr (ptr, '.');
-  if (!ptr2 || ((ptr2 - ptr) & 1) || grub_strlen (ptr2 + 1) & 1)
-    {
-      grub_free (pass);
-      return grub_error (GRUB_ERR_BAD_ARGUMENT, "Incorrect PBKDF2 password.");
-    }
-
-  pass->saltlen = (ptr2 - ptr) >> 1;
-  pass->buflen = grub_strlen (ptr2 + 1) >> 1;
-  ptro = pass->salt = grub_malloc (pass->saltlen);
-  if (!ptro)
-    {
-      grub_free (pass);
-      return grub_errno;
-    }
-  while (ptr < ptr2)
-    {
-      int hex1, hex2;
-      hex1 = hex2val (*ptr);
-      ptr++;
-      hex2 = hex2val (*ptr);
-      ptr++;
-      if (hex1 < 0 || hex2 < 0)
-       {
-         grub_free (pass->salt);
-         grub_free (pass);
-         return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                            "Incorrect PBKDF2 password.");
-       }
-
-      *ptro = (hex1 << 4) | hex2;
-      ptro++;
-    }
-
-  ptro = pass->expected = grub_malloc (pass->buflen);
-  if (!ptro)
-    {
-      grub_free (pass->salt);
-      grub_free (pass);
-      return grub_errno;
-    }
-  ptr = ptr2 + 1;
-  ptr2 += grub_strlen (ptr2); 
-  while (ptr < ptr2)
-    {
-      int hex1, hex2;
-      hex1 = hex2val (*ptr);
-      ptr++;
-      hex2 = hex2val (*ptr);
-      ptr++;
-      if (hex1 < 0 || hex2 < 0)
-       {
-         grub_free (pass->expected);
-         grub_free (pass->salt);
-         grub_free (pass);
-         return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                            "Incorrect PBKDF2 password.");
-       }
-
-      *ptro = (hex1 << 4) | hex2;
-      ptro++;
-    }
-
-  err = grub_auth_register_authentication (args[0], check_password, pass);
-  if (err)
-    {
-      grub_free (pass);
-      return err;
-    }
-  grub_dl_ref (my_mod);
-  return GRUB_ERR_NONE;
-}
-
-static grub_command_t cmd;
-\f
-GRUB_MOD_INIT(password_pbkdf2)
-{
-  my_mod = mod;
-  cmd = grub_register_command ("password_pbkdf2", grub_cmd_password,
-                              N_("USER PBKDF2_PASSWORD"),
-                              N_("Set user password (PBKDF2). "));
-}
-
-GRUB_MOD_FINI(password_pbkdf2)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/probe.c b/commands/probe.c
deleted file mode 100644 (file)
index c2cc599..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/device.h>
-#include <grub/disk.h>
-#include <grub/partition.h>
-#include <grub/net.h>
-#include <grub/fs.h>
-#include <grub/file.h>
-#include <grub/misc.h>
-#include <grub/env.h>
-#include <grub/extcmd.h>
-#include <grub/i18n.h>
-
-static const struct grub_arg_option options[] =
-  {
-    {"set",             's', GRUB_ARG_OPTION_OPTIONAL,
-     N_("Set a variable to return value."), "VAR", ARG_TYPE_STRING},
-    {"driver",         'd', 0, N_("Determine driver."), 0, 0},
-    {"partmap",                'p', 0, N_("Determine partition map type."), 0, 0},
-    {"fs",             'f', 0, N_("Determine filesystem type."), 0, 0},
-    {"fs-uuid",                'u', 0, N_("Determine filesystem UUID."), 0, 0},
-    {"label",          'l', 0, N_("Determine filesystem label."), 0, 0},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-static grub_err_t
-grub_cmd_probe (grub_extcmd_t cmd, int argc, char **args)
-{
-  struct grub_arg_list *state = cmd->state;
-  grub_device_t dev;
-  grub_fs_t fs;
-  char *ptr;
-  grub_err_t err;
-
-  if (argc < 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
-
-  ptr = args[0] + grub_strlen (args[0]) - 1;
-  if (args[0][0] == '(' && *ptr == ')')
-    {
-      *ptr = 0;
-      dev = grub_device_open (args[0] + 1);
-      *ptr = ')';
-    }
-  else
-    dev = grub_device_open (args[0]);
-  if (! dev)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "couldn't open device");
-
-  if (state[1].set)
-    {
-      const char *val = "none";
-      if (dev->net)
-       val = dev->net->dev->name;
-      if (dev->disk)
-       val = dev->disk->dev->name;
-      if (state[0].set)
-       grub_env_set (state[0].arg, val);
-      else
-       grub_printf ("%s", val);
-      return GRUB_ERR_NONE;
-    }
-  if (state[2].set)
-    {
-      const char *val = "none";
-      if (dev->disk && dev->disk->partition)
-       val = dev->disk->partition->partmap->name;
-      if (state[0].set)
-       grub_env_set (state[0].arg, val);
-      else
-       grub_printf ("%s", val);
-      return GRUB_ERR_NONE;
-    }
-  fs = grub_fs_probe (dev);
-  if (! fs)
-    return grub_error (GRUB_ERR_UNKNOWN_FS, "unrecognised fs");
-  if (state[3].set)
-    {
-      if (state[0].set)
-       grub_env_set (state[0].arg, fs->name);
-      else
-       grub_printf ("%s", fs->name);
-      return GRUB_ERR_NONE;
-    }
-  if (state[4].set)
-    {
-      char *uuid;
-      if (! fs->uuid)
-       return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                          "uuid for this FS isn't supported yet");
-      err = fs->uuid (dev, &uuid);
-      if (err)
-       return err;
-      if (! uuid)
-       return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                          "uuid for this FS isn't supported yet");
-
-      if (state[0].set)
-       grub_env_set (state[0].arg, uuid);
-      else
-       grub_printf ("%s", uuid);
-      grub_free (uuid);
-      return GRUB_ERR_NONE;
-    }
-  if (state[5].set)
-    {
-      char *label;
-      if (! fs->label)
-       return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                          "label for this FS isn't supported yet");
-      err = fs->label (dev, &label);
-      if (err)
-       return err;
-      if (! label)
-       return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                          "uuid for this FS isn't supported yet");
-
-      if (state[0].set)
-       grub_env_set (state[0].arg, label);
-      else
-       grub_printf ("%s", label);
-      grub_free (label);
-      return GRUB_ERR_NONE;
-    }
-  return grub_error (GRUB_ERR_BAD_ARGUMENT, "unrecognised target");
-}
-
-static grub_extcmd_t cmd;
-
-GRUB_MOD_INIT (probe)
-{
-  cmd = grub_register_extcmd ("probe", grub_cmd_probe, GRUB_COMMAND_FLAG_BOTH,
-                             N_("[DEVICE]"),
-                             N_("Retrieve device info."), options);
-}
-
-GRUB_MOD_FINI (probe)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/commands/read.c b/commands/read.c
deleted file mode 100644 (file)
index 8a7c4a0..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/* read.c - Command to read variables from user.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/env.h>
-#include <grub/term.h>
-#include <grub/types.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static char *
-grub_getline (void)
-{
-  int i;
-  char *line;
-  char *tmp;
-  char c;
-
-  i = 0;
-  line = grub_malloc (1 + i + sizeof('\0'));
-  if (! line)
-    return NULL;
-
-  while (1)
-    {
-      c = grub_getkey ();
-      if ((c == '\n') || (c == '\r'))
-       break;
-
-      line[i] = c;
-      if (grub_isprint (c))
-       grub_putchar (c);
-      i++;
-      tmp = grub_realloc (line, 1 + i + sizeof('\0'));
-      if (! tmp)
-       {
-         grub_free (line);
-         return NULL;
-       }
-      line = tmp;
-    }
-  line[i] = '\0';
-
-  return line;
-}
-
-static grub_err_t
-grub_cmd_read (grub_command_t cmd __attribute__ ((unused)), int argc, char **args)
-{
-  char *line = grub_getline ();
-  if (! line)
-    return grub_errno;
-  if (argc > 0)
-    grub_env_set (args[0], line);
-
-  grub_free (line);
-  return 0;
-}
-
-static grub_command_t cmd;
-\f
-GRUB_MOD_INIT(read)
-{
-  cmd = grub_register_command ("read", grub_cmd_read,
-                              N_("[ENVVAR]"),
-                              N_("Set variable with user input."));
-}
-
-GRUB_MOD_FINI(read)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/reboot.c b/commands/reboot.c
deleted file mode 100644 (file)
index eedd53c..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* reboot.c - command to reboot the computer.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/command.h>
-#include <grub/misc.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-grub_cmd_reboot (grub_command_t cmd __attribute__ ((unused)),
-                int argc __attribute__ ((unused)),
-                char **args __attribute__ ((unused)))
-{
-  grub_reboot ();
-  return 0;
-}
-
-static grub_command_t cmd;
-\f
-GRUB_MOD_INIT(reboot)
-{
-  cmd = grub_register_command ("reboot", grub_cmd_reboot,
-                              0, N_("Reboot the computer."));
-}
-
-GRUB_MOD_FINI(reboot)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/regexp.c b/commands/regexp.c
deleted file mode 100644 (file)
index e8e8243..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/* regexp.c -- The regexp command.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-#include <regex.h>
-
-static grub_err_t
-grub_cmd_regexp (grub_command_t cmd __attribute__ ((unused)),
-                int argc, char **args)
-{
-  int argn = 0;
-  int matches = 0;
-  regex_t regex;
-  int ret;
-  grub_size_t s;
-  char *comperr;
-  grub_err_t err;
-
-  if (argc != 2)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "2 arguments expected");
-
-  ret = regcomp (&regex, args[0], RE_SYNTAX_GNU_AWK);
-  if (ret)
-    goto fail;
-
-  ret = regexec (&regex, args[1], 0, 0, 0);
-  if (!ret)
-    {
-      regfree (&regex);
-      return GRUB_ERR_NONE;
-    }
-
- fail:
-  s = regerror (ret, &regex, 0, 0);
-  comperr = grub_malloc (s);
-  if (!comperr)
-    {
-      regfree (&regex);
-      return grub_errno;
-    }
-  regerror (ret, &regex, comperr, s);
-  err = grub_error (GRUB_ERR_TEST_FAILURE, "%s", comperr);
-  regfree (&regex);
-  grub_free (comperr);
-  return err;
-}
-
-static grub_command_t cmd;
-\f
-GRUB_MOD_INIT(regexp)
-{
-  cmd = grub_register_command ("regexp", grub_cmd_regexp,
-                              N_("REGEXP STRING"),
-                              N_("Test if REGEXP matches STRING."));
-}
-
-GRUB_MOD_FINI(regexp)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/search.c b/commands/search.c
deleted file mode 100644 (file)
index 71267b1..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/* search.c - search devices based on a file or a filesystem label */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/device.h>
-#include <grub/file.h>
-#include <grub/env.h>
-#include <grub/command.h>
-#include <grub/search.h>
-#include <grub/i18n.h>
-
-void
-FUNC_NAME (const char *key, const char *var, int no_floppy)
-{
-  int count = 0;
-  grub_fs_autoload_hook_t saved_autoload;
-
-  auto int iterate_device (const char *name);
-  int iterate_device (const char *name)
-  {
-    int found = 0;
-
-    /* Skip floppy drives when requested.  */
-    if (no_floppy &&
-       name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
-      return 0;
-
-#ifdef DO_SEARCH_FILE
-      {
-       char *buf;
-       grub_file_t file;
-
-       buf = grub_xasprintf ("(%s)%s", name, key);
-       if (! buf)
-         return 1;
-
-       file = grub_file_open (buf);
-       if (file)
-         {
-           found = 1;
-           grub_file_close (file);
-         }
-       grub_free (buf);
-      }
-#else
-      {
-       /* SEARCH_FS_UUID or SEARCH_LABEL */
-       grub_device_t dev;
-       grub_fs_t fs;
-       char *quid;
-
-       dev = grub_device_open (name);
-       if (dev)
-         {
-           fs = grub_fs_probe (dev);
-
-#ifdef DO_SEARCH_FS_UUID
-#define compare_fn grub_strcasecmp
-#define read_fn uuid
-#else
-#define compare_fn grub_strcmp
-#define read_fn label
-#endif
-
-           if (fs && fs->read_fn)
-             {
-               fs->read_fn (dev, &quid);
-
-               if (grub_errno == GRUB_ERR_NONE && quid)
-                 {
-                   if (compare_fn (quid, key) == 0)
-                     found = 1;
-
-                   grub_free (quid);
-                 }
-             }
-
-           grub_device_close (dev);
-         }
-      }
-#endif
-
-    if (found)
-      {
-       count++;
-       if (var)
-         grub_env_set (var, name);
-       else
-         grub_printf (" %s", name);
-      }
-
-    grub_errno = GRUB_ERR_NONE;
-    return (found && var);
-  }
-
-  /* First try without autoloading if we're setting variable. */
-  if (var)
-    {
-      saved_autoload = grub_fs_autoload_hook;
-      grub_fs_autoload_hook = 0;
-      grub_device_iterate (iterate_device);
-
-      /* Restore autoload hook.  */
-      grub_fs_autoload_hook = saved_autoload;
-
-      /* Retry with autoload if nothing found.  */
-      if (grub_errno == GRUB_ERR_NONE && count == 0)
-       grub_device_iterate (iterate_device);
-    }
-  else
-    grub_device_iterate (iterate_device);
-
-  if (grub_errno == GRUB_ERR_NONE && count == 0)
-    grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key);
-}
-
-static grub_err_t
-grub_cmd_do_search (grub_command_t cmd __attribute__ ((unused)), int argc,
-                   char **args)
-{
-  if (argc == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no argument specified");
-
-  FUNC_NAME (args[0], argc == 1 ? 0 : args[1], 0);
-
-  return grub_errno;
-}
-
-static grub_command_t cmd;
-
-#ifdef DO_SEARCH_FILE
-GRUB_MOD_INIT(search_fs_file)
-#elif defined (DO_SEARCH_FS_UUID)
-GRUB_MOD_INIT(search_fs_uuid)
-#else
-GRUB_MOD_INIT(search_label)
-#endif
-{
-  cmd =
-    grub_register_command (COMMAND_NAME, grub_cmd_do_search,
-                          N_("NAME [VARIABLE]"),
-                          HELP_MESSAGE);
-}
-
-#ifdef DO_SEARCH_FILE
-GRUB_MOD_FINI(search_fs_file)
-#elif defined (DO_SEARCH_FS_UUID)
-GRUB_MOD_FINI(search_fs_uuid)
-#else
-GRUB_MOD_FINI(search_label)
-#endif
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/search_file.c b/commands/search_file.c
deleted file mode 100644 (file)
index 73ce89c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#define DO_SEARCH_FILE 1
-#define FUNC_NAME grub_search_fs_file
-#define COMMAND_NAME "search.file"
-#define SEARCH_TARGET "file"
-#define HELP_MESSAGE N_("Search devices by file. If VARIABLE is specified, the first device found is set to a variable.")
-#include "search.c"
diff --git a/commands/search_label.c b/commands/search_label.c
deleted file mode 100644 (file)
index ee9c792..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#define DO_SEARCH_FS_LABEL 1
-#define FUNC_NAME grub_search_label
-#define COMMAND_NAME "search.fs_label"
-#define SEARCH_TARGET "filesystem label"
-#define HELP_MESSAGE N_("Search devices by label. If VARIABLE is specified, the first device found is set to a variable.")
-#include "search.c"
diff --git a/commands/search_uuid.c b/commands/search_uuid.c
deleted file mode 100644 (file)
index 52f8381..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#define DO_SEARCH_FS_UUID 1
-#define FUNC_NAME grub_search_fs_uuid
-#define COMMAND_NAME "search.fs_uuid"
-#define SEARCH_TARGET "filesystem UUID"
-#define HELP_MESSAGE N_("Search devices by UUID. If VARIABLE is specified, the first device found is set to a variable.")
-#include "search.c"
diff --git a/commands/search_wrap.c b/commands/search_wrap.c
deleted file mode 100644 (file)
index 2891d85..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/* search.c - search devices based on a file or a filesystem label */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/env.h>
-#include <grub/extcmd.h>
-#include <grub/search.h>
-#include <grub/i18n.h>
-
-static const struct grub_arg_option options[] =
-  {
-    {"file",           'f', 0, N_("Search devices by a file."), 0, 0},
-    {"label",          'l', 0, N_("Search devices by a filesystem label."),
-     0, 0},
-    {"fs-uuid",                'u', 0, N_("Search devices by a filesystem UUID."),
-     0, 0},
-    {"set",            's', GRUB_ARG_OPTION_OPTIONAL,
-     N_("Set a variable to the first device found."), "VAR", ARG_TYPE_STRING},
-    {"no-floppy",      'n', 0, N_("Do not probe any floppy drive."), 0, 0},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-enum options
-  {
-    SEARCH_FILE,
-    SEARCH_LABEL,
-    SEARCH_FS_UUID,
-    SEARCH_SET,
-    SEARCH_NO_FLOPPY,
- };
-
-static grub_err_t
-grub_cmd_search (grub_extcmd_t cmd, int argc, char **args)
-{
-  struct grub_arg_list *state = cmd->state;
-  const char *var = 0;
-
-  if (argc == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no argument specified");
-
-  if (state[SEARCH_SET].set)
-    var = state[SEARCH_SET].arg ? state[SEARCH_SET].arg : "root";
-
-  if (state[SEARCH_LABEL].set)
-    grub_search_label (args[0], var, state[SEARCH_NO_FLOPPY].set);
-  else if (state[SEARCH_FS_UUID].set)
-    grub_search_fs_uuid (args[0], var, state[SEARCH_NO_FLOPPY].set);
-  else if (state[SEARCH_FILE].set)
-    grub_search_fs_file (args[0], var, state[SEARCH_NO_FLOPPY].set);
-  else
-    return grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type");
-
-  return grub_errno;
-}
-
-static grub_extcmd_t cmd;
-
-GRUB_MOD_INIT(search)
-{
-  cmd =
-    grub_register_extcmd ("search", grub_cmd_search,
-                         GRUB_COMMAND_FLAG_BOTH,
-                         N_("search [-f|-l|-u|-s|-n] NAME"),
-                         N_("Search devices by file, filesystem label"
-                            " or filesystem UUID."
-                            " If --set is specified, the first device found is"
-                            " set to a variable. If no variable name is"
-                            " specified, \"root\" is used."),
-                         options);
-}
-
-GRUB_MOD_FINI(search)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/commands/setpci.c b/commands/setpci.c
deleted file mode 100644 (file)
index fbc7c21..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-/* lspci.c - List PCI devices.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/pci.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/extcmd.h>
-#include <grub/env.h>
-#include <grub/mm.h>
-#include <grub/i18n.h>
-
-struct pci_register
-{
-  const char *name;
-  grub_uint16_t addr;
-  unsigned size;
-};
-
-struct pci_register pci_registers[] =
-  {
-    {"VENDOR_ID",       GRUB_PCI_REG_VENDOR      , 2},
-    {"DEVICE_ID",       GRUB_PCI_REG_DEVICE      , 2},
-    {"COMMAND",         GRUB_PCI_REG_COMMAND     , 2},
-    {"STATUS",          GRUB_PCI_REG_STATUS      , 2},
-    {"REVISION",        GRUB_PCI_REG_REVISION    , 1},
-    {"CLASS_PROG",      GRUB_PCI_REG_CLASS + 1   , 1},
-    {"CLASS_DEVICE",    GRUB_PCI_REG_CLASS + 2   , 2},
-    {"CACHE_LINE_SIZE", GRUB_PCI_REG_CACHELINE   , 1},
-    {"LATENCY_TIMER",   GRUB_PCI_REG_LAT_TIMER   , 1},
-    {"HEADER_TYPE",     GRUB_PCI_REG_HEADER_TYPE , 1},
-    {"BIST",            GRUB_PCI_REG_BIST        , 1},
-    {"BASE_ADDRESS_0",  GRUB_PCI_REG_ADDRESS_REG0, 4},
-    {"BASE_ADDRESS_1",  GRUB_PCI_REG_ADDRESS_REG1, 4},
-    {"BASE_ADDRESS_2",  GRUB_PCI_REG_ADDRESS_REG2, 4},
-    {"BASE_ADDRESS_3",  GRUB_PCI_REG_ADDRESS_REG3, 4},
-    {"BASE_ADDRESS_4",  GRUB_PCI_REG_ADDRESS_REG4, 4},
-    {"BASE_ADDRESS_5",  GRUB_PCI_REG_ADDRESS_REG5, 4},
-    {"CARDBUS_CIS",     GRUB_PCI_REG_CIS_POINTER , 4},
-    {"SUBVENDOR_ID",    GRUB_PCI_REG_SUBVENDOR   , 2},
-    {"SUBSYSTEM_ID",    GRUB_PCI_REG_SUBSYSTEM   , 2},
-    {"ROM_ADDRESS",     GRUB_PCI_REG_ROM_ADDRESS , 4},
-    {"CAP_POINTER",     GRUB_PCI_REG_CAP_POINTER , 1},
-    {"INTERRUPT_LINE",  GRUB_PCI_REG_IRQ_LINE    , 1},
-    {"INTERRUPT_PIN",   GRUB_PCI_REG_IRQ_PIN     , 1},
-    {"MIN_GNT",         GRUB_PCI_REG_MIN_GNT     , 1},
-    {"MAX_LAT",         GRUB_PCI_REG_MIN_GNT     , 1},
-  };
-
-static const struct grub_arg_option options[] =
-  {
-    {0, 'd', 0, "Select device by vendor and device IDs.",
-     "[vendor]:[device]", ARG_TYPE_STRING},
-    {0, 's', 0, "Select device by its position on the bus.",
-     "[bus]:[slot][.func]", ARG_TYPE_STRING},
-    {0, 'v', 0, "Save read value into variable VARNAME.",
-     "VARNAME", ARG_TYPE_STRING},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-static grub_uint32_t pciid_check_mask, pciid_check_value;
-static int bus, device, function;
-static int check_bus, check_device, check_function;
-static grub_uint32_t write_mask, regwrite;
-static int regsize;
-static grub_uint16_t regaddr;
-static const char *varname;
-
-static int NESTED_FUNC_ATTR
-grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid)
-{
-  grub_uint32_t regval = 0;
-  grub_pci_address_t addr;
-
-  if ((pciid & pciid_check_mask) != pciid_check_value)
-    return 0;
-
-  if (check_bus && grub_pci_get_bus (dev) != bus)
-    return 0;
-
-  if (check_device && grub_pci_get_device (dev) != device)
-    return 0;
-
-  if (check_function && grub_pci_get_function (dev) != device)
-    return 0;
-
-  addr = grub_pci_make_address (dev, regaddr);
-
-  switch (regsize)
-    {
-    case 1:
-      regval = grub_pci_read_byte (addr);
-      break;
-
-    case 2:
-      regval = grub_pci_read_word (addr);
-      break;
-
-    case 4:
-      regval = grub_pci_read (addr);
-      break;
-    }
-
-  if (varname)
-    {
-      char buf[sizeof ("XXXXXXXX")];
-      grub_snprintf (buf, sizeof (buf), "%x", regval);
-      grub_env_set (varname, buf);
-      return 1;
-    }
-
-  if (!write_mask)
-    {
-      grub_printf ("Register %x of %d:%d.%d is %x\n", regaddr,
-                  grub_pci_get_bus (dev),
-                  grub_pci_get_device (dev),
-                  grub_pci_get_function (dev),
-                  regval);
-      return 0;
-    }
-
-  regval = (regval & ~write_mask) | regwrite;
-
-  switch (regsize)
-    {
-    case 1:
-      grub_pci_write_byte (addr, regval);
-      break;
-
-    case 2:
-      grub_pci_write_word (addr, regval);
-      break;
-
-    case 4:
-      grub_pci_write (addr, regval);
-      break;
-    }
-
-  return 0;
-}
-
-static grub_err_t
-grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv)
-{
-  const char *ptr;
-  unsigned i;
-
-  pciid_check_value = 0;
-  pciid_check_mask = 0;
-
-  if (cmd->state[0].set)
-    {
-      ptr = cmd->state[0].arg;
-      pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff);
-      if (grub_errno == GRUB_ERR_BAD_NUMBER)
-       {
-         grub_errno = GRUB_ERR_NONE;
-         ptr = cmd->state[0].arg;
-       }
-      else
-       pciid_check_mask |= 0xffff;
-      if (grub_errno)
-       return grub_errno;
-      if (*ptr != ':')
-       return grub_error (GRUB_ERR_BAD_ARGUMENT, "Colon expected.");
-      ptr++;
-      pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff)
-       << 16;
-      if (grub_errno == GRUB_ERR_BAD_NUMBER)
-       grub_errno = GRUB_ERR_NONE;
-      else
-       pciid_check_mask |= 0xffff0000;
-    }
-
-  pciid_check_value &= pciid_check_mask;
-
-  check_bus = check_device = check_function = 0;
-
-  if (cmd->state[1].set)
-    {
-      const char *optr;
-      
-      ptr = cmd->state[1].arg;
-      optr = ptr;
-      bus = grub_strtoul (ptr, (char **) &ptr, 16);
-      if (grub_errno == GRUB_ERR_BAD_NUMBER)
-       {
-         grub_errno = GRUB_ERR_NONE;
-         ptr = optr;
-       }
-      else
-       check_bus = 1;
-      if (grub_errno)
-       return grub_errno;
-      if (*ptr != ':')
-       return grub_error (GRUB_ERR_BAD_ARGUMENT, "Colon expected.");
-      ptr++;
-      optr = ptr;
-      device = grub_strtoul (ptr, (char **) &ptr, 16);
-      if (grub_errno == GRUB_ERR_BAD_NUMBER)
-       {
-         grub_errno = GRUB_ERR_NONE;
-         ptr = optr;
-       }
-      else
-       check_device = 1;
-      if (*ptr == '.')
-       {
-         ptr++;
-         function = grub_strtoul (ptr, (char **) &ptr, 16);
-         if (grub_errno)
-           return grub_errno;
-         check_function = 1;
-       }
-    }
-
-  if (cmd->state[2].set)
-    varname = cmd->state[2].arg;
-  else
-    varname = NULL;
-
-  write_mask = 0;
-
-  if (argc == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Command expected.");
-
-  if (argc > 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Only one command is supported.");
-
-  ptr = argv[0];
-
-  for (i = 0; i < ARRAY_SIZE (pci_registers); i++)
-    {
-      if (grub_strncmp (ptr, pci_registers[i].name,
-                       grub_strlen (pci_registers[i].name)) == 0)
-       break;
-    }
-  if (i == ARRAY_SIZE (pci_registers))
-    {
-      regsize = 0;
-      regaddr = grub_strtoul (ptr, (char **) &ptr, 16);
-      if (grub_errno)
-       return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown register");
-    }
-  else
-    {
-      regaddr = pci_registers[i].addr;
-      regsize = pci_registers[i].size;
-      ptr += grub_strlen (pci_registers[i].name);
-    }
-
-  if (grub_errno)
-    return grub_errno;
-
-  if (*ptr == '+')
-    {
-      ptr++;
-      regaddr += grub_strtoul (ptr, (char **) &ptr, 16);
-      if (grub_errno)
-       return grub_errno;
-    }
-
-  if (grub_memcmp (ptr, ".L", sizeof (".L") - 1) == 0
-      || grub_memcmp (ptr, ".l", sizeof (".l") - 1) == 0)
-    {
-      regsize = 4;
-      ptr += sizeof (".l") - 1;
-    }
-  else if (grub_memcmp (ptr, ".W", sizeof (".W") - 1) == 0
-      || grub_memcmp (ptr, ".w", sizeof (".w") - 1) == 0)
-    {
-      regsize = 2;
-      ptr += sizeof (".w") - 1;
-    }
-  else if (grub_memcmp (ptr, ".B", sizeof (".B") - 1) == 0
-      || grub_memcmp (ptr, ".b", sizeof (".b") - 1) == 0)
-    {
-      regsize = 1;
-      ptr += sizeof (".b") - 1;
-    }
-
-  if (!regsize)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "Unknown register size.");
-
-  write_mask = 0;
-  if (*ptr == '=')
-    {
-      ptr++;
-      regwrite = grub_strtoul (ptr, (char **) &ptr, 16);
-      if (grub_errno)
-       return grub_errno;
-      write_mask = 0xffffffff;
-      if (*ptr == ':')
-       {
-         ptr++;
-         write_mask = grub_strtoul (ptr, (char **) &ptr, 16);
-         if (grub_errno)
-           return grub_errno;
-         write_mask = 0xffffffff;
-       }
-      regwrite &= write_mask;
-    }
-
-  if (write_mask && varname)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "Option -v isn't valid for writes.");
-
-  grub_pci_iterate (grub_setpci_iter);
-  return GRUB_ERR_NONE;
-}
-
-static grub_extcmd_t cmd;
-
-GRUB_MOD_INIT(setpci)
-{
-  cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, GRUB_COMMAND_FLAG_BOTH,
-                             N_("[-s POSITION] [-d DEVICE] [-v VAR] "
-                                "[REGISTER][=VALUE[:MASK]]"),
-                             N_("Manipulate PCI devices."), options);
-}
-
-GRUB_MOD_FINI(setpci)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/commands/sleep.c b/commands/sleep.c
deleted file mode 100644 (file)
index ead2795..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/* sleep.c - Command to wait a specified number of seconds.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/term.h>
-#include <grub/time.h>
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/extcmd.h>
-#include <grub/i18n.h>
-
-static const struct grub_arg_option options[] =
-  {
-    {"verbose", 'v', 0, N_("Verbose countdown."), 0, 0},
-    {"interruptible", 'i', 0, N_("Interruptible with ESC."), 0, 0},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-static grub_uint16_t *pos;
-
-static void
-do_print (int n)
-{
-  grub_term_restore_pos (pos);
-  /* NOTE: Do not remove the trailing space characters.
-     They are required to clear the line.  */
-  grub_printf ("%d    ", n);
-}
-
-/* Based on grub_millisleep() from kern/generic/millisleep.c.  */
-static int
-grub_interruptible_millisleep (grub_uint32_t ms)
-{
-  grub_uint64_t start;
-
-  start = grub_get_time_ms ();
-
-  while (grub_get_time_ms () - start < ms)
-    if (grub_checkkey () >= 0 &&
-       GRUB_TERM_ASCII_CHAR (grub_getkey ()) == GRUB_TERM_ESC)
-      return 1;
-
-  return 0;
-}
-
-static grub_err_t
-grub_cmd_sleep (grub_extcmd_t cmd, int argc, char **args)
-{
-  struct grub_arg_list *state = cmd->state;
-  int n;
-
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing operand");
-
-  n = grub_strtoul (args[0], 0, 10);
-
-  if (n == 0)
-    {
-      /* Either `0' or broken input.  */
-      return 0;
-    }
-
-  pos = grub_term_save_pos ();
-
-  for (; n; n--)
-    {
-      if (state[0].set)
-       do_print (n);
-
-      if (state[1].set)
-       {
-         if (grub_interruptible_millisleep (1000))
-           return 1;
-       }
-      else
-       grub_millisleep (1000);
-    }
-  if (state[0].set)
-    do_print (0);
-
-  return 0;
-}
-
-static grub_extcmd_t cmd;
-\f
-GRUB_MOD_INIT(sleep)
-{
-  cmd = grub_register_extcmd ("sleep", grub_cmd_sleep, GRUB_COMMAND_FLAG_BOTH,
-                             N_("NUMBER_OF_SECONDS"),
-                             N_("Wait for a specified number of seconds."),
-                             options);
-}
-
-GRUB_MOD_FINI(sleep)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/commands/terminal.c b/commands/terminal.c
deleted file mode 100644 (file)
index 1129c39..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/dl.h>
-#include <grub/command.h>
-#include <grub/term.h>
-#include <grub/i18n.h>
-#include <grub/misc.h>
-
-struct grub_term_autoload *grub_term_input_autoload = NULL;
-struct grub_term_autoload *grub_term_output_autoload = NULL;
-
-struct abstract_terminal
-{
-  struct abstract_terminal *next;
-  const char *name;
-  grub_err_t (*init) (void);
-  grub_err_t (*fini) (void);
-};
-
-static grub_err_t
-handle_command (int argc, char **args, struct abstract_terminal **enabled,
-               struct abstract_terminal **disabled,
-               struct grub_term_autoload *autoloads,
-               const char *active_str,
-               const char *available_str)
-{
-  int i;
-  struct abstract_terminal *term;
-  struct grub_term_autoload *aut;
-
-  if (argc == 0)
-    {
-      grub_puts_ (active_str);
-      for (term = *enabled; term; term = term->next)
-       grub_printf ("%s ", term->name);
-      grub_printf ("\n");
-      grub_puts_ (available_str);
-      for (term = *disabled; term; term = term->next)
-       grub_printf ("%s ", term->name);
-      /* This is quadratic but we don't expect mode than 30 terminal
-        modules ever.  */
-      for (aut = autoloads; aut; aut = aut->next)
-       {
-         for (term = *disabled; term; term = term->next)
-           if (grub_strcmp (term->name, aut->name) == 0)
-             break;
-         if (!term)
-           for (term = *enabled; term; term = term->next)
-             if (grub_strcmp (term->name, aut->name) == 0)
-               break;
-         if (!term)
-           grub_printf ("%s ", aut->name);
-       }
-      grub_printf ("\n");
-      return GRUB_ERR_NONE;
-    }
-  i = 0;
-
-  if (grub_strcmp (args[0], "--append") == 0
-      || grub_strcmp (args[0], "--remove") == 0)
-    i++;
-
-  if (i == argc)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
-
-  for (; i < argc; i++)
-    {
-      int again = 0;
-      while (1)
-       {
-         for (term = *disabled; term; term = term->next)
-           if (grub_strcmp (args[i], term->name) == 0)
-             break;
-         if (term == 0)
-           for (term = *enabled; term; term = term->next)
-             if (grub_strcmp (args[i], term->name) == 0)
-               break;
-         if (term)
-           break;
-         if (again)
-           return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
-                              args[i]);
-         for (aut = autoloads; aut; aut = aut->next)
-           if (grub_strcmp (args[i], aut->name) == 0)
-             {
-               grub_dl_t mod;
-               mod = grub_dl_load (aut->modname);
-               if (mod)
-                 grub_dl_ref (mod);
-               grub_errno = GRUB_ERR_NONE;
-               break;
-             }
-         if (!aut)
-           return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
-                              args[i]);
-         again = 1;
-       }
-    }
-
-  if (grub_strcmp (args[0], "--append") == 0)
-    {
-      for (i = 1; i < argc; i++)
-       {
-         for (term = *disabled; term; term = term->next)
-           if (grub_strcmp (args[i], term->name) == 0)
-             break;
-         if (term)
-           {
-              if (term->init && term->init () != GRUB_ERR_NONE)
-                return grub_errno;
-
-             grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
-             grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
-           }
-       }
-      return GRUB_ERR_NONE;
-    }
-
-  if (grub_strcmp (args[0], "--remove") == 0)
-    {
-      for (i = 1; i < argc; i++)
-       {
-         for (term = *enabled; term; term = term->next)
-           if (grub_strcmp (args[i], term->name) == 0)
-             break;
-         if (term)
-           {
-             if (!term->next && term == *enabled)
-               return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                                  "can't remove the last terminal");
-             grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
-             if (term->fini)
-               term->fini ();
-             grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
-           }
-       }
-      return GRUB_ERR_NONE;
-    }
-  for (i = 0; i < argc; i++)
-    {
-      for (term = *disabled; term; term = term->next)
-       if (grub_strcmp (args[i], term->name) == 0)
-         break;
-      if (term)
-       {
-         if (term->init && term->init () != GRUB_ERR_NONE)
-           return grub_errno;
-
-         grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
-         grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
-       }       
-    }
-  
-  {
-    struct abstract_terminal *next;
-    for (term = *enabled; term; term = next)
-      {
-       next = term->next;
-       for (i = 0; i < argc; i++)
-         if (grub_strcmp (args[i], term->name) == 0)
-           break;
-       if (i == argc)
-         {
-           if (!term->next && term == *enabled)
-             return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                                "can't remove the last terminal");
-           grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
-           if (term->fini)
-             term->fini ();
-           grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
-         }
-      }
-  }
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
-                        int argc, char **args)
-{
-  (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, next);
-  (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, name);
-  (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, init);
-  (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, fini);
-  return handle_command (argc, args,
-                        (struct abstract_terminal **) &grub_term_inputs,
-                        (struct abstract_terminal **) &grub_term_inputs_disabled,
-                        grub_term_input_autoload,
-                        N_ ("Active input terminals:"),
-                        N_ ("Available input terminals:"));
-}
-
-static grub_err_t
-grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
-                         int argc, char **args)
-{
-  (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, next);
-  (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, name);
-  (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, init);
-  (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, fini);
-  return handle_command (argc, args, (struct abstract_terminal **) &grub_term_outputs,
-                        (struct abstract_terminal **) &grub_term_outputs_disabled,
-                        grub_term_output_autoload,
-                        N_ ("Active output terminals:"),
-                        N_ ("Available output terminals:"));
-}
-
-static grub_command_t cmd_terminal_input, cmd_terminal_output;
-
-GRUB_MOD_INIT(terminal)
-{
-  cmd_terminal_input =
-    grub_register_command ("terminal_input", grub_cmd_terminal_input,
-                          N_("[--append|--remove] "
-                             "[TERMINAL1] [TERMINAL2] ..."),
-                          N_("List or select an input terminal."));
-  cmd_terminal_output =
-    grub_register_command ("terminal_output", grub_cmd_terminal_output,
-                          N_("[--append|--remove] "
-                             "[TERMINAL1] [TERMINAL2] ..."),
-                          N_("List or select an output terminal."));
-}
-
-GRUB_MOD_FINI(terminal)
-{
-  grub_unregister_command (cmd_terminal_input);
-  grub_unregister_command (cmd_terminal_output);
-}
diff --git a/commands/test.c b/commands/test.c
deleted file mode 100644 (file)
index 6995165..0000000
+++ /dev/null
@@ -1,433 +0,0 @@
-/* test.c -- The test command..  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/env.h>
-#include <grub/fs.h>
-#include <grub/device.h>
-#include <grub/file.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-/* A simple implementation for signed numbers. */
-static int
-grub_strtosl (char *arg, char **end, int base)
-{
-  if (arg[0] == '-')
-    return -grub_strtoul (arg + 1, end, base);
-  return grub_strtoul (arg, end, base);
-}
-
-/* Parse a test expression starting from *argn. */
-static int
-test_parse (char **args, int *argn, int argc)
-{
-  int ret = 0, discard = 0, invert = 0;
-  int file_exists;
-  struct grub_dirhook_info file_info;
-
-  auto void update_val (int val);
-  auto void get_fileinfo (char *pathname);
-
-  /* Take care of discarding and inverting. */
-  void update_val (int val)
-  {
-    if (! discard)
-      ret = invert ? ! val : val;
-    invert = discard = 0;
-  }
-
-  /* Check if file exists and fetch its information. */
-  void get_fileinfo (char *path)
-  {
-    char *filename, *pathname;
-    char *device_name;
-    grub_fs_t fs;
-    grub_device_t dev;
-
-    /* A hook for iterating directories. */
-    auto int find_file (const char *cur_filename,
-                       const struct grub_dirhook_info *info);
-    int find_file (const char *cur_filename,
-                  const struct grub_dirhook_info *info)
-    {
-      if ((info->case_insensitive ? grub_strcasecmp (cur_filename, filename)
-          : grub_strcmp (cur_filename, filename)) == 0)
-       {
-         file_info = *info;
-         file_exists = 1;
-         return 1;
-       }
-      return 0;
-    }
-
-    file_exists = 0;
-    device_name = grub_file_get_device_name (path);
-    dev = grub_device_open (device_name);
-    if (! dev)
-      {
-       grub_free (device_name);
-       return;
-      }
-
-    fs = grub_fs_probe (dev);
-    if (! fs)
-      {
-       grub_free (device_name);
-       grub_device_close (dev);
-       return;
-      }
-
-    pathname = grub_strchr (path, ')');
-    if (! pathname)
-      pathname = path;
-    else
-      pathname++;
-
-    /* Remove trailing '/'. */
-    while (*pathname && pathname[grub_strlen (pathname) - 1] == '/')
-      pathname[grub_strlen (pathname) - 1] = 0;
-
-    /* Split into path and filename. */
-    filename = grub_strrchr (pathname, '/');
-    if (! filename)
-      {
-       path = grub_strdup ("/");
-       filename = pathname;
-      }
-    else
-      {
-       filename++;
-       path = grub_strdup (pathname);
-       path[filename - pathname] = 0;
-      }
-
-    /* It's the whole device. */
-    if (! *pathname)
-      {
-       file_exists = 1;
-       grub_memset (&file_info, 0, sizeof (file_info));
-       /* Root is always a directory. */
-       file_info.dir = 1;
-
-       /* Fetch writing time. */
-       file_info.mtimeset = 0;
-       if (fs->mtime)
-         {
-           if (! fs->mtime (dev, &file_info.mtime))
-             file_info.mtimeset = 1;
-           grub_errno = GRUB_ERR_NONE;
-         }
-      }
-    else
-      (fs->dir) (dev, path, find_file);
-
-    grub_device_close (dev);
-    grub_free (path);
-    grub_free (device_name);
-  }
-
-  /* Here we have the real parsing. */
-  while (*argn < argc)
-    {
-      /* First try 3 argument tests. */
-      if (*argn + 2 < argc)
-       {
-         /* String tests. */
-         if (grub_strcmp (args[*argn + 1], "=") == 0
-             || grub_strcmp (args[*argn + 1], "==") == 0)
-           {
-             update_val (grub_strcmp (args[*argn], args[*argn + 2]) == 0);
-             (*argn) += 3;
-             continue;
-           }
-
-         if (grub_strcmp (args[*argn + 1], "!=") == 0)
-           {
-             update_val (grub_strcmp (args[*argn], args[*argn + 2]) != 0);
-             (*argn) += 3;
-             continue;
-           }
-
-         /* GRUB extension: lexicographical sorting. */
-         if (grub_strcmp (args[*argn + 1], "<") == 0)
-           {
-             update_val (grub_strcmp (args[*argn], args[*argn + 2]) < 0);
-             (*argn) += 3;
-             continue;
-           }
-
-         if (grub_strcmp (args[*argn + 1], "<=") == 0)
-           {
-             update_val (grub_strcmp (args[*argn], args[*argn + 2]) <= 0);
-             (*argn) += 3;
-             continue;
-           }
-
-         if (grub_strcmp (args[*argn + 1], ">") == 0)
-           {
-             update_val (grub_strcmp (args[*argn], args[*argn + 2]) > 0);
-             (*argn) += 3;
-             continue;
-           }
-
-         if (grub_strcmp (args[*argn + 1], ">=") == 0)
-           {
-             update_val (grub_strcmp (args[*argn], args[*argn + 2]) >= 0);
-             (*argn) += 3;
-             continue;
-           }
-
-         /* Number tests. */
-         if (grub_strcmp (args[*argn + 1], "-eq") == 0)
-           {
-             update_val (grub_strtosl (args[*argn], 0, 0)
-                         == grub_strtosl (args[*argn + 2], 0, 0));
-             (*argn) += 3;
-             continue;
-           }
-
-         if (grub_strcmp (args[*argn + 1], "-ge") == 0)
-           {
-             update_val (grub_strtosl (args[*argn], 0, 0)
-                         >= grub_strtosl (args[*argn + 2], 0, 0));
-             (*argn) += 3;
-             continue;
-           }
-
-         if (grub_strcmp (args[*argn + 1], "-gt") == 0)
-           {
-             update_val (grub_strtosl (args[*argn], 0, 0)
-                         > grub_strtosl (args[*argn + 2], 0, 0));
-             (*argn) += 3;
-             continue;
-           }
-
-         if (grub_strcmp (args[*argn + 1], "-le") == 0)
-           {
-             update_val (grub_strtosl (args[*argn], 0, 0)
-                     <= grub_strtosl (args[*argn + 2], 0, 0));
-             (*argn) += 3;
-             continue;
-           }
-
-         if (grub_strcmp (args[*argn + 1], "-lt") == 0)
-           {
-             update_val (grub_strtosl (args[*argn], 0, 0)
-                         < grub_strtosl (args[*argn + 2], 0, 0));
-             (*argn) += 3;
-             continue;
-           }
-
-         if (grub_strcmp (args[*argn + 1], "-ne") == 0)
-           {
-             update_val (grub_strtosl (args[*argn], 0, 0)
-                         != grub_strtosl (args[*argn + 2], 0, 0));
-             (*argn) += 3;
-             continue;
-           }
-
-         /* GRUB extension: compare numbers skipping prefixes.
-            Useful for comparing versions. E.g. vmlinuz-2 -plt vmlinuz-11. */
-         if (grub_strcmp (args[*argn + 1], "-pgt") == 0
-             || grub_strcmp (args[*argn + 1], "-plt") == 0)
-           {
-             int i;
-             /* Skip common prefix. */
-             for (i = 0; args[*argn][i] == args[*argn + 2][i]
-                    && args[*argn][i]; i++);
-
-             /* Go the digits back. */
-             i--;
-             while (grub_isdigit (args[*argn][i]) && i > 0)
-               i--;
-             i++;
-
-             if (grub_strcmp (args[*argn + 1], "-pgt") == 0)
-               update_val (grub_strtoul (args[*argn] + i, 0, 0)
-                           > grub_strtoul (args[*argn + 2] + i, 0, 0));
-             else
-               update_val (grub_strtoul (args[*argn] + i, 0, 0)
-                           < grub_strtoul (args[*argn + 2] + i, 0, 0));
-             (*argn) += 3;
-             continue;
-           }
-
-         /* -nt and -ot tests. GRUB extension: when doing -?t<bias> bias
-            will be added to the first mtime. */
-         if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0
-             || grub_memcmp (args[*argn + 1], "-ot", 3) == 0)
-           {
-             struct grub_dirhook_info file1;
-             int file1exists;
-             int bias = 0;
-
-             /* Fetch fileinfo. */
-             get_fileinfo (args[*argn]);
-             file1 = file_info;
-             file1exists = file_exists;
-             get_fileinfo (args[*argn + 2]);
-
-             if (args[*argn + 1][3])
-               bias = grub_strtosl (args[*argn + 1] + 3, 0, 0);
-
-             if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0)
-               update_val ((file1exists && ! file_exists)
-                           || (file1.mtimeset && file_info.mtimeset
-                               && file1.mtime + bias > file_info.mtime));
-             else
-               update_val ((! file1exists && file_exists)
-                           || (file1.mtimeset && file_info.mtimeset
-                               && file1.mtime + bias < file_info.mtime));
-             (*argn) += 3;
-             continue;
-           }
-       }
-
-      /* Two-argument tests. */
-      if (*argn + 1 < argc)
-       {
-         /* File tests. */
-         if (grub_strcmp (args[*argn], "-d") == 0)
-           {
-             get_fileinfo (args[*argn + 1]);
-             update_val (file_exists && file_info.dir);
-             (*argn) += 2;
-             return ret;
-           }
-
-         if (grub_strcmp (args[*argn], "-e") == 0)
-           {
-             get_fileinfo (args[*argn + 1]);
-             update_val (file_exists);
-             (*argn) += 2;
-             return ret;
-           }
-
-         if (grub_strcmp (args[*argn], "-f") == 0)
-           {
-             get_fileinfo (args[*argn + 1]);
-             /* FIXME: check for other types. */
-             update_val (file_exists && ! file_info.dir);
-             (*argn) += 2;
-             return ret;
-           }
-
-         if (grub_strcmp (args[*argn], "-s") == 0)
-           {
-             grub_file_t file;
-             file = grub_file_open (args[*argn + 1]);
-             update_val (file && (grub_file_size (file) != 0));
-             if (file)
-               grub_file_close (file);
-             grub_errno = GRUB_ERR_NONE;
-             (*argn) += 2;
-             return ret;
-           }
-
-         /* String tests. */
-         if (grub_strcmp (args[*argn], "-n") == 0)
-           {
-             update_val (args[*argn + 1][0]);
-
-             (*argn) += 2;
-             continue;
-           }
-         if (grub_strcmp (args[*argn], "-z") == 0)
-           {
-             update_val (! args[*argn + 1][0]);
-             (*argn) += 2;
-             continue;
-           }
-       }
-
-      /* Special modifiers. */
-
-      /* End of expression. return to parent. */
-      if (grub_strcmp (args[*argn], ")") == 0)
-       {
-         (*argn)++;
-         return ret;
-       }
-      /* Recursively invoke if parenthesis. */
-      if (grub_strcmp (args[*argn], "(") == 0)
-       {
-         (*argn)++;
-         update_val (test_parse (args, argn, argc));
-         continue;
-       }
-
-      if (grub_strcmp (args[*argn], "!") == 0)
-       {
-         invert = ! invert;
-         (*argn)++;
-         continue;
-       }
-      if (grub_strcmp (args[*argn], "-a") == 0)
-       {
-         /* If current value is 0 second value is to be discarded. */
-         discard = ! ret;
-         (*argn)++;
-         continue;
-       }
-      if (grub_strcmp (args[*argn], "-o") == 0)
-       {
-         /* If current value is 1 second value is to be discarded. */
-         discard = ret;
-         (*argn)++;
-         continue;
-       }
-
-      /* No test found. Interpret if as just a string. */
-      update_val (args[*argn][0]);
-      (*argn)++;
-    }
-  return ret;
-}
-
-static grub_err_t
-grub_cmd_test (grub_command_t cmd __attribute__ ((unused)),
-              int argc, char **args)
-{
-  int argn = 0;
-
-  if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0)
-    argc--;
-
-  return test_parse (args, &argn, argc) ? GRUB_ERR_NONE
-    : grub_error (GRUB_ERR_TEST_FAILURE, "false");
-}
-
-static grub_command_t cmd_1, cmd_2;
-\f
-GRUB_MOD_INIT(test)
-{
-  cmd_1 = grub_register_command ("[", grub_cmd_test,
-                                N_("EXPRESSION ]"), N_("Evaluate an expression."));
-  cmd_2 = grub_register_command ("test", grub_cmd_test,
-                                N_("EXPRESSION"), N_("Evaluate an expression."));
-}
-
-GRUB_MOD_FINI(test)
-{
-  grub_unregister_command (cmd_1);
-  grub_unregister_command (cmd_2);
-}
diff --git a/commands/true.c b/commands/true.c
deleted file mode 100644 (file)
index aa81258..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* true.c - true and false commands.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-grub_cmd_true (struct grub_command *cmd __attribute__ ((unused)),
-              int argc __attribute__ ((unused)),
-              char *argv[] __attribute__ ((unused)))
-{
-  return 0;
-}
-
-static grub_err_t
-grub_cmd_false (struct grub_command *cmd __attribute__ ((unused)),
-               int argc __attribute__ ((unused)),
-               char *argv[] __attribute__ ((unused)))
-{
-  return grub_error (GRUB_ERR_TEST_FAILURE, "false");
-}
-
-static grub_command_t cmd_true, cmd_false;
-
-\f
-GRUB_MOD_INIT(true)
-{
-  cmd_true =
-    grub_register_command ("true", grub_cmd_true,
-                          0, N_("Do nothing, successfully."));
-  cmd_false =
-    grub_register_command ("false", grub_cmd_false,
-                          0, N_("Do nothing, unsuccessfully."));
-}
-
-GRUB_MOD_FINI(true)
-{
-  grub_unregister_command (cmd_true);
-  grub_unregister_command (cmd_false);
-}
diff --git a/commands/usbtest.c b/commands/usbtest.c
deleted file mode 100644 (file)
index b884a93..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/* usbtest.c - test module for USB */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/charset.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/usb.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static const char *usb_classes[] =
-  {
-    "",
-    "Audio",
-    "Communication Interface",
-    "HID",
-    "",
-    "Physical",
-    "Image",
-    "Printer",
-    "Mass Storage",
-    "Hub",
-    "Data Interface",
-    "Smart Card",
-    "Content Security",
-    "Video"
-  };
-
-static const char *usb_endp_type[] =
-  {
-    "Control",
-    "Isochronous",
-    "Bulk",
-    "Interrupt"
-  };
-
-static const char *usb_devspeed[] =
-  {
-    "",
-    "Low",
-    "Full",
-    "High"
-  };
-
-static grub_usb_err_t
-grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid,
-                    char **string)
-{
-  struct grub_usb_desc_str descstr;
-  struct grub_usb_desc_str *descstrp;
-  grub_usb_err_t err;
-
-  /* Only get the length.  */
-  err = grub_usb_control_msg (dev, 1 << 7,
-                             0x06, (3 << 8) | index,
-                             langid, 1, (char *) &descstr);
-  if (err)
-    return err;
-
-  descstrp = grub_malloc (descstr.length);
-  if (! descstrp)
-    return GRUB_USB_ERR_INTERNAL;
-  err = grub_usb_control_msg (dev, 1 << 7,
-                             0x06, (3 << 8) | index,
-                             langid, descstr.length, (char *) descstrp);
-
-  *string = grub_malloc (descstr.length / 2);
-  if (! *string)
-    {
-      grub_free (descstrp);
-      return GRUB_USB_ERR_INTERNAL;
-    }
-
-  grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, descstrp->length / 2 - 1);
-  (*string)[descstr.length / 2 - 1] = '\0';
-  grub_free (descstrp);
-
-  return GRUB_USB_ERR_NONE;
-}
-
-static void
-usb_print_str (const char *description, grub_usb_device_t dev, int idx)
-{
-  char *name;
-  grub_usb_err_t err;
-  /* XXX: LANGID  */
-
-  if (! idx)
-    return;
-
-  err = grub_usb_get_string (dev, idx, 0x0409, &name);
-  if (err)
-    grub_printf ("Error %d retrieving %s\n", err, description);
-  else
-    {
-      grub_printf ("%s: `%s'\n", description, name);
-      grub_free (name);
-    }
-}
-
-static int
-usb_iterate (grub_usb_device_t dev)
-{
-  struct grub_usb_desc_device *descdev;
-  int i;
-
-  descdev = &dev->descdev;
-
-  usb_print_str ("Product", dev, descdev->strprod);
-  usb_print_str ("Vendor", dev, descdev->strvendor);
-  usb_print_str ("Serial", dev, descdev->strserial);
-
-  if (descdev->class > 0 && descdev->class <= 0x0E)
-    grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n",
-                descdev->class, usb_classes[descdev->class],
-                descdev->subclass, descdev->protocol);
-  grub_printf ("USB version %d.%d, VendorID: 0x%02x, ProductID: 0x%02x, #conf: %d\n",
-              descdev->usbrel >> 8, (descdev->usbrel >> 4) & 0x0F,
-              descdev->vendorid, descdev->prodid, descdev->configcnt);
-
-  grub_printf ("%s speed device\n", usb_devspeed[dev->speed]);
-
-  for (i = 0; i < descdev->configcnt; i++)
-    {
-      struct grub_usb_desc_config *config;
-
-      config = dev->config[i].descconf;
-      usb_print_str ("Configuration:", dev, config->strconfig);
-    }
-
-  for (i = 0; i < dev->config[0].descconf->numif; i++)
-    {
-      int j;
-      struct grub_usb_desc_if *interf;
-      interf = dev->config[0].interf[i].descif;
-
-      grub_printf ("Interface #%d: #Endpoints: %d   ",
-                  i, interf->endpointcnt);
-      if (interf->class > 0 && interf->class <= 0x0E)
-       grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n",
-                    interf->class, usb_classes[interf->class],
-                    interf->subclass, interf->protocol);
-
-      usb_print_str ("Interface", dev, interf->strif);
-
-      for (j = 0; j < interf->endpointcnt; j++)
-       {
-         struct grub_usb_desc_endp *endp;
-         endp = &dev->config[0].interf[i].descendp[j];
-
-         grub_printf ("Endpoint #%d: %s, max packed size: %d, transfer type: %s, latency: %d\n",
-                      endp->endp_addr & 15,
-                      (endp->endp_addr & 128) ? "IN" : "OUT",
-                      endp->maxpacket, usb_endp_type[endp->attrib & 3],
-                      endp->interval);
-       }
-    }
-
-  grub_printf("\n");
-
-  return 0;
-}
-
-static grub_err_t
-grub_cmd_usbtest (grub_command_t cmd __attribute__ ((unused)),
-                 int argc __attribute__ ((unused)),
-                 char **args __attribute__ ((unused)))
-{
-  grub_printf ("USB devices:\n\n");
-  grub_usb_iterate (usb_iterate);
-
-  return 0;
-}
-
-static grub_command_t cmd;
-
-GRUB_MOD_INIT(usbtest)
-{
-  cmd = grub_register_command ("usb", grub_cmd_usbtest,
-                              0, N_("Test USB support."));
-}
-
-GRUB_MOD_FINI(usbtest)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/videotest.c b/commands/videotest.c
deleted file mode 100644 (file)
index 390811a..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/video.h>
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/font.h>
-#include <grub/term.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
-                    int argc __attribute__ ((unused)),
-                    char **args __attribute__ ((unused)))
-{
-  grub_err_t err;
-  grub_video_color_t color;
-  unsigned int x;
-  unsigned int y;
-  unsigned int width;
-  unsigned int height;
-  int i;
-  grub_font_t sansbig;
-  grub_font_t sans;
-  grub_font_t sanssmall;
-  grub_font_t fixed;
-  struct grub_font_glyph *glyph;
-  struct grub_video_render_target *text_layer;
-  grub_video_color_t palette[16];
-  const char *str;
-  int texty;
-
-  err = grub_video_set_mode ("auto", GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
-  if (err)
-    return err;
-
-  grub_video_get_viewport (&x, &y, &width, &height);
-
-  grub_video_create_render_target (&text_layer, width, height,
-                                   GRUB_VIDEO_MODE_TYPE_RGB
-                                   | GRUB_VIDEO_MODE_TYPE_ALPHA);
-
-  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
-
-  color = grub_video_map_rgb (0, 0, 0);
-  grub_video_fill_rect (color, 0, 0, width, height);
-
-  color = grub_video_map_rgb (255, 0, 0);
-  grub_video_fill_rect (color, 0, 0, 100, 100);
-
-  color = grub_video_map_rgb (0, 255, 255);
-  grub_video_fill_rect (color, 100, 100, 100, 100);
-
-  sansbig = grub_font_get ("Unknown Regular 16");
-  sans = grub_font_get ("Unknown Regular 16");
-  sanssmall = grub_font_get ("Unknown Regular 16");
-  fixed = grub_font_get ("Fixed 20");
-  if (! sansbig || ! sans || ! sanssmall || ! fixed)
-    return grub_error (GRUB_ERR_BAD_FONT, "no font loaded");
-
-  glyph = grub_font_get_glyph (fixed, '*');
-  grub_font_draw_glyph (glyph, color, 200 ,0);
-
-  grub_video_set_viewport (x + 150, y + 150,
-                           width - 150 * 2, height - 150 * 2);
-  color = grub_video_map_rgb (77, 33, 77);
-  grub_video_fill_rect (color, 0, 0, width, height);
-
-  grub_video_set_active_render_target (text_layer);
-
-  color = grub_video_map_rgb (255, 255, 255);
-
-  texty = 32;
-  grub_font_draw_string ("The quick brown fox jumped over the lazy dog.",
-                         sans, color, 16, texty);
-  texty += grub_font_get_descent (sans) + grub_font_get_leading (sans);
-
-  texty += grub_font_get_ascent (fixed);
-  grub_font_draw_string ("The quick brown fox jumped over the lazy dog.",
-                         fixed, color, 16, texty);
-  texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed);
-
-  /* To convert Unicode characters into UTF-8 for this test, the following
-     command is useful:
-       echo -ne '\x00\x00\x26\x3A' | iconv -f UTF-32BE -t UTF-8 | od -t x1
-     This converts the Unicode character U+263A to UTF-8.  */
-
-  /* Characters used:
-     Code point  Description                    UTF-8 encoding
-     ----------- ------------------------------ --------------
-     U+263A      unfilled smiley face           E2 98 BA
-     U+00A1      inverted exclamation point     C2 A1
-     U+00A3      British pound currency symbol  C2 A3
-     U+03C4      Greek tau                      CF 84
-     U+00E4      lowercase letter a with umlaut C3 A4
-     U+2124      set 'Z' symbol (integers)      E2 84 A4
-     U+2287      subset symbol                  E2 8A 87
-     U+211D      set 'R' symbol (real numbers)  E2 84 9D  */
-
-  str =
-    "Unicode test: happy\xE2\x98\xBA \xC2\xA3 5.00"
-    " \xC2\xA1\xCF\x84\xC3\xA4u! "
-    " \xE2\x84\xA4\xE2\x8A\x87\xE2\x84\x9D";
-  color = grub_video_map_rgb (128, 128, 255);
-
-  /* All characters in the string exist in the 'Fixed 20' (10x20) font.  */
-  texty += grub_font_get_ascent(fixed);
-  grub_font_draw_string (str, fixed, color, 16, texty);
-  texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed);
-
-  texty += grub_font_get_ascent(sansbig);
-  grub_font_draw_string (str, sansbig, color, 16, texty);
-  texty += grub_font_get_descent (sansbig) + grub_font_get_leading (sansbig);
-
-  texty += grub_font_get_ascent(sans);
-  grub_font_draw_string (str, sans, color, 16, texty);
-  texty += grub_font_get_descent (sans) + grub_font_get_leading (sans);
-
-  texty += grub_font_get_ascent(sanssmall);
-  grub_font_draw_string (str, sanssmall, color, 16, texty);
-  texty += (grub_font_get_descent (sanssmall)
-            + grub_font_get_leading (sanssmall));
-
-  glyph = grub_font_get_glyph (fixed, '*');
-
-  for (i = 0; i < 16; i++)
-    {
-      color = grub_video_map_color (i);
-      palette[i] = color;
-      grub_font_draw_glyph (glyph, color, 16 + i * 16, 220);
-    }
-
-  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
-
-  for (i = 0; i < 5; i++)
-    {
-      color = grub_video_map_rgb (i, 33, 77);
-      grub_video_fill_rect (color, 0, 0, width, height);
-      grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, 0, 0,
-                                     0, 0, width, height);
-      grub_video_swap_buffers ();
-    }
-
-  grub_getkey ();
-
-  grub_video_delete_render_target (text_layer);
-
-  grub_video_restore ();
-
-  for (i = 0; i < 16; i++)
-    grub_printf("color %d: %08x\n", i, palette[i]);
-
-  grub_errno = GRUB_ERR_NONE;
-  return grub_errno;
-}
-
-static grub_command_t cmd;
-
-GRUB_MOD_INIT(videotest)
-{
-  cmd = grub_register_command ("videotest", grub_cmd_videotest,
-                              0, N_("Test video subsystem."));
-}
-
-GRUB_MOD_FINI(videotest)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/commands/xnu_uuid.c b/commands/xnu_uuid.c
deleted file mode 100644 (file)
index 382d319..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/* xnu_uuid.c - transform 64-bit serial number
-   to 128-bit uuid suitable for xnu. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1995,1996,1998,1999,2001,2002,
- *                2003, 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/device.h>
-#include <grub/disk.h>
-#include <grub/fs.h>
-#include <grub/file.h>
-#include <grub/misc.h>
-#include <grub/env.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-#include <grub/crypto.h>
-
-/* This prefix is used by xnu and boot-132 to hash
-   together with volume serial. */
-static grub_uint8_t hash_prefix[16]
-  = {0xB3, 0xE2, 0x0F, 0x39, 0xF2, 0x92, 0x11, 0xD6,
-     0x97, 0xA4, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC};
-
-static grub_err_t
-grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)),
-                  int argc, char **args)
-{
-  grub_uint64_t serial;
-  grub_uint8_t *xnu_uuid;
-  char uuid_string[sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
-  char *ptr;
-  grub_uint8_t ctx[GRUB_MD_MD5->contextsize];
-
-  if (argc < 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "UUID required");
-
-  serial = grub_cpu_to_be64 (grub_strtoull (args[0], 0, 16));
-
-  GRUB_MD_MD5->init (&ctx);
-  GRUB_MD_MD5->write (&ctx, hash_prefix, sizeof (hash_prefix));
-  GRUB_MD_MD5->write (&ctx, &serial, sizeof (serial));
-  GRUB_MD_MD5->final (&ctx);
-  xnu_uuid = GRUB_MD_MD5->read (&ctx);
-
-  grub_snprintf (uuid_string, sizeof (uuid_string),
-               "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-               (unsigned int) xnu_uuid[0], (unsigned int) xnu_uuid[1],
-               (unsigned int) xnu_uuid[2], (unsigned int) xnu_uuid[3],
-               (unsigned int) xnu_uuid[4], (unsigned int) xnu_uuid[5],
-               (unsigned int) ((xnu_uuid[6] & 0xf) | 0x30),
-               (unsigned int) xnu_uuid[7],
-               (unsigned int) ((xnu_uuid[8] & 0x3f) | 0x80),
-               (unsigned int) xnu_uuid[9],
-               (unsigned int) xnu_uuid[10], (unsigned int) xnu_uuid[11],
-               (unsigned int) xnu_uuid[12], (unsigned int) xnu_uuid[13],
-               (unsigned int) xnu_uuid[14], (unsigned int) xnu_uuid[15]);
-  for (ptr = uuid_string; *ptr; ptr++)
-    *ptr = grub_toupper (*ptr);
-  if (argc == 1)
-    grub_printf ("%s", uuid_string);
-  if (argc > 1)
-    grub_env_set (args[1], uuid_string);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_command_t cmd;
-
-
-GRUB_MOD_INIT (xnu_uuid)
-{
-  cmd = grub_register_command ("xnu_uuid", grub_cmd_xnu_uuid,
-                              N_("GRUBUUID [VARNAME]"),
-                              N_("Transform 64-bit UUID to format "
-                              "suitable for XNU."));
-}
-
-GRUB_MOD_FINI (xnu_uuid)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk
deleted file mode 100644 (file)
index d1e5754..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-# -*- makefile -*-
-
-COMMON_CFLAGS += -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include)
-
-kernel_img_RELOCATABLE = yes
-pkglib_PROGRAMS = kernel.img
-kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c    \
-       kern/err.c kern/list.c kern/handler.c kern/command.c            \
-       kern/corecmd.c kern/file.c kern/fs.c kern/main.c kern/misc.c    \
-       kern/parser.c kern/partition.c kern/term.c                      \
-       kern/rescue_reader.c kern/rescue_parser.c                       \
-       \
-       util/console.c  util/grub-emu.c util/misc.c                     \
-       util/hostdisk.c util/getroot.c util/mm.c util/time.c            \
-       \
-       gnulib/progname.c util/hostfs.c disk/host.c
-kernel_img_HEADERS += datetime.h util/misc.h
-kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-undef -I$(srcdir)/gnulib
-kernel_img_LDFLAGS = $(COMMON_LDFLAGS)
-TARGET_NO_STRIP = yes
-
-ifneq ($(TARGET_NO_MODULES), yes)
-kernel_img_SOURCES += symlist.c kern/$(target_cpu)/dl.c
-ifneq ($(target_cpu), i386)
-ifneq ($(target_cpu), x86_64)
-kernel_img_SOURCES += kern/$(target_cpu)/cache.S
-endif
-endif
-else
-kernel_img_SOURCES += grub_emu_init.c
-endif
-
-# For halt.mod.
-pkglib_MODULES += halt.mod
-halt_mod_SOURCES = commands/halt.c
-halt_mod_CFLAGS = $(COMMON_CFLAGS)
-halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-ifeq ($(target_cpu), i386)
-pkglib_MODULES += cpuid.mod
-cpuid_mod_SOURCES = commands/i386/cpuid.c
-cpuid_mod_CFLAGS = $(COMMON_CFLAGS)
-cpuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
-endif
-
-grub_emu_LDFLAGS = $(LIBCURSES)
-
-ifeq ($(enable_grub_emu_usb), yes)
-kernel_img_HEADERS += libusb.h
-
-pkglib_MODULES += libusb.mod
-libusb_mod_SOURCES = util/usb.c
-libusb_mod_CFLAGS = 
-libusb_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For usb.mod
-pkglib_MODULES += usb.mod
-usb_mod_SOURCES = bus/usb/usb.c
-usb_mod_CFLAGS = $(COMMON_CFLAGS)
-usb_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For usbtest.mod
-pkglib_MODULES += usbtest.mod
-usbtest_mod_SOURCES = commands/usbtest.c
-usbtest_mod_CFLAGS = $(COMMON_CFLAGS)
-usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For usbms.mod
-pkglib_MODULES += usbms.mod
-usbms_mod_SOURCES = disk/usbms.c
-usbms_mod_CFLAGS = $(COMMON_CFLAGS)
-usbms_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-grub_emu_LDFLAGS += $(LIBUSB)
-endif
-
-ifeq ($(enable_grub_emu_sdl), yes)
-pkglib_MODULES += sdl.mod
-sdl_mod_SOURCES = util/sdl.c
-sdl_mod_CFLAGS = 
-sdl_mod_LDFLAGS = $(COMMON_LDFLAGS)
-grub_emu_LDFLAGS += $(LIBSDL)
-kernel_img_HEADERS += sdl.h
-endif
-
-ifeq ($(enable_grub_emu_pci), yes)
-pkglib_MODULES += pci.mod
-pci_mod_SOURCES = util/pci.c commands/lspci.c
-pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
-grub_emu_LDFLAGS += $(LIBPCIACCESS)
-kernel_img_HEADERS += libpciaccess.h
-endif
-
-include $(srcdir)/conf/common.mk
-
-grub_emu_init.h: genemuinitheader.sh $(pkglib_MODULES)
-       rm -f $@; echo $(pkglib_MODULES) | sh $(srcdir)/genemuinitheader.sh $(NM)  > $@
-DISTCLEANFILES += grub_emu_init.h
-
-grub_emu_init.c: genemuinit.sh $(pkglib_MODULES) grub_emu_init.h
-       rm -f $@; echo $(pkglib_MODULES) | sh $(srcdir)/genemuinit.sh $(NM) > $@
-DISTCLEANFILES += grub_emu_init.c
-
-CLEANFILES += grub-emu
-ifneq ($(TARGET_NO_MODULES), yes)
-grub-emu: $(pkglib_PROGRAMS)
-       $(CC) -o $@ $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS)
-else
-grub-emu: $(pkglib_MODULES) $(pkglib_PROGRAMS)
-       $(CC) -o $@ $(pkglib_MODULES) $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS)
-endif
-GRUB_EMU=grub-emu
-
diff --git a/conf/common.rmk b/conf/common.rmk
deleted file mode 100644 (file)
index 4b39e9b..0000000
+++ /dev/null
@@ -1,867 +0,0 @@
-# -*- makefile -*-
-
-# Used by various components.  These rules need to precede them.
-script/lexer.c_DEPENDENCIES = grub_script.tab.h
-
-sbin_UTILITIES += grub-mkdevicemap
-grub_mkdevicemap_SOURCES = gnulib/progname.c util/grub-mkdevicemap.c \
-       util/deviceiter.c \
-       util/misc.c
-
-ifeq ($(target_cpu)-$(platform), sparc64-ieee1275)
-grub_mkdevicemap_SOURCES += util/ieee1275/ofpath.c util/ieee1275/devicemap.c
-else
-grub_mkdevicemap_SOURCES += util/devicemap.c
-endif
-
-# For grub-mkelfimage.
-bin_UTILITIES += grub-mkelfimage
-grub_mkelfimage_SOURCES = gnulib/progname.c \
-       util/elf/grub-mkimage.c util/misc.c \
-       util/resolve.c
-util/elf/grub-mkimage.c_DEPENDENCIES = Makefile
-
-# For grub-probe.
-sbin_UTILITIES += grub-probe
-util/grub-probe.c_DEPENDENCIES = grub_probe_init.h
-grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c       \
-       util/hostdisk.c util/misc.c util/getroot.c util/mm.c    \
-       kern/device.c kern/disk.c kern/err.c kern/misc.c        \
-       kern/parser.c kern/partition.c kern/file.c kern/list.c  \
-       \
-       fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c         \
-       fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c  \
-       fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c       \
-       fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c           \
-       fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c             \
-       \
-       partmap/msdos.c partmap/bsdlabel.c partmap/apple.c \
-       partmap/sun.c partmap/sunpc.c partmap/gpt.c \
-       kern/fs.c kern/env.c fs/fshelp.c                        \
-       disk/raid.c disk/mdraid_linux.c disk/lvm.c grub_probe_init.c
-
-ifeq ($(enable_grub_fstest), yes)
-bin_UTILITIES += grub-fstest
-endif
-
-bin_UTILITIES += grub-mkisofs
-grub_mkisofs_SOURCES = util/mkisofs/eltorito.c                                 \
-       util/mkisofs/hash.c util/mkisofs/joliet.c                       \
-       util/mkisofs/match.c util/mkisofs/mkisofs.c                     \
-       util/mkisofs/multi.c util/mkisofs/name.c                        \
-       util/mkisofs/rock.c util/mkisofs/tree.c                         \
-       util/mkisofs/write.c                                            \
-       \
-       gnulib/fnmatch.c gnulib/getopt1.c gnulib/getopt.c               \
-       gnulib/error.c gnulib/progname.c
-grub_mkisofs_CFLAGS = -D_FILE_OFFSET_BITS=64                           \
-       -I$(srcdir)/util/mkisofs/include                                \
-       -Wno-all -Werror $(GNULIB_UTIL_CFLAGS)
-
-# For grub-fstest.
-util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h
-grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \
-       util/misc.c util/mm.c   \
-       kern/file.c kern/device.c kern/disk.c kern/err.c kern/misc.c    \
-       disk/host.c disk/loopback.c kern/list.c kern/command.c          \
-       lib/arg.c commands/extcmd.c normal/datetime.c normal/misc.c     \
-       lib/hexdump.c lib/crc.c commands/blocklist.c commands/ls.c      \
-       \
-       fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c                 \
-       fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c          \
-       fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c      \
-       fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c fs/befs.c      \
-       fs/befs_be.c fs/tar.c                   \
-       \
-       kern/partition.c partmap/msdos.c partmap/bsdlabel.c             \
-       partmap/apple.c partmap/sun.c partmap/sunpc.c partmap/gpt.c     \
-       kern/fs.c kern/env.c fs/fshelp.c disk/raid.c                    \
-       disk/raid5_recover.c disk/raid6_recover.c                       \
-       disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c             \
-       grub_fstest_init.c
-
-# For grub-mkfont.
-ifeq ($(enable_grub_mkfont), yes)
-bin_UTILITIES += grub-mkfont
-grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c
-grub_mkfont_CFLAGS = $(freetype_cflags)
-grub_mkfont_LDFLAGS = $(freetype_libs)
-endif
-
-# For grub-mkrelpath.
-bin_UTILITIES += grub-mkrelpath
-grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c
-
-bin_UTILITIES += grub-bin2h
-grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c
-
-# For the lexer.
-grub_script.yy.c grub_script.yy.h: script/yylex.l
-       $(LEX) -o grub_script.yy.c --header-file=grub_script.yy.h $(srcdir)/script/yylex.l
-DISTCLEANFILES += grub_script.yy.c grub_script.yy.h
-
-# For grub-script-check.
-bin_UTILITIES += grub-script-check
-util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h
-grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c \
-       util/grub-script-check.c util/misc.c util/mm.c \
-       script/main.c script/script.c script/function.c script/lexer.c \
-       kern/handler.c kern/err.c kern/parser.c kern/list.c \
-       kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \
-       grub_script.yy.c
-grub_script_check_CFLAGS = $(GNULIB_UTIL_CFLAGS)
-MOSTLYCLEANFILES += symlist.c kernel_syms.lst
-DEFSYMFILES += kernel_syms.lst
-
-kernel_img_HEADERS += 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 msdos_partition.h reader.h symbol.h term.h time.h types.h \
-       list.h handler.h command.h i18n.h env_private.h libgcc.h
-
-ifneq ($(platform), emu)
-kernel_img_HEADERS += machine/memory.h machine/loader.h machine/kernel.h
-endif
-
-symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
-       /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
-
-kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh
-       /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
-
-# For the parser.
-grub_script.tab.c grub_script.tab.h: script/parser.y
-       $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y
-DISTCLEANFILES += grub_script.tab.c grub_script.tab.h
-
-# For grub-script-check.
-grub_script_check_init.lst: geninit.sh $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES))
-       rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
-DISTCLEANFILES += grub_script_check_init.lst
-
-grub_script_check_init.h: grub_script_check_init.lst $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) geninitheader.sh
-       rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
-DISTCLEANFILES += grub_script_check_init.h
-
-grub_script_check_init.c: grub_script_check_init.lst $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) geninit.sh
-       rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
-DISTCLEANFILES += grub_script_check_init.c
-
-# For grub-probe.
-grub_probe_init.lst: geninit.sh $(filter-out grub_probe_init.c,$(grub_probe_SOURCES))
-       rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
-DISTCLEANFILES += grub_probe_init.lst
-
-grub_probe_init.h: grub_probe_init.lst $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) geninitheader.sh
-       rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
-DISTCLEANFILES += grub_probe_init.h
-
-grub_probe_init.c: grub_probe_init.lst $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) geninit.sh grub_probe_init.h
-       rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
-DISTCLEANFILES += grub_probe_init.c
-
-# For grub-setup.
-grub_setup_init.lst: geninit.sh $(filter-out grub_setup_init.c,$(grub_setup_SOURCES))
-       rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
-DISTCLEANFILES += grub_setup_init.lst
-
-grub_setup_init.h: grub_setup_init.lst $(filter-out grub_setup_init.c,$(grub_setup_SOURCES)) geninitheader.sh
-       rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
-DISTCLEANFILES += grub_setup_init.h
-
-grub_setup_init.c: grub_setup_init.lst $(filter-out grub_setup_init.c,$(grub_setup_SOURCES)) geninit.sh grub_setup_init.h
-       rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
-DISTCLEANFILES += grub_setup_init.c
-
-# For grub-fstest.
-grub_fstest_init.lst: geninit.sh $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES))
-       rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
-DISTCLEANFILES += grub_fstest_init.lst
-
-grub_fstest_init.h: grub_fstest_init.lst $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES)) geninitheader.sh
-       rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
-DISTCLEANFILES += grub_fstest_init.h
-
-grub_fstest_init.c: grub_fstest_init.lst $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES)) geninit.sh grub_fstest_init.h
-       rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
-DISTCLEANFILES += grub_fstest_init.c
-
-# for grub-editenv
-bin_UTILITIES += grub-editenv
-grub_editenv_SOURCES = gnulib/progname.c util/grub-editenv.c lib/envblk.c util/misc.c util/mm.c kern/misc.c kern/err.c
-CLEANFILES += grub-editenv
-
-# Needed for genmk.rb to work
-ifeq (0,1)
-bin_UTILITIES += grub-macho2img grub-pe2elf
-endif
-
-grub_pe2elf_SOURCES = gnulib/progname.c util/grub-pe2elf.c util/misc.c
-CLEANFILES += grub-pe2elf
-
-grub_macho2img_SOURCES = util/grub-macho2img.c
-CLEANFILES += grub-macho2img
-
-# For grub-mkconfig
-grub-mkconfig: util/grub-mkconfig.in config.status
-       ./config.status --file=$@:$<
-       chmod +x $@
-sbin_SCRIPTS += grub-mkconfig
-CLEANFILES += grub-mkconfig
-
-grub-mkconfig_lib: util/grub-mkconfig_lib.in config.status
-       ./config.status --file=$@:$<
-       chmod +x $@
-lib_SCRIPTS += grub-mkconfig_lib
-CLEANFILES += grub-mkconfig_lib
-
-update-grub_lib: util/update-grub_lib.in config.status
-       ./config.status --file=$@:$<
-       chmod +x $@
-lib_SCRIPTS += update-grub_lib
-CLEANFILES += update-grub_lib
-
-grub-gettext_lib: util/grub-gettext_lib.in config.status
-       ./config.status --file=$@:$<
-       chmod +x $@
-lib_DATA += grub-gettext_lib
-CLEANFILES += grub-gettext_lib
-
-%: util/grub.d/%.in config.status
-       ./config.status --file=$@:$<
-       chmod +x $@
-grub-mkconfig_SCRIPTS = 00_header 30_os-prober 40_custom
-ifneq (, $(host_kernel))
-grub-mkconfig_SCRIPTS += 10_$(host_kernel)
-endif
-
-CLEANFILES += $(grub-mkconfig_SCRIPTS)
-
-grub-mkconfig_DATA += util/grub.d/README
-
-# For grub-set-default.
-grub-set-default: util/grub-set-default.in config.status
-       ./config.status --file=$@:$<
-       chmod +x $@
-sbin_SCRIPTS += grub-set-default
-CLEANFILES += grub-set-default
-
-# For grub-reboot.
-grub-reboot: util/grub-reboot.in config.status
-       ./config.status --file=$@:$<
-       chmod +x $@
-sbin_SCRIPTS += grub-reboot
-CLEANFILES += grub-reboot
-
-# Filing systems.
-pkglib_MODULES += fshelp.mod fat.mod ufs1.mod ufs2.mod ext2.mod ntfs.mod \
-       ntfscomp.mod minix.mod hfs.mod jfs.mod iso9660.mod xfs.mod      \
-       affs.mod sfs.mod hfsplus.mod reiserfs.mod cpio.mod tar.mod      \
-       udf.mod afs.mod afs_be.mod befs.mod befs_be.mod
-
-# For fshelp.mod.
-fshelp_mod_SOURCES = fs/fshelp.c
-fshelp_mod_CFLAGS = $(COMMON_CFLAGS)
-fshelp_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For fat.mod.
-fat_mod_SOURCES = fs/fat.c
-fat_mod_CFLAGS = $(COMMON_CFLAGS)
-fat_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For ufs1.mod.
-ufs1_mod_SOURCES = fs/ufs.c
-ufs1_mod_CFLAGS = $(COMMON_CFLAGS)
-ufs1_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For ufs2.mod.
-ufs2_mod_SOURCES = fs/ufs2.c
-ufs2_mod_CFLAGS = $(COMMON_CFLAGS)
-ufs2_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For ext2.mod.
-ext2_mod_SOURCES = fs/ext2.c
-ext2_mod_CFLAGS = $(COMMON_CFLAGS)
-ext2_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For ntfs.mod.
-ntfs_mod_SOURCES = fs/ntfs.c
-ntfs_mod_CFLAGS = $(COMMON_CFLAGS)
-ntfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For ntfscomp.mod.
-ntfscomp_mod_SOURCES = fs/ntfscomp.c
-ntfscomp_mod_CFLAGS = $(COMMON_CFLAGS)
-ntfscomp_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For minix.mod.
-minix_mod_SOURCES = fs/minix.c
-minix_mod_CFLAGS = $(COMMON_CFLAGS)
-minix_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For nilfs2.mod.
-pkglib_MODULES += nilfs2.mod
-nilfs2_mod_SOURCES = fs/nilfs2.c
-nilfs2_mod_CFLAGS = $(COMMON_CFLAGS)
-nilfs2_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For hfs.mod.
-hfs_mod_SOURCES = fs/hfs.c
-hfs_mod_CFLAGS = $(COMMON_CFLAGS)
-hfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For jfs.mod.
-jfs_mod_SOURCES = fs/jfs.c
-jfs_mod_CFLAGS = $(COMMON_CFLAGS)
-jfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For iso9660.mod.
-iso9660_mod_SOURCES = fs/iso9660.c
-iso9660_mod_CFLAGS = $(COMMON_CFLAGS)
-iso9660_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For xfs.mod.
-xfs_mod_SOURCES = fs/xfs.c
-xfs_mod_CFLAGS = $(COMMON_CFLAGS)
-xfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For affs.mod.
-affs_mod_SOURCES = fs/affs.c
-affs_mod_CFLAGS = $(COMMON_CFLAGS)
-affs_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For sfs.mod.
-sfs_mod_SOURCES = fs/sfs.c
-sfs_mod_CFLAGS = $(COMMON_CFLAGS)
-sfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For hfsplus.mod.
-hfsplus_mod_SOURCES = fs/hfsplus.c
-hfsplus_mod_CFLAGS = $(COMMON_CFLAGS)
-hfsplus_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For reiserfs.mod.
-reiserfs_mod_SOURCES = fs/reiserfs.c
-reiserfs_mod_CFLAGS = $(COMMON_CFLAGS)
-reiserfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For cpio.mod.
-cpio_mod_SOURCES = fs/cpio.c
-cpio_mod_CFLAGS = $(COMMON_CFLAGS)
-cpio_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For tar.mod.
-tar_mod_SOURCES = fs/tar.c
-tar_mod_CFLAGS = $(COMMON_CFLAGS)
-tar_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For udf.mod.
-udf_mod_SOURCES = fs/udf.c
-udf_mod_CFLAGS = $(COMMON_CFLAGS)
-udf_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For afs.mod.
-afs_mod_SOURCES = fs/afs.c
-afs_mod_CFLAGS = $(COMMON_CFLAGS)
-afs_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For afs_be.mod.
-afs_be_mod_SOURCES = fs/afs_be.c
-afs_be_mod_CFLAGS = $(COMMON_CFLAGS)
-afs_be_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For befs.mod.
-befs_mod_SOURCES = fs/befs.c
-befs_mod_CFLAGS = $(COMMON_CFLAGS)
-befs_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For befs_be.mod.
-befs_be_mod_SOURCES = fs/befs_be.c
-befs_be_mod_CFLAGS = $(COMMON_CFLAGS)
-befs_be_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# Partition maps.
-
-pkglib_MODULES += part_amiga.mod
-part_amiga_mod_SOURCES = partmap/amiga.c
-part_amiga_mod_CFLAGS = $(COMMON_CFLAGS)
-part_amiga_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += part_apple.mod
-part_apple_mod_SOURCES = partmap/apple.c
-part_apple_mod_CFLAGS = $(COMMON_CFLAGS)
-part_apple_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += part_msdos.mod
-part_msdos_mod_SOURCES = partmap/msdos.c
-part_msdos_mod_CFLAGS = $(COMMON_CFLAGS)
-part_msdos_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += part_sun.mod
-part_sun_mod_SOURCES = partmap/sun.c
-part_sun_mod_CFLAGS = $(COMMON_CFLAGS)
-part_sun_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += part_acorn.mod
-part_acorn_mod_SOURCES = partmap/acorn.c
-part_acorn_mod_CFLAGS = $(COMMON_CFLAGS)
-part_acorn_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += part_gpt.mod
-part_gpt_mod_SOURCES = partmap/gpt.c
-part_gpt_mod_CFLAGS = $(COMMON_CFLAGS)
-part_gpt_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += part_bsd.mod
-part_bsd_mod_SOURCES = partmap/bsdlabel.c
-part_bsd_mod_CFLAGS = $(COMMON_CFLAGS)
-part_bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += part_sunpc.mod
-part_sunpc_mod_SOURCES = partmap/sunpc.c
-part_sunpc_mod_CFLAGS = $(COMMON_CFLAGS)
-part_sunpc_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# Special disk structures and generic drivers
-
-pkglib_MODULES += raid.mod raid5rec.mod raid6rec.mod mdraid.mod dm_nv.mod \
-       lvm.mod scsi.mod
-
-# For raid.mod
-raid_mod_SOURCES = disk/raid.c
-raid_mod_CFLAGS = $(COMMON_CFLAGS)
-raid_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For raid5rec.mod
-raid5rec_mod_SOURCES = disk/raid5_recover.c
-raid5rec_mod_CFLAGS = $(COMMON_CFLAGS)
-raid5rec_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For raid6rec.mod
-raid6rec_mod_SOURCES = disk/raid6_recover.c
-raid6rec_mod_CFLAGS = $(COMMON_CFLAGS)
-raid6rec_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For mdraid.mod
-mdraid_mod_SOURCES = disk/mdraid_linux.c
-mdraid_mod_CFLAGS = $(COMMON_CFLAGS)
-mdraid_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For dm_nv.mod
-dm_nv_mod_SOURCES = disk/dmraid_nvidia.c
-dm_nv_mod_CFLAGS = $(COMMON_CFLAGS)
-dm_nv_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For lvm.mod
-lvm_mod_SOURCES = disk/lvm.c
-lvm_mod_CFLAGS = $(COMMON_CFLAGS)
-lvm_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For scsi.mod
-scsi_mod_SOURCES = disk/scsi.c
-scsi_mod_CFLAGS = $(COMMON_CFLAGS)
-scsi_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# Commands.
-pkglib_MODULES += minicmd.mod extcmd.mod hello.mod handler.mod \
-       ls.mod cmp.mod cat.mod help.mod search.mod loopback.mod \
-       configfile.mod echo.mod         \
-       terminfo.mod test.mod blocklist.mod hexdump.mod         \
-       read.mod sleep.mod loadenv.mod crc.mod parttool.mod     \
-       msdospart.mod memrw.mod normal.mod sh.mod               \
-       gptsync.mod true.mod probe.mod password.mod             \
-       keystatus.mod
-
-# For password.mod.
-password_mod_SOURCES = commands/password.c
-password_mod_CFLAGS = $(COMMON_CFLAGS)
-password_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For gptsync.mod.
-gptsync_mod_SOURCES = commands/gptsync.c
-gptsync_mod_CFLAGS = $(COMMON_CFLAGS)
-gptsync_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For minicmd.mod.
-minicmd_mod_SOURCES = commands/minicmd.c
-minicmd_mod_CFLAGS = $(COMMON_CFLAGS)
-minicmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For extcmd.mod.
-extcmd_mod_SOURCES = commands/extcmd.c lib/arg.c
-extcmd_mod_CFLAGS = $(COMMON_CFLAGS)
-extcmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For hello.mod.
-hello_mod_SOURCES = hello/hello.c
-hello_mod_CFLAGS = $(COMMON_CFLAGS)
-hello_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For gfxmenu.mod.
-pkglib_MODULES += gfxmenu.mod
-gfxmenu_mod_SOURCES = \
-       gfxmenu/gfxmenu.c \
-       gfxmenu/model.c \
-       gfxmenu/view.c \
-       gfxmenu/icon_manager.c \
-       gfxmenu/theme_loader.c \
-       gfxmenu/widget-box.c \
-       gfxmenu/gui_canvas.c \
-       gfxmenu/gui_circular_progress.c \
-       gfxmenu/gui_box.c \
-       gfxmenu/gui_label.c \
-       gfxmenu/gui_list.c \
-       gfxmenu/gui_image.c \
-       gfxmenu/gui_progress_bar.c \
-       gfxmenu/gui_util.c \
-       gfxmenu/gui_string_util.c \
-       gfxmenu/named_colors.c
-gfxmenu_mod_CFLAGS = $(COMMON_CFLAGS)
-gfxmenu_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For parttool.mod.
-parttool_mod_SOURCES = commands/parttool.c
-parttool_mod_CFLAGS = $(COMMON_CFLAGS)
-parttool_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For msdospart.mod.
-msdospart_mod_SOURCES = parttool/msdospart.c
-msdospart_mod_CFLAGS = $(COMMON_CFLAGS)
-msdospart_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For handler.mod.
-handler_mod_SOURCES = commands/handler.c
-handler_mod_CFLAGS = $(COMMON_CFLAGS)
-handler_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For ls.mod.
-ls_mod_SOURCES = commands/ls.c
-ls_mod_CFLAGS = $(COMMON_CFLAGS)
-ls_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For cmp.mod.
-cmp_mod_SOURCES = commands/cmp.c
-cmp_mod_CFLAGS = $(COMMON_CFLAGS)
-cmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For cat.mod.
-cat_mod_SOURCES = commands/cat.c
-cat_mod_CFLAGS = $(COMMON_CFLAGS)
-cat_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For echo.mod
-echo_mod_SOURCES = commands/echo.c
-echo_mod_CFLAGS = $(COMMON_CFLAGS)
-echo_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For help.mod.
-help_mod_SOURCES = commands/help.c
-help_mod_CFLAGS = $(COMMON_CFLAGS)
-help_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For search.mod.
-search_mod_SOURCES = commands/search_wrap.c
-search_mod_CFLAGS = $(COMMON_CFLAGS)
-search_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += search_fs_file.mod search_fs_uuid.mod search_label.mod
-
-# For search.mod.
-search_fs_file_mod_SOURCES = commands/search_file.c
-search_fs_file_mod_CFLAGS = $(COMMON_CFLAGS)
-search_fs_file_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For search.mod.
-search_label_mod_SOURCES = commands/search_label.c
-search_label_mod_CFLAGS = $(COMMON_CFLAGS)
-search_label_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For search.mod.
-search_fs_uuid_mod_SOURCES = commands/search_uuid.c
-search_fs_uuid_mod_CFLAGS = $(COMMON_CFLAGS)
-search_fs_uuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For test.mod.
-test_mod_SOURCES = commands/test.c
-test_mod_CFLAGS = $(COMMON_CFLAGS)
-test_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For loopback.mod
-loopback_mod_SOURCES = disk/loopback.c
-loopback_mod_CFLAGS = $(COMMON_CFLAGS)
-loopback_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For configfile.mod
-configfile_mod_SOURCES = commands/configfile.c
-configfile_mod_CFLAGS = $(COMMON_CFLAGS)
-configfile_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For terminfo.mod.
-terminfo_mod_SOURCES = term/terminfo.c term/tparm.c
-terminfo_mod_CFLAGS = $(COMMON_CFLAGS)
-terminfo_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For blocklist.mod.
-blocklist_mod_SOURCES = commands/blocklist.c
-blocklist_mod_CFLAGS = $(COMMON_CFLAGS)
-blocklist_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For hexdump.mod.
-hexdump_mod_SOURCES = commands/hexdump.c lib/hexdump.c
-hexdump_mod_CFLAGS = $(COMMON_CFLAGS)
-hexdump_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For read.mod.
-read_mod_SOURCES = commands/read.c
-read_mod_CFLAGS = $(COMMON_CFLAGS)
-read_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For sleep.mod.
-sleep_mod_SOURCES = commands/sleep.c
-sleep_mod_CFLAGS = $(COMMON_CFLAGS)
-sleep_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For loadenv.mod.
-loadenv_mod_SOURCES = commands/loadenv.c lib/envblk.c
-loadenv_mod_CFLAGS = $(COMMON_CFLAGS)
-loadenv_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For crc.mod.
-crc_mod_SOURCES = commands/crc.c lib/crc.c
-crc_mod_CFLAGS = $(COMMON_CFLAGS)
-crc_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For memrw.mod.
-memrw_mod_SOURCES = commands/memrw.c
-memrw_mod_CFLAGS = $(COMMON_CFLAGS)
-memrw_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For true.mod
-true_mod_SOURCES = commands/true.c
-true_mod_CFLAGS = $(COMMON_CFLAGS)
-true_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For probe.mod.
-probe_mod_SOURCES = commands/probe.c
-probe_mod_CFLAGS = $(COMMON_CFLAGS)
-probe_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For keystatus.mod.
-keystatus_mod_SOURCES = commands/keystatus.c
-keystatus_mod_CFLAGS = $(COMMON_CFLAGS)
-keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For normal.mod.
-normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
-       normal/auth.c normal/autofs.c normal/handler.c \
-       normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
-       normal/menu_entry.c normal/menu_text.c \
-       normal/misc.c normal/crypto.c normal/term.c normal/context.c
-normal_mod_CFLAGS = $(COMMON_CFLAGS)
-normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For sh.mod.
-sh_mod_SOURCES = script/main.c script/script.c script/execute.c \
-       script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c
-sh_mod_CFLAGS = $(COMMON_CFLAGS) $(POSIX_CFLAGS) -Wno-error
-sh_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-ifneq (, $(FONT_SOURCE))
-font/font.c_DEPENDENCIES = ascii.h
-endif
-
-# Common Video Subsystem specific modules.
-# On Yeeloong it's part of kernel
-ifneq ($(platform), yeeloong)
-
-# For video.mod.
-pkglib_MODULES += video.mod
-video_mod_SOURCES = video/video.c
-video_mod_CFLAGS = $(COMMON_CFLAGS)
-video_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += video_fb.mod
-video_fb_mod_SOURCES = video/fb/video_fb.c video/fb/fbblit.c \
-                 video/fb/fbfill.c video/fb/fbutil.c
-video_fb_mod_CFLAGS = $(COMMON_CFLAGS)
-video_fb_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For bitmap.mod
-pkglib_MODULES += bitmap.mod
-bitmap_mod_SOURCES = video/bitmap.c
-bitmap_mod_CFLAGS = $(COMMON_CFLAGS)
-bitmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For bitmap_scale.mod
-pkglib_MODULES += bitmap_scale.mod
-bitmap_scale_mod_SOURCES = video/bitmap_scale.c
-bitmap_scale_mod_CFLAGS = $(COMMON_CFLAGS)
-bitmap_scale_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += font.mod
-font_mod_SOURCES = font/font_cmd.c font/font.c
-font_mod_CFLAGS = $(COMMON_CFLAGS)
-font_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For gfxterm.mod.
-pkglib_MODULES += gfxterm.mod
-gfxterm_mod_SOURCES = term/gfxterm.c
-gfxterm_mod_CFLAGS = $(COMMON_CFLAGS)
-gfxterm_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-endif
-
-# For videotest.mod.
-pkglib_MODULES += videotest.mod
-videotest_mod_SOURCES = commands/videotest.c
-videotest_mod_CFLAGS = $(COMMON_CFLAGS)
-videotest_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For tga.mod
-pkglib_MODULES += tga.mod
-tga_mod_SOURCES = video/readers/tga.c
-tga_mod_CFLAGS = $(COMMON_CFLAGS)
-tga_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For jpeg.mod.
-pkglib_MODULES += jpeg.mod
-jpeg_mod_SOURCES = video/readers/jpeg.c
-jpeg_mod_CFLAGS = $(COMMON_CFLAGS)
-jpeg_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For png.mod.
-pkglib_MODULES += png.mod
-png_mod_SOURCES = video/readers/png.c
-png_mod_CFLAGS = $(COMMON_CFLAGS)
-png_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-
-# Misc.
-pkglib_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
-gzio_mod_CFLAGS = $(COMMON_CFLAGS)
-gzio_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# On Yeeloong it's part of kernel
-ifneq ($(platform), yeeloong)
-# For bufio.mod.
-pkglib_MODULES += bufio.mod
-bufio_mod_SOURCES = io/bufio.c
-bufio_mod_CFLAGS = $(COMMON_CFLAGS)
-bufio_mod_LDFLAGS = $(COMMON_LDFLAGS)
-endif
-
-# For gettext.mod.
-pkglib_MODULES += gettext.mod
-gettext_mod_SOURCES = gettext/gettext.c
-gettext_mod_CFLAGS = $(COMMON_CFLAGS)
-gettext_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# Misc.
-pkglib_MODULES += xnu_uuid.mod
-
-# For elf.mod.
-xnu_uuid_mod_SOURCES = commands/xnu_uuid.c
-xnu_uuid_mod_CFLAGS = $(COMMON_CFLAGS)
-xnu_uuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += trig.mod
-trig_mod_SOURCES = trigtables.c
-trig_mod_CFLAGS = $(COMMON_CFLAGS)
-trig_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-trigtables.c: gentrigtables
-       ./gentrigtables > $@
-DISTCLEANFILES += trigtables.c
-gentrigtables: gentrigtables.c
-       $(CC) -o $@ $^ $(CPPFLAGS) -lm
-DISTCLEANFILES += gentrigtables
-
-pkglib_MODULES += setjmp.mod
-setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S
-setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS)
-setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += charset.mod
-charset_mod_SOURCES = lib/charset.c
-charset_mod_CFLAGS = $(COMMON_CFLAGS)
-charset_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += regexp.mod
-regexp_mod_SOURCES = gnulib/regex.c commands/regexp.c
-regexp_mod_CFLAGS = $(COMMON_CFLAGS) $(GNULIB_CFLAGS)
-regexp_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += terminal.mod
-terminal_mod_SOURCES = commands/terminal.c
-terminal_mod_CFLAGS = $(COMMON_CFLAGS)
-terminal_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += crypto.mod
-crypto_mod_SOURCES = lib/crypto.c
-crypto_mod_CFLAGS = $(COMMON_CFLAGS)
-crypto_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += hashsum.mod
-hashsum_mod_SOURCES = commands/hashsum.c
-hashsum_mod_CFLAGS = $(COMMON_CFLAGS)
-hashsum_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += pbkdf2.mod
-pbkdf2_mod_SOURCES = lib/pbkdf2.c
-pbkdf2_mod_CFLAGS = $(COMMON_CFLAGS)
-pbkdf2_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For password_pbkdf2.mod.
-pkglib_MODULES += password_pbkdf2.mod
-password_pbkdf2_mod_SOURCES = commands/password_pbkdf2.c
-password_pbkdf2_mod_CFLAGS = $(COMMON_CFLAGS)
-password_pbkdf2_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For memdisk.mod.
-pkglib_MODULES += memdisk.mod
-memdisk_mod_SOURCES = disk/memdisk.c
-memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
-memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For reboot.mod.
-pkglib_MODULES += reboot.mod
-reboot_mod_SOURCES = commands/reboot.c
-reboot_mod_CFLAGS = $(COMMON_CFLAGS)
-reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For date.mod
-pkglib_MODULES += date.mod
-date_mod_SOURCES = commands/date.c
-date_mod_CFLAGS = $(COMMON_CFLAGS)
-date_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For datehook.mod
-pkglib_MODULES += datehook.mod
-datehook_mod_SOURCES = hook/datehook.c
-datehook_mod_CFLAGS = $(COMMON_CFLAGS)
-datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For lsmmap.mod
-pkglib_MODULES += lsmmap.mod
-lsmmap_mod_SOURCES = commands/lsmmap.c
-lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
-lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For boot.mod.
-pkglib_MODULES += boot.mod
-boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
-boot_mod_CFLAGS = $(COMMON_CFLAGS)
-boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-bin_UTILITIES += grub-mkpasswd-pbkdf2
-grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c util/mm.c kern/err.c
-grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap -DGRUB_MKPASSWD=1
-
-include $(srcdir)/conf/gcry.mk
diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk
deleted file mode 100644 (file)
index ca96963..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-# -*- makefile -*-
-
-COMMON_CFLAGS = -mrtd -mregparm=3 
-
-# Images.
-
-GRUB_KERNEL_MACHINE_LINK_ADDR  = 0x8200
-
-pkglib_PROGRAMS += kernel.img
-kernel_img_SOURCES = kern/i386/coreboot/startup.S \
-       kern/i386/misc.S \
-       kern/i386/coreboot/init.c \
-       kern/i386/coreboot/mmap.c \
-       kern/i386/halt.c \
-       kern/main.c kern/device.c \
-       kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
-       kern/misc.c kern/mm.c kern/term.c \
-       kern/rescue_parser.c kern/rescue_reader.c \
-       kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
-       kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
-       kern/i386/tsc.c kern/i386/pit.c \
-       kern/generic/rtc_get_time_ms.c \
-       kern/generic/millisleep.c \
-       kern/env.c \
-       term/i386/pc/vga_text.c term/i386/vga_common.c \
-       symlist.c
-kernel_img_CFLAGS = $(COMMON_CFLAGS)
-kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
-kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic
-
-sbin_SCRIPTS += grub-install
-grub_install_SOURCES = util/grub-install.in
-
-bin_SCRIPTS += grub-mkrescue
-grub_mkrescue_SOURCES = util/grub-mkrescue.in
-
-# Modules.
-pkglib_MODULES = linux.mod aout.mod halt.mod datetime.mod mmap.mod
-
-# For mmap.mod.
-mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
-mmap_mod_CFLAGS = $(COMMON_CFLAGS)
-mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-# For linux.mod.
-linux_mod_SOURCES = loader/i386/linux.c
-linux_mod_CFLAGS = $(COMMON_CFLAGS)
-linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For halt.mod.
-halt_mod_SOURCES = commands/halt.c
-halt_mod_CFLAGS = $(COMMON_CFLAGS)
-halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For aout.mod.
-aout_mod_SOURCES = loader/aout.c
-aout_mod_CFLAGS = $(COMMON_CFLAGS)
-aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For bsd.mod
-pkglib_MODULES += bsd.mod
-bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S
-bsd_mod_CFLAGS = $(COMMON_CFLAGS)
-bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
-bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-# For datetime.mod
-datetime_mod_SOURCES = lib/cmos_datetime.c
-datetime_mod_CFLAGS = $(COMMON_CFLAGS)
-datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-include $(srcdir)/conf/i386.mk
-include $(srcdir)/conf/common.mk
diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk
deleted file mode 100644 (file)
index e826cb3..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# -*- makefile -*-
-
-COMMON_LDFLAGS = -melf_i386
-
-include $(srcdir)/conf/x86-efi.mk
diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk
deleted file mode 100644 (file)
index 05ba38a..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-# -*- makefile -*-
-
-COMMON_CFLAGS  = -mrtd -mregparm=3
-
-# Images.
-pkglib_PROGRAMS = kernel.img
-
-# For kernel.img.
-kernel_img_SOURCES = kern/i386/ieee1275/startup.S \
-       kern/i386/misc.S \
-       kern/i386/ieee1275/init.c \
-       kern/ieee1275/init.c \
-       kern/ieee1275/mmap.c \
-       kern/ieee1275/cmain.c kern/ieee1275/openfw.c \
-       kern/main.c kern/device.c \
-       kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
-       kern/misc.c kern/mm.c kern/term.c \
-       kern/rescue_parser.c kern/rescue_reader.c \
-       kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
-       kern/env.c \
-       kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
-       kern/generic/millisleep.c \
-       kern/ieee1275/ieee1275.c \
-       term/ieee1275/ofconsole.c \
-       disk/ieee1275/ofdisk.c \
-       symlist.c
-kernel_img_HEADERS += ieee1275/ieee1275.h
-kernel_img_CFLAGS = $(COMMON_CFLAGS)
-kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
-kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic
-
-# Scripts.
-sbin_SCRIPTS = grub-install
-
-# For grub-install.
-grub_install_SOURCES = util/ieee1275/grub-install.in
-
-# Modules.
-pkglib_MODULES = halt.mod suspend.mod          \
-       aout.mod linux.mod      \
-       nand.mod datetime.mod   \
-       mmap.mod
-
-# For mmap.mod.
-mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
-mmap_mod_CFLAGS = $(COMMON_CFLAGS)
-mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-# For aout.mod.
-aout_mod_SOURCES = loader/aout.c
-aout_mod_CFLAGS = $(COMMON_CFLAGS)
-aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For suspend.mod
-suspend_mod_SOURCES = commands/ieee1275/suspend.c
-suspend_mod_CFLAGS = $(COMMON_CFLAGS)
-suspend_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For halt.mod
-halt_mod_SOURCES = commands/halt.c
-halt_mod_CFLAGS = $(COMMON_CFLAGS)
-halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For linux.mod.
-linux_mod_SOURCES = loader/i386/ieee1275/linux.c
-linux_mod_CFLAGS = $(COMMON_CFLAGS)
-linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For nand.mod.
-nand_mod_SOURCES = disk/ieee1275/nand.c
-nand_mod_CFLAGS = $(COMMON_CFLAGS)
-nand_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For datetime.mod
-datetime_mod_SOURCES = lib/cmos_datetime.c
-datetime_mod_CFLAGS = $(COMMON_CFLAGS)
-datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-include $(srcdir)/conf/i386.mk
-include $(srcdir)/conf/common.mk
diff --git a/conf/i386-multiboot.rmk b/conf/i386-multiboot.rmk
deleted file mode 100644 (file)
index 69b8e9a..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-# -*- makefile -*-
-
-COMMON_CFLAGS = -mrtd -mregparm=3 
-
-# Images.
-
-GRUB_KERNEL_MACHINE_LINK_ADDR  = 0x8200
-
-pkglib_PROGRAMS += kernel.img
-kernel_img_SOURCES = kern/i386/coreboot/startup.S \
-       kern/i386/misc.S \
-       kern/i386/coreboot/init.c \
-       kern/i386/multiboot_mmap.c \
-       kern/i386/halt.c \
-       kern/main.c kern/device.c \
-       kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
-       kern/misc.c kern/mm.c kern/term.c \
-       kern/rescue_parser.c kern/rescue_reader.c \
-       kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
-       kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
-       kern/i386/tsc.c kern/i386/pit.c \
-       kern/generic/rtc_get_time_ms.c \
-       kern/generic/millisleep.c \
-       kern/env.c \
-       term/i386/pc/vga_text.c term/i386/vga_common.c \
-       symlist.c
-kernel_img_CFLAGS = $(COMMON_CFLAGS)
-kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
-kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic
-
-sbin_SCRIPTS += grub-install
-grub_install_SOURCES = util/grub-install.in
-
-bin_SCRIPTS += grub-mkrescue
-grub_mkrescue_SOURCES = util/grub-mkrescue.in
-
-# Modules.
-pkglib_MODULES = linux.mod aout.mod halt.mod datetime.mod mmap.mod
-
-# For mmap.mod.
-mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
-mmap_mod_CFLAGS = $(COMMON_CFLAGS)
-mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-# For linux.mod.
-linux_mod_SOURCES = loader/i386/linux.c
-linux_mod_CFLAGS = $(COMMON_CFLAGS)
-linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For halt.mod.
-halt_mod_SOURCES = commands/halt.c
-halt_mod_CFLAGS = $(COMMON_CFLAGS)
-halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For aout.mod.
-aout_mod_SOURCES = loader/aout.c
-aout_mod_CFLAGS = $(COMMON_CFLAGS)
-aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For bsd.mod
-pkglib_MODULES += bsd.mod
-bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S
-bsd_mod_CFLAGS = $(COMMON_CFLAGS)
-bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
-bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-# For datetime.mod
-datetime_mod_SOURCES = lib/cmos_datetime.c
-datetime_mod_CFLAGS = $(COMMON_CFLAGS)
-datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-include $(srcdir)/conf/i386.mk
-include $(srcdir)/conf/common.mk
diff --git a/conf/i386-pc-cygwin-img-ld.sc b/conf/i386-pc-cygwin-img-ld.sc
deleted file mode 100644 (file)
index a41cac7..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Linker script to create grub .img files on Cygwin.  */
-
-SECTIONS
-{
-  .text :
-  {
-    start = . ;
-    *(.text)
-    etext = . ;
-  }
-  .data :
-  {
-    __data_start__ = . ;
-    *(.data)
-    __data_end__ = . ;
-  }
-  .rdata :
-  {
-    __rdata_start__ = . ;
-    *(.rdata)
-    __rdata_end__ = . ;
-  }
-  .pdata :
-  {
-    *(.pdata)
-    edata = . ;
-  }
-  .bss :
-  {
-    __bss_start__ = . ;
-    *(.bss)
-    __common_start__ = . ;
-    *(COMMON)
-    __bss_end__ = . ;
-  }
-  .edata :
-  {
-    *(.edata)
-    end = . ;
-  }
-  .stab :
-  {
-    *(.stab)
-  }
-  .stabstr :
-  {
-    *(.stabstr)
-  }
-}
-
-ASSERT("__rdata_end__"=="edata", ".pdata not empty")
-ASSERT("__bss_end__"  =="end"  , ".edata not empty")
-
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
deleted file mode 100644 (file)
index a5a1b08..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-# -*- makefile -*-
-
-GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200
-
-COMMON_CFLAGS = -mrtd -mregparm=3
-
-# Images.
-pkglib_IMAGES = boot.img cdboot.img diskboot.img kernel.img lnxboot.img \
-       pxeboot.img
-
-# For boot.img.
-boot_img_SOURCES = boot/i386/pc/boot.S
-boot_img_ASFLAGS = $(COMMON_ASFLAGS)
-boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00
-boot_img_FORMAT = binary
-
-# For pxeboot.img
-pxeboot_img_SOURCES = boot/i386/pc/pxeboot.S
-pxeboot_img_ASFLAGS = $(COMMON_ASFLAGS)
-pxeboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00
-pxeboot_img_FORMAT = binary
-
-# For diskboot.img.
-diskboot_img_SOURCES = boot/i386/pc/diskboot.S
-diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
-diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x8000
-diskboot_img_FORMAT = binary
-
-# For lnxboot.img.
-lnxboot_img_SOURCES = boot/i386/pc/lnxboot.S
-lnxboot_img_ASFLAGS = $(COMMON_ASFLAGS)
-lnxboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x6000
-lnxboot_img_FORMAT = binary
-
-# For cdboot.img.
-cdboot_img_SOURCES = boot/i386/pc/cdboot.S
-cdboot_img_ASFLAGS = $(COMMON_ASFLAGS)
-cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00
-cdboot_img_FORMAT = binary
-
-# For kernel.img.
-kernel_img_SOURCES = kern/i386/pc/startup.S \
-       kern/i386/misc.S \
-       kern/main.c kern/device.c \
-       kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
-       kern/misc.c kern/mm.c kern/term.c \
-       kern/rescue_parser.c kern/rescue_reader.c \
-       kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
-       kern/$(target_cpu)/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \
-       kern/parser.c kern/partition.c \
-       kern/i386/tsc.c kern/i386/pit.c \
-       kern/generic/rtc_get_time_ms.c \
-       kern/generic/millisleep.c \
-       kern/env.c \
-       term/i386/pc/console.c term/i386/vga_common.c \
-       symlist.c
-kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \
-       machine/pxe.h i386/pit.h
-kernel_img_CFLAGS = $(COMMON_CFLAGS)  $(TARGET_IMG_CFLAGS)
-kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
-kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
-kernel_img_FORMAT = binary
-
-# Utilities.
-bin_UTILITIES = grub-mkimage
-sbin_UTILITIES = grub-setup
-
-# For grub-mkimage.
-grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \
-       util/resolve.c lib/LzmaEnc.c lib/LzFind.c
-grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
-util/grub-mkrawimage.c_DEPENDENCIES = Makefile
-
-# For grub-setup.
-util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h
-grub_setup_SOURCES = gnulib/progname.c \
-       util/i386/pc/grub-setup.c util/hostdisk.c       \
-       util/misc.c util/getroot.c kern/device.c kern/disk.c    \
-       kern/err.c kern/misc.c kern/parser.c kern/partition.c   \
-       kern/file.c kern/fs.c kern/env.c kern/list.c            \
-       fs/fshelp.c                                             \
-       \
-       fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c          \
-       fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c   \
-       fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c       \
-       fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c           \
-       fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c             \
-       \
-       partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c      \
-       partmap/gpt.c           \
-       \
-       disk/raid.c disk/mdraid_linux.c disk/lvm.c              \
-       util/raid.c util/lvm.c util/mm.c                        \
-       grub_setup_init.c
-
-sbin_SCRIPTS += grub-install
-grub_install_SOURCES = util/grub-install.in
-
-bin_SCRIPTS += grub-mkrescue
-grub_mkrescue_SOURCES = util/grub-mkrescue.in
-
-pkglib_MODULES = biosdisk.mod chain.mod                                \
-       halt.mod                                \
-       vbe.mod vbetest.mod vbeinfo.mod                 \
-       vga.mod                         \
-       aout.mod bsd.mod pxe.mod pxecmd.mod datetime.mod        \
-       ata_pthru.mod hdparm.mod                \
-       usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod \
-       efiemu.mod mmap.mod acpi.mod drivemap.mod
-
-# For drivemap.mod.
-drivemap_mod_SOURCES = commands/i386/pc/drivemap.c \
-                       commands/i386/pc/drivemap_int13h.S
-drivemap_mod_ASFLAGS = $(COMMON_ASFLAGS)
-drivemap_mod_CFLAGS = $(COMMON_CFLAGS)
-drivemap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For efiemu.mod.
-efiemu_mod_SOURCES = efiemu/main.c efiemu/i386/loadcore32.c \
-                    efiemu/i386/loadcore64.c efiemu/i386/pc/cfgtables.c \
-                    efiemu/mm.c efiemu/loadcore_common.c efiemu/symbols.c \
-                    efiemu/loadcore32.c efiemu/loadcore64.c \
-                    efiemu/prepare32.c efiemu/prepare64.c efiemu/pnvram.c \
-                    efiemu/i386/coredetect.c
-efiemu_mod_CFLAGS = $(COMMON_CFLAGS)
-efiemu_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For acpi.mod.
-acpi_mod_SOURCES = commands/acpi.c commands/i386/pc/acpi.c
-acpi_mod_CFLAGS = $(COMMON_CFLAGS)
-acpi_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For mmap.mod.
-mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \
-                  mmap/i386/pc/mmap.c mmap/i386/pc/mmap_helper.S
-mmap_mod_CFLAGS = $(COMMON_CFLAGS)
-mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-# For biosdisk.mod.
-biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c
-biosdisk_mod_CFLAGS = $(COMMON_CFLAGS)
-biosdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For chain.mod.
-chain_mod_SOURCES = loader/i386/pc/chainloader.c
-chain_mod_CFLAGS = $(COMMON_CFLAGS)
-chain_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += linux16.mod
-linux16_mod_SOURCES = loader/i386/pc/linux.c
-linux16_mod_CFLAGS = $(COMMON_CFLAGS)
-linux16_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += linux.mod
-linux_mod_SOURCES = loader/i386/linux.c
-linux_mod_CFLAGS = $(COMMON_CFLAGS)
-linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += xnu.mod
-xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/pc/xnu.c \
-        loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c
-xnu_mod_CFLAGS = $(COMMON_CFLAGS)
-xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
-xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-# For halt.mod.
-halt_mod_SOURCES = commands/i386/pc/halt.c
-halt_mod_CFLAGS = $(COMMON_CFLAGS)
-halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For vbe.mod.
-vbe_mod_SOURCES = video/i386/pc/vbe.c
-vbe_mod_CFLAGS = $(COMMON_CFLAGS)
-vbe_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For vbeinfo.mod.
-vbeinfo_mod_SOURCES = commands/i386/pc/vbeinfo.c
-vbeinfo_mod_CFLAGS = $(COMMON_CFLAGS)
-vbeinfo_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For vbetest.mod.
-vbetest_mod_SOURCES = commands/i386/pc/vbetest.c
-vbetest_mod_CFLAGS = $(COMMON_CFLAGS)
-vbetest_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For vga.mod.
-vga_mod_SOURCES = term/i386/pc/vga.c
-vga_mod_CFLAGS = $(COMMON_CFLAGS)
-vga_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For aout.mod
-aout_mod_SOURCES = loader/aout.c
-aout_mod_CFLAGS = $(COMMON_CFLAGS)
-aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For bsd.mod
-bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S
-bsd_mod_CFLAGS = $(COMMON_CFLAGS)
-bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
-bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-# For usb.mod
-usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c
-usb_mod_CFLAGS = $(COMMON_CFLAGS)
-usb_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For usbtest.mod
-usbtest_mod_SOURCES = commands/usbtest.c
-usbtest_mod_CFLAGS = $(COMMON_CFLAGS)
-usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For uhci.mod
-uhci_mod_SOURCES = bus/usb/uhci.c
-uhci_mod_CFLAGS = $(COMMON_CFLAGS)
-uhci_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For ohci.mod
-ohci_mod_SOURCES = bus/usb/ohci.c
-ohci_mod_CFLAGS = $(COMMON_CFLAGS)
-ohci_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For usbms.mod
-usbms_mod_SOURCES = disk/usbms.c
-usbms_mod_CFLAGS = $(COMMON_CFLAGS)
-usbms_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For usb_keyboard.mod
-usb_keyboard_mod_SOURCES = term/usb_keyboard.c
-usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS)
-usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For pxe.mod
-pxe_mod_SOURCES = fs/i386/pc/pxe.c
-pxe_mod_CFLAGS = $(COMMON_CFLAGS)
-pxe_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For pxecmd.mod
-pxecmd_mod_SOURCES = commands/i386/pc/pxecmd.c
-pxecmd_mod_CFLAGS = $(COMMON_CFLAGS)
-pxecmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For datetime.mod
-datetime_mod_SOURCES = lib/cmos_datetime.c
-datetime_mod_CFLAGS = $(COMMON_CFLAGS)
-datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For ata_pthru.mod.
-ata_pthru_mod_SOURCES = disk/ata_pthru.c
-ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS)
-ata_pthru_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For hdparm.mod.
-hdparm_mod_SOURCES = commands/hdparm.c lib/hexdump.c
-hdparm_mod_CFLAGS = $(COMMON_CFLAGS)
-hdparm_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-ifeq ($(enable_efiemu), yes)
-
-efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF)
-       -rm -f $@
-ifeq ($(TARGET_APPLE_CC), 1)
-       -rm -f $@.bin
-       $(TARGET_CC) -c -m32 -DELF32 -DAPPLE_CC -o $@.bin -Wall -Werror $< -nostdlib -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
-       $(OBJCONV) -felf32 -nu -nd $@.bin $@
-       -rm -f $@.bin
-else
-       $(TARGET_CC) -c -m32 -DELF32 -o $@ -Wall -Werror $< -nostdlib -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
-       if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
-endif
-
-efiemu64_c.o: efiemu/runtime/efiemu.c
-ifeq ($(TARGET_APPLE_CC), 1)
-       $(TARGET_CC) -c -m64 -DAPPLE_CC=1 -DELF64 -o $@ -Wall -Werror $< -nostdlib -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
-else
-       $(TARGET_CC) -c -m64 -DELF64 -o $@ -Wall -Werror $< -nostdlib  -mcmodel=large -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
-endif
-
-efiemu64_s.o: efiemu/runtime/efiemu.S
-       -rm -f $@
-ifeq ($(TARGET_APPLE_CC), 1)
-       $(TARGET_CC) -c -m64 -DAPPLE_CC=1 -DELF64 -o $@ -Wall -Werror $< -nostdlib -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
-else
-       $(TARGET_CC) -c -m64 -DELF64 -o $@ -Wall -Werror $< -nostdlib  -mcmodel=large -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
-endif
-
-efiemu64.o: efiemu64_c.o efiemu64_s.o  $(TARGET_OBJ2ELF)
-       -rm -f $@
-ifeq ($(TARGET_APPLE_CC), 1)
-       -rm -f $@.bin
-       $(TARGET_CC) -m64 -o $@.bin -Wl,-r $^ -nostdlib
-       $(OBJCONV) -felf64 -nu -nd $@.bin $@
-       -rm -f $@.bin
-else
-       $(TARGET_CC) -m64 -o $@ -Wl,-r $^ -nostdlib
-       if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
-endif
-
-CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o
-pkglib_DATA += efiemu32.o efiemu64.o
-
-endif
-
-include $(srcdir)/conf/i386.mk
-include $(srcdir)/conf/common.mk
diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk
deleted file mode 100644 (file)
index 664bef1..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-# -*- makefile -*-
-
-COMMON_CFLAGS = -mrtd -mregparm=3
-
-# Images.
-
-GRUB_KERNEL_MACHINE_LINK_ADDR  = 0x8200
-GRUB_BOOT_MACHINE_LINK_ADDR    = 0xffe00
-
-pkglib_IMAGES += boot.img
-boot_img_SOURCES = boot/i386/qemu/boot.S
-boot_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)
-boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LINK_ADDR)
-boot_img_FORMAT = binary
-
-bin_UTILITIES += grub-mkimage
-grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \
-       util/resolve.c gnulib/progname.c
-grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
-util/grub-mkrawimage.c_DEPENDENCIES = Makefile
-
-pkglib_IMAGES += kernel.img
-kernel_img_SOURCES = kern/i386/qemu/startup.S \
-       kern/i386/misc.S \
-       kern/i386/coreboot/init.c \
-       kern/i386/qemu/mmap.c \
-       kern/i386/halt.c \
-       kern/main.c kern/device.c \
-       kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
-       kern/misc.c kern/mm.c kern/term.c \
-       kern/rescue_parser.c kern/rescue_reader.c \
-       kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
-       kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
-       kern/i386/tsc.c kern/i386/pit.c \
-       kern/generic/rtc_get_time_ms.c \
-       kern/generic/millisleep.c \
-       kern/env.c \
-       term/i386/pc/vga_text.c term/i386/vga_common.c \
-       symlist.c
-kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)
-kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
-kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR)
-kernel_img_FORMAT = binary
-
-sbin_SCRIPTS += grub-install
-grub_install_SOURCES = util/grub-install.in
-
-bin_SCRIPTS += grub-mkrescue
-grub_mkrescue_SOURCES = util/grub-mkrescue.in
-
-# Modules.
-pkglib_MODULES = linux.mod aout.mod halt.mod datetime.mod mmap.mod
-
-# For mmap.mod.
-mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
-mmap_mod_CFLAGS = $(COMMON_CFLAGS)
-mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-# For linux.mod.
-linux_mod_SOURCES = loader/i386/linux.c
-linux_mod_CFLAGS = $(COMMON_CFLAGS)
-linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For halt.mod.
-halt_mod_SOURCES = commands/halt.c
-halt_mod_CFLAGS = $(COMMON_CFLAGS)
-halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For aout.mod.
-aout_mod_SOURCES = loader/aout.c
-aout_mod_CFLAGS = $(COMMON_CFLAGS)
-aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For bsd.mod
-pkglib_MODULES += bsd.mod
-bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S
-bsd_mod_CFLAGS = $(COMMON_CFLAGS)
-bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
-bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-# For datetime.mod
-datetime_mod_SOURCES = lib/cmos_datetime.c
-datetime_mod_CFLAGS = $(COMMON_CFLAGS)
-datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-include $(srcdir)/conf/i386.mk
-include $(srcdir)/conf/common.mk
diff --git a/conf/i386.rmk b/conf/i386.rmk
deleted file mode 100644 (file)
index 02ce398..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-# -*- makefile -*-
-
-pkglib_MODULES += cpuid.mod
-cpuid_mod_SOURCES = commands/i386/cpuid.c
-cpuid_mod_CFLAGS = $(COMMON_CFLAGS)
-cpuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += at_keyboard.mod
-at_keyboard_mod_SOURCES = term/at_keyboard.c
-at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS)
-at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += vga_text.mod
-vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c
-vga_text_mod_CFLAGS = $(COMMON_CFLAGS)
-vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += relocator.mod
-relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S
-relocator_mod_CFLAGS = $(COMMON_CFLAGS)
-relocator_mod_ASFLAGS = $(COMMON_ASFLAGS)
-relocator_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += ata.mod
-ata_mod_SOURCES = disk/ata.c
-ata_mod_CFLAGS = $(COMMON_CFLAGS)
-ata_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For setpci.mod
-pkglib_MODULES += setpci.mod
-setpci_mod_SOURCES = commands/setpci.c
-setpci_mod_CFLAGS = $(COMMON_CFLAGS)
-setpci_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += multiboot.mod
-multiboot_mod_SOURCES = loader/multiboot.c loader/i386/multiboot_mbi.c
-multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
-multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
-multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-pkglib_MODULES += multiboot2.mod
-multiboot2_mod_SOURCES = loader/multiboot.c loader/multiboot_mbi2.c
-multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2
-multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS)
-multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-# For serial.mod.
-pkglib_MODULES += serial.mod
-serial_mod_SOURCES = term/serial.c
-serial_mod_CFLAGS = $(COMMON_CFLAGS)
-serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For pci.mod
-pkglib_MODULES += pci.mod
-pci_mod_SOURCES = bus/pci.c
-pci_mod_CFLAGS = $(COMMON_CFLAGS)
-pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For lspci.mod
-pkglib_MODULES += lspci.mod
-lspci_mod_SOURCES = commands/lspci.c
-lspci_mod_CFLAGS = $(COMMON_CFLAGS)
-lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For play.mod.
-pkglib_MODULES += play.mod
-play_mod_SOURCES = commands/i386/pc/play.c
-play_mod_CFLAGS = $(COMMON_CFLAGS)
-play_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For iorw.mod.
-pkglib_MODULES += iorw.mod
-iorw_mod_SOURCES = commands/iorw.c
-iorw_mod_CFLAGS = $(COMMON_CFLAGS)
-iorw_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/conf/mips-qemu-mips.rmk b/conf/mips-qemu-mips.rmk
deleted file mode 100644 (file)
index af5b26b..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- makefile -*-
-LINK_BASE = 0x80010000
-target_machine=qemu-mips
-COMMON_CFLAGS += -march=mips3
-COMMON_ASFLAGS += -march=mips3
-include $(srcdir)/conf/mips.mk
-
-pkglib_IMAGES = kernel.img
-kernel_img_SOURCES = kern/$(target_cpu)/startup.S \
-       kern/main.c kern/device.c kern/$(target_cpu)/init.c \
-       kern/$(target_cpu)/$(target_machine)/init.c             \
-       kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c          \
-       kern/misc.c kern/mm.c kern/term.c       \
-       kern/rescue_parser.c kern/rescue_reader.c \
-       kern/list.c kern/handler.c kern/command.c kern/corecmd.c        \
-       kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c       \
-       kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c    \
-       symlist.c kern/$(target_cpu)/cache.S
-kernel_img_CFLAGS = $(COMMON_CFLAGS)
-kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
-kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic
-kernel_img_FORMAT = binary
diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk
deleted file mode 100644 (file)
index 6a96ddf..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-# -*- makefile -*-
-LINK_BASE = 0x80200000
-target_machine=yeeloong
-COMMON_CFLAGS += -march=mips3
-COMMON_ASFLAGS += -march=mips3
-
-kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h bitmap_scale.h bufio.h
-
-include $(srcdir)/conf/mips.mk
-
-pkglib_IMAGES = kernel.img
-kernel_img_SOURCES = kern/$(target_cpu)/startup.S \
-       kern/main.c kern/device.c kern/$(target_cpu)/init.c \
-       kern/$(target_cpu)/$(target_machine)/init.c             \
-       kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c          \
-       kern/misc.c kern/mm.c kern/term.c       \
-       kern/rescue_parser.c kern/rescue_reader.c \
-       kern/list.c kern/handler.c kern/command.c kern/corecmd.c        \
-       kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c       \
-       kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c    \
-       kern/$(target_cpu)/cache.S \
-       \
-       term/at_keyboard.c \
-       font/font_cmd.c font/font.c io/bufio.c \
-       video/video.c video/fb/video_fb.c video/fb/fbblit.c \
-       video/fb/fbfill.c video/fb/fbutil.c video/bitmap.c \
-       video/bitmap_scale.c video/sm712.c bus/pci.c bus/bonito.c \
-       term/gfxterm.c commands/extcmd.c lib/arg.c \
-       symlist.c
-kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK
-kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
-kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic
-kernel_img_FORMAT = binary
-
-# For ata.mod.
-pkglib_MODULES += ata.mod
-ata_mod_SOURCES = disk/ata.c
-ata_mod_CFLAGS = $(COMMON_CFLAGS)
-ata_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For lspci.mod
-pkglib_MODULES += lspci.mod
-lspci_mod_SOURCES = commands/lspci.c
-lspci_mod_CFLAGS = $(COMMON_CFLAGS)
-lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For ata_pthru.mod.
-pkglib_MODULES += ata_pthru.mod
-ata_pthru_mod_SOURCES = disk/ata_pthru.c
-ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS)
-ata_pthru_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For mmap.mod.
-pkglib_MODULES += mmap.mod
-mmap_mod_SOURCES = mmap/mmap.c mmap/mips/yeeloong/uppermem.c
-mmap_mod_CFLAGS = $(COMMON_CFLAGS)
-mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-# For datetime.mod
-pkglib_MODULES += datetime.mod
-datetime_mod_SOURCES = lib/cmos_datetime.c
-datetime_mod_CFLAGS = $(COMMON_CFLAGS)
-datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += linux.mod
-linux_mod_SOURCES = loader/$(target_cpu)/linux.c
-linux_mod_CFLAGS = $(COMMON_CFLAGS)
-linux_mod_ASFLAGS = $(COMMON_ASFLAGS)
-linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-sbin_SCRIPTS += grub-install
-grub_install_SOURCES = util/grub-install.in
diff --git a/conf/mips.rmk b/conf/mips.rmk
deleted file mode 100644 (file)
index 4603c21..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-
-# -*- makefile -*-
-
-COMMON_CFLAGS += -mexplicit-relocs -mflush-func=grub_cpu_flush_cache
-
-# Images.
-kernel_img_HEADERS += cpu/cache.h
-
-# Scripts.
-sbin_SCRIPTS = 
-bin_SCRIPTS = 
-
-# For grub-mkimage.
-bin_UTILITIES += grub-mkimage
-grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \
-       util/resolve.c lib/LzmaEnc.c lib/LzFind.c
-grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE)
-util/grub-mkrawimage.c_DEPENDENCIES = Makefile
-
-# For serial.mod.
-pkglib_MODULES += serial.mod
-serial_mod_SOURCES = term/serial.c
-serial_mod_CFLAGS = $(COMMON_CFLAGS)
-serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For relocator.mod.
-pkglib_MODULES += relocator.mod
-relocator_mod_SOURCES = lib/$(target_cpu)/relocator.c lib/$(target_cpu)/relocator_asm.S
-relocator_mod_CFLAGS = $(COMMON_CFLAGS)
-relocator_mod_ASFLAGS = $(COMMON_ASFLAGS)
-relocator_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += multiboot2.mod
-multiboot2_mod_SOURCES = loader/multiboot.c \
-                        loader/multiboot_mbi2.c
-multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2
-multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS)
-multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-include $(srcdir)/conf/common.mk
diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk
deleted file mode 100644 (file)
index d5968ac..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-
-# -*- makefile -*-
-
-# Images.
-
-kernel_img_HEADERS += ieee1275/ieee1275.h
-
-# Programs
-pkglib_PROGRAMS = kernel.img
-
-kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \
-       kern/ieee1275/ieee1275.c kern/main.c kern/device.c              \
-       kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c          \
-       kern/misc.c kern/mm.c kern/term.c       \
-       kern/rescue_parser.c kern/rescue_reader.c \
-       kern/list.c kern/handler.c kern/command.c kern/corecmd.c        \
-       kern/ieee1275/init.c                                            \
-       kern/ieee1275/mmap.c                                            \
-       term/ieee1275/ofconsole.c               \
-       kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c           \
-       kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c       \
-       kern/generic/millisleep.c kern/time.c                            \
-       symlist.c kern/$(target_cpu)/cache.S
-kernel_img_CFLAGS = $(COMMON_CFLAGS)
-kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
-kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x200000,-Bstatic
-
-# Scripts.
-sbin_SCRIPTS = grub-install
-bin_SCRIPTS = grub-mkrescue
-
-# For grub-install.
-grub_install_SOURCES = util/ieee1275/grub-install.in
-
-# For grub-mkrescue.
-grub_mkrescue_SOURCES = util/powerpc/ieee1275/grub-mkrescue.in
-
-# Modules.
-pkglib_MODULES += ieee1275_fb.mod 
-ieee1275_fb_mod_SOURCES = video/ieee1275.c
-ieee1275_fb_mod_CFLAGS = $(COMMON_CFLAGS)
-ieee1275_fb_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For linux.mod.
-pkglib_MODULES += linux.mod
-linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c
-linux_mod_CFLAGS = $(COMMON_CFLAGS)
-linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For suspend.mod
-pkglib_MODULES += suspend.mod
-suspend_mod_SOURCES = commands/ieee1275/suspend.c
-suspend_mod_CFLAGS = $(COMMON_CFLAGS)
-suspend_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For halt.mod
-pkglib_MODULES += halt.mod
-halt_mod_SOURCES = commands/halt.c
-halt_mod_CFLAGS = $(COMMON_CFLAGS)
-halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For datetime.mod
-pkglib_MODULES += datetime.mod
-datetime_mod_SOURCES = lib/ieee1275/datetime.c
-datetime_mod_CFLAGS = $(COMMON_CFLAGS)
-datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-include $(srcdir)/conf/common.mk
diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk
deleted file mode 100644 (file)
index f0c9b0d..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-
-# -*- makefile -*-
-
-COMMON_CFLAGS = -mno-app-regs
-COMMON_LDFLAGS = -melf64_sparc -mno-relax
-
-# Images.
-pkglib_IMAGES = boot.img diskboot.img kernel.img
-
-# For boot.img.
-boot_img_SOURCES = boot/sparc64/ieee1275/boot.S
-boot_img_ASFLAGS = $(COMMON_ASFLAGS)
-boot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4000
-boot_img_FORMAT = a.out-sunos-big
-
-# For diskboot.img.
-diskboot_img_SOURCES = boot/sparc64/ieee1275/diskboot.S
-diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
-diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4200
-diskboot_img_FORMAT = binary
-
-kernel_img_HEADERS += ieee1275/ieee1275.h cpu/ieee1275/ieee1275.h
-kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c        \
-       kern/ieee1275/ieee1275.c kern/main.c kern/device.c              \
-       kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c          \
-       kern/misc.c kern/mm.c kern/term.c                       \
-       kern/rescue_parser.c kern/rescue_reader.c \
-       kern/list.c kern/handler.c kern/command.c kern/corecmd.c        \
-       kern/sparc64/ieee1275/ieee1275.c                                \
-       kern/sparc64/ieee1275/init.c                                    \
-       kern/ieee1275/mmap.c                                            \
-       term/ieee1275/ofconsole.c                                       \
-       kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c                   \
-       kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c       \
-       kern/generic/millisleep.c kern/time.c                           \
-       symlist.c kern/$(target_cpu)/cache.S
-kernel_img_CFLAGS = $(COMMON_CFLAGS)
-kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
-kernel_img_LDFLAGS += -nostdlib -Wl,-N,-Ttext,0x4400,-Bstatic,-melf64_sparc
-kernel_img_FORMAT = binary
-
-# Utilities.
-bin_UTILITIES = grub-mkimage
-sbin_UTILITIES = grub-setup grub-ofpathname
-
-# For grub-mkimage.
-grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \
-        util/resolve.c gnulib/progname.c
-
-# For grub-setup.
-util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h
-grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c        \
-       util/ieee1275/ofpath.c \
-       util/misc.c util/getroot.c kern/device.c kern/disk.c    \
-       kern/err.c kern/misc.c kern/parser.c kern/partition.c   \
-       kern/file.c kern/fs.c kern/env.c kern/list.c            \
-       fs/fshelp.c                                             \
-       \
-       fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c         \
-       fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c  \
-       fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c       \
-       fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c           \
-       fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c             \
-       \
-       partmap/amiga.c partmap/apple.c partmap/msdos.c         \
-       partmap/bsdlabel.c partmap/sun.c partmap/acorn.c        \
-       \
-       disk/raid.c disk/mdraid_linux.c disk/lvm.c              \
-       util/raid.c util/lvm.c util/mm.c gnulib/progname.c      \
-       grub_setup_init.c
-
-# For grub-ofpathname.
-grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \
-       util/ieee1275/ofpath.c util/misc.c gnulib/progname.c
-
-# Scripts.
-sbin_SCRIPTS = grub-install
-
-# For grub-install.
-grub_install_SOURCES = util/grub-install.in
-
-# Modules.
-pkglib_MODULES += ieee1275_fb.mod 
-ieee1275_fb_mod_SOURCES = video/ieee1275.c
-ieee1275_fb_mod_CFLAGS = $(COMMON_CFLAGS)
-ieee1275_fb_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For linux.mod.
-pkglib_MODULES += linux.mod 
-linux_mod_SOURCES = loader/sparc64/ieee1275/linux.c
-linux_mod_CFLAGS = $(COMMON_CFLAGS)
-linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For halt.mod.
-pkglib_MODULES += halt.mod
-halt_mod_SOURCES = commands/halt.c
-halt_mod_CFLAGS = $(COMMON_CFLAGS)
-halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For datetime.mod
-pkglib_MODULES += datetime.mod
-datetime_mod_SOURCES = lib/ieee1275/datetime.c
-datetime_mod_CFLAGS = $(COMMON_CFLAGS)
-datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-include $(srcdir)/conf/common.mk
diff --git a/conf/tests.rmk b/conf/tests.rmk
deleted file mode 100644 (file)
index 9af2f8f..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-# -*- makefile -*-
-
-# For grub-shell
-grub-shell: tests/util/grub-shell.in config.status
-       ./config.status --file=$@:$<
-       chmod +x $@
-check_SCRIPTS += grub-shell
-CLEANFILES += grub-shell
-
-# For grub-shell-tester
-grub-shell-tester: tests/util/grub-shell-tester.in config.status
-       ./config.status --file=$@:$<
-       chmod +x $@
-check_SCRIPTS += grub-shell-tester
-CLEANFILES += grub-shell-tester
-
-pkglib_MODULES += functional_test.mod
-functional_test_mod_SOURCES = tests/lib/functional_test.c tests/lib/test.c
-functional_test_mod_CFLAGS  = $(COMMON_CFLAGS)
-functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# Rules for unit tests
-check_UTILITIES += example_unit_test
-example_unit_test_SOURCES = tests/example_unit_test.c kern/list.c kern/misc.c tests/lib/test.c tests/lib/unit_test.c
-example_unit_test_CFLAGS  = -Wno-format
-
-# Rules for functional tests
-pkglib_MODULES += example_functional_test.mod
-example_functional_test_mod_SOURCES = tests/example_functional_test.c
-example_functional_test_mod_CFLAGS  = -Wno-format $(COMMON_CFLAGS)
-example_functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# Rules for scripted tests
-check_SCRIPTS += example_scripted_test
-example_scripted_test_SOURCES = tests/example_scripted_test.in
-
-check_SCRIPTS += example_grub_script_test
-example_grub_script_test_SOURCES = tests/example_grub_script_test.in
-
-#
-# Rules for real tests
-#
-
-check_SCRIPTS += grub_script_echo1
-grub_script_echo1_SOURCES = tests/grub_script_echo1.in
-
-check_SCRIPTS += grub_script_echo_keywords
-grub_script_echo_keywords_SOURCES = tests/grub_script_echo_keywords.in
-
-check_SCRIPTS += grub_script_vars1
-grub_script_vars1_SOURCES = tests/grub_script_vars1.in
-
-check_SCRIPTS += grub_script_for1
-grub_script_for1_SOURCES = tests/grub_script_for1.in
-
-check_SCRIPTS += grub_script_while1
-grub_script_while1_SOURCES = tests/grub_script_while1.in
-
-check_SCRIPTS += grub_script_if
-grub_script_if_SOURCES = tests/grub_script_if.in
-
-check_SCRIPTS += grub_script_blanklines
-grub_script_blanklines_SOURCES = tests/grub_script_blanklines.in
-
-check_SCRIPTS += grub_script_final_semicolon
-grub_script_final_semicolon_SOURCES = tests/grub_script_final_semicolon.in
-
-check_SCRIPTS += grub_script_dollar
-grub_script_dollar_SOURCES = tests/grub_script_dollar.in
-
-check_SCRIPTS += grub_script_comments
-grub_script_comments_SOURCES = tests/grub_script_comments.in
-
-# List of tests to execute on "make check"
-# SCRIPTED_TESTS    = example_scripted_test
-# SCRIPTED_TESTS   += example_grub_script_test
-# UNIT_TESTS        = example_unit_test
-# FUNCTIONAL_TESTS  = example_functional_test.mod
-
-SCRIPTED_TESTS  = grub_script_echo1
-SCRIPTED_TESTS += grub_script_echo_keywords
-SCRIPTED_TESTS += grub_script_vars1
-SCRIPTED_TESTS += grub_script_for1
-SCRIPTED_TESTS += grub_script_while1
-SCRIPTED_TESTS += grub_script_if
-SCRIPTED_TESTS += grub_script_blanklines
-SCRIPTED_TESTS += grub_script_final_semicolon
-SCRIPTED_TESTS += grub_script_dollar
-SCRIPTED_TESTS += grub_script_comments
-
-# dependencies between tests and testing-tools
-$(SCRIPTED_TESTS): grub-shell grub-shell-tester
-$(FUNCTIONAL_TESTS): functional_test.mod
-
diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk
deleted file mode 100644 (file)
index e29dad6..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-# -*- makefile -*-
-
-# Utilities.
-bin_UTILITIES = grub-mkimage
-
-# For grub-mkimage.
-grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \
-       util/misc.c util/resolve.c
-util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile
-
-# Scripts.
-sbin_SCRIPTS = grub-install
-
-# For grub-install.
-grub_install_SOURCES = util/i386/efi/grub-install.in
-
-# Modules.
-pkglib_PROGRAMS = kernel.img
-pkglib_MODULES = chain.mod appleldr.mod \
-       linux.mod halt.mod  \
-       datetime.mod loadbios.mod \
-       fixvideo.mod mmap.mod acpi.mod
-
-# For kernel.img.
-kernel_img_RELOCATABLE = yes
-kernel_img_SOURCES = kern/$(target_cpu)/efi/startup.S kern/main.c kern/device.c \
-       kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
-       kern/misc.c kern/mm.c kern/term.c \
-       kern/rescue_parser.c kern/rescue_reader.c \
-       kern/$(target_cpu)/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 \
-       kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
-       kern/i386/tsc.c kern/i386/pit.c \
-       kern/generic/rtc_get_time_ms.c \
-       kern/generic/millisleep.c
-ifeq ($(target_cpu),x86_64)
-kernel_img_SOURCES += kern/x86_64/efi/callwrap.S
-endif
-kernel_img_HEADERS += efi/efi.h efi/time.h efi/disk.h i386/pit.h
-kernel_img_CFLAGS = $(COMMON_CFLAGS)
-kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
-kernel_img_LDFLAGS += $(COMMON_LDFLAGS)
-
-# For acpi.mod.
-acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c
-acpi_mod_CFLAGS = $(COMMON_CFLAGS)
-acpi_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For mmap.mod.
-mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \
-                  mmap/efi/mmap.c
-mmap_mod_CFLAGS = $(COMMON_CFLAGS)
-mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For chain.mod.
-chain_mod_SOURCES = loader/efi/chainloader.c
-chain_mod_CFLAGS = $(COMMON_CFLAGS)
-chain_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For appleldr.mod.
-appleldr_mod_SOURCES = loader/efi/appleloader.c
-appleldr_mod_CFLAGS = $(COMMON_CFLAGS)
-appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For linux.mod.
-ifeq ($(target_cpu), x86_64)
-linux_mod_SOURCES = loader/i386/efi/linux.c loader/i386/linux_trampoline.S
-linux_mod_CFLAGS = $(COMMON_CFLAGS)
-linux_mod_ASFLAGS = $(COMMON_ASFLAGS)
-linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
-else
-linux_mod_SOURCES = loader/i386/efi/linux.c
-linux_mod_CFLAGS = $(COMMON_CFLAGS)
-linux_mod_ASFLAGS = $(COMMON_ASFLAGS)
-linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
-endif
-
-# For halt.mod.
-halt_mod_SOURCES = commands/halt.c
-halt_mod_CFLAGS = $(COMMON_CFLAGS)
-halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For datetime.mod
-datetime_mod_SOURCES = lib/efi/datetime.c
-datetime_mod_CFLAGS = $(COMMON_CFLAGS)
-datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For loadbios.mod
-loadbios_mod_SOURCES = commands/efi/loadbios.c
-loadbios_mod_CFLAGS = $(COMMON_CFLAGS)
-loadbios_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For fixvideo.mod
-fixvideo_mod_SOURCES = commands/efi/fixvideo.c
-fixvideo_mod_CFLAGS = $(COMMON_CFLAGS)
-fixvideo_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += efi_uga.mod
-efi_uga_mod_SOURCES = video/efi_uga.c
-efi_uga_mod_CFLAGS = $(COMMON_CFLAGS)
-efi_uga_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += efi_gop.mod
-efi_gop_mod_SOURCES = video/efi_gop.c
-efi_gop_mod_CFLAGS = $(COMMON_CFLAGS)
-efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += xnu.mod
-xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c \
-       loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c
-xnu_mod_CFLAGS = $(COMMON_CFLAGS)
-xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
-xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-include $(srcdir)/conf/i386.mk
-include $(srcdir)/conf/common.mk
diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk
deleted file mode 100644 (file)
index 2006212..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# -*- makefile -*-
-
-COMMON_LDFLAGS = -melf_x86_64
-
-include $(srcdir)/conf/x86-efi.mk
index 4e1dd41d88ef40b22897ad1d6eaa09c173cc9fa1..10c5275654ad3055b151bd45f79668139bc442df 100644 (file)
@@ -1,6 +1,6 @@
 # Process this file with autoconf to produce a configure script.
 
-# Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+# Copyright (C) 2010  Free Software Foundation, Inc.
 #
 # This configure.ac is free software; the author
 # gives unlimited permission to copy and/or distribute it,
@@ -23,782 +23,50 @@ dnl which specifies the system running GRUB, such as firmware.
 dnl This is necessary because the target type in autoconf does not
 dnl describe such a system very well.
 dnl
-dnl The current strategy is to use variables with no prefix (such as
-dnl CC, CFLAGS, etc.) for the host type as well as the build type,
-dnl because GRUB does not need to use those variables for the build
-dnl type, so there is no conflict. Variables with the prefix "TARGET_"
-dnl (such as TARGET_CC, TARGET_CFLAGS, etc.) are used for the target
-dnl type.
-
+dnl The current strategy is to build utilities using host
+dnl cross-compiler and grub core and modules using target
+dnl cross-compiler.  For this we use nested packages approach, where
+dnl top-level package grub utilities is built with HOSTCC and nested
+dnl package (in grub-core directory) builds with TARGETCC.
 
+# NOTE: grub-core/configure.ac must also be updated.
 AC_INIT([GRUB],[1.98],[bug-grub@gnu.org])
-AM_INIT_AUTOMAKE()
-AC_PREREQ(2.60)
-AC_CONFIG_SRCDIR([include/grub/dl.h])
-AC_CONFIG_HEADER([config.h])
+AC_CONFIG_AUX_DIR([.])
 
 # Checks for host and target systems.
 AC_CANONICAL_HOST
 AC_CANONICAL_TARGET
 
-# Program name transformations
-AC_ARG_PROGRAM
-
-# Optimization flag.  Allow user to override.
-if test "x$TARGET_CFLAGS" = x; then
-  TARGET_CFLAGS="$TARGET_CFLAGS -Os"
-fi
-
-case "$target_cpu" in
-  i[[3456]]86) target_cpu=i386 ;;
-  amd64)       target_cpu=x86_64 ;;
-  sparc)       target_cpu=sparc64 ;;
-  mipsel|mips64el)
-                target_cpu=mips;    
-               TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPSEL=1"; 
-               CFLAGS="$CFLAGS -DGRUB_CPU_MIPSEL=1";
-               ;;
-  mips|mips64)
-                target_cpu=mips;    
-               TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPS=1"; 
-               CFLAGS="$CFLAGS -DGRUB_CPU_MIPS=1";
-               ;;
-esac
-
-# Specify the platform (such as firmware).
-AC_ARG_WITH([platform],
-            AS_HELP_STRING([--with-platform=PLATFORM],
-                           [select the host platform [[guessed]]]))
-
-# Guess the platform if not specified.
-if test "x$with_platform" = x; then
-  case "$target_cpu"-"$target_vendor" in
-    i386-apple) platform=efi ;;
-    i386-*) platform=pc ;;
-    x86_64-apple) platform=efi ;;
-    x86_64-*) platform=pc ;;
-    powerpc-*) platform=ieee1275 ;;
-    powerpc64-*) platform=ieee1275 ;;
-    sparc64-*) platform=ieee1275 ;;
-    mips-*) platform=yeeloong ;;
-    *) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;;
-  esac
-else
-  platform="$with_platform"
-fi
-
-# Adjust CPU unless target was explicitly specified.
-if test -z "$target_alias"; then
-  case "$target_cpu"-"$platform" in
-    x86_64-efi) ;;
-    x86_64-emu) ;;
-    x86_64-*) target_cpu=i386 ;;
-    powerpc64-ieee1275) target_cpu=powerpc ;;
-  esac
-fi
-
-# Check if the platform is supported, make final adjustments.
-case "$target_cpu"-"$platform" in
-  i386-efi) ;;
-  x86_64-efi) ;;
-  i386-pc) ;;
-  i386-multiboot) ;;
-  i386-coreboot) ;;
-  i386-linuxbios) platform=coreboot ;;
-  i386-ieee1275) ;;
-  i386-qemu) ;;
-  powerpc-ieee1275) ;;
-  sparc64-ieee1275) ;;
-  mips-qemu-mips) ;;
-  mips-yeeloong) ;;
-  *-emu) ;;
-  *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
-esac
-
-case "$target_cpu" in
-  i386 | powerpc) target_m32=1 ;;
-  x86_64 | sparc64) target_m64=1 ;;
-esac
-
-case "$host_os" in
-  mingw32*) host_os=cygwin ;;
-esac
-
-# This normalizes the names, and creates a new variable ("host_kernel")
-# while at it, since the mapping is not always 1:1 (e.g. different OSes
-# using the same kernel type).
-case "$host_os" in
-  gnu*)                                host_kernel=hurd ;;
-  linux*)                      host_kernel=linux ;;
-  freebsd* | kfreebsd*-gnu)    host_kernel=kfreebsd ;;
-  netbsd*)                     host_kernel=netbsd ;;
-  cygwin)                      host_kernel=windows ;;
-esac
-
-case "$platform" in
-  coreboot)    machine_CFLAGS="-DGRUB_MACHINE_COREBOOT=1" ;;
-  multiboot)   machine_CFLAGS="-DGRUB_MACHINE_MULTIBOOT=1" ;;
-  efi)         machine_CFLAGS="-DGRUB_MACHINE_EFI=1" ;;
-  ieee1275)    machine_CFLAGS="-DGRUB_MACHINE_IEEE1275=1" ;;
-  qemu)                machine_CFLAGS="-DGRUB_MACHINE_QEMU=1" ;;
-  pc)          machine_CFLAGS="-DGRUB_MACHINE_PCBIOS=1" ;;
-  emu)         machine_CFLAGS="-DGRUB_MACHINE_EMU=1" ;;
-  yeeloong)    machine_CFLAGS="-DGRUB_MACHINE_MIPS_YEELOONG=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;;
-  qemu-mips)   machine_CFLAGS="-DGRUB_MACHINE_MIPS_QEMU_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;;
-esac
-case "$target_cpu" in
-  mips)        machine_CFLAGS="$machine_CFLAGS -DGRUB_MACHINE_MIPS=1" ;;
-  sparc64)      machine_CFLAGS="$machine_CFLAGS -DGRUB_MACHINE_SPARC64=1" ;;
-esac
-
-CFLAGS="$CFLAGS $machine_CFLAGS"
-TARGET_ASFLAGS="$TARGET_ASFLAGS $machine_CFLAGS"
-TARGET_CFLAGS="$TARGET_CFLAGS $machine_CFLAGS"
-
-AC_SUBST(host_cpu)
-AC_SUBST(host_os)
-AC_SUBST(host_kernel)
-
-AC_SUBST(target_cpu)
-AC_SUBST(platform)
-
-#
-# Checks for build programs.
-#
-
-# Although cmp is listed in the GNU Coding Standards as a command which
-# can used directly, OpenBSD lacks cmp in the default installation.
-AC_CHECK_PROGS([CMP], [cmp])
-if test "x$CMP" = x; then
-  AC_MSG_ERROR([cmp is not found])
-fi
-
-AC_CHECK_PROGS([YACC], [bison])
-if test "x$YACC" = x; then
-  AC_MSG_ERROR([bison is not found])
-fi
-
-for file in /usr/src/unifont.bdf /usr/share/fonts/X11/misc/unifont.pcf.gz /usr/share/fonts/unifont/unifont.pcf.gz; do
-  if test -e $file ; then
-    AC_SUBST([FONT_SOURCE], [$file])
-    break
-  fi
-done
-
-AC_PROG_INSTALL
-AC_PROG_AWK
-AC_PROG_LEX
-AC_PROG_MAKE_SET
-AC_PROG_MKDIR_P
-
-if test "x$LEX" = x; then
-  AC_MSG_ERROR([flex is not found])
-else
-  version=`$LEX --version | $AWK '{ split($NF,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'`
-  if test -n "$version" -a "$version" -ge 20535; then
-    :
-  else
-    AC_MSG_ERROR([flex is too old. GRUB requires 2.5.35 or above])
-  fi
-fi
-
-# These are not a "must".
-AC_PATH_PROG(RUBY, ruby)
-AC_PATH_PROG(MAKEINFO, makeinfo)
-
-#
-# Checks for host programs.
-#
-
-AC_PROG_CC
-# Must be GCC.
-test "x$GCC" = xyes || AC_MSG_ERROR([GCC is required])
-
-AC_GNU_SOURCE
-AM_GNU_GETTEXT([external])
-AC_SYS_LARGEFILE
-
-# Identify characteristics of the host architecture.
-AC_C_BIGENDIAN
-AC_CHECK_SIZEOF(void *)
-AC_CHECK_SIZEOF(long)
-
-grub_apple_cc
-if test x$grub_cv_apple_cc = xyes ; then
-  CFLAGS="$CFLAGS -DAPPLE_CC=1 -fnested-functions"
-  ASFLAGS="$ASFLAGS -DAPPLE_CC=1"
-fi
-
-if test "x$cross_compiling" = xyes; then
-  AC_MSG_WARN([cannot generate manual pages while cross compiling])
-else
-  AC_PATH_PROG(HELP2MAN, help2man)
-fi
-
-# Check for functions.
-AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf)
-
-# For grub-mkisofs
-AC_HEADER_MAJOR
-AC_HEADER_DIRENT
-AC_CHECK_FUNCS(memmove sbrk strdup lstat getuid getgid)
-AC_CHECK_HEADERS(sys/mkdev.h sys/sysmacros.h malloc.h termios.h sys/types.h)
-AC_CHECK_HEADERS(unistd.h string.h strings.h sys/stat.h sys/fcntl.h limits.h)
-
-# For opendisk() and getrawpartition() on NetBSD.
-# Used in util/deviceiter.c and in util/hostdisk.c.
-AC_CHECK_HEADER([util.h], [
-  AC_CHECK_LIB([util], [opendisk], [
-    LIBUTIL="-lutil"
-    AC_DEFINE(HAVE_OPENDISK, 1, [Define if opendisk() in -lutil can be used])
-  ])
-  AC_CHECK_LIB([util], [getrawpartition], [
-    LIBUTIL="-lutil"
-    AC_DEFINE(HAVE_GETRAWPARTITION, 1, [Define if getrawpartition() in -lutil can be used])
-  ])
-])
-AC_SUBST([LIBUTIL])
-
-#
-# Check for target programs.
-#
-
-# Find tools for the target.
-if test "x$target_alias" != x && test "x$host_alias" != "x$target_alias"; then
-  tmp_ac_tool_prefix="$ac_tool_prefix"
-  ac_tool_prefix=$target_alias-
-
-  AC_CHECK_TOOLS(TARGET_CC, [gcc egcs cc],
-                 [AC_MSG_ERROR([none of gcc, egcs and cc is found. set TARGET_CC manually.])])
-  AC_CHECK_TOOL(OBJCOPY, objcopy)
-  AC_CHECK_TOOL(STRIP, strip)
-  AC_CHECK_TOOL(NM, nm)
-
-  ac_tool_prefix="$tmp_ac_tool_prefix"
-else
-  if test "x$TARGET_CC" = x; then
-    TARGET_CC=$CC
-  fi
-  AC_CHECK_TOOL(OBJCOPY, objcopy)
-  AC_CHECK_TOOL(STRIP, strip)
-  AC_CHECK_TOOL(NM, nm)
-fi
-AC_SUBST(TARGET_CC)
-
-
-# Test the C compiler for the target environment.
-tmp_CC="$CC"
-tmp_CFLAGS="$CFLAGS"
-tmp_LDFLAGS="$LDFLAGS"
-tmp_CPPFLAGS="$CPPFLAGS"
-tmp_LIBS="$LIBS"
-CC="$TARGET_CC"
-CFLAGS="$TARGET_CFLAGS"
-CPPFLAGS="$TARGET_CPPFLAGS"
-LDFLAGS="$TARGET_LDFLAGS"
-LIBS=""
-
-# debug flags.
-TARGET_CFLAGS="$TARGET_CFLAGS -Wall -W -Wshadow -Wpointer-arith -Wmissing-prototypes \
-               -Wundef -Wstrict-prototypes -g"
-
-# Force no alignment to save space on i386.
-if test "x$target_cpu" = xi386; then
-  AC_CACHE_CHECK([whether -falign-loops works], [grub_cv_cc_falign_loop], [
-    CFLAGS="$CFLAGS -falign-loops=1"
-    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
-        [grub_cv_cc_falign_loop=yes],
-       [grub_cv_cc_falign_loop=no])
-  ])
-
-  if test "x$grub_cv_cc_falign_loop" = xyes; then
-    TARGET_CFLAGS="$TARGET_CFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1"
-  else
-    TARGET_CFLAGS="$TARGET_CFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1"
-  fi
-
-  # Some toolchains enable these features by default, but they need
-  # registers that aren't set up properly in GRUB.
-  TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-3dnow"
-fi
-
-# By default, GCC 4.4 generates .eh_frame sections containing unwind
-# information in some cases where it previously did not. GRUB doesn't need
-# these and they just use up vital space. Restore the old compiler
-# behaviour.
-AC_CACHE_CHECK([whether -fno-dwarf2-cfi-asm works], [grub_cv_cc_fno_dwarf2_cfi_asm], [
-  SAVE_CFLAGS="$CFLAGS"
-  CFLAGS="$CFLAGS -fno-dwarf2-cfi-asm"
-  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
-      [grub_cv_cc_fno_dwarf2_cfi_asm=yes],
-      [grub_cv_cc_fno_dwarf2_cfi_asm=no])
-  CFLAGS="$SAVE_CFLAGS"
-])
-
-if test "x$grub_cv_cc_fno_dwarf2_cfi_asm" = xyes; then
-  TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm"
-fi
-
-grub_apple_target_cc
-if test x$grub_cv_apple_target_cc = xyes ; then
-  TARGET_CFLAGS="$TARGET_CFLAGS -DAPPLE_CC=1 -fnested-functions"
-  CFLAGS="$CFLAGS -DAPPLE_CC=1 -fnested-functions"
-  TARGET_ASFLAGS="$TARGET_ASFLAGS -DAPPLE_CC=1"
-  TARGET_APPLE_CC=1
-  AC_CHECK_PROG([OBJCONV], [objconv], [objconv], [])
-  if test "x$OBJCONV" = x ; then
-     AC_CHECK_PROG([OBJCONV], [objconv], [./objconv], [], [.])
-  fi
-  if test "x$OBJCONV" = x ; then
-    AC_MSG_ERROR([objconv not found which is required when building with apple compiler])
-  fi
-  TARGET_IMG_LDSCRIPT=
-  TARGET_IMG_CFLAGS="-static"
-  TARGET_IMG_LDFLAGS='-nostdlib -static -Wl,-preload -Wl,-segalign,20 -Wl,-image_base,'
-  TARGET_IMG_LDFLAGS_AC='-nostdlib -static -Wl,-preload -Wl,-segalign,20 -Wl,-image_base,'
-else
-  TARGET_APPLE_CC=0
-# Use linker script if present, otherwise use builtin -N script.
-if test -f "${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"; then
-  TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"
-  TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}  -Wl,-Ttext,"
-  TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc  -Wl,-Ttext,"
-else
-  TARGET_IMG_LDSCRIPT=
-  TARGET_IMG_LDFLAGS='-Wl,-N  -Wl,-Ttext,'
-  TARGET_IMG_LDFLAGS_AC='-Wl,-N  -Wl,-Ttext,'
-fi
-TARGET_IMG_CFLAGS=
-fi
-
-AC_SUBST(TARGET_IMG_LDSCRIPT)
-AC_SUBST(TARGET_IMG_LDFLAGS)
-AC_SUBST(TARGET_IMG_CFLAGS)
-
-# For platforms where ELF is not the default link format.
-AC_MSG_CHECKING([for command to convert module to ELF format])
-case "${host_os}" in
-  cygwin) TARGET_OBJ2ELF='grub-pe2elf';
-# FIXME: put proper test here
-  AC_DEFINE([NEED_REGISTER_FRAME_INFO], 1,
-           [Define to 1 if GCC generates calls to __register_frame_info()])
-  ;;
-  *) ;;
-esac
-AC_SUBST(TARGET_OBJ2ELF)
-AC_MSG_RESULT([$TARGET_OBJ2ELF])
-
-
-if test "x$target_m32" = x1; then
-  # Force 32-bit mode.
-  TARGET_CFLAGS="$TARGET_CFLAGS -m32"
-  TARGET_ASFLAGS="$TARGET_CFLAGS -m32"
-  TARGET_LDFLAGS="$TARGET_LDFLAGS -m32"
-  TARGET_MODULE_FORMAT="elf32"
-fi
-
-if test "x$target_m64" = x1; then
-  # Force 64-bit mode.
-  TARGET_CFLAGS="$TARGET_CFLAGS -m64"
-  TARGET_ASFLAGS="$TARGET_ASFLAGS -m64"
-  TARGET_LDFLAGS="$TARGET_LDFLAGS -m64"
-  TARGET_MODULE_FORMAT="elf64"
-fi
-
-if test "$target_cpu"-"$platform" = x86_64-efi; then
-  # Use large model to support 4G memory
-  AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [
-    SAVED_CFLAGS=$CFLAGS
-    CFLAGS="$CFLAGS -m64 -mcmodel=large"
-    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
-                     [grub_cv_cc_mcmodel=yes],
-                     [grub_cv_cc_mcmodel=no])
-  ])
-  if test "x$grub_cv_cc_mcmodel" = xno; then
-    AC_MSG_ERROR([-mcmodel=large not supported. Upgrade your gcc.])
-  else
-    TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large"
-  fi
-
-  # EFI writes to stack below %rsp, we must not use the red zone
-  AC_CACHE_CHECK([whether option -mno-red-zone works], grub_cv_cc_no_red_zone, [
-    CFLAGS="$CFLAGS -m64 -mno-red-zone"
-    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
-                     [grub_cv_cc_no_red_zone=yes],
-                     [grub_cv_cc_no_red_zone=no])
-  ])
-  if test "x$grub_cv_cc_no_red_zone" = xno; then
-    AC_MSG_ERROR([-mno-red-zone not supported, upgrade your gcc])
-  fi
-
-  TARGET_CFLAGS="$TARGET_CFLAGS -mno-red-zone"
-fi
-
-#
-# Compiler features.
-#
-
-# Need __enable_execute_stack() for nested function trampolines?
-grub_CHECK_ENABLE_EXECUTE_STACK
-
-# Position independent executable.
-grub_CHECK_PIE
-[# Need that, because some distributions ship compilers that include
-# `-fPIE' in the default specs.
-if [ x"$pie_possible" = xyes ]; then
-  TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE"
-fi]
-
-# Smashing stack protector.
-grub_CHECK_STACK_PROTECTOR
-# Need that, because some distributions ship compilers that include
-# `-fstack-protector' in the default specs.
-if test "x$ssp_possible" = xyes; then
-  TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector"
-fi
-grub_CHECK_STACK_ARG_PROBE
-# Cygwin's GCC uses alloca() to probe the stackframe on static
-# stack allocations above some threshold.
-if test x"$sap_possible" = xyes; then
-  TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe"
-fi
-
-AC_ARG_ENABLE([werror],
-             [AS_HELP_STRING([--disable-werror],
-                             [do not use -Werror when building GRUB])])
-if test x"$enable_werror" != xno ; then
-  TARGET_CFLAGS="$TARGET_CFLAGS -Werror"
-fi
-
-AC_SUBST(TARGET_CFLAGS)
-AC_SUBST(TARGET_MODULE_FORMAT)
-AC_SUBST(OBJCONV)
-AC_SUBST(TARGET_APPLE_CC)
-AC_SUBST(TARGET_ASFLAGS)
-AC_SUBST(TARGET_CPPFLAGS)
-AC_SUBST(TARGET_LDFLAGS)
-
-# Set them to their new values for the tests below.
-CC="$TARGET_CC"
-if test "x$TARGET_APPLE_CC" = x1 ; then
-CFLAGS="$TARGET_CFLAGS -nostdlib -Wno-error"
-else
-CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100 -Wno-error"
-fi
-CPPFLAGS="$TARGET_CPPFLAGS"
-LDFLAGS="$TARGET_LDFLAGS"
-LIBS=-lgcc
-
-grub_ASM_USCORE
-if test x$grub_cv_asm_uscore = xyes; then
-CFLAGS="$CFLAGS -Wl,--defsym,_abort=_main"
-else
-CFLAGS="$CFLAGS -Wl,--defsym,abort=main"
-fi
-
-# Check for libgcc symbols
-AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x)
-
-if test "x$TARGET_APPLE_CC" = x1 ; then
-CFLAGS="$TARGET_CFLAGS -nostdlib"
-else
-CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100"
-fi
-LIBS=""
-
-# Defined in aclocal.m4.
-grub_PROG_TARGET_CC
-if test "x$TARGET_APPLE_CC" != x1 ; then
-grub_PROG_OBJCOPY_ABSOLUTE
-fi
-grub_PROG_LD_BUILD_ID_NONE
-if test "x$target_cpu" = xi386; then
-  if test "$platform" != emu && test "x$TARGET_APPLE_CC" != x1 ; then
-    if test ! -z "$TARGET_IMG_LDSCRIPT"; then
-      # Check symbols provided by linker script.
-      CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC}8000 -Wl,--defsym,___main=0x8100"
-    fi
-    grub_CHECK_BSS_START_SYMBOL
-    grub_CHECK_END_SYMBOL
-  fi
-  CFLAGS="$TARGET_CFLAGS"
-  grub_I386_ASM_PREFIX_REQUIREMENT
-  grub_I386_ASM_ADDR32
-  grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK
-else
-  AC_DEFINE([NESTED_FUNC_ATTR], [], [Catch gcc bug])
-fi
-
-AH_BOTTOM([#if defined(__i386__) && !defined(GRUB_UTIL)
-#define NESTED_FUNC_ATTR __attribute__ ((__regparm__ (1)))
-#else
-#define NESTED_FUNC_ATTR
-#endif])
-
-AC_ARG_ENABLE([efiemu],
-             [AS_HELP_STRING([--enable-efiemu],
-                             [build and install the efiemu runtimes (default=guessed)])])
-if test x"$enable_efiemu" = xno ; then
-  efiemu_excuse="explicitly disabled"
-fi
-if test x"$efiemu_excuse" = x ; then
-  AC_CACHE_CHECK([whether options required for efiemu work], grub_cv_cc_efiemu, [
-    CFLAGS="$CFLAGS -m64 -mcmodel=large -mno-red-zone -nostdlib"
-    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
-                     [grub_cv_cc_efiemu=yes],
-                     [grub_cv_cc_efiemu=no])
-  ])
-  if test x$grub_cv_cc_efiemu = xno; then
-     efiemu_excuse="cannot compile with -m64 -mcmodel=large -mno-red-zone -nostdlib"
-  fi
-fi
-if test x"$enable_efiemu" = xyes && test x"$efiemu_excuse" != x ; then
-  AC_MSG_ERROR([efiemu runtime was explicitly requested but can't be compiled])
-fi
-if test x"$efiemu_excuse" = x ; then
-enable_efiemu=yes
-else
-enable_efiemu=no
-fi
-AC_SUBST([enable_efiemu])
-
-if test "$platform" != emu; then
-AC_CACHE_CHECK([whether -nostdinc -isystem works], [grub_cv_cc_isystem], [
-  SAVED_CPPFLAGS="$CPPFLAGS"
-  CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -isystem `$TARGET_CC -print-file-name=include`"
-  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdarg.h>
-int va_arg_func (int fixed, va_list args);]], [[]])],
-      [grub_cv_cc_isystem=yes],
-      [grub_cv_cc_isystem=no])
-  CPPFLAGS="$SAVED_CPPFLAGS"
-])
-
-if test x"$grub_cv_cc_isystem" = xyes ; then
-  TARGET_CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -isystem `$TARGET_CC -print-file-name=include`"
-fi
-fi
-
-# Restore the flags.
-CC="$tmp_CC"
-CFLAGS="$tmp_CFLAGS"
-CPPFLAGS="$tmp_CPPFLAGS"
-LDFLAGS="$tmp_LDFLAGS"
-LIBS="$tmp_LIBS"
-
-#
-# Check for options.
-#
-
-# Memory manager debugging.
-AC_ARG_ENABLE([mm-debug],
-             AS_HELP_STRING([--enable-mm-debug],
-                             [include memory manager debugging]),
-              [AC_DEFINE([MM_DEBUG], [1],
-                         [Define to 1 if you enable memory manager debugging.])])
-
-AC_ARG_ENABLE([grub-emu-usb],
-             [AS_HELP_STRING([--enable-grub-emu-usb],
-                             [build and install the `grub-emu' debugging utility with USB support (default=guessed)])])
-
-AC_ARG_ENABLE([grub-emu-sdl],
-             [AS_HELP_STRING([--enable-grub-emu-sdl],
-                             [build and install the `grub-emu' debugging utility with SDL support (default=guessed)])])
-
-AC_ARG_ENABLE([grub-emu-pci],
-             [AS_HELP_STRING([--enable-grub-emu-pci],
-                             [build and install the `grub-emu' debugging utility with PCI support (potentially dangerous) (default=no)])])
-
-AC_ARG_ENABLE([grub-emu-modules],
-             [AS_HELP_STRING([--enable-grub-emu-modules],
-                             [Support module loading in `grub-emu' debugging utility (default=no)])])
-
-if test "$platform" = emu; then
-  missing_ncurses=
-[# Check for curses libraries.]
-  AC_CHECK_LIB([ncurses], [wgetch], [LIBCURSES="-lncurses"],
-    [AC_CHECK_LIB([curses], [wgetch], [LIBCURSES="-lcurses"],
-      [missing_ncurses=[true]])])
-  AC_SUBST([LIBCURSES])
-[if [ x"$missing_ncurses" = x ]; then ]
-  [# Check for headers.]
-  AC_CHECK_HEADERS([ncurses/curses.h], [],
-    [AC_CHECK_HEADERS([ncurses.h], [],
-      [AC_CHECK_HEADERS([curses.h], [],
-       [missing_ncurses=[true]])])])
-[fi]
-if test x"$missing_ncurses" = xtrue ; then
-  AC_MSG_ERROR([grub-emu can't be compiled without ncurses])
-fi
-
-if test x"$enable_grub_emu_modules" = xyes ; then
-  TARGET_NO_MODULES=no
-else
-  TARGET_NO_MODULES=yes
-fi
-AC_SUBST(TARGET_NO_MODULES)
-
-if test "$TARGET_NO_MODULES" = yes ; then
-  # Do not convert modules, otherwise linkage may fail (Cygwin only).
-  # FIXME: Should be checked above before TARGET_OBJ2ELF is set first.
-  TARGET_OBJ2ELF=
-fi
-
-if test x"$enable_grub_emu_usb" = xno ; then
-  grub_emu_usb_excuse="explicitly disabled"
-fi
-
-if test x"$enable_grub_emu_pci" = xyes ; then
-   grub_emu_usb_excuse="conflicts with PCI support"
-fi
-
-[if [ x"$grub_emu_usb_excuse" = x ]; then
-    # Check for libusb libraries.]
-AC_CHECK_LIB([usb], [usb_claim_interface], [LIBUSB="-lusb"],
-    [grub_emu_usb_excuse=["need libusb library"]])
-    AC_SUBST([LIBUSB])
-[fi]
-[if [ x"$grub_emu_usb_excuse" = x ]; then
-    # Check for headers.]
-    AC_CHECK_HEADERS([usb.h], [],
-      [grub_emu_usb_excuse=["need libusb headers"]])
-[fi]
-if test x"$enable_grub_emu_usb" = xyes && test x"$grub_emu_usb_excuse" != x ; then
-  AC_MSG_ERROR([USB support for grub-emu was explicitly requested but can't be compiled])
-fi
-if test x"$grub_emu_usb_excuse" = x ; then
-enable_grub_emu_usb=yes
-else
-enable_grub_emu_usb=no
-fi
-
-if test x"$enable_grub_emu_sdl" = xno ; then
-  grub_emu_sdl_excuse="explicitely disabled"
-fi
-[if [ x"$grub_emu_sdl_excuse" = x ]; then
-    # Check for libSDL libraries.]
-AC_CHECK_LIB([SDL], [SDL_Init], [LIBSDL="-lSDL"],
-    [grub_emu_sdl_excuse=["libSDL libraries are required to build \`grub-emu' with SDL support"]])
-    AC_SUBST([LIBSDL])
-[fi]
-
-[if [ x"$grub_emu_sdl_excuse" = x ]; then
-    # Check for headers.]
-    AC_CHECK_HEADERS([SDL/SDL.h], [],
-      [grub_emu_sdl_excuse=["libSDL header file is required to build \`grub-emu' with SDL support"]])
-[fi]
-
-if test x"enable_grub_emu_sdl" = xyes && test x"$grub_emu_sdl_excuse" != x ; then
-  AC_MSG_ERROR([SDL support for grub-emu was explicitely requested but can't be compiled])
-fi
-if test x"$grub_emu_sdl_excuse" = x ; then
-enable_grub_emu_sdl=yes
-else
-enable_grub_emu_sdl=no
-fi
-
-if test x"$enable_grub_emu_pci" != xyes ; then
-   grub_emu_pci_excuse="not enabled"
-fi
-
-if test x"$enable_grub_emu_usb" = xyes ; then
-   grub_emu_pci_excuse="conflicts with USB support"
-fi
-
-[if [ x"$grub_emu_pci_excuse" = x ]; then
-      # Check for libpci libraries.]
-   AC_CHECK_LIB([pciaccess], [pci_system_init], [LIBPCIACCESS="-lpciaccess"],
-      [grub_emu_pci_excuse=["need libpciaccess library"]])
-    AC_SUBST([LIBPCIACCESS])
-[fi]
-[if [ x"$grub_emu_pci_excuse" = x ]; then
-    # Check for headers.]
-    AC_CHECK_HEADERS([pci/pci.h], [],
-      [grub_emu_pci_excuse=["need libpciaccess headers"]])
-[fi]
-
-if test x"$grub_emu_pci_excuse" = x ; then
-enable_grub_emu_pci=yes
-else
-
-enable_grub_emu_pci=no
-fi
-
-AC_SUBST([enable_grub_emu_sdl])
-AC_SUBST([enable_grub_emu_usb])
-AC_SUBST([enable_grub_emu_pci])
-fi
-
-AC_ARG_ENABLE([grub-fstest],
-             [AS_HELP_STRING([--enable-grub-fstest],
-                             [build and install the `grub-fstest' debugging utility (default=guessed)])])
-if test x"$enable_grub_fstest" = xno ; then
-  grub_fstest_excuse="explicitly disabled"
-fi
-if test x"$grub_fstest_excuse" = x ; then
-enable_grub_fstest=yes
-else
-enable_grub_fstest=no
-fi
-AC_SUBST([enable_grub_fstest])
-
-AC_ARG_ENABLE([grub-mkfont],
-             [AS_HELP_STRING([--enable-grub-mkfont],
-                             [build and install the `grub-mkfont' utility (default=guessed)])])
-if test x"$enable_grub_mkfont" = xno ; then
-  grub_mkfont_excuse="explicitly disabled"
-fi
-
-if test x"$grub_mkfont_excuse" = x ; then
-  # Check for freetype libraries.
-  AC_CHECK_PROGS([FREETYPE], [freetype-config])
-  if test "x$FREETYPE" = x ; then
-    grub_mkfont_excuse=["need freetype2 library"]
-  fi
-  freetype_cflags=`freetype-config --cflags`
-  freetype_libs=`freetype-config --libs`
-fi
-
-if test x"$grub_mkfont_excuse" = x ; then
-  # Check for freetype libraries.
-  SAVED_CPPFLAGS="$CPPFLAGS"
-  CPPFLAGS="$CPPFLAGS $freetype_cflags"
-  AC_CHECK_HEADERS([ft2build.h], [],
-       [grub_mkfont_excuse=["need freetype2 headers"]])
-  CPPFLAGS="$SAVED_CPPFLAGS"
-fi
-
-if test x"$enable_grub_mkfont" = xyes && test x"$grub_mkfont_excuse" != x ; then
-  AC_MSG_ERROR([grub-mkfont was explicitly requested but can't be compiled])
-fi
-if test x"$grub_mkfont_excuse" = x ; then
-enable_grub_mkfont=yes
-else
-enable_grub_mkfont=no
-fi
-AC_SUBST([enable_grub_mkfont])
-AC_SUBST([freetype_cflags])
-AC_SUBST([freetype_libs])
+AM_INIT_AUTOMAKE()
+AC_PREREQ(2.60)
+AC_CONFIG_SRCDIR([grub-core/include/grub/dl.h])
+AC_CONFIG_HEADER([config.h])
 
-AC_SUBST(ASFLAGS)
+m4_include([configure.common])
 
 # Output files.
 grub_CHECK_LINK_DIR
 if test x"$link_dir" = xyes ; then
-  AC_CONFIG_LINKS([include/grub/cpu:include/grub/$target_cpu])
+  AC_CONFIG_LINKS([include/grub/cpu:grub-core/include/grub/$target_cpu])
   if test "$platform" != emu ; then
-    AC_CONFIG_LINKS([include/grub/machine:include/grub/$target_cpu/$platform])
+    AC_CONFIG_LINKS([include/grub/machine:grub-core/include/grub/$target_cpu/$platform])
   fi
 else
   mkdir -p include/grub 2>/dev/null
   rm -rf include/grub/cpu
-  cp -rp $srcdir/include/grub/$target_cpu include/grub/cpu 2>/dev/null
+  cp -rp $srcdir/grub-core/include/grub/$target_cpu include/grub/cpu 2>/dev/null
   if test "$platform" != emu ; then
     rm -rf include/grub/machine
-    cp -rp $srcdir/include/grub/$target_cpu/$platform include/grub/machine 2>/dev/null
+    cp -rp $srcdir/grub-core/include/grub/$target_cpu/$platform include/grub/machine 2>/dev/null
   fi
 fi
-AC_CONFIG_FILES([Makefile gensymlist.sh genkernsyms.sh])
+
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([po/Makefile])
+AC_CONFIG_FILES([docs/Makefile])
 AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h])
+
+AC_CONFIG_SUBDIRS([grub-core])
 AC_OUTPUT
 [
 echo "*******************************************************"
@@ -820,11 +88,6 @@ echo PCI support for grub-emu: Yes
 else
 echo PCI support for grub-emu: No "($grub_emu_pci_excuse)"
 fi
-if [ x"$TARGET_NO_MODULES" = xno ]; then
-echo Module support for grub-emu: Yes
-else
-echo Module support for grub-emu: No
-fi
 fi
 if [ x"$enable_mm_debug" = xyes ]; then
 echo With memory debugging: Yes
diff --git a/configure.common b/configure.common
new file mode 100644 (file)
index 0000000..31bac77
--- /dev/null
@@ -0,0 +1,804 @@
+# -*- autoconf -*-
+
+# Process this file with autoconf to produce a configure script.
+
+# Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+#
+# This configure.ac is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# This file is shared between grub-core and util configure scripts.
+
+# Program name transformations
+AC_ARG_PROGRAM
+
+# Optimization flag.  Allow user to override.
+if test "x$CFLAGS" = x; then
+  CFLAGS="$CFLAGS -Os"
+fi
+
+# Default HOST_CPPFLAGS
+CPPFLAGS=''
+HOST_CPPFLAGS="$HOST_CPPFLAGS -Wall -W"
+HOST_CPPFLAGS="$HOST_CPPFLAGS -I\$(top_srcdir)/grub-core/include"
+HOST_CPPFLAGS="$HOST_CPPFLAGS -I\$(top_builddir)/include"
+HOST_CPPFLAGS="$HOST_CPPFLAGS -I\$(top_srcdir)/grub-core/gnulib"
+HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_UTIL=1"
+HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_LIBDIR=\\\"\$(pkglibdir)\\\""
+HOST_CPPFLAGS="$HOST_CPPFLAGS -DLOCALEDIR=\\\"\$(localedir)\\\""
+
+TARGET_CPPFLAGS="$TARGET_CPPFLAGS -Wall -W"
+TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_srcdir)/include"
+TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_builddir)/include"
+
+case "$target_cpu" in
+  i[[3456]]86) target_cpu=i386 ;;
+  amd64)       target_cpu=x86_64 ;;
+  sparc)       target_cpu=sparc64 ;;
+  mipsel|mips64el)
+                target_cpu=mips;
+               cpu_CPPFLAGS="-DGRUB_CPU_MIPSEL=1";
+               ;;
+  mips|mips64)
+                target_cpu=mips;
+               cpu_CPPFLAGS="-DGRUB_CPU_MIPS=1";
+               ;;
+esac
+
+# Specify the platform (such as firmware).
+AC_ARG_WITH([platform],
+            AS_HELP_STRING([--with-platform=PLATFORM],
+                           [select the host platform [[guessed]]]))
+
+# Guess the platform if not specified.
+if test "x$with_platform" = x; then
+  case "$target_cpu"-"$target_vendor" in
+    i386-apple) platform=efi ;;
+    i386-*) platform=pc ;;
+    x86_64-apple) platform=efi ;;
+    x86_64-*) platform=pc ;;
+    powerpc-*) platform=ieee1275 ;;
+    powerpc64-*) platform=ieee1275 ;;
+    sparc64-*) platform=ieee1275 ;;
+    mips-*) platform=yeeloong ;;
+    *) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;;
+  esac
+else
+  platform="$with_platform"
+fi
+
+# Adjust CPU unless target was explicitly specified.
+if test -z "$target_alias"; then
+  case "$target_cpu"-"$platform" in
+    x86_64-efi) ;;
+    x86_64-emu) ;;
+    x86_64-*) target_cpu=i386 ;;
+    powerpc64-ieee1275) target_cpu=powerpc ;;
+  esac
+fi
+
+# Check if the platform is supported, make final adjustments.
+case "$target_cpu"-"$platform" in
+  i386-efi) ;;
+  x86_64-efi) ;;
+  i386-pc) ;;
+  i386-multiboot) ;;
+  i386-coreboot) ;;
+  i386-linuxbios) platform=coreboot ;;
+  i386-ieee1275) ;;
+  i386-qemu) ;;
+  powerpc-ieee1275) ;;
+  sparc64-ieee1275) ;;
+  mips-qemu-mips) ;;
+  mips-yeeloong) ;;
+  *-emu) ;;
+  *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
+esac
+
+case "$target_cpu" in
+  i386 | powerpc) target_m32=1 ;;
+  x86_64 | sparc64) target_m64=1 ;;
+esac
+
+case "$host_os" in
+  mingw32*) host_os=cygwin ;;
+esac
+
+# This normalizes the names, and creates a new variable ("host_kernel")
+# while at it, since the mapping is not always 1:1 (e.g. different OSes
+# using the same kernel type).
+case "$host_os" in
+  gnu*)                                host_kernel=hurd ;;
+  linux*)                      host_kernel=linux ;;
+  freebsd* | kfreebsd*-gnu)    host_kernel=kfreebsd ;;
+  netbsd*)                     host_kernel=netbsd ;;
+  cygwin)                      host_kernel=windows ;;
+esac
+
+case "$platform" in
+  coreboot)    machine_CPPFLAGS="-DGRUB_MACHINE_COREBOOT=1" ;;
+  multiboot)   machine_CFLAGS="-DGRUB_MACHINE_MULTIBOOT=1" ;;
+  efi)         machine_CPPFLAGS="-DGRUB_MACHINE_EFI=1" ;;
+  ieee1275)    machine_CPPFLAGS="-DGRUB_MACHINE_IEEE1275=1" ;;
+  qemu)                machine_CPPFLAGS="-DGRUB_MACHINE_QEMU=1" ;;
+  pc)          machine_CPPFLAGS="-DGRUB_MACHINE_PCBIOS=1" ;;
+  emu)         machine_CPPFLAGS="-DGRUB_MACHINE_EMU=1" ;;
+  yeeloong)    machine_CPPFLAGS="-DGRUB_MACHINE_MIPS_YEELOONG=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;;
+  qemu-mips)   machine_CPPFLAGS="-DGRUB_MACHINE_MIPS_QEMU_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;;
+esac
+case "$target_cpu" in
+  i386)         cpu_CPPFLAGS="$cpu_CPPFLAGS -DGRUB_CPU_I386";;
+  x86_64)       cpu_CPPFLAGS="$cpu_CPPFLAGS -DGRUB_CPU_X86_64";;
+  powerpc)      cpu_CPPFLAGS="$cpu_CPPFLAGS -DGRUB_CPU_POWERPC";;
+  mips)        machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS=1" ;; # cpu_CPPFLAGS handled above
+  sparc64)      cpu_CPPFLAGS="$cpu_CPPFLAGS -DGRUB_CPU_SPARC64";
+                machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_SPARC64=1" ;;
+esac
+
+HOST_CPPFLAGS="$HOST_CPPFLAGS $cpu_CPPFLAGS $machine_CPPFLAGS"
+TARGET_CPPFLAGS="$TARGET_CPPFLAGS $cpu_CPPFLAGS $machine_CPPFLAGS"
+
+AC_SUBST(host_cpu)
+AC_SUBST(host_os)
+AC_SUBST(host_kernel)
+
+AC_SUBST(target_cpu)
+AC_SUBST(platform)
+
+#
+# Checks for build programs.
+#
+
+# Although cmp is listed in the GNU Coding Standards as a command which
+# can used directly, OpenBSD lacks cmp in the default installation.
+AC_CHECK_PROGS([CMP], [cmp])
+if test "x$CMP" = x; then
+  AC_MSG_ERROR([cmp is not found])
+fi
+
+for file in /usr/src/unifont.bdf /usr/share/fonts/X11/misc/unifont.pcf.gz /usr/share/fonts/unifont/unifont.pcf.gz; do
+  if test -e $file ; then
+    FONT_SOURCE=$file
+    HOST_CPPFLAGS="$HOST_CPPFLAGS -DUSE_ASCII_FAILBACK=1"
+    TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DUSE_ASCII_FAILBACK=1"
+    break
+  fi
+done
+
+AC_PROG_RANLIB
+AC_PROG_INSTALL
+AC_PROG_AWK
+AC_PROG_LEX
+AC_PROG_YACC
+AC_PROG_MAKE_SET
+AC_PROG_MKDIR_P
+
+if test "x$LEX" = x; then
+  AC_MSG_ERROR([flex is not found])
+else
+  version=`$LEX --version | $AWK '{ split($NF,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'`
+  if test -n "$version" -a "$version" -ge 20535; then
+    :
+  else
+    AC_MSG_ERROR([flex is too old. GRUB requires 2.5.35 or above])
+  fi
+fi
+
+# These are not a "must".
+AC_PATH_PROG(MAKEINFO, makeinfo)
+
+#
+# Checks for host programs.
+#
+
+AC_PROG_CC
+AM_PROG_CC_C_O
+AM_PROG_AS
+
+# Must be GCC.
+test "x$GCC" = xyes || AC_MSG_ERROR([GCC is required])
+
+AC_GNU_SOURCE
+AM_GNU_GETTEXT([external])
+AC_SYS_LARGEFILE
+
+# Identify characteristics of the host architecture.
+AC_C_BIGENDIAN
+AC_CHECK_SIZEOF(void *)
+AC_CHECK_SIZEOF(long)
+
+grub_apple_cc
+if test x$grub_cv_apple_cc = xyes ; then
+  HOST_CPPFLAGS="$HOST_CPPFLAGS -DAPPLE_CC=1"
+  HOST_CFLAGS="$HOST_CFLAGS -fnested-functions"
+fi
+
+if test "x$cross_compiling" = xyes; then
+  AC_MSG_WARN([cannot generate manual pages while cross compiling])
+else
+  AC_PATH_PROG(HELP2MAN, help2man)
+fi
+
+# Check for functions.
+AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf)
+
+# For grub-mkisofs
+AC_HEADER_MAJOR
+AC_HEADER_DIRENT
+AC_CHECK_FUNCS(memmove sbrk strdup lstat getuid getgid)
+AC_CHECK_HEADERS(sys/mkdev.h sys/sysmacros.h malloc.h termios.h sys/types.h)
+AC_CHECK_HEADERS(unistd.h string.h strings.h sys/stat.h sys/fcntl.h limits.h)
+
+# For opendisk() and getrawpartition() on NetBSD.
+# Used in util/deviceiter.c and in util/hostdisk.c.
+AC_CHECK_HEADER([util.h], [
+  AC_CHECK_LIB([util], [opendisk], [
+    LIBUTIL="-lutil"
+    AC_DEFINE(HAVE_OPENDISK, 1, [Define if opendisk() in -lutil can be used])
+  ])
+  AC_CHECK_LIB([util], [getrawpartition], [
+    LIBUTIL="-lutil"
+    AC_DEFINE(HAVE_GETRAWPARTITION, 1, [Define if getrawpartition() in -lutil can be used])
+  ])
+])
+AC_SUBST([LIBUTIL])
+
+#
+# Check for host and build compilers.
+#
+HOST_CC=$CC
+AC_CHECK_PROGS(BUILD_CC, [gcc egcs cc],
+                 [AC_MSG_ERROR([none of gcc, egcs and cc is found. set BUILD_CC manually.])])
+
+#
+# Check for target programs.
+#
+
+# Find tools for the target.
+if test "x$target_alias" != x && test "x$host_alias" != "x$target_alias"; then
+  tmp_ac_tool_prefix="$ac_tool_prefix"
+  ac_tool_prefix=$target_alias-
+
+  AC_CHECK_TOOLS(TARGET_CC, [gcc egcs cc],
+                 [AC_MSG_ERROR([none of gcc, egcs and cc is found. set TARGET_CC manually.])])
+  AC_CHECK_TOOL(OBJCOPY, objcopy)
+  AC_CHECK_TOOL(STRIP, strip)
+  AC_CHECK_TOOL(NM, nm)
+
+  ac_tool_prefix="$tmp_ac_tool_prefix"
+else
+  if test "x$TARGET_CC" = x; then
+    TARGET_CC=$CC
+  fi
+  AC_CHECK_TOOL(OBJCOPY, objcopy)
+  AC_CHECK_TOOL(STRIP, strip)
+  AC_CHECK_TOOL(NM, nm)
+fi
+AC_SUBST(HOST_CC)
+AC_SUBST(BUILD_CC)
+AC_SUBST(TARGET_CC)
+
+# Test the C compiler for the target environment.
+tmp_CC="$CC"
+tmp_CFLAGS="$CFLAGS"
+tmp_LDFLAGS="$LDFLAGS"
+tmp_CPPFLAGS="$CPPFLAGS"
+tmp_LIBS="$LIBS"
+CC="$TARGET_CC"
+CFLAGS="$TARGET_CFLAGS"
+CPPFLAGS="$TARGET_CPPFLAGS"
+LDFLAGS="$TARGET_LDFLAGS"
+LIBS=""
+
+# debug flags.
+TARGET_CFLAGS="$TARGET_CFLAGS -Wall -W -Wshadow -Wpointer-arith -Wmissing-prototypes -Wundef -Wstrict-prototypes -g"
+TARGET_CCASFLAGS="$TARGET_CCASFLAGS -g"
+
+# Force no alignment to save space on i386.
+if test "x$target_cpu" = xi386; then
+  AC_CACHE_CHECK([whether -falign-loops works], [grub_cv_cc_falign_loop], [
+    CFLAGS="$CFLAGS -falign-loops=1"
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+        [grub_cv_cc_falign_loop=yes],
+       [grub_cv_cc_falign_loop=no])
+  ])
+
+  if test "x$grub_cv_cc_falign_loop" = xyes; then
+    TARGET_CFLAGS="$TARGET_CFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1"
+  else
+    TARGET_CFLAGS="$TARGET_CFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1"
+  fi
+
+  # Some toolchains enable these features by default, but they need
+  # registers that aren't set up properly in GRUB.
+  TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-3dnow"
+fi
+
+# By default, GCC 4.4 generates .eh_frame sections containing unwind
+# information in some cases where it previously did not. GRUB doesn't need
+# these and they just use up vital space. Restore the old compiler
+# behaviour.
+AC_CACHE_CHECK([whether -fno-dwarf2-cfi-asm works], [grub_cv_cc_fno_dwarf2_cfi_asm], [
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -fno-dwarf2-cfi-asm"
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+      [grub_cv_cc_fno_dwarf2_cfi_asm=yes],
+      [grub_cv_cc_fno_dwarf2_cfi_asm=no])
+  CFLAGS="$SAVE_CFLAGS"
+])
+
+if test "x$grub_cv_cc_fno_dwarf2_cfi_asm" = xyes; then
+  TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm"
+fi
+
+grub_apple_target_cc
+if test x$grub_cv_apple_target_cc = xyes ; then
+  TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DAPPLE_CC=1"
+  TARGET_CFLAGS="$TARGET_CFLAGS -fnested-functions"
+
+  CFLAGS="$CFLAGS -DAPPLE_CC=1 -fnested-functions"
+  TARGET_APPLE_CC=1
+  AC_CHECK_PROG([OBJCONV], [objconv], [objconv], [])
+  if test "x$OBJCONV" = x ; then
+     AC_CHECK_PROG([OBJCONV], [objconv], [./objconv], [], [.])
+  fi
+  if test "x$OBJCONV" = x ; then
+    AC_MSG_ERROR([objconv not found which is required when building with apple compiler])
+  fi
+  TARGET_IMG_LDSCRIPT=
+  TARGET_IMG_CFLAGS="-static"
+  TARGET_IMG_LDFLAGS='-nostdlib -static -Wl,-preload -Wl,-segalign,20 -Wl,-image_base,'
+  TARGET_IMG_LDFLAGS_AC='-nostdlib -static -Wl,-preload -Wl,-segalign,20 -Wl,-image_base,'
+else
+  TARGET_APPLE_CC=0
+# Use linker script if present, otherwise use builtin -N script.
+if test -f "${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"; then
+  TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"
+  TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}  -Wl,-Ttext,"
+  TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc  -Wl,-Ttext,"
+else
+  TARGET_IMG_LDSCRIPT=
+  TARGET_IMG_LDFLAGS='-Wl,-N  -Wl,-Ttext,'
+  TARGET_IMG_LDFLAGS_AC='-Wl,-N  -Wl,-Ttext,'
+fi
+TARGET_IMG_CFLAGS=
+fi
+
+# For platforms where ELF is not the default link format.
+AC_MSG_CHECKING([for command to convert module to ELF format])
+case "${host_os}" in
+  cygwin) TARGET_OBJ2ELF='grub-pe2elf';
+# FIXME: put proper test here
+  AC_DEFINE([NEED_REGISTER_FRAME_INFO], 1,
+           [Define to 1 if GCC generates calls to __register_frame_info()])
+  ;;
+  *) ;;
+esac
+AC_MSG_RESULT([$TARGET_OBJ2ELF])
+
+if test "x$target_m32" = x1; then
+  # Force 32-bit mode.
+  TARGET_CFLAGS="$TARGET_CFLAGS -m32"
+  TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m32"
+  TARGET_LDFLAGS="$TARGET_LDFLAGS -m32"
+  TARGET_MODULE_FORMAT="elf32"
+fi
+
+if test "x$target_m64" = x1; then
+  # Force 64-bit mode.
+  TARGET_CFLAGS="$TARGET_CFLAGS -m64"
+  TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m64"
+  TARGET_LDFLAGS="$TARGET_LDFLAGS -m64"
+  TARGET_MODULE_FORMAT="elf64"
+fi
+
+if test "$target_cpu"-"$platform" = x86_64-efi; then
+  # Use large model to support 4G memory
+  AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [
+    SAVED_CFLAGS=$CFLAGS
+    CFLAGS="$CFLAGS -m64 -mcmodel=large"
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+                     [grub_cv_cc_mcmodel=yes],
+                     [grub_cv_cc_mcmodel=no])
+  ])
+  if test "x$grub_cv_cc_mcmodel" = xno; then
+    AC_MSG_ERROR([-mcmodel=large not supported. Upgrade your gcc.])
+  else
+    TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large"
+  fi
+
+  # EFI writes to stack below %rsp, we must not use the red zone
+  AC_CACHE_CHECK([whether option -mno-red-zone works], grub_cv_cc_no_red_zone, [
+    CFLAGS="$CFLAGS -m64 -mno-red-zone"
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+                     [grub_cv_cc_no_red_zone=yes],
+                     [grub_cv_cc_no_red_zone=no])
+  ])
+  if test "x$grub_cv_cc_no_red_zone" = xno; then
+    AC_MSG_ERROR([-mno-red-zone not supported, upgrade your gcc])
+  fi
+
+  TARGET_CFLAGS="$TARGET_CFLAGS -mno-red-zone"
+fi
+
+#
+# Compiler features.
+#
+
+# Need __enable_execute_stack() for nested function trampolines?
+grub_CHECK_ENABLE_EXECUTE_STACK
+
+# Position independent executable.
+grub_CHECK_PIE
+[# Need that, because some distributions ship compilers that include
+# `-fPIE' in the default specs.
+if [ x"$pie_possible" = xyes ]; then
+  TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE"
+fi]
+
+# Smashing stack protector.
+grub_CHECK_STACK_PROTECTOR
+# Need that, because some distributions ship compilers that include
+# `-fstack-protector' in the default specs.
+if test "x$ssp_possible" = xyes; then
+  TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector"
+fi
+grub_CHECK_STACK_ARG_PROBE
+# Cygwin's GCC uses alloca() to probe the stackframe on static
+# stack allocations above some threshold.
+if test x"$sap_possible" = xyes; then
+  TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe"
+fi
+
+AC_ARG_ENABLE([werror],
+             [AS_HELP_STRING([--disable-werror],
+                             [do not use -Werror when building GRUB])])
+if test x"$enable_werror" != xno ; then
+  TARGET_CFLAGS="$TARGET_CFLAGS -Werror"
+fi
+
+AC_SUBST(TARGET_MODULE_FORMAT)
+AC_SUBST(OBJCONV)
+AC_SUBST(TARGET_APPLE_CC)
+
+AC_SUBST(TARGET_CFLAGS)
+AC_SUBST(TARGET_LDFLAGS)
+AC_SUBST(TARGET_CPPFLAGS)
+AC_SUBST(TARGET_CCASFLAGS)
+
+AC_SUBST(HOST_CFLAGS)
+AC_SUBST(HOST_LDFLAGS)
+AC_SUBST(HOST_CPPFLAGS)
+AC_SUBST(HOST_CCASFLAGS)
+
+# Set them to their new values for the tests below.
+CC="$TARGET_CC"
+if test "x$TARGET_APPLE_CC" = x1 ; then
+CFLAGS="$TARGET_CFLAGS -nostdlib -Wno-error"
+else
+CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100 -Wno-error"
+fi
+CPPFLAGS="$TARGET_CPPFLAGS"
+LDFLAGS="$TARGET_LDFLAGS"
+LIBS=-lgcc
+
+grub_ASM_USCORE
+if test x$grub_cv_asm_uscore = xyes; then
+CFLAGS="$CFLAGS -Wl,--defsym,_abort=_main"
+else
+CFLAGS="$CFLAGS -Wl,--defsym,abort=main"
+fi
+
+# Check for libgcc symbols
+AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x)
+
+if test "x$TARGET_APPLE_CC" = x1 ; then
+CFLAGS="$TARGET_CFLAGS -nostdlib"
+else
+CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100"
+fi
+LIBS=""
+
+# Defined in aclocal.m4.
+grub_PROG_TARGET_CC
+if test "x$TARGET_APPLE_CC" != x1 ; then
+grub_PROG_OBJCOPY_ABSOLUTE
+fi
+grub_PROG_LD_BUILD_ID_NONE
+if test "x$target_cpu" = xi386; then
+  if test "$platform" != emu && test "x$TARGET_APPLE_CC" != x1 ; then
+    if test ! -z "$TARGET_IMG_LDSCRIPT"; then
+      # Check symbols provided by linker script.
+      CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC}8000 -Wl,--defsym,___main=0x8100"
+    fi
+    grub_CHECK_BSS_START_SYMBOL
+    grub_CHECK_END_SYMBOL
+  fi
+  CFLAGS="$TARGET_CFLAGS"
+  grub_I386_ASM_PREFIX_REQUIREMENT
+  grub_I386_ASM_ADDR32
+  grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK
+else
+  AC_DEFINE([NESTED_FUNC_ATTR], [], [Catch gcc bug])
+fi
+
+AH_BOTTOM([#if defined(__i386__) && !defined(GRUB_UTIL)
+#define NESTED_FUNC_ATTR __attribute__ ((__regparm__ (1)))
+#else
+#define NESTED_FUNC_ATTR
+#endif])
+
+AC_ARG_ENABLE([efiemu],
+             [AS_HELP_STRING([--enable-efiemu],
+                             [build and install the efiemu runtimes (default=guessed)])])
+if test x"$enable_efiemu" = xno ; then
+  efiemu_excuse="explicitly disabled"
+fi
+if test x"$efiemu_excuse" = x ; then
+  AC_CACHE_CHECK([whether options required for efiemu work], grub_cv_cc_efiemu, [
+    CFLAGS="$CFLAGS -m64 -mcmodel=large -mno-red-zone -nostdlib"
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+                     [grub_cv_cc_efiemu=yes],
+                     [grub_cv_cc_efiemu=no])
+  ])
+  if test x$grub_cv_cc_efiemu = xno; then
+     efiemu_excuse="cannot compile with -m64 -mcmodel=large -mno-red-zone -nostdlib"
+  fi
+fi
+if test x"$enable_efiemu" = xyes && test x"$efiemu_excuse" != x ; then
+  AC_MSG_ERROR([efiemu runtime was explicitly requested but can't be compiled])
+fi
+if test x"$efiemu_excuse" = x ; then
+enable_efiemu=yes
+else
+enable_efiemu=no
+fi
+AC_SUBST([enable_efiemu])
+
+if test "$platform" != emu; then
+AC_CACHE_CHECK([whether -nostdinc -isystem works], [grub_cv_cc_isystem], [
+  SAVED_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -isystem `$TARGET_CC -print-file-name=include`"
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdarg.h>
+int va_arg_func (int fixed, va_list args);]], [[]])],
+      [grub_cv_cc_isystem=yes],
+      [grub_cv_cc_isystem=no])
+  CPPFLAGS="$SAVED_CPPFLAGS"
+])
+
+if test x"$grub_cv_cc_isystem" = xyes ; then
+  TARGET_CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -isystem `$TARGET_CC -print-file-name=include`"
+fi
+fi
+
+# Restore the flags.
+CC="$tmp_CC"
+CFLAGS="$tmp_CFLAGS"
+CPPFLAGS="$tmp_CPPFLAGS"
+LDFLAGS="$tmp_LDFLAGS"
+LIBS="$tmp_LIBS"
+
+#
+# Check for options.
+#
+
+# Memory manager debugging.
+AC_ARG_ENABLE([mm-debug],
+             AS_HELP_STRING([--enable-mm-debug],
+                             [include memory manager debugging]),
+              [AC_DEFINE([MM_DEBUG], [1],
+                         [Define to 1 if you enable memory manager debugging.])])
+
+AC_ARG_ENABLE([grub-emu-usb],
+             [AS_HELP_STRING([--enable-grub-emu-usb],
+                             [build and install the `grub-emu' debugging utility with USB support (default=guessed)])])
+
+AC_ARG_ENABLE([grub-emu-sdl],
+             [AS_HELP_STRING([--enable-grub-emu-sdl],
+                             [build and install the `grub-emu' debugging utility with SDL support (default=guessed)])])
+
+AC_ARG_ENABLE([grub-emu-pci],
+             [AS_HELP_STRING([--enable-grub-emu-pci],
+                             [build and install the `grub-emu' debugging utility with PCI support (potentially dangerous) (default=no)])])
+
+if test "$platform" = emu; then
+  missing_ncurses=
+[# Check for curses libraries.]
+  AC_CHECK_LIB([ncurses], [wgetch], [LIBCURSES="-lncurses"],
+    [AC_CHECK_LIB([curses], [wgetch], [LIBCURSES="-lcurses"],
+      [missing_ncurses=[true]])])
+  AC_SUBST([LIBCURSES])
+[if [ x"$missing_ncurses" = x ]; then ]
+  [# Check for headers.]
+  AC_CHECK_HEADERS([ncurses/curses.h], [],
+    [AC_CHECK_HEADERS([ncurses.h], [],
+      [AC_CHECK_HEADERS([curses.h], [],
+       [missing_ncurses=[true]])])])
+[fi]
+if test x"$missing_ncurses" = xtrue ; then
+  AC_MSG_ERROR([grub-emu can't be compiled without ncurses])
+fi
+
+if test x"$enable_grub_emu_usb" = xno ; then
+  grub_emu_usb_excuse="explicitly disabled"
+fi
+
+if test x"$enable_grub_emu_pci" = xyes ; then
+   grub_emu_usb_excuse="conflicts with PCI support"
+fi
+
+[if [ x"$grub_emu_usb_excuse" = x ]; then
+    # Check for libusb libraries.]
+AC_CHECK_LIB([usb], [usb_claim_interface], [LIBUSB="-lusb"],
+    [grub_emu_usb_excuse=["need libusb library"]])
+    AC_SUBST([LIBUSB])
+[fi]
+[if [ x"$grub_emu_usb_excuse" = x ]; then
+    # Check for headers.]
+    AC_CHECK_HEADERS([usb.h], [],
+      [grub_emu_usb_excuse=["need libusb headers"]])
+[fi]
+if test x"$enable_grub_emu_usb" = xyes && test x"$grub_emu_usb_excuse" != x ; then
+  AC_MSG_ERROR([USB support for grub-emu was explicitly requested but can't be compiled])
+fi
+if test x"$grub_emu_usb_excuse" = x ; then
+enable_grub_emu_usb=yes
+else
+enable_grub_emu_usb=no
+fi
+
+if test x"$enable_grub_emu_sdl" = xno ; then
+  grub_emu_sdl_excuse="explicitely disabled"
+fi
+[if [ x"$grub_emu_sdl_excuse" = x ]; then
+    # Check for libSDL libraries.]
+AC_CHECK_LIB([SDL], [SDL_Init], [LIBSDL="-lSDL"],
+    [grub_emu_sdl_excuse=["libSDL libraries are required to build \`grub-emu' with SDL support"]])
+    AC_SUBST([LIBSDL])
+[fi]
+
+[if [ x"$grub_emu_sdl_excuse" = x ]; then
+    # Check for headers.]
+    AC_CHECK_HEADERS([SDL/SDL.h], [],
+      [grub_emu_sdl_excuse=["libSDL header file is required to build \`grub-emu' with SDL support"]])
+[fi]
+
+if test x"enable_grub_emu_sdl" = xyes && test x"$grub_emu_sdl_excuse" != x ; then
+  AC_MSG_ERROR([SDL support for grub-emu was explicitely requested but can't be compiled])
+fi
+if test x"$grub_emu_sdl_excuse" = x ; then
+enable_grub_emu_sdl=yes
+else
+enable_grub_emu_sdl=no
+fi
+
+if test x"$enable_grub_emu_pci" != xyes ; then
+   grub_emu_pci_excuse="not enabled"
+fi
+
+if test x"$enable_grub_emu_usb" = xyes ; then
+   grub_emu_pci_excuse="conflicts with USB support"
+fi
+
+[if [ x"$grub_emu_pci_excuse" = x ]; then
+      # Check for libpci libraries.]
+   AC_CHECK_LIB([pciaccess], [pci_system_init], [LIBPCIACCESS="-lpciaccess"],
+      [grub_emu_pci_excuse=["need libpciaccess library"]])
+    AC_SUBST([LIBPCIACCESS])
+[fi]
+[if [ x"$grub_emu_pci_excuse" = x ]; then
+    # Check for headers.]
+    AC_CHECK_HEADERS([pci/pci.h], [],
+      [grub_emu_pci_excuse=["need libpciaccess headers"]])
+[fi]
+
+if test x"$grub_emu_pci_excuse" = x ; then
+enable_grub_emu_pci=yes
+else
+
+enable_grub_emu_pci=no
+fi
+
+AC_SUBST([enable_grub_emu_sdl])
+AC_SUBST([enable_grub_emu_usb])
+AC_SUBST([enable_grub_emu_pci])
+fi
+
+AC_ARG_ENABLE([grub-fstest],
+             [AS_HELP_STRING([--enable-grub-fstest],
+                             [build and install the `grub-fstest' debugging utility (default=guessed)])])
+if test x"$enable_grub_fstest" = xno ; then
+  grub_fstest_excuse="explicitly disabled"
+fi
+if test x"$grub_fstest_excuse" = x ; then
+enable_grub_fstest=yes
+else
+enable_grub_fstest=no
+fi
+AC_SUBST([enable_grub_fstest])
+
+AC_ARG_ENABLE([grub-mkfont],
+             [AS_HELP_STRING([--enable-grub-mkfont],
+                             [build and install the `grub-mkfont' utility (default=guessed)])])
+if test x"$enable_grub_mkfont" = xno ; then
+  grub_mkfont_excuse="explicitly disabled"
+fi
+
+if test x"$grub_mkfont_excuse" = x ; then
+  # Check for freetype libraries.
+  AC_CHECK_PROGS([FREETYPE], [freetype-config])
+  if test "x$FREETYPE" = x ; then
+    grub_mkfont_excuse=["need freetype2 library"]
+  fi
+  freetype_cflags=`freetype-config --cflags`
+  freetype_libs=`freetype-config --libs`
+fi
+
+if test x"$grub_mkfont_excuse" = x ; then
+  # Check for freetype libraries.
+  SAVED_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $freetype_cflags"
+  AC_CHECK_HEADERS([ft2build.h], [],
+       [grub_mkfont_excuse=["need freetype2 headers"]])
+  CPPFLAGS="$SAVED_CPPFLAGS"
+fi
+
+if test x"$enable_grub_mkfont" = xyes && test x"$grub_mkfont_excuse" != x ; then
+  AC_MSG_ERROR([grub-mkfont was explicitly requested but can't be compiled])
+fi
+if test x"$grub_mkfont_excuse" = x ; then
+enable_grub_mkfont=yes
+else
+enable_grub_mkfont=no
+fi
+AC_SUBST([enable_grub_mkfont])
+AC_SUBST([freetype_cflags])
+AC_SUBST([freetype_libs])
+
+AC_SUBST([FONT_SOURCE])
+AS_IF([test x$target_cpu = xi386 -a x$platform = xpc],
+           [AC_SUBST([GRUB_KERNEL_MACHINE_LINK_ADDR], 0x8200)])
+AS_IF([test x$target_cpu = xi386 -a x$platform = xcoreboot],
+           [AC_SUBST([GRUB_KERNEL_MACHINE_LINK_ADDR], 0x8200)])
+AS_IF([test x$target_cpu = xmips -a x$platform = xyeeloong],
+           [AC_SUBST([GRUB_KERNEL_MACHINE_LINK_ADDR], 0x80200000)])
+AS_IF([test x$target_cpu = xpowerpc -a x$platform = xieee1275],
+           [AC_SUBST([GRUB_KERNEL_MACHINE_LINK_ADDR], 0x200000)])
+AS_IF([test x$target_cpu = xi386 -a x$platform = xqemu],
+           [AC_SUBST([GRUB_BOOT_MACHINE_LINK_ADDR], 0xffe00)])
+AS_IF([test x$target_cpu = xi386 -a x$platform = xieee1275],
+           [AC_SUBST([GRUB_KERNEL_MACHINE_LINK_ADDR], 0x10000)])
+AS_IF([test x$TARGET_APPLE_CC = x1],
+           [AC_SUBST([USE_APPLE_CC_FIXES], yes)])
+
+#
+# Automake conditionals
+#
+
+AM_CONDITIONAL([COND_emu], [test x$platform = xemu])
+AM_CONDITIONAL([COND_i386_pc], [test x$target_cpu = xi386 -a x$platform = xpc])
+AM_CONDITIONAL([COND_i386_efi], [test x$target_cpu = xi386 -a x$platform = xefi])
+AM_CONDITIONAL([COND_i386_coreboot], [test x$target_cpu = xi386 -a x$platform = xcoreboot])
+AM_CONDITIONAL([COND_i386_ieee1275], [test x$target_cpu = xi386 -a x$platform = xieee1275])
+AM_CONDITIONAL([COND_i386_qemu], [test x$target_cpu = xi386 -a x$platform = xqemu])
+AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi])
+AM_CONDITIONAL([COND_mips_yeeloong], [test x$target_cpu = xmips -a x$platform = xyeeloong])
+AM_CONDITIONAL([COND_mips_qemu_mips], [test x$target_cpu = xmips -a x$platform = xqemu_mips])
+AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275])
+AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275])
+
+AM_CONDITIONAL([COND_MAN_PAGES], [test x$cross_compiling = xno -a x$HELP2MAN != x])
+AM_CONDITIONAL([COND_GRUB_EMU_USB], [test x$enable_grub_emu_usb = xyes])
+AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes])
+AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes])
+AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes])
+AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x])
+AM_CONDITIONAL([COND_GRUB_FSTEST], [test x$enable_grub_fstest = xyes])
+AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes])
+
diff --git a/disk/ata.c b/disk/ata.c
deleted file mode 100644 (file)
index 687ed93..0000000
+++ /dev/null
@@ -1,894 +0,0 @@
-/* ata.c - ATA disk access.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007, 2008, 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/ata.h>
-#include <grub/dl.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/time.h>
-#include <grub/pci.h>
-#include <grub/scsi.h>
-
-/* At the moment, only two IDE ports are supported.  */
-static const grub_port_t grub_ata_ioaddress[] = { 0x1f0, 0x170 };
-static const grub_port_t grub_ata_ioaddress2[] = { 0x3f6, 0x376 };
-
-static struct grub_ata_device *grub_ata_devices;
-
-/* Wait for !BSY.  */
-grub_err_t
-grub_ata_wait_not_busy (struct grub_ata_device *dev, int milliseconds)
-{
-  /* ATA requires 400ns (after a write to CMD register) or
-     1 PIO cycle (after a DRQ block transfer) before
-     first check of BSY.  */
-  grub_millisleep (1);
-
-  int i = 1;
-  grub_uint8_t sts;
-  while ((sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS))
-        & GRUB_ATA_STATUS_BUSY)
-    {
-      if (i >= milliseconds)
-        {
-         grub_dprintf ("ata", "timeout: %dms, status=0x%x\n",
-                       milliseconds, sts);
-         return grub_error (GRUB_ERR_TIMEOUT, "ATA timeout");
-       }
-
-      grub_millisleep (1);
-      i++;
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-static inline void
-grub_ata_wait (void)
-{
-  grub_millisleep (50);
-}
-
-/* Wait for !BSY, DRQ.  */
-grub_err_t
-grub_ata_wait_drq (struct grub_ata_device *dev, int rw,
-                  int milliseconds)
-{
-  if (grub_ata_wait_not_busy (dev, milliseconds))
-    return grub_errno;
-
-  /* !DRQ implies error condition.  */
-  grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
-  if ((sts & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
-      != GRUB_ATA_STATUS_DRQ)
-    {
-      grub_dprintf ("ata", "ata error: status=0x%x, error=0x%x\n",
-                   sts, grub_ata_regget (dev, GRUB_ATA_REG_ERROR));
-      if (! rw)
-        return grub_error (GRUB_ERR_READ_ERROR, "ATA read error");
-      else
-        return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-/* Byteorder has to be changed before strings can be read.  */
-static void
-grub_ata_strncpy (char *dst, char *src, grub_size_t len)
-{
-  grub_uint16_t *src16 = (grub_uint16_t *) src;
-  grub_uint16_t *dst16 = (grub_uint16_t *) dst;
-  unsigned int i;
-
-  for (i = 0; i < len / 2; i++)
-    *(dst16++) = grub_be_to_cpu16 (*(src16++));
-  dst[len] = '\0';
-}
-
-void
-grub_ata_pio_read (struct grub_ata_device *dev, char *buf, grub_size_t size)
-{
-  grub_uint16_t *buf16 = (grub_uint16_t *) buf;
-  unsigned int i;
-
-  /* Read in the data, word by word.  */
-  for (i = 0; i < size / 2; i++)
-    buf16[i] = grub_le_to_cpu16 (grub_inw(dev->ioaddress + GRUB_ATA_REG_DATA));
-}
-
-static void
-grub_ata_pio_write (struct grub_ata_device *dev, char *buf, grub_size_t size)
-{
-  grub_uint16_t *buf16 = (grub_uint16_t *) buf;
-  unsigned int i;
-
-  /* Write the data, word by word.  */
-  for (i = 0; i < size / 2; i++)
-    grub_outw(grub_cpu_to_le16 (buf16[i]), dev->ioaddress + GRUB_ATA_REG_DATA);
-}
-
-static void
-grub_ata_dumpinfo (struct grub_ata_device *dev, char *info)
-{
-  char text[41];
-
-  /* The device information was read, dump it for debugging.  */
-  grub_ata_strncpy (text, info + 20, 20);
-  grub_dprintf ("ata", "Serial: %s\n", text);
-  grub_ata_strncpy (text, info + 46, 8);
-  grub_dprintf ("ata", "Firmware: %s\n", text);
-  grub_ata_strncpy (text, info + 54, 40);
-  grub_dprintf ("ata", "Model: %s\n", text);
-
-  if (! dev->atapi)
-    {
-      grub_dprintf ("ata", "Addressing: %d\n", dev->addr);
-      grub_dprintf ("ata", "Sectors: %lld\n", (unsigned long long) dev->size);
-    }
-}
-
-static grub_err_t
-grub_atapi_identify (struct grub_ata_device *dev)
-{
-  char *info;
-
-  info = grub_malloc (GRUB_DISK_SECTOR_SIZE);
-  if (! info)
-    return grub_errno;
-
-  grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
-  grub_ata_wait ();
-  if (grub_ata_check_ready (dev))
-    {
-      grub_free (info);
-      return grub_errno;
-    }
-
-  grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE);
-  grub_ata_wait ();
-
-  if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD))
-    {
-      grub_free (info);
-      return grub_errno;
-    }
-  grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
-
-  dev->atapi = 1;
-
-  grub_ata_dumpinfo (dev, info);
-
-  grub_free (info);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_atapi_wait_drq (struct grub_ata_device *dev,
-                    grub_uint8_t ireason,
-                    int milliseconds)
-{
-  /* Wait for !BSY, DRQ, ireason */
-  if (grub_ata_wait_not_busy (dev, milliseconds))
-    return grub_errno;
-
-  grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
-  grub_uint8_t irs = grub_ata_regget (dev, GRUB_ATAPI_REG_IREASON);
-
-  /* OK if DRQ is asserted and interrupt reason is as expected.  */
-  if ((sts & GRUB_ATA_STATUS_DRQ)
-      && (irs & GRUB_ATAPI_IREASON_MASK) == ireason)
-    return GRUB_ERR_NONE;
-
-  /* !DRQ implies error condition.  */
-  grub_dprintf ("ata", "atapi error: status=0x%x, ireason=0x%x, error=0x%x\n",
-               sts, irs, grub_ata_regget (dev, GRUB_ATA_REG_ERROR));
-
-  if (! (sts & GRUB_ATA_STATUS_DRQ)
-      && (irs & GRUB_ATAPI_IREASON_MASK) == GRUB_ATAPI_IREASON_ERROR)
-    {
-      if (ireason == GRUB_ATAPI_IREASON_CMD_OUT)
-       return grub_error (GRUB_ERR_READ_ERROR, "ATA PACKET command error");
-      else
-       return grub_error (GRUB_ERR_READ_ERROR, "ATAPI read error");
-    }
-
-  return grub_error (GRUB_ERR_READ_ERROR, "ATAPI protocol error");
-}
-
-static grub_err_t
-grub_atapi_packet (struct grub_ata_device *dev, char *packet,
-                  grub_size_t size)
-{
-  grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
-  if (grub_ata_check_ready (dev))
-    return grub_errno;
-
-  /* Send ATA PACKET command.  */
-  grub_ata_regset (dev, GRUB_ATA_REG_FEATURES, 0);
-  grub_ata_regset (dev, GRUB_ATAPI_REG_IREASON, 0);
-  grub_ata_regset (dev, GRUB_ATAPI_REG_CNTHIGH, size >> 8);
-  grub_ata_regset (dev, GRUB_ATAPI_REG_CNTLOW, size & 0xFF);
-
-  grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_PACKET);
-
-  /* Wait for !BSY, DRQ, !I/O, C/D.  */
-  if (grub_atapi_wait_drq (dev, GRUB_ATAPI_IREASON_CMD_OUT, GRUB_ATA_TOUT_STD))
-    return grub_errno;
-
-  /* Write the packet.  */
-  grub_ata_pio_write (dev, packet, 12);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_ata_identify (struct grub_ata_device *dev)
-{
-  char *info;
-  grub_uint16_t *info16;
-
-  info = grub_malloc (GRUB_DISK_SECTOR_SIZE);
-  if (! info)
-    return grub_errno;
-
-  info16 = (grub_uint16_t *) info;
-
-  grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
-  grub_ata_wait ();
-  if (grub_ata_check_ready (dev))
-    {
-      grub_free (info);
-      return grub_errno;
-    }
-
-  grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_DEVICE);
-  grub_ata_wait ();
-
-  if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD))
-    {
-      grub_free (info);
-      grub_errno = GRUB_ERR_NONE;
-      grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
-
-      if ((sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ
-         | GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_ERR
-         && (grub_ata_regget (dev, GRUB_ATA_REG_ERROR) & 0x04 /* ABRT */))
-       /* Device without ATA IDENTIFY, try ATAPI.  */
-       return grub_atapi_identify (dev);
-
-      else if (sts == 0x00)
-       /* No device, return error but don't print message.  */
-       return GRUB_ERR_UNKNOWN_DEVICE;
-
-      else
-       /* Other Error.  */
-       return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
-                          "device cannot be identified");
-    }
-
-  grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
-
-  /* Re-check status to avoid bogus identify data due to stuck DRQ.  */
-  grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
-  if (sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
-    {
-      grub_dprintf ("ata", "bad status=0x%x\n", sts);
-      grub_free (info);
-      /* No device, return error but don't print message.  */
-      grub_errno = GRUB_ERR_NONE;
-      return GRUB_ERR_UNKNOWN_DEVICE;
-    }
-
-  /* Now it is certain that this is not an ATAPI device.  */
-  dev->atapi = 0;
-
-  /* CHS is always supported.  */
-  dev->addr = GRUB_ATA_CHS;
-
-  /* Check if LBA is supported.  */
-  if (info16[49] & (1 << 9))
-    {
-      /* Check if LBA48 is supported.  */
-      if (info16[83] & (1 << 10))
-       dev->addr = GRUB_ATA_LBA48;
-      else
-       dev->addr = GRUB_ATA_LBA;
-    }
-
-  /* Determine the amount of sectors.  */
-  if (dev->addr != GRUB_ATA_LBA48)
-    dev->size = grub_le_to_cpu32(*((grub_uint32_t *) &info16[60]));
-  else
-    dev->size = grub_le_to_cpu64(*((grub_uint64_t *) &info16[100]));
-
-  /* Read CHS information.  */
-  dev->cylinders = info16[1];
-  dev->heads = info16[3];
-  dev->sectors_per_track = info16[6];
-
-  grub_ata_dumpinfo (dev, info);
-
-  grub_free(info);
-
-  return 0;
-}
-
-static grub_err_t
-grub_ata_device_initialize (int port, int device, int addr, int addr2)
-{
-  struct grub_ata_device *dev;
-  struct grub_ata_device **devp;
-
-  grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n",
-               port, device, addr, addr2);
-
-  dev = grub_malloc (sizeof(*dev));
-  if (! dev)
-    return grub_errno;
-
-  /* Setup the device information.  */
-  dev->port = port;
-  dev->device = device;
-  dev->ioaddress = addr + GRUB_MACHINE_PCI_IO_BASE;
-  dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE;
-  dev->next = NULL;
-
-  grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
-  grub_ata_wait ();
-
-  /* Try to detect if the port is in use by writing to it,
-     waiting for a while and reading it again.  If the value
-     was preserved, there is a device connected.  */
-  grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
-  grub_ata_wait ();
-  grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS);
-  grub_dprintf ("ata", "sectors=0x%x\n", sec);
-  if (sec != 0x5A)
-    {
-      grub_free(dev);
-      return 0;
-    }
-
-  /* The above test may detect a second (slave) device
-     connected to a SATA controller which supports only one
-     (master) device.  It is not safe to use the status register
-     READY bit to check for controller channel existence.  Some
-     ATAPI commands (RESET, DIAGNOSTIC) may clear this bit.  */
-
-  /* Use the IDENTIFY DEVICE command to query the device.  */
-  if (grub_ata_identify (dev))
-    {
-      grub_free (dev);
-      return 0;
-    }
-
-  /* Register the device.  */
-  for (devp = &grub_ata_devices; *devp; devp = &(*devp)->next);
-  *devp = dev;
-
-  return 0;
-}
-
-static int NESTED_FUNC_ATTR
-grub_ata_pciinit (grub_pci_device_t dev,
-                 grub_pci_id_t pciid)
-{
-  static int compat_use[2] = { 0 };
-  grub_pci_address_t addr;
-  grub_uint32_t class;
-  grub_uint32_t bar1;
-  grub_uint32_t bar2;
-  int rega;
-  int regb;
-  int i;
-  static int controller = 0;
-  int cs5536 = 0;
-  int nports = 2;
-
-  /* Read class.  */
-  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
-  class = grub_pci_read (addr);
-
-  /* AMD CS5536 Southbridge.  */
-  if (pciid == 0x208f1022)
-    {
-      cs5536 = 1;
-      nports = 1;
-    }
-
-  /* Check if this class ID matches that of a PCI IDE Controller.  */
-  if (!cs5536 && (class >> 16 != 0x0101))
-    return 0;
-
-  for (i = 0; i < nports; i++)
-    {
-      /* Set to 0 when the channel operated in compatibility mode.  */
-      int compat;
-
-      /* We don't support non-compatibility mode for CS5536.  */
-      if (cs5536)
-       compat = 0;
-      else
-       compat = (class >> (8 + 2 * i)) & 1;
-
-      rega = 0;
-      regb = 0;
-
-      /* If the channel is in compatibility mode, just assign the
-        default registers.  */
-      if (compat == 0 && !compat_use[i])
-       {
-         rega = grub_ata_ioaddress[i];
-         regb = grub_ata_ioaddress2[i];
-         compat_use[i] = 1;
-       }
-      else if (compat)
-       {
-         /* Read the BARs, which either contain a mmapped IO address
-            or the IO port address.  */
-         addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES
-                                       + sizeof (grub_uint64_t) * i);
-         bar1 = grub_pci_read (addr);
-         addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES
-                                       + sizeof (grub_uint64_t) * i
-                                       + sizeof (grub_uint32_t));
-         bar2 = grub_pci_read (addr);
-
-         /* Check if the BARs describe an IO region.  */
-         if ((bar1 & 1) && (bar2 & 1))
-           {
-             rega = bar1 & ~3;
-             regb = bar2 & ~3;
-           }
-       }
-
-      grub_dprintf ("ata",
-                   "PCI dev (%d,%d,%d) compat=%d rega=0x%x regb=0x%x\n",
-                   grub_pci_get_bus (dev), grub_pci_get_device (dev),
-                   grub_pci_get_function (dev), compat, rega, regb);
-
-      if (rega && regb)
-       {
-         grub_errno = GRUB_ERR_NONE;
-         grub_ata_device_initialize (controller * 2 + i, 0, rega, regb);
-
-         /* Most errors raised by grub_ata_device_initialize() are harmless.
-            They just indicate this particular drive is not responding, most
-            likely because it doesn't exist.  We might want to ignore specific
-            error types here, instead of printing them.  */
-         if (grub_errno)
-           {
-             grub_print_error ();
-             grub_errno = GRUB_ERR_NONE;
-           }
-
-         grub_ata_device_initialize (controller * 2 + i, 1, rega, regb);
-
-         /* Likewise.  */
-         if (grub_errno)
-           {
-             grub_print_error ();
-             grub_errno = GRUB_ERR_NONE;
-           }
-       }
-    }
-
-  controller++;
-
-  return 0;
-}
-
-static grub_err_t
-grub_ata_initialize (void)
-{
-  grub_pci_iterate (grub_ata_pciinit);
-  return 0;
-}
-
-static void
-grub_ata_setlba (struct grub_ata_device *dev, grub_disk_addr_t sector,
-                grub_size_t size)
-{
-  grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, size);
-  grub_ata_regset (dev, GRUB_ATA_REG_LBALOW, sector & 0xFF);
-  grub_ata_regset (dev, GRUB_ATA_REG_LBAMID, (sector >> 8) & 0xFF);
-  grub_ata_regset (dev, GRUB_ATA_REG_LBAHIGH, (sector >> 16) & 0xFF);
-}
-
-static grub_err_t
-grub_ata_setaddress (struct grub_ata_device *dev,
-                    grub_ata_addressing_t addressing,
-                    grub_disk_addr_t sector,
-                    grub_size_t size)
-{
-  switch (addressing)
-    {
-    case GRUB_ATA_CHS:
-      {
-       unsigned int cylinder;
-       unsigned int head;
-       unsigned int sect;
-
-       /* Calculate the sector, cylinder and head to use.  */
-       sect = ((grub_uint32_t) sector % dev->sectors_per_track) + 1;
-       cylinder = (((grub_uint32_t) sector / dev->sectors_per_track)
-                   / dev->heads);
-       head = ((grub_uint32_t) sector / dev->sectors_per_track) % dev->heads;
-
-       if (sect > dev->sectors_per_track
-           || cylinder > dev->cylinders
-           || head > dev->heads)
-         return grub_error (GRUB_ERR_OUT_OF_RANGE,
-                            "sector %d cannot be addressed "
-                            "using CHS addressing", sector);
-
-       grub_ata_regset (dev, GRUB_ATA_REG_DISK, (dev->device << 4) | head);
-       if (grub_ata_check_ready (dev))
-         return grub_errno;
-
-       grub_ata_regset (dev, GRUB_ATA_REG_SECTNUM, sect);
-       grub_ata_regset (dev, GRUB_ATA_REG_CYLLSB, cylinder & 0xFF);
-       grub_ata_regset (dev, GRUB_ATA_REG_CYLMSB, cylinder >> 8);
-
-       break;
-      }
-
-    case GRUB_ATA_LBA:
-      if (size == 256)
-       size = 0;
-      grub_ata_regset (dev, GRUB_ATA_REG_DISK,
-                      0xE0 | (dev->device << 4) | ((sector >> 24) & 0x0F));
-      if (grub_ata_check_ready (dev))
-       return grub_errno;
-
-      grub_ata_setlba (dev, sector, size);
-      break;
-
-    case GRUB_ATA_LBA48:
-      if (size == 65536)
-       size = 0;
-
-      grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | (dev->device << 4));
-      if (grub_ata_check_ready (dev))
-       return grub_errno;
-
-      /* Set "Previous".  */
-      grub_ata_setlba (dev, sector >> 24, size >> 8);
-      /* Set "Current".  */
-      grub_ata_setlba (dev, sector, size);
-
-      break;
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector,
-                   grub_size_t size, char *buf, int rw)
-{
-  struct grub_ata_device *dev = (struct grub_ata_device *) disk->data;
-
-  grub_dprintf("ata", "grub_ata_readwrite (size=%llu, rw=%d)\n", (unsigned long long) size, rw);
-
-  grub_ata_addressing_t addressing = dev->addr;
-  grub_size_t batch;
-  int cmd, cmd_write;
-
-  if (addressing == GRUB_ATA_LBA48 && ((sector + size) >> 28) != 0)
-    {
-      batch = 65536;
-      cmd = GRUB_ATA_CMD_READ_SECTORS_EXT;
-      cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_EXT;
-    }
-  else
-    {
-      if (addressing == GRUB_ATA_LBA48)
-       addressing = GRUB_ATA_LBA;
-      batch = 256;
-      cmd = GRUB_ATA_CMD_READ_SECTORS;
-      cmd_write = GRUB_ATA_CMD_WRITE_SECTORS;
-    }
-
-  grub_size_t nsectors = 0;
-  while (nsectors < size)
-    {
-      if (size - nsectors < batch)
-       batch = size - nsectors;
-
-      grub_dprintf("ata", "rw=%d, sector=%llu, batch=%llu\n", rw, (unsigned long long) sector, (unsigned long long) batch);
-
-      /* Send read/write command.  */
-      if (grub_ata_setaddress (dev, addressing, sector, batch))
-       return grub_errno;
-
-      grub_ata_regset (dev, GRUB_ATA_REG_CMD, (! rw ? cmd : cmd_write));
-
-      unsigned sect;
-      for (sect = 0; sect < batch; sect++)
-       {
-         /* Wait for !BSY, DRQ.  */
-         if (grub_ata_wait_drq (dev, rw, GRUB_ATA_TOUT_DATA))
-           return grub_errno;
-
-         /* Transfer data.  */
-         if (! rw)
-           grub_ata_pio_read (dev, buf, GRUB_DISK_SECTOR_SIZE);
-         else
-           grub_ata_pio_write (dev, buf, GRUB_DISK_SECTOR_SIZE);
-
-         buf += GRUB_DISK_SECTOR_SIZE;
-       }
-
-      if (rw)
-        {
-         /* Check for write error.  */
-         if (grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA))
-           return grub_errno;
-
-         if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS)
-             & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
-           return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
-       }
-
-      sector += batch;
-      nsectors += batch;
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-\f
-
-static int
-grub_ata_iterate (int (*hook) (const char *name))
-{
-  struct grub_ata_device *dev;
-
-  for (dev = grub_ata_devices; dev; dev = dev->next)
-    {
-      char devname[10];
-
-      if (dev->atapi)
-       continue;
-
-      grub_snprintf (devname, sizeof (devname), 
-                    "ata%d", dev->port * 2 + dev->device);
-
-      if (hook (devname))
-       return 1;
-    }
-
-  return 0;
-}
-
-static grub_err_t
-grub_ata_open (const char *name, grub_disk_t disk)
-{
-  struct grub_ata_device *dev;
-
-  for (dev = grub_ata_devices; dev; dev = dev->next)
-    {
-      char devname[10];
-      grub_snprintf (devname, sizeof (devname),
-                    "ata%d", dev->port * 2 + dev->device);
-      if (grub_strcmp (name, devname) == 0)
-       break;
-    }
-
-  if (! dev)
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
-
-  if (dev->atapi)
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk");
-
-  disk->total_sectors = dev->size;
-
-  disk->id = (unsigned long) dev;
-
-  disk->has_partitions = 1;
-  disk->data = dev;
-
-  return 0;
-}
-
-static void
-grub_ata_close (grub_disk_t disk __attribute__((unused)))
-{
-
-}
-
-static grub_err_t
-grub_ata_read (grub_disk_t disk, grub_disk_addr_t sector,
-              grub_size_t size, char *buf)
-{
-  return grub_ata_readwrite (disk, sector, size, buf, 0);
-}
-
-static grub_err_t
-grub_ata_write (grub_disk_t disk,
-               grub_disk_addr_t sector,
-               grub_size_t size,
-               const char *buf)
-{
-  return grub_ata_readwrite (disk, sector, size, (char *) buf, 1);
-}
-
-static struct grub_disk_dev grub_atadisk_dev =
-  {
-    .name = "ATA",
-    .id = GRUB_DISK_DEVICE_ATA_ID,
-    .iterate = grub_ata_iterate,
-    .open = grub_ata_open,
-    .close = grub_ata_close,
-    .read = grub_ata_read,
-    .write = grub_ata_write,
-    .next = 0
-  };
-
-
-\f
-/* ATAPI code.  */
-
-static int
-grub_atapi_iterate (int (*hook) (const char *name, int luns))
-{
-  struct grub_ata_device *dev;
-
-  for (dev = grub_ata_devices; dev; dev = dev->next)
-    {
-      char devname[10];
-      grub_snprintf (devname, sizeof (devname),
-                    "ata%d", dev->port * 2 + dev->device);
-
-      if (! dev->atapi)
-       continue;
-
-      if (hook (devname, 1))
-       return 1;
-    }
-
-  return 0;
-
-}
-
-static grub_err_t
-grub_atapi_read (struct grub_scsi *scsi,
-                grub_size_t cmdsize __attribute__((unused)),
-                char *cmd, grub_size_t size, char *buf)
-{
-  struct grub_ata_device *dev = (struct grub_ata_device *) scsi->data;
-
-  grub_dprintf("ata", "grub_atapi_read (size=%llu)\n", (unsigned long long) size);
-
-  if (grub_atapi_packet (dev, cmd, size))
-    return grub_errno;
-
-  grub_size_t nread = 0;
-  while (nread < size)
-    {
-      /* Wait for !BSY, DRQ, I/O, !C/D.  */
-      if (grub_atapi_wait_drq (dev, GRUB_ATAPI_IREASON_DATA_IN, GRUB_ATA_TOUT_DATA))
-       return grub_errno;
-
-      /* Get byte count for this DRQ assertion.  */
-      unsigned cnt = grub_ata_regget (dev, GRUB_ATAPI_REG_CNTHIGH) << 8
-                  | grub_ata_regget (dev, GRUB_ATAPI_REG_CNTLOW);
-      grub_dprintf("ata", "DRQ count=%u\n", cnt);
-
-      /* Count of last transfer may be uneven.  */
-      if (! (0 < cnt && cnt <= size - nread && (! (cnt & 1) || cnt == size - nread)))
-       return grub_error (GRUB_ERR_READ_ERROR, "invalid ATAPI transfer count");
-
-      /* Read the data.  */
-      grub_ata_pio_read (dev, buf + nread, cnt);
-
-      if (cnt & 1)
-       buf[nread + cnt - 1] = (char) grub_le_to_cpu16 (grub_inw (dev->ioaddress + GRUB_ATA_REG_DATA));
-
-      nread += cnt;
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_atapi_write (struct grub_scsi *scsi __attribute__((unused)),
-                 grub_size_t cmdsize __attribute__((unused)),
-                 char *cmd __attribute__((unused)),
-                 grub_size_t size __attribute__((unused)),
-                 char *buf __attribute__((unused)))
-{
-  // XXX: scsi.mod does not use write yet.
-  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "ATAPI write not implemented");
-}
-
-static grub_err_t
-grub_atapi_open (const char *name, struct grub_scsi *scsi)
-{
-  struct grub_ata_device *dev;
-  struct grub_ata_device *devfnd = 0;
-
-  for (dev = grub_ata_devices; dev; dev = dev->next)
-    {
-      char devname[10];
-      grub_snprintf (devname, sizeof (devname),
-                    "ata%d", dev->port * 2 + dev->device);
-
-      if (!grub_strcmp (devname, name))
-       {
-         devfnd = dev;
-         break;
-       }
-    }
-
-  grub_dprintf ("ata", "opening ATAPI dev `%s'\n", name);
-
-  if (! devfnd)
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device");
-
-  scsi->data = devfnd;
-
-  return GRUB_ERR_NONE;
-}
-
-static void
-grub_atapi_close (struct grub_scsi *scsi)
-{
-  grub_free (scsi->name);
-}
-
-static struct grub_scsi_dev grub_atapi_dev =
-  {
-    .name = "ATAPI",
-    .iterate = grub_atapi_iterate,
-    .open = grub_atapi_open,
-    .close = grub_atapi_close,
-    .read = grub_atapi_read,
-    .write = grub_atapi_write
-  };
-
-\f
-
-GRUB_MOD_INIT(ata)
-{
-  /* To prevent two drivers operating on the same disks.  */
-  grub_disk_firmware_is_tainted = 1;
-  if (grub_disk_firmware_fini)
-    {
-      grub_disk_firmware_fini ();
-      grub_disk_firmware_fini = NULL;
-    }
-
-  /* ATA initialization.  */
-  grub_ata_initialize ();
-
-  grub_disk_dev_register (&grub_atadisk_dev);
-
-  /* ATAPI devices are handled by scsi.mod.  */
-  grub_scsi_dev_register (&grub_atapi_dev);
-}
-
-GRUB_MOD_FINI(ata)
-{
-  grub_scsi_dev_unregister (&grub_atapi_dev);
-  grub_disk_dev_unregister (&grub_atadisk_dev);
-}
diff --git a/disk/ata_pthru.c b/disk/ata_pthru.c
deleted file mode 100644 (file)
index f52725a..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/* ata_pthru.c - ATA pass through for ata.mod.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/ata.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/mm.h>
-
-
-/* ATA pass through support, used by hdparm.mod.  */
-static grub_err_t
-grub_ata_pass_through (grub_disk_t disk,
-                      struct grub_disk_ata_pass_through_parms *parms)
-{
-  if (disk->dev->id != GRUB_DISK_DEVICE_ATA_ID)
-    return grub_error (GRUB_ERR_BAD_DEVICE,
-                      "device not accessed via ata.mod");
-
-  struct grub_ata_device *dev = (struct grub_ata_device *) disk->data;
-
-  if (! (parms->size == 0 || parms->size == GRUB_DISK_SECTOR_SIZE))
-    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                      "ATA multi-sector read and DATA OUT not implemented");
-
-  grub_dprintf ("ata", "ata_pass_through: cmd=0x%x, features=0x%x, sectors=0x%x\n",
-               parms->taskfile[GRUB_ATA_REG_CMD],
-               parms->taskfile[GRUB_ATA_REG_FEATURES],
-               parms->taskfile[GRUB_ATA_REG_SECTORS]);
-  grub_dprintf ("ata", "lba_high=0x%x, lba_mid=0x%x, lba_low=0x%x, size=%d\n",
-               parms->taskfile[GRUB_ATA_REG_LBAHIGH],
-               parms->taskfile[GRUB_ATA_REG_LBAMID],
-               parms->taskfile[GRUB_ATA_REG_LBALOW], parms->size);
-
-  /* Set registers.  */
-  grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4
-                  | (parms->taskfile[GRUB_ATA_REG_DISK] & 0xf));
-  if (grub_ata_check_ready (dev))
-    return grub_errno;
-
-  int i;
-  for (i = GRUB_ATA_REG_FEATURES; i <= GRUB_ATA_REG_LBAHIGH; i++)
-    grub_ata_regset (dev, i, parms->taskfile[i]);
-
-  /* Start command. */
-  grub_ata_regset (dev, GRUB_ATA_REG_CMD, parms->taskfile[GRUB_ATA_REG_CMD]);
-
-  /* Wait for !BSY.  */
-  if (grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA))
-    return grub_errno;
-
-  /* Check status.  */
-  grub_int8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
-  grub_dprintf ("ata", "status=0x%x\n", sts);
-
-  /* Transfer data.  */
-  if ((sts & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_DRQ)
-    {
-      if (parms->size != GRUB_DISK_SECTOR_SIZE)
-        return grub_error (GRUB_ERR_READ_ERROR, "DRQ unexpected");
-      grub_ata_pio_read (dev, parms->buffer, GRUB_DISK_SECTOR_SIZE);
-    }
-
-  /* Return registers.  */
-  for (i = GRUB_ATA_REG_ERROR; i <= GRUB_ATA_REG_STATUS; i++)
-    parms->taskfile[i] = grub_ata_regget (dev, i);
-
-  grub_dprintf ("ata", "status=0x%x, error=0x%x, sectors=0x%x\n",
-               parms->taskfile[GRUB_ATA_REG_STATUS],
-               parms->taskfile[GRUB_ATA_REG_ERROR],
-               parms->taskfile[GRUB_ATA_REG_SECTORS]);
-
-  if (parms->taskfile[GRUB_ATA_REG_STATUS]
-      & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
-    return grub_error (GRUB_ERR_READ_ERROR, "ATA passthrough failed");
-
-  return GRUB_ERR_NONE;
-}
-
-\f
-
-GRUB_MOD_INIT(ata_pthru)
-{
-  /* Register ATA pass through function.  */
-  grub_disk_ata_pass_through = grub_ata_pass_through;
-}
-
-GRUB_MOD_FINI(ata_pthru)
-{
-  if (grub_disk_ata_pass_through == grub_ata_pass_through)
-    grub_disk_ata_pass_through = NULL;
-}
diff --git a/disk/dmraid_nvidia.c b/disk/dmraid_nvidia.c
deleted file mode 100644 (file)
index c4e3922..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/* dmraid_nvidia.c - module to handle Nvidia fakeraid.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/raid.h>
-
-#define NV_SIGNATURES          4
-
-#define NV_IDLE                        0
-#define NV_SCDB_INIT_RAID      2
-#define NV_SCDB_REBUILD_RAID   3
-#define NV_SCDB_UPGRADE_RAID   4
-#define NV_SCDB_SYNC_RAID      5
-
-#define NV_LEVEL_UNKNOWN       0x00
-#define NV_LEVEL_JBOD          0xFF
-#define NV_LEVEL_0             0x80
-#define NV_LEVEL_1             0x81
-#define NV_LEVEL_3             0x83
-#define NV_LEVEL_5             0x85
-#define NV_LEVEL_10            0x8a
-#define NV_LEVEL_1_0           0x8180
-
-#define NV_ARRAY_FLAG_BOOT             1 /* BIOS use only.  */
-#define NV_ARRAY_FLAG_ERROR            2 /* Degraded or offline.  */
-#define NV_ARRAY_FLAG_PARITY_VALID     4 /* RAID-3/5 parity valid.  */
-
-struct grub_nv_array
-{
-  grub_uint32_t version;
-  grub_uint32_t signature[NV_SIGNATURES];
-  grub_uint8_t raid_job_code;
-  grub_uint8_t stripe_width;
-  grub_uint8_t total_volumes;
-  grub_uint8_t original_width;
-  grub_uint32_t raid_level;
-  grub_uint32_t stripe_block_size;
-  grub_uint32_t stripe_block_size_bytes;
-  grub_uint32_t stripe_block_size_log2;
-  grub_uint32_t stripe_mask;
-  grub_uint32_t stripe_size;
-  grub_uint32_t stripe_size_bytes;
-  grub_uint32_t raid_job_mask;
-  grub_uint32_t original_capacity;
-  grub_uint32_t flags;
-};
-
-#define NV_ID_LEN              8
-#define NV_ID_STRING           "NVIDIA"
-#define NV_VERSION             100
-
-#define        NV_PRODID_LEN           16
-#define        NV_PRODREV_LEN          4
-
-struct grub_nv_super
-{
-  char vendor[NV_ID_LEN];      /* 0x00 - 0x07 ID string.  */
-  grub_uint32_t size;          /* 0x08 - 0x0B Size of metadata in dwords.  */
-  grub_uint32_t chksum;                /* 0x0C - 0x0F Checksum of this struct.  */
-  grub_uint16_t version;       /* 0x10 - 0x11 NV version.  */
-  grub_uint8_t unit_number;    /* 0x12 Disk index in array.  */
-  grub_uint8_t reserved;       /* 0x13.  */
-  grub_uint32_t capacity;      /* 0x14 - 0x17 Array capacity in sectors.  */
-  grub_uint32_t sector_size;   /* 0x18 - 0x1B Sector size.  */
-  char prodid[NV_PRODID_LEN];  /* 0x1C - 0x2B Array product ID.  */
-  char prodrev[NV_PRODREV_LEN];        /* 0x2C - 0x2F Array product revision */
-  grub_uint32_t unit_flags;    /* 0x30 - 0x33 Flags for this disk */
-  struct grub_nv_array array;  /* Array information */
-} __attribute__ ((packed));
-
-static grub_err_t
-grub_dmraid_nv_detect (grub_disk_t disk, struct grub_raid_array *array)
-{
-  grub_disk_addr_t sector;
-  struct grub_nv_super sb;
-
-  if (disk->partition)
-    return grub_error (GRUB_ERR_OUT_OF_RANGE, "skip partition");
-
-  sector = grub_disk_get_size (disk) - 2;
-
-  if (grub_disk_read (disk, sector, 0, sizeof (sb), &sb))
-    return grub_errno;
-
-  if (grub_memcmp (sb.vendor, NV_ID_STRING, 6))
-    return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid");
-
-  if (sb.version != NV_VERSION)
-    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                       "unknown version: %d.%d", sb.version);
-
-  switch (sb.array.raid_level)
-    {
-    case NV_LEVEL_0:
-      array->level = 0;
-      array->disk_size = sb.capacity / sb.array.total_volumes;
-      break;
-
-    case NV_LEVEL_1:
-      array->level = 1;
-      array->disk_size = sb.capacity;
-      break;
-
-    case NV_LEVEL_5:
-      array->level = 5;
-      array->layout = GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC;
-      array->disk_size = sb.capacity / (sb.array.total_volumes - 1);
-      break;
-
-    default:
-      return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                         "unsupported RAID level: %d", sb.array.raid_level);
-    }
-
-  array->number = 0;
-  array->total_devs = sb.array.total_volumes;
-  array->chunk_size = sb.array.stripe_block_size;
-  array->index = sb.unit_number;
-  array->uuid_len = sizeof (sb.array.signature);
-  array->uuid = grub_malloc (sizeof (sb.array.signature));
-  if (! array->uuid)
-    return grub_errno;
-
-  grub_memcpy (array->uuid, (char *) &sb.array.signature,
-               sizeof (sb.array.signature));
-
-  return 0;
-}
-
-static struct grub_raid grub_dmraid_nv_dev =
-{
-  .name = "dmraid_nv",
-  .detect = grub_dmraid_nv_detect,
-  .next = 0
-};
-
-GRUB_MOD_INIT(dm_nv)
-{
-  grub_raid_register (&grub_dmraid_nv_dev);
-}
-
-GRUB_MOD_FINI(dm_nv)
-{
-  grub_raid_unregister (&grub_dmraid_nv_dev);
-}
diff --git a/disk/efi/efidisk.c b/disk/efi/efidisk.c
deleted file mode 100644 (file)
index f9c6f31..0000000
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/disk.h>
-#include <grub/partition.h>
-#include <grub/mm.h>
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/err.h>
-#include <grub/term.h>
-#include <grub/efi/api.h>
-#include <grub/efi/efi.h>
-#include <grub/efi/disk.h>
-
-struct grub_efidisk_data
-{
-  grub_efi_handle_t handle;
-  grub_efi_device_path_t *device_path;
-  grub_efi_device_path_t *last_device_path;
-  grub_efi_block_io_t *block_io;
-  grub_efi_disk_io_t *disk_io;
-  struct grub_efidisk_data *next;
-};
-
-/* GUIDs.  */
-static grub_efi_guid_t disk_io_guid = GRUB_EFI_DISK_IO_GUID;
-static grub_efi_guid_t block_io_guid = GRUB_EFI_BLOCK_IO_GUID;
-
-static struct grub_efidisk_data *fd_devices;
-static struct grub_efidisk_data *hd_devices;
-static struct grub_efidisk_data *cd_devices;
-
-/* Duplicate a device path.  */
-static grub_efi_device_path_t *
-duplicate_device_path (const grub_efi_device_path_t *dp)
-{
-  grub_efi_device_path_t *p;
-  grub_size_t total_size = 0;
-
-  for (p = (grub_efi_device_path_t *) dp;
-       ;
-       p = GRUB_EFI_NEXT_DEVICE_PATH (p))
-    {
-      total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
-      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
-       break;
-    }
-
-  p = grub_malloc (total_size);
-  if (! p)
-    return 0;
-
-  grub_memcpy (p, dp, total_size);
-  return p;
-}
-
-/* Return the device path node right before the end node.  */
-static grub_efi_device_path_t *
-find_last_device_path (const grub_efi_device_path_t *dp)
-{
-  grub_efi_device_path_t *next, *p;
-
-  if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
-    return 0;
-
-  for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p);
-       ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next);
-       p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next))
-    ;
-
-  return p;
-}
-
-/* Compare device paths.  */
-static int
-compare_device_paths (const grub_efi_device_path_t *dp1,
-                     const grub_efi_device_path_t *dp2)
-{
-  if (! dp1 || ! dp2)
-    /* Return non-zero.  */
-    return 1;
-
-  while (1)
-    {
-      grub_efi_uint8_t type1, type2;
-      grub_efi_uint8_t subtype1, subtype2;
-      grub_efi_uint16_t len1, len2;
-      int ret;
-
-      type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1);
-      type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2);
-
-      if (type1 != type2)
-       return (int) type2 - (int) type1;
-
-      subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1);
-      subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2);
-
-      if (subtype1 != subtype2)
-       return (int) subtype1 - (int) subtype2;
-
-      len1 = GRUB_EFI_DEVICE_PATH_LENGTH (dp1);
-      len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2);
-
-      if (len1 != len2)
-       return (int) len1 - (int) len2;
-
-      ret = grub_memcmp (dp1, dp2, len1);
-      if (ret != 0)
-       return ret;
-
-      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1))
-       break;
-
-      dp1 = (grub_efi_device_path_t *) ((char *) dp1 + len1);
-      dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
-    }
-
-  return 0;
-}
-
-static struct grub_efidisk_data *
-make_devices (void)
-{
-  grub_efi_uintn_t num_handles;
-  grub_efi_handle_t *handles;
-  grub_efi_handle_t *handle;
-  struct grub_efidisk_data *devices = 0;
-
-  /* Find handles which support the disk io interface.  */
-  handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &disk_io_guid,
-                                   0, &num_handles);
-  if (! handles)
-    return 0;
-
-  /* Make a linked list of devices.  */
-  for (handle = handles; num_handles--; handle++)
-    {
-      grub_efi_device_path_t *dp;
-      grub_efi_device_path_t *ldp;
-      struct grub_efidisk_data *d;
-      grub_efi_block_io_t *bio;
-      grub_efi_disk_io_t *dio;
-
-      dp = grub_efi_get_device_path (*handle);
-      if (! dp)
-       continue;
-
-      ldp = find_last_device_path (dp);
-      if (! ldp)
-       /* This is empty. Why?  */
-       continue;
-
-      bio = grub_efi_open_protocol (*handle, &block_io_guid,
-                                   GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
-      dio = grub_efi_open_protocol (*handle, &disk_io_guid,
-                                   GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
-      if (! bio || ! dio)
-       /* This should not happen... Why?  */
-       continue;
-
-      d = grub_malloc (sizeof (*d));
-      if (! d)
-       {
-         /* Uggh.  */
-         grub_free (handles);
-         return 0;
-       }
-
-      d->handle = *handle;
-      d->device_path = dp;
-      d->last_device_path = ldp;
-      d->block_io = bio;
-      d->disk_io = dio;
-      d->next = devices;
-      devices = d;
-    }
-
-  grub_free (handles);
-
-  return devices;
-}
-
-/* Find the parent device.  */
-static struct grub_efidisk_data *
-find_parent_device (struct grub_efidisk_data *devices,
-                   struct grub_efidisk_data *d)
-{
-  grub_efi_device_path_t *dp, *ldp;
-  struct grub_efidisk_data *parent;
-
-  dp = duplicate_device_path (d->device_path);
-  if (! dp)
-    return 0;
-
-  ldp = find_last_device_path (dp);
-  ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
-  ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
-  ldp->length[0] = sizeof (*ldp);
-  ldp->length[1] = 0;
-
-  for (parent = devices; parent; parent = parent->next)
-    {
-      /* Ignore itself.  */
-      if (parent == d)
-       continue;
-
-      if (compare_device_paths (parent->device_path, dp) == 0)
-       {
-         /* Found.  */
-         if (! parent->last_device_path)
-           parent = 0;
-
-         break;
-       }
-    }
-
-  grub_free (dp);
-  return parent;
-}
-
-static int
-iterate_child_devices (struct grub_efidisk_data *devices,
-                      struct grub_efidisk_data *d,
-                      int (*hook) (struct grub_efidisk_data *child))
-{
-  struct grub_efidisk_data *p;
-
-  for (p = devices; p; p = p->next)
-    {
-      grub_efi_device_path_t *dp, *ldp;
-
-      dp = duplicate_device_path (p->device_path);
-      if (! dp)
-       return 0;
-
-      ldp = find_last_device_path (dp);
-      ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
-      ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
-      ldp->length[0] = sizeof (*ldp);
-      ldp->length[1] = 0;
-
-      if (compare_device_paths (dp, d->device_path) == 0)
-       if (hook (p))
-         {
-           grub_free (dp);
-           return 1;
-         }
-
-      grub_free (dp);
-    }
-
-  return 0;
-}
-
-/* Add a device into a list of devices in an ascending order.  */
-static void
-add_device (struct grub_efidisk_data **devices, struct grub_efidisk_data *d)
-{
-  struct grub_efidisk_data **p;
-  struct grub_efidisk_data *n;
-
-  for (p = devices; *p; p = &((*p)->next))
-    {
-      int ret;
-
-      ret = compare_device_paths (find_last_device_path ((*p)->device_path),
-                                 find_last_device_path (d->device_path));
-      if (ret == 0)
-       ret = compare_device_paths ((*p)->device_path,
-                                   d->device_path);
-      if (ret == 0)
-       return;
-      else if (ret > 0)
-       break;
-    }
-
-  n = grub_malloc (sizeof (*n));
-  if (! n)
-    return;
-
-  grub_memcpy (n, d, sizeof (*n));
-  n->next = (*p);
-  (*p) = n;
-}
-
-/* Name the devices.  */
-static void
-name_devices (struct grub_efidisk_data *devices)
-{
-  struct grub_efidisk_data *d;
-
-  /* First, identify devices by media device paths.  */
-  for (d = devices; d; d = d->next)
-    {
-      grub_efi_device_path_t *dp;
-
-      dp = d->last_device_path;
-      if (! dp)
-       continue;
-
-      if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE)
-       {
-         int is_hard_drive = 0;
-
-         switch (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp))
-           {
-           case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
-             is_hard_drive = 1;
-             /* Fall through by intention.  */
-           case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE:
-             {
-               struct grub_efidisk_data *parent;
-
-               parent = find_parent_device (devices, d);
-               if (parent)
-                 {
-                   if (is_hard_drive)
-                     {
-#if 0
-                       grub_printf ("adding a hard drive by a partition: ");
-                       grub_print_device_path (parent->device_path);
-#endif
-                       add_device (&hd_devices, parent);
-                     }
-                   else
-                     {
-#if 0
-                       grub_printf ("adding a cdrom by a partition: ");
-                       grub_print_device_path (parent->device_path);
-#endif
-                       add_device (&cd_devices, parent);
-                     }
-
-                   /* Mark the parent as used.  */
-                   parent->last_device_path = 0;
-                 }
-             }
-             /* Mark itself as used.  */
-             d->last_device_path = 0;
-             break;
-
-           default:
-             /* For now, ignore the others.  */
-             break;
-           }
-       }
-    }
-
-  /* Let's see what can be added more.  */
-  for (d = devices; d; d = d->next)
-    {
-      grub_efi_device_path_t *dp;
-      grub_efi_block_io_media_t *m;
-
-      dp = d->last_device_path;
-      if (! dp)
-       continue;
-
-      m = d->block_io->media;
-      if (m->logical_partition)
-       {
-         /* Only one partition in a non-media device. Assume that this
-            is a floppy drive.  */
-#if 0
-         grub_printf ("adding a floppy by guessing: ");
-         grub_print_device_path (d->device_path);
-#endif
-         add_device (&fd_devices, d);
-       }
-      else if (m->read_only && m->block_size > GRUB_DISK_SECTOR_SIZE)
-       {
-         /* This check is too heuristic, but assume that this is a
-            CDROM drive.  */
-#if 0
-         grub_printf ("adding a cdrom by guessing: ");
-         grub_print_device_path (d->device_path);
-#endif
-         add_device (&cd_devices, d);
-       }
-      else
-       {
-         /* The default is a hard drive.  */
-#if 0
-         grub_printf ("adding a hard drive by guessing: ");
-         grub_print_device_path (d->device_path);
-#endif
-         add_device (&hd_devices, d);
-       }
-    }
-}
-
-static void
-free_devices (struct grub_efidisk_data *devices)
-{
-  struct grub_efidisk_data *p, *q;
-
-  for (p = devices; p; p = q)
-    {
-      q = p->next;
-      grub_free (p);
-    }
-}
-
-/* Enumerate all disks to name devices.  */
-static void
-enumerate_disks (void)
-{
-  struct grub_efidisk_data *devices;
-
-  devices = make_devices ();
-  if (! devices)
-    return;
-
-  name_devices (devices);
-  free_devices (devices);
-}
-
-static int
-grub_efidisk_iterate (int (*hook) (const char *name))
-{
-  struct grub_efidisk_data *d;
-  char buf[16];
-  int count;
-
-  for (d = fd_devices, count = 0; d; d = d->next, count++)
-    {
-      grub_snprintf (buf, sizeof (buf), "fd%d", count);
-      grub_dprintf ("efidisk", "iterating %s\n", buf);
-      if (hook (buf))
-       return 1;
-    }
-
-  for (d = hd_devices, count = 0; d; d = d->next, count++)
-    {
-      grub_snprintf (buf, sizeof (buf), "hd%d", count);
-      grub_dprintf ("efidisk", "iterating %s\n", buf);
-      if (hook (buf))
-       return 1;
-    }
-
-  for (d = cd_devices, count = 0; d; d = d->next, count++)
-    {
-      grub_snprintf (buf, sizeof (buf), "cd%d", count);
-      grub_dprintf ("efidisk", "iterating %s\n", buf);
-      if (hook (buf))
-       return 1;
-    }
-
-  return 0;
-}
-
-static int
-get_drive_number (const char *name)
-{
-  unsigned long drive;
-
-  if ((name[0] != 'f' && name[0] != 'h' && name[0] != 'c') || name[1] != 'd')
-    goto fail;
-
-  drive = grub_strtoul (name + 2, 0, 10);
-  if (grub_errno != GRUB_ERR_NONE)
-    goto fail;
-
-  return (int) drive ;
-
- fail:
-  grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a efidisk");
-  return -1;
-}
-
-static struct grub_efidisk_data *
-get_device (struct grub_efidisk_data *devices, int num)
-{
-  struct grub_efidisk_data *d;
-
-  for (d = devices; d && num; d = d->next, num--)
-    ;
-
-  if (num == 0)
-    return d;
-
-  return 0;
-}
-
-static grub_err_t
-grub_efidisk_open (const char *name, struct grub_disk *disk)
-{
-  int num;
-  struct grub_efidisk_data *d = 0;
-  grub_efi_block_io_media_t *m;
-
-  grub_dprintf ("efidisk", "opening %s\n", name);
-
-  num = get_drive_number (name);
-  if (num < 0)
-    return grub_errno;
-
-  switch (name[0])
-    {
-    case 'f':
-      disk->has_partitions = 0;
-      d = get_device (fd_devices, num);
-      break;
-    case 'c':
-      /* FIXME: a CDROM should have partitions, but not implemented yet.  */
-      disk->has_partitions = 0;
-      d = get_device (cd_devices, num);
-      break;
-    case 'h':
-      disk->has_partitions = 1;
-      d = get_device (hd_devices, num);
-      break;
-    default:
-      /* Never reach here.  */
-      break;
-    }
-
-  if (! d)
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such device");
-
-  disk->id = ((num << 8) | name[0]);
-  m = d->block_io->media;
-  /* FIXME: Probably it is better to store the block size in the disk,
-     and total sectors should be replaced with total blocks.  */
-  grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n",
-               m, (unsigned long long) m->last_block, m->block_size);
-  disk->total_sectors = (m->last_block
-                        * (m->block_size >> GRUB_DISK_SECTOR_BITS));
-  disk->data = d;
-
-  grub_dprintf ("efidisk", "opening %s succeeded\n", name);
-
-  return GRUB_ERR_NONE;
-}
-
-static void
-grub_efidisk_close (struct grub_disk *disk __attribute__ ((unused)))
-{
-  /* EFI disks do not allocate extra memory, so nothing to do here.  */
-  grub_dprintf ("efidisk", "closing %s\n", disk->name);
-}
-
-static grub_err_t
-grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector,
-                  grub_size_t size, char *buf)
-{
-  /* For now, use the disk io interface rather than the block io's.  */
-  struct grub_efidisk_data *d;
-  grub_efi_disk_io_t *dio;
-  grub_efi_block_io_t *bio;
-  grub_efi_status_t status;
-
-  d = disk->data;
-  dio = d->disk_io;
-  bio = d->block_io;
-
-  grub_dprintf ("efidisk",
-               "reading 0x%lx sectors at the sector 0x%llx from %s\n",
-               (unsigned long) size, (unsigned long long) sector, disk->name);
-
-  status = efi_call_5 (dio->read, dio, bio->media->media_id,
-                     (grub_efi_uint64_t) sector << GRUB_DISK_SECTOR_BITS,
-                     (grub_efi_uintn_t) size << GRUB_DISK_SECTOR_BITS,
-                     buf);
-  if (status != GRUB_EFI_SUCCESS)
-    return grub_error (GRUB_ERR_READ_ERROR, "efidisk read error");
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_efidisk_write (struct grub_disk *disk, grub_disk_addr_t sector,
-                   grub_size_t size, const char *buf)
-{
-  /* For now, use the disk io interface rather than the block io's.  */
-  struct grub_efidisk_data *d;
-  grub_efi_disk_io_t *dio;
-  grub_efi_block_io_t *bio;
-  grub_efi_status_t status;
-
-  d = disk->data;
-  dio = d->disk_io;
-  bio = d->block_io;
-
-  grub_dprintf ("efidisk",
-               "writing 0x%lx sectors at the sector 0x%llx to %s\n",
-               (unsigned long) size, (unsigned long long) sector, disk->name);
-
-  status = efi_call_5 (dio->write, dio, bio->media->media_id,
-                      (grub_efi_uint64_t) sector << GRUB_DISK_SECTOR_BITS,
-                      (grub_efi_uintn_t) size << GRUB_DISK_SECTOR_BITS,
-                      (void *) buf);
-  if (status != GRUB_EFI_SUCCESS)
-    return grub_error (GRUB_ERR_WRITE_ERROR, "efidisk write error");
-
-  return GRUB_ERR_NONE;
-}
-
-static struct grub_disk_dev grub_efidisk_dev =
-  {
-    .name = "efidisk",
-    .id = GRUB_DISK_DEVICE_EFIDISK_ID,
-    .iterate = grub_efidisk_iterate,
-    .open = grub_efidisk_open,
-    .close = grub_efidisk_close,
-    .read = grub_efidisk_read,
-    .write = grub_efidisk_write,
-    .next = 0
-  };
-
-void
-grub_efidisk_init (void)
-{
-  enumerate_disks ();
-  grub_disk_dev_register (&grub_efidisk_dev);
-}
-
-void
-grub_efidisk_fini (void)
-{
-  free_devices (fd_devices);
-  free_devices (hd_devices);
-  free_devices (cd_devices);
-  grub_disk_dev_unregister (&grub_efidisk_dev);
-}
-
-/* Some utility functions to map GRUB devices with EFI devices.  */
-grub_efi_handle_t
-grub_efidisk_get_device_handle (grub_disk_t disk)
-{
-  struct grub_efidisk_data *d;
-  char type;
-
-  if (disk->dev->id != GRUB_DISK_DEVICE_EFIDISK_ID)
-    return 0;
-
-  d = disk->data;
-  type = disk->name[0];
-
-  switch (type)
-    {
-    case 'f':
-      /* This is the simplest case.  */
-      return d->handle;
-
-    case 'c':
-      /* FIXME: probably this is not correct.  */
-      return d->handle;
-
-    case 'h':
-      /* If this is the whole disk, just return its own data.  */
-      if (! disk->partition)
-       return d->handle;
-
-      /* Otherwise, we must query the corresponding device to the firmware.  */
-      {
-       struct grub_efidisk_data *devices;
-       grub_efi_handle_t handle = 0;
-       auto int find_partition (struct grub_efidisk_data *c);
-
-       int find_partition (struct grub_efidisk_data *c)
-         {
-           grub_efi_hard_drive_device_path_t hd;
-
-           grub_memcpy (&hd, c->last_device_path, sizeof (hd));
-
-           if ((GRUB_EFI_DEVICE_PATH_TYPE (c->last_device_path)
-                == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE)
-               && (GRUB_EFI_DEVICE_PATH_SUBTYPE (c->last_device_path)
-                   == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)
-               && (grub_partition_get_start (disk->partition)
-                   == hd.partition_start)
-               && (grub_partition_get_len (disk->partition)
-                   == hd.partition_size))
-             {
-               handle = c->handle;
-               return 1;
-             }
-
-           return 0;
-         }
-
-       devices = make_devices ();
-       iterate_child_devices (devices, d, find_partition);
-       free_devices (devices);
-
-       if (handle != 0)
-         return handle;
-      }
-      break;
-
-    default:
-      break;
-    }
-
-  return 0;
-}
-
-char *
-grub_efidisk_get_device_name (grub_efi_handle_t *handle)
-{
-  grub_efi_device_path_t *dp, *ldp;
-
-  dp = grub_efi_get_device_path (handle);
-  if (! dp)
-    return 0;
-
-  ldp = find_last_device_path (dp);
-  if (! ldp)
-    return 0;
-
-  if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
-      && (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp)
-         == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))
-    {
-      /* This is a hard disk partition.  */
-      grub_disk_t parent = 0;
-      char *partition_name = 0;
-      char *device_name;
-      grub_efi_device_path_t *dup_dp, *dup_ldp;
-      grub_efi_hard_drive_device_path_t hd;
-      auto int find_parent_disk (const char *name);
-      auto int find_partition (grub_disk_t disk, const grub_partition_t part);
-
-      /* Find the disk which is the parent of a given hard disk partition.  */
-      int find_parent_disk (const char *name)
-       {
-         grub_disk_t disk;
-
-         disk = grub_disk_open (name);
-         if (! disk)
-           return 1;
-
-         if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID)
-           {
-             struct grub_efidisk_data *d;
-
-             d = disk->data;
-             if (compare_device_paths (d->device_path, dup_dp) == 0)
-               {
-                 parent = disk;
-                 return 1;
-               }
-           }
-
-         grub_disk_close (disk);
-         return 0;
-       }
-
-      /* Find the identical partition.  */
-      int find_partition (grub_disk_t disk __attribute__ ((unused)),
-                         const grub_partition_t part)
-       {
-         if (grub_partition_get_start (part) == hd.partition_start
-             && grub_partition_get_len (part) == hd.partition_size)
-           {
-             partition_name = grub_partition_get_name (part);
-             return 1;
-           }
-
-         return 0;
-       }
-
-      /* It is necessary to duplicate the device path so that GRUB
-        can overwrite it.  */
-      dup_dp = duplicate_device_path (dp);
-      if (! dup_dp)
-       return 0;
-
-      dup_ldp = find_last_device_path (dup_dp);
-      dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
-      dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
-      dup_ldp->length[0] = sizeof (*dup_ldp);
-      dup_ldp->length[1] = 0;
-
-      grub_efidisk_iterate (find_parent_disk);
-      grub_free (dup_dp);
-
-      if (! parent)
-       return 0;
-
-      /* Find a partition which matches the hard drive device path.  */
-      grub_memcpy (&hd, ldp, sizeof (hd));
-      grub_partition_iterate (parent, find_partition);
-
-      if (! partition_name)
-       {
-         grub_disk_close (parent);
-         return 0;
-       }
-
-      device_name = grub_xasprintf ("%s,%s", parent->name, partition_name);
-      grub_free (partition_name);
-      grub_disk_close (parent);
-
-      return device_name;
-    }
-  else
-    {
-      /* This should be an entire disk.  */
-      auto int find_disk (const char *name);
-      char *device_name = 0;
-
-      int find_disk (const char *name)
-       {
-         grub_disk_t disk;
-
-         disk = grub_disk_open (name);
-         if (! disk)
-           return 1;
-
-         if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID)
-           {
-             struct grub_efidisk_data *d;
-
-             d = disk->data;
-             if (compare_device_paths (d->device_path, dp) == 0)
-               {
-                 device_name = grub_strdup (disk->name);
-                 grub_disk_close (disk);
-                 return 1;
-               }
-           }
-
-         grub_disk_close (disk);
-         return 0;
-
-       }
-
-      grub_efidisk_iterate (find_disk);
-      return device_name;
-    }
-
-  return 0;
-}
diff --git a/disk/host.c b/disk/host.c
deleted file mode 100644 (file)
index c4f3e71..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* host.c - Dummy disk driver to provide access to the hosts filesystem  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* When using the disk, make a reference to this module.  Otherwise
-   the user will end up with a useless module :-).  */
-
-#include <grub/dl.h>
-#include <grub/disk.h>
-#include <grub/misc.h>
-
-int grub_disk_host_i_want_a_reference;
-
-static int
-grub_host_iterate (int (*hook) (const char *name))
-{
-  if (hook ("host"))
-    return 1;
-  return 0;
-}
-
-static grub_err_t
-grub_host_open (const char *name, grub_disk_t disk)
-{
-  if (grub_strcmp (name, "host"))
-      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a host disk");
-
-  disk->total_sectors = 0;
-  disk->id = (unsigned long) "host";
-
-  disk->has_partitions = 0;
-  disk->data = 0;
-
-  return GRUB_ERR_NONE;
-}
-
-static void
-grub_host_close (grub_disk_t disk __attribute((unused)))
-{
-}
-
-static grub_err_t
-grub_host_read (grub_disk_t disk __attribute((unused)),
-               grub_disk_addr_t sector __attribute((unused)),
-               grub_size_t size __attribute((unused)),
-               char *buf __attribute((unused)))
-{
-  return GRUB_ERR_OUT_OF_RANGE;
-}
-
-static grub_err_t
-grub_host_write (grub_disk_t disk __attribute ((unused)),
-                    grub_disk_addr_t sector __attribute ((unused)),
-                    grub_size_t size __attribute ((unused)),
-                    const char *buf __attribute ((unused)))
-{
-  return GRUB_ERR_OUT_OF_RANGE;
-}
-
-static struct grub_disk_dev grub_host_dev =
-  {
-    /* The only important line in this file :-) */
-    .name = "host",
-    .id = GRUB_DISK_DEVICE_HOST_ID,
-    .iterate = grub_host_iterate,
-    .open = grub_host_open,
-    .close = grub_host_close,
-    .read = grub_host_read,
-    .write = grub_host_write,
-    .next = 0
-  };
-
-GRUB_MOD_INIT(host)
-{
-  grub_disk_dev_register (&grub_host_dev);
-}
-
-GRUB_MOD_FINI(host)
-{
-  grub_disk_dev_unregister (&grub_host_dev);
-}
diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c
deleted file mode 100644 (file)
index 94d0e37..0000000
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/machine/biosdisk.h>
-#include <grub/machine/memory.h>
-#include <grub/machine/kernel.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/err.h>
-#include <grub/term.h>
-
-static int cd_drive = 0;
-
-static int
-grub_biosdisk_get_drive (const char *name)
-{
-  unsigned long drive;
-
-  if ((name[0] != 'f' && name[0] != 'h') || name[1] != 'd')
-    goto fail;
-
-  drive = grub_strtoul (name + 2, 0, 10);
-  if (grub_errno != GRUB_ERR_NONE)
-    goto fail;
-
-  if (name[0] == 'h')
-    drive += 0x80;
-
-  return (int) drive ;
-
- fail:
-  grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a biosdisk");
-  return -1;
-}
-
-static int
-grub_biosdisk_call_hook (int (*hook) (const char *name), int drive)
-{
-  char name[10];
-
-  grub_snprintf (name, sizeof (name),
-                (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80));
-  return hook (name);
-}
-
-static int
-grub_biosdisk_iterate (int (*hook) (const char *name))
-{
-  int drive;
-  int num_floppies;
-
-  /* For hard disks, attempt to read the MBR.  */
-  for (drive = 0x80; drive < 0x90; drive++)
-    {
-      if (grub_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1,
-                                    GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0)
-       {
-         grub_dprintf ("disk", "Read error when probing drive 0x%2x\n", drive);
-         break;
-       }
-
-      if (grub_biosdisk_call_hook (hook, drive))
-       return 1;
-    }
-
-  if (cd_drive)
-    {
-      if (grub_biosdisk_call_hook (hook, cd_drive))
-      return 1;
-    }
-
-  /* For floppy disks, we can get the number safely.  */
-  num_floppies = grub_biosdisk_get_num_floppies ();
-  for (drive = 0; drive < num_floppies; drive++)
-    if (grub_biosdisk_call_hook (hook, drive))
-      return 1;
-
-  return 0;
-}
-
-static grub_err_t
-grub_biosdisk_open (const char *name, grub_disk_t disk)
-{
-  grub_uint64_t total_sectors = 0;
-  int drive;
-  struct grub_biosdisk_data *data;
-
-  drive = grub_biosdisk_get_drive (name);
-  if (drive < 0)
-    return grub_errno;
-
-  disk->has_partitions = ((drive & 0x80) && (drive != cd_drive));
-  disk->id = drive;
-
-  data = (struct grub_biosdisk_data *) grub_zalloc (sizeof (*data));
-  if (! data)
-    return grub_errno;
-
-  data->drive = drive;
-
-  if ((cd_drive) && (drive == cd_drive))
-    {
-      data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM;
-      data->sectors = 32;
-      total_sectors = GRUB_ULONG_MAX;  /* TODO: get the correct size.  */
-    }
-  else if (drive & 0x80)
-    {
-      /* HDD */
-      int version;
-
-      version = grub_biosdisk_check_int13_extensions (drive);
-      if (version)
-       {
-         struct grub_biosdisk_drp *drp
-           = (struct grub_biosdisk_drp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
-
-         /* Clear out the DRP.  */
-         grub_memset (drp, 0, sizeof (*drp));
-         drp->size = sizeof (*drp);
-         if (! grub_biosdisk_get_diskinfo_int13_extensions (drive, drp))
-           {
-             data->flags = GRUB_BIOSDISK_FLAG_LBA;
-
-             if (drp->total_sectors)
-               total_sectors = drp->total_sectors;
-             else
-                /* Some buggy BIOSes doesn't return the total sectors
-                   correctly but returns zero. So if it is zero, compute
-                   it by C/H/S returned by the LBA BIOS call.  */
-                total_sectors = drp->cylinders * drp->heads * drp->sectors;
-           }
-       }
-    }
-
-  if (! (data->flags & GRUB_BIOSDISK_FLAG_CDROM))
-    {
-      if (grub_biosdisk_get_diskinfo_standard (drive,
-                                              &data->cylinders,
-                                              &data->heads,
-                                              &data->sectors) != 0)
-        {
-         if (total_sectors && (data->flags & GRUB_BIOSDISK_FLAG_LBA))
-           {
-             data->sectors = 63;
-             data->heads = 255;
-             data->cylinders
-               = grub_divmod64 (total_sectors
-                                + data->heads * data->sectors - 1,
-                                data->heads * data->sectors, 0);
-           }
-         else
-           {
-             grub_free (data);
-             return grub_error (GRUB_ERR_BAD_DEVICE, "%s cannot get C/H/S values", disk->name);
-           }
-        }
-
-      if (! total_sectors)
-        total_sectors = data->cylinders * data->heads * data->sectors;
-    }
-
-  disk->total_sectors = total_sectors;
-  disk->data = data;
-
-  return GRUB_ERR_NONE;
-}
-
-static void
-grub_biosdisk_close (grub_disk_t disk)
-{
-  grub_free (disk->data);
-}
-
-/* For readability.  */
-#define GRUB_BIOSDISK_READ     0
-#define GRUB_BIOSDISK_WRITE    1
-
-#define GRUB_BIOSDISK_CDROM_RETRY_COUNT 3
-
-static grub_err_t
-grub_biosdisk_rw (int cmd, grub_disk_t disk,
-                 grub_disk_addr_t sector, grub_size_t size,
-                 unsigned segment)
-{
-  struct grub_biosdisk_data *data = disk->data;
-
-  if (data->flags & GRUB_BIOSDISK_FLAG_LBA)
-    {
-      struct grub_biosdisk_dap *dap;
-
-      dap = (struct grub_biosdisk_dap *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR
-                                         + (data->sectors
-                                            << GRUB_DISK_SECTOR_BITS));
-      dap->length = sizeof (*dap);
-      dap->reserved = 0;
-      dap->blocks = size;
-      dap->buffer = segment << 16;     /* The format SEGMENT:ADDRESS.  */
-      dap->block = sector;
-
-      if (data->flags & GRUB_BIOSDISK_FLAG_CDROM)
-        {
-         int i;
-
-         if (cmd)
-           return grub_error (GRUB_ERR_WRITE_ERROR, "can\'t write to cdrom");
-
-         dap->blocks = ALIGN_UP (dap->blocks, 4) >> 2;
-         dap->block >>= 2;
-
-         for (i = 0; i < GRUB_BIOSDISK_CDROM_RETRY_COUNT; i++)
-            if (! grub_biosdisk_rw_int13_extensions (0x42, data->drive, dap))
-             break;
-
-         if (i == GRUB_BIOSDISK_CDROM_RETRY_COUNT)
-           return grub_error (GRUB_ERR_READ_ERROR, "cdrom read error");
-       }
-      else
-        if (grub_biosdisk_rw_int13_extensions (cmd + 0x42, data->drive, dap))
-         {
-           /* Fall back to the CHS mode.  */
-           data->flags &= ~GRUB_BIOSDISK_FLAG_LBA;
-           disk->total_sectors = data->cylinders * data->heads * data->sectors;
-           return grub_biosdisk_rw (cmd, disk, sector, size, segment);
-         }
-    }
-  else
-    {
-      unsigned coff, hoff, soff;
-      unsigned head;
-
-      /* It is impossible to reach over 8064 MiB (a bit less than LBA24) with
-        the traditional CHS access.  */
-      if (sector >
-         1024 /* cylinders */ *
-         256 /* heads */ *
-         63 /* spt */)
-       return grub_error (GRUB_ERR_OUT_OF_RANGE, "%s out of disk", disk->name);
-
-      soff = ((grub_uint32_t) sector) % data->sectors + 1;
-      head = ((grub_uint32_t) sector) / data->sectors;
-      hoff = head % data->heads;
-      coff = head / data->heads;
-
-      if (coff >= data->cylinders)
-       return grub_error (GRUB_ERR_OUT_OF_RANGE, "%s out of disk", disk->name);
-
-      if (grub_biosdisk_rw_standard (cmd + 0x02, data->drive,
-                                    coff, hoff, soff, size, segment))
-       {
-         switch (cmd)
-           {
-           case GRUB_BIOSDISK_READ:
-             return grub_error (GRUB_ERR_READ_ERROR, "%s read error", disk->name);
-           case GRUB_BIOSDISK_WRITE:
-             return grub_error (GRUB_ERR_WRITE_ERROR, "%s write error", disk->name);
-           }
-       }
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-/* Return the number of sectors which can be read safely at a time.  */
-static grub_size_t
-get_safe_sectors (grub_disk_addr_t sector, grub_uint32_t sectors)
-{
-  grub_size_t size;
-  grub_uint32_t offset;
-
-  /* OFFSET = SECTOR % SECTORS */
-  grub_divmod64 (sector, sectors, &offset);
-
-  size = sectors - offset;
-
-  /* Limit the max to 0x7f because of Phoenix EDD.  */
-  if (size > 0x7f)
-    size = 0x7f;
-
-  return size;
-}
-
-static grub_err_t
-grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
-                   grub_size_t size, char *buf)
-{
-  struct grub_biosdisk_data *data = disk->data;
-
-  while (size)
-    {
-      grub_size_t len;
-      grub_size_t cdoff = 0;
-
-      len = get_safe_sectors (sector, data->sectors);
-
-      if (data->flags & GRUB_BIOSDISK_FLAG_CDROM)
-       {
-         cdoff = (sector & 3) << GRUB_DISK_SECTOR_BITS;
-         len = ALIGN_UP (sector + len, 4) - (sector & ~3);
-         sector &= ~3;
-       }
-
-      if (len > size)
-       len = size;
-
-      if (grub_biosdisk_rw (GRUB_BIOSDISK_READ, disk, sector, len,
-                           GRUB_MEMORY_MACHINE_SCRATCH_SEG))
-       return grub_errno;
-
-      grub_memcpy (buf, (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + cdoff),
-                  len << GRUB_DISK_SECTOR_BITS);
-      buf += len << GRUB_DISK_SECTOR_BITS;
-      sector += len;
-      size -= len;
-    }
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
-                    grub_size_t size, const char *buf)
-{
-  struct grub_biosdisk_data *data = disk->data;
-
-  if (data->flags & GRUB_BIOSDISK_FLAG_CDROM)
-    return grub_error (GRUB_ERR_IO, "can't write to CDROM");
-
-  while (size)
-    {
-      grub_size_t len;
-
-      len = get_safe_sectors (sector, data->sectors);
-      if (len > size)
-       len = size;
-
-      grub_memcpy ((void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, buf,
-                  len << GRUB_DISK_SECTOR_BITS);
-
-      if (grub_biosdisk_rw (GRUB_BIOSDISK_WRITE, disk, sector, len,
-                           GRUB_MEMORY_MACHINE_SCRATCH_SEG))
-       return grub_errno;
-
-      buf += len << GRUB_DISK_SECTOR_BITS;
-      sector += len;
-      size -= len;
-    }
-
-  return grub_errno;
-}
-
-static struct grub_disk_dev grub_biosdisk_dev =
-  {
-    .name = "biosdisk",
-    .id = GRUB_DISK_DEVICE_BIOSDISK_ID,
-    .iterate = grub_biosdisk_iterate,
-    .open = grub_biosdisk_open,
-    .close = grub_biosdisk_close,
-    .read = grub_biosdisk_read,
-    .write = grub_biosdisk_write,
-    .next = 0
-  };
-
-static void
-grub_disk_biosdisk_fini (void)
-{
-  grub_disk_dev_unregister (&grub_biosdisk_dev);
-}
-
-GRUB_MOD_INIT(biosdisk)
-{
-  struct grub_biosdisk_cdrp *cdrp
-        = (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
-
-  if (grub_disk_firmware_is_tainted)
-    {
-      grub_printf ("Firmware is marked as tainted, refusing to initialize.\n");
-      return;
-    }
-  grub_disk_firmware_fini = grub_disk_biosdisk_fini;
-
-  grub_memset (cdrp, 0, sizeof (*cdrp));
-  cdrp->size = sizeof (*cdrp);
-  cdrp->media_type = 0xFF;
-  if ((! grub_biosdisk_get_cdinfo_int13_extensions (grub_boot_drive, cdrp)) &&
-      ((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK)
-       == GRUB_BIOSDISK_CDTYPE_NO_EMUL))
-    cd_drive = cdrp->drive_no;
-
-  grub_disk_dev_register (&grub_biosdisk_dev);
-}
-
-GRUB_MOD_FINI(biosdisk)
-{
-  grub_disk_biosdisk_fini ();
-}
diff --git a/disk/ieee1275/nand.c b/disk/ieee1275/nand.c
deleted file mode 100644 (file)
index df2ee81..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/* nand.c - NAND flash disk access.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/dl.h>
-#include <grub/ieee1275/ieee1275.h>
-
-struct grub_nand_data
-{
-  grub_ieee1275_ihandle_t handle;
-  grub_uint32_t block_size;
-};
-
-static int
-grub_nand_iterate (int (*hook) (const char *name))
-{
-  auto int dev_iterate (struct grub_ieee1275_devalias *alias);
-  int dev_iterate (struct grub_ieee1275_devalias *alias)
-    {
-      if (! grub_strcmp (alias->name, "nand"))
-        {
-          hook (alias->name);
-          return 1;
-        }
-
-      return 0;
-    }
-
-  return grub_devalias_iterate (dev_iterate);
-}
-
-static grub_err_t
-grub_nand_read (grub_disk_t disk, grub_disk_addr_t sector,
-                grub_size_t size, char *buf);
-
-static grub_err_t
-grub_nand_open (const char *name, grub_disk_t disk)
-{
-  grub_ieee1275_ihandle_t dev_ihandle = 0;
-  struct grub_nand_data *data = 0;
-  struct size_args
-    {
-      struct grub_ieee1275_common_hdr common;
-      grub_ieee1275_cell_t method;
-      grub_ieee1275_cell_t ihandle;
-      grub_ieee1275_cell_t result;
-      grub_ieee1275_cell_t size1;
-      grub_ieee1275_cell_t size2;
-    } args;
-
-  if (! grub_strstr (name, "nand"))
-    return  grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a NAND device");
-
-  data = grub_malloc (sizeof (*data));
-  if (! data)
-    goto fail;
-
-  grub_ieee1275_open (name, &dev_ihandle);
-  if (! dev_ihandle)
-    {
-      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
-      goto fail;
-    }
-
-  data->handle = dev_ihandle;
-
-  INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 2);
-  args.method = (grub_ieee1275_cell_t) "block-size";
-  args.ihandle = dev_ihandle;
-  args.result = 1;
-
-  if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result))
-    {
-      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't get block size");
-      goto fail;
-    }
-
-  data->block_size = (args.size1 >> GRUB_DISK_SECTOR_BITS);
-
-  INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3);
-  args.method = (grub_ieee1275_cell_t) "size";
-  args.ihandle = dev_ihandle;
-  args.result = 1;
-
-  if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result))
-    {
-      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't get disk size");
-      goto fail;
-    }
-
-  disk->total_sectors = args.size1;
-  disk->total_sectors <<= 32;
-  disk->total_sectors += args.size2;
-  disk->total_sectors >>= GRUB_DISK_SECTOR_BITS;
-
-  disk->id = dev_ihandle;
-
-  disk->has_partitions = 0;
-  disk->data = data;
-
-  return 0;
-
-fail:
-  if (dev_ihandle)
-    grub_ieee1275_close (dev_ihandle);
-  grub_free (data);
-  return grub_errno;
-}
-
-static void
-grub_nand_close (grub_disk_t disk)
-{
-  grub_ieee1275_close (((struct grub_nand_data *) disk->data)->handle);
-  grub_free (disk->data);
-}
-
-static grub_err_t
-grub_nand_read (grub_disk_t disk, grub_disk_addr_t sector,
-                grub_size_t size, char *buf)
-{
-  struct grub_nand_data *data = disk->data;
-  grub_size_t bsize, ofs;
-
-  struct read_args
-    {
-      struct grub_ieee1275_common_hdr common;
-      grub_ieee1275_cell_t method;
-      grub_ieee1275_cell_t ihandle;
-      grub_ieee1275_cell_t ofs;
-      grub_ieee1275_cell_t page;
-      grub_ieee1275_cell_t len;
-      grub_ieee1275_cell_t buf;
-      grub_ieee1275_cell_t result;
-    } args;
-
-  INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1);
-  args.method = (grub_ieee1275_cell_t) "pio-read";
-  args.ihandle = data->handle;
-  args.buf = (grub_ieee1275_cell_t) buf;
-  args.page = (grub_ieee1275_cell_t) ((grub_size_t) sector / data->block_size);
-
-  ofs = ((grub_size_t) sector % data->block_size) << GRUB_DISK_SECTOR_BITS;
-  size <<= GRUB_DISK_SECTOR_BITS;
-  bsize = (data->block_size << GRUB_DISK_SECTOR_BITS);
-
-  do
-    {
-      grub_size_t len;
-
-      len = (ofs + size > bsize) ? (bsize - ofs) : size;
-
-      args.len = (grub_ieee1275_cell_t) len;
-      args.ofs = (grub_ieee1275_cell_t) ofs;
-      args.result = 1;
-
-      if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result))
-        return grub_error (GRUB_ERR_READ_ERROR, "read error");
-
-      ofs = 0;
-      size -= len;
-      args.buf += len;
-      args.page++;
-    } while (size);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_nand_write (grub_disk_t disk __attribute ((unused)),
-                 grub_disk_addr_t sector __attribute ((unused)),
-                 grub_size_t size __attribute ((unused)),
-                 const char *buf __attribute ((unused)))
-{
-  return GRUB_ERR_NOT_IMPLEMENTED_YET;
-}
-
-static struct grub_disk_dev grub_nand_dev =
-  {
-    .name = "nand",
-    .id = GRUB_DISK_DEVICE_NAND_ID,
-    .iterate = grub_nand_iterate,
-    .open = grub_nand_open,
-    .close = grub_nand_close,
-    .read = grub_nand_read,
-    .write = grub_nand_write,
-    .next = 0
-  };
-
-GRUB_MOD_INIT(nand)
-{
-  grub_disk_dev_register (&grub_nand_dev);
-}
-
-GRUB_MOD_FINI(nand)
-{
-  grub_disk_dev_unregister (&grub_nand_dev);
-}
diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c
deleted file mode 100644 (file)
index e5a4a67..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/* ofdisk.c - Open Firmware disk access.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/ieee1275/ieee1275.h>
-#include <grub/ieee1275/ofdisk.h>
-
-struct ofdisk_hash_ent
-{
-  char *devpath;
-  struct ofdisk_hash_ent *next;
-};
-
-#define OFDISK_HASH_SZ 8
-static struct ofdisk_hash_ent *ofdisk_hash[OFDISK_HASH_SZ];
-
-static int
-ofdisk_hash_fn (const char *devpath)
-{
-  int hash = 0;
-  while (*devpath)
-    hash ^= *devpath++;
-  return (hash & (OFDISK_HASH_SZ - 1));
-}
-
-static struct ofdisk_hash_ent *
-ofdisk_hash_find (const char *devpath)
-{
-  struct ofdisk_hash_ent *p = ofdisk_hash[ofdisk_hash_fn(devpath)];
-
-  while (p)
-    {
-      if (!grub_strcmp (p->devpath, devpath))
-       break;
-      p = p->next;
-    }
-  return p;
-}
-
-static struct ofdisk_hash_ent *
-ofdisk_hash_add (char *devpath)
-{
-  struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)];
-  struct ofdisk_hash_ent *p = grub_malloc(sizeof (*p));
-
-  if (p)
-    {
-      p->devpath = devpath;
-      p->next = *head;
-      *head = p;
-    }
-  return p;
-}
-
-static int
-grub_ofdisk_iterate (int (*hook) (const char *name))
-{
-  auto int dev_iterate (struct grub_ieee1275_devalias *alias);
-
-  int dev_iterate (struct grub_ieee1275_devalias *alias)
-    {
-      int ret = 0;
-
-      grub_dprintf ("disk", "disk name = %s\n", alias->name);
-
-      if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY))
-       {
-         grub_ieee1275_phandle_t dev;
-         char tmp[8];
-
-         if (grub_ieee1275_finddevice (alias->path, &dev))
-           {
-             grub_dprintf ("disk", "finddevice (%s) failed\n", alias->path);
-             return 0;
-           }
-
-         if (grub_ieee1275_get_property (dev, "iconname", tmp,
-                                         sizeof tmp, 0))
-           {
-             grub_dprintf ("disk", "get iconname failed\n");
-             return 0;
-           }
-
-         if (grub_strcmp (tmp, "sdmmc"))
-           {
-             grub_dprintf ("disk", "device is not an SD card\n");
-             return 0;
-           }
-       }
-
-      if (! grub_strcmp (alias->type, "block") &&
-         grub_strncmp (alias->name, "cdrom", 5))
-       ret = hook (alias->name);
-      return ret;
-    }
-
-  return grub_devalias_iterate (dev_iterate);
-}
-
-static char *
-compute_dev_path (const char *name)
-{
-  char *devpath = grub_malloc (grub_strlen (name) + 3);
-  char *p, c;
-
-  if (!devpath)
-    return NULL;
-
-  /* Un-escape commas. */
-  p = devpath;
-  while ((c = *name++) != '\0')
-    {
-      if (c == '\\' && *name == ',')
-       {
-         *p++ = ',';
-         name++;
-       }
-      else
-       *p++ = c;
-    }
-
-  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0))
-    {
-      *p++ = ':';
-      *p++ = '0';
-    }
-  *p++ = '\0';
-
-  return devpath;
-}
-
-static grub_err_t
-grub_ofdisk_open (const char *name, grub_disk_t disk)
-{
-  grub_ieee1275_phandle_t dev;
-  grub_ieee1275_ihandle_t dev_ihandle = 0;
-  struct ofdisk_hash_ent *op;
-  char *devpath;
-  /* XXX: This should be large enough for any possible case.  */
-  char prop[64];
-  grub_ssize_t actual;
-
-  devpath = compute_dev_path (name);
-  if (! devpath)
-    return grub_errno;
-
-  op = ofdisk_hash_find (devpath);
-  if (!op)
-    op = ofdisk_hash_add (devpath);
-
-  grub_free (devpath);
-  if (!op)
-    return grub_errno;
-
-  grub_dprintf ("disk", "Opening `%s'.\n", op->devpath);
-
-  if (grub_ieee1275_finddevice (op->devpath, &dev))
-    {
-      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read device properties");
-      goto fail;
-    }
-
-  if (grub_ieee1275_get_property (dev, "device_type", prop, sizeof (prop),
-                                 &actual))
-    {
-      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read the device type");
-      goto fail;
-    }
-
-  if (grub_strcmp (prop, "block"))
-    {
-      grub_error (GRUB_ERR_BAD_DEVICE, "not a block device");
-      goto fail;
-    }
-
-  grub_ieee1275_open (op->devpath, &dev_ihandle);
-  if (! dev_ihandle)
-    {
-      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
-      goto fail;
-    }
-
-  grub_dprintf ("disk", "Opened `%s' as handle %p.\n", op->devpath,
-               (void *) (unsigned long) dev_ihandle);
-
-  /* XXX: There is no property to read the number of blocks.  There
-     should be a property `#blocks', but it is not there.  Perhaps it
-     is possible to use seek for this.  */
-  disk->total_sectors = 0xFFFFFFFFUL;
-
-  disk->id = (unsigned long) op;
-
-  /* XXX: Read this, somehow.  */
-  disk->has_partitions = 1;
-  disk->data = (void *) (unsigned long) dev_ihandle;
-  return 0;
-
- fail:
-  if (dev_ihandle)
-    grub_ieee1275_close (dev_ihandle);
-  return grub_errno;
-}
-
-static void
-grub_ofdisk_close (grub_disk_t disk)
-{
-  grub_dprintf ("disk", "Closing handle %p.\n",
-               (void *) disk->data);
-  grub_ieee1275_close ((grub_ieee1275_ihandle_t) (unsigned long) disk->data);
-}
-
-static grub_err_t
-grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
-                 grub_size_t size, char *buf)
-{
-  grub_ssize_t status, actual;
-  unsigned long long pos;
-
-  pos = sector * 512UL;
-
-  grub_ieee1275_seek ((grub_ieee1275_ihandle_t) (unsigned long) disk->data,
-                     pos, &status);
-  if (status < 0)
-    return grub_error (GRUB_ERR_READ_ERROR,
-                      "seek error, can't seek block %llu",
-                      (long long) sector);
-  grub_ieee1275_read ((grub_ieee1275_ihandle_t) (unsigned long) disk->data,
-                     buf, size * 512UL, &actual);
-  if (actual != (grub_ssize_t) (size * 512UL))
-    return grub_error (GRUB_ERR_READ_ERROR, "read error on block: %llu",
-                      (long long) sector);
-
-  return 0;
-}
-
-static grub_err_t
-grub_ofdisk_write (grub_disk_t disk __attribute ((unused)),
-                  grub_disk_addr_t sector __attribute ((unused)),
-                  grub_size_t size __attribute ((unused)),
-                  const char *buf __attribute ((unused)))
-{
-  return GRUB_ERR_NOT_IMPLEMENTED_YET;
-}
-
-static struct grub_disk_dev grub_ofdisk_dev =
-  {
-    .name = "ofdisk",
-    .id = GRUB_DISK_DEVICE_OFDISK_ID,
-    .iterate = grub_ofdisk_iterate,
-    .open = grub_ofdisk_open,
-    .close = grub_ofdisk_close,
-    .read = grub_ofdisk_read,
-    .write = grub_ofdisk_write,
-    .next = 0
-  };
-
-void
-grub_ofdisk_init (void)
-{
-  grub_disk_dev_register (&grub_ofdisk_dev);
-}
-
-void
-grub_ofdisk_fini (void)
-{
-  grub_disk_dev_unregister (&grub_ofdisk_dev);
-}
diff --git a/disk/loopback.c b/disk/loopback.c
deleted file mode 100644 (file)
index 1b525e0..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-/* loopback.c - command to add loopback devices.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/file.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/extcmd.h>
-#include <grub/i18n.h>
-
-struct grub_loopback
-{
-  char *devname;
-  char *filename;
-  int has_partitions;
-  struct grub_loopback *next;
-};
-
-static struct grub_loopback *loopback_list;
-
-static const struct grub_arg_option options[] =
-  {
-    {"delete", 'd', 0, N_("Delete the loopback device entry."), 0, 0},
-    {"partitions", 'p', 0, N_("Simulate a hard drive with partitions."), 0, 0},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-/* Delete the loopback device NAME.  */
-static grub_err_t
-delete_loopback (const char *name)
-{
-  struct grub_loopback *dev;
-  struct grub_loopback **prev;
-
-  /* Search for the device.  */
-  for (dev = loopback_list, prev = &loopback_list;
-       dev;
-       prev = &dev->next, dev = dev->next)
-    if (grub_strcmp (dev->devname, name) == 0)
-      break;
-
-  if (! dev)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "device not found");
-
-  /* Remove the device from the list.  */
-  *prev = dev->next;
-
-  grub_free (dev->devname);
-  grub_free (dev->filename);
-  grub_free (dev);
-
-  return 0;
-}
-
-/* The command to add and remove loopback devices.  */
-static grub_err_t
-grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args)
-{
-  struct grub_arg_list *state = state = cmd->state;
-  grub_file_t file;
-  struct grub_loopback *newdev;
-
-  if (argc < 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
-
-  /* Check if `-d' was used.  */
-  if (state[0].set)
-      return delete_loopback (args[0]);
-
-  if (argc < 2)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
-  file = grub_file_open (args[1]);
-  if (! file)
-    return grub_errno;
-
-  /* Close the file, the only reason for opening it is validation.  */
-  grub_file_close (file);
-
-  /* First try to replace the old device.  */
-  for (newdev = loopback_list; newdev; newdev = newdev->next)
-    if (grub_strcmp (newdev->devname, args[0]) == 0)
-      break;
-
-  if (newdev)
-    {
-      char *newname = grub_strdup (args[1]);
-      if (! newname)
-       return grub_errno;
-
-      grub_free (newdev->filename);
-      newdev->filename = newname;
-
-      /* Set has_partitions when `--partitions' was used.  */
-      newdev->has_partitions = state[1].set;
-
-      return 0;
-    }
-
-  /* Unable to replace it, make a new entry.  */
-  newdev = grub_malloc (sizeof (struct grub_loopback));
-  if (! newdev)
-    return grub_errno;
-
-  newdev->devname = grub_strdup (args[0]);
-  if (! newdev->devname)
-    {
-      grub_free (newdev);
-      return grub_errno;
-    }
-
-  newdev->filename = grub_strdup (args[1]);
-  if (! newdev->filename)
-    {
-      grub_free (newdev->devname);
-      grub_free (newdev);
-      return grub_errno;
-    }
-
-  /* Set has_partitions when `--partitions' was used.  */
-  newdev->has_partitions = state[1].set;
-
-  /* Add the new entry to the list.  */
-  newdev->next = loopback_list;
-  loopback_list = newdev;
-
-  return 0;
-}
-
-\f
-static int
-grub_loopback_iterate (int (*hook) (const char *name))
-{
-  struct grub_loopback *d;
-  for (d = loopback_list; d; d = d->next)
-    {
-      if (hook (d->devname))
-       return 1;
-    }
-  return 0;
-}
-
-static grub_err_t
-grub_loopback_open (const char *name, grub_disk_t disk)
-{
-  grub_file_t file;
-  struct grub_loopback *dev;
-
-  for (dev = loopback_list; dev; dev = dev->next)
-    if (grub_strcmp (dev->devname, name) == 0)
-      break;
-
-  if (! dev)
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
-
-  file = grub_file_open (dev->filename);
-  if (! file)
-    return grub_errno;
-
-  /* Use the filesize for the disk size, round up to a complete sector.  */
-  disk->total_sectors = ((file->size + GRUB_DISK_SECTOR_SIZE - 1)
-                        / GRUB_DISK_SECTOR_SIZE);
-  disk->id = (unsigned long) dev;
-
-  disk->has_partitions = dev->has_partitions;
-  disk->data = file;
-
-  return 0;
-}
-
-static void
-grub_loopback_close (grub_disk_t disk)
-{
-  grub_file_t file = (grub_file_t) disk->data;
-
-  grub_file_close (file);
-}
-
-static grub_err_t
-grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector,
-                   grub_size_t size, char *buf)
-{
-  grub_file_t file = (grub_file_t) disk->data;
-  grub_off_t pos;
-
-  grub_file_seek (file, sector << GRUB_DISK_SECTOR_BITS);
-
-  grub_file_read (file, buf, size << GRUB_DISK_SECTOR_BITS);
-  if (grub_errno)
-    return grub_errno;
-
-  /* In case there is more data read than there is available, in case
-     of files that are not a multiple of GRUB_DISK_SECTOR_SIZE, fill
-     the rest with zeros.  */
-  pos = (sector + size) << GRUB_DISK_SECTOR_BITS;
-  if (pos > file->size)
-    {
-      grub_size_t amount = pos - file->size;
-      grub_memset (buf + (size << GRUB_DISK_SECTOR_BITS) - amount, 0, amount);
-    }
-
-  return 0;
-}
-
-static grub_err_t
-grub_loopback_write (grub_disk_t disk __attribute ((unused)),
-                    grub_disk_addr_t sector __attribute ((unused)),
-                    grub_size_t size __attribute ((unused)),
-                    const char *buf __attribute ((unused)))
-{
-  return GRUB_ERR_NOT_IMPLEMENTED_YET;
-}
-
-static struct grub_disk_dev grub_loopback_dev =
-  {
-    .name = "loopback",
-    .id = GRUB_DISK_DEVICE_LOOPBACK_ID,
-    .iterate = grub_loopback_iterate,
-    .open = grub_loopback_open,
-    .close = grub_loopback_close,
-    .read = grub_loopback_read,
-    .write = grub_loopback_write,
-    .next = 0
-  };
-
-static grub_extcmd_t cmd;
-
-GRUB_MOD_INIT(loopback)
-{
-  cmd = grub_register_extcmd ("loopback", grub_cmd_loopback,
-                             GRUB_COMMAND_FLAG_BOTH,
-                             N_("[-d|-p] DEVICENAME FILE."),
-                             N_("Make a device of a file."), options);
-  grub_disk_dev_register (&grub_loopback_dev);
-}
-
-GRUB_MOD_FINI(loopback)
-{
-  grub_unregister_extcmd (cmd);
-  grub_disk_dev_unregister (&grub_loopback_dev);
-}
diff --git a/disk/lvm.c b/disk/lvm.c
deleted file mode 100644 (file)
index c2ae82d..0000000
+++ /dev/null
@@ -1,624 +0,0 @@
-/* lvm.c - module to read Logical Volumes.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/lvm.h>
-
-#ifdef GRUB_UTIL
-#include <grub/util/misc.h>
-#endif
-
-static struct grub_lvm_vg *vg_list;
-static int lv_count;
-
-\f
-/* Go the string STR and return the number after STR.  *P will point
-   at the number.  In case STR is not found, *P will be NULL and the
-   return value will be 0.  */
-static int
-grub_lvm_getvalue (char **p, char *str)
-{
-  *p = grub_strstr (*p, str);
-  if (! *p)
-    return 0;
-  *p += grub_strlen (str);
-  return grub_strtoul (*p, NULL, 10);
-}
-
-static int
-grub_lvm_iterate (int (*hook) (const char *name))
-{
-  struct grub_lvm_vg *vg;
-  for (vg = vg_list; vg; vg = vg->next)
-    {
-      struct grub_lvm_lv *lv;
-      if (vg->lvs)
-       for (lv = vg->lvs; lv; lv = lv->next)
-         if (hook (lv->name))
-           return 1;
-    }
-
-  return 0;
-}
-
-#ifdef GRUB_UTIL
-static grub_disk_memberlist_t
-grub_lvm_memberlist (grub_disk_t disk)
-{
-  struct grub_lvm_lv *lv = disk->data;
-  grub_disk_memberlist_t list = NULL, tmp;
-  struct grub_lvm_pv *pv;
-
-  if (lv->vg->pvs)
-    for (pv = lv->vg->pvs; pv; pv = pv->next)
-      {
-       if (!pv->disk)
-         grub_util_error ("Couldn't find PV %s. Check your device.map",
-                          pv->name);
-       tmp = grub_malloc (sizeof (*tmp));
-       tmp->disk = pv->disk;
-       tmp->next = list;
-       list = tmp;
-      }
-
-  return list;
-}
-#endif
-
-static grub_err_t
-grub_lvm_open (const char *name, grub_disk_t disk)
-{
-  struct grub_lvm_vg *vg;
-  struct grub_lvm_lv *lv = NULL;
-  for (vg = vg_list; vg; vg = vg->next)
-    {
-      if (vg->lvs)
-       for (lv = vg->lvs; lv; lv = lv->next)
-         if (! grub_strcmp (lv->name, name))
-           break;
-
-      if (lv)
-       break;
-    }
-
-  if (! lv)
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown LVM device %s", name);
-
-  disk->has_partitions = 0;
-  disk->id = lv->number;
-  disk->data = lv;
-  disk->total_sectors = lv->size;
-
-  return 0;
-}
-
-static void
-grub_lvm_close (grub_disk_t disk __attribute ((unused)))
-{
-  return;
-}
-
-static grub_err_t
-grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector,
-               grub_size_t size, char *buf)
-{
-  grub_err_t err = 0;
-  struct grub_lvm_lv *lv = disk->data;
-  struct grub_lvm_vg *vg = lv->vg;
-  struct grub_lvm_segment *seg = lv->segments;
-  struct grub_lvm_pv *pv;
-  grub_uint64_t offset;
-  grub_uint64_t extent;
-  unsigned int i;
-
-  extent = grub_divmod64 (sector, vg->extent_size, NULL);
-
-  /* Find the right segment.  */
-  for (i = 0; i < lv->segment_count; i++)
-    {
-      if ((seg->start_extent <= extent)
-         && ((seg->start_extent + seg->extent_count) > extent))
-       {
-         break;
-       }
-
-      seg++;
-    }
-
-  if (seg->stripe_count == 1)
-    {
-      /* This segment is linear, so that's easy.  We just need to find
-        out the offset in the physical volume and read SIZE bytes
-        from that.  */
-      struct grub_lvm_stripe *stripe = seg->stripes;
-      grub_uint64_t seg_offset; /* Offset of the segment in PV device.  */
-
-      pv = stripe->pv;
-      seg_offset = ((grub_uint64_t) stripe->start
-                   * (grub_uint64_t) vg->extent_size) + pv->start;
-
-      offset = sector - ((grub_uint64_t) seg->start_extent
-                        * (grub_uint64_t) vg->extent_size) + seg_offset;
-    }
-  else
-    {
-      /* This is a striped segment. We have to find the right PV
-        similar to RAID0. */
-      struct grub_lvm_stripe *stripe = seg->stripes;
-      grub_uint32_t a, b;
-      grub_uint64_t seg_offset; /* Offset of the segment in PV device.  */
-      unsigned int stripenr;
-
-      offset = sector - ((grub_uint64_t) seg->start_extent
-                        * (grub_uint64_t) vg->extent_size);
-
-      a = grub_divmod64 (offset, seg->stripe_size, NULL);
-      grub_divmod64 (a, seg->stripe_count, &stripenr);
-
-      a = grub_divmod64 (offset, seg->stripe_size * seg->stripe_count, NULL);
-      grub_divmod64 (offset, seg->stripe_size, &b);
-      offset = a * seg->stripe_size + b;
-
-      stripe += stripenr;
-      pv = stripe->pv;
-
-      seg_offset = ((grub_uint64_t) stripe->start
-                   * (grub_uint64_t) vg->extent_size) + pv->start;
-
-      offset += seg_offset;
-    }
-
-  /* Check whether we actually know the physical volume we want to
-     read from.  */
-  if (pv->disk)
-    err = grub_disk_read (pv->disk, offset, 0,
-                         size << GRUB_DISK_SECTOR_BITS, buf);
-  else
-    err = grub_error (GRUB_ERR_UNKNOWN_DEVICE,
-                     "physical volume %s not found", pv->name);
-
-  return err;
-}
-
-static grub_err_t
-grub_lvm_write (grub_disk_t disk __attribute ((unused)),
-                grub_disk_addr_t sector __attribute ((unused)),
-                grub_size_t size __attribute ((unused)),
-                const char *buf __attribute ((unused)))
-{
-  return GRUB_ERR_NOT_IMPLEMENTED_YET;
-}
-
-static int
-grub_lvm_scan_device (const char *name)
-{
-  grub_err_t err;
-  grub_disk_t disk;
-  grub_uint64_t da_offset, da_size, mda_offset, mda_size;
-  char buf[GRUB_LVM_LABEL_SIZE];
-  char vg_id[GRUB_LVM_ID_STRLEN+1];
-  char pv_id[GRUB_LVM_ID_STRLEN+1];
-  char *metadatabuf, *p, *q, *vgname;
-  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
-  struct grub_lvm_pv_header *pvh;
-  struct grub_lvm_disk_locn *dlocn;
-  struct grub_lvm_mda_header *mdah;
-  struct grub_lvm_raw_locn *rlocn;
-  unsigned int i, j, vgname_len;
-  struct grub_lvm_vg *vg;
-  struct grub_lvm_pv *pv;
-
-  disk = grub_disk_open (name);
-  if (!disk)
-    return 0;
-
-  /* Search for label. */
-  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
-    {
-      err = grub_disk_read (disk, i, 0, sizeof(buf), buf);
-      if (err)
-       goto fail;
-
-      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
-                          sizeof (lh->id)))
-         && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
-                             sizeof (lh->type))))
-       break;
-    }
-
-  /* Return if we didn't find a label. */
-  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
-    goto fail;
-
-  pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
-
-  for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++)
-    {
-      pv_id[j++] = pvh->pv_uuid[i];
-      if ((i != 1) && (i != 29) && (i % 4 == 1))
-       pv_id[j++] = '-';
-    }
-  pv_id[j] = '\0';
-
-  dlocn = pvh->disk_areas_xl;
-  da_offset = grub_le_to_cpu64 (dlocn->offset);
-  da_size = grub_le_to_cpu64 (dlocn->size);
-
-  dlocn++;
-  /* Is it possible to have multiple data/metadata areas? I haven't
-     seen devices that have it. */
-  if (dlocn->offset)
-    {
-      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                 "we don't support multiple LVM data areas");
-
-      goto fail;
-    }
-
-  dlocn++;
-  mda_offset = grub_le_to_cpu64 (dlocn->offset);
-  mda_size = grub_le_to_cpu64 (dlocn->size);
-
-  /* It's possible to have multiple copies of metadata areas, we just use the
-     first one.  */
-
-  /* Allocate buffer space for the circular worst-case scenario. */
-  metadatabuf = grub_malloc (2 * mda_size);
-  if (! metadatabuf)
-    goto fail;
-
-  err = grub_disk_read (disk, 0, mda_offset, mda_size, metadatabuf);
-  if (err)
-    goto fail2;
-
-  mdah = (struct grub_lvm_mda_header *) metadatabuf;
-  if ((grub_strncmp ((char *)mdah->magic, GRUB_LVM_FMTT_MAGIC,
-                    sizeof (mdah->magic)))
-      || (grub_le_to_cpu32 (mdah->version) != GRUB_LVM_FMTT_VERSION))
-    {
-      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                 "unknown LVM metadata header");
-      goto fail2;
-    }
-
-  rlocn = mdah->raw_locns;
-  if (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) >
-      grub_le_to_cpu64 (mdah->size))
-    {
-      /* Metadata is circular. Copy the wrap in place. */
-      grub_memcpy (metadatabuf + mda_size,
-                   metadatabuf + GRUB_LVM_MDA_HEADER_SIZE,
-                   grub_le_to_cpu64 (rlocn->offset) +
-                   grub_le_to_cpu64 (rlocn->size) -
-                   grub_le_to_cpu64 (mdah->size));
-    }
-  p = q = metadatabuf + grub_le_to_cpu64 (rlocn->offset);
-
-  while (*q != ' ' && q < metadatabuf + mda_size)
-    q++;
-
-  if (q == metadatabuf + mda_size)
-    goto fail2;
-
-  vgname_len = q - p;
-  vgname = grub_malloc (vgname_len + 1);
-  if (!vgname)
-    goto fail2;
-
-  grub_memcpy (vgname, p, vgname_len);
-  vgname[vgname_len] = '\0';
-
-  p = grub_strstr (q, "id = \"");
-  if (p == NULL)
-    goto fail3;
-  p += sizeof ("id = \"") - 1;
-  grub_memcpy (vg_id, p, GRUB_LVM_ID_STRLEN);
-  vg_id[GRUB_LVM_ID_STRLEN] = '\0';
-
-  for (vg = vg_list; vg; vg = vg->next)
-    {
-      if (! grub_memcmp(vg_id, vg->id, GRUB_LVM_ID_STRLEN))
-       break;
-    }
-
-  if (! vg)
-    {
-      /* First time we see this volume group. We've to create the
-        whole volume group structure. */
-      vg = grub_malloc (sizeof (*vg));
-      if (! vg)
-       goto fail3;
-      vg->name = vgname;
-      grub_memcpy (vg->id, vg_id, GRUB_LVM_ID_STRLEN+1);
-
-      vg->extent_size = grub_lvm_getvalue (&p, "extent_size = ");
-      if (p == NULL)
-       goto fail4;
-
-      vg->lvs = NULL;
-      vg->pvs = NULL;
-
-      p = grub_strstr (p, "physical_volumes {");
-      if (p)
-       {
-         p += sizeof ("physical_volumes {") - 1;
-
-         /* Add all the pvs to the volume group. */
-         while (1)
-           {
-             int s;
-             while (grub_isspace (*p))
-               p++;
-
-             if (*p == '}')
-               break;
-
-             pv = grub_malloc (sizeof (*pv));
-             q = p;
-             while (*q != ' ')
-               q++;
-
-             s = q - p;
-             pv->name = grub_malloc (s + 1);
-             grub_memcpy (pv->name, p, s);
-             pv->name[s] = '\0';
-
-             p = grub_strstr (p, "id = \"");
-             if (p == NULL)
-               goto pvs_fail;
-             p += sizeof("id = \"") - 1;
-
-             grub_memcpy (pv->id, p, GRUB_LVM_ID_STRLEN);
-             pv->id[GRUB_LVM_ID_STRLEN] = '\0';
-
-             pv->start = grub_lvm_getvalue (&p, "pe_start = ");
-             if (p == NULL)
-               goto pvs_fail;
-
-             p = grub_strchr (p, '}');
-             if (p == NULL)
-               goto pvs_fail;
-             p++;
-
-             pv->disk = NULL;
-             pv->next = vg->pvs;
-             vg->pvs = pv;
-
-             continue;
-           pvs_fail:
-             grub_free (pv->name);
-             grub_free (pv);
-             goto fail4;
-           }
-       }
-
-      p = grub_strstr (p, "logical_volumes");
-      if (p)
-       {
-         p += 18;
-
-         /* And add all the lvs to the volume group. */
-         while (1)
-           {
-             int s;
-             struct grub_lvm_lv *lv;
-             struct grub_lvm_segment *seg;
-
-             while (grub_isspace (*p))
-               p++;
-
-             if (*p == '}')
-               break;
-
-             lv = grub_malloc (sizeof (*lv));
-
-             q = p;
-             while (*q != ' ')
-               q++;
-
-             s = q - p;
-             lv->name = grub_malloc (vgname_len + 1 + s + 1);
-             grub_memcpy (lv->name, vgname, vgname_len);
-             lv->name[vgname_len] = '-';
-             grub_memcpy (lv->name + vgname_len + 1, p, s);
-             lv->name[vgname_len + 1 + s] = '\0';
-
-             lv->size = 0;
-
-             lv->segment_count = grub_lvm_getvalue (&p, "segment_count = ");
-             if (p == NULL)
-               goto lvs_fail;
-             lv->segments = grub_malloc (sizeof (*seg) * lv->segment_count);
-             seg = lv->segments;
-
-             for (i = 0; i < lv->segment_count; i++)
-               {
-                 struct grub_lvm_stripe *stripe;
-
-                 p = grub_strstr (p, "segment");
-                 if (p == NULL)
-                   goto lvs_segment_fail;
-
-                 seg->start_extent = grub_lvm_getvalue (&p, "start_extent = ");
-                 if (p == NULL)
-                   goto lvs_segment_fail;
-                 seg->extent_count = grub_lvm_getvalue (&p, "extent_count = ");
-                 if (p == NULL)
-                   goto lvs_segment_fail;
-                 seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = ");
-                 if (p == NULL)
-                   goto lvs_segment_fail;
-
-                 lv->size += seg->extent_count * vg->extent_size;
-
-                 if (seg->stripe_count != 1)
-                   seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
-
-                 seg->stripes = grub_malloc (sizeof (*stripe)
-                                             * seg->stripe_count);
-                 stripe = seg->stripes;
-
-                 p = grub_strstr (p, "stripes = [");
-                 if (p == NULL)
-                   goto lvs_segment_fail2;
-                 p += sizeof("stripes = [") - 1;
-
-                 for (j = 0; j < seg->stripe_count; j++)
-                   {
-                     char *pvname;
-
-                     p = grub_strchr (p, '"');
-                     if (p == NULL)
-                       continue;
-                     q = ++p;
-                     while (*q != '"')
-                       q++;
-
-                     s = q - p;
-
-                     pvname = grub_malloc (s + 1);
-                      if (pvname == NULL)
-                        goto lvs_segment_fail2;
-
-                     grub_memcpy (pvname, p, s);
-                     pvname[s] = '\0';
-
-                     if (vg->pvs)
-                       for (pv = vg->pvs; pv; pv = pv->next)
-                         {
-                           if (! grub_strcmp (pvname, pv->name))
-                             {
-                               stripe->pv = pv;
-                               break;
-                             }
-                         }
-
-                     grub_free(pvname);
-
-                     stripe->start = grub_lvm_getvalue (&p, ",");
-                     if (p == NULL)
-                       continue;
-
-                     stripe++;
-                   }
-
-                 seg++;
-
-                 continue;
-               lvs_segment_fail2:
-                 grub_free (seg->stripes);
-               lvs_segment_fail:
-                 goto fail4;
-               }
-
-             if (p != NULL)
-               p = grub_strchr (p, '}');
-             if (p == NULL)
-               goto lvs_fail;
-             p += 3;
-
-             lv->number = lv_count++;
-             lv->vg = vg;
-             lv->next = vg->lvs;
-             vg->lvs = lv;
-
-             continue;
-           lvs_fail:
-             grub_free (lv->name);
-             grub_free (lv);
-             goto fail4;
-           }
-       }
-
-       vg->next = vg_list;
-       vg_list = vg;
-    }
-  else
-    {
-      grub_free (vgname);
-    }
-
-  /* Match the device we are currently reading from with the right
-     PV. */
-  if (vg->pvs)
-    for (pv = vg->pvs; pv; pv = pv->next)
-      {
-       if (! grub_memcmp (pv->id, pv_id, GRUB_LVM_ID_STRLEN))
-         {
-           /* This could happen to LVM on RAID, pv->disk points to the
-              raid device, we shouldn't change it.  */
-           if (! pv->disk)
-             pv->disk = grub_disk_open (name);
-           break;
-         }
-      }
-
-  goto fail2;
-
-  /* Failure path.  */
- fail4:
-  grub_free (vg);
- fail3:
-  grub_free (vgname);
-
-  /* Normal exit path.  */
- fail2:
-  grub_free (metadatabuf);
- fail:
-  grub_disk_close (disk);
-  return 0;
-}
-
-static struct grub_disk_dev grub_lvm_dev =
-  {
-    .name = "lvm",
-    .id = GRUB_DISK_DEVICE_LVM_ID,
-    .iterate = grub_lvm_iterate,
-    .open = grub_lvm_open,
-    .close = grub_lvm_close,
-    .read = grub_lvm_read,
-    .write = grub_lvm_write,
-#ifdef GRUB_UTIL
-    .memberlist = grub_lvm_memberlist,
-#endif
-    .next = 0
-  };
-
-\f
-GRUB_MOD_INIT(lvm)
-{
-  grub_device_iterate (&grub_lvm_scan_device);
-  if (grub_errno)
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-    }
-
-  grub_disk_dev_register (&grub_lvm_dev);
-}
-
-GRUB_MOD_FINI(lvm)
-{
-  grub_disk_dev_unregister (&grub_lvm_dev);
-  /* FIXME: free the lvm list. */
-}
diff --git a/disk/mdraid_linux.c b/disk/mdraid_linux.c
deleted file mode 100644 (file)
index 306c66a..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/* mdraid_linux.c - module to handle linux softraid.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/raid.h>
-
-/* Linux RAID on disk structures and constants,
-   copied from include/linux/raid/md_p.h.  */
-
-#define RESERVED_BYTES                 (64 * 1024)
-#define RESERVED_SECTORS               (RESERVED_BYTES / 512)
-
-#define NEW_SIZE_SECTORS(x)            ((x & ~(RESERVED_SECTORS - 1)) \
-                                       - RESERVED_SECTORS)
-
-#define SB_BYTES                       4096
-#define SB_WORDS                       (SB_BYTES / 4)
-#define SB_SECTORS                     (SB_BYTES / 512)
-
-/*
- * The following are counted in 32-bit words
- */
-#define        SB_GENERIC_OFFSET               0
-
-#define SB_PERSONALITY_OFFSET          64
-#define SB_DISKS_OFFSET                        128
-#define SB_DESCRIPTOR_OFFSET           992
-
-#define SB_GENERIC_CONSTANT_WORDS      32
-#define SB_GENERIC_STATE_WORDS         32
-#define SB_GENERIC_WORDS               (SB_GENERIC_CONSTANT_WORDS + \
-                                         SB_GENERIC_STATE_WORDS)
-
-#define SB_PERSONALITY_WORDS           64
-#define SB_DESCRIPTOR_WORDS            32
-#define SB_DISKS                       27
-#define SB_DISKS_WORDS                 (SB_DISKS * SB_DESCRIPTOR_WORDS)
-
-#define SB_RESERVED_WORDS              (1024 \
-                                         - SB_GENERIC_WORDS \
-                                         - SB_PERSONALITY_WORDS \
-                                         - SB_DISKS_WORDS \
-                                         - SB_DESCRIPTOR_WORDS)
-
-#define SB_EQUAL_WORDS                 (SB_GENERIC_WORDS \
-                                         + SB_PERSONALITY_WORDS \
-                                         + SB_DISKS_WORDS)
-
-/*
- * Device "operational" state bits
- */
-#define DISK_FAULTY                    0
-#define DISK_ACTIVE                    1
-#define DISK_SYNC                      2
-#define DISK_REMOVED                   3
-
-#define        DISK_WRITEMOSTLY                9
-
-#define SB_MAGIC                       0xa92b4efc
-
-/*
- * Superblock state bits
- */
-#define SB_CLEAN                       0
-#define SB_ERRORS                      1
-
-#define        SB_BITMAP_PRESENT               8
-
-struct grub_raid_disk_09
-{
-  grub_uint32_t number;                /* Device number in the entire set.  */
-  grub_uint32_t major;         /* Device major number.  */
-  grub_uint32_t minor;         /* Device minor number.  */
-  grub_uint32_t raid_disk;     /* The role of the device in the raid set.  */
-  grub_uint32_t state;         /* Operational state.  */
-  grub_uint32_t reserved[SB_DESCRIPTOR_WORDS - 5];
-};
-
-struct grub_raid_super_09
-{
-  /*
-   * Constant generic information
-   */
-  grub_uint32_t md_magic;      /* MD identifier.  */
-  grub_uint32_t major_version; /* Major version.  */
-  grub_uint32_t minor_version; /* Minor version.  */
-  grub_uint32_t patch_version; /* Patchlevel version.  */
-  grub_uint32_t gvalid_words;  /* Number of used words in this section.  */
-  grub_uint32_t set_uuid0;     /* Raid set identifier.  */
-  grub_uint32_t ctime;         /* Creation time.  */
-  grub_uint32_t level;         /* Raid personality.  */
-  grub_uint32_t size;          /* Apparent size of each individual disk.  */
-  grub_uint32_t nr_disks;      /* Total disks in the raid set.  */
-  grub_uint32_t raid_disks;    /* Disks in a fully functional raid set.  */
-  grub_uint32_t md_minor;      /* Preferred MD minor device number.  */
-  grub_uint32_t not_persistent;        /* Does it have a persistent superblock.  */
-  grub_uint32_t set_uuid1;     /* Raid set identifier #2.  */
-  grub_uint32_t set_uuid2;     /* Raid set identifier #3.  */
-  grub_uint32_t set_uuid3;     /* Raid set identifier #4.  */
-  grub_uint32_t gstate_creserved[SB_GENERIC_CONSTANT_WORDS - 16];
-
-  /*
-   * Generic state information
-   */
-  grub_uint32_t utime;         /* Superblock update time.  */
-  grub_uint32_t state;         /* State bits (clean, ...).  */
-  grub_uint32_t active_disks;  /* Number of currently active disks.  */
-  grub_uint32_t working_disks; /* Number of working disks.  */
-  grub_uint32_t failed_disks;  /* Number of failed disks.  */
-  grub_uint32_t spare_disks;   /* Number of spare disks.  */
-  grub_uint32_t sb_csum;       /* Checksum of the whole superblock.  */
-  grub_uint64_t events;                /* Superblock update count.  */
-  grub_uint64_t cp_events;     /* Checkpoint update count.  */
-  grub_uint32_t recovery_cp;   /* Recovery checkpoint sector count.  */
-  grub_uint32_t gstate_sreserved[SB_GENERIC_STATE_WORDS - 12];
-
-  /*
-   * Personality information
-   */
-  grub_uint32_t layout;                /* The array's physical layout.  */
-  grub_uint32_t chunk_size;    /* Chunk size in bytes.  */
-  grub_uint32_t root_pv;       /* LV root PV.  */
-  grub_uint32_t root_block;    /* LV root block.  */
-  grub_uint32_t pstate_reserved[SB_PERSONALITY_WORDS - 4];
-
-  /*
-   * Disks information
-   */
-  struct grub_raid_disk_09 disks[SB_DISKS];
-
-  /*
-   * Reserved
-   */
-  grub_uint32_t reserved[SB_RESERVED_WORDS];
-
-  /*
-   * Active descriptor
-   */
-  struct grub_raid_disk_09 this_disk;
-} __attribute__ ((packed));
-
-static grub_err_t
-grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array)
-{
-  grub_disk_addr_t sector;
-  grub_uint64_t size;
-  struct grub_raid_super_09 sb;
-  grub_uint32_t *uuid;
-
-  /* The sector where the RAID superblock is stored, if available. */
-  size = grub_disk_get_size (disk);
-  sector = NEW_SIZE_SECTORS (size);
-
-  if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb))
-    return grub_errno;
-
-  /* Look whether there is a RAID superblock. */
-  if (sb.md_magic != SB_MAGIC)
-    return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid");
-
-  /* FIXME: Also support version 1.0. */
-  if (sb.major_version != 0 || sb.minor_version != 90)
-    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                      "unsupported RAID version: %d.%d",
-                      sb.major_version, sb.minor_version);
-
-  /* FIXME: Check the checksum. */
-
-  /* Multipath.  */
-  if ((int) sb.level == -4)
-    sb.level = 1;
-
-  if (sb.level != 0 && sb.level != 1 && sb.level != 4 &&
-      sb.level != 5 && sb.level != 6 && sb.level != 10)
-    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                      "unsupported RAID level: %d", sb.level);
-
-  array->number = sb.md_minor;
-  array->level = sb.level;
-  array->layout = sb.layout;
-  array->total_devs = sb.raid_disks;
-  array->disk_size = (sb.size) ? sb.size * 2 : sector;
-  array->chunk_size = sb.chunk_size >> 9;
-  array->index = sb.this_disk.number;
-  array->uuid_len = 16;
-  array->uuid = grub_malloc (16);
-  if (!array->uuid)
-    return grub_errno;
-
-  uuid = (grub_uint32_t *) array->uuid;
-  uuid[0] = sb.set_uuid0;
-  uuid[1] = sb.set_uuid1;
-  uuid[2] = sb.set_uuid2;
-  uuid[3] = sb.set_uuid3;
-
-  return 0;
-}
-
-static struct grub_raid grub_mdraid_dev = {
-  .name = "mdraid",
-  .detect = grub_mdraid_detect,
-  .next = 0
-};
-
-GRUB_MOD_INIT (mdraid)
-{
-  grub_raid_register (&grub_mdraid_dev);
-}
-
-GRUB_MOD_FINI (mdraid)
-{
-  grub_raid_unregister (&grub_mdraid_dev);
-}
diff --git a/disk/memdisk.c b/disk/memdisk.c
deleted file mode 100644 (file)
index 2e88850..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/* memdisk.c - Access embedded memory disk.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/kernel.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/types.h>
-
-static char *memdisk_addr;
-static grub_off_t memdisk_size = 0;
-
-static int
-grub_memdisk_iterate (int (*hook) (const char *name))
-{
-  return hook ("memdisk");
-}
-
-static grub_err_t
-grub_memdisk_open (const char *name, grub_disk_t disk)
-{
-  if (grub_strcmp (name, "memdisk"))
-      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a memdisk");
-
-  disk->total_sectors = memdisk_size / GRUB_DISK_SECTOR_SIZE;
-  disk->id = (unsigned long) "mdsk";
-  disk->has_partitions = 0;
-
-  return GRUB_ERR_NONE;
-}
-
-static void
-grub_memdisk_close (grub_disk_t disk __attribute((unused)))
-{
-}
-
-static grub_err_t
-grub_memdisk_read (grub_disk_t disk __attribute((unused)), grub_disk_addr_t sector,
-                   grub_size_t size, char *buf)
-{
-  grub_memcpy (buf, memdisk_addr + (sector << GRUB_DISK_SECTOR_BITS), size << GRUB_DISK_SECTOR_BITS);
-  return 0;
-}
-
-static grub_err_t
-grub_memdisk_write (grub_disk_t disk __attribute((unused)), grub_disk_addr_t sector,
-                    grub_size_t size, const char *buf)
-{
-  grub_memcpy (memdisk_addr + (sector << GRUB_DISK_SECTOR_BITS), buf, size << GRUB_DISK_SECTOR_BITS);
-  return 0;
-}
-
-static struct grub_disk_dev grub_memdisk_dev =
-  {
-    .name = "memdisk",
-    .id = GRUB_DISK_DEVICE_MEMDISK_ID,
-    .iterate = grub_memdisk_iterate,
-    .open = grub_memdisk_open,
-    .close = grub_memdisk_close,
-    .read = grub_memdisk_read,
-    .write = grub_memdisk_write,
-    .next = 0
-  };
-
-GRUB_MOD_INIT(memdisk)
-{
-  auto int hook (struct grub_module_header *);
-  int hook (struct grub_module_header *header)
-    {
-      if (header->type == OBJ_TYPE_MEMDISK)
-       {
-         char *memdisk_orig_addr;
-         memdisk_orig_addr = (char *) header + sizeof (struct grub_module_header);
-
-         grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr);
-
-         memdisk_size = header->size - sizeof (struct grub_module_header);
-         memdisk_addr = grub_malloc (memdisk_size);
-
-         grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n");
-         grub_memmove (memdisk_addr, memdisk_orig_addr, memdisk_size);
-
-         grub_disk_dev_register (&grub_memdisk_dev);
-         return 1;
-       }
-
-      return 0;
-    }
-
-  grub_module_iterate (hook);
-}
-
-GRUB_MOD_FINI(memdisk)
-{
-  if (! memdisk_size)
-    return;
-  grub_free (memdisk_addr);
-  grub_disk_dev_unregister (&grub_memdisk_dev);
-}
diff --git a/disk/raid.c b/disk/raid.c
deleted file mode 100644 (file)
index 2d544af..0000000
+++ /dev/null
@@ -1,691 +0,0 @@
-/* raid.c - module to read RAID arrays.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/raid.h>
-
-/* Linked list of RAID arrays. */
-static struct grub_raid_array *array_list;
-grub_raid5_recover_func_t grub_raid5_recover_func;
-grub_raid6_recover_func_t grub_raid6_recover_func;
-
-\f
-static char
-grub_is_array_readable (struct grub_raid_array *array)
-{
-  switch (array->level)
-    {
-    case 0:
-      if (array->nr_devs == array->total_devs)
-       return 1;
-      break;
-
-    case 1:
-      if (array->nr_devs >= 1)
-       return 1;
-      break;
-
-    case 4:
-    case 5:
-    case 6:
-    case 10:
-      {
-        unsigned int n;
-
-        if (array->level == 10)
-          {
-            n = array->layout & 0xFF;
-            if (n == 1)
-              n = (array->layout >> 8) & 0xFF;
-
-            n--;
-          }
-        else
-          n = array->level / 3;
-
-        if (array->nr_devs >= array->total_devs - n)
-          return 1;
-
-        break;
-      }
-    }
-
-  return 0;
-}
-
-static int
-grub_raid_iterate (int (*hook) (const char *name))
-{
-  struct grub_raid_array *array;
-
-  for (array = array_list; array != NULL; array = array->next)
-    {
-      if (grub_is_array_readable (array))
-       if (hook (array->name))
-         return 1;
-    }
-
-  return 0;
-}
-
-#ifdef GRUB_UTIL
-static grub_disk_memberlist_t
-grub_raid_memberlist (grub_disk_t disk)
-{
-  struct grub_raid_array *array = disk->data;
-  grub_disk_memberlist_t list = NULL, tmp;
-  unsigned int i;
-
-  for (i = 0; i < array->total_devs; i++)
-    if (array->device[i])
-      {
-        tmp = grub_malloc (sizeof (*tmp));
-        tmp->disk = array->device[i];
-        tmp->next = list;
-        list = tmp;
-      }
-
-  return list;
-}
-#endif
-
-static grub_err_t
-grub_raid_open (const char *name, grub_disk_t disk)
-{
-  struct grub_raid_array *array;
-  unsigned n;
-
-  for (array = array_list; array != NULL; array = array->next)
-    {
-      if (!grub_strcmp (array->name, name))
-       if (grub_is_array_readable (array))
-         break;
-    }
-
-  if (!array)
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown RAID device %s",
-                       name);
-
-  disk->has_partitions = 1;
-  disk->id = array->number;
-  disk->data = array;
-
-  grub_dprintf ("raid", "%s: total_devs=%d, disk_size=%lld\n", name,
-               array->total_devs, (unsigned long long) array->disk_size);
-
-  switch (array->level)
-    {
-    case 1:
-      disk->total_sectors = array->disk_size;
-      break;
-
-    case 10:
-      n = array->layout & 0xFF;
-      if (n == 1)
-        n = (array->layout >> 8) & 0xFF;
-
-      disk->total_sectors = grub_divmod64 (array->total_devs *
-                                           array->disk_size,
-                                           n, 0);
-      break;
-
-    case 0:
-    case 4:
-    case 5:
-    case 6:
-      n = array->level / 3;
-
-      disk->total_sectors = (array->total_devs - n) * array->disk_size;
-      break;
-    }
-
-  grub_dprintf ("raid", "%s: level=%d, total_sectors=%lld\n", name,
-               array->level, (unsigned long long) disk->total_sectors);
-
-  return 0;
-}
-
-static void
-grub_raid_close (grub_disk_t disk __attribute ((unused)))
-{
-  return;
-}
-
-void
-grub_raid_block_xor (char *buf1, const char *buf2, int size)
-{
-  grub_size_t *p1;
-  const grub_size_t *p2;
-
-  p1 = (grub_size_t *) buf1;
-  p2 = (const grub_size_t *) buf2;
-  size /= GRUB_CPU_SIZEOF_VOID_P;
-
-  while (size)
-    {
-      *(p1++) ^= *(p2++);
-      size--;
-    }
-}
-
-static grub_err_t
-grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector,
-               grub_size_t size, char *buf)
-{
-  struct grub_raid_array *array = disk->data;
-  grub_err_t err = 0;
-
-  switch (array->level)
-    {
-    case 0:
-    case 1:
-    case 10:
-      {
-        grub_disk_addr_t read_sector, far_ofs;
-       grub_uint32_t disknr, b, near, far, ofs;
-
-        read_sector = grub_divmod64 (sector, array->chunk_size, &b);
-        far = ofs = near = 1;
-        far_ofs = 0;
-
-        if (array->level == 1)
-          near = array->total_devs;
-        else if (array->level == 10)
-          {
-            near = array->layout & 0xFF;
-            far = (array->layout >> 8) & 0xFF;
-            if (array->layout >> 16)
-              {
-                ofs = far;
-                far_ofs = 1;
-              }
-            else
-              far_ofs = grub_divmod64 (array->disk_size,
-                                       far * array->chunk_size, 0);
-
-            far_ofs *= array->chunk_size;
-          }
-
-        read_sector = grub_divmod64 (read_sector * near, array->total_devs,
-                                     &disknr);
-
-        ofs *= array->chunk_size;
-        read_sector *= ofs;
-
-        while (1)
-          {
-            grub_size_t read_size;
-            unsigned int i, j;
-
-            read_size = array->chunk_size - b;
-            if (read_size > size)
-              read_size = size;
-
-            for (i = 0; i < near; i++)
-              {
-                unsigned int k;
-
-                k = disknr;
-                for (j = 0; j < far; j++)
-                  {
-                    if (array->device[k])
-                      {
-                        if (grub_errno == GRUB_ERR_READ_ERROR)
-                          grub_errno = GRUB_ERR_NONE;
-
-                        err = grub_disk_read (array->device[k],
-                                              read_sector + j * far_ofs + b,
-                                              0,
-                                              read_size << GRUB_DISK_SECTOR_BITS,
-                                              buf);
-                        if (! err)
-                          break;
-                        else if (err != GRUB_ERR_READ_ERROR)
-                          return err;
-                      }
-                    else
-                      err = grub_error (GRUB_ERR_READ_ERROR,
-                                        "disk missing");
-
-                    k++;
-                    if (k == array->total_devs)
-                      k = 0;
-                  }
-
-                if (! err)
-                  break;
-
-                disknr++;
-                if (disknr == array->total_devs)
-                  {
-                    disknr = 0;
-                    read_sector += ofs;
-                  }
-              }
-
-            if (err)
-              return err;
-
-            buf += read_size << GRUB_DISK_SECTOR_BITS;
-           size -= read_size;
-           if (! size)
-             break;
-
-            b = 0;
-            disknr += (near - i);
-            while (disknr >= array->total_devs)
-              {
-                disknr -= array->total_devs;
-                read_sector += ofs;
-              }
-          }
-        break;
-      }
-
-    case 4:
-    case 5:
-    case 6:
-      {
-       grub_disk_addr_t read_sector;
-       grub_uint32_t b, p, n, disknr, e;
-
-        /* n = 1 for level 4 and 5, 2 for level 6.  */
-        n = array->level / 3;
-
-       /* Find the first sector to read. */
-       read_sector = grub_divmod64 (sector, array->chunk_size, &b);
-       read_sector = grub_divmod64 (read_sector, array->total_devs - n,
-                                     &disknr);
-        if (array->level >= 5)
-          {
-            grub_divmod64 (read_sector, array->total_devs, &p);
-
-            if (! (array->layout & GRUB_RAID_LAYOUT_RIGHT_MASK))
-              p = array->total_devs - 1 - p;
-
-            if (array->layout & GRUB_RAID_LAYOUT_SYMMETRIC_MASK)
-              {
-                disknr += p + n;
-              }
-            else
-              {
-                grub_uint32_t q;
-
-                q = p + (n - 1);
-                if (q >= array->total_devs)
-                  q -= array->total_devs;
-
-                if (disknr >= p)
-                  disknr += n;
-                else if (disknr >= q)
-                  disknr += q + 1;
-              }
-
-            if (disknr >= array->total_devs)
-              disknr -= array->total_devs;
-          }
-        else
-          p = array->total_devs - n;
-
-       read_sector *= array->chunk_size;
-
-       while (1)
-         {
-            grub_size_t read_size;
-            int next_level;
-
-            read_size = array->chunk_size - b;
-            if (read_size > size)
-              read_size = size;
-
-            e = 0;
-            if (array->device[disknr])
-              {
-                /* Reset read error.  */
-                if (grub_errno == GRUB_ERR_READ_ERROR)
-                  grub_errno = GRUB_ERR_NONE;
-
-                err = grub_disk_read (array->device[disknr],
-                                      read_sector + b, 0,
-                                      read_size << GRUB_DISK_SECTOR_BITS,
-                                      buf);
-
-                if ((err) && (err != GRUB_ERR_READ_ERROR))
-                  break;
-                e++;
-              }
-            else
-              err = GRUB_ERR_READ_ERROR;
-
-           if (err)
-              {
-                if (array->nr_devs < array->total_devs - n + e)
-                  break;
-
-                grub_errno = GRUB_ERR_NONE;
-                if (array->level == 6)
-                  {
-                    err = ((grub_raid6_recover_func) ?
-                           (*grub_raid6_recover_func) (array, disknr, p,
-                                                       buf, read_sector + b,
-                                                       read_size) :
-                           grub_error (GRUB_ERR_BAD_DEVICE,
-                                       "raid6rec is not loaded"));
-                  }
-                else
-                  {
-                    err = ((grub_raid5_recover_func) ?
-                           (*grub_raid5_recover_func) (array, disknr,
-                                                       buf, read_sector + b,
-                                                       read_size) :
-                           grub_error (GRUB_ERR_BAD_DEVICE,
-                                       "raid5rec is not loaded"));
-                  }
-
-                if (err)
-                  break;
-              }
-
-           buf += read_size << GRUB_DISK_SECTOR_BITS;
-           size -= read_size;
-           if (! size)
-             break;
-
-            b = 0;
-           disknr++;
-
-            if (array->layout & GRUB_RAID_LAYOUT_SYMMETRIC_MASK)
-              {
-                if (disknr == array->total_devs)
-                  disknr = 0;
-
-                next_level = (disknr == p);
-              }
-            else
-              {
-                if (disknr == p)
-                  disknr += n;
-
-                next_level = (disknr >= array->total_devs);
-              }
-
-            if (next_level)
-              {
-                read_sector += array->chunk_size;
-
-                if (array->level >= 5)
-                  {
-                    if (array->layout & GRUB_RAID_LAYOUT_RIGHT_MASK)
-                      p = (p == array->total_devs - 1) ? 0 : p + 1;
-                    else
-                      p = (p == 0) ? array->total_devs - 1 : p - 1;
-
-                    if (array->layout & GRUB_RAID_LAYOUT_SYMMETRIC_MASK)
-                      {
-                        disknr = p + n;
-                        if (disknr >= array->total_devs)
-                          disknr -= array->total_devs;
-                      }
-                    else
-                      {
-                        disknr -= array->total_devs;
-                        if (disknr == p)
-                          disknr += n;
-                      }
-                  }
-                else
-                  disknr = 0;
-              }
-         }
-      }
-      break;
-    }
-
-  return err;
-}
-
-static grub_err_t
-grub_raid_write (grub_disk_t disk __attribute ((unused)),
-                grub_disk_addr_t sector __attribute ((unused)),
-                grub_size_t size __attribute ((unused)),
-                const char *buf __attribute ((unused)))
-{
-  return GRUB_ERR_NOT_IMPLEMENTED_YET;
-}
-
-static grub_err_t
-insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
-              const char *scanner_name)
-{
-  struct grub_raid_array *array = 0, *p;
-
-  /* See whether the device is part of an array we have already seen a
-     device from. */
-  for (p = array_list; p != NULL; p = p->next)
-    if ((p->uuid_len == new_array->uuid_len) &&
-        (! grub_memcmp (p->uuid, new_array->uuid, p->uuid_len)))
-      {
-        grub_free (new_array->uuid);
-        array = p;
-
-        /* Do some checks before adding the device to the array.  */
-
-        /* FIXME: Check whether the update time of the superblocks are
-           the same. */
-
-        if (array->total_devs == array->nr_devs)
-          /* We found more members of the array than the array
-             actually has according to its superblock.  This shouldn't
-             happen normally.  */
-          grub_dprintf ("raid", "array->nr_devs > array->total_devs (%d)?!?",
-                       array->total_devs);
-
-        if (array->device[new_array->index] != NULL)
-          /* We found multiple devices with the same number. Again,
-             this shouldn't happen.*/
-          grub_dprintf ("raid", "Found two disks with the number %d?!?",
-                       new_array->number);
-
-        if (new_array->disk_size < array->disk_size)
-          array->disk_size = new_array->disk_size;
-        break;
-      }
-
-  /* Add an array to the list if we didn't find any.  */
-  if (!array)
-    {
-      array = grub_malloc (sizeof (*array));
-      if (!array)
-        {
-          grub_free (new_array->uuid);
-          return grub_errno;
-        }
-
-      *array = *new_array;
-      array->nr_devs = 0;
-      grub_memset (&array->device, 0, sizeof (array->device));
-
-      /* Check whether we don't have multiple arrays with the same number. */
-      for (p = array_list; p != NULL; p = p->next)
-        {
-          if (p->number == array->number)
-            break;
-        }
-
-      if (p)
-        {
-          /* The number is already in use, so we need to find an new number. */
-          int i = 0;
-
-          while (1)
-            {
-              for (p = array_list; p != NULL; p = p->next)
-                {
-                  if (p->number == i)
-                    break;
-                }
-
-              if (!p)
-                {
-                  /* We found an unused number.  */
-                  array->number = i;
-                  break;
-                }
-
-              i++;
-            }
-        }
-
-      array->name = grub_xasprintf ("md%d", array->number);
-      if (! array->name)
-        {
-          grub_free (array->uuid);
-          grub_free (array);
-
-          return grub_errno;
-        }
-
-      grub_dprintf ("raid", "Found array %s (%s)\n", array->name,
-                    scanner_name);
-
-      /* Add our new array to the list.  */
-      array->next = array_list;
-      array_list = array;
-
-      /* RAID 1 doesn't use a chunksize but code assumes one so set
-        one. */
-      if (array->level == 1)
-       array->chunk_size = 64;
-    }
-
-  /* Add the device to the array. */
-  array->device[new_array->index] = disk;
-  array->nr_devs++;
-
-  return 0;
-}
-
-static grub_raid_t grub_raid_list;
-
-static void
-free_array (void)
-{
-  struct grub_raid_array *array;
-
-  array = array_list;
-  while (array)
-    {
-      struct grub_raid_array *p;
-      int i;
-
-      p = array;
-      array = array->next;
-
-      for (i = 0; i < GRUB_RAID_MAX_DEVICES; i++)
-        if (p->device[i])
-          grub_disk_close (p->device[i]);
-
-      grub_free (p->uuid);
-      grub_free (p->name);
-      grub_free (p);
-    }
-
-  array_list = 0;
-}
-
-void
-grub_raid_register (grub_raid_t raid)
-{
-  auto int hook (const char *name);
-  int hook (const char *name)
-    {
-      grub_disk_t disk;
-      struct grub_raid_array array;
-
-      grub_dprintf ("raid", "Scanning for RAID devices on disk %s\n", name);
-
-      disk = grub_disk_open (name);
-      if (!disk)
-        return 0;
-
-      if ((disk->total_sectors != GRUB_ULONG_MAX) &&
-         (! grub_raid_list->detect (disk, &array)) &&
-         (! insert_array (disk, &array, grub_raid_list->name)))
-       return 0;
-
-      /* This error usually means it's not raid, no need to display
-        it.  */
-      if (grub_errno != GRUB_ERR_OUT_OF_RANGE)
-       grub_print_error ();
-
-      grub_errno = GRUB_ERR_NONE;
-
-      grub_disk_close (disk);
-
-      return 0;
-    }
-
-  raid->next = grub_raid_list;
-  grub_raid_list = raid;
-  grub_device_iterate (&hook);
-}
-
-void
-grub_raid_unregister (grub_raid_t raid)
-{
-  grub_raid_t *p, q;
-
-  for (p = &grub_raid_list, q = *p; q; p = &(q->next), q = q->next)
-    if (q == raid)
-      {
-       *p = q->next;
-       break;
-      }
-}
-
-static struct grub_disk_dev grub_raid_dev =
-  {
-    .name = "raid",
-    .id = GRUB_DISK_DEVICE_RAID_ID,
-    .iterate = grub_raid_iterate,
-    .open = grub_raid_open,
-    .close = grub_raid_close,
-    .read = grub_raid_read,
-    .write = grub_raid_write,
-#ifdef GRUB_UTIL
-    .memberlist = grub_raid_memberlist,
-#endif
-    .next = 0
-  };
-
-\f
-GRUB_MOD_INIT(raid)
-{
-  grub_disk_dev_register (&grub_raid_dev);
-}
-
-GRUB_MOD_FINI(raid)
-{
-  grub_disk_dev_unregister (&grub_raid_dev);
-  free_array ();
-}
diff --git a/disk/raid5_recover.c b/disk/raid5_recover.c
deleted file mode 100644 (file)
index 31cef88..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* raid5_recover.c - module to recover from faulty RAID4/5 arrays.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/raid.h>
-
-static grub_err_t
-grub_raid5_recover (struct grub_raid_array *array, int disknr,
-                    char *buf, grub_disk_addr_t sector, int size)
-{
-  char *buf2;
-  int i;
-
-  size <<= GRUB_DISK_SECTOR_BITS;
-  buf2 = grub_malloc (size);
-  if (!buf2)
-    return grub_errno;
-
-  grub_memset (buf, 0, size);
-
-  for (i = 0; i < (int) array->total_devs; i++)
-    {
-      grub_err_t err;
-
-      if (i == disknr)
-        continue;
-
-      err = grub_disk_read (array->device[i], sector, 0, size, buf2);
-
-      if (err)
-        {
-          grub_free (buf2);
-          return err;
-        }
-
-      grub_raid_block_xor (buf, buf2, size);
-    }
-
-  grub_free (buf2);
-
-  return GRUB_ERR_NONE;
-}
-
-GRUB_MOD_INIT(raid5rec)
-{
-  grub_raid5_recover_func = grub_raid5_recover;
-}
-
-GRUB_MOD_FINI(raid5rec)
-{
-  grub_raid5_recover_func = 0;
-}
diff --git a/disk/raid6_recover.c b/disk/raid6_recover.c
deleted file mode 100644 (file)
index 550968c..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/* raid6_recover.c - module to recover from faulty RAID6 arrays.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/raid.h>
-
-static grub_uint8_t raid6_table1[256][256];
-static grub_uint8_t raid6_table2[256][256];
-
-static void
-grub_raid_block_mul (grub_uint8_t mul, char *buf, int size)
-{
-  int i;
-  grub_uint8_t *p;
-
-  p = (grub_uint8_t *) buf;
-  for (i = 0; i < size; i++, p++)
-    *p = raid6_table1[mul][*p];
-}
-
-static void
-grub_raid6_init_table (void)
-{
-  int i, j;
-
-  for (i = 0; i < 256; i++)
-    raid6_table1[i][1] = raid6_table1[1][i] = i;
-
-  for (i = 2; i < 256; i++)
-    for (j = i; j < 256; j++)
-      {
-        int n;
-        grub_uint8_t c;
-
-        n = i >> 1;
-
-        c = raid6_table1[n][j];
-        c = (c << 1) ^ ((c & 0x80) ? 0x1d : 0);
-        if (i & 1)
-          c ^= j;
-
-        raid6_table1[j][i] = raid6_table1[i][j] = c;
-      }
-
-  raid6_table2[0][0] = 1;
-  for (i = 1; i < 256; i++)
-    raid6_table2[i][i] = raid6_table1[raid6_table2[i - 1][i - 1]][2];
-
-  for (i = 0; i < 254; i++)
-    for (j = 0; j < 254; j++)
-      {
-        grub_uint8_t c, n;
-        int k;
-
-        if (i == j)
-          continue;
-
-        k = i - j;
-        if (k < 0)
-          k += 255;
-
-        c = n = raid6_table2[k][k] ^ 1;
-        for (k = 0; k < 253; k++)
-          c = raid6_table1[c][n];
-
-        raid6_table2[i][j] = raid6_table1[raid6_table2[255 - j][255 - j]][c];
-      }
-}
-
-static grub_err_t
-grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
-                    char *buf, grub_disk_addr_t sector, int size)
-{
-  int i, q, pos;
-  int bad1 = -1, bad2 = -1;
-  char *pbuf = 0, *qbuf = 0;
-
-  size <<= GRUB_DISK_SECTOR_BITS;
-  pbuf = grub_zalloc (size);
-  if (!pbuf)
-    goto quit;
-
-  qbuf = grub_zalloc (size);
-  if (!qbuf)
-    goto quit;
-
-  q = p + 1;
-  if (q == (int) array->total_devs)
-    q = 0;
-
-  pos = q + 1;
-  if (pos == (int) array->total_devs)
-    pos = 0;
-
-  for (i = 0; i < (int) array->total_devs - 2; i++)
-    {
-      if (pos == disknr)
-        bad1 = i;
-      else
-        {
-          if ((array->device[pos]) &&
-              (! grub_disk_read (array->device[pos], sector, 0, size, buf)))
-            {
-              grub_raid_block_xor (pbuf, buf, size);
-              grub_raid_block_mul (raid6_table2[i][i], buf, size);
-              grub_raid_block_xor (qbuf, buf, size);
-            }
-          else
-            {
-              /* Too many bad devices */
-              if (bad2 >= 0)
-                goto quit;
-
-              bad2 = i;
-              grub_errno = GRUB_ERR_NONE;
-            }
-        }
-
-      pos++;
-      if (pos == (int) array->total_devs)
-        pos = 0;
-    }
-
-  /* Invalid disknr or p */
-  if (bad1 < 0)
-    goto quit;
-
-  if (bad2 < 0)
-    {
-      /* One bad device */
-      if ((array->device[p]) &&
-          (! grub_disk_read (array->device[p], sector, 0, size, buf)))
-        {
-          grub_raid_block_xor (buf, pbuf, size);
-          goto quit;
-        }
-
-      if (! array->device[q])
-        {
-          grub_error (GRUB_ERR_READ_ERROR, "not enough disk to restore");
-          goto quit;
-        }
-
-      grub_errno = GRUB_ERR_NONE;
-      if (grub_disk_read (array->device[q], sector, 0, size, buf))
-        goto quit;
-
-      grub_raid_block_xor (buf, qbuf, size);
-      grub_raid_block_mul (raid6_table2[255 - bad1][255 - bad1], buf,
-                           size);
-    }
-  else
-    {
-      /* Two bad devices */
-      grub_uint8_t c;
-
-      if ((! array->device[p]) || (! array->device[q]))
-        {
-          grub_error (GRUB_ERR_READ_ERROR, "not enough disk to restore");
-          goto quit;
-        }
-
-      if (grub_disk_read (array->device[p], sector, 0, size, buf))
-        goto quit;
-
-      grub_raid_block_xor (pbuf, buf, size);
-
-      if (grub_disk_read (array->device[q], sector, 0, size, buf))
-        goto quit;
-
-      grub_raid_block_xor (qbuf, buf, size);
-
-      c = raid6_table2[bad2][bad1];
-      grub_raid_block_mul (c, qbuf, size);
-
-      c = raid6_table1[raid6_table2[bad2][bad2]][c];
-      grub_raid_block_mul (c, pbuf, size);
-
-      grub_raid_block_xor (pbuf, qbuf, size);
-      grub_memcpy (buf, pbuf, size);
-    }
-
-quit:
-  grub_free (pbuf);
-  grub_free (qbuf);
-
-  return grub_errno;
-}
-
-GRUB_MOD_INIT(raid6rec)
-{
-  grub_raid6_init_table ();
-  grub_raid6_recover_func = grub_raid6_recover;
-}
-
-GRUB_MOD_FINI(raid6rec)
-{
-  grub_raid6_recover_func = 0;
-}
diff --git a/disk/scsi.c b/disk/scsi.c
deleted file mode 100644 (file)
index eba2372..0000000
+++ /dev/null
@@ -1,407 +0,0 @@
-/* scsi.c - scsi support.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/kernel.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/types.h>
-#include <grub/scsi.h>
-#include <grub/scsicmd.h>
-
-\f
-static grub_scsi_dev_t grub_scsi_dev_list;
-
-void
-grub_scsi_dev_register (grub_scsi_dev_t dev)
-{
-  dev->next = grub_scsi_dev_list;
-  grub_scsi_dev_list = dev;
-}
-
-void
-grub_scsi_dev_unregister (grub_scsi_dev_t dev)
-{
-  grub_scsi_dev_t *p, q;
-
-  for (p = &grub_scsi_dev_list, q = *p; q; p = &(q->next), q = q->next)
-    if (q == dev)
-      {
-        *p = q->next;
-       break;
-      }
-}
-
-\f
-/* Determine the the device is removable and the type of the device
-   SCSI.  */
-static grub_err_t
-grub_scsi_inquiry (grub_scsi_t scsi)
-{
-  struct grub_scsi_inquiry iq;
-  struct grub_scsi_inquiry_data iqd;
-  grub_err_t err;
-
-  iq.opcode = grub_scsi_cmd_inquiry;
-  iq.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
-  iq.reserved = 0;
-  iq.alloc_length = 0x24; /* XXX: Hardcoded for now */
-  iq.reserved2 = 0;
-
-  err = scsi->dev->read (scsi, sizeof (iq), (char *) &iq,
-                        sizeof (iqd), (char *) &iqd);
-  if (err)
-    return err;
-
-  scsi->devtype = iqd.devtype & GRUB_SCSI_DEVTYPE_MASK;
-  scsi->removable = iqd.rmb >> GRUB_SCSI_REMOVABLE_BIT;
-
-  return GRUB_ERR_NONE;
-}
-
-/* Read the capacity and block size of SCSI.  */
-static grub_err_t
-grub_scsi_read_capacity (grub_scsi_t scsi)
-{
-  struct grub_scsi_read_capacity rc;
-  struct grub_scsi_read_capacity_data rcd;
-  grub_err_t err;
-
-  rc.opcode = grub_scsi_cmd_read_capacity;
-  rc.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
-  grub_memset (rc.reserved, 0, sizeof (rc.reserved));
-
-  err = scsi->dev->read (scsi, sizeof (rc), (char *) &rc,
-                        sizeof (rcd), (char *) &rcd);
-  if (err)
-    return err;
-
-  scsi->size = grub_be_to_cpu32 (rcd.size);
-  scsi->blocksize = grub_be_to_cpu32 (rcd.blocksize);
-
-  return GRUB_ERR_NONE;
-}
-
-/* Send a SCSI request for DISK: read SIZE sectors starting with
-   sector SECTOR to BUF.  */
-static grub_err_t
-grub_scsi_read10 (grub_disk_t disk, grub_disk_addr_t sector,
-                 grub_size_t size, char *buf)
-{
-  grub_scsi_t scsi;
-  struct grub_scsi_read10 rd;
-
-  scsi = disk->data;
-
-  rd.opcode = grub_scsi_cmd_read10;
-  rd.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
-  rd.lba = grub_cpu_to_be32 (sector);
-  rd.reserved = 0;
-  rd.size = grub_cpu_to_be16 (size);
-  rd.reserved2 = 0;
-  rd.pad = 0;
-
-  return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
-}
-
-/* Send a SCSI request for DISK: read SIZE sectors starting with
-   sector SECTOR to BUF.  */
-static grub_err_t
-grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector,
-                 grub_size_t size, char *buf)
-{
-  grub_scsi_t scsi;
-  struct grub_scsi_read12 rd;
-
-  scsi = disk->data;
-
-  rd.opcode = grub_scsi_cmd_read12;
-  rd.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
-  rd.lba = grub_cpu_to_be32 (sector);
-  rd.size = grub_cpu_to_be32 (size);
-  rd.reserved = 0;
-  rd.control = 0;
-
-  return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
-}
-
-#if 0
-/* Send a SCSI request for DISK: write the data stored in BUF to SIZE
-   sectors starting with SECTOR.  */
-static grub_err_t
-grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector,
-                  grub_size_t size, char *buf)
-{
-  grub_scsi_t scsi;
-  struct grub_scsi_write10 wr;
-
-  scsi = disk->data;
-
-  wr.opcode = grub_scsi_cmd_write10;
-  wr.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
-  wr.lba = grub_cpu_to_be32 (sector);
-  wr.reserved = 0;
-  wr.size = grub_cpu_to_be16 (size);
-  wr.reserved2 = 0;
-  wr.pad = 0;
-
-  return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
-}
-
-/* Send a SCSI request for DISK: write the data stored in BUF to SIZE
-   sectors starting with SECTOR.  */
-static grub_err_t
-grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector,
-                  grub_size_t size, char *buf)
-{
-  grub_scsi_t scsi;
-  struct grub_scsi_write10 wr;
-
-  scsi = disk->data;
-
-  wr.opcode = grub_scsi_cmd_write12;
-  wr.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
-  wr.lba = grub_cpu_to_be32 (sector);
-  wr.size = grub_cpu_to_be32 (size);
-  wr.reserved = 0;
-  wr.pad = 0;
-
-  return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
-}
-#endif
-
-\f
-static int
-grub_scsi_iterate (int (*hook) (const char *name))
-{
-  grub_scsi_dev_t p;
-
-  auto int scsi_iterate (const char *name, int luns);
-
-  int scsi_iterate (const char *name, int luns)
-    {
-      int i;
-
-      /* In case of a single LUN, just return `usbX'.  */
-      if (luns == 1)
-       return hook (name);
-
-      /* In case of multiple LUNs, every LUN will get a prefix to
-        distinguish it.  */
-      for (i = 0; i < luns; i++)
-       {
-         char *sname;
-         int ret;
-         sname = grub_xasprintf ("%s%c", name, 'a' + i);
-         if (!sname)
-           return 1;
-         ret = hook (sname);
-         grub_free (sname);
-         if (ret)
-           return 1;
-       }
-      return 0;
-    }
-
-  for (p = grub_scsi_dev_list; p; p = p->next)
-    if (p->iterate && (p->iterate) (scsi_iterate))
-      return 1;
-
-  return 0;
-}
-
-static grub_err_t
-grub_scsi_open (const char *name, grub_disk_t disk)
-{
-  grub_scsi_dev_t p;
-  grub_scsi_t scsi;
-  grub_err_t err;
-  int len;
-  int lun;
-
-  scsi = grub_malloc (sizeof (*scsi));
-  if (! scsi)
-    return grub_errno;
-
-  len = grub_strlen (name);
-  lun = name[len - 1] - 'a';
-
-  /* Try to detect a LUN ('a'-'z'), otherwise just use the first
-     LUN.  */
-  if (lun < 0 || lun > 26)
-    lun = 0;
-
-  for (p = grub_scsi_dev_list; p; p = p->next)
-    {
-      if (p->open (name, scsi))
-       continue;
-
-      disk->id = (unsigned long) "scsi"; /* XXX */
-      disk->data = scsi;
-      scsi->dev = p;
-      scsi->lun = lun;
-      scsi->name = grub_strdup (name);
-      if (! scsi->name)
-       {
-         grub_free (scsi);
-         return grub_errno;
-       }
-
-      grub_dprintf ("scsi", "dev opened\n");
-
-      err = grub_scsi_inquiry (scsi);
-      if (err)
-       {
-         grub_free (scsi);
-         grub_dprintf ("scsi", "inquiry failed\n");
-         return err;
-       }
-
-      grub_dprintf ("scsi", "inquiry: devtype=0x%02x removable=%d\n",
-                   scsi->devtype, scsi->removable);
-
-      /* Try to be conservative about the device types
-        supported.  */
-      if (scsi->devtype != grub_scsi_devtype_direct
-         && scsi->devtype != grub_scsi_devtype_cdrom)
-       {
-         grub_free (scsi);
-         return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
-                            "unknown SCSI device");
-       }
-
-      if (scsi->devtype == grub_scsi_devtype_cdrom)
-       disk->has_partitions = 0;
-      else
-       disk->has_partitions = 1;
-
-      err = grub_scsi_read_capacity (scsi);
-      if (err)
-       {
-         grub_free (scsi);
-         grub_dprintf ("scsi", "READ CAPACITY failed\n");
-         return err;
-       }
-
-      /* SCSI blocks can be something else than 512, although GRUB
-        wants 512 byte blocks.  */
-      disk->total_sectors = ((scsi->size * scsi->blocksize)
-                            << GRUB_DISK_SECTOR_BITS);
-
-      grub_dprintf ("scsi", "capacity=%llu, blksize=%d\n",
-                   (unsigned long long) disk->total_sectors,
-                   scsi->blocksize);
-
-      return GRUB_ERR_NONE;
-    }
-
-  grub_free (scsi);
-
-  return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk");
-}
-
-static void
-grub_scsi_close (grub_disk_t disk)
-{
-  grub_scsi_t scsi;
-
-  scsi = disk->data;
-  scsi->dev->close (scsi);
-  grub_free (scsi);
-}
-
-static grub_err_t
-grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector,
-               grub_size_t size, char *buf)
-{
-  grub_scsi_t scsi;
-
-  scsi = disk->data;
-
-  /* SCSI sectors are variable in size.  GRUB uses 512 byte
-     sectors.  */
-  if (scsi->blocksize != GRUB_DISK_SECTOR_SIZE)
-    {
-      unsigned spb = scsi->blocksize >> GRUB_DISK_SECTOR_BITS;
-      if (! (spb != 0 && (scsi->blocksize & GRUB_DISK_SECTOR_SIZE) == 0))
-       return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                          "unsupported SCSI block size");
-
-      grub_uint32_t sector_mod = 0;
-      sector = grub_divmod64 (sector, spb, &sector_mod);
-
-      if (! (sector_mod == 0 && size % spb == 0))
-       return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                          "unaligned SCSI read not supported");
-
-      size /= spb;
-    }
-
-  /* Depending on the type, select a read function.  */
-  switch (scsi->devtype)
-    {
-    case grub_scsi_devtype_direct:
-      return grub_scsi_read10 (disk, sector, size, buf);
-
-    case grub_scsi_devtype_cdrom:
-      return grub_scsi_read12 (disk, sector, size, buf);
-    }
-
-  /* XXX: Never reached.  */
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_scsi_write (grub_disk_t disk __attribute((unused)),
-                grub_disk_addr_t sector __attribute((unused)),
-                grub_size_t size __attribute((unused)),
-                const char *buf __attribute((unused)))
-{
-#if 0
-  /* XXX: Not tested yet!  */
-
-  /* XXX: This should depend on the device type?  */
-  return grub_scsi_write10 (disk, sector, size, buf);
-#endif
-  return GRUB_ERR_NOT_IMPLEMENTED_YET;
-}
-
-
-static struct grub_disk_dev grub_scsi_dev =
-  {
-    .name = "scsi",
-    .id = GRUB_DISK_DEVICE_SCSI_ID,
-    .iterate = grub_scsi_iterate,
-    .open = grub_scsi_open,
-    .close = grub_scsi_close,
-    .read = grub_scsi_read,
-    .write = grub_scsi_write,
-    .next = 0
-  };
-
-GRUB_MOD_INIT(scsi)
-{
-  grub_disk_dev_register (&grub_scsi_dev);
-}
-
-GRUB_MOD_FINI(scsi)
-{
-  grub_disk_dev_unregister (&grub_scsi_dev);
-}
diff --git a/disk/usbms.c b/disk/usbms.c
deleted file mode 100644 (file)
index 8554b22..0000000
+++ /dev/null
@@ -1,394 +0,0 @@
-/* usbms.c - USB Mass Storage Support.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/usb.h>
-#include <grub/scsi.h>
-#include <grub/scsicmd.h>
-#include <grub/misc.h>
-
-#define GRUB_USBMS_DIRECTION_BIT       7
-
-/* The USB Mass Storage Command Block Wrapper.  */
-struct grub_usbms_cbw
-{
-  grub_uint32_t signature;
-  grub_uint32_t tag;
-  grub_uint32_t transfer_length;
-  grub_uint8_t flags;
-  grub_uint8_t lun;
-  grub_uint8_t length;
-  grub_uint8_t cbwcb[16];
-} __attribute__ ((packed));
-
-struct grub_usbms_csw
-{
-  grub_uint32_t signature;
-  grub_uint32_t tag;
-  grub_uint32_t residue;
-  grub_uint8_t status;
-} __attribute__ ((packed));
-
-struct grub_usbms_dev
-{
-  struct grub_usb_device *dev;
-
-  int luns;
-
-  int interface;
-  struct grub_usb_desc_endp *in;
-  struct grub_usb_desc_endp *out;
-
-  int in_maxsz;
-  int out_maxsz;
-
-  struct grub_usbms_dev *next;
-};
-typedef struct grub_usbms_dev *grub_usbms_dev_t;
-
-static grub_usbms_dev_t grub_usbms_dev_list;
-
-static int devcnt;
-
-static grub_err_t
-grub_usbms_reset (grub_usb_device_t dev, int interface)
-{
-  return grub_usb_control_msg (dev, 0x21, 255, 0, interface, 0, 0);
-}
-
-static void
-grub_usbms_finddevs (void)
-{
-  auto int usb_iterate (grub_usb_device_t dev);
-
-  int usb_iterate (grub_usb_device_t usbdev)
-    {
-      grub_usb_err_t err;
-      struct grub_usb_desc_device *descdev = &usbdev->descdev;
-      int i;
-
-      if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0)
-       return 0;
-
-      /* XXX: Just check configuration 0 for now.  */
-      for (i = 0; i < usbdev->config[0].descconf->numif; i++)
-       {
-         struct grub_usbms_dev *usbms;
-         struct grub_usb_desc_if *interf;
-         int j;
-         grub_uint8_t luns;
-
-         interf = usbdev->config[0].interf[i].descif;
-
-         /* If this is not a USB Mass Storage device with a supported
-            protocol, just skip it.  */
-         if (interf->class != GRUB_USB_CLASS_MASS_STORAGE
-             || interf->subclass != GRUB_USBMS_SUBCLASS_BULK
-             || interf->protocol != GRUB_USBMS_PROTOCOL_BULK)
-           {
-             continue;
-           }
-
-         devcnt++;
-         usbms = grub_zalloc (sizeof (struct grub_usbms_dev));
-         if (! usbms)
-           return 1;
-
-         usbms->dev = usbdev;
-         usbms->interface = i;
-
-         /* Iterate over all endpoints of this interface, at least a
-            IN and OUT bulk endpoint are required.  */
-         for (j = 0; j < interf->endpointcnt; j++)
-           {
-             struct grub_usb_desc_endp *endp;
-             endp = &usbdev->config[0].interf[i].descendp[j];
-
-             if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2)
-               {
-                 /* Bulk IN endpoint.  */
-                 usbms->in = endp;
-                 grub_usb_clear_halt (usbdev, endp->endp_addr & 128);
-                 usbms->in_maxsz = endp->maxpacket;
-               }
-             else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2)
-               {
-                 /* Bulk OUT endpoint.  */
-                 usbms->out = endp;
-                 grub_usb_clear_halt (usbdev, endp->endp_addr & 128);
-                 usbms->out_maxsz = endp->maxpacket;
-               }
-           }
-
-         if (!usbms->in || !usbms->out)
-           {
-             grub_free (usbms);
-             return 0;
-           }
-
-         /* Query the amount of LUNs.  */
-         err = grub_usb_control_msg (usbdev, 0xA1, 254,
-                                     0, i, 1, (char *) &luns);
-         if (err)
-           {
-             /* In case of a stall, clear the stall.  */
-             if (err == GRUB_USB_ERR_STALL)
-               {
-                 grub_usb_clear_halt (usbdev, usbms->in->endp_addr & 3);
-                 grub_usb_clear_halt (usbdev, usbms->out->endp_addr & 3);
-               }
-
-             /* Just set the amount of LUNs to one.  */
-             grub_errno = GRUB_ERR_NONE;
-             usbms->luns = 1;
-           }
-         else
-           usbms->luns = luns;
-
-         /* XXX: Check the magic values, does this really make
-            sense?  */
-         grub_usb_control_msg (usbdev, (1 << 6) | 1, 255,
-                               0, i, 0, 0);
-
-         /* XXX: To make Qemu work?  */
-         if (usbms->luns == 0)
-           usbms->luns = 1;
-
-         usbms->next = grub_usbms_dev_list;
-         grub_usbms_dev_list = usbms;
-
-         /* XXX: Activate the first configuration.  */
-         grub_usb_set_configuration (usbdev, 1);
-
-         /* Bulk-Only Mass Storage Reset, after the reset commands
-            will be accepted.  */
-         grub_usbms_reset (usbdev, i);
-
-         return 0;
-       }
-
-      return 0;
-    }
-
-  grub_usb_iterate (usb_iterate);
-}
-
-\f
-
-static int
-grub_usbms_iterate (int (*hook) (const char *name, int luns))
-{
-  grub_usbms_dev_t p;
-  int cnt = 0;
-
-  for (p = grub_usbms_dev_list; p; p = p->next)
-    {
-      char *devname;
-      devname = grub_xasprintf ("usb%d", cnt);
-
-      if (hook (devname, p->luns))
-       {
-         grub_free (devname);
-         return 1;
-       }
-      grub_free (devname);
-      cnt++;
-    }
-
-  return 0;
-}
-
-static grub_err_t
-grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
-                    grub_size_t size, char *buf, int read_write)
-{
-  struct grub_usbms_cbw cbw;
-  grub_usbms_dev_t dev = (grub_usbms_dev_t) scsi->data;
-  struct grub_usbms_csw status;
-  static grub_uint32_t tag = 0;
-  grub_usb_err_t err = GRUB_USB_ERR_NONE;
-  int retrycnt = 3 + 1;
-
- retry:
-  retrycnt--;
-  if (retrycnt == 0)
-    return grub_error (GRUB_ERR_IO, "USB Mass Storage stalled");
-
-  /* Setup the request.  */
-  grub_memset (&cbw, 0, sizeof (cbw));
-  cbw.signature = grub_cpu_to_le32 (0x43425355);
-  cbw.tag = tag++;
-  cbw.transfer_length = grub_cpu_to_le32 (size);
-  cbw.flags = (!read_write) << GRUB_USBMS_DIRECTION_BIT;
-  cbw.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
-  cbw.length = cmdsize;
-  grub_memcpy (cbw.cbwcb, cmd, cmdsize);
-
-  /* Write the request.  */
-  err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr & 15,
-                            sizeof (cbw), (char *) &cbw);
-  if (err)
-    {
-      if (err == GRUB_USB_ERR_STALL)
-       {
-         grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
-         goto retry;
-       }
-      return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed");
-    }
-
-  /* Read/write the data.  */
-  if (read_write == 0)
-    {
-      err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15, size, buf);
-      grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL);
-      if (err)
-       {
-         if (err == GRUB_USB_ERR_STALL)
-           {
-             grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
-             goto retry;
-           }
-         return grub_error (GRUB_ERR_READ_ERROR,
-                            "can't read from USB Mass Storage device");
-       }
-    }
-  else
-    {
-      err = grub_usb_bulk_write (dev->dev, dev->in->endp_addr & 15, size, buf);
-      grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL);
-      if (err)
-       {
-         if (err == GRUB_USB_ERR_STALL)
-           {
-             grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
-             goto retry;
-           }
-         return grub_error (GRUB_ERR_WRITE_ERROR,
-                            "can't write to USB Mass Storage device");
-       }
-    }
-
-  /* Read the status.  */
-  err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15,
-                           sizeof (status), (char *) &status);
-  if (err)
-    {
-      if (err == GRUB_USB_ERR_STALL)
-       {
-         grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
-         goto retry;
-       }
-      return grub_error (GRUB_ERR_READ_ERROR,
-                        "can't read status from USB Mass Storage device");
-    }
-
-  /* XXX: Magic and check this code.  */
-  if (status.status == 2)
-    {
-      /* XXX: Phase error, reset device.  */
-      grub_usbms_reset (dev->dev, dev->interface);
-      grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
-      grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
-
-      goto retry;
-    }
-
-  if (status.status)
-    return grub_error (GRUB_ERR_READ_ERROR,
-                      "error communication with USB Mass Storage device");
-
-  return GRUB_ERR_NONE;
-}
-
-
-static grub_err_t
-grub_usbms_read (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
-                grub_size_t size, char *buf)
-{
-  return grub_usbms_transfer (scsi, cmdsize, cmd, size, buf, 0);
-}
-
-static grub_err_t
-grub_usbms_write (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
-                 grub_size_t size, char *buf)
-{
-  return grub_usbms_transfer (scsi, cmdsize, cmd, size, buf, 1);
-}
-
-static grub_err_t
-grub_usbms_open (const char *name, struct grub_scsi *scsi)
-{
-  grub_usbms_dev_t p;
-  int devnum;
-  int i = 0;
-
-  if (grub_strncmp (name, "usb", 3))
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
-                      "not a USB Mass Storage device");
-
-  devnum = grub_strtoul (name + 3, NULL, 10);
-  for (p = grub_usbms_dev_list; p; p = p->next)
-    {
-      /* Check if this is the devnumth device.  */
-      if (devnum == i)
-       {
-         scsi->data = p;
-         scsi->name = grub_strdup (name);
-         scsi->luns = p->luns;
-         if (! scsi->name)
-           return grub_errno;
-
-         return GRUB_ERR_NONE;
-       }
-
-      i++;
-    }
-
-  return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
-                    "not a USB Mass Storage device");
-}
-
-static void
-grub_usbms_close (struct grub_scsi *scsi)
-{
-  grub_free (scsi->name);
-}
-
-static struct grub_scsi_dev grub_usbms_dev =
-  {
-    .name = "usb",
-    .iterate = grub_usbms_iterate,
-    .open = grub_usbms_open,
-    .close = grub_usbms_close,
-    .read = grub_usbms_read,
-    .write = grub_usbms_write
-  };
-
-GRUB_MOD_INIT(usbms)
-{
-  grub_usbms_finddevs ();
-  grub_scsi_dev_register (&grub_usbms_dev);
-}
-
-GRUB_MOD_FINI(usbms)
-{
-  grub_scsi_dev_unregister (&grub_usbms_dev);
-}
diff --git a/docs/Makefile.am b/docs/Makefile.am
new file mode 100644 (file)
index 0000000..ab65a8d
--- /dev/null
@@ -0,0 +1,6 @@
+AUTOMAKE_OPTIONS = subdir-objects
+AM_MAKEINFOFLAGS = --force --no-split --no-validate
+
+info_TEXINFOS = grub.texi
+grub_TEXINFOS = fdl.texi
+
diff --git a/efiemu/i386/coredetect.c b/efiemu/i386/coredetect.c
deleted file mode 100644 (file)
index 828508d..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/efiemu/efiemu.h>
-#include <grub/machine/efiemu.h>
-#include <grub/command.h>
-
-#define cpuid(num,a,b,c,d) \
-  asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
-               : "=a" (a), "=r" (b), "=c" (c), "=d" (d)  \
-               : "0" (num))
-
-#define bit_LM (1 << 29)
-
-char *
-grub_efiemu_get_default_core_name (void)
-{
-
-  unsigned int eax, ebx, ecx, edx;
-  unsigned int max_level;
-  unsigned int ext_level;
-
-  /* See if we can use cpuid.  */
-  asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
-               "pushl %0; popfl; pushfl; popl %0; popfl"
-               : "=&r" (eax), "=&r" (ebx)
-               : "i" (0x00200000));
-  if (((eax ^ ebx) & 0x00200000) == 0)
-    return "efiemu32.o";
-
-  /* Check the highest input value for eax.  */
-  cpuid (0, eax, ebx, ecx, edx);
-  /* We only look at the first four characters.  */
-  max_level = eax;
-  if (max_level == 0)
-    return "efiemu32.o";
-
-  cpuid (0x80000000, eax, ebx, ecx, edx);
-  ext_level = eax;
-  if (ext_level < 0x80000000)
-    return "efiemu32.o";
-
-  cpuid (0x80000001, eax, ebx, ecx, edx);
-  return (edx & bit_LM) ? "efiemu64.o" : "efiemu32.o";
-}
diff --git a/efiemu/i386/loadcore32.c b/efiemu/i386/loadcore32.c
deleted file mode 100644 (file)
index 24b63ec..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/* i386 CPU-specific part of loadcore.c for 32-bit mode */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/efiemu/efiemu.h>
-#include <grub/cpu/efiemu.h>
-#include <grub/elf.h>
-
-/* Check if EHDR is a valid ELF header.  */
-int
-grub_arch_efiemu_check_header32 (void *ehdr)
-{
-  Elf32_Ehdr *e = ehdr;
-
-  /* Check the magic numbers.  */
-  return (e->e_ident[EI_CLASS] == ELFCLASS32
-         && e->e_ident[EI_DATA] == ELFDATA2LSB
-         && e->e_machine == EM_386);
-}
-
-/* Relocate symbols.  */
-grub_err_t
-grub_arch_efiemu_relocate_symbols32 (grub_efiemu_segment_t segs,
-                                    struct grub_efiemu_elf_sym *elfsyms,
-                                    void *ehdr)
-{
-  unsigned i;
-  Elf32_Ehdr *e = ehdr;
-  Elf32_Shdr *s;
-  grub_err_t err;
-
-  grub_dprintf ("efiemu", "relocating symbols %d %d\n",
-               e->e_shoff, e->e_shnum);
-
-  for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_REL)
-      {
-       grub_efiemu_segment_t seg;
-       grub_dprintf ("efiemu", "shtrel\n");
-
-       /* Find the target segment.  */
-       for (seg = segs; seg; seg = seg->next)
-         if (seg->section == s->sh_info)
-           break;
-
-       if (seg)
-         {
-           Elf32_Rel *rel, *max;
-
-           for (rel = (Elf32_Rel *) ((char *) e + s->sh_offset),
-                  max = rel + s->sh_size / s->sh_entsize;
-                rel < max;
-                rel++)
-             {
-               Elf32_Word *addr;
-               struct grub_efiemu_elf_sym sym;
-               if (seg->size < rel->r_offset)
-                 return grub_error (GRUB_ERR_BAD_MODULE,
-                                    "reloc offset is out of the segment");
-
-               addr = (Elf32_Word *)
-                 ((char *) grub_efiemu_mm_obtain_request (seg->handle)
-                  + seg->off + rel->r_offset);
-               sym = elfsyms[ELF32_R_SYM (rel->r_info)];
-
-               switch (ELF32_R_TYPE (rel->r_info))
-                 {
-                 case R_386_32:
-                   if ((err = grub_efiemu_write_value
-                        (addr, sym.off + *addr, sym.handle, 0,
-                         seg->ptv_rel_needed, sizeof (grub_uint32_t))))
-                     return err;
-
-                   break;
-
-                 case R_386_PC32:
-                   if ((err = grub_efiemu_write_value
-                        (addr, sym.off + *addr - rel->r_offset
-                         - seg->off, sym.handle, seg->handle,
-                         seg->ptv_rel_needed, sizeof (grub_uint32_t))))
-                     return err;
-                   break;
-                 default:
-                   return grub_error (GRUB_ERR_BAD_OS,
-                                      "unrecognised relocation");
-                 }
-             }
-         }
-      }
-
-  return GRUB_ERR_NONE;
-}
-
-
diff --git a/efiemu/i386/loadcore64.c b/efiemu/i386/loadcore64.c
deleted file mode 100644 (file)
index a692790..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/* i386 CPU-specific part of loadcore.c for 32-bit mode */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/efiemu/efiemu.h>
-#include <grub/cpu/efiemu.h>
-#include <grub/elf.h>
-
-/* Check if EHDR is a valid ELF header.  */
-int
-grub_arch_efiemu_check_header64 (void *ehdr)
-{
-  Elf64_Ehdr *e = ehdr;
-
-  return (e->e_ident[EI_CLASS] == ELFCLASS64
-         && e->e_ident[EI_DATA] == ELFDATA2LSB
-         && e->e_machine == EM_X86_64);
-}
-
-/* Relocate symbols.  */
-grub_err_t
-grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs,
-                                    struct grub_efiemu_elf_sym *elfsyms,
-                                    void *ehdr)
-{
-  unsigned i;
-  Elf64_Ehdr *e = ehdr;
-  Elf64_Shdr *s;
-  grub_err_t err;
-
-  for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_RELA)
-      {
-       grub_efiemu_segment_t seg;
-       grub_dprintf ("efiemu", "shtrel\n");
-
-       /* Find the target segment.  */
-       for (seg = segs; seg; seg = seg->next)
-         if (seg->section == s->sh_info)
-           break;
-
-       if (seg)
-         {
-           Elf64_Rela *rel, *max;
-
-           for (rel = (Elf64_Rela *) ((char *) e + s->sh_offset),
-                  max = rel + (unsigned long) s->sh_size
-                  / (unsigned long)s->sh_entsize;
-                rel < max;
-                rel++)
-             {
-               void *addr;
-               grub_uint32_t *addr32;
-               grub_uint64_t *addr64;
-               struct grub_efiemu_elf_sym sym;
-               if (seg->size < rel->r_offset)
-                 return grub_error (GRUB_ERR_BAD_MODULE,
-                                    "reloc offset is out of the segment");
-
-               addr =
-                 ((char *) grub_efiemu_mm_obtain_request (seg->handle)
-                  + seg->off + rel->r_offset);
-               addr32 = (grub_uint32_t *) addr;
-               addr64 = (grub_uint64_t *) addr;
-               sym = elfsyms[ELF64_R_SYM (rel->r_info)];
-
-               switch (ELF64_R_TYPE (rel->r_info))
-                 {
-                 case R_X86_64_64:
-                   if ((err = grub_efiemu_write_value
-                        (addr, *addr64 + rel->r_addend + sym.off, sym.handle,
-                         0, seg->ptv_rel_needed, sizeof (grub_uint64_t))))
-                     return err;
-                   break;
-
-                 case R_X86_64_PC32:
-                   if ((err = grub_efiemu_write_value
-                        (addr, *addr32 + rel->r_addend + sym.off
-                         - rel->r_offset - seg->off, sym.handle, seg->handle,
-                         seg->ptv_rel_needed, sizeof (grub_uint32_t))))
-                     return err;
-                   break;
-
-                  case R_X86_64_32:
-                  case R_X86_64_32S:
-                   if ((err = grub_efiemu_write_value
-                        (addr, *addr32 + rel->r_addend + sym.off, sym.handle,
-                         0, seg->ptv_rel_needed, sizeof (grub_uint32_t))))
-                     return err;
-                    break;
-                 default:
-                   return grub_error (GRUB_ERR_BAD_OS,
-                                      "unrecognised relocation");
-                 }
-             }
-         }
-      }
-
-  return GRUB_ERR_NONE;
-}
diff --git a/efiemu/i386/pc/cfgtables.c b/efiemu/i386/pc/cfgtables.c
deleted file mode 100644 (file)
index 9c6b4e5..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Register SMBIOS and ACPI tables. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/efiemu/efiemu.h>
-#include <grub/machine/efiemu.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/acpi.h>
-
-grub_err_t
-grub_machine_efiemu_init_tables ()
-{
-  grub_uint8_t *ptr;
-  void *table;
-  grub_err_t err;
-  grub_efi_guid_t smbios = GRUB_EFI_SMBIOS_TABLE_GUID;
-  grub_efi_guid_t acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
-  grub_efi_guid_t acpi = GRUB_EFI_ACPI_TABLE_GUID;
-
-  err = grub_efiemu_unregister_configuration_table (smbios);
-  if (err)
-    return err;
-  err = grub_efiemu_unregister_configuration_table (acpi);
-  if (err)
-    return err;
-  err = grub_efiemu_unregister_configuration_table (acpi20);
-  if (err)
-    return err;
-
-  table = grub_acpi_get_rsdpv1 ();
-  if (table)
-    {
-      err = grub_efiemu_register_configuration_table (acpi, 0, 0, table);
-      if (err)
-       return err;
-    }
-  table = grub_acpi_get_rsdpv2 ();
-  if (table)
-    {
-      err = grub_efiemu_register_configuration_table (acpi20, 0, 0, table);
-      if (err)
-       return err;
-    }
-
-  for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000;
-       ptr += 16)
-    if (grub_memcmp (ptr, "_SM_", 4) == 0
-       && grub_byte_checksum (ptr, *(ptr + 5)) == 0)
-      break;
-
-  if (ptr < (grub_uint8_t *) 0x100000)
-    {
-      grub_dprintf ("efiemu", "Registering SMBIOS\n");
-      if ((err = grub_efiemu_register_configuration_table (smbios, 0, 0, ptr)))
-       return err;
-    }
-
-  return GRUB_ERR_NONE;
-}
diff --git a/efiemu/loadcore.c b/efiemu/loadcore.c
deleted file mode 100644 (file)
index 4bf26ee..0000000
+++ /dev/null
@@ -1,370 +0,0 @@
-/* Load runtime image of EFIemu. Functions specific to 32/64-bit mode */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/efiemu/efiemu.h>
-#include <grub/cpu/efiemu.h>
-#include <grub/machine/efiemu.h>
-#include <grub/elf.h>
-
-/* ELF symbols and their values */
-static struct grub_efiemu_elf_sym *grub_efiemu_elfsyms = 0;
-static int grub_efiemu_nelfsyms = 0;
-
-/* Return the address of a section whose index is N.  */
-static grub_err_t
-grub_efiemu_get_section_addr (grub_efiemu_segment_t segs, unsigned n,
-                             int *handle, grub_off_t *off)
-{
-  grub_efiemu_segment_t seg;
-
-  for (seg = segs; seg; seg = seg->next)
-    if (seg->section == n)
-      {
-       *handle = seg->handle;
-       *off = seg->off;
-       return GRUB_ERR_NONE;
-      }
-
-  return grub_error (GRUB_ERR_BAD_OS, "section %d not found", n);
-}
-
-grub_err_t
-SUFFIX (grub_efiemu_loadcore_unload) (void)
-{
-  grub_free (grub_efiemu_elfsyms);
-  grub_efiemu_elfsyms = 0;
-  return GRUB_ERR_NONE;
-}
-
-/* Check if EHDR is a valid ELF header.  */
-int
-SUFFIX (grub_efiemu_check_header) (void *ehdr, grub_size_t size)
-{
-  Elf_Ehdr *e = ehdr;
-
-  /* Check the header size.  */
-  if (size < sizeof (Elf_Ehdr))
-    return 0;
-
-  /* Check the magic numbers.  */
-  if (!SUFFIX (grub_arch_efiemu_check_header) (ehdr)
-      || 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 0;
-
-  return 1;
-}
-
-/* Load all segments from memory specified by E.  */
-static grub_err_t
-grub_efiemu_load_segments (grub_efiemu_segment_t segs, const Elf_Ehdr *e)
-{
-  Elf_Shdr *s;
-  grub_efiemu_segment_t cur;
-
-  grub_dprintf ("efiemu", "loading segments\n");
-
-  for (cur=segs; cur; cur = cur->next)
-    {
-      s = (Elf_Shdr *)cur->srcptr;
-
-      if ((s->sh_flags & SHF_ALLOC) && s->sh_size)
-       {
-         void *addr;
-
-         addr = (grub_uint8_t *) grub_efiemu_mm_obtain_request (cur->handle)
-           + cur->off;
-
-         switch (s->sh_type)
-           {
-           case SHT_PROGBITS:
-             grub_memcpy (addr, (char *) e + s->sh_offset, s->sh_size);
-             break;
-           case SHT_NOBITS:
-             grub_memset (addr, 0, s->sh_size);
-             break;
-           }
-       }
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-/* Get a string at offset OFFSET from strtab */
-static char *
-grub_efiemu_get_string (unsigned offset, const Elf_Ehdr *e)
-{
-  unsigned i;
-  Elf_Shdr *s;
-
-  for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_STRTAB && offset < s->sh_size)
-      return (char *) e + s->sh_offset + offset;
-  return 0;
-}
-
-/* Request memory for segments and fill segments info */
-static grub_err_t
-grub_efiemu_init_segments (grub_efiemu_segment_t *segs, const Elf_Ehdr *e)
-{
-  unsigned i;
-  Elf_Shdr *s;
-
-  for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
-    {
-      if (s->sh_flags & SHF_ALLOC)
-       {
-         grub_efiemu_segment_t seg;
-         seg = (grub_efiemu_segment_t) grub_malloc (sizeof (*seg));
-         if (! seg)
-           return grub_errno;
-
-         if (s->sh_size)
-           {
-             seg->handle
-               = grub_efiemu_request_memalign
-               (s->sh_addralign, s->sh_size,
-                s->sh_flags & SHF_EXECINSTR ? GRUB_EFI_RUNTIME_SERVICES_CODE
-                : GRUB_EFI_RUNTIME_SERVICES_DATA);
-             if (seg->handle < 0)
-               return grub_errno;
-             seg->off = 0;
-           }
-
-         /*
-            .text-physical doesn't need to be relocated when switching to
-            virtual mode
-          */
-         if (!grub_strcmp (grub_efiemu_get_string (s->sh_name, e),
-                           ".text-physical"))
-           seg->ptv_rel_needed = 0;
-         else
-           seg->ptv_rel_needed = 1;
-         seg->size = s->sh_size;
-         seg->section = i;
-         seg->next = *segs;
-         seg->srcptr = s;
-         *segs = seg;
-       }
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-/* Count symbols and relocators and allocate/request memory for them */
-static grub_err_t
-grub_efiemu_count_symbols (const Elf_Ehdr *e)
-{
-  unsigned i;
-  Elf_Shdr *s;
-  int num = 0;
-
-  /* Symbols */
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_SYMTAB)
-      break;
-
-  if (i == e->e_shnum)
-    return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
-
-  grub_efiemu_nelfsyms = (unsigned) s->sh_size / (unsigned) s->sh_entsize;
-  grub_efiemu_elfsyms = (struct grub_efiemu_elf_sym *)
-    grub_malloc (sizeof (struct grub_efiemu_elf_sym) * grub_efiemu_nelfsyms);
-
-  /* Relocators */
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_REL || s->sh_type == SHT_RELA)
-      num += ((unsigned) s->sh_size) / ((unsigned) s->sh_entsize);
-
-  grub_efiemu_request_symbols (num);
-
-  return GRUB_ERR_NONE;
-}
-
-/* Fill grub_efiemu_elfsyms with symbol values */
-static grub_err_t
-grub_efiemu_resolve_symbols (grub_efiemu_segment_t segs, Elf_Ehdr *e)
-{
-  unsigned i;
-  Elf_Shdr *s;
-  Elf_Sym *sym;
-  const char *str;
-  Elf_Word size, entsize;
-
-  grub_dprintf ("efiemu", "resolving symbols\n");
-
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_SYMTAB)
-      break;
-
-  if (i == e->e_shnum)
-    return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
-
-  sym = (Elf_Sym *) ((char *) e + s->sh_offset);
-  size = s->sh_size;
-  entsize = s->sh_entsize;
-
-  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
-  str = (char *) e + s->sh_offset;
-
-  for (i = 0;
-       i < size / entsize;
-       i++, sym = (Elf_Sym *) ((char *) sym + entsize))
-    {
-      unsigned char type = ELF_ST_TYPE (sym->st_info);
-      unsigned char bind = ELF_ST_BIND (sym->st_info);
-      int handle;
-      grub_off_t off;
-      grub_err_t err;
-      const char *name = str + sym->st_name;
-      grub_efiemu_elfsyms[i].section = sym->st_shndx;
-      switch (type)
-       {
-       case STT_NOTYPE:
-         /* Resolve a global symbol.  */
-         if (sym->st_name != 0 && sym->st_shndx == 0)
-           {
-             if ((err = grub_efiemu_resolve_symbol (name, &handle, &off)))
-               return err;
-             grub_efiemu_elfsyms[i].handle = handle;
-             grub_efiemu_elfsyms[i].off = off;
-           }
-         else
-           sym->st_value = 0;
-         break;
-
-       case STT_OBJECT:
-         if ((err = grub_efiemu_get_section_addr
-              (segs, sym->st_shndx, &handle, &off)))
-           return err;
-
-         off += sym->st_value;
-         if (bind != STB_LOCAL)
-           if ((err = grub_efiemu_register_symbol (name, handle, off)))
-             return err;
-         grub_efiemu_elfsyms[i].handle = handle;
-         grub_efiemu_elfsyms[i].off = off;
-         break;
-
-       case STT_FUNC:
-         if ((err = grub_efiemu_get_section_addr
-              (segs, sym->st_shndx, &handle, &off)))
-           return err;
-
-         off += sym->st_value;
-         if (bind != STB_LOCAL)
-           if ((err = grub_efiemu_register_symbol (name, handle, off)))
-             return err;
-         grub_efiemu_elfsyms[i].handle = handle;
-         grub_efiemu_elfsyms[i].off = off;
-         break;
-
-       case STT_SECTION:
-         if ((err = grub_efiemu_get_section_addr
-              (segs, sym->st_shndx, &handle, &off)))
-           {
-             grub_efiemu_elfsyms[i].handle = 0;
-             grub_efiemu_elfsyms[i].off = 0;
-             grub_errno = GRUB_ERR_NONE;
-             break;
-           }
-
-         grub_efiemu_elfsyms[i].handle = handle;
-         grub_efiemu_elfsyms[i].off = off;
-         break;
-
-       case STT_FILE:
-         grub_efiemu_elfsyms[i].handle = 0;
-         grub_efiemu_elfsyms[i].off = 0;
-         break;
-
-       default:
-         return grub_error (GRUB_ERR_BAD_MODULE,
-                            "unknown symbol type `%d'", (int) type);
-       }
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-/* Load runtime to the memory and request memory for definitive location*/
-grub_err_t
-SUFFIX (grub_efiemu_loadcore_init) (void *core, grub_size_t core_size,
-                                   grub_efiemu_segment_t *segments)
-{
-  Elf_Ehdr *e = (Elf_Ehdr *) core;
-  grub_err_t err;
-
-  if (e->e_type != ET_REL)
-    return grub_error (GRUB_ERR_BAD_MODULE, "invalid ELF file type");
-
-  /* Make sure that every section is within the core.  */
-  if ((grub_size_t) core_size < e->e_shoff + e->e_shentsize * e->e_shnum)
-    return grub_error (GRUB_ERR_BAD_OS, "ELF sections outside core");
-
-  if ((err = grub_efiemu_init_segments (segments, core)))
-    return err;
-  if ((err = grub_efiemu_count_symbols (core)))
-    return err;
-
-  grub_efiemu_request_symbols (1);
-  return GRUB_ERR_NONE;
-}
-
-/* Load runtime definitively */
-grub_err_t
-SUFFIX (grub_efiemu_loadcore_load) (void *core,
-                                   grub_size_t core_size
-                                   __attribute__ ((unused)),
-                                   grub_efiemu_segment_t segments)
-{
-  grub_err_t err;
-  err = grub_efiemu_load_segments (segments, core);
-  if (err)
-    return err;
-
-  err = grub_efiemu_resolve_symbols (segments, core);
-  if (err)
-    return err;
-
-  err = SUFFIX (grub_arch_efiemu_relocate_symbols) (segments,
-                                                   grub_efiemu_elfsyms,
-                                                   core);
-  if (err)
-    return err;
-
-  return GRUB_ERR_NONE;
-}
diff --git a/efiemu/loadcore32.c b/efiemu/loadcore32.c
deleted file mode 100644 (file)
index c1e033b..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* This file contains definitions so that loadcore.c compiles for 32-bit */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define SUFFIX(x) x ## 32
-#define GRUB_TARGET_WORDSIZE 32
-#include "loadcore.c"
diff --git a/efiemu/loadcore64.c b/efiemu/loadcore64.c
deleted file mode 100644 (file)
index ce7284f..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* This file contains definitions so that loadcore.c compiles for 64-bit */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define SUFFIX(x) x ## 64
-#define GRUB_TARGET_WORDSIZE 64
-#include "loadcore.c"
diff --git a/efiemu/loadcore_common.c b/efiemu/loadcore_common.c
deleted file mode 100644 (file)
index a4db0ee..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/* Load runtime image of EFIemu. Functions common to 32/64-bit mode */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/file.h>
-#include <grub/err.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/efiemu/efiemu.h>
-#include <grub/cpu/efiemu.h>
-
-/* Are we in 32 or 64-bit mode?*/
-static grub_efiemu_mode_t grub_efiemu_mode = GRUB_EFIEMU_NOTLOADED;
-/* Runtime ELF file */
-static grub_ssize_t efiemu_core_size;
-static void *efiemu_core = 0;
-/* Linked list of segments */
-static grub_efiemu_segment_t efiemu_segments = 0;
-
-/* equivalent to sizeof (grub_efi_uintn_t) but taking the mode into account*/
-int
-grub_efiemu_sizeof_uintn_t (void)
-{
-  if (grub_efiemu_mode == GRUB_EFIEMU32)
-    return 4;
-  if (grub_efiemu_mode == GRUB_EFIEMU64)
-    return 8;
-  return 0;
-}
-
-/* Check the header and set mode */
-static grub_err_t
-grub_efiemu_check_header (void *ehdr, grub_size_t size,
-                         grub_efiemu_mode_t *mode)
-{
-  /* Check the magic numbers.  */
-  if ((*mode == GRUB_EFIEMU_NOTLOADED || *mode == GRUB_EFIEMU32)
-      && grub_efiemu_check_header32 (ehdr,size))
-    {
-      *mode = GRUB_EFIEMU32;
-      return GRUB_ERR_NONE;
-    }
-  if ((*mode == GRUB_EFIEMU_NOTLOADED || *mode == GRUB_EFIEMU64)
-      && grub_efiemu_check_header64 (ehdr,size))
-    {
-      *mode = GRUB_EFIEMU64;
-      return GRUB_ERR_NONE;
-    }
-  return grub_error (GRUB_ERR_BAD_OS, "invalid ELF magic");
-}
-
-/* Unload segments */
-static int
-grub_efiemu_unload_segs (grub_efiemu_segment_t seg)
-{
-  grub_efiemu_segment_t segn;
-  for (; seg; seg = segn)
-    {
-      segn = seg->next;
-      grub_efiemu_mm_return_request (seg->handle);
-      grub_free (seg);
-    }
-  return 1;
-}
-
-
-grub_err_t
-grub_efiemu_loadcore_unload(void)
-{
-  switch (grub_efiemu_mode)
-    {
-    case GRUB_EFIEMU32:
-      grub_efiemu_loadcore_unload32 ();
-      break;
-
-    case GRUB_EFIEMU64:
-      grub_efiemu_loadcore_unload64 ();
-      break;
-
-    default:
-      break;
-    }
-
-  grub_efiemu_mode = GRUB_EFIEMU_NOTLOADED;
-
-  grub_free (efiemu_core);
-  efiemu_core = 0;
-
-  grub_efiemu_unload_segs (efiemu_segments);
-  efiemu_segments = 0;
-
-  grub_efiemu_free_syms ();
-
-  return GRUB_ERR_NONE;
-}
-
-/* Load runtime file and do some initial preparations */
-grub_err_t
-grub_efiemu_loadcore_init (grub_file_t file)
-{
-  grub_err_t err;
-
-  efiemu_core_size = grub_file_size (file);
-  efiemu_core = 0;
-  efiemu_core = grub_malloc (efiemu_core_size);
-  if (! efiemu_core)
-    return grub_errno;
-
-  if (grub_file_read (file, efiemu_core, efiemu_core_size)
-      != (int) efiemu_core_size)
-    {
-      grub_free (efiemu_core);
-      efiemu_core = 0;
-      return grub_errno;
-    }
-
-  if (grub_efiemu_check_header (efiemu_core, efiemu_core_size,
-                               &grub_efiemu_mode))
-    {
-      grub_free (efiemu_core);
-      efiemu_core = 0;
-      return GRUB_ERR_BAD_MODULE;
-    }
-
-  switch (grub_efiemu_mode)
-    {
-    case GRUB_EFIEMU32:
-      if ((err = grub_efiemu_loadcore_init32 (efiemu_core, efiemu_core_size,
-                                             &efiemu_segments)))
-       {
-         grub_free (efiemu_core);
-         efiemu_core = 0;
-         grub_efiemu_mode = GRUB_EFIEMU_NOTLOADED;
-         return err;
-       }
-      break;
-
-    case GRUB_EFIEMU64:
-      if ((err = grub_efiemu_loadcore_init64 (efiemu_core, efiemu_core_size,
-                                             &efiemu_segments)))
-       {
-         grub_free (efiemu_core);
-         efiemu_core = 0;
-         grub_efiemu_mode = GRUB_EFIEMU_NOTLOADED;
-         return err;
-       }
-      break;
-
-    default:
-      return grub_error (GRUB_ERR_BAD_OS, "unknown EFI runtime");
-    }
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_efiemu_loadcore_load (void)
-{
-  grub_err_t err;
-  switch (grub_efiemu_mode)
-    {
-    case GRUB_EFIEMU32:
-      if ((err = grub_efiemu_loadcore_load32 (efiemu_core, efiemu_core_size,
-                                             efiemu_segments)))
-         grub_efiemu_loadcore_unload ();
-      return err;
-    case GRUB_EFIEMU64:
-      if ((err = grub_efiemu_loadcore_load64 (efiemu_core, efiemu_core_size,
-                                             efiemu_segments)))
-         grub_efiemu_loadcore_unload ();
-      return err;
-    default:
-      return grub_error (GRUB_ERR_BAD_OS, "unknown EFI runtime");
-    }
-}
diff --git a/efiemu/main.c b/efiemu/main.c
deleted file mode 100644 (file)
index b197a8b..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* This is an emulation of EFI runtime services.
-   This allows a more uniform boot on i386 machines.
-   As it emulates only runtime service it isn't able
-   to chainload EFI bootloader on non-EFI system. */
-
-
-#include <grub/file.h>
-#include <grub/err.h>
-#include <grub/normal.h>
-#include <grub/mm.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/efiemu/efiemu.h>
-#include <grub/machine/efiemu.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-/* System table. Two version depending on mode */
-grub_efi_system_table32_t *grub_efiemu_system_table32 = 0;
-grub_efi_system_table64_t *grub_efiemu_system_table64 = 0;
-/* Modules may need to execute some actions after memory allocation happens */
-static struct grub_efiemu_prepare_hook *efiemu_prepare_hooks = 0;
-/* Linked list of configuration tables */
-static struct grub_efiemu_configuration_table *efiemu_config_tables = 0;
-static int prepared = 0;
-
-/* Free all allocated space */
-grub_err_t
-grub_efiemu_unload (void)
-{
-  struct grub_efiemu_configuration_table *cur, *d;
-  struct grub_efiemu_prepare_hook *curhook, *d2;
-  grub_efiemu_loadcore_unload ();
-
-  grub_efiemu_mm_unload ();
-
-  for (cur = efiemu_config_tables; cur;)
-    {
-      d = cur->next;
-      if (cur->unload)
-       cur->unload (cur->data);
-      grub_free (cur);
-      cur = d;
-    }
-  efiemu_config_tables = 0;
-
-  for (curhook = efiemu_prepare_hooks; curhook;)
-    {
-      d2 = curhook->next;
-      if (curhook->unload)
-       curhook->unload (curhook->data);
-      grub_free (curhook);
-      curhook = d2;
-    }
-  efiemu_prepare_hooks = 0;
-
-  prepared = 0;
-
-  return GRUB_ERR_NONE;
-}
-
-/* Remove previously registered table from the list */
-grub_err_t
-grub_efiemu_unregister_configuration_table (grub_efi_guid_t guid)
-{
-  struct grub_efiemu_configuration_table *cur, *prev;
-
-  /* Special treating if head is to remove */
-  while (efiemu_config_tables
-        && !grub_memcmp (&(efiemu_config_tables->guid), &guid, sizeof (guid)))
-    {
-      if (efiemu_config_tables->unload)
-         efiemu_config_tables->unload (efiemu_config_tables->data);
-       cur = efiemu_config_tables->next;
-       grub_free (efiemu_config_tables);
-       efiemu_config_tables = cur;
-    }
-  if (!efiemu_config_tables)
-    return GRUB_ERR_NONE;
-
-  /* Remove from chain */
-  for (prev = efiemu_config_tables, cur = prev->next; cur;)
-    if (grub_memcmp (&(cur->guid), &guid, sizeof (guid)) == 0)
-      {
-       if (cur->unload)
-         cur->unload (cur->data);
-       prev->next = cur->next;
-       grub_free (cur);
-       cur = prev->next;
-      }
-    else
-      {
-       prev = cur;
-       cur = cur->next;
-      }
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_efiemu_register_prepare_hook (grub_err_t (*hook) (void *data),
-                                  void (*unload) (void *data),
-                                  void *data)
-{
-  struct grub_efiemu_prepare_hook *nhook;
-  if (! hook)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "you must supply the hook");
-  nhook = (struct grub_efiemu_prepare_hook *) grub_malloc (sizeof (*nhook));
-  if (! nhook)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't prepare hook");
-  nhook->hook = hook;
-  nhook->unload = unload;
-  nhook->data = data;
-  nhook->next = efiemu_prepare_hooks;
-  efiemu_prepare_hooks = nhook;
-  return GRUB_ERR_NONE;
-}
-
-/* Register a configuration table either supplying the address directly
-   or with a hook
-*/
-grub_err_t
-grub_efiemu_register_configuration_table (grub_efi_guid_t guid,
-                                         void * (*get_table) (void *data),
-                                         void (*unload) (void *data),
-                                         void *data)
-{
-  struct grub_efiemu_configuration_table *tbl;
-  grub_err_t err;
-
- if (! get_table && ! data)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "you must set at least get_table or data");
-  if ((err = grub_efiemu_unregister_configuration_table (guid)))
-    return err;
-
-  tbl = (struct grub_efiemu_configuration_table *) grub_malloc (sizeof (*tbl));
-  if (! tbl)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't register table");
-
-  tbl->guid = guid;
-  tbl->get_table = get_table;
-  tbl->unload = unload;
-  tbl->data = data;
-  tbl->next = efiemu_config_tables;
-  efiemu_config_tables = tbl;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_cmd_efiemu_unload (grub_command_t cmd __attribute__ ((unused)),
-                       int argc __attribute__ ((unused)),
-                       char *args[] __attribute__ ((unused)))
-{
-  return grub_efiemu_unload ();
-}
-
-static grub_err_t
-grub_cmd_efiemu_prepare (grub_command_t cmd __attribute__ ((unused)),
-                        int argc __attribute__ ((unused)),
-                        char *args[] __attribute__ ((unused)))
-{
-  return grub_efiemu_prepare ();
-}
-
-\f
-
-
-int
-grub_efiemu_exit_boot_services (grub_efi_uintn_t map_key
-                               __attribute__ ((unused)))
-{
-  /* Nothing to do here yet */
-  return 1;
-}
-
-int
-grub_efiemu_finish_boot_services (void)
-{
-  /* Nothing to do here yet */
-  return 1;
-}
-
-/* Load the runtime from the file FILENAME.  */
-static grub_err_t
-grub_efiemu_load_file (const char *filename)
-{
-  grub_file_t file;
-  grub_err_t err;
-
-  file = grub_file_open (filename);
-  if (! file)
-    return 0;
-
-  err = grub_efiemu_mm_init ();
-  if (err)
-    {
-      grub_file_close (file);
-      grub_efiemu_unload ();
-      return grub_error (grub_errno, "couldn't init memory management");
-    }
-
-  grub_dprintf ("efiemu", "mm initialized\n");
-
-  err = grub_efiemu_loadcore_init (file);
-  if (err)
-    {
-      grub_file_close (file);
-      grub_efiemu_unload ();
-      return err;
-    }
-
-  grub_file_close (file);
-
-  /* For configuration tables entry in system table. */
-  grub_efiemu_request_symbols (1);
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_efiemu_autocore (void)
-{
-  const char *prefix;
-  char *filename;
-  char *suffix;
-  grub_err_t err;
-
-  if (grub_efiemu_sizeof_uintn_t () != 0)
-    return GRUB_ERR_NONE;
-
-  prefix = grub_env_get ("prefix");
-
-  if (! prefix)
-    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
-                      "couldn't find efiemu core because prefix "
-                      "isn't set");
-
-  suffix = grub_efiemu_get_default_core_name ();
-
-  filename = grub_xasprintf ("%s/%s", prefix, suffix);
-  if (! filename)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                      "couldn't allocate temporary space");
-
-
-  err = grub_efiemu_load_file (filename);
-  grub_free (filename);
-  if (err)
-    return err;
-#ifndef GRUB_MACHINE_EMU
-  err = grub_machine_efiemu_init_tables ();
-  if (err)
-    return err;
-#endif
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_efiemu_prepare (void)
-{
-  grub_err_t err;
-
-  if (prepared)
-    return GRUB_ERR_NONE;
-
-  grub_dprintf ("efiemu", "Preparing %d-bit efiemu\n",
-               8 * grub_efiemu_sizeof_uintn_t ());
-
-  err = grub_efiemu_autocore ();
-
-  /* Create NVRAM. */
-  grub_efiemu_pnvram ();
-
-  prepared = 1;
-
-  if (grub_efiemu_sizeof_uintn_t () == 4)
-    return grub_efiemu_prepare32 (efiemu_prepare_hooks, efiemu_config_tables);
-  else
-    return grub_efiemu_prepare64 (efiemu_prepare_hooks, efiemu_config_tables);
-}
-
-
-static grub_err_t
-grub_cmd_efiemu_load (grub_command_t cmd __attribute__ ((unused)),
-                     int argc, char *args[])
-{
-  grub_err_t err;
-
-  grub_efiemu_unload ();
-
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "filename required");
-
-  err = grub_efiemu_load_file (args[0]);
-  if (err)
-    return err;
-#ifndef GRUB_MACHINE_EMU
-  err = grub_machine_efiemu_init_tables ();
-  if (err)
-    return err;
-#endif
-  return GRUB_ERR_NONE;
-}
-
-static grub_command_t cmd_loadcore, cmd_prepare, cmd_unload;
-
-GRUB_MOD_INIT(efiemu)
-{
-  cmd_loadcore = grub_register_command ("efiemu_loadcore",
-                                       grub_cmd_efiemu_load,
-                                       N_("FILE"),
-                                       N_("Load and initialize EFI emulator."));
-  cmd_prepare = grub_register_command ("efiemu_prepare",
-                                      grub_cmd_efiemu_prepare,
-                                      0,
-                                      N_("Finalize loading of EFI emulator."));
-  cmd_unload = grub_register_command ("efiemu_unload", grub_cmd_efiemu_unload,
-                                     0,
-                                     N_("Unload EFI emulator."));
-}
-
-GRUB_MOD_FINI(efiemu)
-{
-  grub_unregister_command (cmd_loadcore);
-  grub_unregister_command (cmd_prepare);
-  grub_unregister_command (cmd_unload);
-}
diff --git a/efiemu/mm.c b/efiemu/mm.c
deleted file mode 100644 (file)
index 4b29360..0000000
+++ /dev/null
@@ -1,633 +0,0 @@
-/* Memory management for efiemu */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-/*
-  To keep efiemu runtime contiguous this mm is special.
-  It uses deferred allocation.
-  In the first stage you may request memory with grub_efiemu_request_memalign
-  It will give you a handle with which in the second phase you can access your
-  memory with grub_efiemu_mm_obtain_request (handle). It's guaranteed that
-  subsequent calls with the same handle return the same result. You can't request any additional memory once you're in the second phase
-*/
-
-#include <grub/err.h>
-#include <grub/normal.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/machine/memory.h>
-#include <grub/efiemu/efiemu.h>
-
-struct grub_efiemu_memrequest
-{
-  struct grub_efiemu_memrequest *next;
-  grub_efi_memory_type_t type;
-  grub_size_t size;
-  grub_size_t align_overhead;
-  int handle;
-  void *val;
-};
-/* Linked list of requested memory. */
-static struct grub_efiemu_memrequest *memrequests = 0;
-/* Memory map. */
-static grub_efi_memory_descriptor_t *efiemu_mmap = 0;
-/* Pointer to allocated memory */
-static void *resident_memory = 0;
-/* Size of requested memory per type */
-static grub_size_t requested_memory[GRUB_EFI_MAX_MEMORY_TYPE];
-/* How many slots is allocated for memory_map and how many are already used */
-static int mmap_reserved_size = 0, mmap_num = 0;
-
-/* Add a memory region to map*/
-static grub_err_t
-grub_efiemu_add_to_mmap (grub_uint64_t start, grub_uint64_t size,
-                        grub_efi_memory_type_t type)
-{
-  grub_uint64_t page_start, npages;
-
-  /* Extend map if necessary*/
-  if (mmap_num >= mmap_reserved_size)
-    {
-      efiemu_mmap = (grub_efi_memory_descriptor_t *)
-       grub_realloc (efiemu_mmap, (++mmap_reserved_size)
-                     * sizeof (grub_efi_memory_descriptor_t));
-      if (!efiemu_mmap)
-       return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                          "not enough space for memory map");
-    }
-
-  /* Fill slot*/
-  page_start = start - (start % GRUB_EFIEMU_PAGESIZE);
-  npages = (size + (start % GRUB_EFIEMU_PAGESIZE) + GRUB_EFIEMU_PAGESIZE - 1)
-    / GRUB_EFIEMU_PAGESIZE;
-  efiemu_mmap[mmap_num].physical_start = page_start;
-  efiemu_mmap[mmap_num].virtual_start = page_start;
-  efiemu_mmap[mmap_num].num_pages = npages;
-  efiemu_mmap[mmap_num].type = type;
-  mmap_num++;
-
-  return GRUB_ERR_NONE;
-}
-
-/* Request a resident memory of type TYPE of size SIZE aligned at ALIGN
-   ALIGN must be a divisor of page size (if it's a divisor of 4096
-   it should be ok on all platforms)
- */
-int
-grub_efiemu_request_memalign (grub_size_t align, grub_size_t size,
-                             grub_efi_memory_type_t type)
-{
-  grub_size_t align_overhead;
-  struct grub_efiemu_memrequest *ret, *cur, *prev;
-  /* Check that the request is correct */
-  if (type >= GRUB_EFI_MAX_MEMORY_TYPE || type <= GRUB_EFI_LOADER_CODE)
-    return -2;
-
-  /* Add new size to requested size */
-  align_overhead = align - (requested_memory[type]%align);
-  if (align_overhead == align)
-    align_overhead = 0;
-  requested_memory[type] += align_overhead + size;
-
-  /* Remember the request */
-  ret = grub_zalloc (sizeof (*ret));
-  if (!ret)
-    return -1;
-  ret->type = type;
-  ret->size = size;
-  ret->align_overhead = align_overhead;
-  prev = 0;
-
-  /* Add request to the end of the chain.
-     It should be at the end because otherwise alignment isn't guaranteed */
-  for (cur = memrequests; cur; prev = cur, cur = cur->next);
-  if (prev)
-    {
-      ret->handle = prev->handle + 1;
-      prev->next = ret;
-    }
-  else
-    {
-      ret->handle = 1; /* Avoid 0 handle*/
-      memrequests = ret;
-    }
-  return ret->handle;
-}
-
-/* Really allocate the memory */
-static grub_err_t
-efiemu_alloc_requests (void)
-{
-  grub_size_t align_overhead = 0;
-  grub_uint8_t *curptr, *typestart;
-  struct grub_efiemu_memrequest *cur;
-  grub_size_t total_alloc = 0;
-  unsigned i;
-  /* Order of memory regions */
-  grub_efi_memory_type_t reqorder[] =
-    {
-      /* First come regions usable by OS*/
-      GRUB_EFI_LOADER_CODE,
-      GRUB_EFI_LOADER_DATA,
-      GRUB_EFI_BOOT_SERVICES_CODE,
-      GRUB_EFI_BOOT_SERVICES_DATA,
-      GRUB_EFI_CONVENTIONAL_MEMORY,
-      GRUB_EFI_ACPI_RECLAIM_MEMORY,
-
-      /* Then memory used by runtime */
-      /* This way all our regions are in a single block */
-      GRUB_EFI_RUNTIME_SERVICES_CODE,
-      GRUB_EFI_RUNTIME_SERVICES_DATA,
-      GRUB_EFI_ACPI_MEMORY_NVS,
-
-      /* And then unavailable memory types. This is more for a completeness.
-        You should double think before allocating memory of any of these types
-       */
-      GRUB_EFI_UNUSABLE_MEMORY,
-      GRUB_EFI_MEMORY_MAPPED_IO,
-      GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE,
-      GRUB_EFI_PAL_CODE
-    };
-
-  /* Compute total memory needed */
-  for (i = 0; i < sizeof (reqorder) / sizeof (reqorder[0]); i++)
-    {
-      align_overhead = GRUB_EFIEMU_PAGESIZE
-       - (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE);
-      if (align_overhead == GRUB_EFIEMU_PAGESIZE)
-       align_overhead = 0;
-      total_alloc += requested_memory[reqorder[i]] + align_overhead;
-    }
-
-  /* Allocate the whole memory in one block */
-  resident_memory = grub_memalign (GRUB_EFIEMU_PAGESIZE, total_alloc);
-  if (!resident_memory)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                      "couldn't allocate resident memory");
-
-  /* Split the memory into blocks by type */
-  curptr = resident_memory;
-  for (i = 0; i < sizeof (reqorder) / sizeof (reqorder[0]); i++)
-    {
-      if (!requested_memory[reqorder[i]])
-       continue;
-      typestart = curptr;
-
-      /* Write pointers to requests */
-      for (cur = memrequests; cur; cur = cur->next)
-       if (cur->type == reqorder[i])
-         {
-           curptr = ((grub_uint8_t *)curptr) + cur->align_overhead;
-           cur->val = curptr;
-           curptr = ((grub_uint8_t *)curptr) + cur->size;
-         }
-
-      /* Ensure that the regions are page-aligned */
-      align_overhead = GRUB_EFIEMU_PAGESIZE
-       - (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE);
-      if (align_overhead == GRUB_EFIEMU_PAGESIZE)
-       align_overhead = 0;
-      curptr = ((grub_uint8_t *)curptr) + align_overhead;
-
-      /* Add the region to memory map */
-      grub_efiemu_add_to_mmap (PTR_TO_UINT64 (typestart),
-                              curptr - typestart, reqorder[i]);
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-/* Get a pointer to requested memory from handle */
-void *
-grub_efiemu_mm_obtain_request (int handle)
-{
-  struct grub_efiemu_memrequest *cur;
-  for (cur = memrequests; cur; cur = cur->next)
-    if (cur->handle == handle)
-      return cur->val;
-  return 0;
-}
-
-/* Get type of requested memory by handle */
-grub_efi_memory_type_t
-grub_efiemu_mm_get_type (int handle)
-{
-  struct grub_efiemu_memrequest *cur;
-  for (cur = memrequests; cur; cur = cur->next)
-    if (cur->handle == handle)
-      return cur->type;
-  return 0;
-}
-
-/* Free a request */
-void
-grub_efiemu_mm_return_request (int handle)
-{
-  struct grub_efiemu_memrequest *cur, *prev;
-
-  /* Remove head if necessary */
-  while (memrequests && memrequests->handle == handle)
-    {
-      cur = memrequests->next;
-      grub_free (memrequests);
-      memrequests = cur;
-    }
-  if (!memrequests)
-    return;
-
-  /* Remove request from a middle of chain*/
-  for (prev = memrequests, cur = prev->next; cur;)
-    if (cur->handle == handle)
-      {
-       prev->next = cur->next;
-       grub_free (cur);
-       cur = prev->next;
-      }
-    else
-      {
-       prev = cur;
-       cur = prev->next;
-      }
-}
-
-/* Reserve space for memory map */
-static grub_err_t
-grub_efiemu_mmap_init (void)
-{
-  auto int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t, grub_uint64_t,
-                                        grub_uint32_t);
-  int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t addr __attribute__ ((unused)),
-                                   grub_uint64_t size __attribute__ ((unused)),
-                                   grub_uint32_t type __attribute__ ((unused)))
-    {
-      mmap_reserved_size++;
-      return 0;
-    }
-
-  // the place for memory used by efiemu itself
-  mmap_reserved_size = GRUB_EFI_MAX_MEMORY_TYPE + 1;
-
-#ifndef GRUB_MACHINE_EMU
-  grub_machine_mmap_iterate (bounds_hook);
-#endif
-
-  return GRUB_ERR_NONE;
-}
-
-/* This is a drop-in replacement of grub_efi_get_memory_map */
-/* Get the memory map as defined in the EFI spec. Return 1 if successful,
-   return 0 if partial, or return -1 if an error occurs.  */
-int
-grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size,
-                           grub_efi_memory_descriptor_t *memory_map,
-                           grub_efi_uintn_t *map_key,
-                           grub_efi_uintn_t *descriptor_size,
-                           grub_efi_uint32_t *descriptor_version)
-{
-  if (!efiemu_mmap)
-    {
-      grub_error (GRUB_ERR_INVALID_COMMAND,
-                 "you need to first launch efiemu_prepare");
-      return -1;
-    }
-
-  if (*memory_map_size < mmap_num * sizeof (grub_efi_memory_descriptor_t))
-    {
-      *memory_map_size = mmap_num * sizeof (grub_efi_memory_descriptor_t);
-      return 0;
-    }
-
-  *memory_map_size = mmap_num * sizeof (grub_efi_memory_descriptor_t);
-  grub_memcpy (memory_map, efiemu_mmap, *memory_map_size);
-  if (descriptor_size)
-    *descriptor_size = sizeof (grub_efi_memory_descriptor_t);
-  if (descriptor_version)
-    *descriptor_version = 1;
-  if (map_key)
-    *map_key = 0;
-
-  return 1;
-}
-
-/* Free everything */
-grub_err_t
-grub_efiemu_mm_unload (void)
-{
-  struct grub_efiemu_memrequest *cur, *d;
-  for (cur = memrequests; cur;)
-    {
-      d = cur->next;
-      grub_free (cur);
-      cur = d;
-    }
-  memrequests = 0;
-  grub_memset (&requested_memory, 0, sizeof (requested_memory));
-  grub_free (resident_memory);
-  resident_memory = 0;
-  grub_free (efiemu_mmap);
-  efiemu_mmap = 0;
-  mmap_reserved_size = mmap_num = 0;
-  return GRUB_ERR_NONE;
-}
-
-/* This function should be called before doing any requests */
-grub_err_t
-grub_efiemu_mm_init (void)
-{
-  grub_err_t err;
-
-  err = grub_efiemu_mm_unload ();
-  if (err)
-    return err;
-
-  grub_efiemu_mmap_init ();
-
-  return GRUB_ERR_NONE;
-}
-
-/* Copy host memory map */
-static grub_err_t
-grub_efiemu_mmap_fill (void)
-{
-  auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr,
-                                 grub_uint64_t size,
-                                 grub_uint32_t type)
-    {
-      switch (type)
-       {
-       case GRUB_MACHINE_MEMORY_AVAILABLE:
-         return grub_efiemu_add_to_mmap (addr, size,
-                                         GRUB_EFI_CONVENTIONAL_MEMORY);
-
-#ifdef GRUB_MACHINE_MEMORY_ACPI
-       case GRUB_MACHINE_MEMORY_ACPI:
-         return grub_efiemu_add_to_mmap (addr, size,
-                                         GRUB_EFI_ACPI_RECLAIM_MEMORY);
-#endif
-
-#ifdef GRUB_MACHINE_MEMORY_NVS
-       case GRUB_MACHINE_MEMORY_NVS:
-         return grub_efiemu_add_to_mmap (addr, size,
-                                         GRUB_EFI_ACPI_MEMORY_NVS);
-#endif
-
-       default:
-         grub_printf ("Unknown memory type %d. Marking as unusable\n", type);
-       case GRUB_MACHINE_MEMORY_RESERVED:
-         return grub_efiemu_add_to_mmap (addr, size,
-                                         GRUB_EFI_UNUSABLE_MEMORY);
-       }
-    }
-
-#ifndef GRUB_MACHINE_EMU
-  grub_machine_mmap_iterate (fill_hook);
-#endif
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
-                                                       grub_uint64_t,
-                                                       grub_uint32_t))
-{
-  unsigned i;
-
-  for (i = 0; i < (unsigned) mmap_num; i++)
-    switch (efiemu_mmap[i].type)
-      {
-      case GRUB_EFI_RUNTIME_SERVICES_CODE:
-       hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
-             GRUB_EFIEMU_MEMORY_CODE);
-       break;
-
-      case GRUB_EFI_RESERVED_MEMORY_TYPE:
-      case GRUB_EFI_RUNTIME_SERVICES_DATA:
-      case GRUB_EFI_UNUSABLE_MEMORY:
-      case GRUB_EFI_MEMORY_MAPPED_IO:
-      case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
-      case GRUB_EFI_PAL_CODE:
-      case GRUB_EFI_MAX_MEMORY_TYPE:
-       hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
-             GRUB_EFIEMU_MEMORY_RESERVED);
-       break;
-
-      case GRUB_EFI_LOADER_CODE:
-      case GRUB_EFI_LOADER_DATA:
-      case GRUB_EFI_BOOT_SERVICES_CODE:
-      case GRUB_EFI_BOOT_SERVICES_DATA:
-      case GRUB_EFI_CONVENTIONAL_MEMORY:
-       hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
-             GRUB_EFIEMU_MEMORY_AVAILABLE);
-       break;
-
-      case GRUB_EFI_ACPI_RECLAIM_MEMORY:
-       hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
-             GRUB_EFIEMU_MEMORY_ACPI);
-       break;
-
-      case GRUB_EFI_ACPI_MEMORY_NVS:
-       hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
-             GRUB_EFIEMU_MEMORY_NVS);
-       break;
-      }
-
-  return 0;
-}
-
-
-/* This function resolves overlapping regions and sorts the memory map
-   It uses scanline (sweeping) algorithm
- */
-static grub_err_t
-grub_efiemu_mmap_sort_and_uniq (void)
-{
-  /* If same page is used by multiple types it's resolved
-     according to priority
-     0 - free memory
-     1 - memory immediately usable after ExitBootServices
-     2 - memory usable after loading ACPI tables
-     3 - efiemu memory
-     4 - unusable memory
-  */
-  int priority[GRUB_EFI_MAX_MEMORY_TYPE] =
-    {
-      [GRUB_EFI_RESERVED_MEMORY_TYPE] = 4,
-      [GRUB_EFI_LOADER_CODE] = 1,
-      [GRUB_EFI_LOADER_DATA] = 1,
-      [GRUB_EFI_BOOT_SERVICES_CODE] = 1,
-      [GRUB_EFI_BOOT_SERVICES_DATA] = 1,
-      [GRUB_EFI_RUNTIME_SERVICES_CODE] = 3,
-      [GRUB_EFI_RUNTIME_SERVICES_DATA] = 3,
-      [GRUB_EFI_CONVENTIONAL_MEMORY] = 0,
-      [GRUB_EFI_UNUSABLE_MEMORY] = 4,
-      [GRUB_EFI_ACPI_RECLAIM_MEMORY] = 2,
-      [GRUB_EFI_ACPI_MEMORY_NVS] = 3,
-      [GRUB_EFI_MEMORY_MAPPED_IO] = 4,
-      [GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE] = 4,
-      [GRUB_EFI_PAL_CODE] = 4
-    };
-
-  int i, j, k, done;
-
-  /* Scanline events */
-  struct grub_efiemu_mmap_scan
-  {
-    /* At which memory address*/
-    grub_uint64_t pos;
-    /* 0 = region starts, 1 = region ends */
-    int type;
-    /* Which type of memory region */
-    grub_efi_memory_type_t memtype;
-  };
-  struct grub_efiemu_mmap_scan *scanline_events;
-  struct grub_efiemu_mmap_scan t;
-
-  /* Previous scanline event */
-  grub_uint64_t lastaddr;
-  int lasttype;
-  /* Current scanline event */
-  int curtype;
-  /* how many regions of given type overlap at current location */
-  int present[GRUB_EFI_MAX_MEMORY_TYPE];
-  /* Here is stored the resulting memory map*/
-  grub_efi_memory_descriptor_t *result;
-
-  /* Initialize variables*/
-  grub_memset (present, 0, sizeof (int) * GRUB_EFI_MAX_MEMORY_TYPE);
-  scanline_events = (struct grub_efiemu_mmap_scan *)
-    grub_malloc (sizeof (struct grub_efiemu_mmap_scan) * 2 * mmap_num);
-
-  /* Number of chunks can't increase more than by factor of 2 */
-  result = (grub_efi_memory_descriptor_t *)
-    grub_malloc (sizeof (grub_efi_memory_descriptor_t) * 2 * mmap_num);
-  if (!result || !scanline_events)
-    {
-      grub_free (result);
-      grub_free (scanline_events);
-      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                        "couldn't allocate space for new memory map");
-    }
-
-  /* Register scanline events */
-  for (i = 0; i < mmap_num; i++)
-    {
-      scanline_events[2 * i].pos = efiemu_mmap[i].physical_start;
-      scanline_events[2 * i].type = 0;
-      scanline_events[2 * i].memtype = efiemu_mmap[i].type;
-      scanline_events[2 * i + 1].pos = efiemu_mmap[i].physical_start
-       + efiemu_mmap[i].num_pages * GRUB_EFIEMU_PAGESIZE;
-      scanline_events[2 * i + 1].type = 1;
-      scanline_events[2 * i + 1].memtype = efiemu_mmap[i].type;
-    }
-
-  /* Primitive bubble sort. It has complexity O(n^2) but since we're
-     unlikely to have more than 100 chunks it's probably one of the
-     fastest for one purpose */
-  done = 1;
-  while (done)
-    {
-      done = 0;
-      for (i = 0; i < 2 * mmap_num - 1; i++)
-       if (scanline_events[i + 1].pos < scanline_events[i].pos)
-         {
-           t = scanline_events[i + 1];
-           scanline_events[i + 1] = scanline_events[i];
-           scanline_events[i] = t;
-           done = 1;
-         }
-    }
-
-  /* Pointer in resulting memory map */
-  j = 0;
-  lastaddr = scanline_events[0].pos;
-  lasttype = scanline_events[0].memtype;
-  for (i = 0; i < 2 * mmap_num; i++)
-    {
-      /* Process event */
-      if (scanline_events[i].type)
-       present[scanline_events[i].memtype]--;
-      else
-       present[scanline_events[i].memtype]++;
-
-      /* Determine current region type */
-      curtype = -1;
-      for (k = 0; k < GRUB_EFI_MAX_MEMORY_TYPE; k++)
-       if (present[k] && (curtype == -1 || priority[k] > priority[curtype]))
-         curtype = k;
-
-      /* Add memory region to resulting map if necessary */
-      if ((curtype == -1 || curtype != lasttype)
-         && lastaddr != scanline_events[i].pos
-         && lasttype != -1)
-       {
-         result[j].virtual_start = result[j].physical_start = lastaddr;
-         result[j].num_pages = (scanline_events[i].pos - lastaddr)
-           / GRUB_EFIEMU_PAGESIZE;
-         result[j].type = lasttype;
-
-         /* We set runtime attribute on pages we need to be mapped */
-         result[j].attribute
-           = (lasttype == GRUB_EFI_RUNTIME_SERVICES_CODE
-                  || lasttype == GRUB_EFI_RUNTIME_SERVICES_DATA)
-           ? GRUB_EFI_MEMORY_RUNTIME : 0;
-         grub_dprintf ("efiemu",
-                       "mmap entry: type %d start 0x%llx 0x%llx pages\n",
-                       result[j].type,
-                       result[j].physical_start, result[j].num_pages);
-         j++;
-       }
-
-      /* Update last values if necessary */
-      if (curtype == -1 || curtype != lasttype)
-       {
-         lasttype = curtype;
-         lastaddr = scanline_events[i].pos;
-       }
-    }
-
-  grub_free (scanline_events);
-
-  /* Shrink resulting memory map to really used size and replace efiemu_mmap
-     by new value */
-  grub_free (efiemu_mmap);
-  efiemu_mmap = grub_realloc (result, j * sizeof (*result));
-  return GRUB_ERR_NONE;
-}
-
-/* This function is called to switch from first to second phase */
-grub_err_t
-grub_efiemu_mm_do_alloc (void)
-{
-  grub_err_t err;
-
-  /* Preallocate mmap */
-  efiemu_mmap = (grub_efi_memory_descriptor_t *)
-    grub_malloc (mmap_reserved_size * sizeof (grub_efi_memory_descriptor_t));
-  if (!efiemu_mmap)
-    {
-      grub_efiemu_unload ();
-      return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't initialize mmap");
-    }
-
-  if ((err = efiemu_alloc_requests ()))
-    return err;
-  if ((err = grub_efiemu_mmap_fill ()))
-    return err;
-  return grub_efiemu_mmap_sort_and_uniq ();
-}
diff --git a/efiemu/pnvram.c b/efiemu/pnvram.c
deleted file mode 100644 (file)
index e58fce8..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/* Export pnvram and some variables for runtime */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/file.h>
-#include <grub/err.h>
-#include <grub/normal.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/charset.h>
-#include <grub/efiemu/efiemu.h>
-#include <grub/efiemu/runtime.h>
-#include <grub/extcmd.h>
-
-/* Place for final location of variables */
-static int nvram_handle = 0;
-static int nvramsize_handle = 0;
-static int high_monotonic_count_handle = 0;
-static int timezone_handle = 0;
-static int accuracy_handle = 0;
-static int daylight_handle = 0;
-
-static grub_size_t nvramsize;
-
-/* Parse signed value */
-static int
-grub_strtosl (const char *arg, char **end, int base)
-{
-  if (arg[0] == '-')
-    return -grub_strtoul (arg + 1, end, base);
-  return grub_strtoul (arg, end, base);
-}
-
-static inline int
-hextoval (char c)
-{
-  if (c >= '0' && c <= '9')
-    return c - '0';
-  if (c >= 'a' && c <= 'z')
-    return c - 'a' + 10;
-  if (c >= 'A' && c <= 'Z')
-    return c - 'A' + 10;
-  return 0;
-}
-
-static inline grub_err_t
-unescape (char *in, char *out, char *outmax, int *len)
-{
-  char *ptr, *dptr;
-  dptr = out;
-  for (ptr = in; *ptr && dptr < outmax; )
-    if (*ptr == '%' && ptr[1] && ptr[2])
-      {
-       *dptr = (hextoval (ptr[1]) << 4) | (hextoval (ptr[2]));
-       ptr += 3;
-       dptr++;
-      }
-    else
-      {
-       *dptr = *ptr;
-       ptr++;
-       dptr++;
-      }
-  if (dptr == outmax)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                      "too many NVRAM variables for reserved variable space."
-                      " Try increasing EfiEmu.pnvram.size");
-  *len = dptr - out;
-  return 0;
-}
-
-/* Export stuff for efiemu */
-static grub_err_t
-nvram_set (void * data __attribute__ ((unused)))
-{
-  const char *env;
-  /* Take definitive pointers */
-  char *nvram = grub_efiemu_mm_obtain_request (nvram_handle);
-  grub_uint32_t *nvramsize_def
-    = grub_efiemu_mm_obtain_request (nvramsize_handle);
-  grub_uint32_t *high_monotonic_count
-    = grub_efiemu_mm_obtain_request (high_monotonic_count_handle);
-  grub_int16_t *timezone
-    = grub_efiemu_mm_obtain_request (timezone_handle);
-  grub_uint8_t *daylight
-    = grub_efiemu_mm_obtain_request (daylight_handle);
-  grub_uint32_t *accuracy
-    = grub_efiemu_mm_obtain_request (accuracy_handle);
-  char *nvramptr;
-
-  auto int iterate_env (struct grub_env_var *var);
-  int iterate_env (struct grub_env_var *var)
-  {
-    char *guid, *attr, *name, *varname;
-    struct efi_variable *efivar;
-    int len = 0;
-    int i;
-    grub_uint64_t guidcomp;
-
-    if (grub_memcmp (var->name, "EfiEmu.pnvram.",
-                    sizeof ("EfiEmu.pnvram.") - 1) != 0)
-      return 0;
-
-    guid = var->name + sizeof ("EfiEmu.pnvram.") - 1;
-
-    attr = grub_strchr (guid, '.');
-    if (!attr)
-      return 0;
-    attr++;
-
-    name = grub_strchr (attr, '.');
-    if (!name)
-      return 0;
-    name++;
-
-    efivar = (struct efi_variable *) nvramptr;
-    if (nvramptr - nvram + sizeof (struct efi_variable) > nvramsize)
-      {
-       grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                   "too many NVRAM variables for reserved variable space."
-                   " Try increasing EfiEmu.pnvram.size");
-       return 1;
-      }
-
-    nvramptr += sizeof (struct efi_variable);
-
-    efivar->guid.data1 = grub_cpu_to_le32 (grub_strtoul (guid, &guid, 16));
-    if (*guid != '-')
-      return 0;
-    guid++;
-
-    efivar->guid.data2 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16));
-    if (*guid != '-')
-      return 0;
-    guid++;
-
-    efivar->guid.data3 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16));
-    if (*guid != '-')
-      return 0;
-    guid++;
-
-    guidcomp = grub_strtoull (guid, 0, 16);
-    for (i = 0; i < 8; i++)
-      efivar->guid.data4[i] = (guidcomp >> (56 - 8 * i)) & 0xff;
-
-    efivar->attributes = grub_strtoull (attr, 0, 16);
-
-    varname = grub_malloc (grub_strlen (name) + 1);
-    if (! varname)
-      return 1;
-
-    if (unescape (name, varname, varname + grub_strlen (name) + 1, &len))
-      return 1;
-
-    len = grub_utf8_to_utf16 ((grub_uint16_t *) nvramptr,
-                             (nvramsize - (nvramptr - nvram)) / 2,
-                             (grub_uint8_t *) varname, len, NULL);
-
-    if (len < 0)
-      {
-       grub_error (GRUB_ERR_BAD_ARGUMENT, "broken UTF-8 in variable name");
-       return 1;
-      }
-
-    nvramptr += 2 * len;
-    *((grub_uint16_t *) nvramptr) = 0;
-    nvramptr += 2;
-    efivar->namelen = 2 * len + 2;
-
-    if (unescape (var->value, nvramptr, nvram + nvramsize, &len))
-      {
-       efivar->namelen = 0;
-       return 1;
-      }
-
-    nvramptr += len;
-
-    efivar->size = len;
-
-    return 0;
-  }
-
-  /* Copy to definitive loaction */
-  grub_dprintf ("efiemu", "preparing pnvram\n");
-
-  env = grub_env_get ("EfiEmu.pnvram.high_monotonic_count");
-  *high_monotonic_count = env ? grub_strtoul (env, 0, 0) : 1;
-  env = grub_env_get ("EfiEmu.pnvram.timezone");
-  *timezone = env ? grub_strtosl (env, 0, 0) : GRUB_EFI_UNSPECIFIED_TIMEZONE;
-  env = grub_env_get ("EfiEmu.pnvram.accuracy");
-  *accuracy = env ? grub_strtoul (env, 0, 0) : 50000000;
-  env = grub_env_get ("EfiEmu.pnvram.daylight");
-  *daylight = env ? grub_strtoul (env, 0, 0) : 0;
-
-  nvramptr = nvram;
-  grub_memset (nvram, 0, nvramsize);
-  grub_env_iterate (iterate_env);
-  if (grub_errno)
-    return grub_errno;
-  *nvramsize_def = nvramsize;
-
-  /* Register symbols */
-  grub_efiemu_register_symbol ("efiemu_variables", nvram_handle, 0);
-  grub_efiemu_register_symbol ("efiemu_varsize", nvramsize_handle, 0);
-  grub_efiemu_register_symbol ("efiemu_high_monotonic_count",
-                              high_monotonic_count_handle, 0);
-  grub_efiemu_register_symbol ("efiemu_time_zone", timezone_handle, 0);
-  grub_efiemu_register_symbol ("efiemu_time_daylight", daylight_handle, 0);
-  grub_efiemu_register_symbol ("efiemu_time_accuracy",
-                              accuracy_handle, 0);
-
-  return GRUB_ERR_NONE;
-}
-
-static void
-nvram_unload (void * data __attribute__ ((unused)))
-{
-  grub_efiemu_mm_return_request (nvram_handle);
-  grub_efiemu_mm_return_request (nvramsize_handle);
-  grub_efiemu_mm_return_request (high_monotonic_count_handle);
-  grub_efiemu_mm_return_request (timezone_handle);
-  grub_efiemu_mm_return_request (accuracy_handle);
-  grub_efiemu_mm_return_request (daylight_handle);
-}
-
-grub_err_t
-grub_efiemu_pnvram (void)
-{
-  const char *size;
-  grub_err_t err;
-
-  nvramsize = 0;
-
-  size = grub_env_get ("EfiEmu.pnvram.size");
-  if (size)
-    nvramsize = grub_strtoul (size, 0, 0);
-
-  if (!nvramsize)
-    nvramsize = 2048;
-
-  err = grub_efiemu_register_prepare_hook (nvram_set, nvram_unload, 0);
-  if (err)
-    return err;
-
-  nvram_handle
-    = grub_efiemu_request_memalign (1, nvramsize,
-                                   GRUB_EFI_RUNTIME_SERVICES_DATA);
-  nvramsize_handle
-    = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
-                                   GRUB_EFI_RUNTIME_SERVICES_DATA);
-  high_monotonic_count_handle
-    = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
-                                   GRUB_EFI_RUNTIME_SERVICES_DATA);
-  timezone_handle
-    = grub_efiemu_request_memalign (1, sizeof (grub_uint16_t),
-                                   GRUB_EFI_RUNTIME_SERVICES_DATA);
-  daylight_handle
-    = grub_efiemu_request_memalign (1, sizeof (grub_uint8_t),
-                                   GRUB_EFI_RUNTIME_SERVICES_DATA);
-  accuracy_handle
-    = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
-                                   GRUB_EFI_RUNTIME_SERVICES_DATA);
-
-  return GRUB_ERR_NONE;
-}
diff --git a/efiemu/prepare.c b/efiemu/prepare.c
deleted file mode 100644 (file)
index 6202600..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/* Prepare efiemu. E.g. allocate memory, load the runtime
-   to appropriate place, etc */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/efiemu/efiemu.h>
-#include <grub/lib/crc.h>
-
-grub_err_t
-SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks,
-                             struct grub_efiemu_configuration_table
-                             *config_tables)
-{
-  grub_err_t err;
-  int conftable_handle;
-  struct grub_efiemu_configuration_table *cur;
-  struct grub_efiemu_prepare_hook *curhook;
-
-  int cntconftables = 0;
-  struct SUFFIX (grub_efiemu_configuration_table) *conftables = 0;
-  int i;
-  int handle;
-  grub_off_t off;
-
-  grub_dprintf ("efiemu", "Preparing EfiEmu\n");
-
-  /* Request space for the list of configuration tables */
-  for (cur = config_tables; cur; cur = cur->next)
-    cntconftables++;
-  conftable_handle
-    = grub_efiemu_request_memalign (GRUB_EFIEMU_PAGESIZE,
-                                   cntconftables * sizeof (*conftables),
-                                   GRUB_EFI_RUNTIME_SERVICES_DATA);
-
-  /* Switch from phase 1 (counting) to phase 2 (real job) */
-  grub_efiemu_alloc_syms ();
-  grub_efiemu_mm_do_alloc ();
-  grub_efiemu_write_sym_markers ();
-
-  grub_efiemu_system_table32 = 0;
-  grub_efiemu_system_table64 = 0;
-
-  /* Execute hooks */
-  for (curhook = prepare_hooks; curhook; curhook = curhook->next)
-    curhook->hook (curhook->data);
-
-  /* Move runtime to its due place */
-  err = grub_efiemu_loadcore_load ();
-  if (err)
-    {
-      grub_efiemu_unload ();
-      return err;
-    }
-
-  err = grub_efiemu_resolve_symbol ("efiemu_system_table", &handle, &off);
-  if (err)
-    {
-      grub_efiemu_unload ();
-      return err;
-    }
-
-  SUFFIX (grub_efiemu_system_table)
-    = (struct SUFFIX (grub_efi_system_table) *)
-    ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off);
-
-  /* Put pointer to the list of configuration tables in system table */
-  grub_efiemu_write_value
-    (&(SUFFIX (grub_efiemu_system_table)->configuration_table), 0,
-     conftable_handle, 0, 1,
-     sizeof (SUFFIX (grub_efiemu_system_table)->configuration_table));
-  SUFFIX(grub_efiemu_system_table)->num_table_entries = cntconftables;
-
-  /* Fill the list of configuration tables */
-  conftables = (struct SUFFIX (grub_efiemu_configuration_table) *)
-    grub_efiemu_mm_obtain_request (conftable_handle);
-  i = 0;
-  for (cur = config_tables; cur; cur = cur->next, i++)
-    {
-      grub_memcpy (&(conftables[i].vendor_guid), &(cur->guid),
-                      sizeof (cur->guid));
-      if (cur->get_table)
-       conftables[i].vendor_table
-         = PTR_TO_UINT64 (cur->get_table (cur->data));
-      else
-       conftables[i].vendor_table = PTR_TO_UINT64 (cur->data);
-    }
-
-  err = SUFFIX (grub_efiemu_crc) ();
-  if (err)
-    {
-      grub_efiemu_unload ();
-      return err;
-    }
-
-  grub_dprintf ("efiemu","system_table = %p, conftables = %p (%d entries)\n",
-               SUFFIX (grub_efiemu_system_table), conftables, cntconftables);
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-SUFFIX (grub_efiemu_crc) (void)
-{
-  grub_err_t err;
-  int handle;
-  grub_off_t off;
-  struct SUFFIX (grub_efiemu_runtime_services) *runtime_services;
-
-  /* compute CRC32 of runtime_services */
-  err = grub_efiemu_resolve_symbol ("efiemu_runtime_services",
-                                   &handle, &off);
-  if (err)
-    return err;
-
-  runtime_services = (struct SUFFIX (grub_efiemu_runtime_services) *)
-       ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off);
-  runtime_services->hdr.crc32 = 0;
-  runtime_services->hdr.crc32 = grub_getcrc32
-    (0, runtime_services, runtime_services->hdr.header_size);
-
-  err = grub_efiemu_resolve_symbol ("efiemu_system_table", &handle, &off);
-  if (err)
-    return err;
-
-  /* compute CRC32 of system table */
-  SUFFIX (grub_efiemu_system_table)->hdr.crc32 = 0;
-  SUFFIX (grub_efiemu_system_table)->hdr.crc32
-    = grub_getcrc32 (0, SUFFIX (grub_efiemu_system_table),
-                    SUFFIX (grub_efiemu_system_table)->hdr.header_size);
-
-  grub_dprintf ("efiemu","system_table = %p, runtime_services = %p\n",
-               SUFFIX (grub_efiemu_system_table), runtime_services);
-
-  return GRUB_ERR_NONE;
-}
diff --git a/efiemu/prepare32.c b/efiemu/prepare32.c
deleted file mode 100644 (file)
index fd6109e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* This file contains definitions so that prepare.c compiles for 32-bit */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define SUFFIX(x) x ## 32
-
-#include "prepare.c"
diff --git a/efiemu/prepare64.c b/efiemu/prepare64.c
deleted file mode 100644 (file)
index 811f558..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* This file contains definitions so that prepare.c compiles for 64-bit */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define SUFFIX(x) x ## 64
-
-#include "prepare.c"
diff --git a/efiemu/runtime/config.h b/efiemu/runtime/config.h
deleted file mode 100644 (file)
index 26fb2ff..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* This is a pseudo config.h so that types.h compiles nicely */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define GRUB_TYPES_CPU_HEADER  1
-
-#ifdef ELF32
-# define SIZEOF_VOID_P 4
-# define SIZEOF_LONG   4
-# define GRUB_TARGET_SIZEOF_VOID_P     4
-# define GRUB_TARGET_SIZEOF_LONG       4
-# define EFI_FUNC(x) x
-#else
-# define SIZEOF_VOID_P 8
-# define SIZEOF_LONG   8
-# define GRUB_TARGET_SIZEOF_VOID_P     8
-# define GRUB_TARGET_SIZEOF_LONG       8
-# define EFI_FUNC(x) x ## _real
-#endif
diff --git a/efiemu/runtime/efiemu.S b/efiemu/runtime/efiemu.S
deleted file mode 100644 (file)
index b502314..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-
-/*
- * x86_64 uses registry to pass parameters. Unfortunately, gcc and efi use
- * different call conversion, so we need to do some conversion.
- *
- * gcc:
- *   %rdi,  %rsi,  %rdx,  %rcx, %r8, %r9, 8(%rsp), 16(%rsp), ...
- *
- * efi:
- *   %rcx,  %rdx,  %r8,  %r9,  32(%rsp), 40(%rsp), 48(%rsp), ...
- *
- */
-
-        .file   "efiemu.S"
-       .text
-
-FUNCTION (efiemu_get_time)
-       push %rdi
-       push %rsi
-       mov %rcx, %rdi
-       mov %rdx, %rsi
-       call efiemu_get_time_real
-       pop %rsi
-       pop %rdi
-       ret
-
-FUNCTION (efiemu_set_time)
-       push %rdi
-       push %rsi
-       mov %rcx, %rdi
-       call efiemu_set_time_real
-       pop %rsi
-       pop %rdi
-       ret
-
-
-FUNCTION (efiemu_get_wakeup_time)
-       push %rdi
-       push %rsi
-       mov %rcx, %rdi
-       mov %rdx, %rsi
-       mov %r8, %rdx
-       call efiemu_get_wakeup_time_real
-       pop %rsi
-       pop %rdi
-       ret
-
-FUNCTION (efiemu_set_wakeup_time)
-       push %rdi
-       push %rsi
-       mov %rcx, %rdi
-       mov %rdx, %rsi
-       call efiemu_set_wakeup_time_real
-       pop %rsi
-       pop %rdi
-       ret
-
-FUNCTION (efiemu_get_variable)
-       push %rdi
-       push %rsi
-       mov %rcx, %rdi
-       mov %rdx, %rsi
-       mov %r8, %rdx
-       mov %r9, %rcx
-       mov 56(%rsp), %r8
-       call efiemu_get_variable_real
-       pop %rsi
-       pop %rdi
-       ret
-
-FUNCTION (efiemu_get_next_variable_name)
-       push %rdi
-       push %rsi
-       mov %rcx, %rdi
-       mov %rdx, %rsi
-       mov %r8, %rdx
-       call efiemu_get_next_variable_name_real
-       pop %rsi
-       pop %rdi
-       ret
-
-FUNCTION (efiemu_set_variable)
-       push %rdi
-       push %rsi
-       mov %rcx, %rdi
-       mov %rdx, %rsi
-       mov %r8, %rdx
-       mov %r9, %rcx
-       mov 56(%rsp), %r8
-       call efiemu_set_variable_real
-       pop %rsi
-       pop %rdi
-       ret
-
-FUNCTION (efiemu_get_next_high_monotonic_count)
-       push %rdi
-       push %rsi
-       mov %rcx, %rdi
-       call efiemu_get_next_high_monotonic_count_real
-       pop %rsi
-       pop %rdi
-       ret
-
-FUNCTION (efiemu_reset_system)
-       push %rdi
-       push %rsi
-       mov %rcx, %rdi
-       mov %rdx, %rsi
-       mov %r8, %rdx
-       mov %r9, %rcx
-       call efiemu_reset_system_real
-       pop %rsi
-       pop %rdi
-       ret
-
-       /* The following functions are always called in physical mode */
-       .section ".text-physical", "ax"
-
-FUNCTION (efiemu_set_virtual_address_map)
-       push %rdi
-       push %rsi
-       mov %rcx, %rdi
-       mov %rdx, %rsi
-       mov %r8, %rdx
-       mov %r9, %rcx
-       call efiemu_set_virtual_address_map_real
-       pop %rsi
-       pop %rdi
-       ret
-
-FUNCTION (efiemu_convert_pointer)
-       push %rdi
-       push %rsi
-       mov %rcx, %rdi
-       mov %rdx, %rsi
-       call efiemu_convert_pointer_real
-       pop %rsi
-       pop %rdi
-       ret
-
diff --git a/efiemu/runtime/efiemu.c b/efiemu/runtime/efiemu.c
deleted file mode 100644 (file)
index 7389341..0000000
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* This is an emulation of EFI runtime services.
-   This allows a more uniform boot on i386 machines.
-   As it emulates only runtime serviceit isn't able
-   to chainload EFI bootloader on non-EFI system (TODO) */
-
-#include <grub/symbol.h>
-#include <grub/types.h>
-#include <grub/efi/api.h>
-#include <grub/efiemu/runtime.h>
-
-grub_efi_status_t
-efiemu_get_time (grub_efi_time_t *time,
-                grub_efi_time_capabilities_t *capabilities);
-grub_efi_status_t
-efiemu_set_time (grub_efi_time_t *time);
-
-grub_efi_status_t
-efiemu_get_wakeup_time (grub_efi_boolean_t *enabled,
-                       grub_efi_boolean_t *pending,
-                       grub_efi_time_t *time);
-grub_efi_status_t
-efiemu_set_wakeup_time (grub_efi_boolean_t enabled,
-                       grub_efi_time_t *time);
-
-#ifdef APPLE_CC
-#define PHYSICAL_ATTRIBUTE __attribute__ ((section("_text-physical, _text-physical")));
-#else
-#define PHYSICAL_ATTRIBUTE __attribute__ ((section(".text-physical")));
-#endif
-
-grub_efi_status_t
-efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
-                               grub_efi_uintn_t descriptor_size,
-                               grub_efi_uint32_t descriptor_version,
-                               grub_efi_memory_descriptor_t *virtual_map)
-  PHYSICAL_ATTRIBUTE;
-
-grub_efi_status_t
-efiemu_convert_pointer (grub_efi_uintn_t debug_disposition,
-                       void **address)
-  PHYSICAL_ATTRIBUTE;
-
-grub_efi_status_t
-efiemu_get_variable (grub_efi_char16_t *variable_name,
-                    grub_efi_guid_t *vendor_guid,
-                    grub_efi_uint32_t *attributes,
-                    grub_efi_uintn_t *data_size,
-                    void *data);
-
-grub_efi_status_t
-efiemu_get_next_variable_name (grub_efi_uintn_t *variable_name_size,
-                              grub_efi_char16_t *variable_name,
-                              grub_efi_guid_t *vendor_guid);
-
-grub_efi_status_t
-efiemu_set_variable (grub_efi_char16_t *variable_name,
-                    grub_efi_guid_t *vendor_guid,
-                    grub_efi_uint32_t attributes,
-                    grub_efi_uintn_t data_size,
-                    void *data);
-grub_efi_status_t
-efiemu_get_next_high_monotonic_count (grub_efi_uint32_t *high_count);
-void
-efiemu_reset_system (grub_efi_reset_type_t reset_type,
-                    grub_efi_status_t reset_status,
-                    grub_efi_uintn_t data_size,
-                    grub_efi_char16_t *reset_data);
-
-grub_efi_status_t
-EFI_FUNC (efiemu_set_virtual_address_map) (grub_efi_uintn_t,
-                                             grub_efi_uintn_t,
-                                             grub_efi_uint32_t,
-                                             grub_efi_memory_descriptor_t *)
-     PHYSICAL_ATTRIBUTE;
-grub_efi_status_t
-EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition,
-                                     void **address)
-     PHYSICAL_ATTRIBUTE;
-static grub_uint32_t
-efiemu_getcrc32 (grub_uint32_t crc, void *buf, int size)
-     PHYSICAL_ATTRIBUTE;
-static void
-init_crc32_table (void)
-     PHYSICAL_ATTRIBUTE;
-static grub_uint32_t
-reflect (grub_uint32_t ref, int len)
-     PHYSICAL_ATTRIBUTE;
-
-/*
-  The log. It's used when examining memory dump
-*/
-static grub_uint8_t loge[1000] = "EFIEMULOG";
-static int logn = 9;
-#define LOG(x)   { if (logn<900) loge[logn++]=x; }
-
-/* Interface with grub */
-extern grub_uint8_t efiemu_ptv_relocated;
-struct grub_efi_runtime_services efiemu_runtime_services;
-struct grub_efi_system_table efiemu_system_table;
-extern struct grub_efiemu_ptv_rel efiemu_ptv_relloc[];
-extern grub_uint8_t efiemu_variables[];
-extern grub_uint32_t efiemu_varsize;
-extern grub_uint32_t efiemu_high_monotonic_count;
-extern grub_int16_t efiemu_time_zone;
-extern grub_uint8_t efiemu_time_daylight;
-extern grub_uint32_t efiemu_time_accuracy;
-
-/* Some standard functions because we need to be standalone */
-static void
-efiemu_memcpy (void *to, void *from, int count)
-{
-  int i;
-  for (i = 0; i < count; i++)
-    ((grub_uint8_t *) to)[i] = ((grub_uint8_t *) from)[i];
-}
-
-static int
-efiemu_str16equal (grub_uint16_t *a, grub_uint16_t *b)
-{
-  grub_uint16_t *ptr1, *ptr2;
-  for (ptr1=a,ptr2=b; *ptr1 && *ptr2 == *ptr1; ptr1++, ptr2++);
-  return *ptr2 == *ptr1;
-}
-
-static grub_size_t
-efiemu_str16len (grub_uint16_t *a)
-{
-  grub_uint16_t *ptr1;
-  for (ptr1 = a; *ptr1; ptr1++);
-  return ptr1 - a;
-}
-
-static int
-efiemu_memequal (void *a, void *b, grub_size_t n)
-{
-  grub_uint8_t *ptr1, *ptr2;
-  for (ptr1 = (grub_uint8_t *) a, ptr2 = (grub_uint8_t *)b;
-       ptr1 < (grub_uint8_t *)a + n && *ptr2 == *ptr1; ptr1++, ptr2++);
-  return ptr1 == a + n;
-}
-
-static void
-efiemu_memset (grub_uint8_t *a, grub_uint8_t b, grub_size_t n)
-{
-  grub_uint8_t *ptr1;
-  for (ptr1=a; ptr1 < a + n; ptr1++)
-    *ptr1 = b;
-}
-
-static inline void
-write_cmos (grub_uint8_t addr, grub_uint8_t val)
-{
-  __asm__ __volatile__ ("outb %%al,$0x70\n"
-                       "mov %%cl, %%al\n"
-                       "outb %%al,$0x71": :"a" (addr), "c" (val));
-}
-
-static inline grub_uint8_t
-read_cmos (grub_uint8_t addr)
-{
-  grub_uint8_t ret;
-  __asm__ __volatile__ ("outb %%al, $0x70\n"
-                       "inb $0x71, %%al": "=a"(ret) :"a" (addr));
-  return ret;
-}
-
-/* Needed by some gcc versions */
-int __stack_chk_fail ()
-{
-  return 0;
-}
-
-/* The function that implement runtime services as specified in
-   EFI specification */
-static inline grub_uint8_t
-bcd_to_hex (grub_uint8_t in)
-{
-  return 10 * ((in & 0xf0) >> 4) + (in & 0x0f);
-}
-
-grub_efi_status_t
-EFI_FUNC (efiemu_get_time) (grub_efi_time_t *time,
-                              grub_efi_time_capabilities_t *capabilities)
-{
-  LOG ('a');
-  grub_uint8_t state;
-  state = read_cmos (0xb);
-  if (!(state & (1 << 2)))
-    {
-      time->year = 2000 + bcd_to_hex (read_cmos (0x9));
-      time->month = bcd_to_hex (read_cmos (0x8));
-      time->day = bcd_to_hex (read_cmos (0x7));
-      time->hour = bcd_to_hex (read_cmos (0x4));
-      if (time->hour >= 81)
-       time->hour -= 80 - 12;
-      if (time->hour == 24)
-       time->hour = 0;
-      time->minute = bcd_to_hex (read_cmos (0x2));
-      time->second = bcd_to_hex (read_cmos (0x0));
-    }
-  else
-    {
-      time->year = 2000 + read_cmos (0x9);
-      time->month = read_cmos (0x8);
-      time->day = read_cmos (0x7);
-      time->hour = read_cmos (0x4);
-      if (time->hour >= 0x81)
-       time->hour -= 0x80 - 12;
-      if (time->hour == 24)
-       time->hour = 0;
-      time->minute = read_cmos (0x2);
-      time->second = read_cmos (0x0);
-    }
-  time->nanosecond = 0;
-  time->pad1 = 0;
-  time->pad2 = 0;
-  time->time_zone = efiemu_time_zone;
-  time->daylight = efiemu_time_daylight;
-  capabilities->resolution = 1;
-  capabilities->accuracy = efiemu_time_accuracy;
-  capabilities->sets_to_zero = 0;
-  return GRUB_EFI_SUCCESS;
-}
-
-grub_efi_status_t
-EFI_FUNC (efiemu_set_time) (grub_efi_time_t *time)
-{
-  LOG ('b');
-  grub_uint8_t state;
-  state = read_cmos (0xb);
-  write_cmos (0xb, state | 0x6);
-  write_cmos (0x9, time->year - 2000);
-  write_cmos (0x8, time->month);
-  write_cmos (0x7, time->day);
-  write_cmos (0x4, time->hour);
-  write_cmos (0x2, time->minute);
-  write_cmos (0x0, time->second);
-  efiemu_time_zone = time->time_zone;
-  efiemu_time_daylight = time->daylight;
-  return GRUB_EFI_SUCCESS;
-}
-
-/* Following 2 functions are vendor specific. So announce it as unsupported */
-grub_efi_status_t
-EFI_FUNC (efiemu_get_wakeup_time) (grub_efi_boolean_t *enabled,
-                                     grub_efi_boolean_t *pending,
-                                     grub_efi_time_t *time)
-{
-  LOG ('c');
-  return GRUB_EFI_UNSUPPORTED;
-}
-
-grub_efi_status_t
-EFI_FUNC (efiemu_set_wakeup_time) (grub_efi_boolean_t enabled,
-                                     grub_efi_time_t *time)
-{
-  LOG ('d');
-  return GRUB_EFI_UNSUPPORTED;
-}
-
-static grub_uint32_t crc32_table [256];
-
-static grub_uint32_t
-reflect (grub_uint32_t ref, int len)
-{
-  grub_uint32_t result = 0;
-  int i;
-
-  for (i = 1; i <= len; i++)
-    {
-      if (ref & 1)
-       result |= 1 << (len - i);
-      ref >>= 1;
-    }
-
-  return result;
-}
-
-static void
-init_crc32_table (void)
-{
-  grub_uint32_t polynomial = 0x04c11db7;
-  int i, j;
-
-  for(i = 0; i < 256; i++)
-    {
-      crc32_table[i] = reflect(i, 8) << 24;
-      for (j = 0; j < 8; j++)
-        crc32_table[i] = (crc32_table[i] << 1) ^
-            (crc32_table[i] & (1 << 31) ? polynomial : 0);
-      crc32_table[i] = reflect(crc32_table[i], 32);
-    }
-}
-
-static grub_uint32_t
-efiemu_getcrc32 (grub_uint32_t crc, void *buf, int size)
-{
-  int i;
-  grub_uint8_t *data = buf;
-
-  if (! crc32_table[1])
-    init_crc32_table ();
-
-  crc^= 0xffffffff;
-
-  for (i = 0; i < size; i++)
-    {
-      crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ *data];
-      data++;
-    }
-
-  return crc ^ 0xffffffff;
-}
-
-
-grub_efi_status_t EFI_FUNC
-(efiemu_set_virtual_address_map) (grub_efi_uintn_t memory_map_size,
-                                 grub_efi_uintn_t descriptor_size,
-                                 grub_efi_uint32_t descriptor_version,
-                                 grub_efi_memory_descriptor_t *virtual_map)
-{
-  struct grub_efiemu_ptv_rel *cur_relloc;
-
-  LOG ('e');
-
-  /* Ensure that we are called only once */
-  if (efiemu_ptv_relocated)
-    return GRUB_EFI_UNSUPPORTED;
-  efiemu_ptv_relocated = 1;
-
-  /* Correct addresses using information supplied by grub */
-  for (cur_relloc = efiemu_ptv_relloc; cur_relloc->size;cur_relloc++)
-    {
-      grub_int64_t corr = 0;
-      grub_efi_memory_descriptor_t *descptr;
-
-      /* Compute correction */
-      for (descptr = virtual_map;
-          ((grub_uint8_t *) descptr - (grub_uint8_t *) virtual_map)
-            < memory_map_size;
-          descptr = (grub_efi_memory_descriptor_t *)
-            ((grub_uint8_t *) descptr + descriptor_size))
-       {
-         if (descptr->type == cur_relloc->plustype)
-           corr += descptr->virtual_start - descptr->physical_start;
-         if (descptr->type == cur_relloc->minustype)
-           corr -= descptr->virtual_start - descptr->physical_start;
-       }
-
-      /* Apply correction */
-      switch (cur_relloc->size)
-       {
-       case 8:
-         *((grub_uint64_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
-         break;
-       case 4:
-         *((grub_uint32_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
-         break;
-       case 2:
-         *((grub_uint16_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
-         break;
-       case 1:
-         *((grub_uint8_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
-         break;
-       }
-    }
-
-  /* Recompute crc32 of system table and runtime services */
-  efiemu_system_table.hdr.crc32 = 0;
-  efiemu_system_table.hdr.crc32 = efiemu_getcrc32
-    (0, &efiemu_system_table, sizeof (efiemu_system_table));
-
-  efiemu_runtime_services.hdr.crc32 = 0;
-  efiemu_runtime_services.hdr.crc32 = efiemu_getcrc32
-    (0, &efiemu_runtime_services, sizeof (efiemu_runtime_services));
-
-  return GRUB_EFI_SUCCESS;
-}
-
-/* since efiemu_set_virtual_address_map corrects all the pointers
-   we don't need efiemu_convert_pointer */
-grub_efi_status_t
-EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition,
-                                     void **address)
-{
-  LOG ('f');
-  return GRUB_EFI_UNSUPPORTED;
-}
-
-/* Next comes variable services. Because we have no vendor-independent
-   way to store these variables we have no non-volatility */
-
-/* Find variable by name and GUID. */
-static struct efi_variable *
-find_variable (grub_efi_guid_t *vendor_guid,
-              grub_efi_char16_t *variable_name)
-{
-  grub_uint8_t *ptr;
-  struct efi_variable *efivar;
-
-  for (ptr = efiemu_variables; ptr < efiemu_variables + efiemu_varsize; )
-    {
-      efivar = (struct efi_variable *) ptr;
-      if (!efivar->namelen)
-       return 0;
-      if (efiemu_str16equal((grub_efi_char16_t *)(efivar + 1), variable_name)
-         && efiemu_memequal (&(efivar->guid), vendor_guid,
-                             sizeof (efivar->guid)))
-       return efivar;
-      ptr += efivar->namelen + efivar->size + sizeof (*efivar);
-    }
-  return 0;
-}
-
-grub_efi_status_t
-EFI_FUNC (efiemu_get_variable) (grub_efi_char16_t *variable_name,
-                                  grub_efi_guid_t *vendor_guid,
-                                  grub_efi_uint32_t *attributes,
-                                  grub_efi_uintn_t *data_size,
-                                  void *data)
-{
-  struct efi_variable *efivar;
-  LOG ('g');
-  efivar = find_variable (vendor_guid, variable_name);
-  if (!efivar)
-    return GRUB_EFI_NOT_FOUND;
-  if (*data_size < efivar->size)
-    {
-      *data_size = efivar->size;
-      return GRUB_EFI_BUFFER_TOO_SMALL;
-    }
-  *data_size = efivar->size;
-  efiemu_memcpy (data, (grub_uint8_t *)(efivar + 1) + efivar->namelen,
-                efivar->size);
-  *attributes = efivar->attributes;
-
-  return GRUB_EFI_SUCCESS;
-}
-
-grub_efi_status_t EFI_FUNC
-(efiemu_get_next_variable_name) (grub_efi_uintn_t *variable_name_size,
-                                grub_efi_char16_t *variable_name,
-                                grub_efi_guid_t *vendor_guid)
-{
-  struct efi_variable *efivar;
-  LOG ('l');
-
-  if (!variable_name_size || !variable_name || !vendor_guid)
-    return GRUB_EFI_INVALID_PARAMETER;
-  if (variable_name[0])
-    {
-      efivar = find_variable (vendor_guid, variable_name);
-      if (!efivar)
-       return GRUB_EFI_NOT_FOUND;
-      efivar = (struct efi_variable *)((grub_uint8_t *)efivar
-                                      + efivar->namelen
-                                      + efivar->size + sizeof (*efivar));
-    }
-  else
-    efivar = (struct efi_variable *) (efiemu_variables);
-
-  LOG ('m');
-  if ((grub_uint8_t *)efivar >= efiemu_variables + efiemu_varsize
-      || !efivar->namelen)
-    return GRUB_EFI_NOT_FOUND;
-  if (*variable_name_size < efivar->namelen)
-    {
-      *variable_name_size = efivar->namelen;
-      return GRUB_EFI_BUFFER_TOO_SMALL;
-    }
-
-  efiemu_memcpy (variable_name, efivar + 1, efivar->namelen);
-  efiemu_memcpy (vendor_guid, &(efivar->guid),
-                sizeof (efivar->guid));
-
-  LOG('h');
-  return GRUB_EFI_SUCCESS;
-}
-
-grub_efi_status_t
-EFI_FUNC (efiemu_set_variable) (grub_efi_char16_t *variable_name,
-                                  grub_efi_guid_t *vendor_guid,
-                                  grub_efi_uint32_t attributes,
-                                  grub_efi_uintn_t data_size,
-                                  void *data)
-{
-  struct efi_variable *efivar;
-  grub_uint8_t *ptr;
-  LOG('i');
-  if (!variable_name[0])
-    return GRUB_EFI_INVALID_PARAMETER;
-  efivar = find_variable (vendor_guid, variable_name);
-
-  /* Delete variable if any */
-  if (efivar)
-    {
-      efiemu_memcpy (efivar, (grub_uint8_t *)(efivar + 1)
-                    + efivar->namelen + efivar->size,
-                    (efiemu_variables + efiemu_varsize)
-                    - ((grub_uint8_t *)(efivar + 1)
-                       + efivar->namelen + efivar->size));
-      efiemu_memset (efiemu_variables + efiemu_varsize
-                    - (sizeof (*efivar) + efivar->namelen + efivar->size),
-                    0, (sizeof (*efivar) + efivar->namelen + efivar->size));
-    }
-
-  if (!data_size)
-    return GRUB_EFI_SUCCESS;
-
-  for (ptr = efiemu_variables; ptr < efiemu_variables + efiemu_varsize; )
-    {
-      efivar = (struct efi_variable *) ptr;
-      ptr += efivar->namelen + efivar->size + sizeof (*efivar);
-      if (!efivar->namelen)
-       break;
-    }
-  if ((grub_uint8_t *)(efivar + 1) + data_size
-      + 2 * (efiemu_str16len (variable_name) + 1)
-      >= efiemu_variables + efiemu_varsize)
-    return GRUB_EFI_OUT_OF_RESOURCES;
-
-  efiemu_memcpy (&(efivar->guid), vendor_guid, sizeof (efivar->guid));
-  efivar->namelen = 2 * (efiemu_str16len (variable_name) + 1);
-  efivar->size = data_size;
-  efivar->attributes = attributes;
-  efiemu_memcpy (efivar + 1, variable_name,
-                2 * (efiemu_str16len (variable_name) + 1));
-  efiemu_memcpy ((grub_uint8_t *)(efivar + 1)
-                + 2 * (efiemu_str16len (variable_name) + 1),
-                data, data_size);
-
-  return GRUB_EFI_SUCCESS;
-}
-
-grub_efi_status_t EFI_FUNC
-(efiemu_get_next_high_monotonic_count) (grub_efi_uint32_t *high_count)
-{
-  LOG ('j');
-  if (!high_count)
-    return GRUB_EFI_INVALID_PARAMETER;
-  *high_count = ++efiemu_high_monotonic_count;
-  return GRUB_EFI_SUCCESS;
-}
-
-/* To implement it with APM we need to go to real mode. It's too much hassle
-   Besides EFI specification says that this function shouldn't be used
-   on systems supporting ACPI
- */
-void
-EFI_FUNC (efiemu_reset_system) (grub_efi_reset_type_t reset_type,
-                                  grub_efi_status_t reset_status,
-                                  grub_efi_uintn_t data_size,
-                                  grub_efi_char16_t *reset_data)
-{
-  LOG ('k');
-}
-
-struct grub_efi_runtime_services efiemu_runtime_services =
-{
-  .hdr =
-  {
-    .signature = GRUB_EFIEMU_RUNTIME_SERVICES_SIGNATURE,
-    .revision = 0x0001000a,
-    .header_size = sizeof (struct grub_efi_runtime_services),
-    .crc32 = 0, /* filled later*/
-    .reserved = 0
-  },
-  .get_time = efiemu_get_time,
-  .set_time = efiemu_set_time,
-  .get_wakeup_time = efiemu_get_wakeup_time,
-  .set_wakeup_time = efiemu_set_wakeup_time,
-
-  .set_virtual_address_map = efiemu_set_virtual_address_map,
-  .convert_pointer = efiemu_convert_pointer,
-
-  .get_variable = efiemu_get_variable,
-  .get_next_variable_name = efiemu_get_next_variable_name,
-  .set_variable = efiemu_set_variable,
-  .get_next_high_monotonic_count = efiemu_get_next_high_monotonic_count,
-
-  .reset_system = efiemu_reset_system
-};
-
-
-static grub_uint16_t efiemu_vendor[] =
-  {'G', 'R', 'U', 'B', ' ', 'E', 'F', 'I', ' ',
-   'R', 'U', 'N', 'T', 'I', 'M', 'E', 0};
-
-struct grub_efi_system_table efiemu_system_table =
-{
-  .hdr =
-  {
-    .signature = GRUB_EFIEMU_SYSTEM_TABLE_SIGNATURE,
-    .revision = 0x0001000a,
-    .header_size = sizeof (struct grub_efi_system_table),
-    .crc32 = 0, /* filled later*/
-    .reserved = 0
-  },
-  .firmware_vendor = efiemu_vendor,
-  .firmware_revision = 0x0001000a,
-  .console_in_handler = 0,
-  .con_in = 0,
-  .console_out_handler = 0,
-  .con_out = 0,
-  .standard_error_handle = 0,
-  .std_err = 0,
-  .runtime_services = &efiemu_runtime_services,
-  .boot_services = 0,
-  .num_table_entries = 0,
-  .configuration_table = 0
-};
-
diff --git a/efiemu/runtime/efiemu.sh b/efiemu/runtime/efiemu.sh
deleted file mode 100644 (file)
index 5a492dc..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-gcc -c -m32 -DELF32 -o efiemu32.o ./efiemu.c -Wall -Werror -nostdlib -O2 -I. -I../../include
-gcc -c -m64 -DELF64 -o efiemu64_c.o ./efiemu.c -Wall -Werror -mcmodel=large -O2 -I. -I../../include
-gcc -c -m64 -DELF64 -o efiemu64_s.o ./efiemu.S -Wall -Werror -mcmodel=large -O2 -I. -I../../include
-ld -o efiemu64.o -r efiemu64_s.o efiemu64_c.o -nostdlib
diff --git a/efiemu/symbols.c b/efiemu/symbols.c
deleted file mode 100644 (file)
index 4fc546b..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-/* Code for managing symbols and pointers in efiemu */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/efiemu/efiemu.h>
-#include <grub/efiemu/runtime.h>
-
-static int ptv_written = 0;
-static int ptv_alloc = 0;
-static int ptv_handle = 0;
-static int relocated_handle = 0;
-static int ptv_requested = 0;
-static struct grub_efiemu_sym *efiemu_syms = 0;
-
-struct grub_efiemu_sym
-{
-  struct grub_efiemu_sym *next;
-  char *name;
-  int handle;
-  grub_off_t off;
-};
-
-void
-grub_efiemu_free_syms (void)
-{
-  struct grub_efiemu_sym *cur, *d;
-  for (cur = efiemu_syms; cur;)
-    {
-      d = cur->next;
-      grub_free (cur->name);
-      grub_free (cur);
-      cur = d;
-    }
-  efiemu_syms = 0;
-  ptv_written = 0;
-  ptv_alloc = 0;
-  ptv_requested = 0;
-  grub_efiemu_mm_return_request (ptv_handle);
-  ptv_handle = 0;
-  grub_efiemu_mm_return_request (relocated_handle);
-  relocated_handle = 0;
-}
-
-/* Announce that the module will need NUM allocators */
-/* Because of deferred memory allocation all the relocators have to be
-   announced during phase 1*/
-grub_err_t
-grub_efiemu_request_symbols (int num)
-{
-  if (ptv_alloc)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "symbols have already been allocated");
-  if (num < 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "can't request negative symbols");
-  ptv_requested += num;
-  return GRUB_ERR_NONE;
-}
-
-/* Resolve the symbol name NAME and set HANDLE and OFF accordingly  */
-grub_err_t
-grub_efiemu_resolve_symbol (const char *name, int *handle, grub_off_t *off)
-{
-  struct grub_efiemu_sym *cur;
-  for (cur = efiemu_syms; cur; cur = cur->next)
-    if (!grub_strcmp (name, cur->name))
-      {
-       *handle = cur->handle;
-       *off = cur->off;
-       return GRUB_ERR_NONE;
-      }
-  grub_dprintf ("efiemu", "%s not found\n", name);
-  return grub_error (GRUB_ERR_BAD_OS, "symbol %s isn't found", name);
-}
-
-/* Register symbol named NAME in memory handle HANDLE at offset OFF */
-grub_err_t
-grub_efiemu_register_symbol (const char *name, int handle, grub_off_t off)
-{
-  struct grub_efiemu_sym *cur;
-  cur = (struct grub_efiemu_sym *) grub_malloc (sizeof (*cur));
-  grub_dprintf ("efiemu", "registering symbol '%s'\n", name);
-  if (!cur)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't register symbol");
-  cur->name = grub_strdup (name);
-  cur->next = efiemu_syms;
-  cur->handle = handle;
-  cur->off = off;
-  efiemu_syms = cur;
-
-  return 0;
-}
-
-/* Go from phase 1 to phase 2. Must be called before similar function in mm.c */
-grub_err_t
-grub_efiemu_alloc_syms (void)
-{
-  ptv_alloc = ptv_requested;
-  ptv_handle = grub_efiemu_request_memalign
-    (1, (ptv_requested + 1) * sizeof (struct grub_efiemu_ptv_rel),
-     GRUB_EFI_RUNTIME_SERVICES_DATA);
-  relocated_handle = grub_efiemu_request_memalign
-    (1, sizeof (grub_uint8_t), GRUB_EFI_RUNTIME_SERVICES_DATA);
-
-  grub_efiemu_register_symbol ("efiemu_ptv_relocated", relocated_handle, 0);
-  grub_efiemu_register_symbol ("efiemu_ptv_relloc", ptv_handle, 0);
-  return grub_errno;
-}
-
-grub_err_t
-grub_efiemu_write_sym_markers (void)
-{
-  struct grub_efiemu_ptv_rel *ptv_rels
-    = grub_efiemu_mm_obtain_request (ptv_handle);
-  grub_uint8_t *relocated = grub_efiemu_mm_obtain_request (relocated_handle);
-  grub_memset (ptv_rels, 0, (ptv_requested + 1)
-              * sizeof (struct grub_efiemu_ptv_rel));
-  *relocated = 0;
-  return GRUB_ERR_NONE;
-}
-
-/* Write value (pointer to memory PLUS_HANDLE)
-   - (pointer to memory MINUS_HANDLE) + VALUE to ADDR assuming that the
-   size SIZE bytes. If PTV_NEEDED is 1 then announce it to runtime that this
-   value needs to be recomputed before going to virtual mode
-*/
-grub_err_t
-grub_efiemu_write_value (void *addr, grub_uint32_t value, int plus_handle,
-                        int minus_handle, int ptv_needed, int size)
-{
-  /* Announce relocator to runtime */
-  if (ptv_needed)
-    {
-      struct grub_efiemu_ptv_rel *ptv_rels
-       = grub_efiemu_mm_obtain_request (ptv_handle);
-
-      if (ptv_needed && ptv_written >= ptv_alloc)
-       return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                          "your module didn't declare efiemu "
-                          " relocators correctly");
-
-      if (minus_handle)
-       ptv_rels[ptv_written].minustype
-         = grub_efiemu_mm_get_type (minus_handle);
-      else
-       ptv_rels[ptv_written].minustype = 0;
-
-      if (plus_handle)
-       ptv_rels[ptv_written].plustype
-         = grub_efiemu_mm_get_type (plus_handle);
-      else
-       ptv_rels[ptv_written].plustype = 0;
-
-      ptv_rels[ptv_written].addr = PTR_TO_UINT64 (addr);
-      ptv_rels[ptv_written].size = size;
-      ptv_written++;
-
-      /* memset next value to zero to mark the end */
-      grub_memset (&ptv_rels[ptv_written], 0, sizeof (ptv_rels[ptv_written]));
-    }
-
-  /* Compute the value */
-  if (minus_handle)
-    value -= PTR_TO_UINT32 (grub_efiemu_mm_obtain_request (minus_handle));
-
-  if (plus_handle)
-    value += PTR_TO_UINT32 (grub_efiemu_mm_obtain_request (plus_handle));
-
-  /* Write the value */
-  switch (size)
-    {
-    case 8:
-      *((grub_uint64_t *) addr) = value;
-      break;
-    case 4:
-      *((grub_uint32_t *) addr) = value;
-      break;
-    case 2:
-      *((grub_uint16_t *) addr) = value;
-      break;
-    case 1:
-      *((grub_uint8_t *) addr) = value;
-      break;
-    default:
-      return grub_error (GRUB_ERR_BAD_ARGUMENT, "wrong symbol size");
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
-                                    grub_efi_uintn_t descriptor_size,
-                                    grub_efi_uint32_t descriptor_version
-                                    __attribute__ ((unused)),
-                                    grub_efi_memory_descriptor_t *virtual_map)
-{
-  grub_uint8_t *ptv_relocated;
-  struct grub_efiemu_ptv_rel *cur_relloc;
-  struct grub_efiemu_ptv_rel *ptv_rels;
-
-  ptv_relocated = grub_efiemu_mm_obtain_request (relocated_handle);
-  ptv_rels = grub_efiemu_mm_obtain_request (ptv_handle);
-
-  /* Ensure that we are called only once */
-  if (*ptv_relocated)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "EfiEmu is already relocated");
-  *ptv_relocated = 1;
-
-  /* Correct addresses using information supplied by grub */
-  for (cur_relloc = ptv_rels; cur_relloc->size; cur_relloc++)
-    {
-      grub_int64_t corr = 0;
-      grub_efi_memory_descriptor_t *descptr;
-
-      /* Compute correction */
-      for (descptr = virtual_map;
-          (grub_size_t) ((grub_uint8_t *) descptr
-                         - (grub_uint8_t *) virtual_map) < memory_map_size;
-          descptr = (grub_efi_memory_descriptor_t *)
-            ((grub_uint8_t *) descptr + descriptor_size))
-       {
-         if (descptr->type == cur_relloc->plustype)
-           corr += descptr->virtual_start - descptr->physical_start;
-         if (descptr->type == cur_relloc->minustype)
-           corr -= descptr->virtual_start - descptr->physical_start;
-       }
-
-      /* Apply correction */
-      switch (cur_relloc->size)
-       {
-       case 8:
-         *((grub_uint64_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
-         break;
-       case 4:
-         *((grub_uint32_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
-         break;
-       case 2:
-         *((grub_uint16_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
-         break;
-       case 1:
-         *((grub_uint8_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
-         break;
-       }
-    }
-
-  /* Recompute crc32 of system table and runtime services */
-
-  if (grub_efiemu_sizeof_uintn_t () == 4)
-    return grub_efiemu_crc32 ();
-  else
-    return grub_efiemu_crc64 ();
-}
diff --git a/font/font.c b/font/font.c
deleted file mode 100644 (file)
index 9a89cad..0000000
+++ /dev/null
@@ -1,1124 +0,0 @@
-/* font.c - Font API and font file loader.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/bufio.h>
-#include <grub/dl.h>
-#include <grub/file.h>
-#include <grub/font.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/types.h>
-#include <grub/video.h>
-#include <grub/bitmap.h>
-#include <grub/fontformat.h>
-
-#ifdef USE_ASCII_FAILBACK
-#include "ascii.h"
-#endif
-
-#ifndef FONT_DEBUG
-#define FONT_DEBUG 0
-#endif
-
-struct char_index_entry
-{
-  grub_uint32_t code;
-  grub_uint8_t storage_flags;
-  grub_uint32_t offset;
-
-  /* Glyph if loaded, or NULL otherwise.  */
-  struct grub_font_glyph *glyph;
-};
-
-#define FONT_WEIGHT_NORMAL 100
-#define FONT_WEIGHT_BOLD 200
-#define ASCII_BITMAP_SIZE 16
-
-struct grub_font
-{
-  char *name;
-  grub_file_t file;
-  char *family;
-  short point_size;
-  short weight;
-  short max_char_width;
-  short max_char_height;
-  short ascent;
-  short descent;
-  short leading;
-  grub_uint32_t num_chars;
-  struct char_index_entry *char_index;
-  grub_uint16_t *bmp_idx;
-};
-
-/* Definition of font registry.  */
-struct grub_font_node *grub_font_list;
-
-static int register_font (grub_font_t font);
-static void font_init (grub_font_t font);
-static void free_font (grub_font_t font);
-static void remove_font (grub_font_t font);
-
-struct font_file_section
-{
-  /* The file this section is in.  */
-  grub_file_t file;
-
-  /* FOURCC name of the section.  */
-  char name[4];
-
-  /* Length of the section contents.  */
-  grub_uint32_t length;
-
-  /* Set by open_section() on EOF.  */
-  int eof;
-};
-
-/* Replace unknown glyphs with a rounded question mark.  */
-static grub_uint8_t unknown_glyph_bitmap[] = {
-  /*                               76543210 */
-  0x7C,                                /*  ooooo   */
-  0x82,                                /* o     o  */
-  0xBA,                                /* o ooo o  */
-  0xAA,                                /* o o o o  */
-  0xAA,                                /* o o o o  */
-  0x8A,                                /* o   o o  */
-  0x9A,                                /* o  oo o  */
-  0x92,                                /* o  o  o  */
-  0x92,                                /* o  o  o  */
-  0x92,                                /* o  o  o  */
-  0x92,                                /* o  o  o  */
-  0x82,                                /* o     o  */
-  0x92,                                /* o  o  o  */
-  0x82,                                /* o     o  */
-  0x7C,                                /*  ooooo   */
-  0x00                         /*          */
-};
-
-/* The "unknown glyph" glyph, used as a last resort.  */
-static struct grub_font_glyph *unknown_glyph;
-
-/* The font structure used when no other font is loaded.  This functions
-   as a "Null Object" pattern, so that code everywhere does not have to
-   check for a NULL grub_font_t to avoid dereferencing a null pointer.  */
-static struct grub_font null_font;
-
-/* Flag to ensure module is initialized only once.  */
-static grub_uint8_t font_loader_initialized;
-
-#ifdef USE_ASCII_FAILBACK
-static struct grub_font_glyph *ascii_font_glyph[0x80];
-#endif
-
-static struct grub_font_glyph *
-ascii_glyph_lookup (grub_uint32_t code)
-{
-#ifdef USE_ASCII_FAILBACK
-  static int ascii_failback_initialized = 0;
-
-  if (code >= 0x80)
-    return unknown_glyph;
-
-  if (ascii_failback_initialized == 0)
-    {
-      int current;
-      for (current = 0; current < 0x80; current++)
-       {
-         ascii_font_glyph[current] =
-           grub_malloc (sizeof (struct grub_font_glyph) + ASCII_BITMAP_SIZE);
-
-         ascii_font_glyph[current]->width = 8;
-         ascii_font_glyph[current]->height = 16;
-         ascii_font_glyph[current]->offset_x = 0;
-         ascii_font_glyph[current]->offset_y = -2;
-         ascii_font_glyph[current]->device_width = 8;
-
-         grub_memcpy (ascii_font_glyph[current]->bitmap,
-                      &ascii_bitmaps[(0x7f - current) * ASCII_BITMAP_SIZE],
-                      ASCII_BITMAP_SIZE);
-       }
-
-      ascii_failback_initialized = 1;
-    }
-
-  return ascii_font_glyph[code];
-#else
-  (void) code;
-  return unknown_glyph;
-#endif
-}
-
-void
-grub_font_loader_init (void)
-{
-  /* Only initialize font loader once.  */
-  if (font_loader_initialized)
-    return;
-
-  /* Make glyph for unknown glyph.  */
-  unknown_glyph = grub_malloc (sizeof (struct grub_font_glyph)
-                              + sizeof (unknown_glyph_bitmap));
-  if (!unknown_glyph)
-    return;
-
-  unknown_glyph->width = 8;
-  unknown_glyph->height = 16;
-  unknown_glyph->offset_x = 0;
-  unknown_glyph->offset_y = -3;
-  unknown_glyph->device_width = 8;
-  grub_memcpy (unknown_glyph->bitmap,
-              unknown_glyph_bitmap, sizeof (unknown_glyph_bitmap));
-
-  /* Initialize the null font.  */
-  font_init (&null_font);
-  null_font.name = "<No Font>";
-  null_font.ascent = unknown_glyph->height - 3;
-  null_font.descent = 3;
-  null_font.max_char_width = unknown_glyph->width;
-  null_font.max_char_height = unknown_glyph->height;
-
-  font_loader_initialized = 1;
-}
-
-/* Initialize the font object with initial default values.  */
-static void
-font_init (grub_font_t font)
-{
-  font->name = 0;
-  font->file = 0;
-  font->family = 0;
-  font->point_size = 0;
-  font->weight = 0;
-
-  /* Default leading value, not in font file yet.  */
-  font->leading = 1;
-
-  font->max_char_width = 0;
-  font->max_char_height = 0;
-  font->ascent = 0;
-  font->descent = 0;
-  font->num_chars = 0;
-  font->char_index = 0;
-  font->bmp_idx = 0;
-}
-
-/* Open the next section in the file.
-
-   On success, the section name is stored in section->name and the length in
-   section->length, and 0 is returned.  On failure, 1 is returned and
-   grub_errno is set appropriately with an error message.
-
-   If 1 is returned due to being at the end of the file, then section->eof is
-   set to 1; otherwise, section->eof is set to 0.  */
-static int
-open_section (grub_file_t file, struct font_file_section *section)
-{
-  grub_ssize_t retval;
-  grub_uint32_t raw_length;
-
-  section->file = file;
-  section->eof = 0;
-
-  /* Read the FOURCC section name.  */
-  retval = grub_file_read (file, section->name, 4);
-  if (retval >= 0 && retval < 4)
-    {
-      /* EOF encountered.  */
-      section->eof = 1;
-      return 1;
-    }
-  else if (retval < 0)
-    {
-      grub_error (GRUB_ERR_BAD_FONT,
-                 "font format error: can't read section name");
-      return 1;
-    }
-
-  /* Read the big-endian 32-bit section length.  */
-  retval = grub_file_read (file, &raw_length, 4);
-  if (retval >= 0 && retval < 4)
-    {
-      /* EOF encountered.  */
-      section->eof = 1;
-      return 1;
-    }
-  else if (retval < 0)
-    {
-      grub_error (GRUB_ERR_BAD_FONT,
-                 "font format error: can't read section length");
-      return 1;
-    }
-
-  /* Convert byte-order and store in *length.  */
-  section->length = grub_be_to_cpu32 (raw_length);
-
-  return 0;
-}
-
-/* Size in bytes of each character index (CHIX section)
-   entry in the font file.  */
-#define FONT_CHAR_INDEX_ENTRY_SIZE (4 + 1 + 4)
-
-/* Load the character index (CHIX) section contents from the font file.  This
-   presumes that the position of FILE is positioned immediately after the
-   section length for the CHIX section (i.e., at the start of the section
-   contents).  Returns 0 upon success, nonzero for failure (in which case
-   grub_errno is set appropriately).  */
-static int
-load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
-                grub_font *font)
-{
-  unsigned i;
-  grub_uint32_t last_code;
-
-#if FONT_DEBUG >= 2
-  grub_printf ("load_font_index(sect_length=%d)\n", sect_length);
-#endif
-
-  /* Sanity check: ensure section length is divisible by the entry size.  */
-  if ((sect_length % FONT_CHAR_INDEX_ENTRY_SIZE) != 0)
-    {
-      grub_error (GRUB_ERR_BAD_FONT,
-                 "font file format error: character index length %d "
-                 "is not a multiple of the entry size %d",
-                 sect_length, FONT_CHAR_INDEX_ENTRY_SIZE);
-      return 1;
-    }
-
-  /* Calculate the number of characters.  */
-  font->num_chars = sect_length / FONT_CHAR_INDEX_ENTRY_SIZE;
-
-  /* Allocate the character index array.  */
-  font->char_index = grub_malloc (font->num_chars
-                                 * sizeof (struct char_index_entry));
-  if (!font->char_index)
-    return 1;
-  font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t));
-  if (!font->bmp_idx)
-    {
-      grub_free (font->char_index);
-      return 1;
-    }
-  grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t));
-
-
-#if FONT_DEBUG >= 2
-  grub_printf ("num_chars=%d)\n", font->num_chars);
-#endif
-
-  last_code = 0;
-
-  /* Load the character index data from the file.  */
-  for (i = 0; i < font->num_chars; i++)
-    {
-      struct char_index_entry *entry = &font->char_index[i];
-
-      /* Read code point value; convert to native byte order.  */
-      if (grub_file_read (file, &entry->code, 4) != 4)
-       return 1;
-      entry->code = grub_be_to_cpu32 (entry->code);
-
-      /* Verify that characters are in ascending order.  */
-      if (i != 0 && entry->code <= last_code)
-       {
-         grub_error (GRUB_ERR_BAD_FONT,
-                     "font characters not in ascending order: %u <= %u",
-                     entry->code, last_code);
-         return 1;
-       }
-
-      if (entry->code < 0x10000)
-       font->bmp_idx[entry->code] = i;
-
-      last_code = entry->code;
-
-      /* Read storage flags byte.  */
-      if (grub_file_read (file, &entry->storage_flags, 1) != 1)
-       return 1;
-
-      /* Read glyph data offset; convert to native byte order.  */
-      if (grub_file_read (file, &entry->offset, 4) != 4)
-       return 1;
-      entry->offset = grub_be_to_cpu32 (entry->offset);
-
-      /* No glyph loaded.  Will be loaded on demand and cached thereafter.  */
-      entry->glyph = 0;
-
-#if FONT_DEBUG >= 5
-      /* Print the 1st 10 characters.  */
-      if (i < 10)
-       grub_printf ("c=%d o=%d\n", entry->code, entry->offset);
-#endif
-    }
-
-  return 0;
-}
-
-/* Read the contents of the specified section as a string, which is
-   allocated on the heap.  Returns 0 if there is an error.  */
-static char *
-read_section_as_string (struct font_file_section *section)
-{
-  char *str;
-  grub_ssize_t ret;
-
-  str = grub_malloc (section->length + 1);
-  if (!str)
-    return 0;
-
-  ret = grub_file_read (section->file, str, section->length);
-  if (ret < 0 || ret != (grub_ssize_t) section->length)
-    {
-      grub_free (str);
-      return 0;
-    }
-
-  str[section->length] = '\0';
-  return str;
-}
-
-/* Read the contents of the current section as a 16-bit integer value,
-   which is stored into *VALUE.
-   Returns 0 upon success, nonzero upon failure.  */
-static int
-read_section_as_short (struct font_file_section *section,
-                      grub_int16_t * value)
-{
-  grub_uint16_t raw_value;
-
-  if (section->length != 2)
-    {
-      grub_error (GRUB_ERR_BAD_FONT,
-                 "font file format error: section %c%c%c%c length "
-                 "is %d but should be 2",
-                 section->name[0], section->name[1],
-                 section->name[2], section->name[3], section->length);
-      return 1;
-    }
-  if (grub_file_read (section->file, &raw_value, 2) != 2)
-    return 1;
-
-  *value = grub_be_to_cpu16 (raw_value);
-  return 0;
-}
-
-/* Load a font and add it to the beginning of the global font list.
-   Returns 0 upon success, nonzero upon failure.  */
-int
-grub_font_load (const char *filename)
-{
-  grub_file_t file = 0;
-  struct font_file_section section;
-  char magic[4];
-  grub_font_t font = 0;
-
-#if FONT_DEBUG >= 1
-  grub_printf ("add_font(%s)\n", filename);
-#endif
-
-  file = grub_buffile_open (filename, 1024);
-  if (!file)
-    goto fail;
-
-#if FONT_DEBUG >= 3
-  grub_printf ("file opened\n");
-#endif
-
-  /* Read the FILE section.  It indicates the file format.  */
-  if (open_section (file, &section) != 0)
-    goto fail;
-
-#if FONT_DEBUG >= 3
-  grub_printf ("opened FILE section\n");
-#endif
-  if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FILE,
-                  sizeof (FONT_FORMAT_SECTION_NAMES_FILE) - 1) != 0)
-    {
-      grub_error (GRUB_ERR_BAD_FONT,
-                 "font file format error: 1st section must be FILE");
-      goto fail;
-    }
-
-#if FONT_DEBUG >= 3
-  grub_printf ("section name ok\n");
-#endif
-  if (section.length != 4)
-    {
-      grub_error (GRUB_ERR_BAD_FONT,
-                 "font file format error (file type ID length is %d "
-                 "but should be 4)", section.length);
-      goto fail;
-    }
-
-#if FONT_DEBUG >= 3
-  grub_printf ("section length ok\n");
-#endif
-  /* Check the file format type code.  */
-  if (grub_file_read (file, magic, 4) != 4)
-    goto fail;
-
-#if FONT_DEBUG >= 3
-  grub_printf ("read magic ok\n");
-#endif
-
-  if (grub_memcmp (magic, FONT_FORMAT_PFF2_MAGIC, 4) != 0)
-    {
-      grub_error (GRUB_ERR_BAD_FONT, "invalid font magic %x %x %x %x",
-                 magic[0], magic[1], magic[2], magic[3]);
-      goto fail;
-    }
-
-#if FONT_DEBUG >= 3
-  grub_printf ("compare magic ok\n");
-#endif
-
-  /* Allocate the font object.  */
-  font = (grub_font_t) grub_malloc (sizeof (struct grub_font));
-  if (!font)
-    goto fail;
-
-  font_init (font);
-  font->file = file;
-
-#if FONT_DEBUG >= 3
-  grub_printf ("allocate font ok; loading font info\n");
-#endif
-
-  /* Load the font information.  */
-  while (1)
-    {
-      if (open_section (file, &section) != 0)
-       {
-         if (section.eof)
-           break;              /* Done reading the font file.  */
-         else
-           goto fail;
-       }
-
-#if FONT_DEBUG >= 2
-      grub_printf ("opened section %c%c%c%c ok\n",
-                  section.name[0], section.name[1],
-                  section.name[2], section.name[3]);
-#endif
-
-      if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FONT_NAME,
-                      sizeof (FONT_FORMAT_SECTION_NAMES_FONT_NAME) - 1) == 0)
-       {
-         font->name = read_section_as_string (&section);
-         if (!font->name)
-           goto fail;
-       }
-      else if (grub_memcmp (section.name,
-                           FONT_FORMAT_SECTION_NAMES_POINT_SIZE,
-                           sizeof (FONT_FORMAT_SECTION_NAMES_POINT_SIZE) -
-                           1) == 0)
-       {
-         if (read_section_as_short (&section, &font->point_size) != 0)
-           goto fail;
-       }
-      else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_WEIGHT,
-                           sizeof (FONT_FORMAT_SECTION_NAMES_WEIGHT) - 1)
-              == 0)
-       {
-         char *wt;
-         wt = read_section_as_string (&section);
-         if (!wt)
-           continue;
-         /* Convert the weight string 'normal' or 'bold' into a number.  */
-         if (grub_strcmp (wt, "normal") == 0)
-           font->weight = FONT_WEIGHT_NORMAL;
-         else if (grub_strcmp (wt, "bold") == 0)
-           font->weight = FONT_WEIGHT_BOLD;
-         grub_free (wt);
-       }
-      else if (grub_memcmp (section.name,
-                           FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH,
-                           sizeof (FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH)
-                           - 1) == 0)
-       {
-         if (read_section_as_short (&section, &font->max_char_width) != 0)
-           goto fail;
-       }
-      else if (grub_memcmp (section.name,
-                           FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT,
-                           sizeof (FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT)
-                           - 1) == 0)
-       {
-         if (read_section_as_short (&section, &font->max_char_height) != 0)
-           goto fail;
-       }
-      else if (grub_memcmp (section.name,
-                           FONT_FORMAT_SECTION_NAMES_ASCENT,
-                           sizeof (FONT_FORMAT_SECTION_NAMES_ASCENT) - 1)
-              == 0)
-       {
-         if (read_section_as_short (&section, &font->ascent) != 0)
-           goto fail;
-       }
-      else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_DESCENT,
-                           sizeof (FONT_FORMAT_SECTION_NAMES_DESCENT) - 1)
-              == 0)
-       {
-         if (read_section_as_short (&section, &font->descent) != 0)
-           goto fail;
-       }
-      else if (grub_memcmp (section.name,
-                           FONT_FORMAT_SECTION_NAMES_CHAR_INDEX,
-                           sizeof (FONT_FORMAT_SECTION_NAMES_CHAR_INDEX) -
-                           1) == 0)
-       {
-         if (load_font_index (file, section.length, font) != 0)
-           goto fail;
-       }
-      else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_DATA,
-                           sizeof (FONT_FORMAT_SECTION_NAMES_DATA) - 1) == 0)
-       {
-         /* When the DATA section marker is reached, we stop reading.  */
-         break;
-       }
-      else
-       {
-         /* Unhandled section type, simply skip past it.  */
-#if FONT_DEBUG >= 3
-         grub_printf ("Unhandled section type, skipping.\n");
-#endif
-         grub_off_t section_end = grub_file_tell (file) + section.length;
-         if ((int) grub_file_seek (file, section_end) == -1)
-           goto fail;
-       }
-    }
-
-  if (!font->name)
-    {
-      grub_printf ("Note: Font has no name.\n");
-      font->name = grub_strdup ("Unknown");
-    }
-
-#if FONT_DEBUG >= 1
-  grub_printf ("Loaded font `%s'.\n"
-              "Ascent=%d Descent=%d MaxW=%d MaxH=%d Number of characters=%d.\n",
-              font->name,
-              font->ascent, font->descent,
-              font->max_char_width, font->max_char_height, font->num_chars);
-#endif
-
-  if (font->max_char_width == 0
-      || font->max_char_height == 0
-      || font->num_chars == 0
-      || font->char_index == 0 || font->ascent == 0 || font->descent == 0)
-    {
-      grub_error (GRUB_ERR_BAD_FONT,
-                 "invalid font file: missing some required data");
-      goto fail;
-    }
-
-  /* Add the font to the global font registry.  */
-  if (register_font (font) != 0)
-    goto fail;
-
-  return 0;
-
-fail:
-  free_font (font);
-  return 1;
-}
-
-/* Read a 16-bit big-endian integer from FILE, convert it to native byte
-   order, and store it in *VALUE.
-   Returns 0 on success, 1 on failure.  */
-static int
-read_be_uint16 (grub_file_t file, grub_uint16_t * value)
-{
-  if (grub_file_read (file, value, 2) != 2)
-    return 1;
-  *value = grub_be_to_cpu16 (*value);
-  return 0;
-}
-
-static int
-read_be_int16 (grub_file_t file, grub_int16_t * value)
-{
-  /* For the signed integer version, use the same code as for unsigned.  */
-  return read_be_uint16 (file, (grub_uint16_t *) value);
-}
-
-/* Return a pointer to the character index entry for the glyph corresponding to
-   the codepoint CODE in the font FONT.  If not found, return zero.  */
-static inline struct char_index_entry *
-find_glyph (const grub_font_t font, grub_uint32_t code)
-{
-  struct char_index_entry *table;
-  grub_size_t lo;
-  grub_size_t hi;
-  grub_size_t mid;
-
-  table = font->char_index;
-
-  /* Use BMP index if possible.  */
-  if (code < 0x10000 && font->bmp_idx)
-    {
-      if (font->bmp_idx[code] == 0xffff)
-       return 0;
-      return &table[font->bmp_idx[code]];
-    }
-
-  /* Do a binary search in `char_index', which is ordered by code point.  */
-  lo = 0;
-  hi = font->num_chars - 1;
-
-  if (!table)
-    return 0;
-
-  while (lo <= hi)
-    {
-      mid = lo + (hi - lo) / 2;
-      if (code < table[mid].code)
-       hi = mid - 1;
-      else if (code > table[mid].code)
-       lo = mid + 1;
-      else
-       return &table[mid];
-    }
-
-  return 0;
-}
-
-/* Get a glyph for the Unicode character CODE in FONT.  The glyph is loaded
-   from the font file if has not been loaded yet.
-   Returns a pointer to the glyph if found, or 0 if it is not found.  */
-static struct grub_font_glyph *
-grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
-{
-  struct char_index_entry *index_entry;
-
-  index_entry = find_glyph (font, code);
-  if (index_entry)
-    {
-      struct grub_font_glyph *glyph = 0;
-      grub_uint16_t width;
-      grub_uint16_t height;
-      grub_int16_t xoff;
-      grub_int16_t yoff;
-      grub_int16_t dwidth;
-      int len;
-
-      if (index_entry->glyph)
-       /* Return cached glyph.  */
-       return index_entry->glyph;
-
-      if (!font->file)
-       /* No open file, can't load any glyphs.  */
-       return 0;
-
-      /* Make sure we can find glyphs for error messages.  Push active
-         error message to error stack and reset error message.  */
-      grub_error_push ();
-
-      grub_file_seek (font->file, index_entry->offset);
-
-      /* Read the glyph width, height, and baseline.  */
-      if (read_be_uint16 (font->file, &width) != 0
-         || read_be_uint16 (font->file, &height) != 0
-         || read_be_int16 (font->file, &xoff) != 0
-         || read_be_int16 (font->file, &yoff) != 0
-         || read_be_int16 (font->file, &dwidth) != 0)
-       {
-         remove_font (font);
-         return 0;
-       }
-
-      len = (width * height + 7) / 8;
-      glyph = grub_malloc (sizeof (struct grub_font_glyph) + len);
-      if (!glyph)
-       {
-         remove_font (font);
-         return 0;
-       }
-
-      glyph->font = font;
-      glyph->width = width;
-      glyph->height = height;
-      glyph->offset_x = xoff;
-      glyph->offset_y = yoff;
-      glyph->device_width = dwidth;
-
-      /* Don't try to read empty bitmaps (e.g., space characters).  */
-      if (len != 0)
-       {
-         if (grub_file_read (font->file, glyph->bitmap, len) != len)
-           {
-             remove_font (font);
-             return 0;
-           }
-       }
-
-      /* Restore old error message.  */
-      grub_error_pop ();
-
-      /* Cache the glyph.  */
-      index_entry->glyph = glyph;
-
-      return glyph;
-    }
-
-  return 0;
-}
-
-/* Free the memory used by FONT.
-   This should not be called if the font has been made available to
-   users (once it is added to the global font list), since there would
-   be the possibility of a dangling pointer.  */
-static void
-free_font (grub_font_t font)
-{
-  if (font)
-    {
-      if (font->file)
-       grub_file_close (font->file);
-      grub_free (font->name);
-      grub_free (font->family);
-      grub_free (font->char_index);
-      grub_free (font);
-    }
-}
-
-/* Add FONT to the global font registry.
-   Returns 0 upon success, nonzero on failure
-   (the font was not registered).  */
-static int
-register_font (grub_font_t font)
-{
-  struct grub_font_node *node = 0;
-
-  node = grub_malloc (sizeof (struct grub_font_node));
-  if (!node)
-    return 1;
-
-  node->value = font;
-  node->next = grub_font_list;
-  grub_font_list = node;
-
-  return 0;
-}
-
-/* Remove the font from the global font list.  We don't actually free the
-   font's memory since users could be holding references to the font.  */
-static void
-remove_font (grub_font_t font)
-{
-  struct grub_font_node **nextp, *cur;
-
-  for (nextp = &grub_font_list, cur = *nextp;
-       cur; nextp = &cur->next, cur = cur->next)
-    {
-      if (cur->value == font)
-       {
-         *nextp = cur->next;
-
-         /* Free the node, but not the font itself.  */
-         grub_free (cur);
-
-         return;
-       }
-    }
-}
-
-/* Get a font from the list of loaded fonts.  This function will return
-   another font if the requested font is not available.  If no fonts are
-   loaded, then a special 'null font' is returned, which contains no glyphs,
-   but is not a null pointer so the caller may omit checks for NULL.  */
-grub_font_t
-grub_font_get (const char *font_name)
-{
-  struct grub_font_node *node;
-
-  for (node = grub_font_list; node; node = node->next)
-    {
-      grub_font_t font = node->value;
-      if (grub_strcmp (font->name, font_name) == 0)
-       return font;
-    }
-
-  /* If no font by that name is found, return the first font in the list
-     as a fallback.  */
-  if (grub_font_list && grub_font_list->value)
-    return grub_font_list->value;
-  else
-    /* The null_font is a last resort.  */
-    return &null_font;
-}
-
-/* Get the full name of the font.  */
-const char *
-grub_font_get_name (grub_font_t font)
-{
-  return font->name;
-}
-
-/* Get the maximum width of any character in the font in pixels.  */
-int
-grub_font_get_max_char_width (grub_font_t font)
-{
-  return font->max_char_width;
-}
-
-/* Get the maximum height of any character in the font in pixels.  */
-int
-grub_font_get_max_char_height (grub_font_t font)
-{
-  return font->max_char_height;
-}
-
-/* Get the distance in pixels from the top of characters to the baseline.  */
-int
-grub_font_get_ascent (grub_font_t font)
-{
-  return font->ascent;
-}
-
-/* Get the distance in pixels from the baseline to the lowest descenders
-   (for instance, in a lowercase 'y', 'g', etc.).  */
-int
-grub_font_get_descent (grub_font_t font)
-{
-  return font->descent;
-}
-
-/* Get the *standard leading* of the font in pixel, which is the spacing
-   between two lines of text.  Specifically, it is the space between the
-   descent of one line and the ascent of the next line.  This is included
-   in the *height* metric.  */
-int
-grub_font_get_leading (grub_font_t font)
-{
-  return font->leading;
-}
-
-/* Get the distance in pixels between baselines of adjacent lines of text.  */
-int
-grub_font_get_height (grub_font_t font)
-{
-  return font->ascent + font->descent + font->leading;
-}
-
-/* Get the width in pixels of the specified UTF-8 string, when rendered in
-   in the specified font (but falling back on other fonts for glyphs that
-   are missing).  */
-int
-grub_font_get_string_width (grub_font_t font, const char *str)
-{
-  int width;
-  struct grub_font_glyph *glyph;
-  grub_uint32_t code;
-  const grub_uint8_t *ptr;
-
-  for (ptr = (const grub_uint8_t *) str, width = 0;
-       grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0;)
-    {
-      glyph = grub_font_get_glyph_with_fallback (font, code);
-      width += glyph->device_width;
-    }
-
-  return width;
-}
-
-/* Get the glyph for FONT corresponding to the Unicode code point CODE.
-   Returns the ASCII glyph for the code if no other fonts are available. 
-   The glyphs are cached once loaded.  */
-struct grub_font_glyph *
-grub_font_get_glyph (grub_font_t font, grub_uint32_t code)
-{
-  struct grub_font_glyph *glyph = 0;
-  if (font)
-    glyph = grub_font_get_glyph_internal (font, code);
-  if (glyph == 0)
-    {
-      glyph = ascii_glyph_lookup (code);
-    }
-  return glyph;
-}
-
-
-/* Calculate a subject value representing "how similar" two fonts are.
-   This is used to prioritize the order that fonts are scanned for missing
-   glyphs.  The object is to select glyphs from the most similar font
-   possible, for the best appearance.
-   The heuristic is crude, but it helps greatly when fonts of similar
-   sizes are used so that tiny 8 point glyphs are not mixed into a string
-   of 24 point text unless there is no other choice.  */
-static int
-get_font_diversity (grub_font_t a, grub_font_t b)
-{
-  int d;
-
-  d = 0;
-
-  if (a->ascent && b->ascent)
-    d += grub_abs (a->ascent - b->ascent) * 8;
-  else
-    /* Penalty for missing attributes.  */
-    d += 50;
-
-  if (a->max_char_height && b->max_char_height)
-    d += grub_abs (a->max_char_height - b->max_char_height) * 8;
-  else
-    /* Penalty for missing attributes.  */
-    d += 50;
-
-  /* Weight is a minor factor. */
-  d += (a->weight != b->weight) ? 5 : 0;
-
-  return d;
-}
-
-/* Get a glyph corresponding to the codepoint CODE.  If FONT contains the
-   specified glyph, then it is returned.  Otherwise, all other loaded fonts
-   are searched until one is found that contains a glyph for CODE.
-   If no glyph is available for CODE in the loaded fonts, then a glyph
-   representing an unknown character is returned.
-   This function never returns NULL.
-   The returned glyph is owned by the font manager and should not be freed
-   by the caller.  The glyphs are cached.  */
-struct grub_font_glyph *
-grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
-{
-  struct grub_font_glyph *glyph;
-  struct grub_font_node *node;
-  /* Keep track of next node, in case there's an I/O error in
-     grub_font_get_glyph_internal() and the font is removed from the list.  */
-  struct grub_font_node *next;
-  /* Information on the best glyph found so far, to help find the glyph in
-     the best matching to the requested one.  */
-  int best_diversity;
-  struct grub_font_glyph *best_glyph;
-
-  if (font)
-    {
-      /* First try to get the glyph from the specified font.  */
-      glyph = grub_font_get_glyph_internal (font, code);
-      if (glyph)
-       return glyph;
-    }
-
-  /* Otherwise, search all loaded fonts for the glyph and use the one from
-     the font that best matches the requested font.  */
-  best_diversity = 10000;
-  best_glyph = 0;
-
-  for (node = grub_font_list; node; node = next)
-    {
-      grub_font_t curfont;
-
-      curfont = node->value;
-      next = node->next;
-
-      glyph = grub_font_get_glyph_internal (curfont, code);
-      if (glyph)
-       {
-         int d;
-
-         d = get_font_diversity (curfont, font);
-         if (d < best_diversity)
-           {
-             best_diversity = d;
-             best_glyph = glyph;
-           }
-       }
-    }
-
-  if (best_glyph)
-    return best_glyph;
-  else
-    /* Glyph not available in any font.  Return ASCII failback.  */
-    return ascii_glyph_lookup (code);
-}
-
-
-/* Draw the specified glyph at (x, y).  The y coordinate designates the
-   baseline of the character, while the x coordinate designates the left
-   side location of the character.  */
-grub_err_t
-grub_font_draw_glyph (struct grub_font_glyph * glyph,
-                     grub_video_color_t color, int left_x, int baseline_y)
-{
-  struct grub_video_bitmap glyph_bitmap;
-
-  /* Don't try to draw empty glyphs (U+0020, etc.).  */
-  if (glyph->width == 0 || glyph->height == 0)
-    return GRUB_ERR_NONE;
-
-  glyph_bitmap.mode_info.width = glyph->width;
-  glyph_bitmap.mode_info.height = glyph->height;
-  glyph_bitmap.mode_info.mode_type =
-    (1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP;
-  glyph_bitmap.mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED;
-  glyph_bitmap.mode_info.bpp = 1;
-
-  /* Really 1 bit per pixel.  */
-  glyph_bitmap.mode_info.bytes_per_pixel = 0;
-
-  /* Packed densely as bits.  */
-  glyph_bitmap.mode_info.pitch = glyph->width;
-
-  glyph_bitmap.mode_info.number_of_colors = 2;
-  glyph_bitmap.mode_info.bg_red = 0;
-  glyph_bitmap.mode_info.bg_green = 0;
-  glyph_bitmap.mode_info.bg_blue = 0;
-  glyph_bitmap.mode_info.bg_alpha = 0;
-  grub_video_unmap_color (color,
-                         &glyph_bitmap.mode_info.fg_red,
-                         &glyph_bitmap.mode_info.fg_green,
-                         &glyph_bitmap.mode_info.fg_blue,
-                         &glyph_bitmap.mode_info.fg_alpha);
-  glyph_bitmap.data = glyph->bitmap;
-
-  int bitmap_left = left_x + glyph->offset_x;
-  int bitmap_bottom = baseline_y - glyph->offset_y;
-  int bitmap_top = bitmap_bottom - glyph->height;
-
-  return grub_video_blit_bitmap (&glyph_bitmap, GRUB_VIDEO_BLIT_BLEND,
-                                bitmap_left, bitmap_top,
-                                0, 0, glyph->width, glyph->height);
-}
-
-/* Draw a UTF-8 string of text on the current video render target.
-   The x coordinate specifies the starting x position for the first character,
-   while the y coordinate specifies the baseline position.
-   If the string contains a character that FONT does not contain, then
-   a glyph from another loaded font may be used instead.  */
-grub_err_t
-grub_font_draw_string (const char *str, grub_font_t font,
-                      grub_video_color_t color, int left_x, int baseline_y)
-{
-  int x;
-  struct grub_font_glyph *glyph;
-  grub_uint32_t code;
-  const grub_uint8_t *ptr;
-
-  for (ptr = (const grub_uint8_t *) str, x = left_x;
-       grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0;)
-    {
-      glyph = grub_font_get_glyph_with_fallback (font, code);
-      if (grub_font_draw_glyph (glyph, color, x, baseline_y) != GRUB_ERR_NONE)
-       return grub_errno;
-      x += glyph->device_width;
-    }
-
-  return GRUB_ERR_NONE;
-}
diff --git a/font/font_cmd.c b/font/font_cmd.c
deleted file mode 100644 (file)
index 8b00dd8..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/* font_cmd.c - Font command definition. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/font.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-loadfont_command (grub_command_t cmd __attribute__ ((unused)),
-                 int argc,
-                 char **args)
-{
-  if (argc == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no font specified");
-
-  while (argc--)
-    if (grub_font_load (*args++) != 0)
-      return GRUB_ERR_BAD_FONT;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-lsfonts_command (grub_command_t cmd __attribute__ ((unused)),
-                 int argc __attribute__ ((unused)),
-                 char **args __attribute__ ((unused)))
-{
-  struct grub_font_node *node;
-
-  grub_printf ("Loaded fonts:\n");
-  for (node = grub_font_list; node; node = node->next)
-    {
-      grub_font_t font = node->value;
-      grub_printf ("%s\n", grub_font_get_name (font));
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_command_t cmd_loadfont, cmd_lsfonts;
-
-GRUB_MOD_INIT(font)
-{
-  grub_font_loader_init ();
-
-  cmd_loadfont =
-    grub_register_command ("loadfont", loadfont_command,
-                          N_("FILE..."),
-                          N_("Specify one or more font files to load."));
-  cmd_lsfonts =
-    grub_register_command ("lsfonts", lsfonts_command,
-                          0, N_("List the loaded fonts."));
-}
-
-GRUB_MOD_FINI(font)
-{
-  /* TODO: Determine way to free allocated resources.
-     Warning: possible pointer references could be in use.  */
-
-  grub_unregister_command (cmd_loadfont);
-  grub_unregister_command (cmd_lsfonts);
-}
diff --git a/fs/affs.c b/fs/affs.c
deleted file mode 100644 (file)
index 3dc8075..0000000
--- a/fs/affs.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/* affs.c - Amiga Fast FileSystem.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/types.h>
-#include <grub/fshelp.h>
-
-/* The affs bootblock.  */
-struct grub_affs_bblock
-{
-  grub_uint8_t type[3];
-  grub_uint8_t flags;
-  grub_uint32_t checksum;
-  grub_uint32_t rootblock;
-} __attribute__ ((packed));
-
-/* Set if the filesystem is a AFFS filesystem.  Otherwise this is an
-   OFS filesystem.  */
-#define GRUB_AFFS_FLAG_FFS     1
-
-/* The affs rootblock.  */
-struct grub_affs_rblock
-{
-  grub_uint8_t type[4];
-  grub_uint8_t unused1[8];
-  grub_uint32_t htsize;
-  grub_uint32_t unused2;
-  grub_uint32_t checksum;
-  grub_uint32_t hashtable[1];
-} __attribute__ ((packed));
-
-/* The second part of a file header block.  */
-struct grub_affs_file
-{
-  grub_uint8_t unused1[12];
-  grub_uint32_t size;
-  grub_uint8_t unused2[104];
-  grub_uint8_t namelen;
-  grub_uint8_t name[30];
-  grub_uint8_t unused3[33];
-  grub_uint32_t next;
-  grub_uint32_t parent;
-  grub_uint32_t extension;
-  grub_int32_t type;
-} __attribute__ ((packed));
-
-/* The location of `struct grub_affs_file' relative to the end of a
-   file header block.  */
-#define        GRUB_AFFS_FILE_LOCATION         200
-
-/* The offset in both the rootblock and the file header block for the
-   hashtable, symlink and block pointers (all synonyms).  */
-#define GRUB_AFFS_HASHTABLE_OFFSET     24
-#define GRUB_AFFS_BLOCKPTR_OFFSET      24
-#define GRUB_AFFS_SYMLINK_OFFSET       24
-
-#define GRUB_AFFS_SYMLINK_SIZE(blocksize) ((blocksize) - 225)
-
-#define GRUB_AFFS_FILETYPE_DIR         -3
-#define GRUB_AFFS_FILETYPE_REG         2
-#define GRUB_AFFS_FILETYPE_SYMLINK     3
-\f
-
-struct grub_fshelp_node
-{
-  struct grub_affs_data *data;
-  int block;
-  int size;
-  int parent;
-};
-
-/* Information about a "mounted" affs filesystem.  */
-struct grub_affs_data
-{
-  struct grub_affs_bblock bblock;
-  struct grub_fshelp_node diropen;
-  grub_disk_t disk;
-
-  /* Blocksize in sectors.  */
-  int blocksize;
-
-  /* The number of entries in the hashtable.  */
-  int htsize;
-};
-
-static grub_dl_t my_mod;
-
-\f
-static grub_disk_addr_t
-grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
-{
-  int links;
-  grub_uint32_t pos;
-  int block = node->block;
-  struct grub_affs_file file;
-  struct grub_affs_data *data = node->data;
-  grub_uint32_t mod;
-
-  /* Find the block that points to the fileblock we are looking up by
-     following the chain until the right table is reached.  */
-  for (links = grub_divmod64 (fileblock, data->htsize, &mod); links; links--)
-    {
-      grub_disk_read (data->disk, block + data->blocksize - 1,
-                     data->blocksize * (GRUB_DISK_SECTOR_SIZE
-                                        - GRUB_AFFS_FILE_LOCATION),
-                     sizeof (file), &file);
-      if (grub_errno)
-       return 0;
-
-      block = grub_be_to_cpu32 (file.extension);
-    }
-
-  /* Translate the fileblock to the block within the right table.  */
-  fileblock = mod;
-  grub_disk_read (data->disk, block,
-                 GRUB_AFFS_BLOCKPTR_OFFSET
-                 + (data->htsize - fileblock - 1) * sizeof (pos),
-                 sizeof (pos), &pos);
-  if (grub_errno)
-    return 0;
-
-  return grub_be_to_cpu32 (pos);
-}
-
-
-/* Read LEN bytes from the file described by DATA starting with byte
-   POS.  Return the amount of read bytes in READ.  */
-static grub_ssize_t
-grub_affs_read_file (grub_fshelp_node_t node,
-                    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                       unsigned offset, unsigned length),
-                    int pos, grub_size_t len, char *buf)
-{
-  return grub_fshelp_read_file (node->data->disk, node, read_hook,
-                               pos, len, buf, grub_affs_read_block,
-                               node->size, 0);
-}
-
-
-static struct grub_affs_data *
-grub_affs_mount (grub_disk_t disk)
-{
-  struct grub_affs_data *data;
-  grub_uint32_t *rootblock = 0;
-  struct grub_affs_rblock *rblock;
-
-  int checksum = 0;
-  int checksumr = 0;
-  int blocksize = 0;
-
-  data = grub_malloc (sizeof (struct grub_affs_data));
-  if (!data)
-    return 0;
-
-  /* Read the bootblock.  */
-  grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock),
-                 &data->bblock);
-  if (grub_errno)
-    goto fail;
-
-  /* Make sure this is an affs filesystem.  */
-  if (grub_strncmp ((char *) (data->bblock.type), "DOS", 3))
-    {
-      grub_error (GRUB_ERR_BAD_FS, "not an AFFS filesystem");
-      goto fail;
-    }
-
-  /* Test if the filesystem is a OFS filesystem.  */
-  if (! (data->bblock.flags & GRUB_AFFS_FLAG_FFS))
-    {
-      grub_error (GRUB_ERR_BAD_FS, "OFS not yet supported");
-      goto fail;
-    }
-
-  /* Read the bootblock.  */
-  grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock),
-                 &data->bblock);
-  if (grub_errno)
-    goto fail;
-
-  /* No sane person uses more than 8KB for a block.  At least I hope
-     for that person because in that case this won't work.  */
-  rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE * 16);
-  if (!rootblock)
-    goto fail;
-
-  rblock = (struct grub_affs_rblock *) rootblock;
-
-  /* Read the rootblock.  */
-  grub_disk_read (disk, (disk->total_sectors >> 1) + blocksize, 0,
-                 GRUB_DISK_SECTOR_SIZE * 16, rootblock);
-  if (grub_errno)
-    goto fail;
-
-  /* The filesystem blocksize is not stored anywhere in the filesystem
-     itself.  One way to determine it is reading blocks for the
-     rootblock until the checksum is correct.  */
-  checksumr = grub_be_to_cpu32 (rblock->checksum);
-  rblock->checksum = 0;
-  for (blocksize = 0; blocksize < 8; blocksize++)
-    {
-      grub_uint32_t *currblock = rootblock + GRUB_DISK_SECTOR_SIZE * blocksize;
-      unsigned int i;
-
-      for (i = 0; i < GRUB_DISK_SECTOR_SIZE / sizeof (*currblock); i++)
-       checksum += grub_be_to_cpu32 (currblock[i]);
-
-      if (checksumr == -checksum)
-       break;
-    }
-  if (-checksum != checksumr)
-    {
-      grub_error (GRUB_ERR_BAD_FS, "AFFS blocksize couldn't be determined");
-      goto fail;
-    }
-  blocksize++;
-
-  data->blocksize = blocksize;
-  data->disk = disk;
-  data->htsize = grub_be_to_cpu32 (rblock->htsize);
-  data->diropen.data = data;
-  data->diropen.block = (disk->total_sectors >> 1);
-
-  grub_free (rootblock);
-
-  return data;
-
- fail:
-  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
-    grub_error (GRUB_ERR_BAD_FS, "not an AFFS filesystem");
-
-  grub_free (data);
-  grub_free (rootblock);
-  return 0;
-}
-
-
-static char *
-grub_affs_read_symlink (grub_fshelp_node_t node)
-{
-  struct grub_affs_data *data = node->data;
-  char *symlink;
-
-  symlink = grub_malloc (GRUB_AFFS_SYMLINK_SIZE (data->blocksize));
-  if (!symlink)
-    return 0;
-
-  grub_disk_read (data->disk, node->block, GRUB_AFFS_SYMLINK_OFFSET,
-                 GRUB_AFFS_SYMLINK_SIZE (data->blocksize), symlink);
-  if (grub_errno)
-    {
-      grub_free (symlink);
-      return 0;
-    }
-  grub_dprintf ("affs", "Symlink: `%s'\n", symlink);
-  return symlink;
-}
-
-
-static int
-grub_affs_iterate_dir (grub_fshelp_node_t dir,
-                      int NESTED_FUNC_ATTR
-                      (*hook) (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node))
-{
-  int i;
-  struct grub_affs_file file;
-  struct grub_fshelp_node *node = 0;
-  struct grub_affs_data *data = dir->data;
-  grub_uint32_t *hashtable;
-
-  auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block,
-                                                  int size, int type);
-
-  int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block,
-                                             int size, int type)
-    {
-      node = grub_malloc (sizeof (*node));
-      if (!node)
-       {
-         grub_free (hashtable);
-         return 1;
-       }
-
-      node->data = data;
-      node->size = size;
-      node->block = block;
-      node->parent = grub_be_to_cpu32 (file.parent);
-
-      if (hook (name, type, node))
-       {
-         grub_free (hashtable);
-         return 1;
-       }
-      return 0;
-    }
-
-  hashtable = grub_malloc (data->htsize * sizeof (*hashtable));
-  if (!hashtable)
-    return 1;
-
-  grub_disk_read (data->disk, dir->block, GRUB_AFFS_HASHTABLE_OFFSET,
-                 data->htsize * sizeof (*hashtable), (char *) hashtable);
-  if (grub_errno)
-    goto fail;
-
-  /* Create the directory entries for `.' and `..'.  */
-  if (grub_affs_create_node (".", dir->block, dir->size, GRUB_FSHELP_DIR))
-    return 1;
-  if (grub_affs_create_node ("..", dir->parent ? dir->parent : dir->block,
-                            dir->size, GRUB_FSHELP_DIR))
-    return 1;
-
-  for (i = 0; i < data->htsize; i++)
-    {
-      enum grub_fshelp_filetype type;
-      grub_uint64_t next;
-
-      if (!hashtable[i])
-       continue;
-
-      /* Every entry in the hashtable can be chained.  Read the entire
-        chain.  */
-      next = grub_be_to_cpu32 (hashtable[i]);
-
-      while (next)
-       {
-         grub_disk_read (data->disk, next + data->blocksize - 1,
-                         data->blocksize * GRUB_DISK_SECTOR_SIZE
-                         - GRUB_AFFS_FILE_LOCATION,
-                         sizeof (file), (char *) &file);
-         if (grub_errno)
-           goto fail;
-
-         file.name[file.namelen] = '\0';
-
-         if ((int) grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_DIR)
-           type = GRUB_FSHELP_REG;
-         else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_REG)
-           type = GRUB_FSHELP_DIR;
-         else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_SYMLINK)
-           type = GRUB_FSHELP_SYMLINK;
-         else
-           type = GRUB_FSHELP_UNKNOWN;
-
-         if (grub_affs_create_node ((char *) (file.name), next,
-                                    grub_be_to_cpu32 (file.size), type))
-           return 1;
-
-         next = grub_be_to_cpu32 (file.next);
-       }
-    }
-
-  grub_free (hashtable);
-  return 0;
-
- fail:
-  grub_free (node);
-  grub_free (hashtable);
-  return 0;
-}
-
-
-/* Open a file named NAME and initialize FILE.  */
-static grub_err_t
-grub_affs_open (struct grub_file *file, const char *name)
-{
-  struct grub_affs_data *data;
-  struct grub_fshelp_node *fdiro = 0;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_affs_mount (file->device->disk);
-  if (!data)
-    goto fail;
-
-  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_affs_iterate_dir,
-                        grub_affs_read_symlink, GRUB_FSHELP_REG);
-  if (grub_errno)
-    goto fail;
-
-  file->size = fdiro->size;
-  data->diropen = *fdiro;
-  grub_free (fdiro);
-
-  file->data = data;
-  file->offset = 0;
-
-  return 0;
-
- fail:
-  if (data && fdiro != &data->diropen)
-    grub_free (fdiro);
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-
-static grub_err_t
-grub_affs_close (grub_file_t file)
-{
-  grub_free (file->data);
-
-  grub_dl_unref (my_mod);
-
-  return GRUB_ERR_NONE;
-}
-
-
-/* Read LEN bytes data from FILE into BUF.  */
-static grub_ssize_t
-grub_affs_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_affs_data *data =
-    (struct grub_affs_data *) file->data;
-
-  int size = grub_affs_read_file (&data->diropen, file->read_hook,
-                             file->offset, len, buf);
-
-  return size;
-}
-
-
-static grub_err_t
-grub_affs_dir (grub_device_t device, const char *path,
-              int (*hook) (const char *filename,
-                           const struct grub_dirhook_info *info))
-{
-  struct grub_affs_data *data = 0;
-  struct grub_fshelp_node *fdiro = 0;
-
-  auto int NESTED_FUNC_ATTR iterate (const char *filename,
-                                    enum grub_fshelp_filetype filetype,
-                                    grub_fshelp_node_t node);
-
-  int NESTED_FUNC_ATTR iterate (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node)
-    {
-      struct grub_dirhook_info info;
-      grub_memset (&info, 0, sizeof (info));
-      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
-      grub_free (node);
-      return hook (filename, &info);
-    }
-
-  grub_dl_ref (my_mod);
-
-  data = grub_affs_mount (device->disk);
-  if (!data)
-    goto fail;
-
-  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_affs_iterate_dir,
-                        grub_affs_read_symlink, GRUB_FSHELP_DIR);
-  if (grub_errno)
-    goto fail;
-
-  grub_affs_iterate_dir (fdiro, iterate);
-
- fail:
-  if (data && fdiro != &data->diropen)
-    grub_free (fdiro);
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-
-static grub_err_t
-grub_affs_label (grub_device_t device, char **label)
-{
-  struct grub_affs_data *data;
-  struct grub_affs_file file;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_affs_mount (disk);
-  if (data)
-    {
-      /* The rootblock maps quite well on a file header block, it's
-        something we can use here.  */
-      grub_disk_read (data->disk, disk->total_sectors >> 1,
-                     data->blocksize * (GRUB_DISK_SECTOR_SIZE
-                                        - GRUB_AFFS_FILE_LOCATION),
-                     sizeof (file), &file);
-      if (grub_errno)
-       return 0;
-
-      *label = grub_strndup ((char *) (file.name), file.namelen);
-    }
-  else
-    *label = 0;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-\f
-static struct grub_fs grub_affs_fs =
-  {
-    .name = "affs",
-    .dir = grub_affs_dir,
-    .open = grub_affs_open,
-    .read = grub_affs_read,
-    .close = grub_affs_close,
-    .label = grub_affs_label,
-    .next = 0
-  };
-
-GRUB_MOD_INIT(affs)
-{
-  grub_fs_register (&grub_affs_fs);
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(affs)
-{
-  grub_fs_unregister (&grub_affs_fs);
-}
diff --git a/fs/afs.c b/fs/afs.c
deleted file mode 100644 (file)
index cd61f4d..0000000
--- a/fs/afs.c
+++ /dev/null
@@ -1,718 +0,0 @@
-/* afs.c - The native AtheOS file-system.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/types.h>
-#include <grub/fshelp.h>
-
-#ifdef MODE_BIGENDIAN
-#define GRUB_AFS_FSNAME_SUFFIX "_be"
-#else
-#define GRUB_AFS_FSNAME_SUFFIX ""
-#endif
-
-#ifdef MODE_BFS
-#define GRUB_AFS_FSNAME "befs" GRUB_AFS_FSNAME_SUFFIX
-#else
-#define GRUB_AFS_FSNAME "afs" GRUB_AFS_FSNAME_SUFFIX
-#endif
-
-#define        GRUB_AFS_DIRECT_BLOCK_COUNT     12
-#define        GRUB_AFS_BLOCKS_PER_DI_RUN      4
-
-#ifdef MODE_BFS
-#define GRUB_AFS_SBLOCK_SECTOR 1
-#define        GRUB_AFS_SBLOCK_MAGIC1  0x42465331 /* BFS1.  */
-#else
-#define GRUB_AFS_SBLOCK_SECTOR 2
-#define        GRUB_AFS_SBLOCK_MAGIC1  0x41465331 /* AFS1.  */
-#endif
-
-#define        GRUB_AFS_SBLOCK_MAGIC2  0xdd121031
-#define        GRUB_AFS_SBLOCK_MAGIC3  0x15b6830e
-
-#define        GRUB_AFS_INODE_MAGIC    0x64358428
-
-#ifdef MODE_BFS
-#define GRUB_AFS_BTREE_MAGIC   0x69f6c2e8
-#else
-#define GRUB_AFS_BTREE_MAGIC   0x65768995
-#endif
-
-#define GRUB_AFS_BNODE_SIZE    1024
-
-#define GRUB_AFS_S_IFMT                00170000
-#define GRUB_AFS_S_IFLNK       0120000
-
-#define GRUB_AFS_S_IFREG       0100000
-#define GRUB_AFS_S_IFDIR       0040000
-#define GRUB_AFS_S_IFIFO       0010000
-
-#define GRUB_AFS_NULL_VAL      ((grub_afs_bvalue_t)-1)
-
-#ifdef MODE_BIGENDIAN
-#define grub_afs_to_cpu16(x) grub_be_to_cpu16 (x)
-#define grub_afs_to_cpu32(x) grub_be_to_cpu32 (x)
-#define grub_afs_to_cpu64(x) grub_be_to_cpu64 (x)
-#else
-#define grub_afs_to_cpu16(x) grub_le_to_cpu16 (x)
-#define grub_afs_to_cpu32(x) grub_le_to_cpu32 (x)
-#define grub_afs_to_cpu64(x) grub_le_to_cpu64 (x)
-#endif
-
-#ifdef MODE_BFS
-#define B_KEY_INDEX_ALIGN 8
-#else
-#define B_KEY_INDEX_ALIGN 4
-#endif
-
-#define B_KEY_INDEX_OFFSET(node) ((grub_uint16_t *) \
-                                 ((char *) (node) \
-                                  + ALIGN_UP (sizeof (struct grub_afs_bnode) \
-                                              + node->key_size, \
-                                              B_KEY_INDEX_ALIGN)))
-
-#define B_KEY_VALUE_OFFSET(node) ((grub_afs_bvalue_t *) \
-                                   ((char *) B_KEY_INDEX_OFFSET (node) + \
-                                    node->key_count * 2))
-
-typedef grub_uint64_t grub_afs_off_t;
-typedef grub_uint64_t grub_afs_bigtime;
-typedef grub_uint64_t grub_afs_bvalue_t;
-
-struct grub_afs_blockrun
-{
-  grub_uint32_t group;
-  grub_uint16_t start;
-  grub_uint16_t len;
-} __attribute__ ((packed));
-
-struct grub_afs_datastream
-{
-  struct grub_afs_blockrun direct[GRUB_AFS_DIRECT_BLOCK_COUNT];
-  grub_afs_off_t max_direct_range;
-  struct grub_afs_blockrun indirect;
-  grub_afs_off_t max_indirect_range;
-  struct grub_afs_blockrun double_indirect;
-  grub_afs_off_t max_double_indirect_range;
-  grub_afs_off_t size;
-} __attribute__ ((packed));
-
-struct grub_afs_bnode
-{
-  grub_afs_bvalue_t left;
-  grub_afs_bvalue_t right;
-  grub_afs_bvalue_t overflow;
-#ifdef MODE_BFS
-  grub_uint16_t key_count;
-  grub_uint16_t key_size;
-#else
-  grub_uint32_t key_count;
-  grub_uint32_t key_size;
-#endif
-  char key_data[0];
-} __attribute__ ((packed));
-
-#ifdef MODE_BFS
-struct grub_afs_btree
-{
-  grub_uint32_t magic;
-  grub_uint32_t unused1;
-  grub_uint32_t tree_depth;
-  grub_uint32_t unused2;
-  grub_afs_bvalue_t root;
-  grub_uint32_t unused3[4];
-} __attribute__ ((packed));
-#else
-struct grub_afs_btree
-{
-  grub_uint32_t magic;
-  grub_afs_bvalue_t root;
-  grub_uint32_t tree_depth;
-  grub_afs_bvalue_t last_node;
-  grub_afs_bvalue_t first_free;
-} __attribute__ ((packed));
-#endif
-
-/* Beware that following structure describes AtheFS and if you write code
-   which uses currently unused fields check it with both AtheFS and BeFS.
- */
-struct grub_afs_sblock
-{
-  char name[32];
-  grub_uint32_t magic1;
-  grub_uint32_t byte_order;
-  grub_uint32_t        block_size;
-  grub_uint32_t block_shift;
-  grub_afs_off_t num_blocks;
-  grub_afs_off_t used_blocks;
-  grub_uint32_t        inode_size;
-  grub_uint32_t        magic2;
-  grub_uint32_t        block_per_group; /* Number of blocks per allocation
-                                   group. (Max 65536)  */
-  grub_uint32_t        alloc_group_shift; /* Number of bits to shift a group
-                                     number to get a byte address.  */
-  grub_uint32_t        alloc_group_count;
-  grub_uint32_t        flags;
-  struct grub_afs_blockrun log_block;
-  grub_afs_off_t log_start;
-  grub_uint32_t valid_log_blocks;
-  grub_uint32_t log_size;
-  grub_uint32_t        magic3;
-  struct grub_afs_blockrun root_dir; /* Root dir inode.  */
-  struct grub_afs_blockrun deleted_files; /* Directory containing files
-                                            scheduled for deletion.  */
-  struct grub_afs_blockrun index_dir; /* Directory of index files.  */
-  grub_uint32_t boot_loader_size;
-  grub_uint32_t        pad[7];
-}  __attribute__ ((packed));
-
-struct grub_afs_inode
-{
-  grub_uint32_t magic1;
-  struct grub_afs_blockrun inode_num;
-  grub_uint32_t uid;
-  grub_uint32_t gid;
-  grub_uint32_t mode;
-  grub_uint32_t flags;
-#ifndef MODE_BFS
-  grub_uint32_t link_count;
-#endif
-  grub_afs_bigtime create_time;
-  grub_afs_bigtime modified_time;
-  struct grub_afs_blockrun parent;
-  struct grub_afs_blockrun attrib_dir;
-  grub_uint32_t index_type; /* Key data-key only used for index files. */
-  grub_uint32_t inode_size;
-  grub_uint32_t unused;
-  struct grub_afs_datastream stream;
-  grub_uint32_t        pad[4];
-  grub_uint32_t small_data[1];
-} __attribute__ ((packed));
-
-struct grub_fshelp_node
-{
-  struct grub_afs_data *data;
-  struct grub_afs_inode inode;
-};
-
-struct grub_afs_data
-{
-  grub_disk_t disk;
-  struct grub_afs_sblock sblock;
-  struct grub_afs_inode *inode;
-  struct grub_fshelp_node diropen;
-};
-
-static grub_dl_t my_mod;
-
-static grub_afs_off_t
-grub_afs_run_to_num (struct grub_afs_sblock *sb,
-                     struct grub_afs_blockrun *run)
-{
-  return ((grub_afs_off_t) grub_afs_to_cpu32 (run->group)
-         * sb->block_per_group + grub_afs_to_cpu16 (run->start));
-}
-
-static grub_err_t
-grub_afs_read_inode (struct grub_afs_data *data,
-                     grub_uint32_t ino, struct grub_afs_inode *inode)
-{
-  return grub_disk_read (data->disk,
-                         ino *
-                         (data->sblock.block_size >> GRUB_DISK_SECTOR_BITS),
-                         0, sizeof (struct grub_afs_inode),
-                         inode);
-}
-
-static grub_disk_addr_t
-grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
-{
-  struct grub_afs_sblock *sb = &node->data->sblock;
-  struct grub_afs_datastream *ds = &node->inode.stream;
-
-  if (fileblock < grub_afs_to_cpu64 (ds->max_direct_range))
-    {
-      int i;
-
-      for (i = 0; i < GRUB_AFS_DIRECT_BLOCK_COUNT; i++)
-        {
-          if (fileblock < grub_afs_to_cpu16 (ds->direct[i].len))
-            return grub_afs_run_to_num (sb, &ds->direct[i]) + fileblock;
-          fileblock -= grub_afs_to_cpu16 (ds->direct[i].len);
-        }
-    }
-  else if (fileblock < grub_afs_to_cpu64 (ds->max_indirect_range))
-    {
-      int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun);
-      struct grub_afs_blockrun indir[ptrs_per_blk];
-      grub_afs_off_t blk = grub_afs_run_to_num (sb, &ds->indirect);
-      int i;
-
-      fileblock -= grub_afs_to_cpu64 (ds->max_direct_range);
-      for (i = 0; i < ds->indirect.len; i++, blk++)
-        {
-          int j;
-
-          if (grub_disk_read (node->data->disk,
-                              blk * (sb->block_size >> GRUB_DISK_SECTOR_BITS),
-                              0, sizeof (indir),
-                              indir))
-            return 0;
-
-          for (j = 0; j < ptrs_per_blk; j++)
-            {
-              if (fileblock < grub_afs_to_cpu16 (indir[j].len))
-                return grub_afs_run_to_num (sb, &indir[j]) + fileblock;
-
-              fileblock -= grub_afs_to_cpu16 (indir[j].len);
-            }
-        }
-    }
-  else
-    {
-      int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun);
-      struct grub_afs_blockrun indir[ptrs_per_blk];
-
-      /* ([idblk][idptr]) ([dblk][dptr]) [blk]  */
-      int cur_pos = fileblock - grub_afs_to_cpu64 (ds->max_indirect_range);
-
-      int dptr_size = GRUB_AFS_BLOCKS_PER_DI_RUN;
-      int dblk_size = dptr_size * ptrs_per_blk;
-      int idptr_size = dblk_size * GRUB_AFS_BLOCKS_PER_DI_RUN;
-      int idblk_size = idptr_size * ptrs_per_blk;
-
-      int off = cur_pos % GRUB_AFS_BLOCKS_PER_DI_RUN;
-      int dptr = (cur_pos / dptr_size) % ptrs_per_blk;
-      int dblk = (cur_pos / dblk_size) % GRUB_AFS_BLOCKS_PER_DI_RUN;
-      int idptr = (cur_pos / idptr_size) % ptrs_per_blk;
-      int idblk = (cur_pos / idblk_size);
-
-      if (grub_disk_read (node->data->disk,
-                          (grub_afs_run_to_num (sb, &ds->double_indirect)
-                           + idblk) *
-                          (sb->block_size >> GRUB_DISK_SECTOR_BITS),
-                          0, sizeof (indir),
-                          indir))
-        return 0;
-
-      if (grub_disk_read (node->data->disk,
-                          (grub_afs_run_to_num (sb, &indir[idptr]) + dblk) *
-                          (sb->block_size >> GRUB_DISK_SECTOR_BITS),
-                          0, sizeof (indir),
-                          indir))
-        return 0;
-
-      return grub_afs_run_to_num (sb, &indir[dptr]) + off;
-    }
-
-  return 0;
-}
-
-static grub_ssize_t
-grub_afs_read_file (grub_fshelp_node_t node,
-                    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                                        unsigned offset, unsigned length),
-                    int pos, grub_size_t len, char *buf)
-{
-  return grub_fshelp_read_file (node->data->disk, node, read_hook,
-                               pos, len, buf, grub_afs_read_block,
-                                grub_afs_to_cpu64 (node->inode.stream.size),
-                               node->data->sblock.block_shift
-                                - GRUB_DISK_SECTOR_BITS);
-}
-
-static char *
-grub_afs_read_symlink (grub_fshelp_node_t node)
-{
-  char *ret;
-  grub_afs_off_t size = grub_afs_to_cpu64 (node->inode.stream.size);
-
-  if (size == 0)
-    {
-      size = sizeof (node->inode.stream);
-      ret = grub_zalloc (size + 1);
-      if (! ret)
-       return 0;
-      grub_memcpy (ret, (char *) &(node->inode.stream),
-                  sizeof (node->inode.stream));
-      return ret;
-    }
-  ret = grub_zalloc (size + 1);
-  if (! ret)
-    return 0;
-  grub_afs_read_file (node, 0, 0, size, ret);
-  return ret;
-}
-
-static int
-grub_afs_iterate_dir (grub_fshelp_node_t dir,
-                      int NESTED_FUNC_ATTR
-                      (*hook) (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node))
-{
-  struct grub_afs_btree head;
-  char node_data [GRUB_AFS_BNODE_SIZE];
-  struct grub_afs_bnode *node = (struct grub_afs_bnode *) node_data;
-  int i;
-
-  if ((dir->inode.stream.size == 0)
-      || ((grub_afs_to_cpu32 (dir->inode.mode) & GRUB_AFS_S_IFMT)
-         != GRUB_AFS_S_IFDIR))
-    return 0;
-
-  grub_afs_read_file (dir, 0, 0, sizeof (head), (char *) &head);
-  if (grub_errno)
-    return 0;
-
-  grub_afs_read_file (dir, 0, grub_afs_to_cpu64 (head.root),
-                      GRUB_AFS_BNODE_SIZE, (char *) node);
-  if (grub_errno)
-    return 0;
-
-  for (i = 0; i < (int) grub_afs_to_cpu32 (head.tree_depth) - 1; i++)
-    {
-      grub_afs_bvalue_t blk;
-
-      blk = grub_afs_to_cpu64(B_KEY_VALUE_OFFSET (node) [0]);
-      grub_afs_read_file (dir, 0, blk, GRUB_AFS_BNODE_SIZE, (char *) node);
-      if (grub_errno)
-        return 0;
-    }
-
-  if (node->key_count)
-    {
-      grub_uint32_t cur_key = 0;
-
-      while (1)
-        {
-          int key_start, key_size;
-          grub_uint16_t *index;
-
-          index = B_KEY_INDEX_OFFSET (node);
-
-         key_start = (cur_key > 0)
-           ? grub_afs_to_cpu16 (index[cur_key - 1]) : 0;
-          key_size = grub_afs_to_cpu16 (index[cur_key]) - key_start;
-          if (key_size > 0)
-            {
-              char filename [key_size + 1];
-              struct grub_fshelp_node *fdiro;
-              int mode, type;
-
-              fdiro = grub_malloc (sizeof (struct grub_fshelp_node));
-              if (! fdiro)
-                return 0;
-
-              fdiro->data = dir->data;
-              if (grub_afs_read_inode (dir->data,
-                                       grub_afs_to_cpu64
-                                      (B_KEY_VALUE_OFFSET (node) [cur_key]),
-                                       &fdiro->inode))
-                return 0;
-
-              grub_memcpy (filename, &node->key_data[key_start], key_size);
-              filename [key_size] = 0;
-
-              mode = (grub_afs_to_cpu32 (fdiro->inode.mode) & GRUB_AFS_S_IFMT);
-              if (mode == GRUB_AFS_S_IFDIR)
-                type = GRUB_FSHELP_DIR;
-              else if (mode == GRUB_AFS_S_IFREG)
-                type = GRUB_FSHELP_REG;
-             else if (mode == GRUB_AFS_S_IFLNK)
-               type = GRUB_FSHELP_SYMLINK;
-              else
-                type = GRUB_FSHELP_UNKNOWN;
-
-              if (hook (filename, type, fdiro))
-                return 1;
-            }
-
-          cur_key++;
-          if (cur_key >= grub_afs_to_cpu32 (node->key_count))
-            {
-              if (node->right == GRUB_AFS_NULL_VAL)
-                break;
-
-              grub_afs_read_file (dir, 0, grub_afs_to_cpu64 (node->right),
-                                  GRUB_AFS_BNODE_SIZE, (char *) node);
-              if (grub_errno)
-                return 0;
-
-              cur_key = 0;
-            }
-        }
-    }
-
-  return 0;
-}
-
-static int
-grub_afs_validate_sblock (struct grub_afs_sblock *sb)
-{
-  if (grub_afs_to_cpu32 (sb->magic1) == GRUB_AFS_SBLOCK_MAGIC1)
-    {
-      sb->magic2 = grub_afs_to_cpu32 (sb->magic2);
-      sb->magic3 = grub_afs_to_cpu32 (sb->magic3);
-      sb->block_shift = grub_afs_to_cpu32 (sb->block_shift);
-      sb->block_size = grub_afs_to_cpu32 (sb->block_size);
-      sb->used_blocks = grub_afs_to_cpu64 (sb->used_blocks);
-      sb->num_blocks = grub_afs_to_cpu64 (sb->num_blocks);
-      sb->inode_size = grub_afs_to_cpu32 (sb->inode_size);
-      sb->alloc_group_count = grub_afs_to_cpu32 (sb->alloc_group_count);
-      sb->alloc_group_shift = grub_afs_to_cpu32 (sb->alloc_group_shift);
-      sb->block_per_group = grub_afs_to_cpu32 (sb->block_per_group);
-      sb->alloc_group_count = grub_afs_to_cpu32 (sb->alloc_group_count);
-      sb->log_size = grub_afs_to_cpu32 (sb->log_size);
-    }
-  else
-    return 0;
-
-  if ((sb->magic2 != GRUB_AFS_SBLOCK_MAGIC2) ||
-      (sb->magic3 != GRUB_AFS_SBLOCK_MAGIC3))
-    return 0;
-
-#ifdef MODE_BFS
-  sb->block_per_group = 1 << (sb->alloc_group_shift);
-#endif
-
-  if (((grub_uint32_t) (1 << sb->block_shift) != sb->block_size)
-      || (sb->used_blocks > sb->num_blocks )
-      || (sb->inode_size != sb->block_size)
-      || (0 == sb->block_size)
-#ifndef MODE_BFS
-      || ((grub_uint32_t) (1 << sb->alloc_group_shift) !=
-         sb->block_per_group * sb->block_size)
-      || (sb->alloc_group_count * sb->block_per_group < sb->num_blocks)
-      || (grub_afs_to_cpu16 (sb->log_block.len) != sb->log_size)
-      || (grub_afs_to_cpu32 (sb->valid_log_blocks) > sb->log_size)
-#endif
-      )
-    return 0;
-
-  return 1;
-}
-
-static struct grub_afs_data *
-grub_afs_mount (grub_disk_t disk)
-{
-  struct grub_afs_data *data = 0;
-
-  data = grub_malloc (sizeof (struct grub_afs_data));
-  if (!data)
-    return 0;
-
-  /* Read the superblock.  */
-  if (grub_disk_read (disk, GRUB_AFS_SBLOCK_SECTOR, 0,
-                     sizeof (struct grub_afs_sblock), &data->sblock))
-    goto fail;
-
-  if (! grub_afs_validate_sblock (&data->sblock))
-    goto fail;
-
-  data->diropen.data = data;
-  data->inode = &data->diropen.inode;
-  data->disk = disk;
-
-  if (grub_afs_read_inode (data,
-                           grub_afs_run_to_num (&data->sblock,
-                                                &data->sblock.root_dir),
-                           data->inode))
-    goto fail;
-
-  return data;
-
-fail:
-  grub_error (GRUB_ERR_BAD_FS, "not an " GRUB_AFS_FSNAME " filesystem");
-
-  grub_free (data);
-  return 0;
-}
-
-static grub_err_t
-grub_afs_open (struct grub_file *file, const char *name)
-{
-  struct grub_afs_data *data;
-  struct grub_fshelp_node *fdiro = 0;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_afs_mount (file->device->disk);
-  if (! data)
-    goto fail;
-
-  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_afs_iterate_dir,
-                        grub_afs_read_symlink, GRUB_FSHELP_REG);
-  if (grub_errno)
-    goto fail;
-
-  grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_afs_inode));
-  grub_free (fdiro);
-
-  file->size = grub_afs_to_cpu64 (data->inode->stream.size);
-  file->data = data;
-  file->offset = 0;
-
-  return 0;
-
-fail:
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_ssize_t
-grub_afs_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_afs_data *data = (struct grub_afs_data *) file->data;
-
-  return grub_afs_read_file (&data->diropen, file->read_hook,
-                             file->offset, len, buf);
-}
-
-static grub_err_t
-grub_afs_close (grub_file_t file)
-{
-  grub_free (file->data);
-
-  grub_dl_unref (my_mod);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_afs_dir (grub_device_t device, const char *path,
-              int (*hook) (const char *filename,
-                          const struct grub_dirhook_info *info))
-{
-  struct grub_afs_data *data = 0;
-  struct grub_fshelp_node *fdiro = 0;
-
-  auto int NESTED_FUNC_ATTR iterate (const char *filename,
-                                    enum grub_fshelp_filetype filetype,
-                                    grub_fshelp_node_t node);
-
-  int NESTED_FUNC_ATTR iterate (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node)
-    {
-      struct grub_dirhook_info info;
-      grub_memset (&info, 0, sizeof (info));
-      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
-      info.mtimeset = 1;
-#ifdef MODE_BFS
-      info.mtime = grub_afs_to_cpu64 (node->inode.modified_time) >> 16;
-#else
-      info.mtime = grub_divmod64 (grub_afs_to_cpu64 (node->inode.modified_time),
-                                 1000000, 0);
-#endif
-      grub_free (node);
-      return hook (filename, &info);
-    }
-
-  grub_dl_ref (my_mod);
-
-  data = grub_afs_mount (device->disk);
-  if (! data)
-    goto fail;
-
-  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_afs_iterate_dir,
-                        grub_afs_read_symlink, GRUB_FSHELP_DIR);
-  if (grub_errno)
-    goto fail;
-
-  grub_afs_iterate_dir (fdiro, iterate);
-
-  if (fdiro != &data->diropen)
-    grub_free (fdiro);
-
- fail:
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_afs_label (grub_device_t device, char **label)
-{
-  struct grub_afs_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_afs_mount (disk);
-  if (data)
-    *label = grub_strndup (data->sblock.name, sizeof (data->sblock.name));
-  else
-    *label = NULL;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-
-static struct grub_fs grub_afs_fs = {
-  .name = GRUB_AFS_FSNAME,
-  .dir = grub_afs_dir,
-  .open = grub_afs_open,
-  .read = grub_afs_read,
-  .close = grub_afs_close,
-  .label = grub_afs_label,
-  .next = 0
-};
-
-#if defined (MODE_BIGENDIAN) && defined (MODE_BFS)
-GRUB_MOD_INIT (befs_be)
-#elif defined (MODE_BFS)
-GRUB_MOD_INIT (befs)
-#elif defined (MODE_BIGENDIAN)
-GRUB_MOD_INIT (afs_be)
-#else
-GRUB_MOD_INIT (afs)
-#endif
-{
-  grub_fs_register (&grub_afs_fs);
-  my_mod = mod;
-}
-
-#if defined (MODE_BIGENDIAN) && defined (MODE_BFS)
-GRUB_MOD_FINI (befs_be)
-#elif defined (MODE_BFS)
-GRUB_MOD_FINI (befs)
-#elif defined (MODE_BIGENDIAN)
-GRUB_MOD_FINI (afs_be)
-#else
-GRUB_MOD_FINI (afs)
-#endif
-{
-  grub_fs_unregister (&grub_afs_fs);
-}
diff --git a/fs/afs_be.c b/fs/afs_be.c
deleted file mode 100644 (file)
index 1f1f48f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#define MODE_BIGENDIAN 1
-#include "afs.c"
diff --git a/fs/befs.c b/fs/befs.c
deleted file mode 100644 (file)
index c54d8e1..0000000
--- a/fs/befs.c
+++ /dev/null
@@ -1,3 +0,0 @@
-/* befs.c - The native BeOS/Haiku file-system.  */
-#define MODE_BFS 1
-#include "afs.c"
diff --git a/fs/befs_be.c b/fs/befs_be.c
deleted file mode 100644 (file)
index f6e8179..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-/* befs.c - The native BeOS/Haiku file-system.  */
-#define MODE_BFS 1
-#define MODE_BIGENDIAN 1
-#include "afs.c"
diff --git a/fs/cpio.c b/fs/cpio.c
deleted file mode 100644 (file)
index c087b4f..0000000
--- a/fs/cpio.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/* cpio.c - cpio and tar filesystem.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007,2008,2009 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 3 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-
-#ifndef MODE_USTAR
-/* cpio support */
-#define        MAGIC_BCPIO     070707
-struct head
-{
-  grub_uint16_t magic;
-  grub_uint16_t dev;
-  grub_uint16_t ino;
-  grub_uint16_t mode;
-  grub_uint16_t uid;
-  grub_uint16_t gid;
-  grub_uint16_t nlink;
-  grub_uint16_t rdev;
-  grub_uint16_t mtime_1;
-  grub_uint16_t mtime_2;
-  grub_uint16_t namesize;
-  grub_uint16_t filesize_1;
-  grub_uint16_t filesize_2;
-} __attribute__ ((packed));
-#else
-/* tar support */
-#define MAGIC_USTAR    "ustar"
-struct head
-{
-  char name[100];
-  char mode[8];
-  char uid[8];
-  char gid[8];
-  char size[12];
-  char mtime[12];
-  char chksum[8];
-  char typeflag;
-  char linkname[100];
-  char magic[6];
-  char version[2];
-  char uname[32];
-  char gname[32];
-  char devmajor[8];
-  char devminor[8];
-  char prefix[155];
-} __attribute__ ((packed));
-#endif
-
-struct grub_cpio_data
-{
-  grub_disk_t disk;
-  grub_uint32_t hofs;
-  grub_uint32_t dofs;
-  grub_uint32_t size;
-};
-
-static grub_dl_t my_mod;
-
-static grub_err_t
-grub_cpio_find_file (struct grub_cpio_data *data, char **name,
-                    grub_uint32_t * ofs)
-{
-#ifndef MODE_USTAR
-      struct head hd;
-
-      if (grub_disk_read
-         (data->disk, 0, data->hofs, sizeof (hd), &hd))
-       return grub_errno;
-
-      if (hd.magic != MAGIC_BCPIO)
-       return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive");
-
-      data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2;
-
-      if (hd.namesize & 1)
-       hd.namesize++;
-
-      if ((*name = grub_malloc (hd.namesize)) == NULL)
-       return grub_errno;
-
-      if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd),
-                         hd.namesize, *name))
-       {
-         grub_free (*name);
-         return grub_errno;
-       }
-
-      if (data->size == 0 && hd.mode == 0 && hd.namesize == 11 + 1
-         && ! grub_memcmp(*name, "TRAILER!!!", 11))
-       {
-         *ofs = 0;
-         return GRUB_ERR_NONE;
-       }
-
-      data->dofs = data->hofs + sizeof (hd) + hd.namesize;
-      *ofs = data->dofs + data->size;
-      if (data->size & 1)
-       (*ofs)++;
-#else
-      struct head hd;
-
-      if (grub_disk_read
-         (data->disk, 0, data->hofs, sizeof (hd), &hd))
-       return grub_errno;
-
-      if (!hd.name[0])
-       {
-         *ofs = 0;
-         return GRUB_ERR_NONE;
-       }
-
-      if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1))
-       return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive");
-
-      if ((*name = grub_strdup (hd.name)) == NULL)
-       return grub_errno;
-
-      data->size = grub_strtoul (hd.size, NULL, 8);
-      data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE;
-      *ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) &
-                          ~(GRUB_DISK_SECTOR_SIZE - 1));
-#endif
-  return GRUB_ERR_NONE;
-}
-
-static struct grub_cpio_data *
-grub_cpio_mount (grub_disk_t disk)
-{
-  struct head hd;
-  struct grub_cpio_data *data;
-
-  if (grub_disk_read (disk, 0, 0, sizeof (hd), &hd))
-    goto fail;
-
-#ifndef MODE_USTAR
-  if (hd.magic != MAGIC_BCPIO)
-#else
-  if (grub_memcmp (hd.magic, MAGIC_USTAR,
-                  sizeof (MAGIC_USTAR) - 1))
-#endif
-    goto fail;
-
-  data = (struct grub_cpio_data *) grub_malloc (sizeof (*data));
-  if (!data)
-    goto fail;
-
-  data->disk = disk;
-
-  return data;
-
-fail:
-  grub_error (GRUB_ERR_BAD_FS, "not a "
-#ifdef MODE_USTAR
-             "tar"
-#else
-             "cpio"
-#endif
-             " filesystem");
-  return 0;
-}
-
-static grub_err_t
-grub_cpio_dir (grub_device_t device, const char *path,
-              int (*hook) (const char *filename,
-                           const struct grub_dirhook_info *info))
-{
-  struct grub_cpio_data *data;
-  grub_uint32_t ofs;
-  char *prev, *name;
-  const char *np;
-  int len;
-
-  grub_dl_ref (my_mod);
-
-  prev = 0;
-
-  data = grub_cpio_mount (device->disk);
-  if (!data)
-    goto fail;
-
-  np = path + 1;
-  len = grub_strlen (path) - 1;
-
-  data->hofs = 0;
-  while (1)
-    {
-      if (grub_cpio_find_file (data, &name, &ofs))
-       goto fail;
-
-      if (!ofs)
-       break;
-
-      if (grub_memcmp (np, name, len) == 0)
-       {
-         char *p, *n;
-
-         n = name + len;
-         if (*n == '/')
-           n++;
-
-         p = grub_strchr (name + len, '/');
-         if (p)
-           *p = 0;
-
-         if ((!prev) || (grub_strcmp (prev, name) != 0))
-           {
-             struct grub_dirhook_info info;
-             grub_memset (&info, 0, sizeof (info));
-             info.dir = (p != NULL);
-
-             hook (name + len, &info);
-             if (prev)
-               grub_free (prev);
-             prev = name;
-           }
-         else
-           grub_free (name);
-       }
-      data->hofs = ofs;
-    }
-
-fail:
-
-  if (prev)
-    grub_free (prev);
-
-  if (data)
-    grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_cpio_open (grub_file_t file, const char *name)
-{
-  struct grub_cpio_data *data;
-  grub_uint32_t ofs;
-  char *fn;
-  int i, j;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_cpio_mount (file->device->disk);
-  if (!data)
-    goto fail;
-
-  data->hofs = 0;
-  while (1)
-    {
-      if (grub_cpio_find_file (data, &fn, &ofs))
-       goto fail;
-
-      if (!ofs)
-       {
-         grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
-         break;
-       }
-
-      /* Compare NAME and FN by hand in order to cope with duplicate
-        slashes.  */
-      i = 0;
-      j = 0;
-      while (name[i] == '/')
-       i++;
-      while (1)
-       {
-         if (name[i] != fn[j])
-           goto no_match;
-
-         if (name[i] == '\0')
-           break;
-
-         while (name[i] == '/' && name[i+1] == '/')
-           i++;
-
-         i++;
-         j++;
-       }
-
-      if (name[i] != fn[j])
-       goto no_match;
-
-      file->data = data;
-      file->size = data->size;
-      grub_free (fn);
-
-      return GRUB_ERR_NONE;
-
-    no_match:
-
-      grub_free (fn);
-      data->hofs = ofs;
-    }
-
-fail:
-
-  if (data)
-    grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_ssize_t
-grub_cpio_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_cpio_data *data;
-
-  data = file->data;
-  return (grub_disk_read (data->disk, 0, data->dofs + file->offset,
-                         len, buf)) ? -1 : (grub_ssize_t) len;
-}
-
-static grub_err_t
-grub_cpio_close (grub_file_t file)
-{
-  grub_free (file->data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static struct grub_fs grub_cpio_fs = {
-#ifdef MODE_USTAR
-  .name = "tarfs",
-#else
-  .name = "cpiofs",
-#endif
-  .dir = grub_cpio_dir,
-  .open = grub_cpio_open,
-  .read = grub_cpio_read,
-  .close = grub_cpio_close,
-};
-
-#ifdef MODE_USTAR
-GRUB_MOD_INIT (tar)
-#else
-GRUB_MOD_INIT (cpio)
-#endif
-{
-  grub_fs_register (&grub_cpio_fs);
-  my_mod = mod;
-}
-
-#ifdef MODE_USTAR
-GRUB_MOD_FINI (tar)
-#else
-GRUB_MOD_FINI (cpio)
-#endif
-{
-  grub_fs_unregister (&grub_cpio_fs);
-}
diff --git a/fs/ext2.c b/fs/ext2.c
deleted file mode 100644 (file)
index f2fec82..0000000
--- a/fs/ext2.c
+++ /dev/null
@@ -1,951 +0,0 @@
-/* ext2.c - Second Extended filesystem */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Magic value used to identify an ext2 filesystem.  */
-#define        EXT2_MAGIC              0xEF53
-/* Amount of indirect blocks in an inode.  */
-#define INDIRECT_BLOCKS                12
-/* Maximum length of a pathname.  */
-#define EXT2_PATH_MAX          4096
-/* Maximum nesting of symlinks, used to prevent a loop.  */
-#define        EXT2_MAX_SYMLINKCNT     8
-
-/* The good old revision and the default inode size.  */
-#define EXT2_GOOD_OLD_REVISION         0
-#define EXT2_GOOD_OLD_INODE_SIZE       128
-
-/* Filetype used in directory entry.  */
-#define        FILETYPE_UNKNOWN        0
-#define        FILETYPE_REG            1
-#define        FILETYPE_DIRECTORY      2
-#define        FILETYPE_SYMLINK        7
-
-/* Filetype information as used in inodes.  */
-#define FILETYPE_INO_MASK      0170000
-#define FILETYPE_INO_REG       0100000
-#define FILETYPE_INO_DIRECTORY 0040000
-#define FILETYPE_INO_SYMLINK   0120000
-
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/types.h>
-#include <grub/fshelp.h>
-
-/* Log2 size of ext2 block in 512 blocks.  */
-#define LOG2_EXT2_BLOCK_SIZE(data)                     \
-       (grub_le_to_cpu32 (data->sblock.log2_block_size) + 1)
-
-/* Log2 size of ext2 block in bytes.  */
-#define LOG2_BLOCK_SIZE(data)                                  \
-       (grub_le_to_cpu32 (data->sblock.log2_block_size) + 10)
-
-/* The size of an ext2 block in bytes.  */
-#define EXT2_BLOCK_SIZE(data)          (1 << LOG2_BLOCK_SIZE (data))
-
-/* The revision level.  */
-#define EXT2_REVISION(data)    grub_le_to_cpu32 (data->sblock.revision_level)
-
-/* The inode size.  */
-#define EXT2_INODE_SIZE(data)  \
-        (EXT2_REVISION (data) == EXT2_GOOD_OLD_REVISION \
-         ? EXT2_GOOD_OLD_INODE_SIZE \
-         : grub_le_to_cpu16 (data->sblock.inode_size))
-
-/* Superblock filesystem feature flags (RW compatible)
- * A filesystem with any of these enabled can be read and written by a driver
- * that does not understand them without causing metadata/data corruption.  */
-#define EXT2_FEATURE_COMPAT_DIR_PREALLOC       0x0001
-#define EXT2_FEATURE_COMPAT_IMAGIC_INODES      0x0002
-#define EXT3_FEATURE_COMPAT_HAS_JOURNAL                0x0004
-#define EXT2_FEATURE_COMPAT_EXT_ATTR           0x0008
-#define EXT2_FEATURE_COMPAT_RESIZE_INODE       0x0010
-#define EXT2_FEATURE_COMPAT_DIR_INDEX          0x0020
-/* Superblock filesystem feature flags (RO compatible)
- * A filesystem with any of these enabled can be safely read by a driver that
- * does not understand them, but should not be written to, usually because
- * additional metadata is required.  */
-#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
-#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
-#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR       0x0004
-#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM                0x0010
-#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK       0x0020
-#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE     0x0040
-/* Superblock filesystem feature flags (back-incompatible)
- * A filesystem with any of these enabled should not be attempted to be read
- * by a driver that does not understand them, since they usually indicate
- * metadata format changes that might confuse the reader.  */
-#define EXT2_FEATURE_INCOMPAT_COMPRESSION      0x0001
-#define EXT2_FEATURE_INCOMPAT_FILETYPE         0x0002
-#define EXT3_FEATURE_INCOMPAT_RECOVER          0x0004 /* Needs recovery */
-#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV      0x0008 /* Volume is journal device */
-#define EXT2_FEATURE_INCOMPAT_META_BG          0x0010
-#define EXT4_FEATURE_INCOMPAT_EXTENTS          0x0040 /* Extents used */
-#define EXT4_FEATURE_INCOMPAT_64BIT            0x0080
-#define EXT4_FEATURE_INCOMPAT_FLEX_BG          0x0200
-
-/* The set of back-incompatible features this driver DOES support. Add (OR)
- * flags here as the related features are implemented into the driver.  */
-#define EXT2_DRIVER_SUPPORTED_INCOMPAT ( EXT2_FEATURE_INCOMPAT_FILETYPE \
-                                       | EXT4_FEATURE_INCOMPAT_EXTENTS  \
-                                       | EXT4_FEATURE_INCOMPAT_FLEX_BG )
-/* List of rationales for the ignored "incompatible" features:
- * needs_recovery: Not really back-incompatible - was added as such to forbid
- *                 ext2 drivers from mounting an ext3 volume with a dirty
- *                 journal because they will ignore the journal, but the next
- *                 ext3 driver to mount the volume will find the journal and
- *                 replay it, potentially corrupting the metadata written by
- *                 the ext2 drivers. Safe to ignore for this RO driver.  */
-#define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER )
-
-
-#define EXT3_JOURNAL_MAGIC_NUMBER      0xc03b3998U
-
-#define EXT3_JOURNAL_DESCRIPTOR_BLOCK  1
-#define EXT3_JOURNAL_COMMIT_BLOCK      2
-#define EXT3_JOURNAL_SUPERBLOCK_V1     3
-#define EXT3_JOURNAL_SUPERBLOCK_V2     4
-#define EXT3_JOURNAL_REVOKE_BLOCK      5
-
-#define EXT3_JOURNAL_FLAG_ESCAPE       1
-#define EXT3_JOURNAL_FLAG_SAME_UUID    2
-#define EXT3_JOURNAL_FLAG_DELETED      4
-#define EXT3_JOURNAL_FLAG_LAST_TAG     8
-
-#define EXT4_EXTENTS_FLAG              0x80000
-
-/* The ext2 superblock.  */
-struct grub_ext2_sblock
-{
-  grub_uint32_t total_inodes;
-  grub_uint32_t total_blocks;
-  grub_uint32_t reserved_blocks;
-  grub_uint32_t free_blocks;
-  grub_uint32_t free_inodes;
-  grub_uint32_t first_data_block;
-  grub_uint32_t log2_block_size;
-  grub_uint32_t log2_fragment_size;
-  grub_uint32_t blocks_per_group;
-  grub_uint32_t fragments_per_group;
-  grub_uint32_t inodes_per_group;
-  grub_uint32_t mtime;
-  grub_uint32_t utime;
-  grub_uint16_t mnt_count;
-  grub_uint16_t max_mnt_count;
-  grub_uint16_t magic;
-  grub_uint16_t fs_state;
-  grub_uint16_t error_handling;
-  grub_uint16_t minor_revision_level;
-  grub_uint32_t lastcheck;
-  grub_uint32_t checkinterval;
-  grub_uint32_t creator_os;
-  grub_uint32_t revision_level;
-  grub_uint16_t uid_reserved;
-  grub_uint16_t gid_reserved;
-  grub_uint32_t first_inode;
-  grub_uint16_t inode_size;
-  grub_uint16_t block_group_number;
-  grub_uint32_t feature_compatibility;
-  grub_uint32_t feature_incompat;
-  grub_uint32_t feature_ro_compat;
-  grub_uint16_t uuid[8];
-  char volume_name[16];
-  char last_mounted_on[64];
-  grub_uint32_t compression_info;
-  grub_uint8_t prealloc_blocks;
-  grub_uint8_t prealloc_dir_blocks;
-  grub_uint16_t reserved_gdt_blocks;
-  grub_uint8_t journal_uuid[16];
-  grub_uint32_t journal_inum;
-  grub_uint32_t journal_dev;
-  grub_uint32_t last_orphan;
-  grub_uint32_t hash_seed[4];
-  grub_uint8_t def_hash_version;
-  grub_uint8_t jnl_backup_type;
-  grub_uint16_t reserved_word_pad;
-  grub_uint32_t default_mount_opts;
-  grub_uint32_t first_meta_bg;
-  grub_uint32_t mkfs_time;
-  grub_uint32_t jnl_blocks[17];
-};
-
-/* The ext2 blockgroup.  */
-struct grub_ext2_block_group
-{
-  grub_uint32_t block_id;
-  grub_uint32_t inode_id;
-  grub_uint32_t inode_table_id;
-  grub_uint16_t free_blocks;
-  grub_uint16_t free_inodes;
-  grub_uint16_t used_dirs;
-  grub_uint16_t pad;
-  grub_uint32_t reserved[3];
-};
-
-/* The ext2 inode.  */
-struct grub_ext2_inode
-{
-  grub_uint16_t mode;
-  grub_uint16_t uid;
-  grub_uint32_t size;
-  grub_uint32_t atime;
-  grub_uint32_t ctime;
-  grub_uint32_t mtime;
-  grub_uint32_t dtime;
-  grub_uint16_t gid;
-  grub_uint16_t nlinks;
-  grub_uint32_t blockcnt;  /* Blocks of 512 bytes!! */
-  grub_uint32_t flags;
-  grub_uint32_t osd1;
-  union
-  {
-    struct datablocks
-    {
-      grub_uint32_t dir_blocks[INDIRECT_BLOCKS];
-      grub_uint32_t indir_block;
-      grub_uint32_t double_indir_block;
-      grub_uint32_t triple_indir_block;
-    } blocks;
-    char symlink[60];
-  };
-  grub_uint32_t version;
-  grub_uint32_t acl;
-  grub_uint32_t dir_acl;
-  grub_uint32_t fragment_addr;
-  grub_uint32_t osd2[3];
-};
-
-/* The header of an ext2 directory entry.  */
-struct ext2_dirent
-{
-  grub_uint32_t inode;
-  grub_uint16_t direntlen;
-  grub_uint8_t namelen;
-  grub_uint8_t filetype;
-};
-
-struct grub_ext3_journal_header
-{
-  grub_uint32_t magic;
-  grub_uint32_t block_type;
-  grub_uint32_t sequence;
-};
-
-struct grub_ext3_journal_revoke_header
-{
-  struct grub_ext3_journal_header header;
-  grub_uint32_t count;
-  grub_uint32_t data[0];
-};
-
-struct grub_ext3_journal_block_tag
-{
-  grub_uint32_t block;
-  grub_uint32_t flags;
-};
-
-struct grub_ext3_journal_sblock
-{
-  struct grub_ext3_journal_header header;
-  grub_uint32_t block_size;
-  grub_uint32_t maxlen;
-  grub_uint32_t first;
-  grub_uint32_t sequence;
-  grub_uint32_t start;
-};
-
-#define EXT4_EXT_MAGIC         0xf30a
-
-struct grub_ext4_extent_header
-{
-  grub_uint16_t magic;
-  grub_uint16_t entries;
-  grub_uint16_t max;
-  grub_uint16_t depth;
-  grub_uint32_t generation;
-};
-
-struct grub_ext4_extent
-{
-  grub_uint32_t block;
-  grub_uint16_t len;
-  grub_uint16_t start_hi;
-  grub_uint32_t start;
-};
-
-struct grub_ext4_extent_idx
-{
-  grub_uint32_t block;
-  grub_uint32_t leaf;
-  grub_uint16_t leaf_hi;
-  grub_uint16_t unused;
-};
-
-struct grub_fshelp_node
-{
-  struct grub_ext2_data *data;
-  struct grub_ext2_inode inode;
-  int ino;
-  int inode_read;
-};
-
-/* Information about a "mounted" ext2 filesystem.  */
-struct grub_ext2_data
-{
-  struct grub_ext2_sblock sblock;
-  grub_disk_t disk;
-  struct grub_ext2_inode *inode;
-  struct grub_fshelp_node diropen;
-};
-
-static grub_dl_t my_mod;
-
-\f
-
-/* Read into BLKGRP the blockgroup descriptor of blockgroup GROUP of
-   the mounted filesystem DATA.  */
-inline static grub_err_t
-grub_ext2_blockgroup (struct grub_ext2_data *data, int group,
-                     struct grub_ext2_block_group *blkgrp)
-{
-  return grub_disk_read (data->disk,
-                         ((grub_le_to_cpu32 (data->sblock.first_data_block) + 1)
-                          << LOG2_EXT2_BLOCK_SIZE (data)),
-                        group * sizeof (struct grub_ext2_block_group),
-                        sizeof (struct grub_ext2_block_group), blkgrp);
-}
-
-static struct grub_ext4_extent_header *
-grub_ext4_find_leaf (struct grub_ext2_data *data, char *buf,
-                     struct grub_ext4_extent_header *ext_block,
-                     grub_uint32_t fileblock)
-{
-  struct grub_ext4_extent_idx *index;
-
-  while (1)
-    {
-      int i;
-      grub_disk_addr_t block;
-
-      index = (struct grub_ext4_extent_idx *) (ext_block + 1);
-
-      if (grub_le_to_cpu16(ext_block->magic) != EXT4_EXT_MAGIC)
-        return 0;
-
-      if (ext_block->depth == 0)
-        return ext_block;
-
-      for (i = 0; i < grub_le_to_cpu16 (ext_block->entries); i++)
-        {
-          if (fileblock < grub_le_to_cpu32(index[i].block))
-            break;
-        }
-
-      if (--i < 0)
-        return 0;
-
-      block = grub_le_to_cpu16 (index[i].leaf_hi);
-      block = (block << 32) + grub_le_to_cpu32 (index[i].leaf);
-      if (grub_disk_read (data->disk,
-                          block << LOG2_EXT2_BLOCK_SIZE (data),
-                          0, EXT2_BLOCK_SIZE(data), buf))
-        return 0;
-
-      ext_block = (struct grub_ext4_extent_header *) buf;
-    }
-}
-
-static grub_disk_addr_t
-grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
-{
-  struct grub_ext2_data *data = node->data;
-  struct grub_ext2_inode *inode = &node->inode;
-  int blknr = -1;
-  unsigned int blksz = EXT2_BLOCK_SIZE (data);
-  int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data);
-
-  if (grub_le_to_cpu32(inode->flags) & EXT4_EXTENTS_FLAG)
-    {
-      char buf[EXT2_BLOCK_SIZE(data)];
-      struct grub_ext4_extent_header *leaf;
-      struct grub_ext4_extent *ext;
-      int i;
-
-      leaf = grub_ext4_find_leaf (data, buf,
-                                  (struct grub_ext4_extent_header *) inode->blocks.dir_blocks,
-                                  fileblock);
-      if (! leaf)
-        {
-          grub_error (GRUB_ERR_BAD_FS, "invalid extent");
-          return -1;
-        }
-
-      ext = (struct grub_ext4_extent *) (leaf + 1);
-      for (i = 0; i < grub_le_to_cpu16 (leaf->entries); i++)
-        {
-          if (fileblock < grub_le_to_cpu32 (ext[i].block))
-            break;
-        }
-
-      if (--i >= 0)
-        {
-          fileblock -= grub_le_to_cpu32 (ext[i].block);
-          if (fileblock >= grub_le_to_cpu16 (ext[i].len))
-            return 0;
-          else
-            {
-              grub_disk_addr_t start;
-
-              start = grub_le_to_cpu16 (ext[i].start_hi);
-              start = (start << 32) + grub_le_to_cpu32 (ext[i].start);
-
-              return fileblock + start;
-            }
-        }
-      else
-        {
-          grub_error (GRUB_ERR_BAD_FS, "something wrong with extent");
-          return -1;
-        }
-    }
-  /* Direct blocks.  */
-  if (fileblock < INDIRECT_BLOCKS)
-    blknr = grub_le_to_cpu32 (inode->blocks.dir_blocks[fileblock]);
-  /* Indirect.  */
-  else if (fileblock < INDIRECT_BLOCKS + blksz / 4)
-    {
-      grub_uint32_t indir[blksz / 4];
-
-      if (grub_disk_read (data->disk,
-                         ((grub_disk_addr_t)
-                          grub_le_to_cpu32 (inode->blocks.indir_block))
-                         << log2_blksz,
-                         0, blksz, indir))
-       return grub_errno;
-
-      blknr = grub_le_to_cpu32 (indir[fileblock - INDIRECT_BLOCKS]);
-    }
-  /* Double indirect.  */
-  else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * (blksz / 4 + 1))
-    {
-      unsigned int perblock = blksz / 4;
-      unsigned int rblock = fileblock - (INDIRECT_BLOCKS
-                                        + blksz / 4);
-      grub_uint32_t indir[blksz / 4];
-
-      if (grub_disk_read (data->disk,
-                         ((grub_disk_addr_t)
-                          grub_le_to_cpu32 (inode->blocks.double_indir_block))
-                         << log2_blksz,
-                         0, blksz, indir))
-       return grub_errno;
-
-      if (grub_disk_read (data->disk,
-                         ((grub_disk_addr_t)
-                          grub_le_to_cpu32 (indir[rblock / perblock]))
-                         << log2_blksz,
-                         0, blksz, indir))
-       return grub_errno;
-
-
-      blknr = grub_le_to_cpu32 (indir[rblock % perblock]);
-    }
-  /* triple indirect.  */
-  else
-    {
-      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                 "ext2fs doesn't support triple indirect blocks");
-    }
-
-  return blknr;
-}
-
-/* Read LEN bytes from the file described by DATA starting with byte
-   POS.  Return the amount of read bytes in READ.  */
-static grub_ssize_t
-grub_ext2_read_file (grub_fshelp_node_t node,
-                    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                       unsigned offset, unsigned length),
-                    int pos, grub_size_t len, char *buf)
-{
-  return grub_fshelp_read_file (node->data->disk, node, read_hook,
-                               pos, len, buf, grub_ext2_read_block,
-                               node->inode.size,
-                               LOG2_EXT2_BLOCK_SIZE (node->data));
-
-}
-
-
-/* Read the inode INO for the file described by DATA into INODE.  */
-static grub_err_t
-grub_ext2_read_inode (struct grub_ext2_data *data,
-                     int ino, struct grub_ext2_inode *inode)
-{
-  struct grub_ext2_block_group blkgrp;
-  struct grub_ext2_sblock *sblock = &data->sblock;
-  int inodes_per_block;
-  unsigned int blkno;
-  unsigned int blkoff;
-
-  /* It is easier to calculate if the first inode is 0.  */
-  ino--;
-
-  grub_ext2_blockgroup (data,
-                        ino / grub_le_to_cpu32 (sblock->inodes_per_group),
-                       &blkgrp);
-  if (grub_errno)
-    return grub_errno;
-
-  inodes_per_block = EXT2_BLOCK_SIZE (data) / EXT2_INODE_SIZE (data);
-  blkno = (ino % grub_le_to_cpu32 (sblock->inodes_per_group))
-    / inodes_per_block;
-  blkoff = (ino % grub_le_to_cpu32 (sblock->inodes_per_group))
-    % inodes_per_block;
-
-  /* Read the inode.  */
-  if (grub_disk_read (data->disk,
-                     ((grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno)
-                       << LOG2_EXT2_BLOCK_SIZE (data)),
-                     EXT2_INODE_SIZE (data) * blkoff,
-                     sizeof (struct grub_ext2_inode), inode))
-    return grub_errno;
-
-  return 0;
-}
-
-static struct grub_ext2_data *
-grub_ext2_mount (grub_disk_t disk)
-{
-  struct grub_ext2_data *data;
-
-  data = grub_malloc (sizeof (struct grub_ext2_data));
-  if (!data)
-    return 0;
-
-  /* Read the superblock.  */
-  grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_ext2_sblock),
-                  &data->sblock);
-  if (grub_errno)
-    goto fail;
-
-  /* Make sure this is an ext2 filesystem.  */
-  if (grub_le_to_cpu16 (data->sblock.magic) != EXT2_MAGIC)
-    {
-      grub_error (GRUB_ERR_BAD_FS, "not an ext2 filesystem");
-      goto fail;
-    }
-
-  /* Check the FS doesn't have feature bits enabled that we don't support. */
-  if (grub_le_to_cpu32 (data->sblock.feature_incompat)
-        & ~(EXT2_DRIVER_SUPPORTED_INCOMPAT | EXT2_DRIVER_IGNORED_INCOMPAT))
-    {
-      grub_error (GRUB_ERR_BAD_FS, "filesystem has unsupported incompatible features");
-      goto fail;
-    }
-
-
-  data->disk = disk;
-
-  data->diropen.data = data;
-  data->diropen.ino = 2;
-  data->diropen.inode_read = 1;
-
-  data->inode = &data->diropen.inode;
-
-  grub_ext2_read_inode (data, 2, data->inode);
-  if (grub_errno)
-    goto fail;
-
-  return data;
-
- fail:
-  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
-    grub_error (GRUB_ERR_BAD_FS, "not an ext2 filesystem");
-
-  grub_free (data);
-  return 0;
-}
-
-static char *
-grub_ext2_read_symlink (grub_fshelp_node_t node)
-{
-  char *symlink;
-  struct grub_fshelp_node *diro = node;
-
-  if (! diro->inode_read)
-    {
-      grub_ext2_read_inode (diro->data, diro->ino, &diro->inode);
-      if (grub_errno)
-       return 0;
-    }
-
-  symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1);
-  if (! symlink)
-    return 0;
-
-  /* If the filesize of the symlink is bigger than
-     60 the symlink is stored in a separate block,
-     otherwise it is stored in the inode.  */
-  if (grub_le_to_cpu32 (diro->inode.size) <= 60)
-    grub_strncpy (symlink,
-                 diro->inode.symlink,
-                 grub_le_to_cpu32 (diro->inode.size));
-  else
-    {
-      grub_ext2_read_file (diro, 0, 0,
-                          grub_le_to_cpu32 (diro->inode.size),
-                          symlink);
-      if (grub_errno)
-       {
-         grub_free (symlink);
-         return 0;
-       }
-    }
-
-  symlink[grub_le_to_cpu32 (diro->inode.size)] = '\0';
-  return symlink;
-}
-
-static int
-grub_ext2_iterate_dir (grub_fshelp_node_t dir,
-                      int NESTED_FUNC_ATTR
-                      (*hook) (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node))
-{
-  unsigned int fpos = 0;
-  struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
-
-  if (! diro->inode_read)
-    {
-      grub_ext2_read_inode (diro->data, diro->ino, &diro->inode);
-      if (grub_errno)
-       return 0;
-    }
-
-  /* Search the file.  */
-  while (fpos < grub_le_to_cpu32 (diro->inode.size))
-    {
-      struct ext2_dirent dirent;
-
-      grub_ext2_read_file (diro, 0, fpos, sizeof (struct ext2_dirent),
-                          (char *) &dirent);
-      if (grub_errno)
-       return 0;
-
-      if (dirent.direntlen == 0)
-        return 0;
-
-      if (dirent.namelen != 0)
-       {
-         char filename[dirent.namelen + 1];
-         struct grub_fshelp_node *fdiro;
-         enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN;
-
-         grub_ext2_read_file (diro, 0, fpos + sizeof (struct ext2_dirent),
-                              dirent.namelen, filename);
-         if (grub_errno)
-           return 0;
-
-         fdiro = grub_malloc (sizeof (struct grub_fshelp_node));
-         if (! fdiro)
-           return 0;
-
-         fdiro->data = diro->data;
-         fdiro->ino = grub_le_to_cpu32 (dirent.inode);
-
-         filename[dirent.namelen] = '\0';
-
-         if (dirent.filetype != FILETYPE_UNKNOWN)
-           {
-             fdiro->inode_read = 0;
-
-             if (dirent.filetype == FILETYPE_DIRECTORY)
-               type = GRUB_FSHELP_DIR;
-             else if (dirent.filetype == FILETYPE_SYMLINK)
-               type = GRUB_FSHELP_SYMLINK;
-             else if (dirent.filetype == FILETYPE_REG)
-               type = GRUB_FSHELP_REG;
-           }
-         else
-           {
-             /* The filetype can not be read from the dirent, read
-                the inode to get more information.  */
-             grub_ext2_read_inode (diro->data,
-                                    grub_le_to_cpu32 (dirent.inode),
-                                   &fdiro->inode);
-             if (grub_errno)
-               {
-                 grub_free (fdiro);
-                 return 0;
-               }
-
-             fdiro->inode_read = 1;
-
-             if ((grub_le_to_cpu16 (fdiro->inode.mode)
-                  & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY)
-               type = GRUB_FSHELP_DIR;
-             else if ((grub_le_to_cpu16 (fdiro->inode.mode)
-                       & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK)
-               type = GRUB_FSHELP_SYMLINK;
-             else if ((grub_le_to_cpu16 (fdiro->inode.mode)
-                       & FILETYPE_INO_MASK) == FILETYPE_INO_REG)
-               type = GRUB_FSHELP_REG;
-           }
-
-         if (hook (filename, type, fdiro))
-           return 1;
-       }
-
-      fpos += grub_le_to_cpu16 (dirent.direntlen);
-    }
-
-  return 0;
-}
-
-/* Open a file named NAME and initialize FILE.  */
-static grub_err_t
-grub_ext2_open (struct grub_file *file, const char *name)
-{
-  struct grub_ext2_data *data;
-  struct grub_fshelp_node *fdiro = 0;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_ext2_mount (file->device->disk);
-  if (! data)
-    goto fail;
-
-  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_ext2_iterate_dir,
-                        grub_ext2_read_symlink, GRUB_FSHELP_REG);
-  if (grub_errno)
-    goto fail;
-
-  if (! fdiro->inode_read)
-    {
-      grub_ext2_read_inode (data, fdiro->ino, &fdiro->inode);
-      if (grub_errno)
-       goto fail;
-    }
-
-  grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_ext2_inode));
-  grub_free (fdiro);
-
-  file->size = grub_le_to_cpu32 (data->inode->size);
-  file->data = data;
-  file->offset = 0;
-
-  return 0;
-
- fail:
-  if (fdiro != &data->diropen)
-    grub_free (fdiro);
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_ext2_close (grub_file_t file)
-{
-  grub_free (file->data);
-
-  grub_dl_unref (my_mod);
-
-  return GRUB_ERR_NONE;
-}
-
-/* Read LEN bytes data from FILE into BUF.  */
-static grub_ssize_t
-grub_ext2_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_ext2_data *data = (struct grub_ext2_data *) file->data;
-
-  return grub_ext2_read_file (&data->diropen, file->read_hook,
-                             file->offset, len, buf);
-}
-
-
-static grub_err_t
-grub_ext2_dir (grub_device_t device, const char *path,
-              int (*hook) (const char *filename,
-                           const struct grub_dirhook_info *info))
-{
-  struct grub_ext2_data *data = 0;
-  struct grub_fshelp_node *fdiro = 0;
-
-  auto int NESTED_FUNC_ATTR iterate (const char *filename,
-                                    enum grub_fshelp_filetype filetype,
-                                    grub_fshelp_node_t node);
-
-  int NESTED_FUNC_ATTR iterate (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node)
-    {
-      struct grub_dirhook_info info;
-      grub_memset (&info, 0, sizeof (info));
-      if (! node->inode_read)
-       {
-         grub_ext2_read_inode (data, node->ino, &node->inode);
-         if (!grub_errno)
-           node->inode_read = 1;
-         grub_errno = GRUB_ERR_NONE;
-       }
-      if (node->inode_read)
-       {
-         info.mtimeset = 1;
-         info.mtime = grub_le_to_cpu32 (node->inode.mtime);
-       }
-
-      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
-      grub_free (node);
-      return hook (filename, &info);
-    }
-
-  grub_dl_ref (my_mod);
-
-  data = grub_ext2_mount (device->disk);
-  if (! data)
-    goto fail;
-
-  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_ext2_iterate_dir,
-                        grub_ext2_read_symlink, GRUB_FSHELP_DIR);
-  if (grub_errno)
-    goto fail;
-
-  grub_ext2_iterate_dir (fdiro, iterate);
-
- fail:
-  if (fdiro != &data->diropen)
-    grub_free (fdiro);
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_ext2_label (grub_device_t device, char **label)
-{
-  struct grub_ext2_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_ext2_mount (disk);
-  if (data)
-    *label = grub_strndup (data->sblock.volume_name, 14);
-  else
-    *label = NULL;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_ext2_uuid (grub_device_t device, char **uuid)
-{
-  struct grub_ext2_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_ext2_mount (disk);
-  if (data)
-    {
-      *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
-                            grub_be_to_cpu16 (data->sblock.uuid[0]),
-                            grub_be_to_cpu16 (data->sblock.uuid[1]),
-                            grub_be_to_cpu16 (data->sblock.uuid[2]),
-                            grub_be_to_cpu16 (data->sblock.uuid[3]),
-                            grub_be_to_cpu16 (data->sblock.uuid[4]),
-                            grub_be_to_cpu16 (data->sblock.uuid[5]),
-                            grub_be_to_cpu16 (data->sblock.uuid[6]),
-                            grub_be_to_cpu16 (data->sblock.uuid[7]));
-    }
-  else
-    *uuid = NULL;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-/* Get mtime.  */
-static grub_err_t
-grub_ext2_mtime (grub_device_t device, grub_int32_t *tm)
-{
-  struct grub_ext2_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_ext2_mount (disk);
-  if (!data)
-    *tm = 0;
-  else
-    *tm = grub_le_to_cpu32 (data->sblock.utime);
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-
-}
-
-
-\f
-static struct grub_fs grub_ext2_fs =
-  {
-    .name = "ext2",
-    .dir = grub_ext2_dir,
-    .open = grub_ext2_open,
-    .read = grub_ext2_read,
-    .close = grub_ext2_close,
-    .label = grub_ext2_label,
-    .uuid = grub_ext2_uuid,
-    .mtime = grub_ext2_mtime,
-#ifdef GRUB_UTIL
-    .reserved_first_sector = 1,
-#endif
-    .next = 0
-  };
-
-GRUB_MOD_INIT(ext2)
-{
-  grub_fs_register (&grub_ext2_fs);
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(ext2)
-{
-  grub_fs_unregister (&grub_ext2_fs);
-}
diff --git a/fs/fat.c b/fs/fat.c
deleted file mode 100644 (file)
index 8905094..0000000
--- a/fs/fat.c
+++ /dev/null
@@ -1,876 +0,0 @@
-/* fat.c - FAT filesystem */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/fs.h>
-#include <grub/disk.h>
-#include <grub/file.h>
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/charset.h>
-
-#define GRUB_FAT_DIR_ENTRY_SIZE        32
-
-#define GRUB_FAT_ATTR_READ_ONLY        0x01
-#define GRUB_FAT_ATTR_HIDDEN   0x02
-#define GRUB_FAT_ATTR_SYSTEM   0x04
-#define GRUB_FAT_ATTR_VOLUME_ID        0x08
-#define GRUB_FAT_ATTR_DIRECTORY        0x10
-#define GRUB_FAT_ATTR_ARCHIVE  0x20
-
-#define GRUB_FAT_MAXFILE       256
-
-#define GRUB_FAT_ATTR_LONG_NAME        (GRUB_FAT_ATTR_READ_ONLY \
-                                | GRUB_FAT_ATTR_HIDDEN \
-                                | GRUB_FAT_ATTR_SYSTEM \
-                                | GRUB_FAT_ATTR_VOLUME_ID)
-#define GRUB_FAT_ATTR_VALID    (GRUB_FAT_ATTR_READ_ONLY \
-                                | GRUB_FAT_ATTR_HIDDEN \
-                                | GRUB_FAT_ATTR_SYSTEM \
-                                | GRUB_FAT_ATTR_DIRECTORY \
-                                | GRUB_FAT_ATTR_ARCHIVE \
-                                | GRUB_FAT_ATTR_VOLUME_ID)
-
-struct grub_fat_bpb
-{
-  grub_uint8_t jmp_boot[3];
-  grub_uint8_t oem_name[8];
-  grub_uint16_t bytes_per_sector;
-  grub_uint8_t sectors_per_cluster;
-  grub_uint16_t num_reserved_sectors;
-  grub_uint8_t num_fats;
-  grub_uint16_t num_root_entries;
-  grub_uint16_t num_total_sectors_16;
-  grub_uint8_t media;
-  grub_uint16_t sectors_per_fat_16;
-  grub_uint16_t sectors_per_track;
-  grub_uint16_t num_heads;
-  grub_uint32_t num_hidden_sectors;
-  grub_uint32_t num_total_sectors_32;
-  union
-  {
-    struct
-    {
-      grub_uint8_t num_ph_drive;
-      grub_uint8_t reserved;
-      grub_uint8_t boot_sig;
-      grub_uint32_t num_serial;
-      grub_uint8_t label[11];
-      grub_uint8_t fstype[8];
-    } __attribute__ ((packed)) fat12_or_fat16;
-    struct
-    {
-      grub_uint32_t sectors_per_fat_32;
-      grub_uint16_t extended_flags;
-      grub_uint16_t fs_version;
-      grub_uint32_t root_cluster;
-      grub_uint16_t fs_info;
-      grub_uint16_t backup_boot_sector;
-      grub_uint8_t reserved[12];
-      grub_uint8_t num_ph_drive;
-      grub_uint8_t reserved1;
-      grub_uint8_t boot_sig;
-      grub_uint32_t num_serial;
-      grub_uint8_t label[11];
-      grub_uint8_t fstype[8];
-    } __attribute__ ((packed)) fat32;
-  } __attribute__ ((packed)) version_specific;
-} __attribute__ ((packed));
-
-struct grub_fat_dir_entry
-{
-  grub_uint8_t name[11];
-  grub_uint8_t attr;
-  grub_uint8_t nt_reserved;
-  grub_uint8_t c_time_tenth;
-  grub_uint16_t c_time;
-  grub_uint16_t c_date;
-  grub_uint16_t a_date;
-  grub_uint16_t first_cluster_high;
-  grub_uint16_t w_time;
-  grub_uint16_t w_date;
-  grub_uint16_t first_cluster_low;
-  grub_uint32_t file_size;
-} __attribute__ ((packed));
-
-struct grub_fat_long_name_entry
-{
-  grub_uint8_t id;
-  grub_uint16_t name1[5];
-  grub_uint8_t attr;
-  grub_uint8_t reserved;
-  grub_uint8_t checksum;
-  grub_uint16_t name2[6];
-  grub_uint16_t first_cluster;
-  grub_uint16_t name3[2];
-} __attribute__ ((packed));
-
-struct grub_fat_data
-{
-  int logical_sector_bits;
-  grub_uint32_t num_sectors;
-
-  grub_uint16_t fat_sector;
-  grub_uint32_t sectors_per_fat;
-  int fat_size;
-
-  grub_uint32_t root_cluster;
-  grub_uint32_t root_sector;
-  grub_uint32_t num_root_sectors;
-
-  int cluster_bits;
-  grub_uint32_t cluster_eof_mark;
-  grub_uint32_t cluster_sector;
-  grub_uint32_t num_clusters;
-
-  grub_uint8_t attr;
-  grub_ssize_t file_size;
-  grub_uint32_t file_cluster;
-  grub_uint32_t cur_cluster_num;
-  grub_uint32_t cur_cluster;
-
-  grub_uint32_t uuid;
-};
-
-static grub_dl_t my_mod;
-
-static int
-fat_log2 (unsigned x)
-{
-  int i;
-
-  if (x == 0)
-    return -1;
-
-  for (i = 0; (x & 1) == 0; i++)
-    x >>= 1;
-
-  if (x != 1)
-    return -1;
-
-  return i;
-}
-
-static struct grub_fat_data *
-grub_fat_mount (grub_disk_t disk)
-{
-  struct grub_fat_bpb bpb;
-  struct grub_fat_data *data = 0;
-  grub_uint32_t first_fat, magic;
-
-  if (! disk)
-    goto fail;
-
-  data = (struct grub_fat_data *) grub_malloc (sizeof (*data));
-  if (! data)
-    goto fail;
-
-  /* Read the BPB.  */
-  if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb))
-    goto fail;
-
-  if (grub_strncmp((const char *) bpb.version_specific.fat12_or_fat16.fstype, "FAT12", 5)
-      && grub_strncmp((const char *) bpb.version_specific.fat12_or_fat16.fstype, "FAT16", 5)
-      && grub_strncmp((const char *) bpb.version_specific.fat32.fstype, "FAT32", 5))
-    goto fail;
-
-  /* Get the sizes of logical sectors and clusters.  */
-  data->logical_sector_bits =
-    fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector));
-  if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS)
-    goto fail;
-  data->logical_sector_bits -= GRUB_DISK_SECTOR_BITS;
-
-  data->cluster_bits = fat_log2 (bpb.sectors_per_cluster);
-  if (data->cluster_bits < 0)
-    goto fail;
-  data->cluster_bits += data->logical_sector_bits;
-
-  /* Get information about FATs.  */
-  data->fat_sector = (grub_le_to_cpu16 (bpb.num_reserved_sectors)
-                     << data->logical_sector_bits);
-  if (data->fat_sector == 0)
-    goto fail;
-
-  data->sectors_per_fat = ((bpb.sectors_per_fat_16
-                           ? grub_le_to_cpu16 (bpb.sectors_per_fat_16)
-                           : grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32))
-                          << data->logical_sector_bits);
-  if (data->sectors_per_fat == 0)
-    goto fail;
-
-  /* Get the number of sectors in this volume.  */
-  data->num_sectors = ((bpb.num_total_sectors_16
-                       ? grub_le_to_cpu16 (bpb.num_total_sectors_16)
-                       : grub_le_to_cpu32 (bpb.num_total_sectors_32))
-                      << data->logical_sector_bits);
-  if (data->num_sectors == 0)
-    goto fail;
-
-  /* Get information about the root directory.  */
-  if (bpb.num_fats == 0)
-    goto fail;
-
-  data->root_sector = data->fat_sector + bpb.num_fats * data->sectors_per_fat;
-  data->num_root_sectors
-    = ((((grub_uint32_t) grub_le_to_cpu16 (bpb.num_root_entries)
-        * GRUB_FAT_DIR_ENTRY_SIZE
-        + grub_le_to_cpu16 (bpb.bytes_per_sector) - 1)
-       >> (data->logical_sector_bits + GRUB_DISK_SECTOR_BITS))
-       << (data->logical_sector_bits));
-
-  data->cluster_sector = data->root_sector + data->num_root_sectors;
-  data->num_clusters = (((data->num_sectors - data->cluster_sector)
-                        >> (data->cluster_bits + data->logical_sector_bits))
-                       + 2);
-
-  if (data->num_clusters <= 2)
-    goto fail;
-
-  if (! bpb.sectors_per_fat_16)
-    {
-      /* FAT32.  */
-      grub_uint16_t flags = grub_le_to_cpu16 (bpb.version_specific.fat32.extended_flags);
-
-      data->root_cluster = grub_le_to_cpu32 (bpb.version_specific.fat32.root_cluster);
-      data->fat_size = 32;
-      data->cluster_eof_mark = 0x0ffffff8;
-
-      if (flags & 0x80)
-       {
-         /* Get an active FAT.  */
-         unsigned active_fat = flags & 0xf;
-
-         if (active_fat > bpb.num_fats)
-           goto fail;
-
-         data->fat_sector += active_fat * data->sectors_per_fat;
-       }
-
-      if (bpb.num_root_entries != 0 || bpb.version_specific.fat32.fs_version != 0)
-       goto fail;
-    }
-  else
-    {
-      /* FAT12 or FAT16.  */
-      data->root_cluster = ~0U;
-
-      if (data->num_clusters <= 4085 + 2)
-       {
-         /* FAT12.  */
-         data->fat_size = 12;
-         data->cluster_eof_mark = 0x0ff8;
-       }
-      else
-       {
-         /* FAT16.  */
-         data->fat_size = 16;
-         data->cluster_eof_mark = 0xfff8;
-       }
-    }
-
-  /* More sanity checks.  */
-  if (data->num_sectors <= data->fat_sector)
-    goto fail;
-
-  if (grub_disk_read (disk,
-                     data->fat_sector,
-                     0,
-                     sizeof (first_fat),
-                     &first_fat))
-    goto fail;
-
-  first_fat = grub_le_to_cpu32 (first_fat);
-
-  if (data->fat_size == 32)
-    {
-      first_fat &= 0x0fffffff;
-      magic = 0x0fffff00;
-    }
-  else if (data->fat_size == 16)
-    {
-      first_fat &= 0x0000ffff;
-      magic = 0xff00;
-    }
-  else
-    {
-      first_fat &= 0x00000fff;
-      magic = 0x0f00;
-    }
-
-  /* Serial number.  */
-  if (bpb.sectors_per_fat_16)
-    data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial);
-  else
-    data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat32.num_serial);
-
-  /* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media
-     descriptor, even if it is a so-called superfloppy (e.g. an USB key).
-     The check may be too strict for this kind of stupid BIOSes, as
-     they overwrite the media descriptor.  */
-  if ((first_fat | 0x8) != (magic | bpb.media | 0x8))
-    goto fail;
-
-  /* Start from the root directory.  */
-  data->file_cluster = data->root_cluster;
-  data->cur_cluster_num = ~0U;
-  data->attr = GRUB_FAT_ATTR_DIRECTORY;
-  return data;
-
- fail:
-
-  grub_free (data);
-  grub_error (GRUB_ERR_BAD_FS, "not a FAT filesystem");
-  return 0;
-}
-
-static grub_ssize_t
-grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
-                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                      unsigned offset, unsigned length),
-                   grub_off_t offset, grub_size_t len, char *buf)
-{
-  grub_size_t size;
-  grub_uint32_t logical_cluster;
-  unsigned logical_cluster_bits;
-  grub_ssize_t ret = 0;
-  unsigned long sector;
-
-  /* This is a special case. FAT12 and FAT16 doesn't have the root directory
-     in clusters.  */
-  if (data->file_cluster == ~0U)
-    {
-      size = (data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset;
-      if (size > len)
-       size = len;
-
-      if (grub_disk_read (disk, data->root_sector, offset, size, buf))
-       return -1;
-
-      return size;
-    }
-
-  /* Calculate the logical cluster number and offset.  */
-  logical_cluster_bits = (data->cluster_bits
-                         + data->logical_sector_bits
-                         + GRUB_DISK_SECTOR_BITS);
-  logical_cluster = offset >> logical_cluster_bits;
-  offset &= (1 << logical_cluster_bits) - 1;
-
-  if (logical_cluster < data->cur_cluster_num)
-    {
-      data->cur_cluster_num = 0;
-      data->cur_cluster = data->file_cluster;
-    }
-
-  while (len)
-    {
-      while (logical_cluster > data->cur_cluster_num)
-       {
-         /* Find next cluster.  */
-         grub_uint32_t next_cluster;
-         unsigned long fat_offset;
-
-         switch (data->fat_size)
-           {
-           case 32:
-             fat_offset = data->cur_cluster << 2;
-             break;
-           case 16:
-             fat_offset = data->cur_cluster << 1;
-             break;
-           default:
-             /* case 12: */
-             fat_offset = data->cur_cluster + (data->cur_cluster >> 1);
-             break;
-           }
-
-         /* Read the FAT.  */
-         if (grub_disk_read (disk, data->fat_sector, fat_offset,
-                             (data->fat_size + 7) >> 3,
-                             (char *) &next_cluster))
-           return -1;
-
-         next_cluster = grub_le_to_cpu32 (next_cluster);
-         switch (data->fat_size)
-           {
-           case 16:
-             next_cluster &= 0xFFFF;
-             break;
-           case 12:
-             if (data->cur_cluster & 1)
-               next_cluster >>= 4;
-
-             next_cluster &= 0x0FFF;
-             break;
-           }
-
-         grub_dprintf ("fat", "fat_size=%d, next_cluster=%u\n",
-                       data->fat_size, next_cluster);
-
-         /* Check the end.  */
-         if (next_cluster >= data->cluster_eof_mark)
-           return ret;
-
-         if (next_cluster < 2 || next_cluster >= data->num_clusters)
-           {
-             grub_error (GRUB_ERR_BAD_FS, "invalid cluster %u",
-                         next_cluster);
-             return -1;
-           }
-
-         data->cur_cluster = next_cluster;
-         data->cur_cluster_num++;
-       }
-
-      /* Read the data here.  */
-      sector = (data->cluster_sector
-               + ((data->cur_cluster - 2)
-                  << (data->cluster_bits + data->logical_sector_bits)));
-      size = (1 << logical_cluster_bits) - offset;
-      if (size > len)
-       size = len;
-
-      disk->read_hook = read_hook;
-      grub_disk_read (disk, sector, offset, size, buf);
-      disk->read_hook = 0;
-      if (grub_errno)
-       return -1;
-
-      len -= size;
-      buf += size;
-      ret += size;
-      logical_cluster++;
-      offset = 0;
-    }
-
-  return ret;
-}
-
-static grub_err_t
-grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
-                     int (*hook) (const char *filename,
-                                  struct grub_fat_dir_entry *dir))
-{
-  struct grub_fat_dir_entry dir;
-  char *filename, *filep = 0;
-  grub_uint16_t *unibuf;
-  int slot = -1, slots = -1;
-  int checksum = -1;
-  grub_ssize_t offset = -sizeof(dir);
-
-  if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-
-  /* Allocate space enough to hold a long name.  */
-  filename = grub_malloc (0x40 * 13 * 4 + 1);
-  unibuf = (grub_uint16_t *) grub_malloc (0x40 * 13 * 2);
-  if (! filename || ! unibuf)
-    {
-      grub_free (filename);
-      grub_free (unibuf);
-      return 0;
-    }
-
-  while (1)
-    {
-      unsigned i;
-
-      /* Adjust the offset.  */
-      offset += sizeof (dir);
-
-      /* Read a directory entry.  */
-      if ((grub_fat_read_data (disk, data, 0,
-                              offset, sizeof (dir), (char *) &dir)
-          != sizeof (dir) || dir.name[0] == 0))
-       break;
-      /* Handle long name entries.  */
-      if (dir.attr == GRUB_FAT_ATTR_LONG_NAME)
-       {
-         struct grub_fat_long_name_entry *long_name
-           = (struct grub_fat_long_name_entry *) &dir;
-         grub_uint8_t id = long_name->id;
-
-         if (id & 0x40)
-           {
-             id &= 0x3f;
-             slots = slot = id;
-             checksum = long_name->checksum;
-           }
-
-         if (id != slot || slot == 0 || checksum != long_name->checksum)
-           {
-             checksum = -1;
-             continue;
-           }
-
-         slot--;
-         grub_memcpy (unibuf + slot * 13, long_name->name1, 5 * 2);
-         grub_memcpy (unibuf + slot * 13 + 5, long_name->name2, 6 * 2);
-         grub_memcpy (unibuf + slot * 13 + 11, long_name->name3, 2 * 2);
-         continue;
-       }
-
-      /* Check if this entry is valid.  */
-      if (dir.name[0] == 0xe5 || (dir.attr & ~GRUB_FAT_ATTR_VALID))
-       continue;
-
-      /* This is a workaround for Japanese.  */
-      if (dir.name[0] == 0x05)
-       dir.name[0] = 0xe5;
-
-      if (checksum != -1 && slot == 0)
-       {
-         grub_uint8_t sum;
-
-         for (sum = 0, i = 0; i < sizeof (dir.name); i++)
-           sum = ((sum >> 1) | (sum << 7)) + dir.name[i];
-
-         if (sum == checksum)
-           {
-             int u;
-
-             for (u = 0; u < slots * 13; u++)
-               unibuf[u] = grub_le_to_cpu16 (unibuf[u]);
-
-             *grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf,
-                                  slots * 13) = '\0';
-
-             if (hook (filename, &dir))
-               break;
-
-             checksum = -1;
-             continue;
-           }
-
-         checksum = -1;
-       }
-
-      /* Convert the 8.3 file name.  */
-      filep = filename;
-      if (dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
-       {
-         for (i = 0; i < sizeof (dir.name) && dir.name[i]
-                && ! grub_isspace (dir.name[i]); i++)
-           *filep++ = dir.name[i];
-       }
-      else
-       {
-         for (i = 0; i < 8 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
-           *filep++ = grub_tolower (dir.name[i]);
-
-         *filep = '.';
-
-         for (i = 8; i < 11 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
-           *++filep = grub_tolower (dir.name[i]);
-
-         if (*filep != '.')
-           filep++;
-       }
-      *filep = '\0';
-
-      if (hook (filename, &dir))
-       break;
-    }
-
-  grub_free (filename);
-  grub_free (unibuf);
-
-  return grub_errno;
-}
-
-
-/* Find the underlying directory or file in PATH and return the
-   next path. If there is no next path or an error occurs, return NULL.
-   If HOOK is specified, call it with each file name.  */
-static char *
-grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
-                  const char *path,
-                  int (*hook) (const char *filename,
-                               const struct grub_dirhook_info *info))
-{
-  char *dirname, *dirp;
-  int call_hook;
-  int found = 0;
-
-  auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir);
-  int iter_hook (const char *filename, struct grub_fat_dir_entry *dir)
-  {
-    struct grub_dirhook_info info;
-    grub_memset (&info, 0, sizeof (info));
-
-    info.dir = !! (dir->attr & GRUB_FAT_ATTR_DIRECTORY);
-    info.case_insensitive = 1;
-
-    if (dir->attr & GRUB_FAT_ATTR_VOLUME_ID)
-      return 0;
-    if (*dirname == '\0' && call_hook)
-      return hook (filename, &info);
-
-    if (grub_strcasecmp (dirname, filename) == 0)
-      {
-       found = 1;
-       data->attr = dir->attr;
-       data->file_size = grub_le_to_cpu32 (dir->file_size);
-       data->file_cluster = ((grub_le_to_cpu16 (dir->first_cluster_high) << 16)
-                             | grub_le_to_cpu16 (dir->first_cluster_low));
-       data->cur_cluster_num = ~0U;
-
-       if (call_hook)
-         hook (filename, &info);
-
-       return 1;
-      }
-    return 0;
-  }
-
-  if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-      return 0;
-    }
-
-  /* Extract a directory name.  */
-  while (*path == '/')
-    path++;
-
-  dirp = grub_strchr (path, '/');
-  if (dirp)
-    {
-      unsigned len = dirp - path;
-
-      dirname = grub_malloc (len + 1);
-      if (! dirname)
-       return 0;
-
-      grub_memcpy (dirname, path, len);
-      dirname[len] = '\0';
-    }
-  else
-    /* This is actually a file.  */
-    dirname = grub_strdup (path);
-
-  call_hook = (! dirp && hook);
-
-  grub_fat_iterate_dir (disk, data, iter_hook);
-  if (grub_errno == GRUB_ERR_NONE && ! found && !call_hook)
-    grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
-
-  grub_free (dirname);
-
-  return found ? dirp : 0;
-}
-
-static grub_err_t
-grub_fat_dir (grub_device_t device, const char *path,
-             int (*hook) (const char *filename,
-                          const struct grub_dirhook_info *info))
-{
-  struct grub_fat_data *data = 0;
-  grub_disk_t disk = device->disk;
-  grub_size_t len;
-  char *dirname = 0;
-  char *p;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_fat_mount (disk);
-  if (! data)
-    goto fail;
-
-  /* Make sure that DIRNAME terminates with '/'.  */
-  len = grub_strlen (path);
-  dirname = grub_malloc (len + 1 + 1);
-  if (! dirname)
-    goto fail;
-  grub_memcpy (dirname, path, len);
-  p = dirname + len;
-  if (path[len - 1] != '/')
-    *p++ = '/';
-  *p = '\0';
-  p = dirname;
-
-  do
-    {
-      p = grub_fat_find_dir (disk, data, p, hook);
-    }
-  while (p && grub_errno == GRUB_ERR_NONE);
-
- fail:
-
-  grub_free (dirname);
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_fat_open (grub_file_t file, const char *name)
-{
-  struct grub_fat_data *data = 0;
-  char *p = (char *) name;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_fat_mount (file->device->disk);
-  if (! data)
-    goto fail;
-
-  do
-    {
-      p = grub_fat_find_dir (file->device->disk, data, p, 0);
-      if (grub_errno != GRUB_ERR_NONE)
-       goto fail;
-    }
-  while (p);
-
-  if (data->attr & GRUB_FAT_ATTR_DIRECTORY)
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a file");
-      goto fail;
-    }
-
-  file->data = data;
-  file->size = data->file_size;
-
-  return GRUB_ERR_NONE;
-
- fail:
-
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_ssize_t
-grub_fat_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  return grub_fat_read_data (file->device->disk, file->data, file->read_hook,
-                            file->offset, len, buf);
-}
-
-static grub_err_t
-grub_fat_close (grub_file_t file)
-{
-  grub_free (file->data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_fat_label (grub_device_t device, char **label)
-{
-  struct grub_fat_data *data;
-  grub_disk_t disk = device->disk;
-
-  auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir);
-  int iter_hook (const char *filename, struct grub_fat_dir_entry *dir)
-  {
-    if (dir->attr == GRUB_FAT_ATTR_VOLUME_ID)
-      {
-       *label = grub_strdup (filename);
-       return 1;
-      }
-    return 0;
-  }
-
-  grub_dl_ref (my_mod);
-
-  data = grub_fat_mount (disk);
-  if (! data)
-    goto fail;
-
-  if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-      return 0;
-    }
-
-  *label = 0;
-
-  grub_fat_iterate_dir (disk, data, iter_hook);
-
- fail:
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_fat_uuid (grub_device_t device, char **uuid)
-{
-  struct grub_fat_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_fat_mount (disk);
-  if (data)
-    {
-      *uuid = grub_xasprintf ("%04x-%04x",
-                            (grub_uint16_t) (data->uuid >> 16),
-                            (grub_uint16_t) data->uuid);
-    }
-  else
-    *uuid = NULL;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-static struct grub_fs grub_fat_fs =
-  {
-    .name = "fat",
-    .dir = grub_fat_dir,
-    .open = grub_fat_open,
-    .read = grub_fat_read,
-    .close = grub_fat_close,
-    .label = grub_fat_label,
-    .uuid = grub_fat_uuid,
-#ifdef GRUB_UTIL
-    .reserved_first_sector = 1,
-#endif
-    .next = 0
-  };
-
-GRUB_MOD_INIT(fat)
-{
-  grub_fs_register (&grub_fat_fs);
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(fat)
-{
-  grub_fs_unregister (&grub_fat_fs);
-}
-
diff --git a/fs/fshelp.c b/fs/fshelp.c
deleted file mode 100644 (file)
index d0b1e49..0000000
+++ /dev/null
@@ -1,315 +0,0 @@
-/* fshelp.c -- Filesystem helper functions */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2005,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/fshelp.h>
-
-
-/* Lookup the node PATH.  The node ROOTNODE describes the root of the
-   directory tree.  The node found is returned in FOUNDNODE, which is
-   either a ROOTNODE or a new malloc'ed node.  ITERATE_DIR is used to
-   iterate over all directory entries in the current node.
-   READ_SYMLINK is used to read the symlink if a node is a symlink.
-   EXPECTTYPE is the type node that is expected by the called, an
-   error is generated if the node is not of the expected type.  Make
-   sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required
-   because GCC has a nasty bug when using regparm=3.  */
-grub_err_t
-grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode,
-                      grub_fshelp_node_t *foundnode,
-                      int (*iterate_dir) (grub_fshelp_node_t dir,
-                                          int NESTED_FUNC_ATTR (*hook)
-                                          (const char *filename,
-                                           enum grub_fshelp_filetype filetype,
-                                           grub_fshelp_node_t node)),
-                      char *(*read_symlink) (grub_fshelp_node_t node),
-                      enum grub_fshelp_filetype expecttype)
-{
-  grub_err_t err;
-  enum grub_fshelp_filetype foundtype = GRUB_FSHELP_DIR;
-  int symlinknest = 0;
-
-  auto grub_err_t NESTED_FUNC_ATTR find_file (const char *currpath,
-                                             grub_fshelp_node_t currroot,
-                                             grub_fshelp_node_t *currfound);
-
-  grub_err_t NESTED_FUNC_ATTR find_file (const char *currpath,
-                                        grub_fshelp_node_t currroot,
-                                        grub_fshelp_node_t *currfound)
-    {
-      char fpath[grub_strlen (currpath) + 1];
-      char *name = fpath;
-      char *next;
-      //  unsigned int pos = 0;
-      enum grub_fshelp_filetype type = GRUB_FSHELP_DIR;
-      grub_fshelp_node_t currnode = currroot;
-      grub_fshelp_node_t oldnode = currroot;
-
-      auto int NESTED_FUNC_ATTR iterate (const char *filename,
-                                        enum grub_fshelp_filetype filetype,
-                                        grub_fshelp_node_t node);
-
-      auto void free_node (grub_fshelp_node_t node);
-
-      void free_node (grub_fshelp_node_t node)
-       {
-          if (node != rootnode && node != currroot)
-           grub_free (node);
-       }
-
-      int NESTED_FUNC_ATTR iterate (const char *filename,
-                                   enum grub_fshelp_filetype filetype,
-                                   grub_fshelp_node_t node)
-       {
-         if (filetype == GRUB_FSHELP_UNKNOWN ||
-              (grub_strcmp (name, filename) &&
-               (! (filetype & GRUB_FSHELP_CASE_INSENSITIVE) ||
-                grub_strncasecmp (name, filename, GRUB_LONG_MAX))))
-           {
-             grub_free (node);
-             return 0;
-           }
-
-         /* The node is found, stop iterating over the nodes.  */
-         type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE;
-         oldnode = currnode;
-         currnode = node;
-
-         return 1;
-       }
-
-      grub_strncpy (fpath, currpath, grub_strlen (currpath) + 1);
-
-      /* Remove all leading slashes.  */
-      while (*name == '/')
-       name++;
-
-      if (! *name)
-       {
-         *currfound = currnode;
-         return 0;
-       }
-
-      for (;;)
-       {
-         int found;
-
-         /* Extract the actual part from the pathname.  */
-         next = grub_strchr (name, '/');
-         if (next)
-           {
-             /* Remove all leading slashes.  */
-             while (*next == '/')
-               *(next++) = '\0';
-           }
-
-         /* At this point it is expected that the current node is a
-            directory, check if this is true.  */
-         if (type != GRUB_FSHELP_DIR)
-           {
-             free_node (currnode);
-             return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-           }
-
-         /* Iterate over the directory.  */
-         found = iterate_dir (currnode, iterate);
-         if (! found)
-           {
-             if (grub_errno)
-               return grub_errno;
-
-             break;
-           }
-
-         /* Read in the symlink and follow it.  */
-         if (type == GRUB_FSHELP_SYMLINK)
-           {
-             char *symlink;
-
-             /* Test if the symlink does not loop.  */
-             if (++symlinknest == 8)
-               {
-                 free_node (currnode);
-                 free_node (oldnode);
-                 return grub_error (GRUB_ERR_SYMLINK_LOOP,
-                                     "too deep nesting of symlinks");
-               }
-
-             symlink = read_symlink (currnode);
-             free_node (currnode);
-
-             if (!symlink)
-               {
-                 free_node (oldnode);
-                 return grub_errno;
-               }
-
-             /* The symlink is an absolute path, go back to the root inode.  */
-             if (symlink[0] == '/')
-               {
-                 free_node (oldnode);
-                 oldnode = rootnode;
-               }
-
-             /* Lookup the node the symlink points to.  */
-             find_file (symlink, oldnode, &currnode);
-             type = foundtype;
-             grub_free (symlink);
-
-             if (grub_errno)
-               {
-                 free_node (oldnode);
-                 return grub_errno;
-               }
-           }
-
-         free_node (oldnode);
-
-         /* Found the node!  */
-         if (! next || *next == '\0')
-           {
-             *currfound = currnode;
-             foundtype = type;
-             return 0;
-           }
-
-         name = next;
-       }
-
-      return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
-    }
-
-  if (!path || path[0] != '/')
-    {
-      grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
-      return grub_errno;
-    }
-
-  err = find_file (path, rootnode, foundnode);
-  if (err)
-    return err;
-
-  /* Check if the node that was found was of the expected type.  */
-  if (expecttype == GRUB_FSHELP_REG && foundtype != expecttype)
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file");
-  else if (expecttype == GRUB_FSHELP_DIR && foundtype != expecttype)
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-
-  return 0;
-}
-
-/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
-   beginning with the block POS.  READ_HOOK should be set before
-   reading a block from the file.  GET_BLOCK is used to translate file
-   blocks to disk blocks.  The file is FILESIZE bytes big and the
-   blocks have a size of LOG2BLOCKSIZE (in log2).  */
-grub_ssize_t
-grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
-                      void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                                           unsigned offset,
-                                                           unsigned length),
-                      grub_off_t pos, grub_size_t len, char *buf,
-                      grub_disk_addr_t (*get_block) (grub_fshelp_node_t node,
-                                                      grub_disk_addr_t block),
-                      grub_off_t filesize, int log2blocksize)
-{
-  grub_disk_addr_t i, blockcnt;
-  int blocksize = 1 << (log2blocksize + GRUB_DISK_SECTOR_BITS);
-
-  /* Adjust LEN so it we can't read past the end of the file.  */
-  if (pos + len > filesize)
-    len = filesize - pos;
-
-  blockcnt = ((len + pos) + blocksize - 1) >> (log2blocksize + GRUB_DISK_SECTOR_BITS);
-
-  for (i = pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS); i < blockcnt; i++)
-    {
-      grub_disk_addr_t blknr;
-      int blockoff = pos & (blocksize - 1);
-      int blockend = blocksize;
-
-      int skipfirst = 0;
-
-      blknr = get_block (node, i);
-      if (grub_errno)
-       return -1;
-
-      blknr = blknr << log2blocksize;
-
-      /* Last block.  */
-      if (i == blockcnt - 1)
-       {
-         blockend = (len + pos) & (blocksize - 1);
-
-         /* The last portion is exactly blocksize.  */
-         if (! blockend)
-           blockend = blocksize;
-       }
-
-      /* First block.  */
-      if (i == (pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS)))
-       {
-         skipfirst = blockoff;
-         blockend -= skipfirst;
-       }
-
-      /* If the block number is 0 this block is not stored on disk but
-        is zero filled instead.  */
-      if (blknr)
-       {
-         disk->read_hook = read_hook;
-
-         grub_disk_read (disk, blknr, skipfirst,
-                         blockend, buf);
-         disk->read_hook = 0;
-         if (grub_errno)
-           return -1;
-       }
-      else
-       grub_memset (buf, 0, blockend);
-
-      buf += blocksize - skipfirst;
-    }
-
-  return len;
-}
-
-unsigned int
-grub_fshelp_log2blksize (unsigned int blksize, unsigned int *pow)
-{
-  int mod;
-
-  *pow = 0;
-  while (blksize > 1)
-    {
-      mod = blksize - ((blksize >> 1) << 1);
-      blksize >>= 1;
-
-      /* Check if it really is a power of two.  */
-      if (mod)
-       return grub_error (GRUB_ERR_BAD_NUMBER,
-                          "the blocksize is not a power of two");
-      (*pow)++;
-    }
-
-  return GRUB_ERR_NONE;
-}
diff --git a/fs/hfs.c b/fs/hfs.c
deleted file mode 100644 (file)
index cef8563..0000000
--- a/fs/hfs.c
+++ /dev/null
@@ -1,1122 +0,0 @@
-/* hfs.c - HFS.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* HFS is documented at
-   http://developer.apple.com/documentation/mac/Files/Files-2.html */
-
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/types.h>
-#include <grub/hfs.h>
-
-#define        GRUB_HFS_SBLOCK         2
-#define GRUB_HFS_EMBED_HFSPLUS_SIG 0x482B
-
-#define GRUB_HFS_BLKS          (data->blksz >> 9)
-
-#define GRUB_HFS_NODE_LEAF     0xFF
-
-/* The two supported filesystems a record can have.  */
-enum
-  {
-    GRUB_HFS_FILETYPE_DIR = 1,
-    GRUB_HFS_FILETYPE_FILE = 2
-  };
-
-/* Catalog node ID (CNID).  */
-enum grub_hfs_cnid_type
-  {
-    GRUB_HFS_CNID_ROOT_PARENT = 1,
-    GRUB_HFS_CNID_ROOT = 2,
-    GRUB_HFS_CNID_EXT = 3,
-    GRUB_HFS_CNID_CAT = 4,
-    GRUB_HFS_CNID_BAD = 5
-  };
-
-/* A node descriptor.  This is the header of every node.  */
-struct grub_hfs_node
-{
-  grub_uint32_t next;
-  grub_uint32_t prev;
-  grub_uint8_t type;
-  grub_uint8_t level;
-  grub_uint16_t reccnt;
-  grub_uint16_t unused;
-} __attribute__ ((packed));
-
-/* The head of the B*-Tree.  */
-struct grub_hfs_treeheader
-{
-  grub_uint16_t tree_depth;
-  /* The number of the first node.  */
-  grub_uint32_t root_node;
-  grub_uint32_t leaves;
-  grub_uint32_t first_leaf;
-  grub_uint32_t last_leaf;
-  grub_uint16_t node_size;
-  grub_uint16_t key_size;
-  grub_uint32_t nodes;
-  grub_uint32_t free_nodes;
-  grub_uint8_t unused[76];
-} __attribute__ ((packed));
-
-/* The state of a mounted HFS filesystem.  */
-struct grub_hfs_data
-{
-  struct grub_hfs_sblock sblock;
-  grub_disk_t disk;
-  grub_hfs_datarecord_t extents;
-  int fileid;
-  int size;
-  int ext_root;
-  int ext_size;
-  int cat_root;
-  int cat_size;
-  int blksz;
-  int log2_blksz;
-  int rootdir;
-};
-
-/* The key as used on disk in a catalog tree.  This is used to lookup
-   file/directory nodes by parent directory ID and filename.  */
-struct grub_hfs_catalog_key
-{
-  grub_uint8_t unused;
-  grub_uint32_t parent_dir;
-
-  /* Filename length.  */
-  grub_uint8_t strlen;
-
-  /* Filename.  */
-  grub_uint8_t str[31];
-} __attribute__ ((packed));
-
-/* The key as used on disk in a extent overflow tree.  Using this key
-   the extents can be looked up using a fileid and logical start block
-   as index.  */
-struct grub_hfs_extent_key
-{
-  /* The kind of fork.  This is used to store meta information like
-     icons, attributes, etc.  We will only use the datafork, which is
-     0.  */
-  grub_uint8_t forktype;
-  grub_uint32_t fileid;
-  grub_uint16_t first_block;
-} __attribute__ ((packed));
-
-/* A directory record.  This is used to find out the directory ID.  */
-struct grub_hfs_dirrec
-{
-  /* For a directory, type == 1.  */
-  grub_uint8_t type;
-  grub_uint8_t unused[5];
-  grub_uint32_t dirid;
-} __attribute__ ((packed));
-
-/* Information about a file.  */
-struct grub_hfs_filerec
-{
-  /* For a file, type == 2.  */
-  grub_uint8_t type;
-  grub_uint8_t unused[19];
-  grub_uint32_t fileid;
-  grub_uint8_t unused2[2];
-  grub_uint32_t size;
-  grub_uint8_t unused3[44];
-
-  /* The first 3 extents of the file.  The other extents can be found
-     in the extent overflow file.  */
-  grub_hfs_datarecord_t extents;
-} __attribute__ ((packed));
-
-/* A record descriptor, both key and data, used to pass to call back
-   functions.  */
-struct grub_hfs_record
-{
-  void *key;
-  int keylen;
-  void *data;
-  int datalen;
-};
-
-static grub_dl_t my_mod;
-\f
-static int grub_hfs_find_node (struct grub_hfs_data *, char *,
-                              grub_uint32_t, int, char *, int);
-
-/* Find block BLOCK of the file FILE in the mounted UFS filesystem
-   DATA.  The first 3 extents are described by DAT.  If cache is set,
-   using caching to improve non-random reads.  */
-static unsigned int
-grub_hfs_block (struct grub_hfs_data *data, grub_hfs_datarecord_t dat,
-               int file, int block, int cache)
-{
-  grub_hfs_datarecord_t dr;
-  int pos = 0;
-  struct grub_hfs_extent_key key;
-
-  int tree = 0;
-  static int cache_file = 0;
-  static int cache_pos = 0;
-  static grub_hfs_datarecord_t cache_dr;
-
-  grub_memcpy (dr, dat, sizeof (dr));
-
-  key.forktype = 0;
-  key.fileid = grub_cpu_to_be32 (file);
-
-  if (cache && cache_file == file  && block > cache_pos)
-    {
-      pos = cache_pos;
-      key.first_block = grub_cpu_to_be16 (pos);
-      grub_memcpy (dr, cache_dr, sizeof (cache_dr));
-    }
-
-  for (;;)
-    {
-      int i;
-
-      /* Try all 3 extents.  */
-      for (i = 0; i < 3; i++)
-       {
-         /* Check if the block is stored in this extent.  */
-         if (grub_be_to_cpu16 (dr[i].count) + pos > block)
-           {
-             int first = grub_be_to_cpu16 (dr[i].first_block);
-
-             /* If the cache is enabled, store the current position
-                in the tree.  */
-             if (tree && cache)
-               {
-                 cache_file = file;
-                 cache_pos = pos;
-                 grub_memcpy (cache_dr, dr, sizeof (cache_dr));
-               }
-
-             return (grub_be_to_cpu16 (data->sblock.first_block)
-                     + (first + block - pos) * GRUB_HFS_BLKS);
-           }
-
-         /* Try the next extent.  */
-         pos += grub_be_to_cpu16 (dr[i].count);
-       }
-
-      /* Lookup the block in the extent overflow file.  */
-      key.first_block = grub_cpu_to_be16 (pos);
-      tree = 1;
-      grub_hfs_find_node (data, (char *) &key, data->ext_root,
-                         1, (char *) &dr, sizeof (dr));
-      if (grub_errno)
-       return 0;
-    }
-}
-
-
-/* Read LEN bytes from the file described by DATA starting with byte
-   POS.  Return the amount of read bytes in READ.  */
-static grub_ssize_t
-grub_hfs_read_file (struct grub_hfs_data *data,
-                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                      unsigned offset, unsigned length),
-                    int pos, grub_size_t len, char *buf)
-{
-  int i;
-  int blockcnt;
-
-  blockcnt = ((len + pos)
-             + data->blksz - 1) / data->blksz;
-
-  for (i = pos / data->blksz; i < blockcnt; i++)
-    {
-      int blknr;
-      int blockoff = pos % data->blksz;
-      int blockend = data->blksz;
-
-      int skipfirst = 0;
-
-      blknr = grub_hfs_block (data, data->extents, data->fileid, i, 1);
-      if (grub_errno)
-       return -1;
-
-      /* Last block.  */
-      if (i == blockcnt - 1)
-       {
-         blockend = (len + pos) % data->blksz;
-
-         /* The last portion is exactly EXT2_BLOCK_SIZE (data).  */
-         if (! blockend)
-           blockend = data->blksz;
-       }
-
-      /* First block.  */
-      if (i == pos / data->blksz)
-       {
-         skipfirst = blockoff;
-         blockend -= skipfirst;
-       }
-
-      /* If the block number is 0 this block is not stored on disk but
-        is zero filled instead.  */
-      if (blknr)
-       {
-         data->disk->read_hook = read_hook;
-         grub_disk_read (data->disk, blknr, skipfirst,
-                         blockend, buf);
-         data->disk->read_hook = 0;
-         if (grub_errno)
-           return -1;
-       }
-
-      buf += data->blksz - skipfirst;
-    }
-
-  return len;
-}
-
-
-/* Mount the filesystem on the disk DISK.  */
-static struct grub_hfs_data *
-grub_hfs_mount (grub_disk_t disk)
-{
-  struct grub_hfs_data *data;
-  struct grub_hfs_catalog_key key;
-  struct grub_hfs_dirrec dir;
-  int first_block;
-
-  struct
-  {
-    struct grub_hfs_node node;
-    struct grub_hfs_treeheader head;
-  } treehead;
-
-  data = grub_malloc (sizeof (struct grub_hfs_data));
-  if (!data)
-    return 0;
-
-  /* Read the superblock.  */
-  if (grub_disk_read (disk, GRUB_HFS_SBLOCK, 0,
-                     sizeof (struct grub_hfs_sblock), &data->sblock))
-    goto fail;
-
-  /* Check if this is a HFS filesystem.  */
-  if (grub_be_to_cpu16 (data->sblock.magic) != GRUB_HFS_MAGIC)
-    {
-      grub_error (GRUB_ERR_BAD_FS, "not an HFS filesystem");
-      goto fail;
-    }
-
-  /* Check if this is an embedded HFS+ filesystem.  */
-  if (grub_be_to_cpu16 (data->sblock.embed_sig) == GRUB_HFS_EMBED_HFSPLUS_SIG)
-    {
-      grub_error (GRUB_ERR_BAD_FS, "embedded HFS+ filesystem");
-      goto fail;
-    }
-
-  data->blksz = grub_be_to_cpu32 (data->sblock.blksz);
-  data->disk = disk;
-
-  /* Lookup the root node of the extent overflow tree.  */
-  first_block = ((grub_be_to_cpu16 (data->sblock.extent_recs[0].first_block)
-                 * GRUB_HFS_BLKS)
-                + grub_be_to_cpu16 (data->sblock.first_block));
-
-  if (grub_disk_read (data->disk, first_block, 0,
-                     sizeof (treehead), &treehead))
-    goto fail;
-  data->ext_root = grub_be_to_cpu32 (treehead.head.root_node);
-  data->ext_size = grub_be_to_cpu16 (treehead.head.node_size);
-
-  /* Lookup the root node of the catalog tree.  */
-  first_block = ((grub_be_to_cpu16 (data->sblock.catalog_recs[0].first_block)
-                 * GRUB_HFS_BLKS)
-                + grub_be_to_cpu16 (data->sblock.first_block));
-  if (grub_disk_read (data->disk, first_block, 0,
-                     sizeof (treehead), &treehead))
-    goto fail;
-  data->cat_root = grub_be_to_cpu32 (treehead.head.root_node);
-  data->cat_size = grub_be_to_cpu16 (treehead.head.node_size);
-
-  /* Lookup the root directory node in the catalog tree using the
-     volume name.  */
-  key.parent_dir = grub_cpu_to_be32 (1);
-  key.strlen = data->sblock.volname[0];
-  grub_strcpy ((char *) key.str, (char *) (data->sblock.volname + 1));
-
-  if (grub_hfs_find_node (data, (char *) &key, data->cat_root,
-                         0, (char *) &dir, sizeof (dir)) == 0)
-    {
-      grub_error (GRUB_ERR_BAD_FS, "cannot find the HFS root directory");
-      goto fail;
-    }
-
-  if (grub_errno)
-    goto fail;
-
-  data->rootdir = grub_be_to_cpu32 (dir.dirid);
-
-  return data;
- fail:
-  grub_free (data);
-
-  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
-    grub_error (GRUB_ERR_BAD_FS, "not a HFS filesystem");
-
-  return 0;
-}
-
-/* Compare the K1 and K2 catalog file keys using HFS character ordering.  */
-static int
-grub_hfs_cmp_catkeys (struct grub_hfs_catalog_key *k1,
-                     struct grub_hfs_catalog_key *k2)
-{
-  /* Taken from hfsutils 3.2.6 and converted to a readable form */
-  static const unsigned char hfs_charorder[256] = {
-    [0x00] = 0,
-    [0x01] = 1,
-    [0x02] = 2,
-    [0x03] = 3,
-    [0x04] = 4,
-    [0x05] = 5,
-    [0x06] = 6,
-    [0x07] = 7,
-    [0x08] = 8,
-    [0x09] = 9,
-    [0x0A] = 10,
-    [0x0B] = 11,
-    [0x0C] = 12,
-    [0x0D] = 13,
-    [0x0E] = 14,
-    [0x0F] = 15,
-    [0x10] = 16,
-    [0x11] = 17,
-    [0x12] = 18,
-    [0x13] = 19,
-    [0x14] = 20,
-    [0x15] = 21,
-    [0x16] = 22,
-    [0x17] = 23,
-    [0x18] = 24,
-    [0x19] = 25,
-    [0x1A] = 26,
-    [0x1B] = 27,
-    [0x1C] = 28,
-    [0x1D] = 29,
-    [0x1E] = 30,
-    [0x1F] = 31,
-    [' '] = 32,                [0xCA] = 32,
-    ['!'] = 33,
-    ['"'] = 34,
-    [0xD2] = 35,
-    [0xD3] = 36,
-    [0xC7] = 37,
-    [0xC8] = 38,
-    ['#'] = 39,
-    ['$'] = 40,
-    ['%'] = 41,
-    ['&'] = 42,
-    ['\''] = 43,
-    [0xD4] = 44,
-    [0xD5] = 45,
-    ['('] = 46,
-    [')'] = 47,
-    ['*'] = 48,
-    ['+'] = 49,
-    [','] = 50,
-    ['-'] = 51,
-    ['.'] = 52,
-    ['/'] = 53,
-    ['0'] = 54,
-    ['1'] = 55,
-    ['2'] = 56,
-    ['3'] = 57,
-    ['4'] = 58,
-    ['5'] = 59,
-    ['6'] = 60,
-    ['7'] = 61,
-    ['8'] = 62,
-    ['9'] = 63,
-    [':'] = 64,
-    [';'] = 65,
-    ['<'] = 66,
-    ['='] = 67,
-    ['>'] = 68,
-    ['?'] = 69,
-    ['@'] = 70,
-    ['A'] = 71,                ['a'] = 71,
-    [0x88] = 72,       [0xCB] = 72,
-    [0x80] = 73,       [0x8A] = 73,
-    [0x8B] = 74,       [0xCC] = 74,
-    [0x81] = 75,       [0x8C] = 75,
-    [0xAE] = 76,       [0xBE] = 76,
-    ['`'] = 77,
-    [0x87] = 78,
-    [0x89] = 79,
-    [0xBB] = 80,
-    ['B'] = 81,                ['b'] = 81,
-    ['C'] = 82,                ['c'] = 82,
-    [0x82] = 83,       [0x8D] = 83,
-    ['D'] = 84,                ['d'] = 84,
-    ['E'] = 85,                ['e'] = 85,
-    [0x83] = 86,       [0x8E] = 86,
-    [0x8F] = 87,
-    [0x90] = 88,
-    [0x91] = 89,
-    ['F'] = 90,                ['f'] = 90,
-    ['G'] = 91,                ['g'] = 91,
-    ['H'] = 92,                ['h'] = 92,
-    ['I'] = 93,                ['i'] = 93,
-    [0x92] = 94,
-    [0x93] = 95,
-    [0x94] = 96,
-    [0x95] = 97,
-    ['J'] = 98,                ['j'] = 98,
-    ['K'] = 99,                ['k'] = 99,
-    ['L'] = 100,       ['l'] = 100,
-    ['M'] = 101,       ['m'] = 101,
-    ['N'] = 102,       ['n'] = 102,
-    [0x84] = 103,      [0x96] = 103,
-    ['O'] = 104,       ['o'] = 104,
-    [0x85] = 105,      [0x9A] = 105,
-    [0x9B] = 106,      [0xCD] = 106,
-    [0xAF] = 107,      [0xBF] = 107,
-    [0xCE] = 108,      [0xCF] = 108,
-    [0x97] = 109,
-    [0x98] = 110,
-    [0x99] = 111,
-    [0xBC] = 112,
-    ['P'] = 113,       ['p'] = 113,
-    ['Q'] = 114,       ['q'] = 114,
-    ['R'] = 115,       ['r'] = 115,
-    ['S'] = 116,       ['s'] = 116,
-    [0xA7] = 117,
-    ['T'] = 118,       ['t'] = 118,
-    ['U'] = 119,       ['u'] = 119,
-    [0x86] = 120,      [0x9F] = 120,
-    [0x9C] = 121,
-    [0x9D] = 122,
-    [0x9E] = 123,
-    ['V'] = 124,       ['v'] = 124,
-    ['W'] = 125,       ['w'] = 125,
-    ['X'] = 126,       ['x'] = 126,
-    ['Y'] = 127,       ['y'] = 127,
-    [0xD8] = 128,
-    ['Z'] = 129,       ['z'] = 129,
-    ['['] = 130,
-    ['\\'] = 131,
-    [']'] = 132,
-    ['^'] = 133,
-    ['_'] = 134,
-    ['{'] = 135,
-    ['|'] = 136,
-    ['}'] = 137,
-    ['~'] = 138,
-    [0x7F] = 139,
-    [0xA0] = 140,
-    [0xA1] = 141,
-    [0xA2] = 142,
-    [0xA3] = 143,
-    [0xA4] = 144,
-    [0xA5] = 145,
-    [0xA6] = 146,
-    [0xA8] = 147,
-    [0xA9] = 148,
-    [0xAA] = 149,
-    [0xAB] = 150,
-    [0xAC] = 151,
-    [0xAD] = 152,
-    [0xB0] = 153,
-    [0xB1] = 154,
-    [0xB2] = 155,
-    [0xB3] = 156,
-    [0xB4] = 157,
-    [0xB5] = 158,
-    [0xB6] = 159,
-    [0xB7] = 160,
-    [0xB8] = 161,
-    [0xB9] = 162,
-    [0xBA] = 163,
-    [0xBD] = 164,
-    [0xC0] = 165,
-    [0xC1] = 166,
-    [0xC2] = 167,
-    [0xC3] = 168,
-    [0xC4] = 169,
-    [0xC5] = 170,
-    [0xC6] = 171,
-    [0xC9] = 172,
-    [0xD0] = 173,
-    [0xD1] = 174,
-    [0xD6] = 175,
-    [0xD7] = 176,
-    [0xD9] = 177,
-    [0xDA] = 178,
-    [0xDB] = 179,
-    [0xDC] = 180,
-    [0xDD] = 181,
-    [0xDE] = 182,
-    [0xDF] = 183,
-    [0xE0] = 184,
-    [0xE1] = 185,
-    [0xE2] = 186,
-    [0xE3] = 187,
-    [0xE4] = 188,
-    [0xE5] = 189,
-    [0xE6] = 190,
-    [0xE7] = 191,
-    [0xE8] = 192,
-    [0xE9] = 193,
-    [0xEA] = 194,
-    [0xEB] = 195,
-    [0xEC] = 196,
-    [0xED] = 197,
-    [0xEE] = 198,
-    [0xEF] = 199,
-    [0xF0] = 200,
-    [0xF1] = 201,
-    [0xF2] = 202,
-    [0xF3] = 203,
-    [0xF4] = 204,
-    [0xF5] = 205,
-    [0xF6] = 206,
-    [0xF7] = 207,
-    [0xF8] = 208,
-    [0xF9] = 209,
-    [0xFA] = 210,
-    [0xFB] = 211,
-    [0xFC] = 212,
-    [0xFD] = 213,
-    [0xFE] = 214,
-    [0xFF] = 215,
-  };
-  int i;
-  int cmp;
-  int minlen = (k1->strlen < k2->strlen) ? k1->strlen : k2->strlen;
-
-  cmp = (grub_be_to_cpu32 (k1->parent_dir) - grub_be_to_cpu32 (k2->parent_dir));
-  if (cmp != 0)
-    return cmp;
-
-  for (i = 0; i < minlen; i++)
-    {
-      cmp = (hfs_charorder[k1->str[i]] - hfs_charorder[k2->str[i]]);
-      if (cmp != 0)
-       return cmp;
-    }
-
-  /* Shorter strings precede long ones.  */
-  return (k1->strlen - k2->strlen);
-}
-
-
-/* Compare the K1 and K2 extent overflow file keys.  */
-static int
-grub_hfs_cmp_extkeys (struct grub_hfs_extent_key *k1,
-                     struct grub_hfs_extent_key *k2)
-{
-  int cmp = k1->forktype - k2->forktype;
-  if (cmp == 0)
-    cmp = grub_be_to_cpu32 (k1->fileid) - grub_be_to_cpu32 (k2->fileid);
-  if (cmp == 0)
-    cmp = (grub_be_to_cpu16 (k1->first_block)
-          - grub_be_to_cpu16 (k2->first_block));
-  return cmp;
-}
-
-
-/* Iterate the records in the node with index IDX in the mounted HFS
-   filesystem DATA.  This node holds data of the type TYPE (0 =
-   catalog node, 1 = extent overflow node).  If this is set, continue
-   iterating to the next node.  For every records, call NODE_HOOK.  */
-static grub_err_t
-grub_hfs_iterate_records (struct grub_hfs_data *data, int type, int idx,
-                         int this, int (*node_hook) (struct grub_hfs_node *hnd,
-                                                     struct grub_hfs_record *))
-{
-  int nodesize = type == 0 ? data->cat_size : data->ext_size;
-
-  union
-  {
-    struct grub_hfs_node node;
-    char rawnode[nodesize];
-    grub_uint16_t offsets[nodesize / 2];
-  } node;
-
-  do
-    {
-      int i;
-      struct grub_hfs_extent *dat;
-      int blk;
-
-      dat = (struct grub_hfs_extent *) (type == 0
-                                       ? (&data->sblock.catalog_recs)
-                                       : (&data->sblock.extent_recs));
-
-      /* Read the node into memory.  */
-      blk = grub_hfs_block (data, dat,
-                            (type == 0) ? GRUB_HFS_CNID_CAT : GRUB_HFS_CNID_EXT,
-                           idx / (data->blksz / nodesize), 0);
-      blk += (idx % (data->blksz / nodesize));
-      if (grub_errno)
-       return grub_errno;
-
-      if (grub_disk_read (data->disk, blk, 0,
-                         sizeof (node), &node))
-       return grub_errno;
-
-      /* Iterate over all records in this node.  */
-      for (i = 0; i < grub_be_to_cpu16 (node.node.reccnt); i++)
-       {
-         int pos = (nodesize >> 1) - 1 - i;
-         struct pointer
-         {
-           grub_uint8_t keylen;
-           grub_uint8_t key;
-         } __attribute__ ((packed)) *pnt;
-         pnt = (struct pointer *) (grub_be_to_cpu16 (node.offsets[pos])
-                                   + node.rawnode);
-
-         struct grub_hfs_record rec =
-           {
-             &pnt->key,
-             pnt->keylen,
-             &pnt->key + pnt->keylen +(pnt->keylen + 1) % 2,
-             nodesize - grub_be_to_cpu16 (node.offsets[pos])
-             - pnt->keylen - 1
-           };
-
-         if (node_hook (&node.node, &rec))
-           return 0;
-       }
-
-      idx = grub_be_to_cpu32 (node.node.next);
-    } while (idx && this);
-
-  return 0;
-}
-
-
-/* Lookup a record in the mounted filesystem DATA using the key KEY.
-   The index of the node on top of the tree is IDX.  The tree is of
-   the type TYPE (0 = catalog node, 1 = extent overflow node).  Return
-   the data in DATAR with a maximum length of DATALEN.  */
-static int
-grub_hfs_find_node (struct grub_hfs_data *data, char *key,
-                   grub_uint32_t idx, int type, char *datar, int datalen)
-{
-  int found = -1;
-  int isleaf = 0;
-  int done = 0;
-
-  auto int node_found (struct grub_hfs_node *, struct grub_hfs_record *);
-
-  int node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec)
-    {
-      int cmp = 1;
-
-      if (type == 0)
-       cmp = grub_hfs_cmp_catkeys (rec->key, (void *) key);
-      else
-       cmp = grub_hfs_cmp_extkeys (rec->key, (void *) key);
-
-      /* If the key is smaller or equal to the current node, mark the
-        entry.  In case of a non-leaf mode it will be used to lookup
-        the rest of the tree.  */
-      if (cmp <= 0)
-       {
-         grub_uint32_t *node = (grub_uint32_t *) rec->data;
-         found = grub_be_to_cpu32 (*node);
-       }
-      else /* The key can not be found in the tree. */
-       return 1;
-
-      /* Check if this node is a leaf node.  */
-      if (hnd->type == GRUB_HFS_NODE_LEAF)
-       {
-         isleaf = 1;
-
-         /* Found it!!!!  */
-         if (cmp == 0)
-           {
-              done = 1;
-
-             grub_memcpy (datar, rec->data,
-                          rec->datalen < datalen ? rec->datalen : datalen);
-             return 1;
-           }
-       }
-
-      return 0;
-    }
-
-  do
-    {
-      found = -1;
-
-      if (grub_hfs_iterate_records (data, type, idx, 0, node_found))
-        return 0;
-
-      if (found == -1)
-        return 0;
-
-      idx = found;
-    } while (! isleaf);
-
-  return done;
-}
-
-
-/* Iterate over the directory with the id DIR.  The tree is searched
-   starting with the node ROOT_IDX.  For every entry in this directory
-   call HOOK.  */
-static grub_err_t
-grub_hfs_iterate_dir (struct grub_hfs_data *data, grub_uint32_t root_idx,
-                     unsigned int dir, int (*hook) (struct grub_hfs_record *))
-{
-  int found = -1;
-  int isleaf = 0;
-  int next = 0;
-
-  /* The lowest key possible with DIR as root directory.  */
-  struct grub_hfs_catalog_key key = {0, grub_cpu_to_be32 (dir), 0, ""};
-
-  auto int node_found (struct grub_hfs_node *, struct grub_hfs_record *);
-  auto int it_dir (struct grub_hfs_node * __attribute ((unused)),
-                  struct grub_hfs_record *);
-
-
-  int node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec)
-    {
-      struct grub_hfs_catalog_key *ckey = rec->key;
-
-      if (grub_hfs_cmp_catkeys (rec->key, (void *) &key) <= 0)
-       found = grub_be_to_cpu32 (*(grub_uint32_t *) rec->data);
-
-      if (hnd->type == 0xFF && ckey->strlen > 0)
-       {
-         isleaf = 1;
-         next = grub_be_to_cpu32 (hnd->next);
-
-         /* An entry was found.  */
-         if (grub_be_to_cpu32 (ckey->parent_dir) == dir)
-           return hook (rec);
-       }
-
-      return 0;
-    }
-
-  int it_dir (struct grub_hfs_node *hnd __attribute ((unused)),
-             struct grub_hfs_record *rec)
-    {
-      struct grub_hfs_catalog_key *ckey = rec->key;
-      struct grub_hfs_catalog_key *origkey = &key;
-
-      /* Stop when the entries do not match anymore.  */
-      if (grub_be_to_cpu32 (ckey->parent_dir)
-         != grub_be_to_cpu32 ((origkey)->parent_dir))
-       return 1;
-
-      return hook (rec);
-    }
-
-  do
-    {
-      found = -1;
-
-      if (grub_hfs_iterate_records (data, 0, root_idx, 0, node_found))
-        return grub_errno;
-
-      if (found == -1)
-        return 0;
-
-      root_idx = found;
-    } while (! isleaf);
-
-  /* If there was a matching record in this leaf node, continue the
-     iteration until the last record was found.  */
-  grub_hfs_iterate_records (data, 0, next, 1, it_dir);
-  return grub_errno;
-}
-
-
-/* Find a file or directory with the pathname PATH in the filesystem
-   DATA.  Return the file record in RETDATA when it is non-zero.
-   Return the directory number in RETINODE when it is non-zero.  */
-static grub_err_t
-grub_hfs_find_dir (struct grub_hfs_data *data, const char *path,
-                  struct grub_hfs_filerec *retdata, int *retinode)
-{
-  int inode = data->rootdir;
-  char *next;
-  char *origpath;
-  union {
-    struct grub_hfs_filerec frec;
-    struct grub_hfs_dirrec dir;
-  } fdrec;
-
-  fdrec.frec.type = GRUB_HFS_FILETYPE_DIR;
-
-  if (path[0] != '/')
-    {
-      grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
-      return 0;
-    }
-
-  origpath = grub_strdup (path);
-  if (!origpath)
-    return grub_errno;
-
-  path = origpath;
-  while (*path == '/')
-    path++;
-
-  while (path && grub_strlen (path))
-    {
-      if (fdrec.frec.type != GRUB_HFS_FILETYPE_DIR)
-       {
-         grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-         goto fail;
-       }
-
-      /* Isolate a part of the path.  */
-      next = grub_strchr (path, '/');
-      if (next)
-       {
-         while (*next == '/')
-           *(next++) = '\0';
-       }
-
-      struct grub_hfs_catalog_key key;
-
-      key.parent_dir = grub_cpu_to_be32 (inode);
-      key.strlen = grub_strlen (path);
-      grub_strcpy ((char *) (key.str), path);
-
-      /* Lookup this node.  */
-      if (! grub_hfs_find_node (data, (char *) &key, data->cat_root,
-                               0, (char *) &fdrec.frec, sizeof (fdrec.frec)))
-       {
-         grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
-         goto fail;
-       }
-
-      if (grub_errno)
-       goto fail;
-
-      inode = grub_be_to_cpu32 (fdrec.dir.dirid);
-      path = next;
-    }
-
-  if (retdata)
-    grub_memcpy (retdata, &fdrec.frec, sizeof (fdrec.frec));
-
-  if (retinode)
-    *retinode = inode;
-
- fail:
-  grub_free (origpath);
-  return grub_errno;
-}
-
-
-\f
-static grub_err_t
-grub_hfs_dir (grub_device_t device, const char *path,
-                 int (*hook) (const char *filename,
-                              const struct grub_dirhook_info *info))
-{
-  int inode;
-
-  auto int dir_hook (struct grub_hfs_record *rec);
-
-  int dir_hook (struct grub_hfs_record *rec)
-    {
-      char fname[32] = { 0 };
-      char *filetype = rec->data;
-      struct grub_hfs_catalog_key *ckey = rec->key;
-      struct grub_dirhook_info info;
-      grub_memset (&info, 0, sizeof (info));
-
-      grub_strncpy (fname, (char *) (ckey->str), ckey->strlen);
-
-      if (*filetype == GRUB_HFS_FILETYPE_DIR
-         || *filetype == GRUB_HFS_FILETYPE_FILE)
-       {
-         info.dir = (*filetype == GRUB_HFS_FILETYPE_DIR);
-         return hook (fname, &info);
-       }
-      return 0;
-    }
-
-  struct grub_hfs_data *data;
-  struct grub_hfs_filerec frec;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_hfs_mount (device->disk);
-  if (!data)
-    goto fail;
-
-  /* First the directory ID for the directory.  */
-  if (grub_hfs_find_dir (data, path, &frec, &inode))
-    goto fail;
-
-  if (frec.type != GRUB_HFS_FILETYPE_DIR)
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-      goto fail;
-    }
-
-  grub_hfs_iterate_dir (data, data->cat_root, inode, dir_hook);
-
- fail:
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-
-/* Open a file named NAME and initialize FILE.  */
-static grub_err_t
-grub_hfs_open (struct grub_file *file, const char *name)
-{
-  struct grub_hfs_data *data;
-  struct grub_hfs_filerec frec;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_hfs_mount (file->device->disk);
-
-  if (grub_hfs_find_dir (data, name, &frec, 0))
-    {
-      grub_free (data);
-      grub_dl_unref (my_mod);
-      return grub_errno;
-    }
-
-  if (frec.type != GRUB_HFS_FILETYPE_FILE)
-    {
-      grub_free (data);
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a file");
-      grub_dl_unref (my_mod);
-      return grub_errno;
-    }
-
-  grub_memcpy (data->extents, frec.extents, sizeof (grub_hfs_datarecord_t));
-  file->size = grub_be_to_cpu32 (frec.size);
-  data->size = grub_be_to_cpu32 (frec.size);
-  data->fileid = grub_be_to_cpu32 (frec.fileid);
-  file->offset = 0;
-
-  file->data = data;
-
-  return 0;
-}
-
-static grub_ssize_t
-grub_hfs_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_hfs_data *data =
-    (struct grub_hfs_data *) file->data;
-
-  return grub_hfs_read_file (data, file->read_hook, file->offset, len, buf);
-}
-
-
-static grub_err_t
-grub_hfs_close (grub_file_t file)
-{
-  grub_free (file->data);
-
-  grub_dl_unref (my_mod);
-
-  return 0;
-}
-
-
-static grub_err_t
-grub_hfs_label (grub_device_t device, char **label)
-{
-  struct grub_hfs_data *data;
-
-  data = grub_hfs_mount (device->disk);
-
-  if (data)
-    *label = grub_strndup ((char *) (data->sblock.volname + 1),
-                          *data->sblock.volname);
-  else
-    *label = 0;
-
-  grub_free (data);
-  return grub_errno;
-}
-
-static grub_err_t
-grub_hfs_uuid (grub_device_t device, char **uuid)
-{
-  struct grub_hfs_data *data;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_hfs_mount (device->disk);
-  if (data && data->sblock.num_serial != 0)
-    {
-      *uuid = grub_xasprintf ("%016llx",
-                            (unsigned long long)
-                            grub_be_to_cpu64 (data->sblock.num_serial));
-    }
-  else
-    *uuid = NULL;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-
-\f
-static struct grub_fs grub_hfs_fs =
-  {
-    .name = "hfs",
-    .dir = grub_hfs_dir,
-    .open = grub_hfs_open,
-    .read = grub_hfs_read,
-    .close = grub_hfs_close,
-    .label = grub_hfs_label,
-    .uuid = grub_hfs_uuid,
-    .next = 0
-  };
-
-GRUB_MOD_INIT(hfs)
-{
-  grub_fs_register (&grub_hfs_fs);
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(hfs)
-{
-  grub_fs_unregister (&grub_hfs_fs);
-}
diff --git a/fs/hfsplus.c b/fs/hfsplus.c
deleted file mode 100644 (file)
index bcb8e95..0000000
+++ /dev/null
@@ -1,1039 +0,0 @@
-/* hfsplus.c - HFS+ Filesystem.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* HFS+ is documented at http://developer.apple.com/technotes/tn/tn1150.html */
-
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/types.h>
-#include <grub/fshelp.h>
-#include <grub/hfs.h>
-#include <grub/charset.h>
-
-#define GRUB_HFSPLUS_MAGIC 0x482B
-#define GRUB_HFSPLUSX_MAGIC 0x4858
-#define GRUB_HFSPLUS_SBLOCK 2
-
-/* A HFS+ extent.  */
-struct grub_hfsplus_extent
-{
-  /* The first block of a file on disk.  */
-  grub_uint32_t start;
-  /* The amount of blocks described by this extent.  */
-  grub_uint32_t count;
-} __attribute__ ((packed));
-
-/* The descriptor of a fork.  */
-struct grub_hfsplus_forkdata
-{
-  grub_uint64_t size;
-  grub_uint32_t clumpsize;
-  grub_uint32_t blocks;
-  struct grub_hfsplus_extent extents[8];
-} __attribute__ ((packed));
-
-/* The HFS+ Volume Header.  */
-struct grub_hfsplus_volheader
-{
-  grub_uint16_t magic;
-  grub_uint16_t version;
-  grub_uint32_t attributes;
-  grub_uint8_t unused1[12];
-  grub_uint32_t utime;
-  grub_uint8_t unused2[16];
-  grub_uint32_t blksize;
-  grub_uint8_t unused3[60];
-  grub_uint64_t num_serial;
-  struct grub_hfsplus_forkdata allocations_file;
-  struct grub_hfsplus_forkdata extents_file;
-  struct grub_hfsplus_forkdata catalog_file;
-  struct grub_hfsplus_forkdata attrib_file;
-  struct grub_hfsplus_forkdata startup_file;
-} __attribute__ ((packed));
-
-/* The type of node.  */
-enum grub_hfsplus_btnode_type
-  {
-    GRUB_HFSPLUS_BTNODE_TYPE_LEAF = -1,
-    GRUB_HFSPLUS_BTNODE_TYPE_INDEX = 0,
-    GRUB_HFSPLUS_BTNODE_TYPE_HEADER = 1,
-    GRUB_HFSPLUS_BTNODE_TYPE_MAP = 2,
-  };
-
-struct grub_hfsplus_btnode
-{
-  grub_uint32_t next;
-  grub_uint32_t prev;
-  grub_int8_t type;
-  grub_uint8_t height;
-  grub_uint16_t count;
-  grub_uint16_t unused;
-} __attribute__ ((packed));
-
-/* The header of a HFS+ B+ Tree.  */
-struct grub_hfsplus_btheader
-{
-  grub_uint16_t depth;
-  grub_uint32_t root;
-  grub_uint32_t leaf_records;
-  grub_uint32_t first_leaf_node;
-  grub_uint32_t last_leaf_node;
-  grub_uint16_t nodesize;
-  grub_uint16_t keysize;
-  grub_uint32_t total_nodes;
-  grub_uint32_t free_nodes;
-  grub_uint16_t reserved1;
-  grub_uint32_t clump_size;  /* ignored */
-  grub_uint8_t btree_type;
-  grub_uint8_t key_compare;
-  grub_uint32_t attributes;
-} __attribute__ ((packed));
-
-/* The on disk layout of a catalog key.  */
-struct grub_hfsplus_catkey
-{
-  grub_uint16_t keylen;
-  grub_uint32_t parent;
-  grub_uint16_t namelen;
-  grub_uint16_t name[30];
-} __attribute__ ((packed));
-
-/* The on disk layout of an extent overflow file key.  */
-struct grub_hfsplus_extkey
-{
-  grub_uint16_t keylen;
-  grub_uint8_t type;
-  grub_uint8_t unused;
-  grub_uint32_t fileid;
-  grub_uint32_t start;
-} __attribute__ ((packed));
-
-struct grub_hfsplus_key
-{
-  union
-  {
-    struct grub_hfsplus_extkey extkey;
-    struct grub_hfsplus_catkey catkey;
-    grub_uint16_t keylen;
-  };
-} __attribute__ ((packed));
-
-struct grub_hfsplus_catfile
-{
-  grub_uint16_t type;
-  grub_uint16_t flags;
-  grub_uint32_t reserved;
-  grub_uint32_t fileid;
-  grub_uint8_t unused1[4];
-  grub_uint32_t mtime;
-  grub_uint8_t unused2[22];
-  grub_uint16_t mode;
-  grub_uint8_t unused3[44];
-  struct grub_hfsplus_forkdata data;
-  struct grub_hfsplus_forkdata resource;
-} __attribute__ ((packed));
-
-/* Filetype information as used in inodes.  */
-#define GRUB_HFSPLUS_FILEMODE_MASK     0170000
-#define GRUB_HFSPLUS_FILEMODE_REG      0100000
-#define GRUB_HFSPLUS_FILEMODE_DIRECTORY        0040000
-#define GRUB_HFSPLUS_FILEMODE_SYMLINK  0120000
-
-/* Some pre-defined file IDs.  */
-#define GRUB_HFSPLUS_FILEID_ROOTDIR    2
-#define GRUB_HFSPLUS_FILEID_OVERFLOW   3
-#define GRUB_HFSPLUS_FILEID_CATALOG    4
-
-enum grub_hfsplus_filetype
-  {
-    GRUB_HFSPLUS_FILETYPE_DIR = 1,
-    GRUB_HFSPLUS_FILETYPE_REG = 2,
-    GRUB_HFSPLUS_FILETYPE_DIR_THREAD = 3,
-    GRUB_HFSPLUS_FILETYPE_REG_THREAD = 4
-  };
-
-#define GRUB_HFSPLUSX_BINARYCOMPARE    0xBC
-#define GRUB_HFSPLUSX_CASEFOLDING      0xCF
-
-/* Internal representation of a catalog key.  */
-struct grub_hfsplus_catkey_internal
-{
-  int parent;
-  char *name;
-};
-
-/* Internal representation of an extent overflow key.  */
-struct grub_hfsplus_extkey_internal
-{
-  grub_uint32_t fileid;
-  grub_uint32_t start;
-};
-
-struct grub_hfsplus_key_internal
-{
-  union
-  {
-    struct grub_hfsplus_extkey_internal extkey;
-    struct grub_hfsplus_catkey_internal catkey;
-  };
-};
-
-\f
-
-struct grub_fshelp_node
-{
-  struct grub_hfsplus_data *data;
-  struct grub_hfsplus_extent extents[8];
-  grub_uint64_t size;
-  grub_uint32_t fileid;
-  grub_int32_t mtime;
-};
-
-struct grub_hfsplus_btree
-{
-  grub_uint32_t root;
-  int nodesize;
-
-  /* Catalog file node.  */
-  struct grub_fshelp_node file;
-};
-
-/* Information about a "mounted" HFS+ filesystem.  */
-struct grub_hfsplus_data
-{
-  struct grub_hfsplus_volheader volheader;
-  grub_disk_t disk;
-
-  unsigned int log2blksize;
-
-  struct grub_hfsplus_btree catalog_tree;
-  struct grub_hfsplus_btree extoverflow_tree;
-
-  struct grub_fshelp_node dirroot;
-  struct grub_fshelp_node opened_file;
-
-  /* This is the offset into the physical disk for an embedded HFS+
-     filesystem (one inside a plain HFS wrapper).  */
-  int embedded_offset;
-  int case_sensitive;
-};
-
-static grub_dl_t my_mod;
-
-\f
-/* Return the offset of the record with the index INDEX, in the node
-   NODE which is part of the B+ tree BTREE.  */
-static inline unsigned int
-grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree,
-                          struct grub_hfsplus_btnode *node, int index)
-{
-  char *cnode = (char *) node;
-  grub_uint16_t *recptr;
-  recptr = (grub_uint16_t *) (&cnode[btree->nodesize
-                                    - index * sizeof (grub_uint16_t) - 2]);
-  return grub_be_to_cpu16 (*recptr);
-}
-
-/* Return a pointer to the record with the index INDEX, in the node
-   NODE which is part of the B+ tree BTREE.  */
-static inline struct grub_hfsplus_key *
-grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree,
-                          struct grub_hfsplus_btnode *node, int index)
-{
-  char *cnode = (char *) node;
-  unsigned int offset;
-  offset = grub_hfsplus_btree_recoffset (btree, node, index);
-  return (struct grub_hfsplus_key *) &cnode[offset];
-}
-
-
-/* Find the extent that points to FILEBLOCK.  If it is not in one of
-   the 8 extents described by EXTENT, return -1.  In that case set
-   FILEBLOCK to the next block.  */
-static int
-grub_hfsplus_find_block (struct grub_hfsplus_extent *extent,
-                        int *fileblock)
-{
-  int i;
-  grub_size_t blksleft = *fileblock;
-
-  /* First lookup the file in the given extents.  */
-  for (i = 0; i < 8; i++)
-    {
-      if (blksleft < grub_be_to_cpu32 (extent[i].count))
-       return grub_be_to_cpu32 (extent[i].start) + blksleft;
-      blksleft -= grub_be_to_cpu32 (extent[i].count);
-    }
-
-  *fileblock = blksleft;
-  return -1;
-}
-
-static grub_err_t
-grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
-                          struct grub_hfsplus_key_internal *key,
-                          int (*compare_keys) (struct grub_hfsplus_key *keya,
-                                               struct grub_hfsplus_key_internal *keyb),
-                          struct grub_hfsplus_btnode **matchnode, int *keyoffset);
-
-static int grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya,
-                                   struct grub_hfsplus_key_internal *keyb);
-
-/* Search for the block FILEBLOCK inside the file NODE.  Return the
-   blocknumber of this block on disk.  */
-static grub_disk_addr_t
-grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
-{
-  struct grub_hfsplus_btnode *nnode = 0;
-  int blksleft = fileblock;
-  struct grub_hfsplus_extent *extents = &node->extents[0];
-
-  while (1)
-    {
-      struct grub_hfsplus_extkey *key;
-      struct grub_hfsplus_extkey_internal extoverflow;
-      int blk;
-      int ptr;
-
-      /* Try to find this block in the current set of extents.  */
-      blk = grub_hfsplus_find_block (extents, &blksleft);
-
-      /* The previous iteration of this loop allocated memory.  The
-        code above used this memory, it can be freed now.  */
-      grub_free (nnode);
-      nnode = 0;
-
-      if (blk != -1)
-       return (blk
-               + (node->data->embedded_offset >> (node->data->log2blksize
-                                                  - GRUB_DISK_SECTOR_BITS)));
-
-      /* For the extent overflow file, extra extents can't be found in
-        the extent overflow file.  If this happens, you found a
-        bug...  */
-      if (node->fileid == GRUB_HFSPLUS_FILEID_OVERFLOW)
-       {
-         grub_error (GRUB_ERR_READ_ERROR,
-                     "extra extents found in an extend overflow file");
-         break;
-       }
-
-      /* Set up the key to look for in the extent overflow file.  */
-      extoverflow.fileid = node->fileid;
-      extoverflow.start = fileblock - blksleft;
-
-      if (grub_hfsplus_btree_search (&node->data->extoverflow_tree,
-                                    (struct grub_hfsplus_key_internal *) &extoverflow,
-                                    grub_hfsplus_cmp_extkey, &nnode, &ptr))
-       {
-         grub_error (GRUB_ERR_READ_ERROR,
-                     "no block found for the file id 0x%x and the block offset 0x%x",
-                     node->fileid, fileblock);
-         break;
-       }
-
-      /* The extent overflow file has 8 extents right after the key.  */
-      key = (struct grub_hfsplus_extkey *)
-       grub_hfsplus_btree_recptr (&node->data->extoverflow_tree, nnode, ptr);
-      extents = (struct grub_hfsplus_extent *) (key + 1);
-
-      /* The block wasn't found.  Perhaps the next iteration will find
-        it.  The last block we found is stored in BLKSLEFT now.  */
-    }
-
-  grub_free (nnode);
-
-  /* Too bad, you lose.  */
-  return -1;
-}
-
-
-/* Read LEN bytes from the file described by DATA starting with byte
-   POS.  Return the amount of read bytes in READ.  */
-static grub_ssize_t
-grub_hfsplus_read_file (grub_fshelp_node_t node,
-                       void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                          unsigned offset, unsigned length),
-                       int pos, grub_size_t len, char *buf)
-{
-  return grub_fshelp_read_file (node->data->disk, node, read_hook,
-                               pos, len, buf, grub_hfsplus_read_block,
-                               node->size,
-                               node->data->log2blksize - GRUB_DISK_SECTOR_BITS);
-}
-
-static struct grub_hfsplus_data *
-grub_hfsplus_mount (grub_disk_t disk)
-{
-  struct grub_hfsplus_data *data;
-  struct grub_hfsplus_btheader header;
-  struct grub_hfsplus_btnode node;
-  grub_uint16_t magic;
-  union {
-    struct grub_hfs_sblock hfs;
-    struct grub_hfsplus_volheader hfsplus;
-  } volheader;
-
-  data = grub_malloc (sizeof (*data));
-  if (!data)
-    return 0;
-
-  data->disk = disk;
-
-  /* Read the bootblock.  */
-  grub_disk_read (disk, GRUB_HFSPLUS_SBLOCK, 0, sizeof (volheader),
-                 &volheader);
-  if (grub_errno)
-    goto fail;
-
-  data->embedded_offset = 0;
-  if (grub_be_to_cpu16 (volheader.hfs.magic) == GRUB_HFS_MAGIC)
-    {
-      int extent_start;
-      int ablk_size;
-      int ablk_start;
-
-      /* See if there's an embedded HFS+ filesystem.  */
-      if (grub_be_to_cpu16 (volheader.hfs.embed_sig) != GRUB_HFSPLUS_MAGIC)
-       {
-         grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem");
-         goto fail;
-       }
-
-      /* Calculate the offset needed to translate HFS+ sector numbers.  */
-      extent_start = grub_be_to_cpu16 (volheader.hfs.embed_extent.first_block);
-      ablk_size = grub_be_to_cpu32 (volheader.hfs.blksz);
-      ablk_start = grub_be_to_cpu16 (volheader.hfs.first_block);
-      data->embedded_offset = (ablk_start
-                              + extent_start
-                              * (ablk_size >> GRUB_DISK_SECTOR_BITS));
-
-      grub_disk_read (disk, data->embedded_offset + GRUB_HFSPLUS_SBLOCK, 0,
-                     sizeof (volheader), &volheader);
-      if (grub_errno)
-       goto fail;
-    }
-
-  /* Make sure this is an HFS+ filesystem.  XXX: Do we really support
-     HFX?  */
-  magic = grub_be_to_cpu16 (volheader.hfsplus.magic);
-  if ((magic != GRUB_HFSPLUS_MAGIC) && (magic != GRUB_HFSPLUSX_MAGIC))
-    {
-      grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem");
-      goto fail;
-    }
-
-  grub_memcpy (&data->volheader, &volheader.hfsplus,
-      sizeof (volheader.hfsplus));
-
-  if (grub_fshelp_log2blksize (grub_be_to_cpu32 (data->volheader.blksize),
-                              &data->log2blksize))
-    goto fail;
-
-  /* Make a new node for the catalog tree.  */
-  data->catalog_tree.file.data = data;
-  data->catalog_tree.file.fileid = GRUB_HFSPLUS_FILEID_CATALOG;
-  grub_memcpy (&data->catalog_tree.file.extents,
-              data->volheader.catalog_file.extents,
-              sizeof data->volheader.catalog_file.extents);
-  data->catalog_tree.file.size =
-    grub_be_to_cpu64 (data->volheader.catalog_file.size);
-
-  /* Make a new node for the extent overflow file.  */
-  data->extoverflow_tree.file.data = data;
-  data->extoverflow_tree.file.fileid = GRUB_HFSPLUS_FILEID_OVERFLOW;
-  grub_memcpy (&data->extoverflow_tree.file.extents,
-              data->volheader.extents_file.extents,
-              sizeof data->volheader.catalog_file.extents);
-
-  data->extoverflow_tree.file.size =
-    grub_be_to_cpu64 (data->volheader.extents_file.size);
-
-  /* Read the essential information about the trees.  */
-  if (grub_hfsplus_read_file (&data->catalog_tree.file, 0,
-                             sizeof (struct grub_hfsplus_btnode),
-                             sizeof (header), (char *) &header) <= 0)
-    goto fail;
-
-  data->catalog_tree.root = grub_be_to_cpu32 (header.root);
-  data->catalog_tree.nodesize = grub_be_to_cpu16 (header.nodesize);
-  data->case_sensitive = ((magic == GRUB_HFSPLUSX_MAGIC) &&
-                         (header.key_compare == GRUB_HFSPLUSX_BINARYCOMPARE));
-
-  if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0,
-                             sizeof (struct grub_hfsplus_btnode),
-                             sizeof (header), (char *) &header) <= 0)
-    goto fail;
-
-  data->extoverflow_tree.root = grub_be_to_cpu32 (header.root);
-
-  if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0,
-                             sizeof (node), (char *) &node) <= 0)
-    goto fail;
-
-  data->extoverflow_tree.root = grub_be_to_cpu32 (header.root);
-  data->extoverflow_tree.nodesize = grub_be_to_cpu16 (header.nodesize);
-
-  data->dirroot.data = data;
-  data->dirroot.fileid = GRUB_HFSPLUS_FILEID_ROOTDIR;
-
-  return data;
-
- fail:
-
-  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
-    grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem");
-
-  grub_free (data);
-  return 0;
-}
-
-/* Compare the on disk catalog key KEYA with the catalog key we are
-   looking for (KEYB).  */
-static int
-grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya,
-                        struct grub_hfsplus_key_internal *keyb)
-{
-  struct grub_hfsplus_catkey *catkey_a = &keya->catkey;
-  struct grub_hfsplus_catkey_internal *catkey_b = &keyb->catkey;
-  char *filename;
-  int i;
-  int diff;
-
-  diff = grub_be_to_cpu32 (catkey_a->parent) - catkey_b->parent;
-  if (diff)
-    return diff;
-
-  /* Change the filename in keya so the endianness is correct.  */
-  for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++)
-    catkey_a->name[i] = grub_be_to_cpu16 (catkey_a->name[i]);
-
-  filename = grub_malloc (grub_be_to_cpu16 (catkey_a->namelen) + 1);
-
-  if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey_a->name,
-                           grub_be_to_cpu16 (catkey_a->namelen)))
-    return -1; /* XXX: This error never occurs, but in case it happens
-                 just skip this entry.  */
-
-  diff = grub_strncmp (filename, catkey_b->name,
-                      grub_be_to_cpu16 (catkey_a->namelen));
-
-  grub_free (filename);
-
-  /* The endianness was changed to host format, change it back to
-     whatever it was.  */
-  for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++)
-    catkey_a->name[i] = grub_cpu_to_be16 (catkey_a->name[i]);
-  return diff;
-}
-
-/* Compare the on disk extent overflow key KEYA with the extent
-   overflow key we are looking for (KEYB).  */
-static int
-grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya,
-                        struct grub_hfsplus_key_internal *keyb)
-{
-  struct grub_hfsplus_extkey *extkey_a = &keya->extkey;
-  struct grub_hfsplus_extkey_internal *extkey_b = &keyb->extkey;
-  int diff;
-
-  diff = grub_be_to_cpu32 (extkey_a->fileid) - extkey_b->fileid;
-
-  if (diff)
-    return diff;
-
-  diff = grub_be_to_cpu32 (extkey_a->start) - extkey_b->start;
-  return diff;
-}
-
-static char *
-grub_hfsplus_read_symlink (grub_fshelp_node_t node)
-{
-  char *symlink;
-  grub_ssize_t numread;
-
-  symlink = grub_malloc (node->size + 1);
-  if (!symlink)
-    return 0;
-
-  numread = grub_hfsplus_read_file (node, 0, 0, node->size, symlink);
-  if (numread != (grub_ssize_t) node->size)
-    {
-      grub_free (symlink);
-      return 0;
-    }
-  symlink[node->size] = '\0';
-
-  return symlink;
-}
-
-static int
-grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree,
-                                struct grub_hfsplus_btnode *first_node,
-                                int first_rec,
-                                int (*hook) (void *record))
-{
-  int rec;
-
-  for (;;)
-    {
-      char *cnode = (char *) first_node;
-
-      /* Iterate over all records in this node.  */
-      for (rec = first_rec; rec < grub_be_to_cpu16 (first_node->count); rec++)
-       {
-         if (hook (grub_hfsplus_btree_recptr (btree, first_node, rec)))
-           return 1;
-       }
-
-      if (! first_node->next)
-       break;
-
-      if (grub_hfsplus_read_file (&btree->file, 0,
-                                 (grub_be_to_cpu32 (first_node->next)
-                                  * btree->nodesize),
-                                 btree->nodesize, cnode) <= 0)
-       return 1;
-
-      /* Don't skip any record in the next iteration.  */
-      first_rec = 0;
-    }
-
-  return 0;
-}
-
-/* Lookup the node described by KEY in the B+ Tree BTREE.  Compare
-   keys using the function COMPARE_KEYS.  When a match is found,
-   return the node in MATCHNODE and a pointer to the data in this node
-   in KEYOFFSET.  MATCHNODE should be freed by the caller.  */
-static grub_err_t
-grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
-                          struct grub_hfsplus_key_internal *key,
-                          int (*compare_keys) (struct grub_hfsplus_key *keya,
-                                               struct grub_hfsplus_key_internal *keyb),
-                          struct grub_hfsplus_btnode **matchnode, int *keyoffset)
-{
-  grub_uint64_t currnode;
-  char *node;
-  struct grub_hfsplus_btnode *nodedesc;
-  int rec;
-
-  node = grub_malloc (btree->nodesize);
-  if (! node)
-    return grub_errno;
-
-  currnode = btree->root;
-  while (1)
-    {
-      int match = 0;
-
-      /* Read a node.  */
-      if (grub_hfsplus_read_file (&btree->file, 0,
-                                 (long)currnode * (long)btree->nodesize,
-                                 btree->nodesize, (char *) node) <= 0)
-       {
-         grub_free (node);
-         return grub_error (GRUB_ERR_BAD_FS, "couldn't read i-node");
-       }
-
-      nodedesc = (struct grub_hfsplus_btnode *) node;
-
-      /* Find the record in this tree.  */
-      for (rec = 0; rec < grub_be_to_cpu16 (nodedesc->count); rec++)
-       {
-         struct grub_hfsplus_key *currkey;
-         currkey = grub_hfsplus_btree_recptr (btree, nodedesc, rec);
-
-         /* The action that has to be taken depend on the type of
-            record.  */
-         if (nodedesc->type == GRUB_HFSPLUS_BTNODE_TYPE_LEAF
-             && compare_keys (currkey, key) == 0)
-           {
-             /* An exact match was found!  */
-
-             *matchnode = nodedesc;
-             *keyoffset = rec;
-
-             return 0;
-           }
-         else if (nodedesc->type == GRUB_HFSPLUS_BTNODE_TYPE_INDEX)
-           {
-             grub_uint32_t *pointer;
-
-             /* The place where the key could have been found didn't
-                contain the key.  This means that the previous match
-                is the one that should be followed.  */
-             if (compare_keys (currkey, key) > 0)
-               break;
-
-             /* Mark the last key which is lower or equal to the key
-                that we are looking for.  The last match that is
-                found will be used to locate the child which can
-                contain the record.  */
-             pointer = (grub_uint32_t *) ((char *) currkey
-                                          + grub_be_to_cpu16 (currkey->keylen)
-                                          + 2);
-             currnode = grub_be_to_cpu32 (*pointer);
-             match = 1;
-           }
-       }
-
-      /* No match is found, no record with this key exists in the
-        tree.  */
-      if (! match)
-       {
-         *matchnode = 0;
-         grub_free (node);
-         return 1;
-       }
-    }
-}
-
-static int
-grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
-                         int NESTED_FUNC_ATTR
-                         (*hook) (const char *filename,
-                                  enum grub_fshelp_filetype filetype,
-                                  grub_fshelp_node_t node))
-{
-  int ret = 0;
-
-  auto int list_nodes (void *record);
-  int list_nodes (void *record)
-    {
-      struct grub_hfsplus_catkey *catkey;
-      char *filename;
-      int i;
-      struct grub_fshelp_node *node;
-      struct grub_hfsplus_catfile *fileinfo;
-      enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN;
-
-      catkey = (struct grub_hfsplus_catkey *) record;
-
-      fileinfo =
-       (struct grub_hfsplus_catfile *) ((char *) record
-                                        + grub_be_to_cpu16 (catkey->keylen)
-                                        + 2 + (grub_be_to_cpu16(catkey->keylen)
-                                               % 2));
-
-      /* Stop iterating when the last directory entry is found.  */
-      if (grub_be_to_cpu32 (catkey->parent) != dir->fileid)
-       return 1;
-
-      /* Determine the type of the node that is found.  */
-      if (grub_be_to_cpu16 (fileinfo->type) == GRUB_HFSPLUS_FILETYPE_REG)
-       {
-         int mode = (grub_be_to_cpu16 (fileinfo->mode)
-                     & GRUB_HFSPLUS_FILEMODE_MASK);
-
-         if (mode == GRUB_HFSPLUS_FILEMODE_REG)
-           type = GRUB_FSHELP_REG;
-         else if (mode == GRUB_HFSPLUS_FILEMODE_SYMLINK)
-           type = GRUB_FSHELP_SYMLINK;
-         else
-           type = GRUB_FSHELP_UNKNOWN;
-       }
-      else if (grub_be_to_cpu16 (fileinfo->type) == GRUB_HFSPLUS_FILETYPE_DIR)
-       type = GRUB_FSHELP_DIR;
-
-      if (type == GRUB_FSHELP_UNKNOWN)
-       return 0;
-
-      /* Make sure the byte order of the UTF16 string is correct.  */
-      for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++)
-       {
-         catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]);
-
-         /* If the name is obviously invalid, skip this node.  */
-         if (catkey->name[i] == 0)
-           return 0;
-       }
-
-      filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen) + 1);
-      if (! filename)
-       return 0;
-
-      if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name,
-                               grub_be_to_cpu16 (catkey->namelen)))
-       {
-         grub_free (filename);
-         return 0;
-       }
-
-      filename[grub_be_to_cpu16 (catkey->namelen)] = '\0';
-
-      /* Restore the byte order to what it was previously.  */
-      for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++)
-       catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]);
-
-      /* hfs+ is case insensitive.  */
-      if (! dir->data->case_sensitive)
-       type |= GRUB_FSHELP_CASE_INSENSITIVE;
-
-      /* Only accept valid nodes.  */
-      if (grub_strlen (filename) == grub_be_to_cpu16 (catkey->namelen))
-       {
-         /* A valid node is found; setup the node and call the
-            callback function.  */
-         node = grub_malloc (sizeof (*node));
-         node->data = dir->data;
-
-         grub_memcpy (node->extents, fileinfo->data.extents,
-                      sizeof (node->extents));
-         node->mtime = grub_be_to_cpu32 (fileinfo->mtime) - 2082844800;
-         node->size = grub_be_to_cpu64 (fileinfo->data.size);
-         node->fileid = grub_be_to_cpu32 (fileinfo->fileid);
-
-         ret = hook (filename, type, node);
-       }
-
-      grub_free (filename);
-
-      return ret;
-    }
-
-  struct grub_hfsplus_key_internal intern;
-  struct grub_hfsplus_btnode *node;
-  int ptr;
-
-  /* Create a key that points to the first entry in the directory.  */
-  intern.catkey.parent = dir->fileid;
-  intern.catkey.name = "";
-
-  /* First lookup the first entry.  */
-  if (grub_hfsplus_btree_search (&dir->data->catalog_tree, &intern,
-                                grub_hfsplus_cmp_catkey, &node, &ptr))
-    return 0;
-
-  /* Iterate over all entries in this directory.  */
-  grub_hfsplus_btree_iterate_node (&dir->data->catalog_tree, node, ptr,
-                                  list_nodes);
-
-  grub_free (node);
-
-  return ret;
-}
-
-/* Open a file named NAME and initialize FILE.  */
-static grub_err_t
-grub_hfsplus_open (struct grub_file *file, const char *name)
-{
-  struct grub_hfsplus_data *data;
-  struct grub_fshelp_node *fdiro = 0;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_hfsplus_mount (file->device->disk);
-  if (!data)
-    goto fail;
-
-  grub_fshelp_find_file (name, &data->dirroot, &fdiro,
-                        grub_hfsplus_iterate_dir,
-                        grub_hfsplus_read_symlink, GRUB_FSHELP_REG);
-  if (grub_errno)
-    goto fail;
-
-  file->size = fdiro->size;
-  data->opened_file = *fdiro;
-  grub_free (fdiro);
-
-  file->data = data;
-  file->offset = 0;
-
-  return 0;
-
- fail:
-  if (data && fdiro != &data->dirroot)
-    grub_free (fdiro);
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-
-static grub_err_t
-grub_hfsplus_close (grub_file_t file)
-{
-  grub_free (file->data);
-
-  grub_dl_unref (my_mod);
-
-  return GRUB_ERR_NONE;
-}
-
-
-/* Read LEN bytes data from FILE into BUF.  */
-static grub_ssize_t
-grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_hfsplus_data *data =
-    (struct grub_hfsplus_data *) file->data;
-
-  int size = grub_hfsplus_read_file (&data->opened_file, file->read_hook,
-                                    file->offset, len, buf);
-
-  return size;
-}
-
-
-static grub_err_t
-grub_hfsplus_dir (grub_device_t device, const char *path,
-                 int (*hook) (const char *filename,
-                              const struct grub_dirhook_info *info))
-{
-  struct grub_hfsplus_data *data = 0;
-  struct grub_fshelp_node *fdiro = 0;
-
-  auto int NESTED_FUNC_ATTR iterate (const char *filename,
-                                    enum grub_fshelp_filetype filetype,
-                                    grub_fshelp_node_t node);
-
-  int NESTED_FUNC_ATTR iterate (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node)
-    {
-      struct grub_dirhook_info info;
-      grub_memset (&info, 0, sizeof (info));
-      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
-      info.mtimeset = 1;
-      info.mtime = node->mtime;
-      info.case_insensitive = !! (filetype & GRUB_FSHELP_CASE_INSENSITIVE);
-      grub_free (node);
-      return hook (filename, &info);
-    }
-
-  grub_dl_ref (my_mod);
-
-  data = grub_hfsplus_mount (device->disk);
-  if (!data)
-    goto fail;
-
-  /* Find the directory that should be opened.  */
-  grub_fshelp_find_file (path, &data->dirroot, &fdiro,
-                        grub_hfsplus_iterate_dir,
-                        grub_hfsplus_read_symlink, GRUB_FSHELP_DIR);
-  if (grub_errno)
-    goto fail;
-
-  /* Iterate over all entries in this directory.  */
-  grub_hfsplus_iterate_dir (fdiro, iterate);
-
- fail:
-  if (data && fdiro != &data->dirroot)
-    grub_free (fdiro);
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-
-static grub_err_t
-grub_hfsplus_label (grub_device_t device __attribute__((unused))
-                   , char **label __attribute__((unused)))
-{
-  /* XXX: It's not documented how to read a label.  */
-  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                    "reading the label of a HFS+ "
-                    "partition is not implemented");
-}
-
-/* Get mtime.  */
-static grub_err_t
-grub_hfsplus_mtime (grub_device_t device, grub_int32_t *tm)
-{
-  struct grub_hfsplus_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_hfsplus_mount (disk);
-  if (!data)
-    *tm = 0;
-  else
-    *tm = grub_be_to_cpu32 (data->volheader.utime) - 2082844800;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-
-}
-
-static grub_err_t
-grub_hfsplus_uuid (grub_device_t device, char **uuid)
-{
-  struct grub_hfsplus_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_hfsplus_mount (disk);
-  if (data)
-    {
-      *uuid = grub_xasprintf ("%016llx",
-                            (unsigned long long)
-                            grub_be_to_cpu64 (data->volheader.num_serial));
-    }
-  else
-    *uuid = NULL;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-
-\f
-static struct grub_fs grub_hfsplus_fs =
-  {
-    .name = "hfsplus",
-    .dir = grub_hfsplus_dir,
-    .open = grub_hfsplus_open,
-    .read = grub_hfsplus_read,
-    .close = grub_hfsplus_close,
-    .label = grub_hfsplus_label,
-    .mtime = grub_hfsplus_mtime,
-    .uuid = grub_hfsplus_uuid,
-#ifdef GRUB_UTIL
-    .reserved_first_sector = 1,
-#endif
-    .next = 0
-  };
-
-GRUB_MOD_INIT(hfsplus)
-{
-  grub_fs_register (&grub_hfsplus_fs);
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(hfsplus)
-{
-  grub_fs_unregister (&grub_hfsplus_fs);
-}
diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c
deleted file mode 100644 (file)
index 82d8ee5..0000000
+++ /dev/null
@@ -1,595 +0,0 @@
-/* pxe.c - Driver to provide access to the pxe filesystem  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/fs.h>
-#include <grub/mm.h>
-#include <grub/disk.h>
-#include <grub/file.h>
-#include <grub/misc.h>
-#include <grub/bufio.h>
-#include <grub/env.h>
-
-#include <grub/machine/pxe.h>
-#include <grub/machine/memory.h>
-
-#define SEGMENT(x)     ((x) >> 4)
-#define OFFSET(x)      ((x) & 0xF)
-#define SEGOFS(x)      ((SEGMENT(x) << 16) + OFFSET(x))
-#define LINEAR(x)      (void *) (((x >> 16) <<4) + (x & 0xFFFF))
-
-struct grub_pxe_disk_data
-{
-  grub_uint32_t server_ip;
-  grub_uint32_t gateway_ip;
-};
-
-struct grub_pxenv *grub_pxe_pxenv;
-static grub_uint32_t grub_pxe_your_ip;
-static grub_uint32_t grub_pxe_default_server_ip;
-static grub_uint32_t grub_pxe_default_gateway_ip;
-static unsigned grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE;
-
-static grub_file_t curr_file = 0;
-
-struct grub_pxe_data
-{
-  grub_uint32_t packet_number;
-  grub_uint32_t block_size;
-  char filename[0];
-};
-
-static int
-grub_pxe_iterate (int (*hook) (const char *name))
-{
-  if (hook ("pxe"))
-    return 1;
-  return 0;
-}
-
-static grub_err_t
-parse_ip (const char *val, grub_uint32_t *ip, const char **rest)
-{
-  grub_uint32_t newip = 0;
-  unsigned long t;
-  int i;
-  const char *ptr = val;
-
-  for (i = 0; i < 4; i++)
-    {
-      t = grub_strtoul (ptr, (char **) &ptr, 0);
-      if (grub_errno)
-       return grub_errno;
-      if (t & ~0xff)
-       return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
-      newip >>= 8;
-      newip |= (t << 24);
-      if (i != 3 && *ptr != '.')
-       return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
-      ptr++;
-    }
-  *ip = newip;
-  if (rest)
-    *rest = ptr - 1;
-  return 0;
-}
-
-static grub_err_t
-grub_pxe_open (const char *name, grub_disk_t disk)
-{
-  struct grub_pxe_disk_data *data;
-
-  if (grub_strcmp (name, "pxe") != 0
-      && grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) != 0)
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a pxe disk");
-
-  data = grub_malloc (sizeof (*data));
-  if (!data)
-    return grub_errno;
-
-  if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0)
-    {
-      const char *ptr;
-      grub_err_t err;
-
-      ptr = name + sizeof ("pxe:") - 1;
-      err = parse_ip (ptr, &(data->server_ip), &ptr);
-      if (err)
-       return err;
-      if (*ptr == ':')
-       {
-         err = parse_ip (ptr + 1, &(data->server_ip), 0);
-         if (err)
-           return err;
-       }
-      else
-       data->gateway_ip = grub_pxe_default_gateway_ip;
-    }
-  else
-    {
-      data->server_ip = grub_pxe_default_server_ip;
-      data->gateway_ip = grub_pxe_default_gateway_ip;
-    }
-
-  disk->total_sectors = 0;
-  disk->id = (unsigned long) data;
-
-  disk->has_partitions = 0;
-  disk->data = data;
-
-  return GRUB_ERR_NONE;
-}
-
-static void
-grub_pxe_close (grub_disk_t disk)
-{
-  grub_free (disk->data);
-}
-
-static grub_err_t
-grub_pxe_read (grub_disk_t disk __attribute((unused)),
-               grub_disk_addr_t sector __attribute((unused)),
-               grub_size_t size __attribute((unused)),
-               char *buf __attribute((unused)))
-{
-  return GRUB_ERR_OUT_OF_RANGE;
-}
-
-static grub_err_t
-grub_pxe_write (grub_disk_t disk __attribute((unused)),
-                grub_disk_addr_t sector __attribute((unused)),
-                grub_size_t size __attribute((unused)),
-                const char *buf __attribute((unused)))
-{
-  return GRUB_ERR_OUT_OF_RANGE;
-}
-
-static struct grub_disk_dev grub_pxe_dev =
-  {
-    .name = "pxe",
-    .id = GRUB_DISK_DEVICE_PXE_ID,
-    .iterate = grub_pxe_iterate,
-    .open = grub_pxe_open,
-    .close = grub_pxe_close,
-    .read = grub_pxe_read,
-    .write = grub_pxe_write,
-    .next = 0
-  };
-
-static grub_err_t
-grub_pxefs_dir (grub_device_t device,
-               const char *path  __attribute__ ((unused)),
-               int (*hook) (const char *filename,
-                            const struct grub_dirhook_info *info)
-               __attribute__ ((unused)))
-{
-  if (device->disk->dev->id != GRUB_DISK_DEVICE_PXE_ID)
-    return grub_error (GRUB_ERR_IO, "not a pxe disk");
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_pxefs_open (struct grub_file *file, const char *name)
-{
-  union
-    {
-      struct grub_pxenv_tftp_get_fsize c1;
-      struct grub_pxenv_tftp_open c2;
-    } c;
-  struct grub_pxe_data *data;
-  struct grub_pxe_disk_data *disk_data = file->device->disk->data;
-  grub_file_t file_int, bufio;
-
-  if (file->device->disk->dev->id != GRUB_DISK_DEVICE_PXE_ID)
-    return grub_error (GRUB_ERR_IO, "not a pxe disk");
-
-  if (curr_file != 0)
-    {
-      grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c.c2);
-      curr_file = 0;
-    }
-
-  c.c1.server_ip = disk_data->server_ip;
-  c.c1.gateway_ip = disk_data->gateway_ip;
-  grub_strcpy ((char *)&c.c1.filename[0], name);
-  grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1);
-  if (c.c1.status)
-    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
-
-  file->size = c.c1.file_size;
-
-  c.c2.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
-  c.c2.packet_size = grub_pxe_blksize;
-  grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &c.c2);
-  if (c.c2.status)
-    return grub_error (GRUB_ERR_BAD_FS, "open fails");
-
-  data = grub_zalloc (sizeof (struct grub_pxe_data) + grub_strlen (name) + 1);
-  if (! data)
-    return grub_errno;
-
-  data->block_size = c.c2.packet_size;
-  grub_strcpy (data->filename, name);
-
-  file_int = grub_malloc (sizeof (*file_int));
-  if (! file_int)
-    {
-      grub_free (data);
-      return grub_errno;
-    }
-
-  file->data = data;
-  grub_memcpy (file_int, file, sizeof (struct grub_file));
-  curr_file = file_int;
-
-  bufio = grub_bufio_open (file_int, data->block_size);
-  if (! bufio)
-    {
-      grub_free (file_int);
-      grub_free (data);
-      return grub_errno;
-    }
-
-  grub_memcpy (file, bufio, sizeof (struct grub_file));
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_ssize_t
-grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_pxenv_tftp_read c;
-  struct grub_pxe_data *data;
-  struct grub_pxe_disk_data *disk_data = file->device->disk->data;
-  grub_uint32_t pn, r;
-
-  data = file->data;
-
-  pn = grub_divmod64 (file->offset, data->block_size, &r);
-  if (r)
-    {
-      grub_error (GRUB_ERR_BAD_FS,
-                 "read access must be aligned to packet size");
-      return -1;
-    }
-
-  if ((curr_file != file) || (data->packet_number > pn))
-    {
-      struct grub_pxenv_tftp_open o;
-
-      if (curr_file != 0)
-        grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o);
-
-      o.server_ip = disk_data->server_ip;
-      o.gateway_ip = disk_data->gateway_ip;
-      grub_strcpy ((char *)&o.filename[0], data->filename);
-      o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
-      o.packet_size = grub_pxe_blksize;
-      grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o);
-      if (o.status)
-       {
-         grub_error (GRUB_ERR_BAD_FS, "open fails");
-         return -1;
-       }
-      data->block_size = o.packet_size;
-      data->packet_number = 0;
-      curr_file = file;
-    }
-
-  c.buffer = SEGOFS (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
-  while (pn >= data->packet_number)
-    {
-      c.buffer_size = data->block_size;
-      grub_pxe_call (GRUB_PXENV_TFTP_READ, &c);
-      if (c.status)
-        {
-          grub_error (GRUB_ERR_BAD_FS, "read fails");
-          return -1;
-        }
-      data->packet_number++;
-    }
-
-  grub_memcpy (buf, (char *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, len);
-
-  return len;
-}
-
-static grub_err_t
-grub_pxefs_close (grub_file_t file)
-{
-  struct grub_pxenv_tftp_close c;
-
-  if (curr_file == file)
-    {
-      grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c);
-      curr_file = 0;
-    }
-
-  grub_free (file->data);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_pxefs_label (grub_device_t device __attribute ((unused)),
-                  char **label __attribute ((unused)))
-{
-  *label = 0;
-  return GRUB_ERR_NONE;
-}
-
-static struct grub_fs grub_pxefs_fs =
-  {
-    .name = "pxefs",
-    .dir = grub_pxefs_dir,
-    .open = grub_pxefs_open,
-    .read = grub_pxefs_read,
-    .close = grub_pxefs_close,
-    .label = grub_pxefs_label,
-    .next = 0
-  };
-
-static char *
-grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)),
-                        const char *val __attribute__ ((unused)))
-{
-  return NULL;
-}
-
-static void
-set_mac_env (grub_uint8_t *mac_addr, grub_size_t mac_len)
-{
-  char buf[(sizeof ("XX:") - 1) * mac_len + 1];
-  char *ptr = buf;
-  unsigned i;
-
-  for (i = 0; i < mac_len; i++)
-    {
-      grub_snprintf (ptr, sizeof (buf) - (ptr - buf),
-                    "%02x:", mac_addr[i] & 0xff);
-      ptr += (sizeof ("XX:") - 1);
-    }
-  if (mac_len)
-    *(ptr - 1) = 0;
-  else
-    buf[0] = 0;
-
-  grub_env_set ("net_pxe_mac", buf);
-  /* XXX: Is it possible to change MAC in PXE?  */
-  grub_register_variable_hook ("net_pxe_mac", 0, grub_env_write_readonly);
-}
-
-static void
-set_env_limn_ro (const char *varname, char *value, grub_size_t len)
-{
-  char c;
-  c = value[len];
-  value[len] = 0;
-  grub_env_set (varname, value);
-  value[len] = c;
-  grub_register_variable_hook (varname, 0, grub_env_write_readonly);
-}
-
-static void
-parse_dhcp_vendor (void *vend, int limit)
-{
-  grub_uint8_t *ptr, *ptr0;
-
-  ptr = ptr0 = vend;
-
-  if (grub_be_to_cpu32 (*(grub_uint32_t *) ptr) != 0x63825363)
-    return;
-  ptr = ptr + sizeof (grub_uint32_t);
-  while (ptr - ptr0 < limit)
-    {
-      grub_uint8_t tagtype;
-      grub_uint8_t taglength;
-
-      tagtype = *ptr++;
-
-      /* Pad tag.  */
-      if (tagtype == 0)
-       continue;
-
-      /* End tag.  */
-      if (tagtype == 0xff)
-       return;
-
-      taglength = *ptr++;
-
-      switch (tagtype)
-       {
-       case 12:
-         set_env_limn_ro ("net_pxe_hostname", (char *) ptr, taglength);
-         break;
-
-       case 15:
-         set_env_limn_ro ("net_pxe_domain", (char *) ptr, taglength);
-         break;
-
-       case 17:
-         set_env_limn_ro ("net_pxe_rootpath", (char *) ptr, taglength);
-         break;
-
-       case 18:
-         set_env_limn_ro ("net_pxe_extensionspath", (char *) ptr, taglength);
-         break;
-
-         /* If you need any other options please contact GRUB
-            developpement team.  */
-       }
-
-      ptr += taglength;
-    }
-}
-
-static void
-grub_pxe_detect (void)
-{
-  struct grub_pxenv *pxenv;
-  struct grub_pxenv_get_cached_info ci;
-  struct grub_pxenv_boot_player *bp;
-
-  pxenv = grub_pxe_scan ();
-  if (! pxenv)
-    return;
-
-  ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK;
-  ci.buffer = 0;
-  ci.buffer_size = 0;
-  grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci);
-  if (ci.status)
-    return;
-
-  bp = LINEAR (ci.buffer);
-
-  grub_pxe_your_ip = bp->your_ip;
-  grub_pxe_default_server_ip = bp->server_ip;
-  grub_pxe_default_gateway_ip = bp->gateway_ip;
-  set_mac_env (bp->mac_addr, bp->hw_len < sizeof (bp->mac_addr) ? bp->hw_len
-              : sizeof (bp->mac_addr));
-  set_env_limn_ro ("net_pxe_boot_file", (char *) bp->boot_file,
-                  sizeof (bp->boot_file));
-  set_env_limn_ro ("net_pxe_dhcp_server_name", (char *) bp->server_name,
-                  sizeof (bp->server_name));
-  parse_dhcp_vendor (&bp->vendor, sizeof (bp->vendor));
-  grub_pxe_pxenv = pxenv;
-}
-
-void
-grub_pxe_unload (void)
-{
-  if (grub_pxe_pxenv)
-    {
-      grub_fs_unregister (&grub_pxefs_fs);
-      grub_disk_dev_unregister (&grub_pxe_dev);
-
-      grub_pxe_pxenv = 0;
-    }
-}
-
-static void
-set_ip_env (char *varname, grub_uint32_t ip)
-{
-  char buf[sizeof ("XXX.XXX.XXX.XXX")];
-
-  grub_snprintf (buf, sizeof (buf), "%d.%d.%d.%d", (ip & 0xff),
-                (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff);
-  grub_env_set (varname, buf);
-}
-
-static char *
-write_ip_env (grub_uint32_t *ip, const char *val)
-{
-  char *buf;
-  grub_err_t err;
-  grub_uint32_t newip;
-  
-  err = parse_ip (val, &newip, 0);
-  if (err)
-    return 0;
-
-  /* Normalize the IP.  */
-  buf = grub_xasprintf ("%d.%d.%d.%d", (newip & 0xff), (newip >> 8) & 0xff,
-                      (newip >> 16) & 0xff, (newip >> 24) & 0xff);
-  if (!buf)
-    return 0;
-
-  *ip = newip;
-
-  return buf; 
-}
-
-static char *
-grub_env_write_pxe_default_server (struct grub_env_var *var 
-                                  __attribute__ ((unused)),
-                                  const char *val)
-{
-  return write_ip_env (&grub_pxe_default_server_ip, val);
-}
-
-static char *
-grub_env_write_pxe_default_gateway (struct grub_env_var *var
-                                   __attribute__ ((unused)),
-                                   const char *val)
-{
-  return write_ip_env (&grub_pxe_default_gateway_ip, val);
-}
-
-static char *
-grub_env_write_pxe_blocksize (struct grub_env_var *var __attribute__ ((unused)),
-                             const char *val)
-{
-  unsigned size;
-  char *buf;
-
-  size = grub_strtoul (val, 0, 0);
-  if (grub_errno)
-    return 0;
-
-  if (size < GRUB_PXE_MIN_BLKSIZE)
-    size = GRUB_PXE_MIN_BLKSIZE;
-  else if (size > GRUB_PXE_MAX_BLKSIZE)
-    size = GRUB_PXE_MAX_BLKSIZE;
-  
-  buf = grub_xasprintf ("%d", size);
-  if (!buf)
-    return 0;
-
-  grub_pxe_blksize = size;
-  
-  return buf;
-}
-
-
-GRUB_MOD_INIT(pxe)
-{
-  grub_pxe_detect ();
-  if (grub_pxe_pxenv)
-    {
-      char *buf;
-
-      buf = grub_xasprintf ("%d", grub_pxe_blksize);
-      if (buf)
-       grub_env_set ("pxe_blksize", buf);
-      grub_free (buf);
-
-      set_ip_env ("pxe_default_server", grub_pxe_default_server_ip);
-      set_ip_env ("pxe_default_gateway", grub_pxe_default_gateway_ip);
-      set_ip_env ("net_pxe_ip", grub_pxe_your_ip);
-      grub_register_variable_hook ("pxe_default_server", 0,
-                                  grub_env_write_pxe_default_server);
-      grub_register_variable_hook ("pxe_default_gateway", 0,
-                                  grub_env_write_pxe_default_gateway);
-
-      /* XXX: Is it possible to change IP in PXE?  */
-      grub_register_variable_hook ("net_pxe_ip", 0,
-                                  grub_env_write_readonly);
-      grub_register_variable_hook ("pxe_blksize", 0,
-                                  grub_env_write_pxe_blocksize);
-      grub_disk_dev_register (&grub_pxe_dev);
-      grub_fs_register (&grub_pxefs_fs);
-    }
-}
-
-GRUB_MOD_FINI(pxe)
-{
-  grub_pxe_unload ();
-}
diff --git a/fs/iso9660.c b/fs/iso9660.c
deleted file mode 100644 (file)
index 6dc465f..0000000
+++ /dev/null
@@ -1,897 +0,0 @@
-/* iso9660.c - iso9660 implementation with extensions:
-   SUSP, Rock Ridge.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/types.h>
-#include <grub/fshelp.h>
-#include <grub/charset.h>
-
-#define GRUB_ISO9660_FSTYPE_DIR                0040000
-#define GRUB_ISO9660_FSTYPE_REG                0100000
-#define GRUB_ISO9660_FSTYPE_SYMLINK    0120000
-#define GRUB_ISO9660_FSTYPE_MASK       0170000
-
-#define GRUB_ISO9660_LOG2_BLKSZ                2
-#define GRUB_ISO9660_BLKSZ             2048
-
-#define GRUB_ISO9660_RR_DOT            2
-#define GRUB_ISO9660_RR_DOTDOT         4
-
-#define GRUB_ISO9660_VOLDESC_BOOT      0
-#define GRUB_ISO9660_VOLDESC_PRIMARY   1
-#define GRUB_ISO9660_VOLDESC_SUPP      2
-#define GRUB_ISO9660_VOLDESC_PART      3
-#define GRUB_ISO9660_VOLDESC_END       255
-
-/* The head of a volume descriptor.  */
-struct grub_iso9660_voldesc
-{
-  grub_uint8_t type;
-  grub_uint8_t magic[5];
-  grub_uint8_t version;
-} __attribute__ ((packed));
-
-/* A directory entry.  */
-struct grub_iso9660_dir
-{
-  grub_uint8_t len;
-  grub_uint8_t ext_sectors;
-  grub_uint32_t first_sector;
-  grub_uint32_t first_sector_be;
-  grub_uint32_t size;
-  grub_uint32_t size_be;
-  grub_uint8_t unused1[7];
-  grub_uint8_t flags;
-  grub_uint8_t unused2[6];
-  grub_uint8_t namelen;
-} __attribute__ ((packed));
-
-struct grub_iso9660_date
-{
-  grub_uint8_t year[4];
-  grub_uint8_t month[2];
-  grub_uint8_t day[2];
-  grub_uint8_t hour[2];
-  grub_uint8_t minute[2];
-  grub_uint8_t second[2];
-  grub_uint8_t hundredth[2];
-  grub_uint8_t offset;
-} __attribute__ ((packed));
-
-/* The primary volume descriptor.  Only little endian is used.  */
-struct grub_iso9660_primary_voldesc
-{
-  struct grub_iso9660_voldesc voldesc;
-  grub_uint8_t unused1[33];
-  grub_uint8_t volname[32];
-  grub_uint8_t unused2[16];
-  grub_uint8_t escape[32];
-  grub_uint8_t unused3[12];
-  grub_uint32_t path_table_size;
-  grub_uint8_t unused4[4];
-  grub_uint32_t path_table;
-  grub_uint8_t unused5[12];
-  struct grub_iso9660_dir rootdir;
-  grub_uint8_t unused6[624];
-  struct grub_iso9660_date created;
-  struct grub_iso9660_date modified;
-} __attribute__ ((packed));
-
-/* A single entry in the path table.  */
-struct grub_iso9660_path
-{
-  grub_uint8_t len;
-  grub_uint8_t sectors;
-  grub_uint32_t first_sector;
-  grub_uint16_t parentdir;
-  grub_uint8_t name[0];
-} __attribute__ ((packed));
-
-/* An entry in the System Usage area of the directory entry.  */
-struct grub_iso9660_susp_entry
-{
-  grub_uint8_t sig[2];
-  grub_uint8_t len;
-  grub_uint8_t version;
-  grub_uint8_t data[0];
-} __attribute__ ((packed));
-
-/* The CE entry.  This is used to describe the next block where data
-   can be found.  */
-struct grub_iso9660_susp_ce
-{
-  struct grub_iso9660_susp_entry entry;
-  grub_uint32_t blk;
-  grub_uint32_t blk_be;
-  grub_uint32_t off;
-  grub_uint32_t off_be;
-  grub_uint32_t len;
-  grub_uint32_t len_be;
-} __attribute__ ((packed));
-
-struct grub_iso9660_data
-{
-  struct grub_iso9660_primary_voldesc voldesc;
-  grub_disk_t disk;
-  unsigned int first_sector;
-  int rockridge;
-  int susp_skip;
-  int joliet;
-};
-
-struct grub_fshelp_node
-{
-  struct grub_iso9660_data *data;
-  unsigned int size;
-  unsigned int blk;
-  unsigned int dir_blk;
-  unsigned int dir_off;
-};
-
-static grub_dl_t my_mod;
-\f
-
-/* Iterate over the susp entries, starting with block SUA_BLOCK on the
-   offset SUA_POS with a size of SUA_SIZE bytes.  Hook is called for
-   every entry.  */
-static grub_err_t
-grub_iso9660_susp_iterate (struct grub_iso9660_data *data,
-                          int sua_block, int sua_pos, int sua_size,
-                          grub_err_t (*hook)
-                          (struct grub_iso9660_susp_entry *entry))
-{
-  char *sua;
-  struct grub_iso9660_susp_entry *entry;
-
-  auto grub_err_t load_sua (void);
-
-  /* Load a part of the System Usage Area.  */
-  grub_err_t load_sua (void)
-    {
-      sua = grub_malloc (sua_size);
-      if (!sua)
-       return grub_errno;
-
-      if (grub_disk_read (data->disk, sua_block, sua_pos,
-                         sua_size, sua))
-       return grub_errno;
-
-      entry = (struct grub_iso9660_susp_entry *) sua;
-      return 0;
-    }
-
-  if (load_sua ())
-    return grub_errno;
-
-  for (; (char *) entry < (char *) sua + sua_size - 1;
-       entry = (struct grub_iso9660_susp_entry *)
-        ((char *) entry + entry->len))
-    {
-      /* The last entry.  */
-      if (grub_strncmp ((char *) entry->sig, "ST", 2) == 0)
-       break;
-
-      /* Additional entries are stored elsewhere.  */
-      if (grub_strncmp ((char *) entry->sig, "CE", 2) == 0)
-       {
-         struct grub_iso9660_susp_ce *ce;
-
-         ce = (struct grub_iso9660_susp_ce *) entry;
-         sua_size = grub_le_to_cpu32 (ce->len);
-         sua_pos = grub_le_to_cpu32 (ce->off);
-         sua_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ;
-
-         grub_free (sua);
-         if (load_sua ())
-           return grub_errno;
-       }
-
-      if (hook (entry))
-       {
-         grub_free (sua);
-         return 0;
-       }
-    }
-
-  grub_free (sua);
-  return 0;
-}
-
-static char *
-grub_iso9660_convert_string (grub_uint16_t *us, int len)
-{
-  char *p;
-  int i;
-
-  p = grub_malloc (len * 4 + 1);
-  if (! p)
-    return p;
-
-  for (i=0; i<len; i++)
-    us[i] = grub_be_to_cpu16 (us[i]);
-
-  *grub_utf16_to_utf8 ((grub_uint8_t *) p, us, len) = '\0';
-
-  return p;
-}
-
-static struct grub_iso9660_data *
-grub_iso9660_mount (grub_disk_t disk)
-{
-  struct grub_iso9660_data *data = 0;
-  struct grub_iso9660_dir rootdir;
-  int sua_pos;
-  int sua_size;
-  char *sua;
-  struct grub_iso9660_susp_entry *entry;
-  struct grub_iso9660_primary_voldesc voldesc;
-  int block;
-
-  auto grub_err_t susp_iterate (struct grub_iso9660_susp_entry *);
-
-  grub_err_t susp_iterate (struct grub_iso9660_susp_entry *susp_entry)
-    {
-      /* The "ER" entry is used to detect extensions.  The
-        `IEEE_P1285' extension means Rock ridge.  */
-      if (grub_strncmp ((char *) susp_entry->sig, "ER", 2) == 0)
-       {
-         data->rockridge = 1;
-         return 1;
-       }
-      return 0;
-    }
-
-  data = grub_zalloc (sizeof (struct grub_iso9660_data));
-  if (! data)
-    return 0;
-
-  data->disk = disk;
-
-  block = 16;
-  do
-    {
-      int copy_voldesc = 0;
-
-      /* Read the superblock.  */
-      if (grub_disk_read (disk, block << GRUB_ISO9660_LOG2_BLKSZ, 0,
-                         sizeof (struct grub_iso9660_primary_voldesc),
-                         (char *) &voldesc))
-        {
-          grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
-          goto fail;
-        }
-
-      if (grub_strncmp ((char *) voldesc.voldesc.magic, "CD001", 5) != 0)
-        {
-          grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
-          goto fail;
-        }
-
-      if (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_PRIMARY)
-        copy_voldesc = 1;
-      else if ((voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP) &&
-               (voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f) &&
-               ((voldesc.escape[2] == 0x40) || /* UCS-2 Level 1.  */
-                (voldesc.escape[2] == 0x43) ||  /* UCS-2 Level 2.  */
-                (voldesc.escape[2] == 0x45)))  /* UCS-2 Level 3.  */
-        {
-          copy_voldesc = 1;
-          data->joliet = 1;
-        }
-
-      if (copy_voldesc)
-        grub_memcpy((char *) &data->voldesc, (char *) &voldesc,
-                    sizeof (struct grub_iso9660_primary_voldesc));
-
-      block++;
-    } while (voldesc.voldesc.type != GRUB_ISO9660_VOLDESC_END);
-
-  /* Read the system use area and test it to see if SUSP is
-     supported.  */
-  if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
-                            << GRUB_ISO9660_LOG2_BLKSZ), 0,
-                     sizeof (rootdir), (char *) &rootdir))
-    {
-      grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
-      goto fail;
-    }
-
-  sua_pos = (sizeof (rootdir) + rootdir.namelen
-            + (rootdir.namelen % 2) - 1);
-  sua_size = rootdir.len - sua_pos;
-
-  sua = grub_malloc (sua_size);
-  if (! sua)
-    goto fail;
-
-  if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
-                            << GRUB_ISO9660_LOG2_BLKSZ), sua_pos,
-                     sua_size, sua))
-    {
-      grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
-      goto fail;
-    }
-
-  entry = (struct grub_iso9660_susp_entry *) sua;
-
-  /* Test if the SUSP protocol is used on this filesystem.  */
-  if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0)
-    {
-      /* The 2nd data byte stored how many bytes are skipped every time
-        to get to the SUA (System Usage Area).  */
-      data->susp_skip = entry->data[2];
-      entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len);
-
-      /* Iterate over the entries in the SUA area to detect
-        extensions.  */
-      if (grub_iso9660_susp_iterate (data,
-                                    (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
-                                     << GRUB_ISO9660_LOG2_BLKSZ),
-                                    sua_pos, sua_size, susp_iterate))
-       goto fail;
-    }
-
-  return data;
-
- fail:
-  grub_free (data);
-  return 0;
-}
-
-
-static char *
-grub_iso9660_read_symlink (grub_fshelp_node_t node)
-{
-  struct grub_iso9660_dir dirent;
-  int sua_off;
-  int sua_size;
-  char *symlink = 0;
-  int addslash = 0;
-
-  auto void add_part (const char *part, int len);
-  auto grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *);
-
-  /* Extend the symlink.  */
-  void add_part (const char *part, int len)
-    {
-      int size = grub_strlen (symlink);
-
-      symlink = grub_realloc (symlink, size + len + 1);
-      if (! symlink)
-       return;
-
-      grub_strncat (symlink, part, len);
-    }
-
-  /* Read in a symlink.  */
-  grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *entry)
-    {
-      if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0)
-       {
-         unsigned int pos = 1;
-
-         /* The symlink is not stored as a POSIX symlink, translate it.  */
-         while (pos < grub_le_to_cpu32 (entry->len))
-           {
-             if (addslash)
-               {
-                 add_part ("/", 1);
-                 addslash = 0;
-               }
-
-             /* The current position is the `Component Flag'.  */
-             switch (entry->data[pos] & 30)
-               {
-               case 0:
-                 {
-                   /* The data on pos + 2 is the actual data, pos + 1
-                      is the length.  Both are part of the `Component
-                      Record'.  */
-                   add_part ((char *) &entry->data[pos + 2],
-                             entry->data[pos + 1]);
-                   if ((entry->data[pos] & 1))
-                     addslash = 1;
-
-                   break;
-                 }
-
-               case 2:
-                 add_part ("./", 2);
-                 break;
-
-               case 4:
-                 add_part ("../", 3);
-                 break;
-
-               case 8:
-                 add_part ("/", 1);
-                 break;
-               }
-             /* In pos + 1 the length of the `Component Record' is
-                stored.  */
-             pos += entry->data[pos + 1] + 2;
-           }
-
-         /* Check if `grub_realloc' failed.  */
-         if (grub_errno)
-           return grub_errno;
-       }
-
-      return 0;
-    }
-
-  if (grub_disk_read (node->data->disk, node->dir_blk, node->dir_off,
-                     sizeof (dirent), (char *) &dirent))
-    return 0;
-
-  sua_off = (sizeof (dirent) + dirent.namelen + 1 - (dirent.namelen % 2)
-            + node->data->susp_skip);
-  sua_size = dirent.len - sua_off;
-
-  symlink = grub_malloc (1);
-  if (!symlink)
-    return 0;
-
-  *symlink = '\0';
-
-  if (grub_iso9660_susp_iterate (node->data, node->dir_blk,
-                                node->dir_off + sua_off,
-                                sua_size, susp_iterate_sl))
-    {
-      grub_free (symlink);
-      return 0;
-    }
-
-  return symlink;
-}
-
-
-static int
-grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
-                         int NESTED_FUNC_ATTR
-                         (*hook) (const char *filename,
-                                  enum grub_fshelp_filetype filetype,
-                                  grub_fshelp_node_t node))
-{
-  struct grub_iso9660_dir dirent;
-  unsigned int offset = 0;
-  char *filename;
-  int filename_alloc = 0;
-  enum grub_fshelp_filetype type;
-
-  auto grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *);
-
-  grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *entry)
-    {
-      /* The filename in the rock ridge entry.  */
-      if (grub_strncmp ("NM", (char *) entry->sig, 2) == 0)
-       {
-         /* The flags are stored at the data position 0, here the
-            filename type is stored.  */
-         if (entry->data[0] & GRUB_ISO9660_RR_DOT)
-           filename = ".";
-         else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT)
-           filename = "..";
-         else
-           {
-             int size = 1;
-             if (filename)
-               {
-                 size += grub_strlen (filename);
-                 grub_realloc (filename,
-                               grub_strlen (filename)
-                               + entry->len);
-               }
-             else
-               {
-                 size = entry->len - 5;
-                 filename = grub_zalloc (size + 1);
-               }
-             filename_alloc = 1;
-             grub_strncpy (filename, (char *) &entry->data[1], size);
-             filename[size] = '\0';
-           }
-       }
-      /* The mode information (st_mode).  */
-      else if (grub_strncmp ((char *) entry->sig, "PX", 2) == 0)
-       {
-         /* At position 0 of the PX record the st_mode information is
-            stored (little-endian).  */
-         grub_uint32_t mode = ((entry->data[0] + (entry->data[1] << 8))
-                               & GRUB_ISO9660_FSTYPE_MASK);
-
-         switch (mode)
-           {
-           case GRUB_ISO9660_FSTYPE_DIR:
-             type = GRUB_FSHELP_DIR;
-             break;
-           case GRUB_ISO9660_FSTYPE_REG:
-             type = GRUB_FSHELP_REG;
-             break;
-           case GRUB_ISO9660_FSTYPE_SYMLINK:
-             type = GRUB_FSHELP_SYMLINK;
-             break;
-           default:
-             type = GRUB_FSHELP_UNKNOWN;
-           }
-       }
-
-      return 0;
-    }
-
-  while (offset < dir->size)
-    {
-      if (grub_disk_read (dir->data->disk,
-                         (dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
-                         + offset / GRUB_DISK_SECTOR_SIZE,
-                         offset % GRUB_DISK_SECTOR_SIZE,
-                         sizeof (dirent), (char *) &dirent))
-       return 0;
-
-      /* The end of the block, skip to the next one.  */
-      if (!dirent.len)
-       {
-         offset = (offset / GRUB_ISO9660_BLKSZ + 1) * GRUB_ISO9660_BLKSZ;
-         continue;
-       }
-
-      {
-       char name[dirent.namelen + 1];
-       int nameoffset = offset + sizeof (dirent);
-       struct grub_fshelp_node *node;
-       int sua_off = (sizeof (dirent) + dirent.namelen + 1
-                      - (dirent.namelen % 2));
-       int sua_size = dirent.len - sua_off;
-
-       sua_off += offset + dir->data->susp_skip;
-
-       filename = 0;
-       filename_alloc = 0;
-       type = GRUB_FSHELP_UNKNOWN;
-
-       if (dir->data->rockridge
-           && grub_iso9660_susp_iterate (dir->data,
-                                         (dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
-                                         + (sua_off
-                                            / GRUB_DISK_SECTOR_SIZE),
-                                         sua_off % GRUB_DISK_SECTOR_SIZE,
-                                         sua_size, susp_iterate_dir))
-         return 0;
-
-       /* Read the name.  */
-       if (grub_disk_read (dir->data->disk,
-                           (dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
-                           + nameoffset / GRUB_DISK_SECTOR_SIZE,
-                           nameoffset % GRUB_DISK_SECTOR_SIZE,
-                           dirent.namelen, (char *) name))
-         return 0;
-
-       node = grub_malloc (sizeof (struct grub_fshelp_node));
-       if (!node)
-         return 0;
-
-       /* Setup a new node.  */
-       node->data = dir->data;
-       node->size = grub_le_to_cpu32 (dirent.size);
-       node->blk = grub_le_to_cpu32 (dirent.first_sector);
-       node->dir_blk = ((dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
-                        + offset / GRUB_DISK_SECTOR_SIZE);
-       node->dir_off = offset % GRUB_DISK_SECTOR_SIZE;
-
-       /* If the filetype was not stored using rockridge, use
-          whatever is stored in the iso9660 filesystem.  */
-       if (type == GRUB_FSHELP_UNKNOWN)
-         {
-           if ((dirent.flags & 3) == 2)
-             type = GRUB_FSHELP_DIR;
-           else
-             type = GRUB_FSHELP_REG;
-         }
-
-       /* The filename was not stored in a rock ridge entry.  Read it
-          from the iso9660 filesystem.  */
-       if (!filename)
-         {
-           name[dirent.namelen] = '\0';
-           filename = grub_strrchr (name, ';');
-           if (filename)
-             *filename = '\0';
-
-           if (dirent.namelen == 1 && name[0] == 0)
-             filename = ".";
-           else if (dirent.namelen == 1 && name[0] == 1)
-             filename = "..";
-           else
-             filename = name;
-         }
-
-        if (dir->data->joliet)
-          {
-            char *oldname, *semicolon;
-
-            oldname = filename;
-            filename = grub_iso9660_convert_string
-                  ((grub_uint16_t *) oldname, dirent.namelen >> 1);
-
-           semicolon = grub_strrchr (filename, ';');
-           if (semicolon)
-             *semicolon = '\0';
-
-            if (filename_alloc)
-              grub_free (oldname);
-
-            filename_alloc = 1;
-          }
-
-       if (hook (filename, type, node))
-         {
-           if (filename_alloc)
-             grub_free (filename);
-           return 1;
-         }
-       if (filename_alloc)
-         grub_free (filename);
-      }
-
-      offset += dirent.len;
-    }
-
-  return 0;
-}
-
-
-\f
-static grub_err_t
-grub_iso9660_dir (grub_device_t device, const char *path,
-                 int (*hook) (const char *filename,
-                              const struct grub_dirhook_info *info))
-{
-  struct grub_iso9660_data *data = 0;
-  struct grub_fshelp_node rootnode;
-  struct grub_fshelp_node *foundnode;
-
-  auto int NESTED_FUNC_ATTR iterate (const char *filename,
-                                    enum grub_fshelp_filetype filetype,
-                                    grub_fshelp_node_t node);
-
-  int NESTED_FUNC_ATTR iterate (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node)
-    {
-      struct grub_dirhook_info info;
-      grub_memset (&info, 0, sizeof (info));
-      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
-      grub_free (node);
-      return hook (filename, &info);
-    }
-
-  grub_dl_ref (my_mod);
-
-  data = grub_iso9660_mount (device->disk);
-  if (! data)
-    goto fail;
-
-  rootnode.data = data;
-  rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector);
-  rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size);
-
-  /* Use the fshelp function to traverse the path.  */
-  if (grub_fshelp_find_file (path, &rootnode,
-                            &foundnode,
-                            grub_iso9660_iterate_dir,
-                            grub_iso9660_read_symlink,
-                            GRUB_FSHELP_DIR))
-    goto fail;
-
-  /* List the files in the directory.  */
-  grub_iso9660_iterate_dir (foundnode, iterate);
-
-  if (foundnode != &rootnode)
-    grub_free (foundnode);
-
- fail:
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-
-/* Open a file named NAME and initialize FILE.  */
-static grub_err_t
-grub_iso9660_open (struct grub_file *file, const char *name)
-{
-  struct grub_iso9660_data *data;
-  struct grub_fshelp_node rootnode;
-  struct grub_fshelp_node *foundnode;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_iso9660_mount (file->device->disk);
-  if (!data)
-    goto fail;
-
-  rootnode.data = data;
-  rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector);
-  rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size);
-
-  /* Use the fshelp function to traverse the path.  */
-  if (grub_fshelp_find_file (name, &rootnode,
-                            &foundnode,
-                            grub_iso9660_iterate_dir,
-                            grub_iso9660_read_symlink,
-                            GRUB_FSHELP_REG))
-    goto fail;
-
-  data->first_sector = foundnode->blk;
-
-  file->data = data;
-  file->size = foundnode->size;
-  file->offset = 0;
-
-  return 0;
-
- fail:
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-
-static grub_ssize_t
-grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_iso9660_data *data =
-    (struct grub_iso9660_data *) file->data;
-
-  /* XXX: The file is stored in as a single extent.  */
-  data->disk->read_hook = file->read_hook;
-  grub_disk_read (data->disk,
-                 data->first_sector << GRUB_ISO9660_LOG2_BLKSZ,
-                 file->offset,
-                 len, buf);
-  data->disk->read_hook = NULL;
-
-  if (grub_errno)
-    return -1;
-
-  return len;
-}
-
-
-static grub_err_t
-grub_iso9660_close (grub_file_t file)
-{
-  grub_free (file->data);
-
-  grub_dl_unref (my_mod);
-
-  return GRUB_ERR_NONE;
-}
-
-
-static grub_err_t
-grub_iso9660_label (grub_device_t device, char **label)
-{
-  struct grub_iso9660_data *data;
-  data = grub_iso9660_mount (device->disk);
-
-  if (data)
-    {
-      if (data->joliet)
-        *label = grub_iso9660_convert_string
-                 ((grub_uint16_t *) &data->voldesc.volname, 16);
-      else
-        *label = grub_strndup ((char *) data->voldesc.volname, 32);
-      grub_free (data);
-    }
-  else
-    *label = 0;
-
-  return grub_errno;
-}
-
-
-static grub_err_t
-grub_iso9660_uuid (grub_device_t device, char **uuid)
-{
-  struct grub_iso9660_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_iso9660_mount (disk);
-  if (data)
-    {
-      if (! data->voldesc.modified.year[0] && ! data->voldesc.modified.year[1]
-         && ! data->voldesc.modified.year[2] && ! data->voldesc.modified.year[3]
-         && ! data->voldesc.modified.month[0] && ! data->voldesc.modified.month[1]
-         && ! data->voldesc.modified.day[0] && ! data->voldesc.modified.day[1]
-         && ! data->voldesc.modified.hour[0] && ! data->voldesc.modified.hour[1]
-         && ! data->voldesc.modified.minute[0] && ! data->voldesc.modified.minute[1]
-         && ! data->voldesc.modified.second[0] && ! data->voldesc.modified.second[1]
-         && ! data->voldesc.modified.hundredth[0] && ! data->voldesc.modified.hundredth[1])
-       {
-         grub_error (GRUB_ERR_BAD_NUMBER, "no creation date in filesystem to generate UUID");
-         *uuid = NULL;
-       }
-      else
-       {
-         *uuid = grub_xasprintf ("%c%c%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c",
-                                data->voldesc.modified.year[0],
-                                data->voldesc.modified.year[1],
-                                data->voldesc.modified.year[2],
-                                data->voldesc.modified.year[3],
-                                data->voldesc.modified.month[0],
-                                data->voldesc.modified.month[1],
-                                data->voldesc.modified.day[0],
-                                data->voldesc.modified.day[1],
-                                data->voldesc.modified.hour[0],
-                                data->voldesc.modified.hour[1],
-                                data->voldesc.modified.minute[0],
-                                data->voldesc.modified.minute[1],
-                                data->voldesc.modified.second[0],
-                                data->voldesc.modified.second[1],
-                                data->voldesc.modified.hundredth[0],
-                                data->voldesc.modified.hundredth[1]);
-       }
-    }
-  else
-    *uuid = NULL;
-
-       grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-\f
-
-static struct grub_fs grub_iso9660_fs =
-  {
-    .name = "iso9660",
-    .dir = grub_iso9660_dir,
-    .open = grub_iso9660_open,
-    .read = grub_iso9660_read,
-    .close = grub_iso9660_close,
-    .label = grub_iso9660_label,
-    .uuid = grub_iso9660_uuid,
-    .next = 0
-  };
-
-GRUB_MOD_INIT(iso9660)
-{
-  grub_fs_register (&grub_iso9660_fs);
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(iso9660)
-{
-  grub_fs_unregister (&grub_iso9660_fs);
-}
diff --git a/fs/jfs.c b/fs/jfs.c
deleted file mode 100644 (file)
index c9839a2..0000000
--- a/fs/jfs.c
+++ /dev/null
@@ -1,902 +0,0 @@
-/* jfs.c - JFS.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/types.h>
-#include <grub/charset.h>
-
-#define GRUB_JFS_MAX_SYMLNK_CNT        8
-#define GRUB_JFS_FILETYPE_MASK 0170000
-#define GRUB_JFS_FILETYPE_REG  0100000
-#define GRUB_JFS_FILETYPE_LNK  0120000
-#define GRUB_JFS_FILETYPE_DIR  0040000
-
-#define GRUB_JFS_SBLOCK                64
-#define GRUB_JFS_AGGR_INODE    2
-#define GRUB_JFS_FS1_INODE_BLK 104
-
-#define GRUB_JFS_TREE_LEAF     2
-
-struct grub_jfs_sblock
-{
-  /* The magic for JFS.  It should contain the string "JFS1".  */
-  grub_uint8_t magic[4];
-  grub_uint32_t version;
-  grub_uint64_t ag_size;
-
-  /* The size of a filesystem block in bytes.  XXX: currently only
-     4096 was tested.  */
-  grub_uint32_t blksz;
-  grub_uint16_t log2_blksz;
-
-  grub_uint8_t unused[71];
-  grub_uint8_t volname[11];
-  grub_uint8_t unused2[32];
-  grub_uint8_t uuid[16];
-};
-
-struct grub_jfs_extent
-{
-  /* The length of the extent in filesystem blocks.  */
-  grub_uint16_t length;
-  grub_uint8_t length2;
-
-  /* The physical offset of the first block on the disk.  */
-  grub_uint8_t blk1;
-  grub_uint32_t blk2;
-} __attribute__ ((packed));
-
-struct grub_jfs_iag
-{
-  grub_uint8_t unused[3072];
-  struct grub_jfs_extent inodes[128];
-} __attribute__ ((packed));
-
-
-/* The head of the tree used to find extents.  */
-struct grub_jfs_treehead
-{
-  grub_uint64_t next;
-  grub_uint64_t prev;
-
-  grub_uint8_t flags;
-  grub_uint8_t unused;
-
-  grub_uint16_t count;
-  grub_uint16_t max;
-  grub_uint8_t unused2[10];
-} __attribute__ ((packed));
-
-/* A node in the extent tree.  */
-struct grub_jfs_tree_extent
-{
-  grub_uint8_t flags;
-  grub_uint16_t unused;
-
-  /* The offset is the key used to lookup an extent.  */
-  grub_uint8_t offset1;
-  grub_uint32_t offset2;
-
-  struct grub_jfs_extent extent;
-} __attribute__ ((packed));
-
-/* The tree of directory entries.  */
-struct grub_jfs_tree_dir
-{
-  /* Pointers to the previous and next tree headers of other nodes on
-     this level.  */
-  grub_uint64_t nextb;
-  grub_uint64_t prevb;
-
-  grub_uint8_t flags;
-
-  /* The amount of dirents in this node.  */
-  grub_uint8_t count;
-  grub_uint8_t freecnt;
-  grub_uint8_t freelist;
-  grub_uint8_t maxslot;
-
-  /* The location of the sorted array of pointers to dirents.  */
-  grub_uint8_t sindex;
-  grub_uint8_t unused[10];
-} __attribute__ ((packed));
-
-/* An internal node in the dirents tree.  */
-struct grub_jfs_internal_dirent
-{
-  struct grub_jfs_extent ex;
-  grub_uint8_t next;
-  grub_uint8_t len;
-  grub_uint16_t namepart[11];
-} __attribute__ ((packed));
-
-/* A leaf node in the dirents tree.  */
-struct grub_jfs_leaf_dirent
-{
-  /* The inode for this dirent.  */
-  grub_uint32_t inode;
-  grub_uint8_t next;
-
-  /* The size of the name.  */
-  grub_uint8_t len;
-  grub_uint16_t namepart[11];
-  grub_uint32_t index;
-} __attribute__ ((packed));
-
-/* A leaf in the dirents tree.  This one is used if the previously
-   dirent was not big enough to store the name.  */
-struct grub_jfs_leaf_next_dirent
-{
-  grub_uint8_t next;
-  grub_uint8_t len;
-  grub_uint16_t namepart[15];
-} __attribute__ ((packed));
-
-struct grub_jfs_inode
-{
-  grub_uint32_t stamp;
-  grub_uint32_t fileset;
-  grub_uint32_t inode;
-  grub_uint8_t unused[12];
-  grub_uint64_t size;
-  grub_uint8_t unused2[20];
-  grub_uint32_t mode;
-  grub_uint8_t unused3[72];
-  grub_uint8_t unused4[96];
-
-  union
-  {
-    /* The tree describing the extents of the file.  */
-    struct __attribute__ ((packed))
-    {
-      struct grub_jfs_treehead tree;
-      struct grub_jfs_tree_extent extents[16];
-    } file;
-    union
-    {
-      /* The tree describing the dirents.  */
-      struct
-      {
-       grub_uint8_t unused[16];
-       grub_uint8_t flags;
-
-       /* Amount of dirents in this node.  */
-       grub_uint8_t count;
-       grub_uint8_t freecnt;
-       grub_uint8_t freelist;
-       grub_uint32_t idotdot;
-       grub_uint8_t sorted[8];
-      } header;
-      struct grub_jfs_leaf_dirent dirents[8];
-    } dir __attribute__ ((packed));
-    /* Fast symlink.  */
-    struct
-    {
-      grub_uint8_t unused[32];
-      grub_uint8_t path[128];
-    } symlink;
-  } __attribute__ ((packed));
-} __attribute__ ((packed));
-
-struct grub_jfs_data
-{
-  struct grub_jfs_sblock sblock;
-  grub_disk_t disk;
-  struct grub_jfs_inode fileset;
-  struct grub_jfs_inode currinode;
-  int pos;
-  int linknest;
-} __attribute__ ((packed));
-
-struct grub_jfs_diropen
-{
-  int index;
-  union
-  {
-    struct grub_jfs_tree_dir header;
-    struct grub_jfs_leaf_dirent dirent[0];
-    struct grub_jfs_leaf_next_dirent next_dirent[0];
-    char sorted[0];
-  } *dirpage __attribute__ ((packed));
-  struct grub_jfs_data *data;
-  struct grub_jfs_inode *inode;
-  int count;
-  char *sorted;
-  struct grub_jfs_leaf_dirent *leaf;
-  struct grub_jfs_leaf_next_dirent *next_leaf;
-
-  /* The filename and inode of the last read dirent.  */
-  char name[255];
-  grub_uint32_t ino;
-} __attribute__ ((packed));
-
-
-static grub_dl_t my_mod;
-\f
-static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, int ino);
-
-/* Get the block number for the block BLK in the node INODE in the
-   mounted filesystem DATA.  */
-static int
-grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode,
-               unsigned int blk)
-{
-  auto int getblk (struct grub_jfs_treehead *treehead,
-                  struct grub_jfs_tree_extent *extents);
-
-  int getblk (struct grub_jfs_treehead *treehead,
-             struct grub_jfs_tree_extent *extents)
-    {
-      int found = -1;
-      int i;
-
-      for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2; i++)
-       {
-         if (treehead->flags & GRUB_JFS_TREE_LEAF)
-           {
-             /* Read the leafnode.  */
-             if (grub_le_to_cpu32 (extents[i].offset2) <= blk
-                 && ((grub_le_to_cpu16 (extents[i].extent.length))
-                     + (extents[i].extent.length2 << 8)
-                     + grub_le_to_cpu32 (extents[i].offset2)) > blk)
-               return (blk - grub_le_to_cpu32 (extents[i].offset2)
-                       + grub_le_to_cpu32 (extents[i].extent.blk2));
-           }
-         else
-           if (blk >= grub_le_to_cpu32 (extents[i].offset2))
-             found = i;
-       }
-
-      if (found != -1)
-       {
-         struct
-         {
-           struct grub_jfs_treehead treehead;
-           struct grub_jfs_tree_extent extents[254];
-         } tree;
-
-         if (grub_disk_read (data->disk,
-                             grub_le_to_cpu32 (extents[found].extent.blk2)
-                             << (grub_le_to_cpu16 (data->sblock.log2_blksz)
-                                 - GRUB_DISK_SECTOR_BITS), 0,
-                             sizeof (tree), (char *) &tree))
-           return -1;
-
-         return getblk (&tree.treehead, &tree.extents[0]);
-       }
-
-      return -1;
-    }
-
-  return getblk (&inode->file.tree, &inode->file.extents[0]);
-}
-
-
-static grub_err_t
-grub_jfs_read_inode (struct grub_jfs_data *data, int ino,
-                    struct grub_jfs_inode *inode)
-{
-  struct grub_jfs_iag iag;
-  int iagnum = ino / 4096;
-  int inoext = (ino % 4096) / 32;
-  int inonum = (ino % 4096) % 32;
-  grub_uint32_t iagblk;
-  grub_uint32_t inoblk;
-
-  iagblk = grub_jfs_blkno (data, &data->fileset, iagnum + 1);
-  if (grub_errno)
-    return grub_errno;
-
-  /* Read in the IAG.  */
-  if (grub_disk_read (data->disk,
-                     iagblk << (grub_le_to_cpu16 (data->sblock.log2_blksz)
-                                - GRUB_DISK_SECTOR_BITS), 0,
-                     sizeof (struct grub_jfs_iag), &iag))
-    return grub_errno;
-
-  inoblk = grub_le_to_cpu32 (iag.inodes[inoext].blk2);
-  inoblk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz)
-             - GRUB_DISK_SECTOR_BITS);
-  inoblk += inonum;
-
-  if (grub_disk_read (data->disk, inoblk, 0,
-                     sizeof (struct grub_jfs_inode), inode))
-    return grub_errno;
-
-  return 0;
-}
-
-
-static struct grub_jfs_data *
-grub_jfs_mount (grub_disk_t disk)
-{
-  struct grub_jfs_data *data = 0;
-
-  data = grub_malloc (sizeof (struct grub_jfs_data));
-  if (!data)
-    return 0;
-
-  /* Read the superblock.  */
-  if (grub_disk_read (disk, GRUB_JFS_SBLOCK, 0,
-                     sizeof (struct grub_jfs_sblock), &data->sblock))
-    goto fail;
-
-  if (grub_strncmp ((char *) (data->sblock.magic), "JFS1", 4))
-    {
-      grub_error (GRUB_ERR_BAD_FS, "not a JFS filesystem");
-      goto fail;
-    }
-
-  data->disk = disk;
-  data->pos = 0;
-  data->linknest = 0;
-
-  /* Read the inode of the first fileset.  */
-  if (grub_disk_read (data->disk, GRUB_JFS_FS1_INODE_BLK, 0,
-                     sizeof (struct grub_jfs_inode), &data->fileset))
-    goto fail;
-
-  return data;
-
- fail:
-  grub_free (data);
-
-  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
-    grub_error (GRUB_ERR_BAD_FS, "not a JFS filesystem");
-
-  return 0;
-}
-
-
-static struct grub_jfs_diropen *
-grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode)
-{
-  struct grub_jfs_internal_dirent *de;
-  struct grub_jfs_diropen *diro;
-  int blk;
-
-  de = (struct grub_jfs_internal_dirent *) inode->dir.dirents;
-
-  if (!((grub_le_to_cpu32 (inode->mode)
-        & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR))
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-      return 0;
-    }
-
-  diro = grub_zalloc (sizeof (struct grub_jfs_diropen));
-  if (!diro)
-    return 0;
-
-  diro->data = data;
-  diro->inode = inode;
-
-  /* Check if the entire tree is contained within the inode.  */
-  if (inode->file.tree.flags & GRUB_JFS_TREE_LEAF)
-    {
-      diro->leaf = inode->dir.dirents;
-      diro->next_leaf = (struct grub_jfs_leaf_next_dirent *) de;
-      diro->sorted = (char *) (inode->dir.header.sorted);
-      diro->count = inode->dir.header.count;
-
-      return diro;
-    }
-
-  diro->dirpage = grub_malloc (grub_le_to_cpu32 (data->sblock.blksz));
-  if (!diro->dirpage)
-    {
-      grub_free (diro);
-      return 0;
-    }
-
-  blk = grub_le_to_cpu32 (de[inode->dir.header.sorted[0]].ex.blk2);
-  blk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS);
-
-  /* Read in the nodes until we are on the leaf node level.  */
-  do
-    {
-      int index;
-      if (grub_disk_read (data->disk, blk, 0,
-                         grub_le_to_cpu32 (data->sblock.blksz),
-                         diro->dirpage->sorted))
-       {
-         grub_free (diro->dirpage);
-         grub_free (diro);
-         return 0;
-       }
-
-      de = (struct grub_jfs_internal_dirent *) diro->dirpage->dirent;
-      index = diro->dirpage->sorted[diro->dirpage->header.sindex * 32];
-      blk = (grub_le_to_cpu32 (de[index].ex.blk2)
-            << (grub_le_to_cpu16 (data->sblock.log2_blksz)
-                - GRUB_DISK_SECTOR_BITS));
-    } while (!(diro->dirpage->header.flags & GRUB_JFS_TREE_LEAF));
-
-  diro->leaf = diro->dirpage->dirent;
-  diro->next_leaf = diro->dirpage->next_dirent;
-  diro->sorted = &diro->dirpage->sorted[diro->dirpage->header.sindex * 32];
-  diro->count = diro->dirpage->header.count;
-
-  return diro;
-}
-
-
-static void
-grub_jfs_closedir (struct grub_jfs_diropen *diro)
-{
-  if (!diro)
-    return;
-  grub_free (diro->dirpage);
-  grub_free (diro);
-}
-
-
-/* Read in the next dirent from the directory described by DIRO.  */
-static grub_err_t
-grub_jfs_getent (struct grub_jfs_diropen *diro)
-{
-  int strpos = 0;
-  struct grub_jfs_leaf_dirent *leaf;
-  struct grub_jfs_leaf_next_dirent *next_leaf;
-  int len;
-  int nextent;
-  grub_uint16_t filename[255];
-
-  auto void addstr (grub_uint16_t *uname, int ulen);
-
-  /* Add the unicode string to the utf16 filename buffer.  */
-  void addstr (grub_uint16_t *name, int ulen)
-    {
-      while (ulen--)
-       filename[strpos++] = *(name++);
-    }
-
-  /* The last node, read in more.  */
-  if (diro->index == diro->count)
-    {
-      unsigned int next;
-
-      /* If the inode contains the entry tree or if this was the last
-        node, there is nothing to read.  */
-      if ((diro->inode->file.tree.flags & GRUB_JFS_TREE_LEAF)
-         || !grub_le_to_cpu64 (diro->dirpage->header.nextb))
-       return GRUB_ERR_OUT_OF_RANGE;
-
-      next = grub_le_to_cpu64 (diro->dirpage->header.nextb);
-      next <<= (grub_le_to_cpu16 (diro->data->sblock.log2_blksz)
-               - GRUB_DISK_SECTOR_BITS);
-
-      if (grub_disk_read (diro->data->disk, next, 0,
-                         grub_le_to_cpu32 (diro->data->sblock.blksz),
-                         diro->dirpage->sorted))
-       return grub_errno;
-
-      diro->leaf = diro->dirpage->dirent;
-      diro->next_leaf = diro->dirpage->next_dirent;
-      diro->sorted = &diro->dirpage->sorted[diro->dirpage->header.sindex * 32];
-      diro->count = diro->dirpage->header.count;
-      diro->index = 0;
-    }
-
-  leaf = &diro->leaf[(int) diro->sorted[diro->index]];
-  next_leaf = &diro->next_leaf[diro->index];
-
-  len = leaf->len;
-  if (!len)
-    {
-      diro->index++;
-      return grub_jfs_getent (diro);
-    }
-
-  addstr (leaf->namepart, len < 11 ? len : 11);
-  diro->ino = grub_le_to_cpu32 (leaf->inode);
-  len -= 11;
-
-  /* Move down to the leaf level.  */
-  nextent = leaf->next;
-  if (leaf->next != 255)
-    do
-      {
-       next_leaf = &diro->next_leaf[nextent];
-       addstr (next_leaf->namepart, len < 15 ? len : 15 );
-
-       len -= 15;
-       nextent = next_leaf->next;
-      } while (next_leaf->next != 255 && len > 0);
-
-  diro->index++;
-
-  /* Convert the temporary UTF16 filename to UTF8.  */
-  *grub_utf16_to_utf8 ((grub_uint8_t *) (diro->name), filename, strpos) = '\0';
-
-  return 0;
-}
-
-
-/* Read LEN bytes from the file described by DATA starting with byte
-   POS.  Return the amount of read bytes in READ.  */
-static grub_ssize_t
-grub_jfs_read_file (struct grub_jfs_data *data,
-                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                      unsigned offset, unsigned length),
-                   int pos, grub_size_t len, char *buf)
-{
-  int i;
-  int blockcnt;
-
-  blockcnt = ((len + pos + grub_le_to_cpu32 (data->sblock.blksz) - 1)
-             / grub_le_to_cpu32 (data->sblock.blksz));
-
-  for (i = pos / grub_le_to_cpu32 (data->sblock.blksz); i < blockcnt; i++)
-    {
-      int blknr;
-      int blockoff = pos % grub_le_to_cpu32 (data->sblock.blksz);
-      int blockend = grub_le_to_cpu32 (data->sblock.blksz);
-
-      int skipfirst = 0;
-
-      blknr = grub_jfs_blkno (data, &data->currinode, i);
-      if (grub_errno)
-       return -1;
-
-      /* Last block.  */
-      if (i == blockcnt - 1)
-       {
-         blockend = (len + pos) % grub_le_to_cpu32 (data->sblock.blksz);
-
-         if (!blockend)
-           blockend = grub_le_to_cpu32 (data->sblock.blksz);
-       }
-
-      /* First block.  */
-      if (i == (pos / (int) grub_le_to_cpu32 (data->sblock.blksz)))
-       {
-         skipfirst = blockoff;
-         blockend -= skipfirst;
-       }
-
-      data->disk->read_hook = read_hook;
-      grub_disk_read (data->disk,
-                     blknr << (grub_le_to_cpu16 (data->sblock.log2_blksz)
-                               - GRUB_DISK_SECTOR_BITS),
-                     skipfirst, blockend, buf);
-
-      data->disk->read_hook = 0;
-      if (grub_errno)
-       return -1;
-
-      buf += grub_le_to_cpu32 (data->sblock.blksz) - skipfirst;
-    }
-
-  return len;
-}
-
-
-/* Find the file with the pathname PATH on the filesystem described by
-   DATA.  */
-static grub_err_t
-grub_jfs_find_file (struct grub_jfs_data *data, const char *path)
-{
-  char fpath[grub_strlen (path)];
-  char *name = fpath;
-  char *next;
-  unsigned int pos = 0;
-  struct grub_jfs_diropen *diro;
-
-  grub_strncpy (fpath, path, grub_strlen (path) + 1);
-
-  if (grub_jfs_read_inode (data, GRUB_JFS_AGGR_INODE, &data->currinode))
-    return grub_errno;
-
-  /* Skip the first slashes.  */
-  while (*name == '/')
-    {
-      name++;
-      if (!*name)
-       return 0;
-    }
-
-  /* Extract the actual part from the pathname.  */
-  next = grub_strchr (name, '/');
-  if (next)
-    {
-      while (*next == '/')
-       {
-         next[0] = '\0';
-         next++;
-       }
-    }
-  diro = grub_jfs_opendir (data, &data->currinode);
-  if (!diro)
-    return grub_errno;
-
-  for (;;)
-    {
-      if (grub_strlen (name) == 0)
-       return GRUB_ERR_NONE;
-
-      if (grub_jfs_getent (diro) == GRUB_ERR_OUT_OF_RANGE)
-       break;
-
-      /* Check if the current direntry matches the current part of the
-        pathname.  */
-      if (!grub_strcmp (name, diro->name))
-       {
-         int ino = diro->ino;
-         int dirino = grub_le_to_cpu32 (data->currinode.inode);
-
-         grub_jfs_closedir (diro);
-         diro = 0;
-
-         if (grub_jfs_read_inode (data, ino, &data->currinode))
-           break;
-
-         /* Check if this is a symlink.  */
-         if ((grub_le_to_cpu32 (data->currinode.mode)
-              & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_LNK)
-           {
-             grub_jfs_lookup_symlink (data, dirino);
-             if (grub_errno)
-               return grub_errno;
-           }
-
-         if (!next)
-           return 0;
-
-         pos = 0;
-
-         name = next;
-         next = grub_strchr (name, '/');
-         if (next)
-           {
-             next[0] = '\0';
-             next++;
-           }
-
-         /* Open this directory for reading dirents.  */
-         diro = grub_jfs_opendir (data, &data->currinode);
-         if (!diro)
-           return grub_errno;
-
-         continue;
-       }
-    }
-
-  grub_jfs_closedir (diro);
-  grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
-  return grub_errno;
-}
-
-
-static grub_err_t
-grub_jfs_lookup_symlink (struct grub_jfs_data *data, int ino)
-{
-  int size = grub_le_to_cpu64 (data->currinode.size);
-  char symlink[size + 1];
-
-  if (++data->linknest > GRUB_JFS_MAX_SYMLNK_CNT)
-    return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
-
-  if (size <= 128)
-    grub_strncpy (symlink, (char *) (data->currinode.symlink.path), 128);
-  else if (grub_jfs_read_file (data, 0, 0, size, symlink) < 0)
-    return grub_errno;
-
-  symlink[size] = '\0';
-
-  /* The symlink is an absolute path, go back to the root inode.  */
-  if (symlink[0] == '/')
-    ino = 2;
-
-  /* Now load in the old inode.  */
-  if (grub_jfs_read_inode (data, ino, &data->currinode))
-    return grub_errno;
-
-  grub_jfs_find_file (data, symlink);
-  if (grub_errno)
-    grub_error (grub_errno, "cannot follow symlink `%s'", symlink);
-
-  return grub_errno;
-}
-\f
-
-static grub_err_t
-grub_jfs_dir (grub_device_t device, const char *path,
-             int (*hook) (const char *filename,
-                          const struct grub_dirhook_info *info))
-{
-  struct grub_jfs_data *data = 0;
-  struct grub_jfs_diropen *diro = 0;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_jfs_mount (device->disk);
-  if (!data)
-    goto fail;
-
-  if (grub_jfs_find_file (data, path))
-    goto fail;
-
-  diro = grub_jfs_opendir (data, &data->currinode);
-  if (!diro)
-    goto fail;
-
-  /* Iterate over the dirents in the directory that was found.  */
-  while (grub_jfs_getent (diro) != GRUB_ERR_OUT_OF_RANGE)
-    {
-      struct grub_jfs_inode inode;
-      struct grub_dirhook_info info;
-      grub_memset (&info, 0, sizeof (info));
-
-      if (grub_jfs_read_inode (data, diro->ino, &inode))
-       goto fail;
-
-      info.dir = (grub_le_to_cpu32 (inode.mode)
-                 & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR;
-      if (hook (diro->name, &info))
-       goto fail;
-    }
-
-  /* XXX: GRUB_ERR_OUT_OF_RANGE is used for the last dirent.  */
-  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
-    grub_errno = 0;
-
- fail:
-  grub_jfs_closedir (diro);
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-
-/* Open a file named NAME and initialize FILE.  */
-static grub_err_t
-grub_jfs_open (struct grub_file *file, const char *name)
-{
-  struct grub_jfs_data *data;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_jfs_mount (file->device->disk);
-  if (!data)
-    goto fail;
-
-  grub_jfs_find_file (data, name);
-  if (grub_errno)
-    goto fail;
-
-  /* It is only possible for open regular files.  */
-  if (! ((grub_le_to_cpu32 (data->currinode.mode)
-         & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_REG))
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file");
-      goto fail;
-    }
-
-  file->data = data;
-  file->size = grub_le_to_cpu64 (data->currinode.size);
-
-  return 0;
-
- fail:
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-
-static grub_ssize_t
-grub_jfs_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_jfs_data *data =
-    (struct grub_jfs_data *) file->data;
-
-  return grub_jfs_read_file (data, file->read_hook, file->offset, len, buf);
-}
-
-
-static grub_err_t
-grub_jfs_close (grub_file_t file)
-{
-  grub_free (file->data);
-
-  grub_dl_unref (my_mod);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_jfs_uuid (grub_device_t device, char **uuid)
-{
-  struct grub_jfs_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_jfs_mount (disk);
-  if (data)
-    {
-      *uuid = grub_xasprintf ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
-                            "%02x%02x%02x%02x%02x%02x",
-                            data->sblock.uuid[0], data->sblock.uuid[1],
-                            data->sblock.uuid[2], data->sblock.uuid[3],
-                            data->sblock.uuid[4], data->sblock.uuid[5],
-                            data->sblock.uuid[6], data->sblock.uuid[7],
-                            data->sblock.uuid[8], data->sblock.uuid[9],
-                            data->sblock.uuid[10], data->sblock.uuid[11],
-                            data->sblock.uuid[12], data->sblock.uuid[13],
-                            data->sblock.uuid[14], data->sblock.uuid[15]);
-    }
-  else
-    *uuid = NULL;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_jfs_label (grub_device_t device, char **label)
-{
-  struct grub_jfs_data *data;
-  data = grub_jfs_mount (device->disk);
-
-  if (data)
-    *label = grub_strndup ((char *) (data->sblock.volname), 11);
-  else
-    *label = 0;
-
-  return grub_errno;
-}
-\f
-
-static struct grub_fs grub_jfs_fs =
-  {
-    .name = "jfs",
-    .dir = grub_jfs_dir,
-    .open = grub_jfs_open,
-    .read = grub_jfs_read,
-    .close = grub_jfs_close,
-    .label = grub_jfs_label,
-    .uuid = grub_jfs_uuid,
-    .next = 0
-  };
-
-GRUB_MOD_INIT(jfs)
-{
-  grub_fs_register (&grub_jfs_fs);
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(jfs)
-{
-  grub_fs_unregister (&grub_jfs_fs);
-}
diff --git a/fs/minix.c b/fs/minix.c
deleted file mode 100644 (file)
index a856e38..0000000
+++ /dev/null
@@ -1,614 +0,0 @@
-/* minix.c - The minix filesystem, version 1 and 2.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2005,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/types.h>
-
-#define GRUB_MINIX_MAGIC       0x137F
-#define GRUB_MINIX2_MAGIC      0x2468
-#define GRUB_MINIX_MAGIC_30    0x138F
-#define GRUB_MINIX2_MAGIC_30   0x2478
-#define GRUB_MINIX_BSIZE       1024U
-#define GRUB_MINIX_LOG2_BSIZE  1
-#define GRUB_MINIX_ROOT_INODE  1
-#define GRUB_MINIX_MAX_SYMLNK_CNT      8
-#define GRUB_MINIX_SBLOCK      2
-
-#define GRUB_MINIX_IFDIR       0040000U
-#define GRUB_MINIX_IFLNK       0120000U
-
-#define GRUB_MINIX_INODE(data,field) (data->version == 1 ? \
-                           data->inode.  field : data->inode2.  field)
-#define GRUB_MINIX_INODE_ENDIAN(data,field,bits1,bits2) (data->version == 1 ?  \
-                        grub_le_to_cpu##bits1 (data->inode.field) :            \
-                        grub_le_to_cpu##bits2 (data->inode2.field))
-#define GRUB_MINIX_INODE_SIZE(data) GRUB_MINIX_INODE_ENDIAN (data,size,16,32)
-#define GRUB_MINIX_INODE_MODE(data) GRUB_MINIX_INODE_ENDIAN (data,mode,16,16)
-#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) GRUB_MINIX_INODE_ENDIAN           \
-                                               (data,dir_zones[blk],16,32)
-#define GRUB_MINIX_INODE_INDIR_ZONE(data)                              \
-                        GRUB_MINIX_INODE_ENDIAN (data,indir_zone,16,32)
-#define GRUB_MINIX_INODE_DINDIR_ZONE(data)                                     \
-                        GRUB_MINIX_INODE_ENDIAN (data,double_indir_zone,16,32)
-#define GRUB_MINIX_INODE_BLKSZ(data) (data->version == 1 ? 2 : 4)
-#define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE                          \
-                                + grub_le_to_cpu16 (sblock->log2_zone_size))
-#define GRUB_MINIX_ZONESZ      (GRUB_MINIX_BSIZE                               \
-                                << grub_le_to_cpu16 (sblock->log2_zone_size))
-
-struct grub_minix_sblock
-{
-  grub_uint16_t inode_cnt;
-  grub_uint16_t zone_cnt;
-  grub_uint16_t inode_bmap_size;
-  grub_uint16_t zone_bmap_size;
-  grub_uint16_t first_data_zone;
-  grub_uint16_t log2_zone_size;
-  grub_uint32_t max_file_size;
-  grub_uint16_t magic;
-};
-
-struct grub_minix_inode
-{
-  grub_uint16_t mode;
-  grub_uint16_t uid;
-  grub_uint16_t size;
-  grub_uint32_t ctime;
-  grub_uint8_t gid;
-  grub_uint8_t nlinks;
-  grub_uint16_t dir_zones[7];
-  grub_uint16_t indir_zone;
-  grub_uint16_t double_indir_zone;
-};
-
-struct grub_minix2_inode
-{
-  grub_uint16_t mode;
-  grub_uint16_t nlinks;
-  grub_uint16_t uid;
-  grub_uint16_t gid;
-  grub_uint32_t size;
-  grub_uint32_t atime;
-  grub_uint32_t mtime;
-  grub_uint32_t ctime;
-  grub_uint32_t dir_zones[7];
-  grub_uint32_t indir_zone;
-  grub_uint32_t double_indir_zone;
-  grub_uint32_t unused;
-
-};
-
-/* Information about a "mounted" minix filesystem.  */
-struct grub_minix_data
-{
-  struct grub_minix_sblock sblock;
-  struct grub_minix_inode inode;
-  struct grub_minix2_inode inode2;
-  int ino;
-  int linknest;
-  grub_disk_t disk;
-  int version;
-  int filename_size;
-};
-
-static grub_dl_t my_mod;
-\f
-static grub_err_t grub_minix_find_file (struct grub_minix_data *data,
-                                       const char *path);
-
-static int
-grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
-{
-  struct grub_minix_sblock *sblock = &data->sblock;
-  int indir;
-
-  auto int grub_get_indir (int, int);
-
-  /* Read the block pointer in ZONE, on the offset NUM.  */
-  int grub_get_indir (int zone, int num)
-    {
-      if (data->version == 1)
-       {
-         grub_uint16_t indir16;
-         grub_disk_read (data->disk,
-                         zone << GRUB_MINIX_LOG2_ZONESZ,
-                         sizeof (grub_uint16_t) * num,
-                         sizeof (grub_uint16_t), (char *) &indir16);
-         return grub_le_to_cpu16 (indir16);
-       }
-      else
-       {
-         grub_uint32_t indir32;
-         grub_disk_read (data->disk,
-                         zone << GRUB_MINIX_LOG2_ZONESZ,
-                         sizeof (grub_uint32_t) * num,
-                         sizeof (grub_uint32_t), (char *) &indir32);
-         return grub_le_to_cpu32 (indir32);
-       }
-    }
-
-  /* Direct block.  */
-  if (blk < 7)
-    return GRUB_MINIX_INODE_DIR_ZONES (data, blk);
-
-  /* Indirect block.  */
-  blk -= 7;
-  if (blk < GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
-    {
-      indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk);
-      return indir;
-    }
-
-  /* Double indirect block.  */
-  blk -= GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data);
-  if (blk < (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
-      * (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data)))
-    {
-      indir = grub_get_indir (GRUB_MINIX_INODE_DINDIR_ZONE (data),
-                             blk / GRUB_MINIX_ZONESZ);
-
-      indir = grub_get_indir (indir, blk % GRUB_MINIX_ZONESZ);
-
-      return indir;
-    }
-
-  /* This should never happen.  */
-  grub_error (GRUB_ERR_OUT_OF_RANGE, "file bigger than maximum size");
-
-  return 0;
-}
-
-
-/* Read LEN bytes from the file described by DATA starting with byte
-   POS.  Return the amount of read bytes in READ.  */
-static grub_ssize_t
-grub_minix_read_file (struct grub_minix_data *data,
-                     void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                        unsigned offset, unsigned length),
-                     int pos, grub_disk_addr_t len, char *buf)
-{
-  struct grub_minix_sblock *sblock = &data->sblock;
-  int i;
-  int blockcnt;
-
-  /* Adjust len so it we can't read past the end of the file.  */
-  if (len + pos > GRUB_MINIX_INODE_SIZE (data))
-    len = GRUB_MINIX_INODE_SIZE (data) - pos;
-
-  blockcnt = (len + pos + GRUB_MINIX_BSIZE - 1) / GRUB_MINIX_BSIZE;
-
-  for (i = pos / GRUB_MINIX_BSIZE; i < blockcnt; i++)
-    {
-      int blknr;
-      int blockoff = pos % GRUB_MINIX_BSIZE;
-      int blockend = GRUB_MINIX_BSIZE;
-
-      int skipfirst = 0;
-
-      blknr = grub_minix_get_file_block (data, i);
-      if (grub_errno)
-       return -1;
-
-      /* Last block.  */
-      if (i == blockcnt - 1)
-       {
-         blockend = (len + pos) % GRUB_MINIX_BSIZE;
-
-         if (!blockend)
-           blockend = GRUB_MINIX_BSIZE;
-       }
-
-      /* First block.  */
-      if (i == (pos / (int) GRUB_MINIX_BSIZE))
-       {
-         skipfirst = blockoff;
-         blockend -= skipfirst;
-       }
-
-      data->disk->read_hook = read_hook;
-      grub_disk_read (data->disk, blknr << GRUB_MINIX_LOG2_ZONESZ,
-                     skipfirst, blockend, buf);
-
-      data->disk->read_hook = 0;
-      if (grub_errno)
-       return -1;
-
-      buf += GRUB_MINIX_BSIZE - skipfirst;
-    }
-
-  return len;
-}
-
-
-/* Read inode INO from the mounted filesystem described by DATA.  This
-   inode is used by default now.  */
-static grub_err_t
-grub_minix_read_inode (struct grub_minix_data *data, int ino)
-{
-  struct grub_minix_sblock *sblock = &data->sblock;
-
-  /* Block in which the inode is stored.  */
-  int block;
-  data->ino = ino;
-
-  /* The first inode in minix is inode 1.  */
-  ino--;
-
-  block = ((2 + grub_le_to_cpu16 (sblock->inode_bmap_size)
-           + grub_le_to_cpu16 (sblock->zone_bmap_size))
-          << GRUB_MINIX_LOG2_BSIZE);
-
-  if (data->version == 1)
-    {
-      block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
-      int offs = (ino % (GRUB_DISK_SECTOR_SIZE
-                        / sizeof (struct grub_minix_inode))
-                 * sizeof (struct grub_minix_inode));
-
-      grub_disk_read (data->disk, block, offs,
-                     sizeof (struct grub_minix_inode), &data->inode);
-    }
-  else
-    {
-      block += ino / (GRUB_DISK_SECTOR_SIZE
-                     / sizeof (struct grub_minix2_inode));
-      int offs = (ino
-                 % (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix2_inode))
-                 * sizeof (struct grub_minix2_inode));
-
-      grub_disk_read (data->disk, block, offs,
-                     sizeof (struct grub_minix2_inode),&data->inode2);
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-
-/* Lookup the symlink the current inode points to.  INO is the inode
-   number of the directory the symlink is relative to.  */
-static grub_err_t
-grub_minix_lookup_symlink (struct grub_minix_data *data, int ino)
-{
-  char symlink[GRUB_MINIX_INODE_SIZE (data) + 1];
-
-  if (++data->linknest > GRUB_MINIX_MAX_SYMLNK_CNT)
-    return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
-
-  if (grub_minix_read_file (data, 0, 0,
-                           GRUB_MINIX_INODE_SIZE (data), symlink) < 0)
-    return grub_errno;
-
-  symlink[GRUB_MINIX_INODE_SIZE (data)] = '\0';
-
-  /* The symlink is an absolute path, go back to the root inode.  */
-  if (symlink[0] == '/')
-    ino = GRUB_MINIX_ROOT_INODE;
-
-  /* Now load in the old inode.  */
-  if (grub_minix_read_inode (data, ino))
-    return grub_errno;
-
-  grub_minix_find_file (data, symlink);
-  if (grub_errno)
-    grub_error (grub_errno, "cannot follow symlink `%s'", symlink);
-
-  return grub_errno;
-}
-
-
-/* Find the file with the pathname PATH on the filesystem described by
-   DATA.  */
-static grub_err_t
-grub_minix_find_file (struct grub_minix_data *data, const char *path)
-{
-  char fpath[grub_strlen (path) + 1];
-  char *name = fpath;
-  char *next;
-  unsigned int pos = 0;
-  int dirino;
-
-  grub_strcpy (fpath, path);
-
-  /* Skip the first slash.  */
-  if (name[0] == '/')
-    {
-      name++;
-      if (!*name)
-       return 0;
-    }
-
-  /* Extract the actual part from the pathname.  */
-  next = grub_strchr (name, '/');
-  if (next)
-    {
-      next[0] = '\0';
-      next++;
-    }
-
-  do
-    {
-      grub_uint16_t ino;
-      char filename[data->filename_size + 1];
-
-      if (grub_strlen (name) == 0)
-       return GRUB_ERR_NONE;
-
-      if (grub_minix_read_file (data, 0, pos, sizeof (ino),
-                               (char *) &ino) < 0)
-       return grub_errno;
-      if (grub_minix_read_file (data, 0, pos + sizeof (ino),
-                               data->filename_size, (char *) filename)< 0)
-       return grub_errno;
-
-      filename[data->filename_size] = '\0';
-
-      /* Check if the current direntry matches the current part of the
-        pathname.  */
-      if (!grub_strcmp (name, filename))
-       {
-         dirino = data->ino;
-         grub_minix_read_inode (data, grub_le_to_cpu16 (ino));
-
-         /* Follow the symlink.  */
-         if ((GRUB_MINIX_INODE_MODE (data)
-              & GRUB_MINIX_IFLNK) == GRUB_MINIX_IFLNK)
-           {
-             grub_minix_lookup_symlink (data, dirino);
-             if (grub_errno)
-               return grub_errno;
-           }
-
-         if (!next)
-           return 0;
-
-         pos = 0;
-
-         name = next;
-         next = grub_strchr (name, '/');
-         if (next)
-           {
-             next[0] = '\0';
-             next++;
-           }
-
-         if ((GRUB_MINIX_INODE_MODE (data)
-              & GRUB_MINIX_IFDIR) != GRUB_MINIX_IFDIR)
-           return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-
-         continue;
-       }
-
-      pos += sizeof (ino) + data->filename_size;
-    } while (pos < GRUB_MINIX_INODE_SIZE (data));
-
-  grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
-  return grub_errno;
-}
-
-
-/* Mount the filesystem on the disk DISK.  */
-static struct grub_minix_data *
-grub_minix_mount (grub_disk_t disk)
-{
-  struct grub_minix_data *data;
-
-  data = grub_malloc (sizeof (struct grub_minix_data));
-  if (!data)
-    return 0;
-
-  /* Read the superblock.  */
-  grub_disk_read (disk, GRUB_MINIX_SBLOCK, 0,
-                 sizeof (struct grub_minix_sblock),&data->sblock);
-  if (grub_errno)
-    goto fail;
-
-  if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC)
-    {
-      data->version = 1;
-      data->filename_size = 14;
-    }
-  else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC)
-    {
-      data->version = 2;
-      data->filename_size = 14;
-    }
-  else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC_30)
-    {
-      data->version = 1;
-      data->filename_size = 30;
-    }
-  else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC_30)
-    {
-      data->version = 2;
-      data->filename_size = 30;
-    }
-  else
-    goto fail;
-
-  data->disk = disk;
-  data->linknest = 0;
-
-  return data;
-
- fail:
-  grub_free (data);
-  grub_error (GRUB_ERR_BAD_FS, "not a minix filesystem");
-  return 0;
-}
-\f
-static grub_err_t
-grub_minix_dir (grub_device_t device, const char *path,
-                 int (*hook) (const char *filename,
-                              const struct grub_dirhook_info *info))
-{
-  struct grub_minix_data *data = 0;
-  struct grub_minix_sblock *sblock;
-  unsigned int pos = 0;
-
-  data = grub_minix_mount (device->disk);
-  if (!data)
-    return grub_errno;
-
-  grub_minix_read_inode (data, GRUB_MINIX_ROOT_INODE);
-  if (grub_errno)
-    goto fail;
-
-  sblock = &data->sblock;
-
-  grub_minix_find_file (data, path);
-  if (grub_errno)
-    goto fail;
-
-  if ((GRUB_MINIX_INODE_MODE (data) & GRUB_MINIX_IFDIR) != GRUB_MINIX_IFDIR)
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-      goto fail;
-    }
-
-  while (pos < GRUB_MINIX_INODE_SIZE (data))
-    {
-      grub_uint16_t ino;
-      char filename[data->filename_size + 1];
-      int dirino = data->ino;
-      struct grub_dirhook_info info;
-      grub_memset (&info, 0, sizeof (info));
-
-
-      if (grub_minix_read_file (data, 0, pos, sizeof (ino),
-                               (char *) &ino) < 0)
-       return grub_errno;
-
-      if (grub_minix_read_file (data, 0, pos + sizeof (ino),
-                               data->filename_size,
-                               (char *) filename) < 0)
-       return grub_errno;
-      filename[data->filename_size] = '\0';
-
-      /* The filetype is not stored in the dirent.  Read the inode to
-        find out the filetype.  This *REALLY* sucks.  */
-      grub_minix_read_inode (data, grub_le_to_cpu16 (ino));
-      info.dir = ((GRUB_MINIX_INODE_MODE (data)
-                  & GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR);
-      if (hook (filename, &info) ? 1 : 0)
-       break;
-
-      /* Load the old inode back in.  */
-      grub_minix_read_inode (data, dirino);
-
-      pos += sizeof (ino) + data->filename_size;
-    }
-
- fail:
-  grub_free (data);
-  return grub_errno;
-}
-
-
-/* Open a file named NAME and initialize FILE.  */
-static grub_err_t
-grub_minix_open (struct grub_file *file, const char *name)
-{
-  struct grub_minix_data *data;
-  data = grub_minix_mount (file->device->disk);
-  if (!data)
-    return grub_errno;
-
-  /* Open the inode op the root directory.  */
-  grub_minix_read_inode (data, GRUB_MINIX_ROOT_INODE);
-  if (grub_errno)
-    {
-      grub_free (data);
-      return grub_errno;
-    }
-
-  if (!name || name[0] != '/')
-    {
-      grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
-      return grub_errno;
-    }
-
-  /* Traverse the directory tree to the node that should be
-     opened.  */
-  grub_minix_find_file (data, name);
-  if (grub_errno)
-    {
-      grub_free (data);
-      return grub_errno;
-    }
-
-  file->data = data;
-  file->size = GRUB_MINIX_INODE_SIZE (data);
-
-  return GRUB_ERR_NONE;
-}
-
-
-static grub_ssize_t
-grub_minix_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_minix_data *data =
-    (struct grub_minix_data *) file->data;
-
-  return grub_minix_read_file (data, file->read_hook, file->offset, len, buf);
-}
-
-
-static grub_err_t
-grub_minix_close (grub_file_t file)
-{
-  grub_free (file->data);
-
-  return GRUB_ERR_NONE;
-}
-
-
-static grub_err_t
-grub_minix_label (grub_device_t device __attribute ((unused)),
-               char **label __attribute ((unused)))
-{
-  return GRUB_ERR_NONE;
-}
-
-\f
-static struct grub_fs grub_minix_fs =
-  {
-    .name = "minix",
-    .dir = grub_minix_dir,
-    .open = grub_minix_open,
-    .read = grub_minix_read,
-    .close = grub_minix_close,
-    .label = grub_minix_label,
-    .next = 0
-  };
-
-GRUB_MOD_INIT(minix)
-{
-  grub_fs_register (&grub_minix_fs);
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(minix)
-{
-  grub_fs_unregister (&grub_minix_fs);
-}
diff --git a/fs/nilfs2.c b/fs/nilfs2.c
deleted file mode 100644 (file)
index 7e0415d..0000000
+++ /dev/null
@@ -1,1133 +0,0 @@
-/* 
- *  nilfs2.c - New Implementation of Log filesystem 
- *
- *  Written by Jiro SEKIBA <jir@unicus.jp>
- *
- *  Copyright (C) 2003,2004,2005,2007,2008,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-/* Filetype information as used in inodes.  */
-#define FILETYPE_INO_MASK      0170000
-#define FILETYPE_INO_REG       0100000
-#define FILETYPE_INO_DIRECTORY 0040000
-#define FILETYPE_INO_SYMLINK   0120000
-
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/types.h>
-#include <grub/fshelp.h>
-
-#define NILFS_INODE_BMAP_SIZE  7
-
-#define NILFS_SUPORT_REV       2
-
-/* Magic value used to identify an nilfs2 filesystem.  */
-#define        NILFS2_SUPER_MAGIC      0x3434
-/* nilfs btree node flag.  */
-#define NILFS_BTREE_NODE_ROOT   0x01
-
-/* nilfs btree node level. */
-#define NILFS_BTREE_LEVEL_DATA          0
-#define NILFS_BTREE_LEVEL_NODE_MIN      (NILFS_BTREE_LEVEL_DATA + 1)
-#define NILFS_BTREE_LEVEL_MAX           14
-
-struct grub_nilfs2_inode
-{
-  grub_uint64_t i_blocks;
-  grub_uint64_t i_size;
-  grub_uint64_t i_ctime;
-  grub_uint64_t i_mtime;
-  grub_uint32_t i_ctime_nsec;
-  grub_uint32_t i_mtime_nsec;
-  grub_uint32_t i_uid;
-  grub_uint32_t i_gid;
-  grub_uint16_t i_mode;
-  grub_uint16_t i_links_count;
-  grub_uint32_t i_flags;
-  grub_uint64_t i_bmap[NILFS_INODE_BMAP_SIZE];
-#define i_device_code  i_bmap[0]
-  grub_uint64_t i_xattr;
-  grub_uint32_t i_generation;
-  grub_uint32_t i_pad;
-};
-
-struct grub_nilfs2_super_root
-{
-  grub_uint32_t sr_sum;
-  grub_uint16_t sr_bytes;
-  grub_uint16_t sr_flags;
-  grub_uint64_t sr_nongc_ctime;
-  struct grub_nilfs2_inode sr_dat;
-  struct grub_nilfs2_inode sr_cpfile;
-  struct grub_nilfs2_inode sr_sufile;
-};
-
-struct grub_nilfs2_super_block
-{
-  grub_uint32_t s_rev_level;
-  grub_uint16_t s_minor_rev_level;
-  grub_uint16_t s_magic;
-  grub_uint16_t s_bytes;
-  grub_uint16_t s_flags;
-  grub_uint32_t s_crc_seed;
-  grub_uint32_t s_sum;
-  grub_uint32_t s_log_block_size;
-  grub_uint64_t s_nsegments;
-  grub_uint64_t s_dev_size;
-  grub_uint64_t s_first_data_block;
-  grub_uint32_t s_blocks_per_segment;
-  grub_uint32_t s_r_segments_percentage;
-  grub_uint64_t s_last_cno;
-  grub_uint64_t s_last_pseg;
-  grub_uint64_t s_last_seq;
-  grub_uint64_t s_free_blocks_count;
-  grub_uint64_t s_ctime;
-  grub_uint64_t s_mtime;
-  grub_uint64_t s_wtime;
-  grub_uint16_t s_mnt_count;
-  grub_uint16_t s_max_mnt_count;
-  grub_uint16_t s_state;
-  grub_uint16_t s_errors;
-  grub_uint64_t s_lastcheck;
-  grub_uint32_t s_checkinterval;
-  grub_uint32_t s_creator_os;
-  grub_uint16_t s_def_resuid;
-  grub_uint16_t s_def_resgid;
-  grub_uint32_t s_first_ino;
-  grub_uint16_t s_inode_size;
-  grub_uint16_t s_dat_entry_size;
-  grub_uint16_t s_checkpoint_size;
-  grub_uint16_t s_segment_usage_size;
-  grub_uint8_t s_uuid[16];
-  char s_volume_name[16];
-  char s_last_mounted[64];
-  grub_uint32_t s_c_interval;
-  grub_uint32_t s_c_block_max;
-  grub_uint32_t s_reserved[192];
-};
-
-struct grub_nilfs2_dir_entry
-{
-  grub_uint64_t inode;
-  grub_uint16_t rec_len;
-  grub_uint8_t name_len;
-  grub_uint8_t file_type;
-#if 0                          /* followed by file name. */
-  char name[NILFS_NAME_LEN];
-  char pad;
-#endif
-} __attribute__ ((packed));
-
-enum
-{
-  NILFS_FT_UNKNOWN,
-  NILFS_FT_REG_FILE,
-  NILFS_FT_DIR,
-  NILFS_FT_CHRDEV,
-  NILFS_FT_BLKDEV,
-  NILFS_FT_FIFO,
-  NILFS_FT_SOCK,
-  NILFS_FT_SYMLINK,
-  NILFS_FT_MAX
-};
-
-struct grub_nilfs2_finfo
-{
-  grub_uint64_t fi_ino;
-  grub_uint64_t fi_cno;
-  grub_uint32_t fi_nblocks;
-  grub_uint32_t fi_ndatablk;
-};
-
-struct grub_nilfs2_binfo_v
-{
-  grub_uint64_t bi_vblocknr;
-  grub_uint64_t bi_blkoff;
-};
-
-struct grub_nilfs2_binfo_dat
-{
-  grub_uint64_t bi_blkoff;
-  grub_uint8_t bi_level;
-  grub_uint8_t bi_pad[7];
-};
-
-union grub_nilfs2_binfo
-{
-  struct grub_nilfs2_binfo_v bi_v;
-  struct grub_nilfs2_binfo_dat bi_dat;
-};
-
-struct grub_nilfs2_segment_summary
-{
-  grub_uint32_t ss_datasum;
-  grub_uint32_t ss_sumsum;
-  grub_uint32_t ss_magic;
-  grub_uint16_t ss_bytes;
-  grub_uint16_t ss_flags;
-  grub_uint64_t ss_seq;
-  grub_uint64_t ss_create;
-  grub_uint64_t ss_next;
-  grub_uint32_t ss_nblocks;
-  grub_uint32_t ss_nfinfo;
-  grub_uint32_t ss_sumbytes;
-  grub_uint32_t ss_pad;
-};
-
-struct grub_nilfs2_btree_node
-{
-  grub_uint8_t bn_flags;
-  grub_uint8_t bn_level;
-  grub_uint16_t bn_nchildren;
-  grub_uint32_t bn_pad;
-};
-
-struct grub_nilfs2_palloc_group_desc
-{
-  grub_uint32_t pg_nfrees;
-};
-
-struct grub_nilfs2_dat_entry
-{
-  grub_uint64_t de_blocknr;
-  grub_uint64_t de_start;
-  grub_uint64_t de_end;
-  grub_uint64_t de_rsv;
-};
-
-struct grub_nilfs2_snapshot_list
-{
-  grub_uint64_t ssl_next;
-  grub_uint64_t ssl_prev;
-};
-
-struct grub_nilfs2_cpfile_header
-{
-  grub_uint64_t ch_ncheckpoints;
-  grub_uint64_t ch_nsnapshots;
-  struct grub_nilfs2_snapshot_list ch_snapshot_list;
-};
-
-struct grub_nilfs2_checkpoint
-{
-  grub_uint32_t cp_flags;
-  grub_uint32_t cp_checkpoints_count;
-  struct grub_nilfs2_snapshot_list cp_snapshot_list;
-  grub_uint64_t cp_cno;
-  grub_uint64_t cp_create;
-  grub_uint64_t cp_nblk_inc;
-  grub_uint64_t cp_inodes_count;
-  grub_uint64_t cp_blocks_count;
-  struct grub_nilfs2_inode cp_ifile_inode;
-};
-
-
-#define NILFS_BMAP_LARGE       0x1
-#define NILFS_BMAP_SIZE        (NILFS_INODE_BMAP_SIZE * sizeof(grub_uint64_t))
-
-/* nilfs extra padding for nonroot btree node. */
-#define NILFS_BTREE_NODE_EXTRA_PAD_SIZE (sizeof(grub_uint64_t))
-#define NILFS_BTREE_ROOT_SIZE  NILFS_BMAP_SIZE
-#define NILFS_BTREE_ROOT_NCHILDREN_MAX \
- ((NILFS_BTREE_ROOT_SIZE - sizeof(struct nilfs_btree_node)) / \
-  (sizeof(grub_uint64_t) + sizeof(grub_uint64_t)) )
-
-
-struct grub_fshelp_node
-{
-  struct grub_nilfs2_data *data;
-  struct grub_nilfs2_inode inode;
-  grub_uint64_t ino;
-  int inode_read;
-};
-
-struct grub_nilfs2_data
-{
-  struct grub_nilfs2_super_block sblock;
-  struct grub_nilfs2_super_root sroot;
-  struct grub_nilfs2_inode ifile;
-  grub_disk_t disk;
-  struct grub_nilfs2_inode *inode;
-  struct grub_fshelp_node diropen;
-};
-
-/* Log2 size of nilfs2 block in 512 blocks.  */
-#define LOG2_NILFS2_BLOCK_SIZE(data)                   \
-       (grub_le_to_cpu32 (data->sblock.s_log_block_size) + 1)
-
-/* Log2 size of nilfs2 block in bytes.  */
-#define LOG2_BLOCK_SIZE(data)                                  \
-       (grub_le_to_cpu32 (data->sblock.s_log_block_size) + 10)
-
-/* The size of an nilfs2 block in bytes.  */
-#define NILFS2_BLOCK_SIZE(data)                (1 << LOG2_BLOCK_SIZE (data))
-
-static grub_uint64_t
-grub_nilfs2_dat_translate (struct grub_nilfs2_data *data, grub_uint64_t key);
-static grub_dl_t my_mod;
-\f
-
-
-static inline unsigned long
-grub_nilfs2_palloc_entries_per_group (struct grub_nilfs2_data *data)
-{
-  return 1UL << (LOG2_BLOCK_SIZE (data) + 3);
-}
-
-static inline grub_uint64_t
-grub_nilfs2_palloc_group (struct grub_nilfs2_data *data,
-                         grub_uint64_t nr, grub_uint32_t * offset)
-{
-  return grub_divmod64 (nr, grub_nilfs2_palloc_entries_per_group (data),
-                       offset);
-}
-
-static inline grub_uint32_t
-grub_nilfs2_palloc_groups_per_desc_block (struct grub_nilfs2_data *data)
-{
-  return NILFS2_BLOCK_SIZE (data) /
-    sizeof (struct grub_nilfs2_palloc_group_desc);
-}
-
-static inline grub_uint32_t
-grub_nilfs2_entries_per_block (struct grub_nilfs2_data *data,
-                              unsigned long entry_size)
-{
-  return NILFS2_BLOCK_SIZE (data) / entry_size;
-}
-
-
-static inline grub_uint32_t
-grub_nilfs2_blocks_per_group (struct grub_nilfs2_data *data,
-                             unsigned long entry_size)
-{
-  return grub_div_roundup (grub_nilfs2_palloc_entries_per_group (data),
-                          grub_nilfs2_entries_per_block (data,
-                                                         entry_size)) + 1;
-}
-
-static inline grub_uint32_t
-grub_nilfs2_blocks_per_desc_block (struct grub_nilfs2_data *data,
-                                  unsigned long entry_size)
-{
-  return grub_nilfs2_palloc_groups_per_desc_block (data) *
-    grub_nilfs2_blocks_per_group (data, entry_size) + 1;
-}
-
-static inline grub_uint32_t
-grub_nilfs2_palloc_desc_block_offset (struct grub_nilfs2_data *data,
-                                     unsigned long group,
-                                     unsigned long entry_size)
-{
-  grub_uint32_t desc_block =
-    group / grub_nilfs2_palloc_groups_per_desc_block (data);
-  return desc_block * grub_nilfs2_blocks_per_desc_block (data, entry_size);
-}
-
-static inline grub_uint32_t
-grub_nilfs2_palloc_bitmap_block_offset (struct grub_nilfs2_data *data,
-                                       unsigned long group,
-                                       unsigned long entry_size)
-{
-  unsigned long desc_offset = group %
-    grub_nilfs2_palloc_groups_per_desc_block (data);
-
-  return grub_nilfs2_palloc_desc_block_offset (data, group, entry_size) + 1 +
-    desc_offset * grub_nilfs2_blocks_per_group (data, entry_size);
-}
-
-static inline grub_uint32_t
-grub_nilfs2_palloc_entry_offset (struct grub_nilfs2_data *data,
-                                grub_uint64_t nr, unsigned long entry_size)
-{
-  unsigned long group;
-  grub_uint32_t group_offset;
-
-  group = grub_nilfs2_palloc_group (data, nr, &group_offset);
-
-  return grub_nilfs2_palloc_bitmap_block_offset (data, group,
-                                                entry_size) + 1 +
-    group_offset / grub_nilfs2_entries_per_block (data, entry_size);
-
-}
-
-static inline struct grub_nilfs2_btree_node *
-grub_nilfs2_btree_get_root (struct grub_nilfs2_inode *inode)
-{
-  return (struct grub_nilfs2_btree_node *) &inode->i_bmap[0];
-}
-
-static inline int
-grub_nilfs2_btree_get_level (struct grub_nilfs2_btree_node *node)
-{
-  return node->bn_level;
-}
-
-static inline grub_uint64_t *
-grub_nilfs2_btree_node_dkeys (struct grub_nilfs2_btree_node *node)
-{
-  return (grub_uint64_t *) ((char *) (node + 1) +
-                           ((node->bn_flags & NILFS_BTREE_NODE_ROOT) ?
-                            0 : NILFS_BTREE_NODE_EXTRA_PAD_SIZE));
-}
-
-static inline grub_uint64_t
-grub_nilfs2_btree_node_get_key (struct grub_nilfs2_btree_node *node,
-                               int index)
-{
-  return grub_le_to_cpu64 (*(grub_nilfs2_btree_node_dkeys (node) + index));
-}
-
-static inline int
-grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node,
-                              grub_uint64_t key, int *indexp)
-{
-  grub_uint64_t nkey;
-  int index, low, high, s;
-
-  low = 0;
-  high = grub_le_to_cpu16 (node->bn_nchildren) - 1;
-  index = 0;
-  s = 0;
-  while (low <= high)
-    {
-      index = (low + high) / 2;
-      nkey = grub_nilfs2_btree_node_get_key (node, index);
-      if (nkey == key)
-       {
-         *indexp = index;
-         return 1;
-       }
-      else if (nkey < key)
-       {
-         low = index + 1;
-         s = -1;
-       }
-      else
-       {
-         high = index - 1;
-         s = 1;
-       }
-    }
-
-  if (node->bn_level > NILFS_BTREE_LEVEL_NODE_MIN)
-    {
-      if (s > 0 && index > 0)
-       index--;
-    }
-  else if (s < 0)
-    index++;
-
-  *indexp = index;
-  return s == 0;
-}
-
-static inline int
-grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data,
-                                     struct grub_nilfs2_btree_node *node)
-{
-  int node_children_max = ((NILFS2_BLOCK_SIZE (data) -
-                           sizeof (struct grub_nilfs2_btree_node) -
-                           NILFS_BTREE_NODE_EXTRA_PAD_SIZE) /
-                          (sizeof (grub_uint64_t) + sizeof (grub_uint64_t)));
-
-  return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max;
-}
-
-static inline grub_uint64_t *
-grub_nilfs2_btree_node_dptrs (struct grub_nilfs2_data *data,
-                             struct grub_nilfs2_btree_node *node)
-{
-  return (grub_uint64_t *) (grub_nilfs2_btree_node_dkeys (node) +
-                           grub_nilfs2_btree_node_nchildren_max (data,
-                                                                 node));
-}
-
-static inline grub_uint64_t
-grub_nilfs2_btree_node_get_ptr (struct grub_nilfs2_data *data,
-                               struct grub_nilfs2_btree_node *node,
-                               int index)
-{
-  return
-    grub_le_to_cpu64 (*(grub_nilfs2_btree_node_dptrs (data, node) + index));
-}
-
-static inline int
-grub_nilfs2_btree_get_nonroot_node (struct grub_nilfs2_data *data,
-                                   grub_uint64_t ptr, void *block)
-{
-  grub_disk_t disk = data->disk;
-  unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
-
-  return grub_disk_read (disk, ptr * nilfs2_block_count, 0,
-                        NILFS2_BLOCK_SIZE (data), block);
-}
-
-static grub_uint64_t
-grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data,
-                         struct grub_nilfs2_inode *inode,
-                         grub_uint64_t key, int need_translate)
-{
-  struct grub_nilfs2_btree_node *node;
-  unsigned char block[NILFS2_BLOCK_SIZE (data)];
-  grub_uint64_t ptr;
-  int level, found, index;
-
-  node = grub_nilfs2_btree_get_root (inode);
-  level = grub_nilfs2_btree_get_level (node);
-
-  found = grub_nilfs2_btree_node_lookup (node, key, &index);
-  ptr = grub_nilfs2_btree_node_get_ptr (data, node, index);
-  if (need_translate)
-    ptr = grub_nilfs2_dat_translate (data, ptr);
-
-  for (level--; level >= NILFS_BTREE_LEVEL_NODE_MIN; level--)
-    {
-      grub_nilfs2_btree_get_nonroot_node (data, ptr, block);
-      if (grub_errno)
-       {
-         return -1;
-       }
-      node = (struct grub_nilfs2_btree_node *) block;
-
-      if (node->bn_level != level)
-       {
-         grub_error (GRUB_ERR_BAD_FS, "btree level mismatch\n");
-         return -1;
-       }
-
-      if (!found)
-       found = grub_nilfs2_btree_node_lookup (node, key, &index);
-      else
-       index = 0;
-
-      if (index < grub_nilfs2_btree_node_nchildren_max (data, node))
-       {
-         ptr = grub_nilfs2_btree_node_get_ptr (data, node, index);
-         if (need_translate)
-           ptr = grub_nilfs2_dat_translate (data, ptr);
-       }
-      else
-       {
-         grub_error (GRUB_ERR_BAD_FS, "btree corruption\n");
-         return -1;
-       }
-    }
-
-  if (!found)
-    return -1;
-
-  return ptr;
-}
-
-static inline grub_uint64_t
-grub_nilfs2_direct_lookup (struct grub_nilfs2_inode *inode, grub_uint64_t key)
-{
-  return grub_le_to_cpu64 (inode->i_bmap[1 + key]);
-}
-
-static inline grub_uint64_t
-grub_nilfs2_bmap_lookup (struct grub_nilfs2_data *data,
-                        struct grub_nilfs2_inode *inode,
-                        grub_uint64_t key, int need_translate)
-{
-  struct grub_nilfs2_btree_node *root = grub_nilfs2_btree_get_root (inode);
-  if (root->bn_flags & NILFS_BMAP_LARGE)
-    return grub_nilfs2_btree_lookup (data, inode, key, need_translate);
-  else
-    {
-      grub_uint64_t ptr;
-      ptr = grub_nilfs2_direct_lookup (inode, key);
-      if (need_translate)
-       ptr = grub_nilfs2_dat_translate (data, ptr);
-      return ptr;
-    }
-}
-
-static grub_uint64_t
-grub_nilfs2_dat_translate (struct grub_nilfs2_data *data, grub_uint64_t key)
-{
-  struct grub_nilfs2_dat_entry entry;
-  grub_disk_t disk = data->disk;
-  grub_uint64_t pptr;
-  grub_uint32_t blockno, offset;
-  unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
-
-  blockno = grub_nilfs2_palloc_entry_offset (data, key,
-                                            sizeof (struct
-                                                    grub_nilfs2_dat_entry));
-
-  grub_divmod64 (key * sizeof (struct grub_nilfs2_dat_entry),
-                NILFS2_BLOCK_SIZE (data), &offset);
-
-  pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_dat, blockno, 0);
-  if (pptr == (grub_uint64_t) - 1)
-    {
-      grub_error (GRUB_ERR_BAD_FS, "btree lookup failure");
-      return -1;
-    }
-
-  grub_disk_read (disk, pptr * nilfs2_block_count, offset,
-                 sizeof (struct grub_nilfs2_dat_entry), &entry);
-
-  return grub_le_to_cpu64 (entry.de_blocknr);
-}
-
-
-static grub_disk_addr_t
-grub_nilfs2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
-{
-  struct grub_nilfs2_data *data = node->data;
-  struct grub_nilfs2_inode *inode = &node->inode;
-  grub_uint64_t pptr = -1;
-
-  pptr = grub_nilfs2_bmap_lookup (data, inode, fileblock, 1);
-  if (pptr == (grub_uint64_t) - 1)
-    {
-      grub_error (GRUB_ERR_BAD_FS, "btree lookup failure");
-      return -1;
-    }
-
-  return pptr;
-}
-
-/* Read LEN bytes from the file described by DATA starting with byte
-   POS.  Return the amount of read bytes in READ.  */
-static grub_ssize_t
-grub_nilfs2_read_file (grub_fshelp_node_t node,
-                      void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
-                                                          sector,
-                                                          unsigned offset,
-                                                          unsigned length),
-                      int pos, grub_size_t len, char *buf)
-{
-  return grub_fshelp_read_file (node->data->disk, node, read_hook,
-                               pos, len, buf, grub_nilfs2_read_block,
-                               grub_le_to_cpu64 (node->inode.i_size),
-                               LOG2_NILFS2_BLOCK_SIZE (node->data));
-
-}
-
-static grub_err_t
-grub_nilfs2_read_checkpoint (struct grub_nilfs2_data *data,
-                            grub_uint64_t cpno,
-                            struct grub_nilfs2_checkpoint *cpp)
-{
-  grub_uint64_t blockno;
-  grub_uint32_t offset;
-  grub_uint64_t pptr;
-  grub_disk_t disk = data->disk;
-  unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
-
-  /* Assume sizeof(struct grub_nilfs2_cpfile_header) < 
-     sizeof(struct grub_nilfs2_checkpoint).
-   */
-  blockno = grub_divmod64 (cpno, NILFS2_BLOCK_SIZE (data) /
-                          sizeof (struct grub_nilfs2_checkpoint), &offset);
-
-  pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_cpfile, blockno, 1);
-  if (pptr == (grub_uint64_t) - 1)
-    {
-      return grub_error (GRUB_ERR_BAD_FS, "btree lookup failure");
-    }
-
-  return grub_disk_read (disk, pptr * nilfs2_block_count,
-                        offset * sizeof (struct grub_nilfs2_checkpoint),
-                        sizeof (struct grub_nilfs2_checkpoint), cpp);
-}
-
-static inline grub_err_t
-grub_nilfs2_read_last_checkpoint (struct grub_nilfs2_data *data,
-                                 struct grub_nilfs2_checkpoint *cpp)
-{
-  return grub_nilfs2_read_checkpoint (data,
-                                     grub_le_to_cpu64 (data->
-                                                       sblock.s_last_cno),
-                                     cpp);
-}
-
-/* Read the inode INO for the file described by DATA into INODE.  */
-static grub_err_t
-grub_nilfs2_read_inode (struct grub_nilfs2_data *data,
-                       grub_uint64_t ino, struct grub_nilfs2_inode *inodep)
-{
-  grub_uint64_t blockno;
-  unsigned int offset;
-  grub_uint64_t pptr;
-  grub_disk_t disk = data->disk;
-  unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
-
-  blockno = grub_nilfs2_palloc_entry_offset (data, ino,
-                                            sizeof (struct
-                                                    grub_nilfs2_inode));
-
-  grub_divmod64 (sizeof (struct grub_nilfs2_inode) * ino,
-                NILFS2_BLOCK_SIZE (data), &offset);
-  pptr = grub_nilfs2_bmap_lookup (data, &data->ifile, blockno, 1);
-  if (pptr == (grub_uint64_t) - 1)
-    {
-      return grub_error (GRUB_ERR_BAD_FS, "btree lookup failure");
-    }
-
-  return grub_disk_read (disk, pptr * nilfs2_block_count, offset,
-                        sizeof (struct grub_nilfs2_inode), inodep);
-}
-
-static int
-grub_nilfs2_valid_sb (struct grub_nilfs2_super_block *sbp)
-{
-  if (grub_le_to_cpu16 (sbp->s_magic) != NILFS2_SUPER_MAGIC)
-    return 0;
-
-  if (grub_le_to_cpu32 (sbp->s_rev_level) != NILFS_SUPORT_REV)
-    return 0;
-
-  return 1;
-}
-
-static struct grub_nilfs2_data *
-grub_nilfs2_mount (grub_disk_t disk)
-{
-  struct grub_nilfs2_data *data;
-  struct grub_nilfs2_segment_summary ss;
-  struct grub_nilfs2_checkpoint last_checkpoint;
-  grub_uint64_t last_pseg;
-  grub_uint32_t nblocks;
-  unsigned int nilfs2_block_count;
-
-  data = grub_malloc (sizeof (struct grub_nilfs2_data));
-  if (!data)
-    return 0;
-
-  /* Read the superblock.  */
-  grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_block),
-                 &data->sblock);
-  if (grub_errno)
-    goto fail;
-
-  /* Make sure this is an nilfs2 filesystem.  */
-  if (!grub_nilfs2_valid_sb (&data->sblock))
-    {
-      grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem");
-      goto fail;
-    }
-
-  nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
-
-  /* Read the last segment summary. */
-  last_pseg = grub_le_to_cpu64 (data->sblock.s_last_pseg);
-  grub_disk_read (disk, last_pseg * nilfs2_block_count, 0,
-                 sizeof (struct grub_nilfs2_segment_summary), &ss);
-
-  if (grub_errno)
-    goto fail;
-
-  /* Read the super root block. */
-  nblocks = grub_le_to_cpu32 (ss.ss_nblocks);
-  grub_disk_read (disk, (last_pseg + (nblocks - 1)) * nilfs2_block_count, 0,
-                 sizeof (struct grub_nilfs2_super_root), &data->sroot);
-
-  if (grub_errno)
-    goto fail;
-
-  data->disk = disk;
-
-  grub_nilfs2_read_last_checkpoint (data, &last_checkpoint);
-
-  if (grub_errno)
-    goto fail;
-
-  grub_memcpy (&data->ifile, &last_checkpoint.cp_ifile_inode,
-              sizeof (struct grub_nilfs2_inode));
-
-  data->diropen.data = data;
-  data->diropen.ino = 2;
-  data->diropen.inode_read = 1;
-  data->inode = &data->diropen.inode;
-
-  grub_nilfs2_read_inode (data, 2, data->inode);
-
-  return data;
-
-fail:
-  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
-    grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem");
-
-  grub_free (data);
-  return 0;
-}
-
-static char *
-grub_nilfs2_read_symlink (grub_fshelp_node_t node)
-{
-  char *symlink;
-  struct grub_fshelp_node *diro = node;
-
-  if (!diro->inode_read)
-    {
-      grub_nilfs2_read_inode (diro->data, diro->ino, &diro->inode);
-      if (grub_errno)
-       return 0;
-    }
-
-  symlink = grub_malloc (grub_le_to_cpu64 (diro->inode.i_size) + 1);
-  if (!symlink)
-    return 0;
-
-  grub_nilfs2_read_file (diro, 0, 0,
-                        grub_le_to_cpu64 (diro->inode.i_size), symlink);
-  if (grub_errno)
-    {
-      grub_free (symlink);
-      return 0;
-    }
-
-  symlink[grub_le_to_cpu64 (diro->inode.i_size)] = '\0';
-  return symlink;
-}
-
-static int
-grub_nilfs2_iterate_dir (grub_fshelp_node_t dir,
-                        int NESTED_FUNC_ATTR
-                        (*hook) (const char *filename,
-                                 enum grub_fshelp_filetype filetype,
-                                 grub_fshelp_node_t node))
-{
-  unsigned int fpos = 0;
-  struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
-
-  if (!diro->inode_read)
-    {
-      grub_nilfs2_read_inode (diro->data, diro->ino, &diro->inode);
-      if (grub_errno)
-       return 0;
-    }
-
-  /* Iterate files.  */
-  while (fpos < grub_le_to_cpu64 (diro->inode.i_size))
-    {
-      struct grub_nilfs2_dir_entry dirent;
-
-      grub_nilfs2_read_file (diro, 0, fpos,
-                            sizeof (struct grub_nilfs2_dir_entry),
-                            (char *) &dirent);
-      if (grub_errno)
-       return 0;
-
-      if (dirent.rec_len == 0)
-       return 0;
-
-      if (dirent.name_len != 0)
-       {
-         char filename[dirent.name_len + 1];
-         struct grub_fshelp_node *fdiro;
-         enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN;
-
-         grub_nilfs2_read_file (diro, 0,
-                                fpos + sizeof (struct grub_nilfs2_dir_entry),
-                                dirent.name_len, filename);
-         if (grub_errno)
-           return 0;
-
-         fdiro = grub_malloc (sizeof (struct grub_fshelp_node));
-         if (!fdiro)
-           return 0;
-
-         fdiro->data = diro->data;
-         fdiro->ino = grub_le_to_cpu64 (dirent.inode);
-
-         filename[dirent.name_len] = '\0';
-
-         if (dirent.file_type != NILFS_FT_UNKNOWN)
-           {
-             fdiro->inode_read = 0;
-
-             if (dirent.file_type == NILFS_FT_DIR)
-               type = GRUB_FSHELP_DIR;
-             else if (dirent.file_type == NILFS_FT_SYMLINK)
-               type = GRUB_FSHELP_SYMLINK;
-             else if (dirent.file_type == NILFS_FT_REG_FILE)
-               type = GRUB_FSHELP_REG;
-           }
-         else
-           {
-             /* The filetype can not be read from the dirent, read
-                the inode to get more information.  */
-             grub_nilfs2_read_inode (diro->data,
-                                     grub_le_to_cpu64 (dirent.inode),
-                                     &fdiro->inode);
-             if (grub_errno)
-               {
-                 grub_free (fdiro);
-                 return 0;
-               }
-
-             fdiro->inode_read = 1;
-
-             if ((grub_le_to_cpu16 (fdiro->inode.i_mode)
-                  & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY)
-               type = GRUB_FSHELP_DIR;
-             else if ((grub_le_to_cpu16 (fdiro->inode.i_mode)
-                       & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK)
-               type = GRUB_FSHELP_SYMLINK;
-             else if ((grub_le_to_cpu16 (fdiro->inode.i_mode)
-                       & FILETYPE_INO_MASK) == FILETYPE_INO_REG)
-               type = GRUB_FSHELP_REG;
-           }
-
-         if (hook (filename, type, fdiro))
-           return 1;
-       }
-
-      fpos += grub_le_to_cpu16 (dirent.rec_len);
-    }
-
-  return 0;
-}
-
-/* Open a file named NAME and initialize FILE.  */
-static grub_err_t
-grub_nilfs2_open (struct grub_file *file, const char *name)
-{
-  struct grub_nilfs2_data *data = NULL;
-  struct grub_fshelp_node *fdiro = 0;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_nilfs2_mount (file->device->disk);
-  if (!data)
-    goto fail;
-
-  grub_fshelp_find_file (name, &data->diropen, &fdiro,
-                        grub_nilfs2_iterate_dir, grub_nilfs2_read_symlink,
-                        GRUB_FSHELP_REG);
-  if (grub_errno)
-    goto fail;
-
-  if (!fdiro->inode_read)
-    {
-      grub_nilfs2_read_inode (data, fdiro->ino, &fdiro->inode);
-      if (grub_errno)
-       goto fail;
-    }
-
-  grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_nilfs2_inode));
-  grub_free (fdiro);
-
-  file->size = grub_le_to_cpu64 (data->inode->i_size);
-  file->data = data;
-  file->offset = 0;
-
-  return 0;
-
-fail:
-  if (fdiro != &data->diropen)
-    grub_free (fdiro);
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_nilfs2_close (grub_file_t file)
-{
-  grub_free (file->data);
-
-  grub_dl_unref (my_mod);
-
-  return GRUB_ERR_NONE;
-}
-
-/* Read LEN bytes data from FILE into BUF.  */
-static grub_ssize_t
-grub_nilfs2_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_nilfs2_data *data = (struct grub_nilfs2_data *) file->data;
-
-  return grub_nilfs2_read_file (&data->diropen, file->read_hook,
-                               file->offset, len, buf);
-}
-
-static grub_err_t
-grub_nilfs2_dir (grub_device_t device, const char *path,
-                int (*hook) (const char *filename,
-                             const struct grub_dirhook_info * info))
-{
-  struct grub_nilfs2_data *data = 0;
-  struct grub_fshelp_node *fdiro = 0;
-
-  auto int NESTED_FUNC_ATTR iterate (const char *filename,
-                                    enum grub_fshelp_filetype filetype,
-                                    grub_fshelp_node_t node);
-
-  int NESTED_FUNC_ATTR iterate (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node)
-  {
-    struct grub_dirhook_info info;
-    grub_memset (&info, 0, sizeof (info));
-    if (!node->inode_read)
-      {
-       grub_nilfs2_read_inode (data, node->ino, &node->inode);
-       if (!grub_errno)
-         node->inode_read = 1;
-       grub_errno = GRUB_ERR_NONE;
-      }
-    if (node->inode_read)
-      {
-       info.mtimeset = 1;
-       info.mtime = grub_le_to_cpu64 (node->inode.i_mtime);
-      }
-
-    info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
-    grub_free (node);
-    return hook (filename, &info);
-  }
-
-  grub_dl_ref (my_mod);
-
-  data = grub_nilfs2_mount (device->disk);
-  if (!data)
-    goto fail;
-
-  grub_fshelp_find_file (path, &data->diropen, &fdiro,
-                        grub_nilfs2_iterate_dir, grub_nilfs2_read_symlink,
-                        GRUB_FSHELP_DIR);
-  if (grub_errno)
-    goto fail;
-
-  grub_nilfs2_iterate_dir (fdiro, iterate);
-
-fail:
-  if (fdiro != &data->diropen)
-    grub_free (fdiro);
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_nilfs2_label (grub_device_t device, char **label)
-{
-  struct grub_nilfs2_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_nilfs2_mount (disk);
-  if (data)
-    *label = grub_strndup (data->sblock.s_volume_name, 14);
-  else
-    *label = NULL;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_nilfs2_uuid (grub_device_t device, char **uuid)
-{
-  struct grub_nilfs2_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_nilfs2_mount (disk);
-  if (data)
-    {
-      *uuid =
-       grub_xasprintf
-       ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%0x-%02x%02x%02x%02x%02x%02x",
-        data->sblock.s_uuid[0], data->sblock.s_uuid[1],
-        data->sblock.s_uuid[2], data->sblock.s_uuid[3],
-        data->sblock.s_uuid[4], data->sblock.s_uuid[5],
-        data->sblock.s_uuid[6], data->sblock.s_uuid[7],
-        data->sblock.s_uuid[8], data->sblock.s_uuid[9],
-        data->sblock.s_uuid[10], data->sblock.s_uuid[11],
-        data->sblock.s_uuid[12], data->sblock.s_uuid[13],
-        data->sblock.s_uuid[14], data->sblock.s_uuid[15]);
-    }
-  else
-    *uuid = NULL;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-/* Get mtime.  */
-static grub_err_t
-grub_nilfs2_mtime (grub_device_t device, grub_int32_t * tm)
-{
-  struct grub_nilfs2_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_nilfs2_mount (disk);
-  if (!data)
-    *tm = 0;
-  else
-    *tm = (grub_int32_t) grub_le_to_cpu64 (data->sblock.s_mtime);
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-\f
-
-
-static struct grub_fs grub_nilfs2_fs = {
-  .name = "nilfs2",
-  .dir = grub_nilfs2_dir,
-  .open = grub_nilfs2_open,
-  .read = grub_nilfs2_read,
-  .close = grub_nilfs2_close,
-  .label = grub_nilfs2_label,
-  .uuid = grub_nilfs2_uuid,
-  .mtime = grub_nilfs2_mtime,
-#ifdef GRUB_UTIL
-  .reserved_first_sector = 1,
-#endif
-  .next = 0
-};
-
-GRUB_MOD_INIT (nilfs2)
-{
-  grub_fs_register (&grub_nilfs2_fs);
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI (nilfs2)
-{
-  grub_fs_unregister (&grub_nilfs2_fs);
-}
diff --git a/fs/ntfs.c b/fs/ntfs.c
deleted file mode 100644 (file)
index dd041e2..0000000
--- a/fs/ntfs.c
+++ /dev/null
@@ -1,1111 +0,0 @@
-/* ntfs.c - NTFS filesystem */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007,2008,2009 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 3 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/fshelp.h>
-#include <grub/ntfs.h>
-#include <grub/charset.h>
-
-static grub_dl_t my_mod;
-
-ntfscomp_func_t grub_ntfscomp_func;
-
-static grub_err_t
-fixup (struct grub_ntfs_data *data, char *buf, int len, char *magic)
-{
-  int ss;
-  char *pu;
-  grub_uint16_t us;
-
-  if (grub_memcmp (buf, magic, 4))
-    return grub_error (GRUB_ERR_BAD_FS, "%s label not found", magic);
-
-  ss = u16at (buf, 6) - 1;
-  if (ss * (int) data->blocksize != len * GRUB_DISK_SECTOR_SIZE)
-    return grub_error (GRUB_ERR_BAD_FS, "size not match",
-                      ss * (int) data->blocksize,
-                      len * GRUB_DISK_SECTOR_SIZE);
-  pu = buf + u16at (buf, 4);
-  us = u16at (pu, 0);
-  buf -= 2;
-  while (ss > 0)
-    {
-      buf += data->blocksize;
-      pu += 2;
-      if (u16at (buf, 0) != us)
-       return grub_error (GRUB_ERR_BAD_FS, "fixup signature not match");
-      v16at (buf, 0) = v16at (pu, 0);
-      ss--;
-    }
-
-  return 0;
-}
-
-static grub_err_t read_mft (struct grub_ntfs_data *data, char *buf,
-                           grub_uint32_t mftno);
-static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest,
-                            grub_disk_addr_t ofs, grub_size_t len,
-                            int cached,
-                            void
-                            NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
-                                                           sector,
-                                                           unsigned offset,
-                                                           unsigned length));
-
-static grub_err_t read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
-                            grub_disk_addr_t ofs, grub_size_t len,
-                            int cached,
-                            void
-                            NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
-                                                           sector,
-                                                           unsigned offset,
-                                                           unsigned length));
-
-static void
-init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft)
-{
-  at->mft = mft;
-  at->flags = (mft == &mft->data->mmft) ? AF_MMFT : 0;
-  at->attr_nxt = mft->buf + u16at (mft->buf, 0x14);
-  at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL;
-}
-
-static void
-free_attr (struct grub_ntfs_attr *at)
-{
-  grub_free (at->emft_buf);
-  grub_free (at->edat_buf);
-  grub_free (at->sbuf);
-}
-
-static char *
-find_attr (struct grub_ntfs_attr *at, unsigned char attr)
-{
-  if (at->flags & AF_ALST)
-    {
-    retry:
-      while (at->attr_nxt < at->attr_end)
-       {
-         at->attr_cur = at->attr_nxt;
-         at->attr_nxt += u16at (at->attr_cur, 4);
-         if (((unsigned char) *at->attr_cur == attr) || (attr == 0))
-           {
-             char *new_pos;
-
-             if (at->flags & AF_MMFT)
-               {
-                 if ((grub_disk_read
-                      (at->mft->data->disk, v32at (at->attr_cur, 0x10), 0,
-                       512, at->emft_buf))
-                     ||
-                     (grub_disk_read
-                      (at->mft->data->disk, v32at (at->attr_cur, 0x14), 0,
-                       512, at->emft_buf + 512)))
-                   return NULL;
-
-                 if (fixup
-                     (at->mft->data, at->emft_buf, at->mft->data->mft_size,
-                      "FILE"))
-                   return NULL;
-               }
-             else
-               {
-                 if (read_mft (at->mft->data, at->emft_buf,
-                               u32at (at->attr_cur, 0x10)))
-                   return NULL;
-               }
-
-             new_pos = &at->emft_buf[u16at (at->emft_buf, 0x14)];
-             while ((unsigned char) *new_pos != 0xFF)
-               {
-                 if (((unsigned char) *new_pos ==
-                      (unsigned char) *at->attr_cur)
-                     && (u16at (new_pos, 0xE) == u16at (at->attr_cur, 0x18)))
-                   {
-                     return new_pos;
-                   }
-                 new_pos += u16at (new_pos, 4);
-               }
-             grub_error (GRUB_ERR_BAD_FS,
-                         "can\'t find 0x%X in attribute list",
-                         (unsigned char) *at->attr_cur);
-             return NULL;
-           }
-       }
-      return NULL;
-    }
-  at->attr_cur = at->attr_nxt;
-  while ((unsigned char) *at->attr_cur != 0xFF)
-    {
-      at->attr_nxt += u16at (at->attr_cur, 4);
-      if ((unsigned char) *at->attr_cur == AT_ATTRIBUTE_LIST)
-       at->attr_end = at->attr_cur;
-      if (((unsigned char) *at->attr_cur == attr) || (attr == 0))
-       return at->attr_cur;
-      at->attr_cur = at->attr_nxt;
-    }
-  if (at->attr_end)
-    {
-      char *pa;
-
-      at->emft_buf = grub_malloc (at->mft->data->mft_size << BLK_SHR);
-      if (at->emft_buf == NULL)
-       return NULL;
-
-      pa = at->attr_end;
-      if (pa[8])
-       {
-          int n;
-
-          n = ((u32at (pa, 0x30) + GRUB_DISK_SECTOR_SIZE - 1)
-               & (~(GRUB_DISK_SECTOR_SIZE - 1)));
-         at->attr_cur = at->attr_end;
-         at->edat_buf = grub_malloc (n);
-         if (!at->edat_buf)
-           return NULL;
-         if (read_data (at, pa, at->edat_buf, 0, n, 0, 0))
-           {
-             grub_error (GRUB_ERR_BAD_FS,
-                         "fail to read non-resident attribute list");
-             return NULL;
-           }
-         at->attr_nxt = at->edat_buf;
-         at->attr_end = at->edat_buf + u32at (pa, 0x30);
-       }
-      else
-       {
-         at->attr_nxt = at->attr_end + u16at (pa, 0x14);
-         at->attr_end = at->attr_end + u32at (pa, 4);
-       }
-      at->flags |= AF_ALST;
-      while (at->attr_nxt < at->attr_end)
-       {
-         if (((unsigned char) *at->attr_nxt == attr) || (attr == 0))
-           break;
-         at->attr_nxt += u16at (at->attr_nxt, 4);
-       }
-      if (at->attr_nxt >= at->attr_end)
-       return NULL;
-
-      if ((at->flags & AF_MMFT) && (attr == AT_DATA))
-       {
-         at->flags |= AF_GPOS;
-         at->attr_cur = at->attr_nxt;
-         pa = at->attr_cur;
-         v32at (pa, 0x10) = at->mft->data->mft_start;
-         v32at (pa, 0x14) = at->mft->data->mft_start + 1;
-         pa = at->attr_nxt + u16at (pa, 4);
-         while (pa < at->attr_end)
-           {
-             if ((unsigned char) *pa != attr)
-               break;
-             if (read_attr
-                 (at, pa + 0x10,
-                  u32at (pa, 0x10) * (at->mft->data->mft_size << BLK_SHR),
-                  at->mft->data->mft_size << BLK_SHR, 0, 0))
-               return NULL;
-             pa += u16at (pa, 4);
-           }
-         at->attr_nxt = at->attr_cur;
-         at->flags &= ~AF_GPOS;
-       }
-      goto retry;
-    }
-  return NULL;
-}
-
-static char *
-locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft,
-            unsigned char attr)
-{
-  char *pa;
-
-  init_attr (at, mft);
-  if ((pa = find_attr (at, attr)) == NULL)
-    return NULL;
-  if ((at->flags & AF_ALST) == 0)
-    {
-      while (1)
-       {
-         if ((pa = find_attr (at, attr)) == NULL)
-           break;
-         if (at->flags & AF_ALST)
-           return pa;
-       }
-      grub_errno = GRUB_ERR_NONE;
-      free_attr (at);
-      init_attr (at, mft);
-      pa = find_attr (at, attr);
-    }
-  return pa;
-}
-
-static char *
-read_run_data (char *run, int nn, grub_disk_addr_t * val, int sig)
-{
-  grub_disk_addr_t r, v;
-
-  r = 0;
-  v = 1;
-
-  while (nn--)
-    {
-      r += v * (*(unsigned char *) (run++));
-      v <<= 8;
-    }
-
-  if ((sig) && (r & (v >> 1)))
-    r -= v;
-
-  *val = r;
-  return run;
-}
-
-grub_err_t
-grub_ntfs_read_run_list (struct grub_ntfs_rlst * ctx)
-{
-  int c1, c2;
-  grub_disk_addr_t val;
-  char *run;
-
-  run = ctx->cur_run;
-retry:
-  c1 = ((unsigned char) (*run) & 0xF);
-  c2 = ((unsigned char) (*run) >> 4);
-  if (!c1)
-    {
-      if ((ctx->attr) && (ctx->attr->flags & AF_ALST))
-       {
-         void NESTED_FUNC_ATTR (*save_hook) (grub_disk_addr_t sector,
-                                             unsigned offset,
-                                             unsigned length);
-
-         save_hook = ctx->comp.disk->read_hook;
-         ctx->comp.disk->read_hook = 0;
-         run = find_attr (ctx->attr, (unsigned char) *ctx->attr->attr_cur);
-         ctx->comp.disk->read_hook = save_hook;
-         if (run)
-           {
-             if (run[8] == 0)
-               return grub_error (GRUB_ERR_BAD_FS,
-                                  "$DATA should be non-resident");
-
-             run += u16at (run, 0x20);
-             ctx->curr_lcn = 0;
-             goto retry;
-           }
-       }
-      return grub_error (GRUB_ERR_BAD_FS, "run list overflown");
-    }
-  run = read_run_data (run + 1, c1, &val, 0);  /* length of current VCN */
-  ctx->curr_vcn = ctx->next_vcn;
-  ctx->next_vcn += val;
-  run = read_run_data (run, c2, &val, 1);      /* offset to previous LCN */
-  ctx->curr_lcn += val;
-  if (val == 0)
-    ctx->flags |= RF_BLNK;
-  else
-    ctx->flags &= ~RF_BLNK;
-  ctx->cur_run = run;
-  return 0;
-}
-
-static grub_disk_addr_t
-grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block)
-{
-  struct grub_ntfs_rlst *ctx;
-
-  ctx = (struct grub_ntfs_rlst *) node;
-  if (block >= ctx->next_vcn)
-    {
-      if (grub_ntfs_read_run_list (ctx))
-       return -1;
-      return ctx->curr_lcn;
-    }
-  else
-    return (ctx->flags & RF_BLNK) ? 0 : (block -
-                                        ctx->curr_vcn + ctx->curr_lcn);
-}
-
-static grub_err_t
-read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
-          grub_disk_addr_t ofs, grub_size_t len, int cached,
-          void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                              unsigned offset,
-                                              unsigned length))
-{
-  grub_disk_addr_t vcn;
-  struct grub_ntfs_rlst cc, *ctx;
-
-  if (len == 0)
-    return 0;
-
-  grub_memset (&cc, 0, sizeof (cc));
-  ctx = &cc;
-  ctx->attr = at;
-  ctx->comp.spc = at->mft->data->spc;
-  ctx->comp.disk = at->mft->data->disk;
-
-  if (pa[8] == 0)
-    {
-      if (ofs + len > u32at (pa, 0x10))
-       return grub_error (GRUB_ERR_BAD_FS, "read out of range");
-      grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len);
-      return 0;
-    }
-
-  if (u16at (pa, 0xC) & FLAG_COMPRESSED)
-    ctx->flags |= RF_COMP;
-  else
-    ctx->flags &= ~RF_COMP;
-  ctx->cur_run = pa + u16at (pa, 0x20);
-
-  if (ctx->flags & RF_COMP)
-    {
-      if (!cached)
-       return grub_error (GRUB_ERR_BAD_FS, "attribute can\'t be compressed");
-
-      if (at->sbuf)
-       {
-         if ((ofs & (~(COM_LEN - 1))) == at->save_pos)
-           {
-             grub_disk_addr_t n;
-
-             n = COM_LEN - (ofs - at->save_pos);
-             if (n > len)
-               n = len;
-
-             grub_memcpy (dest, at->sbuf + ofs - at->save_pos, n);
-             if (n == len)
-               return 0;
-
-             dest += n;
-             len -= n;
-             ofs += n;
-           }
-       }
-      else
-       {
-         at->sbuf = grub_malloc (COM_LEN);
-         if (at->sbuf == NULL)
-           return grub_errno;
-         at->save_pos = 1;
-       }
-
-      vcn = ctx->target_vcn = (ofs >> COM_LOG_LEN) * (COM_SEC / ctx->comp.spc);
-      ctx->target_vcn &= ~0xF;
-    }
-  else
-    vcn = ctx->target_vcn = grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, 0);
-
-  ctx->next_vcn = u32at (pa, 0x10);
-  ctx->curr_lcn = 0;
-  while (ctx->next_vcn <= ctx->target_vcn)
-    {
-      if (grub_ntfs_read_run_list (ctx))
-       return grub_errno;
-    }
-
-  if (at->flags & AF_GPOS)
-    {
-      grub_disk_addr_t st0, st1;
-      grub_uint32_t m;
-
-      grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, &m);
-
-      st0 =
-       (ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc + m;
-      st1 = st0 + 1;
-      if (st1 ==
-         (ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc)
-       {
-         if (grub_ntfs_read_run_list (ctx))
-           return grub_errno;
-         st1 = ctx->curr_lcn * ctx->comp.spc;
-       }
-      v32at (dest, 0) = st0;
-      v32at (dest, 4) = st1;
-      return 0;
-    }
-
-  if (!(ctx->flags & RF_COMP))
-    {
-      unsigned int pow;
-
-      if (!grub_fshelp_log2blksize (ctx->comp.spc, &pow))
-       grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx,
-                              read_hook, ofs, len, dest,
-                              grub_ntfs_read_block, ofs + len, pow);
-      return grub_errno;
-    }
-
-  return (grub_ntfscomp_func) ? grub_ntfscomp_func (at, dest, ofs, len, ctx,
-                                                   vcn) :
-    grub_error (GRUB_ERR_BAD_FS, "ntfscomp module not loaded");
-}
-
-static grub_err_t
-read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs,
-          grub_size_t len, int cached,
-          void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                              unsigned offset,
-                                              unsigned length))
-{
-  char *save_cur;
-  unsigned char attr;
-  char *pp;
-  grub_err_t ret;
-
-  save_cur = at->attr_cur;
-  at->attr_nxt = at->attr_cur;
-  attr = (unsigned char) *at->attr_nxt;
-  if (at->flags & AF_ALST)
-    {
-      char *pa;
-      grub_disk_addr_t vcn;
-
-      vcn = grub_divmod64 (ofs, at->mft->data->spc << BLK_SHR, 0);
-      pa = at->attr_nxt + u16at (at->attr_nxt, 4);
-      while (pa < at->attr_end)
-       {
-         if ((unsigned char) *pa != attr)
-           break;
-         if (u32at (pa, 8) > vcn)
-           break;
-         at->attr_nxt = pa;
-         pa += u16at (pa, 4);
-       }
-    }
-  pp = find_attr (at, attr);
-  if (pp)
-    ret = read_data (at, pp, dest, ofs, len, cached, read_hook);
-  else
-    ret =
-      (grub_errno) ? grub_errno : grub_error (GRUB_ERR_BAD_FS,
-                                             "attribute not found");
-  at->attr_cur = save_cur;
-  return ret;
-}
-
-static grub_err_t
-read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno)
-{
-  if (read_attr
-      (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << BLK_SHR),
-       data->mft_size << BLK_SHR, 0, 0))
-    return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%X fails", mftno);
-  return fixup (data, buf, data->mft_size, "FILE");
-}
-
-static grub_err_t
-init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno)
-{
-  unsigned short flag;
-
-  mft->inode_read = 1;
-
-  mft->buf = grub_malloc (mft->data->mft_size << BLK_SHR);
-  if (mft->buf == NULL)
-    return grub_errno;
-
-  if (read_mft (mft->data, mft->buf, mftno))
-    return grub_errno;
-
-  flag = u16at (mft->buf, 0x16);
-  if ((flag & 1) == 0)
-    return grub_error (GRUB_ERR_BAD_FS, "MFT 0x%X is not in use", mftno);
-
-  if ((flag & 2) == 0)
-    {
-      char *pa;
-
-      pa = locate_attr (&mft->attr, mft, AT_DATA);
-      if (pa == NULL)
-       return grub_error (GRUB_ERR_BAD_FS, "no $DATA in MFT 0x%X", mftno);
-
-      if (!pa[8])
-       mft->size = u32at (pa, 0x10);
-      else
-       mft->size = u64at (pa, 0x30);
-
-      if ((mft->attr.flags & AF_ALST) == 0)
-       mft->attr.attr_end = 0; /*  Don't jump to attribute list */
-    }
-  else
-    init_attr (&mft->attr, mft);
-
-  return 0;
-}
-
-static void
-free_file (struct grub_ntfs_file *mft)
-{
-  free_attr (&mft->attr);
-  grub_free (mft->buf);
-}
-
-static int
-list_file (struct grub_ntfs_file *diro, char *pos,
-          int NESTED_FUNC_ATTR
-          (*hook) (const char *filename,
-                   enum grub_fshelp_filetype filetype,
-                   grub_fshelp_node_t node))
-{
-  char *np;
-  int ns;
-
-  while (1)
-    {
-      char *ustr, namespace;
-
-      if (pos[0xC] & 2)                /* end signature */
-       break;
-
-      np = pos + 0x50;
-      ns = (unsigned char) *(np++);
-      namespace = *(np++);
-
-      /*
-       *  Ignore files in DOS namespace, as they will reappear as Win32
-       *  names.
-       */
-      if ((ns) && (namespace != 2))
-       {
-         enum grub_fshelp_filetype type;
-         struct grub_ntfs_file *fdiro;
-
-         if (u16at (pos, 4))
-           {
-             grub_error (GRUB_ERR_BAD_FS, "64-bit MFT number");
-             return 0;
-           }
-
-         type =
-           (u32at (pos, 0x48) & ATTR_DIRECTORY) ? GRUB_FSHELP_DIR :
-           GRUB_FSHELP_REG;
-
-         fdiro = grub_zalloc (sizeof (struct grub_ntfs_file));
-         if (!fdiro)
-           return 0;
-
-         fdiro->data = diro->data;
-         fdiro->ino = u32at (pos, 0);
-
-         ustr = grub_malloc (ns * 4 + 1);
-         if (ustr == NULL)
-           return 0;
-         *grub_utf16_to_utf8 ((grub_uint8_t *) ustr, (grub_uint16_t *) np,
-                              ns) = '\0';
-
-          if (namespace)
-            type |= GRUB_FSHELP_CASE_INSENSITIVE;
-
-         if (hook (ustr, type, fdiro))
-           {
-             grub_free (ustr);
-             return 1;
-           }
-
-         grub_free (ustr);
-       }
-      pos += u16at (pos, 8);
-    }
-  return 0;
-}
-
-static int
-grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
-                      int NESTED_FUNC_ATTR
-                      (*hook) (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node))
-{
-  unsigned char *bitmap;
-  struct grub_ntfs_attr attr, *at;
-  char *cur_pos, *indx, *bmp;
-  int ret = 0;
-  grub_size_t bitmap_len;
-  struct grub_ntfs_file *mft;
-
-  mft = (struct grub_ntfs_file *) dir;
-
-  if (!mft->inode_read)
-    {
-      if (init_file (mft, mft->ino))
-       return 0;
-    }
-
-  indx = NULL;
-  bmp = NULL;
-
-  at = &attr;
-  init_attr (at, mft);
-  while (1)
-    {
-      if ((cur_pos = find_attr (at, AT_INDEX_ROOT)) == NULL)
-       {
-         grub_error (GRUB_ERR_BAD_FS, "no $INDEX_ROOT");
-         goto done;
-       }
-
-      /* Resident, Namelen=4, Offset=0x18, Flags=0x00, Name="$I30" */
-      if ((u32at (cur_pos, 8) != 0x180400) ||
-         (u32at (cur_pos, 0x18) != 0x490024) ||
-         (u32at (cur_pos, 0x1C) != 0x300033))
-       continue;
-      cur_pos += u16at (cur_pos, 0x14);
-      if (*cur_pos != 0x30)    /* Not filename index */
-       continue;
-      break;
-    }
-
-  cur_pos += 0x10;             /* Skip index root */
-  ret = list_file (mft, cur_pos + u16at (cur_pos, 0), hook);
-  if (ret)
-    goto done;
-
-  bitmap = NULL;
-  bitmap_len = 0;
-  free_attr (at);
-  init_attr (at, mft);
-  while ((cur_pos = find_attr (at, AT_BITMAP)) != NULL)
-    {
-      int ofs;
-
-      ofs = (unsigned char) cur_pos[0xA];
-      /* Namelen=4, Name="$I30" */
-      if ((cur_pos[9] == 4) &&
-         (u32at (cur_pos, ofs) == 0x490024) &&
-         (u32at (cur_pos, ofs + 4) == 0x300033))
-       {
-          int is_resident = (cur_pos[8] == 0);
-
-          bitmap_len = ((is_resident) ? u32at (cur_pos, 0x10) :
-                        u32at (cur_pos, 0x28));
-
-          bmp = grub_malloc (bitmap_len);
-          if (bmp == NULL)
-            goto done;
-
-         if (is_resident)
-           {
-              grub_memcpy (bmp, (char *) (cur_pos + u16at (cur_pos, 0x14)),
-                           bitmap_len);
-           }
-          else
-            {
-              if (read_data (at, cur_pos, bmp, 0, bitmap_len, 0, 0))
-                {
-                  grub_error (GRUB_ERR_BAD_FS,
-                              "fails to read non-resident $BITMAP");
-                  goto done;
-                }
-              bitmap_len = u32at (cur_pos, 0x30);
-            }
-
-          bitmap = (unsigned char *) bmp;
-         break;
-       }
-    }
-
-  free_attr (at);
-  cur_pos = locate_attr (at, mft, AT_INDEX_ALLOCATION);
-  while (cur_pos != NULL)
-    {
-      /* Non-resident, Namelen=4, Offset=0x40, Flags=0, Name="$I30" */
-      if ((u32at (cur_pos, 8) == 0x400401) &&
-         (u32at (cur_pos, 0x40) == 0x490024) &&
-         (u32at (cur_pos, 0x44) == 0x300033))
-       break;
-      cur_pos = find_attr (at, AT_INDEX_ALLOCATION);
-    }
-
-  if ((!cur_pos) && (bitmap))
-    {
-      grub_error (GRUB_ERR_BAD_FS, "$BITMAP without $INDEX_ALLOCATION");
-      goto done;
-    }
-
-  if (bitmap)
-    {
-      grub_disk_addr_t v, i;
-
-      indx = grub_malloc (mft->data->idx_size << BLK_SHR);
-      if (indx == NULL)
-       goto done;
-
-      v = 1;
-      for (i = 0; i < (grub_disk_addr_t)bitmap_len * 8; i++)
-       {
-         if (*bitmap & v)
-           {
-             if ((read_attr
-                  (at, indx, i * (mft->data->idx_size << BLK_SHR),
-                   (mft->data->idx_size << BLK_SHR), 0, 0))
-                 || (fixup (mft->data, indx, mft->data->idx_size, "INDX")))
-               goto done;
-             ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], hook);
-             if (ret)
-               goto done;
-           }
-         v <<= 1;
-         if (v >= 0x100)
-           {
-             v = 1;
-             bitmap++;
-           }
-       }
-    }
-
-done:
-  free_attr (at);
-  grub_free (indx);
-  grub_free (bmp);
-
-  return ret;
-}
-
-static struct grub_ntfs_data *
-grub_ntfs_mount (grub_disk_t disk)
-{
-  struct grub_ntfs_bpb bpb;
-  struct grub_ntfs_data *data = 0;
-
-  if (!disk)
-    goto fail;
-
-  data = (struct grub_ntfs_data *) grub_zalloc (sizeof (*data));
-  if (!data)
-    goto fail;
-
-  data->disk = disk;
-
-  /* Read the BPB.  */
-  if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb))
-    goto fail;
-
-  if (grub_memcmp ((char *) &bpb.oem_name, "NTFS", 4))
-    goto fail;
-
-  data->blocksize = grub_le_to_cpu16 (bpb.bytes_per_sector);
-  data->spc = bpb.sectors_per_cluster * (data->blocksize >> BLK_SHR);
-
-  if (bpb.clusters_per_mft > 0)
-    data->mft_size = data->spc * bpb.clusters_per_mft;
-  else
-    data->mft_size = 1 << (-bpb.clusters_per_mft - BLK_SHR);
-
-  if (bpb.clusters_per_index > 0)
-    data->idx_size = data->spc * bpb.clusters_per_index;
-  else
-    data->idx_size = 1 << (-bpb.clusters_per_index - BLK_SHR);
-
-  data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) * data->spc;
-
-  if ((data->mft_size > MAX_MFT) || (data->idx_size > MAX_IDX))
-    goto fail;
-
-  data->mmft.data = data;
-  data->cmft.data = data;
-
-  data->mmft.buf = grub_malloc (data->mft_size << BLK_SHR);
-  if (!data->mmft.buf)
-    goto fail;
-
-  if (grub_disk_read
-      (disk, data->mft_start, 0, data->mft_size << BLK_SHR, data->mmft.buf))
-    goto fail;
-
-  data->uuid = grub_le_to_cpu64 (bpb.num_serial);
-
-  if (fixup (data, data->mmft.buf, data->mft_size, "FILE"))
-    goto fail;
-
-  if (!locate_attr (&data->mmft.attr, &data->mmft, AT_DATA))
-    goto fail;
-
-  if (init_file (&data->cmft, FILE_ROOT))
-    goto fail;
-
-  return data;
-
-fail:
-  grub_error (GRUB_ERR_BAD_FS, "not an ntfs filesystem");
-
-  if (data)
-    {
-      free_file (&data->mmft);
-      free_file (&data->cmft);
-      grub_free (data);
-    }
-  return 0;
-}
-
-static grub_err_t
-grub_ntfs_dir (grub_device_t device, const char *path,
-              int (*hook) (const char *filename,
-                           const struct grub_dirhook_info *info))
-{
-  struct grub_ntfs_data *data = 0;
-  struct grub_fshelp_node *fdiro = 0;
-
-  auto int NESTED_FUNC_ATTR iterate (const char *filename,
-                                    enum grub_fshelp_filetype filetype,
-                                    grub_fshelp_node_t node);
-
-  int NESTED_FUNC_ATTR iterate (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node)
-  {
-      struct grub_dirhook_info info;
-      grub_memset (&info, 0, sizeof (info));
-      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
-      grub_free (node);
-      return hook (filename, &info);
-  }
-
-  grub_dl_ref (my_mod);
-
-  data = grub_ntfs_mount (device->disk);
-  if (!data)
-    goto fail;
-
-  grub_fshelp_find_file (path, &data->cmft, &fdiro, grub_ntfs_iterate_dir,
-                        0, GRUB_FSHELP_DIR);
-
-  if (grub_errno)
-    goto fail;
-
-  grub_ntfs_iterate_dir (fdiro, iterate);
-
-fail:
-  if ((fdiro) && (fdiro != &data->cmft))
-    {
-      free_file (fdiro);
-      grub_free (fdiro);
-    }
-  if (data)
-    {
-      free_file (&data->mmft);
-      free_file (&data->cmft);
-      grub_free (data);
-    }
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_ntfs_open (grub_file_t file, const char *name)
-{
-  struct grub_ntfs_data *data = 0;
-  struct grub_fshelp_node *mft = 0;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_ntfs_mount (file->device->disk);
-  if (!data)
-    goto fail;
-
-  grub_fshelp_find_file (name, &data->cmft, &mft, grub_ntfs_iterate_dir,
-                        0, GRUB_FSHELP_REG);
-
-  if (grub_errno)
-    goto fail;
-
-  if (mft != &data->cmft)
-    {
-      free_file (&data->cmft);
-      grub_memcpy (&data->cmft, mft, sizeof (*mft));
-      grub_free (mft);
-      if (!data->cmft.inode_read)
-       {
-         if (init_file (&data->cmft, data->cmft.ino))
-           goto fail;
-       }
-    }
-
-  file->size = data->cmft.size;
-  file->data = data;
-  file->offset = 0;
-
-  return 0;
-
-fail:
-  if (data)
-    {
-      free_file (&data->mmft);
-      free_file (&data->cmft);
-      grub_free (data);
-    }
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_ssize_t
-grub_ntfs_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_ntfs_file *mft;
-
-  mft = &((struct grub_ntfs_data *) file->data)->cmft;
-  if (file->read_hook)
-    mft->attr.save_pos = 1;
-
-  read_attr (&mft->attr, buf, file->offset, len, 1, file->read_hook);
-  return (grub_errno) ? 0 : len;
-}
-
-static grub_err_t
-grub_ntfs_close (grub_file_t file)
-{
-  struct grub_ntfs_data *data;
-
-  data = file->data;
-
-  if (data)
-    {
-      free_file (&data->mmft);
-      free_file (&data->cmft);
-      grub_free (data);
-    }
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_ntfs_label (grub_device_t device, char **label)
-{
-  struct grub_ntfs_data *data = 0;
-  struct grub_fshelp_node *mft = 0;
-  char *pa;
-
-  grub_dl_ref (my_mod);
-
-  *label = 0;
-
-  data = grub_ntfs_mount (device->disk);
-  if (!data)
-    goto fail;
-
-  grub_fshelp_find_file ("/$Volume", &data->cmft, &mft, grub_ntfs_iterate_dir,
-                        0, GRUB_FSHELP_REG);
-
-  if (grub_errno)
-    goto fail;
-
-  if (!mft->inode_read)
-    {
-      mft->buf = grub_malloc (mft->data->mft_size << BLK_SHR);
-      if (mft->buf == NULL)
-       goto fail;
-
-      if (read_mft (mft->data, mft->buf, mft->ino))
-       goto fail;
-    }
-
-  init_attr (&mft->attr, mft);
-  pa = find_attr (&mft->attr, AT_VOLUME_NAME);
-  if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10)))
-    {
-      char *buf;
-      int len;
-
-      len = u32at (pa, 0x10) / 2;
-      buf = grub_malloc (len * 4 + 1);
-      pa += u16at (pa, 0x14);
-      *grub_utf16_to_utf8 ((grub_uint8_t *) buf, (grub_uint16_t *) pa, len) =
-       '\0';
-      *label = buf;
-    }
-
-fail:
-  if ((mft) && (mft != &data->cmft))
-    {
-      free_file (mft);
-      grub_free (mft);
-    }
-  if (data)
-    {
-      free_file (&data->mmft);
-      free_file (&data->cmft);
-      grub_free (data);
-    }
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_ntfs_uuid (grub_device_t device, char **uuid)
-{
-  struct grub_ntfs_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_ntfs_mount (disk);
-  if (data)
-    {
-      *uuid = grub_xasprintf ("%016llx", (unsigned long long) data->uuid);
-    }
-  else
-    *uuid = NULL;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-static struct grub_fs grub_ntfs_fs =
-  {
-    .name = "ntfs",
-    .dir = grub_ntfs_dir,
-    .open = grub_ntfs_open,
-    .read = grub_ntfs_read,
-    .close = grub_ntfs_close,
-    .label = grub_ntfs_label,
-    .uuid = grub_ntfs_uuid,
-#ifdef GRUB_UTIL
-    .reserved_first_sector = 1,
-#endif
-    .next = 0
-};
-
-GRUB_MOD_INIT (ntfs)
-{
-  grub_fs_register (&grub_ntfs_fs);
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI (ntfs)
-{
-  grub_fs_unregister (&grub_ntfs_fs);
-}
diff --git a/fs/ntfscomp.c b/fs/ntfscomp.c
deleted file mode 100644 (file)
index c29979e..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-/* ntfscomp.c - compression support for the NTFS filesystem */
-/*
- *  Copyright (C) 2007 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 3 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/fshelp.h>
-#include <grub/ntfs.h>
-
-static grub_err_t
-decomp_nextvcn (struct grub_ntfs_comp *cc)
-{
-  if (cc->comp_head >= cc->comp_tail)
-    return grub_error (GRUB_ERR_BAD_FS, "compression block overflown");
-  if (grub_disk_read
-      (cc->disk,
-       (cc->comp_table[cc->comp_head][1] -
-       (cc->comp_table[cc->comp_head][0] - cc->cbuf_vcn)) * cc->spc, 0,
-       cc->spc << BLK_SHR, cc->cbuf))
-    return grub_errno;
-  cc->cbuf_vcn++;
-  if ((cc->cbuf_vcn >= cc->comp_table[cc->comp_head][0]))
-    cc->comp_head++;
-  cc->cbuf_ofs = 0;
-  return 0;
-}
-
-static grub_err_t
-decomp_getch (struct grub_ntfs_comp *cc, unsigned char *res)
-{
-  if (cc->cbuf_ofs >= (cc->spc << BLK_SHR))
-    {
-      if (decomp_nextvcn (cc))
-       return grub_errno;
-    }
-  *res = (unsigned char) cc->cbuf[cc->cbuf_ofs++];
-  return 0;
-}
-
-static grub_err_t
-decomp_get16 (struct grub_ntfs_comp *cc, grub_uint16_t * res)
-{
-  unsigned char c1 = 0, c2 = 0;
-
-  if ((decomp_getch (cc, &c1)) || (decomp_getch (cc, &c2)))
-    return grub_errno;
-  *res = ((grub_uint16_t) c2) * 256 + ((grub_uint16_t) c1);
-  return 0;
-}
-
-/* Decompress a block (4096 bytes) */
-static grub_err_t
-decomp_block (struct grub_ntfs_comp *cc, char *dest)
-{
-  grub_uint16_t flg, cnt;
-
-  if (decomp_get16 (cc, &flg))
-    return grub_errno;
-  cnt = (flg & 0xFFF) + 1;
-
-  if (dest)
-    {
-      if (flg & 0x8000)
-       {
-         unsigned char tag;
-         grub_uint32_t bits, copied;
-
-         bits = copied = tag = 0;
-         while (cnt > 0)
-           {
-             if (copied > COM_LEN)
-               return grub_error (GRUB_ERR_BAD_FS,
-                                  "compression block too large");
-
-             if (!bits)
-               {
-                 if (decomp_getch (cc, &tag))
-                   return grub_errno;
-
-                 bits = 8;
-                 cnt--;
-                 if (cnt <= 0)
-                   break;
-               }
-             if (tag & 1)
-               {
-                 grub_uint32_t i, len, delta, code, lmask, dshift;
-                 grub_uint16_t word;
-
-                 if (decomp_get16 (cc, &word))
-                   return grub_errno;
-
-                 code = word;
-                 cnt -= 2;
-
-                 if (!copied)
-                   {
-                     grub_error (GRUB_ERR_BAD_FS, "nontext window empty");
-                     return 0;
-                   }
-
-                 for (i = copied - 1, lmask = 0xFFF, dshift = 12; i >= 0x10;
-                      i >>= 1)
-                   {
-                     lmask >>= 1;
-                     dshift--;
-                   }
-
-                 delta = code >> dshift;
-                 len = (code & lmask) + 3;
-
-                 for (i = 0; i < len; i++)
-                   {
-                     dest[copied] = dest[copied - delta - 1];
-                     copied++;
-                   }
-               }
-             else
-               {
-                 unsigned char ch = 0;
-
-                 if (decomp_getch (cc, &ch))
-                   return grub_errno;
-                 dest[copied++] = ch;
-                 cnt--;
-               }
-             tag >>= 1;
-             bits--;
-           }
-         return 0;
-       }
-      else
-       {
-         if (cnt != COM_LEN)
-           return grub_error (GRUB_ERR_BAD_FS,
-                              "invalid compression block size");
-       }
-    }
-
-  while (cnt > 0)
-    {
-      int n;
-
-      n = (cc->spc << BLK_SHR) - cc->cbuf_ofs;
-      if (n > cnt)
-       n = cnt;
-      if ((dest) && (n))
-       {
-         grub_memcpy (dest, &cc->cbuf[cc->cbuf_ofs], n);
-         dest += n;
-       }
-      cnt -= n;
-      cc->cbuf_ofs += n;
-      if ((cnt) && (decomp_nextvcn (cc)))
-       return grub_errno;
-    }
-  return 0;
-}
-
-static grub_err_t
-read_block (struct grub_ntfs_rlst *ctx, char *buf, int num)
-{
-  int cpb = COM_SEC / ctx->comp.spc;
-
-  while (num)
-    {
-      int nn;
-
-      if ((ctx->target_vcn & 0xF) == 0)
-       {
-
-         if (ctx->comp.comp_head != ctx->comp.comp_tail)
-           return grub_error (GRUB_ERR_BAD_FS, "invalid compression block");
-         ctx->comp.comp_head = ctx->comp.comp_tail = 0;
-         ctx->comp.cbuf_vcn = ctx->target_vcn;
-         ctx->comp.cbuf_ofs = (ctx->comp.spc << BLK_SHR);
-         if (ctx->target_vcn >= ctx->next_vcn)
-           {
-             if (grub_ntfs_read_run_list (ctx))
-               return grub_errno;
-           }
-         while (ctx->target_vcn + 16 > ctx->next_vcn)
-           {
-             if (ctx->flags & RF_BLNK)
-               break;
-             ctx->comp.comp_table[ctx->comp.comp_tail][0] = ctx->next_vcn;
-             ctx->comp.comp_table[ctx->comp.comp_tail][1] =
-               ctx->curr_lcn + ctx->next_vcn - ctx->curr_vcn;
-             ctx->comp.comp_tail++;
-             if (grub_ntfs_read_run_list (ctx))
-               return grub_errno;
-           }
-       }
-
-      nn = (16 - (unsigned) (ctx->target_vcn & 0xF)) / cpb;
-      if (nn > num)
-       nn = num;
-      num -= nn;
-
-      if (ctx->flags & RF_BLNK)
-       {
-         ctx->target_vcn += nn * cpb;
-         if (ctx->comp.comp_tail == 0)
-           {
-             if (buf)
-               {
-                 grub_memset (buf, 0, nn * COM_LEN);
-                 buf += nn * COM_LEN;
-               }
-           }
-         else
-           {
-             while (nn)
-               {
-                 if (decomp_block (&ctx->comp, buf))
-                   return grub_errno;
-                 if (buf)
-                   buf += COM_LEN;
-                 nn--;
-               }
-           }
-       }
-      else
-       {
-         nn *= cpb;
-         while ((ctx->comp.comp_head < ctx->comp.comp_tail) && (nn))
-           {
-             int tt;
-
-             tt =
-               ctx->comp.comp_table[ctx->comp.comp_head][0] -
-               ctx->target_vcn;
-             if (tt > nn)
-               tt = nn;
-             ctx->target_vcn += tt;
-             if (buf)
-               {
-                 if (grub_disk_read
-                     (ctx->comp.disk,
-                      (ctx->comp.comp_table[ctx->comp.comp_head][1] -
-                       (ctx->comp.comp_table[ctx->comp.comp_head][0] -
-                        ctx->target_vcn)) * ctx->comp.spc, 0,
-                      tt * (ctx->comp.spc << BLK_SHR), buf))
-                   return grub_errno;
-                 buf += tt * (ctx->comp.spc << BLK_SHR);
-               }
-             nn -= tt;
-             if (ctx->target_vcn >=
-                 ctx->comp.comp_table[ctx->comp.comp_head][0])
-               ctx->comp.comp_head++;
-           }
-         if (nn)
-           {
-             if (buf)
-               {
-                 if (grub_disk_read
-                     (ctx->comp.disk,
-                      (ctx->target_vcn - ctx->curr_vcn +
-                       ctx->curr_lcn) * ctx->comp.spc, 0,
-                      nn * (ctx->comp.spc << BLK_SHR), buf))
-                   return grub_errno;
-                 buf += nn * (ctx->comp.spc << BLK_SHR);
-               }
-             ctx->target_vcn += nn;
-           }
-       }
-    }
-  return 0;
-}
-
-static grub_err_t
-ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs,
-         grub_uint32_t len, struct grub_ntfs_rlst *ctx, grub_uint32_t vcn)
-{
-  grub_err_t ret;
-
-  ctx->comp.comp_head = ctx->comp.comp_tail = 0;
-  ctx->comp.cbuf = grub_malloc ((ctx->comp.spc) << BLK_SHR);
-  if (!ctx->comp.cbuf)
-    return 0;
-
-  ret = 0;
-
-  //ctx->comp.disk->read_hook = read_hook;
-
-  if ((vcn > ctx->target_vcn) &&
-      (read_block
-       (ctx, NULL, ((vcn - ctx->target_vcn) * ctx->comp.spc) / COM_SEC)))
-    {
-      ret = grub_errno;
-      goto quit;
-    }
-
-  if (ofs % COM_LEN)
-    {
-      grub_uint32_t t, n, o;
-
-      t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR);
-      if (read_block (ctx, at->sbuf, 1))
-       {
-         ret = grub_errno;
-         goto quit;
-       }
-
-      at->save_pos = t;
-
-      o = ofs % COM_LEN;
-      n = COM_LEN - o;
-      if (n > len)
-       n = len;
-      grub_memcpy (dest, &at->sbuf[o], n);
-      if (n == len)
-       goto quit;
-      dest += n;
-      len -= n;
-    }
-
-  if (read_block (ctx, dest, len / COM_LEN))
-    {
-      ret = grub_errno;
-      goto quit;
-    }
-
-  dest += (len / COM_LEN) * COM_LEN;
-  len = len % COM_LEN;
-  if (len)
-    {
-      grub_uint32_t t;
-
-      t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR);
-      if (read_block (ctx, at->sbuf, 1))
-       {
-         ret = grub_errno;
-         goto quit;
-       }
-
-      at->save_pos = t;
-
-      grub_memcpy (dest, at->sbuf, len);
-    }
-
-quit:
-  //ctx->comp.disk->read_hook = 0;
-  if (ctx->comp.cbuf)
-    grub_free (ctx->comp.cbuf);
-  return ret;
-}
-
-GRUB_MOD_INIT (ntfscomp)
-{
-  grub_ntfscomp_func = ntfscomp;
-}
-
-GRUB_MOD_FINI (ntfscomp)
-{
-  grub_ntfscomp_func = NULL;
-}
diff --git a/fs/reiserfs.c b/fs/reiserfs.c
deleted file mode 100644 (file)
index 5acd339..0000000
+++ /dev/null
@@ -1,1381 +0,0 @@
-/* reiserfs.c - ReiserFS versions up to 3.6 */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
-  TODO:
-  implement journal handling (ram replay)
-  test tail packing & direct files
-  validate partition label position
-*/
-
-#if 0
-# define GRUB_REISERFS_DEBUG
-# define GRUB_REISERFS_JOURNALING
-# define GRUB_HEXDUMP
-#endif
-
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/types.h>
-#include <grub/fshelp.h>
-
-#define MIN(a, b) \
-  ({ typeof (a) _a = (a); \
-     typeof (b) _b = (b); \
-     _a < _b ? _a : _b; })
-
-#define MAX(a, b) \
-  ({ typeof (a) _a = (a); \
-     typeof (b) _b = (b); \
-     _a > _b ? _a : _b; })
-
-#define REISERFS_SUPER_BLOCK_OFFSET 0x10000
-#define REISERFS_MAGIC_LEN 12
-#define REISERFS_MAGIC_STRING "ReIsEr"
-#define REISERFS_MAGIC_DESC_BLOCK "ReIsErLB"
-/* If the 3rd bit of an item state is set, then it's visible.  */
-#define GRUB_REISERFS_VISIBLE_MASK ((grub_uint16_t) 0x04)
-#define REISERFS_MAX_LABEL_LENGTH 16
-#define REISERFS_LABEL_OFFSET 0x64
-
-#define S_IFLNK 0xA000
-
-static grub_dl_t my_mod;
-
-#define assert(boolean) real_assert (boolean, GRUB_FILE, __LINE__)
-static inline void
-real_assert (int boolean, const char *file, const int line)
-{
-  if (! boolean)
-    grub_printf ("Assertion failed at %s:%d\n", file, line);
-}
-
-enum grub_reiserfs_item_type
-  {
-    GRUB_REISERFS_STAT,
-    GRUB_REISERFS_DIRECTORY,
-    GRUB_REISERFS_DIRECT,
-    GRUB_REISERFS_INDIRECT,
-    /* Matches both _DIRECT and _INDIRECT when searching.  */
-    GRUB_REISERFS_ANY,
-    GRUB_REISERFS_UNKNOWN
-  };
-
-struct grub_reiserfs_superblock
-{
-  grub_uint32_t block_count;
-  grub_uint32_t block_free_count;
-  grub_uint32_t root_block;
-  grub_uint32_t journal_block;
-  grub_uint32_t journal_device;
-  grub_uint32_t journal_original_size;
-  grub_uint32_t journal_max_transaction_size;
-  grub_uint32_t journal_block_count;
-  grub_uint32_t journal_max_batch;
-  grub_uint32_t journal_max_commit_age;
-  grub_uint32_t journal_max_transaction_age;
-  grub_uint16_t block_size;
-  grub_uint16_t oid_max_size;
-  grub_uint16_t oid_current_size;
-  grub_uint16_t state;
-  grub_uint8_t magic_string[REISERFS_MAGIC_LEN];
-  grub_uint32_t function_hash_code;
-  grub_uint16_t tree_height;
-  grub_uint16_t bitmap_number;
-  grub_uint16_t version;
-  grub_uint16_t reserved;
-  grub_uint32_t inode_generation;
-  grub_uint8_t unused[4];
-  grub_uint16_t uuid[8];
-} __attribute__ ((packed));
-
-struct grub_reiserfs_journal_header
-{
-  grub_uint32_t last_flush_uid;
-  grub_uint32_t unflushed_offset;
-  grub_uint32_t mount_id;
-} __attribute__ ((packed));
-
-struct grub_reiserfs_description_block
-{
-  grub_uint32_t id;
-  grub_uint32_t len;
-  grub_uint32_t mount_id;
-  grub_uint32_t real_blocks[0];
-} __attribute__ ((packed));
-
-struct grub_reiserfs_commit_block
-{
-  grub_uint32_t id;
-  grub_uint32_t len;
-  grub_uint32_t real_blocks[0];
-} __attribute__ ((packed));
-
-struct grub_reiserfs_stat_item_v1
-{
-  grub_uint16_t mode;
-  grub_uint16_t hardlink_count;
-  grub_uint16_t uid;
-  grub_uint16_t gid;
-  grub_uint32_t size;
-  grub_uint32_t atime;
-  grub_uint32_t mtime;
-  grub_uint32_t ctime;
-  grub_uint32_t rdev;
-  grub_uint32_t first_direct_byte;
-} __attribute__ ((packed));
-
-struct grub_reiserfs_stat_item_v2
-{
-  grub_uint16_t mode;
-  grub_uint16_t reserved;
-  grub_uint32_t hardlink_count;
-  grub_uint64_t size;
-  grub_uint32_t uid;
-  grub_uint32_t gid;
-  grub_uint32_t atime;
-  grub_uint32_t mtime;
-  grub_uint32_t ctime;
-  grub_uint32_t blocks;
-  grub_uint32_t first_direct_byte;
-} __attribute__ ((packed));
-
-struct grub_reiserfs_key
-{
-  grub_uint32_t directory_id;
-  grub_uint32_t object_id;
-  union
-  {
-    struct
-    {
-      grub_uint32_t offset;
-      grub_uint32_t type;
-    } v1 __attribute__ ((packed));
-    struct
-    {
-      grub_uint64_t offset_type;
-    } v2 __attribute__ ((packed));
-  } u;
-} __attribute__ ((packed));
-
-struct grub_reiserfs_item_header
-{
-  struct grub_reiserfs_key key;
-  union
-  {
-    grub_uint16_t free_space;
-    grub_uint16_t entry_count;
-  } u __attribute__ ((packed));
-  grub_uint16_t item_size;
-  grub_uint16_t item_location;
-  grub_uint16_t version;
-} __attribute__ ((packed));
-
-struct grub_reiserfs_block_header
-{
-  grub_uint16_t level;
-  grub_uint16_t item_count;
-  grub_uint16_t free_space;
-  grub_uint16_t reserved;
-  struct grub_reiserfs_key block_right_delimiting_key;
-} __attribute__ ((packed));
-
-struct grub_reiserfs_disk_child
-{
-  grub_uint32_t block_number;
-  grub_uint16_t size;
-  grub_uint16_t reserved;
-} __attribute__ ((packed));
-
-struct grub_reiserfs_directory_header
-{
-  grub_uint32_t offset;
-  grub_uint32_t directory_id;
-  grub_uint32_t object_id;
-  grub_uint16_t location;
-  grub_uint16_t state;
-} __attribute__ ((packed));
-
-struct grub_fshelp_node
-{
-  struct grub_reiserfs_data *data;
-  grub_uint32_t block_number; /* 0 if node is not found.  */
-  grub_uint16_t block_position;
-  grub_uint64_t next_offset;
-  enum grub_reiserfs_item_type type; /* To know how to read the header.  */
-  struct grub_reiserfs_item_header header;
-};
-
-/* Returned when opening a file.  */
-struct grub_reiserfs_data
-{
-  struct grub_reiserfs_superblock superblock;
-  grub_disk_t disk;
-};
-
-/* Internal-only functions. Not to be used outside of this file.  */
-
-/* Return the type of given v2 key.  */
-static enum grub_reiserfs_item_type
-grub_reiserfs_get_key_v2_type (const struct grub_reiserfs_key *key)
-{
-  switch (grub_le_to_cpu64 (key->u.v2.offset_type) >> 60)
-    {
-    case 0:
-      return GRUB_REISERFS_STAT;
-    case 15:
-      return GRUB_REISERFS_ANY;
-    case 3:
-      return GRUB_REISERFS_DIRECTORY;
-    case 2:
-      return GRUB_REISERFS_DIRECT;
-    case 1:
-      return GRUB_REISERFS_INDIRECT;
-    }
-  return GRUB_REISERFS_UNKNOWN;
-}
-
-/* Return the type of given v1 key.  */
-static enum grub_reiserfs_item_type
-grub_reiserfs_get_key_v1_type (const struct grub_reiserfs_key *key)
-{
-  switch (grub_le_to_cpu32 (key->u.v1.type))
-    {
-    case 0:
-      return GRUB_REISERFS_STAT;
-    case 555:
-      return GRUB_REISERFS_ANY;
-    case 500:
-      return GRUB_REISERFS_DIRECTORY;
-    case 0x20000000:
-    case 0xFFFFFFFF:
-      return GRUB_REISERFS_DIRECT;
-    case 0x10000000:
-    case 0xFFFFFFFE:
-      return GRUB_REISERFS_INDIRECT;
-    }
-  return GRUB_REISERFS_UNKNOWN;
-}
-
-/* Return 1 if the given key is version 1 key, 2 otherwise.  */
-static int
-grub_reiserfs_get_key_version (const struct grub_reiserfs_key *key)
-{
-  return grub_reiserfs_get_key_v1_type (key) == GRUB_REISERFS_UNKNOWN ? 2 : 1;
-}
-
-#ifdef GRUB_HEXDUMP
-static void
-grub_hexdump (char *buffer, grub_size_t len)
-{
-  grub_size_t a;
-  for (a = 0; a < len; a++)
-    {
-      if (! (a & 0x0F))
-        grub_printf ("\n%08x  ", a);
-      grub_printf ("%02x ",
-                   ((unsigned int) ((unsigned char *) buffer)[a]) & 0xFF);
-    }
-  grub_printf ("\n");
-}
-#endif
-
-#ifdef GRUB_REISERFS_DEBUG
-static grub_uint64_t
-grub_reiserfs_get_key_offset (const struct grub_reiserfs_key *key);
-
-static enum grub_reiserfs_item_type
-grub_reiserfs_get_key_type (const struct grub_reiserfs_key *key);
-
-static void
-grub_reiserfs_print_key (const struct grub_reiserfs_key *key)
-{
-  unsigned int a;
-  char *reiserfs_type_strings[] = {
-    "stat     ",
-    "directory",
-    "direct   ",
-    "indirect ",
-    "any      ",
-    "unknown  "
-  };
-
-  for (a = 0; a < sizeof (struct grub_reiserfs_key); a++)
-    grub_printf ("%02x ", ((unsigned int) ((unsigned char *) key)[a]) & 0xFF);
-  grub_printf ("parent id = 0x%08x, self id = 0x%08x, type = %s, offset = ",
-               grub_le_to_cpu32 (key->directory_id),
-               grub_le_to_cpu32 (key->object_id),
-               reiserfs_type_strings [grub_reiserfs_get_key_type (key)]);
-  if (grub_reiserfs_get_key_version (key) == 1)
-    grub_printf("%08x", (unsigned int) grub_reiserfs_get_key_offset (key));
-  else
-    grub_printf("0x%07x%08x",
-                (unsigned) (grub_reiserfs_get_key_offset (key) >> 32),
-                (unsigned) (grub_reiserfs_get_key_offset (key) & 0xFFFFFFFF));
-  grub_printf ("\n");
-}
-#endif
-
-/* Return the offset of given key.  */
-static grub_uint64_t
-grub_reiserfs_get_key_offset (const struct grub_reiserfs_key *key)
-{
-  if (grub_reiserfs_get_key_version (key) == 1)
-    return grub_le_to_cpu32 (key->u.v1.offset);
-  else
-    return grub_le_to_cpu64 (key->u.v2.offset_type) & (~0ULL >> 4);
-}
-
-/* Set the offset of given key.  */
-static void
-grub_reiserfs_set_key_offset (struct grub_reiserfs_key *key,
-                              grub_uint64_t value)
-{
-  if (grub_reiserfs_get_key_version (key) == 1)
-    key->u.v1.offset = grub_cpu_to_le32 (value);
-  else
-    key->u.v2.offset_type \
-      = ((key->u.v2.offset_type & grub_cpu_to_le64 (15ULL << 60))
-         | grub_cpu_to_le64 (value & (~0ULL >> 4)));
-}
-
-/* Return the type of given key.  */
-static enum grub_reiserfs_item_type
-grub_reiserfs_get_key_type (const struct grub_reiserfs_key *key)
-{
-  if (grub_reiserfs_get_key_version (key) == 1)
-    return grub_reiserfs_get_key_v1_type (key);
-  else
-    return grub_reiserfs_get_key_v2_type (key);
-}
-
-/* Set the type of given key, with given version number.  */
-static void
-grub_reiserfs_set_key_type (struct grub_reiserfs_key *key,
-                            enum grub_reiserfs_item_type grub_type,
-                            int version)
-{
-  grub_uint32_t type;
-
-  switch (grub_type)
-    {
-    case GRUB_REISERFS_STAT:
-      type = 0;
-      break;
-    case GRUB_REISERFS_ANY:
-      type = (version == 1) ? 555 : 15;
-      break;
-    case GRUB_REISERFS_DIRECTORY:
-      type = (version == 1) ? 500 : 3;
-      break;
-    case GRUB_REISERFS_DIRECT:
-      type = (version == 1) ? 0xFFFFFFFF : 2;
-      break;
-    case GRUB_REISERFS_INDIRECT:
-      type = (version == 1) ? 0xFFFFFFFE : 1;
-      break;
-    default:
-      return;
-    }
-
-  if (version == 1)
-    key->u.v1.type = grub_cpu_to_le32 (type);
-  else
-    key->u.v2.offset_type
-      = ((key->u.v2.offset_type & grub_cpu_to_le64 (~0ULL >> 4))
-         | grub_cpu_to_le64 ((grub_uint64_t) type << 60));
-
-  assert (grub_reiserfs_get_key_type (key) == grub_type);
-}
-
-/* -1 if key 1 if lower than key 2.
-   0 if key 1 is equal to key 2.
-   1 if key 1 is higher than key 2.  */
-static int
-grub_reiserfs_compare_keys (const struct grub_reiserfs_key *key1,
-                            const struct grub_reiserfs_key *key2)
-{
-  grub_uint64_t offset1, offset2;
-  enum grub_reiserfs_item_type type1, type2;
-  grub_uint32_t id1, id2;
-
-  if (! key1 || ! key2)
-    return -2;
-
-  id1 = grub_le_to_cpu32 (key1->directory_id);
-  id2 = grub_le_to_cpu32 (key2->directory_id);
-  if (id1 < id2)
-    return -1;
-  if (id1 > id2)
-    return 1;
-
-  id1 = grub_le_to_cpu32 (key1->object_id);
-  id2 = grub_le_to_cpu32 (key2->object_id);
-  if (id1 < id2)
-    return -1;
-  if (id1 > id2)
-    return 1;
-
-  offset1 = grub_reiserfs_get_key_offset (key1);
-  offset2 = grub_reiserfs_get_key_offset (key2);
-  if (offset1 < offset2)
-    return -1;
-  if (offset1 > offset2)
-    return 1;
-
-  type1 = grub_reiserfs_get_key_type (key1);
-  type2 = grub_reiserfs_get_key_type (key2);
-  if ((type1 == GRUB_REISERFS_ANY
-       && (type2 == GRUB_REISERFS_DIRECT
-           || type2 == GRUB_REISERFS_INDIRECT))
-      || (type2 == GRUB_REISERFS_ANY
-          && (type1 == GRUB_REISERFS_DIRECT
-              || type1 == GRUB_REISERFS_INDIRECT)))
-    return 0;
-  if (type1 < type2)
-    return -1;
-  if (type1 > type2)
-    return 1;
-
-  return 0;
-}
-
-/* Find the item identified by KEY in mounted filesystem DATA, and fill ITEM
-   accordingly to what was found.  */
-static grub_err_t
-grub_reiserfs_get_item (struct grub_reiserfs_data *data,
-                        const struct grub_reiserfs_key *key,
-                        struct grub_fshelp_node *item)
-{
-  grub_uint32_t block_number;
-  struct grub_reiserfs_block_header *block_header = 0;
-  struct grub_reiserfs_key *block_key = 0;
-  grub_uint16_t block_size, item_count, current_level;
-  grub_uint16_t i;
-  grub_uint16_t previous_level = ~0;
-  struct grub_reiserfs_item_header *item_headers = 0;
-
-  if (! data)
-    {
-      grub_error (GRUB_ERR_TEST_FAILURE, "data is NULL");
-      goto fail;
-    }
-
-  if (! key)
-    {
-      grub_error (GRUB_ERR_TEST_FAILURE, "key is NULL");
-      goto fail;
-    }
-
-  if (! item)
-    {
-      grub_error (GRUB_ERR_TEST_FAILURE, "item is NULL");
-      goto fail;
-    }
-
-  block_size = grub_le_to_cpu16 (data->superblock.block_size);
-  block_number = grub_le_to_cpu32 (data->superblock.root_block);
-#ifdef GRUB_REISERFS_DEBUG
-  grub_printf("Searching for ");
-  grub_reiserfs_print_key (key);
-#endif
-  block_header = grub_malloc (block_size);
-  if (! block_header)
-    goto fail;
-
-  item->next_offset = 0;
-  do
-    {
-      grub_disk_read (data->disk,
-                      block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
-                      (((grub_off_t) block_number * block_size)
-                       & (GRUB_DISK_SECTOR_SIZE - 1)),
-                      block_size, block_header);
-      if (grub_errno)
-        goto fail;
-      current_level = grub_le_to_cpu16 (block_header->level);
-      grub_dprintf ("reiserfs_tree", " at level %d\n", current_level);
-      if (current_level >= previous_level)
-        {
-          grub_dprintf ("reiserfs_tree", "level loop detected, aborting\n");
-          grub_error (GRUB_ERR_FILE_READ_ERROR, "level loop");
-          goto fail;
-        }
-      previous_level = current_level;
-      item_count = grub_le_to_cpu16 (block_header->item_count);
-      grub_dprintf ("reiserfs_tree", " number of contained items : %d\n",
-                    item_count);
-      if (current_level > 1)
-        {
-          /* Internal node. Navigate to the child that should contain
-             the searched key.  */
-          struct grub_reiserfs_key *keys
-            = (struct grub_reiserfs_key *) (block_header + 1);
-          struct grub_reiserfs_disk_child *children
-            = ((struct grub_reiserfs_disk_child *)
-               (keys + item_count));
-
-          for (i = 0;
-               i < item_count
-                 && grub_reiserfs_compare_keys (key, &(keys[i])) >= 0;
-               i++)
-            {
-#ifdef GRUB_REISERFS_DEBUG
-              grub_printf("i %03d/%03d ", i + 1, item_count + 1);
-              grub_reiserfs_print_key (&(keys[i]));
-#endif
-            }
-          block_number = grub_le_to_cpu32 (children[i].block_number);
-         if ((i < item_count) && (key->directory_id == keys[i].directory_id)
-              && (key->object_id == keys[i].object_id))
-           item->next_offset = grub_reiserfs_get_key_offset(&(keys[i]));
-#ifdef GRUB_REISERFS_DEBUG
-          if (i == item_count
-              || grub_reiserfs_compare_keys (key, &(keys[i])) == 0)
-            grub_printf(">");
-          else
-            grub_printf("<");
-          if (i < item_count)
-            {
-              grub_printf (" %03d/%03d ", i + 1, item_count + 1);
-              grub_reiserfs_print_key (&(keys[i]));
-              if (i + 1 < item_count)
-                {
-                  grub_printf ("+ %03d/%03d ", i + 2, item_count);
-                  grub_reiserfs_print_key (&(keys[i + 1]));
-                }
-            }
-          else
-            grub_printf ("Accessing rightmost child at block %d.\n",
-                         block_number);
-#endif
-        }
-      else
-        {
-          /* Leaf node.  Check that the key is actually present.  */
-          item_headers
-            = (struct grub_reiserfs_item_header *) (block_header + 1);
-          for (i = 0;
-               i < item_count
-                 && (grub_reiserfs_compare_keys (key, &(item_headers[i].key))
-                     != 0);
-               i++)
-            {
-#ifdef GRUB_REISERFS_DEBUG
-              if (key->directory_id == item_headers[i].key.directory_id && \
-                  key->object_id == item_headers[i].key.object_id)
-                grub_printf("C");
-              else
-                grub_printf(" ");
-              grub_printf(" %03d/%03d ", i + 1, item_count);
-              grub_reiserfs_print_key (&(item_headers[i].key));
-#endif
-            }
-          if (i < item_count)
-            block_key = &(item_headers[i].key);
-        }
-    }
-  while (current_level > 1);
-
-  item->data = data;
-
-  if (i == item_count || grub_reiserfs_compare_keys (key, block_key))
-    {
-      item->block_number = 0;
-      item->block_position = 0;
-      item->type = GRUB_REISERFS_UNKNOWN;
-#ifdef GRUB_REISERFS_DEBUG
-      grub_printf("Not found.\n");
-#endif
-    }
-  else
-    {
-      item->block_number = block_number;
-      item->block_position = i;
-      item->type = grub_reiserfs_get_key_type (block_key);
-      grub_memcpy (&(item->header), &(item_headers[i]),
-                   sizeof (struct grub_reiserfs_item_header));
-#ifdef GRUB_REISERFS_DEBUG
-      grub_printf ("F %03d/%03d ", i + 1, item_count);
-      grub_reiserfs_print_key (block_key);
-#endif
-    }
-
-  assert (grub_errno == GRUB_ERR_NONE);
-  grub_free (block_header);
-  return GRUB_ERR_NONE;
-
- fail:
-  assert (grub_errno != GRUB_ERR_NONE);
-  grub_free (block_header);
-  assert (grub_errno != GRUB_ERR_NONE);
-  return grub_errno;
-}
-
-/* Return the path of the file which is pointed at by symlink NODE.  */
-static char *
-grub_reiserfs_read_symlink (grub_fshelp_node_t node)
-{
-  char *symlink_buffer = 0;
-  grub_uint16_t block_size;
-  grub_disk_addr_t block;
-  grub_off_t offset;
-  grub_size_t len;
-  struct grub_fshelp_node found;
-  struct grub_reiserfs_key key;
-
-  grub_memcpy (&key, &(node->header.key), sizeof (key));
-  grub_reiserfs_set_key_offset (&key, 1);
-  grub_reiserfs_set_key_type (&key, GRUB_REISERFS_DIRECT,
-                              grub_reiserfs_get_key_version (&key));
-
-  if (grub_reiserfs_get_item (node->data, &key, &found) != GRUB_ERR_NONE)
-    goto fail;
-
-  if (found.block_number == 0)
-    goto fail;
-
-  block_size = grub_le_to_cpu16 (node->data->superblock.block_size);
-  len = grub_le_to_cpu16 (found.header.item_size);
-  block = found.block_number * (block_size  >> GRUB_DISK_SECTOR_BITS);
-  offset = grub_le_to_cpu16 (found.header.item_location);
-
-  symlink_buffer = grub_malloc (len + 1);
-  if (! symlink_buffer)
-    goto fail;
-
-  grub_disk_read (node->data->disk, block, offset, len, symlink_buffer);
-  if (grub_errno)
-    goto fail;
-
-  symlink_buffer[len] = 0;
-  return symlink_buffer;
-
- fail:
-  grub_free (symlink_buffer);
-  return 0;
-}
-
-/* Fill the mounted filesystem structure and return it.  */
-static struct grub_reiserfs_data *
-grub_reiserfs_mount (grub_disk_t disk)
-{
-  struct grub_reiserfs_data *data = 0;
-  data = grub_malloc (sizeof (*data));
-  if (! data)
-    goto fail;
-  grub_disk_read (disk, REISERFS_SUPER_BLOCK_OFFSET / GRUB_DISK_SECTOR_SIZE,
-                  0, sizeof (data->superblock), &(data->superblock));
-  if (grub_errno)
-    goto fail;
-  if (grub_memcmp (data->superblock.magic_string,
-                   REISERFS_MAGIC_STRING, sizeof (REISERFS_MAGIC_STRING) - 1))
-    {
-      grub_error (GRUB_ERR_BAD_FS, "not a ReiserFS filesystem");
-      goto fail;
-    }
-  data->disk = disk;
-  return data;
-
- fail:
-  /* Disk is too small to contain a ReiserFS.  */
-  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
-    grub_error (GRUB_ERR_BAD_FS, "not a ReiserFS filesystem");
-
-  grub_free (data);
-  return 0;
-}
-
-/* Call HOOK for each file in directory ITEM.  */
-static int
-grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
-                           int NESTED_FUNC_ATTR
-                           (*hook) (const char *filename,
-                                    enum grub_fshelp_filetype filetype,
-                                    grub_fshelp_node_t node))
-{
-  struct grub_reiserfs_data *data = item->data;
-  struct grub_reiserfs_block_header *block_header = 0;
-  grub_uint16_t block_size, block_position;
-  grub_uint32_t block_number;
-  grub_uint64_t next_offset = item->next_offset;
-  int ret = 0;
-
-  if (item->type != GRUB_REISERFS_DIRECTORY)
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                  "grub_reiserfs_iterate_dir called on a non-directory item");
-      goto fail;
-    }
-  block_size = grub_le_to_cpu16 (data->superblock.block_size);
-  block_header = grub_malloc (block_size);
-  if (! block_header)
-    goto fail;
-  block_number = item->block_number;
-  block_position = item->block_position;
-  grub_dprintf ("reiserfs", "Iterating directory...\n");
-  do
-    {
-      struct grub_reiserfs_directory_header *directory_headers;
-      struct grub_fshelp_node directory_item;
-      grub_uint16_t entry_count, entry_number;
-      struct grub_reiserfs_item_header *item_headers;
-
-      grub_disk_read (data->disk,
-                      block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
-                      (((grub_off_t) block_number * block_size)
-                       & (GRUB_DISK_SECTOR_SIZE - 1)),
-                      block_size, (char *) block_header);
-      if (grub_errno)
-        goto fail;
-
-#if 0
-      if (grub_le_to_cpu16 (block_header->level) != 1)
-        {
-          grub_error (GRUB_ERR_TEST_FAILURE,
-                      "reiserfs: block %d is not a leaf block",
-                      block_number);
-          goto fail;
-        }
-#endif
-
-      item_headers = (struct grub_reiserfs_item_header *) (block_header + 1);
-      directory_headers
-        = ((struct grub_reiserfs_directory_header *)
-           ((char *) block_header
-            + grub_le_to_cpu16 (item_headers[block_position].item_location)));
-      entry_count
-        = grub_le_to_cpu16 (item_headers[block_position].u.entry_count);
-      for (entry_number = 0; entry_number < entry_count; entry_number++)
-        {
-          struct grub_reiserfs_directory_header *directory_header
-            = &directory_headers[entry_number];
-          grub_uint16_t entry_state
-            = grub_le_to_cpu16 (directory_header->state);
-
-          if (entry_state & GRUB_REISERFS_VISIBLE_MASK)
-            {
-              grub_fshelp_node_t entry_item;
-              struct grub_reiserfs_key entry_key;
-              enum grub_reiserfs_item_type entry_type;
-              char *entry_name;
-
-              entry_name = (((char *) directory_headers)
-                            + grub_le_to_cpu16 (directory_header->location));
-              entry_key.directory_id = directory_header->directory_id;
-              entry_key.object_id = directory_header->object_id;
-              entry_key.u.v2.offset_type = 0;
-              grub_reiserfs_set_key_type (&entry_key, GRUB_REISERFS_DIRECTORY,
-                                          2);
-              grub_reiserfs_set_key_offset (&entry_key, 1);
-
-              entry_item = grub_malloc (sizeof (*entry_item));
-              if (! entry_item)
-                goto fail;
-
-              if (grub_reiserfs_get_item (data, &entry_key, entry_item)
-                  != GRUB_ERR_NONE)
-                {
-                  grub_free (entry_item);
-                  goto fail;
-                }
-
-              if (entry_item->type == GRUB_REISERFS_DIRECTORY)
-                entry_type = GRUB_FSHELP_DIR;
-              else
-                {
-                  grub_uint32_t entry_block_number;
-                  /* Order is very important here.
-                     First set the offset to 0 using current key version.
-                     Then change the key type, which affects key version
-                     detection.  */
-                  grub_reiserfs_set_key_offset (&entry_key, 0);
-                  grub_reiserfs_set_key_type (&entry_key, GRUB_REISERFS_STAT,
-                                              2);
-                  if (grub_reiserfs_get_item (data, &entry_key, entry_item)
-                      != GRUB_ERR_NONE)
-                    {
-                      grub_free (entry_item);
-                      goto fail;
-                    }
-
-                  if (entry_item->block_number != 0)
-                    {
-                      grub_uint16_t entry_version;
-                      entry_version
-                        = grub_le_to_cpu16 (entry_item->header.version);
-                      entry_block_number = entry_item->block_number;
-#if 0
-                     grub_dprintf ("reiserfs",
-                                    "version %04x block %08x (%08x) position %08x\n",
-                                    entry_version, entry_block_number,
-                                    ((grub_disk_addr_t) entry_block_number * block_size) / GRUB_DISK_SECTOR_SIZE,
-                                    grub_le_to_cpu16 (entry_item->header.item_location));
-#endif
-                      if (entry_version == 0) /* Version 1 stat item. */
-                        {
-                          struct grub_reiserfs_stat_item_v1 entry_v1_stat;
-                          grub_disk_read (data->disk,
-                                          entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
-                                          grub_le_to_cpu16 (entry_item->header.item_location),
-                                          sizeof (entry_v1_stat),
-                                          (char *) &entry_v1_stat);
-                          if (grub_errno)
-                            goto fail;
-#if 0
-                         grub_dprintf ("reiserfs",
-                                        "%04x %04x %04x %04x %08x %08x | %08x %08x %08x %08x\n",
-                                        grub_le_to_cpu16 (entry_v1_stat.mode),
-                                        grub_le_to_cpu16 (entry_v1_stat.hardlink_count),
-                                        grub_le_to_cpu16 (entry_v1_stat.uid),
-                                        grub_le_to_cpu16 (entry_v1_stat.gid),
-                                        grub_le_to_cpu32 (entry_v1_stat.size),
-                                        grub_le_to_cpu32 (entry_v1_stat.atime),
-                                        grub_le_to_cpu32 (entry_v1_stat.mtime),
-                                        grub_le_to_cpu32 (entry_v1_stat.ctime),
-                                        grub_le_to_cpu32 (entry_v1_stat.rdev),
-                                        grub_le_to_cpu32 (entry_v1_stat.first_direct_byte));
-                         grub_dprintf ("reiserfs",
-                                        "%04x %04x %04x %04x %08x %08x | %08x %08x %08x %08x\n",
-                                        entry_v1_stat.mode,
-                                        entry_v1_stat.hardlink_count,
-                                        entry_v1_stat.uid,
-                                        entry_v1_stat.gid,
-                                        entry_v1_stat.size,
-                                        entry_v1_stat.atime,
-                                        entry_v1_stat.mtime,
-                                        entry_v1_stat.ctime,
-                                        entry_v1_stat.rdev,
-                                        entry_v1_stat.first_direct_byte);
-#endif
-                          if ((grub_le_to_cpu16 (entry_v1_stat.mode) & S_IFLNK)
-                              == S_IFLNK)
-                            entry_type = GRUB_FSHELP_SYMLINK;
-                          else
-                            entry_type = GRUB_FSHELP_REG;
-                        }
-                      else
-                        {
-                          struct grub_reiserfs_stat_item_v2 entry_v2_stat;
-                          grub_disk_read (data->disk,
-                                          entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
-                                          grub_le_to_cpu16 (entry_item->header.item_location),
-                                          sizeof (entry_v2_stat),
-                                          (char *) &entry_v2_stat);
-                          if (grub_errno)
-                            goto fail;
-#if 0
-                         grub_dprintf ("reiserfs",
-                                        "%04x %04x %08x %08x%08x | %08x %08x %08x %08x | %08x %08x %08x\n",
-                                        grub_le_to_cpu16 (entry_v2_stat.mode),
-                                        grub_le_to_cpu16 (entry_v2_stat.reserved),
-                                        grub_le_to_cpu32 (entry_v2_stat.hardlink_count),
-                                        (unsigned int) (grub_le_to_cpu64 (entry_v2_stat.size) >> 32),
-                                        (unsigned int) (grub_le_to_cpu64 (entry_v2_stat.size) && 0xFFFFFFFF),
-                                        grub_le_to_cpu32 (entry_v2_stat.uid),
-                                        grub_le_to_cpu32 (entry_v2_stat.gid),
-                                        grub_le_to_cpu32 (entry_v2_stat.atime),
-                                        grub_le_to_cpu32 (entry_v2_stat.mtime),
-                                        grub_le_to_cpu32 (entry_v2_stat.ctime),
-                                        grub_le_to_cpu32 (entry_v2_stat.blocks),
-                                        grub_le_to_cpu32 (entry_v2_stat.first_direct_byte));
-                         grub_dprintf ("reiserfs",
-                                        "%04x %04x %08x %08x%08x | %08x %08x %08x %08x | %08x %08x %08x\n",
-                                        entry_v2_stat.mode,
-                                        entry_v2_stat.reserved,
-                                        entry_v2_stat.hardlink_count,
-                                        (unsigned int) (entry_v2_stat.size >> 32),
-                                        (unsigned int) (entry_v2_stat.size && 0xFFFFFFFF),
-                                        entry_v2_stat.uid,
-                                        entry_v2_stat.gid,
-                                        entry_v2_stat.atime,
-                                        entry_v2_stat.mtime,
-                                        entry_v2_stat.ctime,
-                                        entry_v2_stat.blocks,
-                                        entry_v2_stat.first_direct_byte);
-#endif
-                          if ((grub_le_to_cpu16 (entry_v2_stat.mode) & S_IFLNK)
-                              == S_IFLNK)
-                            entry_type = GRUB_FSHELP_SYMLINK;
-                          else
-                            entry_type = GRUB_FSHELP_REG;
-                        }
-                    }
-                  else
-                    {
-                      /* Pseudo file ".." never has stat block.  */
-                      if (grub_strcmp (entry_name, ".."))
-                        grub_dprintf ("reiserfs",
-                                      "Warning : %s has no stat block !\n",
-                                      entry_name);
-                      grub_free (entry_item);
-                      continue;
-                    }
-                }
-              if (hook (entry_name, entry_type, entry_item))
-                {
-                  grub_dprintf ("reiserfs", "Found : %s, type=%d\n",
-                                entry_name, entry_type);
-                  ret = 1;
-                  goto found;
-                }
-
-              *entry_name = 0; /* Make sure next entry name (which is just
-                                  before this one in disk order) stops before
-                                  the current one.  */
-            }
-        }
-
-      if (next_offset == 0)
-        break;
-
-      grub_reiserfs_set_key_offset (&(item_headers[block_position].key),
-                                    next_offset);
-      if (grub_reiserfs_get_item (data, &(item_headers[block_position].key),
-                                  &directory_item) != GRUB_ERR_NONE)
-        goto fail;
-      block_number = directory_item.block_number;
-      block_position = directory_item.block_position;
-      next_offset = directory_item.next_offset;
-    }
-  while (block_number);
-
- found:
-  assert (grub_errno == GRUB_ERR_NONE);
-  grub_free (block_header);
-  return ret;
- fail:
-  assert (grub_errno != GRUB_ERR_NONE);
-  grub_free (block_header);
-  return 0;
-}
-
-/****************************************************************************/
-/* grub api functions */
-/****************************************************************************/
-
-/* Open a file named NAME and initialize FILE.  */
-static grub_err_t
-grub_reiserfs_open (struct grub_file *file, const char *name)
-{
-  struct grub_reiserfs_data *data = 0;
-  struct grub_fshelp_node root, *found = 0, info;
-  struct grub_reiserfs_key key;
-  grub_uint32_t block_number;
-  grub_uint16_t entry_version, block_size, entry_location;
-
-  grub_dl_ref (my_mod);
-  data = grub_reiserfs_mount (file->device->disk);
-  if (! data)
-    goto fail;
-  block_size = grub_le_to_cpu16 (data->superblock.block_size);
-  key.directory_id = grub_cpu_to_le32 (1);
-  key.object_id = grub_cpu_to_le32 (2);
-  key.u.v2.offset_type = 0;
-  grub_reiserfs_set_key_type (&key, GRUB_REISERFS_DIRECTORY, 2);
-  grub_reiserfs_set_key_offset (&key, 1);
-  if (grub_reiserfs_get_item (data, &key, &root) != GRUB_ERR_NONE)
-    goto fail;
-  if (root.block_number == 0)
-    {
-      grub_error (GRUB_ERR_BAD_FS, "unable to find root item");
-      goto fail; /* Should never happen since checked at mount.  */
-    }
-  grub_fshelp_find_file (name, &root, &found,
-                         grub_reiserfs_iterate_dir,
-                         grub_reiserfs_read_symlink, GRUB_FSHELP_REG);
-  if (grub_errno)
-    goto fail;
-  key.directory_id = found->header.key.directory_id;
-  key.object_id = found->header.key.object_id;
-  grub_reiserfs_set_key_type (&key, GRUB_REISERFS_STAT, 2);
-  grub_reiserfs_set_key_offset (&key, 0);
-  if (grub_reiserfs_get_item (data, &key, &info) != GRUB_ERR_NONE)
-    goto fail;
-  if (info.block_number == 0)
-    {
-      grub_error (GRUB_ERR_BAD_FS, "unable to find searched item");
-      goto fail;
-    }
-  entry_version = grub_le_to_cpu16 (info.header.version);
-  entry_location = grub_le_to_cpu16 (info.header.item_location);
-  block_number = info.block_number;
-  if (entry_version == 0) /* Version 1 stat item. */
-    {
-      struct grub_reiserfs_stat_item_v1 entry_v1_stat;
-      grub_disk_read (data->disk,
-                      block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
-                      entry_location
-                      + (((grub_off_t) block_number * block_size)
-                         & (GRUB_DISK_SECTOR_SIZE - 1)),
-                      sizeof (entry_v1_stat), &entry_v1_stat);
-      if (grub_errno)
-        goto fail;
-      file->size = (grub_off_t) grub_le_to_cpu64 (entry_v1_stat.size);
-    }
-  else
-    {
-      struct grub_reiserfs_stat_item_v2 entry_v2_stat;
-      grub_disk_read (data->disk,
-                      block_number * (block_size  >> GRUB_DISK_SECTOR_BITS),
-                      entry_location
-                      + (((grub_off_t) block_number * block_size)
-                         & (GRUB_DISK_SECTOR_SIZE - 1)),
-                      sizeof (entry_v2_stat), &entry_v2_stat);
-      if (grub_errno)
-        goto fail;
-      file->size = (grub_off_t) grub_le_to_cpu64 (entry_v2_stat.size);
-    }
-  grub_dprintf ("reiserfs", "file size : %d (%08x%08x)\n",
-                (unsigned int) file->size,
-                (unsigned int) (file->size >> 32), (unsigned int) file->size);
-  file->offset = 0;
-  file->data = found;
-  return GRUB_ERR_NONE;
-
- fail:
-  assert (grub_errno != GRUB_ERR_NONE);
-  grub_free (found);
-  grub_free (data);
-  grub_dl_unref (my_mod);
-  return grub_errno;
-}
-
-static grub_ssize_t
-grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  unsigned int indirect_block, indirect_block_count;
-  struct grub_reiserfs_key key;
-  struct grub_fshelp_node *node = file->data;
-  struct grub_reiserfs_data *data = node->data;
-  struct grub_fshelp_node found;
-  grub_uint16_t block_size = grub_le_to_cpu16 (data->superblock.block_size);
-  grub_uint16_t item_size;
-  grub_uint32_t *indirect_block_ptr = 0;
-  grub_uint64_t current_key_offset = 1;
-  grub_off_t initial_position, current_position, final_position, length;
-  grub_disk_addr_t block;
-  grub_off_t offset;
-
-  key.directory_id = node->header.key.directory_id;
-  key.object_id = node->header.key.object_id;
-  key.u.v2.offset_type = 0;
-  grub_reiserfs_set_key_type (&key, GRUB_REISERFS_ANY, 2);
-  initial_position = file->offset;
-  current_position = 0;
-  final_position = MIN (len + initial_position, file->size);
-  grub_dprintf ("reiserfs",
-               "Reading from %lld to %lld (%lld instead of requested %ld)\n",
-               (unsigned long long) initial_position,
-               (unsigned long long) final_position,
-               (unsigned long long) (final_position - initial_position),
-               (unsigned long) len);
-  while (current_position < final_position)
-    {
-      grub_reiserfs_set_key_offset (&key, current_key_offset);
-
-      if (grub_reiserfs_get_item (data, &key, &found) != GRUB_ERR_NONE)
-        goto fail;
-      if (found.block_number == 0)
-        goto fail;
-      item_size = grub_le_to_cpu16 (found.header.item_size);
-      switch (found.type)
-        {
-        case GRUB_REISERFS_DIRECT:
-          block = found.block_number * (block_size  >> GRUB_DISK_SECTOR_BITS);
-          grub_dprintf ("reiserfs_blocktype", "D: %u\n", (unsigned) block);
-          if (initial_position < current_position + item_size)
-            {
-              offset = MAX ((signed) (initial_position - current_position), 0);
-              length = (MIN (item_size, final_position - current_position)
-                        - offset);
-              grub_dprintf ("reiserfs",
-                            "Reading direct block %u from %u to %u...\n",
-                            (unsigned) block, (unsigned) offset,
-                            (unsigned) (offset + length));
-              found.data->disk->read_hook = file->read_hook;
-              grub_disk_read (found.data->disk,
-                              block,
-                              offset
-                              + grub_le_to_cpu16 (found.header.item_location),
-                              length, buf);
-              found.data->disk->read_hook = 0;
-              if (grub_errno)
-                goto fail;
-              buf += length;
-              current_position += offset + length;
-            }
-          else
-            current_position += item_size;
-          break;
-        case GRUB_REISERFS_INDIRECT:
-          indirect_block_count = item_size / sizeof (*indirect_block_ptr);
-          indirect_block_ptr = grub_malloc (item_size);
-          if (! indirect_block_ptr)
-            goto fail;
-          grub_disk_read (found.data->disk,
-                          found.block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
-                          grub_le_to_cpu16 (found.header.item_location),
-                          item_size, indirect_block_ptr);
-          if (grub_errno)
-            goto fail;
-          found.data->disk->read_hook = file->read_hook;
-          for (indirect_block = 0;
-               indirect_block < indirect_block_count
-                 && current_position < final_position;
-               indirect_block++)
-            {
-              block = grub_le_to_cpu32 (indirect_block_ptr[indirect_block]) *
-                      (block_size >> GRUB_DISK_SECTOR_BITS);
-              grub_dprintf ("reiserfs_blocktype", "I: %u\n", (unsigned) block);
-              if (current_position + block_size >= initial_position)
-                {
-                  offset = MAX ((signed) (initial_position - current_position),
-                                0);
-                  length = (MIN (block_size, final_position - current_position)
-                            - offset);
-                  grub_dprintf ("reiserfs",
-                                "Reading indirect block %u from %u to %u...\n",
-                                (unsigned) block, (unsigned) offset,
-                                (unsigned) (offset + length));
-#if 0
-                  grub_dprintf ("reiserfs",
-                                "\nib=%04d/%04d, ip=%d, cp=%d, fp=%d, off=%d, l=%d, tl=%d\n",
-                                indirect_block + 1, indirect_block_count,
-                                initial_position, current_position,
-                                final_position, offset, length, len);
-#endif
-                  grub_disk_read (found.data->disk, block, offset, length, buf);
-                  if (grub_errno)
-                    goto fail;
-                  buf += length;
-                  current_position += offset + length;
-                }
-              else
-                current_position += block_size;
-            }
-          found.data->disk->read_hook = 0;
-          grub_free (indirect_block_ptr);
-          indirect_block_ptr = 0;
-          break;
-        default:
-          goto fail;
-        }
-      current_key_offset = current_position + 1;
-    }
-
-  grub_dprintf ("reiserfs",
-               "Have successfully read %lld bytes (%ld requested)\n",
-               (unsigned long long) (current_position - initial_position),
-               (unsigned long) len);
-  return current_position - initial_position;
-
-#if 0
-  switch (found.type)
-    {
-      case GRUB_REISERFS_DIRECT:
-        read_length = MIN (len, item_size - file->offset);
-        grub_disk_read (found.data->disk,
-                        (found.block_number * block_size) / GRUB_DISK_SECTOR_SIZE,
-                        grub_le_to_cpu16 (found.header.item_location) + file->offset,
-                        read_length, buf);
-        if (grub_errno)
-          goto fail;
-        break;
-      case GRUB_REISERFS_INDIRECT:
-        indirect_block_count = item_size / sizeof (*indirect_block_ptr);
-        indirect_block_ptr = grub_malloc (item_size);
-        if (!indirect_block_ptr)
-          goto fail;
-        grub_disk_read (found.data->disk,
-                        (found.block_number * block_size) / GRUB_DISK_SECTOR_SIZE,
-                        grub_le_to_cpu16 (found.header.item_location),
-                        item_size, (char *) indirect_block_ptr);
-        if (grub_errno)
-          goto fail;
-        len = MIN (len, file->size - file->offset);
-        for (indirect_block = file->offset / block_size;
-             indirect_block < indirect_block_count && read_length < len;
-             indirect_block++)
-          {
-            read = MIN (block_size, len - read_length);
-            grub_disk_read (found.data->disk,
-                            (grub_le_to_cpu32 (indirect_block_ptr[indirect_block]) * block_size) / GRUB_DISK_SECTOR_SIZE,
-                            file->offset % block_size, read,
-                            ((void *) buf) + read_length);
-            if (grub_errno)
-              goto fail;
-            read_length += read;
-          }
-        grub_free (indirect_block_ptr);
-        break;
-      default:
-        goto fail;
-    }
-
-  return read_length;
-#endif
-
- fail:
-  grub_free (indirect_block_ptr);
-  return 0;
-}
-
-/* Close the file FILE.  */
-static grub_err_t
-grub_reiserfs_close (grub_file_t file)
-{
-  struct grub_fshelp_node *node = file->data;
-  struct grub_reiserfs_data *data = node->data;
-
-  grub_free (data);
-  grub_free (node);
-  grub_dl_unref (my_mod);
-  return GRUB_ERR_NONE;
-}
-
-/* Call HOOK with each file under DIR.  */
-static grub_err_t
-grub_reiserfs_dir (grub_device_t device, const char *path,
-                   int (*hook) (const char *filename,
-                               const struct grub_dirhook_info *info))
-{
-  struct grub_reiserfs_data *data = 0;
-  struct grub_fshelp_node root, *found;
-  struct grub_reiserfs_key root_key;
-
-  auto int NESTED_FUNC_ATTR iterate (const char *filename,
-                                     enum grub_fshelp_filetype filetype,
-                                     grub_fshelp_node_t node);
-
-  int NESTED_FUNC_ATTR iterate (const char *filename,
-                                enum grub_fshelp_filetype filetype,
-                                grub_fshelp_node_t node)
-    {
-      struct grub_dirhook_info info;
-      grub_memset (&info, 0, sizeof (info));
-      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
-      grub_free (node);
-      return hook (filename, &info);
-    }
-  grub_dl_ref (my_mod);
-  data = grub_reiserfs_mount (device->disk);
-  if (! data)
-    goto fail;
-  root_key.directory_id = grub_cpu_to_le32 (1);
-  root_key.object_id = grub_cpu_to_le32 (2);
-  root_key.u.v2.offset_type = 0;
-  grub_reiserfs_set_key_type (&root_key, GRUB_REISERFS_DIRECTORY, 2);
-  grub_reiserfs_set_key_offset (&root_key, 1);
-  if (grub_reiserfs_get_item (data, &root_key, &root) != GRUB_ERR_NONE)
-    goto fail;
-  if (root.block_number == 0)
-    {
-      grub_error(GRUB_ERR_BAD_FS, "root not found");
-      goto fail;
-    }
-  grub_fshelp_find_file (path, &root, &found, grub_reiserfs_iterate_dir,
-                         grub_reiserfs_read_symlink, GRUB_FSHELP_DIR);
-  if (grub_errno)
-    goto fail;
-  grub_reiserfs_iterate_dir (found, iterate);
-  grub_free (data);
-  grub_dl_unref (my_mod);
-  return GRUB_ERR_NONE;
-
- fail:
-  grub_free (data);
-  grub_dl_unref (my_mod);
-  return grub_errno;
-}
-
-/* Return the label of the device DEVICE in LABEL.  The label is
-   returned in a grub_malloc'ed buffer and should be freed by the
-   caller.  */
-static grub_err_t
-grub_reiserfs_label (grub_device_t device, char **label)
-{
-  *label = grub_malloc (REISERFS_MAX_LABEL_LENGTH);
-  if (*label)
-    {
-      grub_disk_read (device->disk,
-                      REISERFS_SUPER_BLOCK_OFFSET / GRUB_DISK_SECTOR_SIZE,
-                      REISERFS_LABEL_OFFSET, REISERFS_MAX_LABEL_LENGTH,
-                      *label);
-    }
-  return grub_errno;
-}
-
-static grub_err_t
-grub_reiserfs_uuid (grub_device_t device, char **uuid)
-{
-  struct grub_reiserfs_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_reiserfs_mount (disk);
-  if (data)
-    {
-      *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
-                            grub_be_to_cpu16 (data->superblock.uuid[0]),
-                            grub_be_to_cpu16 (data->superblock.uuid[1]),
-                            grub_be_to_cpu16 (data->superblock.uuid[2]),
-                            grub_be_to_cpu16 (data->superblock.uuid[3]),
-                            grub_be_to_cpu16 (data->superblock.uuid[4]),
-                            grub_be_to_cpu16 (data->superblock.uuid[5]),
-                            grub_be_to_cpu16 (data->superblock.uuid[6]),
-                            grub_be_to_cpu16 (data->superblock.uuid[7]));
-    }
-  else
-    *uuid = NULL;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-static struct grub_fs grub_reiserfs_fs =
-  {
-    .name = "reiserfs",
-    .dir = grub_reiserfs_dir,
-    .open = grub_reiserfs_open,
-    .read = grub_reiserfs_read,
-    .close = grub_reiserfs_close,
-    .label = grub_reiserfs_label,
-    .uuid = grub_reiserfs_uuid,
-    .next = 0
-  };
-
-GRUB_MOD_INIT(reiserfs)
-{
-  grub_fs_register (&grub_reiserfs_fs);
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(reiserfs)
-{
-  grub_fs_unregister (&grub_reiserfs_fs);
-}
diff --git a/fs/sfs.c b/fs/sfs.c
deleted file mode 100644 (file)
index 68f8b3a..0000000
--- a/fs/sfs.c
+++ /dev/null
@@ -1,597 +0,0 @@
-/* sfs.c - Amiga Smart FileSystem.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/types.h>
-#include <grub/fshelp.h>
-
-/* The common header for a block.  */
-struct grub_sfs_bheader
-{
-  grub_uint8_t magic[4];
-  grub_uint32_t chksum;
-  grub_uint32_t ipointtomyself;
-} __attribute__ ((packed));
-
-/* The sfs rootblock.  */
-struct grub_sfs_rblock
-{
-  struct grub_sfs_bheader header;
-  grub_uint32_t version;
-  grub_uint8_t unused1[36];
-  grub_uint32_t blocksize;
-  grub_uint8_t unused2[40];
-  grub_uint8_t unused3[8];
-  grub_uint32_t rootobject;
-  grub_uint32_t btree;
-} __attribute__ ((packed));
-
-/* A SFS object container.  */
-struct grub_sfs_obj
-{
-  grub_uint8_t unused1[4];
-  grub_uint32_t nodeid;
-  grub_uint8_t unused2[4];
-  union
-  {
-    struct
-    {
-      grub_uint32_t first_block;
-      grub_uint32_t size;
-    } file __attribute__ ((packed));
-    struct
-    {
-      grub_uint32_t hashtable;
-      grub_uint32_t dir_objc;
-    } dir __attribute__ ((packed));
-  } file_dir;
-  grub_uint8_t unused3[4];
-  grub_uint8_t type;
-  grub_uint8_t filename[1];
-  grub_uint8_t comment[1];
-} __attribute__ ((packed));
-
-#define        GRUB_SFS_TYPE_DELETED   32
-#define        GRUB_SFS_TYPE_SYMLINK   64
-#define        GRUB_SFS_TYPE_DIR       128
-
-/* A SFS object container.  */
-struct grub_sfs_objc
-{
-  struct grub_sfs_bheader header;
-  grub_uint32_t parent;
-  grub_uint32_t next;
-  grub_uint32_t prev;
-  /* The amount of objects depends on the blocksize.  */
-  struct grub_sfs_obj objects[1];
-} __attribute__ ((packed));
-
-struct grub_sfs_btree_node
-{
-  grub_uint32_t key;
-  grub_uint32_t data;
-} __attribute__ ((packed));
-
-struct grub_sfs_btree_extent
-{
-  grub_uint32_t key;
-  grub_uint32_t next;
-  grub_uint32_t prev;
-  grub_uint16_t size;
-} __attribute__ ((packed));
-
-struct grub_sfs_btree
-{
-  struct grub_sfs_bheader header;
-  grub_uint16_t nodes;
-  grub_uint8_t leaf;
-  grub_uint8_t nodesize;
-  /* Normally this can be kind of node, but just extents are
-     supported.  */
-  struct grub_sfs_btree_node node[1];
-} __attribute__ ((packed));
-
-\f
-
-struct grub_fshelp_node
-{
-  struct grub_sfs_data *data;
-  int block;
-  int size;
-};
-
-/* Information about a "mounted" sfs filesystem.  */
-struct grub_sfs_data
-{
-  struct grub_sfs_rblock rblock;
-  struct grub_fshelp_node diropen;
-  grub_disk_t disk;
-
-  /* Blocksize in sectors.  */
-  unsigned int blocksize;
-
-  /* Label of the filesystem.  */
-  char *label;
-};
-
-static grub_dl_t my_mod;
-
-\f
-/* Lookup the extent starting with BLOCK in the filesystem described
-   by DATA.  Return the extent size in SIZE and the following extent
-   in NEXTEXT.  */
-static grub_err_t
-grub_sfs_read_extent (struct grub_sfs_data *data, unsigned int block,
-                     int *size, int *nextext)
-{
-  char *treeblock;
-  struct grub_sfs_btree *tree;
-  int i;
-  int next;
-  int prev;
-
-  treeblock = grub_malloc (data->blocksize);
-  if (!block)
-    return 0;
-
-  next = grub_be_to_cpu32 (data->rblock.btree);
-  tree = (struct grub_sfs_btree *) treeblock;
-
-  /* Handle this level in the btree.  */
-  do
-    {
-      prev = 0;
-
-      grub_disk_read (data->disk, next, 0, data->blocksize, treeblock);
-      if (grub_errno)
-       {
-         grub_free (treeblock);
-         return grub_errno;
-       }
-
-      for (i = grub_be_to_cpu16 (tree->nodes) - 1; i >= 0; i--)
-       {
-
-#define EXTNODE(tree, index)                                           \
-       ((struct grub_sfs_btree_node *) (((char *) &(tree)->node[0])    \
-                                        + (index) * (tree)->nodesize))
-
-         /* Follow the tree down to the leaf level.  */
-         if ((grub_be_to_cpu32 (EXTNODE(tree, i)->key) <= block)
-             && !tree->leaf)
-           {
-             next = grub_be_to_cpu32 (EXTNODE (tree, i)->data);
-             break;
-           }
-
-         /* If the leaf level is reached, just find the correct extent.  */
-         if (grub_be_to_cpu32 (EXTNODE (tree, i)->key) == block && tree->leaf)
-           {
-             struct grub_sfs_btree_extent *extent;
-             extent = (struct grub_sfs_btree_extent *) EXTNODE (tree, i);
-
-             /* We found a correct leaf.  */
-             *size = grub_be_to_cpu16 (extent->size);
-             *nextext = grub_be_to_cpu32 (extent->next);
-
-             grub_free (treeblock);
-             return 0;
-           }
-
-#undef EXTNODE
-
-       }
-    } while (!tree->leaf);
-
-  grub_free (treeblock);
-
-  return grub_error (GRUB_ERR_FILE_READ_ERROR, "SFS extent not found");
-}
-
-static grub_disk_addr_t
-grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
-{
-  int blk = node->block;
-  int size = 0;
-  int next = 0;
-
-  while (blk)
-    {
-      grub_err_t err;
-
-      /* In case of the first block we don't have to lookup the
-        extent, the minimum size is always 1.  */
-      if (fileblock == 0)
-       return blk;
-
-      err = grub_sfs_read_extent (node->data, blk, &size, &next);
-      if (err)
-       return 0;
-
-      if (fileblock < (unsigned int) size)
-       return fileblock + blk;
-
-      fileblock -= size;
-
-      blk = next;
-    }
-
-  grub_error (GRUB_ERR_FILE_READ_ERROR,
-             "reading a SFS block outside the extent");
-
-  return 0;
-}
-
-
-/* Read LEN bytes from the file described by DATA starting with byte
-   POS.  Return the amount of read bytes in READ.  */
-static grub_ssize_t
-grub_sfs_read_file (grub_fshelp_node_t node,
-                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                      unsigned offset, unsigned length),
-                   int pos, grub_size_t len, char *buf)
-{
-  return grub_fshelp_read_file (node->data->disk, node, read_hook,
-                               pos, len, buf, grub_sfs_read_block,
-                               node->size, 0);
-}
-
-
-static struct grub_sfs_data *
-grub_sfs_mount (grub_disk_t disk)
-{
-  struct grub_sfs_data *data;
-  struct grub_sfs_objc *rootobjc;
-  char *rootobjc_data = 0;
-  unsigned int blk;
-
-  data = grub_malloc (sizeof (*data));
-  if (!data)
-    return 0;
-
-  /* Read the rootblock.  */
-  grub_disk_read (disk, 0, 0, sizeof (struct grub_sfs_rblock),
-                 &data->rblock);
-  if (grub_errno)
-    goto fail;
-
-  /* Make sure this is a sfs filesystem.  */
-  if (grub_strncmp ((char *) (data->rblock.header.magic), "SFS", 4))
-    {
-      grub_error (GRUB_ERR_BAD_FS, "not a SFS filesystem");
-      goto fail;
-    }
-
-  data->blocksize = grub_be_to_cpu32 (data->rblock.blocksize);
-  rootobjc_data = grub_malloc (data->blocksize);
-  if (! rootobjc_data)
-    goto fail;
-
-  /* Read the root object container.  */
-  grub_disk_read (disk, grub_be_to_cpu32 (data->rblock.rootobject), 0,
-                 data->blocksize, rootobjc_data);
-  if (grub_errno)
-    goto fail;
-
-  rootobjc = (struct grub_sfs_objc *) rootobjc_data;
-
-  blk = grub_be_to_cpu32 (rootobjc->objects[0].file_dir.dir.dir_objc);
-  data->diropen.size = 0;
-  data->diropen.block = blk;
-  data->diropen.data = data;
-  data->disk = disk;
-  data->label = grub_strdup ((char *) (rootobjc->objects[0].filename));
-
-  return data;
-
- fail:
-  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
-    grub_error (GRUB_ERR_BAD_FS, "not an SFS filesystem");
-
-  grub_free (data);
-  grub_free (rootobjc_data);
-  return 0;
-}
-
-
-static char *
-grub_sfs_read_symlink (grub_fshelp_node_t node)
-{
-  struct grub_sfs_data *data = node->data;
-  char *symlink;
-  char *block;
-
-  block = grub_malloc (data->blocksize);
-  if (!block)
-    return 0;
-
-  grub_disk_read (data->disk, node->block, 0, data->blocksize, block);
-  if (grub_errno)
-    {
-      grub_free (block);
-      return 0;
-    }
-
-  /* This is just a wild guess, but it always worked for me.  How the
-     SLNK block looks like is not documented in the SFS docs.  */
-  symlink = grub_strdup (&block[24]);
-  grub_free (block);
-  if (!symlink)
-    return 0;
-
-  return symlink;
-}
-
-static int
-grub_sfs_iterate_dir (grub_fshelp_node_t dir,
-                      int NESTED_FUNC_ATTR
-                      (*hook) (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node))
-{
-  struct grub_fshelp_node *node = 0;
-  struct grub_sfs_data *data = dir->data;
-  char *objc_data;
-  struct grub_sfs_objc *objc;
-  unsigned int next = dir->block;
-  int pos;
-
-  auto int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block,
-                                                 int size, int type);
-
-  int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block,
-                                            int size, int type)
-    {
-      node = grub_malloc (sizeof (*node));
-      if (!node)
-       return 1;
-
-      node->data = data;
-      node->size = size;
-      node->block = block;
-
-      return hook (name, type, node);
-    }
-
-  objc_data = grub_malloc (data->blocksize);
-  if (!objc_data)
-    goto fail;
-
-  /* The Object container can consist of multiple blocks, iterate over
-     every block.  */
-  while (next)
-    {
-      grub_disk_read (data->disk, next, 0, data->blocksize, objc_data);
-      if (grub_errno)
-       goto fail;
-
-      objc = (struct grub_sfs_objc *) objc_data;
-
-      pos = (char *) &objc->objects[0] - (char *) objc;
-
-      /* Iterate over all entries in this block.  */
-      while (pos + sizeof (struct grub_sfs_obj) < data->blocksize)
-       {
-         struct grub_sfs_obj *obj;
-         obj = (struct grub_sfs_obj *) ((char *) objc + pos);
-         char *filename = (char *) (obj->filename);
-         int len;
-         enum grub_fshelp_filetype type;
-         unsigned int block;
-
-         /* The filename and comment dynamically increase the size of
-            the object.  */
-         len = grub_strlen (filename);
-         len += grub_strlen (filename + len + 1);
-
-         pos += sizeof (*obj) + len;
-         /* Round up to a multiple of two bytes.  */
-         pos = ((pos + 1) >> 1) << 1;
-
-         if (grub_strlen (filename) == 0)
-           continue;
-
-         /* First check if the file was not deleted.  */
-         if (obj->type & GRUB_SFS_TYPE_DELETED)
-           continue;
-         else if (obj->type & GRUB_SFS_TYPE_SYMLINK)
-           type = GRUB_FSHELP_SYMLINK;
-         else if (obj->type & GRUB_SFS_TYPE_DIR)
-           type = GRUB_FSHELP_DIR;
-         else
-           type = GRUB_FSHELP_REG;
-
-         if (type == GRUB_FSHELP_DIR)
-           block = grub_be_to_cpu32 (obj->file_dir.dir.dir_objc);
-         else
-           block = grub_be_to_cpu32 (obj->file_dir.file.first_block);
-
-         if (grub_sfs_create_node (filename, block,
-                                   grub_be_to_cpu32 (obj->file_dir.file.size),
-                                   type))
-           {
-             grub_free (objc_data);
-             return 1;
-           }
-       }
-
-      next = grub_be_to_cpu32 (objc->next);
-    }
-
- fail:
-  grub_free (objc_data);
-  return 0;
-}
-
-
-/* Open a file named NAME and initialize FILE.  */
-static grub_err_t
-grub_sfs_open (struct grub_file *file, const char *name)
-{
-  struct grub_sfs_data *data;
-  struct grub_fshelp_node *fdiro = 0;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_sfs_mount (file->device->disk);
-  if (!data)
-    goto fail;
-
-  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_sfs_iterate_dir,
-                        grub_sfs_read_symlink, GRUB_FSHELP_REG);
-  if (grub_errno)
-    goto fail;
-
-  file->size = fdiro->size;
-  data->diropen = *fdiro;
-  grub_free (fdiro);
-
-  file->data = data;
-  file->offset = 0;
-
-  return 0;
-
- fail:
-  if (data && fdiro != &data->diropen)
-    grub_free (fdiro);
-  if (data)
-    grub_free (data->label);
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-
-static grub_err_t
-grub_sfs_close (grub_file_t file)
-{
-  grub_free (file->data);
-
-  grub_dl_unref (my_mod);
-
-  return GRUB_ERR_NONE;
-}
-
-
-/* Read LEN bytes data from FILE into BUF.  */
-static grub_ssize_t
-grub_sfs_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_sfs_data *data = (struct grub_sfs_data *) file->data;
-
-  int size = grub_sfs_read_file (&data->diropen, file->read_hook,
-                                file->offset, len, buf);
-
-  return size;
-}
-
-
-static grub_err_t
-grub_sfs_dir (grub_device_t device, const char *path,
-              int (*hook) (const char *filename,
-                           const struct grub_dirhook_info *info))
-{
-  struct grub_sfs_data *data = 0;
-  struct grub_fshelp_node *fdiro = 0;
-
-  auto int NESTED_FUNC_ATTR iterate (const char *filename,
-                                    enum grub_fshelp_filetype filetype,
-                                    grub_fshelp_node_t node);
-
-  int NESTED_FUNC_ATTR iterate (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node)
-    {
-      struct grub_dirhook_info info;
-      grub_memset (&info, 0, sizeof (info));
-      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
-      grub_free (node);
-      return hook (filename, &info);
-    }
-
-  grub_dl_ref (my_mod);
-
-  data = grub_sfs_mount (device->disk);
-  if (!data)
-    goto fail;
-
-  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_sfs_iterate_dir,
-                       grub_sfs_read_symlink, GRUB_FSHELP_DIR);
-  if (grub_errno)
-    goto fail;
-
-  grub_sfs_iterate_dir (fdiro, iterate);
-
- fail:
-  if (data && fdiro != &data->diropen)
-    grub_free (fdiro);
-  if (data)
-    grub_free (data->label);
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-
-static grub_err_t
-grub_sfs_label (grub_device_t device, char **label)
-{
-  struct grub_sfs_data *data;
-  grub_disk_t disk = device->disk;
-
-  data = grub_sfs_mount (disk);
-  if (data)
-    *label = data->label;
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-\f
-static struct grub_fs grub_sfs_fs =
-  {
-    .name = "sfs",
-    .dir = grub_sfs_dir,
-    .open = grub_sfs_open,
-    .read = grub_sfs_read,
-    .close = grub_sfs_close,
-    .label = grub_sfs_label,
-    .next = 0
-  };
-
-GRUB_MOD_INIT(sfs)
-{
-  grub_fs_register (&grub_sfs_fs);
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(sfs)
-{
-  grub_fs_unregister (&grub_sfs_fs);
-}
diff --git a/fs/tar.c b/fs/tar.c
deleted file mode 100644 (file)
index 6ab62bc..0000000
--- a/fs/tar.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define MODE_USTAR 1
-#include "cpio.c"
diff --git a/fs/udf.c b/fs/udf.c
deleted file mode 100644 (file)
index ad109be..0000000
--- a/fs/udf.c
+++ /dev/null
@@ -1,939 +0,0 @@
-/* udf.c - Universal Disk Format filesystem.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/types.h>
-#include <grub/fshelp.h>
-#include <grub/charset.h>
-
-#define GRUB_UDF_MAX_PDS               2
-#define GRUB_UDF_MAX_PMS               6
-
-#define U16                            grub_le_to_cpu16
-#define U32                            grub_le_to_cpu32
-#define U64                            grub_le_to_cpu64
-
-#define GRUB_UDF_LOG2_BLKSZ            2
-#define GRUB_UDF_BLKSZ                 2048
-
-#define GRUB_UDF_TAG_IDENT_PVD         0x0001
-#define GRUB_UDF_TAG_IDENT_AVDP                0x0002
-#define GRUB_UDF_TAG_IDENT_VDP         0x0003
-#define GRUB_UDF_TAG_IDENT_IUVD                0x0004
-#define GRUB_UDF_TAG_IDENT_PD          0x0005
-#define GRUB_UDF_TAG_IDENT_LVD         0x0006
-#define GRUB_UDF_TAG_IDENT_USD         0x0007
-#define GRUB_UDF_TAG_IDENT_TD          0x0008
-#define GRUB_UDF_TAG_IDENT_LVID                0x0009
-
-#define GRUB_UDF_TAG_IDENT_FSD         0x0100
-#define GRUB_UDF_TAG_IDENT_FID         0x0101
-#define GRUB_UDF_TAG_IDENT_AED         0x0102
-#define GRUB_UDF_TAG_IDENT_IE          0x0103
-#define GRUB_UDF_TAG_IDENT_TE          0x0104
-#define GRUB_UDF_TAG_IDENT_FE          0x0105
-#define GRUB_UDF_TAG_IDENT_EAHD                0x0106
-#define GRUB_UDF_TAG_IDENT_USE         0x0107
-#define GRUB_UDF_TAG_IDENT_SBD         0x0108
-#define GRUB_UDF_TAG_IDENT_PIE         0x0109
-#define GRUB_UDF_TAG_IDENT_EFE         0x010A
-
-#define GRUB_UDF_ICBTAG_TYPE_UNDEF     0x00
-#define GRUB_UDF_ICBTAG_TYPE_USE       0x01
-#define GRUB_UDF_ICBTAG_TYPE_PIE       0x02
-#define GRUB_UDF_ICBTAG_TYPE_IE                0x03
-#define GRUB_UDF_ICBTAG_TYPE_DIRECTORY 0x04
-#define GRUB_UDF_ICBTAG_TYPE_REGULAR   0x05
-#define GRUB_UDF_ICBTAG_TYPE_BLOCK     0x06
-#define GRUB_UDF_ICBTAG_TYPE_CHAR      0x07
-#define GRUB_UDF_ICBTAG_TYPE_EA                0x08
-#define GRUB_UDF_ICBTAG_TYPE_FIFO      0x09
-#define GRUB_UDF_ICBTAG_TYPE_SOCKET    0x0A
-#define GRUB_UDF_ICBTAG_TYPE_TE                0x0B
-#define GRUB_UDF_ICBTAG_TYPE_SYMLINK   0x0C
-#define GRUB_UDF_ICBTAG_TYPE_STREAMDIR 0x0D
-
-#define GRUB_UDF_ICBTAG_FLAG_AD_MASK   0x0007
-#define GRUB_UDF_ICBTAG_FLAG_AD_SHORT  0x0000
-#define GRUB_UDF_ICBTAG_FLAG_AD_LONG   0x0001
-#define GRUB_UDF_ICBTAG_FLAG_AD_EXT    0x0002
-#define GRUB_UDF_ICBTAG_FLAG_AD_IN_ICB 0x0003
-
-#define GRUB_UDF_EXT_NORMAL            0x00000000
-#define GRUB_UDF_EXT_NREC_ALLOC                0x40000000
-#define GRUB_UDF_EXT_NREC_NALLOC       0x80000000
-#define GRUB_UDF_EXT_MASK              0xC0000000
-
-#define GRUB_UDF_FID_CHAR_HIDDEN       0x01
-#define GRUB_UDF_FID_CHAR_DIRECTORY    0x02
-#define GRUB_UDF_FID_CHAR_DELETED      0x04
-#define GRUB_UDF_FID_CHAR_PARENT       0x08
-#define GRUB_UDF_FID_CHAR_METADATA     0x10
-
-#define GRUB_UDF_STD_IDENT_BEA01       "BEA01"
-#define GRUB_UDF_STD_IDENT_BOOT2       "BOOT2"
-#define GRUB_UDF_STD_IDENT_CD001       "CD001"
-#define GRUB_UDF_STD_IDENT_CDW02       "CDW02"
-#define GRUB_UDF_STD_IDENT_NSR02       "NSR02"
-#define GRUB_UDF_STD_IDENT_NSR03       "NSR03"
-#define GRUB_UDF_STD_IDENT_TEA01       "TEA01"
-
-#define GRUB_UDF_CHARSPEC_TYPE_CS0     0x00
-#define GRUB_UDF_CHARSPEC_TYPE_CS1     0x01
-#define GRUB_UDF_CHARSPEC_TYPE_CS2     0x02
-#define GRUB_UDF_CHARSPEC_TYPE_CS3     0x03
-#define GRUB_UDF_CHARSPEC_TYPE_CS4     0x04
-#define GRUB_UDF_CHARSPEC_TYPE_CS5     0x05
-#define GRUB_UDF_CHARSPEC_TYPE_CS6     0x06
-#define GRUB_UDF_CHARSPEC_TYPE_CS7     0x07
-#define GRUB_UDF_CHARSPEC_TYPE_CS8     0x08
-
-#define GRUB_UDF_PARTMAP_TYPE_1                1
-#define GRUB_UDF_PARTMAP_TYPE_2                2
-
-struct grub_udf_lb_addr
-{
-  grub_uint32_t block_num;
-  grub_uint16_t part_ref;
-} __attribute__ ((packed));
-
-struct grub_udf_short_ad
-{
-  grub_uint32_t length;
-  grub_uint32_t position;
-} __attribute__ ((packed));
-
-struct grub_udf_long_ad
-{
-  grub_uint32_t length;
-  struct grub_udf_lb_addr block;
-  grub_uint8_t imp_use[6];
-} __attribute__ ((packed));
-
-struct grub_udf_extent_ad
-{
-  grub_uint32_t length;
-  grub_uint32_t start;
-} __attribute__ ((packed));
-
-struct grub_udf_charspec
-{
-  grub_uint8_t charset_type;
-  grub_uint8_t charset_info[63];
-} __attribute__ ((packed));
-
-struct grub_udf_timestamp
-{
-  grub_uint16_t type_and_timezone;
-  grub_uint16_t year;
-  grub_uint8_t month;
-  grub_uint8_t day;
-  grub_uint8_t hour;
-  grub_uint8_t minute;
-  grub_uint8_t second;
-  grub_uint8_t centi_seconds;
-  grub_uint8_t hundreds_of_micro_seconds;
-  grub_uint8_t micro_seconds;
-} __attribute__ ((packed));
-
-struct grub_udf_regid
-{
-  grub_uint8_t flags;
-  grub_uint8_t ident[23];
-  grub_uint8_t ident_suffix[8];
-} __attribute__ ((packed));
-
-struct grub_udf_tag
-{
-  grub_uint16_t tag_ident;
-  grub_uint16_t desc_version;
-  grub_uint8_t tag_checksum;
-  grub_uint8_t reserved;
-  grub_uint16_t tag_serial_number;
-  grub_uint16_t desc_crc;
-  grub_uint16_t desc_crc_length;
-  grub_uint32_t tag_location;
-} __attribute__ ((packed));
-
-struct grub_udf_fileset
-{
-  struct grub_udf_tag tag;
-  struct grub_udf_timestamp datetime;
-  grub_uint16_t interchange_level;
-  grub_uint16_t max_interchange_level;
-  grub_uint32_t charset_list;
-  grub_uint32_t max_charset_list;
-  grub_uint32_t fileset_num;
-  grub_uint32_t fileset_desc_num;
-  struct grub_udf_charspec vol_charset;
-  grub_uint8_t vol_ident[128];
-  struct grub_udf_charspec fileset_charset;
-  grub_uint8_t fileset_ident[32];
-  grub_uint8_t copyright_file_ident[32];
-  grub_uint8_t abstract_file_ident[32];
-  struct grub_udf_long_ad root_icb;
-  struct grub_udf_regid domain_ident;
-  struct grub_udf_long_ad next_ext;
-  struct grub_udf_long_ad streamdir_icb;
-} __attribute__ ((packed));
-
-struct grub_udf_icbtag
-{
-  grub_uint32_t prior_recorded_num_direct_entries;
-  grub_uint16_t strategy_type;
-  grub_uint16_t strategy_parameter;
-  grub_uint16_t num_entries;
-  grub_uint8_t reserved;
-  grub_uint8_t file_type;
-  struct grub_udf_lb_addr parent_idb;
-  grub_uint16_t flags;
-} __attribute__ ((packed));
-
-struct grub_udf_file_ident
-{
-  struct grub_udf_tag tag;
-  grub_uint16_t version_num;
-  grub_uint8_t characteristics;
-  grub_uint8_t file_ident_length;
-  struct grub_udf_long_ad icb;
-  grub_uint16_t imp_use_length;
-} __attribute__ ((packed));
-
-struct grub_udf_file_entry
-{
-  struct grub_udf_tag tag;
-  struct grub_udf_icbtag icbtag;
-  grub_uint32_t uid;
-  grub_uint32_t gid;
-  grub_uint32_t permissions;
-  grub_uint16_t link_count;
-  grub_uint8_t record_format;
-  grub_uint8_t record_display_attr;
-  grub_uint32_t record_length;
-  grub_uint64_t file_size;
-  grub_uint64_t blocks_recorded;
-  struct grub_udf_timestamp access_time;
-  struct grub_udf_timestamp modification_time;
-  struct grub_udf_timestamp attr_time;
-  grub_uint32_t checkpoint;
-  struct grub_udf_long_ad extended_attr_idb;
-  struct grub_udf_regid imp_ident;
-  grub_uint64_t unique_id;
-  grub_uint32_t ext_attr_length;
-  grub_uint32_t alloc_descs_length;
-  grub_uint8_t ext_attr[1872];
-} __attribute__ ((packed));
-
-struct grub_udf_extended_file_entry
-{
-  struct grub_udf_tag tag;
-  struct grub_udf_icbtag icbtag;
-  grub_uint32_t uid;
-  grub_uint32_t gid;
-  grub_uint32_t permissions;
-  grub_uint16_t link_count;
-  grub_uint8_t record_format;
-  grub_uint8_t record_display_attr;
-  grub_uint32_t record_length;
-  grub_uint64_t file_size;
-  grub_uint64_t object_size;
-  grub_uint64_t blocks_recorded;
-  struct grub_udf_timestamp access_time;
-  struct grub_udf_timestamp modification_time;
-  struct grub_udf_timestamp create_time;
-  struct grub_udf_timestamp attr_time;
-  grub_uint32_t checkpoint;
-  grub_uint32_t reserved;
-  struct grub_udf_long_ad extended_attr_icb;
-  struct grub_udf_long_ad streamdir_icb;
-  struct grub_udf_regid imp_ident;
-  grub_uint64_t unique_id;
-  grub_uint32_t ext_attr_length;
-  grub_uint32_t alloc_descs_length;
-  grub_uint8_t ext_attr[1832];
-} __attribute__ ((packed));
-
-struct grub_udf_vrs
-{
-  grub_uint8_t type;
-  grub_uint8_t magic[5];
-  grub_uint8_t version;
-} __attribute__ ((packed));
-
-struct grub_udf_avdp
-{
-  struct grub_udf_tag tag;
-  struct grub_udf_extent_ad vds;
-} __attribute__ ((packed));
-
-struct grub_udf_pd
-{
-  struct grub_udf_tag tag;
-  grub_uint32_t seq_num;
-  grub_uint16_t flags;
-  grub_uint16_t part_num;
-  struct grub_udf_regid contents;
-  grub_uint8_t contents_use[128];
-  grub_uint32_t access_type;
-  grub_uint32_t start;
-  grub_uint32_t length;
-} __attribute__ ((packed));
-
-struct grub_udf_partmap
-{
-  grub_uint8_t type;
-  grub_uint8_t length;
-  union
-  {
-    struct
-    {
-      grub_uint16_t seq_num;
-      grub_uint16_t part_num;
-    } type1;
-
-    struct
-    {
-      grub_uint8_t ident[62];
-    } type2;
-  };
-};
-
-struct grub_udf_lvd
-{
-  struct grub_udf_tag tag;
-  grub_uint32_t seq_num;
-  struct grub_udf_charspec charset;
-  grub_uint8_t ident[128];
-  grub_uint32_t bsize;
-  struct grub_udf_regid domain_ident;
-  struct grub_udf_long_ad root_fileset;
-  grub_uint32_t map_table_length;
-  grub_uint32_t num_part_maps;
-  struct grub_udf_regid imp_ident;
-  grub_uint8_t imp_use[128];
-  struct grub_udf_extent_ad integrity_seq_ext;
-  grub_uint8_t part_maps[1608];
-} __attribute__ ((packed));
-
-struct grub_udf_data
-{
-  grub_disk_t disk;
-  struct grub_udf_lvd lvd;
-  struct grub_udf_pd pds[GRUB_UDF_MAX_PDS];
-  struct grub_udf_partmap *pms[GRUB_UDF_MAX_PMS];
-  struct grub_udf_long_ad root_icb;
-  int npd, npm;
-};
-
-struct grub_fshelp_node
-{
-  struct grub_udf_data *data;
-  union
-  {
-    struct grub_udf_file_entry fe;
-    struct grub_udf_extended_file_entry efe;
-  };
-  int part_ref;
-};
-
-static grub_dl_t my_mod;
-
-static grub_uint32_t
-grub_udf_get_block (struct grub_udf_data *data,
-                   grub_uint16_t part_ref, grub_uint32_t block)
-{
-  part_ref = U16 (part_ref);
-
-  if (part_ref >= data->npm)
-    {
-      grub_error (GRUB_ERR_BAD_FS, "invalid part ref");
-      return 0;
-    }
-
-  return (U32 (data->pds[data->pms[part_ref]->type1.part_num].start)
-          + U32 (block));
-}
-
-static grub_err_t
-grub_udf_read_icb (struct grub_udf_data *data,
-                  struct grub_udf_long_ad *icb,
-                  struct grub_fshelp_node *node)
-{
-  grub_uint32_t block;
-
-  block = grub_udf_get_block (data,
-                             icb->block.part_ref,
-                              icb->block.block_num);
-
-  if (grub_errno)
-    return grub_errno;
-
-  if (grub_disk_read (data->disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
-                     sizeof (struct grub_udf_file_entry),
-                     &node->fe))
-    return grub_errno;
-
-  if ((U16 (node->fe.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FE) &&
-      (U16 (node->fe.tag.tag_ident) != GRUB_UDF_TAG_IDENT_EFE))
-    return grub_error (GRUB_ERR_BAD_FS, "invalid fe/efe descriptor");
-
-  node->part_ref = icb->block.part_ref;
-  node->data = data;
-  return 0;
-}
-
-static grub_disk_addr_t
-grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
-{
-  char *ptr;
-  int len;
-  grub_disk_addr_t filebytes;
-
-  if (U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE)
-    {
-      ptr = (char *) &node->fe.ext_attr[0] + U32 (node->fe.ext_attr_length);
-      len = U32 (node->fe.alloc_descs_length);
-    }
-  else
-    {
-      ptr = (char *) &node->efe.ext_attr[0] + U32 (node->efe.ext_attr_length);
-      len = U32 (node->efe.alloc_descs_length);
-    }
-
-  if ((U16 (node->fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK)
-      == GRUB_UDF_ICBTAG_FLAG_AD_SHORT)
-    {
-      struct grub_udf_short_ad *ad = (struct grub_udf_short_ad *) ptr;
-
-      len /= sizeof (struct grub_udf_short_ad);
-      filebytes = fileblock * GRUB_UDF_BLKSZ;
-      while (len > 0)
-       {
-         if (filebytes < U32 (ad->length))
-           return ((U32 (ad->position) & GRUB_UDF_EXT_MASK) ? 0 :
-                    (grub_udf_get_block (node->data,
-                                         node->part_ref,
-                                         ad->position)
-                     + (filebytes / GRUB_UDF_BLKSZ)));
-
-         filebytes -= U32 (ad->length);
-         ad++;
-         len--;
-       }
-    }
-  else
-    {
-      struct grub_udf_long_ad *ad = (struct grub_udf_long_ad *) ptr;
-
-      len /= sizeof (struct grub_udf_long_ad);
-      filebytes = fileblock * GRUB_UDF_BLKSZ;
-      while (len > 0)
-       {
-         if (filebytes < U32 (ad->length))
-           return ((U32 (ad->block.block_num) & GRUB_UDF_EXT_MASK) ?  0 :
-                    (grub_udf_get_block (node->data,
-                                         ad->block.part_ref,
-                                         ad->block.block_num)
-                    + (filebytes / GRUB_UDF_BLKSZ)));
-
-         filebytes -= U32 (ad->length);
-         ad++;
-         len--;
-       }
-    }
-
-  return 0;
-}
-
-static grub_ssize_t
-grub_udf_read_file (grub_fshelp_node_t node,
-                   void NESTED_FUNC_ATTR
-                   (*read_hook) (grub_disk_addr_t sector,
-                                 unsigned offset, unsigned length),
-                   int pos, grub_size_t len, char *buf)
-{
-  switch (U16 (node->fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK)
-    {
-    case GRUB_UDF_ICBTAG_FLAG_AD_IN_ICB:
-      {
-       char *ptr;
-
-       ptr = ((U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE) ?
-              ((char *) &node->fe.ext_attr[0]
-                + U32 (node->fe.ext_attr_length)) :
-              ((char *) &node->efe.ext_attr[0]
-                + U32 (node->efe.ext_attr_length)));
-
-       grub_memcpy (buf, ptr + pos, len);
-
-       return len;
-      }
-
-    case GRUB_UDF_ICBTAG_FLAG_AD_EXT:
-      grub_error (GRUB_ERR_BAD_FS, "invalid extent type");
-      return 0;
-    }
-
-  return  grub_fshelp_read_file (node->data->disk, node, read_hook,
-                                 pos, len, buf, grub_udf_read_block,
-                                 U64 (node->fe.file_size),
-                                 GRUB_UDF_LOG2_BLKSZ);
-}
-
-static int sblocklist[] = { 256, 512, 0 };
-
-static struct grub_udf_data *
-grub_udf_mount (grub_disk_t disk)
-{
-  struct grub_udf_data *data = 0;
-  struct grub_udf_fileset root_fs;
-  int *sblklist = sblocklist;
-  grub_uint32_t block;
-  int i;
-
-  data = grub_malloc (sizeof (struct grub_udf_data));
-  if (!data)
-    return 0;
-
-  data->disk = disk;
-
-  /* Search for Volume Recognition Sequence (VRS).  */
-  for (block = 16;; block++)
-    {
-      struct grub_udf_vrs vrs;
-
-      if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
-                         sizeof (struct grub_udf_vrs), &vrs))
-       {
-         grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
-         goto fail;
-       }
-
-      if ((!grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_NSR03, 5)) ||
-         (!grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_NSR02, 5)))
-       break;
-
-      if ((grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_BEA01, 5)) &&
-         (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_BOOT2, 5)) &&
-         (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_CD001, 5)) &&
-         (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_CDW02, 5)) &&
-         (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_TEA01, 5)))
-       {
-         grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
-         goto fail;
-       }
-    }
-
-  /* Search for Anchor Volume Descriptor Pointer (AVDP).  */
-  while (1)
-    {
-      struct grub_udf_avdp avdp;
-
-      if (grub_disk_read (disk, *sblklist << GRUB_UDF_LOG2_BLKSZ, 0,
-                         sizeof (struct grub_udf_avdp), &avdp))
-       {
-         grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
-         goto fail;
-       }
-
-      if (U16 (avdp.tag.tag_ident) == GRUB_UDF_TAG_IDENT_AVDP)
-       {
-         block = U32 (avdp.vds.start);
-         break;
-       }
-
-      sblklist++;
-      if (*sblklist == 0)
-       {
-         grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
-         goto fail;
-       }
-    }
-
-  data->npd = data->npm = 0;
-  /* Locate Partition Descriptor (PD) and Logical Volume Descriptor (LVD).  */
-  while (1)
-    {
-      struct grub_udf_tag tag;
-
-      if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
-                         sizeof (struct grub_udf_tag), &tag))
-       {
-         grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
-         goto fail;
-       }
-
-      tag.tag_ident = U16 (tag.tag_ident);
-      if (tag.tag_ident == GRUB_UDF_TAG_IDENT_PD)
-       {
-         if (data->npd >= GRUB_UDF_MAX_PDS)
-           {
-             grub_error (GRUB_ERR_BAD_FS, "too many PDs");
-             goto fail;
-           }
-
-         if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
-                             sizeof (struct grub_udf_pd),
-                             &data->pds[data->npd]))
-           {
-             grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
-             goto fail;
-           }
-
-         data->npd++;
-       }
-      else if (tag.tag_ident == GRUB_UDF_TAG_IDENT_LVD)
-       {
-         int k;
-
-         struct grub_udf_partmap *ppm;
-
-         if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
-                             sizeof (struct grub_udf_lvd),
-                             &data->lvd))
-           {
-             grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
-             goto fail;
-           }
-
-         if (data->npm + U32 (data->lvd.num_part_maps) > GRUB_UDF_MAX_PMS)
-           {
-             grub_error (GRUB_ERR_BAD_FS, "too many partition maps");
-             goto fail;
-           }
-
-         ppm = (struct grub_udf_partmap *) &data->lvd.part_maps;
-         for (k = U32 (data->lvd.num_part_maps); k > 0; k--)
-           {
-             if (ppm->type != GRUB_UDF_PARTMAP_TYPE_1)
-               {
-                 grub_error (GRUB_ERR_BAD_FS, "partmap type not supported");
-                 goto fail;
-               }
-
-             data->pms[data->npm++] = ppm;
-             ppm = (struct grub_udf_partmap *) ((char *) ppm +
-                                                 U32 (ppm->length));
-           }
-       }
-      else if (tag.tag_ident > GRUB_UDF_TAG_IDENT_TD)
-       {
-         grub_error (GRUB_ERR_BAD_FS, "invalid tag ident");
-         goto fail;
-       }
-      else if (tag.tag_ident == GRUB_UDF_TAG_IDENT_TD)
-       break;
-
-      block++;
-    }
-
-  for (i = 0; i < data->npm; i++)
-    {
-      int j;
-
-      for (j = 0; j < data->npd; j++)
-       if (data->pms[i]->type1.part_num == data->pds[j].part_num)
-         {
-           data->pms[i]->type1.part_num = j;
-           break;
-         }
-
-      if (j == data->npd)
-       {
-         grub_error (GRUB_ERR_BAD_FS, "can\'t find PD");
-         goto fail;
-       }
-    }
-
-  block = grub_udf_get_block (data,
-                             data->lvd.root_fileset.block.part_ref,
-                             data->lvd.root_fileset.block.block_num);
-
-  if (grub_errno)
-    goto fail;
-
-  if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
-                     sizeof (struct grub_udf_fileset), &root_fs))
-    {
-      grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
-      goto fail;
-    }
-
-  if (U16 (root_fs.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FSD)
-    {
-      grub_error (GRUB_ERR_BAD_FS, "invalid fileset descriptor");
-      goto fail;
-    }
-
-  data->root_icb = root_fs.root_icb;
-
-  return data;
-
-fail:
-  grub_free (data);
-  return 0;
-}
-
-static int
-grub_udf_iterate_dir (grub_fshelp_node_t dir,
-                     int NESTED_FUNC_ATTR
-                     (*hook) (const char *filename,
-                              enum grub_fshelp_filetype filetype,
-                              grub_fshelp_node_t node))
-{
-  grub_fshelp_node_t child;
-  struct grub_udf_file_ident dirent;
-  grub_uint32_t offset = 0;
-
-  child = grub_malloc (sizeof (struct grub_fshelp_node));
-  if (!child)
-    return 0;
-
-  /* The current directory is not stored.  */
-  grub_memcpy ((char *) child, (char *) dir,
-              sizeof (struct grub_fshelp_node));
-
-  if (hook (".", GRUB_FSHELP_DIR, child))
-    return 1;
-
-  while (offset < U64 (dir->fe.file_size))
-    {
-      if (grub_udf_read_file (dir, 0, offset, sizeof (dirent),
-                             (char *) &dirent) != sizeof (dirent))
-       return 0;
-
-      if (U16 (dirent.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FID)
-       {
-         grub_error (GRUB_ERR_BAD_FS, "invalid fid tag");
-         return 0;
-       }
-
-      child = grub_malloc (sizeof (struct grub_fshelp_node));
-      if (!child)
-       return 0;
-
-      if (grub_udf_read_icb (dir->data, &dirent.icb, child))
-       return 0;
-
-      offset += sizeof (dirent) + U16 (dirent.imp_use_length);
-      if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT)
-       {
-         /* This is the parent directory.  */
-         if (hook ("..", GRUB_FSHELP_DIR, child))
-           return 1;
-       }
-      else
-       {
-         enum grub_fshelp_filetype type;
-         grub_uint8_t raw[dirent.file_ident_length];
-         grub_uint16_t utf16[dirent.file_ident_length - 1];
-         grub_uint8_t filename[dirent.file_ident_length * 2];
-         grub_size_t utf16len = 0;
-
-         type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ?
-                 (GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG));
-
-         if ((grub_udf_read_file (dir, 0, offset,
-                                  dirent.file_ident_length,
-                                  (char *) raw))
-             != dirent.file_ident_length)
-           return 0;
-
-         if (raw[0] == 8)
-           {
-             unsigned i;
-             utf16len = dirent.file_ident_length - 1;
-             for (i = 0; i < utf16len; i++)
-               utf16[i] = raw[i + 1];
-           }
-         if (raw[0] == 16)
-           {
-             unsigned i;
-             utf16len = (dirent.file_ident_length - 1) / 2;
-             for (i = 0; i < utf16len; i++)
-               utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
-           }
-         if (raw[0] == 8 || raw[0] == 16)
-           {
-             *grub_utf16_to_utf8 (filename, utf16, utf16len) = '\0';
-         
-             if (hook ((char *) filename, type, child))
-               return 1;
-           }
-       }
-
-      /* Align to dword boundary.  */
-      offset = (offset + dirent.file_ident_length + 3) & (~3);
-    }
-
-  return 0;
-}
-
-static grub_err_t
-grub_udf_dir (grub_device_t device, const char *path,
-             int (*hook) (const char *filename,
-                          const struct grub_dirhook_info *info))
-{
-  struct grub_udf_data *data = 0;
-  struct grub_fshelp_node rootnode;
-  struct grub_fshelp_node *foundnode;
-
-  auto int NESTED_FUNC_ATTR iterate (const char *filename,
-                                    enum grub_fshelp_filetype filetype,
-                                    grub_fshelp_node_t node);
-
-  int NESTED_FUNC_ATTR iterate (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node)
-  {
-      struct grub_dirhook_info info;
-      grub_memset (&info, 0, sizeof (info));
-      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
-      grub_free (node);
-      return hook (filename, &info);
-  }
-
-  grub_dl_ref (my_mod);
-
-  data = grub_udf_mount (device->disk);
-  if (!data)
-    goto fail;
-
-  if (grub_udf_read_icb (data, &data->root_icb, &rootnode))
-    goto fail;
-
-  if (grub_fshelp_find_file (path, &rootnode,
-                            &foundnode,
-                            grub_udf_iterate_dir, 0, GRUB_FSHELP_DIR))
-    goto fail;
-
-  grub_udf_iterate_dir (foundnode, iterate);
-
-  if (foundnode != &rootnode)
-    grub_free (foundnode);
-
-fail:
-  grub_free (data);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_udf_open (struct grub_file *file, const char *name)
-{
-  struct grub_udf_data *data;
-  struct grub_fshelp_node rootnode;
-  struct grub_fshelp_node *foundnode;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_udf_mount (file->device->disk);
-  if (!data)
-    goto fail;
-
-  if (grub_udf_read_icb (data, &data->root_icb, &rootnode))
-    goto fail;
-
-  if (grub_fshelp_find_file (name, &rootnode,
-                            &foundnode,
-                            grub_udf_iterate_dir, 0, GRUB_FSHELP_REG))
-    goto fail;
-
-  file->data = foundnode;
-  file->offset = 0;
-  file->size = U64 (foundnode->fe.file_size);
-
-  return 0;
-
-fail:
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-static grub_ssize_t
-grub_udf_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_fshelp_node *node = (struct grub_fshelp_node *) file->data;
-
-  return grub_udf_read_file (node, file->read_hook, file->offset, len, buf);
-}
-
-static grub_err_t
-grub_udf_close (grub_file_t file)
-{
-  if (file->data)
-    {
-      struct grub_fshelp_node *node = (struct grub_fshelp_node *) file->data;
-
-      grub_free (node->data);
-      grub_free (node);
-    }
-
-  grub_dl_unref (my_mod);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_udf_label (grub_device_t device, char **label)
-{
-  struct grub_udf_data *data;
-  data = grub_udf_mount (device->disk);
-
-  if (data)
-    {
-      *label = grub_strdup ((char *) &data->lvd.ident[1]);
-      grub_free (data);
-    }
-  else
-    *label = 0;
-
-  return grub_errno;
-}
-
-static struct grub_fs grub_udf_fs = {
-  .name = "udf",
-  .dir = grub_udf_dir,
-  .open = grub_udf_open,
-  .read = grub_udf_read,
-  .close = grub_udf_close,
-  .label = grub_udf_label,
-  .next = 0
-};
-
-GRUB_MOD_INIT (udf)
-{
-  grub_fs_register (&grub_udf_fs);
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI (udf)
-{
-  grub_fs_unregister (&grub_udf_fs);
-}
diff --git a/fs/ufs.c b/fs/ufs.c
deleted file mode 100644 (file)
index 40cf068..0000000
--- a/fs/ufs.c
+++ /dev/null
@@ -1,813 +0,0 @@
-/* ufs.c - Unix File System */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/types.h>
-
-#ifdef MODE_UFS2
-#define GRUB_UFS_MAGIC         0x19540119
-#else
-#define GRUB_UFS_MAGIC         0x11954
-#endif
-
-#define GRUB_UFS_INODE         2
-#define GRUB_UFS_FILETYPE_DIR  4
-#define GRUB_UFS_FILETYPE_LNK  10
-#define GRUB_UFS_MAX_SYMLNK_CNT        8
-
-#define GRUB_UFS_DIRBLKS       12
-#define GRUB_UFS_INDIRBLKS     3
-
-#define GRUB_UFS_ATTR_TYPE      0160000
-#define GRUB_UFS_ATTR_FILE     0100000
-#define GRUB_UFS_ATTR_DIR      0040000
-#define GRUB_UFS_ATTR_LNK       0120000
-
-#define GRUB_UFS_VOLNAME_LEN   32
-
-/* Calculate in which group the inode can be found.  */
-#define UFS_BLKSZ(sblock) (grub_le_to_cpu32 (sblock->bsize))
-
-#define INODE(data,field) data->inode.  field
-#ifdef MODE_UFS2
-#define INODE_ENDIAN(data,field,bits1,bits2) grub_le_to_cpu##bits2 (data->inode.field)
-#else
-#define INODE_ENDIAN(data,field,bits1,bits2) grub_le_to_cpu##bits1 (data->inode.field)
-#endif
-
-#define INODE_SIZE(data) INODE_ENDIAN (data,size,32,64)
-#define INODE_NBLOCKS(data) INODE_ENDIAN (data,nblocks,32,64)
-
-#define INODE_MODE(data) INODE_ENDIAN (data,mode,16,16)
-#ifdef MODE_UFS2
-#define INODE_BLKSZ 8
-#else
-#define INODE_BLKSZ 4
-#endif
-#ifdef MODE_UFS2
-#define UFS_INODE_PER_BLOCK 2
-#else
-#define UFS_INODE_PER_BLOCK 4
-#endif
-#define INODE_DIRBLOCKS(data,blk) INODE_ENDIAN \
-                                   (data,blocks.dir_blocks[blk],32,64)
-#define INODE_INDIRBLOCKS(data,blk) INODE_ENDIAN \
-                                     (data,blocks.indir_blocks[blk],32,64)
-
-/* The blocks on which the superblock can be found.  */
-static int sblocklist[] = { 128, 16, 0, 512, -1 };
-
-struct grub_ufs_sblock
-{
-  grub_uint8_t unused[16];
-  /* The offset of the inodes in the cylinder group.  */
-  grub_uint32_t inoblk_offs;
-
-  grub_uint8_t unused2[4];
-
-  /* The start of the cylinder group.  */
-  grub_uint32_t cylg_offset;
-  grub_uint32_t cylg_mask;
-
-  grub_uint32_t mtime;
-  grub_uint8_t unused4[12];
-
-  /* The size of a block in bytes.  */
-  grub_int32_t bsize;
-  grub_uint8_t unused5[48];
-
-  /* The size of filesystem blocks to disk blocks.  */
-  grub_uint32_t log2_blksz;
-  grub_uint8_t unused6[40];
-  grub_uint32_t uuidhi;
-  grub_uint32_t uuidlow;
-  grub_uint8_t unused7[32];
-
-  /* Inodes stored per cylinder group.  */
-  grub_uint32_t ino_per_group;
-
-  /* The frags per cylinder group.  */
-  grub_uint32_t frags_per_group;
-
-  grub_uint8_t unused8[488];
-
-  /* Volume name for UFS2.  */
-  grub_uint8_t volume_name[GRUB_UFS_VOLNAME_LEN];
-  grub_uint8_t unused9[360];
-
-  grub_uint64_t mtime2;
-  grub_uint8_t unused10[292];
-
-  /* Magic value to check if this is really a UFS filesystem.  */
-  grub_uint32_t magic;
-};
-
-#ifdef MODE_UFS2
-/* UFS inode.  */
-struct grub_ufs_inode
-{
-  grub_uint16_t mode;
-  grub_uint16_t nlinks;
-  grub_uint32_t uid;
-  grub_uint32_t gid;
-  grub_uint32_t blocksize;
-  grub_int64_t size;
-  grub_int64_t nblocks;
-  grub_uint64_t atime;
-  grub_uint64_t mtime;
-  grub_uint64_t ctime;
-  grub_uint64_t create_time;
-  grub_uint32_t atime_sec;
-  grub_uint32_t mtime_sec;
-  grub_uint32_t ctime_sec;
-  grub_uint32_t create_time_sec;
-  grub_uint32_t gen;
-  grub_uint32_t kernel_flags;
-  grub_uint32_t flags;
-  grub_uint32_t extsz;
-  grub_uint64_t ext[2];
-  union
-  {
-    struct
-    {
-      grub_uint64_t dir_blocks[GRUB_UFS_DIRBLKS];
-      grub_uint64_t indir_blocks[GRUB_UFS_INDIRBLKS];
-    } blocks;
-    grub_uint8_t symlink[(GRUB_UFS_DIRBLKS + GRUB_UFS_INDIRBLKS) * 8];
-  };
-
-  grub_uint8_t unused[24];
-} __attribute__ ((packed));
-#else
-/* UFS inode.  */
-struct grub_ufs_inode
-{
-  grub_uint16_t mode;
-  grub_uint16_t nlinks;
-  grub_uint16_t uid;
-  grub_uint16_t gid;
-  grub_int64_t size;
-  grub_uint64_t atime;
-  grub_uint64_t mtime;
-  grub_uint64_t ctime;
-  union
-  {
-    struct
-    {
-      grub_uint32_t dir_blocks[GRUB_UFS_DIRBLKS];
-      grub_uint32_t indir_blocks[GRUB_UFS_INDIRBLKS];
-    } blocks;
-    grub_uint8_t symlink[(GRUB_UFS_DIRBLKS + GRUB_UFS_INDIRBLKS) * 4];
-  };
-  grub_uint32_t flags;
-  grub_uint32_t nblocks;
-  grub_uint32_t gen;
-  grub_uint32_t unused;
-  grub_uint8_t pad[12];
-} __attribute__ ((packed));
-#endif
-
-/* Directory entry.  */
-struct grub_ufs_dirent
-{
-  grub_uint32_t ino;
-  grub_uint16_t direntlen;
-  union
-  {
-    grub_uint16_t namelen;
-    struct
-    {
-      grub_uint8_t filetype_bsd;
-      grub_uint8_t namelen_bsd;
-    };
-  };
-} __attribute__ ((packed));
-
-/* Information about a "mounted" ufs filesystem.  */
-struct grub_ufs_data
-{
-  struct grub_ufs_sblock sblock;
-  grub_disk_t disk;
-  struct grub_ufs_inode inode;
-  int ino;
-  int linknest;
-};
-
-static grub_dl_t my_mod;
-\f
-/* Forward declaration.  */
-static grub_err_t grub_ufs_find_file (struct grub_ufs_data *data,
-                                     const char *path);
-
-
-static grub_disk_addr_t
-grub_ufs_get_file_block (struct grub_ufs_data *data, unsigned int blk)
-{
-  struct grub_ufs_sblock *sblock = &data->sblock;
-  unsigned int indirsz;
-  int log2_blksz;
-
-  /* Direct.  */
-  if (blk < GRUB_UFS_DIRBLKS)
-    return INODE_DIRBLOCKS (data, blk);
-
-  log2_blksz = grub_le_to_cpu32 (data->sblock.log2_blksz);
-
-  blk -= GRUB_UFS_DIRBLKS;
-
-  indirsz = UFS_BLKSZ (sblock) / INODE_BLKSZ;
-  /* Single indirect block.  */
-  if (blk < indirsz)
-    {
-#ifdef MODE_UFS2
-      grub_uint64_t indir[UFS_BLKSZ (sblock) / sizeof (grub_uint64_t)];
-#else
-      grub_uint32_t indir[UFS_BLKSZ (sblock) / sizeof (grub_uint32_t)];
-#endif
-      grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 0) << log2_blksz,
-                     0, sizeof (indir), indir);
-      return indir[blk];
-    }
-  blk -= indirsz;
-
-  /* Double indirect block.  */
-  if (blk < indirsz * indirsz)
-    {
-#ifdef MODE_UFS2
-      grub_uint64_t indir[UFS_BLKSZ (sblock) / sizeof (grub_uint64_t)];
-#else
-      grub_uint32_t indir[UFS_BLKSZ (sblock) / sizeof (grub_uint32_t)];
-#endif
-
-      grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 1) << log2_blksz,
-                     0, sizeof (indir), indir);
-      grub_disk_read (data->disk,
-                     (indir [blk / indirsz])
-                     << log2_blksz,
-                     0, sizeof (indir), indir);
-
-      return indir[blk % indirsz];
-    }
-
-
-  grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-             "ufs does not support triple indirect blocks");
-  return 0;
-}
-
-
-/* Read LEN bytes from the file described by DATA starting with byte
-   POS.  Return the amount of read bytes in READ.  */
-static grub_ssize_t
-grub_ufs_read_file (struct grub_ufs_data *data,
-                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                      unsigned offset, unsigned length),
-                   int pos, grub_size_t len, char *buf)
-{
-  struct grub_ufs_sblock *sblock = &data->sblock;
-  int i;
-  int blockcnt;
-
-  /* Adjust len so it we can't read past the end of the file.  */
-  if (len + pos > INODE_SIZE (data))
-    len = INODE_SIZE (data) - pos;
-
-  blockcnt = (len + pos + UFS_BLKSZ (sblock) - 1) / UFS_BLKSZ (sblock);
-
-  for (i = pos / UFS_BLKSZ (sblock); i < blockcnt; i++)
-    {
-      int blknr;
-      int blockoff = pos % UFS_BLKSZ (sblock);
-      int blockend = UFS_BLKSZ (sblock);
-
-      int skipfirst = 0;
-
-      blknr = grub_ufs_get_file_block (data, i);
-      if (grub_errno)
-       return -1;
-
-      /* Last block.  */
-      if (i == blockcnt - 1)
-       {
-         blockend = (len + pos) % UFS_BLKSZ (sblock);
-
-         if (!blockend)
-           blockend = UFS_BLKSZ (sblock);
-       }
-
-      /* First block.  */
-      if (i == (pos / (int) UFS_BLKSZ (sblock)))
-       {
-         skipfirst = blockoff;
-         blockend -= skipfirst;
-       }
-
-      /* XXX: If the block number is 0 this block is not stored on
-        disk but is zero filled instead.  */
-      if (blknr)
-       {
-         data->disk->read_hook = read_hook;
-         grub_disk_read (data->disk,
-                         blknr << grub_le_to_cpu32 (data->sblock.log2_blksz),
-                         skipfirst, blockend, buf);
-         data->disk->read_hook = 0;
-         if (grub_errno)
-           return -1;
-       }
-      else
-       grub_memset (buf, UFS_BLKSZ (sblock) - skipfirst, 0);
-
-      buf += UFS_BLKSZ (sblock) - skipfirst;
-    }
-
-  return len;
-}
-
-/* Read inode INO from the mounted filesystem described by DATA.  This
-   inode is used by default now.  */
-static grub_err_t
-grub_ufs_read_inode (struct grub_ufs_data *data, int ino, char *inode)
-{
-  struct grub_ufs_sblock *sblock = &data->sblock;
-
-  /* Determine the group the inode is in.  */
-  int group = ino / grub_le_to_cpu32 (sblock->ino_per_group);
-
-  /* Determine the inode within the group.  */
-  int grpino = ino % grub_le_to_cpu32 (sblock->ino_per_group);
-
-  /* The first block of the group.  */
-  int grpblk = group * (grub_le_to_cpu32 (sblock->frags_per_group));
-
-#ifndef MODE_UFS2
-  grpblk += grub_le_to_cpu32 (sblock->cylg_offset)
-    * (group & (~grub_le_to_cpu32 (sblock->cylg_mask)));
-#endif
-
-  if (!inode)
-    {
-      inode = (char *) &data->inode;
-      data->ino = ino;
-    }
-
-  grub_disk_read (data->disk,
-                 ((grub_le_to_cpu32 (sblock->inoblk_offs) + grpblk)
-                  << grub_le_to_cpu32 (data->sblock.log2_blksz))
-                 + grpino / UFS_INODE_PER_BLOCK,
-                 (grpino % UFS_INODE_PER_BLOCK)
-                 * sizeof (struct grub_ufs_inode),
-                 sizeof (struct grub_ufs_inode),
-                 inode);
-
-  return grub_errno;
-}
-
-
-/* Lookup the symlink the current inode points to.  INO is the inode
-   number of the directory the symlink is relative to.  */
-static grub_err_t
-grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino)
-{
-  char symlink[INODE_SIZE (data)];
-
-  if (++data->linknest > GRUB_UFS_MAX_SYMLNK_CNT)
-    return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
-
-  if (INODE_NBLOCKS (data) == 0)
-    grub_strcpy (symlink, (char *) INODE (data, symlink));
-  else
-    {
-      grub_disk_read (data->disk,
-                     (INODE_DIRBLOCKS (data, 0)
-                      << grub_le_to_cpu32 (data->sblock.log2_blksz)),
-                     0, INODE_SIZE (data), symlink);
-      symlink[INODE_SIZE (data)] = '\0';
-    }
-
-  /* The symlink is an absolute path, go back to the root inode.  */
-  if (symlink[0] == '/')
-    ino = GRUB_UFS_INODE;
-
-  /* Now load in the old inode.  */
-  if (grub_ufs_read_inode (data, ino, 0))
-    return grub_errno;
-
-  grub_ufs_find_file (data, symlink);
-  if (grub_errno)
-    grub_error (grub_errno, "cannot follow symlink `%s'", symlink);
-
-  return grub_errno;
-}
-
-
-/* Find the file with the pathname PATH on the filesystem described by
-   DATA.  */
-static grub_err_t
-grub_ufs_find_file (struct grub_ufs_data *data, const char *path)
-{
-  char fpath[grub_strlen (path) + 1];
-  char *name = fpath;
-  char *next;
-  unsigned int pos = 0;
-  int dirino;
-
-  grub_strcpy (fpath, path);
-
-  /* Skip the first slash.  */
-  if (name[0] == '/')
-    {
-      name++;
-      if (!*name)
-       return 0;
-    }
-
-  /* Extract the actual part from the pathname.  */
-  next = grub_strchr (name, '/');
-  if (next)
-    {
-      next[0] = '\0';
-      next++;
-    }
-
-  do
-    {
-      struct grub_ufs_dirent dirent;
-      int namelen;
-
-      if (grub_strlen (name) == 0)
-       return GRUB_ERR_NONE;
-
-      if (grub_ufs_read_file (data, 0, pos, sizeof (dirent),
-                             (char *) &dirent) < 0)
-       return grub_errno;
-
-#ifdef MODE_UFS2
-      namelen = dirent.namelen_bsd;
-#else
-      namelen = grub_le_to_cpu16 (dirent.namelen);
-#endif
-      {
-       char filename[namelen + 1];
-
-       if (grub_ufs_read_file (data, 0, pos + sizeof (dirent),
-                               namelen, filename) < 0)
-         return grub_errno;
-
-       filename[namelen] = '\0';
-
-       if (!grub_strcmp (name, filename))
-         {
-           dirino = data->ino;
-           grub_ufs_read_inode (data, grub_le_to_cpu32 (dirent.ino), 0);
-
-           if ((INODE_MODE(data) & GRUB_UFS_ATTR_TYPE)
-               == GRUB_UFS_ATTR_LNK)
-             {
-               grub_ufs_lookup_symlink (data, dirino);
-               if (grub_errno)
-                 return grub_errno;
-             }
-
-           if (!next)
-             return 0;
-
-           pos = 0;
-
-           name = next;
-           next = grub_strchr (name, '/');
-           if (next)
-             {
-               next[0] = '\0';
-               next++;
-             }
-
-           if ((INODE_MODE(data) & GRUB_UFS_ATTR_TYPE) != GRUB_UFS_ATTR_DIR)
-             return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-
-           continue;
-         }
-      }
-
-      pos += grub_le_to_cpu16 (dirent.direntlen);
-    } while (pos < INODE_SIZE (data));
-
-  grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
-  return grub_errno;
-}
-
-
-/* Mount the filesystem on the disk DISK.  */
-static struct grub_ufs_data *
-grub_ufs_mount (grub_disk_t disk)
-{
-  struct grub_ufs_data *data;
-  int *sblklist = sblocklist;
-
-  data = grub_malloc (sizeof (struct grub_ufs_data));
-  if (!data)
-    return 0;
-
-  /* Find a UFS sblock.  */
-  while (*sblklist != -1)
-    {
-      grub_disk_read (disk, *sblklist, 0, sizeof (struct grub_ufs_sblock),
-                     &data->sblock);
-      if (grub_errno)
-       goto fail;
-
-      if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC)
-       {
-         data->disk = disk;
-         data->linknest = 0;
-         return data;
-       }
-      sblklist++;
-    }
-
- fail:
-
-  if (grub_errno == GRUB_ERR_NONE || grub_errno == GRUB_ERR_OUT_OF_RANGE)
-    {
-#ifdef MODE_UFS2
-      grub_error (GRUB_ERR_BAD_FS, "not an ufs2 filesystem");
-#else
-      grub_error (GRUB_ERR_BAD_FS, "not an ufs1 filesystem");
-#endif
-    }
-
-  grub_free (data);
-
-  return 0;
-}
-
-
-static grub_err_t
-grub_ufs_dir (grub_device_t device, const char *path,
-              int (*hook) (const char *filename,
-                           const struct grub_dirhook_info *info))
-{
-  struct grub_ufs_data *data;
-  struct grub_ufs_sblock *sblock;
-  unsigned int pos = 0;
-
-  data = grub_ufs_mount (device->disk);
-  if (!data)
-    return grub_errno;
-
-  grub_ufs_read_inode (data, GRUB_UFS_INODE, 0);
-  if (grub_errno)
-    return grub_errno;
-
-  sblock = &data->sblock;
-
-  if (!path || path[0] != '/')
-    {
-      grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
-      return grub_errno;
-    }
-
-  grub_ufs_find_file (data, path);
-  if (grub_errno)
-    goto fail;
-
-  if ((INODE_MODE (data) & GRUB_UFS_ATTR_TYPE) != GRUB_UFS_ATTR_DIR)
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-      goto fail;
-    }
-
-  while (pos < INODE_SIZE (data))
-    {
-      struct grub_ufs_dirent dirent;
-      int namelen;
-
-      if (grub_ufs_read_file (data, 0, pos, sizeof (dirent),
-                             (char *) &dirent) < 0)
-       break;
-
-#ifdef MODE_UFS2
-      namelen = dirent.namelen_bsd;
-#else
-      namelen = grub_le_to_cpu16 (dirent.namelen);
-#endif
-
-      {
-       char filename[namelen + 1];
-       struct grub_dirhook_info info;
-       struct grub_ufs_inode inode;
-
-       grub_memset (&info, 0, sizeof (info));
-
-       if (grub_ufs_read_file (data, 0, pos + sizeof (dirent),
-                               namelen, filename) < 0)
-         break;
-
-       filename[namelen] = '\0';
-       grub_ufs_read_inode (data, dirent.ino, (char *) &inode);
-
-       info.dir = ((grub_le_to_cpu16 (inode.mode) & GRUB_UFS_ATTR_TYPE)
-                   == GRUB_UFS_ATTR_DIR);
-       info.mtime = grub_le_to_cpu64 (inode.mtime);
-       info.mtimeset = 1;
-
-       if (hook (filename, &info))
-         break;
-      }
-
-      pos += grub_le_to_cpu16 (dirent.direntlen);
-    }
-
- fail:
-  grub_free (data);
-
-  return grub_errno;
-}
-
-
-/* Open a file named NAME and initialize FILE.  */
-static grub_err_t
-grub_ufs_open (struct grub_file *file, const char *name)
-{
-  struct grub_ufs_data *data;
-  data = grub_ufs_mount (file->device->disk);
-  if (!data)
-    return grub_errno;
-
-  grub_ufs_read_inode (data, 2, 0);
-  if (grub_errno)
-    {
-      grub_free (data);
-      return grub_errno;
-    }
-
-  if (!name || name[0] != '/')
-    {
-      grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
-      return grub_errno;
-    }
-
-  grub_ufs_find_file (data, name);
-  if (grub_errno)
-    {
-      grub_free (data);
-      return grub_errno;
-    }
-
-  file->data = data;
-  file->size = INODE_SIZE (data);
-
-  return GRUB_ERR_NONE;
-}
-
-
-static grub_ssize_t
-grub_ufs_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_ufs_data *data =
-    (struct grub_ufs_data *) file->data;
-
-  return grub_ufs_read_file (data, file->read_hook, file->offset, len, buf);
-}
-
-
-static grub_err_t
-grub_ufs_close (grub_file_t file)
-{
-  grub_free (file->data);
-
-  return GRUB_ERR_NONE;
-}
-
-
-#ifdef MODE_UFS2
-static grub_err_t
-grub_ufs_label (grub_device_t device, char **label)
-{
-  struct grub_ufs_data *data = 0;
-
-  grub_dl_ref (my_mod);
-
-  *label = 0;
-
-  data = grub_ufs_mount (device->disk);
-  if (data)
-    *label = grub_strdup ((char *) data->sblock.volume_name);
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-#endif
-
-static grub_err_t
-grub_ufs_uuid (grub_device_t device, char **uuid)
-{
-  struct grub_ufs_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_ufs_mount (disk);
-  if (data && (data->sblock.uuidhi != 0 || data->sblock.uuidlow != 0))
-    *uuid = grub_xasprintf ("%08x%08x",
-                          (unsigned) grub_le_to_cpu32 (data->sblock.uuidhi),
-                          (unsigned) grub_le_to_cpu32 (data->sblock.uuidlow));
-  else
-    *uuid = NULL;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-
-/* Get mtime.  */
-static grub_err_t
-grub_ufs_mtime (grub_device_t device, grub_int32_t *tm)
-{
-  struct grub_ufs_data *data = 0;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_ufs_mount (device->disk);
-  if (!data)
-    *tm = 0;
-  else
-#ifdef MODE_UFS2
-    *tm = grub_le_to_cpu64 (data->sblock.mtime2);
-#else
-    *tm = grub_le_to_cpu32 (data->sblock.mtime);
-#endif
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-
-\f
-static struct grub_fs grub_ufs_fs =
-  {
-#ifdef MODE_UFS2
-    .name = "ufs2",
-#else
-    .name = "ufs1",
-#endif
-    .dir = grub_ufs_dir,
-    .open = grub_ufs_open,
-    .read = grub_ufs_read,
-    .close = grub_ufs_close,
-#ifdef MODE_UFS2
-    .label = grub_ufs_label,
-#endif
-    .uuid = grub_ufs_uuid,
-    .mtime = grub_ufs_mtime,
-    .next = 0
-  };
-
-#ifdef MODE_UFS2
-GRUB_MOD_INIT(ufs2)
-#else
-GRUB_MOD_INIT(ufs1)
-#endif
-{
-  grub_fs_register (&grub_ufs_fs);
-  my_mod = mod;
-}
-
-#ifdef MODE_UFS2
-GRUB_MOD_FINI(ufs2)
-#else
-GRUB_MOD_FINI(ufs1)
-#endif
-{
-  grub_fs_unregister (&grub_ufs_fs);
-}
-
diff --git a/fs/ufs2.c b/fs/ufs2.c
deleted file mode 100644 (file)
index 7f4eb95..0000000
--- a/fs/ufs2.c
+++ /dev/null
@@ -1,3 +0,0 @@
-/* ufs2.c - Unix File System 2 */
-#define MODE_UFS2 1
-#include "ufs.c"
diff --git a/fs/xfs.c b/fs/xfs.c
deleted file mode 100644 (file)
index 9dffe31..0000000
--- a/fs/xfs.c
+++ /dev/null
@@ -1,823 +0,0 @@
-/* xfs.c - XFS.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-#include <grub/types.h>
-#include <grub/fshelp.h>
-
-#define        XFS_INODE_EXTENTS       9
-
-#define XFS_INODE_FORMAT_INO   1
-#define XFS_INODE_FORMAT_EXT   2
-#define XFS_INODE_FORMAT_BTREE 3
-
-
-struct grub_xfs_sblock
-{
-  grub_uint8_t magic[4];
-  grub_uint32_t bsize;
-  grub_uint8_t unused1[24];
-  grub_uint16_t uuid[8];
-  grub_uint8_t unused2[8];
-  grub_uint64_t rootino;
-  grub_uint8_t unused3[20];
-  grub_uint32_t agsize;
-  grub_uint8_t unused4[20];
-  grub_uint8_t label[12];
-  grub_uint8_t log2_bsize;
-  grub_uint8_t log2_sect;
-  grub_uint8_t log2_inode;
-  grub_uint8_t log2_inop;
-  grub_uint8_t log2_agblk;
-  grub_uint8_t unused6[67];
-  grub_uint8_t log2_dirblk;
-} __attribute__ ((packed));
-
-struct grub_xfs_dir_header
-{
-  grub_uint8_t count;
-  grub_uint8_t smallino;
-  union
-  {
-    grub_uint32_t i4;
-    grub_uint64_t i8;
-  } parent __attribute__ ((packed));
-} __attribute__ ((packed));
-
-struct grub_xfs_dir_entry
-{
-  grub_uint8_t len;
-  grub_uint16_t offset;
-  char name[1];
-  /* Inode number follows, 32 bits.  */
-} __attribute__ ((packed));
-
-struct grub_xfs_dir2_entry
-{
-  grub_uint64_t inode;
-  grub_uint8_t len;
-} __attribute__ ((packed));
-
-typedef grub_uint32_t grub_xfs_extent[4];
-
-struct grub_xfs_btree_node
-{
-  grub_uint8_t magic[4];
-  grub_uint16_t level;
-  grub_uint16_t numrecs;
-  grub_uint64_t left;
-  grub_uint64_t right;
-  grub_uint64_t keys[1];
-}  __attribute__ ((packed));
-
-struct grub_xfs_btree_root
-{
-  grub_uint16_t level;
-  grub_uint16_t numrecs;
-  grub_uint64_t keys[1];
-}  __attribute__ ((packed));
-
-struct grub_xfs_inode
-{
-  grub_uint8_t magic[2];
-  grub_uint16_t mode;
-  grub_uint8_t version;
-  grub_uint8_t format;
-  grub_uint8_t unused2[50];
-  grub_uint64_t size;
-  grub_uint64_t nblocks;
-  grub_uint32_t extsize;
-  grub_uint32_t nextents;
-  grub_uint8_t unused3[20];
-  union
-  {
-    char raw[156];
-    struct dir
-    {
-      struct grub_xfs_dir_header dirhead;
-      struct grub_xfs_dir_entry direntry[1];
-    } dir;
-    grub_xfs_extent extents[XFS_INODE_EXTENTS];
-    struct grub_xfs_btree_root btree;
-  } data __attribute__ ((packed));
-} __attribute__ ((packed));
-
-struct grub_xfs_dirblock_tail
-{
-  grub_uint32_t leaf_count;
-  grub_uint32_t leaf_stale;
-} __attribute__ ((packed));
-
-struct grub_fshelp_node
-{
-  struct grub_xfs_data *data;
-  grub_uint64_t ino;
-  int inode_read;
-  struct grub_xfs_inode inode;
-};
-
-struct grub_xfs_data
-{
-  struct grub_xfs_sblock sblock;
-  grub_disk_t disk;
-  int pos;
-  int bsize;
-  int agsize;
-  struct grub_fshelp_node diropen;
-};
-
-static grub_dl_t my_mod;
-
-\f
-
-/* Filetype information as used in inodes.  */
-#define FILETYPE_INO_MASK      0170000
-#define FILETYPE_INO_REG       0100000
-#define FILETYPE_INO_DIRECTORY 0040000
-#define FILETYPE_INO_SYMLINK   0120000
-
-#define GRUB_XFS_INO_AGBITS(data)              \
-  ((data)->sblock.log2_agblk + (data)->sblock.log2_inop)
-#define GRUB_XFS_INO_INOINAG(data, ino)                \
-  (grub_be_to_cpu64 (ino) & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1))
-#define GRUB_XFS_INO_AG(data,ino)              \
-  (grub_be_to_cpu64 (ino) >> GRUB_XFS_INO_AGBITS (data))
-
-#define GRUB_XFS_FSB_TO_BLOCK(data, fsb) \
-  (((fsb) >> (data)->sblock.log2_agblk) * (data)->agsize \
- + ((fsb) & ((1LL << (data)->sblock.log2_agblk) - 1)))
-
-#define GRUB_XFS_EXTENT_OFFSET(exts,ex) \
-       ((grub_be_to_cpu32 (exts[ex][0]) & ~(1 << 31)) << 23 \
-       | grub_be_to_cpu32 (exts[ex][1]) >> 9)
-
-#define GRUB_XFS_EXTENT_BLOCK(exts,ex)         \
-  ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex][1]) \
-                 & (0x1ff)) << 43 \
-   | (grub_uint64_t) grub_be_to_cpu32 (exts[ex][2]) << 11 \
-   | grub_be_to_cpu32 (exts[ex][3]) >> 21)
-
-#define GRUB_XFS_EXTENT_SIZE(exts,ex)          \
-  (grub_be_to_cpu32 (exts[ex][3]) & ((1 << 20) - 1))
-
-#define GRUB_XFS_ROUND_TO_DIRENT(pos)  ((((pos) + 8 - 1) / 8) * 8)
-#define GRUB_XFS_NEXT_DIRENT(pos,len)          \
-  (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2)
-\f
-static inline grub_uint64_t
-grub_xfs_inode_block (struct grub_xfs_data *data,
-                     grub_uint64_t ino)
-{
-  long long int inoinag = GRUB_XFS_INO_INOINAG (data, ino);
-  long long ag = GRUB_XFS_INO_AG (data, ino);
-  long long block;
-
-  block = (inoinag >> data->sblock.log2_inop) + ag * data->agsize;
-  block <<= (data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS);
-  return block;
-}
-
-
-static inline int
-grub_xfs_inode_offset (struct grub_xfs_data *data,
-                      grub_uint64_t ino)
-{
-  int inoag = GRUB_XFS_INO_INOINAG (data, ino);
-  return ((inoag & ((1 << data->sblock.log2_inop) - 1)) <<
-         data->sblock.log2_inode);
-}
-
-
-static grub_err_t
-grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
-                    struct grub_xfs_inode *inode)
-{
-  grub_uint64_t block = grub_xfs_inode_block (data, ino);
-  int offset = grub_xfs_inode_offset (data, ino);
-
-  /* Read the inode.  */
-  if (grub_disk_read (data->disk, block, offset,
-                     1 << data->sblock.log2_inode, inode))
-    return grub_errno;
-
-  if (grub_strncmp ((char *) inode->magic, "IN", 2))
-    return grub_error (GRUB_ERR_BAD_FS, "not a correct XFS inode");
-
-  return 0;
-}
-
-
-static grub_disk_addr_t
-grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
-{
-  struct grub_xfs_btree_node *leaf = 0;
-  int ex, nrec;
-  grub_xfs_extent *exts;
-  grub_uint64_t ret = 0;
-
-  if (node->inode.format == XFS_INODE_FORMAT_BTREE)
-    {
-      grub_uint64_t *keys;
-
-      leaf = grub_malloc (node->data->sblock.bsize);
-      if (leaf == 0)
-        return 0;
-
-      nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs);
-      keys = &node->inode.data.btree.keys[0];
-      do
-        {
-          int i;
-
-          for (i = 0; i < nrec; i++)
-            {
-              if (fileblock < grub_be_to_cpu64 (keys[i]))
-                break;
-            }
-
-          /* Sparse block.  */
-          if (i == 0)
-            {
-              grub_free (leaf);
-              return 0;
-            }
-
-          if (grub_disk_read (node->data->disk,
-                              grub_be_to_cpu64 (keys[i - 1 + nrec])
-                              << (node->data->sblock.log2_bsize
-                                  - GRUB_DISK_SECTOR_BITS),
-                              0, node->data->sblock.bsize, leaf))
-            return 0;
-
-          if (grub_strncmp ((char *) leaf->magic, "BMAP", 4))
-            {
-              grub_free (leaf);
-              grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node");
-              return 0;
-            }
-
-          nrec = grub_be_to_cpu16 (leaf->numrecs);
-          keys = &leaf->keys[0];
-        } while (leaf->level);
-      exts = (grub_xfs_extent *) keys;
-    }
-  else if (node->inode.format == XFS_INODE_FORMAT_EXT)
-    {
-      nrec = grub_be_to_cpu32 (node->inode.nextents);
-      exts = &node->inode.data.extents[0];
-    }
-  else
-    {
-      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                 "XFS does not support inode format %d yet",
-                 node->inode.format);
-      return 0;
-    }
-
-  /* Iterate over each extent to figure out which extent has
-     the block we are looking for.  */
-  for (ex = 0; ex < nrec; ex++)
-    {
-      grub_uint64_t start = GRUB_XFS_EXTENT_BLOCK (exts, ex);
-      grub_uint64_t offset = GRUB_XFS_EXTENT_OFFSET (exts, ex);
-      grub_uint64_t size = GRUB_XFS_EXTENT_SIZE (exts, ex);
-
-      /* Sparse block.  */
-      if (fileblock < offset)
-        break;
-      else if (fileblock < offset + size)
-        {
-          ret = (fileblock - offset + start);
-          break;
-        }
-    }
-
-  if (leaf)
-    grub_free (leaf);
-
-  return GRUB_XFS_FSB_TO_BLOCK(node->data, ret);
-}
-
-
-/* Read LEN bytes from the file described by DATA starting with byte
-   POS.  Return the amount of read bytes in READ.  */
-static grub_ssize_t
-grub_xfs_read_file (grub_fshelp_node_t node,
-                    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                       unsigned offset, unsigned length),
-                    int pos, grub_size_t len, char *buf)
-{
-  return grub_fshelp_read_file (node->data->disk, node, read_hook,
-                               pos, len, buf, grub_xfs_read_block,
-                               grub_be_to_cpu64 (node->inode.size),
-                               node->data->sblock.log2_bsize
-                               - GRUB_DISK_SECTOR_BITS);
-}
-
-
-static char *
-grub_xfs_read_symlink (grub_fshelp_node_t node)
-{
-  int size = grub_be_to_cpu64 (node->inode.size);
-
-  switch (node->inode.format)
-    {
-    case XFS_INODE_FORMAT_INO:
-      return grub_strndup (node->inode.data.raw, size);
-
-    case XFS_INODE_FORMAT_EXT:
-      {
-       char *symlink;
-       grub_ssize_t numread;
-
-       symlink = grub_malloc (size + 1);
-       if (!symlink)
-         return 0;
-
-       numread = grub_xfs_read_file (node, 0, 0, size, symlink);
-       if (numread != size)
-         {
-           grub_free (symlink);
-           return 0;
-         }
-       symlink[size] = '\0';
-       return symlink;
-      }
-    }
-
-  return 0;
-}
-
-
-static enum grub_fshelp_filetype
-grub_xfs_mode_to_filetype (grub_uint16_t mode)
-{
-  if ((grub_be_to_cpu16 (mode)
-       & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY)
-    return GRUB_FSHELP_DIR;
-  else if ((grub_be_to_cpu16 (mode)
-           & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK)
-    return GRUB_FSHELP_SYMLINK;
-  else if ((grub_be_to_cpu16 (mode)
-           & FILETYPE_INO_MASK) == FILETYPE_INO_REG)
-    return GRUB_FSHELP_REG;
-  return GRUB_FSHELP_UNKNOWN;
-}
-
-
-static int
-grub_xfs_iterate_dir (grub_fshelp_node_t dir,
-                      int NESTED_FUNC_ATTR
-                      (*hook) (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node))
-{
-  struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
-  auto int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, char *filename);
-
-  int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, char *filename)
-    {
-      struct grub_fshelp_node *fdiro;
-
-      fdiro = grub_malloc (sizeof (struct grub_fshelp_node)
-                          - sizeof (struct grub_xfs_inode)
-                          + (1 << diro->data->sblock.log2_inode));
-      if (!fdiro)
-       return 0;
-
-      /* The inode should be read, otherwise the filetype can
-        not be determined.  */
-      fdiro->ino = ino;
-      fdiro->inode_read = 1;
-      fdiro->data = diro->data;
-      grub_xfs_read_inode (diro->data, ino, &fdiro->inode);
-
-      return hook (filename,
-                  grub_xfs_mode_to_filetype (fdiro->inode.mode),
-                  fdiro);
-    }
-
-  switch (diro->inode.format)
-    {
-    case XFS_INODE_FORMAT_INO:
-      {
-       struct grub_xfs_dir_entry *de = &diro->inode.data.dir.direntry[0];
-       int smallino = !diro->inode.data.dir.dirhead.smallino;
-       int i;
-       grub_uint64_t parent;
-
-       /* If small inode numbers are used to pack the direntry, the
-          parent inode number is small too.  */
-       if (smallino)
-         {
-           parent = grub_be_to_cpu32 (diro->inode.data.dir.dirhead.parent.i4);
-           parent = grub_cpu_to_be64 (parent);
-           /* The header is a bit smaller than usual.  */
-           de = (struct grub_xfs_dir_entry *) ((char *) de - 4);
-         }
-       else
-         {
-           parent = diro->inode.data.dir.dirhead.parent.i8;
-         }
-
-       /* Synthesize the direntries for `.' and `..'.  */
-       if (call_hook (diro->ino, "."))
-         return 1;
-
-       if (call_hook (parent, ".."))
-         return 1;
-
-       for (i = 0; i < diro->inode.data.dir.dirhead.count; i++)
-         {
-           grub_uint64_t ino;
-           void *inopos = (((char *) de)
-                           + sizeof (struct grub_xfs_dir_entry)
-                           + de->len - 1);
-           char name[de->len + 1];
-
-           if (smallino)
-             {
-               ino = grub_be_to_cpu32 (*(grub_uint32_t *) inopos);
-               ino = grub_cpu_to_be64 (ino);
-             }
-           else
-             ino = *(grub_uint64_t *) inopos;
-
-           grub_memcpy (name, de->name, de->len);
-           name[de->len] = '\0';
-           if (call_hook (ino, name))
-             return 1;
-
-           de = ((struct grub_xfs_dir_entry *)
-                 (((char *) de)+ sizeof (struct grub_xfs_dir_entry) + de->len
-                  + ((smallino ? sizeof (grub_uint32_t)
-                      : sizeof (grub_uint64_t))) - 1));
-         }
-       break;
-      }
-
-    case XFS_INODE_FORMAT_BTREE:
-    case XFS_INODE_FORMAT_EXT:
-      {
-       grub_ssize_t numread;
-       char *dirblock;
-       grub_uint64_t blk;
-        int dirblk_size, dirblk_log2;
-
-        dirblk_log2 = (dir->data->sblock.log2_bsize
-                       + dir->data->sblock.log2_dirblk);
-        dirblk_size = 1 << dirblk_log2;
-
-       dirblock = grub_malloc (dirblk_size);
-       if (! dirblock)
-         return 0;
-
-       /* Iterate over every block the directory has.  */
-       for (blk = 0;
-            blk < (grub_be_to_cpu64 (dir->inode.size)
-                   >> dirblk_log2);
-            blk++)
-         {
-           /* The header is skipped, the first direntry is stored
-              from byte 16.  */
-           int pos = 16;
-           int entries;
-           int tail_start = (dirblk_size
-                             - sizeof (struct grub_xfs_dirblock_tail));
-
-           struct grub_xfs_dirblock_tail *tail;
-           tail = (struct grub_xfs_dirblock_tail *) &dirblock[tail_start];
-
-           numread = grub_xfs_read_file (dir, 0,
-                                         blk << dirblk_log2,
-                                         dirblk_size, dirblock);
-           if (numread != dirblk_size)
-             return 0;
-
-           entries = (grub_be_to_cpu32 (tail->leaf_count)
-                      - grub_be_to_cpu32 (tail->leaf_stale));
-
-           /* Iterate over all entries within this block.  */
-           while (pos < (dirblk_size
-                         - (int) sizeof (struct grub_xfs_dir2_entry)))
-             {
-               struct grub_xfs_dir2_entry *direntry;
-               grub_uint16_t *freetag;
-               char *filename;
-
-               direntry = (struct grub_xfs_dir2_entry *) &dirblock[pos];
-               freetag = (grub_uint16_t *) direntry;
-
-               if (*freetag == 0XFFFF)
-                 {
-                   grub_uint16_t *skip = (grub_uint16_t *) (freetag + 1);
-
-                   /* This entry is not used, go to the next one.  */
-                   pos += grub_be_to_cpu16 (*skip);
-
-                   continue;
-                 }
-
-               filename = &dirblock[pos + sizeof (*direntry)];
-               /* The byte after the filename is for the tag, which
-                  is not used by GRUB.  So it can be overwritten.  */
-               filename[direntry->len] = '\0';
-
-               if (call_hook (direntry->inode, filename))
-                 {
-                   grub_free (dirblock);
-                   return 1;
-                 }
-
-               /* Check if last direntry in this block is
-                  reached.  */
-               entries--;
-               if (!entries)
-                 break;
-
-               /* Select the next directory entry.  */
-               pos = GRUB_XFS_NEXT_DIRENT (pos, direntry->len);
-               pos = GRUB_XFS_ROUND_TO_DIRENT (pos);
-             }
-         }
-       grub_free (dirblock);
-       break;
-      }
-
-    default:
-      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                 "XFS does not support inode format %d yet",
-                 diro->inode.format);
-    }
-  return 0;
-}
-
-
-static struct grub_xfs_data *
-grub_xfs_mount (grub_disk_t disk)
-{
-  struct grub_xfs_data *data = 0;
-
-  data = grub_zalloc (sizeof (struct grub_xfs_data));
-  if (!data)
-    return 0;
-
-  /* Read the superblock.  */
-  if (grub_disk_read (disk, 0, 0,
-                     sizeof (struct grub_xfs_sblock), &data->sblock))
-    goto fail;
-
-  if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4))
-    {
-      grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem");
-      goto fail;
-    }
-
-  data = grub_realloc (data,
-                      sizeof (struct grub_xfs_data)
-                      - sizeof (struct grub_xfs_inode)
-                      + (1 << data->sblock.log2_inode));
-
-  if (! data)
-    goto fail;
-
-  data->diropen.data = data;
-  data->diropen.ino = data->sblock.rootino;
-  data->diropen.inode_read = 1;
-  data->bsize = grub_be_to_cpu32 (data->sblock.bsize);
-  data->agsize = grub_be_to_cpu32 (data->sblock.agsize);
-
-  data->disk = disk;
-  data->pos = 0;
-
-  grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode);
-
-  return data;
- fail:
-
-  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
-    grub_error (GRUB_ERR_BAD_FS, "not an XFS filesystem");
-
-  grub_free (data);
-
-  return 0;
-}
-
-\f
-static grub_err_t
-grub_xfs_dir (grub_device_t device, const char *path,
-             int (*hook) (const char *filename,
-                          const struct grub_dirhook_info *info))
-{
-  struct grub_xfs_data *data = 0;
-  struct grub_fshelp_node *fdiro = 0;
-
-  auto int NESTED_FUNC_ATTR iterate (const char *filename,
-                                    enum grub_fshelp_filetype filetype,
-                                    grub_fshelp_node_t node);
-
-  int NESTED_FUNC_ATTR iterate (const char *filename,
-                               enum grub_fshelp_filetype filetype,
-                               grub_fshelp_node_t node)
-    {
-      struct grub_dirhook_info info;
-      grub_memset (&info, 0, sizeof (info));
-      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
-      grub_free (node);
-      return hook (filename, &info);
-    }
-
-  grub_dl_ref (my_mod);
-
-  data = grub_xfs_mount (device->disk);
-  if (!data)
-    goto mount_fail;
-
-  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_xfs_iterate_dir,
-                        grub_xfs_read_symlink, GRUB_FSHELP_DIR);
-  if (grub_errno)
-    goto fail;
-
-  grub_xfs_iterate_dir (fdiro, iterate);
-
- fail:
-  if (fdiro != &data->diropen)
-    grub_free (fdiro);
-  grub_free (data);
-
- mount_fail:
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-
-/* Open a file named NAME and initialize FILE.  */
-static grub_err_t
-grub_xfs_open (struct grub_file *file, const char *name)
-{
-  struct grub_xfs_data *data;
-  struct grub_fshelp_node *fdiro = 0;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_xfs_mount (file->device->disk);
-  if (!data)
-    goto mount_fail;
-
-  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_xfs_iterate_dir,
-                        grub_xfs_read_symlink, GRUB_FSHELP_REG);
-  if (grub_errno)
-    goto fail;
-
-  if (!fdiro->inode_read)
-    {
-      grub_xfs_read_inode (data, fdiro->ino, &fdiro->inode);
-      if (grub_errno)
-       goto fail;
-    }
-
-  if (fdiro != &data->diropen)
-    grub_memcpy (&data->diropen, fdiro,
-                sizeof (struct grub_fshelp_node)
-                - sizeof (struct grub_xfs_inode)
-                + (1 << data->sblock.log2_inode));
-
-  file->size = grub_be_to_cpu64 (data->diropen.inode.size);
-  file->data = data;
-  file->offset = 0;
-
-  return 0;
-
- fail:
-  if (fdiro != &data->diropen)
-    grub_free (fdiro);
-  grub_free (data);
-
- mount_fail:
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-
-static grub_ssize_t
-grub_xfs_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_xfs_data *data =
-    (struct grub_xfs_data *) file->data;
-
-  return grub_xfs_read_file (&data->diropen, file->read_hook,
-                             file->offset, len, buf);
-}
-
-
-static grub_err_t
-grub_xfs_close (grub_file_t file)
-{
-  grub_free (file->data);
-
-  grub_dl_unref (my_mod);
-
-  return GRUB_ERR_NONE;
-}
-
-
-static grub_err_t
-grub_xfs_label (grub_device_t device, char **label)
-{
-  struct grub_xfs_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_xfs_mount (disk);
-  if (data)
-    *label = grub_strndup ((char *) (data->sblock.label), 12);
-  else
-    *label = 0;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_xfs_uuid (grub_device_t device, char **uuid)
-{
-  struct grub_xfs_data *data;
-  grub_disk_t disk = device->disk;
-
-  grub_dl_ref (my_mod);
-
-  data = grub_xfs_mount (disk);
-  if (data)
-    {
-      *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
-                            grub_be_to_cpu16 (data->sblock.uuid[0]),
-                            grub_be_to_cpu16 (data->sblock.uuid[1]),
-                            grub_be_to_cpu16 (data->sblock.uuid[2]),
-                            grub_be_to_cpu16 (data->sblock.uuid[3]),
-                            grub_be_to_cpu16 (data->sblock.uuid[4]),
-                            grub_be_to_cpu16 (data->sblock.uuid[5]),
-                            grub_be_to_cpu16 (data->sblock.uuid[6]),
-                            grub_be_to_cpu16 (data->sblock.uuid[7]));
-    }
-  else
-    *uuid = NULL;
-
-  grub_dl_unref (my_mod);
-
-  grub_free (data);
-
-  return grub_errno;
-}
-
-\f
-
-static struct grub_fs grub_xfs_fs =
-  {
-    .name = "xfs",
-    .dir = grub_xfs_dir,
-    .open = grub_xfs_open,
-    .read = grub_xfs_read,
-    .close = grub_xfs_close,
-    .label = grub_xfs_label,
-    .uuid = grub_xfs_uuid,
-    .next = 0
-  };
-
-GRUB_MOD_INIT(xfs)
-{
-  grub_fs_register (&grub_xfs_fs);
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(xfs)
-{
-  grub_fs_unregister (&grub_xfs_fs);
-}
diff --git a/gencmdlist.sh b/gencmdlist.sh
deleted file mode 100644 (file)
index ed5965f..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2005,2009  Free Software Foundation, Inc.
-#
-# This gensymlist.sh is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-# Read source code from stdin and detect command names.
-
-module=$1
-
-grep -v "^#" | sed -n \
- -e "/grub_register_command *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $module/;p;}" \
- -e "/grub_register_extcmd *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $module/;p;}" \
- -e "/grub_register_command_p1 *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $module/;p;}"
-
diff --git a/gendistlist.sh b/gendistlist.sh
deleted file mode 100755 (executable)
index 102c0c1..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2005, 2008, 2009  Free Software Foundation, Inc.
-#
-# This gendistlist.sh is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-# Generate a list of distributed files.
-
-EXTRA_DISTFILES="AUTHORS COPYING ChangeLog DISTLIST INSTALL NEWS README \
-       THANKS TODO Makefile.in aclocal.m4 autogen.sh config.guess \
-       config.h.in config.sub configure configure.ac gencmdlist.sh \
-       gendistlist.sh genfslist.sh genhandlerlist.sh geninit.sh \
-       geninitheader.sh genkernsyms.sh.in genmk.rb genmoddep.awk \
-       genmodsrc.sh genpartmaplist.sh genparttoollist.sh \
-       genvideolist.sh \
-       gensymlist.sh.in install-sh mkinstalldirs stamp-h.in"
-
-DISTDIRS="boot bus commands conf disk docs efiemu font fs hello hook include io \
-       kern lib loader mmap normal partmap parttool script term util video"
-
-LC_COLLATE=C
-export LC_COLLATE
-
-for f in $EXTRA_DISTFILES; do
-    echo $f
-done
-
-dir=`dirname $0`
-cd $dir
-
-for dir in $DISTDIRS; do
-  for d in `find $dir -type d ! -name .svn ! -name .bzr | sort`; do
-    find $d -maxdepth 1 -name '*.[chSy]' -o -name '*.mk' -o -name '*.rmk' \
-      -o -name '*.rb' -o -name '*.in' -o -name '*.tex' -o -name '*.texi' \
-      -o -name '*.info' -o -name 'grub.cfg' -o -name 'README' \
-      -o -name '*.sc' -o -name 'mdate-sh' -o -name '*.sh' \
-      -o -name 'grub-dumpdevtree' -o -name '*.lua' | sort
-  done
-done
diff --git a/genemuinit.sh b/genemuinit.sh
deleted file mode 100644 (file)
index 45c15ec..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
-#
-# This gensymlist.sh is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-nm="$1"
-shift
-
-cat <<EOF
-/* This file is automatically generated by geninit.sh. DO NOT EDIT! */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "grub_emu_init.h"
-
-EOF
-
-cat <<EOF
-void
-grub_init_all (void)
-{
-EOF
-
-read mods
-for line in $mods; do
-  if ${nm} --defined-only -P -p ${line} | grep grub_mod_init > /dev/null; then
-      echo "grub_${line}_init ();" | sed 's,\.mod,,g;'
-  fi
-done
-
-cat <<EOF
-}
-EOF
-
-cat <<EOF
-void
-grub_fini_all (void)
-{
-EOF
-
-for line in $mods; do
-  if ${nm} --defined-only -P -p ${line} | grep grub_mod_fini > /dev/null; then
-      echo "grub_${line}_fini ();" | sed 's,\.mod,,g;'
-  fi
-done
-
-cat <<EOF
-}
-EOF
diff --git a/genemuinitheader.sh b/genemuinitheader.sh
deleted file mode 100644 (file)
index 6b83f59..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2005,2007  Free Software Foundation, Inc.
-#
-# This gensymlist.sh is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-nm="$1"
-shift
-
-cat <<EOF
-/* This file is automatically generated by gensymlist.sh. DO NOT EDIT! */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-EOF
-
-cat <<EOF
-void grub_init_all (void);
-void grub_fini_all (void);
-EOF
-
-read mods
-for line in $mods; do
-  if ${nm} --defined-only -P -p ${line} | grep grub_mod_init > /dev/null; then
-      echo "void grub_${line}_init (void);" | sed 's,\.mod,,g;'
-  fi
-  if ${nm} --defined-only -P -p ${line} | grep grub_mod_fini > /dev/null; then
-      echo "void grub_${line}_fini (void);" | sed 's,\.mod,,g;'
-  fi
-done
diff --git a/genfslist.sh b/genfslist.sh
deleted file mode 100644 (file)
index 6fa7e92..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2005,2008  Free Software Foundation, Inc.
-#
-# This gensymlist.sh is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-# Read source code from stdin and detect fs names.
-
-module=$1
-
-# Ignore kernel.mod.
-if test $module = kernel; then
-    exit
-fi
-
-# For now, this emits only a module name, if the module registers a filesystem.
-if grep -v "^#" | grep '^ *grub_fs_register' >/dev/null 2>&1; then
-    echo $module
-fi
diff --git a/genhandlerlist.sh b/genhandlerlist.sh
deleted file mode 100644 (file)
index e4cb0d9..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2009  Free Software Foundation, Inc.
-#
-# This script is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-# Read source code from stdin and detect command names.
-
-module=$1
-
-grep -v "^#" | sed -n \
- -e "/grub_parser_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/parser.\1: $module/;p;}"
index 43d2d1640f937b94f457f64c254043819f61166a..f0810120fb9cc535ffc23d8faf639deae972da97 100644 (file)
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
-lst="$1"
-shift
-
-header=`echo "${lst}" | sed -e "s/\.lst$/.h/g"`
-
 cat <<EOF
 /* This file is automatically generated by geninit.sh. DO NOT EDIT! */
 /*
@@ -36,22 +31,24 @@ cat <<EOF
  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <$header>
+#include <grub/emu/misc.h>
 
 EOF
 
+for mod in "$@"; do
+    echo "extern void grub_${mod}_init (void);"
+    echo "extern void grub_${mod}_fini (void);"
+done
+
 cat <<EOF
 void
 grub_init_all (void)
 {
 EOF
 
-while read line; do
-  file=`echo $line | cut -f1 -d:`
-  if echo $@ | grep $file >/dev/null; then
-    echo $line | sed -e 's/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/  grub_\1_init ();/'
-  fi
-done < ${lst}
+for mod in "$@"; do
+    echo "grub_${mod}_init ();"
+done
 
 cat <<EOF
 }
@@ -63,12 +60,9 @@ grub_fini_all (void)
 {
 EOF
 
-while read line; do
-  file=`echo $line | cut -f1 -d:`
-  if echo $@ | grep $file >/dev/null; then
-    echo $line | sed -e 's/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/  grub_\1_fini ();/'
-  fi
-done < ${lst}
+for mod in "$@"; do
+    echo "grub_${mod}_fini ();"
+done
 
 cat <<EOF
 }
diff --git a/geninitheader.sh b/geninitheader.sh
deleted file mode 100644 (file)
index 5ad1428..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2005,2007  Free Software Foundation, Inc.
-#
-# This gensymlist.sh is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-lst="$1"
-shift
-
-cat <<EOF
-/* This file is automatically generated by gensymlist.sh. DO NOT EDIT! */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-EOF
-
-cat <<EOF
-void grub_init_all (void);
-void grub_fini_all (void);
-EOF
-
-grep -v '^#' "${lst}" | sed -n '/GRUB_MOD_INIT *([a-zA-Z0-9_]*)/{s/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/void grub_\1_init (void);/;p;}'
-grep -v '^#' "${lst}" | sed -n '/GRUB_MOD_INIT *([a-zA-Z0-9_]*)/{s/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/void grub_\1_fini (void);/;p;}'
diff --git a/genkernsyms.sh.in b/genkernsyms.sh.in
deleted file mode 100644 (file)
index c5c63b2..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2002,2006,2008  Free Software Foundation, Inc.
-#
-# This gensymlist.sh is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-### The configure script will replace these variables.
-
-: ${srcdir=@srcdir@}
-: ${CC=@TARGET_CC@}
-
-u=
-grep "^#define HAVE_ASM_USCORE" config.h >/dev/null 2>&1 && u="_"
-
-$CC @TARGET_CFLAGS@ -DGRUB_SYMBOL_GENERATOR=1 -E -I. -Iinclude -I"$srcdir/include" $* \
-  | grep -v '^#' \
-  | sed -n \
-        -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/'"$u"'\1 kernel/;p;}' \
-        -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/'"$u"'\1 kernel/;p;}' \
-  | sort -u
diff --git a/genmk.rb b/genmk.rb
deleted file mode 100644 (file)
index e62dbd4..0000000
--- a/genmk.rb
+++ /dev/null
@@ -1,475 +0,0 @@
-#! /usr/bin/ruby -w
-#
-# Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
-#
-# This genmk.rb is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-module Enumerable
-  def collect_with_index
-    ret = []
-    self.each_with_index do |item, index|
-      ret.push(yield(item, index))
-    end
-    ret
-  end
-end
-
-class String
-  def to_var
-    self.gsub(/[^a-zA-Z0-9_@]/, '_')
-  end
-
-  def suffix(str)
-    self.sub(/\.[^\.]*$/, '') + '.' + str
-  end
-
-  def to_obj
-    self.sub(/\.[^\.]*$/, '').to_var + '.o'
-  end
-end
-
-class Image
-  def initialize(dir, name)
-    @dir = dir
-    @name = name
-    @rule_count = 0
-  end
-  attr_reader :dir, :name
-
-  def rule(sources)
-    prefix = @name.to_var
-    @rule_count += 1
-    exe = @name.suffix('exec')
-    objs = sources.collect do |src|
-      raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src
-      prefix + '-' + src.to_obj
-    end
-    objs_str = objs.join(' ')
-    deps = objs.collect {|obj| obj.suffix('d')}
-    deps_str = deps.join(' ')
-
-"
-clean-image-#{@name}.#{@rule_count}:
-       rm -f #{@name} #{exe} #{objs_str}
-
-CLEAN_IMAGE_TARGETS += clean-image-#{@name}.#{@rule_count}
-
-mostlyclean-image-#{@name}.#{@rule_count}:
-       rm -f #{deps_str}
-
-MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-#{@name}.#{@rule_count}
-
-ifneq ($(TARGET_APPLE_CC),1)
-#{@name}: #{exe}
-       $(OBJCOPY) -O $(#{prefix}_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn $< $@
-else
-ifneq (#{exe},kernel.exec)
-#{@name}: #{exe} ./grub-macho2img
-       ./grub-macho2img $< $@
-else
-#{@name}: #{exe} ./grub-macho2img
-       ./grub-macho2img --bss $< $@
-endif
-endif
-
-#{exe}: #{objs_str}
-       $(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS)
-
-" + objs.collect_with_index do |obj, i|
-      src = sources[i]
-      fake_obj = File.basename(src).suffix('o')
-      dep = deps[i]
-      flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end
-      extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end
-      dir = File.dirname(src)
-
-      "#{obj}: #{src} $(#{src}_DEPENDENCIES)
-       $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -DGRUB_FILE=\\\"#{src}\\\" -MD -c -o $@ $<
--include #{dep}
-
-"
-    end.join('')
-  end
-end
-
-# Use PModule instead Module, to avoid name conflicting.
-class PModule
-  def initialize(dir, name)
-    @dir = dir
-    @name = name
-    @rule_count = 0
-  end
-  attr_reader :dir, :name
-
-  def rule(sources)
-    prefix = @name.to_var
-    @rule_count += 1
-    objs = sources.collect do |src|
-      raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src
-      prefix + '-' + src.to_obj
-    end
-    objs_str = objs.join(' ')
-    deps = objs.collect {|obj| obj.suffix('d')}
-    deps_str = deps.join(' ')
-    pre_obj = 'pre-' + @name.suffix('o')
-    mod_src = 'mod-' + @name.suffix('c')
-    mod_obj = mod_src.suffix('o')
-    defsym = 'def-' + @name.suffix('lst')
-    undsym = 'und-' + @name.suffix('lst')
-    mod_name = File.basename(@name, '.mod')
-    symbolic_name = mod_name.sub(/\.[^\.]*$/, '')
-
-"
-clean-module-#{@name}.#{@rule_count}:
-       rm -f #{@name} #{mod_obj} #{mod_src} #{pre_obj} #{objs_str} #{undsym}
-
-CLEAN_MODULE_TARGETS += clean-module-#{@name}.#{@rule_count}
-
-clean-module-#{@name}-symbol.#{@rule_count}:
-       rm -f #{defsym}
-
-CLEAN_MODULE_TARGETS += clean-module-#{@name}-symbol.#{@rule_count}
-DEFSYMFILES += #{defsym}
-mostlyclean-module-#{@name}.#{@rule_count}:
-       rm -f #{deps_str}
-
-MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-#{@name}.#{@rule_count}
-UNDSYMFILES += #{undsym}
-
-ifeq ($(TARGET_NO_MODULES), yes)
-#{@name}: #{pre_obj} $(TARGET_OBJ2ELF)
-       -rm -f $@
-       $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ #{pre_obj}
-       if test ! -z \"$(TARGET_OBJ2ELF)\"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
-       if test x$(TARGET_NO_STRIP) != xyes ; then $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@; fi
-else
-ifneq ($(TARGET_APPLE_CC),1)
-#{@name}: #{pre_obj} #{mod_obj} $(TARGET_OBJ2ELF)
-       -rm -f $@
-       $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ #{pre_obj} #{mod_obj}
-       if test ! -z \"$(TARGET_OBJ2ELF)\"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
-       if test x$(TARGET_NO_STRIP) != xyes ; then $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@; fi
-else
-#{@name}: #{pre_obj} #{mod_obj} $(TARGET_OBJ2ELF)
-       -rm -f $@
-       -rm -f $@.bin
-       $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin #{pre_obj} #{mod_obj}
-       $(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -ew2030 -ew2050 -nu -nd $@.bin $@
-       -rm -f $@.bin
-endif
-endif
-
-#{pre_obj}: $(#{prefix}_DEPENDENCIES) #{objs_str}
-       -rm -f $@
-       $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ #{objs_str}
-
-#{mod_obj}: #{mod_src}
-       $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(#{prefix}_CFLAGS) -DGRUB_FILE=\\\"#{mod_src}\\\" -c -o $@ $<
-
-#{mod_src}: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
-       sh $(srcdir)/genmodsrc.sh '#{mod_name}' $< > $@ || (rm -f $@; exit 1)
-
-ifneq ($(TARGET_APPLE_CC),1)
-#{defsym}: #{pre_obj}
-       $(NM) -g --defined-only -P -p $< | sed 's/^\\([^ ]*\\).*/\\1 #{mod_name}/' > $@
-else
-#{defsym}: #{pre_obj}
-       $(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\\([^ ]*\\).*/\\1 #{mod_name}/' > $@
-endif
-
-#{undsym}: #{pre_obj}
-       echo '#{mod_name}' > $@
-       $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
-
-" + objs.collect_with_index do |obj, i|
-      src = sources[i]
-      fake_obj = File.basename(src).suffix('o')
-      extra_target = obj.sub(/\.[^\.]*$/, '') + '-extra'
-      command = 'cmd-' + obj.suffix('lst')
-      fs = 'fs-' + obj.suffix('lst')
-      partmap = 'partmap-' + obj.suffix('lst')
-      handler = 'handler-' + obj.suffix('lst')
-      terminal = 'terminal-' + obj.suffix('lst')
-      parttool = 'parttool-' + obj.suffix('lst')
-      video = 'video-' + obj.suffix('lst')
-      dep = deps[i]
-      flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end
-      extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end
-      dir = File.dirname(src)
-
-      "#{obj}: #{src} $(#{src}_DEPENDENCIES)
-       $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -DGRUB_FILE=\\\"#{src}\\\" -MD -c -o $@ $<
--include #{dep}
-
-clean-module-#{extra_target}.#{@rule_count}:
-       rm -f #{command} #{fs} #{partmap} #{handler} #{parttool} #{video} #{terminal}
-
-CLEAN_MODULE_TARGETS += clean-module-#{extra_target}.#{@rule_count}
-
-COMMANDFILES += #{command}
-FSFILES += #{fs}
-PARTTOOLFILES += #{parttool}
-PARTMAPFILES += #{partmap}
-HANDLERFILES += #{handler}
-TERMINALFILES += #{terminal}
-VIDEOFILES += #{video}
-
-#{command}: #{src} $(#{src}_DEPENDENCIES) gencmdlist.sh
-       set -e; \
-         $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
-         | sh $(srcdir)/gencmdlist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
-
-#{fs}: #{src} $(#{src}_DEPENDENCIES) genfslist.sh
-       set -e; \
-         $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
-         | sh $(srcdir)/genfslist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
-
-#{parttool}: #{src} $(#{src}_DEPENDENCIES) genparttoollist.sh
-       set -e; \
-         $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
-         | sh $(srcdir)/genparttoollist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
-
-#{partmap}: #{src} $(#{src}_DEPENDENCIES) genpartmaplist.sh
-       set -e; \
-         $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
-         | sh $(srcdir)/genpartmaplist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
-
-#{handler}: #{src} $(#{src}_DEPENDENCIES) genhandlerlist.sh
-       set -e; \
-         $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
-         | sh $(srcdir)/genhandlerlist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
-
-#{terminal}: #{src} $(#{src}_DEPENDENCIES) genterminallist.sh
-       set -e; \
-         $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
-         | sh $(srcdir)/genterminallist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
-
-#{video}: #{src} $(#{src}_DEPENDENCIES) genvideolist.sh
-       set -e; \
-         $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
-         | sh $(srcdir)/genvideolist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
-
-"
-    end.join('')
-  end
-end
-
-class Utility
-  def initialize(dir, name)
-    @dir = dir
-    @name = name
-    @rule_count = 0
-  end
-  def print_tail()
-    prefix = @name.to_var
-    print "#{@name}: $(#{prefix}_DEPENDENCIES) $(#{prefix}_OBJECTS)
-       $(CC) -o $@ $(#{prefix}_OBJECTS) $(LDFLAGS) $(#{prefix}_LDFLAGS)
-
-"
-  end
-  attr_reader :dir, :name
-
-  def rule(sources)
-    prefix = @name.to_var
-    @rule_count += 1
-    objs = sources.collect do |src|
-      raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src
-      prefix + '-' + src.to_obj
-    end
-    objs_str = objs.join(' ');
-    deps = objs.collect {|obj| obj.suffix('d')}
-    deps_str = deps.join(' ');
-
-    "
-clean-utility-#{@name}.#{@rule_count}:
-       rm -f #{@name}$(EXEEXT) #{objs_str}
-
-CLEAN_UTILITY_TARGETS += clean-utility-#{@name}.#{@rule_count}
-
-mostlyclean-utility-#{@name}.#{@rule_count}:
-       rm -f #{deps_str}
-
-MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-#{@name}.#{@rule_count}
-
-#{prefix}_OBJECTS += #{objs_str}
-
-" + objs.collect_with_index do |obj, i|
-      src = sources[i]
-      fake_obj = File.basename(src).suffix('o')
-      dep = deps[i]
-      dir = File.dirname(src)
-
-      "#{obj}: #{src} $(#{src}_DEPENDENCIES)
-       $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(#{prefix}_CFLAGS) -DGRUB_FILE=\\\"#{src}\\\" -MD -c -o $@ $<
--include #{dep}
-
-"
-    end.join('')
-  end
-end
-
-class Program
-  def initialize(dir, name)
-    @dir = dir
-    @name = name
-  end
-  attr_reader :dir, :name
-
-  def print_tail()
-    prefix = @name.to_var
-    print "CLEANFILES += #{@name} $(#{prefix}_OBJECTS)
-ifeq ($(#{prefix}_RELOCATABLE),yes)
-#{@name}: $(#{prefix}_DEPENDENCIES) $(#{prefix}_OBJECTS)
-       $(TARGET_CC) -Wl,-r,-d -o $@ $(#{prefix}_OBJECTS) $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS)
-       if test x$(TARGET_NO_STRIP) != xyes ; then $(STRIP) --strip-unneeded -K start -R .note -R .comment $@; fi
-else
-#{@name}: $(#{prefix}_DEPENDENCIES) $(#{prefix}_OBJECTS)
-       $(TARGET_CC) -o $@ $(#{prefix}_OBJECTS) $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS)
-       if test x$(TARGET_NO_STRIP) != xyes ; then $(STRIP) -R .rel.dyn -R .reginfo -R .note -R .comment $@; fi
-endif
-
-"
-  end
-
-  def rule(sources)
-    prefix = @name.to_var
-    objs = sources.collect do |src|
-      raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src
-      prefix + '-' + src.to_obj
-    end
-    deps = objs.collect {|obj| obj.suffix('d')}
-    deps_str = deps.join(' ');
-
-    "MOSTLYCLEANFILES += #{deps_str}
-
-" + objs.collect_with_index do |obj, i|
-      src = sources[i]
-      fake_obj = File.basename(src).suffix('o')
-      dep = deps[i]
-      flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end
-      extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end
-      dir = File.dirname(src)
-
-      "#{obj}: #{src} $(#{src}_DEPENDENCIES)
-       $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -DGRUB_FILE=\\\"#{src}\\\" -MD -c -o $@ $<
-
--include #{dep}
-
-#{prefix}_OBJECTS += #{obj}
-"
-    end.join('')
-  end
-end
-
-class Script
-  def initialize(dir, name)
-    @dir = dir
-    @name = name
-  end
-  attr_reader :dir, :name
-
-  def rule(sources)
-    if sources.length != 1
-      raise "only a single source file must be specified for a script"
-    end
-    src = sources[0]
-    if /\.in$/ !~ src
-      raise "unknown source file `#{src}'"
-    end
-
-    "CLEANFILES += #{@name}
-
-#{@name}: #{src} $(#{src}_DEPENDENCIES) config.status
-       ./config.status --file=-:#{src} | sed -e 's,@pkglib_DATA@,$(pkglib_DATA),g' > $@
-       chmod +x $@
-
-"
-  end
-end
-
-images = []
-utils = []
-pmodules = []
-programs = []
-scripts = []
-
-l = gets
-print l
-print "# Generated by genmk.rb, please don't edit!\n"
-
-cont = false
-str = nil
-while l = gets
-  if cont
-    str += l
-  else
-    str = l
-  end
-
-  print l
-  cont = (/\\$/ =~ l)
-  unless cont
-    str.gsub!(/\\\n/, ' ')
-
-    if /^([a-zA-Z0-9_]+)\s*\+?=\s*(.*?)\s*$/ =~ str
-      var, args = $1, $2
-
-      if var =~ /^([a-zA-Z0-9_]+)_([A-Z]+)$/
-       prefix, type = $1, $2
-
-       case type
-       when 'IMAGES'
-         images += args.split(/\s+/).collect do |img|
-           Image.new(prefix, img)
-         end
-
-       when 'MODULES'
-         pmodules += args.split(/\s+/).collect do |pmod|
-           PModule.new(prefix, pmod)
-         end
-
-       when 'UTILITIES'
-         utils += args.split(/\s+/).collect do |util|
-           Utility.new(prefix, util)
-         end
-
-       when 'PROGRAMS'
-         programs += args.split(/\s+/).collect do |prog|
-           Program.new(prefix, prog)
-         end
-
-       when 'SCRIPTS'
-         scripts += args.split(/\s+/).collect do |script|
-           Script.new(prefix, script)
-         end
-
-       when 'SOURCES'
-         if img = images.detect() {|i| i.name.to_var == prefix}
-           print img.rule(args.split(/\s+/))
-         elsif pmod = pmodules.detect() {|m| m.name.to_var == prefix}
-           print pmod.rule(args.split(/\s+/))
-         elsif util = utils.detect() {|u| u.name.to_var == prefix}
-           print util.rule(args.split(/\s+/))
-         elsif program = programs.detect() {|u| u.name.to_var == prefix}
-           print program.rule(args.split(/\s+/))
-         elsif script = scripts.detect() {|s| s.name.to_var == prefix}
-           print script.rule(args.split(/\s+/))
-         end
-       end
-      end
-
-    end
-
-  end
-
-end
-utils.each {|util| util.print_tail()}
-programs.each {|program| program.print_tail()}
-
diff --git a/genmoddep.awk b/genmoddep.awk
deleted file mode 100644 (file)
index 48419a0..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#! /usr/bin/awk -f
-#
-# Copyright (C) 2006  Free Software Foundation, Inc.
-#
-# This genmoddep.awk is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-# Read defined symbols from stdin.
-BEGIN {
-  while (getline <"/dev/stdin") {
-    symtab[$1] = $2
-  }
-}
-
-# The first line contains a module name.
-FNR == 1 {
-  module = $1
-  next
-};
-
-# The rest is undefined symbols.
-{
-  if ($1 in symtab) {
-    modtab[module] = modtab[module] " " symtab[$1];
-  }
-  else if ($1 != "__gnu_local_gp") {
-    printf "%s in %s is not defined\n", $1, module >"/dev/stderr";
-    error++;
-  }
-}
-
-# Output the result.
-END {
-  if (error >= 1)
-    exit 1;
-
-  for (mod in modtab) {
-    # Remove duplications.
-    split(modtab[mod], depmods, " ");
-    for (depmod in uniqmods) {
-      delete uniqmods[depmod];
-    }
-    for (i in depmods) {
-      depmod = depmods[i];
-      # Ignore kernel, as always loaded.
-      if (depmod != "kernel" && depmod != mod)
-       uniqmods[depmod] = 1;
-    }
-    modlist = ""
-    for (depmod in uniqmods) {
-      modlist = modlist " " depmod;
-    }
-    printf "%s:%s\n", mod, modlist;
-  }
-}
diff --git a/genmodsrc.sh b/genmodsrc.sh
deleted file mode 100644 (file)
index 2d42055..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2002,2007  Free Software Foundation, Inc.
-#
-# This genmodsrc.sh is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-set -e
-
-mod_name="$1"
-deps="$2"
-
-cat <<EOF
-/* This file is automatically generated by genmodsrc.sh. DO NOT EDIT! */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2007 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-
-EOF
-
-echo "GRUB_MOD_NAME(${mod_name});"
-
-for mod in `grep "^${mod_name}:" ${deps} | sed 's/^[^:]*://'`; do
-  echo "GRUB_MOD_DEP(${mod});"
-done
diff --git a/genpartmaplist.sh b/genpartmaplist.sh
deleted file mode 100644 (file)
index fceb0f8..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2005, 2008  Free Software Foundation, Inc.
-#
-# This script is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-# Read source code from stdin and detect partmap names.
-
-module=$1
-
-# Ignore kernel.mod.
-if test $module = kernel; then
-    exit
-fi
-
-# For now, this emits only a module name, if the module registers a partition map.
-if grep -v "^#" | grep '^ *grub_partition_map_register' >/dev/null 2>&1; then
-    echo $module
-fi
diff --git a/genparttoollist.sh b/genparttoollist.sh
deleted file mode 100644 (file)
index 48a0efe..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2009  Free Software Foundation, Inc.
-#
-# This gensymlist.sh is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-# Read source code from stdin and detect parttool names.
-
-module=$1
-
-grep -v "^#" | sed -n \
- -e "/grub_parttool_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $module/;p;}"
diff --git a/gensymlist.sh.in b/gensymlist.sh.in
deleted file mode 100644 (file)
index 3c3ddfa..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2002,2006,2007,2008  Free Software Foundation, Inc.
-#
-# This gensymlist.sh.in is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-### The configure script will replace these variables.
-
-: ${srcdir=@srcdir@}
-: ${CC=@TARGET_CC@}
-
-
-cat <<EOF
-/* This file is automatically generated by gensymlist.sh. DO NOT EDIT! */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-EOF
-
-for i in $*; do
-  echo "#include <$i>"
-done
-
-cat <<EOF
-
-#define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; }
-
-void
-grub_register_exported_symbols (void)
-{
-EOF
-
-cat <<EOF
-  struct symtab { const char *name; void *addr; };
-  struct symtab *p;
-  static struct symtab tab[] =
-    {
-EOF
-
-$CC @TARGET_CFLAGS@ -DGRUB_SYMBOL_GENERATOR=1 -E -I. -Iinclude -I"$srcdir/include" $* \
-  | grep -v '^#' \
-  | sed -n \
-        -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/      {"\1", \1},/;p;}' \
-        -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/      {"\1", \&\1},/;p;}' \
-  | sort -u
-
-cat <<EOF
-      {0, 0}
-    };
-
-  COMPILE_TIME_ASSERT (sizeof (tab) > sizeof (tab[0]));
-  for (p = tab; p->name; p++)
-    grub_dl_register_symbol (p->name, p->addr, 0);
-}
-EOF
diff --git a/genterminallist.sh b/genterminallist.sh
deleted file mode 100644 (file)
index 60f5b91..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2009,2010  Free Software Foundation, Inc.
-#
-# This script is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-# Read source code from stdin and detect command names.
-
-module=$1
-
-grep -v "^#" | sed -n \
- -e "/grub_term_register_input *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $module/;p;}" \
- -e "/grub_term_register_output *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $module/;p;}" \
diff --git a/gentpl.py b/gentpl.py
new file mode 100644 (file)
index 0000000..214b58a
--- /dev/null
+++ b/gentpl.py
@@ -0,0 +1,460 @@
+#! /usr/bin/python
+
+#
+# This is the python script used to generate Makefile.tpl
+#
+
+GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
+                   "i386_ieee1275", "x86_64_efi", "mips_yeeloong", "sparc64_ieee1275",
+                   "powerpc_ieee1275" ]
+
+GROUPS = {}
+GROUPS["i386"]    = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_ieee1275" ]
+GROUPS["x86_64"]  = [ "x86_64_efi" ]
+GROUPS["mips"]    = [ "mips_yeeloong" ]
+GROUPS["sparc64"] = [ "sparc64_ieee1275" ]
+GROUPS["powerpc"] = [ "powerpc_ieee1275" ]
+GROUPS["x86"]     = GROUPS["i386"] + GROUPS["x86_64"]
+GROUPS["x86_efi"] = [ "i386_efi", "x86_64_efi" ]
+GROUPS["common"]  = GRUB_PLATFORMS[:]
+GROUPS["nonemu"]  = GRUB_PLATFORMS[:]
+GROUPS["nonemu"].remove("emu")
+
+#
+# Create platform => groups reverse map, where groups covering that
+# platform are ordered by their sizes
+#
+RMAP = {}
+for platform in GRUB_PLATFORMS:
+    # initialize with platform itself as a group
+    RMAP[platform] = [ platform ]
+
+    for k in GROUPS.keys():
+        v = GROUPS[k]
+        # skip groups that don't cover this platform
+        if platform not in v: continue
+
+        bigger = []
+        smaller = []
+        # partition currently known groups based on their size
+        for group in RMAP[platform]:
+            if group in GRUB_PLATFORMS: smaller.append(group)
+            elif len(GROUPS[group]) < len(v): smaller.append(group)
+            else: bigger.append(group)
+        # insert in the middle
+        RMAP[platform] = smaller + [ k ] + bigger
+
+#
+# Global variables
+#
+GVARS = []
+
+def gvar_add(var, value):
+    if var not in GVARS:
+        GVARS.append(var)
+    return var + " += " + value + "\n"
+
+def global_variable_initializers():
+    r = ""
+    for var in GVARS:
+        r += var + " ?= \n"
+    return r
+
+#
+# Per PROGRAM/SCRIPT variables 
+#
+
+def var_set(var, value):
+    return var + "  = " + value + "\n"
+
+def var_add(var, value):
+    return var + " += " + value + "\n"
+
+#
+# Autogen constructs
+#
+
+def if_tag(tag, closure):
+    return "[+ IF " + tag + " +]" + closure() + "[+ ENDIF +]"
+
+def if_tag_defined(tag, closure):
+    return "[+ IF " + tag + " defined +]" + closure() + "[+ ENDIF +]"
+
+def for_tag(tag, closure):
+    return "[+ FOR ." + tag + " +]" + closure() + "[+ ENDFOR +]"
+
+def collect_values(tag, prefix=""):
+    return for_tag(tag, lambda: prefix + "[+ ." + tag + " +] ")
+
+def each_group(platform, suffix, closure):
+    r = None
+    for group in RMAP[platform]:
+        if r == None:
+            r = "[+ IF ." + group + suffix + " +]"
+        else:
+            r += "[+ ELIF ." + group + suffix + " +]"
+            
+        r += closure(group)
+
+    if r:
+        r += "[+ ELSE +]"
+        r += closure(None)
+        r += "[+ ENDIF +]"
+    else:
+        r = closure(None)
+
+    return r
+
+def each_platform(closure):
+    r = ""
+    for platform in GRUB_PLATFORMS:
+        for group in RMAP[platform]:
+            if group == RMAP[platform][0]:
+                r += "[+ IF ." + group + " defined +]"
+            else:
+                r += "[+ ELIF ." + group + " defined +]"
+
+            r += "if COND_" + platform + "\n"
+            r += closure(platform)
+            r += "endif\n"
+        r += "[+ ENDIF +]"
+    return r
+
+def canonical_name():   return "[+ % name `echo -n %s | sed -e 's/[^0-9A-Za-z@_]/_/g'` +]"
+def canonical_module(): return canonical_name() + "_module"
+def canonical_kernel(): return canonical_name() + "_exec"
+def canonical_image(): return canonical_name() + "_image"
+
+def shared_sources(prefix=""):        return collect_values("shared", prefix)
+def shared_nodist_sources(prefix=""): return collect_values("nodist_shared", prefix)
+
+def default_sources(prefix=""):        return collect_values("source", prefix)
+def default_nodist_sources(prefix=""): return collect_values("nodist", prefix)
+def default_ldadd():     return collect_values("ldadd")
+def default_cflags():    return collect_values("cflags")
+def default_ldflags():   return collect_values("ldflags")
+def default_cppflags():  return collect_values("cppflags")
+def default_ccasflags(): return collect_values("ccasflags")
+
+def group_sources(group, prefix=""):        return collect_values(group, prefix) if group else default_sources(prefix)
+def group_nodist_sources(group, prefix=""): return collect_values(group + "_nodist", prefix) if group else default_nodist_sources(prefix)
+
+def platform_sources(platform, prefix=""):        return each_group(platform, "", lambda g: collect_values(g, prefix) if g else default_sources(prefix))
+def platform_nodist_sources(platform, prefix=""): return each_group(platform, "_nodist", lambda g: collect_values(g + "_nodist", prefix) if g else default_nodist_sources(prefix))
+
+def platform_ldadd(platform):     return each_group(platform, "_ldadd", lambda g: collect_values(g + "_ldadd") if g else default_ldadd())
+def platform_cflags(platform):    return each_group(platform, "_cflags", lambda g: collect_values(g + "_cflags") if g else default_cflags())
+def platform_ldflags(platform):   return each_group(platform, "_ldflags", lambda g: collect_values(g + "_ldflags") if g else default_ldflags())
+def platform_cppflags(platform):  return each_group(platform, "_cppflags", lambda g: collect_values(g + "_cppflags") if g else default_cppflags())
+def platform_ccasflags(platform): return each_group(platform, "_ccasflags", lambda g: collect_values(g + "_ccasflags") if g else default_ccasflags())
+def platform_format(platform):    return each_group(platform, "_format", lambda g: collect_values(g + "_format") if g else "binary")
+
+def module(platform):
+    r  = gvar_add("noinst_PROGRAMS", "[+ name +].module")
+    r += gvar_add("MODULE_FILES", "[+ name +].module")
+
+    r += var_set(canonical_module() + "_SOURCES", platform_sources(platform) + "## platform sources")
+    r += var_add(canonical_module() + "_SOURCES", shared_sources() + "## shared sources")
+    r += var_set("nodist_" + canonical_module() + "_SOURCES", platform_nodist_sources(platform) + "## platform nodist sources")
+    r += var_add("nodist_" + canonical_module() + "_SOURCES", shared_nodist_sources() + "## shared nodist sources")
+    r += var_set(canonical_module() + "_LDADD", platform_ldadd(platform))
+    r += var_set(canonical_module() + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_MODULE) " + platform_cflags(platform))
+    r += var_set(canonical_module() + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_MODULE) " + platform_ldflags(platform))
+    r += var_set(canonical_module() + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_MODULE) " + platform_cppflags(platform))
+    r += var_set(canonical_module() + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_MODULE) " + platform_ccasflags(platform))
+
+    r += gvar_add("BUILT_SOURCES", "$(nodist_" + canonical_module() + "_SOURCES)")
+    r += gvar_add("CLEANFILES", "$(nodist_" + canonical_module() + "_SOURCES)")
+
+    r += gvar_add("DEF_FILES", "def-[+ name +].lst")
+    r += gvar_add("UND_FILES", "und-[+ name +].lst")
+    r += gvar_add("MOD_FILES", "[+ name +].mod")
+    r += gvar_add("platform_DATA", "[+ name +].mod")
+    r += gvar_add("CLEANFILES", "def-[+ name +].lst und-[+ name +].lst mod-[+ name +].c mod-[+ name +].o [+ name +].mod")
+
+    r += gvar_add("COMMAND_FILES", "command-[+ name +].lst")
+    r += gvar_add("FS_FILES", "fs-[+ name +].lst")
+    r += gvar_add("VIDEO_FILES", "video-[+ name +].lst")
+    r += gvar_add("PARTMAP_FILES", "partmap-[+ name +].lst")
+    r += gvar_add("HANDLER_FILES", "handler-[+ name +].lst")
+    r += gvar_add("PARTTOOL_FILES", "parttool-[+ name +].lst")
+    r += gvar_add("TERMINAL_FILES", "terminal-[+ name +].lst")
+    r += gvar_add("CLEANFILES", "command-[+ name +].lst fs-[+ name +].lst")
+    r += gvar_add("CLEANFILES", "handler-[+ name +].lst terminal-[+ name +].lst")
+    r += gvar_add("CLEANFILES", "video-[+ name +].lst partmap-[+ name +].lst parttool-[+ name +].lst")
+
+    r += """
+[+ name +].pp: $(""" + canonical_module() + """_SOURCES) $(nodist_""" + canonical_module() + """_SOURCES)
+       $(TARGET_CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + canonical_module() + """_CPPFLAGS) $(CPPFLAGS) $^ > $@ || (rm -f $@; exit 1)
+
+def-[+ name +].lst: [+ name +].module
+       if test x$(USE_APPLE_CC_FIXES) = xyes; then \
+         $(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]' | sed "s/^\\([^ ]*\\).*/\\1 [+ name +]/" >> $@; \
+       else \
+         $(NM) -g --defined-only -P -p $< | sed "s/^\\([^ ]*\\).*/\\1 [+ name +]/" >> $@; \
+       fi
+
+und-[+ name +].lst: [+ name +].module
+       $(NM) -u -P -p $< | sed "s/^\\([^ ]*\\).*/\\1 [+ name +]/" >> $@
+
+mod-[+ name +].c: [+ name +].module $(top_builddir)/moddep.lst $(top_srcdir)/genmodsrc.sh
+       sh $(top_srcdir)/genmodsrc.sh [+ name +] $(top_builddir)/moddep.lst > $@ || (rm -f $@; exit 1)
+
+mod-[+ name +].o: mod-[+ name +].c
+       $(TARGET_CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS_MODULE) $(CPPFLAGS) $(CFLAGS_MODULE) $(CFLAGS) -c -o $@ $<
+
+[+ name +].mod: [+ name +].module mod-[+ name +].o
+       if test x$(USE_APPLE_CC_FIXES) = xyes; then \
+         $(CCLD) $(LDFLAGS_MODULE) $(LDFLAGS) -o $@.bin $^; \
+         $(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@; \
+         rm -f $@.bin; \
+       else \
+         $(CCLD) -o $@ $(LDFLAGS_MODULE) $(LDFLAGS) $^; \
+         if test ! -z '$(TARGET_OBJ2ELF)'; then $(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi; \
+         $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@; \
+       fi
+
+command-[+ name +].lst: [+ name +].pp $(top_srcdir)/gencmdlist.sh
+       cat $< | sh $(top_srcdir)/gencmdlist.sh [+ name +] > $@ || (rm -f $@; exit 1)
+
+fs-[+ name +].lst: [+ name +].pp $(top_srcdir)/genfslist.sh
+       cat $< | sh $(top_srcdir)/genfslist.sh [+ name +] > $@ || (rm -f $@; exit 1)
+
+video-[+ name +].lst: [+ name +].pp $(top_srcdir)/genvideolist.sh
+       cat $< | sh $(top_srcdir)/genvideolist.sh [+ name +] > $@ || (rm -f $@; exit 1)
+
+partmap-[+ name +].lst: [+ name +].pp $(top_srcdir)/genpartmaplist.sh
+       cat $< | sh $(top_srcdir)/genpartmaplist.sh [+ name +] > $@ || (rm -f $@; exit 1)
+
+parttool-[+ name +].lst: [+ name +].pp $(top_srcdir)/genparttoollist.sh
+       cat $< | sh $(top_srcdir)/genparttoollist.sh [+ name +] > $@ || (rm -f $@; exit 1)
+
+handler-[+ name +].lst: [+ name +].pp $(top_srcdir)/genhandlerlist.sh
+       cat $< | sh $(top_srcdir)/genhandlerlist.sh [+ name +] > $@ || (rm -f $@; exit 1)
+
+terminal-[+ name +].lst: [+ name +].pp $(top_srcdir)/genterminallist.sh
+       cat $< | sh $(top_srcdir)/genterminallist.sh [+ name +] > $@ || (rm -f $@; exit 1)
+"""
+    return r
+
+def rule(target, source, cmd):
+    if cmd[0] == "\n":
+        return "\n" + target + ": " + source + cmd.replace("\n", "\n\t") + "\n"
+    else:
+        return "\n" + target + ": " + source + "\n\t" + cmd.replace("\n", "\n\t") + "\n"
+
+def image_nostrip(platform):
+    return if_tag_defined("image_nostrip." + platform, lambda: rule("[+ name +].img", "[+ name +].exec", "cp $< $@"))
+
+def image_strip(platform):
+    return if_tag_defined("image_strip." + platform, lambda: rule("[+ name +].img", "[+ name +].exec", "$(STRIP) -o $@ -R .rel.dyn -R .reginfo -R .note -R .comment $<"))
+
+def image_strip_keep_kernel(platform):
+    return if_tag_defined("image_strip_keep_kernel." + platform, lambda: rule("[+ name +].img", "[+ name +].exec", "$(STRIP) -o $@ --strip-unneeded -K start -R .note -R .comment $<"))
+
+def image_strip_macho2img(platform):
+    return if_tag_defined("image_strip_macho2img." + platform, lambda: rule("[+ name +].img", "[+ name +].exec", """
+if test "x$(TARGET_APPLE_CC)" = x1; then \
+  $(MACHO2IMG) --bss $< $@ || exit 1; \
+else \
+  $(STRIP) -o $@ -O binary --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn $< || exit 1; \
+fi
+"""))
+
+def kernel(platform):
+    r  = gvar_add("noinst_PROGRAMS", "[+ name +].exec")
+    r += var_set(canonical_kernel() + "_SOURCES", platform_sources(platform))
+    r += var_add(canonical_kernel() + "_SOURCES", shared_sources())
+    r += var_set("nodist_" + canonical_kernel() + "_SOURCES", platform_nodist_sources(platform) + "## platform nodist sources")
+    r += var_add("nodist_" + canonical_kernel() + "_SOURCES", shared_nodist_sources() + "## shared nodist sources")
+    r += var_set(canonical_kernel() + "_LDADD", platform_ldadd(platform))
+    r += var_set(canonical_kernel() + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_KERNEL) " + platform_cflags(platform))
+    r += var_set(canonical_kernel() + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_KERNEL) " + platform_ldflags(platform))
+    r += var_set(canonical_kernel() + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) " + platform_cppflags(platform))
+    r += var_set(canonical_kernel() + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_KERNEL) " + platform_ccasflags(platform))
+
+    r += gvar_add("BUILT_SOURCES", "$(nodist_" + canonical_kernel() + "_SOURCES)")
+    r += gvar_add("CLEANFILES", "$(nodist_" + canonical_kernel() + "_SOURCES)")
+
+    r += gvar_add("platform_DATA", "[+ name +].img")
+    r += image_nostrip(platform)
+    r += image_strip(platform)
+    r += image_strip_keep_kernel(platform)
+    r += image_strip_macho2img(platform)
+    return r
+
+def image(platform):
+    r  = gvar_add("noinst_PROGRAMS", "[+ name +].image")
+    r += var_set(canonical_image() + "_SOURCES", platform_sources(platform))
+    r += var_add(canonical_image() + "_SOURCES", shared_sources())
+    r += var_set("nodist_" + canonical_image() + "_SOURCES", platform_nodist_sources(platform) + "## platform nodist sources")
+    r += var_add("nodist_" + canonical_image() + "_SOURCES", shared_nodist_sources() + "## shared nodist sources")
+    r += var_set(canonical_image() + "_LDADD", platform_ldadd(platform))
+    r += var_set(canonical_image() + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_IMAGE) " + platform_cflags(platform))
+    r += var_set(canonical_image() + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_IMAGE) " + platform_ldflags(platform))
+    r += var_set(canonical_image() + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_IMAGE) " + platform_cppflags(platform))
+    r += var_set(canonical_image() + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_IMAGE) " + platform_ccasflags(platform))
+
+    r += gvar_add("BUILT_SOURCES", "$(nodist_" + canonical_image() + "_SOURCES)")
+    r += gvar_add("CLEANFILES", "$(nodist_" + canonical_image() + "_SOURCES)")
+
+    r += gvar_add("platform_DATA", "[+ name +].img")
+    r += rule("[+ name +].img", "[+ name +].image", """
+if test x$(USE_APPLE_CC_FIXES) = xyes; then \
+  $(MACHO2IMG) $< $@; \
+else \
+  $(OBJCOPY) -O """ + platform_format(platform) + """ --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn $< $@; \
+fi
+""")
+    return r
+
+def library(platform):
+    r  = gvar_add("noinst_LIBRARIES", "[+ name +]")
+    r += var_set(canonical_name() + "_SOURCES", platform_sources(platform))
+    r += var_add(canonical_name() + "_SOURCES", shared_sources())
+    r += var_set("nodist_" + canonical_name() + "_SOURCES", platform_nodist_sources(platform))
+    r += var_add("nodist_" + canonical_name() + "_SOURCES", shared_nodist_sources())
+    r += var_set(canonical_name() + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_LIBRARY) " + platform_cflags(platform))
+    r += var_set(canonical_name() + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_LIBRARY) " + platform_cppflags(platform))
+    r += var_set(canonical_name() + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_LIBRARY) " + platform_ccasflags(platform))
+
+    r += gvar_add("BUILT_SOURCES", "$(nodist_" + canonical_name() + "_SOURCES)")
+    r += gvar_add("CLEANFILES", "$(nodist_" + canonical_name() + "_SOURCES)")
+
+    return r
+
+def installdir(default="bin"):
+    return "[+ IF installdir +][+ installdir +][+ ELSE +]" + default + "[+ ENDIF +]"
+
+def manpage():
+    r  = "if COND_MAN_PAGES\n"
+    r += "man_MANS += [+ name +].[+ mansection +]\n"
+    r += rule("[+ name +].[+ mansection +]", "", """
+$(MAKE) $(AM_MAKEFLAGS) [+ name +]
+chmod a+x [+ name +]
+$(HELP2MAN) --section=[+ mansection +] -o $@ ./[+ name +]
+""")
+    r += gvar_add("CLEANFILES", "[+ name +].[+ mansection +]")
+    r += "endif\n"
+    return r
+
+def program(platform, test=False):
+    if test:
+        r = gvar_add("check_PROGRAMS", "[+ name +]")
+    else:
+        r  = gvar_add(installdir() + "_PROGRAMS", "[+ name +]")
+
+    r += var_set(canonical_name() + "_SOURCES", platform_sources(platform))
+    r += var_add(canonical_name() + "_SOURCES", shared_sources())
+    r += var_set("nodist_" + canonical_name() + "_SOURCES", platform_nodist_sources(platform))
+    r += var_add("nodist_" + canonical_name() + "_SOURCES", shared_nodist_sources())
+    r += var_set(canonical_name() + "_LDADD", platform_ldadd(platform))
+    r += var_set(canonical_name() + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_PROGRAM) " + platform_cflags(platform))
+    r += var_set(canonical_name() + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_PROGRAM) " + platform_ldflags(platform))
+    r += var_set(canonical_name() + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_PROGRAM) " + platform_cppflags(platform))
+    r += var_set(canonical_name() + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_PROGRAM) " + platform_ccasflags(platform))
+
+    r += gvar_add("BUILT_SOURCES", "$(nodist_" + canonical_name() + "_SOURCES)")
+    r += gvar_add("CLEANFILES", "$(nodist_" + canonical_name() + "_SOURCES)")
+
+    if test:
+        r += if_tag_defined("enable", lambda: gvar_add("TESTS", "[+ name +]"))
+    else:
+        r += if_tag("mansection", lambda: manpage())
+
+    return r
+
+def test_program(platform):
+    return program(platform, True)
+
+def data(platform):
+    return gvar_add(installdir() + "_DATA", platform_sources(platform))
+
+def script(platform, test=False):
+    if test:
+        r = gvar_add("check_SCRIPTS", "[+ name +]")
+    else:
+        r  = gvar_add(installdir() + "_SCRIPTS", "[+ name +]")
+
+    r += rule("[+ name +]", "$(top_builddir)/config.status " + platform_sources(platform), """
+$(top_builddir)/config.status --file=-:""" + platform_sources(platform) + """ \
+  | sed -e 's,@pkglib_DATA@,$(pkglib_DATA),g' > $@
+chmod a+x [+ name +]
+""")
+
+    r += gvar_add("CLEANFILES", "[+ name +]")
+    r += gvar_add("EXTRA_DIST", platform_sources(platform))
+
+    if test:
+        r += if_tag_defined("enable", lambda: gvar_add("TESTS", "[+ name +]"))
+    else:
+        r += if_tag("mansection", lambda: manpage())
+
+    return r
+
+def test_script(platform):
+    return script(platform, True)
+
+def with_enable_condition(x):
+    return "[+ IF enable +]if [+ enable +]\n" + x + "endif\n[+ ELSE +]" + x + "[+ ENDIF +]"
+
+def module_rules():
+    return for_tag("module", lambda: with_enable_condition(each_platform(lambda p: module(p))))
+
+def kernel_rules():
+    return for_tag("kernel", lambda: with_enable_condition(each_platform(lambda p: kernel(p))))
+
+def image_rules():
+    return for_tag("image", lambda: with_enable_condition(each_platform(lambda p: image(p))))
+
+def library_rules():
+    return for_tag("library", lambda: with_enable_condition(each_platform(lambda p: library(p))))
+
+def program_rules():
+    return for_tag("program", lambda: with_enable_condition(each_platform(lambda p: program(p))))
+
+def script_rules():
+    return for_tag("script", lambda: with_enable_condition(each_platform(lambda p: script(p))))
+
+def data_rules():
+    return for_tag("data", lambda: with_enable_condition(each_platform(lambda p: data(p))))
+
+def test_program_rules():
+    return for_tag("test_program", lambda: with_enable_condition(each_platform(lambda p: test_program(p))))
+
+def test_script_rules():
+    return for_tag("test_script", lambda: with_enable_condition(each_platform(lambda p: test_script(p))))
+
+print "[+ AutoGen5 template +]\n"
+a = module_rules()
+b = kernel_rules()
+c = image_rules()
+d = library_rules()
+e = program_rules()
+f = script_rules()
+g = data_rules()
+h = test_program_rules()
+i = test_script_rules()
+z = global_variable_initializers()
+
+print z # initializer for all vars
+print a
+print b
+print c
+print d
+print e
+print f
+print g
+print h
+print i
+
+print """.PRECIOUS: modules.am
+$(srcdir)/modules.am: $(srcdir)/modules.def $(top_srcdir)/Makefile.tpl
+       autogen -T $(top_srcdir)/Makefile.tpl $(srcdir)/modules.def | sed -e '/^$$/{N;/^\\n$$/D;}' > $@.new || (rm -f $@.new; exit 1)
+       mv $@.new $@
+
+.PRECIOUS: $(top_srcdir)/Makefile.tpl
+$(top_srcdir)/Makefile.tpl: $(top_srcdir)/gentpl.py
+       python $(top_srcdir)/gentpl.py | sed -e '/^$$/{N;/^\\n$$/D;}' > $@.new || (rm -f $@.new; exit 1)
+       mv $@.new $@
+"""
diff --git a/gentrigtables.c b/gentrigtables.c
deleted file mode 100644 (file)
index 772cd62..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Generate trigonometric function tables. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define _GNU_SOURCE 1
-
-#include <grub/trig.h>
-#include <math.h>
-#include <stdio.h>
-
-int
-main ()
-{
-  int i;
-
-  printf ("#include <grub/types.h>\n");
-
-#define TAB(op) \
-  printf ("grub_int16_t grub_trig_" #op "tab[] =\n{"); \
-  for (i = 0; i < GRUB_TRIG_ANGLE_MAX; i++) \
-    { \
-      double x = i * 2 * M_PI / GRUB_TRIG_ANGLE_MAX; \
-      if (i % 10 == 0) \
-       printf ("\n    "); \
-      printf ("%d,", (int) (round (op (x) * GRUB_TRIG_FRACTION_SCALE))); \
-    } \
-  printf ("\n};\n")
-
-  TAB(sin);
-  TAB(cos);
-
-  return 0;
-}
diff --git a/genvideolist.sh b/genvideolist.sh
deleted file mode 100644 (file)
index b208fa2..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 2005,2008,2009  Free Software Foundation, Inc.
-#
-# This script is free software; the author
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-# Read source code from stdin and detect partmap names.
-
-module=$1
-
-# Ignore video.mod.
-if test $module = video; then
-    exit
-fi
-
-# For now, this emits only a module name, if the module registers a partition map.
-if grep -v "^#" | grep '^ *grub_video_register' >/dev/null 2>&1; then
-    echo $module
-fi
diff --git a/gettext/gettext.c b/gettext/gettext.c
deleted file mode 100644 (file)
index 0aa8dec..0000000
+++ /dev/null
@@ -1,377 +0,0 @@
-/* gettext.c - gettext module */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/list.h>
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/normal.h>
-#include <grub/file.h>
-#include <grub/kernel.h>
-#include <grub/gzio.h>
-#include <grub/i18n.h>
-
-/*
-   .mo file information from:
-   http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html .
-*/
-
-
-static grub_file_t fd_mo;
-
-static int grub_gettext_offsetoriginal;
-static int grub_gettext_max;
-
-static const char *(*grub_gettext_original) (const char *s);
-
-struct grub_gettext_msg
-{
-  struct grub_gettext_msg *next;
-  const char *name;
-
-  const char *translated;
-};
-
-struct grub_gettext_msg *grub_gettext_msg_list = NULL;
-
-#define GETTEXT_MAGIC_NUMBER           0
-#define GETTEXT_FILE_FORMAT            4
-#define GETTEXT_NUMBER_OF_STRINGS      8
-#define GETTEXT_OFFSET_ORIGINAL        12
-#define GETTEXT_OFFSET_TRANSLATION     16
-
-#define MO_MAGIC_NUMBER                0x950412de
-
-static grub_ssize_t
-grub_gettext_pread (grub_file_t file, void *buf, grub_size_t len,
-                   grub_off_t offset)
-{
-  if (grub_file_seek (file, offset) == (grub_off_t) - 1)
-    {
-      return -1;
-    }
-  return grub_file_read (file, buf, len);
-}
-
-static grub_uint32_t
-grub_gettext_get_info (int offset)
-{
-  grub_uint32_t value;
-
-  grub_gettext_pread (fd_mo, (char *) &value, 4, offset);
-
-  value = grub_cpu_to_le32 (value);
-  return value;
-}
-
-static void
-grub_gettext_getstring_from_offset (grub_uint32_t offset,
-                                   grub_uint32_t length, char *translation)
-{
-  grub_gettext_pread (fd_mo, translation, length, offset);
-  translation[length] = '\0';
-}
-
-static const char *
-grub_gettext_gettranslation_from_position (int position)
-{
-  int offsettranslation;
-  int internal_position;
-  grub_uint32_t length, offset;
-  char *translation;
-
-  offsettranslation = grub_gettext_get_info (GETTEXT_OFFSET_TRANSLATION);
-
-  internal_position = offsettranslation + position * 8;
-
-  grub_gettext_pread (fd_mo, (char *) &length, 4, internal_position);
-  length = grub_cpu_to_le32 (length);
-
-  grub_gettext_pread (fd_mo, (char *) &offset, 4, internal_position + 4);
-  offset = grub_cpu_to_le32 (offset);
-
-  translation = grub_malloc (length + 1);
-  grub_gettext_getstring_from_offset (offset, length, translation);
-
-  return translation;
-}
-
-static char *
-grub_gettext_getstring_from_position (int position)
-{
-  int internal_position;
-  int length, offset;
-  char *original;
-
-  /* Get position for string i.  */
-  internal_position = grub_gettext_offsetoriginal + (position * 8);
-
-  /* Get the length of the string i.  */
-  grub_gettext_pread (fd_mo, (char *) &length, 4, internal_position);
-
-  /* Get the offset of the string i.  */
-  grub_gettext_pread (fd_mo, (char *) &offset, 4, internal_position + 4);
-
-  /* Get the string i.  */
-  original = grub_malloc (length + 1);
-  grub_gettext_getstring_from_offset (offset, length, original);
-
-  return original;
-}
-
-static const char *
-grub_gettext_translate (const char *orig)
-{
-  char *current_string;
-  const char *ret;
-
-  int min, max, current;
-  int found = 0;
-
-  struct grub_gettext_msg *cur;
-
-  /* Make sure we can use grub_gettext_translate for error messages.  Push
-     active error message to error stack and reset error message.  */
-  grub_error_push ();
-
-  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_gettext_msg_list),
-                             orig);
-
-  if (cur)
-    {
-      grub_error_pop ();
-      return cur->translated;
-    }
-
-  if (fd_mo == 0)
-    {
-      grub_error_pop ();
-      return orig;
-    }
-
-  min = 0;
-  max = grub_gettext_max;
-
-  current = (max + min) / 2;
-
-  while (current != min && current != max && found == 0)
-    {
-      current_string = grub_gettext_getstring_from_position (current);
-
-      /* Search by bisection.  */
-      if (grub_strcmp (current_string, orig) < 0)
-       {
-         grub_free (current_string);
-         min = current;
-       }
-      else if (grub_strcmp (current_string, orig) > 0)
-       {
-         grub_free (current_string);
-         max = current;
-       }
-      else if (grub_strcmp (current_string, orig) == 0)
-       {
-         grub_free (current_string);
-         found = 1;
-       }
-      current = (max + min) / 2;
-    }
-
-  ret = found ? grub_gettext_gettranslation_from_position (current) : orig;
-
-  if (found)
-    {
-      cur = grub_zalloc (sizeof (*cur));
-
-      if (cur)
-       {
-         cur->name = grub_strdup (orig);
-         if (cur->name)
-           {
-             cur->translated = ret;
-             grub_list_push (GRUB_AS_LIST_P (&grub_gettext_msg_list),
-                             GRUB_AS_LIST (cur));
-           }
-       }
-      else
-       grub_errno = GRUB_ERR_NONE;
-    }
-
-  grub_error_pop ();
-  return ret;
-}
-
-/* This is similar to grub_gzfile_open. */
-static grub_file_t
-grub_mofile_open (const char *filename)
-{
-  int unsigned magic;
-  int version;
-
-  /* Using fd_mo and not another variable because
-     it's needed for grub_gettext_get_info.  */
-
-  fd_mo = grub_gzfile_open (filename, 1);
-  grub_errno = GRUB_ERR_NONE;
-
-  if (!fd_mo)
-    {
-      grub_dprintf ("gettext", "Cannot read %s\n", filename);
-      return 0;
-    }
-
-  magic = grub_gettext_get_info (GETTEXT_MAGIC_NUMBER);
-
-  if (magic != MO_MAGIC_NUMBER)
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "mo: invalid mo file: %s",
-                 filename);
-      grub_file_close (fd_mo);
-      fd_mo = 0;
-      return 0;
-    }
-
-  version = grub_gettext_get_info (GETTEXT_FILE_FORMAT);
-
-  if (version != 0)
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                 "mo: invalid mo version in file: %s", filename);
-      fd_mo = 0;
-      return 0;
-    }
-
-  return fd_mo;
-}
-
-static void
-grub_gettext_init_ext (const char *lang)
-{
-  char *mo_file;
-  char *locale_dir;
-
-  locale_dir = grub_env_get ("locale_dir");
-  if (locale_dir == NULL)
-    {
-      grub_dprintf ("gettext", "locale_dir variable is not set up.\n");
-      return;
-    }
-
-  fd_mo = NULL;
-
-  /* mo_file e.g.: /boot/grub/locale/ca.mo   */
-
-  mo_file = grub_xasprintf ("%s/%s.mo", locale_dir, lang);
-  if (!mo_file)
-    return;
-
-  fd_mo = grub_mofile_open (mo_file);
-
-  /* Will try adding .gz as well.  */
-  if (fd_mo == NULL)
-    {
-      grub_free (mo_file);
-      mo_file = grub_xasprintf ("%s.gz", mo_file);
-      if (!mo_file)
-       return;
-      fd_mo = grub_mofile_open (mo_file);
-    }
-
-  if (fd_mo)
-    {
-      grub_gettext_offsetoriginal =
-       grub_gettext_get_info (GETTEXT_OFFSET_ORIGINAL);
-      grub_gettext_max = grub_gettext_get_info (GETTEXT_NUMBER_OF_STRINGS);
-
-      grub_gettext_original = grub_gettext;
-      grub_gettext = grub_gettext_translate;
-    }
-}
-
-static void
-grub_gettext_delete_list (void)
-{
-  struct grub_gettext_msg *item;
-
-  while ((item =
-         grub_list_pop (GRUB_AS_LIST_P (&grub_gettext_msg_list))) != 0)
-    {
-      char *original = (char *) ((struct grub_gettext_msg *) item)->name;
-      grub_free (original);
-
-      /* Don't delete the translated message because could be in use.  */
-    }
-}
-
-static char *
-grub_gettext_env_write_lang (struct grub_env_var *var
-                            __attribute__ ((unused)), const char *val)
-{
-  grub_gettext_init_ext (val);
-
-  grub_gettext_delete_list ();
-
-  return grub_strdup (val);
-}
-
-static grub_err_t
-grub_cmd_translate (grub_command_t cmd __attribute__ ((unused)),
-                   int argc, char **args)
-{
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "text to translate required");
-
-  const char *translation;
-  translation = grub_gettext_translate (args[0]);
-  grub_printf ("%s\n", translation);
-  return 0;
-}
-
-GRUB_MOD_INIT (gettext)
-{
-  (void) mod;                  /* To stop warning.  */
-
-  const char *lang;
-
-  lang = grub_env_get ("lang");
-
-  grub_gettext_init_ext (lang);
-
-  grub_register_command_p1 ("gettext", grub_cmd_translate,
-                           N_("STRING"),
-                           N_("Translates the string with the current settings."));
-
-  /* Reload .mo file information if lang changes.  */
-  grub_register_variable_hook ("lang", NULL, grub_gettext_env_write_lang);
-
-  /* Preserve hooks after context changes.  */
-  grub_env_export ("lang");
-}
-
-GRUB_MOD_FINI (gettext)
-{
-  if (fd_mo != 0)
-    grub_file_close (fd_mo);
-
-  grub_gettext_delete_list ();
-
-  grub_gettext = grub_gettext_original;
-}
diff --git a/gfxmenu/gfxmenu.c b/gfxmenu/gfxmenu.c
deleted file mode 100644 (file)
index a2e7651..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/* gfxmenu.c - Graphical menu interface controller. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/command.h>
-#include <grub/video.h>
-#include <grub/gfxterm.h>
-#include <grub/bitmap.h>
-#include <grub/bitmap_scale.h>
-#include <grub/term.h>
-#include <grub/env.h>
-#include <grub/normal.h>
-#include <grub/gfxwidgets.h>
-#include <grub/menu.h>
-#include <grub/menu_viewer.h>
-#include <grub/gfxmenu_model.h>
-#include <grub/gfxmenu_view.h>
-#include <grub/time.h>
-
-grub_gfxmenu_view_t cached_view;
-
-static void 
-grub_gfxmenu_viewer_fini (void *data __attribute__ ((unused)))
-{
-}
-
-/* FIXME: Previously 't' changed to text menu is it necessary?  */
-static grub_err_t
-grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
-{
-  grub_gfxmenu_view_t view = NULL;
-  const char *theme_path;
-  struct grub_menu_viewer *instance;
-  grub_err_t err;
-  struct grub_video_mode_info mode_info;
-
-  theme_path = grub_env_get ("theme");
-  if (! theme_path)
-    {
-      grub_error_push ();
-      grub_gfxterm_fullscreen ();
-      grub_error_pop ();
-      return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no theme specified");
-    }
-
-  instance = grub_zalloc (sizeof (*instance));
-  if (!instance)
-    {
-      grub_error_push ();
-      grub_gfxterm_fullscreen ();
-      grub_error_pop ();
-      return grub_errno;
-    }
-
-  err = grub_video_get_info (&mode_info);
-  if (err)
-    {
-      grub_error_push ();
-      grub_gfxterm_fullscreen ();
-      grub_error_pop ();
-      return err;
-    }
-
-  if (!cached_view || grub_strcmp (cached_view->theme_path, theme_path) != 0
-      || cached_view->screen.width != mode_info.width
-      || cached_view->screen.height != mode_info.height)
-    {
-      grub_free (cached_view);
-      /* Create the view.  */
-      cached_view = grub_gfxmenu_view_new (theme_path, mode_info.width,
-                                          mode_info.height);
-    }
-
-  if (! cached_view)
-    {
-      grub_free (instance);
-      grub_error_push ();
-      grub_gfxterm_fullscreen ();
-      grub_error_pop ();
-      return grub_errno;
-    }
-
-  view = cached_view;
-
-  view->double_repaint = (mode_info.mode_type
-                         & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)
-    && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
-  view->selected = entry;
-  view->menu = menu;
-  view->nested = nested;
-  view->first_timeout = -1;
-
-  grub_gfxmenu_view_draw (view);
-
-  instance->data = view;
-  instance->set_chosen_entry = grub_gfxmenu_set_chosen_entry;
-  instance->fini = grub_gfxmenu_viewer_fini;
-  instance->print_timeout = grub_gfxmenu_print_timeout;
-  instance->clear_timeout = grub_gfxmenu_clear_timeout;
-
-  grub_menu_register_viewer (instance);
-
-  return GRUB_ERR_NONE;
-}
-
-GRUB_MOD_INIT (gfxmenu)
-{
-  struct grub_term_output *term;
-
-  FOR_ACTIVE_TERM_OUTPUTS(term)
-    if (grub_gfxmenu_try_hook && grub_strcmp (term->name, "gfxterm") == 0)
-      {
-       grub_gfxterm_fullscreen ();
-       break;
-      }
-
-  grub_gfxmenu_try_hook = grub_gfxmenu_try;
-}
-
-GRUB_MOD_FINI (gfxmenu)
-{
-  grub_gfxmenu_view_destroy (cached_view);
-  grub_gfxmenu_try_hook = NULL;
-}
diff --git a/gfxmenu/gui_box.c b/gfxmenu/gui_box.c
deleted file mode 100644 (file)
index 38b15f9..0000000
+++ /dev/null
@@ -1,412 +0,0 @@
-/* gui_box.c - GUI container that stack components. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/gui.h>
-#include <grub/gui_string_util.h>
-
-struct component_node
-{
-  grub_gui_component_t component;
-  struct component_node *next;
-  struct component_node *prev;
-};
-
-typedef struct grub_gui_box *grub_gui_box_t;
-
-typedef void (*layout_func_t) (grub_gui_box_t self, int modify_layout,
-                               unsigned *minimal_width,
-                              unsigned *minimal_height);
-
-struct grub_gui_box
-{
-  struct grub_gui_container container;
-
-  grub_gui_container_t parent;
-  grub_video_rect_t bounds;
-  char *id;
-
-  /* Doubly linked list of components with dummy head & tail nodes.  */
-  struct component_node chead;
-  struct component_node ctail;
-
-  /* The layout function: differs for vertical and horizontal boxes.  */
-  layout_func_t layout_func;
-};
-
-static void
-box_destroy (void *vself)
-{
-  grub_gui_box_t self = vself;
-  struct component_node *cur;
-  struct component_node *next;
-  for (cur = self->chead.next; cur != &self->ctail; cur = next)
-    {
-      /* Copy the 'next' pointer, since we need it for the next iteration,
-         and we're going to free the memory it is stored in.  */
-      next = cur->next;
-      /* Destroy the child component.  */
-      cur->component->ops->destroy (cur->component);
-      /* Free the linked list node.  */
-      grub_free (cur);
-    }
-  grub_free (self);
-}
-
-static const char *
-box_get_id (void *vself)
-{
-  grub_gui_box_t self = vself;
-  return self->id;
-}
-
-static int
-box_is_instance (void *vself __attribute__((unused)), const char *type)
-{
-  return (grub_strcmp (type, "component") == 0
-          || grub_strcmp (type, "container") == 0);
-}
-
-static void
-layout_horizontally (grub_gui_box_t self, int modify_layout,
-                     unsigned *min_width, unsigned *min_height)
-{
-  /* Start at the left (chead) and set the x coordinates as we go right.  */
-  /* All components have their width set to the box's width.  */
-
-  struct component_node *cur;
-  unsigned w = 0, mwfrac = 0, h = 0, x = 0;
-  grub_fixed_signed_t wfrac = 0;
-  int bogus_frac = 0;
-
-  for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
-    {
-      grub_gui_component_t c = cur->component;
-      unsigned mw = 0, mh = 0;
-
-      if (c->ops->get_minimal_size)
-       c->ops->get_minimal_size (c, &mw, &mh);
-
-      if (c->h > (signed) h)
-       h = c->h;
-      if (mh > h)
-       h = mh;
-      wfrac += c->wfrac;
-      w += c->w;
-      if (mw - c->w > 0)
-       mwfrac += mw - c->w;
-    }
-  if (wfrac > GRUB_FIXED_1 || (w > 0 && wfrac == GRUB_FIXED_1))
-    bogus_frac = 1;
-
-  if (min_width)
-    {
-      if (wfrac < GRUB_FIXED_1)
-       *min_width = grub_fixed_sfs_divide (w, GRUB_FIXED_1 - wfrac);
-      else
-       *min_width = w;
-      if (*min_width < w + mwfrac)
-       *min_width = w + mwfrac;
-    }
-  if (min_height)
-    *min_height = h;
-
-  if (!modify_layout)
-    return;
-
-  for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
-    {
-      grub_video_rect_t r;
-      grub_gui_component_t c = cur->component;
-      unsigned mw = 0, mh = 0;
-
-      r.x = x;
-      r.y = 0;
-      r.height = h;
-
-      if (c->ops->get_minimal_size)
-       c->ops->get_minimal_size (c, &mw, &mh);
-
-      r.width = c->w;
-      if (!bogus_frac)
-       r.width += grub_fixed_sfs_multiply (self->bounds.width, c->wfrac);
-
-      if (r.width < mw)
-       r.width = mw;
-
-      c->ops->set_bounds (c, &r);
-
-      x += r.width;
-    }
-}
-
-static void
-layout_vertically (grub_gui_box_t self, int modify_layout,
-                     unsigned *min_width, unsigned *min_height)
-{
-  /* Start at the top (chead) and set the y coordinates as we go rdown.  */
-  /* All components have their height set to the box's height.  */
-
-  struct component_node *cur;
-  unsigned h = 0, mhfrac = 0, w = 0, y = 0;
-  grub_fixed_signed_t hfrac = 0;
-  int bogus_frac = 0;
-
-  for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
-    {
-      grub_gui_component_t c = cur->component;
-      unsigned mw = 0, mh = 0;
-
-      if (c->ops->get_minimal_size)
-       c->ops->get_minimal_size (c, &mw, &mh);
-
-      if (c->w > (signed) w)
-       w = c->w;
-      if (mw > w)
-       w = mw;
-      hfrac += c->hfrac;
-      h += c->h;
-      if (mh - c->h > 0)
-       mhfrac += mh - c->h;
-    }
-  if (hfrac > GRUB_FIXED_1 || (h > 0 && hfrac == GRUB_FIXED_1))
-    bogus_frac = 1;
-
-  if (min_height)
-    {
-      if (hfrac < GRUB_FIXED_1)
-       *min_height = grub_fixed_sfs_divide (h, GRUB_FIXED_1 - hfrac);
-      else
-       *min_height = h;
-      if (*min_height < h + mhfrac)
-       *min_height = h + mhfrac;
-    }
-  if (min_width)
-    *min_width = w;
-
-  if (!modify_layout)
-    return;
-
-  for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
-    {
-      grub_video_rect_t r;
-      grub_gui_component_t c = cur->component;
-      unsigned mw = 0, mh = 0;
-
-      r.x = 0;
-      r.y = y;
-      r.width = w;
-
-      if (c->ops->get_minimal_size)
-       c->ops->get_minimal_size (c, &mw, &mh);
-
-      r.height = c->h;
-      if (!bogus_frac)
-       r.height += grub_fixed_sfs_multiply (self->bounds.height, c->hfrac);
-
-      if (r.height < mh)
-       r.height = mh;
-
-      c->ops->set_bounds (c, &r);
-
-      y += r.height;
-    }
-}
-
-static void
-box_paint (void *vself, const grub_video_rect_t *region)
-{
-  grub_gui_box_t self = vself;
-  struct component_node *cur;
-  grub_video_rect_t vpsave;
-
-  grub_gui_set_viewport (&self->bounds, &vpsave);
-  for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
-    {
-      grub_gui_component_t comp = cur->component;
-      comp->ops->paint (comp, region);
-    }
-  grub_gui_restore_viewport (&vpsave);
-}
-
-static void
-box_set_parent (void *vself, grub_gui_container_t parent)
-{
-  grub_gui_box_t self = vself;
-  self->parent = parent;
-}
-
-static grub_gui_container_t
-box_get_parent (void *vself)
-{
-  grub_gui_box_t self = vself;
-  return self->parent;
-}
-
-static void
-box_set_bounds (void *vself, const grub_video_rect_t *bounds)
-{
-  grub_gui_box_t self = vself;
-  self->bounds = *bounds;
-  self->layout_func (self, 1, 0, 0);   /* Relayout the children.  */
-}
-
-static void
-box_get_bounds (void *vself, grub_video_rect_t *bounds)
-{
-  grub_gui_box_t self = vself;
-  *bounds = self->bounds;
-}
-
-/* The box's preferred size is based on the preferred sizes
-   of its children.  */
-static void
-box_get_minimal_size (void *vself, unsigned *width, unsigned *height)
-{
-  grub_gui_box_t self = vself;
-  self->layout_func (self, 0, width, height);   /* Just calculate the size.  */
-}
-
-static grub_err_t
-box_set_property (void *vself, const char *name, const char *value)
-{
-  grub_gui_box_t self = vself;
-  if (grub_strcmp (name, "id") == 0)
-    {
-      grub_free (self->id);
-      if (value)
-        {
-          self->id = grub_strdup (value);
-          if (! self->id)
-            return grub_errno;
-        }
-      else
-        self->id = 0;
-    }
-
-  return grub_errno;
-}
-
-static void
-box_add (void *vself, grub_gui_component_t comp)
-{
-  grub_gui_box_t self = vself;
-  struct component_node *node;
-  node = grub_malloc (sizeof (*node));
-  if (! node)
-    return;   /* Note: probably should handle the error.  */
-  node->component = comp;
-  /* Insert the node before the tail.  */
-  node->prev = self->ctail.prev;
-  node->prev->next = node;
-  node->next = &self->ctail;
-  node->next->prev = node;
-
-  comp->ops->set_parent (comp, (grub_gui_container_t) self);
-  self->layout_func (self, 1, 0, 0);   /* Relayout the children.  */
-}
-
-static void
-box_remove (void *vself, grub_gui_component_t comp)
-{
-  grub_gui_box_t self = vself;
-  struct component_node *cur;
-  for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
-    {
-      if (cur->component == comp)
-        {
-          /* Unlink 'cur' from the list.  */
-          cur->prev->next = cur->next;
-          cur->next->prev = cur->prev;
-          /* Free the node's memory (but don't destroy the component).  */
-          grub_free (cur);
-          /* Must not loop again, since 'cur' would be dereferenced!  */
-          return;
-        }
-    }
-}
-
-static void
-box_iterate_children (void *vself,
-                      grub_gui_component_callback cb, void *userdata)
-{
-  grub_gui_box_t self = vself;
-  struct component_node *cur;
-  for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
-    cb (cur->component, userdata);
-}
-
-static struct grub_gui_component_ops box_comp_ops =
-  {
-    .destroy = box_destroy,
-    .get_id = box_get_id,
-    .is_instance = box_is_instance,
-    .paint = box_paint,
-    .set_parent = box_set_parent,
-    .get_parent = box_get_parent,
-    .set_bounds = box_set_bounds,
-    .get_bounds = box_get_bounds,
-    .get_minimal_size = box_get_minimal_size,
-    .set_property = box_set_property
-  };
-
-static struct grub_gui_container_ops box_ops =
-{
-  .add = box_add,
-  .remove = box_remove,
-  .iterate_children = box_iterate_children
-};
-
-/* Box constructor.  Specify the appropriate layout function to create
-   a horizontal or vertical stacking box.  */
-static grub_gui_box_t
-box_new (layout_func_t layout_func)
-{
-  grub_gui_box_t box;
-  box = grub_zalloc (sizeof (*box));
-  if (! box)
-    return 0;
-  box->container.ops = &box_ops;
-  box->container.component.ops = &box_comp_ops;
-  box->chead.next = &box->ctail;
-  box->ctail.prev = &box->chead;
-  box->layout_func = layout_func;
-  return box;
-}
-
-/* Create a new container that stacks its child components horizontally,
-   from left to right.  Each child get a width corresponding to its
-   preferred width.  The height of each child is set the maximum of the
-   preferred heights of all children.  */
-grub_gui_container_t
-grub_gui_hbox_new (void)
-{
-  return (grub_gui_container_t) box_new (layout_horizontally);
-}
-
-/* Create a new container that stacks its child components verticallyj,
-   from top to bottom.  Each child get a height corresponding to its
-   preferred height.  The width of each child is set the maximum of the
-   preferred widths of all children.  */
-grub_gui_container_t
-grub_gui_vbox_new (void)
-{
-  return (grub_gui_container_t) box_new (layout_vertically);
-}
diff --git a/gfxmenu/gui_canvas.c b/gfxmenu/gui_canvas.c
deleted file mode 100644 (file)
index b3919c2..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-/* gui_canvas.c - GUI container allowing manually placed components. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/gui.h>
-#include <grub/gui_string_util.h>
-
-/* TODO Add layering so that components can be properly overlaid. */
-
-struct component_node
-{
-  grub_gui_component_t component;
-  struct component_node *next;
-};
-
-struct grub_gui_canvas
-{
-  struct grub_gui_container container;
-
-  grub_gui_container_t parent;
-  grub_video_rect_t bounds;
-  char *id;
-  /* Component list (dummy head node).  */
-  struct component_node components;
-};
-
-typedef struct grub_gui_canvas *grub_gui_canvas_t;
-
-static void
-canvas_destroy (void *vself)
-{
-  grub_gui_canvas_t self = vself;
-  struct component_node *cur;
-  struct component_node *next;
-  for (cur = self->components.next; cur; cur = next)
-    {
-      /* Copy the 'next' pointer, since we need it for the next iteration,
-         and we're going to free the memory it is stored in.  */
-      next = cur->next;
-      /* Destroy the child component.  */
-      cur->component->ops->destroy (cur->component);
-      /* Free the linked list node.  */
-      grub_free (cur);
-    }
-  grub_free (self);
-}
-
-static const char *
-canvas_get_id (void *vself)
-{
-  grub_gui_canvas_t self = vself;
-  return self->id;
-}
-
-static int
-canvas_is_instance (void *vself __attribute__((unused)), const char *type)
-{
-  return (grub_strcmp (type, "component") == 0
-          || grub_strcmp (type, "container") == 0);
-}
-
-static void
-canvas_paint (void *vself, const grub_video_rect_t *region)
-{
-  grub_gui_canvas_t self = vself;
-  struct component_node *cur;
-  grub_video_rect_t vpsave;
-
-  grub_gui_set_viewport (&self->bounds, &vpsave);
-  for (cur = self->components.next; cur; cur = cur->next)
-    {
-      grub_video_rect_t r;
-      grub_gui_component_t comp;
-      signed x, y, w, h;
-
-      comp = cur->component;
-
-      w = grub_fixed_sfs_multiply (self->bounds.width, comp->wfrac) + comp->w;
-      h = grub_fixed_sfs_multiply (self->bounds.height, comp->hfrac) + comp->h;
-      x = grub_fixed_sfs_multiply (self->bounds.width, comp->xfrac) + comp->x;
-      y = grub_fixed_sfs_multiply (self->bounds.height, comp->yfrac) + comp->y;
-
-      if (comp->ops->get_minimal_size)
-       {
-         unsigned mw;
-         unsigned mh;
-         comp->ops->get_minimal_size (comp, &mw, &mh);
-         if (w < (signed) mw)
-           w = mw;
-         if (h < (signed) mh)
-           h = mh;
-       }
-
-      /* Sanity checks.  */
-      if (w <= 0)
-       w = 32;
-      if (h <= 0)
-       h = 32;
-
-      if (x >= (signed) self->bounds.width)
-       x = self->bounds.width - 32;
-      if (y >= (signed) self->bounds.height)
-       y = self->bounds.height - 32;
-
-      if (x < 0)
-       x = 0;
-      if (y < 0)
-       y = 0;
-
-      if (x + w >= (signed) self->bounds.width)
-       w = self->bounds.width - x;
-      if (y + h >= (signed) self->bounds.height)
-       h = self->bounds.height - y;
-
-      r.x = x;
-      r.y = y;
-      r.width = w;
-      r.height = h;
-      comp->ops->set_bounds (comp, &r);
-
-      /* Paint the child.  */
-      if (grub_video_have_common_points (region, &r))
-       comp->ops->paint (comp, region);
-    }
-  grub_gui_restore_viewport (&vpsave);
-}
-
-static void
-canvas_set_parent (void *vself, grub_gui_container_t parent)
-{
-  grub_gui_canvas_t self = vself;
-  self->parent = parent;
-}
-
-static grub_gui_container_t
-canvas_get_parent (void *vself)
-{
-  grub_gui_canvas_t self = vself;
-  return self->parent;
-}
-
-static void
-canvas_set_bounds (void *vself, const grub_video_rect_t *bounds)
-{
-  grub_gui_canvas_t self = vself;
-  self->bounds = *bounds;
-}
-
-static void
-canvas_get_bounds (void *vself, grub_video_rect_t *bounds)
-{
-  grub_gui_canvas_t self = vself;
-  *bounds = self->bounds;
-}
-
-static grub_err_t
-canvas_set_property (void *vself, const char *name, const char *value)
-{
-  grub_gui_canvas_t self = vself;
-  if (grub_strcmp (name, "id") == 0)
-    {
-      grub_free (self->id);
-      if (value)
-        {
-          self->id = grub_strdup (value);
-          if (! self->id)
-            return grub_errno;
-        }
-      else
-        self->id = 0;
-    }
-  return grub_errno;
-}
-
-static void
-canvas_add (void *vself, grub_gui_component_t comp)
-{
-  grub_gui_canvas_t self = vself;
-  struct component_node *node;
-  node = grub_malloc (sizeof (*node));
-  if (! node)
-    return;   /* Note: probably should handle the error.  */
-  node->component = comp;
-  node->next = self->components.next;
-  self->components.next = node;
-  comp->ops->set_parent (comp, (grub_gui_container_t) self);
-}
-
-static void
-canvas_remove (void *vself, grub_gui_component_t comp)
-{
-  grub_gui_canvas_t self = vself;
-  struct component_node *cur;
-  struct component_node *prev;
-  prev = &self->components;
-  for (cur = self->components.next; cur; prev = cur, cur = cur->next)
-    {
-      if (cur->component == comp)
-        {
-          /* Unlink 'cur' from the list.  */
-          prev->next = cur->next;
-          /* Free the node's memory (but don't destroy the component).  */
-          grub_free (cur);
-          /* Must not loop again, since 'cur' would be dereferenced!  */
-          return;
-        }
-    }
-}
-
-static void
-canvas_iterate_children (void *vself,
-                         grub_gui_component_callback cb, void *userdata)
-{
-  grub_gui_canvas_t self = vself;
-  struct component_node *cur;
-  for (cur = self->components.next; cur; cur = cur->next)
-    cb (cur->component, userdata);
-}
-
-static struct grub_gui_component_ops canvas_comp_ops =
-{
-  .destroy = canvas_destroy,
-  .get_id = canvas_get_id,
-  .is_instance = canvas_is_instance,
-  .paint = canvas_paint,
-  .set_parent = canvas_set_parent,
-  .get_parent = canvas_get_parent,
-  .set_bounds = canvas_set_bounds,
-  .get_bounds = canvas_get_bounds,
-  .set_property = canvas_set_property
-};
-
-static struct grub_gui_container_ops canvas_ops =
-{
-  .add = canvas_add,
-  .remove = canvas_remove,
-  .iterate_children = canvas_iterate_children
-};
-
-grub_gui_container_t
-grub_gui_canvas_new (void)
-{
-  grub_gui_canvas_t canvas;
-  canvas = grub_zalloc (sizeof (*canvas));
-  if (! canvas)
-    return 0;
-  canvas->container.ops = &canvas_ops;
-  canvas->container.component.ops = &canvas_comp_ops;
-  return (grub_gui_container_t) canvas;
-}
diff --git a/gfxmenu/gui_circular_progress.c b/gfxmenu/gui_circular_progress.c
deleted file mode 100644 (file)
index 9a859ee..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/* gui_circular_process.c - GUI circular progress indicator component.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/gui.h>
-#include <grub/font.h>
-#include <grub/gui_string_util.h>
-#include <grub/gfxmenu_view.h>
-#include <grub/gfxwidgets.h>
-#include <grub/trig.h>
-
-struct grub_gui_circular_progress
-{
-  struct grub_gui_progress progress;
-
-  grub_gui_container_t parent;
-  grub_video_rect_t bounds;
-  char *id;
-  int visible;
-  int start;
-  int end;
-  int value;
-  int num_ticks;
-  int start_angle;
-  int ticks_disappear;
-  char *theme_dir;
-  int need_to_load_pixmaps;
-  char *center_file;
-  char *tick_file;
-  struct grub_video_bitmap *center_bitmap;
-  struct grub_video_bitmap *tick_bitmap;
-};
-
-typedef struct grub_gui_circular_progress *circular_progress_t;
-
-static void
-circprog_destroy (void *vself)
-{
-  circular_progress_t self = vself;
-  grub_free (self);
-}
-
-static const char *
-circprog_get_id (void *vself)
-{
-  circular_progress_t self = vself;
-  return self->id;
-}
-
-static int
-circprog_is_instance (void *vself __attribute__((unused)), const char *type)
-{
-  return grub_strcmp (type, "component") == 0;
-}
-
-static struct grub_video_bitmap *
-load_bitmap (const char *dir, const char *file)
-{
-  struct grub_video_bitmap *bitmap;
-  char *abspath;
-
-  /* Check arguments.  */
-  if (! dir || ! file)
-    return 0;
-
-  /* Resolve to an absolute path.  */
-  abspath = grub_resolve_relative_path (dir, file);
-  if (! abspath)
-    return 0;
-
-  /* Load the image.  */
-  grub_errno = GRUB_ERR_NONE;
-  grub_video_bitmap_load (&bitmap, abspath);
-  grub_errno = GRUB_ERR_NONE;
-
-  grub_free (abspath);
-  return bitmap;
-}
-
-static int
-check_pixmaps (circular_progress_t self)
-{
-  if (self->need_to_load_pixmaps)
-    {
-      if (self->center_bitmap)
-        grub_video_bitmap_destroy (self->center_bitmap);
-      self->center_bitmap = load_bitmap (self->theme_dir, self->center_file);
-      self->tick_bitmap = load_bitmap (self->theme_dir, self->tick_file);
-      self->need_to_load_pixmaps = 0;
-    }
-
-  return (self->center_bitmap != 0 && self->tick_bitmap != 0);
-}
-
-static void
-circprog_paint (void *vself, const grub_video_rect_t *region)
-{
-  circular_progress_t self = vself;
-
-  if (! self->visible)
-    return;
-
-  if (!grub_video_have_common_points (region, &self->bounds))
-    return;
-
-  if (! check_pixmaps (self))
-    return;
-
-  grub_video_rect_t vpsave;
-  grub_gui_set_viewport (&self->bounds, &vpsave);
-
-  int width = self->bounds.width;
-  int height = self->bounds.height;
-  int center_width = grub_video_bitmap_get_width (self->center_bitmap);
-  int center_height = grub_video_bitmap_get_height (self->center_bitmap);
-  int tick_width = grub_video_bitmap_get_width (self->tick_bitmap);
-  int tick_height = grub_video_bitmap_get_height (self->tick_bitmap);
-  grub_video_blit_bitmap (self->center_bitmap, GRUB_VIDEO_BLIT_BLEND,
-                          (width - center_width) / 2,
-                          (height - center_height) / 2, 0, 0,
-                          center_width, center_height);
-
-  int radius = width / 2 - tick_width / 2 - 1;
-  int nticks;
-  int tick_begin;
-  int tick_end;
-  if (self->end == self->start)
-    nticks = 0;
-  else
-    nticks = (self->num_ticks
-             * (self->value - self->start)
-             / (self->end - self->start));
-  /* Do ticks appear or disappear as the value approached the end?  */
-  if (self->ticks_disappear)
-    {
-      tick_begin = nticks;
-      tick_end = self->num_ticks - 1;
-    }
-  else
-    {
-      tick_begin = 0;
-      tick_end = nticks - 1;
-    }
-
-  int i;
-  for (i = tick_begin; i < tick_end; i++)
-    {
-       int x;
-       int y;
-       int angle;
-
-       /* Calculate the location of the tick.  */
-       angle = self->start_angle + i * GRUB_TRIG_ANGLE_MAX / self->num_ticks;
-       x = width / 2 + (grub_cos (angle) * radius / GRUB_TRIG_FRACTION_SCALE);
-       y = height / 2 + (grub_sin (angle) * radius / GRUB_TRIG_FRACTION_SCALE);
-
-       /* Adjust (x,y) so the tick is centered.  */
-       x -= tick_width / 2;
-       y -= tick_height / 2;
-
-       /* Draw the tick.  */
-       grub_video_blit_bitmap (self->tick_bitmap, GRUB_VIDEO_BLIT_BLEND,
-                               x, y, 0, 0, tick_width, tick_height);
-    }
-
-  grub_gui_restore_viewport (&vpsave);
-}
-
-static void
-circprog_set_parent (void *vself, grub_gui_container_t parent)
-{
-  circular_progress_t self = vself;
-  self->parent = parent;
-}
-
-static grub_gui_container_t
-circprog_get_parent (void *vself)
-{
-  circular_progress_t self = vself;
-  return self->parent;
-}
-
-static void
-circprog_set_bounds (void *vself, const grub_video_rect_t *bounds)
-{
-  circular_progress_t self = vself;
-  self->bounds = *bounds;
-}
-
-static void
-circprog_get_bounds (void *vself, grub_video_rect_t *bounds)
-{
-  circular_progress_t self = vself;
-  *bounds = self->bounds;
-}
-
-static grub_err_t
-circprog_set_property (void *vself, const char *name, const char *value)
-{
-  circular_progress_t self = vself;
-  if (grub_strcmp (name, "num_ticks") == 0)
-    {
-      self->num_ticks = grub_strtol (value, 0, 10);
-    }
-  else if (grub_strcmp (name, "start_angle") == 0)
-    {
-      self->start_angle = grub_strtol (value, 0, 10);
-    }
-  else if (grub_strcmp (name, "ticks_disappear") == 0)
-    {
-      self->ticks_disappear = grub_strcmp (value, "false") != 0;
-    }
-  else if (grub_strcmp (name, "center_bitmap") == 0)
-    {
-      self->need_to_load_pixmaps = 1;
-      grub_free (self->center_file);
-      self->center_file = value ? grub_strdup (value) : 0;
-    }
-  else if (grub_strcmp (name, "tick_bitmap") == 0)
-    {
-      self->need_to_load_pixmaps = 1;
-      grub_free (self->tick_file);
-      self->tick_file = value ? grub_strdup (value) : 0;
-    }
-  else if (grub_strcmp (name, "theme_dir") == 0)
-    {
-      self->need_to_load_pixmaps = 1;
-      grub_free (self->theme_dir);
-      self->theme_dir = value ? grub_strdup (value) : 0;
-    }
-  else if (grub_strcmp (name, "id") == 0)
-    {
-      grub_free (self->id);
-      if (value)
-        self->id = grub_strdup (value);
-      else
-        self->id = 0;
-    }
-  return grub_errno;
-}
-
-static void
-circprog_set_state (void *vself, int visible, int start,
-                   int current, int end)
-{
-  circular_progress_t self = vself;  
-  self->visible = visible;
-  self->start = start;
-  self->value = current;
-  self->end = end;
-}
-
-static struct grub_gui_component_ops circprog_ops =
-{
-  .destroy = circprog_destroy,
-  .get_id = circprog_get_id,
-  .is_instance = circprog_is_instance,
-  .paint = circprog_paint,
-  .set_parent = circprog_set_parent,
-  .get_parent = circprog_get_parent,
-  .set_bounds = circprog_set_bounds,
-  .get_bounds = circprog_get_bounds,
-  .set_property = circprog_set_property
-};
-
-static struct grub_gui_progress_ops circprog_prog_ops =
-  {
-    .set_state = circprog_set_state
-  };
-
-grub_gui_component_t
-grub_gui_circular_progress_new (void)
-{
-  circular_progress_t self;
-  self = grub_zalloc (sizeof (*self));
-  if (! self)
-    return 0;
-  self->progress.ops = &circprog_prog_ops;
-  self->progress.component.ops = &circprog_ops;
-  self->visible = 1;
-  self->num_ticks = 64;
-  self->start_angle = -64;
-
-  return (grub_gui_component_t) self;
-}
diff --git a/gfxmenu/gui_image.c b/gfxmenu/gui_image.c
deleted file mode 100644 (file)
index 3988f4b..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/* gui_image.c - GUI component to display an image.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/gui.h>
-#include <grub/gui_string_util.h>
-#include <grub/bitmap.h>
-#include <grub/bitmap_scale.h>
-
-struct grub_gui_image
-{
-  struct grub_gui_component component;
-
-  grub_gui_container_t parent;
-  grub_video_rect_t bounds;
-  char *id;
-  char *theme_dir;
-  struct grub_video_bitmap *raw_bitmap;
-  struct grub_video_bitmap *bitmap;
-};
-
-typedef struct grub_gui_image *grub_gui_image_t;
-
-static void
-image_destroy (void *vself)
-{
-  grub_gui_image_t self = vself;
-
-  /* Free the scaled bitmap, unless it's a reference to the raw bitmap.  */
-  if (self->bitmap && (self->bitmap != self->raw_bitmap))
-    grub_video_bitmap_destroy (self->bitmap);
-  if (self->raw_bitmap)
-    grub_video_bitmap_destroy (self->raw_bitmap);
-
-  grub_free (self);
-}
-
-static const char *
-image_get_id (void *vself)
-{
-  grub_gui_image_t self = vself;
-  return self->id;
-}
-
-static int
-image_is_instance (void *vself __attribute__((unused)), const char *type)
-{
-  return grub_strcmp (type, "component") == 0;
-}
-
-static void
-image_paint (void *vself, const grub_video_rect_t *region)
-{
-  grub_gui_image_t self = vself;
-  grub_video_rect_t vpsave;
-
-  if (! self->bitmap)
-    return;
-  if (!grub_video_have_common_points (region, &self->bounds))
-    return;
-
-  grub_gui_set_viewport (&self->bounds, &vpsave);
-  grub_video_blit_bitmap (self->bitmap, GRUB_VIDEO_BLIT_BLEND,
-                          0, 0, 0, 0,
-                          grub_video_bitmap_get_width (self->bitmap),
-                          grub_video_bitmap_get_height (self->bitmap));
-  grub_gui_restore_viewport (&vpsave);
-}
-
-static void
-image_set_parent (void *vself, grub_gui_container_t parent)
-{
-  grub_gui_image_t self = vself;
-  self->parent = parent;
-}
-
-static grub_gui_container_t
-image_get_parent (void *vself)
-{
-  grub_gui_image_t self = vself;
-  return self->parent;
-}
-
-static grub_err_t
-rescale_image (grub_gui_image_t self)
-{
-  if (! self->raw_bitmap)
-    {
-      if (self->bitmap)
-        {
-          grub_video_bitmap_destroy (self->bitmap);
-          self->bitmap = 0;
-        }
-      return grub_errno;
-    }
-
-  unsigned width = self->bounds.width;
-  unsigned height = self->bounds.height;
-
-  if (self->bitmap
-      && (grub_video_bitmap_get_width (self->bitmap) == width)
-      && (grub_video_bitmap_get_height (self->bitmap) == height))
-    {
-      /* Nothing to do; already the right size.  */
-      return grub_errno;
-    }
-
-  /* Free any old scaled bitmap,
-     *unless* it's a reference to the raw bitmap.  */
-  if (self->bitmap && (self->bitmap != self->raw_bitmap))
-    grub_video_bitmap_destroy (self->bitmap);
-
-  self->bitmap = 0;
-
-  /* Create a scaled bitmap, unless the requested size is the same
-     as the raw size -- in that case a reference is made.  */
-  if (grub_video_bitmap_get_width (self->raw_bitmap) == width
-      && grub_video_bitmap_get_height (self->raw_bitmap) == height)
-    {
-      self->bitmap = self->raw_bitmap;
-      return grub_errno;
-    }
-
-  /* Don't scale to an invalid size.  */
-  if (width == 0 || height == 0)
-    return grub_errno;
-
-  /* Create the scaled bitmap.  */
-  grub_video_bitmap_create_scaled (&self->bitmap,
-                                   width,
-                                   height,
-                                   self->raw_bitmap,
-                                   GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_error_push ();
-      grub_error (grub_errno, "failed to scale bitmap for image component");
-    }
-  return grub_errno;
-}
-
-static void
-image_set_bounds (void *vself, const grub_video_rect_t *bounds)
-{
-  grub_gui_image_t self = vself;
-  self->bounds = *bounds;
-  rescale_image (self);
-}
-
-static void
-image_get_bounds (void *vself, grub_video_rect_t *bounds)
-{
-  grub_gui_image_t self = vself;
-  *bounds = self->bounds;
-}
-
-/* FIXME: inform rendering system it's not forced minimum.  */
-static void
-image_get_minimal_size (void *vself, unsigned *width, unsigned *height)
-{
-  grub_gui_image_t self = vself;
-
-  if (self->raw_bitmap)
-    {
-      *width = grub_video_bitmap_get_width (self->raw_bitmap);
-      *height = grub_video_bitmap_get_height (self->raw_bitmap);
-    }
-  else
-    {
-      *width = 0;
-      *height = 0;
-    }
-}
-
-static grub_err_t
-load_image (grub_gui_image_t self, const char *path)
-{
-  struct grub_video_bitmap *bitmap;
-  if (grub_video_bitmap_load (&bitmap, path) != GRUB_ERR_NONE)
-    return grub_errno;
-
-  if (self->bitmap && (self->bitmap != self->raw_bitmap))
-    grub_video_bitmap_destroy (self->bitmap);
-  if (self->raw_bitmap)
-    grub_video_bitmap_destroy (self->raw_bitmap);
-
-  self->raw_bitmap = bitmap;
-  return rescale_image (self);
-}
-
-static grub_err_t
-image_set_property (void *vself, const char *name, const char *value)
-{
-  grub_gui_image_t self = vself;
-  if (grub_strcmp (name, "theme_dir") == 0)
-    {
-      grub_free (self->theme_dir);
-      self->theme_dir = grub_strdup (value);
-    }
-  else if (grub_strcmp (name, "file") == 0)
-    {
-      char *absvalue;
-      grub_err_t err;
-
-      /* Resolve to an absolute path.  */
-      if (! self->theme_dir)
-       return grub_error (GRUB_ERR_BAD_ARGUMENT, "unspecified theme_dir");
-      absvalue = grub_resolve_relative_path (self->theme_dir, value);
-      if (! absvalue)
-       return grub_errno;
-
-      err = load_image (self, absvalue);
-      grub_free (absvalue);
-
-      return err;
-    }
-  else if (grub_strcmp (name, "id") == 0)
-    {
-      grub_free (self->id);
-      if (value)
-        self->id = grub_strdup (value);
-      else
-        self->id = 0;
-    }
-  return grub_errno;
-}
-
-static struct grub_gui_component_ops image_ops =
-{
-  .destroy = image_destroy,
-  .get_id = image_get_id,
-  .is_instance = image_is_instance,
-  .paint = image_paint,
-  .set_parent = image_set_parent,
-  .get_parent = image_get_parent,
-  .set_bounds = image_set_bounds,
-  .get_bounds = image_get_bounds,
-  .get_minimal_size = image_get_minimal_size,
-  .set_property = image_set_property
-};
-
-grub_gui_component_t
-grub_gui_image_new (void)
-{
-  grub_gui_image_t image;
-  image = grub_zalloc (sizeof (*image));
-  if (! image)
-    return 0;
-  image->component.ops = &image_ops;
-  return (grub_gui_component_t) image;
-}
-
diff --git a/gfxmenu/gui_label.c b/gfxmenu/gui_label.c
deleted file mode 100644 (file)
index a9dd575..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/* gui_label.c - GUI component to display a line of text.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/gui.h>
-#include <grub/font.h>
-#include <grub/gui_string_util.h>
-
-static const char *align_options[] =
-{
-  "left",
-  "center",
-  "right",
-  0
-};
-
-enum align_mode {
-  align_left,
-  align_center,
-  align_right
-};
-
-struct grub_gui_label
-{
-  struct grub_gui_component comp;
-
-  grub_gui_container_t parent;
-  grub_video_rect_t bounds;
-  char *id;
-  int visible;
-  char *text;
-  grub_font_t font;
-  grub_gui_color_t color;
-  enum align_mode align;
-};
-
-typedef struct grub_gui_label *grub_gui_label_t;
-
-static void
-label_destroy (void *vself)
-{
-  grub_gui_label_t self = vself;
-  grub_free (self->text);
-  grub_free (self);
-}
-
-static const char *
-label_get_id (void *vself)
-{
-  grub_gui_label_t self = vself;
-  return self->id;
-}
-
-static int
-label_is_instance (void *vself __attribute__((unused)), const char *type)
-{
-  return grub_strcmp (type, "component") == 0;
-}
-
-static void
-label_paint (void *vself, const grub_video_rect_t *region)
-{
-  grub_gui_label_t self = vself;
-
-  if (! self->visible)
-    return;
-
-  if (!grub_video_have_common_points (region, &self->bounds))
-    return;
-
-  /* Calculate the starting x coordinate.  */
-  int left_x;
-  if (self->align == align_left)
-    left_x = 0;
-  else if (self->align == align_center)
-    left_x = ((self->bounds.width
-               - grub_font_get_string_width (self->font, self->text))
-             ) / 2;
-  else if (self->align == align_right)
-    left_x = (self->bounds.width
-              - grub_font_get_string_width (self->font, self->text));
-  else
-    return;   /* Invalid alignment.  */
-
-  grub_video_rect_t vpsave;
-  grub_gui_set_viewport (&self->bounds, &vpsave);
-  grub_font_draw_string (self->text,
-                         self->font,
-                         grub_gui_map_color (self->color),
-                         left_x,
-                         grub_font_get_ascent (self->font));
-  grub_gui_restore_viewport (&vpsave);
-}
-
-static void
-label_set_parent (void *vself, grub_gui_container_t parent)
-{
-  grub_gui_label_t self = vself;
-  self->parent = parent;
-}
-
-static grub_gui_container_t
-label_get_parent (void *vself)
-{
-  grub_gui_label_t self = vself;
-  return self->parent;
-}
-
-static void
-label_set_bounds (void *vself, const grub_video_rect_t *bounds)
-{
-  grub_gui_label_t self = vself;
-  self->bounds = *bounds;
-}
-
-static void
-label_get_bounds (void *vself, grub_video_rect_t *bounds)
-{
-  grub_gui_label_t self = vself;
-  *bounds = self->bounds;
-}
-
-static void
-label_get_minimal_size (void *vself, unsigned *width, unsigned *height)
-{
-  grub_gui_label_t self = vself;
-  *width = grub_font_get_string_width (self->font, self->text);
-  *height = (grub_font_get_ascent (self->font)
-             + grub_font_get_descent (self->font));
-}
-
-static grub_err_t
-label_set_property (void *vself, const char *name, const char *value)
-{
-  grub_gui_label_t self = vself;
-  if (grub_strcmp (name, "text") == 0)
-    {
-      grub_free (self->text);
-      if (! value)
-        value = "";
-      self->text = grub_strdup (value);
-    }
-  else if (grub_strcmp (name, "font") == 0)
-    {
-      self->font = grub_font_get (value);
-    }
-  else if (grub_strcmp (name, "color") == 0)
-    {
-      grub_gui_parse_color (value, &self->color);
-    }
-  else if (grub_strcmp (name, "align") == 0)
-    {
-      int i;
-      for (i = 0; align_options[i]; i++)
-        {
-          if (grub_strcmp (align_options[i], value) == 0)
-            {
-              self->align = i;   /* Set the alignment mode.  */
-              break;
-            }
-        }
-    }
-  else if (grub_strcmp (name, "visible") == 0)
-    {
-      self->visible = grub_strcmp (value, "false") != 0;
-    }
-  else if (grub_strcmp (name, "id") == 0)
-    {
-      grub_free (self->id);
-      if (value)
-        self->id = grub_strdup (value);
-      else
-        self->id = 0;
-    }
-  return GRUB_ERR_NONE;
-}
-
-static struct grub_gui_component_ops label_ops =
-{
-  .destroy = label_destroy,
-  .get_id = label_get_id,
-  .is_instance = label_is_instance,
-  .paint = label_paint,
-  .set_parent = label_set_parent,
-  .get_parent = label_get_parent,
-  .set_bounds = label_set_bounds,
-  .get_bounds = label_get_bounds,
-  .get_minimal_size = label_get_minimal_size,
-  .set_property = label_set_property
-};
-
-grub_gui_component_t
-grub_gui_label_new (void)
-{
-  grub_gui_label_t label;
-  label = grub_zalloc (sizeof (*label));
-  if (! label)
-    return 0;
-  label->comp.ops = &label_ops;
-  label->visible = 1;
-  label->text = grub_strdup ("");
-  label->font = grub_font_get ("Unknown Regular 16");
-  label->color.red = 0;
-  label->color.green = 0;
-  label->color.blue = 0;
-  label->color.alpha = 255;
-  label->align = align_left;
-  return (grub_gui_component_t) label;
-}
diff --git a/gfxmenu/gui_list.c b/gfxmenu/gui_list.c
deleted file mode 100644 (file)
index 0d77141..0000000
+++ /dev/null
@@ -1,612 +0,0 @@
-/* gui_list.c - GUI component to display a selectable list of items.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/gui.h>
-#include <grub/gui_string_util.h>
-#include <grub/gfxmenu_view.h>
-#include <grub/gfxwidgets.h>
-
-struct grub_gui_list_impl
-{
-  struct grub_gui_list list;
-
-  grub_gui_container_t parent;
-  grub_video_rect_t bounds;
-  char *id;
-  int visible;
-
-  int icon_width;
-  int icon_height;
-  int item_height;
-  int item_padding;
-  int item_icon_space;
-  int item_spacing;
-  grub_font_t item_font;
-  grub_font_t selected_item_font;
-  grub_gui_color_t item_color;
-  int selected_item_color_set;
-  grub_gui_color_t selected_item_color;
-
-  int draw_scrollbar;
-  int need_to_recreate_scrollbar;
-  char *scrollbar_frame_pattern;
-  char *scrollbar_thumb_pattern;
-  grub_gfxmenu_box_t scrollbar_frame;
-  grub_gfxmenu_box_t scrollbar_thumb;
-  int scrollbar_width;
-
-  int first_shown_index;
-
-  int need_to_recreate_boxes;
-  char *theme_dir;
-  char *menu_box_pattern;
-  char *selected_item_box_pattern;
-  grub_gfxmenu_box_t menu_box;
-  grub_gfxmenu_box_t selected_item_box;
-
-  grub_gfxmenu_icon_manager_t icon_manager;
-
-  grub_gfxmenu_view_t view;
-};
-
-typedef struct grub_gui_list_impl *list_impl_t;
-
-static void
-list_destroy (void *vself)
-{
-  list_impl_t self = vself;
-
-  grub_free (self->theme_dir);
-  grub_free (self->menu_box_pattern);
-  grub_free (self->selected_item_box_pattern);
-  if (self->menu_box)
-    self->menu_box->destroy (self->menu_box);
-  if (self->selected_item_box)
-    self->selected_item_box->destroy (self->selected_item_box);
-  if (self->icon_manager)
-    grub_gfxmenu_icon_manager_destroy (self->icon_manager);
-
-  grub_free (self);
-}
-
-static int
-get_num_shown_items (list_impl_t self)
-{
-  int boxpad = self->item_padding;
-  int item_vspace = self->item_spacing;
-  int item_height = self->item_height;
-  
-  grub_gfxmenu_box_t box = self->menu_box;
-  int box_top_pad = box->get_top_pad (box);
-  int box_bottom_pad = box->get_bottom_pad (box);
-      
-  return (self->bounds.height + item_vspace - 2 * boxpad
-         - box_top_pad - box_bottom_pad) / (item_height + item_vspace);
-}
-
-static int
-check_boxes (list_impl_t self)
-{
-  if (self->need_to_recreate_boxes)
-    {
-      grub_gui_recreate_box (&self->menu_box,
-                             self->menu_box_pattern,
-                             self->theme_dir);
-
-      grub_gui_recreate_box (&self->selected_item_box,
-                             self->selected_item_box_pattern,
-                             self->theme_dir);
-
-      self->need_to_recreate_boxes = 0;
-    }
-
-  return (self->menu_box != 0 && self->selected_item_box != 0);
-}
-
-static int
-check_scrollbar (list_impl_t self)
-{
-  if (self->need_to_recreate_scrollbar)
-    {
-      grub_gui_recreate_box (&self->scrollbar_frame,
-                             self->scrollbar_frame_pattern,
-                             self->theme_dir);
-
-      grub_gui_recreate_box (&self->scrollbar_thumb,
-                             self->scrollbar_thumb_pattern,
-                             self->theme_dir);
-
-      self->need_to_recreate_scrollbar = 0;
-    }
-
-  return (self->scrollbar_frame != 0 && self->scrollbar_thumb != 0);
-}
-
-static const char *
-list_get_id (void *vself)
-{
-  list_impl_t self = vself;
-  return self->id;
-}
-
-static int
-list_is_instance (void *vself __attribute__((unused)), const char *type)
-{
-  return (grub_strcmp (type, "component") == 0
-          || grub_strcmp (type, "list") == 0);
-}
-
-static struct grub_video_bitmap *
-get_item_icon (list_impl_t self, int item_index)
-{
-  grub_menu_entry_t entry;
-  entry = grub_menu_get_entry (self->view->menu, item_index);
-  if (! entry)
-    return 0;
-
-  return grub_gfxmenu_icon_manager_get_icon (self->icon_manager, entry);
-}
-
-static void
-make_selected_item_visible (list_impl_t self)
-{
-  int selected_index = self->view->selected;
-  if (selected_index < 0)
-    return;   /* No item is selected.  */
-  int num_shown_items = get_num_shown_items (self);
-  int last_shown_index = self->first_shown_index + (num_shown_items - 1);
-  if (selected_index < self->first_shown_index)
-    self->first_shown_index = selected_index;
-  else if (selected_index > last_shown_index)
-    self->first_shown_index = selected_index - (num_shown_items - 1);
-}
-
-/* Draw a scrollbar on the menu.  */
-static void
-draw_scrollbar (list_impl_t self,
-                int value, int extent, int min, int max,
-                int rightx, int topy, int height)
-{
-  grub_gfxmenu_box_t frame = self->scrollbar_frame;
-  grub_gfxmenu_box_t thumb = self->scrollbar_thumb;
-  int frame_vertical_pad = (frame->get_top_pad (frame)
-                            + frame->get_bottom_pad (frame));
-  int frame_horizontal_pad = (frame->get_left_pad (frame)
-                              + frame->get_right_pad (frame));
-  int tracktop = topy + frame->get_top_pad (frame);
-  int tracklen = height - frame_vertical_pad;
-  frame->set_content_size (frame, self->scrollbar_width, tracklen);
-  int thumby = tracktop + tracklen * (value - min) / (max - min);
-  int thumbheight = tracklen * extent / (max - min) + 1;
-  thumb->set_content_size (thumb,
-                           self->scrollbar_width - frame_horizontal_pad,
-                           thumbheight - (thumb->get_top_pad (thumb)
-                                          + thumb->get_bottom_pad (thumb)));
-  frame->draw (frame,
-               rightx - (self->scrollbar_width + frame_horizontal_pad),
-               topy);
-  thumb->draw (thumb,
-               rightx - (self->scrollbar_width - frame->get_right_pad (frame)),
-               thumby);
-}
-
-/* Draw the list of items.  */
-static void
-draw_menu (list_impl_t self, int width, int drawing_scrollbar,
-          int num_shown_items)
-{
-  if (! self->menu_box || ! self->selected_item_box)
-    return;
-
-  int boxpad = self->item_padding;
-  int icon_text_space = self->item_icon_space;
-  int item_vspace = self->item_spacing;
-
-  int ascent = grub_font_get_ascent (self->item_font);
-  int descent = grub_font_get_descent (self->item_font);
-  int item_height = self->item_height;
-
-  make_selected_item_visible (self);
-
-  int scrollbar_h_space = drawing_scrollbar ? self->scrollbar_width : 0;
-
-  grub_gfxmenu_box_t selbox = self->selected_item_box;
-  int sel_leftpad = selbox->get_left_pad (selbox);
-  int item_top = boxpad;
-  int item_left = boxpad + sel_leftpad;
-  int menu_index;
-  int visible_index;
-
-  for (visible_index = 0, menu_index = self->first_shown_index;
-       visible_index < num_shown_items && menu_index < self->view->menu->size;
-       visible_index++, menu_index++)
-    {
-      int is_selected = (menu_index == self->view->selected);
-
-      if (is_selected)
-        {
-          int sel_toppad = selbox->get_top_pad (selbox);
-          selbox->set_content_size (selbox,
-                                    (width - 2 * boxpad
-                                     - scrollbar_h_space),
-                                    item_height);
-          selbox->draw (selbox,
-                        item_left - sel_leftpad,
-                        item_top - sel_toppad);
-        }
-
-      struct grub_video_bitmap *icon;
-      if ((icon = get_item_icon (self, menu_index)) != 0)
-        grub_video_blit_bitmap (icon, GRUB_VIDEO_BLIT_BLEND,
-                                item_left,
-                                item_top + (item_height - self->icon_height) / 2,
-                                0, 0, self->icon_width, self->icon_height);
-
-      const char *item_title =
-        grub_menu_get_entry (self->view->menu, menu_index)->title;
-      grub_font_t font =
-        (is_selected && self->selected_item_font
-         ? self->selected_item_font
-         : self->item_font);
-      grub_gui_color_t text_color =
-        ((is_selected && self->selected_item_color_set)
-         ? self->selected_item_color
-         : self->item_color);
-      grub_font_draw_string (item_title,
-                             font,
-                             grub_gui_map_color (text_color),
-                             item_left + self->icon_width + icon_text_space,
-                             (item_top + (item_height - (ascent + descent))
-                              / 2 + ascent));
-
-      item_top += item_height + item_vspace;
-    }
-}
-
-static void
-list_paint (void *vself, const grub_video_rect_t *region)
-{
-  list_impl_t self = vself;
-  grub_video_rect_t vpsave;
-
-  if (! self->visible)
-    return;
-  if (!grub_video_have_common_points (region, &self->bounds))
-    return;
-
-  check_boxes (self);
-
-  if (! self->menu_box || ! self->selected_item_box)
-    return;
-
-  grub_gui_set_viewport (&self->bounds, &vpsave);
-  {
-    grub_gfxmenu_box_t box = self->menu_box;
-    int box_left_pad = box->get_left_pad (box);
-    int box_top_pad = box->get_top_pad (box);
-    int box_right_pad = box->get_right_pad (box);
-    int box_bottom_pad = box->get_bottom_pad (box);
-    grub_video_rect_t vpsave2, content_rect;
-    int num_shown_items = get_num_shown_items (self);
-    int drawing_scrollbar = (self->draw_scrollbar
-                            && (num_shown_items < self->view->menu->size)
-                            && check_scrollbar (self));
-
-    content_rect.x = box_left_pad;
-    content_rect.y = box_top_pad;
-    content_rect.width = self->bounds.width - box_left_pad - box_right_pad;
-    content_rect.height = self->bounds.height - box_top_pad - box_bottom_pad;
-
-    box->set_content_size (box, content_rect.width, content_rect.height);
-
-    box->draw (box, 0, 0);
-
-    grub_gui_set_viewport (&content_rect, &vpsave2);
-    draw_menu (self, content_rect.width, drawing_scrollbar, num_shown_items);
-    grub_gui_restore_viewport (&vpsave2);
-
-    if (drawing_scrollbar)
-      draw_scrollbar (self,
-                     self->first_shown_index, num_shown_items,
-                     0, self->view->menu->size,
-                     self->bounds.width - box_right_pad
-                     + self->scrollbar_width,
-                     box_top_pad + self->item_padding,
-                     self->bounds.height - box_top_pad - box_bottom_pad);
-  }
-
-  grub_gui_restore_viewport (&vpsave);
-}
-
-static void
-list_set_parent (void *vself, grub_gui_container_t parent)
-{
-  list_impl_t self = vself;
-  self->parent = parent;
-}
-
-static grub_gui_container_t
-list_get_parent (void *vself)
-{
-  list_impl_t self = vself;
-  return self->parent;
-}
-
-static void
-list_set_bounds (void *vself, const grub_video_rect_t *bounds)
-{
-  list_impl_t self = vself;
-  self->bounds = *bounds;
-}
-
-static void
-list_get_bounds (void *vself, grub_video_rect_t *bounds)
-{
-  list_impl_t self = vself;
-  *bounds = self->bounds;
-}
-
-static void
-list_get_minimal_size (void *vself, unsigned *width, unsigned *height)
-{
-  list_impl_t self = vself;
-
-  if (check_boxes (self))
-    {
-      int boxpad = self->item_padding;
-      int item_vspace = self->item_spacing;
-      int item_height = self->item_height;
-      int num_items = 3;
-
-      grub_gfxmenu_box_t box = self->menu_box;
-      int box_left_pad = box->get_left_pad (box);
-      int box_top_pad = box->get_top_pad (box);
-      int box_right_pad = box->get_right_pad (box);
-      int box_bottom_pad = box->get_bottom_pad (box);
-      unsigned width_s;
-      
-      *width = grub_font_get_string_width (self->item_font, "Typical OS");
-      width_s = grub_font_get_string_width (self->selected_item_font,
-                                           "Typical OS");
-      if (*width < width_s)
-       *width = width_s;
-
-      *width += 2 * boxpad + box_left_pad + box_right_pad;
-
-      /* Set the menu box height to fit the items.  */
-      *height = (item_height * num_items
-                 + item_vspace * (num_items - 1)
-                 + 2 * boxpad
-                 + box_top_pad + box_bottom_pad);
-    }
-  else
-    {
-      *width = 0;
-      *height = 0;
-    }
-}
-
-static grub_err_t
-list_set_property (void *vself, const char *name, const char *value)
-{
-  list_impl_t self = vself;
-  if (grub_strcmp (name, "item_font") == 0)
-    {
-      self->item_font = grub_font_get (value);
-    }
-  else if (grub_strcmp (name, "selected_item_font") == 0)
-    {
-      if (! value || grub_strcmp (value, "inherit") == 0)
-        self->selected_item_font = 0;
-      else
-        self->selected_item_font = grub_font_get (value);
-    }
-  else if (grub_strcmp (name, "item_color") == 0)
-    {
-      grub_gui_parse_color (value, &self->item_color);
-    }
-  else if (grub_strcmp (name, "selected_item_color") == 0)
-    {
-      if (! value || grub_strcmp (value, "inherit") == 0)
-        {
-          self->selected_item_color_set = 0;
-        }
-      else
-        {
-          if (grub_gui_parse_color (value, &self->selected_item_color)
-              == GRUB_ERR_NONE)
-            self->selected_item_color_set = 1;
-        }
-    }
-  else if (grub_strcmp (name, "icon_width") == 0)
-    {
-      self->icon_width = grub_strtol (value, 0, 10);
-      grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager,
-                                               self->icon_width,
-                                               self->icon_height);
-    }
-  else if (grub_strcmp (name, "icon_height") == 0)
-    {
-      self->icon_height = grub_strtol (value, 0, 10);
-      grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager,
-                                               self->icon_width,
-                                               self->icon_height);
-    }
-  else if (grub_strcmp (name, "item_height") == 0)
-    {
-      self->item_height = grub_strtol (value, 0, 10);
-    }
-  else if (grub_strcmp (name, "item_padding") == 0)
-    {
-      self->item_padding = grub_strtol (value, 0, 10);
-    }
-  else if (grub_strcmp (name, "item_icon_space") == 0)
-    {
-      self->item_icon_space = grub_strtol (value, 0, 10);
-    }
-  else if (grub_strcmp (name, "item_spacing") == 0)
-    {
-      self->item_spacing = grub_strtol (value, 0, 10);
-    }
-  else if (grub_strcmp (name, "visible") == 0)
-    {
-      self->visible = grub_strcmp (value, "false") != 0;
-    }
-  else if (grub_strcmp (name, "menu_pixmap_style") == 0)
-    {
-      self->need_to_recreate_boxes = 1;
-      grub_free (self->menu_box_pattern);
-      self->menu_box_pattern = value ? grub_strdup (value) : 0;
-    }
-  else if (grub_strcmp (name, "selected_item_pixmap_style") == 0)
-    {
-      self->need_to_recreate_boxes = 1;
-      grub_free (self->selected_item_box_pattern);
-      self->selected_item_box_pattern = value ? grub_strdup (value) : 0;
-    }
-  else if (grub_strcmp (name, "scrollbar_frame") == 0)
-    {
-      self->need_to_recreate_scrollbar = 1;
-      grub_free (self->scrollbar_frame_pattern);
-      self->scrollbar_frame_pattern = value ? grub_strdup (value) : 0;
-    }
-  else if (grub_strcmp (name, "scrollbar_thumb") == 0)
-    {
-      self->need_to_recreate_scrollbar = 1;
-      grub_free (self->scrollbar_thumb_pattern);
-      self->scrollbar_thumb_pattern = value ? grub_strdup (value) : 0;
-    }
-  else if (grub_strcmp (name, "scrollbar_width") == 0)
-    {
-      self->scrollbar_width = grub_strtol (value, 0, 10);
-    }
-  else if (grub_strcmp (name, "scrollbar") == 0)
-    {
-      self->draw_scrollbar = grub_strcmp (value, "false") != 0;
-    }
-  else if (grub_strcmp (name, "theme_dir") == 0)
-    {
-      self->need_to_recreate_boxes = 1;
-      grub_free (self->theme_dir);
-      self->theme_dir = value ? grub_strdup (value) : 0;
-    }
-  else if (grub_strcmp (name, "id") == 0)
-    {
-      grub_free (self->id);
-      if (value)
-        self->id = grub_strdup (value);
-      else
-        self->id = 0;
-    }
-  return grub_errno;
-}
-
-/* Set necessary information that the gfxmenu view provides.  */
-static void
-list_set_view_info (void *vself,
-                    grub_gfxmenu_view_t view)
-{
-  list_impl_t self = vself;
-  grub_gfxmenu_icon_manager_set_theme_path (self->icon_manager,
-                                           view->theme_path);
-  self->view = view;
-}
-
-static struct grub_gui_component_ops list_comp_ops =
-  {
-    .destroy = list_destroy,
-    .get_id = list_get_id,
-    .is_instance = list_is_instance,
-    .paint = list_paint,
-    .set_parent = list_set_parent,
-    .get_parent = list_get_parent,
-    .set_bounds = list_set_bounds,
-    .get_bounds = list_get_bounds,
-    .get_minimal_size = list_get_minimal_size,
-    .set_property = list_set_property
-  };
-
-static struct grub_gui_list_ops list_ops =
-{
-  .set_view_info = list_set_view_info
-};
-
-grub_gui_component_t
-grub_gui_list_new (void)
-{
-  list_impl_t self;
-  grub_font_t default_font;
-  grub_gui_color_t default_fg_color;
-  grub_gui_color_t default_bg_color;
-
-  self = grub_zalloc (sizeof (*self));
-  if (! self)
-    return 0;
-
-  self->list.ops = &list_ops;
-  self->list.component.ops = &list_comp_ops;
-
-  self->visible = 1;
-
-  default_font = grub_font_get ("Unknown Regular 16");
-  default_fg_color = grub_gui_color_rgb (0, 0, 0);
-  default_bg_color = grub_gui_color_rgb (255, 255, 255);
-
-  self->icon_width = 32;
-  self->icon_height = 32;
-  self->item_height = 42;
-  self->item_padding = 14;
-  self->item_icon_space = 4;
-  self->item_spacing = 16;
-  self->item_font = default_font;
-  self->selected_item_font = 0;    /* Default to using the item_font.  */
-  self->item_color = default_fg_color;
-  self->selected_item_color_set = 0;  /* Default to using the item_color.  */
-  self->selected_item_color = default_fg_color;
-
-  self->draw_scrollbar = 1;
-  self->need_to_recreate_scrollbar = 1;
-  self->scrollbar_frame = 0;
-  self->scrollbar_thumb = 0;
-  self->scrollbar_frame_pattern = 0;
-  self->scrollbar_thumb_pattern = 0;
-  self->scrollbar_width = 16;
-
-  self->first_shown_index = 0;
-
-  self->need_to_recreate_boxes = 0;
-  self->theme_dir = 0;
-  self->menu_box_pattern = 0;
-  self->selected_item_box_pattern = 0;
-  self->menu_box = grub_gfxmenu_create_box (0, 0);
-  self->selected_item_box = grub_gfxmenu_create_box (0, 0);
-
-  self->icon_manager = grub_gfxmenu_icon_manager_new ();
-  if (! self->icon_manager)
-    {
-      self->list.component.ops->destroy (self);
-      return 0;
-    }
-  grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager,
-                                           self->icon_width,
-                                           self->icon_height);
-  return (grub_gui_component_t) self;
-}
diff --git a/gfxmenu/gui_progress_bar.c b/gfxmenu/gui_progress_bar.c
deleted file mode 100644 (file)
index d786aae..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-/* gui_progress_bar.c - GUI progress bar component.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/gui.h>
-#include <grub/font.h>
-#include <grub/gui_string_util.h>
-#include <grub/gfxmenu_view.h>
-#include <grub/gfxwidgets.h>
-#include <grub/i18n.h>
-
-struct grub_gui_progress_bar
-{
-  struct grub_gui_progress progress;
-
-  grub_gui_container_t parent;
-  grub_video_rect_t bounds;
-  char *id;
-  int visible;
-  int start;
-  int end;
-  int value;
-  int show_text;
-  char *template;
-  grub_font_t font;
-  grub_gui_color_t text_color;
-  grub_gui_color_t border_color;
-  grub_gui_color_t bg_color;
-  grub_gui_color_t fg_color;
-
-  char *theme_dir;
-  int need_to_recreate_pixmaps;
-  int pixmapbar_available;
-  char *bar_pattern;
-  char *highlight_pattern;
-  grub_gfxmenu_box_t bar_box;
-  grub_gfxmenu_box_t highlight_box;
-};
-
-typedef struct grub_gui_progress_bar *grub_gui_progress_bar_t;
-
-static void
-progress_bar_destroy (void *vself)
-{
-  grub_gui_progress_bar_t self = vself;
-  grub_free (self);
-}
-
-static const char *
-progress_bar_get_id (void *vself)
-{
-  grub_gui_progress_bar_t self = vself;
-  return self->id;
-}
-
-static int
-progress_bar_is_instance (void *vself __attribute__((unused)), const char *type)
-{
-  return grub_strcmp (type, "component") == 0;
-}
-
-static int
-check_pixmaps (grub_gui_progress_bar_t self)
-{
-  if (!self->pixmapbar_available)
-    return 0;
-  if (self->need_to_recreate_pixmaps)
-    {
-      grub_gui_recreate_box (&self->bar_box,
-                             self->bar_pattern,
-                             self->theme_dir);
-
-      grub_gui_recreate_box (&self->highlight_box,
-                             self->highlight_pattern,
-                             self->theme_dir);
-
-      self->need_to_recreate_pixmaps = 0;
-    }
-
-  return (self->bar_box != 0 && self->highlight_box != 0);
-}
-
-static void
-draw_filled_rect_bar (grub_gui_progress_bar_t self)
-{
-  /* Set the progress bar's frame.  */
-  grub_video_rect_t f;
-  f.x = 1;
-  f.y = 1;
-  f.width = self->bounds.width - 2;
-  f.height = self->bounds.height - 2;
-
-  /* Border.  */
-  grub_video_fill_rect (grub_gui_map_color (self->border_color),
-                        f.x - 1, f.y - 1,
-                        f.width + 2, f.height + 2);
-
-  /* Bar background.  */
-  int barwidth = (f.width
-                  * (self->value - self->start)
-                  / (self->end - self->start));
-  grub_video_fill_rect (grub_gui_map_color (self->bg_color),
-                        f.x + barwidth, f.y,
-                        f.width - barwidth, f.height);
-
-  /* Bar foreground.  */
-  grub_video_fill_rect (grub_gui_map_color (self->fg_color),
-                        f.x, f.y,
-                        barwidth, f.height);
-}
-
-static void
-draw_pixmap_bar (grub_gui_progress_bar_t self)
-{
-  grub_gfxmenu_box_t bar = self->bar_box;
-  grub_gfxmenu_box_t hl = self->highlight_box;
-  int w = self->bounds.width;
-  int h = self->bounds.height;
-  int bar_l_pad = bar->get_left_pad (bar);
-  int bar_r_pad = bar->get_right_pad (bar);
-  int bar_t_pad = bar->get_top_pad (bar);
-  int bar_b_pad = bar->get_bottom_pad (bar);
-  int bar_h_pad = bar_l_pad + bar_r_pad;
-  int bar_v_pad = bar_t_pad + bar_b_pad;
-  int tracklen = w - bar_h_pad;
-  int trackheight = h - bar_v_pad;
-  int barwidth;
-
-  bar->set_content_size (bar, tracklen, trackheight);
-
-  barwidth = (tracklen * (self->value - self->start) 
-             / (self->end - self->start));
-
-  hl->set_content_size (hl, barwidth, h - bar_v_pad);
-
-  bar->draw (bar, 0, 0);
-  hl->draw (hl, bar_l_pad, bar_t_pad);
-}
-
-static void
-draw_text (grub_gui_progress_bar_t self)
-{
-  if (self->template)
-    {
-      grub_font_t font = self->font;
-      grub_video_color_t text_color = grub_gui_map_color (self->text_color);
-      int width = self->bounds.width;
-      int height = self->bounds.height;
-      char *text;
-      text = grub_xasprintf (self->template,
-                            self->value > 0 ? self->value : -self->value);
-      if (!text)
-       {
-         grub_print_error ();
-         grub_errno = GRUB_ERR_NONE;
-         return;
-       }
-      /* Center the text. */
-      int text_width = grub_font_get_string_width (font, text);
-      int x = (width - text_width) / 2;
-      int y = ((height - grub_font_get_descent (font)) / 2
-               + grub_font_get_ascent (font) / 2);
-      grub_font_draw_string (text, font, text_color, x, y);
-    }
-}
-
-static void
-progress_bar_paint (void *vself, const grub_video_rect_t *region)
-{
-  grub_gui_progress_bar_t self = vself;
-  grub_video_rect_t vpsave;
-
-  if (! self->visible)
-    return;
-  if (!grub_video_have_common_points (region, &self->bounds))
-    return;
-
-  if (self->end == self->start)
-    return;
-
-  grub_gui_set_viewport (&self->bounds, &vpsave);
-
-  if (check_pixmaps (self))
-    draw_pixmap_bar (self);
-  else
-    draw_filled_rect_bar (self);
-
-  draw_text (self);
-
-  grub_gui_restore_viewport (&vpsave);
-}
-
-static void
-progress_bar_set_parent (void *vself, grub_gui_container_t parent)
-{
-  grub_gui_progress_bar_t self = vself;
-  self->parent = parent;
-}
-
-static grub_gui_container_t
-progress_bar_get_parent (void *vself)
-{
-  grub_gui_progress_bar_t self = vself;
-  return self->parent;
-}
-
-static void
-progress_bar_set_bounds (void *vself, const grub_video_rect_t *bounds)
-{
-  grub_gui_progress_bar_t self = vself;
-  self->bounds = *bounds;
-}
-
-static void
-progress_bar_get_bounds (void *vself, grub_video_rect_t *bounds)
-{
-  grub_gui_progress_bar_t self = vself;
-  *bounds = self->bounds;
-}
-
-static void
-progress_bar_get_minimal_size (void *vself,
-                              unsigned *width, unsigned *height)
-{
-  unsigned text_width = 0, text_height = 0;
-  grub_gui_progress_bar_t self = vself;
-
-  if (self->template)
-    {
-      text_width = grub_font_get_string_width (self->font, self->template);
-      text_width += grub_font_get_string_width (self->font, "XXXXXXXXXX");
-      text_height = grub_font_get_descent (self->font)
-       + grub_font_get_ascent (self->font);
-    }
-  *width = 200;
-  if (*width < text_width)
-    *width = text_width;
-  *height = 28;
-  if (*height < text_height)
-    *height = text_height;
-}
-
-static void
-progress_bar_set_state (void *vself, int visible, int start,
-                       int current, int end)
-{
-  grub_gui_progress_bar_t self = vself;  
-  self->visible = visible;
-  self->start = start;
-  self->value = current;
-  self->end = end;
-}
-
-static grub_err_t
-progress_bar_set_property (void *vself, const char *name, const char *value)
-{
-  grub_gui_progress_bar_t self = vself;
-  if (grub_strcmp (name, "text") == 0)
-    {
-      grub_free (self->template);
-      if (grub_strcmp (value, "@TIMEOUT_NOTIFICATION_LONG@") == 0)
-       value 
-         = _("The highlighted entry will be executed automatically in %ds.");
-      else if (grub_strcmp (value, "@TIMEOUT_NOTIFICATION_MIDDLE@") == 0)
-       /* TRANSLATORS:  's' stands for seconds.
-          It's a standalone timeout notification.
-          Please use the short form in your language.  */
-       value = _("%ds remaining.");
-      else if (grub_strcmp (value, "@TIMEOUT_NOTIFICATION_SHORT@") == 0)
-       /* TRANSLATORS:  's' stands for seconds.
-          It's a standalone timeout notification.
-          Please use the shortest form available in you language.  */
-       value = _("%ds");
-
-      self->template = grub_strdup (value);
-    }
-  else if (grub_strcmp (name, "font") == 0)
-    {
-      self->font = grub_font_get (value);
-    }
-  else if (grub_strcmp (name, "text_color") == 0)
-    {
-      grub_gui_parse_color (value, &self->text_color);
-    }
-  else if (grub_strcmp (name, "border_color") == 0)
-    {
-       grub_gui_parse_color (value, &self->border_color);
-    }
-  else if (grub_strcmp (name, "bg_color") == 0)
-    {
-       grub_gui_parse_color (value, &self->bg_color);
-    }
-  else if (grub_strcmp (name, "fg_color") == 0)
-    {
-      grub_gui_parse_color (value, &self->fg_color);
-    }
-  else if (grub_strcmp (name, "bar_style") == 0)
-    {
-      self->need_to_recreate_pixmaps = 1;
-      self->pixmapbar_available = 1;
-      grub_free (self->bar_pattern);
-      self->bar_pattern = value ? grub_strdup (value) : 0;
-    }
-  else if (grub_strcmp (name, "highlight_style") == 0)
-    {
-      self->need_to_recreate_pixmaps = 1;
-      self->pixmapbar_available = 1;
-      grub_free (self->highlight_pattern);
-      self->highlight_pattern = value ? grub_strdup (value) : 0;
-    }
-  else if (grub_strcmp (name, "theme_dir") == 0)
-    {
-      self->need_to_recreate_pixmaps = 1;
-      grub_free (self->theme_dir);
-      self->theme_dir = value ? grub_strdup (value) : 0;
-    }
-  else if (grub_strcmp (name, "id") == 0)
-    {
-      grub_free (self->id);
-      if (value)
-        self->id = grub_strdup (value);
-      else
-        self->id = 0;
-    }
-  return grub_errno;
-}
-
-static struct grub_gui_component_ops progress_bar_ops =
-{
-  .destroy = progress_bar_destroy,
-  .get_id = progress_bar_get_id,
-  .is_instance = progress_bar_is_instance,
-  .paint = progress_bar_paint,
-  .set_parent = progress_bar_set_parent,
-  .get_parent = progress_bar_get_parent,
-  .set_bounds = progress_bar_set_bounds,
-  .get_bounds = progress_bar_get_bounds,
-  .get_minimal_size = progress_bar_get_minimal_size,
-  .set_property = progress_bar_set_property
-};
-
-static struct grub_gui_progress_ops progress_bar_pb_ops =
-  {
-    .set_state = progress_bar_set_state
-  };
-
-grub_gui_component_t
-grub_gui_progress_bar_new (void)
-{
-  grub_gui_progress_bar_t self;
-  self = grub_zalloc (sizeof (*self));
-  if (! self)
-    return 0;
-  self->progress.ops = &progress_bar_pb_ops;
-  self->progress.component.ops = &progress_bar_ops;
-  self->visible = 1;
-  self->font = grub_font_get ("Unknown Regular 16");
-  grub_gui_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 };
-  grub_gui_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 };
-  grub_gui_color_t lightgray = { .red = 200, .green = 200, .blue = 200, .alpha = 255 };
-  self->text_color = black;
-  self->border_color = black;
-  self->bg_color = gray;
-  self->fg_color = lightgray;
-
-  return (grub_gui_component_t) self;
-}
diff --git a/gfxmenu/gui_string_util.c b/gfxmenu/gui_string_util.c
deleted file mode 100644 (file)
index 8c51e39..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-/* gui_string_util.c - String utilities used by the GUI system.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/gui_string_util.h>
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-
-/* Create a new NUL-terminated string on the heap as a substring of BUF.
-   The range of buf included is the half-open interval [START,END).
-   The index START is inclusive, END is exclusive.  */
-char *
-grub_new_substring (const char *buf,
-                    grub_size_t start, grub_size_t end)
-{
-  if (end < start)
-    return 0;
-  grub_size_t len = end - start;
-  char *s = grub_malloc (len + 1);
-  if (! s)
-    return 0;
-  grub_memcpy (s, buf + start, len);
-  s[len] = '\0';
-  return s;
-}
-
-/* Eliminate "." and ".." path elements from PATH.  A new heap-allocated
-   string is returned.  */
-static char *
-canonicalize_path (const char *path)
-{
-  int i;
-  const char *p;
-  char *newpath = 0;
-
-  /* Count the path components in path.  */
-  int components = 1;
-  for (p = path; *p; p++)
-    if (*p == '/')
-      components++;
-
-  char **path_array = grub_malloc (components * sizeof (*path_array));
-  if (! path_array)
-    return 0;
-
-  /* Initialize array elements to NULL pointers; in case once of the
-     allocations fails, the cleanup code can just call grub_free() for all
-     pointers in the array.  */
-  for (i = 0; i < components; i++)
-    path_array[i] = 0;
-
-  /* Parse the path into path_array.  */
-  p = path;
-  for (i = 0; i < components && p; i++)
-    {
-      /* Find the end of the path element.  */
-      const char *end = grub_strchr (p, '/');
-      if (!end)
-        end = p + grub_strlen (p);
-
-      /* Copy the element.  */
-      path_array[i] = grub_new_substring (p, 0, end - p);
-      if (! path_array[i])
-        goto cleanup;
-
-      /* Advance p to point to the start of the next element, or NULL.  */
-      if (*end)
-        p = end + 1;
-      else
-        p = 0;
-    }
-
-  /* Eliminate '.' and '..' elements from the path array.  */
-  int newpath_length = 0;
-  for (i = components - 1; i >= 0; --i)
-    {
-      if (! grub_strcmp (path_array[i], "."))
-        {
-          grub_free (path_array[i]);
-          path_array[i] = 0;
-        }
-      else if (! grub_strcmp (path_array[i], "..")
-               && i > 0)
-        {
-          /* Delete the '..' and the prior path element.  */
-          grub_free (path_array[i]);
-          path_array[i] = 0;
-          --i;
-          grub_free (path_array[i]);
-          path_array[i] = 0;
-        }
-      else
-        {
-          newpath_length += grub_strlen (path_array[i]) + 1;
-        }
-    }
-
-  /* Construct a new path string.  */
-  newpath = grub_malloc (newpath_length + 1);
-  if (! newpath)
-    goto cleanup;
-
-  newpath[0] = '\0';
-  char *newpath_end = newpath;
-  int first = 1;
-  for (i = 0; i < components; i++)
-    {
-      char *element = path_array[i];
-      if (element)
-        {
-          /* For all components but the first, prefix with a slash.  */
-          if (! first)
-            newpath_end = grub_stpcpy (newpath_end, "/");
-          newpath_end = grub_stpcpy (newpath_end, element);
-          first = 0;
-        }
-    }
-
-cleanup:
-  for (i = 0; i < components; i++)
-    grub_free (path_array[i]);
-  grub_free (path_array);
-
-  return newpath;
-}
-
-/* Return a new heap-allocated string representing to absolute path
-   to the file referred to by PATH.  If PATH is an absolute path, then
-   the returned path is a copy of PATH.  If PATH is a relative path, then
-   BASE is with PATH used to construct the absolute path.  */
-char *
-grub_resolve_relative_path (const char *base, const char *path)
-{
-  char *abspath;
-  char *canonpath;
-  char *p;
-  grub_size_t l;
-
-  /* If PATH is an absolute path, then just use it as is.  */
-  if (path[0] == '/' || path[0] == '(')
-    return canonicalize_path (path);
-
-  abspath = grub_malloc (grub_strlen (base) + grub_strlen (path) + 3);
-  if (! abspath)
-    return 0;
-
-  /* Concatenate BASE and PATH.  */
-  p = grub_stpcpy (abspath, base);
-  l = grub_strlen (abspath);
-  if (l == 0 || abspath[l-1] != '/')
-    {
-      *p = '/';
-      p++;
-      *p = 0;
-    }
-  grub_stpcpy (p, path);
-
-  canonpath = canonicalize_path (abspath);
-  if (! canonpath)
-    return abspath;
-
-  grub_free (abspath);
-  return canonpath;
-}
-
-/* Get the path of the directory where the file at FILE_PATH is located.
-   FILE_PATH should refer to a file, not a directory.  The returned path
-   includes a trailing slash.
-   This does not handle GRUB "(hd0,0)" paths properly yet since it only
-   looks at slashes.  */
-char *
-grub_get_dirname (const char *file_path)
-{
-  int i;
-  int last_slash;
-
-  last_slash = -1;
-  for (i = grub_strlen (file_path) - 1; i >= 0; --i)
-    {
-      if (file_path[i] == '/')
-        {
-          last_slash = i;
-          break;
-        }
-    }
-  if (last_slash == -1)
-    return grub_strdup ("/");
-
-  return grub_new_substring (file_path, 0, last_slash + 1);
-}
-
-static __inline int
-my_isxdigit (char c)
-{
-  return ((c >= '0' && c <= '9')
-          || (c >= 'a' && c <= 'f')
-          || (c >= 'A' && c <= 'F'));
-}
-
-static int
-parse_hex_color_component (const char *s, unsigned start, unsigned end)
-{
-  unsigned len;
-  char buf[3];
-
-  len = end - start;
-  /* Check the limits so we don't overrun the buffer.  */
-  if (len < 1 || len > 2)
-    return 0;
-
-  if (len == 1)
-    {
-      buf[0] = s[start];   /* Get the first and only hex digit.  */
-      buf[1] = buf[0];     /* Duplicate the hex digit.  */
-    }
-  else if (len == 2)
-    {
-      buf[0] = s[start];
-      buf[1] = s[start + 1];
-    }
-
-  buf[2] = '\0';
-
-  return grub_strtoul (buf, 0, 16);
-}
-
-/* Parse a color string of the form "r, g, b", "#RGB", "#RGBA",
-   "#RRGGBB", or "#RRGGBBAA".  */
-grub_err_t
-grub_gui_parse_color (const char *s, grub_gui_color_t *color)
-{
-  grub_gui_color_t c;
-
-  /* Skip whitespace.  */
-  while (*s && grub_isspace (*s))
-    s++;
-
-  if (*s == '#')
-    {
-      /* HTML-style.  Number if hex digits:
-         [6] #RRGGBB     [3] #RGB
-         [8] #RRGGBBAA   [4] #RGBA  */
-
-      s++;  /* Skip the '#'.  */
-      /* Count the hexits to determine the format.  */
-      int hexits = 0;
-      const char *end = s;
-      while (my_isxdigit (*end))
-        {
-          end++;
-          hexits++;
-        }
-
-      /* Parse the color components based on the format.  */
-      if (hexits == 3 || hexits == 4)
-        {
-          c.red = parse_hex_color_component (s, 0, 1);
-          c.green = parse_hex_color_component (s, 1, 2);
-          c.blue = parse_hex_color_component (s, 2, 3);
-          if (hexits == 4)
-            c.alpha = parse_hex_color_component (s, 3, 4);
-          else
-            c.alpha = 255;
-        }
-      else if (hexits == 6 || hexits == 8)
-        {
-          c.red = parse_hex_color_component (s, 0, 2);
-          c.green = parse_hex_color_component (s, 2, 4);
-          c.blue = parse_hex_color_component (s, 4, 6);
-          if (hexits == 8)
-            c.alpha = parse_hex_color_component (s, 6, 8);
-          else
-            c.alpha = 255;
-        }
-      else
-        return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                           "invalid HTML-type color string `%s'", s);
-    }
-  else if (grub_isdigit (*s))
-    {
-      /* Comma separated decimal values.  */
-      c.red = grub_strtoul (s, 0, 0);
-      if ((s = grub_strchr (s, ',')) == 0)
-        return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                           "missing 1st comma separator in color `%s'", s);
-      s++;
-      c.green = grub_strtoul (s, 0, 0);
-      if ((s = grub_strchr (s, ',')) == 0)
-        return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                           "missing 2nd comma separator in color `%s'", s);
-      s++;
-      c.blue = grub_strtoul (s, 0, 0);
-      if ((s = grub_strchr (s, ',')) == 0)
-        c.alpha = 255;
-      else
-        {
-          s++;
-          c.alpha = grub_strtoul (s, 0, 0);
-        }
-    }
-  else
-    {
-      if (! grub_gui_get_named_color (s, &c))
-        return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                           "invalid named color `%s'", s);
-    }
-
-  if (grub_errno == GRUB_ERR_NONE)
-    *color = c;
-  return grub_errno;
-}
diff --git a/gfxmenu/gui_util.c b/gfxmenu/gui_util.c
deleted file mode 100644 (file)
index eba7bb3..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/* gui_util.c - GUI utility functions.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/gui.h>
-#include <grub/gui_string_util.h>
-
-
-struct find_by_id_state
-{
-  const char *match_id;
-  grub_gui_component_callback match_callback;
-  void *match_userdata;
-};
-
-static void
-find_by_id_recursively (grub_gui_component_t component, void *userdata)
-{
-  struct find_by_id_state *state;
-  const char *id;
-
-  state = (struct find_by_id_state *) userdata;
-  id = component->ops->get_id (component);
-  if (id && grub_strcmp (id, state->match_id) == 0)
-    state->match_callback (component, state->match_userdata);
-
-  if (component->ops->is_instance (component, "container"))
-    {
-      grub_gui_container_t container;
-      container = (grub_gui_container_t) component;
-      container->ops->iterate_children (container,
-                                        find_by_id_recursively,
-                                        state);
-    }
-}
-
-void
-grub_gui_find_by_id (grub_gui_component_t root,
-                     const char *id,
-                     grub_gui_component_callback cb,
-                     void *userdata)
-{
-  struct find_by_id_state state;
-  state.match_id = id;
-  state.match_callback = cb;
-  state.match_userdata = userdata;
-  find_by_id_recursively (root, &state);
-}
-
-
-struct iterate_recursively_state
-{
-  grub_gui_component_callback callback;
-  void *userdata;
-};
-
-static
-void iterate_recursively_cb (grub_gui_component_t component, void *userdata)
-{
-  struct iterate_recursively_state *state;
-
-  state = (struct iterate_recursively_state *) userdata;
-  state->callback (component, state->userdata);
-
-  if (component->ops->is_instance (component, "container"))
-    {
-      grub_gui_container_t container;
-      container = (grub_gui_container_t) component;
-      container->ops->iterate_children (container,
-                                        iterate_recursively_cb,
-                                        state);
-    }
-}
-
-void
-grub_gui_iterate_recursively (grub_gui_component_t root,
-                              grub_gui_component_callback cb,
-                              void *userdata)
-{
-  struct iterate_recursively_state state;
-  state.callback = cb;
-  state.userdata = userdata;
-  iterate_recursively_cb (root, &state);
-}
diff --git a/gfxmenu/icon_manager.c b/gfxmenu/icon_manager.c
deleted file mode 100644 (file)
index 0c304ed..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/* icon_manager.c - gfxmenu icon manager.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/gui_string_util.h>
-#include <grub/bitmap.h>
-#include <grub/bitmap_scale.h>
-#include <grub/menu.h>
-#include <grub/icon_manager.h>
-#include <grub/env.h>
-
-/* Currently hard coded to '.png' extension.  */
-static const char icon_extension[] = ".png";
-
-typedef struct icon_entry
-{
-  char *class_name;
-  struct grub_video_bitmap *bitmap;
-  struct icon_entry *next;
-} *icon_entry_t;
-
-struct grub_gfxmenu_icon_manager
-{
-  char *theme_path;
-  int icon_width;
-  int icon_height;
-
-  /* Icon cache: linked list w/ dummy head node.  */
-  struct icon_entry cache;
-};
-
-
-/* Create a new icon manager and return a point to it.  */
-grub_gfxmenu_icon_manager_t
-grub_gfxmenu_icon_manager_new (void)
-{
-  grub_gfxmenu_icon_manager_t mgr;
-  mgr = grub_malloc (sizeof (*mgr));
-  if (! mgr)
-    return 0;
-
-  mgr->theme_path = 0;
-  mgr->icon_width = 0;
-  mgr->icon_height = 0;
-
-  /* Initialize the dummy head node.  */
-  mgr->cache.class_name = 0;
-  mgr->cache.bitmap = 0;
-  mgr->cache.next = 0;
-
-  return mgr;
-}
-
-/* Destroy the icon manager MGR, freeing all resources used by it.
-
-Note: Any bitmaps returned by grub_gfxmenu_icon_manager_get_icon()
-are destroyed and must not be used by the caller after this function
-is called.  */
-void
-grub_gfxmenu_icon_manager_destroy (grub_gfxmenu_icon_manager_t mgr)
-{
-  grub_gfxmenu_icon_manager_clear_cache (mgr);
-  grub_free (mgr->theme_path);
-  grub_free (mgr);
-}
-
-/* Clear the icon cache.  */
-void
-grub_gfxmenu_icon_manager_clear_cache (grub_gfxmenu_icon_manager_t mgr)
-{
-  icon_entry_t cur;
-  icon_entry_t next;
-  for (cur = mgr->cache.next; cur; cur = next)
-    {
-      next = cur->next;
-      grub_free (cur->class_name);
-      grub_video_bitmap_destroy (cur->bitmap);
-      grub_free (cur);
-    }
-  mgr->cache.next = 0;
-}
-
-/* Set the theme path.  If the theme path is changed, the icon cache
-   is cleared.  */
-void
-grub_gfxmenu_icon_manager_set_theme_path (grub_gfxmenu_icon_manager_t mgr,
-                                          const char *path)
-{
-  /* Clear the cache if the theme path has changed.  */
-  if (((mgr->theme_path == 0) != (path == 0))
-      || (grub_strcmp (mgr->theme_path, path) != 0))
-    grub_gfxmenu_icon_manager_clear_cache (mgr);
-
-  grub_free (mgr->theme_path);
-  mgr->theme_path = path ? grub_strdup (path) : 0;
-}
-
-/* Set the icon size.  When icons are requested from the icon manager,
-   they are scaled to this size before being returned.  If the size is
-   changed, the icon cache is cleared.  */
-void
-grub_gfxmenu_icon_manager_set_icon_size (grub_gfxmenu_icon_manager_t mgr,
-                                         int width, int height)
-{
-  /* If the width or height is changed, we must clear the cache, since the
-     scaled bitmaps are stored in the cache.  */
-  if (width != mgr->icon_width || height != mgr->icon_height)
-    grub_gfxmenu_icon_manager_clear_cache (mgr);
-
-  mgr->icon_width = width;
-  mgr->icon_height = height;
-}
-
-/* Try to load an icon for the specified CLASS_NAME in the directory DIR.
-   Returns 0 if the icon could not be loaded, or returns a pointer to a new
-   bitmap if it was successful.  */
-static struct grub_video_bitmap *
-try_loading_icon (grub_gfxmenu_icon_manager_t mgr,
-                  const char *dir, const char *class_name)
-{
-  char *path;
-  int l;
-
-  path = grub_malloc (grub_strlen (dir) + grub_strlen (class_name)
-                     + grub_strlen (icon_extension) + 3);
-  if (! path)
-    return 0;
-
-  grub_strcpy (path, dir);
-  l = grub_strlen (path);
-  if (path[l-1] != '/')
-    {
-      path[l] = '/';
-      path[l+1] = 0;
-    }
-  grub_strcat (path, class_name);
-  grub_strcat (path, icon_extension);
-
-  struct grub_video_bitmap *raw_bitmap;
-  grub_video_bitmap_load (&raw_bitmap, path);
-  grub_free (path);
-  grub_errno = GRUB_ERR_NONE;  /* Critical to clear the error!!  */
-  if (! raw_bitmap)
-    return 0;
-
-  struct grub_video_bitmap *scaled_bitmap;
-  grub_video_bitmap_create_scaled (&scaled_bitmap,
-                                   mgr->icon_width, mgr->icon_height,
-                                   raw_bitmap,
-                                   GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
-  grub_video_bitmap_destroy (raw_bitmap);
-  if (! scaled_bitmap)
-    {
-      grub_error_push ();
-      grub_error (grub_errno, "failed to scale icon");
-      return 0;
-    }
-
-  return scaled_bitmap;
-}
-
-/* Get the icon for the specified class CLASS_NAME.  If an icon for
-   CLASS_NAME already exists in the cache, then a reference to the cached
-   bitmap is returned.  If it is not cached, then it is loaded and cached.
-   If no icon could be could for CLASS_NAME, then 0 is returned.  */
-static struct grub_video_bitmap *
-get_icon_by_class (grub_gfxmenu_icon_manager_t mgr, const char *class_name)
-{
-  /* First check the icon cache.  */
-  icon_entry_t entry;
-  for (entry = mgr->cache.next; entry; entry = entry->next)
-    {
-      if (grub_strcmp (entry->class_name, class_name) == 0)
-        return entry->bitmap;
-    }
-
-  if (! mgr->theme_path)
-    return 0;
-
-  /* Otherwise, we search for an icon to load.  */
-  char *theme_dir = grub_get_dirname (mgr->theme_path);
-  char *icons_dir;
-  struct grub_video_bitmap *icon;
-  icon = 0;
-  /* First try the theme's own icons, from "grub/themes/NAME/icons/"  */
-  icons_dir = grub_resolve_relative_path (theme_dir, "icons/");
-  if (icons_dir)
-    {
-      icon = try_loading_icon (mgr, icons_dir, class_name);
-      grub_free (icons_dir);
-    }
-
-  grub_free (theme_dir);
-  if (! icon)
-    {
-      const char *icondir;
-
-      icondir = grub_env_get ("icondir");
-      if (icondir)
-       icon = try_loading_icon (mgr, icondir, class_name);
-    }
-
-  /* No icon was found.  */
-  /* This should probably be noted in the cache, so that a search is not
-     performed each time an icon for CLASS_NAME is requested.  */
-  if (! icon)
-    return 0;
-
-  /* Insert a new cache entry for this icon.  */
-  entry = grub_malloc (sizeof (*entry));
-  if (! entry)
-    {
-      grub_video_bitmap_destroy (icon);
-      return 0;
-    }
-  entry->class_name = grub_strdup (class_name);
-  entry->bitmap = icon;
-  entry->next = mgr->cache.next;
-  mgr->cache.next = entry;   /* Link it into the cache.  */
-  return entry->bitmap;
-}
-
-/* Get the best available icon for ENTRY.  Beginning with the first class
-   listed in the menu entry and proceeding forward, an icon for each class
-   is searched for.  The first icon found is returned.  The returned icon
-   is scaled to the size specified by
-   grub_gfxmenu_icon_manager_set_icon_size().
-
-     Note:  Bitmaps returned by this function are destroyed when the
-            icon manager is destroyed.
- */
-struct grub_video_bitmap *
-grub_gfxmenu_icon_manager_get_icon (grub_gfxmenu_icon_manager_t mgr,
-                                    grub_menu_entry_t entry)
-{
-  struct grub_menu_entry_class *c;
-  struct grub_video_bitmap *icon;
-
-  /* Try each class in succession.  */
-  icon = 0;
-  for (c = entry->classes->next; c && ! icon; c = c->next)
-    icon = get_icon_by_class (mgr, c->name);
-  return icon;
-}
diff --git a/gfxmenu/model.c b/gfxmenu/model.c
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/gfxmenu/named_colors.c b/gfxmenu/named_colors.c
deleted file mode 100644 (file)
index eedbc47..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/* named_colors.c - Named color values.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/gui.h>
-#include <grub/gui_string_util.h>
-#include <grub/misc.h>
-
-struct named_color
-{
-  const char *name;
-  grub_gui_color_t color;
-};
-
-/*
-   Named color list generated from the list of SVG color keywords from
-   <http://www.w3.org/TR/css3-color/#svg-color>,
-   processed through the following Perl command:
-   perl -ne 'chomp;split;print "{ \"$_[0]\", RGB_COLOR($_[2]) },\n"'
- */
-
-#define RGB_COLOR(r,g,b) {.red = r, .green = g, .blue = b, .alpha = 255}
-
-static struct named_color named_colors[] =
-{
-    { "aliceblue", RGB_COLOR(240,248,255) },
-    { "antiquewhite", RGB_COLOR(250,235,215) },
-    { "aqua", RGB_COLOR(0,255,255) },
-    { "aquamarine", RGB_COLOR(127,255,212) },
-    { "azure", RGB_COLOR(240,255,255) },
-    { "beige", RGB_COLOR(245,245,220) },
-    { "bisque", RGB_COLOR(255,228,196) },
-    { "black", RGB_COLOR(0,0,0) },
-    { "blanchedalmond", RGB_COLOR(255,235,205) },
-    { "blue", RGB_COLOR(0,0,255) },
-    { "blueviolet", RGB_COLOR(138,43,226) },
-    { "brown", RGB_COLOR(165,42,42) },
-    { "burlywood", RGB_COLOR(222,184,135) },
-    { "cadetblue", RGB_COLOR(95,158,160) },
-    { "chartreuse", RGB_COLOR(127,255,0) },
-    { "chocolate", RGB_COLOR(210,105,30) },
-    { "coral", RGB_COLOR(255,127,80) },
-    { "cornflowerblue", RGB_COLOR(100,149,237) },
-    { "cornsilk", RGB_COLOR(255,248,220) },
-    { "crimson", RGB_COLOR(220,20,60) },
-    { "cyan", RGB_COLOR(0,255,255) },
-    { "darkblue", RGB_COLOR(0,0,139) },
-    { "darkcyan", RGB_COLOR(0,139,139) },
-    { "darkgoldenrod", RGB_COLOR(184,134,11) },
-    { "darkgray", RGB_COLOR(169,169,169) },
-    { "darkgreen", RGB_COLOR(0,100,0) },
-    { "darkgrey", RGB_COLOR(169,169,169) },
-    { "darkkhaki", RGB_COLOR(189,183,107) },
-    { "darkmagenta", RGB_COLOR(139,0,139) },
-    { "darkolivegreen", RGB_COLOR(85,107,47) },
-    { "darkorange", RGB_COLOR(255,140,0) },
-    { "darkorchid", RGB_COLOR(153,50,204) },
-    { "darkred", RGB_COLOR(139,0,0) },
-    { "darksalmon", RGB_COLOR(233,150,122) },
-    { "darkseagreen", RGB_COLOR(143,188,143) },
-    { "darkslateblue", RGB_COLOR(72,61,139) },
-    { "darkslategray", RGB_COLOR(47,79,79) },
-    { "darkslategrey", RGB_COLOR(47,79,79) },
-    { "darkturquoise", RGB_COLOR(0,206,209) },
-    { "darkviolet", RGB_COLOR(148,0,211) },
-    { "deeppink", RGB_COLOR(255,20,147) },
-    { "deepskyblue", RGB_COLOR(0,191,255) },
-    { "dimgray", RGB_COLOR(105,105,105) },
-    { "dimgrey", RGB_COLOR(105,105,105) },
-    { "dodgerblue", RGB_COLOR(30,144,255) },
-    { "firebrick", RGB_COLOR(178,34,34) },
-    { "floralwhite", RGB_COLOR(255,250,240) },
-    { "forestgreen", RGB_COLOR(34,139,34) },
-    { "fuchsia", RGB_COLOR(255,0,255) },
-    { "gainsboro", RGB_COLOR(220,220,220) },
-    { "ghostwhite", RGB_COLOR(248,248,255) },
-    { "gold", RGB_COLOR(255,215,0) },
-    { "goldenrod", RGB_COLOR(218,165,32) },
-    { "gray", RGB_COLOR(128,128,128) },
-    { "green", RGB_COLOR(0,128,0) },
-    { "greenyellow", RGB_COLOR(173,255,47) },
-    { "grey", RGB_COLOR(128,128,128) },
-    { "honeydew", RGB_COLOR(240,255,240) },
-    { "hotpink", RGB_COLOR(255,105,180) },
-    { "indianred", RGB_COLOR(205,92,92) },
-    { "indigo", RGB_COLOR(75,0,130) },
-    { "ivory", RGB_COLOR(255,255,240) },
-    { "khaki", RGB_COLOR(240,230,140) },
-    { "lavender", RGB_COLOR(230,230,250) },
-    { "lavenderblush", RGB_COLOR(255,240,245) },
-    { "lawngreen", RGB_COLOR(124,252,0) },
-    { "lemonchiffon", RGB_COLOR(255,250,205) },
-    { "lightblue", RGB_COLOR(173,216,230) },
-    { "lightcoral", RGB_COLOR(240,128,128) },
-    { "lightcyan", RGB_COLOR(224,255,255) },
-    { "lightgoldenrodyellow", RGB_COLOR(250,250,210) },
-    { "lightgray", RGB_COLOR(211,211,211) },
-    { "lightgreen", RGB_COLOR(144,238,144) },
-    { "lightgrey", RGB_COLOR(211,211,211) },
-    { "lightpink", RGB_COLOR(255,182,193) },
-    { "lightsalmon", RGB_COLOR(255,160,122) },
-    { "lightseagreen", RGB_COLOR(32,178,170) },
-    { "lightskyblue", RGB_COLOR(135,206,250) },
-    { "lightslategray", RGB_COLOR(119,136,153) },
-    { "lightslategrey", RGB_COLOR(119,136,153) },
-    { "lightsteelblue", RGB_COLOR(176,196,222) },
-    { "lightyellow", RGB_COLOR(255,255,224) },
-    { "lime", RGB_COLOR(0,255,0) },
-    { "limegreen", RGB_COLOR(50,205,50) },
-    { "linen", RGB_COLOR(250,240,230) },
-    { "magenta", RGB_COLOR(255,0,255) },
-    { "maroon", RGB_COLOR(128,0,0) },
-    { "mediumaquamarine", RGB_COLOR(102,205,170) },
-    { "mediumblue", RGB_COLOR(0,0,205) },
-    { "mediumorchid", RGB_COLOR(186,85,211) },
-    { "mediumpurple", RGB_COLOR(147,112,219) },
-    { "mediumseagreen", RGB_COLOR(60,179,113) },
-    { "mediumslateblue", RGB_COLOR(123,104,238) },
-    { "mediumspringgreen", RGB_COLOR(0,250,154) },
-    { "mediumturquoise", RGB_COLOR(72,209,204) },
-    { "mediumvioletred", RGB_COLOR(199,21,133) },
-    { "midnightblue", RGB_COLOR(25,25,112) },
-    { "mintcream", RGB_COLOR(245,255,250) },
-    { "mistyrose", RGB_COLOR(255,228,225) },
-    { "moccasin", RGB_COLOR(255,228,181) },
-    { "navajowhite", RGB_COLOR(255,222,173) },
-    { "navy", RGB_COLOR(0,0,128) },
-    { "oldlace", RGB_COLOR(253,245,230) },
-    { "olive", RGB_COLOR(128,128,0) },
-    { "olivedrab", RGB_COLOR(107,142,35) },
-    { "orange", RGB_COLOR(255,165,0) },
-    { "orangered", RGB_COLOR(255,69,0) },
-    { "orchid", RGB_COLOR(218,112,214) },
-    { "palegoldenrod", RGB_COLOR(238,232,170) },
-    { "palegreen", RGB_COLOR(152,251,152) },
-    { "paleturquoise", RGB_COLOR(175,238,238) },
-    { "palevioletred", RGB_COLOR(219,112,147) },
-    { "papayawhip", RGB_COLOR(255,239,213) },
-    { "peachpuff", RGB_COLOR(255,218,185) },
-    { "peru", RGB_COLOR(205,133,63) },
-    { "pink", RGB_COLOR(255,192,203) },
-    { "plum", RGB_COLOR(221,160,221) },
-    { "powderblue", RGB_COLOR(176,224,230) },
-    { "purple", RGB_COLOR(128,0,128) },
-    { "red", RGB_COLOR(255,0,0) },
-    { "rosybrown", RGB_COLOR(188,143,143) },
-    { "royalblue", RGB_COLOR(65,105,225) },
-    { "saddlebrown", RGB_COLOR(139,69,19) },
-    { "salmon", RGB_COLOR(250,128,114) },
-    { "sandybrown", RGB_COLOR(244,164,96) },
-    { "seagreen", RGB_COLOR(46,139,87) },
-    { "seashell", RGB_COLOR(255,245,238) },
-    { "sienna", RGB_COLOR(160,82,45) },
-    { "silver", RGB_COLOR(192,192,192) },
-    { "skyblue", RGB_COLOR(135,206,235) },
-    { "slateblue", RGB_COLOR(106,90,205) },
-    { "slategray", RGB_COLOR(112,128,144) },
-    { "slategrey", RGB_COLOR(112,128,144) },
-    { "snow", RGB_COLOR(255,250,250) },
-    { "springgreen", RGB_COLOR(0,255,127) },
-    { "steelblue", RGB_COLOR(70,130,180) },
-    { "tan", RGB_COLOR(210,180,140) },
-    { "teal", RGB_COLOR(0,128,128) },
-    { "thistle", RGB_COLOR(216,191,216) },
-    { "tomato", RGB_COLOR(255,99,71) },
-    { "turquoise", RGB_COLOR(64,224,208) },
-    { "violet", RGB_COLOR(238,130,238) },
-    { "wheat", RGB_COLOR(245,222,179) },
-    { "white", RGB_COLOR(255,255,255) },
-    { "whitesmoke", RGB_COLOR(245,245,245) },
-    { "yellow", RGB_COLOR(255,255,0) },
-    { "yellowgreen", RGB_COLOR(154,205,50) },
-    { 0, { 0, 0, 0, 0 } }  /* Terminator.  */
-};
-
-/* Get the color named NAME.  If the color was found, returns 1 and
-   stores the color into *COLOR.  If the color was not found, returns 0 and
-   does not modify *COLOR.  */
-int
-grub_gui_get_named_color (const char *name,
-                          grub_gui_color_t *color)
-{
-  int i;
-  for (i = 0; named_colors[i].name; i++)
-    {
-      if (grub_strcmp (named_colors[i].name, name) == 0)
-        {
-          *color = named_colors[i].color;
-          return 1;
-        }
-    }
-  return 0;
-}
diff --git a/gfxmenu/theme_loader.c b/gfxmenu/theme_loader.c
deleted file mode 100644 (file)
index 3854c6c..0000000
+++ /dev/null
@@ -1,723 +0,0 @@
-/* theme_loader.c - Theme file loader for gfxmenu.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/file.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/video.h>
-#include <grub/gui_string_util.h>
-#include <grub/bitmap.h>
-#include <grub/bitmap_scale.h>
-#include <grub/gfxwidgets.h>
-#include <grub/gfxmenu_view.h>
-#include <grub/gui.h>
-
-/* Construct a new box widget using ABSPATTERN to find the pixmap files for
-   it, storing the new box instance at *BOXPTR.
-   PATTERN should be of the form: "(hd0,0)/somewhere/style*.png".
-   The '*' then gets substituted with the various pixmap names that the
-   box uses.  */
-static grub_err_t
-recreate_box_absolute (grub_gfxmenu_box_t *boxptr, const char *abspattern)
-{
-  char *prefix;
-  char *suffix;
-  char *star;
-  grub_gfxmenu_box_t box;
-
-  star = grub_strchr (abspattern, '*');
-  if (! star)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                       "missing `*' in box pixmap pattern `%s'", abspattern);
-
-  /* Prefix:  Get the part before the '*'.  */
-  prefix = grub_malloc (star - abspattern + 1);
-  if (! prefix)
-    return grub_errno;
-
-  grub_memcpy (prefix, abspattern, star - abspattern);
-  prefix[star - abspattern] = '\0';
-
-  /* Suffix:  Everything after the '*' is the suffix.  */
-  suffix = star + 1;
-
-  box = grub_gfxmenu_create_box (prefix, suffix);
-  grub_free (prefix);
-  if (! box)
-    return grub_errno;
-
-  if (*boxptr)
-    (*boxptr)->destroy (*boxptr);
-  *boxptr = box;
-  return grub_errno;
-}
-
-
-/* Construct a new box widget using PATTERN to find the pixmap files for it,
-   storing the new widget at *BOXPTR.  PATTERN should be of the form:
-   "somewhere/style*.png".  The '*' then gets substituted with the various
-   pixmap names that the widget uses.
-
-   Important!  The value of *BOXPTR must be initialized!  It must either
-   (1) Be 0 (a NULL pointer), or
-   (2) Be a pointer to a valid 'grub_gfxmenu_box_t' instance.
-   In this case, the previous instance is destroyed.  */
-grub_err_t
-grub_gui_recreate_box (grub_gfxmenu_box_t *boxptr,
-                       const char *pattern, const char *theme_dir)
-{
-  char *abspattern;
-
-  /* Check arguments.  */
-  if (! pattern)
-    {
-      /* If no pixmap pattern is given, then just create an empty box.  */
-      if (*boxptr)
-        (*boxptr)->destroy (*boxptr);
-      *boxptr = grub_gfxmenu_create_box (0, 0);
-      return grub_errno;
-    }
-
-  if (! theme_dir)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                       "styled box missing theme directory");
-
-  /* Resolve to an absolute path.  */
-  abspattern = grub_resolve_relative_path (theme_dir, pattern);
-  if (! abspattern)
-    return grub_errno;
-
-  /* Create the box.  */
-  recreate_box_absolute (boxptr, abspattern);
-  grub_free (abspattern);
-  return grub_errno;
-}
-
-/* Set the specified property NAME on the view to the given string VALUE.
-   The caller is responsible for the lifetimes of NAME and VALUE.  */
-static grub_err_t
-theme_set_string (grub_gfxmenu_view_t view,
-                  const char *name,
-                  const char *value,
-                  const char *theme_dir,
-                  const char *filename,
-                  int line_num,
-                  int col_num)
-{
-  if (! grub_strcmp ("title-font", name))
-    view->title_font = grub_font_get (value);
-  else if (! grub_strcmp ("message-font", name))
-    view->message_font = grub_font_get (value);
-  else if (! grub_strcmp ("terminal-font", name))
-    {
-      grub_free (view->terminal_font_name);
-      view->terminal_font_name = grub_strdup (value);
-      if (! view->terminal_font_name)
-        return grub_errno;
-    }
-  else if (! grub_strcmp ("title-color", name))
-    grub_gui_parse_color (value, &view->title_color);
-  else if (! grub_strcmp ("message-color", name))
-    grub_gui_parse_color (value, &view->message_color);
-  else if (! grub_strcmp ("message-bg-color", name))
-    grub_gui_parse_color (value, &view->message_bg_color);
-  else if (! grub_strcmp ("desktop-image", name))
-    {
-      struct grub_video_bitmap *raw_bitmap;
-      struct grub_video_bitmap *scaled_bitmap;
-      char *path;
-      path = grub_resolve_relative_path (theme_dir, value);
-      if (! path)
-        return grub_errno;
-      if (grub_video_bitmap_load (&raw_bitmap, path) != GRUB_ERR_NONE)
-        {
-          grub_free (path);
-          return grub_errno;
-        }
-      grub_free(path);
-      grub_video_bitmap_create_scaled (&scaled_bitmap,
-                                       view->screen.width,
-                                       view->screen.height,
-                                       raw_bitmap,
-                                       GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
-      grub_video_bitmap_destroy (raw_bitmap);
-      if (! scaled_bitmap)
-        {
-          grub_error_push ();
-          return grub_error (grub_errno, "error scaling desktop image");
-        }
-
-      grub_video_bitmap_destroy (view->desktop_image);
-      view->desktop_image = scaled_bitmap;
-    }
-  else if (! grub_strcmp ("desktop-color", name))
-     grub_gui_parse_color (value, &view->desktop_color);
-  else if (! grub_strcmp ("terminal-box", name))
-    {
-        grub_err_t err;
-        err = grub_gui_recreate_box (&view->terminal_box, value, theme_dir);
-        if (err != GRUB_ERR_NONE)
-          return err;
-    }
-  else if (! grub_strcmp ("title-text", name))
-    {
-      grub_free (view->title_text);
-      view->title_text = grub_strdup (value);
-      if (! view->title_text)
-        return grub_errno;
-    }
-  else
-    {
-      return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                         "%s:%d:%d unknown property `%s'",
-                         filename, line_num, col_num, name);
-    }
-  return grub_errno;
-}
-
-struct parsebuf
-{
-  char *buf;
-  int pos;
-  int len;
-  int line_num;
-  int col_num;
-  const char *filename;
-  char *theme_dir;
-  grub_gfxmenu_view_t view;
-};
-
-static int
-has_more (struct parsebuf *p)
-{
-  return p->pos < p->len;
-}
-
-static int
-read_char (struct parsebuf *p)
-{
-  if (has_more (p))
-    {
-      char c;
-      c = p->buf[p->pos++];
-      if (c == '\n')
-        {
-          p->line_num++;
-          p->col_num = 1;
-        }
-      else
-        {
-          p->col_num++;
-        }
-      return c;
-    }
-  else
-    return -1;
-}
-
-static int
-peek_char (struct parsebuf *p)
-{
-  if (has_more (p))
-    return p->buf[p->pos];
-  else
-    return -1;
-}
-
-static int
-is_whitespace (char c)
-{
-  return (c == ' '
-          || c == '\t'
-          || c == '\r'
-          || c == '\n'
-          || c == '\f');
-}
-
-static void
-skip_whitespace (struct parsebuf *p)
-{
-  while (has_more (p) && is_whitespace(peek_char (p)))
-    read_char (p);
-}
-
-static void
-advance_to_next_line (struct parsebuf *p)
-{
-  int c;
-
-  /* Eat characters up to the newline.  */
-  do
-    {
-      c = read_char (p);
-    }
-  while (c != -1 && c != '\n');
-}
-
-static int
-is_identifier_char (int c)
-{
-  return (c != -1
-          && (grub_isalpha(c)
-              || grub_isdigit(c)
-              || c == '_'
-              || c == '-'));
-}
-
-static char *
-read_identifier (struct parsebuf *p)
-{
-  /* Index of the first character of the identifier in p->buf.  */
-  int start;
-  /* Next index after the last character of the identifer in p->buf.  */
-  int end;
-
-  skip_whitespace (p);
-
-  /* Capture the start of the identifier.  */
-  start = p->pos;
-
-  /* Scan for the end.  */
-  while (is_identifier_char (peek_char (p)))
-    read_char (p);
-  end = p->pos;
-
-  if (end - start < 1)
-    return 0;
-
-  return grub_new_substring (p->buf, start, end);
-}
-
-static char *
-read_expression (struct parsebuf *p)
-{
-  int start;
-  int end;
-
-  skip_whitespace (p);
-  if (peek_char (p) == '"')
-    {
-      /* Read as a quoted string.  
-         The quotation marks are not included in the expression value.  */
-      /* Skip opening quotation mark.  */
-      read_char (p);
-      start = p->pos;
-      while (has_more (p) && peek_char (p) != '"')
-        read_char (p);
-      end = p->pos;
-      /* Skip the terminating quotation mark.  */
-      read_char (p);
-    }
-  else if (peek_char (p) == '(')
-    {
-      /* Read as a parenthesized string -- for tuples/coordinates.  */
-      /* The parentheses are included in the expression value.  */
-      int c;
-
-      start = p->pos;
-      do
-        {
-          c = read_char (p);
-        }
-      while (c != -1 && c != ')');
-      end = p->pos;
-    }
-  else if (has_more (p))
-    {
-      /* Read as a single word -- for numeric values or words without
-         whitespace.  */
-      start = p->pos;
-      while (has_more (p) && ! is_whitespace (peek_char (p)))
-        read_char (p);
-      end = p->pos;
-    }
-  else
-    {
-      /* The end of the theme file has been reached.  */
-      grub_error (GRUB_ERR_IO, "%s:%d:%d expression expected in theme file",
-                  p->filename, p->line_num, p->col_num);
-      return 0;
-    }
-
-  return grub_new_substring (p->buf, start, end);
-}
-
-static grub_err_t
-parse_proportional_spec (char *value, signed *abs, grub_fixed_signed_t *prop)
-{
-  signed num;
-  char *ptr;
-  int sig = 0;
-  *abs = 0;
-  *prop = 0;
-  ptr = value;
-  while (*ptr)
-    {
-      sig = 0;
-
-      while (*ptr == '-' || *ptr == '+')
-       {
-         if (*ptr == '-')
-           sig = !sig;
-         ptr++;
-       }
-
-      num = grub_strtoul (ptr, &ptr, 0);
-      if (grub_errno)
-       return grub_errno;
-      if (sig)
-       num = -num;
-      if (*ptr == '%')
-       {
-         *prop += grub_fixed_fsf_divide (grub_signed_to_fixed (num), 100);
-         ptr++;
-       }
-      else
-       *abs += num;
-    }
-  return GRUB_ERR_NONE;
-}
-
-
-/* Read a GUI object specification from the theme file.
-   Any components created will be added to the GUI container PARENT.  */
-static grub_err_t
-read_object (struct parsebuf *p, grub_gui_container_t parent)
-{
-  grub_video_rect_t bounds;
-
-  char *name;
-  name = read_identifier (p);
-  if (! name)
-    goto cleanup;
-
-  grub_gui_component_t component = 0;
-  if (grub_strcmp (name, "label") == 0)
-    {
-      component = grub_gui_label_new ();
-    }
-  else if (grub_strcmp (name, "image") == 0)
-    {
-      component = grub_gui_image_new ();
-    }
-  else if (grub_strcmp (name, "vbox") == 0)
-    {
-      component = (grub_gui_component_t) grub_gui_vbox_new ();
-    }
-  else if (grub_strcmp (name, "hbox") == 0)
-    {
-      component = (grub_gui_component_t) grub_gui_hbox_new ();
-    }
-  else if (grub_strcmp (name, "canvas") == 0)
-    {
-      component = (grub_gui_component_t) grub_gui_canvas_new ();
-    }
-  else if (grub_strcmp (name, "progress_bar") == 0)
-    {
-      component = grub_gui_progress_bar_new ();
-    }
-  else if (grub_strcmp (name, "circular_progress") == 0)
-    {
-      component = grub_gui_circular_progress_new ();
-    }
-  else if (grub_strcmp (name, "boot_menu") == 0)
-    {
-      component = grub_gui_list_new ();
-    }
-  else
-    {
-      /* Unknown type.  */
-      grub_error (GRUB_ERR_IO, "%s:%d:%d unknown object type `%s'",
-                  p->filename, p->line_num, p->col_num, name);
-      goto cleanup;
-    }
-
-  if (! component)
-    goto cleanup;
-
-  /* Inform the component about the theme so it can find its resources.  */
-  component->ops->set_property (component, "theme_dir", p->theme_dir);
-  component->ops->set_property (component, "theme_path", p->filename);
-
-  /* Add the component as a child of PARENT.  */
-  bounds.x = 0;
-  bounds.y = 0;
-  bounds.width = -1;
-  bounds.height = -1;
-  component->ops->set_bounds (component, &bounds);
-  parent->ops->add (parent, component);
-
-  skip_whitespace (p);
-  if (read_char (p) != '{')
-    {
-      grub_error (GRUB_ERR_IO,
-                  "%s:%d:%d expected `{' after object type name `%s'",
-                  p->filename, p->line_num, p->col_num, name);
-      goto cleanup;
-    }
-
-  while (has_more (p))
-    {
-      skip_whitespace (p);
-
-      /* Check whether the end has been encountered.  */
-      if (peek_char (p) == '}')
-        {
-          /* Skip the closing brace.  */
-          read_char (p);
-          break;
-        }
-
-      if (peek_char (p) == '#')
-        {
-          /* Skip comments.  */
-          advance_to_next_line (p);
-          continue;
-        }
-
-      if (peek_char (p) == '+')
-        {
-          /* Skip the '+'.  */
-          read_char (p);
-
-          /* Check whether this component is a container.  */
-          if (component->ops->is_instance (component, "container"))
-            {
-              /* Read the sub-object recursively and add it as a child.  */
-              if (read_object (p, (grub_gui_container_t) component) != 0)
-                goto cleanup;
-              /* After reading the sub-object, resume parsing, expecting
-                 another property assignment or sub-object definition.  */
-              continue;
-            }
-          else
-            {
-              grub_error (GRUB_ERR_IO,
-                          "%s:%d:%d attempted to add object to non-container",
-                          p->filename, p->line_num, p->col_num);
-              goto cleanup;
-            }
-        }
-
-      char *property;
-      property = read_identifier (p);
-      if (! property)
-        {
-          grub_error (GRUB_ERR_IO, "%s:%d:%d identifier expected in theme file",
-                      p->filename, p->line_num, p->col_num);
-          goto cleanup;
-        }
-
-      skip_whitespace (p);
-      if (read_char (p) != '=')
-        {
-          grub_error (GRUB_ERR_IO,
-                      "%s:%d:%d expected `=' after property name `%s'",
-                      p->filename, p->line_num, p->col_num, property);
-          grub_free (property);
-          goto cleanup;
-        }
-      skip_whitespace (p);
-
-      char *value;
-      value = read_expression (p);
-      if (! value)
-        {
-          grub_free (property);
-          goto cleanup;
-        }
-
-      /* Handle the property value.  */
-      if (grub_strcmp (property, "left") == 0)
-       parse_proportional_spec (value, &component->x, &component->xfrac);
-      else if (grub_strcmp (property, "top") == 0)
-       parse_proportional_spec (value, &component->y, &component->yfrac);
-      else if (grub_strcmp (property, "width") == 0)
-       parse_proportional_spec (value, &component->w, &component->wfrac);
-      else if (grub_strcmp (property, "height") == 0)
-       parse_proportional_spec (value, &component->h, &component->hfrac);
-      else
-       /* General property handling.  */
-       component->ops->set_property (component, property, value);
-
-      grub_free (value);
-      grub_free (property);
-      if (grub_errno != GRUB_ERR_NONE)
-        goto cleanup;
-    }
-
-cleanup:
-  grub_free (name);
-  return grub_errno;
-}
-
-static grub_err_t
-read_property (struct parsebuf *p)
-{
-  char *name;
-
-  /* Read the property name.  */
-  name = read_identifier (p);
-  if (! name)
-    {
-      advance_to_next_line (p);
-      return grub_errno;
-    }
-
-  /* Skip whitespace before separator.  */
-  skip_whitespace (p);
-
-  /* Read separator.  */
-  if (read_char (p) != ':')
-    {
-      grub_error (GRUB_ERR_IO,
-                  "%s:%d:%d missing separator after property name `%s'",
-                  p->filename, p->line_num, p->col_num, name);
-      goto done;
-    }
-
-  /* Skip whitespace after separator.  */
-  skip_whitespace (p);
-
-  /* Get the value based on its type.  */
-  if (peek_char (p) == '"')
-    {
-      /* String value (e.g., '"My string"').  */
-      char *value = read_expression (p);
-      if (! value)
-        {
-          grub_error (GRUB_ERR_IO, "%s:%d:%d missing property value",
-                      p->filename, p->line_num, p->col_num);
-          goto done;
-        }
-      /* If theme_set_string results in an error, grub_errno will be returned
-         below.  */
-      theme_set_string (p->view, name, value, p->theme_dir,
-                        p->filename, p->line_num, p->col_num);
-      grub_free (value);
-    }
-  else
-    {
-      grub_error (GRUB_ERR_IO,
-                  "%s:%d:%d property value invalid; "
-                  "enclose literal values in quotes (\")",
-                  p->filename, p->line_num, p->col_num);
-      goto done;
-    }
-
-done:
-  grub_free (name);
-  return grub_errno;
-}
-
-/* Set properties on the view based on settings from the specified
-   theme file.  */
-grub_err_t
-grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
-{
-  grub_file_t file;
-  struct parsebuf p;
-
-  p.view = view;
-  p.theme_dir = grub_get_dirname (theme_path);
-
-  file = grub_file_open (theme_path);
-  if (! file)
-    {
-      grub_free (p.theme_dir);
-      return grub_errno;
-    }
-
-  p.len = grub_file_size (file);
-  p.buf = grub_malloc (p.len);
-  p.pos = 0;
-  p.line_num = 1;
-  p.col_num = 1;
-  p.filename = theme_path;
-  if (! p.buf)
-    {
-      grub_file_close (file);
-      grub_free (p.theme_dir);
-      return grub_errno;
-    }
-  if (grub_file_read (file, p.buf, p.len) != p.len)
-    {
-      grub_free (p.buf);
-      grub_file_close (file);
-      grub_free (p.theme_dir);
-      return grub_errno;
-    }
-
-  if (view->canvas)
-    view->canvas->component.ops->destroy (view->canvas);
-
-  view->canvas = grub_gui_canvas_new ();
-  ((grub_gui_component_t) view->canvas)
-    ->ops->set_bounds ((grub_gui_component_t) view->canvas,
-                       &view->screen);
-
-  while (has_more (&p))
-    {
-      /* Skip comments (lines beginning with #).  */
-      if (peek_char (&p) == '#')
-        {
-          advance_to_next_line (&p);
-          continue;
-        }
-
-      /* Find the first non-whitespace character.  */
-      skip_whitespace (&p);
-
-      /* Handle the content.  */
-      if (peek_char (&p) == '+')
-        {
-          /* Skip the '+'.  */
-          read_char (&p);
-          read_object (&p, view->canvas);
-        }
-      else
-        {
-          read_property (&p);
-        }
-
-      if (grub_errno != GRUB_ERR_NONE)
-        goto fail;
-    }
-
-  /* Set the new theme path.  */
-  grub_free (view->theme_path);
-  view->theme_path = grub_strdup (theme_path);
-  goto cleanup;
-
-fail:
-  if (view->canvas)
-    {
-      view->canvas->component.ops->destroy (view->canvas);
-      view->canvas = 0;
-    }
-
-cleanup:
-  grub_free (p.buf);
-  grub_file_close (file);
-  grub_free (p.theme_dir);
-  return grub_errno;
-}
diff --git a/gfxmenu/view.c b/gfxmenu/view.c
deleted file mode 100644 (file)
index bf637a9..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-/* view.c - Graphical menu interface MVC view. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/file.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/normal.h>
-#include <grub/video.h>
-#include <grub/gfxterm.h>
-#include <grub/bitmap.h>
-#include <grub/bitmap_scale.h>
-#include <grub/term.h>
-#include <grub/gfxwidgets.h>
-#include <grub/time.h>
-#include <grub/menu.h>
-#include <grub/menu_viewer.h>
-#include <grub/gfxmenu_view.h>
-#include <grub/gui_string_util.h>
-#include <grub/icon_manager.h>
-
-/* The component ID identifying GUI components to be updated as the timeout
-   status changes.  */
-#define TIMEOUT_COMPONENT_ID "__timeout__"
-
-static void
-init_terminal (grub_gfxmenu_view_t view);
-static grub_video_rect_t term_rect;
-static grub_gfxmenu_view_t term_view;
-
-/* Create a new view object, loading the theme specified by THEME_PATH and
-   associating MODEL with the view.  */
-grub_gfxmenu_view_t
-grub_gfxmenu_view_new (const char *theme_path,
-                      int width, int height)
-{
-  grub_gfxmenu_view_t view;
-  grub_font_t default_font;
-  grub_gui_color_t default_fg_color;
-  grub_gui_color_t default_bg_color;
-
-  view = grub_malloc (sizeof (*view));
-  if (! view)
-    return 0;
-
-  view->screen.x = 0;
-  view->screen.y = 0;
-  view->screen.width = width;
-  view->screen.height = height;
-
-  default_font = grub_font_get ("Unknown Regular 16");
-  default_fg_color = grub_gui_color_rgb (0, 0, 0);
-  default_bg_color = grub_gui_color_rgb (255, 255, 255);
-
-  view->canvas = 0;
-
-  view->title_font = default_font;
-  view->message_font = default_font;
-  view->terminal_font_name = grub_strdup ("Fixed 10");
-  view->title_color = default_fg_color;
-  view->message_color = default_bg_color;
-  view->message_bg_color = default_fg_color;
-  view->desktop_image = 0;
-  view->desktop_color = default_bg_color;
-  view->terminal_box = grub_gfxmenu_create_box (0, 0);
-  view->title_text = grub_strdup ("GRUB Boot Menu");
-  view->progress_message_text = 0;
-  view->theme_path = 0;
-
-  /* Set the timeout bar's frame.  */
-  view->progress_message_frame.width = view->screen.width * 4 / 5;
-  view->progress_message_frame.height = 50;
-  view->progress_message_frame.x = view->screen.x
-    + (view->screen.width - view->progress_message_frame.width) / 2;
-  view->progress_message_frame.y = view->screen.y
-    + view->screen.height - 90 - 20 - view->progress_message_frame.height;
-
-  if (grub_gfxmenu_view_load_theme (view, theme_path) != 0)
-    {
-      grub_gfxmenu_view_destroy (view);
-      return 0;
-    }
-
-  return view;
-}
-
-/* Destroy the view object.  All used memory is freed.  */
-void
-grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view)
-{
-  if (!view)
-    return;
-  grub_video_bitmap_destroy (view->desktop_image);
-  if (view->terminal_box)
-    view->terminal_box->destroy (view->terminal_box);
-  grub_free (view->terminal_font_name);
-  grub_free (view->title_text);
-  grub_free (view->progress_message_text);
-  grub_free (view->theme_path);
-  if (view->canvas)
-    view->canvas->component.ops->destroy (view->canvas);
-  grub_free (view);
-}
-
-static void
-redraw_background (grub_gfxmenu_view_t view,
-                  const grub_video_rect_t *bounds)
-{
-  if (view->desktop_image)
-    {
-      struct grub_video_bitmap *img = view->desktop_image;
-      grub_video_blit_bitmap (img, GRUB_VIDEO_BLIT_REPLACE,
-                              bounds->x, bounds->y,
-                             bounds->x - view->screen.x,
-                             bounds->y - view->screen.y,
-                             bounds->width, bounds->height);
-    }
-  else
-    {
-      grub_video_fill_rect (grub_gui_map_color (view->desktop_color),
-                            bounds->x, bounds->y,
-                            bounds->width, bounds->height);
-    }
-}
-
-static void
-draw_title (grub_gfxmenu_view_t view)
-{
-  if (! view->title_text)
-    return;
-
-  /* Center the title. */
-  int title_width = grub_font_get_string_width (view->title_font,
-                                                view->title_text);
-  int x = (view->screen.width - title_width) / 2;
-  int y = 40 + grub_font_get_ascent (view->title_font);
-  grub_font_draw_string (view->title_text,
-                         view->title_font,
-                         grub_gui_map_color (view->title_color),
-                         x, y);
-}
-
-struct progress_value_data
-{
-  int visible;
-  int start;
-  int end;
-  int value;
-};
-
-static void
-update_timeout_visit (grub_gui_component_t component,
-                      void *userdata)
-{
-  struct progress_value_data *pv;
-  pv = (struct progress_value_data *) userdata;
-
-  ((struct grub_gui_progress *) component)->ops
-    ->set_state ((struct grub_gui_progress *) component,
-                pv->visible, pv->start, pv->value, pv->end);
-}
-
-void 
-grub_gfxmenu_print_timeout (int timeout, void *data)
-{
-  struct grub_gfxmenu_view *view = data;
-
-  struct progress_value_data pv;
-
-  auto void redraw_timeout_visit (grub_gui_component_t component,
-                                 void *userdata __attribute__ ((unused)));
-
-  auto void redraw_timeout_visit (grub_gui_component_t component,
-                                 void *userdata __attribute__ ((unused)))
-  {
-    grub_video_rect_t bounds;
-    component->ops->get_bounds (component, &bounds);
-    grub_gfxmenu_view_redraw (view, &bounds);
-  }
-
-  if (view->first_timeout == -1)
-    view->first_timeout = timeout;
-
-  pv.visible = 1;
-  pv.start = -(view->first_timeout + 1);
-  pv.end = 0;
-  pv.value = -timeout;
-
-  grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
-                       TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv);
-  grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
-                      TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
-  grub_video_swap_buffers ();
-  if (view->double_repaint)
-    grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
-                        TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
-}
-
-void 
-grub_gfxmenu_clear_timeout (void *data)
-{
-  struct progress_value_data pv;
-  struct grub_gfxmenu_view *view = data;
-
-  auto void redraw_timeout_visit (grub_gui_component_t component,
-                                 void *userdata __attribute__ ((unused)));
-
-  auto void redraw_timeout_visit (grub_gui_component_t component,
-                                 void *userdata __attribute__ ((unused)))
-  {
-    grub_video_rect_t bounds;
-    component->ops->get_bounds (component, &bounds);
-    grub_gfxmenu_view_redraw (view, &bounds);
-  }
-
-  pv.visible = 0;
-  pv.start = 1;
-  pv.end = 0;
-  pv.value = 0;
-
-  grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
-                       TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv);
-  grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
-                      TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
-  grub_video_swap_buffers ();
-  if (view->double_repaint)
-    grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
-                        TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
-}
-
-static void
-update_menu_visit (grub_gui_component_t component,
-                   void *userdata)
-{
-  grub_gfxmenu_view_t view;
-  view = userdata;
-  if (component->ops->is_instance (component, "list"))
-    {
-      grub_gui_list_t list = (grub_gui_list_t) component;
-      list->ops->set_view_info (list, view);
-    }
-}
-
-/* Update any boot menu components with the current menu model and
-   theme path.  */
-static void
-update_menu_components (grub_gfxmenu_view_t view)
-{
-  grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
-                                update_menu_visit, view);
-}
-
-static void
-draw_message (grub_gfxmenu_view_t view)
-{
-  char *text = view->progress_message_text;
-  grub_video_rect_t f = view->progress_message_frame;
-  if (! text)
-    return;
-
-  grub_font_t font = view->message_font;
-  grub_video_color_t color = grub_gui_map_color (view->message_color);
-
-  /* Border.  */
-  grub_video_fill_rect (color,
-                        f.x-1, f.y-1, f.width+2, f.height+2);
-  /* Fill.  */
-  grub_video_fill_rect (grub_gui_map_color (view->message_bg_color),
-                        f.x, f.y, f.width, f.height);
-
-  /* Center the text. */
-  int text_width = grub_font_get_string_width (font, text);
-  int x = f.x + (f.width - text_width) / 2;
-  int y = (f.y + (f.height - grub_font_get_descent (font)) / 2
-           + grub_font_get_ascent (font) / 2);
-  grub_font_draw_string (text, font, color, x, y);
-}
-
-void
-grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
-                         const grub_video_rect_t *region)
-{
-  if (grub_video_have_common_points (&term_rect, region))
-    grub_gfxterm_schedule_repaint ();
-
-  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
-
-  redraw_background (view, region);
-  if (view->canvas)
-    view->canvas->component.ops->paint (view->canvas, region);
-  draw_title (view);
-  if (grub_video_have_common_points (&view->progress_message_frame, region))
-    draw_message (view);
-}
-
-void
-grub_gfxmenu_view_draw (grub_gfxmenu_view_t view)
-{
-  init_terminal (view);
-
-  /* Clear the screen; there may be garbage left over in video memory. */
-  grub_video_fill_rect (grub_video_map_rgb (0, 0, 0),
-                        view->screen.x, view->screen.y,
-                        view->screen.width, view->screen.height);
-  grub_video_swap_buffers ();
-  if (view->double_repaint)
-    grub_video_fill_rect (grub_video_map_rgb (0, 0, 0),
-                         view->screen.x, view->screen.y,
-                         view->screen.width, view->screen.height);
-
-  update_menu_components (view);
-
-  grub_gfxmenu_view_redraw (view, &view->screen);
-  grub_video_swap_buffers ();
-  if (view->double_repaint)
-    grub_gfxmenu_view_redraw (view, &view->screen);
-}
-
-static void
-redraw_menu_visit (grub_gui_component_t component,
-                   void *userdata)
-{
-  grub_gfxmenu_view_t view;
-  view = userdata;
-  if (component->ops->is_instance (component, "list"))
-    {
-      grub_gui_list_t list;
-      grub_video_rect_t bounds;
-
-      list = (grub_gui_list_t) component;
-      component->ops->get_bounds (component, &bounds);
-      grub_gfxmenu_view_redraw (view, &bounds);
-    }
-}
-
-void
-grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view)
-{
-  update_menu_components (view);
-
-  grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
-                                redraw_menu_visit, view);
-  grub_video_swap_buffers ();
-  if (view->double_repaint)
-    {
-      grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
-                                   redraw_menu_visit, view);
-    }
-}
-
-void 
-grub_gfxmenu_set_chosen_entry (int entry, void *data)
-{
-  grub_gfxmenu_view_t view = data;
-
-  view->selected = entry;
-  grub_gfxmenu_redraw_menu (view);
-}
-
-static void
-grub_gfxmenu_draw_terminal_box (void)
-{
-  grub_gfxmenu_box_t term_box;
-
-  term_box = term_view->terminal_box;
-  if (!term_box)
-    return;
-  
-  term_box->set_content_size (term_box, term_rect.width,
-                             term_rect.height);
-  
-  term_box->draw (term_box,
-                 term_rect.x - term_box->get_left_pad (term_box),
-                 term_rect.y - term_box->get_top_pad (term_box));
-  grub_video_swap_buffers ();
-  if (term_view->double_repaint)
-    term_box->draw (term_box,
-                   term_rect.x - term_box->get_left_pad (term_box),
-                   term_rect.y - term_box->get_top_pad (term_box));
-}
-
-static void
-init_terminal (grub_gfxmenu_view_t view)
-{
-  term_rect.width = view->screen.width * 7 / 10;
-  term_rect.height = view->screen.height * 7 / 10;
-
-  term_rect.x = view->screen.x + view->screen.width * (10 - 7) / 10 / 2;
-  term_rect.y = view->screen.y + view->screen.height * (10 - 7) / 10 / 2;
-
-  term_view = view;
-
-  /* Note: currently there is no API for changing the gfxterm font
-     on the fly, so whatever font the initially loaded theme specifies
-     will be permanent.  */
-  grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, term_rect.x,
-                          term_rect.y,
-                          term_rect.width, term_rect.height,
-                          view->double_repaint, view->terminal_font_name, 3);
-  grub_gfxterm_decorator_hook = grub_gfxmenu_draw_terminal_box;
-}
-
-/* FIXME: previously notifications were displayed in special case.
-   Is it necessary?
- */
-#if 0
-/* Sets MESSAGE as the progress message for the view.
-   MESSAGE can be 0, in which case no message is displayed.  */
-static void
-set_progress_message (grub_gfxmenu_view_t view, const char *message)
-{
-  grub_free (view->progress_message_text);
-  if (message)
-    view->progress_message_text = grub_strdup (message);
-  else
-    view->progress_message_text = 0;
-}
-
-static void
-notify_booting (grub_menu_entry_t entry, void *userdata)
-{
-  grub_gfxmenu_view_t view = (grub_gfxmenu_view_t) userdata;
-
-  char *s = grub_malloc (100 + grub_strlen (entry->title));
-  if (!s)
-    return;
-
-  grub_sprintf (s, "Booting '%s'", entry->title);
-  set_progress_message (view, s);
-  grub_free (s);
-  grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
-  grub_video_swap_buffers ();
-  if (view->double_repaint)
-    grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
-}
-
-static void
-notify_fallback (grub_menu_entry_t entry, void *userdata)
-{
-  grub_gfxmenu_view_t view = (grub_gfxmenu_view_t) userdata;
-
-  char *s = grub_malloc (100 + grub_strlen (entry->title));
-  if (!s)
-    return;
-
-  grub_sprintf (s, "Falling back to '%s'", entry->title);
-  set_progress_message (view, s);
-  grub_free (s);
-  grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
-  grub_video_swap_buffers ();
-  if (view->double_repaint)
-    grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
-}
-
-static void
-notify_execution_failure (void *userdata __attribute__ ((unused)))
-{
-}
-
-
-static struct grub_menu_execute_callback execute_callback =
-{
-  .notify_booting = notify_booting,
-  .notify_fallback = notify_fallback,
-  .notify_failure = notify_execution_failure
-};
-
-#endif
diff --git a/gfxmenu/widget-box.c b/gfxmenu/widget-box.c
deleted file mode 100644 (file)
index 079fd66..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-/* widget_box.c - Pixmap-stylized box widget. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/video.h>
-#include <grub/bitmap.h>
-#include <grub/bitmap_scale.h>
-#include <grub/gfxwidgets.h>
-
-enum box_pixmaps
-{
-  BOX_PIXMAP_NW, BOX_PIXMAP_NE, BOX_PIXMAP_SE, BOX_PIXMAP_SW,
-  BOX_PIXMAP_N, BOX_PIXMAP_E, BOX_PIXMAP_S, BOX_PIXMAP_W,
-  BOX_PIXMAP_CENTER
-};
-
-static const char *box_pixmap_names[] = {
-  /* Corners: */
-  "nw", "ne", "se", "sw",
-  /* Sides: */
-  "n", "e", "s", "w",
-  /* Center: */
-  "c"
-};
-
-#define BOX_NUM_PIXMAPS (sizeof(box_pixmap_names)/sizeof(*box_pixmap_names))
-
-static int
-get_height (struct grub_video_bitmap *bitmap)
-{
-  if (bitmap)
-    return grub_video_bitmap_get_height (bitmap);
-  else
-    return 0;
-}
-
-static int
-get_width (struct grub_video_bitmap *bitmap)
-{
-  if (bitmap)
-    return grub_video_bitmap_get_width (bitmap);
-  else
-    return 0;
-}
-
-static void
-blit (grub_gfxmenu_box_t self, int pixmap_index, int x, int y)
-{
-  struct grub_video_bitmap *bitmap;
-  bitmap = self->scaled_pixmaps[pixmap_index];
-  if (! bitmap)
-    return;
-  grub_video_blit_bitmap (bitmap, GRUB_VIDEO_BLIT_BLEND,
-                          x, y, 0, 0,
-                          grub_video_bitmap_get_width (bitmap),
-                          grub_video_bitmap_get_height (bitmap));
-}
-
-static void
-draw (grub_gfxmenu_box_t self, int x, int y)
-{
-  int height_n;
-  int height_s;
-  int height_e;
-  int height_w;
-  int width_n;
-  int width_s;
-  int width_e;
-  int width_w;
-
-  height_n = get_height (self->scaled_pixmaps[BOX_PIXMAP_N]);
-  height_s = get_height (self->scaled_pixmaps[BOX_PIXMAP_S]);
-  height_e = get_height (self->scaled_pixmaps[BOX_PIXMAP_E]);
-  height_w = get_height (self->scaled_pixmaps[BOX_PIXMAP_W]);
-  width_n = get_width (self->scaled_pixmaps[BOX_PIXMAP_N]);
-  width_s = get_width (self->scaled_pixmaps[BOX_PIXMAP_S]);
-  width_e = get_width (self->scaled_pixmaps[BOX_PIXMAP_E]);
-  width_w = get_width (self->scaled_pixmaps[BOX_PIXMAP_W]);
-
-  /* Draw sides.  */
-  blit (self, BOX_PIXMAP_N, x + width_w, y);
-  blit (self, BOX_PIXMAP_S, x + width_w, y + height_n + self->content_height);
-  blit (self, BOX_PIXMAP_E, x + width_w + self->content_width, y + height_n);
-  blit (self, BOX_PIXMAP_W, x, y + height_n);
-
-  /* Draw corners.  */
-  blit (self, BOX_PIXMAP_NW, x, y);
-  blit (self, BOX_PIXMAP_NE, x + width_w + self->content_width, y);
-  blit (self, BOX_PIXMAP_SE,
-        x + width_w + self->content_width,
-        y + height_n + self->content_height);
-  blit (self, BOX_PIXMAP_SW, x, y + height_n + self->content_height);
-
-  /* Draw center.  */
-  blit (self, BOX_PIXMAP_CENTER, x + width_w, y + height_n);
-}
-
-static grub_err_t
-scale_pixmap (grub_gfxmenu_box_t self, int i, int w, int h)
-{
-  struct grub_video_bitmap **scaled = &self->scaled_pixmaps[i];
-  struct grub_video_bitmap *raw = self->raw_pixmaps[i];
-
-  if (raw == 0)
-    return grub_errno;
-
-  if (w == -1)
-    w = grub_video_bitmap_get_width (raw);
-  if (h == -1)
-    h = grub_video_bitmap_get_height (raw);
-
-  if (*scaled == 0
-      || ((int) grub_video_bitmap_get_width (*scaled) != w)
-      || ((int) grub_video_bitmap_get_height (*scaled) != h))
-    {
-      if (*scaled)
-        {
-          grub_video_bitmap_destroy (*scaled);
-          *scaled = 0;
-        }
-
-      /* Don't try to create a bitmap with a zero dimension.  */
-      if (w != 0 && h != 0)
-        grub_video_bitmap_create_scaled (scaled, w, h, raw,
-                                         GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
-      if (grub_errno != GRUB_ERR_NONE)
-        {
-          grub_error_push ();
-          grub_error (grub_errno,
-                      "failed to scale bitmap for styled box pixmap #%d", i);
-        }
-    }
-
-  return grub_errno;
-}
-
-static void
-set_content_size (grub_gfxmenu_box_t self,
-                  int width, int height)
-{
-  self->content_width = width;
-  self->content_height = height;
-
-  /* Resize sides to match the width and height.  */
-  /* It is assumed that the corners width/height match the adjacent sides.  */
-
-  /* Resize N and S sides to match width.  */
-  if (scale_pixmap(self, BOX_PIXMAP_N, width, -1) != GRUB_ERR_NONE)
-    return;
-  if (scale_pixmap(self, BOX_PIXMAP_S, width, -1) != GRUB_ERR_NONE)
-    return;
-
-  /* Resize E and W sides to match height.  */
-  if (scale_pixmap(self, BOX_PIXMAP_E, -1, height) != GRUB_ERR_NONE)
-      return;
-  if (scale_pixmap(self, BOX_PIXMAP_W, -1, height) != GRUB_ERR_NONE)
-    return;
-
-  /* Don't scale the corners--they are assumed to match the sides. */
-  if (scale_pixmap(self, BOX_PIXMAP_NW, -1, -1) != GRUB_ERR_NONE)
-    return;
-  if (scale_pixmap(self, BOX_PIXMAP_SW, -1, -1) != GRUB_ERR_NONE)
-    return;
-  if (scale_pixmap(self, BOX_PIXMAP_NE, -1, -1) != GRUB_ERR_NONE)
-    return;
-  if (scale_pixmap(self, BOX_PIXMAP_SE, -1, -1) != GRUB_ERR_NONE)
-    return;
-
-  /* Scale the center area. */
-  if (scale_pixmap(self, BOX_PIXMAP_CENTER, width, height) != GRUB_ERR_NONE)
-    return;
-}
-
-static int
-get_left_pad (grub_gfxmenu_box_t self)
-{
-  return get_width (self->raw_pixmaps[BOX_PIXMAP_W]);
-}
-
-static int
-get_top_pad (grub_gfxmenu_box_t self)
-{
-  return get_height (self->raw_pixmaps[BOX_PIXMAP_N]);
-}
-
-static int
-get_right_pad (grub_gfxmenu_box_t self)
-{
-  return get_width (self->raw_pixmaps[BOX_PIXMAP_E]);
-}
-
-static int
-get_bottom_pad (grub_gfxmenu_box_t self)
-{
-  return get_height (self->raw_pixmaps[BOX_PIXMAP_S]);
-}
-
-static void
-destroy (grub_gfxmenu_box_t self)
-{
-  unsigned i;
-  for (i = 0; i < BOX_NUM_PIXMAPS; i++)
-    {
-      if (self->raw_pixmaps[i])
-        grub_video_bitmap_destroy(self->raw_pixmaps[i]);
-      self->raw_pixmaps[i] = 0;
-
-      if (self->scaled_pixmaps[i])
-        grub_video_bitmap_destroy(self->scaled_pixmaps[i]);
-      self->scaled_pixmaps[i] = 0;
-    }
-  grub_free (self->raw_pixmaps);
-  self->raw_pixmaps = 0;
-  grub_free (self->scaled_pixmaps);
-  self->scaled_pixmaps = 0;
-
-  /* Free self:  must be the last step!  */
-  grub_free (self);
-}
-
-
-/* Create a new box.  If PIXMAPS_PREFIX and PIXMAPS_SUFFIX are both non-null,
-   then an attempt is made to load the north, south, east, west, northwest,
-   northeast, southeast, southwest, and center pixmaps.
-   If either PIXMAPS_PREFIX or PIXMAPS_SUFFIX is 0, then no pixmaps are
-   loaded, and the box has zero-width borders and is drawn transparent.  */
-grub_gfxmenu_box_t
-grub_gfxmenu_create_box (const char *pixmaps_prefix,
-                         const char *pixmaps_suffix)
-{
-  unsigned i;
-  grub_gfxmenu_box_t box;
-
-  box = (grub_gfxmenu_box_t) grub_malloc (sizeof (*box));
-  if (! box)
-    return 0;
-
-  box->content_width = 0;
-  box->content_height = 0;
-  box->raw_pixmaps =
-    (struct grub_video_bitmap **)
-    grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *));
-  box->scaled_pixmaps =
-    (struct grub_video_bitmap **)
-    grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *));
-
-  /* Initialize all pixmap pointers to NULL so that proper destruction can
-     be performed if an error is encountered partway through construction.  */
-  for (i = 0; i < BOX_NUM_PIXMAPS; i++)
-      box->raw_pixmaps[i] = 0;
-  for (i = 0; i < BOX_NUM_PIXMAPS; i++)
-      box->scaled_pixmaps[i] = 0;
-
-  /* Load the pixmaps.  */
-  for (i = 0; i < BOX_NUM_PIXMAPS; i++)
-    {
-      if (pixmaps_prefix && pixmaps_suffix)
-        {
-          char *path;
-          char *path_end;
-
-          path = grub_malloc (grub_strlen (pixmaps_prefix)
-                              + grub_strlen (box_pixmap_names[i])
-                              + grub_strlen (pixmaps_suffix)
-                              + 1);
-          if (! path)
-            goto fail_and_destroy;
-
-          /* Construct the specific path for this pixmap.  */
-          path_end = grub_stpcpy (path, pixmaps_prefix);
-          path_end = grub_stpcpy (path_end, box_pixmap_names[i]);
-          path_end = grub_stpcpy (path_end, pixmaps_suffix);
-
-          grub_video_bitmap_load (&box->raw_pixmaps[i], path);
-          grub_free (path);
-
-          /* Ignore missing pixmaps.  */
-          grub_errno = GRUB_ERR_NONE;
-        }
-    }
-
-  box->draw = draw;
-  box->set_content_size = set_content_size;
-  box->get_left_pad = get_left_pad;
-  box->get_top_pad = get_top_pad;
-  box->get_right_pad = get_right_pad;
-  box->get_bottom_pad = get_bottom_pad;
-  box->destroy = destroy;
-  return box;
-
-fail_and_destroy:
-  destroy (box);
-  return 0;
-}
diff --git a/gnulib/alloca.h b/gnulib/alloca.h
deleted file mode 100644 (file)
index 107534e..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Memory allocation on the stack.
-
-   Copyright (C) 1995, 1999, 2001-2004, 2006-2010 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-   USA.  */
-
-/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H
-   means there is a real alloca function.  */
-#ifndef _GL_ALLOCA_H
-#define _GL_ALLOCA_H
-
-/* alloca (N) returns a pointer to N bytes of memory
-   allocated on the stack, which will last until the function returns.
-   Use of alloca should be avoided:
-     - inside arguments of function calls - undefined behaviour,
-     - in inline functions - the allocation may actually last until the
-       calling function returns,
-     - for huge N (say, N >= 65536) - you never know how large (or small)
-       the stack is, and when the stack cannot fulfill the memory allocation
-       request, the program just crashes.
- */
-
-#ifndef alloca
-# ifdef __GNUC__
-#  define alloca __builtin_alloca
-# elif defined _AIX
-#  define alloca __alloca
-# elif defined _MSC_VER
-#  include <malloc.h>
-#  define alloca _alloca
-# elif defined __DECC && defined __VMS
-#  define alloca __ALLOCA
-# else
-#  include <stddef.h>
-#  ifdef  __cplusplus
-extern "C"
-#  endif
-void *alloca (size_t);
-# endif
-#endif
-
-#endif /* _GL_ALLOCA_H */
diff --git a/gnulib/argp-ba.c b/gnulib/argp-ba.c
deleted file mode 100644 (file)
index 95feabb..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Default definition for ARGP_PROGRAM_BUG_ADDRESS.
-   Copyright (C) 1996, 1997, 1999, 2009, 2010 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-/* If set by the user program, it should point to string that is the
-   bug-reporting address for the program.  It will be printed by argp_help if
-   the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help
-   messages), embedded in a sentence that says something like `Report bugs to
-   ADDR.'.  */
-const char *argp_program_bug_address
-/* This variable should be zero-initialized.  On most systems, putting it into
-   BSS is sufficient.  Not so on MacOS X 10.3 and 10.4, see
-   <http://lists.gnu.org/archive/html/bug-gnulib/2009-01/msg00329.html>
-   <http://lists.gnu.org/archive/html/bug-gnulib/2009-08/msg00096.html>.  */
-#if defined __ELF__
-  /* On ELF systems, variables in BSS behave well.  */
-#else
-  = (const char *) 0
-#endif
-  ;
diff --git a/gnulib/argp-eexst.c b/gnulib/argp-eexst.c
deleted file mode 100644 (file)
index 115a8cd..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Default definition for ARGP_ERR_EXIT_STATUS
-   Copyright (C) 1997, 2009, 2010 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <sysexits.h>
-
-#include "argp.h"
-
-/* The exit status that argp will use when exiting due to a parsing error.
-   If not defined or set by the user program, this defaults to EX_USAGE from
-   <sysexits.h>.  */
-error_t argp_err_exit_status = EX_USAGE;
diff --git a/gnulib/argp-fmtstream.c b/gnulib/argp-fmtstream.c
deleted file mode 100644 (file)
index 70bbebc..0000000
+++ /dev/null
@@ -1,435 +0,0 @@
-/* Word-wrapping and line-truncating streams
-   Copyright (C) 1997-1999, 2001-2003, 2005, 2009-2010 Free Software
-   Foundation, Inc.
-   This file is part of the GNU C Library.
-   Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-/* This package emulates glibc `line_wrap_stream' semantics for systems that
-   don't have that.  */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-#include "argp-fmtstream.h"
-#include "argp-namefrob.h"
-
-#ifndef ARGP_FMTSTREAM_USE_LINEWRAP
-
-#ifndef isblank
-#define isblank(ch) ((ch)==' ' || (ch)=='\t')
-#endif
-
-#if defined _LIBC && defined USE_IN_LIBIO
-# include <wchar.h>
-# include <libio/libioP.h>
-# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
-#endif
-
-#define INIT_BUF_SIZE 200
-#define PRINTF_SIZE_GUESS 150
-\f
-/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
-   written on it with LMARGIN spaces and limits them to RMARGIN columns
-   total.  If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
-   replacing the whitespace before them with a newline and WMARGIN spaces.
-   Otherwise, chars beyond RMARGIN are simply dropped until a newline.
-   Returns NULL if there was an error.  */
-argp_fmtstream_t
-__argp_make_fmtstream (FILE *stream,
-                       size_t lmargin, size_t rmargin, ssize_t wmargin)
-{
-  argp_fmtstream_t fs;
-
-  fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream));
-  if (fs != NULL)
-    {
-      fs->stream = stream;
-
-      fs->lmargin = lmargin;
-      fs->rmargin = rmargin;
-      fs->wmargin = wmargin;
-      fs->point_col = 0;
-      fs->point_offs = 0;
-
-      fs->buf = (char *) malloc (INIT_BUF_SIZE);
-      if (! fs->buf)
-        {
-          free (fs);
-          fs = 0;
-        }
-      else
-        {
-          fs->p = fs->buf;
-          fs->end = fs->buf + INIT_BUF_SIZE;
-        }
-    }
-
-  return fs;
-}
-#if 0
-/* Not exported.  */
-#ifdef weak_alias
-weak_alias (__argp_make_fmtstream, argp_make_fmtstream)
-#endif
-#endif
-
-/* Flush FS to its stream, and free it (but don't close the stream).  */
-void
-__argp_fmtstream_free (argp_fmtstream_t fs)
-{
-  __argp_fmtstream_update (fs);
-  if (fs->p > fs->buf)
-    {
-#ifdef USE_IN_LIBIO
-      __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
-#else
-      fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
-#endif
-    }
-  free (fs->buf);
-  free (fs);
-}
-#if 0
-/* Not exported.  */
-#ifdef weak_alias
-weak_alias (__argp_fmtstream_free, argp_fmtstream_free)
-#endif
-#endif
-\f
-/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the
-   end of its buffer.  This code is mostly from glibc stdio/linewrap.c.  */
-void
-__argp_fmtstream_update (argp_fmtstream_t fs)
-{
-  char *buf, *nl;
-  size_t len;
-
-  /* Scan the buffer for newlines.  */
-  buf = fs->buf + fs->point_offs;
-  while (buf < fs->p)
-    {
-      size_t r;
-
-      if (fs->point_col == 0 && fs->lmargin != 0)
-        {
-          /* We are starting a new line.  Print spaces to the left margin.  */
-          const size_t pad = fs->lmargin;
-          if (fs->p + pad < fs->end)
-            {
-              /* We can fit in them in the buffer by moving the
-                 buffer text up and filling in the beginning.  */
-              memmove (buf + pad, buf, fs->p - buf);
-              fs->p += pad; /* Compensate for bigger buffer. */
-              memset (buf, ' ', pad); /* Fill in the spaces.  */
-              buf += pad; /* Don't bother searching them.  */
-            }
-          else
-            {
-              /* No buffer space for spaces.  Must flush.  */
-              size_t i;
-              for (i = 0; i < pad; i++)
-                {
-#ifdef USE_IN_LIBIO
-                  if (_IO_fwide (fs->stream, 0) > 0)
-                    putwc_unlocked (L' ', fs->stream);
-                  else
-#endif
-                    putc_unlocked (' ', fs->stream);
-                }
-            }
-          fs->point_col = pad;
-        }
-
-      len = fs->p - buf;
-      nl = memchr (buf, '\n', len);
-
-      if (fs->point_col < 0)
-        fs->point_col = 0;
-
-      if (!nl)
-        {
-          /* The buffer ends in a partial line.  */
-
-          if (fs->point_col + len < fs->rmargin)
-            {
-              /* The remaining buffer text is a partial line and fits
-                 within the maximum line width.  Advance point for the
-                 characters to be written and stop scanning.  */
-              fs->point_col += len;
-              break;
-            }
-          else
-            /* Set the end-of-line pointer for the code below to
-               the end of the buffer.  */
-            nl = fs->p;
-        }
-      else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin)
-        {
-          /* The buffer contains a full line that fits within the maximum
-             line width.  Reset point and scan the next line.  */
-          fs->point_col = 0;
-          buf = nl + 1;
-          continue;
-        }
-
-      /* This line is too long.  */
-      r = fs->rmargin - 1;
-
-      if (fs->wmargin < 0)
-        {
-          /* Truncate the line by overwriting the excess with the
-             newline and anything after it in the buffer.  */
-          if (nl < fs->p)
-            {
-              memmove (buf + (r - fs->point_col), nl, fs->p - nl);
-              fs->p -= buf + (r - fs->point_col) - nl;
-              /* Reset point for the next line and start scanning it.  */
-              fs->point_col = 0;
-              buf += r + 1; /* Skip full line plus \n. */
-            }
-          else
-            {
-              /* The buffer ends with a partial line that is beyond the
-                 maximum line width.  Advance point for the characters
-                 written, and discard those past the max from the buffer.  */
-              fs->point_col += len;
-              fs->p -= fs->point_col - r;
-              break;
-            }
-        }
-      else
-        {
-          /* Do word wrap.  Go to the column just past the maximum line
-             width and scan back for the beginning of the word there.
-             Then insert a line break.  */
-
-          char *p, *nextline;
-          int i;
-
-          p = buf + (r + 1 - fs->point_col);
-          while (p >= buf && !isblank ((unsigned char) *p))
-            --p;
-          nextline = p + 1;     /* This will begin the next line.  */
-
-          if (nextline > buf)
-            {
-              /* Swallow separating blanks.  */
-              if (p >= buf)
-                do
-                  --p;
-                while (p >= buf && isblank ((unsigned char) *p));
-              nl = p + 1;       /* The newline will replace the first blank. */
-            }
-          else
-            {
-              /* A single word that is greater than the maximum line width.
-                 Oh well.  Put it on an overlong line by itself.  */
-              p = buf + (r + 1 - fs->point_col);
-              /* Find the end of the long word.  */
-              if (p < nl)
-                do
-                  ++p;
-                while (p < nl && !isblank ((unsigned char) *p));
-              if (p == nl)
-                {
-                  /* It already ends a line.  No fussing required.  */
-                  fs->point_col = 0;
-                  buf = nl + 1;
-                  continue;
-                }
-              /* We will move the newline to replace the first blank.  */
-              nl = p;
-              /* Swallow separating blanks.  */
-              do
-                ++p;
-              while (isblank ((unsigned char) *p));
-              /* The next line will start here.  */
-              nextline = p;
-            }
-
-          /* Note: There are a bunch of tests below for
-             NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall
-             at the end of the buffer, and NEXTLINE is in fact empty (and so
-             we need not be careful to maintain its contents).  */
-
-          if ((nextline == buf + len + 1
-               ? fs->end - nl < fs->wmargin + 1
-               : nextline - (nl + 1) < fs->wmargin)
-              && fs->p > nextline)
-            {
-              /* The margin needs more blanks than we removed.  */
-              if (fs->end - fs->p > fs->wmargin + 1)
-                /* Make some space for them.  */
-                {
-                  size_t mv = fs->p - nextline;
-                  memmove (nl + 1 + fs->wmargin, nextline, mv);
-                  nextline = nl + 1 + fs->wmargin;
-                  len = nextline + mv - buf;
-                  *nl++ = '\n';
-                }
-              else
-                /* Output the first line so we can use the space.  */
-                {
-#ifdef _LIBC
-                  __fxprintf (fs->stream, "%.*s\n",
-                              (int) (nl - fs->buf), fs->buf);
-#else
-                  if (nl > fs->buf)
-                    fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream);
-                  putc_unlocked ('\n', fs->stream);
-#endif
-
-                  len += buf - fs->buf;
-                  nl = buf = fs->buf;
-                }
-            }
-          else
-            /* We can fit the newline and blanks in before
-               the next word.  */
-            *nl++ = '\n';
-
-          if (nextline - nl >= fs->wmargin
-              || (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin))
-            /* Add blanks up to the wrap margin column.  */
-            for (i = 0; i < fs->wmargin; ++i)
-              *nl++ = ' ';
-          else
-            for (i = 0; i < fs->wmargin; ++i)
-#ifdef USE_IN_LIBIO
-              if (_IO_fwide (fs->stream, 0) > 0)
-                putwc_unlocked (L' ', fs->stream);
-              else
-#endif
-                putc_unlocked (' ', fs->stream);
-
-          /* Copy the tail of the original buffer into the current buffer
-             position.  */
-          if (nl < nextline)
-            memmove (nl, nextline, buf + len - nextline);
-          len -= nextline - buf;
-
-          /* Continue the scan on the remaining lines in the buffer.  */
-          buf = nl;
-
-          /* Restore bufp to include all the remaining text.  */
-          fs->p = nl + len;
-
-          /* Reset the counter of what has been output this line.  If wmargin
-             is 0, we want to avoid the lmargin getting added, so we set
-             point_col to a magic value of -1 in that case.  */
-          fs->point_col = fs->wmargin ? fs->wmargin : -1;
-        }
-    }
-
-  /* Remember that we've scanned as far as the end of the buffer.  */
-  fs->point_offs = fs->p - fs->buf;
-}
-\f
-/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by
-   growing the buffer, or by flushing it.  True is returned iff we succeed. */
-int
-__argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
-{
-  if ((size_t) (fs->end - fs->p) < amount)
-    {
-      ssize_t wrote;
-
-      /* Flush FS's buffer.  */
-      __argp_fmtstream_update (fs);
-
-#ifdef _LIBC
-      __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
-      wrote = fs->p - fs->buf;
-#else
-      wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
-#endif
-      if (wrote == fs->p - fs->buf)
-        {
-          fs->p = fs->buf;
-          fs->point_offs = 0;
-        }
-      else
-        {
-          fs->p -= wrote;
-          fs->point_offs -= wrote;
-          memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf);
-          return 0;
-        }
-
-      if ((size_t) (fs->end - fs->buf) < amount)
-        /* Gotta grow the buffer.  */
-        {
-          size_t old_size = fs->end - fs->buf;
-          size_t new_size = old_size + amount;
-          char *new_buf;
-
-          if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size)))
-            {
-              __set_errno (ENOMEM);
-              return 0;
-            }
-
-          fs->buf = new_buf;
-          fs->end = new_buf + new_size;
-          fs->p = fs->buf;
-        }
-    }
-
-  return 1;
-}
-\f
-ssize_t
-__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...)
-{
-  int out;
-  size_t avail;
-  size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */
-
-  do
-    {
-      va_list args;
-
-      if (! __argp_fmtstream_ensure (fs, size_guess))
-        return -1;
-
-      va_start (args, fmt);
-      avail = fs->end - fs->p;
-      out = __vsnprintf (fs->p, avail, fmt, args);
-      va_end (args);
-      if ((size_t) out >= avail)
-        size_guess = out + 1;
-    }
-  while ((size_t) out >= avail);
-
-  fs->p += out;
-
-  return out;
-}
-#if 0
-/* Not exported.  */
-#ifdef weak_alias
-weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf)
-#endif
-#endif
-
-#endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */
diff --git a/gnulib/argp-fmtstream.h b/gnulib/argp-fmtstream.h
deleted file mode 100644 (file)
index b913d1b..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-/* Word-wrapping and line-truncating streams.
-   Copyright (C) 1997, 2006-2010 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-/* This package emulates glibc `line_wrap_stream' semantics for systems that
-   don't have that.  If the system does have it, it is just a wrapper for
-   that.  This header file is only used internally while compiling argp, and
-   shouldn't be installed.  */
-
-#ifndef _ARGP_FMTSTREAM_H
-#define _ARGP_FMTSTREAM_H
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#ifndef __attribute__
-/* The __attribute__ feature is available in gcc versions 2.5 and later.
-   The __-protected variants of the attributes 'format' and 'printf' are
-   accepted by gcc versions 2.6.4 (effectively 2.7) and later.
-   We enable __attribute__ only if these are supported too, because
-   gnulib and libintl do '#define printf __printf__' when they override
-   the 'printf' function.  */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
-#  define __attribute__(Spec)   /* empty */
-# endif
-#endif
-
-#if    (_LIBC - 0 && !defined (USE_IN_LIBIO)) \
-    || (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H))
-/* line_wrap_stream is available, so use that.  */
-#define ARGP_FMTSTREAM_USE_LINEWRAP
-#endif
-
-#ifdef ARGP_FMTSTREAM_USE_LINEWRAP
-/* Just be a simple wrapper for line_wrap_stream; the semantics are
-   *slightly* different, as line_wrap_stream doesn't actually make a new
-   object, it just modifies the given stream (reversibly) to do
-   line-wrapping.  Since we control who uses this code, it doesn't matter.  */
-
-#include <linewrap.h>
-
-typedef FILE *argp_fmtstream_t;
-
-#define argp_make_fmtstream line_wrap_stream
-#define __argp_make_fmtstream line_wrap_stream
-#define argp_fmtstream_free line_unwrap_stream
-#define __argp_fmtstream_free line_unwrap_stream
-
-#define __argp_fmtstream_putc(fs,ch) putc(ch,fs)
-#define argp_fmtstream_putc(fs,ch) putc(ch,fs)
-#define __argp_fmtstream_puts(fs,str) fputs(str,fs)
-#define argp_fmtstream_puts(fs,str) fputs(str,fs)
-#define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
-#define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
-#define __argp_fmtstream_printf fprintf
-#define argp_fmtstream_printf fprintf
-
-#define __argp_fmtstream_lmargin line_wrap_lmargin
-#define argp_fmtstream_lmargin line_wrap_lmargin
-#define __argp_fmtstream_set_lmargin line_wrap_set_lmargin
-#define argp_fmtstream_set_lmargin line_wrap_set_lmargin
-#define __argp_fmtstream_rmargin line_wrap_rmargin
-#define argp_fmtstream_rmargin line_wrap_rmargin
-#define __argp_fmtstream_set_rmargin line_wrap_set_rmargin
-#define argp_fmtstream_set_rmargin line_wrap_set_rmargin
-#define __argp_fmtstream_wmargin line_wrap_wmargin
-#define argp_fmtstream_wmargin line_wrap_wmargin
-#define __argp_fmtstream_set_wmargin line_wrap_set_wmargin
-#define argp_fmtstream_set_wmargin line_wrap_set_wmargin
-#define __argp_fmtstream_point line_wrap_point
-#define argp_fmtstream_point line_wrap_point
-
-#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */
-/* Guess we have to define our own version.  */
-\f
-struct argp_fmtstream
-{
-  FILE *stream;                 /* The stream we're outputting to.  */
-
-  size_t lmargin, rmargin;      /* Left and right margins.  */
-  ssize_t wmargin;              /* Margin to wrap to, or -1 to truncate.  */
-
-  /* Point in buffer to which we've processed for wrapping, but not output.  */
-  size_t point_offs;
-  /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin.  */
-  ssize_t point_col;
-
-  char *buf;                    /* Output buffer.  */
-  char *p;                      /* Current end of text in BUF. */
-  char *end;                    /* Absolute end of BUF.  */
-};
-
-typedef struct argp_fmtstream *argp_fmtstream_t;
-
-/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
-   written on it with LMARGIN spaces and limits them to RMARGIN columns
-   total.  If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
-   replacing the whitespace before them with a newline and WMARGIN spaces.
-   Otherwise, chars beyond RMARGIN are simply dropped until a newline.
-   Returns NULL if there was an error.  */
-extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream,
-                                               size_t __lmargin,
-                                               size_t __rmargin,
-                                               ssize_t __wmargin);
-extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream,
-                                             size_t __lmargin,
-                                             size_t __rmargin,
-                                             ssize_t __wmargin);
-
-/* Flush __FS to its stream, and free it (but don't close the stream).  */
-extern void __argp_fmtstream_free (argp_fmtstream_t __fs);
-extern void argp_fmtstream_free (argp_fmtstream_t __fs);
-
-extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs,
-                                        const char *__fmt, ...)
-     __attribute__ ((__format__ (printf, 2, 3)));
-extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs,
-                                      const char *__fmt, ...)
-     __attribute__ ((__format__ (printf, 2, 3)));
-
-#if _LIBC || !defined __OPTIMIZE__
-extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
-extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
-
-extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str);
-extern int argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str);
-
-extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs,
-                                      const char *__str, size_t __len);
-extern size_t argp_fmtstream_write (argp_fmtstream_t __fs,
-                                    const char *__str, size_t __len);
-#endif
-\f
-/* Access macros for various bits of state.  */
-#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin)
-#define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin)
-#define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin)
-#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
-#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
-#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
-
-#if _LIBC || !defined __OPTIMIZE__
-/* Set __FS's left margin to LMARGIN and return the old value.  */
-extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
-                                          size_t __lmargin);
-extern size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
-                                            size_t __lmargin);
-
-/* Set __FS's right margin to __RMARGIN and return the old value.  */
-extern size_t argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
-                                          size_t __rmargin);
-extern size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
-                                            size_t __rmargin);
-
-/* Set __FS's wrap margin to __WMARGIN and return the old value.  */
-extern size_t argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
-                                          size_t __wmargin);
-extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
-                                            size_t __wmargin);
-
-/* Return the column number of the current output point in __FS.  */
-extern size_t argp_fmtstream_point (argp_fmtstream_t __fs);
-extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs);
-#endif
-
-/* Internal routines.  */
-extern void _argp_fmtstream_update (argp_fmtstream_t __fs);
-extern void __argp_fmtstream_update (argp_fmtstream_t __fs);
-extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
-extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
-\f
-#ifdef __OPTIMIZE__
-/* Inline versions of above routines.  */
-
-#if !_LIBC
-#define __argp_fmtstream_putc argp_fmtstream_putc
-#define __argp_fmtstream_puts argp_fmtstream_puts
-#define __argp_fmtstream_write argp_fmtstream_write
-#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
-#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
-#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
-#define __argp_fmtstream_point argp_fmtstream_point
-#define __argp_fmtstream_update _argp_fmtstream_update
-#define __argp_fmtstream_ensure _argp_fmtstream_ensure
-#endif
-
-#ifndef ARGP_FS_EI
-# ifdef __GNUC__
-   /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
-      inline semantics, unless -fgnu89-inline is used.  It defines a macro
-      __GNUC_STDC_INLINE__ to indicate this situation or a macro
-      __GNUC_GNU_INLINE__ to indicate the opposite situation.
-
-      GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline
-      semantics but warns, unless -fgnu89-inline is used:
-        warning: C99 inline functions are not supported; using GNU89
-        warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute
-      It defines a macro __GNUC_GNU_INLINE__ to indicate this situation.
-
-      Whereas Apple GCC 4.0.1 build 5479 without -std=c99 or -std=gnu99
-      implements the GNU C inline semantics and defines the macro
-      __GNUC_GNU_INLINE__, but it does not warn and does not support
-      __attribute__ ((__gnu_inline__)).
-
-      All in all, these are the possible combinations.  For every compiler,
-      we need to choose ARGP_FS_EI so that the corresponding table cell
-      contains an "ok".
-
-        \    ARGP_FS_EI                      inline   extern    extern
-          \                                           inline    inline
-      CC    \                                                   __attribute__
-                                                                ((gnu_inline))
-
-      gcc 4.3.0                              error    ok        ok
-      gcc 4.3.0 -std=gnu99 -fgnu89-inline    error    ok        ok
-      gcc 4.3.0 -std=gnu99                   ok       error     ok
-
-      gcc 4.2.2                              error    ok        ok
-      gcc 4.2.2 -std=gnu99 -fgnu89-inline    error    ok        ok
-      gcc 4.2.2 -std=gnu99                   error    warning   ok
-
-      gcc 4.1.2                              error    ok        warning
-      gcc 4.1.2 -std=gnu99                   error    ok        warning
-
-      Apple gcc 4.0.1                        error    ok        warning
-      Apple gcc 4.0.1 -std=gnu99             ok       error     warning
-    */
-#  if defined __GNUC_STDC_INLINE__
-#   define ARGP_FS_EI inline
-#  elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)
-#   define ARGP_FS_EI extern inline __attribute__ ((__gnu_inline__))
-#  else
-#   define ARGP_FS_EI extern inline
-#  endif
-# else
-   /* With other compilers, assume the ISO C99 meaning of 'inline', if
-      the compiler supports 'inline' at all.  */
-#  define ARGP_FS_EI inline
-# endif
-#endif
-
-ARGP_FS_EI size_t
-__argp_fmtstream_write (argp_fmtstream_t __fs,
-                        const char *__str, size_t __len)
-{
-  if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
-    {
-      memcpy (__fs->p, __str, __len);
-      __fs->p += __len;
-      return __len;
-    }
-  else
-    return 0;
-}
-
-ARGP_FS_EI int
-__argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str)
-{
-  size_t __len = strlen (__str);
-  if (__len)
-    {
-      size_t __wrote = __argp_fmtstream_write (__fs, __str, __len);
-      return __wrote == __len ? 0 : -1;
-    }
-  else
-    return 0;
-}
-
-ARGP_FS_EI int
-__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch)
-{
-  if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1))
-    return *__fs->p++ = __ch;
-  else
-    return EOF;
-}
-
-/* Set __FS's left margin to __LMARGIN and return the old value.  */
-ARGP_FS_EI size_t
-__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin)
-{
-  size_t __old;
-  if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
-    __argp_fmtstream_update (__fs);
-  __old = __fs->lmargin;
-  __fs->lmargin = __lmargin;
-  return __old;
-}
-
-/* Set __FS's right margin to __RMARGIN and return the old value.  */
-ARGP_FS_EI size_t
-__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin)
-{
-  size_t __old;
-  if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
-    __argp_fmtstream_update (__fs);
-  __old = __fs->rmargin;
-  __fs->rmargin = __rmargin;
-  return __old;
-}
-
-/* Set FS's wrap margin to __WMARGIN and return the old value.  */
-ARGP_FS_EI size_t
-__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
-{
-  size_t __old;
-  if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
-    __argp_fmtstream_update (__fs);
-  __old = __fs->wmargin;
-  __fs->wmargin = __wmargin;
-  return __old;
-}
-
-/* Return the column number of the current output point in __FS.  */
-ARGP_FS_EI size_t
-__argp_fmtstream_point (argp_fmtstream_t __fs)
-{
-  if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
-    __argp_fmtstream_update (__fs);
-  return __fs->point_col >= 0 ? __fs->point_col : 0;
-}
-
-#if !_LIBC
-#undef __argp_fmtstream_putc
-#undef __argp_fmtstream_puts
-#undef __argp_fmtstream_write
-#undef __argp_fmtstream_set_lmargin
-#undef __argp_fmtstream_set_rmargin
-#undef __argp_fmtstream_set_wmargin
-#undef __argp_fmtstream_point
-#undef __argp_fmtstream_update
-#undef __argp_fmtstream_ensure
-#endif
-
-#endif /* __OPTIMIZE__ */
-
-#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */
-
-#endif /* argp-fmtstream.h */
diff --git a/gnulib/argp-fs-xinl.c b/gnulib/argp-fs-xinl.c
deleted file mode 100644 (file)
index 2c683f9..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Real definitions for extern inline functions in argp-fmtstream.h
-   Copyright (C) 1997, 2003, 2004, 2009, 2010 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#define ARGP_FS_EI
-#undef __OPTIMIZE__
-#define __OPTIMIZE__ 1
-#include "argp-fmtstream.h"
-
-#if 0
-/* Not exported.  */
-/* Add weak aliases.  */
-#if _LIBC - 0 && !defined (ARGP_FMTSTREAM_USE_LINEWRAP) && defined (weak_alias)
-
-weak_alias (__argp_fmtstream_putc, argp_fmtstream_putc)
-weak_alias (__argp_fmtstream_puts, argp_fmtstream_puts)
-weak_alias (__argp_fmtstream_write, argp_fmtstream_write)
-weak_alias (__argp_fmtstream_set_lmargin, argp_fmtstream_set_lmargin)
-weak_alias (__argp_fmtstream_set_rmargin, argp_fmtstream_set_rmargin)
-weak_alias (__argp_fmtstream_set_wmargin, argp_fmtstream_set_wmargin)
-weak_alias (__argp_fmtstream_point, argp_fmtstream_point)
-
-#endif
-#endif
diff --git a/gnulib/argp-help.c b/gnulib/argp-help.c
deleted file mode 100644 (file)
index 5b6d950..0000000
+++ /dev/null
@@ -1,1951 +0,0 @@
-/* Hierarchial argument parsing help output
-   Copyright (C) 1995-2005, 2007, 2009-2010 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE    1
-#endif
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <alloca.h>
-#include <errno.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <limits.h>
-#ifdef USE_IN_LIBIO
-# include <wchar.h>
-#endif
-
-#ifdef _LIBC
-# include <libintl.h>
-# undef dgettext
-# define dgettext(domain, msgid) \
-   INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
-#else
-# include "gettext.h"
-#endif
-
-#include "argp.h"
-#include "argp-fmtstream.h"
-#include "argp-namefrob.h"
-
-#ifndef SIZE_MAX
-# define SIZE_MAX ((size_t) -1)
-#endif
-\f
-/* User-selectable (using an environment variable) formatting parameters.
-
-   These may be specified in an environment variable called `ARGP_HELP_FMT',
-   with a contents like:  VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2
-   Where VALn must be a positive integer.  The list of variables is in the
-   UPARAM_NAMES vector, below.  */
-
-/* Default parameters.  */
-#define DUP_ARGS      0         /* True if option argument can be duplicated. */
-#define DUP_ARGS_NOTE 1         /* True to print a note about duplicate args. */
-#define SHORT_OPT_COL 2         /* column in which short options start */
-#define LONG_OPT_COL  6         /* column in which long options start */
-#define DOC_OPT_COL   2         /* column in which doc options start */
-#define OPT_DOC_COL  29         /* column in which option text starts */
-#define HEADER_COL    1         /* column in which group headers are printed */
-#define USAGE_INDENT 12         /* indentation of wrapped usage lines */
-#define RMARGIN      79         /* right margin used for wrapping */
-
-/* User-selectable (using an environment variable) formatting parameters.
-   They must all be of type `int' for the parsing code to work.  */
-struct uparams
-{
-  /* If true, arguments for an option are shown with both short and long
-     options, even when a given option has both, e.g. `-x ARG, --longx=ARG'.
-     If false, then if an option has both, the argument is only shown with
-     the long one, e.g., `-x, --longx=ARG', and a message indicating that
-     this really means both is printed below the options.  */
-  int dup_args;
-
-  /* This is true if when DUP_ARGS is false, and some duplicate arguments have
-     been suppressed, an explanatory message should be printed.  */
-  int dup_args_note;
-
-  /* Various output columns.  */
-  int short_opt_col;      /* column in which short options start */
-  int long_opt_col;       /* column in which long options start */
-  int doc_opt_col;        /* column in which doc options start */
-  int opt_doc_col;        /* column in which option text starts */
-  int header_col;         /* column in which group headers are printed */
-  int usage_indent;       /* indentation of wrapped usage lines */
-  int rmargin;            /* right margin used for wrapping */
-
-  int valid;              /* True when the values in here are valid.  */
-};
-
-/* This is a global variable, as user options are only ever read once.  */
-static struct uparams uparams = {
-  DUP_ARGS, DUP_ARGS_NOTE,
-  SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL,
-  USAGE_INDENT, RMARGIN,
-  0
-};
-
-/* A particular uparam, and what the user name is.  */
-struct uparam_name
-{
-  const char *name;             /* User name.  */
-  int is_bool;                  /* Whether it's `boolean'.  */
-  size_t uparams_offs;          /* Location of the (int) field in UPARAMS.  */
-};
-
-/* The name-field mappings we know about.  */
-static const struct uparam_name uparam_names[] =
-{
-  { "dup-args",       1, offsetof (struct uparams, dup_args) },
-  { "dup-args-note",  1, offsetof (struct uparams, dup_args_note) },
-  { "short-opt-col",  0, offsetof (struct uparams, short_opt_col) },
-  { "long-opt-col",   0, offsetof (struct uparams, long_opt_col) },
-  { "doc-opt-col",    0, offsetof (struct uparams, doc_opt_col) },
-  { "opt-doc-col",    0, offsetof (struct uparams, opt_doc_col) },
-  { "header-col",     0, offsetof (struct uparams, header_col) },
-  { "usage-indent",   0, offsetof (struct uparams, usage_indent) },
-  { "rmargin",        0, offsetof (struct uparams, rmargin) },
-  { 0 }
-};
-
-static void
-validate_uparams (const struct argp_state *state, struct uparams *upptr)
-{
-  const struct uparam_name *up;
-
-  for (up = uparam_names; up->name; up++)
-    {
-      if (up->is_bool
-          || up->uparams_offs == offsetof (struct uparams, rmargin))
-        continue;
-      if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin)
-        {
-          __argp_failure (state, 0, 0,
-                          dgettext (state->root_argp->argp_domain,
-                                    "\
-ARGP_HELP_FMT: %s value is less than or equal to %s"),
-                          "rmargin", up->name);
-          return;
-        }
-    }
-  uparams = *upptr;
-  uparams.valid = 1;
-}
-
-/* Read user options from the environment, and fill in UPARAMS appropiately. */
-static void
-fill_in_uparams (const struct argp_state *state)
-{
-  const char *var = getenv ("ARGP_HELP_FMT");
-  struct uparams new_params = uparams;
-
-#define SKIPWS(p) do { while (isspace ((unsigned char) *p)) p++; } while (0);
-
-  if (var)
-    {
-      /* Parse var. */
-      while (*var)
-        {
-          SKIPWS (var);
-
-          if (isalpha ((unsigned char) *var))
-            {
-              size_t var_len;
-              const struct uparam_name *un;
-              int unspec = 0, val = 0;
-              const char *arg = var;
-
-              while (isalnum ((unsigned char) *arg) || *arg == '-' || *arg == '_')
-                arg++;
-              var_len = arg - var;
-
-              SKIPWS (arg);
-
-              if (*arg == '\0' || *arg == ',')
-                unspec = 1;
-              else if (*arg == '=')
-                {
-                  arg++;
-                  SKIPWS (arg);
-                }
-
-              if (unspec)
-                {
-                  if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
-                    {
-                      val = 0;
-                      var += 3;
-                      var_len -= 3;
-                    }
-                  else
-                    val = 1;
-                }
-              else if (isdigit ((unsigned char) *arg))
-                {
-                  val = atoi (arg);
-                  while (isdigit ((unsigned char) *arg))
-                    arg++;
-                  SKIPWS (arg);
-                }
-
-              for (un = uparam_names; un->name; un++)
-                if (strlen (un->name) == var_len
-                    && strncmp (var, un->name, var_len) == 0)
-                  {
-                    if (unspec && !un->is_bool)
-                      __argp_failure (state, 0, 0,
-                                      dgettext (state->root_argp->argp_domain,
-                                                "\
-%.*s: ARGP_HELP_FMT parameter requires a value"),
-                                      (int) var_len, var);
-                    else if (val < 0)
-                      __argp_failure (state, 0, 0,
-                                      dgettext (state->root_argp->argp_domain,
-                                                "\
-%.*s: ARGP_HELP_FMT parameter must be positive"),
-                                      (int) var_len, var);
-                    else
-                      *(int *)((char *)&new_params + un->uparams_offs) = val;
-                    break;
-                  }
-              if (! un->name)
-                __argp_failure (state, 0, 0,
-                                dgettext (state->root_argp->argp_domain, "\
-%.*s: Unknown ARGP_HELP_FMT parameter"),
-                                (int) var_len, var);
-
-              var = arg;
-              if (*var == ',')
-                var++;
-            }
-          else if (*var)
-            {
-              __argp_failure (state, 0, 0,
-                              dgettext (state->root_argp->argp_domain,
-                                        "Garbage in ARGP_HELP_FMT: %s"), var);
-              break;
-            }
-        }
-      validate_uparams (state, &new_params);
-    }
-}
-\f
-/* Returns true if OPT hasn't been marked invisible.  Visibility only affects
-   whether OPT is displayed or used in sorting, not option shadowing.  */
-#define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
-
-/* Returns true if OPT is an alias for an earlier option.  */
-#define oalias(opt) ((opt)->flags & OPTION_ALIAS)
-
-/* Returns true if OPT is an documentation-only entry.  */
-#define odoc(opt) ((opt)->flags & OPTION_DOC)
-
-/* Returns true if OPT should not be translated */
-#define onotrans(opt) ((opt)->flags & OPTION_NO_TRANS)
-
-/* Returns true if OPT is the end-of-list marker for a list of options.  */
-#define oend(opt) __option_is_end (opt)
-
-/* Returns true if OPT has a short option.  */
-#define oshort(opt) __option_is_short (opt)
-\f
-/*
-   The help format for a particular option is like:
-
-     -xARG, -yARG, --long1=ARG, --long2=ARG        Documentation...
-
-   Where ARG will be omitted if there's no argument, for this option, or
-   will be surrounded by "[" and "]" appropiately if the argument is
-   optional.  The documentation string is word-wrapped appropiately, and if
-   the list of options is long enough, it will be started on a separate line.
-   If there are no short options for a given option, the first long option is
-   indented slighly in a way that's supposed to make most long options appear
-   to be in a separate column.
-
-   For example, the following output (from ps):
-
-     -p PID, --pid=PID          List the process PID
-         --pgrp=PGRP            List processes in the process group PGRP
-     -P, -x, --no-parent        Include processes without parents
-     -Q, --all-fields           Don't elide unusable fields (normally if there's
-                                some reason ps can't print a field for any
-                                process, it's removed from the output entirely)
-     -r, --reverse, --gratuitously-long-reverse-option
-                                Reverse the order of any sort
-         --session[=SID]        Add the processes from the session SID (which
-                                defaults to the sid of the current process)
-
-    Here are some more options:
-     -f ZOT, --foonly=ZOT       Glork a foonly
-     -z, --zaza                 Snit a zar
-
-     -?, --help                 Give this help list
-         --usage                Give a short usage message
-     -V, --version              Print program version
-
-   The struct argp_option array for the above could look like:
-
-   {
-     {"pid",       'p',      "PID",  0, "List the process PID"},
-     {"pgrp",      OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"},
-     {"no-parent", 'P',       0,     0, "Include processes without parents"},
-     {0,           'x',       0,     OPTION_ALIAS},
-     {"all-fields",'Q',       0,     0, "Don't elide unusable fields (normally"
-                                        " if there's some reason ps can't"
-                                        " print a field for any process, it's"
-                                        " removed from the output entirely)" },
-     {"reverse",   'r',       0,     0, "Reverse the order of any sort"},
-     {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
-     {"session",   OPT_SESS,  "SID", OPTION_ARG_OPTIONAL,
-                                        "Add the processes from the session"
-                                        " SID (which defaults to the sid of"
-                                        " the current process)" },
-
-     {0,0,0,0, "Here are some more options:"},
-     {"foonly", 'f', "ZOT", 0, "Glork a foonly"},
-     {"zaza", 'z', 0, 0, "Snit a zar"},
-
-     {0}
-   }
-
-   Note that the last three options are automatically supplied by argp_parse,
-   unless you tell it not to with ARGP_NO_HELP.
-
-*/
-\f
-/* Returns true if CH occurs between BEG and END.  */
-static int
-find_char (char ch, char *beg, char *end)
-{
-  while (beg < end)
-    if (*beg == ch)
-      return 1;
-    else
-      beg++;
-  return 0;
-}
-\f
-struct hol_cluster;             /* fwd decl */
-
-struct hol_entry
-{
-  /* First option.  */
-  const struct argp_option *opt;
-  /* Number of options (including aliases).  */
-  unsigned num;
-
-  /* A pointers into the HOL's short_options field, to the first short option
-     letter for this entry.  The order of the characters following this point
-     corresponds to the order of options pointed to by OPT, and there are at
-     most NUM.  A short option recorded in a option following OPT is only
-     valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's
-     probably been shadowed by some other entry).  */
-  char *short_options;
-
-  /* Entries are sorted by their group first, in the order:
-       1, 2, ..., n, 0, -m, ..., -2, -1
-     and then alphabetically within each group.  The default is 0.  */
-  int group;
-
-  /* The cluster of options this entry belongs to, or 0 if none.  */
-  struct hol_cluster *cluster;
-
-  /* The argp from which this option came.  */
-  const struct argp *argp;
-
-  /* Position in the array */
-  unsigned ord;
-};
-
-/* A cluster of entries to reflect the argp tree structure.  */
-struct hol_cluster
-{
-  /* A descriptive header printed before options in this cluster.  */
-  const char *header;
-
-  /* Used to order clusters within the same group with the same parent,
-     according to the order in which they occurred in the parent argp's child
-     list.  */
-  int index;
-
-  /* How to sort this cluster with respect to options and other clusters at the
-     same depth (clusters always follow options in the same group).  */
-  int group;
-
-  /* The cluster to which this cluster belongs, or 0 if it's at the base
-     level.  */
-  struct hol_cluster *parent;
-
-  /* The argp from which this cluster is (eventually) derived.  */
-  const struct argp *argp;
-
-  /* The distance this cluster is from the root.  */
-  int depth;
-
-  /* Clusters in a given hol are kept in a linked list, to make freeing them
-     possible.  */
-  struct hol_cluster *next;
-};
-
-/* A list of options for help.  */
-struct hol
-{
-  /* An array of hol_entry's.  */
-  struct hol_entry *entries;
-  /* The number of entries in this hol.  If this field is zero, the others
-     are undefined.  */
-  unsigned num_entries;
-
-  /* A string containing all short options in this HOL.  Each entry contains
-     pointers into this string, so the order can't be messed with blindly.  */
-  char *short_options;
-
-  /* Clusters of entries in this hol.  */
-  struct hol_cluster *clusters;
-};
-\f
-/* Create a struct hol from the options in ARGP.  CLUSTER is the
-   hol_cluster in which these entries occur, or 0, if at the root.  */
-static struct hol *
-make_hol (const struct argp *argp, struct hol_cluster *cluster)
-{
-  char *so;
-  const struct argp_option *o;
-  const struct argp_option *opts = argp->options;
-  struct hol_entry *entry;
-  unsigned num_short_options = 0;
-  struct hol *hol = malloc (sizeof (struct hol));
-
-  assert (hol);
-
-  hol->num_entries = 0;
-  hol->clusters = 0;
-
-  if (opts)
-    {
-      int cur_group = 0;
-
-      /* The first option must not be an alias.  */
-      assert (! oalias (opts));
-
-      /* Calculate the space needed.  */
-      for (o = opts; ! oend (o); o++)
-        {
-          if (! oalias (o))
-            hol->num_entries++;
-          if (oshort (o))
-            num_short_options++;        /* This is an upper bound.  */
-        }
-
-      hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries);
-      hol->short_options = malloc (num_short_options + 1);
-
-      assert (hol->entries && hol->short_options);
-      if (SIZE_MAX <= UINT_MAX)
-        assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry));
-
-      /* Fill in the entries.  */
-      so = hol->short_options;
-      for (o = opts, entry = hol->entries; ! oend (o); entry++)
-        {
-          entry->opt = o;
-          entry->num = 0;
-          entry->short_options = so;
-          entry->group = cur_group =
-            o->group
-            ? o->group
-            : ((!o->name && !o->key)
-               ? cur_group + 1
-               : cur_group);
-          entry->cluster = cluster;
-          entry->argp = argp;
-
-          do
-            {
-              entry->num++;
-              if (oshort (o) && ! find_char (o->key, hol->short_options, so))
-                /* O has a valid short option which hasn't already been used.*/
-                *so++ = o->key;
-              o++;
-            }
-          while (! oend (o) && oalias (o));
-        }
-      *so = '\0';               /* null terminated so we can find the length */
-    }
-
-  return hol;
-}
-\f
-/* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the
-   associated argp child list entry), INDEX, and PARENT, and return a pointer
-   to it.  ARGP is the argp that this cluster results from.  */
-static struct hol_cluster *
-hol_add_cluster (struct hol *hol, int group, const char *header, int index,
-                 struct hol_cluster *parent, const struct argp *argp)
-{
-  struct hol_cluster *cl = malloc (sizeof (struct hol_cluster));
-  if (cl)
-    {
-      cl->group = group;
-      cl->header = header;
-
-      cl->index = index;
-      cl->parent = parent;
-      cl->argp = argp;
-      cl->depth = parent ? parent->depth + 1 : 0;
-
-      cl->next = hol->clusters;
-      hol->clusters = cl;
-    }
-  return cl;
-}
-\f
-/* Free HOL and any resources it uses.  */
-static void
-hol_free (struct hol *hol)
-{
-  struct hol_cluster *cl = hol->clusters;
-
-  while (cl)
-    {
-      struct hol_cluster *next = cl->next;
-      free (cl);
-      cl = next;
-    }
-
-  if (hol->num_entries > 0)
-    {
-      free (hol->entries);
-      free (hol->short_options);
-    }
-
-  free (hol);
-}
-\f
-static int
-hol_entry_short_iterate (const struct hol_entry *entry,
-                         int (*func)(const struct argp_option *opt,
-                                     const struct argp_option *real,
-                                     const char *domain, void *cookie),
-                         const char *domain, void *cookie)
-{
-  unsigned nopts;
-  int val = 0;
-  const struct argp_option *opt, *real = entry->opt;
-  char *so = entry->short_options;
-
-  for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
-    if (oshort (opt) && *so == opt->key)
-      {
-        if (!oalias (opt))
-          real = opt;
-        if (ovisible (opt))
-          val = (*func)(opt, real, domain, cookie);
-        so++;
-      }
-
-  return val;
-}
-
-static inline int
-__attribute__ ((always_inline))
-hol_entry_long_iterate (const struct hol_entry *entry,
-                        int (*func)(const struct argp_option *opt,
-                                    const struct argp_option *real,
-                                    const char *domain, void *cookie),
-                        const char *domain, void *cookie)
-{
-  unsigned nopts;
-  int val = 0;
-  const struct argp_option *opt, *real = entry->opt;
-
-  for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
-    if (opt->name)
-      {
-        if (!oalias (opt))
-          real = opt;
-        if (ovisible (opt))
-          val = (*func)(opt, real, domain, cookie);
-      }
-
-  return val;
-}
-\f
-/* Iterator that returns true for the first short option.  */
-static int
-until_short (const struct argp_option *opt, const struct argp_option *real,
-             const char *domain, void *cookie)
-{
-  return oshort (opt) ? opt->key : 0;
-}
-
-/* Returns the first valid short option in ENTRY, or 0 if there is none.  */
-static char
-hol_entry_first_short (const struct hol_entry *entry)
-{
-  return hol_entry_short_iterate (entry, until_short,
-                                  entry->argp->argp_domain, 0);
-}
-
-/* Returns the first valid long option in ENTRY, or 0 if there is none.  */
-static const char *
-hol_entry_first_long (const struct hol_entry *entry)
-{
-  const struct argp_option *opt;
-  unsigned num;
-  for (opt = entry->opt, num = entry->num; num > 0; opt++, num--)
-    if (opt->name && ovisible (opt))
-      return opt->name;
-  return 0;
-}
-
-/* Returns the entry in HOL with the long option name NAME, or 0 if there is
-   none.  */
-static struct hol_entry *
-hol_find_entry (struct hol *hol, const char *name)
-{
-  struct hol_entry *entry = hol->entries;
-  unsigned num_entries = hol->num_entries;
-
-  while (num_entries-- > 0)
-    {
-      const struct argp_option *opt = entry->opt;
-      unsigned num_opts = entry->num;
-
-      while (num_opts-- > 0)
-        if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0)
-          return entry;
-        else
-          opt++;
-
-      entry++;
-    }
-
-  return 0;
-}
-\f
-/* If an entry with the long option NAME occurs in HOL, set it's special
-   sort position to GROUP.  */
-static void
-hol_set_group (struct hol *hol, const char *name, int group)
-{
-  struct hol_entry *entry = hol_find_entry (hol, name);
-  if (entry)
-    entry->group = group;
-}
-\f
-/* Order by group:  0, 1, 2, ..., n, -m, ..., -2, -1.
-   EQ is what to return if GROUP1 and GROUP2 are the same.  */
-static int
-group_cmp (int group1, int group2, int eq)
-{
-  if (group1 == group2)
-    return eq;
-  else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0))
-    return group1 - group2;
-  else
-    return group2 - group1;
-}
-
-/* Compare clusters CL1 & CL2 by the order that they should appear in
-   output.  */
-static int
-hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
-{
-  /* If one cluster is deeper than the other, use its ancestor at the same
-     level, so that finding the common ancestor is straightforward.
-
-     clN->depth > 0 means that clN->parent != NULL (see hol_add_cluster) */
-  while (cl1->depth > cl2->depth)
-    cl1 = cl1->parent;
-  while (cl2->depth > cl1->depth)
-    cl2 = cl2->parent;
-
-  /* Now reduce both clusters to their ancestors at the point where both have
-     a common parent; these can be directly compared.  */
-  while (cl1->parent != cl2->parent)
-    cl1 = cl1->parent, cl2 = cl2->parent;
-
-  return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index);
-}
-
-/* Return the ancestor of CL that's just below the root (i.e., has a parent
-   of 0).  */
-static struct hol_cluster *
-hol_cluster_base (struct hol_cluster *cl)
-{
-  while (cl->parent)
-    cl = cl->parent;
-  return cl;
-}
-
-/* Return true if CL1 is a child of CL2.  */
-static int
-hol_cluster_is_child (const struct hol_cluster *cl1,
-                      const struct hol_cluster *cl2)
-{
-  while (cl1 && cl1 != cl2)
-    cl1 = cl1->parent;
-  return cl1 == cl2;
-}
-\f
-/* Given the name of a OPTION_DOC option, modifies NAME to start at the tail
-   that should be used for comparisons, and returns true iff it should be
-   treated as a non-option.  */
-static int
-canon_doc_option (const char **name)
-{
-  int non_opt;
-
-  if (!*name)
-    non_opt = 1;
-  else
-    {
-      /* Skip initial whitespace.  */
-      while (isspace ((unsigned char) **name))
-        (*name)++;
-      /* Decide whether this looks like an option (leading `-') or not.  */
-      non_opt = (**name != '-');
-      /* Skip until part of name used for sorting.  */
-      while (**name && !isalnum ((unsigned char) **name))
-        (*name)++;
-    }
-  return non_opt;
-}
-
-#define HOL_ENTRY_PTRCMP(a,b) ((a)->ord < (b)->ord ? -1 : 1)
-
-/* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
-   listing.  */
-static int
-hol_entry_cmp (const struct hol_entry *entry1,
-               const struct hol_entry *entry2)
-{
-  /* The group numbers by which the entries should be ordered; if either is
-     in a cluster, then this is just the group within the cluster.  */
-  int group1 = entry1->group, group2 = entry2->group;
-  int rc;
-
-  if (entry1->cluster != entry2->cluster)
-    {
-      /* The entries are not within the same cluster, so we can't compare them
-         directly, we have to use the appropiate clustering level too.  */
-      if (! entry1->cluster)
-        /* ENTRY1 is at the `base level', not in a cluster, so we have to
-           compare it's group number with that of the base cluster in which
-           ENTRY2 resides.  Note that if they're in the same group, the
-           clustered option always comes laster.  */
-        return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1);
-      else if (! entry2->cluster)
-        /* Likewise, but ENTRY2's not in a cluster.  */
-        return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
-      else
-        /* Both entries are in clusters, we can just compare the clusters.  */
-        return (rc = hol_cluster_cmp (entry1->cluster, entry2->cluster)) ?
-               rc : HOL_ENTRY_PTRCMP (entry1, entry2);
-    }
-  else if (group1 == group2)
-    /* The entries are both in the same cluster and group, so compare them
-       alphabetically.  */
-    {
-      int short1 = hol_entry_first_short (entry1);
-      int short2 = hol_entry_first_short (entry2);
-      int doc1 = odoc (entry1->opt);
-      int doc2 = odoc (entry2->opt);
-      const char *long1 = hol_entry_first_long (entry1);
-      const char *long2 = hol_entry_first_long (entry2);
-
-      if (doc1)
-        doc1 = canon_doc_option (&long1);
-      if (doc2)
-        doc2 = canon_doc_option (&long2);
-
-      if (doc1 != doc2)
-        /* `documentation' options always follow normal options (or
-           documentation options that *look* like normal options).  */
-        return doc1 - doc2;
-      else if (!short1 && !short2 && long1 && long2)
-        /* Only long options.  */
-        return (rc = __strcasecmp (long1, long2)) ?
-               rc : HOL_ENTRY_PTRCMP (entry1, entry2);
-      else
-        /* Compare short/short, long/short, short/long, using the first
-           character of long options.  Entries without *any* valid
-           options (such as options with OPTION_HIDDEN set) will be put
-           first, but as they're not displayed, it doesn't matter where
-           they are.  */
-        {
-          unsigned char first1 = short1 ? short1 : long1 ? *long1 : 0;
-          unsigned char first2 = short2 ? short2 : long2 ? *long2 : 0;
-          /* Use tolower, not _tolower, since only the former is
-             guaranteed to work on something already lower case.  */
-          int lower_cmp = tolower (first1) - tolower (first2);
-          /* Compare ignoring case, except when the options are both the
-             same letter, in which case lower-case always comes first.  */
-          return lower_cmp ? lower_cmp :
-                 (rc = first2 - first1) ?
-                 rc : HOL_ENTRY_PTRCMP (entry1, entry2);
-        }
-    }
-  else
-    /* Within the same cluster, but not the same group, so just compare
-       groups.  */
-    return group_cmp (group1, group2, HOL_ENTRY_PTRCMP (entry1, entry2));
-}
-
-/* Version of hol_entry_cmp with correct signature for qsort.  */
-static int
-hol_entry_qcmp (const void *entry1_v, const void *entry2_v)
-{
-  return hol_entry_cmp (entry1_v, entry2_v);
-}
-
-/* Sort HOL by group and alphabetically by option name (with short options
-   taking precedence over long).  Since the sorting is for display purposes
-   only, the shadowing of options isn't effected.  */
-static void
-hol_sort (struct hol *hol)
-{
-  if (hol->num_entries > 0)
-    {
-      unsigned i;
-      struct hol_entry *e;
-      for (i = 0, e = hol->entries; i < hol->num_entries; i++, e++)
-        e->ord = i;
-      qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
-             hol_entry_qcmp);
-    }
-}
-\f
-/* Append MORE to HOL, destroying MORE in the process.  Options in HOL shadow
-   any in MORE with the same name.  */
-static void
-hol_append (struct hol *hol, struct hol *more)
-{
-  struct hol_cluster **cl_end = &hol->clusters;
-
-  /* Steal MORE's cluster list, and add it to the end of HOL's.  */
-  while (*cl_end)
-    cl_end = &(*cl_end)->next;
-  *cl_end = more->clusters;
-  more->clusters = 0;
-
-  /* Merge entries.  */
-  if (more->num_entries > 0)
-    {
-      if (hol->num_entries == 0)
-        {
-          hol->num_entries = more->num_entries;
-          hol->entries = more->entries;
-          hol->short_options = more->short_options;
-          more->num_entries = 0;        /* Mark MORE's fields as invalid.  */
-        }
-      else
-        /* Append the entries in MORE to those in HOL, taking care to only add
-           non-shadowed SHORT_OPTIONS values.  */
-        {
-          unsigned left;
-          char *so, *more_so;
-          struct hol_entry *e;
-          unsigned num_entries = hol->num_entries + more->num_entries;
-          struct hol_entry *entries =
-            malloc (num_entries * sizeof (struct hol_entry));
-          unsigned hol_so_len = strlen (hol->short_options);
-          char *short_options =
-            malloc (hol_so_len + strlen (more->short_options) + 1);
-
-          assert (entries && short_options);
-          if (SIZE_MAX <= UINT_MAX)
-            assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry));
-
-          __mempcpy (__mempcpy (entries, hol->entries,
-                                hol->num_entries * sizeof (struct hol_entry)),
-                     more->entries,
-                     more->num_entries * sizeof (struct hol_entry));
-
-          __mempcpy (short_options, hol->short_options, hol_so_len);
-
-          /* Fix up the short options pointers from HOL.  */
-          for (e = entries, left = hol->num_entries; left > 0; e++, left--)
-            e->short_options += (short_options - hol->short_options);
-
-          /* Now add the short options from MORE, fixing up its entries
-             too.  */
-          so = short_options + hol_so_len;
-          more_so = more->short_options;
-          for (left = more->num_entries; left > 0; e++, left--)
-            {
-              int opts_left;
-              const struct argp_option *opt;
-
-              e->short_options = so;
-
-              for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--)
-                {
-                  int ch = *more_so;
-                  if (oshort (opt) && ch == opt->key)
-                    /* The next short option in MORE_SO, CH, is from OPT.  */
-                    {
-                      if (! find_char (ch, short_options,
-                                       short_options + hol_so_len))
-                        /* The short option CH isn't shadowed by HOL's options,
-                           so add it to the sum.  */
-                        *so++ = ch;
-                      more_so++;
-                    }
-                }
-            }
-
-          *so = '\0';
-
-          free (hol->entries);
-          free (hol->short_options);
-
-          hol->entries = entries;
-          hol->num_entries = num_entries;
-          hol->short_options = short_options;
-        }
-    }
-
-  hol_free (more);
-}
-\f
-/* Inserts enough spaces to make sure STREAM is at column COL.  */
-static void
-indent_to (argp_fmtstream_t stream, unsigned col)
-{
-  int needed = col - __argp_fmtstream_point (stream);
-  while (needed-- > 0)
-    __argp_fmtstream_putc (stream, ' ');
-}
-
-/* Output to STREAM either a space, or a newline if there isn't room for at
-   least ENSURE characters before the right margin.  */
-static void
-space (argp_fmtstream_t stream, size_t ensure)
-{
-  if (__argp_fmtstream_point (stream) + ensure
-      >= __argp_fmtstream_rmargin (stream))
-    __argp_fmtstream_putc (stream, '\n');
-  else
-    __argp_fmtstream_putc (stream, ' ');
-}
-
-/* If the option REAL has an argument, we print it in using the printf
-   format REQ_FMT or OPT_FMT depending on whether it's a required or
-   optional argument.  */
-static void
-arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
-     const char *domain, argp_fmtstream_t stream)
-{
-  if (real->arg)
-    {
-      if (real->flags & OPTION_ARG_OPTIONAL)
-        __argp_fmtstream_printf (stream, opt_fmt,
-                                 dgettext (domain, real->arg));
-      else
-        __argp_fmtstream_printf (stream, req_fmt,
-                                 dgettext (domain, real->arg));
-    }
-}
-\f
-/* Helper functions for hol_entry_help.  */
-
-/* State used during the execution of hol_help.  */
-struct hol_help_state
-{
-  /* PREV_ENTRY should contain the previous entry printed, or 0.  */
-  struct hol_entry *prev_entry;
-
-  /* If an entry is in a different group from the previous one, and SEP_GROUPS
-     is true, then a blank line will be printed before any output. */
-  int sep_groups;
-
-  /* True if a duplicate option argument was suppressed (only ever set if
-     UPARAMS.dup_args is false).  */
-  int suppressed_dup_arg;
-};
-
-/* Some state used while printing a help entry (used to communicate with
-   helper functions).  See the doc for hol_entry_help for more info, as most
-   of the fields are copied from its arguments.  */
-struct pentry_state
-{
-  const struct hol_entry *entry;
-  argp_fmtstream_t stream;
-  struct hol_help_state *hhstate;
-
-  /* True if nothing's been printed so far.  */
-  int first;
-
-  /* If non-zero, the state that was used to print this help.  */
-  const struct argp_state *state;
-};
-
-/* If a user doc filter should be applied to DOC, do so.  */
-static const char *
-filter_doc (const char *doc, int key, const struct argp *argp,
-            const struct argp_state *state)
-{
-  if (argp->help_filter)
-    /* We must apply a user filter to this output.  */
-    {
-      void *input = __argp_input (argp, state);
-      return (*argp->help_filter) (key, doc, input);
-    }
-  else
-    /* No filter.  */
-    return doc;
-}
-
-/* Prints STR as a header line, with the margin lines set appropiately, and
-   notes the fact that groups should be separated with a blank line.  ARGP is
-   the argp that should dictate any user doc filtering to take place.  Note
-   that the previous wrap margin isn't restored, but the left margin is reset
-   to 0.  */
-static void
-print_header (const char *str, const struct argp *argp,
-              struct pentry_state *pest)
-{
-  const char *tstr = dgettext (argp->argp_domain, str);
-  const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state);
-
-  if (fstr)
-    {
-      if (*fstr)
-        {
-          if (pest->hhstate->prev_entry)
-            /* Precede with a blank line.  */
-            __argp_fmtstream_putc (pest->stream, '\n');
-          indent_to (pest->stream, uparams.header_col);
-          __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col);
-          __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col);
-          __argp_fmtstream_puts (pest->stream, fstr);
-          __argp_fmtstream_set_lmargin (pest->stream, 0);
-          __argp_fmtstream_putc (pest->stream, '\n');
-        }
-
-      pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */
-    }
-
-  if (fstr != tstr)
-    free ((char *) fstr);
-}
-
-/* Inserts a comma if this isn't the first item on the line, and then makes
-   sure we're at least to column COL.  If this *is* the first item on a line,
-   prints any pending whitespace/headers that should precede this line. Also
-   clears FIRST.  */
-static void
-comma (unsigned col, struct pentry_state *pest)
-{
-  if (pest->first)
-    {
-      const struct hol_entry *pe = pest->hhstate->prev_entry;
-      const struct hol_cluster *cl = pest->entry->cluster;
-
-      if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group)
-        __argp_fmtstream_putc (pest->stream, '\n');
-
-      if (cl && cl->header && *cl->header
-          && (!pe
-              || (pe->cluster != cl
-                  && !hol_cluster_is_child (pe->cluster, cl))))
-        /* If we're changing clusters, then this must be the start of the
-           ENTRY's cluster unless that is an ancestor of the previous one
-           (in which case we had just popped into a sub-cluster for a bit).
-           If so, then print the cluster's header line.  */
-        {
-          int old_wm = __argp_fmtstream_wmargin (pest->stream);
-          print_header (cl->header, cl->argp, pest);
-          __argp_fmtstream_set_wmargin (pest->stream, old_wm);
-        }
-
-      pest->first = 0;
-    }
-  else
-    __argp_fmtstream_puts (pest->stream, ", ");
-
-  indent_to (pest->stream, col);
-}
-\f
-/* Print help for ENTRY to STREAM.  */
-static void
-hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
-                argp_fmtstream_t stream, struct hol_help_state *hhstate)
-{
-  unsigned num;
-  const struct argp_option *real = entry->opt, *opt;
-  char *so = entry->short_options;
-  int have_long_opt = 0;        /* We have any long options.  */
-  /* Saved margins.  */
-  int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
-  int old_wm = __argp_fmtstream_wmargin (stream);
-  /* PEST is a state block holding some of our variables that we'd like to
-     share with helper functions.  */
-  struct pentry_state pest;
-
-  pest.entry = entry;
-  pest.stream = stream;
-  pest.hhstate = hhstate;
-  pest.first = 1;
-  pest.state = state;
-
-  if (! odoc (real))
-    for (opt = real, num = entry->num; num > 0; opt++, num--)
-      if (opt->name && ovisible (opt))
-        {
-          have_long_opt = 1;
-          break;
-        }
-
-  /* First emit short options.  */
-  __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */
-  for (opt = real, num = entry->num; num > 0; opt++, num--)
-    if (oshort (opt) && opt->key == *so)
-      /* OPT has a valid (non shadowed) short option.  */
-      {
-        if (ovisible (opt))
-          {
-            comma (uparams.short_opt_col, &pest);
-            __argp_fmtstream_putc (stream, '-');
-            __argp_fmtstream_putc (stream, *so);
-            if (!have_long_opt || uparams.dup_args)
-              arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream);
-            else if (real->arg)
-              hhstate->suppressed_dup_arg = 1;
-          }
-        so++;
-      }
-
-  /* Now, long options.  */
-  if (odoc (real))
-    /* A `documentation' option.  */
-    {
-      __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
-      for (opt = real, num = entry->num; num > 0; opt++, num--)
-        if (opt->name && *opt->name && ovisible (opt))
-          {
-            comma (uparams.doc_opt_col, &pest);
-            /* Calling dgettext here isn't quite right, since sorting will
-               have been done on the original; but documentation options
-               should be pretty rare anyway...  */
-            __argp_fmtstream_puts (stream,
-                                   onotrans (opt) ?
-                                             opt->name :
-                                   dgettext (state->root_argp->argp_domain,
-                                             opt->name));
-          }
-    }
-  else
-    /* A real long option.  */
-    {
-      int first_long_opt = 1;
-
-      __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
-      for (opt = real, num = entry->num; num > 0; opt++, num--)
-        if (opt->name && ovisible (opt))
-          {
-            comma (uparams.long_opt_col, &pest);
-            __argp_fmtstream_printf (stream, "--%s", opt->name);
-            if (first_long_opt || uparams.dup_args)
-              arg (real, "=%s", "[=%s]", state->root_argp->argp_domain,
-                   stream);
-            else if (real->arg)
-              hhstate->suppressed_dup_arg = 1;
-          }
-    }
-
-  /* Next, documentation strings.  */
-  __argp_fmtstream_set_lmargin (stream, 0);
-
-  if (pest.first)
-    {
-      /* Didn't print any switches, what's up?  */
-      if (!oshort (real) && !real->name)
-        /* This is a group header, print it nicely.  */
-        print_header (real->doc, entry->argp, &pest);
-      else
-        /* Just a totally shadowed option or null header; print nothing.  */
-        goto cleanup;           /* Just return, after cleaning up.  */
-    }
-  else
-    {
-      const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain,
-                                               real->doc) : 0;
-      const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
-      if (fstr && *fstr)
-        {
-          unsigned int col = __argp_fmtstream_point (stream);
-
-          __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
-          __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);
-
-          if (col > (unsigned int) (uparams.opt_doc_col + 3))
-            __argp_fmtstream_putc (stream, '\n');
-          else if (col >= (unsigned int) uparams.opt_doc_col)
-            __argp_fmtstream_puts (stream, "   ");
-          else
-            indent_to (stream, uparams.opt_doc_col);
-
-          __argp_fmtstream_puts (stream, fstr);
-        }
-      if (fstr && fstr != tstr)
-        free ((char *) fstr);
-
-      /* Reset the left margin.  */
-      __argp_fmtstream_set_lmargin (stream, 0);
-      __argp_fmtstream_putc (stream, '\n');
-    }
-
-  hhstate->prev_entry = entry;
-
-cleanup:
-  __argp_fmtstream_set_lmargin (stream, old_lm);
-  __argp_fmtstream_set_wmargin (stream, old_wm);
-}
-\f
-/* Output a long help message about the options in HOL to STREAM.  */
-static void
-hol_help (struct hol *hol, const struct argp_state *state,
-          argp_fmtstream_t stream)
-{
-  unsigned num;
-  struct hol_entry *entry;
-  struct hol_help_state hhstate = { 0, 0, 0 };
-
-  for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
-    hol_entry_help (entry, state, stream, &hhstate);
-
-  if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
-    {
-      const char *tstr = dgettext (state->root_argp->argp_domain, "\
-Mandatory or optional arguments to long options are also mandatory or \
-optional for any corresponding short options.");
-      const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
-                                     state ? state->root_argp : 0, state);
-      if (fstr && *fstr)
-        {
-          __argp_fmtstream_putc (stream, '\n');
-          __argp_fmtstream_puts (stream, fstr);
-          __argp_fmtstream_putc (stream, '\n');
-        }
-      if (fstr && fstr != tstr)
-        free ((char *) fstr);
-    }
-}
-\f
-/* Helper functions for hol_usage.  */
-
-/* If OPT is a short option without an arg, append its key to the string
-   pointer pointer to by COOKIE, and advance the pointer.  */
-static int
-add_argless_short_opt (const struct argp_option *opt,
-                       const struct argp_option *real,
-                       const char *domain, void *cookie)
-{
-  char **snao_end = cookie;
-  if (!(opt->arg || real->arg)
-      && !((opt->flags | real->flags) & OPTION_NO_USAGE))
-    *(*snao_end)++ = opt->key;
-  return 0;
-}
-
-/* If OPT is a short option with an arg, output a usage entry for it to the
-   stream pointed at by COOKIE.  */
-static int
-usage_argful_short_opt (const struct argp_option *opt,
-                        const struct argp_option *real,
-                        const char *domain, void *cookie)
-{
-  argp_fmtstream_t stream = cookie;
-  const char *arg = opt->arg;
-  int flags = opt->flags | real->flags;
-
-  if (! arg)
-    arg = real->arg;
-
-  if (arg && !(flags & OPTION_NO_USAGE))
-    {
-      arg = dgettext (domain, arg);
-
-      if (flags & OPTION_ARG_OPTIONAL)
-        __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
-      else
-        {
-          /* Manually do line wrapping so that it (probably) won't
-             get wrapped at the embedded space.  */
-          space (stream, 6 + strlen (arg));
-          __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
-        }
-    }
-
-  return 0;
-}
-
-/* Output a usage entry for the long option opt to the stream pointed at by
-   COOKIE.  */
-static int
-usage_long_opt (const struct argp_option *opt,
-                const struct argp_option *real,
-                const char *domain, void *cookie)
-{
-  argp_fmtstream_t stream = cookie;
-  const char *arg = opt->arg;
-  int flags = opt->flags | real->flags;
-
-  if (! arg)
-    arg = real->arg;
-
-  if (! (flags & OPTION_NO_USAGE) && !odoc (opt))
-    {
-      if (arg)
-        {
-          arg = dgettext (domain, arg);
-          if (flags & OPTION_ARG_OPTIONAL)
-            __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
-          else
-            __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
-        }
-      else
-        __argp_fmtstream_printf (stream, " [--%s]", opt->name);
-    }
-
-  return 0;
-}
-\f
-/* Print a short usage description for the arguments in HOL to STREAM.  */
-static void
-hol_usage (struct hol *hol, argp_fmtstream_t stream)
-{
-  if (hol->num_entries > 0)
-    {
-      unsigned nentries;
-      struct hol_entry *entry;
-      char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1);
-      char *snao_end = short_no_arg_opts;
-
-      /* First we put a list of short options without arguments.  */
-      for (entry = hol->entries, nentries = hol->num_entries
-           ; nentries > 0
-           ; entry++, nentries--)
-        hol_entry_short_iterate (entry, add_argless_short_opt,
-                                 entry->argp->argp_domain, &snao_end);
-      if (snao_end > short_no_arg_opts)
-        {
-          *snao_end++ = 0;
-          __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts);
-        }
-
-      /* Now a list of short options *with* arguments.  */
-      for (entry = hol->entries, nentries = hol->num_entries
-           ; nentries > 0
-           ; entry++, nentries--)
-        hol_entry_short_iterate (entry, usage_argful_short_opt,
-                                 entry->argp->argp_domain, stream);
-
-      /* Finally, a list of long options (whew!).  */
-      for (entry = hol->entries, nentries = hol->num_entries
-           ; nentries > 0
-           ; entry++, nentries--)
-        hol_entry_long_iterate (entry, usage_long_opt,
-                                entry->argp->argp_domain, stream);
-    }
-}
-\f
-/* Make a HOL containing all levels of options in ARGP.  CLUSTER is the
-   cluster in which ARGP's entries should be clustered, or 0.  */
-static struct hol *
-argp_hol (const struct argp *argp, struct hol_cluster *cluster)
-{
-  const struct argp_child *child = argp->children;
-  struct hol *hol = make_hol (argp, cluster);
-  if (child)
-    while (child->argp)
-      {
-        struct hol_cluster *child_cluster =
-          ((child->group || child->header)
-           /* Put CHILD->argp within its own cluster.  */
-           ? hol_add_cluster (hol, child->group, child->header,
-                              child - argp->children, cluster, argp)
-           /* Just merge it into the parent's cluster.  */
-           : cluster);
-        hol_append (hol, argp_hol (child->argp, child_cluster)) ;
-        child++;
-      }
-  return hol;
-}
-\f
-/* Calculate how many different levels with alternative args strings exist in
-   ARGP.  */
-static size_t
-argp_args_levels (const struct argp *argp)
-{
-  size_t levels = 0;
-  const struct argp_child *child = argp->children;
-
-  if (argp->args_doc && strchr (argp->args_doc, '\n'))
-    levels++;
-
-  if (child)
-    while (child->argp)
-      levels += argp_args_levels ((child++)->argp);
-
-  return levels;
-}
-
-/* Print all the non-option args documented in ARGP to STREAM.  Any output is
-   preceded by a space.  LEVELS is a pointer to a byte vector the length
-   returned by argp_args_levels; it should be initialized to zero, and
-   updated by this routine for the next call if ADVANCE is true.  True is
-   returned as long as there are more patterns to output.  */
-static int
-argp_args_usage (const struct argp *argp, const struct argp_state *state,
-                 char **levels, int advance, argp_fmtstream_t stream)
-{
-  char *our_level = *levels;
-  int multiple = 0;
-  const struct argp_child *child = argp->children;
-  const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0;
-  const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state);
-
-  if (fdoc)
-    {
-      const char *cp = fdoc;
-      nl = __strchrnul (cp, '\n');
-      if (*nl != '\0')
-        /* This is a `multi-level' args doc; advance to the correct position
-           as determined by our state in LEVELS, and update LEVELS.  */
-        {
-          int i;
-          multiple = 1;
-          for (i = 0; i < *our_level; i++)
-            cp = nl + 1, nl = __strchrnul (cp, '\n');
-          (*levels)++;
-        }
-
-      /* Manually do line wrapping so that it (probably) won't get wrapped at
-         any embedded spaces.  */
-      space (stream, 1 + nl - cp);
-
-      __argp_fmtstream_write (stream, cp, nl - cp);
-    }
-  if (fdoc && fdoc != tdoc)
-    free ((char *)fdoc);        /* Free user's modified doc string.  */
-
-  if (child)
-    while (child->argp)
-      advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream);
-
-  if (advance && multiple)
-    {
-      /* Need to increment our level.  */
-      if (*nl)
-        /* There's more we can do here.  */
-        {
-          (*our_level)++;
-          advance = 0;          /* Our parent shouldn't advance also. */
-        }
-      else if (*our_level > 0)
-        /* We had multiple levels, but used them up; reset to zero.  */
-        *our_level = 0;
-    }
-
-  return !advance;
-}
-\f
-/* Print the documentation for ARGP to STREAM; if POST is false, then
-   everything preceeding a `\v' character in the documentation strings (or
-   the whole string, for those with none) is printed, otherwise, everything
-   following the `\v' character (nothing for strings without).  Each separate
-   bit of documentation is separated a blank line, and if PRE_BLANK is true,
-   then the first is as well.  If FIRST_ONLY is true, only the first
-   occurrence is output.  Returns true if anything was output.  */
-static int
-argp_doc (const struct argp *argp, const struct argp_state *state,
-          int post, int pre_blank, int first_only,
-          argp_fmtstream_t stream)
-{
-  const char *text;
-  const char *inp_text;
-  size_t inp_text_len = 0;
-  const char *trans_text;
-  void *input = 0;
-  int anything = 0;
-  const struct argp_child *child = argp->children;
-
-  if (argp->doc)
-    {
-      char *vt = strchr (argp->doc, '\v');
-      if (vt)
-        {
-          if (post)
-            inp_text = vt + 1;
-          else
-            {
-              inp_text_len = vt - argp->doc;
-              inp_text = __strndup (argp->doc, inp_text_len);
-            }
-        }
-      else
-        inp_text = post ? 0 : argp->doc;
-      trans_text = inp_text ? dgettext (argp->argp_domain, inp_text) : NULL;
-    }
-  else
-    trans_text = inp_text = 0;
-
-  if (argp->help_filter)
-    /* We have to filter the doc strings.  */
-    {
-      input = __argp_input (argp, state);
-      text =
-        (*argp->help_filter) (post
-                              ? ARGP_KEY_HELP_POST_DOC
-                              : ARGP_KEY_HELP_PRE_DOC,
-                              trans_text, input);
-    }
-  else
-    text = (const char *) trans_text;
-
-  if (text)
-    {
-      if (pre_blank)
-        __argp_fmtstream_putc (stream, '\n');
-
-      __argp_fmtstream_puts (stream, text);
-
-      if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
-        __argp_fmtstream_putc (stream, '\n');
-
-      anything = 1;
-    }
-
-  if (text && text != trans_text)
-    free ((char *) text);       /* Free TEXT returned from the help filter.  */
-
-  if (inp_text && inp_text_len)
-    free ((char *) inp_text);   /* We copied INP_TEXT, so free it now.  */
-
-  if (post && argp->help_filter)
-    /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text.  */
-    {
-      text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);
-      if (text)
-        {
-          if (anything || pre_blank)
-            __argp_fmtstream_putc (stream, '\n');
-          __argp_fmtstream_puts (stream, text);
-          free ((char *) text);
-          if (__argp_fmtstream_point (stream)
-              > __argp_fmtstream_lmargin (stream))
-            __argp_fmtstream_putc (stream, '\n');
-          anything = 1;
-        }
-    }
-
-  if (child)
-    while (child->argp && !(first_only && anything))
-      anything |=
-        argp_doc ((child++)->argp, state,
-                  post, anything || pre_blank, first_only,
-                  stream);
-
-  return anything;
-}
-\f
-/* Output a usage message for ARGP to STREAM.  If called from
-   argp_state_help, STATE is the relevent parsing state.  FLAGS are from the
-   set ARGP_HELP_*.  NAME is what to use wherever a `program name' is
-   needed. */
-static void
-_help (const struct argp *argp, const struct argp_state *state, FILE *stream,
-       unsigned flags, char *name)
-{
-  int anything = 0;             /* Whether we've output anything.  */
-  struct hol *hol = 0;
-  argp_fmtstream_t fs;
-
-  if (! stream)
-    return;
-
-#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
-  __flockfile (stream);
-#endif
-
-  if (! uparams.valid)
-    fill_in_uparams (state);
-
-  fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
-  if (! fs)
-    {
-#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
-      __funlockfile (stream);
-#endif
-      return;
-    }
-
-  if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))
-    {
-      hol = argp_hol (argp, 0);
-
-      /* If present, these options always come last.  */
-      hol_set_group (hol, "help", -1);
-      hol_set_group (hol, "version", -1);
-
-      hol_sort (hol);
-    }
-
-  if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))
-    /* Print a short `Usage:' message.  */
-    {
-      int first_pattern = 1, more_patterns;
-      size_t num_pattern_levels = argp_args_levels (argp);
-      char *pattern_levels = alloca (num_pattern_levels);
-
-      memset (pattern_levels, 0, num_pattern_levels);
-
-      do
-        {
-          int old_lm;
-          int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent);
-          char *levels = pattern_levels;
-
-          if (first_pattern)
-            __argp_fmtstream_printf (fs, "%s %s",
-                                     dgettext (argp->argp_domain, "Usage:"),
-                                     name);
-          else
-            __argp_fmtstream_printf (fs, "%s %s",
-                                     dgettext (argp->argp_domain, "  or: "),
-                                     name);
-
-          /* We set the lmargin as well as the wmargin, because hol_usage
-             manually wraps options with newline to avoid annoying breaks.  */
-          old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent);
-
-          if (flags & ARGP_HELP_SHORT_USAGE)
-            /* Just show where the options go.  */
-            {
-              if (hol->num_entries > 0)
-                __argp_fmtstream_puts (fs, dgettext (argp->argp_domain,
-                                                     " [OPTION...]"));
-            }
-          else
-            /* Actually print the options.  */
-            {
-              hol_usage (hol, fs);
-              flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once.  */
-            }
-
-          more_patterns = argp_args_usage (argp, state, &levels, 1, fs);
-
-          __argp_fmtstream_set_wmargin (fs, old_wm);
-          __argp_fmtstream_set_lmargin (fs, old_lm);
-
-          __argp_fmtstream_putc (fs, '\n');
-          anything = 1;
-
-          first_pattern = 0;
-        }
-      while (more_patterns);
-    }
-
-  if (flags & ARGP_HELP_PRE_DOC)
-    anything |= argp_doc (argp, state, 0, 0, 1, fs);
-
-  if (flags & ARGP_HELP_SEE)
-    {
-      __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\
-Try `%s --help' or `%s --usage' for more information.\n"),
-                               name, name);
-      anything = 1;
-    }
-
-  if (flags & ARGP_HELP_LONG)
-    /* Print a long, detailed help message.  */
-    {
-      /* Print info about all the options.  */
-      if (hol->num_entries > 0)
-        {
-          if (anything)
-            __argp_fmtstream_putc (fs, '\n');
-          hol_help (hol, state, fs);
-          anything = 1;
-        }
-    }
-
-  if (flags & ARGP_HELP_POST_DOC)
-    /* Print any documentation strings at the end.  */
-    anything |= argp_doc (argp, state, 1, anything, 0, fs);
-
-  if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
-    {
-      if (anything)
-        __argp_fmtstream_putc (fs, '\n');
-      __argp_fmtstream_printf (fs, dgettext (argp->argp_domain,
-                                             "Report bugs to %s.\n"),
-                               argp_program_bug_address);
-      anything = 1;
-    }
-
-#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
-  __funlockfile (stream);
-#endif
-
-  if (hol)
-    hol_free (hol);
-
-  __argp_fmtstream_free (fs);
-}
-\f
-/* Output a usage message for ARGP to STREAM.  FLAGS are from the set
-   ARGP_HELP_*.  NAME is what to use wherever a `program name' is needed. */
-void __argp_help (const struct argp *argp, FILE *stream,
-                  unsigned flags, char *name)
-{
-  struct argp_state state;
-  memset (&state, 0, sizeof state);
-  state.root_argp = argp;
-  _help (argp, &state, stream, flags, name);
-}
-#ifdef weak_alias
-weak_alias (__argp_help, argp_help)
-#endif
-
-#if ! (defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME)
-char *
-__argp_short_program_name (void)
-{
-# if HAVE_DECL_PROGRAM_INVOCATION_NAME
-  return __argp_base_name (program_invocation_name);
-# else
-  /* FIXME: What now? Miles suggests that it is better to use NULL,
-     but currently the value is passed on directly to fputs_unlocked,
-     so that requires more changes. */
-# if __GNUC__
-#  warning No reasonable value to return
-# endif /* __GNUC__ */
-  return "";
-# endif
-}
-#endif
-
-/* Output, if appropriate, a usage message for STATE to STREAM.  FLAGS are
-   from the set ARGP_HELP_*.  */
-void
-__argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
-{
-  if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
-    {
-      if (state && (state->flags & ARGP_LONG_ONLY))
-        flags |= ARGP_HELP_LONG_ONLY;
-
-      _help (state ? state->root_argp : 0, state, stream, flags,
-             state ? state->name : __argp_short_program_name ());
-
-      if (!state || ! (state->flags & ARGP_NO_EXIT))
-        {
-          if (flags & ARGP_HELP_EXIT_ERR)
-            exit (argp_err_exit_status);
-          if (flags & ARGP_HELP_EXIT_OK)
-            exit (0);
-        }
-  }
-}
-#ifdef weak_alias
-weak_alias (__argp_state_help, argp_state_help)
-#endif
-\f
-/* If appropriate, print the printf string FMT and following args, preceded
-   by the program name and `:', to stderr, and followed by a `Try ... --help'
-   message, then exit (1).  */
-void
-__argp_error (const struct argp_state *state, const char *fmt, ...)
-{
-  if (!state || !(state->flags & ARGP_NO_ERRS))
-    {
-      FILE *stream = state ? state->err_stream : stderr;
-
-      if (stream)
-        {
-          va_list ap;
-
-#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
-          __flockfile (stream);
-#endif
-
-          va_start (ap, fmt);
-
-#ifdef USE_IN_LIBIO
-          if (_IO_fwide (stream, 0) > 0)
-            {
-              char *buf;
-
-              if (__asprintf (&buf, fmt, ap) < 0)
-                buf = NULL;
-
-              __fwprintf (stream, L"%s: %s\n",
-                          state ? state->name : __argp_short_program_name (),
-                          buf);
-
-              free (buf);
-            }
-          else
-#endif
-            {
-              fputs_unlocked (state
-                              ? state->name : __argp_short_program_name (),
-                              stream);
-              putc_unlocked (':', stream);
-              putc_unlocked (' ', stream);
-
-              vfprintf (stream, fmt, ap);
-
-              putc_unlocked ('\n', stream);
-            }
-
-          __argp_state_help (state, stream, ARGP_HELP_STD_ERR);
-
-          va_end (ap);
-
-#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
-          __funlockfile (stream);
-#endif
-        }
-    }
-}
-#ifdef weak_alias
-weak_alias (__argp_error, argp_error)
-#endif
-\f
-/* Similar to the standard gnu error-reporting function error(), but will
-   respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
-   to STATE->err_stream.  This is useful for argument parsing code that is
-   shared between program startup (when exiting is desired) and runtime
-   option parsing (when typically an error code is returned instead).  The
-   difference between this function and argp_error is that the latter is for
-   *parsing errors*, and the former is for other problems that occur during
-   parsing but don't reflect a (syntactic) problem with the input.  */
-void
-__argp_failure (const struct argp_state *state, int status, int errnum,
-                const char *fmt, ...)
-{
-  if (!state || !(state->flags & ARGP_NO_ERRS))
-    {
-      FILE *stream = state ? state->err_stream : stderr;
-
-      if (stream)
-        {
-#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
-          __flockfile (stream);
-#endif
-
-#ifdef USE_IN_LIBIO
-          if (_IO_fwide (stream, 0) > 0)
-            __fwprintf (stream, L"%s",
-                        state ? state->name : __argp_short_program_name ());
-          else
-#endif
-            fputs_unlocked (state
-                            ? state->name : __argp_short_program_name (),
-                            stream);
-
-          if (fmt)
-            {
-              va_list ap;
-
-              va_start (ap, fmt);
-#ifdef USE_IN_LIBIO
-              if (_IO_fwide (stream, 0) > 0)
-                {
-                  char *buf;
-
-                  if (__asprintf (&buf, fmt, ap) < 0)
-                    buf = NULL;
-
-                  __fwprintf (stream, L": %s", buf);
-
-                  free (buf);
-                }
-              else
-#endif
-                {
-                  putc_unlocked (':', stream);
-                  putc_unlocked (' ', stream);
-
-                  vfprintf (stream, fmt, ap);
-                }
-
-              va_end (ap);
-            }
-
-          if (errnum)
-            {
-              char buf[200];
-
-#ifdef USE_IN_LIBIO
-              if (_IO_fwide (stream, 0) > 0)
-                __fwprintf (stream, L": %s",
-                            __strerror_r (errnum, buf, sizeof (buf)));
-              else
-#endif
-                {
-                  char const *s = NULL;
-                  putc_unlocked (':', stream);
-                  putc_unlocked (' ', stream);
-#if _LIBC || (HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P)
-                  s = __strerror_r (errnum, buf, sizeof buf);
-#elif HAVE_DECL_STRERROR_R
-                  if (__strerror_r (errnum, buf, sizeof buf) == 0)
-                    s = buf;
-#endif
-#if !_LIBC
-                  if (! s && ! (s = strerror (errnum)))
-                    s = dgettext (state->root_argp->argp_domain,
-                                  "Unknown system error");
-#endif
-                  fputs (s, stream);
-                }
-            }
-
-#ifdef USE_IN_LIBIO
-          if (_IO_fwide (stream, 0) > 0)
-            putwc_unlocked (L'\n', stream);
-          else
-#endif
-            putc_unlocked ('\n', stream);
-
-#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
-          __funlockfile (stream);
-#endif
-
-          if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
-            exit (status);
-        }
-    }
-}
-#ifdef weak_alias
-weak_alias (__argp_failure, argp_failure)
-#endif
diff --git a/gnulib/argp-namefrob.h b/gnulib/argp-namefrob.h
deleted file mode 100644 (file)
index 24581a6..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/* Name frobnication for compiling argp outside of glibc
-   Copyright (C) 1997, 2003, 2007, 2009, 2010 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#if !_LIBC
-/* This code is written for inclusion in gnu-libc, and uses names in the
-   namespace reserved for libc.  If we're not compiling in libc, define those
-   names to be the normal ones instead.  */
-
-/* argp-parse functions */
-#undef __argp_parse
-#define __argp_parse argp_parse
-#undef __option_is_end
-#define __option_is_end _option_is_end
-#undef __option_is_short
-#define __option_is_short _option_is_short
-#undef __argp_input
-#define __argp_input _argp_input
-
-/* argp-help functions */
-#undef __argp_help
-#define __argp_help argp_help
-#undef __argp_error
-#define __argp_error argp_error
-#undef __argp_failure
-#define __argp_failure argp_failure
-#undef __argp_state_help
-#define __argp_state_help argp_state_help
-#undef __argp_usage
-#define __argp_usage argp_usage
-
-/* argp-fmtstream functions */
-#undef __argp_make_fmtstream
-#define __argp_make_fmtstream argp_make_fmtstream
-#undef __argp_fmtstream_free
-#define __argp_fmtstream_free argp_fmtstream_free
-#undef __argp_fmtstream_putc
-#define __argp_fmtstream_putc argp_fmtstream_putc
-#undef __argp_fmtstream_puts
-#define __argp_fmtstream_puts argp_fmtstream_puts
-#undef __argp_fmtstream_write
-#define __argp_fmtstream_write argp_fmtstream_write
-#undef __argp_fmtstream_printf
-#define __argp_fmtstream_printf argp_fmtstream_printf
-#undef __argp_fmtstream_set_lmargin
-#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
-#undef __argp_fmtstream_set_rmargin
-#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
-#undef __argp_fmtstream_set_wmargin
-#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
-#undef __argp_fmtstream_point
-#define __argp_fmtstream_point argp_fmtstream_point
-#undef __argp_fmtstream_update
-#define __argp_fmtstream_update _argp_fmtstream_update
-#undef __argp_fmtstream_ensure
-#define __argp_fmtstream_ensure _argp_fmtstream_ensure
-#undef __argp_fmtstream_lmargin
-#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
-#undef __argp_fmtstream_rmargin
-#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
-#undef __argp_fmtstream_wmargin
-#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
-
-/* normal libc functions we call */
-#undef __flockfile
-#define __flockfile flockfile
-#undef __funlockfile
-#define __funlockfile funlockfile
-#undef __mempcpy
-#define __mempcpy mempcpy
-#undef __sleep
-#define __sleep sleep
-#undef __strcasecmp
-#define __strcasecmp strcasecmp
-#undef __strchrnul
-#define __strchrnul strchrnul
-#undef __strerror_r
-#define __strerror_r strerror_r
-#undef __strndup
-#define __strndup strndup
-#undef __vsnprintf
-#define __vsnprintf vsnprintf
-
-#if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED
-# define clearerr_unlocked(x) clearerr (x)
-#endif
-#if defined(HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED
-# define feof_unlocked(x) feof (x)
-# endif
-#if defined(HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED
-# define ferror_unlocked(x) ferror (x)
-# endif
-#if defined(HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED
-# define fflush_unlocked(x) fflush (x)
-# endif
-#if defined(HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED
-# define fgets_unlocked(x,y,z) fgets (x,y,z)
-# endif
-#if defined(HAVE_DECL_FPUTC_UNLOCKED) && !HAVE_DECL_FPUTC_UNLOCKED
-# define fputc_unlocked(x,y) fputc (x,y)
-# endif
-#if defined(HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED
-# define fputs_unlocked(x,y) fputs (x,y)
-# endif
-#if defined(HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED
-# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
-# endif
-#if defined(HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED
-# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
-# endif
-#if defined(HAVE_DECL_GETC_UNLOCKED) && !HAVE_DECL_GETC_UNLOCKED
-# define getc_unlocked(x) getc (x)
-# endif
-#if defined(HAVE_DECL_GETCHAR_UNLOCKED) && !HAVE_DECL_GETCHAR_UNLOCKED
-#  define getchar_unlocked() getchar ()
-# endif
-#if defined(HAVE_DECL_PUTC_UNLOCKED) && !HAVE_DECL_PUTC_UNLOCKED
-# define putc_unlocked(x,y) putc (x,y)
-# endif
-#if defined(HAVE_DECL_PUTCHAR_UNLOCKED) && !HAVE_DECL_PUTCHAR_UNLOCKED
-# define putchar_unlocked(x) putchar (x)
-# endif
-
-#endif /* !_LIBC */
-
-#ifndef __set_errno
-#define __set_errno(e) (errno = (e))
-#endif
-
-#if defined GNULIB_ARGP_DISABLE_DIRNAME
-# define __argp_base_name(arg) arg
-#elif defined GNULIB_ARGP_EXTERN_BASENAME
-extern char *__argp_base_name (const char *arg);
-#else
-# include "dirname.h"
-# define __argp_base_name last_component
-#endif
-
-#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
-# define __argp_short_program_name()    (program_invocation_short_name)
-#else
-extern char *__argp_short_program_name (void);
-#endif
diff --git a/gnulib/argp-parse.c b/gnulib/argp-parse.c
deleted file mode 100644 (file)
index a1cbf88..0000000
+++ /dev/null
@@ -1,952 +0,0 @@
-/* Hierarchial argument parsing, layered over getopt
-   Copyright (C) 1995-2000, 2002-2004, 2009-2010 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <alloca.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <limits.h>
-#include <getopt.h>
-#include <getopt_int.h>
-
-#ifdef _LIBC
-# include <libintl.h>
-# undef dgettext
-# define dgettext(domain, msgid) \
-   INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
-#else
-# include "gettext.h"
-#endif
-#define N_(msgid) msgid
-
-#include "argp.h"
-#include "argp-namefrob.h"
-
-#define alignof(type) offsetof (struct { char c; type x; }, x)
-#define alignto(n, d) ((((n) + (d) - 1) / (d)) * (d))
-
-/* Getopt return values.  */
-#define KEY_END (-1)            /* The end of the options.  */
-#define KEY_ARG 1               /* A non-option argument.  */
-#define KEY_ERR '?'             /* An error parsing the options.  */
-
-/* The meta-argument used to prevent any further arguments being interpreted
-   as options.  */
-#define QUOTE "--"
-
-/* The number of bits we steal in a long-option value for our own use.  */
-#define GROUP_BITS CHAR_BIT
-
-/* The number of bits available for the user value.  */
-#define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS)
-#define USER_MASK ((1 << USER_BITS) - 1)
-
-/* EZ alias for ARGP_ERR_UNKNOWN.  */
-#define EBADKEY ARGP_ERR_UNKNOWN
-\f
-/* Default options.  */
-
-/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep
-   for one second intervals, decrementing _ARGP_HANG until it's zero.  Thus
-   you can force the program to continue by attaching a debugger and setting
-   it to 0 yourself.  */
-static volatile int _argp_hang;
-
-#define OPT_PROGNAME    -2
-#define OPT_USAGE       -3
-#define OPT_HANG        -4
-
-static const struct argp_option argp_default_options[] =
-{
-  {"help",        '?',          0, 0,  N_("give this help list"), -1},
-  {"usage",       OPT_USAGE,    0, 0,  N_("give a short usage message"), 0},
-  {"program-name",OPT_PROGNAME,N_("NAME"), OPTION_HIDDEN, N_("set the program name"), 0},
-  {"HANG",        OPT_HANG,    N_("SECS"), OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
-     N_("hang for SECS seconds (default 3600)"), 0},
-  {NULL, 0, 0, 0, NULL, 0}
-};
-
-static error_t
-argp_default_parser (int key, char *arg, struct argp_state *state)
-{
-  switch (key)
-    {
-    case '?':
-      __argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
-      break;
-    case OPT_USAGE:
-      __argp_state_help (state, state->out_stream,
-                         ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
-      break;
-
-    case OPT_PROGNAME:          /* Set the program name.  */
-#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME
-      program_invocation_name = arg;
-#endif
-      /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka
-         __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined
-         to be that, so we have to be a bit careful here.]  */
-
-      /* Update what we use for messages.  */
-      state->name = __argp_base_name (arg);
-
-#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
-      program_invocation_short_name = state->name;
-#endif
-
-      if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS))
-          == ARGP_PARSE_ARGV0)
-        /* Update what getopt uses too.  */
-        state->argv[0] = arg;
-
-      break;
-
-    case OPT_HANG:
-      _argp_hang = atoi (arg ? arg : "3600");
-      while (_argp_hang-- > 0)
-        __sleep (1);
-      break;
-
-    default:
-      return EBADKEY;
-    }
-  return 0;
-}
-
-static const struct argp argp_default_argp =
-  {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"};
-
-\f
-static const struct argp_option argp_version_options[] =
-{
-  {"version",     'V',          0, 0,  N_("print program version"), -1},
-  {NULL, 0, 0, 0, NULL, 0}
-};
-
-static error_t
-argp_version_parser (int key, char *arg, struct argp_state *state)
-{
-  switch (key)
-    {
-    case 'V':
-      if (argp_program_version_hook)
-        (*argp_program_version_hook) (state->out_stream, state);
-      else if (argp_program_version)
-        fprintf (state->out_stream, "%s\n", argp_program_version);
-      else
-        __argp_error (state, dgettext (state->root_argp->argp_domain,
-                                       "(PROGRAM ERROR) No version known!?"));
-      if (! (state->flags & ARGP_NO_EXIT))
-        exit (0);
-      break;
-    default:
-      return EBADKEY;
-    }
-  return 0;
-}
-
-static const struct argp argp_version_argp =
-  {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"};
-\f
-/* Returns the offset into the getopt long options array LONG_OPTIONS of a
-   long option with called NAME, or -1 if none is found.  Passing NULL as
-   NAME will return the number of options.  */
-static int
-find_long_option (struct option *long_options, const char *name)
-{
-  struct option *l = long_options;
-  while (l->name != NULL)
-    if (name != NULL && strcmp (l->name, name) == 0)
-      return l - long_options;
-    else
-      l++;
-  if (name == NULL)
-    return l - long_options;
-  else
-    return -1;
-}
-
-\f
-/* The state of a `group' during parsing.  Each group corresponds to a
-   particular argp structure from the tree of such descending from the top
-   level argp passed to argp_parse.  */
-struct group
-{
-  /* This group's parsing function.  */
-  argp_parser_t parser;
-
-  /* Which argp this group is from.  */
-  const struct argp *argp;
-
-  /* Points to the point in SHORT_OPTS corresponding to the end of the short
-     options for this group.  We use it to determine from which group a
-     particular short options is from.  */
-  char *short_end;
-
-  /* The number of non-option args sucessfully handled by this parser.  */
-  unsigned args_processed;
-
-  /* This group's parser's parent's group.  */
-  struct group *parent;
-  unsigned parent_index;        /* And the our position in the parent.   */
-
-  /* These fields are swapped into and out of the state structure when
-     calling this group's parser.  */
-  void *input, **child_inputs;
-  void *hook;
-};
-
-/* Call GROUP's parser with KEY and ARG, swapping any group-specific info
-   from STATE before calling, and back into state afterwards.  If GROUP has
-   no parser, EBADKEY is returned.  */
-static error_t
-group_parse (struct group *group, struct argp_state *state, int key, char *arg)
-{
-  if (group->parser)
-    {
-      error_t err;
-      state->hook = group->hook;
-      state->input = group->input;
-      state->child_inputs = group->child_inputs;
-      state->arg_num = group->args_processed;
-      err = (*group->parser)(key, arg, state);
-      group->hook = state->hook;
-      return err;
-    }
-  else
-    return EBADKEY;
-}
-\f
-struct parser
-{
-  const struct argp *argp;
-
-  /* SHORT_OPTS is the getopt short options string for the union of all the
-     groups of options.  */
-  char *short_opts;
-  /* LONG_OPTS is the array of getop long option structures for the union of
-     all the groups of options.  */
-  struct option *long_opts;
-  /* OPT_DATA is the getopt data used for the re-entrant getopt.  */
-  struct _getopt_data opt_data;
-
-  /* States of the various parsing groups.  */
-  struct group *groups;
-  /* The end of the GROUPS array.  */
-  struct group *egroup;
-  /* An vector containing storage for the CHILD_INPUTS field in all groups.  */
-  void **child_inputs;
-
-  /* True if we think using getopt is still useful; if false, then
-     remaining arguments are just passed verbatim with ARGP_KEY_ARG.  This is
-     cleared whenever getopt returns KEY_END, but may be set again if the user
-     moves the next argument pointer backwards.  */
-  int try_getopt;
-
-  /* State block supplied to parsing routines.  */
-  struct argp_state state;
-
-  /* Memory used by this parser.  */
-  void *storage;
-};
-\f
-/* The next usable entries in the various parser tables being filled in by
-   convert_options.  */
-struct parser_convert_state
-{
-  struct parser *parser;
-  char *short_end;
-  struct option *long_end;
-  void **child_inputs_end;
-};
-
-/* Converts all options in ARGP (which is put in GROUP) and ancestors
-   into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and
-   CVT->LONG_END are the points at which new options are added.  Returns the
-   next unused group entry.  CVT holds state used during the conversion.  */
-static struct group *
-convert_options (const struct argp *argp,
-                 struct group *parent, unsigned parent_index,
-                 struct group *group, struct parser_convert_state *cvt)
-{
-  /* REAL is the most recent non-alias value of OPT.  */
-  const struct argp_option *real = argp->options;
-  const struct argp_child *children = argp->children;
-
-  if (real || argp->parser)
-    {
-      const struct argp_option *opt;
-
-      if (real)
-        for (opt = real; !__option_is_end (opt); opt++)
-          {
-            if (! (opt->flags & OPTION_ALIAS))
-              /* OPT isn't an alias, so we can use values from it.  */
-              real = opt;
-
-            if (! (real->flags & OPTION_DOC))
-              /* A real option (not just documentation).  */
-              {
-                if (__option_is_short (opt))
-                  /* OPT can be used as a short option.  */
-                  {
-                    *cvt->short_end++ = opt->key;
-                    if (real->arg)
-                      {
-                        *cvt->short_end++ = ':';
-                        if (real->flags & OPTION_ARG_OPTIONAL)
-                          *cvt->short_end++ = ':';
-                      }
-                    *cvt->short_end = '\0'; /* keep 0 terminated */
-                  }
-
-                if (opt->name
-                    && find_long_option (cvt->parser->long_opts, opt->name) < 0)
-                  /* OPT can be used as a long option.  */
-                  {
-                    cvt->long_end->name = opt->name;
-                    cvt->long_end->has_arg =
-                      (real->arg
-                       ? (real->flags & OPTION_ARG_OPTIONAL
-                          ? optional_argument
-                          : required_argument)
-                       : no_argument);
-                    cvt->long_end->flag = 0;
-                    /* we add a disambiguating code to all the user's
-                       values (which is removed before we actually call
-                       the function to parse the value); this means that
-                       the user loses use of the high 8 bits in all his
-                       values (the sign of the lower bits is preserved
-                       however)...  */
-                    cvt->long_end->val =
-                      ((opt->key ? opt->key : real->key) & USER_MASK)
-                      + (((group - cvt->parser->groups) + 1) << USER_BITS);
-
-                    /* Keep the LONG_OPTS list terminated.  */
-                    (++cvt->long_end)->name = NULL;
-                  }
-              }
-            }
-
-      group->parser = argp->parser;
-      group->argp = argp;
-      group->short_end = cvt->short_end;
-      group->args_processed = 0;
-      group->parent = parent;
-      group->parent_index = parent_index;
-      group->input = 0;
-      group->hook = 0;
-      group->child_inputs = 0;
-
-      if (children)
-        /* Assign GROUP's CHILD_INPUTS field some space from
-           CVT->child_inputs_end.*/
-        {
-          unsigned num_children = 0;
-          while (children[num_children].argp)
-            num_children++;
-          group->child_inputs = cvt->child_inputs_end;
-          cvt->child_inputs_end += num_children;
-        }
-
-      parent = group++;
-    }
-  else
-    parent = 0;
-
-  if (children)
-    {
-      unsigned index = 0;
-      while (children->argp)
-        group =
-          convert_options (children++->argp, parent, index++, group, cvt);
-    }
-
-  return group;
-}
-
-/* Find the merged set of getopt options, with keys appropiately prefixed. */
-static void
-parser_convert (struct parser *parser, const struct argp *argp, int flags)
-{
-  struct parser_convert_state cvt;
-
-  cvt.parser = parser;
-  cvt.short_end = parser->short_opts;
-  cvt.long_end = parser->long_opts;
-  cvt.child_inputs_end = parser->child_inputs;
-
-  if (flags & ARGP_IN_ORDER)
-    *cvt.short_end++ = '-';
-  else if (flags & ARGP_NO_ARGS)
-    *cvt.short_end++ = '+';
-  *cvt.short_end = '\0';
-
-  cvt.long_end->name = NULL;
-
-  parser->argp = argp;
-
-  if (argp)
-    parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt);
-  else
-    parser->egroup = parser->groups; /* No parsers at all! */
-}
-\f
-/* Lengths of various parser fields which we will allocated.  */
-struct parser_sizes
-{
-  size_t short_len;             /* Getopt short options string.  */
-  size_t long_len;              /* Getopt long options vector.  */
-  size_t num_groups;            /* Group structures we allocate.  */
-  size_t num_child_inputs;      /* Child input slots.  */
-};
-
-/* For ARGP, increments the NUM_GROUPS field in SZS by the total number of
- argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by
- the maximum lengths of the resulting merged getopt short options string and
- long-options array, respectively.  */
-static void
-calc_sizes (const struct argp *argp,  struct parser_sizes *szs)
-{
-  const struct argp_child *child = argp->children;
-  const struct argp_option *opt = argp->options;
-
-  if (opt || argp->parser)
-    {
-      szs->num_groups++;
-      if (opt)
-        {
-          int num_opts = 0;
-          while (!__option_is_end (opt++))
-            num_opts++;
-          szs->short_len += num_opts * 3; /* opt + up to 2 `:'s */
-          szs->long_len += num_opts;
-        }
-    }
-
-  if (child)
-    while (child->argp)
-      {
-        calc_sizes ((child++)->argp, szs);
-        szs->num_child_inputs++;
-      }
-}
-
-/* Initializes PARSER to parse ARGP in a manner described by FLAGS.  */
-static error_t
-parser_init (struct parser *parser, const struct argp *argp,
-             int argc, char **argv, int flags, void *input)
-{
-  error_t err = 0;
-  struct group *group;
-  struct parser_sizes szs;
-  struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER;
-  char *storage;
-  size_t glen, gsum;
-  size_t clen, csum;
-  size_t llen, lsum;
-  size_t slen, ssum;
-
-  szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1;
-  szs.long_len = 0;
-  szs.num_groups = 0;
-  szs.num_child_inputs = 0;
-
-  if (argp)
-    calc_sizes (argp, &szs);
-
-  /* Lengths of the various bits of storage used by PARSER.  */
-  glen = (szs.num_groups + 1) * sizeof (struct group);
-  clen = szs.num_child_inputs * sizeof (void *);
-  llen = (szs.long_len + 1) * sizeof (struct option);
-  slen = szs.short_len + 1;
-
-  /* Sums of previous lengths, properly aligned.  There's no need to
-     align gsum, since struct group is aligned at least as strictly as
-     void * (since it contains a void * member).  And there's no need
-     to align lsum, since struct option is aligned at least as
-     strictly as char.  */
-  gsum = glen;
-  csum = alignto (gsum + clen, alignof (struct option));
-  lsum = csum + llen;
-  ssum = lsum + slen;
-
-  parser->storage = malloc (ssum);
-  if (! parser->storage)
-    return ENOMEM;
-
-  storage = parser->storage;
-  parser->groups = parser->storage;
-  parser->child_inputs = (void **) (storage + gsum);
-  parser->long_opts = (struct option *) (storage + csum);
-  parser->short_opts = storage + lsum;
-  parser->opt_data = opt_data;
-
-  memset (parser->child_inputs, 0, clen);
-  parser_convert (parser, argp, flags);
-
-  memset (&parser->state, 0, sizeof (struct argp_state));
-  parser->state.root_argp = parser->argp;
-  parser->state.argc = argc;
-  parser->state.argv = argv;
-  parser->state.flags = flags;
-  parser->state.err_stream = stderr;
-  parser->state.out_stream = stdout;
-  parser->state.next = 0;       /* Tell getopt to initialize.  */
-  parser->state.pstate = parser;
-
-  parser->try_getopt = 1;
-
-  /* Call each parser for the first time, giving it a chance to propagate
-     values to child parsers.  */
-  if (parser->groups < parser->egroup)
-    parser->groups->input = input;
-  for (group = parser->groups;
-       group < parser->egroup && (!err || err == EBADKEY);
-       group++)
-    {
-      if (group->parent)
-        /* If a child parser, get the initial input value from the parent. */
-        group->input = group->parent->child_inputs[group->parent_index];
-
-      if (!group->parser
-          && group->argp->children && group->argp->children->argp)
-        /* For the special case where no parsing function is supplied for an
-           argp, propagate its input to its first child, if any (this just
-           makes very simple wrapper argps more convenient).  */
-        group->child_inputs[0] = group->input;
-
-      err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0);
-    }
-  if (err == EBADKEY)
-    err = 0;                    /* Some parser didn't understand.  */
-
-  if (err)
-    return err;
-
-  if (parser->state.flags & ARGP_NO_ERRS)
-    {
-      parser->opt_data.opterr = 0;
-      if (parser->state.flags & ARGP_PARSE_ARGV0)
-        /* getopt always skips ARGV[0], so we have to fake it out.  As long
-           as OPTERR is 0, then it shouldn't actually try to access it.  */
-        parser->state.argv--, parser->state.argc++;
-    }
-  else
-    parser->opt_data.opterr = 1;        /* Print error messages.  */
-
-  if (parser->state.argv == argv && argv[0])
-    /* There's an argv[0]; use it for messages.  */
-    parser->state.name = __argp_base_name (argv[0]);
-  else
-    parser->state.name = __argp_short_program_name ();
-
-  return 0;
-}
-\f
-/* Free any storage consumed by PARSER (but not PARSER itself).  */
-static error_t
-parser_finalize (struct parser *parser,
-                 error_t err, int arg_ebadkey, int *end_index)
-{
-  struct group *group;
-
-  if (err == EBADKEY && arg_ebadkey)
-    /* Suppress errors generated by unparsed arguments.  */
-    err = 0;
-
-  if (! err)
-    {
-      if (parser->state.next == parser->state.argc)
-        /* We successfully parsed all arguments!  Call all the parsers again,
-           just a few more times... */
-        {
-          for (group = parser->groups;
-               group < parser->egroup && (!err || err==EBADKEY);
-               group++)
-            if (group->args_processed == 0)
-              err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0);
-          for (group = parser->egroup - 1;
-               group >= parser->groups && (!err || err==EBADKEY);
-               group--)
-            err = group_parse (group, &parser->state, ARGP_KEY_END, 0);
-
-          if (err == EBADKEY)
-            err = 0;            /* Some parser didn't understand.  */
-
-          /* Tell the user that all arguments are parsed.  */
-          if (end_index)
-            *end_index = parser->state.next;
-        }
-      else if (end_index)
-        /* Return any remaining arguments to the user.  */
-        *end_index = parser->state.next;
-      else
-        /* No way to return the remaining arguments, they must be bogus. */
-        {
-          if (!(parser->state.flags & ARGP_NO_ERRS)
-              && parser->state.err_stream)
-            fprintf (parser->state.err_stream,
-                     dgettext (parser->argp->argp_domain,
-                               "%s: Too many arguments\n"),
-                     parser->state.name);
-          err = EBADKEY;
-        }
-    }
-
-  /* Okay, we're all done, with either an error or success; call the parsers
-     to indicate which one.  */
-
-  if (err)
-    {
-      /* Maybe print an error message.  */
-      if (err == EBADKEY)
-        /* An appropriate message describing what the error was should have
-           been printed earlier.  */
-        __argp_state_help (&parser->state, parser->state.err_stream,
-                           ARGP_HELP_STD_ERR);
-
-      /* Since we didn't exit, give each parser an error indication.  */
-      for (group = parser->groups; group < parser->egroup; group++)
-        group_parse (group, &parser->state, ARGP_KEY_ERROR, 0);
-    }
-  else
-    /* Notify parsers of success, and propagate back values from parsers.  */
-    {
-      /* We pass over the groups in reverse order so that child groups are
-         given a chance to do there processing before passing back a value to
-         the parent.  */
-      for (group = parser->egroup - 1
-           ; group >= parser->groups && (!err || err == EBADKEY)
-           ; group--)
-        err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0);
-      if (err == EBADKEY)
-        err = 0;                /* Some parser didn't understand.  */
-    }
-
-  /* Call parsers once more, to do any final cleanup.  Errors are ignored.  */
-  for (group = parser->egroup - 1; group >= parser->groups; group--)
-    group_parse (group, &parser->state, ARGP_KEY_FINI, 0);
-
-  if (err == EBADKEY)
-    err = EINVAL;
-
-  free (parser->storage);
-
-  return err;
-}
-\f
-/* Call the user parsers to parse the non-option argument VAL, at the current
-   position, returning any error.  The state NEXT pointer is assumed to have
-   been adjusted (by getopt) to point after this argument; this function will
-   adjust it correctly to reflect however many args actually end up being
-   consumed.  */
-static error_t
-parser_parse_arg (struct parser *parser, char *val)
-{
-  /* Save the starting value of NEXT, first adjusting it so that the arg
-     we're parsing is again the front of the arg vector.  */
-  int index = --parser->state.next;
-  error_t err = EBADKEY;
-  struct group *group;
-  int key = 0;                  /* Which of ARGP_KEY_ARG[S] we used.  */
-
-  /* Try to parse the argument in each parser.  */
-  for (group = parser->groups
-       ; group < parser->egroup && err == EBADKEY
-       ; group++)
-    {
-      parser->state.next++;     /* For ARGP_KEY_ARG, consume the arg.  */
-      key = ARGP_KEY_ARG;
-      err = group_parse (group, &parser->state, key, val);
-
-      if (err == EBADKEY)
-        /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */
-        {
-          parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg.  */
-          key = ARGP_KEY_ARGS;
-          err = group_parse (group, &parser->state, key, 0);
-        }
-    }
-
-  if (! err)
-    {
-      if (key == ARGP_KEY_ARGS)
-        /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't
-           changed by the user, *all* arguments should be considered
-           consumed.  */
-        parser->state.next = parser->state.argc;
-
-      if (parser->state.next > index)
-        /* Remember that we successfully processed a non-option
-           argument -- but only if the user hasn't gotten tricky and set
-           the clock back.  */
-        (--group)->args_processed += (parser->state.next - index);
-      else
-        /* The user wants to reparse some args, give getopt another try.  */
-        parser->try_getopt = 1;
-    }
-
-  return err;
-}
-\f
-/* Call the user parsers to parse the option OPT, with argument VAL, at the
-   current position, returning any error.  */
-static error_t
-parser_parse_opt (struct parser *parser, int opt, char *val)
-{
-  /* The group key encoded in the high bits; 0 for short opts or
-     group_number + 1 for long opts.  */
-  int group_key = opt >> USER_BITS;
-  error_t err = EBADKEY;
-
-  if (group_key == 0)
-    /* A short option.  By comparing OPT's position in SHORT_OPTS to the
-       various starting positions in each group's SHORT_END field, we can
-       determine which group OPT came from.  */
-    {
-      struct group *group;
-      char *short_index = strchr (parser->short_opts, opt);
-
-      if (short_index)
-        for (group = parser->groups; group < parser->egroup; group++)
-          if (group->short_end > short_index)
-            {
-              err = group_parse (group, &parser->state, opt,
-                                 parser->opt_data.optarg);
-              break;
-            }
-    }
-  else
-    /* A long option.  We use shifts instead of masking for extracting
-       the user value in order to preserve the sign.  */
-    err =
-      group_parse (&parser->groups[group_key - 1], &parser->state,
-                   (opt << GROUP_BITS) >> GROUP_BITS,
-                   parser->opt_data.optarg);
-
-  if (err == EBADKEY)
-    /* At least currently, an option not recognized is an error in the
-       parser, because we pre-compute which parser is supposed to deal
-       with each option.  */
-    {
-      static const char bad_key_err[] =
-        N_("(PROGRAM ERROR) Option should have been recognized!?");
-      if (group_key == 0)
-        __argp_error (&parser->state, "-%c: %s", opt,
-                      dgettext (parser->argp->argp_domain, bad_key_err));
-      else
-        {
-          struct option *long_opt = parser->long_opts;
-          while (long_opt->val != opt && long_opt->name)
-            long_opt++;
-          __argp_error (&parser->state, "--%s: %s",
-                        long_opt->name ? long_opt->name : "???",
-                        dgettext (parser->argp->argp_domain, bad_key_err));
-        }
-    }
-
-  return err;
-}
-\f
-/* Parse the next argument in PARSER (as indicated by PARSER->state.next).
-   Any error from the parsers is returned, and *ARGP_EBADKEY indicates
-   whether a value of EBADKEY is due to an unrecognized argument (which is
-   generally not fatal).  */
-static error_t
-parser_parse_next (struct parser *parser, int *arg_ebadkey)
-{
-  int opt;
-  error_t err = 0;
-
-  if (parser->state.quoted && parser->state.next < parser->state.quoted)
-    /* The next argument pointer has been moved to before the quoted
-       region, so pretend we never saw the quoting `--', and give getopt
-       another chance.  If the user hasn't removed it, getopt will just
-       process it again.  */
-    parser->state.quoted = 0;
-
-  if (parser->try_getopt && !parser->state.quoted)
-    /* Give getopt a chance to parse this.  */
-    {
-      /* Put it back in OPTIND for getopt.  */
-      parser->opt_data.optind = parser->state.next;
-      /* Distinguish KEY_ERR from a real option.  */
-      parser->opt_data.optopt = KEY_END;
-      if (parser->state.flags & ARGP_LONG_ONLY)
-        opt = _getopt_long_only_r (parser->state.argc, parser->state.argv,
-                                   parser->short_opts, parser->long_opts, 0,
-                                   &parser->opt_data);
-      else
-        opt = _getopt_long_r (parser->state.argc, parser->state.argv,
-                              parser->short_opts, parser->long_opts, 0,
-                              &parser->opt_data);
-      /* And see what getopt did.  */
-      parser->state.next = parser->opt_data.optind;
-
-      if (opt == KEY_END)
-        /* Getopt says there are no more options, so stop using
-           getopt; we'll continue if necessary on our own.  */
-        {
-          parser->try_getopt = 0;
-          if (parser->state.next > 1
-              && strcmp (parser->state.argv[parser->state.next - 1], QUOTE)
-                   == 0)
-            /* Not only is this the end of the options, but it's a
-               `quoted' region, which may have args that *look* like
-               options, so we definitely shouldn't try to use getopt past
-               here, whatever happens.  */
-            parser->state.quoted = parser->state.next;
-        }
-      else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END)
-        /* KEY_ERR can have the same value as a valid user short
-           option, but in the case of a real error, getopt sets OPTOPT
-           to the offending character, which can never be KEY_END.  */
-        {
-          *arg_ebadkey = 0;
-          return EBADKEY;
-        }
-    }
-  else
-    opt = KEY_END;
-
-  if (opt == KEY_END)
-    {
-      /* We're past what getopt considers the options.  */
-      if (parser->state.next >= parser->state.argc
-          || (parser->state.flags & ARGP_NO_ARGS))
-        /* Indicate that we're done.  */
-        {
-          *arg_ebadkey = 1;
-          return EBADKEY;
-        }
-      else
-        /* A non-option arg; simulate what getopt might have done.  */
-        {
-          opt = KEY_ARG;
-          parser->opt_data.optarg = parser->state.argv[parser->state.next++];
-        }
-    }
-
-  if (opt == KEY_ARG)
-    /* A non-option argument; try each parser in turn.  */
-    err = parser_parse_arg (parser, parser->opt_data.optarg);
-  else
-    err = parser_parse_opt (parser, opt, parser->opt_data.optarg);
-
-  if (err == EBADKEY)
-    *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG);
-
-  return err;
-}
-\f
-/* Parse the options strings in ARGC & ARGV according to the argp in ARGP.
-   FLAGS is one of the ARGP_ flags above.  If END_INDEX is non-NULL, the
-   index in ARGV of the first unparsed option is returned in it.  If an
-   unknown option is present, EINVAL is returned; if some parser routine
-   returned a non-zero value, it is returned; otherwise 0 is returned.  */
-error_t
-__argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags,
-              int *end_index, void *input)
-{
-  error_t err;
-  struct parser parser;
-
-  /* If true, then err == EBADKEY is a result of a non-option argument failing
-     to be parsed (which in some cases isn't actually an error).  */
-  int arg_ebadkey = 0;
-
-#ifndef _LIBC
-  if (!(flags & ARGP_PARSE_ARGV0))
-    {
-#ifdef HAVE_DECL_PROGRAM_INVOCATION_NAME
-      if (!program_invocation_name)
-        program_invocation_name = argv[0];
-#endif
-#ifdef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
-      if (!program_invocation_short_name)
-        program_invocation_short_name = __argp_base_name (argv[0]);
-#endif
-    }
-#endif
-
-  if (! (flags & ARGP_NO_HELP))
-    /* Add our own options.  */
-    {
-      struct argp_child *child = alloca (4 * sizeof (struct argp_child));
-      struct argp *top_argp = alloca (sizeof (struct argp));
-
-      /* TOP_ARGP has no options, it just serves to group the user & default
-         argps.  */
-      memset (top_argp, 0, sizeof (*top_argp));
-      top_argp->children = child;
-
-      memset (child, 0, 4 * sizeof (struct argp_child));
-
-      if (argp)
-        (child++)->argp = argp;
-      (child++)->argp = &argp_default_argp;
-      if (argp_program_version || argp_program_version_hook)
-        (child++)->argp = &argp_version_argp;
-      child->argp = 0;
-
-      argp = top_argp;
-    }
-
-  /* Construct a parser for these arguments.  */
-  err = parser_init (&parser, argp, argc, argv, flags, input);
-
-  if (! err)
-    /* Parse! */
-    {
-      while (! err)
-        err = parser_parse_next (&parser, &arg_ebadkey);
-      err = parser_finalize (&parser, err, arg_ebadkey, end_index);
-    }
-
-  return err;
-}
-#ifdef weak_alias
-weak_alias (__argp_parse, argp_parse)
-#endif
-\f
-/* Return the input field for ARGP in the parser corresponding to STATE; used
-   by the help routines.  */
-void *
-__argp_input (const struct argp *argp, const struct argp_state *state)
-{
-  if (state)
-    {
-      struct group *group;
-      struct parser *parser = state->pstate;
-
-      for (group = parser->groups; group < parser->egroup; group++)
-        if (group->argp == argp)
-          return group->input;
-    }
-
-  return 0;
-}
-#ifdef weak_alias
-weak_alias (__argp_input, _argp_input)
-#endif
diff --git a/gnulib/argp-pin.c b/gnulib/argp-pin.c
deleted file mode 100644 (file)
index eda4d95..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Full and short program names for argp module
-   Copyright (C) 2005, 2009, 2010 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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME
-char *program_invocation_short_name = 0;
-#endif
-#ifndef HAVE_PROGRAM_INVOCATION_NAME
-char *program_invocation_name = 0;
-#endif
-
diff --git a/gnulib/argp-pv.c b/gnulib/argp-pv.c
deleted file mode 100644 (file)
index e3227d3..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Default definition for ARGP_PROGRAM_VERSION.
-   Copyright (C) 1996, 1997, 1999, 2006, 2009, 2010 Free Software Foundation,
-   Inc.
-   This file is part of the GNU C Library.
-   Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-/* If set by the user program to a non-zero value, then a default option
-   --version is added (unless the ARGP_NO_HELP flag is used), which will
-   print this string followed by a newline and exit (unless the
-   ARGP_NO_EXIT flag is used).  Overridden by ARGP_PROGRAM_VERSION_HOOK.  */
-const char *argp_program_version
-/* This variable should be zero-initialized.  On most systems, putting it into
-   BSS is sufficient.  Not so on MacOS X 10.3 and 10.4, see
-   <http://lists.gnu.org/archive/html/bug-gnulib/2009-01/msg00329.html>
-   <http://lists.gnu.org/archive/html/bug-gnulib/2009-08/msg00096.html>.  */
-#if defined __ELF__
-  /* On ELF systems, variables in BSS behave well.  */
-#else
-  = (const char *) 0
-#endif
-  ;
diff --git a/gnulib/argp-pvh.c b/gnulib/argp-pvh.c
deleted file mode 100644 (file)
index fb98fc2..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Default definition for ARGP_PROGRAM_VERSION_HOOK.
-   Copyright (C) 1996, 1997, 1999, 2004, 2009, 2010 Free Software Foundation,
-   Inc.
-   This file is part of the GNU C Library.
-   Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "argp.h"
-
-/* If set by the user program to a non-zero value, then a default option
-   --version is added (unless the ARGP_NO_HELP flag is used), which calls
-   this function with a stream to print the version to and a pointer to the
-   current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
-   used).  This variable takes precedent over ARGP_PROGRAM_VERSION.  */
-void (*argp_program_version_hook) (FILE *stream, struct argp_state *state) = NULL;
diff --git a/gnulib/argp-version-etc.c b/gnulib/argp-version-etc.c
deleted file mode 100644 (file)
index f500a8f..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Version hook for Argp.
-   Copyright (C) 2009, 2010 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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#include <config.h>
-#include <version-etc.h>
-#include <argp.h>
-#include <argp-version-etc.h>
-
-static const char *program_canonical_name;
-static const char * const *program_authors;
-
-static void
-version_etc_hook (FILE *stream, struct argp_state *state)
-{
-  version_etc_ar (stream, program_canonical_name, PACKAGE_NAME, VERSION,
-                  program_authors);
-}
-
-void
-argp_version_setup (const char *name, const char * const *authors)
-{
-  argp_program_version_hook = version_etc_hook;
-  program_canonical_name = name;
-  program_authors = authors;
-}
diff --git a/gnulib/argp-version-etc.h b/gnulib/argp-version-etc.h
deleted file mode 100644 (file)
index 7c12c01..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Version hook for Argp.
-   Copyright (C) 2009, 2010 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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef _ARGP_VERSION_ETC_H
-#define _ARGP_VERSION_ETC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Setup standard display of the version information for the `--version'
-   option.  NAME is the canonical program name, and AUTHORS is a NULL-
-   terminated array of author names. At least one author name must be
-   given.
-
-   If NAME is NULL, the package name (as given by the PACKAGE macro)
-   is asumed to be the name of the program.
-
-   This function is intended to be called before argp_parse().
-*/
-extern void argp_version_setup (const char *name, const char * const *authors);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ARGP_VERSION_ETC_H */
diff --git a/gnulib/argp-xinl.c b/gnulib/argp-xinl.c
deleted file mode 100644 (file)
index 6e7e20b..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Real definitions for extern inline functions in argp.h
-   Copyright (C) 1997, 1998, 2004, 2009, 2010 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if defined _LIBC || defined HAVE_FEATURES_H
-# include <features.h>
-#endif
-
-#ifndef __USE_EXTERN_INLINES
-# define __USE_EXTERN_INLINES   1
-#endif
-#define ARGP_EI
-#undef __OPTIMIZE__
-#define __OPTIMIZE__ 1
-#include "argp.h"
-
-/* Add weak aliases.  */
-#if _LIBC - 0 && defined (weak_alias)
-
-weak_alias (__argp_usage, argp_usage)
-weak_alias (__option_is_short, _option_is_short)
-weak_alias (__option_is_end, _option_is_end)
-
-#endif
diff --git a/gnulib/argp.h b/gnulib/argp.h
deleted file mode 100644 (file)
index 3667224..0000000
+++ /dev/null
@@ -1,645 +0,0 @@
-/* Hierarchial argument parsing, layered over getopt.
-   Copyright (C) 1995-1999, 2003-2010 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Written by Miles Bader <miles@gnu.ai.mit.edu>.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef _ARGP_H
-#define _ARGP_H
-
-#include <stdio.h>
-#include <ctype.h>
-#include <getopt.h>
-#include <limits.h>
-
-#define __need_error_t
-#include <errno.h>
-
-#ifndef __THROW
-# define __THROW
-#endif
-#ifndef __NTH
-# define __NTH(fct) fct __THROW
-#endif
-
-#ifndef __attribute__
-/* The __attribute__ feature is available in gcc versions 2.5 and later.
-   The __-protected variants of the attributes 'format' and 'printf' are
-   accepted by gcc versions 2.6.4 (effectively 2.7) and later.
-   We enable __attribute__ only if these are supported too, because
-   gnulib and libintl do '#define printf __printf__' when they override
-   the 'printf' function.  */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
-#  define __attribute__(Spec)   /* empty */
-# endif
-#endif
-
-/* GCC 2.95 and later have "__restrict"; C99 compilers have
-   "restrict", and "configure" may have defined "restrict".
-   Other compilers use __restrict, __restrict__, and _Restrict, and
-   'configure' might #define 'restrict' to those words.  */
-#ifndef __restrict
-# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
-#  if 199901L <= __STDC_VERSION__
-#   define __restrict restrict
-#  else
-#   define __restrict
-#  endif
-# endif
-#endif
-
-#ifndef __error_t_defined
-typedef int error_t;
-# define __error_t_defined
-#endif
-\f
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-/* A description of a particular option.  A pointer to an array of
-   these is passed in the OPTIONS field of an argp structure.  Each option
-   entry can correspond to one long option and/or one short option; more
-   names for the same option can be added by following an entry in an option
-   array with options having the OPTION_ALIAS flag set.  */
-struct argp_option
-{
-  /* The long option name.  For more than one name for the same option, you
-     can use following options with the OPTION_ALIAS flag set.  */
-  const char *name;
-
-  /* What key is returned for this option.  If > 0 and printable, then it's
-     also accepted as a short option.  */
-  int key;
-
-  /* If non-NULL, this is the name of the argument associated with this
-     option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */
-  const char *arg;
-
-  /* OPTION_ flags.  */
-  int flags;
-
-  /* The doc string for this option.  If both NAME and KEY are 0, This string
-     will be printed outdented from the normal option column, making it
-     useful as a group header (it will be the first thing printed in its
-     group); in this usage, it's conventional to end the string with a `:'.
-
-     Write the initial value as N_("TEXT") if you want xgettext to collect
-     it into a POT file.  */
-  const char *doc;
-
-  /* The group this option is in.  In a long help message, options are sorted
-     alphabetically within each group, and the groups presented in the order
-     0, 1, 2, ..., n, -m, ..., -2, -1.  Every entry in an options array with
-     if this field 0 will inherit the group number of the previous entry, or
-     zero if it's the first one, unless its a group header (NAME and KEY both
-     0), in which case, the previous entry + 1 is the default.  Automagic
-     options such as --help are put into group -1.  */
-  int group;
-};
-
-/* The argument associated with this option is optional.  */
-#define OPTION_ARG_OPTIONAL     0x1
-
-/* This option isn't displayed in any help messages.  */
-#define OPTION_HIDDEN           0x2
-
-/* This option is an alias for the closest previous non-alias option.  This
-   means that it will be displayed in the same help entry, and will inherit
-   fields other than NAME and KEY from the aliased option.  */
-#define OPTION_ALIAS            0x4
-
-/* This option isn't actually an option (and so should be ignored by the
-   actual option parser), but rather an arbitrary piece of documentation that
-   should be displayed in much the same manner as the options.  If this flag
-   is set, then the option NAME field is displayed unmodified (e.g., no `--'
-   prefix is added) at the left-margin (where a *short* option would normally
-   be displayed), and the documentation string in the normal place. The NAME
-   field will be translated using gettext, unless OPTION_NO_TRANS is set (see
-   below). For purposes of sorting, any leading whitespace and punctuation is
-   ignored, except that if the first non-whitespace character is not `-', this
-   entry is displayed after all options (and OPTION_DOC entries with a leading
-   `-') in the same group.  */
-#define OPTION_DOC              0x8
-
-/* This option shouldn't be included in `long' usage messages (but is still
-   included in help messages).  This is mainly intended for options that are
-   completely documented in an argp's ARGS_DOC field, in which case including
-   the option in the generic usage list would be redundant.  For instance,
-   if ARGS_DOC is "FOO BAR\n-x BLAH", and the `-x' option's purpose is to
-   distinguish these two cases, -x should probably be marked
-   OPTION_NO_USAGE.  */
-#define OPTION_NO_USAGE         0x10
-
-/* Valid only in conjunction with OPTION_DOC. This option disables translation
-   of option name. */
-#define OPTION_NO_TRANS         0x20
-
-\f
-struct argp;                    /* fwd declare this type */
-struct argp_state;              /* " */
-struct argp_child;              /* " */
-
-/* The type of a pointer to an argp parsing function.  */
-typedef error_t (*argp_parser_t) (int key, char *arg,
-                                  struct argp_state *state);
-
-/* What to return for unrecognized keys.  For special ARGP_KEY_ keys, such
-   returns will simply be ignored.  For user keys, this error will be turned
-   into EINVAL (if the call to argp_parse is such that errors are propagated
-   back to the user instead of exiting); returning EINVAL itself would result
-   in an immediate stop to parsing in *all* cases.  */
-#define ARGP_ERR_UNKNOWN        E2BIG /* Hurd should never need E2BIG.  XXX */
-
-/* Special values for the KEY argument to an argument parsing function.
-   ARGP_ERR_UNKNOWN should be returned if they aren't understood.
-
-   The sequence of keys to a parsing function is either (where each
-   uppercased word should be prefixed by `ARGP_KEY_' and opt is a user key):
-
-       INIT opt... NO_ARGS END SUCCESS  -- No non-option arguments at all
-   or  INIT (opt | ARG)... END SUCCESS  -- All non-option args parsed
-   or  INIT (opt | ARG)... SUCCESS      -- Some non-option arg unrecognized
-
-   The third case is where every parser returned ARGP_KEY_UNKNOWN for an
-   argument, in which case parsing stops at that argument (returning the
-   unparsed arguments to the caller of argp_parse if requested, or stopping
-   with an error message if not).
-
-   If an error occurs (either detected by argp, or because the parsing
-   function returned an error value), then the parser is called with
-   ARGP_KEY_ERROR, and no further calls are made.  */
-
-/* This is not an option at all, but rather a command line argument.  If a
-   parser receiving this key returns success, the fact is recorded, and the
-   ARGP_KEY_NO_ARGS case won't be used.  HOWEVER, if while processing the
-   argument, a parser function decrements the NEXT field of the state it's
-   passed, the option won't be considered processed; this is to allow you to
-   actually modify the argument (perhaps into an option), and have it
-   processed again.  */
-#define ARGP_KEY_ARG            0
-/* There are remaining arguments not parsed by any parser, which may be found
-   starting at (STATE->argv + STATE->next).  If success is returned, but
-   STATE->next left untouched, it's assumed that all arguments were consume,
-   otherwise, the parser should adjust STATE->next to reflect any arguments
-   consumed.  */
-#define ARGP_KEY_ARGS           0x1000006
-/* There are no more command line arguments at all.  */
-#define ARGP_KEY_END            0x1000001
-/* Because it's common to want to do some special processing if there aren't
-   any non-option args, user parsers are called with this key if they didn't
-   successfully process any non-option arguments.  Called just before
-   ARGP_KEY_END (where more general validity checks on previously parsed
-   arguments can take place).  */
-#define ARGP_KEY_NO_ARGS        0x1000002
-/* Passed in before any parsing is done.  Afterwards, the values of each
-   element of the CHILD_INPUT field, if any, in the state structure is
-   copied to each child's state to be the initial value of the INPUT field.  */
-#define ARGP_KEY_INIT           0x1000003
-/* Use after all other keys, including SUCCESS & END.  */
-#define ARGP_KEY_FINI           0x1000007
-/* Passed in when parsing has successfully been completed (even if there are
-   still arguments remaining).  */
-#define ARGP_KEY_SUCCESS        0x1000004
-/* Passed in if an error occurs.  */
-#define ARGP_KEY_ERROR          0x1000005
-
-/* An argp structure contains a set of options declarations, a function to
-   deal with parsing one, documentation string, a possible vector of child
-   argp's, and perhaps a function to filter help output.  When actually
-   parsing options, getopt is called with the union of all the argp
-   structures chained together through their CHILD pointers, with conflicts
-   being resolved in favor of the first occurrence in the chain.  */
-struct argp
-{
-  /* An array of argp_option structures, terminated by an entry with both
-     NAME and KEY having a value of 0.  */
-  const struct argp_option *options;
-
-  /* What to do with an option from this structure.  KEY is the key
-     associated with the option, and ARG is any associated argument (NULL if
-     none was supplied).  If KEY isn't understood, ARGP_ERR_UNKNOWN should be
-     returned.  If a non-zero, non-ARGP_ERR_UNKNOWN value is returned, then
-     parsing is stopped immediately, and that value is returned from
-     argp_parse().  For special (non-user-supplied) values of KEY, see the
-     ARGP_KEY_ definitions below.  */
-  argp_parser_t parser;
-
-  /* A string describing what other arguments are wanted by this program.  It
-     is only used by argp_usage to print the `Usage:' message.  If it
-     contains newlines, the strings separated by them are considered
-     alternative usage patterns, and printed on separate lines (lines after
-     the first are prefix by `  or: ' instead of `Usage:').  */
-  const char *args_doc;
-
-  /* If non-NULL, a string containing extra text to be printed before and
-     after the options in a long help message (separated by a vertical tab
-     `\v' character).
-     Write the initial value as N_("BEFORE-TEXT") "\v" N_("AFTER-TEXT") if
-     you want xgettext to collect the two pieces of text into a POT file.  */
-  const char *doc;
-
-  /* A vector of argp_children structures, terminated by a member with a 0
-     argp field, pointing to child argps should be parsed with this one.  Any
-     conflicts are resolved in favor of this argp, or early argps in the
-     CHILDREN list.  This field is useful if you use libraries that supply
-     their own argp structure, which you want to use in conjunction with your
-     own.  */
-  const struct argp_child *children;
-
-  /* If non-zero, this should be a function to filter the output of help
-     messages.  KEY is either a key from an option, in which case TEXT is
-     that option's help text, or a special key from the ARGP_KEY_HELP_
-     defines, below, describing which other help text TEXT is.  The function
-     should return either TEXT, if it should be used as-is, a replacement
-     string, which should be malloced, and will be freed by argp, or NULL,
-     meaning `print nothing'.  The value for TEXT is *after* any translation
-     has been done, so if any of the replacement text also needs translation,
-     that should be done by the filter function.  INPUT is either the input
-     supplied to argp_parse, or NULL, if argp_help was called directly.  */
-  char *(*help_filter) (int __key, const char *__text, void *__input);
-
-  /* If non-zero the strings used in the argp library are translated using
-     the domain described by this string.  Otherwise the currently installed
-     default domain is used.  */
-  const char *argp_domain;
-};
-
-/* Possible KEY arguments to a help filter function.  */
-#define ARGP_KEY_HELP_PRE_DOC   0x2000001 /* Help text preceeding options. */
-#define ARGP_KEY_HELP_POST_DOC  0x2000002 /* Help text following options. */
-#define ARGP_KEY_HELP_HEADER    0x2000003 /* Option header string. */
-#define ARGP_KEY_HELP_EXTRA     0x2000004 /* After all other documentation;
-                                             TEXT is NULL for this key.  */
-/* Explanatory note emitted when duplicate option arguments have been
-   suppressed.  */
-#define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005
-#define ARGP_KEY_HELP_ARGS_DOC  0x2000006 /* Argument doc string.  */
-\f
-/* When an argp has a non-zero CHILDREN field, it should point to a vector of
-   argp_child structures, each of which describes a subsidiary argp.  */
-struct argp_child
-{
-  /* The child parser.  */
-  const struct argp *argp;
-
-  /* Flags for this child.  */
-  int flags;
-
-  /* If non-zero, an optional header to be printed in help output before the
-     child options.  As a side-effect, a non-zero value forces the child
-     options to be grouped together; to achieve this effect without actually
-     printing a header string, use a value of "".  */
-  const char *header;
-
-  /* Where to group the child options relative to the other (`consolidated')
-     options in the parent argp; the values are the same as the GROUP field
-     in argp_option structs, but all child-groupings follow parent options at
-     a particular group level.  If both this field and HEADER are zero, then
-     they aren't grouped at all, but rather merged with the parent options
-     (merging the child's grouping levels with the parents).  */
-  int group;
-};
-\f
-/* Parsing state.  This is provided to parsing functions called by argp,
-   which may examine and, as noted, modify fields.  */
-struct argp_state
-{
-  /* The top level ARGP being parsed.  */
-  const struct argp *root_argp;
-
-  /* The argument vector being parsed.  May be modified.  */
-  int argc;
-  char **argv;
-
-  /* The index in ARGV of the next arg that to be parsed.  May be modified. */
-  int next;
-
-  /* The flags supplied to argp_parse.  May be modified.  */
-  unsigned flags;
-
-  /* While calling a parsing function with a key of ARGP_KEY_ARG, this is the
-     number of the current arg, starting at zero, and incremented after each
-     such call returns.  At all other times, this is the number of such
-     arguments that have been processed.  */
-  unsigned arg_num;
-
-  /* If non-zero, the index in ARGV of the first argument following a special
-     `--' argument (which prevents anything following being interpreted as an
-     option).  Only set once argument parsing has proceeded past this point. */
-  int quoted;
-
-  /* An arbitrary pointer passed in from the user.  */
-  void *input;
-  /* Values to pass to child parsers.  This vector will be the same length as
-     the number of children for the current parser.  */
-  void **child_inputs;
-
-  /* For the parser's use.  Initialized to 0.  */
-  void *hook;
-
-  /* The name used when printing messages.  This is initialized to ARGV[0],
-     or PROGRAM_INVOCATION_NAME if that is unavailable.  */
-  char *name;
-
-  /* Streams used when argp prints something.  */
-  FILE *err_stream;             /* For errors; initialized to stderr. */
-  FILE *out_stream;             /* For information; initialized to stdout. */
-
-  void *pstate;                 /* Private, for use by argp.  */
-};
-\f
-/* Flags for argp_parse (note that the defaults are those that are
-   convenient for program command line parsing): */
-
-/* Don't ignore the first element of ARGV.  Normally (and always unless
-   ARGP_NO_ERRS is set) the first element of the argument vector is
-   skipped for option parsing purposes, as it corresponds to the program name
-   in a command line.  */
-#define ARGP_PARSE_ARGV0  0x01
-
-/* Don't print error messages for unknown options to stderr; unless this flag
-   is set, ARGP_PARSE_ARGV0 is ignored, as ARGV[0] is used as the program
-   name in the error messages.  This flag implies ARGP_NO_EXIT (on the
-   assumption that silent exiting upon errors is bad behaviour).  */
-#define ARGP_NO_ERRS    0x02
-
-/* Don't parse any non-option args.  Normally non-option args are parsed by
-   calling the parse functions with a key of ARGP_KEY_ARG, and the actual arg
-   as the value.  Since it's impossible to know which parse function wants to
-   handle it, each one is called in turn, until one returns 0 or an error
-   other than ARGP_ERR_UNKNOWN; if an argument is handled by no one, the
-   argp_parse returns prematurely (but with a return value of 0).  If all
-   args have been parsed without error, all parsing functions are called one
-   last time with a key of ARGP_KEY_END.  This flag needn't normally be set,
-   as the normal behavior is to stop parsing as soon as some argument can't
-   be handled.  */
-#define ARGP_NO_ARGS    0x04
-
-/* Parse options and arguments in the same order they occur on the command
-   line -- normally they're rearranged so that all options come first. */
-#define ARGP_IN_ORDER   0x08
-
-/* Don't provide the standard long option --help, which causes usage and
-      option help information to be output to stdout, and exit (0) called. */
-#define ARGP_NO_HELP    0x10
-
-/* Don't exit on errors (they may still result in error messages).  */
-#define ARGP_NO_EXIT    0x20
-
-/* Use the gnu getopt `long-only' rules for parsing arguments.  */
-#define ARGP_LONG_ONLY  0x40
-
-/* Turns off any message-printing/exiting options.  */
-#define ARGP_SILENT    (ARGP_NO_EXIT | ARGP_NO_ERRS | ARGP_NO_HELP)
-
-/* Parse the options strings in ARGC & ARGV according to the options in ARGP.
-   FLAGS is one of the ARGP_ flags above.  If ARG_INDEX is non-NULL, the
-   index in ARGV of the first unparsed option is returned in it.  If an
-   unknown option is present, ARGP_ERR_UNKNOWN is returned; if some parser
-   routine returned a non-zero value, it is returned; otherwise 0 is
-   returned.  This function may also call exit unless the ARGP_NO_HELP flag
-   is set.  INPUT is a pointer to a value to be passed in to the parser.  */
-extern error_t argp_parse (const struct argp *__restrict __argp,
-                           int /*argc*/, char **__restrict /*argv*/,
-                           unsigned __flags, int *__restrict __arg_index,
-                           void *__restrict __input);
-extern error_t __argp_parse (const struct argp *__restrict __argp,
-                             int /*argc*/, char **__restrict /*argv*/,
-                             unsigned __flags, int *__restrict __arg_index,
-                             void *__restrict __input);
-\f
-/* Global variables.  */
-
-/* GNULIB makes sure both program_invocation_name and
-   program_invocation_short_name are available */
-#ifdef GNULIB_PROGRAM_INVOCATION_NAME
-extern char *program_invocation_name;
-# undef HAVE_DECL_PROGRAM_INVOCATION_NAME
-# define HAVE_DECL_PROGRAM_INVOCATION_NAME 1
-#endif
-
-#ifdef GNULIB_PROGRAM_INVOCATION_SHORT_NAME
-extern char *program_invocation_short_name;
-# undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
-# define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 1
-#endif
-
-/* If defined or set by the user program to a non-zero value, then a default
-   option --version is added (unless the ARGP_NO_HELP flag is used), which
-   will print this string followed by a newline and exit (unless the
-   ARGP_NO_EXIT flag is used).  Overridden by ARGP_PROGRAM_VERSION_HOOK.  */
-extern const char *argp_program_version;
-
-/* If defined or set by the user program to a non-zero value, then a default
-   option --version is added (unless the ARGP_NO_HELP flag is used), which
-   calls this function with a stream to print the version to and a pointer to
-   the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
-   used).  This variable takes precedent over ARGP_PROGRAM_VERSION.  */
-extern void (*argp_program_version_hook) (FILE *__restrict __stream,
-                                          struct argp_state *__restrict
-                                          __state);
-
-/* If defined or set by the user program, it should point to string that is
-   the bug-reporting address for the program.  It will be printed by
-   argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various
-   standard help messages), embedded in a sentence that says something like
-   `Report bugs to ADDR.'.  */
-extern const char *argp_program_bug_address;
-
-/* The exit status that argp will use when exiting due to a parsing error.
-   If not defined or set by the user program, this defaults to EX_USAGE from
-   <sysexits.h>.  */
-extern error_t argp_err_exit_status;
-\f
-/* Flags for argp_help.  */
-#define ARGP_HELP_USAGE         0x01 /* a Usage: message. */
-#define ARGP_HELP_SHORT_USAGE   0x02 /*  " but don't actually print options. */
-#define ARGP_HELP_SEE           0x04 /* a `Try ... for more help' message. */
-#define ARGP_HELP_LONG          0x08 /* a long help message. */
-#define ARGP_HELP_PRE_DOC       0x10 /* doc string preceding long help.  */
-#define ARGP_HELP_POST_DOC      0x20 /* doc string following long help.  */
-#define ARGP_HELP_DOC           (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC)
-#define ARGP_HELP_BUG_ADDR      0x40 /* bug report address */
-#define ARGP_HELP_LONG_ONLY     0x80 /* modify output appropriately to
-                                        reflect ARGP_LONG_ONLY mode.  */
-
-/* These ARGP_HELP flags are only understood by argp_state_help.  */
-#define ARGP_HELP_EXIT_ERR      0x100 /* Call exit(1) instead of returning.  */
-#define ARGP_HELP_EXIT_OK       0x200 /* Call exit(0) instead of returning.  */
-
-/* The standard thing to do after a program command line parsing error, if an
-   error message has already been printed.  */
-#define ARGP_HELP_STD_ERR \
-  (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
-/* The standard thing to do after a program command line parsing error, if no
-   more specific error message has been printed.  */
-#define ARGP_HELP_STD_USAGE \
-  (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
-/* The standard thing to do in response to a --help option.  */
-#define ARGP_HELP_STD_HELP \
-  (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \
-   | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR)
-
-/* Output a usage message for ARGP to STREAM.  FLAGS are from the set
-   ARGP_HELP_*.  */
-extern void argp_help (const struct argp *__restrict __argp,
-                       FILE *__restrict __stream,
-                       unsigned __flags, char *__restrict __name);
-extern void __argp_help (const struct argp *__restrict __argp,
-                         FILE *__restrict __stream, unsigned __flags,
-                         char *__name);
-\f
-/* The following routines are intended to be called from within an argp
-   parsing routine (thus taking an argp_state structure as the first
-   argument).  They may or may not print an error message and exit, depending
-   on the flags in STATE -- in any case, the caller should be prepared for
-   them *not* to exit, and should return an appropiate error after calling
-   them.  [argp_usage & argp_error should probably be called argp_state_...,
-   but they're used often enough that they should be short]  */
-
-/* Output, if appropriate, a usage message for STATE to STREAM.  FLAGS are
-   from the set ARGP_HELP_*.  */
-extern void argp_state_help (const struct argp_state *__restrict __state,
-                             FILE *__restrict __stream,
-                             unsigned int __flags);
-extern void __argp_state_help (const struct argp_state *__restrict __state,
-                               FILE *__restrict __stream,
-                               unsigned int __flags);
-
-#if _LIBC || !defined __USE_EXTERN_INLINES
-/* Possibly output the standard usage message for ARGP to stderr and exit.  */
-extern void argp_usage (const struct argp_state *__state);
-extern void __argp_usage (const struct argp_state *__state);
-#endif
-
-/* If appropriate, print the printf string FMT and following args, preceded
-   by the program name and `:', to stderr, and followed by a `Try ... --help'
-   message, then exit (1).  */
-extern void argp_error (const struct argp_state *__restrict __state,
-                        const char *__restrict __fmt, ...)
-     __attribute__ ((__format__ (__printf__, 2, 3)));
-extern void __argp_error (const struct argp_state *__restrict __state,
-                          const char *__restrict __fmt, ...)
-     __attribute__ ((__format__ (__printf__, 2, 3)));
-
-/* Similar to the standard gnu error-reporting function error(), but will
-   respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
-   to STATE->err_stream.  This is useful for argument parsing code that is
-   shared between program startup (when exiting is desired) and runtime
-   option parsing (when typically an error code is returned instead).  The
-   difference between this function and argp_error is that the latter is for
-   *parsing errors*, and the former is for other problems that occur during
-   parsing but don't reflect a (syntactic) problem with the input.  */
-extern void argp_failure (const struct argp_state *__restrict __state,
-                          int __status, int __errnum,
-                          const char *__restrict __fmt, ...)
-     __attribute__ ((__format__ (__printf__, 4, 5)));
-extern void __argp_failure (const struct argp_state *__restrict __state,
-                            int __status, int __errnum,
-                            const char *__restrict __fmt, ...)
-     __attribute__ ((__format__ (__printf__, 4, 5)));
-
-#if _LIBC || !defined __USE_EXTERN_INLINES
-/* Returns true if the option OPT is a valid short option.  */
-extern int _option_is_short (const struct argp_option *__opt) __THROW;
-extern int __option_is_short (const struct argp_option *__opt) __THROW;
-
-/* Returns true if the option OPT is in fact the last (unused) entry in an
-   options array.  */
-extern int _option_is_end (const struct argp_option *__opt) __THROW;
-extern int __option_is_end (const struct argp_option *__opt) __THROW;
-#endif
-
-/* Return the input field for ARGP in the parser corresponding to STATE; used
-   by the help routines.  */
-extern void *_argp_input (const struct argp *__restrict __argp,
-                          const struct argp_state *__restrict __state)
-     __THROW;
-extern void *__argp_input (const struct argp *__restrict __argp,
-                           const struct argp_state *__restrict __state)
-     __THROW;
-\f
-#ifdef __USE_EXTERN_INLINES
-
-# if !_LIBC
-#  define __argp_usage argp_usage
-#  define __argp_state_help argp_state_help
-#  define __option_is_short _option_is_short
-#  define __option_is_end _option_is_end
-# endif
-
-# ifndef ARGP_EI
-#  ifdef __GNUC__
-    /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
-       inline semantics, unless -fgnu89-inline is used.  It defines a macro
-       __GNUC_STDC_INLINE__ to indicate this situation or a macro
-       __GNUC_GNU_INLINE__ to indicate the opposite situation.
-       GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline
-       semantics but warns, unless -fgnu89-inline is used:
-         warning: C99 inline functions are not supported; using GNU89
-         warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute
-       It defines a macro __GNUC_GNU_INLINE__ to indicate this situation.  */
-#   if defined __GNUC_STDC_INLINE__
-#    define ARGP_EI __inline__
-#   elif defined __GNUC_GNU_INLINE__
-#    define ARGP_EI extern __inline__ __attribute__ ((__gnu_inline__))
-#   else
-#    define ARGP_EI extern __inline__
-#   endif
-#  else
-    /* With other compilers, assume the ISO C99 meaning of 'inline', if
-       the compiler supports 'inline' at all.  */
-#   define ARGP_EI inline
-#  endif
-# endif
-
-ARGP_EI void
-__argp_usage (const struct argp_state *__state)
-{
-  __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE);
-}
-
-ARGP_EI int
-__NTH (__option_is_short (const struct argp_option *__opt))
-{
-  if (__opt->flags & OPTION_DOC)
-    return 0;
-  else
-    {
-      int __key = __opt->key;
-      return __key > 0 && __key <= UCHAR_MAX && isprint (__key);
-    }
-}
-
-ARGP_EI int
-__NTH (__option_is_end (const struct argp_option *__opt))
-{
-  return !__opt->key && !__opt->name && !__opt->doc && !__opt->group;
-}
-
-# if !_LIBC
-#  undef __argp_usage
-#  undef __argp_state_help
-#  undef __option_is_short
-#  undef __option_is_end
-# endif
-#endif /* Use extern inlines.  */
-
-#ifdef  __cplusplus
-}
-#endif
-
-#endif /* argp.h */
diff --git a/gnulib/error.c b/gnulib/error.c
deleted file mode 100644 (file)
index c79e8d4..0000000
+++ /dev/null
@@ -1,366 +0,0 @@
-/* Error handler for noninteractive utilities
-   Copyright (C) 1990-1998, 2000-2007, 2009-2010 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-/* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
-
-#if !_LIBC
-# include <config.h>
-#endif
-
-#include "error.h"
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if !_LIBC && ENABLE_NLS
-# include "gettext.h"
-# define _(msgid) gettext (msgid)
-#endif
-
-#ifdef _LIBC
-# include <libintl.h>
-# include <stdbool.h>
-# include <stdint.h>
-# include <wchar.h>
-# define mbsrtowcs __mbsrtowcs
-#endif
-
-#if USE_UNLOCKED_IO
-# include "unlocked-io.h"
-#endif
-
-#ifndef _
-# define _(String) String
-#endif
-
-/* If NULL, error will flush stdout, then print on stderr the program
-   name, a colon and a space.  Otherwise, error will call this
-   function without parameters instead.  */
-void (*error_print_progname) (void);
-
-/* This variable is incremented each time `error' is called.  */
-unsigned int error_message_count;
-
-#ifdef _LIBC
-/* In the GNU C library, there is a predefined variable for this.  */
-
-# define program_name program_invocation_name
-# include <errno.h>
-# include <limits.h>
-# include <libio/libioP.h>
-
-/* In GNU libc we want do not want to use the common name `error' directly.
-   Instead make it a weak alias.  */
-extern void __error (int status, int errnum, const char *message, ...)
-     __attribute__ ((__format__ (__printf__, 3, 4)));
-extern void __error_at_line (int status, int errnum, const char *file_name,
-                             unsigned int line_number, const char *message,
-                             ...)
-     __attribute__ ((__format__ (__printf__, 5, 6)));;
-# define error __error
-# define error_at_line __error_at_line
-
-# include <libio/iolibio.h>
-# define fflush(s) INTUSE(_IO_fflush) (s)
-# undef putc
-# define putc(c, fp) INTUSE(_IO_putc) (c, fp)
-
-# include <bits/libc-lock.h>
-
-#else /* not _LIBC */
-
-# include <fcntl.h>
-# include <unistd.h>
-
-# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
-#  ifndef HAVE_DECL_STRERROR_R
-"this configure-time declaration test was not run"
-#  endif
-char *strerror_r ();
-# endif
-
-/* The calling program should define program_name and set it to the
-   name of the executing program.  */
-extern char *program_name;
-
-# if HAVE_STRERROR_R || defined strerror_r
-#  define __strerror_r strerror_r
-# endif /* HAVE_STRERROR_R || defined strerror_r */
-#endif  /* not _LIBC */
-
-static inline void
-flush_stdout (void)
-{
-#if !_LIBC && defined F_GETFL
-  int stdout_fd;
-
-# if GNULIB_FREOPEN_SAFER
-  /* Use of gnulib's freopen-safer module normally ensures that
-       fileno (stdout) == 1
-     whenever stdout is open.  */
-  stdout_fd = STDOUT_FILENO;
-# else
-  /* POSIX states that fileno (stdout) after fclose is unspecified.  But in
-     practice it is not a problem, because stdout is statically allocated and
-     the fd of a FILE stream is stored as a field in its allocated memory.  */
-  stdout_fd = fileno (stdout);
-# endif
-  /* POSIX states that fflush (stdout) after fclose is unspecified; it
-     is safe in glibc, but not on all other platforms.  fflush (NULL)
-     is always defined, but too draconian.  */
-  if (0 <= stdout_fd && 0 <= fcntl (stdout_fd, F_GETFL))
-#endif
-    fflush (stdout);
-}
-
-static void
-print_errno_message (int errnum)
-{
-  char const *s;
-
-#if defined HAVE_STRERROR_R || _LIBC
-  char errbuf[1024];
-# if STRERROR_R_CHAR_P || _LIBC
-  s = __strerror_r (errnum, errbuf, sizeof errbuf);
-# else
-  if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
-    s = errbuf;
-  else
-    s = 0;
-# endif
-#else
-  s = strerror (errnum);
-#endif
-
-#if !_LIBC
-  if (! s)
-    s = _("Unknown system error");
-#endif
-
-#if _LIBC
-  __fxprintf (NULL, ": %s", s);
-#else
-  fprintf (stderr, ": %s", s);
-#endif
-}
-
-static void
-error_tail (int status, int errnum, const char *message, va_list args)
-{
-#if _LIBC
-  if (_IO_fwide (stderr, 0) > 0)
-    {
-# define ALLOCA_LIMIT 2000
-      size_t len = strlen (message) + 1;
-      wchar_t *wmessage = NULL;
-      mbstate_t st;
-      size_t res;
-      const char *tmp;
-      bool use_malloc = false;
-
-      while (1)
-        {
-          if (__libc_use_alloca (len * sizeof (wchar_t)))
-            wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
-          else
-            {
-              if (!use_malloc)
-                wmessage = NULL;
-
-              wchar_t *p = (wchar_t *) realloc (wmessage,
-                                                len * sizeof (wchar_t));
-              if (p == NULL)
-                {
-                  free (wmessage);
-                  fputws_unlocked (L"out of memory\n", stderr);
-                  return;
-                }
-              wmessage = p;
-              use_malloc = true;
-            }
-
-          memset (&st, '\0', sizeof (st));
-          tmp = message;
-
-          res = mbsrtowcs (wmessage, &tmp, len, &st);
-          if (res != len)
-            break;
-
-          if (__builtin_expect (len >= SIZE_MAX / 2, 0))
-            {
-              /* This really should not happen if everything is fine.  */
-              res = (size_t) -1;
-              break;
-            }
-
-          len *= 2;
-        }
-
-      if (res == (size_t) -1)
-        {
-          /* The string cannot be converted.  */
-          if (use_malloc)
-            {
-              free (wmessage);
-              use_malloc = false;
-            }
-          wmessage = (wchar_t *) L"???";
-        }
-
-      __vfwprintf (stderr, wmessage, args);
-
-      if (use_malloc)
-        free (wmessage);
-    }
-  else
-#endif
-    vfprintf (stderr, message, args);
-  va_end (args);
-
-  ++error_message_count;
-  if (errnum)
-    print_errno_message (errnum);
-#if _LIBC
-  __fxprintf (NULL, "\n");
-#else
-  putc ('\n', stderr);
-#endif
-  fflush (stderr);
-  if (status)
-    exit (status);
-}
-
-
-/* Print the program name and error message MESSAGE, which is a printf-style
-   format string with optional args.
-   If ERRNUM is nonzero, print its corresponding system error message.
-   Exit with status STATUS if it is nonzero.  */
-void
-error (int status, int errnum, const char *message, ...)
-{
-  va_list args;
-
-#if defined _LIBC && defined __libc_ptf_call
-  /* We do not want this call to be cut short by a thread
-     cancellation.  Therefore disable cancellation for now.  */
-  int state = PTHREAD_CANCEL_ENABLE;
-  __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
-                   0);
-#endif
-
-  flush_stdout ();
-#ifdef _LIBC
-  _IO_flockfile (stderr);
-#endif
-  if (error_print_progname)
-    (*error_print_progname) ();
-  else
-    {
-#if _LIBC
-      __fxprintf (NULL, "%s: ", program_name);
-#else
-      fprintf (stderr, "%s: ", program_name);
-#endif
-    }
-
-  va_start (args, message);
-  error_tail (status, errnum, message, args);
-
-#ifdef _LIBC
-  _IO_funlockfile (stderr);
-# ifdef __libc_ptf_call
-  __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
-# endif
-#endif
-}
-\f
-/* Sometimes we want to have at most one error per line.  This
-   variable controls whether this mode is selected or not.  */
-int error_one_per_line;
-
-void
-error_at_line (int status, int errnum, const char *file_name,
-               unsigned int line_number, const char *message, ...)
-{
-  va_list args;
-
-  if (error_one_per_line)
-    {
-      static const char *old_file_name;
-      static unsigned int old_line_number;
-
-      if (old_line_number == line_number
-          && (file_name == old_file_name
-              || strcmp (old_file_name, file_name) == 0))
-        /* Simply return and print nothing.  */
-        return;
-
-      old_file_name = file_name;
-      old_line_number = line_number;
-    }
-
-#if defined _LIBC && defined __libc_ptf_call
-  /* We do not want this call to be cut short by a thread
-     cancellation.  Therefore disable cancellation for now.  */
-  int state = PTHREAD_CANCEL_ENABLE;
-  __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
-                   0);
-#endif
-
-  flush_stdout ();
-#ifdef _LIBC
-  _IO_flockfile (stderr);
-#endif
-  if (error_print_progname)
-    (*error_print_progname) ();
-  else
-    {
-#if _LIBC
-      __fxprintf (NULL, "%s:", program_name);
-#else
-      fprintf (stderr, "%s:", program_name);
-#endif
-    }
-
-#if _LIBC
-  __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
-              file_name, line_number);
-#else
-  fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
-           file_name, line_number);
-#endif
-
-  va_start (args, message);
-  error_tail (status, errnum, message, args);
-
-#ifdef _LIBC
-  _IO_funlockfile (stderr);
-# ifdef __libc_ptf_call
-  __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
-# endif
-#endif
-}
-
-#ifdef _LIBC
-/* Make the weak alias.  */
-# undef error
-# undef error_at_line
-weak_alias (__error, error)
-weak_alias (__error_at_line, error_at_line)
-#endif
diff --git a/gnulib/error.h b/gnulib/error.h
deleted file mode 100644 (file)
index 9deef02..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Declaration for error-reporting function
-   Copyright (C) 1995, 1996, 1997, 2003, 2006, 2008, 2009, 2010 Free Software
-   Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef _ERROR_H
-#define _ERROR_H 1
-
-#ifndef __attribute__
-/* The __attribute__ feature is available in gcc versions 2.5 and later.
-   The __-protected variants of the attributes 'format' and 'printf' are
-   accepted by gcc versions 2.6.4 (effectively 2.7) and later.
-   We enable __attribute__ only if these are supported too, because
-   gnulib and libintl do '#define printf __printf__' when they override
-   the 'printf' function.  */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
-#  define __attribute__(Spec)   /* empty */
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Print a message with `fprintf (stderr, FORMAT, ...)';
-   if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM).
-   If STATUS is nonzero, terminate the program with `exit (STATUS)'.  */
-
-extern void error (int __status, int __errnum, const char *__format, ...)
-     __attribute__ ((__format__ (__printf__, 3, 4)));
-
-extern void error_at_line (int __status, int __errnum, const char *__fname,
-                           unsigned int __lineno, const char *__format, ...)
-     __attribute__ ((__format__ (__printf__, 5, 6)));
-
-/* If NULL, error will flush stdout, then print on stderr the program
-   name, a colon and a space.  Otherwise, error will call this
-   function without parameters instead.  */
-extern void (*error_print_progname) (void);
-
-/* This variable is incremented each time `error' is called.  */
-extern unsigned int error_message_count;
-
-/* Sometimes we want to have at most one error per line.  This
-   variable controls whether this mode is selected or not.  */
-extern int error_one_per_line;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* error.h */
diff --git a/gnulib/fnmatch.c b/gnulib/fnmatch.c
deleted file mode 100644 (file)
index f15dbb8..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004, 2005, 2006, 2007, 2009, 2010 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
-
-#ifndef _LIBC
-# include <config.h>
-#endif
-
-/* Enable GNU extensions in fnmatch.h.  */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE    1
-#endif
-
-#if ! defined __builtin_expect && __GNUC__ < 3
-# define __builtin_expect(expr, expected) (expr)
-#endif
-
-#include <fnmatch.h>
-
-#include <alloca.h>
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <stddef.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define WIDE_CHAR_SUPPORT \
-  (HAVE_WCTYPE_H && HAVE_BTOWC && HAVE_ISWCTYPE \
-   && HAVE_WMEMCHR && (HAVE_WMEMCPY || HAVE_WMEMPCPY))
-
-/* For platform which support the ISO C amendement 1 functionality we
-   support user defined character classes.  */
-#if defined _LIBC || WIDE_CHAR_SUPPORT
-# include <wctype.h>
-# include <wchar.h>
-#endif
-
-/* We need some of the locale data (the collation sequence information)
-   but there is no interface to get this information in general.  Therefore
-   we support a correct implementation only in glibc.  */
-#ifdef _LIBC
-# include "../locale/localeinfo.h"
-# include "../locale/elem-hash.h"
-# include "../locale/coll-lookup.h"
-# include <shlib-compat.h>
-
-# define CONCAT(a,b) __CONCAT(a,b)
-# define mbsrtowcs __mbsrtowcs
-# define fnmatch __fnmatch
-extern int fnmatch (const char *pattern, const char *string, int flags);
-#endif
-
-#ifndef SIZE_MAX
-# define SIZE_MAX ((size_t) -1)
-#endif
-
-/* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set.  */
-#define NO_LEADING_PERIOD(flags) \
-  ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD))
-
-/* Comment out all this code if we are using the GNU C Library, and are not
-   actually compiling the library itself, and have not detected a bug
-   in the library.  This code is part of the GNU C
-   Library, but also included in many other GNU distributions.  Compiling
-   and linking in this code is a waste when using the GNU C library
-   (especially if it is a shared library).  Rather than having every GNU
-   program understand `configure --with-gnu-libc' and omit the object files,
-   it is simpler to just do this in the source for each such file.  */
-
-#if defined _LIBC || !defined __GNU_LIBRARY__ || !HAVE_FNMATCH_GNU
-
-
-# if ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK))
-#  define isblank(c) ((c) == ' ' || (c) == '\t')
-# endif
-
-# define STREQ(s1, s2) (strcmp (s1, s2) == 0)
-
-# if defined _LIBC || WIDE_CHAR_SUPPORT
-/* The GNU C library provides support for user-defined character classes
-   and the functions from ISO C amendement 1.  */
-#  ifdef CHARCLASS_NAME_MAX
-#   define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
-#  else
-/* This shouldn't happen but some implementation might still have this
-   problem.  Use a reasonable default value.  */
-#   define CHAR_CLASS_MAX_LENGTH 256
-#  endif
-
-#  ifdef _LIBC
-#   define IS_CHAR_CLASS(string) __wctype (string)
-#  else
-#   define IS_CHAR_CLASS(string) wctype (string)
-#  endif
-
-#  ifdef _LIBC
-#   define ISWCTYPE(WC, WT)     __iswctype (WC, WT)
-#  else
-#   define ISWCTYPE(WC, WT)     iswctype (WC, WT)
-#  endif
-
-#  if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
-/* In this case we are implementing the multibyte character handling.  */
-#   define HANDLE_MULTIBYTE     1
-#  endif
-
-# else
-#  define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */
-
-#  define IS_CHAR_CLASS(string)                                               \
-   (STREQ (string, "alpha") || STREQ (string, "upper")                        \
-    || STREQ (string, "lower") || STREQ (string, "digit")                     \
-    || STREQ (string, "alnum") || STREQ (string, "xdigit")                    \
-    || STREQ (string, "space") || STREQ (string, "print")                     \
-    || STREQ (string, "punct") || STREQ (string, "graph")                     \
-    || STREQ (string, "cntrl") || STREQ (string, "blank"))
-# endif
-
-/* Avoid depending on library functions or files
-   whose names are inconsistent.  */
-
-/* Global variable.  */
-static int posixly_correct;
-
-# ifndef internal_function
-/* Inside GNU libc we mark some function in a special way.  In other
-   environments simply ignore the marking.  */
-#  define internal_function
-# endif
-
-/* Note that this evaluates C many times.  */
-# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
-# define CHAR   char
-# define UCHAR  unsigned char
-# define INT    int
-# define FCT    internal_fnmatch
-# define EXT    ext_match
-# define END    end_pattern
-# define L_(CS) CS
-# ifdef _LIBC
-#  define BTOWC(C)      __btowc (C)
-# else
-#  define BTOWC(C)      btowc (C)
-# endif
-# define STRLEN(S) strlen (S)
-# define STRCAT(D, S) strcat (D, S)
-# ifdef _LIBC
-#  define MEMPCPY(D, S, N) __mempcpy (D, S, N)
-# else
-#  if HAVE_MEMPCPY
-#   define MEMPCPY(D, S, N) mempcpy (D, S, N)
-#  else
-#   define MEMPCPY(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N)))
-#  endif
-# endif
-# define MEMCHR(S, C, N) memchr (S, C, N)
-# define STRCOLL(S1, S2) strcoll (S1, S2)
-# include "fnmatch_loop.c"
-
-
-# if HANDLE_MULTIBYTE
-#  define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c))
-#  define CHAR  wchar_t
-#  define UCHAR wint_t
-#  define INT   wint_t
-#  define FCT   internal_fnwmatch
-#  define EXT   ext_wmatch
-#  define END   end_wpattern
-#  define L_(CS)        L##CS
-#  define BTOWC(C)      (C)
-#  ifdef _LIBC
-#   define STRLEN(S) __wcslen (S)
-#   define STRCAT(D, S) __wcscat (D, S)
-#   define MEMPCPY(D, S, N) __wmempcpy (D, S, N)
-#  else
-#   define STRLEN(S) wcslen (S)
-#   define STRCAT(D, S) wcscat (D, S)
-#   if HAVE_WMEMPCPY
-#    define MEMPCPY(D, S, N) wmempcpy (D, S, N)
-#   else
-#    define MEMPCPY(D, S, N) (wmemcpy (D, S, N) + (N))
-#   endif
-#  endif
-#  define MEMCHR(S, C, N) wmemchr (S, C, N)
-#  define STRCOLL(S1, S2) wcscoll (S1, S2)
-#  define WIDE_CHAR_VERSION 1
-
-#  undef IS_CHAR_CLASS
-/* We have to convert the wide character string in a multibyte string.  But
-   we know that the character class names consist of alphanumeric characters
-   from the portable character set, and since the wide character encoding
-   for a member of the portable character set is the same code point as
-   its single-byte encoding, we can use a simplified method to convert the
-   string to a multibyte character string.  */
-static wctype_t
-is_char_class (const wchar_t *wcs)
-{
-  char s[CHAR_CLASS_MAX_LENGTH + 1];
-  char *cp = s;
-
-  do
-    {
-      /* Test for a printable character from the portable character set.  */
-#  ifdef _LIBC
-      if (*wcs < 0x20 || *wcs > 0x7e
-          || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
-        return (wctype_t) 0;
-#  else
-      switch (*wcs)
-        {
-        case L' ': case L'!': case L'"': case L'#': case L'%':
-        case L'&': case L'\'': case L'(': case L')': case L'*':
-        case L'+': case L',': case L'-': case L'.': case L'/':
-        case L'0': case L'1': case L'2': case L'3': case L'4':
-        case L'5': case L'6': case L'7': case L'8': case L'9':
-        case L':': case L';': case L'<': case L'=': case L'>':
-        case L'?':
-        case L'A': case L'B': case L'C': case L'D': case L'E':
-        case L'F': case L'G': case L'H': case L'I': case L'J':
-        case L'K': case L'L': case L'M': case L'N': case L'O':
-        case L'P': case L'Q': case L'R': case L'S': case L'T':
-        case L'U': case L'V': case L'W': case L'X': case L'Y':
-        case L'Z':
-        case L'[': case L'\\': case L']': case L'^': case L'_':
-        case L'a': case L'b': case L'c': case L'd': case L'e':
-        case L'f': case L'g': case L'h': case L'i': case L'j':
-        case L'k': case L'l': case L'm': case L'n': case L'o':
-        case L'p': case L'q': case L'r': case L's': case L't':
-        case L'u': case L'v': case L'w': case L'x': case L'y':
-        case L'z': case L'{': case L'|': case L'}': case L'~':
-          break;
-        default:
-          return (wctype_t) 0;
-        }
-#  endif
-
-      /* Avoid overrunning the buffer.  */
-      if (cp == s + CHAR_CLASS_MAX_LENGTH)
-        return (wctype_t) 0;
-
-      *cp++ = (char) *wcs++;
-    }
-  while (*wcs != L'\0');
-
-  *cp = '\0';
-
-#  ifdef _LIBC
-  return __wctype (s);
-#  else
-  return wctype (s);
-#  endif
-}
-#  define IS_CHAR_CLASS(string) is_char_class (string)
-
-#  include "fnmatch_loop.c"
-# endif
-
-
-int
-fnmatch (const char *pattern, const char *string, int flags)
-{
-# if HANDLE_MULTIBYTE
-#  define ALLOCA_LIMIT 2000
-  if (__builtin_expect (MB_CUR_MAX, 1) != 1)
-    {
-      mbstate_t ps;
-      size_t patsize;
-      size_t strsize;
-      size_t totsize;
-      wchar_t *wpattern;
-      wchar_t *wstring;
-      int res;
-
-      /* Calculate the size needed to convert the strings to
-         wide characters.  */
-      memset (&ps, '\0', sizeof (ps));
-      patsize = mbsrtowcs (NULL, &pattern, 0, &ps) + 1;
-      if (__builtin_expect (patsize != 0, 1))
-        {
-          assert (mbsinit (&ps));
-          strsize = mbsrtowcs (NULL, &string, 0, &ps) + 1;
-          if (__builtin_expect (strsize != 0, 1))
-            {
-              assert (mbsinit (&ps));
-              totsize = patsize + strsize;
-              if (__builtin_expect (! (patsize <= totsize
-                                       && totsize <= SIZE_MAX / sizeof (wchar_t)),
-                                    0))
-                {
-                  errno = ENOMEM;
-                  return -1;
-                }
-
-              /* Allocate room for the wide characters.  */
-              if (__builtin_expect (totsize < ALLOCA_LIMIT, 1))
-                wpattern = (wchar_t *) alloca (totsize * sizeof (wchar_t));
-              else
-                {
-                  wpattern = malloc (totsize * sizeof (wchar_t));
-                  if (__builtin_expect (! wpattern, 0))
-                    {
-                      errno = ENOMEM;
-                      return -1;
-                    }
-                }
-              wstring = wpattern + patsize;
-
-              /* Convert the strings into wide characters.  */
-              mbsrtowcs (wpattern, &pattern, patsize, &ps);
-              assert (mbsinit (&ps));
-              mbsrtowcs (wstring, &string, strsize, &ps);
-
-              res = internal_fnwmatch (wpattern, wstring, wstring + strsize - 1,
-                                       flags & FNM_PERIOD, flags);
-
-              if (__builtin_expect (! (totsize < ALLOCA_LIMIT), 0))
-                free (wpattern);
-              return res;
-            }
-        }
-    }
-
-# endif /* HANDLE_MULTIBYTE */
-
-  return internal_fnmatch (pattern, string, string + strlen (string),
-                           flags & FNM_PERIOD, flags);
-}
-
-# ifdef _LIBC
-#  undef fnmatch
-versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3);
-#  if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3)
-strong_alias (__fnmatch, __fnmatch_old)
-compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0);
-#  endif
-libc_hidden_ver (__fnmatch, fnmatch)
-# endif
-
-#endif  /* _LIBC or not __GNU_LIBRARY__.  */
diff --git a/gnulib/fnmatch.h b/gnulib/fnmatch.h
deleted file mode 100644 (file)
index b086b45..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2001, 2002, 2003,
-   2005, 2007 Free Software Foundation, Inc.
-
-   This file is part of the GNU C Library.
-
-   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
-
-#ifndef        _FNMATCH_H
-#define        _FNMATCH_H      1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* We #undef these before defining them because some losing systems
-   (HP-UX A.08.07 for example) define these in <unistd.h>.  */
-#undef FNM_PATHNAME
-#undef FNM_NOESCAPE
-#undef FNM_PERIOD
-
-/* Bits set in the FLAGS argument to `fnmatch'.  */
-#define        FNM_PATHNAME    (1 << 0) /* No wildcard can ever match `/'.  */
-#define        FNM_NOESCAPE    (1 << 1) /* Backslashes don't quote special chars.  */
-#define        FNM_PERIOD      (1 << 2) /* Leading `.' is matched only explicitly.  */
-
-#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE
-# define FNM_FILE_NAME  FNM_PATHNAME   /* Preferred GNU name.  */
-# define FNM_LEADING_DIR (1 << 3)      /* Ignore `/...' after a match.  */
-# define FNM_CASEFOLD   (1 << 4)       /* Compare without regard to case.  */
-# define FNM_EXTMATCH   (1 << 5)       /* Use ksh-like extended matching. */
-#endif
-
-/* Value returned by `fnmatch' if STRING does not match PATTERN.  */
-#define        FNM_NOMATCH     1
-
-/* This value is returned if the implementation does not support
-   `fnmatch'.  Since this is not the case here it will never be
-   returned but the conformance test suites still require the symbol
-   to be defined.  */
-#ifdef _XOPEN_SOURCE
-# define FNM_NOSYS     (-1)
-#endif
-
-/* Match NAME against the file name pattern PATTERN,
-   returning zero if it matches, FNM_NOMATCH if not.  */
-extern int fnmatch (const char *__pattern, const char *__name,
-                   int __flags);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* fnmatch.h */
diff --git a/gnulib/fnmatch_loop.c b/gnulib/fnmatch_loop.c
deleted file mode 100644 (file)
index 8cd4444..0000000
+++ /dev/null
@@ -1,1215 +0,0 @@
-/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004, 2005, 2006, 2009, 2010 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
-
-/* Match STRING against the file name pattern PATTERN, returning zero if
-   it matches, nonzero if not.  */
-static int EXT (INT opt, const CHAR *pattern, const CHAR *string,
-                const CHAR *string_end, bool no_leading_period, int flags)
-     internal_function;
-static const CHAR *END (const CHAR *patternp) internal_function;
-
-static int
-internal_function
-FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end,
-     bool no_leading_period, int flags)
-{
-  register const CHAR *p = pattern, *n = string;
-  register UCHAR c;
-#ifdef _LIBC
-# if WIDE_CHAR_VERSION
-  const char *collseq = (const char *)
-    _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
-# else
-  const UCHAR *collseq = (const UCHAR *)
-    _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
-# endif
-#endif
-
-  while ((c = *p++) != L_('\0'))
-    {
-      bool new_no_leading_period = false;
-      c = FOLD (c);
-
-      switch (c)
-        {
-        case L_('?'):
-          if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
-            {
-              int res;
-
-              res = EXT (c, p, n, string_end, no_leading_period,
-                         flags);
-              if (res != -1)
-                return res;
-            }
-
-          if (n == string_end)
-            return FNM_NOMATCH;
-          else if (*n == L_('/') && (flags & FNM_FILE_NAME))
-            return FNM_NOMATCH;
-          else if (*n == L_('.') && no_leading_period)
-            return FNM_NOMATCH;
-          break;
-
-        case L_('\\'):
-          if (!(flags & FNM_NOESCAPE))
-            {
-              c = *p++;
-              if (c == L_('\0'))
-                /* Trailing \ loses.  */
-                return FNM_NOMATCH;
-              c = FOLD (c);
-            }
-          if (n == string_end || FOLD ((UCHAR) *n) != c)
-            return FNM_NOMATCH;
-          break;
-
-        case L_('*'):
-          if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
-            {
-              int res;
-
-              res = EXT (c, p, n, string_end, no_leading_period,
-                         flags);
-              if (res != -1)
-                return res;
-            }
-
-          if (n != string_end && *n == L_('.') && no_leading_period)
-            return FNM_NOMATCH;
-
-          for (c = *p++; c == L_('?') || c == L_('*'); c = *p++)
-            {
-              if (*p == L_('(') && (flags & FNM_EXTMATCH) != 0)
-                {
-                  const CHAR *endp = END (p);
-                  if (endp != p)
-                    {
-                      /* This is a pattern.  Skip over it.  */
-                      p = endp;
-                      continue;
-                    }
-                }
-
-              if (c == L_('?'))
-                {
-                  /* A ? needs to match one character.  */
-                  if (n == string_end)
-                    /* There isn't another character; no match.  */
-                    return FNM_NOMATCH;
-                  else if (*n == L_('/')
-                           && __builtin_expect (flags & FNM_FILE_NAME, 0))
-                    /* A slash does not match a wildcard under
-                       FNM_FILE_NAME.  */
-                    return FNM_NOMATCH;
-                  else
-                    /* One character of the string is consumed in matching
-                       this ? wildcard, so *??? won't match if there are
-                       less than three characters.  */
-                    ++n;
-                }
-            }
-
-          if (c == L_('\0'))
-            /* The wildcard(s) is/are the last element of the pattern.
-               If the name is a file name and contains another slash
-               this means it cannot match, unless the FNM_LEADING_DIR
-               flag is set.  */
-            {
-              int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH;
-
-              if (flags & FNM_FILE_NAME)
-                {
-                  if (flags & FNM_LEADING_DIR)
-                    result = 0;
-                  else
-                    {
-                      if (MEMCHR (n, L_('/'), string_end - n) == NULL)
-                        result = 0;
-                    }
-                }
-
-              return result;
-            }
-          else
-            {
-              const CHAR *endp;
-
-              endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\0'),
-                             string_end - n);
-              if (endp == NULL)
-                endp = string_end;
-
-              if (c == L_('[')
-                  || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0
-                      && (c == L_('@') || c == L_('+') || c == L_('!'))
-                      && *p == L_('(')))
-                {
-                  int flags2 = ((flags & FNM_FILE_NAME)
-                                ? flags : (flags & ~FNM_PERIOD));
-                  bool no_leading_period2 = no_leading_period;
-
-                  for (--p; n < endp; ++n, no_leading_period2 = false)
-                    if (FCT (p, n, string_end, no_leading_period2, flags2)
-                        == 0)
-                      return 0;
-                }
-              else if (c == L_('/') && (flags & FNM_FILE_NAME))
-                {
-                  while (n < string_end && *n != L_('/'))
-                    ++n;
-                  if (n < string_end && *n == L_('/')
-                      && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags)
-                          == 0))
-                    return 0;
-                }
-              else
-                {
-                  int flags2 = ((flags & FNM_FILE_NAME)
-                                ? flags : (flags & ~FNM_PERIOD));
-                  int no_leading_period2 = no_leading_period;
-
-                  if (c == L_('\\') && !(flags & FNM_NOESCAPE))
-                    c = *p;
-                  c = FOLD (c);
-                  for (--p; n < endp; ++n, no_leading_period2 = false)
-                    if (FOLD ((UCHAR) *n) == c
-                        && (FCT (p, n, string_end, no_leading_period2, flags2)
-                            == 0))
-                      return 0;
-                }
-            }
-
-          /* If we come here no match is possible with the wildcard.  */
-          return FNM_NOMATCH;
-
-        case L_('['):
-          {
-            /* Nonzero if the sense of the character class is inverted.  */
-            register bool not;
-            CHAR cold;
-            UCHAR fn;
-
-            if (posixly_correct == 0)
-              posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
-
-            if (n == string_end)
-              return FNM_NOMATCH;
-
-            if (*n == L_('.') && no_leading_period)
-              return FNM_NOMATCH;
-
-            if (*n == L_('/') && (flags & FNM_FILE_NAME))
-              /* `/' cannot be matched.  */
-              return FNM_NOMATCH;
-
-            not = (*p == L_('!') || (posixly_correct < 0 && *p == L_('^')));
-            if (not)
-              ++p;
-
-            fn = FOLD ((UCHAR) *n);
-
-            c = *p++;
-            for (;;)
-              {
-                if (!(flags & FNM_NOESCAPE) && c == L_('\\'))
-                  {
-                    if (*p == L_('\0'))
-                      return FNM_NOMATCH;
-                    c = FOLD ((UCHAR) *p);
-                    ++p;
-
-                    goto normal_bracket;
-                  }
-                else if (c == L_('[') && *p == L_(':'))
-                  {
-                    /* Leave room for the null.  */
-                    CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
-                    size_t c1 = 0;
-#if defined _LIBC || WIDE_CHAR_SUPPORT
-                    wctype_t wt;
-#endif
-                    const CHAR *startp = p;
-
-                    for (;;)
-                      {
-                        if (c1 == CHAR_CLASS_MAX_LENGTH)
-                          /* The name is too long and therefore the pattern
-                             is ill-formed.  */
-                          return FNM_NOMATCH;
-
-                        c = *++p;
-                        if (c == L_(':') && p[1] == L_(']'))
-                          {
-                            p += 2;
-                            break;
-                          }
-                        if (c < L_('a') || c >= L_('z'))
-                          {
-                            /* This cannot possibly be a character class name.
-                               Match it as a normal range.  */
-                            p = startp;
-                            c = L_('[');
-                            goto normal_bracket;
-                          }
-                        str[c1++] = c;
-                      }
-                    str[c1] = L_('\0');
-
-#if defined _LIBC || WIDE_CHAR_SUPPORT
-                    wt = IS_CHAR_CLASS (str);
-                    if (wt == 0)
-                      /* Invalid character class name.  */
-                      return FNM_NOMATCH;
-
-# if defined _LIBC && ! WIDE_CHAR_VERSION
-                    /* The following code is glibc specific but does
-                       there a good job in speeding up the code since
-                       we can avoid the btowc() call.  */
-                    if (_ISCTYPE ((UCHAR) *n, wt))
-                      goto matched;
-# else
-                    if (ISWCTYPE (BTOWC ((UCHAR) *n), wt))
-                      goto matched;
-# endif
-#else
-                    if ((STREQ (str, L_("alnum")) && isalnum ((UCHAR) *n))
-                        || (STREQ (str, L_("alpha")) && isalpha ((UCHAR) *n))
-                        || (STREQ (str, L_("blank")) && isblank ((UCHAR) *n))
-                        || (STREQ (str, L_("cntrl")) && iscntrl ((UCHAR) *n))
-                        || (STREQ (str, L_("digit")) && isdigit ((UCHAR) *n))
-                        || (STREQ (str, L_("graph")) && isgraph ((UCHAR) *n))
-                        || (STREQ (str, L_("lower")) && islower ((UCHAR) *n))
-                        || (STREQ (str, L_("print")) && isprint ((UCHAR) *n))
-                        || (STREQ (str, L_("punct")) && ispunct ((UCHAR) *n))
-                        || (STREQ (str, L_("space")) && isspace ((UCHAR) *n))
-                        || (STREQ (str, L_("upper")) && isupper ((UCHAR) *n))
-                        || (STREQ (str, L_("xdigit")) && isxdigit ((UCHAR) *n)))
-                      goto matched;
-#endif
-                    c = *p++;
-                  }
-#ifdef _LIBC
-                else if (c == L_('[') && *p == L_('='))
-                  {
-                    UCHAR str[1];
-                    uint32_t nrules =
-                      _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-                    const CHAR *startp = p;
-
-                    c = *++p;
-                    if (c == L_('\0'))
-                      {
-                        p = startp;
-                        c = L_('[');
-                        goto normal_bracket;
-                      }
-                    str[0] = c;
-
-                    c = *++p;
-                    if (c != L_('=') || p[1] != L_(']'))
-                      {
-                        p = startp;
-                        c = L_('[');
-                        goto normal_bracket;
-                      }
-                    p += 2;
-
-                    if (nrules == 0)
-                      {
-                        if ((UCHAR) *n == str[0])
-                          goto matched;
-                      }
-                    else
-                      {
-                        const int32_t *table;
-# if WIDE_CHAR_VERSION
-                        const int32_t *weights;
-                        const int32_t *extra;
-# else
-                        const unsigned char *weights;
-                        const unsigned char *extra;
-# endif
-                        const int32_t *indirect;
-                        int32_t idx;
-                        const UCHAR *cp = (const UCHAR *) str;
-
-                        /* This #include defines a local function!  */
-# if WIDE_CHAR_VERSION
-#  include <locale/weightwc.h>
-# else
-#  include <locale/weight.h>
-# endif
-
-# if WIDE_CHAR_VERSION
-                        table = (const int32_t *)
-                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
-                        weights = (const int32_t *)
-                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
-                        extra = (const int32_t *)
-                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
-                        indirect = (const int32_t *)
-                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
-# else
-                        table = (const int32_t *)
-                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
-                        weights = (const unsigned char *)
-                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
-                        extra = (const unsigned char *)
-                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
-                        indirect = (const int32_t *)
-                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
-# endif
-
-                        idx = findidx (&cp);
-                        if (idx != 0)
-                          {
-                            /* We found a table entry.  Now see whether the
-                               character we are currently at has the same
-                               equivalance class value.  */
-                            int len = weights[idx & 0xffffff];
-                            int32_t idx2;
-                            const UCHAR *np = (const UCHAR *) n;
-
-                            idx2 = findidx (&np);
-                            if (idx2 != 0
-                                && (idx >> 24) == (idx2 >> 24)
-                                && len == weights[idx2 & 0xffffff])
-                              {
-                                int cnt = 0;
-
-                                idx &= 0xffffff;
-                                idx2 &= 0xffffff;
-
-                                while (cnt < len
-                                       && (weights[idx + 1 + cnt]
-                                           == weights[idx2 + 1 + cnt]))
-                                  ++cnt;
-
-                                if (cnt == len)
-                                  goto matched;
-                              }
-                          }
-                      }
-
-                    c = *p++;
-                  }
-#endif
-                else if (c == L_('\0'))
-                  /* [ (unterminated) loses.  */
-                  return FNM_NOMATCH;
-                else
-                  {
-                    bool is_range = false;
-
-#ifdef _LIBC
-                    bool is_seqval = false;
-
-                    if (c == L_('[') && *p == L_('.'))
-                      {
-                        uint32_t nrules =
-                          _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-                        const CHAR *startp = p;
-                        size_t c1 = 0;
-
-                        while (1)
-                          {
-                            c = *++p;
-                            if (c == L_('.') && p[1] == L_(']'))
-                              {
-                                p += 2;
-                                break;
-                              }
-                            if (c == '\0')
-                              return FNM_NOMATCH;
-                            ++c1;
-                          }
-
-                        /* We have to handling the symbols differently in
-                           ranges since then the collation sequence is
-                           important.  */
-                        is_range = *p == L_('-') && p[1] != L_('\0');
-
-                        if (nrules == 0)
-                          {
-                            /* There are no names defined in the collation
-                               data.  Therefore we only accept the trivial
-                               names consisting of the character itself.  */
-                            if (c1 != 1)
-                              return FNM_NOMATCH;
-
-                            if (!is_range && *n == startp[1])
-                              goto matched;
-
-                            cold = startp[1];
-                            c = *p++;
-                          }
-                        else
-                          {
-                            int32_t table_size;
-                            const int32_t *symb_table;
-# ifdef WIDE_CHAR_VERSION
-                            char str[c1];
-                            size_t strcnt;
-# else
-#  define str (startp + 1)
-# endif
-                            const unsigned char *extra;
-                            int32_t idx;
-                            int32_t elem;
-                            int32_t second;
-                            int32_t hash;
-
-# ifdef WIDE_CHAR_VERSION
-                            /* We have to convert the name to a single-byte
-                               string.  This is possible since the names
-                               consist of ASCII characters and the internal
-                               representation is UCS4.  */
-                            for (strcnt = 0; strcnt < c1; ++strcnt)
-                              str[strcnt] = startp[1 + strcnt];
-# endif
-
-                            table_size =
-                              _NL_CURRENT_WORD (LC_COLLATE,
-                                                _NL_COLLATE_SYMB_HASH_SIZEMB);
-                            symb_table = (const int32_t *)
-                              _NL_CURRENT (LC_COLLATE,
-                                           _NL_COLLATE_SYMB_TABLEMB);
-                            extra = (const unsigned char *)
-                              _NL_CURRENT (LC_COLLATE,
-                                           _NL_COLLATE_SYMB_EXTRAMB);
-
-                            /* Locate the character in the hashing table.  */
-                            hash = elem_hash (str, c1);
-
-                            idx = 0;
-                            elem = hash % table_size;
-                            if (symb_table[2 * elem] != 0)
-                              {
-                                second = hash % (table_size - 2) + 1;
-
-                                do
-                                  {
-                                    /* First compare the hashing value.  */
-                                    if (symb_table[2 * elem] == hash
-                                        && (c1
-                                            == extra[symb_table[2 * elem + 1]])
-                                        && memcmp (str,
-                                                   &extra[symb_table[2 * elem
-                                                                     + 1]
-                                                          + 1], c1) == 0)
-                                      {
-                                        /* Yep, this is the entry.  */
-                                        idx = symb_table[2 * elem + 1];
-                                        idx += 1 + extra[idx];
-                                        break;
-                                      }
-
-                                    /* Next entry.  */
-                                    elem += second;
-                                  }
-                                while (symb_table[2 * elem] != 0);
-                              }
-
-                            if (symb_table[2 * elem] != 0)
-                              {
-                                /* Compare the byte sequence but only if
-                                   this is not part of a range.  */
-# ifdef WIDE_CHAR_VERSION
-                                int32_t *wextra;
-
-                                idx += 1 + extra[idx];
-                                /* Adjust for the alignment.  */
-                                idx = (idx + 3) & ~3;
-
-                                wextra = (int32_t *) &extra[idx + 4];
-# endif
-
-                                if (! is_range)
-                                  {
-# ifdef WIDE_CHAR_VERSION
-                                    for (c1 = 0;
-                                         (int32_t) c1 < wextra[idx];
-                                         ++c1)
-                                      if (n[c1] != wextra[1 + c1])
-                                        break;
-
-                                    if ((int32_t) c1 == wextra[idx])
-                                      goto matched;
-# else
-                                    for (c1 = 0; c1 < extra[idx]; ++c1)
-                                      if (n[c1] != extra[1 + c1])
-                                        break;
-
-                                    if (c1 == extra[idx])
-                                      goto matched;
-# endif
-                                  }
-
-                                /* Get the collation sequence value.  */
-                                is_seqval = true;
-# ifdef WIDE_CHAR_VERSION
-                                cold = wextra[1 + wextra[idx]];
-# else
-                                /* Adjust for the alignment.  */
-                                idx += 1 + extra[idx];
-                                idx = (idx + 3) & ~4;
-                                cold = *((int32_t *) &extra[idx]);
-# endif
-
-                                c = *p++;
-                              }
-                            else if (c1 == 1)
-                              {
-                                /* No valid character.  Match it as a
-                                   single byte.  */
-                                if (!is_range && *n == str[0])
-                                  goto matched;
-
-                                cold = str[0];
-                                c = *p++;
-                              }
-                            else
-                              return FNM_NOMATCH;
-                          }
-                      }
-                    else
-# undef str
-#endif
-                      {
-                        c = FOLD (c);
-                      normal_bracket:
-
-                        /* We have to handling the symbols differently in
-                           ranges since then the collation sequence is
-                           important.  */
-                        is_range = (*p == L_('-') && p[1] != L_('\0')
-                                    && p[1] != L_(']'));
-
-                        if (!is_range && c == fn)
-                          goto matched;
-
-#if _LIBC
-                        /* This is needed if we goto normal_bracket; from
-                           outside of is_seqval's scope.  */
-                        is_seqval = false;
-#endif
-
-                        cold = c;
-                        c = *p++;
-                      }
-
-                    if (c == L_('-') && *p != L_(']'))
-                      {
-#if _LIBC
-                        /* We have to find the collation sequence
-                           value for C.  Collation sequence is nothing
-                           we can regularly access.  The sequence
-                           value is defined by the order in which the
-                           definitions of the collation values for the
-                           various characters appear in the source
-                           file.  A strange concept, nowhere
-                           documented.  */
-                        uint32_t fcollseq;
-                        uint32_t lcollseq;
-                        UCHAR cend = *p++;
-
-# ifdef WIDE_CHAR_VERSION
-                        /* Search in the `names' array for the characters.  */
-                        fcollseq = __collseq_table_lookup (collseq, fn);
-                        if (fcollseq == ~((uint32_t) 0))
-                          /* XXX We don't know anything about the character
-                             we are supposed to match.  This means we are
-                             failing.  */
-                          goto range_not_matched;
-
-                        if (is_seqval)
-                          lcollseq = cold;
-                        else
-                          lcollseq = __collseq_table_lookup (collseq, cold);
-# else
-                        fcollseq = collseq[fn];
-                        lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
-# endif
-
-                        is_seqval = false;
-                        if (cend == L_('[') && *p == L_('.'))
-                          {
-                            uint32_t nrules =
-                              _NL_CURRENT_WORD (LC_COLLATE,
-                                                _NL_COLLATE_NRULES);
-                            const CHAR *startp = p;
-                            size_t c1 = 0;
-
-                            while (1)
-                              {
-                                c = *++p;
-                                if (c == L_('.') && p[1] == L_(']'))
-                                  {
-                                    p += 2;
-                                    break;
-                                  }
-                                if (c == '\0')
-                                  return FNM_NOMATCH;
-                                ++c1;
-                              }
-
-                            if (nrules == 0)
-                              {
-                                /* There are no names defined in the
-                                   collation data.  Therefore we only
-                                   accept the trivial names consisting
-                                   of the character itself.  */
-                                if (c1 != 1)
-                                  return FNM_NOMATCH;
-
-                                cend = startp[1];
-                              }
-                            else
-                              {
-                                int32_t table_size;
-                                const int32_t *symb_table;
-# ifdef WIDE_CHAR_VERSION
-                                char str[c1];
-                                size_t strcnt;
-# else
-#  define str (startp + 1)
-# endif
-                                const unsigned char *extra;
-                                int32_t idx;
-                                int32_t elem;
-                                int32_t second;
-                                int32_t hash;
-
-# ifdef WIDE_CHAR_VERSION
-                                /* We have to convert the name to a single-byte
-                                   string.  This is possible since the names
-                                   consist of ASCII characters and the internal
-                                   representation is UCS4.  */
-                                for (strcnt = 0; strcnt < c1; ++strcnt)
-                                  str[strcnt] = startp[1 + strcnt];
-# endif
-
-                                table_size =
-                                  _NL_CURRENT_WORD (LC_COLLATE,
-                                                    _NL_COLLATE_SYMB_HASH_SIZEMB);
-                                symb_table = (const int32_t *)
-                                  _NL_CURRENT (LC_COLLATE,
-                                               _NL_COLLATE_SYMB_TABLEMB);
-                                extra = (const unsigned char *)
-                                  _NL_CURRENT (LC_COLLATE,
-                                               _NL_COLLATE_SYMB_EXTRAMB);
-
-                                /* Locate the character in the hashing
-                                   table.  */
-                                hash = elem_hash (str, c1);
-
-                                idx = 0;
-                                elem = hash % table_size;
-                                if (symb_table[2 * elem] != 0)
-                                  {
-                                    second = hash % (table_size - 2) + 1;
-
-                                    do
-                                      {
-                                        /* First compare the hashing value.  */
-                                        if (symb_table[2 * elem] == hash
-                                            && (c1
-                                                == extra[symb_table[2 * elem + 1]])
-                                            && memcmp (str,
-                                                       &extra[symb_table[2 * elem + 1]
-                                                              + 1], c1) == 0)
-                                          {
-                                            /* Yep, this is the entry.  */
-                                            idx = symb_table[2 * elem + 1];
-                                            idx += 1 + extra[idx];
-                                            break;
-                                          }
-
-                                        /* Next entry.  */
-                                        elem += second;
-                                      }
-                                    while (symb_table[2 * elem] != 0);
-                                  }
-
-                                if (symb_table[2 * elem] != 0)
-                                  {
-                                    /* Compare the byte sequence but only if
-                                       this is not part of a range.  */
-# ifdef WIDE_CHAR_VERSION
-                                    int32_t *wextra;
-
-                                    idx += 1 + extra[idx];
-                                    /* Adjust for the alignment.  */
-                                    idx = (idx + 3) & ~4;
-
-                                    wextra = (int32_t *) &extra[idx + 4];
-# endif
-                                    /* Get the collation sequence value.  */
-                                    is_seqval = true;
-# ifdef WIDE_CHAR_VERSION
-                                    cend = wextra[1 + wextra[idx]];
-# else
-                                    /* Adjust for the alignment.  */
-                                    idx += 1 + extra[idx];
-                                    idx = (idx + 3) & ~4;
-                                    cend = *((int32_t *) &extra[idx]);
-# endif
-                                  }
-                                else if (symb_table[2 * elem] != 0 && c1 == 1)
-                                  {
-                                    cend = str[0];
-                                    c = *p++;
-                                  }
-                                else
-                                  return FNM_NOMATCH;
-                              }
-# undef str
-                          }
-                        else
-                          {
-                            if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
-                              cend = *p++;
-                            if (cend == L_('\0'))
-                              return FNM_NOMATCH;
-                            cend = FOLD (cend);
-                          }
-
-                        /* XXX It is not entirely clear to me how to handle
-                           characters which are not mentioned in the
-                           collation specification.  */
-                        if (
-# ifdef WIDE_CHAR_VERSION
-                            lcollseq == 0xffffffff ||
-# endif
-                            lcollseq <= fcollseq)
-                          {
-                            /* We have to look at the upper bound.  */
-                            uint32_t hcollseq;
-
-                            if (is_seqval)
-                              hcollseq = cend;
-                            else
-                              {
-# ifdef WIDE_CHAR_VERSION
-                                hcollseq =
-                                  __collseq_table_lookup (collseq, cend);
-                                if (hcollseq == ~((uint32_t) 0))
-                                  {
-                                    /* Hum, no information about the upper
-                                       bound.  The matching succeeds if the
-                                       lower bound is matched exactly.  */
-                                    if (lcollseq != fcollseq)
-                                      goto range_not_matched;
-
-                                    goto matched;
-                                  }
-# else
-                                hcollseq = collseq[cend];
-# endif
-                              }
-
-                            if (lcollseq <= hcollseq && fcollseq <= hcollseq)
-                              goto matched;
-                          }
-# ifdef WIDE_CHAR_VERSION
-                      range_not_matched:
-# endif
-#else
-                        /* We use a boring value comparison of the character
-                           values.  This is better than comparing using
-                           `strcoll' since the latter would have surprising
-                           and sometimes fatal consequences.  */
-                        UCHAR cend = *p++;
-
-                        if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
-                          cend = *p++;
-                        if (cend == L_('\0'))
-                          return FNM_NOMATCH;
-
-                        /* It is a range.  */
-                        if (cold <= fn && fn <= cend)
-                          goto matched;
-#endif
-
-                        c = *p++;
-                      }
-                  }
-
-                if (c == L_(']'))
-                  break;
-              }
-
-            if (!not)
-              return FNM_NOMATCH;
-            break;
-
-          matched:
-            /* Skip the rest of the [...] that already matched.  */
-            do
-              {
-              ignore_next:
-                c = *p++;
-
-                if (c == L_('\0'))
-                  /* [... (unterminated) loses.  */
-                  return FNM_NOMATCH;
-
-                if (!(flags & FNM_NOESCAPE) && c == L_('\\'))
-                  {
-                    if (*p == L_('\0'))
-                      return FNM_NOMATCH;
-                    /* XXX 1003.2d11 is unclear if this is right.  */
-                    ++p;
-                  }
-                else if (c == L_('[') && *p == L_(':'))
-                  {
-                    int c1 = 0;
-                    const CHAR *startp = p;
-
-                    while (1)
-                      {
-                        c = *++p;
-                        if (++c1 == CHAR_CLASS_MAX_LENGTH)
-                          return FNM_NOMATCH;
-
-                        if (*p == L_(':') && p[1] == L_(']'))
-                          break;
-
-                        if (c < L_('a') || c >= L_('z'))
-                          {
-                            p = startp;
-                            goto ignore_next;
-                          }
-                      }
-                    p += 2;
-                    c = *p++;
-                  }
-                else if (c == L_('[') && *p == L_('='))
-                  {
-                    c = *++p;
-                    if (c == L_('\0'))
-                      return FNM_NOMATCH;
-                    c = *++p;
-                    if (c != L_('=') || p[1] != L_(']'))
-                      return FNM_NOMATCH;
-                    p += 2;
-                    c = *p++;
-                  }
-                else if (c == L_('[') && *p == L_('.'))
-                  {
-                    ++p;
-                    while (1)
-                      {
-                        c = *++p;
-                        if (c == '\0')
-                          return FNM_NOMATCH;
-
-                        if (*p == L_('.') && p[1] == L_(']'))
-                          break;
-                      }
-                    p += 2;
-                    c = *p++;
-                  }
-              }
-            while (c != L_(']'));
-            if (not)
-              return FNM_NOMATCH;
-          }
-          break;
-
-        case L_('+'):
-        case L_('@'):
-        case L_('!'):
-          if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
-            {
-              int res;
-
-              res = EXT (c, p, n, string_end, no_leading_period, flags);
-              if (res != -1)
-                return res;
-            }
-          goto normal_match;
-
-        case L_('/'):
-          if (NO_LEADING_PERIOD (flags))
-            {
-              if (n == string_end || c != (UCHAR) *n)
-                return FNM_NOMATCH;
-
-              new_no_leading_period = true;
-              break;
-            }
-          /* FALLTHROUGH */
-        default:
-        normal_match:
-          if (n == string_end || c != FOLD ((UCHAR) *n))
-            return FNM_NOMATCH;
-        }
-
-      no_leading_period = new_no_leading_period;
-      ++n;
-    }
-
-  if (n == string_end)
-    return 0;
-
-  if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L_('/'))
-    /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
-    return 0;
-
-  return FNM_NOMATCH;
-}
-
-
-static const CHAR *
-internal_function
-END (const CHAR *pattern)
-{
-  const CHAR *p = pattern;
-
-  while (1)
-    if (*++p == L_('\0'))
-      /* This is an invalid pattern.  */
-      return pattern;
-    else if (*p == L_('['))
-      {
-        /* Handle brackets special.  */
-        if (posixly_correct == 0)
-          posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
-
-        /* Skip the not sign.  We have to recognize it because of a possibly
-           following ']'.  */
-        if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
-          ++p;
-        /* A leading ']' is recognized as such.  */
-        if (*p == L_(']'))
-          ++p;
-        /* Skip over all characters of the list.  */
-        while (*p != L_(']'))
-          if (*p++ == L_('\0'))
-            /* This is no valid pattern.  */
-            return pattern;
-      }
-    else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
-              || *p == L_('!')) && p[1] == L_('('))
-      p = END (p + 1);
-    else if (*p == L_(')'))
-      break;
-
-  return p + 1;
-}
-
-
-static int
-internal_function
-EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
-     bool no_leading_period, int flags)
-{
-  const CHAR *startp;
-  size_t level;
-  struct patternlist
-  {
-    struct patternlist *next;
-    CHAR str[1];
-  } *list = NULL;
-  struct patternlist **lastp = &list;
-  size_t pattern_len = STRLEN (pattern);
-  const CHAR *p;
-  const CHAR *rs;
-  enum { ALLOCA_LIMIT = 8000 };
-
-  /* Parse the pattern.  Store the individual parts in the list.  */
-  level = 0;
-  for (startp = p = pattern + 1; ; ++p)
-    if (*p == L_('\0'))
-      /* This is an invalid pattern.  */
-      return -1;
-    else if (*p == L_('['))
-      {
-        /* Handle brackets special.  */
-        if (posixly_correct == 0)
-          posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
-
-        /* Skip the not sign.  We have to recognize it because of a possibly
-           following ']'.  */
-        if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
-          ++p;
-        /* A leading ']' is recognized as such.  */
-        if (*p == L_(']'))
-          ++p;
-        /* Skip over all characters of the list.  */
-        while (*p != L_(']'))
-          if (*p++ == L_('\0'))
-            /* This is no valid pattern.  */
-            return -1;
-      }
-    else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
-              || *p == L_('!')) && p[1] == L_('('))
-      /* Remember the nesting level.  */
-      ++level;
-    else if (*p == L_(')'))
-      {
-        if (level-- == 0)
-          {
-            /* This means we found the end of the pattern.  */
-#define NEW_PATTERN \
-            struct patternlist *newp;                                         \
-            size_t plen;                                                      \
-            size_t plensize;                                                  \
-            size_t newpsize;                                                  \
-                                                                              \
-            plen = (opt == L_('?') || opt == L_('@')                          \
-                    ? pattern_len                                             \
-                    : p - startp + 1UL);                                      \
-            plensize = plen * sizeof (CHAR);                                  \
-            newpsize = offsetof (struct patternlist, str) + plensize;         \
-            if ((size_t) -1 / sizeof (CHAR) < plen                            \
-                || newpsize < offsetof (struct patternlist, str)              \
-                || ALLOCA_LIMIT <= newpsize)                                  \
-              return -1;                                                      \
-            newp = (struct patternlist *) alloca (newpsize);                  \
-            *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0');    \
-            newp->next = NULL;                                                \
-            *lastp = newp;                                                    \
-            lastp = &newp->next
-            NEW_PATTERN;
-            break;
-          }
-      }
-    else if (*p == L_('|'))
-      {
-        if (level == 0)
-          {
-            NEW_PATTERN;
-            startp = p + 1;
-          }
-      }
-  assert (list != NULL);
-  assert (p[-1] == L_(')'));
-#undef NEW_PATTERN
-
-  switch (opt)
-    {
-    case L_('*'):
-      if (FCT (p, string, string_end, no_leading_period, flags) == 0)
-        return 0;
-      /* FALLTHROUGH */
-
-    case L_('+'):
-      do
-        {
-          for (rs = string; rs <= string_end; ++rs)
-            /* First match the prefix with the current pattern with the
-               current pattern.  */
-            if (FCT (list->str, string, rs, no_leading_period,
-                     flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0
-                /* This was successful.  Now match the rest with the rest
-                   of the pattern.  */
-                && (FCT (p, rs, string_end,
-                         rs == string
-                         ? no_leading_period
-                         : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
-                         flags & FNM_FILE_NAME
-                         ? flags : flags & ~FNM_PERIOD) == 0
-                    /* This didn't work.  Try the whole pattern.  */
-                    || (rs != string
-                        && FCT (pattern - 1, rs, string_end,
-                                rs == string
-                                ? no_leading_period
-                                : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
-                                flags & FNM_FILE_NAME
-                                ? flags : flags & ~FNM_PERIOD) == 0)))
-              /* It worked.  Signal success.  */
-              return 0;
-        }
-      while ((list = list->next) != NULL);
-
-      /* None of the patterns lead to a match.  */
-      return FNM_NOMATCH;
-
-    case L_('?'):
-      if (FCT (p, string, string_end, no_leading_period, flags) == 0)
-        return 0;
-      /* FALLTHROUGH */
-
-    case L_('@'):
-      do
-        /* I cannot believe it but `strcat' is actually acceptable
-           here.  Match the entire string with the prefix from the
-           pattern list and the rest of the pattern following the
-           pattern list.  */
-        if (FCT (STRCAT (list->str, p), string, string_end,
-                 no_leading_period,
-                 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
-          /* It worked.  Signal success.  */
-          return 0;
-      while ((list = list->next) != NULL);
-
-      /* None of the patterns lead to a match.  */
-      return FNM_NOMATCH;
-
-    case L_('!'):
-      for (rs = string; rs <= string_end; ++rs)
-        {
-          struct patternlist *runp;
-
-          for (runp = list; runp != NULL; runp = runp->next)
-            if (FCT (runp->str, string, rs,  no_leading_period,
-                     flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
-              break;
-
-          /* If none of the patterns matched see whether the rest does.  */
-          if (runp == NULL
-              && (FCT (p, rs, string_end,
-                       rs == string
-                       ? no_leading_period
-                       : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
-                       flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD)
-                  == 0))
-            /* This is successful.  */
-            return 0;
-        }
-
-      /* None of the patterns together with the rest of the pattern
-         lead to a match.  */
-      return FNM_NOMATCH;
-
-    default:
-      assert (! "Invalid extended matching operator");
-      break;
-    }
-
-  return -1;
-}
-
-
-#undef FOLD
-#undef CHAR
-#undef UCHAR
-#undef INT
-#undef FCT
-#undef EXT
-#undef END
-#undef MEMPCPY
-#undef MEMCHR
-#undef STRCOLL
-#undef STRLEN
-#undef STRCAT
-#undef L_
-#undef BTOWC
diff --git a/gnulib/getdelim.c b/gnulib/getdelim.c
deleted file mode 100644 (file)
index c024090..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/* getdelim.c --- Implementation of replacement getdelim function.
-   Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006, 2007, 2008,
-   2009, 2010 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
-
-/* Ported from glibc by Simon Josefsson. */
-
-#include <config.h>
-
-/* Don't use __attribute__ __nonnull__ in this compilation unit.  Otherwise gcc
-   optimizes away the lineptr == NULL || n == NULL || fp == NULL tests below.  */
-#define _GL_ARG_NONNULL(params)
-
-#include <stdio.h>
-
-#include <limits.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#ifndef SSIZE_MAX
-# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
-#endif
-
-#if USE_UNLOCKED_IO
-# include "unlocked-io.h"
-# define getc_maybe_unlocked(fp)        getc(fp)
-#elif !HAVE_FLOCKFILE || !HAVE_FUNLOCKFILE || !HAVE_DECL_GETC_UNLOCKED
-# undef flockfile
-# undef funlockfile
-# define flockfile(x) ((void) 0)
-# define funlockfile(x) ((void) 0)
-# define getc_maybe_unlocked(fp)        getc(fp)
-#else
-# define getc_maybe_unlocked(fp)        getc_unlocked(fp)
-#endif
-
-/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and
-   NUL-terminate it).  *LINEPTR is a pointer returned from malloc (or
-   NULL), pointing to *N characters of space.  It is realloc'ed as
-   necessary.  Returns the number of characters read (not including
-   the null terminator), or -1 on error or EOF.  */
-
-ssize_t
-getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
-{
-  ssize_t result;
-  size_t cur_len = 0;
-
-  if (lineptr == NULL || n == NULL || fp == NULL)
-    {
-      errno = EINVAL;
-      return -1;
-    }
-
-  flockfile (fp);
-
-  if (*lineptr == NULL || *n == 0)
-    {
-      char *new_lineptr;
-      *n = 120;
-      new_lineptr = (char *) realloc (*lineptr, *n);
-      if (new_lineptr == NULL)
-        {
-          result = -1;
-          goto unlock_return;
-        }
-      *lineptr = new_lineptr;
-    }
-
-  for (;;)
-    {
-      int i;
-
-      i = getc_maybe_unlocked (fp);
-      if (i == EOF)
-        {
-          result = -1;
-          break;
-        }
-
-      /* Make enough space for len+1 (for final NUL) bytes.  */
-      if (cur_len + 1 >= *n)
-        {
-          size_t needed_max =
-            SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
-          size_t needed = 2 * *n + 1;   /* Be generous. */
-          char *new_lineptr;
-
-          if (needed_max < needed)
-            needed = needed_max;
-          if (cur_len + 1 >= needed)
-            {
-              result = -1;
-              errno = EOVERFLOW;
-              goto unlock_return;
-            }
-
-          new_lineptr = (char *) realloc (*lineptr, needed);
-          if (new_lineptr == NULL)
-            {
-              result = -1;
-              goto unlock_return;
-            }
-
-          *lineptr = new_lineptr;
-          *n = needed;
-        }
-
-      (*lineptr)[cur_len] = i;
-      cur_len++;
-
-      if (i == delimiter)
-        break;
-    }
-  (*lineptr)[cur_len] = '\0';
-  result = cur_len ? cur_len : result;
-
- unlock_return:
-  funlockfile (fp); /* doesn't set errno */
-
-  return result;
-}
diff --git a/gnulib/getline.c b/gnulib/getline.c
deleted file mode 100644 (file)
index 6cf187b..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* getline.c --- Implementation of replacement getline function.
-   Copyright (C) 2005, 2006, 2007, 2009, 2010 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
-
-/* Written by Simon Josefsson. */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <sys/types.h>
-
-ssize_t
-getline (char **lineptr, size_t *n, FILE *stream)
-{
-  return getdelim (lineptr, n, '\n', stream);
-}
diff --git a/gnulib/getopt.c b/gnulib/getopt.c
deleted file mode 100644 (file)
index aaabc8d..0000000
+++ /dev/null
@@ -1,1185 +0,0 @@
-/* Getopt for GNU.
-   NOTE: getopt is part of the C library, so if you don't know what
-   "Keep this file name-space clean" means, talk to drepper@gnu.org
-   before changing it!
-   Copyright (C) 1987-1996, 1998-2004, 2006, 2008-2010 Free Software
-   Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-\f
-#ifndef _LIBC
-# include <config.h>
-#endif
-
-#include "getopt.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#ifdef _LIBC
-# include <libintl.h>
-#else
-# include "gettext.h"
-# define _(msgid) gettext (msgid)
-#endif
-
-#if defined _LIBC && defined USE_IN_LIBIO
-# include <wchar.h>
-#endif
-
-/* This version of `getopt' appears to the caller like standard Unix `getopt'
-   but it behaves differently for the user, since it allows the user
-   to intersperse the options with the other arguments.
-
-   As `getopt_long' works, it permutes the elements of ARGV so that,
-   when it is done, all the options precede everything else.  Thus
-   all application programs are extended to handle flexible argument order.
-
-   Using `getopt' or setting the environment variable POSIXLY_CORRECT
-   disables permutation.
-   Then the behavior is completely standard.
-
-   GNU application programs can use a third alternative mode in which
-   they can distinguish the relative order of options and other arguments.  */
-
-#include "getopt_int.h"
-
-/* For communication from `getopt' to the caller.
-   When `getopt' finds an option that takes an argument,
-   the argument value is returned here.
-   Also, when `ordering' is RETURN_IN_ORDER,
-   each non-option ARGV-element is returned here.  */
-
-char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
-   This is used for communication to and from the caller
-   and for communication between successive calls to `getopt'.
-
-   On entry to `getopt', zero means this is the first call; initialize.
-
-   When `getopt' returns -1, this is the index of the first of the
-   non-option elements that the caller should itself scan.
-
-   Otherwise, `optind' communicates from one call to the next
-   how much of ARGV has been scanned so far.  */
-
-/* 1003.2 says this must be 1 before any call.  */
-int optind = 1;
-
-/* Callers store zero here to inhibit the error message
-   for unrecognized options.  */
-
-int opterr = 1;
-
-/* Set to an option character which was unrecognized.
-   This must be initialized on some systems to avoid linking in the
-   system's own getopt implementation.  */
-
-int optopt = '?';
-
-/* Keep a global copy of all internal members of getopt_data.  */
-
-static struct _getopt_data getopt_data;
-
-\f
-#if defined HAVE_DECL_GETENV && !HAVE_DECL_GETENV
-extern char *getenv ();
-#endif
-\f
-#ifdef _LIBC
-/* Stored original parameters.
-   XXX This is no good solution.  We should rather copy the args so
-   that we can compare them later.  But we must not use malloc(3).  */
-extern int __libc_argc;
-extern char **__libc_argv;
-
-/* Bash 2.0 gives us an environment variable containing flags
-   indicating ARGV elements that should not be considered arguments.  */
-
-# ifdef USE_NONOPTION_FLAGS
-/* Defined in getopt_init.c  */
-extern char *__getopt_nonoption_flags;
-# endif
-
-# ifdef USE_NONOPTION_FLAGS
-#  define SWAP_FLAGS(ch1, ch2) \
-  if (d->__nonoption_flags_len > 0)                                           \
-    {                                                                         \
-      char __tmp = __getopt_nonoption_flags[ch1];                             \
-      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];          \
-      __getopt_nonoption_flags[ch2] = __tmp;                                  \
-    }
-# else
-#  define SWAP_FLAGS(ch1, ch2)
-# endif
-#else   /* !_LIBC */
-# define SWAP_FLAGS(ch1, ch2)
-#endif  /* _LIBC */
-
-/* Exchange two adjacent subsequences of ARGV.
-   One subsequence is elements [first_nonopt,last_nonopt)
-   which contains all the non-options that have been skipped so far.
-   The other is elements [last_nonopt,optind), which contains all
-   the options processed since those non-options were skipped.
-
-   `first_nonopt' and `last_nonopt' are relocated so that they describe
-   the new indices of the non-options in ARGV after they are moved.  */
-
-static void
-exchange (char **argv, struct _getopt_data *d)
-{
-  int bottom = d->__first_nonopt;
-  int middle = d->__last_nonopt;
-  int top = d->optind;
-  char *tem;
-
-  /* Exchange the shorter segment with the far end of the longer segment.
-     That puts the shorter segment into the right place.
-     It leaves the longer segment in the right place overall,
-     but it consists of two parts that need to be swapped next.  */
-
-#if defined _LIBC && defined USE_NONOPTION_FLAGS
-  /* First make sure the handling of the `__getopt_nonoption_flags'
-     string can work normally.  Our top argument must be in the range
-     of the string.  */
-  if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len)
-    {
-      /* We must extend the array.  The user plays games with us and
-         presents new arguments.  */
-      char *new_str = malloc (top + 1);
-      if (new_str == NULL)
-        d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0;
-      else
-        {
-          memset (__mempcpy (new_str, __getopt_nonoption_flags,
-                             d->__nonoption_flags_max_len),
-                  '\0', top + 1 - d->__nonoption_flags_max_len);
-          d->__nonoption_flags_max_len = top + 1;
-          __getopt_nonoption_flags = new_str;
-        }
-    }
-#endif
-
-  while (top > middle && middle > bottom)
-    {
-      if (top - middle > middle - bottom)
-        {
-          /* Bottom segment is the short one.  */
-          int len = middle - bottom;
-          register int i;
-
-          /* Swap it with the top part of the top segment.  */
-          for (i = 0; i < len; i++)
-            {
-              tem = argv[bottom + i];
-              argv[bottom + i] = argv[top - (middle - bottom) + i];
-              argv[top - (middle - bottom) + i] = tem;
-              SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
-            }
-          /* Exclude the moved bottom segment from further swapping.  */
-          top -= len;
-        }
-      else
-        {
-          /* Top segment is the short one.  */
-          int len = top - middle;
-          register int i;
-
-          /* Swap it with the bottom part of the bottom segment.  */
-          for (i = 0; i < len; i++)
-            {
-              tem = argv[bottom + i];
-              argv[bottom + i] = argv[middle + i];
-              argv[middle + i] = tem;
-              SWAP_FLAGS (bottom + i, middle + i);
-            }
-          /* Exclude the moved top segment from further swapping.  */
-          bottom += len;
-        }
-    }
-
-  /* Update records for the slots the non-options now occupy.  */
-
-  d->__first_nonopt += (d->optind - d->__last_nonopt);
-  d->__last_nonopt = d->optind;
-}
-
-/* Initialize the internal data when the first call is made.  */
-
-static const char *
-_getopt_initialize (int argc _GL_UNUSED,
-                    char **argv _GL_UNUSED, const char *optstring,
-                    struct _getopt_data *d, int posixly_correct)
-{
-  /* Start processing options with ARGV-element 1 (since ARGV-element 0
-     is the program name); the sequence of previously skipped
-     non-option ARGV-elements is empty.  */
-
-  d->__first_nonopt = d->__last_nonopt = d->optind;
-
-  d->__nextchar = NULL;
-
-  d->__posixly_correct = posixly_correct || !!getenv ("POSIXLY_CORRECT");
-
-  /* Determine how to handle the ordering of options and nonoptions.  */
-
-  if (optstring[0] == '-')
-    {
-      d->__ordering = RETURN_IN_ORDER;
-      ++optstring;
-    }
-  else if (optstring[0] == '+')
-    {
-      d->__ordering = REQUIRE_ORDER;
-      ++optstring;
-    }
-  else if (d->__posixly_correct)
-    d->__ordering = REQUIRE_ORDER;
-  else
-    d->__ordering = PERMUTE;
-
-#if defined _LIBC && defined USE_NONOPTION_FLAGS
-  if (!d->__posixly_correct
-      && argc == __libc_argc && argv == __libc_argv)
-    {
-      if (d->__nonoption_flags_max_len == 0)
-        {
-          if (__getopt_nonoption_flags == NULL
-              || __getopt_nonoption_flags[0] == '\0')
-            d->__nonoption_flags_max_len = -1;
-          else
-            {
-              const char *orig_str = __getopt_nonoption_flags;
-              int len = d->__nonoption_flags_max_len = strlen (orig_str);
-              if (d->__nonoption_flags_max_len < argc)
-                d->__nonoption_flags_max_len = argc;
-              __getopt_nonoption_flags =
-                (char *) malloc (d->__nonoption_flags_max_len);
-              if (__getopt_nonoption_flags == NULL)
-                d->__nonoption_flags_max_len = -1;
-              else
-                memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
-                        '\0', d->__nonoption_flags_max_len - len);
-            }
-        }
-      d->__nonoption_flags_len = d->__nonoption_flags_max_len;
-    }
-  else
-    d->__nonoption_flags_len = 0;
-#endif
-
-  return optstring;
-}
-\f
-/* Scan elements of ARGV (whose length is ARGC) for option characters
-   given in OPTSTRING.
-
-   If an element of ARGV starts with '-', and is not exactly "-" or "--",
-   then it is an option element.  The characters of this element
-   (aside from the initial '-') are option characters.  If `getopt'
-   is called repeatedly, it returns successively each of the option characters
-   from each of the option elements.
-
-   If `getopt' finds another option character, it returns that character,
-   updating `optind' and `nextchar' so that the next call to `getopt' can
-   resume the scan with the following option character or ARGV-element.
-
-   If there are no more option characters, `getopt' returns -1.
-   Then `optind' is the index in ARGV of the first ARGV-element
-   that is not an option.  (The ARGV-elements have been permuted
-   so that those that are not options now come last.)
-
-   OPTSTRING is a string containing the legitimate option characters.
-   If an option character is seen that is not listed in OPTSTRING,
-   return '?' after printing an error message.  If you set `opterr' to
-   zero, the error message is suppressed but we still return '?'.
-
-   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
-   so the following text in the same ARGV-element, or the text of the following
-   ARGV-element, is returned in `optarg'.  Two colons mean an option that
-   wants an optional arg; if there is text in the current ARGV-element,
-   it is returned in `optarg', otherwise `optarg' is set to zero.
-
-   If OPTSTRING starts with `-' or `+', it requests different methods of
-   handling the non-option ARGV-elements.
-   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
-
-   Long-named options begin with `--' instead of `-'.
-   Their names may be abbreviated as long as the abbreviation is unique
-   or is an exact match for some defined option.  If they have an
-   argument, it follows the option name in the same ARGV-element, separated
-   from the option name by a `=', or else the in next ARGV-element.
-   When `getopt' finds a long-named option, it returns 0 if that option's
-   `flag' field is nonzero, the value of the option's `val' field
-   if the `flag' field is zero.
-
-   The elements of ARGV aren't really const, because we permute them.
-   But we pretend they're const in the prototype to be compatible
-   with other systems.
-
-   LONGOPTS is a vector of `struct option' terminated by an
-   element containing a name which is zero.
-
-   LONGIND returns the index in LONGOPT of the long-named option found.
-   It is only valid when a long-named option has been found by the most
-   recent call.
-
-   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
-   long-named options.  */
-
-int
-_getopt_internal_r (int argc, char **argv, const char *optstring,
-                    const struct option *longopts, int *longind,
-                    int long_only, struct _getopt_data *d, int posixly_correct)
-{
-  int print_errors = d->opterr;
-  if (optstring[0] == ':')
-    print_errors = 0;
-
-  if (argc < 1)
-    return -1;
-
-  d->optarg = NULL;
-
-  if (d->optind == 0 || !d->__initialized)
-    {
-      if (d->optind == 0)
-        d->optind = 1;  /* Don't scan ARGV[0], the program name.  */
-      optstring = _getopt_initialize (argc, argv, optstring, d,
-                                      posixly_correct);
-      d->__initialized = 1;
-    }
-
-  /* Test whether ARGV[optind] points to a non-option argument.
-     Either it does not have option syntax, or there is an environment flag
-     from the shell indicating it is not an option.  The later information
-     is only used when the used in the GNU libc.  */
-#if defined _LIBC && defined USE_NONOPTION_FLAGS
-# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \
-                      || (d->optind < d->__nonoption_flags_len                \
-                          && __getopt_nonoption_flags[d->optind] == '1'))
-#else
-# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
-#endif
-
-  if (d->__nextchar == NULL || *d->__nextchar == '\0')
-    {
-      /* Advance to the next ARGV-element.  */
-
-      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
-         moved back by the user (who may also have changed the arguments).  */
-      if (d->__last_nonopt > d->optind)
-        d->__last_nonopt = d->optind;
-      if (d->__first_nonopt > d->optind)
-        d->__first_nonopt = d->optind;
-
-      if (d->__ordering == PERMUTE)
-        {
-          /* If we have just processed some options following some non-options,
-             exchange them so that the options come first.  */
-
-          if (d->__first_nonopt != d->__last_nonopt
-              && d->__last_nonopt != d->optind)
-            exchange ((char **) argv, d);
-          else if (d->__last_nonopt != d->optind)
-            d->__first_nonopt = d->optind;
-
-          /* Skip any additional non-options
-             and extend the range of non-options previously skipped.  */
-
-          while (d->optind < argc && NONOPTION_P)
-            d->optind++;
-          d->__last_nonopt = d->optind;
-        }
-
-      /* The special ARGV-element `--' means premature end of options.
-         Skip it like a null option,
-         then exchange with previous non-options as if it were an option,
-         then skip everything else like a non-option.  */
-
-      if (d->optind != argc && !strcmp (argv[d->optind], "--"))
-        {
-          d->optind++;
-
-          if (d->__first_nonopt != d->__last_nonopt
-              && d->__last_nonopt != d->optind)
-            exchange ((char **) argv, d);
-          else if (d->__first_nonopt == d->__last_nonopt)
-            d->__first_nonopt = d->optind;
-          d->__last_nonopt = argc;
-
-          d->optind = argc;
-        }
-
-      /* If we have done all the ARGV-elements, stop the scan
-         and back over any non-options that we skipped and permuted.  */
-
-      if (d->optind == argc)
-        {
-          /* Set the next-arg-index to point at the non-options
-             that we previously skipped, so the caller will digest them.  */
-          if (d->__first_nonopt != d->__last_nonopt)
-            d->optind = d->__first_nonopt;
-          return -1;
-        }
-
-      /* If we have come to a non-option and did not permute it,
-         either stop the scan or describe it to the caller and pass it by.  */
-
-      if (NONOPTION_P)
-        {
-          if (d->__ordering == REQUIRE_ORDER)
-            return -1;
-          d->optarg = argv[d->optind++];
-          return 1;
-        }
-
-      /* We have found another option-ARGV-element.
-         Skip the initial punctuation.  */
-
-      d->__nextchar = (argv[d->optind] + 1
-                  + (longopts != NULL && argv[d->optind][1] == '-'));
-    }
-
-  /* Decode the current option-ARGV-element.  */
-
-  /* Check whether the ARGV-element is a long option.
-
-     If long_only and the ARGV-element has the form "-f", where f is
-     a valid short option, don't consider it an abbreviated form of
-     a long option that starts with f.  Otherwise there would be no
-     way to give the -f short option.
-
-     On the other hand, if there's a long option "fubar" and
-     the ARGV-element is "-fu", do consider that an abbreviation of
-     the long option, just like "--fu", and not "-f" with arg "u".
-
-     This distinction seems to be the most useful approach.  */
-
-  if (longopts != NULL
-      && (argv[d->optind][1] == '-'
-          || (long_only && (argv[d->optind][2]
-                            || !strchr (optstring, argv[d->optind][1])))))
-    {
-      char *nameend;
-      const struct option *p;
-      const struct option *pfound = NULL;
-      int exact = 0;
-      int ambig = 0;
-      int indfound = -1;
-      int option_index;
-
-      for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
-        /* Do nothing.  */ ;
-
-      /* Test all long options for either exact match
-         or abbreviated matches.  */
-      for (p = longopts, option_index = 0; p->name; p++, option_index++)
-        if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
-          {
-            if ((unsigned int) (nameend - d->__nextchar)
-                == (unsigned int) strlen (p->name))
-              {
-                /* Exact match found.  */
-                pfound = p;
-                indfound = option_index;
-                exact = 1;
-                break;
-              }
-            else if (pfound == NULL)
-              {
-                /* First nonexact match found.  */
-                pfound = p;
-                indfound = option_index;
-              }
-            else if (long_only
-                     || pfound->has_arg != p->has_arg
-                     || pfound->flag != p->flag
-                     || pfound->val != p->val)
-              /* Second or later nonexact match found.  */
-              ambig = 1;
-          }
-
-      if (ambig && !exact)
-        {
-          if (print_errors)
-            {
-#if defined _LIBC && defined USE_IN_LIBIO
-              char *buf;
-
-              if (__asprintf (&buf, _("%s: option '%s' is ambiguous\n"),
-                              argv[0], argv[d->optind]) >= 0)
-                {
-                  _IO_flockfile (stderr);
-
-                  int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
-                  ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-
-                  __fxprintf (NULL, "%s", buf);
-
-                  ((_IO_FILE *) stderr)->_flags2 = old_flags2;
-                  _IO_funlockfile (stderr);
-
-                  free (buf);
-                }
-#else
-              fprintf (stderr, _("%s: option '%s' is ambiguous\n"),
-                       argv[0], argv[d->optind]);
-#endif
-            }
-          d->__nextchar += strlen (d->__nextchar);
-          d->optind++;
-          d->optopt = 0;
-          return '?';
-        }
-
-      if (pfound != NULL)
-        {
-          option_index = indfound;
-          d->optind++;
-          if (*nameend)
-            {
-              /* Don't test has_arg with >, because some C compilers don't
-                 allow it to be used on enums.  */
-              if (pfound->has_arg)
-                d->optarg = nameend + 1;
-              else
-                {
-                  if (print_errors)
-                    {
-#if defined _LIBC && defined USE_IN_LIBIO
-                      char *buf;
-                      int n;
-#endif
-
-                      if (argv[d->optind - 1][1] == '-')
-                        {
-                          /* --option */
-#if defined _LIBC && defined USE_IN_LIBIO
-                          n = __asprintf (&buf, _("\
-%s: option '--%s' doesn't allow an argument\n"),
-                                          argv[0], pfound->name);
-#else
-                          fprintf (stderr, _("\
-%s: option '--%s' doesn't allow an argument\n"),
-                                   argv[0], pfound->name);
-#endif
-                        }
-                      else
-                        {
-                          /* +option or -option */
-#if defined _LIBC && defined USE_IN_LIBIO
-                          n = __asprintf (&buf, _("\
-%s: option '%c%s' doesn't allow an argument\n"),
-                                          argv[0], argv[d->optind - 1][0],
-                                          pfound->name);
-#else
-                          fprintf (stderr, _("\
-%s: option '%c%s' doesn't allow an argument\n"),
-                                   argv[0], argv[d->optind - 1][0],
-                                   pfound->name);
-#endif
-                        }
-
-#if defined _LIBC && defined USE_IN_LIBIO
-                      if (n >= 0)
-                        {
-                          _IO_flockfile (stderr);
-
-                          int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
-                          ((_IO_FILE *) stderr)->_flags2
-                            |= _IO_FLAGS2_NOTCANCEL;
-
-                          __fxprintf (NULL, "%s", buf);
-
-                          ((_IO_FILE *) stderr)->_flags2 = old_flags2;
-                          _IO_funlockfile (stderr);
-
-                          free (buf);
-                        }
-#endif
-                    }
-
-                  d->__nextchar += strlen (d->__nextchar);
-
-                  d->optopt = pfound->val;
-                  return '?';
-                }
-            }
-          else if (pfound->has_arg == 1)
-            {
-              if (d->optind < argc)
-                d->optarg = argv[d->optind++];
-              else
-                {
-                  if (print_errors)
-                    {
-#if defined _LIBC && defined USE_IN_LIBIO
-                      char *buf;
-
-                      if (__asprintf (&buf, _("\
-%s: option '%s' requires an argument\n"),
-                                      argv[0], argv[d->optind - 1]) >= 0)
-                        {
-                          _IO_flockfile (stderr);
-
-                          int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
-                          ((_IO_FILE *) stderr)->_flags2
-                            |= _IO_FLAGS2_NOTCANCEL;
-
-                          __fxprintf (NULL, "%s", buf);
-
-                          ((_IO_FILE *) stderr)->_flags2 = old_flags2;
-                          _IO_funlockfile (stderr);
-
-                          free (buf);
-                        }
-#else
-                      fprintf (stderr,
-                               _("%s: option '%s' requires an argument\n"),
-                               argv[0], argv[d->optind - 1]);
-#endif
-                    }
-                  d->__nextchar += strlen (d->__nextchar);
-                  d->optopt = pfound->val;
-                  return optstring[0] == ':' ? ':' : '?';
-                }
-            }
-          d->__nextchar += strlen (d->__nextchar);
-          if (longind != NULL)
-            *longind = option_index;
-          if (pfound->flag)
-            {
-              *(pfound->flag) = pfound->val;
-              return 0;
-            }
-          return pfound->val;
-        }
-
-      /* Can't find it as a long option.  If this is not getopt_long_only,
-         or the option starts with '--' or is not a valid short
-         option, then it's an error.
-         Otherwise interpret it as a short option.  */
-      if (!long_only || argv[d->optind][1] == '-'
-          || strchr (optstring, *d->__nextchar) == NULL)
-        {
-          if (print_errors)
-            {
-#if defined _LIBC && defined USE_IN_LIBIO
-              char *buf;
-              int n;
-#endif
-
-              if (argv[d->optind][1] == '-')
-                {
-                  /* --option */
-#if defined _LIBC && defined USE_IN_LIBIO
-                  n = __asprintf (&buf, _("%s: unrecognized option '--%s'\n"),
-                                  argv[0], d->__nextchar);
-#else
-                  fprintf (stderr, _("%s: unrecognized option '--%s'\n"),
-                           argv[0], d->__nextchar);
-#endif
-                }
-              else
-                {
-                  /* +option or -option */
-#if defined _LIBC && defined USE_IN_LIBIO
-                  n = __asprintf (&buf, _("%s: unrecognized option '%c%s'\n"),
-                                  argv[0], argv[d->optind][0], d->__nextchar);
-#else
-                  fprintf (stderr, _("%s: unrecognized option '%c%s'\n"),
-                           argv[0], argv[d->optind][0], d->__nextchar);
-#endif
-                }
-
-#if defined _LIBC && defined USE_IN_LIBIO
-              if (n >= 0)
-                {
-                  _IO_flockfile (stderr);
-
-                  int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
-                  ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-
-                  __fxprintf (NULL, "%s", buf);
-
-                  ((_IO_FILE *) stderr)->_flags2 = old_flags2;
-                  _IO_funlockfile (stderr);
-
-                  free (buf);
-                }
-#endif
-            }
-          d->__nextchar = (char *) "";
-          d->optind++;
-          d->optopt = 0;
-          return '?';
-        }
-    }
-
-  /* Look at and handle the next short option-character.  */
-
-  {
-    char c = *d->__nextchar++;
-    char *temp = strchr (optstring, c);
-
-    /* Increment `optind' when we start to process its last character.  */
-    if (*d->__nextchar == '\0')
-      ++d->optind;
-
-    if (temp == NULL || c == ':')
-      {
-        if (print_errors)
-          {
-#if defined _LIBC && defined USE_IN_LIBIO
-              char *buf;
-              int n;
-#endif
-
-#if defined _LIBC && defined USE_IN_LIBIO
-              n = __asprintf (&buf, _("%s: invalid option -- '%c'\n"),
-                              argv[0], c);
-#else
-              fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c);
-#endif
-
-#if defined _LIBC && defined USE_IN_LIBIO
-            if (n >= 0)
-              {
-                _IO_flockfile (stderr);
-
-                int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
-                ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-
-                __fxprintf (NULL, "%s", buf);
-
-                ((_IO_FILE *) stderr)->_flags2 = old_flags2;
-                _IO_funlockfile (stderr);
-
-                free (buf);
-              }
-#endif
-          }
-        d->optopt = c;
-        return '?';
-      }
-    /* Convenience. Treat POSIX -W foo same as long option --foo */
-    if (temp[0] == 'W' && temp[1] == ';')
-      {
-        char *nameend;
-        const struct option *p;
-        const struct option *pfound = NULL;
-        int exact = 0;
-        int ambig = 0;
-        int indfound = 0;
-        int option_index;
-
-        /* This is an option that requires an argument.  */
-        if (*d->__nextchar != '\0')
-          {
-            d->optarg = d->__nextchar;
-            /* If we end this ARGV-element by taking the rest as an arg,
-               we must advance to the next element now.  */
-            d->optind++;
-          }
-        else if (d->optind == argc)
-          {
-            if (print_errors)
-              {
-#if defined _LIBC && defined USE_IN_LIBIO
-                char *buf;
-
-                if (__asprintf (&buf,
-                                _("%s: option requires an argument -- '%c'\n"),
-                                argv[0], c) >= 0)
-                  {
-                    _IO_flockfile (stderr);
-
-                    int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
-                    ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-
-                    __fxprintf (NULL, "%s", buf);
-
-                    ((_IO_FILE *) stderr)->_flags2 = old_flags2;
-                    _IO_funlockfile (stderr);
-
-                    free (buf);
-                  }
-#else
-                fprintf (stderr,
-                         _("%s: option requires an argument -- '%c'\n"),
-                         argv[0], c);
-#endif
-              }
-            d->optopt = c;
-            if (optstring[0] == ':')
-              c = ':';
-            else
-              c = '?';
-            return c;
-          }
-        else
-          /* We already incremented `d->optind' once;
-             increment it again when taking next ARGV-elt as argument.  */
-          d->optarg = argv[d->optind++];
-
-        /* optarg is now the argument, see if it's in the
-           table of longopts.  */
-
-        for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '=';
-             nameend++)
-          /* Do nothing.  */ ;
-
-        /* Test all long options for either exact match
-           or abbreviated matches.  */
-        for (p = longopts, option_index = 0; p->name; p++, option_index++)
-          if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
-            {
-              if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name))
-                {
-                  /* Exact match found.  */
-                  pfound = p;
-                  indfound = option_index;
-                  exact = 1;
-                  break;
-                }
-              else if (pfound == NULL)
-                {
-                  /* First nonexact match found.  */
-                  pfound = p;
-                  indfound = option_index;
-                }
-              else
-                /* Second or later nonexact match found.  */
-                ambig = 1;
-            }
-        if (ambig && !exact)
-          {
-            if (print_errors)
-              {
-#if defined _LIBC && defined USE_IN_LIBIO
-                char *buf;
-
-                if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"),
-                                argv[0], argv[d->optind]) >= 0)
-                  {
-                    _IO_flockfile (stderr);
-
-                    int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
-                    ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-
-                    __fxprintf (NULL, "%s", buf);
-
-                    ((_IO_FILE *) stderr)->_flags2 = old_flags2;
-                    _IO_funlockfile (stderr);
-
-                    free (buf);
-                  }
-#else
-                fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"),
-                         argv[0], argv[d->optind]);
-#endif
-              }
-            d->__nextchar += strlen (d->__nextchar);
-            d->optind++;
-            return '?';
-          }
-        if (pfound != NULL)
-          {
-            option_index = indfound;
-            if (*nameend)
-              {
-                /* Don't test has_arg with >, because some C compilers don't
-                   allow it to be used on enums.  */
-                if (pfound->has_arg)
-                  d->optarg = nameend + 1;
-                else
-                  {
-                    if (print_errors)
-                      {
-#if defined _LIBC && defined USE_IN_LIBIO
-                        char *buf;
-
-                        if (__asprintf (&buf, _("\
-%s: option '-W %s' doesn't allow an argument\n"),
-                                        argv[0], pfound->name) >= 0)
-                          {
-                            _IO_flockfile (stderr);
-
-                            int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
-                            ((_IO_FILE *) stderr)->_flags2
-                              |= _IO_FLAGS2_NOTCANCEL;
-
-                            __fxprintf (NULL, "%s", buf);
-
-                            ((_IO_FILE *) stderr)->_flags2 = old_flags2;
-                            _IO_funlockfile (stderr);
-
-                            free (buf);
-                          }
-#else
-                        fprintf (stderr, _("\
-%s: option '-W %s' doesn't allow an argument\n"),
-                                 argv[0], pfound->name);
-#endif
-                      }
-
-                    d->__nextchar += strlen (d->__nextchar);
-                    return '?';
-                  }
-              }
-            else if (pfound->has_arg == 1)
-              {
-                if (d->optind < argc)
-                  d->optarg = argv[d->optind++];
-                else
-                  {
-                    if (print_errors)
-                      {
-#if defined _LIBC && defined USE_IN_LIBIO
-                        char *buf;
-
-                        if (__asprintf (&buf, _("\
-%s: option '%s' requires an argument\n"),
-                                        argv[0], argv[d->optind - 1]) >= 0)
-                          {
-                            _IO_flockfile (stderr);
-
-                            int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
-                            ((_IO_FILE *) stderr)->_flags2
-                              |= _IO_FLAGS2_NOTCANCEL;
-
-                            __fxprintf (NULL, "%s", buf);
-
-                            ((_IO_FILE *) stderr)->_flags2 = old_flags2;
-                            _IO_funlockfile (stderr);
-
-                            free (buf);
-                          }
-#else
-                        fprintf (stderr,
-                                 _("%s: option '%s' requires an argument\n"),
-                                 argv[0], argv[d->optind - 1]);
-#endif
-                      }
-                    d->__nextchar += strlen (d->__nextchar);
-                    return optstring[0] == ':' ? ':' : '?';
-                  }
-              }
-            d->__nextchar += strlen (d->__nextchar);
-            if (longind != NULL)
-              *longind = option_index;
-            if (pfound->flag)
-              {
-                *(pfound->flag) = pfound->val;
-                return 0;
-              }
-            return pfound->val;
-          }
-          d->__nextchar = NULL;
-          return 'W';   /* Let the application handle it.   */
-      }
-    if (temp[1] == ':')
-      {
-        if (temp[2] == ':')
-          {
-            /* This is an option that accepts an argument optionally.  */
-            if (*d->__nextchar != '\0')
-              {
-                d->optarg = d->__nextchar;
-                d->optind++;
-              }
-            else
-              d->optarg = NULL;
-            d->__nextchar = NULL;
-          }
-        else
-          {
-            /* This is an option that requires an argument.  */
-            if (*d->__nextchar != '\0')
-              {
-                d->optarg = d->__nextchar;
-                /* If we end this ARGV-element by taking the rest as an arg,
-                   we must advance to the next element now.  */
-                d->optind++;
-              }
-            else if (d->optind == argc)
-              {
-                if (print_errors)
-                  {
-#if defined _LIBC && defined USE_IN_LIBIO
-                    char *buf;
-
-                    if (__asprintf (&buf, _("\
-%s: option requires an argument -- '%c'\n"),
-                                    argv[0], c) >= 0)
-                      {
-                        _IO_flockfile (stderr);
-
-                        int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
-                        ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-
-                        __fxprintf (NULL, "%s", buf);
-
-                        ((_IO_FILE *) stderr)->_flags2 = old_flags2;
-                        _IO_funlockfile (stderr);
-
-                        free (buf);
-                      }
-#else
-                    fprintf (stderr,
-                             _("%s: option requires an argument -- '%c'\n"),
-                             argv[0], c);
-#endif
-                  }
-                d->optopt = c;
-                if (optstring[0] == ':')
-                  c = ':';
-                else
-                  c = '?';
-              }
-            else
-              /* We already incremented `optind' once;
-                 increment it again when taking next ARGV-elt as argument.  */
-              d->optarg = argv[d->optind++];
-            d->__nextchar = NULL;
-          }
-      }
-    return c;
-  }
-}
-
-int
-_getopt_internal (int argc, char **argv, const char *optstring,
-                  const struct option *longopts, int *longind, int long_only,
-                  int posixly_correct)
-{
-  int result;
-
-  getopt_data.optind = optind;
-  getopt_data.opterr = opterr;
-
-  result = _getopt_internal_r (argc, argv, optstring, longopts,
-                               longind, long_only, &getopt_data,
-                               posixly_correct);
-
-  optind = getopt_data.optind;
-  optarg = getopt_data.optarg;
-  optopt = getopt_data.optopt;
-
-  return result;
-}
-
-/* glibc gets a LSB-compliant getopt.
-   Standalone applications get a POSIX-compliant getopt.  */
-#if _LIBC
-enum { POSIXLY_CORRECT = 0 };
-#else
-enum { POSIXLY_CORRECT = 1 };
-#endif
-
-int
-getopt (int argc, char *const *argv, const char *optstring)
-{
-  return _getopt_internal (argc, (char **) argv, optstring,
-                           (const struct option *) 0,
-                           (int *) 0,
-                           0, POSIXLY_CORRECT);
-}
-
-#ifdef _LIBC
-int
-__posix_getopt (int argc, char *const *argv, const char *optstring)
-{
-  return _getopt_internal (argc, argv, optstring,
-                           (const struct option *) 0,
-                           (int *) 0,
-                           0, 1);
-}
-#endif
-
-\f
-#ifdef TEST
-
-/* Compile with -DTEST to make an executable for use in testing
-   the above definition of `getopt'.  */
-
-int
-main (int argc, char **argv)
-{
-  int c;
-  int digit_optind = 0;
-
-  while (1)
-    {
-      int this_option_optind = optind ? optind : 1;
-
-      c = getopt (argc, argv, "abc:d:0123456789");
-      if (c == -1)
-        break;
-
-      switch (c)
-        {
-        case '0':
-        case '1':
-        case '2':
-        case '3':
-        case '4':
-        case '5':
-        case '6':
-        case '7':
-        case '8':
-        case '9':
-          if (digit_optind != 0 && digit_optind != this_option_optind)
-            printf ("digits occur in two different argv-elements.\n");
-          digit_optind = this_option_optind;
-          printf ("option %c\n", c);
-          break;
-
-        case 'a':
-          printf ("option a\n");
-          break;
-
-        case 'b':
-          printf ("option b\n");
-          break;
-
-        case 'c':
-          printf ("option c with value '%s'\n", optarg);
-          break;
-
-        case '?':
-          break;
-
-        default:
-          printf ("?? getopt returned character code 0%o ??\n", c);
-        }
-    }
-
-  if (optind < argc)
-    {
-      printf ("non-option ARGV-elements: ");
-      while (optind < argc)
-        printf ("%s ", argv[optind++]);
-      printf ("\n");
-    }
-
-  exit (0);
-}
-
-#endif /* TEST */
diff --git a/gnulib/getopt.h b/gnulib/getopt.h
deleted file mode 100644 (file)
index d2d3e6e..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/* Declarations for getopt.
-   Copyright (C) 1989-1994,1996-1999,2001,2003,2004,2005,2006,2007
-   Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef _GETOPT_H
-
-#ifndef __need_getopt
-# define _GETOPT_H 1
-#endif
-
-/* Standalone applications should #define __GETOPT_PREFIX to an
-   identifier that prefixes the external functions and variables
-   defined in this header.  When this happens, include the
-   headers that might declare getopt so that they will not cause
-   confusion if included after this file.  Then systematically rename
-   identifiers so that they do not collide with the system functions
-   and variables.  Renaming avoids problems with some compilers and
-   linkers.  */
-#if defined __GETOPT_PREFIX && !defined __need_getopt
-# include <stdlib.h>
-# include <stdio.h>
-# include <unistd.h>
-# undef __need_getopt
-# undef getopt
-# undef getopt_long
-# undef getopt_long_only
-# undef optarg
-# undef opterr
-# undef optind
-# undef optopt
-# define __GETOPT_CONCAT(x, y) x ## y
-# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y)
-# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y)
-# define getopt __GETOPT_ID (getopt)
-# define getopt_long __GETOPT_ID (getopt_long)
-# define getopt_long_only __GETOPT_ID (getopt_long_only)
-# define optarg __GETOPT_ID (optarg)
-# define opterr __GETOPT_ID (opterr)
-# define optind __GETOPT_ID (optind)
-# define optopt __GETOPT_ID (optopt)
-#endif
-
-/* Standalone applications get correct prototypes for getopt_long and
-   getopt_long_only; they declare "char **argv".  libc uses prototypes
-   with "char *const *argv" that are incorrect because getopt_long and
-   getopt_long_only can permute argv; this is required for backward
-   compatibility (e.g., for LSB 2.0.1).
-
-   This used to be `#if defined __GETOPT_PREFIX && !defined __need_getopt',
-   but it caused redefinition warnings if both unistd.h and getopt.h were
-   included, since unistd.h includes getopt.h having previously defined
-   __need_getopt.
-
-   The only place where __getopt_argv_const is used is in definitions
-   of getopt_long and getopt_long_only below, but these are visible
-   only if __need_getopt is not defined, so it is quite safe to rewrite
-   the conditional as follows:
-*/
-#if !defined __need_getopt
-# if defined __GETOPT_PREFIX
-#  define __getopt_argv_const /* empty */
-# else
-#  define __getopt_argv_const const
-# endif
-#endif
-
-/* If __GNU_LIBRARY__ is not already defined, either we are being used
-   standalone, or this is the first header included in the source file.
-   If we are being used with glibc, we need to include <features.h>, but
-   that does not exist if we are standalone.  So: if __GNU_LIBRARY__ is
-   not defined, include <ctype.h>, which will pull in <features.h> for us
-   if it's from glibc.  (Why ctype.h?  It's guaranteed to exist and it
-   doesn't flood the namespace with stuff the way some other headers do.)  */
-#if !defined __GNU_LIBRARY__
-# include <ctype.h>
-#endif
-
-#ifndef __THROW
-# ifndef __GNUC_PREREQ
-#  define __GNUC_PREREQ(maj, min) (0)
-# endif
-# if defined __cplusplus && __GNUC_PREREQ (2,8)
-#  define __THROW      throw ()
-# else
-#  define __THROW
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* For communication from `getopt' to the caller.
-   When `getopt' finds an option that takes an argument,
-   the argument value is returned here.
-   Also, when `ordering' is RETURN_IN_ORDER,
-   each non-option ARGV-element is returned here.  */
-
-extern char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
-   This is used for communication to and from the caller
-   and for communication between successive calls to `getopt'.
-
-   On entry to `getopt', zero means this is the first call; initialize.
-
-   When `getopt' returns -1, this is the index of the first of the
-   non-option elements that the caller should itself scan.
-
-   Otherwise, `optind' communicates from one call to the next
-   how much of ARGV has been scanned so far.  */
-
-extern int optind;
-
-/* Callers store zero here to inhibit the error message `getopt' prints
-   for unrecognized options.  */
-
-extern int opterr;
-
-/* Set to an option character which was unrecognized.  */
-
-extern int optopt;
-
-#ifndef __need_getopt
-/* Describe the long-named options requested by the application.
-   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
-   of `struct option' terminated by an element containing a name which is
-   zero.
-
-   The field `has_arg' is:
-   no_argument         (or 0) if the option does not take an argument,
-   required_argument   (or 1) if the option requires an argument,
-   optional_argument   (or 2) if the option takes an optional argument.
-
-   If the field `flag' is not NULL, it points to a variable that is set
-   to the value given in the field `val' when the option is found, but
-   left unchanged if the option is not found.
-
-   To have a long-named option do something other than set an `int' to
-   a compiled-in constant, such as set a value from `optarg', set the
-   option's `flag' field to zero and its `val' field to a nonzero
-   value (the equivalent single-letter option character, if there is
-   one).  For long options that have a zero `flag' field, `getopt'
-   returns the contents of the `val' field.  */
-
-struct option
-{
-  const char *name;
-  /* has_arg can't be an enum because some compilers complain about
-     type mismatches in all the code that assumes it is an int.  */
-  int has_arg;
-  int *flag;
-  int val;
-};
-
-/* Names for the values of the `has_arg' field of `struct option'.  */
-
-# define no_argument           0
-# define required_argument     1
-# define optional_argument     2
-#endif /* need getopt */
-
-
-/* Get definitions and prototypes for functions to process the
-   arguments in ARGV (ARGC of them, minus the program name) for
-   options given in OPTS.
-
-   Return the option character from OPTS just read.  Return -1 when
-   there are no more options.  For unrecognized options, or options
-   missing arguments, `optopt' is set to the option letter, and '?' is
-   returned.
-
-   The OPTS string is a list of characters which are recognized option
-   letters, optionally followed by colons, specifying that that letter
-   takes an argument, to be placed in `optarg'.
-
-   If a letter in OPTS is followed by two colons, its argument is
-   optional.  This behavior is specific to the GNU `getopt'.
-
-   The argument `--' causes premature termination of argument
-   scanning, explicitly telling `getopt' that there are no more
-   options.
-
-   If OPTS begins with `-', then non-option arguments are treated as
-   arguments to the option '\1'.  This behavior is specific to the GNU
-   `getopt'.  If OPTS begins with `+', or POSIXLY_CORRECT is set in
-   the environment, then do not permute arguments.  */
-
-extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
-       __THROW;
-
-#ifndef __need_getopt
-extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv,
-                       const char *__shortopts,
-                       const struct option *__longopts, int *__longind)
-       __THROW;
-extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv,
-                            const char *__shortopts,
-                            const struct option *__longopts, int *__longind)
-       __THROW;
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-/* Make sure we later can get all the definitions and declarations.  */
-#undef __need_getopt
-
-#endif /* getopt.h */
diff --git a/gnulib/getopt1.c b/gnulib/getopt1.c
deleted file mode 100644 (file)
index 046d69f..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/* getopt_long and getopt_long_only entry points for GNU getopt.
-   Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997,
-   1998, 2004, 2006, 2009, 2010 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-\f
-#ifdef _LIBC
-# include <getopt.h>
-#else
-# include <config.h>
-# include "getopt.h"
-#endif
-#include "getopt_int.h"
-
-#include <stdio.h>
-
-/* This needs to come after some library #include
-   to get __GNU_LIBRARY__ defined.  */
-#ifdef __GNU_LIBRARY__
-#include <stdlib.h>
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-int
-getopt_long (int argc, char *__getopt_argv_const *argv, const char *options,
-             const struct option *long_options, int *opt_index)
-{
-  return _getopt_internal (argc, (char **) argv, options, long_options,
-                           opt_index, 0, 0);
-}
-
-int
-_getopt_long_r (int argc, char **argv, const char *options,
-                const struct option *long_options, int *opt_index,
-                struct _getopt_data *d)
-{
-  return _getopt_internal_r (argc, argv, options, long_options, opt_index,
-                             0, d, 0);
-}
-
-/* Like getopt_long, but '-' as well as '--' can indicate a long option.
-   If an option that starts with '-' (not '--') doesn't match a long option,
-   but does match a short option, it is parsed as a short option
-   instead.  */
-
-int
-getopt_long_only (int argc, char *__getopt_argv_const *argv,
-                  const char *options,
-                  const struct option *long_options, int *opt_index)
-{
-  return _getopt_internal (argc, (char **) argv, options, long_options,
-                           opt_index, 1, 0);
-}
-
-int
-_getopt_long_only_r (int argc, char **argv, const char *options,
-                     const struct option *long_options, int *opt_index,
-                     struct _getopt_data *d)
-{
-  return _getopt_internal_r (argc, argv, options, long_options, opt_index,
-                             1, d, 0);
-}
-
-\f
-#ifdef TEST
-
-#include <stdio.h>
-
-int
-main (int argc, char **argv)
-{
-  int c;
-  int digit_optind = 0;
-
-  while (1)
-    {
-      int this_option_optind = optind ? optind : 1;
-      int option_index = 0;
-      static const struct option long_options[] =
-      {
-        {"add", 1, 0, 0},
-        {"append", 0, 0, 0},
-        {"delete", 1, 0, 0},
-        {"verbose", 0, 0, 0},
-        {"create", 0, 0, 0},
-        {"file", 1, 0, 0},
-        {0, 0, 0, 0}
-      };
-
-      c = getopt_long (argc, argv, "abc:d:0123456789",
-                       long_options, &option_index);
-      if (c == -1)
-        break;
-
-      switch (c)
-        {
-        case 0:
-          printf ("option %s", long_options[option_index].name);
-          if (optarg)
-            printf (" with arg %s", optarg);
-          printf ("\n");
-          break;
-
-        case '0':
-        case '1':
-        case '2':
-        case '3':
-        case '4':
-        case '5':
-        case '6':
-        case '7':
-        case '8':
-        case '9':
-          if (digit_optind != 0 && digit_optind != this_option_optind)
-            printf ("digits occur in two different argv-elements.\n");
-          digit_optind = this_option_optind;
-          printf ("option %c\n", c);
-          break;
-
-        case 'a':
-          printf ("option a\n");
-          break;
-
-        case 'b':
-          printf ("option b\n");
-          break;
-
-        case 'c':
-          printf ("option c with value `%s'\n", optarg);
-          break;
-
-        case 'd':
-          printf ("option d with value `%s'\n", optarg);
-          break;
-
-        case '?':
-          break;
-
-        default:
-          printf ("?? getopt returned character code 0%o ??\n", c);
-        }
-    }
-
-  if (optind < argc)
-    {
-      printf ("non-option ARGV-elements: ");
-      while (optind < argc)
-        printf ("%s ", argv[optind++]);
-      printf ("\n");
-    }
-
-  exit (0);
-}
-
-#endif /* TEST */
diff --git a/gnulib/getopt_int.h b/gnulib/getopt_int.h
deleted file mode 100644 (file)
index 169def5..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Internal declarations for getopt.
-   Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2004, 2009-2010 Free Software
-   Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef _GETOPT_INT_H
-#define _GETOPT_INT_H   1
-
-#include <getopt.h>
-
-extern int _getopt_internal (int ___argc, char **___argv,
-                             const char *__shortopts,
-                             const struct option *__longopts, int *__longind,
-                             int __long_only, int __posixly_correct);
-
-\f
-/* Reentrant versions which can handle parsing multiple argument
-   vectors at the same time.  */
-
-/* Data type for reentrant functions.  */
-struct _getopt_data
-{
-  /* These have exactly the same meaning as the corresponding global
-     variables, except that they are used for the reentrant
-     versions of getopt.  */
-  int optind;
-  int opterr;
-  int optopt;
-  char *optarg;
-
-  /* Internal members.  */
-
-  /* True if the internal members have been initialized.  */
-  int __initialized;
-
-  /* The next char to be scanned in the option-element
-     in which the last option character we returned was found.
-     This allows us to pick up the scan where we left off.
-
-     If this is zero, or a null string, it means resume the scan
-     by advancing to the next ARGV-element.  */
-  char *__nextchar;
-
-  /* Describe how to deal with options that follow non-option ARGV-elements.
-
-     If the caller did not specify anything,
-     the default is REQUIRE_ORDER if the environment variable
-     POSIXLY_CORRECT is defined, PERMUTE otherwise.
-
-     REQUIRE_ORDER means don't recognize them as options;
-     stop option processing when the first non-option is seen.
-     This is what Unix does.
-     This mode of operation is selected by either setting the environment
-     variable POSIXLY_CORRECT, or using `+' as the first character
-     of the list of option characters, or by calling getopt.
-
-     PERMUTE is the default.  We permute the contents of ARGV as we
-     scan, so that eventually all the non-options are at the end.
-     This allows options to be given in any order, even with programs
-     that were not written to expect this.
-
-     RETURN_IN_ORDER is an option available to programs that were
-     written to expect options and other ARGV-elements in any order
-     and that care about the ordering of the two.  We describe each
-     non-option ARGV-element as if it were the argument of an option
-     with character code 1.  Using `-' as the first character of the
-     list of option characters selects this mode of operation.
-
-     The special argument `--' forces an end of option-scanning regardless
-     of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
-     `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
-
-  enum
-    {
-      REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
-    } __ordering;
-
-  /* If the POSIXLY_CORRECT environment variable is set
-     or getopt was called.  */
-  int __posixly_correct;
-
-
-  /* Handle permutation of arguments.  */
-
-  /* Describe the part of ARGV that contains non-options that have
-     been skipped.  `first_nonopt' is the index in ARGV of the first
-     of them; `last_nonopt' is the index after the last of them.  */
-
-  int __first_nonopt;
-  int __last_nonopt;
-
-#if defined _LIBC && defined USE_NONOPTION_FLAGS
-  int __nonoption_flags_max_len;
-  int __nonoption_flags_len;
-# endif
-};
-
-/* The initializer is necessary to set OPTIND and OPTERR to their
-   default values and to clear the initialization flag.  */
-#define _GETOPT_DATA_INITIALIZER        { 1, 1 }
-
-extern int _getopt_internal_r (int ___argc, char **___argv,
-                               const char *__shortopts,
-                               const struct option *__longopts, int *__longind,
-                               int __long_only, struct _getopt_data *__data,
-                               int __posixly_correct);
-
-extern int _getopt_long_r (int ___argc, char **___argv,
-                           const char *__shortopts,
-                           const struct option *__longopts, int *__longind,
-                           struct _getopt_data *__data);
-
-extern int _getopt_long_only_r (int ___argc, char **___argv,
-                                const char *__shortopts,
-                                const struct option *__longopts,
-                                int *__longind,
-                                struct _getopt_data *__data);
-
-#endif /* getopt_int.h */
diff --git a/gnulib/gettext.h b/gnulib/gettext.h
deleted file mode 100644 (file)
index 6a069c4..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/* Convenience header for conditional use of GNU <libintl.h>.
-   Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2010 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
-
-#ifndef _LIBGETTEXT_H
-#define _LIBGETTEXT_H 1
-
-/* NLS can be disabled through the configure --disable-nls option.  */
-#if ENABLE_NLS
-
-/* Get declarations of GNU message catalog functions.  */
-# include <libintl.h>
-
-/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
-   the gettext() and ngettext() macros.  This is an alternative to calling
-   textdomain(), and is useful for libraries.  */
-# ifdef DEFAULT_TEXT_DOMAIN
-#  undef gettext
-#  define gettext(Msgid) \
-     dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
-#  undef ngettext
-#  define ngettext(Msgid1, Msgid2, N) \
-     dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
-# endif
-
-#else
-
-/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
-   chokes if dcgettext is defined as a macro.  So include it now, to make
-   later inclusions of <locale.h> a NOP.  We don't include <libintl.h>
-   as well because people using "gettext.h" will not include <libintl.h>,
-   and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
-   is OK.  */
-#if defined(__sun)
-# include <locale.h>
-#endif
-
-/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
-   <libintl.h>, which chokes if dcgettext is defined as a macro.  So include
-   it now, to make later inclusions of <libintl.h> a NOP.  */
-#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
-# include <cstdlib>
-# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
-#  include <libintl.h>
-# endif
-#endif
-
-/* Disabled NLS.
-   The casts to 'const char *' serve the purpose of producing warnings
-   for invalid uses of the value returned from these functions.
-   On pre-ANSI systems without 'const', the config.h file is supposed to
-   contain "#define const".  */
-# undef gettext
-# define gettext(Msgid) ((const char *) (Msgid))
-# undef dgettext
-# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
-# undef dcgettext
-# define dcgettext(Domainname, Msgid, Category) \
-    ((void) (Category), dgettext (Domainname, Msgid))
-# undef ngettext
-# define ngettext(Msgid1, Msgid2, N) \
-    ((N) == 1 \
-     ? ((void) (Msgid2), (const char *) (Msgid1)) \
-     : ((void) (Msgid1), (const char *) (Msgid2)))
-# undef dngettext
-# define dngettext(Domainname, Msgid1, Msgid2, N) \
-    ((void) (Domainname), ngettext (Msgid1, Msgid2, N))
-# undef dcngettext
-# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
-    ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N))
-# undef textdomain
-# define textdomain(Domainname) ((const char *) (Domainname))
-# undef bindtextdomain
-# define bindtextdomain(Domainname, Dirname) \
-    ((void) (Domainname), (const char *) (Dirname))
-# undef bind_textdomain_codeset
-# define bind_textdomain_codeset(Domainname, Codeset) \
-    ((void) (Domainname), (const char *) (Codeset))
-
-#endif
-
-/* A pseudo function call that serves as a marker for the automated
-   extraction of messages, but does not call gettext().  The run-time
-   translation is done at a different place in the code.
-   The argument, String, should be a literal string.  Concatenated strings
-   and other string expressions won't work.
-   The macro's expansion is not parenthesized, so that it is suitable as
-   initializer for static 'char[]' or 'const char[]' variables.  */
-#define gettext_noop(String) String
-
-/* The separator between msgctxt and msgid in a .mo file.  */
-#define GETTEXT_CONTEXT_GLUE "\004"
-
-/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
-   MSGID.  MSGCTXT and MSGID must be string literals.  MSGCTXT should be
-   short and rarely need to change.
-   The letter 'p' stands for 'particular' or 'special'.  */
-#ifdef DEFAULT_TEXT_DOMAIN
-# define pgettext(Msgctxt, Msgid) \
-   pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
-#else
-# define pgettext(Msgctxt, Msgid) \
-   pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
-#endif
-#define dpgettext(Domainname, Msgctxt, Msgid) \
-  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
-#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
-  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
-#ifdef DEFAULT_TEXT_DOMAIN
-# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
-   npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
-#else
-# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
-   npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
-#endif
-#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
-  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
-#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
-  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-static const char *
-pgettext_aux (const char *domain,
-              const char *msg_ctxt_id, const char *msgid,
-              int category)
-{
-  const char *translation = dcgettext (domain, msg_ctxt_id, category);
-  if (translation == msg_ctxt_id)
-    return msgid;
-  else
-    return translation;
-}
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-static const char *
-npgettext_aux (const char *domain,
-               const char *msg_ctxt_id, const char *msgid,
-               const char *msgid_plural, unsigned long int n,
-               int category)
-{
-  const char *translation =
-    dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
-  if (translation == msg_ctxt_id || translation == msgid_plural)
-    return (n == 1 ? msgid : msgid_plural);
-  else
-    return translation;
-}
-
-/* The same thing extended for non-constant arguments.  Here MSGCTXT and MSGID
-   can be arbitrary expressions.  But for string literals these macros are
-   less efficient than those above.  */
-
-#include <string.h>
-
-#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
-  (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
-   /* || __STDC_VERSION__ >= 199901L */ )
-
-#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
-#include <stdlib.h>
-#endif
-
-#define pgettext_expr(Msgctxt, Msgid) \
-  dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
-#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
-  dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-static const char *
-dcpgettext_expr (const char *domain,
-                 const char *msgctxt, const char *msgid,
-                 int category)
-{
-  size_t msgctxt_len = strlen (msgctxt) + 1;
-  size_t msgid_len = strlen (msgid) + 1;
-  const char *translation;
-#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
-  char msg_ctxt_id[msgctxt_len + msgid_len];
-#else
-  char buf[1024];
-  char *msg_ctxt_id =
-    (msgctxt_len + msgid_len <= sizeof (buf)
-     ? buf
-     : (char *) malloc (msgctxt_len + msgid_len));
-  if (msg_ctxt_id != NULL)
-#endif
-    {
-      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
-      msg_ctxt_id[msgctxt_len - 1] = '\004';
-      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
-      translation = dcgettext (domain, msg_ctxt_id, category);
-#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
-      if (msg_ctxt_id != buf)
-        free (msg_ctxt_id);
-#endif
-      if (translation != msg_ctxt_id)
-        return translation;
-    }
-  return msgid;
-}
-
-#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
-  dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
-#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
-  dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
-
-#ifdef __GNUC__
-__inline
-#else
-#ifdef __cplusplus
-inline
-#endif
-#endif
-static const char *
-dcnpgettext_expr (const char *domain,
-                  const char *msgctxt, const char *msgid,
-                  const char *msgid_plural, unsigned long int n,
-                  int category)
-{
-  size_t msgctxt_len = strlen (msgctxt) + 1;
-  size_t msgid_len = strlen (msgid) + 1;
-  const char *translation;
-#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
-  char msg_ctxt_id[msgctxt_len + msgid_len];
-#else
-  char buf[1024];
-  char *msg_ctxt_id =
-    (msgctxt_len + msgid_len <= sizeof (buf)
-     ? buf
-     : (char *) malloc (msgctxt_len + msgid_len));
-  if (msg_ctxt_id != NULL)
-#endif
-    {
-      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
-      msg_ctxt_id[msgctxt_len - 1] = '\004';
-      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
-      translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
-#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
-      if (msg_ctxt_id != buf)
-        free (msg_ctxt_id);
-#endif
-      if (!(translation == msg_ctxt_id || translation == msgid_plural))
-        return translation;
-    }
-  return (n == 1 ? msgid : msgid_plural);
-}
-
-#endif /* _LIBGETTEXT_H */
diff --git a/gnulib/progname.c b/gnulib/progname.c
deleted file mode 100644 (file)
index 1415e6a..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Program name management.
-   Copyright (C) 2001-2003, 2005-2010 Free Software Foundation, Inc.
-   Written by Bruno Haible <bruno@clisp.org>, 2001.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-
-#include <config.h>
-
-/* Specification.  */
-#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
-#include "progname.h"
-
-#include <errno.h> /* get program_invocation_name declaration */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-/* String containing name the program is called with.
-   To be initialized by main().  */
-const char *program_name = NULL;
-
-/* Set program_name, based on argv[0].
-   argv0 must be a string allocated with indefinite extent, and must not be
-   modified after this call.  */
-void
-set_program_name (const char *argv0)
-{
-  /* libtool creates a temporary executable whose name is sometimes prefixed
-     with "lt-" (depends on the platform).  It also makes argv[0] absolute.
-     But the name of the temporary executable is a detail that should not be
-     visible to the end user and to the test suite.
-     Remove this "<dirname>/.libs/" or "<dirname>/.libs/lt-" prefix here.  */
-  const char *slash;
-  const char *base;
-
-  /* Sanity check.  POSIX requires the invoking process to pass a non-NULL
-     argv[0].  */
-  if (argv0 == NULL)
-    {
-      /* It's a bug in the invoking program.  Help diagnosing it.  */
-      fputs ("A NULL argv[0] was passed through an exec system call.\n",
-             stderr);
-      abort ();
-    }
-
-  slash = strrchr (argv0, '/');
-  base = (slash != NULL ? slash + 1 : argv0);
-  if (base - argv0 >= 7 && strncmp (base - 7, "/.libs/", 7) == 0)
-    {
-      argv0 = base;
-      if (strncmp (base, "lt-", 3) == 0)
-        {
-          argv0 = base + 3;
-          /* On glibc systems, remove the "lt-" prefix from the variable
-             program_invocation_short_name.  */
-#if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
-          program_invocation_short_name = (char *) argv0;
-#endif
-        }
-    }
-
-  /* But don't strip off a leading <dirname>/ in general, because when the user
-     runs
-         /some/hidden/place/bin/cp foo foo
-     he should get the error message
-         /some/hidden/place/bin/cp: `foo' and `foo' are the same file
-     not
-         cp: `foo' and `foo' are the same file
-   */
-
-  program_name = argv0;
-
-  /* On glibc systems, the error() function comes from libc and uses the
-     variable program_invocation_name, not program_name.  So set this variable
-     as well.  */
-#if HAVE_DECL_PROGRAM_INVOCATION_NAME
-  program_invocation_name = (char *) argv0;
-#endif
-}
diff --git a/gnulib/progname.h b/gnulib/progname.h
deleted file mode 100644 (file)
index 5ba303b..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Program name management.
-   Copyright (C) 2001-2004, 2006, 2009-2010 Free Software Foundation, Inc.
-   Written by Bruno Haible <bruno@clisp.org>, 2001.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef _PROGNAME_H
-#define _PROGNAME_H
-
-/* Programs using this file should do the following in main():
-     set_program_name (argv[0]);
- */
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* String containing name the program is called with.  */
-extern const char *program_name;
-
-/* Set program_name, based on argv[0].
-   argv0 must be a string allocated with indefinite extent, and must not be
-   modified after this call.  */
-extern void set_program_name (const char *argv0);
-
-#if ENABLE_RELOCATABLE
-
-/* Set program_name, based on argv[0], and original installation prefix and
-   directory, for relocatability.  */
-extern void set_program_name_and_installdir (const char *argv0,
-                                             const char *orig_installprefix,
-                                             const char *orig_installdir);
-#undef set_program_name
-#define set_program_name(ARG0) \
-  set_program_name_and_installdir (ARG0, INSTALLPREFIX, INSTALLDIR)
-
-/* Return the full pathname of the current executable, based on the earlier
-   call to set_program_name_and_installdir.  Return NULL if unknown.  */
-extern char *get_full_program_name (void);
-
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* _PROGNAME_H */
diff --git a/gnulib/regcomp.c b/gnulib/regcomp.c
deleted file mode 100644 (file)
index 7eff569..0000000
+++ /dev/null
@@ -1,3877 +0,0 @@
-/* Extended regular expression matching and search library.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
-   Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
-
-   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
-                                         size_t length, reg_syntax_t syntax);
-static void re_compile_fastmap_iter (regex_t *bufp,
-                                    const re_dfastate_t *init_state,
-                                    char *fastmap);
-static reg_errcode_t init_dfa (re_dfa_t *dfa, size_t pat_len);
-#ifdef RE_ENABLE_I18N
-static void free_charset (re_charset_t *cset);
-#endif /* RE_ENABLE_I18N */
-static void free_workarea_compile (regex_t *preg);
-static reg_errcode_t create_initial_state (re_dfa_t *dfa);
-#ifdef RE_ENABLE_I18N
-static void optimize_utf8 (re_dfa_t *dfa);
-#endif
-static reg_errcode_t analyze (regex_t *preg);
-static reg_errcode_t preorder (bin_tree_t *root,
-                              reg_errcode_t (fn (void *, bin_tree_t *)),
-                              void *extra);
-static reg_errcode_t postorder (bin_tree_t *root,
-                               reg_errcode_t (fn (void *, bin_tree_t *)),
-                               void *extra);
-static reg_errcode_t optimize_subexps (void *extra, bin_tree_t *node);
-static reg_errcode_t lower_subexps (void *extra, bin_tree_t *node);
-static bin_tree_t *lower_subexp (reg_errcode_t *err, regex_t *preg,
-                                bin_tree_t *node);
-static reg_errcode_t calc_first (void *extra, bin_tree_t *node);
-static reg_errcode_t calc_next (void *extra, bin_tree_t *node);
-static reg_errcode_t link_nfa_nodes (void *extra, bin_tree_t *node);
-static Idx duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint);
-static Idx search_duplicated_node (const re_dfa_t *dfa, Idx org_node,
-                                  unsigned int constraint);
-static reg_errcode_t calc_eclosure (re_dfa_t *dfa);
-static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa,
-                                        Idx node, bool root);
-static reg_errcode_t calc_inveclosure (re_dfa_t *dfa);
-static Idx fetch_number (re_string_t *input, re_token_t *token,
-                        reg_syntax_t syntax);
-static int peek_token (re_token_t *token, re_string_t *input,
-                       reg_syntax_t syntax) internal_function;
-static bin_tree_t *parse (re_string_t *regexp, regex_t *preg,
-                         reg_syntax_t syntax, reg_errcode_t *err);
-static bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg,
-                                 re_token_t *token, reg_syntax_t syntax,
-                                 Idx nest, reg_errcode_t *err);
-static bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg,
-                                re_token_t *token, reg_syntax_t syntax,
-                                Idx nest, reg_errcode_t *err);
-static bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg,
-                                    re_token_t *token, reg_syntax_t syntax,
-                                    Idx nest, reg_errcode_t *err);
-static bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg,
-                                 re_token_t *token, reg_syntax_t syntax,
-                                 Idx nest, reg_errcode_t *err);
-static bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp,
-                                re_dfa_t *dfa, re_token_t *token,
-                                reg_syntax_t syntax, reg_errcode_t *err);
-static bin_tree_t *parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa,
-                                     re_token_t *token, reg_syntax_t syntax,
-                                     reg_errcode_t *err);
-static reg_errcode_t parse_bracket_element (bracket_elem_t *elem,
-                                           re_string_t *regexp,
-                                           re_token_t *token, int token_len,
-                                           re_dfa_t *dfa,
-                                           reg_syntax_t syntax,
-                                           bool accept_hyphen);
-static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem,
-                                         re_string_t *regexp,
-                                         re_token_t *token);
-#ifdef RE_ENABLE_I18N
-static reg_errcode_t build_equiv_class (bitset_t sbcset,
-                                       re_charset_t *mbcset,
-                                       Idx *equiv_class_alloc,
-                                       const unsigned char *name);
-static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,
-                                     bitset_t sbcset,
-                                     re_charset_t *mbcset,
-                                     Idx *char_class_alloc,
-                                     const unsigned char *class_name,
-                                     reg_syntax_t syntax);
-#else  /* not RE_ENABLE_I18N */
-static reg_errcode_t build_equiv_class (bitset_t sbcset,
-                                       const unsigned char *name);
-static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,
-                                     bitset_t sbcset,
-                                     const unsigned char *class_name,
-                                     reg_syntax_t syntax);
-#endif /* not RE_ENABLE_I18N */
-static bin_tree_t *build_charclass_op (re_dfa_t *dfa,
-                                      RE_TRANSLATE_TYPE trans,
-                                      const unsigned char *class_name,
-                                      const unsigned char *extra,
-                                      bool non_match, reg_errcode_t *err);
-static bin_tree_t *create_tree (re_dfa_t *dfa,
-                               bin_tree_t *left, bin_tree_t *right,
-                               re_token_type_t type);
-static bin_tree_t *create_token_tree (re_dfa_t *dfa,
-                                     bin_tree_t *left, bin_tree_t *right,
-                                     const re_token_t *token);
-static bin_tree_t *duplicate_tree (const bin_tree_t *src, re_dfa_t *dfa);
-static void free_token (re_token_t *node);
-static reg_errcode_t free_tree (void *extra, bin_tree_t *node);
-static reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node);
-\f
-/* This table gives an error message for each of the error codes listed
-   in regex.h.  Obviously the order here has to be same as there.
-   POSIX doesn't require that we do anything for REG_NOERROR,
-   but why not be nice?  */
-
-static const char __re_error_msgid[] =
-  {
-#define REG_NOERROR_IDX        0
-    gettext_noop ("Success")   /* REG_NOERROR */
-    "\0"
-#define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof "Success")
-    gettext_noop ("No match")  /* REG_NOMATCH */
-    "\0"
-#define REG_BADPAT_IDX (REG_NOMATCH_IDX + sizeof "No match")
-    gettext_noop ("Invalid regular expression") /* REG_BADPAT */
-    "\0"
-#define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof "Invalid regular expression")
-    gettext_noop ("Invalid collation character") /* REG_ECOLLATE */
-    "\0"
-#define REG_ECTYPE_IDX (REG_ECOLLATE_IDX + sizeof "Invalid collation character")
-    gettext_noop ("Invalid character class name") /* REG_ECTYPE */
-    "\0"
-#define REG_EESCAPE_IDX        (REG_ECTYPE_IDX + sizeof "Invalid character class name")
-    gettext_noop ("Trailing backslash") /* REG_EESCAPE */
-    "\0"
-#define REG_ESUBREG_IDX        (REG_EESCAPE_IDX + sizeof "Trailing backslash")
-    gettext_noop ("Invalid back reference") /* REG_ESUBREG */
-    "\0"
-#define REG_EBRACK_IDX (REG_ESUBREG_IDX + sizeof "Invalid back reference")
-    gettext_noop ("Unmatched [ or [^") /* REG_EBRACK */
-    "\0"
-#define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [ or [^")
-    gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */
-    "\0"
-#define REG_EBRACE_IDX (REG_EPAREN_IDX + sizeof "Unmatched ( or \\(")
-    gettext_noop ("Unmatched \\{") /* REG_EBRACE */
-    "\0"
-#define REG_BADBR_IDX  (REG_EBRACE_IDX + sizeof "Unmatched \\{")
-    gettext_noop ("Invalid content of \\{\\}") /* REG_BADBR */
-    "\0"
-#define REG_ERANGE_IDX (REG_BADBR_IDX + sizeof "Invalid content of \\{\\}")
-    gettext_noop ("Invalid range end") /* REG_ERANGE */
-    "\0"
-#define REG_ESPACE_IDX (REG_ERANGE_IDX + sizeof "Invalid range end")
-    gettext_noop ("Memory exhausted") /* REG_ESPACE */
-    "\0"
-#define REG_BADRPT_IDX (REG_ESPACE_IDX + sizeof "Memory exhausted")
-    gettext_noop ("Invalid preceding regular expression") /* REG_BADRPT */
-    "\0"
-#define REG_EEND_IDX   (REG_BADRPT_IDX + sizeof "Invalid preceding regular expression")
-    gettext_noop ("Premature end of regular expression") /* REG_EEND */
-    "\0"
-#define REG_ESIZE_IDX  (REG_EEND_IDX + sizeof "Premature end of regular expression")
-    gettext_noop ("Regular expression too big") /* REG_ESIZE */
-    "\0"
-#define REG_ERPAREN_IDX        (REG_ESIZE_IDX + sizeof "Regular expression too big")
-    gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
-  };
-
-static const size_t __re_error_msgid_idx[] =
-  {
-    REG_NOERROR_IDX,
-    REG_NOMATCH_IDX,
-    REG_BADPAT_IDX,
-    REG_ECOLLATE_IDX,
-    REG_ECTYPE_IDX,
-    REG_EESCAPE_IDX,
-    REG_ESUBREG_IDX,
-    REG_EBRACK_IDX,
-    REG_EPAREN_IDX,
-    REG_EBRACE_IDX,
-    REG_BADBR_IDX,
-    REG_ERANGE_IDX,
-    REG_ESPACE_IDX,
-    REG_BADRPT_IDX,
-    REG_EEND_IDX,
-    REG_ESIZE_IDX,
-    REG_ERPAREN_IDX
-  };
-\f
-/* Entry points for GNU code.  */
-
-/* re_compile_pattern is the GNU regular expression compiler: it
-   compiles PATTERN (of length LENGTH) and puts the result in BUFP.
-   Returns 0 if the pattern was valid, otherwise an error string.
-
-   Assumes the `allocated' (and perhaps `buffer') and `translate' fields
-   are set in BUFP on entry.  */
-
-#ifdef _LIBC
-const char *
-re_compile_pattern (pattern, length, bufp)
-    const char *pattern;
-    size_t length;
-    struct re_pattern_buffer *bufp;
-#else /* size_t might promote */
-const char *
-re_compile_pattern (const char *pattern, size_t length,
-                   struct re_pattern_buffer *bufp)
-#endif
-{
-  reg_errcode_t ret;
-
-  /* And GNU code determines whether or not to get register information
-     by passing null for the REGS argument to re_match, etc., not by
-     setting no_sub, unless RE_NO_SUB is set.  */
-  bufp->no_sub = !!(re_syntax_options & RE_NO_SUB);
-
-  /* Match anchors at newline.  */
-  bufp->newline_anchor = 1;
-
-  ret = re_compile_internal (bufp, pattern, length, re_syntax_options);
-
-  if (!ret)
-    return NULL;
-  return gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]);
-}
-#ifdef _LIBC
-weak_alias (__re_compile_pattern, re_compile_pattern)
-#endif
-
-/* Set by `re_set_syntax' to the current regexp syntax to recognize.  Can
-   also be assigned to arbitrarily: each pattern buffer stores its own
-   syntax, so it can be changed between regex compilations.  */
-/* This has no initializer because initialized variables in Emacs
-   become read-only after dumping.  */
-reg_syntax_t re_syntax_options;
-
-
-/* Specify the precise syntax of regexps for compilation.  This provides
-   for compatibility for various utilities which historically have
-   different, incompatible syntaxes.
-
-   The argument SYNTAX is a bit mask comprised of the various bits
-   defined in regex.h.  We return the old syntax.  */
-
-reg_syntax_t
-re_set_syntax (syntax)
-    reg_syntax_t syntax;
-{
-  reg_syntax_t ret = re_syntax_options;
-
-  re_syntax_options = syntax;
-  return ret;
-}
-#ifdef _LIBC
-weak_alias (__re_set_syntax, re_set_syntax)
-#endif
-
-int
-re_compile_fastmap (bufp)
-    struct re_pattern_buffer *bufp;
-{
-  re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
-  char *fastmap = bufp->fastmap;
-
-  memset (fastmap, '\0', sizeof (char) * SBC_MAX);
-  re_compile_fastmap_iter (bufp, dfa->init_state, fastmap);
-  if (dfa->init_state != dfa->init_state_word)
-    re_compile_fastmap_iter (bufp, dfa->init_state_word, fastmap);
-  if (dfa->init_state != dfa->init_state_nl)
-    re_compile_fastmap_iter (bufp, dfa->init_state_nl, fastmap);
-  if (dfa->init_state != dfa->init_state_begbuf)
-    re_compile_fastmap_iter (bufp, dfa->init_state_begbuf, fastmap);
-  bufp->fastmap_accurate = 1;
-  return 0;
-}
-#ifdef _LIBC
-weak_alias (__re_compile_fastmap, re_compile_fastmap)
-#endif
-
-static inline void
-__attribute ((always_inline))
-re_set_fastmap (char *fastmap, bool icase, int ch)
-{
-  fastmap[ch] = 1;
-  if (icase)
-    fastmap[tolower (ch)] = 1;
-}
-
-/* Helper function for re_compile_fastmap.
-   Compile fastmap for the initial_state INIT_STATE.  */
-
-static void
-re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
-                        char *fastmap)
-{
-  re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
-  Idx node_cnt;
-  bool icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));
-  for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
-    {
-      Idx node = init_state->nodes.elems[node_cnt];
-      re_token_type_t type = dfa->nodes[node].type;
-
-      if (type == CHARACTER)
-       {
-         re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
-#ifdef RE_ENABLE_I18N
-         if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
-           {
-             unsigned char buf[MB_LEN_MAX];
-             unsigned char *p;
-             wchar_t wc;
-             mbstate_t state;
-
-             p = buf;
-             *p++ = dfa->nodes[node].opr.c;
-             while (++node < dfa->nodes_len
-                    && dfa->nodes[node].type == CHARACTER
-                    && dfa->nodes[node].mb_partial)
-               *p++ = dfa->nodes[node].opr.c;
-             memset (&state, '\0', sizeof (state));
-             if (__mbrtowc (&wc, (const char *) buf, p - buf,
-                            &state) == p - buf
-                 && (__wcrtomb ((char *) buf, towlower (wc), &state)
-                     != (size_t) -1))
-               re_set_fastmap (fastmap, false, buf[0]);
-           }
-#endif
-       }
-      else if (type == SIMPLE_BRACKET)
-       {
-         int i, ch;
-         for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
-           {
-             int j;
-             bitset_word_t w = dfa->nodes[node].opr.sbcset[i];
-             for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
-               if (w & ((bitset_word_t) 1 << j))
-                 re_set_fastmap (fastmap, icase, ch);
-           }
-       }
-#ifdef RE_ENABLE_I18N
-      else if (type == COMPLEX_BRACKET)
-       {
-         re_charset_t *cset = dfa->nodes[node].opr.mbcset;
-         Idx i;
-
-# ifdef _LIBC
-         /* See if we have to try all bytes which start multiple collation
-            elements.
-            e.g. In da_DK, we want to catch 'a' since "aa" is a valid
-                 collation element, and don't catch 'b' since 'b' is
-                 the only collation element which starts from 'b' (and
-                 it is caught by SIMPLE_BRACKET).  */
-             if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0
-                 && (cset->ncoll_syms || cset->nranges))
-               {
-                 const int32_t *table = (const int32_t *)
-                   _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
-                 for (i = 0; i < SBC_MAX; ++i)
-                   if (table[i] < 0)
-                     re_set_fastmap (fastmap, icase, i);
-               }
-# endif /* _LIBC */
-
-         /* See if we have to start the match at all multibyte characters,
-            i.e. where we would not find an invalid sequence.  This only
-            applies to multibyte character sets; for single byte character
-            sets, the SIMPLE_BRACKET again suffices.  */
-         if (dfa->mb_cur_max > 1
-             && (cset->nchar_classes || cset->non_match || cset->nranges
-# ifdef _LIBC
-                 || cset->nequiv_classes
-# endif /* _LIBC */
-                ))
-           {
-             unsigned char c = 0;
-             do
-               {
-                 mbstate_t mbs;
-                 memset (&mbs, 0, sizeof (mbs));
-                 if (__mbrtowc (NULL, (char *) &c, 1, &mbs) == (size_t) -2)
-                   re_set_fastmap (fastmap, false, (int) c);
-               }
-             while (++c != 0);
-           }
-
-         else
-           {
-             /* ... Else catch all bytes which can start the mbchars.  */
-             for (i = 0; i < cset->nmbchars; ++i)
-               {
-                 char buf[256];
-                 mbstate_t state;
-                 memset (&state, '\0', sizeof (state));
-                 if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
-                   re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
-                 if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
-                   {
-                     if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)
-                         != (size_t) -1)
-                       re_set_fastmap (fastmap, false, *(unsigned char *) buf);
-                   }
-               }
-           }
-       }
-#endif /* RE_ENABLE_I18N */
-      else if (type == OP_PERIOD
-#ifdef RE_ENABLE_I18N
-              || type == OP_UTF8_PERIOD
-#endif /* RE_ENABLE_I18N */
-              || type == END_OF_RE)
-       {
-         memset (fastmap, '\1', sizeof (char) * SBC_MAX);
-         if (type == END_OF_RE)
-           bufp->can_be_null = 1;
-         return;
-       }
-    }
-}
-\f
-/* Entry point for POSIX code.  */
-/* regcomp takes a regular expression as a string and compiles it.
-
-   PREG is a regex_t *.  We do not expect any fields to be initialized,
-   since POSIX says we shouldn't.  Thus, we set
-
-     `buffer' to the compiled pattern;
-     `used' to the length of the compiled pattern;
-     `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
-       REG_EXTENDED bit in CFLAGS is set; otherwise, to
-       RE_SYNTAX_POSIX_BASIC;
-     `newline_anchor' to REG_NEWLINE being set in CFLAGS;
-     `fastmap' to an allocated space for the fastmap;
-     `fastmap_accurate' to zero;
-     `re_nsub' to the number of subexpressions in PATTERN.
-
-   PATTERN is the address of the pattern string.
-
-   CFLAGS is a series of bits which affect compilation.
-
-     If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
-     use POSIX basic syntax.
-
-     If REG_NEWLINE is set, then . and [^...] don't match newline.
-     Also, regexec will try a match beginning after every newline.
-
-     If REG_ICASE is set, then we considers upper- and lowercase
-     versions of letters to be equivalent when matching.
-
-     If REG_NOSUB is set, then when PREG is passed to regexec, that
-     routine will report only success or failure, and nothing about the
-     registers.
-
-   It returns 0 if it succeeds, nonzero if it doesn't.  (See regex.h for
-   the return codes and their meanings.)  */
-
-int
-regcomp (preg, pattern, cflags)
-    regex_t *_Restrict_ preg;
-    const char *_Restrict_ pattern;
-    int cflags;
-{
-  reg_errcode_t ret;
-  reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED
-                        : RE_SYNTAX_POSIX_BASIC);
-
-  preg->buffer = NULL;
-  preg->allocated = 0;
-  preg->used = 0;
-
-  /* Try to allocate space for the fastmap.  */
-  preg->fastmap = re_malloc (char, SBC_MAX);
-  if (BE (preg->fastmap == NULL, 0))
-    return REG_ESPACE;
-
-  syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0;
-
-  /* If REG_NEWLINE is set, newlines are treated differently.  */
-  if (cflags & REG_NEWLINE)
-    { /* REG_NEWLINE implies neither . nor [^...] match newline.  */
-      syntax &= ~RE_DOT_NEWLINE;
-      syntax |= RE_HAT_LISTS_NOT_NEWLINE;
-      /* It also changes the matching behavior.  */
-      preg->newline_anchor = 1;
-    }
-  else
-    preg->newline_anchor = 0;
-  preg->no_sub = !!(cflags & REG_NOSUB);
-  preg->translate = NULL;
-
-  ret = re_compile_internal (preg, pattern, strlen (pattern), syntax);
-
-  /* POSIX doesn't distinguish between an unmatched open-group and an
-     unmatched close-group: both are REG_EPAREN.  */
-  if (ret == REG_ERPAREN)
-    ret = REG_EPAREN;
-
-  /* We have already checked preg->fastmap != NULL.  */
-  if (BE (ret == REG_NOERROR, 1))
-    /* Compute the fastmap now, since regexec cannot modify the pattern
-       buffer.  This function never fails in this implementation.  */
-    (void) re_compile_fastmap (preg);
-  else
-    {
-      /* Some error occurred while compiling the expression.  */
-      re_free (preg->fastmap);
-      preg->fastmap = NULL;
-    }
-
-  return (int) ret;
-}
-#ifdef _LIBC
-weak_alias (__regcomp, regcomp)
-#endif
-
-/* Returns a message corresponding to an error code, ERRCODE, returned
-   from either regcomp or regexec.   We don't use PREG here.  */
-
-#ifdef _LIBC
-size_t
-regerror (errcode, preg, errbuf, errbuf_size)
-    int errcode;
-    const regex_t *_Restrict_ preg;
-    char *_Restrict_ errbuf;
-    size_t errbuf_size;
-#else /* size_t might promote */
-size_t
-regerror (int errcode, const regex_t *_Restrict_ preg,
-         char *_Restrict_ errbuf, size_t errbuf_size)
-#endif
-{
-  const char *msg;
-  size_t msg_size;
-
-  if (BE (errcode < 0
-         || errcode >= (int) (sizeof (__re_error_msgid_idx)
-                              / sizeof (__re_error_msgid_idx[0])), 0))
-    /* Only error codes returned by the rest of the code should be passed
-       to this routine.  If we are given anything else, or if other regex
-       code generates an invalid error code, then the program has a bug.
-       Dump core so we can fix it.  */
-    abort ();
-
-  msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]);
-
-  msg_size = strlen (msg) + 1; /* Includes the null.  */
-
-  if (BE (errbuf_size != 0, 1))
-    {
-      size_t cpy_size = msg_size;
-      if (BE (msg_size > errbuf_size, 0))
-       {
-         cpy_size = errbuf_size - 1;
-         errbuf[cpy_size] = '\0';
-       }
-      memcpy (errbuf, msg, cpy_size);
-    }
-
-  return msg_size;
-}
-#ifdef _LIBC
-weak_alias (__regerror, regerror)
-#endif
-
-
-#ifdef RE_ENABLE_I18N
-/* This static array is used for the map to single-byte characters when
-   UTF-8 is used.  Otherwise we would allocate memory just to initialize
-   it the same all the time.  UTF-8 is the preferred encoding so this is
-   a worthwhile optimization.  */
-static const bitset_t utf8_sb_map =
-{
-  /* Set the first 128 bits.  */
-# if 4 * BITSET_WORD_BITS < ASCII_CHARS
-#  error "bitset_word_t is narrower than 32 bits"
-# elif 3 * BITSET_WORD_BITS < ASCII_CHARS
-  BITSET_WORD_MAX, BITSET_WORD_MAX, BITSET_WORD_MAX,
-# elif 2 * BITSET_WORD_BITS < ASCII_CHARS
-  BITSET_WORD_MAX, BITSET_WORD_MAX,
-# elif 1 * BITSET_WORD_BITS < ASCII_CHARS
-  BITSET_WORD_MAX,
-# endif
-  (BITSET_WORD_MAX
-   >> (SBC_MAX % BITSET_WORD_BITS == 0
-       ? 0
-       : BITSET_WORD_BITS - SBC_MAX % BITSET_WORD_BITS))
-};
-#endif
-
-
-static void
-free_dfa_content (re_dfa_t *dfa)
-{
-  Idx i, j;
-
-  if (dfa->nodes)
-    for (i = 0; i < dfa->nodes_len; ++i)
-      free_token (dfa->nodes + i);
-  re_free (dfa->nexts);
-  for (i = 0; i < dfa->nodes_len; ++i)
-    {
-      if (dfa->eclosures != NULL)
-       re_node_set_free (dfa->eclosures + i);
-      if (dfa->inveclosures != NULL)
-       re_node_set_free (dfa->inveclosures + i);
-      if (dfa->edests != NULL)
-       re_node_set_free (dfa->edests + i);
-    }
-  re_free (dfa->edests);
-  re_free (dfa->eclosures);
-  re_free (dfa->inveclosures);
-  re_free (dfa->nodes);
-
-  if (dfa->state_table)
-    for (i = 0; i <= dfa->state_hash_mask; ++i)
-      {
-       struct re_state_table_entry *entry = dfa->state_table + i;
-       for (j = 0; j < entry->num; ++j)
-         {
-           re_dfastate_t *state = entry->array[j];
-           free_state (state);
-         }
-       re_free (entry->array);
-      }
-  re_free (dfa->state_table);
-#ifdef RE_ENABLE_I18N
-  if (dfa->sb_char != utf8_sb_map)
-    re_free (dfa->sb_char);
-#endif
-  re_free (dfa->subexp_map);
-#ifdef DEBUG
-  re_free (dfa->re_str);
-#endif
-
-  re_free (dfa);
-}
-
-
-/* Free dynamically allocated space used by PREG.  */
-
-void
-regfree (preg)
-    regex_t *preg;
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  if (BE (dfa != NULL, 1))
-    free_dfa_content (dfa);
-  preg->buffer = NULL;
-  preg->allocated = 0;
-
-  re_free (preg->fastmap);
-  preg->fastmap = NULL;
-
-  re_free (preg->translate);
-  preg->translate = NULL;
-}
-#ifdef _LIBC
-weak_alias (__regfree, regfree)
-#endif
-\f
-/* Entry points compatible with 4.2 BSD regex library.  We don't define
-   them unless specifically requested.  */
-
-#if defined _REGEX_RE_COMP || defined _LIBC
-
-/* BSD has one and only one pattern buffer.  */
-static struct re_pattern_buffer re_comp_buf;
-
-char *
-# ifdef _LIBC
-/* Make these definitions weak in libc, so POSIX programs can redefine
-   these names if they don't use our functions, and still use
-   regcomp/regexec above without link errors.  */
-weak_function
-# endif
-re_comp (s)
-     const char *s;
-{
-  reg_errcode_t ret;
-  char *fastmap;
-
-  if (!s)
-    {
-      if (!re_comp_buf.buffer)
-       return gettext ("No previous regular expression");
-      return 0;
-    }
-
-  if (re_comp_buf.buffer)
-    {
-      fastmap = re_comp_buf.fastmap;
-      re_comp_buf.fastmap = NULL;
-      __regfree (&re_comp_buf);
-      memset (&re_comp_buf, '\0', sizeof (re_comp_buf));
-      re_comp_buf.fastmap = fastmap;
-    }
-
-  if (re_comp_buf.fastmap == NULL)
-    {
-      re_comp_buf.fastmap = (char *) malloc (SBC_MAX);
-      if (re_comp_buf.fastmap == NULL)
-       return (char *) gettext (__re_error_msgid
-                                + __re_error_msgid_idx[(int) REG_ESPACE]);
-    }
-
-  /* Since `re_exec' always passes NULL for the `regs' argument, we
-     don't need to initialize the pattern buffer fields which affect it.  */
-
-  /* Match anchors at newlines.  */
-  re_comp_buf.newline_anchor = 1;
-
-  ret = re_compile_internal (&re_comp_buf, s, strlen (s), re_syntax_options);
-
-  if (!ret)
-    return NULL;
-
-  /* Yes, we're discarding `const' here if !HAVE_LIBINTL.  */
-  return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]);
-}
-
-#ifdef _LIBC
-libc_freeres_fn (free_mem)
-{
-  __regfree (&re_comp_buf);
-}
-#endif
-
-#endif /* _REGEX_RE_COMP */
-\f
-/* Internal entry point.
-   Compile the regular expression PATTERN, whose length is LENGTH.
-   SYNTAX indicate regular expression's syntax.  */
-
-static reg_errcode_t
-re_compile_internal (regex_t *preg, const char * pattern, size_t length,
-                    reg_syntax_t syntax)
-{
-  reg_errcode_t err = REG_NOERROR;
-  re_dfa_t *dfa;
-  re_string_t regexp;
-
-  /* Initialize the pattern buffer.  */
-  preg->fastmap_accurate = 0;
-  preg->syntax = syntax;
-  preg->not_bol = preg->not_eol = 0;
-  preg->used = 0;
-  preg->re_nsub = 0;
-  preg->can_be_null = 0;
-  preg->regs_allocated = REGS_UNALLOCATED;
-
-  /* Initialize the dfa.  */
-  dfa = (re_dfa_t *) preg->buffer;
-  if (BE (preg->allocated < sizeof (re_dfa_t), 0))
-    {
-      /* If zero allocated, but buffer is non-null, try to realloc
-        enough space.  This loses if buffer's address is bogus, but
-        that is the user's responsibility.  If ->buffer is NULL this
-        is a simple allocation.  */
-      dfa = re_realloc (preg->buffer, re_dfa_t, 1);
-      if (dfa == NULL)
-       return REG_ESPACE;
-      preg->allocated = sizeof (re_dfa_t);
-      preg->buffer = (unsigned char *) dfa;
-    }
-  preg->used = sizeof (re_dfa_t);
-
-  err = init_dfa (dfa, length);
-  if (BE (err != REG_NOERROR, 0))
-    {
-      free_dfa_content (dfa);
-      preg->buffer = NULL;
-      preg->allocated = 0;
-      return err;
-    }
-#ifdef DEBUG
-  /* Note: length+1 will not overflow since it is checked in init_dfa.  */
-  dfa->re_str = re_malloc (char, length + 1);
-  strncpy (dfa->re_str, pattern, length + 1);
-#endif
-
-  __libc_lock_init (dfa->lock);
-
-  err = re_string_construct (&regexp, pattern, length, preg->translate,
-                            (syntax & RE_ICASE) != 0, dfa);
-  if (BE (err != REG_NOERROR, 0))
-    {
-    re_compile_internal_free_return:
-      free_workarea_compile (preg);
-      re_string_destruct (&regexp);
-      free_dfa_content (dfa);
-      preg->buffer = NULL;
-      preg->allocated = 0;
-      return err;
-    }
-
-  /* Parse the regular expression, and build a structure tree.  */
-  preg->re_nsub = 0;
-  dfa->str_tree = parse (&regexp, preg, syntax, &err);
-  if (BE (dfa->str_tree == NULL, 0))
-    goto re_compile_internal_free_return;
-
-  /* Analyze the tree and create the nfa.  */
-  err = analyze (preg);
-  if (BE (err != REG_NOERROR, 0))
-    goto re_compile_internal_free_return;
-
-#ifdef RE_ENABLE_I18N
-  /* If possible, do searching in single byte encoding to speed things up.  */
-  if (dfa->is_utf8 && !(syntax & RE_ICASE) && preg->translate == NULL)
-    optimize_utf8 (dfa);
-#endif
-
-  /* Then create the initial state of the dfa.  */
-  err = create_initial_state (dfa);
-
-  /* Release work areas.  */
-  free_workarea_compile (preg);
-  re_string_destruct (&regexp);
-
-  if (BE (err != REG_NOERROR, 0))
-    {
-      free_dfa_content (dfa);
-      preg->buffer = NULL;
-      preg->allocated = 0;
-    }
-
-  return err;
-}
-
-/* Initialize DFA.  We use the length of the regular expression PAT_LEN
-   as the initial length of some arrays.  */
-
-static reg_errcode_t
-init_dfa (re_dfa_t *dfa, size_t pat_len)
-{
-  __re_size_t table_size;
-#ifndef _LIBC
-  char *codeset_name;
-#endif
-#ifdef RE_ENABLE_I18N
-  size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t));
-#else
-  size_t max_i18n_object_size = 0;
-#endif
-  size_t max_object_size =
-    MAX (sizeof (struct re_state_table_entry),
-        MAX (sizeof (re_token_t),
-             MAX (sizeof (re_node_set),
-                  MAX (sizeof (regmatch_t),
-                       max_i18n_object_size))));
-
-  memset (dfa, '\0', sizeof (re_dfa_t));
-
-  /* Force allocation of str_tree_storage the first time.  */
-  dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;
-
-  /* Avoid overflows.  The extra "/ 2" is for the table_size doubling
-     calculation below, and for similar doubling calculations
-     elsewhere.  And it's <= rather than <, because some of the
-     doubling calculations add 1 afterwards.  */
-  if (BE (SIZE_MAX / max_object_size / 2 <= pat_len, 0))
-    return REG_ESPACE;
-
-  dfa->nodes_alloc = pat_len + 1;
-  dfa->nodes = re_malloc (re_token_t, dfa->nodes_alloc);
-
-  /*  table_size = 2 ^ ceil(log pat_len) */
-  for (table_size = 1; ; table_size <<= 1)
-    if (table_size > pat_len)
-      break;
-
-  dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size);
-  dfa->state_hash_mask = table_size - 1;
-
-  dfa->mb_cur_max = MB_CUR_MAX;
-#ifdef _LIBC
-  if (dfa->mb_cur_max == 6
-      && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0)
-    dfa->is_utf8 = 1;
-  dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII)
-                      != 0);
-#else
-  codeset_name = nl_langinfo (CODESET);
-  if (strcasecmp (codeset_name, "UTF-8") == 0
-      || strcasecmp (codeset_name, "UTF8") == 0)
-    dfa->is_utf8 = 1;
-
-  /* We check exhaustively in the loop below if this charset is a
-     superset of ASCII.  */
-  dfa->map_notascii = 0;
-#endif
-
-#ifdef RE_ENABLE_I18N
-  if (dfa->mb_cur_max > 1)
-    {
-      if (dfa->is_utf8)
-       dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map;
-      else
-       {
-         int i, j, ch;
-
-         dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
-         if (BE (dfa->sb_char == NULL, 0))
-           return REG_ESPACE;
-
-         /* Set the bits corresponding to single byte chars.  */
-         for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
-           for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
-             {
-               wint_t wch = __btowc (ch);
-               if (wch != WEOF)
-                 dfa->sb_char[i] |= (bitset_word_t) 1 << j;
-# ifndef _LIBC
-               if (isascii (ch) && wch != ch)
-                 dfa->map_notascii = 1;
-# endif
-             }
-       }
-    }
-#endif
-
-  if (BE (dfa->nodes == NULL || dfa->state_table == NULL, 0))
-    return REG_ESPACE;
-  return REG_NOERROR;
-}
-
-/* Initialize WORD_CHAR table, which indicate which character is
-   "word".  In this case "word" means that it is the word construction
-   character used by some operators like "\<", "\>", etc.  */
-
-static void
-internal_function
-init_word_char (re_dfa_t *dfa)
-{
-  int i, j, ch;
-  dfa->word_ops_used = 1;
-  for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
-    for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
-      if (isalnum (ch) || ch == '_')
-       dfa->word_char[i] |= (bitset_word_t) 1 << j;
-}
-
-/* Free the work area which are only used while compiling.  */
-
-static void
-free_workarea_compile (regex_t *preg)
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  bin_tree_storage_t *storage, *next;
-  for (storage = dfa->str_tree_storage; storage; storage = next)
-    {
-      next = storage->next;
-      re_free (storage);
-    }
-  dfa->str_tree_storage = NULL;
-  dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;
-  dfa->str_tree = NULL;
-  re_free (dfa->org_indices);
-  dfa->org_indices = NULL;
-}
-
-/* Create initial states for all contexts.  */
-
-static reg_errcode_t
-create_initial_state (re_dfa_t *dfa)
-{
-  Idx first, i;
-  reg_errcode_t err;
-  re_node_set init_nodes;
-
-  /* Initial states have the epsilon closure of the node which is
-     the first node of the regular expression.  */
-  first = dfa->str_tree->first->node_idx;
-  dfa->init_node = first;
-  err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first);
-  if (BE (err != REG_NOERROR, 0))
-    return err;
-
-  /* The back-references which are in initial states can epsilon transit,
-     since in this case all of the subexpressions can be null.
-     Then we add epsilon closures of the nodes which are the next nodes of
-     the back-references.  */
-  if (dfa->nbackref > 0)
-    for (i = 0; i < init_nodes.nelem; ++i)
-      {
-       Idx node_idx = init_nodes.elems[i];
-       re_token_type_t type = dfa->nodes[node_idx].type;
-
-       Idx clexp_idx;
-       if (type != OP_BACK_REF)
-         continue;
-       for (clexp_idx = 0; clexp_idx < init_nodes.nelem; ++clexp_idx)
-         {
-           re_token_t *clexp_node;
-           clexp_node = dfa->nodes + init_nodes.elems[clexp_idx];
-           if (clexp_node->type == OP_CLOSE_SUBEXP
-               && clexp_node->opr.idx == dfa->nodes[node_idx].opr.idx)
-             break;
-         }
-       if (clexp_idx == init_nodes.nelem)
-         continue;
-
-       if (type == OP_BACK_REF)
-         {
-           Idx dest_idx = dfa->edests[node_idx].elems[0];
-           if (!re_node_set_contains (&init_nodes, dest_idx))
-             {
-               reg_errcode_t merge_err
-                  = re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx);
-               if (merge_err != REG_NOERROR)
-                 return merge_err;
-               i = 0;
-             }
-         }
-      }
-
-  /* It must be the first time to invoke acquire_state.  */
-  dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0);
-  /* We don't check ERR here, since the initial state must not be NULL.  */
-  if (BE (dfa->init_state == NULL, 0))
-    return err;
-  if (dfa->init_state->has_constraint)
-    {
-      dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes,
-                                                      CONTEXT_WORD);
-      dfa->init_state_nl = re_acquire_state_context (&err, dfa, &init_nodes,
-                                                    CONTEXT_NEWLINE);
-      dfa->init_state_begbuf = re_acquire_state_context (&err, dfa,
-                                                        &init_nodes,
-                                                        CONTEXT_NEWLINE
-                                                        | CONTEXT_BEGBUF);
-      if (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL
-             || dfa->init_state_begbuf == NULL, 0))
-       return err;
-    }
-  else
-    dfa->init_state_word = dfa->init_state_nl
-      = dfa->init_state_begbuf = dfa->init_state;
-
-  re_node_set_free (&init_nodes);
-  return REG_NOERROR;
-}
-\f
-#ifdef RE_ENABLE_I18N
-/* If it is possible to do searching in single byte encoding instead of UTF-8
-   to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change
-   DFA nodes where needed.  */
-
-static void
-optimize_utf8 (re_dfa_t *dfa)
-{
-  Idx node;
-  int i;
-  bool mb_chars = false;
-  bool has_period = false;
-
-  for (node = 0; node < dfa->nodes_len; ++node)
-    switch (dfa->nodes[node].type)
-      {
-      case CHARACTER:
-       if (dfa->nodes[node].opr.c >= ASCII_CHARS)
-         mb_chars = true;
-       break;
-      case ANCHOR:
-       switch (dfa->nodes[node].opr.ctx_type)
-         {
-         case LINE_FIRST:
-         case LINE_LAST:
-         case BUF_FIRST:
-         case BUF_LAST:
-           break;
-         default:
-           /* Word anchors etc. cannot be handled.  It's okay to test
-              opr.ctx_type since constraints (for all DFA nodes) are
-              created by ORing one or more opr.ctx_type values.  */
-           return;
-         }
-       break;
-      case OP_PERIOD:
-       has_period = true;
-       break;
-      case OP_BACK_REF:
-      case OP_ALT:
-      case END_OF_RE:
-      case OP_DUP_ASTERISK:
-      case OP_OPEN_SUBEXP:
-      case OP_CLOSE_SUBEXP:
-       break;
-      case COMPLEX_BRACKET:
-       return;
-      case SIMPLE_BRACKET:
-       /* Just double check.  */
-       {
-         int rshift = (ASCII_CHARS % BITSET_WORD_BITS == 0
-                       ? 0
-                       : BITSET_WORD_BITS - ASCII_CHARS % BITSET_WORD_BITS);
-         for (i = ASCII_CHARS / BITSET_WORD_BITS; i < BITSET_WORDS; ++i)
-           {
-             if (dfa->nodes[node].opr.sbcset[i] >> rshift != 0)
-               return;
-             rshift = 0;
-           }
-       }
-       break;
-      default:
-       abort ();
-      }
-
-  if (mb_chars || has_period)
-    for (node = 0; node < dfa->nodes_len; ++node)
-      {
-       if (dfa->nodes[node].type == CHARACTER
-           && dfa->nodes[node].opr.c >= ASCII_CHARS)
-         dfa->nodes[node].mb_partial = 0;
-       else if (dfa->nodes[node].type == OP_PERIOD)
-         dfa->nodes[node].type = OP_UTF8_PERIOD;
-      }
-
-  /* The search can be in single byte locale.  */
-  dfa->mb_cur_max = 1;
-  dfa->is_utf8 = 0;
-  dfa->has_mb_node = dfa->nbackref > 0 || has_period;
-}
-#endif
-\f
-/* Analyze the structure tree, and calculate "first", "next", "edest",
-   "eclosure", and "inveclosure".  */
-
-static reg_errcode_t
-analyze (regex_t *preg)
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  reg_errcode_t ret;
-
-  /* Allocate arrays.  */
-  dfa->nexts = re_malloc (Idx, dfa->nodes_alloc);
-  dfa->org_indices = re_malloc (Idx, dfa->nodes_alloc);
-  dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc);
-  dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc);
-  if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL
-         || dfa->eclosures == NULL, 0))
-    return REG_ESPACE;
-
-  dfa->subexp_map = re_malloc (Idx, preg->re_nsub);
-  if (dfa->subexp_map != NULL)
-    {
-      Idx i;
-      for (i = 0; i < preg->re_nsub; i++)
-       dfa->subexp_map[i] = i;
-      preorder (dfa->str_tree, optimize_subexps, dfa);
-      for (i = 0; i < preg->re_nsub; i++)
-       if (dfa->subexp_map[i] != i)
-         break;
-      if (i == preg->re_nsub)
-       {
-         free (dfa->subexp_map);
-         dfa->subexp_map = NULL;
-       }
-    }
-
-  ret = postorder (dfa->str_tree, lower_subexps, preg);
-  if (BE (ret != REG_NOERROR, 0))
-    return ret;
-  ret = postorder (dfa->str_tree, calc_first, dfa);
-  if (BE (ret != REG_NOERROR, 0))
-    return ret;
-  preorder (dfa->str_tree, calc_next, dfa);
-  ret = preorder (dfa->str_tree, link_nfa_nodes, dfa);
-  if (BE (ret != REG_NOERROR, 0))
-    return ret;
-  ret = calc_eclosure (dfa);
-  if (BE (ret != REG_NOERROR, 0))
-    return ret;
-
-  /* We only need this during the prune_impossible_nodes pass in regexec.c;
-     skip it if p_i_n will not run, as calc_inveclosure can be quadratic.  */
-  if ((!preg->no_sub && preg->re_nsub > 0 && dfa->has_plural_match)
-      || dfa->nbackref)
-    {
-      dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len);
-      if (BE (dfa->inveclosures == NULL, 0))
-       return REG_ESPACE;
-      ret = calc_inveclosure (dfa);
-    }
-
-  return ret;
-}
-
-/* Our parse trees are very unbalanced, so we cannot use a stack to
-   implement parse tree visits.  Instead, we use parent pointers and
-   some hairy code in these two functions.  */
-static reg_errcode_t
-postorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)),
-          void *extra)
-{
-  bin_tree_t *node, *prev;
-
-  for (node = root; ; )
-    {
-      /* Descend down the tree, preferably to the left (or to the right
-        if that's the only child).  */
-      while (node->left || node->right)
-       if (node->left)
-         node = node->left;
-       else
-         node = node->right;
-
-      do
-       {
-         reg_errcode_t err = fn (extra, node);
-         if (BE (err != REG_NOERROR, 0))
-           return err;
-         if (node->parent == NULL)
-           return REG_NOERROR;
-         prev = node;
-         node = node->parent;
-       }
-      /* Go up while we have a node that is reached from the right.  */
-      while (node->right == prev || node->right == NULL);
-      node = node->right;
-    }
-}
-
-static reg_errcode_t
-preorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)),
-         void *extra)
-{
-  bin_tree_t *node;
-
-  for (node = root; ; )
-    {
-      reg_errcode_t err = fn (extra, node);
-      if (BE (err != REG_NOERROR, 0))
-       return err;
-
-      /* Go to the left node, or up and to the right.  */
-      if (node->left)
-       node = node->left;
-      else
-       {
-         bin_tree_t *prev = NULL;
-         while (node->right == prev || node->right == NULL)
-           {
-             prev = node;
-             node = node->parent;
-             if (!node)
-               return REG_NOERROR;
-           }
-         node = node->right;
-       }
-    }
-}
-
-/* Optimization pass: if a SUBEXP is entirely contained, strip it and tell
-   re_search_internal to map the inner one's opr.idx to this one's.  Adjust
-   backreferences as well.  Requires a preorder visit.  */
-static reg_errcode_t
-optimize_subexps (void *extra, bin_tree_t *node)
-{
-  re_dfa_t *dfa = (re_dfa_t *) extra;
-
-  if (node->token.type == OP_BACK_REF && dfa->subexp_map)
-    {
-      int idx = node->token.opr.idx;
-      node->token.opr.idx = dfa->subexp_map[idx];
-      dfa->used_bkref_map |= 1 << node->token.opr.idx;
-    }
-
-  else if (node->token.type == SUBEXP
-          && node->left && node->left->token.type == SUBEXP)
-    {
-      Idx other_idx = node->left->token.opr.idx;
-
-      node->left = node->left->left;
-      if (node->left)
-       node->left->parent = node;
-
-      dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx];
-      if (other_idx < BITSET_WORD_BITS)
-       dfa->used_bkref_map &= ~((bitset_word_t) 1 << other_idx);
-    }
-
-  return REG_NOERROR;
-}
-
-/* Lowering pass: Turn each SUBEXP node into the appropriate concatenation
-   of OP_OPEN_SUBEXP, the body of the SUBEXP (if any) and OP_CLOSE_SUBEXP.  */
-static reg_errcode_t
-lower_subexps (void *extra, bin_tree_t *node)
-{
-  regex_t *preg = (regex_t *) extra;
-  reg_errcode_t err = REG_NOERROR;
-
-  if (node->left && node->left->token.type == SUBEXP)
-    {
-      node->left = lower_subexp (&err, preg, node->left);
-      if (node->left)
-       node->left->parent = node;
-    }
-  if (node->right && node->right->token.type == SUBEXP)
-    {
-      node->right = lower_subexp (&err, preg, node->right);
-      if (node->right)
-       node->right->parent = node;
-    }
-
-  return err;
-}
-
-static bin_tree_t *
-lower_subexp (reg_errcode_t *err, regex_t *preg, bin_tree_t *node)
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  bin_tree_t *body = node->left;
-  bin_tree_t *op, *cls, *tree1, *tree;
-
-  if (preg->no_sub
-      /* We do not optimize empty subexpressions, because otherwise we may
-        have bad CONCAT nodes with NULL children.  This is obviously not
-        very common, so we do not lose much.  An example that triggers
-        this case is the sed "script" /\(\)/x.  */
-      && node->left != NULL
-      && (node->token.opr.idx >= BITSET_WORD_BITS
-         || !(dfa->used_bkref_map
-              & ((bitset_word_t) 1 << node->token.opr.idx))))
-    return node->left;
-
-  /* Convert the SUBEXP node to the concatenation of an
-     OP_OPEN_SUBEXP, the contents, and an OP_CLOSE_SUBEXP.  */
-  op = create_tree (dfa, NULL, NULL, OP_OPEN_SUBEXP);
-  cls = create_tree (dfa, NULL, NULL, OP_CLOSE_SUBEXP);
-  tree1 = body ? create_tree (dfa, body, cls, CONCAT) : cls;
-  tree = create_tree (dfa, op, tree1, CONCAT);
-  if (BE (tree == NULL || tree1 == NULL || op == NULL || cls == NULL, 0))
-    {
-      *err = REG_ESPACE;
-      return NULL;
-    }
-
-  op->token.opr.idx = cls->token.opr.idx = node->token.opr.idx;
-  op->token.opt_subexp = cls->token.opt_subexp = node->token.opt_subexp;
-  return tree;
-}
-
-/* Pass 1 in building the NFA: compute FIRST and create unlinked automaton
-   nodes.  Requires a postorder visit.  */
-static reg_errcode_t
-calc_first (void *extra, bin_tree_t *node)
-{
-  re_dfa_t *dfa = (re_dfa_t *) extra;
-  if (node->token.type == CONCAT)
-    {
-      node->first = node->left->first;
-      node->node_idx = node->left->node_idx;
-    }
-  else
-    {
-      node->first = node;
-      node->node_idx = re_dfa_add_node (dfa, node->token);
-      if (BE (node->node_idx == REG_MISSING, 0))
-       return REG_ESPACE;
-      if (node->token.type == ANCHOR)
-       dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type;
-    }
-  return REG_NOERROR;
-}
-
-/* Pass 2: compute NEXT on the tree.  Preorder visit.  */
-static reg_errcode_t
-calc_next (void *extra, bin_tree_t *node)
-{
-  switch (node->token.type)
-    {
-    case OP_DUP_ASTERISK:
-      node->left->next = node;
-      break;
-    case CONCAT:
-      node->left->next = node->right->first;
-      node->right->next = node->next;
-      break;
-    default:
-      if (node->left)
-       node->left->next = node->next;
-      if (node->right)
-       node->right->next = node->next;
-      break;
-    }
-  return REG_NOERROR;
-}
-
-/* Pass 3: link all DFA nodes to their NEXT node (any order will do).  */
-static reg_errcode_t
-link_nfa_nodes (void *extra, bin_tree_t *node)
-{
-  re_dfa_t *dfa = (re_dfa_t *) extra;
-  Idx idx = node->node_idx;
-  reg_errcode_t err = REG_NOERROR;
-
-  switch (node->token.type)
-    {
-    case CONCAT:
-      break;
-
-    case END_OF_RE:
-      assert (node->next == NULL);
-      break;
-
-    case OP_DUP_ASTERISK:
-    case OP_ALT:
-      {
-       Idx left, right;
-       dfa->has_plural_match = 1;
-       if (node->left != NULL)
-         left = node->left->first->node_idx;
-       else
-         left = node->next->node_idx;
-       if (node->right != NULL)
-         right = node->right->first->node_idx;
-       else
-         right = node->next->node_idx;
-       assert (REG_VALID_INDEX (left));
-       assert (REG_VALID_INDEX (right));
-       err = re_node_set_init_2 (dfa->edests + idx, left, right);
-      }
-      break;
-
-    case ANCHOR:
-    case OP_OPEN_SUBEXP:
-    case OP_CLOSE_SUBEXP:
-      err = re_node_set_init_1 (dfa->edests + idx, node->next->node_idx);
-      break;
-
-    case OP_BACK_REF:
-      dfa->nexts[idx] = node->next->node_idx;
-      if (node->token.type == OP_BACK_REF)
-       err = re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]);
-      break;
-
-    default:
-      assert (!IS_EPSILON_NODE (node->token.type));
-      dfa->nexts[idx] = node->next->node_idx;
-      break;
-    }
-
-  return err;
-}
-
-/* Duplicate the epsilon closure of the node ROOT_NODE.
-   Note that duplicated nodes have constraint INIT_CONSTRAINT in addition
-   to their own constraint.  */
-
-static reg_errcode_t
-internal_function
-duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node,
-                       Idx root_node, unsigned int init_constraint)
-{
-  Idx org_node, clone_node;
-  bool ok;
-  unsigned int constraint = init_constraint;
-  for (org_node = top_org_node, clone_node = top_clone_node;;)
-    {
-      Idx org_dest, clone_dest;
-      if (dfa->nodes[org_node].type == OP_BACK_REF)
-       {
-         /* If the back reference epsilon-transit, its destination must
-            also have the constraint.  Then duplicate the epsilon closure
-            of the destination of the back reference, and store it in
-            edests of the back reference.  */
-         org_dest = dfa->nexts[org_node];
-         re_node_set_empty (dfa->edests + clone_node);
-         clone_dest = duplicate_node (dfa, org_dest, constraint);
-         if (BE (clone_dest == REG_MISSING, 0))
-           return REG_ESPACE;
-         dfa->nexts[clone_node] = dfa->nexts[org_node];
-         ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
-         if (BE (! ok, 0))
-           return REG_ESPACE;
-       }
-      else if (dfa->edests[org_node].nelem == 0)
-       {
-         /* In case of the node can't epsilon-transit, don't duplicate the
-            destination and store the original destination as the
-            destination of the node.  */
-         dfa->nexts[clone_node] = dfa->nexts[org_node];
-         break;
-       }
-      else if (dfa->edests[org_node].nelem == 1)
-       {
-         /* In case of the node can epsilon-transit, and it has only one
-            destination.  */
-         org_dest = dfa->edests[org_node].elems[0];
-         re_node_set_empty (dfa->edests + clone_node);
-         /* If the node is root_node itself, it means the epsilon closure
-            has a loop.  Then tie it to the destination of the root_node.  */
-         if (org_node == root_node && clone_node != org_node)
-           {
-             ok = re_node_set_insert (dfa->edests + clone_node, org_dest);
-             if (BE (! ok, 0))
-               return REG_ESPACE;
-             break;
-           }
-         /* In case the node has another constraint, append it.  */
-         constraint |= dfa->nodes[org_node].constraint;
-         clone_dest = duplicate_node (dfa, org_dest, constraint);
-         if (BE (clone_dest == REG_MISSING, 0))
-           return REG_ESPACE;
-         ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
-         if (BE (! ok, 0))
-           return REG_ESPACE;
-       }
-      else /* dfa->edests[org_node].nelem == 2 */
-       {
-         /* In case of the node can epsilon-transit, and it has two
-            destinations. In the bin_tree_t and DFA, that's '|' and '*'.   */
-         org_dest = dfa->edests[org_node].elems[0];
-         re_node_set_empty (dfa->edests + clone_node);
-         /* Search for a duplicated node which satisfies the constraint.  */
-         clone_dest = search_duplicated_node (dfa, org_dest, constraint);
-         if (clone_dest == REG_MISSING)
-           {
-             /* There is no such duplicated node, create a new one.  */
-             reg_errcode_t err;
-             clone_dest = duplicate_node (dfa, org_dest, constraint);
-             if (BE (clone_dest == REG_MISSING, 0))
-               return REG_ESPACE;
-             ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
-             if (BE (! ok, 0))
-               return REG_ESPACE;
-             err = duplicate_node_closure (dfa, org_dest, clone_dest,
-                                           root_node, constraint);
-             if (BE (err != REG_NOERROR, 0))
-               return err;
-           }
-         else
-           {
-             /* There is a duplicated node which satisfies the constraint,
-                use it to avoid infinite loop.  */
-             ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
-             if (BE (! ok, 0))
-               return REG_ESPACE;
-           }
-
-         org_dest = dfa->edests[org_node].elems[1];
-         clone_dest = duplicate_node (dfa, org_dest, constraint);
-         if (BE (clone_dest == REG_MISSING, 0))
-           return REG_ESPACE;
-         ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
-         if (BE (! ok, 0))
-           return REG_ESPACE;
-       }
-      org_node = org_dest;
-      clone_node = clone_dest;
-    }
-  return REG_NOERROR;
-}
-
-/* Search for a node which is duplicated from the node ORG_NODE, and
-   satisfies the constraint CONSTRAINT.  */
-
-static Idx
-search_duplicated_node (const re_dfa_t *dfa, Idx org_node,
-                       unsigned int constraint)
-{
-  Idx idx;
-  for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx)
-    {
-      if (org_node == dfa->org_indices[idx]
-         && constraint == dfa->nodes[idx].constraint)
-       return idx; /* Found.  */
-    }
-  return REG_MISSING; /* Not found.  */
-}
-
-/* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT.
-   Return the index of the new node, or REG_MISSING if insufficient storage is
-   available.  */
-
-static Idx
-duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint)
-{
-  Idx dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]);
-  if (BE (dup_idx != REG_MISSING, 1))
-    {
-      dfa->nodes[dup_idx].constraint = constraint;
-      dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].constraint;
-      dfa->nodes[dup_idx].duplicated = 1;
-
-      /* Store the index of the original node.  */
-      dfa->org_indices[dup_idx] = org_idx;
-    }
-  return dup_idx;
-}
-
-static reg_errcode_t
-calc_inveclosure (re_dfa_t *dfa)
-{
-  Idx src, idx;
-  bool ok;
-  for (idx = 0; idx < dfa->nodes_len; ++idx)
-    re_node_set_init_empty (dfa->inveclosures + idx);
-
-  for (src = 0; src < dfa->nodes_len; ++src)
-    {
-      Idx *elems = dfa->eclosures[src].elems;
-      for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx)
-       {
-         ok = re_node_set_insert_last (dfa->inveclosures + elems[idx], src);
-         if (BE (! ok, 0))
-           return REG_ESPACE;
-       }
-    }
-
-  return REG_NOERROR;
-}
-
-/* Calculate "eclosure" for all the node in DFA.  */
-
-static reg_errcode_t
-calc_eclosure (re_dfa_t *dfa)
-{
-  Idx node_idx;
-  bool incomplete;
-#ifdef DEBUG
-  assert (dfa->nodes_len > 0);
-#endif
-  incomplete = false;
-  /* For each nodes, calculate epsilon closure.  */
-  for (node_idx = 0; ; ++node_idx)
-    {
-      reg_errcode_t err;
-      re_node_set eclosure_elem;
-      if (node_idx == dfa->nodes_len)
-       {
-         if (!incomplete)
-           break;
-         incomplete = false;
-         node_idx = 0;
-       }
-
-#ifdef DEBUG
-      assert (dfa->eclosures[node_idx].nelem != REG_MISSING);
-#endif
-
-      /* If we have already calculated, skip it.  */
-      if (dfa->eclosures[node_idx].nelem != 0)
-       continue;
-      /* Calculate epsilon closure of `node_idx'.  */
-      err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, true);
-      if (BE (err != REG_NOERROR, 0))
-       return err;
-
-      if (dfa->eclosures[node_idx].nelem == 0)
-       {
-         incomplete = true;
-         re_node_set_free (&eclosure_elem);
-       }
-    }
-  return REG_NOERROR;
-}
-
-/* Calculate epsilon closure of NODE.  */
-
-static reg_errcode_t
-calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
-{
-  reg_errcode_t err;
-  Idx i;
-  re_node_set eclosure;
-  bool ok;
-  bool incomplete = false;
-  err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);
-  if (BE (err != REG_NOERROR, 0))
-    return err;
-
-  /* This indicates that we are calculating this node now.
-     We reference this value to avoid infinite loop.  */
-  dfa->eclosures[node].nelem = REG_MISSING;
-
-  /* If the current node has constraints, duplicate all nodes
-     since they must inherit the constraints.  */
-  if (dfa->nodes[node].constraint
-      && dfa->edests[node].nelem
-      && !dfa->nodes[dfa->edests[node].elems[0]].duplicated)
-    {
-      err = duplicate_node_closure (dfa, node, node, node,
-                                   dfa->nodes[node].constraint);
-      if (BE (err != REG_NOERROR, 0))
-       return err;
-    }
-
-  /* Expand each epsilon destination nodes.  */
-  if (IS_EPSILON_NODE(dfa->nodes[node].type))
-    for (i = 0; i < dfa->edests[node].nelem; ++i)
-      {
-       re_node_set eclosure_elem;
-       Idx edest = dfa->edests[node].elems[i];
-       /* If calculating the epsilon closure of `edest' is in progress,
-          return intermediate result.  */
-       if (dfa->eclosures[edest].nelem == REG_MISSING)
-         {
-           incomplete = true;
-           continue;
-         }
-       /* If we haven't calculated the epsilon closure of `edest' yet,
-          calculate now. Otherwise use calculated epsilon closure.  */
-       if (dfa->eclosures[edest].nelem == 0)
-         {
-           err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false);
-           if (BE (err != REG_NOERROR, 0))
-             return err;
-         }
-       else
-         eclosure_elem = dfa->eclosures[edest];
-       /* Merge the epsilon closure of `edest'.  */
-       err = re_node_set_merge (&eclosure, &eclosure_elem);
-       if (BE (err != REG_NOERROR, 0))
-         return err;
-       /* If the epsilon closure of `edest' is incomplete,
-          the epsilon closure of this node is also incomplete.  */
-       if (dfa->eclosures[edest].nelem == 0)
-         {
-           incomplete = true;
-           re_node_set_free (&eclosure_elem);
-         }
-      }
-
-  /* An epsilon closure includes itself.  */
-  ok = re_node_set_insert (&eclosure, node);
-  if (BE (! ok, 0))
-    return REG_ESPACE;
-  if (incomplete && !root)
-    dfa->eclosures[node].nelem = 0;
-  else
-    dfa->eclosures[node] = eclosure;
-  *new_set = eclosure;
-  return REG_NOERROR;
-}
-\f
-/* Functions for token which are used in the parser.  */
-
-/* Fetch a token from INPUT.
-   We must not use this function inside bracket expressions.  */
-
-static void
-internal_function
-fetch_token (re_token_t *result, re_string_t *input, reg_syntax_t syntax)
-{
-  re_string_skip_bytes (input, peek_token (result, input, syntax));
-}
-
-/* Peek a token from INPUT, and return the length of the token.
-   We must not use this function inside bracket expressions.  */
-
-static int
-internal_function
-peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
-{
-  unsigned char c;
-
-  if (re_string_eoi (input))
-    {
-      token->type = END_OF_RE;
-      return 0;
-    }
-
-  c = re_string_peek_byte (input, 0);
-  token->opr.c = c;
-
-  token->word_char = 0;
-#ifdef RE_ENABLE_I18N
-  token->mb_partial = 0;
-  if (input->mb_cur_max > 1 &&
-      !re_string_first_byte (input, re_string_cur_idx (input)))
-    {
-      token->type = CHARACTER;
-      token->mb_partial = 1;
-      return 1;
-    }
-#endif
-  if (c == '\\')
-    {
-      unsigned char c2;
-      if (re_string_cur_idx (input) + 1 >= re_string_length (input))
-       {
-         token->type = BACK_SLASH;
-         return 1;
-       }
-
-      c2 = re_string_peek_byte_case (input, 1);
-      token->opr.c = c2;
-      token->type = CHARACTER;
-#ifdef RE_ENABLE_I18N
-      if (input->mb_cur_max > 1)
-       {
-         wint_t wc = re_string_wchar_at (input,
-                                         re_string_cur_idx (input) + 1);
-         token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
-       }
-      else
-#endif
-       token->word_char = IS_WORD_CHAR (c2) != 0;
-
-      switch (c2)
-       {
-       case '|':
-         if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_NO_BK_VBAR))
-           token->type = OP_ALT;
-         break;
-       case '1': case '2': case '3': case '4': case '5':
-       case '6': case '7': case '8': case '9':
-         if (!(syntax & RE_NO_BK_REFS))
-           {
-             token->type = OP_BACK_REF;
-             token->opr.idx = c2 - '1';
-           }
-         break;
-       case '<':
-         if (!(syntax & RE_NO_GNU_OPS))
-           {
-             token->type = ANCHOR;
-             token->opr.ctx_type = WORD_FIRST;
-           }
-         break;
-       case '>':
-         if (!(syntax & RE_NO_GNU_OPS))
-           {
-             token->type = ANCHOR;
-             token->opr.ctx_type = WORD_LAST;
-           }
-         break;
-       case 'b':
-         if (!(syntax & RE_NO_GNU_OPS))
-           {
-             token->type = ANCHOR;
-             token->opr.ctx_type = WORD_DELIM;
-           }
-         break;
-       case 'B':
-         if (!(syntax & RE_NO_GNU_OPS))
-           {
-             token->type = ANCHOR;
-             token->opr.ctx_type = NOT_WORD_DELIM;
-           }
-         break;
-       case 'w':
-         if (!(syntax & RE_NO_GNU_OPS))
-           token->type = OP_WORD;
-         break;
-       case 'W':
-         if (!(syntax & RE_NO_GNU_OPS))
-           token->type = OP_NOTWORD;
-         break;
-       case 's':
-         if (!(syntax & RE_NO_GNU_OPS))
-           token->type = OP_SPACE;
-         break;
-       case 'S':
-         if (!(syntax & RE_NO_GNU_OPS))
-           token->type = OP_NOTSPACE;
-         break;
-       case '`':
-         if (!(syntax & RE_NO_GNU_OPS))
-           {
-             token->type = ANCHOR;
-             token->opr.ctx_type = BUF_FIRST;
-           }
-         break;
-       case '\'':
-         if (!(syntax & RE_NO_GNU_OPS))
-           {
-             token->type = ANCHOR;
-             token->opr.ctx_type = BUF_LAST;
-           }
-         break;
-       case '(':
-         if (!(syntax & RE_NO_BK_PARENS))
-           token->type = OP_OPEN_SUBEXP;
-         break;
-       case ')':
-         if (!(syntax & RE_NO_BK_PARENS))
-           token->type = OP_CLOSE_SUBEXP;
-         break;
-       case '+':
-         if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))
-           token->type = OP_DUP_PLUS;
-         break;
-       case '?':
-         if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))
-           token->type = OP_DUP_QUESTION;
-         break;
-       case '{':
-         if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))
-           token->type = OP_OPEN_DUP_NUM;
-         break;
-       case '}':
-         if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))
-           token->type = OP_CLOSE_DUP_NUM;
-         break;
-       default:
-         break;
-       }
-      return 2;
-    }
-
-  token->type = CHARACTER;
-#ifdef RE_ENABLE_I18N
-  if (input->mb_cur_max > 1)
-    {
-      wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input));
-      token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
-    }
-  else
-#endif
-    token->word_char = IS_WORD_CHAR (token->opr.c);
-
-  switch (c)
-    {
-    case '\n':
-      if (syntax & RE_NEWLINE_ALT)
-       token->type = OP_ALT;
-      break;
-    case '|':
-      if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_NO_BK_VBAR))
-       token->type = OP_ALT;
-      break;
-    case '*':
-      token->type = OP_DUP_ASTERISK;
-      break;
-    case '+':
-      if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))
-       token->type = OP_DUP_PLUS;
-      break;
-    case '?':
-      if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))
-       token->type = OP_DUP_QUESTION;
-      break;
-    case '{':
-      if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
-       token->type = OP_OPEN_DUP_NUM;
-      break;
-    case '}':
-      if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
-       token->type = OP_CLOSE_DUP_NUM;
-      break;
-    case '(':
-      if (syntax & RE_NO_BK_PARENS)
-       token->type = OP_OPEN_SUBEXP;
-      break;
-    case ')':
-      if (syntax & RE_NO_BK_PARENS)
-       token->type = OP_CLOSE_SUBEXP;
-      break;
-    case '[':
-      token->type = OP_OPEN_BRACKET;
-      break;
-    case '.':
-      token->type = OP_PERIOD;
-      break;
-    case '^':
-      if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE)) &&
-         re_string_cur_idx (input) != 0)
-       {
-         char prev = re_string_peek_byte (input, -1);
-         if (!(syntax & RE_NEWLINE_ALT) || prev != '\n')
-           break;
-       }
-      token->type = ANCHOR;
-      token->opr.ctx_type = LINE_FIRST;
-      break;
-    case '$':
-      if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) &&
-         re_string_cur_idx (input) + 1 != re_string_length (input))
-       {
-         re_token_t next;
-         re_string_skip_bytes (input, 1);
-         peek_token (&next, input, syntax);
-         re_string_skip_bytes (input, -1);
-         if (next.type != OP_ALT && next.type != OP_CLOSE_SUBEXP)
-           break;
-       }
-      token->type = ANCHOR;
-      token->opr.ctx_type = LINE_LAST;
-      break;
-    default:
-      break;
-    }
-  return 1;
-}
-
-/* Peek a token from INPUT, and return the length of the token.
-   We must not use this function out of bracket expressions.  */
-
-static int
-internal_function
-peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
-{
-  unsigned char c;
-  if (re_string_eoi (input))
-    {
-      token->type = END_OF_RE;
-      return 0;
-    }
-  c = re_string_peek_byte (input, 0);
-  token->opr.c = c;
-
-#ifdef RE_ENABLE_I18N
-  if (input->mb_cur_max > 1 &&
-      !re_string_first_byte (input, re_string_cur_idx (input)))
-    {
-      token->type = CHARACTER;
-      return 1;
-    }
-#endif /* RE_ENABLE_I18N */
-
-  if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS)
-      && re_string_cur_idx (input) + 1 < re_string_length (input))
-    {
-      /* In this case, '\' escape a character.  */
-      unsigned char c2;
-      re_string_skip_bytes (input, 1);
-      c2 = re_string_peek_byte (input, 0);
-      token->opr.c = c2;
-      token->type = CHARACTER;
-      return 1;
-    }
-  if (c == '[') /* '[' is a special char in a bracket exps.  */
-    {
-      unsigned char c2;
-      int token_len;
-      if (re_string_cur_idx (input) + 1 < re_string_length (input))
-       c2 = re_string_peek_byte (input, 1);
-      else
-       c2 = 0;
-      token->opr.c = c2;
-      token_len = 2;
-      switch (c2)
-       {
-       case '.':
-         token->type = OP_OPEN_COLL_ELEM;
-         break;
-       case '=':
-         token->type = OP_OPEN_EQUIV_CLASS;
-         break;
-       case ':':
-         if (syntax & RE_CHAR_CLASSES)
-           {
-             token->type = OP_OPEN_CHAR_CLASS;
-             break;
-           }
-         /* else fall through.  */
-       default:
-         token->type = CHARACTER;
-         token->opr.c = c;
-         token_len = 1;
-         break;
-       }
-      return token_len;
-    }
-  switch (c)
-    {
-    case '-':
-      token->type = OP_CHARSET_RANGE;
-      break;
-    case ']':
-      token->type = OP_CLOSE_BRACKET;
-      break;
-    case '^':
-      token->type = OP_NON_MATCH_LIST;
-      break;
-    default:
-      token->type = CHARACTER;
-    }
-  return 1;
-}
-\f
-/* Functions for parser.  */
-
-/* Entry point of the parser.
-   Parse the regular expression REGEXP and return the structure tree.
-   If an error is occured, ERR is set by error code, and return NULL.
-   This function build the following tree, from regular expression <reg_exp>:
-          CAT
-          / \
-         /   \
-   <reg_exp>  EOR
-
-   CAT means concatenation.
-   EOR means end of regular expression.  */
-
-static bin_tree_t *
-parse (re_string_t *regexp, regex_t *preg, reg_syntax_t syntax,
-       reg_errcode_t *err)
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  bin_tree_t *tree, *eor, *root;
-  re_token_t current_token;
-  dfa->syntax = syntax;
-  fetch_token (&current_token, regexp, syntax | RE_CARET_ANCHORS_HERE);
-  tree = parse_reg_exp (regexp, preg, &current_token, syntax, 0, err);
-  if (BE (*err != REG_NOERROR && tree == NULL, 0))
-    return NULL;
-  eor = create_tree (dfa, NULL, NULL, END_OF_RE);
-  if (tree != NULL)
-    root = create_tree (dfa, tree, eor, CONCAT);
-  else
-    root = eor;
-  if (BE (eor == NULL || root == NULL, 0))
-    {
-      *err = REG_ESPACE;
-      return NULL;
-    }
-  return root;
-}
-
-/* This function build the following tree, from regular expression
-   <branch1>|<branch2>:
-          ALT
-          / \
-         /   \
-   <branch1> <branch2>
-
-   ALT means alternative, which represents the operator `|'.  */
-
-static bin_tree_t *
-parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
-              reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  bin_tree_t *tree, *branch = NULL;
-  tree = parse_branch (regexp, preg, token, syntax, nest, err);
-  if (BE (*err != REG_NOERROR && tree == NULL, 0))
-    return NULL;
-
-  while (token->type == OP_ALT)
-    {
-      fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE);
-      if (token->type != OP_ALT && token->type != END_OF_RE
-         && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
-       {
-         branch = parse_branch (regexp, preg, token, syntax, nest, err);
-         if (BE (*err != REG_NOERROR && branch == NULL, 0))
-           return NULL;
-       }
-      else
-       branch = NULL;
-      tree = create_tree (dfa, tree, branch, OP_ALT);
-      if (BE (tree == NULL, 0))
-       {
-         *err = REG_ESPACE;
-         return NULL;
-       }
-    }
-  return tree;
-}
-
-/* This function build the following tree, from regular expression
-   <exp1><exp2>:
-       CAT
-       / \
-       /   \
-   <exp1> <exp2>
-
-   CAT means concatenation.  */
-
-static bin_tree_t *
-parse_branch (re_string_t *regexp, regex_t *preg, re_token_t *token,
-             reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
-{
-  bin_tree_t *tree, *expr;
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  tree = parse_expression (regexp, preg, token, syntax, nest, err);
-  if (BE (*err != REG_NOERROR && tree == NULL, 0))
-    return NULL;
-
-  while (token->type != OP_ALT && token->type != END_OF_RE
-        && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
-    {
-      expr = parse_expression (regexp, preg, token, syntax, nest, err);
-      if (BE (*err != REG_NOERROR && expr == NULL, 0))
-       {
-         return NULL;
-       }
-      if (tree != NULL && expr != NULL)
-       {
-         tree = create_tree (dfa, tree, expr, CONCAT);
-         if (tree == NULL)
-           {
-             *err = REG_ESPACE;
-             return NULL;
-           }
-       }
-      else if (tree == NULL)
-       tree = expr;
-      /* Otherwise expr == NULL, we don't need to create new tree.  */
-    }
-  return tree;
-}
-
-/* This function build the following tree, from regular expression a*:
-        *
-        |
-        a
-*/
-
-static bin_tree_t *
-parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
-                 reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  bin_tree_t *tree;
-  switch (token->type)
-    {
-    case CHARACTER:
-      tree = create_token_tree (dfa, NULL, NULL, token);
-      if (BE (tree == NULL, 0))
-       {
-         *err = REG_ESPACE;
-         return NULL;
-       }
-#ifdef RE_ENABLE_I18N
-      if (dfa->mb_cur_max > 1)
-       {
-         while (!re_string_eoi (regexp)
-                && !re_string_first_byte (regexp, re_string_cur_idx (regexp)))
-           {
-             bin_tree_t *mbc_remain;
-             fetch_token (token, regexp, syntax);
-             mbc_remain = create_token_tree (dfa, NULL, NULL, token);
-             tree = create_tree (dfa, tree, mbc_remain, CONCAT);
-             if (BE (mbc_remain == NULL || tree == NULL, 0))
-               {
-                 *err = REG_ESPACE;
-                 return NULL;
-               }
-           }
-       }
-#endif
-      break;
-    case OP_OPEN_SUBEXP:
-      tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
-       return NULL;
-      break;
-    case OP_OPEN_BRACKET:
-      tree = parse_bracket_exp (regexp, dfa, token, syntax, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
-       return NULL;
-      break;
-    case OP_BACK_REF:
-      if (!BE (dfa->completed_bkref_map & (1 << token->opr.idx), 1))
-       {
-         *err = REG_ESUBREG;
-         return NULL;
-       }
-      dfa->used_bkref_map |= 1 << token->opr.idx;
-      tree = create_token_tree (dfa, NULL, NULL, token);
-      if (BE (tree == NULL, 0))
-       {
-         *err = REG_ESPACE;
-         return NULL;
-       }
-      ++dfa->nbackref;
-      dfa->has_mb_node = 1;
-      break;
-    case OP_OPEN_DUP_NUM:
-      if (syntax & RE_CONTEXT_INVALID_DUP)
-       {
-         *err = REG_BADRPT;
-         return NULL;
-       }
-      /* FALLTHROUGH */
-    case OP_DUP_ASTERISK:
-    case OP_DUP_PLUS:
-    case OP_DUP_QUESTION:
-      if (syntax & RE_CONTEXT_INVALID_OPS)
-       {
-         *err = REG_BADRPT;
-         return NULL;
-       }
-      else if (syntax & RE_CONTEXT_INDEP_OPS)
-       {
-         fetch_token (token, regexp, syntax);
-         return parse_expression (regexp, preg, token, syntax, nest, err);
-       }
-      /* else fall through  */
-    case OP_CLOSE_SUBEXP:
-      if ((token->type == OP_CLOSE_SUBEXP) &&
-         !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD))
-       {
-         *err = REG_ERPAREN;
-         return NULL;
-       }
-      /* else fall through  */
-    case OP_CLOSE_DUP_NUM:
-      /* We treat it as a normal character.  */
-
-      /* Then we can these characters as normal characters.  */
-      token->type = CHARACTER;
-      /* mb_partial and word_char bits should be initialized already
-        by peek_token.  */
-      tree = create_token_tree (dfa, NULL, NULL, token);
-      if (BE (tree == NULL, 0))
-       {
-         *err = REG_ESPACE;
-         return NULL;
-       }
-      break;
-    case ANCHOR:
-      if ((token->opr.ctx_type
-          & (WORD_DELIM | NOT_WORD_DELIM | WORD_FIRST | WORD_LAST))
-         && dfa->word_ops_used == 0)
-       init_word_char (dfa);
-      if (token->opr.ctx_type == WORD_DELIM
-         || token->opr.ctx_type == NOT_WORD_DELIM)
-       {
-         bin_tree_t *tree_first, *tree_last;
-         if (token->opr.ctx_type == WORD_DELIM)
-           {
-             token->opr.ctx_type = WORD_FIRST;
-             tree_first = create_token_tree (dfa, NULL, NULL, token);
-             token->opr.ctx_type = WORD_LAST;
-           }
-         else
-           {
-             token->opr.ctx_type = INSIDE_WORD;
-             tree_first = create_token_tree (dfa, NULL, NULL, token);
-             token->opr.ctx_type = INSIDE_NOTWORD;
-           }
-         tree_last = create_token_tree (dfa, NULL, NULL, token);
-         tree = create_tree (dfa, tree_first, tree_last, OP_ALT);
-         if (BE (tree_first == NULL || tree_last == NULL || tree == NULL, 0))
-           {
-             *err = REG_ESPACE;
-             return NULL;
-           }
-       }
-      else
-       {
-         tree = create_token_tree (dfa, NULL, NULL, token);
-         if (BE (tree == NULL, 0))
-           {
-             *err = REG_ESPACE;
-             return NULL;
-           }
-       }
-      /* We must return here, since ANCHORs can't be followed
-        by repetition operators.
-        eg. RE"^*" is invalid or "<ANCHOR(^)><CHAR(*)>",
-            it must not be "<ANCHOR(^)><REPEAT(*)>".  */
-      fetch_token (token, regexp, syntax);
-      return tree;
-    case OP_PERIOD:
-      tree = create_token_tree (dfa, NULL, NULL, token);
-      if (BE (tree == NULL, 0))
-       {
-         *err = REG_ESPACE;
-         return NULL;
-       }
-      if (dfa->mb_cur_max > 1)
-       dfa->has_mb_node = 1;
-      break;
-    case OP_WORD:
-    case OP_NOTWORD:
-      tree = build_charclass_op (dfa, regexp->trans,
-                                (const unsigned char *) "alnum",
-                                (const unsigned char *) "_",
-                                token->type == OP_NOTWORD, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
-       return NULL;
-      break;
-    case OP_SPACE:
-    case OP_NOTSPACE:
-      tree = build_charclass_op (dfa, regexp->trans,
-                                (const unsigned char *) "space",
-                                (const unsigned char *) "",
-                                token->type == OP_NOTSPACE, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
-       return NULL;
-      break;
-    case OP_ALT:
-    case END_OF_RE:
-      return NULL;
-    case BACK_SLASH:
-      *err = REG_EESCAPE;
-      return NULL;
-    default:
-      /* Must not happen?  */
-#ifdef DEBUG
-      assert (0);
-#endif
-      return NULL;
-    }
-  fetch_token (token, regexp, syntax);
-
-  while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS
-        || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)
-    {
-      tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
-       return NULL;
-      /* In BRE consecutive duplications are not allowed.  */
-      if ((syntax & RE_CONTEXT_INVALID_DUP)
-         && (token->type == OP_DUP_ASTERISK
-             || token->type == OP_OPEN_DUP_NUM))
-       {
-         *err = REG_BADRPT;
-         return NULL;
-       }
-    }
-
-  return tree;
-}
-
-/* This function build the following tree, from regular expression
-   (<reg_exp>):
-        SUBEXP
-           |
-       <reg_exp>
-*/
-
-static bin_tree_t *
-parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
-              reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
-{
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-  bin_tree_t *tree;
-  size_t cur_nsub;
-  cur_nsub = preg->re_nsub++;
-
-  fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE);
-
-  /* The subexpression may be a null string.  */
-  if (token->type == OP_CLOSE_SUBEXP)
-    tree = NULL;
-  else
-    {
-      tree = parse_reg_exp (regexp, preg, token, syntax, nest, err);
-      if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0))
-       *err = REG_EPAREN;
-      if (BE (*err != REG_NOERROR, 0))
-       return NULL;
-    }
-
-  if (cur_nsub <= '9' - '1')
-    dfa->completed_bkref_map |= 1 << cur_nsub;
-
-  tree = create_tree (dfa, tree, NULL, SUBEXP);
-  if (BE (tree == NULL, 0))
-    {
-      *err = REG_ESPACE;
-      return NULL;
-    }
-  tree->token.opr.idx = cur_nsub;
-  return tree;
-}
-
-/* This function parse repetition operators like "*", "+", "{1,3}" etc.  */
-
-static bin_tree_t *
-parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
-             re_token_t *token, reg_syntax_t syntax, reg_errcode_t *err)
-{
-  bin_tree_t *tree = NULL, *old_tree = NULL;
-  Idx i, start, end, start_idx = re_string_cur_idx (regexp);
-  re_token_t start_token = *token;
-
-  if (token->type == OP_OPEN_DUP_NUM)
-    {
-      end = 0;
-      start = fetch_number (regexp, token, syntax);
-      if (start == REG_MISSING)
-       {
-         if (token->type == CHARACTER && token->opr.c == ',')
-           start = 0; /* We treat "{,m}" as "{0,m}".  */
-         else
-           {
-             *err = REG_BADBR; /* <re>{} is invalid.  */
-             return NULL;
-           }
-       }
-      if (BE (start != REG_ERROR, 1))
-       {
-         /* We treat "{n}" as "{n,n}".  */
-         end = ((token->type == OP_CLOSE_DUP_NUM) ? start
-                : ((token->type == CHARACTER && token->opr.c == ',')
-                   ? fetch_number (regexp, token, syntax) : REG_ERROR));
-       }
-      if (BE (start == REG_ERROR || end == REG_ERROR, 0))
-       {
-         /* Invalid sequence.  */
-         if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0))
-           {
-             if (token->type == END_OF_RE)
-               *err = REG_EBRACE;
-             else
-               *err = REG_BADBR;
-
-             return NULL;
-           }
-
-         /* If the syntax bit is set, rollback.  */
-         re_string_set_index (regexp, start_idx);
-         *token = start_token;
-         token->type = CHARACTER;
-         /* mb_partial and word_char bits should be already initialized by
-            peek_token.  */
-         return elem;
-       }
-
-      if (BE ((end != REG_MISSING && start > end)
-             || token->type != OP_CLOSE_DUP_NUM, 0))
-       {
-         /* First number greater than second.  */
-         *err = REG_BADBR;
-         return NULL;
-       }
-    }
-  else
-    {
-      start = (token->type == OP_DUP_PLUS) ? 1 : 0;
-      end = (token->type == OP_DUP_QUESTION) ? 1 : REG_MISSING;
-    }
-
-  fetch_token (token, regexp, syntax);
-
-  if (BE (elem == NULL, 0))
-    return NULL;
-  if (BE (start == 0 && end == 0, 0))
-    {
-      postorder (elem, free_tree, NULL);
-      return NULL;
-    }
-
-  /* Extract "<re>{n,m}" to "<re><re>...<re><re>{0,<m-n>}".  */
-  if (BE (start > 0, 0))
-    {
-      tree = elem;
-      for (i = 2; i <= start; ++i)
-       {
-         elem = duplicate_tree (elem, dfa);
-         tree = create_tree (dfa, tree, elem, CONCAT);
-         if (BE (elem == NULL || tree == NULL, 0))
-           goto parse_dup_op_espace;
-       }
-
-      if (start == end)
-       return tree;
-
-      /* Duplicate ELEM before it is marked optional.  */
-      elem = duplicate_tree (elem, dfa);
-      old_tree = tree;
-    }
-  else
-    old_tree = NULL;
-
-  if (elem->token.type == SUBEXP)
-    postorder (elem, mark_opt_subexp, (void *) (long) elem->token.opr.idx);
-
-  tree = create_tree (dfa, elem, NULL,
-                     (end == REG_MISSING ? OP_DUP_ASTERISK : OP_ALT));
-  if (BE (tree == NULL, 0))
-    goto parse_dup_op_espace;
-
-/* From gnulib's "intprops.h":
-   True if the arithmetic type T is signed.  */
-#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
-
-  /* This loop is actually executed only when end != REG_MISSING,
-     to rewrite <re>{0,n} as (<re>(<re>...<re>?)?)?...  We have
-     already created the start+1-th copy.  */
-  if (TYPE_SIGNED (Idx) || end != REG_MISSING)
-    for (i = start + 2; i <= end; ++i)
-      {
-       elem = duplicate_tree (elem, dfa);
-       tree = create_tree (dfa, tree, elem, CONCAT);
-       if (BE (elem == NULL || tree == NULL, 0))
-         goto parse_dup_op_espace;
-
-       tree = create_tree (dfa, tree, NULL, OP_ALT);
-       if (BE (tree == NULL, 0))
-         goto parse_dup_op_espace;
-      }
-
-  if (old_tree)
-    tree = create_tree (dfa, old_tree, tree, CONCAT);
-
-  return tree;
-
- parse_dup_op_espace:
-  *err = REG_ESPACE;
-  return NULL;
-}
-
-/* Size of the names for collating symbol/equivalence_class/character_class.
-   I'm not sure, but maybe enough.  */
-#define BRACKET_NAME_BUF_SIZE 32
-
-#ifndef _LIBC
-  /* Local function for parse_bracket_exp only used in case of NOT _LIBC.
-     Build the range expression which starts from START_ELEM, and ends
-     at END_ELEM.  The result are written to MBCSET and SBCSET.
-     RANGE_ALLOC is the allocated size of mbcset->range_starts, and
-     mbcset->range_ends, is a pointer argument sinse we may
-     update it.  */
-
-static reg_errcode_t
-internal_function
-# ifdef RE_ENABLE_I18N
-build_range_exp (const reg_syntax_t syntax,
-                 bitset_t sbcset,
-                 re_charset_t *mbcset,
-                 Idx *range_alloc,
-                 const bracket_elem_t *start_elem,
-                 const bracket_elem_t *end_elem)
-# else /* not RE_ENABLE_I18N */
-build_range_exp (const reg_syntax_t syntax,
-                 bitset_t sbcset,
-                 const bracket_elem_t *start_elem,
-                 const bracket_elem_t *end_elem)
-# endif /* not RE_ENABLE_I18N */
-{
-  unsigned int start_ch, end_ch;
-  /* Equivalence Classes and Character Classes can't be a range start/end.  */
-  if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
-         || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
-         0))
-    return REG_ERANGE;
-
-  /* We can handle no multi character collating elements without libc
-     support.  */
-  if (BE ((start_elem->type == COLL_SYM
-          && strlen ((char *) start_elem->opr.name) > 1)
-         || (end_elem->type == COLL_SYM
-             && strlen ((char *) end_elem->opr.name) > 1), 0))
-    return REG_ECOLLATE;
-
-# ifdef RE_ENABLE_I18N
-  {
-    wchar_t wc;
-    wint_t start_wc;
-    wint_t end_wc;
-    wchar_t cmp_buf[6] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'};
-
-    start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch
-               : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
-                  : 0));
-    end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch
-             : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
-                : 0));
-    start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM)
-               ? __btowc (start_ch) : start_elem->opr.wch);
-    end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM)
-             ? __btowc (end_ch) : end_elem->opr.wch);
-    if (start_wc == WEOF || end_wc == WEOF)
-      return REG_ECOLLATE;
-    cmp_buf[0] = start_wc;
-    cmp_buf[4] = end_wc;
-
-    if (BE ((syntax & RE_NO_EMPTY_RANGES)
-            && wcscoll (cmp_buf, cmp_buf + 4) > 0, 0))
-      return REG_ERANGE;
-
-    /* Got valid collation sequence values, add them as a new entry.
-       However, for !_LIBC we have no collation elements: if the
-       character set is single byte, the single byte character set
-       that we build below suffices.  parse_bracket_exp passes
-       no MBCSET if dfa->mb_cur_max == 1.  */
-    if (mbcset)
-      {
-       /* Check the space of the arrays.  */
-       if (BE (*range_alloc == mbcset->nranges, 0))
-         {
-           /* There is not enough space, need realloc.  */
-           wchar_t *new_array_start, *new_array_end;
-           Idx new_nranges;
-
-           /* +1 in case of mbcset->nranges is 0.  */
-           new_nranges = 2 * mbcset->nranges + 1;
-           /* Use realloc since mbcset->range_starts and mbcset->range_ends
-              are NULL if *range_alloc == 0.  */
-           new_array_start = re_realloc (mbcset->range_starts, wchar_t,
-                                         new_nranges);
-           new_array_end = re_realloc (mbcset->range_ends, wchar_t,
-                                       new_nranges);
-
-           if (BE (new_array_start == NULL || new_array_end == NULL, 0))
-             return REG_ESPACE;
-
-           mbcset->range_starts = new_array_start;
-           mbcset->range_ends = new_array_end;
-           *range_alloc = new_nranges;
-         }
-
-       mbcset->range_starts[mbcset->nranges] = start_wc;
-       mbcset->range_ends[mbcset->nranges++] = end_wc;
-      }
-
-    /* Build the table for single byte characters.  */
-    for (wc = 0; wc < SBC_MAX; ++wc)
-      {
-       cmp_buf[2] = wc;
-       if (wcscoll (cmp_buf, cmp_buf + 2) <= 0
-           && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0)
-         bitset_set (sbcset, wc);
-      }
-  }
-# else /* not RE_ENABLE_I18N */
-  {
-    unsigned int ch;
-    start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch
-               : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
-                  : 0));
-    end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch
-             : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
-                : 0));
-    if (start_ch > end_ch)
-      return REG_ERANGE;
-    /* Build the table for single byte characters.  */
-    for (ch = 0; ch < SBC_MAX; ++ch)
-      if (start_ch <= ch  && ch <= end_ch)
-       bitset_set (sbcset, ch);
-  }
-# endif /* not RE_ENABLE_I18N */
-  return REG_NOERROR;
-}
-#endif /* not _LIBC */
-
-#ifndef _LIBC
-/* Helper function for parse_bracket_exp only used in case of NOT _LIBC..
-   Build the collating element which is represented by NAME.
-   The result are written to MBCSET and SBCSET.
-   COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
-   pointer argument since we may update it.  */
-
-static reg_errcode_t
-internal_function
-build_collating_symbol (bitset_t sbcset,
-# ifdef RE_ENABLE_I18N
-                       re_charset_t *mbcset, Idx *coll_sym_alloc,
-# endif
-                       const unsigned char *name)
-{
-  size_t name_len = strlen ((const char *) name);
-  if (BE (name_len != 1, 0))
-    return REG_ECOLLATE;
-  else
-    {
-      bitset_set (sbcset, name[0]);
-      return REG_NOERROR;
-    }
-}
-#endif /* not _LIBC */
-
-/* This function parse bracket expression like "[abc]", "[a-c]",
-   "[[.a-a.]]" etc.  */
-
-static bin_tree_t *
-parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
-                  reg_syntax_t syntax, reg_errcode_t *err)
-{
-#ifdef _LIBC
-  const unsigned char *collseqmb;
-  const char *collseqwc;
-  uint32_t nrules;
-  int32_t table_size;
-  const int32_t *symb_table;
-  const unsigned char *extra;
-
-  /* Local function for parse_bracket_exp used in _LIBC environement.
-     Seek the collating symbol entry correspondings to NAME.
-     Return the index of the symbol in the SYMB_TABLE.  */
-
-  auto inline int32_t
-  __attribute ((always_inline))
-  seek_collating_symbol_entry (name, name_len)
-        const unsigned char *name;
-        size_t name_len;
-    {
-      int32_t hash = elem_hash ((const char *) name, name_len);
-      int32_t elem = hash % table_size;
-      if (symb_table[2 * elem] != 0)
-       {
-         int32_t second = hash % (table_size - 2) + 1;
-
-         do
-           {
-             /* First compare the hashing value.  */
-             if (symb_table[2 * elem] == hash
-                 /* Compare the length of the name.  */
-                 && name_len == extra[symb_table[2 * elem + 1]]
-                 /* Compare the name.  */
-                 && memcmp (name, &extra[symb_table[2 * elem + 1] + 1],
-                            name_len) == 0)
-               {
-                 /* Yep, this is the entry.  */
-                 break;
-               }
-
-             /* Next entry.  */
-             elem += second;
-           }
-         while (symb_table[2 * elem] != 0);
-       }
-      return elem;
-    }
-
-  /* Local function for parse_bracket_exp used in _LIBC environment.
-     Look up the collation sequence value of BR_ELEM.
-     Return the value if succeeded, UINT_MAX otherwise.  */
-
-  auto inline unsigned int
-  __attribute ((always_inline))
-  lookup_collation_sequence_value (br_elem)
-        bracket_elem_t *br_elem;
-    {
-      if (br_elem->type == SB_CHAR)
-       {
-         /*
-         if (MB_CUR_MAX == 1)
-         */
-         if (nrules == 0)
-           return collseqmb[br_elem->opr.ch];
-         else
-           {
-             wint_t wc = __btowc (br_elem->opr.ch);
-             return __collseq_table_lookup (collseqwc, wc);
-           }
-       }
-      else if (br_elem->type == MB_CHAR)
-       {
-         if (nrules != 0)
-           return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
-       }
-      else if (br_elem->type == COLL_SYM)
-       {
-         size_t sym_name_len = strlen ((char *) br_elem->opr.name);
-         if (nrules != 0)
-           {
-             int32_t elem, idx;
-             elem = seek_collating_symbol_entry (br_elem->opr.name,
-                                                 sym_name_len);
-             if (symb_table[2 * elem] != 0)
-               {
-                 /* We found the entry.  */
-                 idx = symb_table[2 * elem + 1];
-                 /* Skip the name of collating element name.  */
-                 idx += 1 + extra[idx];
-                 /* Skip the byte sequence of the collating element.  */
-                 idx += 1 + extra[idx];
-                 /* Adjust for the alignment.  */
-                 idx = (idx + 3) & ~3;
-                 /* Skip the multibyte collation sequence value.  */
-                 idx += sizeof (unsigned int);
-                 /* Skip the wide char sequence of the collating element.  */
-                 idx += sizeof (unsigned int) *
-                   (1 + *(unsigned int *) (extra + idx));
-                 /* Return the collation sequence value.  */
-                 return *(unsigned int *) (extra + idx);
-               }
-             else if (symb_table[2 * elem] == 0 && sym_name_len == 1)
-               {
-                 /* No valid character.  Match it as a single byte
-                    character.  */
-                 return collseqmb[br_elem->opr.name[0]];
-               }
-           }
-         else if (sym_name_len == 1)
-           return collseqmb[br_elem->opr.name[0]];
-       }
-      return UINT_MAX;
-    }
-
-  /* Local function for parse_bracket_exp used in _LIBC environement.
-     Build the range expression which starts from START_ELEM, and ends
-     at END_ELEM.  The result are written to MBCSET and SBCSET.
-     RANGE_ALLOC is the allocated size of mbcset->range_starts, and
-     mbcset->range_ends, is a pointer argument sinse we may
-     update it.  */
-
-  auto inline reg_errcode_t
-  __attribute ((always_inline))
-  build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem)
-        re_charset_t *mbcset;
-        Idx *range_alloc;
-        bitset_t sbcset;
-        bracket_elem_t *start_elem, *end_elem;
-    {
-      unsigned int ch;
-      uint32_t start_collseq;
-      uint32_t end_collseq;
-
-      /* Equivalence Classes and Character Classes can't be a range
-        start/end.  */
-      if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
-             || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
-             0))
-       return REG_ERANGE;
-
-      start_collseq = lookup_collation_sequence_value (start_elem);
-      end_collseq = lookup_collation_sequence_value (end_elem);
-      /* Check start/end collation sequence values.  */
-      if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0))
-       return REG_ECOLLATE;
-      if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0))
-       return REG_ERANGE;
-
-      /* Got valid collation sequence values, add them as a new entry.
-        However, if we have no collation elements, and the character set
-        is single byte, the single byte character set that we
-        build below suffices. */
-      if (nrules > 0 || dfa->mb_cur_max > 1)
-       {
-         /* Check the space of the arrays.  */
-         if (BE (*range_alloc == mbcset->nranges, 0))
-           {
-             /* There is not enough space, need realloc.  */
-             uint32_t *new_array_start;
-             uint32_t *new_array_end;
-             Idx new_nranges;
-
-             /* +1 in case of mbcset->nranges is 0.  */
-             new_nranges = 2 * mbcset->nranges + 1;
-             new_array_start = re_realloc (mbcset->range_starts, uint32_t,
-                                           new_nranges);
-             new_array_end = re_realloc (mbcset->range_ends, uint32_t,
-                                         new_nranges);
-
-             if (BE (new_array_start == NULL || new_array_end == NULL, 0))
-               return REG_ESPACE;
-
-             mbcset->range_starts = new_array_start;
-             mbcset->range_ends = new_array_end;
-             *range_alloc = new_nranges;
-           }
-
-         mbcset->range_starts[mbcset->nranges] = start_collseq;
-         mbcset->range_ends[mbcset->nranges++] = end_collseq;
-       }
-
-      /* Build the table for single byte characters.  */
-      for (ch = 0; ch < SBC_MAX; ch++)
-       {
-         uint32_t ch_collseq;
-         /*
-         if (MB_CUR_MAX == 1)
-         */
-         if (nrules == 0)
-           ch_collseq = collseqmb[ch];
-         else
-           ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch));
-         if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)
-           bitset_set (sbcset, ch);
-       }
-      return REG_NOERROR;
-    }
-
-  /* Local function for parse_bracket_exp used in _LIBC environement.
-     Build the collating element which is represented by NAME.
-     The result are written to MBCSET and SBCSET.
-     COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
-     pointer argument sinse we may update it.  */
-
-  auto inline reg_errcode_t
-  __attribute ((always_inline))
-  build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name)
-        re_charset_t *mbcset;
-        Idx *coll_sym_alloc;
-        bitset_t sbcset;
-        const unsigned char *name;
-    {
-      int32_t elem, idx;
-      size_t name_len = strlen ((const char *) name);
-      if (nrules != 0)
-       {
-         elem = seek_collating_symbol_entry (name, name_len);
-         if (symb_table[2 * elem] != 0)
-           {
-             /* We found the entry.  */
-             idx = symb_table[2 * elem + 1];
-             /* Skip the name of collating element name.  */
-             idx += 1 + extra[idx];
-           }
-         else if (symb_table[2 * elem] == 0 && name_len == 1)
-           {
-             /* No valid character, treat it as a normal
-                character.  */
-             bitset_set (sbcset, name[0]);
-             return REG_NOERROR;
-           }
-         else
-           return REG_ECOLLATE;
-
-         /* Got valid collation sequence, add it as a new entry.  */
-         /* Check the space of the arrays.  */
-         if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0))
-           {
-             /* Not enough, realloc it.  */
-             /* +1 in case of mbcset->ncoll_syms is 0.  */
-             Idx new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1;
-             /* Use realloc since mbcset->coll_syms is NULL
-                if *alloc == 0.  */
-             int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t,
-                                                  new_coll_sym_alloc);
-             if (BE (new_coll_syms == NULL, 0))
-               return REG_ESPACE;
-             mbcset->coll_syms = new_coll_syms;
-             *coll_sym_alloc = new_coll_sym_alloc;
-           }
-         mbcset->coll_syms[mbcset->ncoll_syms++] = idx;
-         return REG_NOERROR;
-       }
-      else
-       {
-         if (BE (name_len != 1, 0))
-           return REG_ECOLLATE;
-         else
-           {
-             bitset_set (sbcset, name[0]);
-             return REG_NOERROR;
-           }
-       }
-    }
-#endif
-
-  re_token_t br_token;
-  re_bitset_ptr_t sbcset;
-#ifdef RE_ENABLE_I18N
-  re_charset_t *mbcset;
-  Idx coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;
-  Idx equiv_class_alloc = 0, char_class_alloc = 0;
-#endif /* not RE_ENABLE_I18N */
-  bool non_match = false;
-  bin_tree_t *work_tree;
-  int token_len;
-  bool first_round = true;
-#ifdef _LIBC
-  collseqmb = (const unsigned char *)
-    _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
-  nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-  if (nrules)
-    {
-      /*
-      if (MB_CUR_MAX > 1)
-      */
-      collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);
-      table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB);
-      symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE,
-                                                 _NL_COLLATE_SYMB_TABLEMB);
-      extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
-                                                  _NL_COLLATE_SYMB_EXTRAMB);
-    }
-#endif
-  sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
-#ifdef RE_ENABLE_I18N
-  mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
-#endif /* RE_ENABLE_I18N */
-#ifdef RE_ENABLE_I18N
-  if (BE (sbcset == NULL || mbcset == NULL, 0))
-#else
-  if (BE (sbcset == NULL, 0))
-#endif /* RE_ENABLE_I18N */
-    {
-      *err = REG_ESPACE;
-      return NULL;
-    }
-
-  token_len = peek_token_bracket (token, regexp, syntax);
-  if (BE (token->type == END_OF_RE, 0))
-    {
-      *err = REG_BADPAT;
-      goto parse_bracket_exp_free_return;
-    }
-  if (token->type == OP_NON_MATCH_LIST)
-    {
-#ifdef RE_ENABLE_I18N
-      mbcset->non_match = 1;
-#endif /* not RE_ENABLE_I18N */
-      non_match = true;
-      if (syntax & RE_HAT_LISTS_NOT_NEWLINE)
-       bitset_set (sbcset, '\n');
-      re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
-      token_len = peek_token_bracket (token, regexp, syntax);
-      if (BE (token->type == END_OF_RE, 0))
-       {
-         *err = REG_BADPAT;
-         goto parse_bracket_exp_free_return;
-       }
-    }
-
-  /* We treat the first ']' as a normal character.  */
-  if (token->type == OP_CLOSE_BRACKET)
-    token->type = CHARACTER;
-
-  while (1)
-    {
-      bracket_elem_t start_elem, end_elem;
-      unsigned char start_name_buf[BRACKET_NAME_BUF_SIZE];
-      unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE];
-      reg_errcode_t ret;
-      int token_len2 = 0;
-      bool is_range_exp = false;
-      re_token_t token2;
-
-      start_elem.opr.name = start_name_buf;
-      ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa,
-                                  syntax, first_round);
-      if (BE (ret != REG_NOERROR, 0))
-       {
-         *err = ret;
-         goto parse_bracket_exp_free_return;
-       }
-      first_round = false;
-
-      /* Get information about the next token.  We need it in any case.  */
-      token_len = peek_token_bracket (token, regexp, syntax);
-
-      /* Do not check for ranges if we know they are not allowed.  */
-      if (start_elem.type != CHAR_CLASS && start_elem.type != EQUIV_CLASS)
-       {
-         if (BE (token->type == END_OF_RE, 0))
-           {
-             *err = REG_EBRACK;
-             goto parse_bracket_exp_free_return;
-           }
-         if (token->type == OP_CHARSET_RANGE)
-           {
-             re_string_skip_bytes (regexp, token_len); /* Skip '-'.  */
-             token_len2 = peek_token_bracket (&token2, regexp, syntax);
-             if (BE (token2.type == END_OF_RE, 0))
-               {
-                 *err = REG_EBRACK;
-                 goto parse_bracket_exp_free_return;
-               }
-             if (token2.type == OP_CLOSE_BRACKET)
-               {
-                 /* We treat the last '-' as a normal character.  */
-                 re_string_skip_bytes (regexp, -token_len);
-                 token->type = CHARACTER;
-               }
-             else
-               is_range_exp = true;
-           }
-       }
-
-      if (is_range_exp == true)
-       {
-         end_elem.opr.name = end_name_buf;
-         ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2,
-                                      dfa, syntax, true);
-         if (BE (ret != REG_NOERROR, 0))
-           {
-             *err = ret;
-             goto parse_bracket_exp_free_return;
-           }
-
-         token_len = peek_token_bracket (token, regexp, syntax);
-
-#ifdef _LIBC
-         *err = build_range_exp (sbcset, mbcset, &range_alloc,
-                                 &start_elem, &end_elem);
-#else
-# ifdef RE_ENABLE_I18N
-         *err = build_range_exp (syntax, sbcset,
-                                 dfa->mb_cur_max > 1 ? mbcset : NULL,
-                                 &range_alloc, &start_elem, &end_elem);
-# else
-         *err = build_range_exp (syntax, sbcset, &start_elem, &end_elem);
-# endif
-#endif /* RE_ENABLE_I18N */
-         if (BE (*err != REG_NOERROR, 0))
-           goto parse_bracket_exp_free_return;
-       }
-      else
-       {
-         switch (start_elem.type)
-           {
-           case SB_CHAR:
-             bitset_set (sbcset, start_elem.opr.ch);
-             break;
-#ifdef RE_ENABLE_I18N
-           case MB_CHAR:
-             /* Check whether the array has enough space.  */
-             if (BE (mbchar_alloc == mbcset->nmbchars, 0))
-               {
-                 wchar_t *new_mbchars;
-                 /* Not enough, realloc it.  */
-                 /* +1 in case of mbcset->nmbchars is 0.  */
-                 mbchar_alloc = 2 * mbcset->nmbchars + 1;
-                 /* Use realloc since array is NULL if *alloc == 0.  */
-                 new_mbchars = re_realloc (mbcset->mbchars, wchar_t,
-                                           mbchar_alloc);
-                 if (BE (new_mbchars == NULL, 0))
-                   goto parse_bracket_exp_espace;
-                 mbcset->mbchars = new_mbchars;
-               }
-             mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;
-             break;
-#endif /* RE_ENABLE_I18N */
-           case EQUIV_CLASS:
-             *err = build_equiv_class (sbcset,
-#ifdef RE_ENABLE_I18N
-                                       mbcset, &equiv_class_alloc,
-#endif /* RE_ENABLE_I18N */
-                                       start_elem.opr.name);
-             if (BE (*err != REG_NOERROR, 0))
-               goto parse_bracket_exp_free_return;
-             break;
-           case COLL_SYM:
-             *err = build_collating_symbol (sbcset,
-#ifdef RE_ENABLE_I18N
-                                            mbcset, &coll_sym_alloc,
-#endif /* RE_ENABLE_I18N */
-                                            start_elem.opr.name);
-             if (BE (*err != REG_NOERROR, 0))
-               goto parse_bracket_exp_free_return;
-             break;
-           case CHAR_CLASS:
-             *err = build_charclass (regexp->trans, sbcset,
-#ifdef RE_ENABLE_I18N
-                                     mbcset, &char_class_alloc,
-#endif /* RE_ENABLE_I18N */
-                                     start_elem.opr.name, syntax);
-             if (BE (*err != REG_NOERROR, 0))
-              goto parse_bracket_exp_free_return;
-             break;
-           default:
-             assert (0);
-             break;
-           }
-       }
-      if (BE (token->type == END_OF_RE, 0))
-       {
-         *err = REG_EBRACK;
-         goto parse_bracket_exp_free_return;
-       }
-      if (token->type == OP_CLOSE_BRACKET)
-       break;
-    }
-
-  re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
-
-  /* If it is non-matching list.  */
-  if (non_match)
-    bitset_not (sbcset);
-
-#ifdef RE_ENABLE_I18N
-  /* Ensure only single byte characters are set.  */
-  if (dfa->mb_cur_max > 1)
-    bitset_mask (sbcset, dfa->sb_char);
-
-  if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes
-      || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes
-                                                    || mbcset->non_match)))
-    {
-      bin_tree_t *mbc_tree;
-      int sbc_idx;
-      /* Build a tree for complex bracket.  */
-      dfa->has_mb_node = 1;
-      br_token.type = COMPLEX_BRACKET;
-      br_token.opr.mbcset = mbcset;
-      mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token);
-      if (BE (mbc_tree == NULL, 0))
-       goto parse_bracket_exp_espace;
-      for (sbc_idx = 0; sbc_idx < BITSET_WORDS; ++sbc_idx)
-       if (sbcset[sbc_idx])
-         break;
-      /* If there are no bits set in sbcset, there is no point
-        of having both SIMPLE_BRACKET and COMPLEX_BRACKET.  */
-      if (sbc_idx < BITSET_WORDS)
-       {
-         /* Build a tree for simple bracket.  */
-         br_token.type = SIMPLE_BRACKET;
-         br_token.opr.sbcset = sbcset;
-         work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
-         if (BE (work_tree == NULL, 0))
-           goto parse_bracket_exp_espace;
-
-         /* Then join them by ALT node.  */
-         work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT);
-         if (BE (work_tree == NULL, 0))
-           goto parse_bracket_exp_espace;
-       }
-      else
-       {
-         re_free (sbcset);
-         work_tree = mbc_tree;
-       }
-    }
-  else
-#endif /* not RE_ENABLE_I18N */
-    {
-#ifdef RE_ENABLE_I18N
-      free_charset (mbcset);
-#endif
-      /* Build a tree for simple bracket.  */
-      br_token.type = SIMPLE_BRACKET;
-      br_token.opr.sbcset = sbcset;
-      work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
-      if (BE (work_tree == NULL, 0))
-       goto parse_bracket_exp_espace;
-    }
-  return work_tree;
-
- parse_bracket_exp_espace:
-  *err = REG_ESPACE;
- parse_bracket_exp_free_return:
-  re_free (sbcset);
-#ifdef RE_ENABLE_I18N
-  free_charset (mbcset);
-#endif /* RE_ENABLE_I18N */
-  return NULL;
-}
-
-/* Parse an element in the bracket expression.  */
-
-static reg_errcode_t
-parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,
-                      re_token_t *token, int token_len, re_dfa_t *dfa,
-                      reg_syntax_t syntax, bool accept_hyphen)
-{
-#ifdef RE_ENABLE_I18N
-  int cur_char_size;
-  cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp));
-  if (cur_char_size > 1)
-    {
-      elem->type = MB_CHAR;
-      elem->opr.wch = re_string_wchar_at (regexp, re_string_cur_idx (regexp));
-      re_string_skip_bytes (regexp, cur_char_size);
-      return REG_NOERROR;
-    }
-#endif /* RE_ENABLE_I18N */
-  re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
-  if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS
-      || token->type == OP_OPEN_EQUIV_CLASS)
-    return parse_bracket_symbol (elem, regexp, token);
-  if (BE (token->type == OP_CHARSET_RANGE, 0) && !accept_hyphen)
-    {
-      /* A '-' must only appear as anything but a range indicator before
-        the closing bracket.  Everything else is an error.  */
-      re_token_t token2;
-      (void) peek_token_bracket (&token2, regexp, syntax);
-      if (token2.type != OP_CLOSE_BRACKET)
-       /* The actual error value is not standardized since this whole
-          case is undefined.  But ERANGE makes good sense.  */
-       return REG_ERANGE;
-    }
-  elem->type = SB_CHAR;
-  elem->opr.ch = token->opr.c;
-  return REG_NOERROR;
-}
-
-/* Parse a bracket symbol in the bracket expression.  Bracket symbols are
-   such as [:<character_class>:], [.<collating_element>.], and
-   [=<equivalent_class>=].  */
-
-static reg_errcode_t
-parse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp,
-                     re_token_t *token)
-{
-  unsigned char ch, delim = token->opr.c;
-  int i = 0;
-  if (re_string_eoi(regexp))
-    return REG_EBRACK;
-  for (;; ++i)
-    {
-      if (i >= BRACKET_NAME_BUF_SIZE)
-       return REG_EBRACK;
-      if (token->type == OP_OPEN_CHAR_CLASS)
-       ch = re_string_fetch_byte_case (regexp);
-      else
-       ch = re_string_fetch_byte (regexp);
-      if (re_string_eoi(regexp))
-       return REG_EBRACK;
-      if (ch == delim && re_string_peek_byte (regexp, 0) == ']')
-       break;
-      elem->opr.name[i] = ch;
-    }
-  re_string_skip_bytes (regexp, 1);
-  elem->opr.name[i] = '\0';
-  switch (token->type)
-    {
-    case OP_OPEN_COLL_ELEM:
-      elem->type = COLL_SYM;
-      break;
-    case OP_OPEN_EQUIV_CLASS:
-      elem->type = EQUIV_CLASS;
-      break;
-    case OP_OPEN_CHAR_CLASS:
-      elem->type = CHAR_CLASS;
-      break;
-    default:
-      break;
-    }
-  return REG_NOERROR;
-}
-
-  /* Helper function for parse_bracket_exp.
-     Build the equivalence class which is represented by NAME.
-     The result are written to MBCSET and SBCSET.
-     EQUIV_CLASS_ALLOC is the allocated size of mbcset->equiv_classes,
-     is a pointer argument sinse we may update it.  */
-
-static reg_errcode_t
-#ifdef RE_ENABLE_I18N
-build_equiv_class (bitset_t sbcset, re_charset_t *mbcset,
-                  Idx *equiv_class_alloc, const unsigned char *name)
-#else /* not RE_ENABLE_I18N */
-build_equiv_class (bitset_t sbcset, const unsigned char *name)
-#endif /* not RE_ENABLE_I18N */
-{
-#ifdef _LIBC
-  uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-  if (nrules != 0)
-    {
-      const int32_t *table, *indirect;
-      const unsigned char *weights, *extra, *cp;
-      unsigned char char_buf[2];
-      int32_t idx1, idx2;
-      unsigned int ch;
-      size_t len;
-      /* This #include defines a local function!  */
-# include <locale/weight.h>
-      /* Calculate the index for equivalence class.  */
-      cp = name;
-      table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
-      weights = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
-                                              _NL_COLLATE_WEIGHTMB);
-      extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
-                                                  _NL_COLLATE_EXTRAMB);
-      indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
-                                               _NL_COLLATE_INDIRECTMB);
-      idx1 = findidx (&cp);
-      if (BE (idx1 == 0 || cp < name + strlen ((const char *) name), 0))
-       /* This isn't a valid character.  */
-       return REG_ECOLLATE;
-
-      /* Build single byte matcing table for this equivalence class.  */
-      char_buf[1] = (unsigned char) '\0';
-      len = weights[idx1 & 0xffffff];
-      for (ch = 0; ch < SBC_MAX; ++ch)
-       {
-         char_buf[0] = ch;
-         cp = char_buf;
-         idx2 = findidx (&cp);
-/*
-         idx2 = table[ch];
-*/
-         if (idx2 == 0)
-           /* This isn't a valid character.  */
-           continue;
-         /* Compare only if the length matches and the collation rule
-            index is the same.  */
-         if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24))
-           {
-             int cnt = 0;
-
-             while (cnt <= len &&
-                    weights[(idx1 & 0xffffff) + 1 + cnt]
-                    == weights[(idx2 & 0xffffff) + 1 + cnt])
-               ++cnt;
-
-             if (cnt > len)
-               bitset_set (sbcset, ch);
-           }
-       }
-      /* Check whether the array has enough space.  */
-      if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0))
-       {
-         /* Not enough, realloc it.  */
-         /* +1 in case of mbcset->nequiv_classes is 0.  */
-         Idx new_equiv_class_alloc = 2 * mbcset->nequiv_classes + 1;
-         /* Use realloc since the array is NULL if *alloc == 0.  */
-         int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes,
-                                                  int32_t,
-                                                  new_equiv_class_alloc);
-         if (BE (new_equiv_classes == NULL, 0))
-           return REG_ESPACE;
-         mbcset->equiv_classes = new_equiv_classes;
-         *equiv_class_alloc = new_equiv_class_alloc;
-       }
-      mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;
-    }
-  else
-#endif /* _LIBC */
-    {
-      if (BE (strlen ((const char *) name) != 1, 0))
-       return REG_ECOLLATE;
-      bitset_set (sbcset, *name);
-    }
-  return REG_NOERROR;
-}
-
-  /* Helper function for parse_bracket_exp.
-     Build the character class which is represented by NAME.
-     The result are written to MBCSET and SBCSET.
-     CHAR_CLASS_ALLOC is the allocated size of mbcset->char_classes,
-     is a pointer argument sinse we may update it.  */
-
-static reg_errcode_t
-#ifdef RE_ENABLE_I18N
-build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
-                re_charset_t *mbcset, Idx *char_class_alloc,
-                const unsigned char *class_name, reg_syntax_t syntax)
-#else /* not RE_ENABLE_I18N */
-build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
-                const unsigned char *class_name, reg_syntax_t syntax)
-#endif /* not RE_ENABLE_I18N */
-{
-  int i;
-  const char *name = (const char *) class_name;
-
-  /* In case of REG_ICASE "upper" and "lower" match the both of
-     upper and lower cases.  */
-  if ((syntax & RE_ICASE)
-      && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0))
-    name = "alpha";
-
-#ifdef RE_ENABLE_I18N
-  /* Check the space of the arrays.  */
-  if (BE (*char_class_alloc == mbcset->nchar_classes, 0))
-    {
-      /* Not enough, realloc it.  */
-      /* +1 in case of mbcset->nchar_classes is 0.  */
-      Idx new_char_class_alloc = 2 * mbcset->nchar_classes + 1;
-      /* Use realloc since array is NULL if *alloc == 0.  */
-      wctype_t *new_char_classes = re_realloc (mbcset->char_classes, wctype_t,
-                                              new_char_class_alloc);
-      if (BE (new_char_classes == NULL, 0))
-       return REG_ESPACE;
-      mbcset->char_classes = new_char_classes;
-      *char_class_alloc = new_char_class_alloc;
-    }
-  mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name);
-#endif /* RE_ENABLE_I18N */
-
-#define BUILD_CHARCLASS_LOOP(ctype_func)       \
-  do {                                         \
-    if (BE (trans != NULL, 0))                 \
-      {                                                \
-       for (i = 0; i < SBC_MAX; ++i)           \
-         if (ctype_func (i))                   \
-           bitset_set (sbcset, trans[i]);      \
-      }                                                \
-    else                                       \
-      {                                                \
-       for (i = 0; i < SBC_MAX; ++i)           \
-         if (ctype_func (i))                   \
-           bitset_set (sbcset, i);             \
-      }                                                \
-  } while (0)
-
-  if (strcmp (name, "alnum") == 0)
-    BUILD_CHARCLASS_LOOP (isalnum);
-  else if (strcmp (name, "cntrl") == 0)
-    BUILD_CHARCLASS_LOOP (iscntrl);
-  else if (strcmp (name, "lower") == 0)
-    BUILD_CHARCLASS_LOOP (islower);
-  else if (strcmp (name, "space") == 0)
-    BUILD_CHARCLASS_LOOP (isspace);
-  else if (strcmp (name, "alpha") == 0)
-    BUILD_CHARCLASS_LOOP (isalpha);
-  else if (strcmp (name, "digit") == 0)
-    BUILD_CHARCLASS_LOOP (isdigit);
-  else if (strcmp (name, "print") == 0)
-    BUILD_CHARCLASS_LOOP (isprint);
-  else if (strcmp (name, "upper") == 0)
-    BUILD_CHARCLASS_LOOP (isupper);
-  else if (strcmp (name, "blank") == 0)
-    BUILD_CHARCLASS_LOOP (isblank);
-  else if (strcmp (name, "graph") == 0)
-    BUILD_CHARCLASS_LOOP (isgraph);
-  else if (strcmp (name, "punct") == 0)
-    BUILD_CHARCLASS_LOOP (ispunct);
-  else if (strcmp (name, "xdigit") == 0)
-    BUILD_CHARCLASS_LOOP (isxdigit);
-  else
-    return REG_ECTYPE;
-
-  return REG_NOERROR;
-}
-
-static bin_tree_t *
-build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
-                   const unsigned char *class_name,
-                   const unsigned char *extra, bool non_match,
-                   reg_errcode_t *err)
-{
-  re_bitset_ptr_t sbcset;
-#ifdef RE_ENABLE_I18N
-  re_charset_t *mbcset;
-  Idx alloc = 0;
-#endif /* not RE_ENABLE_I18N */
-  reg_errcode_t ret;
-  re_token_t br_token;
-  bin_tree_t *tree;
-
-  sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
-#ifdef RE_ENABLE_I18N
-  mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
-#endif /* RE_ENABLE_I18N */
-
-#ifdef RE_ENABLE_I18N
-  if (BE (sbcset == NULL || mbcset == NULL, 0))
-#else /* not RE_ENABLE_I18N */
-  if (BE (sbcset == NULL, 0))
-#endif /* not RE_ENABLE_I18N */
-    {
-      *err = REG_ESPACE;
-      return NULL;
-    }
-
-  if (non_match)
-    {
-#ifdef RE_ENABLE_I18N
-      mbcset->non_match = 1;
-#endif /* not RE_ENABLE_I18N */
-    }
-
-  /* We don't care the syntax in this case.  */
-  ret = build_charclass (trans, sbcset,
-#ifdef RE_ENABLE_I18N
-                        mbcset, &alloc,
-#endif /* RE_ENABLE_I18N */
-                        class_name, 0);
-
-  if (BE (ret != REG_NOERROR, 0))
-    {
-      re_free (sbcset);
-#ifdef RE_ENABLE_I18N
-      free_charset (mbcset);
-#endif /* RE_ENABLE_I18N */
-      *err = ret;
-      return NULL;
-    }
-  /* \w match '_' also.  */
-  for (; *extra; extra++)
-    bitset_set (sbcset, *extra);
-
-  /* If it is non-matching list.  */
-  if (non_match)
-    bitset_not (sbcset);
-
-#ifdef RE_ENABLE_I18N
-  /* Ensure only single byte characters are set.  */
-  if (dfa->mb_cur_max > 1)
-    bitset_mask (sbcset, dfa->sb_char);
-#endif
-
-  /* Build a tree for simple bracket.  */
-  br_token.type = SIMPLE_BRACKET;
-  br_token.opr.sbcset = sbcset;
-  tree = create_token_tree (dfa, NULL, NULL, &br_token);
-  if (BE (tree == NULL, 0))
-    goto build_word_op_espace;
-
-#ifdef RE_ENABLE_I18N
-  if (dfa->mb_cur_max > 1)
-    {
-      bin_tree_t *mbc_tree;
-      /* Build a tree for complex bracket.  */
-      br_token.type = COMPLEX_BRACKET;
-      br_token.opr.mbcset = mbcset;
-      dfa->has_mb_node = 1;
-      mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token);
-      if (BE (mbc_tree == NULL, 0))
-       goto build_word_op_espace;
-      /* Then join them by ALT node.  */
-      tree = create_tree (dfa, tree, mbc_tree, OP_ALT);
-      if (BE (mbc_tree != NULL, 1))
-       return tree;
-    }
-  else
-    {
-      free_charset (mbcset);
-      return tree;
-    }
-#else /* not RE_ENABLE_I18N */
-  return tree;
-#endif /* not RE_ENABLE_I18N */
-
- build_word_op_espace:
-  re_free (sbcset);
-#ifdef RE_ENABLE_I18N
-  free_charset (mbcset);
-#endif /* RE_ENABLE_I18N */
-  *err = REG_ESPACE;
-  return NULL;
-}
-
-/* This is intended for the expressions like "a{1,3}".
-   Fetch a number from `input', and return the number.
-   Return REG_MISSING if the number field is empty like "{,1}".
-   Return REG_ERROR if an error occurred.  */
-
-static Idx
-fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax)
-{
-  Idx num = REG_MISSING;
-  unsigned char c;
-  while (1)
-    {
-      fetch_token (token, input, syntax);
-      c = token->opr.c;
-      if (BE (token->type == END_OF_RE, 0))
-       return REG_ERROR;
-      if (token->type == OP_CLOSE_DUP_NUM || c == ',')
-       break;
-      num = ((token->type != CHARACTER || c < '0' || '9' < c
-             || num == REG_ERROR)
-            ? REG_ERROR
-            : ((num == REG_MISSING) ? c - '0' : num * 10 + c - '0'));
-      num = (num > RE_DUP_MAX) ? REG_ERROR : num;
-    }
-  return num;
-}
-\f
-#ifdef RE_ENABLE_I18N
-static void
-free_charset (re_charset_t *cset)
-{
-  re_free (cset->mbchars);
-# ifdef _LIBC
-  re_free (cset->coll_syms);
-  re_free (cset->equiv_classes);
-  re_free (cset->range_starts);
-  re_free (cset->range_ends);
-# endif
-  re_free (cset->char_classes);
-  re_free (cset);
-}
-#endif /* RE_ENABLE_I18N */
-\f
-/* Functions for binary tree operation.  */
-
-/* Create a tree node.  */
-
-static bin_tree_t *
-create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,
-            re_token_type_t type)
-{
-  re_token_t t;
-  t.type = type;
-  return create_token_tree (dfa, left, right, &t);
-}
-
-static bin_tree_t *
-create_token_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,
-                  const re_token_t *token)
-{
-  bin_tree_t *tree;
-  if (BE (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE, 0))
-    {
-      bin_tree_storage_t *storage = re_malloc (bin_tree_storage_t, 1);
-
-      if (storage == NULL)
-       return NULL;
-      storage->next = dfa->str_tree_storage;
-      dfa->str_tree_storage = storage;
-      dfa->str_tree_storage_idx = 0;
-    }
-  tree = &dfa->str_tree_storage->data[dfa->str_tree_storage_idx++];
-
-  tree->parent = NULL;
-  tree->left = left;
-  tree->right = right;
-  tree->token = *token;
-  tree->token.duplicated = 0;
-  tree->token.opt_subexp = 0;
-  tree->first = NULL;
-  tree->next = NULL;
-  tree->node_idx = REG_MISSING;
-
-  if (left != NULL)
-    left->parent = tree;
-  if (right != NULL)
-    right->parent = tree;
-  return tree;
-}
-
-/* Mark the tree SRC as an optional subexpression.
-   To be called from preorder or postorder.  */
-
-static reg_errcode_t
-mark_opt_subexp (void *extra, bin_tree_t *node)
-{
-  Idx idx = (Idx) (long) extra;
-  if (node->token.type == SUBEXP && node->token.opr.idx == idx)
-    node->token.opt_subexp = 1;
-
-  return REG_NOERROR;
-}
-
-/* Free the allocated memory inside NODE. */
-
-static void
-free_token (re_token_t *node)
-{
-#ifdef RE_ENABLE_I18N
-  if (node->type == COMPLEX_BRACKET && node->duplicated == 0)
-    free_charset (node->opr.mbcset);
-  else
-#endif /* RE_ENABLE_I18N */
-    if (node->type == SIMPLE_BRACKET && node->duplicated == 0)
-      re_free (node->opr.sbcset);
-}
-
-/* Worker function for tree walking.  Free the allocated memory inside NODE
-   and its children. */
-
-static reg_errcode_t
-free_tree (void *extra, bin_tree_t *node)
-{
-  free_token (&node->token);
-  return REG_NOERROR;
-}
-
-
-/* Duplicate the node SRC, and return new node.  This is a preorder
-   visit similar to the one implemented by the generic visitor, but
-   we need more infrastructure to maintain two parallel trees --- so,
-   it's easier to duplicate.  */
-
-static bin_tree_t *
-duplicate_tree (const bin_tree_t *root, re_dfa_t *dfa)
-{
-  const bin_tree_t *node;
-  bin_tree_t *dup_root;
-  bin_tree_t **p_new = &dup_root, *dup_node = root->parent;
-
-  for (node = root; ; )
-    {
-      /* Create a new tree and link it back to the current parent.  */
-      *p_new = create_token_tree (dfa, NULL, NULL, &node->token);
-      if (*p_new == NULL)
-       return NULL;
-      (*p_new)->parent = dup_node;
-      (*p_new)->token.duplicated = 1;
-      dup_node = *p_new;
-
-      /* Go to the left node, or up and to the right.  */
-      if (node->left)
-       {
-         node = node->left;
-         p_new = &dup_node->left;
-       }
-      else
-       {
-         const bin_tree_t *prev = NULL;
-         while (node->right == prev || node->right == NULL)
-           {
-             prev = node;
-             node = node->parent;
-             dup_node = dup_node->parent;
-             if (!node)
-               return dup_root;
-           }
-         node = node->right;
-         p_new = &dup_node->right;
-       }
-    }
-}
diff --git a/gnulib/regex.c b/gnulib/regex.c
deleted file mode 100644 (file)
index 904fe62..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Extended regular expression matching and search library.
-   Copyright (C) 2002, 2003, 2005, 2006, 2009, 2010 Free Software Foundation,
-   Inc.
-   This file is part of the GNU C Library.
-   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
-
-   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#include <config.h>
-
-/* Make sure noone compiles this code with a C++ compiler.  */
-#if defined __cplusplus && defined _LIBC
-# error "This is C code, use a C compiler"
-#endif
-
-#ifdef _LIBC
-/* We have to keep the namespace clean.  */
-# define regfree(preg) __regfree (preg)
-# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
-# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
-# define regerror(errcode, preg, errbuf, errbuf_size) \
-       __regerror(errcode, preg, errbuf, errbuf_size)
-# define re_set_registers(bu, re, nu, st, en) \
-       __re_set_registers (bu, re, nu, st, en)
-# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
-       __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
-# define re_match(bufp, string, size, pos, regs) \
-       __re_match (bufp, string, size, pos, regs)
-# define re_search(bufp, string, size, startpos, range, regs) \
-       __re_search (bufp, string, size, startpos, range, regs)
-# define re_compile_pattern(pattern, length, bufp) \
-       __re_compile_pattern (pattern, length, bufp)
-# define re_set_syntax(syntax) __re_set_syntax (syntax)
-# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
-       __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
-# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
-
-# include "../locale/localeinfo.h"
-#endif
-
-/* On some systems, limits.h sets RE_DUP_MAX to a lower value than
-   GNU regex allows.  Include it before <regex.h>, which correctly
-   #undefs RE_DUP_MAX and sets it to the right value.  */
-#include <limits.h>
-
-#include <regex.h>
-#include "regex_internal.h"
-
-#include "regex_internal.c"
-#include "regcomp.c"
-#include "regexec.c"
-
-/* Binary backward compatibility.  */
-#if _LIBC
-# include <shlib-compat.h>
-# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)
-link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.")
-int re_max_failures = 2000;
-# endif
-#endif
diff --git a/gnulib/regex.h b/gnulib/regex.h
deleted file mode 100644 (file)
index 594d5e6..0000000
+++ /dev/null
@@ -1,676 +0,0 @@
-/* Definitions for data structures and routines for the regular
-   expression library.
-   Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993, 1995, 1996, 1997, 1998,
-   2000, 2001, 2002, 2003, 2005, 2006, 2009, 2010 Free Software Foundation,
-   Inc.
-   This file is part of the GNU C Library.
-
-   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifndef _REGEX_H
-#define _REGEX_H 1
-
-#include <sys/types.h>
-
-/* Allow the use in C++ code.  */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Define __USE_GNU_REGEX to declare GNU extensions that violate the
-   POSIX name space rules.  */
-#undef __USE_GNU_REGEX
-#if (defined _GNU_SOURCE                                       \
-     || (!defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE    \
-        && !defined _XOPEN_SOURCE))
-# define __USE_GNU_REGEX 1
-#endif
-
-#ifdef _REGEX_LARGE_OFFSETS
-
-/* Use types and values that are wide enough to represent signed and
-   unsigned byte offsets in memory.  This currently works only when
-   the regex code is used outside of the GNU C library; it is not yet
-   supported within glibc itself, and glibc users should not define
-   _REGEX_LARGE_OFFSETS.  */
-
-/* The type of the offset of a byte within a string.
-   For historical reasons POSIX 1003.1-2004 requires that regoff_t be
-   at least as wide as off_t.  However, many common POSIX platforms set
-   regoff_t to the more-sensible ssize_t and the Open Group has
-   signalled its intention to change the requirement to be that
-   regoff_t be at least as wide as ptrdiff_t and ssize_t; see XBD ERN
-   60 (2005-08-25).  We don't know of any hosts where ssize_t or
-   ptrdiff_t is wider than ssize_t, so ssize_t is safe.  */
-typedef ssize_t regoff_t;
-
-/* The type of nonnegative object indexes.  Traditionally, GNU regex
-   uses 'int' for these.  Code that uses __re_idx_t should work
-   regardless of whether the type is signed.  */
-typedef size_t __re_idx_t;
-
-/* The type of object sizes.  */
-typedef size_t __re_size_t;
-
-/* The type of object sizes, in places where the traditional code
-   uses unsigned long int.  */
-typedef size_t __re_long_size_t;
-
-#else
-
-/* Use types that are binary-compatible with the traditional GNU regex
-   implementation, which mishandles strings longer than INT_MAX.  */
-
-typedef int regoff_t;
-typedef int __re_idx_t;
-typedef unsigned int __re_size_t;
-typedef unsigned long int __re_long_size_t;
-
-#endif
-
-/* The following two types have to be signed and unsigned integer type
-   wide enough to hold a value of a pointer.  For most ANSI compilers
-   ptrdiff_t and size_t should be likely OK.  Still size of these two
-   types is 2 for Microsoft C.  Ugh... */
-typedef long int s_reg_t;
-typedef unsigned long int active_reg_t;
-
-/* The following bits are used to determine the regexp syntax we
-   recognize.  The set/not-set meanings are chosen so that Emacs syntax
-   remains the value 0.  The bits are given in alphabetical order, and
-   the definitions shifted by one from the previous bit; thus, when we
-   add or remove a bit, only one other definition need change.  */
-typedef unsigned long int reg_syntax_t;
-
-#ifdef __USE_GNU_REGEX
-
-/* If this bit is not set, then \ inside a bracket expression is literal.
-   If set, then such a \ quotes the following character.  */
-# define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)
-
-/* If this bit is not set, then + and ? are operators, and \+ and \? are
-     literals.
-   If set, then \+ and \? are operators and + and ? are literals.  */
-# define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
-
-/* If this bit is set, then character classes are supported.  They are:
-     [:alpha:], [:upper:], [:lower:],  [:digit:], [:alnum:], [:xdigit:],
-     [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
-   If not set, then character classes are not supported.  */
-# define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
-
-/* If this bit is set, then ^ and $ are always anchors (outside bracket
-     expressions, of course).
-   If this bit is not set, then it depends:
-        ^  is an anchor if it is at the beginning of a regular
-           expression or after an open-group or an alternation operator;
-        $  is an anchor if it is at the end of a regular expression, or
-           before a close-group or an alternation operator.
-
-   This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
-   POSIX draft 11.2 says that * etc. in leading positions is undefined.
-   We already implemented a previous draft which made those constructs
-   invalid, though, so we haven't changed the code back.  */
-# define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
-
-/* If this bit is set, then special characters are always special
-     regardless of where they are in the pattern.
-   If this bit is not set, then special characters are special only in
-     some contexts; otherwise they are ordinary.  Specifically,
-     * + ? and intervals are only special when not after the beginning,
-     open-group, or alternation operator.  */
-# define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
-
-/* If this bit is set, then *, +, ?, and { cannot be first in an re or
-     immediately after an alternation or begin-group operator.  */
-# define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
-
-/* If this bit is set, then . matches newline.
-   If not set, then it doesn't.  */
-# define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
-
-/* If this bit is set, then . doesn't match NUL.
-   If not set, then it does.  */
-# define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
-
-/* If this bit is set, nonmatching lists [^...] do not match newline.
-   If not set, they do.  */
-# define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
-
-/* If this bit is set, either \{...\} or {...} defines an
-     interval, depending on RE_NO_BK_BRACES.
-   If not set, \{, \}, {, and } are literals.  */
-# define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
-
-/* If this bit is set, +, ? and | aren't recognized as operators.
-   If not set, they are.  */
-# define RE_LIMITED_OPS (RE_INTERVALS << 1)
-
-/* If this bit is set, newline is an alternation operator.
-   If not set, newline is literal.  */
-# define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
-
-/* If this bit is set, then `{...}' defines an interval, and \{ and \}
-     are literals.
-  If not set, then `\{...\}' defines an interval.  */
-# define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
-
-/* If this bit is set, (...) defines a group, and \( and \) are literals.
-   If not set, \(...\) defines a group, and ( and ) are literals.  */
-# define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
-
-/* If this bit is set, then \<digit> matches <digit>.
-   If not set, then \<digit> is a back-reference.  */
-# define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
-
-/* If this bit is set, then | is an alternation operator, and \| is literal.
-   If not set, then \| is an alternation operator, and | is literal.  */
-# define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
-
-/* If this bit is set, then an ending range point collating higher
-     than the starting range point, as in [z-a], is invalid.
-   If not set, then when ending range point collates higher than the
-     starting range point, the range is ignored.  */
-# define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
-
-/* If this bit is set, then an unmatched ) is ordinary.
-   If not set, then an unmatched ) is invalid.  */
-# define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
-
-/* If this bit is set, succeed as soon as we match the whole pattern,
-   without further backtracking.  */
-# define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
-
-/* If this bit is set, do not process the GNU regex operators.
-   If not set, then the GNU regex operators are recognized. */
-# define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)
-
-/* If this bit is set, turn on internal regex debugging.
-   If not set, and debugging was on, turn it off.
-   This only works if regex.c is compiled -DDEBUG.
-   We define this bit always, so that all that's needed to turn on
-   debugging is to recompile regex.c; the calling code can always have
-   this bit set, and it won't affect anything in the normal case. */
-# define RE_DEBUG (RE_NO_GNU_OPS << 1)
-
-/* If this bit is set, a syntactically invalid interval is treated as
-   a string of ordinary characters.  For example, the ERE 'a{1' is
-   treated as 'a\{1'.  */
-# define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
-
-/* If this bit is set, then ignore case when matching.
-   If not set, then case is significant.  */
-# define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
-
-/* This bit is used internally like RE_CONTEXT_INDEP_ANCHORS but only
-   for ^, because it is difficult to scan the regex backwards to find
-   whether ^ should be special.  */
-# define RE_CARET_ANCHORS_HERE (RE_ICASE << 1)
-
-/* If this bit is set, then \{ cannot be first in an bre or
-   immediately after an alternation or begin-group operator.  */
-# define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1)
-
-/* If this bit is set, then no_sub will be set to 1 during
-   re_compile_pattern.  */
-# define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1)
-
-#endif /* defined __USE_GNU_REGEX */
-
-/* This global variable defines the particular regexp syntax to use (for
-   some interfaces).  When a regexp is compiled, the syntax used is
-   stored in the pattern buffer, so changing this does not affect
-   already-compiled regexps.  */
-extern reg_syntax_t re_syntax_options;
-\f
-#ifdef __USE_GNU_REGEX
-/* Define combinations of the above bits for the standard possibilities.
-   (The [[[ comments delimit what gets put into the Texinfo file, so
-   don't delete them!)  */
-/* [[[begin syntaxes]]] */
-# define RE_SYNTAX_EMACS 0
-
-# define RE_SYNTAX_AWK                                                 \
-  (RE_BACKSLASH_ESCAPE_IN_LISTS   | RE_DOT_NOT_NULL                    \
-   | RE_NO_BK_PARENS              | RE_NO_BK_REFS                      \
-   | RE_NO_BK_VBAR                | RE_NO_EMPTY_RANGES                 \
-   | RE_DOT_NEWLINE              | RE_CONTEXT_INDEP_ANCHORS            \
-   | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
-
-# define RE_SYNTAX_GNU_AWK                                             \
-  ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG)        \
-   & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS           \
-       | RE_CONTEXT_INVALID_OPS ))
-
-# define RE_SYNTAX_POSIX_AWK                                           \
-  (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS             \
-   | RE_INTERVALS          | RE_NO_GNU_OPS)
-
-# define RE_SYNTAX_GREP                                                        \
-  (RE_BK_PLUS_QM              | RE_CHAR_CLASSES                                \
-   | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS                           \
-   | RE_NEWLINE_ALT)
-
-# define RE_SYNTAX_EGREP                                               \
-  (RE_CHAR_CLASSES        | RE_CONTEXT_INDEP_ANCHORS                   \
-   | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE                   \
-   | RE_NEWLINE_ALT       | RE_NO_BK_PARENS                            \
-   | RE_NO_BK_VBAR)
-
-# define RE_SYNTAX_POSIX_EGREP                                         \
-  (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES                    \
-   | RE_INVALID_INTERVAL_ORD)
-
-/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff.  */
-# define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
-
-# define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
-
-/* Syntax bits common to both basic and extended POSIX regex syntax.  */
-# define _RE_SYNTAX_POSIX_COMMON                                       \
-  (RE_CHAR_CLASSES | RE_DOT_NEWLINE      | RE_DOT_NOT_NULL             \
-   | RE_INTERVALS  | RE_NO_EMPTY_RANGES)
-
-# define RE_SYNTAX_POSIX_BASIC                                         \
-  (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)
-
-/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
-   RE_LIMITED_OPS, i.e., \? \+ \| are not recognized.  Actually, this
-   isn't minimal, since other operators, such as \`, aren't disabled.  */
-# define RE_SYNTAX_POSIX_MINIMAL_BASIC                                 \
-  (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
-
-# define RE_SYNTAX_POSIX_EXTENDED                                      \
-  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS                 \
-   | RE_CONTEXT_INDEP_OPS   | RE_NO_BK_BRACES                          \
-   | RE_NO_BK_PARENS        | RE_NO_BK_VBAR                            \
-   | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD)
-
-/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is
-   removed and RE_NO_BK_REFS is added.  */
-# define RE_SYNTAX_POSIX_MINIMAL_EXTENDED                              \
-  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS                 \
-   | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES                          \
-   | RE_NO_BK_PARENS        | RE_NO_BK_REFS                            \
-   | RE_NO_BK_VBAR         | RE_UNMATCHED_RIGHT_PAREN_ORD)
-/* [[[end syntaxes]]] */
-
-#endif /* defined __USE_GNU_REGEX */
-\f
-#ifdef __USE_GNU_REGEX
-
-/* Maximum number of duplicates an interval can allow.  POSIX-conforming
-   systems might define this in <limits.h>, but we want our
-   value, so remove any previous define.  */
-# ifdef RE_DUP_MAX
-#  undef RE_DUP_MAX
-# endif
-
-/* RE_DUP_MAX is 2**15 - 1 because an earlier implementation stored
-   the counter as a 2-byte signed integer.  This is no longer true, so
-   RE_DUP_MAX could be increased to (INT_MAX / 10 - 1), or to
-   ((SIZE_MAX - 2) / 10 - 1) if _REGEX_LARGE_OFFSETS is defined.
-   However, there would be a huge performance problem if someone
-   actually used a pattern like a\{214748363\}, so RE_DUP_MAX retains
-   its historical value.  */
-# define RE_DUP_MAX (0x7fff)
-
-#endif /* defined __USE_GNU_REGEX */
-
-
-/* POSIX `cflags' bits (i.e., information for `regcomp').  */
-
-/* If this bit is set, then use extended regular expression syntax.
-   If not set, then use basic regular expression syntax.  */
-#define REG_EXTENDED 1
-
-/* If this bit is set, then ignore case when matching.
-   If not set, then case is significant.  */
-#define REG_ICASE (1 << 1)
-
-/* If this bit is set, then anchors do not match at newline
-     characters in the string.
-   If not set, then anchors do match at newlines.  */
-#define REG_NEWLINE (1 << 2)
-
-/* If this bit is set, then report only success or fail in regexec.
-   If not set, then returns differ between not matching and errors.  */
-#define REG_NOSUB (1 << 3)
-
-
-/* POSIX `eflags' bits (i.e., information for regexec).  */
-
-/* If this bit is set, then the beginning-of-line operator doesn't match
-     the beginning of the string (presumably because it's not the
-     beginning of a line).
-   If not set, then the beginning-of-line operator does match the
-     beginning of the string.  */
-#define REG_NOTBOL 1
-
-/* Like REG_NOTBOL, except for the end-of-line.  */
-#define REG_NOTEOL (1 << 1)
-
-/* Use PMATCH[0] to delimit the start and end of the search in the
-   buffer.  */
-#define REG_STARTEND (1 << 2)
-
-
-/* If any error codes are removed, changed, or added, update the
-   `__re_error_msgid' table in regcomp.c.  */
-
-typedef enum
-{
-  _REG_ENOSYS = -1,    /* This will never happen for this implementation.  */
-  _REG_NOERROR = 0,    /* Success.  */
-  _REG_NOMATCH,                /* Didn't find a match (for regexec).  */
-
-  /* POSIX regcomp return error codes.  (In the order listed in the
-     standard.)  */
-  _REG_BADPAT,         /* Invalid pattern.  */
-  _REG_ECOLLATE,       /* Invalid collating element.  */
-  _REG_ECTYPE,         /* Invalid character class name.  */
-  _REG_EESCAPE,                /* Trailing backslash.  */
-  _REG_ESUBREG,                /* Invalid back reference.  */
-  _REG_EBRACK,         /* Unmatched left bracket.  */
-  _REG_EPAREN,         /* Parenthesis imbalance.  */
-  _REG_EBRACE,         /* Unmatched \{.  */
-  _REG_BADBR,          /* Invalid contents of \{\}.  */
-  _REG_ERANGE,         /* Invalid range end.  */
-  _REG_ESPACE,         /* Ran out of memory.  */
-  _REG_BADRPT,         /* No preceding re for repetition op.  */
-
-  /* Error codes we've added.  */
-  _REG_EEND,           /* Premature end.  */
-  _REG_ESIZE,          /* Compiled pattern bigger than 2^16 bytes.  */
-  _REG_ERPAREN         /* Unmatched ) or \); not returned from regcomp.  */
-} reg_errcode_t;
-
-#ifdef _XOPEN_SOURCE
-# define REG_ENOSYS    _REG_ENOSYS
-#endif
-#define REG_NOERROR    _REG_NOERROR
-#define REG_NOMATCH    _REG_NOMATCH
-#define REG_BADPAT     _REG_BADPAT
-#define REG_ECOLLATE   _REG_ECOLLATE
-#define REG_ECTYPE     _REG_ECTYPE
-#define REG_EESCAPE    _REG_EESCAPE
-#define REG_ESUBREG    _REG_ESUBREG
-#define REG_EBRACK     _REG_EBRACK
-#define REG_EPAREN     _REG_EPAREN
-#define REG_EBRACE     _REG_EBRACE
-#define REG_BADBR      _REG_BADBR
-#define REG_ERANGE     _REG_ERANGE
-#define REG_ESPACE     _REG_ESPACE
-#define REG_BADRPT     _REG_BADRPT
-#define REG_EEND       _REG_EEND
-#define REG_ESIZE      _REG_ESIZE
-#define REG_ERPAREN    _REG_ERPAREN
-\f
-/* struct re_pattern_buffer normally uses member names like `buffer'
-   that POSIX does not allow.  In POSIX mode these members have names
-   with leading `re_' (e.g., `re_buffer').  */
-#ifdef __USE_GNU_REGEX
-# define _REG_RE_NAME(id) id
-# define _REG_RM_NAME(id) id
-#else
-# define _REG_RE_NAME(id) re_##id
-# define _REG_RM_NAME(id) rm_##id
-#endif
-
-/* The user can specify the type of the re_translate member by
-   defining the macro RE_TRANSLATE_TYPE, which defaults to unsigned
-   char *.  This pollutes the POSIX name space, so in POSIX mode just
-   use unsigned char *.  */
-#ifdef __USE_GNU_REGEX
-# ifndef RE_TRANSLATE_TYPE
-#  define RE_TRANSLATE_TYPE unsigned char *
-# endif
-# define REG_TRANSLATE_TYPE RE_TRANSLATE_TYPE
-#else
-# define REG_TRANSLATE_TYPE unsigned char *
-#endif
-
-/* This data structure represents a compiled pattern.  Before calling
-   the pattern compiler, the fields `buffer', `allocated', `fastmap',
-   `translate', and `no_sub' can be set.  After the pattern has been
-   compiled, the `re_nsub' field is available.  All other fields are
-   private to the regex routines.  */
-
-struct re_pattern_buffer
-{
-  /* Space that holds the compiled pattern.  It is declared as
-     `unsigned char *' because its elements are sometimes used as
-     array indexes.  */
-  unsigned char *_REG_RE_NAME (buffer);
-
-  /* Number of bytes to which `buffer' points.  */
-  __re_long_size_t _REG_RE_NAME (allocated);
-
-  /* Number of bytes actually used in `buffer'.  */
-  __re_long_size_t _REG_RE_NAME (used);
-
-  /* Syntax setting with which the pattern was compiled.  */
-  reg_syntax_t _REG_RE_NAME (syntax);
-
-  /* Pointer to a fastmap, if any, otherwise zero.  re_search uses the
-     fastmap, if there is one, to skip over impossible starting points
-     for matches.  */
-  char *_REG_RE_NAME (fastmap);
-
-  /* Either a translate table to apply to all characters before
-     comparing them, or zero for no translation.  The translation is
-     applied to a pattern when it is compiled and to a string when it
-     is matched.  */
-  REG_TRANSLATE_TYPE _REG_RE_NAME (translate);
-
-  /* Number of subexpressions found by the compiler.  */
-  size_t re_nsub;
-
-  /* Zero if this pattern cannot match the empty string, one else.
-     Well, in truth it's used only in `re_search_2', to see whether or
-     not we should use the fastmap, so we don't set this absolutely
-     perfectly; see `re_compile_fastmap' (the `duplicate' case).  */
-  unsigned int _REG_RE_NAME (can_be_null) : 1;
-
-  /* If REGS_UNALLOCATED, allocate space in the `regs' structure
-     for `max (RE_NREGS, re_nsub + 1)' groups.
-     If REGS_REALLOCATE, reallocate space if necessary.
-     If REGS_FIXED, use what's there.  */
-#ifdef __USE_GNU_REGEX
-# define REGS_UNALLOCATED 0
-# define REGS_REALLOCATE 1
-# define REGS_FIXED 2
-#endif
-  unsigned int _REG_RE_NAME (regs_allocated) : 2;
-
-  /* Set to zero when `regex_compile' compiles a pattern; set to one
-     by `re_compile_fastmap' if it updates the fastmap.  */
-  unsigned int _REG_RE_NAME (fastmap_accurate) : 1;
-
-  /* If set, `re_match_2' does not return information about
-     subexpressions.  */
-  unsigned int _REG_RE_NAME (no_sub) : 1;
-
-  /* If set, a beginning-of-line anchor doesn't match at the beginning
-     of the string.  */
-  unsigned int _REG_RE_NAME (not_bol) : 1;
-
-  /* Similarly for an end-of-line anchor.  */
-  unsigned int _REG_RE_NAME (not_eol) : 1;
-
-  /* If true, an anchor at a newline matches.  */
-  unsigned int _REG_RE_NAME (newline_anchor) : 1;
-
-/* [[[end pattern_buffer]]] */
-};
-
-typedef struct re_pattern_buffer regex_t;
-\f
-/* This is the structure we store register match data in.  See
-   regex.texinfo for a full description of what registers match.  */
-struct re_registers
-{
-  __re_size_t _REG_RM_NAME (num_regs);
-  regoff_t *_REG_RM_NAME (start);
-  regoff_t *_REG_RM_NAME (end);
-};
-
-
-/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
-   `re_match_2' returns information about at least this many registers
-   the first time a `regs' structure is passed.  */
-#if !defined RE_NREGS && defined __USE_GNU_REGEX
-# define RE_NREGS 30
-#endif
-
-
-/* POSIX specification for registers.  Aside from the different names than
-   `re_registers', POSIX uses an array of structures, instead of a
-   structure of arrays.  */
-typedef struct
-{
-  regoff_t rm_so;  /* Byte offset from string's start to substring's start.  */
-  regoff_t rm_eo;  /* Byte offset from string's start to substring's end.  */
-} regmatch_t;
-\f
-/* Declarations for routines.  */
-
-/* Sets the current default syntax to SYNTAX, and return the old syntax.
-   You can also simply assign to the `re_syntax_options' variable.  */
-extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax);
-
-/* Compile the regular expression PATTERN, with length LENGTH
-   and syntax given by the global `re_syntax_options', into the buffer
-   BUFFER.  Return NULL if successful, and an error string if not.  */
-extern const char *re_compile_pattern (const char *__pattern, size_t __length,
-                                      struct re_pattern_buffer *__buffer);
-
-
-/* Compile a fastmap for the compiled pattern in BUFFER; used to
-   accelerate searches.  Return 0 if successful and -2 if was an
-   internal error.  */
-extern int re_compile_fastmap (struct re_pattern_buffer *__buffer);
-
-
-/* Search in the string STRING (with length LENGTH) for the pattern
-   compiled into BUFFER.  Start searching at position START, for RANGE
-   characters.  Return the starting position of the match, -1 for no
-   match, or -2 for an internal error.  Also return register
-   information in REGS (if REGS and BUFFER->no_sub are nonzero).  */
-extern regoff_t re_search (struct re_pattern_buffer *__buffer,
-                          const char *__string, __re_idx_t __length,
-                          __re_idx_t __start, regoff_t __range,
-                          struct re_registers *__regs);
-
-
-/* Like `re_search', but search in the concatenation of STRING1 and
-   STRING2.  Also, stop searching at index START + STOP.  */
-extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer,
-                            const char *__string1, __re_idx_t __length1,
-                            const char *__string2, __re_idx_t __length2,
-                            __re_idx_t __start, regoff_t __range,
-                            struct re_registers *__regs,
-                            __re_idx_t __stop);
-
-
-/* Like `re_search', but return how many characters in STRING the regexp
-   in BUFFER matched, starting at position START.  */
-extern regoff_t re_match (struct re_pattern_buffer *__buffer,
-                         const char *__string, __re_idx_t __length,
-                         __re_idx_t __start, struct re_registers *__regs);
-
-
-/* Relates to `re_match' as `re_search_2' relates to `re_search'.  */
-extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer,
-                           const char *__string1, __re_idx_t __length1,
-                           const char *__string2, __re_idx_t __length2,
-                           __re_idx_t __start, struct re_registers *__regs,
-                           __re_idx_t __stop);
-
-
-/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
-   ENDS.  Subsequent matches using BUFFER and REGS will use this memory
-   for recording register information.  STARTS and ENDS must be
-   allocated with malloc, and must each be at least `NUM_REGS * sizeof
-   (regoff_t)' bytes long.
-
-   If NUM_REGS == 0, then subsequent matches should allocate their own
-   register data.
-
-   Unless this function is called, the first search or match using
-   PATTERN_BUFFER will allocate its own register data, without
-   freeing the old data.  */
-extern void re_set_registers (struct re_pattern_buffer *__buffer,
-                             struct re_registers *__regs,
-                             __re_size_t __num_regs,
-                             regoff_t *__starts, regoff_t *__ends);
-
-#if defined _REGEX_RE_COMP || defined _LIBC
-# ifndef _CRAY
-/* 4.2 bsd compatibility.  */
-extern char *re_comp (const char *);
-extern int re_exec (const char *);
-# endif
-#endif
-
-/* GCC 2.95 and later have "__restrict"; C99 compilers have
-   "restrict", and "configure" may have defined "restrict".
-   Other compilers use __restrict, __restrict__, and _Restrict, and
-   'configure' might #define 'restrict' to those words, so pick a
-   different name.  */
-#ifndef _Restrict_
-# if 199901L <= __STDC_VERSION__
-#  define _Restrict_ restrict
-# elif 2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)
-#  define _Restrict_ __restrict
-# else
-#  define _Restrict_
-# endif
-#endif
-/* gcc 3.1 and up support the [restrict] syntax.  Don't trust
-   sys/cdefs.h's definition of __restrict_arr, though, as it
-   mishandles gcc -ansi -pedantic.  */
-#ifndef _Restrict_arr_
-# if ((199901L <= __STDC_VERSION__                                     \
-       || ((3 < __GNUC__ || (3 == __GNUC__ && 1 <= __GNUC_MINOR__))    \
-          && !__STRICT_ANSI__))                                        \
-      && !defined __GNUG__)
-#  define _Restrict_arr_ _Restrict_
-# else
-#  define _Restrict_arr_
-# endif
-#endif
-
-/* POSIX compatibility.  */
-extern int regcomp (regex_t *_Restrict_ __preg,
-                   const char *_Restrict_ __pattern,
-                   int __cflags);
-
-extern int regexec (const regex_t *_Restrict_ __preg,
-                   const char *_Restrict_ __string, size_t __nmatch,
-                   regmatch_t __pmatch[_Restrict_arr_],
-                   int __eflags);
-
-extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg,
-                       char *_Restrict_ __errbuf, size_t __errbuf_size);
-
-extern void regfree (regex_t *__preg);
-
-
-#ifdef __cplusplus
-}
-#endif /* C++ */
-
-#endif /* regex.h */
diff --git a/gnulib/regex_internal.c b/gnulib/regex_internal.c
deleted file mode 100644 (file)
index 378b767..0000000
+++ /dev/null
@@ -1,1740 +0,0 @@
-/* Extended regular expression matching and search library.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
-   Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
-
-   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-static void re_string_construct_common (const char *str, Idx len,
-                                       re_string_t *pstr,
-                                       RE_TRANSLATE_TYPE trans, bool icase,
-                                       const re_dfa_t *dfa) internal_function;
-static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa,
-                                         const re_node_set *nodes,
-                                         re_hashval_t hash) internal_function;
-static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
-                                         const re_node_set *nodes,
-                                         unsigned int context,
-                                         re_hashval_t hash) internal_function;
-\f
-/* Functions for string operation.  */
-
-/* This function allocate the buffers.  It is necessary to call
-   re_string_reconstruct before using the object.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len,
-                   RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
-{
-  reg_errcode_t ret;
-  Idx init_buf_len;
-
-  /* Ensure at least one character fits into the buffers.  */
-  if (init_len < dfa->mb_cur_max)
-    init_len = dfa->mb_cur_max;
-  init_buf_len = (len + 1 < init_len) ? len + 1: init_len;
-  re_string_construct_common (str, len, pstr, trans, icase, dfa);
-
-  ret = re_string_realloc_buffers (pstr, init_buf_len);
-  if (BE (ret != REG_NOERROR, 0))
-    return ret;
-
-  pstr->word_char = dfa->word_char;
-  pstr->word_ops_used = dfa->word_ops_used;
-  pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
-  pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len;
-  pstr->valid_raw_len = pstr->valid_len;
-  return REG_NOERROR;
-}
-
-/* This function allocate the buffers, and initialize them.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-re_string_construct (re_string_t *pstr, const char *str, Idx len,
-                    RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
-{
-  reg_errcode_t ret;
-  memset (pstr, '\0', sizeof (re_string_t));
-  re_string_construct_common (str, len, pstr, trans, icase, dfa);
-
-  if (len > 0)
-    {
-      ret = re_string_realloc_buffers (pstr, len + 1);
-      if (BE (ret != REG_NOERROR, 0))
-       return ret;
-    }
-  pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
-
-  if (icase)
-    {
-#ifdef RE_ENABLE_I18N
-      if (dfa->mb_cur_max > 1)
-       {
-         while (1)
-           {
-             ret = build_wcs_upper_buffer (pstr);
-             if (BE (ret != REG_NOERROR, 0))
-               return ret;
-             if (pstr->valid_raw_len >= len)
-               break;
-             if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
-               break;
-             ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
-             if (BE (ret != REG_NOERROR, 0))
-               return ret;
-           }
-       }
-      else
-#endif /* RE_ENABLE_I18N  */
-       build_upper_buffer (pstr);
-    }
-  else
-    {
-#ifdef RE_ENABLE_I18N
-      if (dfa->mb_cur_max > 1)
-       build_wcs_buffer (pstr);
-      else
-#endif /* RE_ENABLE_I18N  */
-       {
-         if (trans != NULL)
-           re_string_translate_buffer (pstr);
-         else
-           {
-             pstr->valid_len = pstr->bufs_len;
-             pstr->valid_raw_len = pstr->bufs_len;
-           }
-       }
-    }
-
-  return REG_NOERROR;
-}
-
-/* Helper functions for re_string_allocate, and re_string_construct.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)
-{
-#ifdef RE_ENABLE_I18N
-  if (pstr->mb_cur_max > 1)
-    {
-      wint_t *new_wcs;
-
-      /* Avoid overflow.  */
-      size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx));
-      if (BE (SIZE_MAX / max_object_size < new_buf_len, 0))
-       return REG_ESPACE;
-
-      new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
-      if (BE (new_wcs == NULL, 0))
-       return REG_ESPACE;
-      pstr->wcs = new_wcs;
-      if (pstr->offsets != NULL)
-       {
-         Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len);
-         if (BE (new_offsets == NULL, 0))
-           return REG_ESPACE;
-         pstr->offsets = new_offsets;
-       }
-    }
-#endif /* RE_ENABLE_I18N  */
-  if (pstr->mbs_allocated)
-    {
-      unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char,
-                                          new_buf_len);
-      if (BE (new_mbs == NULL, 0))
-       return REG_ESPACE;
-      pstr->mbs = new_mbs;
-    }
-  pstr->bufs_len = new_buf_len;
-  return REG_NOERROR;
-}
-
-
-static void
-internal_function
-re_string_construct_common (const char *str, Idx len, re_string_t *pstr,
-                           RE_TRANSLATE_TYPE trans, bool icase,
-                           const re_dfa_t *dfa)
-{
-  pstr->raw_mbs = (const unsigned char *) str;
-  pstr->len = len;
-  pstr->raw_len = len;
-  pstr->trans = trans;
-  pstr->icase = icase;
-  pstr->mbs_allocated = (trans != NULL || icase);
-  pstr->mb_cur_max = dfa->mb_cur_max;
-  pstr->is_utf8 = dfa->is_utf8;
-  pstr->map_notascii = dfa->map_notascii;
-  pstr->stop = pstr->len;
-  pstr->raw_stop = pstr->stop;
-}
-
-#ifdef RE_ENABLE_I18N
-
-/* Build wide character buffer PSTR->WCS.
-   If the byte sequence of the string are:
-     <mb1>(0), <mb1>(1), <mb2>(0), <mb2>(1), <sb3>
-   Then wide character buffer will be:
-     <wc1>   , WEOF    , <wc2>   , WEOF    , <wc3>
-   We use WEOF for padding, they indicate that the position isn't
-   a first byte of a multibyte character.
-
-   Note that this function assumes PSTR->VALID_LEN elements are already
-   built and starts from PSTR->VALID_LEN.  */
-
-static void
-internal_function
-build_wcs_buffer (re_string_t *pstr)
-{
-#ifdef _LIBC
-  unsigned char buf[MB_LEN_MAX];
-  assert (MB_LEN_MAX >= pstr->mb_cur_max);
-#else
-  unsigned char buf[64];
-#endif
-  mbstate_t prev_st;
-  Idx byte_idx, end_idx, remain_len;
-  size_t mbclen;
-
-  /* Build the buffers from pstr->valid_len to either pstr->len or
-     pstr->bufs_len.  */
-  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
-  for (byte_idx = pstr->valid_len; byte_idx < end_idx;)
-    {
-      wchar_t wc;
-      const char *p;
-
-      remain_len = end_idx - byte_idx;
-      prev_st = pstr->cur_state;
-      /* Apply the translation if we need.  */
-      if (BE (pstr->trans != NULL, 0))
-       {
-         int i, ch;
-
-         for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
-           {
-             ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i];
-             buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch];
-           }
-         p = (const char *) buf;
-       }
-      else
-       p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx;
-      mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
-      if (BE (mbclen == (size_t) -2, 0))
-       {
-         /* The buffer doesn't have enough space, finish to build.  */
-         pstr->cur_state = prev_st;
-         break;
-       }
-      else if (BE (mbclen == (size_t) -1 || mbclen == 0, 0))
-       {
-         /* We treat these cases as a singlebyte character.  */
-         mbclen = 1;
-         wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
-         if (BE (pstr->trans != NULL, 0))
-           wc = pstr->trans[wc];
-         pstr->cur_state = prev_st;
-       }
-
-      /* Write wide character and padding.  */
-      pstr->wcs[byte_idx++] = wc;
-      /* Write paddings.  */
-      for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
-       pstr->wcs[byte_idx++] = WEOF;
-    }
-  pstr->valid_len = byte_idx;
-  pstr->valid_raw_len = byte_idx;
-}
-
-/* Build wide character buffer PSTR->WCS like build_wcs_buffer,
-   but for REG_ICASE.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-build_wcs_upper_buffer (re_string_t *pstr)
-{
-  mbstate_t prev_st;
-  Idx src_idx, byte_idx, end_idx, remain_len;
-  size_t mbclen;
-#ifdef _LIBC
-  char buf[MB_LEN_MAX];
-  assert (MB_LEN_MAX >= pstr->mb_cur_max);
-#else
-  char buf[64];
-#endif
-
-  byte_idx = pstr->valid_len;
-  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
-
-  /* The following optimization assumes that ASCII characters can be
-     mapped to wide characters with a simple cast.  */
-  if (! pstr->map_notascii && pstr->trans == NULL && !pstr->offsets_needed)
-    {
-      while (byte_idx < end_idx)
-       {
-         wchar_t wc;
-
-         if (isascii (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx])
-             && mbsinit (&pstr->cur_state))
-           {
-             /* In case of a singlebyte character.  */
-             pstr->mbs[byte_idx]
-               = toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]);
-             /* The next step uses the assumption that wchar_t is encoded
-                ASCII-safe: all ASCII values can be converted like this.  */
-             pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx];
-             ++byte_idx;
-             continue;
-           }
-
-         remain_len = end_idx - byte_idx;
-         prev_st = pstr->cur_state;
-         mbclen = __mbrtowc (&wc,
-                             ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
-                              + byte_idx), remain_len, &pstr->cur_state);
-         if (BE (mbclen < (size_t) -2, 1))
-           {
-             wchar_t wcu = wc;
-             if (iswlower (wc))
-               {
-                 size_t mbcdlen;
-
-                 wcu = towupper (wc);
-                 mbcdlen = wcrtomb (buf, wcu, &prev_st);
-                 if (BE (mbclen == mbcdlen, 1))
-                   memcpy (pstr->mbs + byte_idx, buf, mbclen);
-                 else
-                   {
-                     src_idx = byte_idx;
-                     goto offsets_needed;
-                   }
-               }
-             else
-               memcpy (pstr->mbs + byte_idx,
-                       pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen);
-             pstr->wcs[byte_idx++] = wcu;
-             /* Write paddings.  */
-             for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
-               pstr->wcs[byte_idx++] = WEOF;
-           }
-         else if (mbclen == (size_t) -1 || mbclen == 0)
-           {
-             /* It is an invalid character or '\0'.  Just use the byte.  */
-             int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
-             pstr->mbs[byte_idx] = ch;
-             /* And also cast it to wide char.  */
-             pstr->wcs[byte_idx++] = (wchar_t) ch;
-             if (BE (mbclen == (size_t) -1, 0))
-               pstr->cur_state = prev_st;
-           }
-         else
-           {
-             /* The buffer doesn't have enough space, finish to build.  */
-             pstr->cur_state = prev_st;
-             break;
-           }
-       }
-      pstr->valid_len = byte_idx;
-      pstr->valid_raw_len = byte_idx;
-      return REG_NOERROR;
-    }
-  else
-    for (src_idx = pstr->valid_raw_len; byte_idx < end_idx;)
-      {
-       wchar_t wc;
-       const char *p;
-      offsets_needed:
-       remain_len = end_idx - byte_idx;
-       prev_st = pstr->cur_state;
-       if (BE (pstr->trans != NULL, 0))
-         {
-           int i, ch;
-
-           for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
-             {
-               ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i];
-               buf[i] = pstr->trans[ch];
-             }
-           p = (const char *) buf;
-         }
-       else
-         p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;
-       mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
-       if (BE (mbclen < (size_t) -2, 1))
-         {
-           wchar_t wcu = wc;
-           if (iswlower (wc))
-             {
-               size_t mbcdlen;
-
-               wcu = towupper (wc);
-               mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st);
-               if (BE (mbclen == mbcdlen, 1))
-                 memcpy (pstr->mbs + byte_idx, buf, mbclen);
-               else if (mbcdlen != (size_t) -1)
-                 {
-                   size_t i;
-
-                   if (byte_idx + mbcdlen > pstr->bufs_len)
-                     {
-                       pstr->cur_state = prev_st;
-                       break;
-                     }
-
-                   if (pstr->offsets == NULL)
-                     {
-                       pstr->offsets = re_malloc (Idx, pstr->bufs_len);
-
-                       if (pstr->offsets == NULL)
-                         return REG_ESPACE;
-                     }
-                   if (!pstr->offsets_needed)
-                     {
-                       for (i = 0; i < (size_t) byte_idx; ++i)
-                         pstr->offsets[i] = i;
-                       pstr->offsets_needed = 1;
-                     }
-
-                   memcpy (pstr->mbs + byte_idx, buf, mbcdlen);
-                   pstr->wcs[byte_idx] = wcu;
-                   pstr->offsets[byte_idx] = src_idx;
-                   for (i = 1; i < mbcdlen; ++i)
-                     {
-                       pstr->offsets[byte_idx + i]
-                         = src_idx + (i < mbclen ? i : mbclen - 1);
-                       pstr->wcs[byte_idx + i] = WEOF;
-                     }
-                   pstr->len += mbcdlen - mbclen;
-                   if (pstr->raw_stop > src_idx)
-                     pstr->stop += mbcdlen - mbclen;
-                   end_idx = (pstr->bufs_len > pstr->len)
-                             ? pstr->len : pstr->bufs_len;
-                   byte_idx += mbcdlen;
-                   src_idx += mbclen;
-                   continue;
-                 }
-               else
-                 memcpy (pstr->mbs + byte_idx, p, mbclen);
-             }
-           else
-             memcpy (pstr->mbs + byte_idx, p, mbclen);
-
-           if (BE (pstr->offsets_needed != 0, 0))
-             {
-               size_t i;
-               for (i = 0; i < mbclen; ++i)
-                 pstr->offsets[byte_idx + i] = src_idx + i;
-             }
-           src_idx += mbclen;
-
-           pstr->wcs[byte_idx++] = wcu;
-           /* Write paddings.  */
-           for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
-             pstr->wcs[byte_idx++] = WEOF;
-         }
-       else if (mbclen == (size_t) -1 || mbclen == 0)
-         {
-           /* It is an invalid character or '\0'.  Just use the byte.  */
-           int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx];
-
-           if (BE (pstr->trans != NULL, 0))
-             ch = pstr->trans [ch];
-           pstr->mbs[byte_idx] = ch;
-
-           if (BE (pstr->offsets_needed != 0, 0))
-             pstr->offsets[byte_idx] = src_idx;
-           ++src_idx;
-
-           /* And also cast it to wide char.  */
-           pstr->wcs[byte_idx++] = (wchar_t) ch;
-           if (BE (mbclen == (size_t) -1, 0))
-             pstr->cur_state = prev_st;
-         }
-       else
-         {
-           /* The buffer doesn't have enough space, finish to build.  */
-           pstr->cur_state = prev_st;
-           break;
-         }
-      }
-  pstr->valid_len = byte_idx;
-  pstr->valid_raw_len = src_idx;
-  return REG_NOERROR;
-}
-
-/* Skip characters until the index becomes greater than NEW_RAW_IDX.
-   Return the index.  */
-
-static Idx
-internal_function
-re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc)
-{
-  mbstate_t prev_st;
-  Idx rawbuf_idx;
-  size_t mbclen;
-  wint_t wc = WEOF;
-
-  /* Skip the characters which are not necessary to check.  */
-  for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len;
-       rawbuf_idx < new_raw_idx;)
-    {
-      wchar_t wc2;
-      Idx remain_len;
-      remain_len = pstr->len - rawbuf_idx;
-      prev_st = pstr->cur_state;
-      mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx,
-                         remain_len, &pstr->cur_state);
-      if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
-       {
-         /* We treat these cases as a single byte character.  */
-         if (mbclen == 0 || remain_len == 0)
-           wc = L'\0';
-         else
-           wc = *(unsigned char *) (pstr->raw_mbs + rawbuf_idx);
-         mbclen = 1;
-         pstr->cur_state = prev_st;
-       }
-      else
-       wc = wc2;
-      /* Then proceed the next character.  */
-      rawbuf_idx += mbclen;
-    }
-  *last_wc = wc;
-  return rawbuf_idx;
-}
-#endif /* RE_ENABLE_I18N  */
-
-/* Build the buffer PSTR->MBS, and apply the translation if we need.
-   This function is used in case of REG_ICASE.  */
-
-static void
-internal_function
-build_upper_buffer (re_string_t *pstr)
-{
-  Idx char_idx, end_idx;
-  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
-
-  for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx)
-    {
-      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx];
-      if (BE (pstr->trans != NULL, 0))
-       ch = pstr->trans[ch];
-      if (islower (ch))
-       pstr->mbs[char_idx] = toupper (ch);
-      else
-       pstr->mbs[char_idx] = ch;
-    }
-  pstr->valid_len = char_idx;
-  pstr->valid_raw_len = char_idx;
-}
-
-/* Apply TRANS to the buffer in PSTR.  */
-
-static void
-internal_function
-re_string_translate_buffer (re_string_t *pstr)
-{
-  Idx buf_idx, end_idx;
-  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
-
-  for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx)
-    {
-      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + buf_idx];
-      pstr->mbs[buf_idx] = pstr->trans[ch];
-    }
-
-  pstr->valid_len = buf_idx;
-  pstr->valid_raw_len = buf_idx;
-}
-
-/* This function re-construct the buffers.
-   Concretely, convert to wide character in case of pstr->mb_cur_max > 1,
-   convert to upper case in case of REG_ICASE, apply translation.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
-{
-  Idx offset;
-
-  if (BE (pstr->raw_mbs_idx <= idx, 0))
-    offset = idx - pstr->raw_mbs_idx;
-  else
-    {
-      /* Reset buffer.  */
-#ifdef RE_ENABLE_I18N
-      if (pstr->mb_cur_max > 1)
-       memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
-#endif /* RE_ENABLE_I18N */
-      pstr->len = pstr->raw_len;
-      pstr->stop = pstr->raw_stop;
-      pstr->valid_len = 0;
-      pstr->raw_mbs_idx = 0;
-      pstr->valid_raw_len = 0;
-      pstr->offsets_needed = 0;
-      pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
-                          : CONTEXT_NEWLINE | CONTEXT_BEGBUF);
-      if (!pstr->mbs_allocated)
-       pstr->mbs = (unsigned char *) pstr->raw_mbs;
-      offset = idx;
-    }
-
-  if (BE (offset != 0, 1))
-    {
-      /* Should the already checked characters be kept?  */
-      if (BE (offset < pstr->valid_raw_len, 1))
-       {
-         /* Yes, move them to the front of the buffer.  */
-#ifdef RE_ENABLE_I18N
-         if (BE (pstr->offsets_needed, 0))
-           {
-             Idx low = 0, high = pstr->valid_len, mid;
-             do
-               {
-                 mid = (high + low) / 2;
-                 if (pstr->offsets[mid] > offset)
-                   high = mid;
-                 else if (pstr->offsets[mid] < offset)
-                   low = mid + 1;
-                 else
-                   break;
-               }
-             while (low < high);
-             if (pstr->offsets[mid] < offset)
-               ++mid;
-             pstr->tip_context = re_string_context_at (pstr, mid - 1,
-                                                       eflags);
-             /* This can be quite complicated, so handle specially
-                only the common and easy case where the character with
-                different length representation of lower and upper
-                case is present at or after offset.  */
-             if (pstr->valid_len > offset
-                 && mid == offset && pstr->offsets[mid] == offset)
-               {
-                 memmove (pstr->wcs, pstr->wcs + offset,
-                          (pstr->valid_len - offset) * sizeof (wint_t));
-                 memmove (pstr->mbs, pstr->mbs + offset, pstr->valid_len - offset);
-                 pstr->valid_len -= offset;
-                 pstr->valid_raw_len -= offset;
-                 for (low = 0; low < pstr->valid_len; low++)
-                   pstr->offsets[low] = pstr->offsets[low + offset] - offset;
-               }
-             else
-               {
-                 /* Otherwise, just find out how long the partial multibyte
-                    character at offset is and fill it with WEOF/255.  */
-                 pstr->len = pstr->raw_len - idx + offset;
-                 pstr->stop = pstr->raw_stop - idx + offset;
-                 pstr->offsets_needed = 0;
-                 while (mid > 0 && pstr->offsets[mid - 1] == offset)
-                   --mid;
-                 while (mid < pstr->valid_len)
-                   if (pstr->wcs[mid] != WEOF)
-                     break;
-                   else
-                     ++mid;
-                 if (mid == pstr->valid_len)
-                   pstr->valid_len = 0;
-                 else
-                   {
-                     pstr->valid_len = pstr->offsets[mid] - offset;
-                     if (pstr->valid_len)
-                       {
-                         for (low = 0; low < pstr->valid_len; ++low)
-                           pstr->wcs[low] = WEOF;
-                         memset (pstr->mbs, 255, pstr->valid_len);
-                       }
-                   }
-                 pstr->valid_raw_len = pstr->valid_len;
-               }
-           }
-         else
-#endif
-           {
-             pstr->tip_context = re_string_context_at (pstr, offset - 1,
-                                                       eflags);
-#ifdef RE_ENABLE_I18N
-             if (pstr->mb_cur_max > 1)
-               memmove (pstr->wcs, pstr->wcs + offset,
-                        (pstr->valid_len - offset) * sizeof (wint_t));
-#endif /* RE_ENABLE_I18N */
-             if (BE (pstr->mbs_allocated, 0))
-               memmove (pstr->mbs, pstr->mbs + offset,
-                        pstr->valid_len - offset);
-             pstr->valid_len -= offset;
-             pstr->valid_raw_len -= offset;
-#if DEBUG
-             assert (pstr->valid_len > 0);
-#endif
-           }
-       }
-      else
-       {
-#ifdef RE_ENABLE_I18N
-         /* No, skip all characters until IDX.  */
-         Idx prev_valid_len = pstr->valid_len;
-
-         if (BE (pstr->offsets_needed, 0))
-           {
-             pstr->len = pstr->raw_len - idx + offset;
-             pstr->stop = pstr->raw_stop - idx + offset;
-             pstr->offsets_needed = 0;
-           }
-#endif
-         pstr->valid_len = 0;
-#ifdef RE_ENABLE_I18N
-         if (pstr->mb_cur_max > 1)
-           {
-             Idx wcs_idx;
-             wint_t wc = WEOF;
-
-             if (pstr->is_utf8)
-               {
-                 const unsigned char *raw, *p, *end;
-
-                 /* Special case UTF-8.  Multi-byte chars start with any
-                    byte other than 0x80 - 0xbf.  */
-                 raw = pstr->raw_mbs + pstr->raw_mbs_idx;
-                 end = raw + (offset - pstr->mb_cur_max);
-                 if (end < pstr->raw_mbs)
-                   end = pstr->raw_mbs;
-                 p = raw + offset - 1;
-#ifdef _LIBC
-                 /* We know the wchar_t encoding is UCS4, so for the simple
-                    case, ASCII characters, skip the conversion step.  */
-                 if (isascii (*p) && BE (pstr->trans == NULL, 1))
-                   {
-                     memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
-                     /* pstr->valid_len = 0; */
-                     wc = (wchar_t) *p;
-                   }
-                 else
-#endif
-                   for (; p >= end; --p)
-                     if ((*p & 0xc0) != 0x80)
-                       {
-                         mbstate_t cur_state;
-                         wchar_t wc2;
-                         Idx mlen = raw + pstr->len - p;
-                         unsigned char buf[6];
-                         size_t mbclen;
-
-                         if (BE (pstr->trans != NULL, 0))
-                           {
-                             int i = mlen < 6 ? mlen : 6;
-                             while (--i >= 0)
-                               buf[i] = pstr->trans[p[i]];
-                           }
-                         /* XXX Don't use mbrtowc, we know which conversion
-                            to use (UTF-8 -> UCS4).  */
-                         memset (&cur_state, 0, sizeof (cur_state));
-                         mbclen = __mbrtowc (&wc2, (const char *) p, mlen,
-                                             &cur_state);
-                         if (raw + offset - p <= mbclen
-                             && mbclen < (size_t) -2)
-                           {
-                             memset (&pstr->cur_state, '\0',
-                                     sizeof (mbstate_t));
-                             pstr->valid_len = mbclen - (raw + offset - p);
-                             wc = wc2;
-                           }
-                         break;
-                       }
-               }
-
-             if (wc == WEOF)
-               pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx;
-             if (wc == WEOF)
-               pstr->tip_context
-                 = re_string_context_at (pstr, prev_valid_len - 1, eflags);
-             else
-               pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0)
-                                     && IS_WIDE_WORD_CHAR (wc))
-                                    ? CONTEXT_WORD
-                                    : ((IS_WIDE_NEWLINE (wc)
-                                        && pstr->newline_anchor)
-                                       ? CONTEXT_NEWLINE : 0));
-             if (BE (pstr->valid_len, 0))
-               {
-                 for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
-                   pstr->wcs[wcs_idx] = WEOF;
-                 if (pstr->mbs_allocated)
-                   memset (pstr->mbs, 255, pstr->valid_len);
-               }
-             pstr->valid_raw_len = pstr->valid_len;
-           }
-         else
-#endif /* RE_ENABLE_I18N */
-           {
-             int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1];
-             pstr->valid_raw_len = 0;
-             if (pstr->trans)
-               c = pstr->trans[c];
-             pstr->tip_context = (bitset_contain (pstr->word_char, c)
-                                  ? CONTEXT_WORD
-                                  : ((IS_NEWLINE (c) && pstr->newline_anchor)
-                                     ? CONTEXT_NEWLINE : 0));
-           }
-       }
-      if (!BE (pstr->mbs_allocated, 0))
-       pstr->mbs += offset;
-    }
-  pstr->raw_mbs_idx = idx;
-  pstr->len -= offset;
-  pstr->stop -= offset;
-
-  /* Then build the buffers.  */
-#ifdef RE_ENABLE_I18N
-  if (pstr->mb_cur_max > 1)
-    {
-      if (pstr->icase)
-       {
-         reg_errcode_t ret = build_wcs_upper_buffer (pstr);
-         if (BE (ret != REG_NOERROR, 0))
-           return ret;
-       }
-      else
-       build_wcs_buffer (pstr);
-    }
-  else
-#endif /* RE_ENABLE_I18N */
-    if (BE (pstr->mbs_allocated, 0))
-      {
-       if (pstr->icase)
-         build_upper_buffer (pstr);
-       else if (pstr->trans != NULL)
-         re_string_translate_buffer (pstr);
-      }
-    else
-      pstr->valid_len = pstr->len;
-
-  pstr->cur_idx = 0;
-  return REG_NOERROR;
-}
-
-static unsigned char
-internal_function __attribute ((pure))
-re_string_peek_byte_case (const re_string_t *pstr, Idx idx)
-{
-  int ch;
-  Idx off;
-
-  /* Handle the common (easiest) cases first.  */
-  if (BE (!pstr->mbs_allocated, 1))
-    return re_string_peek_byte (pstr, idx);
-
-#ifdef RE_ENABLE_I18N
-  if (pstr->mb_cur_max > 1
-      && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
-    return re_string_peek_byte (pstr, idx);
-#endif
-
-  off = pstr->cur_idx + idx;
-#ifdef RE_ENABLE_I18N
-  if (pstr->offsets_needed)
-    off = pstr->offsets[off];
-#endif
-
-  ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
-
-#ifdef RE_ENABLE_I18N
-  /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I
-     this function returns CAPITAL LETTER I instead of first byte of
-     DOTLESS SMALL LETTER I.  The latter would confuse the parser,
-     since peek_byte_case doesn't advance cur_idx in any way.  */
-  if (pstr->offsets_needed && !isascii (ch))
-    return re_string_peek_byte (pstr, idx);
-#endif
-
-  return ch;
-}
-
-static unsigned char
-internal_function __attribute ((pure))
-re_string_fetch_byte_case (re_string_t *pstr)
-{
-  if (BE (!pstr->mbs_allocated, 1))
-    return re_string_fetch_byte (pstr);
-
-#ifdef RE_ENABLE_I18N
-  if (pstr->offsets_needed)
-    {
-      Idx off;
-      int ch;
-
-      /* For tr_TR.UTF-8 [[:islower:]] there is
-        [[: CAPITAL LETTER I WITH DOT lower:]] in mbs.  Skip
-        in that case the whole multi-byte character and return
-        the original letter.  On the other side, with
-        [[: DOTLESS SMALL LETTER I return [[:I, as doing
-        anything else would complicate things too much.  */
-
-      if (!re_string_first_byte (pstr, pstr->cur_idx))
-       return re_string_fetch_byte (pstr);
-
-      off = pstr->offsets[pstr->cur_idx];
-      ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
-
-      if (! isascii (ch))
-       return re_string_fetch_byte (pstr);
-
-      re_string_skip_bytes (pstr,
-                           re_string_char_size_at (pstr, pstr->cur_idx));
-      return ch;
-    }
-#endif
-
-  return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++];
-}
-
-static void
-internal_function
-re_string_destruct (re_string_t *pstr)
-{
-#ifdef RE_ENABLE_I18N
-  re_free (pstr->wcs);
-  re_free (pstr->offsets);
-#endif /* RE_ENABLE_I18N  */
-  if (pstr->mbs_allocated)
-    re_free (pstr->mbs);
-}
-
-/* Return the context at IDX in INPUT.  */
-
-static unsigned int
-internal_function
-re_string_context_at (const re_string_t *input, Idx idx, int eflags)
-{
-  int c;
-  if (BE (! REG_VALID_INDEX (idx), 0))
-    /* In this case, we use the value stored in input->tip_context,
-       since we can't know the character in input->mbs[-1] here.  */
-    return input->tip_context;
-  if (BE (idx == input->len, 0))
-    return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
-           : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
-#ifdef RE_ENABLE_I18N
-  if (input->mb_cur_max > 1)
-    {
-      wint_t wc;
-      Idx wc_idx = idx;
-      while(input->wcs[wc_idx] == WEOF)
-       {
-#ifdef DEBUG
-         /* It must not happen.  */
-         assert (REG_VALID_INDEX (wc_idx));
-#endif
-         --wc_idx;
-         if (! REG_VALID_INDEX (wc_idx))
-           return input->tip_context;
-       }
-      wc = input->wcs[wc_idx];
-      if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc))
-       return CONTEXT_WORD;
-      return (IS_WIDE_NEWLINE (wc) && input->newline_anchor
-             ? CONTEXT_NEWLINE : 0);
-    }
-  else
-#endif
-    {
-      c = re_string_byte_at (input, idx);
-      if (bitset_contain (input->word_char, c))
-       return CONTEXT_WORD;
-      return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0;
-    }
-}
-\f
-/* Functions for set operation.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-re_node_set_alloc (re_node_set *set, Idx size)
-{
-  set->alloc = size;
-  set->nelem = 0;
-  set->elems = re_malloc (Idx, size);
-  if (BE (set->elems == NULL, 0))
-    return REG_ESPACE;
-  return REG_NOERROR;
-}
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-re_node_set_init_1 (re_node_set *set, Idx elem)
-{
-  set->alloc = 1;
-  set->nelem = 1;
-  set->elems = re_malloc (Idx, 1);
-  if (BE (set->elems == NULL, 0))
-    {
-      set->alloc = set->nelem = 0;
-      return REG_ESPACE;
-    }
-  set->elems[0] = elem;
-  return REG_NOERROR;
-}
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2)
-{
-  set->alloc = 2;
-  set->elems = re_malloc (Idx, 2);
-  if (BE (set->elems == NULL, 0))
-    return REG_ESPACE;
-  if (elem1 == elem2)
-    {
-      set->nelem = 1;
-      set->elems[0] = elem1;
-    }
-  else
-    {
-      set->nelem = 2;
-      if (elem1 < elem2)
-       {
-         set->elems[0] = elem1;
-         set->elems[1] = elem2;
-       }
-      else
-       {
-         set->elems[0] = elem2;
-         set->elems[1] = elem1;
-       }
-    }
-  return REG_NOERROR;
-}
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
-{
-  dest->nelem = src->nelem;
-  if (src->nelem > 0)
-    {
-      dest->alloc = dest->nelem;
-      dest->elems = re_malloc (Idx, dest->alloc);
-      if (BE (dest->elems == NULL, 0))
-       {
-         dest->alloc = dest->nelem = 0;
-         return REG_ESPACE;
-       }
-      memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));
-    }
-  else
-    re_node_set_init_empty (dest);
-  return REG_NOERROR;
-}
-
-/* Calculate the intersection of the sets SRC1 and SRC2. And merge it to
-   DEST. Return value indicate the error code or REG_NOERROR if succeeded.
-   Note: We assume dest->elems is NULL, when dest->alloc is 0.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
-                          const re_node_set *src2)
-{
-  Idx i1, i2, is, id, delta, sbase;
-  if (src1->nelem == 0 || src2->nelem == 0)
-    return REG_NOERROR;
-
-  /* We need dest->nelem + 2 * elems_in_intersection; this is a
-     conservative estimate.  */
-  if (src1->nelem + src2->nelem + dest->nelem > dest->alloc)
-    {
-      Idx new_alloc = src1->nelem + src2->nelem + dest->alloc;
-      Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc);
-      if (BE (new_elems == NULL, 0))
-       return REG_ESPACE;
-      dest->elems = new_elems;
-      dest->alloc = new_alloc;
-    }
-
-  /* Find the items in the intersection of SRC1 and SRC2, and copy
-     into the top of DEST those that are not already in DEST itself.  */
-  sbase = dest->nelem + src1->nelem + src2->nelem;
-  i1 = src1->nelem - 1;
-  i2 = src2->nelem - 1;
-  id = dest->nelem - 1;
-  for (;;)
-    {
-      if (src1->elems[i1] == src2->elems[i2])
-       {
-         /* Try to find the item in DEST.  Maybe we could binary search?  */
-         while (REG_VALID_INDEX (id) && dest->elems[id] > src1->elems[i1])
-           --id;
-
-          if (! REG_VALID_INDEX (id) || dest->elems[id] != src1->elems[i1])
-            dest->elems[--sbase] = src1->elems[i1];
-
-         if (! REG_VALID_INDEX (--i1) || ! REG_VALID_INDEX (--i2))
-           break;
-       }
-
-      /* Lower the highest of the two items.  */
-      else if (src1->elems[i1] < src2->elems[i2])
-       {
-         if (! REG_VALID_INDEX (--i2))
-           break;
-       }
-      else
-       {
-         if (! REG_VALID_INDEX (--i1))
-           break;
-       }
-    }
-
-  id = dest->nelem - 1;
-  is = dest->nelem + src1->nelem + src2->nelem - 1;
-  delta = is - sbase + 1;
-
-  /* Now copy.  When DELTA becomes zero, the remaining
-     DEST elements are already in place; this is more or
-     less the same loop that is in re_node_set_merge.  */
-  dest->nelem += delta;
-  if (delta > 0 && REG_VALID_INDEX (id))
-    for (;;)
-      {
-       if (dest->elems[is] > dest->elems[id])
-         {
-           /* Copy from the top.  */
-           dest->elems[id + delta--] = dest->elems[is--];
-           if (delta == 0)
-             break;
-         }
-       else
-         {
-           /* Slide from the bottom.  */
-           dest->elems[id + delta] = dest->elems[id];
-           if (! REG_VALID_INDEX (--id))
-             break;
-         }
-      }
-
-  /* Copy remaining SRC elements.  */
-  memcpy (dest->elems, dest->elems + sbase, delta * sizeof (Idx));
-
-  return REG_NOERROR;
-}
-
-/* Calculate the union set of the sets SRC1 and SRC2. And store it to
-   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
-                       const re_node_set *src2)
-{
-  Idx i1, i2, id;
-  if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0)
-    {
-      dest->alloc = src1->nelem + src2->nelem;
-      dest->elems = re_malloc (Idx, dest->alloc);
-      if (BE (dest->elems == NULL, 0))
-       return REG_ESPACE;
-    }
-  else
-    {
-      if (src1 != NULL && src1->nelem > 0)
-       return re_node_set_init_copy (dest, src1);
-      else if (src2 != NULL && src2->nelem > 0)
-       return re_node_set_init_copy (dest, src2);
-      else
-       re_node_set_init_empty (dest);
-      return REG_NOERROR;
-    }
-  for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;)
-    {
-      if (src1->elems[i1] > src2->elems[i2])
-       {
-         dest->elems[id++] = src2->elems[i2++];
-         continue;
-       }
-      if (src1->elems[i1] == src2->elems[i2])
-       ++i2;
-      dest->elems[id++] = src1->elems[i1++];
-    }
-  if (i1 < src1->nelem)
-    {
-      memcpy (dest->elems + id, src1->elems + i1,
-            (src1->nelem - i1) * sizeof (Idx));
-      id += src1->nelem - i1;
-    }
-  else if (i2 < src2->nelem)
-    {
-      memcpy (dest->elems + id, src2->elems + i2,
-            (src2->nelem - i2) * sizeof (Idx));
-      id += src2->nelem - i2;
-    }
-  dest->nelem = id;
-  return REG_NOERROR;
-}
-
-/* Calculate the union set of the sets DEST and SRC. And store it to
-   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-re_node_set_merge (re_node_set *dest, const re_node_set *src)
-{
-  Idx is, id, sbase, delta;
-  if (src == NULL || src->nelem == 0)
-    return REG_NOERROR;
-  if (dest->alloc < 2 * src->nelem + dest->nelem)
-    {
-      Idx new_alloc = 2 * (src->nelem + dest->alloc);
-      Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc);
-      if (BE (new_buffer == NULL, 0))
-       return REG_ESPACE;
-      dest->elems = new_buffer;
-      dest->alloc = new_alloc;
-    }
-
-  if (BE (dest->nelem == 0, 0))
-    {
-      dest->nelem = src->nelem;
-      memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));
-      return REG_NOERROR;
-    }
-
-  /* Copy into the top of DEST the items of SRC that are not
-     found in DEST.  Maybe we could binary search in DEST?  */
-  for (sbase = dest->nelem + 2 * src->nelem,
-       is = src->nelem - 1, id = dest->nelem - 1;
-       REG_VALID_INDEX (is) && REG_VALID_INDEX (id); )
-    {
-      if (dest->elems[id] == src->elems[is])
-       is--, id--;
-      else if (dest->elems[id] < src->elems[is])
-       dest->elems[--sbase] = src->elems[is--];
-      else /* if (dest->elems[id] > src->elems[is]) */
-       --id;
-    }
-
-  if (REG_VALID_INDEX (is))
-    {
-      /* If DEST is exhausted, the remaining items of SRC must be unique.  */
-      sbase -= is + 1;
-      memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (Idx));
-    }
-
-  id = dest->nelem - 1;
-  is = dest->nelem + 2 * src->nelem - 1;
-  delta = is - sbase + 1;
-  if (delta == 0)
-    return REG_NOERROR;
-
-  /* Now copy.  When DELTA becomes zero, the remaining
-     DEST elements are already in place.  */
-  dest->nelem += delta;
-  for (;;)
-    {
-      if (dest->elems[is] > dest->elems[id])
-       {
-         /* Copy from the top.  */
-         dest->elems[id + delta--] = dest->elems[is--];
-         if (delta == 0)
-           break;
-       }
-      else
-       {
-         /* Slide from the bottom.  */
-         dest->elems[id + delta] = dest->elems[id];
-         if (! REG_VALID_INDEX (--id))
-           {
-             /* Copy remaining SRC elements.  */
-             memcpy (dest->elems, dest->elems + sbase,
-                     delta * sizeof (Idx));
-             break;
-           }
-       }
-    }
-
-  return REG_NOERROR;
-}
-
-/* Insert the new element ELEM to the re_node_set* SET.
-   SET should not already have ELEM.
-   Return true if successful.  */
-
-static bool
-internal_function __attribute_warn_unused_result__
-re_node_set_insert (re_node_set *set, Idx elem)
-{
-  Idx idx;
-  /* In case the set is empty.  */
-  if (set->alloc == 0)
-    return BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1);
-
-  if (BE (set->nelem, 0) == 0)
-    {
-      /* We already guaranteed above that set->alloc != 0.  */
-      set->elems[0] = elem;
-      ++set->nelem;
-      return true;
-    }
-
-  /* Realloc if we need.  */
-  if (set->alloc == set->nelem)
-    {
-      Idx *new_elems;
-      set->alloc = set->alloc * 2;
-      new_elems = re_realloc (set->elems, Idx, set->alloc);
-      if (BE (new_elems == NULL, 0))
-       return false;
-      set->elems = new_elems;
-    }
-
-  /* Move the elements which follows the new element.  Test the
-     first element separately to skip a check in the inner loop.  */
-  if (elem < set->elems[0])
-    {
-      idx = 0;
-      for (idx = set->nelem; idx > 0; idx--)
-       set->elems[idx] = set->elems[idx - 1];
-    }
-  else
-    {
-      for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
-       set->elems[idx] = set->elems[idx - 1];
-    }
-
-  /* Insert the new element.  */
-  set->elems[idx] = elem;
-  ++set->nelem;
-  return true;
-}
-
-/* Insert the new element ELEM to the re_node_set* SET.
-   SET should not already have any element greater than or equal to ELEM.
-   Return true if successful.  */
-
-static bool
-internal_function __attribute_warn_unused_result__
-re_node_set_insert_last (re_node_set *set, Idx elem)
-{
-  /* Realloc if we need.  */
-  if (set->alloc == set->nelem)
-    {
-      Idx *new_elems;
-      set->alloc = (set->alloc + 1) * 2;
-      new_elems = re_realloc (set->elems, Idx, set->alloc);
-      if (BE (new_elems == NULL, 0))
-       return false;
-      set->elems = new_elems;
-    }
-
-  /* Insert the new element.  */
-  set->elems[set->nelem++] = elem;
-  return true;
-}
-
-/* Compare two node sets SET1 and SET2.
-   Return true if SET1 and SET2 are equivalent.  */
-
-static bool
-internal_function __attribute ((pure))
-re_node_set_compare (const re_node_set *set1, const re_node_set *set2)
-{
-  Idx i;
-  if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem)
-    return false;
-  for (i = set1->nelem ; REG_VALID_INDEX (--i) ; )
-    if (set1->elems[i] != set2->elems[i])
-      return false;
-  return true;
-}
-
-/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise.  */
-
-static Idx
-internal_function __attribute ((pure))
-re_node_set_contains (const re_node_set *set, Idx elem)
-{
-  __re_size_t idx, right, mid;
-  if (! REG_VALID_NONZERO_INDEX (set->nelem))
-    return 0;
-
-  /* Binary search the element.  */
-  idx = 0;
-  right = set->nelem - 1;
-  while (idx < right)
-    {
-      mid = (idx + right) / 2;
-      if (set->elems[mid] < elem)
-       idx = mid + 1;
-      else
-       right = mid;
-    }
-  return set->elems[idx] == elem ? idx + 1 : 0;
-}
-
-static void
-internal_function
-re_node_set_remove_at (re_node_set *set, Idx idx)
-{
-  if (idx < 0 || idx >= set->nelem)
-    return;
-  --set->nelem;
-  for (; idx < set->nelem; idx++)
-    set->elems[idx] = set->elems[idx + 1];
-}
-\f
-
-/* Add the token TOKEN to dfa->nodes, and return the index of the token.
-   Or return REG_MISSING if an error occurred.  */
-
-static Idx
-internal_function
-re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
-{
-  if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0))
-    {
-      size_t new_nodes_alloc = dfa->nodes_alloc * 2;
-      Idx *new_nexts, *new_indices;
-      re_node_set *new_edests, *new_eclosures;
-      re_token_t *new_nodes;
-      size_t max_object_size =
-       MAX (sizeof (re_token_t),
-            MAX (sizeof (re_node_set),
-                 sizeof (Idx)));
-
-      /* Avoid overflows.  */
-      if (BE (SIZE_MAX / 2 / max_object_size < dfa->nodes_alloc, 0))
-       return REG_MISSING;
-
-      new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc);
-      if (BE (new_nodes == NULL, 0))
-       return REG_MISSING;
-      dfa->nodes = new_nodes;
-      new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc);
-      new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc);
-      new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc);
-      new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc);
-      if (BE (new_nexts == NULL || new_indices == NULL
-             || new_edests == NULL || new_eclosures == NULL, 0))
-       return REG_MISSING;
-      dfa->nexts = new_nexts;
-      dfa->org_indices = new_indices;
-      dfa->edests = new_edests;
-      dfa->eclosures = new_eclosures;
-      dfa->nodes_alloc = new_nodes_alloc;
-    }
-  dfa->nodes[dfa->nodes_len] = token;
-  dfa->nodes[dfa->nodes_len].constraint = 0;
-#ifdef RE_ENABLE_I18N
-  {
-  int type = token.type;
-  dfa->nodes[dfa->nodes_len].accept_mb =
-    (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET;
-  }
-#endif
-  dfa->nexts[dfa->nodes_len] = REG_MISSING;
-  re_node_set_init_empty (dfa->edests + dfa->nodes_len);
-  re_node_set_init_empty (dfa->eclosures + dfa->nodes_len);
-  return dfa->nodes_len++;
-}
-
-static inline re_hashval_t
-internal_function
-calc_state_hash (const re_node_set *nodes, unsigned int context)
-{
-  re_hashval_t hash = nodes->nelem + context;
-  Idx i;
-  for (i = 0 ; i < nodes->nelem ; i++)
-    hash += nodes->elems[i];
-  return hash;
-}
-
-/* Search for the state whose node_set is equivalent to NODES.
-   Return the pointer to the state, if we found it in the DFA.
-   Otherwise create the new one and return it.  In case of an error
-   return NULL and set the error code in ERR.
-   Note: - We assume NULL as the invalid state, then it is possible that
-          return value is NULL and ERR is REG_NOERROR.
-        - We never return non-NULL value in case of any errors, it is for
-          optimization.  */
-
-static re_dfastate_t *
-internal_function __attribute_warn_unused_result__
-re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
-                 const re_node_set *nodes)
-{
-  re_hashval_t hash;
-  re_dfastate_t *new_state;
-  struct re_state_table_entry *spot;
-  Idx i;
-#ifdef lint
-  /* Suppress bogus uninitialized-variable warnings.  */
-  *err = REG_NOERROR;
-#endif
-  if (BE (nodes->nelem == 0, 0))
-    {
-      *err = REG_NOERROR;
-      return NULL;
-    }
-  hash = calc_state_hash (nodes, 0);
-  spot = dfa->state_table + (hash & dfa->state_hash_mask);
-
-  for (i = 0 ; i < spot->num ; i++)
-    {
-      re_dfastate_t *state = spot->array[i];
-      if (hash != state->hash)
-       continue;
-      if (re_node_set_compare (&state->nodes, nodes))
-       return state;
-    }
-
-  /* There are no appropriate state in the dfa, create the new one.  */
-  new_state = create_ci_newstate (dfa, nodes, hash);
-  if (BE (new_state == NULL, 0))
-    *err = REG_ESPACE;
-
-  return new_state;
-}
-
-/* Search for the state whose node_set is equivalent to NODES and
-   whose context is equivalent to CONTEXT.
-   Return the pointer to the state, if we found it in the DFA.
-   Otherwise create the new one and return it.  In case of an error
-   return NULL and set the error code in ERR.
-   Note: - We assume NULL as the invalid state, then it is possible that
-          return value is NULL and ERR is REG_NOERROR.
-        - We never return non-NULL value in case of any errors, it is for
-          optimization.  */
-
-static re_dfastate_t *
-internal_function __attribute_warn_unused_result__
-re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
-                         const re_node_set *nodes, unsigned int context)
-{
-  re_hashval_t hash;
-  re_dfastate_t *new_state;
-  struct re_state_table_entry *spot;
-  Idx i;
-#ifdef lint
-  /* Suppress bogus uninitialized-variable warnings.  */
-  *err = REG_NOERROR;
-#endif
-  if (nodes->nelem == 0)
-    {
-      *err = REG_NOERROR;
-      return NULL;
-    }
-  hash = calc_state_hash (nodes, context);
-  spot = dfa->state_table + (hash & dfa->state_hash_mask);
-
-  for (i = 0 ; i < spot->num ; i++)
-    {
-      re_dfastate_t *state = spot->array[i];
-      if (state->hash == hash
-         && state->context == context
-         && re_node_set_compare (state->entrance_nodes, nodes))
-       return state;
-    }
-  /* There are no appropriate state in `dfa', create the new one.  */
-  new_state = create_cd_newstate (dfa, nodes, context, hash);
-  if (BE (new_state == NULL, 0))
-    *err = REG_ESPACE;
-
-  return new_state;
-}
-
-/* Finish initialization of the new state NEWSTATE, and using its hash value
-   HASH put in the appropriate bucket of DFA's state table.  Return value
-   indicates the error code if failed.  */
-
-static reg_errcode_t
-__attribute_warn_unused_result__
-register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
-               re_hashval_t hash)
-{
-  struct re_state_table_entry *spot;
-  reg_errcode_t err;
-  Idx i;
-
-  newstate->hash = hash;
-  err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem);
-  if (BE (err != REG_NOERROR, 0))
-    return REG_ESPACE;
-  for (i = 0; i < newstate->nodes.nelem; i++)
-    {
-      Idx elem = newstate->nodes.elems[i];
-      if (!IS_EPSILON_NODE (dfa->nodes[elem].type))
-       if (BE (! re_node_set_insert_last (&newstate->non_eps_nodes, elem), 0))
-         return REG_ESPACE;
-    }
-
-  spot = dfa->state_table + (hash & dfa->state_hash_mask);
-  if (BE (spot->alloc <= spot->num, 0))
-    {
-      Idx new_alloc = 2 * spot->num + 2;
-      re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *,
-                                             new_alloc);
-      if (BE (new_array == NULL, 0))
-       return REG_ESPACE;
-      spot->array = new_array;
-      spot->alloc = new_alloc;
-    }
-  spot->array[spot->num++] = newstate;
-  return REG_NOERROR;
-}
-
-static void
-free_state (re_dfastate_t *state)
-{
-  re_node_set_free (&state->non_eps_nodes);
-  re_node_set_free (&state->inveclosure);
-  if (state->entrance_nodes != &state->nodes)
-    {
-      re_node_set_free (state->entrance_nodes);
-      re_free (state->entrance_nodes);
-    }
-  re_node_set_free (&state->nodes);
-  re_free (state->word_trtable);
-  re_free (state->trtable);
-  re_free (state);
-}
-
-/* Create the new state which is independ of contexts.
-   Return the new state if succeeded, otherwise return NULL.  */
-
-static re_dfastate_t *
-internal_function __attribute_warn_unused_result__
-create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
-                   re_hashval_t hash)
-{
-  Idx i;
-  reg_errcode_t err;
-  re_dfastate_t *newstate;
-
-  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
-  if (BE (newstate == NULL, 0))
-    return NULL;
-  err = re_node_set_init_copy (&newstate->nodes, nodes);
-  if (BE (err != REG_NOERROR, 0))
-    {
-      re_free (newstate);
-      return NULL;
-    }
-
-  newstate->entrance_nodes = &newstate->nodes;
-  for (i = 0 ; i < nodes->nelem ; i++)
-    {
-      re_token_t *node = dfa->nodes + nodes->elems[i];
-      re_token_type_t type = node->type;
-      if (type == CHARACTER && !node->constraint)
-       continue;
-#ifdef RE_ENABLE_I18N
-      newstate->accept_mb |= node->accept_mb;
-#endif /* RE_ENABLE_I18N */
-
-      /* If the state has the halt node, the state is a halt state.  */
-      if (type == END_OF_RE)
-       newstate->halt = 1;
-      else if (type == OP_BACK_REF)
-       newstate->has_backref = 1;
-      else if (type == ANCHOR || node->constraint)
-       newstate->has_constraint = 1;
-    }
-  err = register_state (dfa, newstate, hash);
-  if (BE (err != REG_NOERROR, 0))
-    {
-      free_state (newstate);
-      newstate = NULL;
-    }
-  return newstate;
-}
-
-/* Create the new state which is depend on the context CONTEXT.
-   Return the new state if succeeded, otherwise return NULL.  */
-
-static re_dfastate_t *
-internal_function __attribute_warn_unused_result__
-create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
-                   unsigned int context, re_hashval_t hash)
-{
-  Idx i, nctx_nodes = 0;
-  reg_errcode_t err;
-  re_dfastate_t *newstate;
-
-  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
-  if (BE (newstate == NULL, 0))
-    return NULL;
-  err = re_node_set_init_copy (&newstate->nodes, nodes);
-  if (BE (err != REG_NOERROR, 0))
-    {
-      re_free (newstate);
-      return NULL;
-    }
-
-  newstate->context = context;
-  newstate->entrance_nodes = &newstate->nodes;
-
-  for (i = 0 ; i < nodes->nelem ; i++)
-    {
-      re_token_t *node = dfa->nodes + nodes->elems[i];
-      re_token_type_t type = node->type;
-      unsigned int constraint = node->constraint;
-
-      if (type == CHARACTER && !constraint)
-       continue;
-#ifdef RE_ENABLE_I18N
-      newstate->accept_mb |= node->accept_mb;
-#endif /* RE_ENABLE_I18N */
-
-      /* If the state has the halt node, the state is a halt state.  */
-      if (type == END_OF_RE)
-       newstate->halt = 1;
-      else if (type == OP_BACK_REF)
-       newstate->has_backref = 1;
-
-      if (constraint)
-       {
-         if (newstate->entrance_nodes == &newstate->nodes)
-           {
-             newstate->entrance_nodes = re_malloc (re_node_set, 1);
-             if (BE (newstate->entrance_nodes == NULL, 0))
-               {
-                 free_state (newstate);
-                 return NULL;
-               }
-             if (re_node_set_init_copy (newstate->entrance_nodes, nodes)
-                 != REG_NOERROR)
-               return NULL;
-             nctx_nodes = 0;
-             newstate->has_constraint = 1;
-           }
-
-         if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context))
-           {
-             re_node_set_remove_at (&newstate->nodes, i - nctx_nodes);
-             ++nctx_nodes;
-           }
-       }
-    }
-  err = register_state (dfa, newstate, hash);
-  if (BE (err != REG_NOERROR, 0))
-    {
-      free_state (newstate);
-      newstate = NULL;
-    }
-  return  newstate;
-}
diff --git a/gnulib/regex_internal.h b/gnulib/regex_internal.h
deleted file mode 100644 (file)
index e1b4c61..0000000
+++ /dev/null
@@ -1,871 +0,0 @@
-/* Extended regular expression matching and search library.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
-   Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
-
-   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifndef _REGEX_INTERNAL_H
-#define _REGEX_INTERNAL_H 1
-
-#include <assert.h>
-#include <ctype.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <langinfo.h>
-#ifndef _LIBC
-# include "localcharset.h"
-#endif
-#if defined HAVE_LOCALE_H || defined _LIBC
-# include <locale.h>
-#endif
-
-#include <wchar.h>
-#include <wctype.h>
-#include <stdint.h>
-#if defined _LIBC
-# include <bits/libc-lock.h>
-#else
-# define __libc_lock_init(NAME) do { } while (0)
-# define __libc_lock_lock(NAME) do { } while (0)
-# define __libc_lock_unlock(NAME) do { } while (0)
-#endif
-
-/* In case that the system doesn't have isblank().  */
-#if !defined _LIBC && ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK))
-# define isblank(ch) ((ch) == ' ' || (ch) == '\t')
-#endif
-
-#ifdef _LIBC
-# ifndef _RE_DEFINE_LOCALE_FUNCTIONS
-#  define _RE_DEFINE_LOCALE_FUNCTIONS 1
-#   include <locale/localeinfo.h>
-#   include <locale/elem-hash.h>
-#   include <locale/coll-lookup.h>
-# endif
-#endif
-
-/* This is for other GNU distributions with internationalized messages.  */
-#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
-# include <libintl.h>
-# ifdef _LIBC
-#  undef gettext
-#  define gettext(msgid) \
-  INTUSE(__dcgettext) (_libc_intl_domainname, msgid, LC_MESSAGES)
-# endif
-#else
-# define gettext(msgid) (msgid)
-#endif
-
-#ifndef gettext_noop
-/* This define is so xgettext can find the internationalizable
-   strings.  */
-# define gettext_noop(String) String
-#endif
-
-/* For loser systems without the definition.  */
-#ifndef SIZE_MAX
-# define SIZE_MAX ((size_t) -1)
-#endif
-
-#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCSCOLL) || _LIBC
-# define RE_ENABLE_I18N
-#endif
-
-#if __GNUC__ >= 3
-# define BE(expr, val) __builtin_expect (expr, val)
-#else
-# define BE(expr, val) (expr)
-# ifdef _LIBC
-#  define inline
-# endif
-#endif
-
-/* Number of ASCII characters.  */
-#define ASCII_CHARS 0x80
-
-/* Number of single byte characters.  */
-#define SBC_MAX (UCHAR_MAX + 1)
-
-#define COLL_ELEM_LEN_MAX 8
-
-/* The character which represents newline.  */
-#define NEWLINE_CHAR '\n'
-#define WIDE_NEWLINE_CHAR L'\n'
-
-/* Rename to standard API for using out of glibc.  */
-#ifndef _LIBC
-# define __wctype wctype
-# define __iswctype iswctype
-# define __btowc btowc
-# define __wcrtomb wcrtomb
-# define __mbrtowc mbrtowc
-# define __regfree regfree
-# define attribute_hidden
-#endif /* not _LIBC */
-
-#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
-# define __attribute(arg) __attribute__ (arg)
-#else
-# define __attribute(arg)
-#endif
-
-typedef __re_idx_t Idx;
-
-/* Special return value for failure to match.  */
-#define REG_MISSING ((Idx) -1)
-
-/* Special return value for internal error.  */
-#define REG_ERROR ((Idx) -2)
-
-/* Test whether N is a valid index, and is not one of the above.  */
-#ifdef _REGEX_LARGE_OFFSETS
-# define REG_VALID_INDEX(n) ((Idx) (n) < REG_ERROR)
-#else
-# define REG_VALID_INDEX(n) (0 <= (n))
-#endif
-
-/* Test whether N is a valid nonzero index.  */
-#ifdef _REGEX_LARGE_OFFSETS
-# define REG_VALID_NONZERO_INDEX(n) ((Idx) ((n) - 1) < (Idx) (REG_ERROR - 1))
-#else
-# define REG_VALID_NONZERO_INDEX(n) (0 < (n))
-#endif
-
-/* A hash value, suitable for computing hash tables.  */
-typedef __re_size_t re_hashval_t;
-
-/* An integer used to represent a set of bits.  It must be unsigned,
-   and must be at least as wide as unsigned int.  */
-typedef unsigned long int bitset_word_t;
-/* All bits set in a bitset_word_t.  */
-#define BITSET_WORD_MAX ULONG_MAX
-
-/* Number of bits in a bitset_word_t.  For portability to hosts with
-   padding bits, do not use '(sizeof (bitset_word_t) * CHAR_BIT)';
-   instead, deduce it directly from BITSET_WORD_MAX.  Avoid
-   greater-than-32-bit integers and unconditional shifts by more than
-   31 bits, as they're not portable.  */
-#if BITSET_WORD_MAX == 0xffffffffUL
-# define BITSET_WORD_BITS 32
-#elif BITSET_WORD_MAX >> 31 >> 4 == 1
-# define BITSET_WORD_BITS 36
-#elif BITSET_WORD_MAX >> 31 >> 16 == 1
-# define BITSET_WORD_BITS 48
-#elif BITSET_WORD_MAX >> 31 >> 28 == 1
-# define BITSET_WORD_BITS 60
-#elif BITSET_WORD_MAX >> 31 >> 31 >> 1 == 1
-# define BITSET_WORD_BITS 64
-#elif BITSET_WORD_MAX >> 31 >> 31 >> 9 == 1
-# define BITSET_WORD_BITS 72
-#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 3 == 1
-# define BITSET_WORD_BITS 128
-#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 == 1
-# define BITSET_WORD_BITS 256
-#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 > 1
-# define BITSET_WORD_BITS 257 /* any value > SBC_MAX will do here */
-# if BITSET_WORD_BITS <= SBC_MAX
-#  error "Invalid SBC_MAX"
-# endif
-#else
-# error "Add case for new bitset_word_t size"
-#endif
-
-/* Number of bitset_word_t values in a bitset_t.  */
-#define BITSET_WORDS ((SBC_MAX + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
-
-typedef bitset_word_t bitset_t[BITSET_WORDS];
-typedef bitset_word_t *re_bitset_ptr_t;
-typedef const bitset_word_t *re_const_bitset_ptr_t;
-
-#define PREV_WORD_CONSTRAINT 0x0001
-#define PREV_NOTWORD_CONSTRAINT 0x0002
-#define NEXT_WORD_CONSTRAINT 0x0004
-#define NEXT_NOTWORD_CONSTRAINT 0x0008
-#define PREV_NEWLINE_CONSTRAINT 0x0010
-#define NEXT_NEWLINE_CONSTRAINT 0x0020
-#define PREV_BEGBUF_CONSTRAINT 0x0040
-#define NEXT_ENDBUF_CONSTRAINT 0x0080
-#define WORD_DELIM_CONSTRAINT 0x0100
-#define NOT_WORD_DELIM_CONSTRAINT 0x0200
-
-typedef enum
-{
-  INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
-  WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
-  WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
-  INSIDE_NOTWORD = PREV_NOTWORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
-  LINE_FIRST = PREV_NEWLINE_CONSTRAINT,
-  LINE_LAST = NEXT_NEWLINE_CONSTRAINT,
-  BUF_FIRST = PREV_BEGBUF_CONSTRAINT,
-  BUF_LAST = NEXT_ENDBUF_CONSTRAINT,
-  WORD_DELIM = WORD_DELIM_CONSTRAINT,
-  NOT_WORD_DELIM = NOT_WORD_DELIM_CONSTRAINT
-} re_context_type;
-
-typedef struct
-{
-  Idx alloc;
-  Idx nelem;
-  Idx *elems;
-} re_node_set;
-
-typedef enum
-{
-  NON_TYPE = 0,
-
-  /* Node type, These are used by token, node, tree.  */
-  CHARACTER = 1,
-  END_OF_RE = 2,
-  SIMPLE_BRACKET = 3,
-  OP_BACK_REF = 4,
-  OP_PERIOD = 5,
-#ifdef RE_ENABLE_I18N
-  COMPLEX_BRACKET = 6,
-  OP_UTF8_PERIOD = 7,
-#endif /* RE_ENABLE_I18N */
-
-  /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used
-     when the debugger shows values of this enum type.  */
-#define EPSILON_BIT 8
-  OP_OPEN_SUBEXP = EPSILON_BIT | 0,
-  OP_CLOSE_SUBEXP = EPSILON_BIT | 1,
-  OP_ALT = EPSILON_BIT | 2,
-  OP_DUP_ASTERISK = EPSILON_BIT | 3,
-  ANCHOR = EPSILON_BIT | 4,
-
-  /* Tree type, these are used only by tree. */
-  CONCAT = 16,
-  SUBEXP = 17,
-
-  /* Token type, these are used only by token.  */
-  OP_DUP_PLUS = 18,
-  OP_DUP_QUESTION,
-  OP_OPEN_BRACKET,
-  OP_CLOSE_BRACKET,
-  OP_CHARSET_RANGE,
-  OP_OPEN_DUP_NUM,
-  OP_CLOSE_DUP_NUM,
-  OP_NON_MATCH_LIST,
-  OP_OPEN_COLL_ELEM,
-  OP_CLOSE_COLL_ELEM,
-  OP_OPEN_EQUIV_CLASS,
-  OP_CLOSE_EQUIV_CLASS,
-  OP_OPEN_CHAR_CLASS,
-  OP_CLOSE_CHAR_CLASS,
-  OP_WORD,
-  OP_NOTWORD,
-  OP_SPACE,
-  OP_NOTSPACE,
-  BACK_SLASH
-
-} re_token_type_t;
-
-#ifdef RE_ENABLE_I18N
-typedef struct
-{
-  /* Multibyte characters.  */
-  wchar_t *mbchars;
-
-  /* Collating symbols.  */
-# ifdef _LIBC
-  int32_t *coll_syms;
-# endif
-
-  /* Equivalence classes. */
-# ifdef _LIBC
-  int32_t *equiv_classes;
-# endif
-
-  /* Range expressions. */
-# ifdef _LIBC
-  uint32_t *range_starts;
-  uint32_t *range_ends;
-# else /* not _LIBC */
-  wchar_t *range_starts;
-  wchar_t *range_ends;
-# endif /* not _LIBC */
-
-  /* Character classes. */
-  wctype_t *char_classes;
-
-  /* If this character set is the non-matching list.  */
-  unsigned int non_match : 1;
-
-  /* # of multibyte characters.  */
-  Idx nmbchars;
-
-  /* # of collating symbols.  */
-  Idx ncoll_syms;
-
-  /* # of equivalence classes. */
-  Idx nequiv_classes;
-
-  /* # of range expressions. */
-  Idx nranges;
-
-  /* # of character classes. */
-  Idx nchar_classes;
-} re_charset_t;
-#endif /* RE_ENABLE_I18N */
-
-typedef struct
-{
-  union
-  {
-    unsigned char c;           /* for CHARACTER */
-    re_bitset_ptr_t sbcset;    /* for SIMPLE_BRACKET */
-#ifdef RE_ENABLE_I18N
-    re_charset_t *mbcset;      /* for COMPLEX_BRACKET */
-#endif /* RE_ENABLE_I18N */
-    Idx idx;                   /* for BACK_REF */
-    re_context_type ctx_type;  /* for ANCHOR */
-  } opr;
-#if __GNUC__ >= 2 && !__STRICT_ANSI__
-  re_token_type_t type : 8;
-#else
-  re_token_type_t type;
-#endif
-  unsigned int constraint : 10;        /* context constraint */
-  unsigned int duplicated : 1;
-  unsigned int opt_subexp : 1;
-#ifdef RE_ENABLE_I18N
-  unsigned int accept_mb : 1;
-  /* These 2 bits can be moved into the union if needed (e.g. if running out
-     of bits; move opr.c to opr.c.c and move the flags to opr.c.flags).  */
-  unsigned int mb_partial : 1;
-#endif
-  unsigned int word_char : 1;
-} re_token_t;
-
-#define IS_EPSILON_NODE(type) ((type) & EPSILON_BIT)
-
-struct re_string_t
-{
-  /* Indicate the raw buffer which is the original string passed as an
-     argument of regexec(), re_search(), etc..  */
-  const unsigned char *raw_mbs;
-  /* Store the multibyte string.  In case of "case insensitive mode" like
-     REG_ICASE, upper cases of the string are stored, otherwise MBS points
-     the same address that RAW_MBS points.  */
-  unsigned char *mbs;
-#ifdef RE_ENABLE_I18N
-  /* Store the wide character string which is corresponding to MBS.  */
-  wint_t *wcs;
-  Idx *offsets;
-  mbstate_t cur_state;
-#endif
-  /* Index in RAW_MBS.  Each character mbs[i] corresponds to
-     raw_mbs[raw_mbs_idx + i].  */
-  Idx raw_mbs_idx;
-  /* The length of the valid characters in the buffers.  */
-  Idx valid_len;
-  /* The corresponding number of bytes in raw_mbs array.  */
-  Idx valid_raw_len;
-  /* The length of the buffers MBS and WCS.  */
-  Idx bufs_len;
-  /* The index in MBS, which is updated by re_string_fetch_byte.  */
-  Idx cur_idx;
-  /* length of RAW_MBS array.  */
-  Idx raw_len;
-  /* This is RAW_LEN - RAW_MBS_IDX + VALID_LEN - VALID_RAW_LEN.  */
-  Idx len;
-  /* End of the buffer may be shorter than its length in the cases such
-     as re_match_2, re_search_2.  Then, we use STOP for end of the buffer
-     instead of LEN.  */
-  Idx raw_stop;
-  /* This is RAW_STOP - RAW_MBS_IDX adjusted through OFFSETS.  */
-  Idx stop;
-
-  /* The context of mbs[0].  We store the context independently, since
-     the context of mbs[0] may be different from raw_mbs[0], which is
-     the beginning of the input string.  */
-  unsigned int tip_context;
-  /* The translation passed as a part of an argument of re_compile_pattern.  */
-  RE_TRANSLATE_TYPE trans;
-  /* Copy of re_dfa_t's word_char.  */
-  re_const_bitset_ptr_t word_char;
-  /* true if REG_ICASE.  */
-  unsigned char icase;
-  unsigned char is_utf8;
-  unsigned char map_notascii;
-  unsigned char mbs_allocated;
-  unsigned char offsets_needed;
-  unsigned char newline_anchor;
-  unsigned char word_ops_used;
-  int mb_cur_max;
-};
-typedef struct re_string_t re_string_t;
-
-
-struct re_dfa_t;
-typedef struct re_dfa_t re_dfa_t;
-
-#ifndef _LIBC
-# if defined __i386__ && !defined __EMX__
-#  define internal_function   __attribute ((regparm (3), stdcall))
-# else
-#  define internal_function
-# endif
-#endif
-
-static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr,
-                                               Idx new_buf_len)
-     internal_function;
-#ifdef RE_ENABLE_I18N
-static void build_wcs_buffer (re_string_t *pstr) internal_function;
-static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr)
-     internal_function;
-#endif /* RE_ENABLE_I18N */
-static void build_upper_buffer (re_string_t *pstr) internal_function;
-static void re_string_translate_buffer (re_string_t *pstr) internal_function;
-static unsigned int re_string_context_at (const re_string_t *input, Idx idx,
-                                         int eflags)
-     internal_function __attribute ((pure));
-#define re_string_peek_byte(pstr, offset) \
-  ((pstr)->mbs[(pstr)->cur_idx + offset])
-#define re_string_fetch_byte(pstr) \
-  ((pstr)->mbs[(pstr)->cur_idx++])
-#define re_string_first_byte(pstr, idx) \
-  ((idx) == (pstr)->valid_len || (pstr)->wcs[idx] != WEOF)
-#define re_string_is_single_byte_char(pstr, idx) \
-  ((pstr)->wcs[idx] != WEOF && ((pstr)->valid_len == (idx) + 1 \
-                               || (pstr)->wcs[(idx) + 1] != WEOF))
-#define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx)
-#define re_string_cur_idx(pstr) ((pstr)->cur_idx)
-#define re_string_get_buffer(pstr) ((pstr)->mbs)
-#define re_string_length(pstr) ((pstr)->len)
-#define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx])
-#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx))
-#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx))
-
-#include <alloca.h>
-
-#ifndef _LIBC
-# if HAVE_ALLOCA
-/* The OS usually guarantees only one guard page at the bottom of the stack,
-   and a page size can be as small as 4096 bytes.  So we cannot safely
-   allocate anything larger than 4096 bytes.  Also care for the possibility
-   of a few compiler-allocated temporary stack slots.  */
-#  define __libc_use_alloca(n) ((n) < 4032)
-# else
-/* alloca is implemented with malloc, so just use malloc.  */
-#  define __libc_use_alloca(n) 0
-# endif
-#endif
-
-#ifndef MAX
-# define MAX(a,b) ((a) < (b) ? (b) : (a))
-#endif
-
-#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t)))
-#define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t)))
-#define re_free(p) free (p)
-
-struct bin_tree_t
-{
-  struct bin_tree_t *parent;
-  struct bin_tree_t *left;
-  struct bin_tree_t *right;
-  struct bin_tree_t *first;
-  struct bin_tree_t *next;
-
-  re_token_t token;
-
-  /* `node_idx' is the index in dfa->nodes, if `type' == 0.
-     Otherwise `type' indicate the type of this node.  */
-  Idx node_idx;
-};
-typedef struct bin_tree_t bin_tree_t;
-
-#define BIN_TREE_STORAGE_SIZE \
-  ((1024 - sizeof (void *)) / sizeof (bin_tree_t))
-
-struct bin_tree_storage_t
-{
-  struct bin_tree_storage_t *next;
-  bin_tree_t data[BIN_TREE_STORAGE_SIZE];
-};
-typedef struct bin_tree_storage_t bin_tree_storage_t;
-
-#define CONTEXT_WORD 1
-#define CONTEXT_NEWLINE (CONTEXT_WORD << 1)
-#define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1)
-#define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1)
-
-#define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD)
-#define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE)
-#define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF)
-#define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF)
-#define IS_ORDINARY_CONTEXT(c) ((c) == 0)
-
-#define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_')
-#define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR)
-#define IS_WIDE_WORD_CHAR(ch) (iswalnum (ch) || (ch) == L'_')
-#define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR)
-
-#define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \
- ((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
-  || ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
-  || ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\
-  || ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context)))
-
-#define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \
- ((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
-  || (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
-  || (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \
-  || (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context)))
-
-struct re_dfastate_t
-{
-  re_hashval_t hash;
-  re_node_set nodes;
-  re_node_set non_eps_nodes;
-  re_node_set inveclosure;
-  re_node_set *entrance_nodes;
-  struct re_dfastate_t **trtable, **word_trtable;
-  unsigned int context : 4;
-  unsigned int halt : 1;
-  /* If this state can accept `multi byte'.
-     Note that we refer to multibyte characters, and multi character
-     collating elements as `multi byte'.  */
-  unsigned int accept_mb : 1;
-  /* If this state has backreference node(s).  */
-  unsigned int has_backref : 1;
-  unsigned int has_constraint : 1;
-};
-typedef struct re_dfastate_t re_dfastate_t;
-
-struct re_state_table_entry
-{
-  Idx num;
-  Idx alloc;
-  re_dfastate_t **array;
-};
-
-/* Array type used in re_sub_match_last_t and re_sub_match_top_t.  */
-
-typedef struct
-{
-  Idx next_idx;
-  Idx alloc;
-  re_dfastate_t **array;
-} state_array_t;
-
-/* Store information about the node NODE whose type is OP_CLOSE_SUBEXP.  */
-
-typedef struct
-{
-  Idx node;
-  Idx str_idx; /* The position NODE match at.  */
-  state_array_t path;
-} re_sub_match_last_t;
-
-/* Store information about the node NODE whose type is OP_OPEN_SUBEXP.
-   And information about the node, whose type is OP_CLOSE_SUBEXP,
-   corresponding to NODE is stored in LASTS.  */
-
-typedef struct
-{
-  Idx str_idx;
-  Idx node;
-  state_array_t *path;
-  Idx alasts; /* Allocation size of LASTS.  */
-  Idx nlasts; /* The number of LASTS.  */
-  re_sub_match_last_t **lasts;
-} re_sub_match_top_t;
-
-struct re_backref_cache_entry
-{
-  Idx node;
-  Idx str_idx;
-  Idx subexp_from;
-  Idx subexp_to;
-  char more;
-  char unused;
-  unsigned short int eps_reachable_subexps_map;
-};
-
-typedef struct
-{
-  /* The string object corresponding to the input string.  */
-  re_string_t input;
-#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
-  const re_dfa_t *const dfa;
-#else
-  const re_dfa_t *dfa;
-#endif
-  /* EFLAGS of the argument of regexec.  */
-  int eflags;
-  /* Where the matching ends.  */
-  Idx match_last;
-  Idx last_node;
-  /* The state log used by the matcher.  */
-  re_dfastate_t **state_log;
-  Idx state_log_top;
-  /* Back reference cache.  */
-  Idx nbkref_ents;
-  Idx abkref_ents;
-  struct re_backref_cache_entry *bkref_ents;
-  int max_mb_elem_len;
-  Idx nsub_tops;
-  Idx asub_tops;
-  re_sub_match_top_t **sub_tops;
-} re_match_context_t;
-
-typedef struct
-{
-  re_dfastate_t **sifted_states;
-  re_dfastate_t **limited_states;
-  Idx last_node;
-  Idx last_str_idx;
-  re_node_set limits;
-} re_sift_context_t;
-
-struct re_fail_stack_ent_t
-{
-  Idx idx;
-  Idx node;
-  regmatch_t *regs;
-  re_node_set eps_via_nodes;
-};
-
-struct re_fail_stack_t
-{
-  Idx num;
-  Idx alloc;
-  struct re_fail_stack_ent_t *stack;
-};
-
-struct re_dfa_t
-{
-  re_token_t *nodes;
-  size_t nodes_alloc;
-  size_t nodes_len;
-  Idx *nexts;
-  Idx *org_indices;
-  re_node_set *edests;
-  re_node_set *eclosures;
-  re_node_set *inveclosures;
-  struct re_state_table_entry *state_table;
-  re_dfastate_t *init_state;
-  re_dfastate_t *init_state_word;
-  re_dfastate_t *init_state_nl;
-  re_dfastate_t *init_state_begbuf;
-  bin_tree_t *str_tree;
-  bin_tree_storage_t *str_tree_storage;
-  re_bitset_ptr_t sb_char;
-  int str_tree_storage_idx;
-
-  /* number of subexpressions `re_nsub' is in regex_t.  */
-  re_hashval_t state_hash_mask;
-  Idx init_node;
-  Idx nbackref; /* The number of backreference in this dfa.  */
-
-  /* Bitmap expressing which backreference is used.  */
-  bitset_word_t used_bkref_map;
-  bitset_word_t completed_bkref_map;
-
-  unsigned int has_plural_match : 1;
-  /* If this dfa has "multibyte node", which is a backreference or
-     a node which can accept multibyte character or multi character
-     collating element.  */
-  unsigned int has_mb_node : 1;
-  unsigned int is_utf8 : 1;
-  unsigned int map_notascii : 1;
-  unsigned int word_ops_used : 1;
-  int mb_cur_max;
-  bitset_t word_char;
-  reg_syntax_t syntax;
-  Idx *subexp_map;
-#ifdef DEBUG
-  char* re_str;
-#endif
-#ifdef _LIBC
-  __libc_lock_define (, lock)
-#endif
-};
-
-#define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
-#define re_node_set_remove(set,id) \
-  (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
-#define re_node_set_empty(p) ((p)->nelem = 0)
-#define re_node_set_free(set) re_free ((set)->elems)
-\f
-
-typedef enum
-{
-  SB_CHAR,
-  MB_CHAR,
-  EQUIV_CLASS,
-  COLL_SYM,
-  CHAR_CLASS
-} bracket_elem_type;
-
-typedef struct
-{
-  bracket_elem_type type;
-  union
-  {
-    unsigned char ch;
-    unsigned char *name;
-    wchar_t wch;
-  } opr;
-} bracket_elem_t;
-
-
-/* Inline functions for bitset_t operation.  */
-
-static inline void
-bitset_set (bitset_t set, Idx i)
-{
-  set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS;
-}
-
-static inline void
-bitset_clear (bitset_t set, Idx i)
-{
-  set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS);
-}
-
-static inline bool
-bitset_contain (const bitset_t set, Idx i)
-{
-  return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1;
-}
-
-static inline void
-bitset_empty (bitset_t set)
-{
-  memset (set, '\0', sizeof (bitset_t));
-}
-
-static inline void
-bitset_set_all (bitset_t set)
-{
-  memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS));
-  if (SBC_MAX % BITSET_WORD_BITS != 0)
-    set[BITSET_WORDS - 1] =
-      ((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1;
-}
-
-static inline void
-bitset_copy (bitset_t dest, const bitset_t src)
-{
-  memcpy (dest, src, sizeof (bitset_t));
-}
-
-static inline void
-bitset_not (bitset_t set)
-{
-  int bitset_i;
-  for (bitset_i = 0; bitset_i < SBC_MAX / BITSET_WORD_BITS; ++bitset_i)
-    set[bitset_i] = ~set[bitset_i];
-  if (SBC_MAX % BITSET_WORD_BITS != 0)
-    set[BITSET_WORDS - 1] =
-      ((((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1)
-       & ~set[BITSET_WORDS - 1]);
-}
-
-static inline void
-bitset_merge (bitset_t dest, const bitset_t src)
-{
-  int bitset_i;
-  for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)
-    dest[bitset_i] |= src[bitset_i];
-}
-
-static inline void
-bitset_mask (bitset_t dest, const bitset_t src)
-{
-  int bitset_i;
-  for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)
-    dest[bitset_i] &= src[bitset_i];
-}
-
-#ifdef RE_ENABLE_I18N
-/* Inline functions for re_string.  */
-static inline int
-internal_function __attribute ((pure))
-re_string_char_size_at (const re_string_t *pstr, Idx idx)
-{
-  int byte_idx;
-  if (pstr->mb_cur_max == 1)
-    return 1;
-  for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx)
-    if (pstr->wcs[idx + byte_idx] != WEOF)
-      break;
-  return byte_idx;
-}
-
-static inline wint_t
-internal_function __attribute ((pure))
-re_string_wchar_at (const re_string_t *pstr, Idx idx)
-{
-  if (pstr->mb_cur_max == 1)
-    return (wint_t) pstr->mbs[idx];
-  return (wint_t) pstr->wcs[idx];
-}
-
-static int
-internal_function __attribute ((pure))
-re_string_elem_size_at (const re_string_t *pstr, Idx idx)
-{
-# ifdef _LIBC
-  const unsigned char *p, *extra;
-  const int32_t *table, *indirect;
-  int32_t tmp;
-#  include <locale/weight.h>
-  uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-
-  if (nrules != 0)
-    {
-      table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
-      extra = (const unsigned char *)
-       _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
-      indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
-                                               _NL_COLLATE_INDIRECTMB);
-      p = pstr->mbs + idx;
-      tmp = findidx (&p);
-      return p - pstr->mbs - idx;
-    }
-  else
-# endif /* _LIBC */
-    return 1;
-}
-#endif /* RE_ENABLE_I18N */
-
-#ifndef __GNUC_PREREQ
-# if defined __GNUC__ && defined __GNUC_MINOR__
-#  define __GNUC_PREREQ(maj, min) \
-         ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
-# else
-#  define __GNUC_PREREQ(maj, min) 0
-# endif
-#endif
-
-#if __GNUC_PREREQ (3,4)
-# undef __attribute_warn_unused_result__
-# define __attribute_warn_unused_result__ \
-   __attribute__ ((__warn_unused_result__))
-#else
-# define __attribute_warn_unused_result__ /* empty */
-#endif
-
-#endif /*  _REGEX_INTERNAL_H */
diff --git a/gnulib/regexec.c b/gnulib/regexec.c
deleted file mode 100644 (file)
index 9388ac1..0000000
+++ /dev/null
@@ -1,4416 +0,0 @@
-/* Extended regular expression matching and search library.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
-   Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
-
-   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
-                                    Idx n) internal_function;
-static void match_ctx_clean (re_match_context_t *mctx) internal_function;
-static void match_ctx_free (re_match_context_t *cache) internal_function;
-static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, Idx node,
-                                         Idx str_idx, Idx from, Idx to)
-     internal_function;
-static Idx search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx)
-     internal_function;
-static reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, Idx node,
-                                          Idx str_idx) internal_function;
-static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop,
-                                                   Idx node, Idx str_idx)
-     internal_function;
-static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
-                          re_dfastate_t **limited_sts, Idx last_node,
-                          Idx last_str_idx)
-     internal_function;
-static reg_errcode_t re_search_internal (const regex_t *preg,
-                                        const char *string, Idx length,
-                                        Idx start, Idx last_start, Idx stop,
-                                        size_t nmatch, regmatch_t pmatch[],
-                                        int eflags) internal_function;
-static regoff_t re_search_2_stub (struct re_pattern_buffer *bufp,
-                                 const char *string1, Idx length1,
-                                 const char *string2, Idx length2,
-                                 Idx start, regoff_t range,
-                                 struct re_registers *regs,
-                                 Idx stop, bool ret_len) internal_function;
-static regoff_t re_search_stub (struct re_pattern_buffer *bufp,
-                               const char *string, Idx length, Idx start,
-                               regoff_t range, Idx stop,
-                               struct re_registers *regs,
-                               bool ret_len) internal_function;
-static unsigned int re_copy_regs (struct re_registers *regs, regmatch_t *pmatch,
-                                 Idx nregs, int regs_allocated)
-     internal_function;
-static reg_errcode_t prune_impossible_nodes (re_match_context_t *mctx)
-     internal_function;
-static Idx check_matching (re_match_context_t *mctx, bool fl_longest_match,
-                          Idx *p_match_first) internal_function;
-static Idx check_halt_state_context (const re_match_context_t *mctx,
-                                    const re_dfastate_t *state, Idx idx)
-     internal_function;
-static void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,
-                        regmatch_t *prev_idx_match, Idx cur_node,
-                        Idx cur_idx, Idx nmatch) internal_function;
-static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs,
-                                     Idx str_idx, Idx dest_node, Idx nregs,
-                                     regmatch_t *regs,
-                                     re_node_set *eps_via_nodes)
-     internal_function;
-static reg_errcode_t set_regs (const regex_t *preg,
-                              const re_match_context_t *mctx,
-                              size_t nmatch, regmatch_t *pmatch,
-                              bool fl_backtrack) internal_function;
-static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs)
-     internal_function;
-
-#ifdef RE_ENABLE_I18N
-static int sift_states_iter_mb (const re_match_context_t *mctx,
-                               re_sift_context_t *sctx,
-                               Idx node_idx, Idx str_idx, Idx max_str_idx)
-     internal_function;
-#endif /* RE_ENABLE_I18N */
-static reg_errcode_t sift_states_backward (const re_match_context_t *mctx,
-                                          re_sift_context_t *sctx)
-     internal_function;
-static reg_errcode_t build_sifted_states (const re_match_context_t *mctx,
-                                         re_sift_context_t *sctx, Idx str_idx,
-                                         re_node_set *cur_dest)
-     internal_function;
-static reg_errcode_t update_cur_sifted_state (const re_match_context_t *mctx,
-                                             re_sift_context_t *sctx,
-                                             Idx str_idx,
-                                             re_node_set *dest_nodes)
-     internal_function;
-static reg_errcode_t add_epsilon_src_nodes (const re_dfa_t *dfa,
-                                           re_node_set *dest_nodes,
-                                           const re_node_set *candidates)
-     internal_function;
-static bool check_dst_limits (const re_match_context_t *mctx,
-                             const re_node_set *limits,
-                             Idx dst_node, Idx dst_idx, Idx src_node,
-                             Idx src_idx) internal_function;
-static int check_dst_limits_calc_pos_1 (const re_match_context_t *mctx,
-                                       int boundaries, Idx subexp_idx,
-                                       Idx from_node, Idx bkref_idx)
-     internal_function;
-static int check_dst_limits_calc_pos (const re_match_context_t *mctx,
-                                     Idx limit, Idx subexp_idx,
-                                     Idx node, Idx str_idx,
-                                     Idx bkref_idx) internal_function;
-static reg_errcode_t check_subexp_limits (const re_dfa_t *dfa,
-                                         re_node_set *dest_nodes,
-                                         const re_node_set *candidates,
-                                         re_node_set *limits,
-                                         struct re_backref_cache_entry *bkref_ents,
-                                         Idx str_idx) internal_function;
-static reg_errcode_t sift_states_bkref (const re_match_context_t *mctx,
-                                       re_sift_context_t *sctx,
-                                       Idx str_idx, const re_node_set *candidates)
-     internal_function;
-static reg_errcode_t merge_state_array (const re_dfa_t *dfa,
-                                       re_dfastate_t **dst,
-                                       re_dfastate_t **src, Idx num)
-     internal_function;
-static re_dfastate_t *find_recover_state (reg_errcode_t *err,
-                                        re_match_context_t *mctx) internal_function;
-static re_dfastate_t *transit_state (reg_errcode_t *err,
-                                    re_match_context_t *mctx,
-                                    re_dfastate_t *state) internal_function;
-static re_dfastate_t *merge_state_with_log (reg_errcode_t *err,
-                                           re_match_context_t *mctx,
-                                           re_dfastate_t *next_state)
-     internal_function;
-static reg_errcode_t check_subexp_matching_top (re_match_context_t *mctx,
-                                               re_node_set *cur_nodes,
-                                               Idx str_idx) internal_function;
-#if 0
-static re_dfastate_t *transit_state_sb (reg_errcode_t *err,
-                                       re_match_context_t *mctx,
-                                       re_dfastate_t *pstate)
-     internal_function;
-#endif
-#ifdef RE_ENABLE_I18N
-static reg_errcode_t transit_state_mb (re_match_context_t *mctx,
-                                      re_dfastate_t *pstate)
-     internal_function;
-#endif /* RE_ENABLE_I18N */
-static reg_errcode_t transit_state_bkref (re_match_context_t *mctx,
-                                         const re_node_set *nodes)
-     internal_function;
-static reg_errcode_t get_subexp (re_match_context_t *mctx,
-                                Idx bkref_node, Idx bkref_str_idx)
-     internal_function;
-static reg_errcode_t get_subexp_sub (re_match_context_t *mctx,
-                                    const re_sub_match_top_t *sub_top,
-                                    re_sub_match_last_t *sub_last,
-                                    Idx bkref_node, Idx bkref_str)
-     internal_function;
-static Idx find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
-                            Idx subexp_idx, int type) internal_function;
-static reg_errcode_t check_arrival (re_match_context_t *mctx,
-                                   state_array_t *path, Idx top_node,
-                                   Idx top_str, Idx last_node, Idx last_str,
-                                   int type) internal_function;
-static reg_errcode_t check_arrival_add_next_nodes (re_match_context_t *mctx,
-                                                  Idx str_idx,
-                                                  re_node_set *cur_nodes,
-                                                  re_node_set *next_nodes)
-     internal_function;
-static reg_errcode_t check_arrival_expand_ecl (const re_dfa_t *dfa,
-                                              re_node_set *cur_nodes,
-                                              Idx ex_subexp, int type)
-     internal_function;
-static reg_errcode_t check_arrival_expand_ecl_sub (const re_dfa_t *dfa,
-                                                  re_node_set *dst_nodes,
-                                                  Idx target, Idx ex_subexp,
-                                                  int type) internal_function;
-static reg_errcode_t expand_bkref_cache (re_match_context_t *mctx,
-                                        re_node_set *cur_nodes, Idx cur_str,
-                                        Idx subexp_num, int type)
-     internal_function;
-static bool build_trtable (const re_dfa_t *dfa,
-                          re_dfastate_t *state) internal_function;
-#ifdef RE_ENABLE_I18N
-static int check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
-                                   const re_string_t *input, Idx idx)
-     internal_function;
-# ifdef _LIBC
-static unsigned int find_collation_sequence_value (const unsigned char *mbs,
-                                                  size_t name_len)
-     internal_function;
-# endif /* _LIBC */
-#endif /* RE_ENABLE_I18N */
-static Idx group_nodes_into_DFAstates (const re_dfa_t *dfa,
-                                      const re_dfastate_t *state,
-                                      re_node_set *states_node,
-                                      bitset_t *states_ch) internal_function;
-static bool check_node_accept (const re_match_context_t *mctx,
-                              const re_token_t *node, Idx idx)
-     internal_function;
-static reg_errcode_t extend_buffers (re_match_context_t *mctx)
-     internal_function;
-\f
-/* Entry point for POSIX code.  */
-
-/* regexec searches for a given pattern, specified by PREG, in the
-   string STRING.
-
-   If NMATCH is zero or REG_NOSUB was set in the cflags argument to
-   `regcomp', we ignore PMATCH.  Otherwise, we assume PMATCH has at
-   least NMATCH elements, and we set them to the offsets of the
-   corresponding matched substrings.
-
-   EFLAGS specifies `execution flags' which affect matching: if
-   REG_NOTBOL is set, then ^ does not match at the beginning of the
-   string; if REG_NOTEOL is set, then $ does not match at the end.
-
-   We return 0 if we find a match and REG_NOMATCH if not.  */
-
-int
-regexec (preg, string, nmatch, pmatch, eflags)
-    const regex_t *_Restrict_ preg;
-    const char *_Restrict_ string;
-    size_t nmatch;
-    regmatch_t pmatch[_Restrict_arr_];
-    int eflags;
-{
-  reg_errcode_t err;
-  Idx start, length;
-#ifdef _LIBC
-  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
-#endif
-
-  if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND))
-    return REG_BADPAT;
-
-  if (eflags & REG_STARTEND)
-    {
-      start = pmatch[0].rm_so;
-      length = pmatch[0].rm_eo;
-    }
-  else
-    {
-      start = 0;
-      length = strlen (string);
-    }
-
-  __libc_lock_lock (dfa->lock);
-  if (preg->no_sub)
-    err = re_search_internal (preg, string, length, start, length,
-                             length, 0, NULL, eflags);
-  else
-    err = re_search_internal (preg, string, length, start, length,
-                             length, nmatch, pmatch, eflags);
-  __libc_lock_unlock (dfa->lock);
-  return err != REG_NOERROR;
-}
-
-#ifdef _LIBC
-# include <shlib-compat.h>
-versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
-
-# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
-__typeof__ (__regexec) __compat_regexec;
-
-int
-attribute_compat_text_section
-__compat_regexec (const regex_t *_Restrict_ preg,
-                 const char *_Restrict_ string, size_t nmatch,
-                 regmatch_t pmatch[], int eflags)
-{
-  return regexec (preg, string, nmatch, pmatch,
-                 eflags & (REG_NOTBOL | REG_NOTEOL));
-}
-compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
-# endif
-#endif
-
-/* Entry points for GNU code.  */
-
-/* re_match, re_search, re_match_2, re_search_2
-
-   The former two functions operate on STRING with length LENGTH,
-   while the later two operate on concatenation of STRING1 and STRING2
-   with lengths LENGTH1 and LENGTH2, respectively.
-
-   re_match() matches the compiled pattern in BUFP against the string,
-   starting at index START.
-
-   re_search() first tries matching at index START, then it tries to match
-   starting from index START + 1, and so on.  The last start position tried
-   is START + RANGE.  (Thus RANGE = 0 forces re_search to operate the same
-   way as re_match().)
-
-   The parameter STOP of re_{match,search}_2 specifies that no match exceeding
-   the first STOP characters of the concatenation of the strings should be
-   concerned.
-
-   If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match
-   and all groups is stored in REGS.  (For the "_2" variants, the offsets are
-   computed relative to the concatenation, not relative to the individual
-   strings.)
-
-   On success, re_match* functions return the length of the match, re_search*
-   return the position of the start of the match.  Return value -1 means no
-   match was found and -2 indicates an internal error.  */
-
-regoff_t
-re_match (bufp, string, length, start, regs)
-    struct re_pattern_buffer *bufp;
-    const char *string;
-    Idx length, start;
-    struct re_registers *regs;
-{
-  return re_search_stub (bufp, string, length, start, 0, length, regs, true);
-}
-#ifdef _LIBC
-weak_alias (__re_match, re_match)
-#endif
-
-regoff_t
-re_search (bufp, string, length, start, range, regs)
-    struct re_pattern_buffer *bufp;
-    const char *string;
-    Idx length, start;
-    regoff_t range;
-    struct re_registers *regs;
-{
-  return re_search_stub (bufp, string, length, start, range, length, regs,
-                        false);
-}
-#ifdef _LIBC
-weak_alias (__re_search, re_search)
-#endif
-
-regoff_t
-re_match_2 (bufp, string1, length1, string2, length2, start, regs, stop)
-    struct re_pattern_buffer *bufp;
-    const char *string1, *string2;
-    Idx length1, length2, start, stop;
-    struct re_registers *regs;
-{
-  return re_search_2_stub (bufp, string1, length1, string2, length2,
-                          start, 0, regs, stop, true);
-}
-#ifdef _LIBC
-weak_alias (__re_match_2, re_match_2)
-#endif
-
-regoff_t
-re_search_2 (bufp, string1, length1, string2, length2, start, range, regs, stop)
-    struct re_pattern_buffer *bufp;
-    const char *string1, *string2;
-    Idx length1, length2, start, stop;
-    regoff_t range;
-    struct re_registers *regs;
-{
-  return re_search_2_stub (bufp, string1, length1, string2, length2,
-                          start, range, regs, stop, false);
-}
-#ifdef _LIBC
-weak_alias (__re_search_2, re_search_2)
-#endif
-
-static regoff_t
-internal_function
-re_search_2_stub (struct re_pattern_buffer *bufp,
-                 const char *string1, Idx length1,
-                 const char *string2, Idx length2,
-                 Idx start, regoff_t range, struct re_registers *regs,
-                 Idx stop, bool ret_len)
-{
-  const char *str;
-  regoff_t rval;
-  Idx len = length1 + length2;
-  char *s = NULL;
-
-  if (BE (length1 < 0 || length2 < 0 || stop < 0 || len < length1, 0))
-    return -2;
-
-  /* Concatenate the strings.  */
-  if (length2 > 0)
-    if (length1 > 0)
-      {
-       s = re_malloc (char, len);
-
-       if (BE (s == NULL, 0))
-         return -2;
-#ifdef _LIBC
-       memcpy (__mempcpy (s, string1, length1), string2, length2);
-#else
-       memcpy (s, string1, length1);
-       memcpy (s + length1, string2, length2);
-#endif
-       str = s;
-      }
-    else
-      str = string2;
-  else
-    str = string1;
-
-  rval = re_search_stub (bufp, str, len, start, range, stop, regs,
-                        ret_len);
-  re_free (s);
-  return rval;
-}
-
-/* The parameters have the same meaning as those of re_search.
-   Additional parameters:
-   If RET_LEN is true the length of the match is returned (re_match style);
-   otherwise the position of the match is returned.  */
-
-static regoff_t
-internal_function
-re_search_stub (struct re_pattern_buffer *bufp,
-               const char *string, Idx length,
-               Idx start, regoff_t range, Idx stop, struct re_registers *regs,
-               bool ret_len)
-{
-  reg_errcode_t result;
-  regmatch_t *pmatch;
-  Idx nregs;
-  regoff_t rval;
-  int eflags = 0;
-#ifdef _LIBC
-  re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
-#endif
-  Idx last_start = start + range;
-
-  /* Check for out-of-range.  */
-  if (BE (start < 0 || start > length, 0))
-    return -1;
-  if (BE (length < last_start || (0 <= range && last_start < start), 0))
-    last_start = length;
-  else if (BE (last_start < 0 || (range < 0 && start <= last_start), 0))
-    last_start = 0;
-
-  __libc_lock_lock (dfa->lock);
-
-  eflags |= (bufp->not_bol) ? REG_NOTBOL : 0;
-  eflags |= (bufp->not_eol) ? REG_NOTEOL : 0;
-
-  /* Compile fastmap if we haven't yet.  */
-  if (start < last_start && bufp->fastmap != NULL && !bufp->fastmap_accurate)
-    re_compile_fastmap (bufp);
-
-  if (BE (bufp->no_sub, 0))
-    regs = NULL;
-
-  /* We need at least 1 register.  */
-  if (regs == NULL)
-    nregs = 1;
-  else if (BE (bufp->regs_allocated == REGS_FIXED
-              && regs->num_regs <= bufp->re_nsub, 0))
-    {
-      nregs = regs->num_regs;
-      if (BE (nregs < 1, 0))
-       {
-         /* Nothing can be copied to regs.  */
-         regs = NULL;
-         nregs = 1;
-       }
-    }
-  else
-    nregs = bufp->re_nsub + 1;
-  pmatch = re_malloc (regmatch_t, nregs);
-  if (BE (pmatch == NULL, 0))
-    {
-      rval = -2;
-      goto out;
-    }
-
-  result = re_search_internal (bufp, string, length, start, last_start, stop,
-                              nregs, pmatch, eflags);
-
-  rval = 0;
-
-  /* I hope we needn't fill ther regs with -1's when no match was found.  */
-  if (result != REG_NOERROR)
-    rval = -1;
-  else if (regs != NULL)
-    {
-      /* If caller wants register contents data back, copy them.  */
-      bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs,
-                                          bufp->regs_allocated);
-      if (BE (bufp->regs_allocated == REGS_UNALLOCATED, 0))
-       rval = -2;
-    }
-
-  if (BE (rval == 0, 1))
-    {
-      if (ret_len)
-       {
-         assert (pmatch[0].rm_so == start);
-         rval = pmatch[0].rm_eo - start;
-       }
-      else
-       rval = pmatch[0].rm_so;
-    }
-  re_free (pmatch);
- out:
-  __libc_lock_unlock (dfa->lock);
-  return rval;
-}
-
-static unsigned int
-internal_function
-re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, Idx nregs,
-             int regs_allocated)
-{
-  int rval = REGS_REALLOCATE;
-  Idx i;
-  Idx need_regs = nregs + 1;
-  /* We need one extra element beyond `num_regs' for the `-1' marker GNU code
-     uses.  */
-
-  /* Have the register data arrays been allocated?  */
-  if (regs_allocated == REGS_UNALLOCATED)
-    { /* No.  So allocate them with malloc.  */
-      regs->start = re_malloc (regoff_t, need_regs);
-      if (BE (regs->start == NULL, 0))
-       return REGS_UNALLOCATED;
-      regs->end = re_malloc (regoff_t, need_regs);
-      if (BE (regs->end == NULL, 0))
-       {
-         re_free (regs->start);
-         return REGS_UNALLOCATED;
-       }
-      regs->num_regs = need_regs;
-    }
-  else if (regs_allocated == REGS_REALLOCATE)
-    { /* Yes.  If we need more elements than were already
-        allocated, reallocate them.  If we need fewer, just
-        leave it alone.  */
-      if (BE (need_regs > regs->num_regs, 0))
-       {
-         regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs);
-         regoff_t *new_end;
-         if (BE (new_start == NULL, 0))
-           return REGS_UNALLOCATED;
-         new_end = re_realloc (regs->end, regoff_t, need_regs);
-         if (BE (new_end == NULL, 0))
-           {
-             re_free (new_start);
-             return REGS_UNALLOCATED;
-           }
-         regs->start = new_start;
-         regs->end = new_end;
-         regs->num_regs = need_regs;
-       }
-    }
-  else
-    {
-      assert (regs_allocated == REGS_FIXED);
-      /* This function may not be called with REGS_FIXED and nregs too big.  */
-      assert (regs->num_regs >= nregs);
-      rval = REGS_FIXED;
-    }
-
-  /* Copy the regs.  */
-  for (i = 0; i < nregs; ++i)
-    {
-      regs->start[i] = pmatch[i].rm_so;
-      regs->end[i] = pmatch[i].rm_eo;
-    }
-  for ( ; i < regs->num_regs; ++i)
-    regs->start[i] = regs->end[i] = -1;
-
-  return rval;
-}
-
-/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
-   ENDS.  Subsequent matches using PATTERN_BUFFER and REGS will use
-   this memory for recording register information.  STARTS and ENDS
-   must be allocated using the malloc library routine, and must each
-   be at least NUM_REGS * sizeof (regoff_t) bytes long.
-
-   If NUM_REGS == 0, then subsequent matches should allocate their own
-   register data.
-
-   Unless this function is called, the first search or match using
-   PATTERN_BUFFER will allocate its own register data, without
-   freeing the old data.  */
-
-void
-re_set_registers (bufp, regs, num_regs, starts, ends)
-    struct re_pattern_buffer *bufp;
-    struct re_registers *regs;
-    __re_size_t num_regs;
-    regoff_t *starts, *ends;
-{
-  if (num_regs)
-    {
-      bufp->regs_allocated = REGS_REALLOCATE;
-      regs->num_regs = num_regs;
-      regs->start = starts;
-      regs->end = ends;
-    }
-  else
-    {
-      bufp->regs_allocated = REGS_UNALLOCATED;
-      regs->num_regs = 0;
-      regs->start = regs->end = NULL;
-    }
-}
-#ifdef _LIBC
-weak_alias (__re_set_registers, re_set_registers)
-#endif
-\f
-/* Entry points compatible with 4.2 BSD regex library.  We don't define
-   them unless specifically requested.  */
-
-#if defined _REGEX_RE_COMP || defined _LIBC
-int
-# ifdef _LIBC
-weak_function
-# endif
-re_exec (s)
-     const char *s;
-{
-  return 0 == regexec (&re_comp_buf, s, 0, NULL, 0);
-}
-#endif /* _REGEX_RE_COMP */
-\f
-/* Internal entry point.  */
-
-/* Searches for a compiled pattern PREG in the string STRING, whose
-   length is LENGTH.  NMATCH, PMATCH, and EFLAGS have the same
-   meaning as with regexec.  LAST_START is START + RANGE, where
-   START and RANGE have the same meaning as with re_search.
-   Return REG_NOERROR if we find a match, and REG_NOMATCH if not,
-   otherwise return the error code.
-   Note: We assume front end functions already check ranges.
-   (0 <= LAST_START && LAST_START <= LENGTH)  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-re_search_internal (const regex_t *preg,
-                   const char *string, Idx length,
-                   Idx start, Idx last_start, Idx stop,
-                   size_t nmatch, regmatch_t pmatch[],
-                   int eflags)
-{
-  reg_errcode_t err;
-  const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer;
-  Idx left_lim, right_lim;
-  int incr;
-  bool fl_longest_match;
-  int match_kind;
-  Idx match_first;
-  Idx match_last = REG_MISSING;
-  Idx extra_nmatch;
-  bool sb;
-  int ch;
-#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
-  re_match_context_t mctx = { .dfa = dfa };
-#else
-  re_match_context_t mctx;
-#endif
-  char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate
-                   && start != last_start && !preg->can_be_null)
-                  ? preg->fastmap : NULL);
-  RE_TRANSLATE_TYPE t = preg->translate;
-
-#if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
-  memset (&mctx, '\0', sizeof (re_match_context_t));
-  mctx.dfa = dfa;
-#endif
-
-  extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0;
-  nmatch -= extra_nmatch;
-
-  /* Check if the DFA haven't been compiled.  */
-  if (BE (preg->used == 0 || dfa->init_state == NULL
-         || dfa->init_state_word == NULL || dfa->init_state_nl == NULL
-         || dfa->init_state_begbuf == NULL, 0))
-    return REG_NOMATCH;
-
-#ifdef DEBUG
-  /* We assume front-end functions already check them.  */
-  assert (0 <= last_start && last_start <= length);
-#endif
-
-  /* If initial states with non-begbuf contexts have no elements,
-     the regex must be anchored.  If preg->newline_anchor is set,
-     we'll never use init_state_nl, so do not check it.  */
-  if (dfa->init_state->nodes.nelem == 0
-      && dfa->init_state_word->nodes.nelem == 0
-      && (dfa->init_state_nl->nodes.nelem == 0
-         || !preg->newline_anchor))
-    {
-      if (start != 0 && last_start != 0)
-        return REG_NOMATCH;
-      start = last_start = 0;
-    }
-
-  /* We must check the longest matching, if nmatch > 0.  */
-  fl_longest_match = (nmatch != 0 || dfa->nbackref);
-
-  err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1,
-                           preg->translate, (preg->syntax & RE_ICASE) != 0,
-                           dfa);
-  if (BE (err != REG_NOERROR, 0))
-    goto free_return;
-  mctx.input.stop = stop;
-  mctx.input.raw_stop = stop;
-  mctx.input.newline_anchor = preg->newline_anchor;
-
-  err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2);
-  if (BE (err != REG_NOERROR, 0))
-    goto free_return;
-
-  /* We will log all the DFA states through which the dfa pass,
-     if nmatch > 1, or this dfa has "multibyte node", which is a
-     back-reference or a node which can accept multibyte character or
-     multi character collating element.  */
-  if (nmatch > 1 || dfa->has_mb_node)
-    {
-      /* Avoid overflow.  */
-      if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= mctx.input.bufs_len, 0))
-       {
-         err = REG_ESPACE;
-         goto free_return;
-       }
-
-      mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1);
-      if (BE (mctx.state_log == NULL, 0))
-       {
-         err = REG_ESPACE;
-         goto free_return;
-       }
-    }
-  else
-    mctx.state_log = NULL;
-
-  match_first = start;
-  mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
-                          : CONTEXT_NEWLINE | CONTEXT_BEGBUF;
-
-  /* Check incrementally whether of not the input string match.  */
-  incr = (last_start < start) ? -1 : 1;
-  left_lim = (last_start < start) ? last_start : start;
-  right_lim = (last_start < start) ? start : last_start;
-  sb = dfa->mb_cur_max == 1;
-  match_kind =
-    (fastmap
-     ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)
-       | (start <= last_start ? 2 : 0)
-       | (t != NULL ? 1 : 0))
-     : 8);
-
-  for (;; match_first += incr)
-    {
-      err = REG_NOMATCH;
-      if (match_first < left_lim || right_lim < match_first)
-       goto free_return;
-
-      /* Advance as rapidly as possible through the string, until we
-        find a plausible place to start matching.  This may be done
-        with varying efficiency, so there are various possibilities:
-        only the most common of them are specialized, in order to
-        save on code size.  We use a switch statement for speed.  */
-      switch (match_kind)
-       {
-       case 8:
-         /* No fastmap.  */
-         break;
-
-       case 7:
-         /* Fastmap with single-byte translation, match forward.  */
-         while (BE (match_first < right_lim, 1)
-                && !fastmap[t[(unsigned char) string[match_first]]])
-           ++match_first;
-         goto forward_match_found_start_or_reached_end;
-
-       case 6:
-         /* Fastmap without translation, match forward.  */
-         while (BE (match_first < right_lim, 1)
-                && !fastmap[(unsigned char) string[match_first]])
-           ++match_first;
-
-       forward_match_found_start_or_reached_end:
-         if (BE (match_first == right_lim, 0))
-           {
-             ch = match_first >= length
-                      ? 0 : (unsigned char) string[match_first];
-             if (!fastmap[t ? t[ch] : ch])
-               goto free_return;
-           }
-         break;
-
-       case 4:
-       case 5:
-         /* Fastmap without multi-byte translation, match backwards.  */
-         while (match_first >= left_lim)
-           {
-             ch = match_first >= length
-                      ? 0 : (unsigned char) string[match_first];
-             if (fastmap[t ? t[ch] : ch])
-               break;
-             --match_first;
-           }
-         if (match_first < left_lim)
-           goto free_return;
-         break;
-
-       default:
-         /* In this case, we can't determine easily the current byte,
-            since it might be a component byte of a multibyte
-            character.  Then we use the constructed buffer instead.  */
-         for (;;)
-           {
-             /* If MATCH_FIRST is out of the valid range, reconstruct the
-                buffers.  */
-             __re_size_t offset = match_first - mctx.input.raw_mbs_idx;
-             if (BE (offset >= (__re_size_t) mctx.input.valid_raw_len, 0))
-               {
-                 err = re_string_reconstruct (&mctx.input, match_first,
-                                              eflags);
-                 if (BE (err != REG_NOERROR, 0))
-                   goto free_return;
-
-                 offset = match_first - mctx.input.raw_mbs_idx;
-               }
-             /* If MATCH_FIRST is out of the buffer, leave it as '\0'.
-                Note that MATCH_FIRST must not be smaller than 0.  */
-             ch = (match_first >= length
-                   ? 0 : re_string_byte_at (&mctx.input, offset));
-             if (fastmap[ch])
-               break;
-             match_first += incr;
-             if (match_first < left_lim || match_first > right_lim)
-               {
-                 err = REG_NOMATCH;
-                 goto free_return;
-               }
-           }
-         break;
-       }
-
-      /* Reconstruct the buffers so that the matcher can assume that
-        the matching starts from the beginning of the buffer.  */
-      err = re_string_reconstruct (&mctx.input, match_first, eflags);
-      if (BE (err != REG_NOERROR, 0))
-       goto free_return;
-
-#ifdef RE_ENABLE_I18N
-     /* Don't consider this char as a possible match start if it part,
-       yet isn't the head, of a multibyte character.  */
-      if (!sb && !re_string_first_byte (&mctx.input, 0))
-       continue;
-#endif
-
-      /* It seems to be appropriate one, then use the matcher.  */
-      /* We assume that the matching starts from 0.  */
-      mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;
-      match_last = check_matching (&mctx, fl_longest_match,
-                                  start <= last_start ? &match_first : NULL);
-      if (match_last != REG_MISSING)
-       {
-         if (BE (match_last == REG_ERROR, 0))
-           {
-             err = REG_ESPACE;
-             goto free_return;
-           }
-         else
-           {
-             mctx.match_last = match_last;
-             if ((!preg->no_sub && nmatch > 1) || dfa->nbackref)
-               {
-                 re_dfastate_t *pstate = mctx.state_log[match_last];
-                 mctx.last_node = check_halt_state_context (&mctx, pstate,
-                                                            match_last);
-               }
-             if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match)
-                 || dfa->nbackref)
-               {
-                 err = prune_impossible_nodes (&mctx);
-                 if (err == REG_NOERROR)
-                   break;
-                 if (BE (err != REG_NOMATCH, 0))
-                   goto free_return;
-                 match_last = REG_MISSING;
-               }
-             else
-               break; /* We found a match.  */
-           }
-       }
-
-      match_ctx_clean (&mctx);
-    }
-
-#ifdef DEBUG
-  assert (match_last != REG_MISSING);
-  assert (err == REG_NOERROR);
-#endif
-
-  /* Set pmatch[] if we need.  */
-  if (nmatch > 0)
-    {
-      Idx reg_idx;
-
-      /* Initialize registers.  */
-      for (reg_idx = 1; reg_idx < nmatch; ++reg_idx)
-       pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1;
-
-      /* Set the points where matching start/end.  */
-      pmatch[0].rm_so = 0;
-      pmatch[0].rm_eo = mctx.match_last;
-      /* FIXME: This function should fail if mctx.match_last exceeds
-        the maximum possible regoff_t value.  We need a new error
-        code REG_OVERFLOW.  */
-
-      if (!preg->no_sub && nmatch > 1)
-       {
-         err = set_regs (preg, &mctx, nmatch, pmatch,
-                         dfa->has_plural_match && dfa->nbackref > 0);
-         if (BE (err != REG_NOERROR, 0))
-           goto free_return;
-       }
-
-      /* At last, add the offset to the each registers, since we slided
-        the buffers so that we could assume that the matching starts
-        from 0.  */
-      for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
-       if (pmatch[reg_idx].rm_so != -1)
-         {
-#ifdef RE_ENABLE_I18N
-           if (BE (mctx.input.offsets_needed != 0, 0))
-             {
-               pmatch[reg_idx].rm_so =
-                 (pmatch[reg_idx].rm_so == mctx.input.valid_len
-                  ? mctx.input.valid_raw_len
-                  : mctx.input.offsets[pmatch[reg_idx].rm_so]);
-               pmatch[reg_idx].rm_eo =
-                 (pmatch[reg_idx].rm_eo == mctx.input.valid_len
-                  ? mctx.input.valid_raw_len
-                  : mctx.input.offsets[pmatch[reg_idx].rm_eo]);
-             }
-#else
-           assert (mctx.input.offsets_needed == 0);
-#endif
-           pmatch[reg_idx].rm_so += match_first;
-           pmatch[reg_idx].rm_eo += match_first;
-         }
-      for (reg_idx = 0; reg_idx < extra_nmatch; ++reg_idx)
-       {
-         pmatch[nmatch + reg_idx].rm_so = -1;
-         pmatch[nmatch + reg_idx].rm_eo = -1;
-       }
-
-      if (dfa->subexp_map)
-       for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++)
-         if (dfa->subexp_map[reg_idx] != reg_idx)
-           {
-             pmatch[reg_idx + 1].rm_so
-               = pmatch[dfa->subexp_map[reg_idx] + 1].rm_so;
-             pmatch[reg_idx + 1].rm_eo
-               = pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo;
-           }
-    }
-
- free_return:
-  re_free (mctx.state_log);
-  if (dfa->nbackref)
-    match_ctx_free (&mctx);
-  re_string_destruct (&mctx.input);
-  return err;
-}
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-prune_impossible_nodes (re_match_context_t *mctx)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  Idx halt_node, match_last;
-  reg_errcode_t ret;
-  re_dfastate_t **sifted_states;
-  re_dfastate_t **lim_states = NULL;
-  re_sift_context_t sctx;
-#ifdef DEBUG
-  assert (mctx->state_log != NULL);
-#endif
-  match_last = mctx->match_last;
-  halt_node = mctx->last_node;
-
-  /* Avoid overflow.  */
-  if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= match_last, 0))
-    return REG_ESPACE;
-
-  sifted_states = re_malloc (re_dfastate_t *, match_last + 1);
-  if (BE (sifted_states == NULL, 0))
-    {
-      ret = REG_ESPACE;
-      goto free_return;
-    }
-  if (dfa->nbackref)
-    {
-      lim_states = re_malloc (re_dfastate_t *, match_last + 1);
-      if (BE (lim_states == NULL, 0))
-       {
-         ret = REG_ESPACE;
-         goto free_return;
-       }
-      while (1)
-       {
-         memset (lim_states, '\0',
-                 sizeof (re_dfastate_t *) * (match_last + 1));
-         sift_ctx_init (&sctx, sifted_states, lim_states, halt_node,
-                        match_last);
-         ret = sift_states_backward (mctx, &sctx);
-         re_node_set_free (&sctx.limits);
-         if (BE (ret != REG_NOERROR, 0))
-             goto free_return;
-         if (sifted_states[0] != NULL || lim_states[0] != NULL)
-           break;
-         do
-           {
-             --match_last;
-             if (! REG_VALID_INDEX (match_last))
-               {
-                 ret = REG_NOMATCH;
-                 goto free_return;
-               }
-           } while (mctx->state_log[match_last] == NULL
-                    || !mctx->state_log[match_last]->halt);
-         halt_node = check_halt_state_context (mctx,
-                                               mctx->state_log[match_last],
-                                               match_last);
-       }
-      ret = merge_state_array (dfa, sifted_states, lim_states,
-                              match_last + 1);
-      re_free (lim_states);
-      lim_states = NULL;
-      if (BE (ret != REG_NOERROR, 0))
-       goto free_return;
-    }
-  else
-    {
-      sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, match_last);
-      ret = sift_states_backward (mctx, &sctx);
-      re_node_set_free (&sctx.limits);
-      if (BE (ret != REG_NOERROR, 0))
-       goto free_return;
-      if (sifted_states[0] == NULL)
-       {
-         ret = REG_NOMATCH;
-         goto free_return;
-       }
-    }
-  re_free (mctx->state_log);
-  mctx->state_log = sifted_states;
-  sifted_states = NULL;
-  mctx->last_node = halt_node;
-  mctx->match_last = match_last;
-  ret = REG_NOERROR;
- free_return:
-  re_free (sifted_states);
-  re_free (lim_states);
-  return ret;
-}
-
-/* Acquire an initial state and return it.
-   We must select appropriate initial state depending on the context,
-   since initial states may have constraints like "\<", "^", etc..  */
-
-static inline re_dfastate_t *
-__attribute ((always_inline)) internal_function
-acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx,
-                           Idx idx)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  if (dfa->init_state->has_constraint)
-    {
-      unsigned int context;
-      context = re_string_context_at (&mctx->input, idx - 1, mctx->eflags);
-      if (IS_WORD_CONTEXT (context))
-       return dfa->init_state_word;
-      else if (IS_ORDINARY_CONTEXT (context))
-       return dfa->init_state;
-      else if (IS_BEGBUF_CONTEXT (context) && IS_NEWLINE_CONTEXT (context))
-       return dfa->init_state_begbuf;
-      else if (IS_NEWLINE_CONTEXT (context))
-       return dfa->init_state_nl;
-      else if (IS_BEGBUF_CONTEXT (context))
-       {
-         /* It is relatively rare case, then calculate on demand.  */
-         return re_acquire_state_context (err, dfa,
-                                          dfa->init_state->entrance_nodes,
-                                          context);
-       }
-      else
-       /* Must not happen?  */
-       return dfa->init_state;
-    }
-  else
-    return dfa->init_state;
-}
-
-/* Check whether the regular expression match input string INPUT or not,
-   and return the index where the matching end.  Return REG_MISSING if
-   there is no match, and return REG_ERROR in case of an error.
-   FL_LONGEST_MATCH means we want the POSIX longest matching.
-   If P_MATCH_FIRST is not NULL, and the match fails, it is set to the
-   next place where we may want to try matching.
-   Note that the matcher assume that the maching starts from the current
-   index of the buffer.  */
-
-static Idx
-internal_function __attribute_warn_unused_result__
-check_matching (re_match_context_t *mctx, bool fl_longest_match,
-               Idx *p_match_first)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  reg_errcode_t err;
-  Idx match = 0;
-  Idx match_last = REG_MISSING;
-  Idx cur_str_idx = re_string_cur_idx (&mctx->input);
-  re_dfastate_t *cur_state;
-  bool at_init_state = p_match_first != NULL;
-  Idx next_start_idx = cur_str_idx;
-
-  err = REG_NOERROR;
-  cur_state = acquire_init_state_context (&err, mctx, cur_str_idx);
-  /* An initial state must not be NULL (invalid).  */
-  if (BE (cur_state == NULL, 0))
-    {
-      assert (err == REG_ESPACE);
-      return REG_ERROR;
-    }
-
-  if (mctx->state_log != NULL)
-    {
-      mctx->state_log[cur_str_idx] = cur_state;
-
-      /* Check OP_OPEN_SUBEXP in the initial state in case that we use them
-        later.  E.g. Processing back references.  */
-      if (BE (dfa->nbackref, 0))
-       {
-         at_init_state = false;
-         err = check_subexp_matching_top (mctx, &cur_state->nodes, 0);
-         if (BE (err != REG_NOERROR, 0))
-           return err;
-
-         if (cur_state->has_backref)
-           {
-             err = transit_state_bkref (mctx, &cur_state->nodes);
-             if (BE (err != REG_NOERROR, 0))
-               return err;
-           }
-       }
-    }
-
-  /* If the RE accepts NULL string.  */
-  if (BE (cur_state->halt, 0))
-    {
-      if (!cur_state->has_constraint
-         || check_halt_state_context (mctx, cur_state, cur_str_idx))
-       {
-         if (!fl_longest_match)
-           return cur_str_idx;
-         else
-           {
-             match_last = cur_str_idx;
-             match = 1;
-           }
-       }
-    }
-
-  while (!re_string_eoi (&mctx->input))
-    {
-      re_dfastate_t *old_state = cur_state;
-      Idx next_char_idx = re_string_cur_idx (&mctx->input) + 1;
-
-      if (BE (next_char_idx >= mctx->input.bufs_len, 0)
-         || (BE (next_char_idx >= mctx->input.valid_len, 0)
-             && mctx->input.valid_len < mctx->input.len))
-       {
-         err = extend_buffers (mctx);
-         if (BE (err != REG_NOERROR, 0))
-           {
-             assert (err == REG_ESPACE);
-             return REG_ERROR;
-           }
-       }
-
-      cur_state = transit_state (&err, mctx, cur_state);
-      if (mctx->state_log != NULL)
-       cur_state = merge_state_with_log (&err, mctx, cur_state);
-
-      if (cur_state == NULL)
-       {
-         /* Reached the invalid state or an error.  Try to recover a valid
-            state using the state log, if available and if we have not
-            already found a valid (even if not the longest) match.  */
-         if (BE (err != REG_NOERROR, 0))
-           return REG_ERROR;
-
-         if (mctx->state_log == NULL
-             || (match && !fl_longest_match)
-             || (cur_state = find_recover_state (&err, mctx)) == NULL)
-           break;
-       }
-
-      if (BE (at_init_state, 0))
-       {
-         if (old_state == cur_state)
-           next_start_idx = next_char_idx;
-         else
-           at_init_state = false;
-       }
-
-      if (cur_state->halt)
-       {
-         /* Reached a halt state.
-            Check the halt state can satisfy the current context.  */
-         if (!cur_state->has_constraint
-             || check_halt_state_context (mctx, cur_state,
-                                          re_string_cur_idx (&mctx->input)))
-           {
-             /* We found an appropriate halt state.  */
-             match_last = re_string_cur_idx (&mctx->input);
-             match = 1;
-
-             /* We found a match, do not modify match_first below.  */
-             p_match_first = NULL;
-             if (!fl_longest_match)
-               break;
-           }
-       }
-    }
-
-  if (p_match_first)
-    *p_match_first += next_start_idx;
-
-  return match_last;
-}
-
-/* Check NODE match the current context.  */
-
-static bool
-internal_function
-check_halt_node_context (const re_dfa_t *dfa, Idx node, unsigned int context)
-{
-  re_token_type_t type = dfa->nodes[node].type;
-  unsigned int constraint = dfa->nodes[node].constraint;
-  if (type != END_OF_RE)
-    return false;
-  if (!constraint)
-    return true;
-  if (NOT_SATISFY_NEXT_CONSTRAINT (constraint, context))
-    return false;
-  return true;
-}
-
-/* Check the halt state STATE match the current context.
-   Return 0 if not match, if the node, STATE has, is a halt node and
-   match the context, return the node.  */
-
-static Idx
-internal_function
-check_halt_state_context (const re_match_context_t *mctx,
-                         const re_dfastate_t *state, Idx idx)
-{
-  Idx i;
-  unsigned int context;
-#ifdef DEBUG
-  assert (state->halt);
-#endif
-  context = re_string_context_at (&mctx->input, idx, mctx->eflags);
-  for (i = 0; i < state->nodes.nelem; ++i)
-    if (check_halt_node_context (mctx->dfa, state->nodes.elems[i], context))
-      return state->nodes.elems[i];
-  return 0;
-}
-
-/* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA
-   corresponding to the DFA).
-   Return the destination node, and update EPS_VIA_NODES;
-   return REG_MISSING in case of errors.  */
-
-static Idx
-internal_function
-proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
-                  Idx *pidx, Idx node, re_node_set *eps_via_nodes,
-                  struct re_fail_stack_t *fs)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  Idx i;
-  bool ok;
-  if (IS_EPSILON_NODE (dfa->nodes[node].type))
-    {
-      re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes;
-      re_node_set *edests = &dfa->edests[node];
-      Idx dest_node;
-      ok = re_node_set_insert (eps_via_nodes, node);
-      if (BE (! ok, 0))
-       return REG_ERROR;
-      /* Pick up a valid destination, or return REG_MISSING if none
-        is found.  */
-      for (dest_node = REG_MISSING, i = 0; i < edests->nelem; ++i)
-       {
-         Idx candidate = edests->elems[i];
-         if (!re_node_set_contains (cur_nodes, candidate))
-           continue;
-          if (dest_node == REG_MISSING)
-           dest_node = candidate;
-
-         else
-           {
-             /* In order to avoid infinite loop like "(a*)*", return the second
-                epsilon-transition if the first was already considered.  */
-             if (re_node_set_contains (eps_via_nodes, dest_node))
-               return candidate;
-
-             /* Otherwise, push the second epsilon-transition on the fail stack.  */
-             else if (fs != NULL
-                      && push_fail_stack (fs, *pidx, candidate, nregs, regs,
-                                          eps_via_nodes))
-               return REG_ERROR;
-
-             /* We know we are going to exit.  */
-             break;
-           }
-       }
-      return dest_node;
-    }
-  else
-    {
-      Idx naccepted = 0;
-      re_token_type_t type = dfa->nodes[node].type;
-
-#ifdef RE_ENABLE_I18N
-      if (dfa->nodes[node].accept_mb)
-       naccepted = check_node_accept_bytes (dfa, node, &mctx->input, *pidx);
-      else
-#endif /* RE_ENABLE_I18N */
-      if (type == OP_BACK_REF)
-       {
-         Idx subexp_idx = dfa->nodes[node].opr.idx + 1;
-         naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so;
-         if (fs != NULL)
-           {
-             if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1)
-               return REG_MISSING;
-             else if (naccepted)
-               {
-                 char *buf = (char *) re_string_get_buffer (&mctx->input);
-                 if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx,
-                             naccepted) != 0)
-                   return REG_MISSING;
-               }
-           }
-
-         if (naccepted == 0)
-           {
-             Idx dest_node;
-             ok = re_node_set_insert (eps_via_nodes, node);
-             if (BE (! ok, 0))
-               return REG_ERROR;
-             dest_node = dfa->edests[node].elems[0];
-             if (re_node_set_contains (&mctx->state_log[*pidx]->nodes,
-                                       dest_node))
-               return dest_node;
-           }
-       }
-
-      if (naccepted != 0
-         || check_node_accept (mctx, dfa->nodes + node, *pidx))
-       {
-         Idx dest_node = dfa->nexts[node];
-         *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted;
-         if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL
-                    || !re_node_set_contains (&mctx->state_log[*pidx]->nodes,
-                                              dest_node)))
-           return REG_MISSING;
-         re_node_set_empty (eps_via_nodes);
-         return dest_node;
-       }
-    }
-  return REG_MISSING;
-}
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node,
-                Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes)
-{
-  reg_errcode_t err;
-  Idx num = fs->num++;
-  if (fs->num == fs->alloc)
-    {
-      struct re_fail_stack_ent_t *new_array;
-      new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t)
-                                      * fs->alloc * 2));
-      if (new_array == NULL)
-       return REG_ESPACE;
-      fs->alloc *= 2;
-      fs->stack = new_array;
-    }
-  fs->stack[num].idx = str_idx;
-  fs->stack[num].node = dest_node;
-  fs->stack[num].regs = re_malloc (regmatch_t, nregs);
-  if (fs->stack[num].regs == NULL)
-    return REG_ESPACE;
-  memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);
-  err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes);
-  return err;
-}
-
-static Idx
-internal_function
-pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs,
-               regmatch_t *regs, re_node_set *eps_via_nodes)
-{
-  Idx num = --fs->num;
-  assert (REG_VALID_INDEX (num));
-  *pidx = fs->stack[num].idx;
-  memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);
-  re_node_set_free (eps_via_nodes);
-  re_free (fs->stack[num].regs);
-  *eps_via_nodes = fs->stack[num].eps_via_nodes;
-  return fs->stack[num].node;
-}
-
-/* Set the positions where the subexpressions are starts/ends to registers
-   PMATCH.
-   Note: We assume that pmatch[0] is already set, and
-   pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
-         regmatch_t *pmatch, bool fl_backtrack)
-{
-  const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer;
-  Idx idx, cur_node;
-  re_node_set eps_via_nodes;
-  struct re_fail_stack_t *fs;
-  struct re_fail_stack_t fs_body = { 0, 2, NULL };
-  regmatch_t *prev_idx_match;
-  bool prev_idx_match_malloced = false;
-
-#ifdef DEBUG
-  assert (nmatch > 1);
-  assert (mctx->state_log != NULL);
-#endif
-  if (fl_backtrack)
-    {
-      fs = &fs_body;
-      fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc);
-      if (fs->stack == NULL)
-       return REG_ESPACE;
-    }
-  else
-    fs = NULL;
-
-  cur_node = dfa->init_node;
-  re_node_set_init_empty (&eps_via_nodes);
-
-  if (__libc_use_alloca (nmatch * sizeof (regmatch_t)))
-    prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t));
-  else
-    {
-      prev_idx_match = re_malloc (regmatch_t, nmatch);
-      if (prev_idx_match == NULL)
-       {
-         free_fail_stack_return (fs);
-         return REG_ESPACE;
-       }
-      prev_idx_match_malloced = true;
-    }
-  memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
-
-  for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;)
-    {
-      update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch);
-
-      if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
-       {
-         Idx reg_idx;
-         if (fs)
-           {
-             for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
-               if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1)
-                 break;
-             if (reg_idx == nmatch)
-               {
-                 re_node_set_free (&eps_via_nodes);
-                 if (prev_idx_match_malloced)
-                   re_free (prev_idx_match);
-                 return free_fail_stack_return (fs);
-               }
-             cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
-                                        &eps_via_nodes);
-           }
-         else
-           {
-             re_node_set_free (&eps_via_nodes);
-             if (prev_idx_match_malloced)
-               re_free (prev_idx_match);
-             return REG_NOERROR;
-           }
-       }
-
-      /* Proceed to next node.  */
-      cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node,
-                                   &eps_via_nodes, fs);
-
-      if (BE (! REG_VALID_INDEX (cur_node), 0))
-       {
-         if (BE (cur_node == REG_ERROR, 0))
-           {
-             re_node_set_free (&eps_via_nodes);
-             if (prev_idx_match_malloced)
-               re_free (prev_idx_match);
-             free_fail_stack_return (fs);
-             return REG_ESPACE;
-           }
-         if (fs)
-           cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
-                                      &eps_via_nodes);
-         else
-           {
-             re_node_set_free (&eps_via_nodes);
-             if (prev_idx_match_malloced)
-               re_free (prev_idx_match);
-             return REG_NOMATCH;
-           }
-       }
-    }
-  re_node_set_free (&eps_via_nodes);
-  if (prev_idx_match_malloced)
-    re_free (prev_idx_match);
-  return free_fail_stack_return (fs);
-}
-
-static reg_errcode_t
-internal_function
-free_fail_stack_return (struct re_fail_stack_t *fs)
-{
-  if (fs)
-    {
-      Idx fs_idx;
-      for (fs_idx = 0; fs_idx < fs->num; ++fs_idx)
-       {
-         re_node_set_free (&fs->stack[fs_idx].eps_via_nodes);
-         re_free (fs->stack[fs_idx].regs);
-       }
-      re_free (fs->stack);
-    }
-  return REG_NOERROR;
-}
-
-static void
-internal_function
-update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,
-            regmatch_t *prev_idx_match, Idx cur_node, Idx cur_idx, Idx nmatch)
-{
-  int type = dfa->nodes[cur_node].type;
-  if (type == OP_OPEN_SUBEXP)
-    {
-      Idx reg_num = dfa->nodes[cur_node].opr.idx + 1;
-
-      /* We are at the first node of this sub expression.  */
-      if (reg_num < nmatch)
-       {
-         pmatch[reg_num].rm_so = cur_idx;
-         pmatch[reg_num].rm_eo = -1;
-       }
-    }
-  else if (type == OP_CLOSE_SUBEXP)
-    {
-      Idx reg_num = dfa->nodes[cur_node].opr.idx + 1;
-      if (reg_num < nmatch)
-       {
-         /* We are at the last node of this sub expression.  */
-         if (pmatch[reg_num].rm_so < cur_idx)
-           {
-             pmatch[reg_num].rm_eo = cur_idx;
-             /* This is a non-empty match or we are not inside an optional
-                subexpression.  Accept this right away.  */
-             memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
-           }
-         else
-           {
-             if (dfa->nodes[cur_node].opt_subexp
-                 && prev_idx_match[reg_num].rm_so != -1)
-               /* We transited through an empty match for an optional
-                  subexpression, like (a?)*, and this is not the subexp's
-                  first match.  Copy back the old content of the registers
-                  so that matches of an inner subexpression are undone as
-                  well, like in ((a?))*.  */
-               memcpy (pmatch, prev_idx_match, sizeof (regmatch_t) * nmatch);
-             else
-               /* We completed a subexpression, but it may be part of
-                  an optional one, so do not update PREV_IDX_MATCH.  */
-               pmatch[reg_num].rm_eo = cur_idx;
-           }
-       }
-    }
-}
-
-/* This function checks the STATE_LOG from the SCTX->last_str_idx to 0
-   and sift the nodes in each states according to the following rules.
-   Updated state_log will be wrote to STATE_LOG.
-
-   Rules: We throw away the Node `a' in the STATE_LOG[STR_IDX] if...
-     1. When STR_IDX == MATCH_LAST(the last index in the state_log):
-       If `a' isn't the LAST_NODE and `a' can't epsilon transit to
-       the LAST_NODE, we throw away the node `a'.
-     2. When 0 <= STR_IDX < MATCH_LAST and `a' accepts
-       string `s' and transit to `b':
-       i. If 'b' isn't in the STATE_LOG[STR_IDX+strlen('s')], we throw
-          away the node `a'.
-       ii. If 'b' is in the STATE_LOG[STR_IDX+strlen('s')] but 'b' is
-           thrown away, we throw away the node `a'.
-     3. When 0 <= STR_IDX < MATCH_LAST and 'a' epsilon transit to 'b':
-       i. If 'b' isn't in the STATE_LOG[STR_IDX], we throw away the
-          node `a'.
-       ii. If 'b' is in the STATE_LOG[STR_IDX] but 'b' is thrown away,
-           we throw away the node `a'.  */
-
-#define STATE_NODE_CONTAINS(state,node) \
-  ((state) != NULL && re_node_set_contains (&(state)->nodes, node))
-
-static reg_errcode_t
-internal_function
-sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx)
-{
-  reg_errcode_t err;
-  int null_cnt = 0;
-  Idx str_idx = sctx->last_str_idx;
-  re_node_set cur_dest;
-
-#ifdef DEBUG
-  assert (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL);
-#endif
-
-  /* Build sifted state_log[str_idx].  It has the nodes which can epsilon
-     transit to the last_node and the last_node itself.  */
-  err = re_node_set_init_1 (&cur_dest, sctx->last_node);
-  if (BE (err != REG_NOERROR, 0))
-    return err;
-  err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
-  if (BE (err != REG_NOERROR, 0))
-    goto free_return;
-
-  /* Then check each states in the state_log.  */
-  while (str_idx > 0)
-    {
-      /* Update counters.  */
-      null_cnt = (sctx->sifted_states[str_idx] == NULL) ? null_cnt + 1 : 0;
-      if (null_cnt > mctx->max_mb_elem_len)
-       {
-         memset (sctx->sifted_states, '\0',
-                 sizeof (re_dfastate_t *) * str_idx);
-         re_node_set_free (&cur_dest);
-         return REG_NOERROR;
-       }
-      re_node_set_empty (&cur_dest);
-      --str_idx;
-
-      if (mctx->state_log[str_idx])
-       {
-         err = build_sifted_states (mctx, sctx, str_idx, &cur_dest);
-         if (BE (err != REG_NOERROR, 0))
-           goto free_return;
-       }
-
-      /* Add all the nodes which satisfy the following conditions:
-        - It can epsilon transit to a node in CUR_DEST.
-        - It is in CUR_SRC.
-        And update state_log.  */
-      err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
-      if (BE (err != REG_NOERROR, 0))
-       goto free_return;
-    }
-  err = REG_NOERROR;
- free_return:
-  re_node_set_free (&cur_dest);
-  return err;
-}
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx,
-                    Idx str_idx, re_node_set *cur_dest)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  const re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes;
-  Idx i;
-
-  /* Then build the next sifted state.
-     We build the next sifted state on `cur_dest', and update
-     `sifted_states[str_idx]' with `cur_dest'.
-     Note:
-     `cur_dest' is the sifted state from `state_log[str_idx + 1]'.
-     `cur_src' points the node_set of the old `state_log[str_idx]'
-     (with the epsilon nodes pre-filtered out).  */
-  for (i = 0; i < cur_src->nelem; i++)
-    {
-      Idx prev_node = cur_src->elems[i];
-      int naccepted = 0;
-      bool ok;
-
-#ifdef DEBUG
-      re_token_type_t type = dfa->nodes[prev_node].type;
-      assert (!IS_EPSILON_NODE (type));
-#endif
-#ifdef RE_ENABLE_I18N
-      /* If the node may accept `multi byte'.  */
-      if (dfa->nodes[prev_node].accept_mb)
-       naccepted = sift_states_iter_mb (mctx, sctx, prev_node,
-                                        str_idx, sctx->last_str_idx);
-#endif /* RE_ENABLE_I18N */
-
-      /* We don't check backreferences here.
-        See update_cur_sifted_state().  */
-      if (!naccepted
-         && check_node_accept (mctx, dfa->nodes + prev_node, str_idx)
-         && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1],
-                                 dfa->nexts[prev_node]))
-       naccepted = 1;
-
-      if (naccepted == 0)
-       continue;
-
-      if (sctx->limits.nelem)
-       {
-         Idx to_idx = str_idx + naccepted;
-         if (check_dst_limits (mctx, &sctx->limits,
-                               dfa->nexts[prev_node], to_idx,
-                               prev_node, str_idx))
-           continue;
-       }
-      ok = re_node_set_insert (cur_dest, prev_node);
-      if (BE (! ok, 0))
-       return REG_ESPACE;
-    }
-
-  return REG_NOERROR;
-}
-
-/* Helper functions.  */
-
-static reg_errcode_t
-internal_function
-clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx)
-{
-  Idx top = mctx->state_log_top;
-
-  if (next_state_log_idx >= mctx->input.bufs_len
-      || (next_state_log_idx >= mctx->input.valid_len
-         && mctx->input.valid_len < mctx->input.len))
-    {
-      reg_errcode_t err;
-      err = extend_buffers (mctx);
-      if (BE (err != REG_NOERROR, 0))
-       return err;
-    }
-
-  if (top < next_state_log_idx)
-    {
-      memset (mctx->state_log + top + 1, '\0',
-             sizeof (re_dfastate_t *) * (next_state_log_idx - top));
-      mctx->state_log_top = next_state_log_idx;
-    }
-  return REG_NOERROR;
-}
-
-static reg_errcode_t
-internal_function
-merge_state_array (const re_dfa_t *dfa, re_dfastate_t **dst,
-                  re_dfastate_t **src, Idx num)
-{
-  Idx st_idx;
-  reg_errcode_t err;
-  for (st_idx = 0; st_idx < num; ++st_idx)
-    {
-      if (dst[st_idx] == NULL)
-       dst[st_idx] = src[st_idx];
-      else if (src[st_idx] != NULL)
-       {
-         re_node_set merged_set;
-         err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes,
-                                       &src[st_idx]->nodes);
-         if (BE (err != REG_NOERROR, 0))
-           return err;
-         dst[st_idx] = re_acquire_state (&err, dfa, &merged_set);
-         re_node_set_free (&merged_set);
-         if (BE (err != REG_NOERROR, 0))
-           return err;
-       }
-    }
-  return REG_NOERROR;
-}
-
-static reg_errcode_t
-internal_function
-update_cur_sifted_state (const re_match_context_t *mctx,
-                        re_sift_context_t *sctx, Idx str_idx,
-                        re_node_set *dest_nodes)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  reg_errcode_t err = REG_NOERROR;
-  const re_node_set *candidates;
-  candidates = ((mctx->state_log[str_idx] == NULL) ? NULL
-               : &mctx->state_log[str_idx]->nodes);
-
-  if (dest_nodes->nelem == 0)
-    sctx->sifted_states[str_idx] = NULL;
-  else
-    {
-      if (candidates)
-       {
-         /* At first, add the nodes which can epsilon transit to a node in
-            DEST_NODE.  */
-         err = add_epsilon_src_nodes (dfa, dest_nodes, candidates);
-         if (BE (err != REG_NOERROR, 0))
-           return err;
-
-         /* Then, check the limitations in the current sift_context.  */
-         if (sctx->limits.nelem)
-           {
-             err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits,
-                                        mctx->bkref_ents, str_idx);
-             if (BE (err != REG_NOERROR, 0))
-               return err;
-           }
-       }
-
-      sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes);
-      if (BE (err != REG_NOERROR, 0))
-       return err;
-    }
-
-  if (candidates && mctx->state_log[str_idx]->has_backref)
-    {
-      err = sift_states_bkref (mctx, sctx, str_idx, candidates);
-      if (BE (err != REG_NOERROR, 0))
-       return err;
-    }
-  return REG_NOERROR;
-}
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes,
-                      const re_node_set *candidates)
-{
-  reg_errcode_t err = REG_NOERROR;
-  Idx i;
-
-  re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes);
-  if (BE (err != REG_NOERROR, 0))
-    return err;
-
-  if (!state->inveclosure.alloc)
-    {
-      err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem);
-      if (BE (err != REG_NOERROR, 0))
-       return REG_ESPACE;
-      for (i = 0; i < dest_nodes->nelem; i++)
-       {
-         err = re_node_set_merge (&state->inveclosure,
-                                  dfa->inveclosures + dest_nodes->elems[i]);
-         if (BE (err != REG_NOERROR, 0))
-           return REG_ESPACE;
-       }
-    }
-  return re_node_set_add_intersect (dest_nodes, candidates,
-                                   &state->inveclosure);
-}
-
-static reg_errcode_t
-internal_function
-sub_epsilon_src_nodes (const re_dfa_t *dfa, Idx node, re_node_set *dest_nodes,
-                      const re_node_set *candidates)
-{
-    Idx ecl_idx;
-    reg_errcode_t err;
-    re_node_set *inv_eclosure = dfa->inveclosures + node;
-    re_node_set except_nodes;
-    re_node_set_init_empty (&except_nodes);
-    for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
-      {
-       Idx cur_node = inv_eclosure->elems[ecl_idx];
-       if (cur_node == node)
-         continue;
-       if (IS_EPSILON_NODE (dfa->nodes[cur_node].type))
-         {
-           Idx edst1 = dfa->edests[cur_node].elems[0];
-           Idx edst2 = ((dfa->edests[cur_node].nelem > 1)
-                        ? dfa->edests[cur_node].elems[1] : REG_MISSING);
-           if ((!re_node_set_contains (inv_eclosure, edst1)
-                && re_node_set_contains (dest_nodes, edst1))
-               || (REG_VALID_NONZERO_INDEX (edst2)
-                   && !re_node_set_contains (inv_eclosure, edst2)
-                   && re_node_set_contains (dest_nodes, edst2)))
-             {
-               err = re_node_set_add_intersect (&except_nodes, candidates,
-                                                dfa->inveclosures + cur_node);
-               if (BE (err != REG_NOERROR, 0))
-                 {
-                   re_node_set_free (&except_nodes);
-                   return err;
-                 }
-             }
-         }
-      }
-    for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
-      {
-       Idx cur_node = inv_eclosure->elems[ecl_idx];
-       if (!re_node_set_contains (&except_nodes, cur_node))
-         {
-           Idx idx = re_node_set_contains (dest_nodes, cur_node) - 1;
-           re_node_set_remove_at (dest_nodes, idx);
-         }
-      }
-    re_node_set_free (&except_nodes);
-    return REG_NOERROR;
-}
-
-static bool
-internal_function
-check_dst_limits (const re_match_context_t *mctx, const re_node_set *limits,
-                 Idx dst_node, Idx dst_idx, Idx src_node, Idx src_idx)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  Idx lim_idx, src_pos, dst_pos;
-
-  Idx dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx);
-  Idx src_bkref_idx = search_cur_bkref_entry (mctx, src_idx);
-  for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
-    {
-      Idx subexp_idx;
-      struct re_backref_cache_entry *ent;
-      ent = mctx->bkref_ents + limits->elems[lim_idx];
-      subexp_idx = dfa->nodes[ent->node].opr.idx;
-
-      dst_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
-                                          subexp_idx, dst_node, dst_idx,
-                                          dst_bkref_idx);
-      src_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
-                                          subexp_idx, src_node, src_idx,
-                                          src_bkref_idx);
-
-      /* In case of:
-        <src> <dst> ( <subexp> )
-        ( <subexp> ) <src> <dst>
-        ( <subexp1> <src> <subexp2> <dst> <subexp3> )  */
-      if (src_pos == dst_pos)
-       continue; /* This is unrelated limitation.  */
-      else
-       return true;
-    }
-  return false;
-}
-
-static int
-internal_function
-check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries,
-                            Idx subexp_idx, Idx from_node, Idx bkref_idx)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  const re_node_set *eclosures = dfa->eclosures + from_node;
-  Idx node_idx;
-
-  /* Else, we are on the boundary: examine the nodes on the epsilon
-     closure.  */
-  for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx)
-    {
-      Idx node = eclosures->elems[node_idx];
-      switch (dfa->nodes[node].type)
-       {
-       case OP_BACK_REF:
-         if (bkref_idx != REG_MISSING)
-           {
-             struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx;
-             do
-               {
-                 Idx dst;
-                 int cpos;
-
-                 if (ent->node != node)
-                   continue;
-
-                 if (subexp_idx < BITSET_WORD_BITS
-                     && !(ent->eps_reachable_subexps_map
-                          & ((bitset_word_t) 1 << subexp_idx)))
-                   continue;
-
-                 /* Recurse trying to reach the OP_OPEN_SUBEXP and
-                    OP_CLOSE_SUBEXP cases below.  But, if the
-                    destination node is the same node as the source
-                    node, don't recurse because it would cause an
-                    infinite loop: a regex that exhibits this behavior
-                    is ()\1*\1*  */
-                 dst = dfa->edests[node].elems[0];
-                 if (dst == from_node)
-                   {
-                     if (boundaries & 1)
-                       return -1;
-                     else /* if (boundaries & 2) */
-                       return 0;
-                   }
-
-                 cpos =
-                   check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,
-                                                dst, bkref_idx);
-                 if (cpos == -1 /* && (boundaries & 1) */)
-                   return -1;
-                 if (cpos == 0 && (boundaries & 2))
-                   return 0;
-
-                 if (subexp_idx < BITSET_WORD_BITS)
-                   ent->eps_reachable_subexps_map
-                     &= ~((bitset_word_t) 1 << subexp_idx);
-               }
-             while (ent++->more);
-           }
-         break;
-
-       case OP_OPEN_SUBEXP:
-         if ((boundaries & 1) && subexp_idx == dfa->nodes[node].opr.idx)
-           return -1;
-         break;
-
-       case OP_CLOSE_SUBEXP:
-         if ((boundaries & 2) && subexp_idx == dfa->nodes[node].opr.idx)
-           return 0;
-         break;
-
-       default:
-           break;
-       }
-    }
-
-  return (boundaries & 2) ? 1 : 0;
-}
-
-static int
-internal_function
-check_dst_limits_calc_pos (const re_match_context_t *mctx, Idx limit,
-                          Idx subexp_idx, Idx from_node, Idx str_idx,
-                          Idx bkref_idx)
-{
-  struct re_backref_cache_entry *lim = mctx->bkref_ents + limit;
-  int boundaries;
-
-  /* If we are outside the range of the subexpression, return -1 or 1.  */
-  if (str_idx < lim->subexp_from)
-    return -1;
-
-  if (lim->subexp_to < str_idx)
-    return 1;
-
-  /* If we are within the subexpression, return 0.  */
-  boundaries = (str_idx == lim->subexp_from);
-  boundaries |= (str_idx == lim->subexp_to) << 1;
-  if (boundaries == 0)
-    return 0;
-
-  /* Else, examine epsilon closure.  */
-  return check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,
-                                     from_node, bkref_idx);
-}
-
-/* Check the limitations of sub expressions LIMITS, and remove the nodes
-   which are against limitations from DEST_NODES. */
-
-static reg_errcode_t
-internal_function
-check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes,
-                    const re_node_set *candidates, re_node_set *limits,
-                    struct re_backref_cache_entry *bkref_ents, Idx str_idx)
-{
-  reg_errcode_t err;
-  Idx node_idx, lim_idx;
-
-  for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
-    {
-      Idx subexp_idx;
-      struct re_backref_cache_entry *ent;
-      ent = bkref_ents + limits->elems[lim_idx];
-
-      if (str_idx <= ent->subexp_from || ent->str_idx < str_idx)
-       continue; /* This is unrelated limitation.  */
-
-      subexp_idx = dfa->nodes[ent->node].opr.idx;
-      if (ent->subexp_to == str_idx)
-       {
-         Idx ops_node = REG_MISSING;
-         Idx cls_node = REG_MISSING;
-         for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
-           {
-             Idx node = dest_nodes->elems[node_idx];
-             re_token_type_t type = dfa->nodes[node].type;
-             if (type == OP_OPEN_SUBEXP
-                 && subexp_idx == dfa->nodes[node].opr.idx)
-               ops_node = node;
-             else if (type == OP_CLOSE_SUBEXP
-                      && subexp_idx == dfa->nodes[node].opr.idx)
-               cls_node = node;
-           }
-
-         /* Check the limitation of the open subexpression.  */
-         /* Note that (ent->subexp_to = str_idx != ent->subexp_from).  */
-         if (REG_VALID_INDEX (ops_node))
-           {
-             err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes,
-                                          candidates);
-             if (BE (err != REG_NOERROR, 0))
-               return err;
-           }
-
-         /* Check the limitation of the close subexpression.  */
-         if (REG_VALID_INDEX (cls_node))
-           for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
-             {
-               Idx node = dest_nodes->elems[node_idx];
-               if (!re_node_set_contains (dfa->inveclosures + node,
-                                          cls_node)
-                   && !re_node_set_contains (dfa->eclosures + node,
-                                             cls_node))
-                 {
-                   /* It is against this limitation.
-                      Remove it form the current sifted state.  */
-                   err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
-                                                candidates);
-                   if (BE (err != REG_NOERROR, 0))
-                     return err;
-                   --node_idx;
-                 }
-             }
-       }
-      else /* (ent->subexp_to != str_idx)  */
-       {
-         for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
-           {
-             Idx node = dest_nodes->elems[node_idx];
-             re_token_type_t type = dfa->nodes[node].type;
-             if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP)
-               {
-                 if (subexp_idx != dfa->nodes[node].opr.idx)
-                   continue;
-                 /* It is against this limitation.
-                    Remove it form the current sifted state.  */
-                 err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
-                                              candidates);
-                 if (BE (err != REG_NOERROR, 0))
-                   return err;
-               }
-           }
-       }
-    }
-  return REG_NOERROR;
-}
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx,
-                  Idx str_idx, const re_node_set *candidates)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  reg_errcode_t err;
-  Idx node_idx, node;
-  re_sift_context_t local_sctx;
-  Idx first_idx = search_cur_bkref_entry (mctx, str_idx);
-
-  if (first_idx == REG_MISSING)
-    return REG_NOERROR;
-
-  local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized.  */
-
-  for (node_idx = 0; node_idx < candidates->nelem; ++node_idx)
-    {
-      Idx enabled_idx;
-      re_token_type_t type;
-      struct re_backref_cache_entry *entry;
-      node = candidates->elems[node_idx];
-      type = dfa->nodes[node].type;
-      /* Avoid infinite loop for the REs like "()\1+".  */
-      if (node == sctx->last_node && str_idx == sctx->last_str_idx)
-       continue;
-      if (type != OP_BACK_REF)
-       continue;
-
-      entry = mctx->bkref_ents + first_idx;
-      enabled_idx = first_idx;
-      do
-       {
-         Idx subexp_len;
-         Idx to_idx;
-         Idx dst_node;
-         bool ok;
-         re_dfastate_t *cur_state;
-
-         if (entry->node != node)
-           continue;
-         subexp_len = entry->subexp_to - entry->subexp_from;
-         to_idx = str_idx + subexp_len;
-         dst_node = (subexp_len ? dfa->nexts[node]
-                     : dfa->edests[node].elems[0]);
-
-         if (to_idx > sctx->last_str_idx
-             || sctx->sifted_states[to_idx] == NULL
-             || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx], dst_node)
-             || check_dst_limits (mctx, &sctx->limits, node,
-                                  str_idx, dst_node, to_idx))
-           continue;
-
-         if (local_sctx.sifted_states == NULL)
-           {
-             local_sctx = *sctx;
-             err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits);
-             if (BE (err != REG_NOERROR, 0))
-               goto free_return;
-           }
-         local_sctx.last_node = node;
-         local_sctx.last_str_idx = str_idx;
-         ok = re_node_set_insert (&local_sctx.limits, enabled_idx);
-         if (BE (! ok, 0))
-           {
-             err = REG_ESPACE;
-             goto free_return;
-           }
-         cur_state = local_sctx.sifted_states[str_idx];
-         err = sift_states_backward (mctx, &local_sctx);
-         if (BE (err != REG_NOERROR, 0))
-           goto free_return;
-         if (sctx->limited_states != NULL)
-           {
-             err = merge_state_array (dfa, sctx->limited_states,
-                                      local_sctx.sifted_states,
-                                      str_idx + 1);
-             if (BE (err != REG_NOERROR, 0))
-               goto free_return;
-           }
-         local_sctx.sifted_states[str_idx] = cur_state;
-         re_node_set_remove (&local_sctx.limits, enabled_idx);
-
-         /* mctx->bkref_ents may have changed, reload the pointer.  */
-         entry = mctx->bkref_ents + enabled_idx;
-       }
-      while (enabled_idx++, entry++->more);
-    }
-  err = REG_NOERROR;
- free_return:
-  if (local_sctx.sifted_states != NULL)
-    {
-      re_node_set_free (&local_sctx.limits);
-    }
-
-  return err;
-}
-
-
-#ifdef RE_ENABLE_I18N
-static int
-internal_function
-sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx,
-                    Idx node_idx, Idx str_idx, Idx max_str_idx)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  int naccepted;
-  /* Check the node can accept `multi byte'.  */
-  naccepted = check_node_accept_bytes (dfa, node_idx, &mctx->input, str_idx);
-  if (naccepted > 0 && str_idx + naccepted <= max_str_idx &&
-      !STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + naccepted],
-                           dfa->nexts[node_idx]))
-    /* The node can't accept the `multi byte', or the
-       destination was already thrown away, then the node
-       could't accept the current input `multi byte'.   */
-    naccepted = 0;
-  /* Otherwise, it is sure that the node could accept
-     `naccepted' bytes input.  */
-  return naccepted;
-}
-#endif /* RE_ENABLE_I18N */
-
-\f
-/* Functions for state transition.  */
-
-/* Return the next state to which the current state STATE will transit by
-   accepting the current input byte, and update STATE_LOG if necessary.
-   If STATE can accept a multibyte char/collating element/back reference
-   update the destination of STATE_LOG.  */
-
-static re_dfastate_t *
-internal_function __attribute_warn_unused_result__
-transit_state (reg_errcode_t *err, re_match_context_t *mctx,
-              re_dfastate_t *state)
-{
-  re_dfastate_t **trtable;
-  unsigned char ch;
-
-#ifdef RE_ENABLE_I18N
-  /* If the current state can accept multibyte.  */
-  if (BE (state->accept_mb, 0))
-    {
-      *err = transit_state_mb (mctx, state);
-      if (BE (*err != REG_NOERROR, 0))
-       return NULL;
-    }
-#endif /* RE_ENABLE_I18N */
-
-  /* Then decide the next state with the single byte.  */
-#if 0
-  if (0)
-    /* don't use transition table  */
-    return transit_state_sb (err, mctx, state);
-#endif
-
-  /* Use transition table  */
-  ch = re_string_fetch_byte (&mctx->input);
-  for (;;)
-    {
-      trtable = state->trtable;
-      if (BE (trtable != NULL, 1))
-       return trtable[ch];
-
-      trtable = state->word_trtable;
-      if (BE (trtable != NULL, 1))
-       {
-         unsigned int context;
-         context
-           = re_string_context_at (&mctx->input,
-                                   re_string_cur_idx (&mctx->input) - 1,
-                                   mctx->eflags);
-         if (IS_WORD_CONTEXT (context))
-           return trtable[ch + SBC_MAX];
-         else
-           return trtable[ch];
-       }
-
-      if (!build_trtable (mctx->dfa, state))
-       {
-         *err = REG_ESPACE;
-         return NULL;
-       }
-
-      /* Retry, we now have a transition table.  */
-    }
-}
-
-/* Update the state_log if we need */
-static re_dfastate_t *
-internal_function
-merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx,
-                     re_dfastate_t *next_state)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  Idx cur_idx = re_string_cur_idx (&mctx->input);
-
-  if (cur_idx > mctx->state_log_top)
-    {
-      mctx->state_log[cur_idx] = next_state;
-      mctx->state_log_top = cur_idx;
-    }
-  else if (mctx->state_log[cur_idx] == 0)
-    {
-      mctx->state_log[cur_idx] = next_state;
-    }
-  else
-    {
-      re_dfastate_t *pstate;
-      unsigned int context;
-      re_node_set next_nodes, *log_nodes, *table_nodes = NULL;
-      /* If (state_log[cur_idx] != 0), it implies that cur_idx is
-        the destination of a multibyte char/collating element/
-        back reference.  Then the next state is the union set of
-        these destinations and the results of the transition table.  */
-      pstate = mctx->state_log[cur_idx];
-      log_nodes = pstate->entrance_nodes;
-      if (next_state != NULL)
-       {
-         table_nodes = next_state->entrance_nodes;
-         *err = re_node_set_init_union (&next_nodes, table_nodes,
-                                            log_nodes);
-         if (BE (*err != REG_NOERROR, 0))
-           return NULL;
-       }
-      else
-       next_nodes = *log_nodes;
-      /* Note: We already add the nodes of the initial state,
-        then we don't need to add them here.  */
-
-      context = re_string_context_at (&mctx->input,
-                                     re_string_cur_idx (&mctx->input) - 1,
-                                     mctx->eflags);
-      next_state = mctx->state_log[cur_idx]
-       = re_acquire_state_context (err, dfa, &next_nodes, context);
-      /* We don't need to check errors here, since the return value of
-        this function is next_state and ERR is already set.  */
-
-      if (table_nodes != NULL)
-       re_node_set_free (&next_nodes);
-    }
-
-  if (BE (dfa->nbackref, 0) && next_state != NULL)
-    {
-      /* Check OP_OPEN_SUBEXP in the current state in case that we use them
-        later.  We must check them here, since the back references in the
-        next state might use them.  */
-      *err = check_subexp_matching_top (mctx, &next_state->nodes,
-                                       cur_idx);
-      if (BE (*err != REG_NOERROR, 0))
-       return NULL;
-
-      /* If the next state has back references.  */
-      if (next_state->has_backref)
-       {
-         *err = transit_state_bkref (mctx, &next_state->nodes);
-         if (BE (*err != REG_NOERROR, 0))
-           return NULL;
-         next_state = mctx->state_log[cur_idx];
-       }
-    }
-
-  return next_state;
-}
-
-/* Skip bytes in the input that correspond to part of a
-   multi-byte match, then look in the log for a state
-   from which to restart matching.  */
-static re_dfastate_t *
-internal_function
-find_recover_state (reg_errcode_t *err, re_match_context_t *mctx)
-{
-  re_dfastate_t *cur_state;
-  do
-    {
-      Idx max = mctx->state_log_top;
-      Idx cur_str_idx = re_string_cur_idx (&mctx->input);
-
-      do
-       {
-         if (++cur_str_idx > max)
-           return NULL;
-         re_string_skip_bytes (&mctx->input, 1);
-       }
-      while (mctx->state_log[cur_str_idx] == NULL);
-
-      cur_state = merge_state_with_log (err, mctx, NULL);
-    }
-  while (*err == REG_NOERROR && cur_state == NULL);
-  return cur_state;
-}
-
-/* Helper functions for transit_state.  */
-
-/* From the node set CUR_NODES, pick up the nodes whose types are
-   OP_OPEN_SUBEXP and which have corresponding back references in the regular
-   expression. And register them to use them later for evaluating the
-   correspoding back references.  */
-
-static reg_errcode_t
-internal_function
-check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes,
-                          Idx str_idx)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  Idx node_idx;
-  reg_errcode_t err;
-
-  /* TODO: This isn't efficient.
-          Because there might be more than one nodes whose types are
-          OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
-          nodes.
-          E.g. RE: (a){2}  */
-  for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx)
-    {
-      Idx node = cur_nodes->elems[node_idx];
-      if (dfa->nodes[node].type == OP_OPEN_SUBEXP
-         && dfa->nodes[node].opr.idx < BITSET_WORD_BITS
-         && (dfa->used_bkref_map
-             & ((bitset_word_t) 1 << dfa->nodes[node].opr.idx)))
-       {
-         err = match_ctx_add_subtop (mctx, node, str_idx);
-         if (BE (err != REG_NOERROR, 0))
-           return err;
-       }
-    }
-  return REG_NOERROR;
-}
-
-#if 0
-/* Return the next state to which the current state STATE will transit by
-   accepting the current input byte.  */
-
-static re_dfastate_t *
-transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx,
-                 re_dfastate_t *state)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  re_node_set next_nodes;
-  re_dfastate_t *next_state;
-  Idx node_cnt, cur_str_idx = re_string_cur_idx (&mctx->input);
-  unsigned int context;
-
-  *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1);
-  if (BE (*err != REG_NOERROR, 0))
-    return NULL;
-  for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt)
-    {
-      Idx cur_node = state->nodes.elems[node_cnt];
-      if (check_node_accept (mctx, dfa->nodes + cur_node, cur_str_idx))
-       {
-         *err = re_node_set_merge (&next_nodes,
-                                   dfa->eclosures + dfa->nexts[cur_node]);
-         if (BE (*err != REG_NOERROR, 0))
-           {
-             re_node_set_free (&next_nodes);
-             return NULL;
-           }
-       }
-    }
-  context = re_string_context_at (&mctx->input, cur_str_idx, mctx->eflags);
-  next_state = re_acquire_state_context (err, dfa, &next_nodes, context);
-  /* We don't need to check errors here, since the return value of
-     this function is next_state and ERR is already set.  */
-
-  re_node_set_free (&next_nodes);
-  re_string_skip_bytes (&mctx->input, 1);
-  return next_state;
-}
-#endif
-
-#ifdef RE_ENABLE_I18N
-static reg_errcode_t
-internal_function
-transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  reg_errcode_t err;
-  Idx i;
-
-  for (i = 0; i < pstate->nodes.nelem; ++i)
-    {
-      re_node_set dest_nodes, *new_nodes;
-      Idx cur_node_idx = pstate->nodes.elems[i];
-      int naccepted;
-      Idx dest_idx;
-      unsigned int context;
-      re_dfastate_t *dest_state;
-
-      if (!dfa->nodes[cur_node_idx].accept_mb)
-       continue;
-
-      if (dfa->nodes[cur_node_idx].constraint)
-       {
-         context = re_string_context_at (&mctx->input,
-                                         re_string_cur_idx (&mctx->input),
-                                         mctx->eflags);
-         if (NOT_SATISFY_NEXT_CONSTRAINT (dfa->nodes[cur_node_idx].constraint,
-                                          context))
-           continue;
-       }
-
-      /* How many bytes the node can accept?  */
-      naccepted = check_node_accept_bytes (dfa, cur_node_idx, &mctx->input,
-                                          re_string_cur_idx (&mctx->input));
-      if (naccepted == 0)
-       continue;
-
-      /* The node can accepts `naccepted' bytes.  */
-      dest_idx = re_string_cur_idx (&mctx->input) + naccepted;
-      mctx->max_mb_elem_len = ((mctx->max_mb_elem_len < naccepted) ? naccepted
-                              : mctx->max_mb_elem_len);
-      err = clean_state_log_if_needed (mctx, dest_idx);
-      if (BE (err != REG_NOERROR, 0))
-       return err;
-#ifdef DEBUG
-      assert (dfa->nexts[cur_node_idx] != REG_MISSING);
-#endif
-      new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx];
-
-      dest_state = mctx->state_log[dest_idx];
-      if (dest_state == NULL)
-       dest_nodes = *new_nodes;
-      else
-       {
-         err = re_node_set_init_union (&dest_nodes,
-                                       dest_state->entrance_nodes, new_nodes);
-         if (BE (err != REG_NOERROR, 0))
-           return err;
-       }
-      context = re_string_context_at (&mctx->input, dest_idx - 1,
-                                     mctx->eflags);
-      mctx->state_log[dest_idx]
-       = re_acquire_state_context (&err, dfa, &dest_nodes, context);
-      if (dest_state != NULL)
-       re_node_set_free (&dest_nodes);
-      if (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0))
-       return err;
-    }
-  return REG_NOERROR;
-}
-#endif /* RE_ENABLE_I18N */
-
-static reg_errcode_t
-internal_function
-transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  reg_errcode_t err;
-  Idx i;
-  Idx cur_str_idx = re_string_cur_idx (&mctx->input);
-
-  for (i = 0; i < nodes->nelem; ++i)
-    {
-      Idx dest_str_idx, prev_nelem, bkc_idx;
-      Idx node_idx = nodes->elems[i];
-      unsigned int context;
-      const re_token_t *node = dfa->nodes + node_idx;
-      re_node_set *new_dest_nodes;
-
-      /* Check whether `node' is a backreference or not.  */
-      if (node->type != OP_BACK_REF)
-       continue;
-
-      if (node->constraint)
-       {
-         context = re_string_context_at (&mctx->input, cur_str_idx,
-                                         mctx->eflags);
-         if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))
-           continue;
-       }
-
-      /* `node' is a backreference.
-        Check the substring which the substring matched.  */
-      bkc_idx = mctx->nbkref_ents;
-      err = get_subexp (mctx, node_idx, cur_str_idx);
-      if (BE (err != REG_NOERROR, 0))
-       goto free_return;
-
-      /* And add the epsilon closures (which is `new_dest_nodes') of
-        the backreference to appropriate state_log.  */
-#ifdef DEBUG
-      assert (dfa->nexts[node_idx] != REG_MISSING);
-#endif
-      for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx)
-       {
-         Idx subexp_len;
-         re_dfastate_t *dest_state;
-         struct re_backref_cache_entry *bkref_ent;
-         bkref_ent = mctx->bkref_ents + bkc_idx;
-         if (bkref_ent->node != node_idx || bkref_ent->str_idx != cur_str_idx)
-           continue;
-         subexp_len = bkref_ent->subexp_to - bkref_ent->subexp_from;
-         new_dest_nodes = (subexp_len == 0
-                           ? dfa->eclosures + dfa->edests[node_idx].elems[0]
-                           : dfa->eclosures + dfa->nexts[node_idx]);
-         dest_str_idx = (cur_str_idx + bkref_ent->subexp_to
-                         - bkref_ent->subexp_from);
-         context = re_string_context_at (&mctx->input, dest_str_idx - 1,
-                                         mctx->eflags);
-         dest_state = mctx->state_log[dest_str_idx];
-         prev_nelem = ((mctx->state_log[cur_str_idx] == NULL) ? 0
-                       : mctx->state_log[cur_str_idx]->nodes.nelem);
-         /* Add `new_dest_node' to state_log.  */
-         if (dest_state == NULL)
-           {
-             mctx->state_log[dest_str_idx]
-               = re_acquire_state_context (&err, dfa, new_dest_nodes,
-                                           context);
-             if (BE (mctx->state_log[dest_str_idx] == NULL
-                     && err != REG_NOERROR, 0))
-               goto free_return;
-           }
-         else
-           {
-             re_node_set dest_nodes;
-             err = re_node_set_init_union (&dest_nodes,
-                                           dest_state->entrance_nodes,
-                                           new_dest_nodes);
-             if (BE (err != REG_NOERROR, 0))
-               {
-                 re_node_set_free (&dest_nodes);
-                 goto free_return;
-               }
-             mctx->state_log[dest_str_idx]
-               = re_acquire_state_context (&err, dfa, &dest_nodes, context);
-             re_node_set_free (&dest_nodes);
-             if (BE (mctx->state_log[dest_str_idx] == NULL
-                     && err != REG_NOERROR, 0))
-               goto free_return;
-           }
-         /* We need to check recursively if the backreference can epsilon
-            transit.  */
-         if (subexp_len == 0
-             && mctx->state_log[cur_str_idx]->nodes.nelem > prev_nelem)
-           {
-             err = check_subexp_matching_top (mctx, new_dest_nodes,
-                                              cur_str_idx);
-             if (BE (err != REG_NOERROR, 0))
-               goto free_return;
-             err = transit_state_bkref (mctx, new_dest_nodes);
-             if (BE (err != REG_NOERROR, 0))
-               goto free_return;
-           }
-       }
-    }
-  err = REG_NOERROR;
- free_return:
-  return err;
-}
-
-/* Enumerate all the candidates which the backreference BKREF_NODE can match
-   at BKREF_STR_IDX, and register them by match_ctx_add_entry().
-   Note that we might collect inappropriate candidates here.
-   However, the cost of checking them strictly here is too high, then we
-   delay these checking for prune_impossible_nodes().  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  Idx subexp_num, sub_top_idx;
-  const char *buf = (const char *) re_string_get_buffer (&mctx->input);
-  /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX.  */
-  Idx cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx);
-  if (cache_idx != REG_MISSING)
-    {
-      const struct re_backref_cache_entry *entry
-       = mctx->bkref_ents + cache_idx;
-      do
-       if (entry->node == bkref_node)
-         return REG_NOERROR; /* We already checked it.  */
-      while (entry++->more);
-    }
-
-  subexp_num = dfa->nodes[bkref_node].opr.idx;
-
-  /* For each sub expression  */
-  for (sub_top_idx = 0; sub_top_idx < mctx->nsub_tops; ++sub_top_idx)
-    {
-      reg_errcode_t err;
-      re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx];
-      re_sub_match_last_t *sub_last;
-      Idx sub_last_idx, sl_str, bkref_str_off;
-
-      if (dfa->nodes[sub_top->node].opr.idx != subexp_num)
-       continue; /* It isn't related.  */
-
-      sl_str = sub_top->str_idx;
-      bkref_str_off = bkref_str_idx;
-      /* At first, check the last node of sub expressions we already
-        evaluated.  */
-      for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx)
-       {
-         regoff_t sl_str_diff;
-         sub_last = sub_top->lasts[sub_last_idx];
-         sl_str_diff = sub_last->str_idx - sl_str;
-         /* The matched string by the sub expression match with the substring
-            at the back reference?  */
-         if (sl_str_diff > 0)
-           {
-             if (BE (bkref_str_off + sl_str_diff > mctx->input.valid_len, 0))
-               {
-                 /* Not enough chars for a successful match.  */
-                 if (bkref_str_off + sl_str_diff > mctx->input.len)
-                   break;
-
-                 err = clean_state_log_if_needed (mctx,
-                                                  bkref_str_off
-                                                  + sl_str_diff);
-                 if (BE (err != REG_NOERROR, 0))
-                   return err;
-                 buf = (const char *) re_string_get_buffer (&mctx->input);
-               }
-             if (memcmp (buf + bkref_str_off, buf + sl_str, sl_str_diff) != 0)
-               /* We don't need to search this sub expression any more.  */
-               break;
-           }
-         bkref_str_off += sl_str_diff;
-         sl_str += sl_str_diff;
-         err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,
-                               bkref_str_idx);
-
-         /* Reload buf, since the preceding call might have reallocated
-            the buffer.  */
-         buf = (const char *) re_string_get_buffer (&mctx->input);
-
-         if (err == REG_NOMATCH)
-           continue;
-         if (BE (err != REG_NOERROR, 0))
-           return err;
-       }
-
-      if (sub_last_idx < sub_top->nlasts)
-       continue;
-      if (sub_last_idx > 0)
-       ++sl_str;
-      /* Then, search for the other last nodes of the sub expression.  */
-      for (; sl_str <= bkref_str_idx; ++sl_str)
-       {
-         Idx cls_node;
-         regoff_t sl_str_off;
-         const re_node_set *nodes;
-         sl_str_off = sl_str - sub_top->str_idx;
-         /* The matched string by the sub expression match with the substring
-            at the back reference?  */
-         if (sl_str_off > 0)
-           {
-             if (BE (bkref_str_off >= mctx->input.valid_len, 0))
-               {
-                 /* If we are at the end of the input, we cannot match.  */
-                 if (bkref_str_off >= mctx->input.len)
-                   break;
-
-                 err = extend_buffers (mctx);
-                 if (BE (err != REG_NOERROR, 0))
-                   return err;
-
-                 buf = (const char *) re_string_get_buffer (&mctx->input);
-               }
-             if (buf [bkref_str_off++] != buf[sl_str - 1])
-               break; /* We don't need to search this sub expression
-                         any more.  */
-           }
-         if (mctx->state_log[sl_str] == NULL)
-           continue;
-         /* Does this state have a ')' of the sub expression?  */
-         nodes = &mctx->state_log[sl_str]->nodes;
-         cls_node = find_subexp_node (dfa, nodes, subexp_num,
-                                      OP_CLOSE_SUBEXP);
-         if (cls_node == REG_MISSING)
-           continue; /* No.  */
-         if (sub_top->path == NULL)
-           {
-             sub_top->path = calloc (sizeof (state_array_t),
-                                     sl_str - sub_top->str_idx + 1);
-             if (sub_top->path == NULL)
-               return REG_ESPACE;
-           }
-         /* Can the OP_OPEN_SUBEXP node arrive the OP_CLOSE_SUBEXP node
-            in the current context?  */
-         err = check_arrival (mctx, sub_top->path, sub_top->node,
-                              sub_top->str_idx, cls_node, sl_str,
-                              OP_CLOSE_SUBEXP);
-         if (err == REG_NOMATCH)
-             continue;
-         if (BE (err != REG_NOERROR, 0))
-             return err;
-         sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str);
-         if (BE (sub_last == NULL, 0))
-           return REG_ESPACE;
-         err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,
-                               bkref_str_idx);
-         if (err == REG_NOMATCH)
-           continue;
-       }
-    }
-  return REG_NOERROR;
-}
-
-/* Helper functions for get_subexp().  */
-
-/* Check SUB_LAST can arrive to the back reference BKREF_NODE at BKREF_STR.
-   If it can arrive, register the sub expression expressed with SUB_TOP
-   and SUB_LAST.  */
-
-static reg_errcode_t
-internal_function
-get_subexp_sub (re_match_context_t *mctx, const re_sub_match_top_t *sub_top,
-               re_sub_match_last_t *sub_last, Idx bkref_node, Idx bkref_str)
-{
-  reg_errcode_t err;
-  Idx to_idx;
-  /* Can the subexpression arrive the back reference?  */
-  err = check_arrival (mctx, &sub_last->path, sub_last->node,
-                      sub_last->str_idx, bkref_node, bkref_str,
-                      OP_OPEN_SUBEXP);
-  if (err != REG_NOERROR)
-    return err;
-  err = match_ctx_add_entry (mctx, bkref_node, bkref_str, sub_top->str_idx,
-                            sub_last->str_idx);
-  if (BE (err != REG_NOERROR, 0))
-    return err;
-  to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx;
-  return clean_state_log_if_needed (mctx, to_idx);
-}
-
-/* Find the first node which is '(' or ')' and whose index is SUBEXP_IDX.
-   Search '(' if FL_OPEN, or search ')' otherwise.
-   TODO: This function isn't efficient...
-        Because there might be more than one nodes whose types are
-        OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
-        nodes.
-        E.g. RE: (a){2}  */
-
-static Idx
-internal_function
-find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
-                 Idx subexp_idx, int type)
-{
-  Idx cls_idx;
-  for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx)
-    {
-      Idx cls_node = nodes->elems[cls_idx];
-      const re_token_t *node = dfa->nodes + cls_node;
-      if (node->type == type
-         && node->opr.idx == subexp_idx)
-       return cls_node;
-    }
-  return REG_MISSING;
-}
-
-/* Check whether the node TOP_NODE at TOP_STR can arrive to the node
-   LAST_NODE at LAST_STR.  We record the path onto PATH since it will be
-   heavily reused.
-   Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node,
-              Idx top_str, Idx last_node, Idx last_str, int type)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  reg_errcode_t err = REG_NOERROR;
-  Idx subexp_num, backup_cur_idx, str_idx, null_cnt;
-  re_dfastate_t *cur_state = NULL;
-  re_node_set *cur_nodes, next_nodes;
-  re_dfastate_t **backup_state_log;
-  unsigned int context;
-
-  subexp_num = dfa->nodes[top_node].opr.idx;
-  /* Extend the buffer if we need.  */
-  if (BE (path->alloc < last_str + mctx->max_mb_elem_len + 1, 0))
-    {
-      re_dfastate_t **new_array;
-      Idx old_alloc = path->alloc;
-      Idx new_alloc = old_alloc + last_str + mctx->max_mb_elem_len + 1;
-      if (BE (new_alloc < old_alloc, 0)
-         || BE (SIZE_MAX / sizeof (re_dfastate_t *) < new_alloc, 0))
-       return REG_ESPACE;
-      new_array = re_realloc (path->array, re_dfastate_t *, new_alloc);
-      if (BE (new_array == NULL, 0))
-       return REG_ESPACE;
-      path->array = new_array;
-      path->alloc = new_alloc;
-      memset (new_array + old_alloc, '\0',
-             sizeof (re_dfastate_t *) * (path->alloc - old_alloc));
-    }
-
-  str_idx = path->next_idx ? path->next_idx : top_str;
-
-  /* Temporary modify MCTX.  */
-  backup_state_log = mctx->state_log;
-  backup_cur_idx = mctx->input.cur_idx;
-  mctx->state_log = path->array;
-  mctx->input.cur_idx = str_idx;
-
-  /* Setup initial node set.  */
-  context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags);
-  if (str_idx == top_str)
-    {
-      err = re_node_set_init_1 (&next_nodes, top_node);
-      if (BE (err != REG_NOERROR, 0))
-       return err;
-      err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);
-      if (BE (err != REG_NOERROR, 0))
-       {
-         re_node_set_free (&next_nodes);
-         return err;
-       }
-    }
-  else
-    {
-      cur_state = mctx->state_log[str_idx];
-      if (cur_state && cur_state->has_backref)
-       {
-         err = re_node_set_init_copy (&next_nodes, &cur_state->nodes);
-         if (BE (err != REG_NOERROR, 0))
-           return err;
-       }
-      else
-       re_node_set_init_empty (&next_nodes);
-    }
-  if (str_idx == top_str || (cur_state && cur_state->has_backref))
-    {
-      if (next_nodes.nelem)
-       {
-         err = expand_bkref_cache (mctx, &next_nodes, str_idx,
-                                   subexp_num, type);
-         if (BE (err != REG_NOERROR, 0))
-           {
-             re_node_set_free (&next_nodes);
-             return err;
-           }
-       }
-      cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
-      if (BE (cur_state == NULL && err != REG_NOERROR, 0))
-       {
-         re_node_set_free (&next_nodes);
-         return err;
-       }
-      mctx->state_log[str_idx] = cur_state;
-    }
-
-  for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;)
-    {
-      re_node_set_empty (&next_nodes);
-      if (mctx->state_log[str_idx + 1])
-       {
-         err = re_node_set_merge (&next_nodes,
-                                  &mctx->state_log[str_idx + 1]->nodes);
-         if (BE (err != REG_NOERROR, 0))
-           {
-             re_node_set_free (&next_nodes);
-             return err;
-           }
-       }
-      if (cur_state)
-       {
-         err = check_arrival_add_next_nodes (mctx, str_idx,
-                                             &cur_state->non_eps_nodes,
-                                             &next_nodes);
-         if (BE (err != REG_NOERROR, 0))
-           {
-             re_node_set_free (&next_nodes);
-             return err;
-           }
-       }
-      ++str_idx;
-      if (next_nodes.nelem)
-       {
-         err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);
-         if (BE (err != REG_NOERROR, 0))
-           {
-             re_node_set_free (&next_nodes);
-             return err;
-           }
-         err = expand_bkref_cache (mctx, &next_nodes, str_idx,
-                                   subexp_num, type);
-         if (BE (err != REG_NOERROR, 0))
-           {
-             re_node_set_free (&next_nodes);
-             return err;
-           }
-       }
-      context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags);
-      cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
-      if (BE (cur_state == NULL && err != REG_NOERROR, 0))
-       {
-         re_node_set_free (&next_nodes);
-         return err;
-       }
-      mctx->state_log[str_idx] = cur_state;
-      null_cnt = cur_state == NULL ? null_cnt + 1 : 0;
-    }
-  re_node_set_free (&next_nodes);
-  cur_nodes = (mctx->state_log[last_str] == NULL ? NULL
-              : &mctx->state_log[last_str]->nodes);
-  path->next_idx = str_idx;
-
-  /* Fix MCTX.  */
-  mctx->state_log = backup_state_log;
-  mctx->input.cur_idx = backup_cur_idx;
-
-  /* Then check the current node set has the node LAST_NODE.  */
-  if (cur_nodes != NULL && re_node_set_contains (cur_nodes, last_node))
-    return REG_NOERROR;
-
-  return REG_NOMATCH;
-}
-
-/* Helper functions for check_arrival.  */
-
-/* Calculate the destination nodes of CUR_NODES at STR_IDX, and append them
-   to NEXT_NODES.
-   TODO: This function is similar to the functions transit_state*(),
-        however this function has many additional works.
-        Can't we unify them?  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx,
-                             re_node_set *cur_nodes, re_node_set *next_nodes)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  bool ok;
-  Idx cur_idx;
-#ifdef RE_ENABLE_I18N
-  reg_errcode_t err = REG_NOERROR;
-#endif
-  re_node_set union_set;
-  re_node_set_init_empty (&union_set);
-  for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx)
-    {
-      int naccepted = 0;
-      Idx cur_node = cur_nodes->elems[cur_idx];
-#ifdef DEBUG
-      re_token_type_t type = dfa->nodes[cur_node].type;
-      assert (!IS_EPSILON_NODE (type));
-#endif
-#ifdef RE_ENABLE_I18N
-      /* If the node may accept `multi byte'.  */
-      if (dfa->nodes[cur_node].accept_mb)
-       {
-         naccepted = check_node_accept_bytes (dfa, cur_node, &mctx->input,
-                                              str_idx);
-         if (naccepted > 1)
-           {
-             re_dfastate_t *dest_state;
-             Idx next_node = dfa->nexts[cur_node];
-             Idx next_idx = str_idx + naccepted;
-             dest_state = mctx->state_log[next_idx];
-             re_node_set_empty (&union_set);
-             if (dest_state)
-               {
-                 err = re_node_set_merge (&union_set, &dest_state->nodes);
-                 if (BE (err != REG_NOERROR, 0))
-                   {
-                     re_node_set_free (&union_set);
-                     return err;
-                   }
-               }
-             ok = re_node_set_insert (&union_set, next_node);
-             if (BE (! ok, 0))
-               {
-                 re_node_set_free (&union_set);
-                 return REG_ESPACE;
-               }
-             mctx->state_log[next_idx] = re_acquire_state (&err, dfa,
-                                                           &union_set);
-             if (BE (mctx->state_log[next_idx] == NULL
-                     && err != REG_NOERROR, 0))
-               {
-                 re_node_set_free (&union_set);
-                 return err;
-               }
-           }
-       }
-#endif /* RE_ENABLE_I18N */
-      if (naccepted
-         || check_node_accept (mctx, dfa->nodes + cur_node, str_idx))
-       {
-         ok = re_node_set_insert (next_nodes, dfa->nexts[cur_node]);
-         if (BE (! ok, 0))
-           {
-             re_node_set_free (&union_set);
-             return REG_ESPACE;
-           }
-       }
-    }
-  re_node_set_free (&union_set);
-  return REG_NOERROR;
-}
-
-/* For all the nodes in CUR_NODES, add the epsilon closures of them to
-   CUR_NODES, however exclude the nodes which are:
-    - inside the sub expression whose number is EX_SUBEXP, if FL_OPEN.
-    - out of the sub expression whose number is EX_SUBEXP, if !FL_OPEN.
-*/
-
-static reg_errcode_t
-internal_function
-check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes,
-                         Idx ex_subexp, int type)
-{
-  reg_errcode_t err;
-  Idx idx, outside_node;
-  re_node_set new_nodes;
-#ifdef DEBUG
-  assert (cur_nodes->nelem);
-#endif
-  err = re_node_set_alloc (&new_nodes, cur_nodes->nelem);
-  if (BE (err != REG_NOERROR, 0))
-    return err;
-  /* Create a new node set NEW_NODES with the nodes which are epsilon
-     closures of the node in CUR_NODES.  */
-
-  for (idx = 0; idx < cur_nodes->nelem; ++idx)
-    {
-      Idx cur_node = cur_nodes->elems[idx];
-      const re_node_set *eclosure = dfa->eclosures + cur_node;
-      outside_node = find_subexp_node (dfa, eclosure, ex_subexp, type);
-      if (outside_node == REG_MISSING)
-       {
-         /* There are no problematic nodes, just merge them.  */
-         err = re_node_set_merge (&new_nodes, eclosure);
-         if (BE (err != REG_NOERROR, 0))
-           {
-             re_node_set_free (&new_nodes);
-             return err;
-           }
-       }
-      else
-       {
-         /* There are problematic nodes, re-calculate incrementally.  */
-         err = check_arrival_expand_ecl_sub (dfa, &new_nodes, cur_node,
-                                             ex_subexp, type);
-         if (BE (err != REG_NOERROR, 0))
-           {
-             re_node_set_free (&new_nodes);
-             return err;
-           }
-       }
-    }
-  re_node_set_free (cur_nodes);
-  *cur_nodes = new_nodes;
-  return REG_NOERROR;
-}
-
-/* Helper function for check_arrival_expand_ecl.
-   Check incrementally the epsilon closure of TARGET, and if it isn't
-   problematic append it to DST_NODES.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes,
-                             Idx target, Idx ex_subexp, int type)
-{
-  Idx cur_node;
-  for (cur_node = target; !re_node_set_contains (dst_nodes, cur_node);)
-    {
-      bool ok;
-
-      if (dfa->nodes[cur_node].type == type
-         && dfa->nodes[cur_node].opr.idx == ex_subexp)
-       {
-         if (type == OP_CLOSE_SUBEXP)
-           {
-             ok = re_node_set_insert (dst_nodes, cur_node);
-             if (BE (! ok, 0))
-               return REG_ESPACE;
-           }
-         break;
-       }
-      ok = re_node_set_insert (dst_nodes, cur_node);
-      if (BE (! ok, 0))
-       return REG_ESPACE;
-      if (dfa->edests[cur_node].nelem == 0)
-       break;
-      if (dfa->edests[cur_node].nelem == 2)
-       {
-         reg_errcode_t err;
-         err = check_arrival_expand_ecl_sub (dfa, dst_nodes,
-                                             dfa->edests[cur_node].elems[1],
-                                             ex_subexp, type);
-         if (BE (err != REG_NOERROR, 0))
-           return err;
-       }
-      cur_node = dfa->edests[cur_node].elems[0];
-    }
-  return REG_NOERROR;
-}
-
-
-/* For all the back references in the current state, calculate the
-   destination of the back references by the appropriate entry
-   in MCTX->BKREF_ENTS.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes,
-                   Idx cur_str, Idx subexp_num, int type)
-{
-  const re_dfa_t *const dfa = mctx->dfa;
-  reg_errcode_t err;
-  Idx cache_idx_start = search_cur_bkref_entry (mctx, cur_str);
-  struct re_backref_cache_entry *ent;
-
-  if (cache_idx_start == REG_MISSING)
-    return REG_NOERROR;
-
- restart:
-  ent = mctx->bkref_ents + cache_idx_start;
-  do
-    {
-      Idx to_idx, next_node;
-
-      /* Is this entry ENT is appropriate?  */
-      if (!re_node_set_contains (cur_nodes, ent->node))
-       continue; /* No.  */
-
-      to_idx = cur_str + ent->subexp_to - ent->subexp_from;
-      /* Calculate the destination of the back reference, and append it
-        to MCTX->STATE_LOG.  */
-      if (to_idx == cur_str)
-       {
-         /* The backreference did epsilon transit, we must re-check all the
-            node in the current state.  */
-         re_node_set new_dests;
-         reg_errcode_t err2, err3;
-         next_node = dfa->edests[ent->node].elems[0];
-         if (re_node_set_contains (cur_nodes, next_node))
-           continue;
-         err = re_node_set_init_1 (&new_dests, next_node);
-         err2 = check_arrival_expand_ecl (dfa, &new_dests, subexp_num, type);
-         err3 = re_node_set_merge (cur_nodes, &new_dests);
-         re_node_set_free (&new_dests);
-         if (BE (err != REG_NOERROR || err2 != REG_NOERROR
-                 || err3 != REG_NOERROR, 0))
-           {
-             err = (err != REG_NOERROR ? err
-                    : (err2 != REG_NOERROR ? err2 : err3));
-             return err;
-           }
-         /* TODO: It is still inefficient...  */
-         goto restart;
-       }
-      else
-       {
-         re_node_set union_set;
-         next_node = dfa->nexts[ent->node];
-         if (mctx->state_log[to_idx])
-           {
-             bool ok;
-             if (re_node_set_contains (&mctx->state_log[to_idx]->nodes,
-                                       next_node))
-               continue;
-             err = re_node_set_init_copy (&union_set,
-                                          &mctx->state_log[to_idx]->nodes);
-             ok = re_node_set_insert (&union_set, next_node);
-             if (BE (err != REG_NOERROR || ! ok, 0))
-               {
-                 re_node_set_free (&union_set);
-                 err = err != REG_NOERROR ? err : REG_ESPACE;
-                 return err;
-               }
-           }
-         else
-           {
-             err = re_node_set_init_1 (&union_set, next_node);
-             if (BE (err != REG_NOERROR, 0))
-               return err;
-           }
-         mctx->state_log[to_idx] = re_acquire_state (&err, dfa, &union_set);
-         re_node_set_free (&union_set);
-         if (BE (mctx->state_log[to_idx] == NULL
-                 && err != REG_NOERROR, 0))
-           return err;
-       }
-    }
-  while (ent++->more);
-  return REG_NOERROR;
-}
-
-/* Build transition table for the state.
-   Return true if successful.  */
-
-static bool
-internal_function
-build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
-{
-  reg_errcode_t err;
-  Idx i, j;
-  int ch;
-  bool need_word_trtable = false;
-  bitset_word_t elem, mask;
-  bool dests_node_malloced = false;
-  bool dest_states_malloced = false;
-  Idx ndests; /* Number of the destination states from `state'.  */
-  re_dfastate_t **trtable;
-  re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl;
-  re_node_set follows, *dests_node;
-  bitset_t *dests_ch;
-  bitset_t acceptable;
-
-  struct dests_alloc
-  {
-    re_node_set dests_node[SBC_MAX];
-    bitset_t dests_ch[SBC_MAX];
-  } *dests_alloc;
-
-  /* We build DFA states which corresponds to the destination nodes
-     from `state'.  `dests_node[i]' represents the nodes which i-th
-     destination state contains, and `dests_ch[i]' represents the
-     characters which i-th destination state accepts.  */
-  if (__libc_use_alloca (sizeof (struct dests_alloc)))
-    dests_alloc = (struct dests_alloc *) alloca (sizeof (struct dests_alloc));
-  else
-    {
-      dests_alloc = re_malloc (struct dests_alloc, 1);
-      if (BE (dests_alloc == NULL, 0))
-       return false;
-      dests_node_malloced = true;
-    }
-  dests_node = dests_alloc->dests_node;
-  dests_ch = dests_alloc->dests_ch;
-
-  /* Initialize transiton table.  */
-  state->word_trtable = state->trtable = NULL;
-
-  /* At first, group all nodes belonging to `state' into several
-     destinations.  */
-  ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch);
-  if (BE (! REG_VALID_NONZERO_INDEX (ndests), 0))
-    {
-      if (dests_node_malloced)
-       free (dests_alloc);
-      if (ndests == 0)
-       {
-         state->trtable = (re_dfastate_t **)
-           calloc (sizeof (re_dfastate_t *), SBC_MAX);
-         return true;
-       }
-      return false;
-    }
-
-  err = re_node_set_alloc (&follows, ndests + 1);
-  if (BE (err != REG_NOERROR, 0))
-    goto out_free;
-
-  /* Avoid arithmetic overflow in size calculation.  */
-  if (BE ((((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX)
-           / (3 * sizeof (re_dfastate_t *)))
-          < ndests),
-         0))
-    goto out_free;
-
-  if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX
-                        + ndests * 3 * sizeof (re_dfastate_t *)))
-    dest_states = (re_dfastate_t **)
-      alloca (ndests * 3 * sizeof (re_dfastate_t *));
-  else
-    {
-      dest_states = (re_dfastate_t **)
-       malloc (ndests * 3 * sizeof (re_dfastate_t *));
-      if (BE (dest_states == NULL, 0))
-       {
-out_free:
-         if (dest_states_malloced)
-           free (dest_states);
-         re_node_set_free (&follows);
-         for (i = 0; i < ndests; ++i)
-           re_node_set_free (dests_node + i);
-         if (dests_node_malloced)
-           free (dests_alloc);
-         return false;
-       }
-      dest_states_malloced = true;
-    }
-  dest_states_word = dest_states + ndests;
-  dest_states_nl = dest_states_word + ndests;
-  bitset_empty (acceptable);
-
-  /* Then build the states for all destinations.  */
-  for (i = 0; i < ndests; ++i)
-    {
-      Idx next_node;
-      re_node_set_empty (&follows);
-      /* Merge the follows of this destination states.  */
-      for (j = 0; j < dests_node[i].nelem; ++j)
-       {
-         next_node = dfa->nexts[dests_node[i].elems[j]];
-         if (next_node != REG_MISSING)
-           {
-             err = re_node_set_merge (&follows, dfa->eclosures + next_node);
-             if (BE (err != REG_NOERROR, 0))
-               goto out_free;
-           }
-       }
-      dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0);
-      if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0))
-       goto out_free;
-      /* If the new state has context constraint,
-        build appropriate states for these contexts.  */
-      if (dest_states[i]->has_constraint)
-       {
-         dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows,
-                                                         CONTEXT_WORD);
-         if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
-           goto out_free;
-
-         if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)
-           need_word_trtable = true;
-
-         dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
-                                                       CONTEXT_NEWLINE);
-         if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0))
-           goto out_free;
-       }
-      else
-       {
-         dest_states_word[i] = dest_states[i];
-         dest_states_nl[i] = dest_states[i];
-       }
-      bitset_merge (acceptable, dests_ch[i]);
-    }
-
-  if (!BE (need_word_trtable, 0))
-    {
-      /* We don't care about whether the following character is a word
-        character, or we are in a single-byte character set so we can
-        discern by looking at the character code: allocate a
-        256-entry transition table.  */
-      trtable = state->trtable =
-       (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);
-      if (BE (trtable == NULL, 0))
-       goto out_free;
-
-      /* For all characters ch...:  */
-      for (i = 0; i < BITSET_WORDS; ++i)
-       for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;
-            elem;
-            mask <<= 1, elem >>= 1, ++ch)
-         if (BE (elem & 1, 0))
-           {
-             /* There must be exactly one destination which accepts
-                character ch.  See group_nodes_into_DFAstates.  */
-             for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)
-               ;
-
-             /* j-th destination accepts the word character ch.  */
-             if (dfa->word_char[i] & mask)
-               trtable[ch] = dest_states_word[j];
-             else
-               trtable[ch] = dest_states[j];
-           }
-    }
-  else
-    {
-      /* We care about whether the following character is a word
-        character, and we are in a multi-byte character set: discern
-        by looking at the character code: build two 256-entry
-        transition tables, one starting at trtable[0] and one
-        starting at trtable[SBC_MAX].  */
-      trtable = state->word_trtable =
-       (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX);
-      if (BE (trtable == NULL, 0))
-       goto out_free;
-
-      /* For all characters ch...:  */
-      for (i = 0; i < BITSET_WORDS; ++i)
-       for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;
-            elem;
-            mask <<= 1, elem >>= 1, ++ch)
-         if (BE (elem & 1, 0))
-           {
-             /* There must be exactly one destination which accepts
-                character ch.  See group_nodes_into_DFAstates.  */
-             for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)
-               ;
-
-             /* j-th destination accepts the word character ch.  */
-             trtable[ch] = dest_states[j];
-             trtable[ch + SBC_MAX] = dest_states_word[j];
-           }
-    }
-
-  /* new line */
-  if (bitset_contain (acceptable, NEWLINE_CHAR))
-    {
-      /* The current state accepts newline character.  */
-      for (j = 0; j < ndests; ++j)
-       if (bitset_contain (dests_ch[j], NEWLINE_CHAR))
-         {
-           /* k-th destination accepts newline character.  */
-           trtable[NEWLINE_CHAR] = dest_states_nl[j];
-           if (need_word_trtable)
-             trtable[NEWLINE_CHAR + SBC_MAX] = dest_states_nl[j];
-           /* There must be only one destination which accepts
-              newline.  See group_nodes_into_DFAstates.  */
-           break;
-         }
-    }
-
-  if (dest_states_malloced)
-    free (dest_states);
-
-  re_node_set_free (&follows);
-  for (i = 0; i < ndests; ++i)
-    re_node_set_free (dests_node + i);
-
-  if (dests_node_malloced)
-    free (dests_alloc);
-
-  return true;
-}
-
-/* Group all nodes belonging to STATE into several destinations.
-   Then for all destinations, set the nodes belonging to the destination
-   to DESTS_NODE[i] and set the characters accepted by the destination
-   to DEST_CH[i].  This function return the number of destinations.  */
-
-static Idx
-internal_function
-group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
-                           re_node_set *dests_node, bitset_t *dests_ch)
-{
-  reg_errcode_t err;
-  bool ok;
-  Idx i, j, k;
-  Idx ndests; /* Number of the destinations from `state'.  */
-  bitset_t accepts; /* Characters a node can accept.  */
-  const re_node_set *cur_nodes = &state->nodes;
-  bitset_empty (accepts);
-  ndests = 0;
-
-  /* For all the nodes belonging to `state',  */
-  for (i = 0; i < cur_nodes->nelem; ++i)
-    {
-      re_token_t *node = &dfa->nodes[cur_nodes->elems[i]];
-      re_token_type_t type = node->type;
-      unsigned int constraint = node->constraint;
-
-      /* Enumerate all single byte character this node can accept.  */
-      if (type == CHARACTER)
-       bitset_set (accepts, node->opr.c);
-      else if (type == SIMPLE_BRACKET)
-       {
-         bitset_merge (accepts, node->opr.sbcset);
-       }
-      else if (type == OP_PERIOD)
-       {
-#ifdef RE_ENABLE_I18N
-         if (dfa->mb_cur_max > 1)
-           bitset_merge (accepts, dfa->sb_char);
-         else
-#endif
-           bitset_set_all (accepts);
-         if (!(dfa->syntax & RE_DOT_NEWLINE))
-           bitset_clear (accepts, '\n');
-         if (dfa->syntax & RE_DOT_NOT_NULL)
-           bitset_clear (accepts, '\0');
-       }
-#ifdef RE_ENABLE_I18N
-      else if (type == OP_UTF8_PERIOD)
-       {
-         if (ASCII_CHARS % BITSET_WORD_BITS == 0)
-           memset (accepts, -1, ASCII_CHARS / CHAR_BIT);
-         else
-           bitset_merge (accepts, utf8_sb_map);
-         if (!(dfa->syntax & RE_DOT_NEWLINE))
-           bitset_clear (accepts, '\n');
-         if (dfa->syntax & RE_DOT_NOT_NULL)
-           bitset_clear (accepts, '\0');
-       }
-#endif
-      else
-       continue;
-
-      /* Check the `accepts' and sift the characters which are not
-        match it the context.  */
-      if (constraint)
-       {
-         if (constraint & NEXT_NEWLINE_CONSTRAINT)
-           {
-             bool accepts_newline = bitset_contain (accepts, NEWLINE_CHAR);
-             bitset_empty (accepts);
-             if (accepts_newline)
-               bitset_set (accepts, NEWLINE_CHAR);
-             else
-               continue;
-           }
-         if (constraint & NEXT_ENDBUF_CONSTRAINT)
-           {
-             bitset_empty (accepts);
-             continue;
-           }
-
-         if (constraint & NEXT_WORD_CONSTRAINT)
-           {
-             bitset_word_t any_set = 0;
-             if (type == CHARACTER && !node->word_char)
-               {
-                 bitset_empty (accepts);
-                 continue;
-               }
-#ifdef RE_ENABLE_I18N
-             if (dfa->mb_cur_max > 1)
-               for (j = 0; j < BITSET_WORDS; ++j)
-                 any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j]));
-             else
-#endif
-               for (j = 0; j < BITSET_WORDS; ++j)
-                 any_set |= (accepts[j] &= dfa->word_char[j]);
-             if (!any_set)
-               continue;
-           }
-         if (constraint & NEXT_NOTWORD_CONSTRAINT)
-           {
-             bitset_word_t any_set = 0;
-             if (type == CHARACTER && node->word_char)
-               {
-                 bitset_empty (accepts);
-                 continue;
-               }
-#ifdef RE_ENABLE_I18N
-             if (dfa->mb_cur_max > 1)
-               for (j = 0; j < BITSET_WORDS; ++j)
-                 any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j]));
-             else
-#endif
-               for (j = 0; j < BITSET_WORDS; ++j)
-                 any_set |= (accepts[j] &= ~dfa->word_char[j]);
-             if (!any_set)
-               continue;
-           }
-       }
-
-      /* Then divide `accepts' into DFA states, or create a new
-        state.  Above, we make sure that accepts is not empty.  */
-      for (j = 0; j < ndests; ++j)
-       {
-         bitset_t intersec; /* Intersection sets, see below.  */
-         bitset_t remains;
-         /* Flags, see below.  */
-         bitset_word_t has_intersec, not_subset, not_consumed;
-
-         /* Optimization, skip if this state doesn't accept the character.  */
-         if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c))
-           continue;
-
-         /* Enumerate the intersection set of this state and `accepts'.  */
-         has_intersec = 0;
-         for (k = 0; k < BITSET_WORDS; ++k)
-           has_intersec |= intersec[k] = accepts[k] & dests_ch[j][k];
-         /* And skip if the intersection set is empty.  */
-         if (!has_intersec)
-           continue;
-
-         /* Then check if this state is a subset of `accepts'.  */
-         not_subset = not_consumed = 0;
-         for (k = 0; k < BITSET_WORDS; ++k)
-           {
-             not_subset |= remains[k] = ~accepts[k] & dests_ch[j][k];
-             not_consumed |= accepts[k] = accepts[k] & ~dests_ch[j][k];
-           }
-
-         /* If this state isn't a subset of `accepts', create a
-            new group state, which has the `remains'. */
-         if (not_subset)
-           {
-             bitset_copy (dests_ch[ndests], remains);
-             bitset_copy (dests_ch[j], intersec);
-             err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]);
-             if (BE (err != REG_NOERROR, 0))
-               goto error_return;
-             ++ndests;
-           }
-
-         /* Put the position in the current group. */
-         ok = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);
-         if (BE (! ok, 0))
-           goto error_return;
-
-         /* If all characters are consumed, go to next node. */
-         if (!not_consumed)
-           break;
-       }
-      /* Some characters remain, create a new group. */
-      if (j == ndests)
-       {
-         bitset_copy (dests_ch[ndests], accepts);
-         err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]);
-         if (BE (err != REG_NOERROR, 0))
-           goto error_return;
-         ++ndests;
-         bitset_empty (accepts);
-       }
-    }
-  return ndests;
- error_return:
-  for (j = 0; j < ndests; ++j)
-    re_node_set_free (dests_node + j);
-  return REG_MISSING;
-}
-
-#ifdef RE_ENABLE_I18N
-/* Check how many bytes the node `dfa->nodes[node_idx]' accepts.
-   Return the number of the bytes the node accepts.
-   STR_IDX is the current index of the input string.
-
-   This function handles the nodes which can accept one character, or
-   one collating element like '.', '[a-z]', opposite to the other nodes
-   can only accept one byte.  */
-
-static int
-internal_function
-check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
-                        const re_string_t *input, Idx str_idx)
-{
-  const re_token_t *node = dfa->nodes + node_idx;
-  int char_len, elem_len;
-  Idx i;
-
-  if (BE (node->type == OP_UTF8_PERIOD, 0))
-    {
-      unsigned char c = re_string_byte_at (input, str_idx), d;
-      if (BE (c < 0xc2, 1))
-       return 0;
-
-      if (str_idx + 2 > input->len)
-       return 0;
-
-      d = re_string_byte_at (input, str_idx + 1);
-      if (c < 0xe0)
-       return (d < 0x80 || d > 0xbf) ? 0 : 2;
-      else if (c < 0xf0)
-       {
-         char_len = 3;
-         if (c == 0xe0 && d < 0xa0)
-           return 0;
-       }
-      else if (c < 0xf8)
-       {
-         char_len = 4;
-         if (c == 0xf0 && d < 0x90)
-           return 0;
-       }
-      else if (c < 0xfc)
-       {
-         char_len = 5;
-         if (c == 0xf8 && d < 0x88)
-           return 0;
-       }
-      else if (c < 0xfe)
-       {
-         char_len = 6;
-         if (c == 0xfc && d < 0x84)
-           return 0;
-       }
-      else
-       return 0;
-
-      if (str_idx + char_len > input->len)
-       return 0;
-
-      for (i = 1; i < char_len; ++i)
-       {
-         d = re_string_byte_at (input, str_idx + i);
-         if (d < 0x80 || d > 0xbf)
-           return 0;
-       }
-      return char_len;
-    }
-
-  char_len = re_string_char_size_at (input, str_idx);
-  if (node->type == OP_PERIOD)
-    {
-      if (char_len <= 1)
-       return 0;
-      /* FIXME: I don't think this if is needed, as both '\n'
-        and '\0' are char_len == 1.  */
-      /* '.' accepts any one character except the following two cases.  */
-      if ((!(dfa->syntax & RE_DOT_NEWLINE) &&
-          re_string_byte_at (input, str_idx) == '\n') ||
-         ((dfa->syntax & RE_DOT_NOT_NULL) &&
-          re_string_byte_at (input, str_idx) == '\0'))
-       return 0;
-      return char_len;
-    }
-
-  elem_len = re_string_elem_size_at (input, str_idx);
-  if ((elem_len <= 1 && char_len <= 1) || char_len == 0)
-    return 0;
-
-  if (node->type == COMPLEX_BRACKET)
-    {
-      const re_charset_t *cset = node->opr.mbcset;
-# ifdef _LIBC
-      const unsigned char *pin
-       = ((const unsigned char *) re_string_get_buffer (input) + str_idx);
-      Idx j;
-      uint32_t nrules;
-# endif /* _LIBC */
-      int match_len = 0;
-      wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)
-                   ? re_string_wchar_at (input, str_idx) : 0);
-
-      /* match with multibyte character?  */
-      for (i = 0; i < cset->nmbchars; ++i)
-       if (wc == cset->mbchars[i])
-         {
-           match_len = char_len;
-           goto check_node_accept_bytes_match;
-         }
-      /* match with character_class?  */
-      for (i = 0; i < cset->nchar_classes; ++i)
-       {
-         wctype_t wt = cset->char_classes[i];
-         if (__iswctype (wc, wt))
-           {
-             match_len = char_len;
-             goto check_node_accept_bytes_match;
-           }
-       }
-
-# ifdef _LIBC
-      nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-      if (nrules != 0)
-       {
-         unsigned int in_collseq = 0;
-         const int32_t *table, *indirect;
-         const unsigned char *weights, *extra;
-         const char *collseqwc;
-         int32_t idx;
-         /* This #include defines a local function!  */
-#  include <locale/weight.h>
-
-         /* match with collating_symbol?  */
-         if (cset->ncoll_syms)
-           extra = (const unsigned char *)
-             _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
-         for (i = 0; i < cset->ncoll_syms; ++i)
-           {
-             const unsigned char *coll_sym = extra + cset->coll_syms[i];
-             /* Compare the length of input collating element and
-                the length of current collating element.  */
-             if (*coll_sym != elem_len)
-               continue;
-             /* Compare each bytes.  */
-             for (j = 0; j < *coll_sym; j++)
-               if (pin[j] != coll_sym[1 + j])
-                 break;
-             if (j == *coll_sym)
-               {
-                 /* Match if every bytes is equal.  */
-                 match_len = j;
-                 goto check_node_accept_bytes_match;
-               }
-           }
-
-         if (cset->nranges)
-           {
-             if (elem_len <= char_len)
-               {
-                 collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);
-                 in_collseq = __collseq_table_lookup (collseqwc, wc);
-               }
-             else
-               in_collseq = find_collation_sequence_value (pin, elem_len);
-           }
-         /* match with range expression?  */
-         for (i = 0; i < cset->nranges; ++i)
-           if (cset->range_starts[i] <= in_collseq
-               && in_collseq <= cset->range_ends[i])
-             {
-               match_len = elem_len;
-               goto check_node_accept_bytes_match;
-             }
-
-         /* match with equivalence_class?  */
-         if (cset->nequiv_classes)
-           {
-             const unsigned char *cp = pin;
-             table = (const int32_t *)
-               _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
-             weights = (const unsigned char *)
-               _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
-             extra = (const unsigned char *)
-               _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
-             indirect = (const int32_t *)
-               _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
-             int32_t idx = findidx (&cp);
-             if (idx > 0)
-               for (i = 0; i < cset->nequiv_classes; ++i)
-                 {
-                   int32_t equiv_class_idx = cset->equiv_classes[i];
-                   size_t weight_len = weights[idx & 0xffffff];
-                   if (weight_len == weights[equiv_class_idx & 0xffffff]
-                       && (idx >> 24) == (equiv_class_idx >> 24))
-                     {
-                       Idx cnt = 0;
-
-                       idx &= 0xffffff;
-                       equiv_class_idx &= 0xffffff;
-
-                       while (cnt <= weight_len
-                              && (weights[equiv_class_idx + 1 + cnt]
-                                  == weights[idx + 1 + cnt]))
-                         ++cnt;
-                       if (cnt > weight_len)
-                         {
-                           match_len = elem_len;
-                           goto check_node_accept_bytes_match;
-                         }
-                     }
-                 }
-           }
-       }
-      else
-# endif /* _LIBC */
-       {
-         /* match with range expression?  */
-#if __GNUC__ >= 2 && ! (__STDC_VERSION__ < 199901L && __STRICT_ANSI__)
-         wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'};
-#else
-         wchar_t cmp_buf[] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'};
-         cmp_buf[2] = wc;
-#endif
-         for (i = 0; i < cset->nranges; ++i)
-           {
-             cmp_buf[0] = cset->range_starts[i];
-             cmp_buf[4] = cset->range_ends[i];
-             if (wcscoll (cmp_buf, cmp_buf + 2) <= 0
-                 && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0)
-               {
-                 match_len = char_len;
-                 goto check_node_accept_bytes_match;
-               }
-           }
-       }
-    check_node_accept_bytes_match:
-      if (!cset->non_match)
-       return match_len;
-      else
-       {
-         if (match_len > 0)
-           return 0;
-         else
-           return (elem_len > char_len) ? elem_len : char_len;
-       }
-    }
-  return 0;
-}
-
-# ifdef _LIBC
-static unsigned int
-internal_function
-find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
-{
-  uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
-  if (nrules == 0)
-    {
-      if (mbs_len == 1)
-       {
-         /* No valid character.  Match it as a single byte character.  */
-         const unsigned char *collseq = (const unsigned char *)
-           _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
-         return collseq[mbs[0]];
-       }
-      return UINT_MAX;
-    }
-  else
-    {
-      int32_t idx;
-      const unsigned char *extra = (const unsigned char *)
-       _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
-      int32_t extrasize = (const unsigned char *)
-       _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB + 1) - extra;
-
-      for (idx = 0; idx < extrasize;)
-       {
-         int mbs_cnt;
-         bool found = false;
-         int32_t elem_mbs_len;
-         /* Skip the name of collating element name.  */
-         idx = idx + extra[idx] + 1;
-         elem_mbs_len = extra[idx++];
-         if (mbs_len == elem_mbs_len)
-           {
-             for (mbs_cnt = 0; mbs_cnt < elem_mbs_len; ++mbs_cnt)
-               if (extra[idx + mbs_cnt] != mbs[mbs_cnt])
-                 break;
-             if (mbs_cnt == elem_mbs_len)
-               /* Found the entry.  */
-               found = true;
-           }
-         /* Skip the byte sequence of the collating element.  */
-         idx += elem_mbs_len;
-         /* Adjust for the alignment.  */
-         idx = (idx + 3) & ~3;
-         /* Skip the collation sequence value.  */
-         idx += sizeof (uint32_t);
-         /* Skip the wide char sequence of the collating element.  */
-         idx = idx + sizeof (uint32_t) * (extra[idx] + 1);
-         /* If we found the entry, return the sequence value.  */
-         if (found)
-           return *(uint32_t *) (extra + idx);
-         /* Skip the collation sequence value.  */
-         idx += sizeof (uint32_t);
-       }
-      return UINT_MAX;
-    }
-}
-# endif /* _LIBC */
-#endif /* RE_ENABLE_I18N */
-
-/* Check whether the node accepts the byte which is IDX-th
-   byte of the INPUT.  */
-
-static bool
-internal_function
-check_node_accept (const re_match_context_t *mctx, const re_token_t *node,
-                  Idx idx)
-{
-  unsigned char ch;
-  ch = re_string_byte_at (&mctx->input, idx);
-  switch (node->type)
-    {
-    case CHARACTER:
-      if (node->opr.c != ch)
-        return false;
-      break;
-
-    case SIMPLE_BRACKET:
-      if (!bitset_contain (node->opr.sbcset, ch))
-        return false;
-      break;
-
-#ifdef RE_ENABLE_I18N
-    case OP_UTF8_PERIOD:
-      if (ch >= ASCII_CHARS)
-        return false;
-      /* FALLTHROUGH */
-#endif
-    case OP_PERIOD:
-      if ((ch == '\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE))
-         || (ch == '\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL)))
-       return false;
-      break;
-
-    default:
-      return false;
-    }
-
-  if (node->constraint)
-    {
-      /* The node has constraints.  Check whether the current context
-        satisfies the constraints.  */
-      unsigned int context = re_string_context_at (&mctx->input, idx,
-                                                  mctx->eflags);
-      if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))
-       return false;
-    }
-
-  return true;
-}
-
-/* Extend the buffers, if the buffers have run out.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-extend_buffers (re_match_context_t *mctx)
-{
-  reg_errcode_t ret;
-  re_string_t *pstr = &mctx->input;
-
-  /* Avoid overflow.  */
-  if (BE (SIZE_MAX / 2 / sizeof (re_dfastate_t *) <= pstr->bufs_len, 0))
-    return REG_ESPACE;
-
-  /* Double the lengthes of the buffers.  */
-  ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
-  if (BE (ret != REG_NOERROR, 0))
-    return ret;
-
-  if (mctx->state_log != NULL)
-    {
-      /* And double the length of state_log.  */
-      /* XXX We have no indication of the size of this buffer.  If this
-        allocation fail we have no indication that the state_log array
-        does not have the right size.  */
-      re_dfastate_t **new_array = re_realloc (mctx->state_log, re_dfastate_t *,
-                                             pstr->bufs_len + 1);
-      if (BE (new_array == NULL, 0))
-       return REG_ESPACE;
-      mctx->state_log = new_array;
-    }
-
-  /* Then reconstruct the buffers.  */
-  if (pstr->icase)
-    {
-#ifdef RE_ENABLE_I18N
-      if (pstr->mb_cur_max > 1)
-       {
-         ret = build_wcs_upper_buffer (pstr);
-         if (BE (ret != REG_NOERROR, 0))
-           return ret;
-       }
-      else
-#endif /* RE_ENABLE_I18N  */
-       build_upper_buffer (pstr);
-    }
-  else
-    {
-#ifdef RE_ENABLE_I18N
-      if (pstr->mb_cur_max > 1)
-       build_wcs_buffer (pstr);
-      else
-#endif /* RE_ENABLE_I18N  */
-       {
-         if (pstr->trans != NULL)
-           re_string_translate_buffer (pstr);
-       }
-    }
-  return REG_NOERROR;
-}
-
-\f
-/* Functions for matching context.  */
-
-/* Initialize MCTX.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-match_ctx_init (re_match_context_t *mctx, int eflags, Idx n)
-{
-  mctx->eflags = eflags;
-  mctx->match_last = REG_MISSING;
-  if (n > 0)
-    {
-      /* Avoid overflow.  */
-      size_t max_object_size =
-       MAX (sizeof (struct re_backref_cache_entry),
-            sizeof (re_sub_match_top_t *));
-      if (BE (SIZE_MAX / max_object_size < n, 0))
-       return REG_ESPACE;
-
-      mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n);
-      mctx->sub_tops = re_malloc (re_sub_match_top_t *, n);
-      if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0))
-       return REG_ESPACE;
-    }
-  /* Already zero-ed by the caller.
-     else
-       mctx->bkref_ents = NULL;
-     mctx->nbkref_ents = 0;
-     mctx->nsub_tops = 0;  */
-  mctx->abkref_ents = n;
-  mctx->max_mb_elem_len = 1;
-  mctx->asub_tops = n;
-  return REG_NOERROR;
-}
-
-/* Clean the entries which depend on the current input in MCTX.
-   This function must be invoked when the matcher changes the start index
-   of the input, or changes the input string.  */
-
-static void
-internal_function
-match_ctx_clean (re_match_context_t *mctx)
-{
-  Idx st_idx;
-  for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx)
-    {
-      Idx sl_idx;
-      re_sub_match_top_t *top = mctx->sub_tops[st_idx];
-      for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx)
-       {
-         re_sub_match_last_t *last = top->lasts[sl_idx];
-         re_free (last->path.array);
-         re_free (last);
-       }
-      re_free (top->lasts);
-      if (top->path)
-       {
-         re_free (top->path->array);
-         re_free (top->path);
-       }
-      free (top);
-    }
-
-  mctx->nsub_tops = 0;
-  mctx->nbkref_ents = 0;
-}
-
-/* Free all the memory associated with MCTX.  */
-
-static void
-internal_function
-match_ctx_free (re_match_context_t *mctx)
-{
-  /* First, free all the memory associated with MCTX->SUB_TOPS.  */
-  match_ctx_clean (mctx);
-  re_free (mctx->sub_tops);
-  re_free (mctx->bkref_ents);
-}
-
-/* Add a new backreference entry to MCTX.
-   Note that we assume that caller never call this function with duplicate
-   entry, and call with STR_IDX which isn't smaller than any existing entry.
-*/
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-match_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx, Idx from,
-                    Idx to)
-{
-  if (mctx->nbkref_ents >= mctx->abkref_ents)
-    {
-      struct re_backref_cache_entry* new_entry;
-      new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry,
-                             mctx->abkref_ents * 2);
-      if (BE (new_entry == NULL, 0))
-       {
-         re_free (mctx->bkref_ents);
-         return REG_ESPACE;
-       }
-      mctx->bkref_ents = new_entry;
-      memset (mctx->bkref_ents + mctx->nbkref_ents, '\0',
-             sizeof (struct re_backref_cache_entry) * mctx->abkref_ents);
-      mctx->abkref_ents *= 2;
-    }
-  if (mctx->nbkref_ents > 0
-      && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx)
-    mctx->bkref_ents[mctx->nbkref_ents - 1].more = 1;
-
-  mctx->bkref_ents[mctx->nbkref_ents].node = node;
-  mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx;
-  mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from;
-  mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to;
-
-  /* This is a cache that saves negative results of check_dst_limits_calc_pos.
-     If bit N is clear, means that this entry won't epsilon-transition to
-     an OP_OPEN_SUBEXP or OP_CLOSE_SUBEXP for the N+1-th subexpression.  If
-     it is set, check_dst_limits_calc_pos_1 will recurse and try to find one
-     such node.
-
-     A backreference does not epsilon-transition unless it is empty, so set
-     to all zeros if FROM != TO.  */
-  mctx->bkref_ents[mctx->nbkref_ents].eps_reachable_subexps_map
-    = (from == to ? -1 : 0);
-
-  mctx->bkref_ents[mctx->nbkref_ents++].more = 0;
-  if (mctx->max_mb_elem_len < to - from)
-    mctx->max_mb_elem_len = to - from;
-  return REG_NOERROR;
-}
-
-/* Return the first entry with the same str_idx, or REG_MISSING if none is
-   found.  Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX.  */
-
-static Idx
-internal_function
-search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx)
-{
-  Idx left, right, mid, last;
-  last = right = mctx->nbkref_ents;
-  for (left = 0; left < right;)
-    {
-      mid = (left + right) / 2;
-      if (mctx->bkref_ents[mid].str_idx < str_idx)
-       left = mid + 1;
-      else
-       right = mid;
-    }
-  if (left < last && mctx->bkref_ents[left].str_idx == str_idx)
-    return left;
-  else
-    return REG_MISSING;
-}
-
-/* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches
-   at STR_IDX.  */
-
-static reg_errcode_t
-internal_function __attribute_warn_unused_result__
-match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx)
-{
-#ifdef DEBUG
-  assert (mctx->sub_tops != NULL);
-  assert (mctx->asub_tops > 0);
-#endif
-  if (BE (mctx->nsub_tops == mctx->asub_tops, 0))
-    {
-      Idx new_asub_tops = mctx->asub_tops * 2;
-      re_sub_match_top_t **new_array = re_realloc (mctx->sub_tops,
-                                                  re_sub_match_top_t *,
-                                                  new_asub_tops);
-      if (BE (new_array == NULL, 0))
-       return REG_ESPACE;
-      mctx->sub_tops = new_array;
-      mctx->asub_tops = new_asub_tops;
-    }
-  mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t));
-  if (BE (mctx->sub_tops[mctx->nsub_tops] == NULL, 0))
-    return REG_ESPACE;
-  mctx->sub_tops[mctx->nsub_tops]->node = node;
-  mctx->sub_tops[mctx->nsub_tops++]->str_idx = str_idx;
-  return REG_NOERROR;
-}
-
-/* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches
-   at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP.  */
-
-static re_sub_match_last_t *
-internal_function
-match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx)
-{
-  re_sub_match_last_t *new_entry;
-  if (BE (subtop->nlasts == subtop->alasts, 0))
-    {
-      Idx new_alasts = 2 * subtop->alasts + 1;
-      re_sub_match_last_t **new_array = re_realloc (subtop->lasts,
-                                                   re_sub_match_last_t *,
-                                                   new_alasts);
-      if (BE (new_array == NULL, 0))
-       return NULL;
-      subtop->lasts = new_array;
-      subtop->alasts = new_alasts;
-    }
-  new_entry = calloc (1, sizeof (re_sub_match_last_t));
-  if (BE (new_entry != NULL, 1))
-    {
-      subtop->lasts[subtop->nlasts] = new_entry;
-      new_entry->node = node;
-      new_entry->str_idx = str_idx;
-      ++subtop->nlasts;
-    }
-  return new_entry;
-}
-
-static void
-internal_function
-sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
-              re_dfastate_t **limited_sts, Idx last_node, Idx last_str_idx)
-{
-  sctx->sifted_states = sifted_sts;
-  sctx->limited_states = limited_sts;
-  sctx->last_node = last_node;
-  sctx->last_str_idx = last_str_idx;
-  re_node_set_init_empty (&sctx->limits);
-}
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
new file mode 100644 (file)
index 0000000..1f26576
--- /dev/null
@@ -0,0 +1,155 @@
+AUTOMAKE_OPTIONS = subdir-objects
+SUBDIRS = po
+DEPDIR = .deps-core
+
+include $(top_srcdir)/Makefile.extra-dist
+include $(top_srcdir)/Makefile.vars
+
+LDADD_KERNEL = -lgcc
+CFLAGS_KERNEL = $(TARGET_CFLAGS) $(CFLAGS_CPU) $(CFLAGS_PLATFORM) -ffreestanding
+LDFLAGS_KERNEL = $(TARGET_LDFLAGS) $(LDFLAGS_CPU) $(LDFLAGS_PLATFORM) -nostdlib -Wl,-N -static-libgcc
+CPPFLAGS_KERNEL = $(TARGET_CPPFLAGS) $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM)
+CCASFLAGS_KERNEL = $(TARGET_CCASFLAGS) $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM)
+
+CFLAGS_MODULE = $(TARGET_CFLAGS) $(CFLAGS_CPU) $(CFLAGS_PLATFORM) -ffreestanding
+LDFLAGS_MODULE = $(TARGET_LDFLAGS) $(LDFLAGS_CPU) $(LDFLAGS_PLATFORM) -nostdlib -Wl,-N,-r,-d
+CPPFLAGS_MODULE = $(TARGET_CPPFLAGS) $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM)
+CCASFLAGS_MODULE = $(TARGET_CCASFLAGS) $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM)
+
+CFLAGS_IMAGE = $(TARGET_CFLAGS) $(CFLAGS_CPU) $(CFLAGS_PLATFORM) -fno-builtin
+LDFLAGS_IMAGE = $(TARGET_LDFLAGS) $(LDFLAGS_CPU) $(LDFLAGS_PLATFORM) -nostdlib -Wl,-N,-S
+CPPFLAGS_IMAGE = $(TARGET_CPPFLAGS) $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM)
+CCASFLAGS_IMAGE = $(TARGET_CCASFLAGS) $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM)
+
+CFLAGS_LIBRARY = $(TARGET_CFLAGS) $(CFLAGS_CPU) $(CFLAGS_PLATFORM) -fno-builtin
+CPPFLAGS_LIBRARY = $(TARGET_CPPFLAGS) $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM)
+CCASFLAGS_LIBRARY = $(TARGET_CCASFLAGS) $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM)
+
+CFLAGS_PROGRAM = $(TARGET_CFLAGS) $(CFLAGS_CPU) $(CFLAGS_PLATFORM)
+LDFLAGS_PROGRAM = $(TARGET_LDFLAGS) $(LDFLAGS_CPU) $(LDFLAGS_PLATFORM)
+CPPFLAGS_PROGRAM = $(TARGET_CPPFLAGS) $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM)
+CCASFLAGS_PROGRAM = $(TARGET_CCASFLAGS) $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM)
+
+AM_CFLAGS = 
+AM_LDFLAGS =
+AM_CPPFLAGS = $(CPPFLAGS_GRUB) -DGRUB_FILE=\"$(subst $(top_srcdir)/,,$<)\"
+AM_CCASFLAGS = -DASM_FILE=1
+
+# gentrigtables
+gentrigtables: $(top_srcdir)/gentrigtables.c
+       $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(CPPFLAGS) -lm $<
+CLEANFILES += gentrigtables
+
+# trigtables.c
+trigtables.c: gentrigtables.c configure.ac
+       $(MAKE) $(AM_MAKEFLAGS) gentrigtables
+       $(top_builddir)/gentrigtables > $@
+CLEANFILES += trigtables.c
+
+# XXX Use Automake's LEX & YACC support
+# See Recording Dependencies Manually in automake doc for below rules
+script/sh_module-lexer.$(OBJEXT):grub_script.tab.h
+grub_script.tab.c grub_script.tab.h: $(top_srcdir)/script/parser.y
+       $(YACC) -d -p grub_script_yy -b grub_script $(top_srcdir)/script/parser.y
+CLEANFILES += grub_script.tab.c grub_script.tab.h
+
+# For the lexer.
+# See Recording Dependencies Manually in automake doc for below rules
+script/sh_module-lexer.$(OBJEXT):grub_script.yy.h
+grub_script.yy.c grub_script.yy.h: $(top_srcdir)/script/yylex.l
+       $(LEX) -o grub_script.yy.c --header-file=grub_script.yy.h $(top_srcdir)/script/yylex.l
+CLEANFILES += grub_script.yy.c grub_script.yy.h
+
+include $(srcdir)/modules.am
+include $(srcdir)/Makefile.kernel
+
+# .lst files
+platform_DATA += moddep.lst
+platform_DATA += fs.lst
+platform_DATA += command.lst
+platform_DATA += partmap.lst
+platform_DATA += handler.lst
+platform_DATA += terminal.lst
+platform_DATA += parttool.lst
+platform_DATA += video.lst
+platform_DATA += crypto.lst
+CLEANFILES += moddep.lst
+CLEANFILES += fs.lst
+CLEANFILES += command.lst
+CLEANFILES += partmap.lst
+CLEANFILES += handler.lst
+CLEANFILES += terminal.lst
+CLEANFILES += parttool.lst
+CLEANFILES += video.lst
+CLEANFILES += crypto.lst
+
+fs.lst: $(FS_FILES)
+       cat $^ /dev/null | sort | uniq > $@
+command.lst: $(COMMAND_FILES)
+       cat $^ /dev/null | sort | uniq > $@
+partmap.lst: $(PARTMAP_FILES)
+       cat $^ /dev/null | sort | uniq > $@
+handler.lst: $(HANDLER_FILES)
+       cat $^ /dev/null | sort | uniq > $@
+terminal.lst: $(TERMINAL_FILES)
+       cat $^ /dev/null | sort | uniq > $@
+parttool.lst: $(PARTTOOL_FILES)
+       cat $^ /dev/null | sort | uniq > $@
+video.lst: $(VIDEO_FILES)
+       cat $^ /dev/null | sort | uniq > $@
+
+# but, crypto.lst is simply copied
+crypto.lst: $(top_srcdir)/lib/libgcrypt-grub/cipher/crypto.lst
+       cp $^ $@
+
+# generate global module dependencies list
+moddep.lst: kernel_syms.lst genmoddep.awk $(DEF_FILES) $(UND_FILES)
+       cat $(DEF_FILES) kernel_syms.lst /dev/null \
+         | $(AWK) -f $(top_srcdir)/genmoddep.awk $(UND_FILES) > $@ \
+         || (rm -f $@; exit 1)
+
+if COND_i386_pc
+if COND_ENABLE_EFIEMU
+efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF)
+       -rm -f $@; \
+       if test "x$(TARGET_APPLE_CC)" = x1; then \
+         $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_GRUB) -DELF32 -DAPPLE_CC -m32 -Wall -Werror -nostdlib -O2 -c -o $@.bin $< || exit 1; \
+         $(OBJCONV) -felf32 -nu -nd $@.bin $@ || exit 1; \
+         rm -f $@.bin; \
+       else \
+         $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_GRUB) -DELF32 -m32 -Wall -Werror -nostdlib -O2 -c -o $@ $< || exit 1; \
+         if test ! -z "$(TARGET_OBJ2ELF)"; then $(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi; \
+       fi
+
+efiemu64_c.o: efiemu/runtime/efiemu.c
+       if test "x$(TARGET_APPLE_CC)" = x1; then \
+         $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_GRUB) -DELF64 -DAPPLE_CC=1 -m64 -nostdlib -Wall -Werror -mno-red-zone -c -o $@ $< || exit 1; \
+       else \
+         $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_GRUB) -DELF64 -m64 -nostdlib -Wall -Werror -O2 -mcmodel=large -mno-red-zone -c -o $@ $< || exit 1; \
+       fi
+
+efiemu64_s.o: efiemu/runtime/efiemu.S
+       -rm -f $@
+       if test "x$(TARGET_APPLE_CC)" = x1; then \
+         $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_GRUB) -DELF64 -DAPPLE_CC=1 -m64 -Wall -Werror -nostdlib -O2 -mno-red-zone -c -o $@ $< || exit 1; \
+       else \
+         $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_GRUB) -DELF64 -m64 -Wall -Werror -nostdlib -O2 -mcmodel=large -mno-red-zone -c -o $@ $< || exit 1; \
+       fi
+
+efiemu64.o: efiemu64_c.o efiemu64_s.o $(TARGET_OBJ2ELEF)
+       -rm -f $@; \
+       if test "x$(TARGET_APPLE_CC)" = x1; then \
+         rm -f $@.bin; \
+         $(TARGET_CC) -m64 -Wl,-r -nostdlib -o $@.bin $^ || exit 1; \
+         $(OBJCONV) -felf64 -nu -nd $@.bin $@ || exit 1; \
+         rm -f $@.bin; \
+       else \
+         $(TARGET_CC) -m64 -nostdlib -Wl,-r -o $@ $^ || exit 1; \
+         if test ! -z "$(TARGET_OBJ2ELF)"; then $(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi; \
+       fi
+
+platform_DATA += efiemu32.o efiemu64.o
+CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o
+endif
+endif
+
diff --git a/grub-core/Makefile.extra-dist b/grub-core/Makefile.extra-dist
new file mode 100644 (file)
index 0000000..c6516f0
--- /dev/null
@@ -0,0 +1,53 @@
+#
+# Extra files that need to be distributed (in .tar.gz) to build
+# successfully on user site.
+#
+# XXX Remove wildcards;  See 27.3 in automake.info
+#
+
+EXTRA_DIST =
+
+EXTRA_DIST += gentpl.py
+EXTRA_DIST += Makefile.tpl
+EXTRA_DIST += modules.def
+
+EXTRA_DIST += gentrigtables.c
+
+EXTRA_DIST += genmoddep.awk
+EXTRA_DIST += genmodsrc.sh
+EXTRA_DIST += gensymlist.sh
+
+EXTRA_DIST += genemuinit.sh
+EXTRA_DIST += genemuinitheader.sh
+
+EXTRA_DIST += genfslist.sh
+EXTRA_DIST += gencmdlist.sh
+EXTRA_DIST += genvideolist.sh
+EXTRA_DIST += genhandlerlist.sh
+EXTRA_DIST += genpartmaplist.sh
+EXTRA_DIST += genparttoollist.sh
+EXTRA_DIST += genterminallist.sh
+EXTRA_DIST += lib/libgcrypt-grub/cipher/crypto.lst
+
+EXTRA_DIST += script/yylex.l
+EXTRA_DIST += script/parser.y
+
+EXTRA_DIST += lib/relocator.c
+
+EXTRA_DIST += efiemu/loadcore.c
+EXTRA_DIST += efiemu/prepare.c
+
+EXTRA_DIST += loader/machoXX.c
+
+
+EXTRA_DIST += kern/i386/loader.S
+EXTRA_DIST += kern/i386/realmode.S
+EXTRA_DIST += loader/i386/bsdXX.c
+EXTRA_DIST += loader/i386/bsd_pagetable.c
+EXTRA_DIST += loader/i386/multiboot_elfxx.c
+EXTRA_DIST += commands/search.c
+
+EXTRA_DIST += kern/i386/pc/lzma_decode.S
+
+EXTRA_DIST += $(shell find $(top_srcdir) -name '*.h')
+
diff --git a/grub-core/Makefile.kernel b/grub-core/Makefile.kernel
new file mode 100644 (file)
index 0000000..58e4648
--- /dev/null
@@ -0,0 +1,192 @@
+# -*- makefile -*-
+
+KERNEL_HEADER_FILES =
+KERNEL_HEADER_FILES += include/grub/cache.h
+KERNEL_HEADER_FILES += include/grub/command.h
+KERNEL_HEADER_FILES += include/grub/device.h
+KERNEL_HEADER_FILES += include/grub/disk.h
+KERNEL_HEADER_FILES += include/grub/dl.h
+KERNEL_HEADER_FILES += include/grub/elf.h
+KERNEL_HEADER_FILES += include/grub/elfload.h
+KERNEL_HEADER_FILES += include/grub/env.h
+KERNEL_HEADER_FILES += include/grub/env_private.h
+KERNEL_HEADER_FILES += include/grub/err.h
+KERNEL_HEADER_FILES += include/grub/file.h
+KERNEL_HEADER_FILES += include/grub/fs.h
+KERNEL_HEADER_FILES += include/grub/handler.h
+KERNEL_HEADER_FILES += include/grub/i18n.h
+KERNEL_HEADER_FILES += include/grub/kernel.h
+KERNEL_HEADER_FILES += include/grub/list.h
+KERNEL_HEADER_FILES += include/grub/misc.h
+KERNEL_HEADER_FILES += include/grub/mm.h
+KERNEL_HEADER_FILES += include/grub/net.h
+KERNEL_HEADER_FILES += include/grub/parser.h
+KERNEL_HEADER_FILES += include/grub/partition.h
+KERNEL_HEADER_FILES += include/grub/reader.h
+KERNEL_HEADER_FILES += include/grub/symbol.h
+KERNEL_HEADER_FILES += include/grub/term.h
+KERNEL_HEADER_FILES += include/grub/time.h
+KERNEL_HEADER_FILES += include/grub/types.h
+
+if COND_i386_pc
+KERNEL_HEADER_FILES += include/grub/boot.h
+KERNEL_HEADER_FILES += include/grub/loader.h
+KERNEL_HEADER_FILES += include/grub/msdos_partition.h
+KERNEL_HEADER_FILES += include/grub/machine/biosdisk.h
+KERNEL_HEADER_FILES += include/grub/machine/boot.h
+KERNEL_HEADER_FILES += include/grub/machine/console.h
+KERNEL_HEADER_FILES += include/grub/machine/memory.h
+KERNEL_HEADER_FILES += include/grub/machine/loader.h
+KERNEL_HEADER_FILES += include/grub/machine/vga.h
+KERNEL_HEADER_FILES += include/grub/machine/vbe.h
+KERNEL_HEADER_FILES += include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += include/grub/machine/pxe.h
+KERNEL_HEADER_FILES += include/grub/i386/pit.h
+endif
+
+if COND_i386_efi
+KERNEL_HEADER_FILES += include/grub/boot.h
+KERNEL_HEADER_FILES += include/grub/loader.h
+KERNEL_HEADER_FILES += include/grub/msdos_partition.h
+KERNEL_HEADER_FILES += include/grub/efi/efi.h
+KERNEL_HEADER_FILES += include/grub/efi/time.h
+KERNEL_HEADER_FILES += include/grub/efi/disk.h
+KERNEL_HEADER_FILES += include/grub/i386/pit.h
+endif
+
+if COND_i386_coreboot
+KERNEL_HEADER_FILES += include/grub/boot.h
+KERNEL_HEADER_FILES += include/grub/loader.h
+KERNEL_HEADER_FILES += include/grub/msdos_partition.h
+KERNEL_HEADER_FILES += include/grub/machine/boot.h
+KERNEL_HEADER_FILES += include/grub/machine/console.h
+KERNEL_HEADER_FILES += include/grub/machine/init.h
+KERNEL_HEADER_FILES += include/grub/machine/memory.h
+KERNEL_HEADER_FILES += include/grub/machine/loader.h
+endif
+
+if COND_i386_qemu
+KERNEL_HEADER_FILES += include/grub/boot.h
+KERNEL_HEADER_FILES += include/grub/loader.h
+KERNEL_HEADER_FILES += include/grub/msdos_partition.h
+KERNEL_HEADER_FILES += include/grub/machine/boot.h
+KERNEL_HEADER_FILES += include/grub/machine/console.h
+KERNEL_HEADER_FILES += include/grub/machine/init.h
+KERNEL_HEADER_FILES += include/grub/machine/memory.h
+KERNEL_HEADER_FILES += include/grub/machine/loader.h
+endif
+
+if COND_i386_ieee1275
+KERNEL_HEADER_FILES += include/grub/loader.h
+KERNEL_HEADER_FILES += include/grub/msdos_partition.h
+KERNEL_HEADER_FILES += include/grub/ieee1275/ieee1275.h
+KERNEL_HEADER_FILES += include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += include/grub/machine/loader.h
+KERNEL_HEADER_FILES += include/grub/machine/memory.h
+endif
+
+if COND_x86_64_efi
+KERNEL_HEADER_FILES += include/grub/boot.h
+KERNEL_HEADER_FILES += include/grub/loader.h
+KERNEL_HEADER_FILES += include/grub/msdos_partition.h
+KERNEL_HEADER_FILES += include/grub/efi/efi.h
+KERNEL_HEADER_FILES += include/grub/efi/time.h
+KERNEL_HEADER_FILES += include/grub/efi/disk.h
+KERNEL_HEADER_FILES += include/grub/machine/loader.h
+KERNEL_HEADER_FILES += include/grub/i386/pit.h
+endif
+
+if COND_mips_yeeloong
+KERNEL_HEADER_FILES += include/grub/boot.h
+KERNEL_HEADER_FILES += include/grub/loader.h
+KERNEL_HEADER_FILES += include/grub/msdos_partition.h
+KERNEL_HEADER_FILES += include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += include/grub/machine/memory.h
+KERNEL_HEADER_FILES += include/grub/cpu/cache.h
+KERNEL_HEADER_FILES += include/grub/bitmap.h
+KERNEL_HEADER_FILES += include/grub/video.h
+KERNEL_HEADER_FILES += include/grub/gfxterm.h
+KERNEL_HEADER_FILES += include/grub/font.h
+KERNEL_HEADER_FILES += include/grub/bitmap_scale.h
+KERNEL_HEADER_FILES += include/grub/bufio.h
+KERNEL_HEADER_FILES += include/grub/pci.h
+KERNEL_HEADER_FILES += include/grub/libgcc.h
+endif
+
+if COND_powerpc_ieee1275
+KERNEL_HEADER_FILES += include/grub/boot.h
+KERNEL_HEADER_FILES += include/grub/loader.h
+KERNEL_HEADER_FILES += include/grub/msdos_partition.h
+KERNEL_HEADER_FILES += include/grub/ieee1275/ieee1275.h
+KERNEL_HEADER_FILES += include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += include/grub/libgcc.h
+endif
+
+if COND_sparc64_ieee1275
+KERNEL_HEADER_FILES += include/grub/boot.h
+KERNEL_HEADER_FILES += include/grub/loader.h
+KERNEL_HEADER_FILES += include/grub/msdos_partition.h
+KERNEL_HEADER_FILES += include/grub/libgcc.h
+KERNEL_HEADER_FILES += include/grub/ieee1275/ieee1275.h
+KERNEL_HEADER_FILES += include/grub/machine/kernel.h
+KERNEL_HEADER_FILES += include/grub/sparc64/ieee1275/ieee1275.h
+endif
+
+if COND_emu
+KERNEL_HEADER_FILES += include/grub/cpu/time.h
+KERNEL_HEADER_FILES += include/grub/cpu/types.h
+KERNEL_HEADER_FILES += include/grub/gzio.h
+KERNEL_HEADER_FILES += include/grub/menu.h
+KERNEL_HEADER_FILES += include/grub/datetime.h
+KERNEL_HEADER_FILES += include/grub/emu/misc.h
+if COND_GRUB_EMU_SDL
+KERNEL_HEADER_FILES += include/grub/sdl.h
+endif
+if COND_GRUB_EMU_USB
+KERNEL_HEADER_FILES += include/grub/libusb.h
+endif
+if COND_GRUB_EMU_PCI
+KERNEL_HEADER_FILES += include/grub/libpciaccess.h
+endif
+endif
+
+symlist.h: config.h $(KERNEL_HEADER_FILES)
+       @list='$^'; \
+       for p in $$list; do \
+         echo "#include <$$p>" >> $@ || (rm -f $@; exit 1); \
+       done
+CLEANFILES += symlist.h
+BUILT_SOURCES += symlist.h
+
+symlist.c: symlist.h gensymlist.sh
+       $(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) -DGRUB_SYMBOL_GENERATOR=1 symlist.h > symlist.p || (rm -f symlist.p; exit 1)
+       cat symlist.p | /bin/sh $(srcdir)/gensymlist.sh config.h $(KERNEL_HEADER_FILES) >$@ || (rm -f $@; exit 1)
+       rm -f symlist.p
+CLEANFILES += symlist.c
+BUILT_SOURCES += symlist.c
+
+noinst_DATA += kernel_syms.lst
+kernel_syms.lst: $(KERNEL_HEADER_FILES) config.h
+       if grep "^#define HAVE_ASM_USCORE" config.h; then u="_"; else u=""; fi
+       $(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) $(CFLAGS) -DGRUB_SYMBOL_GENERATOR=1 $^ >kernel_syms.input
+       cat kernel_syms.input | grep -v '^#' | sed -n \
+         -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/'"$$u"'\1 kernel/;p;}' \
+         -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/'"$$u"'\1 kernel/;p;}' \
+         | sort -u >$@
+       rm -f kernel_syms.input
+CLEANFILES += kernel_syms.lst
+
+if COND_emu
+kern/emu/grub_emu-main.$(OBJEXT):grub_emu_init.h
+grub_emu-grub_emu_init.$(OBJEXT):grub_emu_init.h
+kern/emu/grub_emu_dyn-main.$(OBJEXT):grub_emu_init.h
+grub_emu_dyn-grub_emu_init.$(OBJEXT):grub_emu_init.h
+
+grub_emu_init.h: genemuinitheader.sh $(MOD_FILES)
+       rm -f $@; echo $(MOD_FILES) | sh $(srcdir)/genemuinitheader.sh $(NM) > $@
+CLEANFILES += grub_emu_init.h
+
+grub_emu_init.c: grub_emu_init.h genemuinit.sh $(MOD_FILES)
+       rm -f $@; echo $(MOD_FILES) | sh $(srcdir)/genemuinit.sh $(NM) > $@
+CLEANFILES += grub_emu_init.c
+endif
diff --git a/grub-core/Makefile.vars b/grub-core/Makefile.vars
new file mode 100644 (file)
index 0000000..710a8fd
--- /dev/null
@@ -0,0 +1,80 @@
+# -*- makefile -*-
+
+# Platform specific options
+if COND_i386_pc
+  CFLAGS_PLATFORM = -mrtd -mregparm=3
+endif
+if COND_i386_efi
+  LDFLAGS_PLATFORM = -melf_i386
+endif
+if COND_x86_64_efi
+  LDFLAGS_PLATFORM = -melf_x86_64
+endif
+if COND_i386_qemu
+  CFLAGS_PLATFORM = -mrtd -mregparm=3
+endif
+if COND_i386_coreboot
+  CFLAGS_PLATFORM = -mrtd -mregparm=3
+endif
+if COND_i386_ieee1275
+  CFLAGS_PLATFORM = -mrtd -mregparm=3
+endif
+if COND_mips_yeeloong
+  CFLAGS_PLATFORM = -march=mips3 -mexplicit-relocs -mflush-func=grub_cpu_flush_cache
+  CCASFLAGS_PLATFORM = -march=mips3
+endif
+if COND_sparc64_ieee1275
+  CFLAGS_PLATFORM = -mno-app-regs
+  LDFLAGS_PLATFORM = -melf64_sparc -mno-relax
+endif
+
+CPPFLAGS_GRUB = -I$(builddir) -I$(srcdir) -I$(top_builddir) -I$(top_srcdir)
+CPPFLAGS_GRUB += -I$(top_srcdir)/include -I$(top_builddir)/include
+
+CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers
+CPPFLAGS_GCRY = -I$(top_srcdir)/lib/libgcrypt_wrap
+
+CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -D_GL_UNUSED="__attribute__ ((unused))"
+CPPFLAGS_GNULIB = -I$(top_srcdir)/gnulib
+
+CFLAGS_MKISOFS = -Wno-all -Werror
+CPPFLAGS_MKISOFS = -D_FILE_OFFSET_BITS=64 -I$(top_srcdir)/util/mkisofs/include
+
+CFLAGS_POSIX = -fno-builtin
+CPPFLAGS_POSIX = -I$(top_srcdir)/lib/posix_wrap
+
+CPPFLAGS_EFIEMU = -I$(top_srcdir)/efiemu/runtime
+
+grubconfdir = $(sysconfdir)/grub.d
+platformdir = $(pkglibdir)/$(target_cpu)-$(platform)
+
+# to calm down automake
+BUILT_SOURCES =
+CLEANFILES =
+COMMAND_FILES =
+DEF_FILES =
+FS_FILES =
+HANDLER_FILES =
+IMG_FILES =
+MOD_FILES =
+MODULE_FILES =
+PARTMAP_FILES =
+PARTTOOL_FILES =
+TERMINAL_FILES =
+TESTS =
+UND_FILES =
+VIDEO_FILES =
+bin_PROGRAMS =
+bin_SCRIPTS =
+check_PROGRAMS =
+check_SCRIPTS =
+grubconf_DATA =
+grubconf_SCRIPTS =
+man_MANS =
+noinst_DATA =
+noinst_LIBRARIES =
+noinst_PROGRAMS =
+pkglib_SCRIPTS =
+platform_DATA =
+sbin_PROGRAMS =
+sbin_SCRIPTS =
diff --git a/grub-core/boot/i386/pc/boot.S b/grub-core/boot/i386/pc/boot.S
new file mode 100644 (file)
index 0000000..4afc573
--- /dev/null
@@ -0,0 +1,479 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/boot.h>
+#include <grub/machine/boot.h>
+
+/*
+ *  defines for the code go here
+ */
+
+       /* Print message string */
+#define MSG(x) movw $x, %si; call LOCAL(message)
+#define ERR(x) movw $x, %si; jmp LOCAL(error_message)
+
+       .file   "boot.S"
+
+       .text
+
+       /* Tell GAS to generate 16-bit instructions so that this code works
+          in real mode. */
+       .code16
+
+.globl _start, start;
+_start:
+start:
+       /*
+        * _start is loaded at 0x7c00 and is jumped to with CS:IP 0:0x7c00
+        */
+
+       /*
+        * Beginning of the sector is compatible with the FAT/HPFS BIOS
+        * parameter block.
+        */
+
+       jmp     LOCAL(after_BPB)
+       nop     /* do I care about this ??? */
+
+       /*
+        * This space is for the BIOS parameter block!!!!  Don't change
+        * the first jump, nor start the code anywhere but right after
+        * this area.
+        */
+
+       . = _start + GRUB_BOOT_MACHINE_BPB_START
+       . = _start + 4
+
+       /* scratch space */
+mode:
+       .byte   0
+disk_address_packet:
+sectors:
+       .long   0
+heads:
+       .long   0
+cylinders:
+       .word   0
+sector_start:
+       .byte   0
+head_start:
+       .byte   0
+cylinder_start:
+       .word   0
+       /* more space... */
+
+       . = _start + GRUB_BOOT_MACHINE_BPB_END
+
+       /*
+        * End of BIOS parameter block.
+        */
+
+kernel_address:
+       .word   GRUB_BOOT_MACHINE_KERNEL_ADDR
+
+       . = _start + GRUB_BOOT_MACHINE_KERNEL_SECTOR
+kernel_sector:
+       .long   1, 0
+
+       . = _start + GRUB_BOOT_MACHINE_BOOT_DRIVE
+boot_drive:
+       .byte 0xff      /* the disk to load kernel from */
+                       /* 0xff means use the boot drive */
+
+LOCAL(after_BPB):
+
+/* general setup */
+       cli             /* we're not safe here! */
+
+        /*
+         * This is a workaround for buggy BIOSes which don't pass boot
+         * drive correctly. If GRUB is installed into a HDD, check if
+         * DL is masked correctly. If not, assume that the BIOS passed
+         * a bogus value and set DL to 0x80, since this is the only
+         * possible boot drive. If GRUB is installed into a floppy,
+         * this does nothing (only jump).
+         */
+       . = _start + GRUB_BOOT_MACHINE_DRIVE_CHECK
+boot_drive_check:
+        jmp     1f     /* grub-setup may overwrite this jump */
+        testb   $0x80, %dl
+        jnz     1f
+        movb    $0x80, %dl
+1:
+
+       /*
+        * ljmp to the next instruction because some bogus BIOSes
+        * jump to 07C0:0000 instead of 0000:7C00.
+        */
+       ljmp    $0, $real_start
+
+real_start:
+
+       /* set up %ds and %ss as offset from 0 */
+       xorw    %ax, %ax
+       movw    %ax, %ds
+       movw    %ax, %ss
+
+       /* set up the REAL stack */
+       movw    $GRUB_BOOT_MACHINE_STACK_SEG, %sp
+
+       sti             /* we're safe again */
+
+       /*
+        *  Check if we have a forced disk reference here
+        */
+       movb   boot_drive, %al
+       cmpb    $0xff, %al
+       je      1f
+       movb    %al, %dl
+1:
+       /* save drive reference first thing! */
+       pushw   %dx
+
+       /* print a notification message on the screen */
+       MSG(notification_string)
+
+       /* set %si to the disk address packet */
+       movw    $disk_address_packet, %si
+
+       /* do not probe LBA if the drive is a floppy */
+       testb   $GRUB_BOOT_MACHINE_BIOS_HD_FLAG, %dl
+       jz      LOCAL(chs_mode)
+
+       /* check if LBA is supported */
+       movb    $0x41, %ah
+       movw    $0x55aa, %bx
+       int     $0x13
+
+       /*
+        *  %dl may have been clobbered by INT 13, AH=41H.
+        *  This happens, for example, with AST BIOS 1.04.
+        */
+       popw    %dx
+       pushw   %dx
+
+       /* use CHS if fails */
+       jc      LOCAL(chs_mode)
+       cmpw    $0xaa55, %bx
+       jne     LOCAL(chs_mode)
+
+       andw    $1, %cx
+       jz      LOCAL(chs_mode)
+
+lba_mode:
+       xorw    %ax, %ax
+       movw    %ax, 4(%si)
+
+       incw    %ax
+       /* set the mode to non-zero */
+       movb    %al, -1(%si)
+
+       /* the blocks */
+       movw    %ax, 2(%si)
+
+       /* the size and the reserved byte */
+       movw    $0x0010, (%si)
+
+       /* the absolute address */
+       movl    kernel_sector, %ebx
+       movl    %ebx, 8(%si)
+       movl    kernel_sector + 4, %ebx
+       movl    %ebx, 12(%si)
+
+       /* the segment of buffer address */
+       movw    $GRUB_BOOT_MACHINE_BUFFER_SEG, 6(%si)
+
+/*
+ * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
+ *     Call with       %ah = 0x42
+ *                     %dl = drive number
+ *                     %ds:%si = segment:offset of disk address packet
+ *     Return:
+ *                     %al = 0x0 on success; err code on failure
+ */
+
+       movb    $0x42, %ah
+       int     $0x13
+
+       /* LBA read is not supported, so fallback to CHS.  */
+       jc      LOCAL(chs_mode)
+
+       movw    $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
+       jmp     LOCAL(copy_buffer)
+
+LOCAL(chs_mode):
+       /*
+        *  Determine the hard disk geometry from the BIOS!
+        *  We do this first, so that LS-120 IDE floppies work correctly.
+        */
+       movb    $8, %ah
+       int     $0x13
+       jnc     LOCAL(final_init)
+
+       /*
+        *  The call failed, so maybe use the floppy probe instead.
+        */
+       testb   $GRUB_BOOT_MACHINE_BIOS_HD_FLAG, %dl
+       jz      LOCAL(floppy_probe)
+
+       /* Nope, we definitely have a hard disk, and we're screwed. */
+       ERR(hd_probe_error_string)
+
+LOCAL(final_init):
+       /* set the mode to zero */
+       movzbl  %dh, %eax
+       movb    %ah, -1(%si)
+
+       /* save number of heads */
+       incw    %ax
+       movl    %eax, 4(%si)
+
+       movzbw  %cl, %dx
+       shlw    $2, %dx
+       movb    %ch, %al
+       movb    %dh, %ah
+
+       /* save number of cylinders */
+       incw    %ax
+       movw    %ax, 8(%si)
+
+       movzbw  %dl, %ax
+       shrb    $2, %al
+
+       /* save number of sectors */
+       movl    %eax, (%si)
+
+setup_sectors:
+       /* load logical sector start (top half) */
+       movl    kernel_sector + 4, %eax
+
+       orl     %eax, %eax
+       jnz     LOCAL(geometry_error)
+
+       /* load logical sector start (bottom half) */
+       movl    kernel_sector, %eax
+
+       /* zero %edx */
+       xorl    %edx, %edx
+
+       /* divide by number of sectors */
+       divl    (%si)
+
+       /* save sector start */
+       movb    %dl, %cl
+
+       xorw    %dx, %dx        /* zero %edx */
+       divl    4(%si)          /* divide by number of heads */
+
+       /* do we need too many cylinders? */
+       cmpw    8(%si), %ax
+       jge     LOCAL(geometry_error)
+
+       /* normalize sector start (1-based) */
+       incb    %cl
+
+       /* low bits of cylinder start */
+       movb    %al, %ch
+
+       /* high bits of cylinder start */
+       xorb    %al, %al
+       shrw    $2, %ax
+       orb     %al, %cl
+
+       /* save head start */
+       movb    %dl, %al
+
+       /* restore %dl */
+       popw    %dx
+
+       /* head start */
+       movb    %al, %dh
+
+/*
+ * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
+ *     Call with       %ah = 0x2
+ *                     %al = number of sectors
+ *                     %ch = cylinder
+ *                     %cl = sector (bits 6-7 are high bits of "cylinder")
+ *                     %dh = head
+ *                     %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+ *                     %es:%bx = segment:offset of buffer
+ *     Return:
+ *                     %al = 0x0 on success; err code on failure
+ */
+
+       movw    $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
+       movw    %bx, %es        /* load %es segment with disk buffer */
+
+       xorw    %bx, %bx        /* %bx = 0, put it at 0 in the segment */
+       movw    $0x0201, %ax    /* function 2 */
+       int     $0x13
+
+       jc      LOCAL(read_error)
+
+       movw    %es, %bx
+
+LOCAL(copy_buffer):
+       /*
+        * We need to save %cx and %si because the startup code in
+        * kernel uses them without initializing them.
+        */
+       pusha
+       pushw   %ds
+
+       movw    $0x100, %cx
+       movw    %bx, %ds
+       xorw    %si, %si
+       movw    $GRUB_BOOT_MACHINE_KERNEL_ADDR, %di
+       movw    %si, %es
+
+       cld
+
+       rep
+       movsw
+
+       popw    %ds
+       popa
+
+       /* boot kernel */
+       jmp     *(kernel_address)
+
+/* END OF MAIN LOOP */
+
+/*
+ * BIOS Geometry translation error (past the end of the disk geometry!).
+ */
+LOCAL(geometry_error):
+       ERR(geometry_error_string)
+
+/*
+ * Read error on the disk.
+ */
+LOCAL(read_error):
+       movw    $read_error_string, %si
+LOCAL(error_message):
+       call    LOCAL(message)
+LOCAL(general_error):
+       MSG(general_error_string)
+
+/* go here when you need to stop the machine hard after an error condition */
+        /* tell the BIOS a boot failure, which may result in no effect */
+        int    $0x18
+LOCAL(stop):
+       jmp     LOCAL(stop)
+
+notification_string:   .asciz "GRUB "
+geometry_error_string: .asciz "Geom"
+hd_probe_error_string: .asciz "Hard Disk"
+read_error_string:     .asciz "Read"
+general_error_string:  .asciz " Error\r\n"
+
+/*
+ * message: write the string pointed to by %si
+ *
+ *   WARNING: trashes %si, %ax, and %bx
+ */
+
+       /*
+        * Use BIOS "int 10H Function 0Eh" to write character in teletype mode
+        *      %ah = 0xe       %al = character
+        *      %bh = page      %bl = foreground color (graphics modes)
+        */
+1:
+       movw    $0x0001, %bx
+       movb    $0xe, %ah
+       int     $0x10           /* display a byte */
+LOCAL(message):
+       lodsb
+       cmpb    $0, %al
+       jne     1b      /* if not end of string, jmp to display */
+       ret
+
+       /*
+        *  Windows NT breaks compatibility by embedding a magic
+        *  number here.
+        */
+
+       . = _start + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC
+nt_magic:
+       .long 0
+       .word 0
+
+       /*
+        *  This is where an MBR would go if on a hard disk.  The code
+        *  here isn't even referenced unless we're on a floppy.  Kinda
+        *  sneaky, huh?
+        */
+
+       . = _start + GRUB_BOOT_MACHINE_PART_START
+part_start:
+
+probe_values:
+       .byte   36, 18, 15, 9, 0
+
+LOCAL(floppy_probe):
+/*
+ *  Perform floppy probe.
+ */
+
+       movw    $probe_values - 1, %si
+
+LOCAL(probe_loop):
+       /* reset floppy controller INT 13h AH=0 */
+       xorw    %ax, %ax
+       int     $0x13
+
+       incw    %si
+       movb    (%si), %cl
+
+       /* if number of sectors is 0, display error and die */
+       cmpb    $0, %cl
+       jne     1f
+
+/*
+ * Floppy disk probe failure.
+ */
+       MSG(fd_probe_error_string)
+       jmp     LOCAL(general_error)
+
+/* "Floppy" */
+fd_probe_error_string: .asciz "Floppy"
+
+1:
+       /* perform read */
+       movw    $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
+       movw    $0x201, %ax
+       movb    $0, %ch
+       movb    $0, %dh
+       int     $0x13
+
+       /* if error, jump to "LOCAL(probe_loop)" */
+       jc      LOCAL(probe_loop)
+
+       /* %cl is already the correct value! */
+       movb    $1, %dh
+       movb    $79, %ch
+
+       jmp     LOCAL(final_init)
+
+       . = _start + GRUB_BOOT_MACHINE_PART_END
+
+/* the last 2 bytes in the sector 0 contain the signature */
+       .word   GRUB_BOOT_MACHINE_SIGNATURE
diff --git a/grub-core/boot/i386/pc/cdboot.S b/grub-core/boot/i386/pc/cdboot.S
new file mode 100644 (file)
index 0000000..33569ce
--- /dev/null
@@ -0,0 +1,173 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/boot.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/kernel.h>
+#include <multiboot.h>
+
+        .file   "cdboot.S"
+
+#define CODE_ADDR      0x6000
+#define DATA_ADDR      ((GRUB_BOOT_MACHINE_KERNEL_ADDR) + 0x200)
+
+#define CDSEC_SHIFT    11
+#define CDBLK_LENG     16
+
+       .text
+
+        .code16
+
+        .globl  start, _start
+
+start:
+_start:
+       call    LOCAL(next)
+
+LOCAL(next):
+       jmp     1f
+
+       . = start + 8
+
+bi_pvd:
+       .long 0         /* LBA of primary volume descriptor.  */
+bi_file:
+       .long 0         /* LBA of boot file. */
+bi_length:
+       .long 0         /* Length of boot file. */
+bi_csum:
+       .long 0         /* Checksum of boot file */
+bi_reserved:
+       .space (10*4)   /* Reserved */
+
+1:
+       popw    %bx
+
+       /* Boot from CDROM.  */
+
+       xorw    %ax, %ax
+       movw    %ax, %ss
+       movw    $(CODE_ADDR), %sp
+       movw    %ax, %ds
+       movw    %ax, %es
+
+       movw    $(0x7C00 + err_noboot_msg - start), %si
+       movl    %cs: bi_length - LOCAL(next)(%bx), %ecx
+       orl     %ecx, %ecx
+       jz      LOCAL(fail)
+
+       addl    $((1 << CDSEC_SHIFT) - 1), %ecx
+       shrl    $CDSEC_SHIFT, %ecx
+
+       movl    %cs: bi_file - LOCAL(next)(%bx), %esi
+
+       call    LOCAL(read_cdrom)
+
+       ljmp    $(DATA_ADDR >> 4), $0
+
+/*
+ * Parameters:
+ *   esi: start sector
+ *   ecx: number of sectors
+ */
+LOCAL(read_cdrom):
+       xorl    %eax, %eax
+
+       /* Number of blocks to read.  */
+       pushw   $CDBLK_LENG
+
+       /* Block number.  */
+       pushl   %eax
+       pushl   %esi
+
+       /* Buffer address.  */
+       pushw   $((DATA_ADDR - 0x400)>> 4)
+       pushl   %eax
+       pushw   $0x10
+
+       xorl    %edi, %edi
+       movw    %sp, %si
+
+1:
+       movw    0x10(%si), %di
+       cmpl    %ecx, %edi
+       jbe     2f
+       movl    %ecx, %edi
+
+2:
+       mov     %di, 2(%si)
+
+       pushl   %ecx
+
+       movb    $0x42, %ah
+       int     $0x13
+
+       jnc     3f
+
+       movb    $0x42, %ah              /* Try again.  */
+       int     $0x13
+
+       jnc     3f
+
+2:
+       shrw    $1, %di                 /* Reduce transfer size.  */
+       jz      LOCAL(cdrom_fail)
+       movw    %di, 0x10(%si)
+       movw    %di, 2(%si)
+       movb    $0x42, %ah
+       int     $0x13
+       jc      2b
+
+3:
+
+       movw    %di, %ax
+       shlw    $(CDSEC_SHIFT - 4), %ax
+       addw    %ax, 6(%si)
+       addl    %edi, 8(%si)
+
+       popl    %ecx
+       subl    %edi, %ecx
+       jnz     1b
+
+       addw    $0x12, %sp
+       ret
+
+LOCAL(cdrom_fail):
+       movw    $(0x7C00 + err_cdfail_msg - start), %si
+
+LOCAL(fail):
+       movb    $0x0e, %ah
+       xorw    %bx, %bx
+1:
+       lodsb   (%si), %al
+       int     $0x10
+       cmpb    $0, %al
+       jne     1b
+1:     jmp     1b
+
+err_noboot_msg:
+       .ascii  "no boot info\0"
+
+err_cdfail_msg:
+       .ascii  "cdrom read fails\0"
+
+       . = start + 0x1FF
+
+       .byte   0
diff --git a/grub-core/boot/i386/pc/diskboot.S b/grub-core/boot/i386/pc/diskboot.S
new file mode 100644 (file)
index 0000000..92f223f
--- /dev/null
@@ -0,0 +1,380 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2006,2007,2009,2010   Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/machine/boot.h>
+
+/*
+ *  defines for the code go here
+ */
+
+#define MSG(x) movw $x, %si; call LOCAL(message)
+
+       .file   "diskboot.S"
+
+       .text
+
+       /* Tell GAS to generate 16-bit instructions so that this code works
+          in real mode. */
+       .code16
+
+       .globl  start, _start
+start:
+_start:
+       /*
+        * _start is loaded at 0x2000 and is jumped to with
+        * CS:IP 0:0x2000 in kernel.
+        */
+
+       /*
+        * we continue to use the stack for boot.img and assume that
+        * some registers are set to correct values. See boot.S
+        * for more information.
+        */
+
+       /* save drive reference first thing! */
+       pushw   %dx
+
+       /* print a notification message on the screen */
+       pushw   %si
+       MSG(notification_string)
+       popw    %si
+
+       /* this sets up for the first run through "bootloop" */
+       movw    $(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE), %di
+
+       /* save the sector number of the second sector in %ebp */
+       movl    (%di), %ebp
+
+        /* this is the loop for reading the rest of the kernel in */
+LOCAL(bootloop):
+
+       /* check the number of sectors to read */
+       cmpw    $0, 8(%di)
+
+       /* if zero, go to the start function */
+       je      LOCAL(bootit)
+
+LOCAL(setup_sectors):
+       /* check if we use LBA or CHS */
+       cmpb    $0, -1(%si)
+
+       /* use CHS if zero, LBA otherwise */
+       je      LOCAL(chs_mode)
+
+       /* load logical sector start */
+       movl    (%di), %ebx
+       movl    4(%di), %ecx
+
+       /* the maximum is limited to 0x7f because of Phoenix EDD */
+       xorl    %eax, %eax
+       movb    $0x7f, %al
+
+       /* how many do we really want to read? */
+       cmpw    %ax, 8(%di)     /* compare against total number of sectors */
+
+       /* which is greater? */
+       jg      1f
+
+       /* if less than, set to total */
+       movw    8(%di), %ax
+
+1:
+       /* subtract from total */
+       subw    %ax, 8(%di)
+
+       /* add into logical sector start */
+       addl    %eax, (%di)
+       adcl    $0, 4(%di)
+
+       /* set up disk address packet */
+
+       /* the size and the reserved byte */
+       movw    $0x0010, (%si)
+
+       /* the number of sectors */
+       movw    %ax, 2(%si)
+
+       /* the absolute address */
+       movl    %ebx, 8(%si)
+       movl    %ecx, 12(%si)
+
+       /* the segment of buffer address */
+       movw    $GRUB_BOOT_MACHINE_BUFFER_SEG, 6(%si)
+
+       /* save %ax from destruction! */
+       pushw   %ax
+
+       /* the offset of buffer address */
+       movw    $0, 4(%si)
+
+/*
+ * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
+ *     Call with       %ah = 0x42
+ *                     %dl = drive number
+ *                     %ds:%si = segment:offset of disk address packet
+ *     Return:
+ *                     %al = 0x0 on success; err code on failure
+ */
+
+       movb    $0x42, %ah
+       int     $0x13
+
+       jc      LOCAL(read_error)
+
+       movw    $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
+       jmp     LOCAL(copy_buffer)
+
+LOCAL(chs_mode):
+       /* load logical sector start (top half) */
+       movl    4(%di), %eax
+       orl     %eax, %eax
+       jnz     LOCAL(geometry_error)
+
+       /* load logical sector start (bottom half) */
+       movl    (%di), %eax
+
+       /* zero %edx */
+       xorl    %edx, %edx
+
+       /* divide by number of sectors */
+       divl    (%si)
+
+       /* save sector start */
+       movb    %dl, 10(%si)
+
+       xorl    %edx, %edx      /* zero %edx */
+       divl    4(%si)          /* divide by number of heads */
+
+       /* save head start */
+       movb    %dl, 11(%si)
+
+       /* save cylinder start */
+       movw    %ax, 12(%si)
+
+       /* do we need too many cylinders? */
+       cmpw    8(%si), %ax
+       jge     LOCAL(geometry_error)
+
+       /* determine the maximum sector length of this read */
+       movw    (%si), %ax      /* get number of sectors per track/head */
+
+       /* subtract sector start */
+       subb    10(%si), %al
+
+       /* how many do we really want to read? */
+       cmpw    %ax, 8(%di)     /* compare against total number of sectors */
+
+
+       /* which is greater? */
+       jg      2f
+
+       /* if less than, set to total */
+       movw    8(%di), %ax
+
+2:
+       /* subtract from total */
+       subw    %ax, 8(%di)
+
+       /* add into logical sector start */
+       addl    %eax, (%di)
+       adcl    $0, 4(%di)
+
+/*
+ *  This is the loop for taking care of BIOS geometry translation (ugh!)
+ */
+
+       /* get high bits of cylinder */
+       movb    13(%si), %dl
+
+       shlb    $6, %dl         /* shift left by 6 bits */
+       movb    10(%si), %cl    /* get sector */
+
+       incb    %cl             /* normalize sector (sectors go
+                                       from 1-N, not 0-(N-1) ) */
+       orb     %dl, %cl        /* composite together */
+       movb    12(%si), %ch    /* sector+hcyl in cl, cylinder in ch */
+
+       /* restore %dx */
+       popw    %dx
+       pushw   %dx
+
+       /* head number */
+       movb    11(%si), %dh
+
+       pushw   %ax     /* save %ax from destruction! */
+
+/*
+ * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
+ *     Call with       %ah = 0x2
+ *                     %al = number of sectors
+ *                     %ch = cylinder
+ *                     %cl = sector (bits 6-7 are high bits of "cylinder")
+ *                     %dh = head
+ *                     %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+ *                     %es:%bx = segment:offset of buffer
+ *     Return:
+ *                     %al = 0x0 on success; err code on failure
+ */
+
+       movw    $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
+       movw    %bx, %es        /* load %es segment with disk buffer */
+
+       xorw    %bx, %bx        /* %bx = 0, put it at 0 in the segment */
+       movb    $0x2, %ah       /* function 2 */
+       int     $0x13
+
+       jc      LOCAL(read_error)
+
+       /* save source segment */
+       movw    %es, %bx
+
+LOCAL(copy_buffer):
+
+       /* load addresses for copy from disk buffer to destination */
+       movw    10(%di), %es    /* load destination segment */
+
+       /* restore %ax */
+       popw    %ax
+
+       /* determine the next possible destination address (presuming
+               512 byte sectors!) */
+       shlw    $5, %ax         /* shift %ax five bits to the left */
+       addw    %ax, 10(%di)    /* add the corrected value to the destination
+                                  address for next time */
+
+       /* save addressing regs */
+       pusha
+       pushw   %ds
+
+       /* get the copy length */
+       shlw    $3, %ax
+       movw    %ax, %cx
+
+       xorw    %di, %di        /* zero offset of destination addresses */
+       xorw    %si, %si        /* zero offset of source addresses */
+       movw    %bx, %ds        /* restore the source segment */
+
+       cld             /* sets the copy direction to forward */
+
+       /* perform copy */
+       rep             /* sets a repeat */
+       movsw           /* this runs the actual copy */
+
+       /* restore addressing regs and print a dot with correct DS
+          (MSG modifies SI, which is saved, and unused AX and BX) */
+       popw    %ds
+       MSG(notification_step)
+       popa
+
+       /* check if finished with this dataset */
+       cmpw    $0, 8(%di)
+       jne     LOCAL(setup_sectors)
+
+       /* update position to load from */
+       subw    $GRUB_BOOT_MACHINE_LIST_SIZE, %di
+
+       /* jump to bootloop */
+       jmp     LOCAL(bootloop)
+
+/* END OF MAIN LOOP */
+
+LOCAL(bootit):
+       /* print a newline */
+       MSG(notification_done)
+       popw    %dx     /* this makes sure %dl is our "boot" drive */
+       ljmp    $0, $(GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200)
+
+
+/*
+ * BIOS Geometry translation error (past the end of the disk geometry!).
+ */
+LOCAL(geometry_error):
+       MSG(geometry_error_string)
+       jmp     LOCAL(general_error)
+
+/*
+ * Read error on the disk.
+ */
+LOCAL(read_error):
+       MSG(read_error_string)
+
+LOCAL(general_error):
+       MSG(general_error_string)
+
+/* go here when you need to stop the machine hard after an error condition */
+LOCAL(stop):   jmp     LOCAL(stop)
+
+notification_string:   .asciz "loading"
+
+notification_step:     .asciz "."
+notification_done:     .asciz "\r\n"
+
+geometry_error_string: .asciz "Geom"
+read_error_string:     .asciz "Read"
+general_error_string:  .asciz " Error"
+
+/*
+ * message: write the string pointed to by %si
+ *
+ *   WARNING: trashes %si, %ax, and %bx
+ */
+
+       /*
+        * Use BIOS "int 10H Function 0Eh" to write character in teletype mode
+        *      %ah = 0xe       %al = character
+        *      %bh = page      %bl = foreground color (graphics modes)
+        */
+1:
+       movw    $0x0001, %bx
+       movb    $0xe, %ah
+       int     $0x10           /* display a byte */
+
+       incw    %si
+LOCAL(message):
+       movb    (%si), %al
+       cmpb    $0, %al
+       jne     1b      /* if not end of string, jmp to display */
+       ret
+
+/*
+ *  This area is an empty space between the main body of code below which
+ *  grows up (fixed after compilation, but between releases it may change
+ *  in size easily), and the lists of sectors to read, which grows down
+ *  from a fixed top location.
+ */
+
+       .word 0
+       .word 0
+
+       . = _start + 0x200 - GRUB_BOOT_MACHINE_LIST_SIZE
+
+        /* fill the first data listing with the default */
+blocklist_default_start:
+       /* this is the sector start parameter, in logical sectors from
+          the start of the disk, sector 0 */
+       .long 2, 0
+blocklist_default_len:
+       /* this is the number of sectors to read.  grub-mkimage
+          will fill this up */
+       .word 0
+blocklist_default_seg:
+       /* this is the segment of the starting address to load the data into */
+       .word (GRUB_BOOT_MACHINE_KERNEL_SEG + 0x20)
+
+firstlist:     /* this label has to be after the list data!!! */
diff --git a/grub-core/boot/i386/pc/lnxboot.S b/grub-core/boot/i386/pc/lnxboot.S
new file mode 100644 (file)
index 0000000..b4f0030
--- /dev/null
@@ -0,0 +1,290 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/boot.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/kernel.h>
+#include <multiboot.h>
+
+        .file   "lnxboot.S"
+
+#define CODE_ADDR      0x6000
+#define CODE_SECTORS   1
+#define DATA_ADDR      ((GRUB_BOOT_MACHINE_KERNEL_ADDR) + 0x200)
+
+#define BLCK_LENG      0x4000
+
+       .text
+
+        .code16
+
+        .globl  start, _start
+
+data_start:
+       xorl    %ebp, %ebp
+       jmp     LOCAL(linux_next)
+
+       . = data_start + 0x1F1
+
+setup_sects:
+       .byte   CODE_SECTORS
+root_flags:
+       .word   0
+syssize:
+       .word   0
+swap_dev:
+       .word   0
+ram_size:
+       .word   0
+vid_mode:
+       .word   0
+root_dev:
+       .word   0
+boot_flag:
+       .word   0xAA55
+
+start:
+_start:
+
+       jmp LOCAL(linux_init)
+
+       .ascii  "HdrS"                  /* Header signature.  */
+       .word   0x0203                  /* Header version number.  */
+
+realmode_swtch:
+       .word   0, 0                    /* default_switch, SETUPSEG.  */
+start_sys_seg:
+       .word   0x1000                  /* Obsolete.  */
+version_ptr:
+       .word   0                       /* Version string ptr.  */
+type_of_loader:
+       .byte   0                       /* Filled in by boot loader.  */
+loadflags:
+       .byte   1                       /* Please load high.  */
+setup_move_size:
+       .word   0                       /* Unused.  */
+code32_start:
+       .long   0x100000                /* 32-bit start address.  */
+ramdisk_image:
+       .long   0                       /* Loaded ramdisk image address.  */
+ramdisk_size:
+       .long   0                       /* Size of loaded ramdisk.  */
+bootsect_kludge:
+       .word   0, 0
+heap_end_ptr:
+       .word   0
+pad1:
+       .word   0
+cmd_line_ptr:
+       .long   0                       /* Command line.  */
+ramdisk_max:
+       .long   0xffffffff              /* Highest allowed ramdisk address.  */
+
+gdt:
+       .long   0, 0, 0, 0              /* Must be zero.  */
+       .word   0xffff                  /* 64 K segment size.  */
+gdt_src1:
+       .byte   0, 0 ,0                 /* Low 24 bits of source address.  */
+       .byte   0x93                    /* Access rights.  */
+       .byte   0                       /* Extended access rights.  */
+gdt_src2:
+       .byte   0                       /* High 8 bits of source address.  */
+       .word   0xffff                  /* 64 K segment size.  */
+gdt_dst1:
+       .byte   0, 0, 0                 /* Low 24 bits of target address.  */
+       .byte   0x93                    /* Access rights.  */
+       .byte   0                       /* Extended access rights.  */
+gdt_dst2:
+       .byte   0                       /* High 8 bits of source address.  */
+       .long   0, 0, 0, 0              /* More space for the BIOS.  */
+
+reg_edx:
+       .byte   0x80, 0, 0xFF, 0xFF
+
+data_leng:
+       .long   0
+
+LOCAL(linux_init):
+       movw    %cs:(reg_edx - start), %dx
+       movl    %cs:(code32_start - start), %ebp
+
+LOCAL(linux_next):
+
+       call    LOCAL(normalize)
+
+LOCAL(normalize):
+       popw    %bx
+       subw    $(LOCAL(normalize) - start), %bx
+       shrw    $4, %bx
+       movw    %cs, %ax
+       addw    %bx, %ax
+       pushw   %ax
+       pushw   $(real_code - start)
+       lret                            /* Jump to real_code.  */
+
+real_code:
+       subw    $0x20, %ax
+       movw    %ax, %ds
+       movw    (setup_sects - data_start), %cx
+       shlw    $7, %cx
+
+       /* Setup stack.  */
+
+       xorw    %si, %si
+       movw    %si, %ss
+       movw    $(CODE_ADDR), %sp
+
+       /* Move itself to 0:CODE_ADDR.  */
+
+       cld
+       movw    %cs, %ax
+       movw    %ax, %ds
+       movw    $(CODE_ADDR >> 4), %ax
+       movw    %ax, %es
+       movw    %si, %di
+
+       rep
+       movsl
+       ljmp    $(CODE_ADDR >> 4), $(real_code_2  - start)
+
+real_code_2:
+
+       xchgl   %ebp, %esi
+       orl     %esi, %esi
+       jnz     1f
+       movw    %ds, %si
+       shll    $4, %esi
+       addl    %ebp, %esi
+1:
+
+       pushw   %es
+       popw    %ds
+
+       movl    $0x200, %ecx
+       addl    %ecx, %esi
+       movl    $DATA_ADDR, %edi
+
+       call    LOCAL(move_memory)
+
+       /* Check for multiboot signature.  */
+       cmpl    $MULTIBOOT_HEADER_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_DATA_END)
+       jz      1f
+
+       movl    (ramdisk_image - start), %esi
+       movl    (ramdisk_size - start), %ecx
+       movl    $(DATA_ADDR - 0x200), %edi
+       jmp     2f
+
+1:
+
+       movl    %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx
+       addl    $(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx
+
+2:
+       call    LOCAL(move_memory)
+
+       movsbl  %dh, %eax
+       movl    %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)
+       movsbl  (reg_edx + 2 - start), %eax
+       movl    %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)
+
+       movb    $0xFF, %dh
+
+       ljmp    $(DATA_ADDR >> 4), $0
+
+/*
+ * Parameters:
+ *   esi: source address
+ *   edi: target address
+ *   ecx: number of bytes
+ */
+
+LOCAL(move_memory):
+       incl    %ecx
+       andb    $0xFE, %cl
+       pushw   %dx
+1:
+       pushl   %esi
+       pushl   %edi
+       pushl   %ecx
+       cmpl    $BLCK_LENG, %ecx
+       jbe     2f
+       movl    $BLCK_LENG, %ecx
+2:
+       pushl   %ecx
+
+       movl    %esi, %eax
+       movw    %si, (gdt_src1 - start)
+       shrl    $16, %eax
+       movb    %al, (gdt_src1 + 2 - start)
+       movb    %ah, (gdt_src2 - start)
+
+       movl    %edi, %eax
+       movw    %di, (gdt_dst1 - start)
+       shrl    $16, %eax
+       movb    %al, (gdt_dst1 + 2 - start)
+       movb    %ah, (gdt_dst2 - start)
+
+       movw    $(gdt - start), %si
+       movb    $0x87, %ah
+       shrw    $1, %cx
+
+       int     $0x15
+
+       popl    %eax
+       popl    %ecx
+       popl    %edi
+       popl    %esi
+
+       jnc     2f
+       movw    $(err_int15_msg - start), %si
+       jmp     LOCAL(fail)
+
+2:
+
+       addl    %eax, %esi
+       addl    %eax, %edi
+       subl    %eax, %ecx
+       jnz     1b
+
+
+       popw    %dx
+       ret
+
+/*
+ * Parameters:
+ *   si: message
+ */
+
+LOCAL(fail):
+       movb    $0x0e, %ah
+       xorw    %bx, %bx
+1:
+       lodsb   (%si), %al
+       int     $0x10
+       cmpb    $0, %al
+       jne     1b
+1:     jmp     1b
+
+err_int15_msg:
+       .ascii  "move memory fails\0"
+
+       . = _start + CODE_SECTORS * 512
diff --git a/grub-core/boot/i386/pc/pxeboot.S b/grub-core/boot/i386/pc/pxeboot.S
new file mode 100644 (file)
index 0000000..446bfc7
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2005,2007,2008,2009,2010   Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/boot.h>
+
+       .file   "pxeboot.S"
+       .text
+
+       /* Start with the prehistoric environment... */
+       .code16
+
+       /* Let's go */
+.globl start, _start;
+_start:
+start:
+
+       /* Use drive number 0x7F for PXE */
+        movb   $GRUB_BOOT_MACHINE_PXE_DL, %dl
+
+       /* Jump to the real world */
+       ljmp    $0, $0x8200
+
+       /* This region is a junk. Do you say that this is wasteful?
+          But I like that the memory layout of the body is consistent
+          among different kernels rather than scamping just for 1.5KB. */
+       . = _start + 0x8200 - 0x7C00 - 0x200 - 1
+       .byte   0
diff --git a/grub-core/boot/i386/qemu/boot.S b/grub-core/boot/i386/qemu/boot.S
new file mode 100644 (file)
index 0000000..03631a2
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/kernel.h>
+
+       .text
+       .code16
+       .globl _start
+_start:
+       /* Disable interrupts.  */
+       cli
+
+       jmp     1f
+
+       . = _start + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR
+VARIABLE(grub_core_entry_addr)
+       .long   0
+1:
+
+       /* Process VGA rom.  */
+       call    $0xc000, $0x3
+
+       /* Set up %ds, %ss, and %es.  */
+       xorw    %ax, %ax
+       movw    %ax, %ds
+       movw    %ax, %ss
+       movw    %ax, %es
+
+       /* Set up the real mode stack.  */
+       movl    $GRUB_MEMORY_MACHINE_REAL_STACK, %esp
+
+       /* Transition to protected mode.  We use pushl to force generation
+          of a flat return address.  */
+       pushl   $1f
+       DATA32  jmp real_to_prot
+       .code32
+1:
+       movl    grub_core_entry_addr, %edx
+       jmp     *%edx
+
+#include "../../../kern/i386/realmode.S"
+
+       /* Intel, in its infinite wisdom, decided to put the i8086 entry point
+          *right here* and this is why we need this kludge.  */
+
+       . = GRUB_BOOT_MACHINE_SIZE - 16
+
+       .code16
+       
+       jmp     _start
+       . = GRUB_BOOT_MACHINE_SIZE
diff --git a/grub-core/boot/sparc64/ieee1275/boot.S b/grub-core/boot/sparc64/ieee1275/boot.S
new file mode 100644 (file)
index 0000000..f08258f
--- /dev/null
@@ -0,0 +1,209 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/boot.h>
+#include <grub/machine/boot.h>
+
+       .text
+       .align  4
+       .globl  _start
+_start:
+       /* OF CIF entry point arrives in %o4 */
+pic_base:
+       call    boot_continue
+        mov    %o4, CIF_REG
+
+       . = _start + GRUB_BOOT_MACHINE_VER_MAJ
+boot_version:          .byte   GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
+
+       /* The offsets to these locations are defined by the
+        * GRUB_BOOT_MACHINE_foo macros in include/grub/sparc/ieee1275/boot.h,
+        * and grub-setup uses this to patch these next three values as needed.
+        *
+        * The boot_path will be the OF device path of the partition where the
+        * rest of the GRUB kernel image resides.  kernel_sector will be set to
+        * the location of the first block of the GRUB kernel, and
+        * kernel_address is the location where we should load that first block.
+        *
+        * After loading in that block we will execute it by jumping to the
+        * load address plus the size of the prepended A.OUT header (32 bytes).
+        */
+boot_path:
+       . = _start + GRUB_BOOT_MACHINE_KERNEL_BYTE
+boot_path_end:
+kernel_byte:           .xword (2 << 9)
+kernel_address:                .word  GRUB_BOOT_MACHINE_KERNEL_ADDR
+
+prom_finddev_name:     .asciz "finddevice"
+prom_chosen_path:      .asciz "/chosen"
+prom_getprop_name:     .asciz "getprop"
+prom_stdout_name:      .asciz "stdout"
+prom_write_name:       .asciz "write"
+prom_bootpath_name:    .asciz "bootpath"
+prom_open_name:                .asciz "open"
+prom_seek_name:                .asciz "seek"
+prom_read_name:                .asciz "read"
+prom_exit_name:                .asciz "exit"
+grub_name:             .asciz "GRUB "
+#define GRUB_NAME_LEN  5
+
+       .align  4
+
+prom_open_error:
+       GET_ABS(prom_open_name, %o2)
+       call    console_write
+        mov    4, %o3
+       /* fallthru */
+
+prom_error:
+       GET_ABS(prom_exit_name, %o0)
+       /* fallthru */
+
+       /* %o0: OF call name
+        * %o1: input arg 1
+        */
+prom_call_1_1_o2:
+       clr     %o2
+       ba      prom_call_x_1
+        mov    1, %g1
+
+prom_call_getprop:
+       mov     4, %g1
+       stx     %g1, [%l1 + 256]
+       mov     CHOSEN_NODE_REG, %o1
+       ba      prom_call_x_1
+        GET_ABS(prom_getprop_name, %o0)
+
+prom_call_3_1_o1:
+       ba prom_call_3_1
+        mov    BOOTDEV_REG, %o1
+
+       
+       /* %o2: message string
+        * %o3: message length
+        */
+console_write:
+       GET_ABS(prom_write_name, %o0)
+       mov     STDOUT_NODE_REG, %o1
+       /* fallthru */
+
+       /* %o0: OF call name
+        * %o1: input arg 1
+        * %o2: input arg 2
+        * %o3: input arg 3
+        */
+prom_call_3_1: 
+       mov     3, %g1
+prom_call_x_1:
+       mov     1, %o5
+       /* fallthru */
+
+       /* %o0: OF call name
+        * %g1: num inputs
+        * %o5: num outputs
+        * %o1-%o4: inputs
+        */
+prom_call:
+       stx     %o0, [%l1 + 0x00]
+       stx     %g1, [%l1 + 0x08]
+       stx     %o5, [%l1 + 0x10]
+       stx     %o1, [%l1 + 0x18]
+       stx     %o2, [%l1 + 0x20]
+       stx     %o3, [%l1 + 0x28]
+       stx     %o4, [%l1 + 0x30]
+       jmpl    CIF_REG, %g0
+        mov    %l1, %o0
+
+boot_continue:
+       mov     %o7, PIC_REG            /* PIC base */
+       sethi   %hi(SCRATCH_PAD_BOOT), %l1      /* OF argument slots */
+
+       /* Find the /chosen node so we can fetch the stdout handle,
+        * and thus perform console output.
+        *
+        * chosen_node = prom_finddevice("/chosen")
+        */
+       GET_ABS(prom_finddev_name, %o0)
+       call    prom_call_1_1_o2
+        GET_ABS(prom_chosen_path, %o1)
+
+       ldx     [%l1 + 0x20], CHOSEN_NODE_REG
+       brz     CHOSEN_NODE_REG, prom_error
+
+       /* getprop(chosen_node, "stdout", &buffer, buffer_size) */
+        GET_ABS(prom_stdout_name, %o2)
+       add     %l1, 256, %o3
+       call    prom_call_getprop
+        mov    1024, %o4
+
+       lduw    [%l1 + 256], STDOUT_NODE_REG
+       brz,pn  STDOUT_NODE_REG, prom_error
+
+       /* write(stdout_node, "GRUB ", strlen("GRUB ")) */
+        GET_ABS(grub_name, %o2)
+       call    console_write
+        mov    GRUB_NAME_LEN, %o3
+
+       GET_ABS(boot_path, %o3)
+       ldub    [%o3], %o1
+       brnz,pn %o1, bootpath_known
+
+       /* getprop(chosen_node, "bootpath", &buffer, buffer_size) */
+        GET_ABS(prom_bootpath_name, %o2)
+       call    prom_call_getprop
+        mov    (boot_path_end - boot_path), %o4
+
+bootpath_known:        
+
+       /* Open up the boot_path, and use that handle to read the
+        * first block of the GRUB kernel image.
+        *
+        * bootdev_handle = open(boot_path)
+        */
+       GET_ABS(prom_open_name, %o0)
+       call    prom_call_1_1_o2
+        GET_ABS(boot_path, %o1)
+
+       ldx     [%l1 + 0x20], BOOTDEV_REG
+       brz,pn  BOOTDEV_REG, prom_open_error
+
+       /* Since we have 64-bit cells, the high cell of the seek offset
+        * is zero and the low cell is the entire value.
+        *
+        * seek(bootdev, 0, *kernel_byte)
+        */
+        GET_ABS(prom_seek_name, %o0)
+       clr     %o2
+       call    prom_call_3_1_o1
+        LDX_ABS(kernel_byte, 0x00, %o3)
+
+       /* read(bootdev, *kernel_address, 512) */
+       GET_ABS(prom_read_name, %o0)
+       LDUW_ABS(kernel_address, 0x00, %o2)
+       call    prom_call_3_1_o1
+        mov    512, %o3
+
+       LDUW_ABS(kernel_address, 0x00, %o2)
+       jmpl    %o2, %o7
+        nop
+
+       . = _start + GRUB_BOOT_MACHINE_CODE_END
+
+/* the last 4 bytes in the sector 0 contain the signature */
+       .word   GRUB_BOOT_MACHINE_SIGNATURE
diff --git a/grub-core/boot/sparc64/ieee1275/diskboot.S b/grub-core/boot/sparc64/ieee1275/diskboot.S
new file mode 100644 (file)
index 0000000..a4d4b5b
--- /dev/null
@@ -0,0 +1,145 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/boot.h>
+#include <grub/machine/boot.h>
+
+       .text
+       .align  4
+       .globl  _start
+_start:
+       /* First stage boot block jumps to us here.  */
+pic_base:
+       call    after_info_block
+        mov    %o7, PIC_REG
+
+prom_write_name:               .asciz "write"
+prom_seek_name:                        .asciz "seek"
+prom_read_name:                        .asciz "read"
+prom_close_name:               .asciz "close"
+
+notification_string:           .asciz "Loading kernel"
+#define NOTIFICATION_STRING_LEN        14
+
+notification_step:             .asciz "."
+#define NOTIFICATION_STEP_LEN  1
+
+notification_done:             .asciz "\r\n"
+#define NOTIFICATION_DONE_LEN  2
+
+       .align  4
+
+       /* %o2: message string
+        * %o3: message length
+        */
+console_write:
+       GET_ABS(prom_write_name, %o0)
+       mov     STDOUT_NODE_REG, %o1
+       /* fallthru */
+
+       /* %o0: OF call name
+        * %o1: input arg 1
+        * %o2: input arg 2
+        * %o3: input arg 3
+        */
+prom_call_3_1:
+       mov     3, %g1
+       mov     1, %o5
+       /* fallthru */
+
+       /* %o0: OF call name
+        * %g1: num inputs
+        * %o5: num outputs
+        * %o1-%o4: inputs
+        */
+prom_call:
+       stx     %o0, [%l1 + 0x00]
+       stx     %g1, [%l1 + 0x08]
+       stx     %o5, [%l1 + 0x10]
+       stx     %o1, [%l1 + 0x18]
+       stx     %o2, [%l1 + 0x20]
+       stx     %o3, [%l1 + 0x28]
+       stx     %o4, [%l1 + 0x30]
+       jmpl    CIF_REG, %g0
+        mov    %l1, %o0
+
+
+after_info_block:
+       sethi   %hi(SCRATCH_PAD_DISKBOOT), %l1  /* OF argument slots */
+
+       GET_ABS(notification_string, %o2)
+       call    console_write
+        mov    NOTIFICATION_STRING_LEN, %o3
+
+       GET_ABS(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE, %l2)
+       set     GRUB_BOOT_MACHINE_IMAGE_ADDRESS, %l3
+bootloop:
+       lduw    [%l2 + 0x08], %o0
+       brz     %o0, bootit
+        lduw   [%l2 + 0x00], %o3
+       sllx    %o3, 32, %o3
+       lduw    [%l2 + 0x04], %o4
+       or      %o3, %o4, %o3
+       GET_ABS(prom_seek_name, %o0)
+       mov     BOOTDEV_REG, %o1
+       clr     %o2
+       call    prom_call_3_1
+        sllx   %o3, 9, %o3
+
+       GET_ABS(prom_read_name, %o0)
+       mov     BOOTDEV_REG, %o1
+       lduw    [%l2 + 0x08], %o3
+       sllx    %o3, 9, %o3
+       mov     %l3, %o2
+       call    prom_call_3_1
+        add    %l3, %o3, %l3
+
+       GET_ABS(notification_step, %o2)
+       call    console_write
+        mov    NOTIFICATION_STEP_LEN, %o3
+
+       ba      bootloop
+        sub    %l2, GRUB_BOOT_MACHINE_LIST_SIZE, %l2
+
+bootit:
+       GET_ABS(prom_close_name, %o0)
+       mov     1, %g1
+       mov     0, %o5
+       call    prom_call
+        mov    BOOTDEV_REG, %o1
+
+       GET_ABS(notification_done, %o2)
+       call    console_write
+        mov    NOTIFICATION_DONE_LEN, %o3
+       sethi   %hi(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o2
+       jmpl    %o2 + %lo(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o7
+        mov    CIF_REG, %o4
+1:     ba,a    1b
+
+lastlist:
+       .word   0
+       .word   0
+
+       . = _start + (0x200 - GRUB_BOOT_MACHINE_LIST_SIZE)
+blocklist_default_start:
+       .word   0
+       .word   2
+blocklist_default_len:
+       .word   0
+firstlist:
diff --git a/grub-core/bus/bonito.c b/grub-core/bus/bonito.c
new file mode 100644 (file)
index 0000000..3f794c4
--- /dev/null
@@ -0,0 +1,90 @@
+/* bonito.c - PCI bonito interface.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/pci.h>
+#include <grub/misc.h>
+
+static grub_uint32_t base_win[GRUB_MACHINE_PCI_NUM_WIN];
+static const grub_size_t sizes_win[GRUB_MACHINE_PCI_NUM_WIN] = 
+  {GRUB_MACHINE_PCI_WIN1_SIZE, GRUB_MACHINE_PCI_WIN_SIZE, 
+   GRUB_MACHINE_PCI_WIN_SIZE};
+/* Usage counters.  */
+static int usage_win[GRUB_MACHINE_PCI_NUM_WIN];
+static grub_addr_t addr_win[GRUB_MACHINE_PCI_NUM_WIN] = 
+  {GRUB_MACHINE_PCI_WIN1_ADDR, GRUB_MACHINE_PCI_WIN2_ADDR,
+   GRUB_MACHINE_PCI_WIN3_ADDR};
+
+static inline void
+write_bases (void)
+{
+  int i;
+  grub_uint32_t reg = 0;
+  for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) 
+    reg |= (((base_win[i] >> GRUB_MACHINE_PCI_WIN_SHIFT) 
+            & GRUB_MACHINE_PCI_WIN_MASK) 
+           >> (i * GRUB_MACHINE_PCI_WIN_MASK_SIZE));
+  GRUB_MACHINE_PCI_IO_CTRL_REG = reg;
+}
+
+volatile void *
+grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)),
+                          grub_addr_t base, grub_size_t size)
+{
+  int i;
+  grub_addr_t newbase;
+
+  /* First try already used registers. */
+  for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++)
+    if (usage_win[i] && base_win[i] <= base 
+       && base_win[i] + sizes_win[i] > base + size)
+      {
+       usage_win[i]++;
+       return (void *) 
+         (addr_win[i] | (base & GRUB_MACHINE_PCI_WIN_OFFSET_MASK));
+      }
+  /* Map new register.  */
+  newbase = base & ~GRUB_MACHINE_PCI_WIN_OFFSET_MASK;
+  for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++)
+    if (!usage_win[i] && newbase <= base 
+       && newbase + sizes_win[i] > base + size)
+      {
+       usage_win[i]++;
+       base_win[i] = newbase;
+       write_bases ();
+       return (void *) 
+         (addr_win[i] | (base & GRUB_MACHINE_PCI_WIN_OFFSET_MASK));
+      }
+  grub_fatal ("Out of PCI windows.");
+}
+
+void
+grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)),
+                            volatile void *mem __attribute__ ((unused)),
+                            grub_size_t size __attribute__ ((unused)))
+{
+  int i;
+  for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++)
+    if (usage_win[i] && addr_win[i] 
+       == (((grub_addr_t) mem) & ~GRUB_MACHINE_PCI_WIN_OFFSET_MASK))
+      {
+       usage_win[i]--;
+       return;
+      }
+  grub_fatal ("Tried to unmap not mapped region");
+}
diff --git a/grub-core/bus/emu/pci.c b/grub-core/bus/emu/pci.c
new file mode 100644 (file)
index 0000000..d1beb56
--- /dev/null
@@ -0,0 +1,77 @@
+/* pci.c - Generic PCI interfaces.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/pci.h>
+#include <grub/dl.h>
+#include <grub/emu/misc.h>
+#include <grub/util/misc.h>
+
+grub_pci_address_t
+grub_pci_make_address (grub_pci_device_t dev, int reg)
+{
+  grub_pci_address_t ret;
+  ret.dev = dev;
+  ret.pos = reg;
+  return ret;
+}
+
+void
+grub_pci_iterate (grub_pci_iteratefunc_t hook)
+{
+  struct pci_device_iterator *iter;
+  struct pci_slot_match slot;
+  struct pci_device *dev;
+  slot.domain = PCI_MATCH_ANY;
+  slot.bus = PCI_MATCH_ANY;
+  slot.dev = PCI_MATCH_ANY;
+  slot.func = PCI_MATCH_ANY;
+  iter = pci_slot_match_iterator_create (&slot);
+  while ((dev = pci_device_next (iter)))
+    hook (dev, dev->vendor_id | (dev->device_id << 16));
+  pci_iterator_destroy (iter);
+}
+
+void *
+grub_pci_device_map_range (grub_pci_device_t dev, grub_addr_t base,
+                          grub_size_t size)
+{
+  void *addr;
+  int err;
+  err = pci_device_map_range (dev, base, size, PCI_DEV_MAP_FLAG_WRITABLE, &addr);
+  if (err)
+    grub_util_error ("mapping 0x%x failed (error %d)\n", base, err);
+  return addr;
+}
+
+void
+grub_pci_device_unmap_range (grub_pci_device_t dev, void *mem,
+                            grub_size_t size)
+{
+  pci_device_unmap_range (dev, mem, size);
+}
+
+GRUB_MOD_INIT (pci)
+{
+  pci_system_init ();
+}
+
+GRUB_MOD_FINI (pci)
+{
+  pci_system_cleanup ();
+}
diff --git a/grub-core/bus/pci.c b/grub-core/bus/pci.c
new file mode 100644 (file)
index 0000000..a08e534
--- /dev/null
@@ -0,0 +1,65 @@
+/* pci.c - Generic PCI interfaces.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/pci.h>
+
+grub_pci_address_t
+grub_pci_make_address (grub_pci_device_t dev, int reg)
+{
+  return (1 << 31) | (dev.bus << 16) | (dev.device << 11)
+    | (dev.function << 8) | reg;
+}
+
+void
+grub_pci_iterate (grub_pci_iteratefunc_t hook)
+{
+  grub_pci_device_t dev;
+  grub_pci_address_t addr;
+  grub_pci_id_t id;
+  grub_uint32_t hdr;
+
+  for (dev.bus = 0; dev.bus < GRUB_PCI_NUM_BUS; dev.bus++)
+    {
+      for (dev.device = 0; dev.device < GRUB_PCI_NUM_DEVICES; dev.device++)
+       {
+         for (dev.function = 0; dev.function < 8; dev.function++)
+           {
+             addr = grub_pci_make_address (dev, GRUB_PCI_REG_PCI_ID);
+             id = grub_pci_read (addr);
+
+             /* Check if there is a device present.  */
+             if (id >> 16 == 0xFFFF)
+               continue;
+
+             if (hook (dev, id))
+               return;
+
+             /* Probe only func = 0 if the device if not multifunction */
+             if (dev.function == 0)
+               {
+                 addr = grub_pci_make_address (dev, GRUB_PCI_REG_CACHELINE);
+                 hdr = grub_pci_read (addr);
+                 if (!(hdr & 0x800000))
+                   break;
+               }
+           }
+       }
+    }
+}
diff --git a/grub-core/bus/usb/emu/usb.c b/grub-core/bus/usb/emu/usb.c
new file mode 100644 (file)
index 0000000..a687eea
--- /dev/null
@@ -0,0 +1,195 @@
+/*  usb.c -- libusb USB support for GRUB.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <usb.h>
+#include <grub/usb.h>
+#include <grub/dl.h>
+
+\f
+static struct grub_usb_controller_dev usb_controller =
+{
+  .name = "libusb"
+};
+
+static struct grub_usb_device *grub_usb_devs[128];
+
+struct usb_bus *busses;
+
+static grub_err_t
+grub_libusb_devices (void)
+
+{
+  struct usb_bus *bus;
+  int last = 0;
+
+  busses = usb_get_busses();
+
+  for (bus = busses; bus; bus = bus->next)
+    {
+      struct usb_device *usbdev;
+      struct grub_usb_device *dev;
+
+      for (usbdev = bus->devices; usbdev; usbdev = usbdev->next)
+       {
+         struct usb_device_descriptor *desc = &usbdev->descriptor;
+         grub_err_t err;
+
+         if (! desc->bcdUSB)
+           continue;
+
+         dev = grub_malloc (sizeof (*dev));
+         if (! dev)
+           return grub_errno;
+
+         dev->data = usbdev;
+
+         /* Fill in all descriptors.  */
+         err = grub_usb_device_initialize (dev);
+         if (err)
+           {
+             grub_errno = GRUB_ERR_NONE;
+             continue;
+           }
+
+         /* Register the device.  */
+         grub_usb_devs[last++] = dev;
+       }
+    }
+
+  return GRUB_USB_ERR_NONE;
+}
+
+\f
+int
+grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
+{
+  int i;
+
+  for (i = 0; i < 128; i++)
+    {
+      if (grub_usb_devs[i])
+       {
+         if (hook (grub_usb_devs[i]))
+             return 1;
+       }
+    }
+
+  return 0;
+}
+
+grub_usb_err_t
+grub_usb_root_hub (grub_usb_controller_t controller __attribute__((unused)))
+{
+  return GRUB_USB_ERR_NONE;
+}
+
+grub_usb_err_t
+grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype,
+                     grub_uint8_t request, grub_uint16_t value,
+                     grub_uint16_t index, grub_size_t size, char *data)
+{
+  usb_dev_handle *devh;
+  struct usb_device *d = dev->data;
+
+  devh = usb_open (d);
+  if (usb_control_msg (devh, reqtype, request,
+                      value, index, data, size, 20) < 0)
+    {
+      usb_close (devh);
+      return GRUB_USB_ERR_STALL;
+    }
+
+  usb_close (devh);
+
+  return GRUB_USB_ERR_NONE;
+}
+
+grub_usb_err_t
+grub_usb_bulk_read (grub_usb_device_t dev,
+                   int endpoint, grub_size_t size, char *data)
+{
+  usb_dev_handle *devh;
+  struct usb_device *d = dev->data;
+
+  devh = usb_open (d);
+  if (usb_claim_interface (devh, 0) < 1)
+    {
+      usb_close (devh);
+      return GRUB_USB_ERR_STALL;
+    }
+
+  if (usb_bulk_read (devh, endpoint, data, size, 20) < 1)
+    {
+      usb_close (devh);
+      return GRUB_USB_ERR_STALL;
+    }
+
+  usb_release_interface (devh, 0);
+  usb_close (devh);
+
+  return GRUB_USB_ERR_NONE;
+}
+
+grub_usb_err_t
+grub_usb_bulk_write (grub_usb_device_t dev,
+                    int endpoint, grub_size_t size, char *data)
+{
+  usb_dev_handle *devh;
+  struct usb_device *d = dev->data;
+
+  devh = usb_open (d);
+  if (usb_claim_interface (devh, 0) < 0)
+    goto fail;
+
+  if (usb_bulk_write (devh, endpoint, data, size, 20) < 0)
+    goto fail;
+
+  if (usb_release_interface (devh, 0) < 0)
+    goto fail;
+
+  usb_close (devh);
+
+  return GRUB_USB_ERR_NONE;
+
+ fail:
+  usb_close (devh);
+  return GRUB_USB_ERR_STALL;
+}
+
+GRUB_MOD_INIT (libusb)
+{
+  usb_init();
+  usb_find_busses();
+  usb_find_devices();
+
+  if (grub_libusb_devices ())
+    return;
+
+  grub_usb_controller_dev_register (&usb_controller);
+
+  return;
+}
+
+GRUB_MOD_FINI (libusb)
+{
+  return;
+}
diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c
new file mode 100644 (file)
index 0000000..6d185bc
--- /dev/null
@@ -0,0 +1,611 @@
+/* ohci.c - OHCI Support.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/usb.h>
+#include <grub/usbtrans.h>
+#include <grub/misc.h>
+#include <grub/pci.h>
+#include <grub/cpu/pci.h>
+#include <grub/i386/io.h>
+#include <grub/time.h>
+
+struct grub_ohci_hcca
+{
+  /* Pointers to Interrupt Endpoint Descriptors.  Not used by
+     GRUB.  */
+  grub_uint32_t inttable[32];
+
+  /* Current frame number.  */
+  grub_uint16_t framenumber;
+
+  grub_uint16_t pad;
+
+  /* List of completed TDs.  */
+  grub_uint32_t donehead;
+
+  grub_uint8_t reserved[116];
+} __attribute__((packed));
+
+/* OHCI Endpoint Descriptor.  */
+struct grub_ohci_ed
+{
+  grub_uint32_t target;
+  grub_uint32_t td_tail;
+  grub_uint32_t td_head;
+  grub_uint32_t next_ed;
+} __attribute__((packed));
+
+struct grub_ohci_td
+{
+  /* Information used to construct the TOKEN packet.  */
+  grub_uint32_t token;
+
+  grub_uint32_t buffer;
+  grub_uint32_t next_td;
+  grub_uint32_t buffer_end;
+} __attribute__((packed));
+
+typedef struct grub_ohci_td *grub_ohci_td_t;
+typedef struct grub_ohci_ed *grub_ohci_ed_t;
+
+struct grub_ohci
+{
+  volatile grub_uint32_t *iobase;
+  volatile struct grub_ohci_hcca *hcca;
+  struct grub_ohci *next;
+};
+
+static struct grub_ohci *ohci;
+
+typedef enum
+{
+  GRUB_OHCI_REG_REVISION = 0x00,
+  GRUB_OHCI_REG_CONTROL,
+  GRUB_OHCI_REG_CMDSTATUS,
+  GRUB_OHCI_REG_INTSTATUS,
+  GRUB_OHCI_REG_INTENA,
+  GRUB_OHCI_REG_INTDIS,
+  GRUB_OHCI_REG_HCCA,
+  GRUB_OHCI_REG_PERIODIC,
+  GRUB_OHCI_REG_CONTROLHEAD,
+  GRUB_OHCI_REG_CONTROLCURR,
+  GRUB_OHCI_REG_BULKHEAD,
+  GRUB_OHCI_REG_BULKCURR,
+  GRUB_OHCI_REG_DONEHEAD,
+  GRUB_OHCI_REG_FRAME_INTERVAL,
+  GRUB_OHCI_REG_RHUBA = 18,
+  GRUB_OHCI_REG_RHUBPORT = 21
+} grub_ohci_reg_t;
+
+static grub_uint32_t
+grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg)
+{
+  return grub_le_to_cpu32 (*(o->iobase + reg));
+}
+
+static void
+grub_ohci_writereg32 (struct grub_ohci *o,
+                     grub_ohci_reg_t reg, grub_uint32_t val)
+{
+  *(o->iobase + reg) = grub_cpu_to_le32 (val);
+}
+
+\f
+
+/* Iterate over all PCI devices.  Determine if a device is an OHCI
+   controller.  If this is the case, initialize it.  */
+static int NESTED_FUNC_ATTR
+grub_ohci_pci_iter (grub_pci_device_t dev,
+                   grub_pci_id_t pciid __attribute__((unused)))
+{
+  grub_uint32_t class_code;
+  grub_uint32_t class;
+  grub_uint32_t subclass;
+  grub_uint32_t interf;
+  grub_uint32_t base;
+  grub_pci_address_t addr;
+  struct grub_ohci *o;
+  grub_uint32_t revision;
+  grub_uint32_t frame_interval;
+
+  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+  class_code = grub_pci_read (addr) >> 8;
+
+  interf = class_code & 0xFF;
+  subclass = (class_code >> 8) & 0xFF;
+  class = class_code >> 16;
+
+  /* If this is not an OHCI controller, just return.  */
+  if (class != 0x0c || subclass != 0x03 || interf != 0x10)
+    return 0;
+
+  /* Determine IO base address.  */
+  addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
+  base = grub_pci_read (addr);
+
+#if 0
+  /* Stop if there is no IO space base address defined.  */
+  if (! (base & 1))
+    return 0;
+#endif
+
+  /* Allocate memory for the controller and register it.  */
+  o = grub_malloc (sizeof (*o));
+  if (! o)
+    return 1;
+
+  o->iobase = (grub_uint32_t *) base;
+
+  /* Reserve memory for the HCCA.  */
+  o->hcca = (struct grub_ohci_hcca *) grub_memalign (256, 256);
+
+  grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x base=%p\n",
+               class, subclass, interf, o->iobase);
+
+  /* Check if the OHCI revision is actually 1.0 as supported.  */
+  revision = grub_ohci_readreg32 (o, GRUB_OHCI_REG_REVISION);
+  grub_dprintf ("ohci", "OHCI revision=0x%02x\n", revision & 0xFF);
+  if ((revision & 0xFF) != 0x10)
+    goto fail;
+
+  /* Backup the frame interval register.  */
+  frame_interval = grub_ohci_readreg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL);
+
+  /* Suspend the OHCI by issuing a reset.  */
+  grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic.  */
+  grub_millisleep (1);
+  grub_dprintf ("ohci", "OHCI reset\n");
+
+  /* Restore the frame interval register.  */
+  grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, frame_interval);
+
+  /* Setup the HCCA.  */
+  grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, (grub_uint32_t) o->hcca);
+  grub_dprintf ("ohci", "OHCI HCCA\n");
+
+  /* Enable the OHCI.  */
+  grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL,
+                       (2 << 6));
+  grub_dprintf ("ohci", "OHCI enable: 0x%02x\n",
+               (grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) >> 6) & 3);
+
+  /* Link to ohci now that initialisation is successful.  */
+  o->next = ohci;
+  ohci = o;
+
+  return 0;
+
+ fail:
+  if (o)
+    grub_free ((void *) o->hcca);
+  grub_free (o);
+
+  return 1;
+}
+
+
+static void
+grub_ohci_inithw (void)
+{
+  grub_pci_iterate (grub_ohci_pci_iter);
+}
+
+\f
+
+static int
+grub_ohci_iterate (int (*hook) (grub_usb_controller_t dev))
+{
+  struct grub_ohci *o;
+  struct grub_usb_controller dev;
+
+  for (o = ohci; o; o = o->next)
+    {
+      dev.data = o;
+      if (hook (&dev))
+       return 1;
+    }
+
+  return 0;
+}
+
+static void
+grub_ohci_transaction (grub_ohci_td_t td,
+                      grub_transfer_type_t type, unsigned int toggle,
+                      grub_size_t size, char *data)
+{
+  grub_uint32_t token;
+  grub_uint32_t buffer;
+  grub_uint32_t buffer_end;
+
+  grub_dprintf ("ohci", "OHCI transaction td=%p type=%d, toggle=%d, size=%d\n",
+               td, type, toggle, size);
+
+  switch (type)
+    {
+    case GRUB_USB_TRANSFER_TYPE_SETUP:
+      token = 0 << 19;
+      break;
+    case GRUB_USB_TRANSFER_TYPE_IN:
+      token = 2 << 19;
+      break;
+    case GRUB_USB_TRANSFER_TYPE_OUT:
+      token = 1 << 19;
+      break;
+    default:
+      token = 0;
+      break;
+    }
+
+  /* Generate no interrupts.  */
+  token |= 7 << 21;
+
+  /* Set the token.  */
+  token |= toggle << 24;
+  token |= 1 << 25;
+
+  buffer = (grub_uint32_t) data;
+  buffer_end = buffer + size - 1;
+
+  td->token = grub_cpu_to_le32 (token);
+  td->buffer = grub_cpu_to_le32 (buffer);
+  td->next_td = 0;
+  td->buffer_end = grub_cpu_to_le32 (buffer_end);
+}
+
+static grub_usb_err_t
+grub_ohci_transfer (grub_usb_controller_t dev,
+                   grub_usb_transfer_t transfer)
+{
+  struct grub_ohci *o = (struct grub_ohci *) dev->data;
+  grub_ohci_ed_t ed;
+  grub_ohci_td_t td_list;
+  grub_uint32_t target;
+  grub_uint32_t td_tail;
+  grub_uint32_t td_head;
+  grub_uint32_t status;
+  grub_uint32_t control;
+  grub_usb_err_t err;
+  int i;
+
+  /* Allocate an Endpoint Descriptor.  */
+  ed = grub_memalign (16, sizeof (*ed));
+  if (! ed)
+    return GRUB_USB_ERR_INTERNAL;
+
+  td_list = grub_memalign (16, sizeof (*td_list) * (transfer->transcnt + 1));
+  if (! td_list)
+    {
+      grub_free ((void *) ed);
+      return GRUB_USB_ERR_INTERNAL;
+    }
+
+  grub_dprintf ("ohci", "alloc=%p\n", td_list);
+
+  /* Setup all Transfer Descriptors.  */
+  for (i = 0; i < transfer->transcnt; i++)
+    {
+      grub_usb_transaction_t tr = &transfer->transactions[i];
+
+      grub_ohci_transaction (&td_list[i], tr->pid, tr->toggle,
+                            tr->size, tr->data);
+
+      td_list[i].next_td = grub_cpu_to_le32 (&td_list[i + 1]);
+    }
+
+  /* Setup the Endpoint Descriptor.  */
+
+  /* Set the device address.  */
+  target = transfer->devaddr;
+
+  /* Set the endpoint.  */
+  target |= transfer->endpoint << 7;
+
+  /* Set the device speed.  */
+  target |= (transfer->dev->speed == GRUB_USB_SPEED_LOW) << 13;
+
+  /* Set the maximum packet size.  */
+  target |= transfer->max << 16;
+
+  td_head = (grub_uint32_t) td_list;
+
+  td_tail = (grub_uint32_t) &td_list[transfer->transcnt];
+
+  ed->target = grub_cpu_to_le32 (target);
+  ed->td_head = grub_cpu_to_le32 (td_head);
+  ed->td_tail = grub_cpu_to_le32 (td_tail);
+  ed->next_ed = grub_cpu_to_le32 (0);
+
+  grub_dprintf ("ohci", "program OHCI\n");
+
+  /* Program the OHCI to actually transfer.  */
+  switch (transfer->type)
+    {
+    case GRUB_USB_TRANSACTION_TYPE_BULK:
+      {
+       grub_dprintf ("ohci", "add to bulk list\n");
+
+       status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
+       control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
+
+       /* Disable the Control and Bulk lists.  */
+       control &= ~(3 << 4);
+       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
+
+       /* Clear BulkListFilled.  */
+       status &= ~(1 << 2);
+       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
+
+       grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, (grub_uint32_t) ed);
+
+       /* Enable the Bulk list.  */
+       control |= 1 << 5;
+       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
+
+       /* Set BulkListFilled.  */
+       status |= 1 << 2;
+       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
+
+       break;
+      }
+
+    case GRUB_USB_TRANSACTION_TYPE_CONTROL:
+      {
+       grub_dprintf ("ohci", "add to control list\n");
+       status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
+       control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
+
+       /* Disable the Control and Bulk lists.  */
+       control &= ~(3 << 4);
+       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
+
+       /* Clear ControlListFilled.  */
+       status &= ~(1 << 1);
+       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
+
+       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD,
+                             (grub_uint32_t) ed);
+       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD+1,
+                             (grub_uint32_t) ed);
+
+       /* Enable the Control list.  */
+       control |= 1 << 4;
+       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
+
+       /* Set ControlListFilled.  */
+       status |= 1 << 1;
+       grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
+       break;
+      }
+    }
+
+  grub_dprintf ("ohci", "wait for completion\n");
+  grub_dprintf ("ohci", "control=0x%02x status=0x%02x\n",
+               grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL),
+               grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS));
+
+  /* Wait until the transfer is completed or STALLs.  */
+  while ((ed->td_head & ~0xf) != (ed->td_tail & ~0xf))
+    {
+      grub_cpu_idle ();
+
+      grub_dprintf ("ohci", "head=0x%02x tail=0x%02x\n", ed->td_head, ed->td_tail);
+
+      /* Detected a STALL.  */
+      if (ed->td_head & 1)
+       break;
+    }
+
+  grub_dprintf ("ohci", "complete\n");
+
+/*   if (ed->td_head & 1) */
+/*     err = GRUB_USB_ERR_STALL; */
+/*   else if (ed->td */
+
+
+  if (ed->td_head & 1)
+    {
+      grub_uint8_t errcode;
+      grub_ohci_td_t tderr;
+
+      tderr = (grub_ohci_td_t) grub_ohci_readreg32 (o,
+                                                   GRUB_OHCI_REG_DONEHEAD);
+      errcode = tderr->token >> 28;
+
+      switch (errcode)
+       {
+       case 0:
+         /* XXX: Should not happen!  */
+         grub_error (GRUB_ERR_IO, "OHCI without reporting the reason");
+         err = GRUB_USB_ERR_INTERNAL;
+         break;
+
+       case 1:
+         /* XXX: CRC error.  */
+         err = GRUB_USB_ERR_TIMEOUT;
+         break;
+
+       case 2:
+         err = GRUB_USB_ERR_BITSTUFF;
+         break;
+
+       case 3:
+         /* XXX: Data Toggle error.  */
+         err = GRUB_USB_ERR_DATA;
+         break;
+
+       case 4:
+         err = GRUB_USB_ERR_STALL;
+         break;
+
+       case 5:
+         /* XXX: Not responding.  */
+         err = GRUB_USB_ERR_TIMEOUT;
+         break;
+
+       case 6:
+         /* XXX: PID Check bits failed.  */
+         err = GRUB_USB_ERR_BABBLE;
+         break;
+
+       case 7:
+         /* XXX: PID unexpected failed.  */
+         err = GRUB_USB_ERR_BABBLE;
+         break;
+
+       case 8:
+         /* XXX: Data overrun error.  */
+         err = GRUB_USB_ERR_DATA;
+         break;
+
+       case 9:
+         /* XXX: Data underrun error.  */
+         err = GRUB_USB_ERR_DATA;
+         break;
+
+       case 10:
+         /* XXX: Reserved.  */
+         err = GRUB_USB_ERR_NAK;
+         break;
+
+       case 11:
+         /* XXX: Reserved.  */
+         err = GRUB_USB_ERR_NAK;
+         break;
+
+       case 12:
+         /* XXX: Buffer overrun.  */
+         err = GRUB_USB_ERR_DATA;
+         break;
+
+       case 13:
+         /* XXX: Buffer underrun.  */
+         err = GRUB_USB_ERR_DATA;
+         break;
+
+       default:
+         err = GRUB_USB_ERR_NAK;
+         break;
+       }
+    }
+  else
+    err = GRUB_USB_ERR_NONE;
+
+  /* Disable the Control and Bulk lists.  */
+  control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
+  control &= ~(3 << 4);
+  grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
+
+  /* Clear BulkListFilled and ControlListFilled.  */
+  status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
+  status &= ~((1 << 2) | (1 << 3));
+  grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
+
+  /* XXX */
+  grub_free (td_list);
+  grub_free (ed);
+
+  return err;
+}
+
+static grub_err_t
+grub_ohci_portstatus (grub_usb_controller_t dev,
+                     unsigned int port, unsigned int enable)
+{
+   struct grub_ohci *o = (struct grub_ohci *) dev->data;
+   grub_uint32_t status;
+
+   /* Reset the port.  */
+   status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+   status |= (1 << 4); /* XXX: Magic.  */
+   grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status);
+   grub_millisleep (100);
+
+   /* End the reset signaling.  */
+   status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+   status |= (1 << 20); /* XXX: Magic.  */
+   grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status);
+   grub_millisleep (10);
+
+   /* Enable the port.  */
+   status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+   status |= (enable << 1); /* XXX: Magic.  */
+   grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status);
+
+   status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+   grub_dprintf ("ohci", "portstatus=0x%02x\n", status);
+
+   return GRUB_ERR_NONE;
+}
+
+static grub_usb_speed_t
+grub_ohci_detect_dev (grub_usb_controller_t dev, int port)
+{
+   struct grub_ohci *o = (struct grub_ohci *) dev->data;
+   grub_uint32_t status;
+
+   status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
+
+   grub_dprintf ("ohci", "detect_dev status=0x%02x\n", status);
+
+   if (! (status & 1))
+     return GRUB_USB_SPEED_NONE;
+   else if (status & (1 << 9))
+     return GRUB_USB_SPEED_LOW;
+   else
+     return GRUB_USB_SPEED_FULL;
+}
+
+static int
+grub_ohci_hubports (grub_usb_controller_t dev)
+{
+  struct grub_ohci *o = (struct grub_ohci *) dev->data;
+  grub_uint32_t portinfo;
+
+  portinfo = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA);
+
+  grub_dprintf ("ohci", "root hub ports=%d\n", portinfo & 0xFF);
+
+  /* The root hub has exactly two ports.  */
+  return portinfo & 0xFF;
+}
+
+
+\f
+static struct grub_usb_controller_dev usb_controller =
+{
+  .name = "ohci",
+  .iterate = grub_ohci_iterate,
+  .transfer = grub_ohci_transfer,
+  .hubports = grub_ohci_hubports,
+  .portstatus = grub_ohci_portstatus,
+  .detect_dev = grub_ohci_detect_dev
+};
+
+GRUB_MOD_INIT(ohci)
+{
+  grub_ohci_inithw ();
+  grub_usb_controller_dev_register (&usb_controller);
+}
+
+GRUB_MOD_FINI(ohci)
+{
+  grub_usb_controller_dev_unregister (&usb_controller);
+}
diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c
new file mode 100644 (file)
index 0000000..947f236
--- /dev/null
@@ -0,0 +1,689 @@
+/* uhci.c - UHCI Support.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/usb.h>
+#include <grub/usbtrans.h>
+#include <grub/pci.h>
+#include <grub/i386/io.h>
+#include <grub/time.h>
+
+#define GRUB_UHCI_IOMASK       (0x7FF << 5)
+
+typedef enum
+  {
+    GRUB_UHCI_REG_USBCMD = 0x00,
+    GRUB_UHCI_REG_FLBASEADD = 0x08,
+    GRUB_UHCI_REG_PORTSC1 = 0x10,
+    GRUB_UHCI_REG_PORTSC2 = 0x12
+  } grub_uhci_reg_t;
+
+#define GRUB_UHCI_LINK_TERMINATE       1
+#define GRUB_UHCI_LINK_QUEUE_HEAD      2
+
+
+/* UHCI Queue Head.  */
+struct grub_uhci_qh
+{
+  /* Queue head link pointer which points to the next queue head.  */
+  grub_uint32_t linkptr;
+
+  /* Queue element link pointer which points to the first data object
+     within the queue.  */
+  grub_uint32_t elinkptr;
+
+  /* Queue heads are aligned on 16 bytes, pad so a queue head is 16
+     bytes so we can store many in a 4K page.  */
+  grub_uint8_t pad[8];
+} __attribute__ ((packed));
+
+/* UHCI Transfer Descriptor.  */
+struct grub_uhci_td
+{
+  /* Pointer to the next TD in the list.  */
+  grub_uint32_t linkptr;
+
+  /* Control and status bits.  */
+  grub_uint32_t ctrl_status;
+
+  /* All information required to transfer the Token packet.  */
+  grub_uint32_t token;
+
+  /* A pointer to the data buffer, UHCI requires this pointer to be 32
+     bits.  */
+  grub_uint32_t buffer;
+
+  /* Another linkptr that is not overwritten by the Host Controller.
+     This is GRUB specific.  */
+  grub_uint32_t linkptr2;
+
+  /* 3 additional 32 bits words reserved for the Host Controller Driver.  */
+  grub_uint32_t data[3];
+} __attribute__ ((packed));
+
+typedef volatile struct grub_uhci_td *grub_uhci_td_t;
+typedef volatile struct grub_uhci_qh *grub_uhci_qh_t;
+
+struct grub_uhci
+{
+  int iobase;
+  grub_uint32_t *framelist;
+
+  /* 256 Queue Heads.  */
+  grub_uhci_qh_t qh;
+
+  /* 256 Transfer Descriptors.  */
+  grub_uhci_td_t td;
+
+  /* Free Transfer Descriptors.  */
+  grub_uhci_td_t tdfree;
+
+  struct grub_uhci *next;
+};
+
+static struct grub_uhci *uhci;
+
+static grub_uint16_t
+grub_uhci_readreg16 (struct grub_uhci *u, grub_uhci_reg_t reg)
+{
+  return grub_inw (u->iobase + reg);
+}
+
+#if 0
+static grub_uint32_t
+grub_uhci_readreg32 (struct grub_uhci *u, grub_uhci_reg_t reg)
+{
+  return grub_inl (u->iobase + reg);
+}
+#endif
+
+static void
+grub_uhci_writereg16 (struct grub_uhci *u,
+                     grub_uhci_reg_t reg, grub_uint16_t val)
+{
+  grub_outw (val, u->iobase + reg);
+}
+
+static void
+grub_uhci_writereg32 (struct grub_uhci *u,
+                   grub_uhci_reg_t reg, grub_uint32_t val)
+{
+  grub_outl (val, u->iobase + reg);
+}
+
+static grub_err_t
+grub_uhci_portstatus (grub_usb_controller_t dev,
+                     unsigned int port, unsigned int enable);
+
+
+/* Iterate over all PCI devices.  Determine if a device is an UHCI
+   controller.  If this is the case, initialize it.  */
+static int NESTED_FUNC_ATTR
+grub_uhci_pci_iter (grub_pci_device_t dev,
+                   grub_pci_id_t pciid __attribute__((unused)))
+{
+  grub_uint32_t class_code;
+  grub_uint32_t class;
+  grub_uint32_t subclass;
+  grub_uint32_t interf;
+  grub_uint32_t base;
+  grub_uint32_t fp;
+  grub_pci_address_t addr;
+  struct grub_uhci *u;
+  int i;
+
+  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+  class_code = grub_pci_read (addr) >> 8;
+
+  interf = class_code & 0xFF;
+  subclass = (class_code >> 8) & 0xFF;
+  class = class_code >> 16;
+
+  /* If this is not an UHCI controller, just return.  */
+  if (class != 0x0c || subclass != 0x03 || interf != 0x00)
+    return 0;
+
+  /* Determine IO base address.  */
+  addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG4);
+  base = grub_pci_read (addr);
+  /* Stop if there is no IO space base address defined.  */
+  if (! (base & 1))
+    return 0;
+
+  /* Allocate memory for the controller and register it.  */
+  u = grub_zalloc (sizeof (*u));
+  if (! u)
+    return 1;
+
+  u->iobase = base & GRUB_UHCI_IOMASK;
+  grub_dprintf ("uhci", "class=0x%02x 0x%02x interface 0x%02x base=0x%x\n",
+               class, subclass, interf, u->iobase);
+
+  /* Reserve a page for the frame list.  */
+  u->framelist = grub_memalign (4096, 4096);
+  if (! u->framelist)
+    goto fail;
+
+  /* The framelist pointer of UHCI is only 32 bits, make sure this
+     code works on on 64 bits architectures.  */
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+  if ((grub_uint64_t) u->framelist >> 32)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                 "allocated frame list memory not <4GB");
+      goto fail;
+    }
+#endif
+
+  /* The QH pointer of UHCI is only 32 bits, make sure this
+     code works on on 64 bits architectures.  */
+  u->qh = (grub_uhci_qh_t) grub_memalign (4096, 4096);
+  if (! u->qh)
+    goto fail;
+
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+  if ((grub_uint64_t) u->qh >> 32)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "allocated QH memory not <4GB");
+      goto fail;
+    }
+#endif
+
+  /* The TD pointer of UHCI is only 32 bits, make sure this
+     code works on on 64 bits architectures.  */
+  u->td = (grub_uhci_td_t) grub_memalign (4096, 4096*2);
+  if (! u->td)
+    goto fail;
+
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+  if ((grub_uint64_t) u->td >> 32)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "allocated TD memory not <4GB");
+      goto fail;
+    }
+#endif
+
+  /* Link all Transfer Descriptors in a list of available Transfer
+     Descriptors.  */
+  for (i = 0; i < 256; i++)
+    u->td[i].linkptr = (grub_uint32_t) &u->td[i + 1];
+  u->td[255 - 1].linkptr = 0;
+  u->tdfree = u->td;
+
+  /* Make sure UHCI is disabled!  */
+  grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 0);
+
+  /* Setup the frame list pointers.  Since no isochronous transfers
+     are and will be supported, they all point to the (same!) queue
+     head.  */
+  fp = (grub_uint32_t) u->qh & (~15);
+  /* Mark this as a queue head.  */
+  fp |= 2;
+  for (i = 0; i < 1024; i++)
+    u->framelist[i] = fp;
+  /* Program the framelist address into the UHCI controller.  */
+  grub_uhci_writereg32 (u, GRUB_UHCI_REG_FLBASEADD,
+                       (grub_uint32_t) u->framelist);
+
+  /* Make the Queue Heads point to each other.  */
+  for (i = 0; i < 256; i++)
+    {
+      /* Point to the next QH.  */
+      u->qh[i].linkptr = (grub_uint32_t) (&u->qh[i + 1]) & (~15);
+
+      /* This is a QH.  */
+      u->qh[i].linkptr |= GRUB_UHCI_LINK_QUEUE_HEAD;
+
+      /* For the moment, do not point to a Transfer Descriptor.  These
+        are set at transfer time, so just terminate it.  */
+      u->qh[i].elinkptr = 1;
+    }
+
+  /* The last Queue Head should terminate.  256 are too many QHs so
+     just use 50.  */
+  u->qh[50 - 1].linkptr = 1;
+
+  /* Enable UHCI again.  */
+  grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 1 | (1 << 7));
+
+  /* UHCI is initialized and ready for transfers.  */
+  grub_dprintf ("uhci", "UHCI initialized\n");
+
+
+#if 0
+  {
+    int i;
+    for (i = 0; i < 10; i++)
+      {
+       grub_uint16_t frnum;
+
+       frnum = grub_uhci_readreg16 (u, 6);
+       grub_dprintf ("uhci", "Framenum=%d\n", frnum);
+       grub_millisleep (100);
+      }
+  }
+#endif
+
+  /* Link to uhci now that initialisation is successful.  */
+  u->next = uhci;
+  uhci = u;
+
+  return 0;
+
+ fail:
+  if (u)
+    {
+      grub_free ((void *) u->qh);
+      grub_free (u->framelist);
+    }
+  grub_free (u);
+
+  return 1;
+}
+
+static void
+grub_uhci_inithw (void)
+{
+  grub_pci_iterate (grub_uhci_pci_iter);
+}
+
+static grub_uhci_td_t
+grub_alloc_td (struct grub_uhci *u)
+{
+  grub_uhci_td_t ret;
+
+  /* Check if there is a Transfer Descriptor available.  */
+  if (! u->tdfree)
+    return NULL;
+
+  ret = u->tdfree;
+  u->tdfree = (grub_uhci_td_t) u->tdfree->linkptr;
+
+  return ret;
+}
+
+static void
+grub_free_td (struct grub_uhci *u, grub_uhci_td_t td)
+{
+  td->linkptr = (grub_uint32_t) u->tdfree;
+  u->tdfree = td;
+}
+
+static void
+grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td)
+{
+  /* Free the TDs in this queue.  */
+  while (td)
+    {
+      grub_uhci_td_t tdprev;
+
+      /* Unlink the queue.  */
+      tdprev = td;
+      td = (grub_uhci_td_t) td->linkptr2;
+
+      /* Free the TD.  */
+      grub_free_td (u, tdprev);
+    }
+}
+
+static grub_uhci_qh_t
+grub_alloc_qh (struct grub_uhci *u,
+              grub_transaction_type_t tr __attribute__((unused)))
+{
+  int i;
+  grub_uhci_qh_t qh;
+
+  /* Look for a Queue Head for this transfer.  Skip the first QH if
+     this is a Interrupt Transfer.  */
+#if 0
+  if (tr == GRUB_USB_TRANSACTION_TYPE_INTERRUPT)
+    i = 0;
+  else
+#endif
+    i = 1;
+
+  for (; i < 255; i++)
+    {
+      if (u->qh[i].elinkptr & 1)
+       break;
+    }
+  qh = &u->qh[i];
+  if (! (qh->elinkptr & 1))
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                 "no free queue heads available");
+      return NULL;
+    }
+
+  return qh;
+}
+
+static grub_uhci_td_t
+grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
+                      grub_transfer_type_t type, unsigned int addr,
+                      unsigned int toggle, grub_size_t size,
+                      char *data)
+{
+  grub_uhci_td_t td;
+  static const unsigned int tf[] = { 0x69, 0xE1, 0x2D };
+
+  /* XXX: Check if data is <4GB.  If it isn't, just copy stuff around.
+     This is only relevant for 64 bits architectures.  */
+
+  /* Grab a free Transfer Descriptor and initialize it.  */
+  td = grub_alloc_td (u);
+  if (! td)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                 "no transfer descriptors available for UHCI transfer");
+      return 0;
+    }
+
+  grub_dprintf ("uhci",
+               "transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=%p td=%p\n",
+               endp, type, addr, toggle, size, data, td);
+
+  /* Don't point to any TD, just terminate.  */
+  td->linkptr = 1;
+
+  /* Active!  Only retry a transfer 3 times.  */
+  td->ctrl_status = (1 << 23) | (3 << 27);
+
+  /* If zero bytes are transmitted, size is 0x7FF.  Otherwise size is
+     size-1.  */
+  if (size == 0)
+    size = 0x7FF;
+  else
+    size = size - 1;
+
+  /* Setup whatever is required for the token packet.  */
+  td->token = ((size << 21) | (toggle << 19) | (endp << 15)
+              | (addr << 8) | tf[type]);
+
+  td->buffer = (grub_uint32_t) data;
+
+  return td;
+}
+
+static grub_usb_err_t
+grub_uhci_transfer (grub_usb_controller_t dev,
+                   grub_usb_transfer_t transfer)
+{
+  struct grub_uhci *u = (struct grub_uhci *) dev->data;
+  grub_uhci_qh_t qh;
+  grub_uhci_td_t td;
+  grub_uhci_td_t td_first = NULL;
+  grub_uhci_td_t td_prev = NULL;
+  grub_usb_err_t err = GRUB_USB_ERR_NONE;
+  int i;
+  grub_uint64_t endtime;
+
+  /* Allocate a queue head for the transfer queue.  */
+  qh = grub_alloc_qh (u, GRUB_USB_TRANSACTION_TYPE_CONTROL);
+  if (! qh)
+    return grub_errno;
+
+  for (i = 0; i < transfer->transcnt; i++)
+    {
+      grub_usb_transaction_t tr = &transfer->transactions[i];
+
+      td = grub_uhci_transaction (u, transfer->endpoint, tr->pid,
+                                 transfer->devaddr, tr->toggle,
+                                 tr->size, tr->data);
+      if (! td)
+       {
+         /* Terminate and free.  */
+         td_prev->linkptr2 = 0;
+         td_prev->linkptr = 1;
+
+         if (td_first)
+           grub_free_queue (u, td_first);
+
+         return GRUB_USB_ERR_INTERNAL;
+       }
+
+      if (! td_first)
+       td_first = td;
+      else
+       {
+         td_prev->linkptr2 = (grub_uint32_t) td;
+         td_prev->linkptr = (grub_uint32_t) td;
+         td_prev->linkptr |= 4;
+       }
+      td_prev = td;
+    }
+  td_prev->linkptr2 = 0;
+  td_prev->linkptr = 1;
+
+  grub_dprintf ("uhci", "setup transaction %d\n", transfer->type);
+
+  /* Link it into the queue and terminate.  Now the transaction can
+     take place.  */
+  qh->elinkptr = (grub_uint32_t) td_first;
+
+  grub_dprintf ("uhci", "initiate transaction\n");
+
+  /* Wait until either the transaction completed or an error
+     occurred.  */
+  endtime = grub_get_time_ms () + 1000;
+  for (;;)
+    {
+      grub_uhci_td_t errtd;
+
+      errtd = (grub_uhci_td_t) (qh->elinkptr & ~0x0f);
+
+      grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p\n",
+                   errtd->ctrl_status, errtd->buffer & (~15), errtd);
+
+      /* Check if the transaction completed.  */
+      if (qh->elinkptr & 1)
+       break;
+
+      grub_dprintf ("uhci", "t status=0x%02x\n", errtd->ctrl_status);
+
+      /* Check if the TD is not longer active.  */
+      if (! (errtd->ctrl_status & (1 << 23)))
+       {
+         grub_dprintf ("uhci", ">>t status=0x%02x\n", errtd->ctrl_status);
+
+         /* Check if the endpoint is stalled.  */
+         if (errtd->ctrl_status & (1 << 22))
+           err = GRUB_USB_ERR_STALL;
+
+         /* Check if an error related to the data buffer occurred.  */
+         if (errtd->ctrl_status & (1 << 21))
+           err = GRUB_USB_ERR_DATA;
+
+         /* Check if a babble error occurred.  */
+         if (errtd->ctrl_status & (1 << 20))
+           err = GRUB_USB_ERR_BABBLE;
+
+         /* Check if a NAK occurred.  */
+         if (errtd->ctrl_status & (1 << 19))
+           err = GRUB_USB_ERR_NAK;
+
+         /* Check if a timeout occurred.  */
+         if (errtd->ctrl_status & (1 << 18))
+           err = GRUB_USB_ERR_TIMEOUT;
+
+         /* Check if a bitstuff error occurred.  */
+         if (errtd->ctrl_status & (1 << 17))
+           err = GRUB_USB_ERR_BITSTUFF;
+
+         if (err)
+           goto fail;
+
+         /* Fall through, no errors occurred, so the QH might be
+            updated.  */
+         grub_dprintf ("uhci", "transaction fallthrough\n");
+       }
+      if (grub_get_time_ms () > endtime)
+       {
+         err = GRUB_USB_ERR_STALL;
+         grub_dprintf ("uhci", "transaction timed out\n");
+         goto fail;
+       }
+      grub_cpu_idle ();
+    }
+
+  grub_dprintf ("uhci", "transaction complete\n");
+
+ fail:
+
+  grub_dprintf ("uhci", "transaction failed\n");
+
+  /* Place the QH back in the free list and deallocate the associated
+     TDs.  */
+  qh->elinkptr = 1;
+  grub_free_queue (u, td_first);
+
+  return err;
+}
+
+static int
+grub_uhci_iterate (int (*hook) (grub_usb_controller_t dev))
+{
+  struct grub_uhci *u;
+  struct grub_usb_controller dev;
+
+  for (u = uhci; u; u = u->next)
+    {
+      dev.data = u;
+      if (hook (&dev))
+       return 1;
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_uhci_portstatus (grub_usb_controller_t dev,
+                     unsigned int port, unsigned int enable)
+{
+  struct grub_uhci *u = (struct grub_uhci *) dev->data;
+  int reg;
+  unsigned int status;
+  grub_uint64_t endtime;
+
+  grub_dprintf ("uhci", "enable=%d port=%d\n", enable, port);
+
+  if (port == 0)
+    reg = GRUB_UHCI_REG_PORTSC1;
+  else if (port == 1)
+    reg = GRUB_UHCI_REG_PORTSC2;
+  else
+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
+                      "UHCI Root Hub port does not exist");
+
+  status = grub_uhci_readreg16 (u, reg);
+  grub_dprintf ("uhci", "detect=0x%02x\n", status);
+
+  /* Reset the port.  */
+  grub_uhci_writereg16 (u, reg, enable << 9);
+
+  /* Wait for the reset to complete.  XXX: How long exactly?  */
+  grub_millisleep (10);
+  status = grub_uhci_readreg16 (u, reg);
+  grub_uhci_writereg16 (u, reg, status & ~(1 << 9));
+  grub_dprintf ("uhci", "reset completed\n");
+  grub_millisleep (10);
+
+  /* Enable the port.  */
+  grub_uhci_writereg16 (u, reg, enable << 2);
+  grub_millisleep (10);
+
+  grub_dprintf ("uhci", "waiting for the port to be enabled\n");
+
+  endtime = grub_get_time_ms () + 1000;
+  while (! (grub_uhci_readreg16 (u, reg) & (1 << 2)))
+    if (grub_get_time_ms () > endtime)
+      return grub_error (GRUB_ERR_IO, "UHCI Timed out");
+
+  status = grub_uhci_readreg16 (u, reg);
+  grub_dprintf ("uhci", ">3detect=0x%02x\n", status);
+
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_usb_speed_t
+grub_uhci_detect_dev (grub_usb_controller_t dev, int port)
+{
+  struct grub_uhci *u = (struct grub_uhci *) dev->data;
+  int reg;
+  unsigned int status;
+
+  if (port == 0)
+    reg = GRUB_UHCI_REG_PORTSC1;
+  else if (port == 1)
+    reg = GRUB_UHCI_REG_PORTSC2;
+  else
+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
+                      "UHCI Root Hub port does not exist");
+
+  status = grub_uhci_readreg16 (u, reg);
+
+  grub_dprintf ("uhci", "detect=0x%02x port=%d\n", status, port);
+
+  if (! (status & 1))
+    return GRUB_USB_SPEED_NONE;
+  else if (status & (1 << 8))
+    return GRUB_USB_SPEED_LOW;
+  else
+    return GRUB_USB_SPEED_FULL;
+}
+
+static int
+grub_uhci_hubports (grub_usb_controller_t dev __attribute__((unused)))
+{
+  /* The root hub has exactly two ports.  */
+  return 2;
+}
+
+\f
+static struct grub_usb_controller_dev usb_controller =
+{
+  .name = "uhci",
+  .iterate = grub_uhci_iterate,
+  .transfer = grub_uhci_transfer,
+  .hubports = grub_uhci_hubports,
+  .portstatus = grub_uhci_portstatus,
+  .detect_dev = grub_uhci_detect_dev
+};
+
+GRUB_MOD_INIT(uhci)
+{
+  grub_uhci_inithw ();
+  grub_usb_controller_dev_register (&usb_controller);
+  grub_dprintf ("uhci", "registered\n");
+}
+
+GRUB_MOD_FINI(uhci)
+{
+  struct grub_uhci *u;
+
+  /* Disable all UHCI controllers.  */
+  for (u = uhci; u; u = u->next)
+    grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 0);
+
+  /* Unregister the controller.  */
+  grub_usb_controller_dev_unregister (&usb_controller);
+}
diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c
new file mode 100644 (file)
index 0000000..8289185
--- /dev/null
@@ -0,0 +1,227 @@
+/* usb.c - Generic USB interfaces.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/usb.h>
+#include <grub/misc.h>
+
+static grub_usb_controller_dev_t grub_usb_list;
+
+void
+grub_usb_controller_dev_register (grub_usb_controller_dev_t usb)
+{
+  auto int iterate_hook (grub_usb_controller_t dev);
+
+  /* Iterate over all controllers found by the driver.  */
+  int iterate_hook (grub_usb_controller_t dev)
+    {
+      dev->dev = usb;
+
+      /* Enable the ports of the USB Root Hub.  */
+      grub_usb_root_hub (dev);
+
+      return 0;
+    }
+
+  usb->next = grub_usb_list;
+  grub_usb_list = usb;
+
+  if (usb->iterate)
+    usb->iterate (iterate_hook);
+}
+
+void
+grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb)
+{
+  grub_usb_controller_dev_t *p, q;
+
+  for (p = &grub_usb_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == usb)
+      {
+       *p = q->next;
+       break;
+      }
+}
+
+#if 0
+int
+grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev))
+{
+  grub_usb_controller_dev_t p;
+
+  auto int iterate_hook (grub_usb_controller_t dev);
+
+  int iterate_hook (grub_usb_controller_t dev)
+    {
+      dev->dev = p;
+      if (hook (dev))
+       return 1;
+      return 0;
+    }
+
+  /* Iterate over all controller drivers.  */
+  for (p = grub_usb_list; p; p = p->next)
+    {
+      /* Iterate over the busses of the controllers.  XXX: Actually, a
+        hub driver should do this.  */
+      if (p->iterate (iterate_hook))
+       return 1;
+    }
+
+  return 0;
+}
+#endif
+
+\f
+grub_usb_err_t
+grub_usb_clear_halt (grub_usb_device_t dev, int endpoint)
+{
+  dev->toggle[endpoint] = 0;
+  return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
+                                    | GRUB_USB_REQTYPE_STANDARD
+                                    | GRUB_USB_REQTYPE_TARGET_ENDP),
+                              GRUB_USB_REQ_CLEAR_FEATURE,
+                              GRUB_USB_FEATURE_ENDP_HALT,
+                              endpoint, 0, 0);
+}
+
+grub_usb_err_t
+grub_usb_set_configuration (grub_usb_device_t dev, int configuration)
+{
+  int i;
+
+  for (i = 0; i < 16; i++)
+    dev->toggle[i] = 0;
+
+  return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
+                                    | GRUB_USB_REQTYPE_STANDARD
+                                    | GRUB_USB_REQTYPE_TARGET_DEV),
+                              GRUB_USB_REQ_SET_CONFIGURATION, configuration,
+                              0, 0, NULL);
+}
+
+grub_usb_err_t
+grub_usb_get_descriptor (grub_usb_device_t dev,
+                        grub_uint8_t type, grub_uint8_t index,
+                        grub_size_t size, char *data)
+{
+  return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
+                                    | GRUB_USB_REQTYPE_STANDARD
+                                    | GRUB_USB_REQTYPE_TARGET_DEV),
+                              GRUB_USB_REQ_GET_DESCRIPTOR,
+                              (type << 8) | index,
+                              0, size, data);
+}
+
+struct grub_usb_desc_endp *
+grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr)
+{
+  int i;
+
+  for (i = 0; i < usbdev->config[0].descconf->numif; i++)
+    {
+      struct grub_usb_desc_if *interf;
+      int j;
+
+      interf = usbdev->config[0].interf[i].descif;
+
+      for (j = 0; j < interf->endpointcnt; j++)
+       {
+         struct grub_usb_desc_endp *endp;
+         endp = &usbdev->config[0].interf[i].descendp[j];
+
+         if (endp->endp_addr == addr)
+           return endp;
+       }
+    }
+
+  return NULL;
+}
+
+grub_usb_err_t
+grub_usb_device_initialize (grub_usb_device_t dev)
+{
+  struct grub_usb_desc_device *descdev;
+  struct grub_usb_desc_config config;
+  grub_usb_err_t err;
+  int i;
+
+  err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE,
+                                0, sizeof (struct grub_usb_desc_device),
+                                (char *) &dev->descdev);
+  if (err)
+    return err;
+  descdev = &dev->descdev;
+
+  for (i = 0; i < 8; i++)
+    dev->config[i].descconf = NULL;
+
+  for (i = 0; i < descdev->configcnt; i++)
+    {
+      int pos;
+      int currif;
+      char *data;
+
+      /* First just read the first 4 bytes of the configuration
+        descriptor, after that it is known how many bytes really have
+        to be read.  */
+      err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i, 4,
+                                    (char *) &config);
+
+      data = grub_malloc (config.totallen);
+      if (! data)
+       {
+         err = GRUB_USB_ERR_INTERNAL;
+         goto fail;
+       }
+
+      dev->config[i].descconf = (struct grub_usb_desc_config *) data;
+      err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i,
+                                    config.totallen, data);
+      if (err)
+       goto fail;
+
+      /* Skip the configuration descriptor.  */
+      pos = sizeof (struct grub_usb_desc_config);
+
+      /* Read all interfaces.  */
+      for (currif = 0; currif < dev->config[i].descconf->numif; currif++)
+       {
+         dev->config[i].interf[currif].descif
+           = (struct grub_usb_desc_if *) &data[pos];
+         pos += sizeof (struct grub_usb_desc_if);
+
+         /* Point to the first endpoint.  */
+         dev->config[i].interf[currif].descendp
+           = (struct grub_usb_desc_endp *) &data[pos];
+         pos += (sizeof (struct grub_usb_desc_endp)
+                 * dev->config[i].interf[currif].descif->endpointcnt);
+       }
+    }
+
+  return GRUB_USB_ERR_NONE;
+
+ fail:
+
+  for (i = 0; i < 8; i++)
+    grub_free (dev->config[i].descconf);
+
+  return err;
+}
diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c
new file mode 100644 (file)
index 0000000..523abf9
--- /dev/null
@@ -0,0 +1,192 @@
+/* usb.c - USB Hub Support.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/usb.h>
+#include <grub/misc.h>
+
+/* USB Supports 127 devices, with device 0 as special case.  */
+static struct grub_usb_device *grub_usb_devs[128];
+
+/* Add a device that currently has device number 0 and resides on
+   CONTROLLER, the Hub reported that the device speed is SPEED.  */
+static grub_usb_device_t
+grub_usb_hub_add_dev (grub_usb_controller_t controller, grub_usb_speed_t speed)
+{
+  grub_usb_device_t dev;
+  int i;
+
+  dev = grub_zalloc (sizeof (struct grub_usb_device));
+  if (! dev)
+    return NULL;
+
+  dev->controller = *controller;
+  dev->speed = speed;
+
+  grub_usb_device_initialize (dev);
+
+  /* Assign a new address to the device.  */
+  for (i = 1; i < 128; i++)
+    {
+      if (! grub_usb_devs[i])
+       break;
+    }
+  if (i == 128)
+    {
+      grub_error (GRUB_ERR_IO, "can't assign address to USB device");
+      return NULL;
+    }
+
+  grub_usb_control_msg (dev,
+                       (GRUB_USB_REQTYPE_OUT
+                        | GRUB_USB_REQTYPE_STANDARD
+                        | GRUB_USB_REQTYPE_TARGET_DEV),
+                       GRUB_USB_REQ_SET_ADDRESS,
+                       i, 0, 0, NULL);
+
+  dev->addr = i;
+  dev->initialized = 1;
+  grub_usb_devs[i] = dev;
+
+  return dev;
+}
+
+\f
+static grub_err_t
+grub_usb_add_hub (grub_usb_device_t dev)
+{
+  struct grub_usb_usb_hubdesc hubdesc;
+  grub_err_t err;
+  int i;
+
+  grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
+                             | GRUB_USB_REQTYPE_CLASS
+                             | GRUB_USB_REQTYPE_TARGET_DEV),
+                       GRUB_USB_REQ_GET_DESCRIPTOR,
+                       (GRUB_USB_DESCRIPTOR_HUB << 8) | 0,
+                       0, sizeof (hubdesc), (char *) &hubdesc);
+
+  /* Iterate over the Hub ports.  */
+  for (i = 1; i <= hubdesc.portcnt; i++)
+    {
+      grub_uint32_t status;
+
+      /* Get the port status.  */
+      err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
+                                       | GRUB_USB_REQTYPE_CLASS
+                                       | GRUB_USB_REQTYPE_TARGET_OTHER),
+                                 GRUB_USB_REQ_HUB_GET_PORT_STATUS,
+                                 0, i, sizeof (status), (char *) &status);
+
+      /* Just ignore the device if the Hub does not report the
+        status.  */
+      if (err)
+       continue;
+
+      /* If connected, reset and enable the port.  */
+      if (status & GRUB_USB_HUB_STATUS_CONNECTED)
+       {
+         grub_usb_speed_t speed;
+
+         /* Determine the device speed.  */
+         if (status & GRUB_USB_HUB_STATUS_LOWSPEED)
+           speed = GRUB_USB_SPEED_LOW;
+         else
+           {
+             if (status & GRUB_USB_HUB_STATUS_HIGHSPEED)
+               speed = GRUB_USB_SPEED_HIGH;
+             else
+               speed = GRUB_USB_SPEED_FULL;
+           }
+
+         /* A device is actually connected to this port, not enable
+            the port.  XXX: Why 0x03?  According to some docs it
+            should be 0x0.  Check the specification!  */
+         err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
+                                           | GRUB_USB_REQTYPE_CLASS
+                                           | GRUB_USB_REQTYPE_TARGET_OTHER),
+                                     0x3, 0x4, i, 0, 0);
+
+         /* If the Hub does not cooperate for this port, just skip
+            the port.  */
+         if (err)
+           continue;
+
+         /* Add the device and assign a device address to it.  */
+         grub_usb_hub_add_dev (&dev->controller, speed);
+       }
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+grub_usb_err_t
+grub_usb_root_hub (grub_usb_controller_t controller)
+{
+  grub_err_t err;
+  int ports;
+  int i;
+
+  /* Query the number of ports the root Hub has.  */
+  ports = controller->dev->hubports (controller);
+
+  for (i = 0; i < ports; i++)
+    {
+      grub_usb_speed_t speed = controller->dev->detect_dev (controller, i);
+
+      if (speed != GRUB_USB_SPEED_NONE)
+       {
+         grub_usb_device_t dev;
+
+         /* Enable the port.  */
+         err = controller->dev->portstatus (controller, i, 1);
+         if (err)
+           continue;
+
+         /* Enable the port and create a device.  */
+         dev = grub_usb_hub_add_dev (controller, speed);
+         if (! dev)
+           continue;
+
+         /* If the device is a Hub, scan it for more devices.  */
+         if (dev->descdev.class == 0x09)
+           grub_usb_add_hub (dev);
+       }
+    }
+
+  return GRUB_USB_ERR_NONE;
+}
+
+int
+grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
+{
+  int i;
+
+  for (i = 0; i < 128; i++)
+    {
+      if (grub_usb_devs[i])
+       {
+         if (hook (grub_usb_devs[i]))
+             return 1;
+       }
+    }
+
+  return 0;
+}
diff --git a/grub-core/bus/usb/usbtrans.c b/grub-core/bus/usb/usbtrans.c
new file mode 100644 (file)
index 0000000..09e7af8
--- /dev/null
@@ -0,0 +1,212 @@
+/* usbtrans.c - USB Transfers and Transactions.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/usb.h>
+#include <grub/usbtrans.h>
+
+grub_usb_err_t
+grub_usb_control_msg (grub_usb_device_t dev,
+                     grub_uint8_t reqtype,
+                     grub_uint8_t request,
+                     grub_uint16_t value,
+                     grub_uint16_t index,
+                     grub_size_t size, char *data)
+{
+  int i;
+  grub_usb_transfer_t transfer;
+  int datablocks;
+  struct grub_usb_packet_setup setupdata;
+  grub_usb_err_t err;
+  unsigned int max;
+
+  grub_dprintf ("usb",
+               "control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%d\n",
+               reqtype, request,  value, index, size);
+
+  /* Create a transfer.  */
+  transfer = grub_malloc (sizeof (struct grub_usb_transfer));
+  if (! transfer)
+    return grub_errno;
+
+  /* Determine the maximum packet size.  */
+  if (dev->initialized)
+    max = dev->descdev.maxsize0;
+  else
+    max = 64;
+
+  datablocks = (size + max - 1) / max;
+
+  /* XXX: Discriminate between different types of control
+     messages.  */
+  transfer->transcnt = datablocks + 2;
+  transfer->size = size; /* XXX ? */
+  transfer->endpoint = 0;
+  transfer->devaddr = dev->addr;
+  transfer->type = GRUB_USB_TRANSACTION_TYPE_CONTROL;
+  transfer->max = max;
+  transfer->dev = dev;
+
+  /* Allocate an array of transfer data structures.  */
+  transfer->transactions = grub_malloc (transfer->transcnt
+                                       * sizeof (struct grub_usb_transfer));
+  if (! transfer->transactions)
+    {
+      grub_free (transfer);
+      return grub_errno;
+    }
+
+  /* Build a Setup packet.  XXX: Endianness.  */
+  setupdata.reqtype = reqtype;
+  setupdata.request = request;
+  setupdata.value = value;
+  setupdata.index = index;
+  setupdata.length = size;
+  transfer->transactions[0].size = sizeof (setupdata);
+  transfer->transactions[0].pid = GRUB_USB_TRANSFER_TYPE_SETUP;
+  transfer->transactions[0].data = (char *) &setupdata;
+  transfer->transactions[0].toggle = 0;
+
+  /* Now the data...  XXX: Is this the right way to transfer control
+     transfers?  */
+  for (i = 0; i < datablocks; i++)
+    {
+      grub_usb_transaction_t tr = &transfer->transactions[i + 1];
+
+      tr->size = (size > max) ? max : size;
+      /* Use the right most bit as the data toggle.  Simple and
+        effective.  */
+      tr->toggle = !(i & 1);
+      if (reqtype & 128)
+       tr->pid = GRUB_USB_TRANSFER_TYPE_IN;
+      else
+       tr->pid = GRUB_USB_TRANSFER_TYPE_OUT;
+      tr->data = &data[i * max];
+      size -= max;
+    }
+
+  /* End with an empty OUT transaction.  */
+  transfer->transactions[datablocks + 1].size = 0;
+  transfer->transactions[datablocks + 1].data = NULL;
+  if (reqtype & 128)
+    transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT;
+  else
+    transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_IN;
+
+  transfer->transactions[datablocks + 1].toggle = 1;
+
+  err = dev->controller.dev->transfer (&dev->controller, transfer);
+
+  grub_free (transfer->transactions);
+  grub_free (transfer);
+
+  return err;
+}
+
+static grub_usb_err_t
+grub_usb_bulk_readwrite (grub_usb_device_t dev,
+                        int endpoint, grub_size_t size, char *data,
+                        grub_transfer_type_t type)
+{
+  int i;
+  grub_usb_transfer_t transfer;
+  int datablocks;
+  unsigned int max;
+  grub_usb_err_t err;
+  int toggle = dev->toggle[endpoint];
+
+  /* Use the maximum packet size given in the endpoint descriptor.  */
+  if (dev->initialized)
+    {
+      struct grub_usb_desc_endp *endpdesc;
+      endpdesc = grub_usb_get_endpdescriptor (dev, 0);
+
+      if (endpdesc)
+       max = endpdesc->maxpacket;
+      else
+       max = 64;
+    }
+  else
+    max = 64;
+
+  /* Create a transfer.  */
+  transfer = grub_malloc (sizeof (struct grub_usb_transfer));
+  if (! transfer)
+    return grub_errno;
+
+  datablocks = ((size + max - 1) / max);
+  transfer->transcnt = datablocks;
+  transfer->size = size - 1;
+  transfer->endpoint = endpoint;
+  transfer->devaddr = dev->addr;
+  transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK;
+  transfer->max = max;
+  transfer->dev = dev;
+
+  /* Allocate an array of transfer data structures.  */
+  transfer->transactions = grub_malloc (transfer->transcnt
+                                       * sizeof (struct grub_usb_transfer));
+  if (! transfer->transactions)
+    {
+      grub_free (transfer);
+      return grub_errno;
+    }
+
+  /* Set up all transfers.  */
+  for (i = 0; i < datablocks; i++)
+    {
+      grub_usb_transaction_t tr = &transfer->transactions[i];
+
+      tr->size = (size > max) ? max : size;
+      /* XXX: Use the right most bit as the data toggle.  Simple and
+        effective.  */
+      tr->toggle = toggle;
+      toggle = toggle ? 0 : 1;
+      tr->pid = type;
+      tr->data = &data[i * max];
+      size -= tr->size;
+    }
+
+  err = dev->controller.dev->transfer (&dev->controller, transfer);
+  grub_dprintf ("usb", "toggle=%d\n", toggle);
+  dev->toggle[endpoint] = toggle;
+
+  grub_free (transfer->transactions);
+  grub_free (transfer);
+
+  return err;
+}
+
+grub_usb_err_t
+grub_usb_bulk_write (grub_usb_device_t dev,
+                    int endpoint, grub_size_t size, char *data)
+{
+  return grub_usb_bulk_readwrite (dev, endpoint, size, data,
+                                 GRUB_USB_TRANSFER_TYPE_OUT);
+}
+
+grub_usb_err_t
+grub_usb_bulk_read (grub_usb_device_t dev,
+                   int endpoint, grub_size_t size, char *data)
+{
+  return grub_usb_bulk_readwrite (dev, endpoint, size, data,
+                                 GRUB_USB_TRANSFER_TYPE_IN);
+}
diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c
new file mode 100644 (file)
index 0000000..5bbfd00
--- /dev/null
@@ -0,0 +1,774 @@
+/* acpi.c - modify acpi tables. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/extcmd.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/gzio.h>
+#include <grub/acpi.h>
+#include <grub/mm.h>
+#include <grub/machine/memory.h>
+#include <grub/memory.h>
+#include <grub/i18n.h>
+
+#ifdef GRUB_MACHINE_EFI
+#include <grub/efi/efi.h>
+#include <grub/efi/api.h>
+#endif
+
+static const struct grub_arg_option options[] = {
+  {"exclude", 'x', 0,
+   N_("Don't load host tables specified by comma-separated list."),
+   0, ARG_TYPE_STRING},
+  {"load-only", 'n', 0,
+   N_("Load only tables specified by comma-separated list."), 0, ARG_TYPE_STRING},
+  {"v1", '1', 0, N_("Expose v1 tables."), 0, ARG_TYPE_NONE},
+  {"v2", '2', 0, N_("Expose v2 and v3 tables."), 0, ARG_TYPE_NONE},
+  {"oemid", 'o', 0, N_("Set OEMID of RSDP, XSDT and RSDT."), 0, ARG_TYPE_STRING},
+  {"oemtable", 't', 0,
+   N_("Set OEMTABLE ID of RSDP, XSDT and RSDT."), 0, ARG_TYPE_STRING},
+  {"oemtablerev", 'r', 0,
+   N_("Set OEMTABLE revision of RSDP, XSDT and RSDT."), 0, ARG_TYPE_INT},
+  {"oemtablecreator", 'c', 0,
+   N_("Set creator field of RSDP, XSDT and RSDT."), 0, ARG_TYPE_STRING},
+  {"oemtablecreatorrev", 'd', 0,
+   N_("Set creator revision of RSDP, XSDT and RSDT."), 0, ARG_TYPE_INT},
+  {"no-ebda", 'e', 0, N_("Don't update EBDA. May fix failures or hangs on some."
+   " BIOSes but makes it ineffective with OS not receiving RSDP from GRUB."),
+   0, ARG_TYPE_NONE},
+  {0, 0, 0, 0, 0, 0}
+};
+
+/* Simple checksum by summing all bytes. Used by ACPI and SMBIOS. */
+grub_uint8_t
+grub_byte_checksum (void *base, grub_size_t size)
+{
+  grub_uint8_t *ptr;
+  grub_uint8_t ret = 0;
+  for (ptr = (grub_uint8_t *) base; ptr < ((grub_uint8_t *) base) + size;
+       ptr++)
+    ret += *ptr;
+  return ret;
+}
+
+/* rev1 is 1 if ACPIv1 is to be generated, 0 otherwise.
+   rev2 contains the revision of ACPIv2+ to generate or 0 if none. */
+static int rev1, rev2;
+/* OEMID of RSDP, RSDT and XSDT. */
+static char root_oemid[6];
+/* OEMTABLE of the same tables. */
+static char root_oemtable[8];
+/* OEMREVISION of the same tables. */
+static grub_uint32_t root_oemrev;
+/* CreatorID of the same tables. */
+static char root_creator_id[4];
+/* CreatorRevision of the same tables. */
+static grub_uint32_t root_creator_rev;
+static struct grub_acpi_rsdp_v10 *rsdpv1_new = 0;
+static struct grub_acpi_rsdp_v20 *rsdpv2_new = 0;
+static char *playground = 0, *playground_ptr = 0;
+static int playground_size = 0;
+
+/* Linked list of ACPI tables. */
+struct efiemu_acpi_table
+{
+  void *addr;
+  grub_size_t size;
+  struct efiemu_acpi_table *next;
+};
+static struct efiemu_acpi_table *acpi_tables = 0;
+
+/* DSDT isn't in RSDT. So treat it specially. */
+static void *table_dsdt = 0;
+/* Pointer to recreated RSDT. */
+static void *rsdt_addr = 0;
+
+/* Allocation handles for different tables. */
+static grub_size_t dsdt_size = 0;
+
+/* Address of original FACS. */
+static grub_uint32_t facs_addr = 0;
+
+struct grub_acpi_rsdp_v20 *
+grub_acpi_get_rsdpv2 (void)
+{
+  if (rsdpv2_new)
+    return rsdpv2_new;
+  if (rsdpv1_new)
+    return 0;
+  return grub_machine_acpi_get_rsdpv2 ();
+}
+
+struct grub_acpi_rsdp_v10 *
+grub_acpi_get_rsdpv1 (void)
+{
+  if (rsdpv1_new)
+    return rsdpv1_new;
+  if (rsdpv2_new)
+    return 0;
+  return grub_machine_acpi_get_rsdpv1 ();
+}
+
+static inline int
+iszero (grub_uint8_t *reg, int size)
+{
+  int i;
+  for (i = 0; i < size; i++)
+    if (reg[i])
+      return 0;
+  return 1;
+}
+
+grub_err_t
+grub_acpi_create_ebda (void)
+{
+  int ebda_kb_len;
+  int ebda_len;
+  int mmapregion = 0;
+  grub_uint8_t *ebda, *v1inebda = 0, *v2inebda = 0;
+  grub_uint64_t highestlow = 0;
+  grub_uint8_t *targetebda, *target;
+  struct grub_acpi_rsdp_v10 *v1;
+  struct grub_acpi_rsdp_v20 *v2;
+  auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t,
+                                      grub_uint32_t);
+  int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t size,
+                                 grub_uint32_t type)
+  {
+    grub_uint64_t end = start + size;
+    if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+      return 0;
+    if (end > 0x100000)
+      end = 0x100000;
+    if (end > start + ebda_len
+       && highestlow < ((end - ebda_len) & (~0xf)) )
+      highestlow = (end - ebda_len) & (~0xf);
+    return 0;
+  }
+
+  ebda = (grub_uint8_t *) UINT_TO_PTR ((*((grub_uint16_t *)0x40e)) << 4);
+  ebda_kb_len = *(grub_uint16_t *) ebda;
+  if (! ebda || ebda_kb_len > 16)
+    ebda_kb_len = 0;
+  ebda_len = (ebda_kb_len + 1) << 10;
+
+  /* FIXME: use low-memory mm allocation once it's available. */
+  grub_mmap_iterate (find_hook);
+  targetebda = (grub_uint8_t *) UINT_TO_PTR (highestlow);
+  grub_dprintf ("acpi", "creating ebda @%llx\n",
+               (unsigned long long) highestlow);
+  if (! highestlow)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                      "couldn't find space for the new EBDA");
+
+  mmapregion = grub_mmap_register (PTR_TO_UINT64 (targetebda), ebda_len,
+                                  GRUB_MACHINE_MEMORY_RESERVED);
+  if (! mmapregion)
+    return grub_errno;
+
+  /* XXX: EBDA is unstandardized, so this implementation is heuristical. */
+  if (ebda_kb_len)
+    grub_memcpy (targetebda, ebda, 0x400);
+  else
+    grub_memset (targetebda, 0, 0x400);
+  *((grub_uint16_t *) targetebda) = ebda_kb_len + 1;
+  target = targetebda;
+
+  v1 = grub_acpi_get_rsdpv1 ();
+  v2 = grub_acpi_get_rsdpv2 ();
+  if (v2 && v2->length > 40)
+    v2 = 0;
+
+  /* First try to replace already existing rsdp. */
+  if (v2)
+    {
+      grub_dprintf ("acpi", "Scanning EBDA for old rsdpv2\n");
+      for (; target < targetebda + 0x400 - v2->length; target += 0x10)
+       if (grub_memcmp (target, "RSD PTR ", 8) == 0
+           && grub_byte_checksum (target,
+                                  sizeof (struct grub_acpi_rsdp_v10)) == 0
+           && ((struct grub_acpi_rsdp_v10 *) target)->revision != 0
+           && ((struct grub_acpi_rsdp_v20 *) target)->length <= v2->length)
+         {
+           grub_memcpy (target, v2, v2->length);
+           grub_dprintf ("acpi", "Copying rsdpv2 to %p\n", target);
+           v2inebda = target;
+           target += v2->length;
+           target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1);
+           v2 = 0;
+           break;
+         }
+    }
+
+  if (v1)
+    {
+      grub_dprintf ("acpi", "Scanning EBDA for old rsdpv1\n");
+      for (; target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10);
+          target += 0x10)
+       if (grub_memcmp (target, "RSD PTR ", 8) == 0
+           && grub_byte_checksum (target,
+                                  sizeof (struct grub_acpi_rsdp_v10)) == 0)
+         {
+           grub_memcpy (target, v1, sizeof (struct grub_acpi_rsdp_v10));
+           grub_dprintf ("acpi", "Copying rsdpv1 to %p\n", target);
+           v1inebda = target;
+           target += sizeof (struct grub_acpi_rsdp_v10);
+           target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1);
+           v1 = 0;
+           break;
+         }
+    }
+
+  target = targetebda + 0x100;
+
+  /* Try contiguous zeros. */
+  if (v2)
+    {
+      grub_dprintf ("acpi", "Scanning EBDA for block of zeros\n");
+      for (; target < targetebda + 0x400 - v2->length; target += 0x10)
+       if (iszero (target, v2->length))
+         {
+           grub_dprintf ("acpi", "Copying rsdpv2 to %p\n", target);
+           grub_memcpy (target, v2, v2->length);
+           v2inebda = target;
+           target += v2->length;
+           target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1);
+           v2 = 0;
+           break;
+         }
+    }
+
+  if (v1)
+    {
+      grub_dprintf ("acpi", "Scanning EBDA for block of zeros\n");
+      for (; target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10);
+          target += 0x10)
+       if (iszero (target, sizeof (struct grub_acpi_rsdp_v10)))
+         {
+           grub_dprintf ("acpi", "Copying rsdpv1 to %p\n", target);
+           grub_memcpy (target, v1, sizeof (struct grub_acpi_rsdp_v10));
+           v1inebda = target;
+           target += sizeof (struct grub_acpi_rsdp_v10);
+           target = (grub_uint8_t *) ((((long) target - 1) | 0xf) + 1);
+           v1 = 0;
+           break;
+         }
+    }
+
+  if (v1 || v2)
+    {
+      grub_mmap_unregister (mmapregion);
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                        "couldn't find suitable spot in EBDA");
+    }
+
+  /* Remove any other RSDT. */
+  for (target = targetebda;
+       target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10);
+       target += 0x10)
+    if (grub_memcmp (target, "RSD PTR ", 8) == 0
+       && grub_byte_checksum (target,
+                              sizeof (struct grub_acpi_rsdp_v10)) == 0
+       && target != v1inebda && target != v2inebda)
+      *target = 0;
+
+  grub_dprintf ("acpi", "Switching EBDA\n");
+  (*((grub_uint16_t *) 0x40e)) = ((long)targetebda) >> 4;
+  grub_dprintf ("acpi", "EBDA switched\n");
+
+  return GRUB_ERR_NONE;
+}
+
+/* Create tables common to ACPIv1 and ACPIv2+ */
+static void
+setup_common_tables (void)
+{
+  struct efiemu_acpi_table *cur;
+  struct grub_acpi_table_header *rsdt;
+  grub_uint32_t *rsdt_entry;
+  int numoftables;
+
+  /* Treat DSDT. */
+  grub_memcpy (playground_ptr, table_dsdt, dsdt_size);
+  grub_free (table_dsdt);
+  table_dsdt = playground_ptr;
+  playground_ptr += dsdt_size;
+
+  /* Treat other tables. */
+  for (cur = acpi_tables; cur; cur = cur->next)
+    {
+      struct grub_acpi_fadt *fadt;
+
+      grub_memcpy (playground_ptr, cur->addr, cur->size);
+      grub_free (cur->addr);
+      cur->addr = playground_ptr;
+      playground_ptr += cur->size;
+
+      /* If it's FADT correct DSDT and FACS addresses. */
+      fadt = (struct grub_acpi_fadt *) cur->addr;
+      if (grub_memcmp (fadt->hdr.signature, "FACP", 4) == 0)
+       {
+         fadt->dsdt_addr = PTR_TO_UINT32 (table_dsdt);
+         fadt->facs_addr = facs_addr;
+
+         /* Does a revision 2 exist at all? */
+         if (fadt->hdr.revision >= 3)
+           {
+             fadt->dsdt_xaddr = PTR_TO_UINT64 (table_dsdt);
+             fadt->facs_xaddr = facs_addr;
+           }
+
+         /* Recompute checksum. */
+         fadt->hdr.checksum = 0;
+         fadt->hdr.checksum = 1 + ~grub_byte_checksum (fadt, fadt->hdr.length);
+       }
+    }
+
+  /* Fill RSDT entries. */
+  numoftables = 0;
+  for (cur = acpi_tables; cur; cur = cur->next)
+    numoftables++;
+
+  rsdt_addr = rsdt = (struct grub_acpi_table_header *) playground_ptr;
+  playground_ptr += sizeof (struct grub_acpi_table_header) + 4 * numoftables;
+
+  rsdt_entry = (grub_uint32_t *)(rsdt + 1);
+
+  /* Fill RSDT header. */
+  grub_memcpy (&(rsdt->signature), "RSDT", 4);
+  rsdt->length = sizeof (struct grub_acpi_table_header) + 4 * numoftables;
+  rsdt->revision = 1;
+  grub_memcpy (&(rsdt->oemid), root_oemid, 6);
+  grub_memcpy (&(rsdt->oemtable), root_oemtable, 4);
+  rsdt->oemrev = root_oemrev;
+  grub_memcpy (&(rsdt->creator_id), root_creator_id, 6);
+  rsdt->creator_rev = root_creator_rev;
+
+  for (cur = acpi_tables; cur; cur = cur->next)
+    *(rsdt_entry++) = PTR_TO_UINT32 (cur->addr);
+
+  /* Recompute checksum. */
+  rsdt->checksum = 0;
+  rsdt->checksum = 1 + ~grub_byte_checksum (rsdt, rsdt->length);
+}
+
+/* Regenerate ACPIv1 RSDP */
+static void
+setv1table (void)
+{
+  /* Create RSDP. */
+  rsdpv1_new = (struct grub_acpi_rsdp_v10 *) playground_ptr;
+  playground_ptr += sizeof (struct grub_acpi_rsdp_v10);
+  grub_memcpy (&(rsdpv1_new->signature), "RSD PTR ", 8);
+  grub_memcpy (&(rsdpv1_new->oemid), root_oemid, sizeof  (rsdpv1_new->oemid));
+  rsdpv1_new->revision = 0;
+  rsdpv1_new->rsdt_addr = PTR_TO_UINT32 (rsdt_addr);
+  rsdpv1_new->checksum = 0;
+  rsdpv1_new->checksum = 1 + ~grub_byte_checksum (rsdpv1_new,
+                                                 sizeof (*rsdpv1_new));
+  grub_dprintf ("acpi", "Generated ACPIv1 tables\n");
+}
+
+static void
+setv2table (void)
+{
+  struct grub_acpi_table_header *xsdt;
+  struct efiemu_acpi_table *cur;
+  grub_uint64_t *xsdt_entry;
+  int numoftables;
+
+  numoftables = 0;
+  for (cur = acpi_tables; cur; cur = cur->next)
+    numoftables++;
+
+  /* Create XSDT. */
+  xsdt = (struct grub_acpi_table_header *) playground_ptr;
+  playground_ptr += sizeof (struct grub_acpi_table_header) + 8 * numoftables;
+
+  xsdt_entry = (grub_uint64_t *)(xsdt + 1);
+  for (cur = acpi_tables; cur; cur = cur->next)
+    *(xsdt_entry++) = PTR_TO_UINT64 (cur->addr);
+  grub_memcpy (&(xsdt->signature), "XSDT", 4);
+  xsdt->length = sizeof (struct grub_acpi_table_header) + 8 * numoftables;
+  xsdt->revision = 1;
+  grub_memcpy (&(xsdt->oemid), root_oemid, sizeof (xsdt->oemid));
+  grub_memcpy (&(xsdt->oemtable), root_oemtable, sizeof (xsdt->oemtable));
+  xsdt->oemrev = root_oemrev;
+  grub_memcpy (&(xsdt->creator_id), root_creator_id, sizeof (xsdt->creator_id));
+  xsdt->creator_rev = root_creator_rev;
+  xsdt->checksum = 0;
+  xsdt->checksum = 1 + ~grub_byte_checksum (xsdt, xsdt->length);
+
+  /* Create RSDPv2. */
+  rsdpv2_new = (struct grub_acpi_rsdp_v20 *) playground_ptr;
+  playground_ptr += sizeof (struct grub_acpi_rsdp_v20);
+  grub_memcpy (&(rsdpv2_new->rsdpv1.signature), "RSD PTR ",
+              sizeof (rsdpv2_new->rsdpv1.signature));
+  grub_memcpy (&(rsdpv2_new->rsdpv1.oemid), root_oemid,
+              sizeof (rsdpv2_new->rsdpv1.oemid));
+  rsdpv2_new->rsdpv1.revision = rev2;
+  rsdpv2_new->rsdpv1.rsdt_addr = PTR_TO_UINT32 (rsdt_addr);
+  rsdpv2_new->rsdpv1.checksum = 0;
+  rsdpv2_new->rsdpv1.checksum = 1 + ~grub_byte_checksum
+    (&(rsdpv2_new->rsdpv1), sizeof (rsdpv2_new->rsdpv1));
+  rsdpv2_new->length = sizeof (*rsdpv2_new);
+  rsdpv2_new->xsdt_addr = PTR_TO_UINT64 (xsdt);
+  rsdpv2_new->checksum = 0;
+  rsdpv2_new->checksum = 1 + ~grub_byte_checksum (rsdpv2_new,
+                                                 rsdpv2_new->length);
+  grub_dprintf ("acpi", "Generated ACPIv2 tables\n");
+}
+
+static void
+free_tables (void)
+{
+  struct efiemu_acpi_table *cur, *t;
+  if (table_dsdt)
+    grub_free (table_dsdt);
+  for (cur = acpi_tables; cur;)
+    {
+      t = cur;
+      grub_free (cur->addr);
+      cur = cur->next;
+      grub_free (t);
+    }
+  acpi_tables = 0;
+  table_dsdt = 0;
+}
+
+static grub_err_t
+grub_cmd_acpi (struct grub_extcmd *cmd,
+                     int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  struct grub_acpi_rsdp_v10 *rsdp;
+  struct efiemu_acpi_table *cur, *t;
+  grub_err_t err;
+  int i, mmapregion;
+  int numoftables;
+
+  /* Default values if no RSDP is found. */
+  rev1 = 1;
+  rev2 = 3;
+
+  facs_addr = 0;
+  playground = playground_ptr = 0;
+  playground_size = 0;
+
+  rsdp = (struct grub_acpi_rsdp_v10 *) grub_machine_acpi_get_rsdpv2 ();
+
+  if (! rsdp)
+    rsdp = grub_machine_acpi_get_rsdpv1 ();
+
+  if (rsdp)
+    {
+      grub_uint32_t *entry_ptr;
+      char *exclude = 0;
+      char *load_only = 0;
+      char *ptr;
+      /* RSDT consists of header and an array of 32-bit pointers. */
+      struct grub_acpi_table_header *rsdt;
+
+      exclude = state[0].set ? grub_strdup (state[0].arg) : 0;
+      if (exclude)
+       {
+         for (ptr = exclude; *ptr; ptr++)
+           *ptr = grub_tolower (*ptr);
+       }
+
+      load_only = state[1].set ? grub_strdup (state[1].arg) : 0;
+      if (load_only)
+       {
+         for (ptr = load_only; *ptr; ptr++)
+           *ptr = grub_tolower (*ptr);
+       }
+
+      /* Set revision variables to replicate the same version as host. */
+      rev1 = ! rsdp->revision;
+      rev2 = rsdp->revision;
+      rsdt = (struct grub_acpi_table_header *) UINT_TO_PTR (rsdp->rsdt_addr);
+      /* Load host tables. */
+      for (entry_ptr = (grub_uint32_t *) (rsdt + 1);
+          entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt)
+                                         + rsdt->length);
+          entry_ptr++)
+       {
+         char signature[5];
+         struct efiemu_acpi_table *table;
+         struct grub_acpi_table_header *curtable
+           = (struct grub_acpi_table_header *) UINT_TO_PTR (*entry_ptr);
+         signature[4] = 0;
+         for (i = 0; i < 4;i++)
+           signature[i] = grub_tolower (curtable->signature[i]);
+
+         /* If it's FADT it contains addresses of DSDT and FACS. */
+         if (grub_strcmp (signature, "facp") == 0)
+           {
+             struct grub_acpi_table_header *dsdt;
+             struct grub_acpi_fadt *fadt = (struct grub_acpi_fadt *) curtable;
+
+             /* Set root header variables to the same values
+                as FACP by default. */
+             grub_memcpy (&root_oemid, &(fadt->hdr.oemid),
+                          sizeof (root_oemid));
+             grub_memcpy (&root_oemtable, &(fadt->hdr.oemtable),
+                          sizeof (root_oemtable));
+             root_oemrev = fadt->hdr.oemrev;
+             grub_memcpy (&root_creator_id, &(fadt->hdr.creator_id),
+                          sizeof (root_creator_id));
+             root_creator_rev = fadt->hdr.creator_rev;
+
+             /* Load DSDT if not excluded. */
+             dsdt = (struct grub_acpi_table_header *)
+               UINT_TO_PTR (fadt->dsdt_addr);
+             if (dsdt && (! exclude || ! grub_strword (exclude, "dsdt"))
+                 && (! load_only || grub_strword (load_only, "dsdt"))
+                 && dsdt->length >= sizeof (*dsdt))
+               {
+                 dsdt_size = dsdt->length;
+                 table_dsdt = grub_malloc (dsdt->length);
+                 if (! table_dsdt)
+                   {
+                     free_tables ();
+                     grub_free (exclude);
+                     grub_free (load_only);
+                     return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                                        "couldn't allocate table");
+                   }
+                 grub_memcpy (table_dsdt, dsdt, dsdt->length);
+               }
+
+             /* Save FACS address. FACS shouldn't be overridden. */
+             facs_addr = fadt->facs_addr;
+           }
+
+         /* Skip excluded tables. */
+         if (exclude && grub_strword (exclude, signature))
+           continue;
+         if (load_only && ! grub_strword (load_only, signature))
+           continue;
+
+         /* Sanity check. */
+         if (curtable->length < sizeof (*curtable))
+           continue;
+
+         table = (struct efiemu_acpi_table *) grub_malloc
+           (sizeof (struct efiemu_acpi_table));
+         if (! table)
+           {
+             free_tables ();
+             grub_free (exclude);
+             grub_free (load_only);
+             return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                                "couldn't allocate table structure");
+           }
+         table->size = curtable->length;
+         table->addr = grub_malloc (table->size);
+         playground_size += table->size;
+         if (! table->addr)
+           {
+             free_tables ();
+             return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                                "couldn't allocate table");
+           }
+         table->next = acpi_tables;
+         acpi_tables = table;
+         grub_memcpy (table->addr, curtable, table->size);
+       }
+      grub_free (exclude);
+      grub_free (load_only);
+    }
+
+  /* Does user specify versions to generate? */
+  if (state[2].set || state[3].set)
+    {
+      rev1 = state[2].set;
+      if (state[3].set)
+       rev2 = rev2 ? : 2;
+      else
+       rev2 = 0;
+    }
+
+  /* Does user override root header information? */
+  if (state[4].set)
+    grub_strncpy (root_oemid, state[4].arg, sizeof (root_oemid));
+  if (state[5].set)
+    grub_strncpy (root_oemtable, state[5].arg, sizeof (root_oemtable));
+  if (state[6].set)
+    root_oemrev = grub_strtoul (state[6].arg, 0, 0);
+  if (state[7].set)
+    grub_strncpy (root_creator_id, state[7].arg, sizeof (root_creator_id));
+  if (state[8].set)
+    root_creator_rev = grub_strtoul (state[8].arg, 0, 0);
+
+  /* Load user tables */
+  for (i = 0; i < argc; i++)
+    {
+      grub_file_t file;
+      grub_size_t size;
+      char *buf;
+
+      file = grub_gzfile_open (args[i], 1);
+      if (! file)
+       {
+         free_tables ();
+         return grub_error (GRUB_ERR_BAD_OS, "couldn't open file %s", args[i]);
+       }
+
+      size = grub_file_size (file);
+      if (size < sizeof (struct grub_acpi_table_header))
+       {
+         grub_file_close (file);
+         free_tables ();
+         return grub_error (GRUB_ERR_BAD_OS, "file %s is too small", args[i]);
+       }
+
+      buf = (char *) grub_malloc (size);
+      if (! buf)
+       {
+         grub_file_close (file);
+         free_tables ();
+         return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                            "couldn't read file %s", args[i]);
+       }
+
+      if (grub_file_read (file, buf, size) != (int) size)
+       {
+         grub_file_close (file);
+         free_tables ();
+         return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[i]);
+       }
+      grub_file_close (file);
+
+      if (grub_memcmp (((struct grub_acpi_table_header *) buf)->signature,
+                      "DSDT", 4) == 0)
+       {
+         grub_free (table_dsdt);
+         table_dsdt = buf;
+         dsdt_size = size;
+       }
+      else
+       {
+         struct efiemu_acpi_table *table;
+         table = (struct efiemu_acpi_table *) grub_malloc
+           (sizeof (struct efiemu_acpi_table));
+         if (! table)
+           {
+             free_tables ();
+             return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                                "couldn't allocate table structure");
+           }
+
+         table->size = size;
+         table->addr = buf;
+         playground_size += table->size;
+
+         table->next = acpi_tables;
+         acpi_tables = table;
+       }
+    }
+
+  numoftables = 0;
+  for (cur = acpi_tables; cur; cur = cur->next)
+    numoftables++;
+
+  /* DSDT. */
+  playground_size += dsdt_size;
+  /* RSDT. */
+  playground_size += sizeof (struct grub_acpi_table_header) + 4 * numoftables;
+  /* RSDPv1. */
+  playground_size += sizeof (struct grub_acpi_rsdp_v10);
+  /* XSDT. */
+  playground_size += sizeof (struct grub_acpi_table_header) + 8 * numoftables;
+  /* RSDPv2. */
+  playground_size += sizeof (struct grub_acpi_rsdp_v20);
+
+  playground = playground_ptr
+    = grub_mmap_malign_and_register (1, playground_size, &mmapregion,
+                                    GRUB_MACHINE_MEMORY_ACPI, 0);
+
+  if (! playground)
+    {
+      free_tables ();
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                        "couldn't allocate space for ACPI tables");
+    }
+
+  setup_common_tables ();
+
+  /* Request space for RSDPv1. */
+  if (rev1)
+    setv1table ();
+
+  /* Request space for RSDPv2+ and XSDT. */
+  if (rev2)
+    setv2table ();
+
+  for (cur = acpi_tables; cur;)
+    {
+      t = cur;
+      cur = cur->next;
+      grub_free (t);
+    }
+  acpi_tables = 0;
+
+  if (! state[9].set && (err = grub_acpi_create_ebda ()))
+    {
+      rsdpv1_new = 0;
+      rsdpv2_new = 0;
+      grub_mmap_free_and_unregister (mmapregion);
+      return err;
+    }
+
+#ifdef GRUB_MACHINE_EFI
+  {
+    struct grub_efi_guid acpi = GRUB_EFI_ACPI_TABLE_GUID;
+    struct grub_efi_guid acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
+
+    grub_efi_system_table->boot_services->install_configuration_table
+      (&acpi20, grub_acpi_get_rsdpv2 ());
+    grub_efi_system_table->boot_services->install_configuration_table
+      (&acpi, grub_acpi_get_rsdpv1 ());
+  }
+#endif
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(acpi)
+{
+  cmd = grub_register_extcmd ("acpi", grub_cmd_acpi,
+                             GRUB_COMMAND_FLAG_BOTH,
+                             N_("[-1|-2] [--exclude=TABLE1,TABLE2|"
+                             "--load-only=table1,table2] FILE1"
+                             " [FILE2] [...]"),
+                             N_("Load host ACPI tables and tables "
+                             "specified by arguments."),
+                             options);
+}
+
+GRUB_MOD_FINI(acpi)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/blocklist.c b/grub-core/commands/blocklist.c
new file mode 100644 (file)
index 0000000..cace311
--- /dev/null
@@ -0,0 +1,119 @@
+/* blocklist.c - print the block list of a file */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)),
+                   int argc, char **args)
+{
+  grub_file_t file;
+  char buf[GRUB_DISK_SECTOR_SIZE];
+  unsigned long start_sector = 0;
+  unsigned num_sectors = 0;
+  int num_entries = 0;
+  grub_disk_addr_t part_start = 0;
+  auto void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned offset,
+                           unsigned length);
+  auto void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num,
+                            unsigned offset, unsigned length);
+
+  void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned offset,
+                      unsigned length)
+    {
+      if (num_sectors > 0)
+       {
+         if (start_sector + num_sectors == sector
+             && offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
+           {
+             num_sectors++;
+             return;
+           }
+
+         print_blocklist (start_sector, num_sectors, 0, 0);
+         num_sectors = 0;
+       }
+
+      if (offset == 0 && length == GRUB_DISK_SECTOR_SIZE)
+       {
+         start_sector = sector;
+         num_sectors++;
+       }
+      else
+       print_blocklist (sector, 0, offset, length);
+    }
+
+  void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num,
+                       unsigned offset, unsigned length)
+    {
+      if (num_entries++)
+       grub_printf (",");
+
+      grub_printf ("%llu", (unsigned long long) (sector - part_start));
+      if (num > 0)
+       grub_printf ("+%u", num);
+      if (offset != 0 || length != 0)
+       grub_printf ("[%u-%u]", offset, offset + length);
+    }
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
+
+  file = grub_file_open (args[0]);
+  if (! file)
+    return grub_errno;
+
+  if (! file->device->disk)
+    return grub_error (GRUB_ERR_BAD_DEVICE,
+                      "this command is available only for disk devices");
+
+  part_start = grub_partition_get_start (file->device->disk->partition);
+
+  file->read_hook = read_blocklist;
+
+  while (grub_file_read (file, buf, sizeof (buf)) > 0)
+    ;
+
+  if (num_sectors > 0)
+    print_blocklist (start_sector, num_sectors, 0, 0);
+
+  grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd;
+\f
+GRUB_MOD_INIT(blocklist)
+{
+  cmd = grub_register_command ("blocklist", grub_cmd_blocklist,
+                              N_("FILE"), N_("Print a block list."));
+}
+
+GRUB_MOD_FINI(blocklist)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/boot.c b/grub-core/commands/boot.c
new file mode 100644 (file)
index 0000000..1ec1e6f
--- /dev/null
@@ -0,0 +1,196 @@
+/* boot.c - command to boot an operating system */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/loader.h>
+#include <grub/kernel.h>
+#include <grub/mm.h>
+#include <grub/i18n.h>
+
+static grub_err_t (*grub_loader_boot_func) (void);
+static grub_err_t (*grub_loader_unload_func) (void);
+static int grub_loader_noreturn;
+
+struct grub_preboot_t
+{
+  grub_err_t (*preboot_func) (int);
+  grub_err_t (*preboot_rest_func) (void);
+  grub_loader_preboot_hook_prio_t prio;
+  struct grub_preboot_t *next;
+  struct grub_preboot_t *prev;
+};
+
+static int grub_loader_loaded;
+static struct grub_preboot_t *preboots_head = 0,
+  *preboots_tail = 0;
+
+int
+grub_loader_is_loaded (void)
+{
+  return grub_loader_loaded;
+}
+
+/* Register a preboot hook. */
+void *
+grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noreturn),
+                                  grub_err_t (*preboot_rest_func) (void),
+                                  grub_loader_preboot_hook_prio_t prio)
+{
+  struct grub_preboot_t *cur, *new_preboot;
+
+  if (! preboot_func && ! preboot_rest_func)
+    return 0;
+
+  new_preboot = (struct grub_preboot_t *)
+    grub_malloc (sizeof (struct grub_preboot_t));
+  if (! new_preboot)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "hook not added");
+      return 0;
+    }
+
+  new_preboot->preboot_func = preboot_func;
+  new_preboot->preboot_rest_func = preboot_rest_func;
+  new_preboot->prio = prio;
+
+  for (cur = preboots_head; cur && cur->prio > prio; cur = cur->next);
+
+  if (cur)
+    {
+      new_preboot->next = cur;
+      new_preboot->prev = cur->prev;
+      cur->prev = new_preboot;
+    }
+  else
+    {
+      new_preboot->next = 0;
+      new_preboot->prev = preboots_tail;
+      preboots_tail = new_preboot;
+    }
+  if (new_preboot->prev)
+    new_preboot->prev->next = new_preboot;
+  else
+    preboots_head = new_preboot;
+
+  return new_preboot;
+}
+
+void
+grub_loader_unregister_preboot_hook (void *hnd)
+{
+  struct grub_preboot_t *preb = hnd;
+
+  if (preb->next)
+    preb->next->prev = preb->prev;
+  else
+    preboots_tail = preb->prev;
+  if (preb->prev)
+    preb->prev->next = preb->next;
+  else
+    preboots_head = preb->next;
+
+  grub_free (preb);
+}
+
+void
+grub_loader_set (grub_err_t (*boot) (void),
+                grub_err_t (*unload) (void),
+                int noreturn)
+{
+  if (grub_loader_loaded && grub_loader_unload_func)
+    grub_loader_unload_func ();
+
+  grub_loader_boot_func = boot;
+  grub_loader_unload_func = unload;
+  grub_loader_noreturn = noreturn;
+
+  grub_loader_loaded = 1;
+}
+
+void
+grub_loader_unset(void)
+{
+  if (grub_loader_loaded && grub_loader_unload_func)
+    grub_loader_unload_func ();
+
+  grub_loader_boot_func = 0;
+  grub_loader_unload_func = 0;
+
+  grub_loader_loaded = 0;
+}
+
+grub_err_t
+grub_loader_boot (void)
+{
+  grub_err_t err = GRUB_ERR_NONE;
+  struct grub_preboot_t *cur;
+
+  if (! grub_loader_loaded)
+    return grub_error (GRUB_ERR_NO_KERNEL, "no loaded kernel");
+
+  if (grub_loader_noreturn)
+    grub_machine_fini ();
+
+  for (cur = preboots_head; cur; cur = cur->next)
+    {
+      err = cur->preboot_func (grub_loader_noreturn);
+      if (err)
+       {
+         for (cur = cur->prev; cur; cur = cur->prev)
+           cur->preboot_rest_func ();
+         return err;
+       }
+    }
+  err = (grub_loader_boot_func) ();
+
+  for (cur = preboots_tail; cur; cur = cur->prev)
+    if (! err)
+      err = cur->preboot_rest_func ();
+    else
+      cur->preboot_rest_func ();
+
+  return err;
+}
+
+/* boot */
+static grub_err_t
+grub_cmd_boot (struct grub_command *cmd __attribute__ ((unused)),
+                   int argc __attribute__ ((unused)),
+                   char *argv[] __attribute__ ((unused)))
+{
+  return grub_loader_boot ();
+}
+
+\f
+
+static grub_command_t cmd_boot;
+
+GRUB_MOD_INIT(boot)
+{
+  cmd_boot =
+    grub_register_command ("boot", grub_cmd_boot,
+                          0, N_("Boot an operating system."));
+}
+
+GRUB_MOD_FINI(boot)
+{
+  grub_unregister_command (cmd_boot);
+}
diff --git a/grub-core/commands/cat.c b/grub-core/commands/cat.c
new file mode 100644 (file)
index 0000000..3bdafc4
--- /dev/null
@@ -0,0 +1,88 @@
+/* cat.c - command to show the contents of a file  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/gzio.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)),
+             int argc, char **args)
+
+{
+  grub_file_t file;
+  char buf[GRUB_DISK_SECTOR_SIZE];
+  grub_ssize_t size;
+  int key = 0;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  file = grub_gzfile_open (args[0], 1);
+  if (! file)
+    return grub_errno;
+
+  while ((size = grub_file_read (file, buf, sizeof (buf))) > 0
+        && key != GRUB_TERM_ESC)
+    {
+      int i;
+
+      for (i = 0; i < size; i++)
+       {
+         unsigned char c = buf[i];
+
+         if ((grub_isprint (c) || grub_isspace (c)) && c != '\r')
+           grub_putchar (c);
+         else
+           {
+             grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
+             grub_printf ("<%x>", (int) c);
+             grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
+           }
+       }
+
+      while (grub_checkkey () >= 0 &&
+            (key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != GRUB_TERM_ESC)
+       ;
+    }
+
+  grub_putchar ('\n');
+  grub_refresh ();
+  grub_file_close (file);
+
+  return 0;
+}
+
+static grub_command_t cmd;
+\f
+GRUB_MOD_INIT(cat)
+{
+  cmd = grub_register_command_p1 ("cat", grub_cmd_cat,
+                                 N_("FILE"), N_("Show the contents of a file."));
+}
+
+GRUB_MOD_FINI(cat)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/cmp.c b/grub-core/commands/cmp.c
new file mode 100644 (file)
index 0000000..626e1d0
--- /dev/null
@@ -0,0 +1,119 @@
+/* cmd.c - command to cmp an operating system */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/gzio.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+#define BUFFER_SIZE 512
+
+static grub_err_t
+grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)),
+             int argc, char **args)
+{
+  grub_ssize_t rd1, rd2;
+  grub_off_t pos;
+  grub_file_t file1 = 0;
+  grub_file_t file2 = 0;
+  char *buf1 = 0;
+  char *buf2 = 0;
+
+  if (argc != 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required");
+
+  grub_printf ("Compare file `%s' with `%s':\n", args[0],
+              args[1]);
+
+  file1 = grub_gzfile_open (args[0], 1);
+  file2 = grub_gzfile_open (args[1], 1);
+  if (! file1 || ! file2)
+    goto cleanup;
+
+  if (grub_file_size (file1) != grub_file_size (file2))
+    grub_printf ("Files differ in size: %llu [%s], %llu [%s]\n",
+                (unsigned long long) grub_file_size (file1), args[0],
+                (unsigned long long) grub_file_size (file2), args[1]);
+  else
+    {
+      pos = 0;
+
+      buf1 = grub_malloc (BUFFER_SIZE);
+      buf2 = grub_malloc (BUFFER_SIZE);
+
+      if (! buf1 || ! buf2)
+        goto cleanup;
+
+      do
+       {
+         int i;
+
+         rd1 = grub_file_read (file1, buf1, BUFFER_SIZE);
+         rd2 = grub_file_read (file2, buf2, BUFFER_SIZE);
+
+         if (rd1 != rd2)
+           goto cleanup;
+
+         for (i = 0; i < rd2; i++)
+           {
+             if (buf1[i] != buf2[i])
+               {
+                 grub_printf ("Files differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n",
+                              (unsigned long long) (i + pos), buf1[i], args[0],
+                              buf2[i], args[1]);
+                 goto cleanup;
+               }
+           }
+         pos += BUFFER_SIZE;
+
+       }
+      while (rd2);
+
+      grub_printf ("The files are identical.\n");
+    }
+
+cleanup:
+
+  if (buf1)
+    grub_free (buf1);
+  if (buf2)
+    grub_free (buf2);
+  if (file1)
+    grub_file_close (file1);
+  if (file2)
+    grub_file_close (file2);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd;
+\f
+GRUB_MOD_INIT(cmp)
+{
+  cmd = grub_register_command ("cmp", grub_cmd_cmp,
+                              N_("FILE1 FILE2"), N_("Compare two files."));
+}
+
+GRUB_MOD_FINI(cmp)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/configfile.c b/grub-core/commands/configfile.c
new file mode 100644 (file)
index 0000000..4694477
--- /dev/null
@@ -0,0 +1,75 @@
+/* configfile.c - command to manually load config file  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/term.h>
+#include <grub/env.h>
+#include <grub/normal.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+grub_cmd_source (grub_command_t cmd, int argc, char **args)
+{
+  int new_env;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  new_env = (cmd->name[0] == 'c');
+
+  if (new_env)
+    {
+      grub_cls ();
+      grub_env_context_open (1);
+    }
+
+  grub_normal_execute (args[0], 1, ! new_env);
+
+  if (new_env)
+    grub_env_context_close ();
+
+  return 0;
+}
+
+static grub_command_t cmd_configfile, cmd_source, cmd_dot;
+\f
+GRUB_MOD_INIT(configfile)
+{
+  cmd_configfile =
+    grub_register_command ("configfile", grub_cmd_source,
+                          N_("FILE"), N_("Load another config file."));
+  cmd_source =
+    grub_register_command ("source", grub_cmd_source,
+                          N_("FILE"),
+                          N_("Load another config file without changing context.")
+                          );
+  cmd_dot =
+    grub_register_command (".", grub_cmd_source,
+                          N_("FILE"),
+                          N_("Load another config file without changing context.")
+                          );
+}
+
+GRUB_MOD_FINI(configfile)
+{
+  grub_unregister_command (cmd_configfile);
+  grub_unregister_command (cmd_source);
+  grub_unregister_command (cmd_dot);
+}
diff --git a/grub-core/commands/crc.c b/grub-core/commands/crc.c
new file mode 100644 (file)
index 0000000..1c1a690
--- /dev/null
@@ -0,0 +1,71 @@
+/* crc.c - command to calculate the crc32 checksum of a file  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/misc.h>
+#include <grub/lib/crc.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+grub_cmd_crc (grub_command_t cmd __attribute__ ((unused)),
+             int argc, char **args)
+
+{
+  grub_file_t file;
+  char buf[GRUB_DISK_SECTOR_SIZE];
+  grub_ssize_t size;
+  grub_uint32_t crc;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  file = grub_file_open (args[0]);
+  if (! file)
+    return 0;
+
+  crc = 0;
+  while ((size = grub_file_read (file, buf, sizeof (buf))) > 0)
+    crc = grub_getcrc32 (crc, buf, size);
+
+  if (grub_errno)
+    goto fail;
+
+  grub_printf ("%08x\n", crc);
+
+ fail:
+  grub_file_close (file);
+  return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(crc)
+{
+  cmd = grub_register_command ("crc", grub_cmd_crc,
+                              N_("FILE"),
+                              N_("Calculate the crc32 checksum of a file."));
+}
+
+GRUB_MOD_FINI(crc)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/date.c b/grub-core/commands/date.c
new file mode 100644 (file)
index 0000000..623db49
--- /dev/null
@@ -0,0 +1,146 @@
+/* date.c - command to display/set current datetime.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/datetime.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+#define GRUB_DATETIME_SET_YEAR         1
+#define GRUB_DATETIME_SET_MONTH                2
+#define GRUB_DATETIME_SET_DAY          4
+#define GRUB_DATETIME_SET_HOUR         8
+#define GRUB_DATETIME_SET_MINUTE       16
+#define GRUB_DATETIME_SET_SECOND       32
+
+static grub_err_t
+grub_cmd_date (grub_command_t cmd __attribute__ ((unused)),
+               int argc, char **args)
+{
+  struct grub_datetime datetime;
+  int limit[6][2] = {{1980, 2079}, {1, 12}, {1, 31}, {0, 23}, {0, 59}, {0, 59}};
+  int value[6], mask;
+
+  if (argc == 0)
+    {
+      if (grub_get_datetime (&datetime))
+        return grub_errno;
+
+      grub_printf ("%d-%02d-%02d %02d:%02d:%02d %s\n",
+                   datetime.year, datetime.month, datetime.day,
+                   datetime.hour, datetime.minute, datetime.second,
+                   grub_get_weekday_name (&datetime));
+
+      return 0;
+    }
+
+  grub_memset (&value, 0, sizeof (value));
+  mask = 0;
+
+  for (; argc; argc--, args++)
+    {
+      char *p, c;
+      int m1, ofs, n, cur_mask;
+
+      p = args[0];
+      m1 = grub_strtoul (p, &p, 10);
+
+      c = *p;
+      if (c == '-')
+        ofs = 0;
+      else if (c == ':')
+        ofs = 3;
+      else
+        goto fail;
+
+      value[ofs] = m1;
+      cur_mask = (1 << ofs);
+      mask &= ~(cur_mask * (1 + 2 + 4));
+
+      for (n = 1; (n < 3) && (*p); n++)
+        {
+          if (*p != c)
+            goto fail;
+
+          value[ofs + n] = grub_strtoul (p + 1, &p, 10);
+          cur_mask |= (1 << (ofs + n));
+        }
+
+      if (*p)
+        goto fail;
+
+      if ((ofs == 0) && (n == 2))
+        {
+          value[ofs + 2] = value[ofs + 1];
+          value[ofs + 1] = value[ofs];
+          ofs++;
+          cur_mask <<= 1;
+        }
+
+      for (; n; n--, ofs++)
+        if ((value [ofs] < limit[ofs][0]) ||
+            (value [ofs] > limit[ofs][1]))
+          goto fail;
+
+      mask |= cur_mask;
+    }
+
+  if (grub_get_datetime (&datetime))
+    return grub_errno;
+
+  if (mask & GRUB_DATETIME_SET_YEAR)
+    datetime.year = value[0];
+
+  if (mask & GRUB_DATETIME_SET_MONTH)
+    datetime.month = value[1];
+
+  if (mask & GRUB_DATETIME_SET_DAY)
+    datetime.day = value[2];
+
+  if (mask & GRUB_DATETIME_SET_HOUR)
+    datetime.hour = value[3];
+
+  if (mask & GRUB_DATETIME_SET_MINUTE)
+    datetime.minute = value[4];
+
+  if (mask & GRUB_DATETIME_SET_SECOND)
+    datetime.second = value[5];
+
+  return grub_set_datetime (&datetime);
+
+fail:
+  return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid datetime");
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(date)
+{
+  cmd =
+    grub_register_command ("date", grub_cmd_date,
+                          N_("[[year-]month-day] [hour:minute[:second]]"),
+                          N_("Command to display/set current datetime."));
+}
+
+GRUB_MOD_FINI(date)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/echo.c b/grub-core/commands/echo.c
new file mode 100644 (file)
index 0000000..4fea091
--- /dev/null
@@ -0,0 +1,124 @@
+/* echo.c - Command to display a line of text  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {0, 'n', 0, N_("Do not output the trailing newline."), 0, 0},
+    {0, 'e', 0, N_("Enable interpretation of backslash escapes."), 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static grub_err_t
+grub_cmd_echo (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  int newline = 1;
+  int i;
+
+  /* Check if `-n' was used.  */
+  if (state[0].set)
+    newline = 0;
+
+  for (i = 0; i < argc; i++)
+    {
+      char *arg = *args;
+      args++;
+
+      while (*arg)
+       {
+         /* In case `-e' is used, parse backslashes.  */
+         if (*arg == '\\' && state[1].set)
+           {
+             arg++;
+             if (*arg == '\0')
+               break;
+
+             switch (*arg)
+               {
+               case '\\':
+                 grub_printf ("\\");
+                 break;
+
+               case 'a':
+                 grub_printf ("\a");
+                 break;
+
+               case 'c':
+                 newline = 0;
+                 break;
+
+               case 'f':
+                 grub_printf ("\f");
+                 break;
+
+               case 'n':
+                 grub_printf ("\n");
+                 break;
+
+               case 'r':
+                 grub_printf ("\r");
+                 break;
+
+               case 't':
+                 grub_printf ("\t");
+                 break;
+
+               case 'v':
+                 grub_printf ("\v");
+                 break;
+               }
+             arg++;
+             continue;
+           }
+
+         /* This was not an escaped character, or escaping is not
+            enabled.  */
+         grub_printf ("%c", *arg);
+         arg++;
+       }
+
+      /* If another argument follows, insert a space.  */
+      if (i != argc - 1)
+       grub_printf (" " );
+    }
+
+  if (newline)
+    grub_printf ("\n");
+
+  return 0;
+}
+
+static grub_extcmd_t cmd;
+\f
+GRUB_MOD_INIT(echo)
+{
+  cmd = grub_register_extcmd ("echo", grub_cmd_echo, GRUB_COMMAND_FLAG_BOTH,
+                             N_("[-e|-n] STRING"), N_("Display a line of text."),
+                             options);
+}
+
+GRUB_MOD_FINI(echo)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/efi/acpi.c b/grub-core/commands/efi/acpi.c
new file mode 100644 (file)
index 0000000..93a560d
--- /dev/null
@@ -0,0 +1,59 @@
+/* acpi.c - get acpi tables. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/acpi.h>
+#include <grub/misc.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/api.h>
+
+struct grub_acpi_rsdp_v10 *
+grub_machine_acpi_get_rsdpv1 (void)
+{
+  unsigned i;
+  static grub_efi_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID;
+
+  for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
+    {
+      grub_efi_guid_t *guid =
+       &grub_efi_system_table->configuration_table[i].vendor_guid;
+
+      if (! grub_memcmp (guid, &acpi_guid, sizeof (grub_efi_guid_t)))
+       return (struct grub_acpi_rsdp_v10 *)
+         grub_efi_system_table->configuration_table[i].vendor_table;
+    }
+  return 0;
+}
+
+struct grub_acpi_rsdp_v20 *
+grub_machine_acpi_get_rsdpv2 (void)
+{
+  unsigned i;
+  static grub_efi_guid_t acpi20_guid = GRUB_EFI_ACPI_20_TABLE_GUID;
+
+  for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
+    {
+      grub_efi_guid_t *guid =
+       &grub_efi_system_table->configuration_table[i].vendor_guid;
+
+      if (! grub_memcmp (guid, &acpi20_guid, sizeof (grub_efi_guid_t)))
+       return (struct grub_acpi_rsdp_v20 *)
+         grub_efi_system_table->configuration_table[i].vendor_table;
+    }
+  return 0;
+}
diff --git a/grub-core/commands/efi/fixvideo.c b/grub-core/commands/efi/fixvideo.c
new file mode 100644 (file)
index 0000000..6430be5
--- /dev/null
@@ -0,0 +1,110 @@
+/* fixvideo.c - fix video problem in efi */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/pci.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static struct grub_video_patch
+{
+  const char *name;
+  grub_uint32_t pci_id;
+  grub_uint32_t mmio_bar;
+  grub_uint32_t mmio_reg;
+  grub_uint32_t mmio_old;
+} video_patches[] =
+  {
+    {"Intel 945GM", 0x27a28086, 0, 0x71184, 0x1000000}, /* DSPBBASE  */
+    {"Intel 965GM", 0x2a028086, 0, 0x7119C, 0x1000000}, /* DSPBSURF  */
+    {0, 0, 0, 0, 0}
+  };
+
+static int NESTED_FUNC_ATTR
+scan_card (grub_pci_device_t dev, grub_pci_id_t pciid)
+{
+  grub_pci_address_t addr;
+
+  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+  if (grub_pci_read_byte (addr + 3) == 0x3)
+    {
+      struct grub_video_patch *p = video_patches;
+
+      while (p->name)
+       {
+         if (p->pci_id == pciid)
+           {
+             grub_target_addr_t base;
+
+             grub_printf ("Found graphic card: %s\n", p->name);
+             addr += 8 + p->mmio_bar * 4;
+             base = grub_pci_read (addr);
+             if ((! base) || (base & GRUB_PCI_ADDR_SPACE_IO) ||
+                 (base & GRUB_PCI_ADDR_MEM_PREFETCH))
+               grub_printf ("Invalid MMIO bar %d\n", p->mmio_bar);
+             else
+               {
+                 base &= GRUB_PCI_ADDR_MEM_MASK;
+                 base += p->mmio_reg;
+
+                 if (*((volatile grub_uint32_t *) base) != p->mmio_old)
+                   grub_printf ("Old value don't match\n");
+                 else
+                   {
+                     *((volatile grub_uint32_t *) base) = 0;
+                     if (*((volatile grub_uint32_t *) base))
+                       grub_printf ("Set MMIO fails\n");
+                   }
+               }
+
+             return 1;
+           }
+         p++;
+       }
+
+      grub_printf ("Unknown graphic card: %x\n", pciid);
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_fixvideo (grub_command_t cmd __attribute__ ((unused)),
+                  int argc __attribute__ ((unused)),
+                  char *argv[] __attribute__ ((unused)))
+{
+  grub_pci_iterate (scan_card);
+  return 0;
+}
+
+static grub_command_t cmd_fixvideo;
+
+GRUB_MOD_INIT(fixvideo)
+{
+  cmd_fixvideo = grub_register_command ("fix_video", grub_cmd_fixvideo,
+                                       0, N_("Fix video problem."));
+
+}
+
+GRUB_MOD_FINI(fixvideo)
+{
+  grub_unregister_command (cmd_fixvideo);
+}
diff --git a/grub-core/commands/efi/loadbios.c b/grub-core/commands/efi/loadbios.c
new file mode 100644 (file)
index 0000000..8c7c25a
--- /dev/null
@@ -0,0 +1,218 @@
+/* loadbios.c - command to load a bios dump  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/efi/efi.h>
+#include <grub/pci.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static grub_efi_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID;
+static grub_efi_guid_t acpi2_guid = GRUB_EFI_ACPI_20_TABLE_GUID;
+static grub_efi_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID;
+
+#define EBDA_SEG_ADDR  0x40e
+#define LOW_MEM_ADDR   0x413
+#define FAKE_EBDA_SEG  0x9fc0
+
+#define BLANK_MEM      0xffffffff
+#define VBIOS_ADDR     0xc0000
+#define SBIOS_ADDR     0xf0000
+
+static int
+enable_rom_area (void)
+{
+  grub_pci_address_t addr;
+  grub_uint32_t *rom_ptr;
+  grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0};
+
+  rom_ptr = (grub_uint32_t *) VBIOS_ADDR;
+  if (*rom_ptr != BLANK_MEM)
+    {
+      grub_printf ("ROM image is present.\n");
+      return 0;
+    }
+
+  /* FIXME: should be macroified.  */
+  addr = grub_pci_make_address (dev, 144);
+  grub_pci_write_byte (addr++, 0x30);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr++, 0x33);
+  grub_pci_write_byte (addr, 0);
+
+  *rom_ptr = 0;
+  if (*rom_ptr != 0)
+    {
+      grub_printf ("Can\'t enable ROM area.\n");
+      return 0;
+    }
+
+  return 1;
+}
+
+static void
+lock_rom_area (void)
+{
+  grub_pci_address_t addr;
+  grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0};
+
+  /* FIXME: should be macroified.  */
+  addr = grub_pci_make_address (dev, 144);
+  grub_pci_write_byte (addr++, 0x10);
+  grub_pci_write_byte (addr++, 0x11);
+  grub_pci_write_byte (addr++, 0x11);
+  grub_pci_write_byte (addr++, 0x11);
+  grub_pci_write_byte (addr, 0x11);
+}
+
+static void
+fake_bios_data (int use_rom)
+{
+  unsigned i;
+  void *acpi, *smbios;
+  grub_uint16_t *ebda_seg_ptr, *low_mem_ptr;
+
+  ebda_seg_ptr = (grub_uint16_t *) EBDA_SEG_ADDR;
+  low_mem_ptr = (grub_uint16_t *) LOW_MEM_ADDR;
+  if ((*ebda_seg_ptr) || (*low_mem_ptr))
+    return;
+
+  acpi = 0;
+  smbios = 0;
+  for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
+    {
+      grub_efi_guid_t *guid =
+       &grub_efi_system_table->configuration_table[i].vendor_guid;
+
+      if (! grub_memcmp (guid, &acpi2_guid, sizeof (grub_efi_guid_t)))
+       {
+         acpi = grub_efi_system_table->configuration_table[i].vendor_table;
+         grub_dprintf ("efi", "ACPI2: %p\n", acpi);
+       }
+      else if (! grub_memcmp (guid, &acpi_guid, sizeof (grub_efi_guid_t)))
+       {
+         void *t;
+
+         t = grub_efi_system_table->configuration_table[i].vendor_table;
+         if (! acpi)
+           acpi = t;
+         grub_dprintf ("efi", "ACPI: %p\n", t);
+       }
+      else if (! grub_memcmp (guid, &smbios_guid, sizeof (grub_efi_guid_t)))
+       {
+         smbios = grub_efi_system_table->configuration_table[i].vendor_table;
+         grub_dprintf ("efi", "SMBIOS: %p\n", smbios);
+       }
+    }
+
+  *ebda_seg_ptr = FAKE_EBDA_SEG;
+  *low_mem_ptr = (FAKE_EBDA_SEG >> 6);
+
+  *((grub_uint16_t *) (FAKE_EBDA_SEG << 4)) = 640 - *low_mem_ptr;
+
+  if (acpi)
+    grub_memcpy ((char *) ((FAKE_EBDA_SEG << 4) + 16), acpi, 1024 - 16);
+
+  if ((use_rom) && (smbios))
+    grub_memcpy ((char *) SBIOS_ADDR, (char *) smbios + 16, 16);
+}
+
+static grub_err_t
+grub_cmd_fakebios (struct grub_command *cmd __attribute__ ((unused)),
+                  int argc __attribute__ ((unused)),
+                  char *argv[] __attribute__ ((unused)))
+{
+  if (enable_rom_area ())
+    {
+      fake_bios_data (1);
+      lock_rom_area ();
+    }
+  else
+    fake_bios_data (0);
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)),
+                  int argc, char *argv[])
+{
+  grub_file_t file;
+  int size;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no ROM image specified");
+
+  if (argc > 1)
+    {
+      file = grub_file_open (argv[1]);
+      if (! file)
+       return grub_errno;
+
+      if (file->size != 4)
+       grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid int10 dump size");
+      else
+       grub_file_read (file, (void *) 0x40, 4);
+
+      grub_file_close (file);
+      if (grub_errno)
+       return grub_errno;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    return grub_errno;
+
+  size = file->size;
+  if ((size < 0x10000) || (size > 0x40000))
+    grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid bios dump size");
+  else if (enable_rom_area ())
+    {
+      grub_file_read (file, (void *) VBIOS_ADDR, size);
+      fake_bios_data (size <= 0x40000);
+      lock_rom_area ();
+    }
+
+  grub_file_close (file);
+  return grub_errno;
+}
+
+static grub_command_t cmd_fakebios, cmd_loadbios;
+
+GRUB_MOD_INIT(loadbios)
+{
+  cmd_fakebios = grub_register_command ("fakebios", grub_cmd_fakebios,
+                                       0, N_("Fake BIOS."));
+
+  cmd_loadbios = grub_register_command ("loadbios", grub_cmd_loadbios,
+                                       "BIOS_DUMP [INT10_DUMP]",
+                                       N_("Load BIOS dump."));
+}
+
+GRUB_MOD_FINI(loadbios)
+{
+  grub_unregister_command (cmd_fakebios);
+  grub_unregister_command (cmd_loadbios);
+}
diff --git a/grub-core/commands/extcmd.c b/grub-core/commands/extcmd.c
new file mode 100644 (file)
index 0000000..16796fe
--- /dev/null
@@ -0,0 +1,96 @@
+/* extcmd.c - support extended command */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/list.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+
+static grub_err_t
+grub_extcmd_dispatcher (struct grub_command *cmd,
+                       int argc, char **args)
+{
+  int new_argc;
+  char **new_args;
+  struct grub_arg_option *parser;
+  struct grub_arg_list *state;
+  int maxargs = 0;
+  grub_err_t ret;
+  grub_extcmd_t ext;
+
+  ext = cmd->data;
+  parser = (struct grub_arg_option *) ext->options;
+  while (parser && (parser++)->doc)
+    maxargs++;
+
+  /* Set up the option state.  */
+  state = grub_zalloc (sizeof (struct grub_arg_list) * maxargs);
+
+  if (grub_arg_parse (ext, argc, args, state, &new_args, &new_argc))
+    {
+      ext->state = state;
+      ret = (ext->func) (ext, new_argc, new_args);
+      grub_free (new_args);
+    }
+  else
+    ret = grub_errno;
+
+  grub_free (state);
+
+  return ret;
+}
+
+grub_extcmd_t
+grub_register_extcmd (const char *name, grub_extcmd_func_t func,
+                     unsigned flags, const char *summary,
+                     const char *description,
+                     const struct grub_arg_option *parser)
+{
+  grub_extcmd_t ext;
+  grub_command_t cmd;
+
+  ext = (grub_extcmd_t) grub_malloc (sizeof (*ext));
+  if (! ext)
+    return 0;
+
+  cmd = grub_register_command_prio (name, grub_extcmd_dispatcher,
+                                   summary, description, 1);
+  if (! cmd)
+    {
+      grub_free (ext);
+      return 0;
+    }
+
+  cmd->flags = (flags | GRUB_COMMAND_FLAG_EXTCMD);
+  cmd->data = ext;
+
+  ext->cmd = cmd;
+  ext->func = func;
+  ext->options = parser;
+  ext->data = 0;
+
+  return ext;
+}
+
+void
+grub_unregister_extcmd (grub_extcmd_t ext)
+{
+  grub_unregister_command (ext->cmd);
+  grub_free (ext);
+}
diff --git a/grub-core/commands/gptsync.c b/grub-core/commands/gptsync.c
new file mode 100644 (file)
index 0000000..d217b5d
--- /dev/null
@@ -0,0 +1,256 @@
+/* gptsync.c - fill the mbr based on gpt entries  */
+/* XXX: I don't know what to do if sector size isn't 512 bytes */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/command.h>
+#include <grub/dl.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/msdos_partition.h>
+#include <grub/partition.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/fs.h>
+#include <grub/i18n.h>
+
+/* Convert a LBA address to a CHS address in the INT 13 format.  */
+/* Taken from grub1. */
+/* XXX: use hardcoded geometry of C = 1024, H = 255, S = 63.
+   Is it a problem?
+*/
+static void
+lba_to_chs (int lba, grub_uint8_t *cl, grub_uint8_t *ch,
+           grub_uint8_t *dh)
+{
+  int cylinder, head, sector;
+  int sectors = 63, heads = 255, cylinders = 1024;
+
+  sector = lba % sectors + 1;
+  head = (lba / sectors) % heads;
+  cylinder = lba / (sectors * heads);
+
+  if (cylinder >= cylinders)
+    {
+      *cl = *ch = *dh = 0xff;
+      return;
+    }
+
+  *cl = sector | ((cylinder & 0x300) >> 2);
+  *ch = cylinder & 0xFF;
+  *dh = head;
+}
+
+static grub_err_t
+grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)),
+                 int argc, char **args)
+{
+  grub_device_t dev;
+  struct grub_msdos_partition_mbr mbr;
+  struct grub_partition *partition;
+  grub_disk_addr_t first_sector;
+  int numactive = 0;
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
+  if (argc > 4)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "only 3 partitions can be "
+                      "in hybrid MBR");
+
+  if (args[0][0] == '(' && args[0][grub_strlen (args[0]) - 1] == ')')
+    {
+      args[0][grub_strlen (args[0]) - 1] = 0;
+      dev = grub_device_open (args[0] + 1);
+      args[0][grub_strlen (args[0])] = ')';
+    }
+  else
+    dev = grub_device_open (args[0]);
+
+  if (! dev)
+    return grub_errno;
+
+  if (! dev->disk)
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a disk");
+    }
+
+  /* Read the protective MBR.  */
+  if (grub_disk_read (dev->disk, 0, 0, sizeof (mbr), &mbr))
+    {
+      grub_device_close (dev);
+      return grub_errno;
+    }
+
+  /* Check if it is valid.  */
+  if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE))
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
+    }
+
+  /* Make sure the MBR is a protective MBR and not a normal MBR.  */
+  if (mbr.entries[0].type != GRUB_PC_PARTITION_TYPE_GPT_DISK)
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_PART_TABLE, "no GPT partition map found");
+    }
+
+  int i;
+  first_sector = dev->disk->total_sectors;
+  for (i = 1; i < argc; i++)
+    {
+      char *separator, csep = 0;
+      grub_uint8_t type;
+      separator = grub_strchr (args[i], '+');
+      if (! separator)
+       separator = grub_strchr (args[i], '-');
+      if (separator)
+       {
+         csep = *separator;
+         *separator = 0;
+       }
+      partition = grub_partition_probe (dev->disk, args[i]);
+      if (separator)
+       *separator = csep;
+      if (! partition)
+       {
+         grub_device_close (dev);
+         return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such partition");
+       }
+
+      if (partition->start + partition->len > 0xffffffff)
+       {
+         grub_device_close (dev);
+         return grub_error (GRUB_ERR_OUT_OF_RANGE,
+                            "only partitions resding in the first 2TB "
+                            "can be presen in hybrid MBR");
+       }
+
+
+      if (first_sector > partition->start)
+       first_sector = partition->start;
+
+      if (separator && *(separator + 1))
+       type = grub_strtoul (separator + 1, 0, 0);
+      else
+       {
+         grub_fs_t fs = 0;
+         dev->disk->partition = partition;
+         fs = grub_fs_probe (dev);
+
+         /* Unknown filesystem isn't fatal. */
+         if (grub_errno == GRUB_ERR_UNKNOWN_FS)
+           {
+             fs = 0;
+             grub_errno = GRUB_ERR_NONE;
+           }
+
+         if (fs && grub_strcmp (fs->name, "ntfs") == 0)
+           type = GRUB_PC_PARTITION_TYPE_NTFS;
+         else if (fs && grub_strcmp (fs->name, "fat") == 0)
+           /* FIXME: detect FAT16. */
+           type = GRUB_PC_PARTITION_TYPE_FAT32_LBA;
+         else if (fs && (grub_strcmp (fs->name, "hfsplus") == 0
+                         || grub_strcmp (fs->name, "hfs") == 0))
+           type = GRUB_PC_PARTITION_TYPE_HFS;
+         else
+           /* FIXME: detect more types. */
+           type = GRUB_PC_PARTITION_TYPE_EXT2FS;
+
+         dev->disk->partition = 0;
+       }
+
+      mbr.entries[i].flag = (csep == '+') ? 0x80 : 0;
+      if (csep == '+')
+       {
+         numactive++;
+         if (numactive == 2)
+           {
+             grub_device_close (dev);
+             return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                                "only one partition can be active");
+           }
+       }
+      mbr.entries[i].type = type;
+      mbr.entries[i].start = grub_cpu_to_le32 (partition->start);
+      lba_to_chs (partition->start,
+                 &(mbr.entries[i].start_sector),
+                 &(mbr.entries[i].start_cylinder),
+                 &(mbr.entries[i].start_head));
+      lba_to_chs (partition->start + partition->len - 1,
+                 &(mbr.entries[i].end_sector),
+                 &(mbr.entries[i].end_cylinder),
+                 &(mbr.entries[i].end_head));
+      mbr.entries[i].length = grub_cpu_to_le32 (partition->len);
+      grub_free (partition);
+    }
+  for (; i < 4; i++)
+    grub_memset (&(mbr.entries[i]), 0, sizeof (mbr.entries[i]));
+
+  /* The protective partition. */
+  if (first_sector > 0xffffffff)
+    first_sector = 0xffffffff;
+  else
+    first_sector--;
+  mbr.entries[0].flag = 0;
+  mbr.entries[0].type = GRUB_PC_PARTITION_TYPE_GPT_DISK;
+  mbr.entries[0].start = grub_cpu_to_le32 (1);
+  lba_to_chs (1,
+             &(mbr.entries[0].start_sector),
+             &(mbr.entries[0].start_cylinder),
+             &(mbr.entries[0].start_head));
+  lba_to_chs (first_sector,
+             &(mbr.entries[0].end_sector),
+             &(mbr.entries[0].end_cylinder),
+             &(mbr.entries[0].end_head));
+  mbr.entries[0].length = grub_cpu_to_le32 (first_sector);
+
+  mbr.signature = grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE);
+
+  if (grub_disk_write (dev->disk, 0, 0, sizeof (mbr), &mbr))
+    {
+      grub_device_close (dev);
+      return grub_errno;
+    }
+
+  grub_printf ("New MBR is written to '%s'\n", args[0]);
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_command_t cmd;
+\f
+GRUB_MOD_INIT(gptsync)
+{
+  (void) mod;                  /* To stop warning. */
+  cmd = grub_register_command ("gptsync", grub_cmd_gptsync,
+                              N_("DEVICE [PARTITION[+/-[TYPE]]] ..."),
+                              N_("Fill hybrid MBR of GPT drive DEVICE. "
+                              "specified partitions will be a part "
+                              "of hybrid mbr. Up to 3 partitions are "
+                              "allowed. TYPE is an MBR type. "
+                              "+ means that partition is active. "
+                              "Only one partition can be active."));
+}
+
+GRUB_MOD_FINI(gptsync)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/halt.c b/grub-core/commands/halt.c
new file mode 100644 (file)
index 0000000..3400115
--- /dev/null
@@ -0,0 +1,46 @@
+/* halt.c - command to halt the computer.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/command.h>
+#include <grub/misc.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+grub_cmd_halt (grub_command_t cmd __attribute__ ((unused)),
+              int argc __attribute__ ((unused)),
+              char **args __attribute__ ((unused)))
+{
+  grub_halt ();
+  return 0;
+}
+
+static grub_command_t cmd;
+\f
+GRUB_MOD_INIT(halt)
+{
+  cmd = grub_register_command ("halt", grub_cmd_halt,
+                              0, N_("Halts the computer.  This command does" 
+                              " not work on all firmware implementations."));
+}
+
+GRUB_MOD_FINI(halt)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/handler.c b/grub-core/commands/handler.c
new file mode 100644 (file)
index 0000000..f927097
--- /dev/null
@@ -0,0 +1,101 @@
+/* handler.c - commands to list or select handlers */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/handler.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)),
+                 int argc, char **args)
+{
+  void *curr_item = 0;
+  grub_handler_class_t head;
+
+  auto int list_item (grub_named_list_t item);
+  int list_item (grub_named_list_t item)
+    {
+      if (item == curr_item)
+       grub_putchar ('*');
+
+      grub_printf ("%s\n", item->name);
+
+      return 0;
+    }
+
+  head = grub_handler_class_list;
+  if (argc == 0)
+    {
+      grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_item);
+    }
+  else
+    {
+      char *class_name;
+      grub_handler_class_t class;
+
+      class_name = args[0];
+      argc--;
+      args++;
+
+      class = grub_named_list_find (GRUB_AS_NAMED_LIST (head), class_name);
+      if (! class)
+       return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found");
+
+      if (argc == 0)
+       {
+         curr_item = class->cur_handler;
+         grub_list_iterate (GRUB_AS_LIST (class->handler_list),
+                            (grub_list_hook_t) list_item);
+       }
+      else
+       {
+         grub_handler_t handler;
+
+         handler =
+           grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list),
+                                 args[0]);
+
+         if (! handler)
+           return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found");
+
+         grub_handler_set_current (class, handler);
+       }
+    }
+
+  return 0;
+}
+
+static grub_command_t cmd_handler;
+
+GRUB_MOD_INIT(handler)
+{
+  cmd_handler =
+    grub_register_command ("handler", grub_cmd_handler,
+                          N_("[class [handler]]"),
+                          N_("List or select a handler."));
+}
+
+GRUB_MOD_FINI(handler)
+{
+  grub_unregister_command (cmd_handler);
+}
diff --git a/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c
new file mode 100644 (file)
index 0000000..d5f551d
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/extcmd.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/crypto.h>
+#include <grub/normal.h>
+#include <grub/i18n.h>
+
+static const struct grub_arg_option options[] = {
+  {"hash", 'h', 0, N_("Specify hash to use."), N_("HASH"), ARG_TYPE_STRING},
+  {"check", 'c', 0, N_("Check hash list file."), N_("FILE"), ARG_TYPE_STRING},
+  {"prefix", 'p', 0, N_("Base directory for hash list."), N_("DIRECTORY"),
+   ARG_TYPE_STRING},
+  {"keep-going", 'k', 0, N_("Don't stop after first error."), 0, 0},
+  {0, 0, 0, 0, 0, 0}
+};
+
+struct { const char *name; const char *hashname; } aliases[] = 
+  {
+    {"sha256sum", "sha256"},
+    {"sha512sum", "sha512"},
+    {"md5sum", "md5"},
+  };
+
+static inline int
+hextoval (char c)
+{
+  if (c >= '0' && c <= '9')
+    return c - '0';
+  if (c >= 'a' && c <= 'f')
+    return c - 'a' + 10;
+  if (c >= 'A' && c <= 'F')
+    return c - 'A' + 10;
+  return -1;
+}
+
+static grub_err_t
+hash_file (grub_file_t file, const gcry_md_spec_t *hash, void *result)
+{
+  grub_uint8_t context[hash->contextsize];
+  grub_uint8_t readbuf[4096];
+
+  grub_memset (context, 0, sizeof (context));
+  hash->init (context);
+  while (1)
+    {
+      grub_ssize_t r;
+      r = grub_file_read (file, readbuf, sizeof (readbuf));
+      if (r < 0)
+       return grub_errno;
+      if (r == 0)
+       break;
+      hash->write (context, readbuf, r);
+    }
+  hash->final (context);
+  grub_memcpy (result, hash->read (context), hash->mdlen);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+check_list (const gcry_md_spec_t *hash, const char *hashfilename,
+           const char *prefix, int keep)
+{
+  grub_file_t hashlist, file;
+  char *buf = NULL;
+  grub_uint8_t expected[hash->mdlen];
+  grub_uint8_t actual[hash->mdlen];
+  grub_err_t err;
+  unsigned i;
+  unsigned unread = 0, mismatch = 0;
+
+  hashlist = grub_file_open (hashfilename);
+  if (!hashlist)
+    return grub_errno;
+  
+  while (grub_free (buf), (buf = grub_file_getline (hashlist)))
+    {
+      const char *p = buf;
+      for (i = 0; i < hash->mdlen; i++)
+       {
+         int high, low;
+         high = hextoval (*p++);
+         low = hextoval (*p++);
+         if (high < 0 || low < 0)
+           return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list");
+         expected[i] = (high << 4) | low;
+       }
+      if (*p++ != ' ' || *p++ != ' ')
+       return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list");
+      if (prefix)
+       {
+         char *filename;
+         
+         filename = grub_xasprintf ("%s/%s", prefix, p);
+         if (!filename)
+           return grub_errno;
+         file = grub_file_open (filename);
+         grub_free (filename);
+       }
+      else
+       file = grub_file_open (p);
+      if (!file)
+       {
+         grub_file_close (hashlist);
+         grub_free (buf);
+         return grub_errno;
+       }
+      err = hash_file (file, hash, actual);
+      grub_file_close (file);
+      if (err)
+       {
+         grub_printf ("%s: READ ERROR\n", p);
+         if (!keep)
+           {
+             grub_file_close (hashlist);
+             grub_free (buf);
+             return err;
+           }
+         grub_print_error ();
+         grub_errno = GRUB_ERR_NONE;
+         unread++;
+         continue;
+       }
+      if (grub_crypto_memcmp (expected, actual, hash->mdlen) != 0)
+       {
+         grub_printf ("%s: HASH MISMATCH\n", p);
+         if (!keep)
+           {
+             grub_file_close (hashlist);
+             grub_free (buf);
+             return grub_error (GRUB_ERR_TEST_FAILURE,
+                                "hash of '%s' mismatches", p);
+           }
+         mismatch++;
+         continue;       
+       }
+      grub_printf ("%s: OK\n", p);
+    }
+  if (mismatch || unread)
+    return grub_error (GRUB_ERR_TEST_FAILURE,
+                      "%d files couldn't be read and hash "
+                      "of %d files mismatches", unread, mismatch);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_hashsum (struct grub_extcmd *cmd,
+                 int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  const char *hashname = NULL;
+  const char *prefix = NULL;
+  const gcry_md_spec_t *hash;
+  unsigned i;
+  int keep = state[3].set;
+  unsigned unread = 0;
+
+  for (i = 0; i < ARRAY_SIZE (aliases); i++)
+    if (grub_strcmp (cmd->cmd->name, aliases[i].name) == 0)
+      hashname = aliases[i].hashname;
+  if (state[0].set)
+    hashname = state[0].arg;
+
+  if (!hashname)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no hash specified");
+
+  hash = grub_crypto_lookup_md_by_name (hashname);
+  if (!hash)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown hash");
+
+  if (state[2].set)
+    prefix = state[2].arg;
+
+  if (state[1].set)
+    {
+      if (argc != 0)
+       return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                          "--check is incompatible with file list");
+      return check_list (hash, state[1].arg, prefix, keep);
+    }
+
+  for (i = 0; i < (unsigned) argc; i++)
+    {
+      grub_uint8_t result[hash->mdlen];
+      grub_file_t file;
+      grub_err_t err;
+      unsigned j;
+      file = grub_file_open (args[i]);
+      if (!file)
+       {
+         if (!keep)
+           return grub_errno;
+         grub_print_error ();
+         grub_errno = GRUB_ERR_NONE;
+         unread++;
+         continue;
+       }
+      err = hash_file (file, hash, result);
+      grub_file_close (file);
+      if (err)
+       {
+         if (!keep)
+           return err;
+         grub_print_error ();
+         grub_errno = GRUB_ERR_NONE;
+         unread++;
+         continue;
+       }
+      for (j = 0; j < hash->mdlen; j++)
+       grub_printf ("%02x", result[j]);
+      grub_printf ("  %s\n", args[i]);
+    }
+
+  if (unread)
+    return grub_error (GRUB_ERR_TEST_FAILURE, "%d files couldn't be read.",
+                      unread);
+  return GRUB_ERR_NONE;
+}
+
+static grub_extcmd_t cmd, cmd_md5, cmd_sha256, cmd_sha512;
+
+GRUB_MOD_INIT(hashsum)
+{
+  cmd = grub_register_extcmd ("hashsum", grub_cmd_hashsum,
+                             GRUB_COMMAND_FLAG_BOTH,
+                             "hashsum -h HASH [-c FILE [-p PREFIX]] "
+                             "[FILE1 [FILE2 ...]]",
+                             "Compute or check hash checksum.",
+                             options);
+  cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum,
+                                 GRUB_COMMAND_FLAG_BOTH,
+                                 N_("[-c FILE [-p PREFIX]] "
+                                    "[FILE1 [FILE2 ...]]"),
+                                 N_("Compute or check hash checksum."),
+                                 options);
+  cmd_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum,
+                                    GRUB_COMMAND_FLAG_BOTH,
+                                    N_("[-c FILE [-p PREFIX]] "
+                                       "[FILE1 [FILE2 ...]]"),
+                                    "Compute or check hash checksum.",
+                                    options);
+  cmd_sha512 = grub_register_extcmd ("sha512sum", grub_cmd_hashsum,
+                                    GRUB_COMMAND_FLAG_BOTH,
+                                    N_("[-c FILE [-p PREFIX]] "
+                                       "[FILE1 [FILE2 ...]]"),
+                                    N_("Compute or check hash checksum."),
+                                    options);
+}
+
+GRUB_MOD_FINI(hashsum)
+{
+  grub_unregister_extcmd (cmd);
+  grub_unregister_extcmd (cmd_md5);
+  grub_unregister_extcmd (cmd_sha256);
+  grub_unregister_extcmd (cmd_sha512);
+}
diff --git a/grub-core/commands/hdparm.c b/grub-core/commands/hdparm.c
new file mode 100644 (file)
index 0000000..a3f8bbf
--- /dev/null
@@ -0,0 +1,421 @@
+/* hdparm.c - command to get/set ATA disk parameters.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/ata.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/lib/hexdump.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+
+static const struct grub_arg_option options[] = {
+  {"apm",             'B', 0, N_("Set Advanced Power Management\n"
+                             "(1=low, ..., 254=high, 255=off)."),
+                             0, ARG_TYPE_INT},
+  {"power",           'C', 0, N_("Check power mode."), 0, ARG_TYPE_NONE},
+  {"security-freeze", 'F', 0, N_("Freeze ATA security settings until reset."),
+                             0, ARG_TYPE_NONE},
+  {"health",          'H', 0, N_("Check SMART health status."), 0, ARG_TYPE_NONE},
+  {"aam",             'M', 0, N_("Set Automatic Acoustic Management\n"
+                             "(0=off, 128=quiet, ..., 254=fast)."),
+                             0, ARG_TYPE_INT},
+  {"standby-timeout", 'S', 0, N_("Set standby timeout\n"
+                             "(0=off, 1=5s, 2=10s, ..., 240=20m, 241=30m, ...)."),
+                             0, ARG_TYPE_INT},
+  {"standby",         'y', 0, N_("Set drive to standby mode."), 0, ARG_TYPE_NONE},
+  {"sleep",           'Y', 0, N_("Set drive to sleep mode."), 0, ARG_TYPE_NONE},
+  {"identify",        'i', 0, N_("Print drive identity and settings."),
+                             0, ARG_TYPE_NONE},
+  {"dumpid",          'I', 0, N_("Dump contents of ATA IDENTIFY sector."),
+                              0, ARG_TYPE_NONE},
+  {"smart",            -1, 0, N_("Disable/enable SMART (0/1)."), 0, ARG_TYPE_INT},
+  {"quiet",           'q', 0, N_("Do not print messages."), 0, ARG_TYPE_NONE},
+  {0, 0, 0, 0, 0, 0}
+};
+
+enum grub_ata_smart_commands
+  {
+    GRUB_ATA_FEAT_SMART_ENABLE  = 0xd8,
+    GRUB_ATA_FEAT_SMART_DISABLE = 0xd9,
+    GRUB_ATA_FEAT_SMART_STATUS  = 0xda,
+  };
+
+static int quiet = 0;
+
+static grub_err_t
+grub_hdparm_do_ata_cmd (grub_disk_t disk, grub_uint8_t cmd,
+                       grub_uint8_t features, grub_uint8_t sectors,
+                       void * buffer, int size)
+{
+  struct grub_disk_ata_pass_through_parms apt;
+  grub_memset (&apt, 0, sizeof (apt));
+
+  apt.taskfile[GRUB_ATA_REG_CMD] = cmd;
+  apt.taskfile[GRUB_ATA_REG_FEATURES] = features;
+  apt.taskfile[GRUB_ATA_REG_SECTORS] = sectors;
+  apt.buffer = buffer;
+  apt.size = size;
+
+  if (grub_disk_ata_pass_through (disk, &apt))
+    return grub_errno;
+
+  return GRUB_ERR_NONE;
+}
+
+static int
+grub_hdparm_do_check_powermode_cmd (grub_disk_t disk)
+{
+  struct grub_disk_ata_pass_through_parms apt;
+  grub_memset (&apt, 0, sizeof (apt));
+
+  apt.taskfile[GRUB_ATA_REG_CMD] = GRUB_ATA_CMD_CHECK_POWER_MODE;
+
+  if (grub_disk_ata_pass_through (disk, &apt))
+    return -1;
+
+  return apt.taskfile[GRUB_ATA_REG_SECTORS];
+}
+
+static int
+grub_hdparm_do_smart_cmd (grub_disk_t disk, grub_uint8_t features)
+{
+  struct grub_disk_ata_pass_through_parms apt;
+  grub_memset (&apt, 0, sizeof (apt));
+
+  apt.taskfile[GRUB_ATA_REG_CMD] = GRUB_ATA_CMD_SMART;
+  apt.taskfile[GRUB_ATA_REG_FEATURES] = features;
+  apt.taskfile[GRUB_ATA_REG_LBAMID]  = 0x4f;
+  apt.taskfile[GRUB_ATA_REG_LBAHIGH] = 0xc2;
+
+  if (grub_disk_ata_pass_through (disk, &apt))
+    return -1;
+
+  if (features == GRUB_ATA_FEAT_SMART_STATUS)
+    {
+      if (   apt.taskfile[GRUB_ATA_REG_LBAMID]  == 0x4f
+          && apt.taskfile[GRUB_ATA_REG_LBAHIGH] == 0xc2)
+       return 0; /* Good SMART status.  */
+      else if (   apt.taskfile[GRUB_ATA_REG_LBAMID]  == 0xf4
+              && apt.taskfile[GRUB_ATA_REG_LBAHIGH] == 0x2c)
+       return 1; /* Bad SMART status.  */
+      else
+       return -1;
+    }
+  return 0;
+}
+
+static grub_err_t
+grub_hdparm_simple_cmd (const char * msg,
+                       grub_disk_t disk, grub_uint8_t cmd)
+{
+  if (! quiet && msg)
+    grub_printf ("%s", msg);
+
+  grub_err_t err = grub_hdparm_do_ata_cmd (disk, cmd, 0, 0, NULL, 0);
+
+  if (! quiet && msg)
+    grub_printf ("%s\n", ! err ? "" : ": not supported");
+  return err;
+}
+
+static grub_err_t
+grub_hdparm_set_val_cmd (const char * msg, int val,
+                        grub_disk_t disk, grub_uint8_t cmd,
+                        grub_uint8_t features, grub_uint8_t sectors)
+{
+  if (! quiet && msg && *msg)
+    {
+      if (val >= 0)
+       grub_printf ("Set %s to %d", msg, val);
+      else
+       grub_printf ("Disable %s", msg);
+    }
+
+  grub_err_t err = grub_hdparm_do_ata_cmd (disk, cmd, features, sectors,
+                                          NULL, 0);
+
+  if (! quiet && msg)
+    grub_printf ("%s\n", ! err ? "" : ": not supported");
+  return err;
+}
+
+static const char *
+le16_to_char (char *dest, const grub_uint16_t * src16, unsigned bytes)
+{
+  grub_uint16_t * dest16 = (grub_uint16_t *) dest;
+  unsigned i;
+  for (i = 0; i < bytes / 2; i++)
+    dest16[i] = grub_be_to_cpu16 (src16[i]);
+  return dest;
+}
+
+static void
+grub_hdparm_print_identify (const char * idbuf)
+{
+  const grub_uint16_t * idw = (const grub_uint16_t *) idbuf;
+
+  /* Print identity strings.  */
+  char tmp[40];
+  grub_printf ("Model:    \"%.40s\"\n", le16_to_char (tmp, &idw[27], 40));
+  grub_printf ("Firmware: \"%.8s\"\n",  le16_to_char (tmp, &idw[23], 8));
+  grub_printf ("Serial:   \"%.20s\"\n", le16_to_char (tmp, &idw[10], 20));
+
+  /* Print AAM, APM and SMART settings.  */
+  grub_uint16_t features1 = grub_le_to_cpu16 (idw[82]);
+  grub_uint16_t features2 = grub_le_to_cpu16 (idw[83]);
+  grub_uint16_t enabled1  = grub_le_to_cpu16 (idw[85]);
+  grub_uint16_t enabled2  = grub_le_to_cpu16 (idw[86]);
+
+  grub_printf ("Automatic Acoustic Management: ");
+  if (features2 & 0x0200)
+    {
+      if (enabled2 & 0x0200)
+       {
+         grub_uint16_t aam = grub_le_to_cpu16 (idw[94]);
+         grub_printf ("%u (128=quiet, ..., 254=fast, recommended=%u)\n",
+                      aam & 0xff, (aam >> 8) & 0xff);
+       }
+      else
+       grub_printf ("disabled\n");
+    }
+  else
+    grub_printf ("not supported\n");
+
+  grub_printf ("Advanced Power Management: ");
+  if (features2 & 0x0008)
+    {
+      if (enabled2 & 0x0008)
+       grub_printf ("%u (1=low, ..., 254=high)\n",
+                    grub_le_to_cpu16 (idw[91]) & 0xff);
+      else
+       grub_printf ("disabled\n");
+    }
+  else
+    grub_printf ("not supported\n");
+
+  grub_printf ("SMART Feature Set: ");
+  if (features1 & 0x0001)
+    grub_printf ("%sabled\n", (enabled1 & 0x0001 ? "en" : "dis"));
+  else
+    grub_printf ("not supported\n");
+
+  /* Print security settings.  */
+  grub_uint16_t security = grub_le_to_cpu16 (idw[128]);
+
+  grub_printf ("ATA Security: ");
+  if (security & 0x0001)
+    grub_printf ("%s, %s, %s, %s\n",
+                (security & 0x0002 ? "ENABLED" : "disabled"),
+                (security & 0x0004 ? "**LOCKED**"  : "not locked"),
+                (security & 0x0008 ? "frozen" : "NOT FROZEN"),
+                (security & 0x0010 ? "COUNT EXPIRED" : "count not expired"));
+  else
+    grub_printf ("not supported\n");
+}
+
+static void
+grub_hdparm_print_standby_tout (int timeout)
+{
+  if (timeout == 0)
+    grub_printf ("off");
+  else if (timeout <= 252 || timeout == 255)
+    {
+      int h = 0, m = 0 , s = 0;
+      if (timeout == 255)
+       {
+         m = 21;
+         s = 15;
+       }
+      else if (timeout == 252)
+       m = 21;
+      else if (timeout <= 240)
+       {
+         s = timeout * 5;
+         m = s / 60;
+         s %= 60;
+       }
+      else
+       {
+         m = (timeout - 240) * 30;
+         h  = m / 60;
+         m %= 60;
+       }
+      grub_printf ("%02d:%02d:%02d", h, m, s);
+    }
+  else
+    grub_printf ("invalid or vendor-specific");
+}
+
+static int get_int_arg (const struct grub_arg_list *state)
+{
+  return (state->set ? (int)grub_strtoul (state->arg, 0, 0) : -1);
+}
+
+static grub_err_t
+grub_cmd_hdparm (grub_extcmd_t cmd, int argc, char **args) // state????
+{
+  struct grub_arg_list *state = cmd->state;
+
+  /* Check command line.  */
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing device name argument");
+
+  grub_size_t len = grub_strlen (args[0]);
+  if (! (args[0][0] == '(' && args[0][len - 1] == ')'))
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "argument is not a device name");
+  args[0][len - 1] = 0;
+
+  if (! grub_disk_ata_pass_through)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "ATA pass through not available");
+
+  int i = 0;
+  int apm          = get_int_arg (&state[i++]);
+  int power        = state[i++].set;
+  int sec_freeze   = state[i++].set;
+  int health       = state[i++].set;
+  int aam          = get_int_arg (&state[i++]);
+  int standby_tout = get_int_arg (&state[i++]);
+  int standby_now  = state[i++].set;
+  int sleep_now    = state[i++].set;
+  int ident        = state[i++].set;
+  int dumpid       = state[i++].set;
+  int enable_smart = get_int_arg (&state[i++]);
+  quiet            = state[i++].set;
+
+  /* Open disk.  */
+  grub_disk_t disk = grub_disk_open (&args[0][1]);
+  if (! disk)
+    return grub_errno;
+
+  if (disk->partition)
+    {
+      grub_disk_close (disk);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "partition not allowed");
+    }
+
+  /* Change settings.  */
+  if (aam >= 0)
+    grub_hdparm_set_val_cmd ("Automatic Acoustic Management", (aam ? aam : -1),
+      disk, GRUB_ATA_CMD_SET_FEATURES, (aam ? 0x42 : 0xc2), aam);
+
+  if (apm >= 0)
+    grub_hdparm_set_val_cmd ("Advanced Power Management",
+      (apm != 255 ? apm : -1), disk, GRUB_ATA_CMD_SET_FEATURES,
+      (apm != 255 ? 0x05 : 0x85), (apm != 255 ? apm : 0));
+
+  if (standby_tout >= 0)
+    {
+      if (! quiet)
+       {
+         grub_printf ("Set standby timeout to %d (", standby_tout);
+         grub_hdparm_print_standby_tout (standby_tout);
+         grub_printf (")");
+       }
+      /* The IDLE cmd sets disk to idle mode and configures standby timer.  */
+      grub_hdparm_set_val_cmd ("", -1, disk, GRUB_ATA_CMD_IDLE, 0, standby_tout);
+    }
+
+  if (enable_smart >= 0)
+    {
+      if (! quiet)
+       grub_printf ("%sable SMART operations", (enable_smart ? "En" : "Dis"));
+      int err = grub_hdparm_do_smart_cmd (disk, (enable_smart ?
+                 GRUB_ATA_FEAT_SMART_ENABLE : GRUB_ATA_FEAT_SMART_DISABLE));
+      if (! quiet)
+       grub_printf ("%s\n", err ? ": not supported" : "");
+    }
+
+  if (sec_freeze)
+    grub_hdparm_simple_cmd ("Freeze security settings", disk,
+                            GRUB_ATA_CMD_SECURITY_FREEZE_LOCK);
+
+  /* Print/dump IDENTIFY.  */
+  if (ident || dumpid)
+    {
+      char buf[GRUB_DISK_SECTOR_SIZE];
+      if (grub_hdparm_do_ata_cmd (disk, GRUB_ATA_CMD_IDENTIFY_DEVICE,
+          0, 0, buf, sizeof (buf)))
+       grub_printf ("Cannot read ATA IDENTIFY data\n");
+      else
+       {
+         if (ident)
+           grub_hdparm_print_identify (buf);
+         if (dumpid)
+           hexdump (0, buf, sizeof (buf));
+       }
+    }
+
+  /* Check power mode.  */
+  if (power)
+    {
+      grub_printf ("Disk power mode is: ");
+      int mode = grub_hdparm_do_check_powermode_cmd (disk);
+      if (mode < 0)
+        grub_printf ("unknown\n");
+      else
+       grub_printf ("%s (0x%02x)\n",
+                    (mode == 0xff ? "active/idle" :
+                     mode == 0x80 ? "idle" :
+                     mode == 0x00 ? "standby" : "unknown"), mode);
+    }
+
+  /* Check health.  */
+  int status = 0;
+  if (health)
+    {
+      if (! quiet)
+       grub_printf ("SMART status is: ");
+      int err = grub_hdparm_do_smart_cmd (disk, GRUB_ATA_FEAT_SMART_STATUS);
+      if (! quiet)
+       grub_printf ("%s\n", (err  < 0 ? "unknown" :
+                             err == 0 ? "OK" : "*BAD*"));
+      status = (err > 0);
+    }
+
+  /* Change power mode.  */
+  if (standby_now)
+    grub_hdparm_simple_cmd ("Set disk to standby mode", disk,
+                           GRUB_ATA_CMD_STANDBY_IMMEDIATE);
+
+  if (sleep_now)
+    grub_hdparm_simple_cmd ("Set disk to sleep mode", disk,
+                           GRUB_ATA_CMD_SLEEP);
+
+  grub_disk_close (disk);
+
+  grub_errno = GRUB_ERR_NONE;
+  return status;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(hdparm)
+{
+  cmd = grub_register_extcmd ("hdparm", grub_cmd_hdparm,
+                             GRUB_COMMAND_FLAG_BOTH,
+                             N_("[OPTIONS] DISK"),
+                             N_("Get/set ATA disk parameters."), options);
+}
+
+GRUB_MOD_FINI(hdparm)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/help.c b/grub-core/commands/help.c
new file mode 100644 (file)
index 0000000..c2aad03
--- /dev/null
@@ -0,0 +1,143 @@
+/* help.c - command to show a help text.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+#include <grub/mm.h>
+#include <grub/normal.h>
+#include <grub/charset.h>
+
+static grub_err_t
+grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
+              char **args)
+{
+  int cnt = 0;
+  char *currarg;
+
+  auto int print_command_info (grub_command_t cmd);
+  auto int print_command_help (grub_command_t cmd);
+
+  int print_command_info (grub_command_t cmd)
+    {
+      if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) &&
+         (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE))
+       {
+         struct grub_term_output *term;
+         const char *summary_translated = _(cmd->summary);
+         char *command_help;
+         grub_uint32_t *unicode_command_help;
+         grub_uint32_t *unicode_last_position;
+                                     
+         command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated);
+         if (!command_help)
+           return 1;
+
+         grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help,
+                                  &unicode_last_position);
+
+         FOR_ACTIVE_TERM_OUTPUTS(term)
+         {
+           unsigned stringwidth;
+           grub_uint32_t *unicode_last_screen_position;
+
+           unicode_last_screen_position = unicode_command_help;
+
+           stringwidth = 0;
+
+           while (unicode_last_screen_position < unicode_last_position && 
+                  stringwidth < ((grub_term_width (term) / 2) - 2))
+             {
+               stringwidth
+                 += grub_term_getcharwidth (term,
+                                            *unicode_last_screen_position);
+               unicode_last_screen_position++;
+             }
+
+           grub_print_ucs4 (unicode_command_help,
+                            unicode_last_screen_position, term);
+           if (!(cnt % 2))
+             grub_print_spaces (term, grub_term_width (term) / 2
+                                - stringwidth);
+         }
+         if (cnt % 2)
+           grub_printf ("\n");
+         cnt++;
+         
+         grub_free (command_help);
+         grub_free (unicode_command_help);
+       }
+      return 0;
+    }
+
+  int print_command_help (grub_command_t cmd)
+    {
+      if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE)
+       {
+         if (! grub_strncmp (cmd->name, currarg, grub_strlen (currarg)))
+           {
+             if (cnt++ > 0)
+               grub_printf ("\n\n");
+
+             if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD)
+               grub_arg_show_help ((grub_extcmd_t) cmd->data);
+             else
+               grub_printf ("%s %s %s\n%s\n", _("Usage:"), cmd->name, _(cmd->summary),
+                            _(cmd->description));
+           }
+       }
+      return 0;
+    }
+
+  if (argc == 0)
+    {
+      grub_command_iterate (print_command_info);
+      if (!(cnt % 2))
+       grub_printf ("\n");
+    }
+  else
+    {
+      int i;
+
+      for (i = 0; i < argc; i++)
+       {
+         currarg = args[i];
+         grub_command_iterate (print_command_help);
+       }
+    }
+
+  return 0;
+}
+
+static grub_extcmd_t cmd;
+\f
+GRUB_MOD_INIT(help)
+{
+  cmd = grub_register_extcmd ("help", grub_cmd_help,
+                             GRUB_COMMAND_FLAG_CMDLINE,
+                             N_("[PATTERN ...]"),
+                             N_("Show a help message."), 0);
+}
+
+GRUB_MOD_FINI(help)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/hexdump.c b/grub-core/commands/hexdump.c
new file mode 100644 (file)
index 0000000..c1d4ecb
--- /dev/null
@@ -0,0 +1,133 @@
+/* hexdump.c - command to dump the contents of a file or memory */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/gzio.h>
+#include <grub/lib/hexdump.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+
+static const struct grub_arg_option options[] = {
+  {"skip", 's', 0, N_("Skip offset bytes from the beginning of file."), 0,
+   ARG_TYPE_INT},
+  {"length", 'n', 0, N_("Read only LENGTH bytes."), 0, ARG_TYPE_INT},
+  {0, 0, 0, 0, 0, 0}
+};
+
+static grub_err_t
+grub_cmd_hexdump (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  char buf[GRUB_DISK_SECTOR_SIZE * 4];
+  grub_ssize_t size, length;
+  grub_disk_addr_t skip;
+  int namelen;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  namelen = grub_strlen (args[0]);
+  skip = (state[0].set) ? grub_strtoull (state[0].arg, 0, 0) : 0;
+  length = (state[1].set) ? grub_strtoul (state[1].arg, 0, 0) : 256;
+
+  if (!grub_strcmp (args[0], "(mem)"))
+    hexdump (skip, (char *) (grub_addr_t) skip, length);
+  else if ((args[0][0] == '(') && (args[0][namelen - 1] == ')'))
+    {
+      grub_disk_t disk;
+      grub_disk_addr_t sector;
+      grub_size_t ofs;
+
+      args[0][namelen - 1] = 0;
+      disk = grub_disk_open (&args[0][1]);
+      if (! disk)
+        return 0;
+
+      sector = (skip >> (GRUB_DISK_SECTOR_BITS + 2)) * 4;
+      ofs = skip & (GRUB_DISK_SECTOR_SIZE * 4 - 1);
+      while (length)
+        {
+          grub_size_t len;
+
+          len = length;
+          if (len > sizeof (buf))
+            len = sizeof (buf);
+
+          if (grub_disk_read (disk, sector, ofs, len, buf))
+            break;
+
+          hexdump (skip, buf, len);
+
+          ofs = 0;
+          skip += len;
+          length -= len;
+          sector += 4;
+        }
+
+      grub_disk_close (disk);
+    }
+  else
+    {
+      grub_file_t file;
+
+      file = grub_gzfile_open (args[0], 1);
+      if (! file)
+       return 0;
+
+      file->offset = skip;
+
+      while ((size = grub_file_read (file, buf, sizeof (buf))) > 0)
+       {
+         unsigned long len;
+
+         len = ((length) && (size > length)) ? length : size;
+         hexdump (skip, buf, len);
+         skip += len;
+         if (length)
+           {
+             length -= len;
+             if (!length)
+               break;
+           }
+       }
+
+      grub_file_close (file);
+    }
+
+  return 0;
+}
+\f
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT (hexdump)
+{
+  cmd = grub_register_extcmd ("hexdump", grub_cmd_hexdump,
+                             GRUB_COMMAND_FLAG_BOTH,
+                             N_("[OPTIONS] FILE_OR_DEVICE"),
+                             N_("Dump the contents of a file or memory."),
+                             options);
+}
+
+GRUB_MOD_FINI (hexdump)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/i386/cpuid.c b/grub-core/commands/i386/cpuid.c
new file mode 100644 (file)
index 0000000..6eebf91
--- /dev/null
@@ -0,0 +1,98 @@
+/* cpuid.c - test for CPU features */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006, 2007, 2009  Free Software Foundation, Inc.
+ *  Based on gcc/gcc/config/i386/driver-i386.c
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/command.h>
+#include <grub/extcmd.h>
+#include <grub/i386/cpuid.h>
+#include <grub/i18n.h>
+
+#define cpuid(num,a,b,c,d) \
+  asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
+               : "=a" (a), "=r" (b), "=c" (c), "=d" (d)  \
+               : "0" (num))
+
+static const struct grub_arg_option options[] =
+  {
+    {"long-mode", 'l', 0, N_("Check for long mode flag (default)."), 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+#define bit_LM (1 << 29)
+
+unsigned char grub_cpuid_has_longmode = 0;
+
+static grub_err_t
+grub_cmd_cpuid (grub_extcmd_t cmd __attribute__ ((unused)),
+               int argc __attribute__ ((unused)),
+               char **args __attribute__ ((unused)))
+{
+  return grub_cpuid_has_longmode ? GRUB_ERR_NONE
+    : grub_error (GRUB_ERR_TEST_FAILURE, "false");
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(cpuid)
+{
+#ifdef __x86_64__
+  /* grub-emu */
+  grub_cpuid_has_longmode = 1;
+#else
+  unsigned int eax, ebx, ecx, edx;
+  unsigned int max_level;
+  unsigned int ext_level;
+
+  /* See if we can use cpuid.  */
+  asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
+               "pushl %0; popfl; pushfl; popl %0; popfl"
+               : "=&r" (eax), "=&r" (ebx)
+               : "i" (0x00200000));
+  if (((eax ^ ebx) & 0x00200000) == 0)
+    goto done;
+
+  /* Check the highest input value for eax.  */
+  cpuid (0, eax, ebx, ecx, edx);
+  /* We only look at the first four characters.  */
+  max_level = eax;
+  if (max_level == 0)
+    goto done;
+
+  cpuid (0x80000000, eax, ebx, ecx, edx);
+  ext_level = eax;
+  if (ext_level < 0x80000000)
+    goto done;
+
+  cpuid (0x80000001, eax, ebx, ecx, edx);
+  grub_cpuid_has_longmode = !!(edx & bit_LM);
+done:
+#endif
+
+  cmd = grub_register_extcmd ("cpuid", grub_cmd_cpuid, GRUB_COMMAND_FLAG_BOTH,
+                             "[-l]", N_("Check for CPU features."), options);
+}
+
+GRUB_MOD_FINI(cpuid)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/i386/pc/acpi.c b/grub-core/commands/i386/pc/acpi.c
new file mode 100644 (file)
index 0000000..88e4f55
--- /dev/null
@@ -0,0 +1,81 @@
+/* acpi.c - get acpi tables. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/acpi.h>
+#include <grub/misc.h>
+
+struct grub_acpi_rsdp_v10 *
+grub_machine_acpi_get_rsdpv1 (void)
+{
+  int ebda_len;
+  grub_uint8_t *ebda, *ptr;
+
+  grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
+  ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
+  ebda_len = * (grub_uint16_t *) ebda;
+  if (! ebda_len)
+    return 0;
+  for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
+    if (grub_memcmp (ptr, "RSD PTR ", 8) == 0
+       && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
+       && ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
+      return (struct grub_acpi_rsdp_v10 *) ptr;
+
+  grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
+  for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
+       ptr += 16)
+    if (grub_memcmp (ptr, "RSD PTR ", 8) == 0
+       && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
+       && ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
+      return (struct grub_acpi_rsdp_v10 *) ptr;
+  return 0;
+}
+
+struct grub_acpi_rsdp_v20 *
+grub_machine_acpi_get_rsdpv2 (void)
+{
+  int ebda_len;
+  grub_uint8_t *ebda, *ptr;
+
+  grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
+  ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
+  ebda_len = * (grub_uint16_t *) ebda;
+  if (! ebda_len)
+    return 0;
+  for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
+    if (grub_memcmp (ptr, "RSD PTR ", 8) == 0
+       && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
+       && ((struct grub_acpi_rsdp_v10 *) ptr)->revision != 0
+       && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024
+       && grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length)
+       == 0)
+      return (struct grub_acpi_rsdp_v20 *) ptr;
+
+  grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
+  for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
+       ptr += 16)
+    if (grub_memcmp (ptr, "RSD PTR ", 8) == 0
+       && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
+       && ((struct grub_acpi_rsdp_v10 *) ptr)->revision != 0
+       && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024
+       && grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length)
+       == 0)
+      return (struct grub_acpi_rsdp_v20 *) ptr;
+  return 0;
+}
diff --git a/grub-core/commands/i386/pc/drivemap.c b/grub-core/commands/i386/pc/drivemap.c
new file mode 100644 (file)
index 0000000..4afc433
--- /dev/null
@@ -0,0 +1,421 @@
+/* drivemap.c - command to manage the BIOS drive mappings.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/extcmd.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/loader.h>
+#include <grub/env.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/biosnum.h>
+#include <grub/i18n.h>
+
+
+/* Real mode IVT slot (seg:off far pointer) for interrupt 0x13.  */
+static grub_uint32_t *const int13slot = UINT_TO_PTR (4 * 0x13);
+
+/* Remember to update enum opt_idxs accordingly.  */
+static const struct grub_arg_option options[] = {
+  {"list", 'l', 0, N_("Show the current mappings."), 0, 0},
+  {"reset", 'r', 0, N_("Reset all mappings to the default values."), 0, 0},
+  {"swap", 's', 0, N_("Perform both direct and reverse mappings."), 0, 0},
+  {0, 0, 0, 0, 0, 0}
+};
+
+/* Remember to update options[] accordingly.  */
+enum opt_idxs
+{
+  OPTIDX_LIST = 0,
+  OPTIDX_RESET,
+  OPTIDX_SWAP,
+};
+
+/* Realmode far ptr (2 * 16b) to the previous INT13h handler.  */
+extern grub_uint32_t grub_drivemap_oldhandler;
+
+/* The type "void" is used for imported assembly labels, takes no storage and
+   serves just to take the address with &label.  */
+
+/* The assembly function to replace the old INT13h handler. It does not follow
+   any C callspecs and returns with IRET.  */
+extern const void grub_drivemap_handler;
+
+/* Start of the drive mappings area (space reserved at runtime).  */
+extern const void grub_drivemap_mapstart;
+
+typedef struct drivemap_node
+{
+  struct drivemap_node *next;
+  grub_uint8_t newdrive;
+  grub_uint8_t redirto;
+} drivemap_node_t;
+
+typedef struct __attribute__ ((packed)) int13map_node
+{
+  grub_uint8_t disknum;
+  grub_uint8_t mapto;
+} int13map_node_t;
+
+#define INT13H_OFFSET(x) \
+       (((grub_uint8_t *)(x)) - ((grub_uint8_t *)&grub_drivemap_handler))
+
+static drivemap_node_t *map_head;
+static void *drivemap_hook;
+static int drivemap_mmap;
+
+/* Puts the specified mapping into the table, replacing an existing mapping
+   for newdrive or adding a new one if required.  */
+static grub_err_t
+drivemap_set (grub_uint8_t newdrive, grub_uint8_t redirto)
+{
+  drivemap_node_t *mapping = 0;
+  drivemap_node_t *search = map_head;
+  while (search)
+    {
+      if (search->newdrive == newdrive)
+       {
+         mapping = search;
+         break;
+       }
+      search = search->next;
+    }
+
+  /* Check for pre-existing mappings to modify before creating a new one.  */
+  if (mapping)
+    mapping->redirto = redirto;
+  else
+    {
+      mapping = grub_malloc (sizeof (drivemap_node_t));
+      if (! mapping)
+       return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                          "cannot allocate map entry, not enough memory");
+      mapping->newdrive = newdrive;
+      mapping->redirto = redirto;
+      mapping->next = map_head;
+      map_head = mapping;
+    }
+  return GRUB_ERR_NONE;
+}
+
+/* Removes the mapping for newdrive from the table.  If there is no mapping,
+   then this function behaves like a no-op on the map.  */
+static void
+drivemap_remove (grub_uint8_t newdrive)
+{
+  drivemap_node_t *mapping = 0;
+  drivemap_node_t *search = map_head;
+  drivemap_node_t *previous = 0;
+
+  while (search)
+    {
+      if (search->newdrive == newdrive)
+       {
+         mapping = search;
+         break;
+       }
+      previous = search;
+      search = search->next;
+    }
+
+  if (mapping)
+    {
+      if (previous)
+       previous->next = mapping->next;
+      else
+       map_head = mapping->next;
+      grub_free (mapping);
+    }
+}
+
+/* Given a GRUB-like device name and a convenient location, stores the
+   related BIOS disk number.  Accepts devices like \((f|h)dN\), with
+   0 <= N < 128.  */
+static grub_err_t
+tryparse_diskstring (const char *str, grub_uint8_t *output)
+{
+  /* Skip opening paren in order to allow both (hd0) and hd0.  */
+  if (*str == '(')
+    str++;
+  if ((str[0] == 'f' || str[0] == 'h') && str[1] == 'd')
+    {
+      grub_uint8_t bios_num = (str[0] == 'h') ? 0x80 : 0x00;
+      unsigned long drivenum = grub_strtoul (str + 2, 0, 0);
+      if (grub_errno == GRUB_ERR_NONE && drivenum < 128)
+       {
+         bios_num |= drivenum;
+         if (output)
+           *output = bios_num;
+         return GRUB_ERR_NONE;
+       }
+    }
+  return grub_error (GRUB_ERR_BAD_ARGUMENT, "device format \"%s\" "
+                    "invalid: must be (f|h)dN, with 0 <= N < 128", str);
+}
+
+static grub_err_t
+list_mappings (void)
+{
+  /* Show: list mappings.  */
+  if (! map_head)
+    {
+      grub_printf ("No drives have been remapped\n");
+      return GRUB_ERR_NONE;
+    }
+
+  grub_printf ("OS disk #num ------> GRUB/BIOS device\n");
+  drivemap_node_t *curnode = map_head;
+  while (curnode)
+    {
+      grub_printf ("%cD #%-3u (0x%02x)       %cd%d\n",
+                  (curnode->newdrive & 0x80) ? 'H' : 'F',
+                  curnode->newdrive & 0x7F, curnode->newdrive,
+                  (curnode->redirto & 0x80) ? 'h' : 'f',
+                  curnode->redirto & 0x7F
+                  );
+      curnode = curnode->next;
+    }
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_drivemap (struct grub_extcmd *cmd, int argc, char **args)
+{
+  if (cmd->state[OPTIDX_LIST].set)
+    {
+      return list_mappings ();
+    }
+  else if (cmd->state[OPTIDX_RESET].set)
+    {
+      /* Reset: just delete all mappings, freeing their memory.  */
+      drivemap_node_t *curnode = map_head;
+      drivemap_node_t *prevnode = 0;
+      while (curnode)
+       {
+         prevnode = curnode;
+         curnode = curnode->next;
+         grub_free (prevnode);
+       }
+      map_head = 0;
+      return GRUB_ERR_NONE;
+    }
+  else if (!cmd->state[OPTIDX_SWAP].set && argc == 0)
+    {
+      /* No arguments */
+      return list_mappings ();
+    }
+
+  /* Neither flag: put mapping.  */
+  grub_uint8_t mapfrom = 0;
+  grub_uint8_t mapto = 0xFF;
+  grub_err_t err;
+
+  if (argc != 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required");
+
+  err = tryparse_diskstring (args[0], &mapfrom);
+  if (err != GRUB_ERR_NONE)
+    return err;
+
+  err = tryparse_diskstring (args[1], &mapto);
+  if (err != GRUB_ERR_NONE)
+    return err;
+
+  if (mapto == mapfrom)
+    {
+      /* Reset to default.  */
+      grub_dprintf ("drivemap", "Removing mapping for %s (%02x)\n",
+                   args[0], mapfrom);
+      drivemap_remove (mapfrom);
+      return GRUB_ERR_NONE;
+    }
+  /* Set the mapping for the disk (overwrites any existing mapping).  */
+  grub_dprintf ("drivemap", "%s %s (%02x) = %s (%02x)\n",
+               cmd->state[OPTIDX_SWAP].set ? "Swapping" : "Mapping",
+               args[1], mapto, args[0], mapfrom);
+  err = drivemap_set (mapto, mapfrom);
+  /* If -s, perform the reverse mapping too (only if the first was OK).  */
+  if (cmd->state[OPTIDX_SWAP].set && err == GRUB_ERR_NONE)
+    err = drivemap_set (mapfrom, mapto);
+  return err;
+}
+
+/* Int13h handler installer - reserves conventional memory for the handler,
+   copies it over and sets the IVT entry for int13h.
+   This code rests on the assumption that GRUB does not activate any kind
+   of memory mapping apart from identity paging, since it accesses
+   realmode structures by their absolute addresses, like the IVT at 0;
+   and transforms a pmode pointer into a rmode seg:off far ptr.  */
+static grub_err_t
+install_int13_handler (int noret __attribute__ ((unused)))
+{
+  /* Size of the full int13 handler "bundle", including code and map.  */
+  grub_uint32_t total_size;
+  /* Base address of the space reserved for the handler bundle.  */
+  grub_uint8_t *handler_base = 0;
+  /* Address of the map within the deployed bundle.  */
+  int13map_node_t *handler_map;
+
+  int i;
+  int entries = 0;
+  drivemap_node_t *curentry = map_head;
+
+  /* Count entries to prepare a contiguous map block.  */
+  while (curentry)
+    {
+      entries++;
+      curentry = curentry->next;
+    }
+  if (entries == 0)
+    {
+      /* No need to install the int13h handler.  */
+      grub_dprintf ("drivemap", "No drives marked as remapped, not installing "
+                   "our int13h handler.\n");
+      return GRUB_ERR_NONE;
+    }
+
+  grub_dprintf ("drivemap", "Installing our int13h handler\n");
+
+  /* Save the pointer to the old handler.  */
+  grub_drivemap_oldhandler = *int13slot;
+  grub_dprintf ("drivemap", "Original int13 handler: %04x:%04x\n",
+               (grub_drivemap_oldhandler >> 16) & 0x0ffff,
+               grub_drivemap_oldhandler & 0x0ffff);
+
+  /* Find a rmode-segment-aligned zone in conventional memory big
+     enough to hold the handler and its data.  */
+  total_size = INT13H_OFFSET (&grub_drivemap_mapstart)
+    + (entries + 1) * sizeof (int13map_node_t);
+  grub_dprintf ("drivemap", "Payload is %u bytes long\n", total_size);
+  handler_base = grub_mmap_malign_and_register (16, total_size,
+                                               &drivemap_mmap,
+                                               GRUB_MACHINE_MEMORY_RESERVED,
+                                               GRUB_MMAP_MALLOC_LOW);
+  if (! handler_base)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't reserve "
+                      "memory for the int13h handler");
+
+  /* Copy int13h handler bundle to reserved area.  */
+  grub_dprintf ("drivemap", "Reserved memory at %p, copying handler\n",
+               handler_base);
+  grub_memcpy (handler_base, &grub_drivemap_handler,
+              INT13H_OFFSET (&grub_drivemap_mapstart));
+
+  /* Copy the mappings to the reserved area.  */
+  curentry = map_head;
+  handler_map = (int13map_node_t *) (handler_base +
+                                    INT13H_OFFSET (&grub_drivemap_mapstart));
+  grub_dprintf ("drivemap", "Target map at %p, copying mappings\n", handler_map);
+  for (i = 0; i < entries; ++i, curentry = curentry->next)
+    {
+      handler_map[i].disknum = curentry->newdrive;
+      handler_map[i].mapto = curentry->redirto;
+      grub_dprintf ("drivemap", "\t#%d: 0x%02x <- 0x%02x\n", i,
+                   handler_map[i].disknum, handler_map[i].mapto);
+    }
+  /* Signal end-of-map.  */
+  handler_map[i].disknum = 0;
+  handler_map[i].mapto = 0;
+  grub_dprintf ("drivemap", "\t#%d: 0x00 <- 0x00 (end)\n", i);
+
+  /* Install our function as the int13h handler in the IVT.  */
+  *int13slot = ((grub_uint32_t) handler_base) << 12;   /* Segment address.  */
+  grub_dprintf ("drivemap", "New int13 handler: %04x:%04x\n",
+               (*int13slot >> 16) & 0x0ffff, *int13slot & 0x0ffff);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+uninstall_int13_handler (void)
+{
+  if (! grub_drivemap_oldhandler)
+    return GRUB_ERR_NONE;
+
+  *int13slot = grub_drivemap_oldhandler;
+  grub_mmap_free_and_unregister (drivemap_mmap);
+  grub_drivemap_oldhandler = 0;
+  grub_dprintf ("drivemap", "Restored int13 handler: %04x:%04x\n",
+               (*int13slot >> 16) & 0x0ffff, *int13slot & 0x0ffff);
+
+  return GRUB_ERR_NONE;
+}
+
+static int
+grub_get_root_biosnumber_drivemap (void)
+{
+  char *biosnum;
+  int ret = -1;
+  grub_device_t dev;
+
+  biosnum = grub_env_get ("biosnum");
+
+  if (biosnum)
+    return grub_strtoul (biosnum, 0, 0);
+
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->dev
+      && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID)
+    {
+      drivemap_node_t *curnode = map_head;
+      ret = (int) dev->disk->id;
+      while (curnode)
+       {
+         if (curnode->redirto == ret)
+           {
+             ret = curnode->newdrive;
+             break;
+           }
+         curnode = curnode->next;
+       }
+
+    }
+
+  if (dev)
+    grub_device_close (dev);
+
+  return ret;
+}
+
+static grub_extcmd_t cmd;
+static int (*grub_get_root_biosnumber_saved) (void);
+
+GRUB_MOD_INIT (drivemap)
+{
+  grub_get_root_biosnumber_saved = grub_get_root_biosnumber;
+  grub_get_root_biosnumber = grub_get_root_biosnumber_drivemap;
+  cmd = grub_register_extcmd ("drivemap", grub_cmd_drivemap,
+                             GRUB_COMMAND_FLAG_BOTH,
+                             N_("-l | -r | [-s] grubdev osdisk."),
+                             N_("Manage the BIOS drive mappings."),
+                             options);
+  drivemap_hook =
+    grub_loader_register_preboot_hook (&install_int13_handler,
+                                      &uninstall_int13_handler,
+                                      GRUB_LOADER_PREBOOT_HOOK_PRIO_NORMAL);
+}
+
+GRUB_MOD_FINI (drivemap)
+{
+  grub_get_root_biosnumber = grub_get_root_biosnumber_saved;
+  grub_loader_unregister_preboot_hook (drivemap_hook);
+  drivemap_hook = 0;
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/i386/pc/drivemap_int13h.S b/grub-core/commands/i386/pc/drivemap_int13h.S
new file mode 100644 (file)
index 0000000..b460cd7
--- /dev/null
@@ -0,0 +1,110 @@
+/* drivemap_int13h.S - interrupt handler for the BIOS drive remapper */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+#define INT13H_OFFSET(x) ((x) - LOCAL (base))
+
+.code16
+
+/* Copy starts here.  When deployed, this code must be segment-aligned.  */
+
+/* The replacement int13 handler.   Preserve all registers.  */
+FUNCTION(grub_drivemap_handler)
+LOCAL (base):
+       /* Save %dx for future restore. */
+       push    %dx
+       /* Push flags. Used to simulate interrupt with original flags. */
+       pushf
+
+       /* Map the drive number (always in DL).  */
+       push    %ax
+       push    %bx
+       movw    $INT13H_OFFSET(LOCAL (mapstart)), %bx
+
+more_remaining:
+       movw    %cs:(%bx), %ax
+       cmpb    %ah, %al
+       jz      not_found /* DRV=DST => map end - drive not remapped, keep DL.  */
+       inc     %bx
+       inc     %bx
+       cmpb    %dl, %al
+       jnz     more_remaining /* Not found, but more remaining, loop.  */
+       movb    %ah, %dl /* Found - drive remapped, modify DL.  */
+
+not_found:
+       pop     %bx
+       pop     %ax
+
+       /* If the call isn't ah=0x8 or ah=0x15 we must restore %dx.  */
+       cmpb    $0x8, %ah
+       jz      norestore
+       cmpb    $0x15, %ah
+       jz      norestore
+
+       /* Restore flags.  */
+       popf
+       pushf
+
+       lcall *%cs:INT13H_OFFSET (LOCAL (oldhandler))
+
+       push    %bp
+       mov     %sp, %bp
+
+tail:
+       /* Save new flags below %esp so the caller will recieve new flags.  */
+       pushf
+       pop     %dx
+       mov     %dx, 8(%bp)
+
+       pop     %bp
+
+       /* Restore %dx.  */
+       pop     %dx
+       iret
+
+norestore:
+
+       /* Restore flags.  */
+       popf
+       pushf
+
+       lcall *%cs:INT13H_OFFSET (LOCAL (oldhandler))
+
+       push    %bp
+       mov     %sp, %bp
+
+       /* Save %dx. So it won't be restored to original value.  */
+       mov     %dx, 2(%bp)
+
+       jmp tail
+
+/* Far pointer to the old handler.  Stored as a CS:IP in the style of real-mode
+   IVT entries (thus PI:SC in mem).  */
+VARIABLE(grub_drivemap_oldhandler)
+LOCAL (oldhandler):
+       .word 0x0, 0x0
+
+/* This label MUST be at the end of the copied block, since the installer code
+   reserves additional space for mappings at runtime and copies them over it.  */
+       .align 2
+       
+VARIABLE(grub_drivemap_mapstart)
+LOCAL (mapstart):
+       .byte 0
diff --git a/grub-core/commands/i386/pc/halt.c b/grub-core/commands/i386/pc/halt.c
new file mode 100644 (file)
index 0000000..4c39612
--- /dev/null
@@ -0,0 +1,58 @@
+/* halt.c - command to halt the computer.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {"no-apm", 'n', 0, N_("Do not use APM to halt the computer."), 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static grub_err_t
+grub_cmd_halt (grub_extcmd_t cmd,
+              int argc __attribute__ ((unused)),
+              char **args __attribute__ ((unused)))
+
+{
+  struct grub_arg_list *state = cmd->state;
+  int no_apm = 0;
+  if (state[0].set)
+    no_apm = 1;
+  grub_halt (no_apm);
+  return 0;
+}
+
+static grub_extcmd_t cmd;
+\f
+GRUB_MOD_INIT(halt)
+{
+  cmd = grub_register_extcmd ("halt", grub_cmd_halt, GRUB_COMMAND_FLAG_BOTH,
+                             "[-n]",
+                             N_("Halt the system, if possible using APM."),
+                             options);
+}
+
+GRUB_MOD_FINI(halt)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/i386/pc/play.c b/grub-core/commands/i386/pc/play.c
new file mode 100644 (file)
index 0000000..4ed937d
--- /dev/null
@@ -0,0 +1,273 @@
+/* play.c - command to play a tune  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Lots of this file is borrowed from GNU/Hurd generic-speaker driver.  */
+
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/machine/time.h>
+#include <grub/cpu/io.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+#define BASE_TEMPO (60 * GRUB_TICKS_PER_SECOND)
+
+/* The speaker port.  */
+#define SPEAKER                        0x61
+
+/* If 0, follow state of SPEAKER_DATA bit, otherwise enable output
+   from timer 2.  */
+#define SPEAKER_TMR2           0x01
+
+/* If SPEAKER_TMR2 is not set, this provides direct input into the
+   speaker.  Otherwise, this enables or disables the output from the
+   timer.  */
+#define SPEAKER_DATA           0x02
+
+/* The PIT channel value ports.  You can write to and read from them.
+   Do not mess with timer 0 or 1.  */
+#define PIT_COUNTER_0          0x40
+#define PIT_COUNTER_1          0x41
+#define PIT_COUNTER_2          0x42
+
+/* The frequency of the PIT clock.  */
+#define PIT_FREQUENCY          0x1234dd
+
+/* The PIT control port.  You can only write to it.  Do not mess with
+   timer 0 or 1.  */
+#define PIT_CTRL               0x43
+#define PIT_CTRL_SELECT_MASK   0xc0
+#define PIT_CTRL_SELECT_0      0x00
+#define PIT_CTRL_SELECT_1      0x40
+#define PIT_CTRL_SELECT_2      0x80
+
+/* Read and load control.  */
+#define PIT_CTRL_READLOAD_MASK 0x30
+#define PIT_CTRL_COUNTER_LATCH 0x00    /* Hold timer value until read.  */
+#define PIT_CTRL_READLOAD_LSB  0x10    /* Read/load the LSB.  */
+#define PIT_CTRL_READLOAD_MSB  0x20    /* Read/load the MSB.  */
+#define PIT_CTRL_READLOAD_WORD 0x30    /* Read/load the LSB then the MSB.  */
+
+/* Mode control.  */
+#define PIT_CTRL_MODE_MASK     0x0e
+
+/* Interrupt on terminal count.  Setting the mode sets output to low.
+   When counter is set and terminated, output is set to high.  */
+#define PIT_CTRL_INTR_ON_TERM  0x00
+
+/* Programmable one-shot.  When loading counter, output is set to
+   high.  When counter terminated, output is set to low.  Can be
+   triggered again from that point on by setting the gate pin to
+   high.  */
+#define PIT_CTRL_PROGR_ONE_SHOT        0x02
+
+/* Rate generator.  Output is low for one period of the counter, and
+   high for the other.  */
+#define PIT_CTRL_RATE_GEN      0x04
+
+/* Square wave generator.  Output is low for one half of the period,
+   and high for the other half.  */
+#define PIT_CTRL_SQUAREWAVE_GEN        0x06
+
+/* Software triggered strobe.  Setting the mode sets output to high.
+   When counter is set and terminated, output is set to low.  */
+#define PIT_CTRL_SOFTSTROBE    0x08
+
+/* Hardware triggered strobe.  Like software triggered strobe, but
+   only starts the counter when the gate pin is set to high.  */
+#define PIT_CTRL_HARDSTROBE    0x0a
+
+/* Count mode.  */
+#define PIT_CTRL_COUNT_MASK    0x01
+#define PIT_CTRL_COUNT_BINARY  0x00    /* 16-bit binary counter.  */
+#define PIT_CTRL_COUNT_BCD     0x01    /* 4-decade BCD counter.  */
+
+#define T_REST                 ((grub_uint16_t) 0)
+#define T_FINE                 ((grub_uint16_t) -1)
+
+struct note
+{
+  grub_uint16_t pitch;
+  grub_uint16_t duration;
+};
+
+static void
+beep_off (void)
+{
+  unsigned char status;
+
+  status = grub_inb (SPEAKER);
+  grub_outb (status & ~(SPEAKER_TMR2 | SPEAKER_DATA), SPEAKER);
+}
+
+static void
+beep_on (grub_uint16_t pitch)
+{
+  unsigned char status;
+  unsigned int counter;
+
+  if (pitch < 20)
+    pitch = 20;
+  else if (pitch > 20000)
+    pitch = 20000;
+
+  counter = PIT_FREQUENCY / pitch;
+
+  /* Program timer 2.  */
+  grub_outb (PIT_CTRL_SELECT_2 | PIT_CTRL_READLOAD_WORD
+       | PIT_CTRL_SQUAREWAVE_GEN | PIT_CTRL_COUNT_BINARY, PIT_CTRL);
+  grub_outb (counter & 0xff, PIT_COUNTER_2);           /* LSB */
+  grub_outb ((counter >> 8) & 0xff, PIT_COUNTER_2);    /* MSB */
+
+  /* Start speaker.  */
+  status = grub_inb (SPEAKER);
+  grub_outb (status | SPEAKER_TMR2 | SPEAKER_DATA, SPEAKER);
+}
+
+/* Returns whether playing should continue.  */
+static int
+play (unsigned tempo, struct note *note)
+{
+  unsigned int to;
+
+  if (note->pitch == T_FINE || grub_checkkey () >= 0)
+    return 1;
+
+  grub_dprintf ("play", "pitch = %d, duration = %d\n", note->pitch,
+                note->duration);
+
+  switch (note->pitch)
+    {
+      case T_REST:
+        beep_off ();
+        break;
+
+      default:
+        beep_on (note->pitch);
+        break;
+    }
+
+  to = grub_get_rtc () + BASE_TEMPO * note->duration / tempo;
+  while (((unsigned int) grub_get_rtc () <= to) && (grub_checkkey () < 0))
+    ;
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_play (grub_command_t cmd __attribute__ ((unused)),
+              int argc, char **args)
+{
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name or tempo and notes required");
+
+  if (argc == 1)
+    {
+      struct note buf;
+      grub_uint32_t tempo;
+      grub_file_t file;
+
+      file = grub_file_open (args[0]);
+
+      if (! file)
+        return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+
+      if (grub_file_read (file, &tempo, sizeof (tempo)) != sizeof (tempo))
+        {
+          grub_file_close (file);
+          return grub_error (GRUB_ERR_FILE_READ_ERROR,
+                             "file doesn't even contains a full tempo record");
+        }
+
+      tempo = grub_le_to_cpu32 (tempo);
+      grub_dprintf ("play","tempo = %d\n", tempo);
+
+      while (grub_file_read (file, &buf,
+                             sizeof (struct note)) == sizeof (struct note))
+        {
+          buf.pitch = grub_le_to_cpu16 (buf.pitch);
+          buf.duration = grub_le_to_cpu16 (buf.duration);
+
+          if (play (tempo, &buf))
+            break;
+        }
+
+      grub_file_close (file);
+    }
+  else
+    {
+      char *end;
+      unsigned tempo;
+      struct note note;
+      int i;
+
+      tempo = grub_strtoul (args[0], &end, 0);
+
+      if (*end)
+        /* Was not a number either, assume it was supposed to be a file name.  */
+        return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+
+      grub_dprintf ("play","tempo = %d\n", tempo);
+
+      for (i = 1; i + 1 < argc; i += 2)
+        {
+          note.pitch = grub_strtoul (args[i], &end, 0);
+          if (*end)
+            {
+              grub_error (GRUB_ERR_BAD_NUMBER, "bogus pitch number");
+              break;
+            }
+
+          note.duration = grub_strtoul (args[i + 1], &end, 0);
+          if (*end)
+            {
+              grub_error (GRUB_ERR_BAD_NUMBER, "bogus duration number");
+              break;
+            }
+
+          if (play (tempo, &note))
+            break;
+        }
+    }
+
+  beep_off ();
+
+  while (grub_checkkey () > 0)
+    grub_getkey ();
+
+  return 0;
+}
+
+static grub_command_t cmd;
+\f
+GRUB_MOD_INIT(play)
+{
+  cmd = grub_register_command ("play", grub_cmd_play,
+                              N_("FILE | TEMPO [PITCH1 DURATION1] [PITCH2 DURATION2] ... "),
+                              N_("Play a tune."));
+}
+
+GRUB_MOD_FINI(play)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/i386/pc/pxecmd.c b/grub-core/commands/i386/pc/pxecmd.c
new file mode 100644 (file)
index 0000000..b576a8e
--- /dev/null
@@ -0,0 +1,52 @@
+/* pxe.c - command to control the pxe driver  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/machine/pxe.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+grub_cmd_pxe_unload (grub_command_t cmd __attribute__ ((unused)),
+                    int argc __attribute__ ((unused)),
+                    char **args __attribute__ ((unused)))
+{
+  if (! grub_pxe_pxenv)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no pxe environment");
+
+  grub_pxe_unload ();
+
+  return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(pxecmd)
+{
+  cmd = grub_register_command ("pxe_unload", grub_cmd_pxe_unload,
+                              0,
+                              N_("Unload PXE environment."));
+}
+
+GRUB_MOD_FINI(pxecmd)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/i386/pc/vbeinfo.c b/grub-core/commands/i386/pc/vbeinfo.c
new file mode 100644 (file)
index 0000000..c266bbf
--- /dev/null
@@ -0,0 +1,185 @@
+/* vbeinfo.c - command to list compatible VBE video modes.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/machine/init.h>
+#include <grub/machine/vbe.h>
+#include <grub/mm.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static void *
+real2pm (grub_vbe_farptr_t ptr)
+{
+  return (void *) ((((unsigned long) ptr & 0xFFFF0000) >> 12UL)
+                  + ((unsigned long) ptr & 0x0000FFFF));
+}
+
+static grub_err_t
+grub_cmd_vbeinfo (grub_command_t cmd __attribute__ ((unused)),
+                 int argc __attribute__ ((unused)),
+                 char **args __attribute__ ((unused)))
+{
+  struct grub_vbe_info_block controller_info;
+  struct grub_vbe_mode_info_block mode_info_tmp;
+  grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE;
+  grub_uint16_t *video_mode_list;
+  grub_uint16_t *p;
+  grub_uint16_t *saved_video_mode_list;
+  grub_size_t video_mode_list_size;
+  grub_err_t err;
+  char *modevar;
+
+  err = grub_vbe_probe (&controller_info);
+  if (err != GRUB_ERR_NONE)
+    return err;
+
+  grub_printf ("VBE info:   version: %d.%d  OEM software rev: %d.%d\n",
+              controller_info.version >> 8,
+               controller_info.version & 0xFF,
+               controller_info.oem_software_rev >> 8,
+               controller_info.oem_software_rev & 0xFF);
+
+  /* The total_memory field is in 64 KiB units.  */
+  grub_printf ("            total memory: %d KiB\n",
+               (controller_info.total_memory << 16) / 1024);
+
+  /* Because the information on video modes is stored in a temporary place,
+     it is better to copy it to somewhere safe.  */
+  p = video_mode_list = real2pm (controller_info.video_mode_ptr);
+  while (*p++ != 0xFFFF)
+    ;
+
+  video_mode_list_size = (grub_addr_t) p - (grub_addr_t) video_mode_list;
+  saved_video_mode_list = grub_malloc (video_mode_list_size);
+  if (! saved_video_mode_list)
+    return grub_errno;
+
+  grub_memcpy (saved_video_mode_list, video_mode_list, video_mode_list_size);
+
+  grub_printf ("List of compatible video modes:\n");
+  grub_printf ("Legend: P=Packed pixel, D=Direct color, "
+              "mask/pos=R/G/B/reserved\n");
+
+  /* Walk through all video modes listed.  */
+  for (p = saved_video_mode_list; *p != 0xFFFF; p++)
+    {
+      const char *memory_model = 0;
+      grub_uint32_t mode = (grub_uint32_t) *p;
+
+      err = grub_vbe_get_video_mode_info (mode, &mode_info_tmp);
+      if (err != GRUB_ERR_NONE)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         continue;
+       }
+
+      if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_SUPPORTED) == 0)
+       /* If not available, skip it.  */
+       continue;
+
+      if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_RESERVED_1) == 0)
+       /* Not enough information.  */
+       continue;
+
+      if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_COLOR) == 0)
+       /* Monochrome is unusable.  */
+       continue;
+
+      if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_LFB_AVAIL) == 0)
+       /* We support only linear frame buffer modes.  */
+       continue;
+
+      if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_GRAPHICS) == 0)
+       /* We allow only graphical modes.  */
+       continue;
+
+      switch (mode_info_tmp.memory_model)
+       {
+       case GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL:
+         memory_model = "Packed";
+         break;
+       case GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR:
+         memory_model = "Direct";
+         break;
+
+       default:
+         break;
+       }
+
+      if (! memory_model)
+       continue;
+
+      grub_printf ("0x%03x:  %4d x %4d x %2d  %s",
+                   mode,
+                   mode_info_tmp.x_resolution,
+                   mode_info_tmp.y_resolution,
+                   mode_info_tmp.bits_per_pixel,
+                   memory_model);
+
+      /* Show mask and position details for direct color modes.  */
+      if (mode_info_tmp.memory_model == GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR)
+        grub_printf (", mask: %d/%d/%d/%d  pos: %d/%d/%d/%d",
+                     mode_info_tmp.red_mask_size,
+                     mode_info_tmp.green_mask_size,
+                     mode_info_tmp.blue_mask_size,
+                     mode_info_tmp.rsvd_mask_size,
+                     mode_info_tmp.red_field_position,
+                     mode_info_tmp.green_field_position,
+                     mode_info_tmp.blue_field_position,
+                     mode_info_tmp.rsvd_field_position);
+      grub_printf ("\n");
+    }
+
+  grub_free (saved_video_mode_list);
+
+  /* Check existence of vbe_mode environment variable.  */
+  modevar = grub_env_get ("vbe_mode");
+
+  if (modevar != 0)
+    {
+      unsigned long value;
+
+      value = grub_strtoul (modevar, 0, 0);
+      if (grub_errno == GRUB_ERR_NONE)
+       use_mode = value;
+      else
+       grub_errno = GRUB_ERR_NONE;
+    }
+
+  grub_printf ("Configured VBE mode (vbe_mode) = 0x%03x\n", use_mode);
+
+  return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(vbeinfo)
+{
+  cmd =
+    grub_register_command ("vbeinfo", grub_cmd_vbeinfo, 0,
+                          N_("List compatible VESA BIOS extension video modes."));
+}
+
+GRUB_MOD_FINI(vbeinfo)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/i386/pc/vbetest.c b/grub-core/commands/i386/pc/vbetest.c
new file mode 100644 (file)
index 0000000..d2921c0
--- /dev/null
@@ -0,0 +1,179 @@
+/* vbetest.c - command to test VESA BIOS Extension 2.0+ support.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/machine/init.h>
+#include <grub/machine/vbe.h>
+#include <grub/video.h>
+#include <grub/err.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+grub_cmd_vbetest (grub_command_t cmd __attribute__ ((unused)),
+                 int argc __attribute__ ((unused)),
+                 char **args __attribute__ ((unused)))
+{
+  grub_err_t err;
+  char *modevar;
+  struct grub_vbe_mode_info_block mode_info;
+  struct grub_vbe_info_block controller_info;
+  grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE;
+  grub_uint32_t old_mode;
+  grub_uint8_t *framebuffer = 0;
+  grub_uint32_t bytes_per_scan_line = 0;
+  unsigned char *ptr;
+  int i;
+
+  grub_printf ("Probing for VESA BIOS Extension ... ");
+
+  /* Check if VESA BIOS exists.  */
+  err = grub_vbe_probe (&controller_info);
+  if (err != GRUB_ERR_NONE)
+    return err;
+
+  grub_printf ("found!\n");
+
+  /* Dump out controller information.  */
+  grub_printf ("VBE signature = %c%c%c%c\n",
+              controller_info.signature[0],
+              controller_info.signature[1],
+              controller_info.signature[2],
+              controller_info.signature[3]);
+
+  grub_printf ("VBE version = %d.%d\n",
+              controller_info.version >> 8,
+              controller_info.version & 0xFF);
+  grub_printf ("OEM string ptr = %08x\n",
+              controller_info.oem_string_ptr);
+  grub_printf ("Total memory = %d\n",
+              controller_info.total_memory);
+
+  err = grub_vbe_get_video_mode (&old_mode);
+  grub_printf ("Get video mode err = %04x\n", err);
+
+  if (err == GRUB_ERR_NONE)
+    grub_printf ("Old video mode = %04x\n", old_mode);
+  else
+    grub_errno = GRUB_ERR_NONE;
+
+  /* Check existence of vbe_mode environment variable.  */
+  modevar = grub_env_get ("vbe_mode");
+  if (modevar != 0)
+    {
+      unsigned long value;
+
+      value = grub_strtoul (modevar, 0, 0);
+      if (grub_errno == GRUB_ERR_NONE)
+       use_mode = value;
+      else
+       grub_errno = GRUB_ERR_NONE;
+    }
+
+  err = grub_vbe_get_video_mode_info (use_mode, &mode_info);
+  if (err != GRUB_ERR_NONE)
+    return err;
+
+  /* Dump out details about the mode being tested.  */
+  grub_printf ("mode: 0x%03x\n",
+               use_mode);
+  grub_printf ("width : %d\n",
+               mode_info.x_resolution);
+  grub_printf ("height: %d\n",
+               mode_info.y_resolution);
+  grub_printf ("memory model: %02x\n",
+               mode_info.memory_model);
+  grub_printf ("bytes/scanline: %d\n",
+               mode_info.bytes_per_scan_line);
+  grub_printf ("bytes/scanline (lin): %d\n",
+               mode_info.lin_bytes_per_scan_line);
+  grub_printf ("base address: %08x\n",
+               mode_info.phys_base_addr);
+  grub_printf ("red mask/pos: %d/%d\n",
+               mode_info.red_mask_size,
+               mode_info.red_field_position);
+  grub_printf ("green mask/pos: %d/%d\n",
+               mode_info.green_mask_size,
+               mode_info.green_field_position);
+  grub_printf ("blue mask/pos: %d/%d\n",
+               mode_info.blue_mask_size,
+               mode_info.blue_field_position);
+
+  grub_printf ("Press any key to continue.\n");
+
+  grub_getkey ();
+
+  /* Setup GFX mode.  */
+  err = grub_vbe_set_video_mode (use_mode, &mode_info);
+  if (err != GRUB_ERR_NONE)
+    return err;
+
+  /* Determine framebuffer address and how many bytes are in scan line.  */
+  framebuffer = (grub_uint8_t *) mode_info.phys_base_addr;
+  ptr = framebuffer;
+
+  if (controller_info.version >= 0x300)
+    {
+      bytes_per_scan_line = mode_info.lin_bytes_per_scan_line;
+    }
+  else
+    {
+      bytes_per_scan_line = mode_info.bytes_per_scan_line;
+    }
+
+  /* Draw some random data to screen.  */
+  for (i = 0; i < 256 * 256; i++)
+    {
+      ptr[i] = i & 0x0F;
+    }
+
+  /* Draw white line to screen.  */
+  for (i = 0; i < 100; i++)
+    {
+      ptr[mode_info.bytes_per_scan_line * 50 + i] = 0x0F;
+    }
+
+  /* Draw another white line to screen.  */
+  grub_memset (ptr + bytes_per_scan_line * 51, 0x0f, bytes_per_scan_line);
+
+  grub_getkey ();
+
+  grub_video_restore ();
+
+  /* Restore old video mode.  */
+  grub_vbe_set_video_mode (old_mode, 0);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(vbetest)
+{
+  cmd = grub_register_command ("vbetest", grub_cmd_vbetest,
+                              0, N_("Test VESA BIOS Extension 2.0+ support."));
+}
+
+GRUB_MOD_FINI(vbetest)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/ieee1275/suspend.c b/grub-core/commands/ieee1275/suspend.c
new file mode 100644 (file)
index 0000000..f096cc9
--- /dev/null
@@ -0,0 +1,49 @@
+/* suspend.c - command to suspend GRUB and return to Open Firmware  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+grub_cmd_suspend (grub_command_t cmd __attribute__ ((unused)),
+                 int argc __attribute__ ((unused)),
+                 char **args __attribute__ ((unused)))
+{
+  grub_printf ("Run 'go' to resume GRUB.\n");
+  grub_ieee1275_enter ();
+  grub_cls ();
+  return 0;
+}
+
+static grub_command_t cmd;
+\f
+GRUB_MOD_INIT(ieee1275_suspend)
+{
+  cmd = grub_register_command ("suspend", grub_cmd_suspend,
+                              0, N_("Return to Open Firmware prompt."));
+}
+
+GRUB_MOD_FINI(ieee1275_suspend)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/iorw.c b/grub-core/commands/iorw.c
new file mode 100644 (file)
index 0000000..474c871
--- /dev/null
@@ -0,0 +1,150 @@
+/* memrw.c - command to read / write physical memory  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+#include <grub/env.h>
+#include <grub/cpu/io.h>
+#include <grub/i18n.h>
+
+static grub_extcmd_t cmd_read_byte, cmd_read_word, cmd_read_dword;
+static grub_command_t cmd_write_byte, cmd_write_word, cmd_write_dword;
+
+static const struct grub_arg_option options[] =
+  {
+    {0, 'v', 0, N_("Save read value into variable VARNAME."),
+     N_("VARNAME"), ARG_TYPE_STRING},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+
+static grub_err_t
+grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
+{
+  grub_target_addr_t addr;
+  grub_uint32_t value = 0;
+  char buf[sizeof ("XXXXXXXX")];
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments");
+
+  addr = grub_strtoul (argv[0], 0, 0);
+  switch (cmd->cmd->name[sizeof ("in") - 1])
+    {
+    case 'l':
+      value = grub_inl (addr);
+      break;
+
+    case 'w':
+      value = grub_inw (addr);
+      break;
+
+    case 'b':
+      value = grub_inb (addr);
+      break;
+    }
+
+  if (cmd->state[0].set)
+    {
+      grub_snprintf (buf, sizeof (buf), "%x", value);
+      grub_env_set (cmd->state[0].arg, buf);
+    }
+  else
+    grub_printf ("0x%x\n", value);
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_write (grub_command_t cmd, int argc, char **argv)
+{
+  grub_target_addr_t addr;
+  grub_uint32_t value;
+  grub_uint32_t mask = 0xffffffff;
+
+  if (argc != 2 && argc != 3)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments");
+
+  addr = grub_strtoul (argv[0], 0, 0);
+  value = grub_strtoul (argv[1], 0, 0);
+  if (argc == 3)
+    mask = grub_strtoul (argv[2], 0, 0);
+  value &= mask;
+  switch (cmd->name[sizeof ("out") - 1])
+    {
+    case 'l':
+      if (mask != 0xffffffff)
+       grub_outl ((grub_inl (addr) & ~mask) | value, addr);
+      else
+       grub_outl (value, addr);
+      break;
+
+    case 'w':
+      if ((mask & 0xffff) != 0xffff)
+       grub_outw ((grub_inw (addr) & ~mask) | value, addr);
+      else
+       grub_outw (value, addr);
+      break;
+
+    case 'b':
+      if ((mask & 0xff) != 0xff)
+       grub_outb ((grub_inb (addr) & ~mask) | value, addr);
+      else
+       grub_outb (value, addr);
+      break;
+    }
+
+  return 0;
+}
+
+GRUB_MOD_INIT(memrw)
+{
+  cmd_read_byte =
+    grub_register_extcmd ("inb", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
+                         N_("PORT"), N_("Read byte from PORT."), options);
+  cmd_read_word =
+    grub_register_extcmd ("inw", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
+                         N_("PORT"), N_("Read word from PORT."), options);
+  cmd_read_dword =
+    grub_register_extcmd ("inl", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
+                         N_("PORT"), N_("Read dword from PORT."), options);
+  cmd_write_byte =
+    grub_register_command ("outb", grub_cmd_write,
+                          N_("PORT VALUE [MASK]"),
+                          N_("Write byte VALUE to PORT."));
+  cmd_write_word =
+    grub_register_command ("outw", grub_cmd_write,
+                          N_("PORT VALUE [MASK]"),
+                          N_("Write word VALUE to PORT."));
+  cmd_write_dword =
+    grub_register_command ("outl", grub_cmd_write,
+                          N_("ADDR VALUE [MASK]"),
+                          N_("Write dword VALUE to PORT."));
+}
+
+GRUB_MOD_FINI(memrw)
+{
+  grub_unregister_extcmd (cmd_read_byte);
+  grub_unregister_extcmd (cmd_read_word);
+  grub_unregister_extcmd (cmd_read_dword);
+  grub_unregister_command (cmd_write_byte);
+  grub_unregister_command (cmd_write_word);
+  grub_unregister_command (cmd_write_dword);
+}
diff --git a/grub-core/commands/keystatus.c b/grub-core/commands/keystatus.c
new file mode 100644 (file)
index 0000000..8387928
--- /dev/null
@@ -0,0 +1,93 @@
+/* keystatus.c - Command to check key modifier status.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+#include <grub/term.h>
+#include <grub/i18n.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {"shift", 's', 0, N_("Check Shift key."), 0, 0},
+    {"ctrl", 'c', 0, N_("Check Control key."), 0, 0},
+    {"alt", 'a', 0, N_("Check Alt key."), 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+#define grub_cur_term_input    grub_term_get_current_input ()
+
+static grub_err_t
+grub_cmd_keystatus (grub_extcmd_t cmd,
+                   int argc __attribute__ ((unused)),
+                   char **args __attribute__ ((unused)))
+{
+  struct grub_arg_list *state = cmd->state;
+  int expect_mods = 0;
+  int mods;
+
+  if (state[0].set)
+    expect_mods |= GRUB_TERM_STATUS_SHIFT;
+  if (state[1].set)
+    expect_mods |= GRUB_TERM_STATUS_CTRL;
+  if (state[2].set)
+    expect_mods |= GRUB_TERM_STATUS_ALT;
+
+  grub_dprintf ("keystatus", "expect_mods: %d\n", expect_mods);
+
+  /* Without arguments, just check whether getkeystatus is supported at
+     all.  */
+  if (expect_mods == 0)
+    {
+      grub_term_input_t term;
+      int nterms = 0;
+
+      FOR_ACTIVE_TERM_INPUTS (term)
+       if (!term->getkeystatus)
+         return grub_error (GRUB_ERR_TEST_FAILURE, "false");
+       else
+         nterms++;
+      if (!nterms)
+       return grub_error (GRUB_ERR_TEST_FAILURE, "false");
+      return 0;
+    }
+
+  mods = grub_getkeystatus ();
+  grub_dprintf ("keystatus", "mods: %d\n", mods);
+  if (mods >= 0 && (mods & expect_mods) != 0)
+    return 0;
+  else
+    return grub_error (GRUB_ERR_TEST_FAILURE, "false");
+}
+
+static grub_extcmd_t cmd;
+\f
+GRUB_MOD_INIT(keystatus)
+{
+  cmd = grub_register_extcmd ("keystatus", grub_cmd_keystatus,
+                             GRUB_COMMAND_FLAG_BOTH,
+                             N_("[--shift] [--ctrl] [--alt]"),
+                             N_("Check key modifier status."),
+                             options);
+}
+
+GRUB_MOD_FINI(keystatus)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c
new file mode 100644 (file)
index 0000000..d763b2d
--- /dev/null
@@ -0,0 +1,400 @@
+/* loadenv.c - command to load/save environment variable.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/partition.h>
+#include <grub/lib/envblk.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {"file", 'f', 0, N_("Specify filename."), 0, ARG_TYPE_PATHNAME},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static grub_file_t
+open_envblk_file (char *filename)
+{
+  grub_file_t file;
+
+  if (! filename)
+    {
+      char *prefix;
+
+      prefix = grub_env_get ("prefix");
+      if (prefix)
+        {
+          int len;
+
+          len = grub_strlen (prefix);
+          filename = grub_malloc (len + 1 + sizeof (GRUB_ENVBLK_DEFCFG));
+          if (! filename)
+            return 0;
+
+          grub_strcpy (filename, prefix);
+          filename[len] = '/';
+          grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG);
+          file = grub_file_open (filename);
+          grub_free (filename);
+          return file;
+        }
+      else
+        {
+          grub_error (GRUB_ERR_FILE_NOT_FOUND, "prefix is not found");
+          return 0;
+        }
+    }
+
+  return grub_file_open (filename);
+}
+
+static grub_envblk_t
+read_envblk_file (grub_file_t file)
+{
+  grub_off_t offset = 0;
+  char *buf;
+  grub_size_t size = grub_file_size (file);
+  grub_envblk_t envblk;
+
+  buf = grub_malloc (size);
+  if (! buf)
+    return 0;
+
+  while (size > 0)
+    {
+      grub_ssize_t ret;
+
+      ret = grub_file_read (file, buf + offset, size);
+      if (ret <= 0)
+        {
+          if (grub_errno == GRUB_ERR_NONE)
+            grub_error (GRUB_ERR_FILE_READ_ERROR, "cannot read");
+          grub_free (buf);
+          return 0;
+        }
+
+      size -= ret;
+      offset += ret;
+    }
+
+  envblk = grub_envblk_open (buf, offset);
+  if (! envblk)
+    {
+      grub_free (buf);
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block");
+      return 0;
+    }
+
+  return envblk;
+}
+
+static grub_err_t
+grub_cmd_load_env (grub_extcmd_t cmd,
+                  int argc __attribute__ ((unused)),
+                  char **args __attribute__ ((unused)))
+{
+  struct grub_arg_list *state = cmd->state;
+  grub_file_t file;
+  grub_envblk_t envblk;
+
+  auto int set_var (const char *name, const char *value);
+  int set_var (const char *name, const char *value)
+  {
+    grub_env_set (name, value);
+    return 0;
+  }
+
+  file = open_envblk_file ((state[0].set) ? state[0].arg : 0);
+  if (! file)
+    return grub_errno;
+
+  envblk = read_envblk_file (file);
+  if (! envblk)
+    goto fail;
+
+  grub_envblk_iterate (envblk, set_var);
+  grub_envblk_close (envblk);
+
+ fail:
+  grub_file_close (file);
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_list_env (grub_extcmd_t cmd,
+                  int argc __attribute__ ((unused)),
+                  char **args __attribute__ ((unused)))
+{
+  struct grub_arg_list *state = cmd->state;
+  grub_file_t file;
+  grub_envblk_t envblk;
+
+  /* Print all variables in current context.  */
+  auto int print_var (const char *name, const char *value);
+  int print_var (const char *name, const char *value)
+    {
+      grub_printf ("%s=%s\n", name, value);
+      return 0;
+    }
+
+  file = open_envblk_file ((state[0].set) ? state[0].arg : 0);
+  if (! file)
+    return grub_errno;
+
+  envblk = read_envblk_file (file);
+  if (! envblk)
+    goto fail;
+
+  grub_envblk_iterate (envblk, print_var);
+  grub_envblk_close (envblk);
+
+ fail:
+  grub_file_close (file);
+  return grub_errno;
+}
+
+/* Used to maintain a variable length of blocklists internally.  */
+struct blocklist
+{
+  grub_disk_addr_t sector;
+  unsigned offset;
+  unsigned length;
+  struct blocklist *next;
+};
+
+static void
+free_blocklists (struct blocklist *p)
+{
+  struct blocklist *q;
+
+  for (; p; p = q)
+    {
+      q = p->next;
+      grub_free (p);
+    }
+}
+
+static grub_err_t
+check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists,
+                  grub_file_t file)
+{
+  grub_size_t total_length;
+  grub_size_t index;
+  grub_disk_t disk;
+  grub_disk_addr_t part_start;
+  struct blocklist *p;
+  char *buf;
+
+  /* Sanity checks.  */
+  total_length = 0;
+  for (p = blocklists; p; p = p->next)
+    {
+      struct blocklist *q;
+      for (q = p->next; q; q = q->next)
+        {
+          /* Check if any pair of blocks overlap.  */
+          if (p->sector == q->sector)
+            {
+              /* This might be actually valid, but it is unbelievable that
+                 any filesystem makes such a silly allocation.  */
+              return grub_error (GRUB_ERR_BAD_FS, "malformed file");
+            }
+        }
+
+      total_length += p->length;
+    }
+
+  if (total_length != grub_file_size (file))
+    {
+      /* Maybe sparse, unallocated sectors. No way in GRUB.  */
+      return grub_error (GRUB_ERR_BAD_FILE_TYPE, "sparse file not allowed");
+    }
+
+  /* One more sanity check. Re-read all sectors by blocklists, and compare
+     those with the data read via a file.  */
+  disk = file->device->disk;
+
+  part_start = grub_partition_get_start (disk->partition);
+
+  buf = grub_envblk_buffer (envblk);
+  for (p = blocklists, index = 0; p; index += p->length, p = p->next)
+    {
+      char blockbuf[GRUB_DISK_SECTOR_SIZE];
+
+      if (grub_disk_read (disk, p->sector - part_start,
+                          p->offset, p->length, blockbuf))
+        return grub_errno;
+
+      if (grub_memcmp (buf + index, blockbuf, p->length) != 0)
+       return grub_error (GRUB_ERR_FILE_READ_ERROR, "invalid blocklist");
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static int
+write_blocklists (grub_envblk_t envblk, struct blocklist *blocklists,
+                  grub_file_t file)
+{
+  char *buf;
+  grub_disk_t disk;
+  grub_disk_addr_t part_start;
+  struct blocklist *p;
+  grub_size_t index;
+
+  buf = grub_envblk_buffer (envblk);
+  disk = file->device->disk;
+  part_start = grub_partition_get_start (disk->partition);
+
+  index = 0;
+  for (p = blocklists; p; index += p->length, p = p->next)
+    {
+      if (grub_disk_write (disk, p->sector - part_start,
+                           p->offset, p->length, buf + index))
+        return 0;
+    }
+
+  return 1;
+}
+
+static grub_err_t
+grub_cmd_save_env (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  grub_file_t file;
+  grub_envblk_t envblk;
+  struct blocklist *head = 0;
+  struct blocklist *tail = 0;
+
+  /* Store blocklists in a linked list.  */
+  auto void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector,
+                                        unsigned offset,
+                                        unsigned length);
+  void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector,
+                                   unsigned offset, unsigned length)
+    {
+      struct blocklist *block;
+
+      if (offset + length > GRUB_DISK_SECTOR_SIZE)
+        /* Seemingly a bug.  */
+        return;
+
+      block = grub_malloc (sizeof (*block));
+      if (! block)
+        return;
+
+      block->sector = sector;
+      block->offset = offset;
+      block->length = length;
+
+      /* Slightly complicated, because the list should be FIFO.  */
+      block->next = 0;
+      if (tail)
+        tail->next = block;
+      tail = block;
+      if (! head)
+        head = block;
+    }
+
+  if (! argc)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no variable is specified");
+
+  file = open_envblk_file ((state[0].set) ? state[0].arg : 0);
+  if (! file)
+    return grub_errno;
+
+  if (! file->device->disk)
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_BAD_DEVICE, "disk device required");
+    }
+
+  file->read_hook = read_hook;
+  envblk = read_envblk_file (file);
+  file->read_hook = 0;
+  if (! envblk)
+    goto fail;
+
+  if (check_blocklists (envblk, head, file))
+    goto fail;
+
+  while (argc)
+    {
+      char *value;
+
+      value = grub_env_get (args[0]);
+      if (value)
+        {
+          if (! grub_envblk_set (envblk, args[0], value))
+            {
+              grub_error (GRUB_ERR_BAD_ARGUMENT, "environment block too small");
+              goto fail;
+            }
+        }
+
+      argc--;
+      args++;
+    }
+
+  write_blocklists (envblk, head, file);
+
+ fail:
+  if (envblk)
+    grub_envblk_close (envblk);
+  free_blocklists (head);
+  grub_file_close (file);
+  return grub_errno;
+}
+
+static grub_extcmd_t cmd_load, cmd_list, cmd_save;
+
+GRUB_MOD_INIT(loadenv)
+{
+  cmd_load =
+    grub_register_extcmd ("load_env", grub_cmd_load_env,
+                         GRUB_COMMAND_FLAG_BOTH,
+                         N_("[-f FILE]"),
+                         N_("Load variables from environment block file."),
+                         options);
+  cmd_list =
+    grub_register_extcmd ("list_env", grub_cmd_list_env,
+                         GRUB_COMMAND_FLAG_BOTH,
+                         N_("[-f FILE]"),
+                         N_("List variables from environment block file."),
+                         options);
+  cmd_save =
+    grub_register_extcmd ("save_env", grub_cmd_save_env,
+                         GRUB_COMMAND_FLAG_BOTH,
+                         N_("[-f FILE] variable_name [...]"),
+                         N_("Save variables to environment block file."),
+                         options);
+}
+
+GRUB_MOD_FINI(loadenv)
+{
+  grub_unregister_extcmd (cmd_load);
+  grub_unregister_extcmd (cmd_list);
+  grub_unregister_extcmd (cmd_save);
+}
diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c
new file mode 100644 (file)
index 0000000..eb10496
--- /dev/null
@@ -0,0 +1,276 @@
+/* ls.c - command to list files and devices */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/device.h>
+#include <grub/term.h>
+#include <grub/partition.h>
+#include <grub/file.h>
+#include <grub/normal.h>
+#include <grub/extcmd.h>
+#include <grub/datetime.h>
+#include <grub/i18n.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {"long", 'l', 0, N_("Show a long list with more detailed information."), 0, 0},
+    {"human-readable", 'h', 0, N_("Print sizes in a human readable format."), 0, 0},
+    {"all", 'a', 0, N_("List all files."), 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static const char grub_human_sizes[] = {' ', 'K', 'M', 'G', 'T'};
+
+static grub_err_t
+grub_ls_list_devices (int longlist)
+{
+  auto int grub_ls_print_devices (const char *name);
+  int grub_ls_print_devices (const char *name)
+    {
+      if (longlist)
+       grub_normal_print_device_info (name);
+      else
+       grub_printf ("(%s) ", name);
+
+      return 0;
+    }
+
+  grub_device_iterate (grub_ls_print_devices);
+  grub_putchar ('\n');
+  grub_refresh ();
+
+  return 0;
+}
+
+static grub_err_t
+grub_ls_list_files (char *dirname, int longlist, int all, int human)
+{
+  char *device_name;
+  grub_fs_t fs;
+  const char *path;
+  grub_device_t dev;
+
+  auto int print_files (const char *filename,
+                       const struct grub_dirhook_info *info);
+  auto int print_files_long (const char *filename,
+                            const struct grub_dirhook_info *info);
+
+  int print_files (const char *filename, const struct grub_dirhook_info *info)
+    {
+      if (all || filename[0] != '.')
+       grub_printf ("%s%s ", filename, info->dir ? "/" : "");
+
+      return 0;
+    }
+
+  int print_files_long (const char *filename,
+                       const struct grub_dirhook_info *info)
+    {
+      if ((! all) && (filename[0] == '.'))
+       return 0;
+
+      if (! info->dir)
+       {
+         grub_file_t file;
+         char *pathname;
+
+         if (dirname[grub_strlen (dirname) - 1] == '/')
+           pathname = grub_xasprintf ("%s%s", dirname, filename);
+         else
+           pathname = grub_xasprintf ("%s/%s", dirname, filename);
+
+         if (!pathname)
+           return 1;
+
+         /* XXX: For ext2fs symlinks are detected as files while they
+            should be reported as directories.  */
+         file = grub_file_open (pathname);
+         if (! file)
+           {
+             grub_errno = 0;
+             grub_free (pathname);
+             return 0;
+           }
+
+         if (! human)
+           grub_printf ("%-12llu", (unsigned long long) file->size);
+         else
+           {
+             grub_uint64_t fsize = file->size * 100ULL;
+             int fsz = file->size;
+             int units = 0;
+             char buf[20];
+
+             while (fsz / 1024)
+               {
+                 fsize = (fsize + 512) / 1024;
+                 fsz /= 1024;
+                 units++;
+               }
+
+             if (units)
+               {
+                 grub_uint32_t whole, fraction;
+
+                 whole = grub_divmod64 (fsize, 100, &fraction);
+                 grub_snprintf (buf, sizeof (buf),
+                                "%u.%02u%c", whole, fraction,
+                                grub_human_sizes[units]);
+                 grub_printf ("%-12s", buf);
+               }
+             else
+               grub_printf ("%-12llu", (unsigned long long) file->size);
+
+           }
+         grub_file_close (file);
+         grub_free (pathname);
+       }
+      else
+       grub_printf ("%-12s", "DIR");
+
+      if (info->mtimeset)
+       {
+         struct grub_datetime datetime;
+         grub_unixtime2datetime (info->mtime, &datetime);
+         if (human)
+           grub_printf (" %d-%02d-%02d %02d:%02d:%02d %-11s ",
+                        datetime.year, datetime.month, datetime.day,
+                        datetime.hour, datetime.minute,
+                        datetime.second,
+                        grub_get_weekday_name (&datetime));
+         else
+           grub_printf (" %04d%02d%02d%02d%02d%02d ",
+                        datetime.year, datetime.month,
+                        datetime.day, datetime.hour,
+                        datetime.minute, datetime.second);
+       }
+      grub_printf ("%s%s\n", filename, info->dir ? "/" : "");
+
+      return 0;
+    }
+
+  device_name = grub_file_get_device_name (dirname);
+  dev = grub_device_open (device_name);
+  if (! dev)
+    goto fail;
+
+  fs = grub_fs_probe (dev);
+  path = grub_strchr (dirname, ')');
+  if (! path)
+    path = dirname;
+  else
+    path++;
+
+  if (! path && ! device_name)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
+      goto fail;
+    }
+
+  if (! *path)
+    {
+      if (grub_errno == GRUB_ERR_UNKNOWN_FS)
+       grub_errno = GRUB_ERR_NONE;
+
+      grub_normal_print_device_info (device_name);
+    }
+  else if (fs)
+    {
+      if (longlist)
+       (fs->dir) (dev, path, print_files_long);
+      else
+       (fs->dir) (dev, path, print_files);
+
+      if (grub_errno == GRUB_ERR_BAD_FILE_TYPE
+         && path[grub_strlen (path) - 1] != '/')
+       {
+         /* PATH might be a regular file.  */
+         char *p;
+         grub_file_t file;
+         struct grub_dirhook_info info;
+         grub_errno = 0;
+
+         file = grub_file_open (dirname);
+         if (! file)
+           goto fail;
+
+         grub_file_close (file);
+
+         p = grub_strrchr (dirname, '/') + 1;
+         dirname = grub_strndup (dirname, p - dirname);
+         if (! dirname)
+           goto fail;
+
+         all = 1;
+         grub_memset (&info, 0, sizeof (info));
+         if (longlist)
+           print_files_long (p, &info);
+         else
+           print_files (p, &info);
+
+         grub_free (dirname);
+       }
+
+      if (grub_errno == GRUB_ERR_NONE)
+       grub_putchar ('\n');
+
+      grub_refresh ();
+    }
+
+ fail:
+  if (dev)
+    grub_device_close (dev);
+
+  grub_free (device_name);
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_ls (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+
+  if (argc == 0)
+    grub_ls_list_devices (state[0].set);
+  else
+    grub_ls_list_files (args[0], state[0].set, state[2].set,
+                       state[1].set);
+
+  return 0;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(ls)
+{
+  cmd = grub_register_extcmd ("ls", grub_cmd_ls, GRUB_COMMAND_FLAG_BOTH,
+                             N_("[-l|-h|-a] [FILE]"),
+                             N_("List devices and files."), options);
+}
+
+GRUB_MOD_FINI(ls)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/lsmmap.c b/grub-core/commands/lsmmap.c
new file mode 100644 (file)
index 0000000..2755df9
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_EMU
+#include <grub/machine/memory.h>
+#endif
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+grub_cmd_lsmmap (grub_command_t cmd __attribute__ ((unused)),
+                int argc __attribute__ ((unused)), char **args __attribute__ ((unused)))
+
+{
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      grub_printf ("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n",
+                  (long long) addr, (long long) size, type);
+      return 0;
+    }
+#ifndef GRUB_MACHINE_EMU
+  grub_machine_mmap_iterate (hook);
+#endif
+
+  return 0;
+}
+
+static grub_command_t cmd;
+\f
+GRUB_MOD_INIT(lsmmap)
+{
+  cmd = grub_register_command ("lsmmap", grub_cmd_lsmmap,
+                              0, N_("List memory map provided by firmware."));
+}
+
+GRUB_MOD_FINI(lsmmap)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/lspci.c b/grub-core/commands/lspci.c
new file mode 100644 (file)
index 0000000..a69bb35
--- /dev/null
@@ -0,0 +1,234 @@
+/* lspci.c - List PCI devices.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/pci.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+
+struct grub_pci_classname
+{
+  int class;
+  int subclass;
+  char *desc;
+};
+
+static const struct grub_pci_classname grub_pci_classes[] =
+  {
+    { 0, 0, "" },
+    { 1, 0, "SCSI Controller" },
+    { 1, 1, "IDE Controller" },
+    { 1, 2, "Floppy Controller" },
+    { 1, 3, "IPI Controller" },
+    { 1, 4, "RAID Controller" },
+    { 1, 6, "SATA Controller" },
+    { 1, 0x80, "Mass storage Controller" },
+    { 2, 0, "Ethernet Controller" },
+    { 2, 1, "Token Ring Controller" },
+    { 2, 2, "FDDI Controller" },
+    { 2, 3, "ATM Controller" },
+    { 2, 4, "ISDN Controller" },
+    { 2, 0x80, "Network controller" },
+    { 3, 0, "VGA Controller" },
+    { 3, 1, "XGA Controller" },
+    { 3, 2, "3D Controller" },
+    { 3, 0x80, "Display Controller" },
+    { 4, 0, "Multimedia Video Device" },
+    { 4, 1, "Multimedia Audio Device" },
+    { 4, 2, "Multimedia Telephony Device" },
+    { 4, 0x80, "Multimedia device" },
+    { 5, 0, "RAM Controller" },
+    { 5, 1, "Flash Memory Controller" },
+    { 5, 0x80, "Memory Controller" },
+    { 6, 0, "Host Bridge" },
+    { 6, 1, "ISA Bridge" },
+    { 6, 2, "EISA Bride" },
+    { 6, 3, "MCA Bridge" },
+    { 6, 4, "PCI-PCI Bridge" },
+    { 6, 5, "PCMCIA Bridge" },
+    { 6, 6, "NuBus Bridge" },
+    { 6, 7, "CardBus Bridge" },
+    { 6, 8, "Raceway Bridge" },
+    { 6, 0x80, "Unknown Bridge" },
+    { 7, 0x80, "Communication controller" },
+    { 8, 0x80, "System hardware" },
+    { 9, 0, "Keyboard Controller" },
+    { 9, 1, "Digitizer" },
+    { 9, 2, "Mouse Controller" },
+    { 9, 3, "Scanner Controller" },
+    { 9, 4, "Gameport Controller" },
+    { 9, 0x80, "Unknown Input Device" },
+    { 10, 0, "Generic Docking Station" },
+    { 10, 0x80, "Unknown Docking Station" },
+    { 11, 0, "80386 Processor" },
+    { 11, 1, "80486 Processor" },
+    { 11, 2, "Pentium Processor" },
+    { 11, 0x10, "Alpha Processor" },
+    { 11, 0x20, "PowerPC Processor" },
+    { 11, 0x30, "MIPS Processor" },
+    { 11, 0x40, "Co-Processor" },
+    { 11, 0x80, "Unknown Processor" },
+    { 12, 3, "USB Controller" },
+    { 12, 0x80, "Serial Bus Controller" },
+    { 13, 0x80, "Wireless Controller" },
+    { 14, 0, "I2O" },
+    { 15, 0, "IrDA Controller" },
+    { 15, 1, "Consumer IR" },
+    { 15, 0x10, "RF-Controller" },
+    { 15, 0x80, "Satellite Communication Controller" },
+    { 16, 0, "Network Decryption" },
+    { 16, 1, "Entertainment Decryption" },
+    { 16, 0x80, "Unknown Decryption Controller" },
+    { 17, 0, "Digital IO Module" },
+    { 17, 0x80, "Unknown Data Input System" },
+    { 0, 0, 0 },
+  };
+
+static const char *
+grub_pci_get_class (int class, int subclass)
+{
+  const struct grub_pci_classname *curr = grub_pci_classes;
+
+  while (curr->desc)
+    {
+      if (curr->class == class && curr->subclass == subclass)
+       return curr->desc;
+      curr++;
+    }
+
+  return 0;
+}
+
+static const struct grub_arg_option options[] =
+  {
+    {"iospace", 'i', 0, "show I/O spaces", 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static int iospace;
+
+static int NESTED_FUNC_ATTR
+grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid)
+{
+  grub_uint32_t class;
+  const char *sclass;
+  grub_pci_address_t addr;
+  int reg;
+
+  grub_printf ("%02x:%02x.%x %04x:%04x", grub_pci_get_bus (dev),
+              grub_pci_get_device (dev), grub_pci_get_function (dev),
+              pciid & 0xFFFF, pciid >> 16);
+  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+  class = grub_pci_read (addr);
+
+  /* Lookup the class name, if there isn't a specific one,
+     retry with 0x80 to get the generic class name.  */
+  sclass = grub_pci_get_class (class >> 24, (class >> 16) & 0xFF);
+  if (! sclass)
+    sclass = grub_pci_get_class (class >> 24, 0x80);
+  if (! sclass)
+    sclass = "";
+
+  grub_printf (" [%04x] %s", (class >> 16) & 0xffff, sclass);
+
+  grub_uint8_t pi = (class >> 8) & 0xff;
+  if (pi)
+    grub_printf (" [PI %02x]", pi);
+
+  grub_printf ("\n");
+
+  if (iospace)
+    {
+      reg = GRUB_PCI_REG_ADDRESSES;
+      while (reg < GRUB_PCI_REG_CIS_POINTER)
+       {
+         grub_uint64_t space;
+         addr = grub_pci_make_address (dev, reg);
+         space = grub_pci_read (addr);
+
+         reg += sizeof (grub_uint32_t);
+
+         if (space == 0)
+           continue;
+        
+         switch (space & GRUB_PCI_ADDR_SPACE_MASK)
+           {
+           case GRUB_PCI_ADDR_SPACE_IO:
+             grub_printf ("\tIO space %d at 0x%llx\n",
+                          (unsigned) ((reg - GRUB_PCI_REG_ADDRESSES)
+                           / sizeof (grub_uint32_t)) - 1,
+                          (unsigned long long)
+                          (space & GRUB_PCI_ADDR_IO_MASK));
+             break;
+           case GRUB_PCI_ADDR_SPACE_MEMORY:
+             if ((space & GRUB_PCI_ADDR_MEM_TYPE_MASK)
+                 == GRUB_PCI_ADDR_MEM_TYPE_64)
+               {
+                 addr = grub_pci_make_address (dev, reg);
+                 space |= ((grub_uint64_t) grub_pci_read (addr)) << 32;
+                 reg += sizeof (grub_uint32_t);
+                 grub_printf ("\t64-bit memory space %d at 0x%016llx [%s]\n",
+                              (unsigned) ((reg - GRUB_PCI_REG_ADDRESSES)
+                               / sizeof (grub_uint32_t)) - 2,
+                              (unsigned long long)
+                              (space & GRUB_PCI_ADDR_MEM_MASK),
+                              space & GRUB_PCI_ADDR_MEM_PREFETCH
+                              ? "prefetchable" : "non-prefetchable");
+                
+               }
+             else
+               grub_printf ("\t32-bit memory space %d at 0x%016llx [%s]\n",
+                            (unsigned) ((reg - GRUB_PCI_REG_ADDRESSES)
+                             / sizeof (grub_uint32_t)) - 1,
+                            (unsigned long long) 
+                            (space & GRUB_PCI_ADDR_MEM_MASK),
+                            space & GRUB_PCI_ADDR_MEM_PREFETCH
+                            ? "prefetchable" : "non-prefetchable");
+             break;
+           }
+       }
+    }
+
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_lspci (grub_extcmd_t cmd,
+               int argc __attribute__ ((unused)),
+               char **args __attribute__ ((unused)))
+{
+  iospace = cmd->state[0].set;
+  grub_pci_iterate (grub_lspci_iter);
+  return GRUB_ERR_NONE;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(lspci)
+{
+  cmd = grub_register_extcmd ("lspci", grub_cmd_lspci, GRUB_COMMAND_FLAG_BOTH,
+                             "[-i]", N_("List PCI devices."), options);
+}
+
+GRUB_MOD_FINI(lspci)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/memrw.c b/grub-core/commands/memrw.c
new file mode 100644 (file)
index 0000000..6a4d43b
--- /dev/null
@@ -0,0 +1,149 @@
+/* memrw.c - command to read / write physical memory  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+#include <grub/env.h>
+#include <grub/i18n.h>
+
+static grub_extcmd_t cmd_read_byte, cmd_read_word, cmd_read_dword;
+static grub_command_t cmd_write_byte, cmd_write_word, cmd_write_dword;
+
+static const struct grub_arg_option options[] =
+  {
+    {0, 'v', 0, N_("Save read value into variable VARNAME."),
+     "VARNAME", ARG_TYPE_STRING},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+
+static grub_err_t
+grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
+{
+  grub_target_addr_t addr;
+  grub_uint32_t value = 0;
+  char buf[sizeof ("XXXXXXXX")];
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid number of arguments");
+
+  addr = grub_strtoul (argv[0], 0, 0);
+  switch (cmd->cmd->name[sizeof ("read_") - 1])
+    {
+    case 'd':
+      value = *((volatile grub_uint32_t *) addr);
+      break;
+
+    case 'w':
+      value = *((volatile grub_uint16_t *) addr);
+      break;
+
+    case 'b':
+      value = *((volatile grub_uint8_t *) addr);
+      break;
+    }
+
+  if (cmd->state[0].set)
+    {
+      grub_snprintf (buf, sizeof (buf), "%x", value);
+      grub_env_set (cmd->state[0].arg, buf);
+    }
+  else
+    grub_printf ("0x%x\n", value);
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_write (grub_command_t cmd, int argc, char **argv)
+{
+  grub_target_addr_t addr;
+  grub_uint32_t value;
+  grub_uint32_t mask = 0xffffffff;
+
+  if (argc != 2 && argc != 3)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid number of arguments");
+
+  addr = grub_strtoul (argv[0], 0, 0);
+  value = grub_strtoul (argv[1], 0, 0);
+  if (argc == 3)
+    mask = grub_strtoul (argv[2], 0, 0);
+  value &= mask;
+  switch (cmd->name[sizeof ("write_") - 1])
+    {
+    case 'd':
+      if (mask != 0xffffffff)
+       *((volatile grub_uint32_t *) addr)
+         = (*((volatile grub_uint32_t *) addr) & ~mask) | value;
+      else
+       *((volatile grub_uint32_t *) addr) = value;
+      break;
+
+    case 'w':
+      if ((mask & 0xffff) != 0xffff)
+       *((volatile grub_uint16_t *) addr)
+         = (*((volatile grub_uint16_t *) addr) & ~mask) | value;
+      else
+       *((volatile grub_uint16_t *) addr) = value;
+      break;
+
+    case 'b':
+      if ((mask & 0xff) != 0xff)
+       *((volatile grub_uint8_t *) addr)
+         = (*((volatile grub_uint8_t *) addr) & ~mask) | value;
+      else
+       *((volatile grub_uint8_t *) addr) = value;
+      break;
+    }
+
+  return 0;
+}
+
+GRUB_MOD_INIT(memrw)
+{
+  cmd_read_byte =
+    grub_register_extcmd ("read_byte", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
+                         N_("ADDR"), N_("Read byte from ADDR."), options);
+  cmd_read_word =
+    grub_register_extcmd ("read_word", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
+                         N_("ADDR"), N_("Read word from ADDR."), options);
+  cmd_read_dword =
+    grub_register_extcmd ("read_dword", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
+                         N_("ADDR"), N_("Read dword from ADDR."), options);
+  cmd_write_byte =
+    grub_register_command ("write_byte", grub_cmd_write,
+                          N_("ADDR VALUE [MASK]"), N_("Write byte VALUE to ADDR."));
+  cmd_write_word =
+    grub_register_command ("write_word", grub_cmd_write,
+                          N_("ADDR VALUE [MASK]"), N_("Write word VALUE to ADDR."));
+  cmd_write_dword =
+    grub_register_command ("write_dword", grub_cmd_write,
+                          N_("ADDR VALUE [MASK]"), N_("Write dword VALUE to ADDR."));
+}
+
+GRUB_MOD_FINI(memrw)
+{
+  grub_unregister_extcmd (cmd_read_byte);
+  grub_unregister_extcmd (cmd_read_word);
+  grub_unregister_extcmd (cmd_read_dword);
+  grub_unregister_command (cmd_write_byte);
+  grub_unregister_command (cmd_write_word);
+  grub_unregister_command (cmd_write_dword);
+}
diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c
new file mode 100644 (file)
index 0000000..4ea9efe
--- /dev/null
@@ -0,0 +1,391 @@
+/* minicmd.c - commands for the rescue mode */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/term.h>
+#include <grub/loader.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+/* cat FILE */
+static grub_err_t
+grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)),
+                  int argc, char *argv[])
+{
+  grub_file_t file;
+  char buf[GRUB_DISK_SECTOR_SIZE];
+  grub_ssize_t size;
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    return grub_errno;
+
+  while ((size = grub_file_read (file, buf, sizeof (buf))) > 0)
+    {
+      int i;
+
+      for (i = 0; i < size; i++)
+       {
+         unsigned char c = buf[i];
+
+         if ((grub_isprint (c) || grub_isspace (c)) && c != '\r')
+           grub_putchar (c);
+         else
+           {
+             grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
+             grub_printf ("<%x>", (int) c);
+             grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
+           }
+       }
+    }
+
+  grub_putchar ('\n');
+  grub_refresh ();
+  grub_file_close (file);
+
+  return 0;
+}
+
+/* help */
+static grub_err_t
+grub_mini_cmd_help (struct grub_command *cmd __attribute__ ((unused)),
+                   int argc __attribute__ ((unused)),
+                   char *argv[] __attribute__ ((unused)))
+{
+  grub_command_t p;
+
+  for (p = grub_command_list; p; p = p->next)
+    grub_printf ("%s (%d%c)\t%s\n", p->name,
+                p->prio & GRUB_PRIO_LIST_PRIO_MASK,
+                (p->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) ? '+' : '-',
+                p->description);
+
+  return 0;
+}
+
+#if 0
+static void
+grub_rescue_cmd_info (void)
+{
+  extern void grub_disk_cache_get_performance (unsigned long *,
+                                              unsigned long *);
+  unsigned long hits, misses;
+
+  grub_disk_cache_get_performance (&hits, &misses);
+  grub_printf ("Disk cache: hits = %u, misses = %u ", hits, misses);
+  if (hits + misses)
+    {
+      unsigned long ratio = hits * 10000 / (hits + misses);
+      grub_printf ("(%u.%u%%)\n", ratio / 100, ratio % 100);
+    }
+  else
+    grub_printf ("(N/A)\n");
+}
+#endif
+
+/* root [DEVICE] */
+static grub_err_t
+grub_mini_cmd_root (struct grub_command *cmd __attribute__ ((unused)),
+                   int argc, char *argv[])
+{
+  grub_device_t dev;
+  grub_fs_t fs;
+
+  if (argc > 0)
+    {
+      char *device_name = grub_file_get_device_name (argv[0]);
+      if (! device_name)
+       return grub_errno;
+
+      grub_env_set ("root", device_name);
+      grub_free (device_name);
+    }
+
+  dev = grub_device_open (0);
+  if (! dev)
+    return grub_errno;
+
+  fs = grub_fs_probe (dev);
+  if (grub_errno == GRUB_ERR_UNKNOWN_FS)
+    grub_errno = GRUB_ERR_NONE;
+
+  grub_printf ("(%s): Filesystem is %s.\n",
+              grub_env_get ("root"), fs ? fs->name : "unknown");
+
+  grub_device_close (dev);
+
+  return 0;
+}
+
+#if 0
+static void
+grub_rescue_cmd_testload (int argc, char *argv[])
+{
+  grub_file_t file;
+  char *buf;
+  grub_ssize_t size;
+  grub_ssize_t pos;
+  auto void read_func (unsigned long sector, unsigned offset, unsigned len);
+
+  void read_func (unsigned long sector __attribute__ ((unused)),
+                 unsigned offset __attribute__ ((unused)),
+                 unsigned len __attribute__ ((unused)))
+    {
+      grub_putchar ('.');
+      grub_refresh ();
+    }
+
+  if (argc < 1)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
+      return;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    return;
+
+  size = grub_file_size (file) & ~(GRUB_DISK_SECTOR_SIZE - 1);
+  if (size == 0)
+    {
+      grub_file_close (file);
+      return;
+    }
+
+  buf = grub_malloc (size);
+  if (! buf)
+    goto fail;
+
+  grub_printf ("Reading %s sequentially", argv[0]);
+  file->read_hook = read_func;
+  if (grub_file_read (file, buf, size) != size)
+    goto fail;
+  grub_printf (" Done.\n");
+
+  /* Read sequentially again.  */
+  grub_printf ("Reading %s sequentially again", argv[0]);
+  if (grub_file_seek (file, 0) < 0)
+    goto fail;
+
+  for (pos = 0; pos < size; pos += GRUB_DISK_SECTOR_SIZE)
+    {
+      char sector[GRUB_DISK_SECTOR_SIZE];
+
+      if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE)
+         != GRUB_DISK_SECTOR_SIZE)
+       goto fail;
+
+      if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0)
+       {
+         grub_printf ("\nDiffers in %d\n", pos);
+         goto fail;
+       }
+    }
+  grub_printf (" Done.\n");
+
+  /* Read backwards and compare.  */
+  grub_printf ("Reading %s backwards", argv[0]);
+  pos = size;
+  while (pos > 0)
+    {
+      char sector[GRUB_DISK_SECTOR_SIZE];
+
+      pos -= GRUB_DISK_SECTOR_SIZE;
+
+      if (grub_file_seek (file, pos) < 0)
+       goto fail;
+
+      if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE)
+         != GRUB_DISK_SECTOR_SIZE)
+       goto fail;
+
+      if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0)
+       {
+         int i;
+
+         grub_printf ("\nDiffers in %d\n", pos);
+
+         for (i = 0; i < GRUB_DISK_SECTOR_SIZE; i++)
+           grub_putchar (buf[pos + i]);
+
+         if (i)
+           grub_refresh ();
+
+         goto fail;
+       }
+    }
+  grub_printf (" Done.\n");
+
+ fail:
+
+  grub_file_close (file);
+  grub_free (buf);
+}
+#endif
+
+/* dump ADDRESS [SIZE] */
+static grub_err_t
+grub_mini_cmd_dump (struct grub_command *cmd __attribute__ ((unused)),
+                   int argc, char *argv[])
+{
+  grub_uint8_t *addr;
+  grub_size_t size = 4;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no address specified");
+
+  addr = (grub_uint8_t *) grub_strtoul (argv[0], 0, 0);
+  if (grub_errno)
+    return grub_errno;
+
+  if (argc > 1)
+    size = (grub_size_t) grub_strtoul (argv[1], 0, 0);
+
+  while (size--)
+    {
+      grub_printf ("%x%x ", *addr >> 4, *addr & 0xf);
+      addr++;
+    }
+
+  return 0;
+}
+
+/* rmmod MODULE */
+static grub_err_t
+grub_mini_cmd_rmmod (struct grub_command *cmd __attribute__ ((unused)),
+                    int argc, char *argv[])
+{
+  grub_dl_t mod;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
+
+  mod = grub_dl_get (argv[0]);
+  if (! mod)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such module");
+
+  if (grub_dl_unref (mod) <= 0)
+    grub_dl_unload (mod);
+
+  return 0;
+}
+
+/* lsmod */
+static grub_err_t
+grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)),
+                    int argc __attribute__ ((unused)),
+                    char *argv[] __attribute__ ((unused)))
+{
+  auto int print_module (grub_dl_t mod);
+
+  int print_module (grub_dl_t mod)
+    {
+      grub_dl_dep_t dep;
+
+      grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count);
+      for (dep = mod->dep; dep; dep = dep->next)
+       {
+         if (dep != mod->dep)
+           grub_putchar (',');
+
+         grub_printf ("%s", dep->mod->name);
+       }
+      grub_putchar ('\n');
+
+      return 0;
+    }
+
+  grub_printf ("Name\tRef Count\tDependencies\n");
+  grub_dl_iterate (print_module);
+
+  return 0;
+}
+
+/* exit */
+static grub_err_t
+grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
+                   int argc __attribute__ ((unused)),
+                   char *argv[] __attribute__ ((unused)))
+{
+  grub_exit ();
+  return 0;
+}
+
+/* clear */
+static grub_err_t
+grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)),
+                  int argc __attribute__ ((unused)),
+                  char *argv[] __attribute__ ((unused)))
+{
+  grub_cls ();
+  return 0;
+}
+
+static grub_command_t cmd_cat, cmd_help, cmd_root;
+static grub_command_t cmd_dump, cmd_rmmod, cmd_lsmod, cmd_exit;
+static grub_command_t cmd_clear;
+
+GRUB_MOD_INIT(minicmd)
+{
+  cmd_cat =
+    grub_register_command ("cat", grub_mini_cmd_cat,
+                          N_("FILE"), N_("Show the contents of a file."));
+  cmd_help =
+    grub_register_command ("help", grub_mini_cmd_help,
+                          0, N_("Show this message."));
+  cmd_root =
+    grub_register_command ("root", grub_mini_cmd_root,
+                          N_("[DEVICE]"), N_("Set the root device."));
+  cmd_dump =
+    grub_register_command ("dump", grub_mini_cmd_dump,
+                          N_("ADDR"), N_("Dump memory."));
+  cmd_rmmod =
+    grub_register_command ("rmmod", grub_mini_cmd_rmmod,
+                          N_("MODULE"), N_("Remove a module."));
+  cmd_lsmod =
+    grub_register_command ("lsmod", grub_mini_cmd_lsmod,
+                          0, N_("Show loaded modules."));
+  cmd_exit =
+    grub_register_command ("exit", grub_mini_cmd_exit,
+                          0, N_("Exit from GRUB."));
+  cmd_clear =
+    grub_register_command ("clear", grub_mini_cmd_clear,
+                          0, N_("Clear the screen."));
+}
+
+GRUB_MOD_FINI(minicmd)
+{
+  grub_unregister_command (cmd_cat);
+  grub_unregister_command (cmd_help);
+  grub_unregister_command (cmd_root);
+  grub_unregister_command (cmd_dump);
+  grub_unregister_command (cmd_rmmod);
+  grub_unregister_command (cmd_lsmod);
+  grub_unregister_command (cmd_exit);
+  grub_unregister_command (cmd_clear);
+}
diff --git a/grub-core/commands/parttool.c b/grub-core/commands/parttool.c
new file mode 100644 (file)
index 0000000..d38a8a9
--- /dev/null
@@ -0,0 +1,332 @@
+/* parttool.c - common dispatcher and parser for partition operations */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  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/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/normal.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/parttool.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static struct grub_parttool *parts = 0;
+static int curhandle = 0;
+static grub_dl_t mymod;
+static char helpmsg[] =
+  "Perform COMMANDS on partition.\n"
+  "Use \"parttool PARTITION help\" for the list "
+  "of available commands.";
+
+int
+grub_parttool_register(const char *part_name,
+                      const grub_parttool_function_t func,
+                      const struct grub_parttool_argdesc *args)
+{
+  struct grub_parttool *cur;
+  int nargs = 0;
+
+  if (! parts)
+    grub_dl_ref (mymod);
+
+  cur = (struct grub_parttool *) grub_malloc (sizeof (struct grub_parttool));
+  cur->next = parts;
+  cur->name = grub_strdup (part_name);
+  cur->handle = curhandle++;
+  for (nargs = 0; args[nargs].name != 0; nargs++);
+  cur->nargs = nargs;
+  cur->args = (struct grub_parttool_argdesc *)
+    grub_malloc ((nargs + 1) * sizeof (struct grub_parttool_argdesc));
+  grub_memcpy (cur->args, args,
+              (nargs + 1) * sizeof (struct grub_parttool_argdesc));
+
+  cur->func = func;
+  parts = cur;
+  return cur->handle;
+}
+
+void
+grub_parttool_unregister (int handle)
+{
+  struct grub_parttool *prev = 0, *cur, *t;
+  for (cur = parts; cur; )
+    if (cur->handle == handle)
+      {
+       grub_free (cur->args);
+       grub_free (cur->name);
+       if (prev)
+         prev->next = cur->next;
+       else
+         parts = cur->next;
+       t = cur;
+       cur = cur->next;
+       grub_free (t);
+      }
+    else
+      {
+       prev = cur;
+       cur = cur->next;
+      }
+  if (! parts)
+    grub_dl_unref (mymod);
+}
+
+static grub_err_t
+grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
+                  int argc, char **args)
+{
+  grub_device_t dev;
+  struct grub_parttool *cur, *ptool;
+  int *parsed;
+  int i, j;
+  grub_err_t err = GRUB_ERR_NONE;
+
+  auto grub_err_t show_help (void);
+  grub_err_t show_help (void)
+  {
+    int found = 0;
+    for (cur = parts; cur; cur = cur->next)
+      if (grub_strcmp (dev->disk->partition->partmap->name, cur->name) == 0)
+       {
+         struct grub_parttool_argdesc *curarg;
+         found = 1;
+         for (curarg = cur->args; curarg->name; curarg++)
+           {
+             int spacing = 20;
+
+             spacing -= grub_strlen (curarg->name);
+             grub_printf ("%s", curarg->name);
+
+             switch (curarg->type)
+               {
+               case GRUB_PARTTOOL_ARG_BOOL:
+                 grub_printf ("+/-");
+                 spacing -= 3;
+                 break;
+
+               case GRUB_PARTTOOL_ARG_VAL:
+                 grub_printf ("=VAL");
+                 spacing -= 4;
+                 break;
+
+                   case GRUB_PARTTOOL_ARG_END:
+                     break;
+               }
+             while (spacing-- > 0)
+               grub_printf (" ");
+             grub_printf ("%s\n", curarg->desc);
+           }
+       }
+    if (! found)
+      grub_printf ("Sorry no parttool is available for %s\n",
+                  dev->disk->partition->partmap->name);
+    return GRUB_ERR_NONE;
+  }
+
+  if (argc < 1)
+    {
+      grub_printf ("%s\n", helpmsg);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few arguments");
+    }
+
+  if (args[0][0] == '(' && args[0][grub_strlen (args[0]) - 1] == ')')
+    {
+      args[0][grub_strlen (args[0]) - 1] = 0;
+      dev = grub_device_open (args[0] + 1);
+      args[0][grub_strlen (args[0]) - 1] = ')';
+    }
+  else
+    dev = grub_device_open (args[0]);
+
+  if (! dev)
+    return grub_errno;
+
+  if (! dev->disk)
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a disk");
+    }
+
+  if (! dev->disk->partition)
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a partition");
+    }
+
+  /* Load modules. */
+#if defined(GRUB_MACHINE_EMU)
+  {
+    const char *prefix;
+    prefix = grub_env_get ("prefix");
+    if (prefix)
+      {
+       char *filename;
+
+       filename = grub_xasprintf ("%s/parttool.lst", prefix);
+       if (filename)
+         {
+           grub_file_t file;
+
+           file = grub_file_open (filename);
+           if (file)
+             {
+               char *buf = 0;
+               for (;; grub_free(buf))
+                 {
+                   char *p, *name;
+
+                   buf = grub_file_getline (file);
+
+                   if (! buf)
+                     break;
+
+                   name = buf;
+
+                   if (! grub_isgraph (name[0]))
+                     continue;
+
+                   p = grub_strchr (name, ':');
+                   if (! p)
+                     continue;
+
+                   *p = '\0';
+                   while (*++p == ' ')
+                     ;
+
+                   if (! grub_isgraph (*p))
+                     continue;
+
+                   if (grub_strcmp (name, dev->disk->partition->partmap->name)
+                       != 0)
+                     continue;
+
+                   grub_dl_load (p);
+                 }
+
+               grub_file_close (file);
+             }
+
+           grub_free (filename);
+         }
+      }
+    /* Ignore errors.  */
+    grub_errno = GRUB_ERR_NONE;
+  }
+#endif
+
+  if (argc == 1)
+    return show_help ();
+
+  for (i = 1; i < argc; i++)
+    if (grub_strcmp (args[i], "help") == 0)
+      return show_help ();
+
+  parsed = (int *) grub_zalloc (argc * sizeof (int));
+
+  for (i = 1; i < argc; i++)
+    if (! parsed[i])
+      {
+       struct grub_parttool_argdesc *curarg;
+       struct grub_parttool_args *pargs;
+       for (cur = parts; cur; cur = cur->next)
+         if (grub_strcmp (dev->disk->partition->partmap->name, cur->name) == 0)
+           {
+             for (curarg = cur->args; curarg->name; curarg++)
+               if (grub_strncmp (curarg->name, args[i],
+                                 grub_strlen (curarg->name)) == 0
+                   && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL
+                        && (args[i][grub_strlen (curarg->name)] == '+'
+                            || args[i][grub_strlen (curarg->name)] == '-'
+                            || args[i][grub_strlen (curarg->name)] == 0))
+                       || (curarg->type == GRUB_PARTTOOL_ARG_VAL
+                           && args[i][grub_strlen (curarg->name)] == '=')))
+
+                 break;
+             if (curarg->name)
+               break;
+           }
+       if (! cur)
+         return grub_error (GRUB_ERR_BAD_ARGUMENT, "unrecognised argument %s",
+                            args[i]);
+       ptool = cur;
+       pargs = (struct grub_parttool_args *)
+         grub_zalloc (ptool->nargs * sizeof (struct grub_parttool_args));
+       for (j = i; j < argc; j++)
+         if (! parsed[j])
+           {
+             for (curarg = ptool->args; curarg->name; curarg++)
+               if (grub_strncmp (curarg->name, args[i],
+                                  grub_strlen (curarg->name)) == 0
+                   && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL
+                        && (args[j][grub_strlen (curarg->name)] == '+'
+                            || args[j][grub_strlen (curarg->name)] == '-'
+                            || args[j][grub_strlen (curarg->name)] == 0))
+                       || (curarg->type == GRUB_PARTTOOL_ARG_VAL
+                           && args[j][grub_strlen (curarg->name)] == '=')))
+                 {
+                   parsed[j] = 1;
+                   pargs[curarg - ptool->args].set = 1;
+                   switch (curarg->type)
+                     {
+                     case GRUB_PARTTOOL_ARG_BOOL:
+                       pargs[curarg - ptool->args].bool
+                         = (args[j][grub_strlen (curarg->name)] != '-');
+                       break;
+
+                     case GRUB_PARTTOOL_ARG_VAL:
+                       pargs[curarg - ptool->args].str
+                         = (args[j] + grub_strlen (curarg->name) + 1);
+                       break;
+
+                     case GRUB_PARTTOOL_ARG_END:
+                       break;
+                     }
+                 }
+           }
+
+       err = ptool->func (dev, pargs);
+       grub_free (pargs);
+       if (err)
+         break;
+      }
+
+  grub_free (parsed);
+  grub_device_close (dev);
+  return err;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(parttool)
+{
+  mymod = mod;
+  cmd = grub_register_command ("parttool", grub_cmd_parttool,
+                              N_("PARTITION COMMANDS"),
+                              helpmsg);
+}
+
+GRUB_MOD_FINI(parttool)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/password.c b/grub-core/commands/password.c
new file mode 100644 (file)
index 0000000..0428525
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/auth.h>
+#include <grub/crypto.h>
+#include <grub/list.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/i18n.h>
+
+static grub_dl_t my_mod;
+
+static grub_err_t
+check_password (const char *user, const char *entered,
+               void *password)
+{
+  if (grub_crypto_memcmp (entered, password, GRUB_AUTH_MAX_PASSLEN) != 0)
+    return GRUB_ACCESS_DENIED;
+
+  grub_auth_authenticate (user);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
+                  int argc, char **args)
+{
+  grub_err_t err;
+  char *pass;
+  int copylen;
+
+  if (argc != 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments expected");
+
+  pass = grub_zalloc (GRUB_AUTH_MAX_PASSLEN);
+  if (!pass)
+    return grub_errno;
+  copylen = grub_strlen (args[1]);
+  if (copylen >= GRUB_AUTH_MAX_PASSLEN)
+    copylen = GRUB_AUTH_MAX_PASSLEN - 1;
+  grub_memcpy (pass, args[1], copylen);
+
+  err = grub_auth_register_authentication (args[0], check_password, pass);
+  if (err)
+    {
+      grub_free (pass);
+      return err;
+    }
+  grub_dl_ref (my_mod);
+  return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd;
+\f
+GRUB_MOD_INIT(password)
+{
+  my_mod = mod;
+  cmd = grub_register_command ("password", grub_cmd_password,
+                              N_("USER PASSWORD"),
+                              N_("Set user password (plaintext). "
+                              "Unrecommended and insecure."));
+}
+
+GRUB_MOD_FINI(password)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/password_pbkdf2.c b/grub-core/commands/password_pbkdf2.c
new file mode 100644 (file)
index 0000000..6886987
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/auth.h>
+#include <grub/crypto.h>
+#include <grub/list.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/i18n.h>
+
+static grub_dl_t my_mod;
+
+struct pbkdf2_password
+{
+  grub_uint8_t *salt;
+  grub_size_t saltlen;
+  unsigned int c;
+  grub_uint8_t *expected;
+  grub_size_t buflen;
+};
+
+static grub_err_t
+check_password (const char *user, const char *entered, void *pin)
+{
+  grub_uint8_t *buf;
+  struct pbkdf2_password *pass = pin;
+  gcry_err_code_t err;
+
+  buf = grub_malloc (pass->buflen);
+  if (!buf)
+    return grub_crypto_gcry_error (GPG_ERR_OUT_OF_MEMORY);
+
+  err = grub_crypto_pbkdf2 (GRUB_MD_SHA512, (grub_uint8_t *) entered,
+                           grub_strlen (entered),
+                           pass->salt, pass->saltlen, pass->c,
+                           buf, pass->buflen);
+  if (err)
+    {
+      grub_free (buf);
+      return grub_crypto_gcry_error (err);
+    }
+
+  if (grub_crypto_memcmp (buf, pass->expected, pass->buflen) != 0)
+    return GRUB_ACCESS_DENIED;
+
+  grub_auth_authenticate (user);
+
+  return GRUB_ERR_NONE;
+}
+
+static inline int
+hex2val (char hex)
+{
+  if ('0' <= hex && hex <= '9')
+    return hex - '0';
+  if ('a' <= hex && hex <= 'f')
+    return hex - 'a' + 10;
+  if ('A' <= hex && hex <= 'F')
+    return hex - 'A' + 10;
+  return -1;
+}
+
+static grub_err_t
+grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
+                  int argc, char **args)
+{
+  grub_err_t err;
+  char *ptr, *ptr2;
+  grub_uint8_t *ptro;
+  struct pbkdf2_password *pass;
+
+  if (argc != 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Two arguments expected.");
+
+  if (grub_memcmp (args[1], "grub.pbkdf2.sha512.",
+                  sizeof ("grub.pbkdf2.sha512.") - 1) != 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Incorrect PBKDF2 password.");
+
+  ptr = args[1] + sizeof ("grub.pbkdf2.sha512.") - 1;
+
+  pass = grub_malloc (sizeof (*pass));
+  if (!pass)
+    return grub_errno;
+
+  pass->c = grub_strtoul (ptr, &ptr, 0);
+  if (*ptr != '.')
+    {
+      grub_free (pass);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "Incorrect PBKDF2 password.");
+    }
+  ptr++;
+
+  ptr2 = grub_strchr (ptr, '.');
+  if (!ptr2 || ((ptr2 - ptr) & 1) || grub_strlen (ptr2 + 1) & 1)
+    {
+      grub_free (pass);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "Incorrect PBKDF2 password.");
+    }
+
+  pass->saltlen = (ptr2 - ptr) >> 1;
+  pass->buflen = grub_strlen (ptr2 + 1) >> 1;
+  ptro = pass->salt = grub_malloc (pass->saltlen);
+  if (!ptro)
+    {
+      grub_free (pass);
+      return grub_errno;
+    }
+  while (ptr < ptr2)
+    {
+      int hex1, hex2;
+      hex1 = hex2val (*ptr);
+      ptr++;
+      hex2 = hex2val (*ptr);
+      ptr++;
+      if (hex1 < 0 || hex2 < 0)
+       {
+         grub_free (pass->salt);
+         grub_free (pass);
+         return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                            "Incorrect PBKDF2 password.");
+       }
+
+      *ptro = (hex1 << 4) | hex2;
+      ptro++;
+    }
+
+  ptro = pass->expected = grub_malloc (pass->buflen);
+  if (!ptro)
+    {
+      grub_free (pass->salt);
+      grub_free (pass);
+      return grub_errno;
+    }
+  ptr = ptr2 + 1;
+  ptr2 += grub_strlen (ptr2); 
+  while (ptr < ptr2)
+    {
+      int hex1, hex2;
+      hex1 = hex2val (*ptr);
+      ptr++;
+      hex2 = hex2val (*ptr);
+      ptr++;
+      if (hex1 < 0 || hex2 < 0)
+       {
+         grub_free (pass->expected);
+         grub_free (pass->salt);
+         grub_free (pass);
+         return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                            "Incorrect PBKDF2 password.");
+       }
+
+      *ptro = (hex1 << 4) | hex2;
+      ptro++;
+    }
+
+  err = grub_auth_register_authentication (args[0], check_password, pass);
+  if (err)
+    {
+      grub_free (pass);
+      return err;
+    }
+  grub_dl_ref (my_mod);
+  return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd;
+\f
+GRUB_MOD_INIT(password_pbkdf2)
+{
+  my_mod = mod;
+  cmd = grub_register_command ("password_pbkdf2", grub_cmd_password,
+                              N_("USER PBKDF2_PASSWORD"),
+                              N_("Set user password (PBKDF2). "));
+}
+
+GRUB_MOD_FINI(password_pbkdf2)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/probe.c b/grub-core/commands/probe.c
new file mode 100644 (file)
index 0000000..c2cc599
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/net.h>
+#include <grub/fs.h>
+#include <grub/file.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {"set",             's', GRUB_ARG_OPTION_OPTIONAL,
+     N_("Set a variable to return value."), "VAR", ARG_TYPE_STRING},
+    {"driver",         'd', 0, N_("Determine driver."), 0, 0},
+    {"partmap",                'p', 0, N_("Determine partition map type."), 0, 0},
+    {"fs",             'f', 0, N_("Determine filesystem type."), 0, 0},
+    {"fs-uuid",                'u', 0, N_("Determine filesystem UUID."), 0, 0},
+    {"label",          'l', 0, N_("Determine filesystem label."), 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static grub_err_t
+grub_cmd_probe (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  grub_device_t dev;
+  grub_fs_t fs;
+  char *ptr;
+  grub_err_t err;
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
+
+  ptr = args[0] + grub_strlen (args[0]) - 1;
+  if (args[0][0] == '(' && *ptr == ')')
+    {
+      *ptr = 0;
+      dev = grub_device_open (args[0] + 1);
+      *ptr = ')';
+    }
+  else
+    dev = grub_device_open (args[0]);
+  if (! dev)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "couldn't open device");
+
+  if (state[1].set)
+    {
+      const char *val = "none";
+      if (dev->net)
+       val = dev->net->dev->name;
+      if (dev->disk)
+       val = dev->disk->dev->name;
+      if (state[0].set)
+       grub_env_set (state[0].arg, val);
+      else
+       grub_printf ("%s", val);
+      return GRUB_ERR_NONE;
+    }
+  if (state[2].set)
+    {
+      const char *val = "none";
+      if (dev->disk && dev->disk->partition)
+       val = dev->disk->partition->partmap->name;
+      if (state[0].set)
+       grub_env_set (state[0].arg, val);
+      else
+       grub_printf ("%s", val);
+      return GRUB_ERR_NONE;
+    }
+  fs = grub_fs_probe (dev);
+  if (! fs)
+    return grub_error (GRUB_ERR_UNKNOWN_FS, "unrecognised fs");
+  if (state[3].set)
+    {
+      if (state[0].set)
+       grub_env_set (state[0].arg, fs->name);
+      else
+       grub_printf ("%s", fs->name);
+      return GRUB_ERR_NONE;
+    }
+  if (state[4].set)
+    {
+      char *uuid;
+      if (! fs->uuid)
+       return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                          "uuid for this FS isn't supported yet");
+      err = fs->uuid (dev, &uuid);
+      if (err)
+       return err;
+      if (! uuid)
+       return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                          "uuid for this FS isn't supported yet");
+
+      if (state[0].set)
+       grub_env_set (state[0].arg, uuid);
+      else
+       grub_printf ("%s", uuid);
+      grub_free (uuid);
+      return GRUB_ERR_NONE;
+    }
+  if (state[5].set)
+    {
+      char *label;
+      if (! fs->label)
+       return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                          "label for this FS isn't supported yet");
+      err = fs->label (dev, &label);
+      if (err)
+       return err;
+      if (! label)
+       return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                          "uuid for this FS isn't supported yet");
+
+      if (state[0].set)
+       grub_env_set (state[0].arg, label);
+      else
+       grub_printf ("%s", label);
+      grub_free (label);
+      return GRUB_ERR_NONE;
+    }
+  return grub_error (GRUB_ERR_BAD_ARGUMENT, "unrecognised target");
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT (probe)
+{
+  cmd = grub_register_extcmd ("probe", grub_cmd_probe, GRUB_COMMAND_FLAG_BOTH,
+                             N_("[DEVICE]"),
+                             N_("Retrieve device info."), options);
+}
+
+GRUB_MOD_FINI (probe)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/read.c b/grub-core/commands/read.c
new file mode 100644 (file)
index 0000000..8a7c4a0
--- /dev/null
@@ -0,0 +1,90 @@
+/* read.c - Command to read variables from user.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/term.h>
+#include <grub/types.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static char *
+grub_getline (void)
+{
+  int i;
+  char *line;
+  char *tmp;
+  char c;
+
+  i = 0;
+  line = grub_malloc (1 + i + sizeof('\0'));
+  if (! line)
+    return NULL;
+
+  while (1)
+    {
+      c = grub_getkey ();
+      if ((c == '\n') || (c == '\r'))
+       break;
+
+      line[i] = c;
+      if (grub_isprint (c))
+       grub_putchar (c);
+      i++;
+      tmp = grub_realloc (line, 1 + i + sizeof('\0'));
+      if (! tmp)
+       {
+         grub_free (line);
+         return NULL;
+       }
+      line = tmp;
+    }
+  line[i] = '\0';
+
+  return line;
+}
+
+static grub_err_t
+grub_cmd_read (grub_command_t cmd __attribute__ ((unused)), int argc, char **args)
+{
+  char *line = grub_getline ();
+  if (! line)
+    return grub_errno;
+  if (argc > 0)
+    grub_env_set (args[0], line);
+
+  grub_free (line);
+  return 0;
+}
+
+static grub_command_t cmd;
+\f
+GRUB_MOD_INIT(read)
+{
+  cmd = grub_register_command ("read", grub_cmd_read,
+                              N_("[ENVVAR]"),
+                              N_("Set variable with user input."));
+}
+
+GRUB_MOD_FINI(read)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/reboot.c b/grub-core/commands/reboot.c
new file mode 100644 (file)
index 0000000..eedd53c
--- /dev/null
@@ -0,0 +1,45 @@
+/* reboot.c - command to reboot the computer.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/command.h>
+#include <grub/misc.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+grub_cmd_reboot (grub_command_t cmd __attribute__ ((unused)),
+                int argc __attribute__ ((unused)),
+                char **args __attribute__ ((unused)))
+{
+  grub_reboot ();
+  return 0;
+}
+
+static grub_command_t cmd;
+\f
+GRUB_MOD_INIT(reboot)
+{
+  cmd = grub_register_command ("reboot", grub_cmd_reboot,
+                              0, N_("Reboot the computer."));
+}
+
+GRUB_MOD_FINI(reboot)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/regexp.c b/grub-core/commands/regexp.c
new file mode 100644 (file)
index 0000000..e8e8243
--- /dev/null
@@ -0,0 +1,80 @@
+/* regexp.c -- The regexp command.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+#include <regex.h>
+
+static grub_err_t
+grub_cmd_regexp (grub_command_t cmd __attribute__ ((unused)),
+                int argc, char **args)
+{
+  int argn = 0;
+  int matches = 0;
+  regex_t regex;
+  int ret;
+  grub_size_t s;
+  char *comperr;
+  grub_err_t err;
+
+  if (argc != 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "2 arguments expected");
+
+  ret = regcomp (&regex, args[0], RE_SYNTAX_GNU_AWK);
+  if (ret)
+    goto fail;
+
+  ret = regexec (&regex, args[1], 0, 0, 0);
+  if (!ret)
+    {
+      regfree (&regex);
+      return GRUB_ERR_NONE;
+    }
+
+ fail:
+  s = regerror (ret, &regex, 0, 0);
+  comperr = grub_malloc (s);
+  if (!comperr)
+    {
+      regfree (&regex);
+      return grub_errno;
+    }
+  regerror (ret, &regex, comperr, s);
+  err = grub_error (GRUB_ERR_TEST_FAILURE, "%s", comperr);
+  regfree (&regex);
+  grub_free (comperr);
+  return err;
+}
+
+static grub_command_t cmd;
+\f
+GRUB_MOD_INIT(regexp)
+{
+  cmd = grub_register_command ("regexp", grub_cmd_regexp,
+                              N_("REGEXP STRING"),
+                              N_("Test if REGEXP matches STRING."));
+}
+
+GRUB_MOD_FINI(regexp)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
new file mode 100644 (file)
index 0000000..71267b1
--- /dev/null
@@ -0,0 +1,174 @@
+/* search.c - search devices based on a file or a filesystem label */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/device.h>
+#include <grub/file.h>
+#include <grub/env.h>
+#include <grub/command.h>
+#include <grub/search.h>
+#include <grub/i18n.h>
+
+void
+FUNC_NAME (const char *key, const char *var, int no_floppy)
+{
+  int count = 0;
+  grub_fs_autoload_hook_t saved_autoload;
+
+  auto int iterate_device (const char *name);
+  int iterate_device (const char *name)
+  {
+    int found = 0;
+
+    /* Skip floppy drives when requested.  */
+    if (no_floppy &&
+       name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
+      return 0;
+
+#ifdef DO_SEARCH_FILE
+      {
+       char *buf;
+       grub_file_t file;
+
+       buf = grub_xasprintf ("(%s)%s", name, key);
+       if (! buf)
+         return 1;
+
+       file = grub_file_open (buf);
+       if (file)
+         {
+           found = 1;
+           grub_file_close (file);
+         }
+       grub_free (buf);
+      }
+#else
+      {
+       /* SEARCH_FS_UUID or SEARCH_LABEL */
+       grub_device_t dev;
+       grub_fs_t fs;
+       char *quid;
+
+       dev = grub_device_open (name);
+       if (dev)
+         {
+           fs = grub_fs_probe (dev);
+
+#ifdef DO_SEARCH_FS_UUID
+#define compare_fn grub_strcasecmp
+#define read_fn uuid
+#else
+#define compare_fn grub_strcmp
+#define read_fn label
+#endif
+
+           if (fs && fs->read_fn)
+             {
+               fs->read_fn (dev, &quid);
+
+               if (grub_errno == GRUB_ERR_NONE && quid)
+                 {
+                   if (compare_fn (quid, key) == 0)
+                     found = 1;
+
+                   grub_free (quid);
+                 }
+             }
+
+           grub_device_close (dev);
+         }
+      }
+#endif
+
+    if (found)
+      {
+       count++;
+       if (var)
+         grub_env_set (var, name);
+       else
+         grub_printf (" %s", name);
+      }
+
+    grub_errno = GRUB_ERR_NONE;
+    return (found && var);
+  }
+
+  /* First try without autoloading if we're setting variable. */
+  if (var)
+    {
+      saved_autoload = grub_fs_autoload_hook;
+      grub_fs_autoload_hook = 0;
+      grub_device_iterate (iterate_device);
+
+      /* Restore autoload hook.  */
+      grub_fs_autoload_hook = saved_autoload;
+
+      /* Retry with autoload if nothing found.  */
+      if (grub_errno == GRUB_ERR_NONE && count == 0)
+       grub_device_iterate (iterate_device);
+    }
+  else
+    grub_device_iterate (iterate_device);
+
+  if (grub_errno == GRUB_ERR_NONE && count == 0)
+    grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key);
+}
+
+static grub_err_t
+grub_cmd_do_search (grub_command_t cmd __attribute__ ((unused)), int argc,
+                   char **args)
+{
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no argument specified");
+
+  FUNC_NAME (args[0], argc == 1 ? 0 : args[1], 0);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd;
+
+#ifdef DO_SEARCH_FILE
+GRUB_MOD_INIT(search_fs_file)
+#elif defined (DO_SEARCH_FS_UUID)
+GRUB_MOD_INIT(search_fs_uuid)
+#else
+GRUB_MOD_INIT(search_label)
+#endif
+{
+  cmd =
+    grub_register_command (COMMAND_NAME, grub_cmd_do_search,
+                          N_("NAME [VARIABLE]"),
+                          HELP_MESSAGE);
+}
+
+#ifdef DO_SEARCH_FILE
+GRUB_MOD_FINI(search_fs_file)
+#elif defined (DO_SEARCH_FS_UUID)
+GRUB_MOD_FINI(search_fs_uuid)
+#else
+GRUB_MOD_FINI(search_label)
+#endif
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/search_file.c b/grub-core/commands/search_file.c
new file mode 100644 (file)
index 0000000..73ce89c
--- /dev/null
@@ -0,0 +1,6 @@
+#define DO_SEARCH_FILE 1
+#define FUNC_NAME grub_search_fs_file
+#define COMMAND_NAME "search.file"
+#define SEARCH_TARGET "file"
+#define HELP_MESSAGE N_("Search devices by file. If VARIABLE is specified, the first device found is set to a variable.")
+#include "search.c"
diff --git a/grub-core/commands/search_label.c b/grub-core/commands/search_label.c
new file mode 100644 (file)
index 0000000..ee9c792
--- /dev/null
@@ -0,0 +1,6 @@
+#define DO_SEARCH_FS_LABEL 1
+#define FUNC_NAME grub_search_label
+#define COMMAND_NAME "search.fs_label"
+#define SEARCH_TARGET "filesystem label"
+#define HELP_MESSAGE N_("Search devices by label. If VARIABLE is specified, the first device found is set to a variable.")
+#include "search.c"
diff --git a/grub-core/commands/search_uuid.c b/grub-core/commands/search_uuid.c
new file mode 100644 (file)
index 0000000..52f8381
--- /dev/null
@@ -0,0 +1,6 @@
+#define DO_SEARCH_FS_UUID 1
+#define FUNC_NAME grub_search_fs_uuid
+#define COMMAND_NAME "search.fs_uuid"
+#define SEARCH_TARGET "filesystem UUID"
+#define HELP_MESSAGE N_("Search devices by UUID. If VARIABLE is specified, the first device found is set to a variable.")
+#include "search.c"
diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c
new file mode 100644 (file)
index 0000000..2891d85
--- /dev/null
@@ -0,0 +1,95 @@
+/* search.c - search devices based on a file or a filesystem label */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/env.h>
+#include <grub/extcmd.h>
+#include <grub/search.h>
+#include <grub/i18n.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {"file",           'f', 0, N_("Search devices by a file."), 0, 0},
+    {"label",          'l', 0, N_("Search devices by a filesystem label."),
+     0, 0},
+    {"fs-uuid",                'u', 0, N_("Search devices by a filesystem UUID."),
+     0, 0},
+    {"set",            's', GRUB_ARG_OPTION_OPTIONAL,
+     N_("Set a variable to the first device found."), "VAR", ARG_TYPE_STRING},
+    {"no-floppy",      'n', 0, N_("Do not probe any floppy drive."), 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+enum options
+  {
+    SEARCH_FILE,
+    SEARCH_LABEL,
+    SEARCH_FS_UUID,
+    SEARCH_SET,
+    SEARCH_NO_FLOPPY,
+ };
+
+static grub_err_t
+grub_cmd_search (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  const char *var = 0;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no argument specified");
+
+  if (state[SEARCH_SET].set)
+    var = state[SEARCH_SET].arg ? state[SEARCH_SET].arg : "root";
+
+  if (state[SEARCH_LABEL].set)
+    grub_search_label (args[0], var, state[SEARCH_NO_FLOPPY].set);
+  else if (state[SEARCH_FS_UUID].set)
+    grub_search_fs_uuid (args[0], var, state[SEARCH_NO_FLOPPY].set);
+  else if (state[SEARCH_FILE].set)
+    grub_search_fs_file (args[0], var, state[SEARCH_NO_FLOPPY].set);
+  else
+    return grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type");
+
+  return grub_errno;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(search)
+{
+  cmd =
+    grub_register_extcmd ("search", grub_cmd_search,
+                         GRUB_COMMAND_FLAG_BOTH,
+                         N_("search [-f|-l|-u|-s|-n] NAME"),
+                         N_("Search devices by file, filesystem label"
+                            " or filesystem UUID."
+                            " If --set is specified, the first device found is"
+                            " set to a variable. If no variable name is"
+                            " specified, \"root\" is used."),
+                         options);
+}
+
+GRUB_MOD_FINI(search)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c
new file mode 100644 (file)
index 0000000..fbc7c21
--- /dev/null
@@ -0,0 +1,341 @@
+/* lspci.c - List PCI devices.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/pci.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+#include <grub/env.h>
+#include <grub/mm.h>
+#include <grub/i18n.h>
+
+struct pci_register
+{
+  const char *name;
+  grub_uint16_t addr;
+  unsigned size;
+};
+
+struct pci_register pci_registers[] =
+  {
+    {"VENDOR_ID",       GRUB_PCI_REG_VENDOR      , 2},
+    {"DEVICE_ID",       GRUB_PCI_REG_DEVICE      , 2},
+    {"COMMAND",         GRUB_PCI_REG_COMMAND     , 2},
+    {"STATUS",          GRUB_PCI_REG_STATUS      , 2},
+    {"REVISION",        GRUB_PCI_REG_REVISION    , 1},
+    {"CLASS_PROG",      GRUB_PCI_REG_CLASS + 1   , 1},
+    {"CLASS_DEVICE",    GRUB_PCI_REG_CLASS + 2   , 2},
+    {"CACHE_LINE_SIZE", GRUB_PCI_REG_CACHELINE   , 1},
+    {"LATENCY_TIMER",   GRUB_PCI_REG_LAT_TIMER   , 1},
+    {"HEADER_TYPE",     GRUB_PCI_REG_HEADER_TYPE , 1},
+    {"BIST",            GRUB_PCI_REG_BIST        , 1},
+    {"BASE_ADDRESS_0",  GRUB_PCI_REG_ADDRESS_REG0, 4},
+    {"BASE_ADDRESS_1",  GRUB_PCI_REG_ADDRESS_REG1, 4},
+    {"BASE_ADDRESS_2",  GRUB_PCI_REG_ADDRESS_REG2, 4},
+    {"BASE_ADDRESS_3",  GRUB_PCI_REG_ADDRESS_REG3, 4},
+    {"BASE_ADDRESS_4",  GRUB_PCI_REG_ADDRESS_REG4, 4},
+    {"BASE_ADDRESS_5",  GRUB_PCI_REG_ADDRESS_REG5, 4},
+    {"CARDBUS_CIS",     GRUB_PCI_REG_CIS_POINTER , 4},
+    {"SUBVENDOR_ID",    GRUB_PCI_REG_SUBVENDOR   , 2},
+    {"SUBSYSTEM_ID",    GRUB_PCI_REG_SUBSYSTEM   , 2},
+    {"ROM_ADDRESS",     GRUB_PCI_REG_ROM_ADDRESS , 4},
+    {"CAP_POINTER",     GRUB_PCI_REG_CAP_POINTER , 1},
+    {"INTERRUPT_LINE",  GRUB_PCI_REG_IRQ_LINE    , 1},
+    {"INTERRUPT_PIN",   GRUB_PCI_REG_IRQ_PIN     , 1},
+    {"MIN_GNT",         GRUB_PCI_REG_MIN_GNT     , 1},
+    {"MAX_LAT",         GRUB_PCI_REG_MIN_GNT     , 1},
+  };
+
+static const struct grub_arg_option options[] =
+  {
+    {0, 'd', 0, "Select device by vendor and device IDs.",
+     "[vendor]:[device]", ARG_TYPE_STRING},
+    {0, 's', 0, "Select device by its position on the bus.",
+     "[bus]:[slot][.func]", ARG_TYPE_STRING},
+    {0, 'v', 0, "Save read value into variable VARNAME.",
+     "VARNAME", ARG_TYPE_STRING},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static grub_uint32_t pciid_check_mask, pciid_check_value;
+static int bus, device, function;
+static int check_bus, check_device, check_function;
+static grub_uint32_t write_mask, regwrite;
+static int regsize;
+static grub_uint16_t regaddr;
+static const char *varname;
+
+static int NESTED_FUNC_ATTR
+grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid)
+{
+  grub_uint32_t regval = 0;
+  grub_pci_address_t addr;
+
+  if ((pciid & pciid_check_mask) != pciid_check_value)
+    return 0;
+
+  if (check_bus && grub_pci_get_bus (dev) != bus)
+    return 0;
+
+  if (check_device && grub_pci_get_device (dev) != device)
+    return 0;
+
+  if (check_function && grub_pci_get_function (dev) != device)
+    return 0;
+
+  addr = grub_pci_make_address (dev, regaddr);
+
+  switch (regsize)
+    {
+    case 1:
+      regval = grub_pci_read_byte (addr);
+      break;
+
+    case 2:
+      regval = grub_pci_read_word (addr);
+      break;
+
+    case 4:
+      regval = grub_pci_read (addr);
+      break;
+    }
+
+  if (varname)
+    {
+      char buf[sizeof ("XXXXXXXX")];
+      grub_snprintf (buf, sizeof (buf), "%x", regval);
+      grub_env_set (varname, buf);
+      return 1;
+    }
+
+  if (!write_mask)
+    {
+      grub_printf ("Register %x of %d:%d.%d is %x\n", regaddr,
+                  grub_pci_get_bus (dev),
+                  grub_pci_get_device (dev),
+                  grub_pci_get_function (dev),
+                  regval);
+      return 0;
+    }
+
+  regval = (regval & ~write_mask) | regwrite;
+
+  switch (regsize)
+    {
+    case 1:
+      grub_pci_write_byte (addr, regval);
+      break;
+
+    case 2:
+      grub_pci_write_word (addr, regval);
+      break;
+
+    case 4:
+      grub_pci_write (addr, regval);
+      break;
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv)
+{
+  const char *ptr;
+  unsigned i;
+
+  pciid_check_value = 0;
+  pciid_check_mask = 0;
+
+  if (cmd->state[0].set)
+    {
+      ptr = cmd->state[0].arg;
+      pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff);
+      if (grub_errno == GRUB_ERR_BAD_NUMBER)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         ptr = cmd->state[0].arg;
+       }
+      else
+       pciid_check_mask |= 0xffff;
+      if (grub_errno)
+       return grub_errno;
+      if (*ptr != ':')
+       return grub_error (GRUB_ERR_BAD_ARGUMENT, "Colon expected.");
+      ptr++;
+      pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff)
+       << 16;
+      if (grub_errno == GRUB_ERR_BAD_NUMBER)
+       grub_errno = GRUB_ERR_NONE;
+      else
+       pciid_check_mask |= 0xffff0000;
+    }
+
+  pciid_check_value &= pciid_check_mask;
+
+  check_bus = check_device = check_function = 0;
+
+  if (cmd->state[1].set)
+    {
+      const char *optr;
+      
+      ptr = cmd->state[1].arg;
+      optr = ptr;
+      bus = grub_strtoul (ptr, (char **) &ptr, 16);
+      if (grub_errno == GRUB_ERR_BAD_NUMBER)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         ptr = optr;
+       }
+      else
+       check_bus = 1;
+      if (grub_errno)
+       return grub_errno;
+      if (*ptr != ':')
+       return grub_error (GRUB_ERR_BAD_ARGUMENT, "Colon expected.");
+      ptr++;
+      optr = ptr;
+      device = grub_strtoul (ptr, (char **) &ptr, 16);
+      if (grub_errno == GRUB_ERR_BAD_NUMBER)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         ptr = optr;
+       }
+      else
+       check_device = 1;
+      if (*ptr == '.')
+       {
+         ptr++;
+         function = grub_strtoul (ptr, (char **) &ptr, 16);
+         if (grub_errno)
+           return grub_errno;
+         check_function = 1;
+       }
+    }
+
+  if (cmd->state[2].set)
+    varname = cmd->state[2].arg;
+  else
+    varname = NULL;
+
+  write_mask = 0;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Command expected.");
+
+  if (argc > 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Only one command is supported.");
+
+  ptr = argv[0];
+
+  for (i = 0; i < ARRAY_SIZE (pci_registers); i++)
+    {
+      if (grub_strncmp (ptr, pci_registers[i].name,
+                       grub_strlen (pci_registers[i].name)) == 0)
+       break;
+    }
+  if (i == ARRAY_SIZE (pci_registers))
+    {
+      regsize = 0;
+      regaddr = grub_strtoul (ptr, (char **) &ptr, 16);
+      if (grub_errno)
+       return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown register");
+    }
+  else
+    {
+      regaddr = pci_registers[i].addr;
+      regsize = pci_registers[i].size;
+      ptr += grub_strlen (pci_registers[i].name);
+    }
+
+  if (grub_errno)
+    return grub_errno;
+
+  if (*ptr == '+')
+    {
+      ptr++;
+      regaddr += grub_strtoul (ptr, (char **) &ptr, 16);
+      if (grub_errno)
+       return grub_errno;
+    }
+
+  if (grub_memcmp (ptr, ".L", sizeof (".L") - 1) == 0
+      || grub_memcmp (ptr, ".l", sizeof (".l") - 1) == 0)
+    {
+      regsize = 4;
+      ptr += sizeof (".l") - 1;
+    }
+  else if (grub_memcmp (ptr, ".W", sizeof (".W") - 1) == 0
+      || grub_memcmp (ptr, ".w", sizeof (".w") - 1) == 0)
+    {
+      regsize = 2;
+      ptr += sizeof (".w") - 1;
+    }
+  else if (grub_memcmp (ptr, ".B", sizeof (".B") - 1) == 0
+      || grub_memcmp (ptr, ".b", sizeof (".b") - 1) == 0)
+    {
+      regsize = 1;
+      ptr += sizeof (".b") - 1;
+    }
+
+  if (!regsize)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "Unknown register size.");
+
+  write_mask = 0;
+  if (*ptr == '=')
+    {
+      ptr++;
+      regwrite = grub_strtoul (ptr, (char **) &ptr, 16);
+      if (grub_errno)
+       return grub_errno;
+      write_mask = 0xffffffff;
+      if (*ptr == ':')
+       {
+         ptr++;
+         write_mask = grub_strtoul (ptr, (char **) &ptr, 16);
+         if (grub_errno)
+           return grub_errno;
+         write_mask = 0xffffffff;
+       }
+      regwrite &= write_mask;
+    }
+
+  if (write_mask && varname)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "Option -v isn't valid for writes.");
+
+  grub_pci_iterate (grub_setpci_iter);
+  return GRUB_ERR_NONE;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(setpci)
+{
+  cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, GRUB_COMMAND_FLAG_BOTH,
+                             N_("[-s POSITION] [-d DEVICE] [-v VAR] "
+                                "[REGISTER][=VALUE[:MASK]]"),
+                             N_("Manipulate PCI devices."), options);
+}
+
+GRUB_MOD_FINI(setpci)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/sleep.c b/grub-core/commands/sleep.c
new file mode 100644 (file)
index 0000000..ead2795
--- /dev/null
@@ -0,0 +1,113 @@
+/* sleep.c - Command to wait a specified number of seconds.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/term.h>
+#include <grub/time.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+
+static const struct grub_arg_option options[] =
+  {
+    {"verbose", 'v', 0, N_("Verbose countdown."), 0, 0},
+    {"interruptible", 'i', 0, N_("Interruptible with ESC."), 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static grub_uint16_t *pos;
+
+static void
+do_print (int n)
+{
+  grub_term_restore_pos (pos);
+  /* NOTE: Do not remove the trailing space characters.
+     They are required to clear the line.  */
+  grub_printf ("%d    ", n);
+}
+
+/* Based on grub_millisleep() from kern/generic/millisleep.c.  */
+static int
+grub_interruptible_millisleep (grub_uint32_t ms)
+{
+  grub_uint64_t start;
+
+  start = grub_get_time_ms ();
+
+  while (grub_get_time_ms () - start < ms)
+    if (grub_checkkey () >= 0 &&
+       GRUB_TERM_ASCII_CHAR (grub_getkey ()) == GRUB_TERM_ESC)
+      return 1;
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_sleep (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+  int n;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing operand");
+
+  n = grub_strtoul (args[0], 0, 10);
+
+  if (n == 0)
+    {
+      /* Either `0' or broken input.  */
+      return 0;
+    }
+
+  pos = grub_term_save_pos ();
+
+  for (; n; n--)
+    {
+      if (state[0].set)
+       do_print (n);
+
+      if (state[1].set)
+       {
+         if (grub_interruptible_millisleep (1000))
+           return 1;
+       }
+      else
+       grub_millisleep (1000);
+    }
+  if (state[0].set)
+    do_print (0);
+
+  return 0;
+}
+
+static grub_extcmd_t cmd;
+\f
+GRUB_MOD_INIT(sleep)
+{
+  cmd = grub_register_extcmd ("sleep", grub_cmd_sleep, GRUB_COMMAND_FLAG_BOTH,
+                             N_("NUMBER_OF_SECONDS"),
+                             N_("Wait for a specified number of seconds."),
+                             options);
+}
+
+GRUB_MOD_FINI(sleep)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/commands/terminal.c b/grub-core/commands/terminal.c
new file mode 100644 (file)
index 0000000..1129c39
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/command.h>
+#include <grub/term.h>
+#include <grub/i18n.h>
+#include <grub/misc.h>
+
+struct grub_term_autoload *grub_term_input_autoload = NULL;
+struct grub_term_autoload *grub_term_output_autoload = NULL;
+
+struct abstract_terminal
+{
+  struct abstract_terminal *next;
+  const char *name;
+  grub_err_t (*init) (void);
+  grub_err_t (*fini) (void);
+};
+
+static grub_err_t
+handle_command (int argc, char **args, struct abstract_terminal **enabled,
+               struct abstract_terminal **disabled,
+               struct grub_term_autoload *autoloads,
+               const char *active_str,
+               const char *available_str)
+{
+  int i;
+  struct abstract_terminal *term;
+  struct grub_term_autoload *aut;
+
+  if (argc == 0)
+    {
+      grub_puts_ (active_str);
+      for (term = *enabled; term; term = term->next)
+       grub_printf ("%s ", term->name);
+      grub_printf ("\n");
+      grub_puts_ (available_str);
+      for (term = *disabled; term; term = term->next)
+       grub_printf ("%s ", term->name);
+      /* This is quadratic but we don't expect mode than 30 terminal
+        modules ever.  */
+      for (aut = autoloads; aut; aut = aut->next)
+       {
+         for (term = *disabled; term; term = term->next)
+           if (grub_strcmp (term->name, aut->name) == 0)
+             break;
+         if (!term)
+           for (term = *enabled; term; term = term->next)
+             if (grub_strcmp (term->name, aut->name) == 0)
+               break;
+         if (!term)
+           grub_printf ("%s ", aut->name);
+       }
+      grub_printf ("\n");
+      return GRUB_ERR_NONE;
+    }
+  i = 0;
+
+  if (grub_strcmp (args[0], "--append") == 0
+      || grub_strcmp (args[0], "--remove") == 0)
+    i++;
+
+  if (i == argc)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
+
+  for (; i < argc; i++)
+    {
+      int again = 0;
+      while (1)
+       {
+         for (term = *disabled; term; term = term->next)
+           if (grub_strcmp (args[i], term->name) == 0)
+             break;
+         if (term == 0)
+           for (term = *enabled; term; term = term->next)
+             if (grub_strcmp (args[i], term->name) == 0)
+               break;
+         if (term)
+           break;
+         if (again)
+           return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
+                              args[i]);
+         for (aut = autoloads; aut; aut = aut->next)
+           if (grub_strcmp (args[i], aut->name) == 0)
+             {
+               grub_dl_t mod;
+               mod = grub_dl_load (aut->modname);
+               if (mod)
+                 grub_dl_ref (mod);
+               grub_errno = GRUB_ERR_NONE;
+               break;
+             }
+         if (!aut)
+           return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
+                              args[i]);
+         again = 1;
+       }
+    }
+
+  if (grub_strcmp (args[0], "--append") == 0)
+    {
+      for (i = 1; i < argc; i++)
+       {
+         for (term = *disabled; term; term = term->next)
+           if (grub_strcmp (args[i], term->name) == 0)
+             break;
+         if (term)
+           {
+              if (term->init && term->init () != GRUB_ERR_NONE)
+                return grub_errno;
+
+             grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
+             grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
+           }
+       }
+      return GRUB_ERR_NONE;
+    }
+
+  if (grub_strcmp (args[0], "--remove") == 0)
+    {
+      for (i = 1; i < argc; i++)
+       {
+         for (term = *enabled; term; term = term->next)
+           if (grub_strcmp (args[i], term->name) == 0)
+             break;
+         if (term)
+           {
+             if (!term->next && term == *enabled)
+               return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                                  "can't remove the last terminal");
+             grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
+             if (term->fini)
+               term->fini ();
+             grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
+           }
+       }
+      return GRUB_ERR_NONE;
+    }
+  for (i = 0; i < argc; i++)
+    {
+      for (term = *disabled; term; term = term->next)
+       if (grub_strcmp (args[i], term->name) == 0)
+         break;
+      if (term)
+       {
+         if (term->init && term->init () != GRUB_ERR_NONE)
+           return grub_errno;
+
+         grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
+         grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
+       }       
+    }
+  
+  {
+    struct abstract_terminal *next;
+    for (term = *enabled; term; term = next)
+      {
+       next = term->next;
+       for (i = 0; i < argc; i++)
+         if (grub_strcmp (args[i], term->name) == 0)
+           break;
+       if (i == argc)
+         {
+           if (!term->next && term == *enabled)
+             return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                                "can't remove the last terminal");
+           grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
+           if (term->fini)
+             term->fini ();
+           grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
+         }
+      }
+  }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
+                        int argc, char **args)
+{
+  (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, next);
+  (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, name);
+  (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, init);
+  (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, fini);
+  return handle_command (argc, args,
+                        (struct abstract_terminal **) &grub_term_inputs,
+                        (struct abstract_terminal **) &grub_term_inputs_disabled,
+                        grub_term_input_autoload,
+                        N_ ("Active input terminals:"),
+                        N_ ("Available input terminals:"));
+}
+
+static grub_err_t
+grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
+                         int argc, char **args)
+{
+  (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, next);
+  (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, name);
+  (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, init);
+  (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, fini);
+  return handle_command (argc, args, (struct abstract_terminal **) &grub_term_outputs,
+                        (struct abstract_terminal **) &grub_term_outputs_disabled,
+                        grub_term_output_autoload,
+                        N_ ("Active output terminals:"),
+                        N_ ("Available output terminals:"));
+}
+
+static grub_command_t cmd_terminal_input, cmd_terminal_output;
+
+GRUB_MOD_INIT(terminal)
+{
+  cmd_terminal_input =
+    grub_register_command ("terminal_input", grub_cmd_terminal_input,
+                          N_("[--append|--remove] "
+                             "[TERMINAL1] [TERMINAL2] ..."),
+                          N_("List or select an input terminal."));
+  cmd_terminal_output =
+    grub_register_command ("terminal_output", grub_cmd_terminal_output,
+                          N_("[--append|--remove] "
+                             "[TERMINAL1] [TERMINAL2] ..."),
+                          N_("List or select an output terminal."));
+}
+
+GRUB_MOD_FINI(terminal)
+{
+  grub_unregister_command (cmd_terminal_input);
+  grub_unregister_command (cmd_terminal_output);
+}
diff --git a/grub-core/commands/test.c b/grub-core/commands/test.c
new file mode 100644 (file)
index 0000000..6995165
--- /dev/null
@@ -0,0 +1,433 @@
+/* test.c -- The test command..  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/fs.h>
+#include <grub/device.h>
+#include <grub/file.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+/* A simple implementation for signed numbers. */
+static int
+grub_strtosl (char *arg, char **end, int base)
+{
+  if (arg[0] == '-')
+    return -grub_strtoul (arg + 1, end, base);
+  return grub_strtoul (arg, end, base);
+}
+
+/* Parse a test expression starting from *argn. */
+static int
+test_parse (char **args, int *argn, int argc)
+{
+  int ret = 0, discard = 0, invert = 0;
+  int file_exists;
+  struct grub_dirhook_info file_info;
+
+  auto void update_val (int val);
+  auto void get_fileinfo (char *pathname);
+
+  /* Take care of discarding and inverting. */
+  void update_val (int val)
+  {
+    if (! discard)
+      ret = invert ? ! val : val;
+    invert = discard = 0;
+  }
+
+  /* Check if file exists and fetch its information. */
+  void get_fileinfo (char *path)
+  {
+    char *filename, *pathname;
+    char *device_name;
+    grub_fs_t fs;
+    grub_device_t dev;
+
+    /* A hook for iterating directories. */
+    auto int find_file (const char *cur_filename,
+                       const struct grub_dirhook_info *info);
+    int find_file (const char *cur_filename,
+                  const struct grub_dirhook_info *info)
+    {
+      if ((info->case_insensitive ? grub_strcasecmp (cur_filename, filename)
+          : grub_strcmp (cur_filename, filename)) == 0)
+       {
+         file_info = *info;
+         file_exists = 1;
+         return 1;
+       }
+      return 0;
+    }
+
+    file_exists = 0;
+    device_name = grub_file_get_device_name (path);
+    dev = grub_device_open (device_name);
+    if (! dev)
+      {
+       grub_free (device_name);
+       return;
+      }
+
+    fs = grub_fs_probe (dev);
+    if (! fs)
+      {
+       grub_free (device_name);
+       grub_device_close (dev);
+       return;
+      }
+
+    pathname = grub_strchr (path, ')');
+    if (! pathname)
+      pathname = path;
+    else
+      pathname++;
+
+    /* Remove trailing '/'. */
+    while (*pathname && pathname[grub_strlen (pathname) - 1] == '/')
+      pathname[grub_strlen (pathname) - 1] = 0;
+
+    /* Split into path and filename. */
+    filename = grub_strrchr (pathname, '/');
+    if (! filename)
+      {
+       path = grub_strdup ("/");
+       filename = pathname;
+      }
+    else
+      {
+       filename++;
+       path = grub_strdup (pathname);
+       path[filename - pathname] = 0;
+      }
+
+    /* It's the whole device. */
+    if (! *pathname)
+      {
+       file_exists = 1;
+       grub_memset (&file_info, 0, sizeof (file_info));
+       /* Root is always a directory. */
+       file_info.dir = 1;
+
+       /* Fetch writing time. */
+       file_info.mtimeset = 0;
+       if (fs->mtime)
+         {
+           if (! fs->mtime (dev, &file_info.mtime))
+             file_info.mtimeset = 1;
+           grub_errno = GRUB_ERR_NONE;
+         }
+      }
+    else
+      (fs->dir) (dev, path, find_file);
+
+    grub_device_close (dev);
+    grub_free (path);
+    grub_free (device_name);
+  }
+
+  /* Here we have the real parsing. */
+  while (*argn < argc)
+    {
+      /* First try 3 argument tests. */
+      if (*argn + 2 < argc)
+       {
+         /* String tests. */
+         if (grub_strcmp (args[*argn + 1], "=") == 0
+             || grub_strcmp (args[*argn + 1], "==") == 0)
+           {
+             update_val (grub_strcmp (args[*argn], args[*argn + 2]) == 0);
+             (*argn) += 3;
+             continue;
+           }
+
+         if (grub_strcmp (args[*argn + 1], "!=") == 0)
+           {
+             update_val (grub_strcmp (args[*argn], args[*argn + 2]) != 0);
+             (*argn) += 3;
+             continue;
+           }
+
+         /* GRUB extension: lexicographical sorting. */
+         if (grub_strcmp (args[*argn + 1], "<") == 0)
+           {
+             update_val (grub_strcmp (args[*argn], args[*argn + 2]) < 0);
+             (*argn) += 3;
+             continue;
+           }
+
+         if (grub_strcmp (args[*argn + 1], "<=") == 0)
+           {
+             update_val (grub_strcmp (args[*argn], args[*argn + 2]) <= 0);
+             (*argn) += 3;
+             continue;
+           }
+
+         if (grub_strcmp (args[*argn + 1], ">") == 0)
+           {
+             update_val (grub_strcmp (args[*argn], args[*argn + 2]) > 0);
+             (*argn) += 3;
+             continue;
+           }
+
+         if (grub_strcmp (args[*argn + 1], ">=") == 0)
+           {
+             update_val (grub_strcmp (args[*argn], args[*argn + 2]) >= 0);
+             (*argn) += 3;
+             continue;
+           }
+
+         /* Number tests. */
+         if (grub_strcmp (args[*argn + 1], "-eq") == 0)
+           {
+             update_val (grub_strtosl (args[*argn], 0, 0)
+                         == grub_strtosl (args[*argn + 2], 0, 0));
+             (*argn) += 3;
+             continue;
+           }
+
+         if (grub_strcmp (args[*argn + 1], "-ge") == 0)
+           {
+             update_val (grub_strtosl (args[*argn], 0, 0)
+                         >= grub_strtosl (args[*argn + 2], 0, 0));
+             (*argn) += 3;
+             continue;
+           }
+
+         if (grub_strcmp (args[*argn + 1], "-gt") == 0)
+           {
+             update_val (grub_strtosl (args[*argn], 0, 0)
+                         > grub_strtosl (args[*argn + 2], 0, 0));
+             (*argn) += 3;
+             continue;
+           }
+
+         if (grub_strcmp (args[*argn + 1], "-le") == 0)
+           {
+             update_val (grub_strtosl (args[*argn], 0, 0)
+                     <= grub_strtosl (args[*argn + 2], 0, 0));
+             (*argn) += 3;
+             continue;
+           }
+
+         if (grub_strcmp (args[*argn + 1], "-lt") == 0)
+           {
+             update_val (grub_strtosl (args[*argn], 0, 0)
+                         < grub_strtosl (args[*argn + 2], 0, 0));
+             (*argn) += 3;
+             continue;
+           }
+
+         if (grub_strcmp (args[*argn + 1], "-ne") == 0)
+           {
+             update_val (grub_strtosl (args[*argn], 0, 0)
+                         != grub_strtosl (args[*argn + 2], 0, 0));
+             (*argn) += 3;
+             continue;
+           }
+
+         /* GRUB extension: compare numbers skipping prefixes.
+            Useful for comparing versions. E.g. vmlinuz-2 -plt vmlinuz-11. */
+         if (grub_strcmp (args[*argn + 1], "-pgt") == 0
+             || grub_strcmp (args[*argn + 1], "-plt") == 0)
+           {
+             int i;
+             /* Skip common prefix. */
+             for (i = 0; args[*argn][i] == args[*argn + 2][i]
+                    && args[*argn][i]; i++);
+
+             /* Go the digits back. */
+             i--;
+             while (grub_isdigit (args[*argn][i]) && i > 0)
+               i--;
+             i++;
+
+             if (grub_strcmp (args[*argn + 1], "-pgt") == 0)
+               update_val (grub_strtoul (args[*argn] + i, 0, 0)
+                           > grub_strtoul (args[*argn + 2] + i, 0, 0));
+             else
+               update_val (grub_strtoul (args[*argn] + i, 0, 0)
+                           < grub_strtoul (args[*argn + 2] + i, 0, 0));
+             (*argn) += 3;
+             continue;
+           }
+
+         /* -nt and -ot tests. GRUB extension: when doing -?t<bias> bias
+            will be added to the first mtime. */
+         if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0
+             || grub_memcmp (args[*argn + 1], "-ot", 3) == 0)
+           {
+             struct grub_dirhook_info file1;
+             int file1exists;
+             int bias = 0;
+
+             /* Fetch fileinfo. */
+             get_fileinfo (args[*argn]);
+             file1 = file_info;
+             file1exists = file_exists;
+             get_fileinfo (args[*argn + 2]);
+
+             if (args[*argn + 1][3])
+               bias = grub_strtosl (args[*argn + 1] + 3, 0, 0);
+
+             if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0)
+               update_val ((file1exists && ! file_exists)
+                           || (file1.mtimeset && file_info.mtimeset
+                               && file1.mtime + bias > file_info.mtime));
+             else
+               update_val ((! file1exists && file_exists)
+                           || (file1.mtimeset && file_info.mtimeset
+                               && file1.mtime + bias < file_info.mtime));
+             (*argn) += 3;
+             continue;
+           }
+       }
+
+      /* Two-argument tests. */
+      if (*argn + 1 < argc)
+       {
+         /* File tests. */
+         if (grub_strcmp (args[*argn], "-d") == 0)
+           {
+             get_fileinfo (args[*argn + 1]);
+             update_val (file_exists && file_info.dir);
+             (*argn) += 2;
+             return ret;
+           }
+
+         if (grub_strcmp (args[*argn], "-e") == 0)
+           {
+             get_fileinfo (args[*argn + 1]);
+             update_val (file_exists);
+             (*argn) += 2;
+             return ret;
+           }
+
+         if (grub_strcmp (args[*argn], "-f") == 0)
+           {
+             get_fileinfo (args[*argn + 1]);
+             /* FIXME: check for other types. */
+             update_val (file_exists && ! file_info.dir);
+             (*argn) += 2;
+             return ret;
+           }
+
+         if (grub_strcmp (args[*argn], "-s") == 0)
+           {
+             grub_file_t file;
+             file = grub_file_open (args[*argn + 1]);
+             update_val (file && (grub_file_size (file) != 0));
+             if (file)
+               grub_file_close (file);
+             grub_errno = GRUB_ERR_NONE;
+             (*argn) += 2;
+             return ret;
+           }
+
+         /* String tests. */
+         if (grub_strcmp (args[*argn], "-n") == 0)
+           {
+             update_val (args[*argn + 1][0]);
+
+             (*argn) += 2;
+             continue;
+           }
+         if (grub_strcmp (args[*argn], "-z") == 0)
+           {
+             update_val (! args[*argn + 1][0]);
+             (*argn) += 2;
+             continue;
+           }
+       }
+
+      /* Special modifiers. */
+
+      /* End of expression. return to parent. */
+      if (grub_strcmp (args[*argn], ")") == 0)
+       {
+         (*argn)++;
+         return ret;
+       }
+      /* Recursively invoke if parenthesis. */
+      if (grub_strcmp (args[*argn], "(") == 0)
+       {
+         (*argn)++;
+         update_val (test_parse (args, argn, argc));
+         continue;
+       }
+
+      if (grub_strcmp (args[*argn], "!") == 0)
+       {
+         invert = ! invert;
+         (*argn)++;
+         continue;
+       }
+      if (grub_strcmp (args[*argn], "-a") == 0)
+       {
+         /* If current value is 0 second value is to be discarded. */
+         discard = ! ret;
+         (*argn)++;
+         continue;
+       }
+      if (grub_strcmp (args[*argn], "-o") == 0)
+       {
+         /* If current value is 1 second value is to be discarded. */
+         discard = ret;
+         (*argn)++;
+         continue;
+       }
+
+      /* No test found. Interpret if as just a string. */
+      update_val (args[*argn][0]);
+      (*argn)++;
+    }
+  return ret;
+}
+
+static grub_err_t
+grub_cmd_test (grub_command_t cmd __attribute__ ((unused)),
+              int argc, char **args)
+{
+  int argn = 0;
+
+  if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0)
+    argc--;
+
+  return test_parse (args, &argn, argc) ? GRUB_ERR_NONE
+    : grub_error (GRUB_ERR_TEST_FAILURE, "false");
+}
+
+static grub_command_t cmd_1, cmd_2;
+\f
+GRUB_MOD_INIT(test)
+{
+  cmd_1 = grub_register_command ("[", grub_cmd_test,
+                                N_("EXPRESSION ]"), N_("Evaluate an expression."));
+  cmd_2 = grub_register_command ("test", grub_cmd_test,
+                                N_("EXPRESSION"), N_("Evaluate an expression."));
+}
+
+GRUB_MOD_FINI(test)
+{
+  grub_unregister_command (cmd_1);
+  grub_unregister_command (cmd_2);
+}
diff --git a/grub-core/commands/true.c b/grub-core/commands/true.c
new file mode 100644 (file)
index 0000000..aa81258
--- /dev/null
@@ -0,0 +1,57 @@
+/* true.c - true and false commands.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+grub_cmd_true (struct grub_command *cmd __attribute__ ((unused)),
+              int argc __attribute__ ((unused)),
+              char *argv[] __attribute__ ((unused)))
+{
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_false (struct grub_command *cmd __attribute__ ((unused)),
+               int argc __attribute__ ((unused)),
+               char *argv[] __attribute__ ((unused)))
+{
+  return grub_error (GRUB_ERR_TEST_FAILURE, "false");
+}
+
+static grub_command_t cmd_true, cmd_false;
+
+\f
+GRUB_MOD_INIT(true)
+{
+  cmd_true =
+    grub_register_command ("true", grub_cmd_true,
+                          0, N_("Do nothing, successfully."));
+  cmd_false =
+    grub_register_command ("false", grub_cmd_false,
+                          0, N_("Do nothing, unsuccessfully."));
+}
+
+GRUB_MOD_FINI(true)
+{
+  grub_unregister_command (cmd_true);
+  grub_unregister_command (cmd_false);
+}
diff --git a/grub-core/commands/usbtest.c b/grub-core/commands/usbtest.c
new file mode 100644 (file)
index 0000000..b884a93
--- /dev/null
@@ -0,0 +1,205 @@
+/* usbtest.c - test module for USB */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/charset.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/usb.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static const char *usb_classes[] =
+  {
+    "",
+    "Audio",
+    "Communication Interface",
+    "HID",
+    "",
+    "Physical",
+    "Image",
+    "Printer",
+    "Mass Storage",
+    "Hub",
+    "Data Interface",
+    "Smart Card",
+    "Content Security",
+    "Video"
+  };
+
+static const char *usb_endp_type[] =
+  {
+    "Control",
+    "Isochronous",
+    "Bulk",
+    "Interrupt"
+  };
+
+static const char *usb_devspeed[] =
+  {
+    "",
+    "Low",
+    "Full",
+    "High"
+  };
+
+static grub_usb_err_t
+grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid,
+                    char **string)
+{
+  struct grub_usb_desc_str descstr;
+  struct grub_usb_desc_str *descstrp;
+  grub_usb_err_t err;
+
+  /* Only get the length.  */
+  err = grub_usb_control_msg (dev, 1 << 7,
+                             0x06, (3 << 8) | index,
+                             langid, 1, (char *) &descstr);
+  if (err)
+    return err;
+
+  descstrp = grub_malloc (descstr.length);
+  if (! descstrp)
+    return GRUB_USB_ERR_INTERNAL;
+  err = grub_usb_control_msg (dev, 1 << 7,
+                             0x06, (3 << 8) | index,
+                             langid, descstr.length, (char *) descstrp);
+
+  *string = grub_malloc (descstr.length / 2);
+  if (! *string)
+    {
+      grub_free (descstrp);
+      return GRUB_USB_ERR_INTERNAL;
+    }
+
+  grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, descstrp->length / 2 - 1);
+  (*string)[descstr.length / 2 - 1] = '\0';
+  grub_free (descstrp);
+
+  return GRUB_USB_ERR_NONE;
+}
+
+static void
+usb_print_str (const char *description, grub_usb_device_t dev, int idx)
+{
+  char *name;
+  grub_usb_err_t err;
+  /* XXX: LANGID  */
+
+  if (! idx)
+    return;
+
+  err = grub_usb_get_string (dev, idx, 0x0409, &name);
+  if (err)
+    grub_printf ("Error %d retrieving %s\n", err, description);
+  else
+    {
+      grub_printf ("%s: `%s'\n", description, name);
+      grub_free (name);
+    }
+}
+
+static int
+usb_iterate (grub_usb_device_t dev)
+{
+  struct grub_usb_desc_device *descdev;
+  int i;
+
+  descdev = &dev->descdev;
+
+  usb_print_str ("Product", dev, descdev->strprod);
+  usb_print_str ("Vendor", dev, descdev->strvendor);
+  usb_print_str ("Serial", dev, descdev->strserial);
+
+  if (descdev->class > 0 && descdev->class <= 0x0E)
+    grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n",
+                descdev->class, usb_classes[descdev->class],
+                descdev->subclass, descdev->protocol);
+  grub_printf ("USB version %d.%d, VendorID: 0x%02x, ProductID: 0x%02x, #conf: %d\n",
+              descdev->usbrel >> 8, (descdev->usbrel >> 4) & 0x0F,
+              descdev->vendorid, descdev->prodid, descdev->configcnt);
+
+  grub_printf ("%s speed device\n", usb_devspeed[dev->speed]);
+
+  for (i = 0; i < descdev->configcnt; i++)
+    {
+      struct grub_usb_desc_config *config;
+
+      config = dev->config[i].descconf;
+      usb_print_str ("Configuration:", dev, config->strconfig);
+    }
+
+  for (i = 0; i < dev->config[0].descconf->numif; i++)
+    {
+      int j;
+      struct grub_usb_desc_if *interf;
+      interf = dev->config[0].interf[i].descif;
+
+      grub_printf ("Interface #%d: #Endpoints: %d   ",
+                  i, interf->endpointcnt);
+      if (interf->class > 0 && interf->class <= 0x0E)
+       grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n",
+                    interf->class, usb_classes[interf->class],
+                    interf->subclass, interf->protocol);
+
+      usb_print_str ("Interface", dev, interf->strif);
+
+      for (j = 0; j < interf->endpointcnt; j++)
+       {
+         struct grub_usb_desc_endp *endp;
+         endp = &dev->config[0].interf[i].descendp[j];
+
+         grub_printf ("Endpoint #%d: %s, max packed size: %d, transfer type: %s, latency: %d\n",
+                      endp->endp_addr & 15,
+                      (endp->endp_addr & 128) ? "IN" : "OUT",
+                      endp->maxpacket, usb_endp_type[endp->attrib & 3],
+                      endp->interval);
+       }
+    }
+
+  grub_printf("\n");
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_usbtest (grub_command_t cmd __attribute__ ((unused)),
+                 int argc __attribute__ ((unused)),
+                 char **args __attribute__ ((unused)))
+{
+  grub_printf ("USB devices:\n\n");
+  grub_usb_iterate (usb_iterate);
+
+  return 0;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(usbtest)
+{
+  cmd = grub_register_command ("usb", grub_cmd_usbtest,
+                              0, N_("Test USB support."));
+}
+
+GRUB_MOD_FINI(usbtest)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/videotest.c b/grub-core/commands/videotest.c
new file mode 100644 (file)
index 0000000..390811a
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/video.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/font.h>
+#include <grub/term.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
+                    int argc __attribute__ ((unused)),
+                    char **args __attribute__ ((unused)))
+{
+  grub_err_t err;
+  grub_video_color_t color;
+  unsigned int x;
+  unsigned int y;
+  unsigned int width;
+  unsigned int height;
+  int i;
+  grub_font_t sansbig;
+  grub_font_t sans;
+  grub_font_t sanssmall;
+  grub_font_t fixed;
+  struct grub_font_glyph *glyph;
+  struct grub_video_render_target *text_layer;
+  grub_video_color_t palette[16];
+  const char *str;
+  int texty;
+
+  err = grub_video_set_mode ("auto", GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
+  if (err)
+    return err;
+
+  grub_video_get_viewport (&x, &y, &width, &height);
+
+  grub_video_create_render_target (&text_layer, width, height,
+                                   GRUB_VIDEO_MODE_TYPE_RGB
+                                   | GRUB_VIDEO_MODE_TYPE_ALPHA);
+
+  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
+
+  color = grub_video_map_rgb (0, 0, 0);
+  grub_video_fill_rect (color, 0, 0, width, height);
+
+  color = grub_video_map_rgb (255, 0, 0);
+  grub_video_fill_rect (color, 0, 0, 100, 100);
+
+  color = grub_video_map_rgb (0, 255, 255);
+  grub_video_fill_rect (color, 100, 100, 100, 100);
+
+  sansbig = grub_font_get ("Unknown Regular 16");
+  sans = grub_font_get ("Unknown Regular 16");
+  sanssmall = grub_font_get ("Unknown Regular 16");
+  fixed = grub_font_get ("Fixed 20");
+  if (! sansbig || ! sans || ! sanssmall || ! fixed)
+    return grub_error (GRUB_ERR_BAD_FONT, "no font loaded");
+
+  glyph = grub_font_get_glyph (fixed, '*');
+  grub_font_draw_glyph (glyph, color, 200 ,0);
+
+  grub_video_set_viewport (x + 150, y + 150,
+                           width - 150 * 2, height - 150 * 2);
+  color = grub_video_map_rgb (77, 33, 77);
+  grub_video_fill_rect (color, 0, 0, width, height);
+
+  grub_video_set_active_render_target (text_layer);
+
+  color = grub_video_map_rgb (255, 255, 255);
+
+  texty = 32;
+  grub_font_draw_string ("The quick brown fox jumped over the lazy dog.",
+                         sans, color, 16, texty);
+  texty += grub_font_get_descent (sans) + grub_font_get_leading (sans);
+
+  texty += grub_font_get_ascent (fixed);
+  grub_font_draw_string ("The quick brown fox jumped over the lazy dog.",
+                         fixed, color, 16, texty);
+  texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed);
+
+  /* To convert Unicode characters into UTF-8 for this test, the following
+     command is useful:
+       echo -ne '\x00\x00\x26\x3A' | iconv -f UTF-32BE -t UTF-8 | od -t x1
+     This converts the Unicode character U+263A to UTF-8.  */
+
+  /* Characters used:
+     Code point  Description                    UTF-8 encoding
+     ----------- ------------------------------ --------------
+     U+263A      unfilled smiley face           E2 98 BA
+     U+00A1      inverted exclamation point     C2 A1
+     U+00A3      British pound currency symbol  C2 A3
+     U+03C4      Greek tau                      CF 84
+     U+00E4      lowercase letter a with umlaut C3 A4
+     U+2124      set 'Z' symbol (integers)      E2 84 A4
+     U+2287      subset symbol                  E2 8A 87
+     U+211D      set 'R' symbol (real numbers)  E2 84 9D  */
+
+  str =
+    "Unicode test: happy\xE2\x98\xBA \xC2\xA3 5.00"
+    " \xC2\xA1\xCF\x84\xC3\xA4u! "
+    " \xE2\x84\xA4\xE2\x8A\x87\xE2\x84\x9D";
+  color = grub_video_map_rgb (128, 128, 255);
+
+  /* All characters in the string exist in the 'Fixed 20' (10x20) font.  */
+  texty += grub_font_get_ascent(fixed);
+  grub_font_draw_string (str, fixed, color, 16, texty);
+  texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed);
+
+  texty += grub_font_get_ascent(sansbig);
+  grub_font_draw_string (str, sansbig, color, 16, texty);
+  texty += grub_font_get_descent (sansbig) + grub_font_get_leading (sansbig);
+
+  texty += grub_font_get_ascent(sans);
+  grub_font_draw_string (str, sans, color, 16, texty);
+  texty += grub_font_get_descent (sans) + grub_font_get_leading (sans);
+
+  texty += grub_font_get_ascent(sanssmall);
+  grub_font_draw_string (str, sanssmall, color, 16, texty);
+  texty += (grub_font_get_descent (sanssmall)
+            + grub_font_get_leading (sanssmall));
+
+  glyph = grub_font_get_glyph (fixed, '*');
+
+  for (i = 0; i < 16; i++)
+    {
+      color = grub_video_map_color (i);
+      palette[i] = color;
+      grub_font_draw_glyph (glyph, color, 16 + i * 16, 220);
+    }
+
+  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
+
+  for (i = 0; i < 5; i++)
+    {
+      color = grub_video_map_rgb (i, 33, 77);
+      grub_video_fill_rect (color, 0, 0, width, height);
+      grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, 0, 0,
+                                     0, 0, width, height);
+      grub_video_swap_buffers ();
+    }
+
+  grub_getkey ();
+
+  grub_video_delete_render_target (text_layer);
+
+  grub_video_restore ();
+
+  for (i = 0; i < 16; i++)
+    grub_printf("color %d: %08x\n", i, palette[i]);
+
+  grub_errno = GRUB_ERR_NONE;
+  return grub_errno;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(videotest)
+{
+  cmd = grub_register_command ("videotest", grub_cmd_videotest,
+                              0, N_("Test video subsystem."));
+}
+
+GRUB_MOD_FINI(videotest)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/commands/xnu_uuid.c b/grub-core/commands/xnu_uuid.c
new file mode 100644 (file)
index 0000000..382d319
--- /dev/null
@@ -0,0 +1,100 @@
+/* xnu_uuid.c - transform 64-bit serial number
+   to 128-bit uuid suitable for xnu. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1995,1996,1998,1999,2001,2002,
+ *                2003, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/fs.h>
+#include <grub/file.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+#include <grub/crypto.h>
+
+/* This prefix is used by xnu and boot-132 to hash
+   together with volume serial. */
+static grub_uint8_t hash_prefix[16]
+  = {0xB3, 0xE2, 0x0F, 0x39, 0xF2, 0x92, 0x11, 0xD6,
+     0x97, 0xA4, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC};
+
+static grub_err_t
+grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)),
+                  int argc, char **args)
+{
+  grub_uint64_t serial;
+  grub_uint8_t *xnu_uuid;
+  char uuid_string[sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")];
+  char *ptr;
+  grub_uint8_t ctx[GRUB_MD_MD5->contextsize];
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "UUID required");
+
+  serial = grub_cpu_to_be64 (grub_strtoull (args[0], 0, 16));
+
+  GRUB_MD_MD5->init (&ctx);
+  GRUB_MD_MD5->write (&ctx, hash_prefix, sizeof (hash_prefix));
+  GRUB_MD_MD5->write (&ctx, &serial, sizeof (serial));
+  GRUB_MD_MD5->final (&ctx);
+  xnu_uuid = GRUB_MD_MD5->read (&ctx);
+
+  grub_snprintf (uuid_string, sizeof (uuid_string),
+               "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+               (unsigned int) xnu_uuid[0], (unsigned int) xnu_uuid[1],
+               (unsigned int) xnu_uuid[2], (unsigned int) xnu_uuid[3],
+               (unsigned int) xnu_uuid[4], (unsigned int) xnu_uuid[5],
+               (unsigned int) ((xnu_uuid[6] & 0xf) | 0x30),
+               (unsigned int) xnu_uuid[7],
+               (unsigned int) ((xnu_uuid[8] & 0x3f) | 0x80),
+               (unsigned int) xnu_uuid[9],
+               (unsigned int) xnu_uuid[10], (unsigned int) xnu_uuid[11],
+               (unsigned int) xnu_uuid[12], (unsigned int) xnu_uuid[13],
+               (unsigned int) xnu_uuid[14], (unsigned int) xnu_uuid[15]);
+  for (ptr = uuid_string; *ptr; ptr++)
+    *ptr = grub_toupper (*ptr);
+  if (argc == 1)
+    grub_printf ("%s", uuid_string);
+  if (argc > 1)
+    grub_env_set (args[1], uuid_string);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd;
+
+
+GRUB_MOD_INIT (xnu_uuid)
+{
+  cmd = grub_register_command ("xnu_uuid", grub_cmd_xnu_uuid,
+                              N_("GRUBUUID [VARNAME]"),
+                              N_("Transform 64-bit UUID to format "
+                              "suitable for XNU."));
+}
+
+GRUB_MOD_FINI (xnu_uuid)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/conf/any-emu.rmk b/grub-core/conf/any-emu.rmk
new file mode 100644 (file)
index 0000000..d1e5754
--- /dev/null
@@ -0,0 +1,113 @@
+# -*- makefile -*-
+
+COMMON_CFLAGS += -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include)
+
+kernel_img_RELOCATABLE = yes
+pkglib_PROGRAMS = kernel.img
+kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c    \
+       kern/err.c kern/list.c kern/handler.c kern/command.c            \
+       kern/corecmd.c kern/file.c kern/fs.c kern/main.c kern/misc.c    \
+       kern/parser.c kern/partition.c kern/term.c                      \
+       kern/rescue_reader.c kern/rescue_parser.c                       \
+       \
+       util/console.c  util/grub-emu.c util/misc.c                     \
+       util/hostdisk.c util/getroot.c util/mm.c util/time.c            \
+       \
+       gnulib/progname.c util/hostfs.c disk/host.c
+kernel_img_HEADERS += datetime.h util/misc.h
+kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-undef -I$(srcdir)/gnulib
+kernel_img_LDFLAGS = $(COMMON_LDFLAGS)
+TARGET_NO_STRIP = yes
+
+ifneq ($(TARGET_NO_MODULES), yes)
+kernel_img_SOURCES += symlist.c kern/$(target_cpu)/dl.c
+ifneq ($(target_cpu), i386)
+ifneq ($(target_cpu), x86_64)
+kernel_img_SOURCES += kern/$(target_cpu)/cache.S
+endif
+endif
+else
+kernel_img_SOURCES += grub_emu_init.c
+endif
+
+# For halt.mod.
+pkglib_MODULES += halt.mod
+halt_mod_SOURCES = commands/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+ifeq ($(target_cpu), i386)
+pkglib_MODULES += cpuid.mod
+cpuid_mod_SOURCES = commands/i386/cpuid.c
+cpuid_mod_CFLAGS = $(COMMON_CFLAGS)
+cpuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+endif
+
+grub_emu_LDFLAGS = $(LIBCURSES)
+
+ifeq ($(enable_grub_emu_usb), yes)
+kernel_img_HEADERS += libusb.h
+
+pkglib_MODULES += libusb.mod
+libusb_mod_SOURCES = util/usb.c
+libusb_mod_CFLAGS = 
+libusb_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usb.mod
+pkglib_MODULES += usb.mod
+usb_mod_SOURCES = bus/usb/usb.c
+usb_mod_CFLAGS = $(COMMON_CFLAGS)
+usb_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usbtest.mod
+pkglib_MODULES += usbtest.mod
+usbtest_mod_SOURCES = commands/usbtest.c
+usbtest_mod_CFLAGS = $(COMMON_CFLAGS)
+usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usbms.mod
+pkglib_MODULES += usbms.mod
+usbms_mod_SOURCES = disk/usbms.c
+usbms_mod_CFLAGS = $(COMMON_CFLAGS)
+usbms_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+grub_emu_LDFLAGS += $(LIBUSB)
+endif
+
+ifeq ($(enable_grub_emu_sdl), yes)
+pkglib_MODULES += sdl.mod
+sdl_mod_SOURCES = util/sdl.c
+sdl_mod_CFLAGS = 
+sdl_mod_LDFLAGS = $(COMMON_LDFLAGS)
+grub_emu_LDFLAGS += $(LIBSDL)
+kernel_img_HEADERS += sdl.h
+endif
+
+ifeq ($(enable_grub_emu_pci), yes)
+pkglib_MODULES += pci.mod
+pci_mod_SOURCES = util/pci.c commands/lspci.c
+pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+grub_emu_LDFLAGS += $(LIBPCIACCESS)
+kernel_img_HEADERS += libpciaccess.h
+endif
+
+include $(srcdir)/conf/common.mk
+
+grub_emu_init.h: genemuinitheader.sh $(pkglib_MODULES)
+       rm -f $@; echo $(pkglib_MODULES) | sh $(srcdir)/genemuinitheader.sh $(NM)  > $@
+DISTCLEANFILES += grub_emu_init.h
+
+grub_emu_init.c: genemuinit.sh $(pkglib_MODULES) grub_emu_init.h
+       rm -f $@; echo $(pkglib_MODULES) | sh $(srcdir)/genemuinit.sh $(NM) > $@
+DISTCLEANFILES += grub_emu_init.c
+
+CLEANFILES += grub-emu
+ifneq ($(TARGET_NO_MODULES), yes)
+grub-emu: $(pkglib_PROGRAMS)
+       $(CC) -o $@ $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS)
+else
+grub-emu: $(pkglib_MODULES) $(pkglib_PROGRAMS)
+       $(CC) -o $@ $(pkglib_MODULES) $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS)
+endif
+GRUB_EMU=grub-emu
+
diff --git a/grub-core/conf/common.rmk b/grub-core/conf/common.rmk
new file mode 100644 (file)
index 0000000..4b39e9b
--- /dev/null
@@ -0,0 +1,867 @@
+# -*- makefile -*-
+
+# Used by various components.  These rules need to precede them.
+script/lexer.c_DEPENDENCIES = grub_script.tab.h
+
+sbin_UTILITIES += grub-mkdevicemap
+grub_mkdevicemap_SOURCES = gnulib/progname.c util/grub-mkdevicemap.c \
+       util/deviceiter.c \
+       util/misc.c
+
+ifeq ($(target_cpu)-$(platform), sparc64-ieee1275)
+grub_mkdevicemap_SOURCES += util/ieee1275/ofpath.c util/ieee1275/devicemap.c
+else
+grub_mkdevicemap_SOURCES += util/devicemap.c
+endif
+
+# For grub-mkelfimage.
+bin_UTILITIES += grub-mkelfimage
+grub_mkelfimage_SOURCES = gnulib/progname.c \
+       util/elf/grub-mkimage.c util/misc.c \
+       util/resolve.c
+util/elf/grub-mkimage.c_DEPENDENCIES = Makefile
+
+# For grub-probe.
+sbin_UTILITIES += grub-probe
+util/grub-probe.c_DEPENDENCIES = grub_probe_init.h
+grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c       \
+       util/hostdisk.c util/misc.c util/getroot.c util/mm.c    \
+       kern/device.c kern/disk.c kern/err.c kern/misc.c        \
+       kern/parser.c kern/partition.c kern/file.c kern/list.c  \
+       \
+       fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c         \
+       fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c  \
+       fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c       \
+       fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c           \
+       fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c             \
+       \
+       partmap/msdos.c partmap/bsdlabel.c partmap/apple.c \
+       partmap/sun.c partmap/sunpc.c partmap/gpt.c \
+       kern/fs.c kern/env.c fs/fshelp.c                        \
+       disk/raid.c disk/mdraid_linux.c disk/lvm.c grub_probe_init.c
+
+ifeq ($(enable_grub_fstest), yes)
+bin_UTILITIES += grub-fstest
+endif
+
+bin_UTILITIES += grub-mkisofs
+grub_mkisofs_SOURCES = util/mkisofs/eltorito.c                                 \
+       util/mkisofs/hash.c util/mkisofs/joliet.c                       \
+       util/mkisofs/match.c util/mkisofs/mkisofs.c                     \
+       util/mkisofs/multi.c util/mkisofs/name.c                        \
+       util/mkisofs/rock.c util/mkisofs/tree.c                         \
+       util/mkisofs/write.c                                            \
+       \
+       gnulib/fnmatch.c gnulib/getopt1.c gnulib/getopt.c               \
+       gnulib/error.c gnulib/progname.c
+grub_mkisofs_CFLAGS = -D_FILE_OFFSET_BITS=64                           \
+       -I$(srcdir)/util/mkisofs/include                                \
+       -Wno-all -Werror $(GNULIB_UTIL_CFLAGS)
+
+# For grub-fstest.
+util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h
+grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \
+       util/misc.c util/mm.c   \
+       kern/file.c kern/device.c kern/disk.c kern/err.c kern/misc.c    \
+       disk/host.c disk/loopback.c kern/list.c kern/command.c          \
+       lib/arg.c commands/extcmd.c normal/datetime.c normal/misc.c     \
+       lib/hexdump.c lib/crc.c commands/blocklist.c commands/ls.c      \
+       \
+       fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c                 \
+       fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c          \
+       fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c      \
+       fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c fs/befs.c      \
+       fs/befs_be.c fs/tar.c                   \
+       \
+       kern/partition.c partmap/msdos.c partmap/bsdlabel.c             \
+       partmap/apple.c partmap/sun.c partmap/sunpc.c partmap/gpt.c     \
+       kern/fs.c kern/env.c fs/fshelp.c disk/raid.c                    \
+       disk/raid5_recover.c disk/raid6_recover.c                       \
+       disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c             \
+       grub_fstest_init.c
+
+# For grub-mkfont.
+ifeq ($(enable_grub_mkfont), yes)
+bin_UTILITIES += grub-mkfont
+grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c
+grub_mkfont_CFLAGS = $(freetype_cflags)
+grub_mkfont_LDFLAGS = $(freetype_libs)
+endif
+
+# For grub-mkrelpath.
+bin_UTILITIES += grub-mkrelpath
+grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c
+
+bin_UTILITIES += grub-bin2h
+grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c
+
+# For the lexer.
+grub_script.yy.c grub_script.yy.h: script/yylex.l
+       $(LEX) -o grub_script.yy.c --header-file=grub_script.yy.h $(srcdir)/script/yylex.l
+DISTCLEANFILES += grub_script.yy.c grub_script.yy.h
+
+# For grub-script-check.
+bin_UTILITIES += grub-script-check
+util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h
+grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c \
+       util/grub-script-check.c util/misc.c util/mm.c \
+       script/main.c script/script.c script/function.c script/lexer.c \
+       kern/handler.c kern/err.c kern/parser.c kern/list.c \
+       kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \
+       grub_script.yy.c
+grub_script_check_CFLAGS = $(GNULIB_UTIL_CFLAGS)
+MOSTLYCLEANFILES += symlist.c kernel_syms.lst
+DEFSYMFILES += kernel_syms.lst
+
+kernel_img_HEADERS += 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 msdos_partition.h reader.h symbol.h term.h time.h types.h \
+       list.h handler.h command.h i18n.h env_private.h libgcc.h
+
+ifneq ($(platform), emu)
+kernel_img_HEADERS += machine/memory.h machine/loader.h machine/kernel.h
+endif
+
+symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh
+       /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh
+       /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
+
+# For the parser.
+grub_script.tab.c grub_script.tab.h: script/parser.y
+       $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y
+DISTCLEANFILES += grub_script.tab.c grub_script.tab.h
+
+# For grub-script-check.
+grub_script_check_init.lst: geninit.sh $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES))
+       rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
+DISTCLEANFILES += grub_script_check_init.lst
+
+grub_script_check_init.h: grub_script_check_init.lst $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) geninitheader.sh
+       rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
+DISTCLEANFILES += grub_script_check_init.h
+
+grub_script_check_init.c: grub_script_check_init.lst $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) geninit.sh
+       rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
+DISTCLEANFILES += grub_script_check_init.c
+
+# For grub-probe.
+grub_probe_init.lst: geninit.sh $(filter-out grub_probe_init.c,$(grub_probe_SOURCES))
+       rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
+DISTCLEANFILES += grub_probe_init.lst
+
+grub_probe_init.h: grub_probe_init.lst $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) geninitheader.sh
+       rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
+DISTCLEANFILES += grub_probe_init.h
+
+grub_probe_init.c: grub_probe_init.lst $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) geninit.sh grub_probe_init.h
+       rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
+DISTCLEANFILES += grub_probe_init.c
+
+# For grub-setup.
+grub_setup_init.lst: geninit.sh $(filter-out grub_setup_init.c,$(grub_setup_SOURCES))
+       rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
+DISTCLEANFILES += grub_setup_init.lst
+
+grub_setup_init.h: grub_setup_init.lst $(filter-out grub_setup_init.c,$(grub_setup_SOURCES)) geninitheader.sh
+       rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
+DISTCLEANFILES += grub_setup_init.h
+
+grub_setup_init.c: grub_setup_init.lst $(filter-out grub_setup_init.c,$(grub_setup_SOURCES)) geninit.sh grub_setup_init.h
+       rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
+DISTCLEANFILES += grub_setup_init.c
+
+# For grub-fstest.
+grub_fstest_init.lst: geninit.sh $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES))
+       rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@
+DISTCLEANFILES += grub_fstest_init.lst
+
+grub_fstest_init.h: grub_fstest_init.lst $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES)) geninitheader.sh
+       rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@
+DISTCLEANFILES += grub_fstest_init.h
+
+grub_fstest_init.c: grub_fstest_init.lst $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES)) geninit.sh grub_fstest_init.h
+       rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@
+DISTCLEANFILES += grub_fstest_init.c
+
+# for grub-editenv
+bin_UTILITIES += grub-editenv
+grub_editenv_SOURCES = gnulib/progname.c util/grub-editenv.c lib/envblk.c util/misc.c util/mm.c kern/misc.c kern/err.c
+CLEANFILES += grub-editenv
+
+# Needed for genmk.rb to work
+ifeq (0,1)
+bin_UTILITIES += grub-macho2img grub-pe2elf
+endif
+
+grub_pe2elf_SOURCES = gnulib/progname.c util/grub-pe2elf.c util/misc.c
+CLEANFILES += grub-pe2elf
+
+grub_macho2img_SOURCES = util/grub-macho2img.c
+CLEANFILES += grub-macho2img
+
+# For grub-mkconfig
+grub-mkconfig: util/grub-mkconfig.in config.status
+       ./config.status --file=$@:$<
+       chmod +x $@
+sbin_SCRIPTS += grub-mkconfig
+CLEANFILES += grub-mkconfig
+
+grub-mkconfig_lib: util/grub-mkconfig_lib.in config.status
+       ./config.status --file=$@:$<
+       chmod +x $@
+lib_SCRIPTS += grub-mkconfig_lib
+CLEANFILES += grub-mkconfig_lib
+
+update-grub_lib: util/update-grub_lib.in config.status
+       ./config.status --file=$@:$<
+       chmod +x $@
+lib_SCRIPTS += update-grub_lib
+CLEANFILES += update-grub_lib
+
+grub-gettext_lib: util/grub-gettext_lib.in config.status
+       ./config.status --file=$@:$<
+       chmod +x $@
+lib_DATA += grub-gettext_lib
+CLEANFILES += grub-gettext_lib
+
+%: util/grub.d/%.in config.status
+       ./config.status --file=$@:$<
+       chmod +x $@
+grub-mkconfig_SCRIPTS = 00_header 30_os-prober 40_custom
+ifneq (, $(host_kernel))
+grub-mkconfig_SCRIPTS += 10_$(host_kernel)
+endif
+
+CLEANFILES += $(grub-mkconfig_SCRIPTS)
+
+grub-mkconfig_DATA += util/grub.d/README
+
+# For grub-set-default.
+grub-set-default: util/grub-set-default.in config.status
+       ./config.status --file=$@:$<
+       chmod +x $@
+sbin_SCRIPTS += grub-set-default
+CLEANFILES += grub-set-default
+
+# For grub-reboot.
+grub-reboot: util/grub-reboot.in config.status
+       ./config.status --file=$@:$<
+       chmod +x $@
+sbin_SCRIPTS += grub-reboot
+CLEANFILES += grub-reboot
+
+# Filing systems.
+pkglib_MODULES += fshelp.mod fat.mod ufs1.mod ufs2.mod ext2.mod ntfs.mod \
+       ntfscomp.mod minix.mod hfs.mod jfs.mod iso9660.mod xfs.mod      \
+       affs.mod sfs.mod hfsplus.mod reiserfs.mod cpio.mod tar.mod      \
+       udf.mod afs.mod afs_be.mod befs.mod befs_be.mod
+
+# For fshelp.mod.
+fshelp_mod_SOURCES = fs/fshelp.c
+fshelp_mod_CFLAGS = $(COMMON_CFLAGS)
+fshelp_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For fat.mod.
+fat_mod_SOURCES = fs/fat.c
+fat_mod_CFLAGS = $(COMMON_CFLAGS)
+fat_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ufs1.mod.
+ufs1_mod_SOURCES = fs/ufs.c
+ufs1_mod_CFLAGS = $(COMMON_CFLAGS)
+ufs1_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ufs2.mod.
+ufs2_mod_SOURCES = fs/ufs2.c
+ufs2_mod_CFLAGS = $(COMMON_CFLAGS)
+ufs2_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ext2.mod.
+ext2_mod_SOURCES = fs/ext2.c
+ext2_mod_CFLAGS = $(COMMON_CFLAGS)
+ext2_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ntfs.mod.
+ntfs_mod_SOURCES = fs/ntfs.c
+ntfs_mod_CFLAGS = $(COMMON_CFLAGS)
+ntfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ntfscomp.mod.
+ntfscomp_mod_SOURCES = fs/ntfscomp.c
+ntfscomp_mod_CFLAGS = $(COMMON_CFLAGS)
+ntfscomp_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For minix.mod.
+minix_mod_SOURCES = fs/minix.c
+minix_mod_CFLAGS = $(COMMON_CFLAGS)
+minix_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For nilfs2.mod.
+pkglib_MODULES += nilfs2.mod
+nilfs2_mod_SOURCES = fs/nilfs2.c
+nilfs2_mod_CFLAGS = $(COMMON_CFLAGS)
+nilfs2_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For hfs.mod.
+hfs_mod_SOURCES = fs/hfs.c
+hfs_mod_CFLAGS = $(COMMON_CFLAGS)
+hfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For jfs.mod.
+jfs_mod_SOURCES = fs/jfs.c
+jfs_mod_CFLAGS = $(COMMON_CFLAGS)
+jfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For iso9660.mod.
+iso9660_mod_SOURCES = fs/iso9660.c
+iso9660_mod_CFLAGS = $(COMMON_CFLAGS)
+iso9660_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For xfs.mod.
+xfs_mod_SOURCES = fs/xfs.c
+xfs_mod_CFLAGS = $(COMMON_CFLAGS)
+xfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For affs.mod.
+affs_mod_SOURCES = fs/affs.c
+affs_mod_CFLAGS = $(COMMON_CFLAGS)
+affs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For sfs.mod.
+sfs_mod_SOURCES = fs/sfs.c
+sfs_mod_CFLAGS = $(COMMON_CFLAGS)
+sfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For hfsplus.mod.
+hfsplus_mod_SOURCES = fs/hfsplus.c
+hfsplus_mod_CFLAGS = $(COMMON_CFLAGS)
+hfsplus_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reiserfs.mod.
+reiserfs_mod_SOURCES = fs/reiserfs.c
+reiserfs_mod_CFLAGS = $(COMMON_CFLAGS)
+reiserfs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For cpio.mod.
+cpio_mod_SOURCES = fs/cpio.c
+cpio_mod_CFLAGS = $(COMMON_CFLAGS)
+cpio_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For tar.mod.
+tar_mod_SOURCES = fs/tar.c
+tar_mod_CFLAGS = $(COMMON_CFLAGS)
+tar_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For udf.mod.
+udf_mod_SOURCES = fs/udf.c
+udf_mod_CFLAGS = $(COMMON_CFLAGS)
+udf_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For afs.mod.
+afs_mod_SOURCES = fs/afs.c
+afs_mod_CFLAGS = $(COMMON_CFLAGS)
+afs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For afs_be.mod.
+afs_be_mod_SOURCES = fs/afs_be.c
+afs_be_mod_CFLAGS = $(COMMON_CFLAGS)
+afs_be_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For befs.mod.
+befs_mod_SOURCES = fs/befs.c
+befs_mod_CFLAGS = $(COMMON_CFLAGS)
+befs_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For befs_be.mod.
+befs_be_mod_SOURCES = fs/befs_be.c
+befs_be_mod_CFLAGS = $(COMMON_CFLAGS)
+befs_be_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Partition maps.
+
+pkglib_MODULES += part_amiga.mod
+part_amiga_mod_SOURCES = partmap/amiga.c
+part_amiga_mod_CFLAGS = $(COMMON_CFLAGS)
+part_amiga_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_apple.mod
+part_apple_mod_SOURCES = partmap/apple.c
+part_apple_mod_CFLAGS = $(COMMON_CFLAGS)
+part_apple_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_msdos.mod
+part_msdos_mod_SOURCES = partmap/msdos.c
+part_msdos_mod_CFLAGS = $(COMMON_CFLAGS)
+part_msdos_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_sun.mod
+part_sun_mod_SOURCES = partmap/sun.c
+part_sun_mod_CFLAGS = $(COMMON_CFLAGS)
+part_sun_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_acorn.mod
+part_acorn_mod_SOURCES = partmap/acorn.c
+part_acorn_mod_CFLAGS = $(COMMON_CFLAGS)
+part_acorn_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_gpt.mod
+part_gpt_mod_SOURCES = partmap/gpt.c
+part_gpt_mod_CFLAGS = $(COMMON_CFLAGS)
+part_gpt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_bsd.mod
+part_bsd_mod_SOURCES = partmap/bsdlabel.c
+part_bsd_mod_CFLAGS = $(COMMON_CFLAGS)
+part_bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += part_sunpc.mod
+part_sunpc_mod_SOURCES = partmap/sunpc.c
+part_sunpc_mod_CFLAGS = $(COMMON_CFLAGS)
+part_sunpc_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Special disk structures and generic drivers
+
+pkglib_MODULES += raid.mod raid5rec.mod raid6rec.mod mdraid.mod dm_nv.mod \
+       lvm.mod scsi.mod
+
+# For raid.mod
+raid_mod_SOURCES = disk/raid.c
+raid_mod_CFLAGS = $(COMMON_CFLAGS)
+raid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For raid5rec.mod
+raid5rec_mod_SOURCES = disk/raid5_recover.c
+raid5rec_mod_CFLAGS = $(COMMON_CFLAGS)
+raid5rec_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For raid6rec.mod
+raid6rec_mod_SOURCES = disk/raid6_recover.c
+raid6rec_mod_CFLAGS = $(COMMON_CFLAGS)
+raid6rec_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mdraid.mod
+mdraid_mod_SOURCES = disk/mdraid_linux.c
+mdraid_mod_CFLAGS = $(COMMON_CFLAGS)
+mdraid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For dm_nv.mod
+dm_nv_mod_SOURCES = disk/dmraid_nvidia.c
+dm_nv_mod_CFLAGS = $(COMMON_CFLAGS)
+dm_nv_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lvm.mod
+lvm_mod_SOURCES = disk/lvm.c
+lvm_mod_CFLAGS = $(COMMON_CFLAGS)
+lvm_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For scsi.mod
+scsi_mod_SOURCES = disk/scsi.c
+scsi_mod_CFLAGS = $(COMMON_CFLAGS)
+scsi_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Commands.
+pkglib_MODULES += minicmd.mod extcmd.mod hello.mod handler.mod \
+       ls.mod cmp.mod cat.mod help.mod search.mod loopback.mod \
+       configfile.mod echo.mod         \
+       terminfo.mod test.mod blocklist.mod hexdump.mod         \
+       read.mod sleep.mod loadenv.mod crc.mod parttool.mod     \
+       msdospart.mod memrw.mod normal.mod sh.mod               \
+       gptsync.mod true.mod probe.mod password.mod             \
+       keystatus.mod
+
+# For password.mod.
+password_mod_SOURCES = commands/password.c
+password_mod_CFLAGS = $(COMMON_CFLAGS)
+password_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For gptsync.mod.
+gptsync_mod_SOURCES = commands/gptsync.c
+gptsync_mod_CFLAGS = $(COMMON_CFLAGS)
+gptsync_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For minicmd.mod.
+minicmd_mod_SOURCES = commands/minicmd.c
+minicmd_mod_CFLAGS = $(COMMON_CFLAGS)
+minicmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For extcmd.mod.
+extcmd_mod_SOURCES = commands/extcmd.c lib/arg.c
+extcmd_mod_CFLAGS = $(COMMON_CFLAGS)
+extcmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For hello.mod.
+hello_mod_SOURCES = hello/hello.c
+hello_mod_CFLAGS = $(COMMON_CFLAGS)
+hello_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For gfxmenu.mod.
+pkglib_MODULES += gfxmenu.mod
+gfxmenu_mod_SOURCES = \
+       gfxmenu/gfxmenu.c \
+       gfxmenu/model.c \
+       gfxmenu/view.c \
+       gfxmenu/icon_manager.c \
+       gfxmenu/theme_loader.c \
+       gfxmenu/widget-box.c \
+       gfxmenu/gui_canvas.c \
+       gfxmenu/gui_circular_progress.c \
+       gfxmenu/gui_box.c \
+       gfxmenu/gui_label.c \
+       gfxmenu/gui_list.c \
+       gfxmenu/gui_image.c \
+       gfxmenu/gui_progress_bar.c \
+       gfxmenu/gui_util.c \
+       gfxmenu/gui_string_util.c \
+       gfxmenu/named_colors.c
+gfxmenu_mod_CFLAGS = $(COMMON_CFLAGS)
+gfxmenu_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For parttool.mod.
+parttool_mod_SOURCES = commands/parttool.c
+parttool_mod_CFLAGS = $(COMMON_CFLAGS)
+parttool_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For msdospart.mod.
+msdospart_mod_SOURCES = parttool/msdospart.c
+msdospart_mod_CFLAGS = $(COMMON_CFLAGS)
+msdospart_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For handler.mod.
+handler_mod_SOURCES = commands/handler.c
+handler_mod_CFLAGS = $(COMMON_CFLAGS)
+handler_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ls.mod.
+ls_mod_SOURCES = commands/ls.c
+ls_mod_CFLAGS = $(COMMON_CFLAGS)
+ls_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For cmp.mod.
+cmp_mod_SOURCES = commands/cmp.c
+cmp_mod_CFLAGS = $(COMMON_CFLAGS)
+cmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For cat.mod.
+cat_mod_SOURCES = commands/cat.c
+cat_mod_CFLAGS = $(COMMON_CFLAGS)
+cat_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For echo.mod
+echo_mod_SOURCES = commands/echo.c
+echo_mod_CFLAGS = $(COMMON_CFLAGS)
+echo_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For help.mod.
+help_mod_SOURCES = commands/help.c
+help_mod_CFLAGS = $(COMMON_CFLAGS)
+help_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For search.mod.
+search_mod_SOURCES = commands/search_wrap.c
+search_mod_CFLAGS = $(COMMON_CFLAGS)
+search_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += search_fs_file.mod search_fs_uuid.mod search_label.mod
+
+# For search.mod.
+search_fs_file_mod_SOURCES = commands/search_file.c
+search_fs_file_mod_CFLAGS = $(COMMON_CFLAGS)
+search_fs_file_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For search.mod.
+search_label_mod_SOURCES = commands/search_label.c
+search_label_mod_CFLAGS = $(COMMON_CFLAGS)
+search_label_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For search.mod.
+search_fs_uuid_mod_SOURCES = commands/search_uuid.c
+search_fs_uuid_mod_CFLAGS = $(COMMON_CFLAGS)
+search_fs_uuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For test.mod.
+test_mod_SOURCES = commands/test.c
+test_mod_CFLAGS = $(COMMON_CFLAGS)
+test_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For loopback.mod
+loopback_mod_SOURCES = disk/loopback.c
+loopback_mod_CFLAGS = $(COMMON_CFLAGS)
+loopback_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For configfile.mod
+configfile_mod_SOURCES = commands/configfile.c
+configfile_mod_CFLAGS = $(COMMON_CFLAGS)
+configfile_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For terminfo.mod.
+terminfo_mod_SOURCES = term/terminfo.c term/tparm.c
+terminfo_mod_CFLAGS = $(COMMON_CFLAGS)
+terminfo_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For blocklist.mod.
+blocklist_mod_SOURCES = commands/blocklist.c
+blocklist_mod_CFLAGS = $(COMMON_CFLAGS)
+blocklist_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For hexdump.mod.
+hexdump_mod_SOURCES = commands/hexdump.c lib/hexdump.c
+hexdump_mod_CFLAGS = $(COMMON_CFLAGS)
+hexdump_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For read.mod.
+read_mod_SOURCES = commands/read.c
+read_mod_CFLAGS = $(COMMON_CFLAGS)
+read_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For sleep.mod.
+sleep_mod_SOURCES = commands/sleep.c
+sleep_mod_CFLAGS = $(COMMON_CFLAGS)
+sleep_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For loadenv.mod.
+loadenv_mod_SOURCES = commands/loadenv.c lib/envblk.c
+loadenv_mod_CFLAGS = $(COMMON_CFLAGS)
+loadenv_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For crc.mod.
+crc_mod_SOURCES = commands/crc.c lib/crc.c
+crc_mod_CFLAGS = $(COMMON_CFLAGS)
+crc_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memrw.mod.
+memrw_mod_SOURCES = commands/memrw.c
+memrw_mod_CFLAGS = $(COMMON_CFLAGS)
+memrw_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For true.mod
+true_mod_SOURCES = commands/true.c
+true_mod_CFLAGS = $(COMMON_CFLAGS)
+true_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For probe.mod.
+probe_mod_SOURCES = commands/probe.c
+probe_mod_CFLAGS = $(COMMON_CFLAGS)
+probe_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For keystatus.mod.
+keystatus_mod_SOURCES = commands/keystatus.c
+keystatus_mod_CFLAGS = $(COMMON_CFLAGS)
+keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For normal.mod.
+normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
+       normal/auth.c normal/autofs.c normal/handler.c \
+       normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
+       normal/menu_entry.c normal/menu_text.c \
+       normal/misc.c normal/crypto.c normal/term.c normal/context.c
+normal_mod_CFLAGS = $(COMMON_CFLAGS)
+normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For sh.mod.
+sh_mod_SOURCES = script/main.c script/script.c script/execute.c \
+       script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c
+sh_mod_CFLAGS = $(COMMON_CFLAGS) $(POSIX_CFLAGS) -Wno-error
+sh_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+ifneq (, $(FONT_SOURCE))
+font/font.c_DEPENDENCIES = ascii.h
+endif
+
+# Common Video Subsystem specific modules.
+# On Yeeloong it's part of kernel
+ifneq ($(platform), yeeloong)
+
+# For video.mod.
+pkglib_MODULES += video.mod
+video_mod_SOURCES = video/video.c
+video_mod_CFLAGS = $(COMMON_CFLAGS)
+video_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += video_fb.mod
+video_fb_mod_SOURCES = video/fb/video_fb.c video/fb/fbblit.c \
+                 video/fb/fbfill.c video/fb/fbutil.c
+video_fb_mod_CFLAGS = $(COMMON_CFLAGS)
+video_fb_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For bitmap.mod
+pkglib_MODULES += bitmap.mod
+bitmap_mod_SOURCES = video/bitmap.c
+bitmap_mod_CFLAGS = $(COMMON_CFLAGS)
+bitmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For bitmap_scale.mod
+pkglib_MODULES += bitmap_scale.mod
+bitmap_scale_mod_SOURCES = video/bitmap_scale.c
+bitmap_scale_mod_CFLAGS = $(COMMON_CFLAGS)
+bitmap_scale_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += font.mod
+font_mod_SOURCES = font/font_cmd.c font/font.c
+font_mod_CFLAGS = $(COMMON_CFLAGS)
+font_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For gfxterm.mod.
+pkglib_MODULES += gfxterm.mod
+gfxterm_mod_SOURCES = term/gfxterm.c
+gfxterm_mod_CFLAGS = $(COMMON_CFLAGS)
+gfxterm_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+endif
+
+# For videotest.mod.
+pkglib_MODULES += videotest.mod
+videotest_mod_SOURCES = commands/videotest.c
+videotest_mod_CFLAGS = $(COMMON_CFLAGS)
+videotest_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For tga.mod
+pkglib_MODULES += tga.mod
+tga_mod_SOURCES = video/readers/tga.c
+tga_mod_CFLAGS = $(COMMON_CFLAGS)
+tga_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For jpeg.mod.
+pkglib_MODULES += jpeg.mod
+jpeg_mod_SOURCES = video/readers/jpeg.c
+jpeg_mod_CFLAGS = $(COMMON_CFLAGS)
+jpeg_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For png.mod.
+pkglib_MODULES += png.mod
+png_mod_SOURCES = video/readers/png.c
+png_mod_CFLAGS = $(COMMON_CFLAGS)
+png_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+
+# Misc.
+pkglib_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
+gzio_mod_CFLAGS = $(COMMON_CFLAGS)
+gzio_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# On Yeeloong it's part of kernel
+ifneq ($(platform), yeeloong)
+# For bufio.mod.
+pkglib_MODULES += bufio.mod
+bufio_mod_SOURCES = io/bufio.c
+bufio_mod_CFLAGS = $(COMMON_CFLAGS)
+bufio_mod_LDFLAGS = $(COMMON_LDFLAGS)
+endif
+
+# For gettext.mod.
+pkglib_MODULES += gettext.mod
+gettext_mod_SOURCES = gettext/gettext.c
+gettext_mod_CFLAGS = $(COMMON_CFLAGS)
+gettext_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Misc.
+pkglib_MODULES += xnu_uuid.mod
+
+# For elf.mod.
+xnu_uuid_mod_SOURCES = commands/xnu_uuid.c
+xnu_uuid_mod_CFLAGS = $(COMMON_CFLAGS)
+xnu_uuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += trig.mod
+trig_mod_SOURCES = trigtables.c
+trig_mod_CFLAGS = $(COMMON_CFLAGS)
+trig_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+trigtables.c: gentrigtables
+       ./gentrigtables > $@
+DISTCLEANFILES += trigtables.c
+gentrigtables: gentrigtables.c
+       $(CC) -o $@ $^ $(CPPFLAGS) -lm
+DISTCLEANFILES += gentrigtables
+
+pkglib_MODULES += setjmp.mod
+setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S
+setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS)
+setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += charset.mod
+charset_mod_SOURCES = lib/charset.c
+charset_mod_CFLAGS = $(COMMON_CFLAGS)
+charset_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += regexp.mod
+regexp_mod_SOURCES = gnulib/regex.c commands/regexp.c
+regexp_mod_CFLAGS = $(COMMON_CFLAGS) $(GNULIB_CFLAGS)
+regexp_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += terminal.mod
+terminal_mod_SOURCES = commands/terminal.c
+terminal_mod_CFLAGS = $(COMMON_CFLAGS)
+terminal_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += crypto.mod
+crypto_mod_SOURCES = lib/crypto.c
+crypto_mod_CFLAGS = $(COMMON_CFLAGS)
+crypto_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += hashsum.mod
+hashsum_mod_SOURCES = commands/hashsum.c
+hashsum_mod_CFLAGS = $(COMMON_CFLAGS)
+hashsum_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += pbkdf2.mod
+pbkdf2_mod_SOURCES = lib/pbkdf2.c
+pbkdf2_mod_CFLAGS = $(COMMON_CFLAGS)
+pbkdf2_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For password_pbkdf2.mod.
+pkglib_MODULES += password_pbkdf2.mod
+password_pbkdf2_mod_SOURCES = commands/password_pbkdf2.c
+password_pbkdf2_mod_CFLAGS = $(COMMON_CFLAGS)
+password_pbkdf2_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For memdisk.mod.
+pkglib_MODULES += memdisk.mod
+memdisk_mod_SOURCES = disk/memdisk.c
+memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For reboot.mod.
+pkglib_MODULES += reboot.mod
+reboot_mod_SOURCES = commands/reboot.c
+reboot_mod_CFLAGS = $(COMMON_CFLAGS)
+reboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For date.mod
+pkglib_MODULES += date.mod
+date_mod_SOURCES = commands/date.c
+date_mod_CFLAGS = $(COMMON_CFLAGS)
+date_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datehook.mod
+pkglib_MODULES += datehook.mod
+datehook_mod_SOURCES = hook/datehook.c
+datehook_mod_CFLAGS = $(COMMON_CFLAGS)
+datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lsmmap.mod
+pkglib_MODULES += lsmmap.mod
+lsmmap_mod_SOURCES = commands/lsmmap.c
+lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
+lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For boot.mod.
+pkglib_MODULES += boot.mod
+boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c
+boot_mod_CFLAGS = $(COMMON_CFLAGS)
+boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+bin_UTILITIES += grub-mkpasswd-pbkdf2
+grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c util/mm.c kern/err.c
+grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap -DGRUB_MKPASSWD=1
+
+include $(srcdir)/conf/gcry.mk
diff --git a/grub-core/conf/i386-coreboot.rmk b/grub-core/conf/i386-coreboot.rmk
new file mode 100644 (file)
index 0000000..ca96963
--- /dev/null
@@ -0,0 +1,74 @@
+# -*- makefile -*-
+
+COMMON_CFLAGS = -mrtd -mregparm=3 
+
+# Images.
+
+GRUB_KERNEL_MACHINE_LINK_ADDR  = 0x8200
+
+pkglib_PROGRAMS += kernel.img
+kernel_img_SOURCES = kern/i386/coreboot/startup.S \
+       kern/i386/misc.S \
+       kern/i386/coreboot/init.c \
+       kern/i386/coreboot/mmap.c \
+       kern/i386/halt.c \
+       kern/main.c kern/device.c \
+       kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+       kern/misc.c kern/mm.c kern/term.c \
+       kern/rescue_parser.c kern/rescue_reader.c \
+       kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+       kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
+       kern/i386/tsc.c kern/i386/pit.c \
+       kern/generic/rtc_get_time_ms.c \
+       kern/generic/millisleep.c \
+       kern/env.c \
+       term/i386/pc/vga_text.c term/i386/vga_common.c \
+       symlist.c
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic
+
+sbin_SCRIPTS += grub-install
+grub_install_SOURCES = util/grub-install.in
+
+bin_SCRIPTS += grub-mkrescue
+grub_mkrescue_SOURCES = util/grub-mkrescue.in
+
+# Modules.
+pkglib_MODULES = linux.mod aout.mod halt.mod datetime.mod mmap.mod
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/i386/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod.
+halt_mod_SOURCES = commands/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For aout.mod.
+aout_mod_SOURCES = loader/aout.c
+aout_mod_CFLAGS = $(COMMON_CFLAGS)
+aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For bsd.mod
+pkglib_MODULES += bsd.mod
+bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S
+bsd_mod_CFLAGS = $(COMMON_CFLAGS)
+bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/cmos_datetime.c
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/i386.mk
+include $(srcdir)/conf/common.mk
diff --git a/grub-core/conf/i386-efi.rmk b/grub-core/conf/i386-efi.rmk
new file mode 100644 (file)
index 0000000..e826cb3
--- /dev/null
@@ -0,0 +1,5 @@
+# -*- makefile -*-
+
+COMMON_LDFLAGS = -melf_i386
+
+include $(srcdir)/conf/x86-efi.mk
diff --git a/grub-core/conf/i386-ieee1275.rmk b/grub-core/conf/i386-ieee1275.rmk
new file mode 100644 (file)
index 0000000..05ba38a
--- /dev/null
@@ -0,0 +1,81 @@
+# -*- makefile -*-
+
+COMMON_CFLAGS  = -mrtd -mregparm=3
+
+# Images.
+pkglib_PROGRAMS = kernel.img
+
+# For kernel.img.
+kernel_img_SOURCES = kern/i386/ieee1275/startup.S \
+       kern/i386/misc.S \
+       kern/i386/ieee1275/init.c \
+       kern/ieee1275/init.c \
+       kern/ieee1275/mmap.c \
+       kern/ieee1275/cmain.c kern/ieee1275/openfw.c \
+       kern/main.c kern/device.c \
+       kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+       kern/misc.c kern/mm.c kern/term.c \
+       kern/rescue_parser.c kern/rescue_reader.c \
+       kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
+       kern/env.c \
+       kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+       kern/generic/millisleep.c \
+       kern/ieee1275/ieee1275.c \
+       term/ieee1275/ofconsole.c \
+       disk/ieee1275/ofdisk.c \
+       symlist.c
+kernel_img_HEADERS += ieee1275/ieee1275.h
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+
+# For grub-install.
+grub_install_SOURCES = util/ieee1275/grub-install.in
+
+# Modules.
+pkglib_MODULES = halt.mod suspend.mod          \
+       aout.mod linux.mod      \
+       nand.mod datetime.mod   \
+       mmap.mod
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For aout.mod.
+aout_mod_SOURCES = loader/aout.c
+aout_mod_CFLAGS = $(COMMON_CFLAGS)
+aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For suspend.mod
+suspend_mod_SOURCES = commands/ieee1275/suspend.c
+suspend_mod_CFLAGS = $(COMMON_CFLAGS)
+suspend_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod
+halt_mod_SOURCES = commands/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/i386/ieee1275/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For nand.mod.
+nand_mod_SOURCES = disk/ieee1275/nand.c
+nand_mod_CFLAGS = $(COMMON_CFLAGS)
+nand_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/cmos_datetime.c
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/i386.mk
+include $(srcdir)/conf/common.mk
diff --git a/grub-core/conf/i386-multiboot.rmk b/grub-core/conf/i386-multiboot.rmk
new file mode 100644 (file)
index 0000000..69b8e9a
--- /dev/null
@@ -0,0 +1,74 @@
+# -*- makefile -*-
+
+COMMON_CFLAGS = -mrtd -mregparm=3 
+
+# Images.
+
+GRUB_KERNEL_MACHINE_LINK_ADDR  = 0x8200
+
+pkglib_PROGRAMS += kernel.img
+kernel_img_SOURCES = kern/i386/coreboot/startup.S \
+       kern/i386/misc.S \
+       kern/i386/coreboot/init.c \
+       kern/i386/multiboot_mmap.c \
+       kern/i386/halt.c \
+       kern/main.c kern/device.c \
+       kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+       kern/misc.c kern/mm.c kern/term.c \
+       kern/rescue_parser.c kern/rescue_reader.c \
+       kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+       kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
+       kern/i386/tsc.c kern/i386/pit.c \
+       kern/generic/rtc_get_time_ms.c \
+       kern/generic/millisleep.c \
+       kern/env.c \
+       term/i386/pc/vga_text.c term/i386/vga_common.c \
+       symlist.c
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic
+
+sbin_SCRIPTS += grub-install
+grub_install_SOURCES = util/grub-install.in
+
+bin_SCRIPTS += grub-mkrescue
+grub_mkrescue_SOURCES = util/grub-mkrescue.in
+
+# Modules.
+pkglib_MODULES = linux.mod aout.mod halt.mod datetime.mod mmap.mod
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/i386/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod.
+halt_mod_SOURCES = commands/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For aout.mod.
+aout_mod_SOURCES = loader/aout.c
+aout_mod_CFLAGS = $(COMMON_CFLAGS)
+aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For bsd.mod
+pkglib_MODULES += bsd.mod
+bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S
+bsd_mod_CFLAGS = $(COMMON_CFLAGS)
+bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/cmos_datetime.c
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/i386.mk
+include $(srcdir)/conf/common.mk
diff --git a/grub-core/conf/i386-pc-cygwin-img-ld.sc b/grub-core/conf/i386-pc-cygwin-img-ld.sc
new file mode 100644 (file)
index 0000000..a41cac7
--- /dev/null
@@ -0,0 +1,53 @@
+/* Linker script to create grub .img files on Cygwin.  */
+
+SECTIONS
+{
+  .text :
+  {
+    start = . ;
+    *(.text)
+    etext = . ;
+  }
+  .data :
+  {
+    __data_start__ = . ;
+    *(.data)
+    __data_end__ = . ;
+  }
+  .rdata :
+  {
+    __rdata_start__ = . ;
+    *(.rdata)
+    __rdata_end__ = . ;
+  }
+  .pdata :
+  {
+    *(.pdata)
+    edata = . ;
+  }
+  .bss :
+  {
+    __bss_start__ = . ;
+    *(.bss)
+    __common_start__ = . ;
+    *(COMMON)
+    __bss_end__ = . ;
+  }
+  .edata :
+  {
+    *(.edata)
+    end = . ;
+  }
+  .stab :
+  {
+    *(.stab)
+  }
+  .stabstr :
+  {
+    *(.stabstr)
+  }
+}
+
+ASSERT("__rdata_end__"=="edata", ".pdata not empty")
+ASSERT("__bss_end__"  =="end"  , ".edata not empty")
+
diff --git a/grub-core/conf/i386-pc.rmk b/grub-core/conf/i386-pc.rmk
new file mode 100644 (file)
index 0000000..a5a1b08
--- /dev/null
@@ -0,0 +1,305 @@
+# -*- makefile -*-
+
+GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200
+
+COMMON_CFLAGS = -mrtd -mregparm=3
+
+# Images.
+pkglib_IMAGES = boot.img cdboot.img diskboot.img kernel.img lnxboot.img \
+       pxeboot.img
+
+# For boot.img.
+boot_img_SOURCES = boot/i386/pc/boot.S
+boot_img_ASFLAGS = $(COMMON_ASFLAGS)
+boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00
+boot_img_FORMAT = binary
+
+# For pxeboot.img
+pxeboot_img_SOURCES = boot/i386/pc/pxeboot.S
+pxeboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+pxeboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00
+pxeboot_img_FORMAT = binary
+
+# For diskboot.img.
+diskboot_img_SOURCES = boot/i386/pc/diskboot.S
+diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x8000
+diskboot_img_FORMAT = binary
+
+# For lnxboot.img.
+lnxboot_img_SOURCES = boot/i386/pc/lnxboot.S
+lnxboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+lnxboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x6000
+lnxboot_img_FORMAT = binary
+
+# For cdboot.img.
+cdboot_img_SOURCES = boot/i386/pc/cdboot.S
+cdboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00
+cdboot_img_FORMAT = binary
+
+# For kernel.img.
+kernel_img_SOURCES = kern/i386/pc/startup.S \
+       kern/i386/misc.S \
+       kern/main.c kern/device.c \
+       kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+       kern/misc.c kern/mm.c kern/term.c \
+       kern/rescue_parser.c kern/rescue_reader.c \
+       kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+       kern/$(target_cpu)/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \
+       kern/parser.c kern/partition.c \
+       kern/i386/tsc.c kern/i386/pit.c \
+       kern/generic/rtc_get_time_ms.c \
+       kern/generic/millisleep.c \
+       kern/env.c \
+       term/i386/pc/console.c term/i386/vga_common.c \
+       symlist.c
+kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \
+       machine/pxe.h i386/pit.h
+kernel_img_CFLAGS = $(COMMON_CFLAGS)  $(TARGET_IMG_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
+kernel_img_FORMAT = binary
+
+# Utilities.
+bin_UTILITIES = grub-mkimage
+sbin_UTILITIES = grub-setup
+
+# For grub-mkimage.
+grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \
+       util/resolve.c lib/LzmaEnc.c lib/LzFind.c
+grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
+util/grub-mkrawimage.c_DEPENDENCIES = Makefile
+
+# For grub-setup.
+util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h
+grub_setup_SOURCES = gnulib/progname.c \
+       util/i386/pc/grub-setup.c util/hostdisk.c       \
+       util/misc.c util/getroot.c kern/device.c kern/disk.c    \
+       kern/err.c kern/misc.c kern/parser.c kern/partition.c   \
+       kern/file.c kern/fs.c kern/env.c kern/list.c            \
+       fs/fshelp.c                                             \
+       \
+       fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c          \
+       fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c   \
+       fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c       \
+       fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c           \
+       fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c             \
+       \
+       partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c      \
+       partmap/gpt.c           \
+       \
+       disk/raid.c disk/mdraid_linux.c disk/lvm.c              \
+       util/raid.c util/lvm.c util/mm.c                        \
+       grub_setup_init.c
+
+sbin_SCRIPTS += grub-install
+grub_install_SOURCES = util/grub-install.in
+
+bin_SCRIPTS += grub-mkrescue
+grub_mkrescue_SOURCES = util/grub-mkrescue.in
+
+pkglib_MODULES = biosdisk.mod chain.mod                                \
+       halt.mod                                \
+       vbe.mod vbetest.mod vbeinfo.mod                 \
+       vga.mod                         \
+       aout.mod bsd.mod pxe.mod pxecmd.mod datetime.mod        \
+       ata_pthru.mod hdparm.mod                \
+       usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod \
+       efiemu.mod mmap.mod acpi.mod drivemap.mod
+
+# For drivemap.mod.
+drivemap_mod_SOURCES = commands/i386/pc/drivemap.c \
+                       commands/i386/pc/drivemap_int13h.S
+drivemap_mod_ASFLAGS = $(COMMON_ASFLAGS)
+drivemap_mod_CFLAGS = $(COMMON_CFLAGS)
+drivemap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For efiemu.mod.
+efiemu_mod_SOURCES = efiemu/main.c efiemu/i386/loadcore32.c \
+                    efiemu/i386/loadcore64.c efiemu/i386/pc/cfgtables.c \
+                    efiemu/mm.c efiemu/loadcore_common.c efiemu/symbols.c \
+                    efiemu/loadcore32.c efiemu/loadcore64.c \
+                    efiemu/prepare32.c efiemu/prepare64.c efiemu/pnvram.c \
+                    efiemu/i386/coredetect.c
+efiemu_mod_CFLAGS = $(COMMON_CFLAGS)
+efiemu_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For acpi.mod.
+acpi_mod_SOURCES = commands/acpi.c commands/i386/pc/acpi.c
+acpi_mod_CFLAGS = $(COMMON_CFLAGS)
+acpi_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \
+                  mmap/i386/pc/mmap.c mmap/i386/pc/mmap_helper.S
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For biosdisk.mod.
+biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c
+biosdisk_mod_CFLAGS = $(COMMON_CFLAGS)
+biosdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For chain.mod.
+chain_mod_SOURCES = loader/i386/pc/chainloader.c
+chain_mod_CFLAGS = $(COMMON_CFLAGS)
+chain_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += linux16.mod
+linux16_mod_SOURCES = loader/i386/pc/linux.c
+linux16_mod_CFLAGS = $(COMMON_CFLAGS)
+linux16_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += linux.mod
+linux_mod_SOURCES = loader/i386/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += xnu.mod
+xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/pc/xnu.c \
+        loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c
+xnu_mod_CFLAGS = $(COMMON_CFLAGS)
+xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
+xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For halt.mod.
+halt_mod_SOURCES = commands/i386/pc/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For vbe.mod.
+vbe_mod_SOURCES = video/i386/pc/vbe.c
+vbe_mod_CFLAGS = $(COMMON_CFLAGS)
+vbe_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For vbeinfo.mod.
+vbeinfo_mod_SOURCES = commands/i386/pc/vbeinfo.c
+vbeinfo_mod_CFLAGS = $(COMMON_CFLAGS)
+vbeinfo_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For vbetest.mod.
+vbetest_mod_SOURCES = commands/i386/pc/vbetest.c
+vbetest_mod_CFLAGS = $(COMMON_CFLAGS)
+vbetest_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For vga.mod.
+vga_mod_SOURCES = term/i386/pc/vga.c
+vga_mod_CFLAGS = $(COMMON_CFLAGS)
+vga_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For aout.mod
+aout_mod_SOURCES = loader/aout.c
+aout_mod_CFLAGS = $(COMMON_CFLAGS)
+aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For bsd.mod
+bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S
+bsd_mod_CFLAGS = $(COMMON_CFLAGS)
+bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For usb.mod
+usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c
+usb_mod_CFLAGS = $(COMMON_CFLAGS)
+usb_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usbtest.mod
+usbtest_mod_SOURCES = commands/usbtest.c
+usbtest_mod_CFLAGS = $(COMMON_CFLAGS)
+usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For uhci.mod
+uhci_mod_SOURCES = bus/usb/uhci.c
+uhci_mod_CFLAGS = $(COMMON_CFLAGS)
+uhci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ohci.mod
+ohci_mod_SOURCES = bus/usb/ohci.c
+ohci_mod_CFLAGS = $(COMMON_CFLAGS)
+ohci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usbms.mod
+usbms_mod_SOURCES = disk/usbms.c
+usbms_mod_CFLAGS = $(COMMON_CFLAGS)
+usbms_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usb_keyboard.mod
+usb_keyboard_mod_SOURCES = term/usb_keyboard.c
+usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS)
+usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pxe.mod
+pxe_mod_SOURCES = fs/i386/pc/pxe.c
+pxe_mod_CFLAGS = $(COMMON_CFLAGS)
+pxe_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pxecmd.mod
+pxecmd_mod_SOURCES = commands/i386/pc/pxecmd.c
+pxecmd_mod_CFLAGS = $(COMMON_CFLAGS)
+pxecmd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/cmos_datetime.c
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ata_pthru.mod.
+ata_pthru_mod_SOURCES = disk/ata_pthru.c
+ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS)
+ata_pthru_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For hdparm.mod.
+hdparm_mod_SOURCES = commands/hdparm.c lib/hexdump.c
+hdparm_mod_CFLAGS = $(COMMON_CFLAGS)
+hdparm_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+ifeq ($(enable_efiemu), yes)
+
+efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF)
+       -rm -f $@
+ifeq ($(TARGET_APPLE_CC), 1)
+       -rm -f $@.bin
+       $(TARGET_CC) -c -m32 -DELF32 -DAPPLE_CC -o $@.bin -Wall -Werror $< -nostdlib -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+       $(OBJCONV) -felf32 -nu -nd $@.bin $@
+       -rm -f $@.bin
+else
+       $(TARGET_CC) -c -m32 -DELF32 -o $@ -Wall -Werror $< -nostdlib -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+       if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+endif
+
+efiemu64_c.o: efiemu/runtime/efiemu.c
+ifeq ($(TARGET_APPLE_CC), 1)
+       $(TARGET_CC) -c -m64 -DAPPLE_CC=1 -DELF64 -o $@ -Wall -Werror $< -nostdlib -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+else
+       $(TARGET_CC) -c -m64 -DELF64 -o $@ -Wall -Werror $< -nostdlib  -mcmodel=large -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+endif
+
+efiemu64_s.o: efiemu/runtime/efiemu.S
+       -rm -f $@
+ifeq ($(TARGET_APPLE_CC), 1)
+       $(TARGET_CC) -c -m64 -DAPPLE_CC=1 -DELF64 -o $@ -Wall -Werror $< -nostdlib -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+else
+       $(TARGET_CC) -c -m64 -DELF64 -o $@ -Wall -Werror $< -nostdlib  -mcmodel=large -mno-red-zone -O2 -I$(srcdir)/efiemu/runtime -I$(srcdir)/include -Iinclude
+endif
+
+efiemu64.o: efiemu64_c.o efiemu64_s.o  $(TARGET_OBJ2ELF)
+       -rm -f $@
+ifeq ($(TARGET_APPLE_CC), 1)
+       -rm -f $@.bin
+       $(TARGET_CC) -m64 -o $@.bin -Wl,-r $^ -nostdlib
+       $(OBJCONV) -felf64 -nu -nd $@.bin $@
+       -rm -f $@.bin
+else
+       $(TARGET_CC) -m64 -o $@ -Wl,-r $^ -nostdlib
+       if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
+endif
+
+CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o
+pkglib_DATA += efiemu32.o efiemu64.o
+
+endif
+
+include $(srcdir)/conf/i386.mk
+include $(srcdir)/conf/common.mk
diff --git a/grub-core/conf/i386-qemu.rmk b/grub-core/conf/i386-qemu.rmk
new file mode 100644 (file)
index 0000000..664bef1
--- /dev/null
@@ -0,0 +1,88 @@
+# -*- makefile -*-
+
+COMMON_CFLAGS = -mrtd -mregparm=3
+
+# Images.
+
+GRUB_KERNEL_MACHINE_LINK_ADDR  = 0x8200
+GRUB_BOOT_MACHINE_LINK_ADDR    = 0xffe00
+
+pkglib_IMAGES += boot.img
+boot_img_SOURCES = boot/i386/qemu/boot.S
+boot_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)
+boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LINK_ADDR)
+boot_img_FORMAT = binary
+
+bin_UTILITIES += grub-mkimage
+grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \
+       util/resolve.c gnulib/progname.c
+grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
+util/grub-mkrawimage.c_DEPENDENCIES = Makefile
+
+pkglib_IMAGES += kernel.img
+kernel_img_SOURCES = kern/i386/qemu/startup.S \
+       kern/i386/misc.S \
+       kern/i386/coreboot/init.c \
+       kern/i386/qemu/mmap.c \
+       kern/i386/halt.c \
+       kern/main.c kern/device.c \
+       kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+       kern/misc.c kern/mm.c kern/term.c \
+       kern/rescue_parser.c kern/rescue_reader.c \
+       kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+       kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
+       kern/i386/tsc.c kern/i386/pit.c \
+       kern/generic/rtc_get_time_ms.c \
+       kern/generic/millisleep.c \
+       kern/env.c \
+       term/i386/pc/vga_text.c term/i386/vga_common.c \
+       symlist.c
+kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)
+kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR)
+kernel_img_FORMAT = binary
+
+sbin_SCRIPTS += grub-install
+grub_install_SOURCES = util/grub-install.in
+
+bin_SCRIPTS += grub-mkrescue
+grub_mkrescue_SOURCES = util/grub-mkrescue.in
+
+# Modules.
+pkglib_MODULES = linux.mod aout.mod halt.mod datetime.mod mmap.mod
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For linux.mod.
+linux_mod_SOURCES = loader/i386/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod.
+halt_mod_SOURCES = commands/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For aout.mod.
+aout_mod_SOURCES = loader/aout.c
+aout_mod_CFLAGS = $(COMMON_CFLAGS)
+aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For bsd.mod
+pkglib_MODULES += bsd.mod
+bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S
+bsd_mod_CFLAGS = $(COMMON_CFLAGS)
+bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/cmos_datetime.c
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/i386.mk
+include $(srcdir)/conf/common.mk
diff --git a/grub-core/conf/i386.rmk b/grub-core/conf/i386.rmk
new file mode 100644 (file)
index 0000000..02ce398
--- /dev/null
@@ -0,0 +1,75 @@
+# -*- makefile -*-
+
+pkglib_MODULES += cpuid.mod
+cpuid_mod_SOURCES = commands/i386/cpuid.c
+cpuid_mod_CFLAGS = $(COMMON_CFLAGS)
+cpuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += at_keyboard.mod
+at_keyboard_mod_SOURCES = term/at_keyboard.c
+at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS)
+at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += vga_text.mod
+vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c
+vga_text_mod_CFLAGS = $(COMMON_CFLAGS)
+vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += relocator.mod
+relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S
+relocator_mod_CFLAGS = $(COMMON_CFLAGS)
+relocator_mod_ASFLAGS = $(COMMON_ASFLAGS)
+relocator_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += ata.mod
+ata_mod_SOURCES = disk/ata.c
+ata_mod_CFLAGS = $(COMMON_CFLAGS)
+ata_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For setpci.mod
+pkglib_MODULES += setpci.mod
+setpci_mod_SOURCES = commands/setpci.c
+setpci_mod_CFLAGS = $(COMMON_CFLAGS)
+setpci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += multiboot.mod
+multiboot_mod_SOURCES = loader/multiboot.c loader/i386/multiboot_mbi.c
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+pkglib_MODULES += multiboot2.mod
+multiboot2_mod_SOURCES = loader/multiboot.c loader/multiboot_mbi2.c
+multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2
+multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS)
+multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For serial.mod.
+pkglib_MODULES += serial.mod
+serial_mod_SOURCES = term/serial.c
+serial_mod_CFLAGS = $(COMMON_CFLAGS)
+serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pci.mod
+pkglib_MODULES += pci.mod
+pci_mod_SOURCES = bus/pci.c
+pci_mod_CFLAGS = $(COMMON_CFLAGS)
+pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lspci.mod
+pkglib_MODULES += lspci.mod
+lspci_mod_SOURCES = commands/lspci.c
+lspci_mod_CFLAGS = $(COMMON_CFLAGS)
+lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For play.mod.
+pkglib_MODULES += play.mod
+play_mod_SOURCES = commands/i386/pc/play.c
+play_mod_CFLAGS = $(COMMON_CFLAGS)
+play_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For iorw.mod.
+pkglib_MODULES += iorw.mod
+iorw_mod_SOURCES = commands/iorw.c
+iorw_mod_CFLAGS = $(COMMON_CFLAGS)
+iorw_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/grub-core/conf/mips-qemu-mips.rmk b/grub-core/conf/mips-qemu-mips.rmk
new file mode 100644 (file)
index 0000000..af5b26b
--- /dev/null
@@ -0,0 +1,22 @@
+# -*- makefile -*-
+LINK_BASE = 0x80010000
+target_machine=qemu-mips
+COMMON_CFLAGS += -march=mips3
+COMMON_ASFLAGS += -march=mips3
+include $(srcdir)/conf/mips.mk
+
+pkglib_IMAGES = kernel.img
+kernel_img_SOURCES = kern/$(target_cpu)/startup.S \
+       kern/main.c kern/device.c kern/$(target_cpu)/init.c \
+       kern/$(target_cpu)/$(target_machine)/init.c             \
+       kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c          \
+       kern/misc.c kern/mm.c kern/term.c       \
+       kern/rescue_parser.c kern/rescue_reader.c \
+       kern/list.c kern/handler.c kern/command.c kern/corecmd.c        \
+       kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c       \
+       kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c    \
+       symlist.c kern/$(target_cpu)/cache.S
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic
+kernel_img_FORMAT = binary
diff --git a/grub-core/conf/mips-yeeloong.rmk b/grub-core/conf/mips-yeeloong.rmk
new file mode 100644 (file)
index 0000000..6a96ddf
--- /dev/null
@@ -0,0 +1,73 @@
+# -*- makefile -*-
+LINK_BASE = 0x80200000
+target_machine=yeeloong
+COMMON_CFLAGS += -march=mips3
+COMMON_ASFLAGS += -march=mips3
+
+kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h bitmap_scale.h bufio.h
+
+include $(srcdir)/conf/mips.mk
+
+pkglib_IMAGES = kernel.img
+kernel_img_SOURCES = kern/$(target_cpu)/startup.S \
+       kern/main.c kern/device.c kern/$(target_cpu)/init.c \
+       kern/$(target_cpu)/$(target_machine)/init.c             \
+       kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c          \
+       kern/misc.c kern/mm.c kern/term.c       \
+       kern/rescue_parser.c kern/rescue_reader.c \
+       kern/list.c kern/handler.c kern/command.c kern/corecmd.c        \
+       kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c       \
+       kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c    \
+       kern/$(target_cpu)/cache.S \
+       \
+       term/at_keyboard.c \
+       font/font_cmd.c font/font.c io/bufio.c \
+       video/video.c video/fb/video_fb.c video/fb/fbblit.c \
+       video/fb/fbfill.c video/fb/fbutil.c video/bitmap.c \
+       video/bitmap_scale.c video/sm712.c bus/pci.c bus/bonito.c \
+       term/gfxterm.c commands/extcmd.c lib/arg.c \
+       symlist.c
+kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic
+kernel_img_FORMAT = binary
+
+# For ata.mod.
+pkglib_MODULES += ata.mod
+ata_mod_SOURCES = disk/ata.c
+ata_mod_CFLAGS = $(COMMON_CFLAGS)
+ata_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For lspci.mod
+pkglib_MODULES += lspci.mod
+lspci_mod_SOURCES = commands/lspci.c
+lspci_mod_CFLAGS = $(COMMON_CFLAGS)
+lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For ata_pthru.mod.
+pkglib_MODULES += ata_pthru.mod
+ata_pthru_mod_SOURCES = disk/ata_pthru.c
+ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS)
+ata_pthru_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mmap.mod.
+pkglib_MODULES += mmap.mod
+mmap_mod_SOURCES = mmap/mmap.c mmap/mips/yeeloong/uppermem.c
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For datetime.mod
+pkglib_MODULES += datetime.mod
+datetime_mod_SOURCES = lib/cmos_datetime.c
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += linux.mod
+linux_mod_SOURCES = loader/$(target_cpu)/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_ASFLAGS = $(COMMON_ASFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+sbin_SCRIPTS += grub-install
+grub_install_SOURCES = util/grub-install.in
diff --git a/grub-core/conf/mips.rmk b/grub-core/conf/mips.rmk
new file mode 100644 (file)
index 0000000..4603c21
--- /dev/null
@@ -0,0 +1,40 @@
+
+# -*- makefile -*-
+
+COMMON_CFLAGS += -mexplicit-relocs -mflush-func=grub_cpu_flush_cache
+
+# Images.
+kernel_img_HEADERS += cpu/cache.h
+
+# Scripts.
+sbin_SCRIPTS = 
+bin_SCRIPTS = 
+
+# For grub-mkimage.
+bin_UTILITIES += grub-mkimage
+grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \
+       util/resolve.c lib/LzmaEnc.c lib/LzFind.c
+grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE)
+util/grub-mkrawimage.c_DEPENDENCIES = Makefile
+
+# For serial.mod.
+pkglib_MODULES += serial.mod
+serial_mod_SOURCES = term/serial.c
+serial_mod_CFLAGS = $(COMMON_CFLAGS)
+serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For relocator.mod.
+pkglib_MODULES += relocator.mod
+relocator_mod_SOURCES = lib/$(target_cpu)/relocator.c lib/$(target_cpu)/relocator_asm.S
+relocator_mod_CFLAGS = $(COMMON_CFLAGS)
+relocator_mod_ASFLAGS = $(COMMON_ASFLAGS)
+relocator_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += multiboot2.mod
+multiboot2_mod_SOURCES = loader/multiboot.c \
+                        loader/multiboot_mbi2.c
+multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2
+multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS)
+multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+include $(srcdir)/conf/common.mk
diff --git a/grub-core/conf/powerpc-ieee1275.rmk b/grub-core/conf/powerpc-ieee1275.rmk
new file mode 100644 (file)
index 0000000..d5968ac
--- /dev/null
@@ -0,0 +1,68 @@
+
+# -*- makefile -*-
+
+# Images.
+
+kernel_img_HEADERS += ieee1275/ieee1275.h
+
+# Programs
+pkglib_PROGRAMS = kernel.img
+
+kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \
+       kern/ieee1275/ieee1275.c kern/main.c kern/device.c              \
+       kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c          \
+       kern/misc.c kern/mm.c kern/term.c       \
+       kern/rescue_parser.c kern/rescue_reader.c \
+       kern/list.c kern/handler.c kern/command.c kern/corecmd.c        \
+       kern/ieee1275/init.c                                            \
+       kern/ieee1275/mmap.c                                            \
+       term/ieee1275/ofconsole.c               \
+       kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c           \
+       kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c       \
+       kern/generic/millisleep.c kern/time.c                            \
+       symlist.c kern/$(target_cpu)/cache.S
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x200000,-Bstatic
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+bin_SCRIPTS = grub-mkrescue
+
+# For grub-install.
+grub_install_SOURCES = util/ieee1275/grub-install.in
+
+# For grub-mkrescue.
+grub_mkrescue_SOURCES = util/powerpc/ieee1275/grub-mkrescue.in
+
+# Modules.
+pkglib_MODULES += ieee1275_fb.mod 
+ieee1275_fb_mod_SOURCES = video/ieee1275.c
+ieee1275_fb_mod_CFLAGS = $(COMMON_CFLAGS)
+ieee1275_fb_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+pkglib_MODULES += linux.mod
+linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For suspend.mod
+pkglib_MODULES += suspend.mod
+suspend_mod_SOURCES = commands/ieee1275/suspend.c
+suspend_mod_CFLAGS = $(COMMON_CFLAGS)
+suspend_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod
+pkglib_MODULES += halt.mod
+halt_mod_SOURCES = commands/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datetime.mod
+pkglib_MODULES += datetime.mod
+datetime_mod_SOURCES = lib/ieee1275/datetime.c
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/common.mk
diff --git a/grub-core/conf/sparc64-ieee1275.rmk b/grub-core/conf/sparc64-ieee1275.rmk
new file mode 100644 (file)
index 0000000..f0c9b0d
--- /dev/null
@@ -0,0 +1,106 @@
+
+# -*- makefile -*-
+
+COMMON_CFLAGS = -mno-app-regs
+COMMON_LDFLAGS = -melf64_sparc -mno-relax
+
+# Images.
+pkglib_IMAGES = boot.img diskboot.img kernel.img
+
+# For boot.img.
+boot_img_SOURCES = boot/sparc64/ieee1275/boot.S
+boot_img_ASFLAGS = $(COMMON_ASFLAGS)
+boot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4000
+boot_img_FORMAT = a.out-sunos-big
+
+# For diskboot.img.
+diskboot_img_SOURCES = boot/sparc64/ieee1275/diskboot.S
+diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4200
+diskboot_img_FORMAT = binary
+
+kernel_img_HEADERS += ieee1275/ieee1275.h cpu/ieee1275/ieee1275.h
+kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c        \
+       kern/ieee1275/ieee1275.c kern/main.c kern/device.c              \
+       kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c          \
+       kern/misc.c kern/mm.c kern/term.c                       \
+       kern/rescue_parser.c kern/rescue_reader.c \
+       kern/list.c kern/handler.c kern/command.c kern/corecmd.c        \
+       kern/sparc64/ieee1275/ieee1275.c                                \
+       kern/sparc64/ieee1275/init.c                                    \
+       kern/ieee1275/mmap.c                                            \
+       term/ieee1275/ofconsole.c                                       \
+       kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c                   \
+       kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c       \
+       kern/generic/millisleep.c kern/time.c                           \
+       symlist.c kern/$(target_cpu)/cache.S
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS += -nostdlib -Wl,-N,-Ttext,0x4400,-Bstatic,-melf64_sparc
+kernel_img_FORMAT = binary
+
+# Utilities.
+bin_UTILITIES = grub-mkimage
+sbin_UTILITIES = grub-setup grub-ofpathname
+
+# For grub-mkimage.
+grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \
+        util/resolve.c gnulib/progname.c
+
+# For grub-setup.
+util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h
+grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c        \
+       util/ieee1275/ofpath.c \
+       util/misc.c util/getroot.c kern/device.c kern/disk.c    \
+       kern/err.c kern/misc.c kern/parser.c kern/partition.c   \
+       kern/file.c kern/fs.c kern/env.c kern/list.c            \
+       fs/fshelp.c                                             \
+       \
+       fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c         \
+       fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c  \
+       fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c       \
+       fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c           \
+       fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c             \
+       \
+       partmap/amiga.c partmap/apple.c partmap/msdos.c         \
+       partmap/bsdlabel.c partmap/sun.c partmap/acorn.c        \
+       \
+       disk/raid.c disk/mdraid_linux.c disk/lvm.c              \
+       util/raid.c util/lvm.c util/mm.c gnulib/progname.c      \
+       grub_setup_init.c
+
+# For grub-ofpathname.
+grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \
+       util/ieee1275/ofpath.c util/misc.c gnulib/progname.c
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+
+# For grub-install.
+grub_install_SOURCES = util/grub-install.in
+
+# Modules.
+pkglib_MODULES += ieee1275_fb.mod 
+ieee1275_fb_mod_SOURCES = video/ieee1275.c
+ieee1275_fb_mod_CFLAGS = $(COMMON_CFLAGS)
+ieee1275_fb_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+pkglib_MODULES += linux.mod 
+linux_mod_SOURCES = loader/sparc64/ieee1275/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For halt.mod.
+pkglib_MODULES += halt.mod
+halt_mod_SOURCES = commands/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datetime.mod
+pkglib_MODULES += datetime.mod
+datetime_mod_SOURCES = lib/ieee1275/datetime.c
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+include $(srcdir)/conf/common.mk
diff --git a/grub-core/conf/tests.rmk b/grub-core/conf/tests.rmk
new file mode 100644 (file)
index 0000000..9af2f8f
--- /dev/null
@@ -0,0 +1,94 @@
+# -*- makefile -*-
+
+# For grub-shell
+grub-shell: tests/util/grub-shell.in config.status
+       ./config.status --file=$@:$<
+       chmod +x $@
+check_SCRIPTS += grub-shell
+CLEANFILES += grub-shell
+
+# For grub-shell-tester
+grub-shell-tester: tests/util/grub-shell-tester.in config.status
+       ./config.status --file=$@:$<
+       chmod +x $@
+check_SCRIPTS += grub-shell-tester
+CLEANFILES += grub-shell-tester
+
+pkglib_MODULES += functional_test.mod
+functional_test_mod_SOURCES = tests/lib/functional_test.c tests/lib/test.c
+functional_test_mod_CFLAGS  = $(COMMON_CFLAGS)
+functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Rules for unit tests
+check_UTILITIES += example_unit_test
+example_unit_test_SOURCES = tests/example_unit_test.c kern/list.c kern/misc.c tests/lib/test.c tests/lib/unit_test.c
+example_unit_test_CFLAGS  = -Wno-format
+
+# Rules for functional tests
+pkglib_MODULES += example_functional_test.mod
+example_functional_test_mod_SOURCES = tests/example_functional_test.c
+example_functional_test_mod_CFLAGS  = -Wno-format $(COMMON_CFLAGS)
+example_functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# Rules for scripted tests
+check_SCRIPTS += example_scripted_test
+example_scripted_test_SOURCES = tests/example_scripted_test.in
+
+check_SCRIPTS += example_grub_script_test
+example_grub_script_test_SOURCES = tests/example_grub_script_test.in
+
+#
+# Rules for real tests
+#
+
+check_SCRIPTS += grub_script_echo1
+grub_script_echo1_SOURCES = tests/grub_script_echo1.in
+
+check_SCRIPTS += grub_script_echo_keywords
+grub_script_echo_keywords_SOURCES = tests/grub_script_echo_keywords.in
+
+check_SCRIPTS += grub_script_vars1
+grub_script_vars1_SOURCES = tests/grub_script_vars1.in
+
+check_SCRIPTS += grub_script_for1
+grub_script_for1_SOURCES = tests/grub_script_for1.in
+
+check_SCRIPTS += grub_script_while1
+grub_script_while1_SOURCES = tests/grub_script_while1.in
+
+check_SCRIPTS += grub_script_if
+grub_script_if_SOURCES = tests/grub_script_if.in
+
+check_SCRIPTS += grub_script_blanklines
+grub_script_blanklines_SOURCES = tests/grub_script_blanklines.in
+
+check_SCRIPTS += grub_script_final_semicolon
+grub_script_final_semicolon_SOURCES = tests/grub_script_final_semicolon.in
+
+check_SCRIPTS += grub_script_dollar
+grub_script_dollar_SOURCES = tests/grub_script_dollar.in
+
+check_SCRIPTS += grub_script_comments
+grub_script_comments_SOURCES = tests/grub_script_comments.in
+
+# List of tests to execute on "make check"
+# SCRIPTED_TESTS    = example_scripted_test
+# SCRIPTED_TESTS   += example_grub_script_test
+# UNIT_TESTS        = example_unit_test
+# FUNCTIONAL_TESTS  = example_functional_test.mod
+
+SCRIPTED_TESTS  = grub_script_echo1
+SCRIPTED_TESTS += grub_script_echo_keywords
+SCRIPTED_TESTS += grub_script_vars1
+SCRIPTED_TESTS += grub_script_for1
+SCRIPTED_TESTS += grub_script_while1
+SCRIPTED_TESTS += grub_script_if
+SCRIPTED_TESTS += grub_script_blanklines
+SCRIPTED_TESTS += grub_script_final_semicolon
+SCRIPTED_TESTS += grub_script_dollar
+SCRIPTED_TESTS += grub_script_comments
+
+# dependencies between tests and testing-tools
+$(SCRIPTED_TESTS): grub-shell grub-shell-tester
+$(FUNCTIONAL_TESTS): functional_test.mod
+
diff --git a/grub-core/conf/x86-efi.rmk b/grub-core/conf/x86-efi.rmk
new file mode 100644 (file)
index 0000000..e29dad6
--- /dev/null
@@ -0,0 +1,117 @@
+# -*- makefile -*-
+
+# Utilities.
+bin_UTILITIES = grub-mkimage
+
+# For grub-mkimage.
+grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \
+       util/misc.c util/resolve.c
+util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile
+
+# Scripts.
+sbin_SCRIPTS = grub-install
+
+# For grub-install.
+grub_install_SOURCES = util/i386/efi/grub-install.in
+
+# Modules.
+pkglib_PROGRAMS = kernel.img
+pkglib_MODULES = chain.mod appleldr.mod \
+       linux.mod halt.mod  \
+       datetime.mod loadbios.mod \
+       fixvideo.mod mmap.mod acpi.mod
+
+# For kernel.img.
+kernel_img_RELOCATABLE = yes
+kernel_img_SOURCES = kern/$(target_cpu)/efi/startup.S kern/main.c kern/device.c \
+       kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
+       kern/misc.c kern/mm.c kern/term.c \
+       kern/rescue_parser.c kern/rescue_reader.c \
+       kern/$(target_cpu)/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 \
+       kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
+       kern/i386/tsc.c kern/i386/pit.c \
+       kern/generic/rtc_get_time_ms.c \
+       kern/generic/millisleep.c
+ifeq ($(target_cpu),x86_64)
+kernel_img_SOURCES += kern/x86_64/efi/callwrap.S
+endif
+kernel_img_HEADERS += efi/efi.h efi/time.h efi/disk.h i386/pit.h
+kernel_img_CFLAGS = $(COMMON_CFLAGS)
+kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
+kernel_img_LDFLAGS += $(COMMON_LDFLAGS)
+
+# For acpi.mod.
+acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c
+acpi_mod_CFLAGS = $(COMMON_CFLAGS)
+acpi_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mmap.mod.
+mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \
+                  mmap/efi/mmap.c
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For chain.mod.
+chain_mod_SOURCES = loader/efi/chainloader.c
+chain_mod_CFLAGS = $(COMMON_CFLAGS)
+chain_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For appleldr.mod.
+appleldr_mod_SOURCES = loader/efi/appleloader.c
+appleldr_mod_CFLAGS = $(COMMON_CFLAGS)
+appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux.mod.
+ifeq ($(target_cpu), x86_64)
+linux_mod_SOURCES = loader/i386/efi/linux.c loader/i386/linux_trampoline.S
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_ASFLAGS = $(COMMON_ASFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+else
+linux_mod_SOURCES = loader/i386/efi/linux.c
+linux_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_mod_ASFLAGS = $(COMMON_ASFLAGS)
+linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+endif
+
+# For halt.mod.
+halt_mod_SOURCES = commands/halt.c
+halt_mod_CFLAGS = $(COMMON_CFLAGS)
+halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For datetime.mod
+datetime_mod_SOURCES = lib/efi/datetime.c
+datetime_mod_CFLAGS = $(COMMON_CFLAGS)
+datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For loadbios.mod
+loadbios_mod_SOURCES = commands/efi/loadbios.c
+loadbios_mod_CFLAGS = $(COMMON_CFLAGS)
+loadbios_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For fixvideo.mod
+fixvideo_mod_SOURCES = commands/efi/fixvideo.c
+fixvideo_mod_CFLAGS = $(COMMON_CFLAGS)
+fixvideo_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += efi_uga.mod
+efi_uga_mod_SOURCES = video/efi_uga.c
+efi_uga_mod_CFLAGS = $(COMMON_CFLAGS)
+efi_uga_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += efi_gop.mod
+efi_gop_mod_SOURCES = video/efi_gop.c
+efi_gop_mod_CFLAGS = $(COMMON_CFLAGS)
+efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += xnu.mod
+xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c \
+       loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c
+xnu_mod_CFLAGS = $(COMMON_CFLAGS)
+xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
+xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+include $(srcdir)/conf/i386.mk
+include $(srcdir)/conf/common.mk
diff --git a/grub-core/conf/x86_64-efi.rmk b/grub-core/conf/x86_64-efi.rmk
new file mode 100644 (file)
index 0000000..2006212
--- /dev/null
@@ -0,0 +1,5 @@
+# -*- makefile -*-
+
+COMMON_LDFLAGS = -melf_x86_64
+
+include $(srcdir)/conf/x86-efi.mk
diff --git a/grub-core/configure.ac b/grub-core/configure.ac
new file mode 100644 (file)
index 0000000..ac462ea
--- /dev/null
@@ -0,0 +1,91 @@
+# Process this file with autoconf to produce a configure script.
+
+# Copyright (C) 2010  Free Software Foundation, Inc.
+#
+# This configure.ac is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+dnl This configure script is complicated, because GRUB needs to deal
+dnl with three potentially different types:
+dnl
+dnl   build  -- the environment for building GRUB
+dnl   host   -- the environment for running utilities
+dnl   target -- the environment for running GRUB
+dnl
+dnl In addition, GRUB needs to deal with a platform specification
+dnl which specifies the system running GRUB, such as firmware.
+dnl This is necessary because the target type in autoconf does not
+dnl describe such a system very well.
+dnl
+dnl The current strategy is to build utilities using host
+dnl cross-compiler and grub core and modules using target
+dnl cross-compiler.  For this we use nested packages approach, where
+dnl top-level package grub utilities is built with HOSTCC and nested
+dnl package (in grub-core directory) builds with TARGETCC.
+
+# NOTE: ../configure.ac must also be updated.
+AC_INIT([GRUB],[1.98],[bug-grub@gnu.org])
+AC_CONFIG_AUX_DIR([.])
+
+# Checks for host and target systems.
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET
+
+AM_INIT_AUTOMAKE()
+AC_PREREQ(2.60)
+AC_CONFIG_SRCDIR([include/grub/dl.h])
+AC_CONFIG_HEADER([config.h])
+
+m4_include([configure.common])
+
+TARGET_CPP="$TARGET_CC -E"
+TARGET_CCAS=$TARGET_CC
+
+CC=$TARGET_CC
+CPP=$TARGET_CC
+CCAS=$TARGET_CC
+
+AC_SUBST(TARGET_CC)
+AC_SUBST(TARGET_CPP)
+AC_SUBST(TARGET_CCAS)
+AC_SUBST(TARGET_IMG_LDSCRIPT)
+AC_SUBST(TARGET_IMG_LDFLAGS)
+AC_SUBST(TARGET_IMG_CFLAGS)
+AC_SUBST(TARGET_OBJ2ELF)
+AC_SUBST(TARGET_MODULE_FORMAT)
+AC_SUBST(OBJCONV)
+AC_SUBST(TARGET_APPLE_CC)
+AC_SUBST(ASFLAGS)
+AC_SUBST(TARGET_CFLAGS)
+AC_SUBST(TARGET_ASFLAGS)
+AC_SUBST(TARGET_LDFLAGS)
+AC_SUBST(TARGET_CPPFLAGS)
+
+# Output files.
+grub_CHECK_LINK_DIR
+if test x"$link_dir" = xyes ; then
+  AC_CONFIG_LINKS([include/grub/cpu:include/grub/$target_cpu])
+  if test "$platform" != emu ; then
+    AC_CONFIG_LINKS([include/grub/machine:include/grub/$target_cpu/$platform])
+  fi
+else
+  mkdir -p include/grub 2>/dev/null
+  rm -rf include/grub/cpu
+  cp -rp $srcdir/include/grub/$target_cpu include/grub/cpu 2>/dev/null
+  if test "$platform" != emu ; then
+    rm -rf include/grub/machine
+    cp -rp $srcdir/include/grub/$target_cpu/$platform include/grub/machine 2>/dev/null
+  fi
+fi
+
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([po/Makefile])
+AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h])
+
+AC_OUTPUT
diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c
new file mode 100644 (file)
index 0000000..687ed93
--- /dev/null
@@ -0,0 +1,894 @@
+/* ata.c - ATA disk access.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007, 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/ata.h>
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/time.h>
+#include <grub/pci.h>
+#include <grub/scsi.h>
+
+/* At the moment, only two IDE ports are supported.  */
+static const grub_port_t grub_ata_ioaddress[] = { 0x1f0, 0x170 };
+static const grub_port_t grub_ata_ioaddress2[] = { 0x3f6, 0x376 };
+
+static struct grub_ata_device *grub_ata_devices;
+
+/* Wait for !BSY.  */
+grub_err_t
+grub_ata_wait_not_busy (struct grub_ata_device *dev, int milliseconds)
+{
+  /* ATA requires 400ns (after a write to CMD register) or
+     1 PIO cycle (after a DRQ block transfer) before
+     first check of BSY.  */
+  grub_millisleep (1);
+
+  int i = 1;
+  grub_uint8_t sts;
+  while ((sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS))
+        & GRUB_ATA_STATUS_BUSY)
+    {
+      if (i >= milliseconds)
+        {
+         grub_dprintf ("ata", "timeout: %dms, status=0x%x\n",
+                       milliseconds, sts);
+         return grub_error (GRUB_ERR_TIMEOUT, "ATA timeout");
+       }
+
+      grub_millisleep (1);
+      i++;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static inline void
+grub_ata_wait (void)
+{
+  grub_millisleep (50);
+}
+
+/* Wait for !BSY, DRQ.  */
+grub_err_t
+grub_ata_wait_drq (struct grub_ata_device *dev, int rw,
+                  int milliseconds)
+{
+  if (grub_ata_wait_not_busy (dev, milliseconds))
+    return grub_errno;
+
+  /* !DRQ implies error condition.  */
+  grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
+  if ((sts & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
+      != GRUB_ATA_STATUS_DRQ)
+    {
+      grub_dprintf ("ata", "ata error: status=0x%x, error=0x%x\n",
+                   sts, grub_ata_regget (dev, GRUB_ATA_REG_ERROR));
+      if (! rw)
+        return grub_error (GRUB_ERR_READ_ERROR, "ATA read error");
+      else
+        return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Byteorder has to be changed before strings can be read.  */
+static void
+grub_ata_strncpy (char *dst, char *src, grub_size_t len)
+{
+  grub_uint16_t *src16 = (grub_uint16_t *) src;
+  grub_uint16_t *dst16 = (grub_uint16_t *) dst;
+  unsigned int i;
+
+  for (i = 0; i < len / 2; i++)
+    *(dst16++) = grub_be_to_cpu16 (*(src16++));
+  dst[len] = '\0';
+}
+
+void
+grub_ata_pio_read (struct grub_ata_device *dev, char *buf, grub_size_t size)
+{
+  grub_uint16_t *buf16 = (grub_uint16_t *) buf;
+  unsigned int i;
+
+  /* Read in the data, word by word.  */
+  for (i = 0; i < size / 2; i++)
+    buf16[i] = grub_le_to_cpu16 (grub_inw(dev->ioaddress + GRUB_ATA_REG_DATA));
+}
+
+static void
+grub_ata_pio_write (struct grub_ata_device *dev, char *buf, grub_size_t size)
+{
+  grub_uint16_t *buf16 = (grub_uint16_t *) buf;
+  unsigned int i;
+
+  /* Write the data, word by word.  */
+  for (i = 0; i < size / 2; i++)
+    grub_outw(grub_cpu_to_le16 (buf16[i]), dev->ioaddress + GRUB_ATA_REG_DATA);
+}
+
+static void
+grub_ata_dumpinfo (struct grub_ata_device *dev, char *info)
+{
+  char text[41];
+
+  /* The device information was read, dump it for debugging.  */
+  grub_ata_strncpy (text, info + 20, 20);
+  grub_dprintf ("ata", "Serial: %s\n", text);
+  grub_ata_strncpy (text, info + 46, 8);
+  grub_dprintf ("ata", "Firmware: %s\n", text);
+  grub_ata_strncpy (text, info + 54, 40);
+  grub_dprintf ("ata", "Model: %s\n", text);
+
+  if (! dev->atapi)
+    {
+      grub_dprintf ("ata", "Addressing: %d\n", dev->addr);
+      grub_dprintf ("ata", "Sectors: %lld\n", (unsigned long long) dev->size);
+    }
+}
+
+static grub_err_t
+grub_atapi_identify (struct grub_ata_device *dev)
+{
+  char *info;
+
+  info = grub_malloc (GRUB_DISK_SECTOR_SIZE);
+  if (! info)
+    return grub_errno;
+
+  grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
+  grub_ata_wait ();
+  if (grub_ata_check_ready (dev))
+    {
+      grub_free (info);
+      return grub_errno;
+    }
+
+  grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE);
+  grub_ata_wait ();
+
+  if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD))
+    {
+      grub_free (info);
+      return grub_errno;
+    }
+  grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
+
+  dev->atapi = 1;
+
+  grub_ata_dumpinfo (dev, info);
+
+  grub_free (info);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_atapi_wait_drq (struct grub_ata_device *dev,
+                    grub_uint8_t ireason,
+                    int milliseconds)
+{
+  /* Wait for !BSY, DRQ, ireason */
+  if (grub_ata_wait_not_busy (dev, milliseconds))
+    return grub_errno;
+
+  grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
+  grub_uint8_t irs = grub_ata_regget (dev, GRUB_ATAPI_REG_IREASON);
+
+  /* OK if DRQ is asserted and interrupt reason is as expected.  */
+  if ((sts & GRUB_ATA_STATUS_DRQ)
+      && (irs & GRUB_ATAPI_IREASON_MASK) == ireason)
+    return GRUB_ERR_NONE;
+
+  /* !DRQ implies error condition.  */
+  grub_dprintf ("ata", "atapi error: status=0x%x, ireason=0x%x, error=0x%x\n",
+               sts, irs, grub_ata_regget (dev, GRUB_ATA_REG_ERROR));
+
+  if (! (sts & GRUB_ATA_STATUS_DRQ)
+      && (irs & GRUB_ATAPI_IREASON_MASK) == GRUB_ATAPI_IREASON_ERROR)
+    {
+      if (ireason == GRUB_ATAPI_IREASON_CMD_OUT)
+       return grub_error (GRUB_ERR_READ_ERROR, "ATA PACKET command error");
+      else
+       return grub_error (GRUB_ERR_READ_ERROR, "ATAPI read error");
+    }
+
+  return grub_error (GRUB_ERR_READ_ERROR, "ATAPI protocol error");
+}
+
+static grub_err_t
+grub_atapi_packet (struct grub_ata_device *dev, char *packet,
+                  grub_size_t size)
+{
+  grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
+  if (grub_ata_check_ready (dev))
+    return grub_errno;
+
+  /* Send ATA PACKET command.  */
+  grub_ata_regset (dev, GRUB_ATA_REG_FEATURES, 0);
+  grub_ata_regset (dev, GRUB_ATAPI_REG_IREASON, 0);
+  grub_ata_regset (dev, GRUB_ATAPI_REG_CNTHIGH, size >> 8);
+  grub_ata_regset (dev, GRUB_ATAPI_REG_CNTLOW, size & 0xFF);
+
+  grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_PACKET);
+
+  /* Wait for !BSY, DRQ, !I/O, C/D.  */
+  if (grub_atapi_wait_drq (dev, GRUB_ATAPI_IREASON_CMD_OUT, GRUB_ATA_TOUT_STD))
+    return grub_errno;
+
+  /* Write the packet.  */
+  grub_ata_pio_write (dev, packet, 12);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_ata_identify (struct grub_ata_device *dev)
+{
+  char *info;
+  grub_uint16_t *info16;
+
+  info = grub_malloc (GRUB_DISK_SECTOR_SIZE);
+  if (! info)
+    return grub_errno;
+
+  info16 = (grub_uint16_t *) info;
+
+  grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
+  grub_ata_wait ();
+  if (grub_ata_check_ready (dev))
+    {
+      grub_free (info);
+      return grub_errno;
+    }
+
+  grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_DEVICE);
+  grub_ata_wait ();
+
+  if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD))
+    {
+      grub_free (info);
+      grub_errno = GRUB_ERR_NONE;
+      grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
+
+      if ((sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ
+         | GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_ERR
+         && (grub_ata_regget (dev, GRUB_ATA_REG_ERROR) & 0x04 /* ABRT */))
+       /* Device without ATA IDENTIFY, try ATAPI.  */
+       return grub_atapi_identify (dev);
+
+      else if (sts == 0x00)
+       /* No device, return error but don't print message.  */
+       return GRUB_ERR_UNKNOWN_DEVICE;
+
+      else
+       /* Other Error.  */
+       return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                          "device cannot be identified");
+    }
+
+  grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
+
+  /* Re-check status to avoid bogus identify data due to stuck DRQ.  */
+  grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
+  if (sts & (GRUB_ATA_STATUS_BUSY | GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
+    {
+      grub_dprintf ("ata", "bad status=0x%x\n", sts);
+      grub_free (info);
+      /* No device, return error but don't print message.  */
+      grub_errno = GRUB_ERR_NONE;
+      return GRUB_ERR_UNKNOWN_DEVICE;
+    }
+
+  /* Now it is certain that this is not an ATAPI device.  */
+  dev->atapi = 0;
+
+  /* CHS is always supported.  */
+  dev->addr = GRUB_ATA_CHS;
+
+  /* Check if LBA is supported.  */
+  if (info16[49] & (1 << 9))
+    {
+      /* Check if LBA48 is supported.  */
+      if (info16[83] & (1 << 10))
+       dev->addr = GRUB_ATA_LBA48;
+      else
+       dev->addr = GRUB_ATA_LBA;
+    }
+
+  /* Determine the amount of sectors.  */
+  if (dev->addr != GRUB_ATA_LBA48)
+    dev->size = grub_le_to_cpu32(*((grub_uint32_t *) &info16[60]));
+  else
+    dev->size = grub_le_to_cpu64(*((grub_uint64_t *) &info16[100]));
+
+  /* Read CHS information.  */
+  dev->cylinders = info16[1];
+  dev->heads = info16[3];
+  dev->sectors_per_track = info16[6];
+
+  grub_ata_dumpinfo (dev, info);
+
+  grub_free(info);
+
+  return 0;
+}
+
+static grub_err_t
+grub_ata_device_initialize (int port, int device, int addr, int addr2)
+{
+  struct grub_ata_device *dev;
+  struct grub_ata_device **devp;
+
+  grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n",
+               port, device, addr, addr2);
+
+  dev = grub_malloc (sizeof(*dev));
+  if (! dev)
+    return grub_errno;
+
+  /* Setup the device information.  */
+  dev->port = port;
+  dev->device = device;
+  dev->ioaddress = addr + GRUB_MACHINE_PCI_IO_BASE;
+  dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE;
+  dev->next = NULL;
+
+  grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
+  grub_ata_wait ();
+
+  /* Try to detect if the port is in use by writing to it,
+     waiting for a while and reading it again.  If the value
+     was preserved, there is a device connected.  */
+  grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
+  grub_ata_wait ();
+  grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS);
+  grub_dprintf ("ata", "sectors=0x%x\n", sec);
+  if (sec != 0x5A)
+    {
+      grub_free(dev);
+      return 0;
+    }
+
+  /* The above test may detect a second (slave) device
+     connected to a SATA controller which supports only one
+     (master) device.  It is not safe to use the status register
+     READY bit to check for controller channel existence.  Some
+     ATAPI commands (RESET, DIAGNOSTIC) may clear this bit.  */
+
+  /* Use the IDENTIFY DEVICE command to query the device.  */
+  if (grub_ata_identify (dev))
+    {
+      grub_free (dev);
+      return 0;
+    }
+
+  /* Register the device.  */
+  for (devp = &grub_ata_devices; *devp; devp = &(*devp)->next);
+  *devp = dev;
+
+  return 0;
+}
+
+static int NESTED_FUNC_ATTR
+grub_ata_pciinit (grub_pci_device_t dev,
+                 grub_pci_id_t pciid)
+{
+  static int compat_use[2] = { 0 };
+  grub_pci_address_t addr;
+  grub_uint32_t class;
+  grub_uint32_t bar1;
+  grub_uint32_t bar2;
+  int rega;
+  int regb;
+  int i;
+  static int controller = 0;
+  int cs5536 = 0;
+  int nports = 2;
+
+  /* Read class.  */
+  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+  class = grub_pci_read (addr);
+
+  /* AMD CS5536 Southbridge.  */
+  if (pciid == 0x208f1022)
+    {
+      cs5536 = 1;
+      nports = 1;
+    }
+
+  /* Check if this class ID matches that of a PCI IDE Controller.  */
+  if (!cs5536 && (class >> 16 != 0x0101))
+    return 0;
+
+  for (i = 0; i < nports; i++)
+    {
+      /* Set to 0 when the channel operated in compatibility mode.  */
+      int compat;
+
+      /* We don't support non-compatibility mode for CS5536.  */
+      if (cs5536)
+       compat = 0;
+      else
+       compat = (class >> (8 + 2 * i)) & 1;
+
+      rega = 0;
+      regb = 0;
+
+      /* If the channel is in compatibility mode, just assign the
+        default registers.  */
+      if (compat == 0 && !compat_use[i])
+       {
+         rega = grub_ata_ioaddress[i];
+         regb = grub_ata_ioaddress2[i];
+         compat_use[i] = 1;
+       }
+      else if (compat)
+       {
+         /* Read the BARs, which either contain a mmapped IO address
+            or the IO port address.  */
+         addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES
+                                       + sizeof (grub_uint64_t) * i);
+         bar1 = grub_pci_read (addr);
+         addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES
+                                       + sizeof (grub_uint64_t) * i
+                                       + sizeof (grub_uint32_t));
+         bar2 = grub_pci_read (addr);
+
+         /* Check if the BARs describe an IO region.  */
+         if ((bar1 & 1) && (bar2 & 1))
+           {
+             rega = bar1 & ~3;
+             regb = bar2 & ~3;
+           }
+       }
+
+      grub_dprintf ("ata",
+                   "PCI dev (%d,%d,%d) compat=%d rega=0x%x regb=0x%x\n",
+                   grub_pci_get_bus (dev), grub_pci_get_device (dev),
+                   grub_pci_get_function (dev), compat, rega, regb);
+
+      if (rega && regb)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         grub_ata_device_initialize (controller * 2 + i, 0, rega, regb);
+
+         /* Most errors raised by grub_ata_device_initialize() are harmless.
+            They just indicate this particular drive is not responding, most
+            likely because it doesn't exist.  We might want to ignore specific
+            error types here, instead of printing them.  */
+         if (grub_errno)
+           {
+             grub_print_error ();
+             grub_errno = GRUB_ERR_NONE;
+           }
+
+         grub_ata_device_initialize (controller * 2 + i, 1, rega, regb);
+
+         /* Likewise.  */
+         if (grub_errno)
+           {
+             grub_print_error ();
+             grub_errno = GRUB_ERR_NONE;
+           }
+       }
+    }
+
+  controller++;
+
+  return 0;
+}
+
+static grub_err_t
+grub_ata_initialize (void)
+{
+  grub_pci_iterate (grub_ata_pciinit);
+  return 0;
+}
+
+static void
+grub_ata_setlba (struct grub_ata_device *dev, grub_disk_addr_t sector,
+                grub_size_t size)
+{
+  grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, size);
+  grub_ata_regset (dev, GRUB_ATA_REG_LBALOW, sector & 0xFF);
+  grub_ata_regset (dev, GRUB_ATA_REG_LBAMID, (sector >> 8) & 0xFF);
+  grub_ata_regset (dev, GRUB_ATA_REG_LBAHIGH, (sector >> 16) & 0xFF);
+}
+
+static grub_err_t
+grub_ata_setaddress (struct grub_ata_device *dev,
+                    grub_ata_addressing_t addressing,
+                    grub_disk_addr_t sector,
+                    grub_size_t size)
+{
+  switch (addressing)
+    {
+    case GRUB_ATA_CHS:
+      {
+       unsigned int cylinder;
+       unsigned int head;
+       unsigned int sect;
+
+       /* Calculate the sector, cylinder and head to use.  */
+       sect = ((grub_uint32_t) sector % dev->sectors_per_track) + 1;
+       cylinder = (((grub_uint32_t) sector / dev->sectors_per_track)
+                   / dev->heads);
+       head = ((grub_uint32_t) sector / dev->sectors_per_track) % dev->heads;
+
+       if (sect > dev->sectors_per_track
+           || cylinder > dev->cylinders
+           || head > dev->heads)
+         return grub_error (GRUB_ERR_OUT_OF_RANGE,
+                            "sector %d cannot be addressed "
+                            "using CHS addressing", sector);
+
+       grub_ata_regset (dev, GRUB_ATA_REG_DISK, (dev->device << 4) | head);
+       if (grub_ata_check_ready (dev))
+         return grub_errno;
+
+       grub_ata_regset (dev, GRUB_ATA_REG_SECTNUM, sect);
+       grub_ata_regset (dev, GRUB_ATA_REG_CYLLSB, cylinder & 0xFF);
+       grub_ata_regset (dev, GRUB_ATA_REG_CYLMSB, cylinder >> 8);
+
+       break;
+      }
+
+    case GRUB_ATA_LBA:
+      if (size == 256)
+       size = 0;
+      grub_ata_regset (dev, GRUB_ATA_REG_DISK,
+                      0xE0 | (dev->device << 4) | ((sector >> 24) & 0x0F));
+      if (grub_ata_check_ready (dev))
+       return grub_errno;
+
+      grub_ata_setlba (dev, sector, size);
+      break;
+
+    case GRUB_ATA_LBA48:
+      if (size == 65536)
+       size = 0;
+
+      grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | (dev->device << 4));
+      if (grub_ata_check_ready (dev))
+       return grub_errno;
+
+      /* Set "Previous".  */
+      grub_ata_setlba (dev, sector >> 24, size >> 8);
+      /* Set "Current".  */
+      grub_ata_setlba (dev, sector, size);
+
+      break;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector,
+                   grub_size_t size, char *buf, int rw)
+{
+  struct grub_ata_device *dev = (struct grub_ata_device *) disk->data;
+
+  grub_dprintf("ata", "grub_ata_readwrite (size=%llu, rw=%d)\n", (unsigned long long) size, rw);
+
+  grub_ata_addressing_t addressing = dev->addr;
+  grub_size_t batch;
+  int cmd, cmd_write;
+
+  if (addressing == GRUB_ATA_LBA48 && ((sector + size) >> 28) != 0)
+    {
+      batch = 65536;
+      cmd = GRUB_ATA_CMD_READ_SECTORS_EXT;
+      cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_EXT;
+    }
+  else
+    {
+      if (addressing == GRUB_ATA_LBA48)
+       addressing = GRUB_ATA_LBA;
+      batch = 256;
+      cmd = GRUB_ATA_CMD_READ_SECTORS;
+      cmd_write = GRUB_ATA_CMD_WRITE_SECTORS;
+    }
+
+  grub_size_t nsectors = 0;
+  while (nsectors < size)
+    {
+      if (size - nsectors < batch)
+       batch = size - nsectors;
+
+      grub_dprintf("ata", "rw=%d, sector=%llu, batch=%llu\n", rw, (unsigned long long) sector, (unsigned long long) batch);
+
+      /* Send read/write command.  */
+      if (grub_ata_setaddress (dev, addressing, sector, batch))
+       return grub_errno;
+
+      grub_ata_regset (dev, GRUB_ATA_REG_CMD, (! rw ? cmd : cmd_write));
+
+      unsigned sect;
+      for (sect = 0; sect < batch; sect++)
+       {
+         /* Wait for !BSY, DRQ.  */
+         if (grub_ata_wait_drq (dev, rw, GRUB_ATA_TOUT_DATA))
+           return grub_errno;
+
+         /* Transfer data.  */
+         if (! rw)
+           grub_ata_pio_read (dev, buf, GRUB_DISK_SECTOR_SIZE);
+         else
+           grub_ata_pio_write (dev, buf, GRUB_DISK_SECTOR_SIZE);
+
+         buf += GRUB_DISK_SECTOR_SIZE;
+       }
+
+      if (rw)
+        {
+         /* Check for write error.  */
+         if (grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA))
+           return grub_errno;
+
+         if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS)
+             & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
+           return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
+       }
+
+      sector += batch;
+      nsectors += batch;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+\f
+
+static int
+grub_ata_iterate (int (*hook) (const char *name))
+{
+  struct grub_ata_device *dev;
+
+  for (dev = grub_ata_devices; dev; dev = dev->next)
+    {
+      char devname[10];
+
+      if (dev->atapi)
+       continue;
+
+      grub_snprintf (devname, sizeof (devname), 
+                    "ata%d", dev->port * 2 + dev->device);
+
+      if (hook (devname))
+       return 1;
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_ata_open (const char *name, grub_disk_t disk)
+{
+  struct grub_ata_device *dev;
+
+  for (dev = grub_ata_devices; dev; dev = dev->next)
+    {
+      char devname[10];
+      grub_snprintf (devname, sizeof (devname),
+                    "ata%d", dev->port * 2 + dev->device);
+      if (grub_strcmp (name, devname) == 0)
+       break;
+    }
+
+  if (! dev)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
+
+  if (dev->atapi)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk");
+
+  disk->total_sectors = dev->size;
+
+  disk->id = (unsigned long) dev;
+
+  disk->has_partitions = 1;
+  disk->data = dev;
+
+  return 0;
+}
+
+static void
+grub_ata_close (grub_disk_t disk __attribute__((unused)))
+{
+
+}
+
+static grub_err_t
+grub_ata_read (grub_disk_t disk, grub_disk_addr_t sector,
+              grub_size_t size, char *buf)
+{
+  return grub_ata_readwrite (disk, sector, size, buf, 0);
+}
+
+static grub_err_t
+grub_ata_write (grub_disk_t disk,
+               grub_disk_addr_t sector,
+               grub_size_t size,
+               const char *buf)
+{
+  return grub_ata_readwrite (disk, sector, size, (char *) buf, 1);
+}
+
+static struct grub_disk_dev grub_atadisk_dev =
+  {
+    .name = "ATA",
+    .id = GRUB_DISK_DEVICE_ATA_ID,
+    .iterate = grub_ata_iterate,
+    .open = grub_ata_open,
+    .close = grub_ata_close,
+    .read = grub_ata_read,
+    .write = grub_ata_write,
+    .next = 0
+  };
+
+
+\f
+/* ATAPI code.  */
+
+static int
+grub_atapi_iterate (int (*hook) (const char *name, int luns))
+{
+  struct grub_ata_device *dev;
+
+  for (dev = grub_ata_devices; dev; dev = dev->next)
+    {
+      char devname[10];
+      grub_snprintf (devname, sizeof (devname),
+                    "ata%d", dev->port * 2 + dev->device);
+
+      if (! dev->atapi)
+       continue;
+
+      if (hook (devname, 1))
+       return 1;
+    }
+
+  return 0;
+
+}
+
+static grub_err_t
+grub_atapi_read (struct grub_scsi *scsi,
+                grub_size_t cmdsize __attribute__((unused)),
+                char *cmd, grub_size_t size, char *buf)
+{
+  struct grub_ata_device *dev = (struct grub_ata_device *) scsi->data;
+
+  grub_dprintf("ata", "grub_atapi_read (size=%llu)\n", (unsigned long long) size);
+
+  if (grub_atapi_packet (dev, cmd, size))
+    return grub_errno;
+
+  grub_size_t nread = 0;
+  while (nread < size)
+    {
+      /* Wait for !BSY, DRQ, I/O, !C/D.  */
+      if (grub_atapi_wait_drq (dev, GRUB_ATAPI_IREASON_DATA_IN, GRUB_ATA_TOUT_DATA))
+       return grub_errno;
+
+      /* Get byte count for this DRQ assertion.  */
+      unsigned cnt = grub_ata_regget (dev, GRUB_ATAPI_REG_CNTHIGH) << 8
+                  | grub_ata_regget (dev, GRUB_ATAPI_REG_CNTLOW);
+      grub_dprintf("ata", "DRQ count=%u\n", cnt);
+
+      /* Count of last transfer may be uneven.  */
+      if (! (0 < cnt && cnt <= size - nread && (! (cnt & 1) || cnt == size - nread)))
+       return grub_error (GRUB_ERR_READ_ERROR, "invalid ATAPI transfer count");
+
+      /* Read the data.  */
+      grub_ata_pio_read (dev, buf + nread, cnt);
+
+      if (cnt & 1)
+       buf[nread + cnt - 1] = (char) grub_le_to_cpu16 (grub_inw (dev->ioaddress + GRUB_ATA_REG_DATA));
+
+      nread += cnt;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_atapi_write (struct grub_scsi *scsi __attribute__((unused)),
+                 grub_size_t cmdsize __attribute__((unused)),
+                 char *cmd __attribute__((unused)),
+                 grub_size_t size __attribute__((unused)),
+                 char *buf __attribute__((unused)))
+{
+  // XXX: scsi.mod does not use write yet.
+  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "ATAPI write not implemented");
+}
+
+static grub_err_t
+grub_atapi_open (const char *name, struct grub_scsi *scsi)
+{
+  struct grub_ata_device *dev;
+  struct grub_ata_device *devfnd = 0;
+
+  for (dev = grub_ata_devices; dev; dev = dev->next)
+    {
+      char devname[10];
+      grub_snprintf (devname, sizeof (devname),
+                    "ata%d", dev->port * 2 + dev->device);
+
+      if (!grub_strcmp (devname, name))
+       {
+         devfnd = dev;
+         break;
+       }
+    }
+
+  grub_dprintf ("ata", "opening ATAPI dev `%s'\n", name);
+
+  if (! devfnd)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device");
+
+  scsi->data = devfnd;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_atapi_close (struct grub_scsi *scsi)
+{
+  grub_free (scsi->name);
+}
+
+static struct grub_scsi_dev grub_atapi_dev =
+  {
+    .name = "ATAPI",
+    .iterate = grub_atapi_iterate,
+    .open = grub_atapi_open,
+    .close = grub_atapi_close,
+    .read = grub_atapi_read,
+    .write = grub_atapi_write
+  };
+
+\f
+
+GRUB_MOD_INIT(ata)
+{
+  /* To prevent two drivers operating on the same disks.  */
+  grub_disk_firmware_is_tainted = 1;
+  if (grub_disk_firmware_fini)
+    {
+      grub_disk_firmware_fini ();
+      grub_disk_firmware_fini = NULL;
+    }
+
+  /* ATA initialization.  */
+  grub_ata_initialize ();
+
+  grub_disk_dev_register (&grub_atadisk_dev);
+
+  /* ATAPI devices are handled by scsi.mod.  */
+  grub_scsi_dev_register (&grub_atapi_dev);
+}
+
+GRUB_MOD_FINI(ata)
+{
+  grub_scsi_dev_unregister (&grub_atapi_dev);
+  grub_disk_dev_unregister (&grub_atadisk_dev);
+}
diff --git a/grub-core/disk/ata_pthru.c b/grub-core/disk/ata_pthru.c
new file mode 100644 (file)
index 0000000..f52725a
--- /dev/null
@@ -0,0 +1,107 @@
+/* ata_pthru.c - ATA pass through for ata.mod.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/ata.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+
+
+/* ATA pass through support, used by hdparm.mod.  */
+static grub_err_t
+grub_ata_pass_through (grub_disk_t disk,
+                      struct grub_disk_ata_pass_through_parms *parms)
+{
+  if (disk->dev->id != GRUB_DISK_DEVICE_ATA_ID)
+    return grub_error (GRUB_ERR_BAD_DEVICE,
+                      "device not accessed via ata.mod");
+
+  struct grub_ata_device *dev = (struct grub_ata_device *) disk->data;
+
+  if (! (parms->size == 0 || parms->size == GRUB_DISK_SECTOR_SIZE))
+    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                      "ATA multi-sector read and DATA OUT not implemented");
+
+  grub_dprintf ("ata", "ata_pass_through: cmd=0x%x, features=0x%x, sectors=0x%x\n",
+               parms->taskfile[GRUB_ATA_REG_CMD],
+               parms->taskfile[GRUB_ATA_REG_FEATURES],
+               parms->taskfile[GRUB_ATA_REG_SECTORS]);
+  grub_dprintf ("ata", "lba_high=0x%x, lba_mid=0x%x, lba_low=0x%x, size=%d\n",
+               parms->taskfile[GRUB_ATA_REG_LBAHIGH],
+               parms->taskfile[GRUB_ATA_REG_LBAMID],
+               parms->taskfile[GRUB_ATA_REG_LBALOW], parms->size);
+
+  /* Set registers.  */
+  grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4
+                  | (parms->taskfile[GRUB_ATA_REG_DISK] & 0xf));
+  if (grub_ata_check_ready (dev))
+    return grub_errno;
+
+  int i;
+  for (i = GRUB_ATA_REG_FEATURES; i <= GRUB_ATA_REG_LBAHIGH; i++)
+    grub_ata_regset (dev, i, parms->taskfile[i]);
+
+  /* Start command. */
+  grub_ata_regset (dev, GRUB_ATA_REG_CMD, parms->taskfile[GRUB_ATA_REG_CMD]);
+
+  /* Wait for !BSY.  */
+  if (grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA))
+    return grub_errno;
+
+  /* Check status.  */
+  grub_int8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS);
+  grub_dprintf ("ata", "status=0x%x\n", sts);
+
+  /* Transfer data.  */
+  if ((sts & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_DRQ)
+    {
+      if (parms->size != GRUB_DISK_SECTOR_SIZE)
+        return grub_error (GRUB_ERR_READ_ERROR, "DRQ unexpected");
+      grub_ata_pio_read (dev, parms->buffer, GRUB_DISK_SECTOR_SIZE);
+    }
+
+  /* Return registers.  */
+  for (i = GRUB_ATA_REG_ERROR; i <= GRUB_ATA_REG_STATUS; i++)
+    parms->taskfile[i] = grub_ata_regget (dev, i);
+
+  grub_dprintf ("ata", "status=0x%x, error=0x%x, sectors=0x%x\n",
+               parms->taskfile[GRUB_ATA_REG_STATUS],
+               parms->taskfile[GRUB_ATA_REG_ERROR],
+               parms->taskfile[GRUB_ATA_REG_SECTORS]);
+
+  if (parms->taskfile[GRUB_ATA_REG_STATUS]
+      & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
+    return grub_error (GRUB_ERR_READ_ERROR, "ATA passthrough failed");
+
+  return GRUB_ERR_NONE;
+}
+
+\f
+
+GRUB_MOD_INIT(ata_pthru)
+{
+  /* Register ATA pass through function.  */
+  grub_disk_ata_pass_through = grub_ata_pass_through;
+}
+
+GRUB_MOD_FINI(ata_pthru)
+{
+  if (grub_disk_ata_pass_through == grub_ata_pass_through)
+    grub_disk_ata_pass_through = NULL;
+}
diff --git a/grub-core/disk/dmraid_nvidia.c b/grub-core/disk/dmraid_nvidia.c
new file mode 100644 (file)
index 0000000..c4e3922
--- /dev/null
@@ -0,0 +1,165 @@
+/* dmraid_nvidia.c - module to handle Nvidia fakeraid.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/raid.h>
+
+#define NV_SIGNATURES          4
+
+#define NV_IDLE                        0
+#define NV_SCDB_INIT_RAID      2
+#define NV_SCDB_REBUILD_RAID   3
+#define NV_SCDB_UPGRADE_RAID   4
+#define NV_SCDB_SYNC_RAID      5
+
+#define NV_LEVEL_UNKNOWN       0x00
+#define NV_LEVEL_JBOD          0xFF
+#define NV_LEVEL_0             0x80
+#define NV_LEVEL_1             0x81
+#define NV_LEVEL_3             0x83
+#define NV_LEVEL_5             0x85
+#define NV_LEVEL_10            0x8a
+#define NV_LEVEL_1_0           0x8180
+
+#define NV_ARRAY_FLAG_BOOT             1 /* BIOS use only.  */
+#define NV_ARRAY_FLAG_ERROR            2 /* Degraded or offline.  */
+#define NV_ARRAY_FLAG_PARITY_VALID     4 /* RAID-3/5 parity valid.  */
+
+struct grub_nv_array
+{
+  grub_uint32_t version;
+  grub_uint32_t signature[NV_SIGNATURES];
+  grub_uint8_t raid_job_code;
+  grub_uint8_t stripe_width;
+  grub_uint8_t total_volumes;
+  grub_uint8_t original_width;
+  grub_uint32_t raid_level;
+  grub_uint32_t stripe_block_size;
+  grub_uint32_t stripe_block_size_bytes;
+  grub_uint32_t stripe_block_size_log2;
+  grub_uint32_t stripe_mask;
+  grub_uint32_t stripe_size;
+  grub_uint32_t stripe_size_bytes;
+  grub_uint32_t raid_job_mask;
+  grub_uint32_t original_capacity;
+  grub_uint32_t flags;
+};
+
+#define NV_ID_LEN              8
+#define NV_ID_STRING           "NVIDIA"
+#define NV_VERSION             100
+
+#define        NV_PRODID_LEN           16
+#define        NV_PRODREV_LEN          4
+
+struct grub_nv_super
+{
+  char vendor[NV_ID_LEN];      /* 0x00 - 0x07 ID string.  */
+  grub_uint32_t size;          /* 0x08 - 0x0B Size of metadata in dwords.  */
+  grub_uint32_t chksum;                /* 0x0C - 0x0F Checksum of this struct.  */
+  grub_uint16_t version;       /* 0x10 - 0x11 NV version.  */
+  grub_uint8_t unit_number;    /* 0x12 Disk index in array.  */
+  grub_uint8_t reserved;       /* 0x13.  */
+  grub_uint32_t capacity;      /* 0x14 - 0x17 Array capacity in sectors.  */
+  grub_uint32_t sector_size;   /* 0x18 - 0x1B Sector size.  */
+  char prodid[NV_PRODID_LEN];  /* 0x1C - 0x2B Array product ID.  */
+  char prodrev[NV_PRODREV_LEN];        /* 0x2C - 0x2F Array product revision */
+  grub_uint32_t unit_flags;    /* 0x30 - 0x33 Flags for this disk */
+  struct grub_nv_array array;  /* Array information */
+} __attribute__ ((packed));
+
+static grub_err_t
+grub_dmraid_nv_detect (grub_disk_t disk, struct grub_raid_array *array)
+{
+  grub_disk_addr_t sector;
+  struct grub_nv_super sb;
+
+  if (disk->partition)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "skip partition");
+
+  sector = grub_disk_get_size (disk) - 2;
+
+  if (grub_disk_read (disk, sector, 0, sizeof (sb), &sb))
+    return grub_errno;
+
+  if (grub_memcmp (sb.vendor, NV_ID_STRING, 6))
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid");
+
+  if (sb.version != NV_VERSION)
+    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                       "unknown version: %d.%d", sb.version);
+
+  switch (sb.array.raid_level)
+    {
+    case NV_LEVEL_0:
+      array->level = 0;
+      array->disk_size = sb.capacity / sb.array.total_volumes;
+      break;
+
+    case NV_LEVEL_1:
+      array->level = 1;
+      array->disk_size = sb.capacity;
+      break;
+
+    case NV_LEVEL_5:
+      array->level = 5;
+      array->layout = GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC;
+      array->disk_size = sb.capacity / (sb.array.total_volumes - 1);
+      break;
+
+    default:
+      return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                         "unsupported RAID level: %d", sb.array.raid_level);
+    }
+
+  array->number = 0;
+  array->total_devs = sb.array.total_volumes;
+  array->chunk_size = sb.array.stripe_block_size;
+  array->index = sb.unit_number;
+  array->uuid_len = sizeof (sb.array.signature);
+  array->uuid = grub_malloc (sizeof (sb.array.signature));
+  if (! array->uuid)
+    return grub_errno;
+
+  grub_memcpy (array->uuid, (char *) &sb.array.signature,
+               sizeof (sb.array.signature));
+
+  return 0;
+}
+
+static struct grub_raid grub_dmraid_nv_dev =
+{
+  .name = "dmraid_nv",
+  .detect = grub_dmraid_nv_detect,
+  .next = 0
+};
+
+GRUB_MOD_INIT(dm_nv)
+{
+  grub_raid_register (&grub_dmraid_nv_dev);
+}
+
+GRUB_MOD_FINI(dm_nv)
+{
+  grub_raid_unregister (&grub_dmraid_nv_dev);
+}
diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c
new file mode 100644 (file)
index 0000000..f9c6f31
--- /dev/null
@@ -0,0 +1,851 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/term.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/disk.h>
+
+struct grub_efidisk_data
+{
+  grub_efi_handle_t handle;
+  grub_efi_device_path_t *device_path;
+  grub_efi_device_path_t *last_device_path;
+  grub_efi_block_io_t *block_io;
+  grub_efi_disk_io_t *disk_io;
+  struct grub_efidisk_data *next;
+};
+
+/* GUIDs.  */
+static grub_efi_guid_t disk_io_guid = GRUB_EFI_DISK_IO_GUID;
+static grub_efi_guid_t block_io_guid = GRUB_EFI_BLOCK_IO_GUID;
+
+static struct grub_efidisk_data *fd_devices;
+static struct grub_efidisk_data *hd_devices;
+static struct grub_efidisk_data *cd_devices;
+
+/* Duplicate a device path.  */
+static grub_efi_device_path_t *
+duplicate_device_path (const grub_efi_device_path_t *dp)
+{
+  grub_efi_device_path_t *p;
+  grub_size_t total_size = 0;
+
+  for (p = (grub_efi_device_path_t *) dp;
+       ;
+       p = GRUB_EFI_NEXT_DEVICE_PATH (p))
+    {
+      total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
+      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
+       break;
+    }
+
+  p = grub_malloc (total_size);
+  if (! p)
+    return 0;
+
+  grub_memcpy (p, dp, total_size);
+  return p;
+}
+
+/* Return the device path node right before the end node.  */
+static grub_efi_device_path_t *
+find_last_device_path (const grub_efi_device_path_t *dp)
+{
+  grub_efi_device_path_t *next, *p;
+
+  if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
+    return 0;
+
+  for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p);
+       ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next);
+       p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next))
+    ;
+
+  return p;
+}
+
+/* Compare device paths.  */
+static int
+compare_device_paths (const grub_efi_device_path_t *dp1,
+                     const grub_efi_device_path_t *dp2)
+{
+  if (! dp1 || ! dp2)
+    /* Return non-zero.  */
+    return 1;
+
+  while (1)
+    {
+      grub_efi_uint8_t type1, type2;
+      grub_efi_uint8_t subtype1, subtype2;
+      grub_efi_uint16_t len1, len2;
+      int ret;
+
+      type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1);
+      type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2);
+
+      if (type1 != type2)
+       return (int) type2 - (int) type1;
+
+      subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1);
+      subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2);
+
+      if (subtype1 != subtype2)
+       return (int) subtype1 - (int) subtype2;
+
+      len1 = GRUB_EFI_DEVICE_PATH_LENGTH (dp1);
+      len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2);
+
+      if (len1 != len2)
+       return (int) len1 - (int) len2;
+
+      ret = grub_memcmp (dp1, dp2, len1);
+      if (ret != 0)
+       return ret;
+
+      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1))
+       break;
+
+      dp1 = (grub_efi_device_path_t *) ((char *) dp1 + len1);
+      dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
+    }
+
+  return 0;
+}
+
+static struct grub_efidisk_data *
+make_devices (void)
+{
+  grub_efi_uintn_t num_handles;
+  grub_efi_handle_t *handles;
+  grub_efi_handle_t *handle;
+  struct grub_efidisk_data *devices = 0;
+
+  /* Find handles which support the disk io interface.  */
+  handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &disk_io_guid,
+                                   0, &num_handles);
+  if (! handles)
+    return 0;
+
+  /* Make a linked list of devices.  */
+  for (handle = handles; num_handles--; handle++)
+    {
+      grub_efi_device_path_t *dp;
+      grub_efi_device_path_t *ldp;
+      struct grub_efidisk_data *d;
+      grub_efi_block_io_t *bio;
+      grub_efi_disk_io_t *dio;
+
+      dp = grub_efi_get_device_path (*handle);
+      if (! dp)
+       continue;
+
+      ldp = find_last_device_path (dp);
+      if (! ldp)
+       /* This is empty. Why?  */
+       continue;
+
+      bio = grub_efi_open_protocol (*handle, &block_io_guid,
+                                   GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+      dio = grub_efi_open_protocol (*handle, &disk_io_guid,
+                                   GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+      if (! bio || ! dio)
+       /* This should not happen... Why?  */
+       continue;
+
+      d = grub_malloc (sizeof (*d));
+      if (! d)
+       {
+         /* Uggh.  */
+         grub_free (handles);
+         return 0;
+       }
+
+      d->handle = *handle;
+      d->device_path = dp;
+      d->last_device_path = ldp;
+      d->block_io = bio;
+      d->disk_io = dio;
+      d->next = devices;
+      devices = d;
+    }
+
+  grub_free (handles);
+
+  return devices;
+}
+
+/* Find the parent device.  */
+static struct grub_efidisk_data *
+find_parent_device (struct grub_efidisk_data *devices,
+                   struct grub_efidisk_data *d)
+{
+  grub_efi_device_path_t *dp, *ldp;
+  struct grub_efidisk_data *parent;
+
+  dp = duplicate_device_path (d->device_path);
+  if (! dp)
+    return 0;
+
+  ldp = find_last_device_path (dp);
+  ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+  ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+  ldp->length[0] = sizeof (*ldp);
+  ldp->length[1] = 0;
+
+  for (parent = devices; parent; parent = parent->next)
+    {
+      /* Ignore itself.  */
+      if (parent == d)
+       continue;
+
+      if (compare_device_paths (parent->device_path, dp) == 0)
+       {
+         /* Found.  */
+         if (! parent->last_device_path)
+           parent = 0;
+
+         break;
+       }
+    }
+
+  grub_free (dp);
+  return parent;
+}
+
+static int
+iterate_child_devices (struct grub_efidisk_data *devices,
+                      struct grub_efidisk_data *d,
+                      int (*hook) (struct grub_efidisk_data *child))
+{
+  struct grub_efidisk_data *p;
+
+  for (p = devices; p; p = p->next)
+    {
+      grub_efi_device_path_t *dp, *ldp;
+
+      dp = duplicate_device_path (p->device_path);
+      if (! dp)
+       return 0;
+
+      ldp = find_last_device_path (dp);
+      ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+      ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+      ldp->length[0] = sizeof (*ldp);
+      ldp->length[1] = 0;
+
+      if (compare_device_paths (dp, d->device_path) == 0)
+       if (hook (p))
+         {
+           grub_free (dp);
+           return 1;
+         }
+
+      grub_free (dp);
+    }
+
+  return 0;
+}
+
+/* Add a device into a list of devices in an ascending order.  */
+static void
+add_device (struct grub_efidisk_data **devices, struct grub_efidisk_data *d)
+{
+  struct grub_efidisk_data **p;
+  struct grub_efidisk_data *n;
+
+  for (p = devices; *p; p = &((*p)->next))
+    {
+      int ret;
+
+      ret = compare_device_paths (find_last_device_path ((*p)->device_path),
+                                 find_last_device_path (d->device_path));
+      if (ret == 0)
+       ret = compare_device_paths ((*p)->device_path,
+                                   d->device_path);
+      if (ret == 0)
+       return;
+      else if (ret > 0)
+       break;
+    }
+
+  n = grub_malloc (sizeof (*n));
+  if (! n)
+    return;
+
+  grub_memcpy (n, d, sizeof (*n));
+  n->next = (*p);
+  (*p) = n;
+}
+
+/* Name the devices.  */
+static void
+name_devices (struct grub_efidisk_data *devices)
+{
+  struct grub_efidisk_data *d;
+
+  /* First, identify devices by media device paths.  */
+  for (d = devices; d; d = d->next)
+    {
+      grub_efi_device_path_t *dp;
+
+      dp = d->last_device_path;
+      if (! dp)
+       continue;
+
+      if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE)
+       {
+         int is_hard_drive = 0;
+
+         switch (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp))
+           {
+           case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
+             is_hard_drive = 1;
+             /* Fall through by intention.  */
+           case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE:
+             {
+               struct grub_efidisk_data *parent;
+
+               parent = find_parent_device (devices, d);
+               if (parent)
+                 {
+                   if (is_hard_drive)
+                     {
+#if 0
+                       grub_printf ("adding a hard drive by a partition: ");
+                       grub_print_device_path (parent->device_path);
+#endif
+                       add_device (&hd_devices, parent);
+                     }
+                   else
+                     {
+#if 0
+                       grub_printf ("adding a cdrom by a partition: ");
+                       grub_print_device_path (parent->device_path);
+#endif
+                       add_device (&cd_devices, parent);
+                     }
+
+                   /* Mark the parent as used.  */
+                   parent->last_device_path = 0;
+                 }
+             }
+             /* Mark itself as used.  */
+             d->last_device_path = 0;
+             break;
+
+           default:
+             /* For now, ignore the others.  */
+             break;
+           }
+       }
+    }
+
+  /* Let's see what can be added more.  */
+  for (d = devices; d; d = d->next)
+    {
+      grub_efi_device_path_t *dp;
+      grub_efi_block_io_media_t *m;
+
+      dp = d->last_device_path;
+      if (! dp)
+       continue;
+
+      m = d->block_io->media;
+      if (m->logical_partition)
+       {
+         /* Only one partition in a non-media device. Assume that this
+            is a floppy drive.  */
+#if 0
+         grub_printf ("adding a floppy by guessing: ");
+         grub_print_device_path (d->device_path);
+#endif
+         add_device (&fd_devices, d);
+       }
+      else if (m->read_only && m->block_size > GRUB_DISK_SECTOR_SIZE)
+       {
+         /* This check is too heuristic, but assume that this is a
+            CDROM drive.  */
+#if 0
+         grub_printf ("adding a cdrom by guessing: ");
+         grub_print_device_path (d->device_path);
+#endif
+         add_device (&cd_devices, d);
+       }
+      else
+       {
+         /* The default is a hard drive.  */
+#if 0
+         grub_printf ("adding a hard drive by guessing: ");
+         grub_print_device_path (d->device_path);
+#endif
+         add_device (&hd_devices, d);
+       }
+    }
+}
+
+static void
+free_devices (struct grub_efidisk_data *devices)
+{
+  struct grub_efidisk_data *p, *q;
+
+  for (p = devices; p; p = q)
+    {
+      q = p->next;
+      grub_free (p);
+    }
+}
+
+/* Enumerate all disks to name devices.  */
+static void
+enumerate_disks (void)
+{
+  struct grub_efidisk_data *devices;
+
+  devices = make_devices ();
+  if (! devices)
+    return;
+
+  name_devices (devices);
+  free_devices (devices);
+}
+
+static int
+grub_efidisk_iterate (int (*hook) (const char *name))
+{
+  struct grub_efidisk_data *d;
+  char buf[16];
+  int count;
+
+  for (d = fd_devices, count = 0; d; d = d->next, count++)
+    {
+      grub_snprintf (buf, sizeof (buf), "fd%d", count);
+      grub_dprintf ("efidisk", "iterating %s\n", buf);
+      if (hook (buf))
+       return 1;
+    }
+
+  for (d = hd_devices, count = 0; d; d = d->next, count++)
+    {
+      grub_snprintf (buf, sizeof (buf), "hd%d", count);
+      grub_dprintf ("efidisk", "iterating %s\n", buf);
+      if (hook (buf))
+       return 1;
+    }
+
+  for (d = cd_devices, count = 0; d; d = d->next, count++)
+    {
+      grub_snprintf (buf, sizeof (buf), "cd%d", count);
+      grub_dprintf ("efidisk", "iterating %s\n", buf);
+      if (hook (buf))
+       return 1;
+    }
+
+  return 0;
+}
+
+static int
+get_drive_number (const char *name)
+{
+  unsigned long drive;
+
+  if ((name[0] != 'f' && name[0] != 'h' && name[0] != 'c') || name[1] != 'd')
+    goto fail;
+
+  drive = grub_strtoul (name + 2, 0, 10);
+  if (grub_errno != GRUB_ERR_NONE)
+    goto fail;
+
+  return (int) drive ;
+
+ fail:
+  grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a efidisk");
+  return -1;
+}
+
+static struct grub_efidisk_data *
+get_device (struct grub_efidisk_data *devices, int num)
+{
+  struct grub_efidisk_data *d;
+
+  for (d = devices; d && num; d = d->next, num--)
+    ;
+
+  if (num == 0)
+    return d;
+
+  return 0;
+}
+
+static grub_err_t
+grub_efidisk_open (const char *name, struct grub_disk *disk)
+{
+  int num;
+  struct grub_efidisk_data *d = 0;
+  grub_efi_block_io_media_t *m;
+
+  grub_dprintf ("efidisk", "opening %s\n", name);
+
+  num = get_drive_number (name);
+  if (num < 0)
+    return grub_errno;
+
+  switch (name[0])
+    {
+    case 'f':
+      disk->has_partitions = 0;
+      d = get_device (fd_devices, num);
+      break;
+    case 'c':
+      /* FIXME: a CDROM should have partitions, but not implemented yet.  */
+      disk->has_partitions = 0;
+      d = get_device (cd_devices, num);
+      break;
+    case 'h':
+      disk->has_partitions = 1;
+      d = get_device (hd_devices, num);
+      break;
+    default:
+      /* Never reach here.  */
+      break;
+    }
+
+  if (! d)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such device");
+
+  disk->id = ((num << 8) | name[0]);
+  m = d->block_io->media;
+  /* FIXME: Probably it is better to store the block size in the disk,
+     and total sectors should be replaced with total blocks.  */
+  grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n",
+               m, (unsigned long long) m->last_block, m->block_size);
+  disk->total_sectors = (m->last_block
+                        * (m->block_size >> GRUB_DISK_SECTOR_BITS));
+  disk->data = d;
+
+  grub_dprintf ("efidisk", "opening %s succeeded\n", name);
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_efidisk_close (struct grub_disk *disk __attribute__ ((unused)))
+{
+  /* EFI disks do not allocate extra memory, so nothing to do here.  */
+  grub_dprintf ("efidisk", "closing %s\n", disk->name);
+}
+
+static grub_err_t
+grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector,
+                  grub_size_t size, char *buf)
+{
+  /* For now, use the disk io interface rather than the block io's.  */
+  struct grub_efidisk_data *d;
+  grub_efi_disk_io_t *dio;
+  grub_efi_block_io_t *bio;
+  grub_efi_status_t status;
+
+  d = disk->data;
+  dio = d->disk_io;
+  bio = d->block_io;
+
+  grub_dprintf ("efidisk",
+               "reading 0x%lx sectors at the sector 0x%llx from %s\n",
+               (unsigned long) size, (unsigned long long) sector, disk->name);
+
+  status = efi_call_5 (dio->read, dio, bio->media->media_id,
+                     (grub_efi_uint64_t) sector << GRUB_DISK_SECTOR_BITS,
+                     (grub_efi_uintn_t) size << GRUB_DISK_SECTOR_BITS,
+                     buf);
+  if (status != GRUB_EFI_SUCCESS)
+    return grub_error (GRUB_ERR_READ_ERROR, "efidisk read error");
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_efidisk_write (struct grub_disk *disk, grub_disk_addr_t sector,
+                   grub_size_t size, const char *buf)
+{
+  /* For now, use the disk io interface rather than the block io's.  */
+  struct grub_efidisk_data *d;
+  grub_efi_disk_io_t *dio;
+  grub_efi_block_io_t *bio;
+  grub_efi_status_t status;
+
+  d = disk->data;
+  dio = d->disk_io;
+  bio = d->block_io;
+
+  grub_dprintf ("efidisk",
+               "writing 0x%lx sectors at the sector 0x%llx to %s\n",
+               (unsigned long) size, (unsigned long long) sector, disk->name);
+
+  status = efi_call_5 (dio->write, dio, bio->media->media_id,
+                      (grub_efi_uint64_t) sector << GRUB_DISK_SECTOR_BITS,
+                      (grub_efi_uintn_t) size << GRUB_DISK_SECTOR_BITS,
+                      (void *) buf);
+  if (status != GRUB_EFI_SUCCESS)
+    return grub_error (GRUB_ERR_WRITE_ERROR, "efidisk write error");
+
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_disk_dev grub_efidisk_dev =
+  {
+    .name = "efidisk",
+    .id = GRUB_DISK_DEVICE_EFIDISK_ID,
+    .iterate = grub_efidisk_iterate,
+    .open = grub_efidisk_open,
+    .close = grub_efidisk_close,
+    .read = grub_efidisk_read,
+    .write = grub_efidisk_write,
+    .next = 0
+  };
+
+void
+grub_efidisk_init (void)
+{
+  enumerate_disks ();
+  grub_disk_dev_register (&grub_efidisk_dev);
+}
+
+void
+grub_efidisk_fini (void)
+{
+  free_devices (fd_devices);
+  free_devices (hd_devices);
+  free_devices (cd_devices);
+  grub_disk_dev_unregister (&grub_efidisk_dev);
+}
+
+/* Some utility functions to map GRUB devices with EFI devices.  */
+grub_efi_handle_t
+grub_efidisk_get_device_handle (grub_disk_t disk)
+{
+  struct grub_efidisk_data *d;
+  char type;
+
+  if (disk->dev->id != GRUB_DISK_DEVICE_EFIDISK_ID)
+    return 0;
+
+  d = disk->data;
+  type = disk->name[0];
+
+  switch (type)
+    {
+    case 'f':
+      /* This is the simplest case.  */
+      return d->handle;
+
+    case 'c':
+      /* FIXME: probably this is not correct.  */
+      return d->handle;
+
+    case 'h':
+      /* If this is the whole disk, just return its own data.  */
+      if (! disk->partition)
+       return d->handle;
+
+      /* Otherwise, we must query the corresponding device to the firmware.  */
+      {
+       struct grub_efidisk_data *devices;
+       grub_efi_handle_t handle = 0;
+       auto int find_partition (struct grub_efidisk_data *c);
+
+       int find_partition (struct grub_efidisk_data *c)
+         {
+           grub_efi_hard_drive_device_path_t hd;
+
+           grub_memcpy (&hd, c->last_device_path, sizeof (hd));
+
+           if ((GRUB_EFI_DEVICE_PATH_TYPE (c->last_device_path)
+                == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE)
+               && (GRUB_EFI_DEVICE_PATH_SUBTYPE (c->last_device_path)
+                   == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)
+               && (grub_partition_get_start (disk->partition)
+                   == hd.partition_start)
+               && (grub_partition_get_len (disk->partition)
+                   == hd.partition_size))
+             {
+               handle = c->handle;
+               return 1;
+             }
+
+           return 0;
+         }
+
+       devices = make_devices ();
+       iterate_child_devices (devices, d, find_partition);
+       free_devices (devices);
+
+       if (handle != 0)
+         return handle;
+      }
+      break;
+
+    default:
+      break;
+    }
+
+  return 0;
+}
+
+char *
+grub_efidisk_get_device_name (grub_efi_handle_t *handle)
+{
+  grub_efi_device_path_t *dp, *ldp;
+
+  dp = grub_efi_get_device_path (handle);
+  if (! dp)
+    return 0;
+
+  ldp = find_last_device_path (dp);
+  if (! ldp)
+    return 0;
+
+  if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
+      && (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp)
+         == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))
+    {
+      /* This is a hard disk partition.  */
+      grub_disk_t parent = 0;
+      char *partition_name = 0;
+      char *device_name;
+      grub_efi_device_path_t *dup_dp, *dup_ldp;
+      grub_efi_hard_drive_device_path_t hd;
+      auto int find_parent_disk (const char *name);
+      auto int find_partition (grub_disk_t disk, const grub_partition_t part);
+
+      /* Find the disk which is the parent of a given hard disk partition.  */
+      int find_parent_disk (const char *name)
+       {
+         grub_disk_t disk;
+
+         disk = grub_disk_open (name);
+         if (! disk)
+           return 1;
+
+         if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID)
+           {
+             struct grub_efidisk_data *d;
+
+             d = disk->data;
+             if (compare_device_paths (d->device_path, dup_dp) == 0)
+               {
+                 parent = disk;
+                 return 1;
+               }
+           }
+
+         grub_disk_close (disk);
+         return 0;
+       }
+
+      /* Find the identical partition.  */
+      int find_partition (grub_disk_t disk __attribute__ ((unused)),
+                         const grub_partition_t part)
+       {
+         if (grub_partition_get_start (part) == hd.partition_start
+             && grub_partition_get_len (part) == hd.partition_size)
+           {
+             partition_name = grub_partition_get_name (part);
+             return 1;
+           }
+
+         return 0;
+       }
+
+      /* It is necessary to duplicate the device path so that GRUB
+        can overwrite it.  */
+      dup_dp = duplicate_device_path (dp);
+      if (! dup_dp)
+       return 0;
+
+      dup_ldp = find_last_device_path (dup_dp);
+      dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+      dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+      dup_ldp->length[0] = sizeof (*dup_ldp);
+      dup_ldp->length[1] = 0;
+
+      grub_efidisk_iterate (find_parent_disk);
+      grub_free (dup_dp);
+
+      if (! parent)
+       return 0;
+
+      /* Find a partition which matches the hard drive device path.  */
+      grub_memcpy (&hd, ldp, sizeof (hd));
+      grub_partition_iterate (parent, find_partition);
+
+      if (! partition_name)
+       {
+         grub_disk_close (parent);
+         return 0;
+       }
+
+      device_name = grub_xasprintf ("%s,%s", parent->name, partition_name);
+      grub_free (partition_name);
+      grub_disk_close (parent);
+
+      return device_name;
+    }
+  else
+    {
+      /* This should be an entire disk.  */
+      auto int find_disk (const char *name);
+      char *device_name = 0;
+
+      int find_disk (const char *name)
+       {
+         grub_disk_t disk;
+
+         disk = grub_disk_open (name);
+         if (! disk)
+           return 1;
+
+         if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID)
+           {
+             struct grub_efidisk_data *d;
+
+             d = disk->data;
+             if (compare_device_paths (d->device_path, dp) == 0)
+               {
+                 device_name = grub_strdup (disk->name);
+                 grub_disk_close (disk);
+                 return 1;
+               }
+           }
+
+         grub_disk_close (disk);
+         return 0;
+
+       }
+
+      grub_efidisk_iterate (find_disk);
+      return device_name;
+    }
+
+  return 0;
+}
diff --git a/grub-core/disk/host.c b/grub-core/disk/host.c
new file mode 100644 (file)
index 0000000..c4f3e71
--- /dev/null
@@ -0,0 +1,96 @@
+/* host.c - Dummy disk driver to provide access to the hosts filesystem  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* When using the disk, make a reference to this module.  Otherwise
+   the user will end up with a useless module :-).  */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+
+int grub_disk_host_i_want_a_reference;
+
+static int
+grub_host_iterate (int (*hook) (const char *name))
+{
+  if (hook ("host"))
+    return 1;
+  return 0;
+}
+
+static grub_err_t
+grub_host_open (const char *name, grub_disk_t disk)
+{
+  if (grub_strcmp (name, "host"))
+      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a host disk");
+
+  disk->total_sectors = 0;
+  disk->id = (unsigned long) "host";
+
+  disk->has_partitions = 0;
+  disk->data = 0;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_host_close (grub_disk_t disk __attribute((unused)))
+{
+}
+
+static grub_err_t
+grub_host_read (grub_disk_t disk __attribute((unused)),
+               grub_disk_addr_t sector __attribute((unused)),
+               grub_size_t size __attribute((unused)),
+               char *buf __attribute((unused)))
+{
+  return GRUB_ERR_OUT_OF_RANGE;
+}
+
+static grub_err_t
+grub_host_write (grub_disk_t disk __attribute ((unused)),
+                    grub_disk_addr_t sector __attribute ((unused)),
+                    grub_size_t size __attribute ((unused)),
+                    const char *buf __attribute ((unused)))
+{
+  return GRUB_ERR_OUT_OF_RANGE;
+}
+
+static struct grub_disk_dev grub_host_dev =
+  {
+    /* The only important line in this file :-) */
+    .name = "host",
+    .id = GRUB_DISK_DEVICE_HOST_ID,
+    .iterate = grub_host_iterate,
+    .open = grub_host_open,
+    .close = grub_host_close,
+    .read = grub_host_read,
+    .write = grub_host_write,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(host)
+{
+  grub_disk_dev_register (&grub_host_dev);
+}
+
+GRUB_MOD_FINI(host)
+{
+  grub_disk_dev_unregister (&grub_host_dev);
+}
diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c
new file mode 100644 (file)
index 0000000..94d0e37
--- /dev/null
@@ -0,0 +1,414 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/biosdisk.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/kernel.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/term.h>
+
+static int cd_drive = 0;
+
+static int
+grub_biosdisk_get_drive (const char *name)
+{
+  unsigned long drive;
+
+  if ((name[0] != 'f' && name[0] != 'h') || name[1] != 'd')
+    goto fail;
+
+  drive = grub_strtoul (name + 2, 0, 10);
+  if (grub_errno != GRUB_ERR_NONE)
+    goto fail;
+
+  if (name[0] == 'h')
+    drive += 0x80;
+
+  return (int) drive ;
+
+ fail:
+  grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a biosdisk");
+  return -1;
+}
+
+static int
+grub_biosdisk_call_hook (int (*hook) (const char *name), int drive)
+{
+  char name[10];
+
+  grub_snprintf (name, sizeof (name),
+                (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80));
+  return hook (name);
+}
+
+static int
+grub_biosdisk_iterate (int (*hook) (const char *name))
+{
+  int drive;
+  int num_floppies;
+
+  /* For hard disks, attempt to read the MBR.  */
+  for (drive = 0x80; drive < 0x90; drive++)
+    {
+      if (grub_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1,
+                                    GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0)
+       {
+         grub_dprintf ("disk", "Read error when probing drive 0x%2x\n", drive);
+         break;
+       }
+
+      if (grub_biosdisk_call_hook (hook, drive))
+       return 1;
+    }
+
+  if (cd_drive)
+    {
+      if (grub_biosdisk_call_hook (hook, cd_drive))
+      return 1;
+    }
+
+  /* For floppy disks, we can get the number safely.  */
+  num_floppies = grub_biosdisk_get_num_floppies ();
+  for (drive = 0; drive < num_floppies; drive++)
+    if (grub_biosdisk_call_hook (hook, drive))
+      return 1;
+
+  return 0;
+}
+
+static grub_err_t
+grub_biosdisk_open (const char *name, grub_disk_t disk)
+{
+  grub_uint64_t total_sectors = 0;
+  int drive;
+  struct grub_biosdisk_data *data;
+
+  drive = grub_biosdisk_get_drive (name);
+  if (drive < 0)
+    return grub_errno;
+
+  disk->has_partitions = ((drive & 0x80) && (drive != cd_drive));
+  disk->id = drive;
+
+  data = (struct grub_biosdisk_data *) grub_zalloc (sizeof (*data));
+  if (! data)
+    return grub_errno;
+
+  data->drive = drive;
+
+  if ((cd_drive) && (drive == cd_drive))
+    {
+      data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM;
+      data->sectors = 32;
+      total_sectors = GRUB_ULONG_MAX;  /* TODO: get the correct size.  */
+    }
+  else if (drive & 0x80)
+    {
+      /* HDD */
+      int version;
+
+      version = grub_biosdisk_check_int13_extensions (drive);
+      if (version)
+       {
+         struct grub_biosdisk_drp *drp
+           = (struct grub_biosdisk_drp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+
+         /* Clear out the DRP.  */
+         grub_memset (drp, 0, sizeof (*drp));
+         drp->size = sizeof (*drp);
+         if (! grub_biosdisk_get_diskinfo_int13_extensions (drive, drp))
+           {
+             data->flags = GRUB_BIOSDISK_FLAG_LBA;
+
+             if (drp->total_sectors)
+               total_sectors = drp->total_sectors;
+             else
+                /* Some buggy BIOSes doesn't return the total sectors
+                   correctly but returns zero. So if it is zero, compute
+                   it by C/H/S returned by the LBA BIOS call.  */
+                total_sectors = drp->cylinders * drp->heads * drp->sectors;
+           }
+       }
+    }
+
+  if (! (data->flags & GRUB_BIOSDISK_FLAG_CDROM))
+    {
+      if (grub_biosdisk_get_diskinfo_standard (drive,
+                                              &data->cylinders,
+                                              &data->heads,
+                                              &data->sectors) != 0)
+        {
+         if (total_sectors && (data->flags & GRUB_BIOSDISK_FLAG_LBA))
+           {
+             data->sectors = 63;
+             data->heads = 255;
+             data->cylinders
+               = grub_divmod64 (total_sectors
+                                + data->heads * data->sectors - 1,
+                                data->heads * data->sectors, 0);
+           }
+         else
+           {
+             grub_free (data);
+             return grub_error (GRUB_ERR_BAD_DEVICE, "%s cannot get C/H/S values", disk->name);
+           }
+        }
+
+      if (! total_sectors)
+        total_sectors = data->cylinders * data->heads * data->sectors;
+    }
+
+  disk->total_sectors = total_sectors;
+  disk->data = data;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_biosdisk_close (grub_disk_t disk)
+{
+  grub_free (disk->data);
+}
+
+/* For readability.  */
+#define GRUB_BIOSDISK_READ     0
+#define GRUB_BIOSDISK_WRITE    1
+
+#define GRUB_BIOSDISK_CDROM_RETRY_COUNT 3
+
+static grub_err_t
+grub_biosdisk_rw (int cmd, grub_disk_t disk,
+                 grub_disk_addr_t sector, grub_size_t size,
+                 unsigned segment)
+{
+  struct grub_biosdisk_data *data = disk->data;
+
+  if (data->flags & GRUB_BIOSDISK_FLAG_LBA)
+    {
+      struct grub_biosdisk_dap *dap;
+
+      dap = (struct grub_biosdisk_dap *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR
+                                         + (data->sectors
+                                            << GRUB_DISK_SECTOR_BITS));
+      dap->length = sizeof (*dap);
+      dap->reserved = 0;
+      dap->blocks = size;
+      dap->buffer = segment << 16;     /* The format SEGMENT:ADDRESS.  */
+      dap->block = sector;
+
+      if (data->flags & GRUB_BIOSDISK_FLAG_CDROM)
+        {
+         int i;
+
+         if (cmd)
+           return grub_error (GRUB_ERR_WRITE_ERROR, "can\'t write to cdrom");
+
+         dap->blocks = ALIGN_UP (dap->blocks, 4) >> 2;
+         dap->block >>= 2;
+
+         for (i = 0; i < GRUB_BIOSDISK_CDROM_RETRY_COUNT; i++)
+            if (! grub_biosdisk_rw_int13_extensions (0x42, data->drive, dap))
+             break;
+
+         if (i == GRUB_BIOSDISK_CDROM_RETRY_COUNT)
+           return grub_error (GRUB_ERR_READ_ERROR, "cdrom read error");
+       }
+      else
+        if (grub_biosdisk_rw_int13_extensions (cmd + 0x42, data->drive, dap))
+         {
+           /* Fall back to the CHS mode.  */
+           data->flags &= ~GRUB_BIOSDISK_FLAG_LBA;
+           disk->total_sectors = data->cylinders * data->heads * data->sectors;
+           return grub_biosdisk_rw (cmd, disk, sector, size, segment);
+         }
+    }
+  else
+    {
+      unsigned coff, hoff, soff;
+      unsigned head;
+
+      /* It is impossible to reach over 8064 MiB (a bit less than LBA24) with
+        the traditional CHS access.  */
+      if (sector >
+         1024 /* cylinders */ *
+         256 /* heads */ *
+         63 /* spt */)
+       return grub_error (GRUB_ERR_OUT_OF_RANGE, "%s out of disk", disk->name);
+
+      soff = ((grub_uint32_t) sector) % data->sectors + 1;
+      head = ((grub_uint32_t) sector) / data->sectors;
+      hoff = head % data->heads;
+      coff = head / data->heads;
+
+      if (coff >= data->cylinders)
+       return grub_error (GRUB_ERR_OUT_OF_RANGE, "%s out of disk", disk->name);
+
+      if (grub_biosdisk_rw_standard (cmd + 0x02, data->drive,
+                                    coff, hoff, soff, size, segment))
+       {
+         switch (cmd)
+           {
+           case GRUB_BIOSDISK_READ:
+             return grub_error (GRUB_ERR_READ_ERROR, "%s read error", disk->name);
+           case GRUB_BIOSDISK_WRITE:
+             return grub_error (GRUB_ERR_WRITE_ERROR, "%s write error", disk->name);
+           }
+       }
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Return the number of sectors which can be read safely at a time.  */
+static grub_size_t
+get_safe_sectors (grub_disk_addr_t sector, grub_uint32_t sectors)
+{
+  grub_size_t size;
+  grub_uint32_t offset;
+
+  /* OFFSET = SECTOR % SECTORS */
+  grub_divmod64 (sector, sectors, &offset);
+
+  size = sectors - offset;
+
+  /* Limit the max to 0x7f because of Phoenix EDD.  */
+  if (size > 0x7f)
+    size = 0x7f;
+
+  return size;
+}
+
+static grub_err_t
+grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
+                   grub_size_t size, char *buf)
+{
+  struct grub_biosdisk_data *data = disk->data;
+
+  while (size)
+    {
+      grub_size_t len;
+      grub_size_t cdoff = 0;
+
+      len = get_safe_sectors (sector, data->sectors);
+
+      if (data->flags & GRUB_BIOSDISK_FLAG_CDROM)
+       {
+         cdoff = (sector & 3) << GRUB_DISK_SECTOR_BITS;
+         len = ALIGN_UP (sector + len, 4) - (sector & ~3);
+         sector &= ~3;
+       }
+
+      if (len > size)
+       len = size;
+
+      if (grub_biosdisk_rw (GRUB_BIOSDISK_READ, disk, sector, len,
+                           GRUB_MEMORY_MACHINE_SCRATCH_SEG))
+       return grub_errno;
+
+      grub_memcpy (buf, (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + cdoff),
+                  len << GRUB_DISK_SECTOR_BITS);
+      buf += len << GRUB_DISK_SECTOR_BITS;
+      sector += len;
+      size -= len;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
+                    grub_size_t size, const char *buf)
+{
+  struct grub_biosdisk_data *data = disk->data;
+
+  if (data->flags & GRUB_BIOSDISK_FLAG_CDROM)
+    return grub_error (GRUB_ERR_IO, "can't write to CDROM");
+
+  while (size)
+    {
+      grub_size_t len;
+
+      len = get_safe_sectors (sector, data->sectors);
+      if (len > size)
+       len = size;
+
+      grub_memcpy ((void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, buf,
+                  len << GRUB_DISK_SECTOR_BITS);
+
+      if (grub_biosdisk_rw (GRUB_BIOSDISK_WRITE, disk, sector, len,
+                           GRUB_MEMORY_MACHINE_SCRATCH_SEG))
+       return grub_errno;
+
+      buf += len << GRUB_DISK_SECTOR_BITS;
+      sector += len;
+      size -= len;
+    }
+
+  return grub_errno;
+}
+
+static struct grub_disk_dev grub_biosdisk_dev =
+  {
+    .name = "biosdisk",
+    .id = GRUB_DISK_DEVICE_BIOSDISK_ID,
+    .iterate = grub_biosdisk_iterate,
+    .open = grub_biosdisk_open,
+    .close = grub_biosdisk_close,
+    .read = grub_biosdisk_read,
+    .write = grub_biosdisk_write,
+    .next = 0
+  };
+
+static void
+grub_disk_biosdisk_fini (void)
+{
+  grub_disk_dev_unregister (&grub_biosdisk_dev);
+}
+
+GRUB_MOD_INIT(biosdisk)
+{
+  struct grub_biosdisk_cdrp *cdrp
+        = (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+
+  if (grub_disk_firmware_is_tainted)
+    {
+      grub_printf ("Firmware is marked as tainted, refusing to initialize.\n");
+      return;
+    }
+  grub_disk_firmware_fini = grub_disk_biosdisk_fini;
+
+  grub_memset (cdrp, 0, sizeof (*cdrp));
+  cdrp->size = sizeof (*cdrp);
+  cdrp->media_type = 0xFF;
+  if ((! grub_biosdisk_get_cdinfo_int13_extensions (grub_boot_drive, cdrp)) &&
+      ((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK)
+       == GRUB_BIOSDISK_CDTYPE_NO_EMUL))
+    cd_drive = cdrp->drive_no;
+
+  grub_disk_dev_register (&grub_biosdisk_dev);
+}
+
+GRUB_MOD_FINI(biosdisk)
+{
+  grub_disk_biosdisk_fini ();
+}
diff --git a/grub-core/disk/ieee1275/nand.c b/grub-core/disk/ieee1275/nand.c
new file mode 100644 (file)
index 0000000..df2ee81
--- /dev/null
@@ -0,0 +1,215 @@
+/* nand.c - NAND flash disk access.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/ieee1275/ieee1275.h>
+
+struct grub_nand_data
+{
+  grub_ieee1275_ihandle_t handle;
+  grub_uint32_t block_size;
+};
+
+static int
+grub_nand_iterate (int (*hook) (const char *name))
+{
+  auto int dev_iterate (struct grub_ieee1275_devalias *alias);
+  int dev_iterate (struct grub_ieee1275_devalias *alias)
+    {
+      if (! grub_strcmp (alias->name, "nand"))
+        {
+          hook (alias->name);
+          return 1;
+        }
+
+      return 0;
+    }
+
+  return grub_devalias_iterate (dev_iterate);
+}
+
+static grub_err_t
+grub_nand_read (grub_disk_t disk, grub_disk_addr_t sector,
+                grub_size_t size, char *buf);
+
+static grub_err_t
+grub_nand_open (const char *name, grub_disk_t disk)
+{
+  grub_ieee1275_ihandle_t dev_ihandle = 0;
+  struct grub_nand_data *data = 0;
+  struct size_args
+    {
+      struct grub_ieee1275_common_hdr common;
+      grub_ieee1275_cell_t method;
+      grub_ieee1275_cell_t ihandle;
+      grub_ieee1275_cell_t result;
+      grub_ieee1275_cell_t size1;
+      grub_ieee1275_cell_t size2;
+    } args;
+
+  if (! grub_strstr (name, "nand"))
+    return  grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a NAND device");
+
+  data = grub_malloc (sizeof (*data));
+  if (! data)
+    goto fail;
+
+  grub_ieee1275_open (name, &dev_ihandle);
+  if (! dev_ihandle)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
+      goto fail;
+    }
+
+  data->handle = dev_ihandle;
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 2);
+  args.method = (grub_ieee1275_cell_t) "block-size";
+  args.ihandle = dev_ihandle;
+  args.result = 1;
+
+  if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result))
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't get block size");
+      goto fail;
+    }
+
+  data->block_size = (args.size1 >> GRUB_DISK_SECTOR_BITS);
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3);
+  args.method = (grub_ieee1275_cell_t) "size";
+  args.ihandle = dev_ihandle;
+  args.result = 1;
+
+  if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result))
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't get disk size");
+      goto fail;
+    }
+
+  disk->total_sectors = args.size1;
+  disk->total_sectors <<= 32;
+  disk->total_sectors += args.size2;
+  disk->total_sectors >>= GRUB_DISK_SECTOR_BITS;
+
+  disk->id = dev_ihandle;
+
+  disk->has_partitions = 0;
+  disk->data = data;
+
+  return 0;
+
+fail:
+  if (dev_ihandle)
+    grub_ieee1275_close (dev_ihandle);
+  grub_free (data);
+  return grub_errno;
+}
+
+static void
+grub_nand_close (grub_disk_t disk)
+{
+  grub_ieee1275_close (((struct grub_nand_data *) disk->data)->handle);
+  grub_free (disk->data);
+}
+
+static grub_err_t
+grub_nand_read (grub_disk_t disk, grub_disk_addr_t sector,
+                grub_size_t size, char *buf)
+{
+  struct grub_nand_data *data = disk->data;
+  grub_size_t bsize, ofs;
+
+  struct read_args
+    {
+      struct grub_ieee1275_common_hdr common;
+      grub_ieee1275_cell_t method;
+      grub_ieee1275_cell_t ihandle;
+      grub_ieee1275_cell_t ofs;
+      grub_ieee1275_cell_t page;
+      grub_ieee1275_cell_t len;
+      grub_ieee1275_cell_t buf;
+      grub_ieee1275_cell_t result;
+    } args;
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1);
+  args.method = (grub_ieee1275_cell_t) "pio-read";
+  args.ihandle = data->handle;
+  args.buf = (grub_ieee1275_cell_t) buf;
+  args.page = (grub_ieee1275_cell_t) ((grub_size_t) sector / data->block_size);
+
+  ofs = ((grub_size_t) sector % data->block_size) << GRUB_DISK_SECTOR_BITS;
+  size <<= GRUB_DISK_SECTOR_BITS;
+  bsize = (data->block_size << GRUB_DISK_SECTOR_BITS);
+
+  do
+    {
+      grub_size_t len;
+
+      len = (ofs + size > bsize) ? (bsize - ofs) : size;
+
+      args.len = (grub_ieee1275_cell_t) len;
+      args.ofs = (grub_ieee1275_cell_t) ofs;
+      args.result = 1;
+
+      if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result))
+        return grub_error (GRUB_ERR_READ_ERROR, "read error");
+
+      ofs = 0;
+      size -= len;
+      args.buf += len;
+      args.page++;
+    } while (size);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_nand_write (grub_disk_t disk __attribute ((unused)),
+                 grub_disk_addr_t sector __attribute ((unused)),
+                 grub_size_t size __attribute ((unused)),
+                 const char *buf __attribute ((unused)))
+{
+  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+static struct grub_disk_dev grub_nand_dev =
+  {
+    .name = "nand",
+    .id = GRUB_DISK_DEVICE_NAND_ID,
+    .iterate = grub_nand_iterate,
+    .open = grub_nand_open,
+    .close = grub_nand_close,
+    .read = grub_nand_read,
+    .write = grub_nand_write,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(nand)
+{
+  grub_disk_dev_register (&grub_nand_dev);
+}
+
+GRUB_MOD_FINI(nand)
+{
+  grub_disk_dev_unregister (&grub_nand_dev);
+}
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
new file mode 100644 (file)
index 0000000..e5a4a67
--- /dev/null
@@ -0,0 +1,285 @@
+/* ofdisk.c - Open Firmware disk access.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/ieee1275/ofdisk.h>
+
+struct ofdisk_hash_ent
+{
+  char *devpath;
+  struct ofdisk_hash_ent *next;
+};
+
+#define OFDISK_HASH_SZ 8
+static struct ofdisk_hash_ent *ofdisk_hash[OFDISK_HASH_SZ];
+
+static int
+ofdisk_hash_fn (const char *devpath)
+{
+  int hash = 0;
+  while (*devpath)
+    hash ^= *devpath++;
+  return (hash & (OFDISK_HASH_SZ - 1));
+}
+
+static struct ofdisk_hash_ent *
+ofdisk_hash_find (const char *devpath)
+{
+  struct ofdisk_hash_ent *p = ofdisk_hash[ofdisk_hash_fn(devpath)];
+
+  while (p)
+    {
+      if (!grub_strcmp (p->devpath, devpath))
+       break;
+      p = p->next;
+    }
+  return p;
+}
+
+static struct ofdisk_hash_ent *
+ofdisk_hash_add (char *devpath)
+{
+  struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)];
+  struct ofdisk_hash_ent *p = grub_malloc(sizeof (*p));
+
+  if (p)
+    {
+      p->devpath = devpath;
+      p->next = *head;
+      *head = p;
+    }
+  return p;
+}
+
+static int
+grub_ofdisk_iterate (int (*hook) (const char *name))
+{
+  auto int dev_iterate (struct grub_ieee1275_devalias *alias);
+
+  int dev_iterate (struct grub_ieee1275_devalias *alias)
+    {
+      int ret = 0;
+
+      grub_dprintf ("disk", "disk name = %s\n", alias->name);
+
+      if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY))
+       {
+         grub_ieee1275_phandle_t dev;
+         char tmp[8];
+
+         if (grub_ieee1275_finddevice (alias->path, &dev))
+           {
+             grub_dprintf ("disk", "finddevice (%s) failed\n", alias->path);
+             return 0;
+           }
+
+         if (grub_ieee1275_get_property (dev, "iconname", tmp,
+                                         sizeof tmp, 0))
+           {
+             grub_dprintf ("disk", "get iconname failed\n");
+             return 0;
+           }
+
+         if (grub_strcmp (tmp, "sdmmc"))
+           {
+             grub_dprintf ("disk", "device is not an SD card\n");
+             return 0;
+           }
+       }
+
+      if (! grub_strcmp (alias->type, "block") &&
+         grub_strncmp (alias->name, "cdrom", 5))
+       ret = hook (alias->name);
+      return ret;
+    }
+
+  return grub_devalias_iterate (dev_iterate);
+}
+
+static char *
+compute_dev_path (const char *name)
+{
+  char *devpath = grub_malloc (grub_strlen (name) + 3);
+  char *p, c;
+
+  if (!devpath)
+    return NULL;
+
+  /* Un-escape commas. */
+  p = devpath;
+  while ((c = *name++) != '\0')
+    {
+      if (c == '\\' && *name == ',')
+       {
+         *p++ = ',';
+         name++;
+       }
+      else
+       *p++ = c;
+    }
+
+  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0))
+    {
+      *p++ = ':';
+      *p++ = '0';
+    }
+  *p++ = '\0';
+
+  return devpath;
+}
+
+static grub_err_t
+grub_ofdisk_open (const char *name, grub_disk_t disk)
+{
+  grub_ieee1275_phandle_t dev;
+  grub_ieee1275_ihandle_t dev_ihandle = 0;
+  struct ofdisk_hash_ent *op;
+  char *devpath;
+  /* XXX: This should be large enough for any possible case.  */
+  char prop[64];
+  grub_ssize_t actual;
+
+  devpath = compute_dev_path (name);
+  if (! devpath)
+    return grub_errno;
+
+  op = ofdisk_hash_find (devpath);
+  if (!op)
+    op = ofdisk_hash_add (devpath);
+
+  grub_free (devpath);
+  if (!op)
+    return grub_errno;
+
+  grub_dprintf ("disk", "Opening `%s'.\n", op->devpath);
+
+  if (grub_ieee1275_finddevice (op->devpath, &dev))
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read device properties");
+      goto fail;
+    }
+
+  if (grub_ieee1275_get_property (dev, "device_type", prop, sizeof (prop),
+                                 &actual))
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read the device type");
+      goto fail;
+    }
+
+  if (grub_strcmp (prop, "block"))
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "not a block device");
+      goto fail;
+    }
+
+  grub_ieee1275_open (op->devpath, &dev_ihandle);
+  if (! dev_ihandle)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
+      goto fail;
+    }
+
+  grub_dprintf ("disk", "Opened `%s' as handle %p.\n", op->devpath,
+               (void *) (unsigned long) dev_ihandle);
+
+  /* XXX: There is no property to read the number of blocks.  There
+     should be a property `#blocks', but it is not there.  Perhaps it
+     is possible to use seek for this.  */
+  disk->total_sectors = 0xFFFFFFFFUL;
+
+  disk->id = (unsigned long) op;
+
+  /* XXX: Read this, somehow.  */
+  disk->has_partitions = 1;
+  disk->data = (void *) (unsigned long) dev_ihandle;
+  return 0;
+
+ fail:
+  if (dev_ihandle)
+    grub_ieee1275_close (dev_ihandle);
+  return grub_errno;
+}
+
+static void
+grub_ofdisk_close (grub_disk_t disk)
+{
+  grub_dprintf ("disk", "Closing handle %p.\n",
+               (void *) disk->data);
+  grub_ieee1275_close ((grub_ieee1275_ihandle_t) (unsigned long) disk->data);
+}
+
+static grub_err_t
+grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
+                 grub_size_t size, char *buf)
+{
+  grub_ssize_t status, actual;
+  unsigned long long pos;
+
+  pos = sector * 512UL;
+
+  grub_ieee1275_seek ((grub_ieee1275_ihandle_t) (unsigned long) disk->data,
+                     pos, &status);
+  if (status < 0)
+    return grub_error (GRUB_ERR_READ_ERROR,
+                      "seek error, can't seek block %llu",
+                      (long long) sector);
+  grub_ieee1275_read ((grub_ieee1275_ihandle_t) (unsigned long) disk->data,
+                     buf, size * 512UL, &actual);
+  if (actual != (grub_ssize_t) (size * 512UL))
+    return grub_error (GRUB_ERR_READ_ERROR, "read error on block: %llu",
+                      (long long) sector);
+
+  return 0;
+}
+
+static grub_err_t
+grub_ofdisk_write (grub_disk_t disk __attribute ((unused)),
+                  grub_disk_addr_t sector __attribute ((unused)),
+                  grub_size_t size __attribute ((unused)),
+                  const char *buf __attribute ((unused)))
+{
+  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+static struct grub_disk_dev grub_ofdisk_dev =
+  {
+    .name = "ofdisk",
+    .id = GRUB_DISK_DEVICE_OFDISK_ID,
+    .iterate = grub_ofdisk_iterate,
+    .open = grub_ofdisk_open,
+    .close = grub_ofdisk_close,
+    .read = grub_ofdisk_read,
+    .write = grub_ofdisk_write,
+    .next = 0
+  };
+
+void
+grub_ofdisk_init (void)
+{
+  grub_disk_dev_register (&grub_ofdisk_dev);
+}
+
+void
+grub_ofdisk_fini (void)
+{
+  grub_disk_dev_unregister (&grub_ofdisk_dev);
+}
diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c
new file mode 100644 (file)
index 0000000..1b525e0
--- /dev/null
@@ -0,0 +1,258 @@
+/* loopback.c - command to add loopback devices.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+
+struct grub_loopback
+{
+  char *devname;
+  char *filename;
+  int has_partitions;
+  struct grub_loopback *next;
+};
+
+static struct grub_loopback *loopback_list;
+
+static const struct grub_arg_option options[] =
+  {
+    {"delete", 'd', 0, N_("Delete the loopback device entry."), 0, 0},
+    {"partitions", 'p', 0, N_("Simulate a hard drive with partitions."), 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+/* Delete the loopback device NAME.  */
+static grub_err_t
+delete_loopback (const char *name)
+{
+  struct grub_loopback *dev;
+  struct grub_loopback **prev;
+
+  /* Search for the device.  */
+  for (dev = loopback_list, prev = &loopback_list;
+       dev;
+       prev = &dev->next, dev = dev->next)
+    if (grub_strcmp (dev->devname, name) == 0)
+      break;
+
+  if (! dev)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "device not found");
+
+  /* Remove the device from the list.  */
+  *prev = dev->next;
+
+  grub_free (dev->devname);
+  grub_free (dev->filename);
+  grub_free (dev);
+
+  return 0;
+}
+
+/* The command to add and remove loopback devices.  */
+static grub_err_t
+grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args)
+{
+  struct grub_arg_list *state = state = cmd->state;
+  grub_file_t file;
+  struct grub_loopback *newdev;
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
+
+  /* Check if `-d' was used.  */
+  if (state[0].set)
+      return delete_loopback (args[0]);
+
+  if (argc < 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  file = grub_file_open (args[1]);
+  if (! file)
+    return grub_errno;
+
+  /* Close the file, the only reason for opening it is validation.  */
+  grub_file_close (file);
+
+  /* First try to replace the old device.  */
+  for (newdev = loopback_list; newdev; newdev = newdev->next)
+    if (grub_strcmp (newdev->devname, args[0]) == 0)
+      break;
+
+  if (newdev)
+    {
+      char *newname = grub_strdup (args[1]);
+      if (! newname)
+       return grub_errno;
+
+      grub_free (newdev->filename);
+      newdev->filename = newname;
+
+      /* Set has_partitions when `--partitions' was used.  */
+      newdev->has_partitions = state[1].set;
+
+      return 0;
+    }
+
+  /* Unable to replace it, make a new entry.  */
+  newdev = grub_malloc (sizeof (struct grub_loopback));
+  if (! newdev)
+    return grub_errno;
+
+  newdev->devname = grub_strdup (args[0]);
+  if (! newdev->devname)
+    {
+      grub_free (newdev);
+      return grub_errno;
+    }
+
+  newdev->filename = grub_strdup (args[1]);
+  if (! newdev->filename)
+    {
+      grub_free (newdev->devname);
+      grub_free (newdev);
+      return grub_errno;
+    }
+
+  /* Set has_partitions when `--partitions' was used.  */
+  newdev->has_partitions = state[1].set;
+
+  /* Add the new entry to the list.  */
+  newdev->next = loopback_list;
+  loopback_list = newdev;
+
+  return 0;
+}
+
+\f
+static int
+grub_loopback_iterate (int (*hook) (const char *name))
+{
+  struct grub_loopback *d;
+  for (d = loopback_list; d; d = d->next)
+    {
+      if (hook (d->devname))
+       return 1;
+    }
+  return 0;
+}
+
+static grub_err_t
+grub_loopback_open (const char *name, grub_disk_t disk)
+{
+  grub_file_t file;
+  struct grub_loopback *dev;
+
+  for (dev = loopback_list; dev; dev = dev->next)
+    if (grub_strcmp (dev->devname, name) == 0)
+      break;
+
+  if (! dev)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
+
+  file = grub_file_open (dev->filename);
+  if (! file)
+    return grub_errno;
+
+  /* Use the filesize for the disk size, round up to a complete sector.  */
+  disk->total_sectors = ((file->size + GRUB_DISK_SECTOR_SIZE - 1)
+                        / GRUB_DISK_SECTOR_SIZE);
+  disk->id = (unsigned long) dev;
+
+  disk->has_partitions = dev->has_partitions;
+  disk->data = file;
+
+  return 0;
+}
+
+static void
+grub_loopback_close (grub_disk_t disk)
+{
+  grub_file_t file = (grub_file_t) disk->data;
+
+  grub_file_close (file);
+}
+
+static grub_err_t
+grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector,
+                   grub_size_t size, char *buf)
+{
+  grub_file_t file = (grub_file_t) disk->data;
+  grub_off_t pos;
+
+  grub_file_seek (file, sector << GRUB_DISK_SECTOR_BITS);
+
+  grub_file_read (file, buf, size << GRUB_DISK_SECTOR_BITS);
+  if (grub_errno)
+    return grub_errno;
+
+  /* In case there is more data read than there is available, in case
+     of files that are not a multiple of GRUB_DISK_SECTOR_SIZE, fill
+     the rest with zeros.  */
+  pos = (sector + size) << GRUB_DISK_SECTOR_BITS;
+  if (pos > file->size)
+    {
+      grub_size_t amount = pos - file->size;
+      grub_memset (buf + (size << GRUB_DISK_SECTOR_BITS) - amount, 0, amount);
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_loopback_write (grub_disk_t disk __attribute ((unused)),
+                    grub_disk_addr_t sector __attribute ((unused)),
+                    grub_size_t size __attribute ((unused)),
+                    const char *buf __attribute ((unused)))
+{
+  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+static struct grub_disk_dev grub_loopback_dev =
+  {
+    .name = "loopback",
+    .id = GRUB_DISK_DEVICE_LOOPBACK_ID,
+    .iterate = grub_loopback_iterate,
+    .open = grub_loopback_open,
+    .close = grub_loopback_close,
+    .read = grub_loopback_read,
+    .write = grub_loopback_write,
+    .next = 0
+  };
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(loopback)
+{
+  cmd = grub_register_extcmd ("loopback", grub_cmd_loopback,
+                             GRUB_COMMAND_FLAG_BOTH,
+                             N_("[-d|-p] DEVICENAME FILE."),
+                             N_("Make a device of a file."), options);
+  grub_disk_dev_register (&grub_loopback_dev);
+}
+
+GRUB_MOD_FINI(loopback)
+{
+  grub_unregister_extcmd (cmd);
+  grub_disk_dev_unregister (&grub_loopback_dev);
+}
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
new file mode 100644 (file)
index 0000000..c2ae82d
--- /dev/null
@@ -0,0 +1,624 @@
+/* lvm.c - module to read Logical Volumes.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/lvm.h>
+
+#ifdef GRUB_UTIL
+#include <grub/util/misc.h>
+#endif
+
+static struct grub_lvm_vg *vg_list;
+static int lv_count;
+
+\f
+/* Go the string STR and return the number after STR.  *P will point
+   at the number.  In case STR is not found, *P will be NULL and the
+   return value will be 0.  */
+static int
+grub_lvm_getvalue (char **p, char *str)
+{
+  *p = grub_strstr (*p, str);
+  if (! *p)
+    return 0;
+  *p += grub_strlen (str);
+  return grub_strtoul (*p, NULL, 10);
+}
+
+static int
+grub_lvm_iterate (int (*hook) (const char *name))
+{
+  struct grub_lvm_vg *vg;
+  for (vg = vg_list; vg; vg = vg->next)
+    {
+      struct grub_lvm_lv *lv;
+      if (vg->lvs)
+       for (lv = vg->lvs; lv; lv = lv->next)
+         if (hook (lv->name))
+           return 1;
+    }
+
+  return 0;
+}
+
+#ifdef GRUB_UTIL
+static grub_disk_memberlist_t
+grub_lvm_memberlist (grub_disk_t disk)
+{
+  struct grub_lvm_lv *lv = disk->data;
+  grub_disk_memberlist_t list = NULL, tmp;
+  struct grub_lvm_pv *pv;
+
+  if (lv->vg->pvs)
+    for (pv = lv->vg->pvs; pv; pv = pv->next)
+      {
+       if (!pv->disk)
+         grub_util_error ("Couldn't find PV %s. Check your device.map",
+                          pv->name);
+       tmp = grub_malloc (sizeof (*tmp));
+       tmp->disk = pv->disk;
+       tmp->next = list;
+       list = tmp;
+      }
+
+  return list;
+}
+#endif
+
+static grub_err_t
+grub_lvm_open (const char *name, grub_disk_t disk)
+{
+  struct grub_lvm_vg *vg;
+  struct grub_lvm_lv *lv = NULL;
+  for (vg = vg_list; vg; vg = vg->next)
+    {
+      if (vg->lvs)
+       for (lv = vg->lvs; lv; lv = lv->next)
+         if (! grub_strcmp (lv->name, name))
+           break;
+
+      if (lv)
+       break;
+    }
+
+  if (! lv)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown LVM device %s", name);
+
+  disk->has_partitions = 0;
+  disk->id = lv->number;
+  disk->data = lv;
+  disk->total_sectors = lv->size;
+
+  return 0;
+}
+
+static void
+grub_lvm_close (grub_disk_t disk __attribute ((unused)))
+{
+  return;
+}
+
+static grub_err_t
+grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector,
+               grub_size_t size, char *buf)
+{
+  grub_err_t err = 0;
+  struct grub_lvm_lv *lv = disk->data;
+  struct grub_lvm_vg *vg = lv->vg;
+  struct grub_lvm_segment *seg = lv->segments;
+  struct grub_lvm_pv *pv;
+  grub_uint64_t offset;
+  grub_uint64_t extent;
+  unsigned int i;
+
+  extent = grub_divmod64 (sector, vg->extent_size, NULL);
+
+  /* Find the right segment.  */
+  for (i = 0; i < lv->segment_count; i++)
+    {
+      if ((seg->start_extent <= extent)
+         && ((seg->start_extent + seg->extent_count) > extent))
+       {
+         break;
+       }
+
+      seg++;
+    }
+
+  if (seg->stripe_count == 1)
+    {
+      /* This segment is linear, so that's easy.  We just need to find
+        out the offset in the physical volume and read SIZE bytes
+        from that.  */
+      struct grub_lvm_stripe *stripe = seg->stripes;
+      grub_uint64_t seg_offset; /* Offset of the segment in PV device.  */
+
+      pv = stripe->pv;
+      seg_offset = ((grub_uint64_t) stripe->start
+                   * (grub_uint64_t) vg->extent_size) + pv->start;
+
+      offset = sector - ((grub_uint64_t) seg->start_extent
+                        * (grub_uint64_t) vg->extent_size) + seg_offset;
+    }
+  else
+    {
+      /* This is a striped segment. We have to find the right PV
+        similar to RAID0. */
+      struct grub_lvm_stripe *stripe = seg->stripes;
+      grub_uint32_t a, b;
+      grub_uint64_t seg_offset; /* Offset of the segment in PV device.  */
+      unsigned int stripenr;
+
+      offset = sector - ((grub_uint64_t) seg->start_extent
+                        * (grub_uint64_t) vg->extent_size);
+
+      a = grub_divmod64 (offset, seg->stripe_size, NULL);
+      grub_divmod64 (a, seg->stripe_count, &stripenr);
+
+      a = grub_divmod64 (offset, seg->stripe_size * seg->stripe_count, NULL);
+      grub_divmod64 (offset, seg->stripe_size, &b);
+      offset = a * seg->stripe_size + b;
+
+      stripe += stripenr;
+      pv = stripe->pv;
+
+      seg_offset = ((grub_uint64_t) stripe->start
+                   * (grub_uint64_t) vg->extent_size) + pv->start;
+
+      offset += seg_offset;
+    }
+
+  /* Check whether we actually know the physical volume we want to
+     read from.  */
+  if (pv->disk)
+    err = grub_disk_read (pv->disk, offset, 0,
+                         size << GRUB_DISK_SECTOR_BITS, buf);
+  else
+    err = grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                     "physical volume %s not found", pv->name);
+
+  return err;
+}
+
+static grub_err_t
+grub_lvm_write (grub_disk_t disk __attribute ((unused)),
+                grub_disk_addr_t sector __attribute ((unused)),
+                grub_size_t size __attribute ((unused)),
+                const char *buf __attribute ((unused)))
+{
+  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+static int
+grub_lvm_scan_device (const char *name)
+{
+  grub_err_t err;
+  grub_disk_t disk;
+  grub_uint64_t da_offset, da_size, mda_offset, mda_size;
+  char buf[GRUB_LVM_LABEL_SIZE];
+  char vg_id[GRUB_LVM_ID_STRLEN+1];
+  char pv_id[GRUB_LVM_ID_STRLEN+1];
+  char *metadatabuf, *p, *q, *vgname;
+  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
+  struct grub_lvm_pv_header *pvh;
+  struct grub_lvm_disk_locn *dlocn;
+  struct grub_lvm_mda_header *mdah;
+  struct grub_lvm_raw_locn *rlocn;
+  unsigned int i, j, vgname_len;
+  struct grub_lvm_vg *vg;
+  struct grub_lvm_pv *pv;
+
+  disk = grub_disk_open (name);
+  if (!disk)
+    return 0;
+
+  /* Search for label. */
+  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
+    {
+      err = grub_disk_read (disk, i, 0, sizeof(buf), buf);
+      if (err)
+       goto fail;
+
+      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
+                          sizeof (lh->id)))
+         && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
+                             sizeof (lh->type))))
+       break;
+    }
+
+  /* Return if we didn't find a label. */
+  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
+    goto fail;
+
+  pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
+
+  for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++)
+    {
+      pv_id[j++] = pvh->pv_uuid[i];
+      if ((i != 1) && (i != 29) && (i % 4 == 1))
+       pv_id[j++] = '-';
+    }
+  pv_id[j] = '\0';
+
+  dlocn = pvh->disk_areas_xl;
+  da_offset = grub_le_to_cpu64 (dlocn->offset);
+  da_size = grub_le_to_cpu64 (dlocn->size);
+
+  dlocn++;
+  /* Is it possible to have multiple data/metadata areas? I haven't
+     seen devices that have it. */
+  if (dlocn->offset)
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                 "we don't support multiple LVM data areas");
+
+      goto fail;
+    }
+
+  dlocn++;
+  mda_offset = grub_le_to_cpu64 (dlocn->offset);
+  mda_size = grub_le_to_cpu64 (dlocn->size);
+
+  /* It's possible to have multiple copies of metadata areas, we just use the
+     first one.  */
+
+  /* Allocate buffer space for the circular worst-case scenario. */
+  metadatabuf = grub_malloc (2 * mda_size);
+  if (! metadatabuf)
+    goto fail;
+
+  err = grub_disk_read (disk, 0, mda_offset, mda_size, metadatabuf);
+  if (err)
+    goto fail2;
+
+  mdah = (struct grub_lvm_mda_header *) metadatabuf;
+  if ((grub_strncmp ((char *)mdah->magic, GRUB_LVM_FMTT_MAGIC,
+                    sizeof (mdah->magic)))
+      || (grub_le_to_cpu32 (mdah->version) != GRUB_LVM_FMTT_VERSION))
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                 "unknown LVM metadata header");
+      goto fail2;
+    }
+
+  rlocn = mdah->raw_locns;
+  if (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) >
+      grub_le_to_cpu64 (mdah->size))
+    {
+      /* Metadata is circular. Copy the wrap in place. */
+      grub_memcpy (metadatabuf + mda_size,
+                   metadatabuf + GRUB_LVM_MDA_HEADER_SIZE,
+                   grub_le_to_cpu64 (rlocn->offset) +
+                   grub_le_to_cpu64 (rlocn->size) -
+                   grub_le_to_cpu64 (mdah->size));
+    }
+  p = q = metadatabuf + grub_le_to_cpu64 (rlocn->offset);
+
+  while (*q != ' ' && q < metadatabuf + mda_size)
+    q++;
+
+  if (q == metadatabuf + mda_size)
+    goto fail2;
+
+  vgname_len = q - p;
+  vgname = grub_malloc (vgname_len + 1);
+  if (!vgname)
+    goto fail2;
+
+  grub_memcpy (vgname, p, vgname_len);
+  vgname[vgname_len] = '\0';
+
+  p = grub_strstr (q, "id = \"");
+  if (p == NULL)
+    goto fail3;
+  p += sizeof ("id = \"") - 1;
+  grub_memcpy (vg_id, p, GRUB_LVM_ID_STRLEN);
+  vg_id[GRUB_LVM_ID_STRLEN] = '\0';
+
+  for (vg = vg_list; vg; vg = vg->next)
+    {
+      if (! grub_memcmp(vg_id, vg->id, GRUB_LVM_ID_STRLEN))
+       break;
+    }
+
+  if (! vg)
+    {
+      /* First time we see this volume group. We've to create the
+        whole volume group structure. */
+      vg = grub_malloc (sizeof (*vg));
+      if (! vg)
+       goto fail3;
+      vg->name = vgname;
+      grub_memcpy (vg->id, vg_id, GRUB_LVM_ID_STRLEN+1);
+
+      vg->extent_size = grub_lvm_getvalue (&p, "extent_size = ");
+      if (p == NULL)
+       goto fail4;
+
+      vg->lvs = NULL;
+      vg->pvs = NULL;
+
+      p = grub_strstr (p, "physical_volumes {");
+      if (p)
+       {
+         p += sizeof ("physical_volumes {") - 1;
+
+         /* Add all the pvs to the volume group. */
+         while (1)
+           {
+             int s;
+             while (grub_isspace (*p))
+               p++;
+
+             if (*p == '}')
+               break;
+
+             pv = grub_malloc (sizeof (*pv));
+             q = p;
+             while (*q != ' ')
+               q++;
+
+             s = q - p;
+             pv->name = grub_malloc (s + 1);
+             grub_memcpy (pv->name, p, s);
+             pv->name[s] = '\0';
+
+             p = grub_strstr (p, "id = \"");
+             if (p == NULL)
+               goto pvs_fail;
+             p += sizeof("id = \"") - 1;
+
+             grub_memcpy (pv->id, p, GRUB_LVM_ID_STRLEN);
+             pv->id[GRUB_LVM_ID_STRLEN] = '\0';
+
+             pv->start = grub_lvm_getvalue (&p, "pe_start = ");
+             if (p == NULL)
+               goto pvs_fail;
+
+             p = grub_strchr (p, '}');
+             if (p == NULL)
+               goto pvs_fail;
+             p++;
+
+             pv->disk = NULL;
+             pv->next = vg->pvs;
+             vg->pvs = pv;
+
+             continue;
+           pvs_fail:
+             grub_free (pv->name);
+             grub_free (pv);
+             goto fail4;
+           }
+       }
+
+      p = grub_strstr (p, "logical_volumes");
+      if (p)
+       {
+         p += 18;
+
+         /* And add all the lvs to the volume group. */
+         while (1)
+           {
+             int s;
+             struct grub_lvm_lv *lv;
+             struct grub_lvm_segment *seg;
+
+             while (grub_isspace (*p))
+               p++;
+
+             if (*p == '}')
+               break;
+
+             lv = grub_malloc (sizeof (*lv));
+
+             q = p;
+             while (*q != ' ')
+               q++;
+
+             s = q - p;
+             lv->name = grub_malloc (vgname_len + 1 + s + 1);
+             grub_memcpy (lv->name, vgname, vgname_len);
+             lv->name[vgname_len] = '-';
+             grub_memcpy (lv->name + vgname_len + 1, p, s);
+             lv->name[vgname_len + 1 + s] = '\0';
+
+             lv->size = 0;
+
+             lv->segment_count = grub_lvm_getvalue (&p, "segment_count = ");
+             if (p == NULL)
+               goto lvs_fail;
+             lv->segments = grub_malloc (sizeof (*seg) * lv->segment_count);
+             seg = lv->segments;
+
+             for (i = 0; i < lv->segment_count; i++)
+               {
+                 struct grub_lvm_stripe *stripe;
+
+                 p = grub_strstr (p, "segment");
+                 if (p == NULL)
+                   goto lvs_segment_fail;
+
+                 seg->start_extent = grub_lvm_getvalue (&p, "start_extent = ");
+                 if (p == NULL)
+                   goto lvs_segment_fail;
+                 seg->extent_count = grub_lvm_getvalue (&p, "extent_count = ");
+                 if (p == NULL)
+                   goto lvs_segment_fail;
+                 seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = ");
+                 if (p == NULL)
+                   goto lvs_segment_fail;
+
+                 lv->size += seg->extent_count * vg->extent_size;
+
+                 if (seg->stripe_count != 1)
+                   seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
+
+                 seg->stripes = grub_malloc (sizeof (*stripe)
+                                             * seg->stripe_count);
+                 stripe = seg->stripes;
+
+                 p = grub_strstr (p, "stripes = [");
+                 if (p == NULL)
+                   goto lvs_segment_fail2;
+                 p += sizeof("stripes = [") - 1;
+
+                 for (j = 0; j < seg->stripe_count; j++)
+                   {
+                     char *pvname;
+
+                     p = grub_strchr (p, '"');
+                     if (p == NULL)
+                       continue;
+                     q = ++p;
+                     while (*q != '"')
+                       q++;
+
+                     s = q - p;
+
+                     pvname = grub_malloc (s + 1);
+                      if (pvname == NULL)
+                        goto lvs_segment_fail2;
+
+                     grub_memcpy (pvname, p, s);
+                     pvname[s] = '\0';
+
+                     if (vg->pvs)
+                       for (pv = vg->pvs; pv; pv = pv->next)
+                         {
+                           if (! grub_strcmp (pvname, pv->name))
+                             {
+                               stripe->pv = pv;
+                               break;
+                             }
+                         }
+
+                     grub_free(pvname);
+
+                     stripe->start = grub_lvm_getvalue (&p, ",");
+                     if (p == NULL)
+                       continue;
+
+                     stripe++;
+                   }
+
+                 seg++;
+
+                 continue;
+               lvs_segment_fail2:
+                 grub_free (seg->stripes);
+               lvs_segment_fail:
+                 goto fail4;
+               }
+
+             if (p != NULL)
+               p = grub_strchr (p, '}');
+             if (p == NULL)
+               goto lvs_fail;
+             p += 3;
+
+             lv->number = lv_count++;
+             lv->vg = vg;
+             lv->next = vg->lvs;
+             vg->lvs = lv;
+
+             continue;
+           lvs_fail:
+             grub_free (lv->name);
+             grub_free (lv);
+             goto fail4;
+           }
+       }
+
+       vg->next = vg_list;
+       vg_list = vg;
+    }
+  else
+    {
+      grub_free (vgname);
+    }
+
+  /* Match the device we are currently reading from with the right
+     PV. */
+  if (vg->pvs)
+    for (pv = vg->pvs; pv; pv = pv->next)
+      {
+       if (! grub_memcmp (pv->id, pv_id, GRUB_LVM_ID_STRLEN))
+         {
+           /* This could happen to LVM on RAID, pv->disk points to the
+              raid device, we shouldn't change it.  */
+           if (! pv->disk)
+             pv->disk = grub_disk_open (name);
+           break;
+         }
+      }
+
+  goto fail2;
+
+  /* Failure path.  */
+ fail4:
+  grub_free (vg);
+ fail3:
+  grub_free (vgname);
+
+  /* Normal exit path.  */
+ fail2:
+  grub_free (metadatabuf);
+ fail:
+  grub_disk_close (disk);
+  return 0;
+}
+
+static struct grub_disk_dev grub_lvm_dev =
+  {
+    .name = "lvm",
+    .id = GRUB_DISK_DEVICE_LVM_ID,
+    .iterate = grub_lvm_iterate,
+    .open = grub_lvm_open,
+    .close = grub_lvm_close,
+    .read = grub_lvm_read,
+    .write = grub_lvm_write,
+#ifdef GRUB_UTIL
+    .memberlist = grub_lvm_memberlist,
+#endif
+    .next = 0
+  };
+
+\f
+GRUB_MOD_INIT(lvm)
+{
+  grub_device_iterate (&grub_lvm_scan_device);
+  if (grub_errno)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+    }
+
+  grub_disk_dev_register (&grub_lvm_dev);
+}
+
+GRUB_MOD_FINI(lvm)
+{
+  grub_disk_dev_unregister (&grub_lvm_dev);
+  /* FIXME: free the lvm list. */
+}
diff --git a/grub-core/disk/mdraid_linux.c b/grub-core/disk/mdraid_linux.c
new file mode 100644 (file)
index 0000000..306c66a
--- /dev/null
@@ -0,0 +1,233 @@
+/* mdraid_linux.c - module to handle linux softraid.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/raid.h>
+
+/* Linux RAID on disk structures and constants,
+   copied from include/linux/raid/md_p.h.  */
+
+#define RESERVED_BYTES                 (64 * 1024)
+#define RESERVED_SECTORS               (RESERVED_BYTES / 512)
+
+#define NEW_SIZE_SECTORS(x)            ((x & ~(RESERVED_SECTORS - 1)) \
+                                       - RESERVED_SECTORS)
+
+#define SB_BYTES                       4096
+#define SB_WORDS                       (SB_BYTES / 4)
+#define SB_SECTORS                     (SB_BYTES / 512)
+
+/*
+ * The following are counted in 32-bit words
+ */
+#define        SB_GENERIC_OFFSET               0
+
+#define SB_PERSONALITY_OFFSET          64
+#define SB_DISKS_OFFSET                        128
+#define SB_DESCRIPTOR_OFFSET           992
+
+#define SB_GENERIC_CONSTANT_WORDS      32
+#define SB_GENERIC_STATE_WORDS         32
+#define SB_GENERIC_WORDS               (SB_GENERIC_CONSTANT_WORDS + \
+                                         SB_GENERIC_STATE_WORDS)
+
+#define SB_PERSONALITY_WORDS           64
+#define SB_DESCRIPTOR_WORDS            32
+#define SB_DISKS                       27
+#define SB_DISKS_WORDS                 (SB_DISKS * SB_DESCRIPTOR_WORDS)
+
+#define SB_RESERVED_WORDS              (1024 \
+                                         - SB_GENERIC_WORDS \
+                                         - SB_PERSONALITY_WORDS \
+                                         - SB_DISKS_WORDS \
+                                         - SB_DESCRIPTOR_WORDS)
+
+#define SB_EQUAL_WORDS                 (SB_GENERIC_WORDS \
+                                         + SB_PERSONALITY_WORDS \
+                                         + SB_DISKS_WORDS)
+
+/*
+ * Device "operational" state bits
+ */
+#define DISK_FAULTY                    0
+#define DISK_ACTIVE                    1
+#define DISK_SYNC                      2
+#define DISK_REMOVED                   3
+
+#define        DISK_WRITEMOSTLY                9
+
+#define SB_MAGIC                       0xa92b4efc
+
+/*
+ * Superblock state bits
+ */
+#define SB_CLEAN                       0
+#define SB_ERRORS                      1
+
+#define        SB_BITMAP_PRESENT               8
+
+struct grub_raid_disk_09
+{
+  grub_uint32_t number;                /* Device number in the entire set.  */
+  grub_uint32_t major;         /* Device major number.  */
+  grub_uint32_t minor;         /* Device minor number.  */
+  grub_uint32_t raid_disk;     /* The role of the device in the raid set.  */
+  grub_uint32_t state;         /* Operational state.  */
+  grub_uint32_t reserved[SB_DESCRIPTOR_WORDS - 5];
+};
+
+struct grub_raid_super_09
+{
+  /*
+   * Constant generic information
+   */
+  grub_uint32_t md_magic;      /* MD identifier.  */
+  grub_uint32_t major_version; /* Major version.  */
+  grub_uint32_t minor_version; /* Minor version.  */
+  grub_uint32_t patch_version; /* Patchlevel version.  */
+  grub_uint32_t gvalid_words;  /* Number of used words in this section.  */
+  grub_uint32_t set_uuid0;     /* Raid set identifier.  */
+  grub_uint32_t ctime;         /* Creation time.  */
+  grub_uint32_t level;         /* Raid personality.  */
+  grub_uint32_t size;          /* Apparent size of each individual disk.  */
+  grub_uint32_t nr_disks;      /* Total disks in the raid set.  */
+  grub_uint32_t raid_disks;    /* Disks in a fully functional raid set.  */
+  grub_uint32_t md_minor;      /* Preferred MD minor device number.  */
+  grub_uint32_t not_persistent;        /* Does it have a persistent superblock.  */
+  grub_uint32_t set_uuid1;     /* Raid set identifier #2.  */
+  grub_uint32_t set_uuid2;     /* Raid set identifier #3.  */
+  grub_uint32_t set_uuid3;     /* Raid set identifier #4.  */
+  grub_uint32_t gstate_creserved[SB_GENERIC_CONSTANT_WORDS - 16];
+
+  /*
+   * Generic state information
+   */
+  grub_uint32_t utime;         /* Superblock update time.  */
+  grub_uint32_t state;         /* State bits (clean, ...).  */
+  grub_uint32_t active_disks;  /* Number of currently active disks.  */
+  grub_uint32_t working_disks; /* Number of working disks.  */
+  grub_uint32_t failed_disks;  /* Number of failed disks.  */
+  grub_uint32_t spare_disks;   /* Number of spare disks.  */
+  grub_uint32_t sb_csum;       /* Checksum of the whole superblock.  */
+  grub_uint64_t events;                /* Superblock update count.  */
+  grub_uint64_t cp_events;     /* Checkpoint update count.  */
+  grub_uint32_t recovery_cp;   /* Recovery checkpoint sector count.  */
+  grub_uint32_t gstate_sreserved[SB_GENERIC_STATE_WORDS - 12];
+
+  /*
+   * Personality information
+   */
+  grub_uint32_t layout;                /* The array's physical layout.  */
+  grub_uint32_t chunk_size;    /* Chunk size in bytes.  */
+  grub_uint32_t root_pv;       /* LV root PV.  */
+  grub_uint32_t root_block;    /* LV root block.  */
+  grub_uint32_t pstate_reserved[SB_PERSONALITY_WORDS - 4];
+
+  /*
+   * Disks information
+   */
+  struct grub_raid_disk_09 disks[SB_DISKS];
+
+  /*
+   * Reserved
+   */
+  grub_uint32_t reserved[SB_RESERVED_WORDS];
+
+  /*
+   * Active descriptor
+   */
+  struct grub_raid_disk_09 this_disk;
+} __attribute__ ((packed));
+
+static grub_err_t
+grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array)
+{
+  grub_disk_addr_t sector;
+  grub_uint64_t size;
+  struct grub_raid_super_09 sb;
+  grub_uint32_t *uuid;
+
+  /* The sector where the RAID superblock is stored, if available. */
+  size = grub_disk_get_size (disk);
+  sector = NEW_SIZE_SECTORS (size);
+
+  if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb))
+    return grub_errno;
+
+  /* Look whether there is a RAID superblock. */
+  if (sb.md_magic != SB_MAGIC)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid");
+
+  /* FIXME: Also support version 1.0. */
+  if (sb.major_version != 0 || sb.minor_version != 90)
+    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                      "unsupported RAID version: %d.%d",
+                      sb.major_version, sb.minor_version);
+
+  /* FIXME: Check the checksum. */
+
+  /* Multipath.  */
+  if ((int) sb.level == -4)
+    sb.level = 1;
+
+  if (sb.level != 0 && sb.level != 1 && sb.level != 4 &&
+      sb.level != 5 && sb.level != 6 && sb.level != 10)
+    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                      "unsupported RAID level: %d", sb.level);
+
+  array->number = sb.md_minor;
+  array->level = sb.level;
+  array->layout = sb.layout;
+  array->total_devs = sb.raid_disks;
+  array->disk_size = (sb.size) ? sb.size * 2 : sector;
+  array->chunk_size = sb.chunk_size >> 9;
+  array->index = sb.this_disk.number;
+  array->uuid_len = 16;
+  array->uuid = grub_malloc (16);
+  if (!array->uuid)
+    return grub_errno;
+
+  uuid = (grub_uint32_t *) array->uuid;
+  uuid[0] = sb.set_uuid0;
+  uuid[1] = sb.set_uuid1;
+  uuid[2] = sb.set_uuid2;
+  uuid[3] = sb.set_uuid3;
+
+  return 0;
+}
+
+static struct grub_raid grub_mdraid_dev = {
+  .name = "mdraid",
+  .detect = grub_mdraid_detect,
+  .next = 0
+};
+
+GRUB_MOD_INIT (mdraid)
+{
+  grub_raid_register (&grub_mdraid_dev);
+}
+
+GRUB_MOD_FINI (mdraid)
+{
+  grub_raid_unregister (&grub_mdraid_dev);
+}
diff --git a/grub-core/disk/memdisk.c b/grub-core/disk/memdisk.c
new file mode 100644 (file)
index 0000000..2e88850
--- /dev/null
@@ -0,0 +1,116 @@
+/* memdisk.c - Access embedded memory disk.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+
+static char *memdisk_addr;
+static grub_off_t memdisk_size = 0;
+
+static int
+grub_memdisk_iterate (int (*hook) (const char *name))
+{
+  return hook ("memdisk");
+}
+
+static grub_err_t
+grub_memdisk_open (const char *name, grub_disk_t disk)
+{
+  if (grub_strcmp (name, "memdisk"))
+      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a memdisk");
+
+  disk->total_sectors = memdisk_size / GRUB_DISK_SECTOR_SIZE;
+  disk->id = (unsigned long) "mdsk";
+  disk->has_partitions = 0;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_memdisk_close (grub_disk_t disk __attribute((unused)))
+{
+}
+
+static grub_err_t
+grub_memdisk_read (grub_disk_t disk __attribute((unused)), grub_disk_addr_t sector,
+                   grub_size_t size, char *buf)
+{
+  grub_memcpy (buf, memdisk_addr + (sector << GRUB_DISK_SECTOR_BITS), size << GRUB_DISK_SECTOR_BITS);
+  return 0;
+}
+
+static grub_err_t
+grub_memdisk_write (grub_disk_t disk __attribute((unused)), grub_disk_addr_t sector,
+                    grub_size_t size, const char *buf)
+{
+  grub_memcpy (memdisk_addr + (sector << GRUB_DISK_SECTOR_BITS), buf, size << GRUB_DISK_SECTOR_BITS);
+  return 0;
+}
+
+static struct grub_disk_dev grub_memdisk_dev =
+  {
+    .name = "memdisk",
+    .id = GRUB_DISK_DEVICE_MEMDISK_ID,
+    .iterate = grub_memdisk_iterate,
+    .open = grub_memdisk_open,
+    .close = grub_memdisk_close,
+    .read = grub_memdisk_read,
+    .write = grub_memdisk_write,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(memdisk)
+{
+  auto int hook (struct grub_module_header *);
+  int hook (struct grub_module_header *header)
+    {
+      if (header->type == OBJ_TYPE_MEMDISK)
+       {
+         char *memdisk_orig_addr;
+         memdisk_orig_addr = (char *) header + sizeof (struct grub_module_header);
+
+         grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr);
+
+         memdisk_size = header->size - sizeof (struct grub_module_header);
+         memdisk_addr = grub_malloc (memdisk_size);
+
+         grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n");
+         grub_memmove (memdisk_addr, memdisk_orig_addr, memdisk_size);
+
+         grub_disk_dev_register (&grub_memdisk_dev);
+         return 1;
+       }
+
+      return 0;
+    }
+
+  grub_module_iterate (hook);
+}
+
+GRUB_MOD_FINI(memdisk)
+{
+  if (! memdisk_size)
+    return;
+  grub_free (memdisk_addr);
+  grub_disk_dev_unregister (&grub_memdisk_dev);
+}
diff --git a/grub-core/disk/raid.c b/grub-core/disk/raid.c
new file mode 100644 (file)
index 0000000..2d544af
--- /dev/null
@@ -0,0 +1,691 @@
+/* raid.c - module to read RAID arrays.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/raid.h>
+
+/* Linked list of RAID arrays. */
+static struct grub_raid_array *array_list;
+grub_raid5_recover_func_t grub_raid5_recover_func;
+grub_raid6_recover_func_t grub_raid6_recover_func;
+
+\f
+static char
+grub_is_array_readable (struct grub_raid_array *array)
+{
+  switch (array->level)
+    {
+    case 0:
+      if (array->nr_devs == array->total_devs)
+       return 1;
+      break;
+
+    case 1:
+      if (array->nr_devs >= 1)
+       return 1;
+      break;
+
+    case 4:
+    case 5:
+    case 6:
+    case 10:
+      {
+        unsigned int n;
+
+        if (array->level == 10)
+          {
+            n = array->layout & 0xFF;
+            if (n == 1)
+              n = (array->layout >> 8) & 0xFF;
+
+            n--;
+          }
+        else
+          n = array->level / 3;
+
+        if (array->nr_devs >= array->total_devs - n)
+          return 1;
+
+        break;
+      }
+    }
+
+  return 0;
+}
+
+static int
+grub_raid_iterate (int (*hook) (const char *name))
+{
+  struct grub_raid_array *array;
+
+  for (array = array_list; array != NULL; array = array->next)
+    {
+      if (grub_is_array_readable (array))
+       if (hook (array->name))
+         return 1;
+    }
+
+  return 0;
+}
+
+#ifdef GRUB_UTIL
+static grub_disk_memberlist_t
+grub_raid_memberlist (grub_disk_t disk)
+{
+  struct grub_raid_array *array = disk->data;
+  grub_disk_memberlist_t list = NULL, tmp;
+  unsigned int i;
+
+  for (i = 0; i < array->total_devs; i++)
+    if (array->device[i])
+      {
+        tmp = grub_malloc (sizeof (*tmp));
+        tmp->disk = array->device[i];
+        tmp->next = list;
+        list = tmp;
+      }
+
+  return list;
+}
+#endif
+
+static grub_err_t
+grub_raid_open (const char *name, grub_disk_t disk)
+{
+  struct grub_raid_array *array;
+  unsigned n;
+
+  for (array = array_list; array != NULL; array = array->next)
+    {
+      if (!grub_strcmp (array->name, name))
+       if (grub_is_array_readable (array))
+         break;
+    }
+
+  if (!array)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown RAID device %s",
+                       name);
+
+  disk->has_partitions = 1;
+  disk->id = array->number;
+  disk->data = array;
+
+  grub_dprintf ("raid", "%s: total_devs=%d, disk_size=%lld\n", name,
+               array->total_devs, (unsigned long long) array->disk_size);
+
+  switch (array->level)
+    {
+    case 1:
+      disk->total_sectors = array->disk_size;
+      break;
+
+    case 10:
+      n = array->layout & 0xFF;
+      if (n == 1)
+        n = (array->layout >> 8) & 0xFF;
+
+      disk->total_sectors = grub_divmod64 (array->total_devs *
+                                           array->disk_size,
+                                           n, 0);
+      break;
+
+    case 0:
+    case 4:
+    case 5:
+    case 6:
+      n = array->level / 3;
+
+      disk->total_sectors = (array->total_devs - n) * array->disk_size;
+      break;
+    }
+
+  grub_dprintf ("raid", "%s: level=%d, total_sectors=%lld\n", name,
+               array->level, (unsigned long long) disk->total_sectors);
+
+  return 0;
+}
+
+static void
+grub_raid_close (grub_disk_t disk __attribute ((unused)))
+{
+  return;
+}
+
+void
+grub_raid_block_xor (char *buf1, const char *buf2, int size)
+{
+  grub_size_t *p1;
+  const grub_size_t *p2;
+
+  p1 = (grub_size_t *) buf1;
+  p2 = (const grub_size_t *) buf2;
+  size /= GRUB_CPU_SIZEOF_VOID_P;
+
+  while (size)
+    {
+      *(p1++) ^= *(p2++);
+      size--;
+    }
+}
+
+static grub_err_t
+grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector,
+               grub_size_t size, char *buf)
+{
+  struct grub_raid_array *array = disk->data;
+  grub_err_t err = 0;
+
+  switch (array->level)
+    {
+    case 0:
+    case 1:
+    case 10:
+      {
+        grub_disk_addr_t read_sector, far_ofs;
+       grub_uint32_t disknr, b, near, far, ofs;
+
+        read_sector = grub_divmod64 (sector, array->chunk_size, &b);
+        far = ofs = near = 1;
+        far_ofs = 0;
+
+        if (array->level == 1)
+          near = array->total_devs;
+        else if (array->level == 10)
+          {
+            near = array->layout & 0xFF;
+            far = (array->layout >> 8) & 0xFF;
+            if (array->layout >> 16)
+              {
+                ofs = far;
+                far_ofs = 1;
+              }
+            else
+              far_ofs = grub_divmod64 (array->disk_size,
+                                       far * array->chunk_size, 0);
+
+            far_ofs *= array->chunk_size;
+          }
+
+        read_sector = grub_divmod64 (read_sector * near, array->total_devs,
+                                     &disknr);
+
+        ofs *= array->chunk_size;
+        read_sector *= ofs;
+
+        while (1)
+          {
+            grub_size_t read_size;
+            unsigned int i, j;
+
+            read_size = array->chunk_size - b;
+            if (read_size > size)
+              read_size = size;
+
+            for (i = 0; i < near; i++)
+              {
+                unsigned int k;
+
+                k = disknr;
+                for (j = 0; j < far; j++)
+                  {
+                    if (array->device[k])
+                      {
+                        if (grub_errno == GRUB_ERR_READ_ERROR)
+                          grub_errno = GRUB_ERR_NONE;
+
+                        err = grub_disk_read (array->device[k],
+                                              read_sector + j * far_ofs + b,
+                                              0,
+                                              read_size << GRUB_DISK_SECTOR_BITS,
+                                              buf);
+                        if (! err)
+                          break;
+                        else if (err != GRUB_ERR_READ_ERROR)
+                          return err;
+                      }
+                    else
+                      err = grub_error (GRUB_ERR_READ_ERROR,
+                                        "disk missing");
+
+                    k++;
+                    if (k == array->total_devs)
+                      k = 0;
+                  }
+
+                if (! err)
+                  break;
+
+                disknr++;
+                if (disknr == array->total_devs)
+                  {
+                    disknr = 0;
+                    read_sector += ofs;
+                  }
+              }
+
+            if (err)
+              return err;
+
+            buf += read_size << GRUB_DISK_SECTOR_BITS;
+           size -= read_size;
+           if (! size)
+             break;
+
+            b = 0;
+            disknr += (near - i);
+            while (disknr >= array->total_devs)
+              {
+                disknr -= array->total_devs;
+                read_sector += ofs;
+              }
+          }
+        break;
+      }
+
+    case 4:
+    case 5:
+    case 6:
+      {
+       grub_disk_addr_t read_sector;
+       grub_uint32_t b, p, n, disknr, e;
+
+        /* n = 1 for level 4 and 5, 2 for level 6.  */
+        n = array->level / 3;
+
+       /* Find the first sector to read. */
+       read_sector = grub_divmod64 (sector, array->chunk_size, &b);
+       read_sector = grub_divmod64 (read_sector, array->total_devs - n,
+                                     &disknr);
+        if (array->level >= 5)
+          {
+            grub_divmod64 (read_sector, array->total_devs, &p);
+
+            if (! (array->layout & GRUB_RAID_LAYOUT_RIGHT_MASK))
+              p = array->total_devs - 1 - p;
+
+            if (array->layout & GRUB_RAID_LAYOUT_SYMMETRIC_MASK)
+              {
+                disknr += p + n;
+              }
+            else
+              {
+                grub_uint32_t q;
+
+                q = p + (n - 1);
+                if (q >= array->total_devs)
+                  q -= array->total_devs;
+
+                if (disknr >= p)
+                  disknr += n;
+                else if (disknr >= q)
+                  disknr += q + 1;
+              }
+
+            if (disknr >= array->total_devs)
+              disknr -= array->total_devs;
+          }
+        else
+          p = array->total_devs - n;
+
+       read_sector *= array->chunk_size;
+
+       while (1)
+         {
+            grub_size_t read_size;
+            int next_level;
+
+            read_size = array->chunk_size - b;
+            if (read_size > size)
+              read_size = size;
+
+            e = 0;
+            if (array->device[disknr])
+              {
+                /* Reset read error.  */
+                if (grub_errno == GRUB_ERR_READ_ERROR)
+                  grub_errno = GRUB_ERR_NONE;
+
+                err = grub_disk_read (array->device[disknr],
+                                      read_sector + b, 0,
+                                      read_size << GRUB_DISK_SECTOR_BITS,
+                                      buf);
+
+                if ((err) && (err != GRUB_ERR_READ_ERROR))
+                  break;
+                e++;
+              }
+            else
+              err = GRUB_ERR_READ_ERROR;
+
+           if (err)
+              {
+                if (array->nr_devs < array->total_devs - n + e)
+                  break;
+
+                grub_errno = GRUB_ERR_NONE;
+                if (array->level == 6)
+                  {
+                    err = ((grub_raid6_recover_func) ?
+                           (*grub_raid6_recover_func) (array, disknr, p,
+                                                       buf, read_sector + b,
+                                                       read_size) :
+                           grub_error (GRUB_ERR_BAD_DEVICE,
+                                       "raid6rec is not loaded"));
+                  }
+                else
+                  {
+                    err = ((grub_raid5_recover_func) ?
+                           (*grub_raid5_recover_func) (array, disknr,
+                                                       buf, read_sector + b,
+                                                       read_size) :
+                           grub_error (GRUB_ERR_BAD_DEVICE,
+                                       "raid5rec is not loaded"));
+                  }
+
+                if (err)
+                  break;
+              }
+
+           buf += read_size << GRUB_DISK_SECTOR_BITS;
+           size -= read_size;
+           if (! size)
+             break;
+
+            b = 0;
+           disknr++;
+
+            if (array->layout & GRUB_RAID_LAYOUT_SYMMETRIC_MASK)
+              {
+                if (disknr == array->total_devs)
+                  disknr = 0;
+
+                next_level = (disknr == p);
+              }
+            else
+              {
+                if (disknr == p)
+                  disknr += n;
+
+                next_level = (disknr >= array->total_devs);
+              }
+
+            if (next_level)
+              {
+                read_sector += array->chunk_size;
+
+                if (array->level >= 5)
+                  {
+                    if (array->layout & GRUB_RAID_LAYOUT_RIGHT_MASK)
+                      p = (p == array->total_devs - 1) ? 0 : p + 1;
+                    else
+                      p = (p == 0) ? array->total_devs - 1 : p - 1;
+
+                    if (array->layout & GRUB_RAID_LAYOUT_SYMMETRIC_MASK)
+                      {
+                        disknr = p + n;
+                        if (disknr >= array->total_devs)
+                          disknr -= array->total_devs;
+                      }
+                    else
+                      {
+                        disknr -= array->total_devs;
+                        if (disknr == p)
+                          disknr += n;
+                      }
+                  }
+                else
+                  disknr = 0;
+              }
+         }
+      }
+      break;
+    }
+
+  return err;
+}
+
+static grub_err_t
+grub_raid_write (grub_disk_t disk __attribute ((unused)),
+                grub_disk_addr_t sector __attribute ((unused)),
+                grub_size_t size __attribute ((unused)),
+                const char *buf __attribute ((unused)))
+{
+  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+static grub_err_t
+insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
+              const char *scanner_name)
+{
+  struct grub_raid_array *array = 0, *p;
+
+  /* See whether the device is part of an array we have already seen a
+     device from. */
+  for (p = array_list; p != NULL; p = p->next)
+    if ((p->uuid_len == new_array->uuid_len) &&
+        (! grub_memcmp (p->uuid, new_array->uuid, p->uuid_len)))
+      {
+        grub_free (new_array->uuid);
+        array = p;
+
+        /* Do some checks before adding the device to the array.  */
+
+        /* FIXME: Check whether the update time of the superblocks are
+           the same. */
+
+        if (array->total_devs == array->nr_devs)
+          /* We found more members of the array than the array
+             actually has according to its superblock.  This shouldn't
+             happen normally.  */
+          grub_dprintf ("raid", "array->nr_devs > array->total_devs (%d)?!?",
+                       array->total_devs);
+
+        if (array->device[new_array->index] != NULL)
+          /* We found multiple devices with the same number. Again,
+             this shouldn't happen.*/
+          grub_dprintf ("raid", "Found two disks with the number %d?!?",
+                       new_array->number);
+
+        if (new_array->disk_size < array->disk_size)
+          array->disk_size = new_array->disk_size;
+        break;
+      }
+
+  /* Add an array to the list if we didn't find any.  */
+  if (!array)
+    {
+      array = grub_malloc (sizeof (*array));
+      if (!array)
+        {
+          grub_free (new_array->uuid);
+          return grub_errno;
+        }
+
+      *array = *new_array;
+      array->nr_devs = 0;
+      grub_memset (&array->device, 0, sizeof (array->device));
+
+      /* Check whether we don't have multiple arrays with the same number. */
+      for (p = array_list; p != NULL; p = p->next)
+        {
+          if (p->number == array->number)
+            break;
+        }
+
+      if (p)
+        {
+          /* The number is already in use, so we need to find an new number. */
+          int i = 0;
+
+          while (1)
+            {
+              for (p = array_list; p != NULL; p = p->next)
+                {
+                  if (p->number == i)
+                    break;
+                }
+
+              if (!p)
+                {
+                  /* We found an unused number.  */
+                  array->number = i;
+                  break;
+                }
+
+              i++;
+            }
+        }
+
+      array->name = grub_xasprintf ("md%d", array->number);
+      if (! array->name)
+        {
+          grub_free (array->uuid);
+          grub_free (array);
+
+          return grub_errno;
+        }
+
+      grub_dprintf ("raid", "Found array %s (%s)\n", array->name,
+                    scanner_name);
+
+      /* Add our new array to the list.  */
+      array->next = array_list;
+      array_list = array;
+
+      /* RAID 1 doesn't use a chunksize but code assumes one so set
+        one. */
+      if (array->level == 1)
+       array->chunk_size = 64;
+    }
+
+  /* Add the device to the array. */
+  array->device[new_array->index] = disk;
+  array->nr_devs++;
+
+  return 0;
+}
+
+static grub_raid_t grub_raid_list;
+
+static void
+free_array (void)
+{
+  struct grub_raid_array *array;
+
+  array = array_list;
+  while (array)
+    {
+      struct grub_raid_array *p;
+      int i;
+
+      p = array;
+      array = array->next;
+
+      for (i = 0; i < GRUB_RAID_MAX_DEVICES; i++)
+        if (p->device[i])
+          grub_disk_close (p->device[i]);
+
+      grub_free (p->uuid);
+      grub_free (p->name);
+      grub_free (p);
+    }
+
+  array_list = 0;
+}
+
+void
+grub_raid_register (grub_raid_t raid)
+{
+  auto int hook (const char *name);
+  int hook (const char *name)
+    {
+      grub_disk_t disk;
+      struct grub_raid_array array;
+
+      grub_dprintf ("raid", "Scanning for RAID devices on disk %s\n", name);
+
+      disk = grub_disk_open (name);
+      if (!disk)
+        return 0;
+
+      if ((disk->total_sectors != GRUB_ULONG_MAX) &&
+         (! grub_raid_list->detect (disk, &array)) &&
+         (! insert_array (disk, &array, grub_raid_list->name)))
+       return 0;
+
+      /* This error usually means it's not raid, no need to display
+        it.  */
+      if (grub_errno != GRUB_ERR_OUT_OF_RANGE)
+       grub_print_error ();
+
+      grub_errno = GRUB_ERR_NONE;
+
+      grub_disk_close (disk);
+
+      return 0;
+    }
+
+  raid->next = grub_raid_list;
+  grub_raid_list = raid;
+  grub_device_iterate (&hook);
+}
+
+void
+grub_raid_unregister (grub_raid_t raid)
+{
+  grub_raid_t *p, q;
+
+  for (p = &grub_raid_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == raid)
+      {
+       *p = q->next;
+       break;
+      }
+}
+
+static struct grub_disk_dev grub_raid_dev =
+  {
+    .name = "raid",
+    .id = GRUB_DISK_DEVICE_RAID_ID,
+    .iterate = grub_raid_iterate,
+    .open = grub_raid_open,
+    .close = grub_raid_close,
+    .read = grub_raid_read,
+    .write = grub_raid_write,
+#ifdef GRUB_UTIL
+    .memberlist = grub_raid_memberlist,
+#endif
+    .next = 0
+  };
+
+\f
+GRUB_MOD_INIT(raid)
+{
+  grub_disk_dev_register (&grub_raid_dev);
+}
+
+GRUB_MOD_FINI(raid)
+{
+  grub_disk_dev_unregister (&grub_raid_dev);
+  free_array ();
+}
diff --git a/grub-core/disk/raid5_recover.c b/grub-core/disk/raid5_recover.c
new file mode 100644 (file)
index 0000000..31cef88
--- /dev/null
@@ -0,0 +1,72 @@
+/* raid5_recover.c - module to recover from faulty RAID4/5 arrays.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/raid.h>
+
+static grub_err_t
+grub_raid5_recover (struct grub_raid_array *array, int disknr,
+                    char *buf, grub_disk_addr_t sector, int size)
+{
+  char *buf2;
+  int i;
+
+  size <<= GRUB_DISK_SECTOR_BITS;
+  buf2 = grub_malloc (size);
+  if (!buf2)
+    return grub_errno;
+
+  grub_memset (buf, 0, size);
+
+  for (i = 0; i < (int) array->total_devs; i++)
+    {
+      grub_err_t err;
+
+      if (i == disknr)
+        continue;
+
+      err = grub_disk_read (array->device[i], sector, 0, size, buf2);
+
+      if (err)
+        {
+          grub_free (buf2);
+          return err;
+        }
+
+      grub_raid_block_xor (buf, buf2, size);
+    }
+
+  grub_free (buf2);
+
+  return GRUB_ERR_NONE;
+}
+
+GRUB_MOD_INIT(raid5rec)
+{
+  grub_raid5_recover_func = grub_raid5_recover;
+}
+
+GRUB_MOD_FINI(raid5rec)
+{
+  grub_raid5_recover_func = 0;
+}
diff --git a/grub-core/disk/raid6_recover.c b/grub-core/disk/raid6_recover.c
new file mode 100644 (file)
index 0000000..550968c
--- /dev/null
@@ -0,0 +1,219 @@
+/* raid6_recover.c - module to recover from faulty RAID6 arrays.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/raid.h>
+
+static grub_uint8_t raid6_table1[256][256];
+static grub_uint8_t raid6_table2[256][256];
+
+static void
+grub_raid_block_mul (grub_uint8_t mul, char *buf, int size)
+{
+  int i;
+  grub_uint8_t *p;
+
+  p = (grub_uint8_t *) buf;
+  for (i = 0; i < size; i++, p++)
+    *p = raid6_table1[mul][*p];
+}
+
+static void
+grub_raid6_init_table (void)
+{
+  int i, j;
+
+  for (i = 0; i < 256; i++)
+    raid6_table1[i][1] = raid6_table1[1][i] = i;
+
+  for (i = 2; i < 256; i++)
+    for (j = i; j < 256; j++)
+      {
+        int n;
+        grub_uint8_t c;
+
+        n = i >> 1;
+
+        c = raid6_table1[n][j];
+        c = (c << 1) ^ ((c & 0x80) ? 0x1d : 0);
+        if (i & 1)
+          c ^= j;
+
+        raid6_table1[j][i] = raid6_table1[i][j] = c;
+      }
+
+  raid6_table2[0][0] = 1;
+  for (i = 1; i < 256; i++)
+    raid6_table2[i][i] = raid6_table1[raid6_table2[i - 1][i - 1]][2];
+
+  for (i = 0; i < 254; i++)
+    for (j = 0; j < 254; j++)
+      {
+        grub_uint8_t c, n;
+        int k;
+
+        if (i == j)
+          continue;
+
+        k = i - j;
+        if (k < 0)
+          k += 255;
+
+        c = n = raid6_table2[k][k] ^ 1;
+        for (k = 0; k < 253; k++)
+          c = raid6_table1[c][n];
+
+        raid6_table2[i][j] = raid6_table1[raid6_table2[255 - j][255 - j]][c];
+      }
+}
+
+static grub_err_t
+grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
+                    char *buf, grub_disk_addr_t sector, int size)
+{
+  int i, q, pos;
+  int bad1 = -1, bad2 = -1;
+  char *pbuf = 0, *qbuf = 0;
+
+  size <<= GRUB_DISK_SECTOR_BITS;
+  pbuf = grub_zalloc (size);
+  if (!pbuf)
+    goto quit;
+
+  qbuf = grub_zalloc (size);
+  if (!qbuf)
+    goto quit;
+
+  q = p + 1;
+  if (q == (int) array->total_devs)
+    q = 0;
+
+  pos = q + 1;
+  if (pos == (int) array->total_devs)
+    pos = 0;
+
+  for (i = 0; i < (int) array->total_devs - 2; i++)
+    {
+      if (pos == disknr)
+        bad1 = i;
+      else
+        {
+          if ((array->device[pos]) &&
+              (! grub_disk_read (array->device[pos], sector, 0, size, buf)))
+            {
+              grub_raid_block_xor (pbuf, buf, size);
+              grub_raid_block_mul (raid6_table2[i][i], buf, size);
+              grub_raid_block_xor (qbuf, buf, size);
+            }
+          else
+            {
+              /* Too many bad devices */
+              if (bad2 >= 0)
+                goto quit;
+
+              bad2 = i;
+              grub_errno = GRUB_ERR_NONE;
+            }
+        }
+
+      pos++;
+      if (pos == (int) array->total_devs)
+        pos = 0;
+    }
+
+  /* Invalid disknr or p */
+  if (bad1 < 0)
+    goto quit;
+
+  if (bad2 < 0)
+    {
+      /* One bad device */
+      if ((array->device[p]) &&
+          (! grub_disk_read (array->device[p], sector, 0, size, buf)))
+        {
+          grub_raid_block_xor (buf, pbuf, size);
+          goto quit;
+        }
+
+      if (! array->device[q])
+        {
+          grub_error (GRUB_ERR_READ_ERROR, "not enough disk to restore");
+          goto quit;
+        }
+
+      grub_errno = GRUB_ERR_NONE;
+      if (grub_disk_read (array->device[q], sector, 0, size, buf))
+        goto quit;
+
+      grub_raid_block_xor (buf, qbuf, size);
+      grub_raid_block_mul (raid6_table2[255 - bad1][255 - bad1], buf,
+                           size);
+    }
+  else
+    {
+      /* Two bad devices */
+      grub_uint8_t c;
+
+      if ((! array->device[p]) || (! array->device[q]))
+        {
+          grub_error (GRUB_ERR_READ_ERROR, "not enough disk to restore");
+          goto quit;
+        }
+
+      if (grub_disk_read (array->device[p], sector, 0, size, buf))
+        goto quit;
+
+      grub_raid_block_xor (pbuf, buf, size);
+
+      if (grub_disk_read (array->device[q], sector, 0, size, buf))
+        goto quit;
+
+      grub_raid_block_xor (qbuf, buf, size);
+
+      c = raid6_table2[bad2][bad1];
+      grub_raid_block_mul (c, qbuf, size);
+
+      c = raid6_table1[raid6_table2[bad2][bad2]][c];
+      grub_raid_block_mul (c, pbuf, size);
+
+      grub_raid_block_xor (pbuf, qbuf, size);
+      grub_memcpy (buf, pbuf, size);
+    }
+
+quit:
+  grub_free (pbuf);
+  grub_free (qbuf);
+
+  return grub_errno;
+}
+
+GRUB_MOD_INIT(raid6rec)
+{
+  grub_raid6_init_table ();
+  grub_raid6_recover_func = grub_raid6_recover;
+}
+
+GRUB_MOD_FINI(raid6rec)
+{
+  grub_raid6_recover_func = 0;
+}
diff --git a/grub-core/disk/scsi.c b/grub-core/disk/scsi.c
new file mode 100644 (file)
index 0000000..eba2372
--- /dev/null
@@ -0,0 +1,407 @@
+/* scsi.c - scsi support.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/scsi.h>
+#include <grub/scsicmd.h>
+
+\f
+static grub_scsi_dev_t grub_scsi_dev_list;
+
+void
+grub_scsi_dev_register (grub_scsi_dev_t dev)
+{
+  dev->next = grub_scsi_dev_list;
+  grub_scsi_dev_list = dev;
+}
+
+void
+grub_scsi_dev_unregister (grub_scsi_dev_t dev)
+{
+  grub_scsi_dev_t *p, q;
+
+  for (p = &grub_scsi_dev_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == dev)
+      {
+        *p = q->next;
+       break;
+      }
+}
+
+\f
+/* Determine the the device is removable and the type of the device
+   SCSI.  */
+static grub_err_t
+grub_scsi_inquiry (grub_scsi_t scsi)
+{
+  struct grub_scsi_inquiry iq;
+  struct grub_scsi_inquiry_data iqd;
+  grub_err_t err;
+
+  iq.opcode = grub_scsi_cmd_inquiry;
+  iq.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
+  iq.reserved = 0;
+  iq.alloc_length = 0x24; /* XXX: Hardcoded for now */
+  iq.reserved2 = 0;
+
+  err = scsi->dev->read (scsi, sizeof (iq), (char *) &iq,
+                        sizeof (iqd), (char *) &iqd);
+  if (err)
+    return err;
+
+  scsi->devtype = iqd.devtype & GRUB_SCSI_DEVTYPE_MASK;
+  scsi->removable = iqd.rmb >> GRUB_SCSI_REMOVABLE_BIT;
+
+  return GRUB_ERR_NONE;
+}
+
+/* Read the capacity and block size of SCSI.  */
+static grub_err_t
+grub_scsi_read_capacity (grub_scsi_t scsi)
+{
+  struct grub_scsi_read_capacity rc;
+  struct grub_scsi_read_capacity_data rcd;
+  grub_err_t err;
+
+  rc.opcode = grub_scsi_cmd_read_capacity;
+  rc.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
+  grub_memset (rc.reserved, 0, sizeof (rc.reserved));
+
+  err = scsi->dev->read (scsi, sizeof (rc), (char *) &rc,
+                        sizeof (rcd), (char *) &rcd);
+  if (err)
+    return err;
+
+  scsi->size = grub_be_to_cpu32 (rcd.size);
+  scsi->blocksize = grub_be_to_cpu32 (rcd.blocksize);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Send a SCSI request for DISK: read SIZE sectors starting with
+   sector SECTOR to BUF.  */
+static grub_err_t
+grub_scsi_read10 (grub_disk_t disk, grub_disk_addr_t sector,
+                 grub_size_t size, char *buf)
+{
+  grub_scsi_t scsi;
+  struct grub_scsi_read10 rd;
+
+  scsi = disk->data;
+
+  rd.opcode = grub_scsi_cmd_read10;
+  rd.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
+  rd.lba = grub_cpu_to_be32 (sector);
+  rd.reserved = 0;
+  rd.size = grub_cpu_to_be16 (size);
+  rd.reserved2 = 0;
+  rd.pad = 0;
+
+  return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
+}
+
+/* Send a SCSI request for DISK: read SIZE sectors starting with
+   sector SECTOR to BUF.  */
+static grub_err_t
+grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector,
+                 grub_size_t size, char *buf)
+{
+  grub_scsi_t scsi;
+  struct grub_scsi_read12 rd;
+
+  scsi = disk->data;
+
+  rd.opcode = grub_scsi_cmd_read12;
+  rd.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
+  rd.lba = grub_cpu_to_be32 (sector);
+  rd.size = grub_cpu_to_be32 (size);
+  rd.reserved = 0;
+  rd.control = 0;
+
+  return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
+}
+
+#if 0
+/* Send a SCSI request for DISK: write the data stored in BUF to SIZE
+   sectors starting with SECTOR.  */
+static grub_err_t
+grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector,
+                  grub_size_t size, char *buf)
+{
+  grub_scsi_t scsi;
+  struct grub_scsi_write10 wr;
+
+  scsi = disk->data;
+
+  wr.opcode = grub_scsi_cmd_write10;
+  wr.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
+  wr.lba = grub_cpu_to_be32 (sector);
+  wr.reserved = 0;
+  wr.size = grub_cpu_to_be16 (size);
+  wr.reserved2 = 0;
+  wr.pad = 0;
+
+  return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
+}
+
+/* Send a SCSI request for DISK: write the data stored in BUF to SIZE
+   sectors starting with SECTOR.  */
+static grub_err_t
+grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector,
+                  grub_size_t size, char *buf)
+{
+  grub_scsi_t scsi;
+  struct grub_scsi_write10 wr;
+
+  scsi = disk->data;
+
+  wr.opcode = grub_scsi_cmd_write12;
+  wr.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
+  wr.lba = grub_cpu_to_be32 (sector);
+  wr.size = grub_cpu_to_be32 (size);
+  wr.reserved = 0;
+  wr.pad = 0;
+
+  return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
+}
+#endif
+
+\f
+static int
+grub_scsi_iterate (int (*hook) (const char *name))
+{
+  grub_scsi_dev_t p;
+
+  auto int scsi_iterate (const char *name, int luns);
+
+  int scsi_iterate (const char *name, int luns)
+    {
+      int i;
+
+      /* In case of a single LUN, just return `usbX'.  */
+      if (luns == 1)
+       return hook (name);
+
+      /* In case of multiple LUNs, every LUN will get a prefix to
+        distinguish it.  */
+      for (i = 0; i < luns; i++)
+       {
+         char *sname;
+         int ret;
+         sname = grub_xasprintf ("%s%c", name, 'a' + i);
+         if (!sname)
+           return 1;
+         ret = hook (sname);
+         grub_free (sname);
+         if (ret)
+           return 1;
+       }
+      return 0;
+    }
+
+  for (p = grub_scsi_dev_list; p; p = p->next)
+    if (p->iterate && (p->iterate) (scsi_iterate))
+      return 1;
+
+  return 0;
+}
+
+static grub_err_t
+grub_scsi_open (const char *name, grub_disk_t disk)
+{
+  grub_scsi_dev_t p;
+  grub_scsi_t scsi;
+  grub_err_t err;
+  int len;
+  int lun;
+
+  scsi = grub_malloc (sizeof (*scsi));
+  if (! scsi)
+    return grub_errno;
+
+  len = grub_strlen (name);
+  lun = name[len - 1] - 'a';
+
+  /* Try to detect a LUN ('a'-'z'), otherwise just use the first
+     LUN.  */
+  if (lun < 0 || lun > 26)
+    lun = 0;
+
+  for (p = grub_scsi_dev_list; p; p = p->next)
+    {
+      if (p->open (name, scsi))
+       continue;
+
+      disk->id = (unsigned long) "scsi"; /* XXX */
+      disk->data = scsi;
+      scsi->dev = p;
+      scsi->lun = lun;
+      scsi->name = grub_strdup (name);
+      if (! scsi->name)
+       {
+         grub_free (scsi);
+         return grub_errno;
+       }
+
+      grub_dprintf ("scsi", "dev opened\n");
+
+      err = grub_scsi_inquiry (scsi);
+      if (err)
+       {
+         grub_free (scsi);
+         grub_dprintf ("scsi", "inquiry failed\n");
+         return err;
+       }
+
+      grub_dprintf ("scsi", "inquiry: devtype=0x%02x removable=%d\n",
+                   scsi->devtype, scsi->removable);
+
+      /* Try to be conservative about the device types
+        supported.  */
+      if (scsi->devtype != grub_scsi_devtype_direct
+         && scsi->devtype != grub_scsi_devtype_cdrom)
+       {
+         grub_free (scsi);
+         return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                            "unknown SCSI device");
+       }
+
+      if (scsi->devtype == grub_scsi_devtype_cdrom)
+       disk->has_partitions = 0;
+      else
+       disk->has_partitions = 1;
+
+      err = grub_scsi_read_capacity (scsi);
+      if (err)
+       {
+         grub_free (scsi);
+         grub_dprintf ("scsi", "READ CAPACITY failed\n");
+         return err;
+       }
+
+      /* SCSI blocks can be something else than 512, although GRUB
+        wants 512 byte blocks.  */
+      disk->total_sectors = ((scsi->size * scsi->blocksize)
+                            << GRUB_DISK_SECTOR_BITS);
+
+      grub_dprintf ("scsi", "capacity=%llu, blksize=%d\n",
+                   (unsigned long long) disk->total_sectors,
+                   scsi->blocksize);
+
+      return GRUB_ERR_NONE;
+    }
+
+  grub_free (scsi);
+
+  return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk");
+}
+
+static void
+grub_scsi_close (grub_disk_t disk)
+{
+  grub_scsi_t scsi;
+
+  scsi = disk->data;
+  scsi->dev->close (scsi);
+  grub_free (scsi);
+}
+
+static grub_err_t
+grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector,
+               grub_size_t size, char *buf)
+{
+  grub_scsi_t scsi;
+
+  scsi = disk->data;
+
+  /* SCSI sectors are variable in size.  GRUB uses 512 byte
+     sectors.  */
+  if (scsi->blocksize != GRUB_DISK_SECTOR_SIZE)
+    {
+      unsigned spb = scsi->blocksize >> GRUB_DISK_SECTOR_BITS;
+      if (! (spb != 0 && (scsi->blocksize & GRUB_DISK_SECTOR_SIZE) == 0))
+       return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                          "unsupported SCSI block size");
+
+      grub_uint32_t sector_mod = 0;
+      sector = grub_divmod64 (sector, spb, &sector_mod);
+
+      if (! (sector_mod == 0 && size % spb == 0))
+       return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                          "unaligned SCSI read not supported");
+
+      size /= spb;
+    }
+
+  /* Depending on the type, select a read function.  */
+  switch (scsi->devtype)
+    {
+    case grub_scsi_devtype_direct:
+      return grub_scsi_read10 (disk, sector, size, buf);
+
+    case grub_scsi_devtype_cdrom:
+      return grub_scsi_read12 (disk, sector, size, buf);
+    }
+
+  /* XXX: Never reached.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_scsi_write (grub_disk_t disk __attribute((unused)),
+                grub_disk_addr_t sector __attribute((unused)),
+                grub_size_t size __attribute((unused)),
+                const char *buf __attribute((unused)))
+{
+#if 0
+  /* XXX: Not tested yet!  */
+
+  /* XXX: This should depend on the device type?  */
+  return grub_scsi_write10 (disk, sector, size, buf);
+#endif
+  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+
+static struct grub_disk_dev grub_scsi_dev =
+  {
+    .name = "scsi",
+    .id = GRUB_DISK_DEVICE_SCSI_ID,
+    .iterate = grub_scsi_iterate,
+    .open = grub_scsi_open,
+    .close = grub_scsi_close,
+    .read = grub_scsi_read,
+    .write = grub_scsi_write,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(scsi)
+{
+  grub_disk_dev_register (&grub_scsi_dev);
+}
+
+GRUB_MOD_FINI(scsi)
+{
+  grub_disk_dev_unregister (&grub_scsi_dev);
+}
diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c
new file mode 100644 (file)
index 0000000..8554b22
--- /dev/null
@@ -0,0 +1,394 @@
+/* usbms.c - USB Mass Storage Support.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/usb.h>
+#include <grub/scsi.h>
+#include <grub/scsicmd.h>
+#include <grub/misc.h>
+
+#define GRUB_USBMS_DIRECTION_BIT       7
+
+/* The USB Mass Storage Command Block Wrapper.  */
+struct grub_usbms_cbw
+{
+  grub_uint32_t signature;
+  grub_uint32_t tag;
+  grub_uint32_t transfer_length;
+  grub_uint8_t flags;
+  grub_uint8_t lun;
+  grub_uint8_t length;
+  grub_uint8_t cbwcb[16];
+} __attribute__ ((packed));
+
+struct grub_usbms_csw
+{
+  grub_uint32_t signature;
+  grub_uint32_t tag;
+  grub_uint32_t residue;
+  grub_uint8_t status;
+} __attribute__ ((packed));
+
+struct grub_usbms_dev
+{
+  struct grub_usb_device *dev;
+
+  int luns;
+
+  int interface;
+  struct grub_usb_desc_endp *in;
+  struct grub_usb_desc_endp *out;
+
+  int in_maxsz;
+  int out_maxsz;
+
+  struct grub_usbms_dev *next;
+};
+typedef struct grub_usbms_dev *grub_usbms_dev_t;
+
+static grub_usbms_dev_t grub_usbms_dev_list;
+
+static int devcnt;
+
+static grub_err_t
+grub_usbms_reset (grub_usb_device_t dev, int interface)
+{
+  return grub_usb_control_msg (dev, 0x21, 255, 0, interface, 0, 0);
+}
+
+static void
+grub_usbms_finddevs (void)
+{
+  auto int usb_iterate (grub_usb_device_t dev);
+
+  int usb_iterate (grub_usb_device_t usbdev)
+    {
+      grub_usb_err_t err;
+      struct grub_usb_desc_device *descdev = &usbdev->descdev;
+      int i;
+
+      if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0)
+       return 0;
+
+      /* XXX: Just check configuration 0 for now.  */
+      for (i = 0; i < usbdev->config[0].descconf->numif; i++)
+       {
+         struct grub_usbms_dev *usbms;
+         struct grub_usb_desc_if *interf;
+         int j;
+         grub_uint8_t luns;
+
+         interf = usbdev->config[0].interf[i].descif;
+
+         /* If this is not a USB Mass Storage device with a supported
+            protocol, just skip it.  */
+         if (interf->class != GRUB_USB_CLASS_MASS_STORAGE
+             || interf->subclass != GRUB_USBMS_SUBCLASS_BULK
+             || interf->protocol != GRUB_USBMS_PROTOCOL_BULK)
+           {
+             continue;
+           }
+
+         devcnt++;
+         usbms = grub_zalloc (sizeof (struct grub_usbms_dev));
+         if (! usbms)
+           return 1;
+
+         usbms->dev = usbdev;
+         usbms->interface = i;
+
+         /* Iterate over all endpoints of this interface, at least a
+            IN and OUT bulk endpoint are required.  */
+         for (j = 0; j < interf->endpointcnt; j++)
+           {
+             struct grub_usb_desc_endp *endp;
+             endp = &usbdev->config[0].interf[i].descendp[j];
+
+             if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2)
+               {
+                 /* Bulk IN endpoint.  */
+                 usbms->in = endp;
+                 grub_usb_clear_halt (usbdev, endp->endp_addr & 128);
+                 usbms->in_maxsz = endp->maxpacket;
+               }
+             else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2)
+               {
+                 /* Bulk OUT endpoint.  */
+                 usbms->out = endp;
+                 grub_usb_clear_halt (usbdev, endp->endp_addr & 128);
+                 usbms->out_maxsz = endp->maxpacket;
+               }
+           }
+
+         if (!usbms->in || !usbms->out)
+           {
+             grub_free (usbms);
+             return 0;
+           }
+
+         /* Query the amount of LUNs.  */
+         err = grub_usb_control_msg (usbdev, 0xA1, 254,
+                                     0, i, 1, (char *) &luns);
+         if (err)
+           {
+             /* In case of a stall, clear the stall.  */
+             if (err == GRUB_USB_ERR_STALL)
+               {
+                 grub_usb_clear_halt (usbdev, usbms->in->endp_addr & 3);
+                 grub_usb_clear_halt (usbdev, usbms->out->endp_addr & 3);
+               }
+
+             /* Just set the amount of LUNs to one.  */
+             grub_errno = GRUB_ERR_NONE;
+             usbms->luns = 1;
+           }
+         else
+           usbms->luns = luns;
+
+         /* XXX: Check the magic values, does this really make
+            sense?  */
+         grub_usb_control_msg (usbdev, (1 << 6) | 1, 255,
+                               0, i, 0, 0);
+
+         /* XXX: To make Qemu work?  */
+         if (usbms->luns == 0)
+           usbms->luns = 1;
+
+         usbms->next = grub_usbms_dev_list;
+         grub_usbms_dev_list = usbms;
+
+         /* XXX: Activate the first configuration.  */
+         grub_usb_set_configuration (usbdev, 1);
+
+         /* Bulk-Only Mass Storage Reset, after the reset commands
+            will be accepted.  */
+         grub_usbms_reset (usbdev, i);
+
+         return 0;
+       }
+
+      return 0;
+    }
+
+  grub_usb_iterate (usb_iterate);
+}
+
+\f
+
+static int
+grub_usbms_iterate (int (*hook) (const char *name, int luns))
+{
+  grub_usbms_dev_t p;
+  int cnt = 0;
+
+  for (p = grub_usbms_dev_list; p; p = p->next)
+    {
+      char *devname;
+      devname = grub_xasprintf ("usb%d", cnt);
+
+      if (hook (devname, p->luns))
+       {
+         grub_free (devname);
+         return 1;
+       }
+      grub_free (devname);
+      cnt++;
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
+                    grub_size_t size, char *buf, int read_write)
+{
+  struct grub_usbms_cbw cbw;
+  grub_usbms_dev_t dev = (grub_usbms_dev_t) scsi->data;
+  struct grub_usbms_csw status;
+  static grub_uint32_t tag = 0;
+  grub_usb_err_t err = GRUB_USB_ERR_NONE;
+  int retrycnt = 3 + 1;
+
+ retry:
+  retrycnt--;
+  if (retrycnt == 0)
+    return grub_error (GRUB_ERR_IO, "USB Mass Storage stalled");
+
+  /* Setup the request.  */
+  grub_memset (&cbw, 0, sizeof (cbw));
+  cbw.signature = grub_cpu_to_le32 (0x43425355);
+  cbw.tag = tag++;
+  cbw.transfer_length = grub_cpu_to_le32 (size);
+  cbw.flags = (!read_write) << GRUB_USBMS_DIRECTION_BIT;
+  cbw.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
+  cbw.length = cmdsize;
+  grub_memcpy (cbw.cbwcb, cmd, cmdsize);
+
+  /* Write the request.  */
+  err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr & 15,
+                            sizeof (cbw), (char *) &cbw);
+  if (err)
+    {
+      if (err == GRUB_USB_ERR_STALL)
+       {
+         grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
+         goto retry;
+       }
+      return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed");
+    }
+
+  /* Read/write the data.  */
+  if (read_write == 0)
+    {
+      err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15, size, buf);
+      grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL);
+      if (err)
+       {
+         if (err == GRUB_USB_ERR_STALL)
+           {
+             grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
+             goto retry;
+           }
+         return grub_error (GRUB_ERR_READ_ERROR,
+                            "can't read from USB Mass Storage device");
+       }
+    }
+  else
+    {
+      err = grub_usb_bulk_write (dev->dev, dev->in->endp_addr & 15, size, buf);
+      grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL);
+      if (err)
+       {
+         if (err == GRUB_USB_ERR_STALL)
+           {
+             grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
+             goto retry;
+           }
+         return grub_error (GRUB_ERR_WRITE_ERROR,
+                            "can't write to USB Mass Storage device");
+       }
+    }
+
+  /* Read the status.  */
+  err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15,
+                           sizeof (status), (char *) &status);
+  if (err)
+    {
+      if (err == GRUB_USB_ERR_STALL)
+       {
+         grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
+         goto retry;
+       }
+      return grub_error (GRUB_ERR_READ_ERROR,
+                        "can't read status from USB Mass Storage device");
+    }
+
+  /* XXX: Magic and check this code.  */
+  if (status.status == 2)
+    {
+      /* XXX: Phase error, reset device.  */
+      grub_usbms_reset (dev->dev, dev->interface);
+      grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
+      grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
+
+      goto retry;
+    }
+
+  if (status.status)
+    return grub_error (GRUB_ERR_READ_ERROR,
+                      "error communication with USB Mass Storage device");
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_err_t
+grub_usbms_read (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
+                grub_size_t size, char *buf)
+{
+  return grub_usbms_transfer (scsi, cmdsize, cmd, size, buf, 0);
+}
+
+static grub_err_t
+grub_usbms_write (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
+                 grub_size_t size, char *buf)
+{
+  return grub_usbms_transfer (scsi, cmdsize, cmd, size, buf, 1);
+}
+
+static grub_err_t
+grub_usbms_open (const char *name, struct grub_scsi *scsi)
+{
+  grub_usbms_dev_t p;
+  int devnum;
+  int i = 0;
+
+  if (grub_strncmp (name, "usb", 3))
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                      "not a USB Mass Storage device");
+
+  devnum = grub_strtoul (name + 3, NULL, 10);
+  for (p = grub_usbms_dev_list; p; p = p->next)
+    {
+      /* Check if this is the devnumth device.  */
+      if (devnum == i)
+       {
+         scsi->data = p;
+         scsi->name = grub_strdup (name);
+         scsi->luns = p->luns;
+         if (! scsi->name)
+           return grub_errno;
+
+         return GRUB_ERR_NONE;
+       }
+
+      i++;
+    }
+
+  return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                    "not a USB Mass Storage device");
+}
+
+static void
+grub_usbms_close (struct grub_scsi *scsi)
+{
+  grub_free (scsi->name);
+}
+
+static struct grub_scsi_dev grub_usbms_dev =
+  {
+    .name = "usb",
+    .iterate = grub_usbms_iterate,
+    .open = grub_usbms_open,
+    .close = grub_usbms_close,
+    .read = grub_usbms_read,
+    .write = grub_usbms_write
+  };
+
+GRUB_MOD_INIT(usbms)
+{
+  grub_usbms_finddevs ();
+  grub_scsi_dev_register (&grub_usbms_dev);
+}
+
+GRUB_MOD_FINI(usbms)
+{
+  grub_scsi_dev_unregister (&grub_usbms_dev);
+}
diff --git a/grub-core/efiemu/i386/coredetect.c b/grub-core/efiemu/i386/coredetect.c
new file mode 100644 (file)
index 0000000..828508d
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/efiemu/efiemu.h>
+#include <grub/machine/efiemu.h>
+#include <grub/command.h>
+
+#define cpuid(num,a,b,c,d) \
+  asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
+               : "=a" (a), "=r" (b), "=c" (c), "=d" (d)  \
+               : "0" (num))
+
+#define bit_LM (1 << 29)
+
+char *
+grub_efiemu_get_default_core_name (void)
+{
+
+  unsigned int eax, ebx, ecx, edx;
+  unsigned int max_level;
+  unsigned int ext_level;
+
+  /* See if we can use cpuid.  */
+  asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
+               "pushl %0; popfl; pushfl; popl %0; popfl"
+               : "=&r" (eax), "=&r" (ebx)
+               : "i" (0x00200000));
+  if (((eax ^ ebx) & 0x00200000) == 0)
+    return "efiemu32.o";
+
+  /* Check the highest input value for eax.  */
+  cpuid (0, eax, ebx, ecx, edx);
+  /* We only look at the first four characters.  */
+  max_level = eax;
+  if (max_level == 0)
+    return "efiemu32.o";
+
+  cpuid (0x80000000, eax, ebx, ecx, edx);
+  ext_level = eax;
+  if (ext_level < 0x80000000)
+    return "efiemu32.o";
+
+  cpuid (0x80000001, eax, ebx, ecx, edx);
+  return (edx & bit_LM) ? "efiemu64.o" : "efiemu32.o";
+}
diff --git a/grub-core/efiemu/i386/loadcore32.c b/grub-core/efiemu/i386/loadcore32.c
new file mode 100644 (file)
index 0000000..24b63ec
--- /dev/null
@@ -0,0 +1,114 @@
+/* i386 CPU-specific part of loadcore.c for 32-bit mode */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/cpu/efiemu.h>
+#include <grub/elf.h>
+
+/* Check if EHDR is a valid ELF header.  */
+int
+grub_arch_efiemu_check_header32 (void *ehdr)
+{
+  Elf32_Ehdr *e = ehdr;
+
+  /* Check the magic numbers.  */
+  return (e->e_ident[EI_CLASS] == ELFCLASS32
+         && e->e_ident[EI_DATA] == ELFDATA2LSB
+         && e->e_machine == EM_386);
+}
+
+/* Relocate symbols.  */
+grub_err_t
+grub_arch_efiemu_relocate_symbols32 (grub_efiemu_segment_t segs,
+                                    struct grub_efiemu_elf_sym *elfsyms,
+                                    void *ehdr)
+{
+  unsigned i;
+  Elf32_Ehdr *e = ehdr;
+  Elf32_Shdr *s;
+  grub_err_t err;
+
+  grub_dprintf ("efiemu", "relocating symbols %d %d\n",
+               e->e_shoff, e->e_shnum);
+
+  for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_REL)
+      {
+       grub_efiemu_segment_t seg;
+       grub_dprintf ("efiemu", "shtrel\n");
+
+       /* Find the target segment.  */
+       for (seg = segs; seg; seg = seg->next)
+         if (seg->section == s->sh_info)
+           break;
+
+       if (seg)
+         {
+           Elf32_Rel *rel, *max;
+
+           for (rel = (Elf32_Rel *) ((char *) e + s->sh_offset),
+                  max = rel + s->sh_size / s->sh_entsize;
+                rel < max;
+                rel++)
+             {
+               Elf32_Word *addr;
+               struct grub_efiemu_elf_sym sym;
+               if (seg->size < rel->r_offset)
+                 return grub_error (GRUB_ERR_BAD_MODULE,
+                                    "reloc offset is out of the segment");
+
+               addr = (Elf32_Word *)
+                 ((char *) grub_efiemu_mm_obtain_request (seg->handle)
+                  + seg->off + rel->r_offset);
+               sym = elfsyms[ELF32_R_SYM (rel->r_info)];
+
+               switch (ELF32_R_TYPE (rel->r_info))
+                 {
+                 case R_386_32:
+                   if ((err = grub_efiemu_write_value
+                        (addr, sym.off + *addr, sym.handle, 0,
+                         seg->ptv_rel_needed, sizeof (grub_uint32_t))))
+                     return err;
+
+                   break;
+
+                 case R_386_PC32:
+                   if ((err = grub_efiemu_write_value
+                        (addr, sym.off + *addr - rel->r_offset
+                         - seg->off, sym.handle, seg->handle,
+                         seg->ptv_rel_needed, sizeof (grub_uint32_t))))
+                     return err;
+                   break;
+                 default:
+                   return grub_error (GRUB_ERR_BAD_OS,
+                                      "unrecognised relocation");
+                 }
+             }
+         }
+      }
+
+  return GRUB_ERR_NONE;
+}
+
+
diff --git a/grub-core/efiemu/i386/loadcore64.c b/grub-core/efiemu/i386/loadcore64.c
new file mode 100644 (file)
index 0000000..a692790
--- /dev/null
@@ -0,0 +1,120 @@
+/* i386 CPU-specific part of loadcore.c for 32-bit mode */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/cpu/efiemu.h>
+#include <grub/elf.h>
+
+/* Check if EHDR is a valid ELF header.  */
+int
+grub_arch_efiemu_check_header64 (void *ehdr)
+{
+  Elf64_Ehdr *e = ehdr;
+
+  return (e->e_ident[EI_CLASS] == ELFCLASS64
+         && e->e_ident[EI_DATA] == ELFDATA2LSB
+         && e->e_machine == EM_X86_64);
+}
+
+/* Relocate symbols.  */
+grub_err_t
+grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs,
+                                    struct grub_efiemu_elf_sym *elfsyms,
+                                    void *ehdr)
+{
+  unsigned i;
+  Elf64_Ehdr *e = ehdr;
+  Elf64_Shdr *s;
+  grub_err_t err;
+
+  for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_RELA)
+      {
+       grub_efiemu_segment_t seg;
+       grub_dprintf ("efiemu", "shtrel\n");
+
+       /* Find the target segment.  */
+       for (seg = segs; seg; seg = seg->next)
+         if (seg->section == s->sh_info)
+           break;
+
+       if (seg)
+         {
+           Elf64_Rela *rel, *max;
+
+           for (rel = (Elf64_Rela *) ((char *) e + s->sh_offset),
+                  max = rel + (unsigned long) s->sh_size
+                  / (unsigned long)s->sh_entsize;
+                rel < max;
+                rel++)
+             {
+               void *addr;
+               grub_uint32_t *addr32;
+               grub_uint64_t *addr64;
+               struct grub_efiemu_elf_sym sym;
+               if (seg->size < rel->r_offset)
+                 return grub_error (GRUB_ERR_BAD_MODULE,
+                                    "reloc offset is out of the segment");
+
+               addr =
+                 ((char *) grub_efiemu_mm_obtain_request (seg->handle)
+                  + seg->off + rel->r_offset);
+               addr32 = (grub_uint32_t *) addr;
+               addr64 = (grub_uint64_t *) addr;
+               sym = elfsyms[ELF64_R_SYM (rel->r_info)];
+
+               switch (ELF64_R_TYPE (rel->r_info))
+                 {
+                 case R_X86_64_64:
+                   if ((err = grub_efiemu_write_value
+                        (addr, *addr64 + rel->r_addend + sym.off, sym.handle,
+                         0, seg->ptv_rel_needed, sizeof (grub_uint64_t))))
+                     return err;
+                   break;
+
+                 case R_X86_64_PC32:
+                   if ((err = grub_efiemu_write_value
+                        (addr, *addr32 + rel->r_addend + sym.off
+                         - rel->r_offset - seg->off, sym.handle, seg->handle,
+                         seg->ptv_rel_needed, sizeof (grub_uint32_t))))
+                     return err;
+                   break;
+
+                  case R_X86_64_32:
+                  case R_X86_64_32S:
+                   if ((err = grub_efiemu_write_value
+                        (addr, *addr32 + rel->r_addend + sym.off, sym.handle,
+                         0, seg->ptv_rel_needed, sizeof (grub_uint32_t))))
+                     return err;
+                    break;
+                 default:
+                   return grub_error (GRUB_ERR_BAD_OS,
+                                      "unrecognised relocation");
+                 }
+             }
+         }
+      }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/efiemu/i386/pc/cfgtables.c b/grub-core/efiemu/i386/pc/cfgtables.c
new file mode 100644 (file)
index 0000000..9c6b4e5
--- /dev/null
@@ -0,0 +1,76 @@
+/* Register SMBIOS and ACPI tables. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/machine/efiemu.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/acpi.h>
+
+grub_err_t
+grub_machine_efiemu_init_tables ()
+{
+  grub_uint8_t *ptr;
+  void *table;
+  grub_err_t err;
+  grub_efi_guid_t smbios = GRUB_EFI_SMBIOS_TABLE_GUID;
+  grub_efi_guid_t acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
+  grub_efi_guid_t acpi = GRUB_EFI_ACPI_TABLE_GUID;
+
+  err = grub_efiemu_unregister_configuration_table (smbios);
+  if (err)
+    return err;
+  err = grub_efiemu_unregister_configuration_table (acpi);
+  if (err)
+    return err;
+  err = grub_efiemu_unregister_configuration_table (acpi20);
+  if (err)
+    return err;
+
+  table = grub_acpi_get_rsdpv1 ();
+  if (table)
+    {
+      err = grub_efiemu_register_configuration_table (acpi, 0, 0, table);
+      if (err)
+       return err;
+    }
+  table = grub_acpi_get_rsdpv2 ();
+  if (table)
+    {
+      err = grub_efiemu_register_configuration_table (acpi20, 0, 0, table);
+      if (err)
+       return err;
+    }
+
+  for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000;
+       ptr += 16)
+    if (grub_memcmp (ptr, "_SM_", 4) == 0
+       && grub_byte_checksum (ptr, *(ptr + 5)) == 0)
+      break;
+
+  if (ptr < (grub_uint8_t *) 0x100000)
+    {
+      grub_dprintf ("efiemu", "Registering SMBIOS\n");
+      if ((err = grub_efiemu_register_configuration_table (smbios, 0, 0, ptr)))
+       return err;
+    }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/efiemu/loadcore.c b/grub-core/efiemu/loadcore.c
new file mode 100644 (file)
index 0000000..4bf26ee
--- /dev/null
@@ -0,0 +1,370 @@
+/* Load runtime image of EFIemu. Functions specific to 32/64-bit mode */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/cpu/efiemu.h>
+#include <grub/machine/efiemu.h>
+#include <grub/elf.h>
+
+/* ELF symbols and their values */
+static struct grub_efiemu_elf_sym *grub_efiemu_elfsyms = 0;
+static int grub_efiemu_nelfsyms = 0;
+
+/* Return the address of a section whose index is N.  */
+static grub_err_t
+grub_efiemu_get_section_addr (grub_efiemu_segment_t segs, unsigned n,
+                             int *handle, grub_off_t *off)
+{
+  grub_efiemu_segment_t seg;
+
+  for (seg = segs; seg; seg = seg->next)
+    if (seg->section == n)
+      {
+       *handle = seg->handle;
+       *off = seg->off;
+       return GRUB_ERR_NONE;
+      }
+
+  return grub_error (GRUB_ERR_BAD_OS, "section %d not found", n);
+}
+
+grub_err_t
+SUFFIX (grub_efiemu_loadcore_unload) (void)
+{
+  grub_free (grub_efiemu_elfsyms);
+  grub_efiemu_elfsyms = 0;
+  return GRUB_ERR_NONE;
+}
+
+/* Check if EHDR is a valid ELF header.  */
+int
+SUFFIX (grub_efiemu_check_header) (void *ehdr, grub_size_t size)
+{
+  Elf_Ehdr *e = ehdr;
+
+  /* Check the header size.  */
+  if (size < sizeof (Elf_Ehdr))
+    return 0;
+
+  /* Check the magic numbers.  */
+  if (!SUFFIX (grub_arch_efiemu_check_header) (ehdr)
+      || 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 0;
+
+  return 1;
+}
+
+/* Load all segments from memory specified by E.  */
+static grub_err_t
+grub_efiemu_load_segments (grub_efiemu_segment_t segs, const Elf_Ehdr *e)
+{
+  Elf_Shdr *s;
+  grub_efiemu_segment_t cur;
+
+  grub_dprintf ("efiemu", "loading segments\n");
+
+  for (cur=segs; cur; cur = cur->next)
+    {
+      s = (Elf_Shdr *)cur->srcptr;
+
+      if ((s->sh_flags & SHF_ALLOC) && s->sh_size)
+       {
+         void *addr;
+
+         addr = (grub_uint8_t *) grub_efiemu_mm_obtain_request (cur->handle)
+           + cur->off;
+
+         switch (s->sh_type)
+           {
+           case SHT_PROGBITS:
+             grub_memcpy (addr, (char *) e + s->sh_offset, s->sh_size);
+             break;
+           case SHT_NOBITS:
+             grub_memset (addr, 0, s->sh_size);
+             break;
+           }
+       }
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Get a string at offset OFFSET from strtab */
+static char *
+grub_efiemu_get_string (unsigned offset, const Elf_Ehdr *e)
+{
+  unsigned i;
+  Elf_Shdr *s;
+
+  for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_STRTAB && offset < s->sh_size)
+      return (char *) e + s->sh_offset + offset;
+  return 0;
+}
+
+/* Request memory for segments and fill segments info */
+static grub_err_t
+grub_efiemu_init_segments (grub_efiemu_segment_t *segs, const Elf_Ehdr *e)
+{
+  unsigned i;
+  Elf_Shdr *s;
+
+  for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
+    {
+      if (s->sh_flags & SHF_ALLOC)
+       {
+         grub_efiemu_segment_t seg;
+         seg = (grub_efiemu_segment_t) grub_malloc (sizeof (*seg));
+         if (! seg)
+           return grub_errno;
+
+         if (s->sh_size)
+           {
+             seg->handle
+               = grub_efiemu_request_memalign
+               (s->sh_addralign, s->sh_size,
+                s->sh_flags & SHF_EXECINSTR ? GRUB_EFI_RUNTIME_SERVICES_CODE
+                : GRUB_EFI_RUNTIME_SERVICES_DATA);
+             if (seg->handle < 0)
+               return grub_errno;
+             seg->off = 0;
+           }
+
+         /*
+            .text-physical doesn't need to be relocated when switching to
+            virtual mode
+          */
+         if (!grub_strcmp (grub_efiemu_get_string (s->sh_name, e),
+                           ".text-physical"))
+           seg->ptv_rel_needed = 0;
+         else
+           seg->ptv_rel_needed = 1;
+         seg->size = s->sh_size;
+         seg->section = i;
+         seg->next = *segs;
+         seg->srcptr = s;
+         *segs = seg;
+       }
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Count symbols and relocators and allocate/request memory for them */
+static grub_err_t
+grub_efiemu_count_symbols (const Elf_Ehdr *e)
+{
+  unsigned i;
+  Elf_Shdr *s;
+  int num = 0;
+
+  /* Symbols */
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
+
+  grub_efiemu_nelfsyms = (unsigned) s->sh_size / (unsigned) s->sh_entsize;
+  grub_efiemu_elfsyms = (struct grub_efiemu_elf_sym *)
+    grub_malloc (sizeof (struct grub_efiemu_elf_sym) * grub_efiemu_nelfsyms);
+
+  /* Relocators */
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_REL || s->sh_type == SHT_RELA)
+      num += ((unsigned) s->sh_size) / ((unsigned) s->sh_entsize);
+
+  grub_efiemu_request_symbols (num);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Fill grub_efiemu_elfsyms with symbol values */
+static grub_err_t
+grub_efiemu_resolve_symbols (grub_efiemu_segment_t segs, Elf_Ehdr *e)
+{
+  unsigned i;
+  Elf_Shdr *s;
+  Elf_Sym *sym;
+  const char *str;
+  Elf_Word size, entsize;
+
+  grub_dprintf ("efiemu", "resolving symbols\n");
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
+
+  sym = (Elf_Sym *) ((char *) e + s->sh_offset);
+  size = s->sh_size;
+  entsize = s->sh_entsize;
+
+  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
+  str = (char *) e + s->sh_offset;
+
+  for (i = 0;
+       i < size / entsize;
+       i++, sym = (Elf_Sym *) ((char *) sym + entsize))
+    {
+      unsigned char type = ELF_ST_TYPE (sym->st_info);
+      unsigned char bind = ELF_ST_BIND (sym->st_info);
+      int handle;
+      grub_off_t off;
+      grub_err_t err;
+      const char *name = str + sym->st_name;
+      grub_efiemu_elfsyms[i].section = sym->st_shndx;
+      switch (type)
+       {
+       case STT_NOTYPE:
+         /* Resolve a global symbol.  */
+         if (sym->st_name != 0 && sym->st_shndx == 0)
+           {
+             if ((err = grub_efiemu_resolve_symbol (name, &handle, &off)))
+               return err;
+             grub_efiemu_elfsyms[i].handle = handle;
+             grub_efiemu_elfsyms[i].off = off;
+           }
+         else
+           sym->st_value = 0;
+         break;
+
+       case STT_OBJECT:
+         if ((err = grub_efiemu_get_section_addr
+              (segs, sym->st_shndx, &handle, &off)))
+           return err;
+
+         off += sym->st_value;
+         if (bind != STB_LOCAL)
+           if ((err = grub_efiemu_register_symbol (name, handle, off)))
+             return err;
+         grub_efiemu_elfsyms[i].handle = handle;
+         grub_efiemu_elfsyms[i].off = off;
+         break;
+
+       case STT_FUNC:
+         if ((err = grub_efiemu_get_section_addr
+              (segs, sym->st_shndx, &handle, &off)))
+           return err;
+
+         off += sym->st_value;
+         if (bind != STB_LOCAL)
+           if ((err = grub_efiemu_register_symbol (name, handle, off)))
+             return err;
+         grub_efiemu_elfsyms[i].handle = handle;
+         grub_efiemu_elfsyms[i].off = off;
+         break;
+
+       case STT_SECTION:
+         if ((err = grub_efiemu_get_section_addr
+              (segs, sym->st_shndx, &handle, &off)))
+           {
+             grub_efiemu_elfsyms[i].handle = 0;
+             grub_efiemu_elfsyms[i].off = 0;
+             grub_errno = GRUB_ERR_NONE;
+             break;
+           }
+
+         grub_efiemu_elfsyms[i].handle = handle;
+         grub_efiemu_elfsyms[i].off = off;
+         break;
+
+       case STT_FILE:
+         grub_efiemu_elfsyms[i].handle = 0;
+         grub_efiemu_elfsyms[i].off = 0;
+         break;
+
+       default:
+         return grub_error (GRUB_ERR_BAD_MODULE,
+                            "unknown symbol type `%d'", (int) type);
+       }
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Load runtime to the memory and request memory for definitive location*/
+grub_err_t
+SUFFIX (grub_efiemu_loadcore_init) (void *core, grub_size_t core_size,
+                                   grub_efiemu_segment_t *segments)
+{
+  Elf_Ehdr *e = (Elf_Ehdr *) core;
+  grub_err_t err;
+
+  if (e->e_type != ET_REL)
+    return grub_error (GRUB_ERR_BAD_MODULE, "invalid ELF file type");
+
+  /* Make sure that every section is within the core.  */
+  if ((grub_size_t) core_size < e->e_shoff + e->e_shentsize * e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_OS, "ELF sections outside core");
+
+  if ((err = grub_efiemu_init_segments (segments, core)))
+    return err;
+  if ((err = grub_efiemu_count_symbols (core)))
+    return err;
+
+  grub_efiemu_request_symbols (1);
+  return GRUB_ERR_NONE;
+}
+
+/* Load runtime definitively */
+grub_err_t
+SUFFIX (grub_efiemu_loadcore_load) (void *core,
+                                   grub_size_t core_size
+                                   __attribute__ ((unused)),
+                                   grub_efiemu_segment_t segments)
+{
+  grub_err_t err;
+  err = grub_efiemu_load_segments (segments, core);
+  if (err)
+    return err;
+
+  err = grub_efiemu_resolve_symbols (segments, core);
+  if (err)
+    return err;
+
+  err = SUFFIX (grub_arch_efiemu_relocate_symbols) (segments,
+                                                   grub_efiemu_elfsyms,
+                                                   core);
+  if (err)
+    return err;
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/efiemu/loadcore32.c b/grub-core/efiemu/loadcore32.c
new file mode 100644 (file)
index 0000000..c1e033b
--- /dev/null
@@ -0,0 +1,22 @@
+/* This file contains definitions so that loadcore.c compiles for 32-bit */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define SUFFIX(x) x ## 32
+#define GRUB_TARGET_WORDSIZE 32
+#include "loadcore.c"
diff --git a/grub-core/efiemu/loadcore64.c b/grub-core/efiemu/loadcore64.c
new file mode 100644 (file)
index 0000000..ce7284f
--- /dev/null
@@ -0,0 +1,22 @@
+/* This file contains definitions so that loadcore.c compiles for 64-bit */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define SUFFIX(x) x ## 64
+#define GRUB_TARGET_WORDSIZE 64
+#include "loadcore.c"
diff --git a/grub-core/efiemu/loadcore_common.c b/grub-core/efiemu/loadcore_common.c
new file mode 100644 (file)
index 0000000..a4db0ee
--- /dev/null
@@ -0,0 +1,189 @@
+/* Load runtime image of EFIemu. Functions common to 32/64-bit mode */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/cpu/efiemu.h>
+
+/* Are we in 32 or 64-bit mode?*/
+static grub_efiemu_mode_t grub_efiemu_mode = GRUB_EFIEMU_NOTLOADED;
+/* Runtime ELF file */
+static grub_ssize_t efiemu_core_size;
+static void *efiemu_core = 0;
+/* Linked list of segments */
+static grub_efiemu_segment_t efiemu_segments = 0;
+
+/* equivalent to sizeof (grub_efi_uintn_t) but taking the mode into account*/
+int
+grub_efiemu_sizeof_uintn_t (void)
+{
+  if (grub_efiemu_mode == GRUB_EFIEMU32)
+    return 4;
+  if (grub_efiemu_mode == GRUB_EFIEMU64)
+    return 8;
+  return 0;
+}
+
+/* Check the header and set mode */
+static grub_err_t
+grub_efiemu_check_header (void *ehdr, grub_size_t size,
+                         grub_efiemu_mode_t *mode)
+{
+  /* Check the magic numbers.  */
+  if ((*mode == GRUB_EFIEMU_NOTLOADED || *mode == GRUB_EFIEMU32)
+      && grub_efiemu_check_header32 (ehdr,size))
+    {
+      *mode = GRUB_EFIEMU32;
+      return GRUB_ERR_NONE;
+    }
+  if ((*mode == GRUB_EFIEMU_NOTLOADED || *mode == GRUB_EFIEMU64)
+      && grub_efiemu_check_header64 (ehdr,size))
+    {
+      *mode = GRUB_EFIEMU64;
+      return GRUB_ERR_NONE;
+    }
+  return grub_error (GRUB_ERR_BAD_OS, "invalid ELF magic");
+}
+
+/* Unload segments */
+static int
+grub_efiemu_unload_segs (grub_efiemu_segment_t seg)
+{
+  grub_efiemu_segment_t segn;
+  for (; seg; seg = segn)
+    {
+      segn = seg->next;
+      grub_efiemu_mm_return_request (seg->handle);
+      grub_free (seg);
+    }
+  return 1;
+}
+
+
+grub_err_t
+grub_efiemu_loadcore_unload(void)
+{
+  switch (grub_efiemu_mode)
+    {
+    case GRUB_EFIEMU32:
+      grub_efiemu_loadcore_unload32 ();
+      break;
+
+    case GRUB_EFIEMU64:
+      grub_efiemu_loadcore_unload64 ();
+      break;
+
+    default:
+      break;
+    }
+
+  grub_efiemu_mode = GRUB_EFIEMU_NOTLOADED;
+
+  grub_free (efiemu_core);
+  efiemu_core = 0;
+
+  grub_efiemu_unload_segs (efiemu_segments);
+  efiemu_segments = 0;
+
+  grub_efiemu_free_syms ();
+
+  return GRUB_ERR_NONE;
+}
+
+/* Load runtime file and do some initial preparations */
+grub_err_t
+grub_efiemu_loadcore_init (grub_file_t file)
+{
+  grub_err_t err;
+
+  efiemu_core_size = grub_file_size (file);
+  efiemu_core = 0;
+  efiemu_core = grub_malloc (efiemu_core_size);
+  if (! efiemu_core)
+    return grub_errno;
+
+  if (grub_file_read (file, efiemu_core, efiemu_core_size)
+      != (int) efiemu_core_size)
+    {
+      grub_free (efiemu_core);
+      efiemu_core = 0;
+      return grub_errno;
+    }
+
+  if (grub_efiemu_check_header (efiemu_core, efiemu_core_size,
+                               &grub_efiemu_mode))
+    {
+      grub_free (efiemu_core);
+      efiemu_core = 0;
+      return GRUB_ERR_BAD_MODULE;
+    }
+
+  switch (grub_efiemu_mode)
+    {
+    case GRUB_EFIEMU32:
+      if ((err = grub_efiemu_loadcore_init32 (efiemu_core, efiemu_core_size,
+                                             &efiemu_segments)))
+       {
+         grub_free (efiemu_core);
+         efiemu_core = 0;
+         grub_efiemu_mode = GRUB_EFIEMU_NOTLOADED;
+         return err;
+       }
+      break;
+
+    case GRUB_EFIEMU64:
+      if ((err = grub_efiemu_loadcore_init64 (efiemu_core, efiemu_core_size,
+                                             &efiemu_segments)))
+       {
+         grub_free (efiemu_core);
+         efiemu_core = 0;
+         grub_efiemu_mode = GRUB_EFIEMU_NOTLOADED;
+         return err;
+       }
+      break;
+
+    default:
+      return grub_error (GRUB_ERR_BAD_OS, "unknown EFI runtime");
+    }
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_loadcore_load (void)
+{
+  grub_err_t err;
+  switch (grub_efiemu_mode)
+    {
+    case GRUB_EFIEMU32:
+      if ((err = grub_efiemu_loadcore_load32 (efiemu_core, efiemu_core_size,
+                                             efiemu_segments)))
+         grub_efiemu_loadcore_unload ();
+      return err;
+    case GRUB_EFIEMU64:
+      if ((err = grub_efiemu_loadcore_load64 (efiemu_core, efiemu_core_size,
+                                             efiemu_segments)))
+         grub_efiemu_loadcore_unload ();
+      return err;
+    default:
+      return grub_error (GRUB_ERR_BAD_OS, "unknown EFI runtime");
+    }
+}
diff --git a/grub-core/efiemu/main.c b/grub-core/efiemu/main.c
new file mode 100644 (file)
index 0000000..b197a8b
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This is an emulation of EFI runtime services.
+   This allows a more uniform boot on i386 machines.
+   As it emulates only runtime service it isn't able
+   to chainload EFI bootloader on non-EFI system. */
+
+
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/machine/efiemu.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+/* System table. Two version depending on mode */
+grub_efi_system_table32_t *grub_efiemu_system_table32 = 0;
+grub_efi_system_table64_t *grub_efiemu_system_table64 = 0;
+/* Modules may need to execute some actions after memory allocation happens */
+static struct grub_efiemu_prepare_hook *efiemu_prepare_hooks = 0;
+/* Linked list of configuration tables */
+static struct grub_efiemu_configuration_table *efiemu_config_tables = 0;
+static int prepared = 0;
+
+/* Free all allocated space */
+grub_err_t
+grub_efiemu_unload (void)
+{
+  struct grub_efiemu_configuration_table *cur, *d;
+  struct grub_efiemu_prepare_hook *curhook, *d2;
+  grub_efiemu_loadcore_unload ();
+
+  grub_efiemu_mm_unload ();
+
+  for (cur = efiemu_config_tables; cur;)
+    {
+      d = cur->next;
+      if (cur->unload)
+       cur->unload (cur->data);
+      grub_free (cur);
+      cur = d;
+    }
+  efiemu_config_tables = 0;
+
+  for (curhook = efiemu_prepare_hooks; curhook;)
+    {
+      d2 = curhook->next;
+      if (curhook->unload)
+       curhook->unload (curhook->data);
+      grub_free (curhook);
+      curhook = d2;
+    }
+  efiemu_prepare_hooks = 0;
+
+  prepared = 0;
+
+  return GRUB_ERR_NONE;
+}
+
+/* Remove previously registered table from the list */
+grub_err_t
+grub_efiemu_unregister_configuration_table (grub_efi_guid_t guid)
+{
+  struct grub_efiemu_configuration_table *cur, *prev;
+
+  /* Special treating if head is to remove */
+  while (efiemu_config_tables
+        && !grub_memcmp (&(efiemu_config_tables->guid), &guid, sizeof (guid)))
+    {
+      if (efiemu_config_tables->unload)
+         efiemu_config_tables->unload (efiemu_config_tables->data);
+       cur = efiemu_config_tables->next;
+       grub_free (efiemu_config_tables);
+       efiemu_config_tables = cur;
+    }
+  if (!efiemu_config_tables)
+    return GRUB_ERR_NONE;
+
+  /* Remove from chain */
+  for (prev = efiemu_config_tables, cur = prev->next; cur;)
+    if (grub_memcmp (&(cur->guid), &guid, sizeof (guid)) == 0)
+      {
+       if (cur->unload)
+         cur->unload (cur->data);
+       prev->next = cur->next;
+       grub_free (cur);
+       cur = prev->next;
+      }
+    else
+      {
+       prev = cur;
+       cur = cur->next;
+      }
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_register_prepare_hook (grub_err_t (*hook) (void *data),
+                                  void (*unload) (void *data),
+                                  void *data)
+{
+  struct grub_efiemu_prepare_hook *nhook;
+  if (! hook)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "you must supply the hook");
+  nhook = (struct grub_efiemu_prepare_hook *) grub_malloc (sizeof (*nhook));
+  if (! nhook)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't prepare hook");
+  nhook->hook = hook;
+  nhook->unload = unload;
+  nhook->data = data;
+  nhook->next = efiemu_prepare_hooks;
+  efiemu_prepare_hooks = nhook;
+  return GRUB_ERR_NONE;
+}
+
+/* Register a configuration table either supplying the address directly
+   or with a hook
+*/
+grub_err_t
+grub_efiemu_register_configuration_table (grub_efi_guid_t guid,
+                                         void * (*get_table) (void *data),
+                                         void (*unload) (void *data),
+                                         void *data)
+{
+  struct grub_efiemu_configuration_table *tbl;
+  grub_err_t err;
+
+ if (! get_table && ! data)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "you must set at least get_table or data");
+  if ((err = grub_efiemu_unregister_configuration_table (guid)))
+    return err;
+
+  tbl = (struct grub_efiemu_configuration_table *) grub_malloc (sizeof (*tbl));
+  if (! tbl)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't register table");
+
+  tbl->guid = guid;
+  tbl->get_table = get_table;
+  tbl->unload = unload;
+  tbl->data = data;
+  tbl->next = efiemu_config_tables;
+  efiemu_config_tables = tbl;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_efiemu_unload (grub_command_t cmd __attribute__ ((unused)),
+                       int argc __attribute__ ((unused)),
+                       char *args[] __attribute__ ((unused)))
+{
+  return grub_efiemu_unload ();
+}
+
+static grub_err_t
+grub_cmd_efiemu_prepare (grub_command_t cmd __attribute__ ((unused)),
+                        int argc __attribute__ ((unused)),
+                        char *args[] __attribute__ ((unused)))
+{
+  return grub_efiemu_prepare ();
+}
+
+\f
+
+
+int
+grub_efiemu_exit_boot_services (grub_efi_uintn_t map_key
+                               __attribute__ ((unused)))
+{
+  /* Nothing to do here yet */
+  return 1;
+}
+
+int
+grub_efiemu_finish_boot_services (void)
+{
+  /* Nothing to do here yet */
+  return 1;
+}
+
+/* Load the runtime from the file FILENAME.  */
+static grub_err_t
+grub_efiemu_load_file (const char *filename)
+{
+  grub_file_t file;
+  grub_err_t err;
+
+  file = grub_file_open (filename);
+  if (! file)
+    return 0;
+
+  err = grub_efiemu_mm_init ();
+  if (err)
+    {
+      grub_file_close (file);
+      grub_efiemu_unload ();
+      return grub_error (grub_errno, "couldn't init memory management");
+    }
+
+  grub_dprintf ("efiemu", "mm initialized\n");
+
+  err = grub_efiemu_loadcore_init (file);
+  if (err)
+    {
+      grub_file_close (file);
+      grub_efiemu_unload ();
+      return err;
+    }
+
+  grub_file_close (file);
+
+  /* For configuration tables entry in system table. */
+  grub_efiemu_request_symbols (1);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_autocore (void)
+{
+  const char *prefix;
+  char *filename;
+  char *suffix;
+  grub_err_t err;
+
+  if (grub_efiemu_sizeof_uintn_t () != 0)
+    return GRUB_ERR_NONE;
+
+  prefix = grub_env_get ("prefix");
+
+  if (! prefix)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
+                      "couldn't find efiemu core because prefix "
+                      "isn't set");
+
+  suffix = grub_efiemu_get_default_core_name ();
+
+  filename = grub_xasprintf ("%s/%s", prefix, suffix);
+  if (! filename)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                      "couldn't allocate temporary space");
+
+
+  err = grub_efiemu_load_file (filename);
+  grub_free (filename);
+  if (err)
+    return err;
+#ifndef GRUB_MACHINE_EMU
+  err = grub_machine_efiemu_init_tables ();
+  if (err)
+    return err;
+#endif
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_prepare (void)
+{
+  grub_err_t err;
+
+  if (prepared)
+    return GRUB_ERR_NONE;
+
+  grub_dprintf ("efiemu", "Preparing %d-bit efiemu\n",
+               8 * grub_efiemu_sizeof_uintn_t ());
+
+  err = grub_efiemu_autocore ();
+
+  /* Create NVRAM. */
+  grub_efiemu_pnvram ();
+
+  prepared = 1;
+
+  if (grub_efiemu_sizeof_uintn_t () == 4)
+    return grub_efiemu_prepare32 (efiemu_prepare_hooks, efiemu_config_tables);
+  else
+    return grub_efiemu_prepare64 (efiemu_prepare_hooks, efiemu_config_tables);
+}
+
+
+static grub_err_t
+grub_cmd_efiemu_load (grub_command_t cmd __attribute__ ((unused)),
+                     int argc, char *args[])
+{
+  grub_err_t err;
+
+  grub_efiemu_unload ();
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "filename required");
+
+  err = grub_efiemu_load_file (args[0]);
+  if (err)
+    return err;
+#ifndef GRUB_MACHINE_EMU
+  err = grub_machine_efiemu_init_tables ();
+  if (err)
+    return err;
+#endif
+  return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd_loadcore, cmd_prepare, cmd_unload;
+
+GRUB_MOD_INIT(efiemu)
+{
+  cmd_loadcore = grub_register_command ("efiemu_loadcore",
+                                       grub_cmd_efiemu_load,
+                                       N_("FILE"),
+                                       N_("Load and initialize EFI emulator."));
+  cmd_prepare = grub_register_command ("efiemu_prepare",
+                                      grub_cmd_efiemu_prepare,
+                                      0,
+                                      N_("Finalize loading of EFI emulator."));
+  cmd_unload = grub_register_command ("efiemu_unload", grub_cmd_efiemu_unload,
+                                     0,
+                                     N_("Unload EFI emulator."));
+}
+
+GRUB_MOD_FINI(efiemu)
+{
+  grub_unregister_command (cmd_loadcore);
+  grub_unregister_command (cmd_prepare);
+  grub_unregister_command (cmd_unload);
+}
diff --git a/grub-core/efiemu/mm.c b/grub-core/efiemu/mm.c
new file mode 100644 (file)
index 0000000..4b29360
--- /dev/null
@@ -0,0 +1,633 @@
+/* Memory management for efiemu */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+/*
+  To keep efiemu runtime contiguous this mm is special.
+  It uses deferred allocation.
+  In the first stage you may request memory with grub_efiemu_request_memalign
+  It will give you a handle with which in the second phase you can access your
+  memory with grub_efiemu_mm_obtain_request (handle). It's guaranteed that
+  subsequent calls with the same handle return the same result. You can't request any additional memory once you're in the second phase
+*/
+
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/machine/memory.h>
+#include <grub/efiemu/efiemu.h>
+
+struct grub_efiemu_memrequest
+{
+  struct grub_efiemu_memrequest *next;
+  grub_efi_memory_type_t type;
+  grub_size_t size;
+  grub_size_t align_overhead;
+  int handle;
+  void *val;
+};
+/* Linked list of requested memory. */
+static struct grub_efiemu_memrequest *memrequests = 0;
+/* Memory map. */
+static grub_efi_memory_descriptor_t *efiemu_mmap = 0;
+/* Pointer to allocated memory */
+static void *resident_memory = 0;
+/* Size of requested memory per type */
+static grub_size_t requested_memory[GRUB_EFI_MAX_MEMORY_TYPE];
+/* How many slots is allocated for memory_map and how many are already used */
+static int mmap_reserved_size = 0, mmap_num = 0;
+
+/* Add a memory region to map*/
+static grub_err_t
+grub_efiemu_add_to_mmap (grub_uint64_t start, grub_uint64_t size,
+                        grub_efi_memory_type_t type)
+{
+  grub_uint64_t page_start, npages;
+
+  /* Extend map if necessary*/
+  if (mmap_num >= mmap_reserved_size)
+    {
+      efiemu_mmap = (grub_efi_memory_descriptor_t *)
+       grub_realloc (efiemu_mmap, (++mmap_reserved_size)
+                     * sizeof (grub_efi_memory_descriptor_t));
+      if (!efiemu_mmap)
+       return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                          "not enough space for memory map");
+    }
+
+  /* Fill slot*/
+  page_start = start - (start % GRUB_EFIEMU_PAGESIZE);
+  npages = (size + (start % GRUB_EFIEMU_PAGESIZE) + GRUB_EFIEMU_PAGESIZE - 1)
+    / GRUB_EFIEMU_PAGESIZE;
+  efiemu_mmap[mmap_num].physical_start = page_start;
+  efiemu_mmap[mmap_num].virtual_start = page_start;
+  efiemu_mmap[mmap_num].num_pages = npages;
+  efiemu_mmap[mmap_num].type = type;
+  mmap_num++;
+
+  return GRUB_ERR_NONE;
+}
+
+/* Request a resident memory of type TYPE of size SIZE aligned at ALIGN
+   ALIGN must be a divisor of page size (if it's a divisor of 4096
+   it should be ok on all platforms)
+ */
+int
+grub_efiemu_request_memalign (grub_size_t align, grub_size_t size,
+                             grub_efi_memory_type_t type)
+{
+  grub_size_t align_overhead;
+  struct grub_efiemu_memrequest *ret, *cur, *prev;
+  /* Check that the request is correct */
+  if (type >= GRUB_EFI_MAX_MEMORY_TYPE || type <= GRUB_EFI_LOADER_CODE)
+    return -2;
+
+  /* Add new size to requested size */
+  align_overhead = align - (requested_memory[type]%align);
+  if (align_overhead == align)
+    align_overhead = 0;
+  requested_memory[type] += align_overhead + size;
+
+  /* Remember the request */
+  ret = grub_zalloc (sizeof (*ret));
+  if (!ret)
+    return -1;
+  ret->type = type;
+  ret->size = size;
+  ret->align_overhead = align_overhead;
+  prev = 0;
+
+  /* Add request to the end of the chain.
+     It should be at the end because otherwise alignment isn't guaranteed */
+  for (cur = memrequests; cur; prev = cur, cur = cur->next);
+  if (prev)
+    {
+      ret->handle = prev->handle + 1;
+      prev->next = ret;
+    }
+  else
+    {
+      ret->handle = 1; /* Avoid 0 handle*/
+      memrequests = ret;
+    }
+  return ret->handle;
+}
+
+/* Really allocate the memory */
+static grub_err_t
+efiemu_alloc_requests (void)
+{
+  grub_size_t align_overhead = 0;
+  grub_uint8_t *curptr, *typestart;
+  struct grub_efiemu_memrequest *cur;
+  grub_size_t total_alloc = 0;
+  unsigned i;
+  /* Order of memory regions */
+  grub_efi_memory_type_t reqorder[] =
+    {
+      /* First come regions usable by OS*/
+      GRUB_EFI_LOADER_CODE,
+      GRUB_EFI_LOADER_DATA,
+      GRUB_EFI_BOOT_SERVICES_CODE,
+      GRUB_EFI_BOOT_SERVICES_DATA,
+      GRUB_EFI_CONVENTIONAL_MEMORY,
+      GRUB_EFI_ACPI_RECLAIM_MEMORY,
+
+      /* Then memory used by runtime */
+      /* This way all our regions are in a single block */
+      GRUB_EFI_RUNTIME_SERVICES_CODE,
+      GRUB_EFI_RUNTIME_SERVICES_DATA,
+      GRUB_EFI_ACPI_MEMORY_NVS,
+
+      /* And then unavailable memory types. This is more for a completeness.
+        You should double think before allocating memory of any of these types
+       */
+      GRUB_EFI_UNUSABLE_MEMORY,
+      GRUB_EFI_MEMORY_MAPPED_IO,
+      GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE,
+      GRUB_EFI_PAL_CODE
+    };
+
+  /* Compute total memory needed */
+  for (i = 0; i < sizeof (reqorder) / sizeof (reqorder[0]); i++)
+    {
+      align_overhead = GRUB_EFIEMU_PAGESIZE
+       - (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE);
+      if (align_overhead == GRUB_EFIEMU_PAGESIZE)
+       align_overhead = 0;
+      total_alloc += requested_memory[reqorder[i]] + align_overhead;
+    }
+
+  /* Allocate the whole memory in one block */
+  resident_memory = grub_memalign (GRUB_EFIEMU_PAGESIZE, total_alloc);
+  if (!resident_memory)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                      "couldn't allocate resident memory");
+
+  /* Split the memory into blocks by type */
+  curptr = resident_memory;
+  for (i = 0; i < sizeof (reqorder) / sizeof (reqorder[0]); i++)
+    {
+      if (!requested_memory[reqorder[i]])
+       continue;
+      typestart = curptr;
+
+      /* Write pointers to requests */
+      for (cur = memrequests; cur; cur = cur->next)
+       if (cur->type == reqorder[i])
+         {
+           curptr = ((grub_uint8_t *)curptr) + cur->align_overhead;
+           cur->val = curptr;
+           curptr = ((grub_uint8_t *)curptr) + cur->size;
+         }
+
+      /* Ensure that the regions are page-aligned */
+      align_overhead = GRUB_EFIEMU_PAGESIZE
+       - (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE);
+      if (align_overhead == GRUB_EFIEMU_PAGESIZE)
+       align_overhead = 0;
+      curptr = ((grub_uint8_t *)curptr) + align_overhead;
+
+      /* Add the region to memory map */
+      grub_efiemu_add_to_mmap (PTR_TO_UINT64 (typestart),
+                              curptr - typestart, reqorder[i]);
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Get a pointer to requested memory from handle */
+void *
+grub_efiemu_mm_obtain_request (int handle)
+{
+  struct grub_efiemu_memrequest *cur;
+  for (cur = memrequests; cur; cur = cur->next)
+    if (cur->handle == handle)
+      return cur->val;
+  return 0;
+}
+
+/* Get type of requested memory by handle */
+grub_efi_memory_type_t
+grub_efiemu_mm_get_type (int handle)
+{
+  struct grub_efiemu_memrequest *cur;
+  for (cur = memrequests; cur; cur = cur->next)
+    if (cur->handle == handle)
+      return cur->type;
+  return 0;
+}
+
+/* Free a request */
+void
+grub_efiemu_mm_return_request (int handle)
+{
+  struct grub_efiemu_memrequest *cur, *prev;
+
+  /* Remove head if necessary */
+  while (memrequests && memrequests->handle == handle)
+    {
+      cur = memrequests->next;
+      grub_free (memrequests);
+      memrequests = cur;
+    }
+  if (!memrequests)
+    return;
+
+  /* Remove request from a middle of chain*/
+  for (prev = memrequests, cur = prev->next; cur;)
+    if (cur->handle == handle)
+      {
+       prev->next = cur->next;
+       grub_free (cur);
+       cur = prev->next;
+      }
+    else
+      {
+       prev = cur;
+       cur = prev->next;
+      }
+}
+
+/* Reserve space for memory map */
+static grub_err_t
+grub_efiemu_mmap_init (void)
+{
+  auto int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t, grub_uint64_t,
+                                        grub_uint32_t);
+  int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t addr __attribute__ ((unused)),
+                                   grub_uint64_t size __attribute__ ((unused)),
+                                   grub_uint32_t type __attribute__ ((unused)))
+    {
+      mmap_reserved_size++;
+      return 0;
+    }
+
+  // the place for memory used by efiemu itself
+  mmap_reserved_size = GRUB_EFI_MAX_MEMORY_TYPE + 1;
+
+#ifndef GRUB_MACHINE_EMU
+  grub_machine_mmap_iterate (bounds_hook);
+#endif
+
+  return GRUB_ERR_NONE;
+}
+
+/* This is a drop-in replacement of grub_efi_get_memory_map */
+/* Get the memory map as defined in the EFI spec. Return 1 if successful,
+   return 0 if partial, or return -1 if an error occurs.  */
+int
+grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size,
+                           grub_efi_memory_descriptor_t *memory_map,
+                           grub_efi_uintn_t *map_key,
+                           grub_efi_uintn_t *descriptor_size,
+                           grub_efi_uint32_t *descriptor_version)
+{
+  if (!efiemu_mmap)
+    {
+      grub_error (GRUB_ERR_INVALID_COMMAND,
+                 "you need to first launch efiemu_prepare");
+      return -1;
+    }
+
+  if (*memory_map_size < mmap_num * sizeof (grub_efi_memory_descriptor_t))
+    {
+      *memory_map_size = mmap_num * sizeof (grub_efi_memory_descriptor_t);
+      return 0;
+    }
+
+  *memory_map_size = mmap_num * sizeof (grub_efi_memory_descriptor_t);
+  grub_memcpy (memory_map, efiemu_mmap, *memory_map_size);
+  if (descriptor_size)
+    *descriptor_size = sizeof (grub_efi_memory_descriptor_t);
+  if (descriptor_version)
+    *descriptor_version = 1;
+  if (map_key)
+    *map_key = 0;
+
+  return 1;
+}
+
+/* Free everything */
+grub_err_t
+grub_efiemu_mm_unload (void)
+{
+  struct grub_efiemu_memrequest *cur, *d;
+  for (cur = memrequests; cur;)
+    {
+      d = cur->next;
+      grub_free (cur);
+      cur = d;
+    }
+  memrequests = 0;
+  grub_memset (&requested_memory, 0, sizeof (requested_memory));
+  grub_free (resident_memory);
+  resident_memory = 0;
+  grub_free (efiemu_mmap);
+  efiemu_mmap = 0;
+  mmap_reserved_size = mmap_num = 0;
+  return GRUB_ERR_NONE;
+}
+
+/* This function should be called before doing any requests */
+grub_err_t
+grub_efiemu_mm_init (void)
+{
+  grub_err_t err;
+
+  err = grub_efiemu_mm_unload ();
+  if (err)
+    return err;
+
+  grub_efiemu_mmap_init ();
+
+  return GRUB_ERR_NONE;
+}
+
+/* Copy host memory map */
+static grub_err_t
+grub_efiemu_mmap_fill (void)
+{
+  auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr,
+                                 grub_uint64_t size,
+                                 grub_uint32_t type)
+    {
+      switch (type)
+       {
+       case GRUB_MACHINE_MEMORY_AVAILABLE:
+         return grub_efiemu_add_to_mmap (addr, size,
+                                         GRUB_EFI_CONVENTIONAL_MEMORY);
+
+#ifdef GRUB_MACHINE_MEMORY_ACPI
+       case GRUB_MACHINE_MEMORY_ACPI:
+         return grub_efiemu_add_to_mmap (addr, size,
+                                         GRUB_EFI_ACPI_RECLAIM_MEMORY);
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_NVS
+       case GRUB_MACHINE_MEMORY_NVS:
+         return grub_efiemu_add_to_mmap (addr, size,
+                                         GRUB_EFI_ACPI_MEMORY_NVS);
+#endif
+
+       default:
+         grub_printf ("Unknown memory type %d. Marking as unusable\n", type);
+       case GRUB_MACHINE_MEMORY_RESERVED:
+         return grub_efiemu_add_to_mmap (addr, size,
+                                         GRUB_EFI_UNUSABLE_MEMORY);
+       }
+    }
+
+#ifndef GRUB_MACHINE_EMU
+  grub_machine_mmap_iterate (fill_hook);
+#endif
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+                                                       grub_uint64_t,
+                                                       grub_uint32_t))
+{
+  unsigned i;
+
+  for (i = 0; i < (unsigned) mmap_num; i++)
+    switch (efiemu_mmap[i].type)
+      {
+      case GRUB_EFI_RUNTIME_SERVICES_CODE:
+       hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
+             GRUB_EFIEMU_MEMORY_CODE);
+       break;
+
+      case GRUB_EFI_RESERVED_MEMORY_TYPE:
+      case GRUB_EFI_RUNTIME_SERVICES_DATA:
+      case GRUB_EFI_UNUSABLE_MEMORY:
+      case GRUB_EFI_MEMORY_MAPPED_IO:
+      case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+      case GRUB_EFI_PAL_CODE:
+      case GRUB_EFI_MAX_MEMORY_TYPE:
+       hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
+             GRUB_EFIEMU_MEMORY_RESERVED);
+       break;
+
+      case GRUB_EFI_LOADER_CODE:
+      case GRUB_EFI_LOADER_DATA:
+      case GRUB_EFI_BOOT_SERVICES_CODE:
+      case GRUB_EFI_BOOT_SERVICES_DATA:
+      case GRUB_EFI_CONVENTIONAL_MEMORY:
+       hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
+             GRUB_EFIEMU_MEMORY_AVAILABLE);
+       break;
+
+      case GRUB_EFI_ACPI_RECLAIM_MEMORY:
+       hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
+             GRUB_EFIEMU_MEMORY_ACPI);
+       break;
+
+      case GRUB_EFI_ACPI_MEMORY_NVS:
+       hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
+             GRUB_EFIEMU_MEMORY_NVS);
+       break;
+      }
+
+  return 0;
+}
+
+
+/* This function resolves overlapping regions and sorts the memory map
+   It uses scanline (sweeping) algorithm
+ */
+static grub_err_t
+grub_efiemu_mmap_sort_and_uniq (void)
+{
+  /* If same page is used by multiple types it's resolved
+     according to priority
+     0 - free memory
+     1 - memory immediately usable after ExitBootServices
+     2 - memory usable after loading ACPI tables
+     3 - efiemu memory
+     4 - unusable memory
+  */
+  int priority[GRUB_EFI_MAX_MEMORY_TYPE] =
+    {
+      [GRUB_EFI_RESERVED_MEMORY_TYPE] = 4,
+      [GRUB_EFI_LOADER_CODE] = 1,
+      [GRUB_EFI_LOADER_DATA] = 1,
+      [GRUB_EFI_BOOT_SERVICES_CODE] = 1,
+      [GRUB_EFI_BOOT_SERVICES_DATA] = 1,
+      [GRUB_EFI_RUNTIME_SERVICES_CODE] = 3,
+      [GRUB_EFI_RUNTIME_SERVICES_DATA] = 3,
+      [GRUB_EFI_CONVENTIONAL_MEMORY] = 0,
+      [GRUB_EFI_UNUSABLE_MEMORY] = 4,
+      [GRUB_EFI_ACPI_RECLAIM_MEMORY] = 2,
+      [GRUB_EFI_ACPI_MEMORY_NVS] = 3,
+      [GRUB_EFI_MEMORY_MAPPED_IO] = 4,
+      [GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE] = 4,
+      [GRUB_EFI_PAL_CODE] = 4
+    };
+
+  int i, j, k, done;
+
+  /* Scanline events */
+  struct grub_efiemu_mmap_scan
+  {
+    /* At which memory address*/
+    grub_uint64_t pos;
+    /* 0 = region starts, 1 = region ends */
+    int type;
+    /* Which type of memory region */
+    grub_efi_memory_type_t memtype;
+  };
+  struct grub_efiemu_mmap_scan *scanline_events;
+  struct grub_efiemu_mmap_scan t;
+
+  /* Previous scanline event */
+  grub_uint64_t lastaddr;
+  int lasttype;
+  /* Current scanline event */
+  int curtype;
+  /* how many regions of given type overlap at current location */
+  int present[GRUB_EFI_MAX_MEMORY_TYPE];
+  /* Here is stored the resulting memory map*/
+  grub_efi_memory_descriptor_t *result;
+
+  /* Initialize variables*/
+  grub_memset (present, 0, sizeof (int) * GRUB_EFI_MAX_MEMORY_TYPE);
+  scanline_events = (struct grub_efiemu_mmap_scan *)
+    grub_malloc (sizeof (struct grub_efiemu_mmap_scan) * 2 * mmap_num);
+
+  /* Number of chunks can't increase more than by factor of 2 */
+  result = (grub_efi_memory_descriptor_t *)
+    grub_malloc (sizeof (grub_efi_memory_descriptor_t) * 2 * mmap_num);
+  if (!result || !scanline_events)
+    {
+      grub_free (result);
+      grub_free (scanline_events);
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                        "couldn't allocate space for new memory map");
+    }
+
+  /* Register scanline events */
+  for (i = 0; i < mmap_num; i++)
+    {
+      scanline_events[2 * i].pos = efiemu_mmap[i].physical_start;
+      scanline_events[2 * i].type = 0;
+      scanline_events[2 * i].memtype = efiemu_mmap[i].type;
+      scanline_events[2 * i + 1].pos = efiemu_mmap[i].physical_start
+       + efiemu_mmap[i].num_pages * GRUB_EFIEMU_PAGESIZE;
+      scanline_events[2 * i + 1].type = 1;
+      scanline_events[2 * i + 1].memtype = efiemu_mmap[i].type;
+    }
+
+  /* Primitive bubble sort. It has complexity O(n^2) but since we're
+     unlikely to have more than 100 chunks it's probably one of the
+     fastest for one purpose */
+  done = 1;
+  while (done)
+    {
+      done = 0;
+      for (i = 0; i < 2 * mmap_num - 1; i++)
+       if (scanline_events[i + 1].pos < scanline_events[i].pos)
+         {
+           t = scanline_events[i + 1];
+           scanline_events[i + 1] = scanline_events[i];
+           scanline_events[i] = t;
+           done = 1;
+         }
+    }
+
+  /* Pointer in resulting memory map */
+  j = 0;
+  lastaddr = scanline_events[0].pos;
+  lasttype = scanline_events[0].memtype;
+  for (i = 0; i < 2 * mmap_num; i++)
+    {
+      /* Process event */
+      if (scanline_events[i].type)
+       present[scanline_events[i].memtype]--;
+      else
+       present[scanline_events[i].memtype]++;
+
+      /* Determine current region type */
+      curtype = -1;
+      for (k = 0; k < GRUB_EFI_MAX_MEMORY_TYPE; k++)
+       if (present[k] && (curtype == -1 || priority[k] > priority[curtype]))
+         curtype = k;
+
+      /* Add memory region to resulting map if necessary */
+      if ((curtype == -1 || curtype != lasttype)
+         && lastaddr != scanline_events[i].pos
+         && lasttype != -1)
+       {
+         result[j].virtual_start = result[j].physical_start = lastaddr;
+         result[j].num_pages = (scanline_events[i].pos - lastaddr)
+           / GRUB_EFIEMU_PAGESIZE;
+         result[j].type = lasttype;
+
+         /* We set runtime attribute on pages we need to be mapped */
+         result[j].attribute
+           = (lasttype == GRUB_EFI_RUNTIME_SERVICES_CODE
+                  || lasttype == GRUB_EFI_RUNTIME_SERVICES_DATA)
+           ? GRUB_EFI_MEMORY_RUNTIME : 0;
+         grub_dprintf ("efiemu",
+                       "mmap entry: type %d start 0x%llx 0x%llx pages\n",
+                       result[j].type,
+                       result[j].physical_start, result[j].num_pages);
+         j++;
+       }
+
+      /* Update last values if necessary */
+      if (curtype == -1 || curtype != lasttype)
+       {
+         lasttype = curtype;
+         lastaddr = scanline_events[i].pos;
+       }
+    }
+
+  grub_free (scanline_events);
+
+  /* Shrink resulting memory map to really used size and replace efiemu_mmap
+     by new value */
+  grub_free (efiemu_mmap);
+  efiemu_mmap = grub_realloc (result, j * sizeof (*result));
+  return GRUB_ERR_NONE;
+}
+
+/* This function is called to switch from first to second phase */
+grub_err_t
+grub_efiemu_mm_do_alloc (void)
+{
+  grub_err_t err;
+
+  /* Preallocate mmap */
+  efiemu_mmap = (grub_efi_memory_descriptor_t *)
+    grub_malloc (mmap_reserved_size * sizeof (grub_efi_memory_descriptor_t));
+  if (!efiemu_mmap)
+    {
+      grub_efiemu_unload ();
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't initialize mmap");
+    }
+
+  if ((err = efiemu_alloc_requests ()))
+    return err;
+  if ((err = grub_efiemu_mmap_fill ()))
+    return err;
+  return grub_efiemu_mmap_sort_and_uniq ();
+}
diff --git a/grub-core/efiemu/pnvram.c b/grub-core/efiemu/pnvram.c
new file mode 100644 (file)
index 0000000..e58fce8
--- /dev/null
@@ -0,0 +1,280 @@
+/* Export pnvram and some variables for runtime */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/charset.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/efiemu/runtime.h>
+#include <grub/extcmd.h>
+
+/* Place for final location of variables */
+static int nvram_handle = 0;
+static int nvramsize_handle = 0;
+static int high_monotonic_count_handle = 0;
+static int timezone_handle = 0;
+static int accuracy_handle = 0;
+static int daylight_handle = 0;
+
+static grub_size_t nvramsize;
+
+/* Parse signed value */
+static int
+grub_strtosl (const char *arg, char **end, int base)
+{
+  if (arg[0] == '-')
+    return -grub_strtoul (arg + 1, end, base);
+  return grub_strtoul (arg, end, base);
+}
+
+static inline int
+hextoval (char c)
+{
+  if (c >= '0' && c <= '9')
+    return c - '0';
+  if (c >= 'a' && c <= 'z')
+    return c - 'a' + 10;
+  if (c >= 'A' && c <= 'Z')
+    return c - 'A' + 10;
+  return 0;
+}
+
+static inline grub_err_t
+unescape (char *in, char *out, char *outmax, int *len)
+{
+  char *ptr, *dptr;
+  dptr = out;
+  for (ptr = in; *ptr && dptr < outmax; )
+    if (*ptr == '%' && ptr[1] && ptr[2])
+      {
+       *dptr = (hextoval (ptr[1]) << 4) | (hextoval (ptr[2]));
+       ptr += 3;
+       dptr++;
+      }
+    else
+      {
+       *dptr = *ptr;
+       ptr++;
+       dptr++;
+      }
+  if (dptr == outmax)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                      "too many NVRAM variables for reserved variable space."
+                      " Try increasing EfiEmu.pnvram.size");
+  *len = dptr - out;
+  return 0;
+}
+
+/* Export stuff for efiemu */
+static grub_err_t
+nvram_set (void * data __attribute__ ((unused)))
+{
+  const char *env;
+  /* Take definitive pointers */
+  char *nvram = grub_efiemu_mm_obtain_request (nvram_handle);
+  grub_uint32_t *nvramsize_def
+    = grub_efiemu_mm_obtain_request (nvramsize_handle);
+  grub_uint32_t *high_monotonic_count
+    = grub_efiemu_mm_obtain_request (high_monotonic_count_handle);
+  grub_int16_t *timezone
+    = grub_efiemu_mm_obtain_request (timezone_handle);
+  grub_uint8_t *daylight
+    = grub_efiemu_mm_obtain_request (daylight_handle);
+  grub_uint32_t *accuracy
+    = grub_efiemu_mm_obtain_request (accuracy_handle);
+  char *nvramptr;
+
+  auto int iterate_env (struct grub_env_var *var);
+  int iterate_env (struct grub_env_var *var)
+  {
+    char *guid, *attr, *name, *varname;
+    struct efi_variable *efivar;
+    int len = 0;
+    int i;
+    grub_uint64_t guidcomp;
+
+    if (grub_memcmp (var->name, "EfiEmu.pnvram.",
+                    sizeof ("EfiEmu.pnvram.") - 1) != 0)
+      return 0;
+
+    guid = var->name + sizeof ("EfiEmu.pnvram.") - 1;
+
+    attr = grub_strchr (guid, '.');
+    if (!attr)
+      return 0;
+    attr++;
+
+    name = grub_strchr (attr, '.');
+    if (!name)
+      return 0;
+    name++;
+
+    efivar = (struct efi_variable *) nvramptr;
+    if (nvramptr - nvram + sizeof (struct efi_variable) > nvramsize)
+      {
+       grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                   "too many NVRAM variables for reserved variable space."
+                   " Try increasing EfiEmu.pnvram.size");
+       return 1;
+      }
+
+    nvramptr += sizeof (struct efi_variable);
+
+    efivar->guid.data1 = grub_cpu_to_le32 (grub_strtoul (guid, &guid, 16));
+    if (*guid != '-')
+      return 0;
+    guid++;
+
+    efivar->guid.data2 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16));
+    if (*guid != '-')
+      return 0;
+    guid++;
+
+    efivar->guid.data3 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16));
+    if (*guid != '-')
+      return 0;
+    guid++;
+
+    guidcomp = grub_strtoull (guid, 0, 16);
+    for (i = 0; i < 8; i++)
+      efivar->guid.data4[i] = (guidcomp >> (56 - 8 * i)) & 0xff;
+
+    efivar->attributes = grub_strtoull (attr, 0, 16);
+
+    varname = grub_malloc (grub_strlen (name) + 1);
+    if (! varname)
+      return 1;
+
+    if (unescape (name, varname, varname + grub_strlen (name) + 1, &len))
+      return 1;
+
+    len = grub_utf8_to_utf16 ((grub_uint16_t *) nvramptr,
+                             (nvramsize - (nvramptr - nvram)) / 2,
+                             (grub_uint8_t *) varname, len, NULL);
+
+    if (len < 0)
+      {
+       grub_error (GRUB_ERR_BAD_ARGUMENT, "broken UTF-8 in variable name");
+       return 1;
+      }
+
+    nvramptr += 2 * len;
+    *((grub_uint16_t *) nvramptr) = 0;
+    nvramptr += 2;
+    efivar->namelen = 2 * len + 2;
+
+    if (unescape (var->value, nvramptr, nvram + nvramsize, &len))
+      {
+       efivar->namelen = 0;
+       return 1;
+      }
+
+    nvramptr += len;
+
+    efivar->size = len;
+
+    return 0;
+  }
+
+  /* Copy to definitive loaction */
+  grub_dprintf ("efiemu", "preparing pnvram\n");
+
+  env = grub_env_get ("EfiEmu.pnvram.high_monotonic_count");
+  *high_monotonic_count = env ? grub_strtoul (env, 0, 0) : 1;
+  env = grub_env_get ("EfiEmu.pnvram.timezone");
+  *timezone = env ? grub_strtosl (env, 0, 0) : GRUB_EFI_UNSPECIFIED_TIMEZONE;
+  env = grub_env_get ("EfiEmu.pnvram.accuracy");
+  *accuracy = env ? grub_strtoul (env, 0, 0) : 50000000;
+  env = grub_env_get ("EfiEmu.pnvram.daylight");
+  *daylight = env ? grub_strtoul (env, 0, 0) : 0;
+
+  nvramptr = nvram;
+  grub_memset (nvram, 0, nvramsize);
+  grub_env_iterate (iterate_env);
+  if (grub_errno)
+    return grub_errno;
+  *nvramsize_def = nvramsize;
+
+  /* Register symbols */
+  grub_efiemu_register_symbol ("efiemu_variables", nvram_handle, 0);
+  grub_efiemu_register_symbol ("efiemu_varsize", nvramsize_handle, 0);
+  grub_efiemu_register_symbol ("efiemu_high_monotonic_count",
+                              high_monotonic_count_handle, 0);
+  grub_efiemu_register_symbol ("efiemu_time_zone", timezone_handle, 0);
+  grub_efiemu_register_symbol ("efiemu_time_daylight", daylight_handle, 0);
+  grub_efiemu_register_symbol ("efiemu_time_accuracy",
+                              accuracy_handle, 0);
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+nvram_unload (void * data __attribute__ ((unused)))
+{
+  grub_efiemu_mm_return_request (nvram_handle);
+  grub_efiemu_mm_return_request (nvramsize_handle);
+  grub_efiemu_mm_return_request (high_monotonic_count_handle);
+  grub_efiemu_mm_return_request (timezone_handle);
+  grub_efiemu_mm_return_request (accuracy_handle);
+  grub_efiemu_mm_return_request (daylight_handle);
+}
+
+grub_err_t
+grub_efiemu_pnvram (void)
+{
+  const char *size;
+  grub_err_t err;
+
+  nvramsize = 0;
+
+  size = grub_env_get ("EfiEmu.pnvram.size");
+  if (size)
+    nvramsize = grub_strtoul (size, 0, 0);
+
+  if (!nvramsize)
+    nvramsize = 2048;
+
+  err = grub_efiemu_register_prepare_hook (nvram_set, nvram_unload, 0);
+  if (err)
+    return err;
+
+  nvram_handle
+    = grub_efiemu_request_memalign (1, nvramsize,
+                                   GRUB_EFI_RUNTIME_SERVICES_DATA);
+  nvramsize_handle
+    = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
+                                   GRUB_EFI_RUNTIME_SERVICES_DATA);
+  high_monotonic_count_handle
+    = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
+                                   GRUB_EFI_RUNTIME_SERVICES_DATA);
+  timezone_handle
+    = grub_efiemu_request_memalign (1, sizeof (grub_uint16_t),
+                                   GRUB_EFI_RUNTIME_SERVICES_DATA);
+  daylight_handle
+    = grub_efiemu_request_memalign (1, sizeof (grub_uint8_t),
+                                   GRUB_EFI_RUNTIME_SERVICES_DATA);
+  accuracy_handle
+    = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
+                                   GRUB_EFI_RUNTIME_SERVICES_DATA);
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/efiemu/prepare.c b/grub-core/efiemu/prepare.c
new file mode 100644 (file)
index 0000000..6202600
--- /dev/null
@@ -0,0 +1,153 @@
+/* Prepare efiemu. E.g. allocate memory, load the runtime
+   to appropriate place, etc */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/lib/crc.h>
+
+grub_err_t
+SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks,
+                             struct grub_efiemu_configuration_table
+                             *config_tables)
+{
+  grub_err_t err;
+  int conftable_handle;
+  struct grub_efiemu_configuration_table *cur;
+  struct grub_efiemu_prepare_hook *curhook;
+
+  int cntconftables = 0;
+  struct SUFFIX (grub_efiemu_configuration_table) *conftables = 0;
+  int i;
+  int handle;
+  grub_off_t off;
+
+  grub_dprintf ("efiemu", "Preparing EfiEmu\n");
+
+  /* Request space for the list of configuration tables */
+  for (cur = config_tables; cur; cur = cur->next)
+    cntconftables++;
+  conftable_handle
+    = grub_efiemu_request_memalign (GRUB_EFIEMU_PAGESIZE,
+                                   cntconftables * sizeof (*conftables),
+                                   GRUB_EFI_RUNTIME_SERVICES_DATA);
+
+  /* Switch from phase 1 (counting) to phase 2 (real job) */
+  grub_efiemu_alloc_syms ();
+  grub_efiemu_mm_do_alloc ();
+  grub_efiemu_write_sym_markers ();
+
+  grub_efiemu_system_table32 = 0;
+  grub_efiemu_system_table64 = 0;
+
+  /* Execute hooks */
+  for (curhook = prepare_hooks; curhook; curhook = curhook->next)
+    curhook->hook (curhook->data);
+
+  /* Move runtime to its due place */
+  err = grub_efiemu_loadcore_load ();
+  if (err)
+    {
+      grub_efiemu_unload ();
+      return err;
+    }
+
+  err = grub_efiemu_resolve_symbol ("efiemu_system_table", &handle, &off);
+  if (err)
+    {
+      grub_efiemu_unload ();
+      return err;
+    }
+
+  SUFFIX (grub_efiemu_system_table)
+    = (struct SUFFIX (grub_efi_system_table) *)
+    ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off);
+
+  /* Put pointer to the list of configuration tables in system table */
+  grub_efiemu_write_value
+    (&(SUFFIX (grub_efiemu_system_table)->configuration_table), 0,
+     conftable_handle, 0, 1,
+     sizeof (SUFFIX (grub_efiemu_system_table)->configuration_table));
+  SUFFIX(grub_efiemu_system_table)->num_table_entries = cntconftables;
+
+  /* Fill the list of configuration tables */
+  conftables = (struct SUFFIX (grub_efiemu_configuration_table) *)
+    grub_efiemu_mm_obtain_request (conftable_handle);
+  i = 0;
+  for (cur = config_tables; cur; cur = cur->next, i++)
+    {
+      grub_memcpy (&(conftables[i].vendor_guid), &(cur->guid),
+                      sizeof (cur->guid));
+      if (cur->get_table)
+       conftables[i].vendor_table
+         = PTR_TO_UINT64 (cur->get_table (cur->data));
+      else
+       conftables[i].vendor_table = PTR_TO_UINT64 (cur->data);
+    }
+
+  err = SUFFIX (grub_efiemu_crc) ();
+  if (err)
+    {
+      grub_efiemu_unload ();
+      return err;
+    }
+
+  grub_dprintf ("efiemu","system_table = %p, conftables = %p (%d entries)\n",
+               SUFFIX (grub_efiemu_system_table), conftables, cntconftables);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+SUFFIX (grub_efiemu_crc) (void)
+{
+  grub_err_t err;
+  int handle;
+  grub_off_t off;
+  struct SUFFIX (grub_efiemu_runtime_services) *runtime_services;
+
+  /* compute CRC32 of runtime_services */
+  err = grub_efiemu_resolve_symbol ("efiemu_runtime_services",
+                                   &handle, &off);
+  if (err)
+    return err;
+
+  runtime_services = (struct SUFFIX (grub_efiemu_runtime_services) *)
+       ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off);
+  runtime_services->hdr.crc32 = 0;
+  runtime_services->hdr.crc32 = grub_getcrc32
+    (0, runtime_services, runtime_services->hdr.header_size);
+
+  err = grub_efiemu_resolve_symbol ("efiemu_system_table", &handle, &off);
+  if (err)
+    return err;
+
+  /* compute CRC32 of system table */
+  SUFFIX (grub_efiemu_system_table)->hdr.crc32 = 0;
+  SUFFIX (grub_efiemu_system_table)->hdr.crc32
+    = grub_getcrc32 (0, SUFFIX (grub_efiemu_system_table),
+                    SUFFIX (grub_efiemu_system_table)->hdr.header_size);
+
+  grub_dprintf ("efiemu","system_table = %p, runtime_services = %p\n",
+               SUFFIX (grub_efiemu_system_table), runtime_services);
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/efiemu/prepare32.c b/grub-core/efiemu/prepare32.c
new file mode 100644 (file)
index 0000000..fd6109e
--- /dev/null
@@ -0,0 +1,22 @@
+/* This file contains definitions so that prepare.c compiles for 32-bit */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define SUFFIX(x) x ## 32
+
+#include "prepare.c"
diff --git a/grub-core/efiemu/prepare64.c b/grub-core/efiemu/prepare64.c
new file mode 100644 (file)
index 0000000..811f558
--- /dev/null
@@ -0,0 +1,22 @@
+/* This file contains definitions so that prepare.c compiles for 64-bit */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define SUFFIX(x) x ## 64
+
+#include "prepare.c"
diff --git a/grub-core/efiemu/runtime/config.h b/grub-core/efiemu/runtime/config.h
new file mode 100644 (file)
index 0000000..26fb2ff
--- /dev/null
@@ -0,0 +1,34 @@
+/* This is a pseudo config.h so that types.h compiles nicely */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define GRUB_TYPES_CPU_HEADER  1
+
+#ifdef ELF32
+# define SIZEOF_VOID_P 4
+# define SIZEOF_LONG   4
+# define GRUB_TARGET_SIZEOF_VOID_P     4
+# define GRUB_TARGET_SIZEOF_LONG       4
+# define EFI_FUNC(x) x
+#else
+# define SIZEOF_VOID_P 8
+# define SIZEOF_LONG   8
+# define GRUB_TARGET_SIZEOF_VOID_P     8
+# define GRUB_TARGET_SIZEOF_LONG       8
+# define EFI_FUNC(x) x ## _real
+#endif
diff --git a/grub-core/efiemu/runtime/efiemu.S b/grub-core/efiemu/runtime/efiemu.S
new file mode 100644 (file)
index 0000000..b502314
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+/*
+ * x86_64 uses registry to pass parameters. Unfortunately, gcc and efi use
+ * different call conversion, so we need to do some conversion.
+ *
+ * gcc:
+ *   %rdi,  %rsi,  %rdx,  %rcx, %r8, %r9, 8(%rsp), 16(%rsp), ...
+ *
+ * efi:
+ *   %rcx,  %rdx,  %r8,  %r9,  32(%rsp), 40(%rsp), 48(%rsp), ...
+ *
+ */
+
+        .file   "efiemu.S"
+       .text
+
+FUNCTION (efiemu_get_time)
+       push %rdi
+       push %rsi
+       mov %rcx, %rdi
+       mov %rdx, %rsi
+       call efiemu_get_time_real
+       pop %rsi
+       pop %rdi
+       ret
+
+FUNCTION (efiemu_set_time)
+       push %rdi
+       push %rsi
+       mov %rcx, %rdi
+       call efiemu_set_time_real
+       pop %rsi
+       pop %rdi
+       ret
+
+
+FUNCTION (efiemu_get_wakeup_time)
+       push %rdi
+       push %rsi
+       mov %rcx, %rdi
+       mov %rdx, %rsi
+       mov %r8, %rdx
+       call efiemu_get_wakeup_time_real
+       pop %rsi
+       pop %rdi
+       ret
+
+FUNCTION (efiemu_set_wakeup_time)
+       push %rdi
+       push %rsi
+       mov %rcx, %rdi
+       mov %rdx, %rsi
+       call efiemu_set_wakeup_time_real
+       pop %rsi
+       pop %rdi
+       ret
+
+FUNCTION (efiemu_get_variable)
+       push %rdi
+       push %rsi
+       mov %rcx, %rdi
+       mov %rdx, %rsi
+       mov %r8, %rdx
+       mov %r9, %rcx
+       mov 56(%rsp), %r8
+       call efiemu_get_variable_real
+       pop %rsi
+       pop %rdi
+       ret
+
+FUNCTION (efiemu_get_next_variable_name)
+       push %rdi
+       push %rsi
+       mov %rcx, %rdi
+       mov %rdx, %rsi
+       mov %r8, %rdx
+       call efiemu_get_next_variable_name_real
+       pop %rsi
+       pop %rdi
+       ret
+
+FUNCTION (efiemu_set_variable)
+       push %rdi
+       push %rsi
+       mov %rcx, %rdi
+       mov %rdx, %rsi
+       mov %r8, %rdx
+       mov %r9, %rcx
+       mov 56(%rsp), %r8
+       call efiemu_set_variable_real
+       pop %rsi
+       pop %rdi
+       ret
+
+FUNCTION (efiemu_get_next_high_monotonic_count)
+       push %rdi
+       push %rsi
+       mov %rcx, %rdi
+       call efiemu_get_next_high_monotonic_count_real
+       pop %rsi
+       pop %rdi
+       ret
+
+FUNCTION (efiemu_reset_system)
+       push %rdi
+       push %rsi
+       mov %rcx, %rdi
+       mov %rdx, %rsi
+       mov %r8, %rdx
+       mov %r9, %rcx
+       call efiemu_reset_system_real
+       pop %rsi
+       pop %rdi
+       ret
+
+       /* The following functions are always called in physical mode */
+       .section ".text-physical", "ax"
+
+FUNCTION (efiemu_set_virtual_address_map)
+       push %rdi
+       push %rsi
+       mov %rcx, %rdi
+       mov %rdx, %rsi
+       mov %r8, %rdx
+       mov %r9, %rcx
+       call efiemu_set_virtual_address_map_real
+       pop %rsi
+       pop %rdi
+       ret
+
+FUNCTION (efiemu_convert_pointer)
+       push %rdi
+       push %rsi
+       mov %rcx, %rdi
+       mov %rdx, %rsi
+       call efiemu_convert_pointer_real
+       pop %rsi
+       pop %rdi
+       ret
+
diff --git a/grub-core/efiemu/runtime/efiemu.c b/grub-core/efiemu/runtime/efiemu.c
new file mode 100644 (file)
index 0000000..7389341
--- /dev/null
@@ -0,0 +1,630 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This is an emulation of EFI runtime services.
+   This allows a more uniform boot on i386 machines.
+   As it emulates only runtime serviceit isn't able
+   to chainload EFI bootloader on non-EFI system (TODO) */
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/efi/api.h>
+#include <grub/efiemu/runtime.h>
+
+grub_efi_status_t
+efiemu_get_time (grub_efi_time_t *time,
+                grub_efi_time_capabilities_t *capabilities);
+grub_efi_status_t
+efiemu_set_time (grub_efi_time_t *time);
+
+grub_efi_status_t
+efiemu_get_wakeup_time (grub_efi_boolean_t *enabled,
+                       grub_efi_boolean_t *pending,
+                       grub_efi_time_t *time);
+grub_efi_status_t
+efiemu_set_wakeup_time (grub_efi_boolean_t enabled,
+                       grub_efi_time_t *time);
+
+#ifdef APPLE_CC
+#define PHYSICAL_ATTRIBUTE __attribute__ ((section("_text-physical, _text-physical")));
+#else
+#define PHYSICAL_ATTRIBUTE __attribute__ ((section(".text-physical")));
+#endif
+
+grub_efi_status_t
+efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
+                               grub_efi_uintn_t descriptor_size,
+                               grub_efi_uint32_t descriptor_version,
+                               grub_efi_memory_descriptor_t *virtual_map)
+  PHYSICAL_ATTRIBUTE;
+
+grub_efi_status_t
+efiemu_convert_pointer (grub_efi_uintn_t debug_disposition,
+                       void **address)
+  PHYSICAL_ATTRIBUTE;
+
+grub_efi_status_t
+efiemu_get_variable (grub_efi_char16_t *variable_name,
+                    grub_efi_guid_t *vendor_guid,
+                    grub_efi_uint32_t *attributes,
+                    grub_efi_uintn_t *data_size,
+                    void *data);
+
+grub_efi_status_t
+efiemu_get_next_variable_name (grub_efi_uintn_t *variable_name_size,
+                              grub_efi_char16_t *variable_name,
+                              grub_efi_guid_t *vendor_guid);
+
+grub_efi_status_t
+efiemu_set_variable (grub_efi_char16_t *variable_name,
+                    grub_efi_guid_t *vendor_guid,
+                    grub_efi_uint32_t attributes,
+                    grub_efi_uintn_t data_size,
+                    void *data);
+grub_efi_status_t
+efiemu_get_next_high_monotonic_count (grub_efi_uint32_t *high_count);
+void
+efiemu_reset_system (grub_efi_reset_type_t reset_type,
+                    grub_efi_status_t reset_status,
+                    grub_efi_uintn_t data_size,
+                    grub_efi_char16_t *reset_data);
+
+grub_efi_status_t
+EFI_FUNC (efiemu_set_virtual_address_map) (grub_efi_uintn_t,
+                                             grub_efi_uintn_t,
+                                             grub_efi_uint32_t,
+                                             grub_efi_memory_descriptor_t *)
+     PHYSICAL_ATTRIBUTE;
+grub_efi_status_t
+EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition,
+                                     void **address)
+     PHYSICAL_ATTRIBUTE;
+static grub_uint32_t
+efiemu_getcrc32 (grub_uint32_t crc, void *buf, int size)
+     PHYSICAL_ATTRIBUTE;
+static void
+init_crc32_table (void)
+     PHYSICAL_ATTRIBUTE;
+static grub_uint32_t
+reflect (grub_uint32_t ref, int len)
+     PHYSICAL_ATTRIBUTE;
+
+/*
+  The log. It's used when examining memory dump
+*/
+static grub_uint8_t loge[1000] = "EFIEMULOG";
+static int logn = 9;
+#define LOG(x)   { if (logn<900) loge[logn++]=x; }
+
+/* Interface with grub */
+extern grub_uint8_t efiemu_ptv_relocated;
+struct grub_efi_runtime_services efiemu_runtime_services;
+struct grub_efi_system_table efiemu_system_table;
+extern struct grub_efiemu_ptv_rel efiemu_ptv_relloc[];
+extern grub_uint8_t efiemu_variables[];
+extern grub_uint32_t efiemu_varsize;
+extern grub_uint32_t efiemu_high_monotonic_count;
+extern grub_int16_t efiemu_time_zone;
+extern grub_uint8_t efiemu_time_daylight;
+extern grub_uint32_t efiemu_time_accuracy;
+
+/* Some standard functions because we need to be standalone */
+static void
+efiemu_memcpy (void *to, void *from, int count)
+{
+  int i;
+  for (i = 0; i < count; i++)
+    ((grub_uint8_t *) to)[i] = ((grub_uint8_t *) from)[i];
+}
+
+static int
+efiemu_str16equal (grub_uint16_t *a, grub_uint16_t *b)
+{
+  grub_uint16_t *ptr1, *ptr2;
+  for (ptr1=a,ptr2=b; *ptr1 && *ptr2 == *ptr1; ptr1++, ptr2++);
+  return *ptr2 == *ptr1;
+}
+
+static grub_size_t
+efiemu_str16len (grub_uint16_t *a)
+{
+  grub_uint16_t *ptr1;
+  for (ptr1 = a; *ptr1; ptr1++);
+  return ptr1 - a;
+}
+
+static int
+efiemu_memequal (void *a, void *b, grub_size_t n)
+{
+  grub_uint8_t *ptr1, *ptr2;
+  for (ptr1 = (grub_uint8_t *) a, ptr2 = (grub_uint8_t *)b;
+       ptr1 < (grub_uint8_t *)a + n && *ptr2 == *ptr1; ptr1++, ptr2++);
+  return ptr1 == a + n;
+}
+
+static void
+efiemu_memset (grub_uint8_t *a, grub_uint8_t b, grub_size_t n)
+{
+  grub_uint8_t *ptr1;
+  for (ptr1=a; ptr1 < a + n; ptr1++)
+    *ptr1 = b;
+}
+
+static inline void
+write_cmos (grub_uint8_t addr, grub_uint8_t val)
+{
+  __asm__ __volatile__ ("outb %%al,$0x70\n"
+                       "mov %%cl, %%al\n"
+                       "outb %%al,$0x71": :"a" (addr), "c" (val));
+}
+
+static inline grub_uint8_t
+read_cmos (grub_uint8_t addr)
+{
+  grub_uint8_t ret;
+  __asm__ __volatile__ ("outb %%al, $0x70\n"
+                       "inb $0x71, %%al": "=a"(ret) :"a" (addr));
+  return ret;
+}
+
+/* Needed by some gcc versions */
+int __stack_chk_fail ()
+{
+  return 0;
+}
+
+/* The function that implement runtime services as specified in
+   EFI specification */
+static inline grub_uint8_t
+bcd_to_hex (grub_uint8_t in)
+{
+  return 10 * ((in & 0xf0) >> 4) + (in & 0x0f);
+}
+
+grub_efi_status_t
+EFI_FUNC (efiemu_get_time) (grub_efi_time_t *time,
+                              grub_efi_time_capabilities_t *capabilities)
+{
+  LOG ('a');
+  grub_uint8_t state;
+  state = read_cmos (0xb);
+  if (!(state & (1 << 2)))
+    {
+      time->year = 2000 + bcd_to_hex (read_cmos (0x9));
+      time->month = bcd_to_hex (read_cmos (0x8));
+      time->day = bcd_to_hex (read_cmos (0x7));
+      time->hour = bcd_to_hex (read_cmos (0x4));
+      if (time->hour >= 81)
+       time->hour -= 80 - 12;
+      if (time->hour == 24)
+       time->hour = 0;
+      time->minute = bcd_to_hex (read_cmos (0x2));
+      time->second = bcd_to_hex (read_cmos (0x0));
+    }
+  else
+    {
+      time->year = 2000 + read_cmos (0x9);
+      time->month = read_cmos (0x8);
+      time->day = read_cmos (0x7);
+      time->hour = read_cmos (0x4);
+      if (time->hour >= 0x81)
+       time->hour -= 0x80 - 12;
+      if (time->hour == 24)
+       time->hour = 0;
+      time->minute = read_cmos (0x2);
+      time->second = read_cmos (0x0);
+    }
+  time->nanosecond = 0;
+  time->pad1 = 0;
+  time->pad2 = 0;
+  time->time_zone = efiemu_time_zone;
+  time->daylight = efiemu_time_daylight;
+  capabilities->resolution = 1;
+  capabilities->accuracy = efiemu_time_accuracy;
+  capabilities->sets_to_zero = 0;
+  return GRUB_EFI_SUCCESS;
+}
+
+grub_efi_status_t
+EFI_FUNC (efiemu_set_time) (grub_efi_time_t *time)
+{
+  LOG ('b');
+  grub_uint8_t state;
+  state = read_cmos (0xb);
+  write_cmos (0xb, state | 0x6);
+  write_cmos (0x9, time->year - 2000);
+  write_cmos (0x8, time->month);
+  write_cmos (0x7, time->day);
+  write_cmos (0x4, time->hour);
+  write_cmos (0x2, time->minute);
+  write_cmos (0x0, time->second);
+  efiemu_time_zone = time->time_zone;
+  efiemu_time_daylight = time->daylight;
+  return GRUB_EFI_SUCCESS;
+}
+
+/* Following 2 functions are vendor specific. So announce it as unsupported */
+grub_efi_status_t
+EFI_FUNC (efiemu_get_wakeup_time) (grub_efi_boolean_t *enabled,
+                                     grub_efi_boolean_t *pending,
+                                     grub_efi_time_t *time)
+{
+  LOG ('c');
+  return GRUB_EFI_UNSUPPORTED;
+}
+
+grub_efi_status_t
+EFI_FUNC (efiemu_set_wakeup_time) (grub_efi_boolean_t enabled,
+                                     grub_efi_time_t *time)
+{
+  LOG ('d');
+  return GRUB_EFI_UNSUPPORTED;
+}
+
+static grub_uint32_t crc32_table [256];
+
+static grub_uint32_t
+reflect (grub_uint32_t ref, int len)
+{
+  grub_uint32_t result = 0;
+  int i;
+
+  for (i = 1; i <= len; i++)
+    {
+      if (ref & 1)
+       result |= 1 << (len - i);
+      ref >>= 1;
+    }
+
+  return result;
+}
+
+static void
+init_crc32_table (void)
+{
+  grub_uint32_t polynomial = 0x04c11db7;
+  int i, j;
+
+  for(i = 0; i < 256; i++)
+    {
+      crc32_table[i] = reflect(i, 8) << 24;
+      for (j = 0; j < 8; j++)
+        crc32_table[i] = (crc32_table[i] << 1) ^
+            (crc32_table[i] & (1 << 31) ? polynomial : 0);
+      crc32_table[i] = reflect(crc32_table[i], 32);
+    }
+}
+
+static grub_uint32_t
+efiemu_getcrc32 (grub_uint32_t crc, void *buf, int size)
+{
+  int i;
+  grub_uint8_t *data = buf;
+
+  if (! crc32_table[1])
+    init_crc32_table ();
+
+  crc^= 0xffffffff;
+
+  for (i = 0; i < size; i++)
+    {
+      crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ *data];
+      data++;
+    }
+
+  return crc ^ 0xffffffff;
+}
+
+
+grub_efi_status_t EFI_FUNC
+(efiemu_set_virtual_address_map) (grub_efi_uintn_t memory_map_size,
+                                 grub_efi_uintn_t descriptor_size,
+                                 grub_efi_uint32_t descriptor_version,
+                                 grub_efi_memory_descriptor_t *virtual_map)
+{
+  struct grub_efiemu_ptv_rel *cur_relloc;
+
+  LOG ('e');
+
+  /* Ensure that we are called only once */
+  if (efiemu_ptv_relocated)
+    return GRUB_EFI_UNSUPPORTED;
+  efiemu_ptv_relocated = 1;
+
+  /* Correct addresses using information supplied by grub */
+  for (cur_relloc = efiemu_ptv_relloc; cur_relloc->size;cur_relloc++)
+    {
+      grub_int64_t corr = 0;
+      grub_efi_memory_descriptor_t *descptr;
+
+      /* Compute correction */
+      for (descptr = virtual_map;
+          ((grub_uint8_t *) descptr - (grub_uint8_t *) virtual_map)
+            < memory_map_size;
+          descptr = (grub_efi_memory_descriptor_t *)
+            ((grub_uint8_t *) descptr + descriptor_size))
+       {
+         if (descptr->type == cur_relloc->plustype)
+           corr += descptr->virtual_start - descptr->physical_start;
+         if (descptr->type == cur_relloc->minustype)
+           corr -= descptr->virtual_start - descptr->physical_start;
+       }
+
+      /* Apply correction */
+      switch (cur_relloc->size)
+       {
+       case 8:
+         *((grub_uint64_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
+         break;
+       case 4:
+         *((grub_uint32_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
+         break;
+       case 2:
+         *((grub_uint16_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
+         break;
+       case 1:
+         *((grub_uint8_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
+         break;
+       }
+    }
+
+  /* Recompute crc32 of system table and runtime services */
+  efiemu_system_table.hdr.crc32 = 0;
+  efiemu_system_table.hdr.crc32 = efiemu_getcrc32
+    (0, &efiemu_system_table, sizeof (efiemu_system_table));
+
+  efiemu_runtime_services.hdr.crc32 = 0;
+  efiemu_runtime_services.hdr.crc32 = efiemu_getcrc32
+    (0, &efiemu_runtime_services, sizeof (efiemu_runtime_services));
+
+  return GRUB_EFI_SUCCESS;
+}
+
+/* since efiemu_set_virtual_address_map corrects all the pointers
+   we don't need efiemu_convert_pointer */
+grub_efi_status_t
+EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition,
+                                     void **address)
+{
+  LOG ('f');
+  return GRUB_EFI_UNSUPPORTED;
+}
+
+/* Next comes variable services. Because we have no vendor-independent
+   way to store these variables we have no non-volatility */
+
+/* Find variable by name and GUID. */
+static struct efi_variable *
+find_variable (grub_efi_guid_t *vendor_guid,
+              grub_efi_char16_t *variable_name)
+{
+  grub_uint8_t *ptr;
+  struct efi_variable *efivar;
+
+  for (ptr = efiemu_variables; ptr < efiemu_variables + efiemu_varsize; )
+    {
+      efivar = (struct efi_variable *) ptr;
+      if (!efivar->namelen)
+       return 0;
+      if (efiemu_str16equal((grub_efi_char16_t *)(efivar + 1), variable_name)
+         && efiemu_memequal (&(efivar->guid), vendor_guid,
+                             sizeof (efivar->guid)))
+       return efivar;
+      ptr += efivar->namelen + efivar->size + sizeof (*efivar);
+    }
+  return 0;
+}
+
+grub_efi_status_t
+EFI_FUNC (efiemu_get_variable) (grub_efi_char16_t *variable_name,
+                                  grub_efi_guid_t *vendor_guid,
+                                  grub_efi_uint32_t *attributes,
+                                  grub_efi_uintn_t *data_size,
+                                  void *data)
+{
+  struct efi_variable *efivar;
+  LOG ('g');
+  efivar = find_variable (vendor_guid, variable_name);
+  if (!efivar)
+    return GRUB_EFI_NOT_FOUND;
+  if (*data_size < efivar->size)
+    {
+      *data_size = efivar->size;
+      return GRUB_EFI_BUFFER_TOO_SMALL;
+    }
+  *data_size = efivar->size;
+  efiemu_memcpy (data, (grub_uint8_t *)(efivar + 1) + efivar->namelen,
+                efivar->size);
+  *attributes = efivar->attributes;
+
+  return GRUB_EFI_SUCCESS;
+}
+
+grub_efi_status_t EFI_FUNC
+(efiemu_get_next_variable_name) (grub_efi_uintn_t *variable_name_size,
+                                grub_efi_char16_t *variable_name,
+                                grub_efi_guid_t *vendor_guid)
+{
+  struct efi_variable *efivar;
+  LOG ('l');
+
+  if (!variable_name_size || !variable_name || !vendor_guid)
+    return GRUB_EFI_INVALID_PARAMETER;
+  if (variable_name[0])
+    {
+      efivar = find_variable (vendor_guid, variable_name);
+      if (!efivar)
+       return GRUB_EFI_NOT_FOUND;
+      efivar = (struct efi_variable *)((grub_uint8_t *)efivar
+                                      + efivar->namelen
+                                      + efivar->size + sizeof (*efivar));
+    }
+  else
+    efivar = (struct efi_variable *) (efiemu_variables);
+
+  LOG ('m');
+  if ((grub_uint8_t *)efivar >= efiemu_variables + efiemu_varsize
+      || !efivar->namelen)
+    return GRUB_EFI_NOT_FOUND;
+  if (*variable_name_size < efivar->namelen)
+    {
+      *variable_name_size = efivar->namelen;
+      return GRUB_EFI_BUFFER_TOO_SMALL;
+    }
+
+  efiemu_memcpy (variable_name, efivar + 1, efivar->namelen);
+  efiemu_memcpy (vendor_guid, &(efivar->guid),
+                sizeof (efivar->guid));
+
+  LOG('h');
+  return GRUB_EFI_SUCCESS;
+}
+
+grub_efi_status_t
+EFI_FUNC (efiemu_set_variable) (grub_efi_char16_t *variable_name,
+                                  grub_efi_guid_t *vendor_guid,
+                                  grub_efi_uint32_t attributes,
+                                  grub_efi_uintn_t data_size,
+                                  void *data)
+{
+  struct efi_variable *efivar;
+  grub_uint8_t *ptr;
+  LOG('i');
+  if (!variable_name[0])
+    return GRUB_EFI_INVALID_PARAMETER;
+  efivar = find_variable (vendor_guid, variable_name);
+
+  /* Delete variable if any */
+  if (efivar)
+    {
+      efiemu_memcpy (efivar, (grub_uint8_t *)(efivar + 1)
+                    + efivar->namelen + efivar->size,
+                    (efiemu_variables + efiemu_varsize)
+                    - ((grub_uint8_t *)(efivar + 1)
+                       + efivar->namelen + efivar->size));
+      efiemu_memset (efiemu_variables + efiemu_varsize
+                    - (sizeof (*efivar) + efivar->namelen + efivar->size),
+                    0, (sizeof (*efivar) + efivar->namelen + efivar->size));
+    }
+
+  if (!data_size)
+    return GRUB_EFI_SUCCESS;
+
+  for (ptr = efiemu_variables; ptr < efiemu_variables + efiemu_varsize; )
+    {
+      efivar = (struct efi_variable *) ptr;
+      ptr += efivar->namelen + efivar->size + sizeof (*efivar);
+      if (!efivar->namelen)
+       break;
+    }
+  if ((grub_uint8_t *)(efivar + 1) + data_size
+      + 2 * (efiemu_str16len (variable_name) + 1)
+      >= efiemu_variables + efiemu_varsize)
+    return GRUB_EFI_OUT_OF_RESOURCES;
+
+  efiemu_memcpy (&(efivar->guid), vendor_guid, sizeof (efivar->guid));
+  efivar->namelen = 2 * (efiemu_str16len (variable_name) + 1);
+  efivar->size = data_size;
+  efivar->attributes = attributes;
+  efiemu_memcpy (efivar + 1, variable_name,
+                2 * (efiemu_str16len (variable_name) + 1));
+  efiemu_memcpy ((grub_uint8_t *)(efivar + 1)
+                + 2 * (efiemu_str16len (variable_name) + 1),
+                data, data_size);
+
+  return GRUB_EFI_SUCCESS;
+}
+
+grub_efi_status_t EFI_FUNC
+(efiemu_get_next_high_monotonic_count) (grub_efi_uint32_t *high_count)
+{
+  LOG ('j');
+  if (!high_count)
+    return GRUB_EFI_INVALID_PARAMETER;
+  *high_count = ++efiemu_high_monotonic_count;
+  return GRUB_EFI_SUCCESS;
+}
+
+/* To implement it with APM we need to go to real mode. It's too much hassle
+   Besides EFI specification says that this function shouldn't be used
+   on systems supporting ACPI
+ */
+void
+EFI_FUNC (efiemu_reset_system) (grub_efi_reset_type_t reset_type,
+                                  grub_efi_status_t reset_status,
+                                  grub_efi_uintn_t data_size,
+                                  grub_efi_char16_t *reset_data)
+{
+  LOG ('k');
+}
+
+struct grub_efi_runtime_services efiemu_runtime_services =
+{
+  .hdr =
+  {
+    .signature = GRUB_EFIEMU_RUNTIME_SERVICES_SIGNATURE,
+    .revision = 0x0001000a,
+    .header_size = sizeof (struct grub_efi_runtime_services),
+    .crc32 = 0, /* filled later*/
+    .reserved = 0
+  },
+  .get_time = efiemu_get_time,
+  .set_time = efiemu_set_time,
+  .get_wakeup_time = efiemu_get_wakeup_time,
+  .set_wakeup_time = efiemu_set_wakeup_time,
+
+  .set_virtual_address_map = efiemu_set_virtual_address_map,
+  .convert_pointer = efiemu_convert_pointer,
+
+  .get_variable = efiemu_get_variable,
+  .get_next_variable_name = efiemu_get_next_variable_name,
+  .set_variable = efiemu_set_variable,
+  .get_next_high_monotonic_count = efiemu_get_next_high_monotonic_count,
+
+  .reset_system = efiemu_reset_system
+};
+
+
+static grub_uint16_t efiemu_vendor[] =
+  {'G', 'R', 'U', 'B', ' ', 'E', 'F', 'I', ' ',
+   'R', 'U', 'N', 'T', 'I', 'M', 'E', 0};
+
+struct grub_efi_system_table efiemu_system_table =
+{
+  .hdr =
+  {
+    .signature = GRUB_EFIEMU_SYSTEM_TABLE_SIGNATURE,
+    .revision = 0x0001000a,
+    .header_size = sizeof (struct grub_efi_system_table),
+    .crc32 = 0, /* filled later*/
+    .reserved = 0
+  },
+  .firmware_vendor = efiemu_vendor,
+  .firmware_revision = 0x0001000a,
+  .console_in_handler = 0,
+  .con_in = 0,
+  .console_out_handler = 0,
+  .con_out = 0,
+  .standard_error_handle = 0,
+  .std_err = 0,
+  .runtime_services = &efiemu_runtime_services,
+  .boot_services = 0,
+  .num_table_entries = 0,
+  .configuration_table = 0
+};
+
diff --git a/grub-core/efiemu/runtime/efiemu.sh b/grub-core/efiemu/runtime/efiemu.sh
new file mode 100644 (file)
index 0000000..5a492dc
--- /dev/null
@@ -0,0 +1,4 @@
+gcc -c -m32 -DELF32 -o efiemu32.o ./efiemu.c -Wall -Werror -nostdlib -O2 -I. -I../../include
+gcc -c -m64 -DELF64 -o efiemu64_c.o ./efiemu.c -Wall -Werror -mcmodel=large -O2 -I. -I../../include
+gcc -c -m64 -DELF64 -o efiemu64_s.o ./efiemu.S -Wall -Werror -mcmodel=large -O2 -I. -I../../include
+ld -o efiemu64.o -r efiemu64_s.o efiemu64_c.o -nostdlib
diff --git a/grub-core/efiemu/symbols.c b/grub-core/efiemu/symbols.c
new file mode 100644 (file)
index 0000000..4fc546b
--- /dev/null
@@ -0,0 +1,271 @@
+/* Code for managing symbols and pointers in efiemu */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/efiemu/runtime.h>
+
+static int ptv_written = 0;
+static int ptv_alloc = 0;
+static int ptv_handle = 0;
+static int relocated_handle = 0;
+static int ptv_requested = 0;
+static struct grub_efiemu_sym *efiemu_syms = 0;
+
+struct grub_efiemu_sym
+{
+  struct grub_efiemu_sym *next;
+  char *name;
+  int handle;
+  grub_off_t off;
+};
+
+void
+grub_efiemu_free_syms (void)
+{
+  struct grub_efiemu_sym *cur, *d;
+  for (cur = efiemu_syms; cur;)
+    {
+      d = cur->next;
+      grub_free (cur->name);
+      grub_free (cur);
+      cur = d;
+    }
+  efiemu_syms = 0;
+  ptv_written = 0;
+  ptv_alloc = 0;
+  ptv_requested = 0;
+  grub_efiemu_mm_return_request (ptv_handle);
+  ptv_handle = 0;
+  grub_efiemu_mm_return_request (relocated_handle);
+  relocated_handle = 0;
+}
+
+/* Announce that the module will need NUM allocators */
+/* Because of deferred memory allocation all the relocators have to be
+   announced during phase 1*/
+grub_err_t
+grub_efiemu_request_symbols (int num)
+{
+  if (ptv_alloc)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "symbols have already been allocated");
+  if (num < 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "can't request negative symbols");
+  ptv_requested += num;
+  return GRUB_ERR_NONE;
+}
+
+/* Resolve the symbol name NAME and set HANDLE and OFF accordingly  */
+grub_err_t
+grub_efiemu_resolve_symbol (const char *name, int *handle, grub_off_t *off)
+{
+  struct grub_efiemu_sym *cur;
+  for (cur = efiemu_syms; cur; cur = cur->next)
+    if (!grub_strcmp (name, cur->name))
+      {
+       *handle = cur->handle;
+       *off = cur->off;
+       return GRUB_ERR_NONE;
+      }
+  grub_dprintf ("efiemu", "%s not found\n", name);
+  return grub_error (GRUB_ERR_BAD_OS, "symbol %s isn't found", name);
+}
+
+/* Register symbol named NAME in memory handle HANDLE at offset OFF */
+grub_err_t
+grub_efiemu_register_symbol (const char *name, int handle, grub_off_t off)
+{
+  struct grub_efiemu_sym *cur;
+  cur = (struct grub_efiemu_sym *) grub_malloc (sizeof (*cur));
+  grub_dprintf ("efiemu", "registering symbol '%s'\n", name);
+  if (!cur)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't register symbol");
+  cur->name = grub_strdup (name);
+  cur->next = efiemu_syms;
+  cur->handle = handle;
+  cur->off = off;
+  efiemu_syms = cur;
+
+  return 0;
+}
+
+/* Go from phase 1 to phase 2. Must be called before similar function in mm.c */
+grub_err_t
+grub_efiemu_alloc_syms (void)
+{
+  ptv_alloc = ptv_requested;
+  ptv_handle = grub_efiemu_request_memalign
+    (1, (ptv_requested + 1) * sizeof (struct grub_efiemu_ptv_rel),
+     GRUB_EFI_RUNTIME_SERVICES_DATA);
+  relocated_handle = grub_efiemu_request_memalign
+    (1, sizeof (grub_uint8_t), GRUB_EFI_RUNTIME_SERVICES_DATA);
+
+  grub_efiemu_register_symbol ("efiemu_ptv_relocated", relocated_handle, 0);
+  grub_efiemu_register_symbol ("efiemu_ptv_relloc", ptv_handle, 0);
+  return grub_errno;
+}
+
+grub_err_t
+grub_efiemu_write_sym_markers (void)
+{
+  struct grub_efiemu_ptv_rel *ptv_rels
+    = grub_efiemu_mm_obtain_request (ptv_handle);
+  grub_uint8_t *relocated = grub_efiemu_mm_obtain_request (relocated_handle);
+  grub_memset (ptv_rels, 0, (ptv_requested + 1)
+              * sizeof (struct grub_efiemu_ptv_rel));
+  *relocated = 0;
+  return GRUB_ERR_NONE;
+}
+
+/* Write value (pointer to memory PLUS_HANDLE)
+   - (pointer to memory MINUS_HANDLE) + VALUE to ADDR assuming that the
+   size SIZE bytes. If PTV_NEEDED is 1 then announce it to runtime that this
+   value needs to be recomputed before going to virtual mode
+*/
+grub_err_t
+grub_efiemu_write_value (void *addr, grub_uint32_t value, int plus_handle,
+                        int minus_handle, int ptv_needed, int size)
+{
+  /* Announce relocator to runtime */
+  if (ptv_needed)
+    {
+      struct grub_efiemu_ptv_rel *ptv_rels
+       = grub_efiemu_mm_obtain_request (ptv_handle);
+
+      if (ptv_needed && ptv_written >= ptv_alloc)
+       return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                          "your module didn't declare efiemu "
+                          " relocators correctly");
+
+      if (minus_handle)
+       ptv_rels[ptv_written].minustype
+         = grub_efiemu_mm_get_type (minus_handle);
+      else
+       ptv_rels[ptv_written].minustype = 0;
+
+      if (plus_handle)
+       ptv_rels[ptv_written].plustype
+         = grub_efiemu_mm_get_type (plus_handle);
+      else
+       ptv_rels[ptv_written].plustype = 0;
+
+      ptv_rels[ptv_written].addr = PTR_TO_UINT64 (addr);
+      ptv_rels[ptv_written].size = size;
+      ptv_written++;
+
+      /* memset next value to zero to mark the end */
+      grub_memset (&ptv_rels[ptv_written], 0, sizeof (ptv_rels[ptv_written]));
+    }
+
+  /* Compute the value */
+  if (minus_handle)
+    value -= PTR_TO_UINT32 (grub_efiemu_mm_obtain_request (minus_handle));
+
+  if (plus_handle)
+    value += PTR_TO_UINT32 (grub_efiemu_mm_obtain_request (plus_handle));
+
+  /* Write the value */
+  switch (size)
+    {
+    case 8:
+      *((grub_uint64_t *) addr) = value;
+      break;
+    case 4:
+      *((grub_uint32_t *) addr) = value;
+      break;
+    case 2:
+      *((grub_uint16_t *) addr) = value;
+      break;
+    case 1:
+      *((grub_uint8_t *) addr) = value;
+      break;
+    default:
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "wrong symbol size");
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
+                                    grub_efi_uintn_t descriptor_size,
+                                    grub_efi_uint32_t descriptor_version
+                                    __attribute__ ((unused)),
+                                    grub_efi_memory_descriptor_t *virtual_map)
+{
+  grub_uint8_t *ptv_relocated;
+  struct grub_efiemu_ptv_rel *cur_relloc;
+  struct grub_efiemu_ptv_rel *ptv_rels;
+
+  ptv_relocated = grub_efiemu_mm_obtain_request (relocated_handle);
+  ptv_rels = grub_efiemu_mm_obtain_request (ptv_handle);
+
+  /* Ensure that we are called only once */
+  if (*ptv_relocated)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "EfiEmu is already relocated");
+  *ptv_relocated = 1;
+
+  /* Correct addresses using information supplied by grub */
+  for (cur_relloc = ptv_rels; cur_relloc->size; cur_relloc++)
+    {
+      grub_int64_t corr = 0;
+      grub_efi_memory_descriptor_t *descptr;
+
+      /* Compute correction */
+      for (descptr = virtual_map;
+          (grub_size_t) ((grub_uint8_t *) descptr
+                         - (grub_uint8_t *) virtual_map) < memory_map_size;
+          descptr = (grub_efi_memory_descriptor_t *)
+            ((grub_uint8_t *) descptr + descriptor_size))
+       {
+         if (descptr->type == cur_relloc->plustype)
+           corr += descptr->virtual_start - descptr->physical_start;
+         if (descptr->type == cur_relloc->minustype)
+           corr -= descptr->virtual_start - descptr->physical_start;
+       }
+
+      /* Apply correction */
+      switch (cur_relloc->size)
+       {
+       case 8:
+         *((grub_uint64_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
+         break;
+       case 4:
+         *((grub_uint32_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
+         break;
+       case 2:
+         *((grub_uint16_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
+         break;
+       case 1:
+         *((grub_uint8_t *) UINT_TO_PTR (cur_relloc->addr)) += corr;
+         break;
+       }
+    }
+
+  /* Recompute crc32 of system table and runtime services */
+
+  if (grub_efiemu_sizeof_uintn_t () == 4)
+    return grub_efiemu_crc32 ();
+  else
+    return grub_efiemu_crc64 ();
+}
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
new file mode 100644 (file)
index 0000000..9a89cad
--- /dev/null
@@ -0,0 +1,1124 @@
+/* font.c - Font API and font file loader.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/bufio.h>
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/font.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/video.h>
+#include <grub/bitmap.h>
+#include <grub/fontformat.h>
+
+#ifdef USE_ASCII_FAILBACK
+#include "ascii.h"
+#endif
+
+#ifndef FONT_DEBUG
+#define FONT_DEBUG 0
+#endif
+
+struct char_index_entry
+{
+  grub_uint32_t code;
+  grub_uint8_t storage_flags;
+  grub_uint32_t offset;
+
+  /* Glyph if loaded, or NULL otherwise.  */
+  struct grub_font_glyph *glyph;
+};
+
+#define FONT_WEIGHT_NORMAL 100
+#define FONT_WEIGHT_BOLD 200
+#define ASCII_BITMAP_SIZE 16
+
+struct grub_font
+{
+  char *name;
+  grub_file_t file;
+  char *family;
+  short point_size;
+  short weight;
+  short max_char_width;
+  short max_char_height;
+  short ascent;
+  short descent;
+  short leading;
+  grub_uint32_t num_chars;
+  struct char_index_entry *char_index;
+  grub_uint16_t *bmp_idx;
+};
+
+/* Definition of font registry.  */
+struct grub_font_node *grub_font_list;
+
+static int register_font (grub_font_t font);
+static void font_init (grub_font_t font);
+static void free_font (grub_font_t font);
+static void remove_font (grub_font_t font);
+
+struct font_file_section
+{
+  /* The file this section is in.  */
+  grub_file_t file;
+
+  /* FOURCC name of the section.  */
+  char name[4];
+
+  /* Length of the section contents.  */
+  grub_uint32_t length;
+
+  /* Set by open_section() on EOF.  */
+  int eof;
+};
+
+/* Replace unknown glyphs with a rounded question mark.  */
+static grub_uint8_t unknown_glyph_bitmap[] = {
+  /*                               76543210 */
+  0x7C,                                /*  ooooo   */
+  0x82,                                /* o     o  */
+  0xBA,                                /* o ooo o  */
+  0xAA,                                /* o o o o  */
+  0xAA,                                /* o o o o  */
+  0x8A,                                /* o   o o  */
+  0x9A,                                /* o  oo o  */
+  0x92,                                /* o  o  o  */
+  0x92,                                /* o  o  o  */
+  0x92,                                /* o  o  o  */
+  0x92,                                /* o  o  o  */
+  0x82,                                /* o     o  */
+  0x92,                                /* o  o  o  */
+  0x82,                                /* o     o  */
+  0x7C,                                /*  ooooo   */
+  0x00                         /*          */
+};
+
+/* The "unknown glyph" glyph, used as a last resort.  */
+static struct grub_font_glyph *unknown_glyph;
+
+/* The font structure used when no other font is loaded.  This functions
+   as a "Null Object" pattern, so that code everywhere does not have to
+   check for a NULL grub_font_t to avoid dereferencing a null pointer.  */
+static struct grub_font null_font;
+
+/* Flag to ensure module is initialized only once.  */
+static grub_uint8_t font_loader_initialized;
+
+#ifdef USE_ASCII_FAILBACK
+static struct grub_font_glyph *ascii_font_glyph[0x80];
+#endif
+
+static struct grub_font_glyph *
+ascii_glyph_lookup (grub_uint32_t code)
+{
+#ifdef USE_ASCII_FAILBACK
+  static int ascii_failback_initialized = 0;
+
+  if (code >= 0x80)
+    return unknown_glyph;
+
+  if (ascii_failback_initialized == 0)
+    {
+      int current;
+      for (current = 0; current < 0x80; current++)
+       {
+         ascii_font_glyph[current] =
+           grub_malloc (sizeof (struct grub_font_glyph) + ASCII_BITMAP_SIZE);
+
+         ascii_font_glyph[current]->width = 8;
+         ascii_font_glyph[current]->height = 16;
+         ascii_font_glyph[current]->offset_x = 0;
+         ascii_font_glyph[current]->offset_y = -2;
+         ascii_font_glyph[current]->device_width = 8;
+
+         grub_memcpy (ascii_font_glyph[current]->bitmap,
+                      &ascii_bitmaps[(0x7f - current) * ASCII_BITMAP_SIZE],
+                      ASCII_BITMAP_SIZE);
+       }
+
+      ascii_failback_initialized = 1;
+    }
+
+  return ascii_font_glyph[code];
+#else
+  (void) code;
+  return unknown_glyph;
+#endif
+}
+
+void
+grub_font_loader_init (void)
+{
+  /* Only initialize font loader once.  */
+  if (font_loader_initialized)
+    return;
+
+  /* Make glyph for unknown glyph.  */
+  unknown_glyph = grub_malloc (sizeof (struct grub_font_glyph)
+                              + sizeof (unknown_glyph_bitmap));
+  if (!unknown_glyph)
+    return;
+
+  unknown_glyph->width = 8;
+  unknown_glyph->height = 16;
+  unknown_glyph->offset_x = 0;
+  unknown_glyph->offset_y = -3;
+  unknown_glyph->device_width = 8;
+  grub_memcpy (unknown_glyph->bitmap,
+              unknown_glyph_bitmap, sizeof (unknown_glyph_bitmap));
+
+  /* Initialize the null font.  */
+  font_init (&null_font);
+  null_font.name = "<No Font>";
+  null_font.ascent = unknown_glyph->height - 3;
+  null_font.descent = 3;
+  null_font.max_char_width = unknown_glyph->width;
+  null_font.max_char_height = unknown_glyph->height;
+
+  font_loader_initialized = 1;
+}
+
+/* Initialize the font object with initial default values.  */
+static void
+font_init (grub_font_t font)
+{
+  font->name = 0;
+  font->file = 0;
+  font->family = 0;
+  font->point_size = 0;
+  font->weight = 0;
+
+  /* Default leading value, not in font file yet.  */
+  font->leading = 1;
+
+  font->max_char_width = 0;
+  font->max_char_height = 0;
+  font->ascent = 0;
+  font->descent = 0;
+  font->num_chars = 0;
+  font->char_index = 0;
+  font->bmp_idx = 0;
+}
+
+/* Open the next section in the file.
+
+   On success, the section name is stored in section->name and the length in
+   section->length, and 0 is returned.  On failure, 1 is returned and
+   grub_errno is set appropriately with an error message.
+
+   If 1 is returned due to being at the end of the file, then section->eof is
+   set to 1; otherwise, section->eof is set to 0.  */
+static int
+open_section (grub_file_t file, struct font_file_section *section)
+{
+  grub_ssize_t retval;
+  grub_uint32_t raw_length;
+
+  section->file = file;
+  section->eof = 0;
+
+  /* Read the FOURCC section name.  */
+  retval = grub_file_read (file, section->name, 4);
+  if (retval >= 0 && retval < 4)
+    {
+      /* EOF encountered.  */
+      section->eof = 1;
+      return 1;
+    }
+  else if (retval < 0)
+    {
+      grub_error (GRUB_ERR_BAD_FONT,
+                 "font format error: can't read section name");
+      return 1;
+    }
+
+  /* Read the big-endian 32-bit section length.  */
+  retval = grub_file_read (file, &raw_length, 4);
+  if (retval >= 0 && retval < 4)
+    {
+      /* EOF encountered.  */
+      section->eof = 1;
+      return 1;
+    }
+  else if (retval < 0)
+    {
+      grub_error (GRUB_ERR_BAD_FONT,
+                 "font format error: can't read section length");
+      return 1;
+    }
+
+  /* Convert byte-order and store in *length.  */
+  section->length = grub_be_to_cpu32 (raw_length);
+
+  return 0;
+}
+
+/* Size in bytes of each character index (CHIX section)
+   entry in the font file.  */
+#define FONT_CHAR_INDEX_ENTRY_SIZE (4 + 1 + 4)
+
+/* Load the character index (CHIX) section contents from the font file.  This
+   presumes that the position of FILE is positioned immediately after the
+   section length for the CHIX section (i.e., at the start of the section
+   contents).  Returns 0 upon success, nonzero for failure (in which case
+   grub_errno is set appropriately).  */
+static int
+load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
+                grub_font *font)
+{
+  unsigned i;
+  grub_uint32_t last_code;
+
+#if FONT_DEBUG >= 2
+  grub_printf ("load_font_index(sect_length=%d)\n", sect_length);
+#endif
+
+  /* Sanity check: ensure section length is divisible by the entry size.  */
+  if ((sect_length % FONT_CHAR_INDEX_ENTRY_SIZE) != 0)
+    {
+      grub_error (GRUB_ERR_BAD_FONT,
+                 "font file format error: character index length %d "
+                 "is not a multiple of the entry size %d",
+                 sect_length, FONT_CHAR_INDEX_ENTRY_SIZE);
+      return 1;
+    }
+
+  /* Calculate the number of characters.  */
+  font->num_chars = sect_length / FONT_CHAR_INDEX_ENTRY_SIZE;
+
+  /* Allocate the character index array.  */
+  font->char_index = grub_malloc (font->num_chars
+                                 * sizeof (struct char_index_entry));
+  if (!font->char_index)
+    return 1;
+  font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t));
+  if (!font->bmp_idx)
+    {
+      grub_free (font->char_index);
+      return 1;
+    }
+  grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t));
+
+
+#if FONT_DEBUG >= 2
+  grub_printf ("num_chars=%d)\n", font->num_chars);
+#endif
+
+  last_code = 0;
+
+  /* Load the character index data from the file.  */
+  for (i = 0; i < font->num_chars; i++)
+    {
+      struct char_index_entry *entry = &font->char_index[i];
+
+      /* Read code point value; convert to native byte order.  */
+      if (grub_file_read (file, &entry->code, 4) != 4)
+       return 1;
+      entry->code = grub_be_to_cpu32 (entry->code);
+
+      /* Verify that characters are in ascending order.  */
+      if (i != 0 && entry->code <= last_code)
+       {
+         grub_error (GRUB_ERR_BAD_FONT,
+                     "font characters not in ascending order: %u <= %u",
+                     entry->code, last_code);
+         return 1;
+       }
+
+      if (entry->code < 0x10000)
+       font->bmp_idx[entry->code] = i;
+
+      last_code = entry->code;
+
+      /* Read storage flags byte.  */
+      if (grub_file_read (file, &entry->storage_flags, 1) != 1)
+       return 1;
+
+      /* Read glyph data offset; convert to native byte order.  */
+      if (grub_file_read (file, &entry->offset, 4) != 4)
+       return 1;
+      entry->offset = grub_be_to_cpu32 (entry->offset);
+
+      /* No glyph loaded.  Will be loaded on demand and cached thereafter.  */
+      entry->glyph = 0;
+
+#if FONT_DEBUG >= 5
+      /* Print the 1st 10 characters.  */
+      if (i < 10)
+       grub_printf ("c=%d o=%d\n", entry->code, entry->offset);
+#endif
+    }
+
+  return 0;
+}
+
+/* Read the contents of the specified section as a string, which is
+   allocated on the heap.  Returns 0 if there is an error.  */
+static char *
+read_section_as_string (struct font_file_section *section)
+{
+  char *str;
+  grub_ssize_t ret;
+
+  str = grub_malloc (section->length + 1);
+  if (!str)
+    return 0;
+
+  ret = grub_file_read (section->file, str, section->length);
+  if (ret < 0 || ret != (grub_ssize_t) section->length)
+    {
+      grub_free (str);
+      return 0;
+    }
+
+  str[section->length] = '\0';
+  return str;
+}
+
+/* Read the contents of the current section as a 16-bit integer value,
+   which is stored into *VALUE.
+   Returns 0 upon success, nonzero upon failure.  */
+static int
+read_section_as_short (struct font_file_section *section,
+                      grub_int16_t * value)
+{
+  grub_uint16_t raw_value;
+
+  if (section->length != 2)
+    {
+      grub_error (GRUB_ERR_BAD_FONT,
+                 "font file format error: section %c%c%c%c length "
+                 "is %d but should be 2",
+                 section->name[0], section->name[1],
+                 section->name[2], section->name[3], section->length);
+      return 1;
+    }
+  if (grub_file_read (section->file, &raw_value, 2) != 2)
+    return 1;
+
+  *value = grub_be_to_cpu16 (raw_value);
+  return 0;
+}
+
+/* Load a font and add it to the beginning of the global font list.
+   Returns 0 upon success, nonzero upon failure.  */
+int
+grub_font_load (const char *filename)
+{
+  grub_file_t file = 0;
+  struct font_file_section section;
+  char magic[4];
+  grub_font_t font = 0;
+
+#if FONT_DEBUG >= 1
+  grub_printf ("add_font(%s)\n", filename);
+#endif
+
+  file = grub_buffile_open (filename, 1024);
+  if (!file)
+    goto fail;
+
+#if FONT_DEBUG >= 3
+  grub_printf ("file opened\n");
+#endif
+
+  /* Read the FILE section.  It indicates the file format.  */
+  if (open_section (file, &section) != 0)
+    goto fail;
+
+#if FONT_DEBUG >= 3
+  grub_printf ("opened FILE section\n");
+#endif
+  if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FILE,
+                  sizeof (FONT_FORMAT_SECTION_NAMES_FILE) - 1) != 0)
+    {
+      grub_error (GRUB_ERR_BAD_FONT,
+                 "font file format error: 1st section must be FILE");
+      goto fail;
+    }
+
+#if FONT_DEBUG >= 3
+  grub_printf ("section name ok\n");
+#endif
+  if (section.length != 4)
+    {
+      grub_error (GRUB_ERR_BAD_FONT,
+                 "font file format error (file type ID length is %d "
+                 "but should be 4)", section.length);
+      goto fail;
+    }
+
+#if FONT_DEBUG >= 3
+  grub_printf ("section length ok\n");
+#endif
+  /* Check the file format type code.  */
+  if (grub_file_read (file, magic, 4) != 4)
+    goto fail;
+
+#if FONT_DEBUG >= 3
+  grub_printf ("read magic ok\n");
+#endif
+
+  if (grub_memcmp (magic, FONT_FORMAT_PFF2_MAGIC, 4) != 0)
+    {
+      grub_error (GRUB_ERR_BAD_FONT, "invalid font magic %x %x %x %x",
+                 magic[0], magic[1], magic[2], magic[3]);
+      goto fail;
+    }
+
+#if FONT_DEBUG >= 3
+  grub_printf ("compare magic ok\n");
+#endif
+
+  /* Allocate the font object.  */
+  font = (grub_font_t) grub_malloc (sizeof (struct grub_font));
+  if (!font)
+    goto fail;
+
+  font_init (font);
+  font->file = file;
+
+#if FONT_DEBUG >= 3
+  grub_printf ("allocate font ok; loading font info\n");
+#endif
+
+  /* Load the font information.  */
+  while (1)
+    {
+      if (open_section (file, &section) != 0)
+       {
+         if (section.eof)
+           break;              /* Done reading the font file.  */
+         else
+           goto fail;
+       }
+
+#if FONT_DEBUG >= 2
+      grub_printf ("opened section %c%c%c%c ok\n",
+                  section.name[0], section.name[1],
+                  section.name[2], section.name[3]);
+#endif
+
+      if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FONT_NAME,
+                      sizeof (FONT_FORMAT_SECTION_NAMES_FONT_NAME) - 1) == 0)
+       {
+         font->name = read_section_as_string (&section);
+         if (!font->name)
+           goto fail;
+       }
+      else if (grub_memcmp (section.name,
+                           FONT_FORMAT_SECTION_NAMES_POINT_SIZE,
+                           sizeof (FONT_FORMAT_SECTION_NAMES_POINT_SIZE) -
+                           1) == 0)
+       {
+         if (read_section_as_short (&section, &font->point_size) != 0)
+           goto fail;
+       }
+      else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_WEIGHT,
+                           sizeof (FONT_FORMAT_SECTION_NAMES_WEIGHT) - 1)
+              == 0)
+       {
+         char *wt;
+         wt = read_section_as_string (&section);
+         if (!wt)
+           continue;
+         /* Convert the weight string 'normal' or 'bold' into a number.  */
+         if (grub_strcmp (wt, "normal") == 0)
+           font->weight = FONT_WEIGHT_NORMAL;
+         else if (grub_strcmp (wt, "bold") == 0)
+           font->weight = FONT_WEIGHT_BOLD;
+         grub_free (wt);
+       }
+      else if (grub_memcmp (section.name,
+                           FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH,
+                           sizeof (FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH)
+                           - 1) == 0)
+       {
+         if (read_section_as_short (&section, &font->max_char_width) != 0)
+           goto fail;
+       }
+      else if (grub_memcmp (section.name,
+                           FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT,
+                           sizeof (FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT)
+                           - 1) == 0)
+       {
+         if (read_section_as_short (&section, &font->max_char_height) != 0)
+           goto fail;
+       }
+      else if (grub_memcmp (section.name,
+                           FONT_FORMAT_SECTION_NAMES_ASCENT,
+                           sizeof (FONT_FORMAT_SECTION_NAMES_ASCENT) - 1)
+              == 0)
+       {
+         if (read_section_as_short (&section, &font->ascent) != 0)
+           goto fail;
+       }
+      else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_DESCENT,
+                           sizeof (FONT_FORMAT_SECTION_NAMES_DESCENT) - 1)
+              == 0)
+       {
+         if (read_section_as_short (&section, &font->descent) != 0)
+           goto fail;
+       }
+      else if (grub_memcmp (section.name,
+                           FONT_FORMAT_SECTION_NAMES_CHAR_INDEX,
+                           sizeof (FONT_FORMAT_SECTION_NAMES_CHAR_INDEX) -
+                           1) == 0)
+       {
+         if (load_font_index (file, section.length, font) != 0)
+           goto fail;
+       }
+      else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_DATA,
+                           sizeof (FONT_FORMAT_SECTION_NAMES_DATA) - 1) == 0)
+       {
+         /* When the DATA section marker is reached, we stop reading.  */
+         break;
+       }
+      else
+       {
+         /* Unhandled section type, simply skip past it.  */
+#if FONT_DEBUG >= 3
+         grub_printf ("Unhandled section type, skipping.\n");
+#endif
+         grub_off_t section_end = grub_file_tell (file) + section.length;
+         if ((int) grub_file_seek (file, section_end) == -1)
+           goto fail;
+       }
+    }
+
+  if (!font->name)
+    {
+      grub_printf ("Note: Font has no name.\n");
+      font->name = grub_strdup ("Unknown");
+    }
+
+#if FONT_DEBUG >= 1
+  grub_printf ("Loaded font `%s'.\n"
+              "Ascent=%d Descent=%d MaxW=%d MaxH=%d Number of characters=%d.\n",
+              font->name,
+              font->ascent, font->descent,
+              font->max_char_width, font->max_char_height, font->num_chars);
+#endif
+
+  if (font->max_char_width == 0
+      || font->max_char_height == 0
+      || font->num_chars == 0
+      || font->char_index == 0 || font->ascent == 0 || font->descent == 0)
+    {
+      grub_error (GRUB_ERR_BAD_FONT,
+                 "invalid font file: missing some required data");
+      goto fail;
+    }
+
+  /* Add the font to the global font registry.  */
+  if (register_font (font) != 0)
+    goto fail;
+
+  return 0;
+
+fail:
+  free_font (font);
+  return 1;
+}
+
+/* Read a 16-bit big-endian integer from FILE, convert it to native byte
+   order, and store it in *VALUE.
+   Returns 0 on success, 1 on failure.  */
+static int
+read_be_uint16 (grub_file_t file, grub_uint16_t * value)
+{
+  if (grub_file_read (file, value, 2) != 2)
+    return 1;
+  *value = grub_be_to_cpu16 (*value);
+  return 0;
+}
+
+static int
+read_be_int16 (grub_file_t file, grub_int16_t * value)
+{
+  /* For the signed integer version, use the same code as for unsigned.  */
+  return read_be_uint16 (file, (grub_uint16_t *) value);
+}
+
+/* Return a pointer to the character index entry for the glyph corresponding to
+   the codepoint CODE in the font FONT.  If not found, return zero.  */
+static inline struct char_index_entry *
+find_glyph (const grub_font_t font, grub_uint32_t code)
+{
+  struct char_index_entry *table;
+  grub_size_t lo;
+  grub_size_t hi;
+  grub_size_t mid;
+
+  table = font->char_index;
+
+  /* Use BMP index if possible.  */
+  if (code < 0x10000 && font->bmp_idx)
+    {
+      if (font->bmp_idx[code] == 0xffff)
+       return 0;
+      return &table[font->bmp_idx[code]];
+    }
+
+  /* Do a binary search in `char_index', which is ordered by code point.  */
+  lo = 0;
+  hi = font->num_chars - 1;
+
+  if (!table)
+    return 0;
+
+  while (lo <= hi)
+    {
+      mid = lo + (hi - lo) / 2;
+      if (code < table[mid].code)
+       hi = mid - 1;
+      else if (code > table[mid].code)
+       lo = mid + 1;
+      else
+       return &table[mid];
+    }
+
+  return 0;
+}
+
+/* Get a glyph for the Unicode character CODE in FONT.  The glyph is loaded
+   from the font file if has not been loaded yet.
+   Returns a pointer to the glyph if found, or 0 if it is not found.  */
+static struct grub_font_glyph *
+grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
+{
+  struct char_index_entry *index_entry;
+
+  index_entry = find_glyph (font, code);
+  if (index_entry)
+    {
+      struct grub_font_glyph *glyph = 0;
+      grub_uint16_t width;
+      grub_uint16_t height;
+      grub_int16_t xoff;
+      grub_int16_t yoff;
+      grub_int16_t dwidth;
+      int len;
+
+      if (index_entry->glyph)
+       /* Return cached glyph.  */
+       return index_entry->glyph;
+
+      if (!font->file)
+       /* No open file, can't load any glyphs.  */
+       return 0;
+
+      /* Make sure we can find glyphs for error messages.  Push active
+         error message to error stack and reset error message.  */
+      grub_error_push ();
+
+      grub_file_seek (font->file, index_entry->offset);
+
+      /* Read the glyph width, height, and baseline.  */
+      if (read_be_uint16 (font->file, &width) != 0
+         || read_be_uint16 (font->file, &height) != 0
+         || read_be_int16 (font->file, &xoff) != 0
+         || read_be_int16 (font->file, &yoff) != 0
+         || read_be_int16 (font->file, &dwidth) != 0)
+       {
+         remove_font (font);
+         return 0;
+       }
+
+      len = (width * height + 7) / 8;
+      glyph = grub_malloc (sizeof (struct grub_font_glyph) + len);
+      if (!glyph)
+       {
+         remove_font (font);
+         return 0;
+       }
+
+      glyph->font = font;
+      glyph->width = width;
+      glyph->height = height;
+      glyph->offset_x = xoff;
+      glyph->offset_y = yoff;
+      glyph->device_width = dwidth;
+
+      /* Don't try to read empty bitmaps (e.g., space characters).  */
+      if (len != 0)
+       {
+         if (grub_file_read (font->file, glyph->bitmap, len) != len)
+           {
+             remove_font (font);
+             return 0;
+           }
+       }
+
+      /* Restore old error message.  */
+      grub_error_pop ();
+
+      /* Cache the glyph.  */
+      index_entry->glyph = glyph;
+
+      return glyph;
+    }
+
+  return 0;
+}
+
+/* Free the memory used by FONT.
+   This should not be called if the font has been made available to
+   users (once it is added to the global font list), since there would
+   be the possibility of a dangling pointer.  */
+static void
+free_font (grub_font_t font)
+{
+  if (font)
+    {
+      if (font->file)
+       grub_file_close (font->file);
+      grub_free (font->name);
+      grub_free (font->family);
+      grub_free (font->char_index);
+      grub_free (font);
+    }
+}
+
+/* Add FONT to the global font registry.
+   Returns 0 upon success, nonzero on failure
+   (the font was not registered).  */
+static int
+register_font (grub_font_t font)
+{
+  struct grub_font_node *node = 0;
+
+  node = grub_malloc (sizeof (struct grub_font_node));
+  if (!node)
+    return 1;
+
+  node->value = font;
+  node->next = grub_font_list;
+  grub_font_list = node;
+
+  return 0;
+}
+
+/* Remove the font from the global font list.  We don't actually free the
+   font's memory since users could be holding references to the font.  */
+static void
+remove_font (grub_font_t font)
+{
+  struct grub_font_node **nextp, *cur;
+
+  for (nextp = &grub_font_list, cur = *nextp;
+       cur; nextp = &cur->next, cur = cur->next)
+    {
+      if (cur->value == font)
+       {
+         *nextp = cur->next;
+
+         /* Free the node, but not the font itself.  */
+         grub_free (cur);
+
+         return;
+       }
+    }
+}
+
+/* Get a font from the list of loaded fonts.  This function will return
+   another font if the requested font is not available.  If no fonts are
+   loaded, then a special 'null font' is returned, which contains no glyphs,
+   but is not a null pointer so the caller may omit checks for NULL.  */
+grub_font_t
+grub_font_get (const char *font_name)
+{
+  struct grub_font_node *node;
+
+  for (node = grub_font_list; node; node = node->next)
+    {
+      grub_font_t font = node->value;
+      if (grub_strcmp (font->name, font_name) == 0)
+       return font;
+    }
+
+  /* If no font by that name is found, return the first font in the list
+     as a fallback.  */
+  if (grub_font_list && grub_font_list->value)
+    return grub_font_list->value;
+  else
+    /* The null_font is a last resort.  */
+    return &null_font;
+}
+
+/* Get the full name of the font.  */
+const char *
+grub_font_get_name (grub_font_t font)
+{
+  return font->name;
+}
+
+/* Get the maximum width of any character in the font in pixels.  */
+int
+grub_font_get_max_char_width (grub_font_t font)
+{
+  return font->max_char_width;
+}
+
+/* Get the maximum height of any character in the font in pixels.  */
+int
+grub_font_get_max_char_height (grub_font_t font)
+{
+  return font->max_char_height;
+}
+
+/* Get the distance in pixels from the top of characters to the baseline.  */
+int
+grub_font_get_ascent (grub_font_t font)
+{
+  return font->ascent;
+}
+
+/* Get the distance in pixels from the baseline to the lowest descenders
+   (for instance, in a lowercase 'y', 'g', etc.).  */
+int
+grub_font_get_descent (grub_font_t font)
+{
+  return font->descent;
+}
+
+/* Get the *standard leading* of the font in pixel, which is the spacing
+   between two lines of text.  Specifically, it is the space between the
+   descent of one line and the ascent of the next line.  This is included
+   in the *height* metric.  */
+int
+grub_font_get_leading (grub_font_t font)
+{
+  return font->leading;
+}
+
+/* Get the distance in pixels between baselines of adjacent lines of text.  */
+int
+grub_font_get_height (grub_font_t font)
+{
+  return font->ascent + font->descent + font->leading;
+}
+
+/* Get the width in pixels of the specified UTF-8 string, when rendered in
+   in the specified font (but falling back on other fonts for glyphs that
+   are missing).  */
+int
+grub_font_get_string_width (grub_font_t font, const char *str)
+{
+  int width;
+  struct grub_font_glyph *glyph;
+  grub_uint32_t code;
+  const grub_uint8_t *ptr;
+
+  for (ptr = (const grub_uint8_t *) str, width = 0;
+       grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0;)
+    {
+      glyph = grub_font_get_glyph_with_fallback (font, code);
+      width += glyph->device_width;
+    }
+
+  return width;
+}
+
+/* Get the glyph for FONT corresponding to the Unicode code point CODE.
+   Returns the ASCII glyph for the code if no other fonts are available. 
+   The glyphs are cached once loaded.  */
+struct grub_font_glyph *
+grub_font_get_glyph (grub_font_t font, grub_uint32_t code)
+{
+  struct grub_font_glyph *glyph = 0;
+  if (font)
+    glyph = grub_font_get_glyph_internal (font, code);
+  if (glyph == 0)
+    {
+      glyph = ascii_glyph_lookup (code);
+    }
+  return glyph;
+}
+
+
+/* Calculate a subject value representing "how similar" two fonts are.
+   This is used to prioritize the order that fonts are scanned for missing
+   glyphs.  The object is to select glyphs from the most similar font
+   possible, for the best appearance.
+   The heuristic is crude, but it helps greatly when fonts of similar
+   sizes are used so that tiny 8 point glyphs are not mixed into a string
+   of 24 point text unless there is no other choice.  */
+static int
+get_font_diversity (grub_font_t a, grub_font_t b)
+{
+  int d;
+
+  d = 0;
+
+  if (a->ascent && b->ascent)
+    d += grub_abs (a->ascent - b->ascent) * 8;
+  else
+    /* Penalty for missing attributes.  */
+    d += 50;
+
+  if (a->max_char_height && b->max_char_height)
+    d += grub_abs (a->max_char_height - b->max_char_height) * 8;
+  else
+    /* Penalty for missing attributes.  */
+    d += 50;
+
+  /* Weight is a minor factor. */
+  d += (a->weight != b->weight) ? 5 : 0;
+
+  return d;
+}
+
+/* Get a glyph corresponding to the codepoint CODE.  If FONT contains the
+   specified glyph, then it is returned.  Otherwise, all other loaded fonts
+   are searched until one is found that contains a glyph for CODE.
+   If no glyph is available for CODE in the loaded fonts, then a glyph
+   representing an unknown character is returned.
+   This function never returns NULL.
+   The returned glyph is owned by the font manager and should not be freed
+   by the caller.  The glyphs are cached.  */
+struct grub_font_glyph *
+grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
+{
+  struct grub_font_glyph *glyph;
+  struct grub_font_node *node;
+  /* Keep track of next node, in case there's an I/O error in
+     grub_font_get_glyph_internal() and the font is removed from the list.  */
+  struct grub_font_node *next;
+  /* Information on the best glyph found so far, to help find the glyph in
+     the best matching to the requested one.  */
+  int best_diversity;
+  struct grub_font_glyph *best_glyph;
+
+  if (font)
+    {
+      /* First try to get the glyph from the specified font.  */
+      glyph = grub_font_get_glyph_internal (font, code);
+      if (glyph)
+       return glyph;
+    }
+
+  /* Otherwise, search all loaded fonts for the glyph and use the one from
+     the font that best matches the requested font.  */
+  best_diversity = 10000;
+  best_glyph = 0;
+
+  for (node = grub_font_list; node; node = next)
+    {
+      grub_font_t curfont;
+
+      curfont = node->value;
+      next = node->next;
+
+      glyph = grub_font_get_glyph_internal (curfont, code);
+      if (glyph)
+       {
+         int d;
+
+         d = get_font_diversity (curfont, font);
+         if (d < best_diversity)
+           {
+             best_diversity = d;
+             best_glyph = glyph;
+           }
+       }
+    }
+
+  if (best_glyph)
+    return best_glyph;
+  else
+    /* Glyph not available in any font.  Return ASCII failback.  */
+    return ascii_glyph_lookup (code);
+}
+
+
+/* Draw the specified glyph at (x, y).  The y coordinate designates the
+   baseline of the character, while the x coordinate designates the left
+   side location of the character.  */
+grub_err_t
+grub_font_draw_glyph (struct grub_font_glyph * glyph,
+                     grub_video_color_t color, int left_x, int baseline_y)
+{
+  struct grub_video_bitmap glyph_bitmap;
+
+  /* Don't try to draw empty glyphs (U+0020, etc.).  */
+  if (glyph->width == 0 || glyph->height == 0)
+    return GRUB_ERR_NONE;
+
+  glyph_bitmap.mode_info.width = glyph->width;
+  glyph_bitmap.mode_info.height = glyph->height;
+  glyph_bitmap.mode_info.mode_type =
+    (1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP;
+  glyph_bitmap.mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED;
+  glyph_bitmap.mode_info.bpp = 1;
+
+  /* Really 1 bit per pixel.  */
+  glyph_bitmap.mode_info.bytes_per_pixel = 0;
+
+  /* Packed densely as bits.  */
+  glyph_bitmap.mode_info.pitch = glyph->width;
+
+  glyph_bitmap.mode_info.number_of_colors = 2;
+  glyph_bitmap.mode_info.bg_red = 0;
+  glyph_bitmap.mode_info.bg_green = 0;
+  glyph_bitmap.mode_info.bg_blue = 0;
+  glyph_bitmap.mode_info.bg_alpha = 0;
+  grub_video_unmap_color (color,
+                         &glyph_bitmap.mode_info.fg_red,
+                         &glyph_bitmap.mode_info.fg_green,
+                         &glyph_bitmap.mode_info.fg_blue,
+                         &glyph_bitmap.mode_info.fg_alpha);
+  glyph_bitmap.data = glyph->bitmap;
+
+  int bitmap_left = left_x + glyph->offset_x;
+  int bitmap_bottom = baseline_y - glyph->offset_y;
+  int bitmap_top = bitmap_bottom - glyph->height;
+
+  return grub_video_blit_bitmap (&glyph_bitmap, GRUB_VIDEO_BLIT_BLEND,
+                                bitmap_left, bitmap_top,
+                                0, 0, glyph->width, glyph->height);
+}
+
+/* Draw a UTF-8 string of text on the current video render target.
+   The x coordinate specifies the starting x position for the first character,
+   while the y coordinate specifies the baseline position.
+   If the string contains a character that FONT does not contain, then
+   a glyph from another loaded font may be used instead.  */
+grub_err_t
+grub_font_draw_string (const char *str, grub_font_t font,
+                      grub_video_color_t color, int left_x, int baseline_y)
+{
+  int x;
+  struct grub_font_glyph *glyph;
+  grub_uint32_t code;
+  const grub_uint8_t *ptr;
+
+  for (ptr = (const grub_uint8_t *) str, x = left_x;
+       grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0;)
+    {
+      glyph = grub_font_get_glyph_with_fallback (font, code);
+      if (grub_font_draw_glyph (glyph, color, x, baseline_y) != GRUB_ERR_NONE)
+       return grub_errno;
+      x += glyph->device_width;
+    }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/font/font_cmd.c b/grub-core/font/font_cmd.c
new file mode 100644 (file)
index 0000000..8b00dd8
--- /dev/null
@@ -0,0 +1,80 @@
+/* font_cmd.c - Font command definition. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/font.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+loadfont_command (grub_command_t cmd __attribute__ ((unused)),
+                 int argc,
+                 char **args)
+{
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no font specified");
+
+  while (argc--)
+    if (grub_font_load (*args++) != 0)
+      return GRUB_ERR_BAD_FONT;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+lsfonts_command (grub_command_t cmd __attribute__ ((unused)),
+                 int argc __attribute__ ((unused)),
+                 char **args __attribute__ ((unused)))
+{
+  struct grub_font_node *node;
+
+  grub_printf ("Loaded fonts:\n");
+  for (node = grub_font_list; node; node = node->next)
+    {
+      grub_font_t font = node->value;
+      grub_printf ("%s\n", grub_font_get_name (font));
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd_loadfont, cmd_lsfonts;
+
+GRUB_MOD_INIT(font)
+{
+  grub_font_loader_init ();
+
+  cmd_loadfont =
+    grub_register_command ("loadfont", loadfont_command,
+                          N_("FILE..."),
+                          N_("Specify one or more font files to load."));
+  cmd_lsfonts =
+    grub_register_command ("lsfonts", lsfonts_command,
+                          0, N_("List the loaded fonts."));
+}
+
+GRUB_MOD_FINI(font)
+{
+  /* TODO: Determine way to free allocated resources.
+     Warning: possible pointer references could be in use.  */
+
+  grub_unregister_command (cmd_loadfont);
+  grub_unregister_command (cmd_lsfonts);
+}
diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c
new file mode 100644 (file)
index 0000000..3dc8075
--- /dev/null
@@ -0,0 +1,550 @@
+/* affs.c - Amiga Fast FileSystem.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+
+/* The affs bootblock.  */
+struct grub_affs_bblock
+{
+  grub_uint8_t type[3];
+  grub_uint8_t flags;
+  grub_uint32_t checksum;
+  grub_uint32_t rootblock;
+} __attribute__ ((packed));
+
+/* Set if the filesystem is a AFFS filesystem.  Otherwise this is an
+   OFS filesystem.  */
+#define GRUB_AFFS_FLAG_FFS     1
+
+/* The affs rootblock.  */
+struct grub_affs_rblock
+{
+  grub_uint8_t type[4];
+  grub_uint8_t unused1[8];
+  grub_uint32_t htsize;
+  grub_uint32_t unused2;
+  grub_uint32_t checksum;
+  grub_uint32_t hashtable[1];
+} __attribute__ ((packed));
+
+/* The second part of a file header block.  */
+struct grub_affs_file
+{
+  grub_uint8_t unused1[12];
+  grub_uint32_t size;
+  grub_uint8_t unused2[104];
+  grub_uint8_t namelen;
+  grub_uint8_t name[30];
+  grub_uint8_t unused3[33];
+  grub_uint32_t next;
+  grub_uint32_t parent;
+  grub_uint32_t extension;
+  grub_int32_t type;
+} __attribute__ ((packed));
+
+/* The location of `struct grub_affs_file' relative to the end of a
+   file header block.  */
+#define        GRUB_AFFS_FILE_LOCATION         200
+
+/* The offset in both the rootblock and the file header block for the
+   hashtable, symlink and block pointers (all synonyms).  */
+#define GRUB_AFFS_HASHTABLE_OFFSET     24
+#define GRUB_AFFS_BLOCKPTR_OFFSET      24
+#define GRUB_AFFS_SYMLINK_OFFSET       24
+
+#define GRUB_AFFS_SYMLINK_SIZE(blocksize) ((blocksize) - 225)
+
+#define GRUB_AFFS_FILETYPE_DIR         -3
+#define GRUB_AFFS_FILETYPE_REG         2
+#define GRUB_AFFS_FILETYPE_SYMLINK     3
+\f
+
+struct grub_fshelp_node
+{
+  struct grub_affs_data *data;
+  int block;
+  int size;
+  int parent;
+};
+
+/* Information about a "mounted" affs filesystem.  */
+struct grub_affs_data
+{
+  struct grub_affs_bblock bblock;
+  struct grub_fshelp_node diropen;
+  grub_disk_t disk;
+
+  /* Blocksize in sectors.  */
+  int blocksize;
+
+  /* The number of entries in the hashtable.  */
+  int htsize;
+};
+
+static grub_dl_t my_mod;
+
+\f
+static grub_disk_addr_t
+grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+{
+  int links;
+  grub_uint32_t pos;
+  int block = node->block;
+  struct grub_affs_file file;
+  struct grub_affs_data *data = node->data;
+  grub_uint32_t mod;
+
+  /* Find the block that points to the fileblock we are looking up by
+     following the chain until the right table is reached.  */
+  for (links = grub_divmod64 (fileblock, data->htsize, &mod); links; links--)
+    {
+      grub_disk_read (data->disk, block + data->blocksize - 1,
+                     data->blocksize * (GRUB_DISK_SECTOR_SIZE
+                                        - GRUB_AFFS_FILE_LOCATION),
+                     sizeof (file), &file);
+      if (grub_errno)
+       return 0;
+
+      block = grub_be_to_cpu32 (file.extension);
+    }
+
+  /* Translate the fileblock to the block within the right table.  */
+  fileblock = mod;
+  grub_disk_read (data->disk, block,
+                 GRUB_AFFS_BLOCKPTR_OFFSET
+                 + (data->htsize - fileblock - 1) * sizeof (pos),
+                 sizeof (pos), &pos);
+  if (grub_errno)
+    return 0;
+
+  return grub_be_to_cpu32 (pos);
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_affs_read_file (grub_fshelp_node_t node,
+                    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                       unsigned offset, unsigned length),
+                    int pos, grub_size_t len, char *buf)
+{
+  return grub_fshelp_read_file (node->data->disk, node, read_hook,
+                               pos, len, buf, grub_affs_read_block,
+                               node->size, 0);
+}
+
+
+static struct grub_affs_data *
+grub_affs_mount (grub_disk_t disk)
+{
+  struct grub_affs_data *data;
+  grub_uint32_t *rootblock = 0;
+  struct grub_affs_rblock *rblock;
+
+  int checksum = 0;
+  int checksumr = 0;
+  int blocksize = 0;
+
+  data = grub_malloc (sizeof (struct grub_affs_data));
+  if (!data)
+    return 0;
+
+  /* Read the bootblock.  */
+  grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock),
+                 &data->bblock);
+  if (grub_errno)
+    goto fail;
+
+  /* Make sure this is an affs filesystem.  */
+  if (grub_strncmp ((char *) (data->bblock.type), "DOS", 3))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not an AFFS filesystem");
+      goto fail;
+    }
+
+  /* Test if the filesystem is a OFS filesystem.  */
+  if (! (data->bblock.flags & GRUB_AFFS_FLAG_FFS))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "OFS not yet supported");
+      goto fail;
+    }
+
+  /* Read the bootblock.  */
+  grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock),
+                 &data->bblock);
+  if (grub_errno)
+    goto fail;
+
+  /* No sane person uses more than 8KB for a block.  At least I hope
+     for that person because in that case this won't work.  */
+  rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE * 16);
+  if (!rootblock)
+    goto fail;
+
+  rblock = (struct grub_affs_rblock *) rootblock;
+
+  /* Read the rootblock.  */
+  grub_disk_read (disk, (disk->total_sectors >> 1) + blocksize, 0,
+                 GRUB_DISK_SECTOR_SIZE * 16, rootblock);
+  if (grub_errno)
+    goto fail;
+
+  /* The filesystem blocksize is not stored anywhere in the filesystem
+     itself.  One way to determine it is reading blocks for the
+     rootblock until the checksum is correct.  */
+  checksumr = grub_be_to_cpu32 (rblock->checksum);
+  rblock->checksum = 0;
+  for (blocksize = 0; blocksize < 8; blocksize++)
+    {
+      grub_uint32_t *currblock = rootblock + GRUB_DISK_SECTOR_SIZE * blocksize;
+      unsigned int i;
+
+      for (i = 0; i < GRUB_DISK_SECTOR_SIZE / sizeof (*currblock); i++)
+       checksum += grub_be_to_cpu32 (currblock[i]);
+
+      if (checksumr == -checksum)
+       break;
+    }
+  if (-checksum != checksumr)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "AFFS blocksize couldn't be determined");
+      goto fail;
+    }
+  blocksize++;
+
+  data->blocksize = blocksize;
+  data->disk = disk;
+  data->htsize = grub_be_to_cpu32 (rblock->htsize);
+  data->diropen.data = data;
+  data->diropen.block = (disk->total_sectors >> 1);
+
+  grub_free (rootblock);
+
+  return data;
+
+ fail:
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not an AFFS filesystem");
+
+  grub_free (data);
+  grub_free (rootblock);
+  return 0;
+}
+
+
+static char *
+grub_affs_read_symlink (grub_fshelp_node_t node)
+{
+  struct grub_affs_data *data = node->data;
+  char *symlink;
+
+  symlink = grub_malloc (GRUB_AFFS_SYMLINK_SIZE (data->blocksize));
+  if (!symlink)
+    return 0;
+
+  grub_disk_read (data->disk, node->block, GRUB_AFFS_SYMLINK_OFFSET,
+                 GRUB_AFFS_SYMLINK_SIZE (data->blocksize), symlink);
+  if (grub_errno)
+    {
+      grub_free (symlink);
+      return 0;
+    }
+  grub_dprintf ("affs", "Symlink: `%s'\n", symlink);
+  return symlink;
+}
+
+
+static int
+grub_affs_iterate_dir (grub_fshelp_node_t dir,
+                      int NESTED_FUNC_ATTR
+                      (*hook) (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node))
+{
+  int i;
+  struct grub_affs_file file;
+  struct grub_fshelp_node *node = 0;
+  struct grub_affs_data *data = dir->data;
+  grub_uint32_t *hashtable;
+
+  auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block,
+                                                  int size, int type);
+
+  int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block,
+                                             int size, int type)
+    {
+      node = grub_malloc (sizeof (*node));
+      if (!node)
+       {
+         grub_free (hashtable);
+         return 1;
+       }
+
+      node->data = data;
+      node->size = size;
+      node->block = block;
+      node->parent = grub_be_to_cpu32 (file.parent);
+
+      if (hook (name, type, node))
+       {
+         grub_free (hashtable);
+         return 1;
+       }
+      return 0;
+    }
+
+  hashtable = grub_malloc (data->htsize * sizeof (*hashtable));
+  if (!hashtable)
+    return 1;
+
+  grub_disk_read (data->disk, dir->block, GRUB_AFFS_HASHTABLE_OFFSET,
+                 data->htsize * sizeof (*hashtable), (char *) hashtable);
+  if (grub_errno)
+    goto fail;
+
+  /* Create the directory entries for `.' and `..'.  */
+  if (grub_affs_create_node (".", dir->block, dir->size, GRUB_FSHELP_DIR))
+    return 1;
+  if (grub_affs_create_node ("..", dir->parent ? dir->parent : dir->block,
+                            dir->size, GRUB_FSHELP_DIR))
+    return 1;
+
+  for (i = 0; i < data->htsize; i++)
+    {
+      enum grub_fshelp_filetype type;
+      grub_uint64_t next;
+
+      if (!hashtable[i])
+       continue;
+
+      /* Every entry in the hashtable can be chained.  Read the entire
+        chain.  */
+      next = grub_be_to_cpu32 (hashtable[i]);
+
+      while (next)
+       {
+         grub_disk_read (data->disk, next + data->blocksize - 1,
+                         data->blocksize * GRUB_DISK_SECTOR_SIZE
+                         - GRUB_AFFS_FILE_LOCATION,
+                         sizeof (file), (char *) &file);
+         if (grub_errno)
+           goto fail;
+
+         file.name[file.namelen] = '\0';
+
+         if ((int) grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_DIR)
+           type = GRUB_FSHELP_REG;
+         else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_REG)
+           type = GRUB_FSHELP_DIR;
+         else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_SYMLINK)
+           type = GRUB_FSHELP_SYMLINK;
+         else
+           type = GRUB_FSHELP_UNKNOWN;
+
+         if (grub_affs_create_node ((char *) (file.name), next,
+                                    grub_be_to_cpu32 (file.size), type))
+           return 1;
+
+         next = grub_be_to_cpu32 (file.next);
+       }
+    }
+
+  grub_free (hashtable);
+  return 0;
+
+ fail:
+  grub_free (node);
+  grub_free (hashtable);
+  return 0;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_affs_open (struct grub_file *file, const char *name)
+{
+  struct grub_affs_data *data;
+  struct grub_fshelp_node *fdiro = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_affs_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_affs_iterate_dir,
+                        grub_affs_read_symlink, GRUB_FSHELP_REG);
+  if (grub_errno)
+    goto fail;
+
+  file->size = fdiro->size;
+  data->diropen = *fdiro;
+  grub_free (fdiro);
+
+  file->data = data;
+  file->offset = 0;
+
+  return 0;
+
+ fail:
+  if (data && fdiro != &data->diropen)
+    grub_free (fdiro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_affs_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+
+/* Read LEN bytes data from FILE into BUF.  */
+static grub_ssize_t
+grub_affs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_affs_data *data =
+    (struct grub_affs_data *) file->data;
+
+  int size = grub_affs_read_file (&data->diropen, file->read_hook,
+                             file->offset, len, buf);
+
+  return size;
+}
+
+
+static grub_err_t
+grub_affs_dir (grub_device_t device, const char *path,
+              int (*hook) (const char *filename,
+                           const struct grub_dirhook_info *info))
+{
+  struct grub_affs_data *data = 0;
+  struct grub_fshelp_node *fdiro = 0;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+                                    enum grub_fshelp_filetype filetype,
+                                    grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+    }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_affs_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_affs_iterate_dir,
+                        grub_affs_read_symlink, GRUB_FSHELP_DIR);
+  if (grub_errno)
+    goto fail;
+
+  grub_affs_iterate_dir (fdiro, iterate);
+
+ fail:
+  if (data && fdiro != &data->diropen)
+    grub_free (fdiro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_affs_label (grub_device_t device, char **label)
+{
+  struct grub_affs_data *data;
+  struct grub_affs_file file;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_affs_mount (disk);
+  if (data)
+    {
+      /* The rootblock maps quite well on a file header block, it's
+        something we can use here.  */
+      grub_disk_read (data->disk, disk->total_sectors >> 1,
+                     data->blocksize * (GRUB_DISK_SECTOR_SIZE
+                                        - GRUB_AFFS_FILE_LOCATION),
+                     sizeof (file), &file);
+      if (grub_errno)
+       return 0;
+
+      *label = grub_strndup ((char *) (file.name), file.namelen);
+    }
+  else
+    *label = 0;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+\f
+static struct grub_fs grub_affs_fs =
+  {
+    .name = "affs",
+    .dir = grub_affs_dir,
+    .open = grub_affs_open,
+    .read = grub_affs_read,
+    .close = grub_affs_close,
+    .label = grub_affs_label,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(affs)
+{
+  grub_fs_register (&grub_affs_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(affs)
+{
+  grub_fs_unregister (&grub_affs_fs);
+}
diff --git a/grub-core/fs/afs.c b/grub-core/fs/afs.c
new file mode 100644 (file)
index 0000000..cd61f4d
--- /dev/null
@@ -0,0 +1,718 @@
+/* afs.c - The native AtheOS file-system.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+
+#ifdef MODE_BIGENDIAN
+#define GRUB_AFS_FSNAME_SUFFIX "_be"
+#else
+#define GRUB_AFS_FSNAME_SUFFIX ""
+#endif
+
+#ifdef MODE_BFS
+#define GRUB_AFS_FSNAME "befs" GRUB_AFS_FSNAME_SUFFIX
+#else
+#define GRUB_AFS_FSNAME "afs" GRUB_AFS_FSNAME_SUFFIX
+#endif
+
+#define        GRUB_AFS_DIRECT_BLOCK_COUNT     12
+#define        GRUB_AFS_BLOCKS_PER_DI_RUN      4
+
+#ifdef MODE_BFS
+#define GRUB_AFS_SBLOCK_SECTOR 1
+#define        GRUB_AFS_SBLOCK_MAGIC1  0x42465331 /* BFS1.  */
+#else
+#define GRUB_AFS_SBLOCK_SECTOR 2
+#define        GRUB_AFS_SBLOCK_MAGIC1  0x41465331 /* AFS1.  */
+#endif
+
+#define        GRUB_AFS_SBLOCK_MAGIC2  0xdd121031
+#define        GRUB_AFS_SBLOCK_MAGIC3  0x15b6830e
+
+#define        GRUB_AFS_INODE_MAGIC    0x64358428
+
+#ifdef MODE_BFS
+#define GRUB_AFS_BTREE_MAGIC   0x69f6c2e8
+#else
+#define GRUB_AFS_BTREE_MAGIC   0x65768995
+#endif
+
+#define GRUB_AFS_BNODE_SIZE    1024
+
+#define GRUB_AFS_S_IFMT                00170000
+#define GRUB_AFS_S_IFLNK       0120000
+
+#define GRUB_AFS_S_IFREG       0100000
+#define GRUB_AFS_S_IFDIR       0040000
+#define GRUB_AFS_S_IFIFO       0010000
+
+#define GRUB_AFS_NULL_VAL      ((grub_afs_bvalue_t)-1)
+
+#ifdef MODE_BIGENDIAN
+#define grub_afs_to_cpu16(x) grub_be_to_cpu16 (x)
+#define grub_afs_to_cpu32(x) grub_be_to_cpu32 (x)
+#define grub_afs_to_cpu64(x) grub_be_to_cpu64 (x)
+#else
+#define grub_afs_to_cpu16(x) grub_le_to_cpu16 (x)
+#define grub_afs_to_cpu32(x) grub_le_to_cpu32 (x)
+#define grub_afs_to_cpu64(x) grub_le_to_cpu64 (x)
+#endif
+
+#ifdef MODE_BFS
+#define B_KEY_INDEX_ALIGN 8
+#else
+#define B_KEY_INDEX_ALIGN 4
+#endif
+
+#define B_KEY_INDEX_OFFSET(node) ((grub_uint16_t *) \
+                                 ((char *) (node) \
+                                  + ALIGN_UP (sizeof (struct grub_afs_bnode) \
+                                              + node->key_size, \
+                                              B_KEY_INDEX_ALIGN)))
+
+#define B_KEY_VALUE_OFFSET(node) ((grub_afs_bvalue_t *) \
+                                   ((char *) B_KEY_INDEX_OFFSET (node) + \
+                                    node->key_count * 2))
+
+typedef grub_uint64_t grub_afs_off_t;
+typedef grub_uint64_t grub_afs_bigtime;
+typedef grub_uint64_t grub_afs_bvalue_t;
+
+struct grub_afs_blockrun
+{
+  grub_uint32_t group;
+  grub_uint16_t start;
+  grub_uint16_t len;
+} __attribute__ ((packed));
+
+struct grub_afs_datastream
+{
+  struct grub_afs_blockrun direct[GRUB_AFS_DIRECT_BLOCK_COUNT];
+  grub_afs_off_t max_direct_range;
+  struct grub_afs_blockrun indirect;
+  grub_afs_off_t max_indirect_range;
+  struct grub_afs_blockrun double_indirect;
+  grub_afs_off_t max_double_indirect_range;
+  grub_afs_off_t size;
+} __attribute__ ((packed));
+
+struct grub_afs_bnode
+{
+  grub_afs_bvalue_t left;
+  grub_afs_bvalue_t right;
+  grub_afs_bvalue_t overflow;
+#ifdef MODE_BFS
+  grub_uint16_t key_count;
+  grub_uint16_t key_size;
+#else
+  grub_uint32_t key_count;
+  grub_uint32_t key_size;
+#endif
+  char key_data[0];
+} __attribute__ ((packed));
+
+#ifdef MODE_BFS
+struct grub_afs_btree
+{
+  grub_uint32_t magic;
+  grub_uint32_t unused1;
+  grub_uint32_t tree_depth;
+  grub_uint32_t unused2;
+  grub_afs_bvalue_t root;
+  grub_uint32_t unused3[4];
+} __attribute__ ((packed));
+#else
+struct grub_afs_btree
+{
+  grub_uint32_t magic;
+  grub_afs_bvalue_t root;
+  grub_uint32_t tree_depth;
+  grub_afs_bvalue_t last_node;
+  grub_afs_bvalue_t first_free;
+} __attribute__ ((packed));
+#endif
+
+/* Beware that following structure describes AtheFS and if you write code
+   which uses currently unused fields check it with both AtheFS and BeFS.
+ */
+struct grub_afs_sblock
+{
+  char name[32];
+  grub_uint32_t magic1;
+  grub_uint32_t byte_order;
+  grub_uint32_t        block_size;
+  grub_uint32_t block_shift;
+  grub_afs_off_t num_blocks;
+  grub_afs_off_t used_blocks;
+  grub_uint32_t        inode_size;
+  grub_uint32_t        magic2;
+  grub_uint32_t        block_per_group; /* Number of blocks per allocation
+                                   group. (Max 65536)  */
+  grub_uint32_t        alloc_group_shift; /* Number of bits to shift a group
+                                     number to get a byte address.  */
+  grub_uint32_t        alloc_group_count;
+  grub_uint32_t        flags;
+  struct grub_afs_blockrun log_block;
+  grub_afs_off_t log_start;
+  grub_uint32_t valid_log_blocks;
+  grub_uint32_t log_size;
+  grub_uint32_t        magic3;
+  struct grub_afs_blockrun root_dir; /* Root dir inode.  */
+  struct grub_afs_blockrun deleted_files; /* Directory containing files
+                                            scheduled for deletion.  */
+  struct grub_afs_blockrun index_dir; /* Directory of index files.  */
+  grub_uint32_t boot_loader_size;
+  grub_uint32_t        pad[7];
+}  __attribute__ ((packed));
+
+struct grub_afs_inode
+{
+  grub_uint32_t magic1;
+  struct grub_afs_blockrun inode_num;
+  grub_uint32_t uid;
+  grub_uint32_t gid;
+  grub_uint32_t mode;
+  grub_uint32_t flags;
+#ifndef MODE_BFS
+  grub_uint32_t link_count;
+#endif
+  grub_afs_bigtime create_time;
+  grub_afs_bigtime modified_time;
+  struct grub_afs_blockrun parent;
+  struct grub_afs_blockrun attrib_dir;
+  grub_uint32_t index_type; /* Key data-key only used for index files. */
+  grub_uint32_t inode_size;
+  grub_uint32_t unused;
+  struct grub_afs_datastream stream;
+  grub_uint32_t        pad[4];
+  grub_uint32_t small_data[1];
+} __attribute__ ((packed));
+
+struct grub_fshelp_node
+{
+  struct grub_afs_data *data;
+  struct grub_afs_inode inode;
+};
+
+struct grub_afs_data
+{
+  grub_disk_t disk;
+  struct grub_afs_sblock sblock;
+  struct grub_afs_inode *inode;
+  struct grub_fshelp_node diropen;
+};
+
+static grub_dl_t my_mod;
+
+static grub_afs_off_t
+grub_afs_run_to_num (struct grub_afs_sblock *sb,
+                     struct grub_afs_blockrun *run)
+{
+  return ((grub_afs_off_t) grub_afs_to_cpu32 (run->group)
+         * sb->block_per_group + grub_afs_to_cpu16 (run->start));
+}
+
+static grub_err_t
+grub_afs_read_inode (struct grub_afs_data *data,
+                     grub_uint32_t ino, struct grub_afs_inode *inode)
+{
+  return grub_disk_read (data->disk,
+                         ino *
+                         (data->sblock.block_size >> GRUB_DISK_SECTOR_BITS),
+                         0, sizeof (struct grub_afs_inode),
+                         inode);
+}
+
+static grub_disk_addr_t
+grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+{
+  struct grub_afs_sblock *sb = &node->data->sblock;
+  struct grub_afs_datastream *ds = &node->inode.stream;
+
+  if (fileblock < grub_afs_to_cpu64 (ds->max_direct_range))
+    {
+      int i;
+
+      for (i = 0; i < GRUB_AFS_DIRECT_BLOCK_COUNT; i++)
+        {
+          if (fileblock < grub_afs_to_cpu16 (ds->direct[i].len))
+            return grub_afs_run_to_num (sb, &ds->direct[i]) + fileblock;
+          fileblock -= grub_afs_to_cpu16 (ds->direct[i].len);
+        }
+    }
+  else if (fileblock < grub_afs_to_cpu64 (ds->max_indirect_range))
+    {
+      int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun);
+      struct grub_afs_blockrun indir[ptrs_per_blk];
+      grub_afs_off_t blk = grub_afs_run_to_num (sb, &ds->indirect);
+      int i;
+
+      fileblock -= grub_afs_to_cpu64 (ds->max_direct_range);
+      for (i = 0; i < ds->indirect.len; i++, blk++)
+        {
+          int j;
+
+          if (grub_disk_read (node->data->disk,
+                              blk * (sb->block_size >> GRUB_DISK_SECTOR_BITS),
+                              0, sizeof (indir),
+                              indir))
+            return 0;
+
+          for (j = 0; j < ptrs_per_blk; j++)
+            {
+              if (fileblock < grub_afs_to_cpu16 (indir[j].len))
+                return grub_afs_run_to_num (sb, &indir[j]) + fileblock;
+
+              fileblock -= grub_afs_to_cpu16 (indir[j].len);
+            }
+        }
+    }
+  else
+    {
+      int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun);
+      struct grub_afs_blockrun indir[ptrs_per_blk];
+
+      /* ([idblk][idptr]) ([dblk][dptr]) [blk]  */
+      int cur_pos = fileblock - grub_afs_to_cpu64 (ds->max_indirect_range);
+
+      int dptr_size = GRUB_AFS_BLOCKS_PER_DI_RUN;
+      int dblk_size = dptr_size * ptrs_per_blk;
+      int idptr_size = dblk_size * GRUB_AFS_BLOCKS_PER_DI_RUN;
+      int idblk_size = idptr_size * ptrs_per_blk;
+
+      int off = cur_pos % GRUB_AFS_BLOCKS_PER_DI_RUN;
+      int dptr = (cur_pos / dptr_size) % ptrs_per_blk;
+      int dblk = (cur_pos / dblk_size) % GRUB_AFS_BLOCKS_PER_DI_RUN;
+      int idptr = (cur_pos / idptr_size) % ptrs_per_blk;
+      int idblk = (cur_pos / idblk_size);
+
+      if (grub_disk_read (node->data->disk,
+                          (grub_afs_run_to_num (sb, &ds->double_indirect)
+                           + idblk) *
+                          (sb->block_size >> GRUB_DISK_SECTOR_BITS),
+                          0, sizeof (indir),
+                          indir))
+        return 0;
+
+      if (grub_disk_read (node->data->disk,
+                          (grub_afs_run_to_num (sb, &indir[idptr]) + dblk) *
+                          (sb->block_size >> GRUB_DISK_SECTOR_BITS),
+                          0, sizeof (indir),
+                          indir))
+        return 0;
+
+      return grub_afs_run_to_num (sb, &indir[dptr]) + off;
+    }
+
+  return 0;
+}
+
+static grub_ssize_t
+grub_afs_read_file (grub_fshelp_node_t node,
+                    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                                        unsigned offset, unsigned length),
+                    int pos, grub_size_t len, char *buf)
+{
+  return grub_fshelp_read_file (node->data->disk, node, read_hook,
+                               pos, len, buf, grub_afs_read_block,
+                                grub_afs_to_cpu64 (node->inode.stream.size),
+                               node->data->sblock.block_shift
+                                - GRUB_DISK_SECTOR_BITS);
+}
+
+static char *
+grub_afs_read_symlink (grub_fshelp_node_t node)
+{
+  char *ret;
+  grub_afs_off_t size = grub_afs_to_cpu64 (node->inode.stream.size);
+
+  if (size == 0)
+    {
+      size = sizeof (node->inode.stream);
+      ret = grub_zalloc (size + 1);
+      if (! ret)
+       return 0;
+      grub_memcpy (ret, (char *) &(node->inode.stream),
+                  sizeof (node->inode.stream));
+      return ret;
+    }
+  ret = grub_zalloc (size + 1);
+  if (! ret)
+    return 0;
+  grub_afs_read_file (node, 0, 0, size, ret);
+  return ret;
+}
+
+static int
+grub_afs_iterate_dir (grub_fshelp_node_t dir,
+                      int NESTED_FUNC_ATTR
+                      (*hook) (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node))
+{
+  struct grub_afs_btree head;
+  char node_data [GRUB_AFS_BNODE_SIZE];
+  struct grub_afs_bnode *node = (struct grub_afs_bnode *) node_data;
+  int i;
+
+  if ((dir->inode.stream.size == 0)
+      || ((grub_afs_to_cpu32 (dir->inode.mode) & GRUB_AFS_S_IFMT)
+         != GRUB_AFS_S_IFDIR))
+    return 0;
+
+  grub_afs_read_file (dir, 0, 0, sizeof (head), (char *) &head);
+  if (grub_errno)
+    return 0;
+
+  grub_afs_read_file (dir, 0, grub_afs_to_cpu64 (head.root),
+                      GRUB_AFS_BNODE_SIZE, (char *) node);
+  if (grub_errno)
+    return 0;
+
+  for (i = 0; i < (int) grub_afs_to_cpu32 (head.tree_depth) - 1; i++)
+    {
+      grub_afs_bvalue_t blk;
+
+      blk = grub_afs_to_cpu64(B_KEY_VALUE_OFFSET (node) [0]);
+      grub_afs_read_file (dir, 0, blk, GRUB_AFS_BNODE_SIZE, (char *) node);
+      if (grub_errno)
+        return 0;
+    }
+
+  if (node->key_count)
+    {
+      grub_uint32_t cur_key = 0;
+
+      while (1)
+        {
+          int key_start, key_size;
+          grub_uint16_t *index;
+
+          index = B_KEY_INDEX_OFFSET (node);
+
+         key_start = (cur_key > 0)
+           ? grub_afs_to_cpu16 (index[cur_key - 1]) : 0;
+          key_size = grub_afs_to_cpu16 (index[cur_key]) - key_start;
+          if (key_size > 0)
+            {
+              char filename [key_size + 1];
+              struct grub_fshelp_node *fdiro;
+              int mode, type;
+
+              fdiro = grub_malloc (sizeof (struct grub_fshelp_node));
+              if (! fdiro)
+                return 0;
+
+              fdiro->data = dir->data;
+              if (grub_afs_read_inode (dir->data,
+                                       grub_afs_to_cpu64
+                                      (B_KEY_VALUE_OFFSET (node) [cur_key]),
+                                       &fdiro->inode))
+                return 0;
+
+              grub_memcpy (filename, &node->key_data[key_start], key_size);
+              filename [key_size] = 0;
+
+              mode = (grub_afs_to_cpu32 (fdiro->inode.mode) & GRUB_AFS_S_IFMT);
+              if (mode == GRUB_AFS_S_IFDIR)
+                type = GRUB_FSHELP_DIR;
+              else if (mode == GRUB_AFS_S_IFREG)
+                type = GRUB_FSHELP_REG;
+             else if (mode == GRUB_AFS_S_IFLNK)
+               type = GRUB_FSHELP_SYMLINK;
+              else
+                type = GRUB_FSHELP_UNKNOWN;
+
+              if (hook (filename, type, fdiro))
+                return 1;
+            }
+
+          cur_key++;
+          if (cur_key >= grub_afs_to_cpu32 (node->key_count))
+            {
+              if (node->right == GRUB_AFS_NULL_VAL)
+                break;
+
+              grub_afs_read_file (dir, 0, grub_afs_to_cpu64 (node->right),
+                                  GRUB_AFS_BNODE_SIZE, (char *) node);
+              if (grub_errno)
+                return 0;
+
+              cur_key = 0;
+            }
+        }
+    }
+
+  return 0;
+}
+
+static int
+grub_afs_validate_sblock (struct grub_afs_sblock *sb)
+{
+  if (grub_afs_to_cpu32 (sb->magic1) == GRUB_AFS_SBLOCK_MAGIC1)
+    {
+      sb->magic2 = grub_afs_to_cpu32 (sb->magic2);
+      sb->magic3 = grub_afs_to_cpu32 (sb->magic3);
+      sb->block_shift = grub_afs_to_cpu32 (sb->block_shift);
+      sb->block_size = grub_afs_to_cpu32 (sb->block_size);
+      sb->used_blocks = grub_afs_to_cpu64 (sb->used_blocks);
+      sb->num_blocks = grub_afs_to_cpu64 (sb->num_blocks);
+      sb->inode_size = grub_afs_to_cpu32 (sb->inode_size);
+      sb->alloc_group_count = grub_afs_to_cpu32 (sb->alloc_group_count);
+      sb->alloc_group_shift = grub_afs_to_cpu32 (sb->alloc_group_shift);
+      sb->block_per_group = grub_afs_to_cpu32 (sb->block_per_group);
+      sb->alloc_group_count = grub_afs_to_cpu32 (sb->alloc_group_count);
+      sb->log_size = grub_afs_to_cpu32 (sb->log_size);
+    }
+  else
+    return 0;
+
+  if ((sb->magic2 != GRUB_AFS_SBLOCK_MAGIC2) ||
+      (sb->magic3 != GRUB_AFS_SBLOCK_MAGIC3))
+    return 0;
+
+#ifdef MODE_BFS
+  sb->block_per_group = 1 << (sb->alloc_group_shift);
+#endif
+
+  if (((grub_uint32_t) (1 << sb->block_shift) != sb->block_size)
+      || (sb->used_blocks > sb->num_blocks )
+      || (sb->inode_size != sb->block_size)
+      || (0 == sb->block_size)
+#ifndef MODE_BFS
+      || ((grub_uint32_t) (1 << sb->alloc_group_shift) !=
+         sb->block_per_group * sb->block_size)
+      || (sb->alloc_group_count * sb->block_per_group < sb->num_blocks)
+      || (grub_afs_to_cpu16 (sb->log_block.len) != sb->log_size)
+      || (grub_afs_to_cpu32 (sb->valid_log_blocks) > sb->log_size)
+#endif
+      )
+    return 0;
+
+  return 1;
+}
+
+static struct grub_afs_data *
+grub_afs_mount (grub_disk_t disk)
+{
+  struct grub_afs_data *data = 0;
+
+  data = grub_malloc (sizeof (struct grub_afs_data));
+  if (!data)
+    return 0;
+
+  /* Read the superblock.  */
+  if (grub_disk_read (disk, GRUB_AFS_SBLOCK_SECTOR, 0,
+                     sizeof (struct grub_afs_sblock), &data->sblock))
+    goto fail;
+
+  if (! grub_afs_validate_sblock (&data->sblock))
+    goto fail;
+
+  data->diropen.data = data;
+  data->inode = &data->diropen.inode;
+  data->disk = disk;
+
+  if (grub_afs_read_inode (data,
+                           grub_afs_run_to_num (&data->sblock,
+                                                &data->sblock.root_dir),
+                           data->inode))
+    goto fail;
+
+  return data;
+
+fail:
+  grub_error (GRUB_ERR_BAD_FS, "not an " GRUB_AFS_FSNAME " filesystem");
+
+  grub_free (data);
+  return 0;
+}
+
+static grub_err_t
+grub_afs_open (struct grub_file *file, const char *name)
+{
+  struct grub_afs_data *data;
+  struct grub_fshelp_node *fdiro = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_afs_mount (file->device->disk);
+  if (! data)
+    goto fail;
+
+  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_afs_iterate_dir,
+                        grub_afs_read_symlink, GRUB_FSHELP_REG);
+  if (grub_errno)
+    goto fail;
+
+  grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_afs_inode));
+  grub_free (fdiro);
+
+  file->size = grub_afs_to_cpu64 (data->inode->stream.size);
+  file->data = data;
+  file->offset = 0;
+
+  return 0;
+
+fail:
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_ssize_t
+grub_afs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_afs_data *data = (struct grub_afs_data *) file->data;
+
+  return grub_afs_read_file (&data->diropen, file->read_hook,
+                             file->offset, len, buf);
+}
+
+static grub_err_t
+grub_afs_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_afs_dir (grub_device_t device, const char *path,
+              int (*hook) (const char *filename,
+                          const struct grub_dirhook_info *info))
+{
+  struct grub_afs_data *data = 0;
+  struct grub_fshelp_node *fdiro = 0;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+                                    enum grub_fshelp_filetype filetype,
+                                    grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      info.mtimeset = 1;
+#ifdef MODE_BFS
+      info.mtime = grub_afs_to_cpu64 (node->inode.modified_time) >> 16;
+#else
+      info.mtime = grub_divmod64 (grub_afs_to_cpu64 (node->inode.modified_time),
+                                 1000000, 0);
+#endif
+      grub_free (node);
+      return hook (filename, &info);
+    }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_afs_mount (device->disk);
+  if (! data)
+    goto fail;
+
+  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_afs_iterate_dir,
+                        grub_afs_read_symlink, GRUB_FSHELP_DIR);
+  if (grub_errno)
+    goto fail;
+
+  grub_afs_iterate_dir (fdiro, iterate);
+
+  if (fdiro != &data->diropen)
+    grub_free (fdiro);
+
+ fail:
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_afs_label (grub_device_t device, char **label)
+{
+  struct grub_afs_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_afs_mount (disk);
+  if (data)
+    *label = grub_strndup (data->sblock.name, sizeof (data->sblock.name));
+  else
+    *label = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+static struct grub_fs grub_afs_fs = {
+  .name = GRUB_AFS_FSNAME,
+  .dir = grub_afs_dir,
+  .open = grub_afs_open,
+  .read = grub_afs_read,
+  .close = grub_afs_close,
+  .label = grub_afs_label,
+  .next = 0
+};
+
+#if defined (MODE_BIGENDIAN) && defined (MODE_BFS)
+GRUB_MOD_INIT (befs_be)
+#elif defined (MODE_BFS)
+GRUB_MOD_INIT (befs)
+#elif defined (MODE_BIGENDIAN)
+GRUB_MOD_INIT (afs_be)
+#else
+GRUB_MOD_INIT (afs)
+#endif
+{
+  grub_fs_register (&grub_afs_fs);
+  my_mod = mod;
+}
+
+#if defined (MODE_BIGENDIAN) && defined (MODE_BFS)
+GRUB_MOD_FINI (befs_be)
+#elif defined (MODE_BFS)
+GRUB_MOD_FINI (befs)
+#elif defined (MODE_BIGENDIAN)
+GRUB_MOD_FINI (afs_be)
+#else
+GRUB_MOD_FINI (afs)
+#endif
+{
+  grub_fs_unregister (&grub_afs_fs);
+}
diff --git a/grub-core/fs/afs_be.c b/grub-core/fs/afs_be.c
new file mode 100644 (file)
index 0000000..1f1f48f
--- /dev/null
@@ -0,0 +1,2 @@
+#define MODE_BIGENDIAN 1
+#include "afs.c"
diff --git a/grub-core/fs/befs.c b/grub-core/fs/befs.c
new file mode 100644 (file)
index 0000000..c54d8e1
--- /dev/null
@@ -0,0 +1,3 @@
+/* befs.c - The native BeOS/Haiku file-system.  */
+#define MODE_BFS 1
+#include "afs.c"
diff --git a/grub-core/fs/befs_be.c b/grub-core/fs/befs_be.c
new file mode 100644 (file)
index 0000000..f6e8179
--- /dev/null
@@ -0,0 +1,4 @@
+/* befs.c - The native BeOS/Haiku file-system.  */
+#define MODE_BFS 1
+#define MODE_BIGENDIAN 1
+#include "afs.c"
diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c
new file mode 100644 (file)
index 0000000..c087b4f
--- /dev/null
@@ -0,0 +1,376 @@
+/* cpio.c - cpio and tar filesystem.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008,2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+
+#ifndef MODE_USTAR
+/* cpio support */
+#define        MAGIC_BCPIO     070707
+struct head
+{
+  grub_uint16_t magic;
+  grub_uint16_t dev;
+  grub_uint16_t ino;
+  grub_uint16_t mode;
+  grub_uint16_t uid;
+  grub_uint16_t gid;
+  grub_uint16_t nlink;
+  grub_uint16_t rdev;
+  grub_uint16_t mtime_1;
+  grub_uint16_t mtime_2;
+  grub_uint16_t namesize;
+  grub_uint16_t filesize_1;
+  grub_uint16_t filesize_2;
+} __attribute__ ((packed));
+#else
+/* tar support */
+#define MAGIC_USTAR    "ustar"
+struct head
+{
+  char name[100];
+  char mode[8];
+  char uid[8];
+  char gid[8];
+  char size[12];
+  char mtime[12];
+  char chksum[8];
+  char typeflag;
+  char linkname[100];
+  char magic[6];
+  char version[2];
+  char uname[32];
+  char gname[32];
+  char devmajor[8];
+  char devminor[8];
+  char prefix[155];
+} __attribute__ ((packed));
+#endif
+
+struct grub_cpio_data
+{
+  grub_disk_t disk;
+  grub_uint32_t hofs;
+  grub_uint32_t dofs;
+  grub_uint32_t size;
+};
+
+static grub_dl_t my_mod;
+
+static grub_err_t
+grub_cpio_find_file (struct grub_cpio_data *data, char **name,
+                    grub_uint32_t * ofs)
+{
+#ifndef MODE_USTAR
+      struct head hd;
+
+      if (grub_disk_read
+         (data->disk, 0, data->hofs, sizeof (hd), &hd))
+       return grub_errno;
+
+      if (hd.magic != MAGIC_BCPIO)
+       return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive");
+
+      data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2;
+
+      if (hd.namesize & 1)
+       hd.namesize++;
+
+      if ((*name = grub_malloc (hd.namesize)) == NULL)
+       return grub_errno;
+
+      if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd),
+                         hd.namesize, *name))
+       {
+         grub_free (*name);
+         return grub_errno;
+       }
+
+      if (data->size == 0 && hd.mode == 0 && hd.namesize == 11 + 1
+         && ! grub_memcmp(*name, "TRAILER!!!", 11))
+       {
+         *ofs = 0;
+         return GRUB_ERR_NONE;
+       }
+
+      data->dofs = data->hofs + sizeof (hd) + hd.namesize;
+      *ofs = data->dofs + data->size;
+      if (data->size & 1)
+       (*ofs)++;
+#else
+      struct head hd;
+
+      if (grub_disk_read
+         (data->disk, 0, data->hofs, sizeof (hd), &hd))
+       return grub_errno;
+
+      if (!hd.name[0])
+       {
+         *ofs = 0;
+         return GRUB_ERR_NONE;
+       }
+
+      if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1))
+       return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive");
+
+      if ((*name = grub_strdup (hd.name)) == NULL)
+       return grub_errno;
+
+      data->size = grub_strtoul (hd.size, NULL, 8);
+      data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE;
+      *ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) &
+                          ~(GRUB_DISK_SECTOR_SIZE - 1));
+#endif
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_cpio_data *
+grub_cpio_mount (grub_disk_t disk)
+{
+  struct head hd;
+  struct grub_cpio_data *data;
+
+  if (grub_disk_read (disk, 0, 0, sizeof (hd), &hd))
+    goto fail;
+
+#ifndef MODE_USTAR
+  if (hd.magic != MAGIC_BCPIO)
+#else
+  if (grub_memcmp (hd.magic, MAGIC_USTAR,
+                  sizeof (MAGIC_USTAR) - 1))
+#endif
+    goto fail;
+
+  data = (struct grub_cpio_data *) grub_malloc (sizeof (*data));
+  if (!data)
+    goto fail;
+
+  data->disk = disk;
+
+  return data;
+
+fail:
+  grub_error (GRUB_ERR_BAD_FS, "not a "
+#ifdef MODE_USTAR
+             "tar"
+#else
+             "cpio"
+#endif
+             " filesystem");
+  return 0;
+}
+
+static grub_err_t
+grub_cpio_dir (grub_device_t device, const char *path,
+              int (*hook) (const char *filename,
+                           const struct grub_dirhook_info *info))
+{
+  struct grub_cpio_data *data;
+  grub_uint32_t ofs;
+  char *prev, *name;
+  const char *np;
+  int len;
+
+  grub_dl_ref (my_mod);
+
+  prev = 0;
+
+  data = grub_cpio_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  np = path + 1;
+  len = grub_strlen (path) - 1;
+
+  data->hofs = 0;
+  while (1)
+    {
+      if (grub_cpio_find_file (data, &name, &ofs))
+       goto fail;
+
+      if (!ofs)
+       break;
+
+      if (grub_memcmp (np, name, len) == 0)
+       {
+         char *p, *n;
+
+         n = name + len;
+         if (*n == '/')
+           n++;
+
+         p = grub_strchr (name + len, '/');
+         if (p)
+           *p = 0;
+
+         if ((!prev) || (grub_strcmp (prev, name) != 0))
+           {
+             struct grub_dirhook_info info;
+             grub_memset (&info, 0, sizeof (info));
+             info.dir = (p != NULL);
+
+             hook (name + len, &info);
+             if (prev)
+               grub_free (prev);
+             prev = name;
+           }
+         else
+           grub_free (name);
+       }
+      data->hofs = ofs;
+    }
+
+fail:
+
+  if (prev)
+    grub_free (prev);
+
+  if (data)
+    grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cpio_open (grub_file_t file, const char *name)
+{
+  struct grub_cpio_data *data;
+  grub_uint32_t ofs;
+  char *fn;
+  int i, j;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_cpio_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  data->hofs = 0;
+  while (1)
+    {
+      if (grub_cpio_find_file (data, &fn, &ofs))
+       goto fail;
+
+      if (!ofs)
+       {
+         grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+         break;
+       }
+
+      /* Compare NAME and FN by hand in order to cope with duplicate
+        slashes.  */
+      i = 0;
+      j = 0;
+      while (name[i] == '/')
+       i++;
+      while (1)
+       {
+         if (name[i] != fn[j])
+           goto no_match;
+
+         if (name[i] == '\0')
+           break;
+
+         while (name[i] == '/' && name[i+1] == '/')
+           i++;
+
+         i++;
+         j++;
+       }
+
+      if (name[i] != fn[j])
+       goto no_match;
+
+      file->data = data;
+      file->size = data->size;
+      grub_free (fn);
+
+      return GRUB_ERR_NONE;
+
+    no_match:
+
+      grub_free (fn);
+      data->hofs = ofs;
+    }
+
+fail:
+
+  if (data)
+    grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_ssize_t
+grub_cpio_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_cpio_data *data;
+
+  data = file->data;
+  return (grub_disk_read (data->disk, 0, data->dofs + file->offset,
+                         len, buf)) ? -1 : (grub_ssize_t) len;
+}
+
+static grub_err_t
+grub_cpio_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static struct grub_fs grub_cpio_fs = {
+#ifdef MODE_USTAR
+  .name = "tarfs",
+#else
+  .name = "cpiofs",
+#endif
+  .dir = grub_cpio_dir,
+  .open = grub_cpio_open,
+  .read = grub_cpio_read,
+  .close = grub_cpio_close,
+};
+
+#ifdef MODE_USTAR
+GRUB_MOD_INIT (tar)
+#else
+GRUB_MOD_INIT (cpio)
+#endif
+{
+  grub_fs_register (&grub_cpio_fs);
+  my_mod = mod;
+}
+
+#ifdef MODE_USTAR
+GRUB_MOD_FINI (tar)
+#else
+GRUB_MOD_FINI (cpio)
+#endif
+{
+  grub_fs_unregister (&grub_cpio_fs);
+}
diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
new file mode 100644 (file)
index 0000000..f2fec82
--- /dev/null
@@ -0,0 +1,951 @@
+/* ext2.c - Second Extended filesystem */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Magic value used to identify an ext2 filesystem.  */
+#define        EXT2_MAGIC              0xEF53
+/* Amount of indirect blocks in an inode.  */
+#define INDIRECT_BLOCKS                12
+/* Maximum length of a pathname.  */
+#define EXT2_PATH_MAX          4096
+/* Maximum nesting of symlinks, used to prevent a loop.  */
+#define        EXT2_MAX_SYMLINKCNT     8
+
+/* The good old revision and the default inode size.  */
+#define EXT2_GOOD_OLD_REVISION         0
+#define EXT2_GOOD_OLD_INODE_SIZE       128
+
+/* Filetype used in directory entry.  */
+#define        FILETYPE_UNKNOWN        0
+#define        FILETYPE_REG            1
+#define        FILETYPE_DIRECTORY      2
+#define        FILETYPE_SYMLINK        7
+
+/* Filetype information as used in inodes.  */
+#define FILETYPE_INO_MASK      0170000
+#define FILETYPE_INO_REG       0100000
+#define FILETYPE_INO_DIRECTORY 0040000
+#define FILETYPE_INO_SYMLINK   0120000
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+
+/* Log2 size of ext2 block in 512 blocks.  */
+#define LOG2_EXT2_BLOCK_SIZE(data)                     \
+       (grub_le_to_cpu32 (data->sblock.log2_block_size) + 1)
+
+/* Log2 size of ext2 block in bytes.  */
+#define LOG2_BLOCK_SIZE(data)                                  \
+       (grub_le_to_cpu32 (data->sblock.log2_block_size) + 10)
+
+/* The size of an ext2 block in bytes.  */
+#define EXT2_BLOCK_SIZE(data)          (1 << LOG2_BLOCK_SIZE (data))
+
+/* The revision level.  */
+#define EXT2_REVISION(data)    grub_le_to_cpu32 (data->sblock.revision_level)
+
+/* The inode size.  */
+#define EXT2_INODE_SIZE(data)  \
+        (EXT2_REVISION (data) == EXT2_GOOD_OLD_REVISION \
+         ? EXT2_GOOD_OLD_INODE_SIZE \
+         : grub_le_to_cpu16 (data->sblock.inode_size))
+
+/* Superblock filesystem feature flags (RW compatible)
+ * A filesystem with any of these enabled can be read and written by a driver
+ * that does not understand them without causing metadata/data corruption.  */
+#define EXT2_FEATURE_COMPAT_DIR_PREALLOC       0x0001
+#define EXT2_FEATURE_COMPAT_IMAGIC_INODES      0x0002
+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL                0x0004
+#define EXT2_FEATURE_COMPAT_EXT_ATTR           0x0008
+#define EXT2_FEATURE_COMPAT_RESIZE_INODE       0x0010
+#define EXT2_FEATURE_COMPAT_DIR_INDEX          0x0020
+/* Superblock filesystem feature flags (RO compatible)
+ * A filesystem with any of these enabled can be safely read by a driver that
+ * does not understand them, but should not be written to, usually because
+ * additional metadata is required.  */
+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
+#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR       0x0004
+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM                0x0010
+#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK       0x0020
+#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE     0x0040
+/* Superblock filesystem feature flags (back-incompatible)
+ * A filesystem with any of these enabled should not be attempted to be read
+ * by a driver that does not understand them, since they usually indicate
+ * metadata format changes that might confuse the reader.  */
+#define EXT2_FEATURE_INCOMPAT_COMPRESSION      0x0001
+#define EXT2_FEATURE_INCOMPAT_FILETYPE         0x0002
+#define EXT3_FEATURE_INCOMPAT_RECOVER          0x0004 /* Needs recovery */
+#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV      0x0008 /* Volume is journal device */
+#define EXT2_FEATURE_INCOMPAT_META_BG          0x0010
+#define EXT4_FEATURE_INCOMPAT_EXTENTS          0x0040 /* Extents used */
+#define EXT4_FEATURE_INCOMPAT_64BIT            0x0080
+#define EXT4_FEATURE_INCOMPAT_FLEX_BG          0x0200
+
+/* The set of back-incompatible features this driver DOES support. Add (OR)
+ * flags here as the related features are implemented into the driver.  */
+#define EXT2_DRIVER_SUPPORTED_INCOMPAT ( EXT2_FEATURE_INCOMPAT_FILETYPE \
+                                       | EXT4_FEATURE_INCOMPAT_EXTENTS  \
+                                       | EXT4_FEATURE_INCOMPAT_FLEX_BG )
+/* List of rationales for the ignored "incompatible" features:
+ * needs_recovery: Not really back-incompatible - was added as such to forbid
+ *                 ext2 drivers from mounting an ext3 volume with a dirty
+ *                 journal because they will ignore the journal, but the next
+ *                 ext3 driver to mount the volume will find the journal and
+ *                 replay it, potentially corrupting the metadata written by
+ *                 the ext2 drivers. Safe to ignore for this RO driver.  */
+#define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER )
+
+
+#define EXT3_JOURNAL_MAGIC_NUMBER      0xc03b3998U
+
+#define EXT3_JOURNAL_DESCRIPTOR_BLOCK  1
+#define EXT3_JOURNAL_COMMIT_BLOCK      2
+#define EXT3_JOURNAL_SUPERBLOCK_V1     3
+#define EXT3_JOURNAL_SUPERBLOCK_V2     4
+#define EXT3_JOURNAL_REVOKE_BLOCK      5
+
+#define EXT3_JOURNAL_FLAG_ESCAPE       1
+#define EXT3_JOURNAL_FLAG_SAME_UUID    2
+#define EXT3_JOURNAL_FLAG_DELETED      4
+#define EXT3_JOURNAL_FLAG_LAST_TAG     8
+
+#define EXT4_EXTENTS_FLAG              0x80000
+
+/* The ext2 superblock.  */
+struct grub_ext2_sblock
+{
+  grub_uint32_t total_inodes;
+  grub_uint32_t total_blocks;
+  grub_uint32_t reserved_blocks;
+  grub_uint32_t free_blocks;
+  grub_uint32_t free_inodes;
+  grub_uint32_t first_data_block;
+  grub_uint32_t log2_block_size;
+  grub_uint32_t log2_fragment_size;
+  grub_uint32_t blocks_per_group;
+  grub_uint32_t fragments_per_group;
+  grub_uint32_t inodes_per_group;
+  grub_uint32_t mtime;
+  grub_uint32_t utime;
+  grub_uint16_t mnt_count;
+  grub_uint16_t max_mnt_count;
+  grub_uint16_t magic;
+  grub_uint16_t fs_state;
+  grub_uint16_t error_handling;
+  grub_uint16_t minor_revision_level;
+  grub_uint32_t lastcheck;
+  grub_uint32_t checkinterval;
+  grub_uint32_t creator_os;
+  grub_uint32_t revision_level;
+  grub_uint16_t uid_reserved;
+  grub_uint16_t gid_reserved;
+  grub_uint32_t first_inode;
+  grub_uint16_t inode_size;
+  grub_uint16_t block_group_number;
+  grub_uint32_t feature_compatibility;
+  grub_uint32_t feature_incompat;
+  grub_uint32_t feature_ro_compat;
+  grub_uint16_t uuid[8];
+  char volume_name[16];
+  char last_mounted_on[64];
+  grub_uint32_t compression_info;
+  grub_uint8_t prealloc_blocks;
+  grub_uint8_t prealloc_dir_blocks;
+  grub_uint16_t reserved_gdt_blocks;
+  grub_uint8_t journal_uuid[16];
+  grub_uint32_t journal_inum;
+  grub_uint32_t journal_dev;
+  grub_uint32_t last_orphan;
+  grub_uint32_t hash_seed[4];
+  grub_uint8_t def_hash_version;
+  grub_uint8_t jnl_backup_type;
+  grub_uint16_t reserved_word_pad;
+  grub_uint32_t default_mount_opts;
+  grub_uint32_t first_meta_bg;
+  grub_uint32_t mkfs_time;
+  grub_uint32_t jnl_blocks[17];
+};
+
+/* The ext2 blockgroup.  */
+struct grub_ext2_block_group
+{
+  grub_uint32_t block_id;
+  grub_uint32_t inode_id;
+  grub_uint32_t inode_table_id;
+  grub_uint16_t free_blocks;
+  grub_uint16_t free_inodes;
+  grub_uint16_t used_dirs;
+  grub_uint16_t pad;
+  grub_uint32_t reserved[3];
+};
+
+/* The ext2 inode.  */
+struct grub_ext2_inode
+{
+  grub_uint16_t mode;
+  grub_uint16_t uid;
+  grub_uint32_t size;
+  grub_uint32_t atime;
+  grub_uint32_t ctime;
+  grub_uint32_t mtime;
+  grub_uint32_t dtime;
+  grub_uint16_t gid;
+  grub_uint16_t nlinks;
+  grub_uint32_t blockcnt;  /* Blocks of 512 bytes!! */
+  grub_uint32_t flags;
+  grub_uint32_t osd1;
+  union
+  {
+    struct datablocks
+    {
+      grub_uint32_t dir_blocks[INDIRECT_BLOCKS];
+      grub_uint32_t indir_block;
+      grub_uint32_t double_indir_block;
+      grub_uint32_t triple_indir_block;
+    } blocks;
+    char symlink[60];
+  };
+  grub_uint32_t version;
+  grub_uint32_t acl;
+  grub_uint32_t dir_acl;
+  grub_uint32_t fragment_addr;
+  grub_uint32_t osd2[3];
+};
+
+/* The header of an ext2 directory entry.  */
+struct ext2_dirent
+{
+  grub_uint32_t inode;
+  grub_uint16_t direntlen;
+  grub_uint8_t namelen;
+  grub_uint8_t filetype;
+};
+
+struct grub_ext3_journal_header
+{
+  grub_uint32_t magic;
+  grub_uint32_t block_type;
+  grub_uint32_t sequence;
+};
+
+struct grub_ext3_journal_revoke_header
+{
+  struct grub_ext3_journal_header header;
+  grub_uint32_t count;
+  grub_uint32_t data[0];
+};
+
+struct grub_ext3_journal_block_tag
+{
+  grub_uint32_t block;
+  grub_uint32_t flags;
+};
+
+struct grub_ext3_journal_sblock
+{
+  struct grub_ext3_journal_header header;
+  grub_uint32_t block_size;
+  grub_uint32_t maxlen;
+  grub_uint32_t first;
+  grub_uint32_t sequence;
+  grub_uint32_t start;
+};
+
+#define EXT4_EXT_MAGIC         0xf30a
+
+struct grub_ext4_extent_header
+{
+  grub_uint16_t magic;
+  grub_uint16_t entries;
+  grub_uint16_t max;
+  grub_uint16_t depth;
+  grub_uint32_t generation;
+};
+
+struct grub_ext4_extent
+{
+  grub_uint32_t block;
+  grub_uint16_t len;
+  grub_uint16_t start_hi;
+  grub_uint32_t start;
+};
+
+struct grub_ext4_extent_idx
+{
+  grub_uint32_t block;
+  grub_uint32_t leaf;
+  grub_uint16_t leaf_hi;
+  grub_uint16_t unused;
+};
+
+struct grub_fshelp_node
+{
+  struct grub_ext2_data *data;
+  struct grub_ext2_inode inode;
+  int ino;
+  int inode_read;
+};
+
+/* Information about a "mounted" ext2 filesystem.  */
+struct grub_ext2_data
+{
+  struct grub_ext2_sblock sblock;
+  grub_disk_t disk;
+  struct grub_ext2_inode *inode;
+  struct grub_fshelp_node diropen;
+};
+
+static grub_dl_t my_mod;
+
+\f
+
+/* Read into BLKGRP the blockgroup descriptor of blockgroup GROUP of
+   the mounted filesystem DATA.  */
+inline static grub_err_t
+grub_ext2_blockgroup (struct grub_ext2_data *data, int group,
+                     struct grub_ext2_block_group *blkgrp)
+{
+  return grub_disk_read (data->disk,
+                         ((grub_le_to_cpu32 (data->sblock.first_data_block) + 1)
+                          << LOG2_EXT2_BLOCK_SIZE (data)),
+                        group * sizeof (struct grub_ext2_block_group),
+                        sizeof (struct grub_ext2_block_group), blkgrp);
+}
+
+static struct grub_ext4_extent_header *
+grub_ext4_find_leaf (struct grub_ext2_data *data, char *buf,
+                     struct grub_ext4_extent_header *ext_block,
+                     grub_uint32_t fileblock)
+{
+  struct grub_ext4_extent_idx *index;
+
+  while (1)
+    {
+      int i;
+      grub_disk_addr_t block;
+
+      index = (struct grub_ext4_extent_idx *) (ext_block + 1);
+
+      if (grub_le_to_cpu16(ext_block->magic) != EXT4_EXT_MAGIC)
+        return 0;
+
+      if (ext_block->depth == 0)
+        return ext_block;
+
+      for (i = 0; i < grub_le_to_cpu16 (ext_block->entries); i++)
+        {
+          if (fileblock < grub_le_to_cpu32(index[i].block))
+            break;
+        }
+
+      if (--i < 0)
+        return 0;
+
+      block = grub_le_to_cpu16 (index[i].leaf_hi);
+      block = (block << 32) + grub_le_to_cpu32 (index[i].leaf);
+      if (grub_disk_read (data->disk,
+                          block << LOG2_EXT2_BLOCK_SIZE (data),
+                          0, EXT2_BLOCK_SIZE(data), buf))
+        return 0;
+
+      ext_block = (struct grub_ext4_extent_header *) buf;
+    }
+}
+
+static grub_disk_addr_t
+grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+{
+  struct grub_ext2_data *data = node->data;
+  struct grub_ext2_inode *inode = &node->inode;
+  int blknr = -1;
+  unsigned int blksz = EXT2_BLOCK_SIZE (data);
+  int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data);
+
+  if (grub_le_to_cpu32(inode->flags) & EXT4_EXTENTS_FLAG)
+    {
+      char buf[EXT2_BLOCK_SIZE(data)];
+      struct grub_ext4_extent_header *leaf;
+      struct grub_ext4_extent *ext;
+      int i;
+
+      leaf = grub_ext4_find_leaf (data, buf,
+                                  (struct grub_ext4_extent_header *) inode->blocks.dir_blocks,
+                                  fileblock);
+      if (! leaf)
+        {
+          grub_error (GRUB_ERR_BAD_FS, "invalid extent");
+          return -1;
+        }
+
+      ext = (struct grub_ext4_extent *) (leaf + 1);
+      for (i = 0; i < grub_le_to_cpu16 (leaf->entries); i++)
+        {
+          if (fileblock < grub_le_to_cpu32 (ext[i].block))
+            break;
+        }
+
+      if (--i >= 0)
+        {
+          fileblock -= grub_le_to_cpu32 (ext[i].block);
+          if (fileblock >= grub_le_to_cpu16 (ext[i].len))
+            return 0;
+          else
+            {
+              grub_disk_addr_t start;
+
+              start = grub_le_to_cpu16 (ext[i].start_hi);
+              start = (start << 32) + grub_le_to_cpu32 (ext[i].start);
+
+              return fileblock + start;
+            }
+        }
+      else
+        {
+          grub_error (GRUB_ERR_BAD_FS, "something wrong with extent");
+          return -1;
+        }
+    }
+  /* Direct blocks.  */
+  if (fileblock < INDIRECT_BLOCKS)
+    blknr = grub_le_to_cpu32 (inode->blocks.dir_blocks[fileblock]);
+  /* Indirect.  */
+  else if (fileblock < INDIRECT_BLOCKS + blksz / 4)
+    {
+      grub_uint32_t indir[blksz / 4];
+
+      if (grub_disk_read (data->disk,
+                         ((grub_disk_addr_t)
+                          grub_le_to_cpu32 (inode->blocks.indir_block))
+                         << log2_blksz,
+                         0, blksz, indir))
+       return grub_errno;
+
+      blknr = grub_le_to_cpu32 (indir[fileblock - INDIRECT_BLOCKS]);
+    }
+  /* Double indirect.  */
+  else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * (blksz / 4 + 1))
+    {
+      unsigned int perblock = blksz / 4;
+      unsigned int rblock = fileblock - (INDIRECT_BLOCKS
+                                        + blksz / 4);
+      grub_uint32_t indir[blksz / 4];
+
+      if (grub_disk_read (data->disk,
+                         ((grub_disk_addr_t)
+                          grub_le_to_cpu32 (inode->blocks.double_indir_block))
+                         << log2_blksz,
+                         0, blksz, indir))
+       return grub_errno;
+
+      if (grub_disk_read (data->disk,
+                         ((grub_disk_addr_t)
+                          grub_le_to_cpu32 (indir[rblock / perblock]))
+                         << log2_blksz,
+                         0, blksz, indir))
+       return grub_errno;
+
+
+      blknr = grub_le_to_cpu32 (indir[rblock % perblock]);
+    }
+  /* triple indirect.  */
+  else
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                 "ext2fs doesn't support triple indirect blocks");
+    }
+
+  return blknr;
+}
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_ext2_read_file (grub_fshelp_node_t node,
+                    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                       unsigned offset, unsigned length),
+                    int pos, grub_size_t len, char *buf)
+{
+  return grub_fshelp_read_file (node->data->disk, node, read_hook,
+                               pos, len, buf, grub_ext2_read_block,
+                               node->inode.size,
+                               LOG2_EXT2_BLOCK_SIZE (node->data));
+
+}
+
+
+/* Read the inode INO for the file described by DATA into INODE.  */
+static grub_err_t
+grub_ext2_read_inode (struct grub_ext2_data *data,
+                     int ino, struct grub_ext2_inode *inode)
+{
+  struct grub_ext2_block_group blkgrp;
+  struct grub_ext2_sblock *sblock = &data->sblock;
+  int inodes_per_block;
+  unsigned int blkno;
+  unsigned int blkoff;
+
+  /* It is easier to calculate if the first inode is 0.  */
+  ino--;
+
+  grub_ext2_blockgroup (data,
+                        ino / grub_le_to_cpu32 (sblock->inodes_per_group),
+                       &blkgrp);
+  if (grub_errno)
+    return grub_errno;
+
+  inodes_per_block = EXT2_BLOCK_SIZE (data) / EXT2_INODE_SIZE (data);
+  blkno = (ino % grub_le_to_cpu32 (sblock->inodes_per_group))
+    / inodes_per_block;
+  blkoff = (ino % grub_le_to_cpu32 (sblock->inodes_per_group))
+    % inodes_per_block;
+
+  /* Read the inode.  */
+  if (grub_disk_read (data->disk,
+                     ((grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno)
+                       << LOG2_EXT2_BLOCK_SIZE (data)),
+                     EXT2_INODE_SIZE (data) * blkoff,
+                     sizeof (struct grub_ext2_inode), inode))
+    return grub_errno;
+
+  return 0;
+}
+
+static struct grub_ext2_data *
+grub_ext2_mount (grub_disk_t disk)
+{
+  struct grub_ext2_data *data;
+
+  data = grub_malloc (sizeof (struct grub_ext2_data));
+  if (!data)
+    return 0;
+
+  /* Read the superblock.  */
+  grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_ext2_sblock),
+                  &data->sblock);
+  if (grub_errno)
+    goto fail;
+
+  /* Make sure this is an ext2 filesystem.  */
+  if (grub_le_to_cpu16 (data->sblock.magic) != EXT2_MAGIC)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not an ext2 filesystem");
+      goto fail;
+    }
+
+  /* Check the FS doesn't have feature bits enabled that we don't support. */
+  if (grub_le_to_cpu32 (data->sblock.feature_incompat)
+        & ~(EXT2_DRIVER_SUPPORTED_INCOMPAT | EXT2_DRIVER_IGNORED_INCOMPAT))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "filesystem has unsupported incompatible features");
+      goto fail;
+    }
+
+
+  data->disk = disk;
+
+  data->diropen.data = data;
+  data->diropen.ino = 2;
+  data->diropen.inode_read = 1;
+
+  data->inode = &data->diropen.inode;
+
+  grub_ext2_read_inode (data, 2, data->inode);
+  if (grub_errno)
+    goto fail;
+
+  return data;
+
+ fail:
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not an ext2 filesystem");
+
+  grub_free (data);
+  return 0;
+}
+
+static char *
+grub_ext2_read_symlink (grub_fshelp_node_t node)
+{
+  char *symlink;
+  struct grub_fshelp_node *diro = node;
+
+  if (! diro->inode_read)
+    {
+      grub_ext2_read_inode (diro->data, diro->ino, &diro->inode);
+      if (grub_errno)
+       return 0;
+    }
+
+  symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1);
+  if (! symlink)
+    return 0;
+
+  /* If the filesize of the symlink is bigger than
+     60 the symlink is stored in a separate block,
+     otherwise it is stored in the inode.  */
+  if (grub_le_to_cpu32 (diro->inode.size) <= 60)
+    grub_strncpy (symlink,
+                 diro->inode.symlink,
+                 grub_le_to_cpu32 (diro->inode.size));
+  else
+    {
+      grub_ext2_read_file (diro, 0, 0,
+                          grub_le_to_cpu32 (diro->inode.size),
+                          symlink);
+      if (grub_errno)
+       {
+         grub_free (symlink);
+         return 0;
+       }
+    }
+
+  symlink[grub_le_to_cpu32 (diro->inode.size)] = '\0';
+  return symlink;
+}
+
+static int
+grub_ext2_iterate_dir (grub_fshelp_node_t dir,
+                      int NESTED_FUNC_ATTR
+                      (*hook) (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node))
+{
+  unsigned int fpos = 0;
+  struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
+
+  if (! diro->inode_read)
+    {
+      grub_ext2_read_inode (diro->data, diro->ino, &diro->inode);
+      if (grub_errno)
+       return 0;
+    }
+
+  /* Search the file.  */
+  while (fpos < grub_le_to_cpu32 (diro->inode.size))
+    {
+      struct ext2_dirent dirent;
+
+      grub_ext2_read_file (diro, 0, fpos, sizeof (struct ext2_dirent),
+                          (char *) &dirent);
+      if (grub_errno)
+       return 0;
+
+      if (dirent.direntlen == 0)
+        return 0;
+
+      if (dirent.namelen != 0)
+       {
+         char filename[dirent.namelen + 1];
+         struct grub_fshelp_node *fdiro;
+         enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN;
+
+         grub_ext2_read_file (diro, 0, fpos + sizeof (struct ext2_dirent),
+                              dirent.namelen, filename);
+         if (grub_errno)
+           return 0;
+
+         fdiro = grub_malloc (sizeof (struct grub_fshelp_node));
+         if (! fdiro)
+           return 0;
+
+         fdiro->data = diro->data;
+         fdiro->ino = grub_le_to_cpu32 (dirent.inode);
+
+         filename[dirent.namelen] = '\0';
+
+         if (dirent.filetype != FILETYPE_UNKNOWN)
+           {
+             fdiro->inode_read = 0;
+
+             if (dirent.filetype == FILETYPE_DIRECTORY)
+               type = GRUB_FSHELP_DIR;
+             else if (dirent.filetype == FILETYPE_SYMLINK)
+               type = GRUB_FSHELP_SYMLINK;
+             else if (dirent.filetype == FILETYPE_REG)
+               type = GRUB_FSHELP_REG;
+           }
+         else
+           {
+             /* The filetype can not be read from the dirent, read
+                the inode to get more information.  */
+             grub_ext2_read_inode (diro->data,
+                                    grub_le_to_cpu32 (dirent.inode),
+                                   &fdiro->inode);
+             if (grub_errno)
+               {
+                 grub_free (fdiro);
+                 return 0;
+               }
+
+             fdiro->inode_read = 1;
+
+             if ((grub_le_to_cpu16 (fdiro->inode.mode)
+                  & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY)
+               type = GRUB_FSHELP_DIR;
+             else if ((grub_le_to_cpu16 (fdiro->inode.mode)
+                       & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK)
+               type = GRUB_FSHELP_SYMLINK;
+             else if ((grub_le_to_cpu16 (fdiro->inode.mode)
+                       & FILETYPE_INO_MASK) == FILETYPE_INO_REG)
+               type = GRUB_FSHELP_REG;
+           }
+
+         if (hook (filename, type, fdiro))
+           return 1;
+       }
+
+      fpos += grub_le_to_cpu16 (dirent.direntlen);
+    }
+
+  return 0;
+}
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_ext2_open (struct grub_file *file, const char *name)
+{
+  struct grub_ext2_data *data;
+  struct grub_fshelp_node *fdiro = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ext2_mount (file->device->disk);
+  if (! data)
+    goto fail;
+
+  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_ext2_iterate_dir,
+                        grub_ext2_read_symlink, GRUB_FSHELP_REG);
+  if (grub_errno)
+    goto fail;
+
+  if (! fdiro->inode_read)
+    {
+      grub_ext2_read_inode (data, fdiro->ino, &fdiro->inode);
+      if (grub_errno)
+       goto fail;
+    }
+
+  grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_ext2_inode));
+  grub_free (fdiro);
+
+  file->size = grub_le_to_cpu32 (data->inode->size);
+  file->data = data;
+  file->offset = 0;
+
+  return 0;
+
+ fail:
+  if (fdiro != &data->diropen)
+    grub_free (fdiro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_ext2_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Read LEN bytes data from FILE into BUF.  */
+static grub_ssize_t
+grub_ext2_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_ext2_data *data = (struct grub_ext2_data *) file->data;
+
+  return grub_ext2_read_file (&data->diropen, file->read_hook,
+                             file->offset, len, buf);
+}
+
+
+static grub_err_t
+grub_ext2_dir (grub_device_t device, const char *path,
+              int (*hook) (const char *filename,
+                           const struct grub_dirhook_info *info))
+{
+  struct grub_ext2_data *data = 0;
+  struct grub_fshelp_node *fdiro = 0;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+                                    enum grub_fshelp_filetype filetype,
+                                    grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      if (! node->inode_read)
+       {
+         grub_ext2_read_inode (data, node->ino, &node->inode);
+         if (!grub_errno)
+           node->inode_read = 1;
+         grub_errno = GRUB_ERR_NONE;
+       }
+      if (node->inode_read)
+       {
+         info.mtimeset = 1;
+         info.mtime = grub_le_to_cpu32 (node->inode.mtime);
+       }
+
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+    }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ext2_mount (device->disk);
+  if (! data)
+    goto fail;
+
+  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_ext2_iterate_dir,
+                        grub_ext2_read_symlink, GRUB_FSHELP_DIR);
+  if (grub_errno)
+    goto fail;
+
+  grub_ext2_iterate_dir (fdiro, iterate);
+
+ fail:
+  if (fdiro != &data->diropen)
+    grub_free (fdiro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_ext2_label (grub_device_t device, char **label)
+{
+  struct grub_ext2_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ext2_mount (disk);
+  if (data)
+    *label = grub_strndup (data->sblock.volume_name, 14);
+  else
+    *label = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_ext2_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_ext2_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ext2_mount (disk);
+  if (data)
+    {
+      *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
+                            grub_be_to_cpu16 (data->sblock.uuid[0]),
+                            grub_be_to_cpu16 (data->sblock.uuid[1]),
+                            grub_be_to_cpu16 (data->sblock.uuid[2]),
+                            grub_be_to_cpu16 (data->sblock.uuid[3]),
+                            grub_be_to_cpu16 (data->sblock.uuid[4]),
+                            grub_be_to_cpu16 (data->sblock.uuid[5]),
+                            grub_be_to_cpu16 (data->sblock.uuid[6]),
+                            grub_be_to_cpu16 (data->sblock.uuid[7]));
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+/* Get mtime.  */
+static grub_err_t
+grub_ext2_mtime (grub_device_t device, grub_int32_t *tm)
+{
+  struct grub_ext2_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ext2_mount (disk);
+  if (!data)
+    *tm = 0;
+  else
+    *tm = grub_le_to_cpu32 (data->sblock.utime);
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+
+}
+
+
+\f
+static struct grub_fs grub_ext2_fs =
+  {
+    .name = "ext2",
+    .dir = grub_ext2_dir,
+    .open = grub_ext2_open,
+    .read = grub_ext2_read,
+    .close = grub_ext2_close,
+    .label = grub_ext2_label,
+    .uuid = grub_ext2_uuid,
+    .mtime = grub_ext2_mtime,
+#ifdef GRUB_UTIL
+    .reserved_first_sector = 1,
+#endif
+    .next = 0
+  };
+
+GRUB_MOD_INIT(ext2)
+{
+  grub_fs_register (&grub_ext2_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(ext2)
+{
+  grub_fs_unregister (&grub_ext2_fs);
+}
diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c
new file mode 100644 (file)
index 0000000..8905094
--- /dev/null
@@ -0,0 +1,876 @@
+/* fat.c - FAT filesystem */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/fs.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/charset.h>
+
+#define GRUB_FAT_DIR_ENTRY_SIZE        32
+
+#define GRUB_FAT_ATTR_READ_ONLY        0x01
+#define GRUB_FAT_ATTR_HIDDEN   0x02
+#define GRUB_FAT_ATTR_SYSTEM   0x04
+#define GRUB_FAT_ATTR_VOLUME_ID        0x08
+#define GRUB_FAT_ATTR_DIRECTORY        0x10
+#define GRUB_FAT_ATTR_ARCHIVE  0x20
+
+#define GRUB_FAT_MAXFILE       256
+
+#define GRUB_FAT_ATTR_LONG_NAME        (GRUB_FAT_ATTR_READ_ONLY \
+                                | GRUB_FAT_ATTR_HIDDEN \
+                                | GRUB_FAT_ATTR_SYSTEM \
+                                | GRUB_FAT_ATTR_VOLUME_ID)
+#define GRUB_FAT_ATTR_VALID    (GRUB_FAT_ATTR_READ_ONLY \
+                                | GRUB_FAT_ATTR_HIDDEN \
+                                | GRUB_FAT_ATTR_SYSTEM \
+                                | GRUB_FAT_ATTR_DIRECTORY \
+                                | GRUB_FAT_ATTR_ARCHIVE \
+                                | GRUB_FAT_ATTR_VOLUME_ID)
+
+struct grub_fat_bpb
+{
+  grub_uint8_t jmp_boot[3];
+  grub_uint8_t oem_name[8];
+  grub_uint16_t bytes_per_sector;
+  grub_uint8_t sectors_per_cluster;
+  grub_uint16_t num_reserved_sectors;
+  grub_uint8_t num_fats;
+  grub_uint16_t num_root_entries;
+  grub_uint16_t num_total_sectors_16;
+  grub_uint8_t media;
+  grub_uint16_t sectors_per_fat_16;
+  grub_uint16_t sectors_per_track;
+  grub_uint16_t num_heads;
+  grub_uint32_t num_hidden_sectors;
+  grub_uint32_t num_total_sectors_32;
+  union
+  {
+    struct
+    {
+      grub_uint8_t num_ph_drive;
+      grub_uint8_t reserved;
+      grub_uint8_t boot_sig;
+      grub_uint32_t num_serial;
+      grub_uint8_t label[11];
+      grub_uint8_t fstype[8];
+    } __attribute__ ((packed)) fat12_or_fat16;
+    struct
+    {
+      grub_uint32_t sectors_per_fat_32;
+      grub_uint16_t extended_flags;
+      grub_uint16_t fs_version;
+      grub_uint32_t root_cluster;
+      grub_uint16_t fs_info;
+      grub_uint16_t backup_boot_sector;
+      grub_uint8_t reserved[12];
+      grub_uint8_t num_ph_drive;
+      grub_uint8_t reserved1;
+      grub_uint8_t boot_sig;
+      grub_uint32_t num_serial;
+      grub_uint8_t label[11];
+      grub_uint8_t fstype[8];
+    } __attribute__ ((packed)) fat32;
+  } __attribute__ ((packed)) version_specific;
+} __attribute__ ((packed));
+
+struct grub_fat_dir_entry
+{
+  grub_uint8_t name[11];
+  grub_uint8_t attr;
+  grub_uint8_t nt_reserved;
+  grub_uint8_t c_time_tenth;
+  grub_uint16_t c_time;
+  grub_uint16_t c_date;
+  grub_uint16_t a_date;
+  grub_uint16_t first_cluster_high;
+  grub_uint16_t w_time;
+  grub_uint16_t w_date;
+  grub_uint16_t first_cluster_low;
+  grub_uint32_t file_size;
+} __attribute__ ((packed));
+
+struct grub_fat_long_name_entry
+{
+  grub_uint8_t id;
+  grub_uint16_t name1[5];
+  grub_uint8_t attr;
+  grub_uint8_t reserved;
+  grub_uint8_t checksum;
+  grub_uint16_t name2[6];
+  grub_uint16_t first_cluster;
+  grub_uint16_t name3[2];
+} __attribute__ ((packed));
+
+struct grub_fat_data
+{
+  int logical_sector_bits;
+  grub_uint32_t num_sectors;
+
+  grub_uint16_t fat_sector;
+  grub_uint32_t sectors_per_fat;
+  int fat_size;
+
+  grub_uint32_t root_cluster;
+  grub_uint32_t root_sector;
+  grub_uint32_t num_root_sectors;
+
+  int cluster_bits;
+  grub_uint32_t cluster_eof_mark;
+  grub_uint32_t cluster_sector;
+  grub_uint32_t num_clusters;
+
+  grub_uint8_t attr;
+  grub_ssize_t file_size;
+  grub_uint32_t file_cluster;
+  grub_uint32_t cur_cluster_num;
+  grub_uint32_t cur_cluster;
+
+  grub_uint32_t uuid;
+};
+
+static grub_dl_t my_mod;
+
+static int
+fat_log2 (unsigned x)
+{
+  int i;
+
+  if (x == 0)
+    return -1;
+
+  for (i = 0; (x & 1) == 0; i++)
+    x >>= 1;
+
+  if (x != 1)
+    return -1;
+
+  return i;
+}
+
+static struct grub_fat_data *
+grub_fat_mount (grub_disk_t disk)
+{
+  struct grub_fat_bpb bpb;
+  struct grub_fat_data *data = 0;
+  grub_uint32_t first_fat, magic;
+
+  if (! disk)
+    goto fail;
+
+  data = (struct grub_fat_data *) grub_malloc (sizeof (*data));
+  if (! data)
+    goto fail;
+
+  /* Read the BPB.  */
+  if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb))
+    goto fail;
+
+  if (grub_strncmp((const char *) bpb.version_specific.fat12_or_fat16.fstype, "FAT12", 5)
+      && grub_strncmp((const char *) bpb.version_specific.fat12_or_fat16.fstype, "FAT16", 5)
+      && grub_strncmp((const char *) bpb.version_specific.fat32.fstype, "FAT32", 5))
+    goto fail;
+
+  /* Get the sizes of logical sectors and clusters.  */
+  data->logical_sector_bits =
+    fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector));
+  if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS)
+    goto fail;
+  data->logical_sector_bits -= GRUB_DISK_SECTOR_BITS;
+
+  data->cluster_bits = fat_log2 (bpb.sectors_per_cluster);
+  if (data->cluster_bits < 0)
+    goto fail;
+  data->cluster_bits += data->logical_sector_bits;
+
+  /* Get information about FATs.  */
+  data->fat_sector = (grub_le_to_cpu16 (bpb.num_reserved_sectors)
+                     << data->logical_sector_bits);
+  if (data->fat_sector == 0)
+    goto fail;
+
+  data->sectors_per_fat = ((bpb.sectors_per_fat_16
+                           ? grub_le_to_cpu16 (bpb.sectors_per_fat_16)
+                           : grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32))
+                          << data->logical_sector_bits);
+  if (data->sectors_per_fat == 0)
+    goto fail;
+
+  /* Get the number of sectors in this volume.  */
+  data->num_sectors = ((bpb.num_total_sectors_16
+                       ? grub_le_to_cpu16 (bpb.num_total_sectors_16)
+                       : grub_le_to_cpu32 (bpb.num_total_sectors_32))
+                      << data->logical_sector_bits);
+  if (data->num_sectors == 0)
+    goto fail;
+
+  /* Get information about the root directory.  */
+  if (bpb.num_fats == 0)
+    goto fail;
+
+  data->root_sector = data->fat_sector + bpb.num_fats * data->sectors_per_fat;
+  data->num_root_sectors
+    = ((((grub_uint32_t) grub_le_to_cpu16 (bpb.num_root_entries)
+        * GRUB_FAT_DIR_ENTRY_SIZE
+        + grub_le_to_cpu16 (bpb.bytes_per_sector) - 1)
+       >> (data->logical_sector_bits + GRUB_DISK_SECTOR_BITS))
+       << (data->logical_sector_bits));
+
+  data->cluster_sector = data->root_sector + data->num_root_sectors;
+  data->num_clusters = (((data->num_sectors - data->cluster_sector)
+                        >> (data->cluster_bits + data->logical_sector_bits))
+                       + 2);
+
+  if (data->num_clusters <= 2)
+    goto fail;
+
+  if (! bpb.sectors_per_fat_16)
+    {
+      /* FAT32.  */
+      grub_uint16_t flags = grub_le_to_cpu16 (bpb.version_specific.fat32.extended_flags);
+
+      data->root_cluster = grub_le_to_cpu32 (bpb.version_specific.fat32.root_cluster);
+      data->fat_size = 32;
+      data->cluster_eof_mark = 0x0ffffff8;
+
+      if (flags & 0x80)
+       {
+         /* Get an active FAT.  */
+         unsigned active_fat = flags & 0xf;
+
+         if (active_fat > bpb.num_fats)
+           goto fail;
+
+         data->fat_sector += active_fat * data->sectors_per_fat;
+       }
+
+      if (bpb.num_root_entries != 0 || bpb.version_specific.fat32.fs_version != 0)
+       goto fail;
+    }
+  else
+    {
+      /* FAT12 or FAT16.  */
+      data->root_cluster = ~0U;
+
+      if (data->num_clusters <= 4085 + 2)
+       {
+         /* FAT12.  */
+         data->fat_size = 12;
+         data->cluster_eof_mark = 0x0ff8;
+       }
+      else
+       {
+         /* FAT16.  */
+         data->fat_size = 16;
+         data->cluster_eof_mark = 0xfff8;
+       }
+    }
+
+  /* More sanity checks.  */
+  if (data->num_sectors <= data->fat_sector)
+    goto fail;
+
+  if (grub_disk_read (disk,
+                     data->fat_sector,
+                     0,
+                     sizeof (first_fat),
+                     &first_fat))
+    goto fail;
+
+  first_fat = grub_le_to_cpu32 (first_fat);
+
+  if (data->fat_size == 32)
+    {
+      first_fat &= 0x0fffffff;
+      magic = 0x0fffff00;
+    }
+  else if (data->fat_size == 16)
+    {
+      first_fat &= 0x0000ffff;
+      magic = 0xff00;
+    }
+  else
+    {
+      first_fat &= 0x00000fff;
+      magic = 0x0f00;
+    }
+
+  /* Serial number.  */
+  if (bpb.sectors_per_fat_16)
+    data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial);
+  else
+    data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat32.num_serial);
+
+  /* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media
+     descriptor, even if it is a so-called superfloppy (e.g. an USB key).
+     The check may be too strict for this kind of stupid BIOSes, as
+     they overwrite the media descriptor.  */
+  if ((first_fat | 0x8) != (magic | bpb.media | 0x8))
+    goto fail;
+
+  /* Start from the root directory.  */
+  data->file_cluster = data->root_cluster;
+  data->cur_cluster_num = ~0U;
+  data->attr = GRUB_FAT_ATTR_DIRECTORY;
+  return data;
+
+ fail:
+
+  grub_free (data);
+  grub_error (GRUB_ERR_BAD_FS, "not a FAT filesystem");
+  return 0;
+}
+
+static grub_ssize_t
+grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
+                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                      unsigned offset, unsigned length),
+                   grub_off_t offset, grub_size_t len, char *buf)
+{
+  grub_size_t size;
+  grub_uint32_t logical_cluster;
+  unsigned logical_cluster_bits;
+  grub_ssize_t ret = 0;
+  unsigned long sector;
+
+  /* This is a special case. FAT12 and FAT16 doesn't have the root directory
+     in clusters.  */
+  if (data->file_cluster == ~0U)
+    {
+      size = (data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset;
+      if (size > len)
+       size = len;
+
+      if (grub_disk_read (disk, data->root_sector, offset, size, buf))
+       return -1;
+
+      return size;
+    }
+
+  /* Calculate the logical cluster number and offset.  */
+  logical_cluster_bits = (data->cluster_bits
+                         + data->logical_sector_bits
+                         + GRUB_DISK_SECTOR_BITS);
+  logical_cluster = offset >> logical_cluster_bits;
+  offset &= (1 << logical_cluster_bits) - 1;
+
+  if (logical_cluster < data->cur_cluster_num)
+    {
+      data->cur_cluster_num = 0;
+      data->cur_cluster = data->file_cluster;
+    }
+
+  while (len)
+    {
+      while (logical_cluster > data->cur_cluster_num)
+       {
+         /* Find next cluster.  */
+         grub_uint32_t next_cluster;
+         unsigned long fat_offset;
+
+         switch (data->fat_size)
+           {
+           case 32:
+             fat_offset = data->cur_cluster << 2;
+             break;
+           case 16:
+             fat_offset = data->cur_cluster << 1;
+             break;
+           default:
+             /* case 12: */
+             fat_offset = data->cur_cluster + (data->cur_cluster >> 1);
+             break;
+           }
+
+         /* Read the FAT.  */
+         if (grub_disk_read (disk, data->fat_sector, fat_offset,
+                             (data->fat_size + 7) >> 3,
+                             (char *) &next_cluster))
+           return -1;
+
+         next_cluster = grub_le_to_cpu32 (next_cluster);
+         switch (data->fat_size)
+           {
+           case 16:
+             next_cluster &= 0xFFFF;
+             break;
+           case 12:
+             if (data->cur_cluster & 1)
+               next_cluster >>= 4;
+
+             next_cluster &= 0x0FFF;
+             break;
+           }
+
+         grub_dprintf ("fat", "fat_size=%d, next_cluster=%u\n",
+                       data->fat_size, next_cluster);
+
+         /* Check the end.  */
+         if (next_cluster >= data->cluster_eof_mark)
+           return ret;
+
+         if (next_cluster < 2 || next_cluster >= data->num_clusters)
+           {
+             grub_error (GRUB_ERR_BAD_FS, "invalid cluster %u",
+                         next_cluster);
+             return -1;
+           }
+
+         data->cur_cluster = next_cluster;
+         data->cur_cluster_num++;
+       }
+
+      /* Read the data here.  */
+      sector = (data->cluster_sector
+               + ((data->cur_cluster - 2)
+                  << (data->cluster_bits + data->logical_sector_bits)));
+      size = (1 << logical_cluster_bits) - offset;
+      if (size > len)
+       size = len;
+
+      disk->read_hook = read_hook;
+      grub_disk_read (disk, sector, offset, size, buf);
+      disk->read_hook = 0;
+      if (grub_errno)
+       return -1;
+
+      len -= size;
+      buf += size;
+      ret += size;
+      logical_cluster++;
+      offset = 0;
+    }
+
+  return ret;
+}
+
+static grub_err_t
+grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
+                     int (*hook) (const char *filename,
+                                  struct grub_fat_dir_entry *dir))
+{
+  struct grub_fat_dir_entry dir;
+  char *filename, *filep = 0;
+  grub_uint16_t *unibuf;
+  int slot = -1, slots = -1;
+  int checksum = -1;
+  grub_ssize_t offset = -sizeof(dir);
+
+  if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+
+  /* Allocate space enough to hold a long name.  */
+  filename = grub_malloc (0x40 * 13 * 4 + 1);
+  unibuf = (grub_uint16_t *) grub_malloc (0x40 * 13 * 2);
+  if (! filename || ! unibuf)
+    {
+      grub_free (filename);
+      grub_free (unibuf);
+      return 0;
+    }
+
+  while (1)
+    {
+      unsigned i;
+
+      /* Adjust the offset.  */
+      offset += sizeof (dir);
+
+      /* Read a directory entry.  */
+      if ((grub_fat_read_data (disk, data, 0,
+                              offset, sizeof (dir), (char *) &dir)
+          != sizeof (dir) || dir.name[0] == 0))
+       break;
+      /* Handle long name entries.  */
+      if (dir.attr == GRUB_FAT_ATTR_LONG_NAME)
+       {
+         struct grub_fat_long_name_entry *long_name
+           = (struct grub_fat_long_name_entry *) &dir;
+         grub_uint8_t id = long_name->id;
+
+         if (id & 0x40)
+           {
+             id &= 0x3f;
+             slots = slot = id;
+             checksum = long_name->checksum;
+           }
+
+         if (id != slot || slot == 0 || checksum != long_name->checksum)
+           {
+             checksum = -1;
+             continue;
+           }
+
+         slot--;
+         grub_memcpy (unibuf + slot * 13, long_name->name1, 5 * 2);
+         grub_memcpy (unibuf + slot * 13 + 5, long_name->name2, 6 * 2);
+         grub_memcpy (unibuf + slot * 13 + 11, long_name->name3, 2 * 2);
+         continue;
+       }
+
+      /* Check if this entry is valid.  */
+      if (dir.name[0] == 0xe5 || (dir.attr & ~GRUB_FAT_ATTR_VALID))
+       continue;
+
+      /* This is a workaround for Japanese.  */
+      if (dir.name[0] == 0x05)
+       dir.name[0] = 0xe5;
+
+      if (checksum != -1 && slot == 0)
+       {
+         grub_uint8_t sum;
+
+         for (sum = 0, i = 0; i < sizeof (dir.name); i++)
+           sum = ((sum >> 1) | (sum << 7)) + dir.name[i];
+
+         if (sum == checksum)
+           {
+             int u;
+
+             for (u = 0; u < slots * 13; u++)
+               unibuf[u] = grub_le_to_cpu16 (unibuf[u]);
+
+             *grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf,
+                                  slots * 13) = '\0';
+
+             if (hook (filename, &dir))
+               break;
+
+             checksum = -1;
+             continue;
+           }
+
+         checksum = -1;
+       }
+
+      /* Convert the 8.3 file name.  */
+      filep = filename;
+      if (dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
+       {
+         for (i = 0; i < sizeof (dir.name) && dir.name[i]
+                && ! grub_isspace (dir.name[i]); i++)
+           *filep++ = dir.name[i];
+       }
+      else
+       {
+         for (i = 0; i < 8 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
+           *filep++ = grub_tolower (dir.name[i]);
+
+         *filep = '.';
+
+         for (i = 8; i < 11 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
+           *++filep = grub_tolower (dir.name[i]);
+
+         if (*filep != '.')
+           filep++;
+       }
+      *filep = '\0';
+
+      if (hook (filename, &dir))
+       break;
+    }
+
+  grub_free (filename);
+  grub_free (unibuf);
+
+  return grub_errno;
+}
+
+
+/* Find the underlying directory or file in PATH and return the
+   next path. If there is no next path or an error occurs, return NULL.
+   If HOOK is specified, call it with each file name.  */
+static char *
+grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
+                  const char *path,
+                  int (*hook) (const char *filename,
+                               const struct grub_dirhook_info *info))
+{
+  char *dirname, *dirp;
+  int call_hook;
+  int found = 0;
+
+  auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir);
+  int iter_hook (const char *filename, struct grub_fat_dir_entry *dir)
+  {
+    struct grub_dirhook_info info;
+    grub_memset (&info, 0, sizeof (info));
+
+    info.dir = !! (dir->attr & GRUB_FAT_ATTR_DIRECTORY);
+    info.case_insensitive = 1;
+
+    if (dir->attr & GRUB_FAT_ATTR_VOLUME_ID)
+      return 0;
+    if (*dirname == '\0' && call_hook)
+      return hook (filename, &info);
+
+    if (grub_strcasecmp (dirname, filename) == 0)
+      {
+       found = 1;
+       data->attr = dir->attr;
+       data->file_size = grub_le_to_cpu32 (dir->file_size);
+       data->file_cluster = ((grub_le_to_cpu16 (dir->first_cluster_high) << 16)
+                             | grub_le_to_cpu16 (dir->first_cluster_low));
+       data->cur_cluster_num = ~0U;
+
+       if (call_hook)
+         hook (filename, &info);
+
+       return 1;
+      }
+    return 0;
+  }
+
+  if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+      return 0;
+    }
+
+  /* Extract a directory name.  */
+  while (*path == '/')
+    path++;
+
+  dirp = grub_strchr (path, '/');
+  if (dirp)
+    {
+      unsigned len = dirp - path;
+
+      dirname = grub_malloc (len + 1);
+      if (! dirname)
+       return 0;
+
+      grub_memcpy (dirname, path, len);
+      dirname[len] = '\0';
+    }
+  else
+    /* This is actually a file.  */
+    dirname = grub_strdup (path);
+
+  call_hook = (! dirp && hook);
+
+  grub_fat_iterate_dir (disk, data, iter_hook);
+  if (grub_errno == GRUB_ERR_NONE && ! found && !call_hook)
+    grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+
+  grub_free (dirname);
+
+  return found ? dirp : 0;
+}
+
+static grub_err_t
+grub_fat_dir (grub_device_t device, const char *path,
+             int (*hook) (const char *filename,
+                          const struct grub_dirhook_info *info))
+{
+  struct grub_fat_data *data = 0;
+  grub_disk_t disk = device->disk;
+  grub_size_t len;
+  char *dirname = 0;
+  char *p;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_fat_mount (disk);
+  if (! data)
+    goto fail;
+
+  /* Make sure that DIRNAME terminates with '/'.  */
+  len = grub_strlen (path);
+  dirname = grub_malloc (len + 1 + 1);
+  if (! dirname)
+    goto fail;
+  grub_memcpy (dirname, path, len);
+  p = dirname + len;
+  if (path[len - 1] != '/')
+    *p++ = '/';
+  *p = '\0';
+  p = dirname;
+
+  do
+    {
+      p = grub_fat_find_dir (disk, data, p, hook);
+    }
+  while (p && grub_errno == GRUB_ERR_NONE);
+
+ fail:
+
+  grub_free (dirname);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_fat_open (grub_file_t file, const char *name)
+{
+  struct grub_fat_data *data = 0;
+  char *p = (char *) name;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_fat_mount (file->device->disk);
+  if (! data)
+    goto fail;
+
+  do
+    {
+      p = grub_fat_find_dir (file->device->disk, data, p, 0);
+      if (grub_errno != GRUB_ERR_NONE)
+       goto fail;
+    }
+  while (p);
+
+  if (data->attr & GRUB_FAT_ATTR_DIRECTORY)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a file");
+      goto fail;
+    }
+
+  file->data = data;
+  file->size = data->file_size;
+
+  return GRUB_ERR_NONE;
+
+ fail:
+
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_ssize_t
+grub_fat_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  return grub_fat_read_data (file->device->disk, file->data, file->read_hook,
+                            file->offset, len, buf);
+}
+
+static grub_err_t
+grub_fat_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_fat_label (grub_device_t device, char **label)
+{
+  struct grub_fat_data *data;
+  grub_disk_t disk = device->disk;
+
+  auto int iter_hook (const char *filename, struct grub_fat_dir_entry *dir);
+  int iter_hook (const char *filename, struct grub_fat_dir_entry *dir)
+  {
+    if (dir->attr == GRUB_FAT_ATTR_VOLUME_ID)
+      {
+       *label = grub_strdup (filename);
+       return 1;
+      }
+    return 0;
+  }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_fat_mount (disk);
+  if (! data)
+    goto fail;
+
+  if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+      return 0;
+    }
+
+  *label = 0;
+
+  grub_fat_iterate_dir (disk, data, iter_hook);
+
+ fail:
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_fat_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_fat_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_fat_mount (disk);
+  if (data)
+    {
+      *uuid = grub_xasprintf ("%04x-%04x",
+                            (grub_uint16_t) (data->uuid >> 16),
+                            (grub_uint16_t) data->uuid);
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static struct grub_fs grub_fat_fs =
+  {
+    .name = "fat",
+    .dir = grub_fat_dir,
+    .open = grub_fat_open,
+    .read = grub_fat_read,
+    .close = grub_fat_close,
+    .label = grub_fat_label,
+    .uuid = grub_fat_uuid,
+#ifdef GRUB_UTIL
+    .reserved_first_sector = 1,
+#endif
+    .next = 0
+  };
+
+GRUB_MOD_INIT(fat)
+{
+  grub_fs_register (&grub_fat_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(fat)
+{
+  grub_fs_unregister (&grub_fat_fs);
+}
+
diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c
new file mode 100644 (file)
index 0000000..d0b1e49
--- /dev/null
@@ -0,0 +1,315 @@
+/* fshelp.c -- Filesystem helper functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/fshelp.h>
+
+
+/* Lookup the node PATH.  The node ROOTNODE describes the root of the
+   directory tree.  The node found is returned in FOUNDNODE, which is
+   either a ROOTNODE or a new malloc'ed node.  ITERATE_DIR is used to
+   iterate over all directory entries in the current node.
+   READ_SYMLINK is used to read the symlink if a node is a symlink.
+   EXPECTTYPE is the type node that is expected by the called, an
+   error is generated if the node is not of the expected type.  Make
+   sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required
+   because GCC has a nasty bug when using regparm=3.  */
+grub_err_t
+grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode,
+                      grub_fshelp_node_t *foundnode,
+                      int (*iterate_dir) (grub_fshelp_node_t dir,
+                                          int NESTED_FUNC_ATTR (*hook)
+                                          (const char *filename,
+                                           enum grub_fshelp_filetype filetype,
+                                           grub_fshelp_node_t node)),
+                      char *(*read_symlink) (grub_fshelp_node_t node),
+                      enum grub_fshelp_filetype expecttype)
+{
+  grub_err_t err;
+  enum grub_fshelp_filetype foundtype = GRUB_FSHELP_DIR;
+  int symlinknest = 0;
+
+  auto grub_err_t NESTED_FUNC_ATTR find_file (const char *currpath,
+                                             grub_fshelp_node_t currroot,
+                                             grub_fshelp_node_t *currfound);
+
+  grub_err_t NESTED_FUNC_ATTR find_file (const char *currpath,
+                                        grub_fshelp_node_t currroot,
+                                        grub_fshelp_node_t *currfound)
+    {
+      char fpath[grub_strlen (currpath) + 1];
+      char *name = fpath;
+      char *next;
+      //  unsigned int pos = 0;
+      enum grub_fshelp_filetype type = GRUB_FSHELP_DIR;
+      grub_fshelp_node_t currnode = currroot;
+      grub_fshelp_node_t oldnode = currroot;
+
+      auto int NESTED_FUNC_ATTR iterate (const char *filename,
+                                        enum grub_fshelp_filetype filetype,
+                                        grub_fshelp_node_t node);
+
+      auto void free_node (grub_fshelp_node_t node);
+
+      void free_node (grub_fshelp_node_t node)
+       {
+          if (node != rootnode && node != currroot)
+           grub_free (node);
+       }
+
+      int NESTED_FUNC_ATTR iterate (const char *filename,
+                                   enum grub_fshelp_filetype filetype,
+                                   grub_fshelp_node_t node)
+       {
+         if (filetype == GRUB_FSHELP_UNKNOWN ||
+              (grub_strcmp (name, filename) &&
+               (! (filetype & GRUB_FSHELP_CASE_INSENSITIVE) ||
+                grub_strncasecmp (name, filename, GRUB_LONG_MAX))))
+           {
+             grub_free (node);
+             return 0;
+           }
+
+         /* The node is found, stop iterating over the nodes.  */
+         type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE;
+         oldnode = currnode;
+         currnode = node;
+
+         return 1;
+       }
+
+      grub_strncpy (fpath, currpath, grub_strlen (currpath) + 1);
+
+      /* Remove all leading slashes.  */
+      while (*name == '/')
+       name++;
+
+      if (! *name)
+       {
+         *currfound = currnode;
+         return 0;
+       }
+
+      for (;;)
+       {
+         int found;
+
+         /* Extract the actual part from the pathname.  */
+         next = grub_strchr (name, '/');
+         if (next)
+           {
+             /* Remove all leading slashes.  */
+             while (*next == '/')
+               *(next++) = '\0';
+           }
+
+         /* At this point it is expected that the current node is a
+            directory, check if this is true.  */
+         if (type != GRUB_FSHELP_DIR)
+           {
+             free_node (currnode);
+             return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+           }
+
+         /* Iterate over the directory.  */
+         found = iterate_dir (currnode, iterate);
+         if (! found)
+           {
+             if (grub_errno)
+               return grub_errno;
+
+             break;
+           }
+
+         /* Read in the symlink and follow it.  */
+         if (type == GRUB_FSHELP_SYMLINK)
+           {
+             char *symlink;
+
+             /* Test if the symlink does not loop.  */
+             if (++symlinknest == 8)
+               {
+                 free_node (currnode);
+                 free_node (oldnode);
+                 return grub_error (GRUB_ERR_SYMLINK_LOOP,
+                                     "too deep nesting of symlinks");
+               }
+
+             symlink = read_symlink (currnode);
+             free_node (currnode);
+
+             if (!symlink)
+               {
+                 free_node (oldnode);
+                 return grub_errno;
+               }
+
+             /* The symlink is an absolute path, go back to the root inode.  */
+             if (symlink[0] == '/')
+               {
+                 free_node (oldnode);
+                 oldnode = rootnode;
+               }
+
+             /* Lookup the node the symlink points to.  */
+             find_file (symlink, oldnode, &currnode);
+             type = foundtype;
+             grub_free (symlink);
+
+             if (grub_errno)
+               {
+                 free_node (oldnode);
+                 return grub_errno;
+               }
+           }
+
+         free_node (oldnode);
+
+         /* Found the node!  */
+         if (! next || *next == '\0')
+           {
+             *currfound = currnode;
+             foundtype = type;
+             return 0;
+           }
+
+         name = next;
+       }
+
+      return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+    }
+
+  if (!path || path[0] != '/')
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
+      return grub_errno;
+    }
+
+  err = find_file (path, rootnode, foundnode);
+  if (err)
+    return err;
+
+  /* Check if the node that was found was of the expected type.  */
+  if (expecttype == GRUB_FSHELP_REG && foundtype != expecttype)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file");
+  else if (expecttype == GRUB_FSHELP_DIR && foundtype != expecttype)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+
+  return 0;
+}
+
+/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
+   beginning with the block POS.  READ_HOOK should be set before
+   reading a block from the file.  GET_BLOCK is used to translate file
+   blocks to disk blocks.  The file is FILESIZE bytes big and the
+   blocks have a size of LOG2BLOCKSIZE (in log2).  */
+grub_ssize_t
+grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
+                      void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                                           unsigned offset,
+                                                           unsigned length),
+                      grub_off_t pos, grub_size_t len, char *buf,
+                      grub_disk_addr_t (*get_block) (grub_fshelp_node_t node,
+                                                      grub_disk_addr_t block),
+                      grub_off_t filesize, int log2blocksize)
+{
+  grub_disk_addr_t i, blockcnt;
+  int blocksize = 1 << (log2blocksize + GRUB_DISK_SECTOR_BITS);
+
+  /* Adjust LEN so it we can't read past the end of the file.  */
+  if (pos + len > filesize)
+    len = filesize - pos;
+
+  blockcnt = ((len + pos) + blocksize - 1) >> (log2blocksize + GRUB_DISK_SECTOR_BITS);
+
+  for (i = pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS); i < blockcnt; i++)
+    {
+      grub_disk_addr_t blknr;
+      int blockoff = pos & (blocksize - 1);
+      int blockend = blocksize;
+
+      int skipfirst = 0;
+
+      blknr = get_block (node, i);
+      if (grub_errno)
+       return -1;
+
+      blknr = blknr << log2blocksize;
+
+      /* Last block.  */
+      if (i == blockcnt - 1)
+       {
+         blockend = (len + pos) & (blocksize - 1);
+
+         /* The last portion is exactly blocksize.  */
+         if (! blockend)
+           blockend = blocksize;
+       }
+
+      /* First block.  */
+      if (i == (pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS)))
+       {
+         skipfirst = blockoff;
+         blockend -= skipfirst;
+       }
+
+      /* If the block number is 0 this block is not stored on disk but
+        is zero filled instead.  */
+      if (blknr)
+       {
+         disk->read_hook = read_hook;
+
+         grub_disk_read (disk, blknr, skipfirst,
+                         blockend, buf);
+         disk->read_hook = 0;
+         if (grub_errno)
+           return -1;
+       }
+      else
+       grub_memset (buf, 0, blockend);
+
+      buf += blocksize - skipfirst;
+    }
+
+  return len;
+}
+
+unsigned int
+grub_fshelp_log2blksize (unsigned int blksize, unsigned int *pow)
+{
+  int mod;
+
+  *pow = 0;
+  while (blksize > 1)
+    {
+      mod = blksize - ((blksize >> 1) << 1);
+      blksize >>= 1;
+
+      /* Check if it really is a power of two.  */
+      if (mod)
+       return grub_error (GRUB_ERR_BAD_NUMBER,
+                          "the blocksize is not a power of two");
+      (*pow)++;
+    }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c
new file mode 100644 (file)
index 0000000..cef8563
--- /dev/null
@@ -0,0 +1,1122 @@
+/* hfs.c - HFS.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* HFS is documented at
+   http://developer.apple.com/documentation/mac/Files/Files-2.html */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/hfs.h>
+
+#define        GRUB_HFS_SBLOCK         2
+#define GRUB_HFS_EMBED_HFSPLUS_SIG 0x482B
+
+#define GRUB_HFS_BLKS          (data->blksz >> 9)
+
+#define GRUB_HFS_NODE_LEAF     0xFF
+
+/* The two supported filesystems a record can have.  */
+enum
+  {
+    GRUB_HFS_FILETYPE_DIR = 1,
+    GRUB_HFS_FILETYPE_FILE = 2
+  };
+
+/* Catalog node ID (CNID).  */
+enum grub_hfs_cnid_type
+  {
+    GRUB_HFS_CNID_ROOT_PARENT = 1,
+    GRUB_HFS_CNID_ROOT = 2,
+    GRUB_HFS_CNID_EXT = 3,
+    GRUB_HFS_CNID_CAT = 4,
+    GRUB_HFS_CNID_BAD = 5
+  };
+
+/* A node descriptor.  This is the header of every node.  */
+struct grub_hfs_node
+{
+  grub_uint32_t next;
+  grub_uint32_t prev;
+  grub_uint8_t type;
+  grub_uint8_t level;
+  grub_uint16_t reccnt;
+  grub_uint16_t unused;
+} __attribute__ ((packed));
+
+/* The head of the B*-Tree.  */
+struct grub_hfs_treeheader
+{
+  grub_uint16_t tree_depth;
+  /* The number of the first node.  */
+  grub_uint32_t root_node;
+  grub_uint32_t leaves;
+  grub_uint32_t first_leaf;
+  grub_uint32_t last_leaf;
+  grub_uint16_t node_size;
+  grub_uint16_t key_size;
+  grub_uint32_t nodes;
+  grub_uint32_t free_nodes;
+  grub_uint8_t unused[76];
+} __attribute__ ((packed));
+
+/* The state of a mounted HFS filesystem.  */
+struct grub_hfs_data
+{
+  struct grub_hfs_sblock sblock;
+  grub_disk_t disk;
+  grub_hfs_datarecord_t extents;
+  int fileid;
+  int size;
+  int ext_root;
+  int ext_size;
+  int cat_root;
+  int cat_size;
+  int blksz;
+  int log2_blksz;
+  int rootdir;
+};
+
+/* The key as used on disk in a catalog tree.  This is used to lookup
+   file/directory nodes by parent directory ID and filename.  */
+struct grub_hfs_catalog_key
+{
+  grub_uint8_t unused;
+  grub_uint32_t parent_dir;
+
+  /* Filename length.  */
+  grub_uint8_t strlen;
+
+  /* Filename.  */
+  grub_uint8_t str[31];
+} __attribute__ ((packed));
+
+/* The key as used on disk in a extent overflow tree.  Using this key
+   the extents can be looked up using a fileid and logical start block
+   as index.  */
+struct grub_hfs_extent_key
+{
+  /* The kind of fork.  This is used to store meta information like
+     icons, attributes, etc.  We will only use the datafork, which is
+     0.  */
+  grub_uint8_t forktype;
+  grub_uint32_t fileid;
+  grub_uint16_t first_block;
+} __attribute__ ((packed));
+
+/* A directory record.  This is used to find out the directory ID.  */
+struct grub_hfs_dirrec
+{
+  /* For a directory, type == 1.  */
+  grub_uint8_t type;
+  grub_uint8_t unused[5];
+  grub_uint32_t dirid;
+} __attribute__ ((packed));
+
+/* Information about a file.  */
+struct grub_hfs_filerec
+{
+  /* For a file, type == 2.  */
+  grub_uint8_t type;
+  grub_uint8_t unused[19];
+  grub_uint32_t fileid;
+  grub_uint8_t unused2[2];
+  grub_uint32_t size;
+  grub_uint8_t unused3[44];
+
+  /* The first 3 extents of the file.  The other extents can be found
+     in the extent overflow file.  */
+  grub_hfs_datarecord_t extents;
+} __attribute__ ((packed));
+
+/* A record descriptor, both key and data, used to pass to call back
+   functions.  */
+struct grub_hfs_record
+{
+  void *key;
+  int keylen;
+  void *data;
+  int datalen;
+};
+
+static grub_dl_t my_mod;
+\f
+static int grub_hfs_find_node (struct grub_hfs_data *, char *,
+                              grub_uint32_t, int, char *, int);
+
+/* Find block BLOCK of the file FILE in the mounted UFS filesystem
+   DATA.  The first 3 extents are described by DAT.  If cache is set,
+   using caching to improve non-random reads.  */
+static unsigned int
+grub_hfs_block (struct grub_hfs_data *data, grub_hfs_datarecord_t dat,
+               int file, int block, int cache)
+{
+  grub_hfs_datarecord_t dr;
+  int pos = 0;
+  struct grub_hfs_extent_key key;
+
+  int tree = 0;
+  static int cache_file = 0;
+  static int cache_pos = 0;
+  static grub_hfs_datarecord_t cache_dr;
+
+  grub_memcpy (dr, dat, sizeof (dr));
+
+  key.forktype = 0;
+  key.fileid = grub_cpu_to_be32 (file);
+
+  if (cache && cache_file == file  && block > cache_pos)
+    {
+      pos = cache_pos;
+      key.first_block = grub_cpu_to_be16 (pos);
+      grub_memcpy (dr, cache_dr, sizeof (cache_dr));
+    }
+
+  for (;;)
+    {
+      int i;
+
+      /* Try all 3 extents.  */
+      for (i = 0; i < 3; i++)
+       {
+         /* Check if the block is stored in this extent.  */
+         if (grub_be_to_cpu16 (dr[i].count) + pos > block)
+           {
+             int first = grub_be_to_cpu16 (dr[i].first_block);
+
+             /* If the cache is enabled, store the current position
+                in the tree.  */
+             if (tree && cache)
+               {
+                 cache_file = file;
+                 cache_pos = pos;
+                 grub_memcpy (cache_dr, dr, sizeof (cache_dr));
+               }
+
+             return (grub_be_to_cpu16 (data->sblock.first_block)
+                     + (first + block - pos) * GRUB_HFS_BLKS);
+           }
+
+         /* Try the next extent.  */
+         pos += grub_be_to_cpu16 (dr[i].count);
+       }
+
+      /* Lookup the block in the extent overflow file.  */
+      key.first_block = grub_cpu_to_be16 (pos);
+      tree = 1;
+      grub_hfs_find_node (data, (char *) &key, data->ext_root,
+                         1, (char *) &dr, sizeof (dr));
+      if (grub_errno)
+       return 0;
+    }
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_hfs_read_file (struct grub_hfs_data *data,
+                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                      unsigned offset, unsigned length),
+                    int pos, grub_size_t len, char *buf)
+{
+  int i;
+  int blockcnt;
+
+  blockcnt = ((len + pos)
+             + data->blksz - 1) / data->blksz;
+
+  for (i = pos / data->blksz; i < blockcnt; i++)
+    {
+      int blknr;
+      int blockoff = pos % data->blksz;
+      int blockend = data->blksz;
+
+      int skipfirst = 0;
+
+      blknr = grub_hfs_block (data, data->extents, data->fileid, i, 1);
+      if (grub_errno)
+       return -1;
+
+      /* Last block.  */
+      if (i == blockcnt - 1)
+       {
+         blockend = (len + pos) % data->blksz;
+
+         /* The last portion is exactly EXT2_BLOCK_SIZE (data).  */
+         if (! blockend)
+           blockend = data->blksz;
+       }
+
+      /* First block.  */
+      if (i == pos / data->blksz)
+       {
+         skipfirst = blockoff;
+         blockend -= skipfirst;
+       }
+
+      /* If the block number is 0 this block is not stored on disk but
+        is zero filled instead.  */
+      if (blknr)
+       {
+         data->disk->read_hook = read_hook;
+         grub_disk_read (data->disk, blknr, skipfirst,
+                         blockend, buf);
+         data->disk->read_hook = 0;
+         if (grub_errno)
+           return -1;
+       }
+
+      buf += data->blksz - skipfirst;
+    }
+
+  return len;
+}
+
+
+/* Mount the filesystem on the disk DISK.  */
+static struct grub_hfs_data *
+grub_hfs_mount (grub_disk_t disk)
+{
+  struct grub_hfs_data *data;
+  struct grub_hfs_catalog_key key;
+  struct grub_hfs_dirrec dir;
+  int first_block;
+
+  struct
+  {
+    struct grub_hfs_node node;
+    struct grub_hfs_treeheader head;
+  } treehead;
+
+  data = grub_malloc (sizeof (struct grub_hfs_data));
+  if (!data)
+    return 0;
+
+  /* Read the superblock.  */
+  if (grub_disk_read (disk, GRUB_HFS_SBLOCK, 0,
+                     sizeof (struct grub_hfs_sblock), &data->sblock))
+    goto fail;
+
+  /* Check if this is a HFS filesystem.  */
+  if (grub_be_to_cpu16 (data->sblock.magic) != GRUB_HFS_MAGIC)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not an HFS filesystem");
+      goto fail;
+    }
+
+  /* Check if this is an embedded HFS+ filesystem.  */
+  if (grub_be_to_cpu16 (data->sblock.embed_sig) == GRUB_HFS_EMBED_HFSPLUS_SIG)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "embedded HFS+ filesystem");
+      goto fail;
+    }
+
+  data->blksz = grub_be_to_cpu32 (data->sblock.blksz);
+  data->disk = disk;
+
+  /* Lookup the root node of the extent overflow tree.  */
+  first_block = ((grub_be_to_cpu16 (data->sblock.extent_recs[0].first_block)
+                 * GRUB_HFS_BLKS)
+                + grub_be_to_cpu16 (data->sblock.first_block));
+
+  if (grub_disk_read (data->disk, first_block, 0,
+                     sizeof (treehead), &treehead))
+    goto fail;
+  data->ext_root = grub_be_to_cpu32 (treehead.head.root_node);
+  data->ext_size = grub_be_to_cpu16 (treehead.head.node_size);
+
+  /* Lookup the root node of the catalog tree.  */
+  first_block = ((grub_be_to_cpu16 (data->sblock.catalog_recs[0].first_block)
+                 * GRUB_HFS_BLKS)
+                + grub_be_to_cpu16 (data->sblock.first_block));
+  if (grub_disk_read (data->disk, first_block, 0,
+                     sizeof (treehead), &treehead))
+    goto fail;
+  data->cat_root = grub_be_to_cpu32 (treehead.head.root_node);
+  data->cat_size = grub_be_to_cpu16 (treehead.head.node_size);
+
+  /* Lookup the root directory node in the catalog tree using the
+     volume name.  */
+  key.parent_dir = grub_cpu_to_be32 (1);
+  key.strlen = data->sblock.volname[0];
+  grub_strcpy ((char *) key.str, (char *) (data->sblock.volname + 1));
+
+  if (grub_hfs_find_node (data, (char *) &key, data->cat_root,
+                         0, (char *) &dir, sizeof (dir)) == 0)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "cannot find the HFS root directory");
+      goto fail;
+    }
+
+  if (grub_errno)
+    goto fail;
+
+  data->rootdir = grub_be_to_cpu32 (dir.dirid);
+
+  return data;
+ fail:
+  grub_free (data);
+
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not a HFS filesystem");
+
+  return 0;
+}
+
+/* Compare the K1 and K2 catalog file keys using HFS character ordering.  */
+static int
+grub_hfs_cmp_catkeys (struct grub_hfs_catalog_key *k1,
+                     struct grub_hfs_catalog_key *k2)
+{
+  /* Taken from hfsutils 3.2.6 and converted to a readable form */
+  static const unsigned char hfs_charorder[256] = {
+    [0x00] = 0,
+    [0x01] = 1,
+    [0x02] = 2,
+    [0x03] = 3,
+    [0x04] = 4,
+    [0x05] = 5,
+    [0x06] = 6,
+    [0x07] = 7,
+    [0x08] = 8,
+    [0x09] = 9,
+    [0x0A] = 10,
+    [0x0B] = 11,
+    [0x0C] = 12,
+    [0x0D] = 13,
+    [0x0E] = 14,
+    [0x0F] = 15,
+    [0x10] = 16,
+    [0x11] = 17,
+    [0x12] = 18,
+    [0x13] = 19,
+    [0x14] = 20,
+    [0x15] = 21,
+    [0x16] = 22,
+    [0x17] = 23,
+    [0x18] = 24,
+    [0x19] = 25,
+    [0x1A] = 26,
+    [0x1B] = 27,
+    [0x1C] = 28,
+    [0x1D] = 29,
+    [0x1E] = 30,
+    [0x1F] = 31,
+    [' '] = 32,                [0xCA] = 32,
+    ['!'] = 33,
+    ['"'] = 34,
+    [0xD2] = 35,
+    [0xD3] = 36,
+    [0xC7] = 37,
+    [0xC8] = 38,
+    ['#'] = 39,
+    ['$'] = 40,
+    ['%'] = 41,
+    ['&'] = 42,
+    ['\''] = 43,
+    [0xD4] = 44,
+    [0xD5] = 45,
+    ['('] = 46,
+    [')'] = 47,
+    ['*'] = 48,
+    ['+'] = 49,
+    [','] = 50,
+    ['-'] = 51,
+    ['.'] = 52,
+    ['/'] = 53,
+    ['0'] = 54,
+    ['1'] = 55,
+    ['2'] = 56,
+    ['3'] = 57,
+    ['4'] = 58,
+    ['5'] = 59,
+    ['6'] = 60,
+    ['7'] = 61,
+    ['8'] = 62,
+    ['9'] = 63,
+    [':'] = 64,
+    [';'] = 65,
+    ['<'] = 66,
+    ['='] = 67,
+    ['>'] = 68,
+    ['?'] = 69,
+    ['@'] = 70,
+    ['A'] = 71,                ['a'] = 71,
+    [0x88] = 72,       [0xCB] = 72,
+    [0x80] = 73,       [0x8A] = 73,
+    [0x8B] = 74,       [0xCC] = 74,
+    [0x81] = 75,       [0x8C] = 75,
+    [0xAE] = 76,       [0xBE] = 76,
+    ['`'] = 77,
+    [0x87] = 78,
+    [0x89] = 79,
+    [0xBB] = 80,
+    ['B'] = 81,                ['b'] = 81,
+    ['C'] = 82,                ['c'] = 82,
+    [0x82] = 83,       [0x8D] = 83,
+    ['D'] = 84,                ['d'] = 84,
+    ['E'] = 85,                ['e'] = 85,
+    [0x83] = 86,       [0x8E] = 86,
+    [0x8F] = 87,
+    [0x90] = 88,
+    [0x91] = 89,
+    ['F'] = 90,                ['f'] = 90,
+    ['G'] = 91,                ['g'] = 91,
+    ['H'] = 92,                ['h'] = 92,
+    ['I'] = 93,                ['i'] = 93,
+    [0x92] = 94,
+    [0x93] = 95,
+    [0x94] = 96,
+    [0x95] = 97,
+    ['J'] = 98,                ['j'] = 98,
+    ['K'] = 99,                ['k'] = 99,
+    ['L'] = 100,       ['l'] = 100,
+    ['M'] = 101,       ['m'] = 101,
+    ['N'] = 102,       ['n'] = 102,
+    [0x84] = 103,      [0x96] = 103,
+    ['O'] = 104,       ['o'] = 104,
+    [0x85] = 105,      [0x9A] = 105,
+    [0x9B] = 106,      [0xCD] = 106,
+    [0xAF] = 107,      [0xBF] = 107,
+    [0xCE] = 108,      [0xCF] = 108,
+    [0x97] = 109,
+    [0x98] = 110,
+    [0x99] = 111,
+    [0xBC] = 112,
+    ['P'] = 113,       ['p'] = 113,
+    ['Q'] = 114,       ['q'] = 114,
+    ['R'] = 115,       ['r'] = 115,
+    ['S'] = 116,       ['s'] = 116,
+    [0xA7] = 117,
+    ['T'] = 118,       ['t'] = 118,
+    ['U'] = 119,       ['u'] = 119,
+    [0x86] = 120,      [0x9F] = 120,
+    [0x9C] = 121,
+    [0x9D] = 122,
+    [0x9E] = 123,
+    ['V'] = 124,       ['v'] = 124,
+    ['W'] = 125,       ['w'] = 125,
+    ['X'] = 126,       ['x'] = 126,
+    ['Y'] = 127,       ['y'] = 127,
+    [0xD8] = 128,
+    ['Z'] = 129,       ['z'] = 129,
+    ['['] = 130,
+    ['\\'] = 131,
+    [']'] = 132,
+    ['^'] = 133,
+    ['_'] = 134,
+    ['{'] = 135,
+    ['|'] = 136,
+    ['}'] = 137,
+    ['~'] = 138,
+    [0x7F] = 139,
+    [0xA0] = 140,
+    [0xA1] = 141,
+    [0xA2] = 142,
+    [0xA3] = 143,
+    [0xA4] = 144,
+    [0xA5] = 145,
+    [0xA6] = 146,
+    [0xA8] = 147,
+    [0xA9] = 148,
+    [0xAA] = 149,
+    [0xAB] = 150,
+    [0xAC] = 151,
+    [0xAD] = 152,
+    [0xB0] = 153,
+    [0xB1] = 154,
+    [0xB2] = 155,
+    [0xB3] = 156,
+    [0xB4] = 157,
+    [0xB5] = 158,
+    [0xB6] = 159,
+    [0xB7] = 160,
+    [0xB8] = 161,
+    [0xB9] = 162,
+    [0xBA] = 163,
+    [0xBD] = 164,
+    [0xC0] = 165,
+    [0xC1] = 166,
+    [0xC2] = 167,
+    [0xC3] = 168,
+    [0xC4] = 169,
+    [0xC5] = 170,
+    [0xC6] = 171,
+    [0xC9] = 172,
+    [0xD0] = 173,
+    [0xD1] = 174,
+    [0xD6] = 175,
+    [0xD7] = 176,
+    [0xD9] = 177,
+    [0xDA] = 178,
+    [0xDB] = 179,
+    [0xDC] = 180,
+    [0xDD] = 181,
+    [0xDE] = 182,
+    [0xDF] = 183,
+    [0xE0] = 184,
+    [0xE1] = 185,
+    [0xE2] = 186,
+    [0xE3] = 187,
+    [0xE4] = 188,
+    [0xE5] = 189,
+    [0xE6] = 190,
+    [0xE7] = 191,
+    [0xE8] = 192,
+    [0xE9] = 193,
+    [0xEA] = 194,
+    [0xEB] = 195,
+    [0xEC] = 196,
+    [0xED] = 197,
+    [0xEE] = 198,
+    [0xEF] = 199,
+    [0xF0] = 200,
+    [0xF1] = 201,
+    [0xF2] = 202,
+    [0xF3] = 203,
+    [0xF4] = 204,
+    [0xF5] = 205,
+    [0xF6] = 206,
+    [0xF7] = 207,
+    [0xF8] = 208,
+    [0xF9] = 209,
+    [0xFA] = 210,
+    [0xFB] = 211,
+    [0xFC] = 212,
+    [0xFD] = 213,
+    [0xFE] = 214,
+    [0xFF] = 215,
+  };
+  int i;
+  int cmp;
+  int minlen = (k1->strlen < k2->strlen) ? k1->strlen : k2->strlen;
+
+  cmp = (grub_be_to_cpu32 (k1->parent_dir) - grub_be_to_cpu32 (k2->parent_dir));
+  if (cmp != 0)
+    return cmp;
+
+  for (i = 0; i < minlen; i++)
+    {
+      cmp = (hfs_charorder[k1->str[i]] - hfs_charorder[k2->str[i]]);
+      if (cmp != 0)
+       return cmp;
+    }
+
+  /* Shorter strings precede long ones.  */
+  return (k1->strlen - k2->strlen);
+}
+
+
+/* Compare the K1 and K2 extent overflow file keys.  */
+static int
+grub_hfs_cmp_extkeys (struct grub_hfs_extent_key *k1,
+                     struct grub_hfs_extent_key *k2)
+{
+  int cmp = k1->forktype - k2->forktype;
+  if (cmp == 0)
+    cmp = grub_be_to_cpu32 (k1->fileid) - grub_be_to_cpu32 (k2->fileid);
+  if (cmp == 0)
+    cmp = (grub_be_to_cpu16 (k1->first_block)
+          - grub_be_to_cpu16 (k2->first_block));
+  return cmp;
+}
+
+
+/* Iterate the records in the node with index IDX in the mounted HFS
+   filesystem DATA.  This node holds data of the type TYPE (0 =
+   catalog node, 1 = extent overflow node).  If this is set, continue
+   iterating to the next node.  For every records, call NODE_HOOK.  */
+static grub_err_t
+grub_hfs_iterate_records (struct grub_hfs_data *data, int type, int idx,
+                         int this, int (*node_hook) (struct grub_hfs_node *hnd,
+                                                     struct grub_hfs_record *))
+{
+  int nodesize = type == 0 ? data->cat_size : data->ext_size;
+
+  union
+  {
+    struct grub_hfs_node node;
+    char rawnode[nodesize];
+    grub_uint16_t offsets[nodesize / 2];
+  } node;
+
+  do
+    {
+      int i;
+      struct grub_hfs_extent *dat;
+      int blk;
+
+      dat = (struct grub_hfs_extent *) (type == 0
+                                       ? (&data->sblock.catalog_recs)
+                                       : (&data->sblock.extent_recs));
+
+      /* Read the node into memory.  */
+      blk = grub_hfs_block (data, dat,
+                            (type == 0) ? GRUB_HFS_CNID_CAT : GRUB_HFS_CNID_EXT,
+                           idx / (data->blksz / nodesize), 0);
+      blk += (idx % (data->blksz / nodesize));
+      if (grub_errno)
+       return grub_errno;
+
+      if (grub_disk_read (data->disk, blk, 0,
+                         sizeof (node), &node))
+       return grub_errno;
+
+      /* Iterate over all records in this node.  */
+      for (i = 0; i < grub_be_to_cpu16 (node.node.reccnt); i++)
+       {
+         int pos = (nodesize >> 1) - 1 - i;
+         struct pointer
+         {
+           grub_uint8_t keylen;
+           grub_uint8_t key;
+         } __attribute__ ((packed)) *pnt;
+         pnt = (struct pointer *) (grub_be_to_cpu16 (node.offsets[pos])
+                                   + node.rawnode);
+
+         struct grub_hfs_record rec =
+           {
+             &pnt->key,
+             pnt->keylen,
+             &pnt->key + pnt->keylen +(pnt->keylen + 1) % 2,
+             nodesize - grub_be_to_cpu16 (node.offsets[pos])
+             - pnt->keylen - 1
+           };
+
+         if (node_hook (&node.node, &rec))
+           return 0;
+       }
+
+      idx = grub_be_to_cpu32 (node.node.next);
+    } while (idx && this);
+
+  return 0;
+}
+
+
+/* Lookup a record in the mounted filesystem DATA using the key KEY.
+   The index of the node on top of the tree is IDX.  The tree is of
+   the type TYPE (0 = catalog node, 1 = extent overflow node).  Return
+   the data in DATAR with a maximum length of DATALEN.  */
+static int
+grub_hfs_find_node (struct grub_hfs_data *data, char *key,
+                   grub_uint32_t idx, int type, char *datar, int datalen)
+{
+  int found = -1;
+  int isleaf = 0;
+  int done = 0;
+
+  auto int node_found (struct grub_hfs_node *, struct grub_hfs_record *);
+
+  int node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec)
+    {
+      int cmp = 1;
+
+      if (type == 0)
+       cmp = grub_hfs_cmp_catkeys (rec->key, (void *) key);
+      else
+       cmp = grub_hfs_cmp_extkeys (rec->key, (void *) key);
+
+      /* If the key is smaller or equal to the current node, mark the
+        entry.  In case of a non-leaf mode it will be used to lookup
+        the rest of the tree.  */
+      if (cmp <= 0)
+       {
+         grub_uint32_t *node = (grub_uint32_t *) rec->data;
+         found = grub_be_to_cpu32 (*node);
+       }
+      else /* The key can not be found in the tree. */
+       return 1;
+
+      /* Check if this node is a leaf node.  */
+      if (hnd->type == GRUB_HFS_NODE_LEAF)
+       {
+         isleaf = 1;
+
+         /* Found it!!!!  */
+         if (cmp == 0)
+           {
+              done = 1;
+
+             grub_memcpy (datar, rec->data,
+                          rec->datalen < datalen ? rec->datalen : datalen);
+             return 1;
+           }
+       }
+
+      return 0;
+    }
+
+  do
+    {
+      found = -1;
+
+      if (grub_hfs_iterate_records (data, type, idx, 0, node_found))
+        return 0;
+
+      if (found == -1)
+        return 0;
+
+      idx = found;
+    } while (! isleaf);
+
+  return done;
+}
+
+
+/* Iterate over the directory with the id DIR.  The tree is searched
+   starting with the node ROOT_IDX.  For every entry in this directory
+   call HOOK.  */
+static grub_err_t
+grub_hfs_iterate_dir (struct grub_hfs_data *data, grub_uint32_t root_idx,
+                     unsigned int dir, int (*hook) (struct grub_hfs_record *))
+{
+  int found = -1;
+  int isleaf = 0;
+  int next = 0;
+
+  /* The lowest key possible with DIR as root directory.  */
+  struct grub_hfs_catalog_key key = {0, grub_cpu_to_be32 (dir), 0, ""};
+
+  auto int node_found (struct grub_hfs_node *, struct grub_hfs_record *);
+  auto int it_dir (struct grub_hfs_node * __attribute ((unused)),
+                  struct grub_hfs_record *);
+
+
+  int node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec)
+    {
+      struct grub_hfs_catalog_key *ckey = rec->key;
+
+      if (grub_hfs_cmp_catkeys (rec->key, (void *) &key) <= 0)
+       found = grub_be_to_cpu32 (*(grub_uint32_t *) rec->data);
+
+      if (hnd->type == 0xFF && ckey->strlen > 0)
+       {
+         isleaf = 1;
+         next = grub_be_to_cpu32 (hnd->next);
+
+         /* An entry was found.  */
+         if (grub_be_to_cpu32 (ckey->parent_dir) == dir)
+           return hook (rec);
+       }
+
+      return 0;
+    }
+
+  int it_dir (struct grub_hfs_node *hnd __attribute ((unused)),
+             struct grub_hfs_record *rec)
+    {
+      struct grub_hfs_catalog_key *ckey = rec->key;
+      struct grub_hfs_catalog_key *origkey = &key;
+
+      /* Stop when the entries do not match anymore.  */
+      if (grub_be_to_cpu32 (ckey->parent_dir)
+         != grub_be_to_cpu32 ((origkey)->parent_dir))
+       return 1;
+
+      return hook (rec);
+    }
+
+  do
+    {
+      found = -1;
+
+      if (grub_hfs_iterate_records (data, 0, root_idx, 0, node_found))
+        return grub_errno;
+
+      if (found == -1)
+        return 0;
+
+      root_idx = found;
+    } while (! isleaf);
+
+  /* If there was a matching record in this leaf node, continue the
+     iteration until the last record was found.  */
+  grub_hfs_iterate_records (data, 0, next, 1, it_dir);
+  return grub_errno;
+}
+
+
+/* Find a file or directory with the pathname PATH in the filesystem
+   DATA.  Return the file record in RETDATA when it is non-zero.
+   Return the directory number in RETINODE when it is non-zero.  */
+static grub_err_t
+grub_hfs_find_dir (struct grub_hfs_data *data, const char *path,
+                  struct grub_hfs_filerec *retdata, int *retinode)
+{
+  int inode = data->rootdir;
+  char *next;
+  char *origpath;
+  union {
+    struct grub_hfs_filerec frec;
+    struct grub_hfs_dirrec dir;
+  } fdrec;
+
+  fdrec.frec.type = GRUB_HFS_FILETYPE_DIR;
+
+  if (path[0] != '/')
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
+      return 0;
+    }
+
+  origpath = grub_strdup (path);
+  if (!origpath)
+    return grub_errno;
+
+  path = origpath;
+  while (*path == '/')
+    path++;
+
+  while (path && grub_strlen (path))
+    {
+      if (fdrec.frec.type != GRUB_HFS_FILETYPE_DIR)
+       {
+         grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+         goto fail;
+       }
+
+      /* Isolate a part of the path.  */
+      next = grub_strchr (path, '/');
+      if (next)
+       {
+         while (*next == '/')
+           *(next++) = '\0';
+       }
+
+      struct grub_hfs_catalog_key key;
+
+      key.parent_dir = grub_cpu_to_be32 (inode);
+      key.strlen = grub_strlen (path);
+      grub_strcpy ((char *) (key.str), path);
+
+      /* Lookup this node.  */
+      if (! grub_hfs_find_node (data, (char *) &key, data->cat_root,
+                               0, (char *) &fdrec.frec, sizeof (fdrec.frec)))
+       {
+         grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+         goto fail;
+       }
+
+      if (grub_errno)
+       goto fail;
+
+      inode = grub_be_to_cpu32 (fdrec.dir.dirid);
+      path = next;
+    }
+
+  if (retdata)
+    grub_memcpy (retdata, &fdrec.frec, sizeof (fdrec.frec));
+
+  if (retinode)
+    *retinode = inode;
+
+ fail:
+  grub_free (origpath);
+  return grub_errno;
+}
+
+
+\f
+static grub_err_t
+grub_hfs_dir (grub_device_t device, const char *path,
+                 int (*hook) (const char *filename,
+                              const struct grub_dirhook_info *info))
+{
+  int inode;
+
+  auto int dir_hook (struct grub_hfs_record *rec);
+
+  int dir_hook (struct grub_hfs_record *rec)
+    {
+      char fname[32] = { 0 };
+      char *filetype = rec->data;
+      struct grub_hfs_catalog_key *ckey = rec->key;
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+
+      grub_strncpy (fname, (char *) (ckey->str), ckey->strlen);
+
+      if (*filetype == GRUB_HFS_FILETYPE_DIR
+         || *filetype == GRUB_HFS_FILETYPE_FILE)
+       {
+         info.dir = (*filetype == GRUB_HFS_FILETYPE_DIR);
+         return hook (fname, &info);
+       }
+      return 0;
+    }
+
+  struct grub_hfs_data *data;
+  struct grub_hfs_filerec frec;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_hfs_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  /* First the directory ID for the directory.  */
+  if (grub_hfs_find_dir (data, path, &frec, &inode))
+    goto fail;
+
+  if (frec.type != GRUB_HFS_FILETYPE_DIR)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+      goto fail;
+    }
+
+  grub_hfs_iterate_dir (data, data->cat_root, inode, dir_hook);
+
+ fail:
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_hfs_open (struct grub_file *file, const char *name)
+{
+  struct grub_hfs_data *data;
+  struct grub_hfs_filerec frec;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_hfs_mount (file->device->disk);
+
+  if (grub_hfs_find_dir (data, name, &frec, 0))
+    {
+      grub_free (data);
+      grub_dl_unref (my_mod);
+      return grub_errno;
+    }
+
+  if (frec.type != GRUB_HFS_FILETYPE_FILE)
+    {
+      grub_free (data);
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a file");
+      grub_dl_unref (my_mod);
+      return grub_errno;
+    }
+
+  grub_memcpy (data->extents, frec.extents, sizeof (grub_hfs_datarecord_t));
+  file->size = grub_be_to_cpu32 (frec.size);
+  data->size = grub_be_to_cpu32 (frec.size);
+  data->fileid = grub_be_to_cpu32 (frec.fileid);
+  file->offset = 0;
+
+  file->data = data;
+
+  return 0;
+}
+
+static grub_ssize_t
+grub_hfs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_hfs_data *data =
+    (struct grub_hfs_data *) file->data;
+
+  return grub_hfs_read_file (data, file->read_hook, file->offset, len, buf);
+}
+
+
+static grub_err_t
+grub_hfs_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return 0;
+}
+
+
+static grub_err_t
+grub_hfs_label (grub_device_t device, char **label)
+{
+  struct grub_hfs_data *data;
+
+  data = grub_hfs_mount (device->disk);
+
+  if (data)
+    *label = grub_strndup ((char *) (data->sblock.volname + 1),
+                          *data->sblock.volname);
+  else
+    *label = 0;
+
+  grub_free (data);
+  return grub_errno;
+}
+
+static grub_err_t
+grub_hfs_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_hfs_data *data;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_hfs_mount (device->disk);
+  if (data && data->sblock.num_serial != 0)
+    {
+      *uuid = grub_xasprintf ("%016llx",
+                            (unsigned long long)
+                            grub_be_to_cpu64 (data->sblock.num_serial));
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+\f
+static struct grub_fs grub_hfs_fs =
+  {
+    .name = "hfs",
+    .dir = grub_hfs_dir,
+    .open = grub_hfs_open,
+    .read = grub_hfs_read,
+    .close = grub_hfs_close,
+    .label = grub_hfs_label,
+    .uuid = grub_hfs_uuid,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(hfs)
+{
+  grub_fs_register (&grub_hfs_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(hfs)
+{
+  grub_fs_unregister (&grub_hfs_fs);
+}
diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
new file mode 100644 (file)
index 0000000..bcb8e95
--- /dev/null
@@ -0,0 +1,1039 @@
+/* hfsplus.c - HFS+ Filesystem.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* HFS+ is documented at http://developer.apple.com/technotes/tn/tn1150.html */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+#include <grub/hfs.h>
+#include <grub/charset.h>
+
+#define GRUB_HFSPLUS_MAGIC 0x482B
+#define GRUB_HFSPLUSX_MAGIC 0x4858
+#define GRUB_HFSPLUS_SBLOCK 2
+
+/* A HFS+ extent.  */
+struct grub_hfsplus_extent
+{
+  /* The first block of a file on disk.  */
+  grub_uint32_t start;
+  /* The amount of blocks described by this extent.  */
+  grub_uint32_t count;
+} __attribute__ ((packed));
+
+/* The descriptor of a fork.  */
+struct grub_hfsplus_forkdata
+{
+  grub_uint64_t size;
+  grub_uint32_t clumpsize;
+  grub_uint32_t blocks;
+  struct grub_hfsplus_extent extents[8];
+} __attribute__ ((packed));
+
+/* The HFS+ Volume Header.  */
+struct grub_hfsplus_volheader
+{
+  grub_uint16_t magic;
+  grub_uint16_t version;
+  grub_uint32_t attributes;
+  grub_uint8_t unused1[12];
+  grub_uint32_t utime;
+  grub_uint8_t unused2[16];
+  grub_uint32_t blksize;
+  grub_uint8_t unused3[60];
+  grub_uint64_t num_serial;
+  struct grub_hfsplus_forkdata allocations_file;
+  struct grub_hfsplus_forkdata extents_file;
+  struct grub_hfsplus_forkdata catalog_file;
+  struct grub_hfsplus_forkdata attrib_file;
+  struct grub_hfsplus_forkdata startup_file;
+} __attribute__ ((packed));
+
+/* The type of node.  */
+enum grub_hfsplus_btnode_type
+  {
+    GRUB_HFSPLUS_BTNODE_TYPE_LEAF = -1,
+    GRUB_HFSPLUS_BTNODE_TYPE_INDEX = 0,
+    GRUB_HFSPLUS_BTNODE_TYPE_HEADER = 1,
+    GRUB_HFSPLUS_BTNODE_TYPE_MAP = 2,
+  };
+
+struct grub_hfsplus_btnode
+{
+  grub_uint32_t next;
+  grub_uint32_t prev;
+  grub_int8_t type;
+  grub_uint8_t height;
+  grub_uint16_t count;
+  grub_uint16_t unused;
+} __attribute__ ((packed));
+
+/* The header of a HFS+ B+ Tree.  */
+struct grub_hfsplus_btheader
+{
+  grub_uint16_t depth;
+  grub_uint32_t root;
+  grub_uint32_t leaf_records;
+  grub_uint32_t first_leaf_node;
+  grub_uint32_t last_leaf_node;
+  grub_uint16_t nodesize;
+  grub_uint16_t keysize;
+  grub_uint32_t total_nodes;
+  grub_uint32_t free_nodes;
+  grub_uint16_t reserved1;
+  grub_uint32_t clump_size;  /* ignored */
+  grub_uint8_t btree_type;
+  grub_uint8_t key_compare;
+  grub_uint32_t attributes;
+} __attribute__ ((packed));
+
+/* The on disk layout of a catalog key.  */
+struct grub_hfsplus_catkey
+{
+  grub_uint16_t keylen;
+  grub_uint32_t parent;
+  grub_uint16_t namelen;
+  grub_uint16_t name[30];
+} __attribute__ ((packed));
+
+/* The on disk layout of an extent overflow file key.  */
+struct grub_hfsplus_extkey
+{
+  grub_uint16_t keylen;
+  grub_uint8_t type;
+  grub_uint8_t unused;
+  grub_uint32_t fileid;
+  grub_uint32_t start;
+} __attribute__ ((packed));
+
+struct grub_hfsplus_key
+{
+  union
+  {
+    struct grub_hfsplus_extkey extkey;
+    struct grub_hfsplus_catkey catkey;
+    grub_uint16_t keylen;
+  };
+} __attribute__ ((packed));
+
+struct grub_hfsplus_catfile
+{
+  grub_uint16_t type;
+  grub_uint16_t flags;
+  grub_uint32_t reserved;
+  grub_uint32_t fileid;
+  grub_uint8_t unused1[4];
+  grub_uint32_t mtime;
+  grub_uint8_t unused2[22];
+  grub_uint16_t mode;
+  grub_uint8_t unused3[44];
+  struct grub_hfsplus_forkdata data;
+  struct grub_hfsplus_forkdata resource;
+} __attribute__ ((packed));
+
+/* Filetype information as used in inodes.  */
+#define GRUB_HFSPLUS_FILEMODE_MASK     0170000
+#define GRUB_HFSPLUS_FILEMODE_REG      0100000
+#define GRUB_HFSPLUS_FILEMODE_DIRECTORY        0040000
+#define GRUB_HFSPLUS_FILEMODE_SYMLINK  0120000
+
+/* Some pre-defined file IDs.  */
+#define GRUB_HFSPLUS_FILEID_ROOTDIR    2
+#define GRUB_HFSPLUS_FILEID_OVERFLOW   3
+#define GRUB_HFSPLUS_FILEID_CATALOG    4
+
+enum grub_hfsplus_filetype
+  {
+    GRUB_HFSPLUS_FILETYPE_DIR = 1,
+    GRUB_HFSPLUS_FILETYPE_REG = 2,
+    GRUB_HFSPLUS_FILETYPE_DIR_THREAD = 3,
+    GRUB_HFSPLUS_FILETYPE_REG_THREAD = 4
+  };
+
+#define GRUB_HFSPLUSX_BINARYCOMPARE    0xBC
+#define GRUB_HFSPLUSX_CASEFOLDING      0xCF
+
+/* Internal representation of a catalog key.  */
+struct grub_hfsplus_catkey_internal
+{
+  int parent;
+  char *name;
+};
+
+/* Internal representation of an extent overflow key.  */
+struct grub_hfsplus_extkey_internal
+{
+  grub_uint32_t fileid;
+  grub_uint32_t start;
+};
+
+struct grub_hfsplus_key_internal
+{
+  union
+  {
+    struct grub_hfsplus_extkey_internal extkey;
+    struct grub_hfsplus_catkey_internal catkey;
+  };
+};
+
+\f
+
+struct grub_fshelp_node
+{
+  struct grub_hfsplus_data *data;
+  struct grub_hfsplus_extent extents[8];
+  grub_uint64_t size;
+  grub_uint32_t fileid;
+  grub_int32_t mtime;
+};
+
+struct grub_hfsplus_btree
+{
+  grub_uint32_t root;
+  int nodesize;
+
+  /* Catalog file node.  */
+  struct grub_fshelp_node file;
+};
+
+/* Information about a "mounted" HFS+ filesystem.  */
+struct grub_hfsplus_data
+{
+  struct grub_hfsplus_volheader volheader;
+  grub_disk_t disk;
+
+  unsigned int log2blksize;
+
+  struct grub_hfsplus_btree catalog_tree;
+  struct grub_hfsplus_btree extoverflow_tree;
+
+  struct grub_fshelp_node dirroot;
+  struct grub_fshelp_node opened_file;
+
+  /* This is the offset into the physical disk for an embedded HFS+
+     filesystem (one inside a plain HFS wrapper).  */
+  int embedded_offset;
+  int case_sensitive;
+};
+
+static grub_dl_t my_mod;
+
+\f
+/* Return the offset of the record with the index INDEX, in the node
+   NODE which is part of the B+ tree BTREE.  */
+static inline unsigned int
+grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree,
+                          struct grub_hfsplus_btnode *node, int index)
+{
+  char *cnode = (char *) node;
+  grub_uint16_t *recptr;
+  recptr = (grub_uint16_t *) (&cnode[btree->nodesize
+                                    - index * sizeof (grub_uint16_t) - 2]);
+  return grub_be_to_cpu16 (*recptr);
+}
+
+/* Return a pointer to the record with the index INDEX, in the node
+   NODE which is part of the B+ tree BTREE.  */
+static inline struct grub_hfsplus_key *
+grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree,
+                          struct grub_hfsplus_btnode *node, int index)
+{
+  char *cnode = (char *) node;
+  unsigned int offset;
+  offset = grub_hfsplus_btree_recoffset (btree, node, index);
+  return (struct grub_hfsplus_key *) &cnode[offset];
+}
+
+
+/* Find the extent that points to FILEBLOCK.  If it is not in one of
+   the 8 extents described by EXTENT, return -1.  In that case set
+   FILEBLOCK to the next block.  */
+static int
+grub_hfsplus_find_block (struct grub_hfsplus_extent *extent,
+                        int *fileblock)
+{
+  int i;
+  grub_size_t blksleft = *fileblock;
+
+  /* First lookup the file in the given extents.  */
+  for (i = 0; i < 8; i++)
+    {
+      if (blksleft < grub_be_to_cpu32 (extent[i].count))
+       return grub_be_to_cpu32 (extent[i].start) + blksleft;
+      blksleft -= grub_be_to_cpu32 (extent[i].count);
+    }
+
+  *fileblock = blksleft;
+  return -1;
+}
+
+static grub_err_t
+grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
+                          struct grub_hfsplus_key_internal *key,
+                          int (*compare_keys) (struct grub_hfsplus_key *keya,
+                                               struct grub_hfsplus_key_internal *keyb),
+                          struct grub_hfsplus_btnode **matchnode, int *keyoffset);
+
+static int grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya,
+                                   struct grub_hfsplus_key_internal *keyb);
+
+/* Search for the block FILEBLOCK inside the file NODE.  Return the
+   blocknumber of this block on disk.  */
+static grub_disk_addr_t
+grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+{
+  struct grub_hfsplus_btnode *nnode = 0;
+  int blksleft = fileblock;
+  struct grub_hfsplus_extent *extents = &node->extents[0];
+
+  while (1)
+    {
+      struct grub_hfsplus_extkey *key;
+      struct grub_hfsplus_extkey_internal extoverflow;
+      int blk;
+      int ptr;
+
+      /* Try to find this block in the current set of extents.  */
+      blk = grub_hfsplus_find_block (extents, &blksleft);
+
+      /* The previous iteration of this loop allocated memory.  The
+        code above used this memory, it can be freed now.  */
+      grub_free (nnode);
+      nnode = 0;
+
+      if (blk != -1)
+       return (blk
+               + (node->data->embedded_offset >> (node->data->log2blksize
+                                                  - GRUB_DISK_SECTOR_BITS)));
+
+      /* For the extent overflow file, extra extents can't be found in
+        the extent overflow file.  If this happens, you found a
+        bug...  */
+      if (node->fileid == GRUB_HFSPLUS_FILEID_OVERFLOW)
+       {
+         grub_error (GRUB_ERR_READ_ERROR,
+                     "extra extents found in an extend overflow file");
+         break;
+       }
+
+      /* Set up the key to look for in the extent overflow file.  */
+      extoverflow.fileid = node->fileid;
+      extoverflow.start = fileblock - blksleft;
+
+      if (grub_hfsplus_btree_search (&node->data->extoverflow_tree,
+                                    (struct grub_hfsplus_key_internal *) &extoverflow,
+                                    grub_hfsplus_cmp_extkey, &nnode, &ptr))
+       {
+         grub_error (GRUB_ERR_READ_ERROR,
+                     "no block found for the file id 0x%x and the block offset 0x%x",
+                     node->fileid, fileblock);
+         break;
+       }
+
+      /* The extent overflow file has 8 extents right after the key.  */
+      key = (struct grub_hfsplus_extkey *)
+       grub_hfsplus_btree_recptr (&node->data->extoverflow_tree, nnode, ptr);
+      extents = (struct grub_hfsplus_extent *) (key + 1);
+
+      /* The block wasn't found.  Perhaps the next iteration will find
+        it.  The last block we found is stored in BLKSLEFT now.  */
+    }
+
+  grub_free (nnode);
+
+  /* Too bad, you lose.  */
+  return -1;
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_hfsplus_read_file (grub_fshelp_node_t node,
+                       void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                          unsigned offset, unsigned length),
+                       int pos, grub_size_t len, char *buf)
+{
+  return grub_fshelp_read_file (node->data->disk, node, read_hook,
+                               pos, len, buf, grub_hfsplus_read_block,
+                               node->size,
+                               node->data->log2blksize - GRUB_DISK_SECTOR_BITS);
+}
+
+static struct grub_hfsplus_data *
+grub_hfsplus_mount (grub_disk_t disk)
+{
+  struct grub_hfsplus_data *data;
+  struct grub_hfsplus_btheader header;
+  struct grub_hfsplus_btnode node;
+  grub_uint16_t magic;
+  union {
+    struct grub_hfs_sblock hfs;
+    struct grub_hfsplus_volheader hfsplus;
+  } volheader;
+
+  data = grub_malloc (sizeof (*data));
+  if (!data)
+    return 0;
+
+  data->disk = disk;
+
+  /* Read the bootblock.  */
+  grub_disk_read (disk, GRUB_HFSPLUS_SBLOCK, 0, sizeof (volheader),
+                 &volheader);
+  if (grub_errno)
+    goto fail;
+
+  data->embedded_offset = 0;
+  if (grub_be_to_cpu16 (volheader.hfs.magic) == GRUB_HFS_MAGIC)
+    {
+      int extent_start;
+      int ablk_size;
+      int ablk_start;
+
+      /* See if there's an embedded HFS+ filesystem.  */
+      if (grub_be_to_cpu16 (volheader.hfs.embed_sig) != GRUB_HFSPLUS_MAGIC)
+       {
+         grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem");
+         goto fail;
+       }
+
+      /* Calculate the offset needed to translate HFS+ sector numbers.  */
+      extent_start = grub_be_to_cpu16 (volheader.hfs.embed_extent.first_block);
+      ablk_size = grub_be_to_cpu32 (volheader.hfs.blksz);
+      ablk_start = grub_be_to_cpu16 (volheader.hfs.first_block);
+      data->embedded_offset = (ablk_start
+                              + extent_start
+                              * (ablk_size >> GRUB_DISK_SECTOR_BITS));
+
+      grub_disk_read (disk, data->embedded_offset + GRUB_HFSPLUS_SBLOCK, 0,
+                     sizeof (volheader), &volheader);
+      if (grub_errno)
+       goto fail;
+    }
+
+  /* Make sure this is an HFS+ filesystem.  XXX: Do we really support
+     HFX?  */
+  magic = grub_be_to_cpu16 (volheader.hfsplus.magic);
+  if ((magic != GRUB_HFSPLUS_MAGIC) && (magic != GRUB_HFSPLUSX_MAGIC))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem");
+      goto fail;
+    }
+
+  grub_memcpy (&data->volheader, &volheader.hfsplus,
+      sizeof (volheader.hfsplus));
+
+  if (grub_fshelp_log2blksize (grub_be_to_cpu32 (data->volheader.blksize),
+                              &data->log2blksize))
+    goto fail;
+
+  /* Make a new node for the catalog tree.  */
+  data->catalog_tree.file.data = data;
+  data->catalog_tree.file.fileid = GRUB_HFSPLUS_FILEID_CATALOG;
+  grub_memcpy (&data->catalog_tree.file.extents,
+              data->volheader.catalog_file.extents,
+              sizeof data->volheader.catalog_file.extents);
+  data->catalog_tree.file.size =
+    grub_be_to_cpu64 (data->volheader.catalog_file.size);
+
+  /* Make a new node for the extent overflow file.  */
+  data->extoverflow_tree.file.data = data;
+  data->extoverflow_tree.file.fileid = GRUB_HFSPLUS_FILEID_OVERFLOW;
+  grub_memcpy (&data->extoverflow_tree.file.extents,
+              data->volheader.extents_file.extents,
+              sizeof data->volheader.catalog_file.extents);
+
+  data->extoverflow_tree.file.size =
+    grub_be_to_cpu64 (data->volheader.extents_file.size);
+
+  /* Read the essential information about the trees.  */
+  if (grub_hfsplus_read_file (&data->catalog_tree.file, 0,
+                             sizeof (struct grub_hfsplus_btnode),
+                             sizeof (header), (char *) &header) <= 0)
+    goto fail;
+
+  data->catalog_tree.root = grub_be_to_cpu32 (header.root);
+  data->catalog_tree.nodesize = grub_be_to_cpu16 (header.nodesize);
+  data->case_sensitive = ((magic == GRUB_HFSPLUSX_MAGIC) &&
+                         (header.key_compare == GRUB_HFSPLUSX_BINARYCOMPARE));
+
+  if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0,
+                             sizeof (struct grub_hfsplus_btnode),
+                             sizeof (header), (char *) &header) <= 0)
+    goto fail;
+
+  data->extoverflow_tree.root = grub_be_to_cpu32 (header.root);
+
+  if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0,
+                             sizeof (node), (char *) &node) <= 0)
+    goto fail;
+
+  data->extoverflow_tree.root = grub_be_to_cpu32 (header.root);
+  data->extoverflow_tree.nodesize = grub_be_to_cpu16 (header.nodesize);
+
+  data->dirroot.data = data;
+  data->dirroot.fileid = GRUB_HFSPLUS_FILEID_ROOTDIR;
+
+  return data;
+
+ fail:
+
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem");
+
+  grub_free (data);
+  return 0;
+}
+
+/* Compare the on disk catalog key KEYA with the catalog key we are
+   looking for (KEYB).  */
+static int
+grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya,
+                        struct grub_hfsplus_key_internal *keyb)
+{
+  struct grub_hfsplus_catkey *catkey_a = &keya->catkey;
+  struct grub_hfsplus_catkey_internal *catkey_b = &keyb->catkey;
+  char *filename;
+  int i;
+  int diff;
+
+  diff = grub_be_to_cpu32 (catkey_a->parent) - catkey_b->parent;
+  if (diff)
+    return diff;
+
+  /* Change the filename in keya so the endianness is correct.  */
+  for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++)
+    catkey_a->name[i] = grub_be_to_cpu16 (catkey_a->name[i]);
+
+  filename = grub_malloc (grub_be_to_cpu16 (catkey_a->namelen) + 1);
+
+  if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey_a->name,
+                           grub_be_to_cpu16 (catkey_a->namelen)))
+    return -1; /* XXX: This error never occurs, but in case it happens
+                 just skip this entry.  */
+
+  diff = grub_strncmp (filename, catkey_b->name,
+                      grub_be_to_cpu16 (catkey_a->namelen));
+
+  grub_free (filename);
+
+  /* The endianness was changed to host format, change it back to
+     whatever it was.  */
+  for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++)
+    catkey_a->name[i] = grub_cpu_to_be16 (catkey_a->name[i]);
+  return diff;
+}
+
+/* Compare the on disk extent overflow key KEYA with the extent
+   overflow key we are looking for (KEYB).  */
+static int
+grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya,
+                        struct grub_hfsplus_key_internal *keyb)
+{
+  struct grub_hfsplus_extkey *extkey_a = &keya->extkey;
+  struct grub_hfsplus_extkey_internal *extkey_b = &keyb->extkey;
+  int diff;
+
+  diff = grub_be_to_cpu32 (extkey_a->fileid) - extkey_b->fileid;
+
+  if (diff)
+    return diff;
+
+  diff = grub_be_to_cpu32 (extkey_a->start) - extkey_b->start;
+  return diff;
+}
+
+static char *
+grub_hfsplus_read_symlink (grub_fshelp_node_t node)
+{
+  char *symlink;
+  grub_ssize_t numread;
+
+  symlink = grub_malloc (node->size + 1);
+  if (!symlink)
+    return 0;
+
+  numread = grub_hfsplus_read_file (node, 0, 0, node->size, symlink);
+  if (numread != (grub_ssize_t) node->size)
+    {
+      grub_free (symlink);
+      return 0;
+    }
+  symlink[node->size] = '\0';
+
+  return symlink;
+}
+
+static int
+grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree,
+                                struct grub_hfsplus_btnode *first_node,
+                                int first_rec,
+                                int (*hook) (void *record))
+{
+  int rec;
+
+  for (;;)
+    {
+      char *cnode = (char *) first_node;
+
+      /* Iterate over all records in this node.  */
+      for (rec = first_rec; rec < grub_be_to_cpu16 (first_node->count); rec++)
+       {
+         if (hook (grub_hfsplus_btree_recptr (btree, first_node, rec)))
+           return 1;
+       }
+
+      if (! first_node->next)
+       break;
+
+      if (grub_hfsplus_read_file (&btree->file, 0,
+                                 (grub_be_to_cpu32 (first_node->next)
+                                  * btree->nodesize),
+                                 btree->nodesize, cnode) <= 0)
+       return 1;
+
+      /* Don't skip any record in the next iteration.  */
+      first_rec = 0;
+    }
+
+  return 0;
+}
+
+/* Lookup the node described by KEY in the B+ Tree BTREE.  Compare
+   keys using the function COMPARE_KEYS.  When a match is found,
+   return the node in MATCHNODE and a pointer to the data in this node
+   in KEYOFFSET.  MATCHNODE should be freed by the caller.  */
+static grub_err_t
+grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
+                          struct grub_hfsplus_key_internal *key,
+                          int (*compare_keys) (struct grub_hfsplus_key *keya,
+                                               struct grub_hfsplus_key_internal *keyb),
+                          struct grub_hfsplus_btnode **matchnode, int *keyoffset)
+{
+  grub_uint64_t currnode;
+  char *node;
+  struct grub_hfsplus_btnode *nodedesc;
+  int rec;
+
+  node = grub_malloc (btree->nodesize);
+  if (! node)
+    return grub_errno;
+
+  currnode = btree->root;
+  while (1)
+    {
+      int match = 0;
+
+      /* Read a node.  */
+      if (grub_hfsplus_read_file (&btree->file, 0,
+                                 (long)currnode * (long)btree->nodesize,
+                                 btree->nodesize, (char *) node) <= 0)
+       {
+         grub_free (node);
+         return grub_error (GRUB_ERR_BAD_FS, "couldn't read i-node");
+       }
+
+      nodedesc = (struct grub_hfsplus_btnode *) node;
+
+      /* Find the record in this tree.  */
+      for (rec = 0; rec < grub_be_to_cpu16 (nodedesc->count); rec++)
+       {
+         struct grub_hfsplus_key *currkey;
+         currkey = grub_hfsplus_btree_recptr (btree, nodedesc, rec);
+
+         /* The action that has to be taken depend on the type of
+            record.  */
+         if (nodedesc->type == GRUB_HFSPLUS_BTNODE_TYPE_LEAF
+             && compare_keys (currkey, key) == 0)
+           {
+             /* An exact match was found!  */
+
+             *matchnode = nodedesc;
+             *keyoffset = rec;
+
+             return 0;
+           }
+         else if (nodedesc->type == GRUB_HFSPLUS_BTNODE_TYPE_INDEX)
+           {
+             grub_uint32_t *pointer;
+
+             /* The place where the key could have been found didn't
+                contain the key.  This means that the previous match
+                is the one that should be followed.  */
+             if (compare_keys (currkey, key) > 0)
+               break;
+
+             /* Mark the last key which is lower or equal to the key
+                that we are looking for.  The last match that is
+                found will be used to locate the child which can
+                contain the record.  */
+             pointer = (grub_uint32_t *) ((char *) currkey
+                                          + grub_be_to_cpu16 (currkey->keylen)
+                                          + 2);
+             currnode = grub_be_to_cpu32 (*pointer);
+             match = 1;
+           }
+       }
+
+      /* No match is found, no record with this key exists in the
+        tree.  */
+      if (! match)
+       {
+         *matchnode = 0;
+         grub_free (node);
+         return 1;
+       }
+    }
+}
+
+static int
+grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
+                         int NESTED_FUNC_ATTR
+                         (*hook) (const char *filename,
+                                  enum grub_fshelp_filetype filetype,
+                                  grub_fshelp_node_t node))
+{
+  int ret = 0;
+
+  auto int list_nodes (void *record);
+  int list_nodes (void *record)
+    {
+      struct grub_hfsplus_catkey *catkey;
+      char *filename;
+      int i;
+      struct grub_fshelp_node *node;
+      struct grub_hfsplus_catfile *fileinfo;
+      enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN;
+
+      catkey = (struct grub_hfsplus_catkey *) record;
+
+      fileinfo =
+       (struct grub_hfsplus_catfile *) ((char *) record
+                                        + grub_be_to_cpu16 (catkey->keylen)
+                                        + 2 + (grub_be_to_cpu16(catkey->keylen)
+                                               % 2));
+
+      /* Stop iterating when the last directory entry is found.  */
+      if (grub_be_to_cpu32 (catkey->parent) != dir->fileid)
+       return 1;
+
+      /* Determine the type of the node that is found.  */
+      if (grub_be_to_cpu16 (fileinfo->type) == GRUB_HFSPLUS_FILETYPE_REG)
+       {
+         int mode = (grub_be_to_cpu16 (fileinfo->mode)
+                     & GRUB_HFSPLUS_FILEMODE_MASK);
+
+         if (mode == GRUB_HFSPLUS_FILEMODE_REG)
+           type = GRUB_FSHELP_REG;
+         else if (mode == GRUB_HFSPLUS_FILEMODE_SYMLINK)
+           type = GRUB_FSHELP_SYMLINK;
+         else
+           type = GRUB_FSHELP_UNKNOWN;
+       }
+      else if (grub_be_to_cpu16 (fileinfo->type) == GRUB_HFSPLUS_FILETYPE_DIR)
+       type = GRUB_FSHELP_DIR;
+
+      if (type == GRUB_FSHELP_UNKNOWN)
+       return 0;
+
+      /* Make sure the byte order of the UTF16 string is correct.  */
+      for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++)
+       {
+         catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]);
+
+         /* If the name is obviously invalid, skip this node.  */
+         if (catkey->name[i] == 0)
+           return 0;
+       }
+
+      filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen) + 1);
+      if (! filename)
+       return 0;
+
+      if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name,
+                               grub_be_to_cpu16 (catkey->namelen)))
+       {
+         grub_free (filename);
+         return 0;
+       }
+
+      filename[grub_be_to_cpu16 (catkey->namelen)] = '\0';
+
+      /* Restore the byte order to what it was previously.  */
+      for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++)
+       catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]);
+
+      /* hfs+ is case insensitive.  */
+      if (! dir->data->case_sensitive)
+       type |= GRUB_FSHELP_CASE_INSENSITIVE;
+
+      /* Only accept valid nodes.  */
+      if (grub_strlen (filename) == grub_be_to_cpu16 (catkey->namelen))
+       {
+         /* A valid node is found; setup the node and call the
+            callback function.  */
+         node = grub_malloc (sizeof (*node));
+         node->data = dir->data;
+
+         grub_memcpy (node->extents, fileinfo->data.extents,
+                      sizeof (node->extents));
+         node->mtime = grub_be_to_cpu32 (fileinfo->mtime) - 2082844800;
+         node->size = grub_be_to_cpu64 (fileinfo->data.size);
+         node->fileid = grub_be_to_cpu32 (fileinfo->fileid);
+
+         ret = hook (filename, type, node);
+       }
+
+      grub_free (filename);
+
+      return ret;
+    }
+
+  struct grub_hfsplus_key_internal intern;
+  struct grub_hfsplus_btnode *node;
+  int ptr;
+
+  /* Create a key that points to the first entry in the directory.  */
+  intern.catkey.parent = dir->fileid;
+  intern.catkey.name = "";
+
+  /* First lookup the first entry.  */
+  if (grub_hfsplus_btree_search (&dir->data->catalog_tree, &intern,
+                                grub_hfsplus_cmp_catkey, &node, &ptr))
+    return 0;
+
+  /* Iterate over all entries in this directory.  */
+  grub_hfsplus_btree_iterate_node (&dir->data->catalog_tree, node, ptr,
+                                  list_nodes);
+
+  grub_free (node);
+
+  return ret;
+}
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_hfsplus_open (struct grub_file *file, const char *name)
+{
+  struct grub_hfsplus_data *data;
+  struct grub_fshelp_node *fdiro = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_hfsplus_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (name, &data->dirroot, &fdiro,
+                        grub_hfsplus_iterate_dir,
+                        grub_hfsplus_read_symlink, GRUB_FSHELP_REG);
+  if (grub_errno)
+    goto fail;
+
+  file->size = fdiro->size;
+  data->opened_file = *fdiro;
+  grub_free (fdiro);
+
+  file->data = data;
+  file->offset = 0;
+
+  return 0;
+
+ fail:
+  if (data && fdiro != &data->dirroot)
+    grub_free (fdiro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_hfsplus_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+
+/* Read LEN bytes data from FILE into BUF.  */
+static grub_ssize_t
+grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_hfsplus_data *data =
+    (struct grub_hfsplus_data *) file->data;
+
+  int size = grub_hfsplus_read_file (&data->opened_file, file->read_hook,
+                                    file->offset, len, buf);
+
+  return size;
+}
+
+
+static grub_err_t
+grub_hfsplus_dir (grub_device_t device, const char *path,
+                 int (*hook) (const char *filename,
+                              const struct grub_dirhook_info *info))
+{
+  struct grub_hfsplus_data *data = 0;
+  struct grub_fshelp_node *fdiro = 0;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+                                    enum grub_fshelp_filetype filetype,
+                                    grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      info.mtimeset = 1;
+      info.mtime = node->mtime;
+      info.case_insensitive = !! (filetype & GRUB_FSHELP_CASE_INSENSITIVE);
+      grub_free (node);
+      return hook (filename, &info);
+    }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_hfsplus_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  /* Find the directory that should be opened.  */
+  grub_fshelp_find_file (path, &data->dirroot, &fdiro,
+                        grub_hfsplus_iterate_dir,
+                        grub_hfsplus_read_symlink, GRUB_FSHELP_DIR);
+  if (grub_errno)
+    goto fail;
+
+  /* Iterate over all entries in this directory.  */
+  grub_hfsplus_iterate_dir (fdiro, iterate);
+
+ fail:
+  if (data && fdiro != &data->dirroot)
+    grub_free (fdiro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_hfsplus_label (grub_device_t device __attribute__((unused))
+                   , char **label __attribute__((unused)))
+{
+  /* XXX: It's not documented how to read a label.  */
+  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                    "reading the label of a HFS+ "
+                    "partition is not implemented");
+}
+
+/* Get mtime.  */
+static grub_err_t
+grub_hfsplus_mtime (grub_device_t device, grub_int32_t *tm)
+{
+  struct grub_hfsplus_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_hfsplus_mount (disk);
+  if (!data)
+    *tm = 0;
+  else
+    *tm = grub_be_to_cpu32 (data->volheader.utime) - 2082844800;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+
+}
+
+static grub_err_t
+grub_hfsplus_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_hfsplus_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_hfsplus_mount (disk);
+  if (data)
+    {
+      *uuid = grub_xasprintf ("%016llx",
+                            (unsigned long long)
+                            grub_be_to_cpu64 (data->volheader.num_serial));
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+\f
+static struct grub_fs grub_hfsplus_fs =
+  {
+    .name = "hfsplus",
+    .dir = grub_hfsplus_dir,
+    .open = grub_hfsplus_open,
+    .read = grub_hfsplus_read,
+    .close = grub_hfsplus_close,
+    .label = grub_hfsplus_label,
+    .mtime = grub_hfsplus_mtime,
+    .uuid = grub_hfsplus_uuid,
+#ifdef GRUB_UTIL
+    .reserved_first_sector = 1,
+#endif
+    .next = 0
+  };
+
+GRUB_MOD_INIT(hfsplus)
+{
+  grub_fs_register (&grub_hfsplus_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(hfsplus)
+{
+  grub_fs_unregister (&grub_hfsplus_fs);
+}
diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c
new file mode 100644 (file)
index 0000000..82d8ee5
--- /dev/null
@@ -0,0 +1,595 @@
+/* pxe.c - Driver to provide access to the pxe filesystem  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/fs.h>
+#include <grub/mm.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/misc.h>
+#include <grub/bufio.h>
+#include <grub/env.h>
+
+#include <grub/machine/pxe.h>
+#include <grub/machine/memory.h>
+
+#define SEGMENT(x)     ((x) >> 4)
+#define OFFSET(x)      ((x) & 0xF)
+#define SEGOFS(x)      ((SEGMENT(x) << 16) + OFFSET(x))
+#define LINEAR(x)      (void *) (((x >> 16) <<4) + (x & 0xFFFF))
+
+struct grub_pxe_disk_data
+{
+  grub_uint32_t server_ip;
+  grub_uint32_t gateway_ip;
+};
+
+struct grub_pxenv *grub_pxe_pxenv;
+static grub_uint32_t grub_pxe_your_ip;
+static grub_uint32_t grub_pxe_default_server_ip;
+static grub_uint32_t grub_pxe_default_gateway_ip;
+static unsigned grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE;
+
+static grub_file_t curr_file = 0;
+
+struct grub_pxe_data
+{
+  grub_uint32_t packet_number;
+  grub_uint32_t block_size;
+  char filename[0];
+};
+
+static int
+grub_pxe_iterate (int (*hook) (const char *name))
+{
+  if (hook ("pxe"))
+    return 1;
+  return 0;
+}
+
+static grub_err_t
+parse_ip (const char *val, grub_uint32_t *ip, const char **rest)
+{
+  grub_uint32_t newip = 0;
+  unsigned long t;
+  int i;
+  const char *ptr = val;
+
+  for (i = 0; i < 4; i++)
+    {
+      t = grub_strtoul (ptr, (char **) &ptr, 0);
+      if (grub_errno)
+       return grub_errno;
+      if (t & ~0xff)
+       return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
+      newip >>= 8;
+      newip |= (t << 24);
+      if (i != 3 && *ptr != '.')
+       return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
+      ptr++;
+    }
+  *ip = newip;
+  if (rest)
+    *rest = ptr - 1;
+  return 0;
+}
+
+static grub_err_t
+grub_pxe_open (const char *name, grub_disk_t disk)
+{
+  struct grub_pxe_disk_data *data;
+
+  if (grub_strcmp (name, "pxe") != 0
+      && grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) != 0)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a pxe disk");
+
+  data = grub_malloc (sizeof (*data));
+  if (!data)
+    return grub_errno;
+
+  if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0)
+    {
+      const char *ptr;
+      grub_err_t err;
+
+      ptr = name + sizeof ("pxe:") - 1;
+      err = parse_ip (ptr, &(data->server_ip), &ptr);
+      if (err)
+       return err;
+      if (*ptr == ':')
+       {
+         err = parse_ip (ptr + 1, &(data->server_ip), 0);
+         if (err)
+           return err;
+       }
+      else
+       data->gateway_ip = grub_pxe_default_gateway_ip;
+    }
+  else
+    {
+      data->server_ip = grub_pxe_default_server_ip;
+      data->gateway_ip = grub_pxe_default_gateway_ip;
+    }
+
+  disk->total_sectors = 0;
+  disk->id = (unsigned long) data;
+
+  disk->has_partitions = 0;
+  disk->data = data;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_pxe_close (grub_disk_t disk)
+{
+  grub_free (disk->data);
+}
+
+static grub_err_t
+grub_pxe_read (grub_disk_t disk __attribute((unused)),
+               grub_disk_addr_t sector __attribute((unused)),
+               grub_size_t size __attribute((unused)),
+               char *buf __attribute((unused)))
+{
+  return GRUB_ERR_OUT_OF_RANGE;
+}
+
+static grub_err_t
+grub_pxe_write (grub_disk_t disk __attribute((unused)),
+                grub_disk_addr_t sector __attribute((unused)),
+                grub_size_t size __attribute((unused)),
+                const char *buf __attribute((unused)))
+{
+  return GRUB_ERR_OUT_OF_RANGE;
+}
+
+static struct grub_disk_dev grub_pxe_dev =
+  {
+    .name = "pxe",
+    .id = GRUB_DISK_DEVICE_PXE_ID,
+    .iterate = grub_pxe_iterate,
+    .open = grub_pxe_open,
+    .close = grub_pxe_close,
+    .read = grub_pxe_read,
+    .write = grub_pxe_write,
+    .next = 0
+  };
+
+static grub_err_t
+grub_pxefs_dir (grub_device_t device,
+               const char *path  __attribute__ ((unused)),
+               int (*hook) (const char *filename,
+                            const struct grub_dirhook_info *info)
+               __attribute__ ((unused)))
+{
+  if (device->disk->dev->id != GRUB_DISK_DEVICE_PXE_ID)
+    return grub_error (GRUB_ERR_IO, "not a pxe disk");
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_pxefs_open (struct grub_file *file, const char *name)
+{
+  union
+    {
+      struct grub_pxenv_tftp_get_fsize c1;
+      struct grub_pxenv_tftp_open c2;
+    } c;
+  struct grub_pxe_data *data;
+  struct grub_pxe_disk_data *disk_data = file->device->disk->data;
+  grub_file_t file_int, bufio;
+
+  if (file->device->disk->dev->id != GRUB_DISK_DEVICE_PXE_ID)
+    return grub_error (GRUB_ERR_IO, "not a pxe disk");
+
+  if (curr_file != 0)
+    {
+      grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c.c2);
+      curr_file = 0;
+    }
+
+  c.c1.server_ip = disk_data->server_ip;
+  c.c1.gateway_ip = disk_data->gateway_ip;
+  grub_strcpy ((char *)&c.c1.filename[0], name);
+  grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1);
+  if (c.c1.status)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+
+  file->size = c.c1.file_size;
+
+  c.c2.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
+  c.c2.packet_size = grub_pxe_blksize;
+  grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &c.c2);
+  if (c.c2.status)
+    return grub_error (GRUB_ERR_BAD_FS, "open fails");
+
+  data = grub_zalloc (sizeof (struct grub_pxe_data) + grub_strlen (name) + 1);
+  if (! data)
+    return grub_errno;
+
+  data->block_size = c.c2.packet_size;
+  grub_strcpy (data->filename, name);
+
+  file_int = grub_malloc (sizeof (*file_int));
+  if (! file_int)
+    {
+      grub_free (data);
+      return grub_errno;
+    }
+
+  file->data = data;
+  grub_memcpy (file_int, file, sizeof (struct grub_file));
+  curr_file = file_int;
+
+  bufio = grub_bufio_open (file_int, data->block_size);
+  if (! bufio)
+    {
+      grub_free (file_int);
+      grub_free (data);
+      return grub_errno;
+    }
+
+  grub_memcpy (file, bufio, sizeof (struct grub_file));
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_ssize_t
+grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_pxenv_tftp_read c;
+  struct grub_pxe_data *data;
+  struct grub_pxe_disk_data *disk_data = file->device->disk->data;
+  grub_uint32_t pn, r;
+
+  data = file->data;
+
+  pn = grub_divmod64 (file->offset, data->block_size, &r);
+  if (r)
+    {
+      grub_error (GRUB_ERR_BAD_FS,
+                 "read access must be aligned to packet size");
+      return -1;
+    }
+
+  if ((curr_file != file) || (data->packet_number > pn))
+    {
+      struct grub_pxenv_tftp_open o;
+
+      if (curr_file != 0)
+        grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o);
+
+      o.server_ip = disk_data->server_ip;
+      o.gateway_ip = disk_data->gateway_ip;
+      grub_strcpy ((char *)&o.filename[0], data->filename);
+      o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
+      o.packet_size = grub_pxe_blksize;
+      grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o);
+      if (o.status)
+       {
+         grub_error (GRUB_ERR_BAD_FS, "open fails");
+         return -1;
+       }
+      data->block_size = o.packet_size;
+      data->packet_number = 0;
+      curr_file = file;
+    }
+
+  c.buffer = SEGOFS (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
+  while (pn >= data->packet_number)
+    {
+      c.buffer_size = data->block_size;
+      grub_pxe_call (GRUB_PXENV_TFTP_READ, &c);
+      if (c.status)
+        {
+          grub_error (GRUB_ERR_BAD_FS, "read fails");
+          return -1;
+        }
+      data->packet_number++;
+    }
+
+  grub_memcpy (buf, (char *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, len);
+
+  return len;
+}
+
+static grub_err_t
+grub_pxefs_close (grub_file_t file)
+{
+  struct grub_pxenv_tftp_close c;
+
+  if (curr_file == file)
+    {
+      grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c);
+      curr_file = 0;
+    }
+
+  grub_free (file->data);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_pxefs_label (grub_device_t device __attribute ((unused)),
+                  char **label __attribute ((unused)))
+{
+  *label = 0;
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_fs grub_pxefs_fs =
+  {
+    .name = "pxefs",
+    .dir = grub_pxefs_dir,
+    .open = grub_pxefs_open,
+    .read = grub_pxefs_read,
+    .close = grub_pxefs_close,
+    .label = grub_pxefs_label,
+    .next = 0
+  };
+
+static char *
+grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)),
+                        const char *val __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static void
+set_mac_env (grub_uint8_t *mac_addr, grub_size_t mac_len)
+{
+  char buf[(sizeof ("XX:") - 1) * mac_len + 1];
+  char *ptr = buf;
+  unsigned i;
+
+  for (i = 0; i < mac_len; i++)
+    {
+      grub_snprintf (ptr, sizeof (buf) - (ptr - buf),
+                    "%02x:", mac_addr[i] & 0xff);
+      ptr += (sizeof ("XX:") - 1);
+    }
+  if (mac_len)
+    *(ptr - 1) = 0;
+  else
+    buf[0] = 0;
+
+  grub_env_set ("net_pxe_mac", buf);
+  /* XXX: Is it possible to change MAC in PXE?  */
+  grub_register_variable_hook ("net_pxe_mac", 0, grub_env_write_readonly);
+}
+
+static void
+set_env_limn_ro (const char *varname, char *value, grub_size_t len)
+{
+  char c;
+  c = value[len];
+  value[len] = 0;
+  grub_env_set (varname, value);
+  value[len] = c;
+  grub_register_variable_hook (varname, 0, grub_env_write_readonly);
+}
+
+static void
+parse_dhcp_vendor (void *vend, int limit)
+{
+  grub_uint8_t *ptr, *ptr0;
+
+  ptr = ptr0 = vend;
+
+  if (grub_be_to_cpu32 (*(grub_uint32_t *) ptr) != 0x63825363)
+    return;
+  ptr = ptr + sizeof (grub_uint32_t);
+  while (ptr - ptr0 < limit)
+    {
+      grub_uint8_t tagtype;
+      grub_uint8_t taglength;
+
+      tagtype = *ptr++;
+
+      /* Pad tag.  */
+      if (tagtype == 0)
+       continue;
+
+      /* End tag.  */
+      if (tagtype == 0xff)
+       return;
+
+      taglength = *ptr++;
+
+      switch (tagtype)
+       {
+       case 12:
+         set_env_limn_ro ("net_pxe_hostname", (char *) ptr, taglength);
+         break;
+
+       case 15:
+         set_env_limn_ro ("net_pxe_domain", (char *) ptr, taglength);
+         break;
+
+       case 17:
+         set_env_limn_ro ("net_pxe_rootpath", (char *) ptr, taglength);
+         break;
+
+       case 18:
+         set_env_limn_ro ("net_pxe_extensionspath", (char *) ptr, taglength);
+         break;
+
+         /* If you need any other options please contact GRUB
+            developpement team.  */
+       }
+
+      ptr += taglength;
+    }
+}
+
+static void
+grub_pxe_detect (void)
+{
+  struct grub_pxenv *pxenv;
+  struct grub_pxenv_get_cached_info ci;
+  struct grub_pxenv_boot_player *bp;
+
+  pxenv = grub_pxe_scan ();
+  if (! pxenv)
+    return;
+
+  ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK;
+  ci.buffer = 0;
+  ci.buffer_size = 0;
+  grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci);
+  if (ci.status)
+    return;
+
+  bp = LINEAR (ci.buffer);
+
+  grub_pxe_your_ip = bp->your_ip;
+  grub_pxe_default_server_ip = bp->server_ip;
+  grub_pxe_default_gateway_ip = bp->gateway_ip;
+  set_mac_env (bp->mac_addr, bp->hw_len < sizeof (bp->mac_addr) ? bp->hw_len
+              : sizeof (bp->mac_addr));
+  set_env_limn_ro ("net_pxe_boot_file", (char *) bp->boot_file,
+                  sizeof (bp->boot_file));
+  set_env_limn_ro ("net_pxe_dhcp_server_name", (char *) bp->server_name,
+                  sizeof (bp->server_name));
+  parse_dhcp_vendor (&bp->vendor, sizeof (bp->vendor));
+  grub_pxe_pxenv = pxenv;
+}
+
+void
+grub_pxe_unload (void)
+{
+  if (grub_pxe_pxenv)
+    {
+      grub_fs_unregister (&grub_pxefs_fs);
+      grub_disk_dev_unregister (&grub_pxe_dev);
+
+      grub_pxe_pxenv = 0;
+    }
+}
+
+static void
+set_ip_env (char *varname, grub_uint32_t ip)
+{
+  char buf[sizeof ("XXX.XXX.XXX.XXX")];
+
+  grub_snprintf (buf, sizeof (buf), "%d.%d.%d.%d", (ip & 0xff),
+                (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff);
+  grub_env_set (varname, buf);
+}
+
+static char *
+write_ip_env (grub_uint32_t *ip, const char *val)
+{
+  char *buf;
+  grub_err_t err;
+  grub_uint32_t newip;
+  
+  err = parse_ip (val, &newip, 0);
+  if (err)
+    return 0;
+
+  /* Normalize the IP.  */
+  buf = grub_xasprintf ("%d.%d.%d.%d", (newip & 0xff), (newip >> 8) & 0xff,
+                      (newip >> 16) & 0xff, (newip >> 24) & 0xff);
+  if (!buf)
+    return 0;
+
+  *ip = newip;
+
+  return buf; 
+}
+
+static char *
+grub_env_write_pxe_default_server (struct grub_env_var *var 
+                                  __attribute__ ((unused)),
+                                  const char *val)
+{
+  return write_ip_env (&grub_pxe_default_server_ip, val);
+}
+
+static char *
+grub_env_write_pxe_default_gateway (struct grub_env_var *var
+                                   __attribute__ ((unused)),
+                                   const char *val)
+{
+  return write_ip_env (&grub_pxe_default_gateway_ip, val);
+}
+
+static char *
+grub_env_write_pxe_blocksize (struct grub_env_var *var __attribute__ ((unused)),
+                             const char *val)
+{
+  unsigned size;
+  char *buf;
+
+  size = grub_strtoul (val, 0, 0);
+  if (grub_errno)
+    return 0;
+
+  if (size < GRUB_PXE_MIN_BLKSIZE)
+    size = GRUB_PXE_MIN_BLKSIZE;
+  else if (size > GRUB_PXE_MAX_BLKSIZE)
+    size = GRUB_PXE_MAX_BLKSIZE;
+  
+  buf = grub_xasprintf ("%d", size);
+  if (!buf)
+    return 0;
+
+  grub_pxe_blksize = size;
+  
+  return buf;
+}
+
+
+GRUB_MOD_INIT(pxe)
+{
+  grub_pxe_detect ();
+  if (grub_pxe_pxenv)
+    {
+      char *buf;
+
+      buf = grub_xasprintf ("%d", grub_pxe_blksize);
+      if (buf)
+       grub_env_set ("pxe_blksize", buf);
+      grub_free (buf);
+
+      set_ip_env ("pxe_default_server", grub_pxe_default_server_ip);
+      set_ip_env ("pxe_default_gateway", grub_pxe_default_gateway_ip);
+      set_ip_env ("net_pxe_ip", grub_pxe_your_ip);
+      grub_register_variable_hook ("pxe_default_server", 0,
+                                  grub_env_write_pxe_default_server);
+      grub_register_variable_hook ("pxe_default_gateway", 0,
+                                  grub_env_write_pxe_default_gateway);
+
+      /* XXX: Is it possible to change IP in PXE?  */
+      grub_register_variable_hook ("net_pxe_ip", 0,
+                                  grub_env_write_readonly);
+      grub_register_variable_hook ("pxe_blksize", 0,
+                                  grub_env_write_pxe_blocksize);
+      grub_disk_dev_register (&grub_pxe_dev);
+      grub_fs_register (&grub_pxefs_fs);
+    }
+}
+
+GRUB_MOD_FINI(pxe)
+{
+  grub_pxe_unload ();
+}
diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
new file mode 100644 (file)
index 0000000..6dc465f
--- /dev/null
@@ -0,0 +1,897 @@
+/* iso9660.c - iso9660 implementation with extensions:
+   SUSP, Rock Ridge.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+#include <grub/charset.h>
+
+#define GRUB_ISO9660_FSTYPE_DIR                0040000
+#define GRUB_ISO9660_FSTYPE_REG                0100000
+#define GRUB_ISO9660_FSTYPE_SYMLINK    0120000
+#define GRUB_ISO9660_FSTYPE_MASK       0170000
+
+#define GRUB_ISO9660_LOG2_BLKSZ                2
+#define GRUB_ISO9660_BLKSZ             2048
+
+#define GRUB_ISO9660_RR_DOT            2
+#define GRUB_ISO9660_RR_DOTDOT         4
+
+#define GRUB_ISO9660_VOLDESC_BOOT      0
+#define GRUB_ISO9660_VOLDESC_PRIMARY   1
+#define GRUB_ISO9660_VOLDESC_SUPP      2
+#define GRUB_ISO9660_VOLDESC_PART      3
+#define GRUB_ISO9660_VOLDESC_END       255
+
+/* The head of a volume descriptor.  */
+struct grub_iso9660_voldesc
+{
+  grub_uint8_t type;
+  grub_uint8_t magic[5];
+  grub_uint8_t version;
+} __attribute__ ((packed));
+
+/* A directory entry.  */
+struct grub_iso9660_dir
+{
+  grub_uint8_t len;
+  grub_uint8_t ext_sectors;
+  grub_uint32_t first_sector;
+  grub_uint32_t first_sector_be;
+  grub_uint32_t size;
+  grub_uint32_t size_be;
+  grub_uint8_t unused1[7];
+  grub_uint8_t flags;
+  grub_uint8_t unused2[6];
+  grub_uint8_t namelen;
+} __attribute__ ((packed));
+
+struct grub_iso9660_date
+{
+  grub_uint8_t year[4];
+  grub_uint8_t month[2];
+  grub_uint8_t day[2];
+  grub_uint8_t hour[2];
+  grub_uint8_t minute[2];
+  grub_uint8_t second[2];
+  grub_uint8_t hundredth[2];
+  grub_uint8_t offset;
+} __attribute__ ((packed));
+
+/* The primary volume descriptor.  Only little endian is used.  */
+struct grub_iso9660_primary_voldesc
+{
+  struct grub_iso9660_voldesc voldesc;
+  grub_uint8_t unused1[33];
+  grub_uint8_t volname[32];
+  grub_uint8_t unused2[16];
+  grub_uint8_t escape[32];
+  grub_uint8_t unused3[12];
+  grub_uint32_t path_table_size;
+  grub_uint8_t unused4[4];
+  grub_uint32_t path_table;
+  grub_uint8_t unused5[12];
+  struct grub_iso9660_dir rootdir;
+  grub_uint8_t unused6[624];
+  struct grub_iso9660_date created;
+  struct grub_iso9660_date modified;
+} __attribute__ ((packed));
+
+/* A single entry in the path table.  */
+struct grub_iso9660_path
+{
+  grub_uint8_t len;
+  grub_uint8_t sectors;
+  grub_uint32_t first_sector;
+  grub_uint16_t parentdir;
+  grub_uint8_t name[0];
+} __attribute__ ((packed));
+
+/* An entry in the System Usage area of the directory entry.  */
+struct grub_iso9660_susp_entry
+{
+  grub_uint8_t sig[2];
+  grub_uint8_t len;
+  grub_uint8_t version;
+  grub_uint8_t data[0];
+} __attribute__ ((packed));
+
+/* The CE entry.  This is used to describe the next block where data
+   can be found.  */
+struct grub_iso9660_susp_ce
+{
+  struct grub_iso9660_susp_entry entry;
+  grub_uint32_t blk;
+  grub_uint32_t blk_be;
+  grub_uint32_t off;
+  grub_uint32_t off_be;
+  grub_uint32_t len;
+  grub_uint32_t len_be;
+} __attribute__ ((packed));
+
+struct grub_iso9660_data
+{
+  struct grub_iso9660_primary_voldesc voldesc;
+  grub_disk_t disk;
+  unsigned int first_sector;
+  int rockridge;
+  int susp_skip;
+  int joliet;
+};
+
+struct grub_fshelp_node
+{
+  struct grub_iso9660_data *data;
+  unsigned int size;
+  unsigned int blk;
+  unsigned int dir_blk;
+  unsigned int dir_off;
+};
+
+static grub_dl_t my_mod;
+\f
+
+/* Iterate over the susp entries, starting with block SUA_BLOCK on the
+   offset SUA_POS with a size of SUA_SIZE bytes.  Hook is called for
+   every entry.  */
+static grub_err_t
+grub_iso9660_susp_iterate (struct grub_iso9660_data *data,
+                          int sua_block, int sua_pos, int sua_size,
+                          grub_err_t (*hook)
+                          (struct grub_iso9660_susp_entry *entry))
+{
+  char *sua;
+  struct grub_iso9660_susp_entry *entry;
+
+  auto grub_err_t load_sua (void);
+
+  /* Load a part of the System Usage Area.  */
+  grub_err_t load_sua (void)
+    {
+      sua = grub_malloc (sua_size);
+      if (!sua)
+       return grub_errno;
+
+      if (grub_disk_read (data->disk, sua_block, sua_pos,
+                         sua_size, sua))
+       return grub_errno;
+
+      entry = (struct grub_iso9660_susp_entry *) sua;
+      return 0;
+    }
+
+  if (load_sua ())
+    return grub_errno;
+
+  for (; (char *) entry < (char *) sua + sua_size - 1;
+       entry = (struct grub_iso9660_susp_entry *)
+        ((char *) entry + entry->len))
+    {
+      /* The last entry.  */
+      if (grub_strncmp ((char *) entry->sig, "ST", 2) == 0)
+       break;
+
+      /* Additional entries are stored elsewhere.  */
+      if (grub_strncmp ((char *) entry->sig, "CE", 2) == 0)
+       {
+         struct grub_iso9660_susp_ce *ce;
+
+         ce = (struct grub_iso9660_susp_ce *) entry;
+         sua_size = grub_le_to_cpu32 (ce->len);
+         sua_pos = grub_le_to_cpu32 (ce->off);
+         sua_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ;
+
+         grub_free (sua);
+         if (load_sua ())
+           return grub_errno;
+       }
+
+      if (hook (entry))
+       {
+         grub_free (sua);
+         return 0;
+       }
+    }
+
+  grub_free (sua);
+  return 0;
+}
+
+static char *
+grub_iso9660_convert_string (grub_uint16_t *us, int len)
+{
+  char *p;
+  int i;
+
+  p = grub_malloc (len * 4 + 1);
+  if (! p)
+    return p;
+
+  for (i=0; i<len; i++)
+    us[i] = grub_be_to_cpu16 (us[i]);
+
+  *grub_utf16_to_utf8 ((grub_uint8_t *) p, us, len) = '\0';
+
+  return p;
+}
+
+static struct grub_iso9660_data *
+grub_iso9660_mount (grub_disk_t disk)
+{
+  struct grub_iso9660_data *data = 0;
+  struct grub_iso9660_dir rootdir;
+  int sua_pos;
+  int sua_size;
+  char *sua;
+  struct grub_iso9660_susp_entry *entry;
+  struct grub_iso9660_primary_voldesc voldesc;
+  int block;
+
+  auto grub_err_t susp_iterate (struct grub_iso9660_susp_entry *);
+
+  grub_err_t susp_iterate (struct grub_iso9660_susp_entry *susp_entry)
+    {
+      /* The "ER" entry is used to detect extensions.  The
+        `IEEE_P1285' extension means Rock ridge.  */
+      if (grub_strncmp ((char *) susp_entry->sig, "ER", 2) == 0)
+       {
+         data->rockridge = 1;
+         return 1;
+       }
+      return 0;
+    }
+
+  data = grub_zalloc (sizeof (struct grub_iso9660_data));
+  if (! data)
+    return 0;
+
+  data->disk = disk;
+
+  block = 16;
+  do
+    {
+      int copy_voldesc = 0;
+
+      /* Read the superblock.  */
+      if (grub_disk_read (disk, block << GRUB_ISO9660_LOG2_BLKSZ, 0,
+                         sizeof (struct grub_iso9660_primary_voldesc),
+                         (char *) &voldesc))
+        {
+          grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
+          goto fail;
+        }
+
+      if (grub_strncmp ((char *) voldesc.voldesc.magic, "CD001", 5) != 0)
+        {
+          grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
+          goto fail;
+        }
+
+      if (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_PRIMARY)
+        copy_voldesc = 1;
+      else if ((voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP) &&
+               (voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f) &&
+               ((voldesc.escape[2] == 0x40) || /* UCS-2 Level 1.  */
+                (voldesc.escape[2] == 0x43) ||  /* UCS-2 Level 2.  */
+                (voldesc.escape[2] == 0x45)))  /* UCS-2 Level 3.  */
+        {
+          copy_voldesc = 1;
+          data->joliet = 1;
+        }
+
+      if (copy_voldesc)
+        grub_memcpy((char *) &data->voldesc, (char *) &voldesc,
+                    sizeof (struct grub_iso9660_primary_voldesc));
+
+      block++;
+    } while (voldesc.voldesc.type != GRUB_ISO9660_VOLDESC_END);
+
+  /* Read the system use area and test it to see if SUSP is
+     supported.  */
+  if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
+                            << GRUB_ISO9660_LOG2_BLKSZ), 0,
+                     sizeof (rootdir), (char *) &rootdir))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
+      goto fail;
+    }
+
+  sua_pos = (sizeof (rootdir) + rootdir.namelen
+            + (rootdir.namelen % 2) - 1);
+  sua_size = rootdir.len - sua_pos;
+
+  sua = grub_malloc (sua_size);
+  if (! sua)
+    goto fail;
+
+  if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
+                            << GRUB_ISO9660_LOG2_BLKSZ), sua_pos,
+                     sua_size, sua))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
+      goto fail;
+    }
+
+  entry = (struct grub_iso9660_susp_entry *) sua;
+
+  /* Test if the SUSP protocol is used on this filesystem.  */
+  if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0)
+    {
+      /* The 2nd data byte stored how many bytes are skipped every time
+        to get to the SUA (System Usage Area).  */
+      data->susp_skip = entry->data[2];
+      entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len);
+
+      /* Iterate over the entries in the SUA area to detect
+        extensions.  */
+      if (grub_iso9660_susp_iterate (data,
+                                    (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
+                                     << GRUB_ISO9660_LOG2_BLKSZ),
+                                    sua_pos, sua_size, susp_iterate))
+       goto fail;
+    }
+
+  return data;
+
+ fail:
+  grub_free (data);
+  return 0;
+}
+
+
+static char *
+grub_iso9660_read_symlink (grub_fshelp_node_t node)
+{
+  struct grub_iso9660_dir dirent;
+  int sua_off;
+  int sua_size;
+  char *symlink = 0;
+  int addslash = 0;
+
+  auto void add_part (const char *part, int len);
+  auto grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *);
+
+  /* Extend the symlink.  */
+  void add_part (const char *part, int len)
+    {
+      int size = grub_strlen (symlink);
+
+      symlink = grub_realloc (symlink, size + len + 1);
+      if (! symlink)
+       return;
+
+      grub_strncat (symlink, part, len);
+    }
+
+  /* Read in a symlink.  */
+  grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *entry)
+    {
+      if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0)
+       {
+         unsigned int pos = 1;
+
+         /* The symlink is not stored as a POSIX symlink, translate it.  */
+         while (pos < grub_le_to_cpu32 (entry->len))
+           {
+             if (addslash)
+               {
+                 add_part ("/", 1);
+                 addslash = 0;
+               }
+
+             /* The current position is the `Component Flag'.  */
+             switch (entry->data[pos] & 30)
+               {
+               case 0:
+                 {
+                   /* The data on pos + 2 is the actual data, pos + 1
+                      is the length.  Both are part of the `Component
+                      Record'.  */
+                   add_part ((char *) &entry->data[pos + 2],
+                             entry->data[pos + 1]);
+                   if ((entry->data[pos] & 1))
+                     addslash = 1;
+
+                   break;
+                 }
+
+               case 2:
+                 add_part ("./", 2);
+                 break;
+
+               case 4:
+                 add_part ("../", 3);
+                 break;
+
+               case 8:
+                 add_part ("/", 1);
+                 break;
+               }
+             /* In pos + 1 the length of the `Component Record' is
+                stored.  */
+             pos += entry->data[pos + 1] + 2;
+           }
+
+         /* Check if `grub_realloc' failed.  */
+         if (grub_errno)
+           return grub_errno;
+       }
+
+      return 0;
+    }
+
+  if (grub_disk_read (node->data->disk, node->dir_blk, node->dir_off,
+                     sizeof (dirent), (char *) &dirent))
+    return 0;
+
+  sua_off = (sizeof (dirent) + dirent.namelen + 1 - (dirent.namelen % 2)
+            + node->data->susp_skip);
+  sua_size = dirent.len - sua_off;
+
+  symlink = grub_malloc (1);
+  if (!symlink)
+    return 0;
+
+  *symlink = '\0';
+
+  if (grub_iso9660_susp_iterate (node->data, node->dir_blk,
+                                node->dir_off + sua_off,
+                                sua_size, susp_iterate_sl))
+    {
+      grub_free (symlink);
+      return 0;
+    }
+
+  return symlink;
+}
+
+
+static int
+grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
+                         int NESTED_FUNC_ATTR
+                         (*hook) (const char *filename,
+                                  enum grub_fshelp_filetype filetype,
+                                  grub_fshelp_node_t node))
+{
+  struct grub_iso9660_dir dirent;
+  unsigned int offset = 0;
+  char *filename;
+  int filename_alloc = 0;
+  enum grub_fshelp_filetype type;
+
+  auto grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *);
+
+  grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *entry)
+    {
+      /* The filename in the rock ridge entry.  */
+      if (grub_strncmp ("NM", (char *) entry->sig, 2) == 0)
+       {
+         /* The flags are stored at the data position 0, here the
+            filename type is stored.  */
+         if (entry->data[0] & GRUB_ISO9660_RR_DOT)
+           filename = ".";
+         else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT)
+           filename = "..";
+         else
+           {
+             int size = 1;
+             if (filename)
+               {
+                 size += grub_strlen (filename);
+                 grub_realloc (filename,
+                               grub_strlen (filename)
+                               + entry->len);
+               }
+             else
+               {
+                 size = entry->len - 5;
+                 filename = grub_zalloc (size + 1);
+               }
+             filename_alloc = 1;
+             grub_strncpy (filename, (char *) &entry->data[1], size);
+             filename[size] = '\0';
+           }
+       }
+      /* The mode information (st_mode).  */
+      else if (grub_strncmp ((char *) entry->sig, "PX", 2) == 0)
+       {
+         /* At position 0 of the PX record the st_mode information is
+            stored (little-endian).  */
+         grub_uint32_t mode = ((entry->data[0] + (entry->data[1] << 8))
+                               & GRUB_ISO9660_FSTYPE_MASK);
+
+         switch (mode)
+           {
+           case GRUB_ISO9660_FSTYPE_DIR:
+             type = GRUB_FSHELP_DIR;
+             break;
+           case GRUB_ISO9660_FSTYPE_REG:
+             type = GRUB_FSHELP_REG;
+             break;
+           case GRUB_ISO9660_FSTYPE_SYMLINK:
+             type = GRUB_FSHELP_SYMLINK;
+             break;
+           default:
+             type = GRUB_FSHELP_UNKNOWN;
+           }
+       }
+
+      return 0;
+    }
+
+  while (offset < dir->size)
+    {
+      if (grub_disk_read (dir->data->disk,
+                         (dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
+                         + offset / GRUB_DISK_SECTOR_SIZE,
+                         offset % GRUB_DISK_SECTOR_SIZE,
+                         sizeof (dirent), (char *) &dirent))
+       return 0;
+
+      /* The end of the block, skip to the next one.  */
+      if (!dirent.len)
+       {
+         offset = (offset / GRUB_ISO9660_BLKSZ + 1) * GRUB_ISO9660_BLKSZ;
+         continue;
+       }
+
+      {
+       char name[dirent.namelen + 1];
+       int nameoffset = offset + sizeof (dirent);
+       struct grub_fshelp_node *node;
+       int sua_off = (sizeof (dirent) + dirent.namelen + 1
+                      - (dirent.namelen % 2));
+       int sua_size = dirent.len - sua_off;
+
+       sua_off += offset + dir->data->susp_skip;
+
+       filename = 0;
+       filename_alloc = 0;
+       type = GRUB_FSHELP_UNKNOWN;
+
+       if (dir->data->rockridge
+           && grub_iso9660_susp_iterate (dir->data,
+                                         (dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
+                                         + (sua_off
+                                            / GRUB_DISK_SECTOR_SIZE),
+                                         sua_off % GRUB_DISK_SECTOR_SIZE,
+                                         sua_size, susp_iterate_dir))
+         return 0;
+
+       /* Read the name.  */
+       if (grub_disk_read (dir->data->disk,
+                           (dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
+                           + nameoffset / GRUB_DISK_SECTOR_SIZE,
+                           nameoffset % GRUB_DISK_SECTOR_SIZE,
+                           dirent.namelen, (char *) name))
+         return 0;
+
+       node = grub_malloc (sizeof (struct grub_fshelp_node));
+       if (!node)
+         return 0;
+
+       /* Setup a new node.  */
+       node->data = dir->data;
+       node->size = grub_le_to_cpu32 (dirent.size);
+       node->blk = grub_le_to_cpu32 (dirent.first_sector);
+       node->dir_blk = ((dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
+                        + offset / GRUB_DISK_SECTOR_SIZE);
+       node->dir_off = offset % GRUB_DISK_SECTOR_SIZE;
+
+       /* If the filetype was not stored using rockridge, use
+          whatever is stored in the iso9660 filesystem.  */
+       if (type == GRUB_FSHELP_UNKNOWN)
+         {
+           if ((dirent.flags & 3) == 2)
+             type = GRUB_FSHELP_DIR;
+           else
+             type = GRUB_FSHELP_REG;
+         }
+
+       /* The filename was not stored in a rock ridge entry.  Read it
+          from the iso9660 filesystem.  */
+       if (!filename)
+         {
+           name[dirent.namelen] = '\0';
+           filename = grub_strrchr (name, ';');
+           if (filename)
+             *filename = '\0';
+
+           if (dirent.namelen == 1 && name[0] == 0)
+             filename = ".";
+           else if (dirent.namelen == 1 && name[0] == 1)
+             filename = "..";
+           else
+             filename = name;
+         }
+
+        if (dir->data->joliet)
+          {
+            char *oldname, *semicolon;
+
+            oldname = filename;
+            filename = grub_iso9660_convert_string
+                  ((grub_uint16_t *) oldname, dirent.namelen >> 1);
+
+           semicolon = grub_strrchr (filename, ';');
+           if (semicolon)
+             *semicolon = '\0';
+
+            if (filename_alloc)
+              grub_free (oldname);
+
+            filename_alloc = 1;
+          }
+
+       if (hook (filename, type, node))
+         {
+           if (filename_alloc)
+             grub_free (filename);
+           return 1;
+         }
+       if (filename_alloc)
+         grub_free (filename);
+      }
+
+      offset += dirent.len;
+    }
+
+  return 0;
+}
+
+
+\f
+static grub_err_t
+grub_iso9660_dir (grub_device_t device, const char *path,
+                 int (*hook) (const char *filename,
+                              const struct grub_dirhook_info *info))
+{
+  struct grub_iso9660_data *data = 0;
+  struct grub_fshelp_node rootnode;
+  struct grub_fshelp_node *foundnode;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+                                    enum grub_fshelp_filetype filetype,
+                                    grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+    }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_iso9660_mount (device->disk);
+  if (! data)
+    goto fail;
+
+  rootnode.data = data;
+  rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector);
+  rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size);
+
+  /* Use the fshelp function to traverse the path.  */
+  if (grub_fshelp_find_file (path, &rootnode,
+                            &foundnode,
+                            grub_iso9660_iterate_dir,
+                            grub_iso9660_read_symlink,
+                            GRUB_FSHELP_DIR))
+    goto fail;
+
+  /* List the files in the directory.  */
+  grub_iso9660_iterate_dir (foundnode, iterate);
+
+  if (foundnode != &rootnode)
+    grub_free (foundnode);
+
+ fail:
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_iso9660_open (struct grub_file *file, const char *name)
+{
+  struct grub_iso9660_data *data;
+  struct grub_fshelp_node rootnode;
+  struct grub_fshelp_node *foundnode;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_iso9660_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  rootnode.data = data;
+  rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector);
+  rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size);
+
+  /* Use the fshelp function to traverse the path.  */
+  if (grub_fshelp_find_file (name, &rootnode,
+                            &foundnode,
+                            grub_iso9660_iterate_dir,
+                            grub_iso9660_read_symlink,
+                            GRUB_FSHELP_REG))
+    goto fail;
+
+  data->first_sector = foundnode->blk;
+
+  file->data = data;
+  file->size = foundnode->size;
+  file->offset = 0;
+
+  return 0;
+
+ fail:
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+static grub_ssize_t
+grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_iso9660_data *data =
+    (struct grub_iso9660_data *) file->data;
+
+  /* XXX: The file is stored in as a single extent.  */
+  data->disk->read_hook = file->read_hook;
+  grub_disk_read (data->disk,
+                 data->first_sector << GRUB_ISO9660_LOG2_BLKSZ,
+                 file->offset,
+                 len, buf);
+  data->disk->read_hook = NULL;
+
+  if (grub_errno)
+    return -1;
+
+  return len;
+}
+
+
+static grub_err_t
+grub_iso9660_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_err_t
+grub_iso9660_label (grub_device_t device, char **label)
+{
+  struct grub_iso9660_data *data;
+  data = grub_iso9660_mount (device->disk);
+
+  if (data)
+    {
+      if (data->joliet)
+        *label = grub_iso9660_convert_string
+                 ((grub_uint16_t *) &data->voldesc.volname, 16);
+      else
+        *label = grub_strndup ((char *) data->voldesc.volname, 32);
+      grub_free (data);
+    }
+  else
+    *label = 0;
+
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_iso9660_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_iso9660_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_iso9660_mount (disk);
+  if (data)
+    {
+      if (! data->voldesc.modified.year[0] && ! data->voldesc.modified.year[1]
+         && ! data->voldesc.modified.year[2] && ! data->voldesc.modified.year[3]
+         && ! data->voldesc.modified.month[0] && ! data->voldesc.modified.month[1]
+         && ! data->voldesc.modified.day[0] && ! data->voldesc.modified.day[1]
+         && ! data->voldesc.modified.hour[0] && ! data->voldesc.modified.hour[1]
+         && ! data->voldesc.modified.minute[0] && ! data->voldesc.modified.minute[1]
+         && ! data->voldesc.modified.second[0] && ! data->voldesc.modified.second[1]
+         && ! data->voldesc.modified.hundredth[0] && ! data->voldesc.modified.hundredth[1])
+       {
+         grub_error (GRUB_ERR_BAD_NUMBER, "no creation date in filesystem to generate UUID");
+         *uuid = NULL;
+       }
+      else
+       {
+         *uuid = grub_xasprintf ("%c%c%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c",
+                                data->voldesc.modified.year[0],
+                                data->voldesc.modified.year[1],
+                                data->voldesc.modified.year[2],
+                                data->voldesc.modified.year[3],
+                                data->voldesc.modified.month[0],
+                                data->voldesc.modified.month[1],
+                                data->voldesc.modified.day[0],
+                                data->voldesc.modified.day[1],
+                                data->voldesc.modified.hour[0],
+                                data->voldesc.modified.hour[1],
+                                data->voldesc.modified.minute[0],
+                                data->voldesc.modified.minute[1],
+                                data->voldesc.modified.second[0],
+                                data->voldesc.modified.second[1],
+                                data->voldesc.modified.hundredth[0],
+                                data->voldesc.modified.hundredth[1]);
+       }
+    }
+  else
+    *uuid = NULL;
+
+       grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+\f
+
+static struct grub_fs grub_iso9660_fs =
+  {
+    .name = "iso9660",
+    .dir = grub_iso9660_dir,
+    .open = grub_iso9660_open,
+    .read = grub_iso9660_read,
+    .close = grub_iso9660_close,
+    .label = grub_iso9660_label,
+    .uuid = grub_iso9660_uuid,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(iso9660)
+{
+  grub_fs_register (&grub_iso9660_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(iso9660)
+{
+  grub_fs_unregister (&grub_iso9660_fs);
+}
diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c
new file mode 100644 (file)
index 0000000..c9839a2
--- /dev/null
@@ -0,0 +1,902 @@
+/* jfs.c - JFS.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/charset.h>
+
+#define GRUB_JFS_MAX_SYMLNK_CNT        8
+#define GRUB_JFS_FILETYPE_MASK 0170000
+#define GRUB_JFS_FILETYPE_REG  0100000
+#define GRUB_JFS_FILETYPE_LNK  0120000
+#define GRUB_JFS_FILETYPE_DIR  0040000
+
+#define GRUB_JFS_SBLOCK                64
+#define GRUB_JFS_AGGR_INODE    2
+#define GRUB_JFS_FS1_INODE_BLK 104
+
+#define GRUB_JFS_TREE_LEAF     2
+
+struct grub_jfs_sblock
+{
+  /* The magic for JFS.  It should contain the string "JFS1".  */
+  grub_uint8_t magic[4];
+  grub_uint32_t version;
+  grub_uint64_t ag_size;
+
+  /* The size of a filesystem block in bytes.  XXX: currently only
+     4096 was tested.  */
+  grub_uint32_t blksz;
+  grub_uint16_t log2_blksz;
+
+  grub_uint8_t unused[71];
+  grub_uint8_t volname[11];
+  grub_uint8_t unused2[32];
+  grub_uint8_t uuid[16];
+};
+
+struct grub_jfs_extent
+{
+  /* The length of the extent in filesystem blocks.  */
+  grub_uint16_t length;
+  grub_uint8_t length2;
+
+  /* The physical offset of the first block on the disk.  */
+  grub_uint8_t blk1;
+  grub_uint32_t blk2;
+} __attribute__ ((packed));
+
+struct grub_jfs_iag
+{
+  grub_uint8_t unused[3072];
+  struct grub_jfs_extent inodes[128];
+} __attribute__ ((packed));
+
+
+/* The head of the tree used to find extents.  */
+struct grub_jfs_treehead
+{
+  grub_uint64_t next;
+  grub_uint64_t prev;
+
+  grub_uint8_t flags;
+  grub_uint8_t unused;
+
+  grub_uint16_t count;
+  grub_uint16_t max;
+  grub_uint8_t unused2[10];
+} __attribute__ ((packed));
+
+/* A node in the extent tree.  */
+struct grub_jfs_tree_extent
+{
+  grub_uint8_t flags;
+  grub_uint16_t unused;
+
+  /* The offset is the key used to lookup an extent.  */
+  grub_uint8_t offset1;
+  grub_uint32_t offset2;
+
+  struct grub_jfs_extent extent;
+} __attribute__ ((packed));
+
+/* The tree of directory entries.  */
+struct grub_jfs_tree_dir
+{
+  /* Pointers to the previous and next tree headers of other nodes on
+     this level.  */
+  grub_uint64_t nextb;
+  grub_uint64_t prevb;
+
+  grub_uint8_t flags;
+
+  /* The amount of dirents in this node.  */
+  grub_uint8_t count;
+  grub_uint8_t freecnt;
+  grub_uint8_t freelist;
+  grub_uint8_t maxslot;
+
+  /* The location of the sorted array of pointers to dirents.  */
+  grub_uint8_t sindex;
+  grub_uint8_t unused[10];
+} __attribute__ ((packed));
+
+/* An internal node in the dirents tree.  */
+struct grub_jfs_internal_dirent
+{
+  struct grub_jfs_extent ex;
+  grub_uint8_t next;
+  grub_uint8_t len;
+  grub_uint16_t namepart[11];
+} __attribute__ ((packed));
+
+/* A leaf node in the dirents tree.  */
+struct grub_jfs_leaf_dirent
+{
+  /* The inode for this dirent.  */
+  grub_uint32_t inode;
+  grub_uint8_t next;
+
+  /* The size of the name.  */
+  grub_uint8_t len;
+  grub_uint16_t namepart[11];
+  grub_uint32_t index;
+} __attribute__ ((packed));
+
+/* A leaf in the dirents tree.  This one is used if the previously
+   dirent was not big enough to store the name.  */
+struct grub_jfs_leaf_next_dirent
+{
+  grub_uint8_t next;
+  grub_uint8_t len;
+  grub_uint16_t namepart[15];
+} __attribute__ ((packed));
+
+struct grub_jfs_inode
+{
+  grub_uint32_t stamp;
+  grub_uint32_t fileset;
+  grub_uint32_t inode;
+  grub_uint8_t unused[12];
+  grub_uint64_t size;
+  grub_uint8_t unused2[20];
+  grub_uint32_t mode;
+  grub_uint8_t unused3[72];
+  grub_uint8_t unused4[96];
+
+  union
+  {
+    /* The tree describing the extents of the file.  */
+    struct __attribute__ ((packed))
+    {
+      struct grub_jfs_treehead tree;
+      struct grub_jfs_tree_extent extents[16];
+    } file;
+    union
+    {
+      /* The tree describing the dirents.  */
+      struct
+      {
+       grub_uint8_t unused[16];
+       grub_uint8_t flags;
+
+       /* Amount of dirents in this node.  */
+       grub_uint8_t count;
+       grub_uint8_t freecnt;
+       grub_uint8_t freelist;
+       grub_uint32_t idotdot;
+       grub_uint8_t sorted[8];
+      } header;
+      struct grub_jfs_leaf_dirent dirents[8];
+    } dir __attribute__ ((packed));
+    /* Fast symlink.  */
+    struct
+    {
+      grub_uint8_t unused[32];
+      grub_uint8_t path[128];
+    } symlink;
+  } __attribute__ ((packed));
+} __attribute__ ((packed));
+
+struct grub_jfs_data
+{
+  struct grub_jfs_sblock sblock;
+  grub_disk_t disk;
+  struct grub_jfs_inode fileset;
+  struct grub_jfs_inode currinode;
+  int pos;
+  int linknest;
+} __attribute__ ((packed));
+
+struct grub_jfs_diropen
+{
+  int index;
+  union
+  {
+    struct grub_jfs_tree_dir header;
+    struct grub_jfs_leaf_dirent dirent[0];
+    struct grub_jfs_leaf_next_dirent next_dirent[0];
+    char sorted[0];
+  } *dirpage __attribute__ ((packed));
+  struct grub_jfs_data *data;
+  struct grub_jfs_inode *inode;
+  int count;
+  char *sorted;
+  struct grub_jfs_leaf_dirent *leaf;
+  struct grub_jfs_leaf_next_dirent *next_leaf;
+
+  /* The filename and inode of the last read dirent.  */
+  char name[255];
+  grub_uint32_t ino;
+} __attribute__ ((packed));
+
+
+static grub_dl_t my_mod;
+\f
+static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, int ino);
+
+/* Get the block number for the block BLK in the node INODE in the
+   mounted filesystem DATA.  */
+static int
+grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode,
+               unsigned int blk)
+{
+  auto int getblk (struct grub_jfs_treehead *treehead,
+                  struct grub_jfs_tree_extent *extents);
+
+  int getblk (struct grub_jfs_treehead *treehead,
+             struct grub_jfs_tree_extent *extents)
+    {
+      int found = -1;
+      int i;
+
+      for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2; i++)
+       {
+         if (treehead->flags & GRUB_JFS_TREE_LEAF)
+           {
+             /* Read the leafnode.  */
+             if (grub_le_to_cpu32 (extents[i].offset2) <= blk
+                 && ((grub_le_to_cpu16 (extents[i].extent.length))
+                     + (extents[i].extent.length2 << 8)
+                     + grub_le_to_cpu32 (extents[i].offset2)) > blk)
+               return (blk - grub_le_to_cpu32 (extents[i].offset2)
+                       + grub_le_to_cpu32 (extents[i].extent.blk2));
+           }
+         else
+           if (blk >= grub_le_to_cpu32 (extents[i].offset2))
+             found = i;
+       }
+
+      if (found != -1)
+       {
+         struct
+         {
+           struct grub_jfs_treehead treehead;
+           struct grub_jfs_tree_extent extents[254];
+         } tree;
+
+         if (grub_disk_read (data->disk,
+                             grub_le_to_cpu32 (extents[found].extent.blk2)
+                             << (grub_le_to_cpu16 (data->sblock.log2_blksz)
+                                 - GRUB_DISK_SECTOR_BITS), 0,
+                             sizeof (tree), (char *) &tree))
+           return -1;
+
+         return getblk (&tree.treehead, &tree.extents[0]);
+       }
+
+      return -1;
+    }
+
+  return getblk (&inode->file.tree, &inode->file.extents[0]);
+}
+
+
+static grub_err_t
+grub_jfs_read_inode (struct grub_jfs_data *data, int ino,
+                    struct grub_jfs_inode *inode)
+{
+  struct grub_jfs_iag iag;
+  int iagnum = ino / 4096;
+  int inoext = (ino % 4096) / 32;
+  int inonum = (ino % 4096) % 32;
+  grub_uint32_t iagblk;
+  grub_uint32_t inoblk;
+
+  iagblk = grub_jfs_blkno (data, &data->fileset, iagnum + 1);
+  if (grub_errno)
+    return grub_errno;
+
+  /* Read in the IAG.  */
+  if (grub_disk_read (data->disk,
+                     iagblk << (grub_le_to_cpu16 (data->sblock.log2_blksz)
+                                - GRUB_DISK_SECTOR_BITS), 0,
+                     sizeof (struct grub_jfs_iag), &iag))
+    return grub_errno;
+
+  inoblk = grub_le_to_cpu32 (iag.inodes[inoext].blk2);
+  inoblk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz)
+             - GRUB_DISK_SECTOR_BITS);
+  inoblk += inonum;
+
+  if (grub_disk_read (data->disk, inoblk, 0,
+                     sizeof (struct grub_jfs_inode), inode))
+    return grub_errno;
+
+  return 0;
+}
+
+
+static struct grub_jfs_data *
+grub_jfs_mount (grub_disk_t disk)
+{
+  struct grub_jfs_data *data = 0;
+
+  data = grub_malloc (sizeof (struct grub_jfs_data));
+  if (!data)
+    return 0;
+
+  /* Read the superblock.  */
+  if (grub_disk_read (disk, GRUB_JFS_SBLOCK, 0,
+                     sizeof (struct grub_jfs_sblock), &data->sblock))
+    goto fail;
+
+  if (grub_strncmp ((char *) (data->sblock.magic), "JFS1", 4))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a JFS filesystem");
+      goto fail;
+    }
+
+  data->disk = disk;
+  data->pos = 0;
+  data->linknest = 0;
+
+  /* Read the inode of the first fileset.  */
+  if (grub_disk_read (data->disk, GRUB_JFS_FS1_INODE_BLK, 0,
+                     sizeof (struct grub_jfs_inode), &data->fileset))
+    goto fail;
+
+  return data;
+
+ fail:
+  grub_free (data);
+
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not a JFS filesystem");
+
+  return 0;
+}
+
+
+static struct grub_jfs_diropen *
+grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode)
+{
+  struct grub_jfs_internal_dirent *de;
+  struct grub_jfs_diropen *diro;
+  int blk;
+
+  de = (struct grub_jfs_internal_dirent *) inode->dir.dirents;
+
+  if (!((grub_le_to_cpu32 (inode->mode)
+        & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR))
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+      return 0;
+    }
+
+  diro = grub_zalloc (sizeof (struct grub_jfs_diropen));
+  if (!diro)
+    return 0;
+
+  diro->data = data;
+  diro->inode = inode;
+
+  /* Check if the entire tree is contained within the inode.  */
+  if (inode->file.tree.flags & GRUB_JFS_TREE_LEAF)
+    {
+      diro->leaf = inode->dir.dirents;
+      diro->next_leaf = (struct grub_jfs_leaf_next_dirent *) de;
+      diro->sorted = (char *) (inode->dir.header.sorted);
+      diro->count = inode->dir.header.count;
+
+      return diro;
+    }
+
+  diro->dirpage = grub_malloc (grub_le_to_cpu32 (data->sblock.blksz));
+  if (!diro->dirpage)
+    {
+      grub_free (diro);
+      return 0;
+    }
+
+  blk = grub_le_to_cpu32 (de[inode->dir.header.sorted[0]].ex.blk2);
+  blk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS);
+
+  /* Read in the nodes until we are on the leaf node level.  */
+  do
+    {
+      int index;
+      if (grub_disk_read (data->disk, blk, 0,
+                         grub_le_to_cpu32 (data->sblock.blksz),
+                         diro->dirpage->sorted))
+       {
+         grub_free (diro->dirpage);
+         grub_free (diro);
+         return 0;
+       }
+
+      de = (struct grub_jfs_internal_dirent *) diro->dirpage->dirent;
+      index = diro->dirpage->sorted[diro->dirpage->header.sindex * 32];
+      blk = (grub_le_to_cpu32 (de[index].ex.blk2)
+            << (grub_le_to_cpu16 (data->sblock.log2_blksz)
+                - GRUB_DISK_SECTOR_BITS));
+    } while (!(diro->dirpage->header.flags & GRUB_JFS_TREE_LEAF));
+
+  diro->leaf = diro->dirpage->dirent;
+  diro->next_leaf = diro->dirpage->next_dirent;
+  diro->sorted = &diro->dirpage->sorted[diro->dirpage->header.sindex * 32];
+  diro->count = diro->dirpage->header.count;
+
+  return diro;
+}
+
+
+static void
+grub_jfs_closedir (struct grub_jfs_diropen *diro)
+{
+  if (!diro)
+    return;
+  grub_free (diro->dirpage);
+  grub_free (diro);
+}
+
+
+/* Read in the next dirent from the directory described by DIRO.  */
+static grub_err_t
+grub_jfs_getent (struct grub_jfs_diropen *diro)
+{
+  int strpos = 0;
+  struct grub_jfs_leaf_dirent *leaf;
+  struct grub_jfs_leaf_next_dirent *next_leaf;
+  int len;
+  int nextent;
+  grub_uint16_t filename[255];
+
+  auto void addstr (grub_uint16_t *uname, int ulen);
+
+  /* Add the unicode string to the utf16 filename buffer.  */
+  void addstr (grub_uint16_t *name, int ulen)
+    {
+      while (ulen--)
+       filename[strpos++] = *(name++);
+    }
+
+  /* The last node, read in more.  */
+  if (diro->index == diro->count)
+    {
+      unsigned int next;
+
+      /* If the inode contains the entry tree or if this was the last
+        node, there is nothing to read.  */
+      if ((diro->inode->file.tree.flags & GRUB_JFS_TREE_LEAF)
+         || !grub_le_to_cpu64 (diro->dirpage->header.nextb))
+       return GRUB_ERR_OUT_OF_RANGE;
+
+      next = grub_le_to_cpu64 (diro->dirpage->header.nextb);
+      next <<= (grub_le_to_cpu16 (diro->data->sblock.log2_blksz)
+               - GRUB_DISK_SECTOR_BITS);
+
+      if (grub_disk_read (diro->data->disk, next, 0,
+                         grub_le_to_cpu32 (diro->data->sblock.blksz),
+                         diro->dirpage->sorted))
+       return grub_errno;
+
+      diro->leaf = diro->dirpage->dirent;
+      diro->next_leaf = diro->dirpage->next_dirent;
+      diro->sorted = &diro->dirpage->sorted[diro->dirpage->header.sindex * 32];
+      diro->count = diro->dirpage->header.count;
+      diro->index = 0;
+    }
+
+  leaf = &diro->leaf[(int) diro->sorted[diro->index]];
+  next_leaf = &diro->next_leaf[diro->index];
+
+  len = leaf->len;
+  if (!len)
+    {
+      diro->index++;
+      return grub_jfs_getent (diro);
+    }
+
+  addstr (leaf->namepart, len < 11 ? len : 11);
+  diro->ino = grub_le_to_cpu32 (leaf->inode);
+  len -= 11;
+
+  /* Move down to the leaf level.  */
+  nextent = leaf->next;
+  if (leaf->next != 255)
+    do
+      {
+       next_leaf = &diro->next_leaf[nextent];
+       addstr (next_leaf->namepart, len < 15 ? len : 15 );
+
+       len -= 15;
+       nextent = next_leaf->next;
+      } while (next_leaf->next != 255 && len > 0);
+
+  diro->index++;
+
+  /* Convert the temporary UTF16 filename to UTF8.  */
+  *grub_utf16_to_utf8 ((grub_uint8_t *) (diro->name), filename, strpos) = '\0';
+
+  return 0;
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_jfs_read_file (struct grub_jfs_data *data,
+                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                      unsigned offset, unsigned length),
+                   int pos, grub_size_t len, char *buf)
+{
+  int i;
+  int blockcnt;
+
+  blockcnt = ((len + pos + grub_le_to_cpu32 (data->sblock.blksz) - 1)
+             / grub_le_to_cpu32 (data->sblock.blksz));
+
+  for (i = pos / grub_le_to_cpu32 (data->sblock.blksz); i < blockcnt; i++)
+    {
+      int blknr;
+      int blockoff = pos % grub_le_to_cpu32 (data->sblock.blksz);
+      int blockend = grub_le_to_cpu32 (data->sblock.blksz);
+
+      int skipfirst = 0;
+
+      blknr = grub_jfs_blkno (data, &data->currinode, i);
+      if (grub_errno)
+       return -1;
+
+      /* Last block.  */
+      if (i == blockcnt - 1)
+       {
+         blockend = (len + pos) % grub_le_to_cpu32 (data->sblock.blksz);
+
+         if (!blockend)
+           blockend = grub_le_to_cpu32 (data->sblock.blksz);
+       }
+
+      /* First block.  */
+      if (i == (pos / (int) grub_le_to_cpu32 (data->sblock.blksz)))
+       {
+         skipfirst = blockoff;
+         blockend -= skipfirst;
+       }
+
+      data->disk->read_hook = read_hook;
+      grub_disk_read (data->disk,
+                     blknr << (grub_le_to_cpu16 (data->sblock.log2_blksz)
+                               - GRUB_DISK_SECTOR_BITS),
+                     skipfirst, blockend, buf);
+
+      data->disk->read_hook = 0;
+      if (grub_errno)
+       return -1;
+
+      buf += grub_le_to_cpu32 (data->sblock.blksz) - skipfirst;
+    }
+
+  return len;
+}
+
+
+/* Find the file with the pathname PATH on the filesystem described by
+   DATA.  */
+static grub_err_t
+grub_jfs_find_file (struct grub_jfs_data *data, const char *path)
+{
+  char fpath[grub_strlen (path)];
+  char *name = fpath;
+  char *next;
+  unsigned int pos = 0;
+  struct grub_jfs_diropen *diro;
+
+  grub_strncpy (fpath, path, grub_strlen (path) + 1);
+
+  if (grub_jfs_read_inode (data, GRUB_JFS_AGGR_INODE, &data->currinode))
+    return grub_errno;
+
+  /* Skip the first slashes.  */
+  while (*name == '/')
+    {
+      name++;
+      if (!*name)
+       return 0;
+    }
+
+  /* Extract the actual part from the pathname.  */
+  next = grub_strchr (name, '/');
+  if (next)
+    {
+      while (*next == '/')
+       {
+         next[0] = '\0';
+         next++;
+       }
+    }
+  diro = grub_jfs_opendir (data, &data->currinode);
+  if (!diro)
+    return grub_errno;
+
+  for (;;)
+    {
+      if (grub_strlen (name) == 0)
+       return GRUB_ERR_NONE;
+
+      if (grub_jfs_getent (diro) == GRUB_ERR_OUT_OF_RANGE)
+       break;
+
+      /* Check if the current direntry matches the current part of the
+        pathname.  */
+      if (!grub_strcmp (name, diro->name))
+       {
+         int ino = diro->ino;
+         int dirino = grub_le_to_cpu32 (data->currinode.inode);
+
+         grub_jfs_closedir (diro);
+         diro = 0;
+
+         if (grub_jfs_read_inode (data, ino, &data->currinode))
+           break;
+
+         /* Check if this is a symlink.  */
+         if ((grub_le_to_cpu32 (data->currinode.mode)
+              & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_LNK)
+           {
+             grub_jfs_lookup_symlink (data, dirino);
+             if (grub_errno)
+               return grub_errno;
+           }
+
+         if (!next)
+           return 0;
+
+         pos = 0;
+
+         name = next;
+         next = grub_strchr (name, '/');
+         if (next)
+           {
+             next[0] = '\0';
+             next++;
+           }
+
+         /* Open this directory for reading dirents.  */
+         diro = grub_jfs_opendir (data, &data->currinode);
+         if (!diro)
+           return grub_errno;
+
+         continue;
+       }
+    }
+
+  grub_jfs_closedir (diro);
+  grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_jfs_lookup_symlink (struct grub_jfs_data *data, int ino)
+{
+  int size = grub_le_to_cpu64 (data->currinode.size);
+  char symlink[size + 1];
+
+  if (++data->linknest > GRUB_JFS_MAX_SYMLNK_CNT)
+    return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
+
+  if (size <= 128)
+    grub_strncpy (symlink, (char *) (data->currinode.symlink.path), 128);
+  else if (grub_jfs_read_file (data, 0, 0, size, symlink) < 0)
+    return grub_errno;
+
+  symlink[size] = '\0';
+
+  /* The symlink is an absolute path, go back to the root inode.  */
+  if (symlink[0] == '/')
+    ino = 2;
+
+  /* Now load in the old inode.  */
+  if (grub_jfs_read_inode (data, ino, &data->currinode))
+    return grub_errno;
+
+  grub_jfs_find_file (data, symlink);
+  if (grub_errno)
+    grub_error (grub_errno, "cannot follow symlink `%s'", symlink);
+
+  return grub_errno;
+}
+\f
+
+static grub_err_t
+grub_jfs_dir (grub_device_t device, const char *path,
+             int (*hook) (const char *filename,
+                          const struct grub_dirhook_info *info))
+{
+  struct grub_jfs_data *data = 0;
+  struct grub_jfs_diropen *diro = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_jfs_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  if (grub_jfs_find_file (data, path))
+    goto fail;
+
+  diro = grub_jfs_opendir (data, &data->currinode);
+  if (!diro)
+    goto fail;
+
+  /* Iterate over the dirents in the directory that was found.  */
+  while (grub_jfs_getent (diro) != GRUB_ERR_OUT_OF_RANGE)
+    {
+      struct grub_jfs_inode inode;
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+
+      if (grub_jfs_read_inode (data, diro->ino, &inode))
+       goto fail;
+
+      info.dir = (grub_le_to_cpu32 (inode.mode)
+                 & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR;
+      if (hook (diro->name, &info))
+       goto fail;
+    }
+
+  /* XXX: GRUB_ERR_OUT_OF_RANGE is used for the last dirent.  */
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_errno = 0;
+
+ fail:
+  grub_jfs_closedir (diro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_jfs_open (struct grub_file *file, const char *name)
+{
+  struct grub_jfs_data *data;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_jfs_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  grub_jfs_find_file (data, name);
+  if (grub_errno)
+    goto fail;
+
+  /* It is only possible for open regular files.  */
+  if (! ((grub_le_to_cpu32 (data->currinode.mode)
+         & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_REG))
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file");
+      goto fail;
+    }
+
+  file->data = data;
+  file->size = grub_le_to_cpu64 (data->currinode.size);
+
+  return 0;
+
+ fail:
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+static grub_ssize_t
+grub_jfs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_jfs_data *data =
+    (struct grub_jfs_data *) file->data;
+
+  return grub_jfs_read_file (data, file->read_hook, file->offset, len, buf);
+}
+
+
+static grub_err_t
+grub_jfs_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_jfs_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_jfs_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_jfs_mount (disk);
+  if (data)
+    {
+      *uuid = grub_xasprintf ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
+                            "%02x%02x%02x%02x%02x%02x",
+                            data->sblock.uuid[0], data->sblock.uuid[1],
+                            data->sblock.uuid[2], data->sblock.uuid[3],
+                            data->sblock.uuid[4], data->sblock.uuid[5],
+                            data->sblock.uuid[6], data->sblock.uuid[7],
+                            data->sblock.uuid[8], data->sblock.uuid[9],
+                            data->sblock.uuid[10], data->sblock.uuid[11],
+                            data->sblock.uuid[12], data->sblock.uuid[13],
+                            data->sblock.uuid[14], data->sblock.uuid[15]);
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_jfs_label (grub_device_t device, char **label)
+{
+  struct grub_jfs_data *data;
+  data = grub_jfs_mount (device->disk);
+
+  if (data)
+    *label = grub_strndup ((char *) (data->sblock.volname), 11);
+  else
+    *label = 0;
+
+  return grub_errno;
+}
+\f
+
+static struct grub_fs grub_jfs_fs =
+  {
+    .name = "jfs",
+    .dir = grub_jfs_dir,
+    .open = grub_jfs_open,
+    .read = grub_jfs_read,
+    .close = grub_jfs_close,
+    .label = grub_jfs_label,
+    .uuid = grub_jfs_uuid,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(jfs)
+{
+  grub_fs_register (&grub_jfs_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(jfs)
+{
+  grub_fs_unregister (&grub_jfs_fs);
+}
diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c
new file mode 100644 (file)
index 0000000..a856e38
--- /dev/null
@@ -0,0 +1,614 @@
+/* minix.c - The minix filesystem, version 1 and 2.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+
+#define GRUB_MINIX_MAGIC       0x137F
+#define GRUB_MINIX2_MAGIC      0x2468
+#define GRUB_MINIX_MAGIC_30    0x138F
+#define GRUB_MINIX2_MAGIC_30   0x2478
+#define GRUB_MINIX_BSIZE       1024U
+#define GRUB_MINIX_LOG2_BSIZE  1
+#define GRUB_MINIX_ROOT_INODE  1
+#define GRUB_MINIX_MAX_SYMLNK_CNT      8
+#define GRUB_MINIX_SBLOCK      2
+
+#define GRUB_MINIX_IFDIR       0040000U
+#define GRUB_MINIX_IFLNK       0120000U
+
+#define GRUB_MINIX_INODE(data,field) (data->version == 1 ? \
+                           data->inode.  field : data->inode2.  field)
+#define GRUB_MINIX_INODE_ENDIAN(data,field,bits1,bits2) (data->version == 1 ?  \
+                        grub_le_to_cpu##bits1 (data->inode.field) :            \
+                        grub_le_to_cpu##bits2 (data->inode2.field))
+#define GRUB_MINIX_INODE_SIZE(data) GRUB_MINIX_INODE_ENDIAN (data,size,16,32)
+#define GRUB_MINIX_INODE_MODE(data) GRUB_MINIX_INODE_ENDIAN (data,mode,16,16)
+#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) GRUB_MINIX_INODE_ENDIAN           \
+                                               (data,dir_zones[blk],16,32)
+#define GRUB_MINIX_INODE_INDIR_ZONE(data)                              \
+                        GRUB_MINIX_INODE_ENDIAN (data,indir_zone,16,32)
+#define GRUB_MINIX_INODE_DINDIR_ZONE(data)                                     \
+                        GRUB_MINIX_INODE_ENDIAN (data,double_indir_zone,16,32)
+#define GRUB_MINIX_INODE_BLKSZ(data) (data->version == 1 ? 2 : 4)
+#define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE                          \
+                                + grub_le_to_cpu16 (sblock->log2_zone_size))
+#define GRUB_MINIX_ZONESZ      (GRUB_MINIX_BSIZE                               \
+                                << grub_le_to_cpu16 (sblock->log2_zone_size))
+
+struct grub_minix_sblock
+{
+  grub_uint16_t inode_cnt;
+  grub_uint16_t zone_cnt;
+  grub_uint16_t inode_bmap_size;
+  grub_uint16_t zone_bmap_size;
+  grub_uint16_t first_data_zone;
+  grub_uint16_t log2_zone_size;
+  grub_uint32_t max_file_size;
+  grub_uint16_t magic;
+};
+
+struct grub_minix_inode
+{
+  grub_uint16_t mode;
+  grub_uint16_t uid;
+  grub_uint16_t size;
+  grub_uint32_t ctime;
+  grub_uint8_t gid;
+  grub_uint8_t nlinks;
+  grub_uint16_t dir_zones[7];
+  grub_uint16_t indir_zone;
+  grub_uint16_t double_indir_zone;
+};
+
+struct grub_minix2_inode
+{
+  grub_uint16_t mode;
+  grub_uint16_t nlinks;
+  grub_uint16_t uid;
+  grub_uint16_t gid;
+  grub_uint32_t size;
+  grub_uint32_t atime;
+  grub_uint32_t mtime;
+  grub_uint32_t ctime;
+  grub_uint32_t dir_zones[7];
+  grub_uint32_t indir_zone;
+  grub_uint32_t double_indir_zone;
+  grub_uint32_t unused;
+
+};
+
+/* Information about a "mounted" minix filesystem.  */
+struct grub_minix_data
+{
+  struct grub_minix_sblock sblock;
+  struct grub_minix_inode inode;
+  struct grub_minix2_inode inode2;
+  int ino;
+  int linknest;
+  grub_disk_t disk;
+  int version;
+  int filename_size;
+};
+
+static grub_dl_t my_mod;
+\f
+static grub_err_t grub_minix_find_file (struct grub_minix_data *data,
+                                       const char *path);
+
+static int
+grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
+{
+  struct grub_minix_sblock *sblock = &data->sblock;
+  int indir;
+
+  auto int grub_get_indir (int, int);
+
+  /* Read the block pointer in ZONE, on the offset NUM.  */
+  int grub_get_indir (int zone, int num)
+    {
+      if (data->version == 1)
+       {
+         grub_uint16_t indir16;
+         grub_disk_read (data->disk,
+                         zone << GRUB_MINIX_LOG2_ZONESZ,
+                         sizeof (grub_uint16_t) * num,
+                         sizeof (grub_uint16_t), (char *) &indir16);
+         return grub_le_to_cpu16 (indir16);
+       }
+      else
+       {
+         grub_uint32_t indir32;
+         grub_disk_read (data->disk,
+                         zone << GRUB_MINIX_LOG2_ZONESZ,
+                         sizeof (grub_uint32_t) * num,
+                         sizeof (grub_uint32_t), (char *) &indir32);
+         return grub_le_to_cpu32 (indir32);
+       }
+    }
+
+  /* Direct block.  */
+  if (blk < 7)
+    return GRUB_MINIX_INODE_DIR_ZONES (data, blk);
+
+  /* Indirect block.  */
+  blk -= 7;
+  if (blk < GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
+    {
+      indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk);
+      return indir;
+    }
+
+  /* Double indirect block.  */
+  blk -= GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data);
+  if (blk < (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
+      * (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data)))
+    {
+      indir = grub_get_indir (GRUB_MINIX_INODE_DINDIR_ZONE (data),
+                             blk / GRUB_MINIX_ZONESZ);
+
+      indir = grub_get_indir (indir, blk % GRUB_MINIX_ZONESZ);
+
+      return indir;
+    }
+
+  /* This should never happen.  */
+  grub_error (GRUB_ERR_OUT_OF_RANGE, "file bigger than maximum size");
+
+  return 0;
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_minix_read_file (struct grub_minix_data *data,
+                     void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                        unsigned offset, unsigned length),
+                     int pos, grub_disk_addr_t len, char *buf)
+{
+  struct grub_minix_sblock *sblock = &data->sblock;
+  int i;
+  int blockcnt;
+
+  /* Adjust len so it we can't read past the end of the file.  */
+  if (len + pos > GRUB_MINIX_INODE_SIZE (data))
+    len = GRUB_MINIX_INODE_SIZE (data) - pos;
+
+  blockcnt = (len + pos + GRUB_MINIX_BSIZE - 1) / GRUB_MINIX_BSIZE;
+
+  for (i = pos / GRUB_MINIX_BSIZE; i < blockcnt; i++)
+    {
+      int blknr;
+      int blockoff = pos % GRUB_MINIX_BSIZE;
+      int blockend = GRUB_MINIX_BSIZE;
+
+      int skipfirst = 0;
+
+      blknr = grub_minix_get_file_block (data, i);
+      if (grub_errno)
+       return -1;
+
+      /* Last block.  */
+      if (i == blockcnt - 1)
+       {
+         blockend = (len + pos) % GRUB_MINIX_BSIZE;
+
+         if (!blockend)
+           blockend = GRUB_MINIX_BSIZE;
+       }
+
+      /* First block.  */
+      if (i == (pos / (int) GRUB_MINIX_BSIZE))
+       {
+         skipfirst = blockoff;
+         blockend -= skipfirst;
+       }
+
+      data->disk->read_hook = read_hook;
+      grub_disk_read (data->disk, blknr << GRUB_MINIX_LOG2_ZONESZ,
+                     skipfirst, blockend, buf);
+
+      data->disk->read_hook = 0;
+      if (grub_errno)
+       return -1;
+
+      buf += GRUB_MINIX_BSIZE - skipfirst;
+    }
+
+  return len;
+}
+
+
+/* Read inode INO from the mounted filesystem described by DATA.  This
+   inode is used by default now.  */
+static grub_err_t
+grub_minix_read_inode (struct grub_minix_data *data, int ino)
+{
+  struct grub_minix_sblock *sblock = &data->sblock;
+
+  /* Block in which the inode is stored.  */
+  int block;
+  data->ino = ino;
+
+  /* The first inode in minix is inode 1.  */
+  ino--;
+
+  block = ((2 + grub_le_to_cpu16 (sblock->inode_bmap_size)
+           + grub_le_to_cpu16 (sblock->zone_bmap_size))
+          << GRUB_MINIX_LOG2_BSIZE);
+
+  if (data->version == 1)
+    {
+      block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
+      int offs = (ino % (GRUB_DISK_SECTOR_SIZE
+                        / sizeof (struct grub_minix_inode))
+                 * sizeof (struct grub_minix_inode));
+
+      grub_disk_read (data->disk, block, offs,
+                     sizeof (struct grub_minix_inode), &data->inode);
+    }
+  else
+    {
+      block += ino / (GRUB_DISK_SECTOR_SIZE
+                     / sizeof (struct grub_minix2_inode));
+      int offs = (ino
+                 % (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix2_inode))
+                 * sizeof (struct grub_minix2_inode));
+
+      grub_disk_read (data->disk, block, offs,
+                     sizeof (struct grub_minix2_inode),&data->inode2);
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+
+/* Lookup the symlink the current inode points to.  INO is the inode
+   number of the directory the symlink is relative to.  */
+static grub_err_t
+grub_minix_lookup_symlink (struct grub_minix_data *data, int ino)
+{
+  char symlink[GRUB_MINIX_INODE_SIZE (data) + 1];
+
+  if (++data->linknest > GRUB_MINIX_MAX_SYMLNK_CNT)
+    return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
+
+  if (grub_minix_read_file (data, 0, 0,
+                           GRUB_MINIX_INODE_SIZE (data), symlink) < 0)
+    return grub_errno;
+
+  symlink[GRUB_MINIX_INODE_SIZE (data)] = '\0';
+
+  /* The symlink is an absolute path, go back to the root inode.  */
+  if (symlink[0] == '/')
+    ino = GRUB_MINIX_ROOT_INODE;
+
+  /* Now load in the old inode.  */
+  if (grub_minix_read_inode (data, ino))
+    return grub_errno;
+
+  grub_minix_find_file (data, symlink);
+  if (grub_errno)
+    grub_error (grub_errno, "cannot follow symlink `%s'", symlink);
+
+  return grub_errno;
+}
+
+
+/* Find the file with the pathname PATH on the filesystem described by
+   DATA.  */
+static grub_err_t
+grub_minix_find_file (struct grub_minix_data *data, const char *path)
+{
+  char fpath[grub_strlen (path) + 1];
+  char *name = fpath;
+  char *next;
+  unsigned int pos = 0;
+  int dirino;
+
+  grub_strcpy (fpath, path);
+
+  /* Skip the first slash.  */
+  if (name[0] == '/')
+    {
+      name++;
+      if (!*name)
+       return 0;
+    }
+
+  /* Extract the actual part from the pathname.  */
+  next = grub_strchr (name, '/');
+  if (next)
+    {
+      next[0] = '\0';
+      next++;
+    }
+
+  do
+    {
+      grub_uint16_t ino;
+      char filename[data->filename_size + 1];
+
+      if (grub_strlen (name) == 0)
+       return GRUB_ERR_NONE;
+
+      if (grub_minix_read_file (data, 0, pos, sizeof (ino),
+                               (char *) &ino) < 0)
+       return grub_errno;
+      if (grub_minix_read_file (data, 0, pos + sizeof (ino),
+                               data->filename_size, (char *) filename)< 0)
+       return grub_errno;
+
+      filename[data->filename_size] = '\0';
+
+      /* Check if the current direntry matches the current part of the
+        pathname.  */
+      if (!grub_strcmp (name, filename))
+       {
+         dirino = data->ino;
+         grub_minix_read_inode (data, grub_le_to_cpu16 (ino));
+
+         /* Follow the symlink.  */
+         if ((GRUB_MINIX_INODE_MODE (data)
+              & GRUB_MINIX_IFLNK) == GRUB_MINIX_IFLNK)
+           {
+             grub_minix_lookup_symlink (data, dirino);
+             if (grub_errno)
+               return grub_errno;
+           }
+
+         if (!next)
+           return 0;
+
+         pos = 0;
+
+         name = next;
+         next = grub_strchr (name, '/');
+         if (next)
+           {
+             next[0] = '\0';
+             next++;
+           }
+
+         if ((GRUB_MINIX_INODE_MODE (data)
+              & GRUB_MINIX_IFDIR) != GRUB_MINIX_IFDIR)
+           return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+
+         continue;
+       }
+
+      pos += sizeof (ino) + data->filename_size;
+    } while (pos < GRUB_MINIX_INODE_SIZE (data));
+
+  grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+  return grub_errno;
+}
+
+
+/* Mount the filesystem on the disk DISK.  */
+static struct grub_minix_data *
+grub_minix_mount (grub_disk_t disk)
+{
+  struct grub_minix_data *data;
+
+  data = grub_malloc (sizeof (struct grub_minix_data));
+  if (!data)
+    return 0;
+
+  /* Read the superblock.  */
+  grub_disk_read (disk, GRUB_MINIX_SBLOCK, 0,
+                 sizeof (struct grub_minix_sblock),&data->sblock);
+  if (grub_errno)
+    goto fail;
+
+  if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC)
+    {
+      data->version = 1;
+      data->filename_size = 14;
+    }
+  else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC)
+    {
+      data->version = 2;
+      data->filename_size = 14;
+    }
+  else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC_30)
+    {
+      data->version = 1;
+      data->filename_size = 30;
+    }
+  else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC_30)
+    {
+      data->version = 2;
+      data->filename_size = 30;
+    }
+  else
+    goto fail;
+
+  data->disk = disk;
+  data->linknest = 0;
+
+  return data;
+
+ fail:
+  grub_free (data);
+  grub_error (GRUB_ERR_BAD_FS, "not a minix filesystem");
+  return 0;
+}
+\f
+static grub_err_t
+grub_minix_dir (grub_device_t device, const char *path,
+                 int (*hook) (const char *filename,
+                              const struct grub_dirhook_info *info))
+{
+  struct grub_minix_data *data = 0;
+  struct grub_minix_sblock *sblock;
+  unsigned int pos = 0;
+
+  data = grub_minix_mount (device->disk);
+  if (!data)
+    return grub_errno;
+
+  grub_minix_read_inode (data, GRUB_MINIX_ROOT_INODE);
+  if (grub_errno)
+    goto fail;
+
+  sblock = &data->sblock;
+
+  grub_minix_find_file (data, path);
+  if (grub_errno)
+    goto fail;
+
+  if ((GRUB_MINIX_INODE_MODE (data) & GRUB_MINIX_IFDIR) != GRUB_MINIX_IFDIR)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+      goto fail;
+    }
+
+  while (pos < GRUB_MINIX_INODE_SIZE (data))
+    {
+      grub_uint16_t ino;
+      char filename[data->filename_size + 1];
+      int dirino = data->ino;
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+
+
+      if (grub_minix_read_file (data, 0, pos, sizeof (ino),
+                               (char *) &ino) < 0)
+       return grub_errno;
+
+      if (grub_minix_read_file (data, 0, pos + sizeof (ino),
+                               data->filename_size,
+                               (char *) filename) < 0)
+       return grub_errno;
+      filename[data->filename_size] = '\0';
+
+      /* The filetype is not stored in the dirent.  Read the inode to
+        find out the filetype.  This *REALLY* sucks.  */
+      grub_minix_read_inode (data, grub_le_to_cpu16 (ino));
+      info.dir = ((GRUB_MINIX_INODE_MODE (data)
+                  & GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR);
+      if (hook (filename, &info) ? 1 : 0)
+       break;
+
+      /* Load the old inode back in.  */
+      grub_minix_read_inode (data, dirino);
+
+      pos += sizeof (ino) + data->filename_size;
+    }
+
+ fail:
+  grub_free (data);
+  return grub_errno;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_minix_open (struct grub_file *file, const char *name)
+{
+  struct grub_minix_data *data;
+  data = grub_minix_mount (file->device->disk);
+  if (!data)
+    return grub_errno;
+
+  /* Open the inode op the root directory.  */
+  grub_minix_read_inode (data, GRUB_MINIX_ROOT_INODE);
+  if (grub_errno)
+    {
+      grub_free (data);
+      return grub_errno;
+    }
+
+  if (!name || name[0] != '/')
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
+      return grub_errno;
+    }
+
+  /* Traverse the directory tree to the node that should be
+     opened.  */
+  grub_minix_find_file (data, name);
+  if (grub_errno)
+    {
+      grub_free (data);
+      return grub_errno;
+    }
+
+  file->data = data;
+  file->size = GRUB_MINIX_INODE_SIZE (data);
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_ssize_t
+grub_minix_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_minix_data *data =
+    (struct grub_minix_data *) file->data;
+
+  return grub_minix_read_file (data, file->read_hook, file->offset, len, buf);
+}
+
+
+static grub_err_t
+grub_minix_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_err_t
+grub_minix_label (grub_device_t device __attribute ((unused)),
+               char **label __attribute ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
+
+\f
+static struct grub_fs grub_minix_fs =
+  {
+    .name = "minix",
+    .dir = grub_minix_dir,
+    .open = grub_minix_open,
+    .read = grub_minix_read,
+    .close = grub_minix_close,
+    .label = grub_minix_label,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(minix)
+{
+  grub_fs_register (&grub_minix_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(minix)
+{
+  grub_fs_unregister (&grub_minix_fs);
+}
diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c
new file mode 100644 (file)
index 0000000..7e0415d
--- /dev/null
@@ -0,0 +1,1133 @@
+/* 
+ *  nilfs2.c - New Implementation of Log filesystem 
+ *
+ *  Written by Jiro SEKIBA <jir@unicus.jp>
+ *
+ *  Copyright (C) 2003,2004,2005,2007,2008,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/* Filetype information as used in inodes.  */
+#define FILETYPE_INO_MASK      0170000
+#define FILETYPE_INO_REG       0100000
+#define FILETYPE_INO_DIRECTORY 0040000
+#define FILETYPE_INO_SYMLINK   0120000
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+
+#define NILFS_INODE_BMAP_SIZE  7
+
+#define NILFS_SUPORT_REV       2
+
+/* Magic value used to identify an nilfs2 filesystem.  */
+#define        NILFS2_SUPER_MAGIC      0x3434
+/* nilfs btree node flag.  */
+#define NILFS_BTREE_NODE_ROOT   0x01
+
+/* nilfs btree node level. */
+#define NILFS_BTREE_LEVEL_DATA          0
+#define NILFS_BTREE_LEVEL_NODE_MIN      (NILFS_BTREE_LEVEL_DATA + 1)
+#define NILFS_BTREE_LEVEL_MAX           14
+
+struct grub_nilfs2_inode
+{
+  grub_uint64_t i_blocks;
+  grub_uint64_t i_size;
+  grub_uint64_t i_ctime;
+  grub_uint64_t i_mtime;
+  grub_uint32_t i_ctime_nsec;
+  grub_uint32_t i_mtime_nsec;
+  grub_uint32_t i_uid;
+  grub_uint32_t i_gid;
+  grub_uint16_t i_mode;
+  grub_uint16_t i_links_count;
+  grub_uint32_t i_flags;
+  grub_uint64_t i_bmap[NILFS_INODE_BMAP_SIZE];
+#define i_device_code  i_bmap[0]
+  grub_uint64_t i_xattr;
+  grub_uint32_t i_generation;
+  grub_uint32_t i_pad;
+};
+
+struct grub_nilfs2_super_root
+{
+  grub_uint32_t sr_sum;
+  grub_uint16_t sr_bytes;
+  grub_uint16_t sr_flags;
+  grub_uint64_t sr_nongc_ctime;
+  struct grub_nilfs2_inode sr_dat;
+  struct grub_nilfs2_inode sr_cpfile;
+  struct grub_nilfs2_inode sr_sufile;
+};
+
+struct grub_nilfs2_super_block
+{
+  grub_uint32_t s_rev_level;
+  grub_uint16_t s_minor_rev_level;
+  grub_uint16_t s_magic;
+  grub_uint16_t s_bytes;
+  grub_uint16_t s_flags;
+  grub_uint32_t s_crc_seed;
+  grub_uint32_t s_sum;
+  grub_uint32_t s_log_block_size;
+  grub_uint64_t s_nsegments;
+  grub_uint64_t s_dev_size;
+  grub_uint64_t s_first_data_block;
+  grub_uint32_t s_blocks_per_segment;
+  grub_uint32_t s_r_segments_percentage;
+  grub_uint64_t s_last_cno;
+  grub_uint64_t s_last_pseg;
+  grub_uint64_t s_last_seq;
+  grub_uint64_t s_free_blocks_count;
+  grub_uint64_t s_ctime;
+  grub_uint64_t s_mtime;
+  grub_uint64_t s_wtime;
+  grub_uint16_t s_mnt_count;
+  grub_uint16_t s_max_mnt_count;
+  grub_uint16_t s_state;
+  grub_uint16_t s_errors;
+  grub_uint64_t s_lastcheck;
+  grub_uint32_t s_checkinterval;
+  grub_uint32_t s_creator_os;
+  grub_uint16_t s_def_resuid;
+  grub_uint16_t s_def_resgid;
+  grub_uint32_t s_first_ino;
+  grub_uint16_t s_inode_size;
+  grub_uint16_t s_dat_entry_size;
+  grub_uint16_t s_checkpoint_size;
+  grub_uint16_t s_segment_usage_size;
+  grub_uint8_t s_uuid[16];
+  char s_volume_name[16];
+  char s_last_mounted[64];
+  grub_uint32_t s_c_interval;
+  grub_uint32_t s_c_block_max;
+  grub_uint32_t s_reserved[192];
+};
+
+struct grub_nilfs2_dir_entry
+{
+  grub_uint64_t inode;
+  grub_uint16_t rec_len;
+  grub_uint8_t name_len;
+  grub_uint8_t file_type;
+#if 0                          /* followed by file name. */
+  char name[NILFS_NAME_LEN];
+  char pad;
+#endif
+} __attribute__ ((packed));
+
+enum
+{
+  NILFS_FT_UNKNOWN,
+  NILFS_FT_REG_FILE,
+  NILFS_FT_DIR,
+  NILFS_FT_CHRDEV,
+  NILFS_FT_BLKDEV,
+  NILFS_FT_FIFO,
+  NILFS_FT_SOCK,
+  NILFS_FT_SYMLINK,
+  NILFS_FT_MAX
+};
+
+struct grub_nilfs2_finfo
+{
+  grub_uint64_t fi_ino;
+  grub_uint64_t fi_cno;
+  grub_uint32_t fi_nblocks;
+  grub_uint32_t fi_ndatablk;
+};
+
+struct grub_nilfs2_binfo_v
+{
+  grub_uint64_t bi_vblocknr;
+  grub_uint64_t bi_blkoff;
+};
+
+struct grub_nilfs2_binfo_dat
+{
+  grub_uint64_t bi_blkoff;
+  grub_uint8_t bi_level;
+  grub_uint8_t bi_pad[7];
+};
+
+union grub_nilfs2_binfo
+{
+  struct grub_nilfs2_binfo_v bi_v;
+  struct grub_nilfs2_binfo_dat bi_dat;
+};
+
+struct grub_nilfs2_segment_summary
+{
+  grub_uint32_t ss_datasum;
+  grub_uint32_t ss_sumsum;
+  grub_uint32_t ss_magic;
+  grub_uint16_t ss_bytes;
+  grub_uint16_t ss_flags;
+  grub_uint64_t ss_seq;
+  grub_uint64_t ss_create;
+  grub_uint64_t ss_next;
+  grub_uint32_t ss_nblocks;
+  grub_uint32_t ss_nfinfo;
+  grub_uint32_t ss_sumbytes;
+  grub_uint32_t ss_pad;
+};
+
+struct grub_nilfs2_btree_node
+{
+  grub_uint8_t bn_flags;
+  grub_uint8_t bn_level;
+  grub_uint16_t bn_nchildren;
+  grub_uint32_t bn_pad;
+};
+
+struct grub_nilfs2_palloc_group_desc
+{
+  grub_uint32_t pg_nfrees;
+};
+
+struct grub_nilfs2_dat_entry
+{
+  grub_uint64_t de_blocknr;
+  grub_uint64_t de_start;
+  grub_uint64_t de_end;
+  grub_uint64_t de_rsv;
+};
+
+struct grub_nilfs2_snapshot_list
+{
+  grub_uint64_t ssl_next;
+  grub_uint64_t ssl_prev;
+};
+
+struct grub_nilfs2_cpfile_header
+{
+  grub_uint64_t ch_ncheckpoints;
+  grub_uint64_t ch_nsnapshots;
+  struct grub_nilfs2_snapshot_list ch_snapshot_list;
+};
+
+struct grub_nilfs2_checkpoint
+{
+  grub_uint32_t cp_flags;
+  grub_uint32_t cp_checkpoints_count;
+  struct grub_nilfs2_snapshot_list cp_snapshot_list;
+  grub_uint64_t cp_cno;
+  grub_uint64_t cp_create;
+  grub_uint64_t cp_nblk_inc;
+  grub_uint64_t cp_inodes_count;
+  grub_uint64_t cp_blocks_count;
+  struct grub_nilfs2_inode cp_ifile_inode;
+};
+
+
+#define NILFS_BMAP_LARGE       0x1
+#define NILFS_BMAP_SIZE        (NILFS_INODE_BMAP_SIZE * sizeof(grub_uint64_t))
+
+/* nilfs extra padding for nonroot btree node. */
+#define NILFS_BTREE_NODE_EXTRA_PAD_SIZE (sizeof(grub_uint64_t))
+#define NILFS_BTREE_ROOT_SIZE  NILFS_BMAP_SIZE
+#define NILFS_BTREE_ROOT_NCHILDREN_MAX \
+ ((NILFS_BTREE_ROOT_SIZE - sizeof(struct nilfs_btree_node)) / \
+  (sizeof(grub_uint64_t) + sizeof(grub_uint64_t)) )
+
+
+struct grub_fshelp_node
+{
+  struct grub_nilfs2_data *data;
+  struct grub_nilfs2_inode inode;
+  grub_uint64_t ino;
+  int inode_read;
+};
+
+struct grub_nilfs2_data
+{
+  struct grub_nilfs2_super_block sblock;
+  struct grub_nilfs2_super_root sroot;
+  struct grub_nilfs2_inode ifile;
+  grub_disk_t disk;
+  struct grub_nilfs2_inode *inode;
+  struct grub_fshelp_node diropen;
+};
+
+/* Log2 size of nilfs2 block in 512 blocks.  */
+#define LOG2_NILFS2_BLOCK_SIZE(data)                   \
+       (grub_le_to_cpu32 (data->sblock.s_log_block_size) + 1)
+
+/* Log2 size of nilfs2 block in bytes.  */
+#define LOG2_BLOCK_SIZE(data)                                  \
+       (grub_le_to_cpu32 (data->sblock.s_log_block_size) + 10)
+
+/* The size of an nilfs2 block in bytes.  */
+#define NILFS2_BLOCK_SIZE(data)                (1 << LOG2_BLOCK_SIZE (data))
+
+static grub_uint64_t
+grub_nilfs2_dat_translate (struct grub_nilfs2_data *data, grub_uint64_t key);
+static grub_dl_t my_mod;
+\f
+
+
+static inline unsigned long
+grub_nilfs2_palloc_entries_per_group (struct grub_nilfs2_data *data)
+{
+  return 1UL << (LOG2_BLOCK_SIZE (data) + 3);
+}
+
+static inline grub_uint64_t
+grub_nilfs2_palloc_group (struct grub_nilfs2_data *data,
+                         grub_uint64_t nr, grub_uint32_t * offset)
+{
+  return grub_divmod64 (nr, grub_nilfs2_palloc_entries_per_group (data),
+                       offset);
+}
+
+static inline grub_uint32_t
+grub_nilfs2_palloc_groups_per_desc_block (struct grub_nilfs2_data *data)
+{
+  return NILFS2_BLOCK_SIZE (data) /
+    sizeof (struct grub_nilfs2_palloc_group_desc);
+}
+
+static inline grub_uint32_t
+grub_nilfs2_entries_per_block (struct grub_nilfs2_data *data,
+                              unsigned long entry_size)
+{
+  return NILFS2_BLOCK_SIZE (data) / entry_size;
+}
+
+
+static inline grub_uint32_t
+grub_nilfs2_blocks_per_group (struct grub_nilfs2_data *data,
+                             unsigned long entry_size)
+{
+  return grub_div_roundup (grub_nilfs2_palloc_entries_per_group (data),
+                          grub_nilfs2_entries_per_block (data,
+                                                         entry_size)) + 1;
+}
+
+static inline grub_uint32_t
+grub_nilfs2_blocks_per_desc_block (struct grub_nilfs2_data *data,
+                                  unsigned long entry_size)
+{
+  return grub_nilfs2_palloc_groups_per_desc_block (data) *
+    grub_nilfs2_blocks_per_group (data, entry_size) + 1;
+}
+
+static inline grub_uint32_t
+grub_nilfs2_palloc_desc_block_offset (struct grub_nilfs2_data *data,
+                                     unsigned long group,
+                                     unsigned long entry_size)
+{
+  grub_uint32_t desc_block =
+    group / grub_nilfs2_palloc_groups_per_desc_block (data);
+  return desc_block * grub_nilfs2_blocks_per_desc_block (data, entry_size);
+}
+
+static inline grub_uint32_t
+grub_nilfs2_palloc_bitmap_block_offset (struct grub_nilfs2_data *data,
+                                       unsigned long group,
+                                       unsigned long entry_size)
+{
+  unsigned long desc_offset = group %
+    grub_nilfs2_palloc_groups_per_desc_block (data);
+
+  return grub_nilfs2_palloc_desc_block_offset (data, group, entry_size) + 1 +
+    desc_offset * grub_nilfs2_blocks_per_group (data, entry_size);
+}
+
+static inline grub_uint32_t
+grub_nilfs2_palloc_entry_offset (struct grub_nilfs2_data *data,
+                                grub_uint64_t nr, unsigned long entry_size)
+{
+  unsigned long group;
+  grub_uint32_t group_offset;
+
+  group = grub_nilfs2_palloc_group (data, nr, &group_offset);
+
+  return grub_nilfs2_palloc_bitmap_block_offset (data, group,
+                                                entry_size) + 1 +
+    group_offset / grub_nilfs2_entries_per_block (data, entry_size);
+
+}
+
+static inline struct grub_nilfs2_btree_node *
+grub_nilfs2_btree_get_root (struct grub_nilfs2_inode *inode)
+{
+  return (struct grub_nilfs2_btree_node *) &inode->i_bmap[0];
+}
+
+static inline int
+grub_nilfs2_btree_get_level (struct grub_nilfs2_btree_node *node)
+{
+  return node->bn_level;
+}
+
+static inline grub_uint64_t *
+grub_nilfs2_btree_node_dkeys (struct grub_nilfs2_btree_node *node)
+{
+  return (grub_uint64_t *) ((char *) (node + 1) +
+                           ((node->bn_flags & NILFS_BTREE_NODE_ROOT) ?
+                            0 : NILFS_BTREE_NODE_EXTRA_PAD_SIZE));
+}
+
+static inline grub_uint64_t
+grub_nilfs2_btree_node_get_key (struct grub_nilfs2_btree_node *node,
+                               int index)
+{
+  return grub_le_to_cpu64 (*(grub_nilfs2_btree_node_dkeys (node) + index));
+}
+
+static inline int
+grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node,
+                              grub_uint64_t key, int *indexp)
+{
+  grub_uint64_t nkey;
+  int index, low, high, s;
+
+  low = 0;
+  high = grub_le_to_cpu16 (node->bn_nchildren) - 1;
+  index = 0;
+  s = 0;
+  while (low <= high)
+    {
+      index = (low + high) / 2;
+      nkey = grub_nilfs2_btree_node_get_key (node, index);
+      if (nkey == key)
+       {
+         *indexp = index;
+         return 1;
+       }
+      else if (nkey < key)
+       {
+         low = index + 1;
+         s = -1;
+       }
+      else
+       {
+         high = index - 1;
+         s = 1;
+       }
+    }
+
+  if (node->bn_level > NILFS_BTREE_LEVEL_NODE_MIN)
+    {
+      if (s > 0 && index > 0)
+       index--;
+    }
+  else if (s < 0)
+    index++;
+
+  *indexp = index;
+  return s == 0;
+}
+
+static inline int
+grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data,
+                                     struct grub_nilfs2_btree_node *node)
+{
+  int node_children_max = ((NILFS2_BLOCK_SIZE (data) -
+                           sizeof (struct grub_nilfs2_btree_node) -
+                           NILFS_BTREE_NODE_EXTRA_PAD_SIZE) /
+                          (sizeof (grub_uint64_t) + sizeof (grub_uint64_t)));
+
+  return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max;
+}
+
+static inline grub_uint64_t *
+grub_nilfs2_btree_node_dptrs (struct grub_nilfs2_data *data,
+                             struct grub_nilfs2_btree_node *node)
+{
+  return (grub_uint64_t *) (grub_nilfs2_btree_node_dkeys (node) +
+                           grub_nilfs2_btree_node_nchildren_max (data,
+                                                                 node));
+}
+
+static inline grub_uint64_t
+grub_nilfs2_btree_node_get_ptr (struct grub_nilfs2_data *data,
+                               struct grub_nilfs2_btree_node *node,
+                               int index)
+{
+  return
+    grub_le_to_cpu64 (*(grub_nilfs2_btree_node_dptrs (data, node) + index));
+}
+
+static inline int
+grub_nilfs2_btree_get_nonroot_node (struct grub_nilfs2_data *data,
+                                   grub_uint64_t ptr, void *block)
+{
+  grub_disk_t disk = data->disk;
+  unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
+
+  return grub_disk_read (disk, ptr * nilfs2_block_count, 0,
+                        NILFS2_BLOCK_SIZE (data), block);
+}
+
+static grub_uint64_t
+grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data,
+                         struct grub_nilfs2_inode *inode,
+                         grub_uint64_t key, int need_translate)
+{
+  struct grub_nilfs2_btree_node *node;
+  unsigned char block[NILFS2_BLOCK_SIZE (data)];
+  grub_uint64_t ptr;
+  int level, found, index;
+
+  node = grub_nilfs2_btree_get_root (inode);
+  level = grub_nilfs2_btree_get_level (node);
+
+  found = grub_nilfs2_btree_node_lookup (node, key, &index);
+  ptr = grub_nilfs2_btree_node_get_ptr (data, node, index);
+  if (need_translate)
+    ptr = grub_nilfs2_dat_translate (data, ptr);
+
+  for (level--; level >= NILFS_BTREE_LEVEL_NODE_MIN; level--)
+    {
+      grub_nilfs2_btree_get_nonroot_node (data, ptr, block);
+      if (grub_errno)
+       {
+         return -1;
+       }
+      node = (struct grub_nilfs2_btree_node *) block;
+
+      if (node->bn_level != level)
+       {
+         grub_error (GRUB_ERR_BAD_FS, "btree level mismatch\n");
+         return -1;
+       }
+
+      if (!found)
+       found = grub_nilfs2_btree_node_lookup (node, key, &index);
+      else
+       index = 0;
+
+      if (index < grub_nilfs2_btree_node_nchildren_max (data, node))
+       {
+         ptr = grub_nilfs2_btree_node_get_ptr (data, node, index);
+         if (need_translate)
+           ptr = grub_nilfs2_dat_translate (data, ptr);
+       }
+      else
+       {
+         grub_error (GRUB_ERR_BAD_FS, "btree corruption\n");
+         return -1;
+       }
+    }
+
+  if (!found)
+    return -1;
+
+  return ptr;
+}
+
+static inline grub_uint64_t
+grub_nilfs2_direct_lookup (struct grub_nilfs2_inode *inode, grub_uint64_t key)
+{
+  return grub_le_to_cpu64 (inode->i_bmap[1 + key]);
+}
+
+static inline grub_uint64_t
+grub_nilfs2_bmap_lookup (struct grub_nilfs2_data *data,
+                        struct grub_nilfs2_inode *inode,
+                        grub_uint64_t key, int need_translate)
+{
+  struct grub_nilfs2_btree_node *root = grub_nilfs2_btree_get_root (inode);
+  if (root->bn_flags & NILFS_BMAP_LARGE)
+    return grub_nilfs2_btree_lookup (data, inode, key, need_translate);
+  else
+    {
+      grub_uint64_t ptr;
+      ptr = grub_nilfs2_direct_lookup (inode, key);
+      if (need_translate)
+       ptr = grub_nilfs2_dat_translate (data, ptr);
+      return ptr;
+    }
+}
+
+static grub_uint64_t
+grub_nilfs2_dat_translate (struct grub_nilfs2_data *data, grub_uint64_t key)
+{
+  struct grub_nilfs2_dat_entry entry;
+  grub_disk_t disk = data->disk;
+  grub_uint64_t pptr;
+  grub_uint32_t blockno, offset;
+  unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
+
+  blockno = grub_nilfs2_palloc_entry_offset (data, key,
+                                            sizeof (struct
+                                                    grub_nilfs2_dat_entry));
+
+  grub_divmod64 (key * sizeof (struct grub_nilfs2_dat_entry),
+                NILFS2_BLOCK_SIZE (data), &offset);
+
+  pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_dat, blockno, 0);
+  if (pptr == (grub_uint64_t) - 1)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "btree lookup failure");
+      return -1;
+    }
+
+  grub_disk_read (disk, pptr * nilfs2_block_count, offset,
+                 sizeof (struct grub_nilfs2_dat_entry), &entry);
+
+  return grub_le_to_cpu64 (entry.de_blocknr);
+}
+
+
+static grub_disk_addr_t
+grub_nilfs2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+{
+  struct grub_nilfs2_data *data = node->data;
+  struct grub_nilfs2_inode *inode = &node->inode;
+  grub_uint64_t pptr = -1;
+
+  pptr = grub_nilfs2_bmap_lookup (data, inode, fileblock, 1);
+  if (pptr == (grub_uint64_t) - 1)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "btree lookup failure");
+      return -1;
+    }
+
+  return pptr;
+}
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_nilfs2_read_file (grub_fshelp_node_t node,
+                      void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
+                                                          sector,
+                                                          unsigned offset,
+                                                          unsigned length),
+                      int pos, grub_size_t len, char *buf)
+{
+  return grub_fshelp_read_file (node->data->disk, node, read_hook,
+                               pos, len, buf, grub_nilfs2_read_block,
+                               grub_le_to_cpu64 (node->inode.i_size),
+                               LOG2_NILFS2_BLOCK_SIZE (node->data));
+
+}
+
+static grub_err_t
+grub_nilfs2_read_checkpoint (struct grub_nilfs2_data *data,
+                            grub_uint64_t cpno,
+                            struct grub_nilfs2_checkpoint *cpp)
+{
+  grub_uint64_t blockno;
+  grub_uint32_t offset;
+  grub_uint64_t pptr;
+  grub_disk_t disk = data->disk;
+  unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
+
+  /* Assume sizeof(struct grub_nilfs2_cpfile_header) < 
+     sizeof(struct grub_nilfs2_checkpoint).
+   */
+  blockno = grub_divmod64 (cpno, NILFS2_BLOCK_SIZE (data) /
+                          sizeof (struct grub_nilfs2_checkpoint), &offset);
+
+  pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_cpfile, blockno, 1);
+  if (pptr == (grub_uint64_t) - 1)
+    {
+      return grub_error (GRUB_ERR_BAD_FS, "btree lookup failure");
+    }
+
+  return grub_disk_read (disk, pptr * nilfs2_block_count,
+                        offset * sizeof (struct grub_nilfs2_checkpoint),
+                        sizeof (struct grub_nilfs2_checkpoint), cpp);
+}
+
+static inline grub_err_t
+grub_nilfs2_read_last_checkpoint (struct grub_nilfs2_data *data,
+                                 struct grub_nilfs2_checkpoint *cpp)
+{
+  return grub_nilfs2_read_checkpoint (data,
+                                     grub_le_to_cpu64 (data->
+                                                       sblock.s_last_cno),
+                                     cpp);
+}
+
+/* Read the inode INO for the file described by DATA into INODE.  */
+static grub_err_t
+grub_nilfs2_read_inode (struct grub_nilfs2_data *data,
+                       grub_uint64_t ino, struct grub_nilfs2_inode *inodep)
+{
+  grub_uint64_t blockno;
+  unsigned int offset;
+  grub_uint64_t pptr;
+  grub_disk_t disk = data->disk;
+  unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
+
+  blockno = grub_nilfs2_palloc_entry_offset (data, ino,
+                                            sizeof (struct
+                                                    grub_nilfs2_inode));
+
+  grub_divmod64 (sizeof (struct grub_nilfs2_inode) * ino,
+                NILFS2_BLOCK_SIZE (data), &offset);
+  pptr = grub_nilfs2_bmap_lookup (data, &data->ifile, blockno, 1);
+  if (pptr == (grub_uint64_t) - 1)
+    {
+      return grub_error (GRUB_ERR_BAD_FS, "btree lookup failure");
+    }
+
+  return grub_disk_read (disk, pptr * nilfs2_block_count, offset,
+                        sizeof (struct grub_nilfs2_inode), inodep);
+}
+
+static int
+grub_nilfs2_valid_sb (struct grub_nilfs2_super_block *sbp)
+{
+  if (grub_le_to_cpu16 (sbp->s_magic) != NILFS2_SUPER_MAGIC)
+    return 0;
+
+  if (grub_le_to_cpu32 (sbp->s_rev_level) != NILFS_SUPORT_REV)
+    return 0;
+
+  return 1;
+}
+
+static struct grub_nilfs2_data *
+grub_nilfs2_mount (grub_disk_t disk)
+{
+  struct grub_nilfs2_data *data;
+  struct grub_nilfs2_segment_summary ss;
+  struct grub_nilfs2_checkpoint last_checkpoint;
+  grub_uint64_t last_pseg;
+  grub_uint32_t nblocks;
+  unsigned int nilfs2_block_count;
+
+  data = grub_malloc (sizeof (struct grub_nilfs2_data));
+  if (!data)
+    return 0;
+
+  /* Read the superblock.  */
+  grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_block),
+                 &data->sblock);
+  if (grub_errno)
+    goto fail;
+
+  /* Make sure this is an nilfs2 filesystem.  */
+  if (!grub_nilfs2_valid_sb (&data->sblock))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem");
+      goto fail;
+    }
+
+  nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
+
+  /* Read the last segment summary. */
+  last_pseg = grub_le_to_cpu64 (data->sblock.s_last_pseg);
+  grub_disk_read (disk, last_pseg * nilfs2_block_count, 0,
+                 sizeof (struct grub_nilfs2_segment_summary), &ss);
+
+  if (grub_errno)
+    goto fail;
+
+  /* Read the super root block. */
+  nblocks = grub_le_to_cpu32 (ss.ss_nblocks);
+  grub_disk_read (disk, (last_pseg + (nblocks - 1)) * nilfs2_block_count, 0,
+                 sizeof (struct grub_nilfs2_super_root), &data->sroot);
+
+  if (grub_errno)
+    goto fail;
+
+  data->disk = disk;
+
+  grub_nilfs2_read_last_checkpoint (data, &last_checkpoint);
+
+  if (grub_errno)
+    goto fail;
+
+  grub_memcpy (&data->ifile, &last_checkpoint.cp_ifile_inode,
+              sizeof (struct grub_nilfs2_inode));
+
+  data->diropen.data = data;
+  data->diropen.ino = 2;
+  data->diropen.inode_read = 1;
+  data->inode = &data->diropen.inode;
+
+  grub_nilfs2_read_inode (data, 2, data->inode);
+
+  return data;
+
+fail:
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem");
+
+  grub_free (data);
+  return 0;
+}
+
+static char *
+grub_nilfs2_read_symlink (grub_fshelp_node_t node)
+{
+  char *symlink;
+  struct grub_fshelp_node *diro = node;
+
+  if (!diro->inode_read)
+    {
+      grub_nilfs2_read_inode (diro->data, diro->ino, &diro->inode);
+      if (grub_errno)
+       return 0;
+    }
+
+  symlink = grub_malloc (grub_le_to_cpu64 (diro->inode.i_size) + 1);
+  if (!symlink)
+    return 0;
+
+  grub_nilfs2_read_file (diro, 0, 0,
+                        grub_le_to_cpu64 (diro->inode.i_size), symlink);
+  if (grub_errno)
+    {
+      grub_free (symlink);
+      return 0;
+    }
+
+  symlink[grub_le_to_cpu64 (diro->inode.i_size)] = '\0';
+  return symlink;
+}
+
+static int
+grub_nilfs2_iterate_dir (grub_fshelp_node_t dir,
+                        int NESTED_FUNC_ATTR
+                        (*hook) (const char *filename,
+                                 enum grub_fshelp_filetype filetype,
+                                 grub_fshelp_node_t node))
+{
+  unsigned int fpos = 0;
+  struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
+
+  if (!diro->inode_read)
+    {
+      grub_nilfs2_read_inode (diro->data, diro->ino, &diro->inode);
+      if (grub_errno)
+       return 0;
+    }
+
+  /* Iterate files.  */
+  while (fpos < grub_le_to_cpu64 (diro->inode.i_size))
+    {
+      struct grub_nilfs2_dir_entry dirent;
+
+      grub_nilfs2_read_file (diro, 0, fpos,
+                            sizeof (struct grub_nilfs2_dir_entry),
+                            (char *) &dirent);
+      if (grub_errno)
+       return 0;
+
+      if (dirent.rec_len == 0)
+       return 0;
+
+      if (dirent.name_len != 0)
+       {
+         char filename[dirent.name_len + 1];
+         struct grub_fshelp_node *fdiro;
+         enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN;
+
+         grub_nilfs2_read_file (diro, 0,
+                                fpos + sizeof (struct grub_nilfs2_dir_entry),
+                                dirent.name_len, filename);
+         if (grub_errno)
+           return 0;
+
+         fdiro = grub_malloc (sizeof (struct grub_fshelp_node));
+         if (!fdiro)
+           return 0;
+
+         fdiro->data = diro->data;
+         fdiro->ino = grub_le_to_cpu64 (dirent.inode);
+
+         filename[dirent.name_len] = '\0';
+
+         if (dirent.file_type != NILFS_FT_UNKNOWN)
+           {
+             fdiro->inode_read = 0;
+
+             if (dirent.file_type == NILFS_FT_DIR)
+               type = GRUB_FSHELP_DIR;
+             else if (dirent.file_type == NILFS_FT_SYMLINK)
+               type = GRUB_FSHELP_SYMLINK;
+             else if (dirent.file_type == NILFS_FT_REG_FILE)
+               type = GRUB_FSHELP_REG;
+           }
+         else
+           {
+             /* The filetype can not be read from the dirent, read
+                the inode to get more information.  */
+             grub_nilfs2_read_inode (diro->data,
+                                     grub_le_to_cpu64 (dirent.inode),
+                                     &fdiro->inode);
+             if (grub_errno)
+               {
+                 grub_free (fdiro);
+                 return 0;
+               }
+
+             fdiro->inode_read = 1;
+
+             if ((grub_le_to_cpu16 (fdiro->inode.i_mode)
+                  & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY)
+               type = GRUB_FSHELP_DIR;
+             else if ((grub_le_to_cpu16 (fdiro->inode.i_mode)
+                       & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK)
+               type = GRUB_FSHELP_SYMLINK;
+             else if ((grub_le_to_cpu16 (fdiro->inode.i_mode)
+                       & FILETYPE_INO_MASK) == FILETYPE_INO_REG)
+               type = GRUB_FSHELP_REG;
+           }
+
+         if (hook (filename, type, fdiro))
+           return 1;
+       }
+
+      fpos += grub_le_to_cpu16 (dirent.rec_len);
+    }
+
+  return 0;
+}
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_nilfs2_open (struct grub_file *file, const char *name)
+{
+  struct grub_nilfs2_data *data = NULL;
+  struct grub_fshelp_node *fdiro = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_nilfs2_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (name, &data->diropen, &fdiro,
+                        grub_nilfs2_iterate_dir, grub_nilfs2_read_symlink,
+                        GRUB_FSHELP_REG);
+  if (grub_errno)
+    goto fail;
+
+  if (!fdiro->inode_read)
+    {
+      grub_nilfs2_read_inode (data, fdiro->ino, &fdiro->inode);
+      if (grub_errno)
+       goto fail;
+    }
+
+  grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_nilfs2_inode));
+  grub_free (fdiro);
+
+  file->size = grub_le_to_cpu64 (data->inode->i_size);
+  file->data = data;
+  file->offset = 0;
+
+  return 0;
+
+fail:
+  if (fdiro != &data->diropen)
+    grub_free (fdiro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_nilfs2_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Read LEN bytes data from FILE into BUF.  */
+static grub_ssize_t
+grub_nilfs2_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_nilfs2_data *data = (struct grub_nilfs2_data *) file->data;
+
+  return grub_nilfs2_read_file (&data->diropen, file->read_hook,
+                               file->offset, len, buf);
+}
+
+static grub_err_t
+grub_nilfs2_dir (grub_device_t device, const char *path,
+                int (*hook) (const char *filename,
+                             const struct grub_dirhook_info * info))
+{
+  struct grub_nilfs2_data *data = 0;
+  struct grub_fshelp_node *fdiro = 0;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+                                    enum grub_fshelp_filetype filetype,
+                                    grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node)
+  {
+    struct grub_dirhook_info info;
+    grub_memset (&info, 0, sizeof (info));
+    if (!node->inode_read)
+      {
+       grub_nilfs2_read_inode (data, node->ino, &node->inode);
+       if (!grub_errno)
+         node->inode_read = 1;
+       grub_errno = GRUB_ERR_NONE;
+      }
+    if (node->inode_read)
+      {
+       info.mtimeset = 1;
+       info.mtime = grub_le_to_cpu64 (node->inode.i_mtime);
+      }
+
+    info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+    grub_free (node);
+    return hook (filename, &info);
+  }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_nilfs2_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (path, &data->diropen, &fdiro,
+                        grub_nilfs2_iterate_dir, grub_nilfs2_read_symlink,
+                        GRUB_FSHELP_DIR);
+  if (grub_errno)
+    goto fail;
+
+  grub_nilfs2_iterate_dir (fdiro, iterate);
+
+fail:
+  if (fdiro != &data->diropen)
+    grub_free (fdiro);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_nilfs2_label (grub_device_t device, char **label)
+{
+  struct grub_nilfs2_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_nilfs2_mount (disk);
+  if (data)
+    *label = grub_strndup (data->sblock.s_volume_name, 14);
+  else
+    *label = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_nilfs2_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_nilfs2_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_nilfs2_mount (disk);
+  if (data)
+    {
+      *uuid =
+       grub_xasprintf
+       ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%0x-%02x%02x%02x%02x%02x%02x",
+        data->sblock.s_uuid[0], data->sblock.s_uuid[1],
+        data->sblock.s_uuid[2], data->sblock.s_uuid[3],
+        data->sblock.s_uuid[4], data->sblock.s_uuid[5],
+        data->sblock.s_uuid[6], data->sblock.s_uuid[7],
+        data->sblock.s_uuid[8], data->sblock.s_uuid[9],
+        data->sblock.s_uuid[10], data->sblock.s_uuid[11],
+        data->sblock.s_uuid[12], data->sblock.s_uuid[13],
+        data->sblock.s_uuid[14], data->sblock.s_uuid[15]);
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+/* Get mtime.  */
+static grub_err_t
+grub_nilfs2_mtime (grub_device_t device, grub_int32_t * tm)
+{
+  struct grub_nilfs2_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_nilfs2_mount (disk);
+  if (!data)
+    *tm = 0;
+  else
+    *tm = (grub_int32_t) grub_le_to_cpu64 (data->sblock.s_mtime);
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+\f
+
+
+static struct grub_fs grub_nilfs2_fs = {
+  .name = "nilfs2",
+  .dir = grub_nilfs2_dir,
+  .open = grub_nilfs2_open,
+  .read = grub_nilfs2_read,
+  .close = grub_nilfs2_close,
+  .label = grub_nilfs2_label,
+  .uuid = grub_nilfs2_uuid,
+  .mtime = grub_nilfs2_mtime,
+#ifdef GRUB_UTIL
+  .reserved_first_sector = 1,
+#endif
+  .next = 0
+};
+
+GRUB_MOD_INIT (nilfs2)
+{
+  grub_fs_register (&grub_nilfs2_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI (nilfs2)
+{
+  grub_fs_unregister (&grub_nilfs2_fs);
+}
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
new file mode 100644 (file)
index 0000000..dd041e2
--- /dev/null
@@ -0,0 +1,1111 @@
+/* ntfs.c - NTFS filesystem */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008,2009 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/fshelp.h>
+#include <grub/ntfs.h>
+#include <grub/charset.h>
+
+static grub_dl_t my_mod;
+
+ntfscomp_func_t grub_ntfscomp_func;
+
+static grub_err_t
+fixup (struct grub_ntfs_data *data, char *buf, int len, char *magic)
+{
+  int ss;
+  char *pu;
+  grub_uint16_t us;
+
+  if (grub_memcmp (buf, magic, 4))
+    return grub_error (GRUB_ERR_BAD_FS, "%s label not found", magic);
+
+  ss = u16at (buf, 6) - 1;
+  if (ss * (int) data->blocksize != len * GRUB_DISK_SECTOR_SIZE)
+    return grub_error (GRUB_ERR_BAD_FS, "size not match",
+                      ss * (int) data->blocksize,
+                      len * GRUB_DISK_SECTOR_SIZE);
+  pu = buf + u16at (buf, 4);
+  us = u16at (pu, 0);
+  buf -= 2;
+  while (ss > 0)
+    {
+      buf += data->blocksize;
+      pu += 2;
+      if (u16at (buf, 0) != us)
+       return grub_error (GRUB_ERR_BAD_FS, "fixup signature not match");
+      v16at (buf, 0) = v16at (pu, 0);
+      ss--;
+    }
+
+  return 0;
+}
+
+static grub_err_t read_mft (struct grub_ntfs_data *data, char *buf,
+                           grub_uint32_t mftno);
+static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest,
+                            grub_disk_addr_t ofs, grub_size_t len,
+                            int cached,
+                            void
+                            NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
+                                                           sector,
+                                                           unsigned offset,
+                                                           unsigned length));
+
+static grub_err_t read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
+                            grub_disk_addr_t ofs, grub_size_t len,
+                            int cached,
+                            void
+                            NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t
+                                                           sector,
+                                                           unsigned offset,
+                                                           unsigned length));
+
+static void
+init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft)
+{
+  at->mft = mft;
+  at->flags = (mft == &mft->data->mmft) ? AF_MMFT : 0;
+  at->attr_nxt = mft->buf + u16at (mft->buf, 0x14);
+  at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL;
+}
+
+static void
+free_attr (struct grub_ntfs_attr *at)
+{
+  grub_free (at->emft_buf);
+  grub_free (at->edat_buf);
+  grub_free (at->sbuf);
+}
+
+static char *
+find_attr (struct grub_ntfs_attr *at, unsigned char attr)
+{
+  if (at->flags & AF_ALST)
+    {
+    retry:
+      while (at->attr_nxt < at->attr_end)
+       {
+         at->attr_cur = at->attr_nxt;
+         at->attr_nxt += u16at (at->attr_cur, 4);
+         if (((unsigned char) *at->attr_cur == attr) || (attr == 0))
+           {
+             char *new_pos;
+
+             if (at->flags & AF_MMFT)
+               {
+                 if ((grub_disk_read
+                      (at->mft->data->disk, v32at (at->attr_cur, 0x10), 0,
+                       512, at->emft_buf))
+                     ||
+                     (grub_disk_read
+                      (at->mft->data->disk, v32at (at->attr_cur, 0x14), 0,
+                       512, at->emft_buf + 512)))
+                   return NULL;
+
+                 if (fixup
+                     (at->mft->data, at->emft_buf, at->mft->data->mft_size,
+                      "FILE"))
+                   return NULL;
+               }
+             else
+               {
+                 if (read_mft (at->mft->data, at->emft_buf,
+                               u32at (at->attr_cur, 0x10)))
+                   return NULL;
+               }
+
+             new_pos = &at->emft_buf[u16at (at->emft_buf, 0x14)];
+             while ((unsigned char) *new_pos != 0xFF)
+               {
+                 if (((unsigned char) *new_pos ==
+                      (unsigned char) *at->attr_cur)
+                     && (u16at (new_pos, 0xE) == u16at (at->attr_cur, 0x18)))
+                   {
+                     return new_pos;
+                   }
+                 new_pos += u16at (new_pos, 4);
+               }
+             grub_error (GRUB_ERR_BAD_FS,
+                         "can\'t find 0x%X in attribute list",
+                         (unsigned char) *at->attr_cur);
+             return NULL;
+           }
+       }
+      return NULL;
+    }
+  at->attr_cur = at->attr_nxt;
+  while ((unsigned char) *at->attr_cur != 0xFF)
+    {
+      at->attr_nxt += u16at (at->attr_cur, 4);
+      if ((unsigned char) *at->attr_cur == AT_ATTRIBUTE_LIST)
+       at->attr_end = at->attr_cur;
+      if (((unsigned char) *at->attr_cur == attr) || (attr == 0))
+       return at->attr_cur;
+      at->attr_cur = at->attr_nxt;
+    }
+  if (at->attr_end)
+    {
+      char *pa;
+
+      at->emft_buf = grub_malloc (at->mft->data->mft_size << BLK_SHR);
+      if (at->emft_buf == NULL)
+       return NULL;
+
+      pa = at->attr_end;
+      if (pa[8])
+       {
+          int n;
+
+          n = ((u32at (pa, 0x30) + GRUB_DISK_SECTOR_SIZE - 1)
+               & (~(GRUB_DISK_SECTOR_SIZE - 1)));
+         at->attr_cur = at->attr_end;
+         at->edat_buf = grub_malloc (n);
+         if (!at->edat_buf)
+           return NULL;
+         if (read_data (at, pa, at->edat_buf, 0, n, 0, 0))
+           {
+             grub_error (GRUB_ERR_BAD_FS,
+                         "fail to read non-resident attribute list");
+             return NULL;
+           }
+         at->attr_nxt = at->edat_buf;
+         at->attr_end = at->edat_buf + u32at (pa, 0x30);
+       }
+      else
+       {
+         at->attr_nxt = at->attr_end + u16at (pa, 0x14);
+         at->attr_end = at->attr_end + u32at (pa, 4);
+       }
+      at->flags |= AF_ALST;
+      while (at->attr_nxt < at->attr_end)
+       {
+         if (((unsigned char) *at->attr_nxt == attr) || (attr == 0))
+           break;
+         at->attr_nxt += u16at (at->attr_nxt, 4);
+       }
+      if (at->attr_nxt >= at->attr_end)
+       return NULL;
+
+      if ((at->flags & AF_MMFT) && (attr == AT_DATA))
+       {
+         at->flags |= AF_GPOS;
+         at->attr_cur = at->attr_nxt;
+         pa = at->attr_cur;
+         v32at (pa, 0x10) = at->mft->data->mft_start;
+         v32at (pa, 0x14) = at->mft->data->mft_start + 1;
+         pa = at->attr_nxt + u16at (pa, 4);
+         while (pa < at->attr_end)
+           {
+             if ((unsigned char) *pa != attr)
+               break;
+             if (read_attr
+                 (at, pa + 0x10,
+                  u32at (pa, 0x10) * (at->mft->data->mft_size << BLK_SHR),
+                  at->mft->data->mft_size << BLK_SHR, 0, 0))
+               return NULL;
+             pa += u16at (pa, 4);
+           }
+         at->attr_nxt = at->attr_cur;
+         at->flags &= ~AF_GPOS;
+       }
+      goto retry;
+    }
+  return NULL;
+}
+
+static char *
+locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft,
+            unsigned char attr)
+{
+  char *pa;
+
+  init_attr (at, mft);
+  if ((pa = find_attr (at, attr)) == NULL)
+    return NULL;
+  if ((at->flags & AF_ALST) == 0)
+    {
+      while (1)
+       {
+         if ((pa = find_attr (at, attr)) == NULL)
+           break;
+         if (at->flags & AF_ALST)
+           return pa;
+       }
+      grub_errno = GRUB_ERR_NONE;
+      free_attr (at);
+      init_attr (at, mft);
+      pa = find_attr (at, attr);
+    }
+  return pa;
+}
+
+static char *
+read_run_data (char *run, int nn, grub_disk_addr_t * val, int sig)
+{
+  grub_disk_addr_t r, v;
+
+  r = 0;
+  v = 1;
+
+  while (nn--)
+    {
+      r += v * (*(unsigned char *) (run++));
+      v <<= 8;
+    }
+
+  if ((sig) && (r & (v >> 1)))
+    r -= v;
+
+  *val = r;
+  return run;
+}
+
+grub_err_t
+grub_ntfs_read_run_list (struct grub_ntfs_rlst * ctx)
+{
+  int c1, c2;
+  grub_disk_addr_t val;
+  char *run;
+
+  run = ctx->cur_run;
+retry:
+  c1 = ((unsigned char) (*run) & 0xF);
+  c2 = ((unsigned char) (*run) >> 4);
+  if (!c1)
+    {
+      if ((ctx->attr) && (ctx->attr->flags & AF_ALST))
+       {
+         void NESTED_FUNC_ATTR (*save_hook) (grub_disk_addr_t sector,
+                                             unsigned offset,
+                                             unsigned length);
+
+         save_hook = ctx->comp.disk->read_hook;
+         ctx->comp.disk->read_hook = 0;
+         run = find_attr (ctx->attr, (unsigned char) *ctx->attr->attr_cur);
+         ctx->comp.disk->read_hook = save_hook;
+         if (run)
+           {
+             if (run[8] == 0)
+               return grub_error (GRUB_ERR_BAD_FS,
+                                  "$DATA should be non-resident");
+
+             run += u16at (run, 0x20);
+             ctx->curr_lcn = 0;
+             goto retry;
+           }
+       }
+      return grub_error (GRUB_ERR_BAD_FS, "run list overflown");
+    }
+  run = read_run_data (run + 1, c1, &val, 0);  /* length of current VCN */
+  ctx->curr_vcn = ctx->next_vcn;
+  ctx->next_vcn += val;
+  run = read_run_data (run, c2, &val, 1);      /* offset to previous LCN */
+  ctx->curr_lcn += val;
+  if (val == 0)
+    ctx->flags |= RF_BLNK;
+  else
+    ctx->flags &= ~RF_BLNK;
+  ctx->cur_run = run;
+  return 0;
+}
+
+static grub_disk_addr_t
+grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block)
+{
+  struct grub_ntfs_rlst *ctx;
+
+  ctx = (struct grub_ntfs_rlst *) node;
+  if (block >= ctx->next_vcn)
+    {
+      if (grub_ntfs_read_run_list (ctx))
+       return -1;
+      return ctx->curr_lcn;
+    }
+  else
+    return (ctx->flags & RF_BLNK) ? 0 : (block -
+                                        ctx->curr_vcn + ctx->curr_lcn);
+}
+
+static grub_err_t
+read_data (struct grub_ntfs_attr *at, char *pa, char *dest,
+          grub_disk_addr_t ofs, grub_size_t len, int cached,
+          void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                              unsigned offset,
+                                              unsigned length))
+{
+  grub_disk_addr_t vcn;
+  struct grub_ntfs_rlst cc, *ctx;
+
+  if (len == 0)
+    return 0;
+
+  grub_memset (&cc, 0, sizeof (cc));
+  ctx = &cc;
+  ctx->attr = at;
+  ctx->comp.spc = at->mft->data->spc;
+  ctx->comp.disk = at->mft->data->disk;
+
+  if (pa[8] == 0)
+    {
+      if (ofs + len > u32at (pa, 0x10))
+       return grub_error (GRUB_ERR_BAD_FS, "read out of range");
+      grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len);
+      return 0;
+    }
+
+  if (u16at (pa, 0xC) & FLAG_COMPRESSED)
+    ctx->flags |= RF_COMP;
+  else
+    ctx->flags &= ~RF_COMP;
+  ctx->cur_run = pa + u16at (pa, 0x20);
+
+  if (ctx->flags & RF_COMP)
+    {
+      if (!cached)
+       return grub_error (GRUB_ERR_BAD_FS, "attribute can\'t be compressed");
+
+      if (at->sbuf)
+       {
+         if ((ofs & (~(COM_LEN - 1))) == at->save_pos)
+           {
+             grub_disk_addr_t n;
+
+             n = COM_LEN - (ofs - at->save_pos);
+             if (n > len)
+               n = len;
+
+             grub_memcpy (dest, at->sbuf + ofs - at->save_pos, n);
+             if (n == len)
+               return 0;
+
+             dest += n;
+             len -= n;
+             ofs += n;
+           }
+       }
+      else
+       {
+         at->sbuf = grub_malloc (COM_LEN);
+         if (at->sbuf == NULL)
+           return grub_errno;
+         at->save_pos = 1;
+       }
+
+      vcn = ctx->target_vcn = (ofs >> COM_LOG_LEN) * (COM_SEC / ctx->comp.spc);
+      ctx->target_vcn &= ~0xF;
+    }
+  else
+    vcn = ctx->target_vcn = grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, 0);
+
+  ctx->next_vcn = u32at (pa, 0x10);
+  ctx->curr_lcn = 0;
+  while (ctx->next_vcn <= ctx->target_vcn)
+    {
+      if (grub_ntfs_read_run_list (ctx))
+       return grub_errno;
+    }
+
+  if (at->flags & AF_GPOS)
+    {
+      grub_disk_addr_t st0, st1;
+      grub_uint32_t m;
+
+      grub_divmod64 (ofs >> BLK_SHR, ctx->comp.spc, &m);
+
+      st0 =
+       (ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc + m;
+      st1 = st0 + 1;
+      if (st1 ==
+         (ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc)
+       {
+         if (grub_ntfs_read_run_list (ctx))
+           return grub_errno;
+         st1 = ctx->curr_lcn * ctx->comp.spc;
+       }
+      v32at (dest, 0) = st0;
+      v32at (dest, 4) = st1;
+      return 0;
+    }
+
+  if (!(ctx->flags & RF_COMP))
+    {
+      unsigned int pow;
+
+      if (!grub_fshelp_log2blksize (ctx->comp.spc, &pow))
+       grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx,
+                              read_hook, ofs, len, dest,
+                              grub_ntfs_read_block, ofs + len, pow);
+      return grub_errno;
+    }
+
+  return (grub_ntfscomp_func) ? grub_ntfscomp_func (at, dest, ofs, len, ctx,
+                                                   vcn) :
+    grub_error (GRUB_ERR_BAD_FS, "ntfscomp module not loaded");
+}
+
+static grub_err_t
+read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs,
+          grub_size_t len, int cached,
+          void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                              unsigned offset,
+                                              unsigned length))
+{
+  char *save_cur;
+  unsigned char attr;
+  char *pp;
+  grub_err_t ret;
+
+  save_cur = at->attr_cur;
+  at->attr_nxt = at->attr_cur;
+  attr = (unsigned char) *at->attr_nxt;
+  if (at->flags & AF_ALST)
+    {
+      char *pa;
+      grub_disk_addr_t vcn;
+
+      vcn = grub_divmod64 (ofs, at->mft->data->spc << BLK_SHR, 0);
+      pa = at->attr_nxt + u16at (at->attr_nxt, 4);
+      while (pa < at->attr_end)
+       {
+         if ((unsigned char) *pa != attr)
+           break;
+         if (u32at (pa, 8) > vcn)
+           break;
+         at->attr_nxt = pa;
+         pa += u16at (pa, 4);
+       }
+    }
+  pp = find_attr (at, attr);
+  if (pp)
+    ret = read_data (at, pp, dest, ofs, len, cached, read_hook);
+  else
+    ret =
+      (grub_errno) ? grub_errno : grub_error (GRUB_ERR_BAD_FS,
+                                             "attribute not found");
+  at->attr_cur = save_cur;
+  return ret;
+}
+
+static grub_err_t
+read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno)
+{
+  if (read_attr
+      (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << BLK_SHR),
+       data->mft_size << BLK_SHR, 0, 0))
+    return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%X fails", mftno);
+  return fixup (data, buf, data->mft_size, "FILE");
+}
+
+static grub_err_t
+init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno)
+{
+  unsigned short flag;
+
+  mft->inode_read = 1;
+
+  mft->buf = grub_malloc (mft->data->mft_size << BLK_SHR);
+  if (mft->buf == NULL)
+    return grub_errno;
+
+  if (read_mft (mft->data, mft->buf, mftno))
+    return grub_errno;
+
+  flag = u16at (mft->buf, 0x16);
+  if ((flag & 1) == 0)
+    return grub_error (GRUB_ERR_BAD_FS, "MFT 0x%X is not in use", mftno);
+
+  if ((flag & 2) == 0)
+    {
+      char *pa;
+
+      pa = locate_attr (&mft->attr, mft, AT_DATA);
+      if (pa == NULL)
+       return grub_error (GRUB_ERR_BAD_FS, "no $DATA in MFT 0x%X", mftno);
+
+      if (!pa[8])
+       mft->size = u32at (pa, 0x10);
+      else
+       mft->size = u64at (pa, 0x30);
+
+      if ((mft->attr.flags & AF_ALST) == 0)
+       mft->attr.attr_end = 0; /*  Don't jump to attribute list */
+    }
+  else
+    init_attr (&mft->attr, mft);
+
+  return 0;
+}
+
+static void
+free_file (struct grub_ntfs_file *mft)
+{
+  free_attr (&mft->attr);
+  grub_free (mft->buf);
+}
+
+static int
+list_file (struct grub_ntfs_file *diro, char *pos,
+          int NESTED_FUNC_ATTR
+          (*hook) (const char *filename,
+                   enum grub_fshelp_filetype filetype,
+                   grub_fshelp_node_t node))
+{
+  char *np;
+  int ns;
+
+  while (1)
+    {
+      char *ustr, namespace;
+
+      if (pos[0xC] & 2)                /* end signature */
+       break;
+
+      np = pos + 0x50;
+      ns = (unsigned char) *(np++);
+      namespace = *(np++);
+
+      /*
+       *  Ignore files in DOS namespace, as they will reappear as Win32
+       *  names.
+       */
+      if ((ns) && (namespace != 2))
+       {
+         enum grub_fshelp_filetype type;
+         struct grub_ntfs_file *fdiro;
+
+         if (u16at (pos, 4))
+           {
+             grub_error (GRUB_ERR_BAD_FS, "64-bit MFT number");
+             return 0;
+           }
+
+         type =
+           (u32at (pos, 0x48) & ATTR_DIRECTORY) ? GRUB_FSHELP_DIR :
+           GRUB_FSHELP_REG;
+
+         fdiro = grub_zalloc (sizeof (struct grub_ntfs_file));
+         if (!fdiro)
+           return 0;
+
+         fdiro->data = diro->data;
+         fdiro->ino = u32at (pos, 0);
+
+         ustr = grub_malloc (ns * 4 + 1);
+         if (ustr == NULL)
+           return 0;
+         *grub_utf16_to_utf8 ((grub_uint8_t *) ustr, (grub_uint16_t *) np,
+                              ns) = '\0';
+
+          if (namespace)
+            type |= GRUB_FSHELP_CASE_INSENSITIVE;
+
+         if (hook (ustr, type, fdiro))
+           {
+             grub_free (ustr);
+             return 1;
+           }
+
+         grub_free (ustr);
+       }
+      pos += u16at (pos, 8);
+    }
+  return 0;
+}
+
+static int
+grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
+                      int NESTED_FUNC_ATTR
+                      (*hook) (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node))
+{
+  unsigned char *bitmap;
+  struct grub_ntfs_attr attr, *at;
+  char *cur_pos, *indx, *bmp;
+  int ret = 0;
+  grub_size_t bitmap_len;
+  struct grub_ntfs_file *mft;
+
+  mft = (struct grub_ntfs_file *) dir;
+
+  if (!mft->inode_read)
+    {
+      if (init_file (mft, mft->ino))
+       return 0;
+    }
+
+  indx = NULL;
+  bmp = NULL;
+
+  at = &attr;
+  init_attr (at, mft);
+  while (1)
+    {
+      if ((cur_pos = find_attr (at, AT_INDEX_ROOT)) == NULL)
+       {
+         grub_error (GRUB_ERR_BAD_FS, "no $INDEX_ROOT");
+         goto done;
+       }
+
+      /* Resident, Namelen=4, Offset=0x18, Flags=0x00, Name="$I30" */
+      if ((u32at (cur_pos, 8) != 0x180400) ||
+         (u32at (cur_pos, 0x18) != 0x490024) ||
+         (u32at (cur_pos, 0x1C) != 0x300033))
+       continue;
+      cur_pos += u16at (cur_pos, 0x14);
+      if (*cur_pos != 0x30)    /* Not filename index */
+       continue;
+      break;
+    }
+
+  cur_pos += 0x10;             /* Skip index root */
+  ret = list_file (mft, cur_pos + u16at (cur_pos, 0), hook);
+  if (ret)
+    goto done;
+
+  bitmap = NULL;
+  bitmap_len = 0;
+  free_attr (at);
+  init_attr (at, mft);
+  while ((cur_pos = find_attr (at, AT_BITMAP)) != NULL)
+    {
+      int ofs;
+
+      ofs = (unsigned char) cur_pos[0xA];
+      /* Namelen=4, Name="$I30" */
+      if ((cur_pos[9] == 4) &&
+         (u32at (cur_pos, ofs) == 0x490024) &&
+         (u32at (cur_pos, ofs + 4) == 0x300033))
+       {
+          int is_resident = (cur_pos[8] == 0);
+
+          bitmap_len = ((is_resident) ? u32at (cur_pos, 0x10) :
+                        u32at (cur_pos, 0x28));
+
+          bmp = grub_malloc (bitmap_len);
+          if (bmp == NULL)
+            goto done;
+
+         if (is_resident)
+           {
+              grub_memcpy (bmp, (char *) (cur_pos + u16at (cur_pos, 0x14)),
+                           bitmap_len);
+           }
+          else
+            {
+              if (read_data (at, cur_pos, bmp, 0, bitmap_len, 0, 0))
+                {
+                  grub_error (GRUB_ERR_BAD_FS,
+                              "fails to read non-resident $BITMAP");
+                  goto done;
+                }
+              bitmap_len = u32at (cur_pos, 0x30);
+            }
+
+          bitmap = (unsigned char *) bmp;
+         break;
+       }
+    }
+
+  free_attr (at);
+  cur_pos = locate_attr (at, mft, AT_INDEX_ALLOCATION);
+  while (cur_pos != NULL)
+    {
+      /* Non-resident, Namelen=4, Offset=0x40, Flags=0, Name="$I30" */
+      if ((u32at (cur_pos, 8) == 0x400401) &&
+         (u32at (cur_pos, 0x40) == 0x490024) &&
+         (u32at (cur_pos, 0x44) == 0x300033))
+       break;
+      cur_pos = find_attr (at, AT_INDEX_ALLOCATION);
+    }
+
+  if ((!cur_pos) && (bitmap))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "$BITMAP without $INDEX_ALLOCATION");
+      goto done;
+    }
+
+  if (bitmap)
+    {
+      grub_disk_addr_t v, i;
+
+      indx = grub_malloc (mft->data->idx_size << BLK_SHR);
+      if (indx == NULL)
+       goto done;
+
+      v = 1;
+      for (i = 0; i < (grub_disk_addr_t)bitmap_len * 8; i++)
+       {
+         if (*bitmap & v)
+           {
+             if ((read_attr
+                  (at, indx, i * (mft->data->idx_size << BLK_SHR),
+                   (mft->data->idx_size << BLK_SHR), 0, 0))
+                 || (fixup (mft->data, indx, mft->data->idx_size, "INDX")))
+               goto done;
+             ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], hook);
+             if (ret)
+               goto done;
+           }
+         v <<= 1;
+         if (v >= 0x100)
+           {
+             v = 1;
+             bitmap++;
+           }
+       }
+    }
+
+done:
+  free_attr (at);
+  grub_free (indx);
+  grub_free (bmp);
+
+  return ret;
+}
+
+static struct grub_ntfs_data *
+grub_ntfs_mount (grub_disk_t disk)
+{
+  struct grub_ntfs_bpb bpb;
+  struct grub_ntfs_data *data = 0;
+
+  if (!disk)
+    goto fail;
+
+  data = (struct grub_ntfs_data *) grub_zalloc (sizeof (*data));
+  if (!data)
+    goto fail;
+
+  data->disk = disk;
+
+  /* Read the BPB.  */
+  if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb))
+    goto fail;
+
+  if (grub_memcmp ((char *) &bpb.oem_name, "NTFS", 4))
+    goto fail;
+
+  data->blocksize = grub_le_to_cpu16 (bpb.bytes_per_sector);
+  data->spc = bpb.sectors_per_cluster * (data->blocksize >> BLK_SHR);
+
+  if (bpb.clusters_per_mft > 0)
+    data->mft_size = data->spc * bpb.clusters_per_mft;
+  else
+    data->mft_size = 1 << (-bpb.clusters_per_mft - BLK_SHR);
+
+  if (bpb.clusters_per_index > 0)
+    data->idx_size = data->spc * bpb.clusters_per_index;
+  else
+    data->idx_size = 1 << (-bpb.clusters_per_index - BLK_SHR);
+
+  data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) * data->spc;
+
+  if ((data->mft_size > MAX_MFT) || (data->idx_size > MAX_IDX))
+    goto fail;
+
+  data->mmft.data = data;
+  data->cmft.data = data;
+
+  data->mmft.buf = grub_malloc (data->mft_size << BLK_SHR);
+  if (!data->mmft.buf)
+    goto fail;
+
+  if (grub_disk_read
+      (disk, data->mft_start, 0, data->mft_size << BLK_SHR, data->mmft.buf))
+    goto fail;
+
+  data->uuid = grub_le_to_cpu64 (bpb.num_serial);
+
+  if (fixup (data, data->mmft.buf, data->mft_size, "FILE"))
+    goto fail;
+
+  if (!locate_attr (&data->mmft.attr, &data->mmft, AT_DATA))
+    goto fail;
+
+  if (init_file (&data->cmft, FILE_ROOT))
+    goto fail;
+
+  return data;
+
+fail:
+  grub_error (GRUB_ERR_BAD_FS, "not an ntfs filesystem");
+
+  if (data)
+    {
+      free_file (&data->mmft);
+      free_file (&data->cmft);
+      grub_free (data);
+    }
+  return 0;
+}
+
+static grub_err_t
+grub_ntfs_dir (grub_device_t device, const char *path,
+              int (*hook) (const char *filename,
+                           const struct grub_dirhook_info *info))
+{
+  struct grub_ntfs_data *data = 0;
+  struct grub_fshelp_node *fdiro = 0;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+                                    enum grub_fshelp_filetype filetype,
+                                    grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node)
+  {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+  }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ntfs_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (path, &data->cmft, &fdiro, grub_ntfs_iterate_dir,
+                        0, GRUB_FSHELP_DIR);
+
+  if (grub_errno)
+    goto fail;
+
+  grub_ntfs_iterate_dir (fdiro, iterate);
+
+fail:
+  if ((fdiro) && (fdiro != &data->cmft))
+    {
+      free_file (fdiro);
+      grub_free (fdiro);
+    }
+  if (data)
+    {
+      free_file (&data->mmft);
+      free_file (&data->cmft);
+      grub_free (data);
+    }
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_ntfs_open (grub_file_t file, const char *name)
+{
+  struct grub_ntfs_data *data = 0;
+  struct grub_fshelp_node *mft = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ntfs_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (name, &data->cmft, &mft, grub_ntfs_iterate_dir,
+                        0, GRUB_FSHELP_REG);
+
+  if (grub_errno)
+    goto fail;
+
+  if (mft != &data->cmft)
+    {
+      free_file (&data->cmft);
+      grub_memcpy (&data->cmft, mft, sizeof (*mft));
+      grub_free (mft);
+      if (!data->cmft.inode_read)
+       {
+         if (init_file (&data->cmft, data->cmft.ino))
+           goto fail;
+       }
+    }
+
+  file->size = data->cmft.size;
+  file->data = data;
+  file->offset = 0;
+
+  return 0;
+
+fail:
+  if (data)
+    {
+      free_file (&data->mmft);
+      free_file (&data->cmft);
+      grub_free (data);
+    }
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_ssize_t
+grub_ntfs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_ntfs_file *mft;
+
+  mft = &((struct grub_ntfs_data *) file->data)->cmft;
+  if (file->read_hook)
+    mft->attr.save_pos = 1;
+
+  read_attr (&mft->attr, buf, file->offset, len, 1, file->read_hook);
+  return (grub_errno) ? 0 : len;
+}
+
+static grub_err_t
+grub_ntfs_close (grub_file_t file)
+{
+  struct grub_ntfs_data *data;
+
+  data = file->data;
+
+  if (data)
+    {
+      free_file (&data->mmft);
+      free_file (&data->cmft);
+      grub_free (data);
+    }
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_ntfs_label (grub_device_t device, char **label)
+{
+  struct grub_ntfs_data *data = 0;
+  struct grub_fshelp_node *mft = 0;
+  char *pa;
+
+  grub_dl_ref (my_mod);
+
+  *label = 0;
+
+  data = grub_ntfs_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file ("/$Volume", &data->cmft, &mft, grub_ntfs_iterate_dir,
+                        0, GRUB_FSHELP_REG);
+
+  if (grub_errno)
+    goto fail;
+
+  if (!mft->inode_read)
+    {
+      mft->buf = grub_malloc (mft->data->mft_size << BLK_SHR);
+      if (mft->buf == NULL)
+       goto fail;
+
+      if (read_mft (mft->data, mft->buf, mft->ino))
+       goto fail;
+    }
+
+  init_attr (&mft->attr, mft);
+  pa = find_attr (&mft->attr, AT_VOLUME_NAME);
+  if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10)))
+    {
+      char *buf;
+      int len;
+
+      len = u32at (pa, 0x10) / 2;
+      buf = grub_malloc (len * 4 + 1);
+      pa += u16at (pa, 0x14);
+      *grub_utf16_to_utf8 ((grub_uint8_t *) buf, (grub_uint16_t *) pa, len) =
+       '\0';
+      *label = buf;
+    }
+
+fail:
+  if ((mft) && (mft != &data->cmft))
+    {
+      free_file (mft);
+      grub_free (mft);
+    }
+  if (data)
+    {
+      free_file (&data->mmft);
+      free_file (&data->cmft);
+      grub_free (data);
+    }
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_ntfs_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_ntfs_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ntfs_mount (disk);
+  if (data)
+    {
+      *uuid = grub_xasprintf ("%016llx", (unsigned long long) data->uuid);
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static struct grub_fs grub_ntfs_fs =
+  {
+    .name = "ntfs",
+    .dir = grub_ntfs_dir,
+    .open = grub_ntfs_open,
+    .read = grub_ntfs_read,
+    .close = grub_ntfs_close,
+    .label = grub_ntfs_label,
+    .uuid = grub_ntfs_uuid,
+#ifdef GRUB_UTIL
+    .reserved_first_sector = 1,
+#endif
+    .next = 0
+};
+
+GRUB_MOD_INIT (ntfs)
+{
+  grub_fs_register (&grub_ntfs_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI (ntfs)
+{
+  grub_fs_unregister (&grub_ntfs_fs);
+}
diff --git a/grub-core/fs/ntfscomp.c b/grub-core/fs/ntfscomp.c
new file mode 100644 (file)
index 0000000..c29979e
--- /dev/null
@@ -0,0 +1,374 @@
+/* ntfscomp.c - compression support for the NTFS filesystem */
+/*
+ *  Copyright (C) 2007 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/fshelp.h>
+#include <grub/ntfs.h>
+
+static grub_err_t
+decomp_nextvcn (struct grub_ntfs_comp *cc)
+{
+  if (cc->comp_head >= cc->comp_tail)
+    return grub_error (GRUB_ERR_BAD_FS, "compression block overflown");
+  if (grub_disk_read
+      (cc->disk,
+       (cc->comp_table[cc->comp_head][1] -
+       (cc->comp_table[cc->comp_head][0] - cc->cbuf_vcn)) * cc->spc, 0,
+       cc->spc << BLK_SHR, cc->cbuf))
+    return grub_errno;
+  cc->cbuf_vcn++;
+  if ((cc->cbuf_vcn >= cc->comp_table[cc->comp_head][0]))
+    cc->comp_head++;
+  cc->cbuf_ofs = 0;
+  return 0;
+}
+
+static grub_err_t
+decomp_getch (struct grub_ntfs_comp *cc, unsigned char *res)
+{
+  if (cc->cbuf_ofs >= (cc->spc << BLK_SHR))
+    {
+      if (decomp_nextvcn (cc))
+       return grub_errno;
+    }
+  *res = (unsigned char) cc->cbuf[cc->cbuf_ofs++];
+  return 0;
+}
+
+static grub_err_t
+decomp_get16 (struct grub_ntfs_comp *cc, grub_uint16_t * res)
+{
+  unsigned char c1 = 0, c2 = 0;
+
+  if ((decomp_getch (cc, &c1)) || (decomp_getch (cc, &c2)))
+    return grub_errno;
+  *res = ((grub_uint16_t) c2) * 256 + ((grub_uint16_t) c1);
+  return 0;
+}
+
+/* Decompress a block (4096 bytes) */
+static grub_err_t
+decomp_block (struct grub_ntfs_comp *cc, char *dest)
+{
+  grub_uint16_t flg, cnt;
+
+  if (decomp_get16 (cc, &flg))
+    return grub_errno;
+  cnt = (flg & 0xFFF) + 1;
+
+  if (dest)
+    {
+      if (flg & 0x8000)
+       {
+         unsigned char tag;
+         grub_uint32_t bits, copied;
+
+         bits = copied = tag = 0;
+         while (cnt > 0)
+           {
+             if (copied > COM_LEN)
+               return grub_error (GRUB_ERR_BAD_FS,
+                                  "compression block too large");
+
+             if (!bits)
+               {
+                 if (decomp_getch (cc, &tag))
+                   return grub_errno;
+
+                 bits = 8;
+                 cnt--;
+                 if (cnt <= 0)
+                   break;
+               }
+             if (tag & 1)
+               {
+                 grub_uint32_t i, len, delta, code, lmask, dshift;
+                 grub_uint16_t word;
+
+                 if (decomp_get16 (cc, &word))
+                   return grub_errno;
+
+                 code = word;
+                 cnt -= 2;
+
+                 if (!copied)
+                   {
+                     grub_error (GRUB_ERR_BAD_FS, "nontext window empty");
+                     return 0;
+                   }
+
+                 for (i = copied - 1, lmask = 0xFFF, dshift = 12; i >= 0x10;
+                      i >>= 1)
+                   {
+                     lmask >>= 1;
+                     dshift--;
+                   }
+
+                 delta = code >> dshift;
+                 len = (code & lmask) + 3;
+
+                 for (i = 0; i < len; i++)
+                   {
+                     dest[copied] = dest[copied - delta - 1];
+                     copied++;
+                   }
+               }
+             else
+               {
+                 unsigned char ch = 0;
+
+                 if (decomp_getch (cc, &ch))
+                   return grub_errno;
+                 dest[copied++] = ch;
+                 cnt--;
+               }
+             tag >>= 1;
+             bits--;
+           }
+         return 0;
+       }
+      else
+       {
+         if (cnt != COM_LEN)
+           return grub_error (GRUB_ERR_BAD_FS,
+                              "invalid compression block size");
+       }
+    }
+
+  while (cnt > 0)
+    {
+      int n;
+
+      n = (cc->spc << BLK_SHR) - cc->cbuf_ofs;
+      if (n > cnt)
+       n = cnt;
+      if ((dest) && (n))
+       {
+         grub_memcpy (dest, &cc->cbuf[cc->cbuf_ofs], n);
+         dest += n;
+       }
+      cnt -= n;
+      cc->cbuf_ofs += n;
+      if ((cnt) && (decomp_nextvcn (cc)))
+       return grub_errno;
+    }
+  return 0;
+}
+
+static grub_err_t
+read_block (struct grub_ntfs_rlst *ctx, char *buf, int num)
+{
+  int cpb = COM_SEC / ctx->comp.spc;
+
+  while (num)
+    {
+      int nn;
+
+      if ((ctx->target_vcn & 0xF) == 0)
+       {
+
+         if (ctx->comp.comp_head != ctx->comp.comp_tail)
+           return grub_error (GRUB_ERR_BAD_FS, "invalid compression block");
+         ctx->comp.comp_head = ctx->comp.comp_tail = 0;
+         ctx->comp.cbuf_vcn = ctx->target_vcn;
+         ctx->comp.cbuf_ofs = (ctx->comp.spc << BLK_SHR);
+         if (ctx->target_vcn >= ctx->next_vcn)
+           {
+             if (grub_ntfs_read_run_list (ctx))
+               return grub_errno;
+           }
+         while (ctx->target_vcn + 16 > ctx->next_vcn)
+           {
+             if (ctx->flags & RF_BLNK)
+               break;
+             ctx->comp.comp_table[ctx->comp.comp_tail][0] = ctx->next_vcn;
+             ctx->comp.comp_table[ctx->comp.comp_tail][1] =
+               ctx->curr_lcn + ctx->next_vcn - ctx->curr_vcn;
+             ctx->comp.comp_tail++;
+             if (grub_ntfs_read_run_list (ctx))
+               return grub_errno;
+           }
+       }
+
+      nn = (16 - (unsigned) (ctx->target_vcn & 0xF)) / cpb;
+      if (nn > num)
+       nn = num;
+      num -= nn;
+
+      if (ctx->flags & RF_BLNK)
+       {
+         ctx->target_vcn += nn * cpb;
+         if (ctx->comp.comp_tail == 0)
+           {
+             if (buf)
+               {
+                 grub_memset (buf, 0, nn * COM_LEN);
+                 buf += nn * COM_LEN;
+               }
+           }
+         else
+           {
+             while (nn)
+               {
+                 if (decomp_block (&ctx->comp, buf))
+                   return grub_errno;
+                 if (buf)
+                   buf += COM_LEN;
+                 nn--;
+               }
+           }
+       }
+      else
+       {
+         nn *= cpb;
+         while ((ctx->comp.comp_head < ctx->comp.comp_tail) && (nn))
+           {
+             int tt;
+
+             tt =
+               ctx->comp.comp_table[ctx->comp.comp_head][0] -
+               ctx->target_vcn;
+             if (tt > nn)
+               tt = nn;
+             ctx->target_vcn += tt;
+             if (buf)
+               {
+                 if (grub_disk_read
+                     (ctx->comp.disk,
+                      (ctx->comp.comp_table[ctx->comp.comp_head][1] -
+                       (ctx->comp.comp_table[ctx->comp.comp_head][0] -
+                        ctx->target_vcn)) * ctx->comp.spc, 0,
+                      tt * (ctx->comp.spc << BLK_SHR), buf))
+                   return grub_errno;
+                 buf += tt * (ctx->comp.spc << BLK_SHR);
+               }
+             nn -= tt;
+             if (ctx->target_vcn >=
+                 ctx->comp.comp_table[ctx->comp.comp_head][0])
+               ctx->comp.comp_head++;
+           }
+         if (nn)
+           {
+             if (buf)
+               {
+                 if (grub_disk_read
+                     (ctx->comp.disk,
+                      (ctx->target_vcn - ctx->curr_vcn +
+                       ctx->curr_lcn) * ctx->comp.spc, 0,
+                      nn * (ctx->comp.spc << BLK_SHR), buf))
+                   return grub_errno;
+                 buf += nn * (ctx->comp.spc << BLK_SHR);
+               }
+             ctx->target_vcn += nn;
+           }
+       }
+    }
+  return 0;
+}
+
+static grub_err_t
+ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs,
+         grub_uint32_t len, struct grub_ntfs_rlst *ctx, grub_uint32_t vcn)
+{
+  grub_err_t ret;
+
+  ctx->comp.comp_head = ctx->comp.comp_tail = 0;
+  ctx->comp.cbuf = grub_malloc ((ctx->comp.spc) << BLK_SHR);
+  if (!ctx->comp.cbuf)
+    return 0;
+
+  ret = 0;
+
+  //ctx->comp.disk->read_hook = read_hook;
+
+  if ((vcn > ctx->target_vcn) &&
+      (read_block
+       (ctx, NULL, ((vcn - ctx->target_vcn) * ctx->comp.spc) / COM_SEC)))
+    {
+      ret = grub_errno;
+      goto quit;
+    }
+
+  if (ofs % COM_LEN)
+    {
+      grub_uint32_t t, n, o;
+
+      t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR);
+      if (read_block (ctx, at->sbuf, 1))
+       {
+         ret = grub_errno;
+         goto quit;
+       }
+
+      at->save_pos = t;
+
+      o = ofs % COM_LEN;
+      n = COM_LEN - o;
+      if (n > len)
+       n = len;
+      grub_memcpy (dest, &at->sbuf[o], n);
+      if (n == len)
+       goto quit;
+      dest += n;
+      len -= n;
+    }
+
+  if (read_block (ctx, dest, len / COM_LEN))
+    {
+      ret = grub_errno;
+      goto quit;
+    }
+
+  dest += (len / COM_LEN) * COM_LEN;
+  len = len % COM_LEN;
+  if (len)
+    {
+      grub_uint32_t t;
+
+      t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR);
+      if (read_block (ctx, at->sbuf, 1))
+       {
+         ret = grub_errno;
+         goto quit;
+       }
+
+      at->save_pos = t;
+
+      grub_memcpy (dest, at->sbuf, len);
+    }
+
+quit:
+  //ctx->comp.disk->read_hook = 0;
+  if (ctx->comp.cbuf)
+    grub_free (ctx->comp.cbuf);
+  return ret;
+}
+
+GRUB_MOD_INIT (ntfscomp)
+{
+  grub_ntfscomp_func = ntfscomp;
+}
+
+GRUB_MOD_FINI (ntfscomp)
+{
+  grub_ntfscomp_func = NULL;
+}
diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c
new file mode 100644 (file)
index 0000000..5acd339
--- /dev/null
@@ -0,0 +1,1381 @@
+/* reiserfs.c - ReiserFS versions up to 3.6 */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+  TODO:
+  implement journal handling (ram replay)
+  test tail packing & direct files
+  validate partition label position
+*/
+
+#if 0
+# define GRUB_REISERFS_DEBUG
+# define GRUB_REISERFS_JOURNALING
+# define GRUB_HEXDUMP
+#endif
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+
+#define MIN(a, b) \
+  ({ typeof (a) _a = (a); \
+     typeof (b) _b = (b); \
+     _a < _b ? _a : _b; })
+
+#define MAX(a, b) \
+  ({ typeof (a) _a = (a); \
+     typeof (b) _b = (b); \
+     _a > _b ? _a : _b; })
+
+#define REISERFS_SUPER_BLOCK_OFFSET 0x10000
+#define REISERFS_MAGIC_LEN 12
+#define REISERFS_MAGIC_STRING "ReIsEr"
+#define REISERFS_MAGIC_DESC_BLOCK "ReIsErLB"
+/* If the 3rd bit of an item state is set, then it's visible.  */
+#define GRUB_REISERFS_VISIBLE_MASK ((grub_uint16_t) 0x04)
+#define REISERFS_MAX_LABEL_LENGTH 16
+#define REISERFS_LABEL_OFFSET 0x64
+
+#define S_IFLNK 0xA000
+
+static grub_dl_t my_mod;
+
+#define assert(boolean) real_assert (boolean, GRUB_FILE, __LINE__)
+static inline void
+real_assert (int boolean, const char *file, const int line)
+{
+  if (! boolean)
+    grub_printf ("Assertion failed at %s:%d\n", file, line);
+}
+
+enum grub_reiserfs_item_type
+  {
+    GRUB_REISERFS_STAT,
+    GRUB_REISERFS_DIRECTORY,
+    GRUB_REISERFS_DIRECT,
+    GRUB_REISERFS_INDIRECT,
+    /* Matches both _DIRECT and _INDIRECT when searching.  */
+    GRUB_REISERFS_ANY,
+    GRUB_REISERFS_UNKNOWN
+  };
+
+struct grub_reiserfs_superblock
+{
+  grub_uint32_t block_count;
+  grub_uint32_t block_free_count;
+  grub_uint32_t root_block;
+  grub_uint32_t journal_block;
+  grub_uint32_t journal_device;
+  grub_uint32_t journal_original_size;
+  grub_uint32_t journal_max_transaction_size;
+  grub_uint32_t journal_block_count;
+  grub_uint32_t journal_max_batch;
+  grub_uint32_t journal_max_commit_age;
+  grub_uint32_t journal_max_transaction_age;
+  grub_uint16_t block_size;
+  grub_uint16_t oid_max_size;
+  grub_uint16_t oid_current_size;
+  grub_uint16_t state;
+  grub_uint8_t magic_string[REISERFS_MAGIC_LEN];
+  grub_uint32_t function_hash_code;
+  grub_uint16_t tree_height;
+  grub_uint16_t bitmap_number;
+  grub_uint16_t version;
+  grub_uint16_t reserved;
+  grub_uint32_t inode_generation;
+  grub_uint8_t unused[4];
+  grub_uint16_t uuid[8];
+} __attribute__ ((packed));
+
+struct grub_reiserfs_journal_header
+{
+  grub_uint32_t last_flush_uid;
+  grub_uint32_t unflushed_offset;
+  grub_uint32_t mount_id;
+} __attribute__ ((packed));
+
+struct grub_reiserfs_description_block
+{
+  grub_uint32_t id;
+  grub_uint32_t len;
+  grub_uint32_t mount_id;
+  grub_uint32_t real_blocks[0];
+} __attribute__ ((packed));
+
+struct grub_reiserfs_commit_block
+{
+  grub_uint32_t id;
+  grub_uint32_t len;
+  grub_uint32_t real_blocks[0];
+} __attribute__ ((packed));
+
+struct grub_reiserfs_stat_item_v1
+{
+  grub_uint16_t mode;
+  grub_uint16_t hardlink_count;
+  grub_uint16_t uid;
+  grub_uint16_t gid;
+  grub_uint32_t size;
+  grub_uint32_t atime;
+  grub_uint32_t mtime;
+  grub_uint32_t ctime;
+  grub_uint32_t rdev;
+  grub_uint32_t first_direct_byte;
+} __attribute__ ((packed));
+
+struct grub_reiserfs_stat_item_v2
+{
+  grub_uint16_t mode;
+  grub_uint16_t reserved;
+  grub_uint32_t hardlink_count;
+  grub_uint64_t size;
+  grub_uint32_t uid;
+  grub_uint32_t gid;
+  grub_uint32_t atime;
+  grub_uint32_t mtime;
+  grub_uint32_t ctime;
+  grub_uint32_t blocks;
+  grub_uint32_t first_direct_byte;
+} __attribute__ ((packed));
+
+struct grub_reiserfs_key
+{
+  grub_uint32_t directory_id;
+  grub_uint32_t object_id;
+  union
+  {
+    struct
+    {
+      grub_uint32_t offset;
+      grub_uint32_t type;
+    } v1 __attribute__ ((packed));
+    struct
+    {
+      grub_uint64_t offset_type;
+    } v2 __attribute__ ((packed));
+  } u;
+} __attribute__ ((packed));
+
+struct grub_reiserfs_item_header
+{
+  struct grub_reiserfs_key key;
+  union
+  {
+    grub_uint16_t free_space;
+    grub_uint16_t entry_count;
+  } u __attribute__ ((packed));
+  grub_uint16_t item_size;
+  grub_uint16_t item_location;
+  grub_uint16_t version;
+} __attribute__ ((packed));
+
+struct grub_reiserfs_block_header
+{
+  grub_uint16_t level;
+  grub_uint16_t item_count;
+  grub_uint16_t free_space;
+  grub_uint16_t reserved;
+  struct grub_reiserfs_key block_right_delimiting_key;
+} __attribute__ ((packed));
+
+struct grub_reiserfs_disk_child
+{
+  grub_uint32_t block_number;
+  grub_uint16_t size;
+  grub_uint16_t reserved;
+} __attribute__ ((packed));
+
+struct grub_reiserfs_directory_header
+{
+  grub_uint32_t offset;
+  grub_uint32_t directory_id;
+  grub_uint32_t object_id;
+  grub_uint16_t location;
+  grub_uint16_t state;
+} __attribute__ ((packed));
+
+struct grub_fshelp_node
+{
+  struct grub_reiserfs_data *data;
+  grub_uint32_t block_number; /* 0 if node is not found.  */
+  grub_uint16_t block_position;
+  grub_uint64_t next_offset;
+  enum grub_reiserfs_item_type type; /* To know how to read the header.  */
+  struct grub_reiserfs_item_header header;
+};
+
+/* Returned when opening a file.  */
+struct grub_reiserfs_data
+{
+  struct grub_reiserfs_superblock superblock;
+  grub_disk_t disk;
+};
+
+/* Internal-only functions. Not to be used outside of this file.  */
+
+/* Return the type of given v2 key.  */
+static enum grub_reiserfs_item_type
+grub_reiserfs_get_key_v2_type (const struct grub_reiserfs_key *key)
+{
+  switch (grub_le_to_cpu64 (key->u.v2.offset_type) >> 60)
+    {
+    case 0:
+      return GRUB_REISERFS_STAT;
+    case 15:
+      return GRUB_REISERFS_ANY;
+    case 3:
+      return GRUB_REISERFS_DIRECTORY;
+    case 2:
+      return GRUB_REISERFS_DIRECT;
+    case 1:
+      return GRUB_REISERFS_INDIRECT;
+    }
+  return GRUB_REISERFS_UNKNOWN;
+}
+
+/* Return the type of given v1 key.  */
+static enum grub_reiserfs_item_type
+grub_reiserfs_get_key_v1_type (const struct grub_reiserfs_key *key)
+{
+  switch (grub_le_to_cpu32 (key->u.v1.type))
+    {
+    case 0:
+      return GRUB_REISERFS_STAT;
+    case 555:
+      return GRUB_REISERFS_ANY;
+    case 500:
+      return GRUB_REISERFS_DIRECTORY;
+    case 0x20000000:
+    case 0xFFFFFFFF:
+      return GRUB_REISERFS_DIRECT;
+    case 0x10000000:
+    case 0xFFFFFFFE:
+      return GRUB_REISERFS_INDIRECT;
+    }
+  return GRUB_REISERFS_UNKNOWN;
+}
+
+/* Return 1 if the given key is version 1 key, 2 otherwise.  */
+static int
+grub_reiserfs_get_key_version (const struct grub_reiserfs_key *key)
+{
+  return grub_reiserfs_get_key_v1_type (key) == GRUB_REISERFS_UNKNOWN ? 2 : 1;
+}
+
+#ifdef GRUB_HEXDUMP
+static void
+grub_hexdump (char *buffer, grub_size_t len)
+{
+  grub_size_t a;
+  for (a = 0; a < len; a++)
+    {
+      if (! (a & 0x0F))
+        grub_printf ("\n%08x  ", a);
+      grub_printf ("%02x ",
+                   ((unsigned int) ((unsigned char *) buffer)[a]) & 0xFF);
+    }
+  grub_printf ("\n");
+}
+#endif
+
+#ifdef GRUB_REISERFS_DEBUG
+static grub_uint64_t
+grub_reiserfs_get_key_offset (const struct grub_reiserfs_key *key);
+
+static enum grub_reiserfs_item_type
+grub_reiserfs_get_key_type (const struct grub_reiserfs_key *key);
+
+static void
+grub_reiserfs_print_key (const struct grub_reiserfs_key *key)
+{
+  unsigned int a;
+  char *reiserfs_type_strings[] = {
+    "stat     ",
+    "directory",
+    "direct   ",
+    "indirect ",
+    "any      ",
+    "unknown  "
+  };
+
+  for (a = 0; a < sizeof (struct grub_reiserfs_key); a++)
+    grub_printf ("%02x ", ((unsigned int) ((unsigned char *) key)[a]) & 0xFF);
+  grub_printf ("parent id = 0x%08x, self id = 0x%08x, type = %s, offset = ",
+               grub_le_to_cpu32 (key->directory_id),
+               grub_le_to_cpu32 (key->object_id),
+               reiserfs_type_strings [grub_reiserfs_get_key_type (key)]);
+  if (grub_reiserfs_get_key_version (key) == 1)
+    grub_printf("%08x", (unsigned int) grub_reiserfs_get_key_offset (key));
+  else
+    grub_printf("0x%07x%08x",
+                (unsigned) (grub_reiserfs_get_key_offset (key) >> 32),
+                (unsigned) (grub_reiserfs_get_key_offset (key) & 0xFFFFFFFF));
+  grub_printf ("\n");
+}
+#endif
+
+/* Return the offset of given key.  */
+static grub_uint64_t
+grub_reiserfs_get_key_offset (const struct grub_reiserfs_key *key)
+{
+  if (grub_reiserfs_get_key_version (key) == 1)
+    return grub_le_to_cpu32 (key->u.v1.offset);
+  else
+    return grub_le_to_cpu64 (key->u.v2.offset_type) & (~0ULL >> 4);
+}
+
+/* Set the offset of given key.  */
+static void
+grub_reiserfs_set_key_offset (struct grub_reiserfs_key *key,
+                              grub_uint64_t value)
+{
+  if (grub_reiserfs_get_key_version (key) == 1)
+    key->u.v1.offset = grub_cpu_to_le32 (value);
+  else
+    key->u.v2.offset_type \
+      = ((key->u.v2.offset_type & grub_cpu_to_le64 (15ULL << 60))
+         | grub_cpu_to_le64 (value & (~0ULL >> 4)));
+}
+
+/* Return the type of given key.  */
+static enum grub_reiserfs_item_type
+grub_reiserfs_get_key_type (const struct grub_reiserfs_key *key)
+{
+  if (grub_reiserfs_get_key_version (key) == 1)
+    return grub_reiserfs_get_key_v1_type (key);
+  else
+    return grub_reiserfs_get_key_v2_type (key);
+}
+
+/* Set the type of given key, with given version number.  */
+static void
+grub_reiserfs_set_key_type (struct grub_reiserfs_key *key,
+                            enum grub_reiserfs_item_type grub_type,
+                            int version)
+{
+  grub_uint32_t type;
+
+  switch (grub_type)
+    {
+    case GRUB_REISERFS_STAT:
+      type = 0;
+      break;
+    case GRUB_REISERFS_ANY:
+      type = (version == 1) ? 555 : 15;
+      break;
+    case GRUB_REISERFS_DIRECTORY:
+      type = (version == 1) ? 500 : 3;
+      break;
+    case GRUB_REISERFS_DIRECT:
+      type = (version == 1) ? 0xFFFFFFFF : 2;
+      break;
+    case GRUB_REISERFS_INDIRECT:
+      type = (version == 1) ? 0xFFFFFFFE : 1;
+      break;
+    default:
+      return;
+    }
+
+  if (version == 1)
+    key->u.v1.type = grub_cpu_to_le32 (type);
+  else
+    key->u.v2.offset_type
+      = ((key->u.v2.offset_type & grub_cpu_to_le64 (~0ULL >> 4))
+         | grub_cpu_to_le64 ((grub_uint64_t) type << 60));
+
+  assert (grub_reiserfs_get_key_type (key) == grub_type);
+}
+
+/* -1 if key 1 if lower than key 2.
+   0 if key 1 is equal to key 2.
+   1 if key 1 is higher than key 2.  */
+static int
+grub_reiserfs_compare_keys (const struct grub_reiserfs_key *key1,
+                            const struct grub_reiserfs_key *key2)
+{
+  grub_uint64_t offset1, offset2;
+  enum grub_reiserfs_item_type type1, type2;
+  grub_uint32_t id1, id2;
+
+  if (! key1 || ! key2)
+    return -2;
+
+  id1 = grub_le_to_cpu32 (key1->directory_id);
+  id2 = grub_le_to_cpu32 (key2->directory_id);
+  if (id1 < id2)
+    return -1;
+  if (id1 > id2)
+    return 1;
+
+  id1 = grub_le_to_cpu32 (key1->object_id);
+  id2 = grub_le_to_cpu32 (key2->object_id);
+  if (id1 < id2)
+    return -1;
+  if (id1 > id2)
+    return 1;
+
+  offset1 = grub_reiserfs_get_key_offset (key1);
+  offset2 = grub_reiserfs_get_key_offset (key2);
+  if (offset1 < offset2)
+    return -1;
+  if (offset1 > offset2)
+    return 1;
+
+  type1 = grub_reiserfs_get_key_type (key1);
+  type2 = grub_reiserfs_get_key_type (key2);
+  if ((type1 == GRUB_REISERFS_ANY
+       && (type2 == GRUB_REISERFS_DIRECT
+           || type2 == GRUB_REISERFS_INDIRECT))
+      || (type2 == GRUB_REISERFS_ANY
+          && (type1 == GRUB_REISERFS_DIRECT
+              || type1 == GRUB_REISERFS_INDIRECT)))
+    return 0;
+  if (type1 < type2)
+    return -1;
+  if (type1 > type2)
+    return 1;
+
+  return 0;
+}
+
+/* Find the item identified by KEY in mounted filesystem DATA, and fill ITEM
+   accordingly to what was found.  */
+static grub_err_t
+grub_reiserfs_get_item (struct grub_reiserfs_data *data,
+                        const struct grub_reiserfs_key *key,
+                        struct grub_fshelp_node *item)
+{
+  grub_uint32_t block_number;
+  struct grub_reiserfs_block_header *block_header = 0;
+  struct grub_reiserfs_key *block_key = 0;
+  grub_uint16_t block_size, item_count, current_level;
+  grub_uint16_t i;
+  grub_uint16_t previous_level = ~0;
+  struct grub_reiserfs_item_header *item_headers = 0;
+
+  if (! data)
+    {
+      grub_error (GRUB_ERR_TEST_FAILURE, "data is NULL");
+      goto fail;
+    }
+
+  if (! key)
+    {
+      grub_error (GRUB_ERR_TEST_FAILURE, "key is NULL");
+      goto fail;
+    }
+
+  if (! item)
+    {
+      grub_error (GRUB_ERR_TEST_FAILURE, "item is NULL");
+      goto fail;
+    }
+
+  block_size = grub_le_to_cpu16 (data->superblock.block_size);
+  block_number = grub_le_to_cpu32 (data->superblock.root_block);
+#ifdef GRUB_REISERFS_DEBUG
+  grub_printf("Searching for ");
+  grub_reiserfs_print_key (key);
+#endif
+  block_header = grub_malloc (block_size);
+  if (! block_header)
+    goto fail;
+
+  item->next_offset = 0;
+  do
+    {
+      grub_disk_read (data->disk,
+                      block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
+                      (((grub_off_t) block_number * block_size)
+                       & (GRUB_DISK_SECTOR_SIZE - 1)),
+                      block_size, block_header);
+      if (grub_errno)
+        goto fail;
+      current_level = grub_le_to_cpu16 (block_header->level);
+      grub_dprintf ("reiserfs_tree", " at level %d\n", current_level);
+      if (current_level >= previous_level)
+        {
+          grub_dprintf ("reiserfs_tree", "level loop detected, aborting\n");
+          grub_error (GRUB_ERR_FILE_READ_ERROR, "level loop");
+          goto fail;
+        }
+      previous_level = current_level;
+      item_count = grub_le_to_cpu16 (block_header->item_count);
+      grub_dprintf ("reiserfs_tree", " number of contained items : %d\n",
+                    item_count);
+      if (current_level > 1)
+        {
+          /* Internal node. Navigate to the child that should contain
+             the searched key.  */
+          struct grub_reiserfs_key *keys
+            = (struct grub_reiserfs_key *) (block_header + 1);
+          struct grub_reiserfs_disk_child *children
+            = ((struct grub_reiserfs_disk_child *)
+               (keys + item_count));
+
+          for (i = 0;
+               i < item_count
+                 && grub_reiserfs_compare_keys (key, &(keys[i])) >= 0;
+               i++)
+            {
+#ifdef GRUB_REISERFS_DEBUG
+              grub_printf("i %03d/%03d ", i + 1, item_count + 1);
+              grub_reiserfs_print_key (&(keys[i]));
+#endif
+            }
+          block_number = grub_le_to_cpu32 (children[i].block_number);
+         if ((i < item_count) && (key->directory_id == keys[i].directory_id)
+              && (key->object_id == keys[i].object_id))
+           item->next_offset = grub_reiserfs_get_key_offset(&(keys[i]));
+#ifdef GRUB_REISERFS_DEBUG
+          if (i == item_count
+              || grub_reiserfs_compare_keys (key, &(keys[i])) == 0)
+            grub_printf(">");
+          else
+            grub_printf("<");
+          if (i < item_count)
+            {
+              grub_printf (" %03d/%03d ", i + 1, item_count + 1);
+              grub_reiserfs_print_key (&(keys[i]));
+              if (i + 1 < item_count)
+                {
+                  grub_printf ("+ %03d/%03d ", i + 2, item_count);
+                  grub_reiserfs_print_key (&(keys[i + 1]));
+                }
+            }
+          else
+            grub_printf ("Accessing rightmost child at block %d.\n",
+                         block_number);
+#endif
+        }
+      else
+        {
+          /* Leaf node.  Check that the key is actually present.  */
+          item_headers
+            = (struct grub_reiserfs_item_header *) (block_header + 1);
+          for (i = 0;
+               i < item_count
+                 && (grub_reiserfs_compare_keys (key, &(item_headers[i].key))
+                     != 0);
+               i++)
+            {
+#ifdef GRUB_REISERFS_DEBUG
+              if (key->directory_id == item_headers[i].key.directory_id && \
+                  key->object_id == item_headers[i].key.object_id)
+                grub_printf("C");
+              else
+                grub_printf(" ");
+              grub_printf(" %03d/%03d ", i + 1, item_count);
+              grub_reiserfs_print_key (&(item_headers[i].key));
+#endif
+            }
+          if (i < item_count)
+            block_key = &(item_headers[i].key);
+        }
+    }
+  while (current_level > 1);
+
+  item->data = data;
+
+  if (i == item_count || grub_reiserfs_compare_keys (key, block_key))
+    {
+      item->block_number = 0;
+      item->block_position = 0;
+      item->type = GRUB_REISERFS_UNKNOWN;
+#ifdef GRUB_REISERFS_DEBUG
+      grub_printf("Not found.\n");
+#endif
+    }
+  else
+    {
+      item->block_number = block_number;
+      item->block_position = i;
+      item->type = grub_reiserfs_get_key_type (block_key);
+      grub_memcpy (&(item->header), &(item_headers[i]),
+                   sizeof (struct grub_reiserfs_item_header));
+#ifdef GRUB_REISERFS_DEBUG
+      grub_printf ("F %03d/%03d ", i + 1, item_count);
+      grub_reiserfs_print_key (block_key);
+#endif
+    }
+
+  assert (grub_errno == GRUB_ERR_NONE);
+  grub_free (block_header);
+  return GRUB_ERR_NONE;
+
+ fail:
+  assert (grub_errno != GRUB_ERR_NONE);
+  grub_free (block_header);
+  assert (grub_errno != GRUB_ERR_NONE);
+  return grub_errno;
+}
+
+/* Return the path of the file which is pointed at by symlink NODE.  */
+static char *
+grub_reiserfs_read_symlink (grub_fshelp_node_t node)
+{
+  char *symlink_buffer = 0;
+  grub_uint16_t block_size;
+  grub_disk_addr_t block;
+  grub_off_t offset;
+  grub_size_t len;
+  struct grub_fshelp_node found;
+  struct grub_reiserfs_key key;
+
+  grub_memcpy (&key, &(node->header.key), sizeof (key));
+  grub_reiserfs_set_key_offset (&key, 1);
+  grub_reiserfs_set_key_type (&key, GRUB_REISERFS_DIRECT,
+                              grub_reiserfs_get_key_version (&key));
+
+  if (grub_reiserfs_get_item (node->data, &key, &found) != GRUB_ERR_NONE)
+    goto fail;
+
+  if (found.block_number == 0)
+    goto fail;
+
+  block_size = grub_le_to_cpu16 (node->data->superblock.block_size);
+  len = grub_le_to_cpu16 (found.header.item_size);
+  block = found.block_number * (block_size  >> GRUB_DISK_SECTOR_BITS);
+  offset = grub_le_to_cpu16 (found.header.item_location);
+
+  symlink_buffer = grub_malloc (len + 1);
+  if (! symlink_buffer)
+    goto fail;
+
+  grub_disk_read (node->data->disk, block, offset, len, symlink_buffer);
+  if (grub_errno)
+    goto fail;
+
+  symlink_buffer[len] = 0;
+  return symlink_buffer;
+
+ fail:
+  grub_free (symlink_buffer);
+  return 0;
+}
+
+/* Fill the mounted filesystem structure and return it.  */
+static struct grub_reiserfs_data *
+grub_reiserfs_mount (grub_disk_t disk)
+{
+  struct grub_reiserfs_data *data = 0;
+  data = grub_malloc (sizeof (*data));
+  if (! data)
+    goto fail;
+  grub_disk_read (disk, REISERFS_SUPER_BLOCK_OFFSET / GRUB_DISK_SECTOR_SIZE,
+                  0, sizeof (data->superblock), &(data->superblock));
+  if (grub_errno)
+    goto fail;
+  if (grub_memcmp (data->superblock.magic_string,
+                   REISERFS_MAGIC_STRING, sizeof (REISERFS_MAGIC_STRING) - 1))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a ReiserFS filesystem");
+      goto fail;
+    }
+  data->disk = disk;
+  return data;
+
+ fail:
+  /* Disk is too small to contain a ReiserFS.  */
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not a ReiserFS filesystem");
+
+  grub_free (data);
+  return 0;
+}
+
+/* Call HOOK for each file in directory ITEM.  */
+static int
+grub_reiserfs_iterate_dir (grub_fshelp_node_t item,
+                           int NESTED_FUNC_ATTR
+                           (*hook) (const char *filename,
+                                    enum grub_fshelp_filetype filetype,
+                                    grub_fshelp_node_t node))
+{
+  struct grub_reiserfs_data *data = item->data;
+  struct grub_reiserfs_block_header *block_header = 0;
+  grub_uint16_t block_size, block_position;
+  grub_uint32_t block_number;
+  grub_uint64_t next_offset = item->next_offset;
+  int ret = 0;
+
+  if (item->type != GRUB_REISERFS_DIRECTORY)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                  "grub_reiserfs_iterate_dir called on a non-directory item");
+      goto fail;
+    }
+  block_size = grub_le_to_cpu16 (data->superblock.block_size);
+  block_header = grub_malloc (block_size);
+  if (! block_header)
+    goto fail;
+  block_number = item->block_number;
+  block_position = item->block_position;
+  grub_dprintf ("reiserfs", "Iterating directory...\n");
+  do
+    {
+      struct grub_reiserfs_directory_header *directory_headers;
+      struct grub_fshelp_node directory_item;
+      grub_uint16_t entry_count, entry_number;
+      struct grub_reiserfs_item_header *item_headers;
+
+      grub_disk_read (data->disk,
+                      block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
+                      (((grub_off_t) block_number * block_size)
+                       & (GRUB_DISK_SECTOR_SIZE - 1)),
+                      block_size, (char *) block_header);
+      if (grub_errno)
+        goto fail;
+
+#if 0
+      if (grub_le_to_cpu16 (block_header->level) != 1)
+        {
+          grub_error (GRUB_ERR_TEST_FAILURE,
+                      "reiserfs: block %d is not a leaf block",
+                      block_number);
+          goto fail;
+        }
+#endif
+
+      item_headers = (struct grub_reiserfs_item_header *) (block_header + 1);
+      directory_headers
+        = ((struct grub_reiserfs_directory_header *)
+           ((char *) block_header
+            + grub_le_to_cpu16 (item_headers[block_position].item_location)));
+      entry_count
+        = grub_le_to_cpu16 (item_headers[block_position].u.entry_count);
+      for (entry_number = 0; entry_number < entry_count; entry_number++)
+        {
+          struct grub_reiserfs_directory_header *directory_header
+            = &directory_headers[entry_number];
+          grub_uint16_t entry_state
+            = grub_le_to_cpu16 (directory_header->state);
+
+          if (entry_state & GRUB_REISERFS_VISIBLE_MASK)
+            {
+              grub_fshelp_node_t entry_item;
+              struct grub_reiserfs_key entry_key;
+              enum grub_reiserfs_item_type entry_type;
+              char *entry_name;
+
+              entry_name = (((char *) directory_headers)
+                            + grub_le_to_cpu16 (directory_header->location));
+              entry_key.directory_id = directory_header->directory_id;
+              entry_key.object_id = directory_header->object_id;
+              entry_key.u.v2.offset_type = 0;
+              grub_reiserfs_set_key_type (&entry_key, GRUB_REISERFS_DIRECTORY,
+                                          2);
+              grub_reiserfs_set_key_offset (&entry_key, 1);
+
+              entry_item = grub_malloc (sizeof (*entry_item));
+              if (! entry_item)
+                goto fail;
+
+              if (grub_reiserfs_get_item (data, &entry_key, entry_item)
+                  != GRUB_ERR_NONE)
+                {
+                  grub_free (entry_item);
+                  goto fail;
+                }
+
+              if (entry_item->type == GRUB_REISERFS_DIRECTORY)
+                entry_type = GRUB_FSHELP_DIR;
+              else
+                {
+                  grub_uint32_t entry_block_number;
+                  /* Order is very important here.
+                     First set the offset to 0 using current key version.
+                     Then change the key type, which affects key version
+                     detection.  */
+                  grub_reiserfs_set_key_offset (&entry_key, 0);
+                  grub_reiserfs_set_key_type (&entry_key, GRUB_REISERFS_STAT,
+                                              2);
+                  if (grub_reiserfs_get_item (data, &entry_key, entry_item)
+                      != GRUB_ERR_NONE)
+                    {
+                      grub_free (entry_item);
+                      goto fail;
+                    }
+
+                  if (entry_item->block_number != 0)
+                    {
+                      grub_uint16_t entry_version;
+                      entry_version
+                        = grub_le_to_cpu16 (entry_item->header.version);
+                      entry_block_number = entry_item->block_number;
+#if 0
+                     grub_dprintf ("reiserfs",
+                                    "version %04x block %08x (%08x) position %08x\n",
+                                    entry_version, entry_block_number,
+                                    ((grub_disk_addr_t) entry_block_number * block_size) / GRUB_DISK_SECTOR_SIZE,
+                                    grub_le_to_cpu16 (entry_item->header.item_location));
+#endif
+                      if (entry_version == 0) /* Version 1 stat item. */
+                        {
+                          struct grub_reiserfs_stat_item_v1 entry_v1_stat;
+                          grub_disk_read (data->disk,
+                                          entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
+                                          grub_le_to_cpu16 (entry_item->header.item_location),
+                                          sizeof (entry_v1_stat),
+                                          (char *) &entry_v1_stat);
+                          if (grub_errno)
+                            goto fail;
+#if 0
+                         grub_dprintf ("reiserfs",
+                                        "%04x %04x %04x %04x %08x %08x | %08x %08x %08x %08x\n",
+                                        grub_le_to_cpu16 (entry_v1_stat.mode),
+                                        grub_le_to_cpu16 (entry_v1_stat.hardlink_count),
+                                        grub_le_to_cpu16 (entry_v1_stat.uid),
+                                        grub_le_to_cpu16 (entry_v1_stat.gid),
+                                        grub_le_to_cpu32 (entry_v1_stat.size),
+                                        grub_le_to_cpu32 (entry_v1_stat.atime),
+                                        grub_le_to_cpu32 (entry_v1_stat.mtime),
+                                        grub_le_to_cpu32 (entry_v1_stat.ctime),
+                                        grub_le_to_cpu32 (entry_v1_stat.rdev),
+                                        grub_le_to_cpu32 (entry_v1_stat.first_direct_byte));
+                         grub_dprintf ("reiserfs",
+                                        "%04x %04x %04x %04x %08x %08x | %08x %08x %08x %08x\n",
+                                        entry_v1_stat.mode,
+                                        entry_v1_stat.hardlink_count,
+                                        entry_v1_stat.uid,
+                                        entry_v1_stat.gid,
+                                        entry_v1_stat.size,
+                                        entry_v1_stat.atime,
+                                        entry_v1_stat.mtime,
+                                        entry_v1_stat.ctime,
+                                        entry_v1_stat.rdev,
+                                        entry_v1_stat.first_direct_byte);
+#endif
+                          if ((grub_le_to_cpu16 (entry_v1_stat.mode) & S_IFLNK)
+                              == S_IFLNK)
+                            entry_type = GRUB_FSHELP_SYMLINK;
+                          else
+                            entry_type = GRUB_FSHELP_REG;
+                        }
+                      else
+                        {
+                          struct grub_reiserfs_stat_item_v2 entry_v2_stat;
+                          grub_disk_read (data->disk,
+                                          entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
+                                          grub_le_to_cpu16 (entry_item->header.item_location),
+                                          sizeof (entry_v2_stat),
+                                          (char *) &entry_v2_stat);
+                          if (grub_errno)
+                            goto fail;
+#if 0
+                         grub_dprintf ("reiserfs",
+                                        "%04x %04x %08x %08x%08x | %08x %08x %08x %08x | %08x %08x %08x\n",
+                                        grub_le_to_cpu16 (entry_v2_stat.mode),
+                                        grub_le_to_cpu16 (entry_v2_stat.reserved),
+                                        grub_le_to_cpu32 (entry_v2_stat.hardlink_count),
+                                        (unsigned int) (grub_le_to_cpu64 (entry_v2_stat.size) >> 32),
+                                        (unsigned int) (grub_le_to_cpu64 (entry_v2_stat.size) && 0xFFFFFFFF),
+                                        grub_le_to_cpu32 (entry_v2_stat.uid),
+                                        grub_le_to_cpu32 (entry_v2_stat.gid),
+                                        grub_le_to_cpu32 (entry_v2_stat.atime),
+                                        grub_le_to_cpu32 (entry_v2_stat.mtime),
+                                        grub_le_to_cpu32 (entry_v2_stat.ctime),
+                                        grub_le_to_cpu32 (entry_v2_stat.blocks),
+                                        grub_le_to_cpu32 (entry_v2_stat.first_direct_byte));
+                         grub_dprintf ("reiserfs",
+                                        "%04x %04x %08x %08x%08x | %08x %08x %08x %08x | %08x %08x %08x\n",
+                                        entry_v2_stat.mode,
+                                        entry_v2_stat.reserved,
+                                        entry_v2_stat.hardlink_count,
+                                        (unsigned int) (entry_v2_stat.size >> 32),
+                                        (unsigned int) (entry_v2_stat.size && 0xFFFFFFFF),
+                                        entry_v2_stat.uid,
+                                        entry_v2_stat.gid,
+                                        entry_v2_stat.atime,
+                                        entry_v2_stat.mtime,
+                                        entry_v2_stat.ctime,
+                                        entry_v2_stat.blocks,
+                                        entry_v2_stat.first_direct_byte);
+#endif
+                          if ((grub_le_to_cpu16 (entry_v2_stat.mode) & S_IFLNK)
+                              == S_IFLNK)
+                            entry_type = GRUB_FSHELP_SYMLINK;
+                          else
+                            entry_type = GRUB_FSHELP_REG;
+                        }
+                    }
+                  else
+                    {
+                      /* Pseudo file ".." never has stat block.  */
+                      if (grub_strcmp (entry_name, ".."))
+                        grub_dprintf ("reiserfs",
+                                      "Warning : %s has no stat block !\n",
+                                      entry_name);
+                      grub_free (entry_item);
+                      continue;
+                    }
+                }
+              if (hook (entry_name, entry_type, entry_item))
+                {
+                  grub_dprintf ("reiserfs", "Found : %s, type=%d\n",
+                                entry_name, entry_type);
+                  ret = 1;
+                  goto found;
+                }
+
+              *entry_name = 0; /* Make sure next entry name (which is just
+                                  before this one in disk order) stops before
+                                  the current one.  */
+            }
+        }
+
+      if (next_offset == 0)
+        break;
+
+      grub_reiserfs_set_key_offset (&(item_headers[block_position].key),
+                                    next_offset);
+      if (grub_reiserfs_get_item (data, &(item_headers[block_position].key),
+                                  &directory_item) != GRUB_ERR_NONE)
+        goto fail;
+      block_number = directory_item.block_number;
+      block_position = directory_item.block_position;
+      next_offset = directory_item.next_offset;
+    }
+  while (block_number);
+
+ found:
+  assert (grub_errno == GRUB_ERR_NONE);
+  grub_free (block_header);
+  return ret;
+ fail:
+  assert (grub_errno != GRUB_ERR_NONE);
+  grub_free (block_header);
+  return 0;
+}
+
+/****************************************************************************/
+/* grub api functions */
+/****************************************************************************/
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_reiserfs_open (struct grub_file *file, const char *name)
+{
+  struct grub_reiserfs_data *data = 0;
+  struct grub_fshelp_node root, *found = 0, info;
+  struct grub_reiserfs_key key;
+  grub_uint32_t block_number;
+  grub_uint16_t entry_version, block_size, entry_location;
+
+  grub_dl_ref (my_mod);
+  data = grub_reiserfs_mount (file->device->disk);
+  if (! data)
+    goto fail;
+  block_size = grub_le_to_cpu16 (data->superblock.block_size);
+  key.directory_id = grub_cpu_to_le32 (1);
+  key.object_id = grub_cpu_to_le32 (2);
+  key.u.v2.offset_type = 0;
+  grub_reiserfs_set_key_type (&key, GRUB_REISERFS_DIRECTORY, 2);
+  grub_reiserfs_set_key_offset (&key, 1);
+  if (grub_reiserfs_get_item (data, &key, &root) != GRUB_ERR_NONE)
+    goto fail;
+  if (root.block_number == 0)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "unable to find root item");
+      goto fail; /* Should never happen since checked at mount.  */
+    }
+  grub_fshelp_find_file (name, &root, &found,
+                         grub_reiserfs_iterate_dir,
+                         grub_reiserfs_read_symlink, GRUB_FSHELP_REG);
+  if (grub_errno)
+    goto fail;
+  key.directory_id = found->header.key.directory_id;
+  key.object_id = found->header.key.object_id;
+  grub_reiserfs_set_key_type (&key, GRUB_REISERFS_STAT, 2);
+  grub_reiserfs_set_key_offset (&key, 0);
+  if (grub_reiserfs_get_item (data, &key, &info) != GRUB_ERR_NONE)
+    goto fail;
+  if (info.block_number == 0)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "unable to find searched item");
+      goto fail;
+    }
+  entry_version = grub_le_to_cpu16 (info.header.version);
+  entry_location = grub_le_to_cpu16 (info.header.item_location);
+  block_number = info.block_number;
+  if (entry_version == 0) /* Version 1 stat item. */
+    {
+      struct grub_reiserfs_stat_item_v1 entry_v1_stat;
+      grub_disk_read (data->disk,
+                      block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
+                      entry_location
+                      + (((grub_off_t) block_number * block_size)
+                         & (GRUB_DISK_SECTOR_SIZE - 1)),
+                      sizeof (entry_v1_stat), &entry_v1_stat);
+      if (grub_errno)
+        goto fail;
+      file->size = (grub_off_t) grub_le_to_cpu64 (entry_v1_stat.size);
+    }
+  else
+    {
+      struct grub_reiserfs_stat_item_v2 entry_v2_stat;
+      grub_disk_read (data->disk,
+                      block_number * (block_size  >> GRUB_DISK_SECTOR_BITS),
+                      entry_location
+                      + (((grub_off_t) block_number * block_size)
+                         & (GRUB_DISK_SECTOR_SIZE - 1)),
+                      sizeof (entry_v2_stat), &entry_v2_stat);
+      if (grub_errno)
+        goto fail;
+      file->size = (grub_off_t) grub_le_to_cpu64 (entry_v2_stat.size);
+    }
+  grub_dprintf ("reiserfs", "file size : %d (%08x%08x)\n",
+                (unsigned int) file->size,
+                (unsigned int) (file->size >> 32), (unsigned int) file->size);
+  file->offset = 0;
+  file->data = found;
+  return GRUB_ERR_NONE;
+
+ fail:
+  assert (grub_errno != GRUB_ERR_NONE);
+  grub_free (found);
+  grub_free (data);
+  grub_dl_unref (my_mod);
+  return grub_errno;
+}
+
+static grub_ssize_t
+grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  unsigned int indirect_block, indirect_block_count;
+  struct grub_reiserfs_key key;
+  struct grub_fshelp_node *node = file->data;
+  struct grub_reiserfs_data *data = node->data;
+  struct grub_fshelp_node found;
+  grub_uint16_t block_size = grub_le_to_cpu16 (data->superblock.block_size);
+  grub_uint16_t item_size;
+  grub_uint32_t *indirect_block_ptr = 0;
+  grub_uint64_t current_key_offset = 1;
+  grub_off_t initial_position, current_position, final_position, length;
+  grub_disk_addr_t block;
+  grub_off_t offset;
+
+  key.directory_id = node->header.key.directory_id;
+  key.object_id = node->header.key.object_id;
+  key.u.v2.offset_type = 0;
+  grub_reiserfs_set_key_type (&key, GRUB_REISERFS_ANY, 2);
+  initial_position = file->offset;
+  current_position = 0;
+  final_position = MIN (len + initial_position, file->size);
+  grub_dprintf ("reiserfs",
+               "Reading from %lld to %lld (%lld instead of requested %ld)\n",
+               (unsigned long long) initial_position,
+               (unsigned long long) final_position,
+               (unsigned long long) (final_position - initial_position),
+               (unsigned long) len);
+  while (current_position < final_position)
+    {
+      grub_reiserfs_set_key_offset (&key, current_key_offset);
+
+      if (grub_reiserfs_get_item (data, &key, &found) != GRUB_ERR_NONE)
+        goto fail;
+      if (found.block_number == 0)
+        goto fail;
+      item_size = grub_le_to_cpu16 (found.header.item_size);
+      switch (found.type)
+        {
+        case GRUB_REISERFS_DIRECT:
+          block = found.block_number * (block_size  >> GRUB_DISK_SECTOR_BITS);
+          grub_dprintf ("reiserfs_blocktype", "D: %u\n", (unsigned) block);
+          if (initial_position < current_position + item_size)
+            {
+              offset = MAX ((signed) (initial_position - current_position), 0);
+              length = (MIN (item_size, final_position - current_position)
+                        - offset);
+              grub_dprintf ("reiserfs",
+                            "Reading direct block %u from %u to %u...\n",
+                            (unsigned) block, (unsigned) offset,
+                            (unsigned) (offset + length));
+              found.data->disk->read_hook = file->read_hook;
+              grub_disk_read (found.data->disk,
+                              block,
+                              offset
+                              + grub_le_to_cpu16 (found.header.item_location),
+                              length, buf);
+              found.data->disk->read_hook = 0;
+              if (grub_errno)
+                goto fail;
+              buf += length;
+              current_position += offset + length;
+            }
+          else
+            current_position += item_size;
+          break;
+        case GRUB_REISERFS_INDIRECT:
+          indirect_block_count = item_size / sizeof (*indirect_block_ptr);
+          indirect_block_ptr = grub_malloc (item_size);
+          if (! indirect_block_ptr)
+            goto fail;
+          grub_disk_read (found.data->disk,
+                          found.block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
+                          grub_le_to_cpu16 (found.header.item_location),
+                          item_size, indirect_block_ptr);
+          if (grub_errno)
+            goto fail;
+          found.data->disk->read_hook = file->read_hook;
+          for (indirect_block = 0;
+               indirect_block < indirect_block_count
+                 && current_position < final_position;
+               indirect_block++)
+            {
+              block = grub_le_to_cpu32 (indirect_block_ptr[indirect_block]) *
+                      (block_size >> GRUB_DISK_SECTOR_BITS);
+              grub_dprintf ("reiserfs_blocktype", "I: %u\n", (unsigned) block);
+              if (current_position + block_size >= initial_position)
+                {
+                  offset = MAX ((signed) (initial_position - current_position),
+                                0);
+                  length = (MIN (block_size, final_position - current_position)
+                            - offset);
+                  grub_dprintf ("reiserfs",
+                                "Reading indirect block %u from %u to %u...\n",
+                                (unsigned) block, (unsigned) offset,
+                                (unsigned) (offset + length));
+#if 0
+                  grub_dprintf ("reiserfs",
+                                "\nib=%04d/%04d, ip=%d, cp=%d, fp=%d, off=%d, l=%d, tl=%d\n",
+                                indirect_block + 1, indirect_block_count,
+                                initial_position, current_position,
+                                final_position, offset, length, len);
+#endif
+                  grub_disk_read (found.data->disk, block, offset, length, buf);
+                  if (grub_errno)
+                    goto fail;
+                  buf += length;
+                  current_position += offset + length;
+                }
+              else
+                current_position += block_size;
+            }
+          found.data->disk->read_hook = 0;
+          grub_free (indirect_block_ptr);
+          indirect_block_ptr = 0;
+          break;
+        default:
+          goto fail;
+        }
+      current_key_offset = current_position + 1;
+    }
+
+  grub_dprintf ("reiserfs",
+               "Have successfully read %lld bytes (%ld requested)\n",
+               (unsigned long long) (current_position - initial_position),
+               (unsigned long) len);
+  return current_position - initial_position;
+
+#if 0
+  switch (found.type)
+    {
+      case GRUB_REISERFS_DIRECT:
+        read_length = MIN (len, item_size - file->offset);
+        grub_disk_read (found.data->disk,
+                        (found.block_number * block_size) / GRUB_DISK_SECTOR_SIZE,
+                        grub_le_to_cpu16 (found.header.item_location) + file->offset,
+                        read_length, buf);
+        if (grub_errno)
+          goto fail;
+        break;
+      case GRUB_REISERFS_INDIRECT:
+        indirect_block_count = item_size / sizeof (*indirect_block_ptr);
+        indirect_block_ptr = grub_malloc (item_size);
+        if (!indirect_block_ptr)
+          goto fail;
+        grub_disk_read (found.data->disk,
+                        (found.block_number * block_size) / GRUB_DISK_SECTOR_SIZE,
+                        grub_le_to_cpu16 (found.header.item_location),
+                        item_size, (char *) indirect_block_ptr);
+        if (grub_errno)
+          goto fail;
+        len = MIN (len, file->size - file->offset);
+        for (indirect_block = file->offset / block_size;
+             indirect_block < indirect_block_count && read_length < len;
+             indirect_block++)
+          {
+            read = MIN (block_size, len - read_length);
+            grub_disk_read (found.data->disk,
+                            (grub_le_to_cpu32 (indirect_block_ptr[indirect_block]) * block_size) / GRUB_DISK_SECTOR_SIZE,
+                            file->offset % block_size, read,
+                            ((void *) buf) + read_length);
+            if (grub_errno)
+              goto fail;
+            read_length += read;
+          }
+        grub_free (indirect_block_ptr);
+        break;
+      default:
+        goto fail;
+    }
+
+  return read_length;
+#endif
+
+ fail:
+  grub_free (indirect_block_ptr);
+  return 0;
+}
+
+/* Close the file FILE.  */
+static grub_err_t
+grub_reiserfs_close (grub_file_t file)
+{
+  struct grub_fshelp_node *node = file->data;
+  struct grub_reiserfs_data *data = node->data;
+
+  grub_free (data);
+  grub_free (node);
+  grub_dl_unref (my_mod);
+  return GRUB_ERR_NONE;
+}
+
+/* Call HOOK with each file under DIR.  */
+static grub_err_t
+grub_reiserfs_dir (grub_device_t device, const char *path,
+                   int (*hook) (const char *filename,
+                               const struct grub_dirhook_info *info))
+{
+  struct grub_reiserfs_data *data = 0;
+  struct grub_fshelp_node root, *found;
+  struct grub_reiserfs_key root_key;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+                                     enum grub_fshelp_filetype filetype,
+                                     grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+                                enum grub_fshelp_filetype filetype,
+                                grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+    }
+  grub_dl_ref (my_mod);
+  data = grub_reiserfs_mount (device->disk);
+  if (! data)
+    goto fail;
+  root_key.directory_id = grub_cpu_to_le32 (1);
+  root_key.object_id = grub_cpu_to_le32 (2);
+  root_key.u.v2.offset_type = 0;
+  grub_reiserfs_set_key_type (&root_key, GRUB_REISERFS_DIRECTORY, 2);
+  grub_reiserfs_set_key_offset (&root_key, 1);
+  if (grub_reiserfs_get_item (data, &root_key, &root) != GRUB_ERR_NONE)
+    goto fail;
+  if (root.block_number == 0)
+    {
+      grub_error(GRUB_ERR_BAD_FS, "root not found");
+      goto fail;
+    }
+  grub_fshelp_find_file (path, &root, &found, grub_reiserfs_iterate_dir,
+                         grub_reiserfs_read_symlink, GRUB_FSHELP_DIR);
+  if (grub_errno)
+    goto fail;
+  grub_reiserfs_iterate_dir (found, iterate);
+  grub_free (data);
+  grub_dl_unref (my_mod);
+  return GRUB_ERR_NONE;
+
+ fail:
+  grub_free (data);
+  grub_dl_unref (my_mod);
+  return grub_errno;
+}
+
+/* Return the label of the device DEVICE in LABEL.  The label is
+   returned in a grub_malloc'ed buffer and should be freed by the
+   caller.  */
+static grub_err_t
+grub_reiserfs_label (grub_device_t device, char **label)
+{
+  *label = grub_malloc (REISERFS_MAX_LABEL_LENGTH);
+  if (*label)
+    {
+      grub_disk_read (device->disk,
+                      REISERFS_SUPER_BLOCK_OFFSET / GRUB_DISK_SECTOR_SIZE,
+                      REISERFS_LABEL_OFFSET, REISERFS_MAX_LABEL_LENGTH,
+                      *label);
+    }
+  return grub_errno;
+}
+
+static grub_err_t
+grub_reiserfs_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_reiserfs_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_reiserfs_mount (disk);
+  if (data)
+    {
+      *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
+                            grub_be_to_cpu16 (data->superblock.uuid[0]),
+                            grub_be_to_cpu16 (data->superblock.uuid[1]),
+                            grub_be_to_cpu16 (data->superblock.uuid[2]),
+                            grub_be_to_cpu16 (data->superblock.uuid[3]),
+                            grub_be_to_cpu16 (data->superblock.uuid[4]),
+                            grub_be_to_cpu16 (data->superblock.uuid[5]),
+                            grub_be_to_cpu16 (data->superblock.uuid[6]),
+                            grub_be_to_cpu16 (data->superblock.uuid[7]));
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static struct grub_fs grub_reiserfs_fs =
+  {
+    .name = "reiserfs",
+    .dir = grub_reiserfs_dir,
+    .open = grub_reiserfs_open,
+    .read = grub_reiserfs_read,
+    .close = grub_reiserfs_close,
+    .label = grub_reiserfs_label,
+    .uuid = grub_reiserfs_uuid,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(reiserfs)
+{
+  grub_fs_register (&grub_reiserfs_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(reiserfs)
+{
+  grub_fs_unregister (&grub_reiserfs_fs);
+}
diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c
new file mode 100644 (file)
index 0000000..68f8b3a
--- /dev/null
@@ -0,0 +1,597 @@
+/* sfs.c - Amiga Smart FileSystem.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+
+/* The common header for a block.  */
+struct grub_sfs_bheader
+{
+  grub_uint8_t magic[4];
+  grub_uint32_t chksum;
+  grub_uint32_t ipointtomyself;
+} __attribute__ ((packed));
+
+/* The sfs rootblock.  */
+struct grub_sfs_rblock
+{
+  struct grub_sfs_bheader header;
+  grub_uint32_t version;
+  grub_uint8_t unused1[36];
+  grub_uint32_t blocksize;
+  grub_uint8_t unused2[40];
+  grub_uint8_t unused3[8];
+  grub_uint32_t rootobject;
+  grub_uint32_t btree;
+} __attribute__ ((packed));
+
+/* A SFS object container.  */
+struct grub_sfs_obj
+{
+  grub_uint8_t unused1[4];
+  grub_uint32_t nodeid;
+  grub_uint8_t unused2[4];
+  union
+  {
+    struct
+    {
+      grub_uint32_t first_block;
+      grub_uint32_t size;
+    } file __attribute__ ((packed));
+    struct
+    {
+      grub_uint32_t hashtable;
+      grub_uint32_t dir_objc;
+    } dir __attribute__ ((packed));
+  } file_dir;
+  grub_uint8_t unused3[4];
+  grub_uint8_t type;
+  grub_uint8_t filename[1];
+  grub_uint8_t comment[1];
+} __attribute__ ((packed));
+
+#define        GRUB_SFS_TYPE_DELETED   32
+#define        GRUB_SFS_TYPE_SYMLINK   64
+#define        GRUB_SFS_TYPE_DIR       128
+
+/* A SFS object container.  */
+struct grub_sfs_objc
+{
+  struct grub_sfs_bheader header;
+  grub_uint32_t parent;
+  grub_uint32_t next;
+  grub_uint32_t prev;
+  /* The amount of objects depends on the blocksize.  */
+  struct grub_sfs_obj objects[1];
+} __attribute__ ((packed));
+
+struct grub_sfs_btree_node
+{
+  grub_uint32_t key;
+  grub_uint32_t data;
+} __attribute__ ((packed));
+
+struct grub_sfs_btree_extent
+{
+  grub_uint32_t key;
+  grub_uint32_t next;
+  grub_uint32_t prev;
+  grub_uint16_t size;
+} __attribute__ ((packed));
+
+struct grub_sfs_btree
+{
+  struct grub_sfs_bheader header;
+  grub_uint16_t nodes;
+  grub_uint8_t leaf;
+  grub_uint8_t nodesize;
+  /* Normally this can be kind of node, but just extents are
+     supported.  */
+  struct grub_sfs_btree_node node[1];
+} __attribute__ ((packed));
+
+\f
+
+struct grub_fshelp_node
+{
+  struct grub_sfs_data *data;
+  int block;
+  int size;
+};
+
+/* Information about a "mounted" sfs filesystem.  */
+struct grub_sfs_data
+{
+  struct grub_sfs_rblock rblock;
+  struct grub_fshelp_node diropen;
+  grub_disk_t disk;
+
+  /* Blocksize in sectors.  */
+  unsigned int blocksize;
+
+  /* Label of the filesystem.  */
+  char *label;
+};
+
+static grub_dl_t my_mod;
+
+\f
+/* Lookup the extent starting with BLOCK in the filesystem described
+   by DATA.  Return the extent size in SIZE and the following extent
+   in NEXTEXT.  */
+static grub_err_t
+grub_sfs_read_extent (struct grub_sfs_data *data, unsigned int block,
+                     int *size, int *nextext)
+{
+  char *treeblock;
+  struct grub_sfs_btree *tree;
+  int i;
+  int next;
+  int prev;
+
+  treeblock = grub_malloc (data->blocksize);
+  if (!block)
+    return 0;
+
+  next = grub_be_to_cpu32 (data->rblock.btree);
+  tree = (struct grub_sfs_btree *) treeblock;
+
+  /* Handle this level in the btree.  */
+  do
+    {
+      prev = 0;
+
+      grub_disk_read (data->disk, next, 0, data->blocksize, treeblock);
+      if (grub_errno)
+       {
+         grub_free (treeblock);
+         return grub_errno;
+       }
+
+      for (i = grub_be_to_cpu16 (tree->nodes) - 1; i >= 0; i--)
+       {
+
+#define EXTNODE(tree, index)                                           \
+       ((struct grub_sfs_btree_node *) (((char *) &(tree)->node[0])    \
+                                        + (index) * (tree)->nodesize))
+
+         /* Follow the tree down to the leaf level.  */
+         if ((grub_be_to_cpu32 (EXTNODE(tree, i)->key) <= block)
+             && !tree->leaf)
+           {
+             next = grub_be_to_cpu32 (EXTNODE (tree, i)->data);
+             break;
+           }
+
+         /* If the leaf level is reached, just find the correct extent.  */
+         if (grub_be_to_cpu32 (EXTNODE (tree, i)->key) == block && tree->leaf)
+           {
+             struct grub_sfs_btree_extent *extent;
+             extent = (struct grub_sfs_btree_extent *) EXTNODE (tree, i);
+
+             /* We found a correct leaf.  */
+             *size = grub_be_to_cpu16 (extent->size);
+             *nextext = grub_be_to_cpu32 (extent->next);
+
+             grub_free (treeblock);
+             return 0;
+           }
+
+#undef EXTNODE
+
+       }
+    } while (!tree->leaf);
+
+  grub_free (treeblock);
+
+  return grub_error (GRUB_ERR_FILE_READ_ERROR, "SFS extent not found");
+}
+
+static grub_disk_addr_t
+grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+{
+  int blk = node->block;
+  int size = 0;
+  int next = 0;
+
+  while (blk)
+    {
+      grub_err_t err;
+
+      /* In case of the first block we don't have to lookup the
+        extent, the minimum size is always 1.  */
+      if (fileblock == 0)
+       return blk;
+
+      err = grub_sfs_read_extent (node->data, blk, &size, &next);
+      if (err)
+       return 0;
+
+      if (fileblock < (unsigned int) size)
+       return fileblock + blk;
+
+      fileblock -= size;
+
+      blk = next;
+    }
+
+  grub_error (GRUB_ERR_FILE_READ_ERROR,
+             "reading a SFS block outside the extent");
+
+  return 0;
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_sfs_read_file (grub_fshelp_node_t node,
+                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                      unsigned offset, unsigned length),
+                   int pos, grub_size_t len, char *buf)
+{
+  return grub_fshelp_read_file (node->data->disk, node, read_hook,
+                               pos, len, buf, grub_sfs_read_block,
+                               node->size, 0);
+}
+
+
+static struct grub_sfs_data *
+grub_sfs_mount (grub_disk_t disk)
+{
+  struct grub_sfs_data *data;
+  struct grub_sfs_objc *rootobjc;
+  char *rootobjc_data = 0;
+  unsigned int blk;
+
+  data = grub_malloc (sizeof (*data));
+  if (!data)
+    return 0;
+
+  /* Read the rootblock.  */
+  grub_disk_read (disk, 0, 0, sizeof (struct grub_sfs_rblock),
+                 &data->rblock);
+  if (grub_errno)
+    goto fail;
+
+  /* Make sure this is a sfs filesystem.  */
+  if (grub_strncmp ((char *) (data->rblock.header.magic), "SFS", 4))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a SFS filesystem");
+      goto fail;
+    }
+
+  data->blocksize = grub_be_to_cpu32 (data->rblock.blocksize);
+  rootobjc_data = grub_malloc (data->blocksize);
+  if (! rootobjc_data)
+    goto fail;
+
+  /* Read the root object container.  */
+  grub_disk_read (disk, grub_be_to_cpu32 (data->rblock.rootobject), 0,
+                 data->blocksize, rootobjc_data);
+  if (grub_errno)
+    goto fail;
+
+  rootobjc = (struct grub_sfs_objc *) rootobjc_data;
+
+  blk = grub_be_to_cpu32 (rootobjc->objects[0].file_dir.dir.dir_objc);
+  data->diropen.size = 0;
+  data->diropen.block = blk;
+  data->diropen.data = data;
+  data->disk = disk;
+  data->label = grub_strdup ((char *) (rootobjc->objects[0].filename));
+
+  return data;
+
+ fail:
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not an SFS filesystem");
+
+  grub_free (data);
+  grub_free (rootobjc_data);
+  return 0;
+}
+
+
+static char *
+grub_sfs_read_symlink (grub_fshelp_node_t node)
+{
+  struct grub_sfs_data *data = node->data;
+  char *symlink;
+  char *block;
+
+  block = grub_malloc (data->blocksize);
+  if (!block)
+    return 0;
+
+  grub_disk_read (data->disk, node->block, 0, data->blocksize, block);
+  if (grub_errno)
+    {
+      grub_free (block);
+      return 0;
+    }
+
+  /* This is just a wild guess, but it always worked for me.  How the
+     SLNK block looks like is not documented in the SFS docs.  */
+  symlink = grub_strdup (&block[24]);
+  grub_free (block);
+  if (!symlink)
+    return 0;
+
+  return symlink;
+}
+
+static int
+grub_sfs_iterate_dir (grub_fshelp_node_t dir,
+                      int NESTED_FUNC_ATTR
+                      (*hook) (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node))
+{
+  struct grub_fshelp_node *node = 0;
+  struct grub_sfs_data *data = dir->data;
+  char *objc_data;
+  struct grub_sfs_objc *objc;
+  unsigned int next = dir->block;
+  int pos;
+
+  auto int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block,
+                                                 int size, int type);
+
+  int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block,
+                                            int size, int type)
+    {
+      node = grub_malloc (sizeof (*node));
+      if (!node)
+       return 1;
+
+      node->data = data;
+      node->size = size;
+      node->block = block;
+
+      return hook (name, type, node);
+    }
+
+  objc_data = grub_malloc (data->blocksize);
+  if (!objc_data)
+    goto fail;
+
+  /* The Object container can consist of multiple blocks, iterate over
+     every block.  */
+  while (next)
+    {
+      grub_disk_read (data->disk, next, 0, data->blocksize, objc_data);
+      if (grub_errno)
+       goto fail;
+
+      objc = (struct grub_sfs_objc *) objc_data;
+
+      pos = (char *) &objc->objects[0] - (char *) objc;
+
+      /* Iterate over all entries in this block.  */
+      while (pos + sizeof (struct grub_sfs_obj) < data->blocksize)
+       {
+         struct grub_sfs_obj *obj;
+         obj = (struct grub_sfs_obj *) ((char *) objc + pos);
+         char *filename = (char *) (obj->filename);
+         int len;
+         enum grub_fshelp_filetype type;
+         unsigned int block;
+
+         /* The filename and comment dynamically increase the size of
+            the object.  */
+         len = grub_strlen (filename);
+         len += grub_strlen (filename + len + 1);
+
+         pos += sizeof (*obj) + len;
+         /* Round up to a multiple of two bytes.  */
+         pos = ((pos + 1) >> 1) << 1;
+
+         if (grub_strlen (filename) == 0)
+           continue;
+
+         /* First check if the file was not deleted.  */
+         if (obj->type & GRUB_SFS_TYPE_DELETED)
+           continue;
+         else if (obj->type & GRUB_SFS_TYPE_SYMLINK)
+           type = GRUB_FSHELP_SYMLINK;
+         else if (obj->type & GRUB_SFS_TYPE_DIR)
+           type = GRUB_FSHELP_DIR;
+         else
+           type = GRUB_FSHELP_REG;
+
+         if (type == GRUB_FSHELP_DIR)
+           block = grub_be_to_cpu32 (obj->file_dir.dir.dir_objc);
+         else
+           block = grub_be_to_cpu32 (obj->file_dir.file.first_block);
+
+         if (grub_sfs_create_node (filename, block,
+                                   grub_be_to_cpu32 (obj->file_dir.file.size),
+                                   type))
+           {
+             grub_free (objc_data);
+             return 1;
+           }
+       }
+
+      next = grub_be_to_cpu32 (objc->next);
+    }
+
+ fail:
+  grub_free (objc_data);
+  return 0;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_sfs_open (struct grub_file *file, const char *name)
+{
+  struct grub_sfs_data *data;
+  struct grub_fshelp_node *fdiro = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_sfs_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_sfs_iterate_dir,
+                        grub_sfs_read_symlink, GRUB_FSHELP_REG);
+  if (grub_errno)
+    goto fail;
+
+  file->size = fdiro->size;
+  data->diropen = *fdiro;
+  grub_free (fdiro);
+
+  file->data = data;
+  file->offset = 0;
+
+  return 0;
+
+ fail:
+  if (data && fdiro != &data->diropen)
+    grub_free (fdiro);
+  if (data)
+    grub_free (data->label);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_sfs_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+
+/* Read LEN bytes data from FILE into BUF.  */
+static grub_ssize_t
+grub_sfs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_sfs_data *data = (struct grub_sfs_data *) file->data;
+
+  int size = grub_sfs_read_file (&data->diropen, file->read_hook,
+                                file->offset, len, buf);
+
+  return size;
+}
+
+
+static grub_err_t
+grub_sfs_dir (grub_device_t device, const char *path,
+              int (*hook) (const char *filename,
+                           const struct grub_dirhook_info *info))
+{
+  struct grub_sfs_data *data = 0;
+  struct grub_fshelp_node *fdiro = 0;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+                                    enum grub_fshelp_filetype filetype,
+                                    grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+    }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_sfs_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_sfs_iterate_dir,
+                       grub_sfs_read_symlink, GRUB_FSHELP_DIR);
+  if (grub_errno)
+    goto fail;
+
+  grub_sfs_iterate_dir (fdiro, iterate);
+
+ fail:
+  if (data && fdiro != &data->diropen)
+    grub_free (fdiro);
+  if (data)
+    grub_free (data->label);
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+static grub_err_t
+grub_sfs_label (grub_device_t device, char **label)
+{
+  struct grub_sfs_data *data;
+  grub_disk_t disk = device->disk;
+
+  data = grub_sfs_mount (disk);
+  if (data)
+    *label = data->label;
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+\f
+static struct grub_fs grub_sfs_fs =
+  {
+    .name = "sfs",
+    .dir = grub_sfs_dir,
+    .open = grub_sfs_open,
+    .read = grub_sfs_read,
+    .close = grub_sfs_close,
+    .label = grub_sfs_label,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(sfs)
+{
+  grub_fs_register (&grub_sfs_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(sfs)
+{
+  grub_fs_unregister (&grub_sfs_fs);
+}
diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c
new file mode 100644 (file)
index 0000000..6ab62bc
--- /dev/null
@@ -0,0 +1,2 @@
+#define MODE_USTAR 1
+#include "cpio.c"
diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
new file mode 100644 (file)
index 0000000..ad109be
--- /dev/null
@@ -0,0 +1,939 @@
+/* udf.c - Universal Disk Format filesystem.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+#include <grub/charset.h>
+
+#define GRUB_UDF_MAX_PDS               2
+#define GRUB_UDF_MAX_PMS               6
+
+#define U16                            grub_le_to_cpu16
+#define U32                            grub_le_to_cpu32
+#define U64                            grub_le_to_cpu64
+
+#define GRUB_UDF_LOG2_BLKSZ            2
+#define GRUB_UDF_BLKSZ                 2048
+
+#define GRUB_UDF_TAG_IDENT_PVD         0x0001
+#define GRUB_UDF_TAG_IDENT_AVDP                0x0002
+#define GRUB_UDF_TAG_IDENT_VDP         0x0003
+#define GRUB_UDF_TAG_IDENT_IUVD                0x0004
+#define GRUB_UDF_TAG_IDENT_PD          0x0005
+#define GRUB_UDF_TAG_IDENT_LVD         0x0006
+#define GRUB_UDF_TAG_IDENT_USD         0x0007
+#define GRUB_UDF_TAG_IDENT_TD          0x0008
+#define GRUB_UDF_TAG_IDENT_LVID                0x0009
+
+#define GRUB_UDF_TAG_IDENT_FSD         0x0100
+#define GRUB_UDF_TAG_IDENT_FID         0x0101
+#define GRUB_UDF_TAG_IDENT_AED         0x0102
+#define GRUB_UDF_TAG_IDENT_IE          0x0103
+#define GRUB_UDF_TAG_IDENT_TE          0x0104
+#define GRUB_UDF_TAG_IDENT_FE          0x0105
+#define GRUB_UDF_TAG_IDENT_EAHD                0x0106
+#define GRUB_UDF_TAG_IDENT_USE         0x0107
+#define GRUB_UDF_TAG_IDENT_SBD         0x0108
+#define GRUB_UDF_TAG_IDENT_PIE         0x0109
+#define GRUB_UDF_TAG_IDENT_EFE         0x010A
+
+#define GRUB_UDF_ICBTAG_TYPE_UNDEF     0x00
+#define GRUB_UDF_ICBTAG_TYPE_USE       0x01
+#define GRUB_UDF_ICBTAG_TYPE_PIE       0x02
+#define GRUB_UDF_ICBTAG_TYPE_IE                0x03
+#define GRUB_UDF_ICBTAG_TYPE_DIRECTORY 0x04
+#define GRUB_UDF_ICBTAG_TYPE_REGULAR   0x05
+#define GRUB_UDF_ICBTAG_TYPE_BLOCK     0x06
+#define GRUB_UDF_ICBTAG_TYPE_CHAR      0x07
+#define GRUB_UDF_ICBTAG_TYPE_EA                0x08
+#define GRUB_UDF_ICBTAG_TYPE_FIFO      0x09
+#define GRUB_UDF_ICBTAG_TYPE_SOCKET    0x0A
+#define GRUB_UDF_ICBTAG_TYPE_TE                0x0B
+#define GRUB_UDF_ICBTAG_TYPE_SYMLINK   0x0C
+#define GRUB_UDF_ICBTAG_TYPE_STREAMDIR 0x0D
+
+#define GRUB_UDF_ICBTAG_FLAG_AD_MASK   0x0007
+#define GRUB_UDF_ICBTAG_FLAG_AD_SHORT  0x0000
+#define GRUB_UDF_ICBTAG_FLAG_AD_LONG   0x0001
+#define GRUB_UDF_ICBTAG_FLAG_AD_EXT    0x0002
+#define GRUB_UDF_ICBTAG_FLAG_AD_IN_ICB 0x0003
+
+#define GRUB_UDF_EXT_NORMAL            0x00000000
+#define GRUB_UDF_EXT_NREC_ALLOC                0x40000000
+#define GRUB_UDF_EXT_NREC_NALLOC       0x80000000
+#define GRUB_UDF_EXT_MASK              0xC0000000
+
+#define GRUB_UDF_FID_CHAR_HIDDEN       0x01
+#define GRUB_UDF_FID_CHAR_DIRECTORY    0x02
+#define GRUB_UDF_FID_CHAR_DELETED      0x04
+#define GRUB_UDF_FID_CHAR_PARENT       0x08
+#define GRUB_UDF_FID_CHAR_METADATA     0x10
+
+#define GRUB_UDF_STD_IDENT_BEA01       "BEA01"
+#define GRUB_UDF_STD_IDENT_BOOT2       "BOOT2"
+#define GRUB_UDF_STD_IDENT_CD001       "CD001"
+#define GRUB_UDF_STD_IDENT_CDW02       "CDW02"
+#define GRUB_UDF_STD_IDENT_NSR02       "NSR02"
+#define GRUB_UDF_STD_IDENT_NSR03       "NSR03"
+#define GRUB_UDF_STD_IDENT_TEA01       "TEA01"
+
+#define GRUB_UDF_CHARSPEC_TYPE_CS0     0x00
+#define GRUB_UDF_CHARSPEC_TYPE_CS1     0x01
+#define GRUB_UDF_CHARSPEC_TYPE_CS2     0x02
+#define GRUB_UDF_CHARSPEC_TYPE_CS3     0x03
+#define GRUB_UDF_CHARSPEC_TYPE_CS4     0x04
+#define GRUB_UDF_CHARSPEC_TYPE_CS5     0x05
+#define GRUB_UDF_CHARSPEC_TYPE_CS6     0x06
+#define GRUB_UDF_CHARSPEC_TYPE_CS7     0x07
+#define GRUB_UDF_CHARSPEC_TYPE_CS8     0x08
+
+#define GRUB_UDF_PARTMAP_TYPE_1                1
+#define GRUB_UDF_PARTMAP_TYPE_2                2
+
+struct grub_udf_lb_addr
+{
+  grub_uint32_t block_num;
+  grub_uint16_t part_ref;
+} __attribute__ ((packed));
+
+struct grub_udf_short_ad
+{
+  grub_uint32_t length;
+  grub_uint32_t position;
+} __attribute__ ((packed));
+
+struct grub_udf_long_ad
+{
+  grub_uint32_t length;
+  struct grub_udf_lb_addr block;
+  grub_uint8_t imp_use[6];
+} __attribute__ ((packed));
+
+struct grub_udf_extent_ad
+{
+  grub_uint32_t length;
+  grub_uint32_t start;
+} __attribute__ ((packed));
+
+struct grub_udf_charspec
+{
+  grub_uint8_t charset_type;
+  grub_uint8_t charset_info[63];
+} __attribute__ ((packed));
+
+struct grub_udf_timestamp
+{
+  grub_uint16_t type_and_timezone;
+  grub_uint16_t year;
+  grub_uint8_t month;
+  grub_uint8_t day;
+  grub_uint8_t hour;
+  grub_uint8_t minute;
+  grub_uint8_t second;
+  grub_uint8_t centi_seconds;
+  grub_uint8_t hundreds_of_micro_seconds;
+  grub_uint8_t micro_seconds;
+} __attribute__ ((packed));
+
+struct grub_udf_regid
+{
+  grub_uint8_t flags;
+  grub_uint8_t ident[23];
+  grub_uint8_t ident_suffix[8];
+} __attribute__ ((packed));
+
+struct grub_udf_tag
+{
+  grub_uint16_t tag_ident;
+  grub_uint16_t desc_version;
+  grub_uint8_t tag_checksum;
+  grub_uint8_t reserved;
+  grub_uint16_t tag_serial_number;
+  grub_uint16_t desc_crc;
+  grub_uint16_t desc_crc_length;
+  grub_uint32_t tag_location;
+} __attribute__ ((packed));
+
+struct grub_udf_fileset
+{
+  struct grub_udf_tag tag;
+  struct grub_udf_timestamp datetime;
+  grub_uint16_t interchange_level;
+  grub_uint16_t max_interchange_level;
+  grub_uint32_t charset_list;
+  grub_uint32_t max_charset_list;
+  grub_uint32_t fileset_num;
+  grub_uint32_t fileset_desc_num;
+  struct grub_udf_charspec vol_charset;
+  grub_uint8_t vol_ident[128];
+  struct grub_udf_charspec fileset_charset;
+  grub_uint8_t fileset_ident[32];
+  grub_uint8_t copyright_file_ident[32];
+  grub_uint8_t abstract_file_ident[32];
+  struct grub_udf_long_ad root_icb;
+  struct grub_udf_regid domain_ident;
+  struct grub_udf_long_ad next_ext;
+  struct grub_udf_long_ad streamdir_icb;
+} __attribute__ ((packed));
+
+struct grub_udf_icbtag
+{
+  grub_uint32_t prior_recorded_num_direct_entries;
+  grub_uint16_t strategy_type;
+  grub_uint16_t strategy_parameter;
+  grub_uint16_t num_entries;
+  grub_uint8_t reserved;
+  grub_uint8_t file_type;
+  struct grub_udf_lb_addr parent_idb;
+  grub_uint16_t flags;
+} __attribute__ ((packed));
+
+struct grub_udf_file_ident
+{
+  struct grub_udf_tag tag;
+  grub_uint16_t version_num;
+  grub_uint8_t characteristics;
+  grub_uint8_t file_ident_length;
+  struct grub_udf_long_ad icb;
+  grub_uint16_t imp_use_length;
+} __attribute__ ((packed));
+
+struct grub_udf_file_entry
+{
+  struct grub_udf_tag tag;
+  struct grub_udf_icbtag icbtag;
+  grub_uint32_t uid;
+  grub_uint32_t gid;
+  grub_uint32_t permissions;
+  grub_uint16_t link_count;
+  grub_uint8_t record_format;
+  grub_uint8_t record_display_attr;
+  grub_uint32_t record_length;
+  grub_uint64_t file_size;
+  grub_uint64_t blocks_recorded;
+  struct grub_udf_timestamp access_time;
+  struct grub_udf_timestamp modification_time;
+  struct grub_udf_timestamp attr_time;
+  grub_uint32_t checkpoint;
+  struct grub_udf_long_ad extended_attr_idb;
+  struct grub_udf_regid imp_ident;
+  grub_uint64_t unique_id;
+  grub_uint32_t ext_attr_length;
+  grub_uint32_t alloc_descs_length;
+  grub_uint8_t ext_attr[1872];
+} __attribute__ ((packed));
+
+struct grub_udf_extended_file_entry
+{
+  struct grub_udf_tag tag;
+  struct grub_udf_icbtag icbtag;
+  grub_uint32_t uid;
+  grub_uint32_t gid;
+  grub_uint32_t permissions;
+  grub_uint16_t link_count;
+  grub_uint8_t record_format;
+  grub_uint8_t record_display_attr;
+  grub_uint32_t record_length;
+  grub_uint64_t file_size;
+  grub_uint64_t object_size;
+  grub_uint64_t blocks_recorded;
+  struct grub_udf_timestamp access_time;
+  struct grub_udf_timestamp modification_time;
+  struct grub_udf_timestamp create_time;
+  struct grub_udf_timestamp attr_time;
+  grub_uint32_t checkpoint;
+  grub_uint32_t reserved;
+  struct grub_udf_long_ad extended_attr_icb;
+  struct grub_udf_long_ad streamdir_icb;
+  struct grub_udf_regid imp_ident;
+  grub_uint64_t unique_id;
+  grub_uint32_t ext_attr_length;
+  grub_uint32_t alloc_descs_length;
+  grub_uint8_t ext_attr[1832];
+} __attribute__ ((packed));
+
+struct grub_udf_vrs
+{
+  grub_uint8_t type;
+  grub_uint8_t magic[5];
+  grub_uint8_t version;
+} __attribute__ ((packed));
+
+struct grub_udf_avdp
+{
+  struct grub_udf_tag tag;
+  struct grub_udf_extent_ad vds;
+} __attribute__ ((packed));
+
+struct grub_udf_pd
+{
+  struct grub_udf_tag tag;
+  grub_uint32_t seq_num;
+  grub_uint16_t flags;
+  grub_uint16_t part_num;
+  struct grub_udf_regid contents;
+  grub_uint8_t contents_use[128];
+  grub_uint32_t access_type;
+  grub_uint32_t start;
+  grub_uint32_t length;
+} __attribute__ ((packed));
+
+struct grub_udf_partmap
+{
+  grub_uint8_t type;
+  grub_uint8_t length;
+  union
+  {
+    struct
+    {
+      grub_uint16_t seq_num;
+      grub_uint16_t part_num;
+    } type1;
+
+    struct
+    {
+      grub_uint8_t ident[62];
+    } type2;
+  };
+};
+
+struct grub_udf_lvd
+{
+  struct grub_udf_tag tag;
+  grub_uint32_t seq_num;
+  struct grub_udf_charspec charset;
+  grub_uint8_t ident[128];
+  grub_uint32_t bsize;
+  struct grub_udf_regid domain_ident;
+  struct grub_udf_long_ad root_fileset;
+  grub_uint32_t map_table_length;
+  grub_uint32_t num_part_maps;
+  struct grub_udf_regid imp_ident;
+  grub_uint8_t imp_use[128];
+  struct grub_udf_extent_ad integrity_seq_ext;
+  grub_uint8_t part_maps[1608];
+} __attribute__ ((packed));
+
+struct grub_udf_data
+{
+  grub_disk_t disk;
+  struct grub_udf_lvd lvd;
+  struct grub_udf_pd pds[GRUB_UDF_MAX_PDS];
+  struct grub_udf_partmap *pms[GRUB_UDF_MAX_PMS];
+  struct grub_udf_long_ad root_icb;
+  int npd, npm;
+};
+
+struct grub_fshelp_node
+{
+  struct grub_udf_data *data;
+  union
+  {
+    struct grub_udf_file_entry fe;
+    struct grub_udf_extended_file_entry efe;
+  };
+  int part_ref;
+};
+
+static grub_dl_t my_mod;
+
+static grub_uint32_t
+grub_udf_get_block (struct grub_udf_data *data,
+                   grub_uint16_t part_ref, grub_uint32_t block)
+{
+  part_ref = U16 (part_ref);
+
+  if (part_ref >= data->npm)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "invalid part ref");
+      return 0;
+    }
+
+  return (U32 (data->pds[data->pms[part_ref]->type1.part_num].start)
+          + U32 (block));
+}
+
+static grub_err_t
+grub_udf_read_icb (struct grub_udf_data *data,
+                  struct grub_udf_long_ad *icb,
+                  struct grub_fshelp_node *node)
+{
+  grub_uint32_t block;
+
+  block = grub_udf_get_block (data,
+                             icb->block.part_ref,
+                              icb->block.block_num);
+
+  if (grub_errno)
+    return grub_errno;
+
+  if (grub_disk_read (data->disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+                     sizeof (struct grub_udf_file_entry),
+                     &node->fe))
+    return grub_errno;
+
+  if ((U16 (node->fe.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FE) &&
+      (U16 (node->fe.tag.tag_ident) != GRUB_UDF_TAG_IDENT_EFE))
+    return grub_error (GRUB_ERR_BAD_FS, "invalid fe/efe descriptor");
+
+  node->part_ref = icb->block.part_ref;
+  node->data = data;
+  return 0;
+}
+
+static grub_disk_addr_t
+grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+{
+  char *ptr;
+  int len;
+  grub_disk_addr_t filebytes;
+
+  if (U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE)
+    {
+      ptr = (char *) &node->fe.ext_attr[0] + U32 (node->fe.ext_attr_length);
+      len = U32 (node->fe.alloc_descs_length);
+    }
+  else
+    {
+      ptr = (char *) &node->efe.ext_attr[0] + U32 (node->efe.ext_attr_length);
+      len = U32 (node->efe.alloc_descs_length);
+    }
+
+  if ((U16 (node->fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK)
+      == GRUB_UDF_ICBTAG_FLAG_AD_SHORT)
+    {
+      struct grub_udf_short_ad *ad = (struct grub_udf_short_ad *) ptr;
+
+      len /= sizeof (struct grub_udf_short_ad);
+      filebytes = fileblock * GRUB_UDF_BLKSZ;
+      while (len > 0)
+       {
+         if (filebytes < U32 (ad->length))
+           return ((U32 (ad->position) & GRUB_UDF_EXT_MASK) ? 0 :
+                    (grub_udf_get_block (node->data,
+                                         node->part_ref,
+                                         ad->position)
+                     + (filebytes / GRUB_UDF_BLKSZ)));
+
+         filebytes -= U32 (ad->length);
+         ad++;
+         len--;
+       }
+    }
+  else
+    {
+      struct grub_udf_long_ad *ad = (struct grub_udf_long_ad *) ptr;
+
+      len /= sizeof (struct grub_udf_long_ad);
+      filebytes = fileblock * GRUB_UDF_BLKSZ;
+      while (len > 0)
+       {
+         if (filebytes < U32 (ad->length))
+           return ((U32 (ad->block.block_num) & GRUB_UDF_EXT_MASK) ?  0 :
+                    (grub_udf_get_block (node->data,
+                                         ad->block.part_ref,
+                                         ad->block.block_num)
+                    + (filebytes / GRUB_UDF_BLKSZ)));
+
+         filebytes -= U32 (ad->length);
+         ad++;
+         len--;
+       }
+    }
+
+  return 0;
+}
+
+static grub_ssize_t
+grub_udf_read_file (grub_fshelp_node_t node,
+                   void NESTED_FUNC_ATTR
+                   (*read_hook) (grub_disk_addr_t sector,
+                                 unsigned offset, unsigned length),
+                   int pos, grub_size_t len, char *buf)
+{
+  switch (U16 (node->fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK)
+    {
+    case GRUB_UDF_ICBTAG_FLAG_AD_IN_ICB:
+      {
+       char *ptr;
+
+       ptr = ((U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE) ?
+              ((char *) &node->fe.ext_attr[0]
+                + U32 (node->fe.ext_attr_length)) :
+              ((char *) &node->efe.ext_attr[0]
+                + U32 (node->efe.ext_attr_length)));
+
+       grub_memcpy (buf, ptr + pos, len);
+
+       return len;
+      }
+
+    case GRUB_UDF_ICBTAG_FLAG_AD_EXT:
+      grub_error (GRUB_ERR_BAD_FS, "invalid extent type");
+      return 0;
+    }
+
+  return  grub_fshelp_read_file (node->data->disk, node, read_hook,
+                                 pos, len, buf, grub_udf_read_block,
+                                 U64 (node->fe.file_size),
+                                 GRUB_UDF_LOG2_BLKSZ);
+}
+
+static int sblocklist[] = { 256, 512, 0 };
+
+static struct grub_udf_data *
+grub_udf_mount (grub_disk_t disk)
+{
+  struct grub_udf_data *data = 0;
+  struct grub_udf_fileset root_fs;
+  int *sblklist = sblocklist;
+  grub_uint32_t block;
+  int i;
+
+  data = grub_malloc (sizeof (struct grub_udf_data));
+  if (!data)
+    return 0;
+
+  data->disk = disk;
+
+  /* Search for Volume Recognition Sequence (VRS).  */
+  for (block = 16;; block++)
+    {
+      struct grub_udf_vrs vrs;
+
+      if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+                         sizeof (struct grub_udf_vrs), &vrs))
+       {
+         grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
+         goto fail;
+       }
+
+      if ((!grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_NSR03, 5)) ||
+         (!grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_NSR02, 5)))
+       break;
+
+      if ((grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_BEA01, 5)) &&
+         (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_BOOT2, 5)) &&
+         (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_CD001, 5)) &&
+         (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_CDW02, 5)) &&
+         (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_TEA01, 5)))
+       {
+         grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
+         goto fail;
+       }
+    }
+
+  /* Search for Anchor Volume Descriptor Pointer (AVDP).  */
+  while (1)
+    {
+      struct grub_udf_avdp avdp;
+
+      if (grub_disk_read (disk, *sblklist << GRUB_UDF_LOG2_BLKSZ, 0,
+                         sizeof (struct grub_udf_avdp), &avdp))
+       {
+         grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
+         goto fail;
+       }
+
+      if (U16 (avdp.tag.tag_ident) == GRUB_UDF_TAG_IDENT_AVDP)
+       {
+         block = U32 (avdp.vds.start);
+         break;
+       }
+
+      sblklist++;
+      if (*sblklist == 0)
+       {
+         grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
+         goto fail;
+       }
+    }
+
+  data->npd = data->npm = 0;
+  /* Locate Partition Descriptor (PD) and Logical Volume Descriptor (LVD).  */
+  while (1)
+    {
+      struct grub_udf_tag tag;
+
+      if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+                         sizeof (struct grub_udf_tag), &tag))
+       {
+         grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
+         goto fail;
+       }
+
+      tag.tag_ident = U16 (tag.tag_ident);
+      if (tag.tag_ident == GRUB_UDF_TAG_IDENT_PD)
+       {
+         if (data->npd >= GRUB_UDF_MAX_PDS)
+           {
+             grub_error (GRUB_ERR_BAD_FS, "too many PDs");
+             goto fail;
+           }
+
+         if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+                             sizeof (struct grub_udf_pd),
+                             &data->pds[data->npd]))
+           {
+             grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
+             goto fail;
+           }
+
+         data->npd++;
+       }
+      else if (tag.tag_ident == GRUB_UDF_TAG_IDENT_LVD)
+       {
+         int k;
+
+         struct grub_udf_partmap *ppm;
+
+         if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+                             sizeof (struct grub_udf_lvd),
+                             &data->lvd))
+           {
+             grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
+             goto fail;
+           }
+
+         if (data->npm + U32 (data->lvd.num_part_maps) > GRUB_UDF_MAX_PMS)
+           {
+             grub_error (GRUB_ERR_BAD_FS, "too many partition maps");
+             goto fail;
+           }
+
+         ppm = (struct grub_udf_partmap *) &data->lvd.part_maps;
+         for (k = U32 (data->lvd.num_part_maps); k > 0; k--)
+           {
+             if (ppm->type != GRUB_UDF_PARTMAP_TYPE_1)
+               {
+                 grub_error (GRUB_ERR_BAD_FS, "partmap type not supported");
+                 goto fail;
+               }
+
+             data->pms[data->npm++] = ppm;
+             ppm = (struct grub_udf_partmap *) ((char *) ppm +
+                                                 U32 (ppm->length));
+           }
+       }
+      else if (tag.tag_ident > GRUB_UDF_TAG_IDENT_TD)
+       {
+         grub_error (GRUB_ERR_BAD_FS, "invalid tag ident");
+         goto fail;
+       }
+      else if (tag.tag_ident == GRUB_UDF_TAG_IDENT_TD)
+       break;
+
+      block++;
+    }
+
+  for (i = 0; i < data->npm; i++)
+    {
+      int j;
+
+      for (j = 0; j < data->npd; j++)
+       if (data->pms[i]->type1.part_num == data->pds[j].part_num)
+         {
+           data->pms[i]->type1.part_num = j;
+           break;
+         }
+
+      if (j == data->npd)
+       {
+         grub_error (GRUB_ERR_BAD_FS, "can\'t find PD");
+         goto fail;
+       }
+    }
+
+  block = grub_udf_get_block (data,
+                             data->lvd.root_fileset.block.part_ref,
+                             data->lvd.root_fileset.block.block_num);
+
+  if (grub_errno)
+    goto fail;
+
+  if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0,
+                     sizeof (struct grub_udf_fileset), &root_fs))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
+      goto fail;
+    }
+
+  if (U16 (root_fs.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FSD)
+    {
+      grub_error (GRUB_ERR_BAD_FS, "invalid fileset descriptor");
+      goto fail;
+    }
+
+  data->root_icb = root_fs.root_icb;
+
+  return data;
+
+fail:
+  grub_free (data);
+  return 0;
+}
+
+static int
+grub_udf_iterate_dir (grub_fshelp_node_t dir,
+                     int NESTED_FUNC_ATTR
+                     (*hook) (const char *filename,
+                              enum grub_fshelp_filetype filetype,
+                              grub_fshelp_node_t node))
+{
+  grub_fshelp_node_t child;
+  struct grub_udf_file_ident dirent;
+  grub_uint32_t offset = 0;
+
+  child = grub_malloc (sizeof (struct grub_fshelp_node));
+  if (!child)
+    return 0;
+
+  /* The current directory is not stored.  */
+  grub_memcpy ((char *) child, (char *) dir,
+              sizeof (struct grub_fshelp_node));
+
+  if (hook (".", GRUB_FSHELP_DIR, child))
+    return 1;
+
+  while (offset < U64 (dir->fe.file_size))
+    {
+      if (grub_udf_read_file (dir, 0, offset, sizeof (dirent),
+                             (char *) &dirent) != sizeof (dirent))
+       return 0;
+
+      if (U16 (dirent.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FID)
+       {
+         grub_error (GRUB_ERR_BAD_FS, "invalid fid tag");
+         return 0;
+       }
+
+      child = grub_malloc (sizeof (struct grub_fshelp_node));
+      if (!child)
+       return 0;
+
+      if (grub_udf_read_icb (dir->data, &dirent.icb, child))
+       return 0;
+
+      offset += sizeof (dirent) + U16 (dirent.imp_use_length);
+      if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT)
+       {
+         /* This is the parent directory.  */
+         if (hook ("..", GRUB_FSHELP_DIR, child))
+           return 1;
+       }
+      else
+       {
+         enum grub_fshelp_filetype type;
+         grub_uint8_t raw[dirent.file_ident_length];
+         grub_uint16_t utf16[dirent.file_ident_length - 1];
+         grub_uint8_t filename[dirent.file_ident_length * 2];
+         grub_size_t utf16len = 0;
+
+         type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ?
+                 (GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG));
+
+         if ((grub_udf_read_file (dir, 0, offset,
+                                  dirent.file_ident_length,
+                                  (char *) raw))
+             != dirent.file_ident_length)
+           return 0;
+
+         if (raw[0] == 8)
+           {
+             unsigned i;
+             utf16len = dirent.file_ident_length - 1;
+             for (i = 0; i < utf16len; i++)
+               utf16[i] = raw[i + 1];
+           }
+         if (raw[0] == 16)
+           {
+             unsigned i;
+             utf16len = (dirent.file_ident_length - 1) / 2;
+             for (i = 0; i < utf16len; i++)
+               utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
+           }
+         if (raw[0] == 8 || raw[0] == 16)
+           {
+             *grub_utf16_to_utf8 (filename, utf16, utf16len) = '\0';
+         
+             if (hook ((char *) filename, type, child))
+               return 1;
+           }
+       }
+
+      /* Align to dword boundary.  */
+      offset = (offset + dirent.file_ident_length + 3) & (~3);
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_udf_dir (grub_device_t device, const char *path,
+             int (*hook) (const char *filename,
+                          const struct grub_dirhook_info *info))
+{
+  struct grub_udf_data *data = 0;
+  struct grub_fshelp_node rootnode;
+  struct grub_fshelp_node *foundnode;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+                                    enum grub_fshelp_filetype filetype,
+                                    grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node)
+  {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+  }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_udf_mount (device->disk);
+  if (!data)
+    goto fail;
+
+  if (grub_udf_read_icb (data, &data->root_icb, &rootnode))
+    goto fail;
+
+  if (grub_fshelp_find_file (path, &rootnode,
+                            &foundnode,
+                            grub_udf_iterate_dir, 0, GRUB_FSHELP_DIR))
+    goto fail;
+
+  grub_udf_iterate_dir (foundnode, iterate);
+
+  if (foundnode != &rootnode)
+    grub_free (foundnode);
+
+fail:
+  grub_free (data);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_udf_open (struct grub_file *file, const char *name)
+{
+  struct grub_udf_data *data;
+  struct grub_fshelp_node rootnode;
+  struct grub_fshelp_node *foundnode;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_udf_mount (file->device->disk);
+  if (!data)
+    goto fail;
+
+  if (grub_udf_read_icb (data, &data->root_icb, &rootnode))
+    goto fail;
+
+  if (grub_fshelp_find_file (name, &rootnode,
+                            &foundnode,
+                            grub_udf_iterate_dir, 0, GRUB_FSHELP_REG))
+    goto fail;
+
+  file->data = foundnode;
+  file->offset = 0;
+  file->size = U64 (foundnode->fe.file_size);
+
+  return 0;
+
+fail:
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static grub_ssize_t
+grub_udf_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_fshelp_node *node = (struct grub_fshelp_node *) file->data;
+
+  return grub_udf_read_file (node, file->read_hook, file->offset, len, buf);
+}
+
+static grub_err_t
+grub_udf_close (grub_file_t file)
+{
+  if (file->data)
+    {
+      struct grub_fshelp_node *node = (struct grub_fshelp_node *) file->data;
+
+      grub_free (node->data);
+      grub_free (node);
+    }
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_udf_label (grub_device_t device, char **label)
+{
+  struct grub_udf_data *data;
+  data = grub_udf_mount (device->disk);
+
+  if (data)
+    {
+      *label = grub_strdup ((char *) &data->lvd.ident[1]);
+      grub_free (data);
+    }
+  else
+    *label = 0;
+
+  return grub_errno;
+}
+
+static struct grub_fs grub_udf_fs = {
+  .name = "udf",
+  .dir = grub_udf_dir,
+  .open = grub_udf_open,
+  .read = grub_udf_read,
+  .close = grub_udf_close,
+  .label = grub_udf_label,
+  .next = 0
+};
+
+GRUB_MOD_INIT (udf)
+{
+  grub_fs_register (&grub_udf_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI (udf)
+{
+  grub_fs_unregister (&grub_udf_fs);
+}
diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c
new file mode 100644 (file)
index 0000000..40cf068
--- /dev/null
@@ -0,0 +1,813 @@
+/* ufs.c - Unix File System */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+
+#ifdef MODE_UFS2
+#define GRUB_UFS_MAGIC         0x19540119
+#else
+#define GRUB_UFS_MAGIC         0x11954
+#endif
+
+#define GRUB_UFS_INODE         2
+#define GRUB_UFS_FILETYPE_DIR  4
+#define GRUB_UFS_FILETYPE_LNK  10
+#define GRUB_UFS_MAX_SYMLNK_CNT        8
+
+#define GRUB_UFS_DIRBLKS       12
+#define GRUB_UFS_INDIRBLKS     3
+
+#define GRUB_UFS_ATTR_TYPE      0160000
+#define GRUB_UFS_ATTR_FILE     0100000
+#define GRUB_UFS_ATTR_DIR      0040000
+#define GRUB_UFS_ATTR_LNK       0120000
+
+#define GRUB_UFS_VOLNAME_LEN   32
+
+/* Calculate in which group the inode can be found.  */
+#define UFS_BLKSZ(sblock) (grub_le_to_cpu32 (sblock->bsize))
+
+#define INODE(data,field) data->inode.  field
+#ifdef MODE_UFS2
+#define INODE_ENDIAN(data,field,bits1,bits2) grub_le_to_cpu##bits2 (data->inode.field)
+#else
+#define INODE_ENDIAN(data,field,bits1,bits2) grub_le_to_cpu##bits1 (data->inode.field)
+#endif
+
+#define INODE_SIZE(data) INODE_ENDIAN (data,size,32,64)
+#define INODE_NBLOCKS(data) INODE_ENDIAN (data,nblocks,32,64)
+
+#define INODE_MODE(data) INODE_ENDIAN (data,mode,16,16)
+#ifdef MODE_UFS2
+#define INODE_BLKSZ 8
+#else
+#define INODE_BLKSZ 4
+#endif
+#ifdef MODE_UFS2
+#define UFS_INODE_PER_BLOCK 2
+#else
+#define UFS_INODE_PER_BLOCK 4
+#endif
+#define INODE_DIRBLOCKS(data,blk) INODE_ENDIAN \
+                                   (data,blocks.dir_blocks[blk],32,64)
+#define INODE_INDIRBLOCKS(data,blk) INODE_ENDIAN \
+                                     (data,blocks.indir_blocks[blk],32,64)
+
+/* The blocks on which the superblock can be found.  */
+static int sblocklist[] = { 128, 16, 0, 512, -1 };
+
+struct grub_ufs_sblock
+{
+  grub_uint8_t unused[16];
+  /* The offset of the inodes in the cylinder group.  */
+  grub_uint32_t inoblk_offs;
+
+  grub_uint8_t unused2[4];
+
+  /* The start of the cylinder group.  */
+  grub_uint32_t cylg_offset;
+  grub_uint32_t cylg_mask;
+
+  grub_uint32_t mtime;
+  grub_uint8_t unused4[12];
+
+  /* The size of a block in bytes.  */
+  grub_int32_t bsize;
+  grub_uint8_t unused5[48];
+
+  /* The size of filesystem blocks to disk blocks.  */
+  grub_uint32_t log2_blksz;
+  grub_uint8_t unused6[40];
+  grub_uint32_t uuidhi;
+  grub_uint32_t uuidlow;
+  grub_uint8_t unused7[32];
+
+  /* Inodes stored per cylinder group.  */
+  grub_uint32_t ino_per_group;
+
+  /* The frags per cylinder group.  */
+  grub_uint32_t frags_per_group;
+
+  grub_uint8_t unused8[488];
+
+  /* Volume name for UFS2.  */
+  grub_uint8_t volume_name[GRUB_UFS_VOLNAME_LEN];
+  grub_uint8_t unused9[360];
+
+  grub_uint64_t mtime2;
+  grub_uint8_t unused10[292];
+
+  /* Magic value to check if this is really a UFS filesystem.  */
+  grub_uint32_t magic;
+};
+
+#ifdef MODE_UFS2
+/* UFS inode.  */
+struct grub_ufs_inode
+{
+  grub_uint16_t mode;
+  grub_uint16_t nlinks;
+  grub_uint32_t uid;
+  grub_uint32_t gid;
+  grub_uint32_t blocksize;
+  grub_int64_t size;
+  grub_int64_t nblocks;
+  grub_uint64_t atime;
+  grub_uint64_t mtime;
+  grub_uint64_t ctime;
+  grub_uint64_t create_time;
+  grub_uint32_t atime_sec;
+  grub_uint32_t mtime_sec;
+  grub_uint32_t ctime_sec;
+  grub_uint32_t create_time_sec;
+  grub_uint32_t gen;
+  grub_uint32_t kernel_flags;
+  grub_uint32_t flags;
+  grub_uint32_t extsz;
+  grub_uint64_t ext[2];
+  union
+  {
+    struct
+    {
+      grub_uint64_t dir_blocks[GRUB_UFS_DIRBLKS];
+      grub_uint64_t indir_blocks[GRUB_UFS_INDIRBLKS];
+    } blocks;
+    grub_uint8_t symlink[(GRUB_UFS_DIRBLKS + GRUB_UFS_INDIRBLKS) * 8];
+  };
+
+  grub_uint8_t unused[24];
+} __attribute__ ((packed));
+#else
+/* UFS inode.  */
+struct grub_ufs_inode
+{
+  grub_uint16_t mode;
+  grub_uint16_t nlinks;
+  grub_uint16_t uid;
+  grub_uint16_t gid;
+  grub_int64_t size;
+  grub_uint64_t atime;
+  grub_uint64_t mtime;
+  grub_uint64_t ctime;
+  union
+  {
+    struct
+    {
+      grub_uint32_t dir_blocks[GRUB_UFS_DIRBLKS];
+      grub_uint32_t indir_blocks[GRUB_UFS_INDIRBLKS];
+    } blocks;
+    grub_uint8_t symlink[(GRUB_UFS_DIRBLKS + GRUB_UFS_INDIRBLKS) * 4];
+  };
+  grub_uint32_t flags;
+  grub_uint32_t nblocks;
+  grub_uint32_t gen;
+  grub_uint32_t unused;
+  grub_uint8_t pad[12];
+} __attribute__ ((packed));
+#endif
+
+/* Directory entry.  */
+struct grub_ufs_dirent
+{
+  grub_uint32_t ino;
+  grub_uint16_t direntlen;
+  union
+  {
+    grub_uint16_t namelen;
+    struct
+    {
+      grub_uint8_t filetype_bsd;
+      grub_uint8_t namelen_bsd;
+    };
+  };
+} __attribute__ ((packed));
+
+/* Information about a "mounted" ufs filesystem.  */
+struct grub_ufs_data
+{
+  struct grub_ufs_sblock sblock;
+  grub_disk_t disk;
+  struct grub_ufs_inode inode;
+  int ino;
+  int linknest;
+};
+
+static grub_dl_t my_mod;
+\f
+/* Forward declaration.  */
+static grub_err_t grub_ufs_find_file (struct grub_ufs_data *data,
+                                     const char *path);
+
+
+static grub_disk_addr_t
+grub_ufs_get_file_block (struct grub_ufs_data *data, unsigned int blk)
+{
+  struct grub_ufs_sblock *sblock = &data->sblock;
+  unsigned int indirsz;
+  int log2_blksz;
+
+  /* Direct.  */
+  if (blk < GRUB_UFS_DIRBLKS)
+    return INODE_DIRBLOCKS (data, blk);
+
+  log2_blksz = grub_le_to_cpu32 (data->sblock.log2_blksz);
+
+  blk -= GRUB_UFS_DIRBLKS;
+
+  indirsz = UFS_BLKSZ (sblock) / INODE_BLKSZ;
+  /* Single indirect block.  */
+  if (blk < indirsz)
+    {
+#ifdef MODE_UFS2
+      grub_uint64_t indir[UFS_BLKSZ (sblock) / sizeof (grub_uint64_t)];
+#else
+      grub_uint32_t indir[UFS_BLKSZ (sblock) / sizeof (grub_uint32_t)];
+#endif
+      grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 0) << log2_blksz,
+                     0, sizeof (indir), indir);
+      return indir[blk];
+    }
+  blk -= indirsz;
+
+  /* Double indirect block.  */
+  if (blk < indirsz * indirsz)
+    {
+#ifdef MODE_UFS2
+      grub_uint64_t indir[UFS_BLKSZ (sblock) / sizeof (grub_uint64_t)];
+#else
+      grub_uint32_t indir[UFS_BLKSZ (sblock) / sizeof (grub_uint32_t)];
+#endif
+
+      grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 1) << log2_blksz,
+                     0, sizeof (indir), indir);
+      grub_disk_read (data->disk,
+                     (indir [blk / indirsz])
+                     << log2_blksz,
+                     0, sizeof (indir), indir);
+
+      return indir[blk % indirsz];
+    }
+
+
+  grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+             "ufs does not support triple indirect blocks");
+  return 0;
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_ufs_read_file (struct grub_ufs_data *data,
+                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                      unsigned offset, unsigned length),
+                   int pos, grub_size_t len, char *buf)
+{
+  struct grub_ufs_sblock *sblock = &data->sblock;
+  int i;
+  int blockcnt;
+
+  /* Adjust len so it we can't read past the end of the file.  */
+  if (len + pos > INODE_SIZE (data))
+    len = INODE_SIZE (data) - pos;
+
+  blockcnt = (len + pos + UFS_BLKSZ (sblock) - 1) / UFS_BLKSZ (sblock);
+
+  for (i = pos / UFS_BLKSZ (sblock); i < blockcnt; i++)
+    {
+      int blknr;
+      int blockoff = pos % UFS_BLKSZ (sblock);
+      int blockend = UFS_BLKSZ (sblock);
+
+      int skipfirst = 0;
+
+      blknr = grub_ufs_get_file_block (data, i);
+      if (grub_errno)
+       return -1;
+
+      /* Last block.  */
+      if (i == blockcnt - 1)
+       {
+         blockend = (len + pos) % UFS_BLKSZ (sblock);
+
+         if (!blockend)
+           blockend = UFS_BLKSZ (sblock);
+       }
+
+      /* First block.  */
+      if (i == (pos / (int) UFS_BLKSZ (sblock)))
+       {
+         skipfirst = blockoff;
+         blockend -= skipfirst;
+       }
+
+      /* XXX: If the block number is 0 this block is not stored on
+        disk but is zero filled instead.  */
+      if (blknr)
+       {
+         data->disk->read_hook = read_hook;
+         grub_disk_read (data->disk,
+                         blknr << grub_le_to_cpu32 (data->sblock.log2_blksz),
+                         skipfirst, blockend, buf);
+         data->disk->read_hook = 0;
+         if (grub_errno)
+           return -1;
+       }
+      else
+       grub_memset (buf, UFS_BLKSZ (sblock) - skipfirst, 0);
+
+      buf += UFS_BLKSZ (sblock) - skipfirst;
+    }
+
+  return len;
+}
+
+/* Read inode INO from the mounted filesystem described by DATA.  This
+   inode is used by default now.  */
+static grub_err_t
+grub_ufs_read_inode (struct grub_ufs_data *data, int ino, char *inode)
+{
+  struct grub_ufs_sblock *sblock = &data->sblock;
+
+  /* Determine the group the inode is in.  */
+  int group = ino / grub_le_to_cpu32 (sblock->ino_per_group);
+
+  /* Determine the inode within the group.  */
+  int grpino = ino % grub_le_to_cpu32 (sblock->ino_per_group);
+
+  /* The first block of the group.  */
+  int grpblk = group * (grub_le_to_cpu32 (sblock->frags_per_group));
+
+#ifndef MODE_UFS2
+  grpblk += grub_le_to_cpu32 (sblock->cylg_offset)
+    * (group & (~grub_le_to_cpu32 (sblock->cylg_mask)));
+#endif
+
+  if (!inode)
+    {
+      inode = (char *) &data->inode;
+      data->ino = ino;
+    }
+
+  grub_disk_read (data->disk,
+                 ((grub_le_to_cpu32 (sblock->inoblk_offs) + grpblk)
+                  << grub_le_to_cpu32 (data->sblock.log2_blksz))
+                 + grpino / UFS_INODE_PER_BLOCK,
+                 (grpino % UFS_INODE_PER_BLOCK)
+                 * sizeof (struct grub_ufs_inode),
+                 sizeof (struct grub_ufs_inode),
+                 inode);
+
+  return grub_errno;
+}
+
+
+/* Lookup the symlink the current inode points to.  INO is the inode
+   number of the directory the symlink is relative to.  */
+static grub_err_t
+grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino)
+{
+  char symlink[INODE_SIZE (data)];
+
+  if (++data->linknest > GRUB_UFS_MAX_SYMLNK_CNT)
+    return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
+
+  if (INODE_NBLOCKS (data) == 0)
+    grub_strcpy (symlink, (char *) INODE (data, symlink));
+  else
+    {
+      grub_disk_read (data->disk,
+                     (INODE_DIRBLOCKS (data, 0)
+                      << grub_le_to_cpu32 (data->sblock.log2_blksz)),
+                     0, INODE_SIZE (data), symlink);
+      symlink[INODE_SIZE (data)] = '\0';
+    }
+
+  /* The symlink is an absolute path, go back to the root inode.  */
+  if (symlink[0] == '/')
+    ino = GRUB_UFS_INODE;
+
+  /* Now load in the old inode.  */
+  if (grub_ufs_read_inode (data, ino, 0))
+    return grub_errno;
+
+  grub_ufs_find_file (data, symlink);
+  if (grub_errno)
+    grub_error (grub_errno, "cannot follow symlink `%s'", symlink);
+
+  return grub_errno;
+}
+
+
+/* Find the file with the pathname PATH on the filesystem described by
+   DATA.  */
+static grub_err_t
+grub_ufs_find_file (struct grub_ufs_data *data, const char *path)
+{
+  char fpath[grub_strlen (path) + 1];
+  char *name = fpath;
+  char *next;
+  unsigned int pos = 0;
+  int dirino;
+
+  grub_strcpy (fpath, path);
+
+  /* Skip the first slash.  */
+  if (name[0] == '/')
+    {
+      name++;
+      if (!*name)
+       return 0;
+    }
+
+  /* Extract the actual part from the pathname.  */
+  next = grub_strchr (name, '/');
+  if (next)
+    {
+      next[0] = '\0';
+      next++;
+    }
+
+  do
+    {
+      struct grub_ufs_dirent dirent;
+      int namelen;
+
+      if (grub_strlen (name) == 0)
+       return GRUB_ERR_NONE;
+
+      if (grub_ufs_read_file (data, 0, pos, sizeof (dirent),
+                             (char *) &dirent) < 0)
+       return grub_errno;
+
+#ifdef MODE_UFS2
+      namelen = dirent.namelen_bsd;
+#else
+      namelen = grub_le_to_cpu16 (dirent.namelen);
+#endif
+      {
+       char filename[namelen + 1];
+
+       if (grub_ufs_read_file (data, 0, pos + sizeof (dirent),
+                               namelen, filename) < 0)
+         return grub_errno;
+
+       filename[namelen] = '\0';
+
+       if (!grub_strcmp (name, filename))
+         {
+           dirino = data->ino;
+           grub_ufs_read_inode (data, grub_le_to_cpu32 (dirent.ino), 0);
+
+           if ((INODE_MODE(data) & GRUB_UFS_ATTR_TYPE)
+               == GRUB_UFS_ATTR_LNK)
+             {
+               grub_ufs_lookup_symlink (data, dirino);
+               if (grub_errno)
+                 return grub_errno;
+             }
+
+           if (!next)
+             return 0;
+
+           pos = 0;
+
+           name = next;
+           next = grub_strchr (name, '/');
+           if (next)
+             {
+               next[0] = '\0';
+               next++;
+             }
+
+           if ((INODE_MODE(data) & GRUB_UFS_ATTR_TYPE) != GRUB_UFS_ATTR_DIR)
+             return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+
+           continue;
+         }
+      }
+
+      pos += grub_le_to_cpu16 (dirent.direntlen);
+    } while (pos < INODE_SIZE (data));
+
+  grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+  return grub_errno;
+}
+
+
+/* Mount the filesystem on the disk DISK.  */
+static struct grub_ufs_data *
+grub_ufs_mount (grub_disk_t disk)
+{
+  struct grub_ufs_data *data;
+  int *sblklist = sblocklist;
+
+  data = grub_malloc (sizeof (struct grub_ufs_data));
+  if (!data)
+    return 0;
+
+  /* Find a UFS sblock.  */
+  while (*sblklist != -1)
+    {
+      grub_disk_read (disk, *sblklist, 0, sizeof (struct grub_ufs_sblock),
+                     &data->sblock);
+      if (grub_errno)
+       goto fail;
+
+      if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC)
+       {
+         data->disk = disk;
+         data->linknest = 0;
+         return data;
+       }
+      sblklist++;
+    }
+
+ fail:
+
+  if (grub_errno == GRUB_ERR_NONE || grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    {
+#ifdef MODE_UFS2
+      grub_error (GRUB_ERR_BAD_FS, "not an ufs2 filesystem");
+#else
+      grub_error (GRUB_ERR_BAD_FS, "not an ufs1 filesystem");
+#endif
+    }
+
+  grub_free (data);
+
+  return 0;
+}
+
+
+static grub_err_t
+grub_ufs_dir (grub_device_t device, const char *path,
+              int (*hook) (const char *filename,
+                           const struct grub_dirhook_info *info))
+{
+  struct grub_ufs_data *data;
+  struct grub_ufs_sblock *sblock;
+  unsigned int pos = 0;
+
+  data = grub_ufs_mount (device->disk);
+  if (!data)
+    return grub_errno;
+
+  grub_ufs_read_inode (data, GRUB_UFS_INODE, 0);
+  if (grub_errno)
+    return grub_errno;
+
+  sblock = &data->sblock;
+
+  if (!path || path[0] != '/')
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
+      return grub_errno;
+    }
+
+  grub_ufs_find_file (data, path);
+  if (grub_errno)
+    goto fail;
+
+  if ((INODE_MODE (data) & GRUB_UFS_ATTR_TYPE) != GRUB_UFS_ATTR_DIR)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
+      goto fail;
+    }
+
+  while (pos < INODE_SIZE (data))
+    {
+      struct grub_ufs_dirent dirent;
+      int namelen;
+
+      if (grub_ufs_read_file (data, 0, pos, sizeof (dirent),
+                             (char *) &dirent) < 0)
+       break;
+
+#ifdef MODE_UFS2
+      namelen = dirent.namelen_bsd;
+#else
+      namelen = grub_le_to_cpu16 (dirent.namelen);
+#endif
+
+      {
+       char filename[namelen + 1];
+       struct grub_dirhook_info info;
+       struct grub_ufs_inode inode;
+
+       grub_memset (&info, 0, sizeof (info));
+
+       if (grub_ufs_read_file (data, 0, pos + sizeof (dirent),
+                               namelen, filename) < 0)
+         break;
+
+       filename[namelen] = '\0';
+       grub_ufs_read_inode (data, dirent.ino, (char *) &inode);
+
+       info.dir = ((grub_le_to_cpu16 (inode.mode) & GRUB_UFS_ATTR_TYPE)
+                   == GRUB_UFS_ATTR_DIR);
+       info.mtime = grub_le_to_cpu64 (inode.mtime);
+       info.mtimeset = 1;
+
+       if (hook (filename, &info))
+         break;
+      }
+
+      pos += grub_le_to_cpu16 (dirent.direntlen);
+    }
+
+ fail:
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_ufs_open (struct grub_file *file, const char *name)
+{
+  struct grub_ufs_data *data;
+  data = grub_ufs_mount (file->device->disk);
+  if (!data)
+    return grub_errno;
+
+  grub_ufs_read_inode (data, 2, 0);
+  if (grub_errno)
+    {
+      grub_free (data);
+      return grub_errno;
+    }
+
+  if (!name || name[0] != '/')
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
+      return grub_errno;
+    }
+
+  grub_ufs_find_file (data, name);
+  if (grub_errno)
+    {
+      grub_free (data);
+      return grub_errno;
+    }
+
+  file->data = data;
+  file->size = INODE_SIZE (data);
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_ssize_t
+grub_ufs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_ufs_data *data =
+    (struct grub_ufs_data *) file->data;
+
+  return grub_ufs_read_file (data, file->read_hook, file->offset, len, buf);
+}
+
+
+static grub_err_t
+grub_ufs_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  return GRUB_ERR_NONE;
+}
+
+
+#ifdef MODE_UFS2
+static grub_err_t
+grub_ufs_label (grub_device_t device, char **label)
+{
+  struct grub_ufs_data *data = 0;
+
+  grub_dl_ref (my_mod);
+
+  *label = 0;
+
+  data = grub_ufs_mount (device->disk);
+  if (data)
+    *label = grub_strdup ((char *) data->sblock.volume_name);
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+#endif
+
+static grub_err_t
+grub_ufs_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_ufs_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ufs_mount (disk);
+  if (data && (data->sblock.uuidhi != 0 || data->sblock.uuidlow != 0))
+    *uuid = grub_xasprintf ("%08x%08x",
+                          (unsigned) grub_le_to_cpu32 (data->sblock.uuidhi),
+                          (unsigned) grub_le_to_cpu32 (data->sblock.uuidlow));
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+/* Get mtime.  */
+static grub_err_t
+grub_ufs_mtime (grub_device_t device, grub_int32_t *tm)
+{
+  struct grub_ufs_data *data = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_ufs_mount (device->disk);
+  if (!data)
+    *tm = 0;
+  else
+#ifdef MODE_UFS2
+    *tm = grub_le_to_cpu64 (data->sblock.mtime2);
+#else
+    *tm = grub_le_to_cpu32 (data->sblock.mtime);
+#endif
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+
+\f
+static struct grub_fs grub_ufs_fs =
+  {
+#ifdef MODE_UFS2
+    .name = "ufs2",
+#else
+    .name = "ufs1",
+#endif
+    .dir = grub_ufs_dir,
+    .open = grub_ufs_open,
+    .read = grub_ufs_read,
+    .close = grub_ufs_close,
+#ifdef MODE_UFS2
+    .label = grub_ufs_label,
+#endif
+    .uuid = grub_ufs_uuid,
+    .mtime = grub_ufs_mtime,
+    .next = 0
+  };
+
+#ifdef MODE_UFS2
+GRUB_MOD_INIT(ufs2)
+#else
+GRUB_MOD_INIT(ufs1)
+#endif
+{
+  grub_fs_register (&grub_ufs_fs);
+  my_mod = mod;
+}
+
+#ifdef MODE_UFS2
+GRUB_MOD_FINI(ufs2)
+#else
+GRUB_MOD_FINI(ufs1)
+#endif
+{
+  grub_fs_unregister (&grub_ufs_fs);
+}
+
diff --git a/grub-core/fs/ufs2.c b/grub-core/fs/ufs2.c
new file mode 100644 (file)
index 0000000..7f4eb95
--- /dev/null
@@ -0,0 +1,3 @@
+/* ufs2.c - Unix File System 2 */
+#define MODE_UFS2 1
+#include "ufs.c"
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
new file mode 100644 (file)
index 0000000..9dffe31
--- /dev/null
@@ -0,0 +1,823 @@
+/* xfs.c - XFS.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/types.h>
+#include <grub/fshelp.h>
+
+#define        XFS_INODE_EXTENTS       9
+
+#define XFS_INODE_FORMAT_INO   1
+#define XFS_INODE_FORMAT_EXT   2
+#define XFS_INODE_FORMAT_BTREE 3
+
+
+struct grub_xfs_sblock
+{
+  grub_uint8_t magic[4];
+  grub_uint32_t bsize;
+  grub_uint8_t unused1[24];
+  grub_uint16_t uuid[8];
+  grub_uint8_t unused2[8];
+  grub_uint64_t rootino;
+  grub_uint8_t unused3[20];
+  grub_uint32_t agsize;
+  grub_uint8_t unused4[20];
+  grub_uint8_t label[12];
+  grub_uint8_t log2_bsize;
+  grub_uint8_t log2_sect;
+  grub_uint8_t log2_inode;
+  grub_uint8_t log2_inop;
+  grub_uint8_t log2_agblk;
+  grub_uint8_t unused6[67];
+  grub_uint8_t log2_dirblk;
+} __attribute__ ((packed));
+
+struct grub_xfs_dir_header
+{
+  grub_uint8_t count;
+  grub_uint8_t smallino;
+  union
+  {
+    grub_uint32_t i4;
+    grub_uint64_t i8;
+  } parent __attribute__ ((packed));
+} __attribute__ ((packed));
+
+struct grub_xfs_dir_entry
+{
+  grub_uint8_t len;
+  grub_uint16_t offset;
+  char name[1];
+  /* Inode number follows, 32 bits.  */
+} __attribute__ ((packed));
+
+struct grub_xfs_dir2_entry
+{
+  grub_uint64_t inode;
+  grub_uint8_t len;
+} __attribute__ ((packed));
+
+typedef grub_uint32_t grub_xfs_extent[4];
+
+struct grub_xfs_btree_node
+{
+  grub_uint8_t magic[4];
+  grub_uint16_t level;
+  grub_uint16_t numrecs;
+  grub_uint64_t left;
+  grub_uint64_t right;
+  grub_uint64_t keys[1];
+}  __attribute__ ((packed));
+
+struct grub_xfs_btree_root
+{
+  grub_uint16_t level;
+  grub_uint16_t numrecs;
+  grub_uint64_t keys[1];
+}  __attribute__ ((packed));
+
+struct grub_xfs_inode
+{
+  grub_uint8_t magic[2];
+  grub_uint16_t mode;
+  grub_uint8_t version;
+  grub_uint8_t format;
+  grub_uint8_t unused2[50];
+  grub_uint64_t size;
+  grub_uint64_t nblocks;
+  grub_uint32_t extsize;
+  grub_uint32_t nextents;
+  grub_uint8_t unused3[20];
+  union
+  {
+    char raw[156];
+    struct dir
+    {
+      struct grub_xfs_dir_header dirhead;
+      struct grub_xfs_dir_entry direntry[1];
+    } dir;
+    grub_xfs_extent extents[XFS_INODE_EXTENTS];
+    struct grub_xfs_btree_root btree;
+  } data __attribute__ ((packed));
+} __attribute__ ((packed));
+
+struct grub_xfs_dirblock_tail
+{
+  grub_uint32_t leaf_count;
+  grub_uint32_t leaf_stale;
+} __attribute__ ((packed));
+
+struct grub_fshelp_node
+{
+  struct grub_xfs_data *data;
+  grub_uint64_t ino;
+  int inode_read;
+  struct grub_xfs_inode inode;
+};
+
+struct grub_xfs_data
+{
+  struct grub_xfs_sblock sblock;
+  grub_disk_t disk;
+  int pos;
+  int bsize;
+  int agsize;
+  struct grub_fshelp_node diropen;
+};
+
+static grub_dl_t my_mod;
+
+\f
+
+/* Filetype information as used in inodes.  */
+#define FILETYPE_INO_MASK      0170000
+#define FILETYPE_INO_REG       0100000
+#define FILETYPE_INO_DIRECTORY 0040000
+#define FILETYPE_INO_SYMLINK   0120000
+
+#define GRUB_XFS_INO_AGBITS(data)              \
+  ((data)->sblock.log2_agblk + (data)->sblock.log2_inop)
+#define GRUB_XFS_INO_INOINAG(data, ino)                \
+  (grub_be_to_cpu64 (ino) & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1))
+#define GRUB_XFS_INO_AG(data,ino)              \
+  (grub_be_to_cpu64 (ino) >> GRUB_XFS_INO_AGBITS (data))
+
+#define GRUB_XFS_FSB_TO_BLOCK(data, fsb) \
+  (((fsb) >> (data)->sblock.log2_agblk) * (data)->agsize \
+ + ((fsb) & ((1LL << (data)->sblock.log2_agblk) - 1)))
+
+#define GRUB_XFS_EXTENT_OFFSET(exts,ex) \
+       ((grub_be_to_cpu32 (exts[ex][0]) & ~(1 << 31)) << 23 \
+       | grub_be_to_cpu32 (exts[ex][1]) >> 9)
+
+#define GRUB_XFS_EXTENT_BLOCK(exts,ex)         \
+  ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex][1]) \
+                 & (0x1ff)) << 43 \
+   | (grub_uint64_t) grub_be_to_cpu32 (exts[ex][2]) << 11 \
+   | grub_be_to_cpu32 (exts[ex][3]) >> 21)
+
+#define GRUB_XFS_EXTENT_SIZE(exts,ex)          \
+  (grub_be_to_cpu32 (exts[ex][3]) & ((1 << 20) - 1))
+
+#define GRUB_XFS_ROUND_TO_DIRENT(pos)  ((((pos) + 8 - 1) / 8) * 8)
+#define GRUB_XFS_NEXT_DIRENT(pos,len)          \
+  (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2)
+\f
+static inline grub_uint64_t
+grub_xfs_inode_block (struct grub_xfs_data *data,
+                     grub_uint64_t ino)
+{
+  long long int inoinag = GRUB_XFS_INO_INOINAG (data, ino);
+  long long ag = GRUB_XFS_INO_AG (data, ino);
+  long long block;
+
+  block = (inoinag >> data->sblock.log2_inop) + ag * data->agsize;
+  block <<= (data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS);
+  return block;
+}
+
+
+static inline int
+grub_xfs_inode_offset (struct grub_xfs_data *data,
+                      grub_uint64_t ino)
+{
+  int inoag = GRUB_XFS_INO_INOINAG (data, ino);
+  return ((inoag & ((1 << data->sblock.log2_inop) - 1)) <<
+         data->sblock.log2_inode);
+}
+
+
+static grub_err_t
+grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
+                    struct grub_xfs_inode *inode)
+{
+  grub_uint64_t block = grub_xfs_inode_block (data, ino);
+  int offset = grub_xfs_inode_offset (data, ino);
+
+  /* Read the inode.  */
+  if (grub_disk_read (data->disk, block, offset,
+                     1 << data->sblock.log2_inode, inode))
+    return grub_errno;
+
+  if (grub_strncmp ((char *) inode->magic, "IN", 2))
+    return grub_error (GRUB_ERR_BAD_FS, "not a correct XFS inode");
+
+  return 0;
+}
+
+
+static grub_disk_addr_t
+grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+{
+  struct grub_xfs_btree_node *leaf = 0;
+  int ex, nrec;
+  grub_xfs_extent *exts;
+  grub_uint64_t ret = 0;
+
+  if (node->inode.format == XFS_INODE_FORMAT_BTREE)
+    {
+      grub_uint64_t *keys;
+
+      leaf = grub_malloc (node->data->sblock.bsize);
+      if (leaf == 0)
+        return 0;
+
+      nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs);
+      keys = &node->inode.data.btree.keys[0];
+      do
+        {
+          int i;
+
+          for (i = 0; i < nrec; i++)
+            {
+              if (fileblock < grub_be_to_cpu64 (keys[i]))
+                break;
+            }
+
+          /* Sparse block.  */
+          if (i == 0)
+            {
+              grub_free (leaf);
+              return 0;
+            }
+
+          if (grub_disk_read (node->data->disk,
+                              grub_be_to_cpu64 (keys[i - 1 + nrec])
+                              << (node->data->sblock.log2_bsize
+                                  - GRUB_DISK_SECTOR_BITS),
+                              0, node->data->sblock.bsize, leaf))
+            return 0;
+
+          if (grub_strncmp ((char *) leaf->magic, "BMAP", 4))
+            {
+              grub_free (leaf);
+              grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node");
+              return 0;
+            }
+
+          nrec = grub_be_to_cpu16 (leaf->numrecs);
+          keys = &leaf->keys[0];
+        } while (leaf->level);
+      exts = (grub_xfs_extent *) keys;
+    }
+  else if (node->inode.format == XFS_INODE_FORMAT_EXT)
+    {
+      nrec = grub_be_to_cpu32 (node->inode.nextents);
+      exts = &node->inode.data.extents[0];
+    }
+  else
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                 "XFS does not support inode format %d yet",
+                 node->inode.format);
+      return 0;
+    }
+
+  /* Iterate over each extent to figure out which extent has
+     the block we are looking for.  */
+  for (ex = 0; ex < nrec; ex++)
+    {
+      grub_uint64_t start = GRUB_XFS_EXTENT_BLOCK (exts, ex);
+      grub_uint64_t offset = GRUB_XFS_EXTENT_OFFSET (exts, ex);
+      grub_uint64_t size = GRUB_XFS_EXTENT_SIZE (exts, ex);
+
+      /* Sparse block.  */
+      if (fileblock < offset)
+        break;
+      else if (fileblock < offset + size)
+        {
+          ret = (fileblock - offset + start);
+          break;
+        }
+    }
+
+  if (leaf)
+    grub_free (leaf);
+
+  return GRUB_XFS_FSB_TO_BLOCK(node->data, ret);
+}
+
+
+/* Read LEN bytes from the file described by DATA starting with byte
+   POS.  Return the amount of read bytes in READ.  */
+static grub_ssize_t
+grub_xfs_read_file (grub_fshelp_node_t node,
+                    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                       unsigned offset, unsigned length),
+                    int pos, grub_size_t len, char *buf)
+{
+  return grub_fshelp_read_file (node->data->disk, node, read_hook,
+                               pos, len, buf, grub_xfs_read_block,
+                               grub_be_to_cpu64 (node->inode.size),
+                               node->data->sblock.log2_bsize
+                               - GRUB_DISK_SECTOR_BITS);
+}
+
+
+static char *
+grub_xfs_read_symlink (grub_fshelp_node_t node)
+{
+  int size = grub_be_to_cpu64 (node->inode.size);
+
+  switch (node->inode.format)
+    {
+    case XFS_INODE_FORMAT_INO:
+      return grub_strndup (node->inode.data.raw, size);
+
+    case XFS_INODE_FORMAT_EXT:
+      {
+       char *symlink;
+       grub_ssize_t numread;
+
+       symlink = grub_malloc (size + 1);
+       if (!symlink)
+         return 0;
+
+       numread = grub_xfs_read_file (node, 0, 0, size, symlink);
+       if (numread != size)
+         {
+           grub_free (symlink);
+           return 0;
+         }
+       symlink[size] = '\0';
+       return symlink;
+      }
+    }
+
+  return 0;
+}
+
+
+static enum grub_fshelp_filetype
+grub_xfs_mode_to_filetype (grub_uint16_t mode)
+{
+  if ((grub_be_to_cpu16 (mode)
+       & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY)
+    return GRUB_FSHELP_DIR;
+  else if ((grub_be_to_cpu16 (mode)
+           & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK)
+    return GRUB_FSHELP_SYMLINK;
+  else if ((grub_be_to_cpu16 (mode)
+           & FILETYPE_INO_MASK) == FILETYPE_INO_REG)
+    return GRUB_FSHELP_REG;
+  return GRUB_FSHELP_UNKNOWN;
+}
+
+
+static int
+grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+                      int NESTED_FUNC_ATTR
+                      (*hook) (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node))
+{
+  struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
+  auto int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, char *filename);
+
+  int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, char *filename)
+    {
+      struct grub_fshelp_node *fdiro;
+
+      fdiro = grub_malloc (sizeof (struct grub_fshelp_node)
+                          - sizeof (struct grub_xfs_inode)
+                          + (1 << diro->data->sblock.log2_inode));
+      if (!fdiro)
+       return 0;
+
+      /* The inode should be read, otherwise the filetype can
+        not be determined.  */
+      fdiro->ino = ino;
+      fdiro->inode_read = 1;
+      fdiro->data = diro->data;
+      grub_xfs_read_inode (diro->data, ino, &fdiro->inode);
+
+      return hook (filename,
+                  grub_xfs_mode_to_filetype (fdiro->inode.mode),
+                  fdiro);
+    }
+
+  switch (diro->inode.format)
+    {
+    case XFS_INODE_FORMAT_INO:
+      {
+       struct grub_xfs_dir_entry *de = &diro->inode.data.dir.direntry[0];
+       int smallino = !diro->inode.data.dir.dirhead.smallino;
+       int i;
+       grub_uint64_t parent;
+
+       /* If small inode numbers are used to pack the direntry, the
+          parent inode number is small too.  */
+       if (smallino)
+         {
+           parent = grub_be_to_cpu32 (diro->inode.data.dir.dirhead.parent.i4);
+           parent = grub_cpu_to_be64 (parent);
+           /* The header is a bit smaller than usual.  */
+           de = (struct grub_xfs_dir_entry *) ((char *) de - 4);
+         }
+       else
+         {
+           parent = diro->inode.data.dir.dirhead.parent.i8;
+         }
+
+       /* Synthesize the direntries for `.' and `..'.  */
+       if (call_hook (diro->ino, "."))
+         return 1;
+
+       if (call_hook (parent, ".."))
+         return 1;
+
+       for (i = 0; i < diro->inode.data.dir.dirhead.count; i++)
+         {
+           grub_uint64_t ino;
+           void *inopos = (((char *) de)
+                           + sizeof (struct grub_xfs_dir_entry)
+                           + de->len - 1);
+           char name[de->len + 1];
+
+           if (smallino)
+             {
+               ino = grub_be_to_cpu32 (*(grub_uint32_t *) inopos);
+               ino = grub_cpu_to_be64 (ino);
+             }
+           else
+             ino = *(grub_uint64_t *) inopos;
+
+           grub_memcpy (name, de->name, de->len);
+           name[de->len] = '\0';
+           if (call_hook (ino, name))
+             return 1;
+
+           de = ((struct grub_xfs_dir_entry *)
+                 (((char *) de)+ sizeof (struct grub_xfs_dir_entry) + de->len
+                  + ((smallino ? sizeof (grub_uint32_t)
+                      : sizeof (grub_uint64_t))) - 1));
+         }
+       break;
+      }
+
+    case XFS_INODE_FORMAT_BTREE:
+    case XFS_INODE_FORMAT_EXT:
+      {
+       grub_ssize_t numread;
+       char *dirblock;
+       grub_uint64_t blk;
+        int dirblk_size, dirblk_log2;
+
+        dirblk_log2 = (dir->data->sblock.log2_bsize
+                       + dir->data->sblock.log2_dirblk);
+        dirblk_size = 1 << dirblk_log2;
+
+       dirblock = grub_malloc (dirblk_size);
+       if (! dirblock)
+         return 0;
+
+       /* Iterate over every block the directory has.  */
+       for (blk = 0;
+            blk < (grub_be_to_cpu64 (dir->inode.size)
+                   >> dirblk_log2);
+            blk++)
+         {
+           /* The header is skipped, the first direntry is stored
+              from byte 16.  */
+           int pos = 16;
+           int entries;
+           int tail_start = (dirblk_size
+                             - sizeof (struct grub_xfs_dirblock_tail));
+
+           struct grub_xfs_dirblock_tail *tail;
+           tail = (struct grub_xfs_dirblock_tail *) &dirblock[tail_start];
+
+           numread = grub_xfs_read_file (dir, 0,
+                                         blk << dirblk_log2,
+                                         dirblk_size, dirblock);
+           if (numread != dirblk_size)
+             return 0;
+
+           entries = (grub_be_to_cpu32 (tail->leaf_count)
+                      - grub_be_to_cpu32 (tail->leaf_stale));
+
+           /* Iterate over all entries within this block.  */
+           while (pos < (dirblk_size
+                         - (int) sizeof (struct grub_xfs_dir2_entry)))
+             {
+               struct grub_xfs_dir2_entry *direntry;
+               grub_uint16_t *freetag;
+               char *filename;
+
+               direntry = (struct grub_xfs_dir2_entry *) &dirblock[pos];
+               freetag = (grub_uint16_t *) direntry;
+
+               if (*freetag == 0XFFFF)
+                 {
+                   grub_uint16_t *skip = (grub_uint16_t *) (freetag + 1);
+
+                   /* This entry is not used, go to the next one.  */
+                   pos += grub_be_to_cpu16 (*skip);
+
+                   continue;
+                 }
+
+               filename = &dirblock[pos + sizeof (*direntry)];
+               /* The byte after the filename is for the tag, which
+                  is not used by GRUB.  So it can be overwritten.  */
+               filename[direntry->len] = '\0';
+
+               if (call_hook (direntry->inode, filename))
+                 {
+                   grub_free (dirblock);
+                   return 1;
+                 }
+
+               /* Check if last direntry in this block is
+                  reached.  */
+               entries--;
+               if (!entries)
+                 break;
+
+               /* Select the next directory entry.  */
+               pos = GRUB_XFS_NEXT_DIRENT (pos, direntry->len);
+               pos = GRUB_XFS_ROUND_TO_DIRENT (pos);
+             }
+         }
+       grub_free (dirblock);
+       break;
+      }
+
+    default:
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                 "XFS does not support inode format %d yet",
+                 diro->inode.format);
+    }
+  return 0;
+}
+
+
+static struct grub_xfs_data *
+grub_xfs_mount (grub_disk_t disk)
+{
+  struct grub_xfs_data *data = 0;
+
+  data = grub_zalloc (sizeof (struct grub_xfs_data));
+  if (!data)
+    return 0;
+
+  /* Read the superblock.  */
+  if (grub_disk_read (disk, 0, 0,
+                     sizeof (struct grub_xfs_sblock), &data->sblock))
+    goto fail;
+
+  if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4))
+    {
+      grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem");
+      goto fail;
+    }
+
+  data = grub_realloc (data,
+                      sizeof (struct grub_xfs_data)
+                      - sizeof (struct grub_xfs_inode)
+                      + (1 << data->sblock.log2_inode));
+
+  if (! data)
+    goto fail;
+
+  data->diropen.data = data;
+  data->diropen.ino = data->sblock.rootino;
+  data->diropen.inode_read = 1;
+  data->bsize = grub_be_to_cpu32 (data->sblock.bsize);
+  data->agsize = grub_be_to_cpu32 (data->sblock.agsize);
+
+  data->disk = disk;
+  data->pos = 0;
+
+  grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode);
+
+  return data;
+ fail:
+
+  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+    grub_error (GRUB_ERR_BAD_FS, "not an XFS filesystem");
+
+  grub_free (data);
+
+  return 0;
+}
+
+\f
+static grub_err_t
+grub_xfs_dir (grub_device_t device, const char *path,
+             int (*hook) (const char *filename,
+                          const struct grub_dirhook_info *info))
+{
+  struct grub_xfs_data *data = 0;
+  struct grub_fshelp_node *fdiro = 0;
+
+  auto int NESTED_FUNC_ATTR iterate (const char *filename,
+                                    enum grub_fshelp_filetype filetype,
+                                    grub_fshelp_node_t node);
+
+  int NESTED_FUNC_ATTR iterate (const char *filename,
+                               enum grub_fshelp_filetype filetype,
+                               grub_fshelp_node_t node)
+    {
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
+      grub_free (node);
+      return hook (filename, &info);
+    }
+
+  grub_dl_ref (my_mod);
+
+  data = grub_xfs_mount (device->disk);
+  if (!data)
+    goto mount_fail;
+
+  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_xfs_iterate_dir,
+                        grub_xfs_read_symlink, GRUB_FSHELP_DIR);
+  if (grub_errno)
+    goto fail;
+
+  grub_xfs_iterate_dir (fdiro, iterate);
+
+ fail:
+  if (fdiro != &data->diropen)
+    grub_free (fdiro);
+  grub_free (data);
+
+ mount_fail:
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_xfs_open (struct grub_file *file, const char *name)
+{
+  struct grub_xfs_data *data;
+  struct grub_fshelp_node *fdiro = 0;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_xfs_mount (file->device->disk);
+  if (!data)
+    goto mount_fail;
+
+  grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_xfs_iterate_dir,
+                        grub_xfs_read_symlink, GRUB_FSHELP_REG);
+  if (grub_errno)
+    goto fail;
+
+  if (!fdiro->inode_read)
+    {
+      grub_xfs_read_inode (data, fdiro->ino, &fdiro->inode);
+      if (grub_errno)
+       goto fail;
+    }
+
+  if (fdiro != &data->diropen)
+    grub_memcpy (&data->diropen, fdiro,
+                sizeof (struct grub_fshelp_node)
+                - sizeof (struct grub_xfs_inode)
+                + (1 << data->sblock.log2_inode));
+
+  file->size = grub_be_to_cpu64 (data->diropen.inode.size);
+  file->data = data;
+  file->offset = 0;
+
+  return 0;
+
+ fail:
+  if (fdiro != &data->diropen)
+    grub_free (fdiro);
+  grub_free (data);
+
+ mount_fail:
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+
+static grub_ssize_t
+grub_xfs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_xfs_data *data =
+    (struct grub_xfs_data *) file->data;
+
+  return grub_xfs_read_file (&data->diropen, file->read_hook,
+                             file->offset, len, buf);
+}
+
+
+static grub_err_t
+grub_xfs_close (grub_file_t file)
+{
+  grub_free (file->data);
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+
+static grub_err_t
+grub_xfs_label (grub_device_t device, char **label)
+{
+  struct grub_xfs_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_xfs_mount (disk);
+  if (data)
+    *label = grub_strndup ((char *) (data->sblock.label), 12);
+  else
+    *label = 0;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_xfs_uuid (grub_device_t device, char **uuid)
+{
+  struct grub_xfs_data *data;
+  grub_disk_t disk = device->disk;
+
+  grub_dl_ref (my_mod);
+
+  data = grub_xfs_mount (disk);
+  if (data)
+    {
+      *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
+                            grub_be_to_cpu16 (data->sblock.uuid[0]),
+                            grub_be_to_cpu16 (data->sblock.uuid[1]),
+                            grub_be_to_cpu16 (data->sblock.uuid[2]),
+                            grub_be_to_cpu16 (data->sblock.uuid[3]),
+                            grub_be_to_cpu16 (data->sblock.uuid[4]),
+                            grub_be_to_cpu16 (data->sblock.uuid[5]),
+                            grub_be_to_cpu16 (data->sblock.uuid[6]),
+                            grub_be_to_cpu16 (data->sblock.uuid[7]));
+    }
+  else
+    *uuid = NULL;
+
+  grub_dl_unref (my_mod);
+
+  grub_free (data);
+
+  return grub_errno;
+}
+
+\f
+
+static struct grub_fs grub_xfs_fs =
+  {
+    .name = "xfs",
+    .dir = grub_xfs_dir,
+    .open = grub_xfs_open,
+    .read = grub_xfs_read,
+    .close = grub_xfs_close,
+    .label = grub_xfs_label,
+    .uuid = grub_xfs_uuid,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(xfs)
+{
+  grub_fs_register (&grub_xfs_fs);
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(xfs)
+{
+  grub_fs_unregister (&grub_xfs_fs);
+}
diff --git a/grub-core/gencmdlist.sh b/grub-core/gencmdlist.sh
new file mode 100644 (file)
index 0000000..ed5965f
--- /dev/null
@@ -0,0 +1,22 @@
+#! /bin/sh
+#
+# Copyright (C) 2005,2009  Free Software Foundation, Inc.
+#
+# This gensymlist.sh is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read source code from stdin and detect command names.
+
+module=$1
+
+grep -v "^#" | sed -n \
+ -e "/grub_register_command *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $module/;p;}" \
+ -e "/grub_register_extcmd *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $module/;p;}" \
+ -e "/grub_register_command_p1 *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $module/;p;}"
+
diff --git a/grub-core/gendistlist.sh b/grub-core/gendistlist.sh
new file mode 100755 (executable)
index 0000000..102c0c1
--- /dev/null
@@ -0,0 +1,46 @@
+#! /bin/sh
+#
+# Copyright (C) 2005, 2008, 2009  Free Software Foundation, Inc.
+#
+# This gendistlist.sh is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Generate a list of distributed files.
+
+EXTRA_DISTFILES="AUTHORS COPYING ChangeLog DISTLIST INSTALL NEWS README \
+       THANKS TODO Makefile.in aclocal.m4 autogen.sh config.guess \
+       config.h.in config.sub configure configure.ac gencmdlist.sh \
+       gendistlist.sh genfslist.sh genhandlerlist.sh geninit.sh \
+       geninitheader.sh genkernsyms.sh.in genmk.rb genmoddep.awk \
+       genmodsrc.sh genpartmaplist.sh genparttoollist.sh \
+       genvideolist.sh \
+       gensymlist.sh.in install-sh mkinstalldirs stamp-h.in"
+
+DISTDIRS="boot bus commands conf disk docs efiemu font fs hello hook include io \
+       kern lib loader mmap normal partmap parttool script term util video"
+
+LC_COLLATE=C
+export LC_COLLATE
+
+for f in $EXTRA_DISTFILES; do
+    echo $f
+done
+
+dir=`dirname $0`
+cd $dir
+
+for dir in $DISTDIRS; do
+  for d in `find $dir -type d ! -name .svn ! -name .bzr | sort`; do
+    find $d -maxdepth 1 -name '*.[chSy]' -o -name '*.mk' -o -name '*.rmk' \
+      -o -name '*.rb' -o -name '*.in' -o -name '*.tex' -o -name '*.texi' \
+      -o -name '*.info' -o -name 'grub.cfg' -o -name 'README' \
+      -o -name '*.sc' -o -name 'mdate-sh' -o -name '*.sh' \
+      -o -name 'grub-dumpdevtree' -o -name '*.lua' | sort
+  done
+done
diff --git a/grub-core/genemuinit.sh b/grub-core/genemuinit.sh
new file mode 100644 (file)
index 0000000..45c15ec
--- /dev/null
@@ -0,0 +1,72 @@
+#! /bin/sh
+#
+# Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
+#
+# This gensymlist.sh is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+nm="$1"
+shift
+
+cat <<EOF
+/* This file is automatically generated by geninit.sh. DO NOT EDIT! */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "grub_emu_init.h"
+
+EOF
+
+cat <<EOF
+void
+grub_init_all (void)
+{
+EOF
+
+read mods
+for line in $mods; do
+  if ${nm} --defined-only -P -p ${line} | grep grub_mod_init > /dev/null; then
+      echo "grub_${line}_init ();" | sed 's,\.mod,,g;'
+  fi
+done
+
+cat <<EOF
+}
+EOF
+
+cat <<EOF
+void
+grub_fini_all (void)
+{
+EOF
+
+for line in $mods; do
+  if ${nm} --defined-only -P -p ${line} | grep grub_mod_fini > /dev/null; then
+      echo "grub_${line}_fini ();" | sed 's,\.mod,,g;'
+  fi
+done
+
+cat <<EOF
+}
+EOF
diff --git a/grub-core/genemuinitheader.sh b/grub-core/genemuinitheader.sh
new file mode 100644 (file)
index 0000000..6b83f59
--- /dev/null
@@ -0,0 +1,52 @@
+#! /bin/sh
+#
+# Copyright (C) 2005,2007  Free Software Foundation, Inc.
+#
+# This gensymlist.sh is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+nm="$1"
+shift
+
+cat <<EOF
+/* This file is automatically generated by gensymlist.sh. DO NOT EDIT! */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+EOF
+
+cat <<EOF
+void grub_init_all (void);
+void grub_fini_all (void);
+EOF
+
+read mods
+for line in $mods; do
+  if ${nm} --defined-only -P -p ${line} | grep grub_mod_init > /dev/null; then
+      echo "void grub_${line}_init (void);" | sed 's,\.mod,,g;'
+  fi
+  if ${nm} --defined-only -P -p ${line} | grep grub_mod_fini > /dev/null; then
+      echo "void grub_${line}_fini (void);" | sed 's,\.mod,,g;'
+  fi
+done
diff --git a/grub-core/genfslist.sh b/grub-core/genfslist.sh
new file mode 100644 (file)
index 0000000..6fa7e92
--- /dev/null
@@ -0,0 +1,26 @@
+#! /bin/sh
+#
+# Copyright (C) 2005,2008  Free Software Foundation, Inc.
+#
+# This gensymlist.sh is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read source code from stdin and detect fs names.
+
+module=$1
+
+# Ignore kernel.mod.
+if test $module = kernel; then
+    exit
+fi
+
+# For now, this emits only a module name, if the module registers a filesystem.
+if grep -v "^#" | grep '^ *grub_fs_register' >/dev/null 2>&1; then
+    echo $module
+fi
diff --git a/grub-core/genhandlerlist.sh b/grub-core/genhandlerlist.sh
new file mode 100644 (file)
index 0000000..e4cb0d9
--- /dev/null
@@ -0,0 +1,19 @@
+#! /bin/sh
+#
+# Copyright (C) 2009  Free Software Foundation, Inc.
+#
+# This script is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read source code from stdin and detect command names.
+
+module=$1
+
+grep -v "^#" | sed -n \
+ -e "/grub_parser_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/parser.\1: $module/;p;}"
diff --git a/grub-core/genmoddep.awk b/grub-core/genmoddep.awk
new file mode 100644 (file)
index 0000000..6c92e2f
--- /dev/null
@@ -0,0 +1,60 @@
+#! /usr/bin/awk -f
+#
+# Copyright (C) 2006  Free Software Foundation, Inc.
+#
+# This genmoddep.awk is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read defined symbols from stdin.
+BEGIN {
+  while (getline <"/dev/stdin") {
+    symtab[$1] = $2
+  }
+}
+
+# The rest is undefined symbols.
+{
+  module = $2
+
+  # skip if empty
+  if ($1 == "" || $2 == "")
+      ;
+  else if ($1 in symtab) {
+    modtab[module] = modtab[module] " " symtab[$1];
+  }
+  else if ($1 != "__gnu_local_gp") {
+    printf "%s in %s is not defined\n", $1, module >"/dev/stderr";
+    error++;
+  }
+}
+
+# Output the result.
+END {
+  if (error >= 1)
+    exit 1;
+
+  for (mod in modtab) {
+    # Remove duplications.
+    split(modtab[mod], depmods, " ");
+    for (depmod in uniqmods) {
+      delete uniqmods[depmod];
+    }
+    for (i in depmods) {
+      depmod = depmods[i];
+      # Ignore kernel, as always loaded.
+      if (depmod != "kernel" && depmod != mod)
+       uniqmods[depmod] = 1;
+    }
+    modlist = ""
+    for (depmod in uniqmods) {
+      modlist = modlist " " depmod;
+    }
+    printf "%s:%s\n", mod, modlist;
+  }
+}
diff --git a/grub-core/genmodsrc.sh b/grub-core/genmodsrc.sh
new file mode 100644 (file)
index 0000000..2d42055
--- /dev/null
@@ -0,0 +1,47 @@
+#! /bin/sh
+#
+# Copyright (C) 2002,2007  Free Software Foundation, Inc.
+#
+# This genmodsrc.sh is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+set -e
+
+mod_name="$1"
+deps="$2"
+
+cat <<EOF
+/* This file is automatically generated by genmodsrc.sh. DO NOT EDIT! */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+
+EOF
+
+echo "GRUB_MOD_NAME(${mod_name});"
+
+for mod in `grep "^${mod_name}:" ${deps} | sed 's/^[^:]*://'`; do
+  echo "GRUB_MOD_DEP(${mod});"
+done
diff --git a/grub-core/genpartmaplist.sh b/grub-core/genpartmaplist.sh
new file mode 100644 (file)
index 0000000..fceb0f8
--- /dev/null
@@ -0,0 +1,26 @@
+#! /bin/sh
+#
+# Copyright (C) 2005, 2008  Free Software Foundation, Inc.
+#
+# This script is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read source code from stdin and detect partmap names.
+
+module=$1
+
+# Ignore kernel.mod.
+if test $module = kernel; then
+    exit
+fi
+
+# For now, this emits only a module name, if the module registers a partition map.
+if grep -v "^#" | grep '^ *grub_partition_map_register' >/dev/null 2>&1; then
+    echo $module
+fi
diff --git a/grub-core/genparttoollist.sh b/grub-core/genparttoollist.sh
new file mode 100644 (file)
index 0000000..48a0efe
--- /dev/null
@@ -0,0 +1,19 @@
+#! /bin/sh
+#
+# Copyright (C) 2009  Free Software Foundation, Inc.
+#
+# This gensymlist.sh is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read source code from stdin and detect parttool names.
+
+module=$1
+
+grep -v "^#" | sed -n \
+ -e "/grub_parttool_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $module/;p;}"
diff --git a/grub-core/gensymlist.sh b/grub-core/gensymlist.sh
new file mode 100644 (file)
index 0000000..0ab56e9
--- /dev/null
@@ -0,0 +1,71 @@
+#! /bin/sh
+#
+# Copyright (C) 2002,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+#
+# This gensymlist.sh.in is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+cat <<EOF
+/* This file is automatically generated by gensymlist.sh. DO NOT EDIT! */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+EOF
+
+for i in $*; do
+  echo "#include <$i>"
+done
+
+cat <<EOF
+
+#define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; }
+
+void
+grub_register_exported_symbols (void)
+{
+EOF
+
+cat <<EOF
+  struct symtab { const char *name; void *addr; };
+  struct symtab *p;
+  static struct symtab tab[] =
+    {
+EOF
+
+(while read LINE; do echo $LINE; done) \
+  | grep -v '^#' \
+  | sed -n \
+        -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/      {"\1", \1},/;p;}' \
+        -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/      {"\1", \&\1},/;p;}' \
+  | sort -u
+
+cat <<EOF
+      {0, 0}
+    };
+
+  COMPILE_TIME_ASSERT (sizeof (tab) > sizeof (tab[0]));
+  for (p = tab; p->name; p++)
+    grub_dl_register_symbol (p->name, p->addr, 0);
+}
+EOF
diff --git a/grub-core/genterminallist.sh b/grub-core/genterminallist.sh
new file mode 100644 (file)
index 0000000..60f5b91
--- /dev/null
@@ -0,0 +1,20 @@
+#! /bin/sh
+#
+# Copyright (C) 2009,2010  Free Software Foundation, Inc.
+#
+# This script is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read source code from stdin and detect command names.
+
+module=$1
+
+grep -v "^#" | sed -n \
+ -e "/grub_term_register_input *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $module/;p;}" \
+ -e "/grub_term_register_output *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $module/;p;}" \
diff --git a/grub-core/gentrigtables.c b/grub-core/gentrigtables.c
new file mode 100644 (file)
index 0000000..bef2b08
--- /dev/null
@@ -0,0 +1,49 @@
+/* Generate trigonometric function tables. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define _GNU_SOURCE 1
+
+#include <grub/trig.h>
+#include <math.h>
+#include <stdio.h>
+
+int
+main (int argc __attribute__ ((unused)),
+      char **argv __attribute__ ((unused)))
+{
+  int i;
+
+  printf ("#include <grub/types.h>\n");
+
+#define TAB(op) \
+  printf ("grub_int16_t grub_trig_" #op "tab[] =\n{"); \
+  for (i = 0; i < GRUB_TRIG_ANGLE_MAX; i++) \
+    { \
+      double x = i * 2 * M_PI / GRUB_TRIG_ANGLE_MAX; \
+      if (i % 10 == 0) \
+       printf ("\n    "); \
+      printf ("%d,", (int) (round (op (x) * GRUB_TRIG_FRACTION_SCALE))); \
+    } \
+  printf ("\n};\n")
+
+  TAB(sin);
+  TAB(cos);
+
+  return 0;
+}
diff --git a/grub-core/genvideolist.sh b/grub-core/genvideolist.sh
new file mode 100644 (file)
index 0000000..b208fa2
--- /dev/null
@@ -0,0 +1,26 @@
+#! /bin/sh
+#
+# Copyright (C) 2005,2008,2009  Free Software Foundation, Inc.
+#
+# This script is free software; the author
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Read source code from stdin and detect partmap names.
+
+module=$1
+
+# Ignore video.mod.
+if test $module = video; then
+    exit
+fi
+
+# For now, this emits only a module name, if the module registers a partition map.
+if grep -v "^#" | grep '^ *grub_video_register' >/dev/null 2>&1; then
+    echo $module
+fi
diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c
new file mode 100644 (file)
index 0000000..0aa8dec
--- /dev/null
@@ -0,0 +1,377 @@
+/* gettext.c - gettext module */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/list.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/normal.h>
+#include <grub/file.h>
+#include <grub/kernel.h>
+#include <grub/gzio.h>
+#include <grub/i18n.h>
+
+/*
+   .mo file information from:
+   http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html .
+*/
+
+
+static grub_file_t fd_mo;
+
+static int grub_gettext_offsetoriginal;
+static int grub_gettext_max;
+
+static const char *(*grub_gettext_original) (const char *s);
+
+struct grub_gettext_msg
+{
+  struct grub_gettext_msg *next;
+  const char *name;
+
+  const char *translated;
+};
+
+struct grub_gettext_msg *grub_gettext_msg_list = NULL;
+
+#define GETTEXT_MAGIC_NUMBER           0
+#define GETTEXT_FILE_FORMAT            4
+#define GETTEXT_NUMBER_OF_STRINGS      8
+#define GETTEXT_OFFSET_ORIGINAL        12
+#define GETTEXT_OFFSET_TRANSLATION     16
+
+#define MO_MAGIC_NUMBER                0x950412de
+
+static grub_ssize_t
+grub_gettext_pread (grub_file_t file, void *buf, grub_size_t len,
+                   grub_off_t offset)
+{
+  if (grub_file_seek (file, offset) == (grub_off_t) - 1)
+    {
+      return -1;
+    }
+  return grub_file_read (file, buf, len);
+}
+
+static grub_uint32_t
+grub_gettext_get_info (int offset)
+{
+  grub_uint32_t value;
+
+  grub_gettext_pread (fd_mo, (char *) &value, 4, offset);
+
+  value = grub_cpu_to_le32 (value);
+  return value;
+}
+
+static void
+grub_gettext_getstring_from_offset (grub_uint32_t offset,
+                                   grub_uint32_t length, char *translation)
+{
+  grub_gettext_pread (fd_mo, translation, length, offset);
+  translation[length] = '\0';
+}
+
+static const char *
+grub_gettext_gettranslation_from_position (int position)
+{
+  int offsettranslation;
+  int internal_position;
+  grub_uint32_t length, offset;
+  char *translation;
+
+  offsettranslation = grub_gettext_get_info (GETTEXT_OFFSET_TRANSLATION);
+
+  internal_position = offsettranslation + position * 8;
+
+  grub_gettext_pread (fd_mo, (char *) &length, 4, internal_position);
+  length = grub_cpu_to_le32 (length);
+
+  grub_gettext_pread (fd_mo, (char *) &offset, 4, internal_position + 4);
+  offset = grub_cpu_to_le32 (offset);
+
+  translation = grub_malloc (length + 1);
+  grub_gettext_getstring_from_offset (offset, length, translation);
+
+  return translation;
+}
+
+static char *
+grub_gettext_getstring_from_position (int position)
+{
+  int internal_position;
+  int length, offset;
+  char *original;
+
+  /* Get position for string i.  */
+  internal_position = grub_gettext_offsetoriginal + (position * 8);
+
+  /* Get the length of the string i.  */
+  grub_gettext_pread (fd_mo, (char *) &length, 4, internal_position);
+
+  /* Get the offset of the string i.  */
+  grub_gettext_pread (fd_mo, (char *) &offset, 4, internal_position + 4);
+
+  /* Get the string i.  */
+  original = grub_malloc (length + 1);
+  grub_gettext_getstring_from_offset (offset, length, original);
+
+  return original;
+}
+
+static const char *
+grub_gettext_translate (const char *orig)
+{
+  char *current_string;
+  const char *ret;
+
+  int min, max, current;
+  int found = 0;
+
+  struct grub_gettext_msg *cur;
+
+  /* Make sure we can use grub_gettext_translate for error messages.  Push
+     active error message to error stack and reset error message.  */
+  grub_error_push ();
+
+  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_gettext_msg_list),
+                             orig);
+
+  if (cur)
+    {
+      grub_error_pop ();
+      return cur->translated;
+    }
+
+  if (fd_mo == 0)
+    {
+      grub_error_pop ();
+      return orig;
+    }
+
+  min = 0;
+  max = grub_gettext_max;
+
+  current = (max + min) / 2;
+
+  while (current != min && current != max && found == 0)
+    {
+      current_string = grub_gettext_getstring_from_position (current);
+
+      /* Search by bisection.  */
+      if (grub_strcmp (current_string, orig) < 0)
+       {
+         grub_free (current_string);
+         min = current;
+       }
+      else if (grub_strcmp (current_string, orig) > 0)
+       {
+         grub_free (current_string);
+         max = current;
+       }
+      else if (grub_strcmp (current_string, orig) == 0)
+       {
+         grub_free (current_string);
+         found = 1;
+       }
+      current = (max + min) / 2;
+    }
+
+  ret = found ? grub_gettext_gettranslation_from_position (current) : orig;
+
+  if (found)
+    {
+      cur = grub_zalloc (sizeof (*cur));
+
+      if (cur)
+       {
+         cur->name = grub_strdup (orig);
+         if (cur->name)
+           {
+             cur->translated = ret;
+             grub_list_push (GRUB_AS_LIST_P (&grub_gettext_msg_list),
+                             GRUB_AS_LIST (cur));
+           }
+       }
+      else
+       grub_errno = GRUB_ERR_NONE;
+    }
+
+  grub_error_pop ();
+  return ret;
+}
+
+/* This is similar to grub_gzfile_open. */
+static grub_file_t
+grub_mofile_open (const char *filename)
+{
+  int unsigned magic;
+  int version;
+
+  /* Using fd_mo and not another variable because
+     it's needed for grub_gettext_get_info.  */
+
+  fd_mo = grub_gzfile_open (filename, 1);
+  grub_errno = GRUB_ERR_NONE;
+
+  if (!fd_mo)
+    {
+      grub_dprintf ("gettext", "Cannot read %s\n", filename);
+      return 0;
+    }
+
+  magic = grub_gettext_get_info (GETTEXT_MAGIC_NUMBER);
+
+  if (magic != MO_MAGIC_NUMBER)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "mo: invalid mo file: %s",
+                 filename);
+      grub_file_close (fd_mo);
+      fd_mo = 0;
+      return 0;
+    }
+
+  version = grub_gettext_get_info (GETTEXT_FILE_FORMAT);
+
+  if (version != 0)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                 "mo: invalid mo version in file: %s", filename);
+      fd_mo = 0;
+      return 0;
+    }
+
+  return fd_mo;
+}
+
+static void
+grub_gettext_init_ext (const char *lang)
+{
+  char *mo_file;
+  char *locale_dir;
+
+  locale_dir = grub_env_get ("locale_dir");
+  if (locale_dir == NULL)
+    {
+      grub_dprintf ("gettext", "locale_dir variable is not set up.\n");
+      return;
+    }
+
+  fd_mo = NULL;
+
+  /* mo_file e.g.: /boot/grub/locale/ca.mo   */
+
+  mo_file = grub_xasprintf ("%s/%s.mo", locale_dir, lang);
+  if (!mo_file)
+    return;
+
+  fd_mo = grub_mofile_open (mo_file);
+
+  /* Will try adding .gz as well.  */
+  if (fd_mo == NULL)
+    {
+      grub_free (mo_file);
+      mo_file = grub_xasprintf ("%s.gz", mo_file);
+      if (!mo_file)
+       return;
+      fd_mo = grub_mofile_open (mo_file);
+    }
+
+  if (fd_mo)
+    {
+      grub_gettext_offsetoriginal =
+       grub_gettext_get_info (GETTEXT_OFFSET_ORIGINAL);
+      grub_gettext_max = grub_gettext_get_info (GETTEXT_NUMBER_OF_STRINGS);
+
+      grub_gettext_original = grub_gettext;
+      grub_gettext = grub_gettext_translate;
+    }
+}
+
+static void
+grub_gettext_delete_list (void)
+{
+  struct grub_gettext_msg *item;
+
+  while ((item =
+         grub_list_pop (GRUB_AS_LIST_P (&grub_gettext_msg_list))) != 0)
+    {
+      char *original = (char *) ((struct grub_gettext_msg *) item)->name;
+      grub_free (original);
+
+      /* Don't delete the translated message because could be in use.  */
+    }
+}
+
+static char *
+grub_gettext_env_write_lang (struct grub_env_var *var
+                            __attribute__ ((unused)), const char *val)
+{
+  grub_gettext_init_ext (val);
+
+  grub_gettext_delete_list ();
+
+  return grub_strdup (val);
+}
+
+static grub_err_t
+grub_cmd_translate (grub_command_t cmd __attribute__ ((unused)),
+                   int argc, char **args)
+{
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "text to translate required");
+
+  const char *translation;
+  translation = grub_gettext_translate (args[0]);
+  grub_printf ("%s\n", translation);
+  return 0;
+}
+
+GRUB_MOD_INIT (gettext)
+{
+  (void) mod;                  /* To stop warning.  */
+
+  const char *lang;
+
+  lang = grub_env_get ("lang");
+
+  grub_gettext_init_ext (lang);
+
+  grub_register_command_p1 ("gettext", grub_cmd_translate,
+                           N_("STRING"),
+                           N_("Translates the string with the current settings."));
+
+  /* Reload .mo file information if lang changes.  */
+  grub_register_variable_hook ("lang", NULL, grub_gettext_env_write_lang);
+
+  /* Preserve hooks after context changes.  */
+  grub_env_export ("lang");
+}
+
+GRUB_MOD_FINI (gettext)
+{
+  if (fd_mo != 0)
+    grub_file_close (fd_mo);
+
+  grub_gettext_delete_list ();
+
+  grub_gettext = grub_gettext_original;
+}
diff --git a/grub-core/gfxmenu/gfxmenu.c b/grub-core/gfxmenu/gfxmenu.c
new file mode 100644 (file)
index 0000000..a2e7651
--- /dev/null
@@ -0,0 +1,144 @@
+/* gfxmenu.c - Graphical menu interface controller. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/command.h>
+#include <grub/video.h>
+#include <grub/gfxterm.h>
+#include <grub/bitmap.h>
+#include <grub/bitmap_scale.h>
+#include <grub/term.h>
+#include <grub/env.h>
+#include <grub/normal.h>
+#include <grub/gfxwidgets.h>
+#include <grub/menu.h>
+#include <grub/menu_viewer.h>
+#include <grub/gfxmenu_model.h>
+#include <grub/gfxmenu_view.h>
+#include <grub/time.h>
+
+grub_gfxmenu_view_t cached_view;
+
+static void 
+grub_gfxmenu_viewer_fini (void *data __attribute__ ((unused)))
+{
+}
+
+/* FIXME: Previously 't' changed to text menu is it necessary?  */
+static grub_err_t
+grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
+{
+  grub_gfxmenu_view_t view = NULL;
+  const char *theme_path;
+  struct grub_menu_viewer *instance;
+  grub_err_t err;
+  struct grub_video_mode_info mode_info;
+
+  theme_path = grub_env_get ("theme");
+  if (! theme_path)
+    {
+      grub_error_push ();
+      grub_gfxterm_fullscreen ();
+      grub_error_pop ();
+      return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no theme specified");
+    }
+
+  instance = grub_zalloc (sizeof (*instance));
+  if (!instance)
+    {
+      grub_error_push ();
+      grub_gfxterm_fullscreen ();
+      grub_error_pop ();
+      return grub_errno;
+    }
+
+  err = grub_video_get_info (&mode_info);
+  if (err)
+    {
+      grub_error_push ();
+      grub_gfxterm_fullscreen ();
+      grub_error_pop ();
+      return err;
+    }
+
+  if (!cached_view || grub_strcmp (cached_view->theme_path, theme_path) != 0
+      || cached_view->screen.width != mode_info.width
+      || cached_view->screen.height != mode_info.height)
+    {
+      grub_free (cached_view);
+      /* Create the view.  */
+      cached_view = grub_gfxmenu_view_new (theme_path, mode_info.width,
+                                          mode_info.height);
+    }
+
+  if (! cached_view)
+    {
+      grub_free (instance);
+      grub_error_push ();
+      grub_gfxterm_fullscreen ();
+      grub_error_pop ();
+      return grub_errno;
+    }
+
+  view = cached_view;
+
+  view->double_repaint = (mode_info.mode_type
+                         & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)
+    && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
+  view->selected = entry;
+  view->menu = menu;
+  view->nested = nested;
+  view->first_timeout = -1;
+
+  grub_gfxmenu_view_draw (view);
+
+  instance->data = view;
+  instance->set_chosen_entry = grub_gfxmenu_set_chosen_entry;
+  instance->fini = grub_gfxmenu_viewer_fini;
+  instance->print_timeout = grub_gfxmenu_print_timeout;
+  instance->clear_timeout = grub_gfxmenu_clear_timeout;
+
+  grub_menu_register_viewer (instance);
+
+  return GRUB_ERR_NONE;
+}
+
+GRUB_MOD_INIT (gfxmenu)
+{
+  struct grub_term_output *term;
+
+  FOR_ACTIVE_TERM_OUTPUTS(term)
+    if (grub_gfxmenu_try_hook && grub_strcmp (term->name, "gfxterm") == 0)
+      {
+       grub_gfxterm_fullscreen ();
+       break;
+      }
+
+  grub_gfxmenu_try_hook = grub_gfxmenu_try;
+}
+
+GRUB_MOD_FINI (gfxmenu)
+{
+  grub_gfxmenu_view_destroy (cached_view);
+  grub_gfxmenu_try_hook = NULL;
+}
diff --git a/grub-core/gfxmenu/gui_box.c b/grub-core/gfxmenu/gui_box.c
new file mode 100644 (file)
index 0000000..38b15f9
--- /dev/null
@@ -0,0 +1,412 @@
+/* gui_box.c - GUI container that stack components. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/gui.h>
+#include <grub/gui_string_util.h>
+
+struct component_node
+{
+  grub_gui_component_t component;
+  struct component_node *next;
+  struct component_node *prev;
+};
+
+typedef struct grub_gui_box *grub_gui_box_t;
+
+typedef void (*layout_func_t) (grub_gui_box_t self, int modify_layout,
+                               unsigned *minimal_width,
+                              unsigned *minimal_height);
+
+struct grub_gui_box
+{
+  struct grub_gui_container container;
+
+  grub_gui_container_t parent;
+  grub_video_rect_t bounds;
+  char *id;
+
+  /* Doubly linked list of components with dummy head & tail nodes.  */
+  struct component_node chead;
+  struct component_node ctail;
+
+  /* The layout function: differs for vertical and horizontal boxes.  */
+  layout_func_t layout_func;
+};
+
+static void
+box_destroy (void *vself)
+{
+  grub_gui_box_t self = vself;
+  struct component_node *cur;
+  struct component_node *next;
+  for (cur = self->chead.next; cur != &self->ctail; cur = next)
+    {
+      /* Copy the 'next' pointer, since we need it for the next iteration,
+         and we're going to free the memory it is stored in.  */
+      next = cur->next;
+      /* Destroy the child component.  */
+      cur->component->ops->destroy (cur->component);
+      /* Free the linked list node.  */
+      grub_free (cur);
+    }
+  grub_free (self);
+}
+
+static const char *
+box_get_id (void *vself)
+{
+  grub_gui_box_t self = vself;
+  return self->id;
+}
+
+static int
+box_is_instance (void *vself __attribute__((unused)), const char *type)
+{
+  return (grub_strcmp (type, "component") == 0
+          || grub_strcmp (type, "container") == 0);
+}
+
+static void
+layout_horizontally (grub_gui_box_t self, int modify_layout,
+                     unsigned *min_width, unsigned *min_height)
+{
+  /* Start at the left (chead) and set the x coordinates as we go right.  */
+  /* All components have their width set to the box's width.  */
+
+  struct component_node *cur;
+  unsigned w = 0, mwfrac = 0, h = 0, x = 0;
+  grub_fixed_signed_t wfrac = 0;
+  int bogus_frac = 0;
+
+  for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
+    {
+      grub_gui_component_t c = cur->component;
+      unsigned mw = 0, mh = 0;
+
+      if (c->ops->get_minimal_size)
+       c->ops->get_minimal_size (c, &mw, &mh);
+
+      if (c->h > (signed) h)
+       h = c->h;
+      if (mh > h)
+       h = mh;
+      wfrac += c->wfrac;
+      w += c->w;
+      if (mw - c->w > 0)
+       mwfrac += mw - c->w;
+    }
+  if (wfrac > GRUB_FIXED_1 || (w > 0 && wfrac == GRUB_FIXED_1))
+    bogus_frac = 1;
+
+  if (min_width)
+    {
+      if (wfrac < GRUB_FIXED_1)
+       *min_width = grub_fixed_sfs_divide (w, GRUB_FIXED_1 - wfrac);
+      else
+       *min_width = w;
+      if (*min_width < w + mwfrac)
+       *min_width = w + mwfrac;
+    }
+  if (min_height)
+    *min_height = h;
+
+  if (!modify_layout)
+    return;
+
+  for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
+    {
+      grub_video_rect_t r;
+      grub_gui_component_t c = cur->component;
+      unsigned mw = 0, mh = 0;
+
+      r.x = x;
+      r.y = 0;
+      r.height = h;
+
+      if (c->ops->get_minimal_size)
+       c->ops->get_minimal_size (c, &mw, &mh);
+
+      r.width = c->w;
+      if (!bogus_frac)
+       r.width += grub_fixed_sfs_multiply (self->bounds.width, c->wfrac);
+
+      if (r.width < mw)
+       r.width = mw;
+
+      c->ops->set_bounds (c, &r);
+
+      x += r.width;
+    }
+}
+
+static void
+layout_vertically (grub_gui_box_t self, int modify_layout,
+                     unsigned *min_width, unsigned *min_height)
+{
+  /* Start at the top (chead) and set the y coordinates as we go rdown.  */
+  /* All components have their height set to the box's height.  */
+
+  struct component_node *cur;
+  unsigned h = 0, mhfrac = 0, w = 0, y = 0;
+  grub_fixed_signed_t hfrac = 0;
+  int bogus_frac = 0;
+
+  for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
+    {
+      grub_gui_component_t c = cur->component;
+      unsigned mw = 0, mh = 0;
+
+      if (c->ops->get_minimal_size)
+       c->ops->get_minimal_size (c, &mw, &mh);
+
+      if (c->w > (signed) w)
+       w = c->w;
+      if (mw > w)
+       w = mw;
+      hfrac += c->hfrac;
+      h += c->h;
+      if (mh - c->h > 0)
+       mhfrac += mh - c->h;
+    }
+  if (hfrac > GRUB_FIXED_1 || (h > 0 && hfrac == GRUB_FIXED_1))
+    bogus_frac = 1;
+
+  if (min_height)
+    {
+      if (hfrac < GRUB_FIXED_1)
+       *min_height = grub_fixed_sfs_divide (h, GRUB_FIXED_1 - hfrac);
+      else
+       *min_height = h;
+      if (*min_height < h + mhfrac)
+       *min_height = h + mhfrac;
+    }
+  if (min_width)
+    *min_width = w;
+
+  if (!modify_layout)
+    return;
+
+  for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
+    {
+      grub_video_rect_t r;
+      grub_gui_component_t c = cur->component;
+      unsigned mw = 0, mh = 0;
+
+      r.x = 0;
+      r.y = y;
+      r.width = w;
+
+      if (c->ops->get_minimal_size)
+       c->ops->get_minimal_size (c, &mw, &mh);
+
+      r.height = c->h;
+      if (!bogus_frac)
+       r.height += grub_fixed_sfs_multiply (self->bounds.height, c->hfrac);
+
+      if (r.height < mh)
+       r.height = mh;
+
+      c->ops->set_bounds (c, &r);
+
+      y += r.height;
+    }
+}
+
+static void
+box_paint (void *vself, const grub_video_rect_t *region)
+{
+  grub_gui_box_t self = vself;
+  struct component_node *cur;
+  grub_video_rect_t vpsave;
+
+  grub_gui_set_viewport (&self->bounds, &vpsave);
+  for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
+    {
+      grub_gui_component_t comp = cur->component;
+      comp->ops->paint (comp, region);
+    }
+  grub_gui_restore_viewport (&vpsave);
+}
+
+static void
+box_set_parent (void *vself, grub_gui_container_t parent)
+{
+  grub_gui_box_t self = vself;
+  self->parent = parent;
+}
+
+static grub_gui_container_t
+box_get_parent (void *vself)
+{
+  grub_gui_box_t self = vself;
+  return self->parent;
+}
+
+static void
+box_set_bounds (void *vself, const grub_video_rect_t *bounds)
+{
+  grub_gui_box_t self = vself;
+  self->bounds = *bounds;
+  self->layout_func (self, 1, 0, 0);   /* Relayout the children.  */
+}
+
+static void
+box_get_bounds (void *vself, grub_video_rect_t *bounds)
+{
+  grub_gui_box_t self = vself;
+  *bounds = self->bounds;
+}
+
+/* The box's preferred size is based on the preferred sizes
+   of its children.  */
+static void
+box_get_minimal_size (void *vself, unsigned *width, unsigned *height)
+{
+  grub_gui_box_t self = vself;
+  self->layout_func (self, 0, width, height);   /* Just calculate the size.  */
+}
+
+static grub_err_t
+box_set_property (void *vself, const char *name, const char *value)
+{
+  grub_gui_box_t self = vself;
+  if (grub_strcmp (name, "id") == 0)
+    {
+      grub_free (self->id);
+      if (value)
+        {
+          self->id = grub_strdup (value);
+          if (! self->id)
+            return grub_errno;
+        }
+      else
+        self->id = 0;
+    }
+
+  return grub_errno;
+}
+
+static void
+box_add (void *vself, grub_gui_component_t comp)
+{
+  grub_gui_box_t self = vself;
+  struct component_node *node;
+  node = grub_malloc (sizeof (*node));
+  if (! node)
+    return;   /* Note: probably should handle the error.  */
+  node->component = comp;
+  /* Insert the node before the tail.  */
+  node->prev = self->ctail.prev;
+  node->prev->next = node;
+  node->next = &self->ctail;
+  node->next->prev = node;
+
+  comp->ops->set_parent (comp, (grub_gui_container_t) self);
+  self->layout_func (self, 1, 0, 0);   /* Relayout the children.  */
+}
+
+static void
+box_remove (void *vself, grub_gui_component_t comp)
+{
+  grub_gui_box_t self = vself;
+  struct component_node *cur;
+  for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
+    {
+      if (cur->component == comp)
+        {
+          /* Unlink 'cur' from the list.  */
+          cur->prev->next = cur->next;
+          cur->next->prev = cur->prev;
+          /* Free the node's memory (but don't destroy the component).  */
+          grub_free (cur);
+          /* Must not loop again, since 'cur' would be dereferenced!  */
+          return;
+        }
+    }
+}
+
+static void
+box_iterate_children (void *vself,
+                      grub_gui_component_callback cb, void *userdata)
+{
+  grub_gui_box_t self = vself;
+  struct component_node *cur;
+  for (cur = self->chead.next; cur != &self->ctail; cur = cur->next)
+    cb (cur->component, userdata);
+}
+
+static struct grub_gui_component_ops box_comp_ops =
+  {
+    .destroy = box_destroy,
+    .get_id = box_get_id,
+    .is_instance = box_is_instance,
+    .paint = box_paint,
+    .set_parent = box_set_parent,
+    .get_parent = box_get_parent,
+    .set_bounds = box_set_bounds,
+    .get_bounds = box_get_bounds,
+    .get_minimal_size = box_get_minimal_size,
+    .set_property = box_set_property
+  };
+
+static struct grub_gui_container_ops box_ops =
+{
+  .add = box_add,
+  .remove = box_remove,
+  .iterate_children = box_iterate_children
+};
+
+/* Box constructor.  Specify the appropriate layout function to create
+   a horizontal or vertical stacking box.  */
+static grub_gui_box_t
+box_new (layout_func_t layout_func)
+{
+  grub_gui_box_t box;
+  box = grub_zalloc (sizeof (*box));
+  if (! box)
+    return 0;
+  box->container.ops = &box_ops;
+  box->container.component.ops = &box_comp_ops;
+  box->chead.next = &box->ctail;
+  box->ctail.prev = &box->chead;
+  box->layout_func = layout_func;
+  return box;
+}
+
+/* Create a new container that stacks its child components horizontally,
+   from left to right.  Each child get a width corresponding to its
+   preferred width.  The height of each child is set the maximum of the
+   preferred heights of all children.  */
+grub_gui_container_t
+grub_gui_hbox_new (void)
+{
+  return (grub_gui_container_t) box_new (layout_horizontally);
+}
+
+/* Create a new container that stacks its child components verticallyj,
+   from top to bottom.  Each child get a height corresponding to its
+   preferred height.  The width of each child is set the maximum of the
+   preferred widths of all children.  */
+grub_gui_container_t
+grub_gui_vbox_new (void)
+{
+  return (grub_gui_container_t) box_new (layout_vertically);
+}
diff --git a/grub-core/gfxmenu/gui_canvas.c b/grub-core/gfxmenu/gui_canvas.c
new file mode 100644 (file)
index 0000000..b3919c2
--- /dev/null
@@ -0,0 +1,267 @@
+/* gui_canvas.c - GUI container allowing manually placed components. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/gui.h>
+#include <grub/gui_string_util.h>
+
+/* TODO Add layering so that components can be properly overlaid. */
+
+struct component_node
+{
+  grub_gui_component_t component;
+  struct component_node *next;
+};
+
+struct grub_gui_canvas
+{
+  struct grub_gui_container container;
+
+  grub_gui_container_t parent;
+  grub_video_rect_t bounds;
+  char *id;
+  /* Component list (dummy head node).  */
+  struct component_node components;
+};
+
+typedef struct grub_gui_canvas *grub_gui_canvas_t;
+
+static void
+canvas_destroy (void *vself)
+{
+  grub_gui_canvas_t self = vself;
+  struct component_node *cur;
+  struct component_node *next;
+  for (cur = self->components.next; cur; cur = next)
+    {
+      /* Copy the 'next' pointer, since we need it for the next iteration,
+         and we're going to free the memory it is stored in.  */
+      next = cur->next;
+      /* Destroy the child component.  */
+      cur->component->ops->destroy (cur->component);
+      /* Free the linked list node.  */
+      grub_free (cur);
+    }
+  grub_free (self);
+}
+
+static const char *
+canvas_get_id (void *vself)
+{
+  grub_gui_canvas_t self = vself;
+  return self->id;
+}
+
+static int
+canvas_is_instance (void *vself __attribute__((unused)), const char *type)
+{
+  return (grub_strcmp (type, "component") == 0
+          || grub_strcmp (type, "container") == 0);
+}
+
+static void
+canvas_paint (void *vself, const grub_video_rect_t *region)
+{
+  grub_gui_canvas_t self = vself;
+  struct component_node *cur;
+  grub_video_rect_t vpsave;
+
+  grub_gui_set_viewport (&self->bounds, &vpsave);
+  for (cur = self->components.next; cur; cur = cur->next)
+    {
+      grub_video_rect_t r;
+      grub_gui_component_t comp;
+      signed x, y, w, h;
+
+      comp = cur->component;
+
+      w = grub_fixed_sfs_multiply (self->bounds.width, comp->wfrac) + comp->w;
+      h = grub_fixed_sfs_multiply (self->bounds.height, comp->hfrac) + comp->h;
+      x = grub_fixed_sfs_multiply (self->bounds.width, comp->xfrac) + comp->x;
+      y = grub_fixed_sfs_multiply (self->bounds.height, comp->yfrac) + comp->y;
+
+      if (comp->ops->get_minimal_size)
+       {
+         unsigned mw;
+         unsigned mh;
+         comp->ops->get_minimal_size (comp, &mw, &mh);
+         if (w < (signed) mw)
+           w = mw;
+         if (h < (signed) mh)
+           h = mh;
+       }
+
+      /* Sanity checks.  */
+      if (w <= 0)
+       w = 32;
+      if (h <= 0)
+       h = 32;
+
+      if (x >= (signed) self->bounds.width)
+       x = self->bounds.width - 32;
+      if (y >= (signed) self->bounds.height)
+       y = self->bounds.height - 32;
+
+      if (x < 0)
+       x = 0;
+      if (y < 0)
+       y = 0;
+
+      if (x + w >= (signed) self->bounds.width)
+       w = self->bounds.width - x;
+      if (y + h >= (signed) self->bounds.height)
+       h = self->bounds.height - y;
+
+      r.x = x;
+      r.y = y;
+      r.width = w;
+      r.height = h;
+      comp->ops->set_bounds (comp, &r);
+
+      /* Paint the child.  */
+      if (grub_video_have_common_points (region, &r))
+       comp->ops->paint (comp, region);
+    }
+  grub_gui_restore_viewport (&vpsave);
+}
+
+static void
+canvas_set_parent (void *vself, grub_gui_container_t parent)
+{
+  grub_gui_canvas_t self = vself;
+  self->parent = parent;
+}
+
+static grub_gui_container_t
+canvas_get_parent (void *vself)
+{
+  grub_gui_canvas_t self = vself;
+  return self->parent;
+}
+
+static void
+canvas_set_bounds (void *vself, const grub_video_rect_t *bounds)
+{
+  grub_gui_canvas_t self = vself;
+  self->bounds = *bounds;
+}
+
+static void
+canvas_get_bounds (void *vself, grub_video_rect_t *bounds)
+{
+  grub_gui_canvas_t self = vself;
+  *bounds = self->bounds;
+}
+
+static grub_err_t
+canvas_set_property (void *vself, const char *name, const char *value)
+{
+  grub_gui_canvas_t self = vself;
+  if (grub_strcmp (name, "id") == 0)
+    {
+      grub_free (self->id);
+      if (value)
+        {
+          self->id = grub_strdup (value);
+          if (! self->id)
+            return grub_errno;
+        }
+      else
+        self->id = 0;
+    }
+  return grub_errno;
+}
+
+static void
+canvas_add (void *vself, grub_gui_component_t comp)
+{
+  grub_gui_canvas_t self = vself;
+  struct component_node *node;
+  node = grub_malloc (sizeof (*node));
+  if (! node)
+    return;   /* Note: probably should handle the error.  */
+  node->component = comp;
+  node->next = self->components.next;
+  self->components.next = node;
+  comp->ops->set_parent (comp, (grub_gui_container_t) self);
+}
+
+static void
+canvas_remove (void *vself, grub_gui_component_t comp)
+{
+  grub_gui_canvas_t self = vself;
+  struct component_node *cur;
+  struct component_node *prev;
+  prev = &self->components;
+  for (cur = self->components.next; cur; prev = cur, cur = cur->next)
+    {
+      if (cur->component == comp)
+        {
+          /* Unlink 'cur' from the list.  */
+          prev->next = cur->next;
+          /* Free the node's memory (but don't destroy the component).  */
+          grub_free (cur);
+          /* Must not loop again, since 'cur' would be dereferenced!  */
+          return;
+        }
+    }
+}
+
+static void
+canvas_iterate_children (void *vself,
+                         grub_gui_component_callback cb, void *userdata)
+{
+  grub_gui_canvas_t self = vself;
+  struct component_node *cur;
+  for (cur = self->components.next; cur; cur = cur->next)
+    cb (cur->component, userdata);
+}
+
+static struct grub_gui_component_ops canvas_comp_ops =
+{
+  .destroy = canvas_destroy,
+  .get_id = canvas_get_id,
+  .is_instance = canvas_is_instance,
+  .paint = canvas_paint,
+  .set_parent = canvas_set_parent,
+  .get_parent = canvas_get_parent,
+  .set_bounds = canvas_set_bounds,
+  .get_bounds = canvas_get_bounds,
+  .set_property = canvas_set_property
+};
+
+static struct grub_gui_container_ops canvas_ops =
+{
+  .add = canvas_add,
+  .remove = canvas_remove,
+  .iterate_children = canvas_iterate_children
+};
+
+grub_gui_container_t
+grub_gui_canvas_new (void)
+{
+  grub_gui_canvas_t canvas;
+  canvas = grub_zalloc (sizeof (*canvas));
+  if (! canvas)
+    return 0;
+  canvas->container.ops = &canvas_ops;
+  canvas->container.component.ops = &canvas_comp_ops;
+  return (grub_gui_container_t) canvas;
+}
diff --git a/grub-core/gfxmenu/gui_circular_progress.c b/grub-core/gfxmenu/gui_circular_progress.c
new file mode 100644 (file)
index 0000000..9a859ee
--- /dev/null
@@ -0,0 +1,302 @@
+/* gui_circular_process.c - GUI circular progress indicator component.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/gui.h>
+#include <grub/font.h>
+#include <grub/gui_string_util.h>
+#include <grub/gfxmenu_view.h>
+#include <grub/gfxwidgets.h>
+#include <grub/trig.h>
+
+struct grub_gui_circular_progress
+{
+  struct grub_gui_progress progress;
+
+  grub_gui_container_t parent;
+  grub_video_rect_t bounds;
+  char *id;
+  int visible;
+  int start;
+  int end;
+  int value;
+  int num_ticks;
+  int start_angle;
+  int ticks_disappear;
+  char *theme_dir;
+  int need_to_load_pixmaps;
+  char *center_file;
+  char *tick_file;
+  struct grub_video_bitmap *center_bitmap;
+  struct grub_video_bitmap *tick_bitmap;
+};
+
+typedef struct grub_gui_circular_progress *circular_progress_t;
+
+static void
+circprog_destroy (void *vself)
+{
+  circular_progress_t self = vself;
+  grub_free (self);
+}
+
+static const char *
+circprog_get_id (void *vself)
+{
+  circular_progress_t self = vself;
+  return self->id;
+}
+
+static int
+circprog_is_instance (void *vself __attribute__((unused)), const char *type)
+{
+  return grub_strcmp (type, "component") == 0;
+}
+
+static struct grub_video_bitmap *
+load_bitmap (const char *dir, const char *file)
+{
+  struct grub_video_bitmap *bitmap;
+  char *abspath;
+
+  /* Check arguments.  */
+  if (! dir || ! file)
+    return 0;
+
+  /* Resolve to an absolute path.  */
+  abspath = grub_resolve_relative_path (dir, file);
+  if (! abspath)
+    return 0;
+
+  /* Load the image.  */
+  grub_errno = GRUB_ERR_NONE;
+  grub_video_bitmap_load (&bitmap, abspath);
+  grub_errno = GRUB_ERR_NONE;
+
+  grub_free (abspath);
+  return bitmap;
+}
+
+static int
+check_pixmaps (circular_progress_t self)
+{
+  if (self->need_to_load_pixmaps)
+    {
+      if (self->center_bitmap)
+        grub_video_bitmap_destroy (self->center_bitmap);
+      self->center_bitmap = load_bitmap (self->theme_dir, self->center_file);
+      self->tick_bitmap = load_bitmap (self->theme_dir, self->tick_file);
+      self->need_to_load_pixmaps = 0;
+    }
+
+  return (self->center_bitmap != 0 && self->tick_bitmap != 0);
+}
+
+static void
+circprog_paint (void *vself, const grub_video_rect_t *region)
+{
+  circular_progress_t self = vself;
+
+  if (! self->visible)
+    return;
+
+  if (!grub_video_have_common_points (region, &self->bounds))
+    return;
+
+  if (! check_pixmaps (self))
+    return;
+
+  grub_video_rect_t vpsave;
+  grub_gui_set_viewport (&self->bounds, &vpsave);
+
+  int width = self->bounds.width;
+  int height = self->bounds.height;
+  int center_width = grub_video_bitmap_get_width (self->center_bitmap);
+  int center_height = grub_video_bitmap_get_height (self->center_bitmap);
+  int tick_width = grub_video_bitmap_get_width (self->tick_bitmap);
+  int tick_height = grub_video_bitmap_get_height (self->tick_bitmap);
+  grub_video_blit_bitmap (self->center_bitmap, GRUB_VIDEO_BLIT_BLEND,
+                          (width - center_width) / 2,
+                          (height - center_height) / 2, 0, 0,
+                          center_width, center_height);
+
+  int radius = width / 2 - tick_width / 2 - 1;
+  int nticks;
+  int tick_begin;
+  int tick_end;
+  if (self->end == self->start)
+    nticks = 0;
+  else
+    nticks = (self->num_ticks
+             * (self->value - self->start)
+             / (self->end - self->start));
+  /* Do ticks appear or disappear as the value approached the end?  */
+  if (self->ticks_disappear)
+    {
+      tick_begin = nticks;
+      tick_end = self->num_ticks - 1;
+    }
+  else
+    {
+      tick_begin = 0;
+      tick_end = nticks - 1;
+    }
+
+  int i;
+  for (i = tick_begin; i < tick_end; i++)
+    {
+       int x;
+       int y;
+       int angle;
+
+       /* Calculate the location of the tick.  */
+       angle = self->start_angle + i * GRUB_TRIG_ANGLE_MAX / self->num_ticks;
+       x = width / 2 + (grub_cos (angle) * radius / GRUB_TRIG_FRACTION_SCALE);
+       y = height / 2 + (grub_sin (angle) * radius / GRUB_TRIG_FRACTION_SCALE);
+
+       /* Adjust (x,y) so the tick is centered.  */
+       x -= tick_width / 2;
+       y -= tick_height / 2;
+
+       /* Draw the tick.  */
+       grub_video_blit_bitmap (self->tick_bitmap, GRUB_VIDEO_BLIT_BLEND,
+                               x, y, 0, 0, tick_width, tick_height);
+    }
+
+  grub_gui_restore_viewport (&vpsave);
+}
+
+static void
+circprog_set_parent (void *vself, grub_gui_container_t parent)
+{
+  circular_progress_t self = vself;
+  self->parent = parent;
+}
+
+static grub_gui_container_t
+circprog_get_parent (void *vself)
+{
+  circular_progress_t self = vself;
+  return self->parent;
+}
+
+static void
+circprog_set_bounds (void *vself, const grub_video_rect_t *bounds)
+{
+  circular_progress_t self = vself;
+  self->bounds = *bounds;
+}
+
+static void
+circprog_get_bounds (void *vself, grub_video_rect_t *bounds)
+{
+  circular_progress_t self = vself;
+  *bounds = self->bounds;
+}
+
+static grub_err_t
+circprog_set_property (void *vself, const char *name, const char *value)
+{
+  circular_progress_t self = vself;
+  if (grub_strcmp (name, "num_ticks") == 0)
+    {
+      self->num_ticks = grub_strtol (value, 0, 10);
+    }
+  else if (grub_strcmp (name, "start_angle") == 0)
+    {
+      self->start_angle = grub_strtol (value, 0, 10);
+    }
+  else if (grub_strcmp (name, "ticks_disappear") == 0)
+    {
+      self->ticks_disappear = grub_strcmp (value, "false") != 0;
+    }
+  else if (grub_strcmp (name, "center_bitmap") == 0)
+    {
+      self->need_to_load_pixmaps = 1;
+      grub_free (self->center_file);
+      self->center_file = value ? grub_strdup (value) : 0;
+    }
+  else if (grub_strcmp (name, "tick_bitmap") == 0)
+    {
+      self->need_to_load_pixmaps = 1;
+      grub_free (self->tick_file);
+      self->tick_file = value ? grub_strdup (value) : 0;
+    }
+  else if (grub_strcmp (name, "theme_dir") == 0)
+    {
+      self->need_to_load_pixmaps = 1;
+      grub_free (self->theme_dir);
+      self->theme_dir = value ? grub_strdup (value) : 0;
+    }
+  else if (grub_strcmp (name, "id") == 0)
+    {
+      grub_free (self->id);
+      if (value)
+        self->id = grub_strdup (value);
+      else
+        self->id = 0;
+    }
+  return grub_errno;
+}
+
+static void
+circprog_set_state (void *vself, int visible, int start,
+                   int current, int end)
+{
+  circular_progress_t self = vself;  
+  self->visible = visible;
+  self->start = start;
+  self->value = current;
+  self->end = end;
+}
+
+static struct grub_gui_component_ops circprog_ops =
+{
+  .destroy = circprog_destroy,
+  .get_id = circprog_get_id,
+  .is_instance = circprog_is_instance,
+  .paint = circprog_paint,
+  .set_parent = circprog_set_parent,
+  .get_parent = circprog_get_parent,
+  .set_bounds = circprog_set_bounds,
+  .get_bounds = circprog_get_bounds,
+  .set_property = circprog_set_property
+};
+
+static struct grub_gui_progress_ops circprog_prog_ops =
+  {
+    .set_state = circprog_set_state
+  };
+
+grub_gui_component_t
+grub_gui_circular_progress_new (void)
+{
+  circular_progress_t self;
+  self = grub_zalloc (sizeof (*self));
+  if (! self)
+    return 0;
+  self->progress.ops = &circprog_prog_ops;
+  self->progress.component.ops = &circprog_ops;
+  self->visible = 1;
+  self->num_ticks = 64;
+  self->start_angle = -64;
+
+  return (grub_gui_component_t) self;
+}
diff --git a/grub-core/gfxmenu/gui_image.c b/grub-core/gfxmenu/gui_image.c
new file mode 100644 (file)
index 0000000..3988f4b
--- /dev/null
@@ -0,0 +1,269 @@
+/* gui_image.c - GUI component to display an image.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/gui.h>
+#include <grub/gui_string_util.h>
+#include <grub/bitmap.h>
+#include <grub/bitmap_scale.h>
+
+struct grub_gui_image
+{
+  struct grub_gui_component component;
+
+  grub_gui_container_t parent;
+  grub_video_rect_t bounds;
+  char *id;
+  char *theme_dir;
+  struct grub_video_bitmap *raw_bitmap;
+  struct grub_video_bitmap *bitmap;
+};
+
+typedef struct grub_gui_image *grub_gui_image_t;
+
+static void
+image_destroy (void *vself)
+{
+  grub_gui_image_t self = vself;
+
+  /* Free the scaled bitmap, unless it's a reference to the raw bitmap.  */
+  if (self->bitmap && (self->bitmap != self->raw_bitmap))
+    grub_video_bitmap_destroy (self->bitmap);
+  if (self->raw_bitmap)
+    grub_video_bitmap_destroy (self->raw_bitmap);
+
+  grub_free (self);
+}
+
+static const char *
+image_get_id (void *vself)
+{
+  grub_gui_image_t self = vself;
+  return self->id;
+}
+
+static int
+image_is_instance (void *vself __attribute__((unused)), const char *type)
+{
+  return grub_strcmp (type, "component") == 0;
+}
+
+static void
+image_paint (void *vself, const grub_video_rect_t *region)
+{
+  grub_gui_image_t self = vself;
+  grub_video_rect_t vpsave;
+
+  if (! self->bitmap)
+    return;
+  if (!grub_video_have_common_points (region, &self->bounds))
+    return;
+
+  grub_gui_set_viewport (&self->bounds, &vpsave);
+  grub_video_blit_bitmap (self->bitmap, GRUB_VIDEO_BLIT_BLEND,
+                          0, 0, 0, 0,
+                          grub_video_bitmap_get_width (self->bitmap),
+                          grub_video_bitmap_get_height (self->bitmap));
+  grub_gui_restore_viewport (&vpsave);
+}
+
+static void
+image_set_parent (void *vself, grub_gui_container_t parent)
+{
+  grub_gui_image_t self = vself;
+  self->parent = parent;
+}
+
+static grub_gui_container_t
+image_get_parent (void *vself)
+{
+  grub_gui_image_t self = vself;
+  return self->parent;
+}
+
+static grub_err_t
+rescale_image (grub_gui_image_t self)
+{
+  if (! self->raw_bitmap)
+    {
+      if (self->bitmap)
+        {
+          grub_video_bitmap_destroy (self->bitmap);
+          self->bitmap = 0;
+        }
+      return grub_errno;
+    }
+
+  unsigned width = self->bounds.width;
+  unsigned height = self->bounds.height;
+
+  if (self->bitmap
+      && (grub_video_bitmap_get_width (self->bitmap) == width)
+      && (grub_video_bitmap_get_height (self->bitmap) == height))
+    {
+      /* Nothing to do; already the right size.  */
+      return grub_errno;
+    }
+
+  /* Free any old scaled bitmap,
+     *unless* it's a reference to the raw bitmap.  */
+  if (self->bitmap && (self->bitmap != self->raw_bitmap))
+    grub_video_bitmap_destroy (self->bitmap);
+
+  self->bitmap = 0;
+
+  /* Create a scaled bitmap, unless the requested size is the same
+     as the raw size -- in that case a reference is made.  */
+  if (grub_video_bitmap_get_width (self->raw_bitmap) == width
+      && grub_video_bitmap_get_height (self->raw_bitmap) == height)
+    {
+      self->bitmap = self->raw_bitmap;
+      return grub_errno;
+    }
+
+  /* Don't scale to an invalid size.  */
+  if (width == 0 || height == 0)
+    return grub_errno;
+
+  /* Create the scaled bitmap.  */
+  grub_video_bitmap_create_scaled (&self->bitmap,
+                                   width,
+                                   height,
+                                   self->raw_bitmap,
+                                   GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_error_push ();
+      grub_error (grub_errno, "failed to scale bitmap for image component");
+    }
+  return grub_errno;
+}
+
+static void
+image_set_bounds (void *vself, const grub_video_rect_t *bounds)
+{
+  grub_gui_image_t self = vself;
+  self->bounds = *bounds;
+  rescale_image (self);
+}
+
+static void
+image_get_bounds (void *vself, grub_video_rect_t *bounds)
+{
+  grub_gui_image_t self = vself;
+  *bounds = self->bounds;
+}
+
+/* FIXME: inform rendering system it's not forced minimum.  */
+static void
+image_get_minimal_size (void *vself, unsigned *width, unsigned *height)
+{
+  grub_gui_image_t self = vself;
+
+  if (self->raw_bitmap)
+    {
+      *width = grub_video_bitmap_get_width (self->raw_bitmap);
+      *height = grub_video_bitmap_get_height (self->raw_bitmap);
+    }
+  else
+    {
+      *width = 0;
+      *height = 0;
+    }
+}
+
+static grub_err_t
+load_image (grub_gui_image_t self, const char *path)
+{
+  struct grub_video_bitmap *bitmap;
+  if (grub_video_bitmap_load (&bitmap, path) != GRUB_ERR_NONE)
+    return grub_errno;
+
+  if (self->bitmap && (self->bitmap != self->raw_bitmap))
+    grub_video_bitmap_destroy (self->bitmap);
+  if (self->raw_bitmap)
+    grub_video_bitmap_destroy (self->raw_bitmap);
+
+  self->raw_bitmap = bitmap;
+  return rescale_image (self);
+}
+
+static grub_err_t
+image_set_property (void *vself, const char *name, const char *value)
+{
+  grub_gui_image_t self = vself;
+  if (grub_strcmp (name, "theme_dir") == 0)
+    {
+      grub_free (self->theme_dir);
+      self->theme_dir = grub_strdup (value);
+    }
+  else if (grub_strcmp (name, "file") == 0)
+    {
+      char *absvalue;
+      grub_err_t err;
+
+      /* Resolve to an absolute path.  */
+      if (! self->theme_dir)
+       return grub_error (GRUB_ERR_BAD_ARGUMENT, "unspecified theme_dir");
+      absvalue = grub_resolve_relative_path (self->theme_dir, value);
+      if (! absvalue)
+       return grub_errno;
+
+      err = load_image (self, absvalue);
+      grub_free (absvalue);
+
+      return err;
+    }
+  else if (grub_strcmp (name, "id") == 0)
+    {
+      grub_free (self->id);
+      if (value)
+        self->id = grub_strdup (value);
+      else
+        self->id = 0;
+    }
+  return grub_errno;
+}
+
+static struct grub_gui_component_ops image_ops =
+{
+  .destroy = image_destroy,
+  .get_id = image_get_id,
+  .is_instance = image_is_instance,
+  .paint = image_paint,
+  .set_parent = image_set_parent,
+  .get_parent = image_get_parent,
+  .set_bounds = image_set_bounds,
+  .get_bounds = image_get_bounds,
+  .get_minimal_size = image_get_minimal_size,
+  .set_property = image_set_property
+};
+
+grub_gui_component_t
+grub_gui_image_new (void)
+{
+  grub_gui_image_t image;
+  image = grub_zalloc (sizeof (*image));
+  if (! image)
+    return 0;
+  image->component.ops = &image_ops;
+  return (grub_gui_component_t) image;
+}
+
diff --git a/grub-core/gfxmenu/gui_label.c b/grub-core/gfxmenu/gui_label.c
new file mode 100644 (file)
index 0000000..a9dd575
--- /dev/null
@@ -0,0 +1,226 @@
+/* gui_label.c - GUI component to display a line of text.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/gui.h>
+#include <grub/font.h>
+#include <grub/gui_string_util.h>
+
+static const char *align_options[] =
+{
+  "left",
+  "center",
+  "right",
+  0
+};
+
+enum align_mode {
+  align_left,
+  align_center,
+  align_right
+};
+
+struct grub_gui_label
+{
+  struct grub_gui_component comp;
+
+  grub_gui_container_t parent;
+  grub_video_rect_t bounds;
+  char *id;
+  int visible;
+  char *text;
+  grub_font_t font;
+  grub_gui_color_t color;
+  enum align_mode align;
+};
+
+typedef struct grub_gui_label *grub_gui_label_t;
+
+static void
+label_destroy (void *vself)
+{
+  grub_gui_label_t self = vself;
+  grub_free (self->text);
+  grub_free (self);
+}
+
+static const char *
+label_get_id (void *vself)
+{
+  grub_gui_label_t self = vself;
+  return self->id;
+}
+
+static int
+label_is_instance (void *vself __attribute__((unused)), const char *type)
+{
+  return grub_strcmp (type, "component") == 0;
+}
+
+static void
+label_paint (void *vself, const grub_video_rect_t *region)
+{
+  grub_gui_label_t self = vself;
+
+  if (! self->visible)
+    return;
+
+  if (!grub_video_have_common_points (region, &self->bounds))
+    return;
+
+  /* Calculate the starting x coordinate.  */
+  int left_x;
+  if (self->align == align_left)
+    left_x = 0;
+  else if (self->align == align_center)
+    left_x = ((self->bounds.width
+               - grub_font_get_string_width (self->font, self->text))
+             ) / 2;
+  else if (self->align == align_right)
+    left_x = (self->bounds.width
+              - grub_font_get_string_width (self->font, self->text));
+  else
+    return;   /* Invalid alignment.  */
+
+  grub_video_rect_t vpsave;
+  grub_gui_set_viewport (&self->bounds, &vpsave);
+  grub_font_draw_string (self->text,
+                         self->font,
+                         grub_gui_map_color (self->color),
+                         left_x,
+                         grub_font_get_ascent (self->font));
+  grub_gui_restore_viewport (&vpsave);
+}
+
+static void
+label_set_parent (void *vself, grub_gui_container_t parent)
+{
+  grub_gui_label_t self = vself;
+  self->parent = parent;
+}
+
+static grub_gui_container_t
+label_get_parent (void *vself)
+{
+  grub_gui_label_t self = vself;
+  return self->parent;
+}
+
+static void
+label_set_bounds (void *vself, const grub_video_rect_t *bounds)
+{
+  grub_gui_label_t self = vself;
+  self->bounds = *bounds;
+}
+
+static void
+label_get_bounds (void *vself, grub_video_rect_t *bounds)
+{
+  grub_gui_label_t self = vself;
+  *bounds = self->bounds;
+}
+
+static void
+label_get_minimal_size (void *vself, unsigned *width, unsigned *height)
+{
+  grub_gui_label_t self = vself;
+  *width = grub_font_get_string_width (self->font, self->text);
+  *height = (grub_font_get_ascent (self->font)
+             + grub_font_get_descent (self->font));
+}
+
+static grub_err_t
+label_set_property (void *vself, const char *name, const char *value)
+{
+  grub_gui_label_t self = vself;
+  if (grub_strcmp (name, "text") == 0)
+    {
+      grub_free (self->text);
+      if (! value)
+        value = "";
+      self->text = grub_strdup (value);
+    }
+  else if (grub_strcmp (name, "font") == 0)
+    {
+      self->font = grub_font_get (value);
+    }
+  else if (grub_strcmp (name, "color") == 0)
+    {
+      grub_gui_parse_color (value, &self->color);
+    }
+  else if (grub_strcmp (name, "align") == 0)
+    {
+      int i;
+      for (i = 0; align_options[i]; i++)
+        {
+          if (grub_strcmp (align_options[i], value) == 0)
+            {
+              self->align = i;   /* Set the alignment mode.  */
+              break;
+            }
+        }
+    }
+  else if (grub_strcmp (name, "visible") == 0)
+    {
+      self->visible = grub_strcmp (value, "false") != 0;
+    }
+  else if (grub_strcmp (name, "id") == 0)
+    {
+      grub_free (self->id);
+      if (value)
+        self->id = grub_strdup (value);
+      else
+        self->id = 0;
+    }
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_gui_component_ops label_ops =
+{
+  .destroy = label_destroy,
+  .get_id = label_get_id,
+  .is_instance = label_is_instance,
+  .paint = label_paint,
+  .set_parent = label_set_parent,
+  .get_parent = label_get_parent,
+  .set_bounds = label_set_bounds,
+  .get_bounds = label_get_bounds,
+  .get_minimal_size = label_get_minimal_size,
+  .set_property = label_set_property
+};
+
+grub_gui_component_t
+grub_gui_label_new (void)
+{
+  grub_gui_label_t label;
+  label = grub_zalloc (sizeof (*label));
+  if (! label)
+    return 0;
+  label->comp.ops = &label_ops;
+  label->visible = 1;
+  label->text = grub_strdup ("");
+  label->font = grub_font_get ("Unknown Regular 16");
+  label->color.red = 0;
+  label->color.green = 0;
+  label->color.blue = 0;
+  label->color.alpha = 255;
+  label->align = align_left;
+  return (grub_gui_component_t) label;
+}
diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c
new file mode 100644 (file)
index 0000000..0d77141
--- /dev/null
@@ -0,0 +1,612 @@
+/* gui_list.c - GUI component to display a selectable list of items.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/gui.h>
+#include <grub/gui_string_util.h>
+#include <grub/gfxmenu_view.h>
+#include <grub/gfxwidgets.h>
+
+struct grub_gui_list_impl
+{
+  struct grub_gui_list list;
+
+  grub_gui_container_t parent;
+  grub_video_rect_t bounds;
+  char *id;
+  int visible;
+
+  int icon_width;
+  int icon_height;
+  int item_height;
+  int item_padding;
+  int item_icon_space;
+  int item_spacing;
+  grub_font_t item_font;
+  grub_font_t selected_item_font;
+  grub_gui_color_t item_color;
+  int selected_item_color_set;
+  grub_gui_color_t selected_item_color;
+
+  int draw_scrollbar;
+  int need_to_recreate_scrollbar;
+  char *scrollbar_frame_pattern;
+  char *scrollbar_thumb_pattern;
+  grub_gfxmenu_box_t scrollbar_frame;
+  grub_gfxmenu_box_t scrollbar_thumb;
+  int scrollbar_width;
+
+  int first_shown_index;
+
+  int need_to_recreate_boxes;
+  char *theme_dir;
+  char *menu_box_pattern;
+  char *selected_item_box_pattern;
+  grub_gfxmenu_box_t menu_box;
+  grub_gfxmenu_box_t selected_item_box;
+
+  grub_gfxmenu_icon_manager_t icon_manager;
+
+  grub_gfxmenu_view_t view;
+};
+
+typedef struct grub_gui_list_impl *list_impl_t;
+
+static void
+list_destroy (void *vself)
+{
+  list_impl_t self = vself;
+
+  grub_free (self->theme_dir);
+  grub_free (self->menu_box_pattern);
+  grub_free (self->selected_item_box_pattern);
+  if (self->menu_box)
+    self->menu_box->destroy (self->menu_box);
+  if (self->selected_item_box)
+    self->selected_item_box->destroy (self->selected_item_box);
+  if (self->icon_manager)
+    grub_gfxmenu_icon_manager_destroy (self->icon_manager);
+
+  grub_free (self);
+}
+
+static int
+get_num_shown_items (list_impl_t self)
+{
+  int boxpad = self->item_padding;
+  int item_vspace = self->item_spacing;
+  int item_height = self->item_height;
+  
+  grub_gfxmenu_box_t box = self->menu_box;
+  int box_top_pad = box->get_top_pad (box);
+  int box_bottom_pad = box->get_bottom_pad (box);
+      
+  return (self->bounds.height + item_vspace - 2 * boxpad
+         - box_top_pad - box_bottom_pad) / (item_height + item_vspace);
+}
+
+static int
+check_boxes (list_impl_t self)
+{
+  if (self->need_to_recreate_boxes)
+    {
+      grub_gui_recreate_box (&self->menu_box,
+                             self->menu_box_pattern,
+                             self->theme_dir);
+
+      grub_gui_recreate_box (&self->selected_item_box,
+                             self->selected_item_box_pattern,
+                             self->theme_dir);
+
+      self->need_to_recreate_boxes = 0;
+    }
+
+  return (self->menu_box != 0 && self->selected_item_box != 0);
+}
+
+static int
+check_scrollbar (list_impl_t self)
+{
+  if (self->need_to_recreate_scrollbar)
+    {
+      grub_gui_recreate_box (&self->scrollbar_frame,
+                             self->scrollbar_frame_pattern,
+                             self->theme_dir);
+
+      grub_gui_recreate_box (&self->scrollbar_thumb,
+                             self->scrollbar_thumb_pattern,
+                             self->theme_dir);
+
+      self->need_to_recreate_scrollbar = 0;
+    }
+
+  return (self->scrollbar_frame != 0 && self->scrollbar_thumb != 0);
+}
+
+static const char *
+list_get_id (void *vself)
+{
+  list_impl_t self = vself;
+  return self->id;
+}
+
+static int
+list_is_instance (void *vself __attribute__((unused)), const char *type)
+{
+  return (grub_strcmp (type, "component") == 0
+          || grub_strcmp (type, "list") == 0);
+}
+
+static struct grub_video_bitmap *
+get_item_icon (list_impl_t self, int item_index)
+{
+  grub_menu_entry_t entry;
+  entry = grub_menu_get_entry (self->view->menu, item_index);
+  if (! entry)
+    return 0;
+
+  return grub_gfxmenu_icon_manager_get_icon (self->icon_manager, entry);
+}
+
+static void
+make_selected_item_visible (list_impl_t self)
+{
+  int selected_index = self->view->selected;
+  if (selected_index < 0)
+    return;   /* No item is selected.  */
+  int num_shown_items = get_num_shown_items (self);
+  int last_shown_index = self->first_shown_index + (num_shown_items - 1);
+  if (selected_index < self->first_shown_index)
+    self->first_shown_index = selected_index;
+  else if (selected_index > last_shown_index)
+    self->first_shown_index = selected_index - (num_shown_items - 1);
+}
+
+/* Draw a scrollbar on the menu.  */
+static void
+draw_scrollbar (list_impl_t self,
+                int value, int extent, int min, int max,
+                int rightx, int topy, int height)
+{
+  grub_gfxmenu_box_t frame = self->scrollbar_frame;
+  grub_gfxmenu_box_t thumb = self->scrollbar_thumb;
+  int frame_vertical_pad = (frame->get_top_pad (frame)
+                            + frame->get_bottom_pad (frame));
+  int frame_horizontal_pad = (frame->get_left_pad (frame)
+                              + frame->get_right_pad (frame));
+  int tracktop = topy + frame->get_top_pad (frame);
+  int tracklen = height - frame_vertical_pad;
+  frame->set_content_size (frame, self->scrollbar_width, tracklen);
+  int thumby = tracktop + tracklen * (value - min) / (max - min);
+  int thumbheight = tracklen * extent / (max - min) + 1;
+  thumb->set_content_size (thumb,
+                           self->scrollbar_width - frame_horizontal_pad,
+                           thumbheight - (thumb->get_top_pad (thumb)
+                                          + thumb->get_bottom_pad (thumb)));
+  frame->draw (frame,
+               rightx - (self->scrollbar_width + frame_horizontal_pad),
+               topy);
+  thumb->draw (thumb,
+               rightx - (self->scrollbar_width - frame->get_right_pad (frame)),
+               thumby);
+}
+
+/* Draw the list of items.  */
+static void
+draw_menu (list_impl_t self, int width, int drawing_scrollbar,
+          int num_shown_items)
+{
+  if (! self->menu_box || ! self->selected_item_box)
+    return;
+
+  int boxpad = self->item_padding;
+  int icon_text_space = self->item_icon_space;
+  int item_vspace = self->item_spacing;
+
+  int ascent = grub_font_get_ascent (self->item_font);
+  int descent = grub_font_get_descent (self->item_font);
+  int item_height = self->item_height;
+
+  make_selected_item_visible (self);
+
+  int scrollbar_h_space = drawing_scrollbar ? self->scrollbar_width : 0;
+
+  grub_gfxmenu_box_t selbox = self->selected_item_box;
+  int sel_leftpad = selbox->get_left_pad (selbox);
+  int item_top = boxpad;
+  int item_left = boxpad + sel_leftpad;
+  int menu_index;
+  int visible_index;
+
+  for (visible_index = 0, menu_index = self->first_shown_index;
+       visible_index < num_shown_items && menu_index < self->view->menu->size;
+       visible_index++, menu_index++)
+    {
+      int is_selected = (menu_index == self->view->selected);
+
+      if (is_selected)
+        {
+          int sel_toppad = selbox->get_top_pad (selbox);
+          selbox->set_content_size (selbox,
+                                    (width - 2 * boxpad
+                                     - scrollbar_h_space),
+                                    item_height);
+          selbox->draw (selbox,
+                        item_left - sel_leftpad,
+                        item_top - sel_toppad);
+        }
+
+      struct grub_video_bitmap *icon;
+      if ((icon = get_item_icon (self, menu_index)) != 0)
+        grub_video_blit_bitmap (icon, GRUB_VIDEO_BLIT_BLEND,
+                                item_left,
+                                item_top + (item_height - self->icon_height) / 2,
+                                0, 0, self->icon_width, self->icon_height);
+
+      const char *item_title =
+        grub_menu_get_entry (self->view->menu, menu_index)->title;
+      grub_font_t font =
+        (is_selected && self->selected_item_font
+         ? self->selected_item_font
+         : self->item_font);
+      grub_gui_color_t text_color =
+        ((is_selected && self->selected_item_color_set)
+         ? self->selected_item_color
+         : self->item_color);
+      grub_font_draw_string (item_title,
+                             font,
+                             grub_gui_map_color (text_color),
+                             item_left + self->icon_width + icon_text_space,
+                             (item_top + (item_height - (ascent + descent))
+                              / 2 + ascent));
+
+      item_top += item_height + item_vspace;
+    }
+}
+
+static void
+list_paint (void *vself, const grub_video_rect_t *region)
+{
+  list_impl_t self = vself;
+  grub_video_rect_t vpsave;
+
+  if (! self->visible)
+    return;
+  if (!grub_video_have_common_points (region, &self->bounds))
+    return;
+
+  check_boxes (self);
+
+  if (! self->menu_box || ! self->selected_item_box)
+    return;
+
+  grub_gui_set_viewport (&self->bounds, &vpsave);
+  {
+    grub_gfxmenu_box_t box = self->menu_box;
+    int box_left_pad = box->get_left_pad (box);
+    int box_top_pad = box->get_top_pad (box);
+    int box_right_pad = box->get_right_pad (box);
+    int box_bottom_pad = box->get_bottom_pad (box);
+    grub_video_rect_t vpsave2, content_rect;
+    int num_shown_items = get_num_shown_items (self);
+    int drawing_scrollbar = (self->draw_scrollbar
+                            && (num_shown_items < self->view->menu->size)
+                            && check_scrollbar (self));
+
+    content_rect.x = box_left_pad;
+    content_rect.y = box_top_pad;
+    content_rect.width = self->bounds.width - box_left_pad - box_right_pad;
+    content_rect.height = self->bounds.height - box_top_pad - box_bottom_pad;
+
+    box->set_content_size (box, content_rect.width, content_rect.height);
+
+    box->draw (box, 0, 0);
+
+    grub_gui_set_viewport (&content_rect, &vpsave2);
+    draw_menu (self, content_rect.width, drawing_scrollbar, num_shown_items);
+    grub_gui_restore_viewport (&vpsave2);
+
+    if (drawing_scrollbar)
+      draw_scrollbar (self,
+                     self->first_shown_index, num_shown_items,
+                     0, self->view->menu->size,
+                     self->bounds.width - box_right_pad
+                     + self->scrollbar_width,
+                     box_top_pad + self->item_padding,
+                     self->bounds.height - box_top_pad - box_bottom_pad);
+  }
+
+  grub_gui_restore_viewport (&vpsave);
+}
+
+static void
+list_set_parent (void *vself, grub_gui_container_t parent)
+{
+  list_impl_t self = vself;
+  self->parent = parent;
+}
+
+static grub_gui_container_t
+list_get_parent (void *vself)
+{
+  list_impl_t self = vself;
+  return self->parent;
+}
+
+static void
+list_set_bounds (void *vself, const grub_video_rect_t *bounds)
+{
+  list_impl_t self = vself;
+  self->bounds = *bounds;
+}
+
+static void
+list_get_bounds (void *vself, grub_video_rect_t *bounds)
+{
+  list_impl_t self = vself;
+  *bounds = self->bounds;
+}
+
+static void
+list_get_minimal_size (void *vself, unsigned *width, unsigned *height)
+{
+  list_impl_t self = vself;
+
+  if (check_boxes (self))
+    {
+      int boxpad = self->item_padding;
+      int item_vspace = self->item_spacing;
+      int item_height = self->item_height;
+      int num_items = 3;
+
+      grub_gfxmenu_box_t box = self->menu_box;
+      int box_left_pad = box->get_left_pad (box);
+      int box_top_pad = box->get_top_pad (box);
+      int box_right_pad = box->get_right_pad (box);
+      int box_bottom_pad = box->get_bottom_pad (box);
+      unsigned width_s;
+      
+      *width = grub_font_get_string_width (self->item_font, "Typical OS");
+      width_s = grub_font_get_string_width (self->selected_item_font,
+                                           "Typical OS");
+      if (*width < width_s)
+       *width = width_s;
+
+      *width += 2 * boxpad + box_left_pad + box_right_pad;
+
+      /* Set the menu box height to fit the items.  */
+      *height = (item_height * num_items
+                 + item_vspace * (num_items - 1)
+                 + 2 * boxpad
+                 + box_top_pad + box_bottom_pad);
+    }
+  else
+    {
+      *width = 0;
+      *height = 0;
+    }
+}
+
+static grub_err_t
+list_set_property (void *vself, const char *name, const char *value)
+{
+  list_impl_t self = vself;
+  if (grub_strcmp (name, "item_font") == 0)
+    {
+      self->item_font = grub_font_get (value);
+    }
+  else if (grub_strcmp (name, "selected_item_font") == 0)
+    {
+      if (! value || grub_strcmp (value, "inherit") == 0)
+        self->selected_item_font = 0;
+      else
+        self->selected_item_font = grub_font_get (value);
+    }
+  else if (grub_strcmp (name, "item_color") == 0)
+    {
+      grub_gui_parse_color (value, &self->item_color);
+    }
+  else if (grub_strcmp (name, "selected_item_color") == 0)
+    {
+      if (! value || grub_strcmp (value, "inherit") == 0)
+        {
+          self->selected_item_color_set = 0;
+        }
+      else
+        {
+          if (grub_gui_parse_color (value, &self->selected_item_color)
+              == GRUB_ERR_NONE)
+            self->selected_item_color_set = 1;
+        }
+    }
+  else if (grub_strcmp (name, "icon_width") == 0)
+    {
+      self->icon_width = grub_strtol (value, 0, 10);
+      grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager,
+                                               self->icon_width,
+                                               self->icon_height);
+    }
+  else if (grub_strcmp (name, "icon_height") == 0)
+    {
+      self->icon_height = grub_strtol (value, 0, 10);
+      grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager,
+                                               self->icon_width,
+                                               self->icon_height);
+    }
+  else if (grub_strcmp (name, "item_height") == 0)
+    {
+      self->item_height = grub_strtol (value, 0, 10);
+    }
+  else if (grub_strcmp (name, "item_padding") == 0)
+    {
+      self->item_padding = grub_strtol (value, 0, 10);
+    }
+  else if (grub_strcmp (name, "item_icon_space") == 0)
+    {
+      self->item_icon_space = grub_strtol (value, 0, 10);
+    }
+  else if (grub_strcmp (name, "item_spacing") == 0)
+    {
+      self->item_spacing = grub_strtol (value, 0, 10);
+    }
+  else if (grub_strcmp (name, "visible") == 0)
+    {
+      self->visible = grub_strcmp (value, "false") != 0;
+    }
+  else if (grub_strcmp (name, "menu_pixmap_style") == 0)
+    {
+      self->need_to_recreate_boxes = 1;
+      grub_free (self->menu_box_pattern);
+      self->menu_box_pattern = value ? grub_strdup (value) : 0;
+    }
+  else if (grub_strcmp (name, "selected_item_pixmap_style") == 0)
+    {
+      self->need_to_recreate_boxes = 1;
+      grub_free (self->selected_item_box_pattern);
+      self->selected_item_box_pattern = value ? grub_strdup (value) : 0;
+    }
+  else if (grub_strcmp (name, "scrollbar_frame") == 0)
+    {
+      self->need_to_recreate_scrollbar = 1;
+      grub_free (self->scrollbar_frame_pattern);
+      self->scrollbar_frame_pattern = value ? grub_strdup (value) : 0;
+    }
+  else if (grub_strcmp (name, "scrollbar_thumb") == 0)
+    {
+      self->need_to_recreate_scrollbar = 1;
+      grub_free (self->scrollbar_thumb_pattern);
+      self->scrollbar_thumb_pattern = value ? grub_strdup (value) : 0;
+    }
+  else if (grub_strcmp (name, "scrollbar_width") == 0)
+    {
+      self->scrollbar_width = grub_strtol (value, 0, 10);
+    }
+  else if (grub_strcmp (name, "scrollbar") == 0)
+    {
+      self->draw_scrollbar = grub_strcmp (value, "false") != 0;
+    }
+  else if (grub_strcmp (name, "theme_dir") == 0)
+    {
+      self->need_to_recreate_boxes = 1;
+      grub_free (self->theme_dir);
+      self->theme_dir = value ? grub_strdup (value) : 0;
+    }
+  else if (grub_strcmp (name, "id") == 0)
+    {
+      grub_free (self->id);
+      if (value)
+        self->id = grub_strdup (value);
+      else
+        self->id = 0;
+    }
+  return grub_errno;
+}
+
+/* Set necessary information that the gfxmenu view provides.  */
+static void
+list_set_view_info (void *vself,
+                    grub_gfxmenu_view_t view)
+{
+  list_impl_t self = vself;
+  grub_gfxmenu_icon_manager_set_theme_path (self->icon_manager,
+                                           view->theme_path);
+  self->view = view;
+}
+
+static struct grub_gui_component_ops list_comp_ops =
+  {
+    .destroy = list_destroy,
+    .get_id = list_get_id,
+    .is_instance = list_is_instance,
+    .paint = list_paint,
+    .set_parent = list_set_parent,
+    .get_parent = list_get_parent,
+    .set_bounds = list_set_bounds,
+    .get_bounds = list_get_bounds,
+    .get_minimal_size = list_get_minimal_size,
+    .set_property = list_set_property
+  };
+
+static struct grub_gui_list_ops list_ops =
+{
+  .set_view_info = list_set_view_info
+};
+
+grub_gui_component_t
+grub_gui_list_new (void)
+{
+  list_impl_t self;
+  grub_font_t default_font;
+  grub_gui_color_t default_fg_color;
+  grub_gui_color_t default_bg_color;
+
+  self = grub_zalloc (sizeof (*self));
+  if (! self)
+    return 0;
+
+  self->list.ops = &list_ops;
+  self->list.component.ops = &list_comp_ops;
+
+  self->visible = 1;
+
+  default_font = grub_font_get ("Unknown Regular 16");
+  default_fg_color = grub_gui_color_rgb (0, 0, 0);
+  default_bg_color = grub_gui_color_rgb (255, 255, 255);
+
+  self->icon_width = 32;
+  self->icon_height = 32;
+  self->item_height = 42;
+  self->item_padding = 14;
+  self->item_icon_space = 4;
+  self->item_spacing = 16;
+  self->item_font = default_font;
+  self->selected_item_font = 0;    /* Default to using the item_font.  */
+  self->item_color = default_fg_color;
+  self->selected_item_color_set = 0;  /* Default to using the item_color.  */
+  self->selected_item_color = default_fg_color;
+
+  self->draw_scrollbar = 1;
+  self->need_to_recreate_scrollbar = 1;
+  self->scrollbar_frame = 0;
+  self->scrollbar_thumb = 0;
+  self->scrollbar_frame_pattern = 0;
+  self->scrollbar_thumb_pattern = 0;
+  self->scrollbar_width = 16;
+
+  self->first_shown_index = 0;
+
+  self->need_to_recreate_boxes = 0;
+  self->theme_dir = 0;
+  self->menu_box_pattern = 0;
+  self->selected_item_box_pattern = 0;
+  self->menu_box = grub_gfxmenu_create_box (0, 0);
+  self->selected_item_box = grub_gfxmenu_create_box (0, 0);
+
+  self->icon_manager = grub_gfxmenu_icon_manager_new ();
+  if (! self->icon_manager)
+    {
+      self->list.component.ops->destroy (self);
+      return 0;
+    }
+  grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager,
+                                           self->icon_width,
+                                           self->icon_height);
+  return (grub_gui_component_t) self;
+}
diff --git a/grub-core/gfxmenu/gui_progress_bar.c b/grub-core/gfxmenu/gui_progress_bar.c
new file mode 100644 (file)
index 0000000..d786aae
--- /dev/null
@@ -0,0 +1,384 @@
+/* gui_progress_bar.c - GUI progress bar component.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/gui.h>
+#include <grub/font.h>
+#include <grub/gui_string_util.h>
+#include <grub/gfxmenu_view.h>
+#include <grub/gfxwidgets.h>
+#include <grub/i18n.h>
+
+struct grub_gui_progress_bar
+{
+  struct grub_gui_progress progress;
+
+  grub_gui_container_t parent;
+  grub_video_rect_t bounds;
+  char *id;
+  int visible;
+  int start;
+  int end;
+  int value;
+  int show_text;
+  char *template;
+  grub_font_t font;
+  grub_gui_color_t text_color;
+  grub_gui_color_t border_color;
+  grub_gui_color_t bg_color;
+  grub_gui_color_t fg_color;
+
+  char *theme_dir;
+  int need_to_recreate_pixmaps;
+  int pixmapbar_available;
+  char *bar_pattern;
+  char *highlight_pattern;
+  grub_gfxmenu_box_t bar_box;
+  grub_gfxmenu_box_t highlight_box;
+};
+
+typedef struct grub_gui_progress_bar *grub_gui_progress_bar_t;
+
+static void
+progress_bar_destroy (void *vself)
+{
+  grub_gui_progress_bar_t self = vself;
+  grub_free (self);
+}
+
+static const char *
+progress_bar_get_id (void *vself)
+{
+  grub_gui_progress_bar_t self = vself;
+  return self->id;
+}
+
+static int
+progress_bar_is_instance (void *vself __attribute__((unused)), const char *type)
+{
+  return grub_strcmp (type, "component") == 0;
+}
+
+static int
+check_pixmaps (grub_gui_progress_bar_t self)
+{
+  if (!self->pixmapbar_available)
+    return 0;
+  if (self->need_to_recreate_pixmaps)
+    {
+      grub_gui_recreate_box (&self->bar_box,
+                             self->bar_pattern,
+                             self->theme_dir);
+
+      grub_gui_recreate_box (&self->highlight_box,
+                             self->highlight_pattern,
+                             self->theme_dir);
+
+      self->need_to_recreate_pixmaps = 0;
+    }
+
+  return (self->bar_box != 0 && self->highlight_box != 0);
+}
+
+static void
+draw_filled_rect_bar (grub_gui_progress_bar_t self)
+{
+  /* Set the progress bar's frame.  */
+  grub_video_rect_t f;
+  f.x = 1;
+  f.y = 1;
+  f.width = self->bounds.width - 2;
+  f.height = self->bounds.height - 2;
+
+  /* Border.  */
+  grub_video_fill_rect (grub_gui_map_color (self->border_color),
+                        f.x - 1, f.y - 1,
+                        f.width + 2, f.height + 2);
+
+  /* Bar background.  */
+  int barwidth = (f.width
+                  * (self->value - self->start)
+                  / (self->end - self->start));
+  grub_video_fill_rect (grub_gui_map_color (self->bg_color),
+                        f.x + barwidth, f.y,
+                        f.width - barwidth, f.height);
+
+  /* Bar foreground.  */
+  grub_video_fill_rect (grub_gui_map_color (self->fg_color),
+                        f.x, f.y,
+                        barwidth, f.height);
+}
+
+static void
+draw_pixmap_bar (grub_gui_progress_bar_t self)
+{
+  grub_gfxmenu_box_t bar = self->bar_box;
+  grub_gfxmenu_box_t hl = self->highlight_box;
+  int w = self->bounds.width;
+  int h = self->bounds.height;
+  int bar_l_pad = bar->get_left_pad (bar);
+  int bar_r_pad = bar->get_right_pad (bar);
+  int bar_t_pad = bar->get_top_pad (bar);
+  int bar_b_pad = bar->get_bottom_pad (bar);
+  int bar_h_pad = bar_l_pad + bar_r_pad;
+  int bar_v_pad = bar_t_pad + bar_b_pad;
+  int tracklen = w - bar_h_pad;
+  int trackheight = h - bar_v_pad;
+  int barwidth;
+
+  bar->set_content_size (bar, tracklen, trackheight);
+
+  barwidth = (tracklen * (self->value - self->start) 
+             / (self->end - self->start));
+
+  hl->set_content_size (hl, barwidth, h - bar_v_pad);
+
+  bar->draw (bar, 0, 0);
+  hl->draw (hl, bar_l_pad, bar_t_pad);
+}
+
+static void
+draw_text (grub_gui_progress_bar_t self)
+{
+  if (self->template)
+    {
+      grub_font_t font = self->font;
+      grub_video_color_t text_color = grub_gui_map_color (self->text_color);
+      int width = self->bounds.width;
+      int height = self->bounds.height;
+      char *text;
+      text = grub_xasprintf (self->template,
+                            self->value > 0 ? self->value : -self->value);
+      if (!text)
+       {
+         grub_print_error ();
+         grub_errno = GRUB_ERR_NONE;
+         return;
+       }
+      /* Center the text. */
+      int text_width = grub_font_get_string_width (font, text);
+      int x = (width - text_width) / 2;
+      int y = ((height - grub_font_get_descent (font)) / 2
+               + grub_font_get_ascent (font) / 2);
+      grub_font_draw_string (text, font, text_color, x, y);
+    }
+}
+
+static void
+progress_bar_paint (void *vself, const grub_video_rect_t *region)
+{
+  grub_gui_progress_bar_t self = vself;
+  grub_video_rect_t vpsave;
+
+  if (! self->visible)
+    return;
+  if (!grub_video_have_common_points (region, &self->bounds))
+    return;
+
+  if (self->end == self->start)
+    return;
+
+  grub_gui_set_viewport (&self->bounds, &vpsave);
+
+  if (check_pixmaps (self))
+    draw_pixmap_bar (self);
+  else
+    draw_filled_rect_bar (self);
+
+  draw_text (self);
+
+  grub_gui_restore_viewport (&vpsave);
+}
+
+static void
+progress_bar_set_parent (void *vself, grub_gui_container_t parent)
+{
+  grub_gui_progress_bar_t self = vself;
+  self->parent = parent;
+}
+
+static grub_gui_container_t
+progress_bar_get_parent (void *vself)
+{
+  grub_gui_progress_bar_t self = vself;
+  return self->parent;
+}
+
+static void
+progress_bar_set_bounds (void *vself, const grub_video_rect_t *bounds)
+{
+  grub_gui_progress_bar_t self = vself;
+  self->bounds = *bounds;
+}
+
+static void
+progress_bar_get_bounds (void *vself, grub_video_rect_t *bounds)
+{
+  grub_gui_progress_bar_t self = vself;
+  *bounds = self->bounds;
+}
+
+static void
+progress_bar_get_minimal_size (void *vself,
+                              unsigned *width, unsigned *height)
+{
+  unsigned text_width = 0, text_height = 0;
+  grub_gui_progress_bar_t self = vself;
+
+  if (self->template)
+    {
+      text_width = grub_font_get_string_width (self->font, self->template);
+      text_width += grub_font_get_string_width (self->font, "XXXXXXXXXX");
+      text_height = grub_font_get_descent (self->font)
+       + grub_font_get_ascent (self->font);
+    }
+  *width = 200;
+  if (*width < text_width)
+    *width = text_width;
+  *height = 28;
+  if (*height < text_height)
+    *height = text_height;
+}
+
+static void
+progress_bar_set_state (void *vself, int visible, int start,
+                       int current, int end)
+{
+  grub_gui_progress_bar_t self = vself;  
+  self->visible = visible;
+  self->start = start;
+  self->value = current;
+  self->end = end;
+}
+
+static grub_err_t
+progress_bar_set_property (void *vself, const char *name, const char *value)
+{
+  grub_gui_progress_bar_t self = vself;
+  if (grub_strcmp (name, "text") == 0)
+    {
+      grub_free (self->template);
+      if (grub_strcmp (value, "@TIMEOUT_NOTIFICATION_LONG@") == 0)
+       value 
+         = _("The highlighted entry will be executed automatically in %ds.");
+      else if (grub_strcmp (value, "@TIMEOUT_NOTIFICATION_MIDDLE@") == 0)
+       /* TRANSLATORS:  's' stands for seconds.
+          It's a standalone timeout notification.
+          Please use the short form in your language.  */
+       value = _("%ds remaining.");
+      else if (grub_strcmp (value, "@TIMEOUT_NOTIFICATION_SHORT@") == 0)
+       /* TRANSLATORS:  's' stands for seconds.
+          It's a standalone timeout notification.
+          Please use the shortest form available in you language.  */
+       value = _("%ds");
+
+      self->template = grub_strdup (value);
+    }
+  else if (grub_strcmp (name, "font") == 0)
+    {
+      self->font = grub_font_get (value);
+    }
+  else if (grub_strcmp (name, "text_color") == 0)
+    {
+      grub_gui_parse_color (value, &self->text_color);
+    }
+  else if (grub_strcmp (name, "border_color") == 0)
+    {
+       grub_gui_parse_color (value, &self->border_color);
+    }
+  else if (grub_strcmp (name, "bg_color") == 0)
+    {
+       grub_gui_parse_color (value, &self->bg_color);
+    }
+  else if (grub_strcmp (name, "fg_color") == 0)
+    {
+      grub_gui_parse_color (value, &self->fg_color);
+    }
+  else if (grub_strcmp (name, "bar_style") == 0)
+    {
+      self->need_to_recreate_pixmaps = 1;
+      self->pixmapbar_available = 1;
+      grub_free (self->bar_pattern);
+      self->bar_pattern = value ? grub_strdup (value) : 0;
+    }
+  else if (grub_strcmp (name, "highlight_style") == 0)
+    {
+      self->need_to_recreate_pixmaps = 1;
+      self->pixmapbar_available = 1;
+      grub_free (self->highlight_pattern);
+      self->highlight_pattern = value ? grub_strdup (value) : 0;
+    }
+  else if (grub_strcmp (name, "theme_dir") == 0)
+    {
+      self->need_to_recreate_pixmaps = 1;
+      grub_free (self->theme_dir);
+      self->theme_dir = value ? grub_strdup (value) : 0;
+    }
+  else if (grub_strcmp (name, "id") == 0)
+    {
+      grub_free (self->id);
+      if (value)
+        self->id = grub_strdup (value);
+      else
+        self->id = 0;
+    }
+  return grub_errno;
+}
+
+static struct grub_gui_component_ops progress_bar_ops =
+{
+  .destroy = progress_bar_destroy,
+  .get_id = progress_bar_get_id,
+  .is_instance = progress_bar_is_instance,
+  .paint = progress_bar_paint,
+  .set_parent = progress_bar_set_parent,
+  .get_parent = progress_bar_get_parent,
+  .set_bounds = progress_bar_set_bounds,
+  .get_bounds = progress_bar_get_bounds,
+  .get_minimal_size = progress_bar_get_minimal_size,
+  .set_property = progress_bar_set_property
+};
+
+static struct grub_gui_progress_ops progress_bar_pb_ops =
+  {
+    .set_state = progress_bar_set_state
+  };
+
+grub_gui_component_t
+grub_gui_progress_bar_new (void)
+{
+  grub_gui_progress_bar_t self;
+  self = grub_zalloc (sizeof (*self));
+  if (! self)
+    return 0;
+  self->progress.ops = &progress_bar_pb_ops;
+  self->progress.component.ops = &progress_bar_ops;
+  self->visible = 1;
+  self->font = grub_font_get ("Unknown Regular 16");
+  grub_gui_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 };
+  grub_gui_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 };
+  grub_gui_color_t lightgray = { .red = 200, .green = 200, .blue = 200, .alpha = 255 };
+  self->text_color = black;
+  self->border_color = black;
+  self->bg_color = gray;
+  self->fg_color = lightgray;
+
+  return (grub_gui_component_t) self;
+}
diff --git a/grub-core/gfxmenu/gui_string_util.c b/grub-core/gfxmenu/gui_string_util.c
new file mode 100644 (file)
index 0000000..8c51e39
--- /dev/null
@@ -0,0 +1,327 @@
+/* gui_string_util.c - String utilities used by the GUI system.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/gui_string_util.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+/* Create a new NUL-terminated string on the heap as a substring of BUF.
+   The range of buf included is the half-open interval [START,END).
+   The index START is inclusive, END is exclusive.  */
+char *
+grub_new_substring (const char *buf,
+                    grub_size_t start, grub_size_t end)
+{
+  if (end < start)
+    return 0;
+  grub_size_t len = end - start;
+  char *s = grub_malloc (len + 1);
+  if (! s)
+    return 0;
+  grub_memcpy (s, buf + start, len);
+  s[len] = '\0';
+  return s;
+}
+
+/* Eliminate "." and ".." path elements from PATH.  A new heap-allocated
+   string is returned.  */
+static char *
+canonicalize_path (const char *path)
+{
+  int i;
+  const char *p;
+  char *newpath = 0;
+
+  /* Count the path components in path.  */
+  int components = 1;
+  for (p = path; *p; p++)
+    if (*p == '/')
+      components++;
+
+  char **path_array = grub_malloc (components * sizeof (*path_array));
+  if (! path_array)
+    return 0;
+
+  /* Initialize array elements to NULL pointers; in case once of the
+     allocations fails, the cleanup code can just call grub_free() for all
+     pointers in the array.  */
+  for (i = 0; i < components; i++)
+    path_array[i] = 0;
+
+  /* Parse the path into path_array.  */
+  p = path;
+  for (i = 0; i < components && p; i++)
+    {
+      /* Find the end of the path element.  */
+      const char *end = grub_strchr (p, '/');
+      if (!end)
+        end = p + grub_strlen (p);
+
+      /* Copy the element.  */
+      path_array[i] = grub_new_substring (p, 0, end - p);
+      if (! path_array[i])
+        goto cleanup;
+
+      /* Advance p to point to the start of the next element, or NULL.  */
+      if (*end)
+        p = end + 1;
+      else
+        p = 0;
+    }
+
+  /* Eliminate '.' and '..' elements from the path array.  */
+  int newpath_length = 0;
+  for (i = components - 1; i >= 0; --i)
+    {
+      if (! grub_strcmp (path_array[i], "."))
+        {
+          grub_free (path_array[i]);
+          path_array[i] = 0;
+        }
+      else if (! grub_strcmp (path_array[i], "..")
+               && i > 0)
+        {
+          /* Delete the '..' and the prior path element.  */
+          grub_free (path_array[i]);
+          path_array[i] = 0;
+          --i;
+          grub_free (path_array[i]);
+          path_array[i] = 0;
+        }
+      else
+        {
+          newpath_length += grub_strlen (path_array[i]) + 1;
+        }
+    }
+
+  /* Construct a new path string.  */
+  newpath = grub_malloc (newpath_length + 1);
+  if (! newpath)
+    goto cleanup;
+
+  newpath[0] = '\0';
+  char *newpath_end = newpath;
+  int first = 1;
+  for (i = 0; i < components; i++)
+    {
+      char *element = path_array[i];
+      if (element)
+        {
+          /* For all components but the first, prefix with a slash.  */
+          if (! first)
+            newpath_end = grub_stpcpy (newpath_end, "/");
+          newpath_end = grub_stpcpy (newpath_end, element);
+          first = 0;
+        }
+    }
+
+cleanup:
+  for (i = 0; i < components; i++)
+    grub_free (path_array[i]);
+  grub_free (path_array);
+
+  return newpath;
+}
+
+/* Return a new heap-allocated string representing to absolute path
+   to the file referred to by PATH.  If PATH is an absolute path, then
+   the returned path is a copy of PATH.  If PATH is a relative path, then
+   BASE is with PATH used to construct the absolute path.  */
+char *
+grub_resolve_relative_path (const char *base, const char *path)
+{
+  char *abspath;
+  char *canonpath;
+  char *p;
+  grub_size_t l;
+
+  /* If PATH is an absolute path, then just use it as is.  */
+  if (path[0] == '/' || path[0] == '(')
+    return canonicalize_path (path);
+
+  abspath = grub_malloc (grub_strlen (base) + grub_strlen (path) + 3);
+  if (! abspath)
+    return 0;
+
+  /* Concatenate BASE and PATH.  */
+  p = grub_stpcpy (abspath, base);
+  l = grub_strlen (abspath);
+  if (l == 0 || abspath[l-1] != '/')
+    {
+      *p = '/';
+      p++;
+      *p = 0;
+    }
+  grub_stpcpy (p, path);
+
+  canonpath = canonicalize_path (abspath);
+  if (! canonpath)
+    return abspath;
+
+  grub_free (abspath);
+  return canonpath;
+}
+
+/* Get the path of the directory where the file at FILE_PATH is located.
+   FILE_PATH should refer to a file, not a directory.  The returned path
+   includes a trailing slash.
+   This does not handle GRUB "(hd0,0)" paths properly yet since it only
+   looks at slashes.  */
+char *
+grub_get_dirname (const char *file_path)
+{
+  int i;
+  int last_slash;
+
+  last_slash = -1;
+  for (i = grub_strlen (file_path) - 1; i >= 0; --i)
+    {
+      if (file_path[i] == '/')
+        {
+          last_slash = i;
+          break;
+        }
+    }
+  if (last_slash == -1)
+    return grub_strdup ("/");
+
+  return grub_new_substring (file_path, 0, last_slash + 1);
+}
+
+static __inline int
+my_isxdigit (char c)
+{
+  return ((c >= '0' && c <= '9')
+          || (c >= 'a' && c <= 'f')
+          || (c >= 'A' && c <= 'F'));
+}
+
+static int
+parse_hex_color_component (const char *s, unsigned start, unsigned end)
+{
+  unsigned len;
+  char buf[3];
+
+  len = end - start;
+  /* Check the limits so we don't overrun the buffer.  */
+  if (len < 1 || len > 2)
+    return 0;
+
+  if (len == 1)
+    {
+      buf[0] = s[start];   /* Get the first and only hex digit.  */
+      buf[1] = buf[0];     /* Duplicate the hex digit.  */
+    }
+  else if (len == 2)
+    {
+      buf[0] = s[start];
+      buf[1] = s[start + 1];
+    }
+
+  buf[2] = '\0';
+
+  return grub_strtoul (buf, 0, 16);
+}
+
+/* Parse a color string of the form "r, g, b", "#RGB", "#RGBA",
+   "#RRGGBB", or "#RRGGBBAA".  */
+grub_err_t
+grub_gui_parse_color (const char *s, grub_gui_color_t *color)
+{
+  grub_gui_color_t c;
+
+  /* Skip whitespace.  */
+  while (*s && grub_isspace (*s))
+    s++;
+
+  if (*s == '#')
+    {
+      /* HTML-style.  Number if hex digits:
+         [6] #RRGGBB     [3] #RGB
+         [8] #RRGGBBAA   [4] #RGBA  */
+
+      s++;  /* Skip the '#'.  */
+      /* Count the hexits to determine the format.  */
+      int hexits = 0;
+      const char *end = s;
+      while (my_isxdigit (*end))
+        {
+          end++;
+          hexits++;
+        }
+
+      /* Parse the color components based on the format.  */
+      if (hexits == 3 || hexits == 4)
+        {
+          c.red = parse_hex_color_component (s, 0, 1);
+          c.green = parse_hex_color_component (s, 1, 2);
+          c.blue = parse_hex_color_component (s, 2, 3);
+          if (hexits == 4)
+            c.alpha = parse_hex_color_component (s, 3, 4);
+          else
+            c.alpha = 255;
+        }
+      else if (hexits == 6 || hexits == 8)
+        {
+          c.red = parse_hex_color_component (s, 0, 2);
+          c.green = parse_hex_color_component (s, 2, 4);
+          c.blue = parse_hex_color_component (s, 4, 6);
+          if (hexits == 8)
+            c.alpha = parse_hex_color_component (s, 6, 8);
+          else
+            c.alpha = 255;
+        }
+      else
+        return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                           "invalid HTML-type color string `%s'", s);
+    }
+  else if (grub_isdigit (*s))
+    {
+      /* Comma separated decimal values.  */
+      c.red = grub_strtoul (s, 0, 0);
+      if ((s = grub_strchr (s, ',')) == 0)
+        return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                           "missing 1st comma separator in color `%s'", s);
+      s++;
+      c.green = grub_strtoul (s, 0, 0);
+      if ((s = grub_strchr (s, ',')) == 0)
+        return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                           "missing 2nd comma separator in color `%s'", s);
+      s++;
+      c.blue = grub_strtoul (s, 0, 0);
+      if ((s = grub_strchr (s, ',')) == 0)
+        c.alpha = 255;
+      else
+        {
+          s++;
+          c.alpha = grub_strtoul (s, 0, 0);
+        }
+    }
+  else
+    {
+      if (! grub_gui_get_named_color (s, &c))
+        return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                           "invalid named color `%s'", s);
+    }
+
+  if (grub_errno == GRUB_ERR_NONE)
+    *color = c;
+  return grub_errno;
+}
diff --git a/grub-core/gfxmenu/gui_util.c b/grub-core/gfxmenu/gui_util.c
new file mode 100644 (file)
index 0000000..eba7bb3
--- /dev/null
@@ -0,0 +1,101 @@
+/* gui_util.c - GUI utility functions.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/gui.h>
+#include <grub/gui_string_util.h>
+
+
+struct find_by_id_state
+{
+  const char *match_id;
+  grub_gui_component_callback match_callback;
+  void *match_userdata;
+};
+
+static void
+find_by_id_recursively (grub_gui_component_t component, void *userdata)
+{
+  struct find_by_id_state *state;
+  const char *id;
+
+  state = (struct find_by_id_state *) userdata;
+  id = component->ops->get_id (component);
+  if (id && grub_strcmp (id, state->match_id) == 0)
+    state->match_callback (component, state->match_userdata);
+
+  if (component->ops->is_instance (component, "container"))
+    {
+      grub_gui_container_t container;
+      container = (grub_gui_container_t) component;
+      container->ops->iterate_children (container,
+                                        find_by_id_recursively,
+                                        state);
+    }
+}
+
+void
+grub_gui_find_by_id (grub_gui_component_t root,
+                     const char *id,
+                     grub_gui_component_callback cb,
+                     void *userdata)
+{
+  struct find_by_id_state state;
+  state.match_id = id;
+  state.match_callback = cb;
+  state.match_userdata = userdata;
+  find_by_id_recursively (root, &state);
+}
+
+
+struct iterate_recursively_state
+{
+  grub_gui_component_callback callback;
+  void *userdata;
+};
+
+static
+void iterate_recursively_cb (grub_gui_component_t component, void *userdata)
+{
+  struct iterate_recursively_state *state;
+
+  state = (struct iterate_recursively_state *) userdata;
+  state->callback (component, state->userdata);
+
+  if (component->ops->is_instance (component, "container"))
+    {
+      grub_gui_container_t container;
+      container = (grub_gui_container_t) component;
+      container->ops->iterate_children (container,
+                                        iterate_recursively_cb,
+                                        state);
+    }
+}
+
+void
+grub_gui_iterate_recursively (grub_gui_component_t root,
+                              grub_gui_component_callback cb,
+                              void *userdata)
+{
+  struct iterate_recursively_state state;
+  state.callback = cb;
+  state.userdata = userdata;
+  iterate_recursively_cb (root, &state);
+}
diff --git a/grub-core/gfxmenu/icon_manager.c b/grub-core/gfxmenu/icon_manager.c
new file mode 100644 (file)
index 0000000..0c304ed
--- /dev/null
@@ -0,0 +1,263 @@
+/* icon_manager.c - gfxmenu icon manager.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/gui_string_util.h>
+#include <grub/bitmap.h>
+#include <grub/bitmap_scale.h>
+#include <grub/menu.h>
+#include <grub/icon_manager.h>
+#include <grub/env.h>
+
+/* Currently hard coded to '.png' extension.  */
+static const char icon_extension[] = ".png";
+
+typedef struct icon_entry
+{
+  char *class_name;
+  struct grub_video_bitmap *bitmap;
+  struct icon_entry *next;
+} *icon_entry_t;
+
+struct grub_gfxmenu_icon_manager
+{
+  char *theme_path;
+  int icon_width;
+  int icon_height;
+
+  /* Icon cache: linked list w/ dummy head node.  */
+  struct icon_entry cache;
+};
+
+
+/* Create a new icon manager and return a point to it.  */
+grub_gfxmenu_icon_manager_t
+grub_gfxmenu_icon_manager_new (void)
+{
+  grub_gfxmenu_icon_manager_t mgr;
+  mgr = grub_malloc (sizeof (*mgr));
+  if (! mgr)
+    return 0;
+
+  mgr->theme_path = 0;
+  mgr->icon_width = 0;
+  mgr->icon_height = 0;
+
+  /* Initialize the dummy head node.  */
+  mgr->cache.class_name = 0;
+  mgr->cache.bitmap = 0;
+  mgr->cache.next = 0;
+
+  return mgr;
+}
+
+/* Destroy the icon manager MGR, freeing all resources used by it.
+
+Note: Any bitmaps returned by grub_gfxmenu_icon_manager_get_icon()
+are destroyed and must not be used by the caller after this function
+is called.  */
+void
+grub_gfxmenu_icon_manager_destroy (grub_gfxmenu_icon_manager_t mgr)
+{
+  grub_gfxmenu_icon_manager_clear_cache (mgr);
+  grub_free (mgr->theme_path);
+  grub_free (mgr);
+}
+
+/* Clear the icon cache.  */
+void
+grub_gfxmenu_icon_manager_clear_cache (grub_gfxmenu_icon_manager_t mgr)
+{
+  icon_entry_t cur;
+  icon_entry_t next;
+  for (cur = mgr->cache.next; cur; cur = next)
+    {
+      next = cur->next;
+      grub_free (cur->class_name);
+      grub_video_bitmap_destroy (cur->bitmap);
+      grub_free (cur);
+    }
+  mgr->cache.next = 0;
+}
+
+/* Set the theme path.  If the theme path is changed, the icon cache
+   is cleared.  */
+void
+grub_gfxmenu_icon_manager_set_theme_path (grub_gfxmenu_icon_manager_t mgr,
+                                          const char *path)
+{
+  /* Clear the cache if the theme path has changed.  */
+  if (((mgr->theme_path == 0) != (path == 0))
+      || (grub_strcmp (mgr->theme_path, path) != 0))
+    grub_gfxmenu_icon_manager_clear_cache (mgr);
+
+  grub_free (mgr->theme_path);
+  mgr->theme_path = path ? grub_strdup (path) : 0;
+}
+
+/* Set the icon size.  When icons are requested from the icon manager,
+   they are scaled to this size before being returned.  If the size is
+   changed, the icon cache is cleared.  */
+void
+grub_gfxmenu_icon_manager_set_icon_size (grub_gfxmenu_icon_manager_t mgr,
+                                         int width, int height)
+{
+  /* If the width or height is changed, we must clear the cache, since the
+     scaled bitmaps are stored in the cache.  */
+  if (width != mgr->icon_width || height != mgr->icon_height)
+    grub_gfxmenu_icon_manager_clear_cache (mgr);
+
+  mgr->icon_width = width;
+  mgr->icon_height = height;
+}
+
+/* Try to load an icon for the specified CLASS_NAME in the directory DIR.
+   Returns 0 if the icon could not be loaded, or returns a pointer to a new
+   bitmap if it was successful.  */
+static struct grub_video_bitmap *
+try_loading_icon (grub_gfxmenu_icon_manager_t mgr,
+                  const char *dir, const char *class_name)
+{
+  char *path;
+  int l;
+
+  path = grub_malloc (grub_strlen (dir) + grub_strlen (class_name)
+                     + grub_strlen (icon_extension) + 3);
+  if (! path)
+    return 0;
+
+  grub_strcpy (path, dir);
+  l = grub_strlen (path);
+  if (path[l-1] != '/')
+    {
+      path[l] = '/';
+      path[l+1] = 0;
+    }
+  grub_strcat (path, class_name);
+  grub_strcat (path, icon_extension);
+
+  struct grub_video_bitmap *raw_bitmap;
+  grub_video_bitmap_load (&raw_bitmap, path);
+  grub_free (path);
+  grub_errno = GRUB_ERR_NONE;  /* Critical to clear the error!!  */
+  if (! raw_bitmap)
+    return 0;
+
+  struct grub_video_bitmap *scaled_bitmap;
+  grub_video_bitmap_create_scaled (&scaled_bitmap,
+                                   mgr->icon_width, mgr->icon_height,
+                                   raw_bitmap,
+                                   GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
+  grub_video_bitmap_destroy (raw_bitmap);
+  if (! scaled_bitmap)
+    {
+      grub_error_push ();
+      grub_error (grub_errno, "failed to scale icon");
+      return 0;
+    }
+
+  return scaled_bitmap;
+}
+
+/* Get the icon for the specified class CLASS_NAME.  If an icon for
+   CLASS_NAME already exists in the cache, then a reference to the cached
+   bitmap is returned.  If it is not cached, then it is loaded and cached.
+   If no icon could be could for CLASS_NAME, then 0 is returned.  */
+static struct grub_video_bitmap *
+get_icon_by_class (grub_gfxmenu_icon_manager_t mgr, const char *class_name)
+{
+  /* First check the icon cache.  */
+  icon_entry_t entry;
+  for (entry = mgr->cache.next; entry; entry = entry->next)
+    {
+      if (grub_strcmp (entry->class_name, class_name) == 0)
+        return entry->bitmap;
+    }
+
+  if (! mgr->theme_path)
+    return 0;
+
+  /* Otherwise, we search for an icon to load.  */
+  char *theme_dir = grub_get_dirname (mgr->theme_path);
+  char *icons_dir;
+  struct grub_video_bitmap *icon;
+  icon = 0;
+  /* First try the theme's own icons, from "grub/themes/NAME/icons/"  */
+  icons_dir = grub_resolve_relative_path (theme_dir, "icons/");
+  if (icons_dir)
+    {
+      icon = try_loading_icon (mgr, icons_dir, class_name);
+      grub_free (icons_dir);
+    }
+
+  grub_free (theme_dir);
+  if (! icon)
+    {
+      const char *icondir;
+
+      icondir = grub_env_get ("icondir");
+      if (icondir)
+       icon = try_loading_icon (mgr, icondir, class_name);
+    }
+
+  /* No icon was found.  */
+  /* This should probably be noted in the cache, so that a search is not
+     performed each time an icon for CLASS_NAME is requested.  */
+  if (! icon)
+    return 0;
+
+  /* Insert a new cache entry for this icon.  */
+  entry = grub_malloc (sizeof (*entry));
+  if (! entry)
+    {
+      grub_video_bitmap_destroy (icon);
+      return 0;
+    }
+  entry->class_name = grub_strdup (class_name);
+  entry->bitmap = icon;
+  entry->next = mgr->cache.next;
+  mgr->cache.next = entry;   /* Link it into the cache.  */
+  return entry->bitmap;
+}
+
+/* Get the best available icon for ENTRY.  Beginning with the first class
+   listed in the menu entry and proceeding forward, an icon for each class
+   is searched for.  The first icon found is returned.  The returned icon
+   is scaled to the size specified by
+   grub_gfxmenu_icon_manager_set_icon_size().
+
+     Note:  Bitmaps returned by this function are destroyed when the
+            icon manager is destroyed.
+ */
+struct grub_video_bitmap *
+grub_gfxmenu_icon_manager_get_icon (grub_gfxmenu_icon_manager_t mgr,
+                                    grub_menu_entry_t entry)
+{
+  struct grub_menu_entry_class *c;
+  struct grub_video_bitmap *icon;
+
+  /* Try each class in succession.  */
+  icon = 0;
+  for (c = entry->classes->next; c && ! icon; c = c->next)
+    icon = get_icon_by_class (mgr, c->name);
+  return icon;
+}
diff --git a/grub-core/gfxmenu/model.c b/grub-core/gfxmenu/model.c
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/grub-core/gfxmenu/named_colors.c b/grub-core/gfxmenu/named_colors.c
new file mode 100644 (file)
index 0000000..eedbc47
--- /dev/null
@@ -0,0 +1,209 @@
+/* named_colors.c - Named color values.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/gui.h>
+#include <grub/gui_string_util.h>
+#include <grub/misc.h>
+
+struct named_color
+{
+  const char *name;
+  grub_gui_color_t color;
+};
+
+/*
+   Named color list generated from the list of SVG color keywords from
+   <http://www.w3.org/TR/css3-color/#svg-color>,
+   processed through the following Perl command:
+   perl -ne 'chomp;split;print "{ \"$_[0]\", RGB_COLOR($_[2]) },\n"'
+ */
+
+#define RGB_COLOR(r,g,b) {.red = r, .green = g, .blue = b, .alpha = 255}
+
+static struct named_color named_colors[] =
+{
+    { "aliceblue", RGB_COLOR(240,248,255) },
+    { "antiquewhite", RGB_COLOR(250,235,215) },
+    { "aqua", RGB_COLOR(0,255,255) },
+    { "aquamarine", RGB_COLOR(127,255,212) },
+    { "azure", RGB_COLOR(240,255,255) },
+    { "beige", RGB_COLOR(245,245,220) },
+    { "bisque", RGB_COLOR(255,228,196) },
+    { "black", RGB_COLOR(0,0,0) },
+    { "blanchedalmond", RGB_COLOR(255,235,205) },
+    { "blue", RGB_COLOR(0,0,255) },
+    { "blueviolet", RGB_COLOR(138,43,226) },
+    { "brown", RGB_COLOR(165,42,42) },
+    { "burlywood", RGB_COLOR(222,184,135) },
+    { "cadetblue", RGB_COLOR(95,158,160) },
+    { "chartreuse", RGB_COLOR(127,255,0) },
+    { "chocolate", RGB_COLOR(210,105,30) },
+    { "coral", RGB_COLOR(255,127,80) },
+    { "cornflowerblue", RGB_COLOR(100,149,237) },
+    { "cornsilk", RGB_COLOR(255,248,220) },
+    { "crimson", RGB_COLOR(220,20,60) },
+    { "cyan", RGB_COLOR(0,255,255) },
+    { "darkblue", RGB_COLOR(0,0,139) },
+    { "darkcyan", RGB_COLOR(0,139,139) },
+    { "darkgoldenrod", RGB_COLOR(184,134,11) },
+    { "darkgray", RGB_COLOR(169,169,169) },
+    { "darkgreen", RGB_COLOR(0,100,0) },
+    { "darkgrey", RGB_COLOR(169,169,169) },
+    { "darkkhaki", RGB_COLOR(189,183,107) },
+    { "darkmagenta", RGB_COLOR(139,0,139) },
+    { "darkolivegreen", RGB_COLOR(85,107,47) },
+    { "darkorange", RGB_COLOR(255,140,0) },
+    { "darkorchid", RGB_COLOR(153,50,204) },
+    { "darkred", RGB_COLOR(139,0,0) },
+    { "darksalmon", RGB_COLOR(233,150,122) },
+    { "darkseagreen", RGB_COLOR(143,188,143) },
+    { "darkslateblue", RGB_COLOR(72,61,139) },
+    { "darkslategray", RGB_COLOR(47,79,79) },
+    { "darkslategrey", RGB_COLOR(47,79,79) },
+    { "darkturquoise", RGB_COLOR(0,206,209) },
+    { "darkviolet", RGB_COLOR(148,0,211) },
+    { "deeppink", RGB_COLOR(255,20,147) },
+    { "deepskyblue", RGB_COLOR(0,191,255) },
+    { "dimgray", RGB_COLOR(105,105,105) },
+    { "dimgrey", RGB_COLOR(105,105,105) },
+    { "dodgerblue", RGB_COLOR(30,144,255) },
+    { "firebrick", RGB_COLOR(178,34,34) },
+    { "floralwhite", RGB_COLOR(255,250,240) },
+    { "forestgreen", RGB_COLOR(34,139,34) },
+    { "fuchsia", RGB_COLOR(255,0,255) },
+    { "gainsboro", RGB_COLOR(220,220,220) },
+    { "ghostwhite", RGB_COLOR(248,248,255) },
+    { "gold", RGB_COLOR(255,215,0) },
+    { "goldenrod", RGB_COLOR(218,165,32) },
+    { "gray", RGB_COLOR(128,128,128) },
+    { "green", RGB_COLOR(0,128,0) },
+    { "greenyellow", RGB_COLOR(173,255,47) },
+    { "grey", RGB_COLOR(128,128,128) },
+    { "honeydew", RGB_COLOR(240,255,240) },
+    { "hotpink", RGB_COLOR(255,105,180) },
+    { "indianred", RGB_COLOR(205,92,92) },
+    { "indigo", RGB_COLOR(75,0,130) },
+    { "ivory", RGB_COLOR(255,255,240) },
+    { "khaki", RGB_COLOR(240,230,140) },
+    { "lavender", RGB_COLOR(230,230,250) },
+    { "lavenderblush", RGB_COLOR(255,240,245) },
+    { "lawngreen", RGB_COLOR(124,252,0) },
+    { "lemonchiffon", RGB_COLOR(255,250,205) },
+    { "lightblue", RGB_COLOR(173,216,230) },
+    { "lightcoral", RGB_COLOR(240,128,128) },
+    { "lightcyan", RGB_COLOR(224,255,255) },
+    { "lightgoldenrodyellow", RGB_COLOR(250,250,210) },
+    { "lightgray", RGB_COLOR(211,211,211) },
+    { "lightgreen", RGB_COLOR(144,238,144) },
+    { "lightgrey", RGB_COLOR(211,211,211) },
+    { "lightpink", RGB_COLOR(255,182,193) },
+    { "lightsalmon", RGB_COLOR(255,160,122) },
+    { "lightseagreen", RGB_COLOR(32,178,170) },
+    { "lightskyblue", RGB_COLOR(135,206,250) },
+    { "lightslategray", RGB_COLOR(119,136,153) },
+    { "lightslategrey", RGB_COLOR(119,136,153) },
+    { "lightsteelblue", RGB_COLOR(176,196,222) },
+    { "lightyellow", RGB_COLOR(255,255,224) },
+    { "lime", RGB_COLOR(0,255,0) },
+    { "limegreen", RGB_COLOR(50,205,50) },
+    { "linen", RGB_COLOR(250,240,230) },
+    { "magenta", RGB_COLOR(255,0,255) },
+    { "maroon", RGB_COLOR(128,0,0) },
+    { "mediumaquamarine", RGB_COLOR(102,205,170) },
+    { "mediumblue", RGB_COLOR(0,0,205) },
+    { "mediumorchid", RGB_COLOR(186,85,211) },
+    { "mediumpurple", RGB_COLOR(147,112,219) },
+    { "mediumseagreen", RGB_COLOR(60,179,113) },
+    { "mediumslateblue", RGB_COLOR(123,104,238) },
+    { "mediumspringgreen", RGB_COLOR(0,250,154) },
+    { "mediumturquoise", RGB_COLOR(72,209,204) },
+    { "mediumvioletred", RGB_COLOR(199,21,133) },
+    { "midnightblue", RGB_COLOR(25,25,112) },
+    { "mintcream", RGB_COLOR(245,255,250) },
+    { "mistyrose", RGB_COLOR(255,228,225) },
+    { "moccasin", RGB_COLOR(255,228,181) },
+    { "navajowhite", RGB_COLOR(255,222,173) },
+    { "navy", RGB_COLOR(0,0,128) },
+    { "oldlace", RGB_COLOR(253,245,230) },
+    { "olive", RGB_COLOR(128,128,0) },
+    { "olivedrab", RGB_COLOR(107,142,35) },
+    { "orange", RGB_COLOR(255,165,0) },
+    { "orangered", RGB_COLOR(255,69,0) },
+    { "orchid", RGB_COLOR(218,112,214) },
+    { "palegoldenrod", RGB_COLOR(238,232,170) },
+    { "palegreen", RGB_COLOR(152,251,152) },
+    { "paleturquoise", RGB_COLOR(175,238,238) },
+    { "palevioletred", RGB_COLOR(219,112,147) },
+    { "papayawhip", RGB_COLOR(255,239,213) },
+    { "peachpuff", RGB_COLOR(255,218,185) },
+    { "peru", RGB_COLOR(205,133,63) },
+    { "pink", RGB_COLOR(255,192,203) },
+    { "plum", RGB_COLOR(221,160,221) },
+    { "powderblue", RGB_COLOR(176,224,230) },
+    { "purple", RGB_COLOR(128,0,128) },
+    { "red", RGB_COLOR(255,0,0) },
+    { "rosybrown", RGB_COLOR(188,143,143) },
+    { "royalblue", RGB_COLOR(65,105,225) },
+    { "saddlebrown", RGB_COLOR(139,69,19) },
+    { "salmon", RGB_COLOR(250,128,114) },
+    { "sandybrown", RGB_COLOR(244,164,96) },
+    { "seagreen", RGB_COLOR(46,139,87) },
+    { "seashell", RGB_COLOR(255,245,238) },
+    { "sienna", RGB_COLOR(160,82,45) },
+    { "silver", RGB_COLOR(192,192,192) },
+    { "skyblue", RGB_COLOR(135,206,235) },
+    { "slateblue", RGB_COLOR(106,90,205) },
+    { "slategray", RGB_COLOR(112,128,144) },
+    { "slategrey", RGB_COLOR(112,128,144) },
+    { "snow", RGB_COLOR(255,250,250) },
+    { "springgreen", RGB_COLOR(0,255,127) },
+    { "steelblue", RGB_COLOR(70,130,180) },
+    { "tan", RGB_COLOR(210,180,140) },
+    { "teal", RGB_COLOR(0,128,128) },
+    { "thistle", RGB_COLOR(216,191,216) },
+    { "tomato", RGB_COLOR(255,99,71) },
+    { "turquoise", RGB_COLOR(64,224,208) },
+    { "violet", RGB_COLOR(238,130,238) },
+    { "wheat", RGB_COLOR(245,222,179) },
+    { "white", RGB_COLOR(255,255,255) },
+    { "whitesmoke", RGB_COLOR(245,245,245) },
+    { "yellow", RGB_COLOR(255,255,0) },
+    { "yellowgreen", RGB_COLOR(154,205,50) },
+    { 0, { 0, 0, 0, 0 } }  /* Terminator.  */
+};
+
+/* Get the color named NAME.  If the color was found, returns 1 and
+   stores the color into *COLOR.  If the color was not found, returns 0 and
+   does not modify *COLOR.  */
+int
+grub_gui_get_named_color (const char *name,
+                          grub_gui_color_t *color)
+{
+  int i;
+  for (i = 0; named_colors[i].name; i++)
+    {
+      if (grub_strcmp (named_colors[i].name, name) == 0)
+        {
+          *color = named_colors[i].color;
+          return 1;
+        }
+    }
+  return 0;
+}
diff --git a/grub-core/gfxmenu/theme_loader.c b/grub-core/gfxmenu/theme_loader.c
new file mode 100644 (file)
index 0000000..3854c6c
--- /dev/null
@@ -0,0 +1,723 @@
+/* theme_loader.c - Theme file loader for gfxmenu.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/file.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/video.h>
+#include <grub/gui_string_util.h>
+#include <grub/bitmap.h>
+#include <grub/bitmap_scale.h>
+#include <grub/gfxwidgets.h>
+#include <grub/gfxmenu_view.h>
+#include <grub/gui.h>
+
+/* Construct a new box widget using ABSPATTERN to find the pixmap files for
+   it, storing the new box instance at *BOXPTR.
+   PATTERN should be of the form: "(hd0,0)/somewhere/style*.png".
+   The '*' then gets substituted with the various pixmap names that the
+   box uses.  */
+static grub_err_t
+recreate_box_absolute (grub_gfxmenu_box_t *boxptr, const char *abspattern)
+{
+  char *prefix;
+  char *suffix;
+  char *star;
+  grub_gfxmenu_box_t box;
+
+  star = grub_strchr (abspattern, '*');
+  if (! star)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                       "missing `*' in box pixmap pattern `%s'", abspattern);
+
+  /* Prefix:  Get the part before the '*'.  */
+  prefix = grub_malloc (star - abspattern + 1);
+  if (! prefix)
+    return grub_errno;
+
+  grub_memcpy (prefix, abspattern, star - abspattern);
+  prefix[star - abspattern] = '\0';
+
+  /* Suffix:  Everything after the '*' is the suffix.  */
+  suffix = star + 1;
+
+  box = grub_gfxmenu_create_box (prefix, suffix);
+  grub_free (prefix);
+  if (! box)
+    return grub_errno;
+
+  if (*boxptr)
+    (*boxptr)->destroy (*boxptr);
+  *boxptr = box;
+  return grub_errno;
+}
+
+
+/* Construct a new box widget using PATTERN to find the pixmap files for it,
+   storing the new widget at *BOXPTR.  PATTERN should be of the form:
+   "somewhere/style*.png".  The '*' then gets substituted with the various
+   pixmap names that the widget uses.
+
+   Important!  The value of *BOXPTR must be initialized!  It must either
+   (1) Be 0 (a NULL pointer), or
+   (2) Be a pointer to a valid 'grub_gfxmenu_box_t' instance.
+   In this case, the previous instance is destroyed.  */
+grub_err_t
+grub_gui_recreate_box (grub_gfxmenu_box_t *boxptr,
+                       const char *pattern, const char *theme_dir)
+{
+  char *abspattern;
+
+  /* Check arguments.  */
+  if (! pattern)
+    {
+      /* If no pixmap pattern is given, then just create an empty box.  */
+      if (*boxptr)
+        (*boxptr)->destroy (*boxptr);
+      *boxptr = grub_gfxmenu_create_box (0, 0);
+      return grub_errno;
+    }
+
+  if (! theme_dir)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                       "styled box missing theme directory");
+
+  /* Resolve to an absolute path.  */
+  abspattern = grub_resolve_relative_path (theme_dir, pattern);
+  if (! abspattern)
+    return grub_errno;
+
+  /* Create the box.  */
+  recreate_box_absolute (boxptr, abspattern);
+  grub_free (abspattern);
+  return grub_errno;
+}
+
+/* Set the specified property NAME on the view to the given string VALUE.
+   The caller is responsible for the lifetimes of NAME and VALUE.  */
+static grub_err_t
+theme_set_string (grub_gfxmenu_view_t view,
+                  const char *name,
+                  const char *value,
+                  const char *theme_dir,
+                  const char *filename,
+                  int line_num,
+                  int col_num)
+{
+  if (! grub_strcmp ("title-font", name))
+    view->title_font = grub_font_get (value);
+  else if (! grub_strcmp ("message-font", name))
+    view->message_font = grub_font_get (value);
+  else if (! grub_strcmp ("terminal-font", name))
+    {
+      grub_free (view->terminal_font_name);
+      view->terminal_font_name = grub_strdup (value);
+      if (! view->terminal_font_name)
+        return grub_errno;
+    }
+  else if (! grub_strcmp ("title-color", name))
+    grub_gui_parse_color (value, &view->title_color);
+  else if (! grub_strcmp ("message-color", name))
+    grub_gui_parse_color (value, &view->message_color);
+  else if (! grub_strcmp ("message-bg-color", name))
+    grub_gui_parse_color (value, &view->message_bg_color);
+  else if (! grub_strcmp ("desktop-image", name))
+    {
+      struct grub_video_bitmap *raw_bitmap;
+      struct grub_video_bitmap *scaled_bitmap;
+      char *path;
+      path = grub_resolve_relative_path (theme_dir, value);
+      if (! path)
+        return grub_errno;
+      if (grub_video_bitmap_load (&raw_bitmap, path) != GRUB_ERR_NONE)
+        {
+          grub_free (path);
+          return grub_errno;
+        }
+      grub_free(path);
+      grub_video_bitmap_create_scaled (&scaled_bitmap,
+                                       view->screen.width,
+                                       view->screen.height,
+                                       raw_bitmap,
+                                       GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
+      grub_video_bitmap_destroy (raw_bitmap);
+      if (! scaled_bitmap)
+        {
+          grub_error_push ();
+          return grub_error (grub_errno, "error scaling desktop image");
+        }
+
+      grub_video_bitmap_destroy (view->desktop_image);
+      view->desktop_image = scaled_bitmap;
+    }
+  else if (! grub_strcmp ("desktop-color", name))
+     grub_gui_parse_color (value, &view->desktop_color);
+  else if (! grub_strcmp ("terminal-box", name))
+    {
+        grub_err_t err;
+        err = grub_gui_recreate_box (&view->terminal_box, value, theme_dir);
+        if (err != GRUB_ERR_NONE)
+          return err;
+    }
+  else if (! grub_strcmp ("title-text", name))
+    {
+      grub_free (view->title_text);
+      view->title_text = grub_strdup (value);
+      if (! view->title_text)
+        return grub_errno;
+    }
+  else
+    {
+      return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                         "%s:%d:%d unknown property `%s'",
+                         filename, line_num, col_num, name);
+    }
+  return grub_errno;
+}
+
+struct parsebuf
+{
+  char *buf;
+  int pos;
+  int len;
+  int line_num;
+  int col_num;
+  const char *filename;
+  char *theme_dir;
+  grub_gfxmenu_view_t view;
+};
+
+static int
+has_more (struct parsebuf *p)
+{
+  return p->pos < p->len;
+}
+
+static int
+read_char (struct parsebuf *p)
+{
+  if (has_more (p))
+    {
+      char c;
+      c = p->buf[p->pos++];
+      if (c == '\n')
+        {
+          p->line_num++;
+          p->col_num = 1;
+        }
+      else
+        {
+          p->col_num++;
+        }
+      return c;
+    }
+  else
+    return -1;
+}
+
+static int
+peek_char (struct parsebuf *p)
+{
+  if (has_more (p))
+    return p->buf[p->pos];
+  else
+    return -1;
+}
+
+static int
+is_whitespace (char c)
+{
+  return (c == ' '
+          || c == '\t'
+          || c == '\r'
+          || c == '\n'
+          || c == '\f');
+}
+
+static void
+skip_whitespace (struct parsebuf *p)
+{
+  while (has_more (p) && is_whitespace(peek_char (p)))
+    read_char (p);
+}
+
+static void
+advance_to_next_line (struct parsebuf *p)
+{
+  int c;
+
+  /* Eat characters up to the newline.  */
+  do
+    {
+      c = read_char (p);
+    }
+  while (c != -1 && c != '\n');
+}
+
+static int
+is_identifier_char (int c)
+{
+  return (c != -1
+          && (grub_isalpha(c)
+              || grub_isdigit(c)
+              || c == '_'
+              || c == '-'));
+}
+
+static char *
+read_identifier (struct parsebuf *p)
+{
+  /* Index of the first character of the identifier in p->buf.  */
+  int start;
+  /* Next index after the last character of the identifer in p->buf.  */
+  int end;
+
+  skip_whitespace (p);
+
+  /* Capture the start of the identifier.  */
+  start = p->pos;
+
+  /* Scan for the end.  */
+  while (is_identifier_char (peek_char (p)))
+    read_char (p);
+  end = p->pos;
+
+  if (end - start < 1)
+    return 0;
+
+  return grub_new_substring (p->buf, start, end);
+}
+
+static char *
+read_expression (struct parsebuf *p)
+{
+  int start;
+  int end;
+
+  skip_whitespace (p);
+  if (peek_char (p) == '"')
+    {
+      /* Read as a quoted string.  
+         The quotation marks are not included in the expression value.  */
+      /* Skip opening quotation mark.  */
+      read_char (p);
+      start = p->pos;
+      while (has_more (p) && peek_char (p) != '"')
+        read_char (p);
+      end = p->pos;
+      /* Skip the terminating quotation mark.  */
+      read_char (p);
+    }
+  else if (peek_char (p) == '(')
+    {
+      /* Read as a parenthesized string -- for tuples/coordinates.  */
+      /* The parentheses are included in the expression value.  */
+      int c;
+
+      start = p->pos;
+      do
+        {
+          c = read_char (p);
+        }
+      while (c != -1 && c != ')');
+      end = p->pos;
+    }
+  else if (has_more (p))
+    {
+      /* Read as a single word -- for numeric values or words without
+         whitespace.  */
+      start = p->pos;
+      while (has_more (p) && ! is_whitespace (peek_char (p)))
+        read_char (p);
+      end = p->pos;
+    }
+  else
+    {
+      /* The end of the theme file has been reached.  */
+      grub_error (GRUB_ERR_IO, "%s:%d:%d expression expected in theme file",
+                  p->filename, p->line_num, p->col_num);
+      return 0;
+    }
+
+  return grub_new_substring (p->buf, start, end);
+}
+
+static grub_err_t
+parse_proportional_spec (char *value, signed *abs, grub_fixed_signed_t *prop)
+{
+  signed num;
+  char *ptr;
+  int sig = 0;
+  *abs = 0;
+  *prop = 0;
+  ptr = value;
+  while (*ptr)
+    {
+      sig = 0;
+
+      while (*ptr == '-' || *ptr == '+')
+       {
+         if (*ptr == '-')
+           sig = !sig;
+         ptr++;
+       }
+
+      num = grub_strtoul (ptr, &ptr, 0);
+      if (grub_errno)
+       return grub_errno;
+      if (sig)
+       num = -num;
+      if (*ptr == '%')
+       {
+         *prop += grub_fixed_fsf_divide (grub_signed_to_fixed (num), 100);
+         ptr++;
+       }
+      else
+       *abs += num;
+    }
+  return GRUB_ERR_NONE;
+}
+
+
+/* Read a GUI object specification from the theme file.
+   Any components created will be added to the GUI container PARENT.  */
+static grub_err_t
+read_object (struct parsebuf *p, grub_gui_container_t parent)
+{
+  grub_video_rect_t bounds;
+
+  char *name;
+  name = read_identifier (p);
+  if (! name)
+    goto cleanup;
+
+  grub_gui_component_t component = 0;
+  if (grub_strcmp (name, "label") == 0)
+    {
+      component = grub_gui_label_new ();
+    }
+  else if (grub_strcmp (name, "image") == 0)
+    {
+      component = grub_gui_image_new ();
+    }
+  else if (grub_strcmp (name, "vbox") == 0)
+    {
+      component = (grub_gui_component_t) grub_gui_vbox_new ();
+    }
+  else if (grub_strcmp (name, "hbox") == 0)
+    {
+      component = (grub_gui_component_t) grub_gui_hbox_new ();
+    }
+  else if (grub_strcmp (name, "canvas") == 0)
+    {
+      component = (grub_gui_component_t) grub_gui_canvas_new ();
+    }
+  else if (grub_strcmp (name, "progress_bar") == 0)
+    {
+      component = grub_gui_progress_bar_new ();
+    }
+  else if (grub_strcmp (name, "circular_progress") == 0)
+    {
+      component = grub_gui_circular_progress_new ();
+    }
+  else if (grub_strcmp (name, "boot_menu") == 0)
+    {
+      component = grub_gui_list_new ();
+    }
+  else
+    {
+      /* Unknown type.  */
+      grub_error (GRUB_ERR_IO, "%s:%d:%d unknown object type `%s'",
+                  p->filename, p->line_num, p->col_num, name);
+      goto cleanup;
+    }
+
+  if (! component)
+    goto cleanup;
+
+  /* Inform the component about the theme so it can find its resources.  */
+  component->ops->set_property (component, "theme_dir", p->theme_dir);
+  component->ops->set_property (component, "theme_path", p->filename);
+
+  /* Add the component as a child of PARENT.  */
+  bounds.x = 0;
+  bounds.y = 0;
+  bounds.width = -1;
+  bounds.height = -1;
+  component->ops->set_bounds (component, &bounds);
+  parent->ops->add (parent, component);
+
+  skip_whitespace (p);
+  if (read_char (p) != '{')
+    {
+      grub_error (GRUB_ERR_IO,
+                  "%s:%d:%d expected `{' after object type name `%s'",
+                  p->filename, p->line_num, p->col_num, name);
+      goto cleanup;
+    }
+
+  while (has_more (p))
+    {
+      skip_whitespace (p);
+
+      /* Check whether the end has been encountered.  */
+      if (peek_char (p) == '}')
+        {
+          /* Skip the closing brace.  */
+          read_char (p);
+          break;
+        }
+
+      if (peek_char (p) == '#')
+        {
+          /* Skip comments.  */
+          advance_to_next_line (p);
+          continue;
+        }
+
+      if (peek_char (p) == '+')
+        {
+          /* Skip the '+'.  */
+          read_char (p);
+
+          /* Check whether this component is a container.  */
+          if (component->ops->is_instance (component, "container"))
+            {
+              /* Read the sub-object recursively and add it as a child.  */
+              if (read_object (p, (grub_gui_container_t) component) != 0)
+                goto cleanup;
+              /* After reading the sub-object, resume parsing, expecting
+                 another property assignment or sub-object definition.  */
+              continue;
+            }
+          else
+            {
+              grub_error (GRUB_ERR_IO,
+                          "%s:%d:%d attempted to add object to non-container",
+                          p->filename, p->line_num, p->col_num);
+              goto cleanup;
+            }
+        }
+
+      char *property;
+      property = read_identifier (p);
+      if (! property)
+        {
+          grub_error (GRUB_ERR_IO, "%s:%d:%d identifier expected in theme file",
+                      p->filename, p->line_num, p->col_num);
+          goto cleanup;
+        }
+
+      skip_whitespace (p);
+      if (read_char (p) != '=')
+        {
+          grub_error (GRUB_ERR_IO,
+                      "%s:%d:%d expected `=' after property name `%s'",
+                      p->filename, p->line_num, p->col_num, property);
+          grub_free (property);
+          goto cleanup;
+        }
+      skip_whitespace (p);
+
+      char *value;
+      value = read_expression (p);
+      if (! value)
+        {
+          grub_free (property);
+          goto cleanup;
+        }
+
+      /* Handle the property value.  */
+      if (grub_strcmp (property, "left") == 0)
+       parse_proportional_spec (value, &component->x, &component->xfrac);
+      else if (grub_strcmp (property, "top") == 0)
+       parse_proportional_spec (value, &component->y, &component->yfrac);
+      else if (grub_strcmp (property, "width") == 0)
+       parse_proportional_spec (value, &component->w, &component->wfrac);
+      else if (grub_strcmp (property, "height") == 0)
+       parse_proportional_spec (value, &component->h, &component->hfrac);
+      else
+       /* General property handling.  */
+       component->ops->set_property (component, property, value);
+
+      grub_free (value);
+      grub_free (property);
+      if (grub_errno != GRUB_ERR_NONE)
+        goto cleanup;
+    }
+
+cleanup:
+  grub_free (name);
+  return grub_errno;
+}
+
+static grub_err_t
+read_property (struct parsebuf *p)
+{
+  char *name;
+
+  /* Read the property name.  */
+  name = read_identifier (p);
+  if (! name)
+    {
+      advance_to_next_line (p);
+      return grub_errno;
+    }
+
+  /* Skip whitespace before separator.  */
+  skip_whitespace (p);
+
+  /* Read separator.  */
+  if (read_char (p) != ':')
+    {
+      grub_error (GRUB_ERR_IO,
+                  "%s:%d:%d missing separator after property name `%s'",
+                  p->filename, p->line_num, p->col_num, name);
+      goto done;
+    }
+
+  /* Skip whitespace after separator.  */
+  skip_whitespace (p);
+
+  /* Get the value based on its type.  */
+  if (peek_char (p) == '"')
+    {
+      /* String value (e.g., '"My string"').  */
+      char *value = read_expression (p);
+      if (! value)
+        {
+          grub_error (GRUB_ERR_IO, "%s:%d:%d missing property value",
+                      p->filename, p->line_num, p->col_num);
+          goto done;
+        }
+      /* If theme_set_string results in an error, grub_errno will be returned
+         below.  */
+      theme_set_string (p->view, name, value, p->theme_dir,
+                        p->filename, p->line_num, p->col_num);
+      grub_free (value);
+    }
+  else
+    {
+      grub_error (GRUB_ERR_IO,
+                  "%s:%d:%d property value invalid; "
+                  "enclose literal values in quotes (\")",
+                  p->filename, p->line_num, p->col_num);
+      goto done;
+    }
+
+done:
+  grub_free (name);
+  return grub_errno;
+}
+
+/* Set properties on the view based on settings from the specified
+   theme file.  */
+grub_err_t
+grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
+{
+  grub_file_t file;
+  struct parsebuf p;
+
+  p.view = view;
+  p.theme_dir = grub_get_dirname (theme_path);
+
+  file = grub_file_open (theme_path);
+  if (! file)
+    {
+      grub_free (p.theme_dir);
+      return grub_errno;
+    }
+
+  p.len = grub_file_size (file);
+  p.buf = grub_malloc (p.len);
+  p.pos = 0;
+  p.line_num = 1;
+  p.col_num = 1;
+  p.filename = theme_path;
+  if (! p.buf)
+    {
+      grub_file_close (file);
+      grub_free (p.theme_dir);
+      return grub_errno;
+    }
+  if (grub_file_read (file, p.buf, p.len) != p.len)
+    {
+      grub_free (p.buf);
+      grub_file_close (file);
+      grub_free (p.theme_dir);
+      return grub_errno;
+    }
+
+  if (view->canvas)
+    view->canvas->component.ops->destroy (view->canvas);
+
+  view->canvas = grub_gui_canvas_new ();
+  ((grub_gui_component_t) view->canvas)
+    ->ops->set_bounds ((grub_gui_component_t) view->canvas,
+                       &view->screen);
+
+  while (has_more (&p))
+    {
+      /* Skip comments (lines beginning with #).  */
+      if (peek_char (&p) == '#')
+        {
+          advance_to_next_line (&p);
+          continue;
+        }
+
+      /* Find the first non-whitespace character.  */
+      skip_whitespace (&p);
+
+      /* Handle the content.  */
+      if (peek_char (&p) == '+')
+        {
+          /* Skip the '+'.  */
+          read_char (&p);
+          read_object (&p, view->canvas);
+        }
+      else
+        {
+          read_property (&p);
+        }
+
+      if (grub_errno != GRUB_ERR_NONE)
+        goto fail;
+    }
+
+  /* Set the new theme path.  */
+  grub_free (view->theme_path);
+  view->theme_path = grub_strdup (theme_path);
+  goto cleanup;
+
+fail:
+  if (view->canvas)
+    {
+      view->canvas->component.ops->destroy (view->canvas);
+      view->canvas = 0;
+    }
+
+cleanup:
+  grub_free (p.buf);
+  grub_file_close (file);
+  grub_free (p.theme_dir);
+  return grub_errno;
+}
diff --git a/grub-core/gfxmenu/view.c b/grub-core/gfxmenu/view.c
new file mode 100644 (file)
index 0000000..bf637a9
--- /dev/null
@@ -0,0 +1,486 @@
+/* view.c - Graphical menu interface MVC view. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/file.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/normal.h>
+#include <grub/video.h>
+#include <grub/gfxterm.h>
+#include <grub/bitmap.h>
+#include <grub/bitmap_scale.h>
+#include <grub/term.h>
+#include <grub/gfxwidgets.h>
+#include <grub/time.h>
+#include <grub/menu.h>
+#include <grub/menu_viewer.h>
+#include <grub/gfxmenu_view.h>
+#include <grub/gui_string_util.h>
+#include <grub/icon_manager.h>
+
+/* The component ID identifying GUI components to be updated as the timeout
+   status changes.  */
+#define TIMEOUT_COMPONENT_ID "__timeout__"
+
+static void
+init_terminal (grub_gfxmenu_view_t view);
+static grub_video_rect_t term_rect;
+static grub_gfxmenu_view_t term_view;
+
+/* Create a new view object, loading the theme specified by THEME_PATH and
+   associating MODEL with the view.  */
+grub_gfxmenu_view_t
+grub_gfxmenu_view_new (const char *theme_path,
+                      int width, int height)
+{
+  grub_gfxmenu_view_t view;
+  grub_font_t default_font;
+  grub_gui_color_t default_fg_color;
+  grub_gui_color_t default_bg_color;
+
+  view = grub_malloc (sizeof (*view));
+  if (! view)
+    return 0;
+
+  view->screen.x = 0;
+  view->screen.y = 0;
+  view->screen.width = width;
+  view->screen.height = height;
+
+  default_font = grub_font_get ("Unknown Regular 16");
+  default_fg_color = grub_gui_color_rgb (0, 0, 0);
+  default_bg_color = grub_gui_color_rgb (255, 255, 255);
+
+  view->canvas = 0;
+
+  view->title_font = default_font;
+  view->message_font = default_font;
+  view->terminal_font_name = grub_strdup ("Fixed 10");
+  view->title_color = default_fg_color;
+  view->message_color = default_bg_color;
+  view->message_bg_color = default_fg_color;
+  view->desktop_image = 0;
+  view->desktop_color = default_bg_color;
+  view->terminal_box = grub_gfxmenu_create_box (0, 0);
+  view->title_text = grub_strdup ("GRUB Boot Menu");
+  view->progress_message_text = 0;
+  view->theme_path = 0;
+
+  /* Set the timeout bar's frame.  */
+  view->progress_message_frame.width = view->screen.width * 4 / 5;
+  view->progress_message_frame.height = 50;
+  view->progress_message_frame.x = view->screen.x
+    + (view->screen.width - view->progress_message_frame.width) / 2;
+  view->progress_message_frame.y = view->screen.y
+    + view->screen.height - 90 - 20 - view->progress_message_frame.height;
+
+  if (grub_gfxmenu_view_load_theme (view, theme_path) != 0)
+    {
+      grub_gfxmenu_view_destroy (view);
+      return 0;
+    }
+
+  return view;
+}
+
+/* Destroy the view object.  All used memory is freed.  */
+void
+grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view)
+{
+  if (!view)
+    return;
+  grub_video_bitmap_destroy (view->desktop_image);
+  if (view->terminal_box)
+    view->terminal_box->destroy (view->terminal_box);
+  grub_free (view->terminal_font_name);
+  grub_free (view->title_text);
+  grub_free (view->progress_message_text);
+  grub_free (view->theme_path);
+  if (view->canvas)
+    view->canvas->component.ops->destroy (view->canvas);
+  grub_free (view);
+}
+
+static void
+redraw_background (grub_gfxmenu_view_t view,
+                  const grub_video_rect_t *bounds)
+{
+  if (view->desktop_image)
+    {
+      struct grub_video_bitmap *img = view->desktop_image;
+      grub_video_blit_bitmap (img, GRUB_VIDEO_BLIT_REPLACE,
+                              bounds->x, bounds->y,
+                             bounds->x - view->screen.x,
+                             bounds->y - view->screen.y,
+                             bounds->width, bounds->height);
+    }
+  else
+    {
+      grub_video_fill_rect (grub_gui_map_color (view->desktop_color),
+                            bounds->x, bounds->y,
+                            bounds->width, bounds->height);
+    }
+}
+
+static void
+draw_title (grub_gfxmenu_view_t view)
+{
+  if (! view->title_text)
+    return;
+
+  /* Center the title. */
+  int title_width = grub_font_get_string_width (view->title_font,
+                                                view->title_text);
+  int x = (view->screen.width - title_width) / 2;
+  int y = 40 + grub_font_get_ascent (view->title_font);
+  grub_font_draw_string (view->title_text,
+                         view->title_font,
+                         grub_gui_map_color (view->title_color),
+                         x, y);
+}
+
+struct progress_value_data
+{
+  int visible;
+  int start;
+  int end;
+  int value;
+};
+
+static void
+update_timeout_visit (grub_gui_component_t component,
+                      void *userdata)
+{
+  struct progress_value_data *pv;
+  pv = (struct progress_value_data *) userdata;
+
+  ((struct grub_gui_progress *) component)->ops
+    ->set_state ((struct grub_gui_progress *) component,
+                pv->visible, pv->start, pv->value, pv->end);
+}
+
+void 
+grub_gfxmenu_print_timeout (int timeout, void *data)
+{
+  struct grub_gfxmenu_view *view = data;
+
+  struct progress_value_data pv;
+
+  auto void redraw_timeout_visit (grub_gui_component_t component,
+                                 void *userdata __attribute__ ((unused)));
+
+  auto void redraw_timeout_visit (grub_gui_component_t component,
+                                 void *userdata __attribute__ ((unused)))
+  {
+    grub_video_rect_t bounds;
+    component->ops->get_bounds (component, &bounds);
+    grub_gfxmenu_view_redraw (view, &bounds);
+  }
+
+  if (view->first_timeout == -1)
+    view->first_timeout = timeout;
+
+  pv.visible = 1;
+  pv.start = -(view->first_timeout + 1);
+  pv.end = 0;
+  pv.value = -timeout;
+
+  grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
+                       TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv);
+  grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
+                      TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
+  grub_video_swap_buffers ();
+  if (view->double_repaint)
+    grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
+                        TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
+}
+
+void 
+grub_gfxmenu_clear_timeout (void *data)
+{
+  struct progress_value_data pv;
+  struct grub_gfxmenu_view *view = data;
+
+  auto void redraw_timeout_visit (grub_gui_component_t component,
+                                 void *userdata __attribute__ ((unused)));
+
+  auto void redraw_timeout_visit (grub_gui_component_t component,
+                                 void *userdata __attribute__ ((unused)))
+  {
+    grub_video_rect_t bounds;
+    component->ops->get_bounds (component, &bounds);
+    grub_gfxmenu_view_redraw (view, &bounds);
+  }
+
+  pv.visible = 0;
+  pv.start = 1;
+  pv.end = 0;
+  pv.value = 0;
+
+  grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
+                       TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv);
+  grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
+                      TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
+  grub_video_swap_buffers ();
+  if (view->double_repaint)
+    grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
+                        TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
+}
+
+static void
+update_menu_visit (grub_gui_component_t component,
+                   void *userdata)
+{
+  grub_gfxmenu_view_t view;
+  view = userdata;
+  if (component->ops->is_instance (component, "list"))
+    {
+      grub_gui_list_t list = (grub_gui_list_t) component;
+      list->ops->set_view_info (list, view);
+    }
+}
+
+/* Update any boot menu components with the current menu model and
+   theme path.  */
+static void
+update_menu_components (grub_gfxmenu_view_t view)
+{
+  grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
+                                update_menu_visit, view);
+}
+
+static void
+draw_message (grub_gfxmenu_view_t view)
+{
+  char *text = view->progress_message_text;
+  grub_video_rect_t f = view->progress_message_frame;
+  if (! text)
+    return;
+
+  grub_font_t font = view->message_font;
+  grub_video_color_t color = grub_gui_map_color (view->message_color);
+
+  /* Border.  */
+  grub_video_fill_rect (color,
+                        f.x-1, f.y-1, f.width+2, f.height+2);
+  /* Fill.  */
+  grub_video_fill_rect (grub_gui_map_color (view->message_bg_color),
+                        f.x, f.y, f.width, f.height);
+
+  /* Center the text. */
+  int text_width = grub_font_get_string_width (font, text);
+  int x = f.x + (f.width - text_width) / 2;
+  int y = (f.y + (f.height - grub_font_get_descent (font)) / 2
+           + grub_font_get_ascent (font) / 2);
+  grub_font_draw_string (text, font, color, x, y);
+}
+
+void
+grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
+                         const grub_video_rect_t *region)
+{
+  if (grub_video_have_common_points (&term_rect, region))
+    grub_gfxterm_schedule_repaint ();
+
+  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
+
+  redraw_background (view, region);
+  if (view->canvas)
+    view->canvas->component.ops->paint (view->canvas, region);
+  draw_title (view);
+  if (grub_video_have_common_points (&view->progress_message_frame, region))
+    draw_message (view);
+}
+
+void
+grub_gfxmenu_view_draw (grub_gfxmenu_view_t view)
+{
+  init_terminal (view);
+
+  /* Clear the screen; there may be garbage left over in video memory. */
+  grub_video_fill_rect (grub_video_map_rgb (0, 0, 0),
+                        view->screen.x, view->screen.y,
+                        view->screen.width, view->screen.height);
+  grub_video_swap_buffers ();
+  if (view->double_repaint)
+    grub_video_fill_rect (grub_video_map_rgb (0, 0, 0),
+                         view->screen.x, view->screen.y,
+                         view->screen.width, view->screen.height);
+
+  update_menu_components (view);
+
+  grub_gfxmenu_view_redraw (view, &view->screen);
+  grub_video_swap_buffers ();
+  if (view->double_repaint)
+    grub_gfxmenu_view_redraw (view, &view->screen);
+}
+
+static void
+redraw_menu_visit (grub_gui_component_t component,
+                   void *userdata)
+{
+  grub_gfxmenu_view_t view;
+  view = userdata;
+  if (component->ops->is_instance (component, "list"))
+    {
+      grub_gui_list_t list;
+      grub_video_rect_t bounds;
+
+      list = (grub_gui_list_t) component;
+      component->ops->get_bounds (component, &bounds);
+      grub_gfxmenu_view_redraw (view, &bounds);
+    }
+}
+
+void
+grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view)
+{
+  update_menu_components (view);
+
+  grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
+                                redraw_menu_visit, view);
+  grub_video_swap_buffers ();
+  if (view->double_repaint)
+    {
+      grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas,
+                                   redraw_menu_visit, view);
+    }
+}
+
+void 
+grub_gfxmenu_set_chosen_entry (int entry, void *data)
+{
+  grub_gfxmenu_view_t view = data;
+
+  view->selected = entry;
+  grub_gfxmenu_redraw_menu (view);
+}
+
+static void
+grub_gfxmenu_draw_terminal_box (void)
+{
+  grub_gfxmenu_box_t term_box;
+
+  term_box = term_view->terminal_box;
+  if (!term_box)
+    return;
+  
+  term_box->set_content_size (term_box, term_rect.width,
+                             term_rect.height);
+  
+  term_box->draw (term_box,
+                 term_rect.x - term_box->get_left_pad (term_box),
+                 term_rect.y - term_box->get_top_pad (term_box));
+  grub_video_swap_buffers ();
+  if (term_view->double_repaint)
+    term_box->draw (term_box,
+                   term_rect.x - term_box->get_left_pad (term_box),
+                   term_rect.y - term_box->get_top_pad (term_box));
+}
+
+static void
+init_terminal (grub_gfxmenu_view_t view)
+{
+  term_rect.width = view->screen.width * 7 / 10;
+  term_rect.height = view->screen.height * 7 / 10;
+
+  term_rect.x = view->screen.x + view->screen.width * (10 - 7) / 10 / 2;
+  term_rect.y = view->screen.y + view->screen.height * (10 - 7) / 10 / 2;
+
+  term_view = view;
+
+  /* Note: currently there is no API for changing the gfxterm font
+     on the fly, so whatever font the initially loaded theme specifies
+     will be permanent.  */
+  grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, term_rect.x,
+                          term_rect.y,
+                          term_rect.width, term_rect.height,
+                          view->double_repaint, view->terminal_font_name, 3);
+  grub_gfxterm_decorator_hook = grub_gfxmenu_draw_terminal_box;
+}
+
+/* FIXME: previously notifications were displayed in special case.
+   Is it necessary?
+ */
+#if 0
+/* Sets MESSAGE as the progress message for the view.
+   MESSAGE can be 0, in which case no message is displayed.  */
+static void
+set_progress_message (grub_gfxmenu_view_t view, const char *message)
+{
+  grub_free (view->progress_message_text);
+  if (message)
+    view->progress_message_text = grub_strdup (message);
+  else
+    view->progress_message_text = 0;
+}
+
+static void
+notify_booting (grub_menu_entry_t entry, void *userdata)
+{
+  grub_gfxmenu_view_t view = (grub_gfxmenu_view_t) userdata;
+
+  char *s = grub_malloc (100 + grub_strlen (entry->title));
+  if (!s)
+    return;
+
+  grub_sprintf (s, "Booting '%s'", entry->title);
+  set_progress_message (view, s);
+  grub_free (s);
+  grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
+  grub_video_swap_buffers ();
+  if (view->double_repaint)
+    grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
+}
+
+static void
+notify_fallback (grub_menu_entry_t entry, void *userdata)
+{
+  grub_gfxmenu_view_t view = (grub_gfxmenu_view_t) userdata;
+
+  char *s = grub_malloc (100 + grub_strlen (entry->title));
+  if (!s)
+    return;
+
+  grub_sprintf (s, "Falling back to '%s'", entry->title);
+  set_progress_message (view, s);
+  grub_free (s);
+  grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
+  grub_video_swap_buffers ();
+  if (view->double_repaint)
+    grub_gfxmenu_view_redraw (view, &view->progress_message_frame);
+}
+
+static void
+notify_execution_failure (void *userdata __attribute__ ((unused)))
+{
+}
+
+
+static struct grub_menu_execute_callback execute_callback =
+{
+  .notify_booting = notify_booting,
+  .notify_fallback = notify_fallback,
+  .notify_failure = notify_execution_failure
+};
+
+#endif
diff --git a/grub-core/gfxmenu/widget-box.c b/grub-core/gfxmenu/widget-box.c
new file mode 100644 (file)
index 0000000..079fd66
--- /dev/null
@@ -0,0 +1,313 @@
+/* widget_box.c - Pixmap-stylized box widget. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/video.h>
+#include <grub/bitmap.h>
+#include <grub/bitmap_scale.h>
+#include <grub/gfxwidgets.h>
+
+enum box_pixmaps
+{
+  BOX_PIXMAP_NW, BOX_PIXMAP_NE, BOX_PIXMAP_SE, BOX_PIXMAP_SW,
+  BOX_PIXMAP_N, BOX_PIXMAP_E, BOX_PIXMAP_S, BOX_PIXMAP_W,
+  BOX_PIXMAP_CENTER
+};
+
+static const char *box_pixmap_names[] = {
+  /* Corners: */
+  "nw", "ne", "se", "sw",
+  /* Sides: */
+  "n", "e", "s", "w",
+  /* Center: */
+  "c"
+};
+
+#define BOX_NUM_PIXMAPS (sizeof(box_pixmap_names)/sizeof(*box_pixmap_names))
+
+static int
+get_height (struct grub_video_bitmap *bitmap)
+{
+  if (bitmap)
+    return grub_video_bitmap_get_height (bitmap);
+  else
+    return 0;
+}
+
+static int
+get_width (struct grub_video_bitmap *bitmap)
+{
+  if (bitmap)
+    return grub_video_bitmap_get_width (bitmap);
+  else
+    return 0;
+}
+
+static void
+blit (grub_gfxmenu_box_t self, int pixmap_index, int x, int y)
+{
+  struct grub_video_bitmap *bitmap;
+  bitmap = self->scaled_pixmaps[pixmap_index];
+  if (! bitmap)
+    return;
+  grub_video_blit_bitmap (bitmap, GRUB_VIDEO_BLIT_BLEND,
+                          x, y, 0, 0,
+                          grub_video_bitmap_get_width (bitmap),
+                          grub_video_bitmap_get_height (bitmap));
+}
+
+static void
+draw (grub_gfxmenu_box_t self, int x, int y)
+{
+  int height_n;
+  int height_s;
+  int height_e;
+  int height_w;
+  int width_n;
+  int width_s;
+  int width_e;
+  int width_w;
+
+  height_n = get_height (self->scaled_pixmaps[BOX_PIXMAP_N]);
+  height_s = get_height (self->scaled_pixmaps[BOX_PIXMAP_S]);
+  height_e = get_height (self->scaled_pixmaps[BOX_PIXMAP_E]);
+  height_w = get_height (self->scaled_pixmaps[BOX_PIXMAP_W]);
+  width_n = get_width (self->scaled_pixmaps[BOX_PIXMAP_N]);
+  width_s = get_width (self->scaled_pixmaps[BOX_PIXMAP_S]);
+  width_e = get_width (self->scaled_pixmaps[BOX_PIXMAP_E]);
+  width_w = get_width (self->scaled_pixmaps[BOX_PIXMAP_W]);
+
+  /* Draw sides.  */
+  blit (self, BOX_PIXMAP_N, x + width_w, y);
+  blit (self, BOX_PIXMAP_S, x + width_w, y + height_n + self->content_height);
+  blit (self, BOX_PIXMAP_E, x + width_w + self->content_width, y + height_n);
+  blit (self, BOX_PIXMAP_W, x, y + height_n);
+
+  /* Draw corners.  */
+  blit (self, BOX_PIXMAP_NW, x, y);
+  blit (self, BOX_PIXMAP_NE, x + width_w + self->content_width, y);
+  blit (self, BOX_PIXMAP_SE,
+        x + width_w + self->content_width,
+        y + height_n + self->content_height);
+  blit (self, BOX_PIXMAP_SW, x, y + height_n + self->content_height);
+
+  /* Draw center.  */
+  blit (self, BOX_PIXMAP_CENTER, x + width_w, y + height_n);
+}
+
+static grub_err_t
+scale_pixmap (grub_gfxmenu_box_t self, int i, int w, int h)
+{
+  struct grub_video_bitmap **scaled = &self->scaled_pixmaps[i];
+  struct grub_video_bitmap *raw = self->raw_pixmaps[i];
+
+  if (raw == 0)
+    return grub_errno;
+
+  if (w == -1)
+    w = grub_video_bitmap_get_width (raw);
+  if (h == -1)
+    h = grub_video_bitmap_get_height (raw);
+
+  if (*scaled == 0
+      || ((int) grub_video_bitmap_get_width (*scaled) != w)
+      || ((int) grub_video_bitmap_get_height (*scaled) != h))
+    {
+      if (*scaled)
+        {
+          grub_video_bitmap_destroy (*scaled);
+          *scaled = 0;
+        }
+
+      /* Don't try to create a bitmap with a zero dimension.  */
+      if (w != 0 && h != 0)
+        grub_video_bitmap_create_scaled (scaled, w, h, raw,
+                                         GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
+      if (grub_errno != GRUB_ERR_NONE)
+        {
+          grub_error_push ();
+          grub_error (grub_errno,
+                      "failed to scale bitmap for styled box pixmap #%d", i);
+        }
+    }
+
+  return grub_errno;
+}
+
+static void
+set_content_size (grub_gfxmenu_box_t self,
+                  int width, int height)
+{
+  self->content_width = width;
+  self->content_height = height;
+
+  /* Resize sides to match the width and height.  */
+  /* It is assumed that the corners width/height match the adjacent sides.  */
+
+  /* Resize N and S sides to match width.  */
+  if (scale_pixmap(self, BOX_PIXMAP_N, width, -1) != GRUB_ERR_NONE)
+    return;
+  if (scale_pixmap(self, BOX_PIXMAP_S, width, -1) != GRUB_ERR_NONE)
+    return;
+
+  /* Resize E and W sides to match height.  */
+  if (scale_pixmap(self, BOX_PIXMAP_E, -1, height) != GRUB_ERR_NONE)
+      return;
+  if (scale_pixmap(self, BOX_PIXMAP_W, -1, height) != GRUB_ERR_NONE)
+    return;
+
+  /* Don't scale the corners--they are assumed to match the sides. */
+  if (scale_pixmap(self, BOX_PIXMAP_NW, -1, -1) != GRUB_ERR_NONE)
+    return;
+  if (scale_pixmap(self, BOX_PIXMAP_SW, -1, -1) != GRUB_ERR_NONE)
+    return;
+  if (scale_pixmap(self, BOX_PIXMAP_NE, -1, -1) != GRUB_ERR_NONE)
+    return;
+  if (scale_pixmap(self, BOX_PIXMAP_SE, -1, -1) != GRUB_ERR_NONE)
+    return;
+
+  /* Scale the center area. */
+  if (scale_pixmap(self, BOX_PIXMAP_CENTER, width, height) != GRUB_ERR_NONE)
+    return;
+}
+
+static int
+get_left_pad (grub_gfxmenu_box_t self)
+{
+  return get_width (self->raw_pixmaps[BOX_PIXMAP_W]);
+}
+
+static int
+get_top_pad (grub_gfxmenu_box_t self)
+{
+  return get_height (self->raw_pixmaps[BOX_PIXMAP_N]);
+}
+
+static int
+get_right_pad (grub_gfxmenu_box_t self)
+{
+  return get_width (self->raw_pixmaps[BOX_PIXMAP_E]);
+}
+
+static int
+get_bottom_pad (grub_gfxmenu_box_t self)
+{
+  return get_height (self->raw_pixmaps[BOX_PIXMAP_S]);
+}
+
+static void
+destroy (grub_gfxmenu_box_t self)
+{
+  unsigned i;
+  for (i = 0; i < BOX_NUM_PIXMAPS; i++)
+    {
+      if (self->raw_pixmaps[i])
+        grub_video_bitmap_destroy(self->raw_pixmaps[i]);
+      self->raw_pixmaps[i] = 0;
+
+      if (self->scaled_pixmaps[i])
+        grub_video_bitmap_destroy(self->scaled_pixmaps[i]);
+      self->scaled_pixmaps[i] = 0;
+    }
+  grub_free (self->raw_pixmaps);
+  self->raw_pixmaps = 0;
+  grub_free (self->scaled_pixmaps);
+  self->scaled_pixmaps = 0;
+
+  /* Free self:  must be the last step!  */
+  grub_free (self);
+}
+
+
+/* Create a new box.  If PIXMAPS_PREFIX and PIXMAPS_SUFFIX are both non-null,
+   then an attempt is made to load the north, south, east, west, northwest,
+   northeast, southeast, southwest, and center pixmaps.
+   If either PIXMAPS_PREFIX or PIXMAPS_SUFFIX is 0, then no pixmaps are
+   loaded, and the box has zero-width borders and is drawn transparent.  */
+grub_gfxmenu_box_t
+grub_gfxmenu_create_box (const char *pixmaps_prefix,
+                         const char *pixmaps_suffix)
+{
+  unsigned i;
+  grub_gfxmenu_box_t box;
+
+  box = (grub_gfxmenu_box_t) grub_malloc (sizeof (*box));
+  if (! box)
+    return 0;
+
+  box->content_width = 0;
+  box->content_height = 0;
+  box->raw_pixmaps =
+    (struct grub_video_bitmap **)
+    grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *));
+  box->scaled_pixmaps =
+    (struct grub_video_bitmap **)
+    grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *));
+
+  /* Initialize all pixmap pointers to NULL so that proper destruction can
+     be performed if an error is encountered partway through construction.  */
+  for (i = 0; i < BOX_NUM_PIXMAPS; i++)
+      box->raw_pixmaps[i] = 0;
+  for (i = 0; i < BOX_NUM_PIXMAPS; i++)
+      box->scaled_pixmaps[i] = 0;
+
+  /* Load the pixmaps.  */
+  for (i = 0; i < BOX_NUM_PIXMAPS; i++)
+    {
+      if (pixmaps_prefix && pixmaps_suffix)
+        {
+          char *path;
+          char *path_end;
+
+          path = grub_malloc (grub_strlen (pixmaps_prefix)
+                              + grub_strlen (box_pixmap_names[i])
+                              + grub_strlen (pixmaps_suffix)
+                              + 1);
+          if (! path)
+            goto fail_and_destroy;
+
+          /* Construct the specific path for this pixmap.  */
+          path_end = grub_stpcpy (path, pixmaps_prefix);
+          path_end = grub_stpcpy (path_end, box_pixmap_names[i]);
+          path_end = grub_stpcpy (path_end, pixmaps_suffix);
+
+          grub_video_bitmap_load (&box->raw_pixmaps[i], path);
+          grub_free (path);
+
+          /* Ignore missing pixmaps.  */
+          grub_errno = GRUB_ERR_NONE;
+        }
+    }
+
+  box->draw = draw;
+  box->set_content_size = set_content_size;
+  box->get_left_pad = get_left_pad;
+  box->get_top_pad = get_top_pad;
+  box->get_right_pad = get_right_pad;
+  box->get_bottom_pad = get_bottom_pad;
+  box->destroy = destroy;
+  return box;
+
+fail_and_destroy:
+  destroy (box);
+  return 0;
+}
diff --git a/grub-core/gnulib/alloca.h b/grub-core/gnulib/alloca.h
new file mode 100644 (file)
index 0000000..107534e
--- /dev/null
@@ -0,0 +1,56 @@
+/* Memory allocation on the stack.
+
+   Copyright (C) 1995, 1999, 2001-2004, 2006-2010 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+   USA.  */
+
+/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H
+   means there is a real alloca function.  */
+#ifndef _GL_ALLOCA_H
+#define _GL_ALLOCA_H
+
+/* alloca (N) returns a pointer to N bytes of memory
+   allocated on the stack, which will last until the function returns.
+   Use of alloca should be avoided:
+     - inside arguments of function calls - undefined behaviour,
+     - in inline functions - the allocation may actually last until the
+       calling function returns,
+     - for huge N (say, N >= 65536) - you never know how large (or small)
+       the stack is, and when the stack cannot fulfill the memory allocation
+       request, the program just crashes.
+ */
+
+#ifndef alloca
+# ifdef __GNUC__
+#  define alloca __builtin_alloca
+# elif defined _AIX
+#  define alloca __alloca
+# elif defined _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# elif defined __DECC && defined __VMS
+#  define alloca __ALLOCA
+# else
+#  include <stddef.h>
+#  ifdef  __cplusplus
+extern "C"
+#  endif
+void *alloca (size_t);
+# endif
+#endif
+
+#endif /* _GL_ALLOCA_H */
diff --git a/grub-core/gnulib/argp-ba.c b/grub-core/gnulib/argp-ba.c
new file mode 100644 (file)
index 0000000..95feabb
--- /dev/null
@@ -0,0 +1,34 @@
+/* Default definition for ARGP_PROGRAM_BUG_ADDRESS.
+   Copyright (C) 1996, 1997, 1999, 2009, 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+/* If set by the user program, it should point to string that is the
+   bug-reporting address for the program.  It will be printed by argp_help if
+   the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help
+   messages), embedded in a sentence that says something like `Report bugs to
+   ADDR.'.  */
+const char *argp_program_bug_address
+/* This variable should be zero-initialized.  On most systems, putting it into
+   BSS is sufficient.  Not so on MacOS X 10.3 and 10.4, see
+   <http://lists.gnu.org/archive/html/bug-gnulib/2009-01/msg00329.html>
+   <http://lists.gnu.org/archive/html/bug-gnulib/2009-08/msg00096.html>.  */
+#if defined __ELF__
+  /* On ELF systems, variables in BSS behave well.  */
+#else
+  = (const char *) 0
+#endif
+  ;
diff --git a/grub-core/gnulib/argp-eexst.c b/grub-core/gnulib/argp-eexst.c
new file mode 100644 (file)
index 0000000..115a8cd
--- /dev/null
@@ -0,0 +1,30 @@
+/* Default definition for ARGP_ERR_EXIT_STATUS
+   Copyright (C) 1997, 2009, 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sysexits.h>
+
+#include "argp.h"
+
+/* The exit status that argp will use when exiting due to a parsing error.
+   If not defined or set by the user program, this defaults to EX_USAGE from
+   <sysexits.h>.  */
+error_t argp_err_exit_status = EX_USAGE;
diff --git a/grub-core/gnulib/argp-fmtstream.c b/grub-core/gnulib/argp-fmtstream.c
new file mode 100644 (file)
index 0000000..70bbebc
--- /dev/null
@@ -0,0 +1,435 @@
+/* Word-wrapping and line-truncating streams
+   Copyright (C) 1997-1999, 2001-2003, 2005, 2009-2010 Free Software
+   Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+/* This package emulates glibc `line_wrap_stream' semantics for systems that
+   don't have that.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#include "argp-fmtstream.h"
+#include "argp-namefrob.h"
+
+#ifndef ARGP_FMTSTREAM_USE_LINEWRAP
+
+#ifndef isblank
+#define isblank(ch) ((ch)==' ' || (ch)=='\t')
+#endif
+
+#if defined _LIBC && defined USE_IN_LIBIO
+# include <wchar.h>
+# include <libio/libioP.h>
+# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
+#endif
+
+#define INIT_BUF_SIZE 200
+#define PRINTF_SIZE_GUESS 150
+\f
+/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
+   written on it with LMARGIN spaces and limits them to RMARGIN columns
+   total.  If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
+   replacing the whitespace before them with a newline and WMARGIN spaces.
+   Otherwise, chars beyond RMARGIN are simply dropped until a newline.
+   Returns NULL if there was an error.  */
+argp_fmtstream_t
+__argp_make_fmtstream (FILE *stream,
+                       size_t lmargin, size_t rmargin, ssize_t wmargin)
+{
+  argp_fmtstream_t fs;
+
+  fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream));
+  if (fs != NULL)
+    {
+      fs->stream = stream;
+
+      fs->lmargin = lmargin;
+      fs->rmargin = rmargin;
+      fs->wmargin = wmargin;
+      fs->point_col = 0;
+      fs->point_offs = 0;
+
+      fs->buf = (char *) malloc (INIT_BUF_SIZE);
+      if (! fs->buf)
+        {
+          free (fs);
+          fs = 0;
+        }
+      else
+        {
+          fs->p = fs->buf;
+          fs->end = fs->buf + INIT_BUF_SIZE;
+        }
+    }
+
+  return fs;
+}
+#if 0
+/* Not exported.  */
+#ifdef weak_alias
+weak_alias (__argp_make_fmtstream, argp_make_fmtstream)
+#endif
+#endif
+
+/* Flush FS to its stream, and free it (but don't close the stream).  */
+void
+__argp_fmtstream_free (argp_fmtstream_t fs)
+{
+  __argp_fmtstream_update (fs);
+  if (fs->p > fs->buf)
+    {
+#ifdef USE_IN_LIBIO
+      __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
+#else
+      fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
+#endif
+    }
+  free (fs->buf);
+  free (fs);
+}
+#if 0
+/* Not exported.  */
+#ifdef weak_alias
+weak_alias (__argp_fmtstream_free, argp_fmtstream_free)
+#endif
+#endif
+\f
+/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the
+   end of its buffer.  This code is mostly from glibc stdio/linewrap.c.  */
+void
+__argp_fmtstream_update (argp_fmtstream_t fs)
+{
+  char *buf, *nl;
+  size_t len;
+
+  /* Scan the buffer for newlines.  */
+  buf = fs->buf + fs->point_offs;
+  while (buf < fs->p)
+    {
+      size_t r;
+
+      if (fs->point_col == 0 && fs->lmargin != 0)
+        {
+          /* We are starting a new line.  Print spaces to the left margin.  */
+          const size_t pad = fs->lmargin;
+          if (fs->p + pad < fs->end)
+            {
+              /* We can fit in them in the buffer by moving the
+                 buffer text up and filling in the beginning.  */
+              memmove (buf + pad, buf, fs->p - buf);
+              fs->p += pad; /* Compensate for bigger buffer. */
+              memset (buf, ' ', pad); /* Fill in the spaces.  */
+              buf += pad; /* Don't bother searching them.  */
+            }
+          else
+            {
+              /* No buffer space for spaces.  Must flush.  */
+              size_t i;
+              for (i = 0; i < pad; i++)
+                {
+#ifdef USE_IN_LIBIO
+                  if (_IO_fwide (fs->stream, 0) > 0)
+                    putwc_unlocked (L' ', fs->stream);
+                  else
+#endif
+                    putc_unlocked (' ', fs->stream);
+                }
+            }
+          fs->point_col = pad;
+        }
+
+      len = fs->p - buf;
+      nl = memchr (buf, '\n', len);
+
+      if (fs->point_col < 0)
+        fs->point_col = 0;
+
+      if (!nl)
+        {
+          /* The buffer ends in a partial line.  */
+
+          if (fs->point_col + len < fs->rmargin)
+            {
+              /* The remaining buffer text is a partial line and fits
+                 within the maximum line width.  Advance point for the
+                 characters to be written and stop scanning.  */
+              fs->point_col += len;
+              break;
+            }
+          else
+            /* Set the end-of-line pointer for the code below to
+               the end of the buffer.  */
+            nl = fs->p;
+        }
+      else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin)
+        {
+          /* The buffer contains a full line that fits within the maximum
+             line width.  Reset point and scan the next line.  */
+          fs->point_col = 0;
+          buf = nl + 1;
+          continue;
+        }
+
+      /* This line is too long.  */
+      r = fs->rmargin - 1;
+
+      if (fs->wmargin < 0)
+        {
+          /* Truncate the line by overwriting the excess with the
+             newline and anything after it in the buffer.  */
+          if (nl < fs->p)
+            {
+              memmove (buf + (r - fs->point_col), nl, fs->p - nl);
+              fs->p -= buf + (r - fs->point_col) - nl;
+              /* Reset point for the next line and start scanning it.  */
+              fs->point_col = 0;
+              buf += r + 1; /* Skip full line plus \n. */
+            }
+          else
+            {
+              /* The buffer ends with a partial line that is beyond the
+                 maximum line width.  Advance point for the characters
+                 written, and discard those past the max from the buffer.  */
+              fs->point_col += len;
+              fs->p -= fs->point_col - r;
+              break;
+            }
+        }
+      else
+        {
+          /* Do word wrap.  Go to the column just past the maximum line
+             width and scan back for the beginning of the word there.
+             Then insert a line break.  */
+
+          char *p, *nextline;
+          int i;
+
+          p = buf + (r + 1 - fs->point_col);
+          while (p >= buf && !isblank ((unsigned char) *p))
+            --p;
+          nextline = p + 1;     /* This will begin the next line.  */
+
+          if (nextline > buf)
+            {
+              /* Swallow separating blanks.  */
+              if (p >= buf)
+                do
+                  --p;
+                while (p >= buf && isblank ((unsigned char) *p));
+              nl = p + 1;       /* The newline will replace the first blank. */
+            }
+          else
+            {
+              /* A single word that is greater than the maximum line width.
+                 Oh well.  Put it on an overlong line by itself.  */
+              p = buf + (r + 1 - fs->point_col);
+              /* Find the end of the long word.  */
+              if (p < nl)
+                do
+                  ++p;
+                while (p < nl && !isblank ((unsigned char) *p));
+              if (p == nl)
+                {
+                  /* It already ends a line.  No fussing required.  */
+                  fs->point_col = 0;
+                  buf = nl + 1;
+                  continue;
+                }
+              /* We will move the newline to replace the first blank.  */
+              nl = p;
+              /* Swallow separating blanks.  */
+              do
+                ++p;
+              while (isblank ((unsigned char) *p));
+              /* The next line will start here.  */
+              nextline = p;
+            }
+
+          /* Note: There are a bunch of tests below for
+             NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall
+             at the end of the buffer, and NEXTLINE is in fact empty (and so
+             we need not be careful to maintain its contents).  */
+
+          if ((nextline == buf + len + 1
+               ? fs->end - nl < fs->wmargin + 1
+               : nextline - (nl + 1) < fs->wmargin)
+              && fs->p > nextline)
+            {
+              /* The margin needs more blanks than we removed.  */
+              if (fs->end - fs->p > fs->wmargin + 1)
+                /* Make some space for them.  */
+                {
+                  size_t mv = fs->p - nextline;
+                  memmove (nl + 1 + fs->wmargin, nextline, mv);
+                  nextline = nl + 1 + fs->wmargin;
+                  len = nextline + mv - buf;
+                  *nl++ = '\n';
+                }
+              else
+                /* Output the first line so we can use the space.  */
+                {
+#ifdef _LIBC
+                  __fxprintf (fs->stream, "%.*s\n",
+                              (int) (nl - fs->buf), fs->buf);
+#else
+                  if (nl > fs->buf)
+                    fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream);
+                  putc_unlocked ('\n', fs->stream);
+#endif
+
+                  len += buf - fs->buf;
+                  nl = buf = fs->buf;
+                }
+            }
+          else
+            /* We can fit the newline and blanks in before
+               the next word.  */
+            *nl++ = '\n';
+
+          if (nextline - nl >= fs->wmargin
+              || (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin))
+            /* Add blanks up to the wrap margin column.  */
+            for (i = 0; i < fs->wmargin; ++i)
+              *nl++ = ' ';
+          else
+            for (i = 0; i < fs->wmargin; ++i)
+#ifdef USE_IN_LIBIO
+              if (_IO_fwide (fs->stream, 0) > 0)
+                putwc_unlocked (L' ', fs->stream);
+              else
+#endif
+                putc_unlocked (' ', fs->stream);
+
+          /* Copy the tail of the original buffer into the current buffer
+             position.  */
+          if (nl < nextline)
+            memmove (nl, nextline, buf + len - nextline);
+          len -= nextline - buf;
+
+          /* Continue the scan on the remaining lines in the buffer.  */
+          buf = nl;
+
+          /* Restore bufp to include all the remaining text.  */
+          fs->p = nl + len;
+
+          /* Reset the counter of what has been output this line.  If wmargin
+             is 0, we want to avoid the lmargin getting added, so we set
+             point_col to a magic value of -1 in that case.  */
+          fs->point_col = fs->wmargin ? fs->wmargin : -1;
+        }
+    }
+
+  /* Remember that we've scanned as far as the end of the buffer.  */
+  fs->point_offs = fs->p - fs->buf;
+}
+\f
+/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by
+   growing the buffer, or by flushing it.  True is returned iff we succeed. */
+int
+__argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
+{
+  if ((size_t) (fs->end - fs->p) < amount)
+    {
+      ssize_t wrote;
+
+      /* Flush FS's buffer.  */
+      __argp_fmtstream_update (fs);
+
+#ifdef _LIBC
+      __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
+      wrote = fs->p - fs->buf;
+#else
+      wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
+#endif
+      if (wrote == fs->p - fs->buf)
+        {
+          fs->p = fs->buf;
+          fs->point_offs = 0;
+        }
+      else
+        {
+          fs->p -= wrote;
+          fs->point_offs -= wrote;
+          memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf);
+          return 0;
+        }
+
+      if ((size_t) (fs->end - fs->buf) < amount)
+        /* Gotta grow the buffer.  */
+        {
+          size_t old_size = fs->end - fs->buf;
+          size_t new_size = old_size + amount;
+          char *new_buf;
+
+          if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size)))
+            {
+              __set_errno (ENOMEM);
+              return 0;
+            }
+
+          fs->buf = new_buf;
+          fs->end = new_buf + new_size;
+          fs->p = fs->buf;
+        }
+    }
+
+  return 1;
+}
+\f
+ssize_t
+__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...)
+{
+  int out;
+  size_t avail;
+  size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */
+
+  do
+    {
+      va_list args;
+
+      if (! __argp_fmtstream_ensure (fs, size_guess))
+        return -1;
+
+      va_start (args, fmt);
+      avail = fs->end - fs->p;
+      out = __vsnprintf (fs->p, avail, fmt, args);
+      va_end (args);
+      if ((size_t) out >= avail)
+        size_guess = out + 1;
+    }
+  while ((size_t) out >= avail);
+
+  fs->p += out;
+
+  return out;
+}
+#if 0
+/* Not exported.  */
+#ifdef weak_alias
+weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf)
+#endif
+#endif
+
+#endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */
diff --git a/grub-core/gnulib/argp-fmtstream.h b/grub-core/gnulib/argp-fmtstream.h
new file mode 100644 (file)
index 0000000..b913d1b
--- /dev/null
@@ -0,0 +1,354 @@
+/* Word-wrapping and line-truncating streams.
+   Copyright (C) 1997, 2006-2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+/* This package emulates glibc `line_wrap_stream' semantics for systems that
+   don't have that.  If the system does have it, it is just a wrapper for
+   that.  This header file is only used internally while compiling argp, and
+   shouldn't be installed.  */
+
+#ifndef _ARGP_FMTSTREAM_H
+#define _ARGP_FMTSTREAM_H
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifndef __attribute__
+/* The __attribute__ feature is available in gcc versions 2.5 and later.
+   The __-protected variants of the attributes 'format' and 'printf' are
+   accepted by gcc versions 2.6.4 (effectively 2.7) and later.
+   We enable __attribute__ only if these are supported too, because
+   gnulib and libintl do '#define printf __printf__' when they override
+   the 'printf' function.  */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
+#  define __attribute__(Spec)   /* empty */
+# endif
+#endif
+
+#if    (_LIBC - 0 && !defined (USE_IN_LIBIO)) \
+    || (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H))
+/* line_wrap_stream is available, so use that.  */
+#define ARGP_FMTSTREAM_USE_LINEWRAP
+#endif
+
+#ifdef ARGP_FMTSTREAM_USE_LINEWRAP
+/* Just be a simple wrapper for line_wrap_stream; the semantics are
+   *slightly* different, as line_wrap_stream doesn't actually make a new
+   object, it just modifies the given stream (reversibly) to do
+   line-wrapping.  Since we control who uses this code, it doesn't matter.  */
+
+#include <linewrap.h>
+
+typedef FILE *argp_fmtstream_t;
+
+#define argp_make_fmtstream line_wrap_stream
+#define __argp_make_fmtstream line_wrap_stream
+#define argp_fmtstream_free line_unwrap_stream
+#define __argp_fmtstream_free line_unwrap_stream
+
+#define __argp_fmtstream_putc(fs,ch) putc(ch,fs)
+#define argp_fmtstream_putc(fs,ch) putc(ch,fs)
+#define __argp_fmtstream_puts(fs,str) fputs(str,fs)
+#define argp_fmtstream_puts(fs,str) fputs(str,fs)
+#define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
+#define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
+#define __argp_fmtstream_printf fprintf
+#define argp_fmtstream_printf fprintf
+
+#define __argp_fmtstream_lmargin line_wrap_lmargin
+#define argp_fmtstream_lmargin line_wrap_lmargin
+#define __argp_fmtstream_set_lmargin line_wrap_set_lmargin
+#define argp_fmtstream_set_lmargin line_wrap_set_lmargin
+#define __argp_fmtstream_rmargin line_wrap_rmargin
+#define argp_fmtstream_rmargin line_wrap_rmargin
+#define __argp_fmtstream_set_rmargin line_wrap_set_rmargin
+#define argp_fmtstream_set_rmargin line_wrap_set_rmargin
+#define __argp_fmtstream_wmargin line_wrap_wmargin
+#define argp_fmtstream_wmargin line_wrap_wmargin
+#define __argp_fmtstream_set_wmargin line_wrap_set_wmargin
+#define argp_fmtstream_set_wmargin line_wrap_set_wmargin
+#define __argp_fmtstream_point line_wrap_point
+#define argp_fmtstream_point line_wrap_point
+
+#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */
+/* Guess we have to define our own version.  */
+\f
+struct argp_fmtstream
+{
+  FILE *stream;                 /* The stream we're outputting to.  */
+
+  size_t lmargin, rmargin;      /* Left and right margins.  */
+  ssize_t wmargin;              /* Margin to wrap to, or -1 to truncate.  */
+
+  /* Point in buffer to which we've processed for wrapping, but not output.  */
+  size_t point_offs;
+  /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin.  */
+  ssize_t point_col;
+
+  char *buf;                    /* Output buffer.  */
+  char *p;                      /* Current end of text in BUF. */
+  char *end;                    /* Absolute end of BUF.  */
+};
+
+typedef struct argp_fmtstream *argp_fmtstream_t;
+
+/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
+   written on it with LMARGIN spaces and limits them to RMARGIN columns
+   total.  If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
+   replacing the whitespace before them with a newline and WMARGIN spaces.
+   Otherwise, chars beyond RMARGIN are simply dropped until a newline.
+   Returns NULL if there was an error.  */
+extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream,
+                                               size_t __lmargin,
+                                               size_t __rmargin,
+                                               ssize_t __wmargin);
+extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream,
+                                             size_t __lmargin,
+                                             size_t __rmargin,
+                                             ssize_t __wmargin);
+
+/* Flush __FS to its stream, and free it (but don't close the stream).  */
+extern void __argp_fmtstream_free (argp_fmtstream_t __fs);
+extern void argp_fmtstream_free (argp_fmtstream_t __fs);
+
+extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs,
+                                        const char *__fmt, ...)
+     __attribute__ ((__format__ (printf, 2, 3)));
+extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs,
+                                      const char *__fmt, ...)
+     __attribute__ ((__format__ (printf, 2, 3)));
+
+#if _LIBC || !defined __OPTIMIZE__
+extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
+extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
+
+extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str);
+extern int argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str);
+
+extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs,
+                                      const char *__str, size_t __len);
+extern size_t argp_fmtstream_write (argp_fmtstream_t __fs,
+                                    const char *__str, size_t __len);
+#endif
+\f
+/* Access macros for various bits of state.  */
+#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin)
+#define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin)
+#define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin)
+#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
+#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
+#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
+
+#if _LIBC || !defined __OPTIMIZE__
+/* Set __FS's left margin to LMARGIN and return the old value.  */
+extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
+                                          size_t __lmargin);
+extern size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
+                                            size_t __lmargin);
+
+/* Set __FS's right margin to __RMARGIN and return the old value.  */
+extern size_t argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
+                                          size_t __rmargin);
+extern size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
+                                            size_t __rmargin);
+
+/* Set __FS's wrap margin to __WMARGIN and return the old value.  */
+extern size_t argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
+                                          size_t __wmargin);
+extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
+                                            size_t __wmargin);
+
+/* Return the column number of the current output point in __FS.  */
+extern size_t argp_fmtstream_point (argp_fmtstream_t __fs);
+extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs);
+#endif
+
+/* Internal routines.  */
+extern void _argp_fmtstream_update (argp_fmtstream_t __fs);
+extern void __argp_fmtstream_update (argp_fmtstream_t __fs);
+extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
+extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
+\f
+#ifdef __OPTIMIZE__
+/* Inline versions of above routines.  */
+
+#if !_LIBC
+#define __argp_fmtstream_putc argp_fmtstream_putc
+#define __argp_fmtstream_puts argp_fmtstream_puts
+#define __argp_fmtstream_write argp_fmtstream_write
+#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
+#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
+#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
+#define __argp_fmtstream_point argp_fmtstream_point
+#define __argp_fmtstream_update _argp_fmtstream_update
+#define __argp_fmtstream_ensure _argp_fmtstream_ensure
+#endif
+
+#ifndef ARGP_FS_EI
+# ifdef __GNUC__
+   /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
+      inline semantics, unless -fgnu89-inline is used.  It defines a macro
+      __GNUC_STDC_INLINE__ to indicate this situation or a macro
+      __GNUC_GNU_INLINE__ to indicate the opposite situation.
+
+      GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline
+      semantics but warns, unless -fgnu89-inline is used:
+        warning: C99 inline functions are not supported; using GNU89
+        warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute
+      It defines a macro __GNUC_GNU_INLINE__ to indicate this situation.
+
+      Whereas Apple GCC 4.0.1 build 5479 without -std=c99 or -std=gnu99
+      implements the GNU C inline semantics and defines the macro
+      __GNUC_GNU_INLINE__, but it does not warn and does not support
+      __attribute__ ((__gnu_inline__)).
+
+      All in all, these are the possible combinations.  For every compiler,
+      we need to choose ARGP_FS_EI so that the corresponding table cell
+      contains an "ok".
+
+        \    ARGP_FS_EI                      inline   extern    extern
+          \                                           inline    inline
+      CC    \                                                   __attribute__
+                                                                ((gnu_inline))
+
+      gcc 4.3.0                              error    ok        ok
+      gcc 4.3.0 -std=gnu99 -fgnu89-inline    error    ok        ok
+      gcc 4.3.0 -std=gnu99                   ok       error     ok
+
+      gcc 4.2.2                              error    ok        ok
+      gcc 4.2.2 -std=gnu99 -fgnu89-inline    error    ok        ok
+      gcc 4.2.2 -std=gnu99                   error    warning   ok
+
+      gcc 4.1.2                              error    ok        warning
+      gcc 4.1.2 -std=gnu99                   error    ok        warning
+
+      Apple gcc 4.0.1                        error    ok        warning
+      Apple gcc 4.0.1 -std=gnu99             ok       error     warning
+    */
+#  if defined __GNUC_STDC_INLINE__
+#   define ARGP_FS_EI inline
+#  elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)
+#   define ARGP_FS_EI extern inline __attribute__ ((__gnu_inline__))
+#  else
+#   define ARGP_FS_EI extern inline
+#  endif
+# else
+   /* With other compilers, assume the ISO C99 meaning of 'inline', if
+      the compiler supports 'inline' at all.  */
+#  define ARGP_FS_EI inline
+# endif
+#endif
+
+ARGP_FS_EI size_t
+__argp_fmtstream_write (argp_fmtstream_t __fs,
+                        const char *__str, size_t __len)
+{
+  if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
+    {
+      memcpy (__fs->p, __str, __len);
+      __fs->p += __len;
+      return __len;
+    }
+  else
+    return 0;
+}
+
+ARGP_FS_EI int
+__argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str)
+{
+  size_t __len = strlen (__str);
+  if (__len)
+    {
+      size_t __wrote = __argp_fmtstream_write (__fs, __str, __len);
+      return __wrote == __len ? 0 : -1;
+    }
+  else
+    return 0;
+}
+
+ARGP_FS_EI int
+__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch)
+{
+  if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1))
+    return *__fs->p++ = __ch;
+  else
+    return EOF;
+}
+
+/* Set __FS's left margin to __LMARGIN and return the old value.  */
+ARGP_FS_EI size_t
+__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin)
+{
+  size_t __old;
+  if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
+    __argp_fmtstream_update (__fs);
+  __old = __fs->lmargin;
+  __fs->lmargin = __lmargin;
+  return __old;
+}
+
+/* Set __FS's right margin to __RMARGIN and return the old value.  */
+ARGP_FS_EI size_t
+__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin)
+{
+  size_t __old;
+  if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
+    __argp_fmtstream_update (__fs);
+  __old = __fs->rmargin;
+  __fs->rmargin = __rmargin;
+  return __old;
+}
+
+/* Set FS's wrap margin to __WMARGIN and return the old value.  */
+ARGP_FS_EI size_t
+__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
+{
+  size_t __old;
+  if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
+    __argp_fmtstream_update (__fs);
+  __old = __fs->wmargin;
+  __fs->wmargin = __wmargin;
+  return __old;
+}
+
+/* Return the column number of the current output point in __FS.  */
+ARGP_FS_EI size_t
+__argp_fmtstream_point (argp_fmtstream_t __fs)
+{
+  if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
+    __argp_fmtstream_update (__fs);
+  return __fs->point_col >= 0 ? __fs->point_col : 0;
+}
+
+#if !_LIBC
+#undef __argp_fmtstream_putc
+#undef __argp_fmtstream_puts
+#undef __argp_fmtstream_write
+#undef __argp_fmtstream_set_lmargin
+#undef __argp_fmtstream_set_rmargin
+#undef __argp_fmtstream_set_wmargin
+#undef __argp_fmtstream_point
+#undef __argp_fmtstream_update
+#undef __argp_fmtstream_ensure
+#endif
+
+#endif /* __OPTIMIZE__ */
+
+#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */
+
+#endif /* argp-fmtstream.h */
diff --git a/grub-core/gnulib/argp-fs-xinl.c b/grub-core/gnulib/argp-fs-xinl.c
new file mode 100644 (file)
index 0000000..2c683f9
--- /dev/null
@@ -0,0 +1,42 @@
+/* Real definitions for extern inline functions in argp-fmtstream.h
+   Copyright (C) 1997, 2003, 2004, 2009, 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define ARGP_FS_EI
+#undef __OPTIMIZE__
+#define __OPTIMIZE__ 1
+#include "argp-fmtstream.h"
+
+#if 0
+/* Not exported.  */
+/* Add weak aliases.  */
+#if _LIBC - 0 && !defined (ARGP_FMTSTREAM_USE_LINEWRAP) && defined (weak_alias)
+
+weak_alias (__argp_fmtstream_putc, argp_fmtstream_putc)
+weak_alias (__argp_fmtstream_puts, argp_fmtstream_puts)
+weak_alias (__argp_fmtstream_write, argp_fmtstream_write)
+weak_alias (__argp_fmtstream_set_lmargin, argp_fmtstream_set_lmargin)
+weak_alias (__argp_fmtstream_set_rmargin, argp_fmtstream_set_rmargin)
+weak_alias (__argp_fmtstream_set_wmargin, argp_fmtstream_set_wmargin)
+weak_alias (__argp_fmtstream_point, argp_fmtstream_point)
+
+#endif
+#endif
diff --git a/grub-core/gnulib/argp-help.c b/grub-core/gnulib/argp-help.c
new file mode 100644 (file)
index 0000000..5b6d950
--- /dev/null
@@ -0,0 +1,1951 @@
+/* Hierarchial argument parsing help output
+   Copyright (C) 1995-2005, 2007, 2009-2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE    1
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <alloca.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <limits.h>
+#ifdef USE_IN_LIBIO
+# include <wchar.h>
+#endif
+
+#ifdef _LIBC
+# include <libintl.h>
+# undef dgettext
+# define dgettext(domain, msgid) \
+   INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
+#else
+# include "gettext.h"
+#endif
+
+#include "argp.h"
+#include "argp-fmtstream.h"
+#include "argp-namefrob.h"
+
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+\f
+/* User-selectable (using an environment variable) formatting parameters.
+
+   These may be specified in an environment variable called `ARGP_HELP_FMT',
+   with a contents like:  VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2
+   Where VALn must be a positive integer.  The list of variables is in the
+   UPARAM_NAMES vector, below.  */
+
+/* Default parameters.  */
+#define DUP_ARGS      0         /* True if option argument can be duplicated. */
+#define DUP_ARGS_NOTE 1         /* True to print a note about duplicate args. */
+#define SHORT_OPT_COL 2         /* column in which short options start */
+#define LONG_OPT_COL  6         /* column in which long options start */
+#define DOC_OPT_COL   2         /* column in which doc options start */
+#define OPT_DOC_COL  29         /* column in which option text starts */
+#define HEADER_COL    1         /* column in which group headers are printed */
+#define USAGE_INDENT 12         /* indentation of wrapped usage lines */
+#define RMARGIN      79         /* right margin used for wrapping */
+
+/* User-selectable (using an environment variable) formatting parameters.
+   They must all be of type `int' for the parsing code to work.  */
+struct uparams
+{
+  /* If true, arguments for an option are shown with both short and long
+     options, even when a given option has both, e.g. `-x ARG, --longx=ARG'.
+     If false, then if an option has both, the argument is only shown with
+     the long one, e.g., `-x, --longx=ARG', and a message indicating that
+     this really means both is printed below the options.  */
+  int dup_args;
+
+  /* This is true if when DUP_ARGS is false, and some duplicate arguments have
+     been suppressed, an explanatory message should be printed.  */
+  int dup_args_note;
+
+  /* Various output columns.  */
+  int short_opt_col;      /* column in which short options start */
+  int long_opt_col;       /* column in which long options start */
+  int doc_opt_col;        /* column in which doc options start */
+  int opt_doc_col;        /* column in which option text starts */
+  int header_col;         /* column in which group headers are printed */
+  int usage_indent;       /* indentation of wrapped usage lines */
+  int rmargin;            /* right margin used for wrapping */
+
+  int valid;              /* True when the values in here are valid.  */
+};
+
+/* This is a global variable, as user options are only ever read once.  */
+static struct uparams uparams = {
+  DUP_ARGS, DUP_ARGS_NOTE,
+  SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL,
+  USAGE_INDENT, RMARGIN,
+  0
+};
+
+/* A particular uparam, and what the user name is.  */
+struct uparam_name
+{
+  const char *name;             /* User name.  */
+  int is_bool;                  /* Whether it's `boolean'.  */
+  size_t uparams_offs;          /* Location of the (int) field in UPARAMS.  */
+};
+
+/* The name-field mappings we know about.  */
+static const struct uparam_name uparam_names[] =
+{
+  { "dup-args",       1, offsetof (struct uparams, dup_args) },
+  { "dup-args-note",  1, offsetof (struct uparams, dup_args_note) },
+  { "short-opt-col",  0, offsetof (struct uparams, short_opt_col) },
+  { "long-opt-col",   0, offsetof (struct uparams, long_opt_col) },
+  { "doc-opt-col",    0, offsetof (struct uparams, doc_opt_col) },
+  { "opt-doc-col",    0, offsetof (struct uparams, opt_doc_col) },
+  { "header-col",     0, offsetof (struct uparams, header_col) },
+  { "usage-indent",   0, offsetof (struct uparams, usage_indent) },
+  { "rmargin",        0, offsetof (struct uparams, rmargin) },
+  { 0 }
+};
+
+static void
+validate_uparams (const struct argp_state *state, struct uparams *upptr)
+{
+  const struct uparam_name *up;
+
+  for (up = uparam_names; up->name; up++)
+    {
+      if (up->is_bool
+          || up->uparams_offs == offsetof (struct uparams, rmargin))
+        continue;
+      if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin)
+        {
+          __argp_failure (state, 0, 0,
+                          dgettext (state->root_argp->argp_domain,
+                                    "\
+ARGP_HELP_FMT: %s value is less than or equal to %s"),
+                          "rmargin", up->name);
+          return;
+        }
+    }
+  uparams = *upptr;
+  uparams.valid = 1;
+}
+
+/* Read user options from the environment, and fill in UPARAMS appropiately. */
+static void
+fill_in_uparams (const struct argp_state *state)
+{
+  const char *var = getenv ("ARGP_HELP_FMT");
+  struct uparams new_params = uparams;
+
+#define SKIPWS(p) do { while (isspace ((unsigned char) *p)) p++; } while (0);
+
+  if (var)
+    {
+      /* Parse var. */
+      while (*var)
+        {
+          SKIPWS (var);
+
+          if (isalpha ((unsigned char) *var))
+            {
+              size_t var_len;
+              const struct uparam_name *un;
+              int unspec = 0, val = 0;
+              const char *arg = var;
+
+              while (isalnum ((unsigned char) *arg) || *arg == '-' || *arg == '_')
+                arg++;
+              var_len = arg - var;
+
+              SKIPWS (arg);
+
+              if (*arg == '\0' || *arg == ',')
+                unspec = 1;
+              else if (*arg == '=')
+                {
+                  arg++;
+                  SKIPWS (arg);
+                }
+
+              if (unspec)
+                {
+                  if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
+                    {
+                      val = 0;
+                      var += 3;
+                      var_len -= 3;
+                    }
+                  else
+                    val = 1;
+                }
+              else if (isdigit ((unsigned char) *arg))
+                {
+                  val = atoi (arg);
+                  while (isdigit ((unsigned char) *arg))
+                    arg++;
+                  SKIPWS (arg);
+                }
+
+              for (un = uparam_names; un->name; un++)
+                if (strlen (un->name) == var_len
+                    && strncmp (var, un->name, var_len) == 0)
+                  {
+                    if (unspec && !un->is_bool)
+                      __argp_failure (state, 0, 0,
+                                      dgettext (state->root_argp->argp_domain,
+                                                "\
+%.*s: ARGP_HELP_FMT parameter requires a value"),
+                                      (int) var_len, var);
+                    else if (val < 0)
+                      __argp_failure (state, 0, 0,
+                                      dgettext (state->root_argp->argp_domain,
+                                                "\
+%.*s: ARGP_HELP_FMT parameter must be positive"),
+                                      (int) var_len, var);
+                    else
+                      *(int *)((char *)&new_params + un->uparams_offs) = val;
+                    break;
+                  }
+              if (! un->name)
+                __argp_failure (state, 0, 0,
+                                dgettext (state->root_argp->argp_domain, "\
+%.*s: Unknown ARGP_HELP_FMT parameter"),
+                                (int) var_len, var);
+
+              var = arg;
+              if (*var == ',')
+                var++;
+            }
+          else if (*var)
+            {
+              __argp_failure (state, 0, 0,
+                              dgettext (state->root_argp->argp_domain,
+                                        "Garbage in ARGP_HELP_FMT: %s"), var);
+              break;
+            }
+        }
+      validate_uparams (state, &new_params);
+    }
+}
+\f
+/* Returns true if OPT hasn't been marked invisible.  Visibility only affects
+   whether OPT is displayed or used in sorting, not option shadowing.  */
+#define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
+
+/* Returns true if OPT is an alias for an earlier option.  */
+#define oalias(opt) ((opt)->flags & OPTION_ALIAS)
+
+/* Returns true if OPT is an documentation-only entry.  */
+#define odoc(opt) ((opt)->flags & OPTION_DOC)
+
+/* Returns true if OPT should not be translated */
+#define onotrans(opt) ((opt)->flags & OPTION_NO_TRANS)
+
+/* Returns true if OPT is the end-of-list marker for a list of options.  */
+#define oend(opt) __option_is_end (opt)
+
+/* Returns true if OPT has a short option.  */
+#define oshort(opt) __option_is_short (opt)
+\f
+/*
+   The help format for a particular option is like:
+
+     -xARG, -yARG, --long1=ARG, --long2=ARG        Documentation...
+
+   Where ARG will be omitted if there's no argument, for this option, or
+   will be surrounded by "[" and "]" appropiately if the argument is
+   optional.  The documentation string is word-wrapped appropiately, and if
+   the list of options is long enough, it will be started on a separate line.
+   If there are no short options for a given option, the first long option is
+   indented slighly in a way that's supposed to make most long options appear
+   to be in a separate column.
+
+   For example, the following output (from ps):
+
+     -p PID, --pid=PID          List the process PID
+         --pgrp=PGRP            List processes in the process group PGRP
+     -P, -x, --no-parent        Include processes without parents
+     -Q, --all-fields           Don't elide unusable fields (normally if there's
+                                some reason ps can't print a field for any
+                                process, it's removed from the output entirely)
+     -r, --reverse, --gratuitously-long-reverse-option
+                                Reverse the order of any sort
+         --session[=SID]        Add the processes from the session SID (which
+                                defaults to the sid of the current process)
+
+    Here are some more options:
+     -f ZOT, --foonly=ZOT       Glork a foonly
+     -z, --zaza                 Snit a zar
+
+     -?, --help                 Give this help list
+         --usage                Give a short usage message
+     -V, --version              Print program version
+
+   The struct argp_option array for the above could look like:
+
+   {
+     {"pid",       'p',      "PID",  0, "List the process PID"},
+     {"pgrp",      OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"},
+     {"no-parent", 'P',       0,     0, "Include processes without parents"},
+     {0,           'x',       0,     OPTION_ALIAS},
+     {"all-fields",'Q',       0,     0, "Don't elide unusable fields (normally"
+                                        " if there's some reason ps can't"
+                                        " print a field for any process, it's"
+                                        " removed from the output entirely)" },
+     {"reverse",   'r',       0,     0, "Reverse the order of any sort"},
+     {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
+     {"session",   OPT_SESS,  "SID", OPTION_ARG_OPTIONAL,
+                                        "Add the processes from the session"
+                                        " SID (which defaults to the sid of"
+                                        " the current process)" },
+
+     {0,0,0,0, "Here are some more options:"},
+     {"foonly", 'f', "ZOT", 0, "Glork a foonly"},
+     {"zaza", 'z', 0, 0, "Snit a zar"},
+
+     {0}
+   }
+
+   Note that the last three options are automatically supplied by argp_parse,
+   unless you tell it not to with ARGP_NO_HELP.
+
+*/
+\f
+/* Returns true if CH occurs between BEG and END.  */
+static int
+find_char (char ch, char *beg, char *end)
+{
+  while (beg < end)
+    if (*beg == ch)
+      return 1;
+    else
+      beg++;
+  return 0;
+}
+\f
+struct hol_cluster;             /* fwd decl */
+
+struct hol_entry
+{
+  /* First option.  */
+  const struct argp_option *opt;
+  /* Number of options (including aliases).  */
+  unsigned num;
+
+  /* A pointers into the HOL's short_options field, to the first short option
+     letter for this entry.  The order of the characters following this point
+     corresponds to the order of options pointed to by OPT, and there are at
+     most NUM.  A short option recorded in a option following OPT is only
+     valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's
+     probably been shadowed by some other entry).  */
+  char *short_options;
+
+  /* Entries are sorted by their group first, in the order:
+       1, 2, ..., n, 0, -m, ..., -2, -1
+     and then alphabetically within each group.  The default is 0.  */
+  int group;
+
+  /* The cluster of options this entry belongs to, or 0 if none.  */
+  struct hol_cluster *cluster;
+
+  /* The argp from which this option came.  */
+  const struct argp *argp;
+
+  /* Position in the array */
+  unsigned ord;
+};
+
+/* A cluster of entries to reflect the argp tree structure.  */
+struct hol_cluster
+{
+  /* A descriptive header printed before options in this cluster.  */
+  const char *header;
+
+  /* Used to order clusters within the same group with the same parent,
+     according to the order in which they occurred in the parent argp's child
+     list.  */
+  int index;
+
+  /* How to sort this cluster with respect to options and other clusters at the
+     same depth (clusters always follow options in the same group).  */
+  int group;
+
+  /* The cluster to which this cluster belongs, or 0 if it's at the base
+     level.  */
+  struct hol_cluster *parent;
+
+  /* The argp from which this cluster is (eventually) derived.  */
+  const struct argp *argp;
+
+  /* The distance this cluster is from the root.  */
+  int depth;
+
+  /* Clusters in a given hol are kept in a linked list, to make freeing them
+     possible.  */
+  struct hol_cluster *next;
+};
+
+/* A list of options for help.  */
+struct hol
+{
+  /* An array of hol_entry's.  */
+  struct hol_entry *entries;
+  /* The number of entries in this hol.  If this field is zero, the others
+     are undefined.  */
+  unsigned num_entries;
+
+  /* A string containing all short options in this HOL.  Each entry contains
+     pointers into this string, so the order can't be messed with blindly.  */
+  char *short_options;
+
+  /* Clusters of entries in this hol.  */
+  struct hol_cluster *clusters;
+};
+\f
+/* Create a struct hol from the options in ARGP.  CLUSTER is the
+   hol_cluster in which these entries occur, or 0, if at the root.  */
+static struct hol *
+make_hol (const struct argp *argp, struct hol_cluster *cluster)
+{
+  char *so;
+  const struct argp_option *o;
+  const struct argp_option *opts = argp->options;
+  struct hol_entry *entry;
+  unsigned num_short_options = 0;
+  struct hol *hol = malloc (sizeof (struct hol));
+
+  assert (hol);
+
+  hol->num_entries = 0;
+  hol->clusters = 0;
+
+  if (opts)
+    {
+      int cur_group = 0;
+
+      /* The first option must not be an alias.  */
+      assert (! oalias (opts));
+
+      /* Calculate the space needed.  */
+      for (o = opts; ! oend (o); o++)
+        {
+          if (! oalias (o))
+            hol->num_entries++;
+          if (oshort (o))
+            num_short_options++;        /* This is an upper bound.  */
+        }
+
+      hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries);
+      hol->short_options = malloc (num_short_options + 1);
+
+      assert (hol->entries && hol->short_options);
+      if (SIZE_MAX <= UINT_MAX)
+        assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry));
+
+      /* Fill in the entries.  */
+      so = hol->short_options;
+      for (o = opts, entry = hol->entries; ! oend (o); entry++)
+        {
+          entry->opt = o;
+          entry->num = 0;
+          entry->short_options = so;
+          entry->group = cur_group =
+            o->group
+            ? o->group
+            : ((!o->name && !o->key)
+               ? cur_group + 1
+               : cur_group);
+          entry->cluster = cluster;
+          entry->argp = argp;
+
+          do
+            {
+              entry->num++;
+              if (oshort (o) && ! find_char (o->key, hol->short_options, so))
+                /* O has a valid short option which hasn't already been used.*/
+                *so++ = o->key;
+              o++;
+            }
+          while (! oend (o) && oalias (o));
+        }
+      *so = '\0';               /* null terminated so we can find the length */
+    }
+
+  return hol;
+}
+\f
+/* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the
+   associated argp child list entry), INDEX, and PARENT, and return a pointer
+   to it.  ARGP is the argp that this cluster results from.  */
+static struct hol_cluster *
+hol_add_cluster (struct hol *hol, int group, const char *header, int index,
+                 struct hol_cluster *parent, const struct argp *argp)
+{
+  struct hol_cluster *cl = malloc (sizeof (struct hol_cluster));
+  if (cl)
+    {
+      cl->group = group;
+      cl->header = header;
+
+      cl->index = index;
+      cl->parent = parent;
+      cl->argp = argp;
+      cl->depth = parent ? parent->depth + 1 : 0;
+
+      cl->next = hol->clusters;
+      hol->clusters = cl;
+    }
+  return cl;
+}
+\f
+/* Free HOL and any resources it uses.  */
+static void
+hol_free (struct hol *hol)
+{
+  struct hol_cluster *cl = hol->clusters;
+
+  while (cl)
+    {
+      struct hol_cluster *next = cl->next;
+      free (cl);
+      cl = next;
+    }
+
+  if (hol->num_entries > 0)
+    {
+      free (hol->entries);
+      free (hol->short_options);
+    }
+
+  free (hol);
+}
+\f
+static int
+hol_entry_short_iterate (const struct hol_entry *entry,
+                         int (*func)(const struct argp_option *opt,
+                                     const struct argp_option *real,
+                                     const char *domain, void *cookie),
+                         const char *domain, void *cookie)
+{
+  unsigned nopts;
+  int val = 0;
+  const struct argp_option *opt, *real = entry->opt;
+  char *so = entry->short_options;
+
+  for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
+    if (oshort (opt) && *so == opt->key)
+      {
+        if (!oalias (opt))
+          real = opt;
+        if (ovisible (opt))
+          val = (*func)(opt, real, domain, cookie);
+        so++;
+      }
+
+  return val;
+}
+
+static inline int
+__attribute__ ((always_inline))
+hol_entry_long_iterate (const struct hol_entry *entry,
+                        int (*func)(const struct argp_option *opt,
+                                    const struct argp_option *real,
+                                    const char *domain, void *cookie),
+                        const char *domain, void *cookie)
+{
+  unsigned nopts;
+  int val = 0;
+  const struct argp_option *opt, *real = entry->opt;
+
+  for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
+    if (opt->name)
+      {
+        if (!oalias (opt))
+          real = opt;
+        if (ovisible (opt))
+          val = (*func)(opt, real, domain, cookie);
+      }
+
+  return val;
+}
+\f
+/* Iterator that returns true for the first short option.  */
+static int
+until_short (const struct argp_option *opt, const struct argp_option *real,
+             const char *domain, void *cookie)
+{
+  return oshort (opt) ? opt->key : 0;
+}
+
+/* Returns the first valid short option in ENTRY, or 0 if there is none.  */
+static char
+hol_entry_first_short (const struct hol_entry *entry)
+{
+  return hol_entry_short_iterate (entry, until_short,
+                                  entry->argp->argp_domain, 0);
+}
+
+/* Returns the first valid long option in ENTRY, or 0 if there is none.  */
+static const char *
+hol_entry_first_long (const struct hol_entry *entry)
+{
+  const struct argp_option *opt;
+  unsigned num;
+  for (opt = entry->opt, num = entry->num; num > 0; opt++, num--)
+    if (opt->name && ovisible (opt))
+      return opt->name;
+  return 0;
+}
+
+/* Returns the entry in HOL with the long option name NAME, or 0 if there is
+   none.  */
+static struct hol_entry *
+hol_find_entry (struct hol *hol, const char *name)
+{
+  struct hol_entry *entry = hol->entries;
+  unsigned num_entries = hol->num_entries;
+
+  while (num_entries-- > 0)
+    {
+      const struct argp_option *opt = entry->opt;
+      unsigned num_opts = entry->num;
+
+      while (num_opts-- > 0)
+        if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0)
+          return entry;
+        else
+          opt++;
+
+      entry++;
+    }
+
+  return 0;
+}
+\f
+/* If an entry with the long option NAME occurs in HOL, set it's special
+   sort position to GROUP.  */
+static void
+hol_set_group (struct hol *hol, const char *name, int group)
+{
+  struct hol_entry *entry = hol_find_entry (hol, name);
+  if (entry)
+    entry->group = group;
+}
+\f
+/* Order by group:  0, 1, 2, ..., n, -m, ..., -2, -1.
+   EQ is what to return if GROUP1 and GROUP2 are the same.  */
+static int
+group_cmp (int group1, int group2, int eq)
+{
+  if (group1 == group2)
+    return eq;
+  else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0))
+    return group1 - group2;
+  else
+    return group2 - group1;
+}
+
+/* Compare clusters CL1 & CL2 by the order that they should appear in
+   output.  */
+static int
+hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
+{
+  /* If one cluster is deeper than the other, use its ancestor at the same
+     level, so that finding the common ancestor is straightforward.
+
+     clN->depth > 0 means that clN->parent != NULL (see hol_add_cluster) */
+  while (cl1->depth > cl2->depth)
+    cl1 = cl1->parent;
+  while (cl2->depth > cl1->depth)
+    cl2 = cl2->parent;
+
+  /* Now reduce both clusters to their ancestors at the point where both have
+     a common parent; these can be directly compared.  */
+  while (cl1->parent != cl2->parent)
+    cl1 = cl1->parent, cl2 = cl2->parent;
+
+  return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index);
+}
+
+/* Return the ancestor of CL that's just below the root (i.e., has a parent
+   of 0).  */
+static struct hol_cluster *
+hol_cluster_base (struct hol_cluster *cl)
+{
+  while (cl->parent)
+    cl = cl->parent;
+  return cl;
+}
+
+/* Return true if CL1 is a child of CL2.  */
+static int
+hol_cluster_is_child (const struct hol_cluster *cl1,
+                      const struct hol_cluster *cl2)
+{
+  while (cl1 && cl1 != cl2)
+    cl1 = cl1->parent;
+  return cl1 == cl2;
+}
+\f
+/* Given the name of a OPTION_DOC option, modifies NAME to start at the tail
+   that should be used for comparisons, and returns true iff it should be
+   treated as a non-option.  */
+static int
+canon_doc_option (const char **name)
+{
+  int non_opt;
+
+  if (!*name)
+    non_opt = 1;
+  else
+    {
+      /* Skip initial whitespace.  */
+      while (isspace ((unsigned char) **name))
+        (*name)++;
+      /* Decide whether this looks like an option (leading `-') or not.  */
+      non_opt = (**name != '-');
+      /* Skip until part of name used for sorting.  */
+      while (**name && !isalnum ((unsigned char) **name))
+        (*name)++;
+    }
+  return non_opt;
+}
+
+#define HOL_ENTRY_PTRCMP(a,b) ((a)->ord < (b)->ord ? -1 : 1)
+
+/* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
+   listing.  */
+static int
+hol_entry_cmp (const struct hol_entry *entry1,
+               const struct hol_entry *entry2)
+{
+  /* The group numbers by which the entries should be ordered; if either is
+     in a cluster, then this is just the group within the cluster.  */
+  int group1 = entry1->group, group2 = entry2->group;
+  int rc;
+
+  if (entry1->cluster != entry2->cluster)
+    {
+      /* The entries are not within the same cluster, so we can't compare them
+         directly, we have to use the appropiate clustering level too.  */
+      if (! entry1->cluster)
+        /* ENTRY1 is at the `base level', not in a cluster, so we have to
+           compare it's group number with that of the base cluster in which
+           ENTRY2 resides.  Note that if they're in the same group, the
+           clustered option always comes laster.  */
+        return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1);
+      else if (! entry2->cluster)
+        /* Likewise, but ENTRY2's not in a cluster.  */
+        return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
+      else
+        /* Both entries are in clusters, we can just compare the clusters.  */
+        return (rc = hol_cluster_cmp (entry1->cluster, entry2->cluster)) ?
+               rc : HOL_ENTRY_PTRCMP (entry1, entry2);
+    }
+  else if (group1 == group2)
+    /* The entries are both in the same cluster and group, so compare them
+       alphabetically.  */
+    {
+      int short1 = hol_entry_first_short (entry1);
+      int short2 = hol_entry_first_short (entry2);
+      int doc1 = odoc (entry1->opt);
+      int doc2 = odoc (entry2->opt);
+      const char *long1 = hol_entry_first_long (entry1);
+      const char *long2 = hol_entry_first_long (entry2);
+
+      if (doc1)
+        doc1 = canon_doc_option (&long1);
+      if (doc2)
+        doc2 = canon_doc_option (&long2);
+
+      if (doc1 != doc2)
+        /* `documentation' options always follow normal options (or
+           documentation options that *look* like normal options).  */
+        return doc1 - doc2;
+      else if (!short1 && !short2 && long1 && long2)
+        /* Only long options.  */
+        return (rc = __strcasecmp (long1, long2)) ?
+               rc : HOL_ENTRY_PTRCMP (entry1, entry2);
+      else
+        /* Compare short/short, long/short, short/long, using the first
+           character of long options.  Entries without *any* valid
+           options (such as options with OPTION_HIDDEN set) will be put
+           first, but as they're not displayed, it doesn't matter where
+           they are.  */
+        {
+          unsigned char first1 = short1 ? short1 : long1 ? *long1 : 0;
+          unsigned char first2 = short2 ? short2 : long2 ? *long2 : 0;
+          /* Use tolower, not _tolower, since only the former is
+             guaranteed to work on something already lower case.  */
+          int lower_cmp = tolower (first1) - tolower (first2);
+          /* Compare ignoring case, except when the options are both the
+             same letter, in which case lower-case always comes first.  */
+          return lower_cmp ? lower_cmp :
+                 (rc = first2 - first1) ?
+                 rc : HOL_ENTRY_PTRCMP (entry1, entry2);
+        }
+    }
+  else
+    /* Within the same cluster, but not the same group, so just compare
+       groups.  */
+    return group_cmp (group1, group2, HOL_ENTRY_PTRCMP (entry1, entry2));
+}
+
+/* Version of hol_entry_cmp with correct signature for qsort.  */
+static int
+hol_entry_qcmp (const void *entry1_v, const void *entry2_v)
+{
+  return hol_entry_cmp (entry1_v, entry2_v);
+}
+
+/* Sort HOL by group and alphabetically by option name (with short options
+   taking precedence over long).  Since the sorting is for display purposes
+   only, the shadowing of options isn't effected.  */
+static void
+hol_sort (struct hol *hol)
+{
+  if (hol->num_entries > 0)
+    {
+      unsigned i;
+      struct hol_entry *e;
+      for (i = 0, e = hol->entries; i < hol->num_entries; i++, e++)
+        e->ord = i;
+      qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
+             hol_entry_qcmp);
+    }
+}
+\f
+/* Append MORE to HOL, destroying MORE in the process.  Options in HOL shadow
+   any in MORE with the same name.  */
+static void
+hol_append (struct hol *hol, struct hol *more)
+{
+  struct hol_cluster **cl_end = &hol->clusters;
+
+  /* Steal MORE's cluster list, and add it to the end of HOL's.  */
+  while (*cl_end)
+    cl_end = &(*cl_end)->next;
+  *cl_end = more->clusters;
+  more->clusters = 0;
+
+  /* Merge entries.  */
+  if (more->num_entries > 0)
+    {
+      if (hol->num_entries == 0)
+        {
+          hol->num_entries = more->num_entries;
+          hol->entries = more->entries;
+          hol->short_options = more->short_options;
+          more->num_entries = 0;        /* Mark MORE's fields as invalid.  */
+        }
+      else
+        /* Append the entries in MORE to those in HOL, taking care to only add
+           non-shadowed SHORT_OPTIONS values.  */
+        {
+          unsigned left;
+          char *so, *more_so;
+          struct hol_entry *e;
+          unsigned num_entries = hol->num_entries + more->num_entries;
+          struct hol_entry *entries =
+            malloc (num_entries * sizeof (struct hol_entry));
+          unsigned hol_so_len = strlen (hol->short_options);
+          char *short_options =
+            malloc (hol_so_len + strlen (more->short_options) + 1);
+
+          assert (entries && short_options);
+          if (SIZE_MAX <= UINT_MAX)
+            assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry));
+
+          __mempcpy (__mempcpy (entries, hol->entries,
+                                hol->num_entries * sizeof (struct hol_entry)),
+                     more->entries,
+                     more->num_entries * sizeof (struct hol_entry));
+
+          __mempcpy (short_options, hol->short_options, hol_so_len);
+
+          /* Fix up the short options pointers from HOL.  */
+          for (e = entries, left = hol->num_entries; left > 0; e++, left--)
+            e->short_options += (short_options - hol->short_options);
+
+          /* Now add the short options from MORE, fixing up its entries
+             too.  */
+          so = short_options + hol_so_len;
+          more_so = more->short_options;
+          for (left = more->num_entries; left > 0; e++, left--)
+            {
+              int opts_left;
+              const struct argp_option *opt;
+
+              e->short_options = so;
+
+              for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--)
+                {
+                  int ch = *more_so;
+                  if (oshort (opt) && ch == opt->key)
+                    /* The next short option in MORE_SO, CH, is from OPT.  */
+                    {
+                      if (! find_char (ch, short_options,
+                                       short_options + hol_so_len))
+                        /* The short option CH isn't shadowed by HOL's options,
+                           so add it to the sum.  */
+                        *so++ = ch;
+                      more_so++;
+                    }
+                }
+            }
+
+          *so = '\0';
+
+          free (hol->entries);
+          free (hol->short_options);
+
+          hol->entries = entries;
+          hol->num_entries = num_entries;
+          hol->short_options = short_options;
+        }
+    }
+
+  hol_free (more);
+}
+\f
+/* Inserts enough spaces to make sure STREAM is at column COL.  */
+static void
+indent_to (argp_fmtstream_t stream, unsigned col)
+{
+  int needed = col - __argp_fmtstream_point (stream);
+  while (needed-- > 0)
+    __argp_fmtstream_putc (stream, ' ');
+}
+
+/* Output to STREAM either a space, or a newline if there isn't room for at
+   least ENSURE characters before the right margin.  */
+static void
+space (argp_fmtstream_t stream, size_t ensure)
+{
+  if (__argp_fmtstream_point (stream) + ensure
+      >= __argp_fmtstream_rmargin (stream))
+    __argp_fmtstream_putc (stream, '\n');
+  else
+    __argp_fmtstream_putc (stream, ' ');
+}
+
+/* If the option REAL has an argument, we print it in using the printf
+   format REQ_FMT or OPT_FMT depending on whether it's a required or
+   optional argument.  */
+static void
+arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
+     const char *domain, argp_fmtstream_t stream)
+{
+  if (real->arg)
+    {
+      if (real->flags & OPTION_ARG_OPTIONAL)
+        __argp_fmtstream_printf (stream, opt_fmt,
+                                 dgettext (domain, real->arg));
+      else
+        __argp_fmtstream_printf (stream, req_fmt,
+                                 dgettext (domain, real->arg));
+    }
+}
+\f
+/* Helper functions for hol_entry_help.  */
+
+/* State used during the execution of hol_help.  */
+struct hol_help_state
+{
+  /* PREV_ENTRY should contain the previous entry printed, or 0.  */
+  struct hol_entry *prev_entry;
+
+  /* If an entry is in a different group from the previous one, and SEP_GROUPS
+     is true, then a blank line will be printed before any output. */
+  int sep_groups;
+
+  /* True if a duplicate option argument was suppressed (only ever set if
+     UPARAMS.dup_args is false).  */
+  int suppressed_dup_arg;
+};
+
+/* Some state used while printing a help entry (used to communicate with
+   helper functions).  See the doc for hol_entry_help for more info, as most
+   of the fields are copied from its arguments.  */
+struct pentry_state
+{
+  const struct hol_entry *entry;
+  argp_fmtstream_t stream;
+  struct hol_help_state *hhstate;
+
+  /* True if nothing's been printed so far.  */
+  int first;
+
+  /* If non-zero, the state that was used to print this help.  */
+  const struct argp_state *state;
+};
+
+/* If a user doc filter should be applied to DOC, do so.  */
+static const char *
+filter_doc (const char *doc, int key, const struct argp *argp,
+            const struct argp_state *state)
+{
+  if (argp->help_filter)
+    /* We must apply a user filter to this output.  */
+    {
+      void *input = __argp_input (argp, state);
+      return (*argp->help_filter) (key, doc, input);
+    }
+  else
+    /* No filter.  */
+    return doc;
+}
+
+/* Prints STR as a header line, with the margin lines set appropiately, and
+   notes the fact that groups should be separated with a blank line.  ARGP is
+   the argp that should dictate any user doc filtering to take place.  Note
+   that the previous wrap margin isn't restored, but the left margin is reset
+   to 0.  */
+static void
+print_header (const char *str, const struct argp *argp,
+              struct pentry_state *pest)
+{
+  const char *tstr = dgettext (argp->argp_domain, str);
+  const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state);
+
+  if (fstr)
+    {
+      if (*fstr)
+        {
+          if (pest->hhstate->prev_entry)
+            /* Precede with a blank line.  */
+            __argp_fmtstream_putc (pest->stream, '\n');
+          indent_to (pest->stream, uparams.header_col);
+          __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col);
+          __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col);
+          __argp_fmtstream_puts (pest->stream, fstr);
+          __argp_fmtstream_set_lmargin (pest->stream, 0);
+          __argp_fmtstream_putc (pest->stream, '\n');
+        }
+
+      pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */
+    }
+
+  if (fstr != tstr)
+    free ((char *) fstr);
+}
+
+/* Inserts a comma if this isn't the first item on the line, and then makes
+   sure we're at least to column COL.  If this *is* the first item on a line,
+   prints any pending whitespace/headers that should precede this line. Also
+   clears FIRST.  */
+static void
+comma (unsigned col, struct pentry_state *pest)
+{
+  if (pest->first)
+    {
+      const struct hol_entry *pe = pest->hhstate->prev_entry;
+      const struct hol_cluster *cl = pest->entry->cluster;
+
+      if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group)
+        __argp_fmtstream_putc (pest->stream, '\n');
+
+      if (cl && cl->header && *cl->header
+          && (!pe
+              || (pe->cluster != cl
+                  && !hol_cluster_is_child (pe->cluster, cl))))
+        /* If we're changing clusters, then this must be the start of the
+           ENTRY's cluster unless that is an ancestor of the previous one
+           (in which case we had just popped into a sub-cluster for a bit).
+           If so, then print the cluster's header line.  */
+        {
+          int old_wm = __argp_fmtstream_wmargin (pest->stream);
+          print_header (cl->header, cl->argp, pest);
+          __argp_fmtstream_set_wmargin (pest->stream, old_wm);
+        }
+
+      pest->first = 0;
+    }
+  else
+    __argp_fmtstream_puts (pest->stream, ", ");
+
+  indent_to (pest->stream, col);
+}
+\f
+/* Print help for ENTRY to STREAM.  */
+static void
+hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
+                argp_fmtstream_t stream, struct hol_help_state *hhstate)
+{
+  unsigned num;
+  const struct argp_option *real = entry->opt, *opt;
+  char *so = entry->short_options;
+  int have_long_opt = 0;        /* We have any long options.  */
+  /* Saved margins.  */
+  int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
+  int old_wm = __argp_fmtstream_wmargin (stream);
+  /* PEST is a state block holding some of our variables that we'd like to
+     share with helper functions.  */
+  struct pentry_state pest;
+
+  pest.entry = entry;
+  pest.stream = stream;
+  pest.hhstate = hhstate;
+  pest.first = 1;
+  pest.state = state;
+
+  if (! odoc (real))
+    for (opt = real, num = entry->num; num > 0; opt++, num--)
+      if (opt->name && ovisible (opt))
+        {
+          have_long_opt = 1;
+          break;
+        }
+
+  /* First emit short options.  */
+  __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */
+  for (opt = real, num = entry->num; num > 0; opt++, num--)
+    if (oshort (opt) && opt->key == *so)
+      /* OPT has a valid (non shadowed) short option.  */
+      {
+        if (ovisible (opt))
+          {
+            comma (uparams.short_opt_col, &pest);
+            __argp_fmtstream_putc (stream, '-');
+            __argp_fmtstream_putc (stream, *so);
+            if (!have_long_opt || uparams.dup_args)
+              arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream);
+            else if (real->arg)
+              hhstate->suppressed_dup_arg = 1;
+          }
+        so++;
+      }
+
+  /* Now, long options.  */
+  if (odoc (real))
+    /* A `documentation' option.  */
+    {
+      __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
+      for (opt = real, num = entry->num; num > 0; opt++, num--)
+        if (opt->name && *opt->name && ovisible (opt))
+          {
+            comma (uparams.doc_opt_col, &pest);
+            /* Calling dgettext here isn't quite right, since sorting will
+               have been done on the original; but documentation options
+               should be pretty rare anyway...  */
+            __argp_fmtstream_puts (stream,
+                                   onotrans (opt) ?
+                                             opt->name :
+                                   dgettext (state->root_argp->argp_domain,
+                                             opt->name));
+          }
+    }
+  else
+    /* A real long option.  */
+    {
+      int first_long_opt = 1;
+
+      __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
+      for (opt = real, num = entry->num; num > 0; opt++, num--)
+        if (opt->name && ovisible (opt))
+          {
+            comma (uparams.long_opt_col, &pest);
+            __argp_fmtstream_printf (stream, "--%s", opt->name);
+            if (first_long_opt || uparams.dup_args)
+              arg (real, "=%s", "[=%s]", state->root_argp->argp_domain,
+                   stream);
+            else if (real->arg)
+              hhstate->suppressed_dup_arg = 1;
+          }
+    }
+
+  /* Next, documentation strings.  */
+  __argp_fmtstream_set_lmargin (stream, 0);
+
+  if (pest.first)
+    {
+      /* Didn't print any switches, what's up?  */
+      if (!oshort (real) && !real->name)
+        /* This is a group header, print it nicely.  */
+        print_header (real->doc, entry->argp, &pest);
+      else
+        /* Just a totally shadowed option or null header; print nothing.  */
+        goto cleanup;           /* Just return, after cleaning up.  */
+    }
+  else
+    {
+      const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain,
+                                               real->doc) : 0;
+      const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
+      if (fstr && *fstr)
+        {
+          unsigned int col = __argp_fmtstream_point (stream);
+
+          __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
+          __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);
+
+          if (col > (unsigned int) (uparams.opt_doc_col + 3))
+            __argp_fmtstream_putc (stream, '\n');
+          else if (col >= (unsigned int) uparams.opt_doc_col)
+            __argp_fmtstream_puts (stream, "   ");
+          else
+            indent_to (stream, uparams.opt_doc_col);
+
+          __argp_fmtstream_puts (stream, fstr);
+        }
+      if (fstr && fstr != tstr)
+        free ((char *) fstr);
+
+      /* Reset the left margin.  */
+      __argp_fmtstream_set_lmargin (stream, 0);
+      __argp_fmtstream_putc (stream, '\n');
+    }
+
+  hhstate->prev_entry = entry;
+
+cleanup:
+  __argp_fmtstream_set_lmargin (stream, old_lm);
+  __argp_fmtstream_set_wmargin (stream, old_wm);
+}
+\f
+/* Output a long help message about the options in HOL to STREAM.  */
+static void
+hol_help (struct hol *hol, const struct argp_state *state,
+          argp_fmtstream_t stream)
+{
+  unsigned num;
+  struct hol_entry *entry;
+  struct hol_help_state hhstate = { 0, 0, 0 };
+
+  for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
+    hol_entry_help (entry, state, stream, &hhstate);
+
+  if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
+    {
+      const char *tstr = dgettext (state->root_argp->argp_domain, "\
+Mandatory or optional arguments to long options are also mandatory or \
+optional for any corresponding short options.");
+      const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
+                                     state ? state->root_argp : 0, state);
+      if (fstr && *fstr)
+        {
+          __argp_fmtstream_putc (stream, '\n');
+          __argp_fmtstream_puts (stream, fstr);
+          __argp_fmtstream_putc (stream, '\n');
+        }
+      if (fstr && fstr != tstr)
+        free ((char *) fstr);
+    }
+}
+\f
+/* Helper functions for hol_usage.  */
+
+/* If OPT is a short option without an arg, append its key to the string
+   pointer pointer to by COOKIE, and advance the pointer.  */
+static int
+add_argless_short_opt (const struct argp_option *opt,
+                       const struct argp_option *real,
+                       const char *domain, void *cookie)
+{
+  char **snao_end = cookie;
+  if (!(opt->arg || real->arg)
+      && !((opt->flags | real->flags) & OPTION_NO_USAGE))
+    *(*snao_end)++ = opt->key;
+  return 0;
+}
+
+/* If OPT is a short option with an arg, output a usage entry for it to the
+   stream pointed at by COOKIE.  */
+static int
+usage_argful_short_opt (const struct argp_option *opt,
+                        const struct argp_option *real,
+                        const char *domain, void *cookie)
+{
+  argp_fmtstream_t stream = cookie;
+  const char *arg = opt->arg;
+  int flags = opt->flags | real->flags;
+
+  if (! arg)
+    arg = real->arg;
+
+  if (arg && !(flags & OPTION_NO_USAGE))
+    {
+      arg = dgettext (domain, arg);
+
+      if (flags & OPTION_ARG_OPTIONAL)
+        __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
+      else
+        {
+          /* Manually do line wrapping so that it (probably) won't
+             get wrapped at the embedded space.  */
+          space (stream, 6 + strlen (arg));
+          __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
+        }
+    }
+
+  return 0;
+}
+
+/* Output a usage entry for the long option opt to the stream pointed at by
+   COOKIE.  */
+static int
+usage_long_opt (const struct argp_option *opt,
+                const struct argp_option *real,
+                const char *domain, void *cookie)
+{
+  argp_fmtstream_t stream = cookie;
+  const char *arg = opt->arg;
+  int flags = opt->flags | real->flags;
+
+  if (! arg)
+    arg = real->arg;
+
+  if (! (flags & OPTION_NO_USAGE) && !odoc (opt))
+    {
+      if (arg)
+        {
+          arg = dgettext (domain, arg);
+          if (flags & OPTION_ARG_OPTIONAL)
+            __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
+          else
+            __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
+        }
+      else
+        __argp_fmtstream_printf (stream, " [--%s]", opt->name);
+    }
+
+  return 0;
+}
+\f
+/* Print a short usage description for the arguments in HOL to STREAM.  */
+static void
+hol_usage (struct hol *hol, argp_fmtstream_t stream)
+{
+  if (hol->num_entries > 0)
+    {
+      unsigned nentries;
+      struct hol_entry *entry;
+      char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1);
+      char *snao_end = short_no_arg_opts;
+
+      /* First we put a list of short options without arguments.  */
+      for (entry = hol->entries, nentries = hol->num_entries
+           ; nentries > 0
+           ; entry++, nentries--)
+        hol_entry_short_iterate (entry, add_argless_short_opt,
+                                 entry->argp->argp_domain, &snao_end);
+      if (snao_end > short_no_arg_opts)
+        {
+          *snao_end++ = 0;
+          __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts);
+        }
+
+      /* Now a list of short options *with* arguments.  */
+      for (entry = hol->entries, nentries = hol->num_entries
+           ; nentries > 0
+           ; entry++, nentries--)
+        hol_entry_short_iterate (entry, usage_argful_short_opt,
+                                 entry->argp->argp_domain, stream);
+
+      /* Finally, a list of long options (whew!).  */
+      for (entry = hol->entries, nentries = hol->num_entries
+           ; nentries > 0
+           ; entry++, nentries--)
+        hol_entry_long_iterate (entry, usage_long_opt,
+                                entry->argp->argp_domain, stream);
+    }
+}
+\f
+/* Make a HOL containing all levels of options in ARGP.  CLUSTER is the
+   cluster in which ARGP's entries should be clustered, or 0.  */
+static struct hol *
+argp_hol (const struct argp *argp, struct hol_cluster *cluster)
+{
+  const struct argp_child *child = argp->children;
+  struct hol *hol = make_hol (argp, cluster);
+  if (child)
+    while (child->argp)
+      {
+        struct hol_cluster *child_cluster =
+          ((child->group || child->header)
+           /* Put CHILD->argp within its own cluster.  */
+           ? hol_add_cluster (hol, child->group, child->header,
+                              child - argp->children, cluster, argp)
+           /* Just merge it into the parent's cluster.  */
+           : cluster);
+        hol_append (hol, argp_hol (child->argp, child_cluster)) ;
+        child++;
+      }
+  return hol;
+}
+\f
+/* Calculate how many different levels with alternative args strings exist in
+   ARGP.  */
+static size_t
+argp_args_levels (const struct argp *argp)
+{
+  size_t levels = 0;
+  const struct argp_child *child = argp->children;
+
+  if (argp->args_doc && strchr (argp->args_doc, '\n'))
+    levels++;
+
+  if (child)
+    while (child->argp)
+      levels += argp_args_levels ((child++)->argp);
+
+  return levels;
+}
+
+/* Print all the non-option args documented in ARGP to STREAM.  Any output is
+   preceded by a space.  LEVELS is a pointer to a byte vector the length
+   returned by argp_args_levels; it should be initialized to zero, and
+   updated by this routine for the next call if ADVANCE is true.  True is
+   returned as long as there are more patterns to output.  */
+static int
+argp_args_usage (const struct argp *argp, const struct argp_state *state,
+                 char **levels, int advance, argp_fmtstream_t stream)
+{
+  char *our_level = *levels;
+  int multiple = 0;
+  const struct argp_child *child = argp->children;
+  const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0;
+  const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state);
+
+  if (fdoc)
+    {
+      const char *cp = fdoc;
+      nl = __strchrnul (cp, '\n');
+      if (*nl != '\0')
+        /* This is a `multi-level' args doc; advance to the correct position
+           as determined by our state in LEVELS, and update LEVELS.  */
+        {
+          int i;
+          multiple = 1;
+          for (i = 0; i < *our_level; i++)
+            cp = nl + 1, nl = __strchrnul (cp, '\n');
+          (*levels)++;
+        }
+
+      /* Manually do line wrapping so that it (probably) won't get wrapped at
+         any embedded spaces.  */
+      space (stream, 1 + nl - cp);
+
+      __argp_fmtstream_write (stream, cp, nl - cp);
+    }
+  if (fdoc && fdoc != tdoc)
+    free ((char *)fdoc);        /* Free user's modified doc string.  */
+
+  if (child)
+    while (child->argp)
+      advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream);
+
+  if (advance && multiple)
+    {
+      /* Need to increment our level.  */
+      if (*nl)
+        /* There's more we can do here.  */
+        {
+          (*our_level)++;
+          advance = 0;          /* Our parent shouldn't advance also. */
+        }
+      else if (*our_level > 0)
+        /* We had multiple levels, but used them up; reset to zero.  */
+        *our_level = 0;
+    }
+
+  return !advance;
+}
+\f
+/* Print the documentation for ARGP to STREAM; if POST is false, then
+   everything preceeding a `\v' character in the documentation strings (or
+   the whole string, for those with none) is printed, otherwise, everything
+   following the `\v' character (nothing for strings without).  Each separate
+   bit of documentation is separated a blank line, and if PRE_BLANK is true,
+   then the first is as well.  If FIRST_ONLY is true, only the first
+   occurrence is output.  Returns true if anything was output.  */
+static int
+argp_doc (const struct argp *argp, const struct argp_state *state,
+          int post, int pre_blank, int first_only,
+          argp_fmtstream_t stream)
+{
+  const char *text;
+  const char *inp_text;
+  size_t inp_text_len = 0;
+  const char *trans_text;
+  void *input = 0;
+  int anything = 0;
+  const struct argp_child *child = argp->children;
+
+  if (argp->doc)
+    {
+      char *vt = strchr (argp->doc, '\v');
+      if (vt)
+        {
+          if (post)
+            inp_text = vt + 1;
+          else
+            {
+              inp_text_len = vt - argp->doc;
+              inp_text = __strndup (argp->doc, inp_text_len);
+            }
+        }
+      else
+        inp_text = post ? 0 : argp->doc;
+      trans_text = inp_text ? dgettext (argp->argp_domain, inp_text) : NULL;
+    }
+  else
+    trans_text = inp_text = 0;
+
+  if (argp->help_filter)
+    /* We have to filter the doc strings.  */
+    {
+      input = __argp_input (argp, state);
+      text =
+        (*argp->help_filter) (post
+                              ? ARGP_KEY_HELP_POST_DOC
+                              : ARGP_KEY_HELP_PRE_DOC,
+                              trans_text, input);
+    }
+  else
+    text = (const char *) trans_text;
+
+  if (text)
+    {
+      if (pre_blank)
+        __argp_fmtstream_putc (stream, '\n');
+
+      __argp_fmtstream_puts (stream, text);
+
+      if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
+        __argp_fmtstream_putc (stream, '\n');
+
+      anything = 1;
+    }
+
+  if (text && text != trans_text)
+    free ((char *) text);       /* Free TEXT returned from the help filter.  */
+
+  if (inp_text && inp_text_len)
+    free ((char *) inp_text);   /* We copied INP_TEXT, so free it now.  */
+
+  if (post && argp->help_filter)
+    /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text.  */
+    {
+      text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);
+      if (text)
+        {
+          if (anything || pre_blank)
+            __argp_fmtstream_putc (stream, '\n');
+          __argp_fmtstream_puts (stream, text);
+          free ((char *) text);
+          if (__argp_fmtstream_point (stream)
+              > __argp_fmtstream_lmargin (stream))
+            __argp_fmtstream_putc (stream, '\n');
+          anything = 1;
+        }
+    }
+
+  if (child)
+    while (child->argp && !(first_only && anything))
+      anything |=
+        argp_doc ((child++)->argp, state,
+                  post, anything || pre_blank, first_only,
+                  stream);
+
+  return anything;
+}
+\f
+/* Output a usage message for ARGP to STREAM.  If called from
+   argp_state_help, STATE is the relevent parsing state.  FLAGS are from the
+   set ARGP_HELP_*.  NAME is what to use wherever a `program name' is
+   needed. */
+static void
+_help (const struct argp *argp, const struct argp_state *state, FILE *stream,
+       unsigned flags, char *name)
+{
+  int anything = 0;             /* Whether we've output anything.  */
+  struct hol *hol = 0;
+  argp_fmtstream_t fs;
+
+  if (! stream)
+    return;
+
+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
+  __flockfile (stream);
+#endif
+
+  if (! uparams.valid)
+    fill_in_uparams (state);
+
+  fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
+  if (! fs)
+    {
+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
+      __funlockfile (stream);
+#endif
+      return;
+    }
+
+  if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))
+    {
+      hol = argp_hol (argp, 0);
+
+      /* If present, these options always come last.  */
+      hol_set_group (hol, "help", -1);
+      hol_set_group (hol, "version", -1);
+
+      hol_sort (hol);
+    }
+
+  if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))
+    /* Print a short `Usage:' message.  */
+    {
+      int first_pattern = 1, more_patterns;
+      size_t num_pattern_levels = argp_args_levels (argp);
+      char *pattern_levels = alloca (num_pattern_levels);
+
+      memset (pattern_levels, 0, num_pattern_levels);
+
+      do
+        {
+          int old_lm;
+          int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent);
+          char *levels = pattern_levels;
+
+          if (first_pattern)
+            __argp_fmtstream_printf (fs, "%s %s",
+                                     dgettext (argp->argp_domain, "Usage:"),
+                                     name);
+          else
+            __argp_fmtstream_printf (fs, "%s %s",
+                                     dgettext (argp->argp_domain, "  or: "),
+                                     name);
+
+          /* We set the lmargin as well as the wmargin, because hol_usage
+             manually wraps options with newline to avoid annoying breaks.  */
+          old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent);
+
+          if (flags & ARGP_HELP_SHORT_USAGE)
+            /* Just show where the options go.  */
+            {
+              if (hol->num_entries > 0)
+                __argp_fmtstream_puts (fs, dgettext (argp->argp_domain,
+                                                     " [OPTION...]"));
+            }
+          else
+            /* Actually print the options.  */
+            {
+              hol_usage (hol, fs);
+              flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once.  */
+            }
+
+          more_patterns = argp_args_usage (argp, state, &levels, 1, fs);
+
+          __argp_fmtstream_set_wmargin (fs, old_wm);
+          __argp_fmtstream_set_lmargin (fs, old_lm);
+
+          __argp_fmtstream_putc (fs, '\n');
+          anything = 1;
+
+          first_pattern = 0;
+        }
+      while (more_patterns);
+    }
+
+  if (flags & ARGP_HELP_PRE_DOC)
+    anything |= argp_doc (argp, state, 0, 0, 1, fs);
+
+  if (flags & ARGP_HELP_SEE)
+    {
+      __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\
+Try `%s --help' or `%s --usage' for more information.\n"),
+                               name, name);
+      anything = 1;
+    }
+
+  if (flags & ARGP_HELP_LONG)
+    /* Print a long, detailed help message.  */
+    {
+      /* Print info about all the options.  */
+      if (hol->num_entries > 0)
+        {
+          if (anything)
+            __argp_fmtstream_putc (fs, '\n');
+          hol_help (hol, state, fs);
+          anything = 1;
+        }
+    }
+
+  if (flags & ARGP_HELP_POST_DOC)
+    /* Print any documentation strings at the end.  */
+    anything |= argp_doc (argp, state, 1, anything, 0, fs);
+
+  if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
+    {
+      if (anything)
+        __argp_fmtstream_putc (fs, '\n');
+      __argp_fmtstream_printf (fs, dgettext (argp->argp_domain,
+                                             "Report bugs to %s.\n"),
+                               argp_program_bug_address);
+      anything = 1;
+    }
+
+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
+  __funlockfile (stream);
+#endif
+
+  if (hol)
+    hol_free (hol);
+
+  __argp_fmtstream_free (fs);
+}
+\f
+/* Output a usage message for ARGP to STREAM.  FLAGS are from the set
+   ARGP_HELP_*.  NAME is what to use wherever a `program name' is needed. */
+void __argp_help (const struct argp *argp, FILE *stream,
+                  unsigned flags, char *name)
+{
+  struct argp_state state;
+  memset (&state, 0, sizeof state);
+  state.root_argp = argp;
+  _help (argp, &state, stream, flags, name);
+}
+#ifdef weak_alias
+weak_alias (__argp_help, argp_help)
+#endif
+
+#if ! (defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME)
+char *
+__argp_short_program_name (void)
+{
+# if HAVE_DECL_PROGRAM_INVOCATION_NAME
+  return __argp_base_name (program_invocation_name);
+# else
+  /* FIXME: What now? Miles suggests that it is better to use NULL,
+     but currently the value is passed on directly to fputs_unlocked,
+     so that requires more changes. */
+# if __GNUC__
+#  warning No reasonable value to return
+# endif /* __GNUC__ */
+  return "";
+# endif
+}
+#endif
+
+/* Output, if appropriate, a usage message for STATE to STREAM.  FLAGS are
+   from the set ARGP_HELP_*.  */
+void
+__argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
+{
+  if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
+    {
+      if (state && (state->flags & ARGP_LONG_ONLY))
+        flags |= ARGP_HELP_LONG_ONLY;
+
+      _help (state ? state->root_argp : 0, state, stream, flags,
+             state ? state->name : __argp_short_program_name ());
+
+      if (!state || ! (state->flags & ARGP_NO_EXIT))
+        {
+          if (flags & ARGP_HELP_EXIT_ERR)
+            exit (argp_err_exit_status);
+          if (flags & ARGP_HELP_EXIT_OK)
+            exit (0);
+        }
+  }
+}
+#ifdef weak_alias
+weak_alias (__argp_state_help, argp_state_help)
+#endif
+\f
+/* If appropriate, print the printf string FMT and following args, preceded
+   by the program name and `:', to stderr, and followed by a `Try ... --help'
+   message, then exit (1).  */
+void
+__argp_error (const struct argp_state *state, const char *fmt, ...)
+{
+  if (!state || !(state->flags & ARGP_NO_ERRS))
+    {
+      FILE *stream = state ? state->err_stream : stderr;
+
+      if (stream)
+        {
+          va_list ap;
+
+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
+          __flockfile (stream);
+#endif
+
+          va_start (ap, fmt);
+
+#ifdef USE_IN_LIBIO
+          if (_IO_fwide (stream, 0) > 0)
+            {
+              char *buf;
+
+              if (__asprintf (&buf, fmt, ap) < 0)
+                buf = NULL;
+
+              __fwprintf (stream, L"%s: %s\n",
+                          state ? state->name : __argp_short_program_name (),
+                          buf);
+
+              free (buf);
+            }
+          else
+#endif
+            {
+              fputs_unlocked (state
+                              ? state->name : __argp_short_program_name (),
+                              stream);
+              putc_unlocked (':', stream);
+              putc_unlocked (' ', stream);
+
+              vfprintf (stream, fmt, ap);
+
+              putc_unlocked ('\n', stream);
+            }
+
+          __argp_state_help (state, stream, ARGP_HELP_STD_ERR);
+
+          va_end (ap);
+
+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
+          __funlockfile (stream);
+#endif
+        }
+    }
+}
+#ifdef weak_alias
+weak_alias (__argp_error, argp_error)
+#endif
+\f
+/* Similar to the standard gnu error-reporting function error(), but will
+   respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
+   to STATE->err_stream.  This is useful for argument parsing code that is
+   shared between program startup (when exiting is desired) and runtime
+   option parsing (when typically an error code is returned instead).  The
+   difference between this function and argp_error is that the latter is for
+   *parsing errors*, and the former is for other problems that occur during
+   parsing but don't reflect a (syntactic) problem with the input.  */
+void
+__argp_failure (const struct argp_state *state, int status, int errnum,
+                const char *fmt, ...)
+{
+  if (!state || !(state->flags & ARGP_NO_ERRS))
+    {
+      FILE *stream = state ? state->err_stream : stderr;
+
+      if (stream)
+        {
+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
+          __flockfile (stream);
+#endif
+
+#ifdef USE_IN_LIBIO
+          if (_IO_fwide (stream, 0) > 0)
+            __fwprintf (stream, L"%s",
+                        state ? state->name : __argp_short_program_name ());
+          else
+#endif
+            fputs_unlocked (state
+                            ? state->name : __argp_short_program_name (),
+                            stream);
+
+          if (fmt)
+            {
+              va_list ap;
+
+              va_start (ap, fmt);
+#ifdef USE_IN_LIBIO
+              if (_IO_fwide (stream, 0) > 0)
+                {
+                  char *buf;
+
+                  if (__asprintf (&buf, fmt, ap) < 0)
+                    buf = NULL;
+
+                  __fwprintf (stream, L": %s", buf);
+
+                  free (buf);
+                }
+              else
+#endif
+                {
+                  putc_unlocked (':', stream);
+                  putc_unlocked (' ', stream);
+
+                  vfprintf (stream, fmt, ap);
+                }
+
+              va_end (ap);
+            }
+
+          if (errnum)
+            {
+              char buf[200];
+
+#ifdef USE_IN_LIBIO
+              if (_IO_fwide (stream, 0) > 0)
+                __fwprintf (stream, L": %s",
+                            __strerror_r (errnum, buf, sizeof (buf)));
+              else
+#endif
+                {
+                  char const *s = NULL;
+                  putc_unlocked (':', stream);
+                  putc_unlocked (' ', stream);
+#if _LIBC || (HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P)
+                  s = __strerror_r (errnum, buf, sizeof buf);
+#elif HAVE_DECL_STRERROR_R
+                  if (__strerror_r (errnum, buf, sizeof buf) == 0)
+                    s = buf;
+#endif
+#if !_LIBC
+                  if (! s && ! (s = strerror (errnum)))
+                    s = dgettext (state->root_argp->argp_domain,
+                                  "Unknown system error");
+#endif
+                  fputs (s, stream);
+                }
+            }
+
+#ifdef USE_IN_LIBIO
+          if (_IO_fwide (stream, 0) > 0)
+            putwc_unlocked (L'\n', stream);
+          else
+#endif
+            putc_unlocked ('\n', stream);
+
+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
+          __funlockfile (stream);
+#endif
+
+          if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
+            exit (status);
+        }
+    }
+}
+#ifdef weak_alias
+weak_alias (__argp_failure, argp_failure)
+#endif
diff --git a/grub-core/gnulib/argp-namefrob.h b/grub-core/gnulib/argp-namefrob.h
new file mode 100644 (file)
index 0000000..24581a6
--- /dev/null
@@ -0,0 +1,157 @@
+/* Name frobnication for compiling argp outside of glibc
+   Copyright (C) 1997, 2003, 2007, 2009, 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#if !_LIBC
+/* This code is written for inclusion in gnu-libc, and uses names in the
+   namespace reserved for libc.  If we're not compiling in libc, define those
+   names to be the normal ones instead.  */
+
+/* argp-parse functions */
+#undef __argp_parse
+#define __argp_parse argp_parse
+#undef __option_is_end
+#define __option_is_end _option_is_end
+#undef __option_is_short
+#define __option_is_short _option_is_short
+#undef __argp_input
+#define __argp_input _argp_input
+
+/* argp-help functions */
+#undef __argp_help
+#define __argp_help argp_help
+#undef __argp_error
+#define __argp_error argp_error
+#undef __argp_failure
+#define __argp_failure argp_failure
+#undef __argp_state_help
+#define __argp_state_help argp_state_help
+#undef __argp_usage
+#define __argp_usage argp_usage
+
+/* argp-fmtstream functions */
+#undef __argp_make_fmtstream
+#define __argp_make_fmtstream argp_make_fmtstream
+#undef __argp_fmtstream_free
+#define __argp_fmtstream_free argp_fmtstream_free
+#undef __argp_fmtstream_putc
+#define __argp_fmtstream_putc argp_fmtstream_putc
+#undef __argp_fmtstream_puts
+#define __argp_fmtstream_puts argp_fmtstream_puts
+#undef __argp_fmtstream_write
+#define __argp_fmtstream_write argp_fmtstream_write
+#undef __argp_fmtstream_printf
+#define __argp_fmtstream_printf argp_fmtstream_printf
+#undef __argp_fmtstream_set_lmargin
+#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
+#undef __argp_fmtstream_set_rmargin
+#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
+#undef __argp_fmtstream_set_wmargin
+#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
+#undef __argp_fmtstream_point
+#define __argp_fmtstream_point argp_fmtstream_point
+#undef __argp_fmtstream_update
+#define __argp_fmtstream_update _argp_fmtstream_update
+#undef __argp_fmtstream_ensure
+#define __argp_fmtstream_ensure _argp_fmtstream_ensure
+#undef __argp_fmtstream_lmargin
+#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
+#undef __argp_fmtstream_rmargin
+#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
+#undef __argp_fmtstream_wmargin
+#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
+
+/* normal libc functions we call */
+#undef __flockfile
+#define __flockfile flockfile
+#undef __funlockfile
+#define __funlockfile funlockfile
+#undef __mempcpy
+#define __mempcpy mempcpy
+#undef __sleep
+#define __sleep sleep
+#undef __strcasecmp
+#define __strcasecmp strcasecmp
+#undef __strchrnul
+#define __strchrnul strchrnul
+#undef __strerror_r
+#define __strerror_r strerror_r
+#undef __strndup
+#define __strndup strndup
+#undef __vsnprintf
+#define __vsnprintf vsnprintf
+
+#if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED
+# define clearerr_unlocked(x) clearerr (x)
+#endif
+#if defined(HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED
+# define feof_unlocked(x) feof (x)
+# endif
+#if defined(HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED
+# define ferror_unlocked(x) ferror (x)
+# endif
+#if defined(HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED
+# define fflush_unlocked(x) fflush (x)
+# endif
+#if defined(HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED
+# define fgets_unlocked(x,y,z) fgets (x,y,z)
+# endif
+#if defined(HAVE_DECL_FPUTC_UNLOCKED) && !HAVE_DECL_FPUTC_UNLOCKED
+# define fputc_unlocked(x,y) fputc (x,y)
+# endif
+#if defined(HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED
+# define fputs_unlocked(x,y) fputs (x,y)
+# endif
+#if defined(HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED
+# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
+# endif
+#if defined(HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED
+# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
+# endif
+#if defined(HAVE_DECL_GETC_UNLOCKED) && !HAVE_DECL_GETC_UNLOCKED
+# define getc_unlocked(x) getc (x)
+# endif
+#if defined(HAVE_DECL_GETCHAR_UNLOCKED) && !HAVE_DECL_GETCHAR_UNLOCKED
+#  define getchar_unlocked() getchar ()
+# endif
+#if defined(HAVE_DECL_PUTC_UNLOCKED) && !HAVE_DECL_PUTC_UNLOCKED
+# define putc_unlocked(x,y) putc (x,y)
+# endif
+#if defined(HAVE_DECL_PUTCHAR_UNLOCKED) && !HAVE_DECL_PUTCHAR_UNLOCKED
+# define putchar_unlocked(x) putchar (x)
+# endif
+
+#endif /* !_LIBC */
+
+#ifndef __set_errno
+#define __set_errno(e) (errno = (e))
+#endif
+
+#if defined GNULIB_ARGP_DISABLE_DIRNAME
+# define __argp_base_name(arg) arg
+#elif defined GNULIB_ARGP_EXTERN_BASENAME
+extern char *__argp_base_name (const char *arg);
+#else
+# include "dirname.h"
+# define __argp_base_name last_component
+#endif
+
+#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
+# define __argp_short_program_name()    (program_invocation_short_name)
+#else
+extern char *__argp_short_program_name (void);
+#endif
diff --git a/grub-core/gnulib/argp-parse.c b/grub-core/gnulib/argp-parse.c
new file mode 100644 (file)
index 0000000..a1cbf88
--- /dev/null
@@ -0,0 +1,952 @@
+/* Hierarchial argument parsing, layered over getopt
+   Copyright (C) 1995-2000, 2002-2004, 2009-2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <alloca.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#include <getopt.h>
+#include <getopt_int.h>
+
+#ifdef _LIBC
+# include <libintl.h>
+# undef dgettext
+# define dgettext(domain, msgid) \
+   INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
+#else
+# include "gettext.h"
+#endif
+#define N_(msgid) msgid
+
+#include "argp.h"
+#include "argp-namefrob.h"
+
+#define alignof(type) offsetof (struct { char c; type x; }, x)
+#define alignto(n, d) ((((n) + (d) - 1) / (d)) * (d))
+
+/* Getopt return values.  */
+#define KEY_END (-1)            /* The end of the options.  */
+#define KEY_ARG 1               /* A non-option argument.  */
+#define KEY_ERR '?'             /* An error parsing the options.  */
+
+/* The meta-argument used to prevent any further arguments being interpreted
+   as options.  */
+#define QUOTE "--"
+
+/* The number of bits we steal in a long-option value for our own use.  */
+#define GROUP_BITS CHAR_BIT
+
+/* The number of bits available for the user value.  */
+#define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS)
+#define USER_MASK ((1 << USER_BITS) - 1)
+
+/* EZ alias for ARGP_ERR_UNKNOWN.  */
+#define EBADKEY ARGP_ERR_UNKNOWN
+\f
+/* Default options.  */
+
+/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep
+   for one second intervals, decrementing _ARGP_HANG until it's zero.  Thus
+   you can force the program to continue by attaching a debugger and setting
+   it to 0 yourself.  */
+static volatile int _argp_hang;
+
+#define OPT_PROGNAME    -2
+#define OPT_USAGE       -3
+#define OPT_HANG        -4
+
+static const struct argp_option argp_default_options[] =
+{
+  {"help",        '?',          0, 0,  N_("give this help list"), -1},
+  {"usage",       OPT_USAGE,    0, 0,  N_("give a short usage message"), 0},
+  {"program-name",OPT_PROGNAME,N_("NAME"), OPTION_HIDDEN, N_("set the program name"), 0},
+  {"HANG",        OPT_HANG,    N_("SECS"), OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
+     N_("hang for SECS seconds (default 3600)"), 0},
+  {NULL, 0, 0, 0, NULL, 0}
+};
+
+static error_t
+argp_default_parser (int key, char *arg, struct argp_state *state)
+{
+  switch (key)
+    {
+    case '?':
+      __argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
+      break;
+    case OPT_USAGE:
+      __argp_state_help (state, state->out_stream,
+                         ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
+      break;
+
+    case OPT_PROGNAME:          /* Set the program name.  */
+#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME
+      program_invocation_name = arg;
+#endif
+      /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka
+         __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined
+         to be that, so we have to be a bit careful here.]  */
+
+      /* Update what we use for messages.  */
+      state->name = __argp_base_name (arg);
+
+#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
+      program_invocation_short_name = state->name;
+#endif
+
+      if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS))
+          == ARGP_PARSE_ARGV0)
+        /* Update what getopt uses too.  */
+        state->argv[0] = arg;
+
+      break;
+
+    case OPT_HANG:
+      _argp_hang = atoi (arg ? arg : "3600");
+      while (_argp_hang-- > 0)
+        __sleep (1);
+      break;
+
+    default:
+      return EBADKEY;
+    }
+  return 0;
+}
+
+static const struct argp argp_default_argp =
+  {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"};
+
+\f
+static const struct argp_option argp_version_options[] =
+{
+  {"version",     'V',          0, 0,  N_("print program version"), -1},
+  {NULL, 0, 0, 0, NULL, 0}
+};
+
+static error_t
+argp_version_parser (int key, char *arg, struct argp_state *state)
+{
+  switch (key)
+    {
+    case 'V':
+      if (argp_program_version_hook)
+        (*argp_program_version_hook) (state->out_stream, state);
+      else if (argp_program_version)
+        fprintf (state->out_stream, "%s\n", argp_program_version);
+      else
+        __argp_error (state, dgettext (state->root_argp->argp_domain,
+                                       "(PROGRAM ERROR) No version known!?"));
+      if (! (state->flags & ARGP_NO_EXIT))
+        exit (0);
+      break;
+    default:
+      return EBADKEY;
+    }
+  return 0;
+}
+
+static const struct argp argp_version_argp =
+  {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"};
+\f
+/* Returns the offset into the getopt long options array LONG_OPTIONS of a
+   long option with called NAME, or -1 if none is found.  Passing NULL as
+   NAME will return the number of options.  */
+static int
+find_long_option (struct option *long_options, const char *name)
+{
+  struct option *l = long_options;
+  while (l->name != NULL)
+    if (name != NULL && strcmp (l->name, name) == 0)
+      return l - long_options;
+    else
+      l++;
+  if (name == NULL)
+    return l - long_options;
+  else
+    return -1;
+}
+
+\f
+/* The state of a `group' during parsing.  Each group corresponds to a
+   particular argp structure from the tree of such descending from the top
+   level argp passed to argp_parse.  */
+struct group
+{
+  /* This group's parsing function.  */
+  argp_parser_t parser;
+
+  /* Which argp this group is from.  */
+  const struct argp *argp;
+
+  /* Points to the point in SHORT_OPTS corresponding to the end of the short
+     options for this group.  We use it to determine from which group a
+     particular short options is from.  */
+  char *short_end;
+
+  /* The number of non-option args sucessfully handled by this parser.  */
+  unsigned args_processed;
+
+  /* This group's parser's parent's group.  */
+  struct group *parent;
+  unsigned parent_index;        /* And the our position in the parent.   */
+
+  /* These fields are swapped into and out of the state structure when
+     calling this group's parser.  */
+  void *input, **child_inputs;
+  void *hook;
+};
+
+/* Call GROUP's parser with KEY and ARG, swapping any group-specific info
+   from STATE before calling, and back into state afterwards.  If GROUP has
+   no parser, EBADKEY is returned.  */
+static error_t
+group_parse (struct group *group, struct argp_state *state, int key, char *arg)
+{
+  if (group->parser)
+    {
+      error_t err;
+      state->hook = group->hook;
+      state->input = group->input;
+      state->child_inputs = group->child_inputs;
+      state->arg_num = group->args_processed;
+      err = (*group->parser)(key, arg, state);
+      group->hook = state->hook;
+      return err;
+    }
+  else
+    return EBADKEY;
+}
+\f
+struct parser
+{
+  const struct argp *argp;
+
+  /* SHORT_OPTS is the getopt short options string for the union of all the
+     groups of options.  */
+  char *short_opts;
+  /* LONG_OPTS is the array of getop long option structures for the union of
+     all the groups of options.  */
+  struct option *long_opts;
+  /* OPT_DATA is the getopt data used for the re-entrant getopt.  */
+  struct _getopt_data opt_data;
+
+  /* States of the various parsing groups.  */
+  struct group *groups;
+  /* The end of the GROUPS array.  */
+  struct group *egroup;
+  /* An vector containing storage for the CHILD_INPUTS field in all groups.  */
+  void **child_inputs;
+
+  /* True if we think using getopt is still useful; if false, then
+     remaining arguments are just passed verbatim with ARGP_KEY_ARG.  This is
+     cleared whenever getopt returns KEY_END, but may be set again if the user
+     moves the next argument pointer backwards.  */
+  int try_getopt;
+
+  /* State block supplied to parsing routines.  */
+  struct argp_state state;
+
+  /* Memory used by this parser.  */
+  void *storage;
+};
+\f
+/* The next usable entries in the various parser tables being filled in by
+   convert_options.  */
+struct parser_convert_state
+{
+  struct parser *parser;
+  char *short_end;
+  struct option *long_end;
+  void **child_inputs_end;
+};
+
+/* Converts all options in ARGP (which is put in GROUP) and ancestors
+   into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and
+   CVT->LONG_END are the points at which new options are added.  Returns the
+   next unused group entry.  CVT holds state used during the conversion.  */
+static struct group *
+convert_options (const struct argp *argp,
+                 struct group *parent, unsigned parent_index,
+                 struct group *group, struct parser_convert_state *cvt)
+{
+  /* REAL is the most recent non-alias value of OPT.  */
+  const struct argp_option *real = argp->options;
+  const struct argp_child *children = argp->children;
+
+  if (real || argp->parser)
+    {
+      const struct argp_option *opt;
+
+      if (real)
+        for (opt = real; !__option_is_end (opt); opt++)
+          {
+            if (! (opt->flags & OPTION_ALIAS))
+              /* OPT isn't an alias, so we can use values from it.  */
+              real = opt;
+
+            if (! (real->flags & OPTION_DOC))
+              /* A real option (not just documentation).  */
+              {
+                if (__option_is_short (opt))
+                  /* OPT can be used as a short option.  */
+                  {
+                    *cvt->short_end++ = opt->key;
+                    if (real->arg)
+                      {
+                        *cvt->short_end++ = ':';
+                        if (real->flags & OPTION_ARG_OPTIONAL)
+                          *cvt->short_end++ = ':';
+                      }
+                    *cvt->short_end = '\0'; /* keep 0 terminated */
+                  }
+
+                if (opt->name
+                    && find_long_option (cvt->parser->long_opts, opt->name) < 0)
+                  /* OPT can be used as a long option.  */
+                  {
+                    cvt->long_end->name = opt->name;
+                    cvt->long_end->has_arg =
+                      (real->arg
+                       ? (real->flags & OPTION_ARG_OPTIONAL
+                          ? optional_argument
+                          : required_argument)
+                       : no_argument);
+                    cvt->long_end->flag = 0;
+                    /* we add a disambiguating code to all the user's
+                       values (which is removed before we actually call
+                       the function to parse the value); this means that
+                       the user loses use of the high 8 bits in all his
+                       values (the sign of the lower bits is preserved
+                       however)...  */
+                    cvt->long_end->val =
+                      ((opt->key ? opt->key : real->key) & USER_MASK)
+                      + (((group - cvt->parser->groups) + 1) << USER_BITS);
+
+                    /* Keep the LONG_OPTS list terminated.  */
+                    (++cvt->long_end)->name = NULL;
+                  }
+              }
+            }
+
+      group->parser = argp->parser;
+      group->argp = argp;
+      group->short_end = cvt->short_end;
+      group->args_processed = 0;
+      group->parent = parent;
+      group->parent_index = parent_index;
+      group->input = 0;
+      group->hook = 0;
+      group->child_inputs = 0;
+
+      if (children)
+        /* Assign GROUP's CHILD_INPUTS field some space from
+           CVT->child_inputs_end.*/
+        {
+          unsigned num_children = 0;
+          while (children[num_children].argp)
+            num_children++;
+          group->child_inputs = cvt->child_inputs_end;
+          cvt->child_inputs_end += num_children;
+        }
+
+      parent = group++;
+    }
+  else
+    parent = 0;
+
+  if (children)
+    {
+      unsigned index = 0;
+      while (children->argp)
+        group =
+          convert_options (children++->argp, parent, index++, group, cvt);
+    }
+
+  return group;
+}
+
+/* Find the merged set of getopt options, with keys appropiately prefixed. */
+static void
+parser_convert (struct parser *parser, const struct argp *argp, int flags)
+{
+  struct parser_convert_state cvt;
+
+  cvt.parser = parser;
+  cvt.short_end = parser->short_opts;
+  cvt.long_end = parser->long_opts;
+  cvt.child_inputs_end = parser->child_inputs;
+
+  if (flags & ARGP_IN_ORDER)
+    *cvt.short_end++ = '-';
+  else if (flags & ARGP_NO_ARGS)
+    *cvt.short_end++ = '+';
+  *cvt.short_end = '\0';
+
+  cvt.long_end->name = NULL;
+
+  parser->argp = argp;
+
+  if (argp)
+    parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt);
+  else
+    parser->egroup = parser->groups; /* No parsers at all! */
+}
+\f
+/* Lengths of various parser fields which we will allocated.  */
+struct parser_sizes
+{
+  size_t short_len;             /* Getopt short options string.  */
+  size_t long_len;              /* Getopt long options vector.  */
+  size_t num_groups;            /* Group structures we allocate.  */
+  size_t num_child_inputs;      /* Child input slots.  */
+};
+
+/* For ARGP, increments the NUM_GROUPS field in SZS by the total number of
+ argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by
+ the maximum lengths of the resulting merged getopt short options string and
+ long-options array, respectively.  */
+static void
+calc_sizes (const struct argp *argp,  struct parser_sizes *szs)
+{
+  const struct argp_child *child = argp->children;
+  const struct argp_option *opt = argp->options;
+
+  if (opt || argp->parser)
+    {
+      szs->num_groups++;
+      if (opt)
+        {
+          int num_opts = 0;
+          while (!__option_is_end (opt++))
+            num_opts++;
+          szs->short_len += num_opts * 3; /* opt + up to 2 `:'s */
+          szs->long_len += num_opts;
+        }
+    }
+
+  if (child)
+    while (child->argp)
+      {
+        calc_sizes ((child++)->argp, szs);
+        szs->num_child_inputs++;
+      }
+}
+
+/* Initializes PARSER to parse ARGP in a manner described by FLAGS.  */
+static error_t
+parser_init (struct parser *parser, const struct argp *argp,
+             int argc, char **argv, int flags, void *input)
+{
+  error_t err = 0;
+  struct group *group;
+  struct parser_sizes szs;
+  struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER;
+  char *storage;
+  size_t glen, gsum;
+  size_t clen, csum;
+  size_t llen, lsum;
+  size_t slen, ssum;
+
+  szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1;
+  szs.long_len = 0;
+  szs.num_groups = 0;
+  szs.num_child_inputs = 0;
+
+  if (argp)
+    calc_sizes (argp, &szs);
+
+  /* Lengths of the various bits of storage used by PARSER.  */
+  glen = (szs.num_groups + 1) * sizeof (struct group);
+  clen = szs.num_child_inputs * sizeof (void *);
+  llen = (szs.long_len + 1) * sizeof (struct option);
+  slen = szs.short_len + 1;
+
+  /* Sums of previous lengths, properly aligned.  There's no need to
+     align gsum, since struct group is aligned at least as strictly as
+     void * (since it contains a void * member).  And there's no need
+     to align lsum, since struct option is aligned at least as
+     strictly as char.  */
+  gsum = glen;
+  csum = alignto (gsum + clen, alignof (struct option));
+  lsum = csum + llen;
+  ssum = lsum + slen;
+
+  parser->storage = malloc (ssum);
+  if (! parser->storage)
+    return ENOMEM;
+
+  storage = parser->storage;
+  parser->groups = parser->storage;
+  parser->child_inputs = (void **) (storage + gsum);
+  parser->long_opts = (struct option *) (storage + csum);
+  parser->short_opts = storage + lsum;
+  parser->opt_data = opt_data;
+
+  memset (parser->child_inputs, 0, clen);
+  parser_convert (parser, argp, flags);
+
+  memset (&parser->state, 0, sizeof (struct argp_state));
+  parser->state.root_argp = parser->argp;
+  parser->state.argc = argc;
+  parser->state.argv = argv;
+  parser->state.flags = flags;
+  parser->state.err_stream = stderr;
+  parser->state.out_stream = stdout;
+  parser->state.next = 0;       /* Tell getopt to initialize.  */
+  parser->state.pstate = parser;
+
+  parser->try_getopt = 1;
+
+  /* Call each parser for the first time, giving it a chance to propagate
+     values to child parsers.  */
+  if (parser->groups < parser->egroup)
+    parser->groups->input = input;
+  for (group = parser->groups;
+       group < parser->egroup && (!err || err == EBADKEY);
+       group++)
+    {
+      if (group->parent)
+        /* If a child parser, get the initial input value from the parent. */
+        group->input = group->parent->child_inputs[group->parent_index];
+
+      if (!group->parser
+          && group->argp->children && group->argp->children->argp)
+        /* For the special case where no parsing function is supplied for an
+           argp, propagate its input to its first child, if any (this just
+           makes very simple wrapper argps more convenient).  */
+        group->child_inputs[0] = group->input;
+
+      err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0);
+    }
+  if (err == EBADKEY)
+    err = 0;                    /* Some parser didn't understand.  */
+
+  if (err)
+    return err;
+
+  if (parser->state.flags & ARGP_NO_ERRS)
+    {
+      parser->opt_data.opterr = 0;
+      if (parser->state.flags & ARGP_PARSE_ARGV0)
+        /* getopt always skips ARGV[0], so we have to fake it out.  As long
+           as OPTERR is 0, then it shouldn't actually try to access it.  */
+        parser->state.argv--, parser->state.argc++;
+    }
+  else
+    parser->opt_data.opterr = 1;        /* Print error messages.  */
+
+  if (parser->state.argv == argv && argv[0])
+    /* There's an argv[0]; use it for messages.  */
+    parser->state.name = __argp_base_name (argv[0]);
+  else
+    parser->state.name = __argp_short_program_name ();
+
+  return 0;
+}
+\f
+/* Free any storage consumed by PARSER (but not PARSER itself).  */
+static error_t
+parser_finalize (struct parser *parser,
+                 error_t err, int arg_ebadkey, int *end_index)
+{
+  struct group *group;
+
+  if (err == EBADKEY && arg_ebadkey)
+    /* Suppress errors generated by unparsed arguments.  */
+    err = 0;
+
+  if (! err)
+    {
+      if (parser->state.next == parser->state.argc)
+        /* We successfully parsed all arguments!  Call all the parsers again,
+           just a few more times... */
+        {
+          for (group = parser->groups;
+               group < parser->egroup && (!err || err==EBADKEY);
+               group++)
+            if (group->args_processed == 0)
+              err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0);
+          for (group = parser->egroup - 1;
+               group >= parser->groups && (!err || err==EBADKEY);
+               group--)
+            err = group_parse (group, &parser->state, ARGP_KEY_END, 0);
+
+          if (err == EBADKEY)
+            err = 0;            /* Some parser didn't understand.  */
+
+          /* Tell the user that all arguments are parsed.  */
+          if (end_index)
+            *end_index = parser->state.next;
+        }
+      else if (end_index)
+        /* Return any remaining arguments to the user.  */
+        *end_index = parser->state.next;
+      else
+        /* No way to return the remaining arguments, they must be bogus. */
+        {
+          if (!(parser->state.flags & ARGP_NO_ERRS)
+              && parser->state.err_stream)
+            fprintf (parser->state.err_stream,
+                     dgettext (parser->argp->argp_domain,
+                               "%s: Too many arguments\n"),
+                     parser->state.name);
+          err = EBADKEY;
+        }
+    }
+
+  /* Okay, we're all done, with either an error or success; call the parsers
+     to indicate which one.  */
+
+  if (err)
+    {
+      /* Maybe print an error message.  */
+      if (err == EBADKEY)
+        /* An appropriate message describing what the error was should have
+           been printed earlier.  */
+        __argp_state_help (&parser->state, parser->state.err_stream,
+                           ARGP_HELP_STD_ERR);
+
+      /* Since we didn't exit, give each parser an error indication.  */
+      for (group = parser->groups; group < parser->egroup; group++)
+        group_parse (group, &parser->state, ARGP_KEY_ERROR, 0);
+    }
+  else
+    /* Notify parsers of success, and propagate back values from parsers.  */
+    {
+      /* We pass over the groups in reverse order so that child groups are
+         given a chance to do there processing before passing back a value to
+         the parent.  */
+      for (group = parser->egroup - 1
+           ; group >= parser->groups && (!err || err == EBADKEY)
+           ; group--)
+        err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0);
+      if (err == EBADKEY)
+        err = 0;                /* Some parser didn't understand.  */
+    }
+
+  /* Call parsers once more, to do any final cleanup.  Errors are ignored.  */
+  for (group = parser->egroup - 1; group >= parser->groups; group--)
+    group_parse (group, &parser->state, ARGP_KEY_FINI, 0);
+
+  if (err == EBADKEY)
+    err = EINVAL;
+
+  free (parser->storage);
+
+  return err;
+}
+\f
+/* Call the user parsers to parse the non-option argument VAL, at the current
+   position, returning any error.  The state NEXT pointer is assumed to have
+   been adjusted (by getopt) to point after this argument; this function will
+   adjust it correctly to reflect however many args actually end up being
+   consumed.  */
+static error_t
+parser_parse_arg (struct parser *parser, char *val)
+{
+  /* Save the starting value of NEXT, first adjusting it so that the arg
+     we're parsing is again the front of the arg vector.  */
+  int index = --parser->state.next;
+  error_t err = EBADKEY;
+  struct group *group;
+  int key = 0;                  /* Which of ARGP_KEY_ARG[S] we used.  */
+
+  /* Try to parse the argument in each parser.  */
+  for (group = parser->groups
+       ; group < parser->egroup && err == EBADKEY
+       ; group++)
+    {
+      parser->state.next++;     /* For ARGP_KEY_ARG, consume the arg.  */
+      key = ARGP_KEY_ARG;
+      err = group_parse (group, &parser->state, key, val);
+
+      if (err == EBADKEY)
+        /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */
+        {
+          parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg.  */
+          key = ARGP_KEY_ARGS;
+          err = group_parse (group, &parser->state, key, 0);
+        }
+    }
+
+  if (! err)
+    {
+      if (key == ARGP_KEY_ARGS)
+        /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't
+           changed by the user, *all* arguments should be considered
+           consumed.  */
+        parser->state.next = parser->state.argc;
+
+      if (parser->state.next > index)
+        /* Remember that we successfully processed a non-option
+           argument -- but only if the user hasn't gotten tricky and set
+           the clock back.  */
+        (--group)->args_processed += (parser->state.next - index);
+      else
+        /* The user wants to reparse some args, give getopt another try.  */
+        parser->try_getopt = 1;
+    }
+
+  return err;
+}
+\f
+/* Call the user parsers to parse the option OPT, with argument VAL, at the
+   current position, returning any error.  */
+static error_t
+parser_parse_opt (struct parser *parser, int opt, char *val)
+{
+  /* The group key encoded in the high bits; 0 for short opts or
+     group_number + 1 for long opts.  */
+  int group_key = opt >> USER_BITS;
+  error_t err = EBADKEY;
+
+  if (group_key == 0)
+    /* A short option.  By comparing OPT's position in SHORT_OPTS to the
+       various starting positions in each group's SHORT_END field, we can
+       determine which group OPT came from.  */
+    {
+      struct group *group;
+      char *short_index = strchr (parser->short_opts, opt);
+
+      if (short_index)
+        for (group = parser->groups; group < parser->egroup; group++)
+          if (group->short_end > short_index)
+            {
+              err = group_parse (group, &parser->state, opt,
+                                 parser->opt_data.optarg);
+              break;
+            }
+    }
+  else
+    /* A long option.  We use shifts instead of masking for extracting
+       the user value in order to preserve the sign.  */
+    err =
+      group_parse (&parser->groups[group_key - 1], &parser->state,
+                   (opt << GROUP_BITS) >> GROUP_BITS,
+                   parser->opt_data.optarg);
+
+  if (err == EBADKEY)
+    /* At least currently, an option not recognized is an error in the
+       parser, because we pre-compute which parser is supposed to deal
+       with each option.  */
+    {
+      static const char bad_key_err[] =
+        N_("(PROGRAM ERROR) Option should have been recognized!?");
+      if (group_key == 0)
+        __argp_error (&parser->state, "-%c: %s", opt,
+                      dgettext (parser->argp->argp_domain, bad_key_err));
+      else
+        {
+          struct option *long_opt = parser->long_opts;
+          while (long_opt->val != opt && long_opt->name)
+            long_opt++;
+          __argp_error (&parser->state, "--%s: %s",
+                        long_opt->name ? long_opt->name : "???",
+                        dgettext (parser->argp->argp_domain, bad_key_err));
+        }
+    }
+
+  return err;
+}
+\f
+/* Parse the next argument in PARSER (as indicated by PARSER->state.next).
+   Any error from the parsers is returned, and *ARGP_EBADKEY indicates
+   whether a value of EBADKEY is due to an unrecognized argument (which is
+   generally not fatal).  */
+static error_t
+parser_parse_next (struct parser *parser, int *arg_ebadkey)
+{
+  int opt;
+  error_t err = 0;
+
+  if (parser->state.quoted && parser->state.next < parser->state.quoted)
+    /* The next argument pointer has been moved to before the quoted
+       region, so pretend we never saw the quoting `--', and give getopt
+       another chance.  If the user hasn't removed it, getopt will just
+       process it again.  */
+    parser->state.quoted = 0;
+
+  if (parser->try_getopt && !parser->state.quoted)
+    /* Give getopt a chance to parse this.  */
+    {
+      /* Put it back in OPTIND for getopt.  */
+      parser->opt_data.optind = parser->state.next;
+      /* Distinguish KEY_ERR from a real option.  */
+      parser->opt_data.optopt = KEY_END;
+      if (parser->state.flags & ARGP_LONG_ONLY)
+        opt = _getopt_long_only_r (parser->state.argc, parser->state.argv,
+                                   parser->short_opts, parser->long_opts, 0,
+                                   &parser->opt_data);
+      else
+        opt = _getopt_long_r (parser->state.argc, parser->state.argv,
+                              parser->short_opts, parser->long_opts, 0,
+                              &parser->opt_data);
+      /* And see what getopt did.  */
+      parser->state.next = parser->opt_data.optind;
+
+      if (opt == KEY_END)
+        /* Getopt says there are no more options, so stop using
+           getopt; we'll continue if necessary on our own.  */
+        {
+          parser->try_getopt = 0;
+          if (parser->state.next > 1
+              && strcmp (parser->state.argv[parser->state.next - 1], QUOTE)
+                   == 0)
+            /* Not only is this the end of the options, but it's a
+               `quoted' region, which may have args that *look* like
+               options, so we definitely shouldn't try to use getopt past
+               here, whatever happens.  */
+            parser->state.quoted = parser->state.next;
+        }
+      else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END)
+        /* KEY_ERR can have the same value as a valid user short
+           option, but in the case of a real error, getopt sets OPTOPT
+           to the offending character, which can never be KEY_END.  */
+        {
+          *arg_ebadkey = 0;
+          return EBADKEY;
+        }
+    }
+  else
+    opt = KEY_END;
+
+  if (opt == KEY_END)
+    {
+      /* We're past what getopt considers the options.  */
+      if (parser->state.next >= parser->state.argc
+          || (parser->state.flags & ARGP_NO_ARGS))
+        /* Indicate that we're done.  */
+        {
+          *arg_ebadkey = 1;
+          return EBADKEY;
+        }
+      else
+        /* A non-option arg; simulate what getopt might have done.  */
+        {
+          opt = KEY_ARG;
+          parser->opt_data.optarg = parser->state.argv[parser->state.next++];
+        }
+    }
+
+  if (opt == KEY_ARG)
+    /* A non-option argument; try each parser in turn.  */
+    err = parser_parse_arg (parser, parser->opt_data.optarg);
+  else
+    err = parser_parse_opt (parser, opt, parser->opt_data.optarg);
+
+  if (err == EBADKEY)
+    *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG);
+
+  return err;
+}
+\f
+/* Parse the options strings in ARGC & ARGV according to the argp in ARGP.
+   FLAGS is one of the ARGP_ flags above.  If END_INDEX is non-NULL, the
+   index in ARGV of the first unparsed option is returned in it.  If an
+   unknown option is present, EINVAL is returned; if some parser routine
+   returned a non-zero value, it is returned; otherwise 0 is returned.  */
+error_t
+__argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags,
+              int *end_index, void *input)
+{
+  error_t err;
+  struct parser parser;
+
+  /* If true, then err == EBADKEY is a result of a non-option argument failing
+     to be parsed (which in some cases isn't actually an error).  */
+  int arg_ebadkey = 0;
+
+#ifndef _LIBC
+  if (!(flags & ARGP_PARSE_ARGV0))
+    {
+#ifdef HAVE_DECL_PROGRAM_INVOCATION_NAME
+      if (!program_invocation_name)
+        program_invocation_name = argv[0];
+#endif
+#ifdef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
+      if (!program_invocation_short_name)
+        program_invocation_short_name = __argp_base_name (argv[0]);
+#endif
+    }
+#endif
+
+  if (! (flags & ARGP_NO_HELP))
+    /* Add our own options.  */
+    {
+      struct argp_child *child = alloca (4 * sizeof (struct argp_child));
+      struct argp *top_argp = alloca (sizeof (struct argp));
+
+      /* TOP_ARGP has no options, it just serves to group the user & default
+         argps.  */
+      memset (top_argp, 0, sizeof (*top_argp));
+      top_argp->children = child;
+
+      memset (child, 0, 4 * sizeof (struct argp_child));
+
+      if (argp)
+        (child++)->argp = argp;
+      (child++)->argp = &argp_default_argp;
+      if (argp_program_version || argp_program_version_hook)
+        (child++)->argp = &argp_version_argp;
+      child->argp = 0;
+
+      argp = top_argp;
+    }
+
+  /* Construct a parser for these arguments.  */
+  err = parser_init (&parser, argp, argc, argv, flags, input);
+
+  if (! err)
+    /* Parse! */
+    {
+      while (! err)
+        err = parser_parse_next (&parser, &arg_ebadkey);
+      err = parser_finalize (&parser, err, arg_ebadkey, end_index);
+    }
+
+  return err;
+}
+#ifdef weak_alias
+weak_alias (__argp_parse, argp_parse)
+#endif
+\f
+/* Return the input field for ARGP in the parser corresponding to STATE; used
+   by the help routines.  */
+void *
+__argp_input (const struct argp *argp, const struct argp_state *state)
+{
+  if (state)
+    {
+      struct group *group;
+      struct parser *parser = state->pstate;
+
+      for (group = parser->groups; group < parser->egroup; group++)
+        if (group->argp == argp)
+          return group->input;
+    }
+
+  return 0;
+}
+#ifdef weak_alias
+weak_alias (__argp_input, _argp_input)
+#endif
diff --git a/grub-core/gnulib/argp-pin.c b/grub-core/gnulib/argp-pin.c
new file mode 100644 (file)
index 0000000..eda4d95
--- /dev/null
@@ -0,0 +1,27 @@
+/* Full and short program names for argp module
+   Copyright (C) 2005, 2009, 2010 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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME
+char *program_invocation_short_name = 0;
+#endif
+#ifndef HAVE_PROGRAM_INVOCATION_NAME
+char *program_invocation_name = 0;
+#endif
+
diff --git a/grub-core/gnulib/argp-pv.c b/grub-core/gnulib/argp-pv.c
new file mode 100644 (file)
index 0000000..e3227d3
--- /dev/null
@@ -0,0 +1,34 @@
+/* Default definition for ARGP_PROGRAM_VERSION.
+   Copyright (C) 1996, 1997, 1999, 2006, 2009, 2010 Free Software Foundation,
+   Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+/* If set by the user program to a non-zero value, then a default option
+   --version is added (unless the ARGP_NO_HELP flag is used), which will
+   print this string followed by a newline and exit (unless the
+   ARGP_NO_EXIT flag is used).  Overridden by ARGP_PROGRAM_VERSION_HOOK.  */
+const char *argp_program_version
+/* This variable should be zero-initialized.  On most systems, putting it into
+   BSS is sufficient.  Not so on MacOS X 10.3 and 10.4, see
+   <http://lists.gnu.org/archive/html/bug-gnulib/2009-01/msg00329.html>
+   <http://lists.gnu.org/archive/html/bug-gnulib/2009-08/msg00096.html>.  */
+#if defined __ELF__
+  /* On ELF systems, variables in BSS behave well.  */
+#else
+  = (const char *) 0
+#endif
+  ;
diff --git a/grub-core/gnulib/argp-pvh.c b/grub-core/gnulib/argp-pvh.c
new file mode 100644 (file)
index 0000000..fb98fc2
--- /dev/null
@@ -0,0 +1,31 @@
+/* Default definition for ARGP_PROGRAM_VERSION_HOOK.
+   Copyright (C) 1996, 1997, 1999, 2004, 2009, 2010 Free Software Foundation,
+   Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "argp.h"
+
+/* If set by the user program to a non-zero value, then a default option
+   --version is added (unless the ARGP_NO_HELP flag is used), which calls
+   this function with a stream to print the version to and a pointer to the
+   current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
+   used).  This variable takes precedent over ARGP_PROGRAM_VERSION.  */
+void (*argp_program_version_hook) (FILE *stream, struct argp_state *state) = NULL;
diff --git a/grub-core/gnulib/argp-version-etc.c b/grub-core/gnulib/argp-version-etc.c
new file mode 100644 (file)
index 0000000..f500a8f
--- /dev/null
@@ -0,0 +1,38 @@
+/* Version hook for Argp.
+   Copyright (C) 2009, 2010 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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <version-etc.h>
+#include <argp.h>
+#include <argp-version-etc.h>
+
+static const char *program_canonical_name;
+static const char * const *program_authors;
+
+static void
+version_etc_hook (FILE *stream, struct argp_state *state)
+{
+  version_etc_ar (stream, program_canonical_name, PACKAGE_NAME, VERSION,
+                  program_authors);
+}
+
+void
+argp_version_setup (const char *name, const char * const *authors)
+{
+  argp_program_version_hook = version_etc_hook;
+  program_canonical_name = name;
+  program_authors = authors;
+}
diff --git a/grub-core/gnulib/argp-version-etc.h b/grub-core/gnulib/argp-version-etc.h
new file mode 100644 (file)
index 0000000..7c12c01
--- /dev/null
@@ -0,0 +1,40 @@
+/* Version hook for Argp.
+   Copyright (C) 2009, 2010 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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _ARGP_VERSION_ETC_H
+#define _ARGP_VERSION_ETC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Setup standard display of the version information for the `--version'
+   option.  NAME is the canonical program name, and AUTHORS is a NULL-
+   terminated array of author names. At least one author name must be
+   given.
+
+   If NAME is NULL, the package name (as given by the PACKAGE macro)
+   is asumed to be the name of the program.
+
+   This function is intended to be called before argp_parse().
+*/
+extern void argp_version_setup (const char *name, const char * const *authors);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ARGP_VERSION_ETC_H */
diff --git a/grub-core/gnulib/argp-xinl.c b/grub-core/gnulib/argp-xinl.c
new file mode 100644 (file)
index 0000000..6e7e20b
--- /dev/null
@@ -0,0 +1,42 @@
+/* Real definitions for extern inline functions in argp.h
+   Copyright (C) 1997, 1998, 2004, 2009, 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined _LIBC || defined HAVE_FEATURES_H
+# include <features.h>
+#endif
+
+#ifndef __USE_EXTERN_INLINES
+# define __USE_EXTERN_INLINES   1
+#endif
+#define ARGP_EI
+#undef __OPTIMIZE__
+#define __OPTIMIZE__ 1
+#include "argp.h"
+
+/* Add weak aliases.  */
+#if _LIBC - 0 && defined (weak_alias)
+
+weak_alias (__argp_usage, argp_usage)
+weak_alias (__option_is_short, _option_is_short)
+weak_alias (__option_is_end, _option_is_end)
+
+#endif
diff --git a/grub-core/gnulib/argp.h b/grub-core/gnulib/argp.h
new file mode 100644 (file)
index 0000000..3667224
--- /dev/null
@@ -0,0 +1,645 @@
+/* Hierarchial argument parsing, layered over getopt.
+   Copyright (C) 1995-1999, 2003-2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Written by Miles Bader <miles@gnu.ai.mit.edu>.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _ARGP_H
+#define _ARGP_H
+
+#include <stdio.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <limits.h>
+
+#define __need_error_t
+#include <errno.h>
+
+#ifndef __THROW
+# define __THROW
+#endif
+#ifndef __NTH
+# define __NTH(fct) fct __THROW
+#endif
+
+#ifndef __attribute__
+/* The __attribute__ feature is available in gcc versions 2.5 and later.
+   The __-protected variants of the attributes 'format' and 'printf' are
+   accepted by gcc versions 2.6.4 (effectively 2.7) and later.
+   We enable __attribute__ only if these are supported too, because
+   gnulib and libintl do '#define printf __printf__' when they override
+   the 'printf' function.  */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
+#  define __attribute__(Spec)   /* empty */
+# endif
+#endif
+
+/* GCC 2.95 and later have "__restrict"; C99 compilers have
+   "restrict", and "configure" may have defined "restrict".
+   Other compilers use __restrict, __restrict__, and _Restrict, and
+   'configure' might #define 'restrict' to those words.  */
+#ifndef __restrict
+# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
+#  if 199901L <= __STDC_VERSION__
+#   define __restrict restrict
+#  else
+#   define __restrict
+#  endif
+# endif
+#endif
+
+#ifndef __error_t_defined
+typedef int error_t;
+# define __error_t_defined
+#endif
+\f
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* A description of a particular option.  A pointer to an array of
+   these is passed in the OPTIONS field of an argp structure.  Each option
+   entry can correspond to one long option and/or one short option; more
+   names for the same option can be added by following an entry in an option
+   array with options having the OPTION_ALIAS flag set.  */
+struct argp_option
+{
+  /* The long option name.  For more than one name for the same option, you
+     can use following options with the OPTION_ALIAS flag set.  */
+  const char *name;
+
+  /* What key is returned for this option.  If > 0 and printable, then it's
+     also accepted as a short option.  */
+  int key;
+
+  /* If non-NULL, this is the name of the argument associated with this
+     option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */
+  const char *arg;
+
+  /* OPTION_ flags.  */
+  int flags;
+
+  /* The doc string for this option.  If both NAME and KEY are 0, This string
+     will be printed outdented from the normal option column, making it
+     useful as a group header (it will be the first thing printed in its
+     group); in this usage, it's conventional to end the string with a `:'.
+
+     Write the initial value as N_("TEXT") if you want xgettext to collect
+     it into a POT file.  */
+  const char *doc;
+
+  /* The group this option is in.  In a long help message, options are sorted
+     alphabetically within each group, and the groups presented in the order
+     0, 1, 2, ..., n, -m, ..., -2, -1.  Every entry in an options array with
+     if this field 0 will inherit the group number of the previous entry, or
+     zero if it's the first one, unless its a group header (NAME and KEY both
+     0), in which case, the previous entry + 1 is the default.  Automagic
+     options such as --help are put into group -1.  */
+  int group;
+};
+
+/* The argument associated with this option is optional.  */
+#define OPTION_ARG_OPTIONAL     0x1
+
+/* This option isn't displayed in any help messages.  */
+#define OPTION_HIDDEN           0x2
+
+/* This option is an alias for the closest previous non-alias option.  This
+   means that it will be displayed in the same help entry, and will inherit
+   fields other than NAME and KEY from the aliased option.  */
+#define OPTION_ALIAS            0x4
+
+/* This option isn't actually an option (and so should be ignored by the
+   actual option parser), but rather an arbitrary piece of documentation that
+   should be displayed in much the same manner as the options.  If this flag
+   is set, then the option NAME field is displayed unmodified (e.g., no `--'
+   prefix is added) at the left-margin (where a *short* option would normally
+   be displayed), and the documentation string in the normal place. The NAME
+   field will be translated using gettext, unless OPTION_NO_TRANS is set (see
+   below). For purposes of sorting, any leading whitespace and punctuation is
+   ignored, except that if the first non-whitespace character is not `-', this
+   entry is displayed after all options (and OPTION_DOC entries with a leading
+   `-') in the same group.  */
+#define OPTION_DOC              0x8
+
+/* This option shouldn't be included in `long' usage messages (but is still
+   included in help messages).  This is mainly intended for options that are
+   completely documented in an argp's ARGS_DOC field, in which case including
+   the option in the generic usage list would be redundant.  For instance,
+   if ARGS_DOC is "FOO BAR\n-x BLAH", and the `-x' option's purpose is to
+   distinguish these two cases, -x should probably be marked
+   OPTION_NO_USAGE.  */
+#define OPTION_NO_USAGE         0x10
+
+/* Valid only in conjunction with OPTION_DOC. This option disables translation
+   of option name. */
+#define OPTION_NO_TRANS         0x20
+
+\f
+struct argp;                    /* fwd declare this type */
+struct argp_state;              /* " */
+struct argp_child;              /* " */
+
+/* The type of a pointer to an argp parsing function.  */
+typedef error_t (*argp_parser_t) (int key, char *arg,
+                                  struct argp_state *state);
+
+/* What to return for unrecognized keys.  For special ARGP_KEY_ keys, such
+   returns will simply be ignored.  For user keys, this error will be turned
+   into EINVAL (if the call to argp_parse is such that errors are propagated
+   back to the user instead of exiting); returning EINVAL itself would result
+   in an immediate stop to parsing in *all* cases.  */
+#define ARGP_ERR_UNKNOWN        E2BIG /* Hurd should never need E2BIG.  XXX */
+
+/* Special values for the KEY argument to an argument parsing function.
+   ARGP_ERR_UNKNOWN should be returned if they aren't understood.
+
+   The sequence of keys to a parsing function is either (where each
+   uppercased word should be prefixed by `ARGP_KEY_' and opt is a user key):
+
+       INIT opt... NO_ARGS END SUCCESS  -- No non-option arguments at all
+   or  INIT (opt | ARG)... END SUCCESS  -- All non-option args parsed
+   or  INIT (opt | ARG)... SUCCESS      -- Some non-option arg unrecognized
+
+   The third case is where every parser returned ARGP_KEY_UNKNOWN for an
+   argument, in which case parsing stops at that argument (returning the
+   unparsed arguments to the caller of argp_parse if requested, or stopping
+   with an error message if not).
+
+   If an error occurs (either detected by argp, or because the parsing
+   function returned an error value), then the parser is called with
+   ARGP_KEY_ERROR, and no further calls are made.  */
+
+/* This is not an option at all, but rather a command line argument.  If a
+   parser receiving this key returns success, the fact is recorded, and the
+   ARGP_KEY_NO_ARGS case won't be used.  HOWEVER, if while processing the
+   argument, a parser function decrements the NEXT field of the state it's
+   passed, the option won't be considered processed; this is to allow you to
+   actually modify the argument (perhaps into an option), and have it
+   processed again.  */
+#define ARGP_KEY_ARG            0
+/* There are remaining arguments not parsed by any parser, which may be found
+   starting at (STATE->argv + STATE->next).  If success is returned, but
+   STATE->next left untouched, it's assumed that all arguments were consume,
+   otherwise, the parser should adjust STATE->next to reflect any arguments
+   consumed.  */
+#define ARGP_KEY_ARGS           0x1000006
+/* There are no more command line arguments at all.  */
+#define ARGP_KEY_END            0x1000001
+/* Because it's common to want to do some special processing if there aren't
+   any non-option args, user parsers are called with this key if they didn't
+   successfully process any non-option arguments.  Called just before
+   ARGP_KEY_END (where more general validity checks on previously parsed
+   arguments can take place).  */
+#define ARGP_KEY_NO_ARGS        0x1000002
+/* Passed in before any parsing is done.  Afterwards, the values of each
+   element of the CHILD_INPUT field, if any, in the state structure is
+   copied to each child's state to be the initial value of the INPUT field.  */
+#define ARGP_KEY_INIT           0x1000003
+/* Use after all other keys, including SUCCESS & END.  */
+#define ARGP_KEY_FINI           0x1000007
+/* Passed in when parsing has successfully been completed (even if there are
+   still arguments remaining).  */
+#define ARGP_KEY_SUCCESS        0x1000004
+/* Passed in if an error occurs.  */
+#define ARGP_KEY_ERROR          0x1000005
+
+/* An argp structure contains a set of options declarations, a function to
+   deal with parsing one, documentation string, a possible vector of child
+   argp's, and perhaps a function to filter help output.  When actually
+   parsing options, getopt is called with the union of all the argp
+   structures chained together through their CHILD pointers, with conflicts
+   being resolved in favor of the first occurrence in the chain.  */
+struct argp
+{
+  /* An array of argp_option structures, terminated by an entry with both
+     NAME and KEY having a value of 0.  */
+  const struct argp_option *options;
+
+  /* What to do with an option from this structure.  KEY is the key
+     associated with the option, and ARG is any associated argument (NULL if
+     none was supplied).  If KEY isn't understood, ARGP_ERR_UNKNOWN should be
+     returned.  If a non-zero, non-ARGP_ERR_UNKNOWN value is returned, then
+     parsing is stopped immediately, and that value is returned from
+     argp_parse().  For special (non-user-supplied) values of KEY, see the
+     ARGP_KEY_ definitions below.  */
+  argp_parser_t parser;
+
+  /* A string describing what other arguments are wanted by this program.  It
+     is only used by argp_usage to print the `Usage:' message.  If it
+     contains newlines, the strings separated by them are considered
+     alternative usage patterns, and printed on separate lines (lines after
+     the first are prefix by `  or: ' instead of `Usage:').  */
+  const char *args_doc;
+
+  /* If non-NULL, a string containing extra text to be printed before and
+     after the options in a long help message (separated by a vertical tab
+     `\v' character).
+     Write the initial value as N_("BEFORE-TEXT") "\v" N_("AFTER-TEXT") if
+     you want xgettext to collect the two pieces of text into a POT file.  */
+  const char *doc;
+
+  /* A vector of argp_children structures, terminated by a member with a 0
+     argp field, pointing to child argps should be parsed with this one.  Any
+     conflicts are resolved in favor of this argp, or early argps in the
+     CHILDREN list.  This field is useful if you use libraries that supply
+     their own argp structure, which you want to use in conjunction with your
+     own.  */
+  const struct argp_child *children;
+
+  /* If non-zero, this should be a function to filter the output of help
+     messages.  KEY is either a key from an option, in which case TEXT is
+     that option's help text, or a special key from the ARGP_KEY_HELP_
+     defines, below, describing which other help text TEXT is.  The function
+     should return either TEXT, if it should be used as-is, a replacement
+     string, which should be malloced, and will be freed by argp, or NULL,
+     meaning `print nothing'.  The value for TEXT is *after* any translation
+     has been done, so if any of the replacement text also needs translation,
+     that should be done by the filter function.  INPUT is either the input
+     supplied to argp_parse, or NULL, if argp_help was called directly.  */
+  char *(*help_filter) (int __key, const char *__text, void *__input);
+
+  /* If non-zero the strings used in the argp library are translated using
+     the domain described by this string.  Otherwise the currently installed
+     default domain is used.  */
+  const char *argp_domain;
+};
+
+/* Possible KEY arguments to a help filter function.  */
+#define ARGP_KEY_HELP_PRE_DOC   0x2000001 /* Help text preceeding options. */
+#define ARGP_KEY_HELP_POST_DOC  0x2000002 /* Help text following options. */
+#define ARGP_KEY_HELP_HEADER    0x2000003 /* Option header string. */
+#define ARGP_KEY_HELP_EXTRA     0x2000004 /* After all other documentation;
+                                             TEXT is NULL for this key.  */
+/* Explanatory note emitted when duplicate option arguments have been
+   suppressed.  */
+#define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005
+#define ARGP_KEY_HELP_ARGS_DOC  0x2000006 /* Argument doc string.  */
+\f
+/* When an argp has a non-zero CHILDREN field, it should point to a vector of
+   argp_child structures, each of which describes a subsidiary argp.  */
+struct argp_child
+{
+  /* The child parser.  */
+  const struct argp *argp;
+
+  /* Flags for this child.  */
+  int flags;
+
+  /* If non-zero, an optional header to be printed in help output before the
+     child options.  As a side-effect, a non-zero value forces the child
+     options to be grouped together; to achieve this effect without actually
+     printing a header string, use a value of "".  */
+  const char *header;
+
+  /* Where to group the child options relative to the other (`consolidated')
+     options in the parent argp; the values are the same as the GROUP field
+     in argp_option structs, but all child-groupings follow parent options at
+     a particular group level.  If both this field and HEADER are zero, then
+     they aren't grouped at all, but rather merged with the parent options
+     (merging the child's grouping levels with the parents).  */
+  int group;
+};
+\f
+/* Parsing state.  This is provided to parsing functions called by argp,
+   which may examine and, as noted, modify fields.  */
+struct argp_state
+{
+  /* The top level ARGP being parsed.  */
+  const struct argp *root_argp;
+
+  /* The argument vector being parsed.  May be modified.  */
+  int argc;
+  char **argv;
+
+  /* The index in ARGV of the next arg that to be parsed.  May be modified. */
+  int next;
+
+  /* The flags supplied to argp_parse.  May be modified.  */
+  unsigned flags;
+
+  /* While calling a parsing function with a key of ARGP_KEY_ARG, this is the
+     number of the current arg, starting at zero, and incremented after each
+     such call returns.  At all other times, this is the number of such
+     arguments that have been processed.  */
+  unsigned arg_num;
+
+  /* If non-zero, the index in ARGV of the first argument following a special
+     `--' argument (which prevents anything following being interpreted as an
+     option).  Only set once argument parsing has proceeded past this point. */
+  int quoted;
+
+  /* An arbitrary pointer passed in from the user.  */
+  void *input;
+  /* Values to pass to child parsers.  This vector will be the same length as
+     the number of children for the current parser.  */
+  void **child_inputs;
+
+  /* For the parser's use.  Initialized to 0.  */
+  void *hook;
+
+  /* The name used when printing messages.  This is initialized to ARGV[0],
+     or PROGRAM_INVOCATION_NAME if that is unavailable.  */
+  char *name;
+
+  /* Streams used when argp prints something.  */
+  FILE *err_stream;             /* For errors; initialized to stderr. */
+  FILE *out_stream;             /* For information; initialized to stdout. */
+
+  void *pstate;                 /* Private, for use by argp.  */
+};
+\f
+/* Flags for argp_parse (note that the defaults are those that are
+   convenient for program command line parsing): */
+
+/* Don't ignore the first element of ARGV.  Normally (and always unless
+   ARGP_NO_ERRS is set) the first element of the argument vector is
+   skipped for option parsing purposes, as it corresponds to the program name
+   in a command line.  */
+#define ARGP_PARSE_ARGV0  0x01
+
+/* Don't print error messages for unknown options to stderr; unless this flag
+   is set, ARGP_PARSE_ARGV0 is ignored, as ARGV[0] is used as the program
+   name in the error messages.  This flag implies ARGP_NO_EXIT (on the
+   assumption that silent exiting upon errors is bad behaviour).  */
+#define ARGP_NO_ERRS    0x02
+
+/* Don't parse any non-option args.  Normally non-option args are parsed by
+   calling the parse functions with a key of ARGP_KEY_ARG, and the actual arg
+   as the value.  Since it's impossible to know which parse function wants to
+   handle it, each one is called in turn, until one returns 0 or an error
+   other than ARGP_ERR_UNKNOWN; if an argument is handled by no one, the
+   argp_parse returns prematurely (but with a return value of 0).  If all
+   args have been parsed without error, all parsing functions are called one
+   last time with a key of ARGP_KEY_END.  This flag needn't normally be set,
+   as the normal behavior is to stop parsing as soon as some argument can't
+   be handled.  */
+#define ARGP_NO_ARGS    0x04
+
+/* Parse options and arguments in the same order they occur on the command
+   line -- normally they're rearranged so that all options come first. */
+#define ARGP_IN_ORDER   0x08
+
+/* Don't provide the standard long option --help, which causes usage and
+      option help information to be output to stdout, and exit (0) called. */
+#define ARGP_NO_HELP    0x10
+
+/* Don't exit on errors (they may still result in error messages).  */
+#define ARGP_NO_EXIT    0x20
+
+/* Use the gnu getopt `long-only' rules for parsing arguments.  */
+#define ARGP_LONG_ONLY  0x40
+
+/* Turns off any message-printing/exiting options.  */
+#define ARGP_SILENT    (ARGP_NO_EXIT | ARGP_NO_ERRS | ARGP_NO_HELP)
+
+/* Parse the options strings in ARGC & ARGV according to the options in ARGP.
+   FLAGS is one of the ARGP_ flags above.  If ARG_INDEX is non-NULL, the
+   index in ARGV of the first unparsed option is returned in it.  If an
+   unknown option is present, ARGP_ERR_UNKNOWN is returned; if some parser
+   routine returned a non-zero value, it is returned; otherwise 0 is
+   returned.  This function may also call exit unless the ARGP_NO_HELP flag
+   is set.  INPUT is a pointer to a value to be passed in to the parser.  */
+extern error_t argp_parse (const struct argp *__restrict __argp,
+                           int /*argc*/, char **__restrict /*argv*/,
+                           unsigned __flags, int *__restrict __arg_index,
+                           void *__restrict __input);
+extern error_t __argp_parse (const struct argp *__restrict __argp,
+                             int /*argc*/, char **__restrict /*argv*/,
+                             unsigned __flags, int *__restrict __arg_index,
+                             void *__restrict __input);
+\f
+/* Global variables.  */
+
+/* GNULIB makes sure both program_invocation_name and
+   program_invocation_short_name are available */
+#ifdef GNULIB_PROGRAM_INVOCATION_NAME
+extern char *program_invocation_name;
+# undef HAVE_DECL_PROGRAM_INVOCATION_NAME
+# define HAVE_DECL_PROGRAM_INVOCATION_NAME 1
+#endif
+
+#ifdef GNULIB_PROGRAM_INVOCATION_SHORT_NAME
+extern char *program_invocation_short_name;
+# undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
+# define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 1
+#endif
+
+/* If defined or set by the user program to a non-zero value, then a default
+   option --version is added (unless the ARGP_NO_HELP flag is used), which
+   will print this string followed by a newline and exit (unless the
+   ARGP_NO_EXIT flag is used).  Overridden by ARGP_PROGRAM_VERSION_HOOK.  */
+extern const char *argp_program_version;
+
+/* If defined or set by the user program to a non-zero value, then a default
+   option --version is added (unless the ARGP_NO_HELP flag is used), which
+   calls this function with a stream to print the version to and a pointer to
+   the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
+   used).  This variable takes precedent over ARGP_PROGRAM_VERSION.  */
+extern void (*argp_program_version_hook) (FILE *__restrict __stream,
+                                          struct argp_state *__restrict
+                                          __state);
+
+/* If defined or set by the user program, it should point to string that is
+   the bug-reporting address for the program.  It will be printed by
+   argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various
+   standard help messages), embedded in a sentence that says something like
+   `Report bugs to ADDR.'.  */
+extern const char *argp_program_bug_address;
+
+/* The exit status that argp will use when exiting due to a parsing error.
+   If not defined or set by the user program, this defaults to EX_USAGE from
+   <sysexits.h>.  */
+extern error_t argp_err_exit_status;
+\f
+/* Flags for argp_help.  */
+#define ARGP_HELP_USAGE         0x01 /* a Usage: message. */
+#define ARGP_HELP_SHORT_USAGE   0x02 /*  " but don't actually print options. */
+#define ARGP_HELP_SEE           0x04 /* a `Try ... for more help' message. */
+#define ARGP_HELP_LONG          0x08 /* a long help message. */
+#define ARGP_HELP_PRE_DOC       0x10 /* doc string preceding long help.  */
+#define ARGP_HELP_POST_DOC      0x20 /* doc string following long help.  */
+#define ARGP_HELP_DOC           (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC)
+#define ARGP_HELP_BUG_ADDR      0x40 /* bug report address */
+#define ARGP_HELP_LONG_ONLY     0x80 /* modify output appropriately to
+                                        reflect ARGP_LONG_ONLY mode.  */
+
+/* These ARGP_HELP flags are only understood by argp_state_help.  */
+#define ARGP_HELP_EXIT_ERR      0x100 /* Call exit(1) instead of returning.  */
+#define ARGP_HELP_EXIT_OK       0x200 /* Call exit(0) instead of returning.  */
+
+/* The standard thing to do after a program command line parsing error, if an
+   error message has already been printed.  */
+#define ARGP_HELP_STD_ERR \
+  (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
+/* The standard thing to do after a program command line parsing error, if no
+   more specific error message has been printed.  */
+#define ARGP_HELP_STD_USAGE \
+  (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
+/* The standard thing to do in response to a --help option.  */
+#define ARGP_HELP_STD_HELP \
+  (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \
+   | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR)
+
+/* Output a usage message for ARGP to STREAM.  FLAGS are from the set
+   ARGP_HELP_*.  */
+extern void argp_help (const struct argp *__restrict __argp,
+                       FILE *__restrict __stream,
+                       unsigned __flags, char *__restrict __name);
+extern void __argp_help (const struct argp *__restrict __argp,
+                         FILE *__restrict __stream, unsigned __flags,
+                         char *__name);
+\f
+/* The following routines are intended to be called from within an argp
+   parsing routine (thus taking an argp_state structure as the first
+   argument).  They may or may not print an error message and exit, depending
+   on the flags in STATE -- in any case, the caller should be prepared for
+   them *not* to exit, and should return an appropiate error after calling
+   them.  [argp_usage & argp_error should probably be called argp_state_...,
+   but they're used often enough that they should be short]  */
+
+/* Output, if appropriate, a usage message for STATE to STREAM.  FLAGS are
+   from the set ARGP_HELP_*.  */
+extern void argp_state_help (const struct argp_state *__restrict __state,
+                             FILE *__restrict __stream,
+                             unsigned int __flags);
+extern void __argp_state_help (const struct argp_state *__restrict __state,
+                               FILE *__restrict __stream,
+                               unsigned int __flags);
+
+#if _LIBC || !defined __USE_EXTERN_INLINES
+/* Possibly output the standard usage message for ARGP to stderr and exit.  */
+extern void argp_usage (const struct argp_state *__state);
+extern void __argp_usage (const struct argp_state *__state);
+#endif
+
+/* If appropriate, print the printf string FMT and following args, preceded
+   by the program name and `:', to stderr, and followed by a `Try ... --help'
+   message, then exit (1).  */
+extern void argp_error (const struct argp_state *__restrict __state,
+                        const char *__restrict __fmt, ...)
+     __attribute__ ((__format__ (__printf__, 2, 3)));
+extern void __argp_error (const struct argp_state *__restrict __state,
+                          const char *__restrict __fmt, ...)
+     __attribute__ ((__format__ (__printf__, 2, 3)));
+
+/* Similar to the standard gnu error-reporting function error(), but will
+   respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
+   to STATE->err_stream.  This is useful for argument parsing code that is
+   shared between program startup (when exiting is desired) and runtime
+   option parsing (when typically an error code is returned instead).  The
+   difference between this function and argp_error is that the latter is for
+   *parsing errors*, and the former is for other problems that occur during
+   parsing but don't reflect a (syntactic) problem with the input.  */
+extern void argp_failure (const struct argp_state *__restrict __state,
+                          int __status, int __errnum,
+                          const char *__restrict __fmt, ...)
+     __attribute__ ((__format__ (__printf__, 4, 5)));
+extern void __argp_failure (const struct argp_state *__restrict __state,
+                            int __status, int __errnum,
+                            const char *__restrict __fmt, ...)
+     __attribute__ ((__format__ (__printf__, 4, 5)));
+
+#if _LIBC || !defined __USE_EXTERN_INLINES
+/* Returns true if the option OPT is a valid short option.  */
+extern int _option_is_short (const struct argp_option *__opt) __THROW;
+extern int __option_is_short (const struct argp_option *__opt) __THROW;
+
+/* Returns true if the option OPT is in fact the last (unused) entry in an
+   options array.  */
+extern int _option_is_end (const struct argp_option *__opt) __THROW;
+extern int __option_is_end (const struct argp_option *__opt) __THROW;
+#endif
+
+/* Return the input field for ARGP in the parser corresponding to STATE; used
+   by the help routines.  */
+extern void *_argp_input (const struct argp *__restrict __argp,
+                          const struct argp_state *__restrict __state)
+     __THROW;
+extern void *__argp_input (const struct argp *__restrict __argp,
+                           const struct argp_state *__restrict __state)
+     __THROW;
+\f
+#ifdef __USE_EXTERN_INLINES
+
+# if !_LIBC
+#  define __argp_usage argp_usage
+#  define __argp_state_help argp_state_help
+#  define __option_is_short _option_is_short
+#  define __option_is_end _option_is_end
+# endif
+
+# ifndef ARGP_EI
+#  ifdef __GNUC__
+    /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
+       inline semantics, unless -fgnu89-inline is used.  It defines a macro
+       __GNUC_STDC_INLINE__ to indicate this situation or a macro
+       __GNUC_GNU_INLINE__ to indicate the opposite situation.
+       GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline
+       semantics but warns, unless -fgnu89-inline is used:
+         warning: C99 inline functions are not supported; using GNU89
+         warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute
+       It defines a macro __GNUC_GNU_INLINE__ to indicate this situation.  */
+#   if defined __GNUC_STDC_INLINE__
+#    define ARGP_EI __inline__
+#   elif defined __GNUC_GNU_INLINE__
+#    define ARGP_EI extern __inline__ __attribute__ ((__gnu_inline__))
+#   else
+#    define ARGP_EI extern __inline__
+#   endif
+#  else
+    /* With other compilers, assume the ISO C99 meaning of 'inline', if
+       the compiler supports 'inline' at all.  */
+#   define ARGP_EI inline
+#  endif
+# endif
+
+ARGP_EI void
+__argp_usage (const struct argp_state *__state)
+{
+  __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE);
+}
+
+ARGP_EI int
+__NTH (__option_is_short (const struct argp_option *__opt))
+{
+  if (__opt->flags & OPTION_DOC)
+    return 0;
+  else
+    {
+      int __key = __opt->key;
+      return __key > 0 && __key <= UCHAR_MAX && isprint (__key);
+    }
+}
+
+ARGP_EI int
+__NTH (__option_is_end (const struct argp_option *__opt))
+{
+  return !__opt->key && !__opt->name && !__opt->doc && !__opt->group;
+}
+
+# if !_LIBC
+#  undef __argp_usage
+#  undef __argp_state_help
+#  undef __option_is_short
+#  undef __option_is_end
+# endif
+#endif /* Use extern inlines.  */
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* argp.h */
diff --git a/grub-core/gnulib/error.c b/grub-core/gnulib/error.c
new file mode 100644 (file)
index 0000000..c79e8d4
--- /dev/null
@@ -0,0 +1,366 @@
+/* Error handler for noninteractive utilities
+   Copyright (C) 1990-1998, 2000-2007, 2009-2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
+
+#if !_LIBC
+# include <config.h>
+#endif
+
+#include "error.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !_LIBC && ENABLE_NLS
+# include "gettext.h"
+# define _(msgid) gettext (msgid)
+#endif
+
+#ifdef _LIBC
+# include <libintl.h>
+# include <stdbool.h>
+# include <stdint.h>
+# include <wchar.h>
+# define mbsrtowcs __mbsrtowcs
+#endif
+
+#if USE_UNLOCKED_IO
+# include "unlocked-io.h"
+#endif
+
+#ifndef _
+# define _(String) String
+#endif
+
+/* If NULL, error will flush stdout, then print on stderr the program
+   name, a colon and a space.  Otherwise, error will call this
+   function without parameters instead.  */
+void (*error_print_progname) (void);
+
+/* This variable is incremented each time `error' is called.  */
+unsigned int error_message_count;
+
+#ifdef _LIBC
+/* In the GNU C library, there is a predefined variable for this.  */
+
+# define program_name program_invocation_name
+# include <errno.h>
+# include <limits.h>
+# include <libio/libioP.h>
+
+/* In GNU libc we want do not want to use the common name `error' directly.
+   Instead make it a weak alias.  */
+extern void __error (int status, int errnum, const char *message, ...)
+     __attribute__ ((__format__ (__printf__, 3, 4)));
+extern void __error_at_line (int status, int errnum, const char *file_name,
+                             unsigned int line_number, const char *message,
+                             ...)
+     __attribute__ ((__format__ (__printf__, 5, 6)));;
+# define error __error
+# define error_at_line __error_at_line
+
+# include <libio/iolibio.h>
+# define fflush(s) INTUSE(_IO_fflush) (s)
+# undef putc
+# define putc(c, fp) INTUSE(_IO_putc) (c, fp)
+
+# include <bits/libc-lock.h>
+
+#else /* not _LIBC */
+
+# include <fcntl.h>
+# include <unistd.h>
+
+# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
+#  ifndef HAVE_DECL_STRERROR_R
+"this configure-time declaration test was not run"
+#  endif
+char *strerror_r ();
+# endif
+
+/* The calling program should define program_name and set it to the
+   name of the executing program.  */
+extern char *program_name;
+
+# if HAVE_STRERROR_R || defined strerror_r
+#  define __strerror_r strerror_r
+# endif /* HAVE_STRERROR_R || defined strerror_r */
+#endif  /* not _LIBC */
+
+static inline void
+flush_stdout (void)
+{
+#if !_LIBC && defined F_GETFL
+  int stdout_fd;
+
+# if GNULIB_FREOPEN_SAFER
+  /* Use of gnulib's freopen-safer module normally ensures that
+       fileno (stdout) == 1
+     whenever stdout is open.  */
+  stdout_fd = STDOUT_FILENO;
+# else
+  /* POSIX states that fileno (stdout) after fclose is unspecified.  But in
+     practice it is not a problem, because stdout is statically allocated and
+     the fd of a FILE stream is stored as a field in its allocated memory.  */
+  stdout_fd = fileno (stdout);
+# endif
+  /* POSIX states that fflush (stdout) after fclose is unspecified; it
+     is safe in glibc, but not on all other platforms.  fflush (NULL)
+     is always defined, but too draconian.  */
+  if (0 <= stdout_fd && 0 <= fcntl (stdout_fd, F_GETFL))
+#endif
+    fflush (stdout);
+}
+
+static void
+print_errno_message (int errnum)
+{
+  char const *s;
+
+#if defined HAVE_STRERROR_R || _LIBC
+  char errbuf[1024];
+# if STRERROR_R_CHAR_P || _LIBC
+  s = __strerror_r (errnum, errbuf, sizeof errbuf);
+# else
+  if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
+    s = errbuf;
+  else
+    s = 0;
+# endif
+#else
+  s = strerror (errnum);
+#endif
+
+#if !_LIBC
+  if (! s)
+    s = _("Unknown system error");
+#endif
+
+#if _LIBC
+  __fxprintf (NULL, ": %s", s);
+#else
+  fprintf (stderr, ": %s", s);
+#endif
+}
+
+static void
+error_tail (int status, int errnum, const char *message, va_list args)
+{
+#if _LIBC
+  if (_IO_fwide (stderr, 0) > 0)
+    {
+# define ALLOCA_LIMIT 2000
+      size_t len = strlen (message) + 1;
+      wchar_t *wmessage = NULL;
+      mbstate_t st;
+      size_t res;
+      const char *tmp;
+      bool use_malloc = false;
+
+      while (1)
+        {
+          if (__libc_use_alloca (len * sizeof (wchar_t)))
+            wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
+          else
+            {
+              if (!use_malloc)
+                wmessage = NULL;
+
+              wchar_t *p = (wchar_t *) realloc (wmessage,
+                                                len * sizeof (wchar_t));
+              if (p == NULL)
+                {
+                  free (wmessage);
+                  fputws_unlocked (L"out of memory\n", stderr);
+                  return;
+                }
+              wmessage = p;
+              use_malloc = true;
+            }
+
+          memset (&st, '\0', sizeof (st));
+          tmp = message;
+
+          res = mbsrtowcs (wmessage, &tmp, len, &st);
+          if (res != len)
+            break;
+
+          if (__builtin_expect (len >= SIZE_MAX / 2, 0))
+            {
+              /* This really should not happen if everything is fine.  */
+              res = (size_t) -1;
+              break;
+            }
+
+          len *= 2;
+        }
+
+      if (res == (size_t) -1)
+        {
+          /* The string cannot be converted.  */
+          if (use_malloc)
+            {
+              free (wmessage);
+              use_malloc = false;
+            }
+          wmessage = (wchar_t *) L"???";
+        }
+
+      __vfwprintf (stderr, wmessage, args);
+
+      if (use_malloc)
+        free (wmessage);
+    }
+  else
+#endif
+    vfprintf (stderr, message, args);
+  va_end (args);
+
+  ++error_message_count;
+  if (errnum)
+    print_errno_message (errnum);
+#if _LIBC
+  __fxprintf (NULL, "\n");
+#else
+  putc ('\n', stderr);
+#endif
+  fflush (stderr);
+  if (status)
+    exit (status);
+}
+
+
+/* Print the program name and error message MESSAGE, which is a printf-style
+   format string with optional args.
+   If ERRNUM is nonzero, print its corresponding system error message.
+   Exit with status STATUS if it is nonzero.  */
+void
+error (int status, int errnum, const char *message, ...)
+{
+  va_list args;
+
+#if defined _LIBC && defined __libc_ptf_call
+  /* We do not want this call to be cut short by a thread
+     cancellation.  Therefore disable cancellation for now.  */
+  int state = PTHREAD_CANCEL_ENABLE;
+  __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
+                   0);
+#endif
+
+  flush_stdout ();
+#ifdef _LIBC
+  _IO_flockfile (stderr);
+#endif
+  if (error_print_progname)
+    (*error_print_progname) ();
+  else
+    {
+#if _LIBC
+      __fxprintf (NULL, "%s: ", program_name);
+#else
+      fprintf (stderr, "%s: ", program_name);
+#endif
+    }
+
+  va_start (args, message);
+  error_tail (status, errnum, message, args);
+
+#ifdef _LIBC
+  _IO_funlockfile (stderr);
+# ifdef __libc_ptf_call
+  __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
+# endif
+#endif
+}
+\f
+/* Sometimes we want to have at most one error per line.  This
+   variable controls whether this mode is selected or not.  */
+int error_one_per_line;
+
+void
+error_at_line (int status, int errnum, const char *file_name,
+               unsigned int line_number, const char *message, ...)
+{
+  va_list args;
+
+  if (error_one_per_line)
+    {
+      static const char *old_file_name;
+      static unsigned int old_line_number;
+
+      if (old_line_number == line_number
+          && (file_name == old_file_name
+              || strcmp (old_file_name, file_name) == 0))
+        /* Simply return and print nothing.  */
+        return;
+
+      old_file_name = file_name;
+      old_line_number = line_number;
+    }
+
+#if defined _LIBC && defined __libc_ptf_call
+  /* We do not want this call to be cut short by a thread
+     cancellation.  Therefore disable cancellation for now.  */
+  int state = PTHREAD_CANCEL_ENABLE;
+  __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
+                   0);
+#endif
+
+  flush_stdout ();
+#ifdef _LIBC
+  _IO_flockfile (stderr);
+#endif
+  if (error_print_progname)
+    (*error_print_progname) ();
+  else
+    {
+#if _LIBC
+      __fxprintf (NULL, "%s:", program_name);
+#else
+      fprintf (stderr, "%s:", program_name);
+#endif
+    }
+
+#if _LIBC
+  __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
+              file_name, line_number);
+#else
+  fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
+           file_name, line_number);
+#endif
+
+  va_start (args, message);
+  error_tail (status, errnum, message, args);
+
+#ifdef _LIBC
+  _IO_funlockfile (stderr);
+# ifdef __libc_ptf_call
+  __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
+# endif
+#endif
+}
+
+#ifdef _LIBC
+/* Make the weak alias.  */
+# undef error
+# undef error_at_line
+weak_alias (__error, error)
+weak_alias (__error_at_line, error_at_line)
+#endif
diff --git a/grub-core/gnulib/error.h b/grub-core/gnulib/error.h
new file mode 100644 (file)
index 0000000..9deef02
--- /dev/null
@@ -0,0 +1,65 @@
+/* Declaration for error-reporting function
+   Copyright (C) 1995, 1996, 1997, 2003, 2006, 2008, 2009, 2010 Free Software
+   Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _ERROR_H
+#define _ERROR_H 1
+
+#ifndef __attribute__
+/* The __attribute__ feature is available in gcc versions 2.5 and later.
+   The __-protected variants of the attributes 'format' and 'printf' are
+   accepted by gcc versions 2.6.4 (effectively 2.7) and later.
+   We enable __attribute__ only if these are supported too, because
+   gnulib and libintl do '#define printf __printf__' when they override
+   the 'printf' function.  */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
+#  define __attribute__(Spec)   /* empty */
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Print a message with `fprintf (stderr, FORMAT, ...)';
+   if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM).
+   If STATUS is nonzero, terminate the program with `exit (STATUS)'.  */
+
+extern void error (int __status, int __errnum, const char *__format, ...)
+     __attribute__ ((__format__ (__printf__, 3, 4)));
+
+extern void error_at_line (int __status, int __errnum, const char *__fname,
+                           unsigned int __lineno, const char *__format, ...)
+     __attribute__ ((__format__ (__printf__, 5, 6)));
+
+/* If NULL, error will flush stdout, then print on stderr the program
+   name, a colon and a space.  Otherwise, error will call this
+   function without parameters instead.  */
+extern void (*error_print_progname) (void);
+
+/* This variable is incremented each time `error' is called.  */
+extern unsigned int error_message_count;
+
+/* Sometimes we want to have at most one error per line.  This
+   variable controls whether this mode is selected or not.  */
+extern int error_one_per_line;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* error.h */
diff --git a/grub-core/gnulib/fnmatch.c b/grub-core/gnulib/fnmatch.c
new file mode 100644 (file)
index 0000000..f15dbb8
--- /dev/null
@@ -0,0 +1,354 @@
+/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+   2003, 2004, 2005, 2006, 2007, 2009, 2010 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _LIBC
+# include <config.h>
+#endif
+
+/* Enable GNU extensions in fnmatch.h.  */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE    1
+#endif
+
+#if ! defined __builtin_expect && __GNUC__ < 3
+# define __builtin_expect(expr, expected) (expr)
+#endif
+
+#include <fnmatch.h>
+
+#include <alloca.h>
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define WIDE_CHAR_SUPPORT \
+  (HAVE_WCTYPE_H && HAVE_BTOWC && HAVE_ISWCTYPE \
+   && HAVE_WMEMCHR && (HAVE_WMEMCPY || HAVE_WMEMPCPY))
+
+/* For platform which support the ISO C amendement 1 functionality we
+   support user defined character classes.  */
+#if defined _LIBC || WIDE_CHAR_SUPPORT
+# include <wctype.h>
+# include <wchar.h>
+#endif
+
+/* We need some of the locale data (the collation sequence information)
+   but there is no interface to get this information in general.  Therefore
+   we support a correct implementation only in glibc.  */
+#ifdef _LIBC
+# include "../locale/localeinfo.h"
+# include "../locale/elem-hash.h"
+# include "../locale/coll-lookup.h"
+# include <shlib-compat.h>
+
+# define CONCAT(a,b) __CONCAT(a,b)
+# define mbsrtowcs __mbsrtowcs
+# define fnmatch __fnmatch
+extern int fnmatch (const char *pattern, const char *string, int flags);
+#endif
+
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+
+/* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set.  */
+#define NO_LEADING_PERIOD(flags) \
+  ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD))
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself, and have not detected a bug
+   in the library.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#if defined _LIBC || !defined __GNU_LIBRARY__ || !HAVE_FNMATCH_GNU
+
+
+# if ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK))
+#  define isblank(c) ((c) == ' ' || (c) == '\t')
+# endif
+
+# define STREQ(s1, s2) (strcmp (s1, s2) == 0)
+
+# if defined _LIBC || WIDE_CHAR_SUPPORT
+/* The GNU C library provides support for user-defined character classes
+   and the functions from ISO C amendement 1.  */
+#  ifdef CHARCLASS_NAME_MAX
+#   define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
+#  else
+/* This shouldn't happen but some implementation might still have this
+   problem.  Use a reasonable default value.  */
+#   define CHAR_CLASS_MAX_LENGTH 256
+#  endif
+
+#  ifdef _LIBC
+#   define IS_CHAR_CLASS(string) __wctype (string)
+#  else
+#   define IS_CHAR_CLASS(string) wctype (string)
+#  endif
+
+#  ifdef _LIBC
+#   define ISWCTYPE(WC, WT)     __iswctype (WC, WT)
+#  else
+#   define ISWCTYPE(WC, WT)     iswctype (WC, WT)
+#  endif
+
+#  if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
+/* In this case we are implementing the multibyte character handling.  */
+#   define HANDLE_MULTIBYTE     1
+#  endif
+
+# else
+#  define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */
+
+#  define IS_CHAR_CLASS(string)                                               \
+   (STREQ (string, "alpha") || STREQ (string, "upper")                        \
+    || STREQ (string, "lower") || STREQ (string, "digit")                     \
+    || STREQ (string, "alnum") || STREQ (string, "xdigit")                    \
+    || STREQ (string, "space") || STREQ (string, "print")                     \
+    || STREQ (string, "punct") || STREQ (string, "graph")                     \
+    || STREQ (string, "cntrl") || STREQ (string, "blank"))
+# endif
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+/* Global variable.  */
+static int posixly_correct;
+
+# ifndef internal_function
+/* Inside GNU libc we mark some function in a special way.  In other
+   environments simply ignore the marking.  */
+#  define internal_function
+# endif
+
+/* Note that this evaluates C many times.  */
+# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
+# define CHAR   char
+# define UCHAR  unsigned char
+# define INT    int
+# define FCT    internal_fnmatch
+# define EXT    ext_match
+# define END    end_pattern
+# define L_(CS) CS
+# ifdef _LIBC
+#  define BTOWC(C)      __btowc (C)
+# else
+#  define BTOWC(C)      btowc (C)
+# endif
+# define STRLEN(S) strlen (S)
+# define STRCAT(D, S) strcat (D, S)
+# ifdef _LIBC
+#  define MEMPCPY(D, S, N) __mempcpy (D, S, N)
+# else
+#  if HAVE_MEMPCPY
+#   define MEMPCPY(D, S, N) mempcpy (D, S, N)
+#  else
+#   define MEMPCPY(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N)))
+#  endif
+# endif
+# define MEMCHR(S, C, N) memchr (S, C, N)
+# define STRCOLL(S1, S2) strcoll (S1, S2)
+# include "fnmatch_loop.c"
+
+
+# if HANDLE_MULTIBYTE
+#  define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c))
+#  define CHAR  wchar_t
+#  define UCHAR wint_t
+#  define INT   wint_t
+#  define FCT   internal_fnwmatch
+#  define EXT   ext_wmatch
+#  define END   end_wpattern
+#  define L_(CS)        L##CS
+#  define BTOWC(C)      (C)
+#  ifdef _LIBC
+#   define STRLEN(S) __wcslen (S)
+#   define STRCAT(D, S) __wcscat (D, S)
+#   define MEMPCPY(D, S, N) __wmempcpy (D, S, N)
+#  else
+#   define STRLEN(S) wcslen (S)
+#   define STRCAT(D, S) wcscat (D, S)
+#   if HAVE_WMEMPCPY
+#    define MEMPCPY(D, S, N) wmempcpy (D, S, N)
+#   else
+#    define MEMPCPY(D, S, N) (wmemcpy (D, S, N) + (N))
+#   endif
+#  endif
+#  define MEMCHR(S, C, N) wmemchr (S, C, N)
+#  define STRCOLL(S1, S2) wcscoll (S1, S2)
+#  define WIDE_CHAR_VERSION 1
+
+#  undef IS_CHAR_CLASS
+/* We have to convert the wide character string in a multibyte string.  But
+   we know that the character class names consist of alphanumeric characters
+   from the portable character set, and since the wide character encoding
+   for a member of the portable character set is the same code point as
+   its single-byte encoding, we can use a simplified method to convert the
+   string to a multibyte character string.  */
+static wctype_t
+is_char_class (const wchar_t *wcs)
+{
+  char s[CHAR_CLASS_MAX_LENGTH + 1];
+  char *cp = s;
+
+  do
+    {
+      /* Test for a printable character from the portable character set.  */
+#  ifdef _LIBC
+      if (*wcs < 0x20 || *wcs > 0x7e
+          || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
+        return (wctype_t) 0;
+#  else
+      switch (*wcs)
+        {
+        case L' ': case L'!': case L'"': case L'#': case L'%':
+        case L'&': case L'\'': case L'(': case L')': case L'*':
+        case L'+': case L',': case L'-': case L'.': case L'/':
+        case L'0': case L'1': case L'2': case L'3': case L'4':
+        case L'5': case L'6': case L'7': case L'8': case L'9':
+        case L':': case L';': case L'<': case L'=': case L'>':
+        case L'?':
+        case L'A': case L'B': case L'C': case L'D': case L'E':
+        case L'F': case L'G': case L'H': case L'I': case L'J':
+        case L'K': case L'L': case L'M': case L'N': case L'O':
+        case L'P': case L'Q': case L'R': case L'S': case L'T':
+        case L'U': case L'V': case L'W': case L'X': case L'Y':
+        case L'Z':
+        case L'[': case L'\\': case L']': case L'^': case L'_':
+        case L'a': case L'b': case L'c': case L'd': case L'e':
+        case L'f': case L'g': case L'h': case L'i': case L'j':
+        case L'k': case L'l': case L'm': case L'n': case L'o':
+        case L'p': case L'q': case L'r': case L's': case L't':
+        case L'u': case L'v': case L'w': case L'x': case L'y':
+        case L'z': case L'{': case L'|': case L'}': case L'~':
+          break;
+        default:
+          return (wctype_t) 0;
+        }
+#  endif
+
+      /* Avoid overrunning the buffer.  */
+      if (cp == s + CHAR_CLASS_MAX_LENGTH)
+        return (wctype_t) 0;
+
+      *cp++ = (char) *wcs++;
+    }
+  while (*wcs != L'\0');
+
+  *cp = '\0';
+
+#  ifdef _LIBC
+  return __wctype (s);
+#  else
+  return wctype (s);
+#  endif
+}
+#  define IS_CHAR_CLASS(string) is_char_class (string)
+
+#  include "fnmatch_loop.c"
+# endif
+
+
+int
+fnmatch (const char *pattern, const char *string, int flags)
+{
+# if HANDLE_MULTIBYTE
+#  define ALLOCA_LIMIT 2000
+  if (__builtin_expect (MB_CUR_MAX, 1) != 1)
+    {
+      mbstate_t ps;
+      size_t patsize;
+      size_t strsize;
+      size_t totsize;
+      wchar_t *wpattern;
+      wchar_t *wstring;
+      int res;
+
+      /* Calculate the size needed to convert the strings to
+         wide characters.  */
+      memset (&ps, '\0', sizeof (ps));
+      patsize = mbsrtowcs (NULL, &pattern, 0, &ps) + 1;
+      if (__builtin_expect (patsize != 0, 1))
+        {
+          assert (mbsinit (&ps));
+          strsize = mbsrtowcs (NULL, &string, 0, &ps) + 1;
+          if (__builtin_expect (strsize != 0, 1))
+            {
+              assert (mbsinit (&ps));
+              totsize = patsize + strsize;
+              if (__builtin_expect (! (patsize <= totsize
+                                       && totsize <= SIZE_MAX / sizeof (wchar_t)),
+                                    0))
+                {
+                  errno = ENOMEM;
+                  return -1;
+                }
+
+              /* Allocate room for the wide characters.  */
+              if (__builtin_expect (totsize < ALLOCA_LIMIT, 1))
+                wpattern = (wchar_t *) alloca (totsize * sizeof (wchar_t));
+              else
+                {
+                  wpattern = malloc (totsize * sizeof (wchar_t));
+                  if (__builtin_expect (! wpattern, 0))
+                    {
+                      errno = ENOMEM;
+                      return -1;
+                    }
+                }
+              wstring = wpattern + patsize;
+
+              /* Convert the strings into wide characters.  */
+              mbsrtowcs (wpattern, &pattern, patsize, &ps);
+              assert (mbsinit (&ps));
+              mbsrtowcs (wstring, &string, strsize, &ps);
+
+              res = internal_fnwmatch (wpattern, wstring, wstring + strsize - 1,
+                                       flags & FNM_PERIOD, flags);
+
+              if (__builtin_expect (! (totsize < ALLOCA_LIMIT), 0))
+                free (wpattern);
+              return res;
+            }
+        }
+    }
+
+# endif /* HANDLE_MULTIBYTE */
+
+  return internal_fnmatch (pattern, string, string + strlen (string),
+                           flags & FNM_PERIOD, flags);
+}
+
+# ifdef _LIBC
+#  undef fnmatch
+versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3);
+#  if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3)
+strong_alias (__fnmatch, __fnmatch_old)
+compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0);
+#  endif
+libc_hidden_ver (__fnmatch, fnmatch)
+# endif
+
+#endif  /* _LIBC or not __GNU_LIBRARY__.  */
diff --git a/grub-core/gnulib/fnmatch.h b/grub-core/gnulib/fnmatch.h
new file mode 100644 (file)
index 0000000..b086b45
--- /dev/null
@@ -0,0 +1,65 @@
+/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2001, 2002, 2003,
+   2005, 2007 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef        _FNMATCH_H
+#define        _FNMATCH_H      1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* We #undef these before defining them because some losing systems
+   (HP-UX A.08.07 for example) define these in <unistd.h>.  */
+#undef FNM_PATHNAME
+#undef FNM_NOESCAPE
+#undef FNM_PERIOD
+
+/* Bits set in the FLAGS argument to `fnmatch'.  */
+#define        FNM_PATHNAME    (1 << 0) /* No wildcard can ever match `/'.  */
+#define        FNM_NOESCAPE    (1 << 1) /* Backslashes don't quote special chars.  */
+#define        FNM_PERIOD      (1 << 2) /* Leading `.' is matched only explicitly.  */
+
+#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE
+# define FNM_FILE_NAME  FNM_PATHNAME   /* Preferred GNU name.  */
+# define FNM_LEADING_DIR (1 << 3)      /* Ignore `/...' after a match.  */
+# define FNM_CASEFOLD   (1 << 4)       /* Compare without regard to case.  */
+# define FNM_EXTMATCH   (1 << 5)       /* Use ksh-like extended matching. */
+#endif
+
+/* Value returned by `fnmatch' if STRING does not match PATTERN.  */
+#define        FNM_NOMATCH     1
+
+/* This value is returned if the implementation does not support
+   `fnmatch'.  Since this is not the case here it will never be
+   returned but the conformance test suites still require the symbol
+   to be defined.  */
+#ifdef _XOPEN_SOURCE
+# define FNM_NOSYS     (-1)
+#endif
+
+/* Match NAME against the file name pattern PATTERN,
+   returning zero if it matches, FNM_NOMATCH if not.  */
+extern int fnmatch (const char *__pattern, const char *__name,
+                   int __flags);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* fnmatch.h */
diff --git a/grub-core/gnulib/fnmatch_loop.c b/grub-core/gnulib/fnmatch_loop.c
new file mode 100644 (file)
index 0000000..8cd4444
--- /dev/null
@@ -0,0 +1,1215 @@
+/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+   2003, 2004, 2005, 2006, 2009, 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* Match STRING against the file name pattern PATTERN, returning zero if
+   it matches, nonzero if not.  */
+static int EXT (INT opt, const CHAR *pattern, const CHAR *string,
+                const CHAR *string_end, bool no_leading_period, int flags)
+     internal_function;
+static const CHAR *END (const CHAR *patternp) internal_function;
+
+static int
+internal_function
+FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end,
+     bool no_leading_period, int flags)
+{
+  register const CHAR *p = pattern, *n = string;
+  register UCHAR c;
+#ifdef _LIBC
+# if WIDE_CHAR_VERSION
+  const char *collseq = (const char *)
+    _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
+# else
+  const UCHAR *collseq = (const UCHAR *)
+    _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
+# endif
+#endif
+
+  while ((c = *p++) != L_('\0'))
+    {
+      bool new_no_leading_period = false;
+      c = FOLD (c);
+
+      switch (c)
+        {
+        case L_('?'):
+          if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
+            {
+              int res;
+
+              res = EXT (c, p, n, string_end, no_leading_period,
+                         flags);
+              if (res != -1)
+                return res;
+            }
+
+          if (n == string_end)
+            return FNM_NOMATCH;
+          else if (*n == L_('/') && (flags & FNM_FILE_NAME))
+            return FNM_NOMATCH;
+          else if (*n == L_('.') && no_leading_period)
+            return FNM_NOMATCH;
+          break;
+
+        case L_('\\'):
+          if (!(flags & FNM_NOESCAPE))
+            {
+              c = *p++;
+              if (c == L_('\0'))
+                /* Trailing \ loses.  */
+                return FNM_NOMATCH;
+              c = FOLD (c);
+            }
+          if (n == string_end || FOLD ((UCHAR) *n) != c)
+            return FNM_NOMATCH;
+          break;
+
+        case L_('*'):
+          if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
+            {
+              int res;
+
+              res = EXT (c, p, n, string_end, no_leading_period,
+                         flags);
+              if (res != -1)
+                return res;
+            }
+
+          if (n != string_end && *n == L_('.') && no_leading_period)
+            return FNM_NOMATCH;
+
+          for (c = *p++; c == L_('?') || c == L_('*'); c = *p++)
+            {
+              if (*p == L_('(') && (flags & FNM_EXTMATCH) != 0)
+                {
+                  const CHAR *endp = END (p);
+                  if (endp != p)
+                    {
+                      /* This is a pattern.  Skip over it.  */
+                      p = endp;
+                      continue;
+                    }
+                }
+
+              if (c == L_('?'))
+                {
+                  /* A ? needs to match one character.  */
+                  if (n == string_end)
+                    /* There isn't another character; no match.  */
+                    return FNM_NOMATCH;
+                  else if (*n == L_('/')
+                           && __builtin_expect (flags & FNM_FILE_NAME, 0))
+                    /* A slash does not match a wildcard under
+                       FNM_FILE_NAME.  */
+                    return FNM_NOMATCH;
+                  else
+                    /* One character of the string is consumed in matching
+                       this ? wildcard, so *??? won't match if there are
+                       less than three characters.  */
+                    ++n;
+                }
+            }
+
+          if (c == L_('\0'))
+            /* The wildcard(s) is/are the last element of the pattern.
+               If the name is a file name and contains another slash
+               this means it cannot match, unless the FNM_LEADING_DIR
+               flag is set.  */
+            {
+              int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH;
+
+              if (flags & FNM_FILE_NAME)
+                {
+                  if (flags & FNM_LEADING_DIR)
+                    result = 0;
+                  else
+                    {
+                      if (MEMCHR (n, L_('/'), string_end - n) == NULL)
+                        result = 0;
+                    }
+                }
+
+              return result;
+            }
+          else
+            {
+              const CHAR *endp;
+
+              endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\0'),
+                             string_end - n);
+              if (endp == NULL)
+                endp = string_end;
+
+              if (c == L_('[')
+                  || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0
+                      && (c == L_('@') || c == L_('+') || c == L_('!'))
+                      && *p == L_('(')))
+                {
+                  int flags2 = ((flags & FNM_FILE_NAME)
+                                ? flags : (flags & ~FNM_PERIOD));
+                  bool no_leading_period2 = no_leading_period;
+
+                  for (--p; n < endp; ++n, no_leading_period2 = false)
+                    if (FCT (p, n, string_end, no_leading_period2, flags2)
+                        == 0)
+                      return 0;
+                }
+              else if (c == L_('/') && (flags & FNM_FILE_NAME))
+                {
+                  while (n < string_end && *n != L_('/'))
+                    ++n;
+                  if (n < string_end && *n == L_('/')
+                      && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags)
+                          == 0))
+                    return 0;
+                }
+              else
+                {
+                  int flags2 = ((flags & FNM_FILE_NAME)
+                                ? flags : (flags & ~FNM_PERIOD));
+                  int no_leading_period2 = no_leading_period;
+
+                  if (c == L_('\\') && !(flags & FNM_NOESCAPE))
+                    c = *p;
+                  c = FOLD (c);
+                  for (--p; n < endp; ++n, no_leading_period2 = false)
+                    if (FOLD ((UCHAR) *n) == c
+                        && (FCT (p, n, string_end, no_leading_period2, flags2)
+                            == 0))
+                      return 0;
+                }
+            }
+
+          /* If we come here no match is possible with the wildcard.  */
+          return FNM_NOMATCH;
+
+        case L_('['):
+          {
+            /* Nonzero if the sense of the character class is inverted.  */
+            register bool not;
+            CHAR cold;
+            UCHAR fn;
+
+            if (posixly_correct == 0)
+              posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
+
+            if (n == string_end)
+              return FNM_NOMATCH;
+
+            if (*n == L_('.') && no_leading_period)
+              return FNM_NOMATCH;
+
+            if (*n == L_('/') && (flags & FNM_FILE_NAME))
+              /* `/' cannot be matched.  */
+              return FNM_NOMATCH;
+
+            not = (*p == L_('!') || (posixly_correct < 0 && *p == L_('^')));
+            if (not)
+              ++p;
+
+            fn = FOLD ((UCHAR) *n);
+
+            c = *p++;
+            for (;;)
+              {
+                if (!(flags & FNM_NOESCAPE) && c == L_('\\'))
+                  {
+                    if (*p == L_('\0'))
+                      return FNM_NOMATCH;
+                    c = FOLD ((UCHAR) *p);
+                    ++p;
+
+                    goto normal_bracket;
+                  }
+                else if (c == L_('[') && *p == L_(':'))
+                  {
+                    /* Leave room for the null.  */
+                    CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
+                    size_t c1 = 0;
+#if defined _LIBC || WIDE_CHAR_SUPPORT
+                    wctype_t wt;
+#endif
+                    const CHAR *startp = p;
+
+                    for (;;)
+                      {
+                        if (c1 == CHAR_CLASS_MAX_LENGTH)
+                          /* The name is too long and therefore the pattern
+                             is ill-formed.  */
+                          return FNM_NOMATCH;
+
+                        c = *++p;
+                        if (c == L_(':') && p[1] == L_(']'))
+                          {
+                            p += 2;
+                            break;
+                          }
+                        if (c < L_('a') || c >= L_('z'))
+                          {
+                            /* This cannot possibly be a character class name.
+                               Match it as a normal range.  */
+                            p = startp;
+                            c = L_('[');
+                            goto normal_bracket;
+                          }
+                        str[c1++] = c;
+                      }
+                    str[c1] = L_('\0');
+
+#if defined _LIBC || WIDE_CHAR_SUPPORT
+                    wt = IS_CHAR_CLASS (str);
+                    if (wt == 0)
+                      /* Invalid character class name.  */
+                      return FNM_NOMATCH;
+
+# if defined _LIBC && ! WIDE_CHAR_VERSION
+                    /* The following code is glibc specific but does
+                       there a good job in speeding up the code since
+                       we can avoid the btowc() call.  */
+                    if (_ISCTYPE ((UCHAR) *n, wt))
+                      goto matched;
+# else
+                    if (ISWCTYPE (BTOWC ((UCHAR) *n), wt))
+                      goto matched;
+# endif
+#else
+                    if ((STREQ (str, L_("alnum")) && isalnum ((UCHAR) *n))
+                        || (STREQ (str, L_("alpha")) && isalpha ((UCHAR) *n))
+                        || (STREQ (str, L_("blank")) && isblank ((UCHAR) *n))
+                        || (STREQ (str, L_("cntrl")) && iscntrl ((UCHAR) *n))
+                        || (STREQ (str, L_("digit")) && isdigit ((UCHAR) *n))
+                        || (STREQ (str, L_("graph")) && isgraph ((UCHAR) *n))
+                        || (STREQ (str, L_("lower")) && islower ((UCHAR) *n))
+                        || (STREQ (str, L_("print")) && isprint ((UCHAR) *n))
+                        || (STREQ (str, L_("punct")) && ispunct ((UCHAR) *n))
+                        || (STREQ (str, L_("space")) && isspace ((UCHAR) *n))
+                        || (STREQ (str, L_("upper")) && isupper ((UCHAR) *n))
+                        || (STREQ (str, L_("xdigit")) && isxdigit ((UCHAR) *n)))
+                      goto matched;
+#endif
+                    c = *p++;
+                  }
+#ifdef _LIBC
+                else if (c == L_('[') && *p == L_('='))
+                  {
+                    UCHAR str[1];
+                    uint32_t nrules =
+                      _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+                    const CHAR *startp = p;
+
+                    c = *++p;
+                    if (c == L_('\0'))
+                      {
+                        p = startp;
+                        c = L_('[');
+                        goto normal_bracket;
+                      }
+                    str[0] = c;
+
+                    c = *++p;
+                    if (c != L_('=') || p[1] != L_(']'))
+                      {
+                        p = startp;
+                        c = L_('[');
+                        goto normal_bracket;
+                      }
+                    p += 2;
+
+                    if (nrules == 0)
+                      {
+                        if ((UCHAR) *n == str[0])
+                          goto matched;
+                      }
+                    else
+                      {
+                        const int32_t *table;
+# if WIDE_CHAR_VERSION
+                        const int32_t *weights;
+                        const int32_t *extra;
+# else
+                        const unsigned char *weights;
+                        const unsigned char *extra;
+# endif
+                        const int32_t *indirect;
+                        int32_t idx;
+                        const UCHAR *cp = (const UCHAR *) str;
+
+                        /* This #include defines a local function!  */
+# if WIDE_CHAR_VERSION
+#  include <locale/weightwc.h>
+# else
+#  include <locale/weight.h>
+# endif
+
+# if WIDE_CHAR_VERSION
+                        table = (const int32_t *)
+                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
+                        weights = (const int32_t *)
+                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
+                        extra = (const int32_t *)
+                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
+                        indirect = (const int32_t *)
+                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
+# else
+                        table = (const int32_t *)
+                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+                        weights = (const unsigned char *)
+                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
+                        extra = (const unsigned char *)
+                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
+                        indirect = (const int32_t *)
+                          _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
+# endif
+
+                        idx = findidx (&cp);
+                        if (idx != 0)
+                          {
+                            /* We found a table entry.  Now see whether the
+                               character we are currently at has the same
+                               equivalance class value.  */
+                            int len = weights[idx & 0xffffff];
+                            int32_t idx2;
+                            const UCHAR *np = (const UCHAR *) n;
+
+                            idx2 = findidx (&np);
+                            if (idx2 != 0
+                                && (idx >> 24) == (idx2 >> 24)
+                                && len == weights[idx2 & 0xffffff])
+                              {
+                                int cnt = 0;
+
+                                idx &= 0xffffff;
+                                idx2 &= 0xffffff;
+
+                                while (cnt < len
+                                       && (weights[idx + 1 + cnt]
+                                           == weights[idx2 + 1 + cnt]))
+                                  ++cnt;
+
+                                if (cnt == len)
+                                  goto matched;
+                              }
+                          }
+                      }
+
+                    c = *p++;
+                  }
+#endif
+                else if (c == L_('\0'))
+                  /* [ (unterminated) loses.  */
+                  return FNM_NOMATCH;
+                else
+                  {
+                    bool is_range = false;
+
+#ifdef _LIBC
+                    bool is_seqval = false;
+
+                    if (c == L_('[') && *p == L_('.'))
+                      {
+                        uint32_t nrules =
+                          _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+                        const CHAR *startp = p;
+                        size_t c1 = 0;
+
+                        while (1)
+                          {
+                            c = *++p;
+                            if (c == L_('.') && p[1] == L_(']'))
+                              {
+                                p += 2;
+                                break;
+                              }
+                            if (c == '\0')
+                              return FNM_NOMATCH;
+                            ++c1;
+                          }
+
+                        /* We have to handling the symbols differently in
+                           ranges since then the collation sequence is
+                           important.  */
+                        is_range = *p == L_('-') && p[1] != L_('\0');
+
+                        if (nrules == 0)
+                          {
+                            /* There are no names defined in the collation
+                               data.  Therefore we only accept the trivial
+                               names consisting of the character itself.  */
+                            if (c1 != 1)
+                              return FNM_NOMATCH;
+
+                            if (!is_range && *n == startp[1])
+                              goto matched;
+
+                            cold = startp[1];
+                            c = *p++;
+                          }
+                        else
+                          {
+                            int32_t table_size;
+                            const int32_t *symb_table;
+# ifdef WIDE_CHAR_VERSION
+                            char str[c1];
+                            size_t strcnt;
+# else
+#  define str (startp + 1)
+# endif
+                            const unsigned char *extra;
+                            int32_t idx;
+                            int32_t elem;
+                            int32_t second;
+                            int32_t hash;
+
+# ifdef WIDE_CHAR_VERSION
+                            /* We have to convert the name to a single-byte
+                               string.  This is possible since the names
+                               consist of ASCII characters and the internal
+                               representation is UCS4.  */
+                            for (strcnt = 0; strcnt < c1; ++strcnt)
+                              str[strcnt] = startp[1 + strcnt];
+# endif
+
+                            table_size =
+                              _NL_CURRENT_WORD (LC_COLLATE,
+                                                _NL_COLLATE_SYMB_HASH_SIZEMB);
+                            symb_table = (const int32_t *)
+                              _NL_CURRENT (LC_COLLATE,
+                                           _NL_COLLATE_SYMB_TABLEMB);
+                            extra = (const unsigned char *)
+                              _NL_CURRENT (LC_COLLATE,
+                                           _NL_COLLATE_SYMB_EXTRAMB);
+
+                            /* Locate the character in the hashing table.  */
+                            hash = elem_hash (str, c1);
+
+                            idx = 0;
+                            elem = hash % table_size;
+                            if (symb_table[2 * elem] != 0)
+                              {
+                                second = hash % (table_size - 2) + 1;
+
+                                do
+                                  {
+                                    /* First compare the hashing value.  */
+                                    if (symb_table[2 * elem] == hash
+                                        && (c1
+                                            == extra[symb_table[2 * elem + 1]])
+                                        && memcmp (str,
+                                                   &extra[symb_table[2 * elem
+                                                                     + 1]
+                                                          + 1], c1) == 0)
+                                      {
+                                        /* Yep, this is the entry.  */
+                                        idx = symb_table[2 * elem + 1];
+                                        idx += 1 + extra[idx];
+                                        break;
+                                      }
+
+                                    /* Next entry.  */
+                                    elem += second;
+                                  }
+                                while (symb_table[2 * elem] != 0);
+                              }
+
+                            if (symb_table[2 * elem] != 0)
+                              {
+                                /* Compare the byte sequence but only if
+                                   this is not part of a range.  */
+# ifdef WIDE_CHAR_VERSION
+                                int32_t *wextra;
+
+                                idx += 1 + extra[idx];
+                                /* Adjust for the alignment.  */
+                                idx = (idx + 3) & ~3;
+
+                                wextra = (int32_t *) &extra[idx + 4];
+# endif
+
+                                if (! is_range)
+                                  {
+# ifdef WIDE_CHAR_VERSION
+                                    for (c1 = 0;
+                                         (int32_t) c1 < wextra[idx];
+                                         ++c1)
+                                      if (n[c1] != wextra[1 + c1])
+                                        break;
+
+                                    if ((int32_t) c1 == wextra[idx])
+                                      goto matched;
+# else
+                                    for (c1 = 0; c1 < extra[idx]; ++c1)
+                                      if (n[c1] != extra[1 + c1])
+                                        break;
+
+                                    if (c1 == extra[idx])
+                                      goto matched;
+# endif
+                                  }
+
+                                /* Get the collation sequence value.  */
+                                is_seqval = true;
+# ifdef WIDE_CHAR_VERSION
+                                cold = wextra[1 + wextra[idx]];
+# else
+                                /* Adjust for the alignment.  */
+                                idx += 1 + extra[idx];
+                                idx = (idx + 3) & ~4;
+                                cold = *((int32_t *) &extra[idx]);
+# endif
+
+                                c = *p++;
+                              }
+                            else if (c1 == 1)
+                              {
+                                /* No valid character.  Match it as a
+                                   single byte.  */
+                                if (!is_range && *n == str[0])
+                                  goto matched;
+
+                                cold = str[0];
+                                c = *p++;
+                              }
+                            else
+                              return FNM_NOMATCH;
+                          }
+                      }
+                    else
+# undef str
+#endif
+                      {
+                        c = FOLD (c);
+                      normal_bracket:
+
+                        /* We have to handling the symbols differently in
+                           ranges since then the collation sequence is
+                           important.  */
+                        is_range = (*p == L_('-') && p[1] != L_('\0')
+                                    && p[1] != L_(']'));
+
+                        if (!is_range && c == fn)
+                          goto matched;
+
+#if _LIBC
+                        /* This is needed if we goto normal_bracket; from
+                           outside of is_seqval's scope.  */
+                        is_seqval = false;
+#endif
+
+                        cold = c;
+                        c = *p++;
+                      }
+
+                    if (c == L_('-') && *p != L_(']'))
+                      {
+#if _LIBC
+                        /* We have to find the collation sequence
+                           value for C.  Collation sequence is nothing
+                           we can regularly access.  The sequence
+                           value is defined by the order in which the
+                           definitions of the collation values for the
+                           various characters appear in the source
+                           file.  A strange concept, nowhere
+                           documented.  */
+                        uint32_t fcollseq;
+                        uint32_t lcollseq;
+                        UCHAR cend = *p++;
+
+# ifdef WIDE_CHAR_VERSION
+                        /* Search in the `names' array for the characters.  */
+                        fcollseq = __collseq_table_lookup (collseq, fn);
+                        if (fcollseq == ~((uint32_t) 0))
+                          /* XXX We don't know anything about the character
+                             we are supposed to match.  This means we are
+                             failing.  */
+                          goto range_not_matched;
+
+                        if (is_seqval)
+                          lcollseq = cold;
+                        else
+                          lcollseq = __collseq_table_lookup (collseq, cold);
+# else
+                        fcollseq = collseq[fn];
+                        lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
+# endif
+
+                        is_seqval = false;
+                        if (cend == L_('[') && *p == L_('.'))
+                          {
+                            uint32_t nrules =
+                              _NL_CURRENT_WORD (LC_COLLATE,
+                                                _NL_COLLATE_NRULES);
+                            const CHAR *startp = p;
+                            size_t c1 = 0;
+
+                            while (1)
+                              {
+                                c = *++p;
+                                if (c == L_('.') && p[1] == L_(']'))
+                                  {
+                                    p += 2;
+                                    break;
+                                  }
+                                if (c == '\0')
+                                  return FNM_NOMATCH;
+                                ++c1;
+                              }
+
+                            if (nrules == 0)
+                              {
+                                /* There are no names defined in the
+                                   collation data.  Therefore we only
+                                   accept the trivial names consisting
+                                   of the character itself.  */
+                                if (c1 != 1)
+                                  return FNM_NOMATCH;
+
+                                cend = startp[1];
+                              }
+                            else
+                              {
+                                int32_t table_size;
+                                const int32_t *symb_table;
+# ifdef WIDE_CHAR_VERSION
+                                char str[c1];
+                                size_t strcnt;
+# else
+#  define str (startp + 1)
+# endif
+                                const unsigned char *extra;
+                                int32_t idx;
+                                int32_t elem;
+                                int32_t second;
+                                int32_t hash;
+
+# ifdef WIDE_CHAR_VERSION
+                                /* We have to convert the name to a single-byte
+                                   string.  This is possible since the names
+                                   consist of ASCII characters and the internal
+                                   representation is UCS4.  */
+                                for (strcnt = 0; strcnt < c1; ++strcnt)
+                                  str[strcnt] = startp[1 + strcnt];
+# endif
+
+                                table_size =
+                                  _NL_CURRENT_WORD (LC_COLLATE,
+                                                    _NL_COLLATE_SYMB_HASH_SIZEMB);
+                                symb_table = (const int32_t *)
+                                  _NL_CURRENT (LC_COLLATE,
+                                               _NL_COLLATE_SYMB_TABLEMB);
+                                extra = (const unsigned char *)
+                                  _NL_CURRENT (LC_COLLATE,
+                                               _NL_COLLATE_SYMB_EXTRAMB);
+
+                                /* Locate the character in the hashing
+                                   table.  */
+                                hash = elem_hash (str, c1);
+
+                                idx = 0;
+                                elem = hash % table_size;
+                                if (symb_table[2 * elem] != 0)
+                                  {
+                                    second = hash % (table_size - 2) + 1;
+
+                                    do
+                                      {
+                                        /* First compare the hashing value.  */
+                                        if (symb_table[2 * elem] == hash
+                                            && (c1
+                                                == extra[symb_table[2 * elem + 1]])
+                                            && memcmp (str,
+                                                       &extra[symb_table[2 * elem + 1]
+                                                              + 1], c1) == 0)
+                                          {
+                                            /* Yep, this is the entry.  */
+                                            idx = symb_table[2 * elem + 1];
+                                            idx += 1 + extra[idx];
+                                            break;
+                                          }
+
+                                        /* Next entry.  */
+                                        elem += second;
+                                      }
+                                    while (symb_table[2 * elem] != 0);
+                                  }
+
+                                if (symb_table[2 * elem] != 0)
+                                  {
+                                    /* Compare the byte sequence but only if
+                                       this is not part of a range.  */
+# ifdef WIDE_CHAR_VERSION
+                                    int32_t *wextra;
+
+                                    idx += 1 + extra[idx];
+                                    /* Adjust for the alignment.  */
+                                    idx = (idx + 3) & ~4;
+
+                                    wextra = (int32_t *) &extra[idx + 4];
+# endif
+                                    /* Get the collation sequence value.  */
+                                    is_seqval = true;
+# ifdef WIDE_CHAR_VERSION
+                                    cend = wextra[1 + wextra[idx]];
+# else
+                                    /* Adjust for the alignment.  */
+                                    idx += 1 + extra[idx];
+                                    idx = (idx + 3) & ~4;
+                                    cend = *((int32_t *) &extra[idx]);
+# endif
+                                  }
+                                else if (symb_table[2 * elem] != 0 && c1 == 1)
+                                  {
+                                    cend = str[0];
+                                    c = *p++;
+                                  }
+                                else
+                                  return FNM_NOMATCH;
+                              }
+# undef str
+                          }
+                        else
+                          {
+                            if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
+                              cend = *p++;
+                            if (cend == L_('\0'))
+                              return FNM_NOMATCH;
+                            cend = FOLD (cend);
+                          }
+
+                        /* XXX It is not entirely clear to me how to handle
+                           characters which are not mentioned in the
+                           collation specification.  */
+                        if (
+# ifdef WIDE_CHAR_VERSION
+                            lcollseq == 0xffffffff ||
+# endif
+                            lcollseq <= fcollseq)
+                          {
+                            /* We have to look at the upper bound.  */
+                            uint32_t hcollseq;
+
+                            if (is_seqval)
+                              hcollseq = cend;
+                            else
+                              {
+# ifdef WIDE_CHAR_VERSION
+                                hcollseq =
+                                  __collseq_table_lookup (collseq, cend);
+                                if (hcollseq == ~((uint32_t) 0))
+                                  {
+                                    /* Hum, no information about the upper
+                                       bound.  The matching succeeds if the
+                                       lower bound is matched exactly.  */
+                                    if (lcollseq != fcollseq)
+                                      goto range_not_matched;
+
+                                    goto matched;
+                                  }
+# else
+                                hcollseq = collseq[cend];
+# endif
+                              }
+
+                            if (lcollseq <= hcollseq && fcollseq <= hcollseq)
+                              goto matched;
+                          }
+# ifdef WIDE_CHAR_VERSION
+                      range_not_matched:
+# endif
+#else
+                        /* We use a boring value comparison of the character
+                           values.  This is better than comparing using
+                           `strcoll' since the latter would have surprising
+                           and sometimes fatal consequences.  */
+                        UCHAR cend = *p++;
+
+                        if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
+                          cend = *p++;
+                        if (cend == L_('\0'))
+                          return FNM_NOMATCH;
+
+                        /* It is a range.  */
+                        if (cold <= fn && fn <= cend)
+                          goto matched;
+#endif
+
+                        c = *p++;
+                      }
+                  }
+
+                if (c == L_(']'))
+                  break;
+              }
+
+            if (!not)
+              return FNM_NOMATCH;
+            break;
+
+          matched:
+            /* Skip the rest of the [...] that already matched.  */
+            do
+              {
+              ignore_next:
+                c = *p++;
+
+                if (c == L_('\0'))
+                  /* [... (unterminated) loses.  */
+                  return FNM_NOMATCH;
+
+                if (!(flags & FNM_NOESCAPE) && c == L_('\\'))
+                  {
+                    if (*p == L_('\0'))
+                      return FNM_NOMATCH;
+                    /* XXX 1003.2d11 is unclear if this is right.  */
+                    ++p;
+                  }
+                else if (c == L_('[') && *p == L_(':'))
+                  {
+                    int c1 = 0;
+                    const CHAR *startp = p;
+
+                    while (1)
+                      {
+                        c = *++p;
+                        if (++c1 == CHAR_CLASS_MAX_LENGTH)
+                          return FNM_NOMATCH;
+
+                        if (*p == L_(':') && p[1] == L_(']'))
+                          break;
+
+                        if (c < L_('a') || c >= L_('z'))
+                          {
+                            p = startp;
+                            goto ignore_next;
+                          }
+                      }
+                    p += 2;
+                    c = *p++;
+                  }
+                else if (c == L_('[') && *p == L_('='))
+                  {
+                    c = *++p;
+                    if (c == L_('\0'))
+                      return FNM_NOMATCH;
+                    c = *++p;
+                    if (c != L_('=') || p[1] != L_(']'))
+                      return FNM_NOMATCH;
+                    p += 2;
+                    c = *p++;
+                  }
+                else if (c == L_('[') && *p == L_('.'))
+                  {
+                    ++p;
+                    while (1)
+                      {
+                        c = *++p;
+                        if (c == '\0')
+                          return FNM_NOMATCH;
+
+                        if (*p == L_('.') && p[1] == L_(']'))
+                          break;
+                      }
+                    p += 2;
+                    c = *p++;
+                  }
+              }
+            while (c != L_(']'));
+            if (not)
+              return FNM_NOMATCH;
+          }
+          break;
+
+        case L_('+'):
+        case L_('@'):
+        case L_('!'):
+          if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
+            {
+              int res;
+
+              res = EXT (c, p, n, string_end, no_leading_period, flags);
+              if (res != -1)
+                return res;
+            }
+          goto normal_match;
+
+        case L_('/'):
+          if (NO_LEADING_PERIOD (flags))
+            {
+              if (n == string_end || c != (UCHAR) *n)
+                return FNM_NOMATCH;
+
+              new_no_leading_period = true;
+              break;
+            }
+          /* FALLTHROUGH */
+        default:
+        normal_match:
+          if (n == string_end || c != FOLD ((UCHAR) *n))
+            return FNM_NOMATCH;
+        }
+
+      no_leading_period = new_no_leading_period;
+      ++n;
+    }
+
+  if (n == string_end)
+    return 0;
+
+  if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L_('/'))
+    /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
+    return 0;
+
+  return FNM_NOMATCH;
+}
+
+
+static const CHAR *
+internal_function
+END (const CHAR *pattern)
+{
+  const CHAR *p = pattern;
+
+  while (1)
+    if (*++p == L_('\0'))
+      /* This is an invalid pattern.  */
+      return pattern;
+    else if (*p == L_('['))
+      {
+        /* Handle brackets special.  */
+        if (posixly_correct == 0)
+          posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
+
+        /* Skip the not sign.  We have to recognize it because of a possibly
+           following ']'.  */
+        if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
+          ++p;
+        /* A leading ']' is recognized as such.  */
+        if (*p == L_(']'))
+          ++p;
+        /* Skip over all characters of the list.  */
+        while (*p != L_(']'))
+          if (*p++ == L_('\0'))
+            /* This is no valid pattern.  */
+            return pattern;
+      }
+    else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
+              || *p == L_('!')) && p[1] == L_('('))
+      p = END (p + 1);
+    else if (*p == L_(')'))
+      break;
+
+  return p + 1;
+}
+
+
+static int
+internal_function
+EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
+     bool no_leading_period, int flags)
+{
+  const CHAR *startp;
+  size_t level;
+  struct patternlist
+  {
+    struct patternlist *next;
+    CHAR str[1];
+  } *list = NULL;
+  struct patternlist **lastp = &list;
+  size_t pattern_len = STRLEN (pattern);
+  const CHAR *p;
+  const CHAR *rs;
+  enum { ALLOCA_LIMIT = 8000 };
+
+  /* Parse the pattern.  Store the individual parts in the list.  */
+  level = 0;
+  for (startp = p = pattern + 1; ; ++p)
+    if (*p == L_('\0'))
+      /* This is an invalid pattern.  */
+      return -1;
+    else if (*p == L_('['))
+      {
+        /* Handle brackets special.  */
+        if (posixly_correct == 0)
+          posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
+
+        /* Skip the not sign.  We have to recognize it because of a possibly
+           following ']'.  */
+        if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
+          ++p;
+        /* A leading ']' is recognized as such.  */
+        if (*p == L_(']'))
+          ++p;
+        /* Skip over all characters of the list.  */
+        while (*p != L_(']'))
+          if (*p++ == L_('\0'))
+            /* This is no valid pattern.  */
+            return -1;
+      }
+    else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
+              || *p == L_('!')) && p[1] == L_('('))
+      /* Remember the nesting level.  */
+      ++level;
+    else if (*p == L_(')'))
+      {
+        if (level-- == 0)
+          {
+            /* This means we found the end of the pattern.  */
+#define NEW_PATTERN \
+            struct patternlist *newp;                                         \
+            size_t plen;                                                      \
+            size_t plensize;                                                  \
+            size_t newpsize;                                                  \
+                                                                              \
+            plen = (opt == L_('?') || opt == L_('@')                          \
+                    ? pattern_len                                             \
+                    : p - startp + 1UL);                                      \
+            plensize = plen * sizeof (CHAR);                                  \
+            newpsize = offsetof (struct patternlist, str) + plensize;         \
+            if ((size_t) -1 / sizeof (CHAR) < plen                            \
+                || newpsize < offsetof (struct patternlist, str)              \
+                || ALLOCA_LIMIT <= newpsize)                                  \
+              return -1;                                                      \
+            newp = (struct patternlist *) alloca (newpsize);                  \
+            *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0');    \
+            newp->next = NULL;                                                \
+            *lastp = newp;                                                    \
+            lastp = &newp->next
+            NEW_PATTERN;
+            break;
+          }
+      }
+    else if (*p == L_('|'))
+      {
+        if (level == 0)
+          {
+            NEW_PATTERN;
+            startp = p + 1;
+          }
+      }
+  assert (list != NULL);
+  assert (p[-1] == L_(')'));
+#undef NEW_PATTERN
+
+  switch (opt)
+    {
+    case L_('*'):
+      if (FCT (p, string, string_end, no_leading_period, flags) == 0)
+        return 0;
+      /* FALLTHROUGH */
+
+    case L_('+'):
+      do
+        {
+          for (rs = string; rs <= string_end; ++rs)
+            /* First match the prefix with the current pattern with the
+               current pattern.  */
+            if (FCT (list->str, string, rs, no_leading_period,
+                     flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0
+                /* This was successful.  Now match the rest with the rest
+                   of the pattern.  */
+                && (FCT (p, rs, string_end,
+                         rs == string
+                         ? no_leading_period
+                         : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
+                         flags & FNM_FILE_NAME
+                         ? flags : flags & ~FNM_PERIOD) == 0
+                    /* This didn't work.  Try the whole pattern.  */
+                    || (rs != string
+                        && FCT (pattern - 1, rs, string_end,
+                                rs == string
+                                ? no_leading_period
+                                : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
+                                flags & FNM_FILE_NAME
+                                ? flags : flags & ~FNM_PERIOD) == 0)))
+              /* It worked.  Signal success.  */
+              return 0;
+        }
+      while ((list = list->next) != NULL);
+
+      /* None of the patterns lead to a match.  */
+      return FNM_NOMATCH;
+
+    case L_('?'):
+      if (FCT (p, string, string_end, no_leading_period, flags) == 0)
+        return 0;
+      /* FALLTHROUGH */
+
+    case L_('@'):
+      do
+        /* I cannot believe it but `strcat' is actually acceptable
+           here.  Match the entire string with the prefix from the
+           pattern list and the rest of the pattern following the
+           pattern list.  */
+        if (FCT (STRCAT (list->str, p), string, string_end,
+                 no_leading_period,
+                 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
+          /* It worked.  Signal success.  */
+          return 0;
+      while ((list = list->next) != NULL);
+
+      /* None of the patterns lead to a match.  */
+      return FNM_NOMATCH;
+
+    case L_('!'):
+      for (rs = string; rs <= string_end; ++rs)
+        {
+          struct patternlist *runp;
+
+          for (runp = list; runp != NULL; runp = runp->next)
+            if (FCT (runp->str, string, rs,  no_leading_period,
+                     flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
+              break;
+
+          /* If none of the patterns matched see whether the rest does.  */
+          if (runp == NULL
+              && (FCT (p, rs, string_end,
+                       rs == string
+                       ? no_leading_period
+                       : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
+                       flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD)
+                  == 0))
+            /* This is successful.  */
+            return 0;
+        }
+
+      /* None of the patterns together with the rest of the pattern
+         lead to a match.  */
+      return FNM_NOMATCH;
+
+    default:
+      assert (! "Invalid extended matching operator");
+      break;
+    }
+
+  return -1;
+}
+
+
+#undef FOLD
+#undef CHAR
+#undef UCHAR
+#undef INT
+#undef FCT
+#undef EXT
+#undef END
+#undef MEMPCPY
+#undef MEMCHR
+#undef STRCOLL
+#undef STRLEN
+#undef STRCAT
+#undef L_
+#undef BTOWC
diff --git a/grub-core/gnulib/getdelim.c b/grub-core/gnulib/getdelim.c
new file mode 100644 (file)
index 0000000..c024090
--- /dev/null
@@ -0,0 +1,137 @@
+/* getdelim.c --- Implementation of replacement getdelim function.
+   Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006, 2007, 2008,
+   2009, 2010 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* Ported from glibc by Simon Josefsson. */
+
+#include <config.h>
+
+/* Don't use __attribute__ __nonnull__ in this compilation unit.  Otherwise gcc
+   optimizes away the lineptr == NULL || n == NULL || fp == NULL tests below.  */
+#define _GL_ARG_NONNULL(params)
+
+#include <stdio.h>
+
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#ifndef SSIZE_MAX
+# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
+#endif
+
+#if USE_UNLOCKED_IO
+# include "unlocked-io.h"
+# define getc_maybe_unlocked(fp)        getc(fp)
+#elif !HAVE_FLOCKFILE || !HAVE_FUNLOCKFILE || !HAVE_DECL_GETC_UNLOCKED
+# undef flockfile
+# undef funlockfile
+# define flockfile(x) ((void) 0)
+# define funlockfile(x) ((void) 0)
+# define getc_maybe_unlocked(fp)        getc(fp)
+#else
+# define getc_maybe_unlocked(fp)        getc_unlocked(fp)
+#endif
+
+/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and
+   NUL-terminate it).  *LINEPTR is a pointer returned from malloc (or
+   NULL), pointing to *N characters of space.  It is realloc'ed as
+   necessary.  Returns the number of characters read (not including
+   the null terminator), or -1 on error or EOF.  */
+
+ssize_t
+getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
+{
+  ssize_t result;
+  size_t cur_len = 0;
+
+  if (lineptr == NULL || n == NULL || fp == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  flockfile (fp);
+
+  if (*lineptr == NULL || *n == 0)
+    {
+      char *new_lineptr;
+      *n = 120;
+      new_lineptr = (char *) realloc (*lineptr, *n);
+      if (new_lineptr == NULL)
+        {
+          result = -1;
+          goto unlock_return;
+        }
+      *lineptr = new_lineptr;
+    }
+
+  for (;;)
+    {
+      int i;
+
+      i = getc_maybe_unlocked (fp);
+      if (i == EOF)
+        {
+          result = -1;
+          break;
+        }
+
+      /* Make enough space for len+1 (for final NUL) bytes.  */
+      if (cur_len + 1 >= *n)
+        {
+          size_t needed_max =
+            SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
+          size_t needed = 2 * *n + 1;   /* Be generous. */
+          char *new_lineptr;
+
+          if (needed_max < needed)
+            needed = needed_max;
+          if (cur_len + 1 >= needed)
+            {
+              result = -1;
+              errno = EOVERFLOW;
+              goto unlock_return;
+            }
+
+          new_lineptr = (char *) realloc (*lineptr, needed);
+          if (new_lineptr == NULL)
+            {
+              result = -1;
+              goto unlock_return;
+            }
+
+          *lineptr = new_lineptr;
+          *n = needed;
+        }
+
+      (*lineptr)[cur_len] = i;
+      cur_len++;
+
+      if (i == delimiter)
+        break;
+    }
+  (*lineptr)[cur_len] = '\0';
+  result = cur_len ? cur_len : result;
+
+ unlock_return:
+  funlockfile (fp); /* doesn't set errno */
+
+  return result;
+}
diff --git a/grub-core/gnulib/getline.c b/grub-core/gnulib/getline.c
new file mode 100644 (file)
index 0000000..6cf187b
--- /dev/null
@@ -0,0 +1,30 @@
+/* getline.c --- Implementation of replacement getline function.
+   Copyright (C) 2005, 2006, 2007, 2009, 2010 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* Written by Simon Josefsson. */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+
+ssize_t
+getline (char **lineptr, size_t *n, FILE *stream)
+{
+  return getdelim (lineptr, n, '\n', stream);
+}
diff --git a/grub-core/gnulib/getopt.c b/grub-core/gnulib/getopt.c
new file mode 100644 (file)
index 0000000..aaabc8d
--- /dev/null
@@ -0,0 +1,1185 @@
+/* Getopt for GNU.
+   NOTE: getopt is part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to drepper@gnu.org
+   before changing it!
+   Copyright (C) 1987-1996, 1998-2004, 2006, 2008-2010 Free Software
+   Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+\f
+#ifndef _LIBC
+# include <config.h>
+#endif
+
+#include "getopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "gettext.h"
+# define _(msgid) gettext (msgid)
+#endif
+
+#if defined _LIBC && defined USE_IN_LIBIO
+# include <wchar.h>
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt_long' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Using `getopt' or setting the environment variable POSIXLY_CORRECT
+   disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include "getopt_int.h"
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* 1003.2 says this must be 1 before any call.  */
+int optind = 1;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
+/* Keep a global copy of all internal members of getopt_data.  */
+
+static struct _getopt_data getopt_data;
+
+\f
+#if defined HAVE_DECL_GETENV && !HAVE_DECL_GETENV
+extern char *getenv ();
+#endif
+\f
+#ifdef _LIBC
+/* Stored original parameters.
+   XXX This is no good solution.  We should rather copy the args so
+   that we can compare them later.  But we must not use malloc(3).  */
+extern int __libc_argc;
+extern char **__libc_argv;
+
+/* Bash 2.0 gives us an environment variable containing flags
+   indicating ARGV elements that should not be considered arguments.  */
+
+# ifdef USE_NONOPTION_FLAGS
+/* Defined in getopt_init.c  */
+extern char *__getopt_nonoption_flags;
+# endif
+
+# ifdef USE_NONOPTION_FLAGS
+#  define SWAP_FLAGS(ch1, ch2) \
+  if (d->__nonoption_flags_len > 0)                                           \
+    {                                                                         \
+      char __tmp = __getopt_nonoption_flags[ch1];                             \
+      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];          \
+      __getopt_nonoption_flags[ch2] = __tmp;                                  \
+    }
+# else
+#  define SWAP_FLAGS(ch1, ch2)
+# endif
+#else   /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif  /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+
+static void
+exchange (char **argv, struct _getopt_data *d)
+{
+  int bottom = d->__first_nonopt;
+  int middle = d->__last_nonopt;
+  int top = d->optind;
+  char *tem;
+
+  /* Exchange the shorter segment with the far end of the longer segment.
+     That puts the shorter segment into the right place.
+     It leaves the longer segment in the right place overall,
+     but it consists of two parts that need to be swapped next.  */
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+  /* First make sure the handling of the `__getopt_nonoption_flags'
+     string can work normally.  Our top argument must be in the range
+     of the string.  */
+  if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len)
+    {
+      /* We must extend the array.  The user plays games with us and
+         presents new arguments.  */
+      char *new_str = malloc (top + 1);
+      if (new_str == NULL)
+        d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0;
+      else
+        {
+          memset (__mempcpy (new_str, __getopt_nonoption_flags,
+                             d->__nonoption_flags_max_len),
+                  '\0', top + 1 - d->__nonoption_flags_max_len);
+          d->__nonoption_flags_max_len = top + 1;
+          __getopt_nonoption_flags = new_str;
+        }
+    }
+#endif
+
+  while (top > middle && middle > bottom)
+    {
+      if (top - middle > middle - bottom)
+        {
+          /* Bottom segment is the short one.  */
+          int len = middle - bottom;
+          register int i;
+
+          /* Swap it with the top part of the top segment.  */
+          for (i = 0; i < len; i++)
+            {
+              tem = argv[bottom + i];
+              argv[bottom + i] = argv[top - (middle - bottom) + i];
+              argv[top - (middle - bottom) + i] = tem;
+              SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+            }
+          /* Exclude the moved bottom segment from further swapping.  */
+          top -= len;
+        }
+      else
+        {
+          /* Top segment is the short one.  */
+          int len = top - middle;
+          register int i;
+
+          /* Swap it with the bottom part of the bottom segment.  */
+          for (i = 0; i < len; i++)
+            {
+              tem = argv[bottom + i];
+              argv[bottom + i] = argv[middle + i];
+              argv[middle + i] = tem;
+              SWAP_FLAGS (bottom + i, middle + i);
+            }
+          /* Exclude the moved top segment from further swapping.  */
+          bottom += len;
+        }
+    }
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  d->__first_nonopt += (d->optind - d->__last_nonopt);
+  d->__last_nonopt = d->optind;
+}
+
+/* Initialize the internal data when the first call is made.  */
+
+static const char *
+_getopt_initialize (int argc _GL_UNUSED,
+                    char **argv _GL_UNUSED, const char *optstring,
+                    struct _getopt_data *d, int posixly_correct)
+{
+  /* Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  d->__first_nonopt = d->__last_nonopt = d->optind;
+
+  d->__nextchar = NULL;
+
+  d->__posixly_correct = posixly_correct || !!getenv ("POSIXLY_CORRECT");
+
+  /* Determine how to handle the ordering of options and nonoptions.  */
+
+  if (optstring[0] == '-')
+    {
+      d->__ordering = RETURN_IN_ORDER;
+      ++optstring;
+    }
+  else if (optstring[0] == '+')
+    {
+      d->__ordering = REQUIRE_ORDER;
+      ++optstring;
+    }
+  else if (d->__posixly_correct)
+    d->__ordering = REQUIRE_ORDER;
+  else
+    d->__ordering = PERMUTE;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+  if (!d->__posixly_correct
+      && argc == __libc_argc && argv == __libc_argv)
+    {
+      if (d->__nonoption_flags_max_len == 0)
+        {
+          if (__getopt_nonoption_flags == NULL
+              || __getopt_nonoption_flags[0] == '\0')
+            d->__nonoption_flags_max_len = -1;
+          else
+            {
+              const char *orig_str = __getopt_nonoption_flags;
+              int len = d->__nonoption_flags_max_len = strlen (orig_str);
+              if (d->__nonoption_flags_max_len < argc)
+                d->__nonoption_flags_max_len = argc;
+              __getopt_nonoption_flags =
+                (char *) malloc (d->__nonoption_flags_max_len);
+              if (__getopt_nonoption_flags == NULL)
+                d->__nonoption_flags_max_len = -1;
+              else
+                memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+                        '\0', d->__nonoption_flags_max_len - len);
+            }
+        }
+      d->__nonoption_flags_len = d->__nonoption_flags_max_len;
+    }
+  else
+    d->__nonoption_flags_len = 0;
+#endif
+
+  return optstring;
+}
+\f
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns -1.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal_r (int argc, char **argv, const char *optstring,
+                    const struct option *longopts, int *longind,
+                    int long_only, struct _getopt_data *d, int posixly_correct)
+{
+  int print_errors = d->opterr;
+  if (optstring[0] == ':')
+    print_errors = 0;
+
+  if (argc < 1)
+    return -1;
+
+  d->optarg = NULL;
+
+  if (d->optind == 0 || !d->__initialized)
+    {
+      if (d->optind == 0)
+        d->optind = 1;  /* Don't scan ARGV[0], the program name.  */
+      optstring = _getopt_initialize (argc, argv, optstring, d,
+                                      posixly_correct);
+      d->__initialized = 1;
+    }
+
+  /* Test whether ARGV[optind] points to a non-option argument.
+     Either it does not have option syntax, or there is an environment flag
+     from the shell indicating it is not an option.  The later information
+     is only used when the used in the GNU libc.  */
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \
+                      || (d->optind < d->__nonoption_flags_len                \
+                          && __getopt_nonoption_flags[d->optind] == '1'))
+#else
+# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
+#endif
+
+  if (d->__nextchar == NULL || *d->__nextchar == '\0')
+    {
+      /* Advance to the next ARGV-element.  */
+
+      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+         moved back by the user (who may also have changed the arguments).  */
+      if (d->__last_nonopt > d->optind)
+        d->__last_nonopt = d->optind;
+      if (d->__first_nonopt > d->optind)
+        d->__first_nonopt = d->optind;
+
+      if (d->__ordering == PERMUTE)
+        {
+          /* If we have just processed some options following some non-options,
+             exchange them so that the options come first.  */
+
+          if (d->__first_nonopt != d->__last_nonopt
+              && d->__last_nonopt != d->optind)
+            exchange ((char **) argv, d);
+          else if (d->__last_nonopt != d->optind)
+            d->__first_nonopt = d->optind;
+
+          /* Skip any additional non-options
+             and extend the range of non-options previously skipped.  */
+
+          while (d->optind < argc && NONOPTION_P)
+            d->optind++;
+          d->__last_nonopt = d->optind;
+        }
+
+      /* The special ARGV-element `--' means premature end of options.
+         Skip it like a null option,
+         then exchange with previous non-options as if it were an option,
+         then skip everything else like a non-option.  */
+
+      if (d->optind != argc && !strcmp (argv[d->optind], "--"))
+        {
+          d->optind++;
+
+          if (d->__first_nonopt != d->__last_nonopt
+              && d->__last_nonopt != d->optind)
+            exchange ((char **) argv, d);
+          else if (d->__first_nonopt == d->__last_nonopt)
+            d->__first_nonopt = d->optind;
+          d->__last_nonopt = argc;
+
+          d->optind = argc;
+        }
+
+      /* If we have done all the ARGV-elements, stop the scan
+         and back over any non-options that we skipped and permuted.  */
+
+      if (d->optind == argc)
+        {
+          /* Set the next-arg-index to point at the non-options
+             that we previously skipped, so the caller will digest them.  */
+          if (d->__first_nonopt != d->__last_nonopt)
+            d->optind = d->__first_nonopt;
+          return -1;
+        }
+
+      /* If we have come to a non-option and did not permute it,
+         either stop the scan or describe it to the caller and pass it by.  */
+
+      if (NONOPTION_P)
+        {
+          if (d->__ordering == REQUIRE_ORDER)
+            return -1;
+          d->optarg = argv[d->optind++];
+          return 1;
+        }
+
+      /* We have found another option-ARGV-element.
+         Skip the initial punctuation.  */
+
+      d->__nextchar = (argv[d->optind] + 1
+                  + (longopts != NULL && argv[d->optind][1] == '-'));
+    }
+
+  /* Decode the current option-ARGV-element.  */
+
+  /* Check whether the ARGV-element is a long option.
+
+     If long_only and the ARGV-element has the form "-f", where f is
+     a valid short option, don't consider it an abbreviated form of
+     a long option that starts with f.  Otherwise there would be no
+     way to give the -f short option.
+
+     On the other hand, if there's a long option "fubar" and
+     the ARGV-element is "-fu", do consider that an abbreviation of
+     the long option, just like "--fu", and not "-f" with arg "u".
+
+     This distinction seems to be the most useful approach.  */
+
+  if (longopts != NULL
+      && (argv[d->optind][1] == '-'
+          || (long_only && (argv[d->optind][2]
+                            || !strchr (optstring, argv[d->optind][1])))))
+    {
+      char *nameend;
+      const struct option *p;
+      const struct option *pfound = NULL;
+      int exact = 0;
+      int ambig = 0;
+      int indfound = -1;
+      int option_index;
+
+      for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
+        /* Do nothing.  */ ;
+
+      /* Test all long options for either exact match
+         or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name; p++, option_index++)
+        if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
+          {
+            if ((unsigned int) (nameend - d->__nextchar)
+                == (unsigned int) strlen (p->name))
+              {
+                /* Exact match found.  */
+                pfound = p;
+                indfound = option_index;
+                exact = 1;
+                break;
+              }
+            else if (pfound == NULL)
+              {
+                /* First nonexact match found.  */
+                pfound = p;
+                indfound = option_index;
+              }
+            else if (long_only
+                     || pfound->has_arg != p->has_arg
+                     || pfound->flag != p->flag
+                     || pfound->val != p->val)
+              /* Second or later nonexact match found.  */
+              ambig = 1;
+          }
+
+      if (ambig && !exact)
+        {
+          if (print_errors)
+            {
+#if defined _LIBC && defined USE_IN_LIBIO
+              char *buf;
+
+              if (__asprintf (&buf, _("%s: option '%s' is ambiguous\n"),
+                              argv[0], argv[d->optind]) >= 0)
+                {
+                  _IO_flockfile (stderr);
+
+                  int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+                  ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+                  __fxprintf (NULL, "%s", buf);
+
+                  ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+                  _IO_funlockfile (stderr);
+
+                  free (buf);
+                }
+#else
+              fprintf (stderr, _("%s: option '%s' is ambiguous\n"),
+                       argv[0], argv[d->optind]);
+#endif
+            }
+          d->__nextchar += strlen (d->__nextchar);
+          d->optind++;
+          d->optopt = 0;
+          return '?';
+        }
+
+      if (pfound != NULL)
+        {
+          option_index = indfound;
+          d->optind++;
+          if (*nameend)
+            {
+              /* Don't test has_arg with >, because some C compilers don't
+                 allow it to be used on enums.  */
+              if (pfound->has_arg)
+                d->optarg = nameend + 1;
+              else
+                {
+                  if (print_errors)
+                    {
+#if defined _LIBC && defined USE_IN_LIBIO
+                      char *buf;
+                      int n;
+#endif
+
+                      if (argv[d->optind - 1][1] == '-')
+                        {
+                          /* --option */
+#if defined _LIBC && defined USE_IN_LIBIO
+                          n = __asprintf (&buf, _("\
+%s: option '--%s' doesn't allow an argument\n"),
+                                          argv[0], pfound->name);
+#else
+                          fprintf (stderr, _("\
+%s: option '--%s' doesn't allow an argument\n"),
+                                   argv[0], pfound->name);
+#endif
+                        }
+                      else
+                        {
+                          /* +option or -option */
+#if defined _LIBC && defined USE_IN_LIBIO
+                          n = __asprintf (&buf, _("\
+%s: option '%c%s' doesn't allow an argument\n"),
+                                          argv[0], argv[d->optind - 1][0],
+                                          pfound->name);
+#else
+                          fprintf (stderr, _("\
+%s: option '%c%s' doesn't allow an argument\n"),
+                                   argv[0], argv[d->optind - 1][0],
+                                   pfound->name);
+#endif
+                        }
+
+#if defined _LIBC && defined USE_IN_LIBIO
+                      if (n >= 0)
+                        {
+                          _IO_flockfile (stderr);
+
+                          int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+                          ((_IO_FILE *) stderr)->_flags2
+                            |= _IO_FLAGS2_NOTCANCEL;
+
+                          __fxprintf (NULL, "%s", buf);
+
+                          ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+                          _IO_funlockfile (stderr);
+
+                          free (buf);
+                        }
+#endif
+                    }
+
+                  d->__nextchar += strlen (d->__nextchar);
+
+                  d->optopt = pfound->val;
+                  return '?';
+                }
+            }
+          else if (pfound->has_arg == 1)
+            {
+              if (d->optind < argc)
+                d->optarg = argv[d->optind++];
+              else
+                {
+                  if (print_errors)
+                    {
+#if defined _LIBC && defined USE_IN_LIBIO
+                      char *buf;
+
+                      if (__asprintf (&buf, _("\
+%s: option '%s' requires an argument\n"),
+                                      argv[0], argv[d->optind - 1]) >= 0)
+                        {
+                          _IO_flockfile (stderr);
+
+                          int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+                          ((_IO_FILE *) stderr)->_flags2
+                            |= _IO_FLAGS2_NOTCANCEL;
+
+                          __fxprintf (NULL, "%s", buf);
+
+                          ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+                          _IO_funlockfile (stderr);
+
+                          free (buf);
+                        }
+#else
+                      fprintf (stderr,
+                               _("%s: option '%s' requires an argument\n"),
+                               argv[0], argv[d->optind - 1]);
+#endif
+                    }
+                  d->__nextchar += strlen (d->__nextchar);
+                  d->optopt = pfound->val;
+                  return optstring[0] == ':' ? ':' : '?';
+                }
+            }
+          d->__nextchar += strlen (d->__nextchar);
+          if (longind != NULL)
+            *longind = option_index;
+          if (pfound->flag)
+            {
+              *(pfound->flag) = pfound->val;
+              return 0;
+            }
+          return pfound->val;
+        }
+
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+         or the option starts with '--' or is not a valid short
+         option, then it's an error.
+         Otherwise interpret it as a short option.  */
+      if (!long_only || argv[d->optind][1] == '-'
+          || strchr (optstring, *d->__nextchar) == NULL)
+        {
+          if (print_errors)
+            {
+#if defined _LIBC && defined USE_IN_LIBIO
+              char *buf;
+              int n;
+#endif
+
+              if (argv[d->optind][1] == '-')
+                {
+                  /* --option */
+#if defined _LIBC && defined USE_IN_LIBIO
+                  n = __asprintf (&buf, _("%s: unrecognized option '--%s'\n"),
+                                  argv[0], d->__nextchar);
+#else
+                  fprintf (stderr, _("%s: unrecognized option '--%s'\n"),
+                           argv[0], d->__nextchar);
+#endif
+                }
+              else
+                {
+                  /* +option or -option */
+#if defined _LIBC && defined USE_IN_LIBIO
+                  n = __asprintf (&buf, _("%s: unrecognized option '%c%s'\n"),
+                                  argv[0], argv[d->optind][0], d->__nextchar);
+#else
+                  fprintf (stderr, _("%s: unrecognized option '%c%s'\n"),
+                           argv[0], argv[d->optind][0], d->__nextchar);
+#endif
+                }
+
+#if defined _LIBC && defined USE_IN_LIBIO
+              if (n >= 0)
+                {
+                  _IO_flockfile (stderr);
+
+                  int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+                  ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+                  __fxprintf (NULL, "%s", buf);
+
+                  ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+                  _IO_funlockfile (stderr);
+
+                  free (buf);
+                }
+#endif
+            }
+          d->__nextchar = (char *) "";
+          d->optind++;
+          d->optopt = 0;
+          return '?';
+        }
+    }
+
+  /* Look at and handle the next short option-character.  */
+
+  {
+    char c = *d->__nextchar++;
+    char *temp = strchr (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*d->__nextchar == '\0')
+      ++d->optind;
+
+    if (temp == NULL || c == ':')
+      {
+        if (print_errors)
+          {
+#if defined _LIBC && defined USE_IN_LIBIO
+              char *buf;
+              int n;
+#endif
+
+#if defined _LIBC && defined USE_IN_LIBIO
+              n = __asprintf (&buf, _("%s: invalid option -- '%c'\n"),
+                              argv[0], c);
+#else
+              fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c);
+#endif
+
+#if defined _LIBC && defined USE_IN_LIBIO
+            if (n >= 0)
+              {
+                _IO_flockfile (stderr);
+
+                int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+                ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+                __fxprintf (NULL, "%s", buf);
+
+                ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+                _IO_funlockfile (stderr);
+
+                free (buf);
+              }
+#endif
+          }
+        d->optopt = c;
+        return '?';
+      }
+    /* Convenience. Treat POSIX -W foo same as long option --foo */
+    if (temp[0] == 'W' && temp[1] == ';')
+      {
+        char *nameend;
+        const struct option *p;
+        const struct option *pfound = NULL;
+        int exact = 0;
+        int ambig = 0;
+        int indfound = 0;
+        int option_index;
+
+        /* This is an option that requires an argument.  */
+        if (*d->__nextchar != '\0')
+          {
+            d->optarg = d->__nextchar;
+            /* If we end this ARGV-element by taking the rest as an arg,
+               we must advance to the next element now.  */
+            d->optind++;
+          }
+        else if (d->optind == argc)
+          {
+            if (print_errors)
+              {
+#if defined _LIBC && defined USE_IN_LIBIO
+                char *buf;
+
+                if (__asprintf (&buf,
+                                _("%s: option requires an argument -- '%c'\n"),
+                                argv[0], c) >= 0)
+                  {
+                    _IO_flockfile (stderr);
+
+                    int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+                    ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+                    __fxprintf (NULL, "%s", buf);
+
+                    ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+                    _IO_funlockfile (stderr);
+
+                    free (buf);
+                  }
+#else
+                fprintf (stderr,
+                         _("%s: option requires an argument -- '%c'\n"),
+                         argv[0], c);
+#endif
+              }
+            d->optopt = c;
+            if (optstring[0] == ':')
+              c = ':';
+            else
+              c = '?';
+            return c;
+          }
+        else
+          /* We already incremented `d->optind' once;
+             increment it again when taking next ARGV-elt as argument.  */
+          d->optarg = argv[d->optind++];
+
+        /* optarg is now the argument, see if it's in the
+           table of longopts.  */
+
+        for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '=';
+             nameend++)
+          /* Do nothing.  */ ;
+
+        /* Test all long options for either exact match
+           or abbreviated matches.  */
+        for (p = longopts, option_index = 0; p->name; p++, option_index++)
+          if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
+            {
+              if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name))
+                {
+                  /* Exact match found.  */
+                  pfound = p;
+                  indfound = option_index;
+                  exact = 1;
+                  break;
+                }
+              else if (pfound == NULL)
+                {
+                  /* First nonexact match found.  */
+                  pfound = p;
+                  indfound = option_index;
+                }
+              else
+                /* Second or later nonexact match found.  */
+                ambig = 1;
+            }
+        if (ambig && !exact)
+          {
+            if (print_errors)
+              {
+#if defined _LIBC && defined USE_IN_LIBIO
+                char *buf;
+
+                if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"),
+                                argv[0], argv[d->optind]) >= 0)
+                  {
+                    _IO_flockfile (stderr);
+
+                    int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+                    ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+                    __fxprintf (NULL, "%s", buf);
+
+                    ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+                    _IO_funlockfile (stderr);
+
+                    free (buf);
+                  }
+#else
+                fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"),
+                         argv[0], argv[d->optind]);
+#endif
+              }
+            d->__nextchar += strlen (d->__nextchar);
+            d->optind++;
+            return '?';
+          }
+        if (pfound != NULL)
+          {
+            option_index = indfound;
+            if (*nameend)
+              {
+                /* Don't test has_arg with >, because some C compilers don't
+                   allow it to be used on enums.  */
+                if (pfound->has_arg)
+                  d->optarg = nameend + 1;
+                else
+                  {
+                    if (print_errors)
+                      {
+#if defined _LIBC && defined USE_IN_LIBIO
+                        char *buf;
+
+                        if (__asprintf (&buf, _("\
+%s: option '-W %s' doesn't allow an argument\n"),
+                                        argv[0], pfound->name) >= 0)
+                          {
+                            _IO_flockfile (stderr);
+
+                            int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+                            ((_IO_FILE *) stderr)->_flags2
+                              |= _IO_FLAGS2_NOTCANCEL;
+
+                            __fxprintf (NULL, "%s", buf);
+
+                            ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+                            _IO_funlockfile (stderr);
+
+                            free (buf);
+                          }
+#else
+                        fprintf (stderr, _("\
+%s: option '-W %s' doesn't allow an argument\n"),
+                                 argv[0], pfound->name);
+#endif
+                      }
+
+                    d->__nextchar += strlen (d->__nextchar);
+                    return '?';
+                  }
+              }
+            else if (pfound->has_arg == 1)
+              {
+                if (d->optind < argc)
+                  d->optarg = argv[d->optind++];
+                else
+                  {
+                    if (print_errors)
+                      {
+#if defined _LIBC && defined USE_IN_LIBIO
+                        char *buf;
+
+                        if (__asprintf (&buf, _("\
+%s: option '%s' requires an argument\n"),
+                                        argv[0], argv[d->optind - 1]) >= 0)
+                          {
+                            _IO_flockfile (stderr);
+
+                            int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+                            ((_IO_FILE *) stderr)->_flags2
+                              |= _IO_FLAGS2_NOTCANCEL;
+
+                            __fxprintf (NULL, "%s", buf);
+
+                            ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+                            _IO_funlockfile (stderr);
+
+                            free (buf);
+                          }
+#else
+                        fprintf (stderr,
+                                 _("%s: option '%s' requires an argument\n"),
+                                 argv[0], argv[d->optind - 1]);
+#endif
+                      }
+                    d->__nextchar += strlen (d->__nextchar);
+                    return optstring[0] == ':' ? ':' : '?';
+                  }
+              }
+            d->__nextchar += strlen (d->__nextchar);
+            if (longind != NULL)
+              *longind = option_index;
+            if (pfound->flag)
+              {
+                *(pfound->flag) = pfound->val;
+                return 0;
+              }
+            return pfound->val;
+          }
+          d->__nextchar = NULL;
+          return 'W';   /* Let the application handle it.   */
+      }
+    if (temp[1] == ':')
+      {
+        if (temp[2] == ':')
+          {
+            /* This is an option that accepts an argument optionally.  */
+            if (*d->__nextchar != '\0')
+              {
+                d->optarg = d->__nextchar;
+                d->optind++;
+              }
+            else
+              d->optarg = NULL;
+            d->__nextchar = NULL;
+          }
+        else
+          {
+            /* This is an option that requires an argument.  */
+            if (*d->__nextchar != '\0')
+              {
+                d->optarg = d->__nextchar;
+                /* If we end this ARGV-element by taking the rest as an arg,
+                   we must advance to the next element now.  */
+                d->optind++;
+              }
+            else if (d->optind == argc)
+              {
+                if (print_errors)
+                  {
+#if defined _LIBC && defined USE_IN_LIBIO
+                    char *buf;
+
+                    if (__asprintf (&buf, _("\
+%s: option requires an argument -- '%c'\n"),
+                                    argv[0], c) >= 0)
+                      {
+                        _IO_flockfile (stderr);
+
+                        int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+                        ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+                        __fxprintf (NULL, "%s", buf);
+
+                        ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+                        _IO_funlockfile (stderr);
+
+                        free (buf);
+                      }
+#else
+                    fprintf (stderr,
+                             _("%s: option requires an argument -- '%c'\n"),
+                             argv[0], c);
+#endif
+                  }
+                d->optopt = c;
+                if (optstring[0] == ':')
+                  c = ':';
+                else
+                  c = '?';
+              }
+            else
+              /* We already incremented `optind' once;
+                 increment it again when taking next ARGV-elt as argument.  */
+              d->optarg = argv[d->optind++];
+            d->__nextchar = NULL;
+          }
+      }
+    return c;
+  }
+}
+
+int
+_getopt_internal (int argc, char **argv, const char *optstring,
+                  const struct option *longopts, int *longind, int long_only,
+                  int posixly_correct)
+{
+  int result;
+
+  getopt_data.optind = optind;
+  getopt_data.opterr = opterr;
+
+  result = _getopt_internal_r (argc, argv, optstring, longopts,
+                               longind, long_only, &getopt_data,
+                               posixly_correct);
+
+  optind = getopt_data.optind;
+  optarg = getopt_data.optarg;
+  optopt = getopt_data.optopt;
+
+  return result;
+}
+
+/* glibc gets a LSB-compliant getopt.
+   Standalone applications get a POSIX-compliant getopt.  */
+#if _LIBC
+enum { POSIXLY_CORRECT = 0 };
+#else
+enum { POSIXLY_CORRECT = 1 };
+#endif
+
+int
+getopt (int argc, char *const *argv, const char *optstring)
+{
+  return _getopt_internal (argc, (char **) argv, optstring,
+                           (const struct option *) 0,
+                           (int *) 0,
+                           0, POSIXLY_CORRECT);
+}
+
+#ifdef _LIBC
+int
+__posix_getopt (int argc, char *const *argv, const char *optstring)
+{
+  return _getopt_internal (argc, argv, optstring,
+                           (const struct option *) 0,
+                           (int *) 0,
+                           0, 1);
+}
+#endif
+
+\f
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (int argc, char **argv)
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == -1)
+        break;
+
+      switch (c)
+        {
+        case '0':
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9':
+          if (digit_optind != 0 && digit_optind != this_option_optind)
+            printf ("digits occur in two different argv-elements.\n");
+          digit_optind = this_option_optind;
+          printf ("option %c\n", c);
+          break;
+
+        case 'a':
+          printf ("option a\n");
+          break;
+
+        case 'b':
+          printf ("option b\n");
+          break;
+
+        case 'c':
+          printf ("option c with value '%s'\n", optarg);
+          break;
+
+        case '?':
+          break;
+
+        default:
+          printf ("?? getopt returned character code 0%o ??\n", c);
+        }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+        printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/grub-core/gnulib/getopt.h b/grub-core/gnulib/getopt.h
new file mode 100644 (file)
index 0000000..d2d3e6e
--- /dev/null
@@ -0,0 +1,225 @@
+/* Declarations for getopt.
+   Copyright (C) 1989-1994,1996-1999,2001,2003,2004,2005,2006,2007
+   Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GETOPT_H
+
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+/* Standalone applications should #define __GETOPT_PREFIX to an
+   identifier that prefixes the external functions and variables
+   defined in this header.  When this happens, include the
+   headers that might declare getopt so that they will not cause
+   confusion if included after this file.  Then systematically rename
+   identifiers so that they do not collide with the system functions
+   and variables.  Renaming avoids problems with some compilers and
+   linkers.  */
+#if defined __GETOPT_PREFIX && !defined __need_getopt
+# include <stdlib.h>
+# include <stdio.h>
+# include <unistd.h>
+# undef __need_getopt
+# undef getopt
+# undef getopt_long
+# undef getopt_long_only
+# undef optarg
+# undef opterr
+# undef optind
+# undef optopt
+# define __GETOPT_CONCAT(x, y) x ## y
+# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y)
+# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y)
+# define getopt __GETOPT_ID (getopt)
+# define getopt_long __GETOPT_ID (getopt_long)
+# define getopt_long_only __GETOPT_ID (getopt_long_only)
+# define optarg __GETOPT_ID (optarg)
+# define opterr __GETOPT_ID (opterr)
+# define optind __GETOPT_ID (optind)
+# define optopt __GETOPT_ID (optopt)
+#endif
+
+/* Standalone applications get correct prototypes for getopt_long and
+   getopt_long_only; they declare "char **argv".  libc uses prototypes
+   with "char *const *argv" that are incorrect because getopt_long and
+   getopt_long_only can permute argv; this is required for backward
+   compatibility (e.g., for LSB 2.0.1).
+
+   This used to be `#if defined __GETOPT_PREFIX && !defined __need_getopt',
+   but it caused redefinition warnings if both unistd.h and getopt.h were
+   included, since unistd.h includes getopt.h having previously defined
+   __need_getopt.
+
+   The only place where __getopt_argv_const is used is in definitions
+   of getopt_long and getopt_long_only below, but these are visible
+   only if __need_getopt is not defined, so it is quite safe to rewrite
+   the conditional as follows:
+*/
+#if !defined __need_getopt
+# if defined __GETOPT_PREFIX
+#  define __getopt_argv_const /* empty */
+# else
+#  define __getopt_argv_const const
+# endif
+#endif
+
+/* If __GNU_LIBRARY__ is not already defined, either we are being used
+   standalone, or this is the first header included in the source file.
+   If we are being used with glibc, we need to include <features.h>, but
+   that does not exist if we are standalone.  So: if __GNU_LIBRARY__ is
+   not defined, include <ctype.h>, which will pull in <features.h> for us
+   if it's from glibc.  (Why ctype.h?  It's guaranteed to exist and it
+   doesn't flood the namespace with stuff the way some other headers do.)  */
+#if !defined __GNU_LIBRARY__
+# include <ctype.h>
+#endif
+
+#ifndef __THROW
+# ifndef __GNUC_PREREQ
+#  define __GNUC_PREREQ(maj, min) (0)
+# endif
+# if defined __cplusplus && __GNUC_PREREQ (2,8)
+#  define __THROW      throw ()
+# else
+#  define __THROW
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+#ifndef __need_getopt
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument         (or 0) if the option does not take an argument,
+   required_argument   (or 1) if the option requires an argument,
+   optional_argument   (or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+  const char *name;
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+# define no_argument           0
+# define required_argument     1
+# define optional_argument     2
+#endif /* need getopt */
+
+
+/* Get definitions and prototypes for functions to process the
+   arguments in ARGV (ARGC of them, minus the program name) for
+   options given in OPTS.
+
+   Return the option character from OPTS just read.  Return -1 when
+   there are no more options.  For unrecognized options, or options
+   missing arguments, `optopt' is set to the option letter, and '?' is
+   returned.
+
+   The OPTS string is a list of characters which are recognized option
+   letters, optionally followed by colons, specifying that that letter
+   takes an argument, to be placed in `optarg'.
+
+   If a letter in OPTS is followed by two colons, its argument is
+   optional.  This behavior is specific to the GNU `getopt'.
+
+   The argument `--' causes premature termination of argument
+   scanning, explicitly telling `getopt' that there are no more
+   options.
+
+   If OPTS begins with `-', then non-option arguments are treated as
+   arguments to the option '\1'.  This behavior is specific to the GNU
+   `getopt'.  If OPTS begins with `+', or POSIXLY_CORRECT is set in
+   the environment, then do not permute arguments.  */
+
+extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
+       __THROW;
+
+#ifndef __need_getopt
+extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv,
+                       const char *__shortopts,
+                       const struct option *__longopts, int *__longind)
+       __THROW;
+extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv,
+                            const char *__shortopts,
+                            const struct option *__longopts, int *__longind)
+       __THROW;
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Make sure we later can get all the definitions and declarations.  */
+#undef __need_getopt
+
+#endif /* getopt.h */
diff --git a/grub-core/gnulib/getopt1.c b/grub-core/gnulib/getopt1.c
new file mode 100644 (file)
index 0000000..046d69f
--- /dev/null
@@ -0,0 +1,170 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+   Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997,
+   1998, 2004, 2006, 2009, 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+\f
+#ifdef _LIBC
+# include <getopt.h>
+#else
+# include <config.h>
+# include "getopt.h"
+#endif
+#include "getopt_int.h"
+
+#include <stdio.h>
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (int argc, char *__getopt_argv_const *argv, const char *options,
+             const struct option *long_options, int *opt_index)
+{
+  return _getopt_internal (argc, (char **) argv, options, long_options,
+                           opt_index, 0, 0);
+}
+
+int
+_getopt_long_r (int argc, char **argv, const char *options,
+                const struct option *long_options, int *opt_index,
+                struct _getopt_data *d)
+{
+  return _getopt_internal_r (argc, argv, options, long_options, opt_index,
+                             0, d, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+   If an option that starts with '-' (not '--') doesn't match a long option,
+   but does match a short option, it is parsed as a short option
+   instead.  */
+
+int
+getopt_long_only (int argc, char *__getopt_argv_const *argv,
+                  const char *options,
+                  const struct option *long_options, int *opt_index)
+{
+  return _getopt_internal (argc, (char **) argv, options, long_options,
+                           opt_index, 1, 0);
+}
+
+int
+_getopt_long_only_r (int argc, char **argv, const char *options,
+                     const struct option *long_options, int *opt_index,
+                     struct _getopt_data *d)
+{
+  return _getopt_internal_r (argc, argv, options, long_options, opt_index,
+                             1, d, 0);
+}
+
+\f
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+      int option_index = 0;
+      static const struct option long_options[] =
+      {
+        {"add", 1, 0, 0},
+        {"append", 0, 0, 0},
+        {"delete", 1, 0, 0},
+        {"verbose", 0, 0, 0},
+        {"create", 0, 0, 0},
+        {"file", 1, 0, 0},
+        {0, 0, 0, 0}
+      };
+
+      c = getopt_long (argc, argv, "abc:d:0123456789",
+                       long_options, &option_index);
+      if (c == -1)
+        break;
+
+      switch (c)
+        {
+        case 0:
+          printf ("option %s", long_options[option_index].name);
+          if (optarg)
+            printf (" with arg %s", optarg);
+          printf ("\n");
+          break;
+
+        case '0':
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9':
+          if (digit_optind != 0 && digit_optind != this_option_optind)
+            printf ("digits occur in two different argv-elements.\n");
+          digit_optind = this_option_optind;
+          printf ("option %c\n", c);
+          break;
+
+        case 'a':
+          printf ("option a\n");
+          break;
+
+        case 'b':
+          printf ("option b\n");
+          break;
+
+        case 'c':
+          printf ("option c with value `%s'\n", optarg);
+          break;
+
+        case 'd':
+          printf ("option d with value `%s'\n", optarg);
+          break;
+
+        case '?':
+          break;
+
+        default:
+          printf ("?? getopt returned character code 0%o ??\n", c);
+        }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+        printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/grub-core/gnulib/getopt_int.h b/grub-core/gnulib/getopt_int.h
new file mode 100644 (file)
index 0000000..169def5
--- /dev/null
@@ -0,0 +1,132 @@
+/* Internal declarations for getopt.
+   Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2004, 2009-2010 Free Software
+   Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GETOPT_INT_H
+#define _GETOPT_INT_H   1
+
+#include <getopt.h>
+
+extern int _getopt_internal (int ___argc, char **___argv,
+                             const char *__shortopts,
+                             const struct option *__longopts, int *__longind,
+                             int __long_only, int __posixly_correct);
+
+\f
+/* Reentrant versions which can handle parsing multiple argument
+   vectors at the same time.  */
+
+/* Data type for reentrant functions.  */
+struct _getopt_data
+{
+  /* These have exactly the same meaning as the corresponding global
+     variables, except that they are used for the reentrant
+     versions of getopt.  */
+  int optind;
+  int opterr;
+  int optopt;
+  char *optarg;
+
+  /* Internal members.  */
+
+  /* True if the internal members have been initialized.  */
+  int __initialized;
+
+  /* The next char to be scanned in the option-element
+     in which the last option character we returned was found.
+     This allows us to pick up the scan where we left off.
+
+     If this is zero, or a null string, it means resume the scan
+     by advancing to the next ARGV-element.  */
+  char *__nextchar;
+
+  /* Describe how to deal with options that follow non-option ARGV-elements.
+
+     If the caller did not specify anything,
+     the default is REQUIRE_ORDER if the environment variable
+     POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+     REQUIRE_ORDER means don't recognize them as options;
+     stop option processing when the first non-option is seen.
+     This is what Unix does.
+     This mode of operation is selected by either setting the environment
+     variable POSIXLY_CORRECT, or using `+' as the first character
+     of the list of option characters, or by calling getopt.
+
+     PERMUTE is the default.  We permute the contents of ARGV as we
+     scan, so that eventually all the non-options are at the end.
+     This allows options to be given in any order, even with programs
+     that were not written to expect this.
+
+     RETURN_IN_ORDER is an option available to programs that were
+     written to expect options and other ARGV-elements in any order
+     and that care about the ordering of the two.  We describe each
+     non-option ARGV-element as if it were the argument of an option
+     with character code 1.  Using `-' as the first character of the
+     list of option characters selects this mode of operation.
+
+     The special argument `--' forces an end of option-scanning regardless
+     of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+     `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
+
+  enum
+    {
+      REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+    } __ordering;
+
+  /* If the POSIXLY_CORRECT environment variable is set
+     or getopt was called.  */
+  int __posixly_correct;
+
+
+  /* Handle permutation of arguments.  */
+
+  /* Describe the part of ARGV that contains non-options that have
+     been skipped.  `first_nonopt' is the index in ARGV of the first
+     of them; `last_nonopt' is the index after the last of them.  */
+
+  int __first_nonopt;
+  int __last_nonopt;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+  int __nonoption_flags_max_len;
+  int __nonoption_flags_len;
+# endif
+};
+
+/* The initializer is necessary to set OPTIND and OPTERR to their
+   default values and to clear the initialization flag.  */
+#define _GETOPT_DATA_INITIALIZER        { 1, 1 }
+
+extern int _getopt_internal_r (int ___argc, char **___argv,
+                               const char *__shortopts,
+                               const struct option *__longopts, int *__longind,
+                               int __long_only, struct _getopt_data *__data,
+                               int __posixly_correct);
+
+extern int _getopt_long_r (int ___argc, char **___argv,
+                           const char *__shortopts,
+                           const struct option *__longopts, int *__longind,
+                           struct _getopt_data *__data);
+
+extern int _getopt_long_only_r (int ___argc, char **___argv,
+                                const char *__shortopts,
+                                const struct option *__longopts,
+                                int *__longind,
+                                struct _getopt_data *__data);
+
+#endif /* getopt_int.h */
diff --git a/grub-core/gnulib/gettext.h b/grub-core/gnulib/gettext.h
new file mode 100644 (file)
index 0000000..6a069c4
--- /dev/null
@@ -0,0 +1,280 @@
+/* Convenience header for conditional use of GNU <libintl.h>.
+   Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2010 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _LIBGETTEXT_H
+#define _LIBGETTEXT_H 1
+
+/* NLS can be disabled through the configure --disable-nls option.  */
+#if ENABLE_NLS
+
+/* Get declarations of GNU message catalog functions.  */
+# include <libintl.h>
+
+/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
+   the gettext() and ngettext() macros.  This is an alternative to calling
+   textdomain(), and is useful for libraries.  */
+# ifdef DEFAULT_TEXT_DOMAIN
+#  undef gettext
+#  define gettext(Msgid) \
+     dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
+#  undef ngettext
+#  define ngettext(Msgid1, Msgid2, N) \
+     dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
+# endif
+
+#else
+
+/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
+   chokes if dcgettext is defined as a macro.  So include it now, to make
+   later inclusions of <locale.h> a NOP.  We don't include <libintl.h>
+   as well because people using "gettext.h" will not include <libintl.h>,
+   and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
+   is OK.  */
+#if defined(__sun)
+# include <locale.h>
+#endif
+
+/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
+   <libintl.h>, which chokes if dcgettext is defined as a macro.  So include
+   it now, to make later inclusions of <libintl.h> a NOP.  */
+#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
+# include <cstdlib>
+# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
+#  include <libintl.h>
+# endif
+#endif
+
+/* Disabled NLS.
+   The casts to 'const char *' serve the purpose of producing warnings
+   for invalid uses of the value returned from these functions.
+   On pre-ANSI systems without 'const', the config.h file is supposed to
+   contain "#define const".  */
+# undef gettext
+# define gettext(Msgid) ((const char *) (Msgid))
+# undef dgettext
+# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
+# undef dcgettext
+# define dcgettext(Domainname, Msgid, Category) \
+    ((void) (Category), dgettext (Domainname, Msgid))
+# undef ngettext
+# define ngettext(Msgid1, Msgid2, N) \
+    ((N) == 1 \
+     ? ((void) (Msgid2), (const char *) (Msgid1)) \
+     : ((void) (Msgid1), (const char *) (Msgid2)))
+# undef dngettext
+# define dngettext(Domainname, Msgid1, Msgid2, N) \
+    ((void) (Domainname), ngettext (Msgid1, Msgid2, N))
+# undef dcngettext
+# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
+    ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N))
+# undef textdomain
+# define textdomain(Domainname) ((const char *) (Domainname))
+# undef bindtextdomain
+# define bindtextdomain(Domainname, Dirname) \
+    ((void) (Domainname), (const char *) (Dirname))
+# undef bind_textdomain_codeset
+# define bind_textdomain_codeset(Domainname, Codeset) \
+    ((void) (Domainname), (const char *) (Codeset))
+
+#endif
+
+/* A pseudo function call that serves as a marker for the automated
+   extraction of messages, but does not call gettext().  The run-time
+   translation is done at a different place in the code.
+   The argument, String, should be a literal string.  Concatenated strings
+   and other string expressions won't work.
+   The macro's expansion is not parenthesized, so that it is suitable as
+   initializer for static 'char[]' or 'const char[]' variables.  */
+#define gettext_noop(String) String
+
+/* The separator between msgctxt and msgid in a .mo file.  */
+#define GETTEXT_CONTEXT_GLUE "\004"
+
+/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
+   MSGID.  MSGCTXT and MSGID must be string literals.  MSGCTXT should be
+   short and rarely need to change.
+   The letter 'p' stands for 'particular' or 'special'.  */
+#ifdef DEFAULT_TEXT_DOMAIN
+# define pgettext(Msgctxt, Msgid) \
+   pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+#else
+# define pgettext(Msgctxt, Msgid) \
+   pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+#endif
+#define dpgettext(Domainname, Msgctxt, Msgid) \
+  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
+  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
+#ifdef DEFAULT_TEXT_DOMAIN
+# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
+   npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+#else
+# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
+   npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+#endif
+#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
+  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
+  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+pgettext_aux (const char *domain,
+              const char *msg_ctxt_id, const char *msgid,
+              int category)
+{
+  const char *translation = dcgettext (domain, msg_ctxt_id, category);
+  if (translation == msg_ctxt_id)
+    return msgid;
+  else
+    return translation;
+}
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+npgettext_aux (const char *domain,
+               const char *msg_ctxt_id, const char *msgid,
+               const char *msgid_plural, unsigned long int n,
+               int category)
+{
+  const char *translation =
+    dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
+  if (translation == msg_ctxt_id || translation == msgid_plural)
+    return (n == 1 ? msgid : msgid_plural);
+  else
+    return translation;
+}
+
+/* The same thing extended for non-constant arguments.  Here MSGCTXT and MSGID
+   can be arbitrary expressions.  But for string literals these macros are
+   less efficient than those above.  */
+
+#include <string.h>
+
+#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
+  (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
+   /* || __STDC_VERSION__ >= 199901L */ )
+
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+#include <stdlib.h>
+#endif
+
+#define pgettext_expr(Msgctxt, Msgid) \
+  dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
+#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
+  dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+dcpgettext_expr (const char *domain,
+                 const char *msgctxt, const char *msgid,
+                 int category)
+{
+  size_t msgctxt_len = strlen (msgctxt) + 1;
+  size_t msgid_len = strlen (msgid) + 1;
+  const char *translation;
+#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+  char msg_ctxt_id[msgctxt_len + msgid_len];
+#else
+  char buf[1024];
+  char *msg_ctxt_id =
+    (msgctxt_len + msgid_len <= sizeof (buf)
+     ? buf
+     : (char *) malloc (msgctxt_len + msgid_len));
+  if (msg_ctxt_id != NULL)
+#endif
+    {
+      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
+      msg_ctxt_id[msgctxt_len - 1] = '\004';
+      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
+      translation = dcgettext (domain, msg_ctxt_id, category);
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+      if (msg_ctxt_id != buf)
+        free (msg_ctxt_id);
+#endif
+      if (translation != msg_ctxt_id)
+        return translation;
+    }
+  return msgid;
+}
+
+#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
+  dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
+#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
+  dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+dcnpgettext_expr (const char *domain,
+                  const char *msgctxt, const char *msgid,
+                  const char *msgid_plural, unsigned long int n,
+                  int category)
+{
+  size_t msgctxt_len = strlen (msgctxt) + 1;
+  size_t msgid_len = strlen (msgid) + 1;
+  const char *translation;
+#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+  char msg_ctxt_id[msgctxt_len + msgid_len];
+#else
+  char buf[1024];
+  char *msg_ctxt_id =
+    (msgctxt_len + msgid_len <= sizeof (buf)
+     ? buf
+     : (char *) malloc (msgctxt_len + msgid_len));
+  if (msg_ctxt_id != NULL)
+#endif
+    {
+      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
+      msg_ctxt_id[msgctxt_len - 1] = '\004';
+      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
+      translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+      if (msg_ctxt_id != buf)
+        free (msg_ctxt_id);
+#endif
+      if (!(translation == msg_ctxt_id || translation == msgid_plural))
+        return translation;
+    }
+  return (n == 1 ? msgid : msgid_plural);
+}
+
+#endif /* _LIBGETTEXT_H */
diff --git a/grub-core/gnulib/progname.c b/grub-core/gnulib/progname.c
new file mode 100644 (file)
index 0000000..1415e6a
--- /dev/null
@@ -0,0 +1,92 @@
+/* Program name management.
+   Copyright (C) 2001-2003, 2005-2010 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2001.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+
+#include <config.h>
+
+/* Specification.  */
+#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
+#include "progname.h"
+
+#include <errno.h> /* get program_invocation_name declaration */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/* String containing name the program is called with.
+   To be initialized by main().  */
+const char *program_name = NULL;
+
+/* Set program_name, based on argv[0].
+   argv0 must be a string allocated with indefinite extent, and must not be
+   modified after this call.  */
+void
+set_program_name (const char *argv0)
+{
+  /* libtool creates a temporary executable whose name is sometimes prefixed
+     with "lt-" (depends on the platform).  It also makes argv[0] absolute.
+     But the name of the temporary executable is a detail that should not be
+     visible to the end user and to the test suite.
+     Remove this "<dirname>/.libs/" or "<dirname>/.libs/lt-" prefix here.  */
+  const char *slash;
+  const char *base;
+
+  /* Sanity check.  POSIX requires the invoking process to pass a non-NULL
+     argv[0].  */
+  if (argv0 == NULL)
+    {
+      /* It's a bug in the invoking program.  Help diagnosing it.  */
+      fputs ("A NULL argv[0] was passed through an exec system call.\n",
+             stderr);
+      abort ();
+    }
+
+  slash = strrchr (argv0, '/');
+  base = (slash != NULL ? slash + 1 : argv0);
+  if (base - argv0 >= 7 && strncmp (base - 7, "/.libs/", 7) == 0)
+    {
+      argv0 = base;
+      if (strncmp (base, "lt-", 3) == 0)
+        {
+          argv0 = base + 3;
+          /* On glibc systems, remove the "lt-" prefix from the variable
+             program_invocation_short_name.  */
+#if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
+          program_invocation_short_name = (char *) argv0;
+#endif
+        }
+    }
+
+  /* But don't strip off a leading <dirname>/ in general, because when the user
+     runs
+         /some/hidden/place/bin/cp foo foo
+     he should get the error message
+         /some/hidden/place/bin/cp: `foo' and `foo' are the same file
+     not
+         cp: `foo' and `foo' are the same file
+   */
+
+  program_name = argv0;
+
+  /* On glibc systems, the error() function comes from libc and uses the
+     variable program_invocation_name, not program_name.  So set this variable
+     as well.  */
+#if HAVE_DECL_PROGRAM_INVOCATION_NAME
+  program_invocation_name = (char *) argv0;
+#endif
+}
diff --git a/grub-core/gnulib/progname.h b/grub-core/gnulib/progname.h
new file mode 100644 (file)
index 0000000..5ba303b
--- /dev/null
@@ -0,0 +1,62 @@
+/* Program name management.
+   Copyright (C) 2001-2004, 2006, 2009-2010 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2001.
+
+   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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _PROGNAME_H
+#define _PROGNAME_H
+
+/* Programs using this file should do the following in main():
+     set_program_name (argv[0]);
+ */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* String containing name the program is called with.  */
+extern const char *program_name;
+
+/* Set program_name, based on argv[0].
+   argv0 must be a string allocated with indefinite extent, and must not be
+   modified after this call.  */
+extern void set_program_name (const char *argv0);
+
+#if ENABLE_RELOCATABLE
+
+/* Set program_name, based on argv[0], and original installation prefix and
+   directory, for relocatability.  */
+extern void set_program_name_and_installdir (const char *argv0,
+                                             const char *orig_installprefix,
+                                             const char *orig_installdir);
+#undef set_program_name
+#define set_program_name(ARG0) \
+  set_program_name_and_installdir (ARG0, INSTALLPREFIX, INSTALLDIR)
+
+/* Return the full pathname of the current executable, based on the earlier
+   call to set_program_name_and_installdir.  Return NULL if unknown.  */
+extern char *get_full_program_name (void);
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _PROGNAME_H */
diff --git a/grub-core/gnulib/regcomp.c b/grub-core/gnulib/regcomp.c
new file mode 100644 (file)
index 0000000..7eff569
--- /dev/null
@@ -0,0 +1,3877 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
+   Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
+
+   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
+                                         size_t length, reg_syntax_t syntax);
+static void re_compile_fastmap_iter (regex_t *bufp,
+                                    const re_dfastate_t *init_state,
+                                    char *fastmap);
+static reg_errcode_t init_dfa (re_dfa_t *dfa, size_t pat_len);
+#ifdef RE_ENABLE_I18N
+static void free_charset (re_charset_t *cset);
+#endif /* RE_ENABLE_I18N */
+static void free_workarea_compile (regex_t *preg);
+static reg_errcode_t create_initial_state (re_dfa_t *dfa);
+#ifdef RE_ENABLE_I18N
+static void optimize_utf8 (re_dfa_t *dfa);
+#endif
+static reg_errcode_t analyze (regex_t *preg);
+static reg_errcode_t preorder (bin_tree_t *root,
+                              reg_errcode_t (fn (void *, bin_tree_t *)),
+                              void *extra);
+static reg_errcode_t postorder (bin_tree_t *root,
+                               reg_errcode_t (fn (void *, bin_tree_t *)),
+                               void *extra);
+static reg_errcode_t optimize_subexps (void *extra, bin_tree_t *node);
+static reg_errcode_t lower_subexps (void *extra, bin_tree_t *node);
+static bin_tree_t *lower_subexp (reg_errcode_t *err, regex_t *preg,
+                                bin_tree_t *node);
+static reg_errcode_t calc_first (void *extra, bin_tree_t *node);
+static reg_errcode_t calc_next (void *extra, bin_tree_t *node);
+static reg_errcode_t link_nfa_nodes (void *extra, bin_tree_t *node);
+static Idx duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint);
+static Idx search_duplicated_node (const re_dfa_t *dfa, Idx org_node,
+                                  unsigned int constraint);
+static reg_errcode_t calc_eclosure (re_dfa_t *dfa);
+static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa,
+                                        Idx node, bool root);
+static reg_errcode_t calc_inveclosure (re_dfa_t *dfa);
+static Idx fetch_number (re_string_t *input, re_token_t *token,
+                        reg_syntax_t syntax);
+static int peek_token (re_token_t *token, re_string_t *input,
+                       reg_syntax_t syntax) internal_function;
+static bin_tree_t *parse (re_string_t *regexp, regex_t *preg,
+                         reg_syntax_t syntax, reg_errcode_t *err);
+static bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg,
+                                 re_token_t *token, reg_syntax_t syntax,
+                                 Idx nest, reg_errcode_t *err);
+static bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg,
+                                re_token_t *token, reg_syntax_t syntax,
+                                Idx nest, reg_errcode_t *err);
+static bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg,
+                                    re_token_t *token, reg_syntax_t syntax,
+                                    Idx nest, reg_errcode_t *err);
+static bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg,
+                                 re_token_t *token, reg_syntax_t syntax,
+                                 Idx nest, reg_errcode_t *err);
+static bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp,
+                                re_dfa_t *dfa, re_token_t *token,
+                                reg_syntax_t syntax, reg_errcode_t *err);
+static bin_tree_t *parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa,
+                                     re_token_t *token, reg_syntax_t syntax,
+                                     reg_errcode_t *err);
+static reg_errcode_t parse_bracket_element (bracket_elem_t *elem,
+                                           re_string_t *regexp,
+                                           re_token_t *token, int token_len,
+                                           re_dfa_t *dfa,
+                                           reg_syntax_t syntax,
+                                           bool accept_hyphen);
+static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem,
+                                         re_string_t *regexp,
+                                         re_token_t *token);
+#ifdef RE_ENABLE_I18N
+static reg_errcode_t build_equiv_class (bitset_t sbcset,
+                                       re_charset_t *mbcset,
+                                       Idx *equiv_class_alloc,
+                                       const unsigned char *name);
+static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,
+                                     bitset_t sbcset,
+                                     re_charset_t *mbcset,
+                                     Idx *char_class_alloc,
+                                     const unsigned char *class_name,
+                                     reg_syntax_t syntax);
+#else  /* not RE_ENABLE_I18N */
+static reg_errcode_t build_equiv_class (bitset_t sbcset,
+                                       const unsigned char *name);
+static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,
+                                     bitset_t sbcset,
+                                     const unsigned char *class_name,
+                                     reg_syntax_t syntax);
+#endif /* not RE_ENABLE_I18N */
+static bin_tree_t *build_charclass_op (re_dfa_t *dfa,
+                                      RE_TRANSLATE_TYPE trans,
+                                      const unsigned char *class_name,
+                                      const unsigned char *extra,
+                                      bool non_match, reg_errcode_t *err);
+static bin_tree_t *create_tree (re_dfa_t *dfa,
+                               bin_tree_t *left, bin_tree_t *right,
+                               re_token_type_t type);
+static bin_tree_t *create_token_tree (re_dfa_t *dfa,
+                                     bin_tree_t *left, bin_tree_t *right,
+                                     const re_token_t *token);
+static bin_tree_t *duplicate_tree (const bin_tree_t *src, re_dfa_t *dfa);
+static void free_token (re_token_t *node);
+static reg_errcode_t free_tree (void *extra, bin_tree_t *node);
+static reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node);
+\f
+/* This table gives an error message for each of the error codes listed
+   in regex.h.  Obviously the order here has to be same as there.
+   POSIX doesn't require that we do anything for REG_NOERROR,
+   but why not be nice?  */
+
+static const char __re_error_msgid[] =
+  {
+#define REG_NOERROR_IDX        0
+    gettext_noop ("Success")   /* REG_NOERROR */
+    "\0"
+#define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof "Success")
+    gettext_noop ("No match")  /* REG_NOMATCH */
+    "\0"
+#define REG_BADPAT_IDX (REG_NOMATCH_IDX + sizeof "No match")
+    gettext_noop ("Invalid regular expression") /* REG_BADPAT */
+    "\0"
+#define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof "Invalid regular expression")
+    gettext_noop ("Invalid collation character") /* REG_ECOLLATE */
+    "\0"
+#define REG_ECTYPE_IDX (REG_ECOLLATE_IDX + sizeof "Invalid collation character")
+    gettext_noop ("Invalid character class name") /* REG_ECTYPE */
+    "\0"
+#define REG_EESCAPE_IDX        (REG_ECTYPE_IDX + sizeof "Invalid character class name")
+    gettext_noop ("Trailing backslash") /* REG_EESCAPE */
+    "\0"
+#define REG_ESUBREG_IDX        (REG_EESCAPE_IDX + sizeof "Trailing backslash")
+    gettext_noop ("Invalid back reference") /* REG_ESUBREG */
+    "\0"
+#define REG_EBRACK_IDX (REG_ESUBREG_IDX + sizeof "Invalid back reference")
+    gettext_noop ("Unmatched [ or [^") /* REG_EBRACK */
+    "\0"
+#define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [ or [^")
+    gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */
+    "\0"
+#define REG_EBRACE_IDX (REG_EPAREN_IDX + sizeof "Unmatched ( or \\(")
+    gettext_noop ("Unmatched \\{") /* REG_EBRACE */
+    "\0"
+#define REG_BADBR_IDX  (REG_EBRACE_IDX + sizeof "Unmatched \\{")
+    gettext_noop ("Invalid content of \\{\\}") /* REG_BADBR */
+    "\0"
+#define REG_ERANGE_IDX (REG_BADBR_IDX + sizeof "Invalid content of \\{\\}")
+    gettext_noop ("Invalid range end") /* REG_ERANGE */
+    "\0"
+#define REG_ESPACE_IDX (REG_ERANGE_IDX + sizeof "Invalid range end")
+    gettext_noop ("Memory exhausted") /* REG_ESPACE */
+    "\0"
+#define REG_BADRPT_IDX (REG_ESPACE_IDX + sizeof "Memory exhausted")
+    gettext_noop ("Invalid preceding regular expression") /* REG_BADRPT */
+    "\0"
+#define REG_EEND_IDX   (REG_BADRPT_IDX + sizeof "Invalid preceding regular expression")
+    gettext_noop ("Premature end of regular expression") /* REG_EEND */
+    "\0"
+#define REG_ESIZE_IDX  (REG_EEND_IDX + sizeof "Premature end of regular expression")
+    gettext_noop ("Regular expression too big") /* REG_ESIZE */
+    "\0"
+#define REG_ERPAREN_IDX        (REG_ESIZE_IDX + sizeof "Regular expression too big")
+    gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
+  };
+
+static const size_t __re_error_msgid_idx[] =
+  {
+    REG_NOERROR_IDX,
+    REG_NOMATCH_IDX,
+    REG_BADPAT_IDX,
+    REG_ECOLLATE_IDX,
+    REG_ECTYPE_IDX,
+    REG_EESCAPE_IDX,
+    REG_ESUBREG_IDX,
+    REG_EBRACK_IDX,
+    REG_EPAREN_IDX,
+    REG_EBRACE_IDX,
+    REG_BADBR_IDX,
+    REG_ERANGE_IDX,
+    REG_ESPACE_IDX,
+    REG_BADRPT_IDX,
+    REG_EEND_IDX,
+    REG_ESIZE_IDX,
+    REG_ERPAREN_IDX
+  };
+\f
+/* Entry points for GNU code.  */
+
+/* re_compile_pattern is the GNU regular expression compiler: it
+   compiles PATTERN (of length LENGTH) and puts the result in BUFP.
+   Returns 0 if the pattern was valid, otherwise an error string.
+
+   Assumes the `allocated' (and perhaps `buffer') and `translate' fields
+   are set in BUFP on entry.  */
+
+#ifdef _LIBC
+const char *
+re_compile_pattern (pattern, length, bufp)
+    const char *pattern;
+    size_t length;
+    struct re_pattern_buffer *bufp;
+#else /* size_t might promote */
+const char *
+re_compile_pattern (const char *pattern, size_t length,
+                   struct re_pattern_buffer *bufp)
+#endif
+{
+  reg_errcode_t ret;
+
+  /* And GNU code determines whether or not to get register information
+     by passing null for the REGS argument to re_match, etc., not by
+     setting no_sub, unless RE_NO_SUB is set.  */
+  bufp->no_sub = !!(re_syntax_options & RE_NO_SUB);
+
+  /* Match anchors at newline.  */
+  bufp->newline_anchor = 1;
+
+  ret = re_compile_internal (bufp, pattern, length, re_syntax_options);
+
+  if (!ret)
+    return NULL;
+  return gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]);
+}
+#ifdef _LIBC
+weak_alias (__re_compile_pattern, re_compile_pattern)
+#endif
+
+/* Set by `re_set_syntax' to the current regexp syntax to recognize.  Can
+   also be assigned to arbitrarily: each pattern buffer stores its own
+   syntax, so it can be changed between regex compilations.  */
+/* This has no initializer because initialized variables in Emacs
+   become read-only after dumping.  */
+reg_syntax_t re_syntax_options;
+
+
+/* Specify the precise syntax of regexps for compilation.  This provides
+   for compatibility for various utilities which historically have
+   different, incompatible syntaxes.
+
+   The argument SYNTAX is a bit mask comprised of the various bits
+   defined in regex.h.  We return the old syntax.  */
+
+reg_syntax_t
+re_set_syntax (syntax)
+    reg_syntax_t syntax;
+{
+  reg_syntax_t ret = re_syntax_options;
+
+  re_syntax_options = syntax;
+  return ret;
+}
+#ifdef _LIBC
+weak_alias (__re_set_syntax, re_set_syntax)
+#endif
+
+int
+re_compile_fastmap (bufp)
+    struct re_pattern_buffer *bufp;
+{
+  re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
+  char *fastmap = bufp->fastmap;
+
+  memset (fastmap, '\0', sizeof (char) * SBC_MAX);
+  re_compile_fastmap_iter (bufp, dfa->init_state, fastmap);
+  if (dfa->init_state != dfa->init_state_word)
+    re_compile_fastmap_iter (bufp, dfa->init_state_word, fastmap);
+  if (dfa->init_state != dfa->init_state_nl)
+    re_compile_fastmap_iter (bufp, dfa->init_state_nl, fastmap);
+  if (dfa->init_state != dfa->init_state_begbuf)
+    re_compile_fastmap_iter (bufp, dfa->init_state_begbuf, fastmap);
+  bufp->fastmap_accurate = 1;
+  return 0;
+}
+#ifdef _LIBC
+weak_alias (__re_compile_fastmap, re_compile_fastmap)
+#endif
+
+static inline void
+__attribute ((always_inline))
+re_set_fastmap (char *fastmap, bool icase, int ch)
+{
+  fastmap[ch] = 1;
+  if (icase)
+    fastmap[tolower (ch)] = 1;
+}
+
+/* Helper function for re_compile_fastmap.
+   Compile fastmap for the initial_state INIT_STATE.  */
+
+static void
+re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
+                        char *fastmap)
+{
+  re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
+  Idx node_cnt;
+  bool icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));
+  for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
+    {
+      Idx node = init_state->nodes.elems[node_cnt];
+      re_token_type_t type = dfa->nodes[node].type;
+
+      if (type == CHARACTER)
+       {
+         re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
+#ifdef RE_ENABLE_I18N
+         if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
+           {
+             unsigned char buf[MB_LEN_MAX];
+             unsigned char *p;
+             wchar_t wc;
+             mbstate_t state;
+
+             p = buf;
+             *p++ = dfa->nodes[node].opr.c;
+             while (++node < dfa->nodes_len
+                    && dfa->nodes[node].type == CHARACTER
+                    && dfa->nodes[node].mb_partial)
+               *p++ = dfa->nodes[node].opr.c;
+             memset (&state, '\0', sizeof (state));
+             if (__mbrtowc (&wc, (const char *) buf, p - buf,
+                            &state) == p - buf
+                 && (__wcrtomb ((char *) buf, towlower (wc), &state)
+                     != (size_t) -1))
+               re_set_fastmap (fastmap, false, buf[0]);
+           }
+#endif
+       }
+      else if (type == SIMPLE_BRACKET)
+       {
+         int i, ch;
+         for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
+           {
+             int j;
+             bitset_word_t w = dfa->nodes[node].opr.sbcset[i];
+             for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
+               if (w & ((bitset_word_t) 1 << j))
+                 re_set_fastmap (fastmap, icase, ch);
+           }
+       }
+#ifdef RE_ENABLE_I18N
+      else if (type == COMPLEX_BRACKET)
+       {
+         re_charset_t *cset = dfa->nodes[node].opr.mbcset;
+         Idx i;
+
+# ifdef _LIBC
+         /* See if we have to try all bytes which start multiple collation
+            elements.
+            e.g. In da_DK, we want to catch 'a' since "aa" is a valid
+                 collation element, and don't catch 'b' since 'b' is
+                 the only collation element which starts from 'b' (and
+                 it is caught by SIMPLE_BRACKET).  */
+             if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0
+                 && (cset->ncoll_syms || cset->nranges))
+               {
+                 const int32_t *table = (const int32_t *)
+                   _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+                 for (i = 0; i < SBC_MAX; ++i)
+                   if (table[i] < 0)
+                     re_set_fastmap (fastmap, icase, i);
+               }
+# endif /* _LIBC */
+
+         /* See if we have to start the match at all multibyte characters,
+            i.e. where we would not find an invalid sequence.  This only
+            applies to multibyte character sets; for single byte character
+            sets, the SIMPLE_BRACKET again suffices.  */
+         if (dfa->mb_cur_max > 1
+             && (cset->nchar_classes || cset->non_match || cset->nranges
+# ifdef _LIBC
+                 || cset->nequiv_classes
+# endif /* _LIBC */
+                ))
+           {
+             unsigned char c = 0;
+             do
+               {
+                 mbstate_t mbs;
+                 memset (&mbs, 0, sizeof (mbs));
+                 if (__mbrtowc (NULL, (char *) &c, 1, &mbs) == (size_t) -2)
+                   re_set_fastmap (fastmap, false, (int) c);
+               }
+             while (++c != 0);
+           }
+
+         else
+           {
+             /* ... Else catch all bytes which can start the mbchars.  */
+             for (i = 0; i < cset->nmbchars; ++i)
+               {
+                 char buf[256];
+                 mbstate_t state;
+                 memset (&state, '\0', sizeof (state));
+                 if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
+                   re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
+                 if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
+                   {
+                     if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)
+                         != (size_t) -1)
+                       re_set_fastmap (fastmap, false, *(unsigned char *) buf);
+                   }
+               }
+           }
+       }
+#endif /* RE_ENABLE_I18N */
+      else if (type == OP_PERIOD
+#ifdef RE_ENABLE_I18N
+              || type == OP_UTF8_PERIOD
+#endif /* RE_ENABLE_I18N */
+              || type == END_OF_RE)
+       {
+         memset (fastmap, '\1', sizeof (char) * SBC_MAX);
+         if (type == END_OF_RE)
+           bufp->can_be_null = 1;
+         return;
+       }
+    }
+}
+\f
+/* Entry point for POSIX code.  */
+/* regcomp takes a regular expression as a string and compiles it.
+
+   PREG is a regex_t *.  We do not expect any fields to be initialized,
+   since POSIX says we shouldn't.  Thus, we set
+
+     `buffer' to the compiled pattern;
+     `used' to the length of the compiled pattern;
+     `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
+       REG_EXTENDED bit in CFLAGS is set; otherwise, to
+       RE_SYNTAX_POSIX_BASIC;
+     `newline_anchor' to REG_NEWLINE being set in CFLAGS;
+     `fastmap' to an allocated space for the fastmap;
+     `fastmap_accurate' to zero;
+     `re_nsub' to the number of subexpressions in PATTERN.
+
+   PATTERN is the address of the pattern string.
+
+   CFLAGS is a series of bits which affect compilation.
+
+     If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
+     use POSIX basic syntax.
+
+     If REG_NEWLINE is set, then . and [^...] don't match newline.
+     Also, regexec will try a match beginning after every newline.
+
+     If REG_ICASE is set, then we considers upper- and lowercase
+     versions of letters to be equivalent when matching.
+
+     If REG_NOSUB is set, then when PREG is passed to regexec, that
+     routine will report only success or failure, and nothing about the
+     registers.
+
+   It returns 0 if it succeeds, nonzero if it doesn't.  (See regex.h for
+   the return codes and their meanings.)  */
+
+int
+regcomp (preg, pattern, cflags)
+    regex_t *_Restrict_ preg;
+    const char *_Restrict_ pattern;
+    int cflags;
+{
+  reg_errcode_t ret;
+  reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED
+                        : RE_SYNTAX_POSIX_BASIC);
+
+  preg->buffer = NULL;
+  preg->allocated = 0;
+  preg->used = 0;
+
+  /* Try to allocate space for the fastmap.  */
+  preg->fastmap = re_malloc (char, SBC_MAX);
+  if (BE (preg->fastmap == NULL, 0))
+    return REG_ESPACE;
+
+  syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0;
+
+  /* If REG_NEWLINE is set, newlines are treated differently.  */
+  if (cflags & REG_NEWLINE)
+    { /* REG_NEWLINE implies neither . nor [^...] match newline.  */
+      syntax &= ~RE_DOT_NEWLINE;
+      syntax |= RE_HAT_LISTS_NOT_NEWLINE;
+      /* It also changes the matching behavior.  */
+      preg->newline_anchor = 1;
+    }
+  else
+    preg->newline_anchor = 0;
+  preg->no_sub = !!(cflags & REG_NOSUB);
+  preg->translate = NULL;
+
+  ret = re_compile_internal (preg, pattern, strlen (pattern), syntax);
+
+  /* POSIX doesn't distinguish between an unmatched open-group and an
+     unmatched close-group: both are REG_EPAREN.  */
+  if (ret == REG_ERPAREN)
+    ret = REG_EPAREN;
+
+  /* We have already checked preg->fastmap != NULL.  */
+  if (BE (ret == REG_NOERROR, 1))
+    /* Compute the fastmap now, since regexec cannot modify the pattern
+       buffer.  This function never fails in this implementation.  */
+    (void) re_compile_fastmap (preg);
+  else
+    {
+      /* Some error occurred while compiling the expression.  */
+      re_free (preg->fastmap);
+      preg->fastmap = NULL;
+    }
+
+  return (int) ret;
+}
+#ifdef _LIBC
+weak_alias (__regcomp, regcomp)
+#endif
+
+/* Returns a message corresponding to an error code, ERRCODE, returned
+   from either regcomp or regexec.   We don't use PREG here.  */
+
+#ifdef _LIBC
+size_t
+regerror (errcode, preg, errbuf, errbuf_size)
+    int errcode;
+    const regex_t *_Restrict_ preg;
+    char *_Restrict_ errbuf;
+    size_t errbuf_size;
+#else /* size_t might promote */
+size_t
+regerror (int errcode, const regex_t *_Restrict_ preg,
+         char *_Restrict_ errbuf, size_t errbuf_size)
+#endif
+{
+  const char *msg;
+  size_t msg_size;
+
+  if (BE (errcode < 0
+         || errcode >= (int) (sizeof (__re_error_msgid_idx)
+                              / sizeof (__re_error_msgid_idx[0])), 0))
+    /* Only error codes returned by the rest of the code should be passed
+       to this routine.  If we are given anything else, or if other regex
+       code generates an invalid error code, then the program has a bug.
+       Dump core so we can fix it.  */
+    abort ();
+
+  msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]);
+
+  msg_size = strlen (msg) + 1; /* Includes the null.  */
+
+  if (BE (errbuf_size != 0, 1))
+    {
+      size_t cpy_size = msg_size;
+      if (BE (msg_size > errbuf_size, 0))
+       {
+         cpy_size = errbuf_size - 1;
+         errbuf[cpy_size] = '\0';
+       }
+      memcpy (errbuf, msg, cpy_size);
+    }
+
+  return msg_size;
+}
+#ifdef _LIBC
+weak_alias (__regerror, regerror)
+#endif
+
+
+#ifdef RE_ENABLE_I18N
+/* This static array is used for the map to single-byte characters when
+   UTF-8 is used.  Otherwise we would allocate memory just to initialize
+   it the same all the time.  UTF-8 is the preferred encoding so this is
+   a worthwhile optimization.  */
+static const bitset_t utf8_sb_map =
+{
+  /* Set the first 128 bits.  */
+# if 4 * BITSET_WORD_BITS < ASCII_CHARS
+#  error "bitset_word_t is narrower than 32 bits"
+# elif 3 * BITSET_WORD_BITS < ASCII_CHARS
+  BITSET_WORD_MAX, BITSET_WORD_MAX, BITSET_WORD_MAX,
+# elif 2 * BITSET_WORD_BITS < ASCII_CHARS
+  BITSET_WORD_MAX, BITSET_WORD_MAX,
+# elif 1 * BITSET_WORD_BITS < ASCII_CHARS
+  BITSET_WORD_MAX,
+# endif
+  (BITSET_WORD_MAX
+   >> (SBC_MAX % BITSET_WORD_BITS == 0
+       ? 0
+       : BITSET_WORD_BITS - SBC_MAX % BITSET_WORD_BITS))
+};
+#endif
+
+
+static void
+free_dfa_content (re_dfa_t *dfa)
+{
+  Idx i, j;
+
+  if (dfa->nodes)
+    for (i = 0; i < dfa->nodes_len; ++i)
+      free_token (dfa->nodes + i);
+  re_free (dfa->nexts);
+  for (i = 0; i < dfa->nodes_len; ++i)
+    {
+      if (dfa->eclosures != NULL)
+       re_node_set_free (dfa->eclosures + i);
+      if (dfa->inveclosures != NULL)
+       re_node_set_free (dfa->inveclosures + i);
+      if (dfa->edests != NULL)
+       re_node_set_free (dfa->edests + i);
+    }
+  re_free (dfa->edests);
+  re_free (dfa->eclosures);
+  re_free (dfa->inveclosures);
+  re_free (dfa->nodes);
+
+  if (dfa->state_table)
+    for (i = 0; i <= dfa->state_hash_mask; ++i)
+      {
+       struct re_state_table_entry *entry = dfa->state_table + i;
+       for (j = 0; j < entry->num; ++j)
+         {
+           re_dfastate_t *state = entry->array[j];
+           free_state (state);
+         }
+       re_free (entry->array);
+      }
+  re_free (dfa->state_table);
+#ifdef RE_ENABLE_I18N
+  if (dfa->sb_char != utf8_sb_map)
+    re_free (dfa->sb_char);
+#endif
+  re_free (dfa->subexp_map);
+#ifdef DEBUG
+  re_free (dfa->re_str);
+#endif
+
+  re_free (dfa);
+}
+
+
+/* Free dynamically allocated space used by PREG.  */
+
+void
+regfree (preg)
+    regex_t *preg;
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  if (BE (dfa != NULL, 1))
+    free_dfa_content (dfa);
+  preg->buffer = NULL;
+  preg->allocated = 0;
+
+  re_free (preg->fastmap);
+  preg->fastmap = NULL;
+
+  re_free (preg->translate);
+  preg->translate = NULL;
+}
+#ifdef _LIBC
+weak_alias (__regfree, regfree)
+#endif
+\f
+/* Entry points compatible with 4.2 BSD regex library.  We don't define
+   them unless specifically requested.  */
+
+#if defined _REGEX_RE_COMP || defined _LIBC
+
+/* BSD has one and only one pattern buffer.  */
+static struct re_pattern_buffer re_comp_buf;
+
+char *
+# ifdef _LIBC
+/* Make these definitions weak in libc, so POSIX programs can redefine
+   these names if they don't use our functions, and still use
+   regcomp/regexec above without link errors.  */
+weak_function
+# endif
+re_comp (s)
+     const char *s;
+{
+  reg_errcode_t ret;
+  char *fastmap;
+
+  if (!s)
+    {
+      if (!re_comp_buf.buffer)
+       return gettext ("No previous regular expression");
+      return 0;
+    }
+
+  if (re_comp_buf.buffer)
+    {
+      fastmap = re_comp_buf.fastmap;
+      re_comp_buf.fastmap = NULL;
+      __regfree (&re_comp_buf);
+      memset (&re_comp_buf, '\0', sizeof (re_comp_buf));
+      re_comp_buf.fastmap = fastmap;
+    }
+
+  if (re_comp_buf.fastmap == NULL)
+    {
+      re_comp_buf.fastmap = (char *) malloc (SBC_MAX);
+      if (re_comp_buf.fastmap == NULL)
+       return (char *) gettext (__re_error_msgid
+                                + __re_error_msgid_idx[(int) REG_ESPACE]);
+    }
+
+  /* Since `re_exec' always passes NULL for the `regs' argument, we
+     don't need to initialize the pattern buffer fields which affect it.  */
+
+  /* Match anchors at newlines.  */
+  re_comp_buf.newline_anchor = 1;
+
+  ret = re_compile_internal (&re_comp_buf, s, strlen (s), re_syntax_options);
+
+  if (!ret)
+    return NULL;
+
+  /* Yes, we're discarding `const' here if !HAVE_LIBINTL.  */
+  return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]);
+}
+
+#ifdef _LIBC
+libc_freeres_fn (free_mem)
+{
+  __regfree (&re_comp_buf);
+}
+#endif
+
+#endif /* _REGEX_RE_COMP */
+\f
+/* Internal entry point.
+   Compile the regular expression PATTERN, whose length is LENGTH.
+   SYNTAX indicate regular expression's syntax.  */
+
+static reg_errcode_t
+re_compile_internal (regex_t *preg, const char * pattern, size_t length,
+                    reg_syntax_t syntax)
+{
+  reg_errcode_t err = REG_NOERROR;
+  re_dfa_t *dfa;
+  re_string_t regexp;
+
+  /* Initialize the pattern buffer.  */
+  preg->fastmap_accurate = 0;
+  preg->syntax = syntax;
+  preg->not_bol = preg->not_eol = 0;
+  preg->used = 0;
+  preg->re_nsub = 0;
+  preg->can_be_null = 0;
+  preg->regs_allocated = REGS_UNALLOCATED;
+
+  /* Initialize the dfa.  */
+  dfa = (re_dfa_t *) preg->buffer;
+  if (BE (preg->allocated < sizeof (re_dfa_t), 0))
+    {
+      /* If zero allocated, but buffer is non-null, try to realloc
+        enough space.  This loses if buffer's address is bogus, but
+        that is the user's responsibility.  If ->buffer is NULL this
+        is a simple allocation.  */
+      dfa = re_realloc (preg->buffer, re_dfa_t, 1);
+      if (dfa == NULL)
+       return REG_ESPACE;
+      preg->allocated = sizeof (re_dfa_t);
+      preg->buffer = (unsigned char *) dfa;
+    }
+  preg->used = sizeof (re_dfa_t);
+
+  err = init_dfa (dfa, length);
+  if (BE (err != REG_NOERROR, 0))
+    {
+      free_dfa_content (dfa);
+      preg->buffer = NULL;
+      preg->allocated = 0;
+      return err;
+    }
+#ifdef DEBUG
+  /* Note: length+1 will not overflow since it is checked in init_dfa.  */
+  dfa->re_str = re_malloc (char, length + 1);
+  strncpy (dfa->re_str, pattern, length + 1);
+#endif
+
+  __libc_lock_init (dfa->lock);
+
+  err = re_string_construct (&regexp, pattern, length, preg->translate,
+                            (syntax & RE_ICASE) != 0, dfa);
+  if (BE (err != REG_NOERROR, 0))
+    {
+    re_compile_internal_free_return:
+      free_workarea_compile (preg);
+      re_string_destruct (&regexp);
+      free_dfa_content (dfa);
+      preg->buffer = NULL;
+      preg->allocated = 0;
+      return err;
+    }
+
+  /* Parse the regular expression, and build a structure tree.  */
+  preg->re_nsub = 0;
+  dfa->str_tree = parse (&regexp, preg, syntax, &err);
+  if (BE (dfa->str_tree == NULL, 0))
+    goto re_compile_internal_free_return;
+
+  /* Analyze the tree and create the nfa.  */
+  err = analyze (preg);
+  if (BE (err != REG_NOERROR, 0))
+    goto re_compile_internal_free_return;
+
+#ifdef RE_ENABLE_I18N
+  /* If possible, do searching in single byte encoding to speed things up.  */
+  if (dfa->is_utf8 && !(syntax & RE_ICASE) && preg->translate == NULL)
+    optimize_utf8 (dfa);
+#endif
+
+  /* Then create the initial state of the dfa.  */
+  err = create_initial_state (dfa);
+
+  /* Release work areas.  */
+  free_workarea_compile (preg);
+  re_string_destruct (&regexp);
+
+  if (BE (err != REG_NOERROR, 0))
+    {
+      free_dfa_content (dfa);
+      preg->buffer = NULL;
+      preg->allocated = 0;
+    }
+
+  return err;
+}
+
+/* Initialize DFA.  We use the length of the regular expression PAT_LEN
+   as the initial length of some arrays.  */
+
+static reg_errcode_t
+init_dfa (re_dfa_t *dfa, size_t pat_len)
+{
+  __re_size_t table_size;
+#ifndef _LIBC
+  char *codeset_name;
+#endif
+#ifdef RE_ENABLE_I18N
+  size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t));
+#else
+  size_t max_i18n_object_size = 0;
+#endif
+  size_t max_object_size =
+    MAX (sizeof (struct re_state_table_entry),
+        MAX (sizeof (re_token_t),
+             MAX (sizeof (re_node_set),
+                  MAX (sizeof (regmatch_t),
+                       max_i18n_object_size))));
+
+  memset (dfa, '\0', sizeof (re_dfa_t));
+
+  /* Force allocation of str_tree_storage the first time.  */
+  dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;
+
+  /* Avoid overflows.  The extra "/ 2" is for the table_size doubling
+     calculation below, and for similar doubling calculations
+     elsewhere.  And it's <= rather than <, because some of the
+     doubling calculations add 1 afterwards.  */
+  if (BE (SIZE_MAX / max_object_size / 2 <= pat_len, 0))
+    return REG_ESPACE;
+
+  dfa->nodes_alloc = pat_len + 1;
+  dfa->nodes = re_malloc (re_token_t, dfa->nodes_alloc);
+
+  /*  table_size = 2 ^ ceil(log pat_len) */
+  for (table_size = 1; ; table_size <<= 1)
+    if (table_size > pat_len)
+      break;
+
+  dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size);
+  dfa->state_hash_mask = table_size - 1;
+
+  dfa->mb_cur_max = MB_CUR_MAX;
+#ifdef _LIBC
+  if (dfa->mb_cur_max == 6
+      && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0)
+    dfa->is_utf8 = 1;
+  dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII)
+                      != 0);
+#else
+  codeset_name = nl_langinfo (CODESET);
+  if (strcasecmp (codeset_name, "UTF-8") == 0
+      || strcasecmp (codeset_name, "UTF8") == 0)
+    dfa->is_utf8 = 1;
+
+  /* We check exhaustively in the loop below if this charset is a
+     superset of ASCII.  */
+  dfa->map_notascii = 0;
+#endif
+
+#ifdef RE_ENABLE_I18N
+  if (dfa->mb_cur_max > 1)
+    {
+      if (dfa->is_utf8)
+       dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map;
+      else
+       {
+         int i, j, ch;
+
+         dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
+         if (BE (dfa->sb_char == NULL, 0))
+           return REG_ESPACE;
+
+         /* Set the bits corresponding to single byte chars.  */
+         for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
+           for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
+             {
+               wint_t wch = __btowc (ch);
+               if (wch != WEOF)
+                 dfa->sb_char[i] |= (bitset_word_t) 1 << j;
+# ifndef _LIBC
+               if (isascii (ch) && wch != ch)
+                 dfa->map_notascii = 1;
+# endif
+             }
+       }
+    }
+#endif
+
+  if (BE (dfa->nodes == NULL || dfa->state_table == NULL, 0))
+    return REG_ESPACE;
+  return REG_NOERROR;
+}
+
+/* Initialize WORD_CHAR table, which indicate which character is
+   "word".  In this case "word" means that it is the word construction
+   character used by some operators like "\<", "\>", etc.  */
+
+static void
+internal_function
+init_word_char (re_dfa_t *dfa)
+{
+  int i, j, ch;
+  dfa->word_ops_used = 1;
+  for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
+    for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
+      if (isalnum (ch) || ch == '_')
+       dfa->word_char[i] |= (bitset_word_t) 1 << j;
+}
+
+/* Free the work area which are only used while compiling.  */
+
+static void
+free_workarea_compile (regex_t *preg)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_storage_t *storage, *next;
+  for (storage = dfa->str_tree_storage; storage; storage = next)
+    {
+      next = storage->next;
+      re_free (storage);
+    }
+  dfa->str_tree_storage = NULL;
+  dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;
+  dfa->str_tree = NULL;
+  re_free (dfa->org_indices);
+  dfa->org_indices = NULL;
+}
+
+/* Create initial states for all contexts.  */
+
+static reg_errcode_t
+create_initial_state (re_dfa_t *dfa)
+{
+  Idx first, i;
+  reg_errcode_t err;
+  re_node_set init_nodes;
+
+  /* Initial states have the epsilon closure of the node which is
+     the first node of the regular expression.  */
+  first = dfa->str_tree->first->node_idx;
+  dfa->init_node = first;
+  err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+
+  /* The back-references which are in initial states can epsilon transit,
+     since in this case all of the subexpressions can be null.
+     Then we add epsilon closures of the nodes which are the next nodes of
+     the back-references.  */
+  if (dfa->nbackref > 0)
+    for (i = 0; i < init_nodes.nelem; ++i)
+      {
+       Idx node_idx = init_nodes.elems[i];
+       re_token_type_t type = dfa->nodes[node_idx].type;
+
+       Idx clexp_idx;
+       if (type != OP_BACK_REF)
+         continue;
+       for (clexp_idx = 0; clexp_idx < init_nodes.nelem; ++clexp_idx)
+         {
+           re_token_t *clexp_node;
+           clexp_node = dfa->nodes + init_nodes.elems[clexp_idx];
+           if (clexp_node->type == OP_CLOSE_SUBEXP
+               && clexp_node->opr.idx == dfa->nodes[node_idx].opr.idx)
+             break;
+         }
+       if (clexp_idx == init_nodes.nelem)
+         continue;
+
+       if (type == OP_BACK_REF)
+         {
+           Idx dest_idx = dfa->edests[node_idx].elems[0];
+           if (!re_node_set_contains (&init_nodes, dest_idx))
+             {
+               reg_errcode_t merge_err
+                  = re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx);
+               if (merge_err != REG_NOERROR)
+                 return merge_err;
+               i = 0;
+             }
+         }
+      }
+
+  /* It must be the first time to invoke acquire_state.  */
+  dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0);
+  /* We don't check ERR here, since the initial state must not be NULL.  */
+  if (BE (dfa->init_state == NULL, 0))
+    return err;
+  if (dfa->init_state->has_constraint)
+    {
+      dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes,
+                                                      CONTEXT_WORD);
+      dfa->init_state_nl = re_acquire_state_context (&err, dfa, &init_nodes,
+                                                    CONTEXT_NEWLINE);
+      dfa->init_state_begbuf = re_acquire_state_context (&err, dfa,
+                                                        &init_nodes,
+                                                        CONTEXT_NEWLINE
+                                                        | CONTEXT_BEGBUF);
+      if (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL
+             || dfa->init_state_begbuf == NULL, 0))
+       return err;
+    }
+  else
+    dfa->init_state_word = dfa->init_state_nl
+      = dfa->init_state_begbuf = dfa->init_state;
+
+  re_node_set_free (&init_nodes);
+  return REG_NOERROR;
+}
+\f
+#ifdef RE_ENABLE_I18N
+/* If it is possible to do searching in single byte encoding instead of UTF-8
+   to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change
+   DFA nodes where needed.  */
+
+static void
+optimize_utf8 (re_dfa_t *dfa)
+{
+  Idx node;
+  int i;
+  bool mb_chars = false;
+  bool has_period = false;
+
+  for (node = 0; node < dfa->nodes_len; ++node)
+    switch (dfa->nodes[node].type)
+      {
+      case CHARACTER:
+       if (dfa->nodes[node].opr.c >= ASCII_CHARS)
+         mb_chars = true;
+       break;
+      case ANCHOR:
+       switch (dfa->nodes[node].opr.ctx_type)
+         {
+         case LINE_FIRST:
+         case LINE_LAST:
+         case BUF_FIRST:
+         case BUF_LAST:
+           break;
+         default:
+           /* Word anchors etc. cannot be handled.  It's okay to test
+              opr.ctx_type since constraints (for all DFA nodes) are
+              created by ORing one or more opr.ctx_type values.  */
+           return;
+         }
+       break;
+      case OP_PERIOD:
+       has_period = true;
+       break;
+      case OP_BACK_REF:
+      case OP_ALT:
+      case END_OF_RE:
+      case OP_DUP_ASTERISK:
+      case OP_OPEN_SUBEXP:
+      case OP_CLOSE_SUBEXP:
+       break;
+      case COMPLEX_BRACKET:
+       return;
+      case SIMPLE_BRACKET:
+       /* Just double check.  */
+       {
+         int rshift = (ASCII_CHARS % BITSET_WORD_BITS == 0
+                       ? 0
+                       : BITSET_WORD_BITS - ASCII_CHARS % BITSET_WORD_BITS);
+         for (i = ASCII_CHARS / BITSET_WORD_BITS; i < BITSET_WORDS; ++i)
+           {
+             if (dfa->nodes[node].opr.sbcset[i] >> rshift != 0)
+               return;
+             rshift = 0;
+           }
+       }
+       break;
+      default:
+       abort ();
+      }
+
+  if (mb_chars || has_period)
+    for (node = 0; node < dfa->nodes_len; ++node)
+      {
+       if (dfa->nodes[node].type == CHARACTER
+           && dfa->nodes[node].opr.c >= ASCII_CHARS)
+         dfa->nodes[node].mb_partial = 0;
+       else if (dfa->nodes[node].type == OP_PERIOD)
+         dfa->nodes[node].type = OP_UTF8_PERIOD;
+      }
+
+  /* The search can be in single byte locale.  */
+  dfa->mb_cur_max = 1;
+  dfa->is_utf8 = 0;
+  dfa->has_mb_node = dfa->nbackref > 0 || has_period;
+}
+#endif
+\f
+/* Analyze the structure tree, and calculate "first", "next", "edest",
+   "eclosure", and "inveclosure".  */
+
+static reg_errcode_t
+analyze (regex_t *preg)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  reg_errcode_t ret;
+
+  /* Allocate arrays.  */
+  dfa->nexts = re_malloc (Idx, dfa->nodes_alloc);
+  dfa->org_indices = re_malloc (Idx, dfa->nodes_alloc);
+  dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc);
+  dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc);
+  if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL
+         || dfa->eclosures == NULL, 0))
+    return REG_ESPACE;
+
+  dfa->subexp_map = re_malloc (Idx, preg->re_nsub);
+  if (dfa->subexp_map != NULL)
+    {
+      Idx i;
+      for (i = 0; i < preg->re_nsub; i++)
+       dfa->subexp_map[i] = i;
+      preorder (dfa->str_tree, optimize_subexps, dfa);
+      for (i = 0; i < preg->re_nsub; i++)
+       if (dfa->subexp_map[i] != i)
+         break;
+      if (i == preg->re_nsub)
+       {
+         free (dfa->subexp_map);
+         dfa->subexp_map = NULL;
+       }
+    }
+
+  ret = postorder (dfa->str_tree, lower_subexps, preg);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+  ret = postorder (dfa->str_tree, calc_first, dfa);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+  preorder (dfa->str_tree, calc_next, dfa);
+  ret = preorder (dfa->str_tree, link_nfa_nodes, dfa);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+  ret = calc_eclosure (dfa);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+
+  /* We only need this during the prune_impossible_nodes pass in regexec.c;
+     skip it if p_i_n will not run, as calc_inveclosure can be quadratic.  */
+  if ((!preg->no_sub && preg->re_nsub > 0 && dfa->has_plural_match)
+      || dfa->nbackref)
+    {
+      dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len);
+      if (BE (dfa->inveclosures == NULL, 0))
+       return REG_ESPACE;
+      ret = calc_inveclosure (dfa);
+    }
+
+  return ret;
+}
+
+/* Our parse trees are very unbalanced, so we cannot use a stack to
+   implement parse tree visits.  Instead, we use parent pointers and
+   some hairy code in these two functions.  */
+static reg_errcode_t
+postorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)),
+          void *extra)
+{
+  bin_tree_t *node, *prev;
+
+  for (node = root; ; )
+    {
+      /* Descend down the tree, preferably to the left (or to the right
+        if that's the only child).  */
+      while (node->left || node->right)
+       if (node->left)
+         node = node->left;
+       else
+         node = node->right;
+
+      do
+       {
+         reg_errcode_t err = fn (extra, node);
+         if (BE (err != REG_NOERROR, 0))
+           return err;
+         if (node->parent == NULL)
+           return REG_NOERROR;
+         prev = node;
+         node = node->parent;
+       }
+      /* Go up while we have a node that is reached from the right.  */
+      while (node->right == prev || node->right == NULL);
+      node = node->right;
+    }
+}
+
+static reg_errcode_t
+preorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)),
+         void *extra)
+{
+  bin_tree_t *node;
+
+  for (node = root; ; )
+    {
+      reg_errcode_t err = fn (extra, node);
+      if (BE (err != REG_NOERROR, 0))
+       return err;
+
+      /* Go to the left node, or up and to the right.  */
+      if (node->left)
+       node = node->left;
+      else
+       {
+         bin_tree_t *prev = NULL;
+         while (node->right == prev || node->right == NULL)
+           {
+             prev = node;
+             node = node->parent;
+             if (!node)
+               return REG_NOERROR;
+           }
+         node = node->right;
+       }
+    }
+}
+
+/* Optimization pass: if a SUBEXP is entirely contained, strip it and tell
+   re_search_internal to map the inner one's opr.idx to this one's.  Adjust
+   backreferences as well.  Requires a preorder visit.  */
+static reg_errcode_t
+optimize_subexps (void *extra, bin_tree_t *node)
+{
+  re_dfa_t *dfa = (re_dfa_t *) extra;
+
+  if (node->token.type == OP_BACK_REF && dfa->subexp_map)
+    {
+      int idx = node->token.opr.idx;
+      node->token.opr.idx = dfa->subexp_map[idx];
+      dfa->used_bkref_map |= 1 << node->token.opr.idx;
+    }
+
+  else if (node->token.type == SUBEXP
+          && node->left && node->left->token.type == SUBEXP)
+    {
+      Idx other_idx = node->left->token.opr.idx;
+
+      node->left = node->left->left;
+      if (node->left)
+       node->left->parent = node;
+
+      dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx];
+      if (other_idx < BITSET_WORD_BITS)
+       dfa->used_bkref_map &= ~((bitset_word_t) 1 << other_idx);
+    }
+
+  return REG_NOERROR;
+}
+
+/* Lowering pass: Turn each SUBEXP node into the appropriate concatenation
+   of OP_OPEN_SUBEXP, the body of the SUBEXP (if any) and OP_CLOSE_SUBEXP.  */
+static reg_errcode_t
+lower_subexps (void *extra, bin_tree_t *node)
+{
+  regex_t *preg = (regex_t *) extra;
+  reg_errcode_t err = REG_NOERROR;
+
+  if (node->left && node->left->token.type == SUBEXP)
+    {
+      node->left = lower_subexp (&err, preg, node->left);
+      if (node->left)
+       node->left->parent = node;
+    }
+  if (node->right && node->right->token.type == SUBEXP)
+    {
+      node->right = lower_subexp (&err, preg, node->right);
+      if (node->right)
+       node->right->parent = node;
+    }
+
+  return err;
+}
+
+static bin_tree_t *
+lower_subexp (reg_errcode_t *err, regex_t *preg, bin_tree_t *node)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_t *body = node->left;
+  bin_tree_t *op, *cls, *tree1, *tree;
+
+  if (preg->no_sub
+      /* We do not optimize empty subexpressions, because otherwise we may
+        have bad CONCAT nodes with NULL children.  This is obviously not
+        very common, so we do not lose much.  An example that triggers
+        this case is the sed "script" /\(\)/x.  */
+      && node->left != NULL
+      && (node->token.opr.idx >= BITSET_WORD_BITS
+         || !(dfa->used_bkref_map
+              & ((bitset_word_t) 1 << node->token.opr.idx))))
+    return node->left;
+
+  /* Convert the SUBEXP node to the concatenation of an
+     OP_OPEN_SUBEXP, the contents, and an OP_CLOSE_SUBEXP.  */
+  op = create_tree (dfa, NULL, NULL, OP_OPEN_SUBEXP);
+  cls = create_tree (dfa, NULL, NULL, OP_CLOSE_SUBEXP);
+  tree1 = body ? create_tree (dfa, body, cls, CONCAT) : cls;
+  tree = create_tree (dfa, op, tree1, CONCAT);
+  if (BE (tree == NULL || tree1 == NULL || op == NULL || cls == NULL, 0))
+    {
+      *err = REG_ESPACE;
+      return NULL;
+    }
+
+  op->token.opr.idx = cls->token.opr.idx = node->token.opr.idx;
+  op->token.opt_subexp = cls->token.opt_subexp = node->token.opt_subexp;
+  return tree;
+}
+
+/* Pass 1 in building the NFA: compute FIRST and create unlinked automaton
+   nodes.  Requires a postorder visit.  */
+static reg_errcode_t
+calc_first (void *extra, bin_tree_t *node)
+{
+  re_dfa_t *dfa = (re_dfa_t *) extra;
+  if (node->token.type == CONCAT)
+    {
+      node->first = node->left->first;
+      node->node_idx = node->left->node_idx;
+    }
+  else
+    {
+      node->first = node;
+      node->node_idx = re_dfa_add_node (dfa, node->token);
+      if (BE (node->node_idx == REG_MISSING, 0))
+       return REG_ESPACE;
+      if (node->token.type == ANCHOR)
+       dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type;
+    }
+  return REG_NOERROR;
+}
+
+/* Pass 2: compute NEXT on the tree.  Preorder visit.  */
+static reg_errcode_t
+calc_next (void *extra, bin_tree_t *node)
+{
+  switch (node->token.type)
+    {
+    case OP_DUP_ASTERISK:
+      node->left->next = node;
+      break;
+    case CONCAT:
+      node->left->next = node->right->first;
+      node->right->next = node->next;
+      break;
+    default:
+      if (node->left)
+       node->left->next = node->next;
+      if (node->right)
+       node->right->next = node->next;
+      break;
+    }
+  return REG_NOERROR;
+}
+
+/* Pass 3: link all DFA nodes to their NEXT node (any order will do).  */
+static reg_errcode_t
+link_nfa_nodes (void *extra, bin_tree_t *node)
+{
+  re_dfa_t *dfa = (re_dfa_t *) extra;
+  Idx idx = node->node_idx;
+  reg_errcode_t err = REG_NOERROR;
+
+  switch (node->token.type)
+    {
+    case CONCAT:
+      break;
+
+    case END_OF_RE:
+      assert (node->next == NULL);
+      break;
+
+    case OP_DUP_ASTERISK:
+    case OP_ALT:
+      {
+       Idx left, right;
+       dfa->has_plural_match = 1;
+       if (node->left != NULL)
+         left = node->left->first->node_idx;
+       else
+         left = node->next->node_idx;
+       if (node->right != NULL)
+         right = node->right->first->node_idx;
+       else
+         right = node->next->node_idx;
+       assert (REG_VALID_INDEX (left));
+       assert (REG_VALID_INDEX (right));
+       err = re_node_set_init_2 (dfa->edests + idx, left, right);
+      }
+      break;
+
+    case ANCHOR:
+    case OP_OPEN_SUBEXP:
+    case OP_CLOSE_SUBEXP:
+      err = re_node_set_init_1 (dfa->edests + idx, node->next->node_idx);
+      break;
+
+    case OP_BACK_REF:
+      dfa->nexts[idx] = node->next->node_idx;
+      if (node->token.type == OP_BACK_REF)
+       err = re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]);
+      break;
+
+    default:
+      assert (!IS_EPSILON_NODE (node->token.type));
+      dfa->nexts[idx] = node->next->node_idx;
+      break;
+    }
+
+  return err;
+}
+
+/* Duplicate the epsilon closure of the node ROOT_NODE.
+   Note that duplicated nodes have constraint INIT_CONSTRAINT in addition
+   to their own constraint.  */
+
+static reg_errcode_t
+internal_function
+duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node,
+                       Idx root_node, unsigned int init_constraint)
+{
+  Idx org_node, clone_node;
+  bool ok;
+  unsigned int constraint = init_constraint;
+  for (org_node = top_org_node, clone_node = top_clone_node;;)
+    {
+      Idx org_dest, clone_dest;
+      if (dfa->nodes[org_node].type == OP_BACK_REF)
+       {
+         /* If the back reference epsilon-transit, its destination must
+            also have the constraint.  Then duplicate the epsilon closure
+            of the destination of the back reference, and store it in
+            edests of the back reference.  */
+         org_dest = dfa->nexts[org_node];
+         re_node_set_empty (dfa->edests + clone_node);
+         clone_dest = duplicate_node (dfa, org_dest, constraint);
+         if (BE (clone_dest == REG_MISSING, 0))
+           return REG_ESPACE;
+         dfa->nexts[clone_node] = dfa->nexts[org_node];
+         ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+         if (BE (! ok, 0))
+           return REG_ESPACE;
+       }
+      else if (dfa->edests[org_node].nelem == 0)
+       {
+         /* In case of the node can't epsilon-transit, don't duplicate the
+            destination and store the original destination as the
+            destination of the node.  */
+         dfa->nexts[clone_node] = dfa->nexts[org_node];
+         break;
+       }
+      else if (dfa->edests[org_node].nelem == 1)
+       {
+         /* In case of the node can epsilon-transit, and it has only one
+            destination.  */
+         org_dest = dfa->edests[org_node].elems[0];
+         re_node_set_empty (dfa->edests + clone_node);
+         /* If the node is root_node itself, it means the epsilon closure
+            has a loop.  Then tie it to the destination of the root_node.  */
+         if (org_node == root_node && clone_node != org_node)
+           {
+             ok = re_node_set_insert (dfa->edests + clone_node, org_dest);
+             if (BE (! ok, 0))
+               return REG_ESPACE;
+             break;
+           }
+         /* In case the node has another constraint, append it.  */
+         constraint |= dfa->nodes[org_node].constraint;
+         clone_dest = duplicate_node (dfa, org_dest, constraint);
+         if (BE (clone_dest == REG_MISSING, 0))
+           return REG_ESPACE;
+         ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+         if (BE (! ok, 0))
+           return REG_ESPACE;
+       }
+      else /* dfa->edests[org_node].nelem == 2 */
+       {
+         /* In case of the node can epsilon-transit, and it has two
+            destinations. In the bin_tree_t and DFA, that's '|' and '*'.   */
+         org_dest = dfa->edests[org_node].elems[0];
+         re_node_set_empty (dfa->edests + clone_node);
+         /* Search for a duplicated node which satisfies the constraint.  */
+         clone_dest = search_duplicated_node (dfa, org_dest, constraint);
+         if (clone_dest == REG_MISSING)
+           {
+             /* There is no such duplicated node, create a new one.  */
+             reg_errcode_t err;
+             clone_dest = duplicate_node (dfa, org_dest, constraint);
+             if (BE (clone_dest == REG_MISSING, 0))
+               return REG_ESPACE;
+             ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+             if (BE (! ok, 0))
+               return REG_ESPACE;
+             err = duplicate_node_closure (dfa, org_dest, clone_dest,
+                                           root_node, constraint);
+             if (BE (err != REG_NOERROR, 0))
+               return err;
+           }
+         else
+           {
+             /* There is a duplicated node which satisfies the constraint,
+                use it to avoid infinite loop.  */
+             ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+             if (BE (! ok, 0))
+               return REG_ESPACE;
+           }
+
+         org_dest = dfa->edests[org_node].elems[1];
+         clone_dest = duplicate_node (dfa, org_dest, constraint);
+         if (BE (clone_dest == REG_MISSING, 0))
+           return REG_ESPACE;
+         ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+         if (BE (! ok, 0))
+           return REG_ESPACE;
+       }
+      org_node = org_dest;
+      clone_node = clone_dest;
+    }
+  return REG_NOERROR;
+}
+
+/* Search for a node which is duplicated from the node ORG_NODE, and
+   satisfies the constraint CONSTRAINT.  */
+
+static Idx
+search_duplicated_node (const re_dfa_t *dfa, Idx org_node,
+                       unsigned int constraint)
+{
+  Idx idx;
+  for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx)
+    {
+      if (org_node == dfa->org_indices[idx]
+         && constraint == dfa->nodes[idx].constraint)
+       return idx; /* Found.  */
+    }
+  return REG_MISSING; /* Not found.  */
+}
+
+/* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT.
+   Return the index of the new node, or REG_MISSING if insufficient storage is
+   available.  */
+
+static Idx
+duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint)
+{
+  Idx dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]);
+  if (BE (dup_idx != REG_MISSING, 1))
+    {
+      dfa->nodes[dup_idx].constraint = constraint;
+      dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].constraint;
+      dfa->nodes[dup_idx].duplicated = 1;
+
+      /* Store the index of the original node.  */
+      dfa->org_indices[dup_idx] = org_idx;
+    }
+  return dup_idx;
+}
+
+static reg_errcode_t
+calc_inveclosure (re_dfa_t *dfa)
+{
+  Idx src, idx;
+  bool ok;
+  for (idx = 0; idx < dfa->nodes_len; ++idx)
+    re_node_set_init_empty (dfa->inveclosures + idx);
+
+  for (src = 0; src < dfa->nodes_len; ++src)
+    {
+      Idx *elems = dfa->eclosures[src].elems;
+      for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx)
+       {
+         ok = re_node_set_insert_last (dfa->inveclosures + elems[idx], src);
+         if (BE (! ok, 0))
+           return REG_ESPACE;
+       }
+    }
+
+  return REG_NOERROR;
+}
+
+/* Calculate "eclosure" for all the node in DFA.  */
+
+static reg_errcode_t
+calc_eclosure (re_dfa_t *dfa)
+{
+  Idx node_idx;
+  bool incomplete;
+#ifdef DEBUG
+  assert (dfa->nodes_len > 0);
+#endif
+  incomplete = false;
+  /* For each nodes, calculate epsilon closure.  */
+  for (node_idx = 0; ; ++node_idx)
+    {
+      reg_errcode_t err;
+      re_node_set eclosure_elem;
+      if (node_idx == dfa->nodes_len)
+       {
+         if (!incomplete)
+           break;
+         incomplete = false;
+         node_idx = 0;
+       }
+
+#ifdef DEBUG
+      assert (dfa->eclosures[node_idx].nelem != REG_MISSING);
+#endif
+
+      /* If we have already calculated, skip it.  */
+      if (dfa->eclosures[node_idx].nelem != 0)
+       continue;
+      /* Calculate epsilon closure of `node_idx'.  */
+      err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, true);
+      if (BE (err != REG_NOERROR, 0))
+       return err;
+
+      if (dfa->eclosures[node_idx].nelem == 0)
+       {
+         incomplete = true;
+         re_node_set_free (&eclosure_elem);
+       }
+    }
+  return REG_NOERROR;
+}
+
+/* Calculate epsilon closure of NODE.  */
+
+static reg_errcode_t
+calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
+{
+  reg_errcode_t err;
+  Idx i;
+  re_node_set eclosure;
+  bool ok;
+  bool incomplete = false;
+  err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+
+  /* This indicates that we are calculating this node now.
+     We reference this value to avoid infinite loop.  */
+  dfa->eclosures[node].nelem = REG_MISSING;
+
+  /* If the current node has constraints, duplicate all nodes
+     since they must inherit the constraints.  */
+  if (dfa->nodes[node].constraint
+      && dfa->edests[node].nelem
+      && !dfa->nodes[dfa->edests[node].elems[0]].duplicated)
+    {
+      err = duplicate_node_closure (dfa, node, node, node,
+                                   dfa->nodes[node].constraint);
+      if (BE (err != REG_NOERROR, 0))
+       return err;
+    }
+
+  /* Expand each epsilon destination nodes.  */
+  if (IS_EPSILON_NODE(dfa->nodes[node].type))
+    for (i = 0; i < dfa->edests[node].nelem; ++i)
+      {
+       re_node_set eclosure_elem;
+       Idx edest = dfa->edests[node].elems[i];
+       /* If calculating the epsilon closure of `edest' is in progress,
+          return intermediate result.  */
+       if (dfa->eclosures[edest].nelem == REG_MISSING)
+         {
+           incomplete = true;
+           continue;
+         }
+       /* If we haven't calculated the epsilon closure of `edest' yet,
+          calculate now. Otherwise use calculated epsilon closure.  */
+       if (dfa->eclosures[edest].nelem == 0)
+         {
+           err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false);
+           if (BE (err != REG_NOERROR, 0))
+             return err;
+         }
+       else
+         eclosure_elem = dfa->eclosures[edest];
+       /* Merge the epsilon closure of `edest'.  */
+       err = re_node_set_merge (&eclosure, &eclosure_elem);
+       if (BE (err != REG_NOERROR, 0))
+         return err;
+       /* If the epsilon closure of `edest' is incomplete,
+          the epsilon closure of this node is also incomplete.  */
+       if (dfa->eclosures[edest].nelem == 0)
+         {
+           incomplete = true;
+           re_node_set_free (&eclosure_elem);
+         }
+      }
+
+  /* An epsilon closure includes itself.  */
+  ok = re_node_set_insert (&eclosure, node);
+  if (BE (! ok, 0))
+    return REG_ESPACE;
+  if (incomplete && !root)
+    dfa->eclosures[node].nelem = 0;
+  else
+    dfa->eclosures[node] = eclosure;
+  *new_set = eclosure;
+  return REG_NOERROR;
+}
+\f
+/* Functions for token which are used in the parser.  */
+
+/* Fetch a token from INPUT.
+   We must not use this function inside bracket expressions.  */
+
+static void
+internal_function
+fetch_token (re_token_t *result, re_string_t *input, reg_syntax_t syntax)
+{
+  re_string_skip_bytes (input, peek_token (result, input, syntax));
+}
+
+/* Peek a token from INPUT, and return the length of the token.
+   We must not use this function inside bracket expressions.  */
+
+static int
+internal_function
+peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
+{
+  unsigned char c;
+
+  if (re_string_eoi (input))
+    {
+      token->type = END_OF_RE;
+      return 0;
+    }
+
+  c = re_string_peek_byte (input, 0);
+  token->opr.c = c;
+
+  token->word_char = 0;
+#ifdef RE_ENABLE_I18N
+  token->mb_partial = 0;
+  if (input->mb_cur_max > 1 &&
+      !re_string_first_byte (input, re_string_cur_idx (input)))
+    {
+      token->type = CHARACTER;
+      token->mb_partial = 1;
+      return 1;
+    }
+#endif
+  if (c == '\\')
+    {
+      unsigned char c2;
+      if (re_string_cur_idx (input) + 1 >= re_string_length (input))
+       {
+         token->type = BACK_SLASH;
+         return 1;
+       }
+
+      c2 = re_string_peek_byte_case (input, 1);
+      token->opr.c = c2;
+      token->type = CHARACTER;
+#ifdef RE_ENABLE_I18N
+      if (input->mb_cur_max > 1)
+       {
+         wint_t wc = re_string_wchar_at (input,
+                                         re_string_cur_idx (input) + 1);
+         token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
+       }
+      else
+#endif
+       token->word_char = IS_WORD_CHAR (c2) != 0;
+
+      switch (c2)
+       {
+       case '|':
+         if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_NO_BK_VBAR))
+           token->type = OP_ALT;
+         break;
+       case '1': case '2': case '3': case '4': case '5':
+       case '6': case '7': case '8': case '9':
+         if (!(syntax & RE_NO_BK_REFS))
+           {
+             token->type = OP_BACK_REF;
+             token->opr.idx = c2 - '1';
+           }
+         break;
+       case '<':
+         if (!(syntax & RE_NO_GNU_OPS))
+           {
+             token->type = ANCHOR;
+             token->opr.ctx_type = WORD_FIRST;
+           }
+         break;
+       case '>':
+         if (!(syntax & RE_NO_GNU_OPS))
+           {
+             token->type = ANCHOR;
+             token->opr.ctx_type = WORD_LAST;
+           }
+         break;
+       case 'b':
+         if (!(syntax & RE_NO_GNU_OPS))
+           {
+             token->type = ANCHOR;
+             token->opr.ctx_type = WORD_DELIM;
+           }
+         break;
+       case 'B':
+         if (!(syntax & RE_NO_GNU_OPS))
+           {
+             token->type = ANCHOR;
+             token->opr.ctx_type = NOT_WORD_DELIM;
+           }
+         break;
+       case 'w':
+         if (!(syntax & RE_NO_GNU_OPS))
+           token->type = OP_WORD;
+         break;
+       case 'W':
+         if (!(syntax & RE_NO_GNU_OPS))
+           token->type = OP_NOTWORD;
+         break;
+       case 's':
+         if (!(syntax & RE_NO_GNU_OPS))
+           token->type = OP_SPACE;
+         break;
+       case 'S':
+         if (!(syntax & RE_NO_GNU_OPS))
+           token->type = OP_NOTSPACE;
+         break;
+       case '`':
+         if (!(syntax & RE_NO_GNU_OPS))
+           {
+             token->type = ANCHOR;
+             token->opr.ctx_type = BUF_FIRST;
+           }
+         break;
+       case '\'':
+         if (!(syntax & RE_NO_GNU_OPS))
+           {
+             token->type = ANCHOR;
+             token->opr.ctx_type = BUF_LAST;
+           }
+         break;
+       case '(':
+         if (!(syntax & RE_NO_BK_PARENS))
+           token->type = OP_OPEN_SUBEXP;
+         break;
+       case ')':
+         if (!(syntax & RE_NO_BK_PARENS))
+           token->type = OP_CLOSE_SUBEXP;
+         break;
+       case '+':
+         if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))
+           token->type = OP_DUP_PLUS;
+         break;
+       case '?':
+         if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))
+           token->type = OP_DUP_QUESTION;
+         break;
+       case '{':
+         if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))
+           token->type = OP_OPEN_DUP_NUM;
+         break;
+       case '}':
+         if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))
+           token->type = OP_CLOSE_DUP_NUM;
+         break;
+       default:
+         break;
+       }
+      return 2;
+    }
+
+  token->type = CHARACTER;
+#ifdef RE_ENABLE_I18N
+  if (input->mb_cur_max > 1)
+    {
+      wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input));
+      token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
+    }
+  else
+#endif
+    token->word_char = IS_WORD_CHAR (token->opr.c);
+
+  switch (c)
+    {
+    case '\n':
+      if (syntax & RE_NEWLINE_ALT)
+       token->type = OP_ALT;
+      break;
+    case '|':
+      if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_NO_BK_VBAR))
+       token->type = OP_ALT;
+      break;
+    case '*':
+      token->type = OP_DUP_ASTERISK;
+      break;
+    case '+':
+      if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))
+       token->type = OP_DUP_PLUS;
+      break;
+    case '?':
+      if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))
+       token->type = OP_DUP_QUESTION;
+      break;
+    case '{':
+      if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+       token->type = OP_OPEN_DUP_NUM;
+      break;
+    case '}':
+      if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+       token->type = OP_CLOSE_DUP_NUM;
+      break;
+    case '(':
+      if (syntax & RE_NO_BK_PARENS)
+       token->type = OP_OPEN_SUBEXP;
+      break;
+    case ')':
+      if (syntax & RE_NO_BK_PARENS)
+       token->type = OP_CLOSE_SUBEXP;
+      break;
+    case '[':
+      token->type = OP_OPEN_BRACKET;
+      break;
+    case '.':
+      token->type = OP_PERIOD;
+      break;
+    case '^':
+      if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE)) &&
+         re_string_cur_idx (input) != 0)
+       {
+         char prev = re_string_peek_byte (input, -1);
+         if (!(syntax & RE_NEWLINE_ALT) || prev != '\n')
+           break;
+       }
+      token->type = ANCHOR;
+      token->opr.ctx_type = LINE_FIRST;
+      break;
+    case '$':
+      if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) &&
+         re_string_cur_idx (input) + 1 != re_string_length (input))
+       {
+         re_token_t next;
+         re_string_skip_bytes (input, 1);
+         peek_token (&next, input, syntax);
+         re_string_skip_bytes (input, -1);
+         if (next.type != OP_ALT && next.type != OP_CLOSE_SUBEXP)
+           break;
+       }
+      token->type = ANCHOR;
+      token->opr.ctx_type = LINE_LAST;
+      break;
+    default:
+      break;
+    }
+  return 1;
+}
+
+/* Peek a token from INPUT, and return the length of the token.
+   We must not use this function out of bracket expressions.  */
+
+static int
+internal_function
+peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
+{
+  unsigned char c;
+  if (re_string_eoi (input))
+    {
+      token->type = END_OF_RE;
+      return 0;
+    }
+  c = re_string_peek_byte (input, 0);
+  token->opr.c = c;
+
+#ifdef RE_ENABLE_I18N
+  if (input->mb_cur_max > 1 &&
+      !re_string_first_byte (input, re_string_cur_idx (input)))
+    {
+      token->type = CHARACTER;
+      return 1;
+    }
+#endif /* RE_ENABLE_I18N */
+
+  if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS)
+      && re_string_cur_idx (input) + 1 < re_string_length (input))
+    {
+      /* In this case, '\' escape a character.  */
+      unsigned char c2;
+      re_string_skip_bytes (input, 1);
+      c2 = re_string_peek_byte (input, 0);
+      token->opr.c = c2;
+      token->type = CHARACTER;
+      return 1;
+    }
+  if (c == '[') /* '[' is a special char in a bracket exps.  */
+    {
+      unsigned char c2;
+      int token_len;
+      if (re_string_cur_idx (input) + 1 < re_string_length (input))
+       c2 = re_string_peek_byte (input, 1);
+      else
+       c2 = 0;
+      token->opr.c = c2;
+      token_len = 2;
+      switch (c2)
+       {
+       case '.':
+         token->type = OP_OPEN_COLL_ELEM;
+         break;
+       case '=':
+         token->type = OP_OPEN_EQUIV_CLASS;
+         break;
+       case ':':
+         if (syntax & RE_CHAR_CLASSES)
+           {
+             token->type = OP_OPEN_CHAR_CLASS;
+             break;
+           }
+         /* else fall through.  */
+       default:
+         token->type = CHARACTER;
+         token->opr.c = c;
+         token_len = 1;
+         break;
+       }
+      return token_len;
+    }
+  switch (c)
+    {
+    case '-':
+      token->type = OP_CHARSET_RANGE;
+      break;
+    case ']':
+      token->type = OP_CLOSE_BRACKET;
+      break;
+    case '^':
+      token->type = OP_NON_MATCH_LIST;
+      break;
+    default:
+      token->type = CHARACTER;
+    }
+  return 1;
+}
+\f
+/* Functions for parser.  */
+
+/* Entry point of the parser.
+   Parse the regular expression REGEXP and return the structure tree.
+   If an error is occured, ERR is set by error code, and return NULL.
+   This function build the following tree, from regular expression <reg_exp>:
+          CAT
+          / \
+         /   \
+   <reg_exp>  EOR
+
+   CAT means concatenation.
+   EOR means end of regular expression.  */
+
+static bin_tree_t *
+parse (re_string_t *regexp, regex_t *preg, reg_syntax_t syntax,
+       reg_errcode_t *err)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_t *tree, *eor, *root;
+  re_token_t current_token;
+  dfa->syntax = syntax;
+  fetch_token (&current_token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+  tree = parse_reg_exp (regexp, preg, &current_token, syntax, 0, err);
+  if (BE (*err != REG_NOERROR && tree == NULL, 0))
+    return NULL;
+  eor = create_tree (dfa, NULL, NULL, END_OF_RE);
+  if (tree != NULL)
+    root = create_tree (dfa, tree, eor, CONCAT);
+  else
+    root = eor;
+  if (BE (eor == NULL || root == NULL, 0))
+    {
+      *err = REG_ESPACE;
+      return NULL;
+    }
+  return root;
+}
+
+/* This function build the following tree, from regular expression
+   <branch1>|<branch2>:
+          ALT
+          / \
+         /   \
+   <branch1> <branch2>
+
+   ALT means alternative, which represents the operator `|'.  */
+
+static bin_tree_t *
+parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
+              reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_t *tree, *branch = NULL;
+  tree = parse_branch (regexp, preg, token, syntax, nest, err);
+  if (BE (*err != REG_NOERROR && tree == NULL, 0))
+    return NULL;
+
+  while (token->type == OP_ALT)
+    {
+      fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+      if (token->type != OP_ALT && token->type != END_OF_RE
+         && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
+       {
+         branch = parse_branch (regexp, preg, token, syntax, nest, err);
+         if (BE (*err != REG_NOERROR && branch == NULL, 0))
+           return NULL;
+       }
+      else
+       branch = NULL;
+      tree = create_tree (dfa, tree, branch, OP_ALT);
+      if (BE (tree == NULL, 0))
+       {
+         *err = REG_ESPACE;
+         return NULL;
+       }
+    }
+  return tree;
+}
+
+/* This function build the following tree, from regular expression
+   <exp1><exp2>:
+       CAT
+       / \
+       /   \
+   <exp1> <exp2>
+
+   CAT means concatenation.  */
+
+static bin_tree_t *
+parse_branch (re_string_t *regexp, regex_t *preg, re_token_t *token,
+             reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
+{
+  bin_tree_t *tree, *expr;
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  tree = parse_expression (regexp, preg, token, syntax, nest, err);
+  if (BE (*err != REG_NOERROR && tree == NULL, 0))
+    return NULL;
+
+  while (token->type != OP_ALT && token->type != END_OF_RE
+        && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
+    {
+      expr = parse_expression (regexp, preg, token, syntax, nest, err);
+      if (BE (*err != REG_NOERROR && expr == NULL, 0))
+       {
+         return NULL;
+       }
+      if (tree != NULL && expr != NULL)
+       {
+         tree = create_tree (dfa, tree, expr, CONCAT);
+         if (tree == NULL)
+           {
+             *err = REG_ESPACE;
+             return NULL;
+           }
+       }
+      else if (tree == NULL)
+       tree = expr;
+      /* Otherwise expr == NULL, we don't need to create new tree.  */
+    }
+  return tree;
+}
+
+/* This function build the following tree, from regular expression a*:
+        *
+        |
+        a
+*/
+
+static bin_tree_t *
+parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
+                 reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_t *tree;
+  switch (token->type)
+    {
+    case CHARACTER:
+      tree = create_token_tree (dfa, NULL, NULL, token);
+      if (BE (tree == NULL, 0))
+       {
+         *err = REG_ESPACE;
+         return NULL;
+       }
+#ifdef RE_ENABLE_I18N
+      if (dfa->mb_cur_max > 1)
+       {
+         while (!re_string_eoi (regexp)
+                && !re_string_first_byte (regexp, re_string_cur_idx (regexp)))
+           {
+             bin_tree_t *mbc_remain;
+             fetch_token (token, regexp, syntax);
+             mbc_remain = create_token_tree (dfa, NULL, NULL, token);
+             tree = create_tree (dfa, tree, mbc_remain, CONCAT);
+             if (BE (mbc_remain == NULL || tree == NULL, 0))
+               {
+                 *err = REG_ESPACE;
+                 return NULL;
+               }
+           }
+       }
+#endif
+      break;
+    case OP_OPEN_SUBEXP:
+      tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err);
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+       return NULL;
+      break;
+    case OP_OPEN_BRACKET:
+      tree = parse_bracket_exp (regexp, dfa, token, syntax, err);
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+       return NULL;
+      break;
+    case OP_BACK_REF:
+      if (!BE (dfa->completed_bkref_map & (1 << token->opr.idx), 1))
+       {
+         *err = REG_ESUBREG;
+         return NULL;
+       }
+      dfa->used_bkref_map |= 1 << token->opr.idx;
+      tree = create_token_tree (dfa, NULL, NULL, token);
+      if (BE (tree == NULL, 0))
+       {
+         *err = REG_ESPACE;
+         return NULL;
+       }
+      ++dfa->nbackref;
+      dfa->has_mb_node = 1;
+      break;
+    case OP_OPEN_DUP_NUM:
+      if (syntax & RE_CONTEXT_INVALID_DUP)
+       {
+         *err = REG_BADRPT;
+         return NULL;
+       }
+      /* FALLTHROUGH */
+    case OP_DUP_ASTERISK:
+    case OP_DUP_PLUS:
+    case OP_DUP_QUESTION:
+      if (syntax & RE_CONTEXT_INVALID_OPS)
+       {
+         *err = REG_BADRPT;
+         return NULL;
+       }
+      else if (syntax & RE_CONTEXT_INDEP_OPS)
+       {
+         fetch_token (token, regexp, syntax);
+         return parse_expression (regexp, preg, token, syntax, nest, err);
+       }
+      /* else fall through  */
+    case OP_CLOSE_SUBEXP:
+      if ((token->type == OP_CLOSE_SUBEXP) &&
+         !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD))
+       {
+         *err = REG_ERPAREN;
+         return NULL;
+       }
+      /* else fall through  */
+    case OP_CLOSE_DUP_NUM:
+      /* We treat it as a normal character.  */
+
+      /* Then we can these characters as normal characters.  */
+      token->type = CHARACTER;
+      /* mb_partial and word_char bits should be initialized already
+        by peek_token.  */
+      tree = create_token_tree (dfa, NULL, NULL, token);
+      if (BE (tree == NULL, 0))
+       {
+         *err = REG_ESPACE;
+         return NULL;
+       }
+      break;
+    case ANCHOR:
+      if ((token->opr.ctx_type
+          & (WORD_DELIM | NOT_WORD_DELIM | WORD_FIRST | WORD_LAST))
+         && dfa->word_ops_used == 0)
+       init_word_char (dfa);
+      if (token->opr.ctx_type == WORD_DELIM
+         || token->opr.ctx_type == NOT_WORD_DELIM)
+       {
+         bin_tree_t *tree_first, *tree_last;
+         if (token->opr.ctx_type == WORD_DELIM)
+           {
+             token->opr.ctx_type = WORD_FIRST;
+             tree_first = create_token_tree (dfa, NULL, NULL, token);
+             token->opr.ctx_type = WORD_LAST;
+           }
+         else
+           {
+             token->opr.ctx_type = INSIDE_WORD;
+             tree_first = create_token_tree (dfa, NULL, NULL, token);
+             token->opr.ctx_type = INSIDE_NOTWORD;
+           }
+         tree_last = create_token_tree (dfa, NULL, NULL, token);
+         tree = create_tree (dfa, tree_first, tree_last, OP_ALT);
+         if (BE (tree_first == NULL || tree_last == NULL || tree == NULL, 0))
+           {
+             *err = REG_ESPACE;
+             return NULL;
+           }
+       }
+      else
+       {
+         tree = create_token_tree (dfa, NULL, NULL, token);
+         if (BE (tree == NULL, 0))
+           {
+             *err = REG_ESPACE;
+             return NULL;
+           }
+       }
+      /* We must return here, since ANCHORs can't be followed
+        by repetition operators.
+        eg. RE"^*" is invalid or "<ANCHOR(^)><CHAR(*)>",
+            it must not be "<ANCHOR(^)><REPEAT(*)>".  */
+      fetch_token (token, regexp, syntax);
+      return tree;
+    case OP_PERIOD:
+      tree = create_token_tree (dfa, NULL, NULL, token);
+      if (BE (tree == NULL, 0))
+       {
+         *err = REG_ESPACE;
+         return NULL;
+       }
+      if (dfa->mb_cur_max > 1)
+       dfa->has_mb_node = 1;
+      break;
+    case OP_WORD:
+    case OP_NOTWORD:
+      tree = build_charclass_op (dfa, regexp->trans,
+                                (const unsigned char *) "alnum",
+                                (const unsigned char *) "_",
+                                token->type == OP_NOTWORD, err);
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+       return NULL;
+      break;
+    case OP_SPACE:
+    case OP_NOTSPACE:
+      tree = build_charclass_op (dfa, regexp->trans,
+                                (const unsigned char *) "space",
+                                (const unsigned char *) "",
+                                token->type == OP_NOTSPACE, err);
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+       return NULL;
+      break;
+    case OP_ALT:
+    case END_OF_RE:
+      return NULL;
+    case BACK_SLASH:
+      *err = REG_EESCAPE;
+      return NULL;
+    default:
+      /* Must not happen?  */
+#ifdef DEBUG
+      assert (0);
+#endif
+      return NULL;
+    }
+  fetch_token (token, regexp, syntax);
+
+  while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS
+        || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)
+    {
+      tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+       return NULL;
+      /* In BRE consecutive duplications are not allowed.  */
+      if ((syntax & RE_CONTEXT_INVALID_DUP)
+         && (token->type == OP_DUP_ASTERISK
+             || token->type == OP_OPEN_DUP_NUM))
+       {
+         *err = REG_BADRPT;
+         return NULL;
+       }
+    }
+
+  return tree;
+}
+
+/* This function build the following tree, from regular expression
+   (<reg_exp>):
+        SUBEXP
+           |
+       <reg_exp>
+*/
+
+static bin_tree_t *
+parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
+              reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_t *tree;
+  size_t cur_nsub;
+  cur_nsub = preg->re_nsub++;
+
+  fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+
+  /* The subexpression may be a null string.  */
+  if (token->type == OP_CLOSE_SUBEXP)
+    tree = NULL;
+  else
+    {
+      tree = parse_reg_exp (regexp, preg, token, syntax, nest, err);
+      if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0))
+       *err = REG_EPAREN;
+      if (BE (*err != REG_NOERROR, 0))
+       return NULL;
+    }
+
+  if (cur_nsub <= '9' - '1')
+    dfa->completed_bkref_map |= 1 << cur_nsub;
+
+  tree = create_tree (dfa, tree, NULL, SUBEXP);
+  if (BE (tree == NULL, 0))
+    {
+      *err = REG_ESPACE;
+      return NULL;
+    }
+  tree->token.opr.idx = cur_nsub;
+  return tree;
+}
+
+/* This function parse repetition operators like "*", "+", "{1,3}" etc.  */
+
+static bin_tree_t *
+parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
+             re_token_t *token, reg_syntax_t syntax, reg_errcode_t *err)
+{
+  bin_tree_t *tree = NULL, *old_tree = NULL;
+  Idx i, start, end, start_idx = re_string_cur_idx (regexp);
+  re_token_t start_token = *token;
+
+  if (token->type == OP_OPEN_DUP_NUM)
+    {
+      end = 0;
+      start = fetch_number (regexp, token, syntax);
+      if (start == REG_MISSING)
+       {
+         if (token->type == CHARACTER && token->opr.c == ',')
+           start = 0; /* We treat "{,m}" as "{0,m}".  */
+         else
+           {
+             *err = REG_BADBR; /* <re>{} is invalid.  */
+             return NULL;
+           }
+       }
+      if (BE (start != REG_ERROR, 1))
+       {
+         /* We treat "{n}" as "{n,n}".  */
+         end = ((token->type == OP_CLOSE_DUP_NUM) ? start
+                : ((token->type == CHARACTER && token->opr.c == ',')
+                   ? fetch_number (regexp, token, syntax) : REG_ERROR));
+       }
+      if (BE (start == REG_ERROR || end == REG_ERROR, 0))
+       {
+         /* Invalid sequence.  */
+         if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0))
+           {
+             if (token->type == END_OF_RE)
+               *err = REG_EBRACE;
+             else
+               *err = REG_BADBR;
+
+             return NULL;
+           }
+
+         /* If the syntax bit is set, rollback.  */
+         re_string_set_index (regexp, start_idx);
+         *token = start_token;
+         token->type = CHARACTER;
+         /* mb_partial and word_char bits should be already initialized by
+            peek_token.  */
+         return elem;
+       }
+
+      if (BE ((end != REG_MISSING && start > end)
+             || token->type != OP_CLOSE_DUP_NUM, 0))
+       {
+         /* First number greater than second.  */
+         *err = REG_BADBR;
+         return NULL;
+       }
+    }
+  else
+    {
+      start = (token->type == OP_DUP_PLUS) ? 1 : 0;
+      end = (token->type == OP_DUP_QUESTION) ? 1 : REG_MISSING;
+    }
+
+  fetch_token (token, regexp, syntax);
+
+  if (BE (elem == NULL, 0))
+    return NULL;
+  if (BE (start == 0 && end == 0, 0))
+    {
+      postorder (elem, free_tree, NULL);
+      return NULL;
+    }
+
+  /* Extract "<re>{n,m}" to "<re><re>...<re><re>{0,<m-n>}".  */
+  if (BE (start > 0, 0))
+    {
+      tree = elem;
+      for (i = 2; i <= start; ++i)
+       {
+         elem = duplicate_tree (elem, dfa);
+         tree = create_tree (dfa, tree, elem, CONCAT);
+         if (BE (elem == NULL || tree == NULL, 0))
+           goto parse_dup_op_espace;
+       }
+
+      if (start == end)
+       return tree;
+
+      /* Duplicate ELEM before it is marked optional.  */
+      elem = duplicate_tree (elem, dfa);
+      old_tree = tree;
+    }
+  else
+    old_tree = NULL;
+
+  if (elem->token.type == SUBEXP)
+    postorder (elem, mark_opt_subexp, (void *) (long) elem->token.opr.idx);
+
+  tree = create_tree (dfa, elem, NULL,
+                     (end == REG_MISSING ? OP_DUP_ASTERISK : OP_ALT));
+  if (BE (tree == NULL, 0))
+    goto parse_dup_op_espace;
+
+/* From gnulib's "intprops.h":
+   True if the arithmetic type T is signed.  */
+#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+
+  /* This loop is actually executed only when end != REG_MISSING,
+     to rewrite <re>{0,n} as (<re>(<re>...<re>?)?)?...  We have
+     already created the start+1-th copy.  */
+  if (TYPE_SIGNED (Idx) || end != REG_MISSING)
+    for (i = start + 2; i <= end; ++i)
+      {
+       elem = duplicate_tree (elem, dfa);
+       tree = create_tree (dfa, tree, elem, CONCAT);
+       if (BE (elem == NULL || tree == NULL, 0))
+         goto parse_dup_op_espace;
+
+       tree = create_tree (dfa, tree, NULL, OP_ALT);
+       if (BE (tree == NULL, 0))
+         goto parse_dup_op_espace;
+      }
+
+  if (old_tree)
+    tree = create_tree (dfa, old_tree, tree, CONCAT);
+
+  return tree;
+
+ parse_dup_op_espace:
+  *err = REG_ESPACE;
+  return NULL;
+}
+
+/* Size of the names for collating symbol/equivalence_class/character_class.
+   I'm not sure, but maybe enough.  */
+#define BRACKET_NAME_BUF_SIZE 32
+
+#ifndef _LIBC
+  /* Local function for parse_bracket_exp only used in case of NOT _LIBC.
+     Build the range expression which starts from START_ELEM, and ends
+     at END_ELEM.  The result are written to MBCSET and SBCSET.
+     RANGE_ALLOC is the allocated size of mbcset->range_starts, and
+     mbcset->range_ends, is a pointer argument sinse we may
+     update it.  */
+
+static reg_errcode_t
+internal_function
+# ifdef RE_ENABLE_I18N
+build_range_exp (const reg_syntax_t syntax,
+                 bitset_t sbcset,
+                 re_charset_t *mbcset,
+                 Idx *range_alloc,
+                 const bracket_elem_t *start_elem,
+                 const bracket_elem_t *end_elem)
+# else /* not RE_ENABLE_I18N */
+build_range_exp (const reg_syntax_t syntax,
+                 bitset_t sbcset,
+                 const bracket_elem_t *start_elem,
+                 const bracket_elem_t *end_elem)
+# endif /* not RE_ENABLE_I18N */
+{
+  unsigned int start_ch, end_ch;
+  /* Equivalence Classes and Character Classes can't be a range start/end.  */
+  if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
+         || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
+         0))
+    return REG_ERANGE;
+
+  /* We can handle no multi character collating elements without libc
+     support.  */
+  if (BE ((start_elem->type == COLL_SYM
+          && strlen ((char *) start_elem->opr.name) > 1)
+         || (end_elem->type == COLL_SYM
+             && strlen ((char *) end_elem->opr.name) > 1), 0))
+    return REG_ECOLLATE;
+
+# ifdef RE_ENABLE_I18N
+  {
+    wchar_t wc;
+    wint_t start_wc;
+    wint_t end_wc;
+    wchar_t cmp_buf[6] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'};
+
+    start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch
+               : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
+                  : 0));
+    end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch
+             : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
+                : 0));
+    start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM)
+               ? __btowc (start_ch) : start_elem->opr.wch);
+    end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM)
+             ? __btowc (end_ch) : end_elem->opr.wch);
+    if (start_wc == WEOF || end_wc == WEOF)
+      return REG_ECOLLATE;
+    cmp_buf[0] = start_wc;
+    cmp_buf[4] = end_wc;
+
+    if (BE ((syntax & RE_NO_EMPTY_RANGES)
+            && wcscoll (cmp_buf, cmp_buf + 4) > 0, 0))
+      return REG_ERANGE;
+
+    /* Got valid collation sequence values, add them as a new entry.
+       However, for !_LIBC we have no collation elements: if the
+       character set is single byte, the single byte character set
+       that we build below suffices.  parse_bracket_exp passes
+       no MBCSET if dfa->mb_cur_max == 1.  */
+    if (mbcset)
+      {
+       /* Check the space of the arrays.  */
+       if (BE (*range_alloc == mbcset->nranges, 0))
+         {
+           /* There is not enough space, need realloc.  */
+           wchar_t *new_array_start, *new_array_end;
+           Idx new_nranges;
+
+           /* +1 in case of mbcset->nranges is 0.  */
+           new_nranges = 2 * mbcset->nranges + 1;
+           /* Use realloc since mbcset->range_starts and mbcset->range_ends
+              are NULL if *range_alloc == 0.  */
+           new_array_start = re_realloc (mbcset->range_starts, wchar_t,
+                                         new_nranges);
+           new_array_end = re_realloc (mbcset->range_ends, wchar_t,
+                                       new_nranges);
+
+           if (BE (new_array_start == NULL || new_array_end == NULL, 0))
+             return REG_ESPACE;
+
+           mbcset->range_starts = new_array_start;
+           mbcset->range_ends = new_array_end;
+           *range_alloc = new_nranges;
+         }
+
+       mbcset->range_starts[mbcset->nranges] = start_wc;
+       mbcset->range_ends[mbcset->nranges++] = end_wc;
+      }
+
+    /* Build the table for single byte characters.  */
+    for (wc = 0; wc < SBC_MAX; ++wc)
+      {
+       cmp_buf[2] = wc;
+       if (wcscoll (cmp_buf, cmp_buf + 2) <= 0
+           && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0)
+         bitset_set (sbcset, wc);
+      }
+  }
+# else /* not RE_ENABLE_I18N */
+  {
+    unsigned int ch;
+    start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch
+               : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
+                  : 0));
+    end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch
+             : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
+                : 0));
+    if (start_ch > end_ch)
+      return REG_ERANGE;
+    /* Build the table for single byte characters.  */
+    for (ch = 0; ch < SBC_MAX; ++ch)
+      if (start_ch <= ch  && ch <= end_ch)
+       bitset_set (sbcset, ch);
+  }
+# endif /* not RE_ENABLE_I18N */
+  return REG_NOERROR;
+}
+#endif /* not _LIBC */
+
+#ifndef _LIBC
+/* Helper function for parse_bracket_exp only used in case of NOT _LIBC..
+   Build the collating element which is represented by NAME.
+   The result are written to MBCSET and SBCSET.
+   COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
+   pointer argument since we may update it.  */
+
+static reg_errcode_t
+internal_function
+build_collating_symbol (bitset_t sbcset,
+# ifdef RE_ENABLE_I18N
+                       re_charset_t *mbcset, Idx *coll_sym_alloc,
+# endif
+                       const unsigned char *name)
+{
+  size_t name_len = strlen ((const char *) name);
+  if (BE (name_len != 1, 0))
+    return REG_ECOLLATE;
+  else
+    {
+      bitset_set (sbcset, name[0]);
+      return REG_NOERROR;
+    }
+}
+#endif /* not _LIBC */
+
+/* This function parse bracket expression like "[abc]", "[a-c]",
+   "[[.a-a.]]" etc.  */
+
+static bin_tree_t *
+parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+                  reg_syntax_t syntax, reg_errcode_t *err)
+{
+#ifdef _LIBC
+  const unsigned char *collseqmb;
+  const char *collseqwc;
+  uint32_t nrules;
+  int32_t table_size;
+  const int32_t *symb_table;
+  const unsigned char *extra;
+
+  /* Local function for parse_bracket_exp used in _LIBC environement.
+     Seek the collating symbol entry correspondings to NAME.
+     Return the index of the symbol in the SYMB_TABLE.  */
+
+  auto inline int32_t
+  __attribute ((always_inline))
+  seek_collating_symbol_entry (name, name_len)
+        const unsigned char *name;
+        size_t name_len;
+    {
+      int32_t hash = elem_hash ((const char *) name, name_len);
+      int32_t elem = hash % table_size;
+      if (symb_table[2 * elem] != 0)
+       {
+         int32_t second = hash % (table_size - 2) + 1;
+
+         do
+           {
+             /* First compare the hashing value.  */
+             if (symb_table[2 * elem] == hash
+                 /* Compare the length of the name.  */
+                 && name_len == extra[symb_table[2 * elem + 1]]
+                 /* Compare the name.  */
+                 && memcmp (name, &extra[symb_table[2 * elem + 1] + 1],
+                            name_len) == 0)
+               {
+                 /* Yep, this is the entry.  */
+                 break;
+               }
+
+             /* Next entry.  */
+             elem += second;
+           }
+         while (symb_table[2 * elem] != 0);
+       }
+      return elem;
+    }
+
+  /* Local function for parse_bracket_exp used in _LIBC environment.
+     Look up the collation sequence value of BR_ELEM.
+     Return the value if succeeded, UINT_MAX otherwise.  */
+
+  auto inline unsigned int
+  __attribute ((always_inline))
+  lookup_collation_sequence_value (br_elem)
+        bracket_elem_t *br_elem;
+    {
+      if (br_elem->type == SB_CHAR)
+       {
+         /*
+         if (MB_CUR_MAX == 1)
+         */
+         if (nrules == 0)
+           return collseqmb[br_elem->opr.ch];
+         else
+           {
+             wint_t wc = __btowc (br_elem->opr.ch);
+             return __collseq_table_lookup (collseqwc, wc);
+           }
+       }
+      else if (br_elem->type == MB_CHAR)
+       {
+         if (nrules != 0)
+           return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
+       }
+      else if (br_elem->type == COLL_SYM)
+       {
+         size_t sym_name_len = strlen ((char *) br_elem->opr.name);
+         if (nrules != 0)
+           {
+             int32_t elem, idx;
+             elem = seek_collating_symbol_entry (br_elem->opr.name,
+                                                 sym_name_len);
+             if (symb_table[2 * elem] != 0)
+               {
+                 /* We found the entry.  */
+                 idx = symb_table[2 * elem + 1];
+                 /* Skip the name of collating element name.  */
+                 idx += 1 + extra[idx];
+                 /* Skip the byte sequence of the collating element.  */
+                 idx += 1 + extra[idx];
+                 /* Adjust for the alignment.  */
+                 idx = (idx + 3) & ~3;
+                 /* Skip the multibyte collation sequence value.  */
+                 idx += sizeof (unsigned int);
+                 /* Skip the wide char sequence of the collating element.  */
+                 idx += sizeof (unsigned int) *
+                   (1 + *(unsigned int *) (extra + idx));
+                 /* Return the collation sequence value.  */
+                 return *(unsigned int *) (extra + idx);
+               }
+             else if (symb_table[2 * elem] == 0 && sym_name_len == 1)
+               {
+                 /* No valid character.  Match it as a single byte
+                    character.  */
+                 return collseqmb[br_elem->opr.name[0]];
+               }
+           }
+         else if (sym_name_len == 1)
+           return collseqmb[br_elem->opr.name[0]];
+       }
+      return UINT_MAX;
+    }
+
+  /* Local function for parse_bracket_exp used in _LIBC environement.
+     Build the range expression which starts from START_ELEM, and ends
+     at END_ELEM.  The result are written to MBCSET and SBCSET.
+     RANGE_ALLOC is the allocated size of mbcset->range_starts, and
+     mbcset->range_ends, is a pointer argument sinse we may
+     update it.  */
+
+  auto inline reg_errcode_t
+  __attribute ((always_inline))
+  build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem)
+        re_charset_t *mbcset;
+        Idx *range_alloc;
+        bitset_t sbcset;
+        bracket_elem_t *start_elem, *end_elem;
+    {
+      unsigned int ch;
+      uint32_t start_collseq;
+      uint32_t end_collseq;
+
+      /* Equivalence Classes and Character Classes can't be a range
+        start/end.  */
+      if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
+             || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
+             0))
+       return REG_ERANGE;
+
+      start_collseq = lookup_collation_sequence_value (start_elem);
+      end_collseq = lookup_collation_sequence_value (end_elem);
+      /* Check start/end collation sequence values.  */
+      if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0))
+       return REG_ECOLLATE;
+      if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0))
+       return REG_ERANGE;
+
+      /* Got valid collation sequence values, add them as a new entry.
+        However, if we have no collation elements, and the character set
+        is single byte, the single byte character set that we
+        build below suffices. */
+      if (nrules > 0 || dfa->mb_cur_max > 1)
+       {
+         /* Check the space of the arrays.  */
+         if (BE (*range_alloc == mbcset->nranges, 0))
+           {
+             /* There is not enough space, need realloc.  */
+             uint32_t *new_array_start;
+             uint32_t *new_array_end;
+             Idx new_nranges;
+
+             /* +1 in case of mbcset->nranges is 0.  */
+             new_nranges = 2 * mbcset->nranges + 1;
+             new_array_start = re_realloc (mbcset->range_starts, uint32_t,
+                                           new_nranges);
+             new_array_end = re_realloc (mbcset->range_ends, uint32_t,
+                                         new_nranges);
+
+             if (BE (new_array_start == NULL || new_array_end == NULL, 0))
+               return REG_ESPACE;
+
+             mbcset->range_starts = new_array_start;
+             mbcset->range_ends = new_array_end;
+             *range_alloc = new_nranges;
+           }
+
+         mbcset->range_starts[mbcset->nranges] = start_collseq;
+         mbcset->range_ends[mbcset->nranges++] = end_collseq;
+       }
+
+      /* Build the table for single byte characters.  */
+      for (ch = 0; ch < SBC_MAX; ch++)
+       {
+         uint32_t ch_collseq;
+         /*
+         if (MB_CUR_MAX == 1)
+         */
+         if (nrules == 0)
+           ch_collseq = collseqmb[ch];
+         else
+           ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch));
+         if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)
+           bitset_set (sbcset, ch);
+       }
+      return REG_NOERROR;
+    }
+
+  /* Local function for parse_bracket_exp used in _LIBC environement.
+     Build the collating element which is represented by NAME.
+     The result are written to MBCSET and SBCSET.
+     COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
+     pointer argument sinse we may update it.  */
+
+  auto inline reg_errcode_t
+  __attribute ((always_inline))
+  build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name)
+        re_charset_t *mbcset;
+        Idx *coll_sym_alloc;
+        bitset_t sbcset;
+        const unsigned char *name;
+    {
+      int32_t elem, idx;
+      size_t name_len = strlen ((const char *) name);
+      if (nrules != 0)
+       {
+         elem = seek_collating_symbol_entry (name, name_len);
+         if (symb_table[2 * elem] != 0)
+           {
+             /* We found the entry.  */
+             idx = symb_table[2 * elem + 1];
+             /* Skip the name of collating element name.  */
+             idx += 1 + extra[idx];
+           }
+         else if (symb_table[2 * elem] == 0 && name_len == 1)
+           {
+             /* No valid character, treat it as a normal
+                character.  */
+             bitset_set (sbcset, name[0]);
+             return REG_NOERROR;
+           }
+         else
+           return REG_ECOLLATE;
+
+         /* Got valid collation sequence, add it as a new entry.  */
+         /* Check the space of the arrays.  */
+         if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0))
+           {
+             /* Not enough, realloc it.  */
+             /* +1 in case of mbcset->ncoll_syms is 0.  */
+             Idx new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1;
+             /* Use realloc since mbcset->coll_syms is NULL
+                if *alloc == 0.  */
+             int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t,
+                                                  new_coll_sym_alloc);
+             if (BE (new_coll_syms == NULL, 0))
+               return REG_ESPACE;
+             mbcset->coll_syms = new_coll_syms;
+             *coll_sym_alloc = new_coll_sym_alloc;
+           }
+         mbcset->coll_syms[mbcset->ncoll_syms++] = idx;
+         return REG_NOERROR;
+       }
+      else
+       {
+         if (BE (name_len != 1, 0))
+           return REG_ECOLLATE;
+         else
+           {
+             bitset_set (sbcset, name[0]);
+             return REG_NOERROR;
+           }
+       }
+    }
+#endif
+
+  re_token_t br_token;
+  re_bitset_ptr_t sbcset;
+#ifdef RE_ENABLE_I18N
+  re_charset_t *mbcset;
+  Idx coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;
+  Idx equiv_class_alloc = 0, char_class_alloc = 0;
+#endif /* not RE_ENABLE_I18N */
+  bool non_match = false;
+  bin_tree_t *work_tree;
+  int token_len;
+  bool first_round = true;
+#ifdef _LIBC
+  collseqmb = (const unsigned char *)
+    _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
+  nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+  if (nrules)
+    {
+      /*
+      if (MB_CUR_MAX > 1)
+      */
+      collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);
+      table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB);
+      symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE,
+                                                 _NL_COLLATE_SYMB_TABLEMB);
+      extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
+                                                  _NL_COLLATE_SYMB_EXTRAMB);
+    }
+#endif
+  sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
+#ifdef RE_ENABLE_I18N
+  mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
+#endif /* RE_ENABLE_I18N */
+#ifdef RE_ENABLE_I18N
+  if (BE (sbcset == NULL || mbcset == NULL, 0))
+#else
+  if (BE (sbcset == NULL, 0))
+#endif /* RE_ENABLE_I18N */
+    {
+      *err = REG_ESPACE;
+      return NULL;
+    }
+
+  token_len = peek_token_bracket (token, regexp, syntax);
+  if (BE (token->type == END_OF_RE, 0))
+    {
+      *err = REG_BADPAT;
+      goto parse_bracket_exp_free_return;
+    }
+  if (token->type == OP_NON_MATCH_LIST)
+    {
+#ifdef RE_ENABLE_I18N
+      mbcset->non_match = 1;
+#endif /* not RE_ENABLE_I18N */
+      non_match = true;
+      if (syntax & RE_HAT_LISTS_NOT_NEWLINE)
+       bitset_set (sbcset, '\n');
+      re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
+      token_len = peek_token_bracket (token, regexp, syntax);
+      if (BE (token->type == END_OF_RE, 0))
+       {
+         *err = REG_BADPAT;
+         goto parse_bracket_exp_free_return;
+       }
+    }
+
+  /* We treat the first ']' as a normal character.  */
+  if (token->type == OP_CLOSE_BRACKET)
+    token->type = CHARACTER;
+
+  while (1)
+    {
+      bracket_elem_t start_elem, end_elem;
+      unsigned char start_name_buf[BRACKET_NAME_BUF_SIZE];
+      unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE];
+      reg_errcode_t ret;
+      int token_len2 = 0;
+      bool is_range_exp = false;
+      re_token_t token2;
+
+      start_elem.opr.name = start_name_buf;
+      ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa,
+                                  syntax, first_round);
+      if (BE (ret != REG_NOERROR, 0))
+       {
+         *err = ret;
+         goto parse_bracket_exp_free_return;
+       }
+      first_round = false;
+
+      /* Get information about the next token.  We need it in any case.  */
+      token_len = peek_token_bracket (token, regexp, syntax);
+
+      /* Do not check for ranges if we know they are not allowed.  */
+      if (start_elem.type != CHAR_CLASS && start_elem.type != EQUIV_CLASS)
+       {
+         if (BE (token->type == END_OF_RE, 0))
+           {
+             *err = REG_EBRACK;
+             goto parse_bracket_exp_free_return;
+           }
+         if (token->type == OP_CHARSET_RANGE)
+           {
+             re_string_skip_bytes (regexp, token_len); /* Skip '-'.  */
+             token_len2 = peek_token_bracket (&token2, regexp, syntax);
+             if (BE (token2.type == END_OF_RE, 0))
+               {
+                 *err = REG_EBRACK;
+                 goto parse_bracket_exp_free_return;
+               }
+             if (token2.type == OP_CLOSE_BRACKET)
+               {
+                 /* We treat the last '-' as a normal character.  */
+                 re_string_skip_bytes (regexp, -token_len);
+                 token->type = CHARACTER;
+               }
+             else
+               is_range_exp = true;
+           }
+       }
+
+      if (is_range_exp == true)
+       {
+         end_elem.opr.name = end_name_buf;
+         ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2,
+                                      dfa, syntax, true);
+         if (BE (ret != REG_NOERROR, 0))
+           {
+             *err = ret;
+             goto parse_bracket_exp_free_return;
+           }
+
+         token_len = peek_token_bracket (token, regexp, syntax);
+
+#ifdef _LIBC
+         *err = build_range_exp (sbcset, mbcset, &range_alloc,
+                                 &start_elem, &end_elem);
+#else
+# ifdef RE_ENABLE_I18N
+         *err = build_range_exp (syntax, sbcset,
+                                 dfa->mb_cur_max > 1 ? mbcset : NULL,
+                                 &range_alloc, &start_elem, &end_elem);
+# else
+         *err = build_range_exp (syntax, sbcset, &start_elem, &end_elem);
+# endif
+#endif /* RE_ENABLE_I18N */
+         if (BE (*err != REG_NOERROR, 0))
+           goto parse_bracket_exp_free_return;
+       }
+      else
+       {
+         switch (start_elem.type)
+           {
+           case SB_CHAR:
+             bitset_set (sbcset, start_elem.opr.ch);
+             break;
+#ifdef RE_ENABLE_I18N
+           case MB_CHAR:
+             /* Check whether the array has enough space.  */
+             if (BE (mbchar_alloc == mbcset->nmbchars, 0))
+               {
+                 wchar_t *new_mbchars;
+                 /* Not enough, realloc it.  */
+                 /* +1 in case of mbcset->nmbchars is 0.  */
+                 mbchar_alloc = 2 * mbcset->nmbchars + 1;
+                 /* Use realloc since array is NULL if *alloc == 0.  */
+                 new_mbchars = re_realloc (mbcset->mbchars, wchar_t,
+                                           mbchar_alloc);
+                 if (BE (new_mbchars == NULL, 0))
+                   goto parse_bracket_exp_espace;
+                 mbcset->mbchars = new_mbchars;
+               }
+             mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;
+             break;
+#endif /* RE_ENABLE_I18N */
+           case EQUIV_CLASS:
+             *err = build_equiv_class (sbcset,
+#ifdef RE_ENABLE_I18N
+                                       mbcset, &equiv_class_alloc,
+#endif /* RE_ENABLE_I18N */
+                                       start_elem.opr.name);
+             if (BE (*err != REG_NOERROR, 0))
+               goto parse_bracket_exp_free_return;
+             break;
+           case COLL_SYM:
+             *err = build_collating_symbol (sbcset,
+#ifdef RE_ENABLE_I18N
+                                            mbcset, &coll_sym_alloc,
+#endif /* RE_ENABLE_I18N */
+                                            start_elem.opr.name);
+             if (BE (*err != REG_NOERROR, 0))
+               goto parse_bracket_exp_free_return;
+             break;
+           case CHAR_CLASS:
+             *err = build_charclass (regexp->trans, sbcset,
+#ifdef RE_ENABLE_I18N
+                                     mbcset, &char_class_alloc,
+#endif /* RE_ENABLE_I18N */
+                                     start_elem.opr.name, syntax);
+             if (BE (*err != REG_NOERROR, 0))
+              goto parse_bracket_exp_free_return;
+             break;
+           default:
+             assert (0);
+             break;
+           }
+       }
+      if (BE (token->type == END_OF_RE, 0))
+       {
+         *err = REG_EBRACK;
+         goto parse_bracket_exp_free_return;
+       }
+      if (token->type == OP_CLOSE_BRACKET)
+       break;
+    }
+
+  re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
+
+  /* If it is non-matching list.  */
+  if (non_match)
+    bitset_not (sbcset);
+
+#ifdef RE_ENABLE_I18N
+  /* Ensure only single byte characters are set.  */
+  if (dfa->mb_cur_max > 1)
+    bitset_mask (sbcset, dfa->sb_char);
+
+  if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes
+      || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes
+                                                    || mbcset->non_match)))
+    {
+      bin_tree_t *mbc_tree;
+      int sbc_idx;
+      /* Build a tree for complex bracket.  */
+      dfa->has_mb_node = 1;
+      br_token.type = COMPLEX_BRACKET;
+      br_token.opr.mbcset = mbcset;
+      mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+      if (BE (mbc_tree == NULL, 0))
+       goto parse_bracket_exp_espace;
+      for (sbc_idx = 0; sbc_idx < BITSET_WORDS; ++sbc_idx)
+       if (sbcset[sbc_idx])
+         break;
+      /* If there are no bits set in sbcset, there is no point
+        of having both SIMPLE_BRACKET and COMPLEX_BRACKET.  */
+      if (sbc_idx < BITSET_WORDS)
+       {
+         /* Build a tree for simple bracket.  */
+         br_token.type = SIMPLE_BRACKET;
+         br_token.opr.sbcset = sbcset;
+         work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+         if (BE (work_tree == NULL, 0))
+           goto parse_bracket_exp_espace;
+
+         /* Then join them by ALT node.  */
+         work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT);
+         if (BE (work_tree == NULL, 0))
+           goto parse_bracket_exp_espace;
+       }
+      else
+       {
+         re_free (sbcset);
+         work_tree = mbc_tree;
+       }
+    }
+  else
+#endif /* not RE_ENABLE_I18N */
+    {
+#ifdef RE_ENABLE_I18N
+      free_charset (mbcset);
+#endif
+      /* Build a tree for simple bracket.  */
+      br_token.type = SIMPLE_BRACKET;
+      br_token.opr.sbcset = sbcset;
+      work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+      if (BE (work_tree == NULL, 0))
+       goto parse_bracket_exp_espace;
+    }
+  return work_tree;
+
+ parse_bracket_exp_espace:
+  *err = REG_ESPACE;
+ parse_bracket_exp_free_return:
+  re_free (sbcset);
+#ifdef RE_ENABLE_I18N
+  free_charset (mbcset);
+#endif /* RE_ENABLE_I18N */
+  return NULL;
+}
+
+/* Parse an element in the bracket expression.  */
+
+static reg_errcode_t
+parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,
+                      re_token_t *token, int token_len, re_dfa_t *dfa,
+                      reg_syntax_t syntax, bool accept_hyphen)
+{
+#ifdef RE_ENABLE_I18N
+  int cur_char_size;
+  cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp));
+  if (cur_char_size > 1)
+    {
+      elem->type = MB_CHAR;
+      elem->opr.wch = re_string_wchar_at (regexp, re_string_cur_idx (regexp));
+      re_string_skip_bytes (regexp, cur_char_size);
+      return REG_NOERROR;
+    }
+#endif /* RE_ENABLE_I18N */
+  re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
+  if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS
+      || token->type == OP_OPEN_EQUIV_CLASS)
+    return parse_bracket_symbol (elem, regexp, token);
+  if (BE (token->type == OP_CHARSET_RANGE, 0) && !accept_hyphen)
+    {
+      /* A '-' must only appear as anything but a range indicator before
+        the closing bracket.  Everything else is an error.  */
+      re_token_t token2;
+      (void) peek_token_bracket (&token2, regexp, syntax);
+      if (token2.type != OP_CLOSE_BRACKET)
+       /* The actual error value is not standardized since this whole
+          case is undefined.  But ERANGE makes good sense.  */
+       return REG_ERANGE;
+    }
+  elem->type = SB_CHAR;
+  elem->opr.ch = token->opr.c;
+  return REG_NOERROR;
+}
+
+/* Parse a bracket symbol in the bracket expression.  Bracket symbols are
+   such as [:<character_class>:], [.<collating_element>.], and
+   [=<equivalent_class>=].  */
+
+static reg_errcode_t
+parse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp,
+                     re_token_t *token)
+{
+  unsigned char ch, delim = token->opr.c;
+  int i = 0;
+  if (re_string_eoi(regexp))
+    return REG_EBRACK;
+  for (;; ++i)
+    {
+      if (i >= BRACKET_NAME_BUF_SIZE)
+       return REG_EBRACK;
+      if (token->type == OP_OPEN_CHAR_CLASS)
+       ch = re_string_fetch_byte_case (regexp);
+      else
+       ch = re_string_fetch_byte (regexp);
+      if (re_string_eoi(regexp))
+       return REG_EBRACK;
+      if (ch == delim && re_string_peek_byte (regexp, 0) == ']')
+       break;
+      elem->opr.name[i] = ch;
+    }
+  re_string_skip_bytes (regexp, 1);
+  elem->opr.name[i] = '\0';
+  switch (token->type)
+    {
+    case OP_OPEN_COLL_ELEM:
+      elem->type = COLL_SYM;
+      break;
+    case OP_OPEN_EQUIV_CLASS:
+      elem->type = EQUIV_CLASS;
+      break;
+    case OP_OPEN_CHAR_CLASS:
+      elem->type = CHAR_CLASS;
+      break;
+    default:
+      break;
+    }
+  return REG_NOERROR;
+}
+
+  /* Helper function for parse_bracket_exp.
+     Build the equivalence class which is represented by NAME.
+     The result are written to MBCSET and SBCSET.
+     EQUIV_CLASS_ALLOC is the allocated size of mbcset->equiv_classes,
+     is a pointer argument sinse we may update it.  */
+
+static reg_errcode_t
+#ifdef RE_ENABLE_I18N
+build_equiv_class (bitset_t sbcset, re_charset_t *mbcset,
+                  Idx *equiv_class_alloc, const unsigned char *name)
+#else /* not RE_ENABLE_I18N */
+build_equiv_class (bitset_t sbcset, const unsigned char *name)
+#endif /* not RE_ENABLE_I18N */
+{
+#ifdef _LIBC
+  uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+  if (nrules != 0)
+    {
+      const int32_t *table, *indirect;
+      const unsigned char *weights, *extra, *cp;
+      unsigned char char_buf[2];
+      int32_t idx1, idx2;
+      unsigned int ch;
+      size_t len;
+      /* This #include defines a local function!  */
+# include <locale/weight.h>
+      /* Calculate the index for equivalence class.  */
+      cp = name;
+      table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+      weights = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
+                                              _NL_COLLATE_WEIGHTMB);
+      extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
+                                                  _NL_COLLATE_EXTRAMB);
+      indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
+                                               _NL_COLLATE_INDIRECTMB);
+      idx1 = findidx (&cp);
+      if (BE (idx1 == 0 || cp < name + strlen ((const char *) name), 0))
+       /* This isn't a valid character.  */
+       return REG_ECOLLATE;
+
+      /* Build single byte matcing table for this equivalence class.  */
+      char_buf[1] = (unsigned char) '\0';
+      len = weights[idx1 & 0xffffff];
+      for (ch = 0; ch < SBC_MAX; ++ch)
+       {
+         char_buf[0] = ch;
+         cp = char_buf;
+         idx2 = findidx (&cp);
+/*
+         idx2 = table[ch];
+*/
+         if (idx2 == 0)
+           /* This isn't a valid character.  */
+           continue;
+         /* Compare only if the length matches and the collation rule
+            index is the same.  */
+         if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24))
+           {
+             int cnt = 0;
+
+             while (cnt <= len &&
+                    weights[(idx1 & 0xffffff) + 1 + cnt]
+                    == weights[(idx2 & 0xffffff) + 1 + cnt])
+               ++cnt;
+
+             if (cnt > len)
+               bitset_set (sbcset, ch);
+           }
+       }
+      /* Check whether the array has enough space.  */
+      if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0))
+       {
+         /* Not enough, realloc it.  */
+         /* +1 in case of mbcset->nequiv_classes is 0.  */
+         Idx new_equiv_class_alloc = 2 * mbcset->nequiv_classes + 1;
+         /* Use realloc since the array is NULL if *alloc == 0.  */
+         int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes,
+                                                  int32_t,
+                                                  new_equiv_class_alloc);
+         if (BE (new_equiv_classes == NULL, 0))
+           return REG_ESPACE;
+         mbcset->equiv_classes = new_equiv_classes;
+         *equiv_class_alloc = new_equiv_class_alloc;
+       }
+      mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;
+    }
+  else
+#endif /* _LIBC */
+    {
+      if (BE (strlen ((const char *) name) != 1, 0))
+       return REG_ECOLLATE;
+      bitset_set (sbcset, *name);
+    }
+  return REG_NOERROR;
+}
+
+  /* Helper function for parse_bracket_exp.
+     Build the character class which is represented by NAME.
+     The result are written to MBCSET and SBCSET.
+     CHAR_CLASS_ALLOC is the allocated size of mbcset->char_classes,
+     is a pointer argument sinse we may update it.  */
+
+static reg_errcode_t
+#ifdef RE_ENABLE_I18N
+build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
+                re_charset_t *mbcset, Idx *char_class_alloc,
+                const unsigned char *class_name, reg_syntax_t syntax)
+#else /* not RE_ENABLE_I18N */
+build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
+                const unsigned char *class_name, reg_syntax_t syntax)
+#endif /* not RE_ENABLE_I18N */
+{
+  int i;
+  const char *name = (const char *) class_name;
+
+  /* In case of REG_ICASE "upper" and "lower" match the both of
+     upper and lower cases.  */
+  if ((syntax & RE_ICASE)
+      && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0))
+    name = "alpha";
+
+#ifdef RE_ENABLE_I18N
+  /* Check the space of the arrays.  */
+  if (BE (*char_class_alloc == mbcset->nchar_classes, 0))
+    {
+      /* Not enough, realloc it.  */
+      /* +1 in case of mbcset->nchar_classes is 0.  */
+      Idx new_char_class_alloc = 2 * mbcset->nchar_classes + 1;
+      /* Use realloc since array is NULL if *alloc == 0.  */
+      wctype_t *new_char_classes = re_realloc (mbcset->char_classes, wctype_t,
+                                              new_char_class_alloc);
+      if (BE (new_char_classes == NULL, 0))
+       return REG_ESPACE;
+      mbcset->char_classes = new_char_classes;
+      *char_class_alloc = new_char_class_alloc;
+    }
+  mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name);
+#endif /* RE_ENABLE_I18N */
+
+#define BUILD_CHARCLASS_LOOP(ctype_func)       \
+  do {                                         \
+    if (BE (trans != NULL, 0))                 \
+      {                                                \
+       for (i = 0; i < SBC_MAX; ++i)           \
+         if (ctype_func (i))                   \
+           bitset_set (sbcset, trans[i]);      \
+      }                                                \
+    else                                       \
+      {                                                \
+       for (i = 0; i < SBC_MAX; ++i)           \
+         if (ctype_func (i))                   \
+           bitset_set (sbcset, i);             \
+      }                                                \
+  } while (0)
+
+  if (strcmp (name, "alnum") == 0)
+    BUILD_CHARCLASS_LOOP (isalnum);
+  else if (strcmp (name, "cntrl") == 0)
+    BUILD_CHARCLASS_LOOP (iscntrl);
+  else if (strcmp (name, "lower") == 0)
+    BUILD_CHARCLASS_LOOP (islower);
+  else if (strcmp (name, "space") == 0)
+    BUILD_CHARCLASS_LOOP (isspace);
+  else if (strcmp (name, "alpha") == 0)
+    BUILD_CHARCLASS_LOOP (isalpha);
+  else if (strcmp (name, "digit") == 0)
+    BUILD_CHARCLASS_LOOP (isdigit);
+  else if (strcmp (name, "print") == 0)
+    BUILD_CHARCLASS_LOOP (isprint);
+  else if (strcmp (name, "upper") == 0)
+    BUILD_CHARCLASS_LOOP (isupper);
+  else if (strcmp (name, "blank") == 0)
+    BUILD_CHARCLASS_LOOP (isblank);
+  else if (strcmp (name, "graph") == 0)
+    BUILD_CHARCLASS_LOOP (isgraph);
+  else if (strcmp (name, "punct") == 0)
+    BUILD_CHARCLASS_LOOP (ispunct);
+  else if (strcmp (name, "xdigit") == 0)
+    BUILD_CHARCLASS_LOOP (isxdigit);
+  else
+    return REG_ECTYPE;
+
+  return REG_NOERROR;
+}
+
+static bin_tree_t *
+build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
+                   const unsigned char *class_name,
+                   const unsigned char *extra, bool non_match,
+                   reg_errcode_t *err)
+{
+  re_bitset_ptr_t sbcset;
+#ifdef RE_ENABLE_I18N
+  re_charset_t *mbcset;
+  Idx alloc = 0;
+#endif /* not RE_ENABLE_I18N */
+  reg_errcode_t ret;
+  re_token_t br_token;
+  bin_tree_t *tree;
+
+  sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
+#ifdef RE_ENABLE_I18N
+  mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
+#endif /* RE_ENABLE_I18N */
+
+#ifdef RE_ENABLE_I18N
+  if (BE (sbcset == NULL || mbcset == NULL, 0))
+#else /* not RE_ENABLE_I18N */
+  if (BE (sbcset == NULL, 0))
+#endif /* not RE_ENABLE_I18N */
+    {
+      *err = REG_ESPACE;
+      return NULL;
+    }
+
+  if (non_match)
+    {
+#ifdef RE_ENABLE_I18N
+      mbcset->non_match = 1;
+#endif /* not RE_ENABLE_I18N */
+    }
+
+  /* We don't care the syntax in this case.  */
+  ret = build_charclass (trans, sbcset,
+#ifdef RE_ENABLE_I18N
+                        mbcset, &alloc,
+#endif /* RE_ENABLE_I18N */
+                        class_name, 0);
+
+  if (BE (ret != REG_NOERROR, 0))
+    {
+      re_free (sbcset);
+#ifdef RE_ENABLE_I18N
+      free_charset (mbcset);
+#endif /* RE_ENABLE_I18N */
+      *err = ret;
+      return NULL;
+    }
+  /* \w match '_' also.  */
+  for (; *extra; extra++)
+    bitset_set (sbcset, *extra);
+
+  /* If it is non-matching list.  */
+  if (non_match)
+    bitset_not (sbcset);
+
+#ifdef RE_ENABLE_I18N
+  /* Ensure only single byte characters are set.  */
+  if (dfa->mb_cur_max > 1)
+    bitset_mask (sbcset, dfa->sb_char);
+#endif
+
+  /* Build a tree for simple bracket.  */
+  br_token.type = SIMPLE_BRACKET;
+  br_token.opr.sbcset = sbcset;
+  tree = create_token_tree (dfa, NULL, NULL, &br_token);
+  if (BE (tree == NULL, 0))
+    goto build_word_op_espace;
+
+#ifdef RE_ENABLE_I18N
+  if (dfa->mb_cur_max > 1)
+    {
+      bin_tree_t *mbc_tree;
+      /* Build a tree for complex bracket.  */
+      br_token.type = COMPLEX_BRACKET;
+      br_token.opr.mbcset = mbcset;
+      dfa->has_mb_node = 1;
+      mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+      if (BE (mbc_tree == NULL, 0))
+       goto build_word_op_espace;
+      /* Then join them by ALT node.  */
+      tree = create_tree (dfa, tree, mbc_tree, OP_ALT);
+      if (BE (mbc_tree != NULL, 1))
+       return tree;
+    }
+  else
+    {
+      free_charset (mbcset);
+      return tree;
+    }
+#else /* not RE_ENABLE_I18N */
+  return tree;
+#endif /* not RE_ENABLE_I18N */
+
+ build_word_op_espace:
+  re_free (sbcset);
+#ifdef RE_ENABLE_I18N
+  free_charset (mbcset);
+#endif /* RE_ENABLE_I18N */
+  *err = REG_ESPACE;
+  return NULL;
+}
+
+/* This is intended for the expressions like "a{1,3}".
+   Fetch a number from `input', and return the number.
+   Return REG_MISSING if the number field is empty like "{,1}".
+   Return REG_ERROR if an error occurred.  */
+
+static Idx
+fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax)
+{
+  Idx num = REG_MISSING;
+  unsigned char c;
+  while (1)
+    {
+      fetch_token (token, input, syntax);
+      c = token->opr.c;
+      if (BE (token->type == END_OF_RE, 0))
+       return REG_ERROR;
+      if (token->type == OP_CLOSE_DUP_NUM || c == ',')
+       break;
+      num = ((token->type != CHARACTER || c < '0' || '9' < c
+             || num == REG_ERROR)
+            ? REG_ERROR
+            : ((num == REG_MISSING) ? c - '0' : num * 10 + c - '0'));
+      num = (num > RE_DUP_MAX) ? REG_ERROR : num;
+    }
+  return num;
+}
+\f
+#ifdef RE_ENABLE_I18N
+static void
+free_charset (re_charset_t *cset)
+{
+  re_free (cset->mbchars);
+# ifdef _LIBC
+  re_free (cset->coll_syms);
+  re_free (cset->equiv_classes);
+  re_free (cset->range_starts);
+  re_free (cset->range_ends);
+# endif
+  re_free (cset->char_classes);
+  re_free (cset);
+}
+#endif /* RE_ENABLE_I18N */
+\f
+/* Functions for binary tree operation.  */
+
+/* Create a tree node.  */
+
+static bin_tree_t *
+create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,
+            re_token_type_t type)
+{
+  re_token_t t;
+  t.type = type;
+  return create_token_tree (dfa, left, right, &t);
+}
+
+static bin_tree_t *
+create_token_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,
+                  const re_token_t *token)
+{
+  bin_tree_t *tree;
+  if (BE (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE, 0))
+    {
+      bin_tree_storage_t *storage = re_malloc (bin_tree_storage_t, 1);
+
+      if (storage == NULL)
+       return NULL;
+      storage->next = dfa->str_tree_storage;
+      dfa->str_tree_storage = storage;
+      dfa->str_tree_storage_idx = 0;
+    }
+  tree = &dfa->str_tree_storage->data[dfa->str_tree_storage_idx++];
+
+  tree->parent = NULL;
+  tree->left = left;
+  tree->right = right;
+  tree->token = *token;
+  tree->token.duplicated = 0;
+  tree->token.opt_subexp = 0;
+  tree->first = NULL;
+  tree->next = NULL;
+  tree->node_idx = REG_MISSING;
+
+  if (left != NULL)
+    left->parent = tree;
+  if (right != NULL)
+    right->parent = tree;
+  return tree;
+}
+
+/* Mark the tree SRC as an optional subexpression.
+   To be called from preorder or postorder.  */
+
+static reg_errcode_t
+mark_opt_subexp (void *extra, bin_tree_t *node)
+{
+  Idx idx = (Idx) (long) extra;
+  if (node->token.type == SUBEXP && node->token.opr.idx == idx)
+    node->token.opt_subexp = 1;
+
+  return REG_NOERROR;
+}
+
+/* Free the allocated memory inside NODE. */
+
+static void
+free_token (re_token_t *node)
+{
+#ifdef RE_ENABLE_I18N
+  if (node->type == COMPLEX_BRACKET && node->duplicated == 0)
+    free_charset (node->opr.mbcset);
+  else
+#endif /* RE_ENABLE_I18N */
+    if (node->type == SIMPLE_BRACKET && node->duplicated == 0)
+      re_free (node->opr.sbcset);
+}
+
+/* Worker function for tree walking.  Free the allocated memory inside NODE
+   and its children. */
+
+static reg_errcode_t
+free_tree (void *extra, bin_tree_t *node)
+{
+  free_token (&node->token);
+  return REG_NOERROR;
+}
+
+
+/* Duplicate the node SRC, and return new node.  This is a preorder
+   visit similar to the one implemented by the generic visitor, but
+   we need more infrastructure to maintain two parallel trees --- so,
+   it's easier to duplicate.  */
+
+static bin_tree_t *
+duplicate_tree (const bin_tree_t *root, re_dfa_t *dfa)
+{
+  const bin_tree_t *node;
+  bin_tree_t *dup_root;
+  bin_tree_t **p_new = &dup_root, *dup_node = root->parent;
+
+  for (node = root; ; )
+    {
+      /* Create a new tree and link it back to the current parent.  */
+      *p_new = create_token_tree (dfa, NULL, NULL, &node->token);
+      if (*p_new == NULL)
+       return NULL;
+      (*p_new)->parent = dup_node;
+      (*p_new)->token.duplicated = 1;
+      dup_node = *p_new;
+
+      /* Go to the left node, or up and to the right.  */
+      if (node->left)
+       {
+         node = node->left;
+         p_new = &dup_node->left;
+       }
+      else
+       {
+         const bin_tree_t *prev = NULL;
+         while (node->right == prev || node->right == NULL)
+           {
+             prev = node;
+             node = node->parent;
+             dup_node = dup_node->parent;
+             if (!node)
+               return dup_root;
+           }
+         node = node->right;
+         p_new = &dup_node->right;
+       }
+    }
+}
diff --git a/grub-core/gnulib/regex.c b/grub-core/gnulib/regex.c
new file mode 100644 (file)
index 0000000..904fe62
--- /dev/null
@@ -0,0 +1,72 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002, 2003, 2005, 2006, 2009, 2010 Free Software Foundation,
+   Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
+
+   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <config.h>
+
+/* Make sure noone compiles this code with a C++ compiler.  */
+#if defined __cplusplus && defined _LIBC
+# error "This is C code, use a C compiler"
+#endif
+
+#ifdef _LIBC
+/* We have to keep the namespace clean.  */
+# define regfree(preg) __regfree (preg)
+# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
+# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
+# define regerror(errcode, preg, errbuf, errbuf_size) \
+       __regerror(errcode, preg, errbuf, errbuf_size)
+# define re_set_registers(bu, re, nu, st, en) \
+       __re_set_registers (bu, re, nu, st, en)
+# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
+       __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
+# define re_match(bufp, string, size, pos, regs) \
+       __re_match (bufp, string, size, pos, regs)
+# define re_search(bufp, string, size, startpos, range, regs) \
+       __re_search (bufp, string, size, startpos, range, regs)
+# define re_compile_pattern(pattern, length, bufp) \
+       __re_compile_pattern (pattern, length, bufp)
+# define re_set_syntax(syntax) __re_set_syntax (syntax)
+# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
+       __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
+# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
+
+# include "../locale/localeinfo.h"
+#endif
+
+/* On some systems, limits.h sets RE_DUP_MAX to a lower value than
+   GNU regex allows.  Include it before <regex.h>, which correctly
+   #undefs RE_DUP_MAX and sets it to the right value.  */
+#include <limits.h>
+
+#include <regex.h>
+#include "regex_internal.h"
+
+#include "regex_internal.c"
+#include "regcomp.c"
+#include "regexec.c"
+
+/* Binary backward compatibility.  */
+#if _LIBC
+# include <shlib-compat.h>
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)
+link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.")
+int re_max_failures = 2000;
+# endif
+#endif
diff --git a/grub-core/gnulib/regex.h b/grub-core/gnulib/regex.h
new file mode 100644 (file)
index 0000000..594d5e6
--- /dev/null
@@ -0,0 +1,676 @@
+/* Definitions for data structures and routines for the regular
+   expression library.
+   Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993, 1995, 1996, 1997, 1998,
+   2000, 2001, 2002, 2003, 2005, 2006, 2009, 2010 Free Software Foundation,
+   Inc.
+   This file is part of the GNU C Library.
+
+   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef _REGEX_H
+#define _REGEX_H 1
+
+#include <sys/types.h>
+
+/* Allow the use in C++ code.  */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Define __USE_GNU_REGEX to declare GNU extensions that violate the
+   POSIX name space rules.  */
+#undef __USE_GNU_REGEX
+#if (defined _GNU_SOURCE                                       \
+     || (!defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE    \
+        && !defined _XOPEN_SOURCE))
+# define __USE_GNU_REGEX 1
+#endif
+
+#ifdef _REGEX_LARGE_OFFSETS
+
+/* Use types and values that are wide enough to represent signed and
+   unsigned byte offsets in memory.  This currently works only when
+   the regex code is used outside of the GNU C library; it is not yet
+   supported within glibc itself, and glibc users should not define
+   _REGEX_LARGE_OFFSETS.  */
+
+/* The type of the offset of a byte within a string.
+   For historical reasons POSIX 1003.1-2004 requires that regoff_t be
+   at least as wide as off_t.  However, many common POSIX platforms set
+   regoff_t to the more-sensible ssize_t and the Open Group has
+   signalled its intention to change the requirement to be that
+   regoff_t be at least as wide as ptrdiff_t and ssize_t; see XBD ERN
+   60 (2005-08-25).  We don't know of any hosts where ssize_t or
+   ptrdiff_t is wider than ssize_t, so ssize_t is safe.  */
+typedef ssize_t regoff_t;
+
+/* The type of nonnegative object indexes.  Traditionally, GNU regex
+   uses 'int' for these.  Code that uses __re_idx_t should work
+   regardless of whether the type is signed.  */
+typedef size_t __re_idx_t;
+
+/* The type of object sizes.  */
+typedef size_t __re_size_t;
+
+/* The type of object sizes, in places where the traditional code
+   uses unsigned long int.  */
+typedef size_t __re_long_size_t;
+
+#else
+
+/* Use types that are binary-compatible with the traditional GNU regex
+   implementation, which mishandles strings longer than INT_MAX.  */
+
+typedef int regoff_t;
+typedef int __re_idx_t;
+typedef unsigned int __re_size_t;
+typedef unsigned long int __re_long_size_t;
+
+#endif
+
+/* The following two types have to be signed and unsigned integer type
+   wide enough to hold a value of a pointer.  For most ANSI compilers
+   ptrdiff_t and size_t should be likely OK.  Still size of these two
+   types is 2 for Microsoft C.  Ugh... */
+typedef long int s_reg_t;
+typedef unsigned long int active_reg_t;
+
+/* The following bits are used to determine the regexp syntax we
+   recognize.  The set/not-set meanings are chosen so that Emacs syntax
+   remains the value 0.  The bits are given in alphabetical order, and
+   the definitions shifted by one from the previous bit; thus, when we
+   add or remove a bit, only one other definition need change.  */
+typedef unsigned long int reg_syntax_t;
+
+#ifdef __USE_GNU_REGEX
+
+/* If this bit is not set, then \ inside a bracket expression is literal.
+   If set, then such a \ quotes the following character.  */
+# define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+     literals.
+   If set, then \+ and \? are operators and + and ? are literals.  */
+# define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* If this bit is set, then character classes are supported.  They are:
+     [:alpha:], [:upper:], [:lower:],  [:digit:], [:alnum:], [:xdigit:],
+     [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+   If not set, then character classes are not supported.  */
+# define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+     expressions, of course).
+   If this bit is not set, then it depends:
+        ^  is an anchor if it is at the beginning of a regular
+           expression or after an open-group or an alternation operator;
+        $  is an anchor if it is at the end of a regular expression, or
+           before a close-group or an alternation operator.
+
+   This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+   POSIX draft 11.2 says that * etc. in leading positions is undefined.
+   We already implemented a previous draft which made those constructs
+   invalid, though, so we haven't changed the code back.  */
+# define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+     regardless of where they are in the pattern.
+   If this bit is not set, then special characters are special only in
+     some contexts; otherwise they are ordinary.  Specifically,
+     * + ? and intervals are only special when not after the beginning,
+     open-group, or alternation operator.  */
+# define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+     immediately after an alternation or begin-group operator.  */
+# define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+   If not set, then it doesn't.  */
+# define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+   If not set, then it does.  */
+# define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+   If not set, they do.  */
+# define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+     interval, depending on RE_NO_BK_BRACES.
+   If not set, \{, \}, {, and } are literals.  */
+# define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+   If not set, they are.  */
+# define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+   If not set, newline is literal.  */
+# define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then `{...}' defines an interval, and \{ and \}
+     are literals.
+  If not set, then `\{...\}' defines an interval.  */
+# define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+   If not set, \(...\) defines a group, and ( and ) are literals.  */
+# define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+   If not set, then \<digit> is a back-reference.  */
+# define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal.
+   If not set, then \| is an alternation operator, and | is literal.  */
+# define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+     than the starting range point, as in [z-a], is invalid.
+   If not set, then when ending range point collates higher than the
+     starting range point, the range is ignored.  */
+# define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+   If not set, then an unmatched ) is invalid.  */
+# define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* If this bit is set, succeed as soon as we match the whole pattern,
+   without further backtracking.  */
+# define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
+
+/* If this bit is set, do not process the GNU regex operators.
+   If not set, then the GNU regex operators are recognized. */
+# define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)
+
+/* If this bit is set, turn on internal regex debugging.
+   If not set, and debugging was on, turn it off.
+   This only works if regex.c is compiled -DDEBUG.
+   We define this bit always, so that all that's needed to turn on
+   debugging is to recompile regex.c; the calling code can always have
+   this bit set, and it won't affect anything in the normal case. */
+# define RE_DEBUG (RE_NO_GNU_OPS << 1)
+
+/* If this bit is set, a syntactically invalid interval is treated as
+   a string of ordinary characters.  For example, the ERE 'a{1' is
+   treated as 'a\{1'.  */
+# define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
+
+/* If this bit is set, then ignore case when matching.
+   If not set, then case is significant.  */
+# define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
+
+/* This bit is used internally like RE_CONTEXT_INDEP_ANCHORS but only
+   for ^, because it is difficult to scan the regex backwards to find
+   whether ^ should be special.  */
+# define RE_CARET_ANCHORS_HERE (RE_ICASE << 1)
+
+/* If this bit is set, then \{ cannot be first in an bre or
+   immediately after an alternation or begin-group operator.  */
+# define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1)
+
+/* If this bit is set, then no_sub will be set to 1 during
+   re_compile_pattern.  */
+# define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1)
+
+#endif /* defined __USE_GNU_REGEX */
+
+/* This global variable defines the particular regexp syntax to use (for
+   some interfaces).  When a regexp is compiled, the syntax used is
+   stored in the pattern buffer, so changing this does not affect
+   already-compiled regexps.  */
+extern reg_syntax_t re_syntax_options;
+\f
+#ifdef __USE_GNU_REGEX
+/* Define combinations of the above bits for the standard possibilities.
+   (The [[[ comments delimit what gets put into the Texinfo file, so
+   don't delete them!)  */
+/* [[[begin syntaxes]]] */
+# define RE_SYNTAX_EMACS 0
+
+# define RE_SYNTAX_AWK                                                 \
+  (RE_BACKSLASH_ESCAPE_IN_LISTS   | RE_DOT_NOT_NULL                    \
+   | RE_NO_BK_PARENS              | RE_NO_BK_REFS                      \
+   | RE_NO_BK_VBAR                | RE_NO_EMPTY_RANGES                 \
+   | RE_DOT_NEWLINE              | RE_CONTEXT_INDEP_ANCHORS            \
+   | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
+
+# define RE_SYNTAX_GNU_AWK                                             \
+  ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG)        \
+   & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS           \
+       | RE_CONTEXT_INVALID_OPS ))
+
+# define RE_SYNTAX_POSIX_AWK                                           \
+  (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS             \
+   | RE_INTERVALS          | RE_NO_GNU_OPS)
+
+# define RE_SYNTAX_GREP                                                        \
+  (RE_BK_PLUS_QM              | RE_CHAR_CLASSES                                \
+   | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS                           \
+   | RE_NEWLINE_ALT)
+
+# define RE_SYNTAX_EGREP                                               \
+  (RE_CHAR_CLASSES        | RE_CONTEXT_INDEP_ANCHORS                   \
+   | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE                   \
+   | RE_NEWLINE_ALT       | RE_NO_BK_PARENS                            \
+   | RE_NO_BK_VBAR)
+
+# define RE_SYNTAX_POSIX_EGREP                                         \
+  (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES                    \
+   | RE_INVALID_INTERVAL_ORD)
+
+/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff.  */
+# define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
+
+# define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax.  */
+# define _RE_SYNTAX_POSIX_COMMON                                       \
+  (RE_CHAR_CLASSES | RE_DOT_NEWLINE      | RE_DOT_NOT_NULL             \
+   | RE_INTERVALS  | RE_NO_EMPTY_RANGES)
+
+# define RE_SYNTAX_POSIX_BASIC                                         \
+  (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+   RE_LIMITED_OPS, i.e., \? \+ \| are not recognized.  Actually, this
+   isn't minimal, since other operators, such as \`, aren't disabled.  */
+# define RE_SYNTAX_POSIX_MINIMAL_BASIC                                 \
+  (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+# define RE_SYNTAX_POSIX_EXTENDED                                      \
+  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS                 \
+   | RE_CONTEXT_INDEP_OPS   | RE_NO_BK_BRACES                          \
+   | RE_NO_BK_PARENS        | RE_NO_BK_VBAR                            \
+   | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is
+   removed and RE_NO_BK_REFS is added.  */
+# define RE_SYNTAX_POSIX_MINIMAL_EXTENDED                              \
+  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS                 \
+   | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES                          \
+   | RE_NO_BK_PARENS        | RE_NO_BK_REFS                            \
+   | RE_NO_BK_VBAR         | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+
+#endif /* defined __USE_GNU_REGEX */
+\f
+#ifdef __USE_GNU_REGEX
+
+/* Maximum number of duplicates an interval can allow.  POSIX-conforming
+   systems might define this in <limits.h>, but we want our
+   value, so remove any previous define.  */
+# ifdef RE_DUP_MAX
+#  undef RE_DUP_MAX
+# endif
+
+/* RE_DUP_MAX is 2**15 - 1 because an earlier implementation stored
+   the counter as a 2-byte signed integer.  This is no longer true, so
+   RE_DUP_MAX could be increased to (INT_MAX / 10 - 1), or to
+   ((SIZE_MAX - 2) / 10 - 1) if _REGEX_LARGE_OFFSETS is defined.
+   However, there would be a huge performance problem if someone
+   actually used a pattern like a\{214748363\}, so RE_DUP_MAX retains
+   its historical value.  */
+# define RE_DUP_MAX (0x7fff)
+
+#endif /* defined __USE_GNU_REGEX */
+
+
+/* POSIX `cflags' bits (i.e., information for `regcomp').  */
+
+/* If this bit is set, then use extended regular expression syntax.
+   If not set, then use basic regular expression syntax.  */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+   If not set, then case is significant.  */
+#define REG_ICASE (1 << 1)
+
+/* If this bit is set, then anchors do not match at newline
+     characters in the string.
+   If not set, then anchors do match at newlines.  */
+#define REG_NEWLINE (1 << 2)
+
+/* If this bit is set, then report only success or fail in regexec.
+   If not set, then returns differ between not matching and errors.  */
+#define REG_NOSUB (1 << 3)
+
+
+/* POSIX `eflags' bits (i.e., information for regexec).  */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+     the beginning of the string (presumably because it's not the
+     beginning of a line).
+   If not set, then the beginning-of-line operator does match the
+     beginning of the string.  */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line.  */
+#define REG_NOTEOL (1 << 1)
+
+/* Use PMATCH[0] to delimit the start and end of the search in the
+   buffer.  */
+#define REG_STARTEND (1 << 2)
+
+
+/* If any error codes are removed, changed, or added, update the
+   `__re_error_msgid' table in regcomp.c.  */
+
+typedef enum
+{
+  _REG_ENOSYS = -1,    /* This will never happen for this implementation.  */
+  _REG_NOERROR = 0,    /* Success.  */
+  _REG_NOMATCH,                /* Didn't find a match (for regexec).  */
+
+  /* POSIX regcomp return error codes.  (In the order listed in the
+     standard.)  */
+  _REG_BADPAT,         /* Invalid pattern.  */
+  _REG_ECOLLATE,       /* Invalid collating element.  */
+  _REG_ECTYPE,         /* Invalid character class name.  */
+  _REG_EESCAPE,                /* Trailing backslash.  */
+  _REG_ESUBREG,                /* Invalid back reference.  */
+  _REG_EBRACK,         /* Unmatched left bracket.  */
+  _REG_EPAREN,         /* Parenthesis imbalance.  */
+  _REG_EBRACE,         /* Unmatched \{.  */
+  _REG_BADBR,          /* Invalid contents of \{\}.  */
+  _REG_ERANGE,         /* Invalid range end.  */
+  _REG_ESPACE,         /* Ran out of memory.  */
+  _REG_BADRPT,         /* No preceding re for repetition op.  */
+
+  /* Error codes we've added.  */
+  _REG_EEND,           /* Premature end.  */
+  _REG_ESIZE,          /* Compiled pattern bigger than 2^16 bytes.  */
+  _REG_ERPAREN         /* Unmatched ) or \); not returned from regcomp.  */
+} reg_errcode_t;
+
+#ifdef _XOPEN_SOURCE
+# define REG_ENOSYS    _REG_ENOSYS
+#endif
+#define REG_NOERROR    _REG_NOERROR
+#define REG_NOMATCH    _REG_NOMATCH
+#define REG_BADPAT     _REG_BADPAT
+#define REG_ECOLLATE   _REG_ECOLLATE
+#define REG_ECTYPE     _REG_ECTYPE
+#define REG_EESCAPE    _REG_EESCAPE
+#define REG_ESUBREG    _REG_ESUBREG
+#define REG_EBRACK     _REG_EBRACK
+#define REG_EPAREN     _REG_EPAREN
+#define REG_EBRACE     _REG_EBRACE
+#define REG_BADBR      _REG_BADBR
+#define REG_ERANGE     _REG_ERANGE
+#define REG_ESPACE     _REG_ESPACE
+#define REG_BADRPT     _REG_BADRPT
+#define REG_EEND       _REG_EEND
+#define REG_ESIZE      _REG_ESIZE
+#define REG_ERPAREN    _REG_ERPAREN
+\f
+/* struct re_pattern_buffer normally uses member names like `buffer'
+   that POSIX does not allow.  In POSIX mode these members have names
+   with leading `re_' (e.g., `re_buffer').  */
+#ifdef __USE_GNU_REGEX
+# define _REG_RE_NAME(id) id
+# define _REG_RM_NAME(id) id
+#else
+# define _REG_RE_NAME(id) re_##id
+# define _REG_RM_NAME(id) rm_##id
+#endif
+
+/* The user can specify the type of the re_translate member by
+   defining the macro RE_TRANSLATE_TYPE, which defaults to unsigned
+   char *.  This pollutes the POSIX name space, so in POSIX mode just
+   use unsigned char *.  */
+#ifdef __USE_GNU_REGEX
+# ifndef RE_TRANSLATE_TYPE
+#  define RE_TRANSLATE_TYPE unsigned char *
+# endif
+# define REG_TRANSLATE_TYPE RE_TRANSLATE_TYPE
+#else
+# define REG_TRANSLATE_TYPE unsigned char *
+#endif
+
+/* This data structure represents a compiled pattern.  Before calling
+   the pattern compiler, the fields `buffer', `allocated', `fastmap',
+   `translate', and `no_sub' can be set.  After the pattern has been
+   compiled, the `re_nsub' field is available.  All other fields are
+   private to the regex routines.  */
+
+struct re_pattern_buffer
+{
+  /* Space that holds the compiled pattern.  It is declared as
+     `unsigned char *' because its elements are sometimes used as
+     array indexes.  */
+  unsigned char *_REG_RE_NAME (buffer);
+
+  /* Number of bytes to which `buffer' points.  */
+  __re_long_size_t _REG_RE_NAME (allocated);
+
+  /* Number of bytes actually used in `buffer'.  */
+  __re_long_size_t _REG_RE_NAME (used);
+
+  /* Syntax setting with which the pattern was compiled.  */
+  reg_syntax_t _REG_RE_NAME (syntax);
+
+  /* Pointer to a fastmap, if any, otherwise zero.  re_search uses the
+     fastmap, if there is one, to skip over impossible starting points
+     for matches.  */
+  char *_REG_RE_NAME (fastmap);
+
+  /* Either a translate table to apply to all characters before
+     comparing them, or zero for no translation.  The translation is
+     applied to a pattern when it is compiled and to a string when it
+     is matched.  */
+  REG_TRANSLATE_TYPE _REG_RE_NAME (translate);
+
+  /* Number of subexpressions found by the compiler.  */
+  size_t re_nsub;
+
+  /* Zero if this pattern cannot match the empty string, one else.
+     Well, in truth it's used only in `re_search_2', to see whether or
+     not we should use the fastmap, so we don't set this absolutely
+     perfectly; see `re_compile_fastmap' (the `duplicate' case).  */
+  unsigned int _REG_RE_NAME (can_be_null) : 1;
+
+  /* If REGS_UNALLOCATED, allocate space in the `regs' structure
+     for `max (RE_NREGS, re_nsub + 1)' groups.
+     If REGS_REALLOCATE, reallocate space if necessary.
+     If REGS_FIXED, use what's there.  */
+#ifdef __USE_GNU_REGEX
+# define REGS_UNALLOCATED 0
+# define REGS_REALLOCATE 1
+# define REGS_FIXED 2
+#endif
+  unsigned int _REG_RE_NAME (regs_allocated) : 2;
+
+  /* Set to zero when `regex_compile' compiles a pattern; set to one
+     by `re_compile_fastmap' if it updates the fastmap.  */
+  unsigned int _REG_RE_NAME (fastmap_accurate) : 1;
+
+  /* If set, `re_match_2' does not return information about
+     subexpressions.  */
+  unsigned int _REG_RE_NAME (no_sub) : 1;
+
+  /* If set, a beginning-of-line anchor doesn't match at the beginning
+     of the string.  */
+  unsigned int _REG_RE_NAME (not_bol) : 1;
+
+  /* Similarly for an end-of-line anchor.  */
+  unsigned int _REG_RE_NAME (not_eol) : 1;
+
+  /* If true, an anchor at a newline matches.  */
+  unsigned int _REG_RE_NAME (newline_anchor) : 1;
+
+/* [[[end pattern_buffer]]] */
+};
+
+typedef struct re_pattern_buffer regex_t;
+\f
+/* This is the structure we store register match data in.  See
+   regex.texinfo for a full description of what registers match.  */
+struct re_registers
+{
+  __re_size_t _REG_RM_NAME (num_regs);
+  regoff_t *_REG_RM_NAME (start);
+  regoff_t *_REG_RM_NAME (end);
+};
+
+
+/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+   `re_match_2' returns information about at least this many registers
+   the first time a `regs' structure is passed.  */
+#if !defined RE_NREGS && defined __USE_GNU_REGEX
+# define RE_NREGS 30
+#endif
+
+
+/* POSIX specification for registers.  Aside from the different names than
+   `re_registers', POSIX uses an array of structures, instead of a
+   structure of arrays.  */
+typedef struct
+{
+  regoff_t rm_so;  /* Byte offset from string's start to substring's start.  */
+  regoff_t rm_eo;  /* Byte offset from string's start to substring's end.  */
+} regmatch_t;
+\f
+/* Declarations for routines.  */
+
+/* Sets the current default syntax to SYNTAX, and return the old syntax.
+   You can also simply assign to the `re_syntax_options' variable.  */
+extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax);
+
+/* Compile the regular expression PATTERN, with length LENGTH
+   and syntax given by the global `re_syntax_options', into the buffer
+   BUFFER.  Return NULL if successful, and an error string if not.  */
+extern const char *re_compile_pattern (const char *__pattern, size_t __length,
+                                      struct re_pattern_buffer *__buffer);
+
+
+/* Compile a fastmap for the compiled pattern in BUFFER; used to
+   accelerate searches.  Return 0 if successful and -2 if was an
+   internal error.  */
+extern int re_compile_fastmap (struct re_pattern_buffer *__buffer);
+
+
+/* Search in the string STRING (with length LENGTH) for the pattern
+   compiled into BUFFER.  Start searching at position START, for RANGE
+   characters.  Return the starting position of the match, -1 for no
+   match, or -2 for an internal error.  Also return register
+   information in REGS (if REGS and BUFFER->no_sub are nonzero).  */
+extern regoff_t re_search (struct re_pattern_buffer *__buffer,
+                          const char *__string, __re_idx_t __length,
+                          __re_idx_t __start, regoff_t __range,
+                          struct re_registers *__regs);
+
+
+/* Like `re_search', but search in the concatenation of STRING1 and
+   STRING2.  Also, stop searching at index START + STOP.  */
+extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer,
+                            const char *__string1, __re_idx_t __length1,
+                            const char *__string2, __re_idx_t __length2,
+                            __re_idx_t __start, regoff_t __range,
+                            struct re_registers *__regs,
+                            __re_idx_t __stop);
+
+
+/* Like `re_search', but return how many characters in STRING the regexp
+   in BUFFER matched, starting at position START.  */
+extern regoff_t re_match (struct re_pattern_buffer *__buffer,
+                         const char *__string, __re_idx_t __length,
+                         __re_idx_t __start, struct re_registers *__regs);
+
+
+/* Relates to `re_match' as `re_search_2' relates to `re_search'.  */
+extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer,
+                           const char *__string1, __re_idx_t __length1,
+                           const char *__string2, __re_idx_t __length2,
+                           __re_idx_t __start, struct re_registers *__regs,
+                           __re_idx_t __stop);
+
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+   ENDS.  Subsequent matches using BUFFER and REGS will use this memory
+   for recording register information.  STARTS and ENDS must be
+   allocated with malloc, and must each be at least `NUM_REGS * sizeof
+   (regoff_t)' bytes long.
+
+   If NUM_REGS == 0, then subsequent matches should allocate their own
+   register data.
+
+   Unless this function is called, the first search or match using
+   PATTERN_BUFFER will allocate its own register data, without
+   freeing the old data.  */
+extern void re_set_registers (struct re_pattern_buffer *__buffer,
+                             struct re_registers *__regs,
+                             __re_size_t __num_regs,
+                             regoff_t *__starts, regoff_t *__ends);
+
+#if defined _REGEX_RE_COMP || defined _LIBC
+# ifndef _CRAY
+/* 4.2 bsd compatibility.  */
+extern char *re_comp (const char *);
+extern int re_exec (const char *);
+# endif
+#endif
+
+/* GCC 2.95 and later have "__restrict"; C99 compilers have
+   "restrict", and "configure" may have defined "restrict".
+   Other compilers use __restrict, __restrict__, and _Restrict, and
+   'configure' might #define 'restrict' to those words, so pick a
+   different name.  */
+#ifndef _Restrict_
+# if 199901L <= __STDC_VERSION__
+#  define _Restrict_ restrict
+# elif 2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)
+#  define _Restrict_ __restrict
+# else
+#  define _Restrict_
+# endif
+#endif
+/* gcc 3.1 and up support the [restrict] syntax.  Don't trust
+   sys/cdefs.h's definition of __restrict_arr, though, as it
+   mishandles gcc -ansi -pedantic.  */
+#ifndef _Restrict_arr_
+# if ((199901L <= __STDC_VERSION__                                     \
+       || ((3 < __GNUC__ || (3 == __GNUC__ && 1 <= __GNUC_MINOR__))    \
+          && !__STRICT_ANSI__))                                        \
+      && !defined __GNUG__)
+#  define _Restrict_arr_ _Restrict_
+# else
+#  define _Restrict_arr_
+# endif
+#endif
+
+/* POSIX compatibility.  */
+extern int regcomp (regex_t *_Restrict_ __preg,
+                   const char *_Restrict_ __pattern,
+                   int __cflags);
+
+extern int regexec (const regex_t *_Restrict_ __preg,
+                   const char *_Restrict_ __string, size_t __nmatch,
+                   regmatch_t __pmatch[_Restrict_arr_],
+                   int __eflags);
+
+extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg,
+                       char *_Restrict_ __errbuf, size_t __errbuf_size);
+
+extern void regfree (regex_t *__preg);
+
+
+#ifdef __cplusplus
+}
+#endif /* C++ */
+
+#endif /* regex.h */
diff --git a/grub-core/gnulib/regex_internal.c b/grub-core/gnulib/regex_internal.c
new file mode 100644 (file)
index 0000000..378b767
--- /dev/null
@@ -0,0 +1,1740 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
+   Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
+
+   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+static void re_string_construct_common (const char *str, Idx len,
+                                       re_string_t *pstr,
+                                       RE_TRANSLATE_TYPE trans, bool icase,
+                                       const re_dfa_t *dfa) internal_function;
+static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa,
+                                         const re_node_set *nodes,
+                                         re_hashval_t hash) internal_function;
+static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
+                                         const re_node_set *nodes,
+                                         unsigned int context,
+                                         re_hashval_t hash) internal_function;
+\f
+/* Functions for string operation.  */
+
+/* This function allocate the buffers.  It is necessary to call
+   re_string_reconstruct before using the object.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len,
+                   RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
+{
+  reg_errcode_t ret;
+  Idx init_buf_len;
+
+  /* Ensure at least one character fits into the buffers.  */
+  if (init_len < dfa->mb_cur_max)
+    init_len = dfa->mb_cur_max;
+  init_buf_len = (len + 1 < init_len) ? len + 1: init_len;
+  re_string_construct_common (str, len, pstr, trans, icase, dfa);
+
+  ret = re_string_realloc_buffers (pstr, init_buf_len);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+
+  pstr->word_char = dfa->word_char;
+  pstr->word_ops_used = dfa->word_ops_used;
+  pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
+  pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len;
+  pstr->valid_raw_len = pstr->valid_len;
+  return REG_NOERROR;
+}
+
+/* This function allocate the buffers, and initialize them.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_string_construct (re_string_t *pstr, const char *str, Idx len,
+                    RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
+{
+  reg_errcode_t ret;
+  memset (pstr, '\0', sizeof (re_string_t));
+  re_string_construct_common (str, len, pstr, trans, icase, dfa);
+
+  if (len > 0)
+    {
+      ret = re_string_realloc_buffers (pstr, len + 1);
+      if (BE (ret != REG_NOERROR, 0))
+       return ret;
+    }
+  pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
+
+  if (icase)
+    {
+#ifdef RE_ENABLE_I18N
+      if (dfa->mb_cur_max > 1)
+       {
+         while (1)
+           {
+             ret = build_wcs_upper_buffer (pstr);
+             if (BE (ret != REG_NOERROR, 0))
+               return ret;
+             if (pstr->valid_raw_len >= len)
+               break;
+             if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
+               break;
+             ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
+             if (BE (ret != REG_NOERROR, 0))
+               return ret;
+           }
+       }
+      else
+#endif /* RE_ENABLE_I18N  */
+       build_upper_buffer (pstr);
+    }
+  else
+    {
+#ifdef RE_ENABLE_I18N
+      if (dfa->mb_cur_max > 1)
+       build_wcs_buffer (pstr);
+      else
+#endif /* RE_ENABLE_I18N  */
+       {
+         if (trans != NULL)
+           re_string_translate_buffer (pstr);
+         else
+           {
+             pstr->valid_len = pstr->bufs_len;
+             pstr->valid_raw_len = pstr->bufs_len;
+           }
+       }
+    }
+
+  return REG_NOERROR;
+}
+
+/* Helper functions for re_string_allocate, and re_string_construct.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)
+{
+#ifdef RE_ENABLE_I18N
+  if (pstr->mb_cur_max > 1)
+    {
+      wint_t *new_wcs;
+
+      /* Avoid overflow.  */
+      size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx));
+      if (BE (SIZE_MAX / max_object_size < new_buf_len, 0))
+       return REG_ESPACE;
+
+      new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
+      if (BE (new_wcs == NULL, 0))
+       return REG_ESPACE;
+      pstr->wcs = new_wcs;
+      if (pstr->offsets != NULL)
+       {
+         Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len);
+         if (BE (new_offsets == NULL, 0))
+           return REG_ESPACE;
+         pstr->offsets = new_offsets;
+       }
+    }
+#endif /* RE_ENABLE_I18N  */
+  if (pstr->mbs_allocated)
+    {
+      unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char,
+                                          new_buf_len);
+      if (BE (new_mbs == NULL, 0))
+       return REG_ESPACE;
+      pstr->mbs = new_mbs;
+    }
+  pstr->bufs_len = new_buf_len;
+  return REG_NOERROR;
+}
+
+
+static void
+internal_function
+re_string_construct_common (const char *str, Idx len, re_string_t *pstr,
+                           RE_TRANSLATE_TYPE trans, bool icase,
+                           const re_dfa_t *dfa)
+{
+  pstr->raw_mbs = (const unsigned char *) str;
+  pstr->len = len;
+  pstr->raw_len = len;
+  pstr->trans = trans;
+  pstr->icase = icase;
+  pstr->mbs_allocated = (trans != NULL || icase);
+  pstr->mb_cur_max = dfa->mb_cur_max;
+  pstr->is_utf8 = dfa->is_utf8;
+  pstr->map_notascii = dfa->map_notascii;
+  pstr->stop = pstr->len;
+  pstr->raw_stop = pstr->stop;
+}
+
+#ifdef RE_ENABLE_I18N
+
+/* Build wide character buffer PSTR->WCS.
+   If the byte sequence of the string are:
+     <mb1>(0), <mb1>(1), <mb2>(0), <mb2>(1), <sb3>
+   Then wide character buffer will be:
+     <wc1>   , WEOF    , <wc2>   , WEOF    , <wc3>
+   We use WEOF for padding, they indicate that the position isn't
+   a first byte of a multibyte character.
+
+   Note that this function assumes PSTR->VALID_LEN elements are already
+   built and starts from PSTR->VALID_LEN.  */
+
+static void
+internal_function
+build_wcs_buffer (re_string_t *pstr)
+{
+#ifdef _LIBC
+  unsigned char buf[MB_LEN_MAX];
+  assert (MB_LEN_MAX >= pstr->mb_cur_max);
+#else
+  unsigned char buf[64];
+#endif
+  mbstate_t prev_st;
+  Idx byte_idx, end_idx, remain_len;
+  size_t mbclen;
+
+  /* Build the buffers from pstr->valid_len to either pstr->len or
+     pstr->bufs_len.  */
+  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+  for (byte_idx = pstr->valid_len; byte_idx < end_idx;)
+    {
+      wchar_t wc;
+      const char *p;
+
+      remain_len = end_idx - byte_idx;
+      prev_st = pstr->cur_state;
+      /* Apply the translation if we need.  */
+      if (BE (pstr->trans != NULL, 0))
+       {
+         int i, ch;
+
+         for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
+           {
+             ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i];
+             buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch];
+           }
+         p = (const char *) buf;
+       }
+      else
+       p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx;
+      mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
+      if (BE (mbclen == (size_t) -2, 0))
+       {
+         /* The buffer doesn't have enough space, finish to build.  */
+         pstr->cur_state = prev_st;
+         break;
+       }
+      else if (BE (mbclen == (size_t) -1 || mbclen == 0, 0))
+       {
+         /* We treat these cases as a singlebyte character.  */
+         mbclen = 1;
+         wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
+         if (BE (pstr->trans != NULL, 0))
+           wc = pstr->trans[wc];
+         pstr->cur_state = prev_st;
+       }
+
+      /* Write wide character and padding.  */
+      pstr->wcs[byte_idx++] = wc;
+      /* Write paddings.  */
+      for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
+       pstr->wcs[byte_idx++] = WEOF;
+    }
+  pstr->valid_len = byte_idx;
+  pstr->valid_raw_len = byte_idx;
+}
+
+/* Build wide character buffer PSTR->WCS like build_wcs_buffer,
+   but for REG_ICASE.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+build_wcs_upper_buffer (re_string_t *pstr)
+{
+  mbstate_t prev_st;
+  Idx src_idx, byte_idx, end_idx, remain_len;
+  size_t mbclen;
+#ifdef _LIBC
+  char buf[MB_LEN_MAX];
+  assert (MB_LEN_MAX >= pstr->mb_cur_max);
+#else
+  char buf[64];
+#endif
+
+  byte_idx = pstr->valid_len;
+  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+
+  /* The following optimization assumes that ASCII characters can be
+     mapped to wide characters with a simple cast.  */
+  if (! pstr->map_notascii && pstr->trans == NULL && !pstr->offsets_needed)
+    {
+      while (byte_idx < end_idx)
+       {
+         wchar_t wc;
+
+         if (isascii (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx])
+             && mbsinit (&pstr->cur_state))
+           {
+             /* In case of a singlebyte character.  */
+             pstr->mbs[byte_idx]
+               = toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]);
+             /* The next step uses the assumption that wchar_t is encoded
+                ASCII-safe: all ASCII values can be converted like this.  */
+             pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx];
+             ++byte_idx;
+             continue;
+           }
+
+         remain_len = end_idx - byte_idx;
+         prev_st = pstr->cur_state;
+         mbclen = __mbrtowc (&wc,
+                             ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
+                              + byte_idx), remain_len, &pstr->cur_state);
+         if (BE (mbclen < (size_t) -2, 1))
+           {
+             wchar_t wcu = wc;
+             if (iswlower (wc))
+               {
+                 size_t mbcdlen;
+
+                 wcu = towupper (wc);
+                 mbcdlen = wcrtomb (buf, wcu, &prev_st);
+                 if (BE (mbclen == mbcdlen, 1))
+                   memcpy (pstr->mbs + byte_idx, buf, mbclen);
+                 else
+                   {
+                     src_idx = byte_idx;
+                     goto offsets_needed;
+                   }
+               }
+             else
+               memcpy (pstr->mbs + byte_idx,
+                       pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen);
+             pstr->wcs[byte_idx++] = wcu;
+             /* Write paddings.  */
+             for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
+               pstr->wcs[byte_idx++] = WEOF;
+           }
+         else if (mbclen == (size_t) -1 || mbclen == 0)
+           {
+             /* It is an invalid character or '\0'.  Just use the byte.  */
+             int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
+             pstr->mbs[byte_idx] = ch;
+             /* And also cast it to wide char.  */
+             pstr->wcs[byte_idx++] = (wchar_t) ch;
+             if (BE (mbclen == (size_t) -1, 0))
+               pstr->cur_state = prev_st;
+           }
+         else
+           {
+             /* The buffer doesn't have enough space, finish to build.  */
+             pstr->cur_state = prev_st;
+             break;
+           }
+       }
+      pstr->valid_len = byte_idx;
+      pstr->valid_raw_len = byte_idx;
+      return REG_NOERROR;
+    }
+  else
+    for (src_idx = pstr->valid_raw_len; byte_idx < end_idx;)
+      {
+       wchar_t wc;
+       const char *p;
+      offsets_needed:
+       remain_len = end_idx - byte_idx;
+       prev_st = pstr->cur_state;
+       if (BE (pstr->trans != NULL, 0))
+         {
+           int i, ch;
+
+           for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
+             {
+               ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i];
+               buf[i] = pstr->trans[ch];
+             }
+           p = (const char *) buf;
+         }
+       else
+         p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;
+       mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
+       if (BE (mbclen < (size_t) -2, 1))
+         {
+           wchar_t wcu = wc;
+           if (iswlower (wc))
+             {
+               size_t mbcdlen;
+
+               wcu = towupper (wc);
+               mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st);
+               if (BE (mbclen == mbcdlen, 1))
+                 memcpy (pstr->mbs + byte_idx, buf, mbclen);
+               else if (mbcdlen != (size_t) -1)
+                 {
+                   size_t i;
+
+                   if (byte_idx + mbcdlen > pstr->bufs_len)
+                     {
+                       pstr->cur_state = prev_st;
+                       break;
+                     }
+
+                   if (pstr->offsets == NULL)
+                     {
+                       pstr->offsets = re_malloc (Idx, pstr->bufs_len);
+
+                       if (pstr->offsets == NULL)
+                         return REG_ESPACE;
+                     }
+                   if (!pstr->offsets_needed)
+                     {
+                       for (i = 0; i < (size_t) byte_idx; ++i)
+                         pstr->offsets[i] = i;
+                       pstr->offsets_needed = 1;
+                     }
+
+                   memcpy (pstr->mbs + byte_idx, buf, mbcdlen);
+                   pstr->wcs[byte_idx] = wcu;
+                   pstr->offsets[byte_idx] = src_idx;
+                   for (i = 1; i < mbcdlen; ++i)
+                     {
+                       pstr->offsets[byte_idx + i]
+                         = src_idx + (i < mbclen ? i : mbclen - 1);
+                       pstr->wcs[byte_idx + i] = WEOF;
+                     }
+                   pstr->len += mbcdlen - mbclen;
+                   if (pstr->raw_stop > src_idx)
+                     pstr->stop += mbcdlen - mbclen;
+                   end_idx = (pstr->bufs_len > pstr->len)
+                             ? pstr->len : pstr->bufs_len;
+                   byte_idx += mbcdlen;
+                   src_idx += mbclen;
+                   continue;
+                 }
+               else
+                 memcpy (pstr->mbs + byte_idx, p, mbclen);
+             }
+           else
+             memcpy (pstr->mbs + byte_idx, p, mbclen);
+
+           if (BE (pstr->offsets_needed != 0, 0))
+             {
+               size_t i;
+               for (i = 0; i < mbclen; ++i)
+                 pstr->offsets[byte_idx + i] = src_idx + i;
+             }
+           src_idx += mbclen;
+
+           pstr->wcs[byte_idx++] = wcu;
+           /* Write paddings.  */
+           for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
+             pstr->wcs[byte_idx++] = WEOF;
+         }
+       else if (mbclen == (size_t) -1 || mbclen == 0)
+         {
+           /* It is an invalid character or '\0'.  Just use the byte.  */
+           int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx];
+
+           if (BE (pstr->trans != NULL, 0))
+             ch = pstr->trans [ch];
+           pstr->mbs[byte_idx] = ch;
+
+           if (BE (pstr->offsets_needed != 0, 0))
+             pstr->offsets[byte_idx] = src_idx;
+           ++src_idx;
+
+           /* And also cast it to wide char.  */
+           pstr->wcs[byte_idx++] = (wchar_t) ch;
+           if (BE (mbclen == (size_t) -1, 0))
+             pstr->cur_state = prev_st;
+         }
+       else
+         {
+           /* The buffer doesn't have enough space, finish to build.  */
+           pstr->cur_state = prev_st;
+           break;
+         }
+      }
+  pstr->valid_len = byte_idx;
+  pstr->valid_raw_len = src_idx;
+  return REG_NOERROR;
+}
+
+/* Skip characters until the index becomes greater than NEW_RAW_IDX.
+   Return the index.  */
+
+static Idx
+internal_function
+re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc)
+{
+  mbstate_t prev_st;
+  Idx rawbuf_idx;
+  size_t mbclen;
+  wint_t wc = WEOF;
+
+  /* Skip the characters which are not necessary to check.  */
+  for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len;
+       rawbuf_idx < new_raw_idx;)
+    {
+      wchar_t wc2;
+      Idx remain_len;
+      remain_len = pstr->len - rawbuf_idx;
+      prev_st = pstr->cur_state;
+      mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx,
+                         remain_len, &pstr->cur_state);
+      if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
+       {
+         /* We treat these cases as a single byte character.  */
+         if (mbclen == 0 || remain_len == 0)
+           wc = L'\0';
+         else
+           wc = *(unsigned char *) (pstr->raw_mbs + rawbuf_idx);
+         mbclen = 1;
+         pstr->cur_state = prev_st;
+       }
+      else
+       wc = wc2;
+      /* Then proceed the next character.  */
+      rawbuf_idx += mbclen;
+    }
+  *last_wc = wc;
+  return rawbuf_idx;
+}
+#endif /* RE_ENABLE_I18N  */
+
+/* Build the buffer PSTR->MBS, and apply the translation if we need.
+   This function is used in case of REG_ICASE.  */
+
+static void
+internal_function
+build_upper_buffer (re_string_t *pstr)
+{
+  Idx char_idx, end_idx;
+  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+
+  for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx)
+    {
+      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx];
+      if (BE (pstr->trans != NULL, 0))
+       ch = pstr->trans[ch];
+      if (islower (ch))
+       pstr->mbs[char_idx] = toupper (ch);
+      else
+       pstr->mbs[char_idx] = ch;
+    }
+  pstr->valid_len = char_idx;
+  pstr->valid_raw_len = char_idx;
+}
+
+/* Apply TRANS to the buffer in PSTR.  */
+
+static void
+internal_function
+re_string_translate_buffer (re_string_t *pstr)
+{
+  Idx buf_idx, end_idx;
+  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+
+  for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx)
+    {
+      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + buf_idx];
+      pstr->mbs[buf_idx] = pstr->trans[ch];
+    }
+
+  pstr->valid_len = buf_idx;
+  pstr->valid_raw_len = buf_idx;
+}
+
+/* This function re-construct the buffers.
+   Concretely, convert to wide character in case of pstr->mb_cur_max > 1,
+   convert to upper case in case of REG_ICASE, apply translation.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
+{
+  Idx offset;
+
+  if (BE (pstr->raw_mbs_idx <= idx, 0))
+    offset = idx - pstr->raw_mbs_idx;
+  else
+    {
+      /* Reset buffer.  */
+#ifdef RE_ENABLE_I18N
+      if (pstr->mb_cur_max > 1)
+       memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
+#endif /* RE_ENABLE_I18N */
+      pstr->len = pstr->raw_len;
+      pstr->stop = pstr->raw_stop;
+      pstr->valid_len = 0;
+      pstr->raw_mbs_idx = 0;
+      pstr->valid_raw_len = 0;
+      pstr->offsets_needed = 0;
+      pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
+                          : CONTEXT_NEWLINE | CONTEXT_BEGBUF);
+      if (!pstr->mbs_allocated)
+       pstr->mbs = (unsigned char *) pstr->raw_mbs;
+      offset = idx;
+    }
+
+  if (BE (offset != 0, 1))
+    {
+      /* Should the already checked characters be kept?  */
+      if (BE (offset < pstr->valid_raw_len, 1))
+       {
+         /* Yes, move them to the front of the buffer.  */
+#ifdef RE_ENABLE_I18N
+         if (BE (pstr->offsets_needed, 0))
+           {
+             Idx low = 0, high = pstr->valid_len, mid;
+             do
+               {
+                 mid = (high + low) / 2;
+                 if (pstr->offsets[mid] > offset)
+                   high = mid;
+                 else if (pstr->offsets[mid] < offset)
+                   low = mid + 1;
+                 else
+                   break;
+               }
+             while (low < high);
+             if (pstr->offsets[mid] < offset)
+               ++mid;
+             pstr->tip_context = re_string_context_at (pstr, mid - 1,
+                                                       eflags);
+             /* This can be quite complicated, so handle specially
+                only the common and easy case where the character with
+                different length representation of lower and upper
+                case is present at or after offset.  */
+             if (pstr->valid_len > offset
+                 && mid == offset && pstr->offsets[mid] == offset)
+               {
+                 memmove (pstr->wcs, pstr->wcs + offset,
+                          (pstr->valid_len - offset) * sizeof (wint_t));
+                 memmove (pstr->mbs, pstr->mbs + offset, pstr->valid_len - offset);
+                 pstr->valid_len -= offset;
+                 pstr->valid_raw_len -= offset;
+                 for (low = 0; low < pstr->valid_len; low++)
+                   pstr->offsets[low] = pstr->offsets[low + offset] - offset;
+               }
+             else
+               {
+                 /* Otherwise, just find out how long the partial multibyte
+                    character at offset is and fill it with WEOF/255.  */
+                 pstr->len = pstr->raw_len - idx + offset;
+                 pstr->stop = pstr->raw_stop - idx + offset;
+                 pstr->offsets_needed = 0;
+                 while (mid > 0 && pstr->offsets[mid - 1] == offset)
+                   --mid;
+                 while (mid < pstr->valid_len)
+                   if (pstr->wcs[mid] != WEOF)
+                     break;
+                   else
+                     ++mid;
+                 if (mid == pstr->valid_len)
+                   pstr->valid_len = 0;
+                 else
+                   {
+                     pstr->valid_len = pstr->offsets[mid] - offset;
+                     if (pstr->valid_len)
+                       {
+                         for (low = 0; low < pstr->valid_len; ++low)
+                           pstr->wcs[low] = WEOF;
+                         memset (pstr->mbs, 255, pstr->valid_len);
+                       }
+                   }
+                 pstr->valid_raw_len = pstr->valid_len;
+               }
+           }
+         else
+#endif
+           {
+             pstr->tip_context = re_string_context_at (pstr, offset - 1,
+                                                       eflags);
+#ifdef RE_ENABLE_I18N
+             if (pstr->mb_cur_max > 1)
+               memmove (pstr->wcs, pstr->wcs + offset,
+                        (pstr->valid_len - offset) * sizeof (wint_t));
+#endif /* RE_ENABLE_I18N */
+             if (BE (pstr->mbs_allocated, 0))
+               memmove (pstr->mbs, pstr->mbs + offset,
+                        pstr->valid_len - offset);
+             pstr->valid_len -= offset;
+             pstr->valid_raw_len -= offset;
+#if DEBUG
+             assert (pstr->valid_len > 0);
+#endif
+           }
+       }
+      else
+       {
+#ifdef RE_ENABLE_I18N
+         /* No, skip all characters until IDX.  */
+         Idx prev_valid_len = pstr->valid_len;
+
+         if (BE (pstr->offsets_needed, 0))
+           {
+             pstr->len = pstr->raw_len - idx + offset;
+             pstr->stop = pstr->raw_stop - idx + offset;
+             pstr->offsets_needed = 0;
+           }
+#endif
+         pstr->valid_len = 0;
+#ifdef RE_ENABLE_I18N
+         if (pstr->mb_cur_max > 1)
+           {
+             Idx wcs_idx;
+             wint_t wc = WEOF;
+
+             if (pstr->is_utf8)
+               {
+                 const unsigned char *raw, *p, *end;
+
+                 /* Special case UTF-8.  Multi-byte chars start with any
+                    byte other than 0x80 - 0xbf.  */
+                 raw = pstr->raw_mbs + pstr->raw_mbs_idx;
+                 end = raw + (offset - pstr->mb_cur_max);
+                 if (end < pstr->raw_mbs)
+                   end = pstr->raw_mbs;
+                 p = raw + offset - 1;
+#ifdef _LIBC
+                 /* We know the wchar_t encoding is UCS4, so for the simple
+                    case, ASCII characters, skip the conversion step.  */
+                 if (isascii (*p) && BE (pstr->trans == NULL, 1))
+                   {
+                     memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
+                     /* pstr->valid_len = 0; */
+                     wc = (wchar_t) *p;
+                   }
+                 else
+#endif
+                   for (; p >= end; --p)
+                     if ((*p & 0xc0) != 0x80)
+                       {
+                         mbstate_t cur_state;
+                         wchar_t wc2;
+                         Idx mlen = raw + pstr->len - p;
+                         unsigned char buf[6];
+                         size_t mbclen;
+
+                         if (BE (pstr->trans != NULL, 0))
+                           {
+                             int i = mlen < 6 ? mlen : 6;
+                             while (--i >= 0)
+                               buf[i] = pstr->trans[p[i]];
+                           }
+                         /* XXX Don't use mbrtowc, we know which conversion
+                            to use (UTF-8 -> UCS4).  */
+                         memset (&cur_state, 0, sizeof (cur_state));
+                         mbclen = __mbrtowc (&wc2, (const char *) p, mlen,
+                                             &cur_state);
+                         if (raw + offset - p <= mbclen
+                             && mbclen < (size_t) -2)
+                           {
+                             memset (&pstr->cur_state, '\0',
+                                     sizeof (mbstate_t));
+                             pstr->valid_len = mbclen - (raw + offset - p);
+                             wc = wc2;
+                           }
+                         break;
+                       }
+               }
+
+             if (wc == WEOF)
+               pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx;
+             if (wc == WEOF)
+               pstr->tip_context
+                 = re_string_context_at (pstr, prev_valid_len - 1, eflags);
+             else
+               pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0)
+                                     && IS_WIDE_WORD_CHAR (wc))
+                                    ? CONTEXT_WORD
+                                    : ((IS_WIDE_NEWLINE (wc)
+                                        && pstr->newline_anchor)
+                                       ? CONTEXT_NEWLINE : 0));
+             if (BE (pstr->valid_len, 0))
+               {
+                 for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
+                   pstr->wcs[wcs_idx] = WEOF;
+                 if (pstr->mbs_allocated)
+                   memset (pstr->mbs, 255, pstr->valid_len);
+               }
+             pstr->valid_raw_len = pstr->valid_len;
+           }
+         else
+#endif /* RE_ENABLE_I18N */
+           {
+             int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1];
+             pstr->valid_raw_len = 0;
+             if (pstr->trans)
+               c = pstr->trans[c];
+             pstr->tip_context = (bitset_contain (pstr->word_char, c)
+                                  ? CONTEXT_WORD
+                                  : ((IS_NEWLINE (c) && pstr->newline_anchor)
+                                     ? CONTEXT_NEWLINE : 0));
+           }
+       }
+      if (!BE (pstr->mbs_allocated, 0))
+       pstr->mbs += offset;
+    }
+  pstr->raw_mbs_idx = idx;
+  pstr->len -= offset;
+  pstr->stop -= offset;
+
+  /* Then build the buffers.  */
+#ifdef RE_ENABLE_I18N
+  if (pstr->mb_cur_max > 1)
+    {
+      if (pstr->icase)
+       {
+         reg_errcode_t ret = build_wcs_upper_buffer (pstr);
+         if (BE (ret != REG_NOERROR, 0))
+           return ret;
+       }
+      else
+       build_wcs_buffer (pstr);
+    }
+  else
+#endif /* RE_ENABLE_I18N */
+    if (BE (pstr->mbs_allocated, 0))
+      {
+       if (pstr->icase)
+         build_upper_buffer (pstr);
+       else if (pstr->trans != NULL)
+         re_string_translate_buffer (pstr);
+      }
+    else
+      pstr->valid_len = pstr->len;
+
+  pstr->cur_idx = 0;
+  return REG_NOERROR;
+}
+
+static unsigned char
+internal_function __attribute ((pure))
+re_string_peek_byte_case (const re_string_t *pstr, Idx idx)
+{
+  int ch;
+  Idx off;
+
+  /* Handle the common (easiest) cases first.  */
+  if (BE (!pstr->mbs_allocated, 1))
+    return re_string_peek_byte (pstr, idx);
+
+#ifdef RE_ENABLE_I18N
+  if (pstr->mb_cur_max > 1
+      && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
+    return re_string_peek_byte (pstr, idx);
+#endif
+
+  off = pstr->cur_idx + idx;
+#ifdef RE_ENABLE_I18N
+  if (pstr->offsets_needed)
+    off = pstr->offsets[off];
+#endif
+
+  ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
+
+#ifdef RE_ENABLE_I18N
+  /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I
+     this function returns CAPITAL LETTER I instead of first byte of
+     DOTLESS SMALL LETTER I.  The latter would confuse the parser,
+     since peek_byte_case doesn't advance cur_idx in any way.  */
+  if (pstr->offsets_needed && !isascii (ch))
+    return re_string_peek_byte (pstr, idx);
+#endif
+
+  return ch;
+}
+
+static unsigned char
+internal_function __attribute ((pure))
+re_string_fetch_byte_case (re_string_t *pstr)
+{
+  if (BE (!pstr->mbs_allocated, 1))
+    return re_string_fetch_byte (pstr);
+
+#ifdef RE_ENABLE_I18N
+  if (pstr->offsets_needed)
+    {
+      Idx off;
+      int ch;
+
+      /* For tr_TR.UTF-8 [[:islower:]] there is
+        [[: CAPITAL LETTER I WITH DOT lower:]] in mbs.  Skip
+        in that case the whole multi-byte character and return
+        the original letter.  On the other side, with
+        [[: DOTLESS SMALL LETTER I return [[:I, as doing
+        anything else would complicate things too much.  */
+
+      if (!re_string_first_byte (pstr, pstr->cur_idx))
+       return re_string_fetch_byte (pstr);
+
+      off = pstr->offsets[pstr->cur_idx];
+      ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
+
+      if (! isascii (ch))
+       return re_string_fetch_byte (pstr);
+
+      re_string_skip_bytes (pstr,
+                           re_string_char_size_at (pstr, pstr->cur_idx));
+      return ch;
+    }
+#endif
+
+  return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++];
+}
+
+static void
+internal_function
+re_string_destruct (re_string_t *pstr)
+{
+#ifdef RE_ENABLE_I18N
+  re_free (pstr->wcs);
+  re_free (pstr->offsets);
+#endif /* RE_ENABLE_I18N  */
+  if (pstr->mbs_allocated)
+    re_free (pstr->mbs);
+}
+
+/* Return the context at IDX in INPUT.  */
+
+static unsigned int
+internal_function
+re_string_context_at (const re_string_t *input, Idx idx, int eflags)
+{
+  int c;
+  if (BE (! REG_VALID_INDEX (idx), 0))
+    /* In this case, we use the value stored in input->tip_context,
+       since we can't know the character in input->mbs[-1] here.  */
+    return input->tip_context;
+  if (BE (idx == input->len, 0))
+    return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
+           : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
+#ifdef RE_ENABLE_I18N
+  if (input->mb_cur_max > 1)
+    {
+      wint_t wc;
+      Idx wc_idx = idx;
+      while(input->wcs[wc_idx] == WEOF)
+       {
+#ifdef DEBUG
+         /* It must not happen.  */
+         assert (REG_VALID_INDEX (wc_idx));
+#endif
+         --wc_idx;
+         if (! REG_VALID_INDEX (wc_idx))
+           return input->tip_context;
+       }
+      wc = input->wcs[wc_idx];
+      if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc))
+       return CONTEXT_WORD;
+      return (IS_WIDE_NEWLINE (wc) && input->newline_anchor
+             ? CONTEXT_NEWLINE : 0);
+    }
+  else
+#endif
+    {
+      c = re_string_byte_at (input, idx);
+      if (bitset_contain (input->word_char, c))
+       return CONTEXT_WORD;
+      return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0;
+    }
+}
+\f
+/* Functions for set operation.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_node_set_alloc (re_node_set *set, Idx size)
+{
+  set->alloc = size;
+  set->nelem = 0;
+  set->elems = re_malloc (Idx, size);
+  if (BE (set->elems == NULL, 0))
+    return REG_ESPACE;
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_node_set_init_1 (re_node_set *set, Idx elem)
+{
+  set->alloc = 1;
+  set->nelem = 1;
+  set->elems = re_malloc (Idx, 1);
+  if (BE (set->elems == NULL, 0))
+    {
+      set->alloc = set->nelem = 0;
+      return REG_ESPACE;
+    }
+  set->elems[0] = elem;
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2)
+{
+  set->alloc = 2;
+  set->elems = re_malloc (Idx, 2);
+  if (BE (set->elems == NULL, 0))
+    return REG_ESPACE;
+  if (elem1 == elem2)
+    {
+      set->nelem = 1;
+      set->elems[0] = elem1;
+    }
+  else
+    {
+      set->nelem = 2;
+      if (elem1 < elem2)
+       {
+         set->elems[0] = elem1;
+         set->elems[1] = elem2;
+       }
+      else
+       {
+         set->elems[0] = elem2;
+         set->elems[1] = elem1;
+       }
+    }
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
+{
+  dest->nelem = src->nelem;
+  if (src->nelem > 0)
+    {
+      dest->alloc = dest->nelem;
+      dest->elems = re_malloc (Idx, dest->alloc);
+      if (BE (dest->elems == NULL, 0))
+       {
+         dest->alloc = dest->nelem = 0;
+         return REG_ESPACE;
+       }
+      memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));
+    }
+  else
+    re_node_set_init_empty (dest);
+  return REG_NOERROR;
+}
+
+/* Calculate the intersection of the sets SRC1 and SRC2. And merge it to
+   DEST. Return value indicate the error code or REG_NOERROR if succeeded.
+   Note: We assume dest->elems is NULL, when dest->alloc is 0.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
+                          const re_node_set *src2)
+{
+  Idx i1, i2, is, id, delta, sbase;
+  if (src1->nelem == 0 || src2->nelem == 0)
+    return REG_NOERROR;
+
+  /* We need dest->nelem + 2 * elems_in_intersection; this is a
+     conservative estimate.  */
+  if (src1->nelem + src2->nelem + dest->nelem > dest->alloc)
+    {
+      Idx new_alloc = src1->nelem + src2->nelem + dest->alloc;
+      Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc);
+      if (BE (new_elems == NULL, 0))
+       return REG_ESPACE;
+      dest->elems = new_elems;
+      dest->alloc = new_alloc;
+    }
+
+  /* Find the items in the intersection of SRC1 and SRC2, and copy
+     into the top of DEST those that are not already in DEST itself.  */
+  sbase = dest->nelem + src1->nelem + src2->nelem;
+  i1 = src1->nelem - 1;
+  i2 = src2->nelem - 1;
+  id = dest->nelem - 1;
+  for (;;)
+    {
+      if (src1->elems[i1] == src2->elems[i2])
+       {
+         /* Try to find the item in DEST.  Maybe we could binary search?  */
+         while (REG_VALID_INDEX (id) && dest->elems[id] > src1->elems[i1])
+           --id;
+
+          if (! REG_VALID_INDEX (id) || dest->elems[id] != src1->elems[i1])
+            dest->elems[--sbase] = src1->elems[i1];
+
+         if (! REG_VALID_INDEX (--i1) || ! REG_VALID_INDEX (--i2))
+           break;
+       }
+
+      /* Lower the highest of the two items.  */
+      else if (src1->elems[i1] < src2->elems[i2])
+       {
+         if (! REG_VALID_INDEX (--i2))
+           break;
+       }
+      else
+       {
+         if (! REG_VALID_INDEX (--i1))
+           break;
+       }
+    }
+
+  id = dest->nelem - 1;
+  is = dest->nelem + src1->nelem + src2->nelem - 1;
+  delta = is - sbase + 1;
+
+  /* Now copy.  When DELTA becomes zero, the remaining
+     DEST elements are already in place; this is more or
+     less the same loop that is in re_node_set_merge.  */
+  dest->nelem += delta;
+  if (delta > 0 && REG_VALID_INDEX (id))
+    for (;;)
+      {
+       if (dest->elems[is] > dest->elems[id])
+         {
+           /* Copy from the top.  */
+           dest->elems[id + delta--] = dest->elems[is--];
+           if (delta == 0)
+             break;
+         }
+       else
+         {
+           /* Slide from the bottom.  */
+           dest->elems[id + delta] = dest->elems[id];
+           if (! REG_VALID_INDEX (--id))
+             break;
+         }
+      }
+
+  /* Copy remaining SRC elements.  */
+  memcpy (dest->elems, dest->elems + sbase, delta * sizeof (Idx));
+
+  return REG_NOERROR;
+}
+
+/* Calculate the union set of the sets SRC1 and SRC2. And store it to
+   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
+                       const re_node_set *src2)
+{
+  Idx i1, i2, id;
+  if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0)
+    {
+      dest->alloc = src1->nelem + src2->nelem;
+      dest->elems = re_malloc (Idx, dest->alloc);
+      if (BE (dest->elems == NULL, 0))
+       return REG_ESPACE;
+    }
+  else
+    {
+      if (src1 != NULL && src1->nelem > 0)
+       return re_node_set_init_copy (dest, src1);
+      else if (src2 != NULL && src2->nelem > 0)
+       return re_node_set_init_copy (dest, src2);
+      else
+       re_node_set_init_empty (dest);
+      return REG_NOERROR;
+    }
+  for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;)
+    {
+      if (src1->elems[i1] > src2->elems[i2])
+       {
+         dest->elems[id++] = src2->elems[i2++];
+         continue;
+       }
+      if (src1->elems[i1] == src2->elems[i2])
+       ++i2;
+      dest->elems[id++] = src1->elems[i1++];
+    }
+  if (i1 < src1->nelem)
+    {
+      memcpy (dest->elems + id, src1->elems + i1,
+            (src1->nelem - i1) * sizeof (Idx));
+      id += src1->nelem - i1;
+    }
+  else if (i2 < src2->nelem)
+    {
+      memcpy (dest->elems + id, src2->elems + i2,
+            (src2->nelem - i2) * sizeof (Idx));
+      id += src2->nelem - i2;
+    }
+  dest->nelem = id;
+  return REG_NOERROR;
+}
+
+/* Calculate the union set of the sets DEST and SRC. And store it to
+   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_node_set_merge (re_node_set *dest, const re_node_set *src)
+{
+  Idx is, id, sbase, delta;
+  if (src == NULL || src->nelem == 0)
+    return REG_NOERROR;
+  if (dest->alloc < 2 * src->nelem + dest->nelem)
+    {
+      Idx new_alloc = 2 * (src->nelem + dest->alloc);
+      Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc);
+      if (BE (new_buffer == NULL, 0))
+       return REG_ESPACE;
+      dest->elems = new_buffer;
+      dest->alloc = new_alloc;
+    }
+
+  if (BE (dest->nelem == 0, 0))
+    {
+      dest->nelem = src->nelem;
+      memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));
+      return REG_NOERROR;
+    }
+
+  /* Copy into the top of DEST the items of SRC that are not
+     found in DEST.  Maybe we could binary search in DEST?  */
+  for (sbase = dest->nelem + 2 * src->nelem,
+       is = src->nelem - 1, id = dest->nelem - 1;
+       REG_VALID_INDEX (is) && REG_VALID_INDEX (id); )
+    {
+      if (dest->elems[id] == src->elems[is])
+       is--, id--;
+      else if (dest->elems[id] < src->elems[is])
+       dest->elems[--sbase] = src->elems[is--];
+      else /* if (dest->elems[id] > src->elems[is]) */
+       --id;
+    }
+
+  if (REG_VALID_INDEX (is))
+    {
+      /* If DEST is exhausted, the remaining items of SRC must be unique.  */
+      sbase -= is + 1;
+      memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (Idx));
+    }
+
+  id = dest->nelem - 1;
+  is = dest->nelem + 2 * src->nelem - 1;
+  delta = is - sbase + 1;
+  if (delta == 0)
+    return REG_NOERROR;
+
+  /* Now copy.  When DELTA becomes zero, the remaining
+     DEST elements are already in place.  */
+  dest->nelem += delta;
+  for (;;)
+    {
+      if (dest->elems[is] > dest->elems[id])
+       {
+         /* Copy from the top.  */
+         dest->elems[id + delta--] = dest->elems[is--];
+         if (delta == 0)
+           break;
+       }
+      else
+       {
+         /* Slide from the bottom.  */
+         dest->elems[id + delta] = dest->elems[id];
+         if (! REG_VALID_INDEX (--id))
+           {
+             /* Copy remaining SRC elements.  */
+             memcpy (dest->elems, dest->elems + sbase,
+                     delta * sizeof (Idx));
+             break;
+           }
+       }
+    }
+
+  return REG_NOERROR;
+}
+
+/* Insert the new element ELEM to the re_node_set* SET.
+   SET should not already have ELEM.
+   Return true if successful.  */
+
+static bool
+internal_function __attribute_warn_unused_result__
+re_node_set_insert (re_node_set *set, Idx elem)
+{
+  Idx idx;
+  /* In case the set is empty.  */
+  if (set->alloc == 0)
+    return BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1);
+
+  if (BE (set->nelem, 0) == 0)
+    {
+      /* We already guaranteed above that set->alloc != 0.  */
+      set->elems[0] = elem;
+      ++set->nelem;
+      return true;
+    }
+
+  /* Realloc if we need.  */
+  if (set->alloc == set->nelem)
+    {
+      Idx *new_elems;
+      set->alloc = set->alloc * 2;
+      new_elems = re_realloc (set->elems, Idx, set->alloc);
+      if (BE (new_elems == NULL, 0))
+       return false;
+      set->elems = new_elems;
+    }
+
+  /* Move the elements which follows the new element.  Test the
+     first element separately to skip a check in the inner loop.  */
+  if (elem < set->elems[0])
+    {
+      idx = 0;
+      for (idx = set->nelem; idx > 0; idx--)
+       set->elems[idx] = set->elems[idx - 1];
+    }
+  else
+    {
+      for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
+       set->elems[idx] = set->elems[idx - 1];
+    }
+
+  /* Insert the new element.  */
+  set->elems[idx] = elem;
+  ++set->nelem;
+  return true;
+}
+
+/* Insert the new element ELEM to the re_node_set* SET.
+   SET should not already have any element greater than or equal to ELEM.
+   Return true if successful.  */
+
+static bool
+internal_function __attribute_warn_unused_result__
+re_node_set_insert_last (re_node_set *set, Idx elem)
+{
+  /* Realloc if we need.  */
+  if (set->alloc == set->nelem)
+    {
+      Idx *new_elems;
+      set->alloc = (set->alloc + 1) * 2;
+      new_elems = re_realloc (set->elems, Idx, set->alloc);
+      if (BE (new_elems == NULL, 0))
+       return false;
+      set->elems = new_elems;
+    }
+
+  /* Insert the new element.  */
+  set->elems[set->nelem++] = elem;
+  return true;
+}
+
+/* Compare two node sets SET1 and SET2.
+   Return true if SET1 and SET2 are equivalent.  */
+
+static bool
+internal_function __attribute ((pure))
+re_node_set_compare (const re_node_set *set1, const re_node_set *set2)
+{
+  Idx i;
+  if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem)
+    return false;
+  for (i = set1->nelem ; REG_VALID_INDEX (--i) ; )
+    if (set1->elems[i] != set2->elems[i])
+      return false;
+  return true;
+}
+
+/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise.  */
+
+static Idx
+internal_function __attribute ((pure))
+re_node_set_contains (const re_node_set *set, Idx elem)
+{
+  __re_size_t idx, right, mid;
+  if (! REG_VALID_NONZERO_INDEX (set->nelem))
+    return 0;
+
+  /* Binary search the element.  */
+  idx = 0;
+  right = set->nelem - 1;
+  while (idx < right)
+    {
+      mid = (idx + right) / 2;
+      if (set->elems[mid] < elem)
+       idx = mid + 1;
+      else
+       right = mid;
+    }
+  return set->elems[idx] == elem ? idx + 1 : 0;
+}
+
+static void
+internal_function
+re_node_set_remove_at (re_node_set *set, Idx idx)
+{
+  if (idx < 0 || idx >= set->nelem)
+    return;
+  --set->nelem;
+  for (; idx < set->nelem; idx++)
+    set->elems[idx] = set->elems[idx + 1];
+}
+\f
+
+/* Add the token TOKEN to dfa->nodes, and return the index of the token.
+   Or return REG_MISSING if an error occurred.  */
+
+static Idx
+internal_function
+re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
+{
+  if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0))
+    {
+      size_t new_nodes_alloc = dfa->nodes_alloc * 2;
+      Idx *new_nexts, *new_indices;
+      re_node_set *new_edests, *new_eclosures;
+      re_token_t *new_nodes;
+      size_t max_object_size =
+       MAX (sizeof (re_token_t),
+            MAX (sizeof (re_node_set),
+                 sizeof (Idx)));
+
+      /* Avoid overflows.  */
+      if (BE (SIZE_MAX / 2 / max_object_size < dfa->nodes_alloc, 0))
+       return REG_MISSING;
+
+      new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc);
+      if (BE (new_nodes == NULL, 0))
+       return REG_MISSING;
+      dfa->nodes = new_nodes;
+      new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc);
+      new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc);
+      new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc);
+      new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc);
+      if (BE (new_nexts == NULL || new_indices == NULL
+             || new_edests == NULL || new_eclosures == NULL, 0))
+       return REG_MISSING;
+      dfa->nexts = new_nexts;
+      dfa->org_indices = new_indices;
+      dfa->edests = new_edests;
+      dfa->eclosures = new_eclosures;
+      dfa->nodes_alloc = new_nodes_alloc;
+    }
+  dfa->nodes[dfa->nodes_len] = token;
+  dfa->nodes[dfa->nodes_len].constraint = 0;
+#ifdef RE_ENABLE_I18N
+  {
+  int type = token.type;
+  dfa->nodes[dfa->nodes_len].accept_mb =
+    (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET;
+  }
+#endif
+  dfa->nexts[dfa->nodes_len] = REG_MISSING;
+  re_node_set_init_empty (dfa->edests + dfa->nodes_len);
+  re_node_set_init_empty (dfa->eclosures + dfa->nodes_len);
+  return dfa->nodes_len++;
+}
+
+static inline re_hashval_t
+internal_function
+calc_state_hash (const re_node_set *nodes, unsigned int context)
+{
+  re_hashval_t hash = nodes->nelem + context;
+  Idx i;
+  for (i = 0 ; i < nodes->nelem ; i++)
+    hash += nodes->elems[i];
+  return hash;
+}
+
+/* Search for the state whose node_set is equivalent to NODES.
+   Return the pointer to the state, if we found it in the DFA.
+   Otherwise create the new one and return it.  In case of an error
+   return NULL and set the error code in ERR.
+   Note: - We assume NULL as the invalid state, then it is possible that
+          return value is NULL and ERR is REG_NOERROR.
+        - We never return non-NULL value in case of any errors, it is for
+          optimization.  */
+
+static re_dfastate_t *
+internal_function __attribute_warn_unused_result__
+re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
+                 const re_node_set *nodes)
+{
+  re_hashval_t hash;
+  re_dfastate_t *new_state;
+  struct re_state_table_entry *spot;
+  Idx i;
+#ifdef lint
+  /* Suppress bogus uninitialized-variable warnings.  */
+  *err = REG_NOERROR;
+#endif
+  if (BE (nodes->nelem == 0, 0))
+    {
+      *err = REG_NOERROR;
+      return NULL;
+    }
+  hash = calc_state_hash (nodes, 0);
+  spot = dfa->state_table + (hash & dfa->state_hash_mask);
+
+  for (i = 0 ; i < spot->num ; i++)
+    {
+      re_dfastate_t *state = spot->array[i];
+      if (hash != state->hash)
+       continue;
+      if (re_node_set_compare (&state->nodes, nodes))
+       return state;
+    }
+
+  /* There are no appropriate state in the dfa, create the new one.  */
+  new_state = create_ci_newstate (dfa, nodes, hash);
+  if (BE (new_state == NULL, 0))
+    *err = REG_ESPACE;
+
+  return new_state;
+}
+
+/* Search for the state whose node_set is equivalent to NODES and
+   whose context is equivalent to CONTEXT.
+   Return the pointer to the state, if we found it in the DFA.
+   Otherwise create the new one and return it.  In case of an error
+   return NULL and set the error code in ERR.
+   Note: - We assume NULL as the invalid state, then it is possible that
+          return value is NULL and ERR is REG_NOERROR.
+        - We never return non-NULL value in case of any errors, it is for
+          optimization.  */
+
+static re_dfastate_t *
+internal_function __attribute_warn_unused_result__
+re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
+                         const re_node_set *nodes, unsigned int context)
+{
+  re_hashval_t hash;
+  re_dfastate_t *new_state;
+  struct re_state_table_entry *spot;
+  Idx i;
+#ifdef lint
+  /* Suppress bogus uninitialized-variable warnings.  */
+  *err = REG_NOERROR;
+#endif
+  if (nodes->nelem == 0)
+    {
+      *err = REG_NOERROR;
+      return NULL;
+    }
+  hash = calc_state_hash (nodes, context);
+  spot = dfa->state_table + (hash & dfa->state_hash_mask);
+
+  for (i = 0 ; i < spot->num ; i++)
+    {
+      re_dfastate_t *state = spot->array[i];
+      if (state->hash == hash
+         && state->context == context
+         && re_node_set_compare (state->entrance_nodes, nodes))
+       return state;
+    }
+  /* There are no appropriate state in `dfa', create the new one.  */
+  new_state = create_cd_newstate (dfa, nodes, context, hash);
+  if (BE (new_state == NULL, 0))
+    *err = REG_ESPACE;
+
+  return new_state;
+}
+
+/* Finish initialization of the new state NEWSTATE, and using its hash value
+   HASH put in the appropriate bucket of DFA's state table.  Return value
+   indicates the error code if failed.  */
+
+static reg_errcode_t
+__attribute_warn_unused_result__
+register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
+               re_hashval_t hash)
+{
+  struct re_state_table_entry *spot;
+  reg_errcode_t err;
+  Idx i;
+
+  newstate->hash = hash;
+  err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem);
+  if (BE (err != REG_NOERROR, 0))
+    return REG_ESPACE;
+  for (i = 0; i < newstate->nodes.nelem; i++)
+    {
+      Idx elem = newstate->nodes.elems[i];
+      if (!IS_EPSILON_NODE (dfa->nodes[elem].type))
+       if (BE (! re_node_set_insert_last (&newstate->non_eps_nodes, elem), 0))
+         return REG_ESPACE;
+    }
+
+  spot = dfa->state_table + (hash & dfa->state_hash_mask);
+  if (BE (spot->alloc <= spot->num, 0))
+    {
+      Idx new_alloc = 2 * spot->num + 2;
+      re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *,
+                                             new_alloc);
+      if (BE (new_array == NULL, 0))
+       return REG_ESPACE;
+      spot->array = new_array;
+      spot->alloc = new_alloc;
+    }
+  spot->array[spot->num++] = newstate;
+  return REG_NOERROR;
+}
+
+static void
+free_state (re_dfastate_t *state)
+{
+  re_node_set_free (&state->non_eps_nodes);
+  re_node_set_free (&state->inveclosure);
+  if (state->entrance_nodes != &state->nodes)
+    {
+      re_node_set_free (state->entrance_nodes);
+      re_free (state->entrance_nodes);
+    }
+  re_node_set_free (&state->nodes);
+  re_free (state->word_trtable);
+  re_free (state->trtable);
+  re_free (state);
+}
+
+/* Create the new state which is independ of contexts.
+   Return the new state if succeeded, otherwise return NULL.  */
+
+static re_dfastate_t *
+internal_function __attribute_warn_unused_result__
+create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
+                   re_hashval_t hash)
+{
+  Idx i;
+  reg_errcode_t err;
+  re_dfastate_t *newstate;
+
+  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
+  if (BE (newstate == NULL, 0))
+    return NULL;
+  err = re_node_set_init_copy (&newstate->nodes, nodes);
+  if (BE (err != REG_NOERROR, 0))
+    {
+      re_free (newstate);
+      return NULL;
+    }
+
+  newstate->entrance_nodes = &newstate->nodes;
+  for (i = 0 ; i < nodes->nelem ; i++)
+    {
+      re_token_t *node = dfa->nodes + nodes->elems[i];
+      re_token_type_t type = node->type;
+      if (type == CHARACTER && !node->constraint)
+       continue;
+#ifdef RE_ENABLE_I18N
+      newstate->accept_mb |= node->accept_mb;
+#endif /* RE_ENABLE_I18N */
+
+      /* If the state has the halt node, the state is a halt state.  */
+      if (type == END_OF_RE)
+       newstate->halt = 1;
+      else if (type == OP_BACK_REF)
+       newstate->has_backref = 1;
+      else if (type == ANCHOR || node->constraint)
+       newstate->has_constraint = 1;
+    }
+  err = register_state (dfa, newstate, hash);
+  if (BE (err != REG_NOERROR, 0))
+    {
+      free_state (newstate);
+      newstate = NULL;
+    }
+  return newstate;
+}
+
+/* Create the new state which is depend on the context CONTEXT.
+   Return the new state if succeeded, otherwise return NULL.  */
+
+static re_dfastate_t *
+internal_function __attribute_warn_unused_result__
+create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
+                   unsigned int context, re_hashval_t hash)
+{
+  Idx i, nctx_nodes = 0;
+  reg_errcode_t err;
+  re_dfastate_t *newstate;
+
+  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
+  if (BE (newstate == NULL, 0))
+    return NULL;
+  err = re_node_set_init_copy (&newstate->nodes, nodes);
+  if (BE (err != REG_NOERROR, 0))
+    {
+      re_free (newstate);
+      return NULL;
+    }
+
+  newstate->context = context;
+  newstate->entrance_nodes = &newstate->nodes;
+
+  for (i = 0 ; i < nodes->nelem ; i++)
+    {
+      re_token_t *node = dfa->nodes + nodes->elems[i];
+      re_token_type_t type = node->type;
+      unsigned int constraint = node->constraint;
+
+      if (type == CHARACTER && !constraint)
+       continue;
+#ifdef RE_ENABLE_I18N
+      newstate->accept_mb |= node->accept_mb;
+#endif /* RE_ENABLE_I18N */
+
+      /* If the state has the halt node, the state is a halt state.  */
+      if (type == END_OF_RE)
+       newstate->halt = 1;
+      else if (type == OP_BACK_REF)
+       newstate->has_backref = 1;
+
+      if (constraint)
+       {
+         if (newstate->entrance_nodes == &newstate->nodes)
+           {
+             newstate->entrance_nodes = re_malloc (re_node_set, 1);
+             if (BE (newstate->entrance_nodes == NULL, 0))
+               {
+                 free_state (newstate);
+                 return NULL;
+               }
+             if (re_node_set_init_copy (newstate->entrance_nodes, nodes)
+                 != REG_NOERROR)
+               return NULL;
+             nctx_nodes = 0;
+             newstate->has_constraint = 1;
+           }
+
+         if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context))
+           {
+             re_node_set_remove_at (&newstate->nodes, i - nctx_nodes);
+             ++nctx_nodes;
+           }
+       }
+    }
+  err = register_state (dfa, newstate, hash);
+  if (BE (err != REG_NOERROR, 0))
+    {
+      free_state (newstate);
+      newstate = NULL;
+    }
+  return  newstate;
+}
diff --git a/grub-core/gnulib/regex_internal.h b/grub-core/gnulib/regex_internal.h
new file mode 100644 (file)
index 0000000..e1b4c61
--- /dev/null
@@ -0,0 +1,871 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
+   Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
+
+   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef _REGEX_INTERNAL_H
+#define _REGEX_INTERNAL_H 1
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <langinfo.h>
+#ifndef _LIBC
+# include "localcharset.h"
+#endif
+#if defined HAVE_LOCALE_H || defined _LIBC
+# include <locale.h>
+#endif
+
+#include <wchar.h>
+#include <wctype.h>
+#include <stdint.h>
+#if defined _LIBC
+# include <bits/libc-lock.h>
+#else
+# define __libc_lock_init(NAME) do { } while (0)
+# define __libc_lock_lock(NAME) do { } while (0)
+# define __libc_lock_unlock(NAME) do { } while (0)
+#endif
+
+/* In case that the system doesn't have isblank().  */
+#if !defined _LIBC && ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK))
+# define isblank(ch) ((ch) == ' ' || (ch) == '\t')
+#endif
+
+#ifdef _LIBC
+# ifndef _RE_DEFINE_LOCALE_FUNCTIONS
+#  define _RE_DEFINE_LOCALE_FUNCTIONS 1
+#   include <locale/localeinfo.h>
+#   include <locale/elem-hash.h>
+#   include <locale/coll-lookup.h>
+# endif
+#endif
+
+/* This is for other GNU distributions with internationalized messages.  */
+#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
+# include <libintl.h>
+# ifdef _LIBC
+#  undef gettext
+#  define gettext(msgid) \
+  INTUSE(__dcgettext) (_libc_intl_domainname, msgid, LC_MESSAGES)
+# endif
+#else
+# define gettext(msgid) (msgid)
+#endif
+
+#ifndef gettext_noop
+/* This define is so xgettext can find the internationalizable
+   strings.  */
+# define gettext_noop(String) String
+#endif
+
+/* For loser systems without the definition.  */
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+
+#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCSCOLL) || _LIBC
+# define RE_ENABLE_I18N
+#endif
+
+#if __GNUC__ >= 3
+# define BE(expr, val) __builtin_expect (expr, val)
+#else
+# define BE(expr, val) (expr)
+# ifdef _LIBC
+#  define inline
+# endif
+#endif
+
+/* Number of ASCII characters.  */
+#define ASCII_CHARS 0x80
+
+/* Number of single byte characters.  */
+#define SBC_MAX (UCHAR_MAX + 1)
+
+#define COLL_ELEM_LEN_MAX 8
+
+/* The character which represents newline.  */
+#define NEWLINE_CHAR '\n'
+#define WIDE_NEWLINE_CHAR L'\n'
+
+/* Rename to standard API for using out of glibc.  */
+#ifndef _LIBC
+# define __wctype wctype
+# define __iswctype iswctype
+# define __btowc btowc
+# define __wcrtomb wcrtomb
+# define __mbrtowc mbrtowc
+# define __regfree regfree
+# define attribute_hidden
+#endif /* not _LIBC */
+
+#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
+# define __attribute(arg) __attribute__ (arg)
+#else
+# define __attribute(arg)
+#endif
+
+typedef __re_idx_t Idx;
+
+/* Special return value for failure to match.  */
+#define REG_MISSING ((Idx) -1)
+
+/* Special return value for internal error.  */
+#define REG_ERROR ((Idx) -2)
+
+/* Test whether N is a valid index, and is not one of the above.  */
+#ifdef _REGEX_LARGE_OFFSETS
+# define REG_VALID_INDEX(n) ((Idx) (n) < REG_ERROR)
+#else
+# define REG_VALID_INDEX(n) (0 <= (n))
+#endif
+
+/* Test whether N is a valid nonzero index.  */
+#ifdef _REGEX_LARGE_OFFSETS
+# define REG_VALID_NONZERO_INDEX(n) ((Idx) ((n) - 1) < (Idx) (REG_ERROR - 1))
+#else
+# define REG_VALID_NONZERO_INDEX(n) (0 < (n))
+#endif
+
+/* A hash value, suitable for computing hash tables.  */
+typedef __re_size_t re_hashval_t;
+
+/* An integer used to represent a set of bits.  It must be unsigned,
+   and must be at least as wide as unsigned int.  */
+typedef unsigned long int bitset_word_t;
+/* All bits set in a bitset_word_t.  */
+#define BITSET_WORD_MAX ULONG_MAX
+
+/* Number of bits in a bitset_word_t.  For portability to hosts with
+   padding bits, do not use '(sizeof (bitset_word_t) * CHAR_BIT)';
+   instead, deduce it directly from BITSET_WORD_MAX.  Avoid
+   greater-than-32-bit integers and unconditional shifts by more than
+   31 bits, as they're not portable.  */
+#if BITSET_WORD_MAX == 0xffffffffUL
+# define BITSET_WORD_BITS 32
+#elif BITSET_WORD_MAX >> 31 >> 4 == 1
+# define BITSET_WORD_BITS 36
+#elif BITSET_WORD_MAX >> 31 >> 16 == 1
+# define BITSET_WORD_BITS 48
+#elif BITSET_WORD_MAX >> 31 >> 28 == 1
+# define BITSET_WORD_BITS 60
+#elif BITSET_WORD_MAX >> 31 >> 31 >> 1 == 1
+# define BITSET_WORD_BITS 64
+#elif BITSET_WORD_MAX >> 31 >> 31 >> 9 == 1
+# define BITSET_WORD_BITS 72
+#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 3 == 1
+# define BITSET_WORD_BITS 128
+#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 == 1
+# define BITSET_WORD_BITS 256
+#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 > 1
+# define BITSET_WORD_BITS 257 /* any value > SBC_MAX will do here */
+# if BITSET_WORD_BITS <= SBC_MAX
+#  error "Invalid SBC_MAX"
+# endif
+#else
+# error "Add case for new bitset_word_t size"
+#endif
+
+/* Number of bitset_word_t values in a bitset_t.  */
+#define BITSET_WORDS ((SBC_MAX + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
+
+typedef bitset_word_t bitset_t[BITSET_WORDS];
+typedef bitset_word_t *re_bitset_ptr_t;
+typedef const bitset_word_t *re_const_bitset_ptr_t;
+
+#define PREV_WORD_CONSTRAINT 0x0001
+#define PREV_NOTWORD_CONSTRAINT 0x0002
+#define NEXT_WORD_CONSTRAINT 0x0004
+#define NEXT_NOTWORD_CONSTRAINT 0x0008
+#define PREV_NEWLINE_CONSTRAINT 0x0010
+#define NEXT_NEWLINE_CONSTRAINT 0x0020
+#define PREV_BEGBUF_CONSTRAINT 0x0040
+#define NEXT_ENDBUF_CONSTRAINT 0x0080
+#define WORD_DELIM_CONSTRAINT 0x0100
+#define NOT_WORD_DELIM_CONSTRAINT 0x0200
+
+typedef enum
+{
+  INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
+  WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
+  WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
+  INSIDE_NOTWORD = PREV_NOTWORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
+  LINE_FIRST = PREV_NEWLINE_CONSTRAINT,
+  LINE_LAST = NEXT_NEWLINE_CONSTRAINT,
+  BUF_FIRST = PREV_BEGBUF_CONSTRAINT,
+  BUF_LAST = NEXT_ENDBUF_CONSTRAINT,
+  WORD_DELIM = WORD_DELIM_CONSTRAINT,
+  NOT_WORD_DELIM = NOT_WORD_DELIM_CONSTRAINT
+} re_context_type;
+
+typedef struct
+{
+  Idx alloc;
+  Idx nelem;
+  Idx *elems;
+} re_node_set;
+
+typedef enum
+{
+  NON_TYPE = 0,
+
+  /* Node type, These are used by token, node, tree.  */
+  CHARACTER = 1,
+  END_OF_RE = 2,
+  SIMPLE_BRACKET = 3,
+  OP_BACK_REF = 4,
+  OP_PERIOD = 5,
+#ifdef RE_ENABLE_I18N
+  COMPLEX_BRACKET = 6,
+  OP_UTF8_PERIOD = 7,
+#endif /* RE_ENABLE_I18N */
+
+  /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used
+     when the debugger shows values of this enum type.  */
+#define EPSILON_BIT 8
+  OP_OPEN_SUBEXP = EPSILON_BIT | 0,
+  OP_CLOSE_SUBEXP = EPSILON_BIT | 1,
+  OP_ALT = EPSILON_BIT | 2,
+  OP_DUP_ASTERISK = EPSILON_BIT | 3,
+  ANCHOR = EPSILON_BIT | 4,
+
+  /* Tree type, these are used only by tree. */
+  CONCAT = 16,
+  SUBEXP = 17,
+
+  /* Token type, these are used only by token.  */
+  OP_DUP_PLUS = 18,
+  OP_DUP_QUESTION,
+  OP_OPEN_BRACKET,
+  OP_CLOSE_BRACKET,
+  OP_CHARSET_RANGE,
+  OP_OPEN_DUP_NUM,
+  OP_CLOSE_DUP_NUM,
+  OP_NON_MATCH_LIST,
+  OP_OPEN_COLL_ELEM,
+  OP_CLOSE_COLL_ELEM,
+  OP_OPEN_EQUIV_CLASS,
+  OP_CLOSE_EQUIV_CLASS,
+  OP_OPEN_CHAR_CLASS,
+  OP_CLOSE_CHAR_CLASS,
+  OP_WORD,
+  OP_NOTWORD,
+  OP_SPACE,
+  OP_NOTSPACE,
+  BACK_SLASH
+
+} re_token_type_t;
+
+#ifdef RE_ENABLE_I18N
+typedef struct
+{
+  /* Multibyte characters.  */
+  wchar_t *mbchars;
+
+  /* Collating symbols.  */
+# ifdef _LIBC
+  int32_t *coll_syms;
+# endif
+
+  /* Equivalence classes. */
+# ifdef _LIBC
+  int32_t *equiv_classes;
+# endif
+
+  /* Range expressions. */
+# ifdef _LIBC
+  uint32_t *range_starts;
+  uint32_t *range_ends;
+# else /* not _LIBC */
+  wchar_t *range_starts;
+  wchar_t *range_ends;
+# endif /* not _LIBC */
+
+  /* Character classes. */
+  wctype_t *char_classes;
+
+  /* If this character set is the non-matching list.  */
+  unsigned int non_match : 1;
+
+  /* # of multibyte characters.  */
+  Idx nmbchars;
+
+  /* # of collating symbols.  */
+  Idx ncoll_syms;
+
+  /* # of equivalence classes. */
+  Idx nequiv_classes;
+
+  /* # of range expressions. */
+  Idx nranges;
+
+  /* # of character classes. */
+  Idx nchar_classes;
+} re_charset_t;
+#endif /* RE_ENABLE_I18N */
+
+typedef struct
+{
+  union
+  {
+    unsigned char c;           /* for CHARACTER */
+    re_bitset_ptr_t sbcset;    /* for SIMPLE_BRACKET */
+#ifdef RE_ENABLE_I18N
+    re_charset_t *mbcset;      /* for COMPLEX_BRACKET */
+#endif /* RE_ENABLE_I18N */
+    Idx idx;                   /* for BACK_REF */
+    re_context_type ctx_type;  /* for ANCHOR */
+  } opr;
+#if __GNUC__ >= 2 && !__STRICT_ANSI__
+  re_token_type_t type : 8;
+#else
+  re_token_type_t type;
+#endif
+  unsigned int constraint : 10;        /* context constraint */
+  unsigned int duplicated : 1;
+  unsigned int opt_subexp : 1;
+#ifdef RE_ENABLE_I18N
+  unsigned int accept_mb : 1;
+  /* These 2 bits can be moved into the union if needed (e.g. if running out
+     of bits; move opr.c to opr.c.c and move the flags to opr.c.flags).  */
+  unsigned int mb_partial : 1;
+#endif
+  unsigned int word_char : 1;
+} re_token_t;
+
+#define IS_EPSILON_NODE(type) ((type) & EPSILON_BIT)
+
+struct re_string_t
+{
+  /* Indicate the raw buffer which is the original string passed as an
+     argument of regexec(), re_search(), etc..  */
+  const unsigned char *raw_mbs;
+  /* Store the multibyte string.  In case of "case insensitive mode" like
+     REG_ICASE, upper cases of the string are stored, otherwise MBS points
+     the same address that RAW_MBS points.  */
+  unsigned char *mbs;
+#ifdef RE_ENABLE_I18N
+  /* Store the wide character string which is corresponding to MBS.  */
+  wint_t *wcs;
+  Idx *offsets;
+  mbstate_t cur_state;
+#endif
+  /* Index in RAW_MBS.  Each character mbs[i] corresponds to
+     raw_mbs[raw_mbs_idx + i].  */
+  Idx raw_mbs_idx;
+  /* The length of the valid characters in the buffers.  */
+  Idx valid_len;
+  /* The corresponding number of bytes in raw_mbs array.  */
+  Idx valid_raw_len;
+  /* The length of the buffers MBS and WCS.  */
+  Idx bufs_len;
+  /* The index in MBS, which is updated by re_string_fetch_byte.  */
+  Idx cur_idx;
+  /* length of RAW_MBS array.  */
+  Idx raw_len;
+  /* This is RAW_LEN - RAW_MBS_IDX + VALID_LEN - VALID_RAW_LEN.  */
+  Idx len;
+  /* End of the buffer may be shorter than its length in the cases such
+     as re_match_2, re_search_2.  Then, we use STOP for end of the buffer
+     instead of LEN.  */
+  Idx raw_stop;
+  /* This is RAW_STOP - RAW_MBS_IDX adjusted through OFFSETS.  */
+  Idx stop;
+
+  /* The context of mbs[0].  We store the context independently, since
+     the context of mbs[0] may be different from raw_mbs[0], which is
+     the beginning of the input string.  */
+  unsigned int tip_context;
+  /* The translation passed as a part of an argument of re_compile_pattern.  */
+  RE_TRANSLATE_TYPE trans;
+  /* Copy of re_dfa_t's word_char.  */
+  re_const_bitset_ptr_t word_char;
+  /* true if REG_ICASE.  */
+  unsigned char icase;
+  unsigned char is_utf8;
+  unsigned char map_notascii;
+  unsigned char mbs_allocated;
+  unsigned char offsets_needed;
+  unsigned char newline_anchor;
+  unsigned char word_ops_used;
+  int mb_cur_max;
+};
+typedef struct re_string_t re_string_t;
+
+
+struct re_dfa_t;
+typedef struct re_dfa_t re_dfa_t;
+
+#ifndef _LIBC
+# if defined __i386__ && !defined __EMX__
+#  define internal_function   __attribute ((regparm (3), stdcall))
+# else
+#  define internal_function
+# endif
+#endif
+
+static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr,
+                                               Idx new_buf_len)
+     internal_function;
+#ifdef RE_ENABLE_I18N
+static void build_wcs_buffer (re_string_t *pstr) internal_function;
+static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr)
+     internal_function;
+#endif /* RE_ENABLE_I18N */
+static void build_upper_buffer (re_string_t *pstr) internal_function;
+static void re_string_translate_buffer (re_string_t *pstr) internal_function;
+static unsigned int re_string_context_at (const re_string_t *input, Idx idx,
+                                         int eflags)
+     internal_function __attribute ((pure));
+#define re_string_peek_byte(pstr, offset) \
+  ((pstr)->mbs[(pstr)->cur_idx + offset])
+#define re_string_fetch_byte(pstr) \
+  ((pstr)->mbs[(pstr)->cur_idx++])
+#define re_string_first_byte(pstr, idx) \
+  ((idx) == (pstr)->valid_len || (pstr)->wcs[idx] != WEOF)
+#define re_string_is_single_byte_char(pstr, idx) \
+  ((pstr)->wcs[idx] != WEOF && ((pstr)->valid_len == (idx) + 1 \
+                               || (pstr)->wcs[(idx) + 1] != WEOF))
+#define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx)
+#define re_string_cur_idx(pstr) ((pstr)->cur_idx)
+#define re_string_get_buffer(pstr) ((pstr)->mbs)
+#define re_string_length(pstr) ((pstr)->len)
+#define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx])
+#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx))
+#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx))
+
+#include <alloca.h>
+
+#ifndef _LIBC
+# if HAVE_ALLOCA
+/* The OS usually guarantees only one guard page at the bottom of the stack,
+   and a page size can be as small as 4096 bytes.  So we cannot safely
+   allocate anything larger than 4096 bytes.  Also care for the possibility
+   of a few compiler-allocated temporary stack slots.  */
+#  define __libc_use_alloca(n) ((n) < 4032)
+# else
+/* alloca is implemented with malloc, so just use malloc.  */
+#  define __libc_use_alloca(n) 0
+# endif
+#endif
+
+#ifndef MAX
+# define MAX(a,b) ((a) < (b) ? (b) : (a))
+#endif
+
+#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t)))
+#define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t)))
+#define re_free(p) free (p)
+
+struct bin_tree_t
+{
+  struct bin_tree_t *parent;
+  struct bin_tree_t *left;
+  struct bin_tree_t *right;
+  struct bin_tree_t *first;
+  struct bin_tree_t *next;
+
+  re_token_t token;
+
+  /* `node_idx' is the index in dfa->nodes, if `type' == 0.
+     Otherwise `type' indicate the type of this node.  */
+  Idx node_idx;
+};
+typedef struct bin_tree_t bin_tree_t;
+
+#define BIN_TREE_STORAGE_SIZE \
+  ((1024 - sizeof (void *)) / sizeof (bin_tree_t))
+
+struct bin_tree_storage_t
+{
+  struct bin_tree_storage_t *next;
+  bin_tree_t data[BIN_TREE_STORAGE_SIZE];
+};
+typedef struct bin_tree_storage_t bin_tree_storage_t;
+
+#define CONTEXT_WORD 1
+#define CONTEXT_NEWLINE (CONTEXT_WORD << 1)
+#define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1)
+#define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1)
+
+#define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD)
+#define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE)
+#define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF)
+#define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF)
+#define IS_ORDINARY_CONTEXT(c) ((c) == 0)
+
+#define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_')
+#define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR)
+#define IS_WIDE_WORD_CHAR(ch) (iswalnum (ch) || (ch) == L'_')
+#define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR)
+
+#define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \
+ ((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
+  || ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
+  || ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\
+  || ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context)))
+
+#define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \
+ ((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
+  || (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
+  || (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \
+  || (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context)))
+
+struct re_dfastate_t
+{
+  re_hashval_t hash;
+  re_node_set nodes;
+  re_node_set non_eps_nodes;
+  re_node_set inveclosure;
+  re_node_set *entrance_nodes;
+  struct re_dfastate_t **trtable, **word_trtable;
+  unsigned int context : 4;
+  unsigned int halt : 1;
+  /* If this state can accept `multi byte'.
+     Note that we refer to multibyte characters, and multi character
+     collating elements as `multi byte'.  */
+  unsigned int accept_mb : 1;
+  /* If this state has backreference node(s).  */
+  unsigned int has_backref : 1;
+  unsigned int has_constraint : 1;
+};
+typedef struct re_dfastate_t re_dfastate_t;
+
+struct re_state_table_entry
+{
+  Idx num;
+  Idx alloc;
+  re_dfastate_t **array;
+};
+
+/* Array type used in re_sub_match_last_t and re_sub_match_top_t.  */
+
+typedef struct
+{
+  Idx next_idx;
+  Idx alloc;
+  re_dfastate_t **array;
+} state_array_t;
+
+/* Store information about the node NODE whose type is OP_CLOSE_SUBEXP.  */
+
+typedef struct
+{
+  Idx node;
+  Idx str_idx; /* The position NODE match at.  */
+  state_array_t path;
+} re_sub_match_last_t;
+
+/* Store information about the node NODE whose type is OP_OPEN_SUBEXP.
+   And information about the node, whose type is OP_CLOSE_SUBEXP,
+   corresponding to NODE is stored in LASTS.  */
+
+typedef struct
+{
+  Idx str_idx;
+  Idx node;
+  state_array_t *path;
+  Idx alasts; /* Allocation size of LASTS.  */
+  Idx nlasts; /* The number of LASTS.  */
+  re_sub_match_last_t **lasts;
+} re_sub_match_top_t;
+
+struct re_backref_cache_entry
+{
+  Idx node;
+  Idx str_idx;
+  Idx subexp_from;
+  Idx subexp_to;
+  char more;
+  char unused;
+  unsigned short int eps_reachable_subexps_map;
+};
+
+typedef struct
+{
+  /* The string object corresponding to the input string.  */
+  re_string_t input;
+#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
+  const re_dfa_t *const dfa;
+#else
+  const re_dfa_t *dfa;
+#endif
+  /* EFLAGS of the argument of regexec.  */
+  int eflags;
+  /* Where the matching ends.  */
+  Idx match_last;
+  Idx last_node;
+  /* The state log used by the matcher.  */
+  re_dfastate_t **state_log;
+  Idx state_log_top;
+  /* Back reference cache.  */
+  Idx nbkref_ents;
+  Idx abkref_ents;
+  struct re_backref_cache_entry *bkref_ents;
+  int max_mb_elem_len;
+  Idx nsub_tops;
+  Idx asub_tops;
+  re_sub_match_top_t **sub_tops;
+} re_match_context_t;
+
+typedef struct
+{
+  re_dfastate_t **sifted_states;
+  re_dfastate_t **limited_states;
+  Idx last_node;
+  Idx last_str_idx;
+  re_node_set limits;
+} re_sift_context_t;
+
+struct re_fail_stack_ent_t
+{
+  Idx idx;
+  Idx node;
+  regmatch_t *regs;
+  re_node_set eps_via_nodes;
+};
+
+struct re_fail_stack_t
+{
+  Idx num;
+  Idx alloc;
+  struct re_fail_stack_ent_t *stack;
+};
+
+struct re_dfa_t
+{
+  re_token_t *nodes;
+  size_t nodes_alloc;
+  size_t nodes_len;
+  Idx *nexts;
+  Idx *org_indices;
+  re_node_set *edests;
+  re_node_set *eclosures;
+  re_node_set *inveclosures;
+  struct re_state_table_entry *state_table;
+  re_dfastate_t *init_state;
+  re_dfastate_t *init_state_word;
+  re_dfastate_t *init_state_nl;
+  re_dfastate_t *init_state_begbuf;
+  bin_tree_t *str_tree;
+  bin_tree_storage_t *str_tree_storage;
+  re_bitset_ptr_t sb_char;
+  int str_tree_storage_idx;
+
+  /* number of subexpressions `re_nsub' is in regex_t.  */
+  re_hashval_t state_hash_mask;
+  Idx init_node;
+  Idx nbackref; /* The number of backreference in this dfa.  */
+
+  /* Bitmap expressing which backreference is used.  */
+  bitset_word_t used_bkref_map;
+  bitset_word_t completed_bkref_map;
+
+  unsigned int has_plural_match : 1;
+  /* If this dfa has "multibyte node", which is a backreference or
+     a node which can accept multibyte character or multi character
+     collating element.  */
+  unsigned int has_mb_node : 1;
+  unsigned int is_utf8 : 1;
+  unsigned int map_notascii : 1;
+  unsigned int word_ops_used : 1;
+  int mb_cur_max;
+  bitset_t word_char;
+  reg_syntax_t syntax;
+  Idx *subexp_map;
+#ifdef DEBUG
+  char* re_str;
+#endif
+#ifdef _LIBC
+  __libc_lock_define (, lock)
+#endif
+};
+
+#define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
+#define re_node_set_remove(set,id) \
+  (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
+#define re_node_set_empty(p) ((p)->nelem = 0)
+#define re_node_set_free(set) re_free ((set)->elems)
+\f
+
+typedef enum
+{
+  SB_CHAR,
+  MB_CHAR,
+  EQUIV_CLASS,
+  COLL_SYM,
+  CHAR_CLASS
+} bracket_elem_type;
+
+typedef struct
+{
+  bracket_elem_type type;
+  union
+  {
+    unsigned char ch;
+    unsigned char *name;
+    wchar_t wch;
+  } opr;
+} bracket_elem_t;
+
+
+/* Inline functions for bitset_t operation.  */
+
+static inline void
+bitset_set (bitset_t set, Idx i)
+{
+  set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS;
+}
+
+static inline void
+bitset_clear (bitset_t set, Idx i)
+{
+  set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS);
+}
+
+static inline bool
+bitset_contain (const bitset_t set, Idx i)
+{
+  return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1;
+}
+
+static inline void
+bitset_empty (bitset_t set)
+{
+  memset (set, '\0', sizeof (bitset_t));
+}
+
+static inline void
+bitset_set_all (bitset_t set)
+{
+  memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS));
+  if (SBC_MAX % BITSET_WORD_BITS != 0)
+    set[BITSET_WORDS - 1] =
+      ((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1;
+}
+
+static inline void
+bitset_copy (bitset_t dest, const bitset_t src)
+{
+  memcpy (dest, src, sizeof (bitset_t));
+}
+
+static inline void
+bitset_not (bitset_t set)
+{
+  int bitset_i;
+  for (bitset_i = 0; bitset_i < SBC_MAX / BITSET_WORD_BITS; ++bitset_i)
+    set[bitset_i] = ~set[bitset_i];
+  if (SBC_MAX % BITSET_WORD_BITS != 0)
+    set[BITSET_WORDS - 1] =
+      ((((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1)
+       & ~set[BITSET_WORDS - 1]);
+}
+
+static inline void
+bitset_merge (bitset_t dest, const bitset_t src)
+{
+  int bitset_i;
+  for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)
+    dest[bitset_i] |= src[bitset_i];
+}
+
+static inline void
+bitset_mask (bitset_t dest, const bitset_t src)
+{
+  int bitset_i;
+  for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)
+    dest[bitset_i] &= src[bitset_i];
+}
+
+#ifdef RE_ENABLE_I18N
+/* Inline functions for re_string.  */
+static inline int
+internal_function __attribute ((pure))
+re_string_char_size_at (const re_string_t *pstr, Idx idx)
+{
+  int byte_idx;
+  if (pstr->mb_cur_max == 1)
+    return 1;
+  for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx)
+    if (pstr->wcs[idx + byte_idx] != WEOF)
+      break;
+  return byte_idx;
+}
+
+static inline wint_t
+internal_function __attribute ((pure))
+re_string_wchar_at (const re_string_t *pstr, Idx idx)
+{
+  if (pstr->mb_cur_max == 1)
+    return (wint_t) pstr->mbs[idx];
+  return (wint_t) pstr->wcs[idx];
+}
+
+static int
+internal_function __attribute ((pure))
+re_string_elem_size_at (const re_string_t *pstr, Idx idx)
+{
+# ifdef _LIBC
+  const unsigned char *p, *extra;
+  const int32_t *table, *indirect;
+  int32_t tmp;
+#  include <locale/weight.h>
+  uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+
+  if (nrules != 0)
+    {
+      table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+      extra = (const unsigned char *)
+       _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
+      indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
+                                               _NL_COLLATE_INDIRECTMB);
+      p = pstr->mbs + idx;
+      tmp = findidx (&p);
+      return p - pstr->mbs - idx;
+    }
+  else
+# endif /* _LIBC */
+    return 1;
+}
+#endif /* RE_ENABLE_I18N */
+
+#ifndef __GNUC_PREREQ
+# if defined __GNUC__ && defined __GNUC_MINOR__
+#  define __GNUC_PREREQ(maj, min) \
+         ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+# else
+#  define __GNUC_PREREQ(maj, min) 0
+# endif
+#endif
+
+#if __GNUC_PREREQ (3,4)
+# undef __attribute_warn_unused_result__
+# define __attribute_warn_unused_result__ \
+   __attribute__ ((__warn_unused_result__))
+#else
+# define __attribute_warn_unused_result__ /* empty */
+#endif
+
+#endif /*  _REGEX_INTERNAL_H */
diff --git a/grub-core/gnulib/regexec.c b/grub-core/gnulib/regexec.c
new file mode 100644 (file)
index 0000000..9388ac1
--- /dev/null
@@ -0,0 +1,4416 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
+   Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
+
+   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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
+                                    Idx n) internal_function;
+static void match_ctx_clean (re_match_context_t *mctx) internal_function;
+static void match_ctx_free (re_match_context_t *cache) internal_function;
+static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, Idx node,
+                                         Idx str_idx, Idx from, Idx to)
+     internal_function;
+static Idx search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx)
+     internal_function;
+static reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, Idx node,
+                                          Idx str_idx) internal_function;
+static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop,
+                                                   Idx node, Idx str_idx)
+     internal_function;
+static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
+                          re_dfastate_t **limited_sts, Idx last_node,
+                          Idx last_str_idx)
+     internal_function;
+static reg_errcode_t re_search_internal (const regex_t *preg,
+                                        const char *string, Idx length,
+                                        Idx start, Idx last_start, Idx stop,
+                                        size_t nmatch, regmatch_t pmatch[],
+                                        int eflags) internal_function;
+static regoff_t re_search_2_stub (struct re_pattern_buffer *bufp,
+                                 const char *string1, Idx length1,
+                                 const char *string2, Idx length2,
+                                 Idx start, regoff_t range,
+                                 struct re_registers *regs,
+                                 Idx stop, bool ret_len) internal_function;
+static regoff_t re_search_stub (struct re_pattern_buffer *bufp,
+                               const char *string, Idx length, Idx start,
+                               regoff_t range, Idx stop,
+                               struct re_registers *regs,
+                               bool ret_len) internal_function;
+static unsigned int re_copy_regs (struct re_registers *regs, regmatch_t *pmatch,
+                                 Idx nregs, int regs_allocated)
+     internal_function;
+static reg_errcode_t prune_impossible_nodes (re_match_context_t *mctx)
+     internal_function;
+static Idx check_matching (re_match_context_t *mctx, bool fl_longest_match,
+                          Idx *p_match_first) internal_function;
+static Idx check_halt_state_context (const re_match_context_t *mctx,
+                                    const re_dfastate_t *state, Idx idx)
+     internal_function;
+static void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,
+                        regmatch_t *prev_idx_match, Idx cur_node,
+                        Idx cur_idx, Idx nmatch) internal_function;
+static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs,
+                                     Idx str_idx, Idx dest_node, Idx nregs,
+                                     regmatch_t *regs,
+                                     re_node_set *eps_via_nodes)
+     internal_function;
+static reg_errcode_t set_regs (const regex_t *preg,
+                              const re_match_context_t *mctx,
+                              size_t nmatch, regmatch_t *pmatch,
+                              bool fl_backtrack) internal_function;
+static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs)
+     internal_function;
+
+#ifdef RE_ENABLE_I18N
+static int sift_states_iter_mb (const re_match_context_t *mctx,
+                               re_sift_context_t *sctx,
+                               Idx node_idx, Idx str_idx, Idx max_str_idx)
+     internal_function;
+#endif /* RE_ENABLE_I18N */
+static reg_errcode_t sift_states_backward (const re_match_context_t *mctx,
+                                          re_sift_context_t *sctx)
+     internal_function;
+static reg_errcode_t build_sifted_states (const re_match_context_t *mctx,
+                                         re_sift_context_t *sctx, Idx str_idx,
+                                         re_node_set *cur_dest)
+     internal_function;
+static reg_errcode_t update_cur_sifted_state (const re_match_context_t *mctx,
+                                             re_sift_context_t *sctx,
+                                             Idx str_idx,
+                                             re_node_set *dest_nodes)
+     internal_function;
+static reg_errcode_t add_epsilon_src_nodes (const re_dfa_t *dfa,
+                                           re_node_set *dest_nodes,
+                                           const re_node_set *candidates)
+     internal_function;
+static bool check_dst_limits (const re_match_context_t *mctx,
+                             const re_node_set *limits,
+                             Idx dst_node, Idx dst_idx, Idx src_node,
+                             Idx src_idx) internal_function;
+static int check_dst_limits_calc_pos_1 (const re_match_context_t *mctx,
+                                       int boundaries, Idx subexp_idx,
+                                       Idx from_node, Idx bkref_idx)
+     internal_function;
+static int check_dst_limits_calc_pos (const re_match_context_t *mctx,
+                                     Idx limit, Idx subexp_idx,
+                                     Idx node, Idx str_idx,
+                                     Idx bkref_idx) internal_function;
+static reg_errcode_t check_subexp_limits (const re_dfa_t *dfa,
+                                         re_node_set *dest_nodes,
+                                         const re_node_set *candidates,
+                                         re_node_set *limits,
+                                         struct re_backref_cache_entry *bkref_ents,
+                                         Idx str_idx) internal_function;
+static reg_errcode_t sift_states_bkref (const re_match_context_t *mctx,
+                                       re_sift_context_t *sctx,
+                                       Idx str_idx, const re_node_set *candidates)
+     internal_function;
+static reg_errcode_t merge_state_array (const re_dfa_t *dfa,
+                                       re_dfastate_t **dst,
+                                       re_dfastate_t **src, Idx num)
+     internal_function;
+static re_dfastate_t *find_recover_state (reg_errcode_t *err,
+                                        re_match_context_t *mctx) internal_function;
+static re_dfastate_t *transit_state (reg_errcode_t *err,
+                                    re_match_context_t *mctx,
+                                    re_dfastate_t *state) internal_function;
+static re_dfastate_t *merge_state_with_log (reg_errcode_t *err,
+                                           re_match_context_t *mctx,
+                                           re_dfastate_t *next_state)
+     internal_function;
+static reg_errcode_t check_subexp_matching_top (re_match_context_t *mctx,
+                                               re_node_set *cur_nodes,
+                                               Idx str_idx) internal_function;
+#if 0
+static re_dfastate_t *transit_state_sb (reg_errcode_t *err,
+                                       re_match_context_t *mctx,
+                                       re_dfastate_t *pstate)
+     internal_function;
+#endif
+#ifdef RE_ENABLE_I18N
+static reg_errcode_t transit_state_mb (re_match_context_t *mctx,
+                                      re_dfastate_t *pstate)
+     internal_function;
+#endif /* RE_ENABLE_I18N */
+static reg_errcode_t transit_state_bkref (re_match_context_t *mctx,
+                                         const re_node_set *nodes)
+     internal_function;
+static reg_errcode_t get_subexp (re_match_context_t *mctx,
+                                Idx bkref_node, Idx bkref_str_idx)
+     internal_function;
+static reg_errcode_t get_subexp_sub (re_match_context_t *mctx,
+                                    const re_sub_match_top_t *sub_top,
+                                    re_sub_match_last_t *sub_last,
+                                    Idx bkref_node, Idx bkref_str)
+     internal_function;
+static Idx find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
+                            Idx subexp_idx, int type) internal_function;
+static reg_errcode_t check_arrival (re_match_context_t *mctx,
+                                   state_array_t *path, Idx top_node,
+                                   Idx top_str, Idx last_node, Idx last_str,
+                                   int type) internal_function;
+static reg_errcode_t check_arrival_add_next_nodes (re_match_context_t *mctx,
+                                                  Idx str_idx,
+                                                  re_node_set *cur_nodes,
+                                                  re_node_set *next_nodes)
+     internal_function;
+static reg_errcode_t check_arrival_expand_ecl (const re_dfa_t *dfa,
+                                              re_node_set *cur_nodes,
+                                              Idx ex_subexp, int type)
+     internal_function;
+static reg_errcode_t check_arrival_expand_ecl_sub (const re_dfa_t *dfa,
+                                                  re_node_set *dst_nodes,
+                                                  Idx target, Idx ex_subexp,
+                                                  int type) internal_function;
+static reg_errcode_t expand_bkref_cache (re_match_context_t *mctx,
+                                        re_node_set *cur_nodes, Idx cur_str,
+                                        Idx subexp_num, int type)
+     internal_function;
+static bool build_trtable (const re_dfa_t *dfa,
+                          re_dfastate_t *state) internal_function;
+#ifdef RE_ENABLE_I18N
+static int check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
+                                   const re_string_t *input, Idx idx)
+     internal_function;
+# ifdef _LIBC
+static unsigned int find_collation_sequence_value (const unsigned char *mbs,
+                                                  size_t name_len)
+     internal_function;
+# endif /* _LIBC */
+#endif /* RE_ENABLE_I18N */
+static Idx group_nodes_into_DFAstates (const re_dfa_t *dfa,
+                                      const re_dfastate_t *state,
+                                      re_node_set *states_node,
+                                      bitset_t *states_ch) internal_function;
+static bool check_node_accept (const re_match_context_t *mctx,
+                              const re_token_t *node, Idx idx)
+     internal_function;
+static reg_errcode_t extend_buffers (re_match_context_t *mctx)
+     internal_function;
+\f
+/* Entry point for POSIX code.  */
+
+/* regexec searches for a given pattern, specified by PREG, in the
+   string STRING.
+
+   If NMATCH is zero or REG_NOSUB was set in the cflags argument to
+   `regcomp', we ignore PMATCH.  Otherwise, we assume PMATCH has at
+   least NMATCH elements, and we set them to the offsets of the
+   corresponding matched substrings.
+
+   EFLAGS specifies `execution flags' which affect matching: if
+   REG_NOTBOL is set, then ^ does not match at the beginning of the
+   string; if REG_NOTEOL is set, then $ does not match at the end.
+
+   We return 0 if we find a match and REG_NOMATCH if not.  */
+
+int
+regexec (preg, string, nmatch, pmatch, eflags)
+    const regex_t *_Restrict_ preg;
+    const char *_Restrict_ string;
+    size_t nmatch;
+    regmatch_t pmatch[_Restrict_arr_];
+    int eflags;
+{
+  reg_errcode_t err;
+  Idx start, length;
+#ifdef _LIBC
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+#endif
+
+  if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND))
+    return REG_BADPAT;
+
+  if (eflags & REG_STARTEND)
+    {
+      start = pmatch[0].rm_so;
+      length = pmatch[0].rm_eo;
+    }
+  else
+    {
+      start = 0;
+      length = strlen (string);
+    }
+
+  __libc_lock_lock (dfa->lock);
+  if (preg->no_sub)
+    err = re_search_internal (preg, string, length, start, length,
+                             length, 0, NULL, eflags);
+  else
+    err = re_search_internal (preg, string, length, start, length,
+                             length, nmatch, pmatch, eflags);
+  __libc_lock_unlock (dfa->lock);
+  return err != REG_NOERROR;
+}
+
+#ifdef _LIBC
+# include <shlib-compat.h>
+versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
+
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+__typeof__ (__regexec) __compat_regexec;
+
+int
+attribute_compat_text_section
+__compat_regexec (const regex_t *_Restrict_ preg,
+                 const char *_Restrict_ string, size_t nmatch,
+                 regmatch_t pmatch[], int eflags)
+{
+  return regexec (preg, string, nmatch, pmatch,
+                 eflags & (REG_NOTBOL | REG_NOTEOL));
+}
+compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
+# endif
+#endif
+
+/* Entry points for GNU code.  */
+
+/* re_match, re_search, re_match_2, re_search_2
+
+   The former two functions operate on STRING with length LENGTH,
+   while the later two operate on concatenation of STRING1 and STRING2
+   with lengths LENGTH1 and LENGTH2, respectively.
+
+   re_match() matches the compiled pattern in BUFP against the string,
+   starting at index START.
+
+   re_search() first tries matching at index START, then it tries to match
+   starting from index START + 1, and so on.  The last start position tried
+   is START + RANGE.  (Thus RANGE = 0 forces re_search to operate the same
+   way as re_match().)
+
+   The parameter STOP of re_{match,search}_2 specifies that no match exceeding
+   the first STOP characters of the concatenation of the strings should be
+   concerned.
+
+   If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match
+   and all groups is stored in REGS.  (For the "_2" variants, the offsets are
+   computed relative to the concatenation, not relative to the individual
+   strings.)
+
+   On success, re_match* functions return the length of the match, re_search*
+   return the position of the start of the match.  Return value -1 means no
+   match was found and -2 indicates an internal error.  */
+
+regoff_t
+re_match (bufp, string, length, start, regs)
+    struct re_pattern_buffer *bufp;
+    const char *string;
+    Idx length, start;
+    struct re_registers *regs;
+{
+  return re_search_stub (bufp, string, length, start, 0, length, regs, true);
+}
+#ifdef _LIBC
+weak_alias (__re_match, re_match)
+#endif
+
+regoff_t
+re_search (bufp, string, length, start, range, regs)
+    struct re_pattern_buffer *bufp;
+    const char *string;
+    Idx length, start;
+    regoff_t range;
+    struct re_registers *regs;
+{
+  return re_search_stub (bufp, string, length, start, range, length, regs,
+                        false);
+}
+#ifdef _LIBC
+weak_alias (__re_search, re_search)
+#endif
+
+regoff_t
+re_match_2 (bufp, string1, length1, string2, length2, start, regs, stop)
+    struct re_pattern_buffer *bufp;
+    const char *string1, *string2;
+    Idx length1, length2, start, stop;
+    struct re_registers *regs;
+{
+  return re_search_2_stub (bufp, string1, length1, string2, length2,
+                          start, 0, regs, stop, true);
+}
+#ifdef _LIBC
+weak_alias (__re_match_2, re_match_2)
+#endif
+
+regoff_t
+re_search_2 (bufp, string1, length1, string2, length2, start, range, regs, stop)
+    struct re_pattern_buffer *bufp;
+    const char *string1, *string2;
+    Idx length1, length2, start, stop;
+    regoff_t range;
+    struct re_registers *regs;
+{
+  return re_search_2_stub (bufp, string1, length1, string2, length2,
+                          start, range, regs, stop, false);
+}
+#ifdef _LIBC
+weak_alias (__re_search_2, re_search_2)
+#endif
+
+static regoff_t
+internal_function
+re_search_2_stub (struct re_pattern_buffer *bufp,
+                 const char *string1, Idx length1,
+                 const char *string2, Idx length2,
+                 Idx start, regoff_t range, struct re_registers *regs,
+                 Idx stop, bool ret_len)
+{
+  const char *str;
+  regoff_t rval;
+  Idx len = length1 + length2;
+  char *s = NULL;
+
+  if (BE (length1 < 0 || length2 < 0 || stop < 0 || len < length1, 0))
+    return -2;
+
+  /* Concatenate the strings.  */
+  if (length2 > 0)
+    if (length1 > 0)
+      {
+       s = re_malloc (char, len);
+
+       if (BE (s == NULL, 0))
+         return -2;
+#ifdef _LIBC
+       memcpy (__mempcpy (s, string1, length1), string2, length2);
+#else
+       memcpy (s, string1, length1);
+       memcpy (s + length1, string2, length2);
+#endif
+       str = s;
+      }
+    else
+      str = string2;
+  else
+    str = string1;
+
+  rval = re_search_stub (bufp, str, len, start, range, stop, regs,
+                        ret_len);
+  re_free (s);
+  return rval;
+}
+
+/* The parameters have the same meaning as those of re_search.
+   Additional parameters:
+   If RET_LEN is true the length of the match is returned (re_match style);
+   otherwise the position of the match is returned.  */
+
+static regoff_t
+internal_function
+re_search_stub (struct re_pattern_buffer *bufp,
+               const char *string, Idx length,
+               Idx start, regoff_t range, Idx stop, struct re_registers *regs,
+               bool ret_len)
+{
+  reg_errcode_t result;
+  regmatch_t *pmatch;
+  Idx nregs;
+  regoff_t rval;
+  int eflags = 0;
+#ifdef _LIBC
+  re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
+#endif
+  Idx last_start = start + range;
+
+  /* Check for out-of-range.  */
+  if (BE (start < 0 || start > length, 0))
+    return -1;
+  if (BE (length < last_start || (0 <= range && last_start < start), 0))
+    last_start = length;
+  else if (BE (last_start < 0 || (range < 0 && start <= last_start), 0))
+    last_start = 0;
+
+  __libc_lock_lock (dfa->lock);
+
+  eflags |= (bufp->not_bol) ? REG_NOTBOL : 0;
+  eflags |= (bufp->not_eol) ? REG_NOTEOL : 0;
+
+  /* Compile fastmap if we haven't yet.  */
+  if (start < last_start && bufp->fastmap != NULL && !bufp->fastmap_accurate)
+    re_compile_fastmap (bufp);
+
+  if (BE (bufp->no_sub, 0))
+    regs = NULL;
+
+  /* We need at least 1 register.  */
+  if (regs == NULL)
+    nregs = 1;
+  else if (BE (bufp->regs_allocated == REGS_FIXED
+              && regs->num_regs <= bufp->re_nsub, 0))
+    {
+      nregs = regs->num_regs;
+      if (BE (nregs < 1, 0))
+       {
+         /* Nothing can be copied to regs.  */
+         regs = NULL;
+         nregs = 1;
+       }
+    }
+  else
+    nregs = bufp->re_nsub + 1;
+  pmatch = re_malloc (regmatch_t, nregs);
+  if (BE (pmatch == NULL, 0))
+    {
+      rval = -2;
+      goto out;
+    }
+
+  result = re_search_internal (bufp, string, length, start, last_start, stop,
+                              nregs, pmatch, eflags);
+
+  rval = 0;
+
+  /* I hope we needn't fill ther regs with -1's when no match was found.  */
+  if (result != REG_NOERROR)
+    rval = -1;
+  else if (regs != NULL)
+    {
+      /* If caller wants register contents data back, copy them.  */
+      bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs,
+                                          bufp->regs_allocated);
+      if (BE (bufp->regs_allocated == REGS_UNALLOCATED, 0))
+       rval = -2;
+    }
+
+  if (BE (rval == 0, 1))
+    {
+      if (ret_len)
+       {
+         assert (pmatch[0].rm_so == start);
+         rval = pmatch[0].rm_eo - start;
+       }
+      else
+       rval = pmatch[0].rm_so;
+    }
+  re_free (pmatch);
+ out:
+  __libc_lock_unlock (dfa->lock);
+  return rval;
+}
+
+static unsigned int
+internal_function
+re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, Idx nregs,
+             int regs_allocated)
+{
+  int rval = REGS_REALLOCATE;
+  Idx i;
+  Idx need_regs = nregs + 1;
+  /* We need one extra element beyond `num_regs' for the `-1' marker GNU code
+     uses.  */
+
+  /* Have the register data arrays been allocated?  */
+  if (regs_allocated == REGS_UNALLOCATED)
+    { /* No.  So allocate them with malloc.  */
+      regs->start = re_malloc (regoff_t, need_regs);
+      if (BE (regs->start == NULL, 0))
+       return REGS_UNALLOCATED;
+      regs->end = re_malloc (regoff_t, need_regs);
+      if (BE (regs->end == NULL, 0))
+       {
+         re_free (regs->start);
+         return REGS_UNALLOCATED;
+       }
+      regs->num_regs = need_regs;
+    }
+  else if (regs_allocated == REGS_REALLOCATE)
+    { /* Yes.  If we need more elements than were already
+        allocated, reallocate them.  If we need fewer, just
+        leave it alone.  */
+      if (BE (need_regs > regs->num_regs, 0))
+       {
+         regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs);
+         regoff_t *new_end;
+         if (BE (new_start == NULL, 0))
+           return REGS_UNALLOCATED;
+         new_end = re_realloc (regs->end, regoff_t, need_regs);
+         if (BE (new_end == NULL, 0))
+           {
+             re_free (new_start);
+             return REGS_UNALLOCATED;
+           }
+         regs->start = new_start;
+         regs->end = new_end;
+         regs->num_regs = need_regs;
+       }
+    }
+  else
+    {
+      assert (regs_allocated == REGS_FIXED);
+      /* This function may not be called with REGS_FIXED and nregs too big.  */
+      assert (regs->num_regs >= nregs);
+      rval = REGS_FIXED;
+    }
+
+  /* Copy the regs.  */
+  for (i = 0; i < nregs; ++i)
+    {
+      regs->start[i] = pmatch[i].rm_so;
+      regs->end[i] = pmatch[i].rm_eo;
+    }
+  for ( ; i < regs->num_regs; ++i)
+    regs->start[i] = regs->end[i] = -1;
+
+  return rval;
+}
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+   ENDS.  Subsequent matches using PATTERN_BUFFER and REGS will use
+   this memory for recording register information.  STARTS and ENDS
+   must be allocated using the malloc library routine, and must each
+   be at least NUM_REGS * sizeof (regoff_t) bytes long.
+
+   If NUM_REGS == 0, then subsequent matches should allocate their own
+   register data.
+
+   Unless this function is called, the first search or match using
+   PATTERN_BUFFER will allocate its own register data, without
+   freeing the old data.  */
+
+void
+re_set_registers (bufp, regs, num_regs, starts, ends)
+    struct re_pattern_buffer *bufp;
+    struct re_registers *regs;
+    __re_size_t num_regs;
+    regoff_t *starts, *ends;
+{
+  if (num_regs)
+    {
+      bufp->regs_allocated = REGS_REALLOCATE;
+      regs->num_regs = num_regs;
+      regs->start = starts;
+      regs->end = ends;
+    }
+  else
+    {
+      bufp->regs_allocated = REGS_UNALLOCATED;
+      regs->num_regs = 0;
+      regs->start = regs->end = NULL;
+    }
+}
+#ifdef _LIBC
+weak_alias (__re_set_registers, re_set_registers)
+#endif
+\f
+/* Entry points compatible with 4.2 BSD regex library.  We don't define
+   them unless specifically requested.  */
+
+#if defined _REGEX_RE_COMP || defined _LIBC
+int
+# ifdef _LIBC
+weak_function
+# endif
+re_exec (s)
+     const char *s;
+{
+  return 0 == regexec (&re_comp_buf, s, 0, NULL, 0);
+}
+#endif /* _REGEX_RE_COMP */
+\f
+/* Internal entry point.  */
+
+/* Searches for a compiled pattern PREG in the string STRING, whose
+   length is LENGTH.  NMATCH, PMATCH, and EFLAGS have the same
+   meaning as with regexec.  LAST_START is START + RANGE, where
+   START and RANGE have the same meaning as with re_search.
+   Return REG_NOERROR if we find a match, and REG_NOMATCH if not,
+   otherwise return the error code.
+   Note: We assume front end functions already check ranges.
+   (0 <= LAST_START && LAST_START <= LENGTH)  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_search_internal (const regex_t *preg,
+                   const char *string, Idx length,
+                   Idx start, Idx last_start, Idx stop,
+                   size_t nmatch, regmatch_t pmatch[],
+                   int eflags)
+{
+  reg_errcode_t err;
+  const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer;
+  Idx left_lim, right_lim;
+  int incr;
+  bool fl_longest_match;
+  int match_kind;
+  Idx match_first;
+  Idx match_last = REG_MISSING;
+  Idx extra_nmatch;
+  bool sb;
+  int ch;
+#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
+  re_match_context_t mctx = { .dfa = dfa };
+#else
+  re_match_context_t mctx;
+#endif
+  char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate
+                   && start != last_start && !preg->can_be_null)
+                  ? preg->fastmap : NULL);
+  RE_TRANSLATE_TYPE t = preg->translate;
+
+#if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
+  memset (&mctx, '\0', sizeof (re_match_context_t));
+  mctx.dfa = dfa;
+#endif
+
+  extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0;
+  nmatch -= extra_nmatch;
+
+  /* Check if the DFA haven't been compiled.  */
+  if (BE (preg->used == 0 || dfa->init_state == NULL
+         || dfa->init_state_word == NULL || dfa->init_state_nl == NULL
+         || dfa->init_state_begbuf == NULL, 0))
+    return REG_NOMATCH;
+
+#ifdef DEBUG
+  /* We assume front-end functions already check them.  */
+  assert (0 <= last_start && last_start <= length);
+#endif
+
+  /* If initial states with non-begbuf contexts have no elements,
+     the regex must be anchored.  If preg->newline_anchor is set,
+     we'll never use init_state_nl, so do not check it.  */
+  if (dfa->init_state->nodes.nelem == 0
+      && dfa->init_state_word->nodes.nelem == 0
+      && (dfa->init_state_nl->nodes.nelem == 0
+         || !preg->newline_anchor))
+    {
+      if (start != 0 && last_start != 0)
+        return REG_NOMATCH;
+      start = last_start = 0;
+    }
+
+  /* We must check the longest matching, if nmatch > 0.  */
+  fl_longest_match = (nmatch != 0 || dfa->nbackref);
+
+  err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1,
+                           preg->translate, (preg->syntax & RE_ICASE) != 0,
+                           dfa);
+  if (BE (err != REG_NOERROR, 0))
+    goto free_return;
+  mctx.input.stop = stop;
+  mctx.input.raw_stop = stop;
+  mctx.input.newline_anchor = preg->newline_anchor;
+
+  err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2);
+  if (BE (err != REG_NOERROR, 0))
+    goto free_return;
+
+  /* We will log all the DFA states through which the dfa pass,
+     if nmatch > 1, or this dfa has "multibyte node", which is a
+     back-reference or a node which can accept multibyte character or
+     multi character collating element.  */
+  if (nmatch > 1 || dfa->has_mb_node)
+    {
+      /* Avoid overflow.  */
+      if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= mctx.input.bufs_len, 0))
+       {
+         err = REG_ESPACE;
+         goto free_return;
+       }
+
+      mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1);
+      if (BE (mctx.state_log == NULL, 0))
+       {
+         err = REG_ESPACE;
+         goto free_return;
+       }
+    }
+  else
+    mctx.state_log = NULL;
+
+  match_first = start;
+  mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
+                          : CONTEXT_NEWLINE | CONTEXT_BEGBUF;
+
+  /* Check incrementally whether of not the input string match.  */
+  incr = (last_start < start) ? -1 : 1;
+  left_lim = (last_start < start) ? last_start : start;
+  right_lim = (last_start < start) ? start : last_start;
+  sb = dfa->mb_cur_max == 1;
+  match_kind =
+    (fastmap
+     ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)
+       | (start <= last_start ? 2 : 0)
+       | (t != NULL ? 1 : 0))
+     : 8);
+
+  for (;; match_first += incr)
+    {
+      err = REG_NOMATCH;
+      if (match_first < left_lim || right_lim < match_first)
+       goto free_return;
+
+      /* Advance as rapidly as possible through the string, until we
+        find a plausible place to start matching.  This may be done
+        with varying efficiency, so there are various possibilities:
+        only the most common of them are specialized, in order to
+        save on code size.  We use a switch statement for speed.  */
+      switch (match_kind)
+       {
+       case 8:
+         /* No fastmap.  */
+         break;
+
+       case 7:
+         /* Fastmap with single-byte translation, match forward.  */
+         while (BE (match_first < right_lim, 1)
+                && !fastmap[t[(unsigned char) string[match_first]]])
+           ++match_first;
+         goto forward_match_found_start_or_reached_end;
+
+       case 6:
+         /* Fastmap without translation, match forward.  */
+         while (BE (match_first < right_lim, 1)
+                && !fastmap[(unsigned char) string[match_first]])
+           ++match_first;
+
+       forward_match_found_start_or_reached_end:
+         if (BE (match_first == right_lim, 0))
+           {
+             ch = match_first >= length
+                      ? 0 : (unsigned char) string[match_first];
+             if (!fastmap[t ? t[ch] : ch])
+               goto free_return;
+           }
+         break;
+
+       case 4:
+       case 5:
+         /* Fastmap without multi-byte translation, match backwards.  */
+         while (match_first >= left_lim)
+           {
+             ch = match_first >= length
+                      ? 0 : (unsigned char) string[match_first];
+             if (fastmap[t ? t[ch] : ch])
+               break;
+             --match_first;
+           }
+         if (match_first < left_lim)
+           goto free_return;
+         break;
+
+       default:
+         /* In this case, we can't determine easily the current byte,
+            since it might be a component byte of a multibyte
+            character.  Then we use the constructed buffer instead.  */
+         for (;;)
+           {
+             /* If MATCH_FIRST is out of the valid range, reconstruct the
+                buffers.  */
+             __re_size_t offset = match_first - mctx.input.raw_mbs_idx;
+             if (BE (offset >= (__re_size_t) mctx.input.valid_raw_len, 0))
+               {
+                 err = re_string_reconstruct (&mctx.input, match_first,
+                                              eflags);
+                 if (BE (err != REG_NOERROR, 0))
+                   goto free_return;
+
+                 offset = match_first - mctx.input.raw_mbs_idx;
+               }
+             /* If MATCH_FIRST is out of the buffer, leave it as '\0'.
+                Note that MATCH_FIRST must not be smaller than 0.  */
+             ch = (match_first >= length
+                   ? 0 : re_string_byte_at (&mctx.input, offset));
+             if (fastmap[ch])
+               break;
+             match_first += incr;
+             if (match_first < left_lim || match_first > right_lim)
+               {
+                 err = REG_NOMATCH;
+                 goto free_return;
+               }
+           }
+         break;
+       }
+
+      /* Reconstruct the buffers so that the matcher can assume that
+        the matching starts from the beginning of the buffer.  */
+      err = re_string_reconstruct (&mctx.input, match_first, eflags);
+      if (BE (err != REG_NOERROR, 0))
+       goto free_return;
+
+#ifdef RE_ENABLE_I18N
+     /* Don't consider this char as a possible match start if it part,
+       yet isn't the head, of a multibyte character.  */
+      if (!sb && !re_string_first_byte (&mctx.input, 0))
+       continue;
+#endif
+
+      /* It seems to be appropriate one, then use the matcher.  */
+      /* We assume that the matching starts from 0.  */
+      mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;
+      match_last = check_matching (&mctx, fl_longest_match,
+                                  start <= last_start ? &match_first : NULL);
+      if (match_last != REG_MISSING)
+       {
+         if (BE (match_last == REG_ERROR, 0))
+           {
+             err = REG_ESPACE;
+             goto free_return;
+           }
+         else
+           {
+             mctx.match_last = match_last;
+             if ((!preg->no_sub && nmatch > 1) || dfa->nbackref)
+               {
+                 re_dfastate_t *pstate = mctx.state_log[match_last];
+                 mctx.last_node = check_halt_state_context (&mctx, pstate,
+                                                            match_last);
+               }
+             if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match)
+                 || dfa->nbackref)
+               {
+                 err = prune_impossible_nodes (&mctx);
+                 if (err == REG_NOERROR)
+                   break;
+                 if (BE (err != REG_NOMATCH, 0))
+                   goto free_return;
+                 match_last = REG_MISSING;
+               }
+             else
+               break; /* We found a match.  */
+           }
+       }
+
+      match_ctx_clean (&mctx);
+    }
+
+#ifdef DEBUG
+  assert (match_last != REG_MISSING);
+  assert (err == REG_NOERROR);
+#endif
+
+  /* Set pmatch[] if we need.  */
+  if (nmatch > 0)
+    {
+      Idx reg_idx;
+
+      /* Initialize registers.  */
+      for (reg_idx = 1; reg_idx < nmatch; ++reg_idx)
+       pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1;
+
+      /* Set the points where matching start/end.  */
+      pmatch[0].rm_so = 0;
+      pmatch[0].rm_eo = mctx.match_last;
+      /* FIXME: This function should fail if mctx.match_last exceeds
+        the maximum possible regoff_t value.  We need a new error
+        code REG_OVERFLOW.  */
+
+      if (!preg->no_sub && nmatch > 1)
+       {
+         err = set_regs (preg, &mctx, nmatch, pmatch,
+                         dfa->has_plural_match && dfa->nbackref > 0);
+         if (BE (err != REG_NOERROR, 0))
+           goto free_return;
+       }
+
+      /* At last, add the offset to the each registers, since we slided
+        the buffers so that we could assume that the matching starts
+        from 0.  */
+      for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
+       if (pmatch[reg_idx].rm_so != -1)
+         {
+#ifdef RE_ENABLE_I18N
+           if (BE (mctx.input.offsets_needed != 0, 0))
+             {
+               pmatch[reg_idx].rm_so =
+                 (pmatch[reg_idx].rm_so == mctx.input.valid_len
+                  ? mctx.input.valid_raw_len
+                  : mctx.input.offsets[pmatch[reg_idx].rm_so]);
+               pmatch[reg_idx].rm_eo =
+                 (pmatch[reg_idx].rm_eo == mctx.input.valid_len
+                  ? mctx.input.valid_raw_len
+                  : mctx.input.offsets[pmatch[reg_idx].rm_eo]);
+             }
+#else
+           assert (mctx.input.offsets_needed == 0);
+#endif
+           pmatch[reg_idx].rm_so += match_first;
+           pmatch[reg_idx].rm_eo += match_first;
+         }
+      for (reg_idx = 0; reg_idx < extra_nmatch; ++reg_idx)
+       {
+         pmatch[nmatch + reg_idx].rm_so = -1;
+         pmatch[nmatch + reg_idx].rm_eo = -1;
+       }
+
+      if (dfa->subexp_map)
+       for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++)
+         if (dfa->subexp_map[reg_idx] != reg_idx)
+           {
+             pmatch[reg_idx + 1].rm_so
+               = pmatch[dfa->subexp_map[reg_idx] + 1].rm_so;
+             pmatch[reg_idx + 1].rm_eo
+               = pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo;
+           }
+    }
+
+ free_return:
+  re_free (mctx.state_log);
+  if (dfa->nbackref)
+    match_ctx_free (&mctx);
+  re_string_destruct (&mctx.input);
+  return err;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+prune_impossible_nodes (re_match_context_t *mctx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  Idx halt_node, match_last;
+  reg_errcode_t ret;
+  re_dfastate_t **sifted_states;
+  re_dfastate_t **lim_states = NULL;
+  re_sift_context_t sctx;
+#ifdef DEBUG
+  assert (mctx->state_log != NULL);
+#endif
+  match_last = mctx->match_last;
+  halt_node = mctx->last_node;
+
+  /* Avoid overflow.  */
+  if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= match_last, 0))
+    return REG_ESPACE;
+
+  sifted_states = re_malloc (re_dfastate_t *, match_last + 1);
+  if (BE (sifted_states == NULL, 0))
+    {
+      ret = REG_ESPACE;
+      goto free_return;
+    }
+  if (dfa->nbackref)
+    {
+      lim_states = re_malloc (re_dfastate_t *, match_last + 1);
+      if (BE (lim_states == NULL, 0))
+       {
+         ret = REG_ESPACE;
+         goto free_return;
+       }
+      while (1)
+       {
+         memset (lim_states, '\0',
+                 sizeof (re_dfastate_t *) * (match_last + 1));
+         sift_ctx_init (&sctx, sifted_states, lim_states, halt_node,
+                        match_last);
+         ret = sift_states_backward (mctx, &sctx);
+         re_node_set_free (&sctx.limits);
+         if (BE (ret != REG_NOERROR, 0))
+             goto free_return;
+         if (sifted_states[0] != NULL || lim_states[0] != NULL)
+           break;
+         do
+           {
+             --match_last;
+             if (! REG_VALID_INDEX (match_last))
+               {
+                 ret = REG_NOMATCH;
+                 goto free_return;
+               }
+           } while (mctx->state_log[match_last] == NULL
+                    || !mctx->state_log[match_last]->halt);
+         halt_node = check_halt_state_context (mctx,
+                                               mctx->state_log[match_last],
+                                               match_last);
+       }
+      ret = merge_state_array (dfa, sifted_states, lim_states,
+                              match_last + 1);
+      re_free (lim_states);
+      lim_states = NULL;
+      if (BE (ret != REG_NOERROR, 0))
+       goto free_return;
+    }
+  else
+    {
+      sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, match_last);
+      ret = sift_states_backward (mctx, &sctx);
+      re_node_set_free (&sctx.limits);
+      if (BE (ret != REG_NOERROR, 0))
+       goto free_return;
+      if (sifted_states[0] == NULL)
+       {
+         ret = REG_NOMATCH;
+         goto free_return;
+       }
+    }
+  re_free (mctx->state_log);
+  mctx->state_log = sifted_states;
+  sifted_states = NULL;
+  mctx->last_node = halt_node;
+  mctx->match_last = match_last;
+  ret = REG_NOERROR;
+ free_return:
+  re_free (sifted_states);
+  re_free (lim_states);
+  return ret;
+}
+
+/* Acquire an initial state and return it.
+   We must select appropriate initial state depending on the context,
+   since initial states may have constraints like "\<", "^", etc..  */
+
+static inline re_dfastate_t *
+__attribute ((always_inline)) internal_function
+acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx,
+                           Idx idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  if (dfa->init_state->has_constraint)
+    {
+      unsigned int context;
+      context = re_string_context_at (&mctx->input, idx - 1, mctx->eflags);
+      if (IS_WORD_CONTEXT (context))
+       return dfa->init_state_word;
+      else if (IS_ORDINARY_CONTEXT (context))
+       return dfa->init_state;
+      else if (IS_BEGBUF_CONTEXT (context) && IS_NEWLINE_CONTEXT (context))
+       return dfa->init_state_begbuf;
+      else if (IS_NEWLINE_CONTEXT (context))
+       return dfa->init_state_nl;
+      else if (IS_BEGBUF_CONTEXT (context))
+       {
+         /* It is relatively rare case, then calculate on demand.  */
+         return re_acquire_state_context (err, dfa,
+                                          dfa->init_state->entrance_nodes,
+                                          context);
+       }
+      else
+       /* Must not happen?  */
+       return dfa->init_state;
+    }
+  else
+    return dfa->init_state;
+}
+
+/* Check whether the regular expression match input string INPUT or not,
+   and return the index where the matching end.  Return REG_MISSING if
+   there is no match, and return REG_ERROR in case of an error.
+   FL_LONGEST_MATCH means we want the POSIX longest matching.
+   If P_MATCH_FIRST is not NULL, and the match fails, it is set to the
+   next place where we may want to try matching.
+   Note that the matcher assume that the maching starts from the current
+   index of the buffer.  */
+
+static Idx
+internal_function __attribute_warn_unused_result__
+check_matching (re_match_context_t *mctx, bool fl_longest_match,
+               Idx *p_match_first)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err;
+  Idx match = 0;
+  Idx match_last = REG_MISSING;
+  Idx cur_str_idx = re_string_cur_idx (&mctx->input);
+  re_dfastate_t *cur_state;
+  bool at_init_state = p_match_first != NULL;
+  Idx next_start_idx = cur_str_idx;
+
+  err = REG_NOERROR;
+  cur_state = acquire_init_state_context (&err, mctx, cur_str_idx);
+  /* An initial state must not be NULL (invalid).  */
+  if (BE (cur_state == NULL, 0))
+    {
+      assert (err == REG_ESPACE);
+      return REG_ERROR;
+    }
+
+  if (mctx->state_log != NULL)
+    {
+      mctx->state_log[cur_str_idx] = cur_state;
+
+      /* Check OP_OPEN_SUBEXP in the initial state in case that we use them
+        later.  E.g. Processing back references.  */
+      if (BE (dfa->nbackref, 0))
+       {
+         at_init_state = false;
+         err = check_subexp_matching_top (mctx, &cur_state->nodes, 0);
+         if (BE (err != REG_NOERROR, 0))
+           return err;
+
+         if (cur_state->has_backref)
+           {
+             err = transit_state_bkref (mctx, &cur_state->nodes);
+             if (BE (err != REG_NOERROR, 0))
+               return err;
+           }
+       }
+    }
+
+  /* If the RE accepts NULL string.  */
+  if (BE (cur_state->halt, 0))
+    {
+      if (!cur_state->has_constraint
+         || check_halt_state_context (mctx, cur_state, cur_str_idx))
+       {
+         if (!fl_longest_match)
+           return cur_str_idx;
+         else
+           {
+             match_last = cur_str_idx;
+             match = 1;
+           }
+       }
+    }
+
+  while (!re_string_eoi (&mctx->input))
+    {
+      re_dfastate_t *old_state = cur_state;
+      Idx next_char_idx = re_string_cur_idx (&mctx->input) + 1;
+
+      if (BE (next_char_idx >= mctx->input.bufs_len, 0)
+         || (BE (next_char_idx >= mctx->input.valid_len, 0)
+             && mctx->input.valid_len < mctx->input.len))
+       {
+         err = extend_buffers (mctx);
+         if (BE (err != REG_NOERROR, 0))
+           {
+             assert (err == REG_ESPACE);
+             return REG_ERROR;
+           }
+       }
+
+      cur_state = transit_state (&err, mctx, cur_state);
+      if (mctx->state_log != NULL)
+       cur_state = merge_state_with_log (&err, mctx, cur_state);
+
+      if (cur_state == NULL)
+       {
+         /* Reached the invalid state or an error.  Try to recover a valid
+            state using the state log, if available and if we have not
+            already found a valid (even if not the longest) match.  */
+         if (BE (err != REG_NOERROR, 0))
+           return REG_ERROR;
+
+         if (mctx->state_log == NULL
+             || (match && !fl_longest_match)
+             || (cur_state = find_recover_state (&err, mctx)) == NULL)
+           break;
+       }
+
+      if (BE (at_init_state, 0))
+       {
+         if (old_state == cur_state)
+           next_start_idx = next_char_idx;
+         else
+           at_init_state = false;
+       }
+
+      if (cur_state->halt)
+       {
+         /* Reached a halt state.
+            Check the halt state can satisfy the current context.  */
+         if (!cur_state->has_constraint
+             || check_halt_state_context (mctx, cur_state,
+                                          re_string_cur_idx (&mctx->input)))
+           {
+             /* We found an appropriate halt state.  */
+             match_last = re_string_cur_idx (&mctx->input);
+             match = 1;
+
+             /* We found a match, do not modify match_first below.  */
+             p_match_first = NULL;
+             if (!fl_longest_match)
+               break;
+           }
+       }
+    }
+
+  if (p_match_first)
+    *p_match_first += next_start_idx;
+
+  return match_last;
+}
+
+/* Check NODE match the current context.  */
+
+static bool
+internal_function
+check_halt_node_context (const re_dfa_t *dfa, Idx node, unsigned int context)
+{
+  re_token_type_t type = dfa->nodes[node].type;
+  unsigned int constraint = dfa->nodes[node].constraint;
+  if (type != END_OF_RE)
+    return false;
+  if (!constraint)
+    return true;
+  if (NOT_SATISFY_NEXT_CONSTRAINT (constraint, context))
+    return false;
+  return true;
+}
+
+/* Check the halt state STATE match the current context.
+   Return 0 if not match, if the node, STATE has, is a halt node and
+   match the context, return the node.  */
+
+static Idx
+internal_function
+check_halt_state_context (const re_match_context_t *mctx,
+                         const re_dfastate_t *state, Idx idx)
+{
+  Idx i;
+  unsigned int context;
+#ifdef DEBUG
+  assert (state->halt);
+#endif
+  context = re_string_context_at (&mctx->input, idx, mctx->eflags);
+  for (i = 0; i < state->nodes.nelem; ++i)
+    if (check_halt_node_context (mctx->dfa, state->nodes.elems[i], context))
+      return state->nodes.elems[i];
+  return 0;
+}
+
+/* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA
+   corresponding to the DFA).
+   Return the destination node, and update EPS_VIA_NODES;
+   return REG_MISSING in case of errors.  */
+
+static Idx
+internal_function
+proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
+                  Idx *pidx, Idx node, re_node_set *eps_via_nodes,
+                  struct re_fail_stack_t *fs)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  Idx i;
+  bool ok;
+  if (IS_EPSILON_NODE (dfa->nodes[node].type))
+    {
+      re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes;
+      re_node_set *edests = &dfa->edests[node];
+      Idx dest_node;
+      ok = re_node_set_insert (eps_via_nodes, node);
+      if (BE (! ok, 0))
+       return REG_ERROR;
+      /* Pick up a valid destination, or return REG_MISSING if none
+        is found.  */
+      for (dest_node = REG_MISSING, i = 0; i < edests->nelem; ++i)
+       {
+         Idx candidate = edests->elems[i];
+         if (!re_node_set_contains (cur_nodes, candidate))
+           continue;
+          if (dest_node == REG_MISSING)
+           dest_node = candidate;
+
+         else
+           {
+             /* In order to avoid infinite loop like "(a*)*", return the second
+                epsilon-transition if the first was already considered.  */
+             if (re_node_set_contains (eps_via_nodes, dest_node))
+               return candidate;
+
+             /* Otherwise, push the second epsilon-transition on the fail stack.  */
+             else if (fs != NULL
+                      && push_fail_stack (fs, *pidx, candidate, nregs, regs,
+                                          eps_via_nodes))
+               return REG_ERROR;
+
+             /* We know we are going to exit.  */
+             break;
+           }
+       }
+      return dest_node;
+    }
+  else
+    {
+      Idx naccepted = 0;
+      re_token_type_t type = dfa->nodes[node].type;
+
+#ifdef RE_ENABLE_I18N
+      if (dfa->nodes[node].accept_mb)
+       naccepted = check_node_accept_bytes (dfa, node, &mctx->input, *pidx);
+      else
+#endif /* RE_ENABLE_I18N */
+      if (type == OP_BACK_REF)
+       {
+         Idx subexp_idx = dfa->nodes[node].opr.idx + 1;
+         naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so;
+         if (fs != NULL)
+           {
+             if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1)
+               return REG_MISSING;
+             else if (naccepted)
+               {
+                 char *buf = (char *) re_string_get_buffer (&mctx->input);
+                 if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx,
+                             naccepted) != 0)
+                   return REG_MISSING;
+               }
+           }
+
+         if (naccepted == 0)
+           {
+             Idx dest_node;
+             ok = re_node_set_insert (eps_via_nodes, node);
+             if (BE (! ok, 0))
+               return REG_ERROR;
+             dest_node = dfa->edests[node].elems[0];
+             if (re_node_set_contains (&mctx->state_log[*pidx]->nodes,
+                                       dest_node))
+               return dest_node;
+           }
+       }
+
+      if (naccepted != 0
+         || check_node_accept (mctx, dfa->nodes + node, *pidx))
+       {
+         Idx dest_node = dfa->nexts[node];
+         *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted;
+         if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL
+                    || !re_node_set_contains (&mctx->state_log[*pidx]->nodes,
+                                              dest_node)))
+           return REG_MISSING;
+         re_node_set_empty (eps_via_nodes);
+         return dest_node;
+       }
+    }
+  return REG_MISSING;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node,
+                Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes)
+{
+  reg_errcode_t err;
+  Idx num = fs->num++;
+  if (fs->num == fs->alloc)
+    {
+      struct re_fail_stack_ent_t *new_array;
+      new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t)
+                                      * fs->alloc * 2));
+      if (new_array == NULL)
+       return REG_ESPACE;
+      fs->alloc *= 2;
+      fs->stack = new_array;
+    }
+  fs->stack[num].idx = str_idx;
+  fs->stack[num].node = dest_node;
+  fs->stack[num].regs = re_malloc (regmatch_t, nregs);
+  if (fs->stack[num].regs == NULL)
+    return REG_ESPACE;
+  memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);
+  err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes);
+  return err;
+}
+
+static Idx
+internal_function
+pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs,
+               regmatch_t *regs, re_node_set *eps_via_nodes)
+{
+  Idx num = --fs->num;
+  assert (REG_VALID_INDEX (num));
+  *pidx = fs->stack[num].idx;
+  memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);
+  re_node_set_free (eps_via_nodes);
+  re_free (fs->stack[num].regs);
+  *eps_via_nodes = fs->stack[num].eps_via_nodes;
+  return fs->stack[num].node;
+}
+
+/* Set the positions where the subexpressions are starts/ends to registers
+   PMATCH.
+   Note: We assume that pmatch[0] is already set, and
+   pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
+         regmatch_t *pmatch, bool fl_backtrack)
+{
+  const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer;
+  Idx idx, cur_node;
+  re_node_set eps_via_nodes;
+  struct re_fail_stack_t *fs;
+  struct re_fail_stack_t fs_body = { 0, 2, NULL };
+  regmatch_t *prev_idx_match;
+  bool prev_idx_match_malloced = false;
+
+#ifdef DEBUG
+  assert (nmatch > 1);
+  assert (mctx->state_log != NULL);
+#endif
+  if (fl_backtrack)
+    {
+      fs = &fs_body;
+      fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc);
+      if (fs->stack == NULL)
+       return REG_ESPACE;
+    }
+  else
+    fs = NULL;
+
+  cur_node = dfa->init_node;
+  re_node_set_init_empty (&eps_via_nodes);
+
+  if (__libc_use_alloca (nmatch * sizeof (regmatch_t)))
+    prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t));
+  else
+    {
+      prev_idx_match = re_malloc (regmatch_t, nmatch);
+      if (prev_idx_match == NULL)
+       {
+         free_fail_stack_return (fs);
+         return REG_ESPACE;
+       }
+      prev_idx_match_malloced = true;
+    }
+  memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
+
+  for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;)
+    {
+      update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch);
+
+      if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
+       {
+         Idx reg_idx;
+         if (fs)
+           {
+             for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
+               if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1)
+                 break;
+             if (reg_idx == nmatch)
+               {
+                 re_node_set_free (&eps_via_nodes);
+                 if (prev_idx_match_malloced)
+                   re_free (prev_idx_match);
+                 return free_fail_stack_return (fs);
+               }
+             cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
+                                        &eps_via_nodes);
+           }
+         else
+           {
+             re_node_set_free (&eps_via_nodes);
+             if (prev_idx_match_malloced)
+               re_free (prev_idx_match);
+             return REG_NOERROR;
+           }
+       }
+
+      /* Proceed to next node.  */
+      cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node,
+                                   &eps_via_nodes, fs);
+
+      if (BE (! REG_VALID_INDEX (cur_node), 0))
+       {
+         if (BE (cur_node == REG_ERROR, 0))
+           {
+             re_node_set_free (&eps_via_nodes);
+             if (prev_idx_match_malloced)
+               re_free (prev_idx_match);
+             free_fail_stack_return (fs);
+             return REG_ESPACE;
+           }
+         if (fs)
+           cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
+                                      &eps_via_nodes);
+         else
+           {
+             re_node_set_free (&eps_via_nodes);
+             if (prev_idx_match_malloced)
+               re_free (prev_idx_match);
+             return REG_NOMATCH;
+           }
+       }
+    }
+  re_node_set_free (&eps_via_nodes);
+  if (prev_idx_match_malloced)
+    re_free (prev_idx_match);
+  return free_fail_stack_return (fs);
+}
+
+static reg_errcode_t
+internal_function
+free_fail_stack_return (struct re_fail_stack_t *fs)
+{
+  if (fs)
+    {
+      Idx fs_idx;
+      for (fs_idx = 0; fs_idx < fs->num; ++fs_idx)
+       {
+         re_node_set_free (&fs->stack[fs_idx].eps_via_nodes);
+         re_free (fs->stack[fs_idx].regs);
+       }
+      re_free (fs->stack);
+    }
+  return REG_NOERROR;
+}
+
+static void
+internal_function
+update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,
+            regmatch_t *prev_idx_match, Idx cur_node, Idx cur_idx, Idx nmatch)
+{
+  int type = dfa->nodes[cur_node].type;
+  if (type == OP_OPEN_SUBEXP)
+    {
+      Idx reg_num = dfa->nodes[cur_node].opr.idx + 1;
+
+      /* We are at the first node of this sub expression.  */
+      if (reg_num < nmatch)
+       {
+         pmatch[reg_num].rm_so = cur_idx;
+         pmatch[reg_num].rm_eo = -1;
+       }
+    }
+  else if (type == OP_CLOSE_SUBEXP)
+    {
+      Idx reg_num = dfa->nodes[cur_node].opr.idx + 1;
+      if (reg_num < nmatch)
+       {
+         /* We are at the last node of this sub expression.  */
+         if (pmatch[reg_num].rm_so < cur_idx)
+           {
+             pmatch[reg_num].rm_eo = cur_idx;
+             /* This is a non-empty match or we are not inside an optional
+                subexpression.  Accept this right away.  */
+             memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
+           }
+         else
+           {
+             if (dfa->nodes[cur_node].opt_subexp
+                 && prev_idx_match[reg_num].rm_so != -1)
+               /* We transited through an empty match for an optional
+                  subexpression, like (a?)*, and this is not the subexp's
+                  first match.  Copy back the old content of the registers
+                  so that matches of an inner subexpression are undone as
+                  well, like in ((a?))*.  */
+               memcpy (pmatch, prev_idx_match, sizeof (regmatch_t) * nmatch);
+             else
+               /* We completed a subexpression, but it may be part of
+                  an optional one, so do not update PREV_IDX_MATCH.  */
+               pmatch[reg_num].rm_eo = cur_idx;
+           }
+       }
+    }
+}
+
+/* This function checks the STATE_LOG from the SCTX->last_str_idx to 0
+   and sift the nodes in each states according to the following rules.
+   Updated state_log will be wrote to STATE_LOG.
+
+   Rules: We throw away the Node `a' in the STATE_LOG[STR_IDX] if...
+     1. When STR_IDX == MATCH_LAST(the last index in the state_log):
+       If `a' isn't the LAST_NODE and `a' can't epsilon transit to
+       the LAST_NODE, we throw away the node `a'.
+     2. When 0 <= STR_IDX < MATCH_LAST and `a' accepts
+       string `s' and transit to `b':
+       i. If 'b' isn't in the STATE_LOG[STR_IDX+strlen('s')], we throw
+          away the node `a'.
+       ii. If 'b' is in the STATE_LOG[STR_IDX+strlen('s')] but 'b' is
+           thrown away, we throw away the node `a'.
+     3. When 0 <= STR_IDX < MATCH_LAST and 'a' epsilon transit to 'b':
+       i. If 'b' isn't in the STATE_LOG[STR_IDX], we throw away the
+          node `a'.
+       ii. If 'b' is in the STATE_LOG[STR_IDX] but 'b' is thrown away,
+           we throw away the node `a'.  */
+
+#define STATE_NODE_CONTAINS(state,node) \
+  ((state) != NULL && re_node_set_contains (&(state)->nodes, node))
+
+static reg_errcode_t
+internal_function
+sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx)
+{
+  reg_errcode_t err;
+  int null_cnt = 0;
+  Idx str_idx = sctx->last_str_idx;
+  re_node_set cur_dest;
+
+#ifdef DEBUG
+  assert (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL);
+#endif
+
+  /* Build sifted state_log[str_idx].  It has the nodes which can epsilon
+     transit to the last_node and the last_node itself.  */
+  err = re_node_set_init_1 (&cur_dest, sctx->last_node);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+  err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
+  if (BE (err != REG_NOERROR, 0))
+    goto free_return;
+
+  /* Then check each states in the state_log.  */
+  while (str_idx > 0)
+    {
+      /* Update counters.  */
+      null_cnt = (sctx->sifted_states[str_idx] == NULL) ? null_cnt + 1 : 0;
+      if (null_cnt > mctx->max_mb_elem_len)
+       {
+         memset (sctx->sifted_states, '\0',
+                 sizeof (re_dfastate_t *) * str_idx);
+         re_node_set_free (&cur_dest);
+         return REG_NOERROR;
+       }
+      re_node_set_empty (&cur_dest);
+      --str_idx;
+
+      if (mctx->state_log[str_idx])
+       {
+         err = build_sifted_states (mctx, sctx, str_idx, &cur_dest);
+         if (BE (err != REG_NOERROR, 0))
+           goto free_return;
+       }
+
+      /* Add all the nodes which satisfy the following conditions:
+        - It can epsilon transit to a node in CUR_DEST.
+        - It is in CUR_SRC.
+        And update state_log.  */
+      err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
+      if (BE (err != REG_NOERROR, 0))
+       goto free_return;
+    }
+  err = REG_NOERROR;
+ free_return:
+  re_node_set_free (&cur_dest);
+  return err;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx,
+                    Idx str_idx, re_node_set *cur_dest)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  const re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes;
+  Idx i;
+
+  /* Then build the next sifted state.
+     We build the next sifted state on `cur_dest', and update
+     `sifted_states[str_idx]' with `cur_dest'.
+     Note:
+     `cur_dest' is the sifted state from `state_log[str_idx + 1]'.
+     `cur_src' points the node_set of the old `state_log[str_idx]'
+     (with the epsilon nodes pre-filtered out).  */
+  for (i = 0; i < cur_src->nelem; i++)
+    {
+      Idx prev_node = cur_src->elems[i];
+      int naccepted = 0;
+      bool ok;
+
+#ifdef DEBUG
+      re_token_type_t type = dfa->nodes[prev_node].type;
+      assert (!IS_EPSILON_NODE (type));
+#endif
+#ifdef RE_ENABLE_I18N
+      /* If the node may accept `multi byte'.  */
+      if (dfa->nodes[prev_node].accept_mb)
+       naccepted = sift_states_iter_mb (mctx, sctx, prev_node,
+                                        str_idx, sctx->last_str_idx);
+#endif /* RE_ENABLE_I18N */
+
+      /* We don't check backreferences here.
+        See update_cur_sifted_state().  */
+      if (!naccepted
+         && check_node_accept (mctx, dfa->nodes + prev_node, str_idx)
+         && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1],
+                                 dfa->nexts[prev_node]))
+       naccepted = 1;
+
+      if (naccepted == 0)
+       continue;
+
+      if (sctx->limits.nelem)
+       {
+         Idx to_idx = str_idx + naccepted;
+         if (check_dst_limits (mctx, &sctx->limits,
+                               dfa->nexts[prev_node], to_idx,
+                               prev_node, str_idx))
+           continue;
+       }
+      ok = re_node_set_insert (cur_dest, prev_node);
+      if (BE (! ok, 0))
+       return REG_ESPACE;
+    }
+
+  return REG_NOERROR;
+}
+
+/* Helper functions.  */
+
+static reg_errcode_t
+internal_function
+clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx)
+{
+  Idx top = mctx->state_log_top;
+
+  if (next_state_log_idx >= mctx->input.bufs_len
+      || (next_state_log_idx >= mctx->input.valid_len
+         && mctx->input.valid_len < mctx->input.len))
+    {
+      reg_errcode_t err;
+      err = extend_buffers (mctx);
+      if (BE (err != REG_NOERROR, 0))
+       return err;
+    }
+
+  if (top < next_state_log_idx)
+    {
+      memset (mctx->state_log + top + 1, '\0',
+             sizeof (re_dfastate_t *) * (next_state_log_idx - top));
+      mctx->state_log_top = next_state_log_idx;
+    }
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function
+merge_state_array (const re_dfa_t *dfa, re_dfastate_t **dst,
+                  re_dfastate_t **src, Idx num)
+{
+  Idx st_idx;
+  reg_errcode_t err;
+  for (st_idx = 0; st_idx < num; ++st_idx)
+    {
+      if (dst[st_idx] == NULL)
+       dst[st_idx] = src[st_idx];
+      else if (src[st_idx] != NULL)
+       {
+         re_node_set merged_set;
+         err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes,
+                                       &src[st_idx]->nodes);
+         if (BE (err != REG_NOERROR, 0))
+           return err;
+         dst[st_idx] = re_acquire_state (&err, dfa, &merged_set);
+         re_node_set_free (&merged_set);
+         if (BE (err != REG_NOERROR, 0))
+           return err;
+       }
+    }
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function
+update_cur_sifted_state (const re_match_context_t *mctx,
+                        re_sift_context_t *sctx, Idx str_idx,
+                        re_node_set *dest_nodes)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err = REG_NOERROR;
+  const re_node_set *candidates;
+  candidates = ((mctx->state_log[str_idx] == NULL) ? NULL
+               : &mctx->state_log[str_idx]->nodes);
+
+  if (dest_nodes->nelem == 0)
+    sctx->sifted_states[str_idx] = NULL;
+  else
+    {
+      if (candidates)
+       {
+         /* At first, add the nodes which can epsilon transit to a node in
+            DEST_NODE.  */
+         err = add_epsilon_src_nodes (dfa, dest_nodes, candidates);
+         if (BE (err != REG_NOERROR, 0))
+           return err;
+
+         /* Then, check the limitations in the current sift_context.  */
+         if (sctx->limits.nelem)
+           {
+             err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits,
+                                        mctx->bkref_ents, str_idx);
+             if (BE (err != REG_NOERROR, 0))
+               return err;
+           }
+       }
+
+      sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes);
+      if (BE (err != REG_NOERROR, 0))
+       return err;
+    }
+
+  if (candidates && mctx->state_log[str_idx]->has_backref)
+    {
+      err = sift_states_bkref (mctx, sctx, str_idx, candidates);
+      if (BE (err != REG_NOERROR, 0))
+       return err;
+    }
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes,
+                      const re_node_set *candidates)
+{
+  reg_errcode_t err = REG_NOERROR;
+  Idx i;
+
+  re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+
+  if (!state->inveclosure.alloc)
+    {
+      err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem);
+      if (BE (err != REG_NOERROR, 0))
+       return REG_ESPACE;
+      for (i = 0; i < dest_nodes->nelem; i++)
+       {
+         err = re_node_set_merge (&state->inveclosure,
+                                  dfa->inveclosures + dest_nodes->elems[i]);
+         if (BE (err != REG_NOERROR, 0))
+           return REG_ESPACE;
+       }
+    }
+  return re_node_set_add_intersect (dest_nodes, candidates,
+                                   &state->inveclosure);
+}
+
+static reg_errcode_t
+internal_function
+sub_epsilon_src_nodes (const re_dfa_t *dfa, Idx node, re_node_set *dest_nodes,
+                      const re_node_set *candidates)
+{
+    Idx ecl_idx;
+    reg_errcode_t err;
+    re_node_set *inv_eclosure = dfa->inveclosures + node;
+    re_node_set except_nodes;
+    re_node_set_init_empty (&except_nodes);
+    for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
+      {
+       Idx cur_node = inv_eclosure->elems[ecl_idx];
+       if (cur_node == node)
+         continue;
+       if (IS_EPSILON_NODE (dfa->nodes[cur_node].type))
+         {
+           Idx edst1 = dfa->edests[cur_node].elems[0];
+           Idx edst2 = ((dfa->edests[cur_node].nelem > 1)
+                        ? dfa->edests[cur_node].elems[1] : REG_MISSING);
+           if ((!re_node_set_contains (inv_eclosure, edst1)
+                && re_node_set_contains (dest_nodes, edst1))
+               || (REG_VALID_NONZERO_INDEX (edst2)
+                   && !re_node_set_contains (inv_eclosure, edst2)
+                   && re_node_set_contains (dest_nodes, edst2)))
+             {
+               err = re_node_set_add_intersect (&except_nodes, candidates,
+                                                dfa->inveclosures + cur_node);
+               if (BE (err != REG_NOERROR, 0))
+                 {
+                   re_node_set_free (&except_nodes);
+                   return err;
+                 }
+             }
+         }
+      }
+    for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
+      {
+       Idx cur_node = inv_eclosure->elems[ecl_idx];
+       if (!re_node_set_contains (&except_nodes, cur_node))
+         {
+           Idx idx = re_node_set_contains (dest_nodes, cur_node) - 1;
+           re_node_set_remove_at (dest_nodes, idx);
+         }
+      }
+    re_node_set_free (&except_nodes);
+    return REG_NOERROR;
+}
+
+static bool
+internal_function
+check_dst_limits (const re_match_context_t *mctx, const re_node_set *limits,
+                 Idx dst_node, Idx dst_idx, Idx src_node, Idx src_idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  Idx lim_idx, src_pos, dst_pos;
+
+  Idx dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx);
+  Idx src_bkref_idx = search_cur_bkref_entry (mctx, src_idx);
+  for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
+    {
+      Idx subexp_idx;
+      struct re_backref_cache_entry *ent;
+      ent = mctx->bkref_ents + limits->elems[lim_idx];
+      subexp_idx = dfa->nodes[ent->node].opr.idx;
+
+      dst_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
+                                          subexp_idx, dst_node, dst_idx,
+                                          dst_bkref_idx);
+      src_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
+                                          subexp_idx, src_node, src_idx,
+                                          src_bkref_idx);
+
+      /* In case of:
+        <src> <dst> ( <subexp> )
+        ( <subexp> ) <src> <dst>
+        ( <subexp1> <src> <subexp2> <dst> <subexp3> )  */
+      if (src_pos == dst_pos)
+       continue; /* This is unrelated limitation.  */
+      else
+       return true;
+    }
+  return false;
+}
+
+static int
+internal_function
+check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries,
+                            Idx subexp_idx, Idx from_node, Idx bkref_idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  const re_node_set *eclosures = dfa->eclosures + from_node;
+  Idx node_idx;
+
+  /* Else, we are on the boundary: examine the nodes on the epsilon
+     closure.  */
+  for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx)
+    {
+      Idx node = eclosures->elems[node_idx];
+      switch (dfa->nodes[node].type)
+       {
+       case OP_BACK_REF:
+         if (bkref_idx != REG_MISSING)
+           {
+             struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx;
+             do
+               {
+                 Idx dst;
+                 int cpos;
+
+                 if (ent->node != node)
+                   continue;
+
+                 if (subexp_idx < BITSET_WORD_BITS
+                     && !(ent->eps_reachable_subexps_map
+                          & ((bitset_word_t) 1 << subexp_idx)))
+                   continue;
+
+                 /* Recurse trying to reach the OP_OPEN_SUBEXP and
+                    OP_CLOSE_SUBEXP cases below.  But, if the
+                    destination node is the same node as the source
+                    node, don't recurse because it would cause an
+                    infinite loop: a regex that exhibits this behavior
+                    is ()\1*\1*  */
+                 dst = dfa->edests[node].elems[0];
+                 if (dst == from_node)
+                   {
+                     if (boundaries & 1)
+                       return -1;
+                     else /* if (boundaries & 2) */
+                       return 0;
+                   }
+
+                 cpos =
+                   check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,
+                                                dst, bkref_idx);
+                 if (cpos == -1 /* && (boundaries & 1) */)
+                   return -1;
+                 if (cpos == 0 && (boundaries & 2))
+                   return 0;
+
+                 if (subexp_idx < BITSET_WORD_BITS)
+                   ent->eps_reachable_subexps_map
+                     &= ~((bitset_word_t) 1 << subexp_idx);
+               }
+             while (ent++->more);
+           }
+         break;
+
+       case OP_OPEN_SUBEXP:
+         if ((boundaries & 1) && subexp_idx == dfa->nodes[node].opr.idx)
+           return -1;
+         break;
+
+       case OP_CLOSE_SUBEXP:
+         if ((boundaries & 2) && subexp_idx == dfa->nodes[node].opr.idx)
+           return 0;
+         break;
+
+       default:
+           break;
+       }
+    }
+
+  return (boundaries & 2) ? 1 : 0;
+}
+
+static int
+internal_function
+check_dst_limits_calc_pos (const re_match_context_t *mctx, Idx limit,
+                          Idx subexp_idx, Idx from_node, Idx str_idx,
+                          Idx bkref_idx)
+{
+  struct re_backref_cache_entry *lim = mctx->bkref_ents + limit;
+  int boundaries;
+
+  /* If we are outside the range of the subexpression, return -1 or 1.  */
+  if (str_idx < lim->subexp_from)
+    return -1;
+
+  if (lim->subexp_to < str_idx)
+    return 1;
+
+  /* If we are within the subexpression, return 0.  */
+  boundaries = (str_idx == lim->subexp_from);
+  boundaries |= (str_idx == lim->subexp_to) << 1;
+  if (boundaries == 0)
+    return 0;
+
+  /* Else, examine epsilon closure.  */
+  return check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,
+                                     from_node, bkref_idx);
+}
+
+/* Check the limitations of sub expressions LIMITS, and remove the nodes
+   which are against limitations from DEST_NODES. */
+
+static reg_errcode_t
+internal_function
+check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes,
+                    const re_node_set *candidates, re_node_set *limits,
+                    struct re_backref_cache_entry *bkref_ents, Idx str_idx)
+{
+  reg_errcode_t err;
+  Idx node_idx, lim_idx;
+
+  for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
+    {
+      Idx subexp_idx;
+      struct re_backref_cache_entry *ent;
+      ent = bkref_ents + limits->elems[lim_idx];
+
+      if (str_idx <= ent->subexp_from || ent->str_idx < str_idx)
+       continue; /* This is unrelated limitation.  */
+
+      subexp_idx = dfa->nodes[ent->node].opr.idx;
+      if (ent->subexp_to == str_idx)
+       {
+         Idx ops_node = REG_MISSING;
+         Idx cls_node = REG_MISSING;
+         for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
+           {
+             Idx node = dest_nodes->elems[node_idx];
+             re_token_type_t type = dfa->nodes[node].type;
+             if (type == OP_OPEN_SUBEXP
+                 && subexp_idx == dfa->nodes[node].opr.idx)
+               ops_node = node;
+             else if (type == OP_CLOSE_SUBEXP
+                      && subexp_idx == dfa->nodes[node].opr.idx)
+               cls_node = node;
+           }
+
+         /* Check the limitation of the open subexpression.  */
+         /* Note that (ent->subexp_to = str_idx != ent->subexp_from).  */
+         if (REG_VALID_INDEX (ops_node))
+           {
+             err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes,
+                                          candidates);
+             if (BE (err != REG_NOERROR, 0))
+               return err;
+           }
+
+         /* Check the limitation of the close subexpression.  */
+         if (REG_VALID_INDEX (cls_node))
+           for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
+             {
+               Idx node = dest_nodes->elems[node_idx];
+               if (!re_node_set_contains (dfa->inveclosures + node,
+                                          cls_node)
+                   && !re_node_set_contains (dfa->eclosures + node,
+                                             cls_node))
+                 {
+                   /* It is against this limitation.
+                      Remove it form the current sifted state.  */
+                   err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
+                                                candidates);
+                   if (BE (err != REG_NOERROR, 0))
+                     return err;
+                   --node_idx;
+                 }
+             }
+       }
+      else /* (ent->subexp_to != str_idx)  */
+       {
+         for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
+           {
+             Idx node = dest_nodes->elems[node_idx];
+             re_token_type_t type = dfa->nodes[node].type;
+             if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP)
+               {
+                 if (subexp_idx != dfa->nodes[node].opr.idx)
+                   continue;
+                 /* It is against this limitation.
+                    Remove it form the current sifted state.  */
+                 err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
+                                              candidates);
+                 if (BE (err != REG_NOERROR, 0))
+                   return err;
+               }
+           }
+       }
+    }
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx,
+                  Idx str_idx, const re_node_set *candidates)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err;
+  Idx node_idx, node;
+  re_sift_context_t local_sctx;
+  Idx first_idx = search_cur_bkref_entry (mctx, str_idx);
+
+  if (first_idx == REG_MISSING)
+    return REG_NOERROR;
+
+  local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized.  */
+
+  for (node_idx = 0; node_idx < candidates->nelem; ++node_idx)
+    {
+      Idx enabled_idx;
+      re_token_type_t type;
+      struct re_backref_cache_entry *entry;
+      node = candidates->elems[node_idx];
+      type = dfa->nodes[node].type;
+      /* Avoid infinite loop for the REs like "()\1+".  */
+      if (node == sctx->last_node && str_idx == sctx->last_str_idx)
+       continue;
+      if (type != OP_BACK_REF)
+       continue;
+
+      entry = mctx->bkref_ents + first_idx;
+      enabled_idx = first_idx;
+      do
+       {
+         Idx subexp_len;
+         Idx to_idx;
+         Idx dst_node;
+         bool ok;
+         re_dfastate_t *cur_state;
+
+         if (entry->node != node)
+           continue;
+         subexp_len = entry->subexp_to - entry->subexp_from;
+         to_idx = str_idx + subexp_len;
+         dst_node = (subexp_len ? dfa->nexts[node]
+                     : dfa->edests[node].elems[0]);
+
+         if (to_idx > sctx->last_str_idx
+             || sctx->sifted_states[to_idx] == NULL
+             || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx], dst_node)
+             || check_dst_limits (mctx, &sctx->limits, node,
+                                  str_idx, dst_node, to_idx))
+           continue;
+
+         if (local_sctx.sifted_states == NULL)
+           {
+             local_sctx = *sctx;
+             err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits);
+             if (BE (err != REG_NOERROR, 0))
+               goto free_return;
+           }
+         local_sctx.last_node = node;
+         local_sctx.last_str_idx = str_idx;
+         ok = re_node_set_insert (&local_sctx.limits, enabled_idx);
+         if (BE (! ok, 0))
+           {
+             err = REG_ESPACE;
+             goto free_return;
+           }
+         cur_state = local_sctx.sifted_states[str_idx];
+         err = sift_states_backward (mctx, &local_sctx);
+         if (BE (err != REG_NOERROR, 0))
+           goto free_return;
+         if (sctx->limited_states != NULL)
+           {
+             err = merge_state_array (dfa, sctx->limited_states,
+                                      local_sctx.sifted_states,
+                                      str_idx + 1);
+             if (BE (err != REG_NOERROR, 0))
+               goto free_return;
+           }
+         local_sctx.sifted_states[str_idx] = cur_state;
+         re_node_set_remove (&local_sctx.limits, enabled_idx);
+
+         /* mctx->bkref_ents may have changed, reload the pointer.  */
+         entry = mctx->bkref_ents + enabled_idx;
+       }
+      while (enabled_idx++, entry++->more);
+    }
+  err = REG_NOERROR;
+ free_return:
+  if (local_sctx.sifted_states != NULL)
+    {
+      re_node_set_free (&local_sctx.limits);
+    }
+
+  return err;
+}
+
+
+#ifdef RE_ENABLE_I18N
+static int
+internal_function
+sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx,
+                    Idx node_idx, Idx str_idx, Idx max_str_idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  int naccepted;
+  /* Check the node can accept `multi byte'.  */
+  naccepted = check_node_accept_bytes (dfa, node_idx, &mctx->input, str_idx);
+  if (naccepted > 0 && str_idx + naccepted <= max_str_idx &&
+      !STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + naccepted],
+                           dfa->nexts[node_idx]))
+    /* The node can't accept the `multi byte', or the
+       destination was already thrown away, then the node
+       could't accept the current input `multi byte'.   */
+    naccepted = 0;
+  /* Otherwise, it is sure that the node could accept
+     `naccepted' bytes input.  */
+  return naccepted;
+}
+#endif /* RE_ENABLE_I18N */
+
+\f
+/* Functions for state transition.  */
+
+/* Return the next state to which the current state STATE will transit by
+   accepting the current input byte, and update STATE_LOG if necessary.
+   If STATE can accept a multibyte char/collating element/back reference
+   update the destination of STATE_LOG.  */
+
+static re_dfastate_t *
+internal_function __attribute_warn_unused_result__
+transit_state (reg_errcode_t *err, re_match_context_t *mctx,
+              re_dfastate_t *state)
+{
+  re_dfastate_t **trtable;
+  unsigned char ch;
+
+#ifdef RE_ENABLE_I18N
+  /* If the current state can accept multibyte.  */
+  if (BE (state->accept_mb, 0))
+    {
+      *err = transit_state_mb (mctx, state);
+      if (BE (*err != REG_NOERROR, 0))
+       return NULL;
+    }
+#endif /* RE_ENABLE_I18N */
+
+  /* Then decide the next state with the single byte.  */
+#if 0
+  if (0)
+    /* don't use transition table  */
+    return transit_state_sb (err, mctx, state);
+#endif
+
+  /* Use transition table  */
+  ch = re_string_fetch_byte (&mctx->input);
+  for (;;)
+    {
+      trtable = state->trtable;
+      if (BE (trtable != NULL, 1))
+       return trtable[ch];
+
+      trtable = state->word_trtable;
+      if (BE (trtable != NULL, 1))
+       {
+         unsigned int context;
+         context
+           = re_string_context_at (&mctx->input,
+                                   re_string_cur_idx (&mctx->input) - 1,
+                                   mctx->eflags);
+         if (IS_WORD_CONTEXT (context))
+           return trtable[ch + SBC_MAX];
+         else
+           return trtable[ch];
+       }
+
+      if (!build_trtable (mctx->dfa, state))
+       {
+         *err = REG_ESPACE;
+         return NULL;
+       }
+
+      /* Retry, we now have a transition table.  */
+    }
+}
+
+/* Update the state_log if we need */
+static re_dfastate_t *
+internal_function
+merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx,
+                     re_dfastate_t *next_state)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  Idx cur_idx = re_string_cur_idx (&mctx->input);
+
+  if (cur_idx > mctx->state_log_top)
+    {
+      mctx->state_log[cur_idx] = next_state;
+      mctx->state_log_top = cur_idx;
+    }
+  else if (mctx->state_log[cur_idx] == 0)
+    {
+      mctx->state_log[cur_idx] = next_state;
+    }
+  else
+    {
+      re_dfastate_t *pstate;
+      unsigned int context;
+      re_node_set next_nodes, *log_nodes, *table_nodes = NULL;
+      /* If (state_log[cur_idx] != 0), it implies that cur_idx is
+        the destination of a multibyte char/collating element/
+        back reference.  Then the next state is the union set of
+        these destinations and the results of the transition table.  */
+      pstate = mctx->state_log[cur_idx];
+      log_nodes = pstate->entrance_nodes;
+      if (next_state != NULL)
+       {
+         table_nodes = next_state->entrance_nodes;
+         *err = re_node_set_init_union (&next_nodes, table_nodes,
+                                            log_nodes);
+         if (BE (*err != REG_NOERROR, 0))
+           return NULL;
+       }
+      else
+       next_nodes = *log_nodes;
+      /* Note: We already add the nodes of the initial state,
+        then we don't need to add them here.  */
+
+      context = re_string_context_at (&mctx->input,
+                                     re_string_cur_idx (&mctx->input) - 1,
+                                     mctx->eflags);
+      next_state = mctx->state_log[cur_idx]
+       = re_acquire_state_context (err, dfa, &next_nodes, context);
+      /* We don't need to check errors here, since the return value of
+        this function is next_state and ERR is already set.  */
+
+      if (table_nodes != NULL)
+       re_node_set_free (&next_nodes);
+    }
+
+  if (BE (dfa->nbackref, 0) && next_state != NULL)
+    {
+      /* Check OP_OPEN_SUBEXP in the current state in case that we use them
+        later.  We must check them here, since the back references in the
+        next state might use them.  */
+      *err = check_subexp_matching_top (mctx, &next_state->nodes,
+                                       cur_idx);
+      if (BE (*err != REG_NOERROR, 0))
+       return NULL;
+
+      /* If the next state has back references.  */
+      if (next_state->has_backref)
+       {
+         *err = transit_state_bkref (mctx, &next_state->nodes);
+         if (BE (*err != REG_NOERROR, 0))
+           return NULL;
+         next_state = mctx->state_log[cur_idx];
+       }
+    }
+
+  return next_state;
+}
+
+/* Skip bytes in the input that correspond to part of a
+   multi-byte match, then look in the log for a state
+   from which to restart matching.  */
+static re_dfastate_t *
+internal_function
+find_recover_state (reg_errcode_t *err, re_match_context_t *mctx)
+{
+  re_dfastate_t *cur_state;
+  do
+    {
+      Idx max = mctx->state_log_top;
+      Idx cur_str_idx = re_string_cur_idx (&mctx->input);
+
+      do
+       {
+         if (++cur_str_idx > max)
+           return NULL;
+         re_string_skip_bytes (&mctx->input, 1);
+       }
+      while (mctx->state_log[cur_str_idx] == NULL);
+
+      cur_state = merge_state_with_log (err, mctx, NULL);
+    }
+  while (*err == REG_NOERROR && cur_state == NULL);
+  return cur_state;
+}
+
+/* Helper functions for transit_state.  */
+
+/* From the node set CUR_NODES, pick up the nodes whose types are
+   OP_OPEN_SUBEXP and which have corresponding back references in the regular
+   expression. And register them to use them later for evaluating the
+   correspoding back references.  */
+
+static reg_errcode_t
+internal_function
+check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes,
+                          Idx str_idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  Idx node_idx;
+  reg_errcode_t err;
+
+  /* TODO: This isn't efficient.
+          Because there might be more than one nodes whose types are
+          OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
+          nodes.
+          E.g. RE: (a){2}  */
+  for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx)
+    {
+      Idx node = cur_nodes->elems[node_idx];
+      if (dfa->nodes[node].type == OP_OPEN_SUBEXP
+         && dfa->nodes[node].opr.idx < BITSET_WORD_BITS
+         && (dfa->used_bkref_map
+             & ((bitset_word_t) 1 << dfa->nodes[node].opr.idx)))
+       {
+         err = match_ctx_add_subtop (mctx, node, str_idx);
+         if (BE (err != REG_NOERROR, 0))
+           return err;
+       }
+    }
+  return REG_NOERROR;
+}
+
+#if 0
+/* Return the next state to which the current state STATE will transit by
+   accepting the current input byte.  */
+
+static re_dfastate_t *
+transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx,
+                 re_dfastate_t *state)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  re_node_set next_nodes;
+  re_dfastate_t *next_state;
+  Idx node_cnt, cur_str_idx = re_string_cur_idx (&mctx->input);
+  unsigned int context;
+
+  *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1);
+  if (BE (*err != REG_NOERROR, 0))
+    return NULL;
+  for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt)
+    {
+      Idx cur_node = state->nodes.elems[node_cnt];
+      if (check_node_accept (mctx, dfa->nodes + cur_node, cur_str_idx))
+       {
+         *err = re_node_set_merge (&next_nodes,
+                                   dfa->eclosures + dfa->nexts[cur_node]);
+         if (BE (*err != REG_NOERROR, 0))
+           {
+             re_node_set_free (&next_nodes);
+             return NULL;
+           }
+       }
+    }
+  context = re_string_context_at (&mctx->input, cur_str_idx, mctx->eflags);
+  next_state = re_acquire_state_context (err, dfa, &next_nodes, context);
+  /* We don't need to check errors here, since the return value of
+     this function is next_state and ERR is already set.  */
+
+  re_node_set_free (&next_nodes);
+  re_string_skip_bytes (&mctx->input, 1);
+  return next_state;
+}
+#endif
+
+#ifdef RE_ENABLE_I18N
+static reg_errcode_t
+internal_function
+transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err;
+  Idx i;
+
+  for (i = 0; i < pstate->nodes.nelem; ++i)
+    {
+      re_node_set dest_nodes, *new_nodes;
+      Idx cur_node_idx = pstate->nodes.elems[i];
+      int naccepted;
+      Idx dest_idx;
+      unsigned int context;
+      re_dfastate_t *dest_state;
+
+      if (!dfa->nodes[cur_node_idx].accept_mb)
+       continue;
+
+      if (dfa->nodes[cur_node_idx].constraint)
+       {
+         context = re_string_context_at (&mctx->input,
+                                         re_string_cur_idx (&mctx->input),
+                                         mctx->eflags);
+         if (NOT_SATISFY_NEXT_CONSTRAINT (dfa->nodes[cur_node_idx].constraint,
+                                          context))
+           continue;
+       }
+
+      /* How many bytes the node can accept?  */
+      naccepted = check_node_accept_bytes (dfa, cur_node_idx, &mctx->input,
+                                          re_string_cur_idx (&mctx->input));
+      if (naccepted == 0)
+       continue;
+
+      /* The node can accepts `naccepted' bytes.  */
+      dest_idx = re_string_cur_idx (&mctx->input) + naccepted;
+      mctx->max_mb_elem_len = ((mctx->max_mb_elem_len < naccepted) ? naccepted
+                              : mctx->max_mb_elem_len);
+      err = clean_state_log_if_needed (mctx, dest_idx);
+      if (BE (err != REG_NOERROR, 0))
+       return err;
+#ifdef DEBUG
+      assert (dfa->nexts[cur_node_idx] != REG_MISSING);
+#endif
+      new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx];
+
+      dest_state = mctx->state_log[dest_idx];
+      if (dest_state == NULL)
+       dest_nodes = *new_nodes;
+      else
+       {
+         err = re_node_set_init_union (&dest_nodes,
+                                       dest_state->entrance_nodes, new_nodes);
+         if (BE (err != REG_NOERROR, 0))
+           return err;
+       }
+      context = re_string_context_at (&mctx->input, dest_idx - 1,
+                                     mctx->eflags);
+      mctx->state_log[dest_idx]
+       = re_acquire_state_context (&err, dfa, &dest_nodes, context);
+      if (dest_state != NULL)
+       re_node_set_free (&dest_nodes);
+      if (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0))
+       return err;
+    }
+  return REG_NOERROR;
+}
+#endif /* RE_ENABLE_I18N */
+
+static reg_errcode_t
+internal_function
+transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err;
+  Idx i;
+  Idx cur_str_idx = re_string_cur_idx (&mctx->input);
+
+  for (i = 0; i < nodes->nelem; ++i)
+    {
+      Idx dest_str_idx, prev_nelem, bkc_idx;
+      Idx node_idx = nodes->elems[i];
+      unsigned int context;
+      const re_token_t *node = dfa->nodes + node_idx;
+      re_node_set *new_dest_nodes;
+
+      /* Check whether `node' is a backreference or not.  */
+      if (node->type != OP_BACK_REF)
+       continue;
+
+      if (node->constraint)
+       {
+         context = re_string_context_at (&mctx->input, cur_str_idx,
+                                         mctx->eflags);
+         if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))
+           continue;
+       }
+
+      /* `node' is a backreference.
+        Check the substring which the substring matched.  */
+      bkc_idx = mctx->nbkref_ents;
+      err = get_subexp (mctx, node_idx, cur_str_idx);
+      if (BE (err != REG_NOERROR, 0))
+       goto free_return;
+
+      /* And add the epsilon closures (which is `new_dest_nodes') of
+        the backreference to appropriate state_log.  */
+#ifdef DEBUG
+      assert (dfa->nexts[node_idx] != REG_MISSING);
+#endif
+      for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx)
+       {
+         Idx subexp_len;
+         re_dfastate_t *dest_state;
+         struct re_backref_cache_entry *bkref_ent;
+         bkref_ent = mctx->bkref_ents + bkc_idx;
+         if (bkref_ent->node != node_idx || bkref_ent->str_idx != cur_str_idx)
+           continue;
+         subexp_len = bkref_ent->subexp_to - bkref_ent->subexp_from;
+         new_dest_nodes = (subexp_len == 0
+                           ? dfa->eclosures + dfa->edests[node_idx].elems[0]
+                           : dfa->eclosures + dfa->nexts[node_idx]);
+         dest_str_idx = (cur_str_idx + bkref_ent->subexp_to
+                         - bkref_ent->subexp_from);
+         context = re_string_context_at (&mctx->input, dest_str_idx - 1,
+                                         mctx->eflags);
+         dest_state = mctx->state_log[dest_str_idx];
+         prev_nelem = ((mctx->state_log[cur_str_idx] == NULL) ? 0
+                       : mctx->state_log[cur_str_idx]->nodes.nelem);
+         /* Add `new_dest_node' to state_log.  */
+         if (dest_state == NULL)
+           {
+             mctx->state_log[dest_str_idx]
+               = re_acquire_state_context (&err, dfa, new_dest_nodes,
+                                           context);
+             if (BE (mctx->state_log[dest_str_idx] == NULL
+                     && err != REG_NOERROR, 0))
+               goto free_return;
+           }
+         else
+           {
+             re_node_set dest_nodes;
+             err = re_node_set_init_union (&dest_nodes,
+                                           dest_state->entrance_nodes,
+                                           new_dest_nodes);
+             if (BE (err != REG_NOERROR, 0))
+               {
+                 re_node_set_free (&dest_nodes);
+                 goto free_return;
+               }
+             mctx->state_log[dest_str_idx]
+               = re_acquire_state_context (&err, dfa, &dest_nodes, context);
+             re_node_set_free (&dest_nodes);
+             if (BE (mctx->state_log[dest_str_idx] == NULL
+                     && err != REG_NOERROR, 0))
+               goto free_return;
+           }
+         /* We need to check recursively if the backreference can epsilon
+            transit.  */
+         if (subexp_len == 0
+             && mctx->state_log[cur_str_idx]->nodes.nelem > prev_nelem)
+           {
+             err = check_subexp_matching_top (mctx, new_dest_nodes,
+                                              cur_str_idx);
+             if (BE (err != REG_NOERROR, 0))
+               goto free_return;
+             err = transit_state_bkref (mctx, new_dest_nodes);
+             if (BE (err != REG_NOERROR, 0))
+               goto free_return;
+           }
+       }
+    }
+  err = REG_NOERROR;
+ free_return:
+  return err;
+}
+
+/* Enumerate all the candidates which the backreference BKREF_NODE can match
+   at BKREF_STR_IDX, and register them by match_ctx_add_entry().
+   Note that we might collect inappropriate candidates here.
+   However, the cost of checking them strictly here is too high, then we
+   delay these checking for prune_impossible_nodes().  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  Idx subexp_num, sub_top_idx;
+  const char *buf = (const char *) re_string_get_buffer (&mctx->input);
+  /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX.  */
+  Idx cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx);
+  if (cache_idx != REG_MISSING)
+    {
+      const struct re_backref_cache_entry *entry
+       = mctx->bkref_ents + cache_idx;
+      do
+       if (entry->node == bkref_node)
+         return REG_NOERROR; /* We already checked it.  */
+      while (entry++->more);
+    }
+
+  subexp_num = dfa->nodes[bkref_node].opr.idx;
+
+  /* For each sub expression  */
+  for (sub_top_idx = 0; sub_top_idx < mctx->nsub_tops; ++sub_top_idx)
+    {
+      reg_errcode_t err;
+      re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx];
+      re_sub_match_last_t *sub_last;
+      Idx sub_last_idx, sl_str, bkref_str_off;
+
+      if (dfa->nodes[sub_top->node].opr.idx != subexp_num)
+       continue; /* It isn't related.  */
+
+      sl_str = sub_top->str_idx;
+      bkref_str_off = bkref_str_idx;
+      /* At first, check the last node of sub expressions we already
+        evaluated.  */
+      for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx)
+       {
+         regoff_t sl_str_diff;
+         sub_last = sub_top->lasts[sub_last_idx];
+         sl_str_diff = sub_last->str_idx - sl_str;
+         /* The matched string by the sub expression match with the substring
+            at the back reference?  */
+         if (sl_str_diff > 0)
+           {
+             if (BE (bkref_str_off + sl_str_diff > mctx->input.valid_len, 0))
+               {
+                 /* Not enough chars for a successful match.  */
+                 if (bkref_str_off + sl_str_diff > mctx->input.len)
+                   break;
+
+                 err = clean_state_log_if_needed (mctx,
+                                                  bkref_str_off
+                                                  + sl_str_diff);
+                 if (BE (err != REG_NOERROR, 0))
+                   return err;
+                 buf = (const char *) re_string_get_buffer (&mctx->input);
+               }
+             if (memcmp (buf + bkref_str_off, buf + sl_str, sl_str_diff) != 0)
+               /* We don't need to search this sub expression any more.  */
+               break;
+           }
+         bkref_str_off += sl_str_diff;
+         sl_str += sl_str_diff;
+         err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,
+                               bkref_str_idx);
+
+         /* Reload buf, since the preceding call might have reallocated
+            the buffer.  */
+         buf = (const char *) re_string_get_buffer (&mctx->input);
+
+         if (err == REG_NOMATCH)
+           continue;
+         if (BE (err != REG_NOERROR, 0))
+           return err;
+       }
+
+      if (sub_last_idx < sub_top->nlasts)
+       continue;
+      if (sub_last_idx > 0)
+       ++sl_str;
+      /* Then, search for the other last nodes of the sub expression.  */
+      for (; sl_str <= bkref_str_idx; ++sl_str)
+       {
+         Idx cls_node;
+         regoff_t sl_str_off;
+         const re_node_set *nodes;
+         sl_str_off = sl_str - sub_top->str_idx;
+         /* The matched string by the sub expression match with the substring
+            at the back reference?  */
+         if (sl_str_off > 0)
+           {
+             if (BE (bkref_str_off >= mctx->input.valid_len, 0))
+               {
+                 /* If we are at the end of the input, we cannot match.  */
+                 if (bkref_str_off >= mctx->input.len)
+                   break;
+
+                 err = extend_buffers (mctx);
+                 if (BE (err != REG_NOERROR, 0))
+                   return err;
+
+                 buf = (const char *) re_string_get_buffer (&mctx->input);
+               }
+             if (buf [bkref_str_off++] != buf[sl_str - 1])
+               break; /* We don't need to search this sub expression
+                         any more.  */
+           }
+         if (mctx->state_log[sl_str] == NULL)
+           continue;
+         /* Does this state have a ')' of the sub expression?  */
+         nodes = &mctx->state_log[sl_str]->nodes;
+         cls_node = find_subexp_node (dfa, nodes, subexp_num,
+                                      OP_CLOSE_SUBEXP);
+         if (cls_node == REG_MISSING)
+           continue; /* No.  */
+         if (sub_top->path == NULL)
+           {
+             sub_top->path = calloc (sizeof (state_array_t),
+                                     sl_str - sub_top->str_idx + 1);
+             if (sub_top->path == NULL)
+               return REG_ESPACE;
+           }
+         /* Can the OP_OPEN_SUBEXP node arrive the OP_CLOSE_SUBEXP node
+            in the current context?  */
+         err = check_arrival (mctx, sub_top->path, sub_top->node,
+                              sub_top->str_idx, cls_node, sl_str,
+                              OP_CLOSE_SUBEXP);
+         if (err == REG_NOMATCH)
+             continue;
+         if (BE (err != REG_NOERROR, 0))
+             return err;
+         sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str);
+         if (BE (sub_last == NULL, 0))
+           return REG_ESPACE;
+         err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,
+                               bkref_str_idx);
+         if (err == REG_NOMATCH)
+           continue;
+       }
+    }
+  return REG_NOERROR;
+}
+
+/* Helper functions for get_subexp().  */
+
+/* Check SUB_LAST can arrive to the back reference BKREF_NODE at BKREF_STR.
+   If it can arrive, register the sub expression expressed with SUB_TOP
+   and SUB_LAST.  */
+
+static reg_errcode_t
+internal_function
+get_subexp_sub (re_match_context_t *mctx, const re_sub_match_top_t *sub_top,
+               re_sub_match_last_t *sub_last, Idx bkref_node, Idx bkref_str)
+{
+  reg_errcode_t err;
+  Idx to_idx;
+  /* Can the subexpression arrive the back reference?  */
+  err = check_arrival (mctx, &sub_last->path, sub_last->node,
+                      sub_last->str_idx, bkref_node, bkref_str,
+                      OP_OPEN_SUBEXP);
+  if (err != REG_NOERROR)
+    return err;
+  err = match_ctx_add_entry (mctx, bkref_node, bkref_str, sub_top->str_idx,
+                            sub_last->str_idx);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+  to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx;
+  return clean_state_log_if_needed (mctx, to_idx);
+}
+
+/* Find the first node which is '(' or ')' and whose index is SUBEXP_IDX.
+   Search '(' if FL_OPEN, or search ')' otherwise.
+   TODO: This function isn't efficient...
+        Because there might be more than one nodes whose types are
+        OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
+        nodes.
+        E.g. RE: (a){2}  */
+
+static Idx
+internal_function
+find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
+                 Idx subexp_idx, int type)
+{
+  Idx cls_idx;
+  for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx)
+    {
+      Idx cls_node = nodes->elems[cls_idx];
+      const re_token_t *node = dfa->nodes + cls_node;
+      if (node->type == type
+         && node->opr.idx == subexp_idx)
+       return cls_node;
+    }
+  return REG_MISSING;
+}
+
+/* Check whether the node TOP_NODE at TOP_STR can arrive to the node
+   LAST_NODE at LAST_STR.  We record the path onto PATH since it will be
+   heavily reused.
+   Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node,
+              Idx top_str, Idx last_node, Idx last_str, int type)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err = REG_NOERROR;
+  Idx subexp_num, backup_cur_idx, str_idx, null_cnt;
+  re_dfastate_t *cur_state = NULL;
+  re_node_set *cur_nodes, next_nodes;
+  re_dfastate_t **backup_state_log;
+  unsigned int context;
+
+  subexp_num = dfa->nodes[top_node].opr.idx;
+  /* Extend the buffer if we need.  */
+  if (BE (path->alloc < last_str + mctx->max_mb_elem_len + 1, 0))
+    {
+      re_dfastate_t **new_array;
+      Idx old_alloc = path->alloc;
+      Idx new_alloc = old_alloc + last_str + mctx->max_mb_elem_len + 1;
+      if (BE (new_alloc < old_alloc, 0)
+         || BE (SIZE_MAX / sizeof (re_dfastate_t *) < new_alloc, 0))
+       return REG_ESPACE;
+      new_array = re_realloc (path->array, re_dfastate_t *, new_alloc);
+      if (BE (new_array == NULL, 0))
+       return REG_ESPACE;
+      path->array = new_array;
+      path->alloc = new_alloc;
+      memset (new_array + old_alloc, '\0',
+             sizeof (re_dfastate_t *) * (path->alloc - old_alloc));
+    }
+
+  str_idx = path->next_idx ? path->next_idx : top_str;
+
+  /* Temporary modify MCTX.  */
+  backup_state_log = mctx->state_log;
+  backup_cur_idx = mctx->input.cur_idx;
+  mctx->state_log = path->array;
+  mctx->input.cur_idx = str_idx;
+
+  /* Setup initial node set.  */
+  context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags);
+  if (str_idx == top_str)
+    {
+      err = re_node_set_init_1 (&next_nodes, top_node);
+      if (BE (err != REG_NOERROR, 0))
+       return err;
+      err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);
+      if (BE (err != REG_NOERROR, 0))
+       {
+         re_node_set_free (&next_nodes);
+         return err;
+       }
+    }
+  else
+    {
+      cur_state = mctx->state_log[str_idx];
+      if (cur_state && cur_state->has_backref)
+       {
+         err = re_node_set_init_copy (&next_nodes, &cur_state->nodes);
+         if (BE (err != REG_NOERROR, 0))
+           return err;
+       }
+      else
+       re_node_set_init_empty (&next_nodes);
+    }
+  if (str_idx == top_str || (cur_state && cur_state->has_backref))
+    {
+      if (next_nodes.nelem)
+       {
+         err = expand_bkref_cache (mctx, &next_nodes, str_idx,
+                                   subexp_num, type);
+         if (BE (err != REG_NOERROR, 0))
+           {
+             re_node_set_free (&next_nodes);
+             return err;
+           }
+       }
+      cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
+      if (BE (cur_state == NULL && err != REG_NOERROR, 0))
+       {
+         re_node_set_free (&next_nodes);
+         return err;
+       }
+      mctx->state_log[str_idx] = cur_state;
+    }
+
+  for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;)
+    {
+      re_node_set_empty (&next_nodes);
+      if (mctx->state_log[str_idx + 1])
+       {
+         err = re_node_set_merge (&next_nodes,
+                                  &mctx->state_log[str_idx + 1]->nodes);
+         if (BE (err != REG_NOERROR, 0))
+           {
+             re_node_set_free (&next_nodes);
+             return err;
+           }
+       }
+      if (cur_state)
+       {
+         err = check_arrival_add_next_nodes (mctx, str_idx,
+                                             &cur_state->non_eps_nodes,
+                                             &next_nodes);
+         if (BE (err != REG_NOERROR, 0))
+           {
+             re_node_set_free (&next_nodes);
+             return err;
+           }
+       }
+      ++str_idx;
+      if (next_nodes.nelem)
+       {
+         err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);
+         if (BE (err != REG_NOERROR, 0))
+           {
+             re_node_set_free (&next_nodes);
+             return err;
+           }
+         err = expand_bkref_cache (mctx, &next_nodes, str_idx,
+                                   subexp_num, type);
+         if (BE (err != REG_NOERROR, 0))
+           {
+             re_node_set_free (&next_nodes);
+             return err;
+           }
+       }
+      context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags);
+      cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
+      if (BE (cur_state == NULL && err != REG_NOERROR, 0))
+       {
+         re_node_set_free (&next_nodes);
+         return err;
+       }
+      mctx->state_log[str_idx] = cur_state;
+      null_cnt = cur_state == NULL ? null_cnt + 1 : 0;
+    }
+  re_node_set_free (&next_nodes);
+  cur_nodes = (mctx->state_log[last_str] == NULL ? NULL
+              : &mctx->state_log[last_str]->nodes);
+  path->next_idx = str_idx;
+
+  /* Fix MCTX.  */
+  mctx->state_log = backup_state_log;
+  mctx->input.cur_idx = backup_cur_idx;
+
+  /* Then check the current node set has the node LAST_NODE.  */
+  if (cur_nodes != NULL && re_node_set_contains (cur_nodes, last_node))
+    return REG_NOERROR;
+
+  return REG_NOMATCH;
+}
+
+/* Helper functions for check_arrival.  */
+
+/* Calculate the destination nodes of CUR_NODES at STR_IDX, and append them
+   to NEXT_NODES.
+   TODO: This function is similar to the functions transit_state*(),
+        however this function has many additional works.
+        Can't we unify them?  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx,
+                             re_node_set *cur_nodes, re_node_set *next_nodes)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  bool ok;
+  Idx cur_idx;
+#ifdef RE_ENABLE_I18N
+  reg_errcode_t err = REG_NOERROR;
+#endif
+  re_node_set union_set;
+  re_node_set_init_empty (&union_set);
+  for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx)
+    {
+      int naccepted = 0;
+      Idx cur_node = cur_nodes->elems[cur_idx];
+#ifdef DEBUG
+      re_token_type_t type = dfa->nodes[cur_node].type;
+      assert (!IS_EPSILON_NODE (type));
+#endif
+#ifdef RE_ENABLE_I18N
+      /* If the node may accept `multi byte'.  */
+      if (dfa->nodes[cur_node].accept_mb)
+       {
+         naccepted = check_node_accept_bytes (dfa, cur_node, &mctx->input,
+                                              str_idx);
+         if (naccepted > 1)
+           {
+             re_dfastate_t *dest_state;
+             Idx next_node = dfa->nexts[cur_node];
+             Idx next_idx = str_idx + naccepted;
+             dest_state = mctx->state_log[next_idx];
+             re_node_set_empty (&union_set);
+             if (dest_state)
+               {
+                 err = re_node_set_merge (&union_set, &dest_state->nodes);
+                 if (BE (err != REG_NOERROR, 0))
+                   {
+                     re_node_set_free (&union_set);
+                     return err;
+                   }
+               }
+             ok = re_node_set_insert (&union_set, next_node);
+             if (BE (! ok, 0))
+               {
+                 re_node_set_free (&union_set);
+                 return REG_ESPACE;
+               }
+             mctx->state_log[next_idx] = re_acquire_state (&err, dfa,
+                                                           &union_set);
+             if (BE (mctx->state_log[next_idx] == NULL
+                     && err != REG_NOERROR, 0))
+               {
+                 re_node_set_free (&union_set);
+                 return err;
+               }
+           }
+       }
+#endif /* RE_ENABLE_I18N */
+      if (naccepted
+         || check_node_accept (mctx, dfa->nodes + cur_node, str_idx))
+       {
+         ok = re_node_set_insert (next_nodes, dfa->nexts[cur_node]);
+         if (BE (! ok, 0))
+           {
+             re_node_set_free (&union_set);
+             return REG_ESPACE;
+           }
+       }
+    }
+  re_node_set_free (&union_set);
+  return REG_NOERROR;
+}
+
+/* For all the nodes in CUR_NODES, add the epsilon closures of them to
+   CUR_NODES, however exclude the nodes which are:
+    - inside the sub expression whose number is EX_SUBEXP, if FL_OPEN.
+    - out of the sub expression whose number is EX_SUBEXP, if !FL_OPEN.
+*/
+
+static reg_errcode_t
+internal_function
+check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes,
+                         Idx ex_subexp, int type)
+{
+  reg_errcode_t err;
+  Idx idx, outside_node;
+  re_node_set new_nodes;
+#ifdef DEBUG
+  assert (cur_nodes->nelem);
+#endif
+  err = re_node_set_alloc (&new_nodes, cur_nodes->nelem);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+  /* Create a new node set NEW_NODES with the nodes which are epsilon
+     closures of the node in CUR_NODES.  */
+
+  for (idx = 0; idx < cur_nodes->nelem; ++idx)
+    {
+      Idx cur_node = cur_nodes->elems[idx];
+      const re_node_set *eclosure = dfa->eclosures + cur_node;
+      outside_node = find_subexp_node (dfa, eclosure, ex_subexp, type);
+      if (outside_node == REG_MISSING)
+       {
+         /* There are no problematic nodes, just merge them.  */
+         err = re_node_set_merge (&new_nodes, eclosure);
+         if (BE (err != REG_NOERROR, 0))
+           {
+             re_node_set_free (&new_nodes);
+             return err;
+           }
+       }
+      else
+       {
+         /* There are problematic nodes, re-calculate incrementally.  */
+         err = check_arrival_expand_ecl_sub (dfa, &new_nodes, cur_node,
+                                             ex_subexp, type);
+         if (BE (err != REG_NOERROR, 0))
+           {
+             re_node_set_free (&new_nodes);
+             return err;
+           }
+       }
+    }
+  re_node_set_free (cur_nodes);
+  *cur_nodes = new_nodes;
+  return REG_NOERROR;
+}
+
+/* Helper function for check_arrival_expand_ecl.
+   Check incrementally the epsilon closure of TARGET, and if it isn't
+   problematic append it to DST_NODES.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes,
+                             Idx target, Idx ex_subexp, int type)
+{
+  Idx cur_node;
+  for (cur_node = target; !re_node_set_contains (dst_nodes, cur_node);)
+    {
+      bool ok;
+
+      if (dfa->nodes[cur_node].type == type
+         && dfa->nodes[cur_node].opr.idx == ex_subexp)
+       {
+         if (type == OP_CLOSE_SUBEXP)
+           {
+             ok = re_node_set_insert (dst_nodes, cur_node);
+             if (BE (! ok, 0))
+               return REG_ESPACE;
+           }
+         break;
+       }
+      ok = re_node_set_insert (dst_nodes, cur_node);
+      if (BE (! ok, 0))
+       return REG_ESPACE;
+      if (dfa->edests[cur_node].nelem == 0)
+       break;
+      if (dfa->edests[cur_node].nelem == 2)
+       {
+         reg_errcode_t err;
+         err = check_arrival_expand_ecl_sub (dfa, dst_nodes,
+                                             dfa->edests[cur_node].elems[1],
+                                             ex_subexp, type);
+         if (BE (err != REG_NOERROR, 0))
+           return err;
+       }
+      cur_node = dfa->edests[cur_node].elems[0];
+    }
+  return REG_NOERROR;
+}
+
+
+/* For all the back references in the current state, calculate the
+   destination of the back references by the appropriate entry
+   in MCTX->BKREF_ENTS.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes,
+                   Idx cur_str, Idx subexp_num, int type)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err;
+  Idx cache_idx_start = search_cur_bkref_entry (mctx, cur_str);
+  struct re_backref_cache_entry *ent;
+
+  if (cache_idx_start == REG_MISSING)
+    return REG_NOERROR;
+
+ restart:
+  ent = mctx->bkref_ents + cache_idx_start;
+  do
+    {
+      Idx to_idx, next_node;
+
+      /* Is this entry ENT is appropriate?  */
+      if (!re_node_set_contains (cur_nodes, ent->node))
+       continue; /* No.  */
+
+      to_idx = cur_str + ent->subexp_to - ent->subexp_from;
+      /* Calculate the destination of the back reference, and append it
+        to MCTX->STATE_LOG.  */
+      if (to_idx == cur_str)
+       {
+         /* The backreference did epsilon transit, we must re-check all the
+            node in the current state.  */
+         re_node_set new_dests;
+         reg_errcode_t err2, err3;
+         next_node = dfa->edests[ent->node].elems[0];
+         if (re_node_set_contains (cur_nodes, next_node))
+           continue;
+         err = re_node_set_init_1 (&new_dests, next_node);
+         err2 = check_arrival_expand_ecl (dfa, &new_dests, subexp_num, type);
+         err3 = re_node_set_merge (cur_nodes, &new_dests);
+         re_node_set_free (&new_dests);
+         if (BE (err != REG_NOERROR || err2 != REG_NOERROR
+                 || err3 != REG_NOERROR, 0))
+           {
+             err = (err != REG_NOERROR ? err
+                    : (err2 != REG_NOERROR ? err2 : err3));
+             return err;
+           }
+         /* TODO: It is still inefficient...  */
+         goto restart;
+       }
+      else
+       {
+         re_node_set union_set;
+         next_node = dfa->nexts[ent->node];
+         if (mctx->state_log[to_idx])
+           {
+             bool ok;
+             if (re_node_set_contains (&mctx->state_log[to_idx]->nodes,
+                                       next_node))
+               continue;
+             err = re_node_set_init_copy (&union_set,
+                                          &mctx->state_log[to_idx]->nodes);
+             ok = re_node_set_insert (&union_set, next_node);
+             if (BE (err != REG_NOERROR || ! ok, 0))
+               {
+                 re_node_set_free (&union_set);
+                 err = err != REG_NOERROR ? err : REG_ESPACE;
+                 return err;
+               }
+           }
+         else
+           {
+             err = re_node_set_init_1 (&union_set, next_node);
+             if (BE (err != REG_NOERROR, 0))
+               return err;
+           }
+         mctx->state_log[to_idx] = re_acquire_state (&err, dfa, &union_set);
+         re_node_set_free (&union_set);
+         if (BE (mctx->state_log[to_idx] == NULL
+                 && err != REG_NOERROR, 0))
+           return err;
+       }
+    }
+  while (ent++->more);
+  return REG_NOERROR;
+}
+
+/* Build transition table for the state.
+   Return true if successful.  */
+
+static bool
+internal_function
+build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
+{
+  reg_errcode_t err;
+  Idx i, j;
+  int ch;
+  bool need_word_trtable = false;
+  bitset_word_t elem, mask;
+  bool dests_node_malloced = false;
+  bool dest_states_malloced = false;
+  Idx ndests; /* Number of the destination states from `state'.  */
+  re_dfastate_t **trtable;
+  re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl;
+  re_node_set follows, *dests_node;
+  bitset_t *dests_ch;
+  bitset_t acceptable;
+
+  struct dests_alloc
+  {
+    re_node_set dests_node[SBC_MAX];
+    bitset_t dests_ch[SBC_MAX];
+  } *dests_alloc;
+
+  /* We build DFA states which corresponds to the destination nodes
+     from `state'.  `dests_node[i]' represents the nodes which i-th
+     destination state contains, and `dests_ch[i]' represents the
+     characters which i-th destination state accepts.  */
+  if (__libc_use_alloca (sizeof (struct dests_alloc)))
+    dests_alloc = (struct dests_alloc *) alloca (sizeof (struct dests_alloc));
+  else
+    {
+      dests_alloc = re_malloc (struct dests_alloc, 1);
+      if (BE (dests_alloc == NULL, 0))
+       return false;
+      dests_node_malloced = true;
+    }
+  dests_node = dests_alloc->dests_node;
+  dests_ch = dests_alloc->dests_ch;
+
+  /* Initialize transiton table.  */
+  state->word_trtable = state->trtable = NULL;
+
+  /* At first, group all nodes belonging to `state' into several
+     destinations.  */
+  ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch);
+  if (BE (! REG_VALID_NONZERO_INDEX (ndests), 0))
+    {
+      if (dests_node_malloced)
+       free (dests_alloc);
+      if (ndests == 0)
+       {
+         state->trtable = (re_dfastate_t **)
+           calloc (sizeof (re_dfastate_t *), SBC_MAX);
+         return true;
+       }
+      return false;
+    }
+
+  err = re_node_set_alloc (&follows, ndests + 1);
+  if (BE (err != REG_NOERROR, 0))
+    goto out_free;
+
+  /* Avoid arithmetic overflow in size calculation.  */
+  if (BE ((((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX)
+           / (3 * sizeof (re_dfastate_t *)))
+          < ndests),
+         0))
+    goto out_free;
+
+  if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX
+                        + ndests * 3 * sizeof (re_dfastate_t *)))
+    dest_states = (re_dfastate_t **)
+      alloca (ndests * 3 * sizeof (re_dfastate_t *));
+  else
+    {
+      dest_states = (re_dfastate_t **)
+       malloc (ndests * 3 * sizeof (re_dfastate_t *));
+      if (BE (dest_states == NULL, 0))
+       {
+out_free:
+         if (dest_states_malloced)
+           free (dest_states);
+         re_node_set_free (&follows);
+         for (i = 0; i < ndests; ++i)
+           re_node_set_free (dests_node + i);
+         if (dests_node_malloced)
+           free (dests_alloc);
+         return false;
+       }
+      dest_states_malloced = true;
+    }
+  dest_states_word = dest_states + ndests;
+  dest_states_nl = dest_states_word + ndests;
+  bitset_empty (acceptable);
+
+  /* Then build the states for all destinations.  */
+  for (i = 0; i < ndests; ++i)
+    {
+      Idx next_node;
+      re_node_set_empty (&follows);
+      /* Merge the follows of this destination states.  */
+      for (j = 0; j < dests_node[i].nelem; ++j)
+       {
+         next_node = dfa->nexts[dests_node[i].elems[j]];
+         if (next_node != REG_MISSING)
+           {
+             err = re_node_set_merge (&follows, dfa->eclosures + next_node);
+             if (BE (err != REG_NOERROR, 0))
+               goto out_free;
+           }
+       }
+      dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0);
+      if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0))
+       goto out_free;
+      /* If the new state has context constraint,
+        build appropriate states for these contexts.  */
+      if (dest_states[i]->has_constraint)
+       {
+         dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows,
+                                                         CONTEXT_WORD);
+         if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
+           goto out_free;
+
+         if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)
+           need_word_trtable = true;
+
+         dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
+                                                       CONTEXT_NEWLINE);
+         if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0))
+           goto out_free;
+       }
+      else
+       {
+         dest_states_word[i] = dest_states[i];
+         dest_states_nl[i] = dest_states[i];
+       }
+      bitset_merge (acceptable, dests_ch[i]);
+    }
+
+  if (!BE (need_word_trtable, 0))
+    {
+      /* We don't care about whether the following character is a word
+        character, or we are in a single-byte character set so we can
+        discern by looking at the character code: allocate a
+        256-entry transition table.  */
+      trtable = state->trtable =
+       (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);
+      if (BE (trtable == NULL, 0))
+       goto out_free;
+
+      /* For all characters ch...:  */
+      for (i = 0; i < BITSET_WORDS; ++i)
+       for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;
+            elem;
+            mask <<= 1, elem >>= 1, ++ch)
+         if (BE (elem & 1, 0))
+           {
+             /* There must be exactly one destination which accepts
+                character ch.  See group_nodes_into_DFAstates.  */
+             for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)
+               ;
+
+             /* j-th destination accepts the word character ch.  */
+             if (dfa->word_char[i] & mask)
+               trtable[ch] = dest_states_word[j];
+             else
+               trtable[ch] = dest_states[j];
+           }
+    }
+  else
+    {
+      /* We care about whether the following character is a word
+        character, and we are in a multi-byte character set: discern
+        by looking at the character code: build two 256-entry
+        transition tables, one starting at trtable[0] and one
+        starting at trtable[SBC_MAX].  */
+      trtable = state->word_trtable =
+       (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX);
+      if (BE (trtable == NULL, 0))
+       goto out_free;
+
+      /* For all characters ch...:  */
+      for (i = 0; i < BITSET_WORDS; ++i)
+       for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;
+            elem;
+            mask <<= 1, elem >>= 1, ++ch)
+         if (BE (elem & 1, 0))
+           {
+             /* There must be exactly one destination which accepts
+                character ch.  See group_nodes_into_DFAstates.  */
+             for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)
+               ;
+
+             /* j-th destination accepts the word character ch.  */
+             trtable[ch] = dest_states[j];
+             trtable[ch + SBC_MAX] = dest_states_word[j];
+           }
+    }
+
+  /* new line */
+  if (bitset_contain (acceptable, NEWLINE_CHAR))
+    {
+      /* The current state accepts newline character.  */
+      for (j = 0; j < ndests; ++j)
+       if (bitset_contain (dests_ch[j], NEWLINE_CHAR))
+         {
+           /* k-th destination accepts newline character.  */
+           trtable[NEWLINE_CHAR] = dest_states_nl[j];
+           if (need_word_trtable)
+             trtable[NEWLINE_CHAR + SBC_MAX] = dest_states_nl[j];
+           /* There must be only one destination which accepts
+              newline.  See group_nodes_into_DFAstates.  */
+           break;
+         }
+    }
+
+  if (dest_states_malloced)
+    free (dest_states);
+
+  re_node_set_free (&follows);
+  for (i = 0; i < ndests; ++i)
+    re_node_set_free (dests_node + i);
+
+  if (dests_node_malloced)
+    free (dests_alloc);
+
+  return true;
+}
+
+/* Group all nodes belonging to STATE into several destinations.
+   Then for all destinations, set the nodes belonging to the destination
+   to DESTS_NODE[i] and set the characters accepted by the destination
+   to DEST_CH[i].  This function return the number of destinations.  */
+
+static Idx
+internal_function
+group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
+                           re_node_set *dests_node, bitset_t *dests_ch)
+{
+  reg_errcode_t err;
+  bool ok;
+  Idx i, j, k;
+  Idx ndests; /* Number of the destinations from `state'.  */
+  bitset_t accepts; /* Characters a node can accept.  */
+  const re_node_set *cur_nodes = &state->nodes;
+  bitset_empty (accepts);
+  ndests = 0;
+
+  /* For all the nodes belonging to `state',  */
+  for (i = 0; i < cur_nodes->nelem; ++i)
+    {
+      re_token_t *node = &dfa->nodes[cur_nodes->elems[i]];
+      re_token_type_t type = node->type;
+      unsigned int constraint = node->constraint;
+
+      /* Enumerate all single byte character this node can accept.  */
+      if (type == CHARACTER)
+       bitset_set (accepts, node->opr.c);
+      else if (type == SIMPLE_BRACKET)
+       {
+         bitset_merge (accepts, node->opr.sbcset);
+       }
+      else if (type == OP_PERIOD)
+       {
+#ifdef RE_ENABLE_I18N
+         if (dfa->mb_cur_max > 1)
+           bitset_merge (accepts, dfa->sb_char);
+         else
+#endif
+           bitset_set_all (accepts);
+         if (!(dfa->syntax & RE_DOT_NEWLINE))
+           bitset_clear (accepts, '\n');
+         if (dfa->syntax & RE_DOT_NOT_NULL)
+           bitset_clear (accepts, '\0');
+       }
+#ifdef RE_ENABLE_I18N
+      else if (type == OP_UTF8_PERIOD)
+       {
+         if (ASCII_CHARS % BITSET_WORD_BITS == 0)
+           memset (accepts, -1, ASCII_CHARS / CHAR_BIT);
+         else
+           bitset_merge (accepts, utf8_sb_map);
+         if (!(dfa->syntax & RE_DOT_NEWLINE))
+           bitset_clear (accepts, '\n');
+         if (dfa->syntax & RE_DOT_NOT_NULL)
+           bitset_clear (accepts, '\0');
+       }
+#endif
+      else
+       continue;
+
+      /* Check the `accepts' and sift the characters which are not
+        match it the context.  */
+      if (constraint)
+       {
+         if (constraint & NEXT_NEWLINE_CONSTRAINT)
+           {
+             bool accepts_newline = bitset_contain (accepts, NEWLINE_CHAR);
+             bitset_empty (accepts);
+             if (accepts_newline)
+               bitset_set (accepts, NEWLINE_CHAR);
+             else
+               continue;
+           }
+         if (constraint & NEXT_ENDBUF_CONSTRAINT)
+           {
+             bitset_empty (accepts);
+             continue;
+           }
+
+         if (constraint & NEXT_WORD_CONSTRAINT)
+           {
+             bitset_word_t any_set = 0;
+             if (type == CHARACTER && !node->word_char)
+               {
+                 bitset_empty (accepts);
+                 continue;
+               }
+#ifdef RE_ENABLE_I18N
+             if (dfa->mb_cur_max > 1)
+               for (j = 0; j < BITSET_WORDS; ++j)
+                 any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j]));
+             else
+#endif
+               for (j = 0; j < BITSET_WORDS; ++j)
+                 any_set |= (accepts[j] &= dfa->word_char[j]);
+             if (!any_set)
+               continue;
+           }
+         if (constraint & NEXT_NOTWORD_CONSTRAINT)
+           {
+             bitset_word_t any_set = 0;
+             if (type == CHARACTER && node->word_char)
+               {
+                 bitset_empty (accepts);
+                 continue;
+               }
+#ifdef RE_ENABLE_I18N
+             if (dfa->mb_cur_max > 1)
+               for (j = 0; j < BITSET_WORDS; ++j)
+                 any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j]));
+             else
+#endif
+               for (j = 0; j < BITSET_WORDS; ++j)
+                 any_set |= (accepts[j] &= ~dfa->word_char[j]);
+             if (!any_set)
+               continue;
+           }
+       }
+
+      /* Then divide `accepts' into DFA states, or create a new
+        state.  Above, we make sure that accepts is not empty.  */
+      for (j = 0; j < ndests; ++j)
+       {
+         bitset_t intersec; /* Intersection sets, see below.  */
+         bitset_t remains;
+         /* Flags, see below.  */
+         bitset_word_t has_intersec, not_subset, not_consumed;
+
+         /* Optimization, skip if this state doesn't accept the character.  */
+         if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c))
+           continue;
+
+         /* Enumerate the intersection set of this state and `accepts'.  */
+         has_intersec = 0;
+         for (k = 0; k < BITSET_WORDS; ++k)
+           has_intersec |= intersec[k] = accepts[k] & dests_ch[j][k];
+         /* And skip if the intersection set is empty.  */
+         if (!has_intersec)
+           continue;
+
+         /* Then check if this state is a subset of `accepts'.  */
+         not_subset = not_consumed = 0;
+         for (k = 0; k < BITSET_WORDS; ++k)
+           {
+             not_subset |= remains[k] = ~accepts[k] & dests_ch[j][k];
+             not_consumed |= accepts[k] = accepts[k] & ~dests_ch[j][k];
+           }
+
+         /* If this state isn't a subset of `accepts', create a
+            new group state, which has the `remains'. */
+         if (not_subset)
+           {
+             bitset_copy (dests_ch[ndests], remains);
+             bitset_copy (dests_ch[j], intersec);
+             err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]);
+             if (BE (err != REG_NOERROR, 0))
+               goto error_return;
+             ++ndests;
+           }
+
+         /* Put the position in the current group. */
+         ok = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);
+         if (BE (! ok, 0))
+           goto error_return;
+
+         /* If all characters are consumed, go to next node. */
+         if (!not_consumed)
+           break;
+       }
+      /* Some characters remain, create a new group. */
+      if (j == ndests)
+       {
+         bitset_copy (dests_ch[ndests], accepts);
+         err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]);
+         if (BE (err != REG_NOERROR, 0))
+           goto error_return;
+         ++ndests;
+         bitset_empty (accepts);
+       }
+    }
+  return ndests;
+ error_return:
+  for (j = 0; j < ndests; ++j)
+    re_node_set_free (dests_node + j);
+  return REG_MISSING;
+}
+
+#ifdef RE_ENABLE_I18N
+/* Check how many bytes the node `dfa->nodes[node_idx]' accepts.
+   Return the number of the bytes the node accepts.
+   STR_IDX is the current index of the input string.
+
+   This function handles the nodes which can accept one character, or
+   one collating element like '.', '[a-z]', opposite to the other nodes
+   can only accept one byte.  */
+
+static int
+internal_function
+check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
+                        const re_string_t *input, Idx str_idx)
+{
+  const re_token_t *node = dfa->nodes + node_idx;
+  int char_len, elem_len;
+  Idx i;
+
+  if (BE (node->type == OP_UTF8_PERIOD, 0))
+    {
+      unsigned char c = re_string_byte_at (input, str_idx), d;
+      if (BE (c < 0xc2, 1))
+       return 0;
+
+      if (str_idx + 2 > input->len)
+       return 0;
+
+      d = re_string_byte_at (input, str_idx + 1);
+      if (c < 0xe0)
+       return (d < 0x80 || d > 0xbf) ? 0 : 2;
+      else if (c < 0xf0)
+       {
+         char_len = 3;
+         if (c == 0xe0 && d < 0xa0)
+           return 0;
+       }
+      else if (c < 0xf8)
+       {
+         char_len = 4;
+         if (c == 0xf0 && d < 0x90)
+           return 0;
+       }
+      else if (c < 0xfc)
+       {
+         char_len = 5;
+         if (c == 0xf8 && d < 0x88)
+           return 0;
+       }
+      else if (c < 0xfe)
+       {
+         char_len = 6;
+         if (c == 0xfc && d < 0x84)
+           return 0;
+       }
+      else
+       return 0;
+
+      if (str_idx + char_len > input->len)
+       return 0;
+
+      for (i = 1; i < char_len; ++i)
+       {
+         d = re_string_byte_at (input, str_idx + i);
+         if (d < 0x80 || d > 0xbf)
+           return 0;
+       }
+      return char_len;
+    }
+
+  char_len = re_string_char_size_at (input, str_idx);
+  if (node->type == OP_PERIOD)
+    {
+      if (char_len <= 1)
+       return 0;
+      /* FIXME: I don't think this if is needed, as both '\n'
+        and '\0' are char_len == 1.  */
+      /* '.' accepts any one character except the following two cases.  */
+      if ((!(dfa->syntax & RE_DOT_NEWLINE) &&
+          re_string_byte_at (input, str_idx) == '\n') ||
+         ((dfa->syntax & RE_DOT_NOT_NULL) &&
+          re_string_byte_at (input, str_idx) == '\0'))
+       return 0;
+      return char_len;
+    }
+
+  elem_len = re_string_elem_size_at (input, str_idx);
+  if ((elem_len <= 1 && char_len <= 1) || char_len == 0)
+    return 0;
+
+  if (node->type == COMPLEX_BRACKET)
+    {
+      const re_charset_t *cset = node->opr.mbcset;
+# ifdef _LIBC
+      const unsigned char *pin
+       = ((const unsigned char *) re_string_get_buffer (input) + str_idx);
+      Idx j;
+      uint32_t nrules;
+# endif /* _LIBC */
+      int match_len = 0;
+      wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)
+                   ? re_string_wchar_at (input, str_idx) : 0);
+
+      /* match with multibyte character?  */
+      for (i = 0; i < cset->nmbchars; ++i)
+       if (wc == cset->mbchars[i])
+         {
+           match_len = char_len;
+           goto check_node_accept_bytes_match;
+         }
+      /* match with character_class?  */
+      for (i = 0; i < cset->nchar_classes; ++i)
+       {
+         wctype_t wt = cset->char_classes[i];
+         if (__iswctype (wc, wt))
+           {
+             match_len = char_len;
+             goto check_node_accept_bytes_match;
+           }
+       }
+
+# ifdef _LIBC
+      nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+      if (nrules != 0)
+       {
+         unsigned int in_collseq = 0;
+         const int32_t *table, *indirect;
+         const unsigned char *weights, *extra;
+         const char *collseqwc;
+         int32_t idx;
+         /* This #include defines a local function!  */
+#  include <locale/weight.h>
+
+         /* match with collating_symbol?  */
+         if (cset->ncoll_syms)
+           extra = (const unsigned char *)
+             _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
+         for (i = 0; i < cset->ncoll_syms; ++i)
+           {
+             const unsigned char *coll_sym = extra + cset->coll_syms[i];
+             /* Compare the length of input collating element and
+                the length of current collating element.  */
+             if (*coll_sym != elem_len)
+               continue;
+             /* Compare each bytes.  */
+             for (j = 0; j < *coll_sym; j++)
+               if (pin[j] != coll_sym[1 + j])
+                 break;
+             if (j == *coll_sym)
+               {
+                 /* Match if every bytes is equal.  */
+                 match_len = j;
+                 goto check_node_accept_bytes_match;
+               }
+           }
+
+         if (cset->nranges)
+           {
+             if (elem_len <= char_len)
+               {
+                 collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);
+                 in_collseq = __collseq_table_lookup (collseqwc, wc);
+               }
+             else
+               in_collseq = find_collation_sequence_value (pin, elem_len);
+           }
+         /* match with range expression?  */
+         for (i = 0; i < cset->nranges; ++i)
+           if (cset->range_starts[i] <= in_collseq
+               && in_collseq <= cset->range_ends[i])
+             {
+               match_len = elem_len;
+               goto check_node_accept_bytes_match;
+             }
+
+         /* match with equivalence_class?  */
+         if (cset->nequiv_classes)
+           {
+             const unsigned char *cp = pin;
+             table = (const int32_t *)
+               _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+             weights = (const unsigned char *)
+               _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
+             extra = (const unsigned char *)
+               _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
+             indirect = (const int32_t *)
+               _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
+             int32_t idx = findidx (&cp);
+             if (idx > 0)
+               for (i = 0; i < cset->nequiv_classes; ++i)
+                 {
+                   int32_t equiv_class_idx = cset->equiv_classes[i];
+                   size_t weight_len = weights[idx & 0xffffff];
+                   if (weight_len == weights[equiv_class_idx & 0xffffff]
+                       && (idx >> 24) == (equiv_class_idx >> 24))
+                     {
+                       Idx cnt = 0;
+
+                       idx &= 0xffffff;
+                       equiv_class_idx &= 0xffffff;
+
+                       while (cnt <= weight_len
+                              && (weights[equiv_class_idx + 1 + cnt]
+                                  == weights[idx + 1 + cnt]))
+                         ++cnt;
+                       if (cnt > weight_len)
+                         {
+                           match_len = elem_len;
+                           goto check_node_accept_bytes_match;
+                         }
+                     }
+                 }
+           }
+       }
+      else
+# endif /* _LIBC */
+       {
+         /* match with range expression?  */
+#if __GNUC__ >= 2 && ! (__STDC_VERSION__ < 199901L && __STRICT_ANSI__)
+         wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'};
+#else
+         wchar_t cmp_buf[] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'};
+         cmp_buf[2] = wc;
+#endif
+         for (i = 0; i < cset->nranges; ++i)
+           {
+             cmp_buf[0] = cset->range_starts[i];
+             cmp_buf[4] = cset->range_ends[i];
+             if (wcscoll (cmp_buf, cmp_buf + 2) <= 0
+                 && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0)
+               {
+                 match_len = char_len;
+                 goto check_node_accept_bytes_match;
+               }
+           }
+       }
+    check_node_accept_bytes_match:
+      if (!cset->non_match)
+       return match_len;
+      else
+       {
+         if (match_len > 0)
+           return 0;
+         else
+           return (elem_len > char_len) ? elem_len : char_len;
+       }
+    }
+  return 0;
+}
+
+# ifdef _LIBC
+static unsigned int
+internal_function
+find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
+{
+  uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+  if (nrules == 0)
+    {
+      if (mbs_len == 1)
+       {
+         /* No valid character.  Match it as a single byte character.  */
+         const unsigned char *collseq = (const unsigned char *)
+           _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
+         return collseq[mbs[0]];
+       }
+      return UINT_MAX;
+    }
+  else
+    {
+      int32_t idx;
+      const unsigned char *extra = (const unsigned char *)
+       _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
+      int32_t extrasize = (const unsigned char *)
+       _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB + 1) - extra;
+
+      for (idx = 0; idx < extrasize;)
+       {
+         int mbs_cnt;
+         bool found = false;
+         int32_t elem_mbs_len;
+         /* Skip the name of collating element name.  */
+         idx = idx + extra[idx] + 1;
+         elem_mbs_len = extra[idx++];
+         if (mbs_len == elem_mbs_len)
+           {
+             for (mbs_cnt = 0; mbs_cnt < elem_mbs_len; ++mbs_cnt)
+               if (extra[idx + mbs_cnt] != mbs[mbs_cnt])
+                 break;
+             if (mbs_cnt == elem_mbs_len)
+               /* Found the entry.  */
+               found = true;
+           }
+         /* Skip the byte sequence of the collating element.  */
+         idx += elem_mbs_len;
+         /* Adjust for the alignment.  */
+         idx = (idx + 3) & ~3;
+         /* Skip the collation sequence value.  */
+         idx += sizeof (uint32_t);
+         /* Skip the wide char sequence of the collating element.  */
+         idx = idx + sizeof (uint32_t) * (extra[idx] + 1);
+         /* If we found the entry, return the sequence value.  */
+         if (found)
+           return *(uint32_t *) (extra + idx);
+         /* Skip the collation sequence value.  */
+         idx += sizeof (uint32_t);
+       }
+      return UINT_MAX;
+    }
+}
+# endif /* _LIBC */
+#endif /* RE_ENABLE_I18N */
+
+/* Check whether the node accepts the byte which is IDX-th
+   byte of the INPUT.  */
+
+static bool
+internal_function
+check_node_accept (const re_match_context_t *mctx, const re_token_t *node,
+                  Idx idx)
+{
+  unsigned char ch;
+  ch = re_string_byte_at (&mctx->input, idx);
+  switch (node->type)
+    {
+    case CHARACTER:
+      if (node->opr.c != ch)
+        return false;
+      break;
+
+    case SIMPLE_BRACKET:
+      if (!bitset_contain (node->opr.sbcset, ch))
+        return false;
+      break;
+
+#ifdef RE_ENABLE_I18N
+    case OP_UTF8_PERIOD:
+      if (ch >= ASCII_CHARS)
+        return false;
+      /* FALLTHROUGH */
+#endif
+    case OP_PERIOD:
+      if ((ch == '\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE))
+         || (ch == '\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL)))
+       return false;
+      break;
+
+    default:
+      return false;
+    }
+
+  if (node->constraint)
+    {
+      /* The node has constraints.  Check whether the current context
+        satisfies the constraints.  */
+      unsigned int context = re_string_context_at (&mctx->input, idx,
+                                                  mctx->eflags);
+      if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))
+       return false;
+    }
+
+  return true;
+}
+
+/* Extend the buffers, if the buffers have run out.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+extend_buffers (re_match_context_t *mctx)
+{
+  reg_errcode_t ret;
+  re_string_t *pstr = &mctx->input;
+
+  /* Avoid overflow.  */
+  if (BE (SIZE_MAX / 2 / sizeof (re_dfastate_t *) <= pstr->bufs_len, 0))
+    return REG_ESPACE;
+
+  /* Double the lengthes of the buffers.  */
+  ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+
+  if (mctx->state_log != NULL)
+    {
+      /* And double the length of state_log.  */
+      /* XXX We have no indication of the size of this buffer.  If this
+        allocation fail we have no indication that the state_log array
+        does not have the right size.  */
+      re_dfastate_t **new_array = re_realloc (mctx->state_log, re_dfastate_t *,
+                                             pstr->bufs_len + 1);
+      if (BE (new_array == NULL, 0))
+       return REG_ESPACE;
+      mctx->state_log = new_array;
+    }
+
+  /* Then reconstruct the buffers.  */
+  if (pstr->icase)
+    {
+#ifdef RE_ENABLE_I18N
+      if (pstr->mb_cur_max > 1)
+       {
+         ret = build_wcs_upper_buffer (pstr);
+         if (BE (ret != REG_NOERROR, 0))
+           return ret;
+       }
+      else
+#endif /* RE_ENABLE_I18N  */
+       build_upper_buffer (pstr);
+    }
+  else
+    {
+#ifdef RE_ENABLE_I18N
+      if (pstr->mb_cur_max > 1)
+       build_wcs_buffer (pstr);
+      else
+#endif /* RE_ENABLE_I18N  */
+       {
+         if (pstr->trans != NULL)
+           re_string_translate_buffer (pstr);
+       }
+    }
+  return REG_NOERROR;
+}
+
+\f
+/* Functions for matching context.  */
+
+/* Initialize MCTX.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+match_ctx_init (re_match_context_t *mctx, int eflags, Idx n)
+{
+  mctx->eflags = eflags;
+  mctx->match_last = REG_MISSING;
+  if (n > 0)
+    {
+      /* Avoid overflow.  */
+      size_t max_object_size =
+       MAX (sizeof (struct re_backref_cache_entry),
+            sizeof (re_sub_match_top_t *));
+      if (BE (SIZE_MAX / max_object_size < n, 0))
+       return REG_ESPACE;
+
+      mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n);
+      mctx->sub_tops = re_malloc (re_sub_match_top_t *, n);
+      if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0))
+       return REG_ESPACE;
+    }
+  /* Already zero-ed by the caller.
+     else
+       mctx->bkref_ents = NULL;
+     mctx->nbkref_ents = 0;
+     mctx->nsub_tops = 0;  */
+  mctx->abkref_ents = n;
+  mctx->max_mb_elem_len = 1;
+  mctx->asub_tops = n;
+  return REG_NOERROR;
+}
+
+/* Clean the entries which depend on the current input in MCTX.
+   This function must be invoked when the matcher changes the start index
+   of the input, or changes the input string.  */
+
+static void
+internal_function
+match_ctx_clean (re_match_context_t *mctx)
+{
+  Idx st_idx;
+  for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx)
+    {
+      Idx sl_idx;
+      re_sub_match_top_t *top = mctx->sub_tops[st_idx];
+      for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx)
+       {
+         re_sub_match_last_t *last = top->lasts[sl_idx];
+         re_free (last->path.array);
+         re_free (last);
+       }
+      re_free (top->lasts);
+      if (top->path)
+       {
+         re_free (top->path->array);
+         re_free (top->path);
+       }
+      free (top);
+    }
+
+  mctx->nsub_tops = 0;
+  mctx->nbkref_ents = 0;
+}
+
+/* Free all the memory associated with MCTX.  */
+
+static void
+internal_function
+match_ctx_free (re_match_context_t *mctx)
+{
+  /* First, free all the memory associated with MCTX->SUB_TOPS.  */
+  match_ctx_clean (mctx);
+  re_free (mctx->sub_tops);
+  re_free (mctx->bkref_ents);
+}
+
+/* Add a new backreference entry to MCTX.
+   Note that we assume that caller never call this function with duplicate
+   entry, and call with STR_IDX which isn't smaller than any existing entry.
+*/
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+match_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx, Idx from,
+                    Idx to)
+{
+  if (mctx->nbkref_ents >= mctx->abkref_ents)
+    {
+      struct re_backref_cache_entry* new_entry;
+      new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry,
+                             mctx->abkref_ents * 2);
+      if (BE (new_entry == NULL, 0))
+       {
+         re_free (mctx->bkref_ents);
+         return REG_ESPACE;
+       }
+      mctx->bkref_ents = new_entry;
+      memset (mctx->bkref_ents + mctx->nbkref_ents, '\0',
+             sizeof (struct re_backref_cache_entry) * mctx->abkref_ents);
+      mctx->abkref_ents *= 2;
+    }
+  if (mctx->nbkref_ents > 0
+      && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx)
+    mctx->bkref_ents[mctx->nbkref_ents - 1].more = 1;
+
+  mctx->bkref_ents[mctx->nbkref_ents].node = node;
+  mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx;
+  mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from;
+  mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to;
+
+  /* This is a cache that saves negative results of check_dst_limits_calc_pos.
+     If bit N is clear, means that this entry won't epsilon-transition to
+     an OP_OPEN_SUBEXP or OP_CLOSE_SUBEXP for the N+1-th subexpression.  If
+     it is set, check_dst_limits_calc_pos_1 will recurse and try to find one
+     such node.
+
+     A backreference does not epsilon-transition unless it is empty, so set
+     to all zeros if FROM != TO.  */
+  mctx->bkref_ents[mctx->nbkref_ents].eps_reachable_subexps_map
+    = (from == to ? -1 : 0);
+
+  mctx->bkref_ents[mctx->nbkref_ents++].more = 0;
+  if (mctx->max_mb_elem_len < to - from)
+    mctx->max_mb_elem_len = to - from;
+  return REG_NOERROR;
+}
+
+/* Return the first entry with the same str_idx, or REG_MISSING if none is
+   found.  Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX.  */
+
+static Idx
+internal_function
+search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx)
+{
+  Idx left, right, mid, last;
+  last = right = mctx->nbkref_ents;
+  for (left = 0; left < right;)
+    {
+      mid = (left + right) / 2;
+      if (mctx->bkref_ents[mid].str_idx < str_idx)
+       left = mid + 1;
+      else
+       right = mid;
+    }
+  if (left < last && mctx->bkref_ents[left].str_idx == str_idx)
+    return left;
+  else
+    return REG_MISSING;
+}
+
+/* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches
+   at STR_IDX.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx)
+{
+#ifdef DEBUG
+  assert (mctx->sub_tops != NULL);
+  assert (mctx->asub_tops > 0);
+#endif
+  if (BE (mctx->nsub_tops == mctx->asub_tops, 0))
+    {
+      Idx new_asub_tops = mctx->asub_tops * 2;
+      re_sub_match_top_t **new_array = re_realloc (mctx->sub_tops,
+                                                  re_sub_match_top_t *,
+                                                  new_asub_tops);
+      if (BE (new_array == NULL, 0))
+       return REG_ESPACE;
+      mctx->sub_tops = new_array;
+      mctx->asub_tops = new_asub_tops;
+    }
+  mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t));
+  if (BE (mctx->sub_tops[mctx->nsub_tops] == NULL, 0))
+    return REG_ESPACE;
+  mctx->sub_tops[mctx->nsub_tops]->node = node;
+  mctx->sub_tops[mctx->nsub_tops++]->str_idx = str_idx;
+  return REG_NOERROR;
+}
+
+/* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches
+   at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP.  */
+
+static re_sub_match_last_t *
+internal_function
+match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx)
+{
+  re_sub_match_last_t *new_entry;
+  if (BE (subtop->nlasts == subtop->alasts, 0))
+    {
+      Idx new_alasts = 2 * subtop->alasts + 1;
+      re_sub_match_last_t **new_array = re_realloc (subtop->lasts,
+                                                   re_sub_match_last_t *,
+                                                   new_alasts);
+      if (BE (new_array == NULL, 0))
+       return NULL;
+      subtop->lasts = new_array;
+      subtop->alasts = new_alasts;
+    }
+  new_entry = calloc (1, sizeof (re_sub_match_last_t));
+  if (BE (new_entry != NULL, 1))
+    {
+      subtop->lasts[subtop->nlasts] = new_entry;
+      new_entry->node = node;
+      new_entry->str_idx = str_idx;
+      ++subtop->nlasts;
+    }
+  return new_entry;
+}
+
+static void
+internal_function
+sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
+              re_dfastate_t **limited_sts, Idx last_node, Idx last_str_idx)
+{
+  sctx->sifted_states = sifted_sts;
+  sctx->limited_states = limited_sts;
+  sctx->last_node = last_node;
+  sctx->last_str_idx = last_str_idx;
+  re_node_set_init_empty (&sctx->limits);
+}
diff --git a/grub-core/hello/hello.c b/grub-core/hello/hello.c
new file mode 100644 (file)
index 0000000..eff07d9
--- /dev/null
@@ -0,0 +1,49 @@
+/* hello.c - test module for dynamic loading */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2007  Free Software Foundation, Inc.
+ *  Copyright (C) 2003  NIIBE Yutaka <gniibe@m17n.org>
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+grub_cmd_hello (struct grub_extcmd *cmd __attribute__ ((unused)),
+               int argc __attribute__ ((unused)),
+               char **args __attribute__ ((unused)))
+{
+  grub_printf ("Hello World\n");
+  return 0;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(hello)
+{
+  cmd = grub_register_extcmd ("hello", grub_cmd_hello, GRUB_COMMAND_FLAG_BOTH,
+                             0, N_("Say \"Hello World\"."), 0);
+}
+
+GRUB_MOD_FINI(hello)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/hook/datehook.c b/grub-core/hook/datehook.c
new file mode 100644 (file)
index 0000000..9b5b54b
--- /dev/null
@@ -0,0 +1,105 @@
+/* datehook.c - Module to install datetime hooks.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+#include <grub/datetime.h>
+
+static char *grub_datetime_names[] =
+{
+  "YEAR",
+  "MONTH",
+  "DAY",
+  "HOUR",
+  "MINUTE",
+  "SECOND",
+  "WEEKDAY",
+};
+
+static char *
+grub_read_hook_datetime (struct grub_env_var *var,
+                         const char *val __attribute__ ((unused)))
+{
+  struct grub_datetime datetime;
+  static char buf[6];
+
+  buf[0] = 0;
+  if (! grub_get_datetime (&datetime))
+    {
+      int i;
+
+      for (i = 0; i < 7; i++)
+        if (! grub_strcmp (var->name, grub_datetime_names[i]))
+          {
+            int n;
+
+            switch (i)
+              {
+              case 0:
+                n = datetime.year;
+                break;
+              case 1:
+                n = datetime.month;
+                break;
+              case 2:
+                n = datetime.day;
+                break;
+              case 3:
+                n = datetime.hour;
+                break;
+              case 4:
+                n = datetime.minute;
+                break;
+              case 5:
+                n = datetime.second;
+                break;
+              default:
+                return grub_get_weekday_name (&datetime);
+              }
+
+            grub_snprintf (buf, sizeof (buf), "%d", n);
+            break;
+          }
+    }
+
+  return buf;
+}
+
+GRUB_MOD_INIT(datehook)
+{
+  int i;
+
+  for (i = 0; i < 7; i++)
+    grub_register_variable_hook (grub_datetime_names[i],
+                                 grub_read_hook_datetime, 0);
+}
+
+GRUB_MOD_FINI(datehook)
+{
+  int i;
+
+  for (i = 0; i < 7; i++)
+    {
+      grub_register_variable_hook (grub_datetime_names[i], 0, 0);
+      grub_env_unset (grub_datetime_names[i]);
+    }
+}
diff --git a/grub-core/import_gcry.py b/grub-core/import_gcry.py
new file mode 100644 (file)
index 0000000..b9c3edc
--- /dev/null
@@ -0,0 +1,341 @@
+#*
+#*  GRUB  --  GRand Unified Bootloader
+#*  Copyright (C) 2009  Free Software Foundation, Inc.
+#*
+#*  GRUB is free software: you can redistribute it and/or modify
+#*  it under the terms of the GNU General Public License as published by
+#*  the Free Software Foundation, either version 3 of the License, or
+#*  (at your option) any later version.
+#*
+#*  GRUB is distributed in the hope that it will be useful,
+#*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#*  GNU General Public License for more details.
+#*
+#*  You should have received a copy of the GNU General Public License
+#*  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+#*
+
+import re
+import sys
+import os
+import datetime
+
+if len (sys.argv) < 3:
+    print ("Usage: %s SOURCE DESTINATION" % sys.argv[0])
+    exit (0)
+indir = sys.argv[1]
+outdir = sys.argv[2]
+
+basedir = os.path.join (outdir, "lib/libgcrypt-grub")
+try:
+    os.makedirs (basedir)
+except:
+    print ("WARNING: %s already exists" % basedir)
+cipher_dir_in = os.path.join (indir, "cipher")
+cipher_dir_out = os.path.join (basedir, "cipher")
+try:
+    os.makedirs (cipher_dir_out)
+except:
+    print ("WARNING: %s already exists" % cipher_dir_out)
+
+cipher_files = os.listdir (cipher_dir_in)
+conf = open (os.path.join (outdir, "conf", "gcry.rmk"), "w")
+conf.write ("# -*- makefile -*-\n\n")
+chlog = ""
+
+# Strictly speaking CRC32/CRC24 work on bytes so this value should be 1
+# But libgcrypt uses 64. Let's keep the value for compatibility. Since
+# noone uses CRC24/CRC32 for HMAC this is no problem
+mdblocksizes = {"_gcry_digest_spec_crc32" : 64,
+                "_gcry_digest_spec_crc32_rfc1510" : 64,
+                "_gcry_digest_spec_crc24_rfc2440" : 64,
+                "_gcry_digest_spec_md4" : 64,
+                "_gcry_digest_spec_md5" : 64,
+                "_gcry_digest_spec_rmd160" : 64,
+                "_gcry_digest_spec_sha1" : 64,
+                "_gcry_digest_spec_sha224" : 64,
+                "_gcry_digest_spec_sha256" : 64,
+                "_gcry_digest_spec_sha384" : 128,
+                "_gcry_digest_spec_sha512" : 128,
+                "_gcry_digest_spec_tiger" : 64,
+                "_gcry_digest_spec_whirlpool" : 64}
+
+cryptolist = open (os.path.join (cipher_dir_out, "crypto.lst"), "w")
+conf.write ("MAINTAINER_CLEANFILES += $(srcdir)/conf/gcry.rmk $(srcdir)/lib/libgcrypt-grub/cipher/ChangeLog $(srcdir)/lib/libgcrypt-grub/cipher/cipher.h $(srcdir)/lib/libgcrypt-grub/cipher/crypto.lst $(srcdir)/lib/libgcrypt-grub/cipher/g10lib.h $(srcdir)/lib/libgcrypt-grub/cipher/memory.h $(srcdir)/lib/libgcrypt-grub/cipher/types.h\n");
+
+# rijndael is the only cipher using aliases. So no need for mangling, just
+# hardcode it
+cryptolist.write ("RIJNDAEL: gcry_rijndael\n");
+cryptolist.write ("RIJNDAEL192: gcry_rijndael\n");
+cryptolist.write ("RIJNDAEL256: gcry_rijndael\n");
+cryptolist.write ("AES128: gcry_rijndael\n");
+cryptolist.write ("AES-128: gcry_rijndael\n");
+cryptolist.write ("AES-192: gcry_rijndael\n");
+cryptolist.write ("AES-256: gcry_rijndael\n");
+
+for cipher_file in cipher_files:
+    infile = os.path.join (cipher_dir_in, cipher_file)
+    outfile = os.path.join (cipher_dir_out, cipher_file)
+    if cipher_file == "ChangeLog":
+        continue
+    chlognew = "       * %s" % cipher_file
+    if re.match ("(Manifest|Makefile\.am|ac\.c|cipher\.c|hash-common\.c|hmac-tests\.c|md\.c|pubkey\.c)$", cipher_file):
+        chlog = "%s%s: Removed\n" % (chlog, chlognew)
+        continue
+    # Autogenerated files. Not even worth mentionning in ChangeLog
+    if re.match ("Makefile\.in$", cipher_file):
+        continue
+    nch = False
+    if re.match (".*\.[ch]$", cipher_file):
+        conf.write ("MAINTAINER_CLEANFILES += $(srcdir)/lib/libgcrypt-grub/cipher/" + cipher_file + "\n");
+        isc = re.match (".*\.c$", cipher_file)
+        f = open (infile, "r")
+        fw = open (outfile, "w")
+        fw.write ("/* This file was automatically imported with \n")
+        fw.write ("   import_gcry.py. Please don't modify it */\n");
+        ciphernames = []
+        mdnames = []
+        hold = False
+        skip = False
+        skip2 = False
+        ismd = False
+        iscryptostart = False
+        iscomma = False
+        isglue = False
+        skip_statement = False
+        if isc:
+            modname = cipher_file [0:len(cipher_file) - 2]
+            if re.match (".*-glue$", modname):
+                modname = modname.replace ("-glue", "")
+                isglue = True
+            modname = "gcry_%s" % modname
+        for line in f:
+            if skip_statement:
+                if not re.search (";", line) is None:
+                    skip_statement = False
+                continue
+            if skip:
+                if line[0] == "}":
+                    skip = False
+                continue
+            if skip2:
+                if not re.search (" *};", line) is None:
+                    skip2 = False
+                continue
+            if iscryptostart:
+                s = re.search (" *\"([A-Z0-9_a-z]*)\"", line)
+                if not s is None:
+                    sg = s.groups()[0]
+                    cryptolist.write (("%s: %s\n") % (sg, modname))
+                    iscryptostart = False
+            if ismd:
+                if not re.search (" *};", line) is None:
+                    if not mdblocksizes.has_key (mdname):
+                        print ("ERROR: Unknown digest blocksize: %s\n" % mdname)
+                        exit (1)
+                    if not iscomma:
+                        fw.write ("    ,\n")
+                    fw.write ("    .blocksize = %s\n" % mdblocksizes [mdname])
+                    ismd = False
+                iscomma = not re.search (",$", line) is None
+            # Used only for selftests.
+            m = re.match ("(static byte|static unsigned char) (weak_keys_chksum)\[[0-9]*\] =", line)
+            if not m is None:
+                skip = True
+                fname = m.groups ()[1]
+                chmsg = "(%s): Removed." % fname
+                if nch:
+                    chlognew = "%s\n   %s" % (chlognew, chmsg)
+                else:
+                    chlognew = "%s %s" % (chlognew, chmsg)
+                    nch = True
+                continue
+            if hold:
+                hold = False
+                # We're optimising for size.
+                if not re.match ("(run_selftests|selftest|_gcry_aes_c.._..c|_gcry_[a-z0-9]*_hash_buffer|tripledes_set2keys|do_tripledes_set_extra_info)", line) is None:
+                    skip = True
+                    fname = re.match ("[a-zA-Z0-9_]*", line).group ()
+                    chmsg = "(%s): Removed." % fname
+                    if nch:
+                        chlognew = "%s\n       %s" % (chlognew, chmsg)
+                    else:
+                        chlognew = "%s %s" % (chlognew, chmsg)
+                        nch = True
+                    continue
+                else:
+                    fw.write (holdline)
+            m = re.match ("#include <.*>", line)
+            if not m is None:
+                chmsg = "Removed including of %s" % \
+                m.group () [len ("#include <"):len (m.group ()) - 1]
+                if nch:
+                    chlognew = "%s\n   %s" % (chlognew, chmsg)
+                else:
+                    chlognew = "%s: %s" % (chlognew, chmsg)
+                    nch = True
+                continue
+            m = re.match ("gcry_cipher_spec_t", line)
+            if isc and not m is None:
+                assert (not iscryptostart)
+                ciphername = line [len ("gcry_cipher_spec_t"):].strip ()
+                ciphername = re.match("[a-zA-Z0-9_]*",ciphername).group ()
+                ciphernames.append (ciphername)
+                iscryptostart = True
+            m = re.match ("gcry_md_spec_t", line)
+            if isc and not m is None:
+                assert (not ismd)
+                assert (not iscryptostart)
+                mdname = line [len ("gcry_md_spec_t"):].strip ()
+                mdname = re.match("[a-zA-Z0-9_]*",mdname).group ()
+                mdnames.append (mdname)
+                ismd = True
+                iscryptostart = True
+            m = re.match ("static const char \*selftest.*;$", line)
+            if not m is None:
+                fname = line[len ("static const char \*"):]
+                fname = re.match ("[a-zA-Z0-9_]*", fname).group ()
+                chmsg = "(%s): Removed declaration." % fname
+                if nch:
+                    chlognew = "%s\n   %s" % (chlognew, chmsg)
+                else:
+                    chlognew = "%s %s" % (chlognew, chmsg)
+                    nch = True
+                continue
+            m = re.match ("(static const char( |)\*|static gpg_err_code_t|void|static int|static gcry_err_code_t)$", line)
+            if not m is None:
+                hold = True
+                holdline = line
+                continue
+            m = re.match ("static int tripledes_set2keys \(.*\);", line)
+            if not m is None:
+                continue
+            m = re.match ("static int tripledes_set2keys \(", line)
+            if not m is None:
+                skip_statement = True
+                continue
+            m = re.match ("cipher_extra_spec_t", line)
+            if isc and not m is None:
+                skip2 = True
+                fname = line[len ("cipher_extra_spec_t "):]
+                fname = re.match ("[a-zA-Z0-9_]*", fname).group ()
+                chmsg = "(%s): Removed." % fname
+                if nch:
+                    chlognew = "%s\n   %s" % (chlognew, chmsg)
+                else:
+                    chlognew = "%s %s" % (chlognew, chmsg)
+                    nch = True
+                continue
+            m = re.match ("md_extra_spec_t", line)
+            if isc and not m is None:
+                skip2 = True
+                fname = line[len ("md_extra_spec_t "):]
+                fname = re.match ("[a-zA-Z0-9_]*", fname).group ()
+                chmsg = "(%s): Removed." % fname
+                if nch:
+                    chlognew = "%s\n   %s" % (chlognew, chmsg)
+                else:
+                    chlognew = "%s %s" % (chlognew, chmsg)
+                    nch = True
+                continue
+            fw.write (line)
+        if len (ciphernames) > 0 or len (mdnames) > 0:
+            if isglue:
+                modfiles = "lib/libgcrypt-grub/cipher/%s lib/libgcrypt-grub/cipher/%s" \
+                    % (cipher_file, cipher_file.replace ("-glue.c", ".c"))
+            else:
+                modfiles = "lib/libgcrypt-grub/cipher/%s" % cipher_file
+            chmsg = "(GRUB_MOD_INIT(%s)): New function\n" % modname
+            if nch:
+                chlognew = "%s\n       %s" % (chlognew, chmsg)
+            else:
+                chlognew = "%s%s" % (chlognew, chmsg)
+                nch = True
+            fw.write ("\n\nGRUB_MOD_INIT(%s)\n" % modname)
+            fw.write ("{\n")
+            for ciphername in ciphernames:
+                chmsg = "Register cipher %s" % ciphername
+                chlognew = "%s\n       %s" % (chlognew, chmsg)
+                fw.write ("  grub_cipher_register (&%s);\n" % ciphername)
+            for mdname in mdnames:
+                chmsg = "Register digest %s" % mdname
+                chlognew = "%s\n       %s" % (chlognew, chmsg)
+                fw.write ("  grub_md_register (&%s);\n" % mdname)
+            fw.write ("}")
+            chmsg = "(GRUB_MOD_FINI(%s)): New function\n" % modname
+            chlognew = "%s\n   %s" % (chlognew, chmsg)
+            fw.write ("\n\nGRUB_MOD_FINI(%s)\n" % modname)
+            fw.write ("{\n")
+            for ciphername in ciphernames:
+                chmsg = "Unregister cipher %s" % ciphername
+                chlognew = "%s\n       %s" % (chlognew, chmsg)
+                fw.write ("  grub_cipher_unregister (&%s);\n" % ciphername)
+            for mdname in mdnames:
+                chmsg = "Unregister MD %s" % mdname
+                chlognew = "%s\n       %s" % (chlognew, chmsg)
+                fw.write ("  grub_md_unregister (&%s);\n" % mdname)
+            fw.write ("}\n")
+            conf.write ("pkglib_MODULES += %s.mod\n" % modname)
+            conf.write ("%s_mod_SOURCES = %s\n" %\
+                            (modname, modfiles))
+            conf.write ("%s_mod_CFLAGS = $(COMMON_CFLAGS) -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap\n" % modname)
+            conf.write ("%s_mod_LDFLAGS = $(COMMON_LDFLAGS)\n\n" % modname)
+        elif isc and cipher_file != "camellia.c":
+            print ("WARNING: C file isn't a module: %s" % cipher_file)
+        f.close ()
+        fw.close ()
+        if nch:
+            chlog = "%s%s\n" % (chlog, chlognew)
+        continue
+    chlog = "%s%sSkipped unknown file\n" % (chlog, chlognew)
+    print ("WARNING: unknown file %s" % cipher_file)
+
+cryptolist.close ()
+chlog = "%s    * crypto.lst: New file.\n" % chlog
+
+outfile = os.path.join (cipher_dir_out, "types.h")
+fw=open (outfile, "w")
+fw.write ("#include <grub/types.h>\n")
+fw.write ("#include <cipher_wrap.h>\n")
+chlog = "%s    * types.h: New file.\n" % chlog
+fw.close ()
+
+outfile = os.path.join (cipher_dir_out, "memory.h")
+fw=open (outfile, "w")
+fw.write ("#include <cipher_wrap.h>\n")
+chlog = "%s    * memory.h: New file.\n" % chlog
+fw.close ()
+
+
+outfile = os.path.join (cipher_dir_out, "cipher.h")
+fw=open (outfile, "w")
+fw.write ("#include <grub/crypto.h>\n")
+fw.write ("#include <cipher_wrap.h>\n")
+chlog = "%s    * cipher.h: Likewise.\n" % chlog
+fw.close ()
+
+outfile = os.path.join (cipher_dir_out, "g10lib.h")
+fw=open (outfile, "w")
+fw.write ("#include <cipher_wrap.h>\n")
+chlog = "%s    * g10lib.h: Likewise.\n" % chlog
+fw.close ()
+
+infile = os.path.join (cipher_dir_in, "ChangeLog")
+outfile = os.path.join (cipher_dir_out, "ChangeLog")
+
+
+f=open (infile, "r")
+fw=open (outfile, "w")
+dt = datetime.date.today ()
+fw.write ("%04d-%02d-%02d  Automatic import tool\n" % \
+          (dt.year,dt.month, dt.day))
+fw.write ("\n")
+fw.write ("    Imported ciphers to GRUB\n")
+fw.write ("\n")
+fw.write (chlog)
+fw.write ("\n")
+for line in f:
+    fw.write (line)
+f.close ()
+fw.close ()
diff --git a/grub-core/include/grub/acorn_filecore.h b/grub-core/include/grub/acorn_filecore.h
new file mode 100644 (file)
index 0000000..6cda6cf
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ACORN_FILECORE_HEADER
+#define GRUB_ACORN_FILECORE_HEADER     1
+
+#include <grub/types.h>
+
+struct grub_filecore_disc_record
+{
+  grub_uint8_t log2secsize;
+  grub_uint8_t secspertrack;
+  grub_uint8_t heads;
+  grub_uint8_t density;
+  grub_uint8_t idlen;
+  grub_uint8_t log2bpmb;
+  grub_uint8_t skew;
+  grub_uint8_t bootoption;
+  /* In bits 0-5, flags in bits 6 and 7.  */
+  grub_uint8_t lowsector;
+  grub_uint8_t nzones;
+  grub_uint16_t zone_spare;
+  grub_uint32_t root_address;
+  /* Disc size in bytes.  */
+  grub_uint32_t disc_size;
+  grub_uint16_t cycle_id;
+  char disc_name[10];
+  /* Yes, it is 32 bits!  */
+  grub_uint32_t disctype;
+  /* Most significant part of the disc size.  */
+  grub_uint32_t disc_size2;
+  grub_uint8_t share_size;
+  grub_uint8_t big_flag;
+  grub_uint8_t reserved[18];
+};
+
+
+#endif /* ! GRUB_ACORN_FILECORE_HEADER */
diff --git a/grub-core/include/grub/acpi.h b/grub-core/include/grub/acpi.h
new file mode 100644 (file)
index 0000000..7933db8
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ACPI_HEADER
+#define GRUB_ACPI_HEADER       1
+
+#include <grub/types.h>
+#include <grub/err.h>
+
+struct grub_acpi_rsdp_v10
+{
+  grub_uint8_t signature[8];
+  grub_uint8_t checksum;
+  grub_uint8_t oemid[6];
+  grub_uint8_t revision;
+  grub_uint32_t rsdt_addr;
+} __attribute__ ((packed));
+
+struct grub_acpi_rsdp_v20
+{
+  struct grub_acpi_rsdp_v10 rsdpv1;
+  grub_uint32_t length;
+  grub_uint64_t xsdt_addr;
+  grub_uint8_t checksum;
+  grub_uint8_t reserved[3];
+} __attribute__ ((packed));
+
+struct grub_acpi_table_header
+{
+  grub_uint8_t signature[4];
+  grub_uint32_t length;
+  grub_uint8_t revision;
+  grub_uint8_t checksum;
+  grub_uint8_t oemid[6];
+  grub_uint8_t oemtable[8];
+  grub_uint32_t oemrev;
+  grub_uint8_t creator_id[4];
+  grub_uint32_t creator_rev;
+} __attribute__ ((packed));
+
+struct grub_acpi_fadt
+{
+  struct grub_acpi_table_header hdr;
+  grub_uint32_t facs_addr;
+  grub_uint32_t dsdt_addr;
+  grub_uint8_t somefields1[88];
+  grub_uint64_t facs_xaddr;
+  grub_uint64_t dsdt_xaddr;
+  grub_uint8_t somefields2[96];
+} __attribute__ ((packed));
+
+struct grub_acpi_rsdp_v10 *grub_acpi_get_rsdpv1 (void);
+struct grub_acpi_rsdp_v20 *grub_acpi_get_rsdpv2 (void);
+struct grub_acpi_rsdp_v10 *grub_machine_acpi_get_rsdpv1 (void);
+struct grub_acpi_rsdp_v20 *grub_machine_acpi_get_rsdpv2 (void);
+grub_uint8_t grub_byte_checksum (void *base, grub_size_t size);
+
+grub_err_t grub_acpi_create_ebda (void);
+
+#endif /* ! GRUB_ACPI_HEADER */
diff --git a/grub-core/include/grub/aout.h b/grub-core/include/grub/aout.h
new file mode 100644 (file)
index 0000000..f962a97
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ *      The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *      from: @(#)exec.h        8.1 (Berkeley) 6/11/93
+ * $FreeBSD$
+ */
+
+#ifndef GRUB_AOUT_HEADER
+#define GRUB_AOUT_HEADER 1
+
+#include <grub/types.h>
+
+struct grub_aout32_header
+{
+  grub_uint32_t a_midmag;      /* htonl(flags<<26 | mid<<16 | magic) */
+  grub_uint32_t a_text;                /* text segment size */
+  grub_uint32_t a_data;                /* initialized data size */
+  grub_uint32_t a_bss;         /* uninitialized data size */
+  grub_uint32_t a_syms;                /* symbol table size */
+  grub_uint32_t a_entry;       /* entry point */
+  grub_uint32_t a_trsize;      /* text relocation size */
+  grub_uint32_t a_drsize;      /* data relocation size */
+};
+
+struct grub_aout64_header
+{
+  grub_uint32_t a_midmag;      /* htonl(flags<<26 | mid<<16 | magic) */
+  grub_uint64_t a_text;                /* text segment size */
+  grub_uint64_t a_data;                /* initialized data size */
+  grub_uint64_t a_bss;         /* uninitialized data size */
+  grub_uint64_t a_syms;                /* symbol table size */
+  grub_uint64_t a_entry;       /* entry point */
+  grub_uint64_t a_trsize;      /* text relocation size */
+  grub_uint64_t a_drsize;      /* data relocation size */
+};
+
+union grub_aout_header
+{
+  struct grub_aout32_header aout32;
+  struct grub_aout64_header aout64;
+};
+
+#define AOUT_TYPE_NONE         0
+#define AOUT_TYPE_AOUT32       1
+#define AOUT_TYPE_AOUT64       6
+
+#define        AOUT32_OMAGIC           0x107   /* 0407 old impure format */
+#define        AOUT32_NMAGIC           0x108   /* 0410 read-only text */
+#define        AOUT32_ZMAGIC           0x10b   /* 0413 demand load format */
+#define AOUT32_QMAGIC          0xcc    /* 0314 "compact" demand load format */
+
+#define AOUT64_OMAGIC          0x1001
+#define AOUT64_ZMAGIC          0x1002
+#define AOUT64_NMAGIC          0x1003
+
+#define        AOUT_MID_ZERO           0       /* unknown - implementation dependent */
+#define        AOUT_MID_SUN010         1       /* sun 68010/68020 binary */
+#define        AOUT_MID_SUN020         2       /* sun 68020-only binary */
+#define AOUT_MID_I386          134     /* i386 BSD binary */
+#define AOUT_MID_SPARC         138     /* sparc */
+#define        AOUT_MID_HP200          200     /* hp200 (68010) BSD binary */
+#define        AOUT_MID_SUN            0x103
+#define        AOUT_MID_HP300          300     /* hp300 (68020+68881) BSD binary */
+#define        AOUT_MID_HPUX           0x20C   /* hp200/300 HP-UX binary */
+#define        AOUT_MID_HPUX800        0x20B   /* hp800 HP-UX binary */
+
+#define AOUT_FLAG_PIC          0x10    /* contains position independent code */
+#define AOUT_FLAG_DYNAMIC      0x20    /* contains run-time link-edit info */
+#define AOUT_FLAG_DPMASK       0x30    /* mask for the above */
+
+#define AOUT_GETMAGIC(header) ((header).a_midmag & 0xffff)
+#define AOUT_GETMID(header) ((header).a_midmag >> 16) & 0x03ff)
+#define AOUT_GETFLAG(header) ((header).a_midmag >> 26) & 0x3f)
+
+#ifndef GRUB_UTIL
+
+int EXPORT_FUNC(grub_aout_get_type) (union grub_aout_header *header);
+
+grub_err_t EXPORT_FUNC(grub_aout_load) (grub_file_t file, int offset,
+                                        grub_addr_t load_addr, int load_size,
+                                        grub_addr_t bss_end_addr);
+
+#endif
+
+#endif /* ! GRUB_AOUT_HEADER */
diff --git a/grub-core/include/grub/at_keyboard.h b/grub-core/include/grub/at_keyboard.h
new file mode 100644 (file)
index 0000000..1042154
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_AT_KEYBOARD_HEADER
+#define GRUB_AT_KEYBOARD_HEADER        1
+
+#define SHIFT_L                0x2a
+#define SHIFT_R                0x36
+#define CTRL           0x1d
+#define ALT            0x38
+#define CAPS_LOCK      0x3a
+#define NUM_LOCK       0x45
+#define SCROLL_LOCK    0x46
+
+/* Used for sending commands to the controller.  */
+#define KEYBOARD_COMMAND_ISREADY(x)    !((x) & 0x02)
+#define KEYBOARD_COMMAND_READ          0x20
+#define KEYBOARD_COMMAND_WRITE         0x60
+#define KEYBOARD_COMMAND_REBOOT                0xfe
+
+#define KEYBOARD_SCANCODE_SET1         0x40
+
+#define KEYBOARD_ISMAKE(x)     !((x) & 0x80)
+#define KEYBOARD_ISREADY(x)    ((x) & 0x01)
+#define KEYBOARD_SCANCODE(x)   ((x) & 0x7f)
+
+#ifdef GRUB_MACHINE_IEEE1275
+#define OLPC_UP                GRUB_TERM_UP
+#define OLPC_DOWN      GRUB_TERM_DOWN
+#define OLPC_LEFT      GRUB_TERM_LEFT
+#define OLPC_RIGHT     GRUB_TERM_RIGHT
+#else
+#define OLPC_UP                '\0'
+#define OLPC_DOWN      '\0'
+#define OLPC_LEFT      '\0'
+#define OLPC_RIGHT     '\0'
+#endif
+
+#endif
diff --git a/grub-core/include/grub/ata.h b/grub-core/include/grub/ata.h
new file mode 100644 (file)
index 0000000..940e671
--- /dev/null
@@ -0,0 +1,168 @@
+/* ata.h - ATA disk access.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ATA_HEADER
+#define GRUB_ATA_HEADER 1
+
+#include <grub/misc.h>
+#include <grub/symbol.h>
+/* XXX: For now this only works on i386.  */
+#include <grub/cpu/io.h>
+
+typedef enum
+  {
+    GRUB_ATA_CHS,
+    GRUB_ATA_LBA,
+    GRUB_ATA_LBA48
+  } grub_ata_addressing_t;
+
+#define GRUB_ATA_REG_DATA      0
+#define GRUB_ATA_REG_ERROR     1
+#define GRUB_ATA_REG_FEATURES  1
+#define GRUB_ATA_REG_SECTORS   2
+#define GRUB_ATAPI_REG_IREASON 2
+#define GRUB_ATA_REG_SECTNUM   3
+#define GRUB_ATA_REG_CYLLSB    4
+#define GRUB_ATA_REG_CYLMSB    5
+#define GRUB_ATA_REG_LBALOW    3
+#define GRUB_ATA_REG_LBAMID    4
+#define GRUB_ATAPI_REG_CNTLOW  4
+#define GRUB_ATA_REG_LBAHIGH   5
+#define GRUB_ATAPI_REG_CNTHIGH 5
+#define GRUB_ATA_REG_DISK      6
+#define GRUB_ATA_REG_CMD       7
+#define GRUB_ATA_REG_STATUS    7
+
+#define GRUB_ATA_REG2_CONTROL  0
+
+#define GRUB_ATA_STATUS_ERR    0x01
+#define GRUB_ATA_STATUS_INDEX  0x02
+#define GRUB_ATA_STATUS_ECC    0x04
+#define GRUB_ATA_STATUS_DRQ    0x08
+#define GRUB_ATA_STATUS_SEEK   0x10
+#define GRUB_ATA_STATUS_WRERR  0x20
+#define GRUB_ATA_STATUS_READY  0x40
+#define GRUB_ATA_STATUS_BUSY   0x80
+
+/* ATAPI interrupt reason values (I/O, D/C bits).  */
+#define GRUB_ATAPI_IREASON_MASK     0x3
+#define GRUB_ATAPI_IREASON_DATA_OUT 0x0
+#define GRUB_ATAPI_IREASON_CMD_OUT  0x1
+#define GRUB_ATAPI_IREASON_DATA_IN  0x2
+#define GRUB_ATAPI_IREASON_ERROR    0x3
+
+enum grub_ata_commands
+  {
+    GRUB_ATA_CMD_CHECK_POWER_MODE      = 0xe5,
+    GRUB_ATA_CMD_IDENTIFY_DEVICE       = 0xec,
+    GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE        = 0xa1,
+    GRUB_ATA_CMD_IDLE                  = 0xe3,
+    GRUB_ATA_CMD_PACKET                        = 0xa0,
+    GRUB_ATA_CMD_READ_SECTORS          = 0x20,
+    GRUB_ATA_CMD_READ_SECTORS_EXT      = 0x24,
+    GRUB_ATA_CMD_SECURITY_FREEZE_LOCK  = 0xf5,
+    GRUB_ATA_CMD_SET_FEATURES          = 0xef,
+    GRUB_ATA_CMD_SLEEP                 = 0xe6,
+    GRUB_ATA_CMD_SMART                 = 0xb0,
+    GRUB_ATA_CMD_STANDBY_IMMEDIATE     = 0xe0,
+    GRUB_ATA_CMD_WRITE_SECTORS         = 0x30,
+    GRUB_ATA_CMD_WRITE_SECTORS_EXT     = 0x34,
+  };
+
+enum grub_ata_timeout_milliseconds
+  {
+    GRUB_ATA_TOUT_STD  =  1000,  /* 1s standard timeout.  */
+    GRUB_ATA_TOUT_DATA = 10000   /* 10s DATA I/O timeout.  */
+  };
+
+struct grub_ata_device
+{
+  /* IDE port to use.  */
+  int port;
+
+  /* IO addresses on which the registers for this device can be
+     found.  */
+  grub_port_t ioaddress;
+  grub_port_t ioaddress2;
+
+  /* Two devices can be connected to a single cable.  Use this field
+     to select device 0 (commonly known as "master") or device 1
+     (commonly known as "slave").  */
+  int device;
+
+  /* Addressing methods available for accessing this device.  If CHS
+     is only available, use that.  Otherwise use LBA, except for the
+     high sectors.  In that case use LBA48.  */
+  grub_ata_addressing_t addr;
+
+  /* Sector count.  */
+  grub_uint64_t size;
+
+  /* CHS maximums.  */
+  grub_uint16_t cylinders;
+  grub_uint16_t heads;
+  grub_uint16_t sectors_per_track;
+
+  /* Set to 0 for ATA, set to 1 for ATAPI.  */
+  int atapi;
+
+  struct grub_ata_device *next;
+};
+
+grub_err_t EXPORT_FUNC(grub_ata_wait_not_busy) (struct grub_ata_device *dev,
+                                                int milliseconds);
+grub_err_t EXPORT_FUNC(grub_ata_wait_drq) (struct grub_ata_device *dev,
+                                          int rw, int milliseconds);
+void EXPORT_FUNC(grub_ata_pio_read) (struct grub_ata_device *dev,
+                                    char *buf, grub_size_t size);
+
+static inline void
+grub_ata_regset (struct grub_ata_device *dev, int reg, int val)
+{
+  grub_outb (val, dev->ioaddress + reg);
+}
+
+static inline grub_uint8_t
+grub_ata_regget (struct grub_ata_device *dev, int reg)
+{
+  return grub_inb (dev->ioaddress + reg);
+}
+
+static inline void
+grub_ata_regset2 (struct grub_ata_device *dev, int reg, int val)
+{
+  grub_outb (val, dev->ioaddress2 + reg);
+}
+
+static inline grub_uint8_t
+grub_ata_regget2 (struct grub_ata_device *dev, int reg)
+{
+  return grub_inb (dev->ioaddress2 + reg);
+}
+
+static inline grub_err_t
+grub_ata_check_ready (struct grub_ata_device *dev)
+{
+  if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY)
+    return grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_STD);
+
+  return GRUB_ERR_NONE;
+}
+
+#endif /* ! GRUB_ATA_HEADER */
diff --git a/grub-core/include/grub/auth.h b/grub-core/include/grub/auth.h
new file mode 100644 (file)
index 0000000..7473344
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef GRUB_AUTH_HEADER
+#define GRUB_AUTH_HEADER       1
+
+#include <grub/err.h>
+#include <grub/crypto.h>
+
+#define GRUB_AUTH_MAX_PASSLEN 1024
+
+typedef grub_err_t (*grub_auth_callback_t) (const char *, const char *, void *);
+
+grub_err_t grub_auth_register_authentication (const char *user,
+                                             grub_auth_callback_t callback,
+                                             void *arg);
+grub_err_t grub_auth_unregister_authentication (const char *user);
+
+grub_err_t grub_auth_authenticate (const char *user);
+grub_err_t grub_auth_deauthenticate (const char *user);
+grub_err_t grub_auth_check_authentication (const char *userlist);
+
+#endif /* ! GRUB_AUTH_HEADER */
diff --git a/grub-core/include/grub/autoefi.h b/grub-core/include/grub/autoefi.h
new file mode 100644 (file)
index 0000000..5ae4b3a
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+/* This file provides some abstractions so that the same code compiles with
+   both efi and efiemu
+ */
+#ifndef GRUB_AUTOEFI_HEADER
+#define GRUB_AUTOEFI_HEADER    1
+
+
+#ifdef GRUB_MACHINE_EFI
+# include <grub/efi/efi.h>
+# define grub_autoefi_get_memory_map grub_efi_get_memory_map
+# define grub_autoefi_finish_boot_services grub_efi_finish_boot_services
+# define grub_autoefi_exit_boot_services grub_efi_exit_boot_services
+# define grub_autoefi_system_table grub_efi_system_table
+# define grub_autoefi_mmap_iterate grub_machine_mmap_iterate
+# define grub_autoefi_set_virtual_address_map grub_efi_set_virtual_address_map
+static inline grub_err_t grub_autoefi_prepare (void)
+{
+  return GRUB_ERR_NONE;
+};
+# define GRUB_AUTOEFI_MEMORY_AVAILABLE GRUB_MACHINE_MEMORY_AVAILABLE
+# define GRUB_AUTOEFI_MEMORY_RESERVED GRUB_MACHINE_MEMORY_RESERVED
+# ifdef GRUB_MACHINE_MEMORY_ACPI
+#  define GRUB_AUTOEFI_MEMORY_ACPI GRUB_MACHINE_MEMORY_ACPI
+# endif
+# ifdef GRUB_MACHINE_MEMORY_NVS
+#  define GRUB_AUTOEFI_MEMORY_NVS GRUB_MACHINE_MEMORY_NVS
+# endif
+# ifdef GRUB_MACHINE_MEMORY_CODE
+#  define GRUB_AUTOEFI_MEMORY_CODE GRUB_MACHINE_MEMORY_CODE
+# endif
+# define SYSTEM_TABLE_SIZEOF(x) (sizeof(grub_efi_system_table->x))
+# define SYSTEM_TABLE_VAR(x) ((void *)&(grub_efi_system_table->x))
+# define SYSTEM_TABLE_PTR(x) ((void *)(grub_efi_system_table->x))
+# define SIZEOF_OF_UINTN sizeof (grub_efi_uintn_t)
+# define SYSTEM_TABLE(x) (grub_efi_system_table->x)
+# define EFI_PRESENT 1
+#else
+# include <grub/efiemu/efiemu.h>
+# define grub_autoefi_get_memory_map grub_efiemu_get_memory_map
+# define grub_autoefi_finish_boot_services grub_efiemu_finish_boot_services
+# define grub_autoefi_exit_boot_services grub_efiemu_exit_boot_services
+# define grub_autoefi_system_table grub_efiemu_system_table
+# define grub_autoefi_mmap_iterate grub_efiemu_mmap_iterate
+# define grub_autoefi_prepare grub_efiemu_prepare
+# define grub_autoefi_set_virtual_address_map grub_efiemu_set_virtual_address_map
+# define GRUB_AUTOEFI_MEMORY_AVAILABLE GRUB_EFIEMU_MEMORY_AVAILABLE
+# define GRUB_AUTOEFI_MEMORY_RESERVED GRUB_EFIEMU_MEMORY_RESERVED
+# define GRUB_AUTOEFI_MEMORY_ACPI GRUB_EFIEMU_MEMORY_ACPI
+# define GRUB_AUTOEFI_MEMORY_NVS GRUB_EFIEMU_MEMORY_NVS
+# define GRUB_AUTOEFI_MEMORY_CODE GRUB_EFIEMU_MEMORY_CODE
+# define SYSTEM_TABLE_SIZEOF GRUB_EFIEMU_SYSTEM_TABLE_SIZEOF
+# define SYSTEM_TABLE_VAR GRUB_EFIEMU_SYSTEM_TABLE_VAR
+# define SYSTEM_TABLE_PTR GRUB_EFIEMU_SYSTEM_TABLE_PTR
+# define SIZEOF_OF_UINTN GRUB_EFIEMU_SIZEOF_OF_UINTN
+# define SYSTEM_TABLE GRUB_EFIEMU_SYSTEM_TABLE
+# define grub_efi_allocate_pages(x,y) (x)
+# define grub_efi_free_pages(x,y) GRUB_EFI_SUCCESS
+# define EFI_PRESENT 1
+#endif
+
+#endif
diff --git a/grub-core/include/grub/bitmap.h b/grub-core/include/grub/bitmap.h
new file mode 100644 (file)
index 0000000..6e30039
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BITMAP_HEADER
+#define GRUB_BITMAP_HEADER     1
+
+#include <grub/err.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/video.h>
+
+struct grub_video_bitmap
+{
+  /* Bitmap format description.  */
+  struct grub_video_mode_info mode_info;
+
+  /* Pointer to bitmap data formatted according to mode_info.  */
+  void *data;
+};
+
+struct grub_video_bitmap_reader
+{
+  /* File extension for this bitmap type (including dot).  */
+  const char *extension;
+
+  /* Reader function to load bitmap.  */
+  grub_err_t (*reader) (struct grub_video_bitmap **bitmap,
+                        const char *filename);
+
+  /* Next reader.  */
+  struct grub_video_bitmap_reader *next;
+};
+typedef struct grub_video_bitmap_reader *grub_video_bitmap_reader_t;
+
+void EXPORT_FUNC (grub_video_bitmap_reader_register) (grub_video_bitmap_reader_t reader);
+void EXPORT_FUNC (grub_video_bitmap_reader_unregister) (grub_video_bitmap_reader_t reader);
+
+grub_err_t EXPORT_FUNC (grub_video_bitmap_create) (struct grub_video_bitmap **bitmap,
+                                                  unsigned int width, unsigned int height,
+                                                  enum grub_video_blit_format blit_format);
+
+grub_err_t EXPORT_FUNC (grub_video_bitmap_destroy) (struct grub_video_bitmap *bitmap);
+
+grub_err_t EXPORT_FUNC (grub_video_bitmap_load) (struct grub_video_bitmap **bitmap,
+                                                const char *filename);
+
+unsigned int EXPORT_FUNC (grub_video_bitmap_get_width) (struct grub_video_bitmap *bitmap);
+unsigned int EXPORT_FUNC (grub_video_bitmap_get_height) (struct grub_video_bitmap *bitmap);
+
+void EXPORT_FUNC (grub_video_bitmap_get_mode_info) (struct grub_video_bitmap *bitmap,
+                                                   struct grub_video_mode_info *mode_info);
+
+void *EXPORT_FUNC (grub_video_bitmap_get_data) (struct grub_video_bitmap *bitmap);
+
+#endif /* ! GRUB_BITMAP_HEADER */
diff --git a/grub-core/include/grub/bitmap_scale.h b/grub-core/include/grub/bitmap_scale.h
new file mode 100644 (file)
index 0000000..dce9fbb
--- /dev/null
@@ -0,0 +1,49 @@
+/* bitmap_scale.h - Bitmap scaling functions. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BITMAP_SCALE_HEADER
+#define GRUB_BITMAP_SCALE_HEADER 1
+
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/bitmap_scale.h>
+
+enum grub_video_bitmap_scale_method
+{
+  /* Choose the fastest interpolation algorithm.  */
+  GRUB_VIDEO_BITMAP_SCALE_METHOD_FASTEST,
+  /* Choose the highest quality interpolation algorithm.  */
+  GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST,
+
+  /* Specific algorithms:  */
+  /* Nearest neighbor interpolation.  */
+  GRUB_VIDEO_BITMAP_SCALE_METHOD_NEAREST,
+  /* Bilinear interpolation.  */
+  GRUB_VIDEO_BITMAP_SCALE_METHOD_BILINEAR
+};
+
+grub_err_t
+EXPORT_FUNC (grub_video_bitmap_create_scaled) (struct grub_video_bitmap **dst,
+                                              int dst_width, int dst_height,
+                                              struct grub_video_bitmap *src,
+                                              enum 
+                                              grub_video_bitmap_scale_method
+                                              scale_method);
+
+#endif /* ! GRUB_BITMAP_SCALE_HEADER */
diff --git a/grub-core/include/grub/boot.h b/grub-core/include/grub/boot.h
new file mode 100644 (file)
index 0000000..2357748
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BOOT_HEADER
+#define GRUB_BOOT_HEADER       1
+
+#define GRUB_BOOT_VERSION_MAJOR        4
+#define GRUB_BOOT_VERSION_MINOR        0
+#define GRUB_BOOT_VERSION      ((GRUB_BOOT_VERSION_MINOR << 8) \
+                                       | GRUB_BOOT_VERSION_MAJOR)
+
+#endif /* ! GRUB_BOOT_HEADER */
diff --git a/grub-core/include/grub/bsdlabel.h b/grub-core/include/grub/bsdlabel.h
new file mode 100644 (file)
index 0000000..d88b253
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BSDLABEL_PARTITION_HEADER
+#define GRUB_BSDLABEL_PARTITION_HEADER 1
+
+/* Constants for BSD disk label.  */
+#define GRUB_PC_PARTITION_BSD_LABEL_SECTOR     1
+#define GRUB_PC_PARTITION_BSD_LABEL_MAGIC      0x82564557
+
+/* BSD partition types.  */
+#define GRUB_PC_PARTITION_BSD_TYPE_UNUSED      0
+#define GRUB_PC_PARTITION_BSD_TYPE_SWAP                1
+#define GRUB_PC_PARTITION_BSD_TYPE_V6          2
+#define GRUB_PC_PARTITION_BSD_TYPE_V7          3
+#define GRUB_PC_PARTITION_BSD_TYPE_SYSV                4
+#define GRUB_PC_PARTITION_BSD_TYPE_V71K                5
+#define GRUB_PC_PARTITION_BSD_TYPE_V8          6
+#define GRUB_PC_PARTITION_BSD_TYPE_BSDFFS      7
+#define GRUB_PC_PARTITION_BSD_TYPE_MSDOS       8
+#define GRUB_PC_PARTITION_BSD_TYPE_BSDLFS      9
+#define GRUB_PC_PARTITION_BSD_TYPE_OTHER       10
+#define GRUB_PC_PARTITION_BSD_TYPE_HPFS                11
+#define GRUB_PC_PARTITION_BSD_TYPE_ISO9660     12
+#define GRUB_PC_PARTITION_BSD_TYPE_BOOT                13
+
+/* FreeBSD-specific types.  */
+#define GRUB_PC_PARTITION_FREEBSD_TYPE_VINUM   14
+#define GRUB_PC_PARTITION_FREEBSD_TYPE_RAID    15
+#define GRUB_PC_PARTITION_FREEBSD_TYPE_JFS2    21
+
+/* NetBSD-specific types.  */
+#define        GRUB_PC_PARTITION_NETBSD_TYPE_ADOS      14
+#define        GRUB_PC_PARTITION_NETBSD_TYPE_HFS       15
+#define        GRUB_PC_PARTITION_NETBSD_TYPE_FILECORE  16
+#define        GRUB_PC_PARTITION_NETBSD_TYPE_EXT2FS    17
+#define        GRUB_PC_PARTITION_NETBSD_TYPE_NTFS      18
+#define        GRUB_PC_PARTITION_NETBSD_TYPE_RAID      19
+#define        GRUB_PC_PARTITION_NETBSD_TYPE_CCD       20
+#define        GRUB_PC_PARTITION_NETBSD_TYPE_JFS2      21
+#define        GRUB_PC_PARTITION_NETBSD_TYPE_APPLEUFS  22
+
+/* OpenBSD-specific types.  */
+#define        GRUB_PC_PARTITION_OPENBSD_TYPE_ADOS     14
+#define        GRUB_PC_PARTITION_OPENBSD_TYPE_HFS      15
+#define        GRUB_PC_PARTITION_OPENBSD_TYPE_FILECORE 16
+#define        GRUB_PC_PARTITION_OPENBSD_TYPE_EXT2FS   17
+#define        GRUB_PC_PARTITION_OPENBSD_TYPE_NTFS     18
+#define        GRUB_PC_PARTITION_OPENBSD_TYPE_RAID     19
+
+/* The BSD partition entry.  */
+struct grub_partition_bsd_entry
+{
+  grub_uint32_t size;
+  grub_uint32_t offset;
+  grub_uint32_t fragment_size;
+  grub_uint8_t fs_type;
+  grub_uint8_t fs_fragments;
+  grub_uint16_t fs_cylinders;
+} __attribute__ ((packed));
+
+/* The BSD disk label. Only define members useful for GRUB.  */
+struct grub_partition_bsd_disk_label
+{
+  grub_uint32_t magic;
+  grub_uint8_t padding[128];
+  grub_uint32_t magic2;
+  grub_uint16_t checksum;
+  grub_uint16_t num_partitions;
+  grub_uint32_t boot_size;
+  grub_uint32_t superblock_size;
+} __attribute__ ((packed));
+
+#endif /* ! GRUB_PC_PARTITION_HEADER */
diff --git a/grub-core/include/grub/bufio.h b/grub-core/include/grub/bufio.h
new file mode 100644 (file)
index 0000000..acdd0c8
--- /dev/null
@@ -0,0 +1,28 @@
+/* bufio.h - prototypes for bufio */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BUFIO_H
+#define GRUB_BUFIO_H   1
+
+#include <grub/file.h>
+
+grub_file_t EXPORT_FUNC (grub_bufio_open) (grub_file_t io, int size);
+grub_file_t EXPORT_FUNC (grub_buffile_open) (const char *name, int size);
+
+#endif /* ! GRUB_BUFIO_H */
diff --git a/grub-core/include/grub/cache.h b/grub-core/include/grub/cache.h
new file mode 100644 (file)
index 0000000..27e44f0
--- /dev/null
@@ -0,0 +1,36 @@
+/* cache.h - Flush the processor's cache.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CACHE_H
+#define GRUB_CACHE_H   1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+#if defined (__i386__) || defined (__x86_64__)
+static inline void
+grub_arch_sync_caches (void *address __attribute__ ((unused)),
+                      grub_size_t len __attribute__ ((unused)))
+{
+}
+#else
+void EXPORT_FUNC(grub_arch_sync_caches) (void *address, grub_size_t len);
+#endif
+
+#endif /* ! GRUB_CACHE_HEADER */
diff --git a/grub-core/include/grub/charset.h b/grub-core/include/grub/charset.h
new file mode 100644 (file)
index 0000000..fc050da
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CHARSET_HEADER
+#define GRUB_CHARSET_HEADER    1
+
+#include <grub/types.h>
+
+#define GRUB_UINT8_1_LEADINGBIT 0x80
+#define GRUB_UINT8_2_LEADINGBITS 0xc0
+#define GRUB_UINT8_3_LEADINGBITS 0xe0
+#define GRUB_UINT8_4_LEADINGBITS 0xf0
+#define GRUB_UINT8_5_LEADINGBITS 0xf8
+#define GRUB_UINT8_6_LEADINGBITS 0xfc
+#define GRUB_UINT8_7_LEADINGBITS 0xfe
+
+#define GRUB_UINT8_1_TRAILINGBIT 0x01
+#define GRUB_UINT8_2_TRAILINGBITS 0x03
+#define GRUB_UINT8_3_TRAILINGBITS 0x07
+#define GRUB_UINT8_4_TRAILINGBITS 0x0f
+#define GRUB_UINT8_5_TRAILINGBITS 0x1f
+#define GRUB_UINT8_6_TRAILINGBITS 0x3f
+
+#define GRUB_UCS2_LIMIT 0x10000
+#define GRUB_UTF16_UPPER_SURROGATE(code) \
+  (0xD800 + ((((code) - GRUB_UCS2_LIMIT) >> 12) & 0xfff))
+#define GRUB_UTF16_LOWER_SURROGATE(code) \
+  (0xDC00 + (((code) - GRUB_UCS2_LIMIT) & 0xfff))
+
+grub_ssize_t
+grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
+                   const grub_uint8_t *src, grub_size_t srcsize,
+                   const grub_uint8_t **srcend);
+
+/* Convert UTF-16 to UTF-8.  */
+static inline grub_uint8_t *
+grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src,
+                   grub_size_t size)
+{
+  grub_uint32_t code_high = 0;
+
+  while (size--)
+    {
+      grub_uint32_t code = *src++;
+
+      if (code_high)
+       {
+         if (code >= 0xDC00 && code <= 0xDFFF)
+           {
+             /* Surrogate pair.  */
+             code = ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000;
+
+             *dest++ = (code >> 18) | 0xF0;
+             *dest++ = ((code >> 12) & 0x3F) | 0x80;
+             *dest++ = ((code >> 6) & 0x3F) | 0x80;
+             *dest++ = (code & 0x3F) | 0x80;
+           }
+         else
+           {
+             /* Error...  */
+             *dest++ = '?';
+           }
+
+         code_high = 0;
+       }
+      else
+       {
+         if (code <= 0x007F)
+           *dest++ = code;
+         else if (code <= 0x07FF)
+           {
+             *dest++ = (code >> 6) | 0xC0;
+             *dest++ = (code & 0x3F) | 0x80;
+           }
+         else if (code >= 0xD800 && code <= 0xDBFF)
+           {
+             code_high = code;
+             continue;
+           }
+         else if (code >= 0xDC00 && code <= 0xDFFF)
+           {
+             /* Error... */
+             *dest++ = '?';
+           }
+         else
+           {
+             *dest++ = (code >> 12) | 0xE0;
+             *dest++ = ((code >> 6) & 0x3F) | 0x80;
+             *dest++ = (code & 0x3F) | 0x80;
+           }
+       }
+    }
+
+  return dest;
+}
+
+/* Convert UCS-4 to UTF-8.  */
+char *grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size);
+
+int
+grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize);
+
+int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
+                            grub_uint32_t **last_position);
+
+#endif
diff --git a/grub-core/include/grub/cmos.h b/grub-core/include/grub/cmos.h
new file mode 100644 (file)
index 0000000..f508e3b
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef        GRUB_CMOS_H
+#define        GRUB_CMOS_H     1
+
+#include <grub/types.h>
+#include <grub/cpu/io.h>
+#include <grub/cpu/cmos.h>
+
+#define GRUB_CMOS_INDEX_SECOND         0
+#define GRUB_CMOS_INDEX_SECOND_ALARM   1
+#define GRUB_CMOS_INDEX_MINUTE         2
+#define GRUB_CMOS_INDEX_MINUTE_ALARM   3
+#define GRUB_CMOS_INDEX_HOUR           4
+#define GRUB_CMOS_INDEX_HOUR_ALARM     5
+#define GRUB_CMOS_INDEX_DAY_OF_WEEK    6
+#define GRUB_CMOS_INDEX_DAY_OF_MONTH   7
+#define GRUB_CMOS_INDEX_MONTH          8
+#define GRUB_CMOS_INDEX_YEAR           9
+
+#define GRUB_CMOS_INDEX_STATUS_A       0xA
+#define GRUB_CMOS_INDEX_STATUS_B       0xB
+#define GRUB_CMOS_INDEX_STATUS_C       0xC
+#define GRUB_CMOS_INDEX_STATUS_D       0xD
+
+#define GRUB_CMOS_STATUS_B_DAYLIGHT    1
+#define GRUB_CMOS_STATUS_B_24HOUR      2
+#define GRUB_CMOS_STATUS_B_BINARY      4
+
+static inline grub_uint8_t
+grub_bcd_to_num (grub_uint8_t a)
+{
+  return ((a >> 4) * 10 + (a & 0xF));
+}
+
+static inline grub_uint8_t
+grub_num_to_bcd (grub_uint8_t a)
+{
+  return (((a / 10) << 4) + (a % 10));
+}
+
+static inline grub_uint8_t
+grub_cmos_read (grub_uint8_t index)
+{
+  grub_outb (index, GRUB_CMOS_ADDR_REG);
+  return grub_inb (GRUB_CMOS_DATA_REG);
+}
+
+static inline void
+grub_cmos_write (grub_uint8_t index, grub_uint8_t value)
+{
+  grub_outb (index, GRUB_CMOS_ADDR_REG);
+  grub_outb (value, GRUB_CMOS_DATA_REG);
+}
+
+#endif /* GRUB_CMOS_H */
diff --git a/grub-core/include/grub/command.h b/grub-core/include/grub/command.h
new file mode 100644 (file)
index 0000000..6e9942b
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_COMMAND_HEADER
+#define GRUB_COMMAND_HEADER    1
+
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/list.h>
+
+/* Can be run in the command-line.  */
+#define GRUB_COMMAND_FLAG_CMDLINE      0x1
+/* Can be run in the menu.  */
+#define GRUB_COMMAND_FLAG_MENU         0x2
+/* Can be run in both interfaces.  */
+#define GRUB_COMMAND_FLAG_BOTH         0x3
+/* Only for the command title.  */
+#define GRUB_COMMAND_FLAG_TITLE                0x4
+/* Don't print the command on booting.  */
+#define GRUB_COMMAND_FLAG_NO_ECHO      0x8
+/* This is an extended command.  */
+#define GRUB_COMMAND_FLAG_EXTCMD       0x10
+/* This is an dynamic command.  */
+#define GRUB_COMMAND_FLAG_DYNCMD       0x20
+
+struct grub_command;
+
+typedef grub_err_t (*grub_command_func_t) (struct grub_command *cmd,
+                                          int argc, char **argv);
+
+/* The command description.  */
+struct grub_command
+{
+  /* The next element.  */
+  struct grub_command *next;
+
+  /* The name.  */
+  const char *name;
+
+    /* The priority.  */
+  int prio;
+
+  /* The callback function.  */
+  grub_command_func_t func;
+
+  /* The flags.  */
+  unsigned flags;
+
+  /* The summary of the command usage.  */
+  const char *summary;
+
+  /* The description of the command.  */
+  const char *description;
+
+  /* Arbitrary data.  */
+  void *data;
+};
+typedef struct grub_command *grub_command_t;
+
+extern grub_command_t EXPORT_VAR(grub_command_list);
+
+grub_command_t
+EXPORT_FUNC(grub_register_command_prio) (const char *name,
+                                        grub_command_func_t func,
+                                        const char *summary,
+                                        const char *description,
+                                        int prio);
+void EXPORT_FUNC(grub_unregister_command) (grub_command_t cmd);
+
+static inline grub_command_t
+grub_register_command (const char *name,
+                      grub_command_func_t func,
+                      const char *summary,
+                      const char *description)
+{
+  return grub_register_command_prio (name, func, summary, description, 0);
+}
+
+static inline grub_command_t
+grub_register_command_p1 (const char *name,
+                         grub_command_func_t func,
+                         const char *summary,
+                         const char *description)
+{
+  return grub_register_command_prio (name, func, summary, description, 1);
+}
+
+static inline grub_command_t
+grub_command_find (const char *name)
+{
+  return grub_named_list_find (GRUB_AS_NAMED_LIST (grub_command_list), name);
+}
+
+static inline grub_err_t
+grub_command_execute (const char *name, int argc, char **argv)
+{
+  grub_command_t cmd;
+
+  cmd = grub_command_find (name);
+  return (cmd) ? cmd->func (cmd, argc, argv) : GRUB_ERR_FILE_NOT_FOUND;
+}
+
+static inline int
+grub_command_iterate (int (*func) (grub_command_t))
+{
+  return grub_list_iterate (GRUB_AS_LIST (grub_command_list),
+                           (grub_list_hook_t) func);
+}
+
+void grub_register_core_commands (void);
+
+#endif /* ! GRUB_COMMAND_HEADER */
diff --git a/grub-core/include/grub/crypto.h b/grub-core/include/grub/crypto.h
new file mode 100644 (file)
index 0000000..48b52ee
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
+ *                2007, 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Contains elements based on gcrypt-module.h and gcrypt.h.in.
+   If it's changed please update this file.  */
+
+#ifndef GRUB_CRYPTO_HEADER
+#define GRUB_CRYPTO_HEADER 1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/err.h>
+
+typedef enum 
+  {
+    GPG_ERR_NO_ERROR,
+    GPG_ERR_BAD_MPI,
+    GPG_ERR_BAD_SECKEY,
+    GPG_ERR_BAD_SIGNATURE,
+    GPG_ERR_CIPHER_ALGO,
+    GPG_ERR_CONFLICT,
+    GPG_ERR_DECRYPT_FAILED,
+    GPG_ERR_DIGEST_ALGO,
+    GPG_ERR_GENERAL,
+    GPG_ERR_INTERNAL,
+    GPG_ERR_INV_ARG,
+    GPG_ERR_INV_CIPHER_MODE,
+    GPG_ERR_INV_FLAG,
+    GPG_ERR_INV_KEYLEN,
+    GPG_ERR_INV_OBJ,
+    GPG_ERR_INV_OP,
+    GPG_ERR_INV_SEXP,
+    GPG_ERR_INV_VALUE,
+    GPG_ERR_MISSING_VALUE,
+    GPG_ERR_NO_ENCRYPTION_SCHEME,
+    GPG_ERR_NO_OBJ,
+    GPG_ERR_NO_PRIME,
+    GPG_ERR_NO_SIGNATURE_SCHEME,
+    GPG_ERR_NOT_FOUND,
+    GPG_ERR_NOT_IMPLEMENTED,
+    GPG_ERR_NOT_SUPPORTED,
+    GPG_ERROR_CFLAGS,
+    GPG_ERR_PUBKEY_ALGO,
+    GPG_ERR_SELFTEST_FAILED,
+    GPG_ERR_TOO_SHORT,
+    GPG_ERR_UNSUPPORTED,
+    GPG_ERR_WEAK_KEY,
+    GPG_ERR_WRONG_KEY_USAGE,
+    GPG_ERR_WRONG_PUBKEY_ALGO,
+    GPG_ERR_OUT_OF_MEMORY
+  } gcry_err_code_t;
+#define gpg_err_code_t gcry_err_code_t
+#define gpg_error_t gcry_err_code_t
+
+enum gcry_cipher_modes 
+  {
+    GCRY_CIPHER_MODE_NONE   = 0,  /* Not yet specified. */
+    GCRY_CIPHER_MODE_ECB    = 1,  /* Electronic codebook. */
+    GCRY_CIPHER_MODE_CFB    = 2,  /* Cipher feedback. */
+    GCRY_CIPHER_MODE_CBC    = 3,  /* Cipher block chaining. */
+    GCRY_CIPHER_MODE_STREAM = 4,  /* Used with stream ciphers. */
+    GCRY_CIPHER_MODE_OFB    = 5,  /* Outer feedback. */
+    GCRY_CIPHER_MODE_CTR    = 6   /* Counter. */
+  };
+
+/* Type for the cipher_setkey function.  */
+typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c,
+                                                const unsigned char *key,
+                                                unsigned keylen);
+
+/* Type for the cipher_encrypt function.  */
+typedef void (*gcry_cipher_encrypt_t) (void *c,
+                                      unsigned char *outbuf,
+                                      const unsigned char *inbuf);
+
+/* Type for the cipher_decrypt function.  */
+typedef void (*gcry_cipher_decrypt_t) (void *c,
+                                      unsigned char *outbuf,
+                                      const unsigned char *inbuf);
+
+/* Type for the cipher_stencrypt function.  */
+typedef void (*gcry_cipher_stencrypt_t) (void *c,
+                                        unsigned char *outbuf,
+                                        const unsigned char *inbuf,
+                                        unsigned int n);
+
+/* Type for the cipher_stdecrypt function.  */
+typedef void (*gcry_cipher_stdecrypt_t) (void *c,
+                                        unsigned char *outbuf,
+                                        const unsigned char *inbuf,
+                                        unsigned int n);
+
+typedef struct gcry_cipher_oid_spec
+{
+  const char *oid;
+  int mode;
+} gcry_cipher_oid_spec_t;
+
+/* Module specification structure for ciphers.  */
+typedef struct gcry_cipher_spec
+{
+  const char *name;
+  const char **aliases;
+  gcry_cipher_oid_spec_t *oids;
+  grub_size_t blocksize;
+  grub_size_t keylen;
+  grub_size_t contextsize;
+  gcry_cipher_setkey_t setkey;
+  gcry_cipher_encrypt_t encrypt;
+  gcry_cipher_decrypt_t decrypt;
+  gcry_cipher_stencrypt_t stencrypt;
+  gcry_cipher_stdecrypt_t stdecrypt;
+  struct gcry_cipher_spec *next;
+} gcry_cipher_spec_t;
+
+/* Type for the md_init function.  */
+typedef void (*gcry_md_init_t) (void *c);
+
+/* Type for the md_write function.  */
+typedef void (*gcry_md_write_t) (void *c, const void *buf, grub_size_t nbytes);
+
+/* Type for the md_final function.  */
+typedef void (*gcry_md_final_t) (void *c);
+
+/* Type for the md_read function.  */
+typedef unsigned char *(*gcry_md_read_t) (void *c);
+
+typedef struct gcry_md_oid_spec
+{
+  const char *oidstring;
+} gcry_md_oid_spec_t;
+
+/* Module specification structure for message digests.  */
+typedef struct gcry_md_spec
+{
+  const char *name;
+  unsigned char *asnoid;
+  int asnlen;
+  gcry_md_oid_spec_t *oids;
+  grub_size_t mdlen;
+  gcry_md_init_t init;
+  gcry_md_write_t write;
+  gcry_md_final_t final;
+  gcry_md_read_t read;
+  grub_size_t contextsize; /* allocate this amount of context */
+  /* Block size, needed for HMAC.  */
+  grub_size_t blocksize;
+  struct gcry_md_spec *next;
+} gcry_md_spec_t;
+
+struct grub_crypto_cipher_handle
+{
+  const struct gcry_cipher_spec *cipher;
+  char ctx[0];
+};
+
+typedef struct grub_crypto_cipher_handle *grub_crypto_cipher_handle_t;
+
+struct grub_crypto_hmac_handle;
+
+const gcry_cipher_spec_t *
+grub_crypto_lookup_cipher_by_name (const char *name);
+
+grub_crypto_cipher_handle_t
+grub_crypto_cipher_open (const struct gcry_cipher_spec *cipher);
+
+gcry_err_code_t
+grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher,
+                           const unsigned char *key,
+                           unsigned keylen);
+
+void
+grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher);
+
+void
+grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size);
+
+gcry_err_code_t
+grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
+                        void *out, void *in, grub_size_t size);
+
+gcry_err_code_t
+grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher,
+                        void *out, void *in, grub_size_t size);
+gcry_err_code_t
+grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher,
+                        void *out, void *in, grub_size_t size,
+                        void *iv_in);
+gcry_err_code_t
+grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher,
+                        void *out, void *in, grub_size_t size,
+                        void *iv);
+void 
+grub_cipher_register (gcry_cipher_spec_t *cipher);
+void
+grub_cipher_unregister (gcry_cipher_spec_t *cipher);
+void 
+grub_md_register (gcry_md_spec_t *digest);
+void 
+grub_md_unregister (gcry_md_spec_t *cipher);
+void
+grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in,
+                 grub_size_t inlen);
+const gcry_md_spec_t *
+grub_crypto_lookup_md_by_name (const char *name);
+
+grub_err_t
+grub_crypto_gcry_error (gcry_err_code_t in);
+
+void grub_burn_stack (grub_size_t size);
+
+struct grub_crypto_hmac_handle *
+grub_crypto_hmac_init (const struct gcry_md_spec *md,
+                      const void *key, grub_size_t keylen);
+void
+grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd, void *data,
+                       grub_size_t datalen);
+gcry_err_code_t
+grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out);
+
+gcry_err_code_t
+grub_crypto_hmac_buffer (const struct gcry_md_spec *md,
+                        const void *key, grub_size_t keylen,
+                        void *data, grub_size_t datalen, void *out);
+
+extern gcry_md_spec_t _gcry_digest_spec_md5;
+extern gcry_md_spec_t _gcry_digest_spec_sha1;
+extern gcry_md_spec_t _gcry_digest_spec_sha256;
+extern gcry_md_spec_t _gcry_digest_spec_sha512;
+#define GRUB_MD_MD5 ((const gcry_md_spec_t *) &_gcry_digest_spec_md5)
+#define GRUB_MD_SHA1 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha1)
+#define GRUB_MD_SHA256 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha256)
+#define GRUB_MD_SHA512 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha512)
+
+/* Implement PKCS#5 PBKDF2 as per RFC 2898.  The PRF to use is HMAC variant
+   of digest supplied by MD.  Inputs are the password P of length PLEN,
+   the salt S of length SLEN, the iteration counter C (> 0), and the
+   desired derived output length DKLEN.  Output buffer is DK which
+   must have room for at least DKLEN octets.  The output buffer will
+   be filled with the derived data.  */
+gcry_err_code_t
+grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
+                   const grub_uint8_t *P, grub_size_t Plen,
+                   const grub_uint8_t *S, grub_size_t Slen,
+                   unsigned int c,
+                   grub_uint8_t *DK, grub_size_t dkLen);
+
+int
+grub_crypto_memcmp (const void *a, const void *b, grub_size_t n);
+
+int
+grub_password_get (char buf[], unsigned buf_size);
+
+/* For indistinguishibility.  */
+#define GRUB_ACCESS_DENIED grub_error (GRUB_ERR_ACCESS_DENIED, "Access denied.")
+
+extern void (*grub_crypto_autoload_hook) (const char *name);
+
+#endif
diff --git a/grub-core/include/grub/datetime.h b/grub-core/include/grub/datetime.h
new file mode 100644 (file)
index 0000000..e721e89
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_DATETIME_HEADER
+#define KERNEL_DATETIME_HEADER 1
+
+#include <grub/types.h>
+#include <grub/err.h>
+
+struct grub_datetime
+{
+  grub_uint16_t year;
+  grub_uint8_t month;
+  grub_uint8_t day;
+  grub_uint8_t hour;
+  grub_uint8_t minute;
+  grub_uint8_t second;
+};
+
+/* Return date and time.  */
+#ifdef GRUB_MACHINE_EMU
+grub_err_t EXPORT_FUNC(grub_get_datetime) (struct grub_datetime *datetime);
+
+/* Set date and time.  */
+grub_err_t EXPORT_FUNC(grub_set_datetime) (struct grub_datetime *datetime);
+#else
+grub_err_t grub_get_datetime (struct grub_datetime *datetime);
+
+/* Set date and time.  */
+grub_err_t grub_set_datetime (struct grub_datetime *datetime);
+#endif
+
+int grub_get_weekday (struct grub_datetime *datetime);
+char *grub_get_weekday_name (struct grub_datetime *datetime);
+
+void grub_unixtime2datetime (grub_int32_t nix,
+                            struct grub_datetime *datetime);
+
+
+#endif /* ! KERNEL_DATETIME_HEADER */
diff --git a/grub-core/include/grub/device.h b/grub-core/include/grub/device.h
new file mode 100644 (file)
index 0000000..f0e8a8c
--- /dev/null
@@ -0,0 +1,41 @@
+/* device.h - device manager */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_DEVICE_HEADER
+#define GRUB_DEVICE_HEADER     1
+
+#include <grub/symbol.h>
+#include <grub/err.h>
+
+struct grub_disk;
+struct grub_net;
+struct grub_fs;
+
+struct grub_device
+{
+  struct grub_disk *disk;
+  struct grub_net *net;
+};
+typedef struct grub_device *grub_device_t;
+
+grub_device_t EXPORT_FUNC(grub_device_open) (const char *name);
+grub_err_t EXPORT_FUNC(grub_device_close) (grub_device_t device);
+int EXPORT_FUNC(grub_device_iterate) (int (*hook) (const char *name));
+
+#endif /* ! GRUB_DEVICE_HEADER */
diff --git a/grub-core/include/grub/disk.h b/grub-core/include/grub/disk.h
new file mode 100644 (file)
index 0000000..e60b1f3
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_DISK_HEADER
+#define GRUB_DISK_HEADER       1
+
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/device.h>
+
+/* These are used to set a device id. When you add a new disk device,
+   you must define a new id for it here.  */
+enum grub_disk_dev_id
+  {
+    GRUB_DISK_DEVICE_BIOSDISK_ID,
+    GRUB_DISK_DEVICE_OFDISK_ID,
+    GRUB_DISK_DEVICE_LOOPBACK_ID,
+    GRUB_DISK_DEVICE_EFIDISK_ID,
+    GRUB_DISK_DEVICE_RAID_ID,
+    GRUB_DISK_DEVICE_LVM_ID,
+    GRUB_DISK_DEVICE_HOST_ID,
+    GRUB_DISK_DEVICE_ATA_ID,
+    GRUB_DISK_DEVICE_MEMDISK_ID,
+    GRUB_DISK_DEVICE_NAND_ID,
+    GRUB_DISK_DEVICE_UUID_ID,
+    GRUB_DISK_DEVICE_PXE_ID,
+    GRUB_DISK_DEVICE_SCSI_ID,
+    GRUB_DISK_DEVICE_FILE_ID,
+    GRUB_DISK_DEVICE_LUKS_ID
+  };
+
+struct grub_disk;
+#ifdef GRUB_UTIL
+struct grub_disk_memberlist;
+#endif
+
+/* Disk device.  */
+struct grub_disk_dev
+{
+  /* The device name.  */
+  const char *name;
+
+  /* The device id used by the cache manager.  */
+  enum grub_disk_dev_id id;
+
+  /* Call HOOK with each device name, until HOOK returns non-zero.  */
+  int (*iterate) (int (*hook) (const char *name));
+
+  /* Open the device named NAME, and set up DISK.  */
+  grub_err_t (*open) (const char *name, struct grub_disk *disk);
+
+  /* Close the disk DISK.  */
+  void (*close) (struct grub_disk *disk);
+
+  /* Read SIZE sectors from the sector SECTOR of the disk DISK into BUF.  */
+  grub_err_t (*read) (struct grub_disk *disk, grub_disk_addr_t sector,
+                     grub_size_t size, char *buf);
+
+  /* Write SIZE sectors from BUF into the sector SECTOR of the disk DISK.  */
+  grub_err_t (*write) (struct grub_disk *disk, grub_disk_addr_t sector,
+                      grub_size_t size, const char *buf);
+
+#ifdef GRUB_UTIL
+  struct grub_disk_memberlist *(*memberlist) (struct grub_disk *disk);
+#endif
+
+  /* The next disk device.  */
+  struct grub_disk_dev *next;
+};
+typedef struct grub_disk_dev *grub_disk_dev_t;
+
+struct grub_partition;
+
+/* Disk.  */
+struct grub_disk
+{
+  /* The disk name.  */
+  const char *name;
+
+  /* The underlying disk device.  */
+  grub_disk_dev_t dev;
+
+  /* The total number of sectors.  */
+  grub_uint64_t total_sectors;
+
+  /* If partitions can be stored.  */
+  int has_partitions;
+
+  /* The id used by the disk cache manager.  */
+  unsigned long id;
+
+  /* The partition information. This is machine-specific.  */
+  struct grub_partition *partition;
+
+  /* Called when a sector was read. OFFSET is between 0 and
+     the sector size minus 1, and LENGTH is between 0 and the sector size.  */
+  void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                    unsigned offset, unsigned length);
+
+  /* Device-specific data.  */
+  void *data;
+};
+typedef struct grub_disk *grub_disk_t;
+
+#ifdef GRUB_UTIL
+struct grub_disk_memberlist
+{
+  grub_disk_t disk;
+  struct grub_disk_memberlist *next;
+};
+typedef struct grub_disk_memberlist *grub_disk_memberlist_t;
+#endif
+
+/* The sector size.  */
+#define GRUB_DISK_SECTOR_SIZE  0x200
+#define GRUB_DISK_SECTOR_BITS  9
+
+/* The maximum number of disk caches.  */
+#define GRUB_DISK_CACHE_NUM    1021
+
+/* The size of a disk cache in sector units.  */
+#define GRUB_DISK_CACHE_SIZE   8
+#define GRUB_DISK_CACHE_BITS   3
+
+/* This is called from the memory manager.  */
+void grub_disk_cache_invalidate_all (void);
+
+void EXPORT_FUNC(grub_disk_dev_register) (grub_disk_dev_t dev);
+void EXPORT_FUNC(grub_disk_dev_unregister) (grub_disk_dev_t dev);
+int EXPORT_FUNC(grub_disk_dev_iterate) (int (*hook) (const char *name));
+
+grub_disk_t EXPORT_FUNC(grub_disk_open) (const char *name);
+void EXPORT_FUNC(grub_disk_close) (grub_disk_t disk);
+grub_err_t EXPORT_FUNC(grub_disk_read) (grub_disk_t disk,
+                                       grub_disk_addr_t sector,
+                                       grub_off_t offset,
+                                       grub_size_t size,
+                                       void *buf);
+grub_err_t EXPORT_FUNC(grub_disk_write) (grub_disk_t disk,
+                                        grub_disk_addr_t sector,
+                                        grub_off_t offset,
+                                        grub_size_t size,
+                                        const void *buf);
+
+grub_uint64_t EXPORT_FUNC(grub_disk_get_size) (grub_disk_t disk);
+
+extern void (* EXPORT_VAR(grub_disk_firmware_fini)) (void);
+extern int EXPORT_VAR(grub_disk_firmware_is_tainted);
+
+/* ATA pass through parameters and function.  */
+struct grub_disk_ata_pass_through_parms
+{
+  grub_uint8_t taskfile[8];
+  void * buffer;
+  int size;
+};
+
+extern grub_err_t (* EXPORT_VAR(grub_disk_ata_pass_through)) (grub_disk_t,
+                  struct grub_disk_ata_pass_through_parms *);
+
+#endif /* ! GRUB_DISK_HEADER */
diff --git a/grub-core/include/grub/dl.h b/grub-core/include/grub/dl.h
new file mode 100644 (file)
index 0000000..f98539a
--- /dev/null
@@ -0,0 +1,119 @@
+/* dl.h - types and prototypes for loadable module support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_DL_H
+#define GRUB_DL_H      1
+
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/elf.h>
+
+/*
+ * Macros GRUB_MOD_INIT and GRUB_MOD_FINI are also used by build rules
+ * to collect module names, so we define them only when they are not
+ * defined already.
+ */
+
+#ifndef GRUB_MOD_INIT
+#define GRUB_MOD_INIT(name)    \
+static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
+void grub_##name##_init (void); \
+void \
+grub_##name##_init (void) { grub_mod_init (0); } \
+static void \
+grub_mod_init (grub_dl_t mod __attribute__ ((unused)))
+#endif
+
+#ifndef GRUB_MOD_FINI
+#define GRUB_MOD_FINI(name)    \
+static void grub_mod_fini (void) __attribute__ ((used)); \
+void grub_##name##_fini (void); \
+void \
+grub_##name##_fini (void) { grub_mod_fini (); } \
+static void \
+grub_mod_fini (void)
+#endif
+
+#ifdef APPLE_CC
+#define GRUB_MOD_NAME(name)    \
+static char grub_modname[] __attribute__ ((section ("_modname, _modname"), used)) = #name;
+
+#define GRUB_MOD_DEP(name)     \
+__asm__ (".section _moddeps, _moddeps\n.asciz \"" #name "\"\n")
+#else
+#define GRUB_MOD_NAME(name)    \
+__asm__ (".section .modname\n.asciz \"" #name "\"\n")
+
+#define GRUB_MOD_DEP(name)     \
+__asm__ (".section .moddeps\n.asciz \"" #name "\"\n")
+#endif
+
+struct grub_dl_segment
+{
+  struct grub_dl_segment *next;
+  void *addr;
+  grub_size_t size;
+  unsigned section;
+};
+typedef struct grub_dl_segment *grub_dl_segment_t;
+
+struct grub_dl;
+
+struct grub_dl_dep
+{
+  struct grub_dl_dep *next;
+  struct grub_dl *mod;
+};
+typedef struct grub_dl_dep *grub_dl_dep_t;
+
+struct grub_dl
+{
+  char *name;
+  int ref_count;
+  grub_dl_dep_t dep;
+  grub_dl_segment_t segment;
+  Elf_Sym *symtab;
+  void (*init) (struct grub_dl *mod);
+  void (*fini) (void);
+};
+typedef struct grub_dl *grub_dl_t;
+
+grub_dl_t EXPORT_FUNC(grub_dl_load_file) (const char *filename);
+grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name);
+grub_dl_t grub_dl_load_core (void *addr, grub_size_t size);
+int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod);
+void grub_dl_unload_unneeded (void);
+void grub_dl_unload_all (void);
+int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod);
+int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod);
+void EXPORT_FUNC(grub_dl_iterate) (int (*hook) (grub_dl_t mod));
+grub_dl_t EXPORT_FUNC(grub_dl_get) (const char *name);
+grub_err_t grub_dl_register_symbol (const char *name, void *addr,
+                                   grub_dl_t mod);
+
+grub_err_t grub_arch_dl_check_header (void *ehdr);
+grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr);
+
+#if defined (_mips)
+#define GRUB_LINKER_HAVE_INIT 1
+void grub_arch_dl_init_linker (void);
+#endif
+
+#endif /* ! GRUB_DL_H */
diff --git a/grub-core/include/grub/efi/api.h b/grub-core/include/grub/efi/api.h
new file mode 100644 (file)
index 0000000..36363ae
--- /dev/null
@@ -0,0 +1,1191 @@
+/* efi.h - declare EFI types and functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_API_HEADER
+#define GRUB_EFI_API_HEADER    1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+/* For consistency and safety, we name the EFI-defined types differently.
+   All names are transformed into lower case, _t appended, and
+   grub_efi_ prepended.  */
+
+/* Constants.  */
+#define GRUB_EFI_EVT_TIMER                             0x80000000
+#define GRUB_EFI_EVT_RUNTIME                           0x40000000
+#define GRUB_EFI_EVT_RUNTIME_CONTEXT                   0x20000000
+#define GRUB_EFI_EVT_NOTIFY_WAIT                       0x00000100
+#define GRUB_EFI_EVT_NOTIFY_SIGNAL                     0x00000200
+#define GRUB_EFI_EVT_SIGNAL_EXIT_BOOT_SERVICES         0x00000201
+#define GRUB_EFI_EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE     0x60000202
+
+#define GRUB_EFI_TPL_APPLICATION       4
+#define GRUB_EFI_TPL_CALLBACK          8
+#define GRUB_EFI_TPL_NOTIFY            16
+#define GRUB_EFI_TPL_HIGH_LEVEL                31
+
+#define GRUB_EFI_MEMORY_UC     0x0000000000000001LL
+#define GRUB_EFI_MEMORY_WC     0x0000000000000002LL
+#define GRUB_EFI_MEMORY_WT     0x0000000000000004LL
+#define GRUB_EFI_MEMORY_WB     0x0000000000000008LL
+#define GRUB_EFI_MEMORY_UCE    0x0000000000000010LL
+#define GRUB_EFI_MEMORY_WP     0x0000000000001000LL
+#define GRUB_EFI_MEMORY_RP     0x0000000000002000LL
+#define GRUB_EFI_MEMORY_XP     0x0000000000004000LL
+#define GRUB_EFI_MEMORY_RUNTIME        0x8000000000000000LL
+
+#define GRUB_EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL      0x00000001
+#define GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL            0x00000002
+#define GRUB_EFI_OPEN_PROTOCOL_TEST_PROTOCOL           0x00000004
+#define GRUB_EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER     0x00000008
+#define GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER               0x00000010
+#define GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE            0x00000020
+
+#define GRUB_EFI_VARIABLE_NON_VOLATILE         0x0000000000000001
+#define GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS   0x0000000000000002
+#define GRUB_EFI_VARIABLE_RUNTIME_ACCESS       0x0000000000000004
+
+#define GRUB_EFI_TIME_ADJUST_DAYLIGHT  0x01
+#define GRUB_EFI_TIME_IN_DAYLIGHT      0x02
+
+#define GRUB_EFI_UNSPECIFIED_TIMEZONE  0x07FF
+
+#define GRUB_EFI_OPTIONAL_PTR  0x00000001
+
+#define GRUB_EFI_LOADED_IMAGE_GUID     \
+  { 0x5b1b31a1, 0x9562, 0x11d2, \
+    { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+#define GRUB_EFI_DISK_IO_GUID  \
+  { 0xce345171, 0xba0b, 0x11d2, \
+    { 0x8e, 0x4f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+#define GRUB_EFI_BLOCK_IO_GUID \
+  { 0x964e5b21, 0x6459, 0x11d2, \
+    { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+#define GRUB_EFI_DEVICE_PATH_GUID      \
+  { 0x09576e91, 0x6d3f, 0x11d2, \
+    { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
+  }
+
+#define GRUB_EFI_MPS_TABLE_GUID        \
+  { 0xeb9d2d2f, 0x2d88, 0x11d3, \
+    { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+  }
+
+#define GRUB_EFI_ACPI_TABLE_GUID       \
+  { 0xeb9d2d30, 0x2d88, 0x11d3, \
+    { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+  }
+
+#define GRUB_EFI_ACPI_20_TABLE_GUID    \
+  { 0x8868e871, 0xe4f1, 0x11d3, \
+    { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
+  }
+
+#define GRUB_EFI_SMBIOS_TABLE_GUID     \
+  { 0xeb9d2d31, 0x2d88, 0x11d3, \
+    { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+  }
+
+/* Enumerations.  */
+enum grub_efi_timer_delay
+  {
+    GRUB_EFI_TIMER_CANCEL,
+    GRUB_EFI_TIMER_PERIODIC,
+    GRUB_EFI_TIMER_RELATIVE
+  };
+typedef enum grub_efi_timer_delay grub_efi_timer_delay_t;
+
+enum grub_efi_allocate_type
+  {
+    GRUB_EFI_ALLOCATE_ANY_PAGES,
+    GRUB_EFI_ALLOCATE_MAX_ADDRESS,
+    GRUB_EFI_ALLOCATE_ADDRESS,
+    GRUB_EFI_MAX_ALLOCATION_TYPE
+  };
+typedef enum grub_efi_allocate_type grub_efi_allocate_type_t;
+
+enum grub_efi_memory_type
+  {
+    GRUB_EFI_RESERVED_MEMORY_TYPE,
+    GRUB_EFI_LOADER_CODE,
+    GRUB_EFI_LOADER_DATA,
+    GRUB_EFI_BOOT_SERVICES_CODE,
+    GRUB_EFI_BOOT_SERVICES_DATA,
+    GRUB_EFI_RUNTIME_SERVICES_CODE,
+    GRUB_EFI_RUNTIME_SERVICES_DATA,
+    GRUB_EFI_CONVENTIONAL_MEMORY,
+    GRUB_EFI_UNUSABLE_MEMORY,
+    GRUB_EFI_ACPI_RECLAIM_MEMORY,
+    GRUB_EFI_ACPI_MEMORY_NVS,
+    GRUB_EFI_MEMORY_MAPPED_IO,
+    GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE,
+    GRUB_EFI_PAL_CODE,
+    GRUB_EFI_MAX_MEMORY_TYPE
+  };
+typedef enum grub_efi_memory_type grub_efi_memory_type_t;
+
+enum grub_efi_interface_type
+  {
+    GRUB_EFI_NATIVE_INTERFACE
+  };
+typedef enum grub_efi_interface_type grub_efi_interface_type_t;
+
+enum grub_efi_locate_search_type
+  {
+    GRUB_EFI_ALL_HANDLES,
+    GRUB_EFI_BY_REGISTER_NOTIFY,
+    GRUB_EFI_BY_PROTOCOL
+  };
+typedef enum grub_efi_locate_search_type grub_efi_locate_search_type_t;
+
+enum grub_efi_reset_type
+  {
+    GRUB_EFI_RESET_COLD,
+    GRUB_EFI_RESET_WARM,
+    GRUB_EFI_RESET_SHUTDOWN
+  };
+typedef enum grub_efi_reset_type grub_efi_reset_type_t;
+
+/* Types.  */
+typedef char grub_efi_boolean_t;
+typedef long grub_efi_intn_t;
+typedef unsigned long grub_efi_uintn_t;
+typedef grub_int8_t grub_efi_int8_t;
+typedef grub_uint8_t grub_efi_uint8_t;
+typedef grub_int16_t grub_efi_int16_t;
+typedef grub_uint16_t grub_efi_uint16_t;
+typedef grub_int32_t grub_efi_int32_t;
+typedef grub_uint32_t grub_efi_uint32_t;
+typedef grub_int64_t grub_efi_int64_t;
+typedef grub_uint64_t grub_efi_uint64_t;
+typedef grub_uint8_t grub_efi_char8_t;
+typedef grub_uint16_t grub_efi_char16_t;
+
+typedef grub_efi_intn_t grub_efi_status_t;
+
+#define GRUB_EFI_ERROR_CODE(value)     \
+  ((1L << (sizeof (grub_efi_status_t) * 8 - 1)) | (value))
+
+#define GRUB_EFI_WARNING_CODE(value)   (value)
+
+#define GRUB_EFI_SUCCESS               0
+
+#define GRUB_EFI_LOAD_ERROR            GRUB_EFI_ERROR_CODE (1)
+#define GRUB_EFI_INVALID_PARAMETER     GRUB_EFI_ERROR_CODE (2)
+#define GRUB_EFI_UNSUPPORTED           GRUB_EFI_ERROR_CODE (3)
+#define GRUB_EFI_BAD_BUFFER_SIZE       GRUB_EFI_ERROR_CODE (4)
+#define GRUB_EFI_BUFFER_TOO_SMALL      GRUB_EFI_ERROR_CODE (5)
+#define GRUB_EFI_NOT_READY             GRUB_EFI_ERROR_CODE (6)
+#define GRUB_EFI_DEVICE_ERROR          GRUB_EFI_ERROR_CODE (7)
+#define GRUB_EFI_WRITE_PROTECTED       GRUB_EFI_ERROR_CODE (8)
+#define GRUB_EFI_OUT_OF_RESOURCES      GRUB_EFI_ERROR_CODE (9)
+#define GRUB_EFI_VOLUME_CORRUPTED      GRUB_EFI_ERROR_CODE (10)
+#define GRUB_EFI_VOLUME_FULL           GRUB_EFI_ERROR_CODE (11)
+#define GRUB_EFI_NO_MEDIA              GRUB_EFI_ERROR_CODE (12)
+#define GRUB_EFI_MEDIA_CHANGED         GRUB_EFI_ERROR_CODE (13)
+#define GRUB_EFI_NOT_FOUND             GRUB_EFI_ERROR_CODE (14)
+#define GRUB_EFI_ACCESS_DENIED         GRUB_EFI_ERROR_CODE (15)
+#define GRUB_EFI_NO_RESPONSE           GRUB_EFI_ERROR_CODE (16)
+#define GRUB_EFI_NO_MAPPING            GRUB_EFI_ERROR_CODE (17)
+#define GRUB_EFI_TIMEOUT               GRUB_EFI_ERROR_CODE (18)
+#define GRUB_EFI_NOT_STARTED           GRUB_EFI_ERROR_CODE (19)
+#define GRUB_EFI_ALREADY_STARTED       GRUB_EFI_ERROR_CODE (20)
+#define GRUB_EFI_ABORTED               GRUB_EFI_ERROR_CODE (21)
+#define GRUB_EFI_ICMP_ERROR            GRUB_EFI_ERROR_CODE (22)
+#define GRUB_EFI_TFTP_ERROR            GRUB_EFI_ERROR_CODE (23)
+#define GRUB_EFI_PROTOCOL_ERROR                GRUB_EFI_ERROR_CODE (24)
+#define GRUB_EFI_INCOMPATIBLE_VERSION  GRUB_EFI_ERROR_CODE (25)
+#define GRUB_EFI_SECURITY_VIOLATION    GRUB_EFI_ERROR_CODE (26)
+#define GRUB_EFI_CRC_ERROR             GRUB_EFI_ERROR_CODE (27)
+
+#define GRUB_EFI_WARN_UNKNOWN_GLYPH    GRUB_EFI_WARNING_CODE (1)
+#define GRUB_EFI_WARN_DELETE_FAILURE   GRUB_EFI_WARNING_CODE (2)
+#define GRUB_EFI_WARN_WRITE_FAILURE    GRUB_EFI_WARNING_CODE (3)
+#define GRUB_EFI_WARN_BUFFER_TOO_SMALL GRUB_EFI_WARNING_CODE (4)
+
+typedef void *grub_efi_handle_t;
+typedef void *grub_efi_event_t;
+typedef grub_efi_uint64_t grub_efi_lba_t;
+typedef grub_efi_uintn_t grub_efi_tpl_t;
+typedef grub_uint8_t grub_efi_mac_address_t[32];
+typedef grub_uint8_t grub_efi_ipv4_address_t[4];
+typedef grub_uint16_t grub_efi_ipv6_address_t[8];
+typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4)));
+typedef grub_efi_uint64_t grub_efi_physical_address_t;
+typedef grub_efi_uint64_t grub_efi_virtual_address_t;
+
+struct grub_efi_guid
+{
+  grub_uint32_t data1;
+  grub_uint16_t data2;
+  grub_uint16_t data3;
+  grub_uint8_t data4[8];
+} __attribute__ ((aligned(8)));
+typedef struct grub_efi_guid grub_efi_guid_t;
+
+/* XXX although the spec does not specify the padding, this actually
+   must have the padding!  */
+struct grub_efi_memory_descriptor
+{
+  grub_efi_uint32_t type;
+  grub_efi_uint32_t padding;
+  grub_efi_physical_address_t physical_start;
+  grub_efi_virtual_address_t virtual_start;
+  grub_efi_uint64_t num_pages;
+  grub_efi_uint64_t attribute;
+};
+typedef struct grub_efi_memory_descriptor grub_efi_memory_descriptor_t;
+
+/* Device Path definitions.  */
+struct grub_efi_device_path
+{
+  grub_efi_uint8_t type;
+  grub_efi_uint8_t subtype;
+  grub_efi_uint8_t length[2];
+};
+typedef struct grub_efi_device_path grub_efi_device_path_t;
+/* XXX EFI does not define EFI_DEVICE_PATH_PROTOCOL but uses it.
+   It seems to be identical to EFI_DEVICE_PATH.  */
+typedef struct grub_efi_device_path grub_efi_device_path_protocol_t;
+
+#define GRUB_EFI_DEVICE_PATH_TYPE(dp)          ((dp)->type & 0x7f)
+#define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp)       ((dp)->subtype)
+#define GRUB_EFI_DEVICE_PATH_LENGTH(dp)                \
+  ((dp)->length[0] | ((grub_efi_uint16_t) ((dp)->length[1]) << 8))
+
+/* The End of Device Path nodes.  */
+#define GRUB_EFI_END_DEVICE_PATH_TYPE                  (0xff & 0x7f)
+
+#define GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE                0xff
+#define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE          0x01
+
+#define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp)    \
+  (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
+   && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
+       == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE))
+
+#define GRUB_EFI_NEXT_DEVICE_PATH(dp)  \
+  ((grub_efi_device_path_t *) ((char *) (dp) \
+                               + GRUB_EFI_DEVICE_PATH_LENGTH (dp)))
+
+/* Hardware Device Path.  */
+#define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE             1
+
+#define GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE               1
+
+struct grub_efi_pci_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint8_t function;
+  grub_efi_uint8_t device;
+};
+typedef struct grub_efi_pci_device_path grub_efi_pci_device_path_t;
+
+#define GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE            2
+
+struct grub_efi_pccard_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint8_t function;
+};
+typedef struct grub_efi_pccard_device_path grub_efi_pccard_device_path_t;
+
+#define GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE     3
+
+struct grub_efi_memory_mapped_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_memory_type_t memory_type;
+  grub_efi_physical_address_t start_address;
+  grub_efi_physical_address_t end_address;
+};
+typedef struct grub_efi_memory_mapped_device_path grub_efi_memory_mapped_device_path_t;
+
+#define GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE            4
+
+struct grub_efi_vendor_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_guid_t vendor_guid;
+  grub_efi_uint8_t vendor_defined_data[0];
+};
+typedef struct grub_efi_vendor_device_path grub_efi_vendor_device_path_t;
+
+#define GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE                5
+
+struct grub_efi_controller_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t controller_number;
+};
+typedef struct grub_efi_controller_device_path grub_efi_controller_device_path_t;
+
+/* ACPI Device Path.  */
+#define GRUB_EFI_ACPI_DEVICE_PATH_TYPE                 2
+
+#define GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE              1
+
+struct grub_efi_acpi_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t hid;
+  grub_efi_uint32_t uid;
+};
+typedef struct grub_efi_acpi_device_path grub_efi_acpi_device_path_t;
+
+#define GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE     2
+
+struct grub_efi_expanded_acpi_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t hid;
+  grub_efi_uint32_t uid;
+  grub_efi_uint32_t cid;
+  char hidstr[1];
+};
+typedef struct grub_efi_expanded_acpi_device_path grub_efi_expanded_acpi_device_path_t;
+
+#define GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp)      \
+  (((grub_efi_expanded_acpi_device_path_t *) dp)->hidstr)
+#define GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp)      \
+  (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \
+   + grub_strlen (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp)) + 1)
+#define GRUB_EFI_EXPANDED_ACPI_CIDSTR(dp)      \
+  (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp) \
+   + grub_strlen (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp)) + 1)
+
+/* Messaging Device Path.  */
+#define GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE            3
+
+#define GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE             1
+
+struct grub_efi_atapi_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint8_t primary_secondary;
+  grub_efi_uint8_t slave_master;
+  grub_efi_uint16_t lun;
+};
+typedef struct grub_efi_atapi_device_path grub_efi_atapi_device_path_t;
+
+#define GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE              2
+
+struct grub_efi_scsi_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint16_t pun;
+  grub_efi_uint16_t lun;
+};
+typedef struct grub_efi_scsi_device_path grub_efi_scsi_device_path_t;
+
+#define GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE     3
+
+struct grub_efi_fibre_channel_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t reserved;
+  grub_efi_uint64_t wwn;
+  grub_efi_uint64_t lun;
+};
+typedef struct grub_efi_fibre_channel_device_path grub_efi_fibre_channel_device_path_t;
+
+#define GRUB_EFI_1394_DEVICE_PATH_SUBTYPE              4
+
+struct grub_efi_1394_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t reserved;
+  grub_efi_uint64_t guid;
+};
+typedef struct grub_efi_1394_device_path grub_efi_1394_device_path_t;
+
+#define GRUB_EFI_USB_DEVICE_PATH_SUBTYPE               5
+
+struct grub_efi_usb_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint8_t parent_port_number;
+  grub_efi_uint8_t interface;
+};
+typedef struct grub_efi_usb_device_path grub_efi_usb_device_path_t;
+
+#define GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE         15
+
+struct grub_efi_usb_class_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint16_t vendor_id;
+  grub_efi_uint16_t product_id;
+  grub_efi_uint8_t device_class;
+  grub_efi_uint8_t device_subclass;
+  grub_efi_uint8_t device_protocol;
+};
+typedef struct grub_efi_usb_class_device_path grub_efi_usb_class_device_path_t;
+
+#define GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE               6
+
+struct grub_efi_i2o_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t tid;
+};
+typedef struct grub_efi_i2o_device_path grub_efi_i2o_device_path_t;
+
+#define GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE       11
+
+struct grub_efi_mac_address_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_mac_address_t mac_address;
+  grub_efi_uint8_t if_type;
+};
+typedef struct grub_efi_mac_address_device_path grub_efi_mac_address_device_path_t;
+
+#define GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE              12
+
+struct grub_efi_ipv4_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_ipv4_address_t local_ip_address;
+  grub_efi_ipv4_address_t remote_ip_address;
+  grub_efi_uint16_t local_port;
+  grub_efi_uint16_t remote_port;
+  grub_efi_uint16_t protocol;
+  grub_efi_uint8_t static_ip_address;
+};
+typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t;
+
+#define GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE              13
+
+struct grub_efi_ipv6_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_ipv6_address_t local_ip_address;
+  grub_efi_ipv6_address_t remote_ip_address;
+  grub_efi_uint16_t local_port;
+  grub_efi_uint16_t remote_port;
+  grub_efi_uint16_t protocol;
+  grub_efi_uint8_t static_ip_address;
+};
+typedef struct grub_efi_ipv6_device_path grub_efi_ipv6_device_path_t;
+
+#define GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE                9
+
+struct grub_efi_infiniband_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t resource_flags;
+  grub_efi_uint8_t port_gid[16];
+  grub_efi_uint64_t remote_id;
+  grub_efi_uint64_t target_port_id;
+  grub_efi_uint64_t device_id;
+};
+typedef struct grub_efi_infiniband_device_path grub_efi_infiniband_device_path_t;
+
+#define GRUB_EFI_UART_DEVICE_PATH_SUBTYPE              14
+
+struct grub_efi_uart_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t reserved;
+  grub_efi_uint64_t baud_rate;
+  grub_efi_uint8_t data_bits;
+  grub_efi_uint8_t parity;
+  grub_efi_uint8_t stop_bits;
+};
+typedef struct grub_efi_uart_device_path grub_efi_uart_device_path_t;
+
+#define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE  10
+
+struct grub_efi_vendor_messaging_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_guid_t vendor_guid;
+  grub_efi_uint8_t vendor_defined_data[0];
+};
+typedef struct grub_efi_vendor_messaging_device_path grub_efi_vendor_messaging_device_path_t;
+
+/* Media Device Path.  */
+#define GRUB_EFI_MEDIA_DEVICE_PATH_TYPE                        4
+
+#define GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE                1
+
+struct grub_efi_hard_drive_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t partition_number;
+  grub_efi_lba_t partition_start;
+  grub_efi_lba_t partition_size;
+  grub_efi_uint8_t partition_signature[8];
+  grub_efi_uint8_t mbr_type;
+  grub_efi_uint8_t signature_type;
+};
+typedef struct grub_efi_hard_drive_device_path grub_efi_hard_drive_device_path_t;
+
+#define GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE             2
+
+struct grub_efi_cdrom_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint32_t boot_entry;
+  grub_efi_lba_t partition_start;
+  grub_efi_lba_t partition_size;
+};
+typedef struct grub_efi_cdrom_device_path grub_efi_cdrom_device_path_t;
+
+#define GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE      3
+
+struct grub_efi_vendor_media_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_guid_t vendor_guid;
+  grub_efi_uint8_t vendor_defined_data[0];
+};
+typedef struct grub_efi_vendor_media_device_path grub_efi_vendor_media_device_path_t;
+
+#define GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE         4
+
+struct grub_efi_file_path_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_char16_t path_name[0];
+};
+typedef struct grub_efi_file_path_device_path grub_efi_file_path_device_path_t;
+
+#define GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE          5
+
+struct grub_efi_protocol_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_guid_t guid;
+};
+typedef struct grub_efi_protocol_device_path grub_efi_protocol_device_path_t;
+
+#define GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE              6
+
+struct grub_efi_piwg_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_guid_t guid __attribute__ ((packed));
+};
+typedef struct grub_efi_piwg_device_path grub_efi_piwg_device_path_t;
+
+
+/* BIOS Boot Specification Device Path.  */
+#define GRUB_EFI_BIOS_DEVICE_PATH_TYPE                 5
+
+#define GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE              1
+
+struct grub_efi_bios_device_path
+{
+  grub_efi_device_path_t header;
+  grub_efi_uint16_t device_type;
+  grub_efi_uint16_t status_flags;
+  char description[0];
+};
+typedef struct grub_efi_bios_device_path grub_efi_bios_device_path_t;
+
+struct grub_efi_open_protocol_information_entry
+{
+  grub_efi_handle_t agent_handle;
+  grub_efi_handle_t controller_handle;
+  grub_efi_uint32_t attributes;
+  grub_efi_uint32_t open_count;
+};
+typedef struct grub_efi_open_protocol_information_entry grub_efi_open_protocol_information_entry_t;
+
+struct grub_efi_time
+{
+  grub_efi_uint16_t year;
+  grub_efi_uint8_t month;
+  grub_efi_uint8_t day;
+  grub_efi_uint8_t hour;
+  grub_efi_uint8_t minute;
+  grub_efi_uint8_t second;
+  grub_efi_uint8_t pad1;
+  grub_efi_uint32_t nanosecond;
+  grub_efi_int16_t time_zone;
+  grub_efi_uint8_t daylight;
+  grub_efi_uint8_t pad2;
+} __attribute__ ((packed));
+typedef struct grub_efi_time grub_efi_time_t;
+
+struct grub_efi_time_capabilities
+{
+  grub_efi_uint32_t resolution;
+  grub_efi_uint32_t accuracy;
+  grub_efi_boolean_t sets_to_zero;
+};
+typedef struct grub_efi_time_capabilities grub_efi_time_capabilities_t;
+
+struct grub_efi_input_key
+{
+  grub_efi_uint16_t scan_code;
+  grub_efi_char16_t unicode_char;
+};
+typedef struct grub_efi_input_key grub_efi_input_key_t;
+
+struct grub_efi_simple_text_output_mode
+{
+  grub_efi_int32_t max_mode;
+  grub_efi_int32_t mode;
+  grub_efi_int32_t attribute;
+  grub_efi_int32_t cursor_column;
+  grub_efi_int32_t cursor_row;
+  grub_efi_boolean_t cursor_visible;
+};
+typedef struct grub_efi_simple_text_output_mode grub_efi_simple_text_output_mode_t;
+
+/* Tables.  */
+struct grub_efi_table_header
+{
+  grub_efi_uint64_t signature;
+  grub_efi_uint32_t revision;
+  grub_efi_uint32_t header_size;
+  grub_efi_uint32_t crc32;
+  grub_efi_uint32_t reserved;
+};
+typedef struct grub_efi_table_header grub_efi_table_header_t;
+
+struct grub_efi_boot_services
+{
+  grub_efi_table_header_t hdr;
+
+  grub_efi_tpl_t
+  (*raise_tpl) (grub_efi_tpl_t new_tpl);
+
+  void
+  (*restore_tpl) (grub_efi_tpl_t old_tpl);
+
+  grub_efi_status_t
+  (*allocate_pages) (grub_efi_allocate_type_t type,
+                    grub_efi_memory_type_t memory_type,
+                    grub_efi_uintn_t pages,
+                    grub_efi_physical_address_t *memory);
+
+  grub_efi_status_t
+  (*free_pages) (grub_efi_physical_address_t memory,
+                grub_efi_uintn_t pages);
+
+  grub_efi_status_t
+  (*get_memory_map) (grub_efi_uintn_t *memory_map_size,
+                    grub_efi_memory_descriptor_t *memory_map,
+                    grub_efi_uintn_t *map_key,
+                    grub_efi_uintn_t *descriptor_size,
+                    grub_efi_uint32_t *descriptor_version);
+
+  grub_efi_status_t
+  (*allocate_pool) (grub_efi_memory_type_t pool_type,
+                   grub_efi_uintn_t size,
+                   void **buffer);
+
+  grub_efi_status_t
+  (*free_pool) (void *buffer);
+
+  grub_efi_status_t
+  (*create_event) (grub_efi_uint32_t type,
+                  grub_efi_tpl_t notify_tpl,
+                  void (*notify_function) (grub_efi_event_t event,
+                                           void *context),
+                  void *notify_context,
+                  grub_efi_event_t *event);
+
+  grub_efi_status_t
+  (*set_timer) (grub_efi_event_t event,
+               grub_efi_timer_delay_t type,
+               grub_efi_uint64_t trigger_time);
+
+   grub_efi_status_t
+   (*wait_for_event) (grub_efi_uintn_t num_events,
+                     grub_efi_event_t *event,
+                     grub_efi_uintn_t *index);
+
+  grub_efi_status_t
+  (*signal_event) (grub_efi_event_t event);
+
+  grub_efi_status_t
+  (*close_event) (grub_efi_event_t event);
+
+  grub_efi_status_t
+  (*check_event) (grub_efi_event_t event);
+
+   grub_efi_status_t
+   (*install_protocol_interface) (grub_efi_handle_t *handle,
+                                 grub_efi_guid_t *protocol,
+                                 grub_efi_interface_type_t interface_type,
+                                 void *interface);
+
+  grub_efi_status_t
+  (*reinstall_protocol_interface) (grub_efi_handle_t handle,
+                                  grub_efi_guid_t *protocol,
+                                  void *old_interface,
+                                  void *new_interface);
+
+  grub_efi_status_t
+  (*uninstall_protocol_interface) (grub_efi_handle_t handle,
+                                  grub_efi_guid_t *protocol,
+                                  void *interface);
+
+  grub_efi_status_t
+  (*handle_protocol) (grub_efi_handle_t handle,
+                     grub_efi_guid_t *protocol,
+                     void **interface);
+
+  void *reserved;
+
+  grub_efi_status_t
+  (*register_protocol_notify) (grub_efi_guid_t *protocol,
+                              grub_efi_event_t event,
+                              void **registration);
+
+  grub_efi_status_t
+  (*locate_handle) (grub_efi_locate_search_type_t search_type,
+                   grub_efi_guid_t *protocol,
+                   void *search_key,
+                   grub_efi_uintn_t *buffer_size,
+                   grub_efi_handle_t *buffer);
+
+  grub_efi_status_t
+  (*locate_device_path) (grub_efi_guid_t *protocol,
+                        grub_efi_device_path_t **device_path,
+                        grub_efi_handle_t *device);
+
+  grub_efi_status_t
+  (*install_configuration_table) (grub_efi_guid_t *guid, void *table);
+
+  grub_efi_status_t
+  (*load_image) (grub_efi_boolean_t boot_policy,
+                grub_efi_handle_t parent_image_handle,
+                grub_efi_device_path_t *file_path,
+                void *source_buffer,
+                grub_efi_uintn_t source_size,
+                grub_efi_handle_t *image_handle);
+
+  grub_efi_status_t
+  (*start_image) (grub_efi_handle_t image_handle,
+                 grub_efi_uintn_t *exit_data_size,
+                 grub_efi_char16_t **exit_data);
+
+  grub_efi_status_t
+  (*exit) (grub_efi_handle_t image_handle,
+          grub_efi_status_t exit_status,
+          grub_efi_uintn_t exit_data_size,
+          grub_efi_char16_t *exit_data) __attribute__((noreturn));
+
+  grub_efi_status_t
+  (*unload_image) (grub_efi_handle_t image_handle);
+
+  grub_efi_status_t
+  (*exit_boot_services) (grub_efi_handle_t image_handle,
+                        grub_efi_uintn_t map_key);
+
+  grub_efi_status_t
+  (*get_next_monotonic_count) (grub_efi_uint64_t *count);
+
+  grub_efi_status_t
+  (*stall) (grub_efi_uintn_t microseconds);
+
+  grub_efi_status_t
+  (*set_watchdog_timer) (grub_efi_uintn_t timeout,
+                        grub_efi_uint64_t watchdog_code,
+                        grub_efi_uintn_t data_size,
+                        grub_efi_char16_t *watchdog_data);
+
+  grub_efi_status_t
+  (*connect_controller) (grub_efi_handle_t controller_handle,
+                        grub_efi_handle_t *driver_image_handle,
+                        grub_efi_device_path_protocol_t *remaining_device_path,
+                        grub_efi_boolean_t recursive);
+
+  grub_efi_status_t
+  (*disconnect_controller) (grub_efi_handle_t controller_handle,
+                           grub_efi_handle_t driver_image_handle,
+                           grub_efi_handle_t child_handle);
+
+  grub_efi_status_t
+  (*open_protocol) (grub_efi_handle_t handle,
+                   grub_efi_guid_t *protocol,
+                   void **interface,
+                   grub_efi_handle_t agent_handle,
+                   grub_efi_handle_t controller_handle,
+                   grub_efi_uint32_t attributes);
+
+  grub_efi_status_t
+  (*close_protocol) (grub_efi_handle_t handle,
+                    grub_efi_guid_t *protocol,
+                    grub_efi_handle_t agent_handle,
+                    grub_efi_handle_t controller_handle);
+
+  grub_efi_status_t
+  (*open_protocol_information) (grub_efi_handle_t handle,
+                               grub_efi_guid_t *protocol,
+                               grub_efi_open_protocol_information_entry_t **entry_buffer,
+                               grub_efi_uintn_t *entry_count);
+
+  grub_efi_status_t
+  (*protocols_per_handle) (grub_efi_handle_t handle,
+                          grub_efi_guid_t ***protocol_buffer,
+                          grub_efi_uintn_t *protocol_buffer_count);
+
+  grub_efi_status_t
+  (*locate_handle_buffer) (grub_efi_locate_search_type_t search_type,
+                          grub_efi_guid_t *protocol,
+                          void *search_key,
+                          grub_efi_uintn_t *no_handles,
+                          grub_efi_handle_t **buffer);
+
+  grub_efi_status_t
+  (*locate_protocol) (grub_efi_guid_t *protocol,
+                     void *registration,
+                     void **interface);
+
+  grub_efi_status_t
+  (*install_multiple_protocol_interfaces) (grub_efi_handle_t *handle, ...);
+
+  grub_efi_status_t
+  (*uninstall_multiple_protocol_interfaces) (grub_efi_handle_t handle, ...);
+
+  grub_efi_status_t
+  (*calculate_crc32) (void *data,
+                     grub_efi_uintn_t data_size,
+                     grub_efi_uint32_t *crc32);
+
+  void
+  (*copy_mem) (void *destination, void *source, grub_efi_uintn_t length);
+
+  void
+  (*set_mem) (void *buffer, grub_efi_uintn_t size, grub_efi_uint8_t value);
+};
+typedef struct grub_efi_boot_services grub_efi_boot_services_t;
+
+struct grub_efi_runtime_services
+{
+  grub_efi_table_header_t hdr;
+
+  grub_efi_status_t
+  (*get_time) (grub_efi_time_t *time,
+              grub_efi_time_capabilities_t *capabilities);
+
+  grub_efi_status_t
+  (*set_time) (grub_efi_time_t *time);
+
+  grub_efi_status_t
+  (*get_wakeup_time) (grub_efi_boolean_t *enabled,
+                     grub_efi_boolean_t *pending,
+                     grub_efi_time_t *time);
+
+  grub_efi_status_t
+  (*set_wakeup_time) (grub_efi_boolean_t enabled,
+                     grub_efi_time_t *time);
+
+  grub_efi_status_t
+  (*set_virtual_address_map) (grub_efi_uintn_t memory_map_size,
+                             grub_efi_uintn_t descriptor_size,
+                             grub_efi_uint32_t descriptor_version,
+                             grub_efi_memory_descriptor_t *virtual_map);
+
+  grub_efi_status_t
+  (*convert_pointer) (grub_efi_uintn_t debug_disposition, void **address);
+
+  grub_efi_status_t
+  (*get_variable) (grub_efi_char16_t *variable_name,
+                  grub_efi_guid_t *vendor_guid,
+                  grub_efi_uint32_t *attributes,
+                  grub_efi_uintn_t *data_size,
+                  void *data);
+
+  grub_efi_status_t
+  (*get_next_variable_name) (grub_efi_uintn_t *variable_name_size,
+                            grub_efi_char16_t *variable_name,
+                            grub_efi_guid_t *vendor_guid);
+
+  grub_efi_status_t
+  (*set_variable) (grub_efi_char16_t *variable_name,
+                  grub_efi_guid_t *vendor_guid,
+                  grub_efi_uint32_t attributes,
+                  grub_efi_uintn_t data_size,
+                  void *data);
+
+  grub_efi_status_t
+  (*get_next_high_monotonic_count) (grub_efi_uint32_t *high_count);
+
+  void
+  (*reset_system) (grub_efi_reset_type_t reset_type,
+                  grub_efi_status_t reset_status,
+                  grub_efi_uintn_t data_size,
+                  grub_efi_char16_t *reset_data);
+};
+typedef struct grub_efi_runtime_services grub_efi_runtime_services_t;
+
+struct grub_efi_configuration_table
+{
+  grub_efi_guid_t vendor_guid;
+  void *vendor_table;
+} __attribute__ ((packed));
+typedef struct grub_efi_configuration_table grub_efi_configuration_table_t;
+
+#define GRUB_EFIEMU_SYSTEM_TABLE_SIGNATURE 0x5453595320494249LL
+#define GRUB_EFIEMU_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552LL
+
+struct grub_efi_simple_input_interface
+{
+  grub_efi_status_t
+  (*reset) (struct grub_efi_simple_input_interface *this,
+           grub_efi_boolean_t extended_verification);
+
+  grub_efi_status_t
+  (*read_key_stroke) (struct grub_efi_simple_input_interface *this,
+                     grub_efi_input_key_t *key);
+
+  grub_efi_event_t wait_for_key;
+};
+typedef struct grub_efi_simple_input_interface grub_efi_simple_input_interface_t;
+
+struct grub_efi_simple_text_output_interface
+{
+  grub_efi_status_t
+  (*reset) (struct grub_efi_simple_text_output_interface *this,
+           grub_efi_boolean_t extended_verification);
+
+  grub_efi_status_t
+  (*output_string) (struct grub_efi_simple_text_output_interface *this,
+                   grub_efi_char16_t *string);
+
+  grub_efi_status_t
+  (*test_string) (struct grub_efi_simple_text_output_interface *this,
+                 grub_efi_char16_t *string);
+
+  grub_efi_status_t
+  (*query_mode) (struct grub_efi_simple_text_output_interface *this,
+                grub_efi_uintn_t mode_number,
+                grub_efi_uintn_t *columns,
+                grub_efi_uintn_t *rows);
+
+  grub_efi_status_t
+  (*set_mode) (struct grub_efi_simple_text_output_interface *this,
+              grub_efi_uintn_t mode_number);
+
+  grub_efi_status_t
+  (*set_attributes) (struct grub_efi_simple_text_output_interface *this,
+                    grub_efi_uintn_t attribute);
+
+  grub_efi_status_t
+  (*clear_screen) (struct grub_efi_simple_text_output_interface *this);
+
+  grub_efi_status_t
+  (*set_cursor_position) (struct grub_efi_simple_text_output_interface *this,
+                         grub_efi_uintn_t column,
+                         grub_efi_uintn_t row);
+
+  grub_efi_status_t
+  (*enable_cursor) (struct grub_efi_simple_text_output_interface *this,
+                   grub_efi_boolean_t visible);
+
+  grub_efi_simple_text_output_mode_t *mode;
+};
+typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t;
+
+#define GRUB_EFI_BLACK         0x00
+#define GRUB_EFI_BLUE          0x01
+#define GRUB_EFI_GREEN         0x02
+#define GRUB_EFI_CYAN          0x03
+#define GRUB_EFI_RED           0x04
+#define GRUB_EFI_MAGENTA       0x05
+#define GRUB_EFI_BROWN         0x06
+#define GRUB_EFI_LIGHTGRAY     0x07
+#define GRUB_EFI_BRIGHT                0x08
+#define GRUB_EFI_DARKGRAY      0x08
+#define GRUB_EFI_LIGHTBLUE     0x09
+#define GRUB_EFI_LIGHTGREEN    0x0A
+#define GRUB_EFI_LIGHTCYAN     0x0B
+#define GRUB_EFI_LIGHTRED      0x0C
+#define GRUB_EFI_LIGHTMAGENTA  0x0D
+#define GRUB_EFI_YELLOW                0x0E
+#define GRUB_EFI_WHITE         0x0F
+
+#define GRUB_EFI_BACKGROUND_BLACK      0x00
+#define GRUB_EFI_BACKGROUND_BLUE       0x10
+#define GRUB_EFI_BACKGROUND_GREEN      0x20
+#define GRUB_EFI_BACKGROUND_CYAN       0x30
+#define GRUB_EFI_BACKGROUND_RED                0x40
+#define GRUB_EFI_BACKGROUND_MAGENTA    0x50
+#define GRUB_EFI_BACKGROUND_BROWN      0x60
+#define GRUB_EFI_BACKGROUND_LIGHTGRAY  0x70
+
+#define GRUB_EFI_TEXT_ATTR(fg, bg)     ((fg) | ((bg)))
+
+struct grub_efi_system_table
+{
+  grub_efi_table_header_t hdr;
+  grub_efi_char16_t *firmware_vendor;
+  grub_efi_uint32_t firmware_revision;
+  grub_efi_handle_t console_in_handler;
+  grub_efi_simple_input_interface_t *con_in;
+  grub_efi_handle_t console_out_handler;
+  grub_efi_simple_text_output_interface_t *con_out;
+  grub_efi_handle_t standard_error_handle;
+  grub_efi_simple_text_output_interface_t *std_err;
+  grub_efi_runtime_services_t *runtime_services;
+  grub_efi_boot_services_t *boot_services;
+  grub_efi_uintn_t num_table_entries;
+  grub_efi_configuration_table_t *configuration_table;
+};
+typedef struct grub_efi_system_table  grub_efi_system_table_t;
+
+struct grub_efi_loaded_image
+{
+  grub_efi_uint32_t revision;
+  grub_efi_handle_t parent_handle;
+  grub_efi_system_table_t *system_table;
+
+  grub_efi_handle_t device_handle;
+  grub_efi_device_path_t *file_path;
+  void *reserved;
+
+  grub_efi_uint32_t load_options_size;
+  void *load_options;
+
+  void *image_base;
+  grub_efi_uint64_t image_size;
+  grub_efi_memory_type_t image_code_type;
+  grub_efi_memory_type_t image_data_type;
+
+  grub_efi_status_t (*unload) (grub_efi_handle_t image_handle);
+};
+typedef struct grub_efi_loaded_image grub_efi_loaded_image_t;
+
+struct grub_efi_disk_io
+{
+  grub_efi_uint64_t revision;
+  grub_efi_status_t (*read) (struct grub_efi_disk_io *this,
+                            grub_efi_uint32_t media_id,
+                            grub_efi_uint64_t offset,
+                            grub_efi_uintn_t buffer_size,
+                            void *buffer);
+  grub_efi_status_t (*write) (struct grub_efi_disk_io *this,
+                            grub_efi_uint32_t media_id,
+                            grub_efi_uint64_t offset,
+                            grub_efi_uintn_t buffer_size,
+                            void *buffer);
+};
+typedef struct grub_efi_disk_io grub_efi_disk_io_t;
+
+struct grub_efi_block_io_media
+{
+  grub_efi_uint32_t media_id;
+  grub_efi_boolean_t removable_media;
+  grub_efi_boolean_t media_present;
+  grub_efi_boolean_t logical_partition;
+  grub_efi_boolean_t read_only;
+  grub_efi_boolean_t write_caching;
+  grub_efi_uint8_t pad[3];
+  grub_efi_uint32_t block_size;
+  grub_efi_uint32_t io_align;
+  grub_efi_uint8_t pad2[4];
+  grub_efi_lba_t last_block;
+};
+typedef struct grub_efi_block_io_media grub_efi_block_io_media_t;
+
+struct grub_efi_block_io
+{
+  grub_efi_uint64_t revision;
+  grub_efi_block_io_media_t *media;
+  grub_efi_status_t (*reset) (struct grub_efi_block_io *this,
+                             grub_efi_boolean_t extended_verification);
+  grub_efi_status_t (*read_blocks) (struct grub_efi_block_io *this,
+                                   grub_efi_uint32_t media_id,
+                                   grub_efi_lba_t lba,
+                                   grub_efi_uintn_t buffer_size,
+                                   void *buffer);
+  grub_efi_status_t (*write_blocks) (struct grub_efi_block_io *this,
+                                    grub_efi_uint32_t media_id,
+                                    grub_efi_lba_t lba,
+                                    grub_efi_uintn_t buffer_size,
+                                    void *buffer);
+  grub_efi_status_t (*flush_blocks) (struct grub_efi_block_io *this);
+};
+typedef struct grub_efi_block_io grub_efi_block_io_t;
+
+#if GRUB_TARGET_SIZEOF_VOID_P == 4
+
+#define efi_call_0(func)               func()
+#define efi_call_1(func, a)            func(a)
+#define efi_call_2(func, a, b)         func(a, b)
+#define efi_call_3(func, a, b, c)      func(a, b, c)
+#define efi_call_4(func, a, b, c, d)   func(a, b, c, d)
+#define efi_call_5(func, a, b, c, d, e)        func(a, b, c, d, e)
+#define efi_call_6(func, a, b, c, d, e, f) func(a, b, c, d, e, f)
+#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j)        func(a, b, c, d, e, f, g, h, i, j)
+
+#else
+
+#define efi_call_0(func) \
+  efi_wrap_0(func)
+#define efi_call_1(func, a) \
+  efi_wrap_1(func, (grub_uint64_t) a)
+#define efi_call_2(func, a, b) \
+  efi_wrap_2(func, (grub_uint64_t) a, (grub_uint64_t) b)
+#define efi_call_3(func, a, b, c) \
+  efi_wrap_3(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c)
+#define efi_call_4(func, a, b, c, d) \
+  efi_wrap_4(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \
+  (grub_uint64_t) d)
+#define efi_call_5(func, a, b, c, d, e)        \
+  efi_wrap_5(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \
+  (grub_uint64_t) d, (grub_uint64_t) e)
+#define efi_call_6(func, a, b, c, d, e, f) \
+  efi_wrap_6(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \
+  (grub_uint64_t) d, (grub_uint64_t) e, (grub_uint64_t) f)
+#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j) \
+  efi_wrap_10(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \
+  (grub_uint64_t) d, (grub_uint64_t) e, (grub_uint64_t) f, (grub_uint64_t) g, \
+  (grub_uint64_t) h, (grub_uint64_t) i, (grub_uint64_t) j)
+
+grub_uint64_t EXPORT_FUNC(efi_wrap_0) (void *func);
+grub_uint64_t EXPORT_FUNC(efi_wrap_1) (void *func, grub_uint64_t arg1);
+grub_uint64_t EXPORT_FUNC(efi_wrap_2) (void *func, grub_uint64_t arg1,
+                                       grub_uint64_t arg2);
+grub_uint64_t EXPORT_FUNC(efi_wrap_3) (void *func, grub_uint64_t arg1,
+                                       grub_uint64_t arg2, grub_uint64_t arg3);
+grub_uint64_t EXPORT_FUNC(efi_wrap_4) (void *func, grub_uint64_t arg1,
+                                       grub_uint64_t arg2, grub_uint64_t arg3,
+                                       grub_uint64_t arg4);
+grub_uint64_t EXPORT_FUNC(efi_wrap_5) (void *func, grub_uint64_t arg1,
+                                       grub_uint64_t arg2, grub_uint64_t arg3,
+                                       grub_uint64_t arg4, grub_uint64_t arg5);
+grub_uint64_t EXPORT_FUNC(efi_wrap_6) (void *func, grub_uint64_t arg1,
+                                       grub_uint64_t arg2, grub_uint64_t arg3,
+                                       grub_uint64_t arg4, grub_uint64_t arg5,
+                                       grub_uint64_t arg6);
+grub_uint64_t EXPORT_FUNC(efi_wrap_10) (void *func, grub_uint64_t arg1,
+                                        grub_uint64_t arg2, grub_uint64_t arg3,
+                                        grub_uint64_t arg4, grub_uint64_t arg5,
+                                        grub_uint64_t arg6, grub_uint64_t arg7,
+                                        grub_uint64_t arg8, grub_uint64_t arg9,
+                                        grub_uint64_t arg10);
+#endif
+
+#endif /* ! GRUB_EFI_API_HEADER */
diff --git a/grub-core/include/grub/efi/console.h b/grub-core/include/grub/efi/console.h
new file mode 100644 (file)
index 0000000..f90b5b7
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_CONSOLE_HEADER
+#define GRUB_EFI_CONSOLE_HEADER        1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+/* Initialize the console system.  */
+void grub_console_init (void);
+
+/* Finish the console system.  */
+void grub_console_fini (void);
+
+#endif /* ! GRUB_EFI_CONSOLE_HEADER */
diff --git a/grub-core/include/grub/efi/console_control.h b/grub-core/include/grub/efi/console_control.h
new file mode 100644 (file)
index 0000000..7c358fc
--- /dev/null
@@ -0,0 +1,57 @@
+/* console_control.h - definitions of the console control protocol */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* The console control protocol is not a part of the EFI spec,
+   but defined in Intel's Sample Implementation.  */
+
+#ifndef GRUB_EFI_CONSOLE_CONTROL_HEADER
+#define GRUB_EFI_CONSOLE_CONTROL_HEADER        1
+
+#define GRUB_EFI_CONSOLE_CONTROL_GUID  \
+  { 0xf42f7782, 0x12e, 0x4c12, \
+    { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } \
+  }
+
+enum grub_efi_screen_mode
+  {
+    GRUB_EFI_SCREEN_TEXT,
+    GRUB_EFI_SCREEN_GRAPHICS,
+    GRUB_EFI_SCREEN_TEXT_MAX_VALUE
+  };
+typedef enum grub_efi_screen_mode grub_efi_screen_mode_t;
+
+struct grub_efi_console_control_protocol
+{
+  grub_efi_status_t
+  (*get_mode) (struct grub_efi_console_control_protocol *this,
+              grub_efi_screen_mode_t *mode,
+              grub_efi_boolean_t *uga_exists,
+              grub_efi_boolean_t *std_in_locked);
+
+  grub_efi_status_t
+  (*set_mode) (struct grub_efi_console_control_protocol *this,
+              grub_efi_screen_mode_t mode);
+
+  grub_efi_status_t
+  (*lock_std_in) (struct grub_efi_console_control_protocol *this,
+                 grub_efi_char16_t *password);
+};
+typedef struct grub_efi_console_control_protocol grub_efi_console_control_protocol_t;
+
+#endif /* ! GRUB_EFI_CONSOLE_CONTROL_HEADER */
diff --git a/grub-core/include/grub/efi/disk.h b/grub-core/include/grub/efi/disk.h
new file mode 100644 (file)
index 0000000..254475c
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_DISK_HEADER
+#define GRUB_EFI_DISK_HEADER   1
+
+#include <grub/efi/api.h>
+#include <grub/symbol.h>
+#include <grub/disk.h>
+
+grub_efi_handle_t
+EXPORT_FUNC(grub_efidisk_get_device_handle) (grub_disk_t disk);
+char *EXPORT_FUNC(grub_efidisk_get_device_name) (grub_efi_handle_t *handle);
+
+void grub_efidisk_init (void);
+void grub_efidisk_fini (void);
+
+#endif /* ! GRUB_EFI_DISK_HEADER */
diff --git a/grub-core/include/grub/efi/efi.h b/grub-core/include/grub/efi/efi.h
new file mode 100644 (file)
index 0000000..5852a47
--- /dev/null
@@ -0,0 +1,73 @@
+/* efi.h - declare variables and functions for EFI support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_EFI_HEADER
+#define GRUB_EFI_EFI_HEADER    1
+
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/efi/api.h>
+
+/* Functions.  */
+void *EXPORT_FUNC(grub_efi_locate_protocol) (grub_efi_guid_t *protocol,
+                                            void *registration);
+grub_efi_handle_t *
+EXPORT_FUNC(grub_efi_locate_handle) (grub_efi_locate_search_type_t search_type,
+                                    grub_efi_guid_t *protocol,
+                                    void *search_key,
+                                    grub_efi_uintn_t *num_handles);
+void *EXPORT_FUNC(grub_efi_open_protocol) (grub_efi_handle_t handle,
+                                          grub_efi_guid_t *protocol,
+                                          grub_efi_uint32_t attributes);
+int EXPORT_FUNC(grub_efi_set_text_mode) (int on);
+void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds);
+void *
+EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address,
+                                     grub_efi_uintn_t pages);
+void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address,
+                                      grub_efi_uintn_t pages);
+int
+EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size,
+                                     grub_efi_memory_descriptor_t *memory_map,
+                                     grub_efi_uintn_t *map_key,
+                                     grub_efi_uintn_t *descriptor_size,
+                                     grub_efi_uint32_t *descriptor_version);
+grub_efi_loaded_image_t *EXPORT_FUNC(grub_efi_get_loaded_image) (grub_efi_handle_t image_handle);
+void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp);
+char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp);
+grub_efi_device_path_t *
+EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle);
+int EXPORT_FUNC(grub_efi_exit_boot_services) (grub_efi_uintn_t map_key);
+int EXPORT_FUNC (grub_efi_finish_boot_services) (void);
+grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memory_map_size,
+                                                          grub_efi_uintn_t descriptor_size,
+                                                          grub_efi_uint32_t descriptor_version,
+                                                          grub_efi_memory_descriptor_t *virtual_map);
+
+void grub_efi_mm_init (void);
+void grub_efi_mm_fini (void);
+void grub_efi_init (void);
+void grub_efi_fini (void);
+void grub_efi_set_prefix (void);
+
+/* Variables.  */
+extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table);
+extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle);
+
+#endif /* ! GRUB_EFI_EFI_HEADER */
diff --git a/grub-core/include/grub/efi/graphics_output.h b/grub-core/include/grub/efi/graphics_output.h
new file mode 100644 (file)
index 0000000..a292219
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_GOP_HEADER
+#define GRUB_EFI_GOP_HEADER    1
+
+/* Based on UEFI specification.  */
+
+#define GRUB_EFI_GOP_GUID \
+  { 0x9042a9de, 0x23dc, 0x4a38, { 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a }}
+
+typedef enum
+  {
+    GRUB_EFI_GOT_RGBA8,
+    GRUB_EFI_GOT_BGRA8,
+    GRUB_EFI_GOT_BITMASK
+  }
+  grub_efi_gop_pixel_format_t;
+
+struct grub_efi_gop_pixel_bitmask
+{
+  grub_uint32_t r;
+  grub_uint32_t g;
+  grub_uint32_t b;
+  grub_uint32_t a;
+};
+
+struct grub_efi_gop_mode_info
+{
+  grub_efi_uint32_t version;
+  grub_efi_uint32_t width;
+  grub_efi_uint32_t height;
+  grub_efi_gop_pixel_format_t pixel_format;
+  struct grub_efi_gop_pixel_bitmask pixel_bitmask;
+  grub_efi_uint32_t pixels_per_scanline;
+};
+
+struct grub_efi_gop_mode
+{
+  grub_efi_uint32_t max_mode;
+  grub_efi_uint32_t mode;
+  struct grub_efi_gop_mode_info *info;
+  grub_efi_uintn_t info_size;
+  grub_efi_physical_address_t fb_base;
+  grub_efi_uintn_t fb_size;
+};
+
+/* Forward declaration.  */
+struct grub_efi_gop;
+
+typedef grub_efi_status_t
+(*grub_efi_gop_query_mode_t) (struct grub_efi_gop *this,
+                             grub_efi_uint32_t mode_number,
+                             grub_efi_uintn_t *size_of_info,
+                             struct grub_efi_gop_mode_info **info);
+
+typedef grub_efi_status_t
+(*grub_efi_gop_set_mode_t) (struct grub_efi_gop *this,
+                           grub_efi_uint32_t mode_number);
+
+typedef grub_efi_status_t
+(*grub_efi_gop_blt_t) (struct grub_efi_gop *this,
+                      void *buffer,
+                      grub_efi_uintn_t operation,
+                      grub_efi_uintn_t sx,
+                      grub_efi_uintn_t sy,
+                      grub_efi_uintn_t dx,
+                      grub_efi_uintn_t dy,
+                      grub_efi_uintn_t width,
+                      grub_efi_uintn_t height,
+                      grub_efi_uintn_t delta);
+
+struct grub_efi_gop
+{
+  grub_efi_gop_query_mode_t query_mode;
+  grub_efi_gop_set_mode_t set_mode;
+  grub_efi_gop_blt_t blt;
+  struct grub_efi_gop_mode *mode;
+};
+
+#endif
diff --git a/grub-core/include/grub/efi/memory.h b/grub-core/include/grub/efi/memory.h
new file mode 100644 (file)
index 0000000..285be83
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MEMORY_MACHINE_HEADER
+#define GRUB_MEMORY_MACHINE_HEADER     1
+
+#include <grub/err.h>
+#include <grub/types.h>
+
+#define GRUB_MMAP_REGISTER_BY_FIRMWARE  1
+
+#define GRUB_MACHINE_MEMORY_AVAILABLE  1
+#define GRUB_MACHINE_MEMORY_RESERVED   2
+#define GRUB_MACHINE_MEMORY_ACPI       3
+#define GRUB_MACHINE_MEMORY_NVS         4
+#define GRUB_MACHINE_MEMORY_CODE        5
+#define GRUB_MACHINE_MEMORY_MAX_TYPE   5
+  /* This one is special: it's used internally but is never reported
+     by firmware. */
+#define GRUB_MACHINE_MEMORY_HOLE       6
+
+grub_err_t grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+                                                                   grub_uint64_t,
+                                                                   grub_uint32_t));
+grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t size,
+                                      int type, int handle);
+grub_err_t grub_machine_mmap_unregister (int handle);
+
+grub_uint64_t grub_mmap_get_post64 (void);
+grub_uint64_t grub_mmap_get_upper (void);
+grub_uint64_t grub_mmap_get_lower (void);
+
+#endif /* ! GRUB_MEMORY_MACHINE_HEADER */
diff --git a/grub-core/include/grub/efi/pe32.h b/grub-core/include/grub/efi/pe32.h
new file mode 100644 (file)
index 0000000..21b56ae
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_PE32_HEADER
+#define GRUB_EFI_PE32_HEADER   1
+
+#include <grub/types.h>
+
+/* The MSDOS compatibility stub. This was copied from the output of
+   objcopy, and it is not necessary to care about what this means.  */
+#define GRUB_PE32_MSDOS_STUB \
+  { \
+    0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, \
+    0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, \
+    0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+    0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+    0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, \
+    0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, \
+    0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, \
+    0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, \
+    0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, \
+    0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, \
+    0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, \
+    0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, \
+    0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  \
+  }
+
+#define GRUB_PE32_MSDOS_STUB_SIZE      0x80
+
+/* According to the spec, the minimal alignment is 512 bytes...
+   But some examples (such as EFI drivers in the Intel
+   Sample Implementation) use 32 bytes (0x20) instead, and it seems
+   to be working. For now, GRUB uses 512 bytes for safety.  */
+#define GRUB_PE32_SECTION_ALIGNMENT    0x200
+#define GRUB_PE32_FILE_ALIGNMENT       GRUB_PE32_SECTION_ALIGNMENT
+
+struct grub_pe32_coff_header
+{
+  grub_uint16_t machine;
+  grub_uint16_t num_sections;
+  grub_uint32_t time;
+  grub_uint32_t symtab_offset;
+  grub_uint32_t num_symbols;
+  grub_uint16_t optional_header_size;
+  grub_uint16_t characteristics;
+};
+
+#define GRUB_PE32_MACHINE_I386         0x14c
+#define GRUB_PE32_MACHINE_X86_64       0x8664
+
+#define GRUB_PE32_RELOCS_STRIPPED              0x0001
+#define GRUB_PE32_EXECUTABLE_IMAGE             0x0002
+#define GRUB_PE32_LINE_NUMS_STRIPPED           0x0004
+#define GRUB_PE32_LOCAL_SYMS_STRIPPED          0x0008
+#define GRUB_PE32_AGGRESSIVE_WS_TRIM           0x0010
+#define GRUB_PE32_LARGE_ADDRESS_AWARE          0x0020
+#define GRUB_PE32_16BIT_MACHINE                        0x0040
+#define GRUB_PE32_BYTES_REVERSED_LO            0x0080
+#define GRUB_PE32_32BIT_MACHINE                        0x0100
+#define GRUB_PE32_DEBUG_STRIPPED               0x0200
+#define GRUB_PE32_REMOVABLE_RUN_FROM_SWAP      0x0400
+#define GRUB_PE32_SYSTEM                       0x1000
+#define GRUB_PE32_DLL                          0x2000
+#define GRUB_PE32_UP_SYSTEM_ONLY               0x4000
+#define GRUB_PE32_BYTES_REVERSED_HI            0x8000
+
+struct grub_pe32_data_directory
+{
+  grub_uint32_t rva;
+  grub_uint32_t size;
+};
+
+struct grub_pe32_optional_header
+{
+  grub_uint16_t magic;
+  grub_uint8_t major_linker_version;
+  grub_uint8_t minor_linker_version;
+  grub_uint32_t code_size;
+  grub_uint32_t data_size;
+  grub_uint32_t bss_size;
+  grub_uint32_t entry_addr;
+  grub_uint32_t code_base;
+
+#if GRUB_TARGET_SIZEOF_VOID_P == 4
+  grub_uint32_t data_base;
+  grub_uint32_t image_base;
+#else
+  grub_uint64_t image_base;
+#endif
+
+  grub_uint32_t section_alignment;
+  grub_uint32_t file_alignment;
+  grub_uint16_t major_os_version;
+  grub_uint16_t minor_os_version;
+  grub_uint16_t major_image_version;
+  grub_uint16_t minor_image_version;
+  grub_uint16_t major_subsystem_version;
+  grub_uint16_t minor_subsystem_version;
+  grub_uint32_t reserved;
+  grub_uint32_t image_size;
+  grub_uint32_t header_size;
+  grub_uint32_t checksum;
+  grub_uint16_t subsystem;
+  grub_uint16_t dll_characteristics;
+
+#if GRUB_TARGET_SIZEOF_VOID_P == 4
+
+  grub_uint32_t stack_reserve_size;
+  grub_uint32_t stack_commit_size;
+  grub_uint32_t heap_reserve_size;
+  grub_uint32_t heap_commit_size;
+
+#else
+
+  grub_uint64_t stack_reserve_size;
+  grub_uint64_t stack_commit_size;
+  grub_uint64_t heap_reserve_size;
+  grub_uint64_t heap_commit_size;
+
+#endif
+
+  grub_uint32_t loader_flags;
+  grub_uint32_t num_data_directories;
+
+  /* Data directories.  */
+  struct grub_pe32_data_directory export_table;
+  struct grub_pe32_data_directory import_table;
+  struct grub_pe32_data_directory resource_table;
+  struct grub_pe32_data_directory exception_table;
+  struct grub_pe32_data_directory certificate_table;
+  struct grub_pe32_data_directory base_relocation_table;
+  struct grub_pe32_data_directory debug;
+  struct grub_pe32_data_directory architecture;
+  struct grub_pe32_data_directory global_ptr;
+  struct grub_pe32_data_directory tls_table;
+  struct grub_pe32_data_directory load_config_table;
+  struct grub_pe32_data_directory bound_import;
+  struct grub_pe32_data_directory iat;
+  struct grub_pe32_data_directory delay_import_descriptor;
+  struct grub_pe32_data_directory com_runtime_header;
+  struct grub_pe32_data_directory reserved_entry;
+};
+
+#if GRUB_TARGET_SIZEOF_VOID_P == 4
+
+#define GRUB_PE32_PE32_MAGIC   0x10b
+
+#else
+
+#define GRUB_PE32_PE32_MAGIC   0x20b
+
+#endif
+
+#define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION    10
+
+#define GRUB_PE32_NUM_DATA_DIRECTORIES 16
+
+struct grub_pe32_section_table
+{
+  char name[8];
+  grub_uint32_t virtual_size;
+  grub_uint32_t virtual_address;
+  grub_uint32_t raw_data_size;
+  grub_uint32_t raw_data_offset;
+  grub_uint32_t relocations_offset;
+  grub_uint32_t line_numbers_offset;
+  grub_uint16_t num_relocations;
+  grub_uint16_t num_line_numbers;
+  grub_uint32_t characteristics;
+};
+
+#define GRUB_PE32_SCN_CNT_CODE                 0x00000020
+#define GRUB_PE32_SCN_CNT_INITIALIZED_DATA     0x00000040
+#define GRUB_PE32_SCN_MEM_DISCARDABLE          0x02000000
+#define GRUB_PE32_SCN_MEM_EXECUTE              0x20000000
+#define GRUB_PE32_SCN_MEM_READ                 0x40000000
+#define GRUB_PE32_SCN_MEM_WRITE                        0x80000000
+
+#define GRUB_PE32_SCN_ALIGN_1BYTES             0x00100000
+#define GRUB_PE32_SCN_ALIGN_2BYTES             0x00200000
+#define GRUB_PE32_SCN_ALIGN_4BYTES             0x00300000
+#define GRUB_PE32_SCN_ALIGN_8BYTES             0x00400000
+#define GRUB_PE32_SCN_ALIGN_16BYTES            0x00500000
+#define GRUB_PE32_SCN_ALIGN_32BYTES            0x00600000
+#define GRUB_PE32_SCN_ALIGN_64BYTES            0x00700000
+
+#define GRUB_PE32_SCN_ALIGN_SHIFT              20
+#define GRUB_PE32_SCN_ALIGN_MASK               7
+
+
+struct grub_pe32_header
+{
+  /* This should be filled in with GRUB_PE32_MSDOS_STUB.  */
+  grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE];
+
+  /* This is always PE\0\0.  */
+  char signature[4];
+
+  /* The COFF file header.  */
+  struct grub_pe32_coff_header coff_header;
+
+  /* The Optional header.  */
+  struct grub_pe32_optional_header optional_header;
+};
+
+struct grub_pe32_fixup_block
+{
+  grub_uint32_t page_rva;
+  grub_uint32_t block_size;
+  grub_uint16_t entries[0];
+};
+
+#define GRUB_PE32_FIXUP_ENTRY(type, offset)    (((type) << 12) | (offset))
+
+#define GRUB_PE32_REL_BASED_ABSOLUTE   0
+#define GRUB_PE32_REL_BASED_HIGH       1
+#define GRUB_PE32_REL_BASED_LOW                2
+#define GRUB_PE32_REL_BASED_HIGHLOW    3
+#define GRUB_PE32_REL_BASED_HIGHADJ    4
+#define GRUB_PE32_REL_BASED_MIPS_JMPADDR 5
+#define GRUB_PE32_REL_BASED_SECTION    6
+#define GRUB_PE32_REL_BASED_REL                7
+#define GRUB_PE32_REL_BASED_IA64_IMM64 9
+#define GRUB_PE32_REL_BASED_DIR64      10
+#define GRUB_PE32_REL_BASED_HIGH3ADJ   11
+
+struct grub_pe32_symbol
+{
+  union
+  {
+    char short_name[8];
+    grub_uint32_t long_name[2];
+  };
+
+  grub_uint32_t value;
+  grub_uint16_t section;
+  grub_uint16_t type;
+  grub_uint8_t storage_class;
+  grub_uint8_t num_aux;
+} __attribute__ ((packed));
+
+#define GRUB_PE32_SYM_CLASS_EXTERNAL   2
+#define GRUB_PE32_SYM_CLASS_STATIC     3
+#define GRUB_PE32_SYM_CLASS_FILE       0x67
+
+#define GRUB_PE32_DT_FUNCTION          0x20
+
+struct grub_pe32_reloc
+{
+  grub_uint32_t offset;
+  grub_uint32_t symtab_index;
+  grub_uint16_t type;
+} __attribute__ ((packed));
+
+#define GRUB_PE32_REL_I386_DIR32       0x6
+#define GRUB_PE32_REL_I386_REL32       0x14
+
+#endif /* ! GRUB_EFI_PE32_HEADER */
diff --git a/grub-core/include/grub/efi/time.h b/grub-core/include/grub/efi/time.h
new file mode 100644 (file)
index 0000000..540f6fc
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_TIME_HEADER
+#define GRUB_EFI_TIME_HEADER   1
+
+#include <grub/symbol.h>
+
+/* This is destined to overflow when one hour passes by.  */
+#define GRUB_TICKS_PER_SECOND  ((1UL << 31) / 60 / 60 * 2)
+
+/* Return the real time in ticks.  */
+grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
+
+#endif /* ! GRUB_EFI_TIME_HEADER */
diff --git a/grub-core/include/grub/efi/uga_draw.h b/grub-core/include/grub/efi/uga_draw.h
new file mode 100644 (file)
index 0000000..9350430
--- /dev/null
@@ -0,0 +1,76 @@
+/* uga_draw.h - definitions of the uga draw protocol */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* The console control protocol is not a part of the EFI spec,
+   but defined in Intel's Sample Implementation.  */
+
+#ifndef GRUB_EFI_UGA_DRAW_HEADER
+#define GRUB_EFI_UGA_DRAW_HEADER       1
+
+#define GRUB_EFI_UGA_DRAW_GUID \
+  { 0x982c298b, 0xf4fa, 0x41cb, { 0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 }}
+
+enum grub_efi_uga_blt_operation
+{
+  GRUB_EFI_UGA_VIDEO_FILL,
+  GRUB_EFI_UGA_VIDEO_TO_BLT,
+  GRUB_EFI_UGA_BLT_TO_VIDEO,
+  GRUB_EFI_UGA_VIDEO_TO_VIDEO,
+  GRUB_EFI_UGA_GLT_MAX
+};
+
+struct grub_efi_uga_pixel
+{
+  grub_uint8_t Blue;
+  grub_uint8_t Green;
+  grub_uint8_t Red;
+  grub_uint8_t Reserved;
+};
+
+struct grub_efi_uga_draw_protocol
+{
+  grub_efi_status_t
+  (*get_mode) (struct grub_efi_uga_draw_protocol *this,
+              grub_uint32_t *width,
+              grub_uint32_t *height,
+              grub_uint32_t *depth,
+              grub_uint32_t *refresh_rate);
+
+  grub_efi_status_t
+  (*set_mode) (struct grub_efi_uga_draw_protocol *this,
+              grub_uint32_t width,
+              grub_uint32_t height,
+              grub_uint32_t depth,
+              grub_uint32_t refresh_rate);
+
+  grub_efi_status_t
+  (*blt) (struct grub_efi_uga_draw_protocol *this,
+         struct grub_efi_uga_pixel *blt_buffer,
+         enum grub_efi_uga_blt_operation blt_operation,
+         grub_efi_uintn_t src_x,
+         grub_efi_uintn_t src_y,
+         grub_efi_uintn_t dest_x,
+         grub_efi_uintn_t dest_y,
+         grub_efi_uintn_t width,
+         grub_efi_uintn_t height,
+         grub_efi_uintn_t delta);
+};
+typedef struct grub_efi_uga_draw_protocol grub_efi_uga_draw_protocol_t;
+
+#endif /* ! GRUB_EFI_UGA_DRAW_HEADER */
diff --git a/grub-core/include/grub/efiemu/efiemu.h b/grub-core/include/grub/efiemu/efiemu.h
new file mode 100644 (file)
index 0000000..3980d32
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_EMU_HEADER
+#define GRUB_EFI_EMU_HEADER    1
+
+#include <grub/efi/api.h>
+#include <grub/file.h>
+
+#define GRUB_EFIEMU_PAGESIZE 4096
+
+/* EFI api defined in 32-bit and 64-bit version*/
+struct grub_efi_system_table32
+{
+  grub_efi_table_header_t hdr;
+  grub_efi_uint32_t firmware_vendor;
+  grub_efi_uint32_t firmware_revision;
+  grub_efi_uint32_t console_in_handler;
+  grub_efi_uint32_t con_in;
+  grub_efi_uint32_t console_out_handler;
+  grub_efi_uint32_t con_out;
+  grub_efi_uint32_t standard_error_handle;
+  grub_efi_uint32_t std_err;
+  grub_efi_uint32_t runtime_services;
+  grub_efi_uint32_t boot_services;
+  grub_efi_uint32_t num_table_entries;
+  grub_efi_uint32_t configuration_table;
+} __attribute__ ((packed));
+typedef struct grub_efi_system_table32  grub_efi_system_table32_t;
+
+struct grub_efi_system_table64
+{
+  grub_efi_table_header_t hdr;
+  grub_efi_uint64_t firmware_vendor;
+  grub_efi_uint32_t firmware_revision;
+  grub_efi_uint32_t pad;
+  grub_efi_uint64_t console_in_handler;
+  grub_efi_uint64_t con_in;
+  grub_efi_uint64_t console_out_handler;
+  grub_efi_uint64_t con_out;
+  grub_efi_uint64_t standard_error_handle;
+  grub_efi_uint64_t std_err;
+  grub_efi_uint64_t runtime_services;
+  grub_efi_uint64_t boot_services;
+  grub_efi_uint64_t num_table_entries;
+  grub_efi_uint64_t configuration_table;
+} __attribute__ ((packed));
+typedef struct grub_efi_system_table64  grub_efi_system_table64_t;
+
+struct grub_efiemu_runtime_services32
+{
+  grub_efi_table_header_t hdr;
+  grub_efi_uint32_t get_time;
+  grub_efi_uint32_t set_time;
+  grub_efi_uint32_t get_wakeup_time;
+  grub_efi_uint32_t set_wakeup_time;
+  grub_efi_uint32_t set_virtual_address_map;
+  grub_efi_uint32_t convert_pointer;
+  grub_efi_uint32_t get_variable;
+  grub_efi_uint32_t get_next_variable_name;
+  grub_efi_uint32_t set_variable;
+  grub_efi_uint32_t get_next_high_monotonic_count;
+  grub_efi_uint32_t reset_system;
+} __attribute__ ((packed));
+typedef struct grub_efiemu_runtime_services32 grub_efiemu_runtime_services32_t;
+
+struct grub_efiemu_runtime_services64
+{
+  grub_efi_table_header_t hdr;
+  grub_efi_uint64_t get_time;
+  grub_efi_uint64_t set_time;
+  grub_efi_uint64_t get_wakeup_time;
+  grub_efi_uint64_t set_wakeup_time;
+  grub_efi_uint64_t set_virtual_address_map;
+  grub_efi_uint64_t convert_pointer;
+  grub_efi_uint64_t get_variable;
+  grub_efi_uint64_t get_next_variable_name;
+  grub_efi_uint64_t set_variable;
+  grub_efi_uint64_t get_next_high_monotonic_count;
+  grub_efi_uint64_t reset_system;
+} __attribute__ ((packed));
+typedef struct grub_efiemu_runtime_services64 grub_efiemu_runtime_services64_t;
+
+extern grub_efi_system_table32_t *grub_efiemu_system_table32;
+extern grub_efi_system_table64_t *grub_efiemu_system_table64;
+
+/* Convenience macros to access currently loaded efiemu */
+#define grub_efiemu_system_table ((grub_efiemu_sizeof_uintn_t () == 8) \
+                                 ? (void *) grub_efiemu_system_table64 \
+                                 : (void *) grub_efiemu_system_table32)
+#define GRUB_EFIEMU_SIZEOF_OF_UINTN (grub_efiemu_sizeof_uintn_t ())
+#define GRUB_EFIEMU_SYSTEM_TABLE(x) ((grub_efiemu_sizeof_uintn_t () == 8) \
+                                    ? grub_efiemu_system_table64->x \
+                                    : grub_efiemu_system_table32->x)
+#define GRUB_EFIEMU_SYSTEM_TABLE_SET(x,y) ((grub_efiemu_sizeof_uintn_t () == 8)\
+                                          ? (grub_efiemu_system_table64->x \
+                                             = (y)) \
+                                          : (grub_efiemu_system_table32->x \
+                                             = (y)))
+#define GRUB_EFIEMU_SYSTEM_TABLE_PTR(x) ((grub_efiemu_sizeof_uintn_t () == 8)\
+                                        ? UINT_TO_PTR \
+                                        (grub_efiemu_system_table64->x) \
+                                        : UINT_TO_PTR \
+                                        (grub_efiemu_system_table32->x))
+#define GRUB_EFIEMU_SYSTEM_TABLE_VAR(x) ((grub_efiemu_sizeof_uintn_t () == 8) \
+                                        ? (void *) \
+                                        &(grub_efiemu_system_table64->x) \
+                                        : (void *) \
+                                        &(grub_efiemu_system_table32->x))
+#define GRUB_EFIEMU_SYSTEM_TABLE_SIZEOF(x) \
+  ((grub_efiemu_sizeof_uintn_t () == 8) \
+   ? sizeof(grub_efiemu_system_table64->x)\
+   : sizeof(grub_efiemu_system_table32->x))
+#define GRUB_EFIEMU_SYSTEM_TABLE_SIZEOF_TOTAL ((grub_efiemu_sizeof_uintn_t () == 8) ? sizeof(*grub_efiemu_system_table64):sizeof(*grub_efiemu_system_table32))
+
+/* ELF management definitions and functions */
+
+struct grub_efiemu_segment
+{
+  struct grub_efiemu_segment *next;
+  grub_size_t size;
+  unsigned section;
+  int handle;
+  int ptv_rel_needed;
+  grub_off_t off;
+  void *srcptr;
+};
+typedef struct grub_efiemu_segment *grub_efiemu_segment_t;
+
+struct grub_efiemu_elf_sym
+{
+  int handle;
+  grub_off_t off;
+  unsigned section;
+};
+
+int grub_efiemu_check_header32 (void *ehdr, grub_size_t size);
+int grub_efiemu_check_header64 (void *ehdr, grub_size_t size);
+grub_err_t grub_efiemu_loadcore_init32 (void *core, grub_size_t core_size,
+                                       grub_efiemu_segment_t *segments);
+grub_err_t grub_efiemu_loadcore_init64 (void *core, grub_size_t core_size,
+                                       grub_efiemu_segment_t *segments);
+grub_err_t grub_efiemu_loadcore_load32 (void *core,
+                                       grub_size_t core_size,
+                                       grub_efiemu_segment_t segments);
+grub_err_t grub_efiemu_loadcore_load64 (void *core,
+                                       grub_size_t core_size,
+                                       grub_efiemu_segment_t segments);
+grub_err_t grub_efiemu_loadcore_unload32 (void);
+grub_err_t grub_efiemu_loadcore_unload64 (void);
+grub_err_t grub_efiemu_loadcore_unload(void);
+grub_err_t grub_efiemu_loadcore_init (grub_file_t file);
+grub_err_t grub_efiemu_loadcore_load (void);
+
+/* Configuration tables manipulation. Definitions and functions */
+struct grub_efiemu_configuration_table
+{
+  struct grub_efiemu_configuration_table *next;
+  grub_efi_guid_t guid;
+  void * (*get_table) (void *data);
+  void (*unload) (void *data);
+  void *data;
+};
+struct grub_efiemu_configuration_table32
+{
+  grub_efi_guid_t vendor_guid;
+  grub_efi_uint32_t vendor_table;
+} __attribute__ ((packed));
+typedef struct grub_efiemu_configuration_table32 grub_efiemu_configuration_table32_t;
+struct grub_efiemu_configuration_table64
+{
+  grub_efi_guid_t vendor_guid;
+  grub_efi_uint64_t vendor_table;
+} __attribute__ ((packed));
+typedef struct grub_efiemu_configuration_table64 grub_efiemu_configuration_table64_t;
+grub_err_t grub_efiemu_unregister_configuration_table (grub_efi_guid_t guid);
+grub_err_t
+grub_efiemu_register_configuration_table (grub_efi_guid_t guid,
+                                         void * (*get_table) (void *data),
+                                         void (*unload) (void *data),
+                                         void *data);
+
+/* Memory management functions */
+int grub_efiemu_request_memalign (grub_size_t align, grub_size_t size,
+                                 grub_efi_memory_type_t type);
+void *grub_efiemu_mm_obtain_request (int handle);
+int grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size,
+                               grub_efi_memory_descriptor_t *memory_map,
+                               grub_efi_uintn_t *map_key,
+                               grub_efi_uintn_t *descriptor_size,
+                               grub_efi_uint32_t *descriptor_version);
+grub_err_t grub_efiemu_mm_unload (void);
+grub_err_t grub_efiemu_mm_do_alloc (void);
+grub_err_t grub_efiemu_mm_init (void);
+void *grub_efiemu_mm_obtain_request (int handle);
+void grub_efiemu_mm_return_request (int handle);
+grub_efi_memory_type_t grub_efiemu_mm_get_type (int handle);
+
+/* Drop-in replacements for grub_efi_* and grub_machine_* */
+int grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size,
+                               grub_efi_memory_descriptor_t *memory_map,
+                               grub_efi_uintn_t *map_key,
+                               grub_efi_uintn_t *descriptor_size,
+                               grub_efi_uint32_t *descriptor_version);
+grub_err_t
+grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+                                                       grub_uint64_t,
+                                                       grub_uint32_t));
+int grub_efiemu_sizeof_uintn_t (void);
+int grub_efiemu_exit_boot_services (grub_efi_uintn_t map_key);
+int grub_efiemu_finish_boot_services (void);
+grub_err_t
+grub_efiemu_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper);
+#define GRUB_EFIEMU_MEMORY_AVAILABLE   1
+#define GRUB_EFIEMU_MEMORY_RESERVED    2
+#define GRUB_EFIEMU_MEMORY_ACPI        3
+#define GRUB_EFIEMU_MEMORY_NVS         4
+#define GRUB_EFIEMU_MEMORY_CODE         5
+
+/* efiemu main control definitions and functions*/
+typedef enum {GRUB_EFIEMU_NOTLOADED,
+             GRUB_EFIEMU32, GRUB_EFIEMU64} grub_efiemu_mode_t;
+struct grub_efiemu_prepare_hook
+{
+  struct grub_efiemu_prepare_hook *next;
+  grub_err_t (*hook) (void *data);
+  void (*unload) (void *data);
+  void *data;
+};
+grub_err_t grub_efiemu_prepare32 (struct grub_efiemu_prepare_hook
+                                 *prepare_hooks,
+                                 struct grub_efiemu_configuration_table
+                                 *config_tables);
+grub_err_t grub_efiemu_prepare64 (struct grub_efiemu_prepare_hook
+                                 *prepare_hooks,
+                                 struct grub_efiemu_configuration_table
+                                 *config_tables);
+grub_err_t grub_efiemu_unload (void);
+grub_err_t grub_efiemu_prepare (void);
+grub_err_t
+grub_efiemu_register_prepare_hook (grub_err_t (*hook) (void *data),
+                                  void (*unload) (void *data),
+                                  void *data);
+
+/* symbols and pointers */
+grub_err_t grub_efiemu_alloc_syms (void);
+grub_err_t grub_efiemu_request_symbols (int num);
+grub_err_t grub_efiemu_resolve_symbol (const char *name,
+                                      int *handle, grub_off_t *off);
+grub_err_t grub_efiemu_register_symbol (const char *name,
+                                       int handle, grub_off_t off);
+void grub_efiemu_free_syms (void);
+grub_err_t grub_efiemu_write_value (void * addr, grub_uint32_t value,
+                                   int plus_handle,
+                                   int minus_handle, int ptv_needed, int size);
+grub_err_t grub_efiemu_write_sym_markers (void);
+grub_err_t grub_efiemu_pnvram (void);
+grub_err_t grub_efiemu_prepare (void);
+char *grub_efiemu_get_default_core_name (void);
+void grub_efiemu_pnvram_cmd_unregister (void);
+grub_err_t grub_efiemu_autocore (void);
+grub_err_t grub_efiemu_crc32 (void);
+grub_err_t grub_efiemu_crc64 (void);
+grub_err_t
+grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
+                                    grub_efi_uintn_t descriptor_size,
+                                    grub_efi_uint32_t descriptor_version
+                                    __attribute__ ((unused)),
+                                    grub_efi_memory_descriptor_t *virtual_map);
+
+#endif /* ! GRUB_EFI_EMU_HEADER */
diff --git a/grub-core/include/grub/efiemu/runtime.h b/grub-core/include/grub/efiemu/runtime.h
new file mode 100644 (file)
index 0000000..1eb474a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_EMU_RUNTIME_HEADER
+#define GRUB_EFI_EMU_RUNTIME_HEADER    1
+
+struct grub_efiemu_ptv_rel
+{
+  grub_uint64_t addr;
+  grub_efi_memory_type_t plustype;
+  grub_efi_memory_type_t minustype;
+  grub_uint32_t size;
+} __attribute__ ((packed));
+
+struct efi_variable
+{
+  grub_efi_guid_t guid;
+  grub_uint32_t namelen;
+  grub_uint32_t size;
+  grub_efi_uint32_t attributes;
+} __attribute__ ((packed));
+#endif /* ! GRUB_EFI_EMU_RUNTIME_HEADER */
diff --git a/grub-core/include/grub/elf.h b/grub-core/include/grub/elf.h
new file mode 100644 (file)
index 0000000..e54989c
--- /dev/null
@@ -0,0 +1,2377 @@
+/* This file defines standard ELF types, structures, and macros.
+   Copyright (C) 1995-1999,2000,2001,2002,2008,2009 Free Software Foundation, Inc.
+   This file was part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef GRUB_ELF_H
+#define        GRUB_ELF_H 1
+
+/* Standard ELF types.  */
+
+#include <grub/types.h>
+
+/* Type for a 16-bit quantity.  */
+typedef grub_uint16_t Elf32_Half;
+typedef grub_uint16_t Elf64_Half;
+
+/* Types for signed and unsigned 32-bit quantities.  */
+typedef grub_uint32_t Elf32_Word;
+typedef        grub_int32_t  Elf32_Sword;
+typedef grub_uint32_t Elf64_Word;
+typedef        grub_int32_t  Elf64_Sword;
+
+/* Types for signed and unsigned 64-bit quantities.  */
+typedef grub_uint64_t Elf32_Xword;
+typedef        grub_int64_t  Elf32_Sxword;
+typedef grub_uint64_t Elf64_Xword;
+typedef        grub_int64_t  Elf64_Sxword;
+
+/* Type of addresses.  */
+typedef grub_uint32_t Elf32_Addr;
+typedef grub_uint64_t Elf64_Addr;
+
+/* Type of file offsets.  */
+typedef grub_uint32_t Elf32_Off;
+typedef grub_uint64_t Elf64_Off;
+
+/* Type for section indices, which are 16-bit quantities.  */
+typedef grub_uint16_t Elf32_Section;
+typedef grub_uint16_t Elf64_Section;
+
+/* Type for version symbol information.  */
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+
+/* The ELF file header.  This appears at the start of every ELF file.  */
+
+#define EI_NIDENT (16)
+
+typedef struct
+{
+  unsigned char        e_ident[EI_NIDENT];     /* Magic number and other info */
+  Elf32_Half   e_type;                 /* Object file type */
+  Elf32_Half   e_machine;              /* Architecture */
+  Elf32_Word   e_version;              /* Object file version */
+  Elf32_Addr   e_entry;                /* Entry point virtual address */
+  Elf32_Off    e_phoff;                /* Program header table file offset */
+  Elf32_Off    e_shoff;                /* Section header table file offset */
+  Elf32_Word   e_flags;                /* Processor-specific flags */
+  Elf32_Half   e_ehsize;               /* ELF header size in bytes */
+  Elf32_Half   e_phentsize;            /* Program header table entry size */
+  Elf32_Half   e_phnum;                /* Program header table entry count */
+  Elf32_Half   e_shentsize;            /* Section header table entry size */
+  Elf32_Half   e_shnum;                /* Section header table entry count */
+  Elf32_Half   e_shstrndx;             /* Section header string table index */
+} Elf32_Ehdr;
+
+typedef struct
+{
+  unsigned char        e_ident[EI_NIDENT];     /* Magic number and other info */
+  Elf64_Half   e_type;                 /* Object file type */
+  Elf64_Half   e_machine;              /* Architecture */
+  Elf64_Word   e_version;              /* Object file version */
+  Elf64_Addr   e_entry;                /* Entry point virtual address */
+  Elf64_Off    e_phoff;                /* Program header table file offset */
+  Elf64_Off    e_shoff;                /* Section header table file offset */
+  Elf64_Word   e_flags;                /* Processor-specific flags */
+  Elf64_Half   e_ehsize;               /* ELF header size in bytes */
+  Elf64_Half   e_phentsize;            /* Program header table entry size */
+  Elf64_Half   e_phnum;                /* Program header table entry count */
+  Elf64_Half   e_shentsize;            /* Section header table entry size */
+  Elf64_Half   e_shnum;                /* Section header table entry count */
+  Elf64_Half   e_shstrndx;             /* Section header string table index */
+} Elf64_Ehdr;
+
+/* Fields in the e_ident array.  The EI_* macros are indices into the
+   array.  The macros under each EI_* macro are the values the byte
+   may have.  */
+
+#define EI_MAG0                0               /* File identification byte 0 index */
+#define ELFMAG0                0x7f            /* Magic number byte 0 */
+
+#define EI_MAG1                1               /* File identification byte 1 index */
+#define ELFMAG1                'E'             /* Magic number byte 1 */
+
+#define EI_MAG2                2               /* File identification byte 2 index */
+#define ELFMAG2                'L'             /* Magic number byte 2 */
+
+#define EI_MAG3                3               /* File identification byte 3 index */
+#define ELFMAG3                'F'             /* Magic number byte 3 */
+
+/* Conglomeration of the identification bytes, for easy testing as a word.  */
+#define        ELFMAG          "\177ELF"
+#define        SELFMAG         4
+
+#define EI_CLASS       4               /* File class byte index */
+#define ELFCLASSNONE   0               /* Invalid class */
+#define ELFCLASS32     1               /* 32-bit objects */
+#define ELFCLASS64     2               /* 64-bit objects */
+#define ELFCLASSNUM    3
+
+#define EI_DATA                5               /* Data encoding byte index */
+#define ELFDATANONE    0               /* Invalid data encoding */
+#define ELFDATA2LSB    1               /* 2's complement, little endian */
+#define ELFDATA2MSB    2               /* 2's complement, big endian */
+#define ELFDATANUM     3
+
+#define EI_VERSION     6               /* File version byte index */
+                                       /* Value must be EV_CURRENT */
+
+#define EI_OSABI       7               /* OS ABI identification */
+#define ELFOSABI_NONE          0       /* UNIX System V ABI */
+#define ELFOSABI_SYSV          0       /* Alias.  */
+#define ELFOSABI_HPUX          1       /* HP-UX */
+#define ELFOSABI_NETBSD                2       /* NetBSD.  */
+#define ELFOSABI_LINUX         3       /* Linux.  */
+#define ELFOSABI_SOLARIS       6       /* Sun Solaris.  */
+#define ELFOSABI_AIX           7       /* IBM AIX.  */
+#define ELFOSABI_IRIX          8       /* SGI Irix.  */
+#define ELFOSABI_FREEBSD       9       /* FreeBSD.  */
+#define ELFOSABI_TRU64         10      /* Compaq TRU64 UNIX.  */
+#define ELFOSABI_MODESTO       11      /* Novell Modesto.  */
+#define ELFOSABI_OPENBSD       12      /* OpenBSD.  */
+#define ELFOSABI_ARM           97      /* ARM */
+#define ELFOSABI_STANDALONE    255     /* Standalone (embedded) application */
+
+#define EI_ABIVERSION  8               /* ABI version */
+
+#define EI_PAD         9               /* Byte index of padding bytes */
+
+/* Legal values for e_type (object file type).  */
+
+#define ET_NONE                0               /* No file type */
+#define ET_REL         1               /* Relocatable file */
+#define ET_EXEC                2               /* Executable file */
+#define ET_DYN         3               /* Shared object file */
+#define ET_CORE                4               /* Core file */
+#define        ET_NUM          5               /* Number of defined types */
+#define ET_LOOS                0xfe00          /* OS-specific range start */
+#define ET_HIOS                0xfeff          /* OS-specific range end */
+#define ET_LOPROC      0xff00          /* Processor-specific range start */
+#define ET_HIPROC      0xffff          /* Processor-specific range end */
+
+/* Legal values for e_machine (architecture).  */
+
+#define EM_NONE                 0              /* No machine */
+#define EM_M32          1              /* AT&T WE 32100 */
+#define EM_SPARC        2              /* SUN SPARC */
+#define EM_386          3              /* Intel 80386 */
+#define EM_68K          4              /* Motorola m68k family */
+#define EM_88K          5              /* Motorola m88k family */
+#define EM_860          7              /* Intel 80860 */
+#define EM_MIPS                 8              /* MIPS R3000 big-endian */
+#define EM_S370                 9              /* IBM System/370 */
+#define EM_MIPS_RS3_LE 10              /* MIPS R3000 little-endian */
+
+#define EM_PARISC      15              /* HPPA */
+#define EM_VPP500      17              /* Fujitsu VPP500 */
+#define EM_SPARC32PLUS 18              /* Sun's "v8plus" */
+#define EM_960         19              /* Intel 80960 */
+#define EM_PPC         20              /* PowerPC */
+#define EM_PPC64       21              /* PowerPC 64-bit */
+#define EM_S390                22              /* IBM S390 */
+
+#define EM_V800                36              /* NEC V800 series */
+#define EM_FR20                37              /* Fujitsu FR20 */
+#define EM_RH32                38              /* TRW RH-32 */
+#define EM_RCE         39              /* Motorola RCE */
+#define EM_ARM         40              /* ARM */
+#define EM_FAKE_ALPHA  41              /* Digital Alpha */
+#define EM_SH          42              /* Hitachi SH */
+#define EM_SPARCV9     43              /* SPARC v9 64-bit */
+#define EM_TRICORE     44              /* Siemens Tricore */
+#define EM_ARC         45              /* Argonaut RISC Core */
+#define EM_H8_300      46              /* Hitachi H8/300 */
+#define EM_H8_300H     47              /* Hitachi H8/300H */
+#define EM_H8S         48              /* Hitachi H8S */
+#define EM_H8_500      49              /* Hitachi H8/500 */
+#define EM_IA_64       50              /* Intel Merced */
+#define EM_MIPS_X      51              /* Stanford MIPS-X */
+#define EM_COLDFIRE    52              /* Motorola Coldfire */
+#define EM_68HC12      53              /* Motorola M68HC12 */
+#define EM_MMA         54              /* Fujitsu MMA Multimedia Accelerator*/
+#define EM_PCP         55              /* Siemens PCP */
+#define EM_NCPU                56              /* Sony nCPU embedded RISC */
+#define EM_NDR1                57              /* Denso NDR1 microprocessor */
+#define EM_STARCORE    58              /* Motorola Start*Core processor */
+#define EM_ME16                59              /* Toyota ME16 processor */
+#define EM_ST100       60              /* STMicroelectronics ST100 processor */
+#define EM_TINYJ       61              /* Advanced Logic Corp. Tinyj emb.fam*/
+#define EM_X86_64      62              /* AMD x86-64 architecture */
+#define EM_PDSP                63              /* Sony DSP Processor */
+
+#define EM_FX66                66              /* Siemens FX66 microcontroller */
+#define EM_ST9PLUS     67              /* STMicroelectronics ST9+ 8/16 mc */
+#define EM_ST7         68              /* STMicroelectronics ST7 8 bit mc */
+#define EM_68HC16      69              /* Motorola MC68HC16 microcontroller */
+#define EM_68HC11      70              /* Motorola MC68HC11 microcontroller */
+#define EM_68HC08      71              /* Motorola MC68HC08 microcontroller */
+#define EM_68HC05      72              /* Motorola MC68HC05 microcontroller */
+#define EM_SVX         73              /* Silicon Graphics SVx */
+#define EM_AT19                74              /* STMicroelectronics ST19 8 bit mc */
+#define EM_VAX         75              /* Digital VAX */
+#define EM_CRIS                76              /* Axis Communications 32-bit embedded processor */
+#define EM_JAVELIN     77              /* Infineon Technologies 32-bit embedded processor */
+#define EM_FIREPATH    78              /* Element 14 64-bit DSP Processor */
+#define EM_ZSP         79              /* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX                80              /* Donald Knuth's educational 64-bit processor */
+#define EM_HUANY       81              /* Harvard University machine-independent object files */
+#define EM_PRISM       82              /* SiTera Prism */
+#define EM_AVR         83              /* Atmel AVR 8-bit microcontroller */
+#define EM_FR30                84              /* Fujitsu FR30 */
+#define EM_D10V                85              /* Mitsubishi D10V */
+#define EM_D30V                86              /* Mitsubishi D30V */
+#define EM_V850                87              /* NEC v850 */
+#define EM_M32R                88              /* Mitsubishi M32R */
+#define EM_MN10300     89              /* Matsushita MN10300 */
+#define EM_MN10200     90              /* Matsushita MN10200 */
+#define EM_PJ          91              /* picoJava */
+#define EM_OPENRISC    92              /* OpenRISC 32-bit embedded processor */
+#define EM_ARC_A5      93              /* ARC Cores Tangent-A5 */
+#define EM_XTENSA      94              /* Tensilica Xtensa Architecture */
+#define EM_NUM         95
+
+/* If it is necessary to assign new unofficial EM_* values, please
+   pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
+   chances of collision with official or non-GNU unofficial values.  */
+
+#define EM_ALPHA       0x9026
+
+/* Legal values for e_version (version).  */
+
+#define EV_NONE                0               /* Invalid ELF version */
+#define EV_CURRENT     1               /* Current version */
+#define EV_NUM         2
+
+/* Section header.  */
+
+typedef struct
+{
+  Elf32_Word   sh_name;                /* Section name (string tbl index) */
+  Elf32_Word   sh_type;                /* Section type */
+  Elf32_Word   sh_flags;               /* Section flags */
+  Elf32_Addr   sh_addr;                /* Section virtual addr at execution */
+  Elf32_Off    sh_offset;              /* Section file offset */
+  Elf32_Word   sh_size;                /* Section size in bytes */
+  Elf32_Word   sh_link;                /* Link to another section */
+  Elf32_Word   sh_info;                /* Additional section information */
+  Elf32_Word   sh_addralign;           /* Section alignment */
+  Elf32_Word   sh_entsize;             /* Entry size if section holds table */
+} Elf32_Shdr;
+
+typedef struct
+{
+  Elf64_Word   sh_name;                /* Section name (string tbl index) */
+  Elf64_Word   sh_type;                /* Section type */
+  Elf64_Xword  sh_flags;               /* Section flags */
+  Elf64_Addr   sh_addr;                /* Section virtual addr at execution */
+  Elf64_Off    sh_offset;              /* Section file offset */
+  Elf64_Xword  sh_size;                /* Section size in bytes */
+  Elf64_Word   sh_link;                /* Link to another section */
+  Elf64_Word   sh_info;                /* Additional section information */
+  Elf64_Xword  sh_addralign;           /* Section alignment */
+  Elf64_Xword  sh_entsize;             /* Entry size if section holds table */
+} Elf64_Shdr;
+
+/* Special section indices.  */
+
+#define SHN_UNDEF      0               /* Undefined section */
+#define SHN_LORESERVE  0xff00          /* Start of reserved indices */
+#define SHN_LOPROC     0xff00          /* Start of processor-specific */
+#define SHN_HIPROC     0xff1f          /* End of processor-specific */
+#define SHN_LOOS       0xff20          /* Start of OS-specific */
+#define SHN_HIOS       0xff3f          /* End of OS-specific */
+#define SHN_ABS                0xfff1          /* Associated symbol is absolute */
+#define SHN_COMMON     0xfff2          /* Associated symbol is common */
+#define SHN_XINDEX     0xffff          /* Index is in extra table.  */
+#define SHN_HIRESERVE  0xffff          /* End of reserved indices */
+
+/* Legal values for sh_type (section type).  */
+
+#define SHT_NULL         0             /* Section header table entry unused */
+#define SHT_PROGBITS     1             /* Program data */
+#define SHT_SYMTAB       2             /* Symbol table */
+#define SHT_STRTAB       3             /* String table */
+#define SHT_RELA         4             /* Relocation entries with addends */
+#define SHT_HASH         5             /* Symbol hash table */
+#define SHT_DYNAMIC      6             /* Dynamic linking information */
+#define SHT_NOTE         7             /* Notes */
+#define SHT_NOBITS       8             /* Program space with no data (bss) */
+#define SHT_REL                  9             /* Relocation entries, no addends */
+#define SHT_SHLIB        10            /* Reserved */
+#define SHT_DYNSYM       11            /* Dynamic linker symbol table */
+#define SHT_INIT_ARRAY   14            /* Array of constructors */
+#define SHT_FINI_ARRAY   15            /* Array of destructors */
+#define SHT_PREINIT_ARRAY 16           /* Array of pre-constructors */
+#define SHT_GROUP        17            /* Section group */
+#define SHT_SYMTAB_SHNDX  18           /* Extended section indices */
+#define        SHT_NUM           19            /* Number of defined types.  */
+#define SHT_LOOS         0x60000000    /* Start OS-specific */
+#define SHT_GNU_LIBLIST          0x6ffffff7    /* Prelink library list */
+#define SHT_CHECKSUM     0x6ffffff8    /* Checksum for DSO content.  */
+#define SHT_LOSUNW       0x6ffffffa    /* Sun-specific low bound.  */
+#define SHT_SUNW_move    0x6ffffffa
+#define SHT_SUNW_COMDAT   0x6ffffffb
+#define SHT_SUNW_syminfo  0x6ffffffc
+#define SHT_GNU_verdef   0x6ffffffd    /* Version definition section.  */
+#define SHT_GNU_verneed          0x6ffffffe    /* Version needs section.  */
+#define SHT_GNU_versym   0x6fffffff    /* Version symbol table.  */
+#define SHT_HISUNW       0x6fffffff    /* Sun-specific high bound.  */
+#define SHT_HIOS         0x6fffffff    /* End OS-specific type */
+#define SHT_LOPROC       0x70000000    /* Start of processor-specific */
+#define SHT_HIPROC       0x7fffffff    /* End of processor-specific */
+#define SHT_LOUSER       0x80000000    /* Start of application-specific */
+#define SHT_HIUSER       0x8fffffff    /* End of application-specific */
+
+/* Legal values for sh_flags (section flags).  */
+
+#define SHF_WRITE           (1 << 0)   /* Writable */
+#define SHF_ALLOC           (1 << 1)   /* Occupies memory during execution */
+#define SHF_EXECINSTR       (1 << 2)   /* Executable */
+#define SHF_MERGE           (1 << 4)   /* Might be merged */
+#define SHF_STRINGS         (1 << 5)   /* Contains nul-terminated strings */
+#define SHF_INFO_LINK       (1 << 6)   /* `sh_info' contains SHT index */
+#define SHF_LINK_ORDER      (1 << 7)   /* Preserve order after combining */
+#define SHF_OS_NONCONFORMING (1 << 8)  /* Non-standard OS specific handling
+                                          required */
+#define SHF_GROUP           (1 << 9)   /* Section is member of a group.  */
+#define SHF_TLS                     (1 << 10)  /* Section hold thread-local data.  */
+#define SHF_MASKOS          0x0ff00000 /* OS-specific.  */
+#define SHF_MASKPROC        0xf0000000 /* Processor-specific */
+
+/* Section group handling.  */
+#define GRP_COMDAT     0x1             /* Mark group as COMDAT.  */
+
+/* Symbol table entry.  */
+
+typedef struct
+{
+  Elf32_Word   st_name;                /* Symbol name (string tbl index) */
+  Elf32_Addr   st_value;               /* Symbol value */
+  Elf32_Word   st_size;                /* Symbol size */
+  unsigned char        st_info;                /* Symbol type and binding */
+  unsigned char        st_other;               /* Symbol visibility */
+  Elf32_Section        st_shndx;               /* Section index */
+} Elf32_Sym;
+
+typedef struct
+{
+  Elf64_Word   st_name;                /* Symbol name (string tbl index) */
+  unsigned char        st_info;                /* Symbol type and binding */
+  unsigned char st_other;              /* Symbol visibility */
+  Elf64_Section        st_shndx;               /* Section index */
+  Elf64_Addr   st_value;               /* Symbol value */
+  Elf64_Xword  st_size;                /* Symbol size */
+} Elf64_Sym;
+
+/* The syminfo section if available contains additional information about
+   every dynamic symbol.  */
+
+typedef struct
+{
+  Elf32_Half si_boundto;               /* Direct bindings, symbol bound to */
+  Elf32_Half si_flags;                 /* Per symbol flags */
+} Elf32_Syminfo;
+
+typedef struct
+{
+  Elf64_Half si_boundto;               /* Direct bindings, symbol bound to */
+  Elf64_Half si_flags;                 /* Per symbol flags */
+} Elf64_Syminfo;
+
+/* Possible values for si_boundto.  */
+#define SYMINFO_BT_SELF                0xffff  /* Symbol bound to self */
+#define SYMINFO_BT_PARENT      0xfffe  /* Symbol bound to parent */
+#define SYMINFO_BT_LOWRESERVE  0xff00  /* Beginning of reserved entries */
+
+/* Possible bitmasks for si_flags.  */
+#define SYMINFO_FLG_DIRECT     0x0001  /* Direct bound symbol */
+#define SYMINFO_FLG_PASSTHRU   0x0002  /* Pass-thru symbol for translator */
+#define SYMINFO_FLG_COPY       0x0004  /* Symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD   0x0008  /* Symbol bound to object to be lazy
+                                          loaded */
+/* Syminfo version values.  */
+#define SYMINFO_NONE           0
+#define SYMINFO_CURRENT                1
+#define SYMINFO_NUM            2
+
+
+/* How to extract and insert information held in the st_info field.  */
+
+#define ELF32_ST_BIND(val)             (((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val)             ((val) & 0xf)
+#define ELF32_ST_INFO(bind, type)      (((bind) << 4) + ((type) & 0xf))
+
+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
+#define ELF64_ST_BIND(val)             ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val)             ELF32_ST_TYPE (val)
+#define ELF64_ST_INFO(bind, type)      ELF32_ST_INFO ((bind), (type))
+
+/* Legal values for ST_BIND subfield of st_info (symbol binding).  */
+
+#define STB_LOCAL      0               /* Local symbol */
+#define STB_GLOBAL     1               /* Global symbol */
+#define STB_WEAK       2               /* Weak symbol */
+#define        STB_NUM         3               /* Number of defined types.  */
+#define STB_LOOS       10              /* Start of OS-specific */
+#define STB_HIOS       12              /* End of OS-specific */
+#define STB_LOPROC     13              /* Start of processor-specific */
+#define STB_HIPROC     15              /* End of processor-specific */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_NOTYPE     0               /* Symbol type is unspecified */
+#define STT_OBJECT     1               /* Symbol is a data object */
+#define STT_FUNC       2               /* Symbol is a code object */
+#define STT_SECTION    3               /* Symbol associated with a section */
+#define STT_FILE       4               /* Symbol's name is file name */
+#define STT_COMMON     5               /* Symbol is a common data object */
+#define STT_TLS                6               /* Symbol is thread-local data object*/
+#define        STT_NUM         7               /* Number of defined types.  */
+#define STT_LOOS       10              /* Start of OS-specific */
+#define STT_HIOS       12              /* End of OS-specific */
+#define STT_LOPROC     13              /* Start of processor-specific */
+#define STT_HIPROC     15              /* End of processor-specific */
+
+
+/* Symbol table indices are found in the hash buckets and chain table
+   of a symbol hash table section.  This special index value indicates
+   the end of a chain, meaning no further symbols are found in that bucket.  */
+
+#define STN_UNDEF      0               /* End of a chain.  */
+#define STN_ABS                65521
+
+
+/* How to extract and insert information held in the st_other field.  */
+
+#define ELF32_ST_VISIBILITY(o) ((o) & 0x03)
+
+/* For ELF64 the definitions are the same.  */
+#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o)
+
+/* Symbol visibility specification encoded in the st_other field.  */
+#define STV_DEFAULT    0               /* Default symbol visibility rules */
+#define STV_INTERNAL   1               /* Processor specific hidden class */
+#define STV_HIDDEN     2               /* Sym unavailable in other modules */
+#define STV_PROTECTED  3               /* Not preemptible, not exported */
+
+
+/* Relocation table entry without addend (in section of type SHT_REL).  */
+
+typedef struct
+{
+  Elf32_Addr   r_offset;               /* Address */
+  Elf32_Word   r_info;                 /* Relocation type and symbol index */
+} Elf32_Rel;
+
+/* I have seen two different definitions of the Elf64_Rel and
+   Elf64_Rela structures, so we'll leave them out until Novell (or
+   whoever) gets their act together.  */
+/* The following, at least, is used on Sparc v9, MIPS, and Alpha.  */
+
+typedef struct
+{
+  Elf64_Addr   r_offset;               /* Address */
+  Elf64_Xword  r_info;                 /* Relocation type and symbol index */
+} Elf64_Rel;
+
+/* Relocation table entry with addend (in section of type SHT_RELA).  */
+
+typedef struct
+{
+  Elf32_Addr   r_offset;               /* Address */
+  Elf32_Word   r_info;                 /* Relocation type and symbol index */
+  Elf32_Sword  r_addend;               /* Addend */
+} Elf32_Rela;
+
+typedef struct
+{
+  Elf64_Addr   r_offset;               /* Address */
+  Elf64_Xword  r_info;                 /* Relocation type and symbol index */
+  Elf64_Sxword r_addend;               /* Addend */
+} Elf64_Rela;
+
+/* How to extract and insert information held in the r_info field.  */
+
+#define ELF32_R_SYM(val)               ((val) >> 8)
+#define ELF32_R_TYPE(val)              ((val) & 0xff)
+#define ELF32_R_INFO(sym, type)                (((sym) << 8) + ((type) & 0xff))
+
+#define ELF64_R_SYM(i)                 ((i) >> 32)
+#define ELF64_R_TYPE(i)                        ((i) & 0xffffffff)
+#define ELF64_R_INFO(sym,type)         ((((Elf64_Xword) (sym)) << 32) + (type))
+
+/* Program segment header.  */
+
+typedef struct
+{
+  Elf32_Word   p_type;                 /* Segment type */
+  Elf32_Off    p_offset;               /* Segment file offset */
+  Elf32_Addr   p_vaddr;                /* Segment virtual address */
+  Elf32_Addr   p_paddr;                /* Segment physical address */
+  Elf32_Word   p_filesz;               /* Segment size in file */
+  Elf32_Word   p_memsz;                /* Segment size in memory */
+  Elf32_Word   p_flags;                /* Segment flags */
+  Elf32_Word   p_align;                /* Segment alignment */
+} Elf32_Phdr;
+
+typedef struct
+{
+  Elf64_Word   p_type;                 /* Segment type */
+  Elf64_Word   p_flags;                /* Segment flags */
+  Elf64_Off    p_offset;               /* Segment file offset */
+  Elf64_Addr   p_vaddr;                /* Segment virtual address */
+  Elf64_Addr   p_paddr;                /* Segment physical address */
+  Elf64_Xword  p_filesz;               /* Segment size in file */
+  Elf64_Xword  p_memsz;                /* Segment size in memory */
+  Elf64_Xword  p_align;                /* Segment alignment */
+} Elf64_Phdr;
+
+/* Legal values for p_type (segment type).  */
+
+#define        PT_NULL         0               /* Program header table entry unused */
+#define PT_LOAD                1               /* Loadable program segment */
+#define PT_DYNAMIC     2               /* Dynamic linking information */
+#define PT_INTERP      3               /* Program interpreter */
+#define PT_NOTE                4               /* Auxiliary information */
+#define PT_SHLIB       5               /* Reserved */
+#define PT_PHDR                6               /* Entry for header table itself */
+#define PT_TLS         7               /* Thread-local storage segment */
+#define        PT_NUM          8               /* Number of defined types */
+#define PT_LOOS                0x60000000      /* Start of OS-specific */
+#define PT_GNU_EH_FRAME        0x6474e550      /* GCC .eh_frame_hdr segment */
+#define PT_LOSUNW      0x6ffffffa
+#define PT_SUNWBSS     0x6ffffffa      /* Sun Specific segment */
+#define PT_SUNWSTACK   0x6ffffffb      /* Stack segment */
+#define PT_HISUNW      0x6fffffff
+#define PT_HIOS                0x6fffffff      /* End of OS-specific */
+#define PT_LOPROC      0x70000000      /* Start of processor-specific */
+#define PT_HIPROC      0x7fffffff      /* End of processor-specific */
+
+/* Legal values for p_flags (segment flags).  */
+
+#define PF_X           (1 << 0)        /* Segment is executable */
+#define PF_W           (1 << 1)        /* Segment is writable */
+#define PF_R           (1 << 2)        /* Segment is readable */
+#define PF_MASKOS      0x0ff00000      /* OS-specific */
+#define PF_MASKPROC    0xf0000000      /* Processor-specific */
+
+/* Legal values for note segment descriptor types for core files. */
+
+#define NT_PRSTATUS    1               /* Contains copy of prstatus struct */
+#define NT_FPREGSET    2               /* Contains copy of fpregset struct */
+#define NT_PRPSINFO    3               /* Contains copy of prpsinfo struct */
+#define NT_PRXREG      4               /* Contains copy of prxregset struct */
+#define NT_PLATFORM    5               /* String from sysinfo(SI_PLATFORM) */
+#define NT_AUXV                6               /* Contains copy of auxv array */
+#define NT_GWINDOWS    7               /* Contains copy of gwindows struct */
+#define NT_ASRS                8               /* Contains copy of asrset struct */
+#define NT_PSTATUS     10              /* Contains copy of pstatus struct */
+#define NT_PSINFO      13              /* Contains copy of psinfo struct */
+#define NT_PRCRED      14              /* Contains copy of prcred struct */
+#define NT_UTSNAME     15              /* Contains copy of utsname struct */
+#define NT_LWPSTATUS   16              /* Contains copy of lwpstatus struct */
+#define NT_LWPSINFO    17              /* Contains copy of lwpinfo struct */
+#define NT_PRFPXREG    20              /* Contains copy of fprxregset struct*/
+
+/* Legal values for the note segment descriptor types for object files.  */
+
+#define NT_VERSION     1               /* Contains a version string.  */
+
+
+/* Dynamic section entry.  */
+
+typedef struct
+{
+  Elf32_Sword  d_tag;                  /* Dynamic entry type */
+  union
+    {
+      Elf32_Word d_val;                        /* Integer value */
+      Elf32_Addr d_ptr;                        /* Address value */
+    } d_un;
+} Elf32_Dyn;
+
+typedef struct
+{
+  Elf64_Sxword d_tag;                  /* Dynamic entry type */
+  union
+    {
+      Elf64_Xword d_val;               /* Integer value */
+      Elf64_Addr d_ptr;                        /* Address value */
+    } d_un;
+} Elf64_Dyn;
+
+/* Legal values for d_tag (dynamic entry type).  */
+
+#define DT_NULL                0               /* Marks end of dynamic section */
+#define DT_NEEDED      1               /* Name of needed library */
+#define DT_PLTRELSZ    2               /* Size in bytes of PLT relocs */
+#define DT_PLTGOT      3               /* Processor defined value */
+#define DT_HASH                4               /* Address of symbol hash table */
+#define DT_STRTAB      5               /* Address of string table */
+#define DT_SYMTAB      6               /* Address of symbol table */
+#define DT_RELA                7               /* Address of Rela relocs */
+#define DT_RELASZ      8               /* Total size of Rela relocs */
+#define DT_RELAENT     9               /* Size of one Rela reloc */
+#define DT_STRSZ       10              /* Size of string table */
+#define DT_SYMENT      11              /* Size of one symbol table entry */
+#define DT_INIT                12              /* Address of init function */
+#define DT_FINI                13              /* Address of termination function */
+#define DT_SONAME      14              /* Name of shared object */
+#define DT_RPATH       15              /* Library search path (deprecated) */
+#define DT_SYMBOLIC    16              /* Start symbol search here */
+#define DT_REL         17              /* Address of Rel relocs */
+#define DT_RELSZ       18              /* Total size of Rel relocs */
+#define DT_RELENT      19              /* Size of one Rel reloc */
+#define DT_PLTREL      20              /* Type of reloc in PLT */
+#define DT_DEBUG       21              /* For debugging; unspecified */
+#define DT_TEXTREL     22              /* Reloc might modify .text */
+#define DT_JMPREL      23              /* Address of PLT relocs */
+#define        DT_BIND_NOW     24              /* Process relocations of object */
+#define        DT_INIT_ARRAY   25              /* Array with addresses of init fct */
+#define        DT_FINI_ARRAY   26              /* Array with addresses of fini fct */
+#define        DT_INIT_ARRAYSZ 27              /* Size in bytes of DT_INIT_ARRAY */
+#define        DT_FINI_ARRAYSZ 28              /* Size in bytes of DT_FINI_ARRAY */
+#define DT_RUNPATH     29              /* Library search path */
+#define DT_FLAGS       30              /* Flags for the object being loaded */
+#define DT_ENCODING    32              /* Start of encoded range */
+#define DT_PREINIT_ARRAY 32            /* Array with addresses of preinit fct*/
+#define DT_PREINIT_ARRAYSZ 33          /* size in bytes of DT_PREINIT_ARRAY */
+#define        DT_NUM          34              /* Number used */
+#define DT_LOOS                0x6000000d      /* Start of OS-specific */
+#define DT_HIOS                0x6ffff000      /* End of OS-specific */
+#define DT_LOPROC      0x70000000      /* Start of processor-specific */
+#define DT_HIPROC      0x7fffffff      /* End of processor-specific */
+#define        DT_PROCNUM      DT_MIPS_NUM     /* Most used by any processor */
+
+/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
+   Dyn.d_un.d_val field of the Elf*_Dyn structure.  This follows Sun's
+   approach.  */
+#define DT_VALRNGLO    0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5    /* Prelinking timestamp */
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6   /* Size of conflict section */
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7    /* Size of library list */
+#define DT_CHECKSUM    0x6ffffdf8
+#define DT_PLTPADSZ    0x6ffffdf9
+#define DT_MOVEENT     0x6ffffdfa
+#define DT_MOVESZ      0x6ffffdfb
+#define DT_FEATURE_1   0x6ffffdfc      /* Feature selection (DTF_*).  */
+#define DT_POSFLAG_1   0x6ffffdfd      /* Flags for DT_* entries, effecting
+                                          the following DT_* entry.  */
+#define DT_SYMINSZ     0x6ffffdfe      /* Size of syminfo table (in bytes) */
+#define DT_SYMINENT    0x6ffffdff      /* Entry size of syminfo */
+#define DT_VALRNGHI    0x6ffffdff
+#define DT_VALTAGIDX(tag)      (DT_VALRNGHI - (tag))   /* Reverse order! */
+#define DT_VALNUM 12
+
+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+   Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+
+   If any adjustment is made to the ELF object after it has been
+   built these entries will need to be adjusted.  */
+#define DT_ADDRRNGLO   0x6ffffe00
+#define DT_GNU_CONFLICT        0x6ffffef8      /* Start of conflict section */
+#define DT_GNU_LIBLIST 0x6ffffef9      /* Library list */
+#define DT_CONFIG      0x6ffffefa      /* Configuration information.  */
+#define DT_DEPAUDIT    0x6ffffefb      /* Dependency auditing.  */
+#define DT_AUDIT       0x6ffffefc      /* Object auditing.  */
+#define        DT_PLTPAD       0x6ffffefd      /* PLT padding.  */
+#define        DT_MOVETAB      0x6ffffefe      /* Move table.  */
+#define DT_SYMINFO     0x6ffffeff      /* Syminfo table.  */
+#define DT_ADDRRNGHI   0x6ffffeff
+#define DT_ADDRTAGIDX(tag)     (DT_ADDRRNGHI - (tag))  /* Reverse order! */
+#define DT_ADDRNUM 10
+
+/* The versioning entry types.  The next are defined as part of the
+   GNU extension.  */
+#define DT_VERSYM      0x6ffffff0
+
+#define DT_RELACOUNT   0x6ffffff9
+#define DT_RELCOUNT    0x6ffffffa
+
+/* These were chosen by Sun.  */
+#define DT_FLAGS_1     0x6ffffffb      /* State flags, see DF_1_* below.  */
+#define        DT_VERDEF       0x6ffffffc      /* Address of version definition
+                                          table */
+#define        DT_VERDEFNUM    0x6ffffffd      /* Number of version definitions */
+#define        DT_VERNEED      0x6ffffffe      /* Address of table with needed
+                                          versions */
+#define        DT_VERNEEDNUM   0x6fffffff      /* Number of needed versions */
+#define DT_VERSIONTAGIDX(tag)  (DT_VERNEEDNUM - (tag)) /* Reverse order! */
+#define DT_VERSIONTAGNUM 16
+
+/* Sun added these machine-independent extensions in the "processor-specific"
+   range.  Be compatible.  */
+#define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
+#define DT_FILTER       0x7fffffff      /* Shared object to get values from */
+#define DT_EXTRATAGIDX(tag)    ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
+#define DT_EXTRANUM    3
+
+/* Values of `d_un.d_val' in the DT_FLAGS entry.  */
+#define DF_ORIGIN      0x00000001      /* Object may use DF_ORIGIN */
+#define DF_SYMBOLIC    0x00000002      /* Symbol resolutions starts here */
+#define DF_TEXTREL     0x00000004      /* Object contains text relocations */
+#define DF_BIND_NOW    0x00000008      /* No lazy binding for this object */
+#define DF_STATIC_TLS  0x00000010      /* Module uses the static TLS model */
+
+/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
+   entry in the dynamic section.  */
+#define DF_1_NOW       0x00000001      /* Set RTLD_NOW for this object.  */
+#define DF_1_GLOBAL    0x00000002      /* Set RTLD_GLOBAL for this object.  */
+#define DF_1_GROUP     0x00000004      /* Set RTLD_GROUP for this object.  */
+#define DF_1_NODELETE  0x00000008      /* Set RTLD_NODELETE for this object.*/
+#define DF_1_LOADFLTR  0x00000010      /* Trigger filtee loading at runtime.*/
+#define DF_1_INITFIRST 0x00000020      /* Set RTLD_INITFIRST for this object*/
+#define DF_1_NOOPEN    0x00000040      /* Set RTLD_NOOPEN for this object.  */
+#define DF_1_ORIGIN    0x00000080      /* $ORIGIN must be handled.  */
+#define DF_1_DIRECT    0x00000100      /* Direct binding enabled.  */
+#define DF_1_TRANS     0x00000200
+#define DF_1_INTERPOSE 0x00000400      /* Object is used to interpose.  */
+#define DF_1_NODEFLIB  0x00000800      /* Ignore default lib search path.  */
+#define DF_1_NODUMP    0x00001000      /* Object can't be dldump'ed.  */
+#define DF_1_CONFALT   0x00002000      /* Configuration alternative created.*/
+#define DF_1_ENDFILTEE 0x00004000      /* Filtee terminates filters search. */
+#define        DF_1_DISPRELDNE 0x00008000      /* Disp reloc applied at build time. */
+#define        DF_1_DISPRELPND 0x00010000      /* Disp reloc applied at run-time.  */
+
+/* Flags for the feature selection in DT_FEATURE_1.  */
+#define DTF_1_PARINIT  0x00000001
+#define DTF_1_CONFEXP  0x00000002
+
+/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry.  */
+#define DF_P1_LAZYLOAD 0x00000001      /* Lazyload following object.  */
+#define DF_P1_GROUPPERM        0x00000002      /* Symbols from next object are not
+                                          generally available.  */
+
+/* Version definition sections.  */
+
+typedef struct
+{
+  Elf32_Half   vd_version;             /* Version revision */
+  Elf32_Half   vd_flags;               /* Version information */
+  Elf32_Half   vd_ndx;                 /* Version Index */
+  Elf32_Half   vd_cnt;                 /* Number of associated aux entries */
+  Elf32_Word   vd_hash;                /* Version name hash value */
+  Elf32_Word   vd_aux;                 /* Offset in bytes to verdaux array */
+  Elf32_Word   vd_next;                /* Offset in bytes to next verdef
+                                          entry */
+} Elf32_Verdef;
+
+typedef struct
+{
+  Elf64_Half   vd_version;             /* Version revision */
+  Elf64_Half   vd_flags;               /* Version information */
+  Elf64_Half   vd_ndx;                 /* Version Index */
+  Elf64_Half   vd_cnt;                 /* Number of associated aux entries */
+  Elf64_Word   vd_hash;                /* Version name hash value */
+  Elf64_Word   vd_aux;                 /* Offset in bytes to verdaux array */
+  Elf64_Word   vd_next;                /* Offset in bytes to next verdef
+                                          entry */
+} Elf64_Verdef;
+
+
+/* Legal values for vd_version (version revision).  */
+#define VER_DEF_NONE   0               /* No version */
+#define VER_DEF_CURRENT        1               /* Current version */
+#define VER_DEF_NUM    2               /* Given version number */
+
+/* Legal values for vd_flags (version information flags).  */
+#define VER_FLG_BASE   0x1             /* Version definition of file itself */
+#define VER_FLG_WEAK   0x2             /* Weak version identifier */
+
+/* Versym symbol index values.  */
+#define        VER_NDX_LOCAL           0       /* Symbol is local.  */
+#define        VER_NDX_GLOBAL          1       /* Symbol is global.  */
+#define        VER_NDX_LORESERVE       0xff00  /* Beginning of reserved entries.  */
+#define        VER_NDX_ELIMINATE       0xff01  /* Symbol is to be eliminated.  */
+
+/* Auxiliary version information.  */
+
+typedef struct
+{
+  Elf32_Word   vda_name;               /* Version or dependency names */
+  Elf32_Word   vda_next;               /* Offset in bytes to next verdaux
+                                          entry */
+} Elf32_Verdaux;
+
+typedef struct
+{
+  Elf64_Word   vda_name;               /* Version or dependency names */
+  Elf64_Word   vda_next;               /* Offset in bytes to next verdaux
+                                          entry */
+} Elf64_Verdaux;
+
+
+/* Version dependency section.  */
+
+typedef struct
+{
+  Elf32_Half   vn_version;             /* Version of structure */
+  Elf32_Half   vn_cnt;                 /* Number of associated aux entries */
+  Elf32_Word   vn_file;                /* Offset of filename for this
+                                          dependency */
+  Elf32_Word   vn_aux;                 /* Offset in bytes to vernaux array */
+  Elf32_Word   vn_next;                /* Offset in bytes to next verneed
+                                          entry */
+} Elf32_Verneed;
+
+typedef struct
+{
+  Elf64_Half   vn_version;             /* Version of structure */
+  Elf64_Half   vn_cnt;                 /* Number of associated aux entries */
+  Elf64_Word   vn_file;                /* Offset of filename for this
+                                          dependency */
+  Elf64_Word   vn_aux;                 /* Offset in bytes to vernaux array */
+  Elf64_Word   vn_next;                /* Offset in bytes to next verneed
+                                          entry */
+} Elf64_Verneed;
+
+
+/* Legal values for vn_version (version revision).  */
+#define VER_NEED_NONE   0              /* No version */
+#define VER_NEED_CURRENT 1             /* Current version */
+#define VER_NEED_NUM    2              /* Given version number */
+
+/* Auxiliary needed version information.  */
+
+typedef struct
+{
+  Elf32_Word   vna_hash;               /* Hash value of dependency name */
+  Elf32_Half   vna_flags;              /* Dependency specific information */
+  Elf32_Half   vna_other;              /* Unused */
+  Elf32_Word   vna_name;               /* Dependency name string offset */
+  Elf32_Word   vna_next;               /* Offset in bytes to next vernaux
+                                          entry */
+} Elf32_Vernaux;
+
+typedef struct
+{
+  Elf64_Word   vna_hash;               /* Hash value of dependency name */
+  Elf64_Half   vna_flags;              /* Dependency specific information */
+  Elf64_Half   vna_other;              /* Unused */
+  Elf64_Word   vna_name;               /* Dependency name string offset */
+  Elf64_Word   vna_next;               /* Offset in bytes to next vernaux
+                                          entry */
+} Elf64_Vernaux;
+
+
+/* Legal values for vna_flags.  */
+#define VER_FLG_WEAK   0x2             /* Weak version identifier */
+
+
+/* Auxiliary vector.  */
+
+/* This vector is normally only used by the program interpreter.  The
+   usual definition in an ABI supplement uses the name auxv_t.  The
+   vector is not usually defined in a standard <elf.h> file, but it
+   can't hurt.  We rename it to avoid conflicts.  The sizes of these
+   types are an arrangement between the exec server and the program
+   interpreter, so we don't fully specify them here.  */
+
+typedef struct
+{
+  int a_type;                  /* Entry type */
+  union
+    {
+      long int a_val;          /* Integer value */
+      void *a_ptr;             /* Pointer value */
+      void (*a_fcn) (void);    /* Function pointer value */
+    } a_un;
+} Elf32_auxv_t;
+
+typedef struct
+{
+  long int a_type;             /* Entry type */
+  union
+    {
+      long int a_val;          /* Integer value */
+      void *a_ptr;             /* Pointer value */
+      void (*a_fcn) (void);    /* Function pointer value */
+    } a_un;
+} Elf64_auxv_t;
+
+/* Legal values for a_type (entry type).  */
+
+#define AT_NULL                0               /* End of vector */
+#define AT_IGNORE      1               /* Entry should be ignored */
+#define AT_EXECFD      2               /* File descriptor of program */
+#define AT_PHDR                3               /* Program headers for program */
+#define AT_PHENT       4               /* Size of program header entry */
+#define AT_PHNUM       5               /* Number of program headers */
+#define AT_PAGESZ      6               /* System page size */
+#define AT_BASE                7               /* Base address of interpreter */
+#define AT_FLAGS       8               /* Flags */
+#define AT_ENTRY       9               /* Entry point of program */
+#define AT_NOTELF      10              /* Program is not ELF */
+#define AT_UID         11              /* Real uid */
+#define AT_EUID                12              /* Effective uid */
+#define AT_GID         13              /* Real gid */
+#define AT_EGID                14              /* Effective gid */
+#define AT_CLKTCK      17              /* Frequency of times() */
+
+/* Some more special a_type values describing the hardware.  */
+#define AT_PLATFORM    15              /* String identifying platform.  */
+#define AT_HWCAP       16              /* Machine dependent hints about
+                                          processor capabilities.  */
+
+/* This entry gives some information about the FPU initialization
+   performed by the kernel.  */
+#define AT_FPUCW       18              /* Used FPU control word.  */
+
+/* Cache block sizes.  */
+#define AT_DCACHEBSIZE 19              /* Data cache block size.  */
+#define AT_ICACHEBSIZE 20              /* Instruction cache block size.  */
+#define AT_UCACHEBSIZE 21              /* Unified cache block size.  */
+
+/* A special ignored value for PPC, used by the kernel to control the
+   interpretation of the AUXV. Must be > 16.  */
+#define AT_IGNOREPPC   22              /* Entry should be ignored */
+
+
+/* Note section contents.  Each entry in the note section begins with
+   a header of a fixed form.  */
+
+typedef struct
+{
+  Elf32_Word n_namesz;                 /* Length of the note's name.  */
+  Elf32_Word n_descsz;                 /* Length of the note's descriptor.  */
+  Elf32_Word n_type;                   /* Type of the note.  */
+} Elf32_Nhdr;
+
+typedef struct
+{
+  Elf64_Word n_namesz;                 /* Length of the note's name.  */
+  Elf64_Word n_descsz;                 /* Length of the note's descriptor.  */
+  Elf64_Word n_type;                   /* Type of the note.  */
+} Elf64_Nhdr;
+
+/* Known names of notes.  */
+
+/* Solaris entries in the note section have this name.  */
+#define ELF_NOTE_SOLARIS       "SUNW Solaris"
+
+/* Note entries for GNU systems have this name.  */
+#define ELF_NOTE_GNU           "GNU"
+
+
+/* Defined types of notes for Solaris.  */
+
+/* Value of descriptor (one word) is desired pagesize for the binary.  */
+#define ELF_NOTE_PAGESIZE_HINT 1
+
+
+/* Defined note types for GNU systems.  */
+
+/* ABI information.  The descriptor consists of words:
+   word 0: OS descriptor
+   word 1: major version of the ABI
+   word 2: minor version of the ABI
+   word 3: subminor version of the ABI
+*/
+#define ELF_NOTE_ABI           1
+
+/* Known OSes.  These value can appear in word 0 of an ELF_NOTE_ABI
+   note section entry.  */
+#define ELF_NOTE_OS_LINUX      0
+#define ELF_NOTE_OS_GNU                1
+#define ELF_NOTE_OS_SOLARIS2   2
+
+
+/* Move records.  */
+typedef struct
+{
+  Elf32_Xword m_value;         /* Symbol value.  */
+  Elf32_Word m_info;           /* Size and index.  */
+  Elf32_Word m_poffset;                /* Symbol offset.  */
+  Elf32_Half m_repeat;         /* Repeat count.  */
+  Elf32_Half m_stride;         /* Stride info.  */
+} Elf32_Move;
+
+typedef struct
+{
+  Elf64_Xword m_value;         /* Symbol value.  */
+  Elf64_Xword m_info;          /* Size and index.  */
+  Elf64_Xword m_poffset;       /* Symbol offset.  */
+  Elf64_Half m_repeat;         /* Repeat count.  */
+  Elf64_Half m_stride;         /* Stride info.  */
+} Elf64_Move;
+
+/* Macro to construct move records.  */
+#define ELF32_M_SYM(info)      ((info) >> 8)
+#define ELF32_M_SIZE(info)     ((unsigned char) (info))
+#define ELF32_M_INFO(sym, size)        (((sym) << 8) + (unsigned char) (size))
+
+#define ELF64_M_SYM(info)      ELF32_M_SYM (info)
+#define ELF64_M_SIZE(info)     ELF32_M_SIZE (info)
+#define ELF64_M_INFO(sym, size)        ELF32_M_INFO (sym, size)
+
+
+/* Motorola 68k specific definitions.  */
+
+/* Values for Elf32_Ehdr.e_flags.  */
+#define EF_CPU32       0x00810000
+
+/* m68k relocs.  */
+
+#define R_68K_NONE     0               /* No reloc */
+#define R_68K_32       1               /* Direct 32 bit  */
+#define R_68K_16       2               /* Direct 16 bit  */
+#define R_68K_8                3               /* Direct 8 bit  */
+#define R_68K_PC32     4               /* PC relative 32 bit */
+#define R_68K_PC16     5               /* PC relative 16 bit */
+#define R_68K_PC8      6               /* PC relative 8 bit */
+#define R_68K_GOT32    7               /* 32 bit PC relative GOT entry */
+#define R_68K_GOT16    8               /* 16 bit PC relative GOT entry */
+#define R_68K_GOT8     9               /* 8 bit PC relative GOT entry */
+#define R_68K_GOT32O   10              /* 32 bit GOT offset */
+#define R_68K_GOT16O   11              /* 16 bit GOT offset */
+#define R_68K_GOT8O    12              /* 8 bit GOT offset */
+#define R_68K_PLT32    13              /* 32 bit PC relative PLT address */
+#define R_68K_PLT16    14              /* 16 bit PC relative PLT address */
+#define R_68K_PLT8     15              /* 8 bit PC relative PLT address */
+#define R_68K_PLT32O   16              /* 32 bit PLT offset */
+#define R_68K_PLT16O   17              /* 16 bit PLT offset */
+#define R_68K_PLT8O    18              /* 8 bit PLT offset */
+#define R_68K_COPY     19              /* Copy symbol at runtime */
+#define R_68K_GLOB_DAT 20              /* Create GOT entry */
+#define R_68K_JMP_SLOT 21              /* Create PLT entry */
+#define R_68K_RELATIVE 22              /* Adjust by program base */
+/* Keep this the last entry.  */
+#define R_68K_NUM      23
+
+/* Intel 80386 specific definitions.  */
+
+/* i386 relocs.  */
+
+#define R_386_NONE        0            /* No reloc */
+#define R_386_32          1            /* Direct 32 bit  */
+#define R_386_PC32        2            /* PC relative 32 bit */
+#define R_386_GOT32       3            /* 32 bit GOT entry */
+#define R_386_PLT32       4            /* 32 bit PLT address */
+#define R_386_COPY        5            /* Copy symbol at runtime */
+#define R_386_GLOB_DAT    6            /* Create GOT entry */
+#define R_386_JMP_SLOT    7            /* Create PLT entry */
+#define R_386_RELATIVE    8            /* Adjust by program base */
+#define R_386_GOTOFF      9            /* 32 bit offset to GOT */
+#define R_386_GOTPC       10           /* 32 bit PC relative offset to GOT */
+#define R_386_32PLT       11
+#define R_386_TLS_TPOFF           14           /* Offset in static TLS block */
+#define R_386_TLS_IE      15           /* Address of GOT entry for static TLS
+                                          block offset */
+#define R_386_TLS_GOTIE           16           /* GOT entry for static TLS block
+                                          offset */
+#define R_386_TLS_LE      17           /* Offset relative to static TLS
+                                          block */
+#define R_386_TLS_GD      18           /* Direct 32 bit for GNU version of
+                                          general dynamic thread local data */
+#define R_386_TLS_LDM     19           /* Direct 32 bit for GNU version of
+                                          local dynamic thread local data
+                                          in LE code */
+#define R_386_16          20
+#define R_386_PC16        21
+#define R_386_8                   22
+#define R_386_PC8         23
+#define R_386_TLS_GD_32           24           /* Direct 32 bit for general dynamic
+                                          thread local data */
+#define R_386_TLS_GD_PUSH  25          /* Tag for pushl in GD TLS code */
+#define R_386_TLS_GD_CALL  26          /* Relocation for call to
+                                          __tls_get_addr() */
+#define R_386_TLS_GD_POP   27          /* Tag for popl in GD TLS code */
+#define R_386_TLS_LDM_32   28          /* Direct 32 bit for local dynamic
+                                          thread local data in LE code */
+#define R_386_TLS_LDM_PUSH 29          /* Tag for pushl in LDM TLS code */
+#define R_386_TLS_LDM_CALL 30          /* Relocation for call to
+                                          __tls_get_addr() in LDM code */
+#define R_386_TLS_LDM_POP  31          /* Tag for popl in LDM TLS code */
+#define R_386_TLS_LDO_32   32          /* Offset relative to TLS block */
+#define R_386_TLS_IE_32           33           /* GOT entry for negated static TLS
+                                          block offset */
+#define R_386_TLS_LE_32           34           /* Negated offset relative to static
+                                          TLS block */
+#define R_386_TLS_DTPMOD32 35          /* ID of module containing symbol */
+#define R_386_TLS_DTPOFF32 36          /* Offset in TLS block */
+#define R_386_TLS_TPOFF32  37          /* Negated offset in static TLS block */
+/* Keep this the last entry.  */
+#define R_386_NUM         38
+
+
+/* SUN SPARC specific definitions.  */
+
+/* x86_64 specific definitions.  */
+#define R_X86_64_NONE          0
+#define R_X86_64_64            1
+#define R_X86_64_PC32          2
+#define R_X86_64_GOT32         3
+#define R_X86_64_PLT32         4
+#define R_X86_64_COPY          5
+#define R_X86_64_GLOB_DAT      6
+#define R_X86_64_JUMP_SLOT     7
+#define R_X86_64_RELATIVE      8
+#define R_X86_64_GOTPCREL      9
+#define R_X86_64_32            10
+#define R_X86_64_32S           11
+#define R_X86_64_16            12
+#define R_X86_64_PC16          13
+#define R_X86_64_8             14
+#define R_X86_64_PC8           15
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_REGISTER   13              /* Global register reserved to app. */
+
+/* Values for Elf64_Ehdr.e_flags.  */
+
+#define EF_SPARCV9_MM          3
+#define EF_SPARCV9_TSO         0
+#define EF_SPARCV9_PSO         1
+#define EF_SPARCV9_RMO         2
+#define EF_SPARC_LEDATA                0x800000 /* little endian data */
+#define EF_SPARC_EXT_MASK      0xFFFF00
+#define EF_SPARC_32PLUS                0x000100 /* generic V8+ features */
+#define EF_SPARC_SUN_US1       0x000200 /* Sun UltraSPARC1 extensions */
+#define EF_SPARC_HAL_R1                0x000400 /* HAL R1 extensions */
+#define EF_SPARC_SUN_US3       0x000800 /* Sun UltraSPARCIII extensions */
+
+/* SPARC relocs.  */
+
+#define R_SPARC_NONE           0       /* No reloc */
+#define R_SPARC_8              1       /* Direct 8 bit */
+#define R_SPARC_16             2       /* Direct 16 bit */
+#define R_SPARC_32             3       /* Direct 32 bit */
+#define R_SPARC_DISP8          4       /* PC relative 8 bit */
+#define R_SPARC_DISP16         5       /* PC relative 16 bit */
+#define R_SPARC_DISP32         6       /* PC relative 32 bit */
+#define R_SPARC_WDISP30                7       /* PC relative 30 bit shifted */
+#define R_SPARC_WDISP22                8       /* PC relative 22 bit shifted */
+#define R_SPARC_HI22           9       /* High 22 bit */
+#define R_SPARC_22             10      /* Direct 22 bit */
+#define R_SPARC_13             11      /* Direct 13 bit */
+#define R_SPARC_LO10           12      /* Truncated 10 bit */
+#define R_SPARC_GOT10          13      /* Truncated 10 bit GOT entry */
+#define R_SPARC_GOT13          14      /* 13 bit GOT entry */
+#define R_SPARC_GOT22          15      /* 22 bit GOT entry shifted */
+#define R_SPARC_PC10           16      /* PC relative 10 bit truncated */
+#define R_SPARC_PC22           17      /* PC relative 22 bit shifted */
+#define R_SPARC_WPLT30         18      /* 30 bit PC relative PLT address */
+#define R_SPARC_COPY           19      /* Copy symbol at runtime */
+#define R_SPARC_GLOB_DAT       20      /* Create GOT entry */
+#define R_SPARC_JMP_SLOT       21      /* Create PLT entry */
+#define R_SPARC_RELATIVE       22      /* Adjust by program base */
+#define R_SPARC_UA32           23      /* Direct 32 bit unaligned */
+
+/* Additional Sparc64 relocs.  */
+
+#define R_SPARC_PLT32          24      /* Direct 32 bit ref to PLT entry */
+#define R_SPARC_HIPLT22                25      /* High 22 bit PLT entry */
+#define R_SPARC_LOPLT10                26      /* Truncated 10 bit PLT entry */
+#define R_SPARC_PCPLT32                27      /* PC rel 32 bit ref to PLT entry */
+#define R_SPARC_PCPLT22                28      /* PC rel high 22 bit PLT entry */
+#define R_SPARC_PCPLT10                29      /* PC rel trunc 10 bit PLT entry */
+#define R_SPARC_10             30      /* Direct 10 bit */
+#define R_SPARC_11             31      /* Direct 11 bit */
+#define R_SPARC_64             32      /* Direct 64 bit */
+#define R_SPARC_OLO10          33      /* 10bit with secondary 13bit addend */
+#define R_SPARC_HH22           34      /* Top 22 bits of direct 64 bit */
+#define R_SPARC_HM10           35      /* High middle 10 bits of ... */
+#define R_SPARC_LM22           36      /* Low middle 22 bits of ... */
+#define R_SPARC_PC_HH22                37      /* Top 22 bits of pc rel 64 bit */
+#define R_SPARC_PC_HM10                38      /* High middle 10 bit of ... */
+#define R_SPARC_PC_LM22                39      /* Low middle 22 bits of ... */
+#define R_SPARC_WDISP16                40      /* PC relative 16 bit shifted */
+#define R_SPARC_WDISP19                41      /* PC relative 19 bit shifted */
+#define R_SPARC_7              43      /* Direct 7 bit */
+#define R_SPARC_5              44      /* Direct 5 bit */
+#define R_SPARC_6              45      /* Direct 6 bit */
+#define R_SPARC_DISP64         46      /* PC relative 64 bit */
+#define R_SPARC_PLT64          47      /* Direct 64 bit ref to PLT entry */
+#define R_SPARC_HIX22          48      /* High 22 bit complemented */
+#define R_SPARC_LOX10          49      /* Truncated 11 bit complemented */
+#define R_SPARC_H44            50      /* Direct high 12 of 44 bit */
+#define R_SPARC_M44            51      /* Direct mid 22 of 44 bit */
+#define R_SPARC_L44            52      /* Direct low 10 of 44 bit */
+#define R_SPARC_REGISTER       53      /* Global register usage */
+#define R_SPARC_UA64           54      /* Direct 64 bit unaligned */
+#define R_SPARC_UA16           55      /* Direct 16 bit unaligned */
+#define R_SPARC_TLS_GD_HI22    56
+#define R_SPARC_TLS_GD_LO10    57
+#define R_SPARC_TLS_GD_ADD     58
+#define R_SPARC_TLS_GD_CALL    59
+#define R_SPARC_TLS_LDM_HI22   60
+#define R_SPARC_TLS_LDM_LO10   61
+#define R_SPARC_TLS_LDM_ADD    62
+#define R_SPARC_TLS_LDM_CALL   63
+#define R_SPARC_TLS_LDO_HIX22  64
+#define R_SPARC_TLS_LDO_LOX10  65
+#define R_SPARC_TLS_LDO_ADD    66
+#define R_SPARC_TLS_IE_HI22    67
+#define R_SPARC_TLS_IE_LO10    68
+#define R_SPARC_TLS_IE_LD      69
+#define R_SPARC_TLS_IE_LDX     70
+#define R_SPARC_TLS_IE_ADD     71
+#define R_SPARC_TLS_LE_HIX22   72
+#define R_SPARC_TLS_LE_LOX10   73
+#define R_SPARC_TLS_DTPMOD32   74
+#define R_SPARC_TLS_DTPMOD64   75
+#define R_SPARC_TLS_DTPOFF32   76
+#define R_SPARC_TLS_DTPOFF64   77
+#define R_SPARC_TLS_TPOFF32    78
+#define R_SPARC_TLS_TPOFF64    79
+/* Keep this the last entry.  */
+#define R_SPARC_NUM            80
+
+/* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_SPARC_NUM   2
+
+/* Bits present in AT_HWCAP, primarily for Sparc32.  */
+
+#define HWCAP_SPARC_FLUSH      1       /* The cpu supports flush insn.  */
+#define HWCAP_SPARC_STBAR      2
+#define HWCAP_SPARC_SWAP       4
+#define HWCAP_SPARC_MULDIV     8
+#define HWCAP_SPARC_V9         16      /* The cpu is v9, so v8plus is ok.  */
+#define HWCAP_SPARC_ULTRA3     32
+
+/* MIPS R3000 specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_MIPS_NOREORDER   1          /* A .noreorder directive was used */
+#define EF_MIPS_PIC        2           /* Contains PIC code */
+#define EF_MIPS_CPIC       4           /* Uses PIC calling sequence */
+#define EF_MIPS_XGOT       8
+#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_ABI2       32
+#define EF_MIPS_ABI_ON32    64
+#define EF_MIPS_ARCH       0xf0000000  /* MIPS architecture level */
+
+/* Legal values for MIPS architecture level.  */
+
+#define EF_MIPS_ARCH_1     0x00000000  /* -mips1 code.  */
+#define EF_MIPS_ARCH_2     0x10000000  /* -mips2 code.  */
+#define EF_MIPS_ARCH_3     0x20000000  /* -mips3 code.  */
+#define EF_MIPS_ARCH_4     0x30000000  /* -mips4 code.  */
+#define EF_MIPS_ARCH_5     0x40000000  /* -mips5 code.  */
+#define EF_MIPS_ARCH_32            0x60000000  /* MIPS32 code.  */
+#define EF_MIPS_ARCH_64            0x70000000  /* MIPS64 code.  */
+
+/* The following are non-official names and should not be used.  */
+
+#define E_MIPS_ARCH_1    0x00000000    /* -mips1 code.  */
+#define E_MIPS_ARCH_2    0x10000000    /* -mips2 code.  */
+#define E_MIPS_ARCH_3    0x20000000    /* -mips3 code.  */
+#define E_MIPS_ARCH_4    0x30000000    /* -mips4 code.  */
+#define E_MIPS_ARCH_5    0x40000000    /* -mips5 code.  */
+#define E_MIPS_ARCH_32   0x60000000    /* MIPS32 code.  */
+#define E_MIPS_ARCH_64   0x70000000    /* MIPS64 code.  */
+
+/* Special section indices.  */
+
+#define SHN_MIPS_ACOMMON    0xff00     /* Allocated common symbols */
+#define SHN_MIPS_TEXT      0xff01      /* Allocated test symbols.  */
+#define SHN_MIPS_DATA      0xff02      /* Allocated data symbols.  */
+#define SHN_MIPS_SCOMMON    0xff03     /* Small common symbols */
+#define SHN_MIPS_SUNDEFINED 0xff04     /* Small undefined symbols */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
+#define SHT_MIPS_MSYM         0x70000001
+#define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
+#define SHT_MIPS_GPTAB        0x70000003 /* Global data area sizes */
+#define SHT_MIPS_UCODE        0x70000004 /* Reserved for SGI/MIPS compilers */
+#define SHT_MIPS_DEBUG        0x70000005 /* MIPS ECOFF debugging information*/
+#define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
+#define SHT_MIPS_PACKAGE       0x70000007
+#define SHT_MIPS_PACKSYM       0x70000008
+#define SHT_MIPS_RELD         0x70000009
+#define SHT_MIPS_IFACE         0x7000000b
+#define SHT_MIPS_CONTENT       0x7000000c
+#define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
+#define SHT_MIPS_SHDR         0x70000010
+#define SHT_MIPS_FDESC        0x70000011
+#define SHT_MIPS_EXTSYM               0x70000012
+#define SHT_MIPS_DENSE        0x70000013
+#define SHT_MIPS_PDESC        0x70000014
+#define SHT_MIPS_LOCSYM               0x70000015
+#define SHT_MIPS_AUXSYM               0x70000016
+#define SHT_MIPS_OPTSYM               0x70000017
+#define SHT_MIPS_LOCSTR               0x70000018
+#define SHT_MIPS_LINE         0x70000019
+#define SHT_MIPS_RFDESC               0x7000001a
+#define SHT_MIPS_DELTASYM      0x7000001b
+#define SHT_MIPS_DELTAINST     0x7000001c
+#define SHT_MIPS_DELTACLASS    0x7000001d
+#define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
+#define SHT_MIPS_DELTADECL     0x7000001f
+#define SHT_MIPS_SYMBOL_LIB    0x70000020
+#define SHT_MIPS_EVENTS               0x70000021 /* Event section.  */
+#define SHT_MIPS_TRANSLATE     0x70000022
+#define SHT_MIPS_PIXIE        0x70000023
+#define SHT_MIPS_XLATE        0x70000024
+#define SHT_MIPS_XLATE_DEBUG   0x70000025
+#define SHT_MIPS_WHIRL        0x70000026
+#define SHT_MIPS_EH_REGION     0x70000027
+#define SHT_MIPS_XLATE_OLD     0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_MIPS_GPREL  0x10000000     /* Must be part of global data area */
+#define SHF_MIPS_MERGE  0x20000000
+#define SHF_MIPS_ADDR   0x40000000
+#define SHF_MIPS_STRINGS 0x80000000
+#define SHF_MIPS_NOSTRIP 0x08000000
+#define SHF_MIPS_LOCAL  0x04000000
+#define SHF_MIPS_NAMES  0x02000000
+#define SHF_MIPS_NODUPE         0x01000000
+
+
+/* Symbol tables.  */
+
+/* MIPS specific values for `st_other'.  */
+#define STO_MIPS_DEFAULT               0x0
+#define STO_MIPS_INTERNAL              0x1
+#define STO_MIPS_HIDDEN                        0x2
+#define STO_MIPS_PROTECTED             0x3
+#define STO_MIPS_SC_ALIGN_UNUSED       0xff
+
+/* MIPS specific values for `st_info'.  */
+#define STB_MIPS_SPLIT_COMMON          13
+
+/* Entries found in sections of type SHT_MIPS_GPTAB.  */
+
+typedef union
+{
+  struct
+    {
+      Elf32_Word gt_current_g_value;   /* -G value used for compilation */
+      Elf32_Word gt_unused;            /* Not used */
+    } gt_header;                       /* First entry in section */
+  struct
+    {
+      Elf32_Word gt_g_value;           /* If this value were used for -G */
+      Elf32_Word gt_bytes;             /* This many bytes would be used */
+    } gt_entry;                                /* Subsequent entries in section */
+} Elf32_gptab;
+
+/* Entry found in sections of type SHT_MIPS_REGINFO.  */
+
+typedef struct
+{
+  Elf32_Word   ri_gprmask;             /* General registers used */
+  Elf32_Word   ri_cprmask[4];          /* Coprocessor registers used */
+  Elf32_Sword  ri_gp_value;            /* $gp register value */
+} Elf32_RegInfo;
+
+/* Entries found in sections of type SHT_MIPS_OPTIONS.  */
+
+typedef struct
+{
+  unsigned char kind;          /* Determines interpretation of the
+                                  variable part of descriptor.  */
+  unsigned char size;          /* Size of descriptor, including header.  */
+  Elf32_Section section;       /* Section header index of section affected,
+                                  0 for global options.  */
+  Elf32_Word info;             /* Kind-specific information.  */
+} Elf_Options;
+
+/* Values for `kind' field in Elf_Options.  */
+
+#define ODK_NULL       0       /* Undefined.  */
+#define ODK_REGINFO    1       /* Register usage information.  */
+#define ODK_EXCEPTIONS 2       /* Exception processing options.  */
+#define ODK_PAD                3       /* Section padding options.  */
+#define ODK_HWPATCH    4       /* Hardware workarounds performed */
+#define ODK_FILL       5       /* record the fill value used by the linker. */
+#define ODK_TAGS       6       /* reserve space for desktop tools to write. */
+#define ODK_HWAND      7       /* HW workarounds.  'AND' bits when merging. */
+#define ODK_HWOR       8       /* HW workarounds.  'OR' bits when merging.  */
+
+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
+
+#define OEX_FPU_MIN    0x1f    /* FPE's which MUST be enabled.  */
+#define OEX_FPU_MAX    0x1f00  /* FPE's which MAY be enabled.  */
+#define OEX_PAGE0      0x10000 /* page zero must be mapped.  */
+#define OEX_SMM                0x20000 /* Force sequential memory mode?  */
+#define OEX_FPDBUG     0x40000 /* Force floating point debug mode?  */
+#define OEX_PRECISEFP  OEX_FPDBUG
+#define OEX_DISMISS    0x80000 /* Dismiss invalid address faults?  */
+
+#define OEX_FPU_INVAL  0x10
+#define OEX_FPU_DIV0   0x08
+#define OEX_FPU_OFLO   0x04
+#define OEX_FPU_UFLO   0x02
+#define OEX_FPU_INEX   0x01
+
+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
+
+#define OHW_R4KEOP     0x1     /* R4000 end-of-page patch.  */
+#define OHW_R8KPFETCH  0x2     /* may need R8000 prefetch patch.  */
+#define OHW_R5KEOP     0x4     /* R5000 end-of-page patch.  */
+#define OHW_R5KCVTL    0x8     /* R5000 cvt.[ds].l bug.  clean=1.  */
+
+#define OPAD_PREFIX    0x1
+#define OPAD_POSTFIX   0x2
+#define OPAD_SYMBOL    0x4
+
+/* Entry found in `.options' section.  */
+
+typedef struct
+{
+  Elf32_Word hwp_flags1;       /* Extra flags.  */
+  Elf32_Word hwp_flags2;       /* Extra flags.  */
+} Elf_Options_Hw;
+
+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
+
+#define OHWA0_R4KEOP_CHECKED   0x00000001
+#define OHWA1_R4KEOP_CLEAN     0x00000002
+
+/* MIPS relocs.  */
+
+#define R_MIPS_NONE            0       /* No reloc */
+#define R_MIPS_16              1       /* Direct 16 bit */
+#define R_MIPS_32              2       /* Direct 32 bit */
+#define R_MIPS_REL32           3       /* PC relative 32 bit */
+#define R_MIPS_26              4       /* Direct 26 bit shifted */
+#define R_MIPS_HI16            5       /* High 16 bit */
+#define R_MIPS_LO16            6       /* Low 16 bit */
+#define R_MIPS_GPREL16         7       /* GP relative 16 bit */
+#define R_MIPS_LITERAL         8       /* 16 bit literal entry */
+#define R_MIPS_GOT16           9       /* 16 bit GOT entry */
+#define R_MIPS_PC16            10      /* PC relative 16 bit */
+#define R_MIPS_CALL16          11      /* 16 bit GOT entry for function */
+#define R_MIPS_GPREL32         12      /* GP relative 32 bit */
+
+#define R_MIPS_SHIFT5          16
+#define R_MIPS_SHIFT6          17
+#define R_MIPS_64              18
+#define R_MIPS_GOT_DISP                19
+#define R_MIPS_GOT_PAGE                20
+#define R_MIPS_GOT_OFST                21
+#define R_MIPS_GOT_HI16                22
+#define R_MIPS_GOT_LO16                23
+#define R_MIPS_SUB             24
+#define R_MIPS_INSERT_A                25
+#define R_MIPS_INSERT_B                26
+#define R_MIPS_DELETE          27
+#define R_MIPS_HIGHER          28
+#define R_MIPS_HIGHEST         29
+#define R_MIPS_CALL_HI16       30
+#define R_MIPS_CALL_LO16       31
+#define R_MIPS_SCN_DISP                32
+#define R_MIPS_REL16           33
+#define R_MIPS_ADD_IMMEDIATE   34
+#define R_MIPS_PJUMP           35
+#define R_MIPS_RELGOT          36
+#define R_MIPS_JALR            37
+/* Keep this the last entry.  */
+#define R_MIPS_NUM             38
+
+/* Legal values for p_type field of Elf32_Phdr.  */
+
+#define PT_MIPS_REGINFO        0x70000000      /* Register usage information */
+#define PT_MIPS_RTPROC  0x70000001     /* Runtime procedure table. */
+#define PT_MIPS_OPTIONS 0x70000002
+
+/* Special program header types.  */
+
+#define PF_MIPS_LOCAL  0x10000000
+
+/* Legal values for d_tag field of Elf32_Dyn.  */
+
+#define DT_MIPS_RLD_VERSION  0x70000001        /* Runtime linker interface version */
+#define DT_MIPS_TIME_STAMP   0x70000002        /* Timestamp */
+#define DT_MIPS_ICHECKSUM    0x70000003        /* Checksum */
+#define DT_MIPS_IVERSION     0x70000004        /* Version string (string tbl index) */
+#define DT_MIPS_FLAGS       0x70000005 /* Flags */
+#define DT_MIPS_BASE_ADDRESS 0x70000006        /* Base address */
+#define DT_MIPS_MSYM        0x70000007
+#define DT_MIPS_CONFLICT     0x70000008        /* Address of CONFLICT section */
+#define DT_MIPS_LIBLIST             0x70000009 /* Address of LIBLIST section */
+#define DT_MIPS_LOCAL_GOTNO  0x7000000a        /* Number of local GOT entries */
+#define DT_MIPS_CONFLICTNO   0x7000000b        /* Number of CONFLICT entries */
+#define DT_MIPS_LIBLISTNO    0x70000010        /* Number of LIBLIST entries */
+#define DT_MIPS_SYMTABNO     0x70000011        /* Number of DYNSYM entries */
+#define DT_MIPS_UNREFEXTNO   0x70000012        /* First external DYNSYM */
+#define DT_MIPS_GOTSYM      0x70000013 /* First GOT entry in DYNSYM */
+#define DT_MIPS_HIPAGENO     0x70000014        /* Number of GOT page table entries */
+#define DT_MIPS_RLD_MAP             0x70000016 /* Address of run time loader map.  */
+#define DT_MIPS_DELTA_CLASS  0x70000017        /* Delta C++ class definition.  */
+#define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
+                                               DT_MIPS_DELTA_CLASS.  */
+#define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
+                                               DT_MIPS_DELTA_INSTANCE.  */
+#define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
+                                            DT_MIPS_DELTA_RELOC.  */
+#define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
+                                          relocations refer to.  */
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
+                                          DT_MIPS_DELTA_SYM.  */
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
+                                            class declaration.  */
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
+                                               DT_MIPS_DELTA_CLASSSYM.  */
+#define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
+#define DT_MIPS_PIXIE_INIT   0x70000023
+#define DT_MIPS_SYMBOL_LIB   0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS             0x70000029 /* Address of .options.  */
+#define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
+                                                   function stored in GOT.  */
+#define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
+                                          by rld on dlopen() calls.  */
+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
+#define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
+#define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
+#define DT_MIPS_NUM         0x32
+
+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
+
+#define RHF_NONE                  0            /* No flags */
+#define RHF_QUICKSTART            (1 << 0)     /* Use quickstart */
+#define RHF_NOTPOT                (1 << 1)     /* Hash size not power of 2 */
+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)    /* Ignore LD_LIBRARY_PATH */
+#define RHF_NO_MOVE               (1 << 3)
+#define RHF_SGI_ONLY              (1 << 4)
+#define RHF_GUARANTEE_INIT        (1 << 5)
+#define RHF_DELTA_C_PLUS_PLUS     (1 << 6)
+#define RHF_GUARANTEE_START_INIT   (1 << 7)
+#define RHF_PIXIE                 (1 << 8)
+#define RHF_DEFAULT_DELAY_LOAD    (1 << 9)
+#define RHF_REQUICKSTART          (1 << 10)
+#define RHF_REQUICKSTARTED        (1 << 11)
+#define RHF_CORD                  (1 << 12)
+#define RHF_NO_UNRES_UNDEF        (1 << 13)
+#define RHF_RLD_ORDER_SAFE        (1 << 14)
+
+/* Entries found in sections of type SHT_MIPS_LIBLIST.  */
+
+typedef struct
+{
+  Elf32_Word l_name;           /* Name (string table index) */
+  Elf32_Word l_time_stamp;     /* Timestamp */
+  Elf32_Word l_checksum;       /* Checksum */
+  Elf32_Word l_version;                /* Interface version */
+  Elf32_Word l_flags;          /* Flags */
+} Elf32_Lib;
+
+typedef struct
+{
+  Elf64_Word l_name;           /* Name (string table index) */
+  Elf64_Word l_time_stamp;     /* Timestamp */
+  Elf64_Word l_checksum;       /* Checksum */
+  Elf64_Word l_version;                /* Interface version */
+  Elf64_Word l_flags;          /* Flags */
+} Elf64_Lib;
+
+
+/* Legal values for l_flags.  */
+
+#define LL_NONE                  0
+#define LL_EXACT_MATCH   (1 << 0)      /* Require exact match */
+#define LL_IGNORE_INT_VER (1 << 1)     /* Ignore interface version */
+#define LL_REQUIRE_MINOR  (1 << 2)
+#define LL_EXPORTS       (1 << 3)
+#define LL_DELAY_LOAD    (1 << 4)
+#define LL_DELTA         (1 << 5)
+
+/* Entries found in sections of type SHT_MIPS_CONFLICT.  */
+
+typedef Elf32_Addr Elf32_Conflict;
+
+
+/* HPPA specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_PARISC_TRAPNIL      0x00010000 /* Trap nil pointer dereference.  */
+#define EF_PARISC_EXT          0x00020000 /* Program uses arch. extensions. */
+#define EF_PARISC_LSB          0x00040000 /* Program expects little endian. */
+#define EF_PARISC_WIDE         0x00080000 /* Program expects wide mode.  */
+#define EF_PARISC_NO_KABP      0x00100000 /* No kernel assisted branch
+                                             prediction.  */
+#define EF_PARISC_LAZYSWAP     0x00400000 /* Allow lazy swapping.  */
+#define EF_PARISC_ARCH         0x0000ffff /* Architecture version.  */
+
+/* Defined values for `e_flags & EF_PARISC_ARCH' are:  */
+
+#define EFA_PARISC_1_0             0x020b /* PA-RISC 1.0 big-endian.  */
+#define EFA_PARISC_1_1             0x0210 /* PA-RISC 1.1 big-endian.  */
+#define EFA_PARISC_2_0             0x0214 /* PA-RISC 2.0 big-endian.  */
+
+/* Additional section indices.  */
+
+#define SHN_PARISC_ANSI_COMMON 0xff00     /* Section for tentatively declared
+                                             symbols in ANSI C.  */
+#define SHN_PARISC_HUGE_COMMON 0xff01     /* Common blocks in huge model.  */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_PARISC_EXT         0x70000000 /* Contains product specific ext. */
+#define SHT_PARISC_UNWIND      0x70000001 /* Unwind information.  */
+#define SHT_PARISC_DOC         0x70000002 /* Debug info for optimized code. */
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_PARISC_SHORT       0x20000000 /* Section with short addressing. */
+#define SHF_PARISC_HUGE                0x40000000 /* Section far from gp.  */
+#define SHF_PARISC_SBP         0x80000000 /* Static branch prediction code. */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_PARISC_MILLICODE   13      /* Millicode function entry point.  */
+
+#define STT_HP_OPAQUE          (STT_LOOS + 0x1)
+#define STT_HP_STUB            (STT_LOOS + 0x2)
+
+/* HPPA relocs.  */
+
+#define R_PARISC_NONE          0       /* No reloc.  */
+#define R_PARISC_DIR32         1       /* Direct 32-bit reference.  */
+#define R_PARISC_DIR21L                2       /* Left 21 bits of eff. address.  */
+#define R_PARISC_DIR17R                3       /* Right 17 bits of eff. address.  */
+#define R_PARISC_DIR17F                4       /* 17 bits of eff. address.  */
+#define R_PARISC_DIR14R                6       /* Right 14 bits of eff. address.  */
+#define R_PARISC_PCREL32       9       /* 32-bit rel. address.  */
+#define R_PARISC_PCREL21L      10      /* Left 21 bits of rel. address.  */
+#define R_PARISC_PCREL17R      11      /* Right 17 bits of rel. address.  */
+#define R_PARISC_PCREL17F      12      /* 17 bits of rel. address.  */
+#define R_PARISC_PCREL14R      14      /* Right 14 bits of rel. address.  */
+#define R_PARISC_DPREL21L      18      /* Left 21 bits of rel. address.  */
+#define R_PARISC_DPREL14R      22      /* Right 14 bits of rel. address.  */
+#define R_PARISC_GPREL21L      26      /* GP-relative, left 21 bits.  */
+#define R_PARISC_GPREL14R      30      /* GP-relative, right 14 bits.  */
+#define R_PARISC_LTOFF21L      34      /* LT-relative, left 21 bits.  */
+#define R_PARISC_LTOFF14R      38      /* LT-relative, right 14 bits.  */
+#define R_PARISC_SECREL32      41      /* 32 bits section rel. address.  */
+#define R_PARISC_SEGBASE       48      /* No relocation, set segment base.  */
+#define R_PARISC_SEGREL32      49      /* 32 bits segment rel. address.  */
+#define R_PARISC_PLTOFF21L     50      /* PLT rel. address, left 21 bits.  */
+#define R_PARISC_PLTOFF14R     54      /* PLT rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_FPTR32  57      /* 32 bits LT-rel. function pointer. */
+#define R_PARISC_LTOFF_FPTR21L 58      /* LT-rel. fct ptr, left 21 bits. */
+#define R_PARISC_LTOFF_FPTR14R 62      /* LT-rel. fct ptr, right 14 bits. */
+#define R_PARISC_FPTR64                64      /* 64 bits function address.  */
+#define R_PARISC_PLABEL32      65      /* 32 bits function address.  */
+#define R_PARISC_PCREL64       72      /* 64 bits PC-rel. address.  */
+#define R_PARISC_PCREL22F      74      /* 22 bits PC-rel. address.  */
+#define R_PARISC_PCREL14WR     75      /* PC-rel. address, right 14 bits.  */
+#define R_PARISC_PCREL14DR     76      /* PC rel. address, right 14 bits.  */
+#define R_PARISC_PCREL16F      77      /* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16WF     78      /* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16DF     79      /* 16 bits PC-rel. address.  */
+#define R_PARISC_DIR64         80      /* 64 bits of eff. address.  */
+#define R_PARISC_DIR14WR       83      /* 14 bits of eff. address.  */
+#define R_PARISC_DIR14DR       84      /* 14 bits of eff. address.  */
+#define R_PARISC_DIR16F                85      /* 16 bits of eff. address.  */
+#define R_PARISC_DIR16WF       86      /* 16 bits of eff. address.  */
+#define R_PARISC_DIR16DF       87      /* 16 bits of eff. address.  */
+#define R_PARISC_GPREL64       88      /* 64 bits of GP-rel. address.  */
+#define R_PARISC_GPREL14WR     91      /* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL14DR     92      /* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL16F      93      /* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16WF     94      /* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16DF     95      /* 16 bits GP-rel. address.  */
+#define R_PARISC_LTOFF64       96      /* 64 bits LT-rel. address.  */
+#define R_PARISC_LTOFF14WR     99      /* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF14DR     100     /* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF16F      101     /* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16WF     102     /* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16DF     103     /* 16 bits LT-rel. address.  */
+#define R_PARISC_SECREL64      104     /* 64 bits section rel. address.  */
+#define R_PARISC_SEGREL64      112     /* 64 bits segment rel. address.  */
+#define R_PARISC_PLTOFF14WR    115     /* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF14DR    116     /* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF16F     117     /* 16 bits LT-rel. address.  */
+#define R_PARISC_PLTOFF16WF    118     /* 16 bits PLT-rel. address.  */
+#define R_PARISC_PLTOFF16DF    119     /* 16 bits PLT-rel. address.  */
+#define R_PARISC_LTOFF_FPTR64  120     /* 64 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR14WR        123     /* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR14DR        124     /* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR16F 125     /* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16WF        126     /* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16DF        127     /* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LORESERVE     128
+#define R_PARISC_COPY          128     /* Copy relocation.  */
+#define R_PARISC_IPLT          129     /* Dynamic reloc, imported PLT */
+#define R_PARISC_EPLT          130     /* Dynamic reloc, exported PLT */
+#define R_PARISC_TPREL32       153     /* 32 bits TP-rel. address.  */
+#define R_PARISC_TPREL21L      154     /* TP-rel. address, left 21 bits.  */
+#define R_PARISC_TPREL14R      158     /* TP-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_TP21L   162     /* LT-TP-rel. address, left 21 bits. */
+#define R_PARISC_LTOFF_TP14R   166     /* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14F   167     /* 14 bits LT-TP-rel. address.  */
+#define R_PARISC_TPREL64       216     /* 64 bits TP-rel. address.  */
+#define R_PARISC_TPREL14WR     219     /* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL14DR     220     /* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL16F      221     /* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16WF     222     /* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16DF     223     /* 16 bits TP-rel. address.  */
+#define R_PARISC_LTOFF_TP64    224     /* 64 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP14WR  227     /* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14DR  228     /* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP16F   229     /* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16WF  230     /* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16DF  231     /* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_HIRESERVE     255
+
+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PT_HP_TLS              (PT_LOOS + 0x0)
+#define PT_HP_CORE_NONE                (PT_LOOS + 0x1)
+#define PT_HP_CORE_VERSION     (PT_LOOS + 0x2)
+#define PT_HP_CORE_KERNEL      (PT_LOOS + 0x3)
+#define PT_HP_CORE_COMM                (PT_LOOS + 0x4)
+#define PT_HP_CORE_PROC                (PT_LOOS + 0x5)
+#define PT_HP_CORE_LOADABLE    (PT_LOOS + 0x6)
+#define PT_HP_CORE_STACK       (PT_LOOS + 0x7)
+#define PT_HP_CORE_SHM         (PT_LOOS + 0x8)
+#define PT_HP_CORE_MMF         (PT_LOOS + 0x9)
+#define PT_HP_PARALLEL         (PT_LOOS + 0x10)
+#define PT_HP_FASTBIND         (PT_LOOS + 0x11)
+#define PT_HP_OPT_ANNOT                (PT_LOOS + 0x12)
+#define PT_HP_HSL_ANNOT                (PT_LOOS + 0x13)
+#define PT_HP_STACK            (PT_LOOS + 0x14)
+
+#define PT_PARISC_ARCHEXT      0x70000000
+#define PT_PARISC_UNWIND       0x70000001
+
+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PF_PARISC_SBP          0x08000000
+
+#define PF_HP_PAGE_SIZE                0x00100000
+#define PF_HP_FAR_SHARED       0x00200000
+#define PF_HP_NEAR_SHARED      0x00400000
+#define PF_HP_CODE             0x01000000
+#define PF_HP_MODIFY           0x02000000
+#define PF_HP_LAZYSWAP         0x04000000
+#define PF_HP_SBP              0x08000000
+
+
+/* Alpha specific definitions.  */
+
+/* Legal values for e_flags field of Elf64_Ehdr.  */
+
+#define EF_ALPHA_32BIT         1       /* All addresses must be < 2GB.  */
+#define EF_ALPHA_CANRELAX      2       /* Relocations for relaxing exist.  */
+
+/* Legal values for sh_type field of Elf64_Shdr.  */
+
+/* These two are primarily concerned with ECOFF debugging info.  */
+#define SHT_ALPHA_DEBUG                0x70000001
+#define SHT_ALPHA_REGINFO      0x70000002
+
+/* Legal values for sh_flags field of Elf64_Shdr.  */
+
+#define SHF_ALPHA_GPREL                0x10000000
+
+/* Legal values for st_other field of Elf64_Sym.  */
+#define STO_ALPHA_NOPV         0x80    /* No PV required.  */
+#define STO_ALPHA_STD_GPLOAD   0x88    /* PV only used for initial ldgp.  */
+
+/* Alpha relocs.  */
+
+#define R_ALPHA_NONE           0       /* No reloc */
+#define R_ALPHA_REFLONG                1       /* Direct 32 bit */
+#define R_ALPHA_REFQUAD                2       /* Direct 64 bit */
+#define R_ALPHA_GPREL32                3       /* GP relative 32 bit */
+#define R_ALPHA_LITERAL                4       /* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE         5       /* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP         6       /* Add displacement to GP */
+#define R_ALPHA_BRADDR         7       /* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT           8       /* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16         9       /* PC relative 16 bit */
+#define R_ALPHA_SREL32         10      /* PC relative 32 bit */
+#define R_ALPHA_SREL64         11      /* PC relative 64 bit */
+#define R_ALPHA_GPRELHIGH      17      /* GP relative 32 bit, high 16 bits */
+#define R_ALPHA_GPRELLOW       18      /* GP relative 32 bit, low 16 bits */
+#define R_ALPHA_GPREL16                19      /* GP relative 16 bit */
+#define R_ALPHA_COPY           24      /* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT       25      /* Create GOT entry */
+#define R_ALPHA_JMP_SLOT       26      /* Create PLT entry */
+#define R_ALPHA_RELATIVE       27      /* Adjust by program base */
+#define R_ALPHA_TLS_GD_HI      28
+#define R_ALPHA_TLSGD          29
+#define R_ALPHA_TLS_LDM                30
+#define R_ALPHA_DTPMOD64       31
+#define R_ALPHA_GOTDTPREL      32
+#define R_ALPHA_DTPREL64       33
+#define R_ALPHA_DTPRELHI       34
+#define R_ALPHA_DTPRELLO       35
+#define R_ALPHA_DTPREL16       36
+#define R_ALPHA_GOTTPREL       37
+#define R_ALPHA_TPREL64                38
+#define R_ALPHA_TPRELHI                39
+#define R_ALPHA_TPRELLO                40
+#define R_ALPHA_TPREL16                41
+/* Keep this the last entry.  */
+#define R_ALPHA_NUM            46
+
+/* Magic values of the LITUSE relocation addend.  */
+#define LITUSE_ALPHA_ADDR      0
+#define LITUSE_ALPHA_BASE      1
+#define LITUSE_ALPHA_BYTOFF    2
+#define LITUSE_ALPHA_JSR       3
+#define LITUSE_ALPHA_TLS_GD    4
+#define LITUSE_ALPHA_TLS_LDM   5
+
+
+/* PowerPC specific declarations */
+
+/* Values for Elf32/64_Ehdr.e_flags.  */
+#define EF_PPC_EMB             0x80000000      /* PowerPC embedded flag */
+
+/* Cygnus local bits below */
+#define EF_PPC_RELOCATABLE     0x00010000      /* PowerPC -mrelocatable flag*/
+#define EF_PPC_RELOCATABLE_LIB 0x00008000      /* PowerPC -mrelocatable-lib
+                                                  flag */
+
+/* PowerPC relocations defined by the ABIs */
+#define R_PPC_NONE             0
+#define R_PPC_ADDR32           1       /* 32bit absolute address */
+#define R_PPC_ADDR24           2       /* 26bit address, 2 bits ignored.  */
+#define R_PPC_ADDR16           3       /* 16bit absolute address */
+#define R_PPC_ADDR16_LO                4       /* lower 16bit of absolute address */
+#define R_PPC_ADDR16_HI                5       /* high 16bit of absolute address */
+#define R_PPC_ADDR16_HA                6       /* adjusted high 16bit */
+#define R_PPC_ADDR14           7       /* 16bit address, 2 bits ignored */
+#define R_PPC_ADDR14_BRTAKEN   8
+#define R_PPC_ADDR14_BRNTAKEN  9
+#define R_PPC_REL24            10      /* PC relative 26 bit */
+#define R_PPC_REL14            11      /* PC relative 16 bit */
+#define R_PPC_REL14_BRTAKEN    12
+#define R_PPC_REL14_BRNTAKEN   13
+#define R_PPC_GOT16            14
+#define R_PPC_GOT16_LO         15
+#define R_PPC_GOT16_HI         16
+#define R_PPC_GOT16_HA         17
+#define R_PPC_PLTREL24         18
+#define R_PPC_COPY             19
+#define R_PPC_GLOB_DAT         20
+#define R_PPC_JMP_SLOT         21
+#define R_PPC_RELATIVE         22
+#define R_PPC_LOCAL24PC                23
+#define R_PPC_UADDR32          24
+#define R_PPC_UADDR16          25
+#define R_PPC_REL32            26
+#define R_PPC_PLT32            27
+#define R_PPC_PLTREL32         28
+#define R_PPC_PLT16_LO         29
+#define R_PPC_PLT16_HI         30
+#define R_PPC_PLT16_HA         31
+#define R_PPC_SDAREL16         32
+#define R_PPC_SECTOFF          33
+#define R_PPC_SECTOFF_LO       34
+#define R_PPC_SECTOFF_HI       35
+#define R_PPC_SECTOFF_HA       36
+/* Keep this the last entry.  */
+#define R_PPC_NUM              37
+
+/* PowerPC64 relocations defined by the ABIs */
+#define R_PPC64_NONE    R_PPC_NONE
+#define R_PPC64_ADDR32  R_PPC_ADDR32  /* 32bit absolute address.  */
+#define R_PPC64_ADDR24  R_PPC_ADDR24  /* 26bit address, word aligned.  */
+#define R_PPC64_ADDR16  R_PPC_ADDR16  /* 16bit absolute address. */
+#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of abs. address.  */
+#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of abs. address. */
+#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits.  */
+#define R_PPC64_ADDR14 R_PPC_ADDR14   /* 16bit address, word aligned.  */
+#define R_PPC64_ADDR14_BRTAKEN  R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24   R_PPC_REL24 /* PC relative 26 bit, word aligned.  */
+#define R_PPC64_REL14   R_PPC_REL14 /* PC relative 16 bit. */
+#define R_PPC64_REL14_BRTAKEN   R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN  R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16     R_PPC_GOT16
+#define R_PPC64_GOT16_LO  R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI  R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA  R_PPC_GOT16_HA
+
+#define R_PPC64_COPY      R_PPC_COPY
+#define R_PPC64_GLOB_DAT  R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT  R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE  R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32   R_PPC_UADDR32
+#define R_PPC64_UADDR16   R_PPC_UADDR16
+#define R_PPC64_REL32     R_PPC_REL32
+#define R_PPC64_PLT32     R_PPC_PLT32
+#define R_PPC64_PLTREL32  R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO  R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI  R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA  R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF     R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO  R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI  R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA  R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30          37  /* word30 (S + A - P) >> 2.  */
+#define R_PPC64_ADDR64          38  /* doubleword64 S + A.  */
+#define R_PPC64_ADDR16_HIGHER   39  /* half16 #higher(S + A).  */
+#define R_PPC64_ADDR16_HIGHERA  40  /* half16 #highera(S + A).  */
+#define R_PPC64_ADDR16_HIGHEST  41  /* half16 #highest(S + A).  */
+#define R_PPC64_ADDR16_HIGHESTA 42  /* half16 #highesta(S + A). */
+#define R_PPC64_UADDR64     43  /* doubleword64 S + A.  */
+#define R_PPC64_REL64       44  /* doubleword64 S + A - P.  */
+#define R_PPC64_PLT64       45  /* doubleword64 L + A.  */
+#define R_PPC64_PLTREL64    46  /* doubleword64 L + A - P.  */
+#define R_PPC64_TOC16       47  /* half16* S + A - .TOC.  */
+#define R_PPC64_TOC16_LO    48  /* half16 #lo(S + A - .TOC.).  */
+#define R_PPC64_TOC16_HI    49  /* half16 #hi(S + A - .TOC.).  */
+#define R_PPC64_TOC16_HA    50  /* half16 #ha(S + A - .TOC.).  */
+#define R_PPC64_TOC         51  /* doubleword64 .TOC. */
+#define R_PPC64_PLTGOT16    52  /* half16* M + A.  */
+#define R_PPC64_PLTGOT16_LO 53  /* half16 #lo(M + A).  */
+#define R_PPC64_PLTGOT16_HI 54  /* half16 #hi(M + A).  */
+#define R_PPC64_PLTGOT16_HA 55  /* half16 #ha(M + A).  */
+
+#define R_PPC64_ADDR16_DS      56 /* half16ds* (S + A) >> 2.  */
+#define R_PPC64_ADDR16_LO_DS   57 /* half16ds  #lo(S + A) >> 2.  */
+#define R_PPC64_GOT16_DS       58 /* half16ds* (G + A) >> 2.  */
+#define R_PPC64_GOT16_LO_DS    59 /* half16ds  #lo(G + A) >> 2.  */
+#define R_PPC64_PLT16_LO_DS    60 /* half16ds  #lo(L + A) >> 2.  */
+#define R_PPC64_SECTOFF_DS     61 /* half16ds* (R + A) >> 2.  */
+#define R_PPC64_SECTOFF_LO_DS  62 /* half16ds  #lo(R + A) >> 2.  */
+#define R_PPC64_TOC16_DS       63 /* half16ds* (S + A - .TOC.) >> 2.  */
+#define R_PPC64_TOC16_LO_DS    64 /* half16ds  #lo(S + A - .TOC.) >> 2.  */
+#define R_PPC64_PLTGOT16_DS    65 /* half16ds* (M + A) >> 2.  */
+#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds  #lo(M + A) >> 2.  */
+/* Keep this the last entry.  */
+#define R_PPC64_NUM            67
+
+/* The remaining relocs are from the Embedded ELF ABI, and are not
+   in the SVR4 ELF ABI.  */
+#define R_PPC_EMB_NADDR32      101
+#define R_PPC_EMB_NADDR16      102
+#define R_PPC_EMB_NADDR16_LO   103
+#define R_PPC_EMB_NADDR16_HI   104
+#define R_PPC_EMB_NADDR16_HA   105
+#define R_PPC_EMB_SDAI16       106
+#define R_PPC_EMB_SDA2I16      107
+#define R_PPC_EMB_SDA2REL      108
+#define R_PPC_EMB_SDA21                109     /* 16 bit offset in SDA */
+#define R_PPC_EMB_MRKREF       110
+#define R_PPC_EMB_RELSEC16     111
+#define R_PPC_EMB_RELST_LO     112
+#define R_PPC_EMB_RELST_HI     113
+#define R_PPC_EMB_RELST_HA     114
+#define R_PPC_EMB_BIT_FLD      115
+#define R_PPC_EMB_RELSDA       116     /* 16 bit relative offset in SDA */
+
+/* Diab tool relocations.  */
+#define R_PPC_DIAB_SDA21_LO    180     /* like EMB_SDA21, but lower 16 bit */
+#define R_PPC_DIAB_SDA21_HI    181     /* like EMB_SDA21, but high 16 bit */
+#define R_PPC_DIAB_SDA21_HA    182     /* like EMB_SDA21, adjusted high 16 */
+#define R_PPC_DIAB_RELSDA_LO   183     /* like EMB_RELSDA, but lower 16 bit */
+#define R_PPC_DIAB_RELSDA_HI   184     /* like EMB_RELSDA, but high 16 bit */
+#define R_PPC_DIAB_RELSDA_HA   185     /* like EMB_RELSDA, adjusted high 16 */
+
+/* This is a phony reloc to handle any old fashioned TOC16 references
+   that may still be in object files.  */
+#define R_PPC_TOC16            255
+
+/* PowerPC64 specific values for the Dyn d_tag field.  */
+#define DT_PPC64_GLINK  (DT_LOPROC + 0)
+#define DT_PPC64_NUM    1
+
+/* ARM specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+#define EF_ARM_RELEXEC     0x01
+#define EF_ARM_HASENTRY    0x02
+#define EF_ARM_INTERWORK   0x04
+#define EF_ARM_APCS_26     0x08
+#define EF_ARM_APCS_FLOAT  0x10
+#define EF_ARM_PIC         0x20
+#define EF_ARM_ALIGN8      0x40                /* 8-bit structure alignment is in use */
+#define EF_ARM_NEW_ABI     0x80
+#define EF_ARM_OLD_ABI     0x100
+
+/* Other constants defined in the ARM ELF spec. version B-01.  */
+/* NB. These conflict with values defined above.  */
+#define EF_ARM_SYMSARESORTED   0x04
+#define EF_ARM_DYNSYMSUSESEGIDX 0x08
+#define EF_ARM_MAPSYMSFIRST    0x10
+#define EF_ARM_EABIMASK                0XFF000000
+
+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN  0x00000000
+#define EF_ARM_EABI_VER1     0x01000000
+#define EF_ARM_EABI_VER2     0x02000000
+
+/* Additional symbol types for Thumb */
+#define STT_ARM_TFUNC      0xd
+
+/* ARM-specific values for sh_flags */
+#define SHF_ARM_ENTRYSECT  0x10000000   /* Section contains an entry point */
+#define SHF_ARM_COMDEF     0x80000000   /* Section may be multiply defined
+                                          in the input to a link step */
+
+/* ARM-specific program header flags */
+#define PF_ARM_SB          0x10000000   /* Segment contains the location
+                                          addressed by the static base */
+
+/* ARM relocs.  */
+#define R_ARM_NONE             0       /* No reloc */
+#define R_ARM_PC24             1       /* PC relative 26 bit branch */
+#define R_ARM_ABS32            2       /* Direct 32 bit  */
+#define R_ARM_REL32            3       /* PC relative 32 bit */
+#define R_ARM_PC13             4
+#define R_ARM_ABS16            5       /* Direct 16 bit */
+#define R_ARM_ABS12            6       /* Direct 12 bit */
+#define R_ARM_THM_ABS5         7
+#define R_ARM_ABS8             8       /* Direct 8 bit */
+#define R_ARM_SBREL32          9
+#define R_ARM_THM_PC22         10
+#define R_ARM_THM_PC8          11
+#define R_ARM_AMP_VCALL9       12
+#define R_ARM_SWI24            13
+#define R_ARM_THM_SWI8         14
+#define R_ARM_XPC25            15
+#define R_ARM_THM_XPC22                16
+#define R_ARM_COPY             20      /* Copy symbol at runtime */
+#define R_ARM_GLOB_DAT         21      /* Create GOT entry */
+#define R_ARM_JUMP_SLOT                22      /* Create PLT entry */
+#define R_ARM_RELATIVE         23      /* Adjust by program base */
+#define R_ARM_GOTOFF           24      /* 32 bit offset to GOT */
+#define R_ARM_GOTPC            25      /* 32 bit PC relative offset to GOT */
+#define R_ARM_GOT32            26      /* 32 bit GOT entry */
+#define R_ARM_PLT32            27      /* 32 bit PLT address */
+#define R_ARM_ALU_PCREL_7_0    32
+#define R_ARM_ALU_PCREL_15_8   33
+#define R_ARM_ALU_PCREL_23_15  34
+#define R_ARM_LDR_SBREL_11_0   35
+#define R_ARM_ALU_SBREL_19_12  36
+#define R_ARM_ALU_SBREL_27_20  37
+#define R_ARM_GNU_VTENTRY      100
+#define R_ARM_GNU_VTINHERIT    101
+#define R_ARM_THM_PC11         102     /* thumb unconditional branch */
+#define R_ARM_THM_PC9          103     /* thumb conditional branch */
+#define R_ARM_RXPC25           249
+#define R_ARM_RSBREL32         250
+#define R_ARM_THM_RPC22                251
+#define R_ARM_RREL32           252
+#define R_ARM_RABS22           253
+#define R_ARM_RPC24            254
+#define R_ARM_RBASE            255
+/* Keep this the last entry.  */
+#define R_ARM_NUM              256
+
+/* IA-64 specific declarations.  */
+
+/* Processor specific flags for the Ehdr e_flags field.  */
+#define EF_IA_64_MASKOS                0x0000000f      /* os-specific flags */
+#define EF_IA_64_ABI64         0x00000010      /* 64-bit ABI */
+#define EF_IA_64_ARCH          0xff000000      /* arch. version mask */
+
+/* Processor specific values for the Phdr p_type field.  */
+#define PT_IA_64_ARCHEXT       (PT_LOPROC + 0) /* arch extension bits */
+#define PT_IA_64_UNWIND                (PT_LOPROC + 1) /* ia64 unwind bits */
+
+/* Processor specific flags for the Phdr p_flags field.  */
+#define PF_IA_64_NORECOV       0x80000000      /* spec insns w/o recovery */
+
+/* Processor specific values for the Shdr sh_type field.  */
+#define SHT_IA_64_EXT          (SHT_LOPROC + 0) /* extension bits */
+#define SHT_IA_64_UNWIND       (SHT_LOPROC + 1) /* unwind bits */
+
+/* Processor specific flags for the Shdr sh_flags field.  */
+#define SHF_IA_64_SHORT                0x10000000      /* section near gp */
+#define SHF_IA_64_NORECOV      0x20000000      /* spec insns w/o recovery */
+
+/* Processor specific values for the Dyn d_tag field.  */
+#define DT_IA_64_PLT_RESERVE   (DT_LOPROC + 0)
+#define DT_IA_64_NUM           1
+
+/* IA-64 relocations.  */
+#define R_IA64_NONE            0x00    /* none */
+#define R_IA64_IMM14           0x21    /* symbol + addend, add imm14 */
+#define R_IA64_IMM22           0x22    /* symbol + addend, add imm22 */
+#define R_IA64_IMM64           0x23    /* symbol + addend, mov imm64 */
+#define R_IA64_DIR32MSB                0x24    /* symbol + addend, data4 MSB */
+#define R_IA64_DIR32LSB                0x25    /* symbol + addend, data4 LSB */
+#define R_IA64_DIR64MSB                0x26    /* symbol + addend, data8 MSB */
+#define R_IA64_DIR64LSB                0x27    /* symbol + addend, data8 LSB */
+#define R_IA64_GPREL22         0x2a    /* @gprel(sym + add), add imm22 */
+#define R_IA64_GPREL64I                0x2b    /* @gprel(sym + add), mov imm64 */
+#define R_IA64_GPREL32MSB      0x2c    /* @gprel(sym + add), data4 MSB */
+#define R_IA64_GPREL32LSB      0x2d    /* @gprel(sym + add), data4 LSB */
+#define R_IA64_GPREL64MSB      0x2e    /* @gprel(sym + add), data8 MSB */
+#define R_IA64_GPREL64LSB      0x2f    /* @gprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF22         0x32    /* @ltoff(sym + add), add imm22 */
+#define R_IA64_LTOFF64I                0x33    /* @ltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF22                0x3a    /* @pltoff(sym + add), add imm22 */
+#define R_IA64_PLTOFF64I       0x3b    /* @pltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF64MSB     0x3e    /* @pltoff(sym + add), data8 MSB */
+#define R_IA64_PLTOFF64LSB     0x3f    /* @pltoff(sym + add), data8 LSB */
+#define R_IA64_FPTR64I         0x43    /* @fptr(sym + add), mov imm64 */
+#define R_IA64_FPTR32MSB       0x44    /* @fptr(sym + add), data4 MSB */
+#define R_IA64_FPTR32LSB       0x45    /* @fptr(sym + add), data4 LSB */
+#define R_IA64_FPTR64MSB       0x46    /* @fptr(sym + add), data8 MSB */
+#define R_IA64_FPTR64LSB       0x47    /* @fptr(sym + add), data8 LSB */
+#define R_IA64_PCREL60B                0x48    /* @pcrel(sym + add), brl */
+#define R_IA64_PCREL21B                0x49    /* @pcrel(sym + add), ptb, call */
+#define R_IA64_PCREL21M                0x4a    /* @pcrel(sym + add), chk.s */
+#define R_IA64_PCREL21F                0x4b    /* @pcrel(sym + add), fchkf */
+#define R_IA64_PCREL32MSB      0x4c    /* @pcrel(sym + add), data4 MSB */
+#define R_IA64_PCREL32LSB      0x4d    /* @pcrel(sym + add), data4 LSB */
+#define R_IA64_PCREL64MSB      0x4e    /* @pcrel(sym + add), data8 MSB */
+#define R_IA64_PCREL64LSB      0x4f    /* @pcrel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_FPTR22    0x52    /* @ltoff(@fptr(s+a)), imm22 */
+#define R_IA64_LTOFF_FPTR64I   0x53    /* @ltoff(@fptr(s+a)), imm64 */
+#define R_IA64_LTOFF_FPTR32MSB 0x54    /* @ltoff(@fptr(s+a)), data4 MSB */
+#define R_IA64_LTOFF_FPTR32LSB 0x55    /* @ltoff(@fptr(s+a)), data4 LSB */
+#define R_IA64_LTOFF_FPTR64MSB 0x56    /* @ltoff(@fptr(s+a)), data8 MSB */
+#define R_IA64_LTOFF_FPTR64LSB 0x57    /* @ltoff(@fptr(s+a)), data8 LSB */
+#define R_IA64_SEGREL32MSB     0x5c    /* @segrel(sym + add), data4 MSB */
+#define R_IA64_SEGREL32LSB     0x5d    /* @segrel(sym + add), data4 LSB */
+#define R_IA64_SEGREL64MSB     0x5e    /* @segrel(sym + add), data8 MSB */
+#define R_IA64_SEGREL64LSB     0x5f    /* @segrel(sym + add), data8 LSB */
+#define R_IA64_SECREL32MSB     0x64    /* @secrel(sym + add), data4 MSB */
+#define R_IA64_SECREL32LSB     0x65    /* @secrel(sym + add), data4 LSB */
+#define R_IA64_SECREL64MSB     0x66    /* @secrel(sym + add), data8 MSB */
+#define R_IA64_SECREL64LSB     0x67    /* @secrel(sym + add), data8 LSB */
+#define R_IA64_REL32MSB                0x6c    /* data 4 + REL */
+#define R_IA64_REL32LSB                0x6d    /* data 4 + REL */
+#define R_IA64_REL64MSB                0x6e    /* data 8 + REL */
+#define R_IA64_REL64LSB                0x6f    /* data 8 + REL */
+#define R_IA64_LTV32MSB                0x74    /* symbol + addend, data4 MSB */
+#define R_IA64_LTV32LSB                0x75    /* symbol + addend, data4 LSB */
+#define R_IA64_LTV64MSB                0x76    /* symbol + addend, data8 MSB */
+#define R_IA64_LTV64LSB                0x77    /* symbol + addend, data8 LSB */
+#define R_IA64_PCREL21BI       0x79    /* @pcrel(sym + add), 21bit inst */
+#define R_IA64_PCREL22         0x7a    /* @pcrel(sym + add), 22bit inst */
+#define R_IA64_PCREL64I                0x7b    /* @pcrel(sym + add), 64bit inst */
+#define R_IA64_IPLTMSB         0x80    /* dynamic reloc, imported PLT, MSB */
+#define R_IA64_IPLTLSB         0x81    /* dynamic reloc, imported PLT, LSB */
+#define R_IA64_COPY            0x84    /* copy relocation */
+#define R_IA64_SUB             0x85    /* Addend and symbol difference */
+#define R_IA64_LTOFF22X                0x86    /* LTOFF22, relaxable.  */
+#define R_IA64_LDXMOV          0x87    /* Use of LTOFF22X.  */
+#define R_IA64_TPREL14         0x91    /* @tprel(sym + add), imm14 */
+#define R_IA64_TPREL22         0x92    /* @tprel(sym + add), imm22 */
+#define R_IA64_TPREL64I                0x93    /* @tprel(sym + add), imm64 */
+#define R_IA64_TPREL64MSB      0x96    /* @tprel(sym + add), data8 MSB */
+#define R_IA64_TPREL64LSB      0x97    /* @tprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_TPREL22   0x9a    /* @ltoff(@tprel(s+a)), imm2 */
+#define R_IA64_DTPMOD64MSB     0xa6    /* @dtpmod(sym + add), data8 MSB */
+#define R_IA64_DTPMOD64LSB     0xa7    /* @dtpmod(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPMOD22  0xaa    /* @ltoff(@dtpmod(sym + add)), imm22 */
+#define R_IA64_DTPREL14                0xb1    /* @dtprel(sym + add), imm14 */
+#define R_IA64_DTPREL22                0xb2    /* @dtprel(sym + add), imm22 */
+#define R_IA64_DTPREL64I       0xb3    /* @dtprel(sym + add), imm64 */
+#define R_IA64_DTPREL32MSB     0xb4    /* @dtprel(sym + add), data4 MSB */
+#define R_IA64_DTPREL32LSB     0xb5    /* @dtprel(sym + add), data4 LSB */
+#define R_IA64_DTPREL64MSB     0xb6    /* @dtprel(sym + add), data8 MSB */
+#define R_IA64_DTPREL64LSB     0xb7    /* @dtprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPREL22  0xba    /* @ltoff(@dtprel(s+a)), imm22 */
+
+/* SH specific declarations */
+
+/* SH relocs.  */
+#define        R_SH_NONE               0
+#define        R_SH_DIR32              1
+#define        R_SH_REL32              2
+#define        R_SH_DIR8WPN            3
+#define        R_SH_IND12W             4
+#define        R_SH_DIR8WPL            5
+#define        R_SH_DIR8WPZ            6
+#define        R_SH_DIR8BP             7
+#define        R_SH_DIR8W              8
+#define        R_SH_DIR8L              9
+#define        R_SH_SWITCH16           25
+#define        R_SH_SWITCH32           26
+#define        R_SH_USES               27
+#define        R_SH_COUNT              28
+#define        R_SH_ALIGN              29
+#define        R_SH_CODE               30
+#define        R_SH_DATA               31
+#define        R_SH_LABEL              32
+#define        R_SH_SWITCH8            33
+#define        R_SH_GNU_VTINHERIT      34
+#define        R_SH_GNU_VTENTRY        35
+#define        R_SH_TLS_GD_32          144
+#define        R_SH_TLS_LD_32          145
+#define        R_SH_TLS_LDO_32         146
+#define        R_SH_TLS_IE_32          147
+#define        R_SH_TLS_LE_32          148
+#define        R_SH_TLS_DTPMOD32       149
+#define        R_SH_TLS_DTPOFF32       150
+#define        R_SH_TLS_TPOFF32        151
+#define        R_SH_TLS_GD_MOV         152
+#define        R_SH_TLS_LDM_MOV        153
+#define        R_SH_TLS_LDO_MOV        154
+#define        R_SH_TLS_IE_MOV         155
+#define        R_SH_TLS_LE_MOV         156
+#define        R_SH_GOT32              160
+#define        R_SH_PLT32              161
+#define        R_SH_COPY               162
+#define        R_SH_GLOB_DAT           163
+#define        R_SH_JMP_SLOT           164
+#define        R_SH_RELATIVE           165
+#define        R_SH_GOTOFF             166
+#define        R_SH_GOTPC              167
+/* Keep this the last entry.  */
+#define        R_SH_NUM                256
+
+/* Additional s390 relocs */
+
+#define R_390_NONE     0              /* No reloc.  */
+#define R_390_8                1              /* Direct 8 bit.  */
+#define R_390_12       2              /* Direct 12 bit.  */
+#define R_390_16       3              /* Direct 16 bit.  */
+#define R_390_32       4              /* Direct 32 bit.  */
+#define R_390_PC32     5              /* PC relative 32 bit.  */
+#define R_390_GOT12    6              /* 12 bit GOT offset.  */
+#define R_390_GOT32    7              /* 32 bit GOT offset.  */
+#define R_390_PLT32    8              /* 32 bit PC relative PLT address.  */
+#define R_390_COPY     9              /* Copy symbol at runtime.  */
+#define R_390_GLOB_DAT 10             /* Create GOT entry.  */
+#define R_390_JMP_SLOT 11             /* Create PLT entry.  */
+#define R_390_RELATIVE 12             /* Adjust by program base.  */
+#define R_390_GOTOFF   13             /* 32 bit offset to GOT.  */
+#define R_390_GOTPC    14             /* 32 bit PC relative offset to GOT.  */
+#define R_390_GOT16    15             /* 16 bit GOT offset.  */
+#define R_390_PC16     16             /* PC relative 16 bit.  */
+#define R_390_PC16DBL  17             /* PC relative 16 bit shifted by 1.  */
+#define R_390_PLT16DBL 18             /* 16 bit PC rel. PLT shifted by 1.  */
+#define R_390_PC32DBL  19             /* PC relative 32 bit shifted by 1.  */
+#define R_390_PLT32DBL 20             /* 32 bit PC rel. PLT shifted by 1.  */
+#define R_390_GOTPCDBL 21             /* 32 bit PC rel. GOT shifted by 1.  */
+#define R_390_64       22             /* Direct 64 bit.  */
+#define R_390_PC64     23             /* PC relative 64 bit.  */
+#define R_390_GOT64    24             /* 64 bit GOT offset.  */
+#define R_390_PLT64    25             /* 64 bit PC relative PLT address.  */
+#define R_390_GOTENT   26             /* 32 bit PC rel. to GOT entry >> 1. */
+
+/* Keep this the last entry.  */
+#define R_390_NUM      27
+
+/* CRIS relocations.  */
+#define R_CRIS_NONE            0
+#define R_CRIS_8               1
+#define R_CRIS_16              2
+#define R_CRIS_32              3
+#define R_CRIS_8_PCREL         4
+#define R_CRIS_16_PCREL                5
+#define R_CRIS_32_PCREL                6
+#define R_CRIS_GNU_VTINHERIT   7
+#define R_CRIS_GNU_VTENTRY     8
+#define R_CRIS_COPY            9
+#define R_CRIS_GLOB_DAT                10
+#define R_CRIS_JUMP_SLOT       11
+#define R_CRIS_RELATIVE                12
+#define R_CRIS_16_GOT          13
+#define R_CRIS_32_GOT          14
+#define R_CRIS_16_GOTPLT       15
+#define R_CRIS_32_GOTPLT       16
+#define R_CRIS_32_GOTREL       17
+#define R_CRIS_32_PLT_GOTREL   18
+#define R_CRIS_32_PLT_PCREL    19
+
+#define R_CRIS_NUM             20
+
+/* AMD x86-64 relocations.  */
+#define R_X86_64_NONE          0       /* No reloc */
+#define R_X86_64_64            1       /* Direct 64 bit  */
+#define R_X86_64_PC32          2       /* PC relative 32 bit signed */
+#define R_X86_64_GOT32         3       /* 32 bit GOT entry */
+#define R_X86_64_PLT32         4       /* 32 bit PLT address */
+#define R_X86_64_COPY          5       /* Copy symbol at runtime */
+#define R_X86_64_GLOB_DAT      6       /* Create GOT entry */
+#define R_X86_64_JUMP_SLOT     7       /* Create PLT entry */
+#define R_X86_64_RELATIVE      8       /* Adjust by program base */
+#define R_X86_64_GOTPCREL      9       /* 32 bit signed PC relative
+                                          offset to GOT */
+#define R_X86_64_32            10      /* Direct 32 bit zero extended */
+#define R_X86_64_32S           11      /* Direct 32 bit sign extended */
+#define R_X86_64_16            12      /* Direct 16 bit zero extended */
+#define R_X86_64_PC16          13      /* 16 bit sign extended pc relative */
+#define R_X86_64_8             14      /* Direct 8 bit sign extended  */
+#define R_X86_64_PC8           15      /* 8 bit sign extended pc relative */
+#define R_X86_64_DTPMOD64      16      /* ID of module containing symbol */
+#define R_X86_64_DTPOFF64      17      /* Offset in module's TLS block */
+#define R_X86_64_TPOFF64       18      /* Offset in initial TLS block */
+#define R_X86_64_TLSGD         19      /* 32 bit signed PC relative offset
+                                          to two GOT entries for GD symbol */
+#define R_X86_64_TLSLD         20      /* 32 bit signed PC relative offset
+                                          to two GOT entries for LD symbol */
+#define R_X86_64_DTPOFF32      21      /* Offset in TLS block */
+#define r_x86_64_GOTTPOFF      22      /* 32 bit signed PC relative offset
+                                          to GOT entry for IE symbol */
+#define R_X86_64_TPOFF32       23      /* Offset in initial TLS block */
+
+#define R_X86_64_NUM           24
+
+#if GRUB_TARGET_WORDSIZE == 32
+
+typedef Elf32_Addr Elf_Addr;
+typedef Elf32_Ehdr Elf_Ehdr;
+typedef Elf32_Half Elf_Half;
+typedef Elf32_Off Elf_Off;
+typedef Elf32_Rel Elf_Rel;
+typedef Elf32_Rela Elf_Rela;
+typedef Elf32_Section Elf_Section;
+typedef Elf32_Shdr Elf_Shdr;
+typedef Elf32_Sword Elf_Sword;
+typedef Elf32_Sym Elf_Sym;
+typedef Elf32_Word Elf_Word;
+typedef Elf32_Xword Elf_Xword;
+
+#define ELF_ST_BIND(val)       ELF32_ST_BIND(val)
+#define ELF_ST_TYPE(val)       ELF32_ST_TYPE(val)
+#define ELF_R_SYM(val)         ELF32_R_SYM(val)
+#define ELF_R_TYPE(val)                ELF32_R_TYPE(val)
+#define ELF_R_INFO(sym, type)  ELF32_R_INFO(sym, type)
+
+#elif GRUB_TARGET_WORDSIZE == 64
+
+typedef Elf64_Addr Elf_Addr;
+typedef Elf64_Ehdr Elf_Ehdr;
+typedef Elf64_Half Elf_Half;
+typedef Elf64_Off Elf_Off;
+typedef Elf64_Rel Elf_Rel;
+typedef Elf64_Rela Elf_Rela;
+typedef Elf64_Section Elf_Section;
+typedef Elf64_Shdr Elf_Shdr;
+typedef Elf64_Sword Elf_Sword;
+typedef Elf64_Sym Elf_Sym;
+typedef Elf64_Word Elf_Word;
+typedef Elf64_Xword Elf_Xword;
+
+#define ELF_ST_BIND(val)       ELF64_ST_BIND (val)
+#define ELF_ST_TYPE(val)       ELF64_ST_TYPE (val)
+#define ELF_R_SYM(val)         ELF64_R_SYM(val)
+#define ELF_R_TYPE(val)                ELF64_R_TYPE(val)
+#define ELF_R_INFO(sym, type)  ELF64_R_INFO(sym, type)
+
+#endif /* GRUB_TARGET_WORDSIZE == 64 */
+
+#endif /* ! GRUB_ELF_H */
diff --git a/grub-core/include/grub/elfload.h b/grub-core/include/grub/elfload.h
new file mode 100644 (file)
index 0000000..77ee416
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#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 grub_err_t (*grub_elf32_load_hook_t)
+  (Elf32_Phdr *phdr, grub_addr_t *addr, int *load);
+typedef grub_err_t (*grub_elf64_load_hook_t)
+  (Elf64_Phdr *phdr, grub_addr_t *addr, int *load);
+
+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, Elf32_Addr *);
+grub_err_t grub_elf32_load (grub_elf_t, grub_elf32_load_hook_t, grub_addr_t *,
+                           grub_size_t *);
+
+int grub_elf_is_elf64 (grub_elf_t);
+grub_size_t grub_elf64_size (grub_elf_t, Elf64_Addr *);
+grub_err_t grub_elf64_load (grub_elf_t, grub_elf64_load_hook_t, grub_addr_t *,
+                           grub_size_t *);
+
+#endif /* ! GRUB_ELFLOAD_HEADER */
diff --git a/grub-core/include/grub/emu/console.h b/grub-core/include/grub/emu/console.h
new file mode 100644 (file)
index 0000000..1e55682
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CONSOLE_UTIL_HEADER
+#define GRUB_CONSOLE_UTIL_HEADER       1
+
+/* Initialize the console system.  */
+void grub_console_init (void);
+
+/* Finish the console system.  */
+void grub_console_fini (void);
+
+#endif /* ! GRUB_CONSOLE_UTIL_HEADER */
diff --git a/grub-core/include/grub/emu/getroot.h b/grub-core/include/grub/emu/getroot.h
new file mode 100644 (file)
index 0000000..04a2805
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003, 2007, 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_UTIL_GETROOT_HEADER
+#define GRUB_UTIL_GETROOT_HEADER       1
+
+enum grub_dev_abstraction_types {
+  GRUB_DEV_ABSTRACTION_NONE,
+  GRUB_DEV_ABSTRACTION_LVM,
+  GRUB_DEV_ABSTRACTION_RAID,
+};
+
+char *grub_guess_root_device (const char *dir);
+int grub_util_get_dev_abstraction (const char *os_dev);
+char *grub_util_get_grub_dev (const char *os_dev);
+char *grub_make_system_path_relative_to_its_root (const char *path);
+const char *grub_util_check_block_device (const char *blk_dev);
+const char *grub_util_check_char_device (const char *blk_dev);
+
+#endif /* ! GRUB_UTIL_GETROOT_HEADER */
diff --git a/grub-core/include/grub/emu/hostdisk.h b/grub-core/include/grub/emu/hostdisk.h
new file mode 100644 (file)
index 0000000..246046e
--- /dev/null
@@ -0,0 +1,30 @@
+/* biosdisk.h - emulate biosdisk */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BIOSDISK_MACHINE_UTIL_HEADER
+#define GRUB_BIOSDISK_MACHINE_UTIL_HEADER      1
+
+#include <grub/disk.h>
+
+void grub_util_biosdisk_init (const char *dev_map);
+void grub_util_biosdisk_fini (void);
+char *grub_util_biosdisk_get_grub_dev (const char *os_dev);
+const char *grub_util_biosdisk_get_osdev (grub_disk_t disk);
+
+#endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */
diff --git a/grub-core/include/grub/emu/misc.h b/grub-core/include/grub/emu/misc.h
new file mode 100644 (file)
index 0000000..29c1d4a
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef GRUB_EMU_MISC_H
+#define GRUB_EMU_MISC_H 1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+extern int verbosity;
+extern const char *program_name;
+
+void grub_init_all (void);
+void grub_fini_all (void);
+
+void * EXPORT_FUNC(xmalloc) (grub_size_t size);
+void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size);
+char * EXPORT_FUNC(xstrdup) (const char *str);
+char * EXPORT_FUNC(xasprintf) (const char *fmt, ...);
+
+void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...);
+void EXPORT_FUNC(grub_util_info) (const char *fmt, ...);
+void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((noreturn));
+
+#endif /* GRUB_EMU_MISC_H */
diff --git a/grub-core/include/grub/env.h b/grub-core/include/grub/env.h
new file mode 100644 (file)
index 0000000..ae4fd87
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ENV_HEADER
+#define GRUB_ENV_HEADER        1
+
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/menu.h>
+
+struct grub_env_var;
+
+typedef char *(*grub_env_read_hook_t) (struct grub_env_var *var,
+                                      const char *val);
+typedef char *(*grub_env_write_hook_t) (struct grub_env_var *var,
+                                       const char *val);
+
+struct grub_env_var
+{
+  char *name;
+  char *value;
+  grub_env_read_hook_t read_hook;
+  grub_env_write_hook_t write_hook;
+  struct grub_env_var *next;
+  struct grub_env_var **prevp;
+  int global;
+};
+
+grub_err_t EXPORT_FUNC(grub_env_set) (const char *name, const char *val);
+char *EXPORT_FUNC(grub_env_get) (const char *name);
+void EXPORT_FUNC(grub_env_unset) (const char *name);
+void EXPORT_FUNC(grub_env_iterate) (int (*func) (struct grub_env_var *var));
+struct grub_env_var *EXPORT_FUNC(grub_env_find) (const char *name);
+grub_err_t EXPORT_FUNC(grub_register_variable_hook) (const char *name,
+                                                    grub_env_read_hook_t read_hook,
+                                                    grub_env_write_hook_t write_hook);
+
+grub_err_t grub_env_context_open (int export);
+grub_err_t grub_env_context_close (void);
+grub_err_t grub_env_export (const char *name);
+
+void grub_env_unset_menu (void);
+grub_menu_t grub_env_get_menu (void);
+void grub_env_set_menu (grub_menu_t nmenu);
+
+#endif /* ! GRUB_ENV_HEADER */
diff --git a/grub-core/include/grub/env_private.h b/grub-core/include/grub/env_private.h
new file mode 100644 (file)
index 0000000..bb00153
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ENV_PRIVATE_HEADER
+#define GRUB_ENV_PRIVATE_HEADER        1
+
+#include <grub/env.h>
+
+/* The size of the hash table.  */
+#define        HASHSZ  13
+
+/* A hashtable for quick lookup of variables.  */
+struct grub_env_context
+{
+  /* A hash table for variables.  */
+  struct grub_env_var *vars[HASHSZ];
+
+  /* One level deeper on the stack.  */
+  struct grub_env_context *prev;
+};
+
+/* This is used for sorting only.  */
+struct grub_env_sorted_var
+{
+  struct grub_env_var *var;
+  struct grub_env_sorted_var *next;
+};
+
+extern struct grub_env_context *EXPORT_VAR(grub_current_context);
+
+#endif /* ! GRUB_ENV_PRIVATE_HEADER */
diff --git a/grub-core/include/grub/err.h b/grub-core/include/grub/err.h
new file mode 100644 (file)
index 0000000..e447053
--- /dev/null
@@ -0,0 +1,72 @@
+/* err.h - error numbers and prototypes */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ERR_HEADER
+#define GRUB_ERR_HEADER        1
+
+#include <grub/symbol.h>
+
+typedef enum
+  {
+    GRUB_ERR_NONE = 0,
+    GRUB_ERR_TEST_FAILURE,
+    GRUB_ERR_BAD_MODULE,
+    GRUB_ERR_OUT_OF_MEMORY,
+    GRUB_ERR_BAD_FILE_TYPE,
+    GRUB_ERR_FILE_NOT_FOUND,
+    GRUB_ERR_FILE_READ_ERROR,
+    GRUB_ERR_BAD_FILENAME,
+    GRUB_ERR_UNKNOWN_FS,
+    GRUB_ERR_BAD_FS,
+    GRUB_ERR_BAD_NUMBER,
+    GRUB_ERR_OUT_OF_RANGE,
+    GRUB_ERR_UNKNOWN_DEVICE,
+    GRUB_ERR_BAD_DEVICE,
+    GRUB_ERR_READ_ERROR,
+    GRUB_ERR_WRITE_ERROR,
+    GRUB_ERR_UNKNOWN_COMMAND,
+    GRUB_ERR_INVALID_COMMAND,
+    GRUB_ERR_BAD_ARGUMENT,
+    GRUB_ERR_BAD_PART_TABLE,
+    GRUB_ERR_UNKNOWN_OS,
+    GRUB_ERR_BAD_OS,
+    GRUB_ERR_NO_KERNEL,
+    GRUB_ERR_BAD_FONT,
+    GRUB_ERR_NOT_IMPLEMENTED_YET,
+    GRUB_ERR_SYMLINK_LOOP,
+    GRUB_ERR_BAD_GZIP_DATA,
+    GRUB_ERR_MENU,
+    GRUB_ERR_TIMEOUT,
+    GRUB_ERR_IO,
+    GRUB_ERR_ACCESS_DENIED
+  }
+grub_err_t;
+
+extern grub_err_t EXPORT_VAR(grub_errno);
+extern char EXPORT_VAR(grub_errmsg)[];
+
+grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...);
+void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn));
+void EXPORT_FUNC(grub_error_push) (void);
+int EXPORT_FUNC(grub_error_pop) (void);
+void EXPORT_FUNC(grub_print_error) (void);
+int grub_err_printf (const char *fmt, ...)
+     __attribute__ ((format (printf, 1, 2)));
+
+#endif /* ! GRUB_ERR_HEADER */
diff --git a/grub-core/include/grub/extcmd.h b/grub-core/include/grub/extcmd.h
new file mode 100644 (file)
index 0000000..03eaba8
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EXTCMD_HEADER
+#define GRUB_EXTCMD_HEADER     1
+
+#include <grub/lib/arg.h>
+#include <grub/command.h>
+
+struct grub_extcmd;
+
+typedef grub_err_t (*grub_extcmd_func_t) (struct grub_extcmd *cmd,
+                                         int argc, char **args);
+
+/* The argcmd description.  */
+struct grub_extcmd
+{
+  grub_command_t cmd;
+
+  grub_extcmd_func_t func;
+
+  /* The argument parser optionlist.  */
+  const struct grub_arg_option *options;
+
+  void *data;
+
+  struct grub_arg_list *state;
+};
+typedef struct grub_extcmd *grub_extcmd_t;
+
+grub_extcmd_t grub_register_extcmd (const char *name,
+                                   grub_extcmd_func_t func,
+                                   unsigned flags,
+                                   const char *summary,
+                                   const char *description,
+                                   const struct grub_arg_option *parser);
+
+void grub_unregister_extcmd (grub_extcmd_t cmd);
+
+#endif /* ! GRUB_EXTCMD_HEADER */
diff --git a/grub-core/include/grub/fbblit.h b/grub-core/include/grub/fbblit.h
new file mode 100644 (file)
index 0000000..af97dfb
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FBBLIT_HEADER
+#define GRUB_FBBLIT_HEADER     1
+
+/* NOTE: This header is private header for fb driver and should not be used
+   in other parts of the code.  */
+
+struct grub_video_fbblit_info;
+
+void
+grub_video_fbblit_replace (struct grub_video_fbblit_info *dst,
+                          struct grub_video_fbblit_info *src,
+                          int x, int y, int width, int height,
+                          int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_directN (struct grub_video_fbblit_info *dst,
+                                  struct grub_video_fbblit_info *src,
+                                  int x, int y, int width, int height,
+                                  int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
+                                            struct grub_video_fbblit_info *src,
+                                            int x, int y, int width, int height,
+                                            int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst,
+                                          struct grub_video_fbblit_info *src,
+                                          int x, int y,
+                                          int width, int height,
+                                          int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst,
+                                          struct grub_video_fbblit_info *src,
+                                          int x, int y,
+                                          int width, int height,
+                                          int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_BGR888_RGB888 (struct grub_video_fbblit_info *dst,
+                                        struct grub_video_fbblit_info *src,
+                                        int x, int y,
+                                        int width, int height,
+                                        int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst,
+                                          struct grub_video_fbblit_info *src,
+                                          int x, int y,
+                                          int width, int height,
+                                          int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst,
+                                          struct grub_video_fbblit_info *src,
+                                          int x, int y,
+                                          int width, int height,
+                                          int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
+                                         struct grub_video_fbblit_info *src,
+                                         int x, int y,
+                                         int width, int height,
+                                         int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
+                                       struct grub_video_fbblit_info *src,
+                                       int x, int y, int width, int height,
+                                       int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend (struct grub_video_fbblit_info *dst,
+                        struct grub_video_fbblit_info *src,
+                        int x, int y, int width, int height,
+                        int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+                                          struct grub_video_fbblit_info *src,
+                                          int x, int y,
+                                          int width, int height,
+                                          int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst,
+                                        struct grub_video_fbblit_info *src,
+                                        int x, int y,
+                                        int width, int height,
+                                        int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_RGBA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+                                          struct grub_video_fbblit_info *src,
+                                          int x, int y,
+                                          int width, int height,
+                                          int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst,
+                                        struct grub_video_fbblit_info *src,
+                                        int x, int y,
+                                        int width, int height,
+                                        int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_index_RGBA8888 (struct grub_video_fbblit_info *dst,
+                                       struct grub_video_fbblit_info *src,
+                                       int x, int y,
+                                       int width, int height,
+                                       int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_32bit_1bit (struct grub_video_fbblit_info *dst,
+                                     struct grub_video_fbblit_info *src,
+                                     int x, int y,
+                                     int width, int height,
+                                     int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_24bit_1bit (struct grub_video_fbblit_info *dst,
+                                     struct grub_video_fbblit_info *src,
+                                     int x, int y,
+                                     int width, int height,
+                                     int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_16bit_1bit (struct grub_video_fbblit_info *dst,
+                                     struct grub_video_fbblit_info *src,
+                                     int x, int y,
+                                     int width, int height,
+                                     int offset_x, int offset_y);
+
+void
+grub_video_fbblit_replace_8bit_1bit (struct grub_video_fbblit_info *dst,
+                                    struct grub_video_fbblit_info *src,
+                                    int x, int y,
+                                    int width, int height,
+                                    int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_XXXA8888_1bit (struct grub_video_fbblit_info *dst,
+                                      struct grub_video_fbblit_info *src,
+                                      int x, int y,
+                                      int width, int height,
+                                      int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_XXX888_1bit (struct grub_video_fbblit_info *dst,
+                                      struct grub_video_fbblit_info *src,
+                                      int x, int y,
+                                      int width, int height,
+                                      int offset_x, int offset_y);
+
+void
+grub_video_fbblit_blend_XXX565_1bit (struct grub_video_fbblit_info *dst,
+                                    struct grub_video_fbblit_info *src,
+                                    int x, int y,
+                                    int width, int height,
+                                    int offset_x, int offset_y);
+#endif /* ! GRUB_FBBLIT_HEADER */
diff --git a/grub-core/include/grub/fbfill.h b/grub-core/include/grub/fbfill.h
new file mode 100644 (file)
index 0000000..c85fa12
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FBFILL_HEADER
+#define GRUB_FBFILL_HEADER     1
+
+/* NOTE: This header is private header for fb driver and should not be used
+   in other parts of the code.  */
+
+struct grub_video_fbblit_info;
+
+struct grub_video_fbrender_target
+{
+  /* Copy of the screen's mode info structure, except that width, height and
+     mode_type has been re-adjusted to requested render target settings.  */
+  struct grub_video_mode_info mode_info;
+
+  struct
+  {
+    unsigned int x;
+    unsigned int y;
+    unsigned int width;
+    unsigned int height;
+  } viewport;
+
+  /* Indicates whether the data has been allocated by us and must be freed
+     when render target is destroyed.  */
+  int is_allocated;
+
+  /* Pointer to data.  Can either be in video card memory or in local host's
+     memory.  */
+  grub_uint8_t *data;
+};
+
+void
+grub_video_fbfill (struct grub_video_fbblit_info *dst,
+                  grub_video_color_t color, int x, int y,
+                  int width, int height);
+
+void
+grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst,
+                           grub_video_color_t color,  int x, int y,
+                           int width, int height);
+
+void
+grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst,
+                           grub_video_color_t color, int x, int y,
+                           int width, int height);
+
+void
+grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst,
+                           grub_video_color_t color, int x, int y,
+                           int width, int height);
+
+void
+grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst,
+                          grub_video_color_t color, int x, int y,
+                          int width, int height);
+
+#endif /* ! GRUB_FBFILL_HEADER */
diff --git a/grub-core/include/grub/fbutil.h b/grub-core/include/grub/fbutil.h
new file mode 100644 (file)
index 0000000..065ccf9
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* NOTE: This header is private header for vbe driver and should not be used
+   in other parts of the code.  */
+
+#ifndef GRUB_VBEUTIL_MACHINE_HEADER
+#define GRUB_VBEUTIL_MACHINE_HEADER    1
+
+#include <grub/types.h>
+#include <grub/video.h>
+
+struct grub_video_fbblit_info
+{
+  struct grub_video_mode_info *mode_info;
+  grub_uint8_t *data;
+};
+
+grub_uint8_t *grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
+                            unsigned int x, unsigned int y);
+
+grub_video_color_t get_pixel (struct grub_video_fbblit_info *source,
+                              unsigned int x, unsigned int y);
+
+void set_pixel (struct grub_video_fbblit_info *source,
+                unsigned int x, unsigned int y, grub_video_color_t color);
+
+#endif /* ! GRUB_VBEUTIL_MACHINE_HEADER */
diff --git a/grub-core/include/grub/file.h b/grub-core/include/grub/file.h
new file mode 100644 (file)
index 0000000..2aacf93
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FILE_HEADER
+#define GRUB_FILE_HEADER       1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/device.h>
+#include <grub/fs.h>
+
+/* File description.  */
+struct grub_file
+{
+  /* The underlying device.  */
+  grub_device_t device;
+
+  /* The underlying filesystem.  */
+  grub_fs_t fs;
+
+  /* The current offset.  */
+  grub_off_t offset;
+
+  /* The file size.  */
+  grub_off_t size;
+
+  /* Filesystem-specific data.  */
+  void *data;
+
+  /* This is called when a sector is read. Used only for a disk device.  */
+  void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                    unsigned offset, unsigned length);
+};
+typedef struct grub_file *grub_file_t;
+
+/* Get a device name from NAME.  */
+char *EXPORT_FUNC(grub_file_get_device_name) (const char *name);
+
+grub_file_t EXPORT_FUNC(grub_file_open) (const char *name);
+grub_ssize_t EXPORT_FUNC(grub_file_read) (grub_file_t file, void *buf,
+                                         grub_size_t len);
+grub_off_t EXPORT_FUNC(grub_file_seek) (grub_file_t file, grub_off_t offset);
+grub_err_t EXPORT_FUNC(grub_file_close) (grub_file_t file);
+
+static inline grub_off_t
+grub_file_size (const grub_file_t file)
+{
+  return file->size;
+}
+
+static inline grub_off_t
+grub_file_tell (const grub_file_t file)
+{
+  return file->offset;
+}
+
+#endif /* ! GRUB_FILE_HEADER */
diff --git a/grub-core/include/grub/font.h b/grub-core/include/grub/font.h
new file mode 100644 (file)
index 0000000..7c5c174
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FONT_HEADER
+#define GRUB_FONT_HEADER       1
+
+#include <grub/types.h>
+#include <grub/video.h>
+#include <grub/file.h>
+
+/* Forward declaration of opaque structure grub_font.
+   Users only pass struct grub_font pointers to the font module functions,
+   and do not have knowledge of the structure contents.  */
+struct grub_font;
+
+/* Font type used to access font functions.  */
+typedef struct grub_font *grub_font_t;
+
+struct grub_font_node
+{
+  struct grub_font_node *next;
+  grub_font_t value;
+};
+
+/* Global font registry.  */
+extern struct grub_font_node *grub_font_list;
+
+struct grub_font_glyph
+{
+  /* Reference to the font this glyph belongs to.  */
+  grub_font_t font;
+
+  /* Glyph bitmap width in pixels.  */
+  grub_uint16_t width;
+
+  /* Glyph bitmap height in pixels.  */
+  grub_uint16_t height;
+
+  /* Glyph bitmap x offset in pixels.  Add to screen coordinate.  */
+  grub_int16_t offset_x;
+
+  /* Glyph bitmap y offset in pixels.  Subtract from screen coordinate.  */
+  grub_int16_t offset_y;
+
+  /* Number of pixels to advance to start the next character.  */
+  grub_uint16_t device_width;
+
+  /* Row-major order, packed bits (no padding; rows can break within a byte).
+     The length of the array is (width * height + 7) / 8.  Within a
+     byte, the most significant bit is the first (leftmost/uppermost) pixel.
+     Pixels are coded as bits, value 1 meaning of opaque pixel and 0 is
+     transparent.  If the length of the array does not fit byte boundary, it
+     will be padded with 0 bits to make it fit.  */
+  grub_uint8_t bitmap[0];
+};
+
+/* Initialize the font loader.
+   Must be called before any fonts are loaded or used.  */
+void grub_font_loader_init (void);
+
+/* Load a font and add it to the beginning of the global font list.
+   Returns: 0 upon success; nonzero upon failure.  */
+int grub_font_load (const char *filename);
+
+/* Get the font that has the specified name.  Font names are in the form
+   "Family Name Bold Italic 14", where Bold and Italic are optional.
+   If no font matches the name specified, the most recently loaded font
+   is returned as a fallback.  */
+grub_font_t EXPORT_FUNC (grub_font_get) (const char *font_name);
+
+const char *EXPORT_FUNC (grub_font_get_name) (grub_font_t font);
+
+int EXPORT_FUNC (grub_font_get_max_char_width) (grub_font_t font);
+
+int EXPORT_FUNC (grub_font_get_max_char_height) (grub_font_t font);
+
+int EXPORT_FUNC (grub_font_get_ascent) (grub_font_t font);
+
+int EXPORT_FUNC (grub_font_get_descent) (grub_font_t font);
+
+int EXPORT_FUNC (grub_font_get_leading) (grub_font_t font);
+
+int EXPORT_FUNC (grub_font_get_height) (grub_font_t font);
+
+int EXPORT_FUNC (grub_font_get_string_width) (grub_font_t font,
+                                             const char *str);
+
+struct grub_font_glyph *EXPORT_FUNC (grub_font_get_glyph) (grub_font_t font,
+                                                          grub_uint32_t code);
+
+struct grub_font_glyph *EXPORT_FUNC (grub_font_get_glyph_with_fallback) (grub_font_t font,
+                                                                        grub_uint32_t code);
+
+grub_err_t EXPORT_FUNC (grub_font_draw_glyph) (struct grub_font_glyph *glyph,
+                                              grub_video_color_t color,
+                                              int left_x, int baseline_y);
+
+grub_err_t EXPORT_FUNC (grub_font_draw_string) (const char *str,
+                                               grub_font_t font,
+                                               grub_video_color_t color,
+                                               int left_x, int baseline_y);
+
+#endif /* ! GRUB_FONT_HEADER */
diff --git a/grub-core/include/grub/fontformat.h b/grub-core/include/grub/fontformat.h
new file mode 100644 (file)
index 0000000..b506058
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FONT_FORMAT_HEADER
+#define GRUB_FONT_FORMAT_HEADER        1
+
+/* FONT_FORMAT_PFF2_MAGIC use only 4 relevants bytes and the \0.  */
+#define FONT_FORMAT_PFF2_MAGIC "PFF2"
+#define FONT_FORMAT_SECTION_NAMES_FILE "FILE"
+#define FONT_FORMAT_SECTION_NAMES_FONT_NAME "NAME"
+#define FONT_FORMAT_SECTION_NAMES_POINT_SIZE "PTSZ"
+#define FONT_FORMAT_SECTION_NAMES_WEIGHT "WEIG"
+#define FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH "MAXW"
+#define FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT "MAXH"
+#define FONT_FORMAT_SECTION_NAMES_ASCENT "ASCE"
+#define FONT_FORMAT_SECTION_NAMES_DESCENT "DESC"
+#define FONT_FORMAT_SECTION_NAMES_CHAR_INDEX "CHIX"
+#define FONT_FORMAT_SECTION_NAMES_DATA "DATA"
+#define FONT_FORMAT_SECTION_NAMES_FAMILY "FAMI"
+#define FONT_FORMAT_SECTION_NAMES_SLAN "SLAN"
+
+#endif /* ! GRUB_FONT_FORMAT_HEADER */
+
diff --git a/grub-core/include/grub/fs.h b/grub-core/include/grub/fs.h
new file mode 100644 (file)
index 0000000..45f5157
--- /dev/null
@@ -0,0 +1,96 @@
+/* fs.h - filesystem manager */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FS_HEADER
+#define GRUB_FS_HEADER 1
+
+#include <grub/device.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+/* Forward declaration is required, because of mutual reference.  */
+struct grub_file;
+
+struct grub_dirhook_info
+{
+  int dir:1;
+  int mtimeset:1;
+  int case_insensitive:1;
+  grub_int32_t mtime;
+};
+
+/* Filesystem descriptor.  */
+struct grub_fs
+{
+  /* My name.  */
+  const char *name;
+
+  /* Call HOOK with each file under DIR.  */
+  grub_err_t (*dir) (grub_device_t device, const char *path,
+                    int (*hook) (const char *filename,
+                                 const struct grub_dirhook_info *info));
+
+  /* Open a file named NAME and initialize FILE.  */
+  grub_err_t (*open) (struct grub_file *file, const char *name);
+
+  /* Read LEN bytes data from FILE into BUF.  */
+  grub_ssize_t (*read) (struct grub_file *file, char *buf, grub_size_t len);
+
+  /* Close the file FILE.  */
+  grub_err_t (*close) (struct grub_file *file);
+
+  /* Return the label of the device DEVICE in LABEL.  The label is
+     returned in a grub_malloc'ed buffer and should be freed by the
+     caller.  */
+  grub_err_t (*label) (grub_device_t device, char **label);
+
+  /* Return the uuid of the device DEVICE in UUID.  The uuid is
+     returned in a grub_malloc'ed buffer and should be freed by the
+     caller.  */
+  grub_err_t (*uuid) (grub_device_t device, char **uuid);
+
+  /* Get writing time of filesystem. */
+  grub_err_t (*mtime) (grub_device_t device, grub_int32_t *timebuf);
+
+#ifdef GRUB_UTIL
+  /* Whether this filesystem reserves first sector for DOS-style boot.  */
+  int reserved_first_sector;
+#endif
+
+  /* The next filesystem.  */
+  struct grub_fs *next;
+};
+typedef struct grub_fs *grub_fs_t;
+
+/* This is special, because block lists are not files in usual sense.  */
+extern struct grub_fs grub_fs_blocklist;
+
+/* This hook is used to automatically load filesystem modules.
+   If this hook loads a module, return non-zero. Otherwise return zero.
+   The newly loaded filesystem is assumed to be inserted into the head of
+   the linked list GRUB_FS_LIST through the function grub_fs_register.  */
+typedef int (*grub_fs_autoload_hook_t) (void);
+extern grub_fs_autoload_hook_t EXPORT_VAR(grub_fs_autoload_hook);
+
+void EXPORT_FUNC(grub_fs_register) (grub_fs_t fs);
+void EXPORT_FUNC(grub_fs_unregister) (grub_fs_t fs);
+void EXPORT_FUNC(grub_fs_iterate) (int (*hook) (const grub_fs_t fs));
+grub_fs_t EXPORT_FUNC(grub_fs_probe) (grub_device_t device);
+
+#endif /* ! GRUB_FS_HEADER */
diff --git a/grub-core/include/grub/fshelp.h b/grub-core/include/grub/fshelp.h
new file mode 100644 (file)
index 0000000..42d8da5
--- /dev/null
@@ -0,0 +1,82 @@
+/* fshelp.h -- Filesystem helper functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_FSHELP_HEADER
+#define GRUB_FSHELP_HEADER     1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/err.h>
+
+typedef struct grub_fshelp_node *grub_fshelp_node_t;
+
+#define GRUB_FSHELP_CASE_INSENSITIVE   0x100
+#define GRUB_FSHELP_TYPE_MASK  0xff
+#define GRUB_FSHELP_FLAGS_MASK 0x100
+
+enum grub_fshelp_filetype
+  {
+    GRUB_FSHELP_UNKNOWN,
+    GRUB_FSHELP_REG,
+    GRUB_FSHELP_DIR,
+    GRUB_FSHELP_SYMLINK
+  };
+
+/* Lookup the node PATH.  The node ROOTNODE describes the root of the
+   directory tree.  The node found is returned in FOUNDNODE, which is
+   either a ROOTNODE or a new malloc'ed node.  ITERATE_DIR is used to
+   iterate over all directory entries in the current node.
+   READ_SYMLINK is used to read the symlink if a node is a symlink.
+   EXPECTTYPE is the type node that is expected by the called, an
+   error is generated if the node is not of the expected type.  Make
+   sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required
+   because GCC has a nasty bug when using regparm=3.  */
+grub_err_t
+EXPORT_FUNC(grub_fshelp_find_file) (const char *path,
+                                   grub_fshelp_node_t rootnode,
+                                   grub_fshelp_node_t *foundnode,
+                                   int (*iterate_dir) (grub_fshelp_node_t dir,
+                                                       int NESTED_FUNC_ATTR
+                                                       (*hook) (const char *filename,
+                                                                enum grub_fshelp_filetype filetype,
+                                                                grub_fshelp_node_t node)),
+                                   char *(*read_symlink) (grub_fshelp_node_t node),
+                                   enum grub_fshelp_filetype expect);
+
+
+/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
+   beginning with the block POS.  READ_HOOK should be set before
+   reading a block from the file.  GET_BLOCK is used to translate file
+   blocks to disk blocks.  The file is FILESIZE bytes big and the
+   blocks have a size of LOG2BLOCKSIZE (in log2).  */
+grub_ssize_t
+EXPORT_FUNC(grub_fshelp_read_file) (grub_disk_t disk, grub_fshelp_node_t node,
+                                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
+                                                                        unsigned offset,
+                                                                        unsigned length),
+                                   grub_off_t pos, grub_size_t len, char *buf,
+                                   grub_disk_addr_t (*get_block) (grub_fshelp_node_t node,
+                                                                   grub_disk_addr_t block),
+                                   grub_off_t filesize, int log2blocksize);
+
+unsigned int
+EXPORT_FUNC(grub_fshelp_log2blksize) (unsigned int blksize,
+                                     unsigned int *pow);
+
+#endif /* ! GRUB_FSHELP_HEADER */
diff --git a/grub-core/include/grub/gfxmenu_model.h b/grub-core/include/grub/gfxmenu_model.h
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/grub-core/include/grub/gfxmenu_view.h b/grub-core/include/grub/gfxmenu_view.h
new file mode 100644 (file)
index 0000000..7cbfa89
--- /dev/null
@@ -0,0 +1,107 @@
+/* gfxmenu_view.h - gfxmenu view interface. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_GFXMENU_VIEW_HEADER
+#define GRUB_GFXMENU_VIEW_HEADER 1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/menu.h>
+#include <grub/font.h>
+#include <grub/gfxwidgets.h>
+
+struct grub_gfxmenu_view;   /* Forward declaration of opaque type.  */
+typedef struct grub_gfxmenu_view *grub_gfxmenu_view_t;
+
+
+grub_gfxmenu_view_t grub_gfxmenu_view_new (const char *theme_path,
+                                          int width, int height);
+
+void grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view);
+
+/* Set properties on the view based on settings from the specified
+   theme file.  */
+grub_err_t grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view,
+                                         const char *theme_path);
+
+grub_err_t grub_gui_recreate_box (grub_gfxmenu_box_t *boxptr,
+                                  const char *pattern, const char *theme_dir);
+
+void grub_gfxmenu_view_draw (grub_gfxmenu_view_t view);
+
+void
+grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view);
+
+void
+grub_gfxmenu_redraw_timeout (grub_gfxmenu_view_t view);
+
+void
+grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
+                         const grub_video_rect_t *region);
+
+void 
+grub_gfxmenu_clear_timeout (void *data);
+void 
+grub_gfxmenu_print_timeout (int timeout, void *data);
+void
+grub_gfxmenu_set_chosen_entry (int entry, void *data);
+
+/* Implementation details -- this should not be used outside of the
+   view itself.  */
+
+#include <grub/video.h>
+#include <grub/bitmap.h>
+#include <grub/gui.h>
+#include <grub/gfxwidgets.h>
+#include <grub/icon_manager.h>
+
+/* Definition of the private representation of the view.  */
+struct grub_gfxmenu_view
+{
+  grub_video_rect_t screen;
+
+  grub_font_t title_font;
+  grub_font_t message_font;
+  char *terminal_font_name;
+  grub_gui_color_t title_color;
+  grub_gui_color_t message_color;
+  grub_gui_color_t message_bg_color;
+  struct grub_video_bitmap *desktop_image;
+  grub_gui_color_t desktop_color;
+  grub_gfxmenu_box_t terminal_box;
+  char *title_text;
+  char *progress_message_text;
+  char *theme_path;
+
+  grub_gui_container_t canvas;
+
+  int double_repaint;
+
+  int selected;
+
+  grub_video_rect_t progress_message_frame;
+
+  grub_menu_t menu;
+
+  int nested;
+
+  int first_timeout;
+};
+
+#endif /* ! GRUB_GFXMENU_VIEW_HEADER */
diff --git a/grub-core/include/grub/gfxterm.h b/grub-core/include/grub/gfxterm.h
new file mode 100644 (file)
index 0000000..295354b
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_GFXTERM_HEADER
+#define GRUB_GFXTERM_HEADER    1
+
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/term.h>
+#include <grub/video.h>
+
+grub_err_t
+EXPORT_FUNC (grub_gfxterm_set_window) (struct grub_video_render_target *target,
+                                      int x, int y, int width, int height,
+                                      int double_repaint,
+                                      const char *font_name, int border_width);
+
+typedef void (*grub_gfxterm_repaint_callback_t)(int x, int y,
+                                                int width, int height);
+
+void grub_gfxterm_set_repaint_callback (grub_gfxterm_repaint_callback_t func);
+
+void EXPORT_FUNC (grub_gfxterm_schedule_repaint) (void);
+
+grub_err_t EXPORT_FUNC (grub_gfxterm_fullscreen) (void);
+
+extern void (*EXPORT_VAR (grub_gfxterm_decorator_hook)) (void);
+
+#endif /* ! GRUB_GFXTERM_HEADER */
diff --git a/grub-core/include/grub/gfxwidgets.h b/grub-core/include/grub/gfxwidgets.h
new file mode 100644 (file)
index 0000000..f9678bf
--- /dev/null
@@ -0,0 +1,49 @@
+/* gfxwidgets.h - Widgets for the graphical menu (gfxmenu).  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_GFXWIDGETS_HEADER
+#define GRUB_GFXWIDGETS_HEADER 1
+
+#include <grub/video.h>
+
+typedef struct grub_gfxmenu_box *grub_gfxmenu_box_t;
+
+struct grub_gfxmenu_box
+{
+  /* The size of the content.  */
+  int content_width;
+  int content_height;
+
+  struct grub_video_bitmap **raw_pixmaps;
+  struct grub_video_bitmap **scaled_pixmaps;
+
+  void (*draw) (grub_gfxmenu_box_t self, int x, int y);
+  void (*set_content_size) (grub_gfxmenu_box_t self,
+                            int width, int height);
+  int (*get_left_pad) (grub_gfxmenu_box_t self);
+  int (*get_top_pad) (grub_gfxmenu_box_t self);
+  int (*get_right_pad) (grub_gfxmenu_box_t self);
+  int (*get_bottom_pad) (grub_gfxmenu_box_t self);
+  void (*destroy) (grub_gfxmenu_box_t self);
+};
+
+grub_gfxmenu_box_t grub_gfxmenu_create_box (const char *pixmaps_prefix,
+                                            const char *pixmaps_suffix);
+
+#endif /* ! GRUB_GFXWIDGETS_HEADER */
diff --git a/grub-core/include/grub/gpt_partition.h b/grub-core/include/grub/gpt_partition.h
new file mode 100644 (file)
index 0000000..428ceb1
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_GPT_PARTITION_HEADER
+#define GRUB_GPT_PARTITION_HEADER      1
+
+#include <grub/types.h>
+
+struct grub_gpt_part_type
+{
+  grub_uint32_t data1;
+  grub_uint16_t data2;
+  grub_uint16_t data3;
+  grub_uint8_t data4[8];
+} __attribute__ ((aligned(8)));
+typedef struct grub_gpt_part_type grub_gpt_part_type_t;
+
+#define GRUB_GPT_PARTITION_TYPE_EMPTY \
+  { 0x0, 0x0, 0x0, \
+    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } \
+  }
+
+#define GRUB_GPT_PARTITION_TYPE_BIOS_BOOT \
+  { grub_cpu_to_le32 (0x21686148), grub_cpu_to_le16 (0x6449), grub_cpu_to_le16 (0x6e6f), \
+    { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } \
+  }
+
+struct grub_gpt_header
+{
+  grub_uint8_t magic[8];
+  grub_uint32_t version;
+  grub_uint32_t headersize;
+  grub_uint32_t crc32;
+  grub_uint32_t unused1;
+  grub_uint64_t primary;
+  grub_uint64_t backup;
+  grub_uint64_t start;
+  grub_uint64_t end;
+  grub_uint8_t guid[16];
+  grub_uint64_t partitions;
+  grub_uint32_t maxpart;
+  grub_uint32_t partentry_size;
+  grub_uint32_t partentry_crc32;
+} __attribute__ ((packed));
+
+struct grub_gpt_partentry
+{
+  grub_gpt_part_type_t type;
+  grub_uint8_t guid[16];
+  grub_uint64_t start;
+  grub_uint64_t end;
+  grub_uint64_t attrib;
+  char name[72];
+} __attribute__ ((packed));
+
+#endif /* ! GRUB_GPT_PARTITION_HEADER */
diff --git a/grub-core/include/grub/gui.h b/grub-core/include/grub/gui.h
new file mode 100644 (file)
index 0000000..7bd71ac
--- /dev/null
@@ -0,0 +1,230 @@
+/* gui.h - GUI components header file. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/video.h>
+#include <grub/bitmap.h>
+#include <grub/gfxmenu_view.h>
+
+#ifndef GRUB_GUI_H
+#define GRUB_GUI_H 1
+
+/* A representation of a color.  Unlike grub_video_color_t, this
+   representation is independent of any video mode specifics.  */
+typedef struct grub_gui_color
+{
+  grub_uint8_t red;
+  grub_uint8_t green;
+  grub_uint8_t blue;
+  grub_uint8_t alpha;
+} grub_gui_color_t;
+
+typedef struct grub_gui_component *grub_gui_component_t;
+typedef struct grub_gui_container *grub_gui_container_t;
+typedef struct grub_gui_list *grub_gui_list_t;
+
+typedef void (*grub_gui_component_callback) (grub_gui_component_t component,
+                                             void *userdata);
+
+/* Component interface.  */
+
+struct grub_gui_component_ops
+{
+  void (*destroy) (void *self);
+  const char * (*get_id) (void *self);
+  int (*is_instance) (void *self, const char *type);
+  void (*paint) (void *self, const grub_video_rect_t *bounds);
+  void (*set_parent) (void *self, grub_gui_container_t parent);
+  grub_gui_container_t (*get_parent) (void *self);
+  void (*set_bounds) (void *self, const grub_video_rect_t *bounds);
+  void (*get_bounds) (void *self, grub_video_rect_t *bounds);
+  void (*get_minimal_size) (void *self, unsigned *width, unsigned *height);
+  grub_err_t (*set_property) (void *self, const char *name, const char *value);
+  void (*repaint) (void *self, int second_pass);
+};
+
+struct grub_gui_container_ops
+{
+  void (*add) (void *self, grub_gui_component_t comp);
+  void (*remove) (void *self, grub_gui_component_t comp);
+  void (*iterate_children) (void *self,
+                            grub_gui_component_callback cb, void *userdata);
+};
+
+struct grub_gui_list_ops
+{
+  void (*set_view_info) (void *self,
+                         grub_gfxmenu_view_t view);
+};
+
+struct grub_gui_progress_ops
+{
+  void (*set_state) (void *self, int visible, int start, int current, int end);
+};
+
+typedef signed grub_fixed_signed_t;
+#define GRUB_FIXED_1 0x10000
+
+static inline signed
+grub_fixed_sfs_divide (signed a, grub_fixed_signed_t b)
+{
+  return (a * GRUB_FIXED_1) / b;
+}
+
+static inline grub_fixed_signed_t
+grub_fixed_fsf_divide (grub_fixed_signed_t a, signed b)
+{
+  return a / b;
+}
+
+static inline signed
+grub_fixed_sfs_multiply (signed a, grub_fixed_signed_t b)
+{
+  return (a * b) / GRUB_FIXED_1;
+}
+
+static inline signed
+grub_fixed_to_signed (grub_fixed_signed_t in)
+{
+  return in / GRUB_FIXED_1;
+}
+
+static inline grub_fixed_signed_t
+grub_signed_to_fixed (signed in)
+{
+  return in * GRUB_FIXED_1;
+}
+
+struct grub_gui_component
+{
+  struct grub_gui_component_ops *ops;
+  signed x;
+  grub_fixed_signed_t xfrac;
+  signed y;
+  grub_fixed_signed_t yfrac;
+  signed w;
+  grub_fixed_signed_t wfrac;
+  signed h;
+  grub_fixed_signed_t hfrac;
+};
+
+struct grub_gui_progress
+{
+  struct grub_gui_component component;
+  struct grub_gui_progress_ops *ops;
+};
+
+struct grub_gui_container
+{
+  struct grub_gui_component component;
+  struct grub_gui_container_ops *ops;
+};
+
+struct grub_gui_list
+{
+  struct grub_gui_component component;
+  struct grub_gui_list_ops *ops;
+};
+
+
+/* Interfaces to concrete component classes.  */
+
+grub_gui_container_t grub_gui_canvas_new (void);
+grub_gui_container_t grub_gui_vbox_new (void);
+grub_gui_container_t grub_gui_hbox_new (void);
+grub_gui_component_t grub_gui_label_new (void);
+grub_gui_component_t grub_gui_image_new (void);
+grub_gui_component_t grub_gui_progress_bar_new (void);
+grub_gui_component_t grub_gui_list_new (void);
+grub_gui_component_t grub_gui_circular_progress_new (void);
+
+/* Manipulation functions.  */
+
+/* Visit all components with the specified ID.  */
+void grub_gui_find_by_id (grub_gui_component_t root,
+                          const char *id,
+                          grub_gui_component_callback cb,
+                          void *userdata);
+
+/* Visit all components.  */
+void grub_gui_iterate_recursively (grub_gui_component_t root,
+                                   grub_gui_component_callback cb,
+                                   void *userdata);
+
+/* Helper functions.  */
+
+static __inline void
+grub_gui_save_viewport (grub_video_rect_t *r)
+{
+  grub_video_get_viewport ((unsigned *) &r->x,
+                           (unsigned *) &r->y,
+                           (unsigned *) &r->width,
+                           (unsigned *) &r->height);
+}
+
+static __inline void
+grub_gui_restore_viewport (const grub_video_rect_t *r)
+{
+  grub_video_set_viewport (r->x, r->y, r->width, r->height);
+}
+
+/* Set a new viewport relative the the current one, saving the current
+   viewport in OLD so it can be later restored.  */
+static __inline void
+grub_gui_set_viewport (const grub_video_rect_t *r, grub_video_rect_t *old)
+{
+  grub_gui_save_viewport (old);
+  grub_video_set_viewport (old->x + r->x,
+                           old->y + r->y,
+                           r->width,
+                           r->height);
+}
+
+static __inline grub_gui_color_t
+grub_gui_color_rgb (int r, int g, int b)
+{
+  grub_gui_color_t c;
+  c.red = r;
+  c.green = g;
+  c.blue = b;
+  c.alpha = 255;
+  return c;
+}
+
+static __inline grub_video_color_t
+grub_gui_map_color (grub_gui_color_t c)
+{
+  return grub_video_map_rgba (c.red, c.green, c.blue, c.alpha);
+}
+
+static inline int
+grub_video_have_common_points (const grub_video_rect_t *a,
+                              const grub_video_rect_t *b)
+{
+  if (!((a->x <= b->x && b->x <= a->x + a->width)
+       || (b->x <= a->x && a->x <= b->x + b->width)))
+    return 0;
+  if (!((a->y <= b->y && b->y <= a->y + a->height)
+       || (b->y <= a->y && a->y <= b->y + b->height)))
+    return 0;
+  return 1;
+}
+
+#endif /* ! GRUB_GUI_H */
diff --git a/grub-core/include/grub/gui_string_util.h b/grub-core/include/grub/gui_string_util.h
new file mode 100644 (file)
index 0000000..1baa2ee
--- /dev/null
@@ -0,0 +1,37 @@
+/* gui_string_util.h - String utilities for the graphical menu interface. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_GUI_STRING_UTIL_HEADER
+#define GRUB_GUI_STRING_UTIL_HEADER 1
+
+#include <grub/types.h>
+#include <grub/gui.h>
+
+char *grub_new_substring (const char *buf,
+                          grub_size_t start, grub_size_t end);
+
+char *grub_resolve_relative_path (const char *base, const char *path);
+
+char *grub_get_dirname (const char *file_path);
+
+int grub_gui_get_named_color (const char *name, grub_gui_color_t *color);
+
+grub_err_t grub_gui_parse_color (const char *s, grub_gui_color_t *color);
+
+#endif /* GRUB_GUI_STRING_UTIL_HEADER */
diff --git a/grub-core/include/grub/gzio.h b/grub-core/include/grub/gzio.h
new file mode 100644 (file)
index 0000000..cd7f397
--- /dev/null
@@ -0,0 +1,28 @@
+/* gzio.h - prototypes for gzio */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_GZIO_H
+#define GRUB_GZIO_H    1
+
+#include <grub/file.h>
+
+grub_file_t grub_gzio_open (grub_file_t io, int transparent);
+grub_file_t grub_gzfile_open (const char *name, int transparent);
+
+#endif /* ! GRUB_GZIO_H */
diff --git a/grub-core/include/grub/handler.h b/grub-core/include/grub/handler.h
new file mode 100644 (file)
index 0000000..77dd7d9
--- /dev/null
@@ -0,0 +1,60 @@
+/* handler.h - header for grub handler */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_HANDLER_HEADER
+#define GRUB_HANDLER_HEADER 1
+
+#include <grub/list.h>
+#include <grub/err.h>
+
+struct grub_handler
+{
+  struct grub_handler *next;
+  const char *name;
+  grub_err_t (*init) (void);
+  grub_err_t (*fini) (void);
+};
+typedef struct grub_handler *grub_handler_t;
+
+struct grub_handler_class
+{
+  struct grub_handler_class *next;
+  const char *name;
+  grub_handler_t handler_list;
+  grub_handler_t cur_handler;
+};
+typedef struct grub_handler_class *grub_handler_class_t;
+
+extern grub_handler_class_t EXPORT_VAR(grub_handler_class_list);
+
+void EXPORT_FUNC(grub_handler_register) (grub_handler_class_t class,
+                                        grub_handler_t handler);
+void EXPORT_FUNC(grub_handler_unregister) (grub_handler_class_t class,
+                                          grub_handler_t handler);
+grub_err_t EXPORT_FUNC(grub_handler_set_current) (grub_handler_class_t class,
+                                                 grub_handler_t handler);
+
+#define GRUB_AS_HANDLER(ptr) \
+  ((GRUB_FIELD_MATCH (ptr, grub_handler_t, next) && \
+    GRUB_FIELD_MATCH (ptr, grub_handler_t, name) && \
+    GRUB_FIELD_MATCH (ptr, grub_handler_t, init) && \
+    GRUB_FIELD_MATCH (ptr, grub_handler_t, fini)) ? \
+   (grub_handler_t) ptr : grub_bad_type_cast ())
+
+#endif /* ! GRUB_HANDLER_HEADER */
diff --git a/grub-core/include/grub/hfs.h b/grub-core/include/grub/hfs.h
new file mode 100644 (file)
index 0000000..d93b9a2
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_HFS_HEADER
+#define GRUB_HFS_HEADER        1
+
+#include <grub/types.h>
+
+#define GRUB_HFS_MAGIC         0x4244
+
+/* A single extent.  A file consists of one or more extents.  */
+struct grub_hfs_extent
+{
+  /* The first physical block.  */
+  grub_uint16_t first_block;
+  grub_uint16_t count;
+};
+
+/* HFS stores extents in groups of 3.  */
+typedef struct grub_hfs_extent grub_hfs_datarecord_t[3];
+
+/* The HFS superblock (The official name is `Master Directory
+   Block').  */
+struct grub_hfs_sblock
+{
+  grub_uint16_t magic;
+  grub_uint8_t unused[18];
+  grub_uint32_t blksz;
+  grub_uint8_t unused2[4];
+  grub_uint16_t first_block;
+  grub_uint8_t unused4[6];
+
+  /* A pascal style string that holds the volumename.  */
+  grub_uint8_t volname[28];
+
+  grub_uint8_t unused5[52];
+  grub_uint64_t num_serial;
+  grub_uint16_t embed_sig;
+  struct grub_hfs_extent embed_extent;
+  grub_uint8_t unused6[4];
+  grub_hfs_datarecord_t extent_recs;
+  grub_uint32_t catalog_size;
+  grub_hfs_datarecord_t catalog_recs;
+} __attribute__ ((packed));
+
+#endif /* ! GRUB_HFS_HEADER */
diff --git a/grub-core/include/grub/i18n.h b/grub-core/include/grub/i18n.h
new file mode 100644 (file)
index 0000000..9e7f52d
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef        GRUB_I18N_H
+#define        GRUB_I18N_H     1
+
+#include <config.h>
+#include <grub/symbol.h>
+
+extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s);
+
+/* NLS can be disabled through the configure --disable-nls option.  */
+#if (defined(ENABLE_NLS) && ENABLE_NLS)
+
+# ifdef GRUB_UTIL
+
+#  include <locale.h>
+#  include <libintl.h>
+
+# endif /* GRUB_UTIL */
+
+#else /* ! (defined(ENABLE_NLS) && ENABLE_NLS) */
+
+/* Disabled NLS.
+   The casts to 'const char *' serve the purpose of producing warnings
+   for invalid uses of the value returned from these functions.
+   On pre-ANSI systems without 'const', the config.h file is supposed to
+   contain "#define const".  */
+# ifdef GRUB_UTIL
+#  define gettext(Msgid) ((const char *) (Msgid))
+# else
+#  define grub_gettext(str) ((const char *) (str))
+# endif /* GRUB_UTIL */
+
+#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */
+
+#ifdef GRUB_UTIL
+# define _(str) gettext(str)
+#else
+# define _(str) grub_gettext(str)
+#endif /* GRUB_UTIL */
+
+#define N_(str) str
+
+#endif /* GRUB_I18N_H */
diff --git a/grub-core/include/grub/i386/at_keyboard.h b/grub-core/include/grub/i386/at_keyboard.h
new file mode 100644 (file)
index 0000000..da4e806
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CPU_AT_KEYBOARD_HEADER
+#define GRUB_CPU_AT_KEYBOARD_HEADER    1
+
+#define KEYBOARD_REG_DATA      0x60
+#define KEYBOARD_REG_STATUS    0x64
+
+#endif
diff --git a/grub-core/include/grub/i386/bsd.h b/grub-core/include/grub/i386/bsd.h
new file mode 100644 (file)
index 0000000..4d55f04
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BSD_CPU_HEADER
+#define GRUB_BSD_CPU_HEADER    1
+
+#include <grub/types.h>
+#include <grub/i386/freebsd_reboot.h>
+#include <grub/i386/netbsd_reboot.h>
+#include <grub/i386/openbsd_reboot.h>
+#include <grub/i386/freebsd_linker.h>
+#include <grub/i386/netbsd_bootinfo.h>
+#include <grub/i386/openbsd_bootarg.h>
+
+
+enum bsd_kernel_types
+  {
+    KERNEL_TYPE_NONE,
+    KERNEL_TYPE_FREEBSD,
+    KERNEL_TYPE_OPENBSD,
+    KERNEL_TYPE_NETBSD,
+  };
+
+#define GRUB_BSD_TEMP_BUFFER   0x80000
+
+#define FREEBSD_B_DEVMAGIC     OPENBSD_B_DEVMAGIC
+#define FREEBSD_B_SLICESHIFT   OPENBSD_B_CTRLSHIFT
+#define FREEBSD_B_UNITSHIFT    OPENBSD_B_UNITSHIFT
+#define FREEBSD_B_PARTSHIFT    OPENBSD_B_PARTSHIFT
+#define FREEBSD_B_TYPESHIFT    OPENBSD_B_TYPESHIFT
+
+#define FREEBSD_MODTYPE_KERNEL         "elf kernel"
+#define FREEBSD_MODTYPE_KERNEL64       "elf64 kernel"
+#define FREEBSD_MODTYPE_ELF_MODULE     "elf module"
+#define FREEBSD_MODTYPE_ELF_MODULE_OBJ "elf obj module"
+#define FREEBSD_MODTYPE_RAW            "raw"
+
+#define FREEBSD_BOOTINFO_VERSION 1
+
+struct grub_freebsd_bootinfo
+{
+  grub_uint32_t version;
+  grub_uint8_t unused1[44];
+  grub_uint32_t length;
+  grub_uint8_t unused2;
+  grub_uint8_t boot_device;
+  grub_uint8_t unused3[18];
+  grub_uint32_t kern_end;
+  grub_uint32_t environment;
+  grub_uint32_t tags;
+} __attribute__ ((packed));
+
+struct grub_openbsd_bios_mmap
+{
+  grub_uint64_t addr;
+  grub_uint64_t len;
+#define        OPENBSD_MMAP_AVAILABLE  1
+#define        OPENBSD_MMAP_RESERVED 2
+#define        OPENBSD_MMAP_ACPI       3
+#define        OPENBSD_MMAP_NVS        4
+  grub_uint32_t type;
+};
+
+void grub_unix_real_boot (grub_addr_t entry, ...)
+     __attribute__ ((cdecl,noreturn));
+grub_err_t grub_freebsd_load_elfmodule32 (grub_file_t file, int argc,
+                                         char *argv[], grub_addr_t *kern_end);
+grub_err_t grub_freebsd_load_elfmodule_obj64 (grub_file_t file, int argc,
+                                             char *argv[],
+                                             grub_addr_t *kern_end);
+grub_err_t grub_freebsd_load_elf_meta32 (grub_file_t file,
+                                        grub_addr_t *kern_end);
+grub_err_t grub_freebsd_load_elf_meta64 (grub_file_t file,
+                                        grub_addr_t *kern_end);
+
+grub_err_t grub_freebsd_add_meta (grub_uint32_t type, void *data,
+                                 grub_uint32_t len);
+grub_err_t grub_freebsd_add_meta_module (char *filename, char *type,
+                                        int argc, char **argv,
+                                        grub_addr_t addr, grub_uint32_t size);
+
+extern grub_uint8_t grub_bsd64_trampoline_start, grub_bsd64_trampoline_end;
+extern grub_uint32_t grub_bsd64_trampoline_selfjump;
+extern grub_uint32_t grub_bsd64_trampoline_gdt;
+
+#endif /* ! GRUB_BSD_CPU_HEADER */
diff --git a/grub-core/include/grub/i386/cmos.h b/grub-core/include/grub/i386/cmos.h
new file mode 100644 (file)
index 0000000..8b1fa35
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef        GRUB_CPU_CMOS_H
+#define        GRUB_CPU_CMOS_H 1
+
+#include <grub/types.h>
+#include <grub/cpu/io.h>
+
+#define GRUB_CMOS_ADDR_REG     0x70
+#define GRUB_CMOS_DATA_REG     0x71
+
+#endif /* GRUB_CPU_CMOS_H */
diff --git a/grub-core/include/grub/i386/coreboot/boot.h b/grub-core/include/grub/i386/coreboot/boot.h
new file mode 100644 (file)
index 0000000..6cd23aa
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/pc/boot.h>
diff --git a/grub-core/include/grub/i386/coreboot/console.h b/grub-core/include/grub/i386/coreboot/console.h
new file mode 100644 (file)
index 0000000..2ffef73
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_CONSOLE_HEADER
+#define GRUB_MACHINE_CONSOLE_HEADER    1
+
+void grub_vga_text_init (void);
+void grub_vga_text_fini (void);
+
+#endif /* ! GRUB_MACHINE_CONSOLE_HEADER */
diff --git a/grub-core/include/grub/i386/coreboot/init.h b/grub-core/include/grub/i386/coreboot/init.h
new file mode 100644 (file)
index 0000000..e670074
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_INIT_I386_LINUXBIOS_HEADER
+#define GRUB_INIT_I386_LINUXBIOS_HEADER                1
+
+#include <grub/symbol.h>
+#include <grub/i386/pc/memory.h>
+
+void EXPORT_FUNC(grub_stop) (void) __attribute__ ((noreturn));
+void EXPORT_FUNC(grub_stop_floppy) (void);
+
+#endif
diff --git a/grub-core/include/grub/i386/coreboot/kernel.h b/grub-core/include/grub/i386/coreboot/kernel.h
new file mode 100644 (file)
index 0000000..fb60668
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_MACHINE_HEADER
+#define GRUB_KERNEL_MACHINE_HEADER     1
+
+#include <grub/symbol.h>
+
+#ifndef ASM_FILE
+extern char grub_prefix[];
+#endif
+
+#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/coreboot/loader.h b/grub-core/include/grub/i386/coreboot/loader.h
new file mode 100644 (file)
index 0000000..d3f36bb
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/cpu/loader.h>
diff --git a/grub-core/include/grub/i386/coreboot/memory.h b/grub-core/include/grub/i386/coreboot/memory.h
new file mode 100644 (file)
index 0000000..664086a
--- /dev/null
@@ -0,0 +1,71 @@
+/* memory.h - describe the memory map */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GRUB_MEMORY_MACHINE_LB_HEADER
+#define _GRUB_MEMORY_MACHINE_LB_HEADER      1
+
+#include <grub/symbol.h>
+#include <grub/i386/pc/memory.h>
+
+#ifndef ASM_FILE
+#include <grub/err.h>
+#include <grub/types.h>
+#endif
+
+#define GRUB_MEMORY_MACHINE_LOWER_USABLE               0x9fc00         /* 640 kiB - 1 kiB */
+
+#define GRUB_MEMORY_MACHINE_UPPER_START                        0x100000        /* 1 MiB */
+#define GRUB_MEMORY_MACHINE_LOWER_SIZE                 GRUB_MEMORY_MACHINE_UPPER_START
+
+#ifndef ASM_FILE
+
+struct grub_linuxbios_table_header
+{
+  char signature[4];
+  grub_uint32_t size;
+};
+typedef struct grub_linuxbios_table_header *grub_linuxbios_table_header_t;
+
+struct grub_linuxbios_table_item
+{
+#define GRUB_LINUXBIOS_MEMBER_UNUSED           0x00
+#define GRUB_LINUXBIOS_MEMBER_MEMORY           0x01
+#define GRUB_LINUXBIOS_MEMBER_LINK              0x11
+  grub_uint32_t tag;
+  grub_uint32_t size;
+};
+typedef struct grub_linuxbios_table_item *grub_linuxbios_table_item_t;
+
+struct grub_linuxbios_mem_region
+{
+  grub_uint64_t addr;
+  grub_uint64_t size;
+#define GRUB_MACHINE_MEMORY_AVAILABLE          1
+  grub_uint32_t type;
+};
+typedef struct grub_linuxbios_mem_region *mem_region_t;
+
+void grub_machine_mmap_init (void);
+
+grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
+     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
+
+#endif
+
+#endif /* ! _GRUB_MEMORY_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/coreboot/serial.h b/grub-core/include/grub/i386/coreboot/serial.h
new file mode 100644 (file)
index 0000000..b6819d5
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_SERIAL_HEADER
+#define GRUB_MACHINE_SERIAL_HEADER     1
+
+#define GRUB_MACHINE_SERIAL_PORTS { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }
+
+#endif
diff --git a/grub-core/include/grub/i386/coreboot/time.h b/grub-core/include/grub/i386/coreboot/time.h
new file mode 100644 (file)
index 0000000..2298ee8
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/pc/time.h>
diff --git a/grub-core/include/grub/i386/cpuid.h b/grub-core/include/grub/i386/cpuid.h
new file mode 100644 (file)
index 0000000..09b313b
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CPU_CPUID_HEADER
+#define GRUB_CPU_CPUID_HEADER 1
+
+extern unsigned char grub_cpuid_has_longmode;
+
+#endif
diff --git a/grub-core/include/grub/i386/efi/kernel.h b/grub-core/include/grub/i386/efi/kernel.h
new file mode 100644 (file)
index 0000000..c0549f4
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_KERNEL_HEADER
+#define GRUB_MACHINE_KERNEL_HEADER   1
+
+/* The prefix which points to the directory where GRUB modules and its
+   configuration file are located.  */
+extern char grub_prefix[];
+
+/* The offset of GRUB_PREFIX.  */
+#define GRUB_KERNEL_MACHINE_PREFIX             0x8
+
+/* End of the data section. */
+#define GRUB_KERNEL_MACHINE_DATA_END           0x50
+
+#endif /* ! GRUB_MACHINE_KERNEL_HEADER */
+
diff --git a/grub-core/include/grub/i386/efi/loader.h b/grub-core/include/grub/i386/efi/loader.h
new file mode 100644 (file)
index 0000000..222dae8
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER     1
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/efi/memory.h b/grub-core/include/grub/i386/efi/memory.h
new file mode 100644 (file)
index 0000000..c9a61bb
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/efi/memory.h>
diff --git a/grub-core/include/grub/i386/efi/serial.h b/grub-core/include/grub/i386/efi/serial.h
new file mode 100644 (file)
index 0000000..2d85634
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/serial.h>
diff --git a/grub-core/include/grub/i386/efi/time.h b/grub-core/include/grub/i386/efi/time.h
new file mode 100644 (file)
index 0000000..7a9241f
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_TIME_HEADER
+#define GRUB_MACHINE_TIME_HEADER       1
+
+#include <grub/efi/time.h>
+
+#endif /* ! GRUB_MACHINE_TIME_HEADER */
diff --git a/grub-core/include/grub/i386/efiemu.h b/grub-core/include/grub/i386/efiemu.h
new file mode 100644 (file)
index 0000000..edb13ff
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ARCH_EFI_EMU_HEADER
+#define GRUB_ARCH_EFI_EMU_HEADER       1
+
+grub_err_t
+grub_arch_efiemu_relocate_symbols32 (grub_efiemu_segment_t segs,
+                                    struct grub_efiemu_elf_sym *elfsyms,
+                                    void *ehdr);
+grub_err_t
+grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs,
+                                    struct grub_efiemu_elf_sym *elfsyms,
+                                    void *ehdr);
+
+int grub_arch_efiemu_check_header32 (void *ehdr);
+int grub_arch_efiemu_check_header64 (void *ehdr);
+#endif
diff --git a/grub-core/include/grub/i386/freebsd_linker.h b/grub-core/include/grub/i386/freebsd_linker.h
new file mode 100644 (file)
index 0000000..3c1eb64
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*-
+ * Copyright (c) 1997-2000 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: stable/8/sys/sys/linker.h 199583 2009-11-20 15:27:52Z jhb $
+ */
+
+#ifndef GRUB_FREEBSD_LINKER_CPU_HEADER
+#define GRUB_FREEBSD_LINKER_CPU_HEADER 1
+
+#define FREEBSD_MODINFO_END            0x0000  /* End of list */
+#define FREEBSD_MODINFO_NAME           0x0001  /* Name of module (string) */
+#define FREEBSD_MODINFO_TYPE           0x0002  /* Type of module (string) */
+#define FREEBSD_MODINFO_ADDR           0x0003  /* Loaded address */
+#define FREEBSD_MODINFO_SIZE           0x0004  /* Size of module */
+#define FREEBSD_MODINFO_EMPTY          0x0005  /* Has been deleted */
+#define FREEBSD_MODINFO_ARGS           0x0006  /* Parameters string */
+#define FREEBSD_MODINFO_METADATA       0x8000  /* Module-specfic */
+
+#define FREEBSD_MODINFOMD_AOUTEXEC     0x0001  /* a.out exec header */
+#define FREEBSD_MODINFOMD_ELFHDR       0x0002  /* ELF header */
+#define FREEBSD_MODINFOMD_SSYM         0x0003  /* start of symbols */
+#define FREEBSD_MODINFOMD_ESYM         0x0004  /* end of symbols */
+#define FREEBSD_MODINFOMD_DYNAMIC      0x0005  /* _DYNAMIC pointer */
+#define FREEBSD_MODINFOMD_ENVP         0x0006  /* envp[] */
+#define FREEBSD_MODINFOMD_HOWTO                0x0007  /* boothowto */
+#define FREEBSD_MODINFOMD_KERNEND      0x0008  /* kernend */
+#define FREEBSD_MODINFOMD_SHDR         0x0009  /* section header table */
+#define FREEBSD_MODINFOMD_NOCOPY       0x8000  /* don't copy this metadata to the kernel */
+
+#define FREEBSD_MODINFOMD_SMAP         0x1001
+
+#define FREEBSD_MODINFOMD_DEPLIST      (0x4001 | FREEBSD_MODINFOMD_NOCOPY)  /* depends on */
+
+#endif
diff --git a/grub-core/include/grub/i386/freebsd_reboot.h b/grub-core/include/grub/i386/freebsd_reboot.h
new file mode 100644 (file)
index 0000000..9c17f6e
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*-
+ * Copyright (c) 1982, 1986, 1988, 1993, 1994
+ *      The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *      @(#)reboot.h    8.3 (Berkeley) 12/13/94
+ * $FreeBSD: stable/8/sys/sys/reboot.h 199583 2009-11-20 15:27:52Z jhb $
+ */
+
+#ifndef GRUB_FREEBSD_REBOOT_CPU_HEADER
+#define GRUB_FREEBSD_REBOOT_CPU_HEADER 1
+
+#define FREEBSD_RB_ASKNAME     (1 << 0)  /* ask for file name to reboot from */
+#define FREEBSD_RB_SINGLE       (1 << 1)  /* reboot to single user only */
+#define FREEBSD_RB_NOSYNC       (1 << 2)  /* dont sync before reboot */
+#define FREEBSD_RB_HALT         (1 << 3)  /* don't reboot, just halt */
+#define FREEBSD_RB_INITNAME     (1 << 4)  /* name given for /etc/init (unused) */
+#define FREEBSD_RB_DFLTROOT     (1 << 5)  /* use compiled-in rootdev */
+#define FREEBSD_RB_KDB          (1 << 6)  /* give control to kernel debugger */
+#define FREEBSD_RB_RDONLY       (1 << 7)  /* mount root fs read-only */
+#define FREEBSD_RB_DUMP         (1 << 8)  /* dump kernel memory before reboot */
+#define FREEBSD_RB_MINIROOT     (1 << 9)  /* mini-root present in memory at boot time */
+#define FREEBSD_RB_CONFIG       (1 << 10) /* invoke user configuration routing */
+#define FREEBSD_RB_VERBOSE      (1 << 11) /* print all potentially useful info */
+#define FREEBSD_RB_SERIAL       (1 << 12) /* user serial port as console */
+#define FREEBSD_RB_CDROM        (1 << 13) /* use cdrom as root */
+#define FREEBSD_RB_GDB         (1 << 15) /* use GDB remote debugger instead of DDB */
+#define FREEBSD_RB_MUTE                (1 << 16) /* Come up with the console muted */
+#define FREEBSD_RB_PAUSE       (1 << 20)
+#define FREEBSD_RB_QUIET       (1 << 21)
+#define FREEBSD_RB_NOINTR      (1 << 28)
+#define FREENSD_RB_MULTIPLE    (1 << 29)  /* Use multiple consoles */
+#define FREEBSD_RB_DUAL                FREENSD_RB_MULTIPLE
+#define FREEBSD_RB_BOOTINFO     (1 << 31) /* have `struct bootinfo *' arg */
+
+#endif
diff --git a/grub-core/include/grub/i386/ieee1275/console.h b/grub-core/include/grub/i386/ieee1275/console.h
new file mode 100644 (file)
index 0000000..854724a
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CONSOLE_MACHINE_HEADER
+#define GRUB_CONSOLE_MACHINE_HEADER 1
+
+#include <grub/symbol.h>
+
+/* Initialize the console system.  */
+void grub_console_init (void);
+
+/* Finish the console system.  */
+void grub_console_fini (void);
+
+#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/ieee1275/ieee1275.h b/grub-core/include/grub/i386/ieee1275/ieee1275.h
new file mode 100644 (file)
index 0000000..2625f02
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/powerpc/ieee1275/ieee1275.h>
diff --git a/grub-core/include/grub/i386/ieee1275/kernel.h b/grub-core/include/grub/i386/ieee1275/kernel.h
new file mode 100644 (file)
index 0000000..dccf8cb
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/powerpc/ieee1275/kernel.h>
diff --git a/grub-core/include/grub/i386/ieee1275/loader.h b/grub-core/include/grub/i386/ieee1275/loader.h
new file mode 100644 (file)
index 0000000..20df2e1
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER     1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/multiboot.h>
+
+void grub_rescue_cmd_linux (int argc, char *argv[]);
+void grub_rescue_cmd_initrd (int argc, char *argv[]);
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/ieee1275/memory.h b/grub-core/include/grub/i386/ieee1275/memory.h
new file mode 100644 (file)
index 0000000..386ee4a
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/pc/memory.h>
diff --git a/grub-core/include/grub/i386/ieee1275/serial.h b/grub-core/include/grub/i386/ieee1275/serial.h
new file mode 100644 (file)
index 0000000..2d85634
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/serial.h>
diff --git a/grub-core/include/grub/i386/ieee1275/time.h b/grub-core/include/grub/i386/ieee1275/time.h
new file mode 100644 (file)
index 0000000..6f474ba
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/powerpc/ieee1275/time.h>
diff --git a/grub-core/include/grub/i386/io.h b/grub-core/include/grub/i386/io.h
new file mode 100644 (file)
index 0000000..ae12a3e
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1996,2000,2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Based on sys/io.h from GNU libc. */
+
+#ifndef        GRUB_IO_H
+#define        GRUB_IO_H       1
+
+typedef unsigned short int grub_port_t;
+
+static __inline unsigned char
+grub_inb (unsigned short int port)
+{
+  unsigned char _v;
+
+  __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
+  return _v;
+}
+
+static __inline unsigned short int
+grub_inw (unsigned short int port)
+{
+  unsigned short _v;
+
+  __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (port));
+  return _v;
+}
+
+static __inline unsigned int
+grub_inl (unsigned short int port)
+{
+  unsigned int _v;
+
+  __asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (port));
+  return _v;
+}
+
+static __inline void
+grub_outb (unsigned char value, unsigned short int port)
+{
+  __asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (port));
+}
+
+static __inline void
+grub_outw (unsigned short int value, unsigned short int port)
+{
+  __asm__ __volatile__ ("outw %w0,%w1": :"a" (value), "Nd" (port));
+
+}
+
+static __inline void
+grub_outl (unsigned int value, unsigned short int port)
+{
+  __asm__ __volatile__ ("outl %0,%w1": :"a" (value), "Nd" (port));
+}
+
+#endif /* _SYS_IO_H */
diff --git a/grub-core/include/grub/i386/kernel.h b/grub-core/include/grub/i386/kernel.h
new file mode 100644 (file)
index 0000000..5514c8c
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_CPU_HEADER
+#define GRUB_KERNEL_CPU_HEADER 1
+
+
+#ifdef GRUB_MACHINE_IEEE1275
+#define GRUB_MOD_ALIGN 0x1000
+#else
+#define GRUB_MOD_ALIGN 0x1
+#endif
+
+/* Non-zero value is only needed for PowerMacs.  */
+#define GRUB_MOD_GAP 0x0
+
+#define GRUB_KERNEL_CPU_PREFIX 0x2
+#define GRUB_KERNEL_CPU_DATA_END       0x42
+
+#endif
diff --git a/grub-core/include/grub/i386/linux.h b/grub-core/include/grub/i386/linux.h
new file mode 100644 (file)
index 0000000..f02a722
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LINUX_MACHINE_HEADER
+#define GRUB_LINUX_MACHINE_HEADER      1
+
+#define GRUB_LINUX_MAGIC_SIGNATURE     0x53726448      /* "HdrS" */
+#define GRUB_LINUX_DEFAULT_SETUP_SECTS 4
+#define GRUB_LINUX_INITRD_MAX_ADDRESS  0x37FFFFFF
+#define GRUB_LINUX_MAX_SETUP_SECTS     64
+#define GRUB_LINUX_BOOT_LOADER_TYPE    0x72
+#define GRUB_LINUX_HEAP_END_OFFSET     (0x9000 - 0x200)
+
+#define GRUB_LINUX_BZIMAGE_ADDR                0x100000
+#define GRUB_LINUX_ZIMAGE_ADDR         0x10000
+#define GRUB_LINUX_OLD_REAL_MODE_ADDR  0x90000
+#define GRUB_LINUX_SETUP_STACK         0x9000
+
+#define GRUB_LINUX_FLAG_BIG_KERNEL     0x1
+#define GRUB_LINUX_FLAG_QUIET          0x20
+#define GRUB_LINUX_FLAG_CAN_USE_HEAP   0x80
+
+/* Linux's video mode selection support. Actually I hate it!  */
+#define GRUB_LINUX_VID_MODE_NORMAL     0xFFFF
+#define GRUB_LINUX_VID_MODE_EXTENDED   0xFFFE
+#define GRUB_LINUX_VID_MODE_ASK                0xFFFD
+#define GRUB_LINUX_VID_MODE_VESA_START 0x0300
+
+#define GRUB_LINUX_SETUP_MOVE_SIZE     0x9100
+#define GRUB_LINUX_CL_MAGIC            0xA33F
+
+#ifdef __x86_64__
+
+#define GRUB_LINUX_EFI_SIGNATURE       \
+  ('4' << 24 | '6' << 16 | 'L' << 8 | 'E')
+
+#else
+
+#define GRUB_LINUX_EFI_SIGNATURE       \
+  ('2' << 24 | '3' << 16 | 'L' << 8 | 'E')
+
+#endif
+
+#define GRUB_LINUX_EFI_SIGNATURE_0204  \
+  ('L' << 24 | 'I' << 16 | 'F' << 8 | 'E')
+
+#define GRUB_LINUX_OFW_SIGNATURE       \
+  (' ' << 24 | 'W' << 16 | 'F' << 8 | 'O')
+
+#ifndef ASM_FILE
+
+#define GRUB_E820_RAM        1
+#define GRUB_E820_RESERVED   2
+#define GRUB_E820_ACPI       3
+#define GRUB_E820_NVS        4
+#define GRUB_E820_EXEC_CODE  5
+
+#define GRUB_E820_MAX_ENTRY  128
+
+struct grub_e820_mmap
+{
+  grub_uint64_t addr;
+  grub_uint64_t size;
+  grub_uint32_t type;
+} __attribute__((packed));
+
+#define GRUB_VIDEO_LINUX_TYPE_TEXT     0x01
+#define GRUB_VIDEO_LINUX_TYPE_VESA     0x23    /* VESA VGA in graphic mode.  */
+#define GRUB_VIDEO_LINUX_TYPE_SIMPLE   0x70    /* Linear framebuffer without any additional functions.  */
+
+/* For the Linux/i386 boot protocol version 2.03.  */
+struct linux_kernel_header
+{
+  grub_uint8_t code1[0x0020];
+  grub_uint16_t cl_magic;              /* Magic number 0xA33F */
+  grub_uint16_t cl_offset;             /* The offset of command line */
+  grub_uint8_t code2[0x01F1 - 0x0020 - 2 - 2];
+  grub_uint8_t setup_sects;            /* The size of the setup in sectors */
+  grub_uint16_t root_flags;            /* If the root is mounted readonly */
+  grub_uint16_t syssize;               /* obsolete */
+  grub_uint16_t swap_dev;              /* obsolete */
+  grub_uint16_t ram_size;              /* obsolete */
+  grub_uint16_t vid_mode;              /* Video mode control */
+  grub_uint16_t root_dev;              /* Default root device number */
+  grub_uint16_t boot_flag;             /* 0xAA55 magic number */
+  grub_uint16_t jump;                  /* Jump instruction */
+  grub_uint32_t header;                        /* Magic signature "HdrS" */
+  grub_uint16_t version;               /* Boot protocol version supported */
+  grub_uint32_t realmode_swtch;                /* Boot loader hook */
+  grub_uint16_t start_sys;             /* The load-low segment (obsolete) */
+  grub_uint16_t kernel_version;                /* Points to kernel version string */
+  grub_uint8_t type_of_loader;         /* Boot loader identifier */
+#define LINUX_LOADER_ID_LILO           0x0
+#define LINUX_LOADER_ID_LOADLIN                0x1
+#define LINUX_LOADER_ID_BOOTSECT       0x2
+#define LINUX_LOADER_ID_SYSLINUX       0x3
+#define LINUX_LOADER_ID_ETHERBOOT      0x4
+#define LINUX_LOADER_ID_ELILO          0x5
+#define LINUX_LOADER_ID_GRUB           0x7
+#define LINUX_LOADER_ID_UBOOT          0x8
+#define LINUX_LOADER_ID_XEN            0x9
+#define LINUX_LOADER_ID_GUJIN          0xa
+#define LINUX_LOADER_ID_QEMU           0xb
+  grub_uint8_t loadflags;              /* Boot protocol option flags */
+  grub_uint16_t setup_move_size;       /* Move to high memory size */
+  grub_uint32_t code32_start;          /* Boot loader hook */
+  grub_uint32_t ramdisk_image;         /* initrd load address */
+  grub_uint32_t ramdisk_size;          /* initrd size */
+  grub_uint32_t bootsect_kludge;       /* obsolete */
+  grub_uint16_t heap_end_ptr;          /* Free memory after setup end */
+  grub_uint16_t pad1;                  /* Unused */
+  char *cmd_line_ptr;                  /* Points to the kernel command line */
+  grub_uint32_t initrd_addr_max;        /* Highest address for initrd */
+} __attribute__ ((packed));
+
+/* Boot parameters for Linux based on 2.6.12. This is used by the setup
+   sectors of Linux, and must be simulated by GRUB on EFI, because
+   the setup sectors depend on BIOS.  */
+struct linux_kernel_params
+{
+  grub_uint8_t video_cursor_x;         /* 0 */
+  grub_uint8_t video_cursor_y;
+
+  grub_uint16_t ext_mem;               /* 2 */
+
+  grub_uint16_t video_page;            /* 4 */
+  grub_uint8_t video_mode;             /* 6 */
+  grub_uint8_t video_width;            /* 7 */
+
+  grub_uint8_t padding1[0xa - 0x8];
+
+  grub_uint16_t video_ega_bx;          /* a */
+
+  grub_uint8_t padding2[0xe - 0xc];
+
+  grub_uint8_t video_height;           /* e */
+  grub_uint8_t have_vga;               /* f */
+  grub_uint16_t font_size;             /* 10 */
+
+  grub_uint16_t lfb_width;             /* 12 */
+  grub_uint16_t lfb_height;            /* 14 */
+  grub_uint16_t lfb_depth;             /* 16 */
+  grub_uint32_t lfb_base;              /* 18 */
+  grub_uint32_t lfb_size;              /* 1c */
+
+  grub_uint16_t cl_magic;              /* 20 */
+  grub_uint16_t cl_offset;
+
+  grub_uint16_t lfb_line_len;          /* 24 */
+  grub_uint8_t red_mask_size;          /* 26 */
+  grub_uint8_t red_field_pos;
+  grub_uint8_t green_mask_size;
+  grub_uint8_t green_field_pos;
+  grub_uint8_t blue_mask_size;
+  grub_uint8_t blue_field_pos;
+  grub_uint8_t reserved_mask_size;
+  grub_uint8_t reserved_field_pos;
+  grub_uint16_t vesapm_segment;                /* 2e */
+  grub_uint16_t vesapm_offset;         /* 30 */
+  grub_uint16_t lfb_pages;             /* 32 */
+  grub_uint16_t vesa_attrib;           /* 34 */
+  grub_uint32_t capabilities;          /* 36 */
+
+  grub_uint8_t padding3[0x40 - 0x3a];
+
+  grub_uint16_t apm_version;           /* 40 */
+  grub_uint16_t apm_code_segment;      /* 42 */
+  grub_uint32_t apm_entry;             /* 44 */
+  grub_uint16_t apm_16bit_code_segment;        /* 48 */
+  grub_uint16_t apm_data_segment;      /* 4a */
+  grub_uint16_t apm_flags;             /* 4c */
+  grub_uint32_t apm_code_len;          /* 4e */
+  grub_uint16_t apm_data_len;          /* 52 */
+
+  grub_uint8_t padding4[0x60 - 0x54];
+
+  grub_uint32_t ist_signature;         /* 60 */
+  grub_uint32_t ist_command;           /* 64 */
+  grub_uint32_t ist_event;             /* 68 */
+  grub_uint32_t ist_perf_level;                /* 6c */
+
+  grub_uint8_t padding5[0x80 - 0x70];
+
+  grub_uint8_t hd0_drive_info[0x10];   /* 80 */
+  grub_uint8_t hd1_drive_info[0x10];   /* 90 */
+  grub_uint16_t rom_config_len;                /* a0 */
+
+  grub_uint8_t padding6[0xb0 - 0xa2];
+
+  grub_uint32_t ofw_signature;         /* b0 */
+  grub_uint32_t ofw_num_items;         /* b4 */
+  grub_uint32_t ofw_cif_handler;       /* b8 */
+  grub_uint32_t ofw_idt;               /* bc */
+
+  grub_uint8_t padding7[0x1b8 - 0xc0];
+
+  union
+    {
+      struct
+        {
+          grub_uint32_t efi_system_table;      /* 1b8 */
+          grub_uint32_t padding7_1;            /* 1bc */
+          grub_uint32_t efi_signature;         /* 1c0 */
+          grub_uint32_t efi_mem_desc_size;     /* 1c4 */
+          grub_uint32_t efi_mem_desc_version;  /* 1c8 */
+          grub_uint32_t efi_mmap_size;         /* 1cc */
+          grub_uint32_t efi_mmap;              /* 1d0 */
+        } v0204;
+      struct
+        {
+          grub_uint32_t padding7_1;            /* 1b8 */
+          grub_uint32_t padding7_2;            /* 1bc */
+          grub_uint32_t efi_signature;         /* 1c0 */
+          grub_uint32_t efi_system_table;      /* 1c4 */
+          grub_uint32_t efi_mem_desc_size;     /* 1c8 */
+          grub_uint32_t efi_mem_desc_version;  /* 1cc */
+          grub_uint32_t efi_mmap;              /* 1d0 */
+          grub_uint32_t efi_mmap_size;         /* 1d4 */
+          grub_uint32_t efi_system_table_hi;   /* 1d8 */
+          grub_uint32_t efi_mmap_hi;           /* 1dc */
+        } v0206;
+    };
+
+  grub_uint32_t alt_mem;               /* 1e0 */
+
+  grub_uint8_t padding8[0x1e8 - 0x1e4];
+
+  grub_uint8_t mmap_size;              /* 1e8 */
+
+  grub_uint8_t padding9[0x1f1 - 0x1e9];
+
+  grub_uint8_t setup_sects;            /* The size of the setup in sectors */
+  grub_uint16_t root_flags;            /* If the root is mounted readonly */
+  grub_uint16_t syssize;               /* obsolete */
+  grub_uint16_t swap_dev;              /* obsolete */
+  grub_uint16_t ram_size;              /* obsolete */
+  grub_uint16_t vid_mode;              /* Video mode control */
+  grub_uint16_t root_dev;              /* Default root device number */
+
+  grub_uint8_t padding10;              /* 1fe */
+  grub_uint8_t ps_mouse;               /* 1ff */
+
+  grub_uint16_t jump;                  /* Jump instruction */
+  grub_uint32_t header;                        /* Magic signature "HdrS" */
+  grub_uint16_t version;               /* Boot protocol version supported */
+  grub_uint32_t realmode_swtch;                /* Boot loader hook */
+  grub_uint16_t start_sys;             /* The load-low segment (obsolete) */
+  grub_uint16_t kernel_version;                /* Points to kernel version string */
+  grub_uint8_t type_of_loader;         /* Boot loader identifier */
+  grub_uint8_t loadflags;              /* Boot protocol option flags */
+  grub_uint16_t setup_move_size;       /* Move to high memory size */
+  grub_uint32_t code32_start;          /* Boot loader hook */
+  grub_uint32_t ramdisk_image;         /* initrd load address */
+  grub_uint32_t ramdisk_size;          /* initrd size */
+  grub_uint32_t bootsect_kludge;       /* obsolete */
+  grub_uint16_t heap_end_ptr;          /* Free memory after setup end */
+  grub_uint16_t pad1;                  /* Unused */
+  grub_uint32_t cmd_line_ptr;          /* Points to the kernel command line */
+
+  grub_uint8_t pad2[164];              /* 22c */
+  struct grub_e820_mmap e820_map[GRUB_E820_MAX_ENTRY]; /* 2d0 */
+
+} __attribute__ ((packed));
+#endif /* ! ASM_FILE */
+
+#endif /* ! GRUB_LINUX_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/loader.h b/grub-core/include/grub/i386/loader.h
new file mode 100644 (file)
index 0000000..05954b6
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_CPU_HEADER
+#define GRUB_LOADER_CPU_HEADER 1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/symbol.h>
+
+extern grub_addr_t EXPORT_VAR(grub_os_area_addr);
+extern grub_size_t EXPORT_VAR(grub_os_area_size);
+
+#ifdef GRUB_MACHINE_PCBIOS
+extern grub_uint32_t EXPORT_VAR(grub_linux_prot_size);
+extern char *EXPORT_VAR(grub_linux_tmp_addr);
+extern char *EXPORT_VAR(grub_linux_real_addr);
+extern grub_int32_t EXPORT_VAR(grub_linux_is_bzimage);
+grub_err_t EXPORT_FUNC(grub_linux16_real_boot) (void);
+#endif
+
+#endif /* ! GRUB_LOADER_CPU_HEADER */
diff --git a/grub-core/include/grub/i386/macho.h b/grub-core/include/grub/i386/macho.h
new file mode 100644 (file)
index 0000000..f22c211
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CPU_MACHO_H
+#define GRUB_CPU_MACHO_H 1
+
+#include <grub/macho.h>
+
+#define GRUB_MACHO_CPUTYPE_IS_HOST32(x) ((x)==0x00000007)
+#define GRUB_MACHO_CPUTYPE_IS_HOST64(x) ((x)==0x01000007)
+
+struct grub_macho_thread32
+{
+  grub_uint32_t cmd;
+  grub_uint32_t cmdsize;
+  grub_uint8_t unknown1[48];
+  grub_uint32_t entry_point;
+  grub_uint8_t unknown2[20];
+} __attribute__ ((packed));
+
+
+struct grub_macho_thread64
+{
+  grub_uint32_t cmd;
+  grub_uint32_t cmdsize;
+  grub_uint8_t unknown1[0x88];
+  grub_uint64_t entry_point;
+  grub_uint8_t unknown2[0x20];
+} __attribute__ ((packed));
+
+#endif
diff --git a/grub-core/include/grub/i386/memory.h b/grub-core/include/grub/i386/memory.h
new file mode 100644 (file)
index 0000000..466947c
--- /dev/null
@@ -0,0 +1,30 @@
+/* memory.h - describe the memory map */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MEMORY_CPU_HEADER
+#define GRUB_MEMORY_CPU_HEADER 1
+
+/* The flag for protected mode.  */
+#define GRUB_MEMORY_CPU_CR0_PE_ON              0x1
+#define GRUB_MEMORY_CPU_CR4_PAE_ON             0x00000040
+#define GRUB_MEMORY_CPU_CR0_PAGING_ON          0x80000000
+#define GRUB_MEMORY_CPU_AMD64_MSR              0xc0000080
+#define GRUB_MEMORY_CPU_AMD64_MSR_ON           0x00000100
+
+#endif /* ! GRUB_MEMORY_CPU_HEADER */
diff --git a/grub-core/include/grub/i386/multiboot.h b/grub-core/include/grub/i386/multiboot.h
new file mode 100644 (file)
index 0000000..1c711fa
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MULTIBOOT_CPU_HEADER
+#define GRUB_MULTIBOOT_CPU_HEADER      1
+
+extern grub_uint32_t grub_multiboot_payload_eip;
+extern char *grub_multiboot_payload_orig;
+extern grub_addr_t grub_multiboot_payload_dest;
+extern grub_size_t grub_multiboot_payload_size;
+
+#define MULTIBOOT_INITIAL_STATE  { .eax = MULTIBOOT_BOOTLOADER_MAGIC,  \
+    .ecx = 0,                                                          \
+    .edx = 0,                                                          \
+    /* Set esp to some random location in low memory to avoid breaking */ \
+    /* non-compliant kernels.  */                                      \
+    .esp = 0x7ff00                                                     \
+      }
+#define MULTIBOOT_ENTRY_REGISTER eip
+#define MULTIBOOT_MBI_REGISTER ebx
+#define MULTIBOOT_ARCHITECTURE_CURRENT MULTIBOOT_ARCHITECTURE_I386
+
+#define MULTIBOOT_ELF32_MACHINE EM_386
+#define MULTIBOOT_ELF64_MACHINE EM_X86_64
+
+#endif /* ! GRUB_MULTIBOOT_CPU_HEADER */
diff --git a/grub-core/include/grub/i386/multiboot/boot.h b/grub-core/include/grub/i386/multiboot/boot.h
new file mode 100644 (file)
index 0000000..c33f9ba
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/boot.h>
diff --git a/grub-core/include/grub/i386/multiboot/console.h b/grub-core/include/grub/i386/multiboot/console.h
new file mode 100644 (file)
index 0000000..774399a
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/console.h>
diff --git a/grub-core/include/grub/i386/multiboot/init.h b/grub-core/include/grub/i386/multiboot/init.h
new file mode 100644 (file)
index 0000000..fd935c3
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/init.h>
diff --git a/grub-core/include/grub/i386/multiboot/kernel.h b/grub-core/include/grub/i386/multiboot/kernel.h
new file mode 100644 (file)
index 0000000..b41e86e
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/kernel.h>
diff --git a/grub-core/include/grub/i386/multiboot/loader.h b/grub-core/include/grub/i386/multiboot/loader.h
new file mode 100644 (file)
index 0000000..1c725be
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/loader.h>
diff --git a/grub-core/include/grub/i386/multiboot/memory.h b/grub-core/include/grub/i386/multiboot/memory.h
new file mode 100644 (file)
index 0000000..8dd6f7c
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/memory.h>
diff --git a/grub-core/include/grub/i386/multiboot/serial.h b/grub-core/include/grub/i386/multiboot/serial.h
new file mode 100644 (file)
index 0000000..2d85634
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/serial.h>
diff --git a/grub-core/include/grub/i386/multiboot/time.h b/grub-core/include/grub/i386/multiboot/time.h
new file mode 100644 (file)
index 0000000..7177c74
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/time.h>
diff --git a/grub-core/include/grub/i386/netbsd_bootinfo.h b/grub-core/include/grub/i386/netbsd_bootinfo.h
new file mode 100644 (file)
index 0000000..776ecf3
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*     $NetBSD: bootinfo.h,v 1.16 2009/08/24 02:15:46 jmcneill Exp $   */
+
+/*
+ * Copyright (c) 1997
+ *     Matthias Drochner.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRUB_NETBSD_BOOTINFO_CPU_HEADER
+#define GRUB_NETBSD_BOOTINFO_CPU_HEADER        1
+
+#include <grub/types.h>
+
+
+#define NETBSD_BTINFO_BOOTPATH         0
+#define NETBSD_BTINFO_ROOTDEVICE       1
+#define NETBSD_BTINFO_BOOTDISK         3
+#define NETBSD_BTINFO_MEMMAP           9
+
+struct grub_netbsd_btinfo_common
+{
+  int len;
+  int type;
+};
+
+struct grub_netbsd_btinfo_mmap_header
+{
+  struct grub_netbsd_btinfo_common common;
+  grub_uint32_t count;
+};
+
+struct grub_netbsd_btinfo_mmap_entry
+{
+  grub_uint64_t addr;
+  grub_uint64_t len;
+#define        NETBSD_MMAP_AVAILABLE   1
+#define        NETBSD_MMAP_RESERVED    2
+#define        NETBSD_MMAP_ACPI        3
+#define        NETBSD_MMAP_NVS         4
+  grub_uint32_t type;
+};
+
+struct grub_netbsd_btinfo_bootpath
+{
+  struct grub_netbsd_btinfo_common common;
+  char bootpath[80];
+};
+
+struct grub_netbsd_btinfo_rootdevice
+{
+  struct grub_netbsd_btinfo_common common;
+  char devname[16];
+};
+
+struct grub_netbsd_btinfo_bootdisk
+{
+  struct grub_netbsd_btinfo_common common;
+  int labelsector;  /* label valid if != -1 */
+  struct
+    {
+      grub_uint16_t type, checksum;
+      char packname[16];
+    } label;
+  int biosdev;
+  int partition;
+};
+
+struct grub_netbsd_bootinfo
+{
+  grub_uint32_t bi_count;
+  void *bi_data[1];
+};
+
+#endif
diff --git a/grub-core/include/grub/i386/netbsd_reboot.h b/grub-core/include/grub/i386/netbsd_reboot.h
new file mode 100644 (file)
index 0000000..ee82455
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*     $NetBSD: reboot.h,v 1.25 2007/12/25 18:33:48 perry Exp $        */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993, 1994
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)reboot.h    8.3 (Berkeley) 12/13/94
+ */
+
+#ifndef GRUB_NETBSD_REBOOT_CPU_HEADER
+#define GRUB_NETBSD_REBOOT_CPU_HEADER  1
+
+#define NETBSD_RB_AUTOBOOT     0  /* flags for system auto-booting itself */
+
+#define NETBSD_RB_ASKNAME      (1 << 0)  /* ask for file name to reboot from */
+#define NETBSD_RB_SINGLE       (1 << 1)  /* reboot to single user only */
+#define NETBSD_RB_NOSYNC       (1 << 2)  /* dont sync before reboot */
+#define NETBSD_RB_HALT         (1 << 3)  /* don't reboot, just halt */
+#define NETBSD_RB_INITNAME     (1 << 4)  /* name given for /etc/init (unused) */
+#define NETBSD_RB_UNUSED1      (1 << 5)  /* was RB_DFLTROOT, obsolete */
+#define NETBSD_RB_KDB          (1 << 6)  /* give control to kernel debugger */
+#define NETBSD_RB_RDONLY       (1 << 7)  /* mount root fs read-only */
+#define NETBSD_RB_DUMP         (1 << 8)  /* dump kernel memory before reboot */
+#define NETBSD_RB_MINIROOT     (1 << 9)  /* mini-root present in memory at boot time */
+#define NETBSD_RB_STRING       (1 << 10) /* use provided bootstr */
+#define NETBSD_RB_POWERDOWN     ((1 << 11) | RB_HALT) /* turn power off (or at least halt) */
+#define NETBSD_RB_USERCONFIG   (1 << 12) /* change configured devices */
+
+#define NETBSD_AB_NORMAL       0  /* boot normally (default) */
+
+#define NETBSD_AB_QUIET                (1 << 16) /* boot quietly */
+#define NETBSD_AB_VERBOSE      (1 << 17) /* boot verbosely */
+#define NETBSD_AB_SILENT       (1 << 18) /* boot silently */
+#define NETBSD_AB_DEBUG                (1 << 19) /* boot with debug messages */
+#define NETBSD_AB_NOSMP                (1 << 28) /* Boot without SMP support.  */
+#define NETBSD_AB_NOACPI        (1 << 29) /* Boot without ACPI support.  */
+
+
+#endif
diff --git a/grub-core/include/grub/i386/openbsd_bootarg.h b/grub-core/include/grub/i386/openbsd_bootarg.h
new file mode 100644 (file)
index 0000000..ccbe1ca
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*      $OpenBSD: bootarg.h,v 1.11 2003/06/02 20:20:54 mickey Exp $     */
+     
+/*
+ * Copyright (c) 1996-1999 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GRUB_OPENBSD_BOOTARG_CPU_HEADER
+#define GRUB_OPENBSD_BOOTARG_CPU_HEADER        1
+
+#define OPENBSD_BOOTARG_APIVER (OPENBSD_BAPIV_VECTOR | \
+                                 OPENBSD_BAPIV_ENV | \
+                                 OPENBSD_BAPIV_BMEMMAP)
+
+#define OPENBSD_BAPIV_ANCIENT  0x0  /* MD old i386 bootblocks */
+#define OPENBSD_BAPIV_VARS     0x1  /* MD structure w/ add info passed */
+#define OPENBSD_BAPIV_VECTOR   0x2  /* MI vector of MD structures passed */
+#define OPENBSD_BAPIV_ENV      0x4  /* MI environment vars vector */
+#define OPENBSD_BAPIV_BMEMMAP  0x8  /* MI memory map passed is in bytes */
+
+#define OPENBSD_BOOTARG_ENV    0x1000
+#define OPENBSD_BOOTARG_END    -1
+
+#define        OPENBSD_BOOTARG_MMAP    0
+
+struct grub_openbsd_bootargs
+{
+  int ba_type;
+  int ba_size;
+  struct grub_openbsd_bootargs *ba_next;
+} __attribute__ ((packed));
+
+#endif
diff --git a/grub-core/include/grub/i386/openbsd_reboot.h b/grub-core/include/grub/i386/openbsd_reboot.h
new file mode 100644 (file)
index 0000000..3f6571a
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*      $OpenBSD: reboot.h,v 1.13 2004/03/10 23:02:53 tom Exp $ */
+/*      $NetBSD: reboot.h,v 1.9 1996/04/22 01:23:25 christos Exp $      */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993, 1994
+ *      The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *      @(#)reboot.h    8.2 (Berkeley) 7/10/94
+ */
+
+#ifndef GRUB_OPENBSD_REBOOT_CPU_HEADER
+#define GRUB_OPENBSD_REBOOT_CPU_HEADER 1
+
+#define OPENBSD_RB_ASKNAME     (1 << 0)  /* ask for file name to reboot from */
+#define OPENBSD_RB_SINGLE      (1 << 1)  /* reboot to single user only */
+#define OPENBSD_RB_NOSYNC      (1 << 2)  /* dont sync before reboot */
+#define OPENBSD_RB_HALT                (1 << 3)  /* don't reboot, just halt */
+#define OPENBSD_RB_INITNAME    (1 << 4)  /* name given for /etc/init (unused) */
+#define OPENBSD_RB_DFLTROOT    (1 << 5)  /* use compiled-in rootdev */
+#define OPENBSD_RB_KDB         (1 << 6)  /* give control to kernel debugger */
+#define OPENBSD_RB_RDONLY      (1 << 7)  /* mount root fs read-only */
+#define OPENBSD_RB_DUMP                (1 << 8)  /* dump kernel memory before reboot */
+#define OPENBSD_RB_MINIROOT    (1 << 9)  /* mini-root present in memory at boot time */
+#define OPENBSD_RB_CONFIG      (1 << 10) /* change configured devices */
+#define OPENBSD_RB_TIMEBAD     (1 << 11) /* don't call resettodr() in boot() */
+#define OPENBSD_RB_POWERDOWN   (1 << 12) /* attempt to power down machine */
+#define OPENBSD_RB_SERCONS     (1 << 13) /* use serial console if available */
+#define OPENBSD_RB_USERREQ     (1 << 14) /* boot() called at user request (e.g. ddb) */
+
+#define OPENBSD_B_DEVMAGIC     0xa0000000
+#define OPENBSD_B_ADAPTORSHIFT 24
+#define OPENBSD_B_CTRLSHIFT    20
+#define OPENBSD_B_UNITSHIFT    16
+#define OPENBSD_B_PARTSHIFT    8
+#define OPENBSD_B_TYPESHIFT    0
+
+#endif
diff --git a/grub-core/include/grub/i386/pc/biosdisk.h b/grub-core/include/grub/i386/pc/biosdisk.h
new file mode 100644 (file)
index 0000000..b87e0e4
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BIOSDISK_MACHINE_HEADER
+#define GRUB_BIOSDISK_MACHINE_HEADER   1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+#define GRUB_BIOSDISK_FLAG_LBA 1
+#define GRUB_BIOSDISK_FLAG_CDROM 2
+
+#define GRUB_BIOSDISK_CDTYPE_NO_EMUL   0
+#define GRUB_BIOSDISK_CDTYPE_1_2_M     1
+#define GRUB_BIOSDISK_CDTYPE_1_44_M    2
+#define GRUB_BIOSDISK_CDTYPE_2_88_M    3
+#define GRUB_BIOSDISK_CDTYPE_HARDDISK  4
+
+#define GRUB_BIOSDISK_CDTYPE_MASK      0xF
+
+struct grub_biosdisk_data
+{
+  int drive;
+  unsigned long cylinders;
+  unsigned long heads;
+  unsigned long sectors;
+  unsigned long flags;
+};
+
+/* Drive Parameters.  */
+struct grub_biosdisk_drp
+{
+  grub_uint16_t size;
+  grub_uint16_t flags;
+  grub_uint32_t cylinders;
+  grub_uint32_t heads;
+  grub_uint32_t sectors;
+  grub_uint64_t total_sectors;
+  grub_uint16_t bytes_per_sector;
+  /* ver 2.0 or higher */
+
+  union
+  {
+    grub_uint32_t EDD_configuration_parameters;
+
+    /* Pointer to the Device Parameter Table Extension (ver 3.0+).  */
+    grub_uint32_t dpte_pointer;
+  };
+
+  /* ver 3.0 or higher */
+  grub_uint16_t signature_dpi;
+  grub_uint8_t length_dpi;
+  grub_uint8_t reserved[3];
+  grub_uint8_t name_of_host_bus[4];
+  grub_uint8_t name_of_interface_type[8];
+  grub_uint8_t interface_path[8];
+  grub_uint8_t device_path[8];
+  grub_uint8_t reserved2;
+  grub_uint8_t checksum;
+
+  /* XXX: This is necessary, because the BIOS of Thinkpad X20
+     writes a garbage to the tail of drive parameters,
+     regardless of a size specified in a caller.  */
+  grub_uint8_t dummy[16];
+} __attribute__ ((packed));
+
+struct grub_biosdisk_cdrp
+{
+  grub_uint8_t size;
+  grub_uint8_t media_type;
+  grub_uint8_t drive_no;
+  grub_uint8_t controller_no;
+  grub_uint32_t image_lba;
+  grub_uint16_t device_spec;
+  grub_uint16_t cache_seg;
+  grub_uint16_t load_seg;
+  grub_uint16_t length_sec512;
+  grub_uint8_t cylinders;
+  grub_uint8_t sectors;
+  grub_uint8_t heads;
+  grub_uint8_t dummy[16];
+} __attribute__ ((packed));
+
+/* Disk Address Packet.  */
+struct grub_biosdisk_dap
+{
+  grub_uint8_t length;
+  grub_uint8_t reserved;
+  grub_uint16_t blocks;
+  grub_uint32_t buffer;
+  grub_uint64_t block;
+} __attribute__ ((packed));
+
+int EXPORT_FUNC(grub_biosdisk_rw_int13_extensions) (int ah, int drive, void *dap);
+int EXPORT_FUNC(grub_biosdisk_rw_standard) (int ah, int drive, int coff, int hoff,
+                              int soff, int nsec, int segment);
+int EXPORT_FUNC(grub_biosdisk_check_int13_extensions) (int drive);
+int EXPORT_FUNC(grub_biosdisk_get_diskinfo_int13_extensions) (int drive,
+           void *drp);
+int EXPORT_FUNC(grub_biosdisk_get_cdinfo_int13_extensions) (int drive,
+           void *cdrp);
+int EXPORT_FUNC(grub_biosdisk_get_diskinfo_standard) (int drive,
+                                        unsigned long *cylinders,
+                                        unsigned long *heads,
+                                        unsigned long *sectors);
+int EXPORT_FUNC(grub_biosdisk_get_num_floppies) (void);
+
+void grub_biosdisk_init (void);
+void grub_biosdisk_fini (void);
+
+#endif /* ! GRUB_BIOSDISK_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/pc/biosnum.h b/grub-core/include/grub/i386/pc/biosnum.h
new file mode 100644 (file)
index 0000000..29c8ecc
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef GRUB_BIOSNUM_MACHINE_HEADER
+#define GRUB_BIOSNUM_MACHINE_HEADER    1
+
+extern int (*grub_get_root_biosnumber) (void);
+
+#endif
diff --git a/grub-core/include/grub/i386/pc/boot.h b/grub-core/include/grub/i386/pc/boot.h
new file mode 100644 (file)
index 0000000..e88c62b
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2002,2005,2006,2007,2008,2010   Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BOOT_MACHINE_HEADER
+#define GRUB_BOOT_MACHINE_HEADER       1
+
+/* The signature for bootloader.  */
+#define GRUB_BOOT_MACHINE_SIGNATURE    0xaa55
+
+/* The offset of the start of BPB (BIOS Parameter Block).  */
+#define GRUB_BOOT_MACHINE_BPB_START    0x3
+
+/* The offset of the end of BPB (BIOS Parameter Block).  */
+#define GRUB_BOOT_MACHINE_BPB_END      0x5a
+
+/* The offset of KERNEL_SECTOR.  */
+#define GRUB_BOOT_MACHINE_KERNEL_SECTOR        0x5c
+
+/* The offset of BOOT_DRIVE.  */
+#define GRUB_BOOT_MACHINE_BOOT_DRIVE   0x64
+
+/* The offset of BOOT_DRIVE_CHECK.  */
+#define GRUB_BOOT_MACHINE_DRIVE_CHECK  0x66
+
+/* The offset of a magic number used by Windows NT.  */
+#define GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC     0x1b8
+
+/* The offset of the start of the partition table.  */
+#define GRUB_BOOT_MACHINE_PART_START   0x1be
+
+/* The offset of the end of the partition table.  */
+#define GRUB_BOOT_MACHINE_PART_END     0x1fe
+
+/* The stack segment.  */
+#define GRUB_BOOT_MACHINE_STACK_SEG    0x2000
+
+/* The segment of disk buffer. The disk buffer MUST be 32K long and
+   cannot straddle a 64K boundary.  */
+#define GRUB_BOOT_MACHINE_BUFFER_SEG   0x7000
+
+/* The flag for BIOS drive number to designate a hard disk vs. a
+   floppy.  */
+#define GRUB_BOOT_MACHINE_BIOS_HD_FLAG 0x80
+
+/* The segment where the kernel is loaded.  */
+#define GRUB_BOOT_MACHINE_KERNEL_SEG   0x800
+
+/* The address where the kernel is loaded.  */
+#define GRUB_BOOT_MACHINE_KERNEL_ADDR  (GRUB_BOOT_MACHINE_KERNEL_SEG << 4)
+
+/* The size of a block list used in the kernel startup code.  */
+#define GRUB_BOOT_MACHINE_LIST_SIZE    12
+
+#define GRUB_BOOT_MACHINE_PXE_DL       0x7f
+
+#ifndef ASM_FILE
+
+/* This is the blocklist used in the diskboot image.  */
+struct grub_boot_blocklist
+{
+  grub_uint64_t start;
+  grub_uint16_t len;
+  grub_uint16_t segment;
+} __attribute__ ((packed));
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! BOOT_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/pc/chainloader.h b/grub-core/include/grub/i386/pc/chainloader.h
new file mode 100644 (file)
index 0000000..ca1da23
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CHAINLOADER_MACHINE_HEADER
+#define GRUB_CHAINLOADER_MACHINE_HEADER        1
+
+#include <grub/dl.h>
+
+/* Common function for normal and rescue mode commands. */
+typedef enum
+  {
+    GRUB_CHAINLOADER_FORCE = 0x1
+  } grub_chainloader_flags_t;
+
+#endif /* GRUB_CHAINLOADER_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/pc/console.h b/grub-core/include/grub/i386/pc/console.h
new file mode 100644 (file)
index 0000000..2a74d15
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CONSOLE_MACHINE_HEADER
+#define GRUB_CONSOLE_MACHINE_HEADER    1
+
+/* Define scan codes.  */
+#define GRUB_CONSOLE_KEY_LEFT          0x4B00
+#define GRUB_CONSOLE_KEY_RIGHT         0x4D00
+#define GRUB_CONSOLE_KEY_UP            0x4800
+#define GRUB_CONSOLE_KEY_DOWN          0x5000
+#define GRUB_CONSOLE_KEY_IC            0x5200
+#define GRUB_CONSOLE_KEY_DC            0x5300
+#define GRUB_CONSOLE_KEY_BACKSPACE     0x0008
+#define GRUB_CONSOLE_KEY_HOME          0x4700
+#define GRUB_CONSOLE_KEY_END           0x4F00
+#define GRUB_CONSOLE_KEY_NPAGE         0x5100
+#define GRUB_CONSOLE_KEY_PPAGE         0x4900
+
+#ifndef ASM_FILE
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/term.h>
+#include <grub/i386/vga_common.h>
+
+/* These are global to share code between C and asm.  */
+int grub_console_checkkey (void);
+int grub_console_getkey (void);
+grub_uint16_t grub_console_getxy (void);
+void grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y);
+void grub_console_cls (void);
+void grub_console_setcursor (int on);
+
+/* Initialize the console system.  */
+void grub_console_init (void);
+
+/* Finish the console system.  */
+void grub_console_fini (void);
+
+#endif
+
+#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/pc/efiemu.h b/grub-core/include/grub/i386/pc/efiemu.h
new file mode 100644 (file)
index 0000000..f269dd0
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_EFI_EMU_HEADER
+#define GRUB_MACHINE_EFI_EMU_HEADER    1
+
+grub_err_t grub_machine_efiemu_init_tables (void);
+
+#endif
diff --git a/grub-core/include/grub/i386/pc/init.h b/grub-core/include/grub/i386/pc/init.h
new file mode 100644 (file)
index 0000000..30130d1
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_INIT_MACHINE_HEADER
+#define GRUB_INIT_MACHINE_HEADER       1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/machine/memory.h>
+
+/* Get the memory size in KB. If EXTENDED is zero, return conventional
+   memory, otherwise return extended memory.  */
+grub_uint16_t grub_get_memsize (int extended);
+
+/* Get a packed EISA memory map. Lower 16 bits are between 1MB and 16MB
+   in 1KB parts, and upper 16 bits are above 16MB in 64KB parts.  */
+grub_uint32_t grub_get_eisa_mmap (void);
+
+/* Get a memory map entry. Return next continuation value. Zero means
+   the end.  */
+grub_uint32_t grub_get_mmap_entry (struct grub_machine_mmap_entry *entry,
+                                  grub_uint32_t cont);
+
+/* Turn on/off Gate A20.  */
+void grub_gate_a20 (int on);
+
+void EXPORT_FUNC(grub_stop_floppy) (void);
+
+#endif /* ! GRUB_INIT_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/pc/kernel.h b/grub-core/include/grub/i386/pc/kernel.h
new file mode 100644 (file)
index 0000000..e830afa
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_MACHINE_HEADER
+#define KERNEL_MACHINE_HEADER  1
+
+/* The offset of GRUB_TOTAL_MODULE_SIZE.  */
+#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE  0x8
+
+/* The offset of GRUB_KERNEL_IMAGE_SIZE.  */
+#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE  0xc
+
+/* The offset of GRUB_COMPRESSED_SIZE.  */
+#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE    0x10
+
+/* The offset of GRUB_INSTALL_DOS_PART.  */
+#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART   0x14
+
+/* The offset of GRUB_INSTALL_BSD_PART.  */
+#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART   0x18
+
+/* The offset of GRUB_PREFIX.  */
+#define GRUB_KERNEL_MACHINE_PREFIX             0x1c
+
+/* End of the data section. */
+#define GRUB_KERNEL_MACHINE_DATA_END           0x5c
+
+/* The size of the first region which won't be compressed.  */
+#define GRUB_KERNEL_MACHINE_RAW_SIZE           (GRUB_KERNEL_MACHINE_DATA_END + 0x5F0)
+
+/* Enable LZMA compression */
+#define ENABLE_LZMA    1
+
+#ifndef ASM_FILE
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+/* The size of kernel image.  */
+extern grub_int32_t grub_kernel_image_size;
+
+/* The total size of module images following the kernel.  */
+extern grub_int32_t grub_total_module_size;
+
+/* The DOS partition number of the installed partition.  */
+extern grub_int32_t grub_install_dos_part;
+
+/* The BSD partition number of the installed partition.  */
+extern grub_int32_t grub_install_bsd_part;
+
+/* The prefix which points to the directory where GRUB modules and its
+   configuration file are located.  */
+extern char grub_prefix[];
+
+/* The boot BIOS drive number.  */
+extern grub_uint8_t EXPORT_VAR(grub_boot_drive);
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! KERNEL_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/pc/loader.h b/grub-core/include/grub/i386/pc/loader.h
new file mode 100644 (file)
index 0000000..3e03141
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER     1
+
+#include <grub/symbol.h>
+#include <grub/cpu/loader.h>
+
+/* This is an asm part of the chainloader.  */
+void EXPORT_FUNC(grub_chainloader_real_boot) (int drive, void *part_addr) __attribute__ ((noreturn));
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/pc/memory.h b/grub-core/include/grub/i386/pc/memory.h
new file mode 100644 (file)
index 0000000..841b061
--- /dev/null
@@ -0,0 +1,140 @@
+/* memory.h - describe the memory map */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MEMORY_MACHINE_HEADER
+#define GRUB_MEMORY_MACHINE_HEADER     1
+
+#include <grub/symbol.h>
+#ifndef ASM_FILE
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/memory.h>
+#endif
+
+#include <grub/i386/memory.h>
+
+/* The scratch buffer used in real mode code.  */
+#define GRUB_MEMORY_MACHINE_SCRATCH_ADDR       0x68000
+#define GRUB_MEMORY_MACHINE_SCRATCH_SEG        (GRUB_MEMORY_MACHINE_SCRATCH_ADDR >> 4)
+#define GRUB_MEMORY_MACHINE_SCRATCH_SIZE       0x10000
+
+/* The real mode stack.  */
+#define GRUB_MEMORY_MACHINE_REAL_STACK (0x2000 - 0x10)
+
+/* The size of the protect mode stack.  */
+#define GRUB_MEMORY_MACHINE_PROT_STACK_SIZE    0x8000
+
+/* The upper memory area (starting at 640 kiB).  */
+#define GRUB_MEMORY_MACHINE_UPPER              0xa0000
+
+/* The protected mode stack.  */
+#define GRUB_MEMORY_MACHINE_PROT_STACK \
+       (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + GRUB_MEMORY_MACHINE_SCRATCH_SIZE \
+        + GRUB_MEMORY_MACHINE_PROT_STACK_SIZE - 0x10)
+
+/* The memory area where GRUB uses its own purpose. This part is not added
+   into free memory for dynamic allocations.  */
+#define GRUB_MEMORY_MACHINE_RESERVED_START     \
+       GRUB_MEMORY_MACHINE_SCRATCH_ADDR
+#define GRUB_MEMORY_MACHINE_RESERVED_END       \
+       (GRUB_MEMORY_MACHINE_PROT_STACK + 0x10)
+
+/* The area where GRUB is decompressed at early startup.  */
+#define GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR 0x100000
+
+/* The address of a partition table passed to another boot loader.  */
+#define GRUB_MEMORY_MACHINE_PART_TABLE_ADDR    0x7be
+
+/* The address where another boot loader is loaded.  */
+#define GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR   0x7c00
+
+/* The code segment of the protected mode.  */
+#define GRUB_MEMORY_MACHINE_PROT_MODE_CSEG     0x8
+
+/* The data segment of the protected mode.  */
+#define GRUB_MEMORY_MACHINE_PROT_MODE_DSEG     0x10
+
+/* The code segment of the pseudo real mode.  */
+#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG   0x18
+
+/* The data segment of the pseudo real mode.  */
+#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG   0x20
+
+#define GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR        0x400
+
+#ifndef ASM_FILE
+
+/* See http://heim.ifi.uio.no/~stanisls/helppc/bios_data_area.html for a
+   description of the BIOS Data Area layout.  */
+struct grub_machine_bios_data_area
+{
+  grub_uint8_t unused1[0x17];
+  grub_uint8_t keyboard_flag_lower; /* 0x17 */
+  grub_uint8_t unused2[0xf0 - 0x18];
+};
+
+struct grub_machine_mmap_entry
+{
+  grub_uint32_t size;
+  grub_uint64_t addr;
+  grub_uint64_t len;
+#define GRUB_MACHINE_MEMORY_AVAILABLE  1
+#define GRUB_MACHINE_MEMORY_RESERVED   2
+#define GRUB_MACHINE_MEMORY_ACPI       3
+#define GRUB_MACHINE_MEMORY_NVS        4
+#define GRUB_MACHINE_MEMORY_MAX_TYPE   4
+  /* This one is special: it's used internally but is never reported
+     by firmware. */
+#define GRUB_MACHINE_MEMORY_HOLE       5
+
+  grub_uint32_t type;
+} __attribute__((packed));
+
+grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
+     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
+
+grub_uint64_t grub_mmap_get_post64 (void);
+grub_uint64_t grub_mmap_get_upper (void);
+grub_uint64_t grub_mmap_get_lower (void);
+
+#define GRUB_MMAP_MALLOC_LOW 1
+
+#ifdef GRUB_MACHINE_PCBIOS
+grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t size,
+                                      int type, int handle);
+grub_err_t grub_machine_mmap_unregister (int handle);
+#else
+static inline grub_err_t
+grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
+                           grub_uint64_t size __attribute__ ((unused)),
+                           int type __attribute__ ((unused)),
+                           int handle __attribute__ ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
+static inline grub_err_t
+grub_machine_mmap_unregister (int handle  __attribute__ ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
+#endif
+
+#endif
+
+#endif /* ! GRUB_MEMORY_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/pc/pxe.h b/grub-core/include/grub/i386/pc/pxe.h
new file mode 100644 (file)
index 0000000..39f356c
--- /dev/null
@@ -0,0 +1,314 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CPU_PXE_H
+#define GRUB_CPU_PXE_H
+
+#include <grub/types.h>
+
+#define GRUB_PXENV_TFTP_OPEN                   0x0020
+#define GRUB_PXENV_TFTP_CLOSE                  0x0021
+#define GRUB_PXENV_TFTP_READ                   0x0022
+#define GRUB_PXENV_TFTP_READ_FILE              0x0023
+#define GRUB_PXENV_TFTP_READ_FILE_PMODE                0x0024
+#define GRUB_PXENV_TFTP_GET_FSIZE              0x0025
+
+#define GRUB_PXENV_UDP_OPEN                    0x0030
+#define GRUB_PXENV_UDP_CLOSE                   0x0031
+#define GRUB_PXENV_UDP_READ                    0x0032
+#define GRUB_PXENV_UDP_WRITE                   0x0033
+
+#define GRUB_PXENV_START_UNDI                  0x0000
+#define GRUB_PXENV_UNDI_STARTUP                        0x0001
+#define GRUB_PXENV_UNDI_CLEANUP                        0x0002
+#define GRUB_PXENV_UNDI_INITIALIZE             0x0003
+#define GRUB_PXENV_UNDI_RESET_NIC              0x0004
+#define GRUB_PXENV_UNDI_SHUTDOWN               0x0005
+#define GRUB_PXENV_UNDI_OPEN                   0x0006
+#define GRUB_PXENV_UNDI_CLOSE                  0x0007
+#define GRUB_PXENV_UNDI_TRANSMIT               0x0008
+#define GRUB_PXENV_UNDI_SET_MCAST_ADDR         0x0009
+#define GRUB_PXENV_UNDI_SET_STATION_ADDR       0x000A
+#define GRUB_PXENV_UNDI_SET_PACKET_FILTER      0x000B
+#define GRUB_PXENV_UNDI_GET_INFORMATION                0x000C
+#define GRUB_PXENV_UNDI_GET_STATISTICS         0x000D
+#define GRUB_PXENV_UNDI_CLEAR_STATISTICS       0x000E
+#define GRUB_PXENV_UNDI_INITIATE_DIAGS         0x000F
+#define GRUB_PXENV_UNDI_FORCE_INTERRUPT                0x0010
+#define GRUB_PXENV_UNDI_GET_MCAST_ADDR         0x0011
+#define GRUB_PXENV_UNDI_GET_NIC_TYPE           0x0012
+#define GRUB_PXENV_UNDI_GET_IFACE_INFO         0x0013
+#define GRUB_PXENV_UNDI_ISR                    0x0014
+#define        GRUB_PXENV_STOP_UNDI                    0x0015
+#define GRUB_PXENV_UNDI_GET_STATE              0x0015
+
+#define GRUB_PXENV_UNLOAD_STACK                        0x0070
+#define GRUB_PXENV_GET_CACHED_INFO             0x0071
+#define GRUB_PXENV_RESTART_DHCP                        0x0072
+#define GRUB_PXENV_RESTART_TFTP                        0x0073
+#define GRUB_PXENV_MODE_SWITCH                 0x0074
+#define GRUB_PXENV_START_BASE                  0x0075
+#define GRUB_PXENV_STOP_BASE                   0x0076
+
+#define GRUB_PXENV_EXIT_SUCCESS                        0x0000
+#define GRUB_PXENV_EXIT_FAILURE                        0x0001
+
+#define GRUB_PXENV_STATUS_SUCCESS                              0x00
+#define GRUB_PXENV_STATUS_FAILURE                              0x01
+#define GRUB_PXENV_STATUS_BAD_FUNC                             0x02
+#define GRUB_PXENV_STATUS_UNSUPPORTED                          0x03
+#define GRUB_PXENV_STATUS_KEEP_UNDI                            0x04
+#define GRUB_PXENV_STATUS_KEEP_ALL                             0x05
+#define GRUB_PXENV_STATUS_OUT_OF_RESOURCES                     0x06
+#define GRUB_PXENV_STATUS_ARP_TIMEOUT                          0x11
+#define GRUB_PXENV_STATUS_UDP_CLOSED                           0x18
+#define GRUB_PXENV_STATUS_UDP_OPEN                             0x19
+#define GRUB_PXENV_STATUS_TFTP_CLOSED                          0x1A
+#define GRUB_PXENV_STATUS_TFTP_OPEN                            0x1B
+#define GRUB_PXENV_STATUS_MCOPY_PROBLEM                                0x20
+#define GRUB_PXENV_STATUS_BIS_INTEGRITY_FAILURE                        0x21
+#define GRUB_PXENV_STATUS_BIS_VALIDATE_FAILURE                 0x22
+#define GRUB_PXENV_STATUS_BIS_INIT_FAILURE                     0x23
+#define GRUB_PXENV_STATUS_BIS_SHUTDOWN_FAILURE                 0x24
+#define GRUB_PXENV_STATUS_BIS_GBOA_FAILURE                     0x25
+#define GRUB_PXENV_STATUS_BIS_FREE_FAILURE                     0x26
+#define GRUB_PXENV_STATUS_BIS_GSI_FAILURE                      0x27
+#define GRUB_PXENV_STATUS_BIS_BAD_CKSUM                                0x28
+#define GRUB_PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS              0x30
+#define GRUB_PXENV_STATUS_TFTP_OPEN_TIMEOUT                    0x32
+
+#define GRUB_PXENV_STATUS_TFTP_UNKNOWN_OPCODE                  0x33
+#define GRUB_PXENV_STATUS_TFTP_READ_TIMEOUT                    0x35
+#define GRUB_PXENV_STATUS_TFTP_ERROR_OPCODE                    0x36
+#define GRUB_PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION          0x38
+#define GRUB_PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION     0x39
+#define GRUB_PXENV_STATUS_TFTP_TOO_MANY_PACKAGES               0x3A
+#define GRUB_PXENV_STATUS_TFTP_FILE_NOT_FOUND                  0x3B
+#define GRUB_PXENV_STATUS_TFTP_ACCESS_VIOLATION                        0x3C
+#define GRUB_PXENV_STATUS_TFTP_NO_MCAST_ADDRESS                        0x3D
+#define GRUB_PXENV_STATUS_TFTP_NO_FILESIZE                     0x3E
+#define GRUB_PXENV_STATUS_TFTP_INVALID_PACKET_SIZE             0x3F
+#define GRUB_PXENV_STATUS_DHCP_TIMEOUT                         0x51
+#define GRUB_PXENV_STATUS_DHCP_NO_IP_ADDRESS                   0x52
+#define GRUB_PXENV_STATUS_DHCP_NO_BOOTFILE_NAME                        0x53
+#define GRUB_PXENV_STATUS_DHCP_BAD_IP_ADDRESS                  0x54
+#define GRUB_PXENV_STATUS_UNDI_INVALID_FUNCTION                        0x60
+#define GRUB_PXENV_STATUS_UNDI_MEDIATEST_FAILED                        0x61
+#define GRUB_PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST       0x62
+#define GRUB_PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC           0x63
+#define GRUB_PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY           0x64
+#define GRUB_PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA         0x65
+#define GRUB_PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA           0x66
+#define GRUB_PXENV_STATUS_UNDI_BAD_MAC_ADDRESS                 0x67
+#define GRUB_PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM             0x68
+#define GRUB_PXENV_STATUS_UNDI_ERROR_SETTING_ISR               0x69
+#define GRUB_PXENV_STATUS_UNDI_INVALID_STATE                   0x6A
+#define GRUB_PXENV_STATUS_UNDI_TRANSMIT_ERROR                  0x6B
+#define GRUB_PXENV_STATUS_UNDI_INVALID_PARAMETER               0x6C
+#define GRUB_PXENV_STATUS_BSTRAP_PROMPT_MENU                   0x74
+#define GRUB_PXENV_STATUS_BSTRAP_MCAST_ADDR                    0x76
+#define GRUB_PXENV_STATUS_BSTRAP_MISSING_LIST                  0x77
+#define GRUB_PXENV_STATUS_BSTRAP_NO_RESPONSE                   0x78
+#define GRUB_PXENV_STATUS_BSTRAP_FILE_TOO_BIG                  0x79
+#define GRUB_PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE           0xA0
+#define GRUB_PXENV_STATUS_BINL_NO_PXE_SERVER                   0xA1
+#define GRUB_PXENV_STATUS_NOT_AVAILABLE_IN_PMODE               0xA2
+#define GRUB_PXENV_STATUS_NOT_AVAILABLE_IN_RMODE               0xA3
+#define GRUB_PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED            0xB0
+#define GRUB_PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY           0xC0
+#define GRUB_PXENV_STATUS_LOADER_NO_BC_ROMID                   0xC1
+#define GRUB_PXENV_STATUS_LOADER_BAD_BC_ROMID                  0xC2
+#define GRUB_PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE          0xC3
+#define GRUB_PXENV_STATUS_LOADER_NO_UNDI_ROMID                 0xC4
+#define GRUB_PXENV_STATUS_LOADER_BAD_UNDI_ROMID                        0xC5
+#define GRUB_PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE         0xC6
+#define GRUB_PXENV_STATUS_LOADER_NO_PXE_STRUCT                 0xC8
+#define GRUB_PXENV_STATUS_LOADER_NO_PXENV_STRUCT               0xC9
+#define GRUB_PXENV_STATUS_LOADER_UNDI_START                    0xCA
+#define GRUB_PXENV_STATUS_LOADER_BC_START                      0xCB
+
+#define GRUB_PXENV_PACKET_TYPE_DHCP_DISCOVER   1
+#define GRUB_PXENV_PACKET_TYPE_DHCP_ACK                2
+#define GRUB_PXENV_PACKET_TYPE_CACHED_REPLY    3
+
+#define GRUB_PXE_BOOTP_REQ     1
+#define GRUB_PXE_BOOTP_REP     2
+
+#define GRUB_PXE_BOOTP_BCAST   0x8000
+
+#if 1
+#define GRUB_PXE_BOOTP_DHCPVEND        1024    /* DHCP extended vendor field size.  */
+#else
+#define GRUB_PXE_BOOTP_DHCPVEND        312     /* DHCP standard vendor field size.  */
+#endif
+
+#define GRUB_PXE_MIN_BLKSIZE   512
+#define GRUB_PXE_MAX_BLKSIZE   1432
+
+#define GRUB_PXE_TFTP_PORT     69
+
+#define        GRUB_PXE_VM_RFC1048     0x63825363L
+
+#define GRUB_PXE_ERR_LEN       0xFFFFFFFF
+
+#ifndef ASM_FILE
+
+struct grub_pxenv
+{
+  grub_uint8_t signature[6];   /* 'PXENV+'.  */
+  grub_uint16_t version;       /* MSB = major, LSB = minor.  */
+  grub_uint8_t length;         /* structure length.  */
+  grub_uint8_t checksum;       /* checksum pad.  */
+  grub_uint32_t rm_entry;      /* SEG:OFF to PXE entry point.  */
+  grub_uint32_t        pm_offset;      /* Protected mode entry.  */
+  grub_uint16_t pm_selector;   /* Protected mode selector.  */
+  grub_uint16_t stack_seg;     /* Stack segment address.  */
+  grub_uint16_t        stack_size;     /* Stack segment size (bytes).  */
+  grub_uint16_t bc_code_seg;   /* BC Code segment address.  */
+  grub_uint16_t        bc_code_size;   /* BC Code segment size (bytes).  */
+  grub_uint16_t        bc_data_seg;    /* BC Data segment address.  */
+  grub_uint16_t        bc_data_size;   /* BC Data segment size (bytes).  */
+  grub_uint16_t        undi_data_seg;  /* UNDI Data segment address.  */
+  grub_uint16_t        undi_data_size; /* UNDI Data segment size (bytes).  */
+  grub_uint16_t        undi_code_seg;  /* UNDI Code segment address.  */
+  grub_uint16_t        undi_code_size; /* UNDI Code segment size (bytes).  */
+  grub_uint32_t pxe_ptr;       /* SEG:OFF to !PXE struct.  */
+} __attribute__ ((packed));
+
+struct grub_pxenv_get_cached_info
+{
+  grub_uint16_t status;
+  grub_uint16_t packet_type;
+  grub_uint16_t buffer_size;
+  grub_uint32_t buffer;
+  grub_uint16_t buffer_limit;
+} __attribute__ ((packed));
+
+#define GRUB_PXE_MAC_ADDR_LEN  16
+
+typedef grub_uint8_t grub_pxe_mac_addr_t[GRUB_PXE_MAC_ADDR_LEN];
+
+struct grub_pxenv_boot_player
+{
+  grub_uint8_t opcode;
+  grub_uint8_t hw_type;                /* hardware type.  */
+  grub_uint8_t hw_len;         /* hardware addr len.  */
+  grub_uint8_t gate_hops;      /* zero it.  */
+  grub_uint32_t ident;         /* random number chosen by client.  */
+  grub_uint16_t seconds;       /* seconds since did initial bootstrap.  */
+  grub_uint16_t flags;
+  grub_uint32_t        client_ip;
+  grub_uint32_t your_ip;
+  grub_uint32_t        server_ip;
+  grub_uint32_t        gateway_ip;
+  grub_pxe_mac_addr_t mac_addr;
+  grub_uint8_t server_name[64];
+  grub_uint8_t boot_file[128];
+  union
+  {
+    grub_uint8_t d[GRUB_PXE_BOOTP_DHCPVEND];   /* raw array of vendor/dhcp options.  */
+    struct
+    {
+      grub_uint32_t magic;     /* DHCP magic cookie.  */
+      grub_uint32_t flags;     /* bootp flags/opcodes.  */
+      grub_uint8_t padding[56];
+    } v;
+  } vendor;
+} __attribute__ ((packed));
+
+struct grub_pxenv_tftp_open
+{
+  grub_uint16_t status;
+  grub_uint32_t server_ip;
+  grub_uint32_t gateway_ip;
+  grub_uint8_t filename[128];
+  grub_uint16_t tftp_port;
+  grub_uint16_t packet_size;
+} __attribute__ ((packed));
+
+struct grub_pxenv_tftp_close
+{
+  grub_uint16_t status;
+} __attribute__ ((packed));
+
+struct grub_pxenv_tftp_read
+{
+  grub_uint16_t status;
+  grub_uint16_t packet_number;
+  grub_uint16_t buffer_size;
+  grub_uint32_t buffer;
+} __attribute__ ((packed));
+
+struct grub_pxenv_tftp_get_fsize
+{
+  grub_uint16_t status;
+  grub_uint32_t server_ip;
+  grub_uint32_t gateway_ip;
+  grub_uint8_t filename[128];
+  grub_uint32_t file_size;
+} __attribute__ ((packed));
+
+struct grub_pxenv_udp_open
+{
+  grub_uint16_t status;
+  grub_uint32_t src_ip;
+} __attribute__ ((packed));
+
+struct grub_pxenv_udp_close
+{
+  grub_uint16_t status;
+} __attribute__ ((packed));
+
+struct grub_pxenv_udp_write
+{
+  grub_uint16_t status;
+  grub_uint32_t ip;
+  grub_uint32_t gateway;
+  grub_uint16_t src_port;
+  grub_uint16_t dst_port;
+  grub_uint16_t buffer_size;
+  grub_uint32_t buffer;
+} __attribute__ ((packed));
+
+struct grub_pxenv_udp_read
+{
+  grub_uint16_t status;
+  grub_uint32_t src_ip;
+  grub_uint32_t dst_ip;
+  grub_uint16_t src_port;
+  grub_uint16_t dst_port;
+  grub_uint16_t buffer_size;
+  grub_uint32_t buffer;
+} __attribute__ ((packed));
+
+struct grub_pxenv_unload_stack
+{
+  grub_uint16_t status;
+  grub_uint8_t reserved[10];
+} __attribute__ ((packed));
+
+struct grub_pxenv * EXPORT_FUNC(grub_pxe_scan) (void);
+int EXPORT_FUNC(grub_pxe_call) (int func, void * data);
+
+extern struct grub_pxenv *grub_pxe_pxenv;
+
+void grub_pxe_unload (void);
+
+#endif
+
+#endif /* GRUB_CPU_PXE_H */
diff --git a/grub-core/include/grub/i386/pc/time.h b/grub-core/include/grub/i386/pc/time.h
new file mode 100644 (file)
index 0000000..98399b6
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_MACHINE_TIME_HEADER
+#define KERNEL_MACHINE_TIME_HEADER     1
+
+#include <grub/symbol.h>
+
+#define GRUB_TICKS_PER_SECOND  18
+
+/* Return the real time in ticks.  */
+grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
+
+#endif /* ! KERNEL_MACHINE_TIME_HEADER */
diff --git a/grub-core/include/grub/i386/pc/vbe.h b/grub-core/include/grub/i386/pc/vbe.h
new file mode 100644 (file)
index 0000000..abf246f
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_VBE_MACHINE_HEADER
+#define GRUB_VBE_MACHINE_HEADER        1
+
+/* Default video mode to be used.  */
+#define GRUB_VBE_DEFAULT_VIDEO_MODE     0x101
+
+/* VBE status codes.  */
+#define GRUB_VBE_STATUS_OK             0x004f
+
+#define GRUB_VBE_CAPABILITY_DACWIDTH   (1 << 0)
+
+/* Bits from the GRUB_VBE "mode_attributes" field in the mode info struct.  */
+#define GRUB_VBE_MODEATTR_SUPPORTED                 (1 << 0)
+#define GRUB_VBE_MODEATTR_RESERVED_1                (1 << 1)
+#define GRUB_VBE_MODEATTR_BIOS_TTY_OUTPUT_SUPPORT   (1 << 2)
+#define GRUB_VBE_MODEATTR_COLOR                     (1 << 3)
+#define GRUB_VBE_MODEATTR_GRAPHICS                  (1 << 4)
+#define GRUB_VBE_MODEATTR_VGA_COMPATIBLE            (1 << 5)
+#define GRUB_VBE_MODEATTR_VGA_WINDOWED_AVAIL        (1 << 6)
+#define GRUB_VBE_MODEATTR_LFB_AVAIL                 (1 << 7)
+#define GRUB_VBE_MODEATTR_DOUBLE_SCAN_AVAIL         (1 << 8)
+#define GRUB_VBE_MODEATTR_INTERLACED_AVAIL          (1 << 9)
+#define GRUB_VBE_MODEATTR_TRIPLE_BUF_AVAIL          (1 << 10)
+#define GRUB_VBE_MODEATTR_STEREO_AVAIL              (1 << 11)
+#define GRUB_VBE_MODEATTR_DUAL_DISPLAY_START        (1 << 12)
+
+/* Values for the GRUB_VBE memory_model field in the mode info struct.  */
+#define GRUB_VBE_MEMORY_MODEL_TEXT           0x00
+#define GRUB_VBE_MEMORY_MODEL_CGA            0x01
+#define GRUB_VBE_MEMORY_MODEL_HERCULES       0x02
+#define GRUB_VBE_MEMORY_MODEL_PLANAR         0x03
+#define GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL   0x04
+#define GRUB_VBE_MEMORY_MODEL_NONCHAIN4_256  0x05
+#define GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR   0x06
+#define GRUB_VBE_MEMORY_MODEL_YUV            0x07
+
+/* Note:
+
+   Please refer to VESA BIOS Extension 3.0 Specification for more descriptive
+   meanings of following structures and how they should be used.
+
+   I have tried to maintain field name compatibility against specification
+   while following naming conventions used in GRUB.  */
+
+typedef grub_uint32_t grub_vbe_farptr_t;
+typedef grub_uint32_t grub_vbe_physptr_t;
+typedef grub_uint32_t grub_vbe_status_t;
+
+struct grub_vbe_info_block
+{
+  grub_uint8_t signature[4];
+  grub_uint16_t version;
+
+  grub_vbe_farptr_t oem_string_ptr;
+  grub_uint32_t capabilities;
+  grub_vbe_farptr_t video_mode_ptr;
+  grub_uint16_t total_memory;
+
+  grub_uint16_t oem_software_rev;
+  grub_vbe_farptr_t oem_vendor_name_ptr;
+  grub_vbe_farptr_t oem_product_name_ptr;
+  grub_vbe_farptr_t oem_product_rev_ptr;
+
+  grub_uint8_t reserved[222];
+
+  grub_uint8_t oem_data[256];
+} __attribute__ ((packed));
+
+struct grub_vbe_mode_info_block
+{
+  /* Mandatory information for all VBE revisions.  */
+  grub_uint16_t mode_attributes;
+  grub_uint8_t win_a_attributes;
+  grub_uint8_t win_b_attributes;
+  grub_uint16_t win_granularity;
+  grub_uint16_t win_size;
+  grub_uint16_t win_a_segment;
+  grub_uint16_t win_b_segment;
+  grub_vbe_farptr_t win_func_ptr;
+  grub_uint16_t bytes_per_scan_line;
+
+  /* Mandatory information for VBE 1.2 and above.  */
+  grub_uint16_t x_resolution;
+  grub_uint16_t y_resolution;
+  grub_uint8_t x_char_size;
+  grub_uint8_t y_char_size;
+  grub_uint8_t number_of_planes;
+  grub_uint8_t bits_per_pixel;
+  grub_uint8_t number_of_banks;
+  grub_uint8_t memory_model;
+  grub_uint8_t bank_size;
+  grub_uint8_t number_of_image_pages;
+  grub_uint8_t reserved;
+
+  /* Direct Color fields (required for direct/6 and YUV/7 memory models).  */
+  grub_uint8_t red_mask_size;
+  grub_uint8_t red_field_position;
+  grub_uint8_t green_mask_size;
+  grub_uint8_t green_field_position;
+  grub_uint8_t blue_mask_size;
+  grub_uint8_t blue_field_position;
+  grub_uint8_t rsvd_mask_size;
+  grub_uint8_t rsvd_field_position;
+  grub_uint8_t direct_color_mode_info;
+
+  /* Mandatory information for VBE 2.0 and above.  */
+  grub_vbe_physptr_t phys_base_addr;
+  grub_uint32_t reserved2;
+  grub_uint16_t reserved3;
+
+  /* Mandatory information for VBE 3.0 and above.  */
+  grub_uint16_t lin_bytes_per_scan_line;
+  grub_uint8_t bnk_number_of_image_pages;
+  grub_uint8_t lin_number_of_image_pages;
+  grub_uint8_t lin_red_mask_size;
+  grub_uint8_t lin_red_field_position;
+  grub_uint8_t lin_green_mask_size;
+  grub_uint8_t lin_green_field_position;
+  grub_uint8_t lin_blue_mask_size;
+  grub_uint8_t lin_blue_field_position;
+  grub_uint8_t lin_rsvd_mask_size;
+  grub_uint8_t lin_rsvd_field_position;
+  grub_uint32_t max_pixel_clock;
+
+  /* Reserved field to make structure to be 256 bytes long, VESA BIOS
+     Extension 3.0 Specification says to reserve 189 bytes here but
+     that doesn't make structure to be 256 bytes.  So additional one is
+     added here.  */
+  grub_uint8_t reserved4[189 + 1];
+} __attribute__ ((packed));
+
+struct grub_vbe_crtc_info_block
+{
+  grub_uint16_t horizontal_total;
+  grub_uint16_t horizontal_sync_start;
+  grub_uint16_t horizontal_sync_end;
+  grub_uint16_t vertical_total;
+  grub_uint16_t vertical_sync_start;
+  grub_uint16_t vertical_sync_end;
+  grub_uint8_t flags;
+  grub_uint32_t pixel_clock;
+  grub_uint16_t refresh_rate;
+  grub_uint8_t reserved[40];
+} __attribute__ ((packed));
+
+struct grub_vbe_palette_data
+{
+  grub_uint8_t blue;
+  grub_uint8_t green;
+  grub_uint8_t red;
+  grub_uint8_t alignment;
+} __attribute__ ((packed));
+
+/* Prototypes for kernel real mode thunks.  */
+
+/* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_controller_info) (struct grub_vbe_info_block *controller_info);
+
+/* Call VESA BIOS 0x4f01 to get VBE Mode Information, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_mode_info) (grub_uint32_t mode,
+                                                            struct grub_vbe_mode_info_block *mode_info);
+
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_getset_dac_palette_width) (int set, int *width);
+
+#define grub_vbe_bios_get_dac_palette_width(width)     grub_vbe_bios_getset_dac_palette_width(0, (width))
+#define grub_vbe_bios_set_dac_palette_width(width)     grub_vbe_bios_getset_dac_palette_width(1, (width))
+
+/* Call VESA BIOS 0x4f02 to set video mode, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_mode) (grub_uint32_t mode,
+                                                       struct grub_vbe_crtc_info_block *crtc_info);
+
+/* Call VESA BIOS 0x4f03 to return current VBE Mode, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_mode) (grub_uint32_t *mode);
+
+/* Call VESA BIOS 0x4f05 to set memory window, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_memory_window) (grub_uint32_t window,
+                                                                grub_uint32_t position);
+
+/* Call VESA BIOS 0x4f05 to return memory window, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_memory_window) (grub_uint32_t window,
+                                                                grub_uint32_t *position);
+
+/* Call VESA BIOS 0x4f06 to set scanline length (in bytes), return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_scanline_length) (grub_uint32_t length);
+
+/* Call VESA BIOS 0x4f06 to return scanline length (in bytes), return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_scanline_length) (grub_uint32_t *length);
+
+/* Call VESA BIOS 0x4f07 to set display start, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_display_start) (grub_uint32_t x,
+                                                                grub_uint32_t y);
+
+/* Call VESA BIOS 0x4f07 to get display start, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_display_start) (grub_uint32_t *x,
+                                                                grub_uint32_t *y);
+
+/* Call VESA BIOS 0x4f09 to set palette data, return status.  */
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_palette_data) (grub_uint32_t color_count,
+                                                               grub_uint32_t start_index,
+                                                               struct grub_vbe_palette_data *palette_data);
+
+/* Prototypes for helper functions.  */
+
+grub_err_t grub_vbe_probe (struct grub_vbe_info_block *info_block);
+grub_err_t grub_vbe_set_video_mode (grub_uint32_t mode,
+                                    struct grub_vbe_mode_info_block *mode_info);
+grub_err_t grub_vbe_get_video_mode (grub_uint32_t *mode);
+grub_err_t grub_vbe_get_video_mode_info (grub_uint32_t mode,
+                                         struct grub_vbe_mode_info_block *mode_info);
+
+
+#endif /* ! GRUB_VBE_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/pc/vga.h b/grub-core/include/grub/i386/pc/vga.h
new file mode 100644 (file)
index 0000000..2724f64
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_VGA_MACHINE_HEADER
+#define GRUB_VGA_MACHINE_HEADER        1
+
+#include <grub/symbol.h>
+#include <grub/machine/memory.h>
+
+/* The VGA (at the beginning of upper memory).  */
+#define GRUB_MEMORY_MACHINE_VGA_ADDR           GRUB_MEMORY_MACHINE_UPPER
+
+/* Set the video mode to MODE and return the previous mode.  */
+unsigned char EXPORT_FUNC(grub_vga_set_mode) (unsigned char mode);
+
+#endif /* ! GRUB_VGA_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/pci.h b/grub-core/include/grub/i386/pci.h
new file mode 100644 (file)
index 0000000..bab42ad
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef        GRUB_CPU_PCI_H
+#define        GRUB_CPU_PCI_H  1
+
+#include <grub/types.h>
+#include <grub/i386/io.h>
+
+#define GRUB_MACHINE_PCI_IO_BASE          0
+#define GRUB_PCI_ADDR_REG      0xcf8
+#define GRUB_PCI_DATA_REG      0xcfc
+#define GRUB_PCI_NUM_BUS        256
+#define GRUB_PCI_NUM_DEVICES    32
+
+static inline grub_uint32_t
+grub_pci_read (grub_pci_address_t addr)
+{
+  grub_outl (addr, GRUB_PCI_ADDR_REG);
+  return grub_inl (GRUB_PCI_DATA_REG);
+}
+
+static inline grub_uint16_t
+grub_pci_read_word (grub_pci_address_t addr)
+{
+  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
+  return grub_inw (GRUB_PCI_DATA_REG + (addr & 3));
+}
+
+static inline grub_uint8_t
+grub_pci_read_byte (grub_pci_address_t addr)
+{
+  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
+  return grub_inb (GRUB_PCI_DATA_REG + (addr & 3));
+}
+
+static inline void
+grub_pci_write (grub_pci_address_t addr, grub_uint32_t data)
+{
+  grub_outl (addr, GRUB_PCI_ADDR_REG);
+  grub_outl (data, GRUB_PCI_DATA_REG);
+}
+
+static inline void
+grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data)
+{
+  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
+  grub_outw (data, GRUB_PCI_DATA_REG + (addr & 3));
+}
+
+static inline void
+grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data)
+{
+  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
+  grub_outb (data, GRUB_PCI_DATA_REG + (addr & 3));
+}
+
+static inline volatile void *
+grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)),
+                          grub_addr_t base,
+                          grub_size_t size __attribute__ ((unused)))
+{
+  return (volatile void *) base;
+}
+
+static inline void
+grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)),
+                            void *mem __attribute__ ((unused)),
+                            grub_size_t size __attribute__ ((unused)))
+{
+}
+
+
+#endif /* GRUB_CPU_PCI_H */
diff --git a/grub-core/include/grub/i386/pit.h b/grub-core/include/grub/i386/pit.h
new file mode 100644 (file)
index 0000000..ff9b9a6
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_PIT_HEADER
+#define KERNEL_CPU_PIT_HEADER   1
+
+#include <grub/types.h>
+#include <grub/err.h>
+
+void EXPORT_FUNC(grub_pit_wait) (grub_uint16_t tics);
+
+#endif /* ! KERNEL_CPU_PIT_HEADER */
diff --git a/grub-core/include/grub/i386/qemu/boot.h b/grub-core/include/grub/i386/qemu/boot.h
new file mode 100644 (file)
index 0000000..6fbb577
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BOOT_MACHINE_HEADER
+#define GRUB_BOOT_MACHINE_HEADER       1
+
+/* The size of boot.img.  */
+#define GRUB_BOOT_MACHINE_SIZE                 (0x100000 - GRUB_BOOT_MACHINE_LINK_ADDR)
+
+/* The offset of GRUB_CORE_ENTRY_ADDR.  */
+#define GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR      0x4
+
+#endif
diff --git a/grub-core/include/grub/i386/qemu/console.h b/grub-core/include/grub/i386/qemu/console.h
new file mode 100644 (file)
index 0000000..774399a
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/console.h>
diff --git a/grub-core/include/grub/i386/qemu/init.h b/grub-core/include/grub/i386/qemu/init.h
new file mode 100644 (file)
index 0000000..fd935c3
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/init.h>
diff --git a/grub-core/include/grub/i386/qemu/kernel.h b/grub-core/include/grub/i386/qemu/kernel.h
new file mode 100644 (file)
index 0000000..bc0b93d
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_MACHINE_HEADER
+#define GRUB_KERNEL_MACHINE_HEADER     1
+
+/* The offset of GRUB_CORE_ENTRY_ADDR.  */
+#define GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR    0x8
+
+/* The offset of GRUB_KERNEL_IMAGE_SIZE.  */
+#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE  0xc
+
+/* The offset of GRUB_PREFIX.  */
+#define GRUB_KERNEL_MACHINE_PREFIX             0x10
+
+/* End of the data section. */
+#define GRUB_KERNEL_MACHINE_DATA_END           0x50
+
+#ifndef ASM_FILE
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+extern grub_addr_t grub_core_entry_addr;
+
+/* The size of kernel image.  */
+extern grub_int32_t grub_kernel_image_size;
+
+/* The total size of module images following the kernel.  */
+extern grub_int32_t grub_total_module_size;
+
+/* The prefix which points to the directory where GRUB modules and its
+   configuration file are located.  */
+extern char grub_prefix[];
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/qemu/loader.h b/grub-core/include/grub/i386/qemu/loader.h
new file mode 100644 (file)
index 0000000..d3f36bb
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/cpu/loader.h>
diff --git a/grub-core/include/grub/i386/qemu/memory.h b/grub-core/include/grub/i386/qemu/memory.h
new file mode 100644 (file)
index 0000000..de55944
--- /dev/null
@@ -0,0 +1,45 @@
+/* memory.h - describe the memory map */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GRUB_MEMORY_MACHINE_HEADER
+#define _GRUB_MEMORY_MACHINE_HEADER      1
+
+#include <grub/symbol.h>
+#include <grub/i386/pc/memory.h>
+
+#ifndef ASM_FILE
+#include <grub/err.h>
+#include <grub/types.h>
+#endif
+
+#define GRUB_MEMORY_MACHINE_LOWER_USABLE               0x9fc00         /* 640 kiB - 1 kiB */
+
+#define GRUB_MEMORY_MACHINE_UPPER_START                        0x100000        /* 1 MiB */
+#define GRUB_MEMORY_MACHINE_LOWER_SIZE                 GRUB_MEMORY_MACHINE_UPPER_START
+
+#ifndef ASM_FILE
+
+void grub_machine_mmap_init (void);
+
+grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
+     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
+
+#endif
+
+#endif /* ! _GRUB_MEMORY_MACHINE_HEADER */
diff --git a/grub-core/include/grub/i386/qemu/serial.h b/grub-core/include/grub/i386/qemu/serial.h
new file mode 100644 (file)
index 0000000..2d85634
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/serial.h>
diff --git a/grub-core/include/grub/i386/qemu/time.h b/grub-core/include/grub/i386/qemu/time.h
new file mode 100644 (file)
index 0000000..7177c74
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/time.h>
diff --git a/grub-core/include/grub/i386/relocator.h b/grub-core/include/grub/i386/relocator.h
new file mode 100644 (file)
index 0000000..ef7fe23
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_RELOCATOR_CPU_HEADER
+#define GRUB_RELOCATOR_CPU_HEADER      1
+
+#include <grub/types.h>
+#include <grub/err.h>
+
+struct grub_relocator32_state
+{
+  grub_uint32_t esp;
+  grub_uint32_t eax;
+  grub_uint32_t ebx;
+  grub_uint32_t ecx;
+  grub_uint32_t edx;
+  grub_uint32_t eip;
+};
+
+void *grub_relocator32_alloc (grub_size_t size);
+grub_err_t grub_relocator32_boot (void *relocator, grub_uint32_t dest,
+                                 struct grub_relocator32_state state);
+void *grub_relocator32_realloc (void *relocator, grub_size_t size);
+void grub_relocator32_free (void *relocator);
+
+#endif /* ! GRUB_RELOCATOR_CPU_HEADER */
diff --git a/grub-core/include/grub/i386/setjmp.h b/grub-core/include/grub/i386/setjmp.h
new file mode 100644 (file)
index 0000000..6b6b6fd
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SETJMP_CPU_HEADER
+#define GRUB_SETJMP_CPU_HEADER 1
+
+typedef unsigned long grub_jmp_buf[6];
+
+#ifdef __MINGW32__
+int grub_setjmp (grub_jmp_buf env) __attribute__ ((cdecl, regparm (3)));
+#else
+int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice, cdecl,
+                                                  regparm (3)));
+#endif
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn, cdecl,
+                                                             regparm (3)));
+
+#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/grub-core/include/grub/i386/time.h b/grub-core/include/grub/i386/time.h
new file mode 100644 (file)
index 0000000..842882c
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_TIME_HEADER
+#define KERNEL_CPU_TIME_HEADER 1
+
+static __inline void
+grub_cpu_idle (void)
+{
+  /* FIXME: this can't work until we handle interrupts.  */
+/*  __asm__ __volatile__ ("hlt"); */
+}
+
+#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/grub-core/include/grub/i386/tsc.h b/grub-core/include/grub/i386/tsc.h
new file mode 100644 (file)
index 0000000..dad9d06
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_TSC_HEADER
+#define KERNEL_CPU_TSC_HEADER   1
+
+#include <grub/types.h>
+
+/* Read the TSC value, which increments with each CPU clock cycle. */
+static __inline grub_uint64_t
+grub_get_tsc (void)
+{
+  grub_uint32_t lo, hi;
+
+  /* The CPUID instruction is a 'serializing' instruction, and
+     avoids out-of-order execution of the RDTSC instruction. */
+#ifdef APPLE_CC
+  __asm__ __volatile__ ("xorl %%eax, %%eax\n\t"
+#ifdef __x86_64__
+                       "push %%rbx\n"
+#else
+                       "push %%ebx\n"
+#endif
+                       "cpuid\n"
+#ifdef __x86_64__
+                       "pop %%rbx\n"
+#else
+                       "pop %%ebx\n"
+#endif
+                       :::"%rax", "%rcx", "%rdx");
+#else
+  __asm__ __volatile__ ("xorl %%eax, %%eax\n\t"
+                       "cpuid":::"%rax", "%rbx", "%rcx", "%rdx");
+#endif
+  /* Read TSC value.  We cannot use "=A", since this would use
+     %rax on x86_64. */
+  __asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi));
+
+  return (((grub_uint64_t) hi) << 32) | lo;
+}
+
+#ifdef __x86_64__
+
+static __inline int
+grub_cpu_is_cpuid_supported (void)
+{
+  grub_uint64_t id_supported;
+
+  __asm__ ("pushfq\n\t"
+           "popq %%rax             /* Get EFLAGS into EAX */\n\t"
+           "movq %%rax, %%rcx      /* Save original flags in ECX */\n\t"
+           "xorq $0x200000, %%rax  /* Flip ID bit in EFLAGS */\n\t"
+           "pushq %%rax            /* Store modified EFLAGS on stack */\n\t"
+           "popfq                  /* Replace current EFLAGS */\n\t"
+           "pushfq                 /* Read back the EFLAGS */\n\t"
+           "popq %%rax             /* Get EFLAGS into EAX */\n\t"
+           "xorq %%rcx, %%rax      /* Check if flag could be modified */\n\t"
+           : "=a" (id_supported)
+           : /* No inputs.  */
+           : /* Clobbered:  */ "%rcx");
+
+  return id_supported != 0;
+}
+
+#else
+
+static __inline int
+grub_cpu_is_cpuid_supported (void)
+{
+  grub_uint32_t id_supported;
+
+  __asm__ ("pushfl\n\t"
+           "popl %%eax             /* Get EFLAGS into EAX */\n\t"
+           "movl %%eax, %%ecx      /* Save original flags in ECX */\n\t"
+           "xorl $0x200000, %%eax  /* Flip ID bit in EFLAGS */\n\t"
+           "pushl %%eax            /* Store modified EFLAGS on stack */\n\t"
+           "popfl                  /* Replace current EFLAGS */\n\t"
+           "pushfl                 /* Read back the EFLAGS */\n\t"
+           "popl %%eax             /* Get EFLAGS into EAX */\n\t"
+           "xorl %%ecx, %%eax      /* Check if flag could be modified */\n\t"
+           : "=a" (id_supported)
+           : /* No inputs.  */
+           : /* Clobbered:  */ "%rcx");
+
+  return id_supported != 0;
+}
+
+#endif
+
+static __inline int
+grub_cpu_is_tsc_supported (void)
+{
+  if (! grub_cpu_is_cpuid_supported ())
+    return 0;
+
+  grub_uint32_t features;
+#ifdef APPLE_CC
+  __asm__ ("movl $1, %%eax\n\t"
+#ifdef __x86_64__
+          "push %%rbx\n"
+#else
+          "push %%ebx\n"
+#endif
+          "cpuid\n"
+#ifdef __x86_64__
+          "pop %%rbx\n"
+#else
+          "pop %%ebx\n"
+#endif
+           : "=d" (features)
+           : /* No inputs.  */
+          : /* Clobbered:  */ "%rax", "%rcx");
+#else
+  __asm__ ("movl $1, %%eax\n\t"
+           "cpuid\n"
+           : "=d" (features)
+           : /* No inputs.  */
+           : /* Clobbered:  */ "%rax", "%rbx", "%rcx");
+#endif
+  return (features & (1 << 4)) != 0;
+}
+
+void grub_tsc_init (void);
+grub_uint64_t grub_tsc_get_time_ms (void);
+
+#endif /* ! KERNEL_CPU_TSC_HEADER */
diff --git a/grub-core/include/grub/i386/types.h b/grub-core/include/grub/i386/types.h
new file mode 100644 (file)
index 0000000..0ac6473
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER  1
+
+/* The size of void *.  */
+#define GRUB_TARGET_SIZEOF_VOID_P      4
+
+/* The size of long.  */
+#define GRUB_TARGET_SIZEOF_LONG                4
+
+/* i386 is little-endian.  */
+#undef GRUB_TARGET_WORDS_BIGENDIAN
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/grub-core/include/grub/i386/vga_common.h b/grub-core/include/grub/i386/vga_common.h
new file mode 100644 (file)
index 0000000..f17fc01
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_VGA_COMMON_CPU_HEADER
+#define GRUB_VGA_COMMON_CPU_HEADER     1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/term.h>
+
+extern grub_uint8_t grub_console_cur_color;
+
+void grub_console_putchar (grub_uint32_t c);
+grub_ssize_t grub_console_getcharwidth (grub_uint32_t c);
+grub_uint16_t grub_console_getwh (void);
+void grub_console_setcolorstate (grub_term_color_state state);
+void grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color);
+void grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color);
+
+/* Implemented in both kern/i386/pc/startup.S and vga_text.c;  this symbol
+   is not exported, so there's no collision, but vga_common.c expects this
+   prototype to be the same.  */
+void grub_console_real_putchar (int c);
+
+#endif /* ! GRUB_VGA_COMMON_CPU_HEADER */
diff --git a/grub-core/include/grub/i386/xnu.h b/grub-core/include/grub/i386/xnu.h
new file mode 100644 (file)
index 0000000..3be2c3b
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CPU_XNU_H
+#define GRUB_CPU_XNU_H 1
+
+#include <grub/err.h>
+#include <grub/efi/api.h>
+#include <grub/cpu/relocator.h>
+
+#define XNU_RELOCATOR(x) (grub_relocator32_ ## x)
+
+#define GRUB_XNU_PAGESIZE 4096
+typedef grub_uint32_t grub_xnu_ptr_t;
+
+struct grub_xnu_boot_params
+{
+  grub_uint16_t verminor;
+  grub_uint16_t vermajor;
+  /* Command line passed to xnu. */
+  grub_uint8_t cmdline[1024];
+
+  /* Later are the same as EFI's get_memory_map (). */
+  grub_xnu_ptr_t efi_mmap;
+  grub_uint32_t efi_mmap_size;
+  grub_uint32_t efi_mem_desc_size;
+  grub_uint32_t efi_mem_desc_version;
+
+  /* Later are video parameters. */
+  grub_xnu_ptr_t lfb_base;
+#define GRUB_XNU_VIDEO_SPLASH 1
+#define GRUB_XNU_VIDEO_TEXT_IN_VIDEO 2
+  grub_uint32_t lfb_mode;
+  grub_uint32_t lfb_line_len;
+  grub_uint32_t lfb_width;
+  grub_uint32_t lfb_height;
+  grub_uint32_t lfb_depth;
+
+  /* Pointer to device tree and its len. */
+  grub_xnu_ptr_t devtree;
+  grub_uint32_t devtreelen;
+
+  /* First used address by kernel or boot structures. */
+  grub_xnu_ptr_t heap_start;
+  /* Last used address by kernel or boot structures minus previous value. */
+  grub_uint32_t heap_size;
+
+  /* First memory page containing runtime code or data. */
+  grub_uint32_t efi_runtime_first_page;
+  /* First memory page containing runtime code or data minus previous value. */
+  grub_uint32_t efi_runtime_npages;
+  grub_uint32_t efi_system_table;
+  /* Size of grub_efi_uintn_t in bits. */
+  grub_uint8_t efi_uintnbits;
+} __attribute__ ((packed));
+#define GRUB_XNU_BOOTARGS_VERMINOR 5
+#define GRUB_XNU_BOOTARGS_VERMAJOR 1
+
+struct grub_xnu_devprop_header
+{
+  grub_uint32_t length;
+  /* Always set to 1. Version?  */
+  grub_uint32_t alwaysone;
+  grub_uint32_t num_devices;
+};
+
+struct grub_xnu_devprop_device_header
+{
+  grub_uint32_t length;
+  grub_uint32_t num_values;
+};
+
+void grub_cpu_xnu_unload (void);
+
+struct grub_xnu_devprop_device_descriptor;
+
+struct grub_xnu_devprop_device_descriptor *
+grub_xnu_devprop_add_device (struct grub_efi_device_path *path, int length);
+grub_err_t
+grub_xnu_devprop_remove_device (struct grub_xnu_devprop_device_descriptor *dev);
+grub_err_t
+grub_xnu_devprop_remove_property (struct grub_xnu_devprop_device_descriptor *dev,
+                                 char *name);
+grub_err_t
+grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *dev,
+                                   char *name, void *data, int datalen);
+grub_err_t
+grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor *dev,
+                                    grub_uint16_t *name, int namelen,
+                                    void *data, int datalen);
+grub_err_t
+grub_xnu_devprop_remove_property_utf8 (struct grub_xnu_devprop_device_descriptor *dev,
+                                      char *name);
+void grub_cpu_xnu_init (void);
+void grub_cpu_xnu_fini (void);
+
+extern grub_uint32_t grub_xnu_entry_point;
+extern grub_uint32_t grub_xnu_stack;
+extern grub_uint32_t grub_xnu_arg1;
+extern char grub_xnu_cmdline[1024];
+grub_err_t grub_xnu_boot (void);
+grub_err_t grub_xnu_set_video (struct grub_xnu_boot_params *bootparams_relloc);
+grub_err_t
+grub_cpu_xnu_fill_devicetree (void);
+extern grub_uint32_t grub_xnu_heap_will_be_at;
+#endif
diff --git a/grub-core/include/grub/icon_manager.h b/grub-core/include/grub/icon_manager.h
new file mode 100644 (file)
index 0000000..81c4884
--- /dev/null
@@ -0,0 +1,41 @@
+/* icon_manager.h - gfxmenu icon manager. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ICON_MANAGER_HEADER
+#define GRUB_ICON_MANAGER_HEADER 1
+
+#include <grub/menu.h>
+#include <grub/bitmap.h>
+
+/* Forward declaration of opaque structure handle type.  */
+typedef struct grub_gfxmenu_icon_manager *grub_gfxmenu_icon_manager_t;
+
+grub_gfxmenu_icon_manager_t grub_gfxmenu_icon_manager_new (void);
+void grub_gfxmenu_icon_manager_destroy (grub_gfxmenu_icon_manager_t mgr);
+void grub_gfxmenu_icon_manager_clear_cache (grub_gfxmenu_icon_manager_t mgr);
+void grub_gfxmenu_icon_manager_set_theme_path (grub_gfxmenu_icon_manager_t mgr,
+                                               const char *path);
+void grub_gfxmenu_icon_manager_set_icon_size (grub_gfxmenu_icon_manager_t mgr,
+                                              int width, int height);
+struct grub_video_bitmap *
+grub_gfxmenu_icon_manager_get_icon (grub_gfxmenu_icon_manager_t mgr,
+                                    grub_menu_entry_t entry);
+
+#endif /* GRUB_ICON_MANAGER_HEADER */
+
diff --git a/grub-core/include/grub/ieee1275/ieee1275.h b/grub-core/include/grub/ieee1275/ieee1275.h
new file mode 100644 (file)
index 0000000..2b2c36f
--- /dev/null
@@ -0,0 +1,187 @@
+/* ieee1275.h - Access the Open Firmware client interface.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_IEEE1275_HEADER
+#define GRUB_IEEE1275_HEADER   1
+
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/machine/ieee1275.h>
+
+/* Maps a device alias to a pathname.  */
+struct grub_ieee1275_devalias
+{
+  char *name;
+  char *path;
+  char *type;
+};
+
+struct grub_ieee1275_mem_region
+{
+  unsigned int start;
+  unsigned int size;
+};
+
+#define IEEE1275_MAX_PROP_LEN  8192
+#define IEEE1275_MAX_PATH_LEN  256
+
+#ifndef IEEE1275_CALL_ENTRY_FN
+#define IEEE1275_CALL_ENTRY_FN(args) (*grub_ieee1275_entry_fn) (args)
+#endif
+
+/* All backcalls to the firmware is done by calling an entry function
+   which was passed to us from the bootloader.  When doing the backcall,
+   a structure is passed which specifies what the firmware should do.
+   NAME is the requested service.  NR_INS and NR_OUTS is the number of
+   passed arguments and the expected number of return values, resp. */
+struct grub_ieee1275_common_hdr
+{
+  grub_ieee1275_cell_t name;
+  grub_ieee1275_cell_t nr_ins;
+  grub_ieee1275_cell_t nr_outs;
+};
+
+#define INIT_IEEE1275_COMMON(p, xname, xins, xouts) \
+  (p)->name = (grub_ieee1275_cell_t) xname; \
+  (p)->nr_ins = (grub_ieee1275_cell_t) xins; \
+  (p)->nr_outs = (grub_ieee1275_cell_t) xouts
+
+typedef grub_uint32_t grub_ieee1275_ihandle_t;
+typedef grub_uint32_t grub_ieee1275_phandle_t;
+
+extern grub_ieee1275_phandle_t EXPORT_VAR(grub_ieee1275_chosen);
+extern grub_ieee1275_ihandle_t EXPORT_VAR(grub_ieee1275_mmu);
+extern int (* EXPORT_VAR(grub_ieee1275_entry_fn)) (void *);
+
+enum grub_ieee1275_flag
+{
+  /* Old World Macintosh firmware fails seek when "dev:0" is opened.  */
+  GRUB_IEEE1275_FLAG_NO_PARTITION_0,
+
+  /* Apple firmware runs in translated mode and requires use of the "map"
+     method.  Other firmware runs in untranslated mode and doesn't like "map"
+     calls.  */
+  GRUB_IEEE1275_FLAG_REAL_MODE,
+
+  /* CHRP specifies partitions are numbered from 1 (partition 0 refers to the
+     whole disk). However, CodeGen firmware numbers partitions from 0.  */
+  GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS,
+
+  /* CodeGen firmware does not correctly implement "output-device output" */
+  GRUB_IEEE1275_FLAG_BROKEN_OUTPUT,
+
+  /* OLPC / XO firmware hangs when accessing USB devices.  */
+  GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY,
+
+  /* Open Hack'Ware stops when trying to set colors */
+  GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS,
+
+  /* Open Hack'Ware stops when grub_ieee1275_interpret is used.  */
+  GRUB_IEEE1275_FLAG_CANNOT_INTERPRET,
+
+  /* Open Hack'Ware has no memory map, just claim what we need.  */
+  GRUB_IEEE1275_FLAG_FORCE_CLAIM,
+
+  /* Open Hack'Ware don't support the ANSI sequence.  */
+  GRUB_IEEE1275_FLAG_NO_ANSI,
+};
+
+extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag);
+extern void EXPORT_FUNC(grub_ieee1275_set_flag) (enum grub_ieee1275_flag flag);
+
+\f
+
+
+void EXPORT_FUNC(grub_ieee1275_init) (void);
+int EXPORT_FUNC(grub_ieee1275_finddevice) (char *name,
+                                          grub_ieee1275_phandle_t *phandlep);
+int EXPORT_FUNC(grub_ieee1275_get_property) (grub_ieee1275_phandle_t phandle,
+                                            const char *property, void *buf,
+                                            grub_size_t size,
+                                            grub_ssize_t *actual);
+int EXPORT_FUNC(grub_ieee1275_get_integer_property) (grub_ieee1275_phandle_t phandle,
+                                                    const char *property, grub_uint32_t *buf,
+                                                    grub_size_t size,
+                                                    grub_ssize_t *actual);
+int EXPORT_FUNC(grub_ieee1275_next_property) (grub_ieee1275_phandle_t phandle,
+                                             char *prev_prop, char *prop);
+int EXPORT_FUNC(grub_ieee1275_get_property_length)
+     (grub_ieee1275_phandle_t phandle, const char *prop, grub_ssize_t *length);
+int EXPORT_FUNC(grub_ieee1275_instance_to_package)
+     (grub_ieee1275_ihandle_t ihandle, grub_ieee1275_phandle_t *phandlep);
+int EXPORT_FUNC(grub_ieee1275_package_to_path) (grub_ieee1275_phandle_t phandle,
+                                               char *path, grub_size_t len,
+                                               grub_ssize_t *actual);
+int EXPORT_FUNC(grub_ieee1275_instance_to_path)
+     (grub_ieee1275_ihandle_t ihandle, char *path, grub_size_t len,
+      grub_ssize_t *actual);
+int EXPORT_FUNC(grub_ieee1275_write) (grub_ieee1275_ihandle_t ihandle,
+                                     void *buffer, grub_size_t len,
+                                     grub_ssize_t *actualp);
+int EXPORT_FUNC(grub_ieee1275_read) (grub_ieee1275_ihandle_t ihandle,
+                                    void *buffer, grub_size_t len,
+                                    grub_ssize_t *actualp);
+int EXPORT_FUNC(grub_ieee1275_seek) (grub_ieee1275_ihandle_t ihandle,
+                                    grub_disk_addr_t pos,
+                                    grub_ssize_t *result);
+int EXPORT_FUNC(grub_ieee1275_peer) (grub_ieee1275_phandle_t node,
+                                    grub_ieee1275_phandle_t *result);
+int EXPORT_FUNC(grub_ieee1275_child) (grub_ieee1275_phandle_t node,
+                                     grub_ieee1275_phandle_t *result);
+int EXPORT_FUNC(grub_ieee1275_parent) (grub_ieee1275_phandle_t node,
+                                      grub_ieee1275_phandle_t *result);
+int EXPORT_FUNC(grub_ieee1275_interpret) (const char *command,
+                                         grub_ieee1275_cell_t *catch);
+int EXPORT_FUNC(grub_ieee1275_enter) (void);
+void EXPORT_FUNC(grub_ieee1275_exit) (void) __attribute__ ((noreturn));
+int EXPORT_FUNC(grub_ieee1275_open) (const char *node,
+                                    grub_ieee1275_ihandle_t *result);
+int EXPORT_FUNC(grub_ieee1275_close) (grub_ieee1275_ihandle_t ihandle);
+int EXPORT_FUNC(grub_ieee1275_claim) (grub_addr_t addr, grub_size_t size,
+                                     unsigned int align, grub_addr_t *result);
+int EXPORT_FUNC(grub_ieee1275_release) (grub_addr_t addr, grub_size_t size);
+int EXPORT_FUNC(grub_ieee1275_set_property) (grub_ieee1275_phandle_t phandle,
+                                            const char *propname, void *buf,
+                                            grub_size_t size,
+                                            grub_ssize_t *actual);
+int EXPORT_FUNC(grub_ieee1275_set_color) (grub_ieee1275_ihandle_t ihandle,
+                                         int index, int r, int g, int b);
+int EXPORT_FUNC(grub_ieee1275_milliseconds) (grub_uint32_t *msecs);
+
+
+int EXPORT_FUNC(grub_devalias_iterate)
+     (int (*hook) (struct grub_ieee1275_devalias *alias));
+int EXPORT_FUNC(grub_children_iterate) (char *devpath,
+     int (*hook) (struct grub_ieee1275_devalias *alias));
+grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
+     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
+int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
+
+int
+EXPORT_FUNC(grub_ieee1275_map) (grub_addr_t phys, grub_addr_t virt,
+                               grub_size_t size, grub_uint32_t mode);
+
+char *EXPORT_FUNC(grub_ieee1275_encode_devname) (const char *path);
+char *EXPORT_FUNC(grub_ieee1275_get_filename) (const char *path);
+
+int EXPORT_FUNC(grub_ieee1275_devices_iterate) (int (*hook)
+                                               (struct grub_ieee1275_devalias *
+                                                alias));
+
+#endif /* ! GRUB_IEEE1275_HEADER */
diff --git a/grub-core/include/grub/ieee1275/ofdisk.h b/grub-core/include/grub/ieee1275/ofdisk.h
new file mode 100644 (file)
index 0000000..2f69e3f
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_OFDISK_HEADER
+#define GRUB_OFDISK_HEADER     1
+
+extern void grub_ofdisk_init (void);
+extern void grub_ofdisk_fini (void);
+
+#endif /* ! GRUB_INIT_HEADER */
diff --git a/grub-core/include/grub/kernel.h b/grub-core/include/grub/kernel.h
new file mode 100644 (file)
index 0000000..bf52ffc
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_HEADER
+#define GRUB_KERNEL_HEADER     1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+enum
+{
+  OBJ_TYPE_ELF,
+  OBJ_TYPE_MEMDISK,
+  OBJ_TYPE_CONFIG,
+  OBJ_TYPE_FONT
+};
+
+/* The module header.  */
+struct grub_module_header
+{
+  /* The type of object.  */
+  grub_uint8_t type;
+  /* The size of object (including this header).  */
+  grub_uint32_t size;
+};
+
+/* "gmim" (GRUB Module Info Magic).  */
+#define GRUB_MODULE_MAGIC 0x676d696d
+
+struct grub_module_info
+{
+  /* Magic number so we know we have modules present.  */
+  grub_uint32_t magic;
+#if GRUB_TARGET_SIZEOF_VOID_P == 8
+  grub_uint32_t padding;
+#endif
+  /* The offset of the modules.  */
+  grub_target_off_t offset;
+  /* The size of all modules plus this header.  */
+  grub_target_size_t size;
+};
+
+extern grub_addr_t grub_arch_modules_addr (void);
+
+extern void EXPORT_FUNC(grub_module_iterate) (int (*hook) (struct grub_module_header *));
+
+grub_addr_t grub_modules_get_end (void);
+
+/* The start point of the C code.  */
+void grub_main (void);
+
+/* The machine-specific initialization. This must initialize memory.  */
+void grub_machine_init (void);
+
+/* The machine-specific finalization.  */
+void EXPORT_FUNC(grub_machine_fini) (void);
+
+/* The machine-specific prefix initialization.  */
+void grub_machine_set_prefix (void);
+
+/* Register all the exported symbols. This is automatically generated.  */
+void grub_register_exported_symbols (void);
+
+#endif /* ! GRUB_KERNEL_HEADER */
diff --git a/grub-core/include/grub/lib/LzFind.h b/grub-core/include/grub/lib/LzFind.h
new file mode 100644 (file)
index 0000000..69447b6
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#ifndef __LZFIND_H
+#define __LZFIND_H
+
+#include <grub/lib/LzmaTypes.h>
+
+typedef UInt32 CLzRef;
+
+typedef struct _CMatchFinder
+{
+  Byte *buffer;
+  UInt32 pos;
+  UInt32 posLimit;
+  UInt32 streamPos;
+  UInt32 lenLimit;
+
+  UInt32 cyclicBufferPos;
+  UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
+
+  UInt32 matchMaxLen;
+  CLzRef *hash;
+  CLzRef *son;
+  UInt32 hashMask;
+  UInt32 cutValue;
+
+  Byte *bufferBase;
+  ISeqInStream *stream;
+  int streamEndWasReached;
+
+  UInt32 blockSize;
+  UInt32 keepSizeBefore;
+  UInt32 keepSizeAfter;
+
+  UInt32 numHashBytes;
+  int directInput;
+  int btMode;
+  /* int skipModeBits; */
+  int bigHash;
+  UInt32 historySize;
+  UInt32 fixedHashSize;
+  UInt32 hashSizeSum;
+  UInt32 numSons;
+  SRes result;
+  UInt32 crc[256];
+} CMatchFinder;
+
+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
+
+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
+
+int MatchFinder_NeedMove(CMatchFinder *p);
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
+void MatchFinder_MoveBlock(CMatchFinder *p);
+void MatchFinder_ReadIfRequired(CMatchFinder *p);
+
+void MatchFinder_Construct(CMatchFinder *p);
+
+/* Conditions:
+     historySize <= 3 GB
+     keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
+*/
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
+    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
+    ISzAlloc *alloc);
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
+
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
+    UInt32 *distances, UInt32 maxLen);
+
+/*
+Conditions:
+  Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
+  Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
+*/
+
+typedef void (*Mf_Init_Func)(void *object);
+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
+typedef void (*Mf_Skip_Func)(void *object, UInt32);
+
+typedef struct _IMatchFinder
+{
+  Mf_Init_Func Init;
+  Mf_GetIndexByte_Func GetIndexByte;
+  Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
+  Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
+  Mf_GetMatches_Func GetMatches;
+  Mf_Skip_Func Skip;
+} IMatchFinder;
+
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
+
+void MatchFinder_Init(CMatchFinder *p);
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
+
+#endif
diff --git a/grub-core/include/grub/lib/LzHash.h b/grub-core/include/grub/lib/LzHash.h
new file mode 100644 (file)
index 0000000..c3d5586
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#ifndef __LZHASH_H
+#define __LZHASH_H
+
+#define kHash2Size (1 << 10)
+#define kHash3Size (1 << 16)
+#define kHash4Size (1 << 20)
+
+#define kFix3HashSize (kHash2Size)
+#define kFix4HashSize (kHash2Size + kHash3Size)
+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
+
+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
+
+#define HASH3_CALC { \
+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+  hash2Value = temp & (kHash2Size - 1); \
+  hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
+
+#define HASH4_CALC { \
+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+  hash2Value = temp & (kHash2Size - 1); \
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+  hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
+
+#define HASH5_CALC { \
+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+  hash2Value = temp & (kHash2Size - 1); \
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
+  hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
+  hash4Value &= (kHash4Size - 1); }
+
+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
+
+
+#define MT_HASH2_CALC \
+  hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
+
+#define MT_HASH3_CALC { \
+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+  hash2Value = temp & (kHash2Size - 1); \
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
+
+#define MT_HASH4_CALC { \
+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+  hash2Value = temp & (kHash2Size - 1); \
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
+
+#endif
diff --git a/grub-core/include/grub/lib/LzmaDec.h b/grub-core/include/grub/lib/LzmaDec.h
new file mode 100644 (file)
index 0000000..1e66b74
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#ifndef __LZMADEC_H
+#define __LZMADEC_H
+
+#include "Types.h"
+
+/* #define _LZMA_PROB32 */
+/* _LZMA_PROB32 can increase the speed on some CPUs,
+   but memory usage for CLzmaDec::probs will be doubled in that case */
+
+#ifdef _LZMA_PROB32
+#define CLzmaProb UInt32
+#else
+#define CLzmaProb UInt16
+#endif
+
+
+/* ---------- LZMA Properties ---------- */
+
+#define LZMA_PROPS_SIZE 5
+
+typedef struct _CLzmaProps
+{
+  unsigned lc, lp, pb;
+  UInt32 dicSize;
+} CLzmaProps;
+
+/* LzmaProps_Decode - decodes properties
+Returns:
+  SZ_OK
+  SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
+
+
+/* ---------- LZMA Decoder state ---------- */
+
+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
+   Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
+
+#define LZMA_REQUIRED_INPUT_MAX 20
+
+typedef struct
+{
+  CLzmaProps prop;
+  CLzmaProb *probs;
+  Byte *dic;
+  const Byte *buf;
+  UInt32 range, code;
+  SizeT dicPos;
+  SizeT dicBufSize;
+  UInt32 processedPos;
+  UInt32 checkDicSize;
+  unsigned state;
+  UInt32 reps[4];
+  unsigned remainLen;
+  int needFlush;
+  int needInitState;
+  UInt32 numProbs;
+  unsigned tempBufSize;
+  Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
+} CLzmaDec;
+
+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
+
+void LzmaDec_Init(CLzmaDec *p);
+
+/* There are two types of LZMA streams:
+     0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
+     1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
+
+typedef enum
+{
+  LZMA_FINISH_ANY,   /* finish at any point */
+  LZMA_FINISH_END    /* block must be finished at the end */
+} ELzmaFinishMode;
+
+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
+
+   You must use LZMA_FINISH_END, when you know that current output buffer
+   covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
+
+   If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
+   and output value of destLen will be less than output buffer size limit.
+   You can check status result also.
+
+   You can use multiple checks to test data integrity after full decompression:
+     1) Check Result and "status" variable.
+     2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
+     3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
+        You must use correct finish mode in that case. */
+
+typedef enum
+{
+  LZMA_STATUS_NOT_SPECIFIED,               /* use main error code instead */
+  LZMA_STATUS_FINISHED_WITH_MARK,          /* stream was finished with end mark. */
+  LZMA_STATUS_NOT_FINISHED,                /* stream was not finished */
+  LZMA_STATUS_NEEDS_MORE_INPUT,            /* you must provide more input bytes */
+  LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK  /* there is probability that stream was finished without end mark */
+} ELzmaStatus;
+
+/* ELzmaStatus is used only as output value for function call */
+
+
+/* ---------- Interfaces ---------- */
+
+/* There are 3 levels of interfaces:
+     1) Dictionary Interface
+     2) Buffer Interface
+     3) One Call Interface
+   You can select any of these interfaces, but don't mix functions from different
+   groups for same object. */
+
+
+/* There are two variants to allocate state for Dictionary Interface:
+     1) LzmaDec_Allocate / LzmaDec_Free
+     2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
+   You can use variant 2, if you set dictionary buffer manually.
+   For Buffer Interface you must always use variant 1.
+
+LzmaDec_Allocate* can return:
+  SZ_OK
+  SZ_ERROR_MEM         - Memory allocation error
+  SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
+
+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
+
+/* ---------- Dictionary Interface ---------- */
+
+/* You can use it, if you want to eliminate the overhead for data copying from
+   dictionary to some other external buffer.
+   You must work with CLzmaDec variables directly in this interface.
+
+   STEPS:
+     LzmaDec_Constr()
+     LzmaDec_Allocate()
+     for (each new stream)
+     {
+       LzmaDec_Init()
+       while (it needs more decompression)
+       {
+         LzmaDec_DecodeToDic()
+         use data from CLzmaDec::dic and update CLzmaDec::dicPos
+       }
+     }
+     LzmaDec_Free()
+*/
+
+/* LzmaDec_DecodeToDic
+
+   The decoding to internal dictionary buffer (CLzmaDec::dic).
+   You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
+
+finishMode:
+  It has meaning only if the decoding reaches output limit (dicLimit).
+  LZMA_FINISH_ANY - Decode just dicLimit bytes.
+  LZMA_FINISH_END - Stream must be finished after dicLimit.
+
+Returns:
+  SZ_OK
+    status:
+      LZMA_STATUS_FINISHED_WITH_MARK
+      LZMA_STATUS_NOT_FINISHED
+      LZMA_STATUS_NEEDS_MORE_INPUT
+      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+  SZ_ERROR_DATA - Data error
+*/
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- Buffer Interface ---------- */
+
+/* It's zlib-like interface.
+   See LzmaDec_DecodeToDic description for information about STEPS and return results,
+   but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
+   to work with CLzmaDec variables manually.
+
+finishMode:
+  It has meaning only if the decoding reaches output limit (*destLen).
+  LZMA_FINISH_ANY - Decode just destLen bytes.
+  LZMA_FINISH_END - Stream must be finished after (*destLen).
+*/
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- One Call Interface ---------- */
+
+/* LzmaDecode
+
+finishMode:
+  It has meaning only if the decoding reaches output limit (*destLen).
+  LZMA_FINISH_ANY - Decode just destLen bytes.
+  LZMA_FINISH_END - Stream must be finished after (*destLen).
+
+Returns:
+  SZ_OK
+    status:
+      LZMA_STATUS_FINISHED_WITH_MARK
+      LZMA_STATUS_NOT_FINISHED
+      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+  SZ_ERROR_DATA - Data error
+  SZ_ERROR_MEM  - Memory allocation error
+  SZ_ERROR_UNSUPPORTED - Unsupported properties
+  SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
+*/
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+    ELzmaStatus *status, ISzAlloc *alloc);
+
+#endif
diff --git a/grub-core/include/grub/lib/LzmaEnc.h b/grub-core/include/grub/lib/LzmaEnc.h
new file mode 100644 (file)
index 0000000..fc156a4
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#ifndef __LZMAENC_H
+#define __LZMAENC_H
+
+#include "LzmaTypes.h"
+
+#define LZMA_PROPS_SIZE 5
+
+typedef struct _CLzmaEncProps
+{
+  int level;       /*  0 <= level <= 9 */
+  UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
+                      (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
+                       default = (1 << 24) */
+  int lc;          /* 0 <= lc <= 8, default = 3 */
+  int lp;          /* 0 <= lp <= 4, default = 0 */
+  int pb;          /* 0 <= pb <= 4, default = 2 */
+  int algo;        /* 0 - fast, 1 - normal, default = 1 */
+  int fb;          /* 5 <= fb <= 273, default = 32 */
+  int btMode;      /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
+  int numHashBytes; /* 2, 3 or 4, default = 4 */
+  UInt32 mc;        /* 1 <= mc <= (1 << 30), default = 32 */
+  unsigned writeEndMark;  /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
+  int numThreads;  /* 1 or 2, default = 2 */
+} CLzmaEncProps;
+
+void LzmaEncProps_Init(CLzmaEncProps *p);
+void LzmaEncProps_Normalize(CLzmaEncProps *p);
+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
+
+
+/* ---------- CLzmaEncHandle Interface ---------- */
+
+/* LzmaEnc_* functions can return the following exit codes:
+Returns:
+  SZ_OK           - OK
+  SZ_ERROR_MEM    - Memory allocation error
+  SZ_ERROR_PARAM  - Incorrect parameter in props
+  SZ_ERROR_WRITE  - Write callback error.
+  SZ_ERROR_PROGRESS - some break from progress callback
+  SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
+*/
+
+typedef void * CLzmaEncHandle;
+
+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
+SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
+SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
+SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
+    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+
+/* ---------- One Call Interface ---------- */
+
+/* LzmaEncode
+Return code:
+  SZ_OK               - OK
+  SZ_ERROR_MEM        - Memory allocation error
+  SZ_ERROR_PARAM      - Incorrect parameter
+  SZ_ERROR_OUTPUT_EOF - output buffer overflow
+  SZ_ERROR_THREAD     - errors in multithreading functions (only for Mt version)
+*/
+
+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
+    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+
+#endif
diff --git a/grub-core/include/grub/lib/LzmaTypes.h b/grub-core/include/grub/lib/LzmaTypes.h
new file mode 100644 (file)
index 0000000..1e783a2
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#ifndef __7Z_TYPES_H
+#define __7Z_TYPES_H
+
+#define SZ_OK 0
+
+#define SZ_ERROR_DATA 1
+#define SZ_ERROR_MEM 2
+#define SZ_ERROR_CRC 3
+#define SZ_ERROR_UNSUPPORTED 4
+#define SZ_ERROR_PARAM 5
+#define SZ_ERROR_INPUT_EOF 6
+#define SZ_ERROR_OUTPUT_EOF 7
+#define SZ_ERROR_READ 8
+#define SZ_ERROR_WRITE 9
+#define SZ_ERROR_PROGRESS 10
+#define SZ_ERROR_FAIL 11
+#define SZ_ERROR_THREAD 12
+
+#define SZ_ERROR_ARCHIVE 16
+#define SZ_ERROR_NO_ARCHIVE 17
+
+typedef int SRes;
+
+#ifndef RINOK
+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
+#endif
+
+typedef unsigned char Byte;
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef long Int32;
+typedef unsigned long UInt32;
+#else
+typedef int Int32;
+typedef unsigned int UInt32;
+#endif
+
+/* #define _SZ_NO_INT_64 */
+/* define it if your compiler doesn't support 64-bit integers */
+
+#ifdef _SZ_NO_INT_64
+
+typedef long Int64;
+typedef unsigned long UInt64;
+
+#else
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef __int64 Int64;
+typedef unsigned __int64 UInt64;
+#else
+typedef long long int Int64;
+typedef unsigned long long int UInt64;
+#endif
+
+#endif
+
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+#include <stddef.h>
+typedef size_t SizeT;
+#endif
+
+typedef int Bool;
+#define True 1
+#define False 0
+
+
+#ifdef _MSC_VER
+
+#if _MSC_VER >= 1300
+#define MY_NO_INLINE __declspec(noinline)
+#else
+#define MY_NO_INLINE
+#endif
+
+#define MY_CDECL __cdecl
+#define MY_STD_CALL __stdcall
+#define MY_FAST_CALL MY_NO_INLINE __fastcall
+
+#else
+
+#define MY_CDECL
+#define MY_STD_CALL
+#define MY_FAST_CALL
+
+#endif
+
+
+/* The following interfaces use first parameter as pointer to structure */
+
+typedef struct
+{
+  SRes (*Read)(void *p, void *buf, size_t *size);
+    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+       (output(*size) < input(*size)) is allowed */
+} ISeqInStream;
+
+typedef struct
+{
+  size_t (*Write)(void *p, const void *buf, size_t size);
+    /* Returns: result - the number of actually written bytes.
+      (result < size) means error */
+} ISeqOutStream;
+
+typedef struct
+{
+  SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
+    /* Returns: result. (result != SZ_OK) means break.
+       Value (UInt64)(Int64)-1 for size means unknown value. */
+} ICompressProgress;
+
+typedef struct
+{
+  void *(*Alloc)(void *p, size_t size);
+  void (*Free)(void *p, void *address); /* address can be 0 */
+} ISzAlloc;
+
+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
+#define IAlloc_Free(p, a) (p)->Free((p), a)
+
+#endif
diff --git a/grub-core/include/grub/lib/arg.h b/grub-core/include/grub/lib/arg.h
new file mode 100644 (file)
index 0000000..e6af60c
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ARG_HEADER
+#define GRUB_ARG_HEADER        1
+
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/types.h>
+
+enum grub_arg_type
+  {
+    ARG_TYPE_NONE,
+    ARG_TYPE_STRING,
+    ARG_TYPE_INT,
+    ARG_TYPE_DEVICE,
+    ARG_TYPE_FILE,
+    ARG_TYPE_DIR,
+    ARG_TYPE_PATHNAME
+  };
+
+typedef enum grub_arg_type grub_arg_type_t;
+
+/* Flags for the option field op grub_arg_option.  */
+#define GRUB_ARG_OPTION_OPTIONAL       (1 << 1)
+
+enum grub_key_type
+  {
+    GRUB_KEY_ARG = -1,
+    GRUB_KEY_END = -2
+  };
+typedef enum grub_key_type grub_arg_key_type_t;
+
+struct grub_arg_option
+{
+  const char *longarg;
+  int shortarg;
+  int flags;
+  char *doc;
+  char *arg;
+  grub_arg_type_t type;
+};
+
+struct grub_arg_list
+{
+  int set;
+  char *arg;
+};
+
+struct grub_extcmd;
+
+int grub_arg_parse (struct grub_extcmd *cmd, int argc, char **argv,
+                   struct grub_arg_list *usr, char ***args, int *argnum);
+
+void grub_arg_show_help (struct grub_extcmd *cmd);
+
+#endif /* ! GRUB_ARG_HEADER */
diff --git a/grub-core/include/grub/lib/crc.h b/grub-core/include/grub/lib/crc.h
new file mode 100644 (file)
index 0000000..ff7284d
--- /dev/null
@@ -0,0 +1,25 @@
+/* crc.h - prototypes for crc */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CRC_H
+#define GRUB_CRC_H     1
+
+grub_uint32_t grub_getcrc32 (grub_uint32_t crc, void *buf, int size);
+
+#endif /* ! GRUB_CRC_H */
diff --git a/grub-core/include/grub/lib/envblk.h b/grub-core/include/grub/lib/envblk.h
new file mode 100644 (file)
index 0000000..368ba53
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_ENVBLK_HEADER
+#define GRUB_ENVBLK_HEADER     1
+
+#define GRUB_ENVBLK_SIGNATURE  "# GRUB Environment Block\n"
+#define GRUB_ENVBLK_DEFCFG     "grubenv"
+
+#ifndef ASM_FILE
+
+struct grub_envblk
+{
+  char *buf;
+  grub_size_t size;
+};
+typedef struct grub_envblk *grub_envblk_t;
+
+grub_envblk_t grub_envblk_open (char *buf, grub_size_t size);
+int grub_envblk_set (grub_envblk_t envblk, const char *name, const char *value);
+void grub_envblk_delete (grub_envblk_t envblk, const char *name);
+void grub_envblk_iterate (grub_envblk_t envblk,
+                          int hook (const char *name, const char *value));
+void grub_envblk_close (grub_envblk_t envblk);
+
+static inline char *
+grub_envblk_buffer (const grub_envblk_t envblk)
+{
+  return envblk->buf;
+}
+
+static inline grub_size_t
+grub_envblk_size (const grub_envblk_t envblk)
+{
+  return envblk->size;
+}
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! GRUB_ENVBLK_HEADER */
diff --git a/grub-core/include/grub/lib/hexdump.h b/grub-core/include/grub/lib/hexdump.h
new file mode 100644 (file)
index 0000000..23c6fa6
--- /dev/null
@@ -0,0 +1,25 @@
+/* hexdump.h - prototypes for dump */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_HEXDUMP_H
+#define GRUB_HEXDUMP_H 1
+
+void hexdump (unsigned long bse,char* buf,int len);
+
+#endif /* ! GRUB_HEXDUMP_H */
diff --git a/grub-core/include/grub/libgcc.h b/grub-core/include/grub/libgcc.h
new file mode 100644 (file)
index 0000000..d0adae8
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+/* On x86 these functions aren't really needed. Save some space.  */
+#if !defined (__i386__) && !defined (__x86_64__)
+# ifdef HAVE___ASHLDI3
+void EXPORT_FUNC (__ashldi3) (void);
+# endif
+# ifdef HAVE___ASHRDI3
+void EXPORT_FUNC (__ashrdi3) (void);
+# endif
+# ifdef HAVE___LSHRDI3
+void EXPORT_FUNC (__lshrdi3) (void);
+# endif
+# ifdef HAVE___UCMPDI2
+void EXPORT_FUNC (__ucmpdi2) (void);
+# endif
+# ifdef HAVE___BSWAPSI2
+void EXPORT_FUNC (__bswapsi2) (void);
+# endif
+# ifdef HAVE___BSWAPDI2
+void EXPORT_FUNC (__bswapdi2) (void);
+# endif
+#endif
+
+#ifdef HAVE___TRAMPOLINE_SETUP
+void EXPORT_FUNC (__trampoline_setup) (void);
+#endif
+
+#ifdef HAVE__RESTGPR_14_X
+void EXPORT_FUNC (_restgpr_14_x) (void);
+void EXPORT_FUNC (_restgpr_15_x) (void);
+void EXPORT_FUNC (_restgpr_16_x) (void);
+void EXPORT_FUNC (_restgpr_17_x) (void);
+void EXPORT_FUNC (_restgpr_18_x) (void);
+void EXPORT_FUNC (_restgpr_19_x) (void);
+void EXPORT_FUNC (_restgpr_20_x) (void);
+void EXPORT_FUNC (_restgpr_21_x) (void);
+void EXPORT_FUNC (_restgpr_22_x) (void);
+void EXPORT_FUNC (_restgpr_23_x) (void);
+void EXPORT_FUNC (_restgpr_24_x) (void);
+void EXPORT_FUNC (_restgpr_25_x) (void);
+void EXPORT_FUNC (_restgpr_26_x) (void);
+void EXPORT_FUNC (_restgpr_27_x) (void);
+void EXPORT_FUNC (_restgpr_28_x) (void);
+void EXPORT_FUNC (_restgpr_29_x) (void);
+void EXPORT_FUNC (_restgpr_30_x) (void);
+void EXPORT_FUNC (_restgpr_31_x) (void);
+void EXPORT_FUNC (_savegpr_14) (void);
+void EXPORT_FUNC (_savegpr_15) (void);
+void EXPORT_FUNC (_savegpr_16) (void);
+void EXPORT_FUNC (_savegpr_17) (void);
+void EXPORT_FUNC (_savegpr_18) (void);
+void EXPORT_FUNC (_savegpr_19) (void);
+void EXPORT_FUNC (_savegpr_20) (void);
+void EXPORT_FUNC (_savegpr_21) (void);
+void EXPORT_FUNC (_savegpr_22) (void);
+void EXPORT_FUNC (_savegpr_23) (void);
+void EXPORT_FUNC (_savegpr_24) (void);
+void EXPORT_FUNC (_savegpr_25) (void);
+void EXPORT_FUNC (_savegpr_26) (void);
+void EXPORT_FUNC (_savegpr_27) (void);
+void EXPORT_FUNC (_savegpr_28) (void);
+void EXPORT_FUNC (_savegpr_29) (void);
+void EXPORT_FUNC (_savegpr_30) (void);
+void EXPORT_FUNC (_savegpr_31) (void);
+#endif
diff --git a/grub-core/include/grub/libpciaccess.h b/grub-core/include/grub/libpciaccess.h
new file mode 100644 (file)
index 0000000..4d2b3bd
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+void EXPORT_FUNC (pci_slot_match_iterator_create) (void);
+void EXPORT_FUNC (pci_system_cleanup) (void);
+void EXPORT_FUNC (pci_device_unmap_range) (void);
+void EXPORT_FUNC (pci_iterator_destroy) (void);
+void EXPORT_FUNC (pci_device_map_range) (void);
+void EXPORT_FUNC (pci_device_cfg_read_u32) (void);
+void EXPORT_FUNC (pci_device_next) (void);
+void EXPORT_FUNC (pci_system_init) (void);
diff --git a/grub-core/include/grub/libusb.h b/grub-core/include/grub/libusb.h
new file mode 100644 (file)
index 0000000..26548bc
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+void EXPORT_FUNC (usb_bulk_write) (void);
+void EXPORT_FUNC (usb_find_busses) (void);
+void EXPORT_FUNC (usb_init) (void);
+void EXPORT_FUNC (usb_find_devices) (void);
+void EXPORT_FUNC (usb_open) (void);
+void EXPORT_FUNC (usb_get_busses) (void);
+void EXPORT_FUNC (usb_control_msg) (void);
+void EXPORT_FUNC (usb_release_interface) (void);
+void EXPORT_FUNC (usb_close) (void);
+void EXPORT_FUNC (usb_bulk_read) (void);
+void EXPORT_FUNC (usb_claim_interface) (void);
diff --git a/grub-core/include/grub/list.h b/grub-core/include/grub/list.h
new file mode 100644 (file)
index 0000000..5559158
--- /dev/null
@@ -0,0 +1,122 @@
+/* list.h - header for grub list */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LIST_HEADER
+#define GRUB_LIST_HEADER 1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+
+struct grub_list
+{
+  struct grub_list *next;
+};
+typedef struct grub_list *grub_list_t;
+
+typedef int (*grub_list_hook_t) (grub_list_t item);
+typedef int (*grub_list_test_t) (grub_list_t new_item, grub_list_t item);
+
+void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item);
+void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head);
+void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item);
+int EXPORT_FUNC(grub_list_iterate) (grub_list_t head, grub_list_hook_t hook);
+void EXPORT_FUNC(grub_list_insert) (grub_list_t *head, grub_list_t item,
+                                   grub_list_test_t test);
+
+static inline void *
+grub_bad_type_cast_real (int line, const char *file)
+     ATTRIBUTE_ERROR ("bad type cast between incompatible grub types");
+
+static inline void *
+grub_bad_type_cast_real (int line, const char *file)
+{
+  grub_fatal ("error:%s:%u: bad type cast between incompatible grub types",
+             file, line);
+  return 0;
+}
+
+#define grub_bad_type_cast() grub_bad_type_cast_real(__LINE__, GRUB_FILE)
+
+#define GRUB_FIELD_MATCH(ptr, type, field) \
+  ((char *) &(ptr)->field == (char *) &((type) (ptr))->field)
+
+#define GRUB_AS_LIST(ptr) \
+  (GRUB_FIELD_MATCH (ptr, grub_list_t, next) ? \
+   (grub_list_t) ptr : grub_bad_type_cast ())
+
+#define GRUB_AS_LIST_P(pptr) \
+  (GRUB_FIELD_MATCH (*pptr, grub_list_t, next) ? \
+   (grub_list_t *) (void *) pptr : grub_bad_type_cast ())
+
+struct grub_named_list
+{
+  struct grub_named_list *next;
+  char *name;
+};
+typedef struct grub_named_list *grub_named_list_t;
+
+void * EXPORT_FUNC(grub_named_list_find) (grub_named_list_t head,
+                                         const char *name);
+
+#define GRUB_AS_NAMED_LIST(ptr) \
+  ((GRUB_FIELD_MATCH (ptr, grub_named_list_t, next) && \
+    GRUB_FIELD_MATCH (ptr, grub_named_list_t, name))? \
+   (grub_named_list_t) ptr : grub_bad_type_cast ())
+
+#define GRUB_AS_NAMED_LIST_P(pptr) \
+  ((GRUB_FIELD_MATCH (*pptr, grub_named_list_t, next) && \
+    GRUB_FIELD_MATCH (*pptr, grub_named_list_t, name))? \
+   (grub_named_list_t *) (void *) pptr : grub_bad_type_cast ())
+
+#define GRUB_PRIO_LIST_PRIO_MASK       0xff
+#define GRUB_PRIO_LIST_FLAG_ACTIVE     0x100
+
+struct grub_prio_list
+{
+  struct grub_prio_list *next;
+  char *name;
+  int prio;
+};
+typedef struct grub_prio_list *grub_prio_list_t;
+
+void EXPORT_FUNC(grub_prio_list_insert) (grub_prio_list_t *head,
+                                        grub_prio_list_t item);
+
+static inline void
+grub_prio_list_remove (grub_prio_list_t *head, grub_prio_list_t item)
+{
+  if ((item->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) && (item->next))
+    item->next->prio |= GRUB_PRIO_LIST_FLAG_ACTIVE;
+  grub_list_remove (GRUB_AS_LIST_P (head), GRUB_AS_LIST (item));
+}
+
+#define GRUB_AS_PRIO_LIST(ptr) \
+  ((GRUB_FIELD_MATCH (ptr, grub_prio_list_t, next) && \
+    GRUB_FIELD_MATCH (ptr, grub_prio_list_t, name) && \
+    GRUB_FIELD_MATCH (ptr, grub_prio_list_t, prio))? \
+   (grub_prio_list_t) ptr : grub_bad_type_cast ())
+
+#define GRUB_AS_PRIO_LIST_P(pptr) \
+  ((GRUB_FIELD_MATCH (*pptr, grub_prio_list_t, next) && \
+    GRUB_FIELD_MATCH (*pptr, grub_prio_list_t, name) && \
+    GRUB_FIELD_MATCH (*pptr, grub_prio_list_t, prio))? \
+   (grub_prio_list_t *) (void *) pptr : grub_bad_type_cast ())
+
+#endif /* ! GRUB_LIST_HEADER */
diff --git a/grub-core/include/grub/loader.h b/grub-core/include/grub/loader.h
new file mode 100644 (file)
index 0000000..319f3c5
--- /dev/null
@@ -0,0 +1,66 @@
+/* loader.h - OS loaders */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_HEADER
+#define GRUB_LOADER_HEADER     1
+
+#include <grub/file.h>
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/types.h>
+
+/* Check if a loader is loaded.  */
+int grub_loader_is_loaded (void);
+
+/* Set loader functions. NORETURN must be set to true, if BOOT won't return
+   to the original state.  */
+void grub_loader_set (grub_err_t (*boot) (void),
+                     grub_err_t (*unload) (void),
+                     int noreturn);
+
+/* Unset current loader, if any.  */
+void grub_loader_unset (void);
+
+/* Call the boot hook in current loader. This may or may not return,
+   depending on the setting by grub_loader_set.  */
+grub_err_t grub_loader_boot (void);
+
+/* The space between numbers is intentional for the simplicity of adding new
+   values even if external modules use them. */
+typedef enum {
+  /* A preboot hook which can use everything and turns nothing off. */
+  GRUB_LOADER_PREBOOT_HOOK_PRIO_NORMAL = 400,
+  /* A preboot hook which can't use disks and may stop disks. */
+  GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK = 300,
+  /* A preboot hook which can't use disks or console and may stop console. */
+  GRUB_LOADER_PREBOOT_HOOK_PRIO_CONSOLE = 200,
+  /* A preboot hook which can't use disks or console, can't modify memory map
+     and may stop memory services or finalize memory map. */
+  GRUB_LOADER_PREBOOT_HOOK_PRIO_MEMORY = 100,
+} grub_loader_preboot_hook_prio_t;
+
+/* Register a preboot hook. */
+void *grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noret),
+                                        grub_err_t (*preboot_rest_func) (void),
+                                        grub_loader_preboot_hook_prio_t prio);
+
+/* Unregister given preboot hook. */
+void grub_loader_unregister_preboot_hook (void *hnd);
+
+#endif /* ! GRUB_LOADER_HEADER */
diff --git a/grub-core/include/grub/lvm.h b/grub-core/include/grub/lvm.h
new file mode 100644 (file)
index 0000000..a4bf3b2
--- /dev/null
@@ -0,0 +1,129 @@
+/* lvm.h - On disk structures for LVM. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LVM_H
+#define GRUB_LVM_H     1
+
+#include <grub/types.h>
+
+/* Length of ID string, excluding terminating zero. */
+#define GRUB_LVM_ID_STRLEN 38
+
+struct grub_lvm_vg {
+  char id[GRUB_LVM_ID_STRLEN+1];
+  char *name;
+  int extent_size;
+  struct grub_lvm_pv *pvs;
+  struct grub_lvm_lv *lvs;
+  struct grub_lvm_vg *next;
+};
+
+struct grub_lvm_pv {
+  char id[GRUB_LVM_ID_STRLEN+1];
+  char *name;
+  grub_disk_t disk;
+  int start; /* Sector number where the data area starts. */
+  struct grub_lvm_pv *next;
+};
+
+struct grub_lvm_lv {
+  char *name;
+  unsigned int number;
+  unsigned int segment_count;
+  grub_uint64_t size;
+  struct grub_lvm_segment *segments; /* Pointer to segment_count segments. */
+  struct grub_lvm_vg *vg;
+  struct grub_lvm_lv *next;
+};
+
+struct grub_lvm_segment {
+  unsigned int start_extent;
+  unsigned int extent_count;
+  unsigned int stripe_count;
+  unsigned int stripe_size;
+  struct grub_lvm_stripe *stripes; /* Pointer to stripe_count stripes. */
+};
+
+struct grub_lvm_stripe {
+  int start;
+  struct grub_lvm_pv *pv;
+};
+
+#define GRUB_LVM_LABEL_SIZE GRUB_DISK_SECTOR_SIZE
+#define GRUB_LVM_LABEL_SCAN_SECTORS 4L
+
+#define GRUB_LVM_LABEL_ID "LABELONE"
+#define GRUB_LVM_LVM2_LABEL "LVM2 001"
+
+#define GRUB_LVM_ID_LEN 32
+
+/* On disk - 32 bytes */
+struct grub_lvm_label_header {
+  grub_int8_t id[8];           /* LABELONE */
+  grub_uint64_t sector_xl;     /* Sector number of this label */
+  grub_uint32_t crc_xl;                /* From next field to end of sector */
+  grub_uint32_t offset_xl;     /* Offset from start of struct to contents */
+  grub_int8_t type[8];         /* LVM2 001 */
+} __attribute__ ((packed));
+
+/* On disk */
+struct grub_lvm_disk_locn {
+  grub_uint64_t offset;                /* Offset in bytes to start sector */
+  grub_uint64_t size;          /* Bytes */
+} __attribute__ ((packed));
+
+/* Fields with the suffix _xl should be xlate'd wherever they appear */
+/* On disk */
+struct grub_lvm_pv_header {
+  grub_int8_t pv_uuid[GRUB_LVM_ID_LEN];
+
+  /* This size can be overridden if PV belongs to a VG */
+  grub_uint64_t device_size_xl;        /* Bytes */
+
+  /* NULL-terminated list of data areas followed by */
+  /* NULL-terminated list of metadata area headers */
+  struct grub_lvm_disk_locn disk_areas_xl[0];  /* Two lists */
+} __attribute__ ((packed));
+
+#define GRUB_LVM_FMTT_MAGIC "\040\114\126\115\062\040\170\133\065\101\045\162\060\116\052\076"
+#define GRUB_LVM_FMTT_VERSION 1
+#define GRUB_LVM_MDA_HEADER_SIZE 512
+
+/* On disk */
+struct grub_lvm_raw_locn {
+  grub_uint64_t offset;                /* Offset in bytes to start sector */
+  grub_uint64_t size;          /* Bytes */
+  grub_uint32_t checksum;
+  grub_uint32_t filler;
+} __attribute__ ((packed));
+
+/* On disk */
+/* Structure size limited to one sector */
+struct grub_lvm_mda_header {
+  grub_uint32_t checksum_xl;   /* Checksum of rest of mda_header */
+  grub_int8_t magic[16];       /* To aid scans for metadata */
+  grub_uint32_t version;
+  grub_uint64_t start;         /* Absolute start byte of mda_header */
+  grub_uint64_t size;          /* Size of metadata area */
+
+  struct grub_lvm_raw_locn raw_locns[0];       /* NULL-terminated list */
+} __attribute__ ((packed));
+
+
+#endif /* ! GRUB_LVM_H */
diff --git a/grub-core/include/grub/macho.h b/grub-core/include/grub/macho.h
new file mode 100644 (file)
index 0000000..8214583
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHO_H
+#define GRUB_MACHO_H 1
+#include <grub/types.h>
+
+/* Multi-architecture header. Always in big-endian. */
+struct grub_macho_fat_header
+{
+  grub_uint32_t magic;
+  grub_uint32_t nfat_arch;
+} __attribute__ ((packed));
+#define GRUB_MACHO_FAT_MAGIC 0xcafebabe
+
+typedef grub_uint32_t grub_macho_cpu_type_t;
+typedef grub_uint32_t grub_macho_cpu_subtype_t;
+
+/* Architecture descriptor. Always in big-endian. */
+struct grub_macho_fat_arch
+{
+  grub_macho_cpu_type_t cputype;
+  grub_macho_cpu_subtype_t cpusubtype;
+  grub_uint32_t offset;
+  grub_uint32_t size;
+  grub_uint32_t align;
+} __attribute__ ((packed));
+
+/* File header for 32-bit. Always in native-endian. */
+struct grub_macho_header32
+{
+#define GRUB_MACHO_MAGIC32 0xfeedface
+  grub_uint32_t magic;
+  grub_macho_cpu_type_t cputype;
+  grub_macho_cpu_subtype_t cpusubtype;
+  grub_uint32_t filetype;
+  grub_uint32_t ncmds;
+  grub_uint32_t sizeofcmds;
+  grub_uint32_t flags;
+} __attribute__ ((packed));
+
+/* File header for 64-bit. Always in native-endian. */
+struct grub_macho_header64
+{
+#define GRUB_MACHO_MAGIC64 0xfeedfacf
+  grub_uint32_t magic;
+  grub_macho_cpu_type_t cputype;
+  grub_macho_cpu_subtype_t cpusubtype;
+  grub_uint32_t filetype;
+  grub_uint32_t ncmds;
+  grub_uint32_t sizeofcmds;
+  grub_uint32_t flags;
+  grub_uint32_t reserved;
+} __attribute__ ((packed));
+
+/* Convenience union. What do we need to load to identify the file type. */
+union grub_macho_filestart
+{
+  struct grub_macho_fat_header fat;
+  struct grub_macho_header32 thin32;
+  struct grub_macho_header64 thin64;
+} __attribute__ ((packed));
+
+/* Common header of Mach-O commands. */
+struct grub_macho_cmd
+{
+  grub_uint32_t cmd;
+  grub_uint32_t cmdsize;
+} __attribute__ ((packed));
+
+typedef grub_uint32_t grub_macho_vmprot_t;
+
+/* 32-bit segment command. */
+struct grub_macho_segment32
+{
+#define GRUB_MACHO_CMD_SEGMENT32  1
+  grub_uint32_t cmd;
+  grub_uint32_t cmdsize;
+  grub_uint8_t segname[16];
+  grub_uint32_t vmaddr;
+  grub_uint32_t vmsize;
+  grub_uint32_t fileoff;
+  grub_uint32_t filesize;
+  grub_macho_vmprot_t maxprot;
+  grub_macho_vmprot_t initprot;
+  grub_uint32_t nsects;
+  grub_uint32_t flags;
+} __attribute__ ((packed));
+
+/* 64-bit segment command. */
+struct grub_macho_segment64
+{
+#define GRUB_MACHO_CMD_SEGMENT64  0x19
+  grub_uint32_t cmd;
+  grub_uint32_t cmdsize;
+  grub_uint8_t segname[16];
+  grub_uint64_t vmaddr;
+  grub_uint64_t vmsize;
+  grub_uint64_t fileoff;
+  grub_uint64_t filesize;
+  grub_macho_vmprot_t maxprot;
+  grub_macho_vmprot_t initprot;
+  grub_uint32_t nsects;
+  grub_uint32_t flags;
+} __attribute__ ((packed));
+
+#define GRUB_MACHO_CMD_THREAD     5
+
+#endif
diff --git a/grub-core/include/grub/machoload.h b/grub-core/include/grub/machoload.h
new file mode 100644 (file)
index 0000000..8410162
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHOLOAD_HEADER
+#define GRUB_MACHOLOAD_HEADER  1
+
+#include <grub/err.h>
+#include <grub/elf.h>
+#include <grub/file.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+struct grub_macho_file
+{
+  grub_file_t file;
+  grub_ssize_t offset32;
+  grub_ssize_t end32;
+  int ncmds32;
+  grub_size_t cmdsize32;
+  grub_uint8_t *cmds32;
+  grub_ssize_t offset64;
+  grub_ssize_t end64;
+  int ncmds64;
+  grub_size_t cmdsize64;
+  grub_uint8_t *cmds64;
+};
+typedef struct grub_macho_file *grub_macho_t;
+
+grub_macho_t grub_macho_open (const char *);
+grub_macho_t grub_macho_file (grub_file_t);
+grub_err_t grub_macho_close (grub_macho_t);
+
+int grub_macho_contains_macho32 (grub_macho_t);
+grub_err_t grub_macho_size32 (grub_macho_t macho, grub_uint32_t *segments_start,
+                             grub_uint32_t *segments_end, int flags);
+grub_uint32_t grub_macho_get_entry_point32 (grub_macho_t macho);
+
+int grub_macho_contains_macho64 (grub_macho_t);
+grub_err_t grub_macho_size64 (grub_macho_t macho, grub_uint64_t *segments_start,
+                             grub_uint64_t *segments_end, int flags);
+grub_uint64_t grub_macho_get_entry_point64 (grub_macho_t macho);
+
+/* Ignore BSS segments when loading. */
+#define GRUB_MACHO_NOBSS 0x1
+grub_err_t grub_macho_load32 (grub_macho_t macho, char *offset, int flags);
+grub_err_t grub_macho_load64 (grub_macho_t macho, char *offset, int flags);
+
+/* Like filesize and file_read but take only 32-bit part
+   for current architecture. */
+grub_size_t grub_macho_filesize32 (grub_macho_t macho);
+grub_err_t grub_macho_readfile32 (grub_macho_t macho, void *dest);
+grub_size_t grub_macho_filesize64 (grub_macho_t macho);
+grub_err_t grub_macho_readfile64 (grub_macho_t macho, void *dest);
+
+void grub_macho_parse32 (grub_macho_t macho);
+void grub_macho_parse64 (grub_macho_t macho);
+
+#endif /* ! GRUB_MACHOLOAD_HEADER */
diff --git a/grub-core/include/grub/memory.h b/grub-core/include/grub/memory.h
new file mode 100644 (file)
index 0000000..43f90e1
--- /dev/null
@@ -0,0 +1,52 @@
+/* memory.h - describe the memory map */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MEMORY_HEADER
+#define GRUB_MEMORY_HEADER     1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/machine/memory.h>
+
+grub_err_t grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+                                                           grub_uint64_t,
+                                                           grub_uint32_t));
+int grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type);
+grub_err_t grub_mmap_unregister (int handle);
+
+void *grub_mmap_malign_and_register (grub_uint64_t align, grub_uint64_t size,
+                                    int *handle, int type, int flags);
+
+void grub_mmap_free_and_unregister (int handle);
+
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+
+struct grub_mmap_region
+{
+  struct grub_mmap_region *next;
+  grub_uint64_t start;
+  grub_uint64_t end;
+  int type;
+  int handle;
+};
+
+extern struct grub_mmap_region *grub_mmap_overlays;
+#endif
+
+#endif /* ! GRUB_MEMORY_HEADER */
diff --git a/grub-core/include/grub/menu.h b/grub-core/include/grub/menu.h
new file mode 100644 (file)
index 0000000..e5e5fb1
--- /dev/null
@@ -0,0 +1,99 @@
+/* menu.h - Menu model function prototypes and data structures. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MENU_HEADER
+#define GRUB_MENU_HEADER 1
+
+struct grub_menu_entry_class
+{
+  char *name;
+  struct grub_menu_entry_class *next;
+};
+
+/* The menu entry.  */
+struct grub_menu_entry
+{
+  /* The title name.  */
+  const char *title;
+
+  /* If set means not everybody is allowed to boot this entry.  */
+  int restricted;
+
+  /* Allowed users.  */
+  const char *users;
+
+  /* The classes associated with the menu entry:
+     used to choose an icon or other style attributes.
+     This is a dummy head node for the linked list, so for an entry E,
+     E.classes->next is the first class if it is not NULL.  */
+  struct grub_menu_entry_class *classes;
+
+  /* The sourcecode of the menu entry, used by the editor.  */
+  const char *sourcecode;
+
+  int hotkey;
+
+  /* The next element.  */
+  struct grub_menu_entry *next;
+};
+typedef struct grub_menu_entry *grub_menu_entry_t;
+
+/* The menu.  */
+struct grub_menu
+{
+  /* The size of a menu.  */
+  int size;
+
+  /* The list of menu entries.  */
+  grub_menu_entry_t entry_list;
+};
+typedef struct grub_menu *grub_menu_t;
+
+/* Callback structure menu viewers can use to provide user feedback when
+   default entries are executed, possibly including fallback entries.  */
+typedef struct grub_menu_execute_callback
+{
+  /* Called immediately before ENTRY is booted.  */
+  void (*notify_booting) (grub_menu_entry_t entry, void *userdata);
+
+  /* Called when executing one entry has failed, and another entry, ENTRY, will
+     be executed as a fallback.  The implementation of this function should
+     delay for a period of at least 2 seconds before returning in order to
+     allow the user time to read the information before it can be lost by
+     executing ENTRY.  */
+  void (*notify_fallback) (grub_menu_entry_t entry, void *userdata);
+
+  /* Called when an entry has failed to execute and there is no remaining
+     fallback entry to attempt.  */
+  void (*notify_failure) (void *userdata);
+}
+*grub_menu_execute_callback_t;
+
+grub_menu_entry_t grub_menu_get_entry (grub_menu_t menu, int no);
+int grub_menu_get_timeout (void);
+void grub_menu_set_timeout (int timeout);
+void grub_menu_execute_entry (grub_menu_entry_t entry);
+void grub_menu_execute_with_fallback (grub_menu_t menu,
+                                     grub_menu_entry_t entry,
+                                     grub_menu_execute_callback_t callback,
+                                     void *callback_data);
+void grub_menu_entry_run (grub_menu_entry_t entry);
+int grub_menu_get_default_entry_index (grub_menu_t menu);
+
+#endif /* GRUB_MENU_HEADER */
diff --git a/grub-core/include/grub/menu_viewer.h b/grub-core/include/grub/menu_viewer.h
new file mode 100644 (file)
index 0000000..c6513c4
--- /dev/null
@@ -0,0 +1,48 @@
+/* menu_viewer.h - Interface to menu viewer implementations. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MENU_VIEWER_HEADER
+#define GRUB_MENU_VIEWER_HEADER 1
+
+#include <grub/err.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/menu.h>
+#include <grub/term.h>
+
+struct grub_menu_viewer
+{
+  struct grub_menu_viewer *next;
+  void *data;
+  void (*set_chosen_entry) (int entry, void *data);
+  void (*print_timeout) (int timeout, void *data);
+  void (*clear_timeout) (void *data);
+  void (*fini) (void *fini);
+};
+
+void grub_menu_register_viewer (struct grub_menu_viewer *viewer);
+
+grub_err_t
+grub_menu_try_text (struct grub_term_output *term, 
+                   int entry, grub_menu_t menu, int nested);
+
+extern grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu,
+                                           int nested);
+
+#endif /* GRUB_MENU_VIEWER_HEADER */
diff --git a/grub-core/include/grub/mips/at_keyboard.h b/grub-core/include/grub/mips/at_keyboard.h
new file mode 100644 (file)
index 0000000..0c30753
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/machine/at_keyboard.h>
diff --git a/grub-core/include/grub/mips/cache.h b/grub-core/include/grub/mips/cache.h
new file mode 100644 (file)
index 0000000..c347057
--- /dev/null
@@ -0,0 +1,27 @@
+/* cache.h - Flush the processor's cache.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CPU_CACHE_H
+#define GRUB_CPU_CACHE_H       1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+void EXPORT_FUNC(grub_cpu_flush_cache) (void *start, grub_size_t size, int type);
+#endif 
diff --git a/grub-core/include/grub/mips/cmos.h b/grub-core/include/grub/mips/cmos.h
new file mode 100644 (file)
index 0000000..79a7a4c
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/machine/cmos.h>
diff --git a/grub-core/include/grub/mips/io.h b/grub-core/include/grub/mips/io.h
new file mode 100644 (file)
index 0000000..dee76bd
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef        GRUB_IO_H
+#define        GRUB_IO_H       1
+
+#include <grub/types.h>
+
+typedef grub_addr_t grub_port_t;
+
+static __inline unsigned char
+grub_inb (grub_port_t port)
+{
+  return *(volatile grub_uint8_t *) port;
+}
+
+static __inline unsigned short int
+grub_inw (grub_port_t port)
+{
+  return *(volatile grub_uint16_t *) port;
+}
+
+static __inline unsigned int
+grub_inl (grub_port_t port)
+{
+  return *(volatile grub_uint32_t *) port;
+}
+
+static __inline void
+grub_outb (unsigned char value, grub_port_t port)
+{
+  *(volatile grub_uint8_t *) port = value;
+}
+
+static __inline void
+grub_outw (unsigned short int value, grub_port_t port)
+{
+  *(volatile grub_uint16_t *) port = value;
+}
+
+static __inline void
+grub_outl (unsigned int value, grub_port_t port)
+{
+  *(volatile grub_uint32_t *) port = value;
+}
+
+#endif /* _SYS_IO_H */
diff --git a/grub-core/include/grub/mips/kernel.h b/grub-core/include/grub/mips/kernel.h
new file mode 100644 (file)
index 0000000..8b68f7b
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_CPU_HEADER
+#define GRUB_KERNEL_CPU_HEADER 1
+
+#define GRUB_MOD_ALIGN 0x1
+/* Non-zero value is only needed for PowerMacs.  */
+#define GRUB_MOD_GAP   0x0
+
+#define GRUB_KERNEL_MACHINE_LINK_ALIGN  32
+
+#define GRUB_KERNEL_CPU_RAW_SIZE        0x200
+#define GRUB_KERNEL_CPU_COMPRESSED_SIZE        0x8
+#define GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE      0xc
+#define GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE      0x10
+
+#define GRUB_KERNEL_CPU_PREFIX         GRUB_KERNEL_CPU_RAW_SIZE
+#define GRUB_KERNEL_CPU_DATA_END       GRUB_KERNEL_CPU_RAW_SIZE + 0x48
+
+#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_KERNEL_CPU_RAW_SIZE
+
+#define GRUB_KERNEL_MACHINE_PREFIX     GRUB_KERNEL_CPU_PREFIX
+#define GRUB_KERNEL_MACHINE_DATA_END   GRUB_KERNEL_CPU_DATA_END
+#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE
+#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE
+#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_KERNEL_CPU_COMPRESSED_SIZE
+
+#define GRUB_PLATFORM_IMAGE_FORMATS     "raw, elf"
+#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT     "raw"
+
+#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW
+
+#ifndef ASM_FILE
+
+typedef enum {
+  GRUB_PLATFORM_IMAGE_RAW,
+  GRUB_PLATFORM_IMAGE_ELF
+}
+  grub_platform_image_format_t;
+#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW
+#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF
+
+/* The prefix which points to the directory where GRUB modules and its
+   configuration file are located.  */
+extern char grub_prefix[];
+
+#endif
+
+#endif
diff --git a/grub-core/include/grub/mips/multiboot.h b/grub-core/include/grub/mips/multiboot.h
new file mode 100644 (file)
index 0000000..a27229e
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MULTIBOOT_CPU_HEADER
+#define GRUB_MULTIBOOT_CPU_HEADER      1
+
+extern grub_uint32_t grub_multiboot_payload_eip;
+extern char *grub_multiboot_payload_orig;
+extern grub_addr_t grub_multiboot_payload_dest;
+extern grub_size_t grub_multiboot_payload_size;
+
+#define MULTIBOOT_INITIAL_STATE  { .gpr[4] = MULTIBOOT_BOOTLOADER_MAGIC, \
+    .jumpreg = 1 }
+#define MULTIBOOT_ENTRY_REGISTER gpr[1]
+#define MULTIBOOT_MBI_REGISTER gpr[5]
+#define MULTIBOOT_ARCHITECTURE_CURRENT MULTIBOOT_ARCHITECTURE_MIPS32
+
+#define MULTIBOOT_ELF32_MACHINE EM_MIPS
+#define MULTIBOOT_ELF64_MACHINE EM_MIPS
+
+#endif /* ! GRUB_MULTIBOOT_CPU_HEADER */
diff --git a/grub-core/include/grub/mips/pci.h b/grub-core/include/grub/mips/pci.h
new file mode 100644 (file)
index 0000000..8b49d84
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/machine/pci.h>
diff --git a/grub-core/include/grub/mips/qemu-mips/boot.h b/grub-core/include/grub/mips/qemu-mips/boot.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/grub-core/include/grub/mips/qemu-mips/kernel.h b/grub-core/include/grub/mips/qemu-mips/kernel.h
new file mode 100644 (file)
index 0000000..dbf74c1
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_MACHINE_HEADER
+#define GRUB_KERNEL_MACHINE_HEADER     1
+
+#include <grub/symbol.h>
+#include <grub/cpu/kernel.h>
+
+#ifndef ASM_FILE
+
+void EXPORT_FUNC (grub_reboot) (void);
+void EXPORT_FUNC (grub_halt) (void);
+
+/* The prefix which points to the directory where GRUB modules and its
+   configuration file are located.  */
+extern char grub_prefix[];
+
+#endif
+
+#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/grub-core/include/grub/mips/qemu-mips/loader.h b/grub-core/include/grub/mips/qemu-mips/loader.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/grub-core/include/grub/mips/qemu-mips/memory.h b/grub-core/include/grub/mips/qemu-mips/memory.h
new file mode 100644 (file)
index 0000000..87e6867
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MEMORY_MACHINE_HEADER
+#define GRUB_MEMORY_MACHINE_HEADER     1
+
+#ifndef ASM_FILE
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#endif
+
+#define GRUB_MACHINE_MEMORY_STACK_HIGH       0x80f00000
+#define GRUB_MACHINE_MEMORY_USABLE       0x81000000
+
+#define GRUB_MACHINE_MEMORY_AVAILABLE        1
+
+#ifndef ASM_FILE
+grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate)
+(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
+grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
+     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
+
+static inline grub_err_t
+grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
+                           grub_uint64_t size __attribute__ ((unused)),
+                           int type __attribute__ ((unused)),
+                           int handle __attribute__ ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
+static inline grub_err_t
+grub_machine_mmap_unregister (int handle  __attribute__ ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
+#endif
+
+#endif
diff --git a/grub-core/include/grub/mips/qemu-mips/serial.h b/grub-core/include/grub/mips/qemu-mips/serial.h
new file mode 100644 (file)
index 0000000..1f8ce08
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_SERIAL_HEADER
+#define GRUB_MACHINE_SERIAL_HEADER     1
+
+#define GRUB_MACHINE_SERIAL_PORTS { 0x140003f8 }
+
+#endif 
diff --git a/grub-core/include/grub/mips/qemu-mips/time.h b/grub-core/include/grub/mips/qemu-mips/time.h
new file mode 100644 (file)
index 0000000..a73f64d
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_MACHINE_TIME_HEADER
+#define KERNEL_MACHINE_TIME_HEADER     1
+
+#include <grub/symbol.h>
+
+#define GRUB_TICKS_PER_SECOND  1000
+
+/* Return the real time in ticks.  */
+grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
+
+static inline void
+grub_cpu_idle(void)
+{
+}
+
+#endif /* ! KERNEL_MACHINE_TIME_HEADER */
diff --git a/grub-core/include/grub/mips/relocator.h b/grub-core/include/grub/mips/relocator.h
new file mode 100644 (file)
index 0000000..838ef83
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_RELOCATOR_CPU_HEADER
+#define GRUB_RELOCATOR_CPU_HEADER      1
+
+#include <grub/types.h>
+#include <grub/err.h>
+
+struct grub_relocator32_state
+{
+  /* gpr[0] is ignored since it's hardwired to 0.  */
+  grub_uint32_t gpr[32];
+  /* Register holding target $pc.  */
+  int jumpreg;
+};
+
+void *grub_relocator32_alloc (grub_size_t size);
+grub_err_t grub_relocator32_boot (void *relocator, grub_uint32_t dest,
+                                 struct grub_relocator32_state state);
+void *grub_relocator32_realloc (void *relocator, grub_size_t size);
+void grub_relocator32_free (void *relocator);
+
+#endif /* ! GRUB_RELOCATOR_CPU_HEADER */
diff --git a/grub-core/include/grub/mips/setjmp.h b/grub-core/include/grub/mips/setjmp.h
new file mode 100644 (file)
index 0000000..5e59855
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SETJMP_CPU_HEADER
+#define GRUB_SETJMP_CPU_HEADER 1
+
+typedef unsigned long grub_jmp_buf[11];
+
+int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice));
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
+
+#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/grub-core/include/grub/mips/time.h b/grub-core/include/grub/mips/time.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/grub-core/include/grub/mips/types.h b/grub-core/include/grub/mips/types.h
new file mode 100644 (file)
index 0000000..fe09afa
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER  1
+
+/* The size of void *.  */
+#define GRUB_TARGET_SIZEOF_VOID_P      4
+
+/* The size of long.  */
+#define GRUB_TARGET_SIZEOF_LONG                4
+
+#ifdef GRUB_CPU_MIPSEL
+/* mipsEL is little-endian.  */
+#undef GRUB_TARGET_WORDS_BIGENDIAN
+#elif defined (GRUB_CPU_MIPS)
+/* mips is big-endian.  */
+#define GRUB_TARGET_WORDS_BIGENDIAN
+#elif !defined (GRUB_SYMBOL_GENERATOR)
+#error Neither GRUB_CPU_MIPS nor GRUB_CPU_MIPSEL is defined
+#endif
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/grub-core/include/grub/mips/yeeloong/at_keyboard.h b/grub-core/include/grub/mips/yeeloong/at_keyboard.h
new file mode 100644 (file)
index 0000000..f279ac8
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_AT_KEYBOARD_HEADER
+#define GRUB_MACHINE_AT_KEYBOARD_HEADER        1
+
+#define KEYBOARD_REG_DATA      0xbfd00060
+#define KEYBOARD_REG_STATUS    0xbfd00064
+
+#endif
diff --git a/grub-core/include/grub/mips/yeeloong/boot.h b/grub-core/include/grub/mips/yeeloong/boot.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/grub-core/include/grub/mips/yeeloong/cmos.h b/grub-core/include/grub/mips/yeeloong/cmos.h
new file mode 100644 (file)
index 0000000..f2a32d7
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef        GRUB_CPU_CMOS_H
+#define        GRUB_CPU_CMOS_H 1
+
+#include <grub/types.h>
+#include <grub/cpu/io.h>
+
+#define GRUB_CMOS_ADDR_REG     0xbfd00070
+#define GRUB_CMOS_DATA_REG     0xbfd00071
+
+#endif /* GRUB_CPU_CMOS_H */
diff --git a/grub-core/include/grub/mips/yeeloong/kernel.h b/grub-core/include/grub/mips/yeeloong/kernel.h
new file mode 100644 (file)
index 0000000..230455d
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_MACHINE_HEADER
+#define GRUB_KERNEL_MACHINE_HEADER     1
+
+#include <grub/symbol.h>
+#include <grub/cpu/kernel.h>
+
+#ifndef ASM_FILE
+
+void EXPORT_FUNC (grub_reboot) (void);
+void EXPORT_FUNC (grub_halt) (void);
+
+#endif
+
+#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/grub-core/include/grub/mips/yeeloong/loader.h b/grub-core/include/grub/mips/yeeloong/loader.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/grub-core/include/grub/mips/yeeloong/memory.h b/grub-core/include/grub/mips/yeeloong/memory.h
new file mode 100644 (file)
index 0000000..922db24
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MEMORY_MACHINE_HEADER
+#define GRUB_MEMORY_MACHINE_HEADER     1
+
+#ifndef ASM_FILE
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#endif
+
+#define GRUB_MACHINE_MEMORY_STACK_HIGH       0x801ffff0
+#define GRUB_ARCH_LOWMEMVSTART 0x80000000
+#define GRUB_ARCH_LOWMEMPSTART 0x00000000
+#define GRUB_ARCH_LOWMEMMAXSIZE 0x10000000
+#define GRUB_ARCH_HIGHMEMPSTART 0x10000000
+
+
+#define GRUB_MACHINE_MEMORY_AVAILABLE        1
+#define GRUB_MACHINE_MEMORY_MAX_TYPE         1
+  /* This one is special: it's used internally but is never reported
+     by firmware. */
+#define GRUB_MACHINE_MEMORY_HOLE       2
+#define GRUB_MACHINE_MEMORY_RESERVED GRUB_MACHINE_MEMORY_HOLE
+
+#ifndef ASM_FILE
+grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate)
+(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
+
+static inline grub_err_t
+grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
+                           grub_uint64_t size __attribute__ ((unused)),
+                           int type __attribute__ ((unused)),
+                           int handle __attribute__ ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
+static inline grub_err_t
+grub_machine_mmap_unregister (int handle  __attribute__ ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
+
+grub_uint64_t grub_mmap_get_lower (void);
+grub_uint64_t grub_mmap_get_upper (void);
+
+extern grub_uint32_t EXPORT_VAR (grub_arch_memsize);
+extern grub_uint32_t EXPORT_VAR (grub_arch_highmemsize);
+
+#endif
+
+#endif
diff --git a/grub-core/include/grub/mips/yeeloong/pci.h b/grub-core/include/grub/mips/yeeloong/pci.h
new file mode 100644 (file)
index 0000000..c7bd31d
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef        GRUB_MACHINE_PCI_H
+#define        GRUB_MACHINE_PCI_H      1
+
+#include <grub/types.h>
+#include <grub/cpu/io.h>
+
+#define GRUB_PCI_NUM_BUS        1
+#define GRUB_PCI_NUM_DEVICES    16
+
+#define GRUB_MACHINE_PCI_IO_BASE          0xbfd00000
+#define GRUB_MACHINE_PCI_CONFSPACE        0xbfe80000
+#define GRUB_MACHINE_PCI_CONF_CTRL_REG    (*(volatile grub_uint32_t *) 0xbfe00118)
+#define GRUB_MACHINE_PCI_IO_CTRL_REG      (*(volatile grub_uint32_t *) 0xbfe00110)
+#define GRUB_MACHINE_PCI_WIN_MASK_SIZE    6
+#define GRUB_MACHINE_PCI_WIN_MASK         ((1 << GRUB_MACHINE_PCI_WIN_MASK_SIZE) - 1)
+
+/* We have 3 PCI windows.  */
+#define GRUB_MACHINE_PCI_NUM_WIN          3
+/* Each window is 64MiB.  */
+#define GRUB_MACHINE_PCI_WIN_SHIFT        26
+#define GRUB_MACHINE_PCI_WIN_OFFSET_MASK  ((1 << GRUB_MACHINE_PCI_WIN_SHIFT) - 1)
+
+#define GRUB_MACHINE_PCI_WIN_SIZE         0x04000000
+/* Graphical acceleration takes 1 MiB away.  */
+#define GRUB_MACHINE_PCI_WIN1_SIZE        0x03f00000
+
+#define GRUB_MACHINE_PCI_WIN1_ADDR        0xb0000000
+#define GRUB_MACHINE_PCI_WIN2_ADDR        0xb4000000
+#define GRUB_MACHINE_PCI_WIN3_ADDR        0xb8000000
+
+static inline grub_uint32_t
+grub_pci_read (grub_pci_address_t addr)
+{
+  GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
+  return *(volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONFSPACE
+                                     | (addr & 0x03ff));
+}
+
+static inline grub_uint16_t
+grub_pci_read_word (grub_pci_address_t addr)
+{
+  GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
+  return *(volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONFSPACE
+                                     | (addr & 0x03ff));
+}
+
+static inline grub_uint8_t
+grub_pci_read_byte (grub_pci_address_t addr)
+{
+  GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
+  return *(volatile grub_uint8_t *) (GRUB_MACHINE_PCI_CONFSPACE
+                                    | (addr & 0x03ff));
+}
+
+static inline void
+grub_pci_write (grub_pci_address_t addr, grub_uint32_t data)
+{
+  GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
+  *(volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONFSPACE
+                              | (addr & 0x03ff)) = data;
+}
+
+static inline void
+grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data)
+{
+  GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
+  *(volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONFSPACE
+                              | (addr & 0x03ff)) = data;
+}
+
+static inline void
+grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data)
+{
+  GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
+  *(volatile grub_uint8_t *) (GRUB_MACHINE_PCI_CONFSPACE
+                             | (addr & 0x03ff)) = data;
+}
+
+volatile void *
+grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)),
+                          grub_addr_t base, grub_size_t size);
+void
+grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)),
+                            volatile void *mem,
+                            grub_size_t size __attribute__ ((unused)));
+
+#endif /* GRUB_MACHINE_PCI_H */
diff --git a/grub-core/include/grub/mips/yeeloong/serial.h b/grub-core/include/grub/mips/yeeloong/serial.h
new file mode 100644 (file)
index 0000000..9390ea1
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_SERIAL_HEADER
+#define GRUB_MACHINE_SERIAL_HEADER     1
+
+#define GRUB_MACHINE_SERIAL_PORTS { 0xbff003f8 }
+
+#endif 
diff --git a/grub-core/include/grub/mips/yeeloong/time.h b/grub-core/include/grub/mips/yeeloong/time.h
new file mode 100644 (file)
index 0000000..7f468bf
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_MACHINE_TIME_HEADER
+#define KERNEL_MACHINE_TIME_HEADER     1
+
+#include <grub/symbol.h>
+
+#define GRUB_TICKS_PER_SECOND  (grub_arch_cpuclock / 2)
+
+/* Return the real time in ticks.  */
+grub_uint64_t EXPORT_FUNC (grub_get_rtc) (void);
+
+extern grub_uint32_t EXPORT_VAR (grub_arch_busclock);
+extern grub_uint32_t EXPORT_VAR (grub_arch_cpuclock);
+
+static inline void
+grub_cpu_idle(void)
+{
+}
+
+#endif /* ! KERNEL_MACHINE_TIME_HEADER */
diff --git a/grub-core/include/grub/misc.h b/grub-core/include/grub/misc.h
new file mode 100644 (file)
index 0000000..9bfc697
--- /dev/null
@@ -0,0 +1,311 @@
+/* misc.h - prototypes for misc functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MISC_HEADER
+#define GRUB_MISC_HEADER       1
+
+#include <stdarg.h>
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/err.h>
+
+/* GCC version checking borrowed from glibc. */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+#  define GNUC_PREREQ(maj,min) \
+       ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+#  define GNUC_PREREQ(maj,min) 0
+#endif
+
+/* Does this compiler support compile-time error attributes? */
+#if GNUC_PREREQ(4,3)
+#  define ATTRIBUTE_ERROR(msg) \
+       __attribute__ ((__error__ (msg)))
+#else
+#  define ATTRIBUTE_ERROR(msg)
+#endif
+
+#define ALIGN_UP(addr, align) \
+       ((addr + (typeof (addr)) align - 1) & ~((typeof (addr)) align - 1))
+#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))
+#define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; }
+
+#define grub_dprintf(condition, fmt, args...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, fmt, ## args)
+/* XXX: If grub_memmove is too slow, we must implement grub_memcpy.  */
+#define grub_memcpy(d,s,n)     grub_memmove ((d), (s), (n))
+
+void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n);
+char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src);
+char *EXPORT_FUNC(grub_strncpy) (char *dest, const char *src, int c);
+char *EXPORT_FUNC(grub_stpcpy) (char *dest, const char *src);
+
+static inline char *
+grub_strcat (char *dest, const char *src)
+{
+  char *p = dest;
+
+  while (*p)
+    p++;
+
+  while ((*p = *src) != '\0')
+    {
+      p++;
+      src++;
+    }
+
+  return dest;
+}
+
+static inline char *
+grub_strncat (char *dest, const char *src, int c)
+{
+  char *p = dest;
+
+  while (*p)
+    p++;
+
+  while ((*p = *src) != '\0' && c--)
+    {
+      p++;
+      src++;
+    }
+
+  *p = '\0';
+
+  return dest;
+}
+
+/* Prototypes for aliases.  */
+#ifndef GRUB_UTIL
+int EXPORT_FUNC(memcmp) (const void *s1, const void *s2, grub_size_t n);
+void *EXPORT_FUNC(memmove) (void *dest, const void *src, grub_size_t n);
+void *EXPORT_FUNC(memcpy) (void *dest, const void *src, grub_size_t n);
+void *EXPORT_FUNC(memset) (void *s, int c, grub_size_t n);
+#endif
+
+int EXPORT_FUNC(grub_memcmp) (const void *s1, const void *s2, grub_size_t n);
+int EXPORT_FUNC(grub_strcmp) (const char *s1, const char *s2);
+int EXPORT_FUNC(grub_strncmp) (const char *s1, const char *s2, grub_size_t n);
+
+char *EXPORT_FUNC(grub_strchr) (const char *s, int c);
+char *EXPORT_FUNC(grub_strrchr) (const char *s, int c);
+int EXPORT_FUNC(grub_strword) (const char *s, const char *w);
+char *EXPORT_FUNC(grub_strstr) (const char *haystack, const char *needle);
+int EXPORT_FUNC(grub_isspace) (int c);
+int EXPORT_FUNC(grub_isprint) (int c);
+
+static inline int
+grub_iscntrl (int c)
+{
+  return (c >= 0x00 && c <= 0x1F) || c == 0x7F;
+}
+
+static inline int
+grub_isalpha (int c)
+{
+  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+}
+
+static inline int
+grub_isgraph (int c)
+{
+  return (c >= '!' && c <= '~');
+}
+
+static inline int
+grub_isdigit (int c)
+{
+  return (c >= '0' && c <= '9');
+}
+
+static inline int
+grub_isalnum (int c)
+{
+  return grub_isalpha (c) || grub_isdigit (c);
+}
+
+static inline int
+grub_tolower (int c)
+{
+  if (c >= 'A' && c <= 'Z')
+    return c - 'A' + 'a';
+
+  return c;
+}
+
+static inline int
+grub_toupper (int c)
+{
+  if (c >= 'a' && c <= 'z')
+    return c - 'a' + 'A';
+
+  return c;
+}
+
+static inline int
+grub_strcasecmp (const char *s1, const char *s2)
+{
+  while (*s1 && *s2)
+    {
+      if (grub_tolower (*s1) != grub_tolower (*s2))
+       break;
+
+      s1++;
+      s2++;
+    }
+
+  return (int) grub_tolower (*s1) - (int) grub_tolower (*s2);
+}
+
+static inline int
+grub_strncasecmp (const char *s1, const char *s2, grub_size_t n)
+{
+  if (n == 0)
+    return 0;
+
+  while (*s1 && *s2 && --n)
+    {
+      if (grub_tolower (*s1) != grub_tolower (*s2))
+       break;
+
+      s1++;
+      s2++;
+    }
+
+  return (int) grub_tolower (*s1) - (int) grub_tolower (*s2);
+}
+
+
+unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base);
+unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base);
+
+static inline long
+grub_strtol (const char *str, char **end, int base)
+{
+  int negative = 0;
+  unsigned long magnitude;
+
+  while (*str && grub_isspace (*str))
+    str++;
+
+  if (*str == '-')
+    {
+      negative = 1;
+      str++;
+    }
+
+  magnitude = grub_strtoull (str, end, base);
+  if (negative)
+    {
+      if (magnitude > (unsigned long) GRUB_LONG_MAX + 1)
+        {
+          grub_error (GRUB_ERR_OUT_OF_RANGE, "negative overflow");
+          return GRUB_LONG_MIN;
+        }
+      return -((long) magnitude);
+    }
+  else
+    {
+      if (magnitude > GRUB_LONG_MAX)
+        {
+          grub_error (GRUB_ERR_OUT_OF_RANGE, "positive overflow");
+          return GRUB_LONG_MAX;
+        }
+      return (long) magnitude;
+    }
+}
+
+char *EXPORT_FUNC(grub_strdup) (const char *s);
+char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n);
+void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n);
+grub_size_t EXPORT_FUNC(grub_strlen) (const char *s);
+int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
+int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
+int EXPORT_FUNC(grub_puts) (const char *s);
+int EXPORT_FUNC(grub_puts_) (const char *s);
+void EXPORT_FUNC(grub_real_dprintf) (const char *file,
+                                     const int line,
+                                     const char *condition,
+                                     const char *fmt, ...) __attribute__ ((format (printf, 4, 5)));
+int EXPORT_FUNC(grub_vprintf) (const char *fmt, va_list args);
+int EXPORT_FUNC(grub_snprintf) (char *str, grub_size_t n, const char *fmt, ...)
+     __attribute__ ((format (printf, 3, 4)));
+int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt,
+                                va_list args);
+char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...)
+     __attribute__ ((format (printf, 1, 2)));
+char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args);
+void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn));
+void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn));
+grub_size_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest,
+                                           grub_size_t destsize,
+                                           const grub_uint8_t *src,
+                                           grub_size_t srcsize,
+                                           const grub_uint8_t **srcend);
+grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
+                                         grub_uint32_t d, grub_uint32_t *r);
+
+#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL)
+void EXPORT_FUNC(__enable_execute_stack) (void *addr);
+#endif
+
+#if defined (NEED_REGISTER_FRAME_INFO) && !defined(GRUB_UTIL)
+void EXPORT_FUNC (__register_frame_info) (void);
+void EXPORT_FUNC (__deregister_frame_info) (void);
+#endif
+
+/* Inline functions.  */
+
+static inline unsigned int
+grub_abs (int x)
+{
+  if (x < 0)
+    return (unsigned int) (-x);
+  else
+    return (unsigned int) x;
+}
+
+static inline long
+grub_max (long x, long y)
+{
+  if (x > y)
+    return x;
+  else
+    return y;
+}
+
+/* Rounded-up division */
+static inline unsigned int
+grub_div_roundup (unsigned int x, unsigned int y)
+{
+  return (x + y - 1) / y;
+}
+
+/* Reboot the machine.  */
+void EXPORT_FUNC (grub_reboot) (void);
+
+#ifdef GRUB_MACHINE_PCBIOS
+/* Halt the system, using APM if possible. If NO_APM is true, don't
+ * use APM even if it is available.  */
+void EXPORT_FUNC (grub_halt) (int no_apm);
+#else
+void EXPORT_FUNC (grub_halt) (void);
+#endif
+
+#endif /* ! GRUB_MISC_HEADER */
diff --git a/grub-core/include/grub/mm.h b/grub-core/include/grub/mm.h
new file mode 100644 (file)
index 0000000..38dd396
--- /dev/null
@@ -0,0 +1,72 @@
+/* mm.h - prototypes and declarations for memory manager */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MM_H
+#define GRUB_MM_H      1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <config.h>
+
+#ifndef NULL
+# define NULL  ((void *) 0)
+#endif
+
+void grub_mm_init_region (void *addr, grub_size_t size);
+void *EXPORT_FUNC(grub_malloc) (grub_size_t size);
+void *EXPORT_FUNC(grub_zalloc) (grub_size_t size);
+void EXPORT_FUNC(grub_free) (void *ptr);
+void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size);
+void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size);
+
+/* For debugging.  */
+#if defined(MM_DEBUG) && !defined(GRUB_UTIL) && !defined (GRUB_MACHINE_EMU)
+/* Set this variable to 1 when you want to trace all memory function calls.  */
+extern int EXPORT_VAR(grub_mm_debug);
+
+void grub_mm_dump_free (void);
+void grub_mm_dump (unsigned lineno);
+
+#define grub_malloc(size)      \
+  grub_debug_malloc (GRUB_FILE, __LINE__, size)
+
+#define grub_zalloc(size)      \
+  grub_debug_zalloc (GRUB_FILE, __LINE__, size)
+
+#define grub_realloc(ptr,size) \
+  grub_debug_realloc (GRUB_FILE, __LINE__, ptr, size)
+
+#define grub_memalign(align,size)      \
+  grub_debug_memalign (GRUB_FILE, __LINE__, align, size)
+
+#define grub_free(ptr) \
+  grub_debug_free (GRUB_FILE, __LINE__, ptr)
+
+void *EXPORT_FUNC(grub_debug_malloc) (const char *file, int line,
+                                     grub_size_t size);
+void *EXPORT_FUNC(grub_debug_zalloc) (const char *file, int line,
+                                      grub_size_t size);
+void EXPORT_FUNC(grub_debug_free) (const char *file, int line, void *ptr);
+void *EXPORT_FUNC(grub_debug_realloc) (const char *file, int line, void *ptr,
+                                      grub_size_t size);
+void *EXPORT_FUNC(grub_debug_memalign) (const char *file, int line,
+                                       grub_size_t align, grub_size_t size);
+#endif /* MM_DEBUG && ! GRUB_UTIL */
+
+#endif /* ! GRUB_MM_H */
diff --git a/grub-core/include/grub/msdos_partition.h b/grub-core/include/grub/msdos_partition.h
new file mode 100644 (file)
index 0000000..650d784
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_PC_PARTITION_HEADER
+#define GRUB_PC_PARTITION_HEADER       1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/err.h>
+
+/* The signature.  */
+#define GRUB_PC_PARTITION_SIGNATURE            0xaa55
+
+/* This is not a flag actually, but used as if it were a flag.  */
+#define GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG     0x10
+
+/* DOS partition types.  */
+#define GRUB_PC_PARTITION_TYPE_NONE            0
+#define GRUB_PC_PARTITION_TYPE_FAT12           1
+#define GRUB_PC_PARTITION_TYPE_FAT16_LT32M     4
+#define GRUB_PC_PARTITION_TYPE_EXTENDED                5
+#define GRUB_PC_PARTITION_TYPE_FAT16_GT32M     6
+#define GRUB_PC_PARTITION_TYPE_NTFS            7
+#define GRUB_PC_PARTITION_TYPE_FAT32           0xb
+#define GRUB_PC_PARTITION_TYPE_FAT32_LBA       0xc
+#define GRUB_PC_PARTITION_TYPE_FAT16_LBA       0xe
+#define GRUB_PC_PARTITION_TYPE_WIN95_EXTENDED  0xf
+#define GRUB_PC_PARTITION_TYPE_EZD             0x55
+#define GRUB_PC_PARTITION_TYPE_MINIX           0x80
+#define GRUB_PC_PARTITION_TYPE_LINUX_MINIX     0x81
+#define GRUB_PC_PARTITION_TYPE_EXT2FS          0x83
+#define GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED  0x85
+#define GRUB_PC_PARTITION_TYPE_VSTAFS          0x9e
+#define GRUB_PC_PARTITION_TYPE_FREEBSD         0xa5
+#define GRUB_PC_PARTITION_TYPE_OPENBSD         0xa6
+#define GRUB_PC_PARTITION_TYPE_NETBSD          0xa9
+#define GRUB_PC_PARTITION_TYPE_HFS             0xaf
+#define GRUB_PC_PARTITION_TYPE_GPT_DISK                0xee
+#define GRUB_PC_PARTITION_TYPE_LINUX_RAID      0xfd
+
+/* The partition entry.  */
+struct grub_msdos_partition_entry
+{
+  /* If active, 0x80, otherwise, 0x00.  */
+  grub_uint8_t flag;
+
+  /* The head of the start.  */
+  grub_uint8_t start_head;
+
+  /* (S | ((C >> 2) & 0xC0)) where S is the sector of the start and C
+     is the cylinder of the start. Note that S is counted from one.  */
+  grub_uint8_t start_sector;
+
+  /* (C & 0xFF) where C is the cylinder of the start.  */
+  grub_uint8_t start_cylinder;
+
+  /* The partition type.  */
+  grub_uint8_t type;
+
+  /* The end versions of start_head, start_sector and start_cylinder,
+     respectively.  */
+  grub_uint8_t end_head;
+  grub_uint8_t end_sector;
+  grub_uint8_t end_cylinder;
+
+  /* The start sector. Note that this is counted from zero.  */
+  grub_uint32_t start;
+
+  /* The length in sector units.  */
+  grub_uint32_t length;
+} __attribute__ ((packed));
+
+/* The structure of MBR.  */
+struct grub_msdos_partition_mbr
+{
+  /* The code area (actually, including BPB).  */
+  grub_uint8_t code[446];
+
+  /* Four partition entries.  */
+  struct grub_msdos_partition_entry entries[4];
+
+  /* The signature 0xaa55.  */
+  grub_uint16_t signature;
+} __attribute__ ((packed));
+
+\f
+
+static inline int
+grub_msdos_partition_is_empty (int type)
+{
+  return (type == GRUB_PC_PARTITION_TYPE_NONE);
+}
+
+static inline int
+grub_msdos_partition_is_extended (int type)
+{
+  return (type == GRUB_PC_PARTITION_TYPE_EXTENDED
+         || type == GRUB_PC_PARTITION_TYPE_WIN95_EXTENDED
+         || type == GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED);
+}
+
+#endif /* ! GRUB_PC_PARTITION_HEADER */
diff --git a/grub-core/include/grub/multiboot.h b/grub-core/include/grub/multiboot.h
new file mode 100644 (file)
index 0000000..63947d1
--- /dev/null
@@ -0,0 +1,74 @@
+/* multiboot.h - multiboot header file with grub definitions. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2007,2008,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MULTIBOOT_HEADER
+#define GRUB_MULTIBOOT_HEADER 1
+
+#include <grub/file.h>
+
+#ifdef GRUB_USE_MULTIBOOT2
+#include <multiboot2.h>
+/* Same thing as far as our loader is concerned.  */
+#define MULTIBOOT_BOOTLOADER_MAGIC     MULTIBOOT2_BOOTLOADER_MAGIC
+#define MULTIBOOT_HEADER_MAGIC         MULTIBOOT2_HEADER_MAGIC
+#else
+#include <multiboot.h>
+#endif
+
+#include <grub/types.h>
+#include <grub/err.h>
+
+void grub_multiboot (int argc, char *argv[]);
+void grub_module (int argc, char *argv[]);
+
+grub_size_t grub_multiboot_get_mbi_size (void);
+grub_err_t grub_multiboot_make_mbi (void *orig, grub_uint32_t dest,
+                                   grub_off_t buf_off, grub_size_t bufsize);
+void grub_multiboot_free_mbi (void);
+grub_err_t grub_multiboot_init_mbi (int argc, char *argv[]);
+grub_err_t grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
+                                     int argc, char *argv[]);
+void grub_multiboot_set_bootdev (void);
+
+grub_uint32_t grub_get_multiboot_mmap_count (void);
+grub_err_t grub_multiboot_set_video_mode (void);
+
+#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU)
+#include <grub/i386/pc/vbe.h>
+#define GRUB_MACHINE_HAS_VGA_TEXT 1
+#else
+#define GRUB_MACHINE_HAS_VGA_TEXT 0
+#endif
+
+#define GRUB_MULTIBOOT_CONSOLE_EGA_TEXT 1
+#define GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER 2 
+
+grub_err_t
+grub_multiboot_set_console (int console_type, int accepted_consoles,
+                           int width, int height, int depth,
+                           int console_required);
+grub_err_t
+grub_multiboot_load (grub_file_t file);
+/* Load ELF32 or ELF64.  */
+grub_err_t
+grub_multiboot_load_elf (grub_file_t file, void *buffer);
+extern grub_size_t grub_multiboot_pure_size;
+extern grub_size_t grub_multiboot_alloc_mbi;
+
+#endif /* ! GRUB_MULTIBOOT_HEADER */
diff --git a/grub-core/include/grub/multiboot_loader.h b/grub-core/include/grub/multiboot_loader.h
new file mode 100644 (file)
index 0000000..bf1c130
--- /dev/null
@@ -0,0 +1,28 @@
+/* multiboot_loader.h - multiboot loader header file. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef GRUB_MULTIBOOT_LOADER_HEADER
+#define GRUB_MULTIBOOT_LOADER_HEADER 1
+
+/* Provided by the core ("rescue mode").  */
+void grub_rescue_cmd_multiboot_loader (int argc, char *argv[]);
+void grub_rescue_cmd_module_loader (int argc, char *argv[]);
+
+#endif /* ! GRUB_MULTIBOOT_LOADER_HEADER */
diff --git a/grub-core/include/grub/net.h b/grub-core/include/grub/net.h
new file mode 100644 (file)
index 0000000..c6d71d5
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_NET_HEADER
+#define GRUB_NET_HEADER        1
+
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/types.h>
+
+struct grub_net;
+
+struct grub_net_dev
+{
+  /* The device name.  */
+  const char *name;
+
+  /* FIXME: Just a template.  */
+  int (*probe) (struct grub_net *net, const void *addr);
+  void (*reset) (struct grub_net *net);
+  int (*poll) (struct grub_net *net);
+  void (*transmit) (struct grub_net *net, const void *destip,
+                   unsigned srcsock, unsigned destsock, const void *packet);
+  void (*disable) (struct grub_net *net);
+
+  /* The next net device.  */
+  struct grub_net_dev *next;
+};
+typedef struct grub_net_dev *grub_net_dev_t;
+
+struct grub_fs;
+
+struct grub_net
+{
+  /* The net name.  */
+  const char *name;
+
+  /* The underlying disk device.  */
+  grub_net_dev_t dev;
+
+  /* The binding filesystem.  */
+  struct grub_fs *fs;
+
+  /* FIXME: More data would be required, such as an IP address, a mask,
+     a gateway, etc.  */
+
+  /* Device-specific data.  */
+  void *data;
+};
+typedef struct grub_net *grub_net_t;
+
+/* FIXME: How to abstract networks? More consideration is necessary.  */
+
+/* Note: Networks are very different from disks, because networks must
+   be initialized before used, and the status is persistent.  */
+
+#endif /* ! GRUB_NET_HEADER */
diff --git a/grub-core/include/grub/normal.h b/grub-core/include/grub/normal.h
new file mode 100644 (file)
index 0000000..35eedf5
--- /dev/null
@@ -0,0 +1,116 @@
+/* normal.h - prototypes for the normal mode */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_NORMAL_HEADER
+#define GRUB_NORMAL_HEADER     1
+
+#include <grub/term.h>
+#include <grub/symbol.h>
+#include <grub/err.h>
+#include <grub/env.h>
+#include <grub/menu.h>
+#include <grub/command.h>
+#include <grub/file.h>
+
+/* The maximum size of a command-line.  */
+#define GRUB_MAX_CMDLINE       1600
+
+/* The standard left and right margin for some messages.  */
+#define STANDARD_MARGIN 6
+
+/* The type of a completion item.  */
+enum grub_completion_type
+  {
+    GRUB_COMPLETION_TYPE_COMMAND,
+    GRUB_COMPLETION_TYPE_DEVICE,
+    GRUB_COMPLETION_TYPE_PARTITION,
+    GRUB_COMPLETION_TYPE_FILE,
+    GRUB_COMPLETION_TYPE_ARGUMENT
+  };
+typedef enum grub_completion_type grub_completion_type_t;
+
+extern struct grub_menu_viewer grub_normal_text_menu_viewer;
+extern int grub_normal_exit_level;
+
+/* Defined in `main.c'.  */
+void grub_enter_normal_mode (const char *config);
+void grub_normal_execute (const char *config, int nested, int batch);
+void grub_menu_init_page (int nested, int edit,
+                         struct grub_term_output *term);
+void grub_normal_init_page (struct grub_term_output *term);
+grub_err_t grub_normal_add_menu_entry (int argc, const char **args,
+                                      const char *sourcecode);
+char *grub_file_getline (grub_file_t file);
+void grub_cmdline_run (int nested);
+
+/* Defined in `cmdline.c'.  */
+char *grub_cmdline_get (const char *prompt);
+grub_err_t grub_set_history (int newsize);
+
+/* Defined in `completion.c'.  */
+char *grub_normal_do_completion (char *buf, int *restore,
+                                void (*hook) (const char *item, grub_completion_type_t type, int count));
+
+/* Defined in `misc.c'.  */
+grub_err_t grub_normal_print_device_info (const char *name);
+
+/* Defined in `color.c'.  */
+char *grub_env_write_color_normal (struct grub_env_var *var, const char *val);
+char *grub_env_write_color_highlight (struct grub_env_var *var, const char *val);
+void grub_parse_color_name_pair (grub_uint8_t *ret, const char *name);
+
+/* Defined in `menu_text.c'.  */
+void grub_wait_after_message (void);
+void grub_print_ucs4 (const grub_uint32_t * str,
+                     const grub_uint32_t * last_position,
+                     struct grub_term_output *term);
+grub_ssize_t grub_getstringwidth (grub_uint32_t * str,
+                                 const grub_uint32_t * last_position,
+                                 struct grub_term_output *term);
+void grub_print_message_indented (const char *msg, int margin_left,
+                                 int margin_right,
+                                 struct grub_term_output *term);
+void
+grub_menu_text_register_instances (int entry, grub_menu_t menu, int nested);
+grub_err_t
+grub_show_menu (grub_menu_t menu, int nested);
+
+/* Defined in `handler.c'.  */
+void read_handler_list (void);
+void free_handler_list (void);
+
+/* Defined in `dyncmd.c'.  */
+void read_command_list (const char *prefix);
+
+/* Defined in `autofs.c'.  */
+void read_fs_list (const char *prefix);
+
+void grub_context_init (void);
+void grub_context_fini (void);
+
+void read_crypto_list (const char *prefix);
+
+void read_terminal_list (const char *prefix);
+
+void grub_set_more (int onoff);
+
+int grub_normal_get_line_counter (void);
+void grub_install_newline_hook (void);
+
+#endif /* ! GRUB_NORMAL_HEADER */
diff --git a/grub-core/include/grub/ntfs.h b/grub-core/include/grub/ntfs.h
new file mode 100644 (file)
index 0000000..31b9939
--- /dev/null
@@ -0,0 +1,183 @@
+/* ntfs.h - header for the NTFS filesystem */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_NTFS_H
+#define GRUB_NTFS_H    1
+
+#define FILE_MFT      0
+#define FILE_MFTMIRR  1
+#define FILE_LOGFILE  2
+#define FILE_VOLUME   3
+#define FILE_ATTRDEF  4
+#define FILE_ROOT     5
+#define FILE_BITMAP   6
+#define FILE_BOOT     7
+#define FILE_BADCLUS  8
+#define FILE_QUOTA    9
+#define FILE_UPCASE  10
+
+#define AT_STANDARD_INFORMATION        0x10
+#define AT_ATTRIBUTE_LIST      0x20
+#define AT_FILENAME            0x30
+#define AT_OBJECT_ID           0x40
+#define AT_SECURITY_DESCRIPTOR 0x50
+#define AT_VOLUME_NAME         0x60
+#define AT_VOLUME_INFORMATION  0x70
+#define AT_DATA                        0x80
+#define AT_INDEX_ROOT          0x90
+#define AT_INDEX_ALLOCATION    0xA0
+#define AT_BITMAP              0xB0
+#define AT_SYMLINK             0xC0
+#define AT_EA_INFORMATION      0xD0
+#define AT_EA                  0xE0
+
+#define ATTR_READ_ONLY         0x1
+#define ATTR_HIDDEN            0x2
+#define ATTR_SYSTEM            0x4
+#define ATTR_ARCHIVE           0x20
+#define ATTR_DEVICE            0x40
+#define ATTR_NORMAL            0x80
+#define ATTR_TEMPORARY         0x100
+#define ATTR_SPARSE            0x200
+#define ATTR_REPARSE           0x400
+#define ATTR_COMPRESSED                0x800
+#define ATTR_OFFLINE           0x1000
+#define ATTR_NOT_INDEXED       0x2000
+#define ATTR_ENCRYPTED         0x4000
+#define ATTR_DIRECTORY         0x10000000
+#define ATTR_INDEX_VIEW                0x20000000
+
+#define FLAG_COMPRESSED                1
+#define FLAG_ENCRYPTED         0x4000
+#define FLAG_SPARSE            0x8000
+
+#define BLK_SHR                GRUB_DISK_SECTOR_BITS
+
+#define MAX_MFT                (1024 >> BLK_SHR)
+#define MAX_IDX                (16384 >> BLK_SHR)
+
+#define COM_LEN                4096
+#define COM_LOG_LEN    12
+#define COM_SEC                (COM_LEN >> BLK_SHR)
+
+#define AF_ALST                1
+#define AF_MMFT                2
+#define AF_GPOS                4
+
+#define RF_COMP                1
+#define RF_CBLK                2
+#define RF_BLNK                4
+
+#define valueat(buf,ofs,type)  *((type*)(((char*)buf)+ofs))
+
+#define u16at(buf,ofs) grub_le_to_cpu16(valueat(buf,ofs,grub_uint16_t))
+#define u32at(buf,ofs) grub_le_to_cpu32(valueat(buf,ofs,grub_uint32_t))
+#define u64at(buf,ofs) grub_le_to_cpu64(valueat(buf,ofs,grub_uint64_t))
+
+#define v16at(buf,ofs) valueat(buf,ofs,grub_uint16_t)
+#define v32at(buf,ofs) valueat(buf,ofs,grub_uint32_t)
+#define v64at(buf,ofs) valueat(buf,ofs,grub_uint64_t)
+
+struct grub_ntfs_bpb
+{
+  grub_uint8_t jmp_boot[3];
+  grub_uint8_t oem_name[8];
+  grub_uint16_t bytes_per_sector;
+  grub_uint8_t sectors_per_cluster;
+  grub_uint8_t reserved_1[7];
+  grub_uint8_t media;
+  grub_uint16_t reserved_2;
+  grub_uint16_t sectors_per_track;
+  grub_uint16_t num_heads;
+  grub_uint32_t num_hidden_sectors;
+  grub_uint32_t reserved_3[2];
+  grub_uint64_t num_total_sectors;
+  grub_uint64_t mft_lcn;
+  grub_uint64_t mft_mirr_lcn;
+  grub_int8_t clusters_per_mft;
+  grub_int8_t reserved_4[3];
+  grub_int8_t clusters_per_index;
+  grub_int8_t reserved_5[3];
+  grub_uint64_t num_serial;
+  grub_uint32_t checksum;
+} __attribute__ ((packed));
+
+#define grub_ntfs_file grub_fshelp_node
+
+struct grub_ntfs_attr
+{
+  int flags;
+  char *emft_buf, *edat_buf;
+  char *attr_cur, *attr_nxt, *attr_end;
+  grub_uint32_t save_pos;
+  char *sbuf;
+  struct grub_ntfs_file *mft;
+};
+
+struct grub_fshelp_node
+{
+  struct grub_ntfs_data *data;
+  char *buf;
+  grub_uint64_t size;
+  grub_uint32_t ino;
+  int inode_read;
+  struct grub_ntfs_attr attr;
+};
+
+struct grub_ntfs_data
+{
+  struct grub_ntfs_file cmft;
+  struct grub_ntfs_file mmft;
+  grub_disk_t disk;
+  grub_uint32_t mft_size;
+  grub_uint32_t idx_size;
+  grub_uint32_t spc;
+  grub_uint32_t blocksize;
+  grub_uint32_t mft_start;
+  grub_uint64_t uuid;
+};
+
+struct grub_ntfs_comp
+{
+  grub_disk_t disk;
+  int comp_head, comp_tail;
+  grub_uint32_t comp_table[16][2];
+  grub_uint32_t cbuf_ofs, cbuf_vcn, spc;
+  char *cbuf;
+};
+
+struct grub_ntfs_rlst
+{
+  int flags;
+  grub_disk_addr_t target_vcn, curr_vcn, next_vcn, curr_lcn;
+  char *cur_run;
+  struct grub_ntfs_attr *attr;
+  struct grub_ntfs_comp comp;
+};
+
+typedef grub_err_t (*ntfscomp_func_t) (struct grub_ntfs_attr * at, char *dest,
+                                      grub_uint32_t ofs, grub_uint32_t len,
+                                      struct grub_ntfs_rlst * ctx,
+                                      grub_uint32_t vcn);
+
+extern ntfscomp_func_t EXPORT_VAR (grub_ntfscomp_func);
+
+grub_err_t EXPORT_FUNC(grub_ntfs_read_run_list) (struct grub_ntfs_rlst *ctx);
+
+#endif /* ! GRUB_NTFS_H */
diff --git a/grub-core/include/grub/parser.h b/grub-core/include/grub/parser.h
new file mode 100644 (file)
index 0000000..17f0c43
--- /dev/null
@@ -0,0 +1,119 @@
+/* parser.h - prototypes for the command line parser.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_PARSER_HEADER
+#define GRUB_PARSER_HEADER     1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/handler.h>
+#include <grub/reader.h>
+
+/* All the states for the command line.  */
+typedef enum
+  {
+    GRUB_PARSER_STATE_TEXT = 1,
+    GRUB_PARSER_STATE_ESC,
+    GRUB_PARSER_STATE_QUOTE,
+    GRUB_PARSER_STATE_DQUOTE,
+    GRUB_PARSER_STATE_VAR,
+    GRUB_PARSER_STATE_VARNAME,
+    GRUB_PARSER_STATE_VARNAME2,
+    GRUB_PARSER_STATE_QVAR,
+    GRUB_PARSER_STATE_QVARNAME,
+    GRUB_PARSER_STATE_QVARNAME2
+  } grub_parser_state_t;
+
+/* A single state transition.  */
+struct grub_parser_state_transition
+{
+  /* The state that is looked up.  */
+  grub_parser_state_t from_state;
+
+  /* The next state, determined by FROM_STATE and INPUT.  */
+  grub_parser_state_t to_state;
+
+  /* The input that will determine the next state from FROM_STATE.  */
+  char input;
+
+  /* If set to 1, the input is valid and should be used.  */
+  int keep_value;
+};
+
+/* Determines the state following STATE, determined by C.  */
+grub_parser_state_t
+EXPORT_FUNC (grub_parser_cmdline_state) (grub_parser_state_t state,
+                                        char c, char *result);
+
+grub_err_t
+EXPORT_FUNC (grub_parser_split_cmdline) (const char *cmdline,
+                                        grub_reader_getline_t getline,
+                                        int *argc, char ***argv);
+
+struct grub_parser
+{
+  /* The next parser.  */
+  struct grub_parser *next;
+
+  /* The parser name.  */
+  const char *name;
+
+  /* Initialize the parser.  */
+  grub_err_t (*init) (void);
+
+  /* Clean up the parser.  */
+  grub_err_t (*fini) (void);
+
+  grub_err_t (*parse_line) (char *line, grub_reader_getline_t getline);
+};
+typedef struct grub_parser *grub_parser_t;
+
+extern struct grub_handler_class EXPORT_VAR(grub_parser_class);
+grub_err_t EXPORT_FUNC(grub_parser_execute) (char *source);
+
+static inline void
+grub_parser_register (const char *name __attribute__ ((unused)),
+                     /* `name' is ignored here, but used by genhandlerlist.sh.  */
+                     grub_parser_t parser)
+{
+  grub_handler_register (&grub_parser_class, GRUB_AS_HANDLER (parser));
+}
+
+static inline void
+grub_parser_unregister (grub_parser_t parser)
+{
+  grub_handler_unregister (&grub_parser_class, GRUB_AS_HANDLER (parser));
+}
+
+static inline grub_parser_t
+grub_parser_get_current (void)
+{
+  return (grub_parser_t) grub_parser_class.cur_handler;
+}
+
+static inline grub_err_t
+grub_parser_set_current (grub_parser_t parser)
+{
+  return grub_handler_set_current (&grub_parser_class,
+                                  GRUB_AS_HANDLER (parser));
+}
+
+void grub_register_rescue_parser (void);
+
+#endif /* ! GRUB_PARSER_HEADER */
diff --git a/grub-core/include/grub/partition.h b/grub-core/include/grub/partition.h
new file mode 100644 (file)
index 0000000..80a9c15
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2004,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_PART_HEADER
+#define GRUB_PART_HEADER       1
+
+#include <grub/dl.h>
+#include <grub/list.h>
+
+struct grub_disk;
+
+typedef struct grub_partition *grub_partition_t;
+
+/* Partition map type.  */
+struct grub_partition_map
+{
+  /* The next partition map type.  */
+  struct grub_partition_map *next;
+
+  /* The name of the partition map type.  */
+  const char *name;
+
+  /* Call HOOK with each partition, until HOOK returns non-zero.  */
+  grub_err_t (*iterate) (struct grub_disk *disk,
+                        int (*hook) (struct grub_disk *disk,
+                                     const grub_partition_t partition));
+};
+typedef struct grub_partition_map *grub_partition_map_t;
+
+/* Partition description.  */
+struct grub_partition
+{
+  /* The partition number.  */
+  int number;
+
+  /* The start sector.  */
+  grub_disk_addr_t start;
+
+  /* The length in sector units.  */
+  grub_uint64_t len;
+
+  /* The offset of the partition table.  */
+  grub_disk_addr_t offset;
+
+  /* The index of this partition in the partition table.  */
+  int index;
+
+  /* Parent partition map.  */
+  struct grub_partition *parent;
+
+  /* The type partition map.  */
+  grub_partition_map_t partmap;
+};
+
+grub_partition_t EXPORT_FUNC(grub_partition_probe) (struct grub_disk *disk,
+                                                   const char *str);
+int EXPORT_FUNC(grub_partition_iterate) (struct grub_disk *disk,
+                                        int (*hook) (struct grub_disk *disk,
+                                                     const grub_partition_t partition));
+char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition);
+
+
+extern grub_partition_map_t EXPORT_VAR(grub_partition_map_list);
+
+static inline void
+grub_partition_map_register (grub_partition_map_t partmap)
+{
+  grub_list_push (GRUB_AS_LIST_P (&grub_partition_map_list),
+                 GRUB_AS_LIST (partmap));
+}
+
+static inline void
+grub_partition_map_unregister (grub_partition_map_t partmap)
+{
+  grub_list_remove (GRUB_AS_LIST_P (&grub_partition_map_list),
+                   GRUB_AS_LIST (partmap));
+}
+
+#define FOR_PARTITION_MAPS(var) for (var = grub_partition_map_list; var; var = var->next)
+
+\f
+static inline grub_disk_addr_t
+grub_partition_get_start (const grub_partition_t p)
+{
+  grub_partition_t part;
+  grub_uint64_t part_start = 0;
+
+  for (part = p; part; part = part->parent)
+    part_start += part->start;
+
+  return part_start;
+}
+
+static inline grub_uint64_t
+grub_partition_get_len (const grub_partition_t p)
+{
+  return p->len;
+}
+
+#endif /* ! GRUB_PART_HEADER */
diff --git a/grub-core/include/grub/parttool.h b/grub-core/include/grub/parttool.h
new file mode 100644 (file)
index 0000000..8291e11
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_PARTTOOL_HEADER
+#define GRUB_PARTTOOL_HEADER   1
+
+struct grub_parttool_argdesc
+{
+  char *name;
+  char *desc;
+  enum {GRUB_PARTTOOL_ARG_END, GRUB_PARTTOOL_ARG_BOOL, GRUB_PARTTOOL_ARG_VAL}
+    type;
+};
+
+struct grub_parttool_args
+{
+  int set;
+  union
+  {
+    int bool;
+    char *str;
+  };
+};
+
+typedef grub_err_t (*grub_parttool_function_t) (const grub_device_t dev,
+                                               const struct grub_parttool_args *args);
+
+struct grub_parttool
+{
+  struct grub_parttool *next;
+  char *name;
+  int handle;
+  int nargs;
+  struct grub_parttool_argdesc *args;
+  grub_parttool_function_t func;
+};
+
+int grub_parttool_register(const char *part_name,
+                          const grub_parttool_function_t func,
+                          const struct grub_parttool_argdesc *args);
+void grub_parttool_unregister (int handle);
+
+#endif /* ! GRUB_PARTTOOL_HEADER*/
diff --git a/grub-core/include/grub/pci.h b/grub-core/include/grub/pci.h
new file mode 100644 (file)
index 0000000..89bd103
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef        GRUB_PCI_H
+#define        GRUB_PCI_H      1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+#define  GRUB_PCI_ADDR_SPACE_MASK      0x01
+#define  GRUB_PCI_ADDR_SPACE_MEMORY    0x00
+#define  GRUB_PCI_ADDR_SPACE_IO                0x01
+
+#define  GRUB_PCI_ADDR_MEM_TYPE_MASK   0x06
+#define  GRUB_PCI_ADDR_MEM_TYPE_32     0x00    /* 32 bit address */
+#define  GRUB_PCI_ADDR_MEM_TYPE_1M     0x02    /* Below 1M [obsolete] */
+#define  GRUB_PCI_ADDR_MEM_TYPE_64     0x04    /* 64 bit address */
+#define  GRUB_PCI_ADDR_MEM_PREFETCH    0x08    /* prefetchable */
+
+#define  GRUB_PCI_ADDR_MEM_MASK                ~0xf
+#define  GRUB_PCI_ADDR_IO_MASK         ~0x03
+
+#define  GRUB_PCI_REG_PCI_ID       0x00
+#define  GRUB_PCI_REG_VENDOR       0x00
+#define  GRUB_PCI_REG_DEVICE       0x02
+#define  GRUB_PCI_REG_COMMAND      0x04
+#define  GRUB_PCI_REG_STATUS       0x06
+#define  GRUB_PCI_REG_REVISION     0x08
+#define  GRUB_PCI_REG_CLASS        0x08
+#define  GRUB_PCI_REG_CACHELINE    0x0c
+#define  GRUB_PCI_REG_LAT_TIMER    0x0d
+#define  GRUB_PCI_REG_HEADER_TYPE  0x0e
+#define  GRUB_PCI_REG_BIST         0x0f
+#define  GRUB_PCI_REG_ADDRESSES    0x10
+
+/* Beware that 64-bit address takes 2 registers.  */
+#define  GRUB_PCI_REG_ADDRESS_REG0 0x10
+#define  GRUB_PCI_REG_ADDRESS_REG1 0x14
+#define  GRUB_PCI_REG_ADDRESS_REG2 0x18
+#define  GRUB_PCI_REG_ADDRESS_REG3 0x1c
+#define  GRUB_PCI_REG_ADDRESS_REG4 0x20
+#define  GRUB_PCI_REG_ADDRESS_REG5 0x24
+
+#define  GRUB_PCI_REG_CIS_POINTER  0x28
+#define  GRUB_PCI_REG_SUBVENDOR    0x2c
+#define  GRUB_PCI_REG_SUBSYSTEM    0x2e
+#define  GRUB_PCI_REG_ROM_ADDRESS  0x30
+#define  GRUB_PCI_REG_CAP_POINTER  0x34
+#define  GRUB_PCI_REG_IRQ_LINE     0x3c
+#define  GRUB_PCI_REG_IRQ_PIN      0x3d
+#define  GRUB_PCI_REG_MIN_GNT      0x3e
+#define  GRUB_PCI_REG_MAX_LAT      0x3f
+
+typedef grub_uint32_t grub_pci_id_t;
+
+#ifdef GRUB_MACHINE_EMU
+#include <grub/pciutils.h>
+#else
+typedef grub_uint32_t grub_pci_address_t;
+struct grub_pci_device
+{
+  int bus;
+  int device;
+  int function;
+};
+typedef struct grub_pci_device grub_pci_device_t;
+static inline int
+grub_pci_get_bus (grub_pci_device_t dev)
+{
+  return dev.bus;
+}
+
+static inline int
+grub_pci_get_device (grub_pci_device_t dev)
+{
+  return dev.device;
+}
+
+static inline int
+grub_pci_get_function (grub_pci_device_t dev)
+{
+  return dev.function;
+}
+#include <grub/cpu/pci.h>
+#endif
+
+typedef int NESTED_FUNC_ATTR (*grub_pci_iteratefunc_t)
+     (grub_pci_device_t dev, grub_pci_id_t pciid);
+
+grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (grub_pci_device_t dev,
+                                                      int reg);
+
+void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook);
+
+#endif /* GRUB_PCI_H */
diff --git a/grub-core/include/grub/pciutils.h b/grub-core/include/grub/pciutils.h
new file mode 100644 (file)
index 0000000..36d47e5
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef        GRUB_PCIUTILS_H
+#define        GRUB_PCIUTILS_H 1
+
+#include <pciaccess.h>
+
+typedef struct pci_device *grub_pci_device_t;
+
+static inline int
+grub_pci_get_bus (grub_pci_device_t dev)
+{
+  return dev->bus;
+}
+
+static inline int
+grub_pci_get_device (grub_pci_device_t dev)
+{
+  return dev->dev;
+}
+
+static inline int
+grub_pci_get_function (grub_pci_device_t dev)
+{
+  return dev->func;
+}
+
+struct grub_pci_address
+{
+  grub_pci_device_t dev;
+  int pos;
+};
+
+typedef struct grub_pci_address grub_pci_address_t;
+
+static inline grub_uint32_t
+grub_pci_read (grub_pci_address_t addr)
+{
+  grub_uint32_t ret;
+  pci_device_cfg_read_u32 (addr.dev, &ret, addr.pos);
+  return ret;
+}
+
+static inline grub_uint16_t
+grub_pci_read_word (grub_pci_address_t addr)
+{
+  grub_uint16_t ret;
+  pci_device_cfg_read_u16 (addr.dev, &ret, addr.pos);
+  return ret;
+}
+
+static inline grub_uint8_t
+grub_pci_read_byte (grub_pci_address_t addr)
+{
+  grub_uint8_t ret;
+  pci_device_cfg_read_u8 (addr.dev, &ret, addr.pos);
+  return ret;
+}
+
+static inline void
+grub_pci_write (grub_pci_address_t addr, grub_uint32_t data)
+{
+  pci_device_cfg_write_u32 (addr.dev, data, addr.pos);
+}
+
+static inline void
+grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data)
+{
+  pci_device_cfg_write_u16 (addr.dev, data, addr.pos);
+}
+
+static inline void
+grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data)
+{
+  pci_device_cfg_write_u8 (addr.dev, data, addr.pos);
+}
+
+void *
+grub_pci_device_map_range (grub_pci_device_t dev, grub_addr_t base,
+                          grub_size_t size);
+
+void
+grub_pci_device_unmap_range (grub_pci_device_t dev, void *mem,
+                            grub_size_t size);
+
+
+#endif /* GRUB_PCIUTILS_H */
diff --git a/grub-core/include/grub/powerpc/ieee1275/biosdisk.h b/grub-core/include/grub/powerpc/ieee1275/biosdisk.h
new file mode 100644 (file)
index 0000000..30584d6
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BIOSDISK_MACHINE_HEADER
+#define GRUB_BIOSDISK_MACHINE_HEADER   1
+
+#define GRUB_BIOSDISK_FLAG_LBA 1
+
+struct grub_biosdisk_data
+{
+  int drive;
+  unsigned long cylinders;
+  unsigned long heads;
+  unsigned long sectors;
+  unsigned long flags;
+};
+
+int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap);
+int grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff,
+                              int soff, int nsec, int segment);
+int grub_biosdisk_check_int13_extensions (int drive);
+int grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp);
+int grub_biosdisk_get_diskinfo_standard (int drive,
+                                        unsigned long *cylinders,
+                                        unsigned long *heads,
+                                        unsigned long *sectors);
+int grub_biosdisk_get_num_floppies (void);
+
+void grub_biosdisk_init (void);
+
+#endif /* ! GRUB_BIOSDISK_MACHINE_HEADER */
diff --git a/grub-core/include/grub/powerpc/ieee1275/console.h b/grub-core/include/grub/powerpc/ieee1275/console.h
new file mode 100644 (file)
index 0000000..ed2b720
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CONSOLE_MACHINE_HEADER
+#define GRUB_CONSOLE_MACHINE_HEADER    1
+
+/* Initialize the console system.  */
+void grub_console_init (void);
+
+/* Finish the console system.  */
+void grub_console_fini (void);
+
+#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */
diff --git a/grub-core/include/grub/powerpc/ieee1275/ieee1275.h b/grub-core/include/grub/powerpc/ieee1275/ieee1275.h
new file mode 100644 (file)
index 0000000..3c7683f
--- /dev/null
@@ -0,0 +1,28 @@
+/* ieee1275.h - Access the Open Firmware client interface.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_IEEE1275_MACHINE_HEADER
+#define GRUB_IEEE1275_MACHINE_HEADER   1
+
+#include <grub/types.h>
+
+#define GRUB_IEEE1275_CELL_SIZEOF 4
+typedef grub_uint32_t grub_ieee1275_cell_t;
+
+#endif /* ! GRUB_IEEE1275_MACHINE_HEADER */
diff --git a/grub-core/include/grub/powerpc/ieee1275/kernel.h b/grub-core/include/grub/powerpc/ieee1275/kernel.h
new file mode 100644 (file)
index 0000000..a76c2a4
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_MACHINE_HEADER
+#define GRUB_KERNEL_MACHINE_HEADER     1
+
+#include <grub/symbol.h>
+
+#ifndef ASM_FILE
+
+/* The prefix which points to the directory where GRUB modules and its
+   configuration file are located.  */
+extern char grub_prefix[];
+
+#endif
+
+#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/grub-core/include/grub/powerpc/ieee1275/loader.h b/grub-core/include/grub/powerpc/ieee1275/loader.h
new file mode 100644 (file)
index 0000000..606bfcd
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER     1
+
+/* The symbol shared between the normal mode and rescue mode
+   loader.  */
+void grub_rescue_cmd_linux (int argc, char *argv[]);
+void grub_rescue_cmd_initrd (int argc, char *argv[]);
+
+void grub_linux_init (void);
+void grub_linux_fini (void);
+void grub_linux_normal_init (void);
+void grub_linux_normal_fini (void);
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/grub-core/include/grub/powerpc/ieee1275/memory.h b/grub-core/include/grub/powerpc/ieee1275/memory.h
new file mode 100644 (file)
index 0000000..f8f2ff0
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MEMORY_MACHINE_HEADER
+#define GRUB_MEMORY_MACHINE_HEADER     1
+
+#include <grub/ieee1275/ieee1275.h>
+
+#define GRUB_MACHINE_MEMORY_AVAILABLE          1
+
+#endif
diff --git a/grub-core/include/grub/powerpc/ieee1275/time.h b/grub-core/include/grub/powerpc/ieee1275/time.h
new file mode 100644 (file)
index 0000000..3f8ad26
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_MACHINE_TIME_HEADER
+#define KERNEL_MACHINE_TIME_HEADER     1
+
+#include <grub/symbol.h>
+
+#define GRUB_TICKS_PER_SECOND  1000
+
+/* Return the real time in ticks.  */
+grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
+
+#endif /* ! KERNEL_MACHINE_TIME_HEADER */
diff --git a/grub-core/include/grub/powerpc/ieee1275/util/biosdisk.h b/grub-core/include/grub/powerpc/ieee1275/util/biosdisk.h
new file mode 100644 (file)
index 0000000..f4262a0
--- /dev/null
@@ -0,0 +1,27 @@
+/* biosdisk.h - emulate biosdisk */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BIOSDISK_MACHINE_UTIL_HEADER
+#define GRUB_BIOSDISK_MACHINE_UTIL_HEADER      1
+
+void grub_util_biosdisk_init (const char *dev_map);
+void grub_util_biosdisk_fini (void);
+char *grub_util_biosdisk_get_grub_dev (const char *os_dev);
+
+#endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */
diff --git a/grub-core/include/grub/powerpc/kernel.h b/grub-core/include/grub/powerpc/kernel.h
new file mode 100644 (file)
index 0000000..b468733
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_CPU_HEADER
+#define GRUB_KERNEL_CPU_HEADER 1
+
+#define GRUB_MOD_ALIGN 0x1000
+
+/* Minimal gap between _end and the start of the modules.  It's a hack
+   for PowerMac to prevent "CLAIM failed" error.  The real fix is to
+   rewrite grub-mkimage to generate valid ELF files.  */
+#define GRUB_MOD_GAP 0x8000
+
+#define GRUB_KERNEL_CPU_PREFIX         0x4
+#define GRUB_KERNEL_CPU_DATA_END       0x44
+
+#endif
diff --git a/grub-core/include/grub/powerpc/setjmp.h b/grub-core/include/grub/powerpc/setjmp.h
new file mode 100644 (file)
index 0000000..fa16f73
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SETJMP_CPU_HEADER
+#define GRUB_SETJMP_CPU_HEADER 1
+
+typedef unsigned long grub_jmp_buf[20];
+
+int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice));
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
+
+#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/grub-core/include/grub/powerpc/time.h b/grub-core/include/grub/powerpc/time.h
new file mode 100644 (file)
index 0000000..5db7ff4
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_TIME_HEADER
+#define KERNEL_CPU_TIME_HEADER 1
+
+static __inline void
+grub_cpu_idle (void)
+{
+  /* FIXME: not implemented */
+}
+
+#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/grub-core/include/grub/powerpc/types.h b/grub-core/include/grub/powerpc/types.h
new file mode 100644 (file)
index 0000000..a098ae6
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER  1
+
+/* The size of void *.  */
+#define GRUB_TARGET_SIZEOF_VOID_P      4
+
+/* The size of long.  */
+#define GRUB_TARGET_SIZEOF_LONG                4
+
+/* powerpc is big-endian.  */
+#define GRUB_TARGET_WORDS_BIGENDIAN    1
+
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/grub-core/include/grub/raid.h b/grub-core/include/grub/raid.h
new file mode 100644 (file)
index 0000000..8fa4c38
--- /dev/null
@@ -0,0 +1,85 @@
+/* raid.h - On disk structures for RAID. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_RAID_H
+#define GRUB_RAID_H    1
+
+#include <grub/types.h>
+
+#define GRUB_RAID_MAX_DEVICES  32
+
+#define GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC       0
+#define GRUB_RAID_LAYOUT_RIGHT_ASYMMETRIC      1
+#define GRUB_RAID_LAYOUT_LEFT_SYMMETRIC                2
+#define GRUB_RAID_LAYOUT_RIGHT_SYMMETRIC       3
+
+#define GRUB_RAID_LAYOUT_RIGHT_MASK            1
+#define GRUB_RAID_LAYOUT_SYMMETRIC_MASK                2
+
+struct grub_raid_array
+{
+  int number;              /* The device number, taken from md_minor so we
+                             are consistent with the device name in
+                             Linux. */
+  int level;               /* RAID levels, only 0, 1 or 5 at the moment. */
+  int layout;              /* Layout for RAID 5/6.  */
+  unsigned int total_devs; /* Total number of devices in the array. */
+  grub_size_t chunk_size;  /* The size of a chunk, in 512 byte sectors. */
+  grub_uint64_t disk_size; /* Size of an individual disk, in 512 byte
+                             sectors. */
+  int index;               /* Index of current device.  */
+  int uuid_len;            /* The length of uuid.  */
+  char *uuid;              /* The UUID of the device. */
+
+  /* The following field is setup by the caller.  */
+  char *name;              /* That will be "md<number>". */
+  unsigned int nr_devs;    /* The number of devices we've found so far. */
+  grub_disk_t device[GRUB_RAID_MAX_DEVICES];  /* Array of total_devs devices. */
+  struct grub_raid_array *next;
+};
+
+struct grub_raid
+{
+  const char *name;
+
+  grub_err_t (*detect) (grub_disk_t disk, struct grub_raid_array *array);
+
+  struct grub_raid *next;
+};
+typedef struct grub_raid *grub_raid_t;
+
+void grub_raid_register (grub_raid_t raid);
+void grub_raid_unregister (grub_raid_t raid);
+
+void grub_raid_block_xor (char *buf1, const char *buf2, int size);
+
+typedef grub_err_t (*grub_raid5_recover_func_t) (struct grub_raid_array *array,
+                                                 int disknr, char *buf,
+                                                 grub_disk_addr_t sector,
+                                                 int size);
+
+typedef grub_err_t (*grub_raid6_recover_func_t) (struct grub_raid_array *array,
+                                                 int disknr, int p, char *buf,
+                                                 grub_disk_addr_t sector,
+                                                 int size);
+
+extern grub_raid5_recover_func_t grub_raid5_recover_func;
+extern grub_raid6_recover_func_t grub_raid6_recover_func;
+
+#endif /* ! GRUB_RAID_H */
diff --git a/grub-core/include/grub/reader.h b/grub-core/include/grub/reader.h
new file mode 100644 (file)
index 0000000..fd72a32
--- /dev/null
@@ -0,0 +1,29 @@
+/* reader.h - prototypes for command line reader.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_READER_HEADER
+#define GRUB_READER_HEADER     1
+
+#include <grub/err.h>
+
+typedef grub_err_t (*grub_reader_getline_t) (char **, int);
+
+void grub_rescue_run (void);
+
+#endif /* ! GRUB_READER_HEADER */
diff --git a/grub-core/include/grub/script_sh.h b/grub-core/include/grub/script_sh.h
new file mode 100644 (file)
index 0000000..b55b6a8
--- /dev/null
@@ -0,0 +1,349 @@
+/* normal_parser.h  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_NORMAL_PARSER_HEADER
+#define GRUB_NORMAL_PARSER_HEADER      1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/parser.h>
+
+struct grub_script_mem;
+
+/* The generic header for each scripting command or structure.  */
+struct grub_script_cmd
+{
+  /* This function is called to execute the command.  */
+  grub_err_t (*exec) (struct grub_script_cmd *cmd);
+
+  /* The next command.  This can be used by the parent to form a chain
+     of commands.  */
+  struct grub_script_cmd *next;
+};
+
+struct grub_script
+{
+  struct grub_script_mem *mem;
+  struct grub_script_cmd *cmd;
+};
+\f
+typedef enum
+{
+  GRUB_SCRIPT_ARG_TYPE_VAR,
+  GRUB_SCRIPT_ARG_TYPE_TEXT,
+  GRUB_SCRIPT_ARG_TYPE_DQVAR,
+  GRUB_SCRIPT_ARG_TYPE_DQSTR,
+  GRUB_SCRIPT_ARG_TYPE_SQSTR
+} grub_script_arg_type_t;
+
+/* A part of an argument.  */
+struct grub_script_arg
+{
+  grub_script_arg_type_t type;
+
+  char *str;
+
+  /* Next argument part.  */
+  struct grub_script_arg *next;
+};
+
+/* A complete argument.  It consists of a list of one or more `struct
+   grub_script_arg's.  */
+struct grub_script_arglist
+{
+  struct grub_script_arglist *next;
+  struct grub_script_arg *arg;
+  /* Only stored in the first link.  */
+  int argcount;
+};
+
+/* A single command line.  */
+struct grub_script_cmdline
+{
+  struct grub_script_cmd cmd;
+
+  /* The arguments for this command.  */
+  struct grub_script_arglist *arglist;
+};
+
+/* A block of commands, this can be used to group commands.  */
+struct grub_script_cmdblock
+{
+  struct grub_script_cmd cmd;
+
+  /* A chain of commands.  */
+  struct grub_script_cmd *cmdlist;
+};
+
+/* An if statement.  */
+struct grub_script_cmdif
+{
+  struct grub_script_cmd cmd;
+
+  /* The command used to check if the 'if' is true or false.  */
+  struct grub_script_cmd *exec_to_evaluate;
+
+  /* The code executed in case the result of 'if' was true.  */
+  struct grub_script_cmd *exec_on_true;
+
+  /* The code executed in case the result of 'if' was false.  */
+  struct grub_script_cmd *exec_on_false;
+};
+
+/* A for statement.  */
+struct grub_script_cmdfor
+{
+  struct grub_script_cmd cmd;
+
+  /* The name used as looping variable.  */
+  struct grub_script_arg *name;
+
+  /* The words loop iterates over.  */
+  struct grub_script_arglist *words;
+
+  /* The command list executed in each loop.  */
+  struct grub_script_cmd *list;
+};
+
+/* A while/until command.  */
+struct grub_script_cmdwhile
+{
+  struct grub_script_cmd cmd;
+
+  /* The command list used as condition.  */
+  struct grub_script_cmd *cond;
+
+  /* The command list executed in each loop.  */
+  struct grub_script_cmd *list;
+
+  /* The flag to indicate this as "until" loop.  */
+  int until;
+};
+
+/* A menu entry generate statement.  */
+struct grub_script_cmd_menuentry
+{
+  struct grub_script_cmd cmd;
+
+  /* The arguments for this menu entry.  */
+  struct grub_script_arglist *arglist;
+
+  /* The sourcecode the entry will be generated from.  */
+  const char *sourcecode;
+
+  /* Options.  XXX: Not used yet.  */
+  int options;
+};
+
+/* State of the lexer as passed to the lexer.  */
+struct grub_lexer_param
+{
+  /* Function used by the lexer to get a new line when more input is
+     expected, but not available.  */
+  grub_reader_getline_t getline;
+
+  /* A reference counter.  If this is >0 it means that the parser
+     expects more tokens and `getline' should be called to fetch more.
+     Otherwise the lexer can stop processing if the current buffer is
+     depleted.  */
+  int refs;
+
+  /* While walking through the databuffer, `record' the characters to
+     this other buffer.  It can be used to edit the menu entry at a
+     later moment.  */
+
+  /* If true, recording is enabled.  */
+  int record;
+
+  /* Points to the recording.  */
+  char *recording;
+
+  /* index in the RECORDING.  */
+  int recordpos;
+
+  /* Size of RECORDING.  */
+  int recordlen;
+
+  /* End of file reached.  */
+  int eof;
+
+  /* Merge multiple word tokens.  */
+  int merge_start;
+  int merge_end;
+
+  /* Part of a multi-part token.  */
+  char *text;
+  unsigned used;
+  unsigned size;
+
+  /* Type of text.  */
+  grub_script_arg_type_t type;
+
+  /* Flex scanner.  */
+  void *yyscanner;
+
+  /* Flex scanner buffer.  */
+  void *buffer;
+};
+
+#define GRUB_LEXER_INITIAL_TEXT_SIZE   32
+#define GRUB_LEXER_INITIAL_RECORD_SIZE 256
+
+/* State of the parser as passes to the parser.  */
+struct grub_parser_param
+{
+  /* Keep track of the memory allocated for this specific
+     function.  */
+  struct grub_script_mem *func_mem;
+
+  /* When set to 0, no errors have occurred during parsing.  */
+  int err;
+
+  /* The memory that was used while parsing and scanning.  */
+  struct grub_script_mem *memused;
+
+  /* The result of the parser.  */
+  struct grub_script_cmd *parsed;
+
+  struct grub_lexer_param *lexerstate;
+};
+
+struct grub_script_arglist *
+grub_script_create_arglist (struct grub_parser_param *state);
+
+struct grub_script_arglist *
+grub_script_add_arglist (struct grub_parser_param *state,
+                        struct grub_script_arglist *list,
+                        struct grub_script_arg *arg);
+struct grub_script_cmd *
+grub_script_create_cmdline (struct grub_parser_param *state,
+                           struct grub_script_arglist *arglist);
+struct grub_script_cmd *
+grub_script_create_cmdblock (struct grub_parser_param *state);
+
+struct grub_script_cmd *
+grub_script_create_cmdif (struct grub_parser_param *state,
+                         struct grub_script_cmd *exec_to_evaluate,
+                         struct grub_script_cmd *exec_on_true,
+                         struct grub_script_cmd *exec_on_false);
+
+struct grub_script_cmd *
+grub_script_create_cmdfor (struct grub_parser_param *state,
+                          struct grub_script_arg *name,
+                          struct grub_script_arglist *words,
+                          struct grub_script_cmd *list);
+
+struct grub_script_cmd *
+grub_script_create_cmdwhile (struct grub_parser_param *state,
+                            struct grub_script_cmd *cond,
+                            struct grub_script_cmd *list,
+                            int is_an_until_loop);
+
+struct grub_script_cmd *
+grub_script_create_cmdmenu (struct grub_parser_param *state,
+                           struct grub_script_arglist *arglist,
+                           char *sourcecode,
+                           int options);
+
+struct grub_script_cmd *
+grub_script_add_cmd (struct grub_parser_param *state,
+                    struct grub_script_cmdblock *cmdblock,
+                    struct grub_script_cmd *cmd);
+struct grub_script_arg *
+grub_script_arg_add (struct grub_parser_param *state,
+                    struct grub_script_arg *arg,
+                    grub_script_arg_type_t type, char *str);
+
+struct grub_script *grub_script_parse (char *script,
+                                      grub_reader_getline_t getline);
+void grub_script_free (struct grub_script *script);
+struct grub_script *grub_script_create (struct grub_script_cmd *cmd,
+                                       struct grub_script_mem *mem);
+
+struct grub_lexer_param *grub_script_lexer_init (struct grub_parser_param *parser,
+                                                char *script,
+                                                grub_reader_getline_t getline);
+void grub_script_lexer_fini (struct grub_lexer_param *);
+void grub_script_lexer_ref (struct grub_lexer_param *);
+void grub_script_lexer_deref (struct grub_lexer_param *);
+void grub_script_lexer_record_start (struct grub_parser_param *);
+char *grub_script_lexer_record_stop (struct grub_parser_param *);
+int  grub_script_lexer_yywrap (struct grub_parser_param *);
+void grub_script_lexer_record (struct grub_parser_param *, char *);
+
+/* Functions to track allocated memory.  */
+struct grub_script_mem *grub_script_mem_record (struct grub_parser_param *state);
+struct grub_script_mem *grub_script_mem_record_stop (struct grub_parser_param *state,
+                                                    struct grub_script_mem *restore);
+void *grub_script_malloc (struct grub_parser_param *state, grub_size_t size);
+
+/* Functions used by bison.  */
+union YYSTYPE;
+int grub_script_yylex (union YYSTYPE *, struct grub_parser_param *);
+int grub_script_yyparse (struct grub_parser_param *);
+void grub_script_yyerror (struct grub_parser_param *, char const *);
+
+/* Commands to execute, don't use these directly.  */
+grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd);
+grub_err_t grub_script_execute_cmdblock (struct grub_script_cmd *cmd);
+grub_err_t grub_script_execute_cmdif (struct grub_script_cmd *cmd);
+grub_err_t grub_script_execute_cmdfor (struct grub_script_cmd *cmd);
+grub_err_t grub_script_execute_cmdwhile (struct grub_script_cmd *cmd);
+grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd);
+
+/* Execute any GRUB pre-parsed command or script.  */
+grub_err_t grub_script_execute (struct grub_script *script);
+
+/* This variable points to the parsed command.  This is used to
+   communicate with the bison code.  */
+extern struct grub_script_cmd *grub_script_parsed;
+
+\f
+
+/* The function description.  */
+struct grub_script_function
+{
+  /* The name.  */
+  char *name;
+
+  /* The script function.  */
+  struct grub_script *func;
+
+  /* The flags.  */
+  unsigned flags;
+
+  /* The next element.  */
+  struct grub_script_function *next;
+
+  int references;
+};
+typedef struct grub_script_function *grub_script_function_t;
+
+grub_script_function_t grub_script_function_create (struct grub_script_arg *functionname,
+                                                   struct grub_script *cmd);
+void grub_script_function_remove (const char *name);
+grub_script_function_t grub_script_function_find (char *functionname);
+int grub_script_function_iterate (int (*iterate) (grub_script_function_t));
+int grub_script_function_call (grub_script_function_t func,
+                              int argc, char **args);
+
+char **
+grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count);
+
+#endif /* ! GRUB_NORMAL_PARSER_HEADER */
diff --git a/grub-core/include/grub/scsi.h b/grub-core/include/grub/scsi.h
new file mode 100644 (file)
index 0000000..fbe4582
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef        GRUB_SCSI_H
+#define        GRUB_SCSI_H     1
+
+typedef struct grub_scsi_dev *grub_scsi_dev_t;
+
+void grub_scsi_dev_register (grub_scsi_dev_t dev);
+void grub_scsi_dev_unregister (grub_scsi_dev_t dev);
+
+struct grub_scsi;
+
+struct grub_scsi_dev
+{
+  /* The device name.  */
+  const char *name;
+
+  /* Call HOOK with each device name, until HOOK returns non-zero.  */
+  int (*iterate) (int (*hook) (const char *name, int luns));
+
+  /* Open the device named NAME, and set up SCSI.  */
+  grub_err_t (*open) (const char *name, struct grub_scsi *scsi);
+
+  /* Close the scsi device SCSI.  */
+  void (*close) (struct grub_scsi *scsi);
+
+  /* Read SIZE bytes from the device SCSI into BUF after sending the
+     command CMD of size CMDSIZE.  */
+  grub_err_t (*read) (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
+                     grub_size_t size, char *buf);
+
+  /* Write SIZE  bytes from BUF to  the device SCSI  after sending the
+     command CMD of size CMDSIZE.  */
+  grub_err_t (*write) (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
+                      grub_size_t size, char *buf);
+
+  /* The next scsi device.  */
+  struct grub_scsi_dev *next;
+};
+
+struct grub_scsi
+{
+  /* The scsi device name.  */
+  char *name;
+
+  /* The underlying scsi device.  */
+  grub_scsi_dev_t dev;
+
+  /* Type of SCSI device.  XXX: Make enum.  */
+  grub_uint8_t devtype;
+
+  /* Number of LUNs.  */
+  int luns;
+
+  /* LUN for this `struct grub_scsi'.  */
+  int lun;
+
+  /* Set to 0 when not removable, 1 when removable.  */
+  int removable;
+
+  /* Size of the device in blocks.  */
+  int size;
+
+  /* Size of one block.  */
+  int blocksize;
+
+  /* Device-specific data.  */
+  void *data;
+};
+typedef struct grub_scsi *grub_scsi_t;
+
+#endif /* GRUB_SCSI_H */
diff --git a/grub-core/include/grub/scsicmd.h b/grub-core/include/grub/scsicmd.h
new file mode 100644 (file)
index 0000000..40f237a
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef        GRUB_SCSICMD_H
+#define        GRUB_SCSICMD_H  1
+
+#include <grub/types.h>
+
+#define GRUB_SCSI_DEVTYPE_MASK 31
+#define GRUB_SCSI_REMOVABLE_BIT        7
+#define GRUB_SCSI_LUN_SHIFT    5
+
+struct grub_scsi_inquiry
+{
+  grub_uint8_t opcode;
+  grub_uint8_t lun;
+  grub_uint16_t reserved;
+  grub_uint16_t alloc_length;
+  grub_uint8_t reserved2;
+  grub_uint8_t pad[5];
+} __attribute__((packed));
+
+struct grub_scsi_inquiry_data
+{
+  grub_uint8_t devtype;
+  grub_uint8_t rmb;
+  grub_uint16_t reserved;
+  grub_uint8_t length;
+  grub_uint8_t reserved2[3];
+  char vendor[8];
+  char prodid[16];
+  char prodrev[4];
+} __attribute__((packed));
+
+struct grub_scsi_read_capacity
+{
+  grub_uint8_t opcode;
+  grub_uint8_t lun;
+  grub_uint8_t reserved[8];
+  grub_uint8_t pad[2];
+} __attribute__((packed));
+
+struct grub_scsi_read_capacity_data
+{
+  grub_uint32_t size;
+  grub_uint32_t blocksize;
+} __attribute__((packed));
+
+struct grub_scsi_read10
+{
+  grub_uint8_t opcode;
+  grub_uint8_t lun;
+  grub_uint32_t lba;
+  grub_uint8_t reserved;
+  grub_uint16_t size;
+  grub_uint8_t reserved2;
+  grub_uint16_t pad;
+} __attribute__((packed));
+
+struct grub_scsi_read12
+{
+  grub_uint8_t opcode;
+  grub_uint8_t lun;
+  grub_uint32_t lba;
+  grub_uint32_t size;
+  grub_uint8_t reserved;
+  grub_uint8_t control;
+} __attribute__((packed));
+
+struct grub_scsi_write10
+{
+  grub_uint8_t opcode;
+  grub_uint8_t lun;
+  grub_uint32_t lba;
+  grub_uint8_t reserved;
+  grub_uint16_t size;
+  grub_uint8_t reserved2;
+  grub_uint16_t pad;
+} __attribute__((packed));
+
+struct grub_scsi_write12
+{
+  grub_uint8_t opcode;
+  grub_uint8_t lun;
+  grub_uint32_t lba;
+  grub_uint32_t size;
+  grub_uint8_t reserved;
+  grub_uint8_t control;
+} __attribute__((packed));
+
+typedef enum
+  {
+    grub_scsi_cmd_inquiry = 0x12,
+    grub_scsi_cmd_read_capacity = 0x25,
+    grub_scsi_cmd_read10 = 0x28,
+    grub_scsi_cmd_write10 = 0x2a,
+    grub_scsi_cmd_read12 = 0xa8,
+    grub_scsi_cmd_write12 = 0xaa
+  } grub_scsi_cmd_t;
+
+typedef enum
+  {
+    grub_scsi_devtype_direct = 0x00,
+    grub_scsi_devtype_cdrom = 0x05
+  } grub_scsi_devtype_t;
+
+#endif /* GRUB_SCSICMD_H */
diff --git a/grub-core/include/grub/sdl.h b/grub-core/include/grub/sdl.h
new file mode 100644 (file)
index 0000000..e4efdc9
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+void EXPORT_FUNC (SDL_Quit) (void);
+void EXPORT_FUNC (SDL_SetColors) (void);
+void EXPORT_FUNC (SDL_Init) (void);
+void EXPORT_FUNC (SDL_GetError) (void);
+void EXPORT_FUNC (SDL_Flip) (void);
+void EXPORT_FUNC (SDL_SetVideoMode) (void);
diff --git a/grub-core/include/grub/search.h b/grub-core/include/grub/search.h
new file mode 100644 (file)
index 0000000..e8f9db2
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SEARCH_HEADER
+#define GRUB_SEARCH_HEADER 1
+
+void grub_search_fs_file (const char *key, const char *var, int no_floppy);
+void grub_search_fs_uuid (const char *key, const char *var, int no_floppy);
+void grub_search_label (const char *key, const char *var, int no_floppy);
+
+#endif
diff --git a/grub-core/include/grub/serial.h b/grub-core/include/grub/serial.h
new file mode 100644 (file)
index 0000000..1c35b40
--- /dev/null
@@ -0,0 +1,67 @@
+/* serial.h - serial device interface */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SERIAL_HEADER
+#define GRUB_SERIAL_HEADER     1
+
+/* Macros.  */
+
+/* The offsets of UART registers.  */
+#define UART_TX                0
+#define UART_RX                0
+#define UART_DLL       0
+#define UART_IER       1
+#define UART_DLH       1
+#define UART_IIR       2
+#define UART_FCR       2
+#define UART_LCR       3
+#define UART_MCR       4
+#define UART_LSR       5
+#define UART_MSR       6
+#define UART_SR                7
+
+/* For LSR bits.  */
+#define UART_DATA_READY                0x01
+#define UART_EMPTY_TRANSMITTER 0x20
+
+/* The type of parity.  */
+#define UART_NO_PARITY         0x00
+#define UART_ODD_PARITY                0x08
+#define UART_EVEN_PARITY       0x18
+
+/* The type of word length.  */
+#define UART_5BITS_WORD        0x00
+#define UART_6BITS_WORD        0x01
+#define UART_7BITS_WORD        0x02
+#define UART_8BITS_WORD        0x03
+
+/* The type of the length of stop bit.  */
+#define UART_1_STOP_BIT                0x00
+#define UART_2_STOP_BITS       0x04
+
+/* the switch of DLAB.  */
+#define UART_DLAB      0x80
+
+/* Enable the FIFO.  */
+#define UART_ENABLE_FIFO       0xC7
+
+/* Turn on DTR, RTS, and OUT2.  */
+#define UART_ENABLE_MODEM      0x0B
+
+#endif /* ! GRUB_SERIAL_MACHINE_HEADER */
diff --git a/grub-core/include/grub/setjmp.h b/grub-core/include/grub/setjmp.h
new file mode 100644 (file)
index 0000000..70147a7
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SETJMP_HEADER
+#define GRUB_SETJMP_HEADER     1
+
+#if defined(GRUB_UTIL) && !defined(GRUBOF)
+#include <setjmp.h>
+typedef jmp_buf grub_jmp_buf;
+#define grub_setjmp setjmp
+#define grub_longjmp longjmp
+#else
+/* This must define grub_jmp_buf, and declare grub_setjmp and
+   grub_longjmp.  */
+# include <grub/cpu/setjmp.h>
+#endif
+
+#endif /* ! GRUB_SETJMP_HEADER */
diff --git a/grub-core/include/grub/sparc64/ieee1275/boot.h b/grub-core/include/grub/sparc64/ieee1275/boot.h
new file mode 100644 (file)
index 0000000..9671c69
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009   Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_BOOT_MACHINE_HEADER
+#define GRUB_BOOT_MACHINE_HEADER       1
+
+#define CIF_REG                                %l0
+#define CHOSEN_NODE_REG                        %l4
+#define STDOUT_NODE_REG                        %l5
+#define BOOTDEV_REG                    %l6
+#define PIC_REG                                %l7
+
+#define        SCRATCH_PAD_BOOT                0x5000
+#define        SCRATCH_PAD_DISKBOOT            0x4000
+
+#define GET_ABS(symbol, reg)   \
+       add     PIC_REG, (symbol - pic_base), reg
+#define LDUW_ABS(symbol, offset, reg)  \
+       lduw    [PIC_REG + (symbol - pic_base) + (offset)], reg
+#define LDX_ABS(symbol, offset, reg)   \
+       ldx     [PIC_REG + (symbol - pic_base) + (offset)], reg
+
+#define GRUB_BOOT_AOUT_HEADER_SIZE     32
+
+#define GRUB_BOOT_MACHINE_SIGNATURE    0xbb44aa55
+
+#define GRUB_BOOT_MACHINE_VER_MAJ      0x08
+
+#define GRUB_BOOT_MACHINE_BOOT_DEVPATH 0x0a
+
+#define GRUB_BOOT_MACHINE_BOOT_DEVPATH_END 0x80
+
+#define GRUB_BOOT_MACHINE_KERNEL_BYTE 0x80
+
+#define GRUB_BOOT_MACHINE_CODE_END \
+       (0x1fc - GRUB_BOOT_AOUT_HEADER_SIZE)
+
+#define GRUB_BOOT_MACHINE_LIST_SIZE    12
+
+#define GRUB_BOOT_MACHINE_IMAGE_ADDRESS        0x4400
+
+#define GRUB_BOOT_MACHINE_KERNEL_ADDR 0x4200
+
+#endif /* ! BOOT_MACHINE_HEADER */
diff --git a/grub-core/include/grub/sparc64/ieee1275/console.h b/grub-core/include/grub/sparc64/ieee1275/console.h
new file mode 100644 (file)
index 0000000..ed2b720
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_CONSOLE_MACHINE_HEADER
+#define GRUB_CONSOLE_MACHINE_HEADER    1
+
+/* Initialize the console system.  */
+void grub_console_init (void);
+
+/* Finish the console system.  */
+void grub_console_fini (void);
+
+#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */
diff --git a/grub-core/include/grub/sparc64/ieee1275/ieee1275.h b/grub-core/include/grub/sparc64/ieee1275/ieee1275.h
new file mode 100644 (file)
index 0000000..32c77f8
--- /dev/null
@@ -0,0 +1,48 @@
+/* ieee1275.h - Access the Open Firmware client interface.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_IEEE1275_MACHINE_HEADER
+#define GRUB_IEEE1275_MACHINE_HEADER   1
+
+#include <grub/types.h>
+
+#define GRUB_IEEE1275_CELL_SIZEOF 8
+typedef grub_uint64_t grub_ieee1275_cell_t;
+
+/* Encoding of 'mode' argument to grub_ieee1275_map_physical() */
+#define IEEE1275_MAP_WRITE     0x0001 /* Writable */
+#define IEEE1275_MAP_READ      0x0002 /* Readable */
+#define IEEE1275_MAP_EXEC      0x0004 /* Executable */
+#define IEEE1275_MAP_LOCKED    0x0010 /* Locked in TLB */
+#define IEEE1275_MAP_CACHED    0x0020 /* Cacheable */
+#define IEEE1275_MAP_SE                0x0040 /* Side-effects */
+#define IEEE1275_MAP_GLOBAL    0x0080 /* Global */
+#define IEEE1275_MAP_IE                0x0100 /* Invert Endianness */
+#define IEEE1275_MAP_DEFAULT   (IEEE1275_MAP_WRITE | IEEE1275_MAP_READ | \
+                                IEEE1275_MAP_EXEC | IEEE1275_MAP_CACHED)
+
+extern int EXPORT_FUNC(grub_ieee1275_claim_vaddr) (grub_addr_t vaddr,
+                                                  grub_size_t size);
+extern int EXPORT_FUNC(grub_ieee1275_alloc_physmem) (grub_addr_t *paddr,
+                                                    grub_size_t size,
+                                                    grub_uint32_t align);
+
+extern grub_addr_t EXPORT_VAR (grub_ieee1275_original_stack);
+
+#endif /* ! GRUB_IEEE1275_MACHINE_HEADER */
diff --git a/grub-core/include/grub/sparc64/ieee1275/kernel.h b/grub-core/include/grub/sparc64/ieee1275/kernel.h
new file mode 100644 (file)
index 0000000..a16fb88
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_MACHINE_HEADER
+#define GRUB_KERNEL_MACHINE_HEADER     1
+
+#define GRUB_MOD_ALIGN 0x2000
+
+/* Non-zero value is only needed for PowerMacs.  */
+#define GRUB_MOD_GAP 0x0
+
+/* The offset of GRUB_TOTAL_MODULE_SIZE.  */
+#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE  0x8
+
+/* The offset of GRUB_KERNEL_IMAGE_SIZE.  */
+#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE  0xc
+
+/* The offset of GRUB_COMPRESSED_SIZE.  */
+#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE    0x10
+
+/* The offset of GRUB_PREFIX.  */
+#define GRUB_KERNEL_MACHINE_PREFIX             0x14
+
+/* End of the data section. */
+#define GRUB_KERNEL_MACHINE_DATA_END           0x114
+
+#define GRUB_KERNEL_MACHINE_RAW_SIZE                   0
+#define GRUB_KERNEL_MACHINE_STACK_SIZE          0x40000
+
+#define GRUB_PLATFORM_IMAGE_FORMATS     "raw, aout"
+#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT     "raw"
+
+#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW
+
+#ifndef ASM_FILE
+
+typedef enum {
+  GRUB_PLATFORM_IMAGE_RAW,
+  GRUB_PLATFORM_IMAGE_AOUT
+}
+  grub_platform_image_format_t;
+#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW
+#define GRUB_PLATFORM_IMAGE_AOUT GRUB_PLATFORM_IMAGE_AOUT
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+/* The size of kernel image.  */
+extern grub_int32_t grub_kernel_image_size;
+
+/* The total size of module images following the kernel.  */
+extern grub_int32_t grub_total_module_size;
+
+/* The prefix which points to the directory where GRUB modules and its
+   configuration file are located.  */
+extern char grub_prefix[];
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/grub-core/include/grub/sparc64/ieee1275/loader.h b/grub-core/include/grub/sparc64/ieee1275/loader.h
new file mode 100644 (file)
index 0000000..12bb2a6
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER     1
+
+/* The symbol shared between the normal mode and rescue mode
+   loader.  */
+void grub_rescue_cmd_linux (int argc, char *argv[]);
+void grub_rescue_cmd_initrd (int argc, char *argv[]);
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/grub-core/include/grub/sparc64/ieee1275/memory.h b/grub-core/include/grub/sparc64/ieee1275/memory.h
new file mode 100644 (file)
index 0000000..25e3100
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MEMORY_MACHINE_HEADER
+#define GRUB_MEMORY_MACHINE_HEADER     1
+
+#include <grub/ieee1275/ieee1275.h>
+
+#define GRUB_MACHINE_MEMORY_AVAILABLE          1
+
+#endif
diff --git a/grub-core/include/grub/sparc64/ieee1275/time.h b/grub-core/include/grub/sparc64/ieee1275/time.h
new file mode 100644 (file)
index 0000000..3f8ad26
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_MACHINE_TIME_HEADER
+#define KERNEL_MACHINE_TIME_HEADER     1
+
+#include <grub/symbol.h>
+
+#define GRUB_TICKS_PER_SECOND  1000
+
+/* Return the real time in ticks.  */
+grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
+
+#endif /* ! KERNEL_MACHINE_TIME_HEADER */
diff --git a/grub-core/include/grub/sparc64/kernel.h b/grub-core/include/grub/sparc64/kernel.h
new file mode 100644 (file)
index 0000000..9f404b0
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_CPU_HEADER
+#define GRUB_KERNEL_CPU_HEADER 1
+
+#define GRUB_MOD_ALIGN 0x2000
+
+/* Non-zero value is only needed for PowerMacs.  */
+#define GRUB_MOD_GAP 0x0
+
+#define GRUB_KERNEL_CPU_PREFIX 0x2
+#define GRUB_KERNEL_CPU_DATA_END       0x42
+
+#endif
diff --git a/grub-core/include/grub/sparc64/setjmp.h b/grub-core/include/grub/sparc64/setjmp.h
new file mode 100644 (file)
index 0000000..6096bae
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SETJMP_CPU_HEADER
+#define GRUB_SETJMP_CPU_HEADER 1
+
+#include <grub/types.h>
+
+typedef grub_uint64_t grub_jmp_buf[3];
+
+int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice));
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
+
+#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/grub-core/include/grub/sparc64/time.h b/grub-core/include/grub/sparc64/time.h
new file mode 100644 (file)
index 0000000..5db7ff4
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_TIME_HEADER
+#define KERNEL_CPU_TIME_HEADER 1
+
+static __inline void
+grub_cpu_idle (void)
+{
+  /* FIXME: not implemented */
+}
+
+#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/grub-core/include/grub/sparc64/types.h b/grub-core/include/grub/sparc64/types.h
new file mode 100644 (file)
index 0000000..b9b0cf9
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER  1
+
+/* The size of void *.  */
+#define GRUB_TARGET_SIZEOF_VOID_P      8
+
+/* The size of long.  */
+#define GRUB_TARGET_SIZEOF_LONG                8
+
+/* sparc64 is big-endian.  */
+#define GRUB_TARGET_WORDS_BIGENDIAN    1
+
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/grub-core/include/grub/symbol.h b/grub-core/include/grub/symbol.h
new file mode 100644 (file)
index 0000000..63ed194
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SYMBOL_HEADER
+#define GRUB_SYMBOL_HEADER     1
+
+#include <config.h>
+
+/* Apple assembler requires local labels to start with a capital L */
+#define LOCAL(sym)     L_ ## sym
+
+/* Add an underscore to a C symbol in assembler code if needed. */
+#ifdef HAVE_ASM_USCORE
+# define EXT_C(sym)    _ ## sym
+#else
+# define EXT_C(sym)    sym
+#endif
+
+#if defined (APPLE_CC)
+#define FUNCTION(x)    .globl EXT_C(x) ; EXT_C(x):
+#define VARIABLE(x)    .globl EXT_C(x) ; EXT_C(x):
+#elif ! defined (__CYGWIN__) && ! defined (__MINGW32__)
+#define FUNCTION(x)    .globl EXT_C(x) ; .type EXT_C(x), "function" ; EXT_C(x):
+#define VARIABLE(x)    .globl EXT_C(x) ; .type EXT_C(x), "object" ; EXT_C(x):
+#else
+/* .type not supported for non-ELF targets.  XXX: Check this in configure? */
+#define FUNCTION(x)    .globl EXT_C(x) ; .def EXT_C(x); .scl 2; .type 32; .endef; EXT_C(x):
+#define VARIABLE(x)    .globl EXT_C(x) ; .def EXT_C(x); .scl 2; .type 0; .endef; EXT_C(x):
+#endif
+
+/* Mark an exported symbol.  */
+#ifndef GRUB_SYMBOL_GENERATOR
+# define EXPORT_FUNC(x)        x
+# define EXPORT_VAR(x) x
+#endif /* ! GRUB_SYMBOL_GENERATOR */
+
+#endif /* ! GRUB_SYMBOL_HEADER */
diff --git a/grub-core/include/grub/term.h b/grub-core/include/grub/term.h
new file mode 100644 (file)
index 0000000..143aabe
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TERM_HEADER
+#define GRUB_TERM_HEADER       1
+
+/* Internal codes used by GRUB to represent terminal input.  */
+#define GRUB_TERM_LEFT         2
+#define GRUB_TERM_RIGHT                6
+#define GRUB_TERM_UP           16
+#define GRUB_TERM_DOWN         14
+#define GRUB_TERM_HOME         1
+#define GRUB_TERM_END          5
+#define GRUB_TERM_DC           4
+#define GRUB_TERM_PPAGE                7
+#define GRUB_TERM_NPAGE                3
+#define GRUB_TERM_ESC          '\e'
+#define GRUB_TERM_TAB          '\t'
+#define GRUB_TERM_BACKSPACE    8
+
+#ifndef ASM_FILE
+
+#include <grub/err.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/handler.h>
+
+/* These are used to represent the various color states we use.  */
+typedef enum
+  {
+    /* The color used to display all text that does not use the
+       user defined colors below.  */
+    GRUB_TERM_COLOR_STANDARD,
+    /* The user defined colors for normal text.  */
+    GRUB_TERM_COLOR_NORMAL,
+    /* The user defined colors for highlighted text.  */
+    GRUB_TERM_COLOR_HIGHLIGHT
+  }
+grub_term_color_state;
+
+/* Flags for representing the capabilities of a terminal.  */
+/* Some notes about the flags:
+   - These flags are used by higher-level functions but not terminals
+   themselves.
+   - If a terminal is dumb, you may assume that only putchar, getkey and
+   checkkey are called.
+   - Some fancy features (setcolorstate, setcolor and setcursor) can be set
+   to NULL.  */
+
+/* Set when input characters shouldn't be echoed back.  */
+#define GRUB_TERM_NO_ECHO      (1 << 0)
+/* Set when the editing feature should be disabled.  */
+#define GRUB_TERM_NO_EDIT      (1 << 1)
+/* Set when the terminal cannot do fancy things.  */
+#define GRUB_TERM_DUMB         (1 << 2)
+
+
+/* Bitmasks for modifier keys returned by grub_getkeystatus.  */
+#define GRUB_TERM_STATUS_SHIFT (1 << 0)
+#define GRUB_TERM_STATUS_CTRL  (1 << 1)
+#define GRUB_TERM_STATUS_ALT   (1 << 2)
+
+
+/* Unicode characters for fancy graphics.  */
+#define GRUB_TERM_DISP_LEFT    0x2190
+#define GRUB_TERM_DISP_UP      0x2191
+#define GRUB_TERM_DISP_RIGHT   0x2192
+#define GRUB_TERM_DISP_DOWN    0x2193
+#define GRUB_TERM_DISP_HLINE   0x2501
+#define GRUB_TERM_DISP_VLINE   0x2503
+#define GRUB_TERM_DISP_UL      0x250F
+#define GRUB_TERM_DISP_UR      0x2513
+#define GRUB_TERM_DISP_LL      0x2517
+#define GRUB_TERM_DISP_LR      0x251B
+
+
+/* Menu-related geometrical constants.  */
+
+/* The number of lines of "GRUB version..." at the top.  */
+#define GRUB_TERM_INFO_HEIGHT  1
+
+/* The number of columns/lines between messages/borders/etc.  */
+#define GRUB_TERM_MARGIN       1
+
+/* The number of columns of scroll information.  */
+#define GRUB_TERM_SCROLL_WIDTH 1
+
+/* The Y position of the top border.  */
+#define GRUB_TERM_TOP_BORDER_Y (GRUB_TERM_MARGIN + GRUB_TERM_INFO_HEIGHT \
+                                 + GRUB_TERM_MARGIN)
+
+/* The X position of the left border.  */
+#define GRUB_TERM_LEFT_BORDER_X        GRUB_TERM_MARGIN
+
+/* The number of lines of messages at the bottom.  */
+#define GRUB_TERM_MESSAGE_HEIGHT       8
+
+/* The Y position of the first entry.  */
+#define GRUB_TERM_FIRST_ENTRY_Y        (GRUB_TERM_TOP_BORDER_Y + 1)
+
+struct grub_term_input
+{
+  /* The next terminal.  */
+  struct grub_term_input *next;
+
+  /* The terminal name.  */
+  const char *name;
+
+  /* Initialize the terminal.  */
+  grub_err_t (*init) (void);
+
+  /* Clean up the terminal.  */
+  grub_err_t (*fini) (void);
+
+  /* Check if any input character is available.  */
+  int (*checkkey) (void);
+
+  /* Get a character.  */
+  int (*getkey) (void);
+
+  /* Get keyboard modifier status.  */
+  int (*getkeystatus) (void);
+};
+typedef struct grub_term_input *grub_term_input_t;
+
+struct grub_term_output
+{
+  /* The next terminal.  */
+  struct grub_term_output *next;
+
+  /* The terminal name.  */
+  const char *name;
+
+  /* Initialize the terminal.  */
+  grub_err_t (*init) (void);
+
+  /* Clean up the terminal.  */
+  grub_err_t (*fini) (void);
+
+  /* Put a character. C is encoded in Unicode.  */
+  void (*putchar) (grub_uint32_t c);
+
+  /* Get the number of columns occupied by a given character C. C is
+     encoded in Unicode.  */
+  grub_ssize_t (*getcharwidth) (grub_uint32_t c);
+
+  /* Get the screen size. The return value is ((Width << 8) | Height).  */
+  grub_uint16_t (*getwh) (void);
+
+  /* Get the cursor position. The return value is ((X << 8) | Y).  */
+  grub_uint16_t (*getxy) (void);
+
+  /* Go to the position (X, Y).  */
+  void (*gotoxy) (grub_uint8_t x, grub_uint8_t y);
+
+  /* Clear the screen.  */
+  void (*cls) (void);
+
+  /* Set the current color to be used */
+  void (*setcolorstate) (grub_term_color_state state);
+
+  /* Set the normal color and the highlight color. The format of each
+     color is VGA's.  */
+  void (*setcolor) (grub_uint8_t normal_color, grub_uint8_t highlight_color);
+
+  /* Get the normal color and the highlight color. The format of each
+     color is VGA's.  */
+  void (*getcolor) (grub_uint8_t *normal_color, grub_uint8_t *highlight_color);
+
+  /* Turn on/off the cursor.  */
+  void (*setcursor) (int on);
+
+  /* Update the screen.  */
+  void (*refresh) (void);
+
+  /* The feature flags defined above.  */
+  grub_uint32_t flags;
+};
+typedef struct grub_term_output *grub_term_output_t;
+
+extern struct grub_term_output *EXPORT_VAR(grub_term_outputs_disabled);
+extern struct grub_term_input *EXPORT_VAR(grub_term_inputs_disabled);
+extern struct grub_term_output *EXPORT_VAR(grub_term_outputs);
+extern struct grub_term_input *EXPORT_VAR(grub_term_inputs);
+
+static inline void
+grub_term_register_input (const char *name __attribute__ ((unused)),
+                         grub_term_input_t term)
+{
+  if (grub_term_inputs)
+    grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
+                   GRUB_AS_LIST (term));
+  else
+    {
+      /* If this is the first terminal, enable automatically.  */
+      if (! term->init || term->init () == GRUB_ERR_NONE)
+       grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term));
+    }
+}
+
+static inline void
+grub_term_register_output (const char *name __attribute__ ((unused)),
+                          grub_term_output_t term)
+{
+  if (grub_term_outputs)
+    grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
+                   GRUB_AS_LIST (term));
+  else
+    {
+      /* If this is the first terminal, enable automatically.  */
+      if (! term->init || term->init () == GRUB_ERR_NONE)
+       grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
+                       GRUB_AS_LIST (term));
+    }
+}
+
+static inline void
+grub_term_unregister_input (grub_term_input_t term)
+{
+  grub_list_remove (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term));
+  grub_list_remove (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
+                   GRUB_AS_LIST (term));
+}
+
+static inline void
+grub_term_unregister_output (grub_term_output_t term)
+{
+  grub_list_remove (GRUB_AS_LIST_P (&grub_term_outputs), GRUB_AS_LIST (term));
+  grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
+                   GRUB_AS_LIST (term));
+}
+
+#define FOR_ACTIVE_TERM_INPUTS(var) for (var = grub_term_inputs; var; var = var->next)
+#define FOR_DISABLED_TERM_INPUTS(var) for (var = grub_term_inputs_disabled; var; var = var->next)
+#define FOR_ACTIVE_TERM_OUTPUTS(var) for (var = grub_term_outputs; var; var = var->next)
+#define FOR_DISABLED_TERM_OUTPUTS(var) for (var = grub_term_outputs_disabled; var; var = var->next)
+
+void EXPORT_FUNC(grub_putchar) (int c);
+void EXPORT_FUNC(grub_putcode) (grub_uint32_t code,
+                               struct grub_term_output *term);
+int EXPORT_FUNC(grub_getkey) (void);
+int EXPORT_FUNC(grub_checkkey) (void);
+int EXPORT_FUNC(grub_getkeystatus) (void);
+void EXPORT_FUNC(grub_cls) (void);
+void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state);
+void EXPORT_FUNC(grub_refresh) (void);
+void grub_puts_terminal (const char *str, struct grub_term_output *term);
+grub_uint16_t *grub_term_save_pos (void);
+void grub_term_restore_pos (grub_uint16_t *pos);
+
+static inline unsigned grub_term_width (struct grub_term_output *term)
+{
+  return ((term->getwh()&0xFF00)>>8);
+}
+
+static inline unsigned grub_term_height (struct grub_term_output *term)
+{
+  return (term->getwh()&0xFF);
+}
+
+/* The width of the border.  */
+static inline unsigned
+grub_term_border_width (struct grub_term_output *term)
+{
+  return grub_term_width (term) - GRUB_TERM_MARGIN * 3 - GRUB_TERM_SCROLL_WIDTH;
+}
+
+/* The max column number of an entry. The last "-1" is for a
+   continuation marker.  */
+static inline int
+grub_term_entry_width (struct grub_term_output *term)
+{
+  return grub_term_border_width (term) - 2 - GRUB_TERM_MARGIN * 2 - 1;
+}
+
+/* The height of the border.  */
+
+static inline unsigned
+grub_term_border_height (struct grub_term_output *term)
+{
+  return grub_term_height (term) - GRUB_TERM_TOP_BORDER_Y
+    - GRUB_TERM_MESSAGE_HEIGHT;
+}
+
+/* The number of entries shown at a time.  */
+static inline int
+grub_term_num_entries (struct grub_term_output *term)
+{
+  return grub_term_border_height (term) - 2;
+}
+
+static inline int
+grub_term_cursor_x (struct grub_term_output *term)
+{
+  return (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term) 
+         - GRUB_TERM_MARGIN - 1);
+}
+
+static inline grub_uint16_t
+grub_term_getxy (struct grub_term_output *term)
+{
+  return term->getxy ();
+}
+
+static inline void
+grub_term_refresh (struct grub_term_output *term)
+{
+  if (term->refresh)
+    term->refresh ();
+}
+
+static inline void
+grub_term_gotoxy (struct grub_term_output *term, grub_uint8_t x, grub_uint8_t y)
+{
+  term->gotoxy (x, y);
+}
+
+static inline void 
+grub_term_setcolorstate (struct grub_term_output *term, 
+                        grub_term_color_state state)
+{
+  if (term->setcolorstate)
+    term->setcolorstate (state);
+}
+
+  /* Set the normal color and the highlight color. The format of each
+     color is VGA's.  */
+static inline void 
+grub_term_setcolor (struct grub_term_output *term,
+                   grub_uint8_t normal_color, grub_uint8_t highlight_color)
+{
+  if (term->setcolor)
+    term->setcolor (normal_color, highlight_color);
+}
+
+/* Turn on/off the cursor.  */
+static inline void 
+grub_term_setcursor (struct grub_term_output *term, int on)
+{
+  if (term->setcursor)
+    term->setcursor (on);
+}
+
+static inline void 
+grub_term_cls (struct grub_term_output *term)
+{
+  if (term->cls)
+    (term->cls) ();
+  else
+    {
+      grub_putcode ('\n', term);
+      grub_term_refresh (term);
+    }
+}
+
+static inline grub_ssize_t 
+grub_term_getcharwidth (struct grub_term_output *term, grub_uint32_t c)
+{
+  if (term->getcharwidth)
+    return term->getcharwidth (c);
+  else
+    return 1;
+}
+
+static inline void 
+grub_term_getcolor (struct grub_term_output *term, 
+                   grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
+{
+  if (term->getcolor)
+    term->getcolor (normal_color, highlight_color);
+  else
+    {
+      *normal_color = 0x07;
+      *highlight_color = 0x07;
+    }
+}
+
+extern void (*EXPORT_VAR (grub_newline_hook)) (void);
+
+struct grub_term_autoload
+{
+  struct grub_term_autoload *next;
+  char *name;
+  char *modname;
+};
+
+extern struct grub_term_autoload *grub_term_input_autoload;
+extern struct grub_term_autoload *grub_term_output_autoload;
+
+static inline void
+grub_print_spaces (struct grub_term_output *term, int number_spaces)
+{
+  while (--number_spaces >= 0)
+    grub_putcode (' ', term);
+}
+
+
+/* For convenience.  */
+#define GRUB_TERM_ASCII_CHAR(c)        ((c) & 0xff)
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! GRUB_TERM_HEADER */
diff --git a/grub-core/include/grub/terminfo.h b/grub-core/include/grub/terminfo.h
new file mode 100644 (file)
index 0000000..e3a2c17
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TERMINFO_HEADER
+#define GRUB_TERMINFO_HEADER   1
+
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/term.h>
+
+char *grub_terminfo_get_current (void);
+grub_err_t grub_terminfo_set_current (const char *);
+
+void grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y,
+                          grub_term_output_t oterm);
+void grub_terminfo_cls (grub_term_output_t oterm);
+void grub_terminfo_reverse_video_on (grub_term_output_t oterm);
+void grub_terminfo_reverse_video_off (grub_term_output_t oterm);
+void grub_terminfo_cursor_on (grub_term_output_t oterm);
+void grub_terminfo_cursor_off (grub_term_output_t oterm);
+
+#endif /* ! GRUB_TERMINFO_HEADER */
diff --git a/grub-core/include/grub/test.h b/grub-core/include/grub/test.h
new file mode 100644 (file)
index 0000000..336d3b6
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TEST_HEADER
+#define GRUB_TEST_HEADER
+
+#include <grub/dl.h>
+#include <grub/list.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+struct grub_test
+{
+  /* The next test.  */
+  struct grub_test *next;
+
+  /* The test name.  */
+  char *name;
+
+  /* The test main function.  */
+  void (*main) (void);
+};
+typedef struct grub_test *grub_test_t;
+
+extern grub_test_t grub_test_list;
+
+void grub_test_register   (const char *name, void (*test) (void));
+void grub_test_unregister (const char *name);
+
+/* Execute a test and print results.  */
+int grub_test_run (grub_test_t test);
+
+/* Test `cond' for nonzero; log failure otherwise.  */
+void grub_test_nonzero (int cond, const char *file,
+                       const char *func, grub_uint32_t line,
+                       const char *fmt, ...)
+  __attribute__ ((format (printf, 5, 6)));
+
+/* Macro to fill in location details and an optional error message.  */
+#define grub_test_assert(cond, ...)                            \
+  grub_test_nonzero(cond, GRUB_FILE, __FUNCTION__, __LINE__,   \
+                   ## __VA_ARGS__,                             \
+                   "assert failed: %s", #cond)
+
+/* Macro to define a unit test.  */
+#define GRUB_UNIT_TEST(name, funp)             \
+  void grub_unit_test_init (void)              \
+  {                                            \
+    grub_test_register (name, funp);           \
+  }                                            \
+                                               \
+  void grub_unit_test_fini (void)              \
+  {                                            \
+    grub_test_unregister (name);               \
+  }
+
+/* Macro to define a functional test.  */
+#define GRUB_FUNCTIONAL_TEST(name, funp)       \
+  GRUB_MOD_INIT(name)                          \
+  {                                            \
+    grub_test_register (#name, funp);          \
+  }                                            \
+                                               \
+  GRUB_MOD_FINI(name)                          \
+  {                                            \
+    grub_test_unregister (#name);              \
+  }
+
+#endif /* ! GRUB_TEST_HEADER */
diff --git a/grub-core/include/grub/time.h b/grub-core/include/grub/time.h
new file mode 100644 (file)
index 0000000..ae2617e
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007, 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_TIME_HEADER
+#define KERNEL_TIME_HEADER     1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/cpu/time.h>
+
+#if defined (GRUB_MACHINE_EMU) || defined (GRUB_UTIL)
+#define GRUB_TICKS_PER_SECOND 100000
+/* Return the real time in ticks.  */
+grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
+#else
+#include <grub/machine/time.h>
+#endif
+
+void EXPORT_FUNC(grub_millisleep) (grub_uint32_t ms);
+grub_uint64_t EXPORT_FUNC(grub_get_time_ms) (void);
+
+grub_uint64_t grub_rtc_get_time_ms (void);
+
+static __inline void
+grub_sleep (grub_uint32_t s)
+{
+  grub_millisleep (1000 * s);
+}
+
+void grub_install_get_time_ms (grub_uint64_t (*get_time_ms_func) (void));
+
+#endif /* ! KERNEL_TIME_HEADER */
diff --git a/grub-core/include/grub/tparm.h b/grub-core/include/grub/tparm.h
new file mode 100644 (file)
index 0000000..642a22f
--- /dev/null
@@ -0,0 +1,26 @@
+/* tparm.h - parameter formatting of terminfo */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TPARM_HEADER
+#define GRUB_TPARM_HEADER      1
+
+/* Function prototypes.  */
+char *grub_terminfo_tparm (const char *string, ...);
+
+#endif /* ! GRUB_TPARM_HEADER */
diff --git a/grub-core/include/grub/trig.h b/grub-core/include/grub/trig.h
new file mode 100644 (file)
index 0000000..2512a5f
--- /dev/null
@@ -0,0 +1,44 @@
+/* trig.h - Trigonometric function support.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TRIG_HEADER
+#define GRUB_TRIG_HEADER 1
+
+#define GRUB_TRIG_ANGLE_MAX 256
+#define GRUB_TRIG_ANGLE_MASK 255
+#define GRUB_TRIG_FRACTION_SCALE 16384
+
+extern short grub_trig_sintab[];
+extern short grub_trig_costab[];
+
+static __inline int
+grub_sin (int x)
+{
+  x &= GRUB_TRIG_ANGLE_MASK;
+  return grub_trig_sintab[x];
+}
+
+static __inline int
+grub_cos (int x)
+{
+  x &= GRUB_TRIG_ANGLE_MASK;
+  return grub_trig_costab[x];
+}
+
+#endif /* ! GRUB_TRIG_HEADER */
diff --git a/grub-core/include/grub/types.h b/grub-core/include/grub/types.h
new file mode 100644 (file)
index 0000000..9eaafd0
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_HEADER
+#define GRUB_TYPES_HEADER      1
+
+#include <config.h>
+#include <grub/cpu/types.h>
+
+#ifdef GRUB_UTIL
+# define GRUB_CPU_SIZEOF_VOID_P        SIZEOF_VOID_P
+# define GRUB_CPU_SIZEOF_LONG  SIZEOF_LONG
+# ifdef WORDS_BIGENDIAN
+#  define GRUB_CPU_WORDS_BIGENDIAN     1
+# else
+#  undef GRUB_CPU_WORDS_BIGENDIAN
+# endif
+#else /* ! GRUB_UTIL */
+# define GRUB_CPU_SIZEOF_VOID_P        GRUB_TARGET_SIZEOF_VOID_P
+# define GRUB_CPU_SIZEOF_LONG  GRUB_TARGET_SIZEOF_LONG
+# ifdef GRUB_TARGET_WORDS_BIGENDIAN
+#  define GRUB_CPU_WORDS_BIGENDIAN     1
+# else
+#  undef GRUB_CPU_WORDS_BIGENDIAN
+# endif
+#endif /* ! GRUB_UTIL */
+
+#if GRUB_CPU_SIZEOF_VOID_P != GRUB_CPU_SIZEOF_LONG
+# error "This architecture is not supported because sizeof(void *) != sizeof(long)"
+#endif
+
+#if GRUB_CPU_SIZEOF_VOID_P != 4 && GRUB_CPU_SIZEOF_VOID_P != 8
+# error "This architecture is not supported because sizeof(void *) != 4 and sizeof(void *) != 8"
+#endif
+
+#ifndef GRUB_TARGET_WORDSIZE
+# if GRUB_TARGET_SIZEOF_VOID_P == 4
+#  define GRUB_TARGET_WORDSIZE 32
+# elif GRUB_TARGET_SIZEOF_VOID_P == 8
+#  define GRUB_TARGET_WORDSIZE 64
+# endif
+#endif
+
+/* Define various wide integers.  */
+typedef signed char            grub_int8_t;
+typedef short                  grub_int16_t;
+typedef int                    grub_int32_t;
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+typedef long                   grub_int64_t;
+#else
+typedef long long              grub_int64_t;
+#endif
+
+typedef unsigned char          grub_uint8_t;
+typedef unsigned short         grub_uint16_t;
+typedef unsigned               grub_uint32_t;
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+typedef unsigned long          grub_uint64_t;
+#else
+typedef unsigned long long     grub_uint64_t;
+#endif
+
+/* Misc types.  */
+#if GRUB_TARGET_SIZEOF_VOID_P == 8
+typedef grub_uint64_t  grub_target_addr_t;
+typedef grub_uint64_t  grub_target_off_t;
+typedef grub_uint64_t  grub_target_size_t;
+typedef grub_int64_t   grub_target_ssize_t;
+#else
+typedef grub_uint32_t  grub_target_addr_t;
+typedef grub_uint32_t  grub_target_off_t;
+typedef grub_uint32_t  grub_target_size_t;
+typedef grub_int32_t   grub_target_ssize_t;
+#endif
+
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+typedef grub_uint64_t  grub_addr_t;
+typedef grub_uint64_t  grub_size_t;
+typedef grub_int64_t   grub_ssize_t;
+#else
+typedef grub_uint32_t  grub_addr_t;
+typedef grub_uint32_t  grub_size_t;
+typedef grub_int32_t   grub_ssize_t;
+#endif
+
+#if GRUB_CPU_SIZEOF_VOID_P == 8
+# define GRUB_ULONG_MAX 18446744073709551615UL
+# define GRUB_LONG_MAX 9223372036854775807L
+# define GRUB_LONG_MIN (-9223372036854775807L - 1)
+#else
+# define GRUB_ULONG_MAX 4294967295UL
+# define GRUB_LONG_MAX 2147483647L
+# define GRUB_LONG_MIN (-2147483647L - 1)
+#endif
+
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+#define UINT_TO_PTR(x) ((void*)(grub_uint32_t)(x))
+#define PTR_TO_UINT64(x) ((grub_uint64_t)(grub_uint32_t)(x))
+#define PTR_TO_UINT32(x) ((grub_uint32_t)(x))
+#else
+#define UINT_TO_PTR(x) ((void*)(grub_uint64_t)(x))
+#define PTR_TO_UINT64(x) ((grub_uint64_t)(x))
+#define PTR_TO_UINT32(x) ((grub_uint32_t)(grub_uint64_t)(x))
+#endif
+
+/* The type for representing a file offset.  */
+typedef grub_uint64_t  grub_off_t;
+
+/* The type for representing a disk block address.  */
+typedef grub_uint64_t  grub_disk_addr_t;
+
+/* Byte-orders.  */
+#define grub_swap_bytes16(x)   \
+({ \
+   grub_uint16_t _x = (x); \
+   (grub_uint16_t) ((_x << 8) | (_x >> 8)); \
+})
+
+#if defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)
+static inline grub_uint32_t grub_swap_bytes32(grub_uint32_t x)
+{
+       return __builtin_bswap32(x);
+}
+
+static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x)
+{
+       return __builtin_bswap64(x);
+}
+#else                                  /* not gcc 4.3 or newer */
+#define grub_swap_bytes32(x)   \
+({ \
+   grub_uint32_t _x = (x); \
+   (grub_uint32_t) ((_x << 24) \
+                    | ((_x & (grub_uint32_t) 0xFF00UL) << 8) \
+                    | ((_x & (grub_uint32_t) 0xFF0000UL) >> 8) \
+                    | (_x >> 24)); \
+})
+
+#define grub_swap_bytes64(x)   \
+({ \
+   grub_uint64_t _x = (x); \
+   (grub_uint64_t) ((_x << 56) \
+                    | ((_x & (grub_uint64_t) 0xFF00ULL) << 40) \
+                    | ((_x & (grub_uint64_t) 0xFF0000ULL) << 24) \
+                    | ((_x & (grub_uint64_t) 0xFF000000ULL) << 8) \
+                    | ((_x & (grub_uint64_t) 0xFF00000000ULL) >> 8) \
+                    | ((_x & (grub_uint64_t) 0xFF0000000000ULL) >> 24) \
+                    | ((_x & (grub_uint64_t) 0xFF000000000000ULL) >> 40) \
+                    | (_x >> 56)); \
+})
+#endif                                 /* not gcc 4.3 or newer */
+
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
+# define grub_cpu_to_le16(x)   grub_swap_bytes16(x)
+# define grub_cpu_to_le32(x)   grub_swap_bytes32(x)
+# define grub_cpu_to_le64(x)   grub_swap_bytes64(x)
+# define grub_le_to_cpu16(x)   grub_swap_bytes16(x)
+# define grub_le_to_cpu32(x)   grub_swap_bytes32(x)
+# define grub_le_to_cpu64(x)   grub_swap_bytes64(x)
+# define grub_cpu_to_be16(x)   ((grub_uint16_t) (x))
+# define grub_cpu_to_be32(x)   ((grub_uint32_t) (x))
+# define grub_cpu_to_be64(x)   ((grub_uint64_t) (x))
+# define grub_be_to_cpu16(x)   ((grub_uint16_t) (x))
+# define grub_be_to_cpu32(x)   ((grub_uint32_t) (x))
+# define grub_be_to_cpu64(x)   ((grub_uint64_t) (x))
+# ifdef GRUB_TARGET_WORDS_BIGENDIAN
+#  define grub_target_to_host16(x)     ((grub_uint16_t) (x))
+#  define grub_target_to_host32(x)     ((grub_uint32_t) (x))
+#  define grub_target_to_host64(x)     ((grub_uint64_t) (x))
+#  define grub_host_to_target16(x)     ((grub_uint16_t) (x))
+#  define grub_host_to_target32(x)     ((grub_uint32_t) (x))
+#  define grub_host_to_target64(x)     ((grub_uint64_t) (x))
+# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */
+#  define grub_target_to_host16(x)     grub_swap_bytes16(x)
+#  define grub_target_to_host32(x)     grub_swap_bytes32(x)
+#  define grub_target_to_host64(x)     grub_swap_bytes64(x)
+#  define grub_host_to_target16(x)     grub_swap_bytes16(x)
+#  define grub_host_to_target32(x)     grub_swap_bytes32(x)
+#  define grub_host_to_target64(x)     grub_swap_bytes64(x)
+# endif
+#else /* ! WORDS_BIGENDIAN */
+# define grub_cpu_to_le16(x)   ((grub_uint16_t) (x))
+# define grub_cpu_to_le32(x)   ((grub_uint32_t) (x))
+# define grub_cpu_to_le64(x)   ((grub_uint64_t) (x))
+# define grub_le_to_cpu16(x)   ((grub_uint16_t) (x))
+# define grub_le_to_cpu32(x)   ((grub_uint32_t) (x))
+# define grub_le_to_cpu64(x)   ((grub_uint64_t) (x))
+# define grub_cpu_to_be16(x)   grub_swap_bytes16(x)
+# define grub_cpu_to_be32(x)   grub_swap_bytes32(x)
+# define grub_cpu_to_be64(x)   grub_swap_bytes64(x)
+# define grub_be_to_cpu16(x)   grub_swap_bytes16(x)
+# define grub_be_to_cpu32(x)   grub_swap_bytes32(x)
+# define grub_be_to_cpu64(x)   grub_swap_bytes64(x)
+# ifdef GRUB_TARGET_WORDS_BIGENDIAN
+#  define grub_target_to_host16(x)     grub_swap_bytes16(x)
+#  define grub_target_to_host32(x)     grub_swap_bytes32(x)
+#  define grub_target_to_host64(x)     grub_swap_bytes64(x)
+#  define grub_host_to_target16(x)     grub_swap_bytes16(x)
+#  define grub_host_to_target32(x)     grub_swap_bytes32(x)
+#  define grub_host_to_target64(x)     grub_swap_bytes64(x)
+# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */
+#  define grub_target_to_host16(x)     ((grub_uint16_t) (x))
+#  define grub_target_to_host32(x)     ((grub_uint32_t) (x))
+#  define grub_target_to_host64(x)     ((grub_uint64_t) (x))
+#  define grub_host_to_target16(x)     ((grub_uint16_t) (x))
+#  define grub_host_to_target32(x)     ((grub_uint32_t) (x))
+#  define grub_host_to_target64(x)     ((grub_uint64_t) (x))
+# endif
+#endif /* ! WORDS_BIGENDIAN */
+
+#if GRUB_TARGET_SIZEOF_VOID_P == 8
+#  define grub_host_to_target_addr(x) grub_host_to_target64(x)
+#else
+#  define grub_host_to_target_addr(x) grub_host_to_target32(x)
+#endif
+
+#endif /* ! GRUB_TYPES_HEADER */
diff --git a/grub-core/include/grub/usb.h b/grub-core/include/grub/usb.h
new file mode 100644 (file)
index 0000000..dc90e78
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef        GRUB_USB_H
+#define        GRUB_USB_H      1
+
+#include <grub/usbdesc.h>
+#include <grub/usbtrans.h>
+
+typedef struct grub_usb_device *grub_usb_device_t;
+typedef struct grub_usb_controller *grub_usb_controller_t;
+typedef struct grub_usb_controller_dev *grub_usb_controller_dev_t;
+
+typedef enum
+  {
+    GRUB_USB_ERR_NONE,
+    GRUB_USB_ERR_INTERNAL,
+    GRUB_USB_ERR_STALL,
+    GRUB_USB_ERR_DATA,
+    GRUB_USB_ERR_NAK,
+    GRUB_USB_ERR_BABBLE,
+    GRUB_USB_ERR_TIMEOUT,
+    GRUB_USB_ERR_BITSTUFF
+  } grub_usb_err_t;
+
+typedef enum
+  {
+    GRUB_USB_SPEED_NONE,
+    GRUB_USB_SPEED_LOW,
+    GRUB_USB_SPEED_FULL,
+    GRUB_USB_SPEED_HIGH
+  } grub_usb_speed_t;
+
+/* Call HOOK with each device, until HOOK returns non-zero.  */
+int grub_usb_iterate (int (*hook) (grub_usb_device_t dev));
+
+grub_usb_err_t grub_usb_device_initialize (grub_usb_device_t dev);
+
+grub_usb_err_t grub_usb_get_descriptor (grub_usb_device_t dev,
+                                       grub_uint8_t type, grub_uint8_t index,
+                                       grub_size_t size, char *data);
+
+struct grub_usb_desc_endp *
+grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr);
+
+grub_usb_err_t grub_usb_clear_halt (grub_usb_device_t dev, int endpoint);
+
+
+grub_usb_err_t grub_usb_set_configuration (grub_usb_device_t dev,
+                                          int configuration);
+
+void grub_usb_controller_dev_register (grub_usb_controller_dev_t usb);
+
+void grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb);
+
+int grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev));
+
+
+grub_usb_err_t grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype,
+                                    grub_uint8_t request, grub_uint16_t value,
+                                    grub_uint16_t index, grub_size_t size,
+                                    char *data);
+
+grub_usb_err_t
+grub_usb_bulk_read (grub_usb_device_t dev,
+                   int endpoint, grub_size_t size, char *data);
+grub_usb_err_t
+grub_usb_bulk_write (grub_usb_device_t dev,
+                    int endpoint, grub_size_t size, char *data);
+
+grub_usb_err_t
+grub_usb_root_hub (grub_usb_controller_t controller);
+
+\f
+/* XXX: All handled by libusb for now.  */
+struct grub_usb_controller_dev
+{
+  /* The device name.  */
+  const char *name;
+
+  int (*iterate) (int (*hook) (grub_usb_controller_t dev));
+
+  grub_usb_err_t (*transfer) (grub_usb_controller_t dev,
+                             grub_usb_transfer_t transfer);
+
+  int (*hubports) (grub_usb_controller_t dev);
+
+  grub_err_t (*portstatus) (grub_usb_controller_t dev, unsigned int port,
+                           unsigned int enable);
+
+  grub_usb_speed_t (*detect_dev) (grub_usb_controller_t dev, int port);
+
+  /* The next host controller.  */
+  struct grub_usb_controller_dev *next;
+};
+
+struct grub_usb_controller
+{
+  /* The underlying USB Host Controller device.  */
+  grub_usb_controller_dev_t dev;
+
+  /* Data used by the USB Host Controller Driver.  */
+  void *data;
+};
+\f
+
+struct grub_usb_interface
+{
+  struct grub_usb_desc_if *descif;
+
+  struct grub_usb_desc_endp *descendp;
+};
+
+struct grub_usb_configuration
+{
+  /* Configuration descriptors .  */
+  struct grub_usb_desc_config *descconf;
+
+  /* Interfaces associated to this configuration.  */
+  struct grub_usb_interface interf[32];
+};
+
+struct grub_usb_device
+{
+  /* The device descriptor of this device.  */
+  struct grub_usb_desc_device descdev;
+
+  /* The controller the device is connected to.  */
+  struct grub_usb_controller controller;
+
+  /* Device configurations (after opening the device).  */
+  struct grub_usb_configuration config[8];
+
+  /* Device address.  */
+  int addr;
+
+  /* Device speed.  */
+  grub_usb_speed_t speed;
+
+  /* All descriptors are read if this is set to 1.  */
+  int initialized;
+
+  /* Data toggle values (used for bulk transfers only).  */
+  int toggle[16];
+
+  /* Device-specific data.  */
+  void *data;
+};
+
+\f
+
+typedef enum
+  {
+    GRUB_USB_CLASS_NOTHERE,
+    GRUB_USB_CLASS_AUDIO,
+    GRUB_USB_CLASS_COMMUNICATION,
+    GRUB_USB_CLASS_HID,
+    GRUB_USB_CLASS_XXX,
+    GRUB_USB_CLASS_PHYSICAL,
+    GRUB_USB_CLASS_IMAGE,
+    GRUB_USB_CLASS_PRINTER,
+    GRUB_USB_CLASS_MASS_STORAGE,
+    GRUB_USB_CLASS_HUB,
+    GRUB_USB_CLASS_DATA_INTERFACE,
+    GRUB_USB_CLASS_SMART_CARD,
+    GRUB_USB_CLASS_CONTENT_SECURITY,
+    GRUB_USB_CLASS_VIDEO
+  } grub_usb_classes_t;
+
+typedef enum
+  {
+    GRUB_USBMS_SUBCLASS_BULK = 0x06
+  } grub_usbms_subclass_t;
+
+typedef enum
+  {
+    GRUB_USBMS_PROTOCOL_BULK = 0x50
+  } grub_usbms_protocol_t;
+
+static inline struct grub_usb_desc_if *
+grub_usb_get_config_interface (struct grub_usb_desc_config *config)
+{
+  struct grub_usb_desc_if *interf;
+
+  interf = (struct grub_usb_desc_if *) (sizeof (*config) + (char *) config);
+  return interf;
+}
+
+#endif /* GRUB_USB_H */
diff --git a/grub-core/include/grub/usbdesc.h b/grub-core/include/grub/usbdesc.h
new file mode 100644 (file)
index 0000000..2f711d7
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef        GRUB_USBDESC_H
+#define        GRUB_USBDESC_H  1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+typedef enum {
+  GRUB_USB_DESCRIPTOR_DEVICE = 1,
+  GRUB_USB_DESCRIPTOR_CONFIG,
+  GRUB_USB_DESCRIPTOR_STRING,
+  GRUB_USB_DESCRIPTOR_INTERFACE,
+  GRUB_USB_DESCRIPTOR_ENDPOINT,
+  GRUB_USB_DESCRIPTOR_HUB = 0x29
+} grub_usb_descriptor_t;
+
+struct grub_usb_desc_device
+{
+  grub_uint8_t length;
+  grub_uint8_t type;
+  grub_uint16_t usbrel;
+  grub_uint8_t class;
+  grub_uint8_t subclass;
+  grub_uint8_t protocol;
+  grub_uint8_t maxsize0;
+  grub_uint16_t vendorid;
+  grub_uint16_t prodid;
+  grub_uint16_t devrel;
+  grub_uint8_t strvendor;
+  grub_uint8_t strprod;
+  grub_uint8_t strserial;
+  grub_uint8_t configcnt;
+} __attribute__ ((packed));
+
+struct grub_usb_desc_config
+{
+  grub_uint8_t length;
+  grub_uint8_t type;
+  grub_uint16_t totallen;
+  grub_uint8_t numif;
+  grub_uint8_t config;
+  grub_uint8_t strconfig;
+  grub_uint8_t attrib;
+  grub_uint8_t maxpower;
+} __attribute__ ((packed));
+
+#if 0
+struct grub_usb_desc_if_association
+{
+  grub_uint8_t length;
+  grub_uint8_t type;
+  grub_uint8_t firstif;
+  grub_uint8_t ifcnt;
+  grub_uint8_t class;
+  grub_uint8_t subclass;
+  grub_uint8_t protocol;
+  grub_uint8_t function;
+} __attribute__ ((packed));
+#endif
+
+struct grub_usb_desc_if
+{
+  grub_uint8_t length;
+  grub_uint8_t type;
+  grub_uint8_t ifnum;
+  grub_uint8_t altsetting;
+  grub_uint8_t endpointcnt;
+  grub_uint8_t class;
+  grub_uint8_t subclass;
+  grub_uint8_t protocol;
+  grub_uint8_t strif;
+} __attribute__ ((packed));
+
+struct grub_usb_desc_endp
+{
+  grub_uint8_t length;
+  grub_uint8_t type;
+  grub_uint8_t endp_addr;
+  grub_uint8_t attrib;
+  grub_uint16_t maxpacket;
+  grub_uint8_t interval;
+} __attribute__ ((packed));
+
+struct grub_usb_desc_str
+{
+  grub_uint8_t length;
+  grub_uint8_t type;
+  grub_uint16_t str[0];
+} __attribute__ ((packed));
+
+struct grub_usb_usb_hubdesc
+{
+  grub_uint8_t length;
+  grub_uint8_t type;
+  grub_uint8_t portcnt;
+  grub_uint16_t characteristics;
+  grub_uint8_t pwdgood;
+  grub_uint8_t current;
+  /* Removable and power control bits follow.  */
+} __attribute__ ((packed));
+
+#endif /* GRUB_USBDESC_H */
diff --git a/grub-core/include/grub/usbtrans.h b/grub-core/include/grub/usbtrans.h
new file mode 100644 (file)
index 0000000..7e4a9d7
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef        GRUB_USBTRANS_H
+#define        GRUB_USBTRANS_H 1
+
+typedef enum
+  {
+    GRUB_USB_TRANSFER_TYPE_IN,
+    GRUB_USB_TRANSFER_TYPE_OUT,
+    GRUB_USB_TRANSFER_TYPE_SETUP
+  } grub_transfer_type_t;
+
+typedef enum
+  {
+    GRUB_USB_TRANSACTION_TYPE_CONTROL,
+    GRUB_USB_TRANSACTION_TYPE_BULK
+  } grub_transaction_type_t;
+
+struct grub_usb_transaction
+{
+  int size;
+  int toggle;
+  grub_transfer_type_t pid;
+  char *data;
+};
+typedef struct grub_usb_transaction *grub_usb_transaction_t;
+
+struct grub_usb_transfer
+{
+  int devaddr;
+
+  int endpoint;
+
+  int size;
+
+  int transcnt;
+
+  int max;
+
+  grub_transaction_type_t type;
+
+  struct grub_usb_device *dev;
+
+  struct grub_usb_transaction *transactions;
+};
+typedef struct grub_usb_transfer *grub_usb_transfer_t;
+
+\f
+#define GRUB_USB_REQTYPE_IN            (1 << 7)
+#define GRUB_USB_REQTYPE_OUT           (0 << 7)
+#define GRUB_USB_REQTYPE_STANDARD      (0 << 5)
+#define GRUB_USB_REQTYPE_CLASS         (1 << 5)
+#define GRUB_USB_REQTYPE_VENDOR                (2 << 5)
+#define GRUB_USB_REQTYPE_TARGET_DEV    (0 << 0)
+#define GRUB_USB_REQTYPE_TARGET_INTERF (1 << 0)
+#define GRUB_USB_REQTYPE_TARGET_ENDP   (2 << 0)
+#define GRUB_USB_REQTYPE_TARGET_OTHER  (3 << 0)
+
+#define GRUB_USB_REQ_GET_STATUS                0x00
+#define GRUB_USB_REQ_CLEAR_FEATURE     0x01
+#define GRUB_USB_REQ_SET_FEATURE       0x03
+#define GRUB_USB_REQ_SET_ADDRESS       0x05
+#define GRUB_USB_REQ_GET_DESCRIPTOR    0x06
+#define GRUB_USB_REQ_SET_DESCRIPTOR    0x07
+#define GRUB_USB_REQ_GET_CONFIGURATION 0x08
+#define GRUB_USB_REQ_SET_CONFIGURATION 0x09
+#define GRUB_USB_REQ_GET_INTERFACE     0x0A
+#define GRUB_USB_REQ_SET_INTERFACE     0x0B
+#define GRUB_USB_REQ_SYNC_FRAME                0x0C
+
+#define GRUB_USB_REQ_HUB_GET_PORT_STATUS 0x00
+
+#define GRUB_USB_FEATURE_ENDP_HALT     0x01
+#define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x02
+#define GRUB_USB_FEATURE_TEST_MODE     0x04
+
+#define GRUB_USB_HUB_STATUS_CONNECTED  (1 << 0)
+#define GRUB_USB_HUB_STATUS_LOWSPEED   (1 << 9)
+#define GRUB_USB_HUB_STATUS_HIGHSPEED  (1 << 10)
+
+struct grub_usb_packet_setup
+{
+  grub_uint8_t reqtype;
+  grub_uint8_t request;
+  grub_uint16_t value;
+  grub_uint16_t index;
+  grub_uint16_t length;
+} __attribute__((packed));
+
+
+#endif /* GRUB_USBTRANS_H */
diff --git a/grub-core/include/grub/util/deviceiter.h b/grub-core/include/grub/util/deviceiter.h
new file mode 100644 (file)
index 0000000..a8af03c
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef GRUB_DEVICEITER_MACHINE_UTIL_HEADER
+#define GRUB_DEVICEITER_MACHINE_UTIL_HEADER    1
+
+#include <config.h>
+
+void grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
+                               int floppy_disks);
+void grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy,
+                                    int *num_fd, int *num_hd);
+
+#endif /* ! GRUB_DEVICEITER_MACHINE_UTIL_HEADER */
diff --git a/grub-core/include/grub/util/lvm.h b/grub-core/include/grub/util/lvm.h
new file mode 100644 (file)
index 0000000..7a4c76c
--- /dev/null
@@ -0,0 +1,27 @@
+/* lvm.h - LVM support for GRUB utils.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LVM_UTIL_HEADER
+#define GRUB_LVM_UTIL_HEADER   1
+
+#ifdef __linux__
+int grub_util_lvm_isvolume (char *name);
+#endif
+
+#endif /* ! GRUB_RAID_UTIL_HEADER */
diff --git a/grub-core/include/grub/util/misc.h b/grub-core/include/grub/util/misc.h
new file mode 100644 (file)
index 0000000..ed71acd
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_UTIL_MISC_HEADER
+#define GRUB_UTIL_MISC_HEADER  1
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <unistd.h>
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+#ifdef __NetBSD__
+/* NetBSD uses /boot for its boot block.  */
+# define DEFAULT_DIRECTORY     "/grub"
+#else
+# define DEFAULT_DIRECTORY     "/boot/grub"
+#endif
+
+#define DEFAULT_DEVICE_MAP     DEFAULT_DIRECTORY "/device.map"
+
+char *grub_util_get_path (const char *dir, const char *file);
+size_t grub_util_get_fp_size (FILE *fp);
+size_t grub_util_get_image_size (const char *path);
+void grub_util_read_at (void *img, size_t len, off_t offset, FILE *fp);
+char *grub_util_read_image (const char *path);
+void grub_util_load_image (const char *path, char *buf);
+void grub_util_write_image (const char *img, size_t size, FILE *out);
+void grub_util_write_image_at (const void *img, size_t size, off_t offset,
+                              FILE *out);
+
+#ifndef HAVE_VASPRINTF
+
+int vasprintf (char **buf, const char *fmt, va_list ap);
+
+#endif
+
+#ifndef  HAVE_ASPRINTF
+
+int asprintf (char **buf, const char *fmt, ...);
+
+#endif
+
+#ifdef __MINGW32__
+
+#define fseeko fseeko64
+#define ftello ftello64
+
+void sync (void);
+int fsync (int fno);
+void sleep(int s);
+
+grub_int64_t grub_util_get_disk_size (char *name);
+
+#endif
+
+
+char *make_system_path_relative_to_its_root (const char *path);
+
+char *canonicalize_file_name (const char *path);
+
+void grub_util_init_nls (void);
+
+#endif /* ! GRUB_UTIL_MISC_HEADER */
diff --git a/grub-core/include/grub/util/ofpath.h b/grub-core/include/grub/util/ofpath.h
new file mode 100644 (file)
index 0000000..b43c523
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef GRUB_OFPATH_MACHINE_UTIL_HEADER
+#define GRUB_OFPATH_MACHINE_UTIL_HEADER        1
+
+char *grub_util_devname_to_ofpath (const char *devname);
+
+#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
diff --git a/grub-core/include/grub/util/raid.h b/grub-core/include/grub/util/raid.h
new file mode 100644 (file)
index 0000000..67020bb
--- /dev/null
@@ -0,0 +1,27 @@
+/* raid.h - RAID support for GRUB utils.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_RAID_UTIL_HEADER
+#define GRUB_RAID_UTIL_HEADER  1
+
+#ifdef __linux__
+char** grub_util_raid_getmembers (char *name);
+#endif
+
+#endif /* ! GRUB_RAID_UTIL_HEADER */
diff --git a/grub-core/include/grub/util/resolve.h b/grub-core/include/grub/util/resolve.h
new file mode 100644 (file)
index 0000000..f42df32
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_UTIL_RESOLVE_HEADER
+#define GRUB_UTIL_RESOLVE_HEADER       1
+
+struct grub_util_path_list
+{
+  const char *name;
+  struct grub_util_path_list *next;
+};
+
+/* Resolve the dependencies of the modules MODULES using the information
+   in the file DEP_LIST_FILE. The directory PREFIX is used to find files.  */
+struct grub_util_path_list *
+grub_util_resolve_dependencies (const char *prefix,
+                               const char *dep_list_file,
+                               char *modules[]);
+
+#endif /* ! GRUB_UTIL_RESOLVE_HEADER */
diff --git a/grub-core/include/grub/video.h b/grub-core/include/grub/video.h
new file mode 100644 (file)
index 0000000..782a528
--- /dev/null
@@ -0,0 +1,363 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_VIDEO_HEADER
+#define GRUB_VIDEO_HEADER      1
+
+#include <grub/err.h>
+#include <grub/types.h>
+
+/* Video color in hardware dependent format.  Users should not assume any
+   specific coding format.  */
+typedef grub_uint32_t grub_video_color_t;
+
+/* This structure is driver specific and should not be accessed directly by
+   outside code.  */
+struct grub_video_render_target;
+
+/* Forward declarations for used data structures.  */
+struct grub_video_bitmap;
+
+/* Defines used to describe video mode or rendering target.  */
+/* If following is set render target contains currenly displayed image
+   after swapping buffers (otherwise it contains previously displayed image).
+ */
+#define GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP     0x00000080
+#define GRUB_VIDEO_MODE_TYPE_PURE_TEXT         0x00000040
+#define GRUB_VIDEO_MODE_TYPE_ALPHA             0x00000020
+#define GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED   0x00000010
+#define GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP       0x00000004
+#define GRUB_VIDEO_MODE_TYPE_INDEX_COLOR       0x00000002
+#define GRUB_VIDEO_MODE_TYPE_RGB               0x00000001
+
+/* Defines used to mask flags.  */
+#define GRUB_VIDEO_MODE_TYPE_COLOR_MASK                0x0000000F
+
+/* Defines used to specify requested bit depth.  */
+#define GRUB_VIDEO_MODE_TYPE_DEPTH_MASK                0x0000ff00
+#define GRUB_VIDEO_MODE_TYPE_DEPTH_POS         8
+
+/* The basic render target representing the whole display.  This always
+   renders to the back buffer when double-buffering is in use.  */
+#define GRUB_VIDEO_RENDER_TARGET_DISPLAY \
+  ((struct grub_video_render_target *) 0)
+
+/* Defined blitting formats.  */
+enum grub_video_blit_format
+  {
+    /* Generic RGBA, use fields & masks.  */
+    GRUB_VIDEO_BLIT_FORMAT_RGBA,
+
+    /* Optimized RGBA's.  */
+    GRUB_VIDEO_BLIT_FORMAT_RGBA_8888,
+    GRUB_VIDEO_BLIT_FORMAT_BGRA_8888,
+
+    /* Generic RGB, use fields & masks.  */
+    GRUB_VIDEO_BLIT_FORMAT_RGB,
+
+    /* Optimized RGB's.  */
+    GRUB_VIDEO_BLIT_FORMAT_RGB_888,
+    GRUB_VIDEO_BLIT_FORMAT_BGR_888,
+    GRUB_VIDEO_BLIT_FORMAT_RGB_565,
+    GRUB_VIDEO_BLIT_FORMAT_BGR_565,
+
+    /* When needed, decode color or just use value as is.  */
+    GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR,
+
+    /* Two color bitmap; bits packed: rows are not padded to byte boundary.  */
+    GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED
+  };
+
+/* Define blitting operators.  */
+enum grub_video_blit_operators
+  {
+    /* Replace target bitmap data with source.  */
+    GRUB_VIDEO_BLIT_REPLACE,
+    /* Blend target and source based on source's alpha value.  */
+    GRUB_VIDEO_BLIT_BLEND
+  };
+
+struct grub_video_mode_info
+{
+  /* Width of the screen.  */
+  unsigned int width;
+
+  /* Height of the screen.  */
+  unsigned int height;
+
+  /* Mode type bitmask.  Contains information like is it Index color or
+     RGB mode.  */
+  unsigned int mode_type;
+
+  /* Bits per pixel.  */
+  unsigned int bpp;
+
+  /* Bytes per pixel.  */
+  unsigned int bytes_per_pixel;
+
+  /* Pitch of one scanline.  How many bytes there are for scanline.  */
+  unsigned int pitch;
+
+  /* In index color mode, number of colors.  In RGB mode this is 256.  */
+  unsigned int number_of_colors;
+
+  /* Optimization hint how binary data is coded.  */
+  enum grub_video_blit_format blit_format;
+
+  /* How many bits are reserved for red color.  */
+  unsigned int red_mask_size;
+
+  /* What is location of red color bits.  In Index Color mode, this is 0.  */
+  unsigned int red_field_pos;
+
+  /* How many bits are reserved for green color.  */
+  unsigned int green_mask_size;
+
+  /* What is location of green color bits.  In Index Color mode, this is 0.  */
+  unsigned int green_field_pos;
+
+  /* How many bits are reserved for blue color.  */
+  unsigned int blue_mask_size;
+
+  /* What is location of blue color bits.  In Index Color mode, this is 0.  */
+  unsigned int blue_field_pos;
+
+  /* How many bits are reserved in color.  */
+  unsigned int reserved_mask_size;
+
+  /* What is location of reserved color bits.  In Index Color mode,
+     this is 0.  */
+  unsigned int reserved_field_pos;
+
+  /* For 1-bit bitmaps, the background color.  Used for bits = 0.  */
+  grub_uint8_t bg_red;
+  grub_uint8_t bg_green;
+  grub_uint8_t bg_blue;
+  grub_uint8_t bg_alpha;
+
+  /* For 1-bit bitmaps, the foreground color.  Used for bits = 1.  */
+  grub_uint8_t fg_red;
+  grub_uint8_t fg_green;
+  grub_uint8_t fg_blue;
+  grub_uint8_t fg_alpha;
+};
+
+/* A 2D rectangle type.  */
+struct grub_video_rect
+{
+  unsigned x;
+  unsigned y;
+  unsigned width;
+  unsigned height;
+};
+typedef struct grub_video_rect grub_video_rect_t;
+
+struct grub_video_palette_data
+{
+  grub_uint8_t r; /* Red color value (0-255).  */
+  grub_uint8_t g; /* Green color value (0-255).  */
+  grub_uint8_t b; /* Blue color value (0-255).  */
+  grub_uint8_t a; /* Reserved bits value (0-255).  */
+};
+
+typedef enum grub_video_driver_id
+  {
+    GRUB_VIDEO_DRIVER_NONE,
+    GRUB_VIDEO_DRIVER_VBE,
+    GRUB_VIDEO_DRIVER_EFI_UGA,
+    GRUB_VIDEO_DRIVER_EFI_GOP,
+    GRUB_VIDEO_DRIVER_SM712
+  } grub_video_driver_id_t;
+
+struct grub_video_adapter
+{
+  /* The video adapter name.  */
+  const char *name;
+  grub_video_driver_id_t id;
+
+  /* Initialize the video adapter.  */
+  grub_err_t (*init) (void);
+
+  /* Clean up the video adapter.  */
+  grub_err_t (*fini) (void);
+
+  grub_err_t (*setup) (unsigned int width,  unsigned int height,
+                       unsigned int mode_type, unsigned int mode_mask);
+
+  grub_err_t (*get_info) (struct grub_video_mode_info *mode_info);
+
+  grub_err_t (*get_info_and_fini) (struct grub_video_mode_info *mode_info,
+                                  void **framebuffer);
+
+  grub_err_t (*set_palette) (unsigned int start, unsigned int count,
+                             struct grub_video_palette_data *palette_data);
+
+  grub_err_t (*get_palette) (unsigned int start, unsigned int count,
+                             struct grub_video_palette_data *palette_data);
+
+  grub_err_t (*set_viewport) (unsigned int x, unsigned int y,
+                              unsigned int width, unsigned int height);
+
+  grub_err_t (*get_viewport) (unsigned int *x, unsigned int *y,
+                              unsigned int *width, unsigned int *height);
+
+  grub_video_color_t (*map_color) (grub_uint32_t color_name);
+
+  grub_video_color_t (*map_rgb) (grub_uint8_t red, grub_uint8_t green,
+                                 grub_uint8_t blue);
+
+  grub_video_color_t (*map_rgba) (grub_uint8_t red, grub_uint8_t green,
+                                  grub_uint8_t blue, grub_uint8_t alpha);
+
+  grub_err_t (*unmap_color) (grub_video_color_t color,
+                             grub_uint8_t *red, grub_uint8_t *green,
+                             grub_uint8_t *blue, grub_uint8_t *alpha);
+
+  grub_err_t (*fill_rect) (grub_video_color_t color, int x, int y,
+                           unsigned int width, unsigned int height);
+
+  grub_err_t (*blit_bitmap) (struct grub_video_bitmap *bitmap,
+                             enum grub_video_blit_operators oper,
+                             int x, int y, int offset_x, int offset_y,
+                             unsigned int width, unsigned int height);
+
+  grub_err_t (*blit_render_target) (struct grub_video_render_target *source,
+                                    enum grub_video_blit_operators oper,
+                                    int x, int y, int offset_x, int offset_y,
+                                    unsigned int width, unsigned int height);
+
+  grub_err_t (*scroll) (grub_video_color_t color, int dx, int dy);
+
+  grub_err_t (*swap_buffers) (void);
+
+  grub_err_t (*create_render_target) (struct grub_video_render_target **result,
+                                      unsigned int width, unsigned int height,
+                                      unsigned int mode_type);
+
+  grub_err_t (*delete_render_target) (struct grub_video_render_target *target);
+
+  grub_err_t (*set_active_render_target) (struct grub_video_render_target *target);
+
+  grub_err_t (*get_active_render_target) (struct grub_video_render_target **target);
+
+  /* The next video adapter.  */
+  struct grub_video_adapter *next;
+};
+typedef struct grub_video_adapter *grub_video_adapter_t;
+
+void EXPORT_FUNC (grub_video_register) (grub_video_adapter_t adapter);
+void grub_video_unregister (grub_video_adapter_t adapter);
+void grub_video_iterate (int (*hook) (grub_video_adapter_t adapter));
+
+grub_err_t EXPORT_FUNC (grub_video_restore) (void);
+
+grub_err_t EXPORT_FUNC (grub_video_get_info) (struct grub_video_mode_info *mode_info);
+
+/* Framebuffer address may change as a part of normal operation
+   (e.g. double buffering). That's why you need to stop video subsystem to be
+   sure that framebuffer address doesn't change. To ensure this abstraction
+   grub_video_get_info_and_fini is the only function supplying framebuffer
+   address. */
+grub_err_t EXPORT_FUNC (grub_video_get_info_and_fini) (struct grub_video_mode_info *mode_info,
+                                        void **framebuffer);
+
+enum grub_video_blit_format grub_video_get_blit_format (struct grub_video_mode_info *mode_info);
+
+grub_err_t grub_video_set_palette (unsigned int start, unsigned int count,
+                                   struct grub_video_palette_data *palette_data);
+
+grub_err_t EXPORT_FUNC (grub_video_get_palette) (unsigned int start,
+                                                unsigned int count,
+                                                struct grub_video_palette_data *palette_data);
+
+grub_err_t EXPORT_FUNC (grub_video_set_viewport) (unsigned int x,
+                                                 unsigned int y,
+                                                 unsigned int width,
+                                                 unsigned int height);
+
+grub_err_t EXPORT_FUNC (grub_video_get_viewport) (unsigned int *x,
+                                                 unsigned int *y,
+                                                 unsigned int *width,
+                                                 unsigned int *height);
+
+grub_video_color_t EXPORT_FUNC (grub_video_map_color) (grub_uint32_t color_name);
+
+grub_video_color_t EXPORT_FUNC (grub_video_map_rgb) (grub_uint8_t red,
+                                                    grub_uint8_t green,
+                                                    grub_uint8_t blue);
+
+grub_video_color_t EXPORT_FUNC (grub_video_map_rgba) (grub_uint8_t red,
+                                                     grub_uint8_t green,
+                                                     grub_uint8_t blue,
+                                                     grub_uint8_t alpha);
+
+grub_err_t EXPORT_FUNC (grub_video_unmap_color) (grub_video_color_t color,
+                                                grub_uint8_t *red,
+                                                grub_uint8_t *green,
+                                                grub_uint8_t *blue,
+                                                grub_uint8_t *alpha);
+
+grub_err_t EXPORT_FUNC (grub_video_fill_rect) (grub_video_color_t color, 
+                                              int x, int y,
+                                              unsigned int width,
+                                              unsigned int height);
+
+grub_err_t EXPORT_FUNC (grub_video_blit_bitmap) (struct grub_video_bitmap *bitmap,
+                                                enum grub_video_blit_operators oper,
+                                                int x, int y,
+                                                int offset_x, int offset_y,
+                                                unsigned int width,
+                                                unsigned int height);
+
+grub_err_t EXPORT_FUNC (grub_video_blit_render_target) (struct grub_video_render_target *source,
+                                                       enum grub_video_blit_operators oper,
+                                                       int x, int y,
+                                                       int offset_x,
+                                                       int offset_y,
+                                                       unsigned int width,
+                                                       unsigned int height);
+
+grub_err_t grub_video_scroll (grub_video_color_t color, int dx, int dy);
+
+grub_err_t EXPORT_FUNC (grub_video_swap_buffers) (void);
+
+grub_err_t EXPORT_FUNC (grub_video_create_render_target) (struct grub_video_render_target **result,
+                                                         unsigned int width,
+                                                         unsigned int height,
+                                                         unsigned int mode_type);
+
+grub_err_t EXPORT_FUNC (grub_video_delete_render_target) (struct grub_video_render_target *target);
+
+grub_err_t EXPORT_FUNC (grub_video_set_active_render_target) (struct grub_video_render_target *target);
+
+grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target);
+
+grub_err_t EXPORT_FUNC (grub_video_set_mode) (const char *modestring,
+                                             unsigned int modemask,
+                                             unsigned int modevalue);
+
+static inline int
+grub_video_check_mode_flag (unsigned int flags, unsigned int mask,
+                           unsigned int flag, int def)
+{
+  return (flag & mask) ? !! (flags & flag) : def;
+}
+
+grub_video_driver_id_t EXPORT_FUNC (grub_video_get_driver_id) (void);
+
+#endif /* ! GRUB_VIDEO_HEADER */
diff --git a/grub-core/include/grub/video_fb.h b/grub-core/include/grub/video_fb.h
new file mode 100644 (file)
index 0000000..3046a59
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_VIDEO_FB_HEADER
+#define GRUB_VIDEO_FB_HEADER   1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/video.h>
+
+/* FB module internal prototype (should not be used from elsewhere).  */
+
+struct grub_video_fbblit_info;
+
+struct grub_video_fbrender_target;
+
+#define GRUB_VIDEO_FBSTD_NUMCOLORS 16
+extern struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLORS];
+
+grub_err_t
+grub_video_fb_init (void);
+
+grub_err_t
+grub_video_fb_fini (void);
+
+grub_err_t
+grub_video_fb_get_info (struct grub_video_mode_info *mode_info);
+
+grub_err_t
+grub_video_fb_get_palette (unsigned int start, unsigned int count,
+                          struct grub_video_palette_data *palette_data);
+grub_err_t
+grub_video_fb_set_palette (unsigned int start, unsigned int count,
+                          struct grub_video_palette_data *palette_data);
+grub_err_t
+grub_video_fb_set_viewport (unsigned int x, unsigned int y,
+                           unsigned int width, unsigned int height);
+grub_err_t
+grub_video_fb_get_viewport (unsigned int *x, unsigned int *y,
+                           unsigned int *width, unsigned int *height);
+
+grub_video_color_t
+grub_video_fb_map_color (grub_uint32_t color_name);
+
+grub_video_color_t
+grub_video_fb_map_rgb (grub_uint8_t red, grub_uint8_t green,
+                      grub_uint8_t blue);
+
+grub_video_color_t
+grub_video_fb_map_rgba (grub_uint8_t red, grub_uint8_t green,
+                       grub_uint8_t blue, grub_uint8_t alpha);
+
+grub_err_t
+grub_video_fb_unmap_color (grub_video_color_t color,
+                          grub_uint8_t *red, grub_uint8_t *green,
+                          grub_uint8_t *blue, grub_uint8_t *alpha);
+
+void
+grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source,
+                              grub_video_color_t color,
+                              grub_uint8_t *red, grub_uint8_t *green,
+                              grub_uint8_t *blue, grub_uint8_t *alpha);
+
+grub_err_t
+grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
+                        unsigned int width, unsigned int height);
+
+grub_err_t
+grub_video_fb_blit_bitmap (struct grub_video_bitmap *bitmap,
+                          enum grub_video_blit_operators oper, int x, int y,
+                          int offset_x, int offset_y,
+                          unsigned int width, unsigned int height);
+
+grub_err_t
+grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source,
+                                   enum grub_video_blit_operators oper,
+                                   int x, int y, int offset_x, int offset_y,
+                                 unsigned int width, unsigned int height);
+
+grub_err_t
+grub_video_fb_scroll (grub_video_color_t color, int dx, int dy);
+
+grub_err_t
+grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
+                                   unsigned int width, unsigned int height,
+                                   unsigned int mode_type __attribute__ ((unused)));
+
+grub_err_t
+grub_video_fb_create_render_target_from_pointer (struct grub_video_fbrender_target **result,
+                                                const struct grub_video_mode_info *mode_info,
+                                                void *ptr);
+
+grub_err_t
+grub_video_fb_delete_render_target (struct grub_video_fbrender_target *target);
+
+grub_err_t
+grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **target);
+
+grub_err_t
+grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *target);
+
+typedef grub_err_t
+(*grub_video_fb_doublebuf_update_screen_t) (struct grub_video_fbrender_target *front,
+                                         struct grub_video_fbrender_target *back);
+
+grub_err_t
+grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **front,
+                                  struct grub_video_fbrender_target **back,
+                                  grub_video_fb_doublebuf_update_screen_t *update_screen,
+                                  struct grub_video_mode_info mode_info,
+                                  void *framebuf);
+
+#endif /* ! GRUB_VIDEO_FB_HEADER */
diff --git a/grub-core/include/grub/x86_64/at_keyboard.h b/grub-core/include/grub/x86_64/at_keyboard.h
new file mode 100644 (file)
index 0000000..c632aa8
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/at_keyboard.h>
diff --git a/grub-core/include/grub/x86_64/efi/kernel.h b/grub-core/include/grub/x86_64/efi/kernel.h
new file mode 100644 (file)
index 0000000..c0549f4
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_KERNEL_HEADER
+#define GRUB_MACHINE_KERNEL_HEADER   1
+
+/* The prefix which points to the directory where GRUB modules and its
+   configuration file are located.  */
+extern char grub_prefix[];
+
+/* The offset of GRUB_PREFIX.  */
+#define GRUB_KERNEL_MACHINE_PREFIX             0x8
+
+/* End of the data section. */
+#define GRUB_KERNEL_MACHINE_DATA_END           0x50
+
+#endif /* ! GRUB_MACHINE_KERNEL_HEADER */
+
diff --git a/grub-core/include/grub/x86_64/efi/loader.h b/grub-core/include/grub/x86_64/efi/loader.h
new file mode 100644 (file)
index 0000000..7c302e8
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOADER_MACHINE_HEADER
+#define GRUB_LOADER_MACHINE_HEADER     1
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+
+
+#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/grub-core/include/grub/x86_64/efi/memory.h b/grub-core/include/grub/x86_64/efi/memory.h
new file mode 100644 (file)
index 0000000..c9a61bb
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/efi/memory.h>
diff --git a/grub-core/include/grub/x86_64/efi/serial.h b/grub-core/include/grub/x86_64/efi/serial.h
new file mode 100644 (file)
index 0000000..2d85634
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/coreboot/serial.h>
diff --git a/grub-core/include/grub/x86_64/efi/time.h b/grub-core/include/grub/x86_64/efi/time.h
new file mode 100644 (file)
index 0000000..7a9241f
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_MACHINE_TIME_HEADER
+#define GRUB_MACHINE_TIME_HEADER       1
+
+#include <grub/efi/time.h>
+
+#endif /* ! GRUB_MACHINE_TIME_HEADER */
diff --git a/grub-core/include/grub/x86_64/io.h b/grub-core/include/grub/x86_64/io.h
new file mode 100644 (file)
index 0000000..9f465bc
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/i386/io.h>
diff --git a/grub-core/include/grub/x86_64/kernel.h b/grub-core/include/grub/x86_64/kernel.h
new file mode 100644 (file)
index 0000000..25ac57e
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/kernel.h>
diff --git a/grub-core/include/grub/x86_64/linux.h b/grub-core/include/grub/x86_64/linux.h
new file mode 100644 (file)
index 0000000..19ea936
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/i386/linux.h>
diff --git a/grub-core/include/grub/x86_64/macho.h b/grub-core/include/grub/x86_64/macho.h
new file mode 100644 (file)
index 0000000..165b8da
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/macho.h>
diff --git a/grub-core/include/grub/x86_64/multiboot.h b/grub-core/include/grub/x86_64/multiboot.h
new file mode 100644 (file)
index 0000000..957c7a5
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/multiboot.h>
diff --git a/grub-core/include/grub/x86_64/pci.h b/grub-core/include/grub/x86_64/pci.h
new file mode 100644 (file)
index 0000000..91a9924
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/i386/pci.h>
diff --git a/grub-core/include/grub/x86_64/relocator.h b/grub-core/include/grub/x86_64/relocator.h
new file mode 100644 (file)
index 0000000..247e7a1
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/relocator.h>
diff --git a/grub-core/include/grub/x86_64/setjmp.h b/grub-core/include/grub/x86_64/setjmp.h
new file mode 100644 (file)
index 0000000..4ad968e
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_SETJMP_CPU_HEADER
+#define GRUB_SETJMP_CPU_HEADER 1
+
+typedef unsigned long grub_jmp_buf[8];
+
+int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice));
+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
+
+#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/grub-core/include/grub/x86_64/time.h b/grub-core/include/grub/x86_64/time.h
new file mode 100644 (file)
index 0000000..842882c
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_TIME_HEADER
+#define KERNEL_CPU_TIME_HEADER 1
+
+static __inline void
+grub_cpu_idle (void)
+{
+  /* FIXME: this can't work until we handle interrupts.  */
+/*  __asm__ __volatile__ ("hlt"); */
+}
+
+#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/grub-core/include/grub/x86_64/types.h b/grub-core/include/grub/x86_64/types.h
new file mode 100644 (file)
index 0000000..bdee5a1
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_TYPES_CPU_HEADER
+#define GRUB_TYPES_CPU_HEADER  1
+
+/* The size of void *.  */
+#define GRUB_TARGET_SIZEOF_VOID_P      8
+
+/* The size of long.  */
+#define GRUB_TARGET_SIZEOF_LONG                8
+
+/* x86_64 is little-endian.  */
+#undef GRUB_TARGET_WORDS_BIGENDIAN
+
+#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/grub-core/include/grub/x86_64/xnu.h b/grub-core/include/grub/x86_64/xnu.h
new file mode 100644 (file)
index 0000000..ae61733
--- /dev/null
@@ -0,0 +1 @@
+#include <grub/i386/xnu.h>
diff --git a/grub-core/include/grub/xnu.h b/grub-core/include/grub/xnu.h
new file mode 100644 (file)
index 0000000..6089aad
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_XNU_H
+#define GRUB_XNU_H 1
+
+#include <grub/bitmap.h>
+
+/* Header of a hibernation image. */
+struct grub_xnu_hibernate_header
+{
+  /* Size of the image. Notice that file containing image is usually bigger. */
+  grub_uint64_t image_size;
+  grub_uint8_t unknown1[8];
+  /* Where to copy launchcode? */
+  grub_uint32_t launchcode_target_page;
+  /* How many pages of launchcode? */
+  grub_uint32_t launchcode_numpages;
+  /* Where to jump? */
+  grub_uint32_t entry_point;
+  /* %esp at start. */
+  grub_uint32_t stack;
+  grub_uint8_t unknown2[44];
+#define GRUB_XNU_HIBERNATE_MAGIC 0x73696d65
+  grub_uint32_t magic;
+  grub_uint8_t unknown3[28];
+  /* This value is non-zero if page is encrypted. Unsupported. */
+  grub_uint64_t encoffset;
+  grub_uint8_t unknown4[360];
+  /* The size of additional header used to locate image without parsing FS.
+     Used only to skip it.
+   */
+  grub_uint32_t extmapsize;
+} __attribute__ ((packed));
+
+/* In-memory structure for temporary keeping device tree. */
+struct grub_xnu_devtree_key
+{
+  char *name;
+  int datasize; /* -1 for not leaves. */
+  union
+  {
+    struct grub_xnu_devtree_key *first_child;
+    void *data;
+  };
+  struct grub_xnu_devtree_key *next;
+};
+
+/* A structure used in memory-map values. */
+struct
+grub_xnu_extdesc
+{
+  grub_uint32_t addr;
+  grub_uint32_t size;
+} __attribute__ ((packed));
+
+/* Header describing extension in the memory. */
+struct grub_xnu_extheader
+{
+  grub_uint32_t infoplistaddr;
+  grub_uint32_t infoplistsize;
+  grub_uint32_t binaryaddr;
+  grub_uint32_t binarysize;
+  grub_uint32_t nameaddr;
+  grub_uint32_t namesize;
+} __attribute__ ((packed));
+
+struct grub_xnu_devtree_key *grub_xnu_create_key (struct grub_xnu_devtree_key **parent,
+                                                 char *name);
+
+extern struct grub_xnu_devtree_key *grub_xnu_devtree_root;
+
+void grub_xnu_free_devtree (struct grub_xnu_devtree_key *cur);
+
+grub_err_t grub_xnu_writetree_toheap (void **start, grub_size_t *size);
+struct grub_xnu_devtree_key *grub_xnu_create_value (struct grub_xnu_devtree_key **parent,
+                                                   char *name);
+
+void grub_xnu_lock (void);
+void grub_xnu_unlock (void);
+grub_err_t grub_xnu_resume (char *imagename);
+grub_err_t grub_xnu_boot_resume (void);
+struct grub_xnu_devtree_key *grub_xnu_find_key (struct grub_xnu_devtree_key *parent,
+                                               char *name);
+grub_err_t grub_xnu_align_heap (int align);
+grub_err_t grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired,
+                                       int maxrecursion);
+grub_err_t grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired,
+                                       int maxrecursion);
+void *grub_xnu_heap_malloc (int size);
+grub_err_t grub_xnu_fill_devicetree (void);
+extern grub_uint32_t grub_xnu_heap_real_start;
+extern grub_size_t grub_xnu_heap_size;
+extern void *grub_xnu_heap_start;
+extern struct grub_video_bitmap *grub_xnu_bitmap;
+typedef enum {GRUB_XNU_BITMAP_CENTER, GRUB_XNU_BITMAP_STRETCH}
+  grub_xnu_bitmap_mode_t;
+extern grub_xnu_bitmap_mode_t grub_xnu_bitmap_mode;
+extern int grub_xnu_is_64bit;
+#endif
diff --git a/grub-core/include/multiboot.h b/grub-core/include/multiboot.h
new file mode 100644 (file)
index 0000000..fda863e
--- /dev/null
@@ -0,0 +1,259 @@
+/*  multiboot.h - Multiboot header file.  */
+/*  Copyright (C) 1999,2003,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to
+ *  deal in the Software without restriction, including without limitation the
+ *  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ *  sell copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL ANY
+ *  DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+ *  IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef MULTIBOOT_HEADER
+#define MULTIBOOT_HEADER 1
+
+/* How many bytes from the start of the file we search for the header.  */
+#define MULTIBOOT_SEARCH                       8192
+#define MULTIBOOT_HEADER_ALIGN                 4
+
+/* The magic field should contain this.  */
+#define MULTIBOOT_HEADER_MAGIC                 0x1BADB002
+
+/* This should be in %eax.  */
+#define MULTIBOOT_BOOTLOADER_MAGIC             0x2BADB002
+
+/* Alignment of multiboot modules.  */
+#define MULTIBOOT_MOD_ALIGN                    0x00001000
+
+/* Alignment of the multiboot info structure.  */
+#define MULTIBOOT_INFO_ALIGN                   0x00000004
+
+/* Flags set in the 'flags' member of the multiboot header.  */
+
+/* Align all boot modules on i386 page (4KB) boundaries.  */
+#define MULTIBOOT_PAGE_ALIGN                   0x00000001
+
+/* Must pass memory information to OS.  */
+#define MULTIBOOT_MEMORY_INFO                  0x00000002
+
+/* Must pass video information to OS.  */
+#define MULTIBOOT_VIDEO_MODE                   0x00000004
+
+/* This flag indicates the use of the address fields in the header.  */
+#define MULTIBOOT_AOUT_KLUDGE                  0x00010000
+
+/* Flags to be set in the 'flags' member of the multiboot info structure.  */
+
+/* is there basic lower/upper memory information? */
+#define MULTIBOOT_INFO_MEMORY                  0x00000001
+/* is there a boot device set? */
+#define MULTIBOOT_INFO_BOOTDEV                 0x00000002
+/* is the command-line defined? */
+#define MULTIBOOT_INFO_CMDLINE                 0x00000004
+/* are there modules to do something with? */
+#define MULTIBOOT_INFO_MODS                    0x00000008
+
+/* These next two are mutually exclusive */
+
+/* is there a symbol table loaded? */
+#define MULTIBOOT_INFO_AOUT_SYMS               0x00000010
+/* is there an ELF section header table? */
+#define MULTIBOOT_INFO_ELF_SHDR                        0X00000020
+
+/* is there a full memory map? */
+#define MULTIBOOT_INFO_MEM_MAP                 0x00000040
+
+/* Is there drive info?  */
+#define MULTIBOOT_INFO_DRIVE_INFO              0x00000080
+
+/* Is there a config table?  */
+#define MULTIBOOT_INFO_CONFIG_TABLE            0x00000100
+
+/* Is there a boot loader name?  */
+#define MULTIBOOT_INFO_BOOT_LOADER_NAME                0x00000200
+
+/* Is there a APM table?  */
+#define MULTIBOOT_INFO_APM_TABLE               0x00000400
+
+/* Is there video information?  */
+#define MULTIBOOT_INFO_VBE_INFO                        0x00000800
+#define MULTIBOOT_INFO_FRAMEBUFFER_INFO                0x00001000
+
+#ifndef ASM_FILE
+
+typedef unsigned char          multiboot_uint8_t;
+typedef unsigned short         multiboot_uint16_t;
+typedef unsigned int           multiboot_uint32_t;
+typedef unsigned long long     multiboot_uint64_t;
+
+struct multiboot_header
+{
+  /* Must be MULTIBOOT_MAGIC - see above.  */
+  multiboot_uint32_t magic;
+
+  /* Feature flags.  */
+  multiboot_uint32_t flags;
+
+  /* The above fields plus this one must equal 0 mod 2^32. */
+  multiboot_uint32_t checksum;
+
+  /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set.  */
+  multiboot_uint32_t header_addr;
+  multiboot_uint32_t load_addr;
+  multiboot_uint32_t load_end_addr;
+  multiboot_uint32_t bss_end_addr;
+  multiboot_uint32_t entry_addr;
+
+  /* These are only valid if MULTIBOOT_VIDEO_MODE is set.  */
+  multiboot_uint32_t mode_type;
+  multiboot_uint32_t width;
+  multiboot_uint32_t height;
+  multiboot_uint32_t depth;
+};
+
+/* The symbol table for a.out.  */
+struct multiboot_aout_symbol_table
+{
+  multiboot_uint32_t tabsize;
+  multiboot_uint32_t strsize;
+  multiboot_uint32_t addr;
+  multiboot_uint32_t reserved;
+};
+typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
+
+/* The section header table for ELF.  */
+struct multiboot_elf_section_header_table
+{
+  multiboot_uint32_t num;
+  multiboot_uint32_t size;
+  multiboot_uint32_t addr;
+  multiboot_uint32_t shndx;
+};
+typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
+
+struct multiboot_info
+{
+  /* Multiboot info version number */
+  multiboot_uint32_t flags;
+
+  /* Available memory from BIOS */
+  multiboot_uint32_t mem_lower;
+  multiboot_uint32_t mem_upper;
+
+  /* "root" partition */
+  multiboot_uint32_t boot_device;
+
+  /* Kernel command line */
+  multiboot_uint32_t cmdline;
+
+  /* Boot-Module list */
+  multiboot_uint32_t mods_count;
+  multiboot_uint32_t mods_addr;
+
+  union
+  {
+    multiboot_aout_symbol_table_t aout_sym;
+    multiboot_elf_section_header_table_t elf_sec;
+  } u;
+
+  /* Memory Mapping buffer */
+  multiboot_uint32_t mmap_length;
+  multiboot_uint32_t mmap_addr;
+
+  /* Drive Info buffer */
+  multiboot_uint32_t drives_length;
+  multiboot_uint32_t drives_addr;
+
+  /* ROM configuration table */
+  multiboot_uint32_t config_table;
+
+  /* Boot Loader Name */
+  multiboot_uint32_t boot_loader_name;
+
+  /* APM table */
+  multiboot_uint32_t apm_table;
+
+  /* Video */
+  multiboot_uint32_t vbe_control_info;
+  multiboot_uint32_t vbe_mode_info;
+  multiboot_uint16_t vbe_mode;
+  multiboot_uint16_t vbe_interface_seg;
+  multiboot_uint16_t vbe_interface_off;
+  multiboot_uint16_t vbe_interface_len;
+
+  multiboot_uint64_t framebuffer_addr;
+  multiboot_uint32_t framebuffer_pitch;
+  multiboot_uint32_t framebuffer_width;
+  multiboot_uint32_t framebuffer_height;
+  multiboot_uint8_t framebuffer_bpp;
+#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
+#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB     1
+#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT    2
+  multiboot_uint8_t framebuffer_type;
+  union
+  {
+    struct
+    {
+      multiboot_uint32_t framebuffer_palette_addr;
+      multiboot_uint16_t framebuffer_palette_num_colors;
+    };
+    struct
+    {
+      multiboot_uint8_t framebuffer_red_field_position;
+      multiboot_uint8_t framebuffer_red_mask_size;
+      multiboot_uint8_t framebuffer_green_field_position;
+      multiboot_uint8_t framebuffer_green_mask_size;
+      multiboot_uint8_t framebuffer_blue_field_position;
+      multiboot_uint8_t framebuffer_blue_mask_size;
+    };
+  };
+};
+typedef struct multiboot_info multiboot_info_t;
+
+struct multiboot_color
+{
+  multiboot_uint8_t red;
+  multiboot_uint8_t green;
+  multiboot_uint8_t blue;
+};
+
+struct multiboot_mmap_entry
+{
+  multiboot_uint32_t size;
+  multiboot_uint64_t addr;
+  multiboot_uint64_t len;
+#define MULTIBOOT_MEMORY_AVAILABLE             1
+#define MULTIBOOT_MEMORY_RESERVED              2
+#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE       3
+#define MULTIBOOT_MEMORY_NVS                    4
+  multiboot_uint32_t type;
+} __attribute__((packed));
+typedef struct multiboot_mmap_entry multiboot_memory_map_t;
+
+struct multiboot_mod_list
+{
+  /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
+  multiboot_uint32_t mod_start;
+  multiboot_uint32_t mod_end;
+
+  /* Module command line */
+  multiboot_uint32_t cmdline;
+
+  /* padding to take it to 16 bytes (must be zero) */
+  multiboot_uint32_t pad;
+};
+typedef struct multiboot_mod_list multiboot_module_t;
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! MULTIBOOT_HEADER */
diff --git a/grub-core/include/multiboot2.h b/grub-core/include/multiboot2.h
new file mode 100644 (file)
index 0000000..275debe
--- /dev/null
@@ -0,0 +1,314 @@
+/*  multiboot2.h - Multiboot 2 header file.  */
+/*  Copyright (C) 1999,2003,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to
+ *  deal in the Software without restriction, including without limitation the
+ *  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ *  sell copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL ANY
+ *  DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+ *  IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef MULTIBOOT_HEADER
+#define MULTIBOOT_HEADER 1
+
+/* How many bytes from the start of the file we search for the header.  */
+#define MULTIBOOT_SEARCH                       32768
+#define MULTIBOOT_HEADER_ALIGN                 8
+
+/* The magic field should contain this.  */
+#define MULTIBOOT2_HEADER_MAGIC                        0xe85250d6
+
+/* This should be in %eax.  */
+#define MULTIBOOT2_BOOTLOADER_MAGIC            0x36d76289
+
+/* Alignment of multiboot modules.  */
+#define MULTIBOOT_MOD_ALIGN                    0x00001000
+
+/* Alignment of the multiboot info structure.  */
+#define MULTIBOOT_INFO_ALIGN                   0x00000008
+
+/* Flags set in the 'flags' member of the multiboot header.  */
+
+#define MULTIBOOT_TAG_ALIGN                  8
+#define MULTIBOOT_TAG_TYPE_END               0
+#define MULTIBOOT_TAG_TYPE_CMDLINE           1
+#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME  2
+#define MULTIBOOT_TAG_TYPE_MODULE            3
+#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO     4
+#define MULTIBOOT_TAG_TYPE_BOOTDEV           5
+#define MULTIBOOT_TAG_TYPE_MMAP              6
+#define MULTIBOOT_TAG_TYPE_VBE               7
+#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER       8
+#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS      9
+#define MULTIBOOT_TAG_TYPE_APM               10
+
+#define MULTIBOOT_HEADER_TAG_END  0
+#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST  1
+#define MULTIBOOT_HEADER_TAG_ADDRESS  2
+#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS  3
+#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS  4
+#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER  5
+#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN  6
+
+#define MULTIBOOT_ARCHITECTURE_I386  0
+#define MULTIBOOT_ARCHITECTURE_MIPS32  4
+#define MULTIBOOT_HEADER_TAG_OPTIONAL 1
+
+#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
+#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
+
+#ifndef ASM_FILE
+
+typedef unsigned char          multiboot_uint8_t;
+typedef unsigned short         multiboot_uint16_t;
+typedef unsigned int           multiboot_uint32_t;
+typedef unsigned long long     multiboot_uint64_t;
+
+struct multiboot_header
+{
+  /* Must be MULTIBOOT_MAGIC - see above.  */
+  multiboot_uint32_t magic;
+
+  /* ISA */
+  multiboot_uint32_t architecture;
+
+  /* Total header length.  */
+  multiboot_uint32_t header_length;
+
+  /* The above fields plus this one must equal 0 mod 2^32. */
+  multiboot_uint32_t checksum;
+};
+
+struct multiboot_header_tag
+{
+  multiboot_uint16_t type;
+  multiboot_uint16_t flags;
+  multiboot_uint32_t size;
+};
+
+struct multiboot_header_tag_information_request
+{
+  multiboot_uint16_t type;
+  multiboot_uint16_t flags;
+  multiboot_uint32_t size;
+  multiboot_uint32_t requests[0];
+};
+
+struct multiboot_header_tag_address
+{
+  multiboot_uint16_t type;
+  multiboot_uint16_t flags;
+  multiboot_uint32_t size;
+  multiboot_uint32_t header_addr;
+  multiboot_uint32_t load_addr;
+  multiboot_uint32_t load_end_addr;
+  multiboot_uint32_t bss_end_addr;
+};
+
+struct multiboot_header_tag_entry_address
+{
+  multiboot_uint16_t type;
+  multiboot_uint16_t flags;
+  multiboot_uint32_t size;
+  multiboot_uint32_t entry_addr;
+};
+
+struct multiboot_header_tag_console_flags
+{
+  multiboot_uint16_t type;
+  multiboot_uint16_t flags;
+  multiboot_uint32_t size;
+  multiboot_uint32_t console_flags;
+};
+
+struct multiboot_header_tag_framebuffer
+{
+  multiboot_uint16_t type;
+  multiboot_uint16_t flags;
+  multiboot_uint32_t size;
+  multiboot_uint32_t width;
+  multiboot_uint32_t height;
+  multiboot_uint32_t depth;
+};
+
+struct multiboot_header_tag_module_align
+{
+  multiboot_uint16_t type;
+  multiboot_uint16_t flags;
+  multiboot_uint32_t size;
+  multiboot_uint32_t width;
+  multiboot_uint32_t height;
+  multiboot_uint32_t depth;
+};
+
+struct multiboot_color
+{
+  multiboot_uint8_t red;
+  multiboot_uint8_t green;
+  multiboot_uint8_t blue;
+};
+
+struct multiboot_mmap_entry
+{
+  multiboot_uint64_t addr;
+  multiboot_uint64_t len;
+#define MULTIBOOT_MEMORY_AVAILABLE             1
+#define MULTIBOOT_MEMORY_RESERVED              2
+#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE       3
+#define MULTIBOOT_MEMORY_NVS                    4
+  multiboot_uint32_t type;
+  multiboot_uint32_t zero;
+} __attribute__((packed));
+typedef struct multiboot_mmap_entry multiboot_memory_map_t;
+
+struct multiboot_tag
+{
+  multiboot_uint32_t type;
+  multiboot_uint32_t size;
+};
+
+struct multiboot_tag_string
+{
+  multiboot_uint32_t type;
+  multiboot_uint32_t size;
+  char string[0];
+};
+
+struct multiboot_tag_module
+{
+  multiboot_uint32_t type;
+  multiboot_uint32_t size;
+  multiboot_uint32_t mod_start;
+  multiboot_uint32_t mod_end;
+  char cmdline[0];
+};
+
+struct multiboot_tag_basic_meminfo
+{
+  multiboot_uint32_t type;
+  multiboot_uint32_t size;
+  multiboot_uint32_t mem_lower;
+  multiboot_uint32_t mem_upper;
+};
+
+struct multiboot_tag_bootdev
+{
+  multiboot_uint32_t type;
+  multiboot_uint32_t size;
+  multiboot_uint32_t biosdev;
+  multiboot_uint32_t slice;
+  multiboot_uint32_t part;
+};
+
+struct multiboot_tag_mmap
+{
+  multiboot_uint32_t type;
+  multiboot_uint32_t size;
+  multiboot_uint32_t entry_size;
+  multiboot_uint32_t entry_version;
+  struct multiboot_mmap_entry entries[0];  
+};
+
+struct multiboot_vbe_info_block
+{
+  multiboot_uint8_t external_specification[512];
+};
+
+struct multiboot_vbe_mode_info_block
+{
+  multiboot_uint8_t external_specification[256];
+};
+
+struct multiboot_tag_vbe
+{
+  multiboot_uint32_t type;
+  multiboot_uint32_t size;
+
+  multiboot_uint16_t vbe_mode;
+  multiboot_uint16_t vbe_interface_seg;
+  multiboot_uint16_t vbe_interface_off;
+  multiboot_uint16_t vbe_interface_len;
+
+  struct multiboot_vbe_info_block vbe_control_info;
+  struct multiboot_vbe_mode_info_block vbe_mode_info;
+};
+
+struct multiboot_tag_framebuffer_common
+{
+  multiboot_uint32_t type;
+  multiboot_uint32_t size;
+
+  multiboot_uint64_t framebuffer_addr;
+  multiboot_uint32_t framebuffer_pitch;
+  multiboot_uint32_t framebuffer_width;
+  multiboot_uint32_t framebuffer_height;
+  multiboot_uint8_t framebuffer_bpp;
+#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
+#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB     1
+#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT    2
+  multiboot_uint8_t framebuffer_type;
+  multiboot_uint16_t reserved;
+};
+
+struct multiboot_tag_framebuffer
+{
+  struct multiboot_tag_framebuffer_common common;
+
+  union
+  {
+    struct
+    {
+      multiboot_uint16_t framebuffer_palette_num_colors;
+      struct multiboot_color framebuffer_palette[0];
+    };
+    struct
+    {
+      multiboot_uint8_t framebuffer_red_field_position;
+      multiboot_uint8_t framebuffer_red_mask_size;
+      multiboot_uint8_t framebuffer_green_field_position;
+      multiboot_uint8_t framebuffer_green_mask_size;
+      multiboot_uint8_t framebuffer_blue_field_position;
+      multiboot_uint8_t framebuffer_blue_mask_size;
+    };
+  };
+};
+
+struct multiboot_tag_elf_sections
+{
+  multiboot_uint32_t type;
+  multiboot_uint32_t size;
+  multiboot_uint32_t num;
+  multiboot_uint32_t entsize;
+  multiboot_uint32_t shndx;
+  char sections[0];
+};
+
+struct multiboot_tag_apm
+{
+  multiboot_uint32_t type;
+  multiboot_uint32_t size;
+  multiboot_uint16_t version;
+  multiboot_uint16_t cseg;
+  multiboot_uint32_t offset;
+  multiboot_uint16_t cseg_16;
+  multiboot_uint16_t dseg;
+  multiboot_uint16_t flags;
+  multiboot_uint16_t cseg_len;
+  multiboot_uint16_t cseg_16_len;
+  multiboot_uint16_t dseg_len;
+};
+
+#endif /* ! ASM_FILE */
+
+#endif /* ! MULTIBOOT_HEADER */
diff --git a/grub-core/io/bufio.c b/grub-core/io/bufio.c
new file mode 100644 (file)
index 0000000..92f2927
--- /dev/null
@@ -0,0 +1,205 @@
+/* bufio.c - buffered io access */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/fs.h>
+#include <grub/bufio.h>
+
+#define GRUB_BUFIO_DEF_SIZE    8192
+#define GRUB_BUFIO_MAX_SIZE    1048576
+
+struct grub_bufio
+{
+  grub_file_t file;
+  grub_size_t block_size;
+  grub_size_t buffer_len;
+  char buffer[0];
+};
+typedef struct grub_bufio *grub_bufio_t;
+
+static struct grub_fs grub_bufio_fs;
+
+grub_file_t
+grub_bufio_open (grub_file_t io, int size)
+{
+  grub_file_t file;
+  grub_bufio_t bufio = 0;
+
+  file = (grub_file_t) grub_malloc (sizeof (*file));
+  if (! file)
+    return 0;
+
+  if (size == 0)
+    size = GRUB_BUFIO_DEF_SIZE;
+  else if (size > GRUB_BUFIO_MAX_SIZE)
+    size = GRUB_BUFIO_MAX_SIZE;
+
+  if ((size < 0) || ((unsigned) size > io->size))
+    size = ((io->size > GRUB_BUFIO_MAX_SIZE) ? GRUB_BUFIO_MAX_SIZE :
+            io->size);
+
+  bufio = grub_malloc (sizeof (struct grub_bufio) + size);
+  if (! bufio)
+    {
+      grub_free (file);
+      return 0;
+    }
+
+  bufio->file = io;
+  bufio->block_size = size;
+  bufio->buffer_len = 0;
+
+  file->device = io->device;
+  file->offset = 0;
+  file->size = io->size;
+  file->data = bufio;
+  file->read_hook = 0;
+  file->fs = &grub_bufio_fs;
+
+  return file;
+}
+
+grub_file_t
+grub_buffile_open (const char *name, int size)
+{
+  grub_file_t io, file;
+
+  io = grub_file_open (name);
+  if (! io)
+    return 0;
+
+  file = grub_bufio_open (io, size);
+  if (! file)
+    {
+      grub_file_close (io);
+      return 0;
+    }
+
+  return file;
+}
+
+static grub_ssize_t
+grub_bufio_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  grub_size_t res = len;
+  grub_bufio_t bufio = file->data;
+  grub_uint32_t pos;
+
+  if ((file->offset >= bufio->file->offset) &&
+      (file->offset < bufio->file->offset + bufio->buffer_len))
+    {
+      grub_size_t n;
+
+      pos = file->offset - bufio->file->offset;
+      n = bufio->buffer_len - pos;
+      if (n > len)
+        n = len;
+
+      grub_memcpy (buf, &bufio->buffer[pos], n);
+      len -= n;
+      if (! len)
+        return res;
+
+      buf += n;
+      bufio->file->offset += bufio->buffer_len;
+      pos = 0;
+    }
+  else
+    {
+      bufio->file->offset = grub_divmod64 (file->offset, bufio->block_size,
+                                           &pos);
+      bufio->file->offset *= bufio->block_size;
+    }
+
+  if (pos + len >= bufio->block_size)
+    {
+      if (pos)
+        {
+          grub_size_t n;
+
+          bufio->file->fs->read (bufio->file, bufio->buffer,
+                                 bufio->block_size);
+          if (grub_errno)
+            return -1;
+
+          n = bufio->block_size - pos;
+          grub_memcpy (buf, &bufio->buffer[pos], n);
+          len -= n;
+          buf += n;
+          bufio->file->offset += bufio->block_size;
+          pos = 0;
+        }
+
+      while (len >= bufio->block_size)
+        {
+          bufio->file->fs->read (bufio->file, buf, bufio->block_size);
+          if (grub_errno)
+            return -1;
+
+          len -= bufio->block_size;
+          buf += bufio->block_size;
+          bufio->file->offset += bufio->block_size;
+        }
+
+      if (! len)
+        {
+          bufio->buffer_len = 0;
+          return res;
+        }
+    }
+
+  bufio->buffer_len = bufio->file->size - bufio->file->offset;
+  if (bufio->buffer_len > bufio->block_size)
+    bufio->buffer_len = bufio->block_size;
+
+  bufio->file->fs->read (bufio->file, bufio->buffer, bufio->buffer_len);
+  if (grub_errno)
+    return -1;
+
+  grub_memcpy (buf, &bufio->buffer[pos], len);
+
+  return res;
+}
+
+static grub_err_t
+grub_bufio_close (grub_file_t file)
+{
+  grub_bufio_t bufio = file->data;
+
+  grub_file_close (bufio->file);
+  grub_free (bufio);
+
+  file->device = 0;
+
+  return grub_errno;
+}
+
+static struct grub_fs grub_bufio_fs =
+  {
+    .name = "bufio",
+    .dir = 0,
+    .open = 0,
+    .read = grub_bufio_read,
+    .close = grub_bufio_close,
+    .label = 0,
+    .next = 0
+  };
diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c
new file mode 100644 (file)
index 0000000..9bf6091
--- /dev/null
@@ -0,0 +1,1251 @@
+/* gzio.c - decompression support for gzip */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2005,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Most of this file was originally the source file "inflate.c", written
+ * by Mark Adler.  It has been very heavily modified.  In particular, the
+ * original would run through the whole file at once, and this version can
+ * be stopped and restarted on any boundary during the decompression process.
+ *
+ * The license and header comments that file are included here.
+ */
+
+/* inflate.c -- Not copyrighted 1992 by Mark Adler
+   version c10p1, 10 January 1993 */
+
+/* You can do whatever you like with this source file, though I would
+   prefer that if you modify it and redistribute it that you include
+   comments to that effect with your name and the date.  Thank you.
+ */
+
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/fs.h>
+#include <grub/file.h>
+#include <grub/gzio.h>
+
+/*
+ *  Window Size
+ *
+ *  This must be a power of two, and at least 32K for zip's deflate method
+ */
+
+#define WSIZE  0x8000
+
+
+#define INBUFSIZ  0x2000
+
+/* The state stored in filesystem-specific data.  */
+struct grub_gzio
+{
+  /* The underlying file object.  */
+  grub_file_t file;
+  /* The offset at which the data starts in the underlying file.  */
+  grub_off_t data_offset;
+  /* The type of current block.  */
+  int block_type;
+  /* The length of current block.  */
+  int block_len;
+  /* The flag of the last block.  */
+  int last_block;
+  /* The flag of codes.  */
+  int code_state;
+  /* The length of a copy.  */
+  unsigned inflate_n;
+  /* The index of a copy.  */
+  unsigned inflate_d;
+  /* The input buffer.  */
+  grub_uint8_t inbuf[INBUFSIZ];
+  int inbuf_d;
+  /* The bit buffer.  */
+  unsigned long bb;
+  /* The bits in the bit buffer.  */
+  unsigned bk;
+  /* The sliding window in uncompressed data.  */
+  grub_uint8_t slide[WSIZE];
+  /* Current position in the slide.  */
+  unsigned wp;
+  /* The literal/length code table.  */
+  struct huft *tl;
+  /* The distance code table.  */
+  struct huft *td;
+  /* The lookup bits for the literal/length code table. */
+  int bl;
+  /* The lookup bits for the distance code table.  */
+  int bd;
+  /* The original offset value.  */
+  grub_off_t saved_offset;
+};
+typedef struct grub_gzio *grub_gzio_t;
+
+/* Declare the filesystem structure for grub_gzio_open.  */
+static struct grub_fs grub_gzio_fs;
+
+/* Function prototypes */
+static void initialize_tables (grub_file_t file);
+
+/* Eat variable-length header fields.  */
+static int
+eat_field (grub_file_t file, int len)
+{
+  char ch = 1;
+  int not_retval = 1;
+
+  do
+    {
+      if (len >= 0)
+       {
+         if (! (len--))
+           break;
+       }
+      else
+       {
+         if (! ch)
+           break;
+       }
+    }
+  while ((not_retval = grub_file_read (file, &ch, 1)) == 1);
+
+  return ! not_retval;
+}
+
+
+/* Little-Endian defines for the 2-byte magic numbers for gzip files.  */
+#define GZIP_MAGIC     grub_le_to_cpu16 (0x8B1F)
+#define OLD_GZIP_MAGIC grub_le_to_cpu16 (0x9E1F)
+
+/* Compression methods (see algorithm.doc) */
+#define STORED      0
+#define COMPRESSED  1
+#define PACKED      2
+#define LZHED       3
+/* methods 4 to 7 reserved */
+#define DEFLATED    8
+#define MAX_METHODS 9
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01      /* bit 0 set: file probably ascii text */
+#define CONTINUATION 0x02      /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04      /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08      /* bit 3 set: original file name present */
+#define COMMENT      0x10      /* bit 4 set: file comment present */
+#define ENCRYPTED    0x20      /* bit 5 set: file is encrypted */
+#define RESERVED     0xC0      /* bit 6,7:   reserved */
+
+#define UNSUPPORTED_FLAGS      (CONTINUATION | ENCRYPTED | RESERVED)
+
+/* inflate block codes */
+#define INFLATE_STORED 0
+#define INFLATE_FIXED  1
+#define INFLATE_DYNAMIC        2
+
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+
+static int
+test_header (grub_file_t file)
+{
+  struct {
+    grub_uint16_t magic;
+    grub_uint8_t method;
+    grub_uint8_t flags;
+    grub_uint32_t timestamp;
+    grub_uint8_t extra_flags;
+    grub_uint8_t os_type;
+  } hdr;
+  grub_uint16_t extra_len;
+  grub_uint32_t orig_len;
+  grub_gzio_t gzio = file->data;
+
+  if (grub_file_tell (gzio->file) != 0)
+    grub_file_seek (gzio->file, 0);
+
+  /*
+   *  This checks if the file is gzipped.  If a problem occurs here
+   *  (other than a real error with the disk) then we don't think it
+   *  is a compressed file, and simply mark it as such.
+   */
+  if (grub_file_read (gzio->file, &hdr, 10) != 10
+      || ((hdr.magic != GZIP_MAGIC)
+         && (hdr.magic != OLD_GZIP_MAGIC)))
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "no gzip magic found");
+      return 0;
+    }
+
+  /*
+   *  This does consistency checking on the header data.  If a
+   *  problem occurs from here on, then we have corrupt or otherwise
+   *  bad data, and the error should be reported to the user.
+   */
+  if (hdr.method != DEFLATED
+      || (hdr.flags & UNSUPPORTED_FLAGS)
+      || ((hdr.flags & EXTRA_FIELD)
+         && (grub_file_read (gzio->file, &extra_len, 2) != 2
+             || eat_field (gzio->file,
+                           grub_le_to_cpu16 (extra_len))))
+      || ((hdr.flags & ORIG_NAME) && eat_field (gzio->file, -1))
+      || ((hdr.flags & COMMENT) && eat_field (gzio->file, -1)))
+    {
+      grub_error (GRUB_ERR_BAD_GZIP_DATA, "unsupported gzip format");
+      return 0;
+    }
+
+  gzio->data_offset = grub_file_tell (gzio->file);
+
+  grub_file_seek (gzio->file, grub_file_size (gzio->file) - 4);
+
+  if (grub_file_read (gzio->file, &orig_len, 4) != 4)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported gzip format");
+      return 0;
+    }
+
+  /* FIXME: this does not handle files whose original size is over 4GB.
+     But how can we know the real original size?  */
+  file->size = grub_le_to_cpu32 (orig_len);
+
+  initialize_tables (file);
+
+  return 1;
+}
+
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+   that have 16-bit pointers (e.g. PC's in the small or medium model).
+   Valid extra bits are 0..13.  e == 15 is EOB (end of block), e == 16
+   means that v is a literal, 16 < e < 32 means that v is a pointer to
+   the next table, which codes e - 16 bits, and lastly e == 99 indicates
+   an unused code.  If a code with e == 99 is looked up, this implies an
+   error in the data. */
+struct huft
+{
+  uch e;                       /* number of extra bits or operation */
+  uch b;                       /* number of bits in this code or subcode */
+  union
+    {
+      ush n;                   /* literal, length base, or distance base */
+      struct huft *t;          /* pointer to next level of table */
+    }
+  v;
+};
+
+
+/* The inflate algorithm uses a sliding 32K byte window on the uncompressed
+   stream to find repeated byte strings.  This is implemented here as a
+   circular buffer.  The index is updated simply by incrementing and then
+   and'ing with 0x7fff (32K-1). */
+/* It is left to other modules to supply the 32K area.  It is assumed
+   to be usable as if it were declared "uch slide[32768];" or as just
+   "uch *slide;" and then malloc'ed in the latter case.  The definition
+   must be in unzip.h, included above. */
+
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+static unsigned bitorder[] =
+{                              /* Order of the bit length code lengths */
+  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+static ush cplens[] =
+{                              /* Copy lengths for literal codes 257..285 */
+  3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+       /* note: see note #13 above about the 258 in this list. */
+static ush cplext[] =
+{                              /* Extra bits for literal codes 257..285 */
+  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+  3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99};      /* 99==invalid */
+static ush cpdist[] =
+{                              /* Copy offsets for distance codes 0..29 */
+  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+  257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+  8193, 12289, 16385, 24577};
+static ush cpdext[] =
+{                              /* Extra bits for distance codes */
+  0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+  7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+  12, 12, 13, 13};
+
+
+/*
+   Huffman code decoding is performed using a multi-level table lookup.
+   The fastest way to decode is to simply build a lookup table whose
+   size is determined by the longest code.  However, the time it takes
+   to build this table can also be a factor if the data being decoded
+   is not very long.  The most common codes are necessarily the
+   shortest codes, so those codes dominate the decoding time, and hence
+   the speed.  The idea is you can have a shorter table that decodes the
+   shorter, more probable codes, and then point to subsidiary tables for
+   the longer codes.  The time it costs to decode the longer codes is
+   then traded against the time it takes to make longer tables.
+
+   This results of this trade are in the variables lbits and dbits
+   below.  lbits is the number of bits the first level table for literal/
+   length codes can decode in one step, and dbits is the same thing for
+   the distance codes.  Subsequent tables are also less than or equal to
+   those sizes.  These values may be adjusted either when all of the
+   codes are shorter than that, in which case the longest code length in
+   bits is used, or when the shortest code is *longer* than the requested
+   table size, in which case the length of the shortest code in bits is
+   used.
+
+   There are two different values for the two tables, since they code a
+   different number of possibilities each.  The literal/length table
+   codes 286 possible values, or in a flat code, a little over eight
+   bits.  The distance table codes 30 possible values, or a little less
+   than five bits, flat.  The optimum values for speed end up being
+   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+   The optimum values may differ though from machine to machine, and
+   possibly even between compilers.  Your mileage may vary.
+ */
+
+
+static int lbits = 9;          /* bits in base literal/length lookup table */
+static int dbits = 6;          /* bits in base distance lookup table */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
+#define BMAX 16                        /* maximum bit length of any code (16 for explode) */
+#define N_MAX 288              /* maximum number of codes in any set */
+
+
+/* Macros for inflate() bit peeking and grabbing.
+   The usage is:
+
+        NEEDBITS(j)
+        x = b & mask_bits[j];
+        DUMPBITS(j)
+
+   where NEEDBITS makes sure that b has at least j bits in it, and
+   DUMPBITS removes the bits from b.  The macros use the variable k
+   for the number of bits in b.  Normally, b and k are register
+   variables for speed, and are initialized at the beginning of a
+   routine that uses these macros from a global bit buffer and count.
+
+   If we assume that EOB will be the longest code, then we will never
+   ask for bits with NEEDBITS that are beyond the end of the stream.
+   So, NEEDBITS should not read any more bytes than are needed to
+   meet the request.  Then no bytes need to be "returned" to the buffer
+   at the end of the last block.
+
+   However, this assumption is not true for fixed blocks--the EOB code
+   is 7 bits, but the other literal/length codes can be 8 or 9 bits.
+   (The EOB code is shorter than other codes because fixed blocks are
+   generally short.  So, while a block always has an EOB, many other
+   literal/length codes have a significantly lower probability of
+   showing up at all.)  However, by making the first table have a
+   lookup of seven bits, the EOB code will be found in that first
+   lookup, and so will not require that too many bits be pulled from
+   the stream.
+ */
+
+static ush mask_bits[] =
+{
+  0x0000,
+  0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+  0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+#define NEEDBITS(n) do {while(k<(n)){b|=((ulg)get_byte(file))<<k;k+=8;}} while (0)
+#define DUMPBITS(n) do {b>>=(n);k-=(n);} while (0)
+
+static int
+get_byte (grub_file_t file)
+{
+  grub_gzio_t gzio = file->data;
+
+  if (grub_file_tell (gzio->file) == (grub_off_t) gzio->data_offset
+      || gzio->inbuf_d == INBUFSIZ)
+    {
+      gzio->inbuf_d = 0;
+      grub_file_read (gzio->file, gzio->inbuf, INBUFSIZ);
+    }
+
+  return gzio->inbuf[gzio->inbuf_d++];
+}
+
+/* more function prototypes */
+static int huft_build (unsigned *, unsigned, unsigned, ush *, ush *,
+                      struct huft **, int *);
+static int huft_free (struct huft *);
+static int inflate_codes_in_window (grub_file_t);
+
+
+/* Given a list of code lengths and a maximum table size, make a set of
+   tables to decode that set of codes.  Return zero on success, one if
+   the given code set is incomplete (the tables are still built in this
+   case), two if the input is invalid (all zero length codes or an
+   oversubscribed set of lengths), and three if not enough memory. */
+
+static int
+huft_build (unsigned *b,       /* code lengths in bits (all assumed <= BMAX) */
+           unsigned n,         /* number of codes (assumed <= N_MAX) */
+           unsigned s,         /* number of simple-valued codes (0..s-1) */
+           ush * d,            /* list of base values for non-simple codes */
+           ush * e,            /* list of extra bits for non-simple codes */
+           struct huft **t,    /* result: starting table */
+           int *m)             /* maximum lookup bits, returns actual */
+{
+  unsigned a;                  /* counter for codes of length k */
+  unsigned c[BMAX + 1];                /* bit length count table */
+  unsigned f;                  /* i repeats in table every f entries */
+  int g;                       /* maximum code length */
+  int h;                       /* table level */
+  register unsigned i;         /* counter, current code */
+  register unsigned j;         /* counter */
+  register int k;              /* number of bits in current code */
+  int l;                       /* bits per table (returned in m) */
+  register unsigned *p;                /* pointer into c[], b[], or v[] */
+  register struct huft *q;     /* points to current table */
+  struct huft r;               /* table entry for structure assignment */
+  struct huft *u[BMAX];                /* table stack */
+  unsigned v[N_MAX];           /* values in order of bit length */
+  register int w;              /* bits before this table == (l * h) */
+  unsigned x[BMAX + 1];                /* bit offsets, then code stack */
+  unsigned *xp;                        /* pointer into x */
+  int y;                       /* number of dummy codes added */
+  unsigned z;                  /* number of entries in current table */
+
+  /* Generate counts for each bit length */
+  grub_memset ((char *) c, 0, sizeof (c));
+  p = b;
+  i = n;
+  do
+    {
+      c[*p]++;                 /* assume all entries <= BMAX */
+      p++;                     /* Can't combine with above line (Solaris bug) */
+    }
+  while (--i);
+  if (c[0] == n)               /* null input--all zero length codes */
+    {
+      *t = (struct huft *) NULL;
+      *m = 0;
+      return 0;
+    }
+
+  /* Find minimum and maximum length, bound *m by those */
+  l = *m;
+  for (j = 1; j <= BMAX; j++)
+    if (c[j])
+      break;
+  k = j;                       /* minimum code length */
+  if ((unsigned) l < j)
+    l = j;
+  for (i = BMAX; i; i--)
+    if (c[i])
+      break;
+  g = i;                       /* maximum code length */
+  if ((unsigned) l > i)
+    l = i;
+  *m = l;
+
+  /* Adjust last length count to fill out codes, if needed */
+  for (y = 1 << j; j < i; j++, y <<= 1)
+    if ((y -= c[j]) < 0)
+      return 2;                        /* bad input: more codes than bits */
+  if ((y -= c[i]) < 0)
+    return 2;
+  c[i] += y;
+
+  /* Generate starting offsets into the value table for each length */
+  x[1] = j = 0;
+  p = c + 1;
+  xp = x + 2;
+  while (--i)
+    {                          /* note that i == g from above */
+      *xp++ = (j += *p++);
+    }
+
+  /* Make a table of values in order of bit lengths */
+  p = b;
+  i = 0;
+  do
+    {
+      if ((j = *p++) != 0)
+       v[x[j]++] = i;
+    }
+  while (++i < n);
+
+  /* Generate the Huffman codes and for each, make the table entries */
+  x[0] = i = 0;                        /* first Huffman code is zero */
+  p = v;                       /* grab values in bit order */
+  h = -1;                      /* no tables yet--level -1 */
+  w = -l;                      /* bits decoded == (l * h) */
+  u[0] = (struct huft *) NULL; /* just to keep compilers happy */
+  q = (struct huft *) NULL;    /* ditto */
+  z = 0;                       /* ditto */
+
+  /* go through the bit lengths (k already is bits in shortest code) */
+  for (; k <= g; k++)
+    {
+      a = c[k];
+      while (a--)
+       {
+         /* here i is the Huffman code of length k bits for value *p */
+         /* make tables up to required level */
+         while (k > w + l)
+           {
+             h++;
+             w += l;           /* previous table always l bits */
+
+             /* compute minimum size table less than or equal to l bits */
+             z = (z = (unsigned) (g - w)) > (unsigned) l ? (unsigned) l : z;   /* upper limit on table size */
+             if ((f = 1 << (j = k - w)) > a + 1)       /* try a k-w bit table */
+               {               /* too few codes for k-w bit table */
+                 f -= a + 1;   /* deduct codes from patterns left */
+                 xp = c + k;
+                 while (++j < z)       /* try smaller tables up to z bits */
+                   {
+                     if ((f <<= 1) <= *++xp)
+                       break;  /* enough codes to use up j bits */
+                     f -= *xp; /* else deduct codes from patterns */
+                   }
+               }
+             z = 1 << j;       /* table entries for j-bit table */
+
+             /* allocate and link in new table */
+             q = (struct huft *) grub_malloc ((z + 1) * sizeof (struct huft));
+             if (! q)
+               {
+                 if (h)
+                   huft_free (u[0]);
+                 return 3;
+               }
+
+             *t = q + 1;       /* link to list for huft_free() */
+             *(t = &(q->v.t)) = (struct huft *) NULL;
+             u[h] = ++q;       /* table starts after link */
+
+             /* connect to last table, if there is one */
+             if (h)
+               {
+                 x[h] = i;     /* save pattern for backing up */
+                 r.b = (uch) l;        /* bits to dump before this table */
+                 r.e = (uch) (16 + j);         /* bits in this table */
+                 r.v.t = q;    /* pointer to this table */
+                 j = i >> (w - l);     /* (get around Turbo C bug) */
+                 u[h - 1][j] = r;      /* connect to last table */
+               }
+           }
+
+         /* set up table entry in r */
+         r.b = (uch) (k - w);
+         if (p >= v + n)
+           r.e = 99;           /* out of values--invalid code */
+         else if (*p < s)
+           {
+             r.e = (uch) (*p < 256 ? 16 : 15);         /* 256 is end-of-block code */
+             r.v.n = (ush) (*p);       /* simple code is just the value */
+             p++;              /* one compiler does not like *p++ */
+           }
+         else
+           {
+             r.e = (uch) e[*p - s];    /* non-simple--look up in lists */
+             r.v.n = d[*p++ - s];
+           }
+
+         /* fill code-like entries with r */
+         f = 1 << (k - w);
+         for (j = i >> w; j < z; j += f)
+           q[j] = r;
+
+         /* backwards increment the k-bit code i */
+         for (j = 1 << (k - 1); i & j; j >>= 1)
+           i ^= j;
+         i ^= j;
+
+         /* backup over finished tables */
+         while ((i & ((1 << w) - 1)) != x[h])
+           {
+             h--;              /* don't need to update q */
+             w -= l;
+           }
+       }
+    }
+
+  /* Return true (1) if we were given an incomplete table */
+  return y != 0 && g != 1;
+}
+
+
+/* Free the malloc'ed tables built by huft_build(), which makes a linked
+   list of the tables it made, with the links in a dummy first entry of
+   each table.  */
+static int
+huft_free (struct huft *t)
+{
+  register struct huft *p, *q;
+
+
+  /* Go through linked list, freeing from the malloced (t[-1]) address. */
+  p = t;
+  while (p != (struct huft *) NULL)
+    {
+      q = (--p)->v.t;
+      grub_free ((char *) p);
+      p = q;
+    }
+  return 0;
+}
+
+
+/*
+ *  inflate (decompress) the codes in a deflated (compressed) block.
+ *  Return an error code or zero if it all goes ok.
+ */
+
+static int
+inflate_codes_in_window (grub_file_t file)
+{
+  register unsigned e;         /* table entry flag/number of extra bits */
+  unsigned n, d;               /* length and index for copy */
+  unsigned w;                  /* current window position */
+  struct huft *t;              /* pointer to table entry */
+  unsigned ml, md;             /* masks for bl and bd bits */
+  register ulg b;              /* bit buffer */
+  register unsigned k;         /* number of bits in bit buffer */
+  grub_gzio_t gzio = file->data;
+
+  /* make local copies of globals */
+  d = gzio->inflate_d;
+  n = gzio->inflate_n;
+  b = gzio->bb;                        /* initialize bit buffer */
+  k = gzio->bk;
+  w = gzio->wp;                        /* initialize window position */
+
+  /* inflate the coded data */
+  ml = mask_bits[gzio->bl];            /* precompute masks for speed */
+  md = mask_bits[gzio->bd];
+  for (;;)                     /* do until end of block */
+    {
+      if (! gzio->code_state)
+       {
+         NEEDBITS ((unsigned) gzio->bl);
+         if ((e = (t = gzio->tl + ((unsigned) b & ml))->e) > 16)
+           do
+             {
+               if (e == 99)
+                 {
+                   grub_error (GRUB_ERR_BAD_GZIP_DATA,
+                               "an unused code found");
+                   return 1;
+                 }
+               DUMPBITS (t->b);
+               e -= 16;
+               NEEDBITS (e);
+             }
+           while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16);
+         DUMPBITS (t->b);
+
+         if (e == 16)          /* then it's a literal */
+           {
+             gzio->slide[w++] = (uch) t->v.n;
+             if (w == WSIZE)
+               break;
+           }
+         else
+           /* it's an EOB or a length */
+           {
+             /* exit if end of block */
+             if (e == 15)
+               {
+                 gzio->block_len = 0;
+                 break;
+               }
+
+             /* get length of block to copy */
+             NEEDBITS (e);
+             n = t->v.n + ((unsigned) b & mask_bits[e]);
+             DUMPBITS (e);
+
+             /* decode distance of block to copy */
+             NEEDBITS ((unsigned) gzio->bd);
+             if ((e = (t = gzio->td + ((unsigned) b & md))->e) > 16)
+               do
+                 {
+                   if (e == 99)
+                     {
+                       grub_error (GRUB_ERR_BAD_GZIP_DATA,
+                                   "an unused code found");
+                       return 1;
+                     }
+                   DUMPBITS (t->b);
+                   e -= 16;
+                   NEEDBITS (e);
+                 }
+               while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e)
+                      > 16);
+             DUMPBITS (t->b);
+             NEEDBITS (e);
+             d = w - t->v.n - ((unsigned) b & mask_bits[e]);
+             DUMPBITS (e);
+             gzio->code_state++;
+           }
+       }
+
+      if (gzio->code_state)
+       {
+         /* do the copy */
+         do
+           {
+             n -= (e = (e = WSIZE - ((d &= WSIZE - 1) > w ? d : w)) > n ? n
+                   : e);
+
+             if (w - d >= e)
+               {
+                 grub_memmove (gzio->slide + w, gzio->slide + d, e);
+                 w += e;
+                 d += e;
+               }
+             else
+               /* purposefully use the overlap for extra copies here!! */
+               {
+                 while (e--)
+                   gzio->slide[w++] = gzio->slide[d++];
+               }
+
+             if (w == WSIZE)
+               break;
+           }
+         while (n);
+
+         if (! n)
+           gzio->code_state--;
+
+         /* did we break from the loop too soon? */
+         if (w == WSIZE)
+           break;
+       }
+    }
+
+  /* restore the globals from the locals */
+  gzio->inflate_d = d;
+  gzio->inflate_n = n;
+  gzio->wp = w;                        /* restore global window pointer */
+  gzio->bb = b;                        /* restore global bit buffer */
+  gzio->bk = k;
+
+  return ! gzio->block_len;
+}
+
+
+/* get header for an inflated type 0 (stored) block. */
+
+static void
+init_stored_block (grub_file_t file)
+{
+  register ulg b;              /* bit buffer */
+  register unsigned k;         /* number of bits in bit buffer */
+  grub_gzio_t gzio = file->data;
+
+  /* make local copies of globals */
+  b = gzio->bb;                        /* initialize bit buffer */
+  k = gzio->bk;
+
+  /* go to byte boundary */
+  DUMPBITS (k & 7);
+
+  /* get the length and its complement */
+  NEEDBITS (16);
+  gzio->block_len = ((unsigned) b & 0xffff);
+  DUMPBITS (16);
+  NEEDBITS (16);
+  if (gzio->block_len != (int) ((~b) & 0xffff))
+    grub_error (GRUB_ERR_BAD_GZIP_DATA,
+               "the length of a stored block does not match");
+  DUMPBITS (16);
+
+  /* restore global variables */
+  gzio->bb = b;
+  gzio->bk = k;
+}
+
+
+/* get header for an inflated type 1 (fixed Huffman codes) block.  We should
+   either replace this with a custom decoder, or at least precompute the
+   Huffman tables. */
+
+static void
+init_fixed_block (grub_file_t file)
+{
+  int i;                       /* temporary variable */
+  unsigned l[288];             /* length list for huft_build */
+  grub_gzio_t gzio = file->data;
+
+  /* set up literal table */
+  for (i = 0; i < 144; i++)
+    l[i] = 8;
+  for (; i < 256; i++)
+    l[i] = 9;
+  for (; i < 280; i++)
+    l[i] = 7;
+  for (; i < 288; i++)         /* make a complete, but wrong code set */
+    l[i] = 8;
+  gzio->bl = 7;
+  if (huft_build (l, 288, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0)
+    {
+      if (grub_errno == GRUB_ERR_NONE)
+       grub_error (GRUB_ERR_BAD_GZIP_DATA,
+                   "failed in building a Huffman code table");
+      return;
+    }
+
+  /* set up distance table */
+  for (i = 0; i < 30; i++)     /* make an incomplete code set */
+    l[i] = 5;
+  gzio->bd = 5;
+  if (huft_build (l, 30, 0, cpdist, cpdext, &gzio->td, &gzio->bd) > 1)
+    {
+      if (grub_errno == GRUB_ERR_NONE)
+       grub_error (GRUB_ERR_BAD_GZIP_DATA,
+                   "failed in building a Huffman code table");
+      huft_free (gzio->tl);
+      gzio->tl = 0;
+      return;
+    }
+
+  /* indicate we're now working on a block */
+  gzio->code_state = 0;
+  gzio->block_len++;
+}
+
+
+/* get header for an inflated type 2 (dynamic Huffman codes) block. */
+
+static void
+init_dynamic_block (grub_file_t file)
+{
+  int i;                       /* temporary variables */
+  unsigned j;
+  unsigned l;                  /* last length */
+  unsigned m;                  /* mask for bit lengths table */
+  unsigned n;                  /* number of lengths to get */
+  unsigned nb;                 /* number of bit length codes */
+  unsigned nl;                 /* number of literal/length codes */
+  unsigned nd;                 /* number of distance codes */
+  unsigned ll[286 + 30];       /* literal/length and distance code lengths */
+  register ulg b;              /* bit buffer */
+  register unsigned k;         /* number of bits in bit buffer */
+  grub_gzio_t gzio = file->data;
+
+  /* make local bit buffer */
+  b = gzio->bb;
+  k = gzio->bk;
+
+  /* read in table lengths */
+  NEEDBITS (5);
+  nl = 257 + ((unsigned) b & 0x1f);    /* number of literal/length codes */
+  DUMPBITS (5);
+  NEEDBITS (5);
+  nd = 1 + ((unsigned) b & 0x1f);      /* number of distance codes */
+  DUMPBITS (5);
+  NEEDBITS (4);
+  nb = 4 + ((unsigned) b & 0xf);       /* number of bit length codes */
+  DUMPBITS (4);
+  if (nl > 286 || nd > 30)
+    {
+      grub_error (GRUB_ERR_BAD_GZIP_DATA, "too much data");
+      return;
+    }
+
+  /* read in bit-length-code lengths */
+  for (j = 0; j < nb; j++)
+    {
+      NEEDBITS (3);
+      ll[bitorder[j]] = (unsigned) b & 7;
+      DUMPBITS (3);
+    }
+  for (; j < 19; j++)
+    ll[bitorder[j]] = 0;
+
+  /* build decoding table for trees--single level, 7 bit lookup */
+  gzio->bl = 7;
+  if (huft_build (ll, 19, 19, NULL, NULL, &gzio->tl, &gzio->bl) != 0)
+    {
+      grub_error (GRUB_ERR_BAD_GZIP_DATA,
+                 "failed in building a Huffman code table");
+      return;
+    }
+
+  /* read in literal and distance code lengths */
+  n = nl + nd;
+  m = mask_bits[gzio->bl];
+  i = l = 0;
+  while ((unsigned) i < n)
+    {
+      NEEDBITS ((unsigned) gzio->bl);
+      j = (gzio->td = gzio->tl + ((unsigned) b & m))->b;
+      DUMPBITS (j);
+      j = gzio->td->v.n;
+      if (j < 16)              /* length of code in bits (0..15) */
+       ll[i++] = l = j;        /* save last length in l */
+      else if (j == 16)                /* repeat last length 3 to 6 times */
+       {
+         NEEDBITS (2);
+         j = 3 + ((unsigned) b & 3);
+         DUMPBITS (2);
+         if ((unsigned) i + j > n)
+           {
+             grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found");
+             return;
+           }
+         while (j--)
+           ll[i++] = l;
+       }
+      else if (j == 17)                /* 3 to 10 zero length codes */
+       {
+         NEEDBITS (3);
+         j = 3 + ((unsigned) b & 7);
+         DUMPBITS (3);
+         if ((unsigned) i + j > n)
+           {
+             grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found");
+             return;
+           }
+         while (j--)
+           ll[i++] = 0;
+         l = 0;
+       }
+      else
+       /* j == 18: 11 to 138 zero length codes */
+       {
+         NEEDBITS (7);
+         j = 11 + ((unsigned) b & 0x7f);
+         DUMPBITS (7);
+         if ((unsigned) i + j > n)
+           {
+             grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found");
+             return;
+           }
+         while (j--)
+           ll[i++] = 0;
+         l = 0;
+       }
+    }
+
+  /* free decoding table for trees */
+  huft_free (gzio->tl);
+  gzio->td = 0;
+  gzio->tl = 0;
+
+  /* restore the global bit buffer */
+  gzio->bb = b;
+  gzio->bk = k;
+
+  /* build the decoding tables for literal/length and distance codes */
+  gzio->bl = lbits;
+  if (huft_build (ll, nl, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0)
+    {
+      grub_error (GRUB_ERR_BAD_GZIP_DATA,
+                 "failed in building a Huffman code table");
+      return;
+    }
+  gzio->bd = dbits;
+  if (huft_build (ll + nl, nd, 0, cpdist, cpdext, &gzio->td, &gzio->bd) != 0)
+    {
+      huft_free (gzio->tl);
+      gzio->tl = 0;
+      grub_error (GRUB_ERR_BAD_GZIP_DATA,
+                 "failed in building a Huffman code table");
+      return;
+    }
+
+  /* indicate we're now working on a block */
+  gzio->code_state = 0;
+  gzio->block_len++;
+}
+
+
+static void
+get_new_block (grub_file_t file)
+{
+  register ulg b;              /* bit buffer */
+  register unsigned k;         /* number of bits in bit buffer */
+  grub_gzio_t gzio = file->data;
+
+  /* make local bit buffer */
+  b = gzio->bb;
+  k = gzio->bk;
+
+  /* read in last block bit */
+  NEEDBITS (1);
+  gzio->last_block = (int) b & 1;
+  DUMPBITS (1);
+
+  /* read in block type */
+  NEEDBITS (2);
+  gzio->block_type = (unsigned) b & 3;
+  DUMPBITS (2);
+
+  /* restore the global bit buffer */
+  gzio->bb = b;
+  gzio->bk = k;
+
+  switch (gzio->block_type)
+    {
+    case INFLATE_STORED:
+      init_stored_block (file);
+      break;
+    case INFLATE_FIXED:
+      init_fixed_block (file);
+      break;
+    case INFLATE_DYNAMIC:
+      init_dynamic_block (file);
+      break;
+    default:
+      break;
+    }
+}
+
+
+static void
+inflate_window (grub_file_t file)
+{
+  grub_gzio_t gzio = file->data;
+
+  /* initialize window */
+  gzio->wp = 0;
+
+  /*
+   *  Main decompression loop.
+   */
+
+  while (gzio->wp < WSIZE && grub_errno == GRUB_ERR_NONE)
+    {
+      if (! gzio->block_len)
+       {
+         if (gzio->last_block)
+           break;
+
+         get_new_block (file);
+       }
+
+      if (gzio->block_type > INFLATE_DYNAMIC)
+       grub_error (GRUB_ERR_BAD_GZIP_DATA,
+                   "unknown block type %d", gzio->block_type);
+
+      if (grub_errno != GRUB_ERR_NONE)
+       return;
+
+      /*
+       *  Expand stored block here.
+       */
+      if (gzio->block_type == INFLATE_STORED)
+       {
+         int w = gzio->wp;
+
+         /*
+          *  This is basically a glorified pass-through
+          */
+
+         while (gzio->block_len && w < WSIZE && grub_errno == GRUB_ERR_NONE)
+           {
+             gzio->slide[w++] = get_byte (file);
+             gzio->block_len--;
+           }
+
+         gzio->wp = w;
+
+         continue;
+       }
+
+      /*
+       *  Expand other kind of block.
+       */
+
+      if (inflate_codes_in_window (file))
+       {
+         huft_free (gzio->tl);
+         huft_free (gzio->td);
+         gzio->tl = 0;
+         gzio->td = 0;
+       }
+    }
+
+  gzio->saved_offset += WSIZE;
+
+  /* XXX do CRC calculation here! */
+}
+
+
+static void
+initialize_tables (grub_file_t file)
+{
+  grub_gzio_t gzio = file->data;
+
+  gzio->saved_offset = 0;
+  grub_file_seek (gzio->file, gzio->data_offset);
+
+  /* Initialize the bit buffer.  */
+  gzio->bk = 0;
+  gzio->bb = 0;
+
+  /* Reset partial decompression code.  */
+  gzio->last_block = 0;
+  gzio->block_len = 0;
+
+  /* Reset memory allocation stuff.  */
+  huft_free (gzio->tl);
+  huft_free (gzio->td);
+}
+
+
+/* Open a new decompressing object on the top of IO. If TRANSPARENT is true,
+   even if IO does not contain data compressed by gzip, return a valid file
+   object. Note that this function won't close IO, even if an error occurs.  */
+grub_file_t
+grub_gzio_open (grub_file_t io, int transparent)
+{
+  grub_file_t file;
+  grub_gzio_t gzio = 0;
+
+  file = (grub_file_t) grub_malloc (sizeof (*file));
+  if (! file)
+    return 0;
+
+  gzio = grub_zalloc (sizeof (*gzio));
+  if (! gzio)
+    {
+      grub_free (file);
+      return 0;
+    }
+
+  gzio->file = io;
+
+  file->device = io->device;
+  file->offset = 0;
+  file->data = gzio;
+  file->read_hook = 0;
+  file->fs = &grub_gzio_fs;
+
+  if (! test_header (file))
+    {
+      grub_free (gzio);
+      grub_free (file);
+      grub_file_seek (io, 0);
+
+      if (grub_errno == GRUB_ERR_BAD_FILE_TYPE && transparent)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         return io;
+       }
+      else
+       return 0;
+    }
+
+  return file;
+}
+
+/* This is similar to grub_gzio_open, but takes a file name as an argument.  */
+grub_file_t
+grub_gzfile_open (const char *name, int transparent)
+{
+  grub_file_t io, file;
+
+  io = grub_file_open (name);
+  if (! io)
+    return 0;
+
+  file = grub_gzio_open (io, transparent);
+  if (! file)
+    {
+      grub_file_close (io);
+      return 0;
+    }
+
+  return file;
+}
+
+static grub_ssize_t
+grub_gzio_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  grub_ssize_t ret = 0;
+  grub_gzio_t gzio = file->data;
+  grub_off_t offset;
+
+  /* Do we reset decompression to the beginning of the file?  */
+  if (gzio->saved_offset > file->offset + WSIZE)
+    initialize_tables (file);
+
+  /*
+   *  This loop operates upon uncompressed data only.  The only
+   *  special thing it does is to make sure the decompression
+   *  window is within the range of data it needs.
+   */
+
+  offset = file->offset;
+
+  while (len > 0 && grub_errno == GRUB_ERR_NONE)
+    {
+      register grub_size_t size;
+      register char *srcaddr;
+
+      while (offset >= gzio->saved_offset)
+       inflate_window (file);
+
+      srcaddr = (char *) ((offset & (WSIZE - 1)) + gzio->slide);
+      size = gzio->saved_offset - offset;
+      if (size > len)
+       size = len;
+
+      grub_memmove (buf, srcaddr, size);
+
+      buf += size;
+      len -= size;
+      ret += size;
+      offset += size;
+    }
+
+  if (grub_errno != GRUB_ERR_NONE)
+    ret = -1;
+
+  return ret;
+}
+
+/* Release everything, including the underlying file object.  */
+static grub_err_t
+grub_gzio_close (grub_file_t file)
+{
+  grub_gzio_t gzio = file->data;
+
+  grub_file_close (gzio->file);
+  huft_free (gzio->tl);
+  huft_free (gzio->td);
+  grub_free (gzio);
+
+  /* No need to close the same device twice.  */
+  file->device = 0;
+
+  return grub_errno;
+}
+
+\f
+
+static struct grub_fs grub_gzio_fs =
+  {
+    .name = "gzio",
+    .dir = 0,
+    .open = 0,
+    .read = grub_gzio_read,
+    .close = grub_gzio_close,
+    .label = 0,
+    .next = 0
+  };
diff --git a/grub-core/kern/command.c b/grub-core/kern/command.c
new file mode 100644 (file)
index 0000000..477240d
--- /dev/null
@@ -0,0 +1,58 @@
+/* command.c - support basic command */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/command.h>
+
+grub_command_t grub_command_list;
+
+grub_command_t
+grub_register_command_prio (const char *name,
+                           grub_command_func_t func,
+                           const char *summary,
+                           const char *description,
+                           int prio)
+{
+  grub_command_t cmd;
+
+  cmd = (grub_command_t) grub_zalloc (sizeof (*cmd));
+  if (! cmd)
+    return 0;
+
+  cmd->name = name;
+  cmd->func = func;
+  cmd->summary = (summary) ? summary : "";
+  cmd->description = description;
+
+  cmd->flags = GRUB_COMMAND_FLAG_BOTH;
+  cmd->prio = prio;
+
+  grub_prio_list_insert (GRUB_AS_PRIO_LIST_P (&grub_command_list),
+                        GRUB_AS_PRIO_LIST (cmd));
+
+  return cmd;
+}
+
+void
+grub_unregister_command (grub_command_t cmd)
+{
+  grub_prio_list_remove (GRUB_AS_PRIO_LIST_P (&grub_command_list),
+                        GRUB_AS_PRIO_LIST (cmd));
+  grub_free (cmd);
+}
diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c
new file mode 100644 (file)
index 0000000..9af706e
--- /dev/null
@@ -0,0 +1,191 @@
+/* corecmd.c - critical commands which are registered in kernel */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/err.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/file.h>
+#include <grub/device.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+/* set ENVVAR=VALUE */
+static grub_err_t
+grub_core_cmd_set (struct grub_command *cmd __attribute__ ((unused)),
+                  int argc, char *argv[])
+{
+  char *var;
+  char *val;
+
+  auto int print_env (struct grub_env_var *env);
+
+  int print_env (struct grub_env_var *env)
+    {
+      grub_printf ("%s=%s\n", env->name, env->value);
+      return 0;
+    }
+
+  if (argc < 1)
+    {
+      grub_env_iterate (print_env);
+      return 0;
+    }
+
+  var = argv[0];
+  val = grub_strchr (var, '=');
+  if (! val)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "not an assignment");
+
+  val[0] = 0;
+  grub_env_set (var, val + 1);
+  val[0] = '=';
+
+  return 0;
+}
+
+static grub_err_t
+grub_core_cmd_unset (struct grub_command *cmd __attribute__ ((unused)),
+                    int argc, char *argv[])
+{
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "no environment variable specified");
+
+  grub_env_unset (argv[0]);
+  return 0;
+}
+
+/* insmod MODULE */
+static grub_err_t
+grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)),
+                     int argc, char *argv[])
+{
+  char *p;
+  grub_dl_t mod;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
+
+  p = grub_strchr (argv[0], '/');
+  if (! p)
+    mod = grub_dl_load (argv[0]);
+  else
+    mod = grub_dl_load_file (argv[0]);
+
+  if (mod)
+    grub_dl_ref (mod);
+
+  return 0;
+}
+
+static int
+grub_mini_print_devices (const char *name)
+{
+  grub_printf ("(%s) ", name);
+
+  return 0;
+}
+
+static int
+grub_mini_print_files (const char *filename,
+                      const struct grub_dirhook_info *info)
+{
+  grub_printf ("%s%s ", filename, info->dir ? "/" : "");
+
+  return 0;
+}
+
+/* ls [ARG] */
+static grub_err_t
+grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
+                 int argc, char *argv[])
+{
+  if (argc < 1)
+    {
+      grub_device_iterate (grub_mini_print_devices);
+      grub_putchar ('\n');
+      grub_refresh ();
+    }
+  else
+    {
+      char *device_name;
+      grub_device_t dev;
+      grub_fs_t fs;
+      char *path;
+
+      device_name = grub_file_get_device_name (argv[0]);
+      dev = grub_device_open (device_name);
+      if (! dev)
+       goto fail;
+
+      fs = grub_fs_probe (dev);
+      path = grub_strchr (argv[0], ')');
+      if (! path)
+       path = argv[0];
+      else
+       path++;
+
+      if (! path && ! device_name)
+       {
+         grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
+         goto fail;
+       }
+
+      if (! path)
+       {
+         if (grub_errno == GRUB_ERR_UNKNOWN_FS)
+           grub_errno = GRUB_ERR_NONE;
+
+         grub_printf ("(%s): Filesystem is %s.\n",
+                      device_name, fs ? fs->name : "unknown");
+       }
+      else if (fs)
+       {
+         (fs->dir) (dev, path, grub_mini_print_files);
+         grub_putchar ('\n');
+         grub_refresh ();
+       }
+
+    fail:
+      if (dev)
+       grub_device_close (dev);
+
+      grub_free (device_name);
+    }
+
+  return grub_errno;
+}
+
+void
+grub_register_core_commands (void)
+{
+  grub_register_command ("set", grub_core_cmd_set,
+                        N_("[ENVVAR=VALUE]"),
+                        N_("Set an environment variable."));
+  grub_register_command ("unset", grub_core_cmd_unset,
+                        N_("ENVVAR"),
+                        N_("Remove an environment variable."));
+  grub_register_command ("ls", grub_core_cmd_ls,
+                        N_("[ARG]"), N_("List devices or files."));
+  grub_register_command ("insmod", grub_core_cmd_insmod,
+                        N_("MODULE"), N_("Insert a module."));
+}
diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c
new file mode 100644 (file)
index 0000000..4273fed
--- /dev/null
@@ -0,0 +1,169 @@
+/* device.c - device manager */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/net.h>
+#include <grub/fs.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/partition.h>
+
+grub_device_t
+grub_device_open (const char *name)
+{
+  grub_disk_t disk = 0;
+  grub_device_t dev = 0;
+
+  if (! name)
+    {
+      name = grub_env_get ("root");
+      if (*name == '\0')
+       {
+         grub_error (GRUB_ERR_BAD_DEVICE, "no device is set");
+         goto fail;
+       }
+    }
+
+  dev = grub_malloc (sizeof (*dev));
+  if (! dev)
+    goto fail;
+
+  /* Try to open a disk.  */
+  disk = grub_disk_open (name);
+  if (! disk)
+    goto fail;
+
+  dev->disk = disk;
+  dev->net = 0;        /* FIXME */
+
+  return dev;
+
+ fail:
+  if (disk)
+    grub_disk_close (disk);
+
+  grub_free (dev);
+
+  return 0;
+}
+
+grub_err_t
+grub_device_close (grub_device_t device)
+{
+  if (device->disk)
+    grub_disk_close (device->disk);
+
+  grub_free (device);
+
+  return grub_errno;
+}
+
+int
+grub_device_iterate (int (*hook) (const char *name))
+{
+  auto int iterate_disk (const char *disk_name);
+  auto int iterate_partition (grub_disk_t disk,
+                             const grub_partition_t partition);
+
+  struct part_ent
+  {
+    struct part_ent *next;
+    char *name;
+  } *ents;
+
+  int iterate_disk (const char *disk_name)
+    {
+      grub_device_t dev;
+
+      if (hook (disk_name))
+       return 1;
+
+      dev = grub_device_open (disk_name);
+      if (! dev)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         return 0;
+       }
+
+      if (dev->disk && dev->disk->has_partitions)
+       {
+         struct part_ent *p;
+         int ret = 0;
+
+         ents = NULL;
+         (void) grub_partition_iterate (dev->disk, iterate_partition);
+         grub_device_close (dev);
+
+         grub_errno = GRUB_ERR_NONE;
+
+         p = ents;
+         while (p != NULL)
+           {
+             struct part_ent *next = p->next;
+
+             if (!ret)
+               ret = hook (p->name);
+             grub_free (p->name);
+             grub_free (p);
+             p = next;
+           }
+
+         return ret;
+       }
+
+      grub_device_close (dev);
+      return 0;
+    }
+
+  int iterate_partition (grub_disk_t disk, const grub_partition_t partition)
+    {
+      char *partition_name;
+      struct part_ent *p;
+
+      partition_name = grub_partition_get_name (partition);
+      if (! partition_name)
+       return 1;
+
+      p = grub_malloc (sizeof (*p));
+      if (!p)
+       {
+         grub_free (partition_name);
+         return 1;
+       }
+
+      p->name = grub_xasprintf ("%s,%s", disk->name, partition_name);
+      if (!p->name)
+       {
+         grub_free (partition_name);
+         grub_free (p);
+         return 1;
+       }
+      grub_free (partition_name);
+
+      p->next = ents;
+      ents = p;
+
+      return 0;
+    }
+
+  /* Only disk devices are supported at the moment.  */
+  return grub_disk_dev_iterate (iterate_disk);
+}
diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c
new file mode 100644 (file)
index 0000000..ccd5f20
--- /dev/null
@@ -0,0 +1,608 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/partition.h>
+#include <grub/misc.h>
+#include <grub/time.h>
+#include <grub/file.h>
+
+#define        GRUB_CACHE_TIMEOUT      2
+
+/* The last time the disk was used.  */
+static grub_uint64_t grub_last_time = 0;
+
+
+/* Disk cache.  */
+struct grub_disk_cache
+{
+  enum grub_disk_dev_id dev_id;
+  unsigned long disk_id;
+  grub_disk_addr_t sector;
+  char *data;
+  int lock;
+};
+
+static struct grub_disk_cache grub_disk_cache_table[GRUB_DISK_CACHE_NUM];
+
+void (*grub_disk_firmware_fini) (void);
+int grub_disk_firmware_is_tainted;
+
+grub_err_t (* grub_disk_ata_pass_through) (grub_disk_t,
+           struct grub_disk_ata_pass_through_parms *);
+
+
+#if 0
+static unsigned long grub_disk_cache_hits;
+static unsigned long grub_disk_cache_misses;
+
+void
+grub_disk_cache_get_performance (unsigned long *hits, unsigned long *misses)
+{
+  *hits = grub_disk_cache_hits;
+  *misses = grub_disk_cache_misses;
+}
+#endif
+
+static unsigned
+grub_disk_cache_get_index (unsigned long dev_id, unsigned long disk_id,
+                          grub_disk_addr_t sector)
+{
+  return ((dev_id * 524287UL + disk_id * 2606459UL
+          + ((unsigned) (sector >> GRUB_DISK_CACHE_BITS)))
+         % GRUB_DISK_CACHE_NUM);
+}
+
+static void
+grub_disk_cache_invalidate (unsigned long dev_id, unsigned long disk_id,
+                           grub_disk_addr_t sector)
+{
+  unsigned index;
+  struct grub_disk_cache *cache;
+
+  sector &= ~(GRUB_DISK_CACHE_SIZE - 1);
+  index = grub_disk_cache_get_index (dev_id, disk_id, sector);
+  cache = grub_disk_cache_table + index;
+
+  if (cache->dev_id == dev_id && cache->disk_id == disk_id
+      && cache->sector == sector && cache->data)
+    {
+      cache->lock = 1;
+      grub_free (cache->data);
+      cache->data = 0;
+      cache->lock = 0;
+    }
+}
+
+void
+grub_disk_cache_invalidate_all (void)
+{
+  unsigned i;
+
+  for (i = 0; i < GRUB_DISK_CACHE_NUM; i++)
+    {
+      struct grub_disk_cache *cache = grub_disk_cache_table + i;
+
+      if (cache->data && ! cache->lock)
+       {
+         grub_free (cache->data);
+         cache->data = 0;
+       }
+    }
+}
+
+static char *
+grub_disk_cache_fetch (unsigned long dev_id, unsigned long disk_id,
+                      grub_disk_addr_t sector)
+{
+  struct grub_disk_cache *cache;
+  unsigned index;
+
+  index = grub_disk_cache_get_index (dev_id, disk_id, sector);
+  cache = grub_disk_cache_table + index;
+
+  if (cache->dev_id == dev_id && cache->disk_id == disk_id
+      && cache->sector == sector)
+    {
+      cache->lock = 1;
+#if 0
+      grub_disk_cache_hits++;
+#endif
+      return cache->data;
+    }
+
+#if 0
+  grub_disk_cache_misses++;
+#endif
+
+  return 0;
+}
+
+static void
+grub_disk_cache_unlock (unsigned long dev_id, unsigned long disk_id,
+                       grub_disk_addr_t sector)
+{
+  struct grub_disk_cache *cache;
+  unsigned index;
+
+  index = grub_disk_cache_get_index (dev_id, disk_id, sector);
+  cache = grub_disk_cache_table + index;
+
+  if (cache->dev_id == dev_id && cache->disk_id == disk_id
+      && cache->sector == sector)
+    cache->lock = 0;
+}
+
+static grub_err_t
+grub_disk_cache_store (unsigned long dev_id, unsigned long disk_id,
+                      grub_disk_addr_t sector, const char *data)
+{
+  unsigned index;
+  struct grub_disk_cache *cache;
+
+  index = grub_disk_cache_get_index (dev_id, disk_id, sector);
+  cache = grub_disk_cache_table + index;
+
+  cache->lock = 1;
+  grub_free (cache->data);
+  cache->data = 0;
+  cache->lock = 0;
+
+  cache->data = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS);
+  if (! cache->data)
+    return grub_errno;
+
+  grub_memcpy (cache->data, data,
+              GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS);
+  cache->dev_id = dev_id;
+  cache->disk_id = disk_id;
+  cache->sector = sector;
+
+  return GRUB_ERR_NONE;
+}
+
+\f
+
+static grub_disk_dev_t grub_disk_dev_list;
+
+void
+grub_disk_dev_register (grub_disk_dev_t dev)
+{
+  dev->next = grub_disk_dev_list;
+  grub_disk_dev_list = dev;
+}
+
+void
+grub_disk_dev_unregister (grub_disk_dev_t dev)
+{
+  grub_disk_dev_t *p, q;
+
+  for (p = &grub_disk_dev_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == dev)
+      {
+        *p = q->next;
+       break;
+      }
+}
+
+int
+grub_disk_dev_iterate (int (*hook) (const char *name))
+{
+  grub_disk_dev_t p;
+
+  for (p = grub_disk_dev_list; p; p = p->next)
+    if (p->iterate && (p->iterate) (hook))
+      return 1;
+
+  return 0;
+}
+
+/* Return the location of the first ',', if any, which is not
+   escaped by a '\'.  */
+static const char *
+find_part_sep (const char *name)
+{
+  const char *p = name;
+  char c;
+
+  while ((c = *p++) != '\0')
+    {
+      if (c == '\\' && *p == ',')
+       p++;
+      else if (c == ',')
+       return p - 1;
+    }
+  return NULL;
+}
+
+grub_disk_t
+grub_disk_open (const char *name)
+{
+  const char *p;
+  grub_disk_t disk;
+  grub_disk_dev_t dev;
+  char *raw = (char *) name;
+  grub_uint64_t current_time;
+
+  grub_dprintf ("disk", "Opening `%s'...\n", name);
+
+  disk = (grub_disk_t) grub_zalloc (sizeof (*disk));
+  if (! disk)
+    return 0;
+
+  disk->name = grub_strdup (name);
+  if (! disk->name)
+    goto fail;
+
+  p = find_part_sep (name);
+  if (p)
+    {
+      grub_size_t len = p - name;
+
+      raw = grub_malloc (len + 1);
+      if (! raw)
+       goto fail;
+
+      grub_memcpy (raw, name, len);
+      raw[len] = '\0';
+    }
+
+  for (dev = grub_disk_dev_list; dev; dev = dev->next)
+    {
+      if ((dev->open) (raw, disk) == GRUB_ERR_NONE)
+       break;
+      else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE)
+       grub_errno = GRUB_ERR_NONE;
+      else
+       goto fail;
+    }
+
+  if (! dev)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such disk");
+      goto fail;
+    }
+
+  if (p && ! disk->has_partitions)
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "no partition on this disk");
+      goto fail;
+    }
+
+  disk->dev = dev;
+
+  if (p)
+    {
+      disk->partition = grub_partition_probe (disk, p + 1);
+      if (! disk->partition)
+       {
+         grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such partition");
+         goto fail;
+       }
+    }
+
+  /* The cache will be invalidated about 2 seconds after a device was
+     closed.  */
+  current_time = grub_get_time_ms ();
+
+  if (current_time > (grub_last_time
+                     + GRUB_CACHE_TIMEOUT * 1000))
+    grub_disk_cache_invalidate_all ();
+
+  grub_last_time = current_time;
+
+ fail:
+
+  if (raw && raw != name)
+    grub_free (raw);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_error_push ();
+      grub_dprintf ("disk", "Opening `%s' failed.\n", name);
+      grub_error_pop ();
+
+      grub_disk_close (disk);
+      return 0;
+    }
+
+  return disk;
+}
+
+void
+grub_disk_close (grub_disk_t disk)
+{
+  grub_partition_t part;
+  grub_dprintf ("disk", "Closing `%s'.\n", disk->name);
+
+  if (disk->dev && disk->dev->close)
+    (disk->dev->close) (disk);
+
+  /* Reset the timer.  */
+  grub_last_time = grub_get_time_ms ();
+
+  while (disk->partition)
+    {
+      part = disk->partition->parent;
+      grub_free (disk->partition);
+      disk->partition = part;
+    }
+  grub_free ((void *) disk->name);
+  grub_free (disk);
+}
+
+/* This function performs three tasks:
+   - Make sectors disk relative from partition relative.
+   - Normalize offset to be less than the sector size.
+   - Verify that the range is inside the partition.  */
+static grub_err_t
+grub_disk_adjust_range (grub_disk_t disk, grub_disk_addr_t *sector,
+                       grub_off_t *offset, grub_size_t size)
+{
+  grub_partition_t part;
+  *sector += *offset >> GRUB_DISK_SECTOR_BITS;
+  *offset &= GRUB_DISK_SECTOR_SIZE - 1;
+
+  for (part = disk->partition; part; part = part->parent)
+    {
+      grub_disk_addr_t start;
+      grub_uint64_t len;
+
+      start = part->start;
+      len = part->len;
+
+      if (*sector >= len
+         || len - *sector < ((*offset + size + GRUB_DISK_SECTOR_SIZE - 1)
+                             >> GRUB_DISK_SECTOR_BITS))
+       return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of partition");
+
+      *sector += start;
+    }
+
+  if (disk->total_sectors <= *sector
+      || ((*offset + size + GRUB_DISK_SECTOR_SIZE - 1)
+         >> GRUB_DISK_SECTOR_BITS) > disk->total_sectors - *sector)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of disk");
+
+  return GRUB_ERR_NONE;
+}
+
+/* Read data from the disk.  */
+grub_err_t
+grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
+               grub_off_t offset, grub_size_t size, void *buf)
+{
+  char *tmp_buf;
+  unsigned real_offset;
+
+  /* First of all, check if the region is within the disk.  */
+  if (grub_disk_adjust_range (disk, &sector, &offset, size) != GRUB_ERR_NONE)
+    {
+      grub_error_push ();
+      grub_dprintf ("disk", "Read out of range: sector 0x%llx (%s).\n",
+                   (unsigned long long) sector, grub_errmsg);
+      grub_error_pop ();
+      return grub_errno;
+    }
+
+  real_offset = offset;
+
+  /* Allocate a temporary buffer.  */
+  tmp_buf = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS);
+  if (! tmp_buf)
+    return grub_errno;
+
+  /* Until SIZE is zero...  */
+  while (size)
+    {
+      char *data;
+      grub_disk_addr_t start_sector;
+      grub_size_t len;
+      grub_size_t pos;
+
+      /* For reading bulk data.  */
+      start_sector = sector & ~(GRUB_DISK_CACHE_SIZE - 1);
+      pos = (sector - start_sector) << GRUB_DISK_SECTOR_BITS;
+      len = ((GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS)
+            - pos - real_offset);
+      if (len > size)
+       len = size;
+
+      /* Fetch the cache.  */
+      data = grub_disk_cache_fetch (disk->dev->id, disk->id, start_sector);
+      if (data)
+       {
+         /* Just copy it!  */
+         grub_memcpy (buf, data + pos + real_offset, len);
+         grub_disk_cache_unlock (disk->dev->id, disk->id, start_sector);
+       }
+      else
+       {
+         /* Otherwise read data from the disk actually.  */
+         if (start_sector + GRUB_DISK_CACHE_SIZE > disk->total_sectors
+             || (disk->dev->read) (disk, start_sector,
+                                   GRUB_DISK_CACHE_SIZE, tmp_buf)
+             != GRUB_ERR_NONE)
+           {
+             /* Uggh... Failed. Instead, just read necessary data.  */
+             unsigned num;
+             char *p;
+
+             grub_errno = GRUB_ERR_NONE;
+
+             num = ((size + real_offset + GRUB_DISK_SECTOR_SIZE - 1)
+                    >> GRUB_DISK_SECTOR_BITS);
+
+             p = grub_realloc (tmp_buf, num << GRUB_DISK_SECTOR_BITS);
+             if (!p)
+               goto finish;
+
+             tmp_buf = p;
+
+             if ((disk->dev->read) (disk, sector, num, tmp_buf))
+               {
+                 grub_error_push ();
+                 grub_dprintf ("disk", "%s read failed\n", disk->name);
+                 grub_error_pop ();
+                 goto finish;
+               }
+
+             grub_memcpy (buf, tmp_buf + real_offset, size);
+
+             /* Call the read hook, if any.  */
+             if (disk->read_hook)
+               while (size)
+                 {
+                   grub_size_t to_read = (size > GRUB_DISK_SECTOR_SIZE) ? GRUB_DISK_SECTOR_SIZE : size;
+                   (disk->read_hook) (sector, real_offset,
+                                      to_read);
+                   if (grub_errno != GRUB_ERR_NONE)
+                     goto finish;
+
+                   sector++;
+                   size -= to_read - real_offset;
+                   real_offset = 0;
+                 }
+
+             /* This must be the end.  */
+             goto finish;
+           }
+
+         /* Copy it and store it in the disk cache.  */
+         grub_memcpy (buf, tmp_buf + pos + real_offset, len);
+         grub_disk_cache_store (disk->dev->id, disk->id,
+                                start_sector, tmp_buf);
+       }
+
+      /* Call the read hook, if any.  */
+      if (disk->read_hook)
+       {
+         grub_disk_addr_t s = sector;
+         grub_size_t l = len;
+
+         while (l)
+           {
+             (disk->read_hook) (s, real_offset,
+                                ((l > GRUB_DISK_SECTOR_SIZE)
+                                 ? GRUB_DISK_SECTOR_SIZE
+                                 : l));
+
+             if (l < GRUB_DISK_SECTOR_SIZE - real_offset)
+               break;
+
+             s++;
+             l -= GRUB_DISK_SECTOR_SIZE - real_offset;
+             real_offset = 0;
+           }
+       }
+
+      sector = start_sector + GRUB_DISK_CACHE_SIZE;
+      buf = (char *) buf + len;
+      size -= len;
+      real_offset = 0;
+    }
+
+ finish:
+
+  grub_free (tmp_buf);
+
+  return grub_errno;
+}
+
+grub_err_t
+grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector,
+                grub_off_t offset, grub_size_t size, const void *buf)
+{
+  unsigned real_offset;
+
+  grub_dprintf ("disk", "Writing `%s'...\n", disk->name);
+
+  if (grub_disk_adjust_range (disk, &sector, &offset, size) != GRUB_ERR_NONE)
+    return -1;
+
+  real_offset = offset;
+
+  while (size)
+    {
+      if (real_offset != 0 || (size < GRUB_DISK_SECTOR_SIZE && size != 0))
+       {
+         char tmp_buf[GRUB_DISK_SECTOR_SIZE];
+         grub_size_t len;
+         grub_partition_t part;
+
+         part = disk->partition;
+         disk->partition = 0;
+         if (grub_disk_read (disk, sector, 0, GRUB_DISK_SECTOR_SIZE, tmp_buf)
+             != GRUB_ERR_NONE)
+           {
+             disk->partition = part;
+             goto finish;
+           }
+         disk->partition = part;
+
+         len = GRUB_DISK_SECTOR_SIZE - real_offset;
+         if (len > size)
+           len = size;
+
+         grub_memcpy (tmp_buf + real_offset, buf, len);
+
+         grub_disk_cache_invalidate (disk->dev->id, disk->id, sector);
+
+         if ((disk->dev->write) (disk, sector, 1, tmp_buf) != GRUB_ERR_NONE)
+           goto finish;
+
+         sector++;
+         buf = (char *) buf + len;
+         size -= len;
+         real_offset = 0;
+       }
+      else
+       {
+         grub_size_t len;
+         grub_size_t n;
+
+         len = size & ~(GRUB_DISK_SECTOR_SIZE - 1);
+         n = size >> GRUB_DISK_SECTOR_BITS;
+
+         if ((disk->dev->write) (disk, sector, n, buf) != GRUB_ERR_NONE)
+           goto finish;
+
+         while (n--)
+           grub_disk_cache_invalidate (disk->dev->id, disk->id, sector++);
+
+         buf = (char *) buf + len;
+         size -= len;
+       }
+    }
+
+ finish:
+
+  return grub_errno;
+}
+
+grub_uint64_t
+grub_disk_get_size (grub_disk_t disk)
+{
+  if (disk->partition)
+    return grub_partition_get_len (disk->partition);
+  else
+    return disk->total_sectors;
+}
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
new file mode 100644 (file)
index 0000000..12391ce
--- /dev/null
@@ -0,0 +1,724 @@
+/* dl.c - loadable module support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Force native word size */
+#define GRUB_TARGET_WORDSIZE (8 * GRUB_CPU_SIZEOF_VOID_P)
+
+#include <config.h>
+#include <grub/elf.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/file.h>
+#include <grub/env.h>
+#include <grub/cache.h>
+
+/* Platforms where modules are in a readonly area of memory.  */
+#if defined(GRUB_MACHINE_QEMU)
+#define GRUB_MODULES_MACHINE_READONLY
+#endif
+
+\f
+
+struct grub_dl_list
+{
+  struct grub_dl_list *next;
+  grub_dl_t mod;
+};
+typedef struct grub_dl_list *grub_dl_list_t;
+
+static grub_dl_list_t grub_dl_head;
+
+static grub_err_t
+grub_dl_add (grub_dl_t mod)
+{
+  grub_dl_list_t l;
+
+  if (grub_dl_get (mod->name))
+    return grub_error (GRUB_ERR_BAD_MODULE,
+                      "`%s' is already loaded", mod->name);
+
+  l = (grub_dl_list_t) grub_malloc (sizeof (*l));
+  if (! l)
+    return grub_errno;
+
+  l->mod = mod;
+  l->next = grub_dl_head;
+  grub_dl_head = l;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_dl_remove (grub_dl_t mod)
+{
+  grub_dl_list_t *p, q;
+
+  for (p = &grub_dl_head, q = *p; q; p = &q->next, q = *p)
+    if (q->mod == mod)
+      {
+       *p = q->next;
+       grub_free (q);
+       return;
+      }
+}
+
+grub_dl_t
+grub_dl_get (const char *name)
+{
+  grub_dl_list_t l;
+
+  for (l = grub_dl_head; l; l = l->next)
+    if (grub_strcmp (name, l->mod->name) == 0)
+      return l->mod;
+
+  return 0;
+}
+
+void
+grub_dl_iterate (int (*hook) (grub_dl_t mod))
+{
+  grub_dl_list_t l;
+
+  for (l = grub_dl_head; l; l = l->next)
+    if (hook (l->mod))
+      break;
+}
+
+\f
+
+struct grub_symbol
+{
+  struct grub_symbol *next;
+  const char *name;
+  void *addr;
+  grub_dl_t mod;       /* The module to which this symbol belongs.  */
+};
+typedef struct grub_symbol *grub_symbol_t;
+
+/* The size of the symbol table.  */
+#define GRUB_SYMTAB_SIZE       509
+
+/* The symbol table (using an open-hash).  */
+static struct grub_symbol *grub_symtab[GRUB_SYMTAB_SIZE];
+
+/* Simple hash function.  */
+static unsigned
+grub_symbol_hash (const char *s)
+{
+  unsigned key = 0;
+
+  while (*s)
+    key = key * 65599 + *s++;
+
+  return (key + (key >> 5)) % GRUB_SYMTAB_SIZE;
+}
+
+/* Resolve the symbol name NAME and return the address.
+   Return NULL, if not found.  */
+static void *
+grub_dl_resolve_symbol (const char *name)
+{
+  grub_symbol_t sym;
+
+  for (sym = grub_symtab[grub_symbol_hash (name)]; sym; sym = sym->next)
+    if (grub_strcmp (sym->name, name) == 0)
+      return sym->addr;
+
+  return 0;
+}
+
+/* Register a symbol with the name NAME and the address ADDR.  */
+grub_err_t
+grub_dl_register_symbol (const char *name, void *addr, grub_dl_t mod)
+{
+  grub_symbol_t sym;
+  unsigned k;
+
+  sym = (grub_symbol_t) grub_malloc (sizeof (*sym));
+  if (! sym)
+    return grub_errno;
+
+  if (mod)
+    {
+      sym->name = grub_strdup (name);
+      if (! sym->name)
+       {
+         grub_free (sym);
+         return grub_errno;
+       }
+    }
+  else
+    sym->name = name;
+
+  sym->addr = addr;
+  sym->mod = mod;
+
+  k = grub_symbol_hash (name);
+  sym->next = grub_symtab[k];
+  grub_symtab[k] = sym;
+
+  return GRUB_ERR_NONE;
+}
+
+/* Unregister all the symbols defined in the module MOD.  */
+static void
+grub_dl_unregister_symbols (grub_dl_t mod)
+{
+  unsigned i;
+
+  if (! mod)
+    grub_fatal ("core symbols cannot be unregistered");
+
+  for (i = 0; i < GRUB_SYMTAB_SIZE; i++)
+    {
+      grub_symbol_t sym, *p, q;
+
+      for (p = &grub_symtab[i], sym = *p; sym; sym = q)
+       {
+         q = sym->next;
+         if (sym->mod == mod)
+           {
+             *p = q;
+             grub_free ((void *) sym->name);
+             grub_free (sym);
+           }
+         else
+           p = &sym->next;
+       }
+    }
+}
+
+/* Return the address of a section whose index is N.  */
+static void *
+grub_dl_get_section_addr (grub_dl_t mod, unsigned n)
+{
+  grub_dl_segment_t seg;
+
+  for (seg = mod->segment; seg; seg = seg->next)
+    if (seg->section == n)
+      return seg->addr;
+
+  return 0;
+}
+
+/* Check if EHDR is a valid ELF header.  */
+static grub_err_t
+grub_dl_check_header (void *ehdr, grub_size_t size)
+{
+  Elf_Ehdr *e = ehdr;
+
+  /* Check the header size.  */
+  if (size < sizeof (Elf_Ehdr))
+    return grub_error (GRUB_ERR_BAD_OS, "ELF header smaller than expected");
+
+  /* Check the magic numbers.  */
+  if (grub_arch_dl_check_header (ehdr)
+      || 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;
+}
+
+/* Load all segments from memory specified by E.  */
+static grub_err_t
+grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
+{
+  unsigned i;
+  Elf_Shdr *s;
+
+  for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
+    {
+      if (s->sh_flags & SHF_ALLOC)
+       {
+         grub_dl_segment_t seg;
+
+         seg = (grub_dl_segment_t) grub_malloc (sizeof (*seg));
+         if (! seg)
+           return grub_errno;
+
+         if (s->sh_size)
+           {
+             void *addr;
+
+             addr = grub_memalign (s->sh_addralign, s->sh_size);
+             if (! addr)
+               {
+                 grub_free (seg);
+                 return grub_errno;
+               }
+
+             switch (s->sh_type)
+               {
+               case SHT_PROGBITS:
+                 grub_memcpy (addr, (char *) e + s->sh_offset, s->sh_size);
+                 break;
+               case SHT_NOBITS:
+                 grub_memset (addr, 0, s->sh_size);
+                 break;
+               }
+
+             seg->addr = addr;
+           }
+         else
+           seg->addr = 0;
+
+         seg->size = s->sh_size;
+         seg->section = i;
+         seg->next = mod->segment;
+         mod->segment = seg;
+       }
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
+{
+  unsigned i;
+  Elf_Shdr *s;
+  Elf_Sym *sym;
+  const char *str;
+  Elf_Word size, entsize;
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_MODULE, "no symbol table");
+
+#ifdef GRUB_MODULES_MACHINE_READONLY
+  mod->symtab = grub_malloc (s->sh_size);
+  memcpy (mod->symtab, (char *) e + s->sh_offset, s->sh_size);
+#else
+  mod->symtab = (Elf_Sym *) ((char *) e + s->sh_offset);
+#endif
+  sym = mod->symtab;
+  size = s->sh_size;
+  entsize = s->sh_entsize;
+
+  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
+  str = (char *) e + s->sh_offset;
+
+  for (i = 0;
+       i < size / entsize;
+       i++, sym = (Elf_Sym *) ((char *) sym + entsize))
+    {
+      unsigned char type = ELF_ST_TYPE (sym->st_info);
+      unsigned char bind = ELF_ST_BIND (sym->st_info);
+      const char *name = str + sym->st_name;
+
+      switch (type)
+       {
+       case STT_NOTYPE:
+       case STT_OBJECT:
+         /* Resolve a global symbol.  */
+         if (sym->st_name != 0 && sym->st_shndx == 0)
+           {
+             sym->st_value = (Elf_Addr) grub_dl_resolve_symbol (name);
+             if (! sym->st_value)
+               return grub_error (GRUB_ERR_BAD_MODULE,
+                                  "symbol not found: `%s'", name);
+           }
+         else
+           {
+             sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
+                                                                   sym->st_shndx);
+             if (bind != STB_LOCAL)
+               if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
+                 return grub_errno;
+           }
+         break;
+
+       case STT_FUNC:
+         sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
+                                                               sym->st_shndx);
+         if (bind != STB_LOCAL)
+           if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
+             return grub_errno;
+
+         if (grub_strcmp (name, "grub_mod_init") == 0)
+           mod->init = (void (*) (grub_dl_t)) sym->st_value;
+         else if (grub_strcmp (name, "grub_mod_fini") == 0)
+           mod->fini = (void (*) (void)) sym->st_value;
+         break;
+
+       case STT_SECTION:
+         sym->st_value = (Elf_Addr) grub_dl_get_section_addr (mod,
+                                                              sym->st_shndx);
+         break;
+
+       case STT_FILE:
+         sym->st_value = 0;
+         break;
+
+       default:
+         return grub_error (GRUB_ERR_BAD_MODULE,
+                            "unknown symbol type `%d'", (int) type);
+       }
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_dl_call_init (grub_dl_t mod)
+{
+  if (mod->init)
+    (mod->init) (mod);
+}
+
+static grub_err_t
+grub_dl_resolve_name (grub_dl_t mod, Elf_Ehdr *e)
+{
+  Elf_Shdr *s;
+  const char *str;
+  unsigned i;
+
+  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize);
+  str = (char *) e + s->sh_offset;
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (grub_strcmp (str + s->sh_name, ".modname") == 0)
+      {
+       mod->name = grub_strdup ((char *) e + s->sh_offset);
+       if (! mod->name)
+         return grub_errno;
+       break;
+      }
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_MODULE, "no module name found");
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_dl_resolve_dependencies (grub_dl_t mod, Elf_Ehdr *e)
+{
+  Elf_Shdr *s;
+  const char *str;
+  unsigned i;
+
+  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize);
+  str = (char *) e + s->sh_offset;
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (grub_strcmp (str + s->sh_name, ".moddeps") == 0)
+      {
+       const char *name = (char *) e + s->sh_offset;
+       const char *max = name + s->sh_size;
+
+       while ((name < max) && (*name))
+         {
+           grub_dl_t m;
+           grub_dl_dep_t dep;
+
+           m = grub_dl_load (name);
+           if (! m)
+             return grub_errno;
+
+           grub_dl_ref (m);
+
+           dep = (grub_dl_dep_t) grub_malloc (sizeof (*dep));
+           if (! dep)
+             return grub_errno;
+
+           dep->mod = m;
+           dep->next = mod->dep;
+           mod->dep = dep;
+
+           name += grub_strlen (name) + 1;
+         }
+      }
+
+  return GRUB_ERR_NONE;
+}
+
+int
+grub_dl_ref (grub_dl_t mod)
+{
+  grub_dl_dep_t dep;
+
+  if (!mod) return 0;
+
+  for (dep = mod->dep; dep; dep = dep->next)
+    grub_dl_ref (dep->mod);
+
+  return ++mod->ref_count;
+}
+
+int
+grub_dl_unref (grub_dl_t mod)
+{
+  grub_dl_dep_t dep;
+
+  if (!mod) return 0;
+
+  for (dep = mod->dep; dep; dep = dep->next)
+    grub_dl_unref (dep->mod);
+
+  return --mod->ref_count;
+}
+
+static void
+grub_dl_flush_cache (grub_dl_t mod)
+{
+  grub_dl_segment_t seg;
+
+  for (seg = mod->segment; seg; seg = seg->next) {
+    if (seg->size) {
+      grub_dprintf ("modules", "flushing 0x%lx bytes at %p\n",
+                   (unsigned long) seg->size, seg->addr);
+      grub_arch_sync_caches (seg->addr, seg->size);
+    }
+  }
+}
+
+/* Load a module from core memory.  */
+grub_dl_t
+grub_dl_load_core (void *addr, grub_size_t size)
+{
+  Elf_Ehdr *e;
+  grub_dl_t mod;
+
+  grub_dprintf ("modules", "module at %p, size 0x%lx\n", addr,
+               (unsigned long) size);
+  e = addr;
+  if (grub_dl_check_header (e, size))
+    return 0;
+
+  if (e->e_type != ET_REL)
+    {
+      grub_error (GRUB_ERR_BAD_MODULE, "invalid ELF file type");
+      return 0;
+    }
+
+  /* Make sure that every section is within the core.  */
+  if (size < e->e_shoff + e->e_shentsize * e->e_shnum)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "ELF sections outside core");
+      return 0;
+    }
+
+  mod = (grub_dl_t) grub_zalloc (sizeof (*mod));
+  if (! mod)
+    return 0;
+
+  mod->ref_count = 1;
+
+  grub_dprintf ("modules", "relocating to %p\n", mod);
+  if (grub_dl_resolve_name (mod, e)
+      || grub_dl_resolve_dependencies (mod, e)
+      || grub_dl_load_segments (mod, e)
+      || grub_dl_resolve_symbols (mod, e)
+      || grub_arch_dl_relocate_symbols (mod, e))
+    {
+      mod->fini = 0;
+      grub_dl_unload (mod);
+      return 0;
+    }
+
+  grub_dl_flush_cache (mod);
+
+  grub_dprintf ("modules", "module name: %s\n", mod->name);
+  grub_dprintf ("modules", "init function: %p\n", mod->init);
+  grub_dl_call_init (mod);
+
+  if (grub_dl_add (mod))
+    {
+      grub_dl_unload (mod);
+      return 0;
+    }
+
+  return mod;
+}
+
+/* Load a module from the file FILENAME.  */
+grub_dl_t
+grub_dl_load_file (const char *filename)
+{
+  grub_file_t file = NULL;
+  grub_ssize_t size;
+  void *core = 0;
+  grub_dl_t mod = 0;
+
+  file = grub_file_open (filename);
+  if (! file)
+    return 0;
+
+  size = grub_file_size (file);
+  core = grub_malloc (size);
+  if (! core)
+    {
+      grub_file_close (file);
+      return 0;
+    }
+
+  if (grub_file_read (file, core, size) != (int) size)
+    {
+      grub_file_close (file);
+      grub_free (core);
+      return 0;
+    }
+
+  /* We must close this before we try to process dependencies.
+     Some disk backends do not handle gracefully multiple concurrent
+     opens of the same device.  */
+  grub_file_close (file);
+
+  mod = grub_dl_load_core (core, size);
+  if (! mod)
+    {
+      grub_free (core);
+      return 0;
+    }
+
+  mod->ref_count = 0;
+  return mod;
+}
+
+/* Load a module using a symbolic name.  */
+grub_dl_t
+grub_dl_load (const char *name)
+{
+  char *filename;
+  grub_dl_t mod;
+  char *grub_dl_dir = grub_env_get ("prefix");
+
+  mod = grub_dl_get (name);
+  if (mod)
+    return mod;
+
+  if (! grub_dl_dir) {
+    grub_error (GRUB_ERR_FILE_NOT_FOUND, "\"prefix\" is not set");
+    return 0;
+  }
+
+  filename = grub_xasprintf ("%s/%s.mod", grub_dl_dir, name);
+  if (! filename)
+    return 0;
+
+  mod = grub_dl_load_file (filename);
+  grub_free (filename);
+
+  if (! mod)
+    return 0;
+
+  if (grub_strcmp (mod->name, name) != 0)
+    grub_error (GRUB_ERR_BAD_MODULE, "mismatched names");
+
+  return mod;
+}
+
+/* Unload the module MOD.  */
+int
+grub_dl_unload (grub_dl_t mod)
+{
+  grub_dl_dep_t dep, depn;
+  grub_dl_segment_t seg, segn;
+
+  if (mod->ref_count > 0)
+    return 0;
+
+  if (mod->fini)
+    (mod->fini) ();
+
+  grub_dl_remove (mod);
+  grub_dl_unregister_symbols (mod);
+
+  for (dep = mod->dep; dep; dep = depn)
+    {
+      depn = dep->next;
+
+      if (! grub_dl_unref (dep->mod))
+       grub_dl_unload (dep->mod);
+
+      grub_free (dep);
+    }
+
+  for (seg = mod->segment; seg; seg = segn)
+    {
+      segn = seg->next;
+      grub_free (seg->addr);
+      grub_free (seg);
+    }
+
+  grub_free (mod->name);
+#ifdef GRUB_MODULES_MACHINE_READONLY
+  grub_free (mod->symtab);
+#endif
+  grub_free (mod);
+  return 1;
+}
+
+/* Unload unneeded modules.  */
+void
+grub_dl_unload_unneeded (void)
+{
+  /* Because grub_dl_remove modifies the list of modules, this
+     implementation is tricky.  */
+  grub_dl_list_t p = grub_dl_head;
+
+  while (p)
+    {
+      if (grub_dl_unload (p->mod))
+       {
+         p = grub_dl_head;
+         continue;
+       }
+
+      p = p->next;
+    }
+}
+
+/* Unload all modules.  */
+void
+grub_dl_unload_all (void)
+{
+  while (grub_dl_head)
+    {
+      grub_dl_list_t p;
+
+      grub_dl_unload_unneeded ();
+
+      /* Force to decrement the ref count. This will purge pre-loaded
+        modules and manually inserted modules.  */
+      for (p = grub_dl_head; p; p = p->next)
+       p->mod->ref_count--;
+    }
+}
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
new file mode 100644 (file)
index 0000000..d8b2255
--- /dev/null
@@ -0,0 +1,783 @@
+/* efi.c - generic EFI support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/charset.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/console_control.h>
+#include <grub/efi/pe32.h>
+#include <grub/machine/time.h>
+#include <grub/term.h>
+#include <grub/kernel.h>
+#include <grub/mm.h>
+
+/* The handle of GRUB itself. Filled in by the startup code.  */
+grub_efi_handle_t grub_efi_image_handle;
+
+/* The pointer to a system table. Filled in by the startup code.  */
+grub_efi_system_table_t *grub_efi_system_table;
+
+static grub_efi_guid_t console_control_guid = GRUB_EFI_CONSOLE_CONTROL_GUID;
+static grub_efi_guid_t loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID;
+static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID;
+
+void *
+grub_efi_locate_protocol (grub_efi_guid_t *protocol, void *registration)
+{
+  void *interface;
+  grub_efi_status_t status;
+
+  status = efi_call_3 (grub_efi_system_table->boot_services->locate_protocol,
+                       protocol, registration, &interface);
+  if (status != GRUB_EFI_SUCCESS)
+    return 0;
+
+  return interface;
+}
+
+/* Return the array of handles which meet the requirement. If successful,
+   the number of handles is stored in NUM_HANDLES. The array is allocated
+   from the heap.  */
+grub_efi_handle_t *
+grub_efi_locate_handle (grub_efi_locate_search_type_t search_type,
+                       grub_efi_guid_t *protocol,
+                       void *search_key,
+                       grub_efi_uintn_t *num_handles)
+{
+  grub_efi_boot_services_t *b;
+  grub_efi_status_t status;
+  grub_efi_handle_t *buffer;
+  grub_efi_uintn_t buffer_size = 8 * sizeof (grub_efi_handle_t);
+
+  buffer = grub_malloc (buffer_size);
+  if (! buffer)
+    return 0;
+
+  b = grub_efi_system_table->boot_services;
+  status = efi_call_5 (b->locate_handle, search_type, protocol, search_key,
+                            &buffer_size, buffer);
+  if (status == GRUB_EFI_BUFFER_TOO_SMALL)
+    {
+      grub_free (buffer);
+      buffer = grub_malloc (buffer_size);
+      if (! buffer)
+       return 0;
+
+      status = efi_call_5 (b->locate_handle, search_type, protocol, search_key,
+                                &buffer_size, buffer);
+    }
+
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      grub_free (buffer);
+      return 0;
+    }
+
+  *num_handles = buffer_size / sizeof (grub_efi_handle_t);
+  return buffer;
+}
+
+void *
+grub_efi_open_protocol (grub_efi_handle_t handle,
+                       grub_efi_guid_t *protocol,
+                       grub_efi_uint32_t attributes)
+{
+  grub_efi_boot_services_t *b;
+  grub_efi_status_t status;
+  void *interface;
+
+  b = grub_efi_system_table->boot_services;
+  status = efi_call_6 (b->open_protocol, handle,
+                      protocol,
+                      &interface,
+                      grub_efi_image_handle,
+                      0,
+                      attributes);
+  if (status != GRUB_EFI_SUCCESS)
+    return 0;
+
+  return interface;
+}
+
+int
+grub_efi_set_text_mode (int on)
+{
+  grub_efi_console_control_protocol_t *c;
+  grub_efi_screen_mode_t mode, new_mode;
+
+  c = grub_efi_locate_protocol (&console_control_guid, 0);
+  if (! c)
+    /* No console control protocol instance available, assume it is
+       already in text mode. */
+    return 1;
+
+  if (efi_call_4 (c->get_mode, c, &mode, 0, 0) != GRUB_EFI_SUCCESS)
+    return 0;
+
+  new_mode = on ? GRUB_EFI_SCREEN_TEXT : GRUB_EFI_SCREEN_GRAPHICS;
+  if (mode != new_mode)
+    if (efi_call_2 (c->set_mode, c, new_mode) != GRUB_EFI_SUCCESS)
+      return 0;
+
+  return 1;
+}
+
+void
+grub_efi_stall (grub_efi_uintn_t microseconds)
+{
+  efi_call_1 (grub_efi_system_table->boot_services->stall, microseconds);
+}
+
+grub_efi_loaded_image_t *
+grub_efi_get_loaded_image (grub_efi_handle_t image_handle)
+{
+  return grub_efi_open_protocol (image_handle,
+                                &loaded_image_guid,
+                                GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+}
+
+void
+grub_exit (void)
+{
+  grub_efi_fini ();
+  efi_call_4 (grub_efi_system_table->boot_services->exit,
+              grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0);
+  for (;;) ;
+}
+
+/* On i386, a firmware-independant grub_reboot() is provided by realmode.S.  */
+#ifndef __i386__
+void
+grub_reboot (void)
+{
+  grub_efi_fini ();
+  efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
+              GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
+}
+#endif
+
+void
+grub_halt (void)
+{
+  grub_efi_fini ();
+  efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
+              GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL);
+}
+
+int
+grub_efi_exit_boot_services (grub_efi_uintn_t map_key)
+{
+  grub_efi_boot_services_t *b;
+  grub_efi_status_t status;
+
+  b = grub_efi_system_table->boot_services;
+  status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle, map_key);
+  return status == GRUB_EFI_SUCCESS;
+}
+
+grub_err_t
+grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
+                                 grub_efi_uintn_t descriptor_size,
+                                 grub_efi_uint32_t descriptor_version,
+                                 grub_efi_memory_descriptor_t *virtual_map)
+{
+  grub_efi_runtime_services_t *r;
+  grub_efi_status_t status;
+
+  r = grub_efi_system_table->runtime_services;
+  status = efi_call_4 (r->set_virtual_address_map, memory_map_size,
+                      descriptor_size, descriptor_version, virtual_map);
+
+  if (status == GRUB_EFI_SUCCESS)
+    return GRUB_ERR_NONE;
+
+  return grub_error (GRUB_ERR_IO, "set_virtual_address_map failed");
+}
+
+grub_uint32_t
+grub_get_rtc (void)
+{
+  grub_efi_time_t time;
+  grub_efi_runtime_services_t *r;
+
+  r = grub_efi_system_table->runtime_services;
+  if (efi_call_2 (r->get_time, &time, 0) != GRUB_EFI_SUCCESS)
+    /* What is possible in this case?  */
+    return 0;
+
+  return (((time.minute * 60 + time.second) * 1000
+          + time.nanosecond / 1000000)
+         * GRUB_TICKS_PER_SECOND / 1000);
+}
+
+/* Search the mods section from the PE32/PE32+ image. This code uses
+   a PE32 header, but should work with PE32+ as well.  */
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+  grub_efi_loaded_image_t *image;
+  struct grub_pe32_header *header;
+  struct grub_pe32_coff_header *coff_header;
+  struct grub_pe32_section_table *sections;
+  struct grub_pe32_section_table *section;
+  struct grub_module_info *info;
+  grub_uint16_t i;
+
+  image = grub_efi_get_loaded_image (grub_efi_image_handle);
+  if (! image)
+    return 0;
+
+  header = image->image_base;
+  coff_header = &(header->coff_header);
+  sections
+    = (struct grub_pe32_section_table *) ((char *) coff_header
+                                         + sizeof (*coff_header)
+                                         + coff_header->optional_header_size);
+
+  for (i = 0, section = sections;
+       i < coff_header->num_sections;
+       i++, section++)
+    {
+      if (grub_strcmp (section->name, "mods") == 0)
+       break;
+    }
+
+  if (i == coff_header->num_sections)
+    return 0;
+
+  info = (struct grub_module_info *) ((char *) image->image_base
+                                     + section->virtual_address);
+  if (info->magic != GRUB_MODULE_MAGIC)
+    return 0;
+
+  return (grub_addr_t) info;
+}
+
+char *
+grub_efi_get_filename (grub_efi_device_path_t *dp)
+{
+  char *name = 0;
+
+  while (1)
+    {
+      grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
+      grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
+
+      if (type == GRUB_EFI_END_DEVICE_PATH_TYPE)
+       break;
+      else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
+              && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
+       {
+         grub_efi_file_path_device_path_t *fp;
+         grub_efi_uint16_t len;
+         char *p;
+         grub_size_t size;
+
+         if (name)
+           {
+             size = grub_strlen (name);
+             name[size] = '/';
+             size++;
+           }
+         else
+           size = 0;
+
+         len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
+                / sizeof (grub_efi_char16_t));
+         p = grub_realloc (name, size + len * 4 + 1);
+         if (! p)
+           {
+             grub_free (name);
+             return 0;
+           }
+
+         name = p;
+         fp = (grub_efi_file_path_device_path_t *) dp;
+         *grub_utf16_to_utf8 ((grub_uint8_t *) name + size,
+                              fp->path_name, len) = '\0';
+       }
+
+      dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
+    }
+
+  if (name)
+    {
+      /* EFI breaks paths with backslashes.  */
+      char *p;
+
+      for (p = name; *p; p++)
+       if (*p == '\\')
+         *p = '/';
+    }
+
+  return name;
+}
+
+grub_efi_device_path_t *
+grub_efi_get_device_path (grub_efi_handle_t handle)
+{
+  return grub_efi_open_protocol (handle, &device_path_guid,
+                                GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+}
+
+/* Print the chain of Device Path nodes. This is mainly for debugging. */
+void
+grub_efi_print_device_path (grub_efi_device_path_t *dp)
+{
+  while (1)
+    {
+      grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
+      grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
+      grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
+
+      switch (type)
+       {
+       case GRUB_EFI_END_DEVICE_PATH_TYPE:
+         switch (subtype)
+           {
+           case GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE:
+             grub_printf ("/EndEntire\n");
+             //grub_putchar ('\n');
+             break;
+           case GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE:
+             grub_printf ("/EndThis\n");
+             //grub_putchar ('\n');
+             break;
+           default:
+             grub_printf ("/EndUnknown(%x)\n", (unsigned) subtype);
+             break;
+           }
+         break;
+
+       case GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE:
+         switch (subtype)
+           {
+           case GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_pci_device_path_t pci;
+               grub_memcpy (&pci, dp, len);
+               grub_printf ("/PCI(%x,%x)",
+                            (unsigned) pci.function, (unsigned) pci.device);
+             }
+             break;
+           case GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_pccard_device_path_t pccard;
+               grub_memcpy (&pccard, dp, len);
+               grub_printf ("/PCCARD(%x)",
+                            (unsigned) pccard.function);
+             }
+             break;
+           case GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_memory_mapped_device_path_t mmapped;
+               grub_memcpy (&mmapped, dp, len);
+               grub_printf ("/MMap(%x,%llx,%llx)",
+                            (unsigned) mmapped.memory_type,
+                            (unsigned long long) mmapped.start_address,
+                            (unsigned long long) mmapped.end_address);
+             }
+             break;
+           case GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_vendor_device_path_t vendor;
+               grub_memcpy (&vendor, dp, sizeof (vendor));
+               grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
+                            (unsigned) vendor.vendor_guid.data1,
+                            (unsigned) vendor.vendor_guid.data2,
+                            (unsigned) vendor.vendor_guid.data3,
+                            (unsigned) vendor.vendor_guid.data4[0],
+                            (unsigned) vendor.vendor_guid.data4[1],
+                            (unsigned) vendor.vendor_guid.data4[2],
+                            (unsigned) vendor.vendor_guid.data4[3],
+                            (unsigned) vendor.vendor_guid.data4[4],
+                            (unsigned) vendor.vendor_guid.data4[5],
+                            (unsigned) vendor.vendor_guid.data4[6],
+                            (unsigned) vendor.vendor_guid.data4[7]);
+             }
+             break;
+           case GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_controller_device_path_t controller;
+               grub_memcpy (&controller, dp, len);
+               grub_printf ("/Ctrl(%x)",
+                            (unsigned) controller.controller_number);
+             }
+             break;
+           default:
+             grub_printf ("/UnknownHW(%x)", (unsigned) subtype);
+             break;
+           }
+         break;
+
+       case GRUB_EFI_ACPI_DEVICE_PATH_TYPE:
+         switch (subtype)
+           {
+           case GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_acpi_device_path_t acpi;
+               grub_memcpy (&acpi, dp, len);
+               grub_printf ("/ACPI(%x,%x)",
+                            (unsigned) acpi.hid,
+                            (unsigned) acpi.uid);
+             }
+             break;
+           case GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_expanded_acpi_device_path_t eacpi;
+               grub_memcpy (&eacpi, dp, sizeof (eacpi));
+               grub_printf ("/ACPI(");
+
+               if (GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp)[0] == '\0')
+                 grub_printf ("%x,", (unsigned) eacpi.hid);
+               else
+                 grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp));
+
+               if (GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp)[0] == '\0')
+                 grub_printf ("%x,", (unsigned) eacpi.uid);
+               else
+                 grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp));
+
+               if (GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp)[0] == '\0')
+                 grub_printf ("%x)", (unsigned) eacpi.cid);
+               else
+                 grub_printf ("%s)", GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp));
+             }
+             break;
+           default:
+             grub_printf ("/UnknownACPI(%x)", (unsigned) subtype);
+             break;
+           }
+         break;
+
+       case GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE:
+         switch (subtype)
+           {
+           case GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_atapi_device_path_t atapi;
+               grub_memcpy (&atapi, dp, len);
+               grub_printf ("/ATAPI(%x,%x,%x)",
+                            (unsigned) atapi.primary_secondary,
+                            (unsigned) atapi.slave_master,
+                            (unsigned) atapi.lun);
+             }
+             break;
+           case GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_scsi_device_path_t scsi;
+               grub_memcpy (&scsi, dp, len);
+               grub_printf ("/SCSI(%x,%x)",
+                            (unsigned) scsi.pun,
+                            (unsigned) scsi.lun);
+             }
+             break;
+           case GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_fibre_channel_device_path_t fc;
+               grub_memcpy (&fc, dp, len);
+               grub_printf ("/FibreChannel(%llx,%llx)",
+                            (unsigned long long) fc.wwn,
+                            (unsigned long long) fc.lun);
+             }
+             break;
+           case GRUB_EFI_1394_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_1394_device_path_t firewire;
+               grub_memcpy (&firewire, dp, len);
+               grub_printf ("/1394(%llx)", (unsigned long long) firewire.guid);
+             }
+             break;
+           case GRUB_EFI_USB_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_usb_device_path_t usb;
+               grub_memcpy (&usb, dp, len);
+               grub_printf ("/USB(%x,%x)",
+                            (unsigned) usb.parent_port_number,
+                            (unsigned) usb.interface);
+             }
+             break;
+           case GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_usb_class_device_path_t usb_class;
+               grub_memcpy (&usb_class, dp, len);
+               grub_printf ("/USBClass(%x,%x,%x,%x,%x)",
+                            (unsigned) usb_class.vendor_id,
+                            (unsigned) usb_class.product_id,
+                            (unsigned) usb_class.device_class,
+                            (unsigned) usb_class.device_subclass,
+                            (unsigned) usb_class.device_protocol);
+             }
+             break;
+           case GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_i2o_device_path_t i2o;
+               grub_memcpy (&i2o, dp, len);
+               grub_printf ("/I2O(%x)", (unsigned) i2o.tid);
+             }
+             break;
+           case GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_mac_address_device_path_t mac;
+               grub_memcpy (&mac, dp, len);
+               grub_printf ("/MacAddr(%02x:%02x:%02x:%02x:%02x:%02x,%x)",
+                            (unsigned) mac.mac_address[0],
+                            (unsigned) mac.mac_address[1],
+                            (unsigned) mac.mac_address[2],
+                            (unsigned) mac.mac_address[3],
+                            (unsigned) mac.mac_address[4],
+                            (unsigned) mac.mac_address[5],
+                            (unsigned) mac.if_type);
+             }
+             break;
+           case GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_ipv4_device_path_t ipv4;
+               grub_memcpy (&ipv4, dp, len);
+               grub_printf ("/IPv4(%u.%u.%u.%u,%u.%u.%u.%u,%u,%u,%x,%x)",
+                            (unsigned) ipv4.local_ip_address[0],
+                            (unsigned) ipv4.local_ip_address[1],
+                            (unsigned) ipv4.local_ip_address[2],
+                            (unsigned) ipv4.local_ip_address[3],
+                            (unsigned) ipv4.remote_ip_address[0],
+                            (unsigned) ipv4.remote_ip_address[1],
+                            (unsigned) ipv4.remote_ip_address[2],
+                            (unsigned) ipv4.remote_ip_address[3],
+                            (unsigned) ipv4.local_port,
+                            (unsigned) ipv4.remote_port,
+                            (unsigned) ipv4.protocol,
+                            (unsigned) ipv4.static_ip_address);
+             }
+             break;
+           case GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_ipv6_device_path_t ipv6;
+               grub_memcpy (&ipv6, dp, len);
+               grub_printf ("/IPv6(%x:%x:%x:%x:%x:%x:%x:%x,%x:%x:%x:%x:%x:%x:%x:%x,%u,%u,%x,%x)",
+                            (unsigned) ipv6.local_ip_address[0],
+                            (unsigned) ipv6.local_ip_address[1],
+                            (unsigned) ipv6.local_ip_address[2],
+                            (unsigned) ipv6.local_ip_address[3],
+                            (unsigned) ipv6.local_ip_address[4],
+                            (unsigned) ipv6.local_ip_address[5],
+                            (unsigned) ipv6.local_ip_address[6],
+                            (unsigned) ipv6.local_ip_address[7],
+                            (unsigned) ipv6.remote_ip_address[0],
+                            (unsigned) ipv6.remote_ip_address[1],
+                            (unsigned) ipv6.remote_ip_address[2],
+                            (unsigned) ipv6.remote_ip_address[3],
+                            (unsigned) ipv6.remote_ip_address[4],
+                            (unsigned) ipv6.remote_ip_address[5],
+                            (unsigned) ipv6.remote_ip_address[6],
+                            (unsigned) ipv6.remote_ip_address[7],
+                            (unsigned) ipv6.local_port,
+                            (unsigned) ipv6.remote_port,
+                            (unsigned) ipv6.protocol,
+                            (unsigned) ipv6.static_ip_address);
+             }
+             break;
+           case GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_infiniband_device_path_t ib;
+               grub_memcpy (&ib, dp, len);
+               grub_printf ("/InfiniBand(%x,%llx,%llx,%llx)",
+                            (unsigned) ib.port_gid[0], /* XXX */
+                            (unsigned long long) ib.remote_id,
+                            (unsigned long long) ib.target_port_id,
+                            (unsigned long long) ib.device_id);
+             }
+             break;
+           case GRUB_EFI_UART_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_uart_device_path_t uart;
+               grub_memcpy (&uart, dp, len);
+               grub_printf ("/UART(%llu,%u,%x,%x)",
+                            (unsigned long long) uart.baud_rate,
+                            uart.data_bits,
+                            uart.parity,
+                            uart.stop_bits);
+             }
+             break;
+           case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_vendor_messaging_device_path_t vendor;
+               grub_memcpy (&vendor, dp, sizeof (vendor));
+               grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
+                            (unsigned) vendor.vendor_guid.data1,
+                            (unsigned) vendor.vendor_guid.data2,
+                            (unsigned) vendor.vendor_guid.data3,
+                            (unsigned) vendor.vendor_guid.data4[0],
+                            (unsigned) vendor.vendor_guid.data4[1],
+                            (unsigned) vendor.vendor_guid.data4[2],
+                            (unsigned) vendor.vendor_guid.data4[3],
+                            (unsigned) vendor.vendor_guid.data4[4],
+                            (unsigned) vendor.vendor_guid.data4[5],
+                            (unsigned) vendor.vendor_guid.data4[6],
+                            (unsigned) vendor.vendor_guid.data4[7]);
+             }
+             break;
+           default:
+             grub_printf ("/UnknownMessaging(%x)", (unsigned) subtype);
+             break;
+           }
+         break;
+
+       case GRUB_EFI_MEDIA_DEVICE_PATH_TYPE:
+         switch (subtype)
+           {
+           case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_hard_drive_device_path_t hd;
+               grub_memcpy (&hd, dp, len);
+               grub_printf ("/HD(%u,%llx,%llx,%02x%02x%02x%02x%02x%02x%02x%02x,%x,%x)",
+                            hd.partition_number,
+                            (unsigned long long) hd.partition_start,
+                            (unsigned long long) hd.partition_size,
+                            (unsigned) hd.partition_signature[0],
+                            (unsigned) hd.partition_signature[1],
+                            (unsigned) hd.partition_signature[2],
+                            (unsigned) hd.partition_signature[3],
+                            (unsigned) hd.partition_signature[4],
+                            (unsigned) hd.partition_signature[5],
+                            (unsigned) hd.partition_signature[6],
+                            (unsigned) hd.partition_signature[7],
+                            (unsigned) hd.mbr_type,
+                            (unsigned) hd.signature_type);
+             }
+             break;
+           case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_cdrom_device_path_t cd;
+               grub_memcpy (&cd, dp, len);
+               grub_printf ("/CD(%u,%llx,%llx)",
+                            cd.boot_entry,
+                            (unsigned long long) cd.partition_start,
+                            (unsigned long long) cd.partition_size);
+             }
+             break;
+           case GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_vendor_media_device_path_t vendor;
+               grub_memcpy (&vendor, dp, sizeof (vendor));
+               grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
+                            (unsigned) vendor.vendor_guid.data1,
+                            (unsigned) vendor.vendor_guid.data2,
+                            (unsigned) vendor.vendor_guid.data3,
+                            (unsigned) vendor.vendor_guid.data4[0],
+                            (unsigned) vendor.vendor_guid.data4[1],
+                            (unsigned) vendor.vendor_guid.data4[2],
+                            (unsigned) vendor.vendor_guid.data4[3],
+                            (unsigned) vendor.vendor_guid.data4[4],
+                            (unsigned) vendor.vendor_guid.data4[5],
+                            (unsigned) vendor.vendor_guid.data4[6],
+                            (unsigned) vendor.vendor_guid.data4[7]);
+             }
+             break;
+           case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_file_path_device_path_t *fp;
+               grub_uint8_t buf[(len - 4) * 2 + 1];
+               fp = (grub_efi_file_path_device_path_t *) dp;
+               *grub_utf16_to_utf8 (buf, fp->path_name,
+                                    (len - 4) / sizeof (grub_efi_char16_t))
+                 = '\0';
+               grub_printf ("/File(%s)", buf);
+             }
+             break;
+           case GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_protocol_device_path_t proto;
+               grub_memcpy (&proto, dp, sizeof (proto));
+               grub_printf ("/Protocol(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
+                            (unsigned) proto.guid.data1,
+                            (unsigned) proto.guid.data2,
+                            (unsigned) proto.guid.data3,
+                            (unsigned) proto.guid.data4[0],
+                            (unsigned) proto.guid.data4[1],
+                            (unsigned) proto.guid.data4[2],
+                            (unsigned) proto.guid.data4[3],
+                            (unsigned) proto.guid.data4[4],
+                            (unsigned) proto.guid.data4[5],
+                            (unsigned) proto.guid.data4[6],
+                            (unsigned) proto.guid.data4[7]);
+             }
+             break;
+           default:
+             grub_printf ("/UnknownMedia(%x)", (unsigned) subtype);
+             break;
+           }
+         break;
+
+       case GRUB_EFI_BIOS_DEVICE_PATH_TYPE:
+         switch (subtype)
+           {
+           case GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE:
+             {
+               grub_efi_bios_device_path_t bios;
+               grub_memcpy (&bios, dp, sizeof (bios));
+               grub_printf ("/BIOS(%x,%x,%s)",
+                            (unsigned) bios.device_type,
+                            (unsigned) bios.status_flags,
+                            (char *) (dp + 1));
+             }
+             break;
+           default:
+             grub_printf ("/UnknownBIOS(%x)", (unsigned) subtype);
+             break;
+           }
+         break;
+
+       default:
+         grub_printf ("/UnknownType(%x,%x)\n",
+                      (unsigned) type,
+                      (unsigned) subtype);
+         return;
+         break;
+       }
+
+      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
+       break;
+
+      dp = (grub_efi_device_path_t *) ((char *) dp + len);
+    }
+}
+
+int
+grub_efi_finish_boot_services (void)
+{
+  grub_efi_uintn_t mmap_size = 0;
+  grub_efi_uintn_t map_key;
+  grub_efi_uintn_t desc_size;
+  grub_efi_uint32_t desc_version;
+  void *mmap_buf = 0;
+
+  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
+                              &desc_size, &desc_version) < 0)
+    return 0;
+
+  mmap_buf = grub_malloc (mmap_size);
+
+  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
+                              &desc_size, &desc_version) <= 0)
+    return 0;
+
+  return grub_efi_exit_boot_services (map_key);
+}
+
diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
new file mode 100644 (file)
index 0000000..a0b4ff7
--- /dev/null
@@ -0,0 +1,85 @@
+/* init.c - generic EFI initialization and finalization */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/efi/efi.h>
+#include <grub/efi/console.h>
+#include <grub/efi/disk.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/mm.h>
+#include <grub/machine/kernel.h>
+
+void
+grub_efi_init (void)
+{
+  /* First of all, initialize the console so that GRUB can display
+     messages.  */
+  grub_console_init ();
+
+  /* Initialize the memory management system.  */
+  grub_efi_mm_init ();
+
+  grub_efidisk_init ();
+}
+
+void
+grub_efi_set_prefix (void)
+{
+  grub_efi_loaded_image_t *image;
+
+  image = grub_efi_get_loaded_image (grub_efi_image_handle);
+  if (image)
+    {
+      char *device;
+      char *file;
+
+      device = grub_efidisk_get_device_name (image->device_handle);
+      file = grub_efi_get_filename (image->file_path);
+
+      if (device && file)
+       {
+         char *p;
+         char *prefix;
+
+         /* Get the directory.  */
+         p = grub_strrchr (file, '/');
+         if (p)
+           *p = '\0';
+
+         prefix = grub_xasprintf ("(%s)%s", device, file);
+         if (prefix)
+           {
+             
+             grub_env_set ("prefix", prefix);
+             grub_free (prefix);
+           }
+       }
+
+      grub_free (device);
+      grub_free (file);
+    }
+}
+
+void
+grub_efi_fini (void)
+{
+  grub_efidisk_fini ();
+  grub_console_fini ();
+}
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
new file mode 100644 (file)
index 0000000..ceb8fc9
--- /dev/null
@@ -0,0 +1,431 @@
+/* mm.c - generic EFI memory management */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+
+#define NEXT_MEMORY_DESCRIPTOR(desc, size)     \
+  ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
+
+#define BYTES_TO_PAGES(bytes)  ((bytes) >> 12)
+#define PAGES_TO_BYTES(pages)  ((pages) << 12)
+
+/* The size of a memory map obtained from the firmware. This must be
+   a multiplier of 4KB.  */
+#define MEMORY_MAP_SIZE        0x3000
+
+/* Maintain the list of allocated pages.  */
+struct allocated_page
+{
+  grub_efi_physical_address_t addr;
+  grub_efi_uint64_t num_pages;
+};
+
+#define ALLOCATED_PAGES_SIZE   0x1000
+#define MAX_ALLOCATED_PAGES    \
+  (ALLOCATED_PAGES_SIZE / sizeof (struct allocated_page))
+
+static struct allocated_page *allocated_pages = 0;
+
+/* The minimum and maximum heap size for GRUB itself.  */
+#define MIN_HEAP_SIZE  0x100000
+#define MAX_HEAP_SIZE  (1600 * 0x100000)
+
+
+/* Allocate pages. Return the pointer to the first of allocated pages.  */
+void *
+grub_efi_allocate_pages (grub_efi_physical_address_t address,
+                        grub_efi_uintn_t pages)
+{
+  grub_efi_allocate_type_t type;
+  grub_efi_status_t status;
+  grub_efi_boot_services_t *b;
+
+#if GRUB_TARGET_SIZEOF_VOID_P < 8
+  /* Limit the memory access to less than 4GB for 32-bit platforms.  */
+  if (address > 0xffffffff)
+    return 0;
+#endif
+
+#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
+  if (address == 0)
+    {
+      type = GRUB_EFI_ALLOCATE_MAX_ADDRESS;
+      address = 0xffffffff;
+    }
+  else
+    type = GRUB_EFI_ALLOCATE_ADDRESS;
+#else
+  if (address == 0)
+    type = GRUB_EFI_ALLOCATE_ANY_PAGES;
+  else
+    type = GRUB_EFI_ALLOCATE_ADDRESS;
+#endif
+
+  b = grub_efi_system_table->boot_services;
+  status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_LOADER_DATA, pages, &address);
+  if (status != GRUB_EFI_SUCCESS)
+    return 0;
+
+  if (address == 0)
+    {
+      /* Uggh, the address 0 was allocated... This is too annoying,
+        so reallocate another one.  */
+      address = 0xffffffff;
+      status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_LOADER_DATA, pages, &address);
+      grub_efi_free_pages (0, pages);
+      if (status != GRUB_EFI_SUCCESS)
+       return 0;
+    }
+
+  if (allocated_pages)
+    {
+      unsigned i;
+
+      for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
+       if (allocated_pages[i].addr == 0)
+         {
+           allocated_pages[i].addr = address;
+           allocated_pages[i].num_pages = pages;
+           break;
+         }
+
+      if (i == MAX_ALLOCATED_PAGES)
+       grub_fatal ("too many page allocations");
+    }
+
+  return (void *) ((grub_addr_t) address);
+}
+
+/* Free pages starting from ADDRESS.  */
+void
+grub_efi_free_pages (grub_efi_physical_address_t address,
+                    grub_efi_uintn_t pages)
+{
+  grub_efi_boot_services_t *b;
+
+  if (allocated_pages
+      && ((grub_efi_physical_address_t) ((grub_addr_t) allocated_pages)
+         != address))
+    {
+      unsigned i;
+
+      for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
+       if (allocated_pages[i].addr == address)
+         {
+           allocated_pages[i].addr = 0;
+           break;
+         }
+    }
+
+  b = grub_efi_system_table->boot_services;
+  efi_call_2 (b->free_pages, address, pages);
+}
+
+/* Get the memory map as defined in the EFI spec. Return 1 if successful,
+   return 0 if partial, or return -1 if an error occurs.  */
+int
+grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size,
+                        grub_efi_memory_descriptor_t *memory_map,
+                        grub_efi_uintn_t *map_key,
+                        grub_efi_uintn_t *descriptor_size,
+                        grub_efi_uint32_t *descriptor_version)
+{
+  grub_efi_status_t status;
+  grub_efi_boot_services_t *b;
+  grub_efi_uintn_t key;
+  grub_efi_uint32_t version;
+
+  /* Allow some parameters to be missing.  */
+  if (! map_key)
+    map_key = &key;
+  if (! descriptor_version)
+    descriptor_version = &version;
+
+  b = grub_efi_system_table->boot_services;
+  status = efi_call_5 (b->get_memory_map, memory_map_size, memory_map, map_key,
+                             descriptor_size, descriptor_version);
+  if (status == GRUB_EFI_SUCCESS)
+    return 1;
+  else if (status == GRUB_EFI_BUFFER_TOO_SMALL)
+    return 0;
+  else
+    return -1;
+}
+
+/* Sort the memory map in place.  */
+static void
+sort_memory_map (grub_efi_memory_descriptor_t *memory_map,
+                grub_efi_uintn_t desc_size,
+                grub_efi_memory_descriptor_t *memory_map_end)
+{
+  grub_efi_memory_descriptor_t *d1;
+  grub_efi_memory_descriptor_t *d2;
+
+  for (d1 = memory_map;
+       d1 < memory_map_end;
+       d1 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size))
+    {
+      grub_efi_memory_descriptor_t *max_desc = d1;
+
+      for (d2 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size);
+          d2 < memory_map_end;
+          d2 = NEXT_MEMORY_DESCRIPTOR (d2, desc_size))
+       {
+         if (max_desc->num_pages < d2->num_pages)
+           max_desc = d2;
+       }
+
+      if (max_desc != d1)
+       {
+         grub_efi_memory_descriptor_t tmp;
+
+         tmp = *d1;
+         *d1 = *max_desc;
+         *max_desc = tmp;
+       }
+    }
+}
+
+/* Filter the descriptors. GRUB needs only available memory.  */
+static grub_efi_memory_descriptor_t *
+filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
+                  grub_efi_memory_descriptor_t *filtered_memory_map,
+                  grub_efi_uintn_t desc_size,
+                  grub_efi_memory_descriptor_t *memory_map_end)
+{
+  grub_efi_memory_descriptor_t *desc;
+  grub_efi_memory_descriptor_t *filtered_desc;
+
+  for (desc = memory_map, filtered_desc = filtered_memory_map;
+       desc < memory_map_end;
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+    {
+      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
+#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
+         && desc->physical_start <= 0xffffffff
+#endif
+         && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000
+         && desc->num_pages != 0)
+       {
+         grub_memcpy (filtered_desc, desc, desc_size);
+
+         /* Avoid less than 1MB, because some loaders seem to be confused.  */
+         if (desc->physical_start < 0x100000)
+           {
+             desc->num_pages -= BYTES_TO_PAGES (0x100000
+                                                - desc->physical_start);
+             desc->physical_start = 0x100000;
+           }
+
+#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
+         if (BYTES_TO_PAGES (filtered_desc->physical_start)
+             + filtered_desc->num_pages
+             > BYTES_TO_PAGES (0x100000000LL))
+           filtered_desc->num_pages
+             = (BYTES_TO_PAGES (0x100000000LL)
+                - BYTES_TO_PAGES (filtered_desc->physical_start));
+#endif
+
+         if (filtered_desc->num_pages == 0)
+           continue;
+
+         filtered_desc = NEXT_MEMORY_DESCRIPTOR (filtered_desc, desc_size);
+       }
+    }
+
+  return filtered_desc;
+}
+
+/* Return the total number of pages.  */
+static grub_efi_uint64_t
+get_total_pages (grub_efi_memory_descriptor_t *memory_map,
+                grub_efi_uintn_t desc_size,
+                grub_efi_memory_descriptor_t *memory_map_end)
+{
+  grub_efi_memory_descriptor_t *desc;
+  grub_efi_uint64_t total = 0;
+
+  for (desc = memory_map;
+       desc < memory_map_end;
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+    total += desc->num_pages;
+
+  return total;
+}
+
+/* Add memory regions.  */
+static void
+add_memory_regions (grub_efi_memory_descriptor_t *memory_map,
+                   grub_efi_uintn_t desc_size,
+                   grub_efi_memory_descriptor_t *memory_map_end,
+                   grub_efi_uint64_t required_pages)
+{
+  grub_efi_memory_descriptor_t *desc;
+
+  for (desc = memory_map;
+       desc < memory_map_end;
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+    {
+      grub_efi_uint64_t pages;
+      grub_efi_physical_address_t start;
+      void *addr;
+
+      start = desc->physical_start;
+      pages = desc->num_pages;
+      if (pages > required_pages)
+       {
+         start += PAGES_TO_BYTES (pages - required_pages);
+         pages = required_pages;
+       }
+
+      addr = grub_efi_allocate_pages (start, pages);
+      if (! addr)
+       grub_fatal ("cannot allocate conventional memory %p with %u pages",
+                   (void *) ((grub_addr_t) start),
+                   (unsigned) pages);
+
+      grub_mm_init_region (addr, PAGES_TO_BYTES (pages));
+
+      required_pages -= pages;
+      if (required_pages == 0)
+       break;
+    }
+
+  if (required_pages > 0)
+    grub_fatal ("too little memory");
+}
+
+#if 0
+/* Print the memory map.  */
+static void
+print_memory_map (grub_efi_memory_descriptor_t *memory_map,
+                 grub_efi_uintn_t desc_size,
+                 grub_efi_memory_descriptor_t *memory_map_end)
+{
+  grub_efi_memory_descriptor_t *desc;
+  int i;
+
+  for (desc = memory_map, i = 0;
+       desc < memory_map_end;
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size), i++)
+    {
+      grub_printf ("MD: t=%x, p=%llx, v=%llx, n=%llx, a=%llx\n",
+                  desc->type, desc->physical_start, desc->virtual_start,
+                  desc->num_pages, desc->attribute);
+    }
+}
+#endif
+
+void
+grub_efi_mm_init (void)
+{
+  grub_efi_memory_descriptor_t *memory_map;
+  grub_efi_memory_descriptor_t *memory_map_end;
+  grub_efi_memory_descriptor_t *filtered_memory_map;
+  grub_efi_memory_descriptor_t *filtered_memory_map_end;
+  grub_efi_uintn_t map_size;
+  grub_efi_uintn_t desc_size;
+  grub_efi_uint64_t total_pages;
+  grub_efi_uint64_t required_pages;
+
+  /* First of all, allocate pages to maintain allocations.  */
+  allocated_pages
+    = grub_efi_allocate_pages (0, BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE));
+  if (! allocated_pages)
+    grub_fatal ("cannot allocate memory");
+
+  grub_memset (allocated_pages, 0, ALLOCATED_PAGES_SIZE);
+
+  /* Prepare a memory region to store two memory maps.  */
+  memory_map = grub_efi_allocate_pages (0,
+                                       2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+  if (! memory_map)
+    grub_fatal ("cannot allocate memory");
+
+  filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map, MEMORY_MAP_SIZE);
+
+  /* Obtain descriptors for available memory.  */
+  map_size = MEMORY_MAP_SIZE;
+
+  if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0)
+    grub_fatal ("cannot get memory map");
+
+  memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size);
+
+  filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map,
+                                              desc_size, memory_map_end);
+
+  /* By default, request a quarter of the available memory.  */
+  total_pages = get_total_pages (filtered_memory_map, desc_size,
+                                filtered_memory_map_end);
+  required_pages = (total_pages >> 2);
+  if (required_pages < BYTES_TO_PAGES (MIN_HEAP_SIZE))
+    required_pages = BYTES_TO_PAGES (MIN_HEAP_SIZE);
+  else if (required_pages > BYTES_TO_PAGES (MAX_HEAP_SIZE))
+    required_pages = BYTES_TO_PAGES (MAX_HEAP_SIZE);
+
+  /* Sort the filtered descriptors, so that GRUB can allocate pages
+     from smaller regions.  */
+  sort_memory_map (filtered_memory_map, desc_size, filtered_memory_map_end);
+
+  /* Allocate memory regions for GRUB's memory management.  */
+  add_memory_regions (filtered_memory_map, desc_size,
+                     filtered_memory_map_end, required_pages);
+
+#if 0
+  /* For debug.  */
+  map_size = MEMORY_MAP_SIZE;
+
+  if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0)
+    grub_fatal ("cannot get memory map");
+
+  grub_printf ("printing memory map\n");
+  print_memory_map (memory_map, desc_size,
+                   NEXT_MEMORY_DESCRIPTOR (memory_map, map_size));
+  grub_abort ();
+#endif
+
+  /* Release the memory maps.  */
+  grub_efi_free_pages ((grub_addr_t) memory_map,
+                      2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+}
+
+void
+grub_efi_mm_fini (void)
+{
+  if (allocated_pages)
+    {
+      unsigned i;
+
+      for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
+       {
+         struct allocated_page *p;
+
+         p = allocated_pages + i;
+         if (p->addr != 0)
+           grub_efi_free_pages ((grub_addr_t) p->addr, p->num_pages);
+       }
+
+      grub_efi_free_pages ((grub_addr_t) allocated_pages,
+                          BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE));
+    }
+}
diff --git a/grub-core/kern/elf.c b/grub-core/kern/elf.c
new file mode 100644 (file)
index 0000000..d9948a8
--- /dev/null
@@ -0,0 +1,480 @@
+/* elf.c - load ELF files */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <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_zalloc (sizeof (*elf));
+  if (! elf)
+    return 0;
+
+  elf->file = file;
+
+  if (grub_file_seek (elf->file, 0) == (grub_off_t) -1)
+    goto fail;
+
+  if (grub_file_read (elf->file, &elf->ehdr, sizeof (elf->ehdr))
+      != sizeof (elf->ehdr))
+    {
+      grub_error_push ();
+      grub_error (GRUB_ERR_READ_ERROR, "cannot read ELF header");
+      goto fail;
+    }
+
+  if (grub_elf_check_header (elf))
+    goto fail;
+
+  return elf;
+
+fail:
+  grub_free (elf->phdrs);
+  grub_free (elf);
+  return 0;
+}
+
+grub_elf_t
+grub_elf_open (const char *name)
+{
+  grub_file_t file;
+  grub_elf_t elf;
+
+  file = grub_gzfile_open (name, 1);
+  if (! file)
+    return 0;
+
+  elf = grub_elf_file (file);
+  if (! elf)
+    grub_file_close (file);
+
+  return elf;
+}
+
+\f
+/* 32-bit */
+
+int
+grub_elf_is_elf32 (grub_elf_t elf)
+{
+  return elf->ehdr.ehdr32.e_ident[EI_CLASS] == ELFCLASS32;
+}
+
+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%lx.\n",
+               (unsigned long long) elf->ehdr.ehdr32.e_phoff,
+               (unsigned long) 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))
+    {
+      grub_error_push ();
+      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 NESTED_FUNC_ATTR (*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 "
+                   "filesz %lx\n",
+                   i, phdr->p_type,
+                   (unsigned long) phdr->p_paddr,
+                   (unsigned long) phdr->p_memsz,
+                   (unsigned long) phdr->p_filesz);
+      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 *base)
+{
+  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 NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf32_Phdr *phdr, void *_arg);
+  int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf  __attribute__ ((unused)),
+                                Elf32_Phdr *phdr,
+                                void *_arg __attribute__ ((unused)))
+    {
+      /* 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 (base)
+    *base = 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;
+    }
+
+  if (base)
+    *base = segments_start;
+
+  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,
+                grub_addr_t *base, grub_size_t *size)
+{
+  grub_addr_t load_base = (grub_addr_t) -1ULL;
+  grub_size_t load_size = 0;
+  grub_err_t err;
+
+  auto int NESTED_FUNC_ATTR grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *hook);
+  int NESTED_FUNC_ATTR 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;
+    int do_load = 1;
+
+    load_addr = phdr->p_paddr;
+    if (load_hook && load_hook (phdr, &load_addr, &do_load))
+      return 1;
+
+    if (! do_load)
+      return 0;
+
+    if (load_addr < load_base)
+      load_base = load_addr;
+
+    grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n",
+                 (unsigned long long) load_addr,
+                 (unsigned long long) phdr->p_memsz);
+
+    if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1)
+      {
+       grub_error_push ();
+       return grub_error (GRUB_ERR_BAD_OS,
+                          "invalid offset in program header");
+      }
+
+    if (phdr->p_filesz)
+      {
+       grub_ssize_t read;
+       read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz);
+       if (read != (grub_ssize_t) phdr->p_filesz)
+         {
+           /* XXX How can we free memory from `load_hook'? */
+           grub_error_push ();
+           return grub_error (GRUB_ERR_BAD_OS,
+                              "couldn't read segment from file: "
+                              "wanted 0x%lx bytes; read 0x%lx bytes",
+                              phdr->p_filesz, read);
+         }
+      }
+
+    if (phdr->p_filesz < phdr->p_memsz)
+      grub_memset ((void *) (long) (load_addr + phdr->p_filesz),
+                  0, phdr->p_memsz - phdr->p_filesz);
+
+    load_size += phdr->p_memsz;
+
+    return 0;
+  }
+
+  err = grub_elf32_phdr_iterate (_elf, grub_elf32_load_segment, _load_hook);
+
+  if (base)
+    *base = load_base;
+  if (size)
+    *size = load_size;
+
+  return err;
+}
+
+
+\f
+/* 64-bit */
+
+int
+grub_elf_is_elf64 (grub_elf_t elf)
+{
+  return elf->ehdr.ehdr64.e_ident[EI_CLASS] == ELFCLASS64;
+}
+
+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%lx.\n",
+               (unsigned long long) elf->ehdr.ehdr64.e_phoff,
+               (unsigned long) 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))
+    {
+      grub_error_push ();
+      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 NESTED_FUNC_ATTR (*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 "
+                   "filesz %lx\n",
+                   i, phdr->p_type,
+                   (unsigned long) phdr->p_paddr,
+                   (unsigned long) phdr->p_memsz,
+                   (unsigned long) phdr->p_filesz);
+      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 *base)
+{
+  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 NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg);
+  int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)),
+                                Elf64_Phdr *phdr,
+                                void *_arg __attribute__ ((unused)))
+    {
+      /* 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 (base)
+    *base = 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;
+    }
+
+  if (base)
+    *base = segments_start;
+
+  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,
+                grub_addr_t *base, grub_size_t *size)
+{
+  grub_addr_t load_base = (grub_addr_t) -1ULL;
+  grub_size_t load_size = 0;
+  grub_err_t err;
+
+  auto int NESTED_FUNC_ATTR grub_elf64_load_segment (grub_elf_t elf, Elf64_Phdr *phdr,
+                                                    void *hook);
+  int NESTED_FUNC_ATTR 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;
+    int do_load = 1;
+
+    load_addr = phdr->p_paddr;
+    if (load_hook && load_hook (phdr, &load_addr, &do_load))
+      return 1;
+
+    if (! do_load)
+      return 0;
+
+    if (load_addr < load_base)
+      load_base = load_addr;
+
+    grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n",
+                 (unsigned long long) load_addr,
+                 (unsigned long long) phdr->p_memsz);
+
+    if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1)
+      {
+       grub_error_push ();
+       return grub_error (GRUB_ERR_BAD_OS,
+                          "invalid offset in program header");
+      }
+
+    if (phdr->p_filesz)
+      {
+       grub_ssize_t read;
+       read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz);
+       if (read != (grub_ssize_t) phdr->p_filesz)
+          {
+           /* XXX How can we free memory from `load_hook'?  */
+           grub_error_push ();
+           return grub_error (GRUB_ERR_BAD_OS,
+                             "couldn't read segment from file: "
+                             "wanted 0x%lx bytes; read 0x%lx bytes",
+                             phdr->p_filesz, read);
+          }
+      }
+
+    if (phdr->p_filesz < phdr->p_memsz)
+      grub_memset ((void *) (long) (load_addr + phdr->p_filesz),
+                  0, phdr->p_memsz - phdr->p_filesz);
+
+    load_size += phdr->p_memsz;
+
+    return 0;
+  }
+
+  err = grub_elf64_phdr_iterate (_elf, grub_elf64_load_segment, _load_hook);
+
+  if (base)
+    *base = load_base;
+  if (size)
+    *size = load_size;
+
+  return err;
+}
diff --git a/grub-core/kern/emu/cache.S b/grub-core/kern/emu/cache.S
new file mode 100644 (file)
index 0000000..087b2b4
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef GRUB_MACHINE_EMU
+#error "This source is only meant for grub-emu platform"
+#endif
+
+#if GRUB_CPU_I386
+#elif GRUB_CPU_X86_64
+#elif GRUB_CPU_SPARC64
+#include "../sparc64/cache.S"
+#elif GRUB_CPU_MIPS
+#include "../mips/cache.S"
+#elif GRUB_CPU_MIPSEL
+#include "../mips/cache.S"
+#elif GRUB_CPU_POWERPC
+#include "../powerpc/cache.S"
+#else
+#error "No target cpu type is defined"
+#endif
diff --git a/grub-core/kern/emu/console.c b/grub-core/kern/emu/console.c
new file mode 100644 (file)
index 0000000..f7fbc89
--- /dev/null
@@ -0,0 +1,384 @@
+/*  console.c -- Ncurses console for GRUB.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+/* For compatibility.  */
+#ifndef A_NORMAL
+# define A_NORMAL      0
+#endif /* ! A_NORMAL */
+#ifndef A_STANDOUT
+# define A_STANDOUT    0
+#endif /* ! A_STANDOUT */
+
+#include <grub/emu/console.h>
+#include <grub/term.h>
+#include <grub/types.h>
+
+#if defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
+
+static int grub_console_attr = A_NORMAL;
+
+grub_uint8_t grub_console_cur_color = 7;
+
+static grub_uint8_t grub_console_standard_color = 0x7;
+static grub_uint8_t grub_console_normal_color = 0x7;
+static grub_uint8_t grub_console_highlight_color = 0x70;
+
+#define NUM_COLORS     8
+
+static grub_uint8_t color_map[NUM_COLORS] =
+{
+  COLOR_BLACK,
+  COLOR_BLUE,
+  COLOR_GREEN,
+  COLOR_CYAN,
+  COLOR_RED,
+  COLOR_MAGENTA,
+  COLOR_YELLOW,
+  COLOR_WHITE
+};
+
+static int use_color;
+
+static void
+grub_ncurses_putchar (grub_uint32_t c)
+{
+  /* Better than nothing.  */
+  switch (c)
+    {
+    case GRUB_TERM_DISP_LEFT:
+      c = '<';
+      break;
+
+    case GRUB_TERM_DISP_UP:
+      c = '^';
+      break;
+
+    case GRUB_TERM_DISP_RIGHT:
+      c = '>';
+      break;
+
+    case GRUB_TERM_DISP_DOWN:
+      c = 'v';
+      break;
+
+    case GRUB_TERM_DISP_HLINE:
+      c = '-';
+      break;
+
+    case GRUB_TERM_DISP_VLINE:
+      c = '|';
+      break;
+
+    case GRUB_TERM_DISP_UL:
+    case GRUB_TERM_DISP_UR:
+    case GRUB_TERM_DISP_LL:
+    case GRUB_TERM_DISP_LR:
+      c = '+';
+      break;
+
+    default:
+      /* ncurses does not support Unicode.  */
+      if (c > 0x7f)
+       c = '?';
+      break;
+    }
+
+  addch (c | grub_console_attr);
+}
+
+static grub_ssize_t
+grub_ncurses_getcharwidth (grub_uint32_t code __attribute__ ((unused)))
+{
+  return 1;
+}
+
+static void
+grub_ncurses_setcolorstate (grub_term_color_state state)
+{
+  switch (state)
+    {
+    case GRUB_TERM_COLOR_STANDARD:
+      grub_console_cur_color = grub_console_standard_color;
+      grub_console_attr = A_NORMAL;
+      break;
+    case GRUB_TERM_COLOR_NORMAL:
+      grub_console_cur_color = grub_console_normal_color;
+      grub_console_attr = A_NORMAL;
+      break;
+    case GRUB_TERM_COLOR_HIGHLIGHT:
+      grub_console_cur_color = grub_console_highlight_color;
+      grub_console_attr = A_STANDOUT;
+      break;
+    default:
+      break;
+    }
+
+  if (use_color)
+    {
+      grub_uint8_t fg, bg;
+
+      fg = (grub_console_cur_color & 7);
+      bg = (grub_console_cur_color >> 4) & 7;
+
+      grub_console_attr = (grub_console_cur_color & 8) ? A_BOLD : A_NORMAL;
+      color_set ((bg << 3) + fg, 0);
+    }
+}
+
+/* XXX: This function is never called.  */
+static void
+grub_ncurses_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
+{
+  grub_console_normal_color = normal_color;
+  grub_console_highlight_color = highlight_color;
+}
+
+static void
+grub_ncurses_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
+{
+  *normal_color = grub_console_normal_color;
+  *highlight_color = grub_console_highlight_color;
+}
+
+static int saved_char = ERR;
+
+static int
+grub_ncurses_checkkey (void)
+{
+  int c;
+
+  /* Check for SAVED_CHAR. This should not be true, because this
+     means checkkey is called twice continuously.  */
+  if (saved_char != ERR)
+    return saved_char;
+
+  wtimeout (stdscr, 100);
+  c = getch ();
+  /* If C is not ERR, then put it back in the input queue.  */
+  if (c != ERR)
+    {
+      saved_char = c;
+      return c;
+    }
+
+  return -1;
+}
+
+static int
+grub_ncurses_getkey (void)
+{
+  int c;
+
+  /* If checkkey has already got a character, then return it.  */
+  if (saved_char != ERR)
+    {
+      c = saved_char;
+      saved_char = ERR;
+    }
+  else
+    {
+      wtimeout (stdscr, -1);
+      c = getch ();
+    }
+
+  switch (c)
+    {
+    case KEY_LEFT:
+      c = 2;
+      break;
+
+    case KEY_RIGHT:
+      c = 6;
+      break;
+
+    case KEY_UP:
+      c = 16;
+      break;
+
+    case KEY_DOWN:
+      c = 14;
+      break;
+
+    case KEY_IC:
+      c = 24;
+      break;
+
+    case KEY_DC:
+      c = 4;
+      break;
+
+    case KEY_BACKSPACE:
+      /* XXX: For some reason ncurses on xterm does not return
+        KEY_BACKSPACE.  */
+    case 127:
+      c = 8;
+      break;
+
+    case KEY_HOME:
+      c = 1;
+      break;
+
+    case KEY_END:
+      c = 5;
+      break;
+
+    case KEY_NPAGE:
+      c = 3;
+      break;
+
+    case KEY_PPAGE:
+      c = 7;
+      break;
+    }
+
+  return c;
+}
+
+static grub_uint16_t
+grub_ncurses_getxy (void)
+{
+  int x;
+  int y;
+
+  getyx (stdscr, y, x);
+
+  return (x << 8) | y;
+}
+
+static grub_uint16_t
+grub_ncurses_getwh (void)
+{
+  int x;
+  int y;
+
+  getmaxyx (stdscr, y, x);
+
+  return (x << 8) | y;
+}
+
+static void
+grub_ncurses_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  move (y, x);
+}
+
+static void
+grub_ncurses_cls (void)
+{
+  clear ();
+  refresh ();
+}
+
+static void
+grub_ncurses_setcursor (int on)
+{
+  curs_set (on ? 1 : 0);
+}
+
+static void
+grub_ncurses_refresh (void)
+{
+  refresh ();
+}
+
+static grub_err_t
+grub_ncurses_init (void)
+{
+  initscr ();
+  raw ();
+  noecho ();
+  scrollok (stdscr, TRUE);
+
+  nonl ();
+  intrflush (stdscr, FALSE);
+  keypad (stdscr, TRUE);
+
+  if (has_colors ())
+    {
+      start_color ();
+
+      if ((COLORS >= NUM_COLORS) && (COLOR_PAIRS >= NUM_COLORS * NUM_COLORS))
+        {
+          int i, j, n;
+
+          n = 0;
+          for (i = 0; i < NUM_COLORS; i++)
+            for (j = 0; j < NUM_COLORS; j++)
+              init_pair(n++, color_map[j], color_map[i]);
+
+          use_color = 1;
+        }
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_ncurses_fini (void)
+{
+  endwin ();
+  return 0;
+}
+
+\f
+static struct grub_term_input grub_ncurses_term_input =
+  {
+    .name = "console",
+    .checkkey = grub_ncurses_checkkey,
+    .getkey = grub_ncurses_getkey,
+  };
+
+static struct grub_term_output grub_ncurses_term_output =
+  {
+    .name = "console",
+    .init = grub_ncurses_init,
+    .fini = grub_ncurses_fini,
+    .putchar = grub_ncurses_putchar,
+    .getcharwidth = grub_ncurses_getcharwidth,
+    .getxy = grub_ncurses_getxy,
+    .getwh = grub_ncurses_getwh,
+    .gotoxy = grub_ncurses_gotoxy,
+    .cls = grub_ncurses_cls,
+    .setcolorstate = grub_ncurses_setcolorstate,
+    .setcolor = grub_ncurses_setcolor,
+    .getcolor = grub_ncurses_getcolor,
+    .setcursor = grub_ncurses_setcursor,
+    .refresh = grub_ncurses_refresh
+  };
+
+void
+grub_console_init (void)
+{
+  grub_term_register_output ("console", &grub_ncurses_term_output);
+  grub_term_register_input ("console", &grub_ncurses_term_input);
+}
+
+void
+grub_console_fini (void)
+{
+  grub_ncurses_fini ();
+}
diff --git a/grub-core/kern/emu/dl.c b/grub-core/kern/emu/dl.c
new file mode 100644 (file)
index 0000000..4266376
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef GRUB_MACHINE_EMU
+#error "This source is only meant for grub-emu platform"
+#endif
+
+#if GRUB_CPU_I386
+#include "../i386/dl.c"
+#elif GRUB_CPU_X86_64
+#include "../x86_64/dl.c"
+#elif GRUB_CPU_SPARC64
+#include "../sparc64/dl.c"
+#elif GRUB_CPU_MIPS
+#include "../mips/dl.c"
+#elif GRUB_CPU_MIPSEL
+#include "../mips/dl.c"
+#elif GRUB_CPU_POWERPC
+#include "../powerpc/dl.c"
+#else
+#error "No target cpu type is defined"
+#endif
diff --git a/grub-core/kern/emu/dummy/dl.c b/grub-core/kern/emu/dummy/dl.c
new file mode 100644 (file)
index 0000000..8e9fabf
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/dl.h>
+
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+  (void) ehdr;
+
+  return GRUB_ERR_BAD_MODULE;
+}
+
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+{
+  (void) mod;
+  (void) ehdr;
+
+  return GRUB_ERR_BAD_MODULE;
+}
+
+/* int */
+/* grub_dl_ref (grub_dl_t mod) */
+/* {  */
+/*   (void) mod; */
+/*   return 0; */
+/* } */
+
+/* int */
+/* grub_dl_unref (grub_dl_t mod) */
+/* {  */
+/*   (void) mod; */
+/*   return 0; */
+/* } */
diff --git a/grub-core/kern/emu/dummy/symlist.c b/grub-core/kern/emu/dummy/symlist.c
new file mode 100644 (file)
index 0000000..d1445a3
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/kernel.h>
+#include <grub/emu/misc.h>
+
+void
+grub_register_exported_symbols (void)
+{
+}
diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c
new file mode 100644 (file)
index 0000000..ba357d8
--- /dev/null
@@ -0,0 +1,646 @@
+/* getroot.c - Get root device */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <dirent.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#ifdef __CYGWIN__
+# include <sys/fcntl.h>
+# include <sys/cygwin.h>
+# include <limits.h>
+# define DEV_CYGDRIVE_MAJOR 98
+#endif
+
+#ifdef __GNU__
+#include <hurd.h>
+#include <hurd/lookup.h>
+#include <hurd/fs.h>
+#endif
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/emu/misc.h>
+#include <grub/emu/hostdisk.h>
+#include <grub/emu/getroot.h>
+
+static void
+strip_extra_slashes (char *dir)
+{
+  char *p = dir;
+
+  while ((p = strchr (p, '/')) != 0)
+    {
+      if (p[1] == '/')
+       {
+         memmove (p, p + 1, strlen (p));
+         continue;
+       }
+      else if (p[1] == '\0')
+       {
+         if (p > dir)
+           p[0] = '\0';
+         break;
+       }
+
+      p++;
+    }
+}
+
+static char *
+xgetcwd (void)
+{
+  size_t size = 10;
+  char *path;
+
+  path = xmalloc (size);
+  while (! getcwd (path, size))
+    {
+      size <<= 1;
+      path = xrealloc (path, size);
+    }
+
+  return path;
+}
+
+#ifdef __MINGW32__
+
+static char *
+find_root_device (const char *dir __attribute__ ((unused)),
+                  dev_t dev __attribute__ ((unused)))
+{
+  return 0;
+}
+
+#elif ! defined(__CYGWIN__)
+
+static char *
+find_root_device (const char *dir, dev_t dev)
+{
+  DIR *dp;
+  char *saved_cwd;
+  struct dirent *ent;
+
+  dp = opendir (dir);
+  if (! dp)
+    return 0;
+
+  saved_cwd = xgetcwd ();
+
+  grub_util_info ("changing current directory to %s", dir);
+  if (chdir (dir) < 0)
+    {
+      free (saved_cwd);
+      closedir (dp);
+      return 0;
+    }
+
+  while ((ent = readdir (dp)) != 0)
+    {
+      struct stat st;
+
+      /* Avoid:
+        - dotfiles (like "/dev/.tmp.md0") since they could be duplicates.
+        - dotdirs (like "/dev/.static") since they could contain duplicates.  */
+      if (ent->d_name[0] == '.')
+       continue;
+
+      if (lstat (ent->d_name, &st) < 0)
+       /* Ignore any error.  */
+       continue;
+
+      if (S_ISLNK (st.st_mode))
+       /* Don't follow symbolic links.  */
+       continue;
+
+      if (S_ISDIR (st.st_mode))
+       {
+         /* Find it recursively.  */
+         char *res;
+
+         res = find_root_device (ent->d_name, dev);
+
+         if (res)
+           {
+             if (chdir (saved_cwd) < 0)
+               grub_util_error ("cannot restore the original directory");
+
+             free (saved_cwd);
+             closedir (dp);
+             return res;
+           }
+       }
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
+      if (S_ISCHR (st.st_mode) && st.st_rdev == dev)
+#else
+      if (S_ISBLK (st.st_mode) && st.st_rdev == dev)
+#endif
+       {
+#ifdef __linux__
+         /* Skip device names like /dev/dm-0, which are short-hand aliases
+            to more descriptive device names, e.g. those under /dev/mapper */
+         if (ent->d_name[0] == 'd' &&
+             ent->d_name[1] == 'm' &&
+             ent->d_name[2] == '-' &&
+             ent->d_name[3] >= '0' &&
+             ent->d_name[3] <= '9')
+           continue;
+#endif
+
+         /* Found!  */
+         char *res;
+         char *cwd;
+#if defined(__NetBSD__)
+         /* Convert this block device to its character (raw) device.  */
+         const char *template = "%s/r%s";
+#else
+         /* Keep the device name as it is.  */
+         const char *template = "%s/%s";
+#endif
+
+         cwd = xgetcwd ();
+         res = xmalloc (strlen (cwd) + strlen (ent->d_name) + 3);
+         sprintf (res, template, cwd, ent->d_name);
+         strip_extra_slashes (res);
+         free (cwd);
+
+         /* /dev/root is not a real block device keep looking, takes care
+            of situation where root filesystem is on the same partition as
+            grub files */
+
+         if (strcmp(res, "/dev/root") == 0)
+               continue;
+
+         if (chdir (saved_cwd) < 0)
+           grub_util_error ("cannot restore the original directory");
+
+         free (saved_cwd);
+         closedir (dp);
+         return res;
+       }
+    }
+
+  if (chdir (saved_cwd) < 0)
+    grub_util_error ("cannot restore the original directory");
+
+  free (saved_cwd);
+  closedir (dp);
+  return 0;
+}
+
+#else /* __CYGWIN__ */
+
+/* Read drive/partition serial number from mbr/boot sector,
+   return 0 on read error, ~0 on unknown serial.  */
+static unsigned
+get_bootsec_serial (const char *os_dev, int mbr)
+{
+  /* Read boot sector.  */
+  int fd = open (os_dev, O_RDONLY);
+  if (fd < 0)
+    return 0;
+  unsigned char buf[0x200];
+  int n = read (fd, buf, sizeof (buf));
+  close (fd);
+  if (n != sizeof(buf))
+    return 0;
+
+  /* Check signature.  */
+  if (!(buf[0x1fe] == 0x55 && buf[0x1ff] == 0xaa))
+    return ~0;
+
+  /* Serial number offset depends on boot sector type.  */
+  if (mbr)
+    n = 0x1b8;
+  else if (memcmp (buf + 0x03, "NTFS", 4) == 0)
+    n = 0x048;
+  else if (memcmp (buf + 0x52, "FAT32", 5) == 0)
+    n = 0x043;
+  else if (memcmp (buf + 0x36, "FAT", 3) == 0)
+    n = 0x027;
+  else
+    return ~0;
+
+  unsigned serial = *(unsigned *)(buf + n);
+  if (serial == 0)
+    return ~0;
+  return serial;
+}
+
+static char *
+find_cygwin_root_device (const char *path, dev_t dev)
+{
+  /* No root device for /cygdrive.  */
+  if (dev == (DEV_CYGDRIVE_MAJOR << 16))
+    return 0;
+
+  /* Convert to full POSIX and Win32 path.  */
+  char fullpath[PATH_MAX], winpath[PATH_MAX];
+  cygwin_conv_to_full_posix_path (path, fullpath);
+  cygwin_conv_to_full_win32_path (fullpath, winpath);
+
+  /* If identical, this is no real filesystem path.  */
+  if (strcmp (fullpath, winpath) == 0)
+    return 0;
+
+  /* Check for floppy drive letter.  */
+  if (winpath[0] && winpath[1] == ':' && strchr ("AaBb", winpath[0]))
+    return xstrdup (strchr ("Aa", winpath[0]) ? "/dev/fd0" : "/dev/fd1");
+
+  /* Cygwin returns the partition serial number in stat.st_dev.
+     This is never identical to the device number of the emulated
+     /dev/sdXN device, so above find_root_device () does not work.
+     Search the partition with the same serial in boot sector instead.  */
+  char devpath[sizeof ("/dev/sda15") + 13]; /* Size + Paranoia.  */
+  int d;
+  for (d = 'a'; d <= 'z'; d++)
+    {
+      sprintf (devpath, "/dev/sd%c", d);
+      if (get_bootsec_serial (devpath, 1) == 0)
+       continue;
+      int p;
+      for (p = 1; p <= 15; p++)
+       {
+         sprintf (devpath, "/dev/sd%c%d", d, p);
+         unsigned ser = get_bootsec_serial (devpath, 0);
+         if (ser == 0)
+           break;
+         if (ser != (unsigned)~0 && dev == (dev_t)ser)
+           return xstrdup (devpath);
+       }
+    }
+  return 0;
+}
+
+#endif /* __CYGWIN__ */
+
+char *
+grub_guess_root_device (const char *dir)
+{
+  char *os_dev;
+#ifdef __GNU__
+  file_t file;
+  mach_port_t *ports;
+  int *ints;
+  loff_t *offsets;
+  char *data;
+  error_t err;
+  mach_msg_type_number_t num_ports = 0, num_ints = 0, num_offsets = 0, data_len = 0;
+  size_t name_len;
+
+  file = file_name_lookup (dir, 0, 0);
+  if (file == MACH_PORT_NULL)
+    return 0;
+
+  err = file_get_storage_info (file,
+                              &ports, &num_ports,
+                              &ints, &num_ints,
+                              &offsets, &num_offsets,
+                              &data, &data_len);
+
+  if (num_ints < 1)
+    grub_util_error ("Storage info for `%s' does not include type", dir);
+  if (ints[0] != STORAGE_DEVICE)
+    grub_util_error ("Filesystem of `%s' is not stored on local disk", dir);
+
+  if (num_ints < 5)
+    grub_util_error ("Storage info for `%s' does not include name", dir);
+  name_len = ints[4];
+  if (name_len < data_len)
+    grub_util_error ("Bogus name length for storage info for `%s'", dir);
+  if (data[name_len - 1] != '\0')
+    grub_util_error ("Storage name for `%s' not NUL-terminated", dir);
+
+  os_dev = xmalloc (strlen ("/dev/") + data_len);
+  memcpy (os_dev, "/dev/", strlen ("/dev/"));
+  memcpy (os_dev + strlen ("/dev/"), data, data_len);
+
+  if (ports && num_ports > 0)
+    {
+      mach_msg_type_number_t i;
+      for (i = 0; i < num_ports; i++)
+        {
+         mach_port_t port = ports[i];
+         if (port != MACH_PORT_NULL)
+           mach_port_deallocate (mach_task_self(), port);
+        }
+      munmap ((caddr_t) ports, num_ports * sizeof (*ports));
+    }
+
+  if (ints && num_ints > 0)
+    munmap ((caddr_t) ints, num_ints * sizeof (*ints));
+  if (offsets && num_offsets > 0)
+    munmap ((caddr_t) offsets, num_offsets * sizeof (*offsets));
+  if (data && data_len > 0)
+    munmap (data, data_len);
+  mach_port_deallocate (mach_task_self (), file);
+#else /* !__GNU__ */
+  struct stat st;
+
+  if (stat (dir, &st) < 0)
+    grub_util_error ("cannot stat `%s'", dir);
+
+#ifdef __CYGWIN__
+  /* Cygwin specific function.  */
+  os_dev = find_cygwin_root_device (dir, st.st_dev);
+
+#else
+
+  /* This might be truly slow, but is there any better way?  */
+  os_dev = find_root_device ("/dev", st.st_dev);
+#endif
+#endif /* !__GNU__ */
+
+  return os_dev;
+}
+
+static int
+grub_util_is_dmraid (const char *os_dev)
+{
+  if (! strncmp (os_dev, "/dev/mapper/nvidia_", 19))
+    return 1;
+  else if (! strncmp (os_dev, "/dev/mapper/isw_", 16))
+    return 1;
+  else if (! strncmp (os_dev, "/dev/mapper/hpt37x_", 19))
+    return 1;
+  else if (! strncmp (os_dev, "/dev/mapper/hpt45x_", 19))
+    return 1;
+  else if (! strncmp (os_dev, "/dev/mapper/via_", 16))
+    return 1;
+  else if (! strncmp (os_dev, "/dev/mapper/lsi_", 16))
+    return 1;
+  else if (! strncmp (os_dev, "/dev/mapper/pdc_", 16))
+    return 1;
+  else if (! strncmp (os_dev, "/dev/mapper/jmicron_", 20))
+    return 1;
+  else if (! strncmp (os_dev, "/dev/mapper/asr_", 16))
+    return 1;
+  else if (! strncmp (os_dev, "/dev/mapper/sil_", 16))
+    return 1;
+
+  return 0;
+}
+
+int
+grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused)))
+{
+#ifdef __linux__
+  /* Check for LVM.  */
+  if (!strncmp (os_dev, "/dev/mapper/", 12)
+      && ! grub_util_is_dmraid (os_dev)
+      && strncmp (os_dev, "/dev/mapper/mpath", 17) != 0)
+    return GRUB_DEV_ABSTRACTION_LVM;
+
+  /* Check for RAID.  */
+  if (!strncmp (os_dev, "/dev/md", 7))
+    return GRUB_DEV_ABSTRACTION_RAID;
+#endif
+
+  /* No abstraction found.  */
+  return GRUB_DEV_ABSTRACTION_NONE;
+}
+
+char *
+grub_util_get_grub_dev (const char *os_dev)
+{
+  char *grub_dev;
+
+  switch (grub_util_get_dev_abstraction (os_dev))
+    {
+    case GRUB_DEV_ABSTRACTION_LVM:
+
+      {
+       unsigned short i, len;
+       grub_size_t offset = sizeof ("/dev/mapper/") - 1;
+
+       len = strlen (os_dev) - offset + 1;
+       grub_dev = xmalloc (len);
+
+       for (i = 0; i < len; i++, offset++)
+         {
+           grub_dev[i] = os_dev[offset];
+           if (os_dev[offset] == '-' && os_dev[offset + 1] == '-')
+             offset++;
+         }
+      }
+
+      break;
+
+    case GRUB_DEV_ABSTRACTION_RAID:
+
+      if (os_dev[7] == '_' && os_dev[8] == 'd')
+       {
+         /* This a partitionable RAID device of the form /dev/md_dNNpMM. */
+
+         char *p, *q;
+
+         p = strdup (os_dev + sizeof ("/dev/md_d") - 1);
+
+         q = strchr (p, 'p');
+         if (q)
+           *q = ',';
+
+         grub_dev = xasprintf ("md%s", p);
+         free (p);
+       }
+      else if (os_dev[7] == '/' && os_dev[8] == 'd')
+       {
+         /* This a partitionable RAID device of the form /dev/md/dNNpMM. */
+
+         char *p, *q;
+
+         p = strdup (os_dev + sizeof ("/dev/md/d") - 1);
+
+         q = strchr (p, 'p');
+         if (q)
+           *q = ',';
+
+         grub_dev = xasprintf ("md%s", p);
+         free (p);
+       }
+      else if (os_dev[7] >= '0' && os_dev[7] <= '9')
+       {
+         char *p , *q;
+
+         p = strdup (os_dev + sizeof ("/dev/md") - 1);
+
+         q = strchr (p, 'p');
+         if (q)
+           *q = ',';
+
+         grub_dev = xasprintf ("md%s", p);
+         free (p);
+       }
+      else if (os_dev[7] == '/' && os_dev[8] >= '0' && os_dev[8] <= '9')
+       {
+         char *p , *q;
+
+         p = strdup (os_dev + sizeof ("/dev/md/") - 1);
+
+         q = strchr (p, 'p');
+         if (q)
+           *q = ',';
+
+         grub_dev = xasprintf ("md%s", p);
+         free (p);
+       }
+      else
+       grub_util_error ("unknown kind of RAID device `%s'", os_dev);
+
+      break;
+
+    default:  /* GRUB_DEV_ABSTRACTION_NONE */
+      grub_dev = grub_util_biosdisk_get_grub_dev (os_dev);
+    }
+
+  return grub_dev;
+}
+
+const char *
+grub_util_check_block_device (const char *blk_dev)
+{
+  struct stat st;
+
+  if (stat (blk_dev, &st) < 0)
+    grub_util_error ("cannot stat `%s'", blk_dev);
+
+  if (S_ISBLK (st.st_mode))
+    return (blk_dev);
+  else
+    return 0;
+}
+
+const char *
+grub_util_check_char_device (const char *blk_dev)
+{
+  struct stat st;
+
+  if (stat (blk_dev, &st) < 0)
+    grub_util_error ("cannot stat `%s'", blk_dev);
+
+  if (S_ISCHR (st.st_mode))
+    return (blk_dev);
+  else
+    return 0;
+}
+
+/* This function never prints trailing slashes (so that its output
+   can be appended a slash unconditionally).  */
+char *
+grub_make_system_path_relative_to_its_root (const char *path)
+{
+  struct stat st;
+  char *p, *buf, *buf2, *buf3;
+  uintptr_t offset = 0;
+  dev_t num;
+  size_t len;
+
+  /* canonicalize.  */
+  p = canonicalize_file_name (path);
+
+  if (p == NULL)
+    grub_util_error ("failed to get canonical path of %s", path);
+
+  len = strlen (p) + 1;
+  buf = xstrdup (p);
+  free (p);
+
+  if (stat (buf, &st) < 0)
+    grub_util_error ("cannot stat %s: %s", buf, strerror (errno));
+
+  buf2 = xstrdup (buf);
+  num = st.st_dev;
+
+  /* This loop sets offset to the number of chars of the root
+     directory we're inspecting.  */
+  while (1)
+    {
+      p = strrchr (buf, '/');
+      if (p == NULL)
+       /* This should never happen.  */
+       grub_util_error ("FIXME: no / in buf. (make_system_path_relative_to_its_root)");
+      if (p != buf)
+       *p = 0;
+      else
+       *++p = 0;
+
+      if (stat (buf, &st) < 0)
+       grub_util_error ("cannot stat %s: %s", buf, strerror (errno));
+
+      /* buf is another filesystem; we found it.  */
+      if (st.st_dev != num)
+       {
+         /* offset == 0 means path given is the mount point.
+            This works around special-casing of "/" in Un*x.  This function never
+            prints trailing slashes (so that its output can be appended a slash
+            unconditionally).  Each slash in is considered a preceding slash, and
+            therefore the root directory is an empty string.  */
+         if (offset == 0)
+           {
+             free (buf);
+             free (buf2);
+             return xstrdup ("");
+           }
+         else
+           break;
+       }
+
+      offset = p - buf;
+      /* offset == 1 means root directory.  */
+      if (offset == 1)
+       {
+         /* Include leading slash.  */
+         offset = 0;
+         break;
+       }
+    }
+  free (buf);
+  buf3 = xstrdup (buf2 + offset);
+  free (buf2);
+
+#ifdef __CYGWIN__
+  if (st.st_dev != (DEV_CYGDRIVE_MAJOR << 16))
+    {
+      /* Reached some mount point not below /cygdrive.
+        GRUB does not know Cygwin's emulated mounts,
+        convert to Win32 path.  */
+      grub_util_info ("Cygwin path = %s\n", buf3);
+      char * temp = get_win32_path (buf3);
+      free (buf3);
+      buf3 = temp;
+    }
+#endif
+
+  /* Remove trailing slashes, return empty string if root directory.  */
+  len = strlen (buf3);
+  while (len > 0 && buf3[len - 1] == '/')
+    {
+      buf3[len - 1] = '\0';
+      len--;
+    }
+
+  return buf3;
+}
diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c
new file mode 100644 (file)
index 0000000..983f101
--- /dev/null
@@ -0,0 +1,1360 @@
+/* hostdisk.c - emulate biosdisk */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/msdos_partition.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/emu/misc.h>
+#include <grub/emu/hostdisk.h>
+#include <grub/misc.h>
+#include <grub/i18n.h>
+#include <grub/list.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+
+#ifdef __linux__
+# include <sys/ioctl.h>         /* ioctl */
+# if !defined(__GLIBC__) || \
+        ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))
+/* Maybe libc doesn't have large file support.  */
+#  include <linux/unistd.h>     /* _llseek */
+# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */
+# ifndef BLKFLSBUF
+#  define BLKFLSBUF     _IO (0x12,97)   /* flush buffer cache */
+# endif /* ! BLKFLSBUF */
+# include <sys/ioctl.h>                /* ioctl */
+# ifndef HDIO_GETGEO
+#  define HDIO_GETGEO  0x0301  /* get device geometry */
+/* If HDIO_GETGEO is not defined, it is unlikely that hd_geometry is
+   defined.  */
+struct hd_geometry
+{
+  unsigned char heads;
+  unsigned char sectors;
+  unsigned short cylinders;
+  unsigned long start;
+};
+# endif /* ! HDIO_GETGEO */
+# ifndef BLKGETSIZE64
+#  define BLKGETSIZE64  _IOR(0x12,114,size_t)    /* return device size */
+# endif /* ! BLKGETSIZE64 */
+# ifndef MAJOR
+#  ifndef MINORBITS
+#   define MINORBITS   8
+#  endif /* ! MINORBITS */
+#  define MAJOR(dev)   ((unsigned) ((dev) >> MINORBITS))
+# endif /* ! MAJOR */
+# ifndef FLOPPY_MAJOR
+#  define FLOPPY_MAJOR 2
+# endif /* ! FLOPPY_MAJOR */
+# ifndef LOOP_MAJOR
+#  define LOOP_MAJOR   7
+# endif /* ! LOOP_MAJOR */
+#endif /* __linux__ */
+
+#ifdef __CYGWIN__
+# include <sys/ioctl.h>
+# include <cygwin/fs.h> /* BLKGETSIZE64 */
+# include <cygwin/hdreg.h> /* HDIO_GETGEO */
+# define MAJOR(dev)    ((unsigned) ((dev) >> 16))
+# define FLOPPY_MAJOR  2
+#endif
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+# include <sys/disk.h> /* DIOCGMEDIASIZE */
+# include <sys/param.h>
+# include <sys/sysctl.h>
+#endif
+
+#if defined(__APPLE__)
+# include <sys/disk.h>
+#endif
+
+#if defined(__NetBSD__)
+# include <sys/ioctl.h>
+# include <sys/disklabel.h>    /* struct disklabel */
+# ifdef HAVE_GETRAWPARTITION
+#  include <util.h>    /* getrawpartition */
+# endif /* HAVE_GETRAWPARTITION */
+# include <sys/fdio.h>
+# ifndef RAW_FLOPPY_MAJOR
+#  define RAW_FLOPPY_MAJOR     9
+# endif /* ! RAW_FLOPPY_MAJOR */
+#endif /* defined(__NetBSD__) */
+
+struct
+{
+  char *drive;
+  char *device;
+} map[256];
+
+struct grub_util_biosdisk_data
+{
+  char *dev;
+  int access_mode;
+  int fd;
+};
+
+#ifdef __linux__
+/* Check if we have devfs support.  */
+static int
+have_devfs (void)
+{
+  static int dev_devfsd_exists = -1;
+
+  if (dev_devfsd_exists < 0)
+    {
+      struct stat st;
+
+      dev_devfsd_exists = stat ("/dev/.devfsd", &st) == 0;
+    }
+
+  return dev_devfsd_exists;
+}
+#endif /* __linux__ */
+
+#if defined(__NetBSD__)
+/* Adjust device driver parameters.  This function should be called just
+   after successfully opening the device.  For now, it simply prevents the
+   floppy driver from retrying operations on failure, as otherwise the
+   driver takes a while to abort when there is no floppy in the drive.  */
+static void
+configure_device_driver (int fd)
+{
+  struct stat st;
+
+  if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode))
+    return;
+  if (major(st.st_rdev) == RAW_FLOPPY_MAJOR)
+    {
+      int floppy_opts;
+
+      if (ioctl (fd, FDIOCGETOPTS, &floppy_opts) == -1)
+       return;
+      floppy_opts |= FDOPT_NORETRY;
+      if (ioctl (fd, FDIOCSETOPTS, &floppy_opts) == -1)
+       return;
+    }
+}
+#endif /* defined(__NetBSD__) */
+
+static int
+find_grub_drive (const char *name)
+{
+  unsigned int i;
+
+  if (name)
+    {
+      for (i = 0; i < ARRAY_SIZE (map); i++)
+       if (map[i].drive && ! strcmp (map[i].drive, name))
+         return i;
+    }
+
+  return -1;
+}
+
+static int
+find_free_slot (void)
+{
+  unsigned int i;
+
+  for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
+    if (! map[i].drive)
+      return i;
+
+  return -1;
+}
+
+static int
+grub_util_biosdisk_iterate (int (*hook) (const char *name))
+{
+  unsigned i;
+
+  for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
+    if (map[i].drive && hook (map[i].drive))
+      return 1;
+
+  return 0;
+}
+
+static grub_err_t
+grub_util_biosdisk_open (const char *name, grub_disk_t disk)
+{
+  int drive;
+  struct stat st;
+  struct grub_util_biosdisk_data *data;
+
+  drive = find_grub_drive (name);
+  if (drive < 0)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                      "no mapping exists for `%s'", name);
+
+  disk->has_partitions = 1;
+  disk->id = drive;
+  disk->data = data = xmalloc (sizeof (struct grub_util_biosdisk_data));
+  data->dev = NULL;
+  data->access_mode = 0;
+  data->fd = -1;
+
+  /* Get the size.  */
+#if defined(__MINGW32__)
+  {
+    grub_uint64_t size;
+
+    size = grub_util_get_disk_size (map[drive].device);
+
+    if (size % 512)
+      grub_util_error ("unaligned device size");
+
+    disk->total_sectors = size >> 9;
+
+    grub_util_info ("the size of %s is %llu", name, disk->total_sectors);
+
+    return GRUB_ERR_NONE;
+  }
+#elif defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \
+      defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__)
+  {
+# if defined(__NetBSD__)
+    struct disklabel label;
+# else
+    unsigned long long nr;
+# endif
+    int fd;
+
+    fd = open (map[drive].device, O_RDONLY);
+    if (fd == -1)
+      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot open `%s' while attempting to get disk size", map[drive].device);
+
+# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__)
+    if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode))
+# else
+    if (fstat (fd, &st) < 0 || ! S_ISBLK (st.st_mode))
+# endif
+      {
+       close (fd);
+       goto fail;
+      }
+
+# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+    if (ioctl (fd, DIOCGMEDIASIZE, &nr))
+# elif defined(__APPLE__)
+    if (ioctl (fd, DKIOCGETBLOCKCOUNT, &nr))
+# elif defined(__NetBSD__)
+    configure_device_driver (fd);
+    if (ioctl (fd, DIOCGDINFO, &label) == -1)
+# else
+    if (ioctl (fd, BLKGETSIZE64, &nr))
+# endif
+      {
+       close (fd);
+       goto fail;
+      }
+
+    close (fd);
+
+# if defined (__APPLE__)
+    disk->total_sectors = nr;
+# elif defined(__NetBSD__)
+    disk->total_sectors = label.d_secperunit;
+# else
+    disk->total_sectors = nr / 512;
+
+    if (nr % 512)
+      grub_util_error ("unaligned device size");
+# endif
+
+    grub_util_info ("the size of %s is %llu", name, disk->total_sectors);
+
+    return GRUB_ERR_NONE;
+  }
+
+ fail:
+  /* In GNU/Hurd, stat() will return the right size.  */
+#elif !defined (__GNU__)
+# warning "No special routine to get the size of a block device is implemented for your OS. This is not possibly fatal."
+#endif
+  if (stat (map[drive].device, &st) < 0)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot stat `%s'", map[drive].device);
+
+  disk->total_sectors = st.st_size >> GRUB_DISK_SECTOR_BITS;
+
+  grub_util_info ("the size of %s is %lu", name, disk->total_sectors);
+
+  return GRUB_ERR_NONE;
+}
+
+#ifdef __linux__
+/* Cache of partition start sectors for each disk.  */
+struct linux_partition_cache
+{
+  struct linux_partition_cache *next;
+  char *dev;
+  unsigned long start;
+  int partno;
+};
+
+struct linux_partition_cache *linux_partition_cache_list;
+
+static int
+linux_find_partition (char *dev, unsigned long sector)
+{
+  size_t len = strlen (dev);
+  const char *format;
+  char *p;
+  int i;
+  char real_dev[PATH_MAX];
+  struct linux_partition_cache *cache;
+
+  strcpy(real_dev, dev);
+
+  if (have_devfs () && strcmp (real_dev + len - 5, "/disc") == 0)
+    {
+      p = real_dev + len - 4;
+      format = "part%d";
+    }
+  else if (real_dev[len - 1] >= '0' && real_dev[len - 1] <= '9')
+    {
+      p = real_dev + len;
+      format = "p%d";
+    }
+  else
+    {
+      p = real_dev + len;
+      format = "%d";
+    }
+
+  for (cache = linux_partition_cache_list; cache; cache = cache->next)
+    {
+      if (strcmp (cache->dev, dev) == 0 && cache->start == sector)
+       {
+         sprintf (p, format, cache->partno);
+         strcpy (dev, real_dev);
+         return 1;
+       }
+    }
+
+  for (i = 1; i < 10000; i++)
+    {
+      int fd;
+      struct hd_geometry hdg;
+
+      sprintf (p, format, i);
+      fd = open (real_dev, O_RDONLY);
+      if (fd == -1)
+       return 0;
+
+      if (ioctl (fd, HDIO_GETGEO, &hdg))
+       {
+         close (fd);
+         return 0;
+       }
+
+      close (fd);
+
+      if (hdg.start == sector)
+       {
+         struct linux_partition_cache *new_cache_item;
+
+         new_cache_item = xmalloc (sizeof *new_cache_item);
+         new_cache_item->dev = xstrdup (dev);
+         new_cache_item->start = hdg.start;
+         new_cache_item->partno = i;
+         grub_list_push (GRUB_AS_LIST_P (&linux_partition_cache_list),
+                         GRUB_AS_LIST (new_cache_item));
+
+         strcpy (dev, real_dev);
+         return 1;
+       }
+    }
+
+  return 0;
+}
+#endif /* __linux__ */
+
+static int
+open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags)
+{
+  int fd;
+  struct grub_util_biosdisk_data *data = disk->data;
+
+#ifdef O_LARGEFILE
+  flags |= O_LARGEFILE;
+#endif
+#ifdef O_SYNC
+  flags |= O_SYNC;
+#endif
+#ifdef O_FSYNC
+  flags |= O_FSYNC;
+#endif
+#ifdef O_BINARY
+  flags |= O_BINARY;
+#endif
+
+#ifdef __linux__
+  /* Linux has a bug that the disk cache for a whole disk is not consistent
+     with the one for a partition of the disk.  */
+  {
+    int is_partition = 0;
+    char dev[PATH_MAX];
+    grub_disk_addr_t part_start = 0;
+
+    part_start = grub_partition_get_start (disk->partition);
+
+    strcpy (dev, map[disk->id].device);
+    if (disk->partition && sector >= part_start
+       && strncmp (map[disk->id].device, "/dev/", 5) == 0)
+      is_partition = linux_find_partition (dev, part_start);
+
+    if (data->dev && strcmp (data->dev, dev) == 0 &&
+       data->access_mode == (flags & O_ACCMODE))
+      {
+       grub_dprintf ("hostdisk", "reusing open device `%s'\n", dev);
+       fd = data->fd;
+      }
+    else
+      {
+       free (data->dev);
+       if (data->fd != -1)
+         close (data->fd);
+
+       /* Open the partition.  */
+       grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev);
+       fd = open (dev, flags);
+       if (fd < 0)
+         {
+           grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s'", dev);
+           return -1;
+         }
+
+       /* Flush the buffer cache to the physical disk.
+          XXX: This also empties the buffer cache.  */
+       ioctl (fd, BLKFLSBUF, 0);
+
+       data->dev = xstrdup (dev);
+       data->access_mode = (flags & O_ACCMODE);
+       data->fd = fd;
+      }
+
+    if (is_partition)
+      sector -= part_start;
+  }
+#else /* ! __linux__ */
+#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
+  int sysctl_flags, sysctl_oldflags;
+  size_t sysctl_size = sizeof (sysctl_flags);
+
+  if (sysctlbyname ("kern.geom.debugflags", &sysctl_oldflags, &sysctl_size, NULL, 0))
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "cannot get current flags of sysctl kern.geom.debugflags");
+      return -1;
+    }
+  sysctl_flags = sysctl_oldflags | 0x10;
+  if (! (sysctl_oldflags & 0x10)
+      && sysctlbyname ("kern.geom.debugflags", NULL , 0, &sysctl_flags, sysctl_size))
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "cannot set flags of sysctl kern.geom.debugflags");
+      return -1;
+    }
+#endif
+
+  if (data->dev && strcmp (data->dev, map[disk->id].device) == 0 &&
+      data->access_mode == (flags & O_ACCMODE))
+    {
+      grub_dprintf ("hostdisk", "reusing open device `%s'\n", data->dev);
+      fd = data->fd;
+    }
+  else
+    {
+      free (data->dev);
+      if (data->fd != -1)
+       close (data->fd);
+
+      fd = open (map[disk->id].device, flags);
+      if (fd >= 0)
+       {
+         data->dev = xstrdup (map[disk->id].device);
+         data->access_mode = (flags & O_ACCMODE);
+         data->fd = fd;
+       }
+    }
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+  if (! (sysctl_oldflags & 0x10)
+      && sysctlbyname ("kern.geom.debugflags", NULL , 0, &sysctl_oldflags, sysctl_size))
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "cannot set flags back to the old value for sysctl kern.geom.debugflags");
+      return -1;
+    }
+#endif
+
+#if defined(__APPLE__)
+  /* If we can't have exclusive access, try shared access */
+  if (fd < 0)
+    fd = open(map[disk->id].device, flags | O_SHLOCK);
+#endif
+
+  if (fd < 0)
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' in open_device()", map[disk->id].device);
+      return -1;
+    }
+#endif /* ! __linux__ */
+
+#if defined(__NetBSD__)
+  configure_device_driver (fd);
+#endif /* defined(__NetBSD__) */
+
+#if defined(__linux__) && (!defined(__GLIBC__) || \
+        ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
+  /* Maybe libc doesn't have large file support.  */
+  {
+    loff_t offset, result;
+    static int _llseek (uint filedes, ulong hi, ulong lo,
+                        loff_t *res, uint wh);
+    _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
+               loff_t *, res, uint, wh);
+
+    offset = (loff_t) sector << GRUB_DISK_SECTOR_BITS;
+    if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
+      {
+       grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id].device);
+       close (fd);
+       return -1;
+      }
+  }
+#else
+  {
+    off_t offset = (off_t) sector << GRUB_DISK_SECTOR_BITS;
+
+    if (lseek (fd, offset, SEEK_SET) != offset)
+      {
+       grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id].device);
+       close (fd);
+       return -1;
+      }
+  }
+#endif
+
+  return fd;
+}
+
+/* Read LEN bytes from FD in BUF. Return less than or equal to zero if an
+   error occurs, otherwise return LEN.  */
+static ssize_t
+nread (int fd, char *buf, size_t len)
+{
+  ssize_t size = len;
+
+  while (len)
+    {
+      ssize_t ret = read (fd, buf, len);
+
+      if (ret <= 0)
+        {
+          if (errno == EINTR)
+            continue;
+          else
+            return ret;
+        }
+
+      len -= ret;
+      buf += ret;
+    }
+
+  return size;
+}
+
+/* Write LEN bytes from BUF to FD. Return less than or equal to zero if an
+   error occurs, otherwise return LEN.  */
+static ssize_t
+nwrite (int fd, const char *buf, size_t len)
+{
+  ssize_t size = len;
+
+  while (len)
+    {
+      ssize_t ret = write (fd, buf, len);
+
+      if (ret <= 0)
+        {
+          if (errno == EINTR)
+            continue;
+          else
+            return ret;
+        }
+
+      len -= ret;
+      buf += ret;
+    }
+
+  return size;
+}
+
+static grub_err_t
+grub_util_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
+                        grub_size_t size, char *buf)
+{
+  int fd;
+
+  /* Split pre-partition and partition reads.  */
+  if (disk->partition && sector < disk->partition->start
+      && sector + size > disk->partition->start)
+    {
+      grub_err_t err;
+      err = grub_util_biosdisk_read (disk, sector,
+                                    disk->partition->start - sector,
+                                    buf);
+      if (err)
+       return err;
+
+      return grub_util_biosdisk_read (disk, disk->partition->start,
+                                     size - (disk->partition->start - sector),
+                                     buf + ((disk->partition->start - sector)
+                                            << GRUB_DISK_SECTOR_BITS));
+    }
+
+  fd = open_device (disk, sector, O_RDONLY);
+  if (fd < 0)
+    return grub_errno;
+
+#ifdef __linux__
+  if (sector == 0 && size > 1)
+    {
+      /* Work around a bug in Linux ez remapping.  Linux remaps all
+        sectors that are read together with the MBR in one read.  It
+        should only remap the MBR, so we split the read in two
+        parts. -jochen  */
+      if (nread (fd, buf, GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE)
+       {
+         grub_error (GRUB_ERR_READ_ERROR, "cannot read `%s'", map[disk->id].device);
+         close (fd);
+         return grub_errno;
+       }
+
+      buf += GRUB_DISK_SECTOR_SIZE;
+      size--;
+    }
+#endif /* __linux__ */
+
+  if (nread (fd, buf, size << GRUB_DISK_SECTOR_BITS)
+      != (ssize_t) (size << GRUB_DISK_SECTOR_BITS))
+    grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", map[disk->id].device);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_util_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
+                         grub_size_t size, const char *buf)
+{
+  int fd;
+
+  /* Split pre-partition and partition writes.  */
+  if (disk->partition && sector < disk->partition->start
+      && sector + size > disk->partition->start)
+    {
+      grub_err_t err;
+      err = grub_util_biosdisk_write (disk, sector,
+                                     disk->partition->start - sector,
+                                     buf);
+      if (err)
+       return err;
+
+      return grub_util_biosdisk_write (disk, disk->partition->start,
+                                      size - (disk->partition->start - sector),
+                                      buf + ((disk->partition->start - sector)
+                                             << GRUB_DISK_SECTOR_BITS));
+    }
+
+  fd = open_device (disk, sector, O_WRONLY);
+  if (fd < 0)
+    return grub_errno;
+
+  if (nwrite (fd, buf, size << GRUB_DISK_SECTOR_BITS)
+      != (ssize_t) (size << GRUB_DISK_SECTOR_BITS))
+    grub_error (GRUB_ERR_WRITE_ERROR, "cannot write to `%s'", map[disk->id].device);
+
+  return grub_errno;
+}
+
+static void
+grub_util_biosdisk_close (struct grub_disk *disk)
+{
+  struct grub_util_biosdisk_data *data = disk->data;
+
+  free (data->dev);
+  if (data->fd != -1)
+    close (data->fd);
+  free (data);
+}
+
+static struct grub_disk_dev grub_util_biosdisk_dev =
+  {
+    .name = "biosdisk",
+    .id = GRUB_DISK_DEVICE_BIOSDISK_ID,
+    .iterate = grub_util_biosdisk_iterate,
+    .open = grub_util_biosdisk_open,
+    .close = grub_util_biosdisk_close,
+    .read = grub_util_biosdisk_read,
+    .write = grub_util_biosdisk_write,
+    .next = 0
+  };
+
+static void
+read_device_map (const char *dev_map)
+{
+  FILE *fp;
+  char buf[1024];      /* XXX */
+  int lineno = 0;
+  struct stat st;
+
+  auto void show_error (const char *msg);
+  void show_error (const char *msg)
+    {
+      grub_util_error ("%s:%d: %s", dev_map, lineno, msg);
+    }
+
+  fp = fopen (dev_map, "r");
+  if (! fp)
+    {
+      grub_util_info (_("cannot open `%s'"), dev_map);
+      return;
+    }
+
+  while (fgets (buf, sizeof (buf), fp))
+    {
+      char *p = buf;
+      char *e;
+      int drive;
+
+      lineno++;
+
+      /* Skip leading spaces.  */
+      while (*p && isspace (*p))
+       p++;
+
+      /* If the first character is `#' or NUL, skip this line.  */
+      if (*p == '\0' || *p == '#')
+       continue;
+
+      if (*p != '(')
+       show_error ("No open parenthesis found");
+
+      p++;
+      /* Find a free slot.  */
+      drive = find_free_slot ();
+      if (drive < 0)
+       show_error ("Map table size exceeded");
+
+      e = p;
+      p = strchr (p, ')');
+      if (! p)
+       show_error ("No close parenthesis found");
+
+      map[drive].drive = xmalloc (p - e + sizeof ('\0'));
+      strncpy (map[drive].drive, e, p - e + sizeof ('\0'));
+      map[drive].drive[p - e] = '\0';
+
+      p++;
+      /* Skip leading spaces.  */
+      while (*p && isspace (*p))
+       p++;
+
+      if (*p == '\0')
+       show_error ("No filename found");
+
+      /* NUL-terminate the filename.  */
+      e = p;
+      while (*e && ! isspace (*e))
+       e++;
+      *e = '\0';
+
+#ifdef __MINGW32__
+      (void) st;
+      if (grub_util_get_disk_size (p) == -1LL)
+#else
+      if (stat (p, &st) == -1)
+#endif
+       {
+         free (map[drive].drive);
+         map[drive].drive = NULL;
+         grub_util_info ("Cannot stat `%s', skipping", p);
+         continue;
+       }
+
+#ifdef __linux__
+      /* On Linux, the devfs uses symbolic links horribly, and that
+        confuses the interface very much, so use realpath to expand
+        symbolic links.  */
+      map[drive].device = xmalloc (PATH_MAX);
+      if (! realpath (p, map[drive].device))
+       grub_util_error ("cannot get the real path of `%s'", p);
+#else
+      map[drive].device = xstrdup (p);
+#endif
+    }
+
+  fclose (fp);
+}
+
+void
+grub_util_biosdisk_init (const char *dev_map)
+{
+  read_device_map (dev_map);
+  grub_disk_dev_register (&grub_util_biosdisk_dev);
+}
+
+void
+grub_util_biosdisk_fini (void)
+{
+  unsigned i;
+
+  for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
+    {
+      if (map[i].drive)
+       free (map[i].drive);
+      if (map[i].device)
+       free (map[i].device);
+      map[i].drive = map[i].device = NULL;
+    }
+
+  grub_disk_dev_unregister (&grub_util_biosdisk_dev);
+}
+
+static char *
+make_device_name (int drive, int dos_part, int bsd_part)
+{
+  char *ret;
+  char *dos_part_str = NULL;
+  char *bsd_part_str = NULL;
+
+  if (dos_part >= 0)
+    dos_part_str = xasprintf (",%d", dos_part + 1);
+
+  if (bsd_part >= 0)
+    bsd_part_str = xasprintf (",%d", bsd_part + 1);
+
+  ret = xasprintf ("%s%s%s", map[drive].drive,
+                   dos_part_str ? : "",
+                   bsd_part_str ? : "");
+
+  if (dos_part_str)
+    free (dos_part_str);
+
+  if (bsd_part_str)
+    free (bsd_part_str);
+
+  return ret;
+}
+
+static char *
+convert_system_partition_to_system_disk (const char *os_dev)
+{
+#if defined(__linux__)
+  char *path = xmalloc (PATH_MAX);
+  if (! realpath (os_dev, path))
+    return NULL;
+
+  if (strncmp ("/dev/", path, 5) == 0)
+    {
+      char *p = path + 5;
+
+      /* If this is an IDE disk.  */
+      if (strncmp ("ide/", p, 4) == 0)
+       {
+         p = strstr (p, "part");
+         if (p)
+           strcpy (p, "disc");
+
+         return path;
+       }
+
+      /* If this is a SCSI disk.  */
+      if (strncmp ("scsi/", p, 5) == 0)
+       {
+         p = strstr (p, "part");
+         if (p)
+           strcpy (p, "disc");
+
+         return path;
+       }
+
+      /* If this is a DAC960 disk.  */
+      if (strncmp ("rd/c", p, 4) == 0)
+       {
+         /* /dev/rd/c[0-9]+d[0-9]+(p[0-9]+)? */
+         p = strchr (p, 'p');
+         if (p)
+           *p = '\0';
+
+         return path;
+       }
+
+      /* If this is a Mylex AcceleRAID Array.  */
+      if (strncmp ("rs/c", p, 4) == 0)
+       {
+         /* /dev/rd/c[0-9]+d[0-9]+(p[0-9]+)? */
+         p = strchr (p, 'p');
+         if (p)
+           *p = '\0';
+
+         return path;
+       }
+      /* If this is a CCISS disk.  */
+      if (strncmp ("cciss/c", p, sizeof ("cciss/c") - 1) == 0)
+       {
+         /* /dev/cciss/c[0-9]+d[0-9]+(p[0-9]+)? */
+         p = strchr (p, 'p');
+         if (p)
+           *p = '\0';
+
+         return path;
+       }
+
+      /* If this is a Compaq Intelligent Drive Array.  */
+      if (strncmp ("ida/c", p, sizeof ("ida/c") - 1) == 0)
+       {
+         /* /dev/ida/c[0-9]+d[0-9]+(p[0-9]+)? */
+         p = strchr (p, 'p');
+         if (p)
+           *p = '\0';
+
+         return path;
+       }
+
+      /* If this is an I2O disk.  */
+      if (strncmp ("i2o/hd", p, sizeof ("i2o/hd") - 1) == 0)
+       {
+         /* /dev/i2o/hd[a-z]([0-9]+)? */
+         p[sizeof ("i2o/hda") - 1] = '\0';
+         return path;
+       }
+
+      /* If this is a MultiMediaCard (MMC).  */
+      if (strncmp ("mmcblk", p, sizeof ("mmcblk") - 1) == 0)
+       {
+         /* /dev/mmcblk[0-9]+(p[0-9]+)? */
+         p = strchr (p, 'p');
+         if (p)
+           *p = '\0';
+
+         return path;
+       }
+
+      /* If this is an IDE, SCSI or Virtio disk.  */
+      if (strncmp ("vdisk", p, 5) == 0
+         && p[5] >= 'a' && p[5] <= 'z')
+       {
+         /* /dev/vdisk[a-z][0-9]* */
+         p[6] = '\0';
+         return path;
+       }
+      if ((strncmp ("hd", p, 2) == 0
+          || strncmp ("vd", p, 2) == 0
+          || strncmp ("sd", p, 2) == 0)
+         && p[2] >= 'a' && p[2] <= 'z')
+       {
+         /* /dev/[hsv]d[a-z][0-9]* */
+         p[3] = '\0';
+         return path;
+       }
+
+      /* If this is a Xen virtual block device.  */
+      if ((strncmp ("xvd", p, 3) == 0) && p[3] >= 'a' && p[3] <= 'z')
+       {
+         /* /dev/xvd[a-z][0-9]* */
+         p[4] = '\0';
+         return path;
+       }
+    }
+
+  return path;
+
+#elif defined(__GNU__)
+  char *path = xstrdup (os_dev);
+  if (strncmp ("/dev/sd", path, 7) == 0 || strncmp ("/dev/hd", path, 7) == 0)
+    {
+      char *p = strchr (path + 7, 's');
+      if (p)
+       *p = '\0';
+    }
+  return path;
+
+#elif defined(__CYGWIN__)
+  char *path = xstrdup (os_dev);
+  if (strncmp ("/dev/sd", path, 7) == 0 && 'a' <= path[7] && path[7] <= 'z')
+    path[8] = 0;
+  return path;
+
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
+  char *path = xstrdup (os_dev);
+  if (strncmp ("/dev/", path, 5) == 0)
+    {
+      char *p;
+      for (p = path + 5; *p; ++p)
+        if (grub_isdigit(*p))
+          {
+            p = strchr (p, 's');
+            if (p)
+              *p = '\0';
+            break;
+          }
+    }
+  return path;
+
+#elif defined(__NetBSD__)
+  /* NetBSD uses "/dev/r[wsc]d[0-9]+[a-z]".  */
+  char *path = xstrdup (os_dev);
+  if (strncmp ("/dev/rwd", path, 8) == 0 ||
+      strncmp ("/dev/rsd", path, 8) == 0 ||
+      strncmp ("/dev/rcd", path, 8) == 0)
+    {
+      char *q;
+      q = path + strlen(path) - 1;    /* last character */
+      if (grub_isalpha(*q) && grub_isdigit(*(q-1)))
+        {
+          int rawpart = -1;
+# ifdef HAVE_GETRAWPARTITION
+          rawpart = getrawpartition();
+# endif /* HAVE_GETRAWPARTITION */
+          if (rawpart >= 0)
+            *q = 'a' + rawpart;
+        }
+    }
+  return path;
+
+#else
+# warning "The function `convert_system_partition_to_system_disk' might not work on your OS correctly."
+  return xstrdup (os_dev);
+#endif
+}
+
+#if defined(__linux__) || defined(__CYGWIN__)
+static int
+device_is_wholedisk (const char *os_dev)
+{
+  int len = strlen (os_dev);
+
+  if (os_dev[len - 1] < '0' || os_dev[len - 1] > '9')
+    return 1;
+  return 0;
+}
+#endif
+
+#if defined(__NetBSD__)
+/* Try to determine whether a given device name corresponds to a whole disk.
+   This function should give in most cases a definite answer, but it may
+   actually give an approximate one in the following sense: if the return
+   value is 0 then the device name does not correspond to a whole disk.  */
+static int
+device_is_wholedisk (const char *os_dev)
+{
+  int len = strlen (os_dev);
+  int rawpart = -1;
+
+# ifdef HAVE_GETRAWPARTITION
+  rawpart = getrawpartition();
+# endif /* HAVE_GETRAWPARTITION */
+  if (rawpart < 0)
+    return 1;
+  return (os_dev[len - 1] == ('a' + rawpart));
+}
+#endif /* defined(__NetBSD__) */
+
+static int
+find_system_device (const char *os_dev)
+{
+  unsigned int i;
+  char *os_disk;
+
+  os_disk = convert_system_partition_to_system_disk (os_dev);
+  if (! os_disk)
+    return -1;
+
+  for (i = 0; i < ARRAY_SIZE (map); i++)
+    if (! map[i].device)
+      break;
+    else if (strcmp (map[i].device, os_disk) == 0)
+      {
+       free (os_disk);
+       return i;
+      }
+
+  if (i == ARRAY_SIZE (map))
+    grub_util_error (_("device count exceeds limit"));
+
+  map[i].device = os_disk;
+  map[i].drive = xstrdup (os_disk);
+
+  return i;
+}
+
+char *
+grub_util_biosdisk_get_grub_dev (const char *os_dev)
+{
+  struct stat st;
+  int drive;
+
+  if (stat (os_dev, &st) < 0)
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "cannot stat `%s'", os_dev);
+      return 0;
+    }
+
+  drive = find_system_device (os_dev);
+  if (drive < 0)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                 "no mapping exists for `%s'", os_dev);
+      return 0;
+    }
+
+  if (grub_strcmp (os_dev, convert_system_partition_to_system_disk (os_dev))
+      == 0)
+    return make_device_name (drive, -1, -1);
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__)
+  if (! S_ISCHR (st.st_mode))
+#else
+  if (! S_ISBLK (st.st_mode))
+#endif
+    return make_device_name (drive, -1, -1);
+
+#if defined(__linux__) || defined(__CYGWIN__) || defined(__NetBSD__)
+  /* Linux counts partitions uniformly, whether a BSD partition or a DOS
+     partition, so mapping them to GRUB devices is not trivial.
+     Here, get the start sector of a partition by HDIO_GETGEO, and
+     compare it with each partition GRUB recognizes.
+
+     Cygwin /dev/sdXN emulation uses Windows partition mapping. It
+     does not count the extended partition and missing primary
+     partitions.  Use same method as on Linux here.
+
+     For NetBSD, proceed as for Linux, except that the start sector is
+     obtained from the disk label.  */
+  {
+    char *name;
+    grub_disk_t disk;
+    int fd;
+# if !defined(__NetBSD__)
+    struct hd_geometry hdg;
+    typeof (hdg.start) p_offset;
+# else /* defined(__NetBSD__) */
+    struct disklabel label;
+    int index;
+    u_int32_t p_offset;
+# endif /* !defined(__NetBSD__) */
+    int dos_part = -1;
+    int bsd_part = -1;
+    auto int find_partition (grub_disk_t dsk,
+                            const grub_partition_t partition);
+
+    int find_partition (grub_disk_t dsk __attribute__ ((unused)),
+                       const grub_partition_t partition)
+      {
+       grub_disk_addr_t part_start = 0;
+       grub_util_info ("Partition %d starts from %lu",
+                       partition->number, partition->start);
+
+       part_start = grub_partition_get_start (partition);
+
+       if (p_offset == part_start)
+         {
+           if (partition->parent)
+             {
+               dos_part = partition->parent->number;
+               bsd_part = partition->number;
+             }
+           else
+             {
+               dos_part = partition->number;
+               bsd_part = -1;
+             }
+
+           return 1;
+         }
+
+       return 0;
+      }
+
+    name = make_device_name (drive, -1, -1);
+
+# if !defined(__NetBSD__)
+    if (MAJOR (st.st_rdev) == FLOPPY_MAJOR)
+      return name;
+# else /* defined(__NetBSD__) */
+    /* Since os_dev and convert_system_partition_to_system_disk (os_dev) are
+     * different, we know that os_dev is of the form /dev/r[wsc]d[0-9]+[a-z]
+     * and in particular it cannot be a floppy device.  */
+    index = os_dev[strlen(os_dev) - 1] - 'a';
+# endif /* !defined(__NetBSD__) */
+
+    fd = open (os_dev, O_RDONLY);
+    if (fd == -1)
+      {
+       grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", os_dev);
+       free (name);
+       return 0;
+      }
+
+# if !defined(__NetBSD__)
+    if (ioctl (fd, HDIO_GETGEO, &hdg))
+# else /* defined(__NetBSD__) */
+    configure_device_driver (fd);
+    if (ioctl (fd, DIOCGDINFO, &label) == -1)
+# endif /* !defined(__NetBSD__) */
+      {
+       grub_error (GRUB_ERR_BAD_DEVICE,
+                   "cannot get disk geometry of `%s'", os_dev);
+       close (fd);
+       free (name);
+       return 0;
+      }
+
+    close (fd);
+
+# if !defined(__NetBSD__)
+    p_offset = hdg.start;
+# else /* defined(__NetBSD__) */
+    if (index >= label.d_npartitions)
+      {
+       grub_error (GRUB_ERR_BAD_DEVICE,
+                   "no disk label entry for `%s'", os_dev);
+       free (name);
+       return 0;
+      }
+    p_offset = label.d_partitions[index].p_offset;
+# endif /* !defined(__NetBSD__) */
+
+    grub_util_info ("%s starts from %lu", os_dev, p_offset);
+
+    if (p_offset == 0 && device_is_wholedisk (os_dev))
+      return name;
+
+    grub_util_info ("opening the device %s", name);
+    disk = grub_disk_open (name);
+    free (name);
+
+    if (! disk)
+      return 0;
+
+    grub_partition_iterate (disk, find_partition);
+    if (grub_errno != GRUB_ERR_NONE)
+      {
+       grub_disk_close (disk);
+       return 0;
+      }
+
+    if (dos_part < 0)
+      {
+       grub_disk_close (disk);
+       grub_error (GRUB_ERR_BAD_DEVICE,
+                   "cannot find the partition of `%s'", os_dev);
+       return 0;
+      }
+
+    return make_device_name (drive, dos_part, bsd_part);
+  }
+
+#elif defined(__GNU__)
+  /* GNU uses "/dev/[hs]d[0-9]+(s[0-9]+[a-z]?)?".  */
+  {
+    char *p;
+    int dos_part = -1;
+    int bsd_part = -1;
+
+    p = strrchr (os_dev, 's');
+    if (p)
+      {
+       long int n;
+       char *q;
+
+       p++;
+       n = strtol (p, &q, 10);
+       if (p != q && n != GRUB_LONG_MIN && n != GRUB_LONG_MAX)
+         {
+           dos_part = (int) n - 1;
+
+           if (*q >= 'a' && *q <= 'g')
+             bsd_part = *q - 'a';
+         }
+      }
+
+    return make_device_name (drive, dos_part, bsd_part);
+  }
+
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
+  /* FreeBSD uses "/dev/[a-z]+[0-9]+(s[0-9]+[a-z]?)?".  */
+  {
+    int dos_part = -1;
+    int bsd_part = -1;
+
+    if (strncmp ("/dev/", os_dev, 5) == 0)
+      {
+        const char *p;
+        char *q;
+        long int n;
+
+        for (p = os_dev + 5; *p; ++p)
+          if (grub_isdigit(*p))
+            {
+              p = strchr (p, 's');
+              if (p)
+                {
+                  p++;
+                  n = strtol (p, &q, 10);
+                  if (p != q && n != GRUB_LONG_MIN && n != GRUB_LONG_MAX)
+                    {
+                      dos_part = (int) n - 1;
+
+                      if (*q >= 'a' && *q <= 'g')
+                        bsd_part = *q - 'a';
+                    }
+                }
+              break;
+            }
+      }
+
+    return make_device_name (drive, dos_part, bsd_part);
+  }
+
+#else
+# warning "The function `grub_util_biosdisk_get_grub_dev' might not work on your OS correctly."
+  return make_device_name (drive, -1, -1);
+#endif
+}
+
+const char *
+grub_util_biosdisk_get_osdev (grub_disk_t disk)
+{
+  return map[disk->id].device;
+}
diff --git a/grub-core/kern/emu/hostfs.c b/grub-core/kern/emu/hostfs.c
new file mode 100644 (file)
index 0000000..501ad46
--- /dev/null
@@ -0,0 +1,175 @@
+/* hostfs.c - Dummy filesystem to provide access to the hosts filesystem  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#define _BSD_SOURCE
+#include <grub/fs.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/dl.h>
+#include <grub/util/misc.h>
+
+#include <dirent.h>
+#include <stdio.h>
+#include <errno.h>
+
+
+/* dirent.d_type is a BSD extension, not part of POSIX */
+#include <sys/stat.h>
+#include <string.h>
+
+static int
+is_dir (const char *path, const char *name)
+{
+  int len1 = strlen(path);
+  int len2 = strlen(name);
+
+  char pathname[len1 + 1 + len2 + 1 + 13];
+  strcpy (pathname, path);
+
+  /* Avoid UNC-path "//name" on Cygwin.  */
+  if (len1 > 0 && pathname[len1 - 1] != '/')
+    strcat (pathname, "/");
+
+  strcat (pathname, name);
+
+  struct stat st;
+  if (stat (pathname, &st))
+    return 0;
+  return S_ISDIR (st.st_mode);
+}
+
+static grub_err_t
+grub_hostfs_dir (grub_device_t device, const char *path,
+                int (*hook) (const char *filename,
+                             const struct grub_dirhook_info *info))
+{
+  DIR *dir;
+
+  /* Check if the disk is our dummy disk.  */
+  if (grub_strcmp (device->disk->name, "host"))
+    return grub_error (GRUB_ERR_BAD_FS, "not a hostfs");
+
+  dir = opendir (path);
+  if (! dir)
+    return grub_error (GRUB_ERR_BAD_FILENAME,
+                      "can't open the hostfs directory `%s'", path);
+
+  while (1)
+    {
+      struct dirent *de;
+      struct grub_dirhook_info info;
+      grub_memset (&info, 0, sizeof (info));
+
+      de = readdir (dir);
+      if (! de)
+       break;
+
+      info.dir = !! is_dir (path, de->d_name);
+      hook (de->d_name, &info);
+
+    }
+
+  closedir (dir);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Open a file named NAME and initialize FILE.  */
+static grub_err_t
+grub_hostfs_open (struct grub_file *file, const char *name)
+{
+  FILE *f;
+
+  f = fopen (name, "rb");
+  if (! f)
+    return grub_error (GRUB_ERR_BAD_FILENAME,
+                      "can't open `%s'", name);
+  file->data = f;
+
+#ifdef __MINGW32__
+  file->size = grub_util_get_disk_size (name);
+#else
+  fseeko (f, 0, SEEK_END);
+  file->size = ftello (f);
+  fseeko (f, 0, SEEK_SET);
+#endif
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_ssize_t
+grub_hostfs_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  FILE *f;
+
+  f = (FILE *) file->data;
+  if (fseeko (f, file->offset, SEEK_SET) != 0)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "fseeko: %s", strerror (errno));
+      return -1;
+    }
+
+  unsigned int s = fread (buf, 1, len, f);
+  if (s != len)
+    grub_error (GRUB_ERR_FILE_READ_ERROR, "fread: %s", strerror (errno));
+
+  return (signed) s;
+}
+
+static grub_err_t
+grub_hostfs_close (grub_file_t file)
+{
+  FILE *f;
+
+  f = (FILE *) file->data;
+  fclose (f);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_hostfs_label (grub_device_t device __attribute ((unused)),
+                  char **label __attribute ((unused)))
+{
+  *label = 0;
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_fs grub_hostfs_fs =
+  {
+    .name = "hostfs",
+    .dir = grub_hostfs_dir,
+    .open = grub_hostfs_open,
+    .read = grub_hostfs_read,
+    .close = grub_hostfs_close,
+    .label = grub_hostfs_label,
+    .next = 0
+  };
+
+\f
+
+GRUB_MOD_INIT(hostfs)
+{
+  grub_fs_register (&grub_hostfs_fs);
+}
+
+GRUB_MOD_FINI(hostfs)
+{
+  grub_fs_unregister (&grub_hostfs_fs);
+}
diff --git a/grub-core/kern/emu/lite.c b/grub-core/kern/emu/lite.c
new file mode 100644 (file)
index 0000000..1f06e39
--- /dev/null
@@ -0,0 +1,16 @@
+#include <config.h>
+#include <grub/emu/misc.h>
+
+/* grub-emu-lite supports dynamic module loading, so it won't have any
+   embedded modules.  */
+void
+grub_init_all(void)
+{
+  return;
+}
+
+void
+grub_fini_all(void)
+{
+  return;
+}
diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c
new file mode 100644 (file)
index 0000000..9083e27
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <setjmp.h>
+#include <sys/stat.h>
+#include <getopt.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <grub/mm.h>
+#include <grub/setjmp.h>
+#include <grub/fs.h>
+#include <grub/emu/hostdisk.h>
+#include <grub/time.h>
+#include <grub/emu/console.h>
+#include <grub/emu/misc.h>
+#include <grub/util/misc.h>
+#include <grub/kernel.h>
+#include <grub/normal.h>
+#include <grub/emu/getroot.h>
+#include <grub/env.h>
+#include <grub/partition.h>
+#include <grub/i18n.h>
+
+#include "progname.h"
+
+#define ENABLE_RELOCATABLE 0
+
+/* Used for going back to the main function.  */
+static jmp_buf main_env;
+
+/* Store the prefix specified by an argument.  */
+static char *prefix = NULL;
+
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+  return 0;
+}
+
+void
+grub_reboot (void)
+{
+  longjmp (main_env, 1);
+}
+
+void
+grub_halt (
+#ifdef GRUB_MACHINE_PCBIOS
+          int no_apm __attribute__ ((unused))
+#endif
+          )
+{
+  grub_reboot ();
+}
+
+void
+grub_machine_init (void)
+{
+}
+
+void
+grub_machine_set_prefix (void)
+{
+  grub_env_set ("prefix", prefix);
+  free (prefix);
+  prefix = 0;
+}
+
+void
+grub_machine_fini (void)
+{
+  grub_console_fini ();
+}
+
+\f
+
+static struct option options[] =
+  {
+    {"root-device", required_argument, 0, 'r'},
+    {"device-map", required_argument, 0, 'm'},
+    {"directory", required_argument, 0, 'd'},
+    {"hold", optional_argument, 0, 'H'},
+    {"help", no_argument, 0, 'h'},
+    {"version", no_argument, 0, 'V'},
+    {"verbose", no_argument, 0, 'v'},
+    { 0, 0, 0, 0 }
+  };
+
+static int
+usage (int status)
+{
+  if (status)
+    fprintf (stderr,
+            "Try `%s --help' for more information.\n", program_name);
+  else
+    printf (
+      "Usage: %s [OPTION]...\n"
+      "\n"
+      "GRUB emulator.\n"
+      "\n"
+      "  -r, --root-device=DEV     use DEV as the root device [default=guessed]\n"
+      "  -m, --device-map=FILE     use FILE as the device map [default=%s]\n"
+      "  -d, --directory=DIR       use GRUB files in the directory DIR [default=%s]\n"
+      "  -v, --verbose             print verbose messages\n"
+      "  -H, --hold[=SECONDS]      wait until a debugger will attach\n"
+      "  -h, --help                display this message and exit\n"
+      "  -V, --version             print version information and exit\n"
+      "\n"
+      "Report bugs to <%s>.\n", program_name, DEFAULT_DEVICE_MAP, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT);
+  return status;
+}
+\f
+
+void grub_hostfs_init (void);
+void grub_hostfs_fini (void);
+void grub_host_init (void);
+void grub_host_fini (void);
+
+int
+main (int argc, char *argv[])
+{
+  char *root_dev = 0;
+  char *dir = DEFAULT_DIRECTORY;
+  char *dev_map = DEFAULT_DEVICE_MAP;
+  volatile int hold = 0;
+  int opt;
+
+  set_program_name (argv[0]);
+
+  while ((opt = getopt_long (argc, argv, "r:d:m:vH:hV", options, 0)) != -1)
+    switch (opt)
+      {
+      case 'r':
+        root_dev = optarg;
+        break;
+      case 'd':
+        dir = optarg;
+        break;
+      case 'm':
+        dev_map = optarg;
+        break;
+      case 'v':
+        verbosity++;
+        break;
+      case 'H':
+        hold = (optarg ? atoi (optarg) : -1);
+        break;
+      case 'h':
+        return usage (0);
+      case 'V':
+        printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
+        return 0;
+      default:
+        return usage (1);
+      }
+
+  if (optind < argc)
+    {
+      fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind]);
+      return usage (1);
+    }
+
+  /* Wait until the ARGS.HOLD variable is cleared by an attached debugger. */
+  if (hold && verbosity > 0)
+    printf ("Run \"gdb %s %d\", and set ARGS.HOLD to zero.\n",
+            program_name, (int) getpid ());
+  while (hold)
+    {
+      if (hold > 0)
+        hold--;
+
+      sleep (1);
+    }
+
+  signal (SIGINT, SIG_IGN);
+  grub_console_init ();
+  grub_host_init ();
+  grub_hostfs_init ();
+
+  /* XXX: This is a bit unportable.  */
+  grub_util_biosdisk_init (dev_map);
+
+  /* Initialize all embedded modules.  */
+  grub_init_all ();
+
+  /* Make sure that there is a root device.  */
+  if (! root_dev)
+    {
+      char *device_name = grub_guess_root_device (dir);
+      if (! device_name)
+        grub_util_error ("cannot find a device for %s", dir);
+
+      root_dev = grub_util_get_grub_dev (device_name);
+      if (! root_dev)
+       {
+         grub_util_info ("guessing the root device failed, because of `%s'",
+                         grub_errmsg);
+         grub_util_error ("cannot guess the root device. Specify the option `--root-device'");
+       }
+    }
+
+  if (strcmp (root_dev, "host") == 0)
+    dir = xstrdup (dir);
+  else
+    dir = grub_make_system_path_relative_to_its_root (dir);
+  prefix = xmalloc (strlen (root_dev) + 2 + strlen (dir) + 1);
+  sprintf (prefix, "(%s)%s", root_dev, dir);
+  free (dir);
+
+  /* Start GRUB!  */
+  if (setjmp (main_env) == 0)
+    grub_main ();
+
+  grub_fini_all ();
+  grub_hostfs_fini ();
+  grub_host_fini ();
+
+  grub_machine_fini ();
+
+  return 0;
+}
+
+#ifdef __MINGW32__
+
+void
+grub_millisleep (grub_uint32_t ms)
+{
+  Sleep (ms);
+}
+
+#else
+
+void
+grub_millisleep (grub_uint32_t ms)
+{
+  struct timespec ts;
+
+  ts.tv_sec = ms / 1000;
+  ts.tv_nsec = (ms % 1000) * 1000000;
+  nanosleep (&ts, NULL);
+}
+
+#endif
diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c
new file mode 100644 (file)
index 0000000..d8dfc93
--- /dev/null
@@ -0,0 +1,199 @@
+#include <config.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/env.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/i18n.h>
+#include <grub/time.h>
+#include <grub/emu/misc.h>
+
+int verbosity;
+
+void
+grub_util_warn (const char *fmt, ...)
+{
+  va_list ap;
+
+  fprintf (stderr, _("%s: warn:"), program_name);
+  fprintf (stderr, " ");
+  va_start (ap, fmt);
+  vfprintf (stderr, fmt, ap);
+  va_end (ap);
+  fprintf (stderr, ".\n");
+  fflush (stderr);
+}
+
+void
+grub_util_info (const char *fmt, ...)
+{
+  if (verbosity > 0)
+    {
+      va_list ap;
+
+      fprintf (stderr, _("%s: info:"), program_name);
+      fprintf (stderr, " ");
+      va_start (ap, fmt);
+      vfprintf (stderr, fmt, ap);
+      va_end (ap);
+      fprintf (stderr, ".\n");
+      fflush (stderr);
+    }
+}
+
+void
+grub_util_error (const char *fmt, ...)
+{
+  va_list ap;
+
+  fprintf (stderr, _("%s: error:"), program_name);
+  fprintf (stderr, " ");
+  va_start (ap, fmt);
+  vfprintf (stderr, fmt, ap);
+  va_end (ap);
+  fprintf (stderr, ".\n");
+  exit (1);
+}
+
+void *
+grub_malloc (grub_size_t size)
+{
+  return malloc (size);
+}
+
+void *
+grub_zalloc (grub_size_t size)
+{
+  void *ret;
+
+  ret = malloc (size);
+  memset (ret, 0, size);
+  return ret;
+}
+
+void
+grub_free (void *ptr)
+{
+  free (ptr);
+}
+
+void *
+grub_realloc (void *ptr, grub_size_t size)
+{
+  return realloc (ptr, size);
+}
+
+void *
+grub_memalign (grub_size_t align, grub_size_t size)
+{
+  void *p;
+
+#if defined(HAVE_POSIX_MEMALIGN)
+  if (align < sizeof (void *))
+    align = sizeof (void *);
+
+  else if (align % sizeof (void *))
+    grub_fatal ("bad alignment");
+
+  if (posix_memalign (&p, align, size) != 0)
+    p = 0;
+#elif defined(HAVE_MEMALIGN)
+  p = memalign (align, size);
+#else
+  (void) align;
+  (void) size;
+  grub_fatal ("grub_memalign is not supported");
+#endif
+
+  if (! p)
+    grub_fatal ("out of memory");
+
+  return p;
+}
+
+void *
+xmalloc (grub_size_t size)
+{
+  void *p;
+
+  p = grub_malloc (size);
+  if (! p)
+    grub_fatal ("out of memory");
+
+  return p;
+}
+
+void *
+xrealloc (void *ptr, grub_size_t size)
+{
+  ptr = grub_realloc (ptr, size);
+  if (! ptr)
+    grub_fatal ("out of memory");
+
+  return ptr;
+}
+
+char *
+xstrdup (const char *str)
+{
+  size_t len;
+  char *newstr;
+
+  len = grub_strlen (str);
+  newstr = (char *) xmalloc (len + 1);
+  grub_memcpy (newstr, str, len + 1);
+
+  return newstr;
+}
+
+char *
+xasprintf (const char *fmt, ...)
+{ 
+  va_list ap;
+  char *result;
+  
+  va_start (ap, fmt);
+  if (vasprintf (&result, fmt, ap) < 0)
+    { 
+      if (errno == ENOMEM)
+        grub_util_error ("out of memory");
+      return NULL;
+    }
+  
+  return result;
+}
+
+void
+grub_exit (void)
+{
+  exit (1);
+}
+
+grub_uint64_t
+grub_get_time_ms (void)
+{
+  struct timeval tv;
+
+  gettimeofday (&tv, 0);
+
+  return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
+}
+
+grub_uint32_t
+grub_get_rtc (void)
+{
+  struct timeval tv;
+
+  gettimeofday (&tv, 0);
+
+  return (tv.tv_sec * GRUB_TICKS_PER_SECOND
+         + (((tv.tv_sec % GRUB_TICKS_PER_SECOND) * 1000000 + tv.tv_usec)
+            * GRUB_TICKS_PER_SECOND / 1000000));
+}
diff --git a/grub-core/kern/emu/time.c b/grub-core/kern/emu/time.c
new file mode 100644 (file)
index 0000000..5da8092
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/datetime.h>
+#include <time.h>
+
+grub_err_t
+grub_get_datetime (struct grub_datetime *datetime)
+{
+  struct tm *mytm;
+  time_t mytime;
+
+  mytime = time (&mytime);
+  mytm = gmtime (&mytime);
+
+  datetime->year = mytm->tm_year + 1900;
+  datetime->month = mytm->tm_mon + 1;
+  datetime->day = mytm->tm_mday;
+  datetime->hour = mytm->tm_hour;
+  datetime->minute = mytm->tm_min;
+  datetime->second = mytm->tm_sec;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_set_datetime (struct grub_datetime *datetime __attribute__ ((unused)))
+{
+  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                    "no clock setting routine available");
+}
diff --git a/grub-core/kern/env.c b/grub-core/kern/env.c
new file mode 100644 (file)
index 0000000..84b3a00
--- /dev/null
@@ -0,0 +1,242 @@
+/* env.c - Environment variables */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/env_private.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+/* The initial context.  */
+static struct grub_env_context initial_context;
+
+/* The current context.  */
+struct grub_env_context *grub_current_context = &initial_context;
+
+/* Return the hash representation of the string S.  */
+static unsigned int
+grub_env_hashval (const char *s)
+{
+  unsigned int i = 0;
+
+  /* XXX: This can be done much more efficiently.  */
+  while (*s)
+    i += 5 * *(s++);
+
+  return i % HASHSZ;
+}
+
+struct grub_env_var *
+grub_env_find (const char *name)
+{
+  struct grub_env_var *var;
+  int idx = grub_env_hashval (name);
+
+  /* Look for the variable in the current context.  */
+  for (var = grub_current_context->vars[idx]; var; var = var->next)
+    if (grub_strcmp (var->name, name) == 0)
+      return var;
+
+  return 0;
+}
+
+static void
+grub_env_insert (struct grub_env_context *context,
+                struct grub_env_var *var)
+{
+  int idx = grub_env_hashval (var->name);
+
+  /* Insert the variable into the hashtable.  */
+  var->prevp = &context->vars[idx];
+  var->next = context->vars[idx];
+  if (var->next)
+    var->next->prevp = &(var->next);
+  context->vars[idx] = var;
+}
+
+static void
+grub_env_remove (struct grub_env_var *var)
+{
+  /* Remove the entry from the variable table.  */
+  *var->prevp = var->next;
+  if (var->next)
+    var->next->prevp = var->prevp;
+}
+
+grub_err_t
+grub_env_set (const char *name, const char *val)
+{
+  struct grub_env_var *var;
+
+  /* If the variable does already exist, just update the variable.  */
+  var = grub_env_find (name);
+  if (var)
+    {
+      char *old = var->value;
+
+      if (var->write_hook)
+       var->value = var->write_hook (var, val);
+      else
+       var->value = grub_strdup (val);
+
+      if (! var->value)
+       {
+         var->value = old;
+         return grub_errno;
+       }
+
+      grub_free (old);
+      return GRUB_ERR_NONE;
+    }
+
+  /* The variable does not exist, so create a new one.  */
+  var = grub_zalloc (sizeof (*var));
+  if (! var)
+    return grub_errno;
+
+  /* This is not necessary. But leave this for readability.  */
+  var->global = 0;
+
+  var->name = grub_strdup (name);
+  if (! var->name)
+    goto fail;
+
+  var->value = grub_strdup (val);
+  if (! var->value)
+    goto fail;
+
+  grub_env_insert (grub_current_context, var);
+
+  return GRUB_ERR_NONE;
+
+ fail:
+  grub_free (var->name);
+  grub_free (var->value);
+  grub_free (var);
+
+  return grub_errno;
+}
+
+char *
+grub_env_get (const char *name)
+{
+  struct grub_env_var *var;
+
+  var = grub_env_find (name);
+  if (! var)
+    return 0;
+
+  if (var->read_hook)
+    return var->read_hook (var, var->value);
+
+  return var->value;
+}
+
+void
+grub_env_unset (const char *name)
+{
+  struct grub_env_var *var;
+
+  var = grub_env_find (name);
+  if (! var)
+    return;
+
+  if (var->read_hook || var->write_hook)
+    {
+      grub_env_set (name, "");
+      return;
+    }
+
+  grub_env_remove (var);
+
+  grub_free (var->name);
+  grub_free (var->value);
+  grub_free (var);
+}
+
+void
+grub_env_iterate (int (*func) (struct grub_env_var *var))
+{
+  struct grub_env_sorted_var *sorted_list = 0;
+  struct grub_env_sorted_var *sorted_var;
+  int i;
+
+  /* Add variables associated with this context into a sorted list.  */
+  for (i = 0; i < HASHSZ; i++)
+    {
+      struct grub_env_var *var;
+
+      for (var = grub_current_context->vars[i]; var; var = var->next)
+       {
+         struct grub_env_sorted_var *p, **q;
+
+         sorted_var = grub_malloc (sizeof (*sorted_var));
+         if (! sorted_var)
+           goto fail;
+
+         sorted_var->var = var;
+
+         for (q = &sorted_list, p = *q; p; q = &((*q)->next), p = *q)
+           {
+             if (grub_strcmp (p->var->name, var->name) > 0)
+               break;
+           }
+
+         sorted_var->next = *q;
+         *q = sorted_var;
+       }
+    }
+
+  /* Iterate FUNC on the sorted list.  */
+  for (sorted_var = sorted_list; sorted_var; sorted_var = sorted_var->next)
+    if (func (sorted_var->var))
+      break;
+
+ fail:
+
+  /* Free the sorted list.  */
+  for (sorted_var = sorted_list; sorted_var; )
+    {
+      struct grub_env_sorted_var *tmp = sorted_var->next;
+
+      grub_free (sorted_var);
+      sorted_var = tmp;
+    }
+}
+
+grub_err_t
+grub_register_variable_hook (const char *name,
+                            grub_env_read_hook_t read_hook,
+                            grub_env_write_hook_t write_hook)
+{
+  struct grub_env_var *var = grub_env_find (name);
+
+  if (! var)
+    {
+      if (grub_env_set (name, "") != GRUB_ERR_NONE)
+       return grub_errno;
+
+      var = grub_env_find (name);
+      /* XXX Insert an assertion?  */
+    }
+
+  var->read_hook = read_hook;
+  var->write_hook = write_hook;
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/kern/err.c b/grub-core/kern/err.c
new file mode 100644 (file)
index 0000000..8272467
--- /dev/null
@@ -0,0 +1,135 @@
+/* err.c - error handling routines */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <stdarg.h>
+#include <grub/i18n.h>
+
+#define GRUB_MAX_ERRMSG                256
+#define GRUB_ERROR_STACK_SIZE  10
+
+grub_err_t grub_errno;
+char grub_errmsg[GRUB_MAX_ERRMSG];
+
+static struct
+{
+  grub_err_t errno;
+  char errmsg[GRUB_MAX_ERRMSG];
+} grub_error_stack_items[GRUB_ERROR_STACK_SIZE];
+
+static int grub_error_stack_pos;
+static int grub_error_stack_assert;
+
+grub_err_t
+grub_error (grub_err_t n, const char *fmt, ...)
+{
+  va_list ap;
+
+  grub_errno = n;
+
+  va_start (ap, fmt);
+  grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), _(fmt), ap);
+  va_end (ap);
+
+  return n;
+}
+
+void
+grub_fatal (const char *fmt, ...)
+{
+  va_list ap;
+
+  va_start (ap, fmt);
+  grub_vprintf (_(fmt), ap);
+  va_end (ap);
+
+  grub_abort ();
+}
+
+void
+grub_error_push (void)
+{
+  /* Only add items to stack, if there is enough room.  */
+  if (grub_error_stack_pos < GRUB_ERROR_STACK_SIZE)
+    {
+      /* Copy active error message to stack.  */
+      grub_error_stack_items[grub_error_stack_pos].errno = grub_errno;
+      grub_memcpy (grub_error_stack_items[grub_error_stack_pos].errmsg,
+                   grub_errmsg,
+                   sizeof (grub_errmsg));
+
+      /* Advance to next error stack position.  */
+      grub_error_stack_pos++;
+    }
+  else
+    {
+      /* There is no room for new error message. Discard new error message
+         and mark error stack assertion flag.  */
+      grub_error_stack_assert = 1;
+    }
+
+  /* Allow further operation of other components by resetting
+     active errno to GRUB_ERR_NONE.  */
+  grub_errno = GRUB_ERR_NONE;
+}
+
+int
+grub_error_pop (void)
+{
+  if (grub_error_stack_pos > 0)
+    {
+      /* Pop error message from error stack to current active error.  */
+      grub_error_stack_pos--;
+
+      grub_errno = grub_error_stack_items[grub_error_stack_pos].errno;
+      grub_memcpy (grub_errmsg,
+                   grub_error_stack_items[grub_error_stack_pos].errmsg,
+                   sizeof (grub_errmsg));
+
+      return 1;
+    }
+  else
+    {
+      /* There is no more items on error stack, reset to no error state.  */
+      grub_errno = GRUB_ERR_NONE;
+
+      return 0;
+    }
+}
+
+void
+grub_print_error (void)
+{
+  /* Print error messages in reverse order. First print active error message
+     and then empty error stack.  */
+  do
+    {
+      if (grub_errno != GRUB_ERR_NONE)
+        grub_err_printf (_("error: %s.\n"), grub_errmsg);
+    }
+  while (grub_error_pop ());
+
+  /* If there was an assert while using error stack, report about it.  */
+  if (grub_error_stack_assert)
+    {
+      grub_err_printf ("assert: error stack overflow detected!\n");
+      grub_error_stack_assert = 0;
+    }
+}
diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c
new file mode 100644 (file)
index 0000000..e17c35f
--- /dev/null
@@ -0,0 +1,166 @@
+/* file.c - file I/O functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/fs.h>
+#include <grub/device.h>
+
+/* Get the device part of the filename NAME. It is enclosed by parentheses.  */
+char *
+grub_file_get_device_name (const char *name)
+{
+  if (name[0] == '(')
+    {
+      char *p = grub_strchr (name, ')');
+      char *ret;
+
+      if (! p)
+       {
+         grub_error (GRUB_ERR_BAD_FILENAME, "missing `)'");
+         return 0;
+       }
+
+      ret = (char *) grub_malloc (p - name);
+      if (! ret)
+       return 0;
+
+      grub_memcpy (ret, name + 1, p - name - 1);
+      ret[p - name - 1] = '\0';
+      return ret;
+    }
+
+  return 0;
+}
+
+grub_file_t
+grub_file_open (const char *name)
+{
+  grub_device_t device;
+  grub_file_t file = 0;
+  char *device_name;
+  char *file_name;
+
+  device_name = grub_file_get_device_name (name);
+  if (grub_errno)
+    return 0;
+
+  /* Get the file part of NAME.  */
+  file_name = grub_strchr (name, ')');
+  if (file_name)
+    file_name++;
+  else
+    file_name = (char *) name;
+
+  device = grub_device_open (device_name);
+  grub_free (device_name);
+  if (! device)
+    goto fail;
+
+  file = (grub_file_t) grub_zalloc (sizeof (*file));
+  if (! file)
+    goto fail;
+
+  file->device = device;
+
+  if (device->disk && file_name[0] != '/')
+    /* This is a block list.  */
+    file->fs = &grub_fs_blocklist;
+  else
+    {
+      file->fs = grub_fs_probe (device);
+      if (! file->fs)
+       goto fail;
+    }
+
+  if ((file->fs->open) (file, file_name) != GRUB_ERR_NONE)
+    goto fail;
+
+  return file;
+
+ fail:
+  if (device)
+    grub_device_close (device);
+
+  /* if (net) grub_net_close (net);  */
+
+  grub_free (file);
+
+  return 0;
+}
+
+grub_ssize_t
+grub_file_read (grub_file_t file, void *buf, grub_size_t len)
+{
+  grub_ssize_t res;
+
+  if (file->offset > file->size)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE,
+                 "attempt to read past the end of file");
+      return -1;
+    }
+
+  if (len == 0 || len > file->size - file->offset)
+    len = file->size - file->offset;
+
+  /* Prevent an overflow.  */
+  if ((grub_ssize_t) len < 0)
+    len >>= 1;
+
+  if (len == 0)
+    return 0;
+
+  res = (file->fs->read) (file, buf, len);
+  if (res > 0)
+    file->offset += res;
+
+  return res;
+}
+
+grub_err_t
+grub_file_close (grub_file_t file)
+{
+  if (file->fs->close)
+    (file->fs->close) (file);
+
+  if (file->device)
+    grub_device_close (file->device);
+  grub_free (file);
+  return grub_errno;
+}
+
+grub_off_t
+grub_file_seek (grub_file_t file, grub_off_t offset)
+{
+  grub_off_t old;
+
+  if (offset > file->size)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE,
+                 "attempt to seek outside of the file");
+      return -1;
+    }
+
+  old = file->offset;
+  file->offset = offset;
+  return old;
+}
diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c
new file mode 100644 (file)
index 0000000..0c45637
--- /dev/null
@@ -0,0 +1,261 @@
+/* fs.c - filesystem manager */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/net.h>
+#include <grub/fs.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/term.h>
+
+static grub_fs_t grub_fs_list;
+
+grub_fs_autoload_hook_t grub_fs_autoload_hook = 0;
+
+void
+grub_fs_register (grub_fs_t fs)
+{
+  fs->next = grub_fs_list;
+  grub_fs_list = fs;
+}
+
+void
+grub_fs_unregister (grub_fs_t fs)
+{
+  grub_fs_t *p, q;
+
+  for (p = &grub_fs_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == fs)
+      {
+       *p = q->next;
+       break;
+      }
+}
+
+void
+grub_fs_iterate (int (*hook) (const grub_fs_t fs))
+{
+  grub_fs_t p;
+
+  for (p = grub_fs_list; p; p = p->next)
+    if (hook (p))
+      break;
+}
+
+grub_fs_t
+grub_fs_probe (grub_device_t device)
+{
+  grub_fs_t p;
+  auto int dummy_func (const char *filename,
+                      const struct grub_dirhook_info *info);
+
+  int dummy_func (const char *filename __attribute__ ((unused)),
+                 const struct grub_dirhook_info *info  __attribute__ ((unused)))
+    {
+      return 1;
+    }
+
+  if (device->disk)
+    {
+      /* Make it sure not to have an infinite recursive calls.  */
+      static int count = 0;
+
+      for (p = grub_fs_list; p; p = p->next)
+       {
+         grub_dprintf ("fs", "Detecting %s...\n", p->name);
+         (p->dir) (device, "/", dummy_func);
+         if (grub_errno == GRUB_ERR_NONE)
+           return p;
+
+         grub_error_push ();
+         grub_dprintf ("fs", "%s detection failed.\n", p->name);
+         grub_error_pop ();
+
+         if (grub_errno != GRUB_ERR_BAD_FS)
+           return 0;
+
+         grub_errno = GRUB_ERR_NONE;
+       }
+
+      /* Let's load modules automatically.  */
+      if (grub_fs_autoload_hook && count == 0)
+       {
+         count++;
+
+         while (grub_fs_autoload_hook ())
+           {
+             p = grub_fs_list;
+
+             (p->dir) (device, "/", dummy_func);
+             if (grub_errno == GRUB_ERR_NONE)
+               {
+                 count--;
+                 return p;
+               }
+
+             if (grub_errno != GRUB_ERR_BAD_FS)
+               {
+                 count--;
+                 return 0;
+               }
+
+             grub_errno = GRUB_ERR_NONE;
+           }
+
+         count--;
+       }
+    }
+  else if (device->net->fs)
+    return device->net->fs;
+
+  grub_error (GRUB_ERR_UNKNOWN_FS, "unknown filesystem");
+  return 0;
+}
+
+\f
+
+/* Block list support routines.  */
+
+struct grub_fs_block
+{
+  grub_disk_addr_t offset;
+  unsigned long length;
+};
+
+static grub_err_t
+grub_fs_blocklist_open (grub_file_t file, const char *name)
+{
+  char *p = (char *) name;
+  unsigned num = 0;
+  unsigned i;
+  grub_disk_t disk = file->device->disk;
+  struct grub_fs_block *blocks;
+
+  /* First, count the number of blocks.  */
+  do
+    {
+      num++;
+      p = grub_strchr (p, ',');
+      if (p)
+       p++;
+    }
+  while (p);
+
+  /* Allocate a block list.  */
+  blocks = grub_zalloc (sizeof (struct grub_fs_block) * (num + 1));
+  if (! blocks)
+    return 0;
+
+  file->size = 0;
+  p = (char *) name;
+  for (i = 0; i < num; i++)
+    {
+      if (*p != '+')
+       {
+         blocks[i].offset = grub_strtoull (p, &p, 0);
+         if (grub_errno != GRUB_ERR_NONE || *p != '+')
+           {
+             grub_error (GRUB_ERR_BAD_FILENAME,
+                         "invalid file name `%s'", name);
+             goto fail;
+           }
+       }
+
+      p++;
+      blocks[i].length = grub_strtoul (p, &p, 0);
+      if (grub_errno != GRUB_ERR_NONE
+         || blocks[i].length == 0
+         || (*p && *p != ',' && ! grub_isspace (*p)))
+       {
+         grub_error (GRUB_ERR_BAD_FILENAME,
+                     "invalid file name `%s'", name);
+         goto fail;
+       }
+
+      if (disk->total_sectors < blocks[i].offset + blocks[i].length)
+       {
+         grub_error (GRUB_ERR_BAD_FILENAME, "beyond the total sectors");
+         goto fail;
+       }
+
+      file->size += (blocks[i].length << GRUB_DISK_SECTOR_BITS);
+      p++;
+    }
+
+  file->data = blocks;
+
+  return GRUB_ERR_NONE;
+
+ fail:
+  grub_free (blocks);
+  return grub_errno;
+}
+
+static grub_ssize_t
+grub_fs_blocklist_read (grub_file_t file, char *buf, grub_size_t len)
+{
+  struct grub_fs_block *p;
+  grub_disk_addr_t sector;
+  grub_off_t offset;
+  grub_ssize_t ret = 0;
+
+  if (len > file->size - file->offset)
+    len = file->size - file->offset;
+
+  sector = (file->offset >> GRUB_DISK_SECTOR_BITS);
+  offset = (file->offset & (GRUB_DISK_SECTOR_SIZE - 1));
+  for (p = file->data; p->length && len > 0; p++)
+    {
+      if (sector < p->length)
+       {
+         grub_size_t size;
+
+         size = len;
+         if (((size + offset + GRUB_DISK_SECTOR_SIZE - 1)
+              >> GRUB_DISK_SECTOR_BITS) > p->length - sector)
+           size = ((p->length - sector) << GRUB_DISK_SECTOR_BITS) - offset;
+
+         if (grub_disk_read (file->device->disk, p->offset + sector, offset,
+                             size, buf) != GRUB_ERR_NONE)
+           return -1;
+
+         ret += size;
+         len -= size;
+         sector -= ((size + offset) >> GRUB_DISK_SECTOR_BITS);
+         offset = ((size + offset) & (GRUB_DISK_SECTOR_SIZE - 1));
+       }
+      else
+       sector -= p->length;
+    }
+
+  return ret;
+}
+
+struct grub_fs grub_fs_blocklist =
+  {
+    .name = "blocklist",
+    .dir = 0,
+    .open = grub_fs_blocklist_open,
+    .read = grub_fs_blocklist_read,
+    .close = 0,
+    .next = 0
+  };
diff --git a/grub-core/kern/generic/millisleep.c b/grub-core/kern/generic/millisleep.c
new file mode 100644 (file)
index 0000000..9d5971f
--- /dev/null
@@ -0,0 +1,39 @@
+/* millisleep.c - generic millisleep function.
+ * The generic implementation of these functions can be used for architectures
+ * or platforms that do not have a more specialized implementation. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/time.h>
+
+void
+grub_millisleep (grub_uint32_t ms)
+{
+  grub_uint64_t start;
+
+  start = grub_get_time_ms ();
+
+  /* Instead of setting an end time and looping while the current time is
+     less than that, comparing the elapsed sleep time with the desired sleep
+     time handles the (unlikely!) case that the timer would wrap around
+     during the sleep. */
+
+  while (grub_get_time_ms () - start < ms)
+    grub_cpu_idle ();
+}
diff --git a/grub-core/kern/generic/rtc_get_time_ms.c b/grub-core/kern/generic/rtc_get_time_ms.c
new file mode 100644 (file)
index 0000000..3592336
--- /dev/null
@@ -0,0 +1,37 @@
+/* rtc_get_time_ms.c - get_time_ms implementation using platform RTC.
+ * The generic implementation of these functions can be used for architectures
+ * or platforms that do not have a more specialized implementation. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/time.h>
+#include <grub/misc.h>
+
+/* Calculate the time in milliseconds since the epoch based on the RTC. */
+grub_uint64_t
+grub_rtc_get_time_ms (void)
+{
+  /* By dimensional analysis:
+
+      1000 ms   N rtc ticks       1 s
+      ------- * ----------- * ----------- = 1000*N/T ms
+        1 s          1        T rtc ticks
+   */
+  grub_uint64_t ticks_ms_per_sec = ((grub_uint64_t) 1000) * grub_get_rtc ();
+  return grub_divmod64 (ticks_ms_per_sec, GRUB_TICKS_PER_SECOND, 0);
+}
diff --git a/grub-core/kern/handler.c b/grub-core/kern/handler.c
new file mode 100644 (file)
index 0000000..2bf8531
--- /dev/null
@@ -0,0 +1,64 @@
+/* handler.c - grub handler function */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/handler.h>
+
+grub_handler_class_t grub_handler_class_list;
+
+void
+grub_handler_register (grub_handler_class_t class, grub_handler_t handler)
+{
+  int first_handler = (class->handler_list == 0);
+
+  grub_list_push (GRUB_AS_LIST_P (&class->handler_list),
+                 GRUB_AS_LIST (handler));
+
+  if (first_handler)
+    {
+      grub_list_push (GRUB_AS_LIST_P (&grub_handler_class_list),
+                     GRUB_AS_LIST (class));
+      grub_handler_set_current (class, handler);
+    }
+}
+
+void
+grub_handler_unregister (grub_handler_class_t class, grub_handler_t handler)
+{
+  grub_list_remove (GRUB_AS_LIST_P (&class->handler_list),
+                   GRUB_AS_LIST (handler));
+
+  if (class->handler_list == 0)
+    grub_list_remove (GRUB_AS_LIST_P (&grub_handler_class_list),
+                     GRUB_AS_LIST (class));
+}
+
+grub_err_t
+grub_handler_set_current (grub_handler_class_t class, grub_handler_t handler)
+{
+  if (class->cur_handler && class->cur_handler->fini)
+    if ((class->cur_handler->fini) () != GRUB_ERR_NONE)
+      return grub_errno;
+
+  if (handler->init)
+    if ((handler->init) () != GRUB_ERR_NONE)
+      return grub_errno;
+
+  class->cur_handler = handler;
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c
new file mode 100644 (file)
index 0000000..f7b8370
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/mm.h>
+#include <grub/machine/time.h>
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/console.h>
+#include <grub/machine/kernel.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/loader.h>
+#include <grub/env.h>
+#include <grub/cache.h>
+#include <grub/time.h>
+#include <grub/symbol.h>
+#include <grub/cpu/io.h>
+#include <grub/cpu/kernel.h>
+#include <grub/cpu/tsc.h>
+
+#define GRUB_FLOPPY_REG_DIGITAL_OUTPUT         0x3f2
+
+extern char _start[];
+extern char _end[];
+
+grub_addr_t grub_os_area_addr;
+grub_size_t grub_os_area_size;
+
+grub_uint32_t
+grub_get_rtc (void)
+{
+  grub_fatal ("grub_get_rtc() is not implemented.\n");
+}
+
+/* Stop the floppy drive from spinning, so that other software is
+   jumped to with a known state.  */
+void
+grub_stop_floppy (void)
+{
+  grub_outb (0, GRUB_FLOPPY_REG_DIGITAL_OUTPUT);
+}
+
+void
+grub_exit (void)
+{
+  /* We can't use grub_fatal() in this function.  This would create an infinite
+     loop, since grub_fatal() calls grub_abort() which in turn calls grub_exit().  */
+  while (1)
+    grub_cpu_idle ();
+}
+
+void
+grub_machine_init (void)
+{
+  /* Initialize the console as early as possible.  */
+  grub_vga_text_init ();
+
+  auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+  {
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+    /* Restrict ourselves to 32-bit memory space.  */
+    if (addr > GRUB_ULONG_MAX)
+      return 0;
+    if (addr + size > GRUB_ULONG_MAX)
+      size = GRUB_ULONG_MAX - addr;
+#endif
+
+    if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+      return 0;
+
+    /* Avoid the lower memory.  */
+    if (addr < GRUB_MEMORY_MACHINE_LOWER_SIZE)
+      {
+       if (addr + size <= GRUB_MEMORY_MACHINE_LOWER_SIZE)
+         return 0;
+       else
+         {
+           size -= GRUB_MEMORY_MACHINE_LOWER_SIZE - addr;
+           addr = GRUB_MEMORY_MACHINE_LOWER_SIZE;
+         }
+      }
+
+    if (addr == GRUB_MEMORY_MACHINE_UPPER_START
+       || (addr >= GRUB_MEMORY_MACHINE_LOWER_SIZE
+           && addr <= GRUB_MEMORY_MACHINE_UPPER_START
+           && (addr + size > GRUB_MEMORY_MACHINE_UPPER_START)))
+      {
+       grub_size_t quarter = size >> 2;
+
+       grub_os_area_addr = addr;
+       grub_os_area_size = size - quarter;
+       grub_mm_init_region ((void *) (grub_os_area_addr + grub_os_area_size),
+                            quarter);
+      }
+    else
+      grub_mm_init_region ((void *) (grub_addr_t) addr, (grub_size_t) size);
+
+    return 0;
+  }
+
+#if defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU)
+  grub_machine_mmap_init ();
+#endif
+  grub_machine_mmap_iterate (heap_init);
+
+  grub_tsc_init ();
+}
+
+void
+grub_machine_set_prefix (void)
+{
+  /* Initialize the prefix.  */
+  grub_env_set ("prefix", grub_prefix);
+}
+
+void
+grub_machine_fini (void)
+{
+  grub_vga_text_fini ();
+  grub_stop_floppy ();
+}
+
+/* Return the end of the core image.  */
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+#ifdef GRUB_MACHINE_QEMU
+  return grub_core_entry_addr + grub_kernel_image_size;
+#else
+  return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN);
+#endif
+}
diff --git a/grub-core/kern/i386/coreboot/mmap.c b/grub-core/kern/i386/coreboot/mmap.c
new file mode 100644 (file)
index 0000000..d06627a
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+
+static grub_err_t
+grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t))
+{
+  grub_linuxbios_table_header_t table_header;
+  grub_linuxbios_table_item_t table_item;
+
+  auto int check_signature (grub_linuxbios_table_header_t);
+  int check_signature (grub_linuxbios_table_header_t tbl_header)
+  {
+    if (! grub_memcmp (tbl_header->signature, "LBIO", 4))
+      return 1;
+
+    return 0;
+  }
+
+  /* Assuming table_header is aligned to its size (8 bytes).  */
+
+  for (table_header = (grub_linuxbios_table_header_t) 0x500;
+       table_header < (grub_linuxbios_table_header_t) 0x1000; table_header++)
+    if (check_signature (table_header))
+      goto signature_found;
+
+  for (table_header = (grub_linuxbios_table_header_t) 0xf0000;
+       table_header < (grub_linuxbios_table_header_t) 0x100000; table_header++)
+    if (check_signature (table_header))
+      goto signature_found;
+
+  grub_fatal ("Could not find coreboot table\n");
+
+signature_found:
+
+  table_item =
+    (grub_linuxbios_table_item_t) ((long) table_header +
+                              (long) table_header->size);
+  for (; table_item->size;
+       table_item = (grub_linuxbios_table_item_t) ((long) table_item + (long) table_item->size))
+    {
+      if (table_item->tag == GRUB_LINUXBIOS_MEMBER_LINK
+         && check_signature ((grub_linuxbios_table_header_t) (grub_addr_t)
+                             *(grub_uint64_t *) (table_item + 1)))
+       {
+         table_header = (grub_linuxbios_table_header_t) (grub_addr_t)
+           *(grub_uint64_t *) (table_item + 1);
+         goto signature_found;   
+       }
+      if (hook (table_item))
+       return 1;
+    }
+
+  return 0;
+}
+
+grub_err_t
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
+{
+  mem_region_t mem_region;
+
+  auto int iterate_linuxbios_table (grub_linuxbios_table_item_t);
+  int iterate_linuxbios_table (grub_linuxbios_table_item_t table_item)
+  {
+    if (table_item->tag != GRUB_LINUXBIOS_MEMBER_MEMORY)
+      return 0;
+
+    mem_region =
+      (mem_region_t) ((long) table_item +
+                                sizeof (struct grub_linuxbios_table_item));
+    while ((long) mem_region < (long) table_item + (long) table_item->size)
+      {
+       if (hook (mem_region->addr, mem_region->size,
+                 /* Multiboot mmaps match with the coreboot mmap definition.
+                    Therefore, we can just pass type through.  */
+                 mem_region->type))
+         return 1;
+
+       mem_region++;
+      }
+
+    return 0;
+  }
+
+  grub_linuxbios_table_iterate (iterate_linuxbios_table);
+
+  return 0;
+}
diff --git a/grub-core/kern/i386/coreboot/startup.S b/grub-core/kern/i386/coreboot/startup.S
new file mode 100644 (file)
index 0000000..2c4a941
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/machine/memory.h>
+#include <grub/cpu/linux.h>
+#include <grub/cpu/kernel.h>
+#include <multiboot.h>
+#include <multiboot2.h>
+
+/*
+ * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
+ *       So the first three arguments are passed in %eax, %edx, and %ecx,
+ *       respectively, and if a function has a fixed number of arguments
+ *       and the number if greater than three, the function must return
+ *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
+ */
+
+       .file   "startup.S"
+       .text
+       .globl  start, _start
+start:
+_start:
+       jmp codestart
+
+       /*
+        *  This is a special data area at a fixed offset from the beginning.
+        */
+
+       . = _start + GRUB_KERNEL_CPU_PREFIX
+
+VARIABLE(grub_prefix)
+       /* to be filled by grub-mkimage */
+
+       /*
+        *  Leave some breathing room for the prefix.
+        */
+
+       . = _start + GRUB_KERNEL_CPU_DATA_END
+
+/*
+ *  Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself).
+ */
+       .p2align        2       /* force 4-byte alignment */
+multiboot_header:
+       /* magic */
+       .long   0x1BADB002
+       /* flags */
+       .long   MULTIBOOT_MEMORY_INFO
+       /* checksum */
+       .long   -0x1BADB002 - MULTIBOOT_MEMORY_INFO
+
+codestart:
+#ifdef GRUB_MACHINE_MULTIBOOT
+       cmpl    $MULTIBOOT_BOOTLOADER_MAGIC, %eax
+       jne 0f
+       movl    %ebx, EXT_C(startup_multiboot_info)
+0:
+#endif
+
+       /* initialize the stack */
+       movl $GRUB_MEMORY_MACHINE_PROT_STACK, %esp
+
+       /* jump to the main body of C code */
+       jmp EXT_C(grub_main)
+
+/*
+ *  prot_to_real and associated structures (but NOT real_to_prot, that is
+ *  only needed for BIOS gates).
+ */
+#include "../realmode.S"
+
+/*
+ *  Routines needed by Linux and Multiboot loaders.
+ */
+#include "../loader.S"
diff --git a/grub-core/kern/i386/dl.c b/grub-core/kern/i386/dl.c
new file mode 100644 (file)
index 0000000..5785496
--- /dev/null
@@ -0,0 +1,109 @@
+/* dl-386.c - arch-dependent part of loadable module support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+
+/* Check if EHDR is a valid ELF header.  */
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+
+  /* Check the magic numbers.  */
+  if (e->e_ident[EI_CLASS] != ELFCLASS32
+      || e->e_ident[EI_DATA] != ELFDATA2LSB
+      || e->e_machine != EM_386)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
+
+  return GRUB_ERR_NONE;
+}
+
+/* Relocate symbols.  */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+  Elf_Shdr *s;
+  Elf_Word entsize;
+  unsigned i;
+
+  /* Find a symbol table.  */
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
+
+  entsize = s->sh_entsize;
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_REL)
+      {
+       grub_dl_segment_t seg;
+
+       /* Find the target segment.  */
+       for (seg = mod->segment; seg; seg = seg->next)
+         if (seg->section == s->sh_info)
+           break;
+
+       if (seg)
+         {
+           Elf_Rel *rel, *max;
+
+           for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
+                  max = rel + s->sh_size / s->sh_entsize;
+                rel < max;
+                rel++)
+             {
+               Elf_Word *addr;
+               Elf_Sym *sym;
+
+               if (seg->size < rel->r_offset)
+                 return grub_error (GRUB_ERR_BAD_MODULE,
+                                    "reloc offset is out of the segment");
+
+               addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
+               sym = (Elf_Sym *) ((char *) mod->symtab
+                                    + entsize * ELF_R_SYM (rel->r_info));
+
+               switch (ELF_R_TYPE (rel->r_info))
+                 {
+                 case R_386_32:
+                   *addr += sym->st_value;
+                   break;
+
+                 case R_386_PC32:
+                   *addr += (sym->st_value - (Elf_Word) seg->addr
+                             - rel->r_offset);
+                   break;
+                 }
+             }
+         }
+      }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/kern/i386/efi/init.c b/grub-core/kern/i386/efi/init.c
new file mode 100644 (file)
index 0000000..f73f828
--- /dev/null
@@ -0,0 +1,47 @@
+/* init.c - initialize an x86-based EFI system */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/cache.h>
+#include <grub/kernel.h>
+#include <grub/efi/efi.h>
+#include <grub/i386/tsc.h>
+
+void
+grub_machine_init (void)
+{
+  grub_efi_init ();
+  grub_tsc_init ();
+}
+
+void
+grub_machine_fini (void)
+{
+  grub_efi_fini ();
+}
+
+void
+grub_machine_set_prefix (void)
+{
+  grub_efi_set_prefix ();
+}
diff --git a/grub-core/kern/i386/efi/startup.S b/grub-core/kern/i386/efi/startup.S
new file mode 100644 (file)
index 0000000..5b464ab
--- /dev/null
@@ -0,0 +1,66 @@
+/* startup.S - bootstrap GRUB itself */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/boot.h>
+
+        .file   "startup.S"
+        .text
+        .globl  start, _start
+start:
+_start:
+       jmp codestart
+
+        /*
+         *  Compatibility version number
+         *
+         *  These MUST be at byte offset 6 and 7 of the executable
+         *  DO NOT MOVE !!!
+         */
+        . = _start + 0x6
+        .byte   GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
+
+        /*
+         *  This is a special data area 8 bytes from the beginning.
+         */
+
+        . = _start + 0x8
+
+VARIABLE(grub_prefix)
+       /* to be filled by grub-mkimage */
+
+        /*
+         *  Leave some breathing room for the prefix.
+         */
+
+        . = _start + 0x50
+
+codestart:
+       /*
+        *  EFI_SYSTEM_TABLE * and EFI_HANDLE are passed on the stack.
+        */
+       movl    4(%esp), %eax
+       movl    %eax, EXT_C(grub_efi_image_handle)
+       movl    8(%esp), %eax
+       movl    %eax, EXT_C(grub_efi_system_table)
+       call    EXT_C(grub_main)
+       ret
+
+#include "../realmode.S"
diff --git a/grub-core/kern/i386/halt.c b/grub-core/kern/i386/halt.c
new file mode 100644 (file)
index 0000000..10805e4
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/cpu/io.h>
+#include <grub/machine/init.h>
+#include <grub/misc.h>
+
+const char bochs_shutdown[] = "Shutdown";
+
+void
+grub_halt (void)
+{
+  unsigned int i;
+
+  /* Disable interrupts.  */
+  __asm__ __volatile__ ("cli");
+
+  /* Bochs, QEMU, etc.  */
+  for (i = 0; i < sizeof (bochs_shutdown) - 1; i++)
+    grub_outb (bochs_shutdown[i], 0x8900);
+
+  grub_printf ("GRUB doesn't know how to halt this machine yet!\n");
+
+  /* In order to return we'd have to check what the previous status of IF
+     flag was.  But user most likely doesn't want to return anyway ...  */
+  grub_stop ();
+}
diff --git a/grub-core/kern/i386/ieee1275/init.c b/grub-core/kern/i386/ieee1275/init.c
new file mode 100644 (file)
index 0000000..9fb9873
--- /dev/null
@@ -0,0 +1,28 @@
+/*  init.c -- Initialize GRUB on Open Firmware.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/cache.h>
+
+void grub_stop_floppy (void);
+
+void
+grub_stop_floppy (void)
+{
+}
diff --git a/grub-core/kern/i386/ieee1275/startup.S b/grub-core/kern/i386/ieee1275/startup.S
new file mode 100644 (file)
index 0000000..35258ad
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/machine/memory.h>
+#include <grub/cpu/linux.h>
+#include <grub/cpu/kernel.h>
+#include <multiboot.h>
+#include <multiboot2.h>
+
+/*
+ * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
+ *       So the first three arguments are passed in %eax, %edx, and %ecx,
+ *       respectively, and if a function has a fixed number of arguments
+ *       and the number if greater than three, the function must return
+ *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
+ */
+
+       .file   "startup.S"
+       .text
+       .globl  start, _start
+
+start:
+_start:
+       jmp codestart
+
+       /*
+        *  This is a special data area at a fixed offset from the beginning.
+        */
+
+       . = _start + GRUB_KERNEL_CPU_PREFIX
+
+VARIABLE(grub_prefix)
+       /* to be filled by grub-mkimage */
+
+       /*
+        *  Leave some breathing room for the prefix.
+        */
+
+       . = _start + GRUB_KERNEL_CPU_DATA_END
+
+codestart:
+       movl %eax, EXT_C(grub_ieee1275_entry_fn)
+       jmp EXT_C(grub_main)
+
+/*
+ *  prot_to_real and associated structures (but NOT real_to_prot, that is
+ *  only needed for BIOS gates).
+ */
+#include "../realmode.S"
+
+/*
+ *  Routines needed by Linux and Multiboot loaders.
+ */
+#include "../loader.S"
diff --git a/grub-core/kern/i386/loader.S b/grub-core/kern/i386/loader.S
new file mode 100644 (file)
index 0000000..ed57c43
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/*
+ * Note: These functions defined in this file may be called from C.
+ *       Be careful of that you must not modify some registers. Quote
+ *       from gcc-2.95.2/gcc/config/i386/i386.h:
+
+   1 for registers not available across function calls.
+   These must include the FIXED_REGISTERS and also any
+   registers that can be used without being saved.
+   The latter must include the registers where values are returned
+   and the register where structure-value addresses are passed.
+   Aside from that, you can include as many other registers as you like.
+
+  ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
+{  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
+ */
+
+/*
+ * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
+ *       So the first three arguments are passed in %eax, %edx, and %ecx,
+ *       respectively, and if a function has a fixed number of arguments
+ *       and the number if greater than three, the function must return
+ *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
+ */
+
+/*
+ *  This is the area for all of the special variables.
+ */
+
+       .p2align        2       /* force 4-byte alignment */
+
+/*
+ * void grub_linux_boot_zimage (void)
+ */
+VARIABLE(grub_linux_prot_size)
+       .long   0
+VARIABLE(grub_linux_tmp_addr)
+       .long   0
+VARIABLE(grub_linux_real_addr)
+       .long   0
+VARIABLE(grub_linux_is_bzimage)
+       .long   0
+
+FUNCTION(grub_linux16_real_boot)
+       /* Must be done before zImage copy.  */
+       call    EXT_C(grub_dl_unload_all)
+
+       movl    EXT_C(grub_linux_is_bzimage), %ebx
+       test    %ebx, %ebx
+       jne bzimage
+
+       /* copy the kernel */
+       movl    EXT_C(grub_linux_prot_size), %ecx
+       addl    $3, %ecx
+       shrl    $2, %ecx
+       movl    $GRUB_LINUX_BZIMAGE_ADDR, %esi
+       movl    $GRUB_LINUX_ZIMAGE_ADDR, %edi
+       cld
+       rep
+       movsl
+
+bzimage:
+       movl    EXT_C(grub_linux_real_addr), %ebx
+
+       /* copy the real mode code */
+       movl    EXT_C(grub_linux_tmp_addr), %esi
+       movl    %ebx, %edi
+       movl    $GRUB_LINUX_SETUP_MOVE_SIZE, %ecx
+       cld
+       rep
+       movsb
+
+       /* change %ebx to the segment address */
+       shrl    $4, %ebx
+       movl    %ebx, %eax
+       addl    $0x20, %eax
+       movw    %ax, linux_setup_seg
+
+       /* XXX new stack pointer in safe area for calling functions */
+       movl    $0x4000, %esp
+       call    EXT_C(grub_stop_floppy)
+
+       /* final setup for linux boot */
+       call    prot_to_real
+       .code16
+
+       cli
+       movw    %bx, %ss
+       movw    $GRUB_LINUX_SETUP_STACK, %sp
+
+       movw    %bx, %ds
+       movw    %bx, %es
+       movw    %bx, %fs
+       movw    %bx, %gs
+
+       /* ljmp */
+       .byte   0xea
+       .word   0
+linux_setup_seg:
+       .word   0
+       .code32
+
diff --git a/grub-core/kern/i386/misc.S b/grub-core/kern/i386/misc.S
new file mode 100644 (file)
index 0000000..7d57df9
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+       .text
+/*
+ *  This call is special...  it never returns...  in fact it should simply
+ *  hang at this point!
+ */
+FUNCTION(grub_stop)
+       cli
+1:     hlt
+       jmp     1b
diff --git a/grub-core/kern/i386/multiboot_mmap.c b/grub-core/kern/i386/multiboot_mmap.c
new file mode 100644 (file)
index 0000000..0f463c2
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/types.h>
+#include <grub/multiboot.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+
+grub_size_t grub_lower_mem, grub_upper_mem;
+
+/* A pointer to the MBI in its initial location.  */
+struct multiboot_info *startup_multiboot_info;
+
+/* The MBI has to be copied to our BSS so that it won't be
+   overwritten.  This is its final location.  */
+static struct multiboot_info kern_multiboot_info;
+
+/* Unfortunately we can't use heap at this point.  But 32 looks like a sane
+   limit (used by memtest86).  */
+static grub_uint8_t mmap_entries[sizeof (struct multiboot_mmap_entry) * 32];
+
+void
+grub_machine_mmap_init ()
+{
+  if (! startup_multiboot_info)
+    grub_fatal ("Unable to find Multiboot Information (is CONFIG_MULTIBOOT disabled in coreboot?)");
+
+  /* Move MBI to a safe place.  */
+  grub_memmove (&kern_multiboot_info, startup_multiboot_info, sizeof (struct multiboot_info));
+
+  if ((kern_multiboot_info.flags & MULTIBOOT_INFO_MEM_MAP) == 0)
+    grub_fatal ("Missing Multiboot memory information");
+
+  /* Move the memory map to a safe place.  */
+  if (kern_multiboot_info.mmap_length > sizeof (mmap_entries))
+    {
+      grub_printf ("WARNING: Memory map size exceeds limit (0x%x > 0x%x); it will be truncated\n",
+                  kern_multiboot_info.mmap_length, sizeof (mmap_entries));
+      kern_multiboot_info.mmap_length = sizeof (mmap_entries);
+    }
+  grub_memmove (mmap_entries, (void *) kern_multiboot_info.mmap_addr, kern_multiboot_info.mmap_length);
+  kern_multiboot_info.mmap_addr = (grub_uint32_t) mmap_entries;
+
+  if ((kern_multiboot_info.flags & MULTIBOOT_INFO_MEMORY) == 0)
+    {
+      grub_lower_mem = GRUB_MEMORY_MACHINE_LOWER_USABLE;
+      grub_upper_mem = 0;
+    }
+  else
+    {
+      grub_lower_mem = kern_multiboot_info.mem_lower * 1024;
+      grub_upper_mem = kern_multiboot_info.mem_upper * 1024;
+    }
+}
+
+grub_err_t
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
+{
+  struct multiboot_mmap_entry *entry = (void *) kern_multiboot_info.mmap_addr;
+
+  while ((unsigned long) entry < kern_multiboot_info.mmap_addr + kern_multiboot_info.mmap_length)
+    {
+      if (hook (entry->addr, entry->len, entry->type))
+       break;
+
+      entry = (void *) ((grub_addr_t) entry + entry->size + sizeof (entry->size));
+    }
+
+  return 0;
+}
diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c
new file mode 100644 (file)
index 0000000..fa646df
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/mm.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/console.h>
+#include <grub/machine/kernel.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/loader.h>
+#include <grub/env.h>
+#include <grub/cache.h>
+#include <grub/time.h>
+#include <grub/cpu/tsc.h>
+
+struct mem_region
+{
+  grub_addr_t addr;
+  grub_size_t size;
+};
+
+#define MAX_REGIONS    32
+
+static struct mem_region mem_regions[MAX_REGIONS];
+static int num_regions;
+
+grub_addr_t grub_os_area_addr;
+grub_size_t grub_os_area_size;
+
+static char *
+make_install_device (void)
+{
+  /* XXX: This should be enough.  */
+  char dev[100], *ptr = dev;
+
+  if (grub_prefix[0] != '(')
+    {
+      /* No hardcoded root partition - make it from the boot drive and the
+        partition number encoded at the install time.  */
+      if (grub_boot_drive == GRUB_BOOT_MACHINE_PXE_DL)
+       {
+         grub_strcpy (dev, "(pxe");
+         ptr += sizeof ("(pxe") - 1;
+       }
+      else
+       {
+         grub_snprintf (dev, sizeof (dev),
+                        "(%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f',
+                        grub_boot_drive & 0x7f);
+         ptr += grub_strlen (ptr);
+
+         if (grub_install_dos_part >= 0)
+           grub_snprintf (ptr, sizeof (dev) - (ptr - dev),
+                          ",%u", grub_install_dos_part + 1);
+         ptr += grub_strlen (ptr);
+
+         if (grub_install_bsd_part >= 0)
+           grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%c",
+                          grub_install_bsd_part + 'a');
+         ptr += grub_strlen (ptr);
+       }
+
+      grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ")%s", grub_prefix);
+      grub_strcpy (grub_prefix, dev);
+    }
+
+  return grub_prefix;
+}
+
+/* Add a memory region.  */
+static void
+add_mem_region (grub_addr_t addr, grub_size_t size)
+{
+  if (num_regions == MAX_REGIONS)
+    /* Ignore.  */
+    return;
+
+  mem_regions[num_regions].addr = addr;
+  mem_regions[num_regions].size = size;
+  num_regions++;
+}
+
+/* Compact memory regions.  */
+static void
+compact_mem_regions (void)
+{
+  int i, j;
+
+  /* Sort them.  */
+  for (i = 0; i < num_regions - 1; i++)
+    for (j = i + 1; j < num_regions; j++)
+      if (mem_regions[i].addr > mem_regions[j].addr)
+       {
+         struct mem_region tmp = mem_regions[i];
+         mem_regions[i] = mem_regions[j];
+         mem_regions[j] = tmp;
+       }
+
+  /* Merge overlaps.  */
+  for (i = 0; i < num_regions - 1; i++)
+    if (mem_regions[i].addr + mem_regions[i].size >= mem_regions[i + 1].addr)
+      {
+       j = i + 1;
+
+       if (mem_regions[i].addr + mem_regions[i].size
+           < mem_regions[j].addr + mem_regions[j].size)
+         mem_regions[i].size = (mem_regions[j].addr + mem_regions[j].size
+                                - mem_regions[i].addr);
+
+       grub_memmove (mem_regions + j, mem_regions + j + 1,
+                     (num_regions - j - 1) * sizeof (struct mem_region));
+       i--;
+        num_regions--;
+      }
+}
+
+void
+grub_machine_init (void)
+{
+  int i;
+  int grub_lower_mem;
+
+  /* Initialize the console as early as possible.  */
+  grub_console_init ();
+
+  grub_lower_mem = grub_get_memsize (0) << 10;
+
+  /* Sanity check.  */
+  if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END)
+    grub_fatal ("too small memory");
+
+#if 0
+  /* Turn on Gate A20 to access >1MB.  */
+  grub_gate_a20 (1);
+#endif
+
+/* FIXME: This prevents loader/i386/linux.c from using low memory.  When our
+   heap implements support for requesting a chunk in low memory, this should
+   no longer be a problem.  */
+#if 0
+  /* Add the lower memory into free memory.  */
+  if (grub_lower_mem >= GRUB_MEMORY_MACHINE_RESERVED_END)
+    add_mem_region (GRUB_MEMORY_MACHINE_RESERVED_END,
+                   grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END);
+#endif
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      /* Avoid the lower memory.  */
+      if (addr < 0x100000)
+       {
+         if (size <= 0x100000 - addr)
+           return 0;
+
+         size -= 0x100000 - addr;
+         addr = 0x100000;
+       }
+
+      /* Ignore >4GB.  */
+      if (addr <= 0xFFFFFFFF && type == GRUB_MACHINE_MEMORY_AVAILABLE)
+       {
+         grub_size_t len;
+
+         len = (grub_size_t) ((addr + size > 0xFFFFFFFF)
+                ? 0xFFFFFFFF - addr
+                : size);
+         add_mem_region (addr, len);
+       }
+
+      return 0;
+    }
+
+  grub_machine_mmap_iterate (hook);
+
+  compact_mem_regions ();
+
+  /* Add the memory regions to free memory, except for the region starting
+     from 1MB. This region is partially used for loading OS images.
+     For now, 1/4 of this is added to free memory.  */
+  for (i = 0; i < num_regions; i++)
+    if (mem_regions[i].addr == 0x100000)
+      {
+       grub_size_t quarter = mem_regions[i].size >> 2;
+
+       grub_os_area_addr = mem_regions[i].addr;
+       grub_os_area_size = mem_regions[i].size - quarter;
+       grub_mm_init_region ((void *) (grub_os_area_addr + grub_os_area_size),
+                            quarter);
+      }
+    else
+      grub_mm_init_region ((void *) mem_regions[i].addr, mem_regions[i].size);
+
+  if (! grub_os_area_addr)
+    grub_fatal ("no upper memory");
+
+  grub_tsc_init ();
+}
+
+void
+grub_machine_set_prefix (void)
+{
+  /* Initialize the prefix.  */
+  grub_env_set ("prefix", make_install_device ());
+}
+
+void
+grub_machine_fini (void)
+{
+  grub_console_fini ();
+  grub_stop_floppy ();
+}
+
+/* Return the end of the core image.  */
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+  return GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR
+    + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE);
+}
diff --git a/grub-core/kern/i386/pc/lzma_decode.S b/grub-core/kern/i386/pc/lzma_decode.S
new file mode 100644 (file)
index 0000000..a5a8684
--- /dev/null
@@ -0,0 +1,677 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define FIXED_PROPS
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+#define kNumTopBits 24
+#define kTopValue (1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+
+#if 0
+
+DbgOut:
+       pushf
+       pushl   %ebp
+       pushl   %edi
+       pushl   %esi
+       pushl   %edx
+       pushl   %ecx
+       pushl   %ebx
+       pushl   %eax
+
+       call    _DebugPrint
+
+       popl    %eax
+       popl    %ebx
+       popl    %ecx
+       popl    %edx
+       popl    %esi
+       popl    %edi
+       popl    %ebp
+       popf
+
+       ret
+
+
+/*
+ * int LzmaDecodeProperties(CLzmaProperties *propsRes,
+ *                          const unsigned char *propsData,
+ *                          int size);
+ */
+
+_LzmaDecodePropertiesA:
+       movb    (%edx), %dl
+
+       xorl    %ecx, %ecx
+1:
+       cmpb    $45, %dl
+       jb      2f
+       incl    %ecx
+       subb    $45, %dl
+       jmp     1b
+2:
+       movl    %ecx, 8(%eax)           /* pb */
+       xorl    %ecx, %ecx
+1:
+       cmpb    $9, %dl
+       jb      2f
+       incl    %ecx
+       subb    $9, %dl
+2:
+       movl    %ecx, 4(%eax)           /* lp */
+       movb    %dl, %cl
+       movl    %ecx, (%eax)            /* lc */
+
+#endif
+
+#ifndef ASM_FILE
+       xorl    %eax, %eax
+#endif
+       ret
+
+#define out_size       8(%ebp)
+
+#define now_pos                -4(%ebp)
+#define prev_byte      -8(%ebp)
+#define range          -12(%ebp)
+#define code           -16(%ebp)
+#define state          -20(%ebp)
+#define rep0           -24(%ebp)
+#define rep1           -28(%ebp)
+#define rep2           -32(%ebp)
+#define rep3           -36(%ebp)
+
+#ifdef FIXED_PROPS
+
+#define FIXED_LC       3
+#define FIXED_LP       0
+#define FIXED_PB       2
+
+#define POS_STATE_MASK ((1 << (FIXED_PB)) - 1)
+#define LIT_POS_MASK   ((1 << (FIXED_LP)) - 1)
+
+#define LOCAL_SIZE     36
+
+#else
+
+#define lc             (%ebx)
+#define lp             4(%ebx)
+#define pb             8(%ebx)
+#define probs          12(%ebx)
+
+#define pos_state_mask -40(%ebp)
+#define lit_pos_mask   -44(%ebp)
+
+#define LOCAL_SIZE     44
+
+#endif
+
+RangeDecoderBitDecode:
+#ifdef FIXED_PROPS
+       leal    (%ebx, %eax, 4), %eax
+#else
+       shll    $2, %eax
+       addl    probs, %eax
+#endif
+
+       movl    %eax, %ecx
+       movl    (%ecx), %eax
+
+       movl    range, %edx
+       shrl    $kNumBitModelTotalBits, %edx
+       mull    %edx
+
+       cmpl    code, %eax
+       jbe     1f
+
+       movl    %eax, range
+       movl    $kBitModelTotal, %edx
+       subl    (%ecx), %edx
+       shrl    $kNumMoveBits, %edx
+       addl    %edx, (%ecx)
+       clc
+3:
+       pushf
+       cmpl    $kTopValue, range
+       jnc     2f
+       shll    $8, code
+       lodsb
+       movb    %al, code
+       shll    $8, range
+2:
+       popf
+       ret
+1:
+       subl    %eax, range
+       subl    %eax, code
+       movl    (%ecx), %edx
+       shrl    $kNumMoveBits, %edx
+       subl    %edx, (%ecx)
+       stc
+       jmp     3b
+
+RangeDecoderBitTreeDecode:
+RangeDecoderReverseBitTreeDecode:
+       movzbl  %cl, %ecx
+       xorl    %edx, %edx
+       pushl   %edx
+       incl    %edx
+       pushl   %edx
+
+1:
+       pushl   %eax
+       pushl   %ecx
+       pushl   %edx
+
+       addl    %edx, %eax
+       call    RangeDecoderBitDecode
+
+       popl    %edx
+       popl    %ecx
+
+       jnc     2f
+       movl    4(%esp), %eax
+       orl     %eax, 8(%esp)
+       stc
+
+2:
+       adcl    %edx, %edx
+       popl    %eax
+
+       shll    $1, (%esp)
+       loop    1b
+
+       popl    %ecx
+       subl    %ecx, %edx              /* RangeDecoderBitTreeDecode */
+       popl    %ecx                    /* RangeDecoderReverseBitTreeDecode */
+       ret
+
+LzmaLenDecode:
+       pushl   %eax
+       addl    $LenChoice, %eax
+       call    RangeDecoderBitDecode
+       popl    %eax
+       jc      1f
+       pushl   $0
+       movb    $kLenNumLowBits, %cl
+       addl    $LenLow, %eax
+2:
+       movl    12(%esp), %edx
+       shll    %cl, %edx
+       addl    %edx, %eax
+3:
+
+       call    RangeDecoderBitTreeDecode
+       popl    %eax
+       addl    %eax, %edx
+       ret
+
+1:
+       pushl   %eax
+       addl    $LenChoice2, %eax
+       call    RangeDecoderBitDecode
+       popl    %eax
+       jc      1f
+       pushl   $kLenNumLowSymbols
+       movb    $kLenNumMidBits, %cl
+       addl    $LenMid, %eax
+       jmp     2b
+
+1:
+       pushl   $(kLenNumLowSymbols + kLenNumMidSymbols)
+       addl    $LenHigh, %eax
+       movb    $kLenNumHighBits, %cl
+       jmp     3b
+
+WriteByte:
+       movb    %al, prev_byte
+       stosb
+       incl    now_pos
+       ret
+
+/*
+ * int LzmaDecode(CLzmaDecoderState *vs,
+ *                const unsigned char *inStream,
+ *                unsigned char *outStream,
+ *                SizeT outSize);
+ */
+
+_LzmaDecodeA:
+
+       pushl   %ebp
+       movl    %esp, %ebp
+       subl    $LOCAL_SIZE, %esp
+
+#ifndef ASM_FILE
+       pushl   %esi
+       pushl   %edi
+       pushl   %ebx
+
+       movl    %eax, %ebx
+       movl    %edx, %esi
+       pushl   %ecx
+#else
+       pushl   %edi
+#endif
+
+       cld
+
+#ifdef FIXED_PROPS
+       movl    %ebx, %edi
+       movl    $(Literal + (LZMA_LIT_SIZE << (FIXED_LC + FIXED_LP))), %ecx
+#else
+       movl    $LZMA_LIT_SIZE, %eax
+       movb    lc, %cl
+       addb    lp, %cl
+       shll    %cl, %eax
+       addl    $Literal, %eax
+       movl    %eax, %ecx
+       movl    probs, %edi
+#endif
+
+       movl    $(kBitModelTotal >> 1), %eax
+
+       rep
+       stosl
+
+       popl    %edi
+
+       xorl    %eax, %eax
+       movl    %eax, now_pos
+       movl    %eax, prev_byte
+       movl    %eax, state
+
+       incl    %eax
+       movl    %eax, rep0
+       movl    %eax, rep1
+       movl    %eax, rep2
+       movl    %eax, rep3
+
+#ifndef FIXED_PROPS
+       movl    %eax, %edx
+       movb    pb, %cl
+       shll    %cl, %edx
+       decl    %edx
+       movl    %edx, pos_state_mask
+
+       movl    %eax, %edx
+       movb    lp, %cl
+       shll    %cl, %edx
+       decl    %edx
+       movl    %edx, lit_pos_mask;
+#endif
+
+       /* RangeDecoderInit */
+       negl    %eax
+       movl    %eax, range
+
+       incl    %eax
+       movb    $5, %cl
+
+1:
+       shll    $8, %eax
+       lodsb
+       loop    1b
+
+       movl    %eax, code
+
+lzma_decode_loop:
+       movl    now_pos, %eax
+       cmpl    out_size, %eax
+
+       jb      1f
+
+#ifndef ASM_FILE
+       xorl    %eax, %eax
+
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+#endif
+
+       movl    %ebp, %esp
+       popl    %ebp
+       ret
+
+1:
+#ifdef FIXED_PROPS
+       andl    $POS_STATE_MASK, %eax
+#else
+       andl    pos_state_mask, %eax
+#endif
+       pushl   %eax                            /* posState */
+       movl    state, %edx
+       shll    $kNumPosBitsMax, %edx
+       addl    %edx, %eax
+       pushl   %eax                            /* (state << kNumPosBitsMax) + posState */
+
+       call    RangeDecoderBitDecode
+       jc      1f
+
+       movl    now_pos, %eax
+
+#ifdef FIXED_PROPS
+       andl    $LIT_POS_MASK, %eax
+       shll    $FIXED_LC, %eax
+       movl    prev_byte, %edx
+       shrl    $(8 - FIXED_LC), %edx
+#else
+       andl    lit_pos_mask, %eax
+       movb    lc, %cl
+       shll    %cl, %eax
+       negb    %cl
+       addb    $8, %cl
+       movl    prev_byte, %edx
+       shrl    %cl, %edx
+#endif
+
+       addl    %edx, %eax
+       movl    $LZMA_LIT_SIZE, %edx
+       mull    %edx
+       addl    $Literal, %eax
+       pushl   %eax
+
+       incl    %edx                    /* edx = 1 */
+
+       movl    rep0, %eax
+       negl    %eax
+       pushl   (%edi, %eax)            /* matchByte */
+
+       cmpb    $kNumLitStates, state
+       jb      5f
+
+       /* LzmaLiteralDecodeMatch */
+
+3:
+       cmpl    $0x100, %edx
+       jae     4f
+
+       xorl    %eax, %eax
+       shlb    $1, (%esp)
+       adcl    %eax, %eax
+
+       pushl   %eax
+       pushl   %edx
+
+       shll    $8, %eax
+       leal    0x100(%edx, %eax), %eax
+       addl    12(%esp), %eax
+       call    RangeDecoderBitDecode
+
+       setc    %al
+       popl    %edx
+       adcl    %edx, %edx
+
+       popl    %ecx
+       cmpb    %cl, %al
+       jz      3b
+
+5:
+
+       /* LzmaLiteralDecode */
+
+       cmpl    $0x100, %edx
+       jae     4f
+
+       pushl   %edx
+       movl    %edx, %eax
+       addl    8(%esp), %eax
+       call    RangeDecoderBitDecode
+       popl    %edx
+       adcl    %edx, %edx
+       jmp     5b
+
+4:
+       addl    $16, %esp
+
+       movb    %dl, %al
+       call    WriteByte
+
+       movb    state, %al
+       cmpb    $4, %al
+       jae     2f
+       xorb    %al, %al
+       jmp     3f
+2:
+       subb    $3, %al
+       cmpb    $7, %al
+       jb      3f
+       subb    $3, %al
+3:
+       movb    %al, state
+       jmp     lzma_decode_loop
+
+1:
+       movl    state, %eax
+       addl    $IsRep, %eax
+       call    RangeDecoderBitDecode
+       jnc     1f
+
+       movl    state, %eax
+       addl    $IsRepG0, %eax
+       call    RangeDecoderBitDecode
+       jc      10f
+
+       movl    (%esp), %eax
+       addl    $IsRep0Long, %eax
+       call    RangeDecoderBitDecode
+       jc      20f
+
+       cmpb    $7, state
+       movb    $9, state
+       jb      100f
+       addb    $2, state
+100:
+
+       movl    $1, %ecx
+
+3:
+       movl    rep0, %edx
+       negl    %edx
+
+4:
+       movb    (%edi, %edx), %al
+       call    WriteByte
+       loop    4b
+
+       popl    %eax
+       popl    %eax
+       jmp     lzma_decode_loop
+
+10:
+       movl    state, %eax
+       addl    $IsRepG1, %eax
+       call    RangeDecoderBitDecode
+       movl    rep1, %edx
+       jnc     100f
+
+       movl    state, %eax
+       addl    $IsRepG2, %eax
+       call    RangeDecoderBitDecode
+       movl    rep2, %edx
+       jnc     1000f
+       movl    rep2, %edx
+       xchgl   rep3, %edx
+1000:
+       pushl   rep1
+       popl    rep2
+100:
+       xchg    rep0, %edx
+       movl    %edx, rep1
+20:
+
+       movl    $RepLenCoder, %eax
+       call    LzmaLenDecode
+
+       cmpb    $7, state
+       movb    $8, state
+       jb      100f
+       addb    $3, state
+100:
+       jmp     2f
+
+1:
+       movl    rep0, %eax
+       xchgl   rep1, %eax
+       xchgl   rep2, %eax
+       movl    %eax, rep3
+
+       cmpb    $7, state
+       movb    $7, state
+       jb      10f
+       addb    $3, state
+10:
+
+       movl    $LenCoder, %eax
+       call    LzmaLenDecode
+       pushl   %edx
+
+       movl    $(kNumLenToPosStates - 1), %eax
+       cmpl    %eax, %edx
+       jbe     100f
+       movl    %eax, %edx
+100:
+       movb    $kNumPosSlotBits, %cl
+       shll    %cl, %edx
+       leal    PosSlot(%edx), %eax
+       call    RangeDecoderBitTreeDecode
+
+       movl    %edx, rep0
+       cmpl    $kStartPosModelIndex, %edx
+       jb      100f
+
+       movl    %edx, %ecx
+       shrl    $1, %ecx
+       decl    %ecx
+
+       movzbl  %dl, %eax
+       andb    $1, %al
+       orb     $2, %al
+       shll    %cl, %eax
+       movl    %eax, rep0
+
+       cmpl    $kEndPosModelIndex, %edx
+       jae     200f
+       movl    rep0, %eax
+       addl    $(SpecPos - 1), %eax
+       subl    %edx, %eax
+       jmp     300f
+200:
+
+       subb    $kNumAlignBits, %cl
+
+       /* RangeDecoderDecodeDirectBits */
+       xorl    %edx, %edx
+
+1000:
+       shrl    $1, range
+       shll    $1, %edx
+
+       movl    range, %eax
+       cmpl    %eax, code
+       jb      2000f
+       subl    %eax, code
+       orb     $1, %dl
+2000:
+
+       cmpl    $kTopValue, %eax
+       jae     3000f
+       shll    $8, range
+       shll    $8, code
+       lodsb
+       movb    %al, code
+
+3000:
+       loop    1000b
+
+       movb    $kNumAlignBits, %cl
+       shll    %cl, %edx
+       addl    %edx, rep0
+
+       movl    $Align, %eax
+
+300:
+       call    RangeDecoderReverseBitTreeDecode
+       addl    %ecx, rep0
+
+100:
+       incl    rep0
+       popl    %edx
+
+2:
+
+       addl    $kMatchMinLen, %edx
+       movl    %edx, %ecx
+
+       jmp     3b
diff --git a/grub-core/kern/i386/pc/mmap.c b/grub-core/kern/i386/pc/mmap.c
new file mode 100644 (file)
index 0000000..52d8fd5
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/err.h>
+#include <grub/types.h>
+
+grub_err_t
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
+{
+  grub_uint32_t cont;
+  struct grub_machine_mmap_entry *entry
+    = (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+
+  /* Check if grub_get_mmap_entry works.  */
+  cont = grub_get_mmap_entry (entry, 0);
+
+  if (entry->size)
+    do
+      {
+       if (hook (entry->addr, entry->len,
+                 /* Multiboot mmaps have been defined to match with the E820 definition.
+                    Therefore, we can just pass type through.  */
+                 entry->type))
+         break;
+
+       if (! cont)
+         break;
+
+       cont = grub_get_mmap_entry (entry, cont);
+      }
+    while (entry->size);
+  else
+    {
+      grub_uint32_t eisa_mmap = grub_get_eisa_mmap ();
+
+      if (eisa_mmap)
+       {
+         if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10, GRUB_MACHINE_MEMORY_AVAILABLE) == 0)
+           hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MACHINE_MEMORY_AVAILABLE);
+       }
+      else
+       hook (0x100000, grub_get_memsize (1) << 10, GRUB_MACHINE_MEMORY_AVAILABLE);
+    }
+
+  return 0;
+}
diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S
new file mode 100644 (file)
index 0000000..3742777
--- /dev/null
@@ -0,0 +1,2074 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/*
+ * Note: These functions defined in this file may be called from C.
+ *       Be careful of that you must not modify some registers. Quote
+ *       from gcc-2.95.2/gcc/config/i386/i386.h:
+
+   1 for registers not available across function calls.
+   These must include the FIXED_REGISTERS and also any
+   registers that can be used without being saved.
+   The latter must include the registers where values are returned
+   and the register where structure-value addresses are passed.
+   Aside from that, you can include as many other registers as you like.
+
+  ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
+{  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
+ */
+
+/*
+ * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
+ *       So the first three arguments are passed in %eax, %edx, and %ecx,
+ *       respectively, and if a function has a fixed number of arguments
+ *       and the number is greater than three, the function must return
+ *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/boot.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/console.h>
+#include <grub/cpu/linux.h>
+#include <grub/machine/kernel.h>
+#include <grub/term.h>
+#include <multiboot.h>
+#include <multiboot2.h>
+
+#define ABS(x) ((x) - LOCAL (base) + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200)
+
+       .file   "startup.S"
+
+       .text
+
+       /* Tell GAS to generate 16-bit instructions so that this code works
+          in real mode. */
+       .code16
+
+       .globl  start, _start
+start:
+_start:
+LOCAL (base):
+       /*
+        *  Guarantee that "main" is loaded at 0x0:0x8200.
+        */
+#ifdef __APPLE__
+       ljmp $0, $(ABS(LOCAL (codestart)) - 0x10000)
+#else
+       ljmp $0, $ABS(LOCAL (codestart))
+#endif
+       /*
+        *  Compatibility version number
+        *
+        *  These MUST be at byte offset 6 and 7 of the executable
+        *  DO NOT MOVE !!!
+        */
+       . = _start + 0x6
+       .byte   GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
+
+       /*
+        *  This is a special data area 8 bytes from the beginning.
+        */
+
+       . = _start + 0x8
+
+VARIABLE(grub_total_module_size)
+       .long   0
+VARIABLE(grub_kernel_image_size)
+       .long   0
+VARIABLE(grub_compressed_size)
+       .long   0
+VARIABLE(grub_install_dos_part)
+       .long   0xFFFFFFFF
+VARIABLE(grub_install_bsd_part)
+       .long   0xFFFFFFFF
+VARIABLE(grub_prefix)
+       /* to be filled by grub-mkimage */
+
+       /*
+        *  Leave some breathing room for the prefix.
+        */
+
+       . = _start + GRUB_KERNEL_MACHINE_DATA_END
+
+#ifdef APPLE_CC
+bss_start:
+       .long 0
+bss_end:
+       .long 0
+#endif
+
+/*
+ * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself).
+ * This uses the a.out kludge to load raw binary to the area starting at 1MB,
+ * and relocates itself after loaded.
+ */
+       .p2align        2       /* force 4-byte alignment */
+multiboot_header:
+       /* magic */
+       .long   0x1BADB002
+       /* flags */
+       .long   (1 << 16)
+       /* checksum */
+       .long   -0x1BADB002 - (1 << 16)
+       /* header addr */
+       .long   multiboot_header - _start + 0x100000 + 0x200
+       /* load addr */
+       .long   0x100000
+       /* load end addr */
+       .long   0
+       /* bss end addr */
+       .long   0
+       /* entry addr */
+       .long   multiboot_entry - _start + 0x100000 + 0x200
+
+multiboot_entry:
+       .code32
+       /* obtain the boot device */
+       movl    12(%ebx), %edx
+
+       movl    $GRUB_MEMORY_MACHINE_PROT_STACK, %ebp
+       movl    %ebp, %esp
+
+       /* relocate the code */
+       movl    $(GRUB_KERNEL_MACHINE_RAW_SIZE + 0x200), %ecx
+       addl    EXT_C(grub_compressed_size) - _start + 0x100000 + 0x200, %ecx
+       movl    $0x100000, %esi
+       movl    $GRUB_BOOT_MACHINE_KERNEL_ADDR, %edi
+       cld
+       rep
+       movsb
+       /* jump to the real address */
+       movl    $multiboot_trampoline, %eax
+       jmp     *%eax
+
+multiboot_trampoline:
+       /* fill the boot information */
+       movl    %edx, %eax
+       shrl    $8, %eax
+       xorl    %ebx, %ebx
+       cmpb    $0xFF, %ah
+       je      1f
+       movb    %ah, %bl
+       movl    %ebx, EXT_C(grub_install_dos_part)
+1:
+       cmpb    $0xFF, %al
+       je      2f
+       movb    %al, %bl
+       movl    %ebx, EXT_C(grub_install_bsd_part)
+2:
+       shrl    $24, %edx
+        movb    $0xFF, %dh
+       /* enter the usual booting */
+       call    prot_to_real
+       .code16
+
+/* the real mode code continues... */
+LOCAL (codestart):
+       cli             /* we're not safe here! */
+
+       /* set up %ds, %ss, and %es */
+       xorw    %ax, %ax
+       movw    %ax, %ds
+       movw    %ax, %ss
+       movw    %ax, %es
+
+       /* set up the real mode/BIOS stack */
+       movl    $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp
+       movl    %ebp, %esp
+
+       sti             /* we're safe again */
+
+       /* save the boot drive */
+       ADDR32  movb    %dl, EXT_C(grub_boot_drive)
+
+       /* reset disk system (%ah = 0) */
+       int     $0x13
+
+       /* transition to protected mode */
+       DATA32  call real_to_prot
+
+       /* The ".code32" directive takes GAS out of 16-bit mode. */
+       .code32
+
+       incl    %eax
+       call    EXT_C(grub_gate_a20)
+
+#ifdef ENABLE_LZMA
+       movl    $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi
+       movl    $(_start + GRUB_KERNEL_MACHINE_RAW_SIZE), %esi
+       pushl   %edi
+       pushl   %esi
+       movl    EXT_C(grub_kernel_image_size), %ecx
+       addl    EXT_C(grub_total_module_size), %ecx
+       subl    $GRUB_KERNEL_MACHINE_RAW_SIZE, %ecx
+       pushl   %ecx
+       leal    (%edi, %ecx), %ebx
+       call    _LzmaDecodeA
+       /* _LzmaDecodeA clears DF, so no need to run cld */
+       popl    %ecx
+       popl    %edi
+       popl    %esi
+#endif
+
+       /* copy back the decompressed part (except the modules) */
+       subl    EXT_C(grub_total_module_size), %ecx
+       rep
+       movsb
+
+#if 0
+       /* copy modules before cleaning out the bss */
+       movl    EXT_C(grub_total_module_size), %ecx
+       movl    EXT_C(grub_kernel_image_size), %esi
+       addl    %ecx, %esi
+       addl    $_start, %esi
+       decl    %esi
+       movl    $END_SYMBOL, %edi
+       addl    %ecx, %edi
+       decl    %edi
+       std
+       rep
+       movsb
+#endif
+
+#ifdef APPLE_CC
+       /* clean out the bss */
+       bss_start_abs = ABS (bss_start)
+       bss_end_abs = ABS (bss_end)
+
+       movl    bss_start_abs, %edi
+
+       /* compute the bss length */
+       movl    bss_end_abs, %ecx
+       subl    %edi, %ecx
+#else
+       /* clean out the bss */
+       movl    $BSS_START_SYMBOL, %edi
+
+       /* compute the bss length */
+       movl    $END_SYMBOL, %ecx
+       subl    %edi, %ecx
+#endif
+
+       /* clean out */
+       xorl    %eax, %eax
+       cld
+       rep
+       stosb
+
+       /*
+        *  Call the start of main body of C code.
+        */
+       call EXT_C(grub_main)
+
+/*
+ *  This is the area for all of the special variables.
+ */
+
+VARIABLE(grub_boot_drive)
+       .byte   0
+
+       .p2align        2       /* force 4-byte alignment */
+
+#include "../realmode.S"
+
+/*
+ * grub_gate_a20(int on)
+ *
+ * Gate address-line 20 for high memory.
+ *
+ * This routine is probably overconservative in what it does, but so what?
+ *
+ * It also eats any keystrokes in the keyboard buffer.  :-(
+ */
+
+FUNCTION(grub_gate_a20)
+       movl    %eax, %edx
+
+gate_a20_test_current_state:
+       /* first of all, test if already in a good state */
+       call    gate_a20_check_state
+       cmpb    %al, %dl
+       jnz     gate_a20_try_bios
+       ret
+
+gate_a20_try_bios:
+       /* second, try a BIOS call */
+       pushl   %ebp
+       call    prot_to_real
+
+       .code16
+       movw    $0x2400, %ax
+       testb   %dl, %dl
+       jz      1f
+       incw    %ax
+1:     int     $0x15
+
+       DATA32  call    real_to_prot
+       .code32
+
+       popl    %ebp
+       call    gate_a20_check_state
+       cmpb    %al, %dl
+       jnz     gate_a20_try_system_control_port_a
+       ret
+
+gate_a20_try_system_control_port_a:
+       /*
+        * In macbook, the keyboard test would hang the machine, so we move
+        * this forward.
+        */
+       /* fourth, try the system control port A */
+       inb     $0x92
+       andb    $(~0x03), %al
+       testb   %dl, %dl
+       jz      6f
+       orb     $0x02, %al
+6:     outb    $0x92
+
+       /* When turning off Gate A20, do not check the state strictly,
+          because a failure is not fatal usually, and Gate A20 is always
+          on some modern machines.  */
+       testb   %dl, %dl
+       jz      7f
+       call    gate_a20_check_state
+       cmpb    %al, %dl
+       jnz     gate_a20_try_keyboard_controller
+7:     ret
+
+gate_a20_flush_keyboard_buffer:
+       inb     $0x64
+       andb    $0x02, %al
+       jnz     gate_a20_flush_keyboard_buffer
+2:
+       inb     $0x64
+       andb    $0x01, %al
+       jz      3f
+       inb     $0x60
+       jmp     2b
+3:
+       ret
+
+gate_a20_try_keyboard_controller:
+       /* third, try the keyboard controller */
+       call    gate_a20_flush_keyboard_buffer
+
+       movb    $0xd1, %al
+       outb    $0x64
+4:
+       inb     $0x64
+       andb    $0x02, %al
+       jnz     4b
+
+       movb    $0xdd, %al
+       testb   %dl, %dl
+       jz      5f
+       orb     $0x02, %al
+5:     outb    $0x60
+       call    gate_a20_flush_keyboard_buffer
+
+       /* output a dummy command (USB keyboard hack) */
+       movb    $0xff, %al
+       outb    $0x64
+       call    gate_a20_flush_keyboard_buffer
+
+       call    gate_a20_check_state
+       cmpb    %al, %dl
+       /* everything failed, so restart from the beginning */
+       jnz     gate_a20_try_bios
+       ret
+
+gate_a20_check_state:
+       /* iterate the checking for a while */
+       movl    $100, %ecx
+1:
+       call    3f
+       cmpb    %al, %dl
+       jz      2f
+       loop    1b
+2:
+       ret
+3:
+       pushl   %ebx
+       pushl   %ecx
+       xorl    %eax, %eax
+       /* compare the byte at 0x8000 with that at 0x108000 */
+       movl    $GRUB_BOOT_MACHINE_KERNEL_ADDR, %ebx
+       pushl   %ebx
+       /* save the original byte in CL */
+       movb    (%ebx), %cl
+       /* store the value at 0x108000 in AL */
+       addl    $0x100000, %ebx
+       movb    (%ebx), %al
+       /* try to set one less value at 0x8000 */
+       popl    %ebx
+       movb    %al, %ch
+       decb    %ch
+       movb    %ch, (%ebx)
+       /* serialize */
+       outb    %al, $0x80
+       outb    %al, $0x80
+       /* obtain the value at 0x108000 in CH */
+       pushl   %ebx
+       addl    $0x100000, %ebx
+       movb    (%ebx), %ch
+       /* this result is 1 if A20 is on or 0 if it is off */
+       subb    %ch, %al
+       xorb    $1, %al
+       /* restore the original */
+       popl    %ebx
+       movb    %cl, (%ebx)
+       popl    %ecx
+       popl    %ebx
+       ret
+
+#ifdef ENABLE_LZMA
+#include "lzma_decode.S"
+#endif
+
+/*
+ * The code beyond this point is compressed.  Assert that the uncompressed
+ * code fits GRUB_KERNEL_MACHINE_RAW_SIZE.
+ */
+       . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE
+
+       /*
+        * This next part is sort of evil.  It takes advantage of the
+        * byte ordering on the x86 to work in either 16-bit or 32-bit
+        * mode, so think about it before changing it.
+        */
+
+FUNCTION(grub_hard_stop)
+       hlt
+       jmp EXT_C(grub_hard_stop)
+
+
+/*
+ * grub_stop_floppy()
+ *
+ * Stop the floppy drive from spinning, so that other software is
+ * jumped to with a known state.
+ */
+FUNCTION(grub_stop_floppy)
+       movw    $0x3F2, %dx
+       xorb    %al, %al
+       outb    %al, %dx
+       ret
+
+/*
+ * grub_exit()
+ *
+ * Exit the system.
+ */
+FUNCTION(grub_exit)
+       call    prot_to_real
+       .code16
+       /* Tell the BIOS a boot failure. If this does not work, reboot.  */
+       int     $0x18
+       jmp     cold_reboot
+       .code32
+
+/*
+ * grub_halt(int no_apm)
+ *
+ * Halt the system, using APM if possible. If NO_APM is true, don't use
+ * APM even if it is available.
+ */
+FUNCTION(grub_halt)
+       /* see if zero */
+       testl   %eax, %eax
+       jnz     EXT_C(grub_stop)
+
+       call    prot_to_real
+       .code16
+
+       /* detect APM */
+       movw    $0x5300, %ax
+       xorw    %bx, %bx
+       int     $0x15
+       jc      EXT_C(grub_hard_stop)
+       /* don't check %bx for buggy BIOSes... */
+
+       /* disconnect APM first */
+       movw    $0x5304, %ax
+       xorw    %bx, %bx
+       int     $0x15
+
+       /* connect APM */
+       movw    $0x5301, %ax
+       xorw    %bx, %bx
+       int     $0x15
+       jc      EXT_C(grub_hard_stop)
+
+       /* set APM protocol level - 1.1 or bust. (this covers APM 1.2 also) */
+       movw    $0x530E, %ax
+       xorw    %bx, %bx
+       movw    $0x0101, %cx
+       int     $0x15
+       jc      EXT_C(grub_hard_stop)
+
+       /* set the power state to off */
+       movw    $0x5307, %ax
+       movw    $1, %bx
+       movw    $3, %cx
+       int     $0x15
+
+       /* shouldn't reach here */
+       jmp     EXT_C(grub_hard_stop)
+       .code32
+
+
+/*
+ *  void grub_chainloader_real_boot (int drive, void *part_addr)
+ *
+ *  This starts another boot loader.
+ */
+
+FUNCTION(grub_chainloader_real_boot)
+       pushl   %edx
+       pushl   %eax
+
+       call    EXT_C(grub_dl_unload_all)
+
+       /* Turn off Gate A20 */
+       xorl    %eax, %eax
+       call    EXT_C(grub_gate_a20)
+
+       /* set up to pass boot drive */
+       popl    %edx
+
+       /* ESI must point to a partition table entry */
+       popl    %esi
+
+       call    prot_to_real
+       .code16
+       ljmp    $0, $GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR
+       .code32
+
+#include "../loader.S"
+
+/*
+ *   int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap)
+ *
+ *   Call IBM/MS INT13 Extensions (int 13 %ah=AH) for DRIVE. DAP
+ *   is passed for disk address packet. If an error occurs, return
+ *   non-zero, otherwise zero.
+ */
+
+FUNCTION(grub_biosdisk_rw_int13_extensions)
+       pushl   %ebp
+       pushl   %esi
+
+       /* compute the address of disk_address_packet */
+       movw    %cx, %si
+       xorw    %cx, %cx
+       shrl    $4, %ecx        /* save the segment to cx */
+
+       /* ah */
+       movb    %al, %dh
+       /* enter real mode */
+       call    prot_to_real
+
+       .code16
+       movb    %dh, %ah
+       movw    %cx, %ds
+       int     $0x13           /* do the operation */
+       movb    %ah, %dl        /* save return value */
+       /* back to protected mode */
+       DATA32  call    real_to_prot
+       .code32
+
+       movb    %dl, %al        /* return value in %eax */
+
+       popl    %esi
+       popl    %ebp
+
+       ret
+
+/*
+ *   int grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff,
+ *                                  int soff, int nsec, int segment)
+ *
+ *   Call standard and old INT13 (int 13 %ah=AH) for DRIVE. Read/write
+ *   NSEC sectors from COFF/HOFF/SOFF into SEGMENT. If an error occurs,
+ *   return non-zero, otherwise zero.
+ */
+
+FUNCTION(grub_biosdisk_rw_standard)
+       pushl   %ebp
+       movl    %esp, %ebp
+
+       pushl   %ebx
+       pushl   %edi
+       pushl   %esi
+
+       /* set up CHS information */
+
+       /* set %ch to low eight bits of cylinder */
+       xchgb   %cl, %ch
+       /* set bits 6-7 of %cl to high two bits of cylinder */
+       shlb    $6, %cl
+       /* set bits 0-5 of %cl to sector */
+       addb    0xc(%ebp), %cl
+       /* set %dh to head */
+       movb    0x8(%ebp), %dh
+       /* set %ah to AH */
+       movb    %al, %ah
+       /* set %al to NSEC */
+       movb    0x10(%ebp), %al
+       /* save %ax in %di */
+       movw    %ax, %di
+       /* save SEGMENT in %bx */
+       movw    0x14(%ebp), %bx
+
+       /* enter real mode */
+       call    prot_to_real
+
+       .code16
+       movw    %bx, %es
+       xorw    %bx, %bx
+       movw    $3, %si         /* attempt at least three times */
+
+1:
+       movw    %di, %ax
+       int     $0x13           /* do the operation */
+       jnc     2f              /* check if successful */
+
+       movb    %ah, %bl        /* save return value */
+       /* if fail, reset the disk system */
+       xorw    %ax, %ax
+       int     $0x13
+
+       decw    %si
+       cmpw    $0, %si
+       je      2f
+       xorb    %bl, %bl
+       jmp     1b              /* retry */
+2:
+       /* back to protected mode */
+       DATA32  call    real_to_prot
+       .code32
+
+       movb    %bl, %al        /* return value in %eax */
+
+       popl    %esi
+       popl    %edi
+       popl    %ebx
+       popl    %ebp
+
+       ret     $(4 * 4)
+
+
+/*
+ *   int grub_biosdisk_check_int13_extensions (int drive)
+ *
+ *   Check if LBA is supported for DRIVE. If it is supported, then return
+ *   the major version of extensions, otherwise zero.
+ */
+
+FUNCTION(grub_biosdisk_check_int13_extensions)
+       pushl   %ebp
+       pushl   %ebx
+
+       /* drive */
+       movb    %al, %dl
+       /* enter real mode */
+       call    prot_to_real
+
+       .code16
+       movb    $0x41, %ah
+       movw    $0x55aa, %bx
+       int     $0x13           /* do the operation */
+
+       /* check the result */
+       jc      1f
+       cmpw    $0xaa55, %bx
+       jne     1f
+
+       movb    %ah, %bl        /* save the major version into %bl */
+
+       /* check if AH=0x42 is supported */
+       andw    $1, %cx
+       jnz     2f
+
+1:
+       xorb    %bl, %bl
+2:
+       /* back to protected mode */
+       DATA32  call    real_to_prot
+       .code32
+
+       movb    %bl, %al        /* return value in %eax */
+
+       popl    %ebx
+       popl    %ebp
+
+       ret
+
+
+/*
+ *   int grub_biosdisk_get_cdinfo_int13_extensions (int drive, void *cdrp)
+ *
+ *   Return the cdrom information of DRIVE in CDRP. If an error occurs,
+ *   then return non-zero, otherwise zero.
+ */
+
+FUNCTION(grub_biosdisk_get_cdinfo_int13_extensions)
+       movw    $0x4B01, %cx
+       jmp     1f
+
+/*
+ *   int grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp)
+ *
+ *   Return the geometry of DRIVE in a drive parameters, DRP. If an error
+ *   occurs, then return non-zero, otherwise zero.
+ */
+
+FUNCTION(grub_biosdisk_get_diskinfo_int13_extensions)
+       movb    $0x48, %ch
+1:
+       pushl   %ebp
+       pushl   %ebx
+       pushl   %esi
+
+       /* compute the address of drive parameters */
+       movw    %dx, %si
+       andl    $0xf, %esi
+       shrl    $4, %edx
+       movw    %dx, %bx        /* save the segment into %bx */
+       /* drive */
+       movb    %al, %dl
+       /* enter real mode */
+       call    prot_to_real
+
+       .code16
+       movw    %cx, %ax
+       movw    %bx, %ds
+       int     $0x13           /* do the operation */
+       jc      noclean
+       /* Clean return value if carry isn't set to workaround
+       some buggy BIOSes.  */
+       xor     %ax, %ax
+noclean:
+       movb    %ah, %bl        /* save return value in %bl */
+       /* back to protected mode */
+       DATA32  call    real_to_prot
+       .code32
+
+       movb    %bl, %al        /* return value in %eax */
+
+       popl    %esi
+       popl    %ebx
+       popl    %ebp
+
+       ret
+
+
+/*
+ *   int grub_biosdisk_get_diskinfo_standard (int drive,
+ *                                            unsigned long *cylinders,
+ *                                            unsigned long *heads,
+ *                                            unsigned long *sectors)
+ *
+ *   Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an
+ *   error occurs, then return non-zero, otherwise zero.
+ */
+
+FUNCTION(grub_biosdisk_get_diskinfo_standard)
+       pushl   %ebp
+       pushl   %ebx
+       pushl   %edi
+
+       /* push CYLINDERS */
+       pushl   %edx
+       /* push HEADS */
+       pushl   %ecx
+       /* SECTORS is on the stack */
+
+       /* drive */
+       movb    %al, %dl
+       /* enter real mode */
+       call    prot_to_real
+
+       .code16
+       movb    $0x8, %ah
+       int     $0x13           /* do the operation */
+       jc      noclean2
+       /* Clean return value if carry isn't set to workaround
+       some buggy BIOSes.  */
+       xor     %ax, %ax
+noclean2:
+       /* check if successful */
+       testb   %ah, %ah
+       jnz     1f
+       /* bogus BIOSes may not return an error number */
+       testb   $0x3f, %cl      /* 0 sectors means no disk */
+       jnz     1f              /* if non-zero, then succeed */
+       /* XXX 0x60 is one of the unused error numbers */
+       movb    $0x60, %ah
+1:
+       movb    %ah, %bl        /* save return value in %bl */
+       /* back to protected mode */
+       DATA32  call    real_to_prot
+       .code32
+
+       /* pop HEADS */
+       popl    %edi
+       movb    %dh, %al
+       incl    %eax    /* the number of heads is counted from zero */
+       movl    %eax, (%edi)
+
+       /* pop CYLINDERS */
+       popl    %edi
+       movb    %ch, %al
+       movb    %cl, %ah
+       shrb    $6, %ah /* the number of cylinders is counted from zero */
+       incl    %eax
+       movl    %eax, (%edi)
+
+       /* SECTORS */
+       movl    0x10(%esp), %edi
+       andb    $0x3f, %cl
+       movzbl  %cl, %eax
+       movl    %eax, (%edi)
+
+       xorl    %eax, %eax
+       movb    %bl, %al        /* return value in %eax */
+
+       popl    %edi
+       popl    %ebx
+       popl    %ebp
+
+       ret     $4
+
+
+/*
+ * int grub_biosdisk_get_num_floppies (void)
+ */
+FUNCTION(grub_biosdisk_get_num_floppies)
+       pushl   %ebp
+
+       xorl    %edx, %edx
+       call    prot_to_real
+
+       .code16
+       /* reset the disk system first */
+       int     $0x13
+1:
+       stc
+
+       /* call GET DISK TYPE */
+       movb    $0x15, %ah
+       int     $0x13
+
+       jc      2f
+
+       /* check if this drive exists */
+       testb   $0x3, %ah
+       jz      2f
+
+       incb    %dl
+       cmpb    $2, %dl
+       jne     1b
+2:
+       DATA32  call    real_to_prot
+       .code32
+
+       movl    %edx, %eax
+       popl    %ebp
+       ret
+
+
+/*
+ *
+ * grub_get_memsize(i) :  return the memory size in KB. i == 0 for conventional
+ *             memory, i == 1 for extended memory
+ *     BIOS call "INT 12H" to get conventional memory size
+ *     BIOS call "INT 15H, AH=88H" to get extended memory size
+ *             Both have the return value in AX.
+ *
+ */
+
+FUNCTION(grub_get_memsize)
+       pushl   %ebp
+
+       movl    %eax, %edx
+
+       call    prot_to_real    /* enter real mode */
+       .code16
+
+       testl   %edx, %edx
+       jnz     xext
+
+       int     $0x12
+       jmp     xdone
+
+xext:
+       movb    $0x88, %ah
+       int     $0x15
+
+xdone:
+       movw    %ax, %dx
+
+       DATA32  call    real_to_prot
+       .code32
+
+       movw    %dx, %ax
+
+       popl    %ebp
+       ret
+
+
+/*
+ *
+ * grub_get_eisa_mmap() :  return packed EISA memory map, lower 16 bits is
+ *             memory between 1M and 16M in 1K parts, upper 16 bits is
+ *             memory above 16M in 64K parts.  If error, return zero.
+ *     BIOS call "INT 15H, AH=E801H" to get EISA memory map,
+ *             AX = memory between 1M and 16M in 1K parts.
+ *             BX = memory above 16M in 64K parts.
+ *
+ */
+
+FUNCTION(grub_get_eisa_mmap)
+       pushl   %ebp
+       pushl   %ebx
+
+       call    prot_to_real    /* enter real mode */
+       .code16
+
+       movw    $0xe801, %ax
+       int     $0x15
+
+       shll    $16, %ebx
+       movw    %ax, %bx
+
+       DATA32  call    real_to_prot
+       .code32
+
+       cmpb    $0x86, %bh
+       je      xnoteisa
+
+       movl    %ebx, %eax
+
+xnoteisa:
+       popl    %ebx
+       popl    %ebp
+       ret
+
+/*
+ *
+ * grub_get_mmap_entry(addr, cont) : address and old continuation value (zero to
+ *             start), for the Query System Address Map BIOS call.
+ *
+ *  Sets the first 4-byte int value of "addr" to the size returned by
+ *  the call.  If the call fails, sets it to zero.
+ *
+ *     Returns:  new (non-zero) continuation value, 0 if done.
+ */
+
+FUNCTION(grub_get_mmap_entry)
+       pushl   %ebp
+       pushl   %ebx
+       pushl   %edi
+       pushl   %esi
+
+       /* push ADDR */
+       pushl   %eax
+
+       /* place address (+4) in ES:DI */
+       addl    $4, %eax
+       movl    %eax, %edi
+       andl    $0xf, %edi
+       shrl    $4, %eax
+       movl    %eax, %esi
+
+       /* set continuation value */
+       movl    %edx, %ebx
+
+       /* set default maximum buffer size */
+       movl    $0x14, %ecx
+
+       /* set EDX to 'SMAP' */
+       movl    $0x534d4150, %edx
+
+       call    prot_to_real    /* enter real mode */
+       .code16
+
+       movw    %si, %es
+       movl    $0xe820, %eax
+       int     $0x15
+
+       DATA32  jc      xnosmap
+
+       cmpl    $0x534d4150, %eax
+       jne     xnosmap
+
+       cmpl    $0x14, %ecx
+       jl      xnosmap
+
+       cmpl    $0x400, %ecx
+       jg      xnosmap
+
+       jmp     xsmap
+
+xnosmap:
+       xorl    %ecx, %ecx
+
+/*     Apple's cc jumps few bytes before the correct
+       label in this context. Hence nops. */
+#ifdef APPLE_CC
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+#endif
+
+xsmap:
+       DATA32  call    real_to_prot
+       .code32
+
+       /* write length of buffer (zero if error) into ADDR */
+       popl    %eax
+       movl    %ecx, (%eax)
+
+       /* set return value to continuation */
+       movl    %ebx, %eax
+
+       popl    %esi
+       popl    %edi
+       popl    %ebx
+       popl    %ebp
+       ret
+
+
+/*
+ * void grub_console_real_putchar (int c)
+ *
+ * Put the character C on the console. Because GRUB wants to write a
+ * character with an attribute, this implementation is a bit tricky.
+ * If C is a control character (CR, LF, BEL, BS), use INT 10, AH = 0Eh
+ * (TELETYPE OUTPUT). Otherwise, save the original position, put a space,
+ * save the current position, restore the original position, write the
+ * character and the attribute, and restore the current position.
+ *
+ * The reason why this is so complicated is that there is no easy way to
+ * get the height of the screen, and the TELETYPE OUTPUT BIOS call doesn't
+ * support setting a background attribute.
+ */
+FUNCTION(grub_console_real_putchar)
+       movl    %eax, %edx
+       pusha
+       movb    EXT_C(grub_console_cur_color), %bl
+
+       call    prot_to_real
+       .code16
+       movb    %dl, %al
+       xorb    %bh, %bh
+
+       /* use teletype output if control character */
+       cmpb    $0x7, %al
+       je      1f
+       cmpb    $0x8, %al
+       je      1f
+       cmpb    $0xa, %al
+       je      1f
+       cmpb    $0xd, %al
+       je      1f
+
+       /* save the character and the attribute on the stack */
+       pushw   %ax
+       pushw   %bx
+
+       /* get the current position */
+       movb    $0x3, %ah
+       int     $0x10
+
+       /* check the column with the width */
+       cmpb    $79, %dl
+       jl      2f
+
+       /* print CR and LF, if next write will exceed the width */
+       movw    $0x0e0d, %ax
+       int     $0x10
+       movb    $0x0a, %al
+       int     $0x10
+
+       /* get the current position */
+       movb    $0x3, %ah
+       int     $0x10
+
+2:
+       /* restore the character and the attribute */
+       popw    %bx
+       popw    %ax
+
+       /* write the character with the attribute */
+       movb    $0x9, %ah
+       movw    $1, %cx
+       int     $0x10
+
+       /* move the cursor forward */
+       incb    %dl
+       movb    $0x2, %ah
+       int     $0x10
+
+       jmp     3f
+
+1:     movw    $1, %bx
+       movb    $0xe, %ah
+       int     $0x10
+
+3:     DATA32  call    real_to_prot
+       .code32
+
+       popa
+       ret
+
+
+/*
+ * int grub_console_getkey (void)
+ * BIOS call "INT 16H Function 00H" to read character from keyboard
+ *     Call with       %ah = 0x0
+ *     Return:         %ah = keyboard scan code
+ *                     %al = ASCII character
+ */
+
+/* this table is used in translate_keycode below */
+LOCAL (translation_table):
+       .word   GRUB_CONSOLE_KEY_LEFT, GRUB_TERM_LEFT
+       .word   GRUB_CONSOLE_KEY_RIGHT, GRUB_TERM_RIGHT
+       .word   GRUB_CONSOLE_KEY_UP, GRUB_TERM_UP
+       .word   GRUB_CONSOLE_KEY_DOWN, GRUB_TERM_DOWN
+       .word   GRUB_CONSOLE_KEY_HOME, GRUB_TERM_HOME
+       .word   GRUB_CONSOLE_KEY_END, GRUB_TERM_END
+       .word   GRUB_CONSOLE_KEY_DC, GRUB_TERM_DC
+       .word   GRUB_CONSOLE_KEY_BACKSPACE, GRUB_TERM_BACKSPACE
+       .word   GRUB_CONSOLE_KEY_PPAGE, GRUB_TERM_PPAGE
+       .word   GRUB_CONSOLE_KEY_NPAGE, GRUB_TERM_NPAGE
+       .word   0
+
+/*
+ * translate_keycode translates the key code %dx to an ascii code.
+ */
+       .code16
+
+translate_keycode:
+       pushw   %bx
+       pushw   %si
+
+#ifdef __APPLE__
+       movw    $(ABS(LOCAL (translation_table)) - 0x10000), %si
+#else
+       movw    $ABS(LOCAL (translation_table)), %si
+#endif
+
+1:     lodsw
+       /* check if this is the end */
+       testw   %ax, %ax
+       jz      2f
+       /* load the ascii code into %ax */
+       movw    %ax, %bx
+       lodsw
+       /* check if this matches the key code */
+       cmpw    %bx, %dx
+       jne     1b
+       /* translate %dx, if successful */
+       movw    %ax, %dx
+
+2:     popw    %si
+       popw    %bx
+       ret
+
+       .code32
+
+FUNCTION(grub_console_getkey)
+       pushl   %ebp
+
+       call    prot_to_real
+       .code16
+
+       /*
+        * Due to a bug in apple's bootcamp implementation, INT 16/AH = 0 would
+        * cause the machine to hang at the second keystroke. However, we can
+        * work around this problem by ensuring the presence of keystroke with
+        * INT 16/AH = 1 before calling INT 16/AH = 0.
+        */
+
+1:
+       movb    $1, %ah
+       int     $0x16
+       jnz     2f
+       hlt
+       jmp     1b
+
+2:
+
+       movb    $0, %ah
+       int     $0x16
+
+       movw    %ax, %dx                /* real_to_prot uses %eax */
+       call    translate_keycode
+
+       DATA32  call    real_to_prot
+       .code32
+
+       movw    %dx, %ax
+
+       popl    %ebp
+       ret
+
+
+/*
+ * int grub_console_checkkey (void)
+ *     if there is a character pending, return it; otherwise return -1
+ * BIOS call "INT 16H Function 01H" to check whether a character is pending
+ *     Call with       %ah = 0x1
+ *     Return:
+ *             If key waiting to be input:
+ *                     %ah = keyboard scan code
+ *                     %al = ASCII character
+ *                     Zero flag = clear
+ *             else
+ *                     Zero flag = set
+ */
+FUNCTION(grub_console_checkkey)
+       pushl   %ebp
+       xorl    %edx, %edx
+
+       call    prot_to_real    /* enter real mode */
+       .code16
+
+       movb    $0x1, %ah
+       int     $0x16
+
+       jz      notpending
+
+       movw    %ax, %dx
+       DATA32  jmp     pending
+
+notpending:
+       decl    %edx
+
+pending:
+       DATA32  call    real_to_prot
+       .code32
+
+       movl    %edx, %eax
+
+       popl    %ebp
+       ret
+
+
+/*
+ * grub_uint16_t grub_console_getxy (void)
+ * BIOS call "INT 10H Function 03h" to get cursor position
+ *     Call with       %ah = 0x03
+ *                     %bh = page
+ *      Returns         %ch = starting scan line
+ *                      %cl = ending scan line
+ *                      %dh = row (0 is top)
+ *                      %dl = column (0 is left)
+ */
+
+
+FUNCTION(grub_console_getxy)
+       pushl   %ebp
+       pushl   %ebx                    /* save EBX */
+
+       call    prot_to_real
+       .code16
+
+        xorb   %bh, %bh                /* set page to 0 */
+       movb    $0x3, %ah
+       int     $0x10                   /* get cursor position */
+
+       DATA32  call    real_to_prot
+       .code32
+
+       movb    %dl, %ah
+       movb    %dh, %al
+
+       popl    %ebx
+       popl    %ebp
+       ret
+
+
+/*
+ * void grub_console_gotoxy(grub_uint8_t x, grub_uint8_t y)
+ * BIOS call "INT 10H Function 02h" to set cursor position
+ *     Call with       %ah = 0x02
+ *                     %bh = page
+ *                      %dh = row (0 is top)
+ *                      %dl = column (0 is left)
+ */
+
+
+FUNCTION(grub_console_gotoxy)
+       pushl   %ebp
+       pushl   %ebx                    /* save EBX */
+
+       movb    %dl, %dh        /* %dh = y */
+       movb    %al, %dl        /* %dl = x */
+
+       call    prot_to_real
+       .code16
+
+        xorb   %bh, %bh                /* set page to 0 */
+       movb    $0x2, %ah
+       int     $0x10                   /* set cursor position */
+
+       DATA32  call    real_to_prot
+       .code32
+
+       popl    %ebx
+       popl    %ebp
+       ret
+
+
+/*
+ * void grub_console_cls (void)
+ * BIOS call "INT 10H Function 09h" to write character and attribute
+ *     Call with       %ah = 0x09
+ *                      %al = (character)
+ *                      %bh = (page number)
+ *                      %bl = (attribute)
+ *                      %cx = (number of times)
+ */
+
+FUNCTION(grub_console_cls)
+       pushl   %ebp
+       pushl   %ebx                    /* save EBX */
+
+       call    prot_to_real
+       .code16
+
+       /* move the cursor to the beginning */
+       movb    $0x02, %ah
+       xorb    %bh, %bh
+       xorw    %dx, %dx
+       int     $0x10
+
+       /* write spaces to the entire screen */
+       movw    $0x0920, %ax
+       movw    $0x07, %bx
+       movw    $(80 * 25), %cx
+        int    $0x10
+
+       /* move back the cursor */
+       movb    $0x02, %ah
+       int     $0x10
+
+       DATA32  call    real_to_prot
+       .code32
+
+       popl    %ebx
+       popl    %ebp
+       ret
+
+
+/*
+ * void grub_console_setcursor (int on)
+ * BIOS call "INT 10H Function 01h" to set cursor type
+ *      Call with       %ah = 0x01
+ *                      %ch = cursor starting scanline
+ *                      %cl = cursor ending scanline
+ */
+
+console_cursor_state:
+       .byte   1
+console_cursor_shape:
+       .word   0
+
+FUNCTION(grub_console_setcursor)
+       pushl   %ebp
+       pushl   %ebx
+
+       /* push ON */
+       pushl   %eax
+
+       /* check if the standard cursor shape has already been saved */
+       movw    console_cursor_shape, %ax
+       testw   %ax, %ax
+       jne     1f
+
+       call    prot_to_real
+       .code16
+
+       movb    $0x03, %ah
+       xorb    %bh, %bh
+       int     $0x10
+
+       DATA32  call    real_to_prot
+       .code32
+
+       movw    %cx, console_cursor_shape
+1:
+       /* set %cx to the designated cursor shape */
+       movw    $0x2000, %cx
+       popl    %eax
+       testl   %eax, %eax
+       jz      2f
+       movw    console_cursor_shape, %cx
+2:
+       call    prot_to_real
+       .code16
+
+       movb    $0x1, %ah
+       int     $0x10
+
+       DATA32  call    real_to_prot
+       .code32
+
+       popl    %ebx
+       popl    %ebp
+       ret
+
+/*
+ * grub_get_rtc()
+ *     return the real time in ticks, of which there are about
+ *     18-20 per second
+ */
+FUNCTION(grub_get_rtc)
+       pushl   %ebp
+
+       call    prot_to_real    /* enter real mode */
+       .code16
+
+       /* %ax is already zero */
+        int    $0x1a
+
+       DATA32  call    real_to_prot
+       .code32
+
+       movl    %ecx, %eax
+       shll    $16, %eax
+       movw    %dx, %ax
+
+       popl    %ebp
+       ret
+
+
+/*
+ * unsigned char grub_vga_set_mode (unsigned char mode)
+ */
+FUNCTION(grub_vga_set_mode)
+       pushl   %ebp
+       pushl   %ebx
+       movl    %eax, %ecx
+
+       call    prot_to_real
+       .code16
+       /* get current mode */
+       xorw    %bx, %bx
+       movb    $0x0f, %ah
+       int     $0x10
+       movb    %al, %dl
+
+       /* set the new mode */
+       movb    %cl, %al
+       xorb    %ah, %ah
+       int     $0x10
+
+       DATA32  call    real_to_prot
+       .code32
+
+       movb    %dl, %al
+       popl    %ebx
+       popl    %ebp
+       ret
+
+/*
+ * grub_vbe_bios_status_t grub_vbe_get_controller_info (struct grub_vbe_info_block *controller_info)
+ *
+ * Register allocations for parameters:
+ * %eax                *controller_info
+ */
+FUNCTION(grub_vbe_bios_get_controller_info)
+       pushl   %ebp
+       pushl   %edi
+       pushl   %edx
+
+       movw    %ax, %di        /* Store *controller_info to %edx:%di.  */
+       xorw    %ax, %ax
+       shrl    $4, %eax
+       mov     %eax, %edx      /* prot_to_real destroys %eax.  */
+
+       call    prot_to_real
+       .code16
+
+       pushw   %es
+
+       movw    %dx, %es        /* *controller_info is now on %es:%di.  */
+       movw    $0x4f00, %ax
+       int     $0x10
+
+       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
+
+       popw    %es
+
+       DATA32 call     real_to_prot
+       .code32
+
+       movl    %edx, %eax
+       andl    $0x0FFFF, %eax  /* Return value in %eax.  */
+
+       pop     %edx
+       popl    %edi
+       popl    %ebp
+       ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_get_mode_info (grub_uint32_t mode,
+ *                                               struct grub_vbe_mode_info_block *mode_info)
+ *
+ * Register allocations for parameters:
+ * %eax                mode
+ * %edx                *mode_info
+ */
+FUNCTION(grub_vbe_bios_get_mode_info)
+       pushl   %ebp
+       pushl   %edi
+
+       movl    %eax, %ecx      /* Store mode number to %ecx.  */
+
+       movw    %dx, %di        /* Store *mode_info to %edx:%di.  */
+       xorw    %dx, %dx
+       shrl    $4, %edx
+
+       call    prot_to_real
+       .code16
+
+       pushw   %es
+
+       movw    %dx, %es        /* *mode_info is now on %es:%di.  */
+       movw    $0x4f01, %ax
+       int     $0x10
+
+       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
+
+       popw    %es
+
+       DATA32 call     real_to_prot
+       .code32
+
+       movl    %edx, %eax
+       andl    $0x0FFFF, %eax  /* Return value in %eax.  */
+
+       popl    %edi
+       popl    %ebp
+       ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_set_mode (grub_uint32_t mode,
+ *                                          struct grub_vbe_crtc_info_block *crtc_info)
+ *
+ * Register allocations for parameters:
+ * %eax                mode
+ * %edx                *crtc_info
+ */
+FUNCTION(grub_vbe_bios_set_mode)
+       pushl   %ebp
+       pushl   %ebx
+       pushl   %edi
+
+       movl    %eax, %ebx      /* Store mode in %ebx.  */
+
+       movw    %dx, %di        /* Store *crtc_info to %edx:%di.  */
+       xorw    %dx, %dx
+       shrl    $4, %edx
+
+       call    prot_to_real
+       .code16
+
+       pushw   %es
+
+       movw    %dx, %es        /* *crtc_info is now on %es:%di.  */
+
+       movw    $0x4f02, %ax
+       int     $0x10
+
+       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
+
+       popw    %es
+
+       DATA32 call     real_to_prot
+       .code32
+
+       movw    %dx, %ax
+       andl    $0xFFFF, %eax   /* Return value in %eax.  */
+
+       popl    %edi
+       popl    %ebx
+       popl    %ebp
+       ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_get_mode (grub_uint32_t *mode)
+ *
+ * Register allocations for parameters:
+ * %eax                *mode
+ */
+FUNCTION(grub_vbe_bios_get_mode)
+       pushl   %ebp
+       pushl   %ebx
+       pushl   %edi
+       pushl   %edx
+       pushl   %eax            /* Push *mode to stack.  */
+
+       call    prot_to_real
+       .code16
+
+       movw    $0x4f03, %ax
+       int     $0x10
+
+       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
+
+       DATA32 call     real_to_prot
+       .code32
+
+       popl    %edi            /* Pops *mode from stack to %edi.  */
+       andl    $0xFFFF, %ebx
+       movl    %ebx, (%edi)
+
+       movw    %dx, %ax
+       andl    $0xFFFF, %eax   /* Return value in %eax.  */
+
+       popl    %edx
+       popl    %edi
+       popl    %ebx
+       popl    %ebp
+       ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_getset_dac_palette_width (int set, int *dac_mask_size)
+ *
+ * Register allocations for parameters:
+ * %eax                set
+ * %edx                *dac_mask_size
+ */
+FUNCTION(grub_vbe_bios_getset_dac_palette_width)
+       pushl   %ebp
+       pushl   %ebx
+
+       xorl    %ebx, %ebx
+
+       /* If we only want to fetch the value, set %bl to 1.  */
+       testl   %eax, %eax
+       jne     1f
+       incb    %bl
+1:
+
+       /* Put desired width in %bh.  */
+       movl    (%edx), %eax
+       movb    %al, %bh
+
+       call    prot_to_real
+       .code16
+
+       movw    $0x4f08, %ax
+       int     $0x10
+
+       movw    %ax, %cx        /* real_to_prot destroys %eax.  */
+
+       DATA32 call     real_to_prot
+       .code32
+
+       /* Move result back to *dac_mask_size.  */
+       xorl    %eax, %eax
+       movb    %bh, %al
+       movl    %eax, (%edx)
+
+       /* Return value in %eax.  */
+       movw    %cx, %ax
+
+       popl    %ebx
+       popl    %ebp
+       ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_set_memory_window (grub_uint32_t window,
+ *                                                   grub_uint32_t position);
+ *
+ * Register allocations for parameters:
+ * %eax                window
+ * %edx                position
+ */
+FUNCTION(grub_vbe_bios_set_memory_window)
+       pushl   %ebp
+       pushl   %ebx
+
+       movl    %eax, %ebx
+
+       call    prot_to_real
+       .code16
+
+       movw    $0x4f05, %ax
+       andw    $0x00ff, %bx    /* BL = window, BH = 0, Set memory window.  */
+       int     $0x10
+
+       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
+
+       DATA32 call     real_to_prot
+       .code32
+
+       movw    %dx, %ax
+       andl    $0xFFFF, %eax   /* Return value in %eax.  */
+
+       popl    %ebx
+       popl    %ebp
+       ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_get_memory_window (grub_uint32_t window,
+ *                                                   grub_uint32_t *position);
+ *
+ * Register allocations for parameters:
+ * %eax                window
+ * %edx                *position
+ */
+FUNCTION(grub_vbe_bios_get_memory_window)
+       pushl   %ebp
+       pushl   %ebx
+       pushl   %edi
+       pushl   %edx            /* Push *position to stack.  */
+
+       movl    %eax, %ebx      /* Store window in %ebx.  */
+
+       call    prot_to_real
+       .code16
+
+       movw    $0x4f05, %ax
+       andw    $0x00ff, %bx    /* BL = window.  */
+       orw     $0x0100, %bx    /* BH = 1, Get memory window.  */
+       int     $0x10
+
+       movw    %ax, %bx        /* real_to_prot destroys %eax.  */
+
+       DATA32 call     real_to_prot
+       .code32
+
+       popl    %edi            /* pops *position from stack to %edi.  */
+       andl    $0xFFFF, %edx
+       movl    %edx, (%edi)    /* Return position to caller.  */
+
+       movw    %bx, %ax
+       andl    $0xFFFF, %eax   /* Return value in %eax.  */
+
+       popl    %edi
+       popl    %ebx
+       popl    %ebp
+       ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_set_scanline_length (grub_uint32_t length)
+ *
+ * Register allocations for parameters:
+ * %eax                length
+ */
+FUNCTION(grub_vbe_bios_set_scanline_length)
+       pushl   %ebp
+       pushl   %ebx
+       pushl   %edx
+
+       movl    %eax, %ecx      /* Store length in %ecx.  */
+
+       call    prot_to_real
+       .code16
+
+       movw    $0x4f06, %ax
+       movw    $0x0002, %bx    /* BL = 2, Set Scan Line in Bytes.  */
+       int     $0x10
+
+       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
+
+       DATA32 call     real_to_prot
+       .code32
+
+       movw    %dx, %ax
+       andl    $0xFFFF, %eax   /* Return value in %eax.  */
+
+       popl    %edx
+       popl    %ebx
+       popl    %ebp
+       ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_get_scanline_length (grub_uint32_t *length)
+ *
+ * Register allocations for parameters:
+ * %eax                *length
+ */
+FUNCTION(grub_vbe_bios_get_scanline_length)
+       pushl   %ebp
+       pushl   %ebx
+       pushl   %edi
+       pushl   %edx            /* Push *length to stack.  */
+
+       call    prot_to_real
+       .code16
+
+       movw    $0x4f06, %ax
+       movw    $0x0001, %bx    /* BL = 1, Get Scan Line Length (in bytes).  */
+       int     $0x10
+
+       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
+
+       DATA32 call     real_to_prot
+       .code32
+
+       popl    %edi            /* Pops *length from stack to %edi.  */
+       andl    $0xFFFF, %ebx
+       movl    %ebx, (%edi)    /* Return length to caller.  */
+
+       movw    %dx, %ax
+       andl    $0xFFFF, %eax   /* Return value in %eax.  */
+
+       popl    %edi
+       popl    %ebx
+       popl    %ebp
+       ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_set_display_start (grub_uint32_t x,
+ *                                                   grub_uint32_t y)
+ *
+ * Register allocations for parameters:
+ * %eax                x
+ * %edx                y
+ */
+FUNCTION(grub_vbe_bios_set_display_start)
+       pushl   %ebp
+       pushl   %ebx
+
+       movl    %eax, %ecx      /* Store x in %ecx.  */
+
+       call    prot_to_real
+       .code16
+
+       movw    $0x4f07, %ax
+       movw    $0x0080, %bx    /* BL = 80h, Set Display Start
+                                  during Vertical Retrace.  */
+       int     $0x10
+
+       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
+
+       DATA32 call     real_to_prot
+       .code32
+
+       movw    %dx, %ax
+       andl    $0xFFFF, %eax   /* Return value in %eax.  */
+
+       popl    %ebx
+       popl    %ebp
+       ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_get_display_start (grub_uint32_t *x,
+ *                                                   grub_uint32_t *y)
+ *
+ * Register allocations for parameters:
+ * %eax                *x
+ * %edx                *y
+ */
+FUNCTION(grub_vbe_bios_get_display_start)
+       pushl   %ebp
+       pushl   %ebx
+       pushl   %edi
+       pushl   %eax            /* Push *x to stack.  */
+       pushl   %edx            /* Push *y to stack.  */
+
+       call    prot_to_real
+       .code16
+
+       movw    $0x4f07, %ax
+       movw    $0x0001, %bx    /* BL = 1, Get Display Start.  */
+       int     $0x10
+
+       movw    %ax, %bx        /* real_to_prot destroys %eax.  */
+
+       DATA32 call     real_to_prot
+       .code32
+
+       popl    %edi            /* Pops *y from stack to %edi.  */
+       andl    $0xFFFF, %edx
+       movl    %edx, (%edi)    /* Return y-position to caller.  */
+
+       popl    %edi            /* Pops *x from stack to %edi.  */
+       andl    $0xFFFF, %ecx
+       movl    %ecx, (%edi)    /* Return x-position to caller.  */
+
+       movw    %bx, %ax
+       andl    $0xFFFF, %eax   /* Return value in %eax.  */
+
+       popl    %edi
+       popl    %ebx
+       popl    %ebp
+       ret
+
+/*
+ * grub_vbe_status_t grub_vbe_bios_set_palette_data (grub_uint32_t color_count,
+ *                                                  grub_uint32_t start_index,
+ *                                                  struct grub_vbe_palette_data *palette_data)
+ *
+ * Register allocations for parameters:
+ * %eax                color_count
+ * %edx                start_index
+ * %ecx                *palette_data
+ */
+FUNCTION(grub_vbe_bios_set_palette_data)
+       pushl   %ebp
+       pushl   %ebx
+       pushl   %edi
+
+       movl    %eax, %ebx      /* Store color_count in %ebx.  */
+
+       movw    %cx, %di        /* Store *palette_data to %ecx:%di.  */
+       xorw    %cx, %cx
+       shrl    $4, %ecx
+
+       call    prot_to_real
+       .code16
+
+       pushw   %es
+
+       movw    %cx, %es        /* *palette_data is now on %es:%di.  */
+       movw    %bx, %cx        /* color_count is now on %cx.  */
+
+       movw    $0x4f09, %ax
+       xorw    %bx, %bx        /* BL = 0, Set Palette Data.  */
+       int     $0x10
+
+       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
+
+       popw    %es
+
+       DATA32 call     real_to_prot
+       .code32
+
+       movw    %dx, %ax
+       andl    $0xFFFF, %eax   /* Return value in %eax.  */
+
+       popl    %edi
+       popl    %ebx
+       popl    %ebp
+       ret
+
+
+pxe_rm_entry:
+       .long   0
+
+/*
+ * struct grub_pxenv *grub_pxe_scan (void);
+ */
+FUNCTION(grub_pxe_scan)
+       pushl   %ebp
+       pushl   %ebx
+
+       xorl    %ebx, %ebx
+       xorl    %ecx, %ecx
+
+       call    prot_to_real
+       .code16
+
+       pushw   %es
+
+       movw    $0x5650, %ax
+       int     $0x1A
+       cmpw    $0x564E, %ax
+       jnz     1f
+       cmpl    $0x4E455850, %es:(%bx)          /* PXEN(V+)  */
+       jnz     1f
+       cmpw    $0x201, %es:6(%bx)              /* API version  */
+       jb      1f
+       lesw    %es:0x28(%bx), %bx              /* !PXE structure  */
+       cmpl    $0x45585021, %es:(%bx)          /* !PXE  */
+       jnz     1f
+       movw    %es, %cx
+       jmp     2f
+1:
+       xorw    %bx, %bx
+       xorw    %cx, %cx
+2:
+
+       popw    %es
+
+       DATA32 call     real_to_prot
+       .code32
+
+       xorl    %eax, %eax
+       leal    (%eax, %ecx, 4), %ecx
+       leal    (%ebx, %ecx, 4), %eax           /* eax = ecx * 16 + ebx  */
+
+       orl     %eax, %eax
+       jz      1f
+
+       movl    0x10(%eax), %ecx
+       movl    %ecx, pxe_rm_entry
+
+1:
+
+       popl    %ebx
+       popl    %ebp
+       ret
+
+/*
+ * int grub_pxe_call (int func, void* data);
+ */
+FUNCTION(grub_pxe_call)
+       pushl   %ebp
+       movl    %esp, %ebp
+       pushl   %esi
+       pushl   %edi
+       pushl   %ebx
+
+       movl    %eax, %ecx
+       movl    %edx, %eax
+       andl    $0xF, %eax
+       shrl    $4, %edx
+       shll    $16, %edx
+       addl    %eax, %edx
+       movl    pxe_rm_entry, %ebx
+
+       call    prot_to_real
+       .code16
+
+       pushl   %ebx
+       pushl   %edx
+       pushw   %cx
+       movw    %sp, %bx
+       lcall   *%ss:6(%bx)
+       cld
+       addw    $10, %sp
+       movw    %ax, %cx
+
+       DATA32  call    real_to_prot
+       .code32
+
+       movzwl  %cx, %eax
+
+       popl    %ebx
+       popl    %edi
+       popl    %esi
+       popl    %ebp
+       ret
diff --git a/grub-core/kern/i386/pit.c b/grub-core/kern/i386/pit.c
new file mode 100644 (file)
index 0000000..82a17d3
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/i386/io.h>
+#include <grub/i386/pit.h>
+
+#define TIMER2_REG_CONTROL     0x42
+#define TIMER_REG_COMMAND      0x43
+#define TIMER2_REG_LATCH       0x61
+
+#define TIMER2_SELECT          0x80
+#define TIMER_ENABLE_LSB       0x20
+#define TIMER_ENABLE_MSB       0x10
+#define TIMER2_LATCH           0x20
+#define TIMER2_SPEAKER         0x02
+#define TIMER2_GATE            0x01
+
+void
+grub_pit_wait (grub_uint16_t tics)
+{
+  /* Disable timer2 gate and speaker.  */
+  grub_outb (grub_inb (TIMER2_REG_LATCH) & ~ (TIMER2_SPEAKER | TIMER2_GATE),
+             TIMER2_REG_LATCH);
+
+  /* Set tics.  */
+  grub_outb (TIMER2_SELECT | TIMER_ENABLE_LSB | TIMER_ENABLE_MSB, TIMER_REG_COMMAND);
+  grub_outb (tics & 0xff, TIMER2_REG_CONTROL);
+  grub_outb (tics >> 8, TIMER2_REG_CONTROL);
+
+  /* Enable timer2 gate, keep speaker disabled.  */
+  grub_outb ((grub_inb (TIMER2_REG_LATCH) & ~ TIMER2_SPEAKER) | TIMER2_GATE,
+             TIMER2_REG_LATCH);
+
+  /* Wait.  */
+  while ((grub_inb (TIMER2_REG_LATCH) & TIMER2_LATCH) == 0x00);
+
+  /* Disable timer2 gate and speaker.  */
+  grub_outb (grub_inb (TIMER2_REG_LATCH) & ~ (TIMER2_SPEAKER | TIMER2_GATE),
+             TIMER2_REG_LATCH);
+}
diff --git a/grub-core/kern/i386/qemu/mmap.c b/grub-core/kern/i386/qemu/mmap.c
new file mode 100644 (file)
index 0000000..c7fc4f4
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/boot.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/cmos.h>
+
+#define QEMU_CMOS_MEMSIZE_HIGH         0x35
+#define QEMU_CMOS_MEMSIZE_LOW          0x34
+
+#define min(a,b)       ((a) > (b) ? (b) : (a))
+
+extern char _start[];
+extern char _end[];
+
+grub_size_t grub_lower_mem, grub_upper_mem;
+grub_uint64_t mem_size;
+
+void
+grub_machine_mmap_init ()
+{
+  mem_size = grub_cmos_read (QEMU_CMOS_MEMSIZE_HIGH) << 24 | grub_cmos_read (QEMU_CMOS_MEMSIZE_LOW) << 16;
+
+  /* Don't ask... */
+  mem_size += (16 * 1024 * 1024);
+}
+
+grub_err_t
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
+{
+  if (hook (0x0,
+           (grub_addr_t) _start,
+           GRUB_MACHINE_MEMORY_AVAILABLE))
+    return 1;
+
+  if (hook (GRUB_MEMORY_MACHINE_UPPER,
+           0x100000 - GRUB_MEMORY_MACHINE_UPPER,
+           GRUB_MACHINE_MEMORY_RESERVED))
+    return 1;
+
+  /* Protect boot.img, which contains the gdt.  It is mapped at the top of memory
+     (it is also mapped below 0x100000, but we already reserved that area).  */
+  if (hook ((grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE,
+           GRUB_BOOT_MACHINE_SIZE,
+           GRUB_MACHINE_MEMORY_RESERVED))
+    return 1;
+
+  /* Everything else is free.  */
+  if (hook (0x100000,
+           min (mem_size, (grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE) - 0x100000,
+           GRUB_MACHINE_MEMORY_AVAILABLE))
+    return 1;
+
+  return 0;
+}
diff --git a/grub-core/kern/i386/qemu/startup.S b/grub-core/kern/i386/qemu/startup.S
new file mode 100644 (file)
index 0000000..7484650
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/kernel.h>
+
+       .text
+       .code32
+       .globl _start
+_start:
+       jmp     codestart
+
+       . = _start + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR
+VARIABLE(grub_core_entry_addr)
+       .long   0
+VARIABLE(grub_kernel_image_size)
+       .long   0
+VARIABLE(grub_prefix)
+       /* to be filled by grub-mkimage */
+
+       /*
+        *  Leave some breathing room for the prefix.
+        */
+
+       . = _start + GRUB_KERNEL_MACHINE_DATA_END
+
+codestart:
+       /* Relocate to low memory.  First we figure out our location.
+          We will derive the rom start address from it.  */
+       call    1f
+1:     popl    %esi
+
+       /* Rom size is a multiple of 64 kiB.  With this we get the
+          value of `grub_core_entry_addr' in %esi.  */
+       xorw    %si, %si
+
+       /* ... which allows us to access `grub_kernel_image_size'
+          before relocation.  */
+       movl    (grub_kernel_image_size - _start)(%esi), %ecx
+
+
+       movl    $_start, %edi
+       cld
+       rep
+       movsb
+       ljmp    $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $1f
+1:
+
+#ifdef APPLE_CC
+       /* clean out the bss */
+       bss_start_abs = ABS (bss_start)
+       bss_end_abs = ABS (bss_end)
+
+       movl    bss_start_abs, %edi
+
+       /* compute the bss length */
+       movl    bss_end_abs, %ecx
+       subl    %edi, %ecx
+#else
+       /* clean out the bss */
+       movl    $BSS_START_SYMBOL, %edi
+
+       /* compute the bss length */
+       movl    $END_SYMBOL, %ecx
+       subl    %edi, %ecx
+#endif
+               
+       /* clean out */
+       xorl    %eax, %eax
+       cld
+       rep
+       stosb
+
+       /*
+        *  Call the start of main body of C code.
+        */
+       call    EXT_C(grub_main)
+
+       /* This should never happen.  */
+       jmp     EXT_C(grub_stop)
+
+#include "../realmode.S"
diff --git a/grub-core/kern/i386/realmode.S b/grub-core/kern/i386/realmode.S
new file mode 100644 (file)
index 0000000..578c8d2
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2009,2010 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/i386/pc/memory.h>
+
+/*
+ * Note: These functions defined in this file may be called from C.
+ *       Be careful of that you must not modify some registers. Quote
+ *       from gcc-2.95.2/gcc/config/i386/i386.h:
+
+   1 for registers not available across function calls.
+   These must include the FIXED_REGISTERS and also any
+   registers that can be used without being saved.
+   The latter must include the registers where values are returned
+   and the register where structure-value addresses are passed.
+   Aside from that, you can include as many other registers as you like.
+
+  ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
+{  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
+ */
+
+/*
+ * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
+ *       So the first three arguments are passed in %eax, %edx, and %ecx,
+ *       respectively, and if a function has a fixed number of arguments
+ *       and the number if greater than three, the function must return
+ *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
+ */
+
+/*
+ *  This is the area for all of the special variables.
+ */
+
+       .p2align        2       /* force 4-byte alignment */
+
+protstack:
+       .long   GRUB_MEMORY_MACHINE_PROT_STACK
+
+/*
+ * This is the Global Descriptor Table
+ *
+ *  An entry, a "Segment Descriptor", looks like this:
+ *
+ * 31          24         19   16                 7           0
+ * ------------------------------------------------------------
+ * |             | |B| |A|       | |   |1|0|E|W|A|            |
+ * | BASE 31..24 |G|/|L|V| LIMIT |P|DPL|  TYPE   | BASE 23:16 |  4
+ * |             | |D| |L| 19..16| |   |1|1|C|R|A|            |
+ * ------------------------------------------------------------
+ * |                             |                            |
+ * |        BASE 15..0           |       LIMIT 15..0          |  0
+ * |                             |                            |
+ * ------------------------------------------------------------
+ *
+ *  Note the ordering of the data items is reversed from the above
+ *  description.
+ */
+
+       .p2align        2       /* force 4-byte alignment */
+gdt:
+       .word   0, 0
+       .byte   0, 0, 0, 0
+
+       /* -- code segment --
+        * base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present
+        * type = 32bit code execute/read, DPL = 0
+        */
+       .word   0xFFFF, 0
+       .byte   0, 0x9A, 0xCF, 0
+
+       /* -- data segment --
+        * base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present
+        * type = 32 bit data read/write, DPL = 0
+        */
+       .word   0xFFFF, 0
+       .byte   0, 0x92, 0xCF, 0
+
+       /* -- 16 bit real mode CS --
+        * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present
+        * type = 16 bit code execute/read only/conforming, DPL = 0
+        */
+       .word   0xFFFF, 0
+       .byte   0, 0x9E, 0, 0
+
+       /* -- 16 bit real mode DS --
+        * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present
+        * type = 16 bit data read/write, DPL = 0
+        */
+       .word   0xFFFF, 0
+       .byte   0, 0x92, 0, 0
+
+
+/* this is the GDT descriptor */
+gdtdesc:
+       .word   0x27                    /* limit */
+       .long   gdt                     /* addr */
+
+/*
+ *  These next two routines, "real_to_prot" and "prot_to_real" are structured
+ *  in a very specific way.  Be very careful when changing them.
+ *
+ *  NOTE:  Use of either one messes up %eax and %ebp.
+ */
+
+real_to_prot:
+       .code16
+       cli
+
+       /* load the GDT register */
+       xorw    %ax, %ax
+       movw    %ax, %ds
+       DATA32  ADDR32  lgdt    gdtdesc
+
+       /* turn on protected mode */
+       movl    %cr0, %eax
+       orl     $GRUB_MEMORY_CPU_CR0_PE_ON, %eax
+       movl    %eax, %cr0
+
+       /* jump to relocation, flush prefetch queue, and reload %cs */
+       DATA32  ljmp    $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg
+
+       .code32
+protcseg:
+       /* reload other segment registers */
+       movw    $GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %ax
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %fs
+       movw    %ax, %gs
+       movw    %ax, %ss
+
+       /* put the return address in a known safe location */
+       movl    (%esp), %eax
+       movl    %eax, GRUB_MEMORY_MACHINE_REAL_STACK
+
+       /* get protected mode stack */
+       movl    protstack, %eax
+       movl    %eax, %esp
+       movl    %eax, %ebp
+
+       /* get return address onto the right stack */
+       movl    GRUB_MEMORY_MACHINE_REAL_STACK, %eax
+       movl    %eax, (%esp)
+
+       /* zero %eax */
+       xorl    %eax, %eax
+
+       /* return on the old (or initialized) stack! */
+       ret
+
+prot_to_real:
+       /* just in case, set GDT */
+       lgdt    gdtdesc
+
+       /* save the protected mode stack */
+       movl    %esp, %eax
+       movl    %eax, protstack
+
+       /* get the return address */
+       movl    (%esp), %eax
+       movl    %eax, GRUB_MEMORY_MACHINE_REAL_STACK
+
+       /* set up new stack */
+       movl    $GRUB_MEMORY_MACHINE_REAL_STACK, %eax
+       movl    %eax, %esp
+       movl    %eax, %ebp
+
+       /* set up segment limits */
+       movw    $GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG, %ax
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %fs
+       movw    %ax, %gs
+       movw    %ax, %ss
+
+       /* this might be an extra step */
+       /* jump to a 16 bit segment */
+       ljmp    $GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG, $tmpcseg
+
+tmpcseg:
+       .code16
+
+       /* clear the PE bit of CR0 */
+       movl    %cr0, %eax
+       andl    $(~GRUB_MEMORY_CPU_CR0_PE_ON), %eax
+       movl    %eax, %cr0
+
+       /* flush prefetch queue, reload %cs */
+       DATA32  ljmp    $0, $realcseg
+
+realcseg:
+       /* we are in real mode now
+        * set up the real mode segment registers : DS, SS, ES
+        */
+       /* zero %eax */
+       xorl    %eax, %eax
+
+       movw    %ax, %ds
+       movw    %ax, %es
+       movw    %ax, %fs
+       movw    %ax, %gs
+       movw    %ax, %ss
+
+#ifdef GRUB_MACHINE_PCBIOS
+       /* restore interrupts */
+       sti
+#endif
+
+       /* return on new stack! */
+       DATA32  ret
+
+       .code32
+
+/*
+ * grub_reboot()
+ *
+ * Reboot the system. At the moment, rely on BIOS.
+ */
+FUNCTION(grub_reboot)
+       call    prot_to_real
+       .code16
+cold_reboot:
+       /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */
+       movw    $0x0472, %di
+       movw    %ax, (%di)
+       ljmp    $0xf000, $0xfff0
+       .code32
diff --git a/grub-core/kern/i386/tsc.c b/grub-core/kern/i386/tsc.c
new file mode 100644 (file)
index 0000000..36b35e2
--- /dev/null
@@ -0,0 +1,74 @@
+/* kern/i386/tsc.c - x86 TSC time source implementation
+ * Requires Pentium or better x86 CPU that supports the RDTSC instruction.
+ * This module uses the RTC (via grub_get_rtc()) to calibrate the TSC to
+ * real time.
+ *
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/time.h>
+#include <grub/misc.h>
+#include <grub/i386/tsc.h>
+#include <grub/i386/pit.h>
+
+/* This defines the value TSC had at the epoch (that is, when we calibrated it). */
+static grub_uint64_t tsc_boot_time;
+
+/* Calibrated TSC rate.  (In TSC ticks per millisecond.) */
+static grub_uint64_t tsc_ticks_per_ms;
+
+
+grub_uint64_t
+grub_tsc_get_time_ms (void)
+{
+  return tsc_boot_time + grub_divmod64 (grub_get_tsc (), tsc_ticks_per_ms, 0);
+}
+
+
+/* How many RTC ticks to use for calibration loop. (>= 1) */
+#define CALIBRATION_TICKS 2
+
+/* Calibrate the TSC based on the RTC.  */
+static void
+calibrate_tsc (void)
+{
+  /* First calibrate the TSC rate (relative, not absolute time). */
+  grub_uint64_t start_tsc;
+  grub_uint64_t end_tsc;
+
+  start_tsc = grub_get_tsc ();
+  grub_pit_wait (0xffff);
+  end_tsc = grub_get_tsc ();
+
+  tsc_ticks_per_ms = grub_divmod64 (end_tsc - start_tsc, 55, 0);
+}
+
+void
+grub_tsc_init (void)
+{
+  if (grub_cpu_is_tsc_supported ())
+    {
+      tsc_boot_time = grub_get_tsc ();
+      calibrate_tsc ();
+      grub_install_get_time_ms (grub_tsc_get_time_ms);
+    }
+  else
+    {
+      grub_install_get_time_ms (grub_rtc_get_time_ms);
+    }
+}
diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c
new file mode 100644 (file)
index 0000000..c1185f8
--- /dev/null
@@ -0,0 +1,165 @@
+/* cmain.c - Startup code for the PowerPC.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/machine/kernel.h>
+#include <grub/ieee1275/ieee1275.h>
+
+int (*grub_ieee1275_entry_fn) (void *);
+
+grub_ieee1275_phandle_t grub_ieee1275_chosen;
+grub_ieee1275_ihandle_t grub_ieee1275_mmu;
+
+static grub_uint32_t grub_ieee1275_flags;
+\f
+
+
+int
+grub_ieee1275_test_flag (enum grub_ieee1275_flag flag)
+{
+  return (grub_ieee1275_flags & (1 << flag));
+}
+
+void
+grub_ieee1275_set_flag (enum grub_ieee1275_flag flag)
+{
+  grub_ieee1275_flags |= (1 << flag);
+}
+
+#define SF "SmartFirmware(tm)"
+#define OHW "PPC Open Hack'Ware"
+
+static void
+grub_ieee1275_find_options (void)
+{
+  grub_ieee1275_phandle_t root;
+  grub_ieee1275_phandle_t options;
+  grub_ieee1275_phandle_t openprom;
+  grub_ieee1275_phandle_t bootrom;
+  int rc;
+  grub_uint32_t realmode = 0;
+  char tmp[32];
+  int is_smartfirmware = 0;
+  int is_olpc = 0;
+
+  grub_ieee1275_finddevice ("/", &root);
+  grub_ieee1275_finddevice ("/options", &options);
+  grub_ieee1275_finddevice ("/openprom", &openprom);
+
+  rc = grub_ieee1275_get_integer_property (options, "real-mode?", &realmode,
+                                          sizeof realmode, 0);
+  if (((rc >= 0) && realmode) || (grub_ieee1275_mmu == 0))
+    grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_REAL_MODE);
+
+  rc = grub_ieee1275_get_property (openprom, "CodeGen-copyright",
+                                  tmp, sizeof (tmp), 0);
+  if (rc >= 0 && !grub_strncmp (tmp, SF, sizeof (SF) - 1))
+    is_smartfirmware = 1;
+
+  rc = grub_ieee1275_get_property (root, "architecture",
+                                  tmp, sizeof (tmp), 0);
+  if (rc >= 0 && !grub_strcmp (tmp, "OLPC"))
+    is_olpc = 1;
+
+  if (is_smartfirmware)
+    {
+      /* Broken in all versions */
+      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT);
+
+      /* There are two incompatible ways of checking the version number.  Try
+         both. */
+      rc = grub_ieee1275_get_property (openprom, "SmartFirmware-version",
+                                      tmp, sizeof (tmp), 0);
+      if (rc < 0)
+       rc = grub_ieee1275_get_property (openprom, "firmware-version",
+                                        tmp, sizeof (tmp), 0);
+      if (rc >= 0)
+       {
+         /* It is tempting to implement a version parser to set the flags for
+            e.g. 1.3 and below.  However, there's a special situation here.
+            3rd party updates which fix the partition bugs are common, and for
+            some reason their fixes aren't being merged into trunk.  So for
+            example we know that 1.2 and 1.3 are broken, but there's 1.2.99
+            and 1.3.99 which are known good (and applying this workaround
+            would cause breakage). */
+         if (!grub_strcmp (tmp, "1.0")
+             || !grub_strcmp (tmp, "1.1")
+             || !grub_strcmp (tmp, "1.2")
+             || !grub_strcmp (tmp, "1.3"))
+           {
+             grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
+             grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS);
+           }
+       }
+    }
+
+  if (is_olpc)
+    {
+      /* OLPC / XO laptops have three kinds of storage devices:
+
+        - NAND flash.  These are accessible via OFW callbacks, but:
+          - Follow strange semantics, imposed by hardware constraints.
+          - Its ABI is undocumented, and not stable.
+          They lack "device_type" property, which conveniently makes GRUB
+          skip them.
+
+        - USB drives.  Not accessible, because OFW shuts down the controller
+          in order to prevent collisions with applications accessing it
+          directly.  Even worse, attempts to access it will NOT return
+          control to the caller, so we have to avoid probing them.
+
+        - SD cards.  These work fine.
+
+        To avoid breakage, we only need to skip USB probing.  However,
+        since detecting SD cards is more reliable, we do that instead.
+      */
+
+      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY);
+    }
+
+  if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom))
+    {
+      rc = grub_ieee1275_get_property (bootrom, "model", tmp, sizeof (tmp), 0);
+      if (rc >= 0 && !grub_strncmp (tmp, OHW, sizeof (OHW) - 1))
+       {
+         grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT);
+         grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS);
+         grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET);
+         grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM);
+         grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_ANSI);
+       }
+    }
+}
+
+#undef SF
+#undef OHW
+
+void
+grub_ieee1275_init (void)
+{
+  grub_ieee1275_finddevice ("/chosen", &grub_ieee1275_chosen);
+
+  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "mmu", &grub_ieee1275_mmu,
+                                         sizeof grub_ieee1275_mmu, 0) < 0)
+    grub_ieee1275_mmu = 0;
+
+  grub_ieee1275_find_options ();
+}
diff --git a/grub-core/kern/ieee1275/ieee1275.c b/grub-core/kern/ieee1275/ieee1275.c
new file mode 100644 (file)
index 0000000..9e29191
--- /dev/null
@@ -0,0 +1,609 @@
+/* of.c - Access the Open Firmware client interface.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/types.h>
+
+#define IEEE1275_PHANDLE_INVALID  ((grub_ieee1275_cell_t) -1)
+#define IEEE1275_IHANDLE_INVALID  ((grub_ieee1275_cell_t) 0)
+#define IEEE1275_CELL_INVALID     ((grub_ieee1275_cell_t) -1)
+
+\f
+
+int
+grub_ieee1275_finddevice (char *name, grub_ieee1275_phandle_t *phandlep)
+{
+  struct find_device_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t device;
+    grub_ieee1275_cell_t phandle;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "finddevice", 1, 1);
+  args.device = (grub_ieee1275_cell_t) name;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *phandlep = args.phandle;
+  if (args.phandle == IEEE1275_PHANDLE_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_get_property (grub_ieee1275_phandle_t phandle,
+                           const char *property, void *buf,
+                           grub_size_t size, grub_ssize_t *actual)
+{
+  struct get_property_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t phandle;
+    grub_ieee1275_cell_t prop;
+    grub_ieee1275_cell_t buf;
+    grub_ieee1275_cell_t buflen;
+    grub_ieee1275_cell_t size;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "getprop", 4, 1);
+  args.phandle = phandle;
+  args.prop = (grub_ieee1275_cell_t) property;
+  args.buf = (grub_ieee1275_cell_t) buf;
+  args.buflen = (grub_ieee1275_cell_t) size;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  if (actual)
+    *actual = (grub_ssize_t) args.size;
+  if (args.size == IEEE1275_CELL_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_get_integer_property (grub_ieee1275_phandle_t phandle,
+                                   const char *property, grub_uint32_t *buf,
+                                   grub_size_t size, grub_ssize_t *actual)
+{
+  int ret;
+  ret = grub_ieee1275_get_property (phandle, property, (void *) buf, size, actual);
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
+  /* Integer properties are always in big endian.  */
+  if (ret == 0)
+    {
+      unsigned int i;
+      size /= sizeof (grub_uint32_t);
+      for (i = 0; i < size; i++)
+       buf[i] = grub_be_to_cpu32 (buf[i]);
+    }
+#endif
+  return ret;
+}
+
+int
+grub_ieee1275_next_property (grub_ieee1275_phandle_t phandle, char *prev_prop,
+                            char *prop)
+{
+  struct get_property_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t phandle;
+    grub_ieee1275_cell_t prev_prop;
+    grub_ieee1275_cell_t next_prop;
+    grub_ieee1275_cell_t flags;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "nextprop", 3, 1);
+  args.phandle = phandle;
+  args.prev_prop = (grub_ieee1275_cell_t) prev_prop;
+  args.next_prop = (grub_ieee1275_cell_t) prop;
+  args.flags = (grub_ieee1275_cell_t) -1;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  return (int) args.flags;
+}
+
+int
+grub_ieee1275_get_property_length (grub_ieee1275_phandle_t phandle,
+                                  const char *prop, grub_ssize_t *length)
+{
+  struct get_property_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t phandle;
+    grub_ieee1275_cell_t prop;
+    grub_ieee1275_cell_t length;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "getproplen", 2, 1);
+  args.phandle = phandle;
+  args.prop = (grub_ieee1275_cell_t) prop;
+  args.length = (grub_ieee1275_cell_t) -1;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *length = args.length;
+  if (args.length == IEEE1275_CELL_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_instance_to_package (grub_ieee1275_ihandle_t ihandle,
+                                  grub_ieee1275_phandle_t *phandlep)
+{
+  struct instance_to_package_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t phandle;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "instance-to-package", 1, 1);
+  args.ihandle = ihandle;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *phandlep = args.phandle;
+  if (args.phandle == IEEE1275_PHANDLE_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_package_to_path (grub_ieee1275_phandle_t phandle,
+                              char *path, grub_size_t len,
+                              grub_ssize_t *actual)
+{
+  struct instance_to_package_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t phandle;
+    grub_ieee1275_cell_t buf;
+    grub_ieee1275_cell_t buflen;
+    grub_ieee1275_cell_t actual;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "package-to-path", 3, 1);
+  args.phandle = phandle;
+  args.buf = (grub_ieee1275_cell_t) path;
+  args.buflen = (grub_ieee1275_cell_t) len;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  if (actual)
+    *actual = args.actual;
+  if (args.actual == IEEE1275_CELL_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_instance_to_path (grub_ieee1275_ihandle_t ihandle,
+                               char *path, grub_size_t len,
+                               grub_ssize_t *actual)
+{
+  struct instance_to_path_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t buf;
+    grub_ieee1275_cell_t buflen;
+    grub_ieee1275_cell_t actual;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "instance-to-path", 3, 1);
+  args.ihandle = ihandle;
+  args.buf = (grub_ieee1275_cell_t) path;
+  args.buflen = (grub_ieee1275_cell_t) len;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  if (actual)
+    *actual = args.actual;
+  if (args.actual == IEEE1275_CELL_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_write (grub_ieee1275_ihandle_t ihandle, void *buffer,
+                    grub_size_t len, grub_ssize_t *actualp)
+{
+  struct write_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t buf;
+    grub_ieee1275_cell_t len;
+    grub_ieee1275_cell_t actual;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "write", 3, 1);
+  args.ihandle = ihandle;
+  args.buf = (grub_ieee1275_cell_t) buffer;
+  args.len = (grub_ieee1275_cell_t) len;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  if (actualp)
+    *actualp = args.actual;
+  return 0;
+}
+
+int
+grub_ieee1275_read (grub_ieee1275_ihandle_t ihandle, void *buffer,
+                   grub_size_t len, grub_ssize_t *actualp)
+{
+  struct write_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t buf;
+    grub_ieee1275_cell_t len;
+    grub_ieee1275_cell_t actual;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "read", 3, 1);
+  args.ihandle = ihandle;
+  args.buf = (grub_ieee1275_cell_t) buffer;
+  args.len = (grub_ieee1275_cell_t) len;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  if (actualp)
+    *actualp = args.actual;
+  return 0;
+}
+
+int
+grub_ieee1275_seek (grub_ieee1275_ihandle_t ihandle, grub_disk_addr_t pos,
+                   grub_ssize_t *result)
+{
+  struct write_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t pos_hi;
+    grub_ieee1275_cell_t pos_lo;
+    grub_ieee1275_cell_t result;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "seek", 3, 1);
+  args.ihandle = ihandle;
+  /* To prevent stupid gcc warning.  */
+#if GRUB_IEEE1275_CELL_SIZEOF >= 8
+  args.pos_hi = 0;
+  args.pos_lo = pos;
+#else
+  args.pos_hi = (grub_ieee1275_cell_t) (pos >> (8 * GRUB_IEEE1275_CELL_SIZEOF));
+  args.pos_lo = (grub_ieee1275_cell_t) 
+    (pos & ((1ULL << (8 * GRUB_IEEE1275_CELL_SIZEOF)) - 1));
+#endif
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+
+  if (result)
+    *result = args.result;
+  return 0;
+}
+
+int
+grub_ieee1275_peer (grub_ieee1275_phandle_t node,
+                   grub_ieee1275_phandle_t *result)
+{
+  struct peer_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t node;
+    grub_ieee1275_cell_t result;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "peer", 1, 1);
+  args.node = node;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *result = args.result;
+  if (args.result == 0)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_child (grub_ieee1275_phandle_t node,
+                    grub_ieee1275_phandle_t *result)
+{
+  struct child_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t node;
+    grub_ieee1275_cell_t result;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "child", 1, 1);
+  args.node = node;
+  args.result = IEEE1275_PHANDLE_INVALID;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *result = args.result;
+  if (args.result == 0)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_parent (grub_ieee1275_phandle_t node,
+                     grub_ieee1275_phandle_t *result)
+{
+  struct parent_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t node;
+    grub_ieee1275_cell_t result;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "parent", 1, 1);
+  args.node = node;
+  args.result = IEEE1275_PHANDLE_INVALID;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *result = args.result;
+  return 0;
+}
+
+int
+grub_ieee1275_interpret (const char *command, grub_ieee1275_cell_t *catch)
+{
+  struct enter_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t command;
+    grub_ieee1275_cell_t catch;
+  }
+  args;
+
+  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
+    return -1;
+
+  INIT_IEEE1275_COMMON (&args.common, "interpret", 1, 1);
+  args.command = (grub_ieee1275_cell_t) command;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  if (catch)
+    *catch = args.catch;
+  return 0;
+}
+
+int
+grub_ieee1275_enter (void)
+{
+  struct enter_args
+  {
+    struct grub_ieee1275_common_hdr common;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "enter", 0, 0);
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  return 0;
+}
+
+void
+grub_ieee1275_exit (void)
+{
+  struct exit_args
+  {
+    struct grub_ieee1275_common_hdr common;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "exit", 0, 0);
+
+  IEEE1275_CALL_ENTRY_FN (&args);
+  for (;;) ;
+}
+
+int
+grub_ieee1275_open (const char *path, grub_ieee1275_ihandle_t *result)
+{
+  struct open_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t path;
+    grub_ieee1275_cell_t result;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "open", 1, 1);
+  args.path = (grub_ieee1275_cell_t) path;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *result = args.result;
+  if (args.result == IEEE1275_IHANDLE_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_close (grub_ieee1275_ihandle_t ihandle)
+{
+  struct close_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t ihandle;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "close", 1, 0);
+  args.ihandle = ihandle;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+
+  return 0;
+}
+
+int
+grub_ieee1275_claim (grub_addr_t addr, grub_size_t size, unsigned int align,
+                    grub_addr_t *result)
+{
+  struct claim_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t addr;
+    grub_ieee1275_cell_t size;
+    grub_ieee1275_cell_t align;
+    grub_ieee1275_cell_t base;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "claim", 3, 1);
+  args.addr = (grub_ieee1275_cell_t) addr;
+  args.size = (grub_ieee1275_cell_t) size;
+  args.align = (grub_ieee1275_cell_t) align;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  if (result)
+    *result = args.base;
+  if (args.base == IEEE1275_CELL_INVALID)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_release (grub_addr_t addr, grub_size_t size)
+{
+ struct release_args
+ {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t addr;
+    grub_ieee1275_cell_t size;
+ }
+ args;
+
+  INIT_IEEE1275_COMMON (&args.common, "release", 2, 0);
+  args.addr = addr;
+  args.size = size;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_set_property (grub_ieee1275_phandle_t phandle,
+                           const char *propname, void *buf,
+                           grub_size_t size, grub_ssize_t *actual)
+{
+  struct set_property_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t phandle;
+    grub_ieee1275_cell_t propname;
+    grub_ieee1275_cell_t buf;
+    grub_ieee1275_cell_t size;
+    grub_ieee1275_cell_t actual;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "setprop", 4, 1);
+  args.size = (grub_ieee1275_cell_t) size;
+  args.buf = (grub_ieee1275_cell_t) buf;
+  args.propname = (grub_ieee1275_cell_t) propname;
+  args.phandle = (grub_ieee1275_cell_t) phandle;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *actual = args.actual;
+  if ((args.actual == IEEE1275_CELL_INVALID) || (args.actual != args.size))
+    return -1;
+  return 0;
+}
+
+int
+grub_ieee1275_set_color (grub_ieee1275_ihandle_t ihandle,
+                        int index, int r, int g, int b)
+{
+  struct set_color_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t method;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t index;
+    grub_ieee1275_cell_t b;
+    grub_ieee1275_cell_t g;
+    grub_ieee1275_cell_t r;
+    grub_ieee1275_cell_t catch_result;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1);
+  args.method = (grub_ieee1275_cell_t) "color!";
+  args.ihandle = ihandle;
+  args.index = index;
+  args.r = r;
+  args.g = g;
+  args.b = b;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  return args.catch_result;
+}
+
+int
+grub_ieee1275_milliseconds (grub_uint32_t *msecs)
+{
+  struct milliseconds_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t msecs;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "milliseconds", 0, 1);
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  *msecs = args.msecs;
+  return 0;
+}
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
new file mode 100644 (file)
index 0000000..75f261a
--- /dev/null
@@ -0,0 +1,288 @@
+/*  init.c -- Initialize GRUB on the newworld mac (PPC).  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+#include <grub/normal.h>
+#include <grub/fs.h>
+#include <grub/setjmp.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/time.h>
+#include <grub/machine/console.h>
+#include <grub/machine/kernel.h>
+#include <grub/cpu/kernel.h>
+#include <grub/ieee1275/ofdisk.h>
+#include <grub/ieee1275/ieee1275.h>
+
+/* The minimal heap size we can live with. */
+#define HEAP_MIN_SIZE          (unsigned long) (2 * 1024 * 1024)
+
+/* The maximum heap size we're going to claim */
+#define HEAP_MAX_SIZE          (unsigned long) (32 * 1024 * 1024)
+
+/* If possible, we will avoid claiming heap above this address, because it
+   seems to cause relocation problems with OSes that link at 4 MiB */
+#define HEAP_MAX_ADDR          (unsigned long) (32 * 1024 * 1024)
+
+extern char _start[];
+extern char _end[];
+
+void
+grub_exit (void)
+{
+  grub_ieee1275_exit ();
+}
+
+/* Translate an OF filesystem path (separated by backslashes), into a GRUB
+   path (separated by forward slashes).  */
+static void
+grub_translate_ieee1275_path (char *filepath)
+{
+  char *backslash;
+
+  backslash = grub_strchr (filepath, '\\');
+  while (backslash != 0)
+    {
+      *backslash = '/';
+      backslash = grub_strchr (filepath, '\\');
+    }
+}
+
+void
+grub_machine_set_prefix (void)
+{
+  char bootpath[64]; /* XXX check length */
+  char *filename;
+  char *prefix;
+
+  if (grub_prefix[0])
+    {
+      grub_env_set ("prefix", grub_prefix);
+      /* Prefix is hardcoded in the core image.  */
+      return;
+    }
+
+  if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath,
+                                 sizeof (bootpath), 0))
+    {
+      /* Should never happen.  */
+      grub_printf ("/chosen/bootpath property missing!\n");
+      grub_env_set ("prefix", "");
+      return;
+    }
+
+  /* Transform an OF device path to a GRUB path.  */
+
+  prefix = grub_ieee1275_encode_devname (bootpath);
+
+  filename = grub_ieee1275_get_filename (bootpath);
+  if (filename)
+    {
+      char *newprefix;
+      char *lastslash = grub_strrchr (filename, '\\');
+
+      /* Truncate at last directory.  */
+      if (lastslash)
+        {
+         *lastslash = '\0';
+         grub_translate_ieee1275_path (filename);
+
+         newprefix = grub_xasprintf ("%s%s", prefix, filename);
+         if (newprefix)
+           {
+             grub_free (prefix);
+             prefix = newprefix;
+           }
+       }
+    }
+
+  grub_env_set ("prefix", prefix);
+
+  grub_free (filename);
+  grub_free (prefix);
+}
+
+/* Claim some available memory in the first /memory node. */
+static void grub_claim_heap (void)
+{
+  unsigned long total = 0;
+
+  auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type);
+  int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type)
+  {
+    if (type != 1)
+      return 0;
+
+    len -= 1; /* Required for some firmware.  */
+
+    /* Never exceed HEAP_MAX_SIZE  */
+    if (total + len > HEAP_MAX_SIZE)
+      len = HEAP_MAX_SIZE - total;
+
+    /* Avoid claiming anything above HEAP_MAX_ADDR, if possible. */
+    if ((addr < HEAP_MAX_ADDR) &&                              /* if it's too late, don't bother */
+        (addr + len > HEAP_MAX_ADDR) &&                                /* if it wasn't available anyway, don't bother */
+        (total + (HEAP_MAX_ADDR - addr) > HEAP_MIN_SIZE))      /* only limit ourselves when we can afford to */
+       len = HEAP_MAX_ADDR - addr;
+
+    /* In theory, firmware should already prevent this from happening by not
+       listing our own image in /memory/available.  The check below is intended
+       as a safeguard in case that doesn't happen.  However, it doesn't protect
+       us from corrupting our module area, which extends up to a
+       yet-undetermined region above _end.  */
+    if ((addr < (grub_addr_t) _end) && ((addr + len) > (grub_addr_t) _start))
+      {
+        grub_printf ("Warning: attempt to claim over our own code!\n");
+        len = 0;
+      }
+
+    if (len)
+      {
+       /* Claim and use it.  */
+       if (grub_claimmap (addr, len) < 0)
+         return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                            "failed to claim heap at 0x%llx, len 0x%llx",
+                            addr, len);
+       grub_mm_init_region ((void *) (grub_addr_t) addr, len);
+      }
+
+    total += len;
+    if (total >= HEAP_MAX_SIZE)
+      return 1;
+
+    return 0;
+  }
+
+  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
+    heap_init (HEAP_MAX_ADDR - HEAP_MIN_SIZE, HEAP_MIN_SIZE, 1);
+  else
+    grub_machine_mmap_iterate (heap_init);
+}
+
+#ifdef __i386__
+
+grub_uint32_t grub_upper_mem;
+
+/* We need to call this before grub_claim_memory.  */
+static void
+grub_get_extended_memory (void)
+{
+  auto int NESTED_FUNC_ATTR find_ext_mem (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type);
+  int NESTED_FUNC_ATTR find_ext_mem (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type)
+    {
+      if (type == 1 && addr == 0x100000)
+        {
+          grub_upper_mem = len;
+          return 1;
+        }
+
+      return 0;
+    }
+
+  grub_machine_mmap_iterate (find_ext_mem);
+}
+
+#endif
+
+static grub_uint64_t ieee1275_get_time_ms (void);
+
+void
+grub_machine_init (void)
+{
+  char args[256];
+  grub_ssize_t actual;
+
+  grub_ieee1275_init ();
+
+  grub_console_init ();
+#ifdef __i386__
+  grub_get_extended_memory ();
+#endif
+  grub_claim_heap ();
+  grub_ofdisk_init ();
+
+  /* Process commandline.  */
+  if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args,
+                                 sizeof args, &actual) == 0
+      && actual > 1)
+    {
+      int i = 0;
+
+      while (i < actual)
+       {
+         char *command = &args[i];
+         char *end;
+         char *val;
+
+         end = grub_strchr (command, ';');
+         if (end == 0)
+           i = actual; /* No more commands after this one.  */
+         else
+           {
+             *end = '\0';
+             i += end - command + 1;
+             while (grub_isspace(args[i]))
+               i++;
+           }
+
+         /* Process command.  */
+         val = grub_strchr (command, '=');
+         if (val)
+           {
+             *val = '\0';
+             grub_env_set (command, val + 1);
+           }
+       }
+    }
+
+  grub_install_get_time_ms (ieee1275_get_time_ms);
+}
+
+void
+grub_machine_fini (void)
+{
+  grub_ofdisk_fini ();
+  grub_console_fini ();
+}
+
+static grub_uint64_t
+ieee1275_get_time_ms (void)
+{
+  grub_uint32_t msecs = 0;
+
+  grub_ieee1275_milliseconds (&msecs);
+
+  return msecs;
+}
+
+grub_uint32_t
+grub_get_rtc (void)
+{
+  return ieee1275_get_time_ms ();
+}
+
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+  return ALIGN_UP((grub_addr_t) _end + GRUB_MOD_GAP, GRUB_MOD_ALIGN);
+}
diff --git a/grub-core/kern/ieee1275/mmap.c b/grub-core/kern/ieee1275/mmap.c
new file mode 100644 (file)
index 0000000..6f06527
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/types.h>
+
+grub_err_t
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
+{
+  grub_ieee1275_phandle_t root;
+  grub_ieee1275_phandle_t memory;
+  grub_uint32_t available[32];
+  grub_ssize_t available_size;
+  grub_uint32_t address_cells = 1;
+  grub_uint32_t size_cells = 1;
+  int i;
+
+  /* Determine the format of each entry in `available'.  */
+  grub_ieee1275_finddevice ("/", &root);
+  grub_ieee1275_get_integer_property (root, "#address-cells", &address_cells,
+                                     sizeof address_cells, 0);
+  grub_ieee1275_get_integer_property (root, "#size-cells", &size_cells,
+                                     sizeof size_cells, 0);
+
+  if (size_cells > address_cells)
+    address_cells = size_cells;
+
+  /* Load `/memory/available'.  */
+  if (grub_ieee1275_finddevice ("/memory", &memory))
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                      "couldn't find /memory node");
+  if (grub_ieee1275_get_integer_property (memory, "available", available,
+                                         sizeof available, &available_size))
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                      "couldn't examine /memory/available property");
+
+  /* Decode each entry and call `hook'.  */
+  i = 0;
+  available_size /= sizeof (grub_uint32_t);
+  while (i < available_size)
+    {
+      grub_uint64_t address;
+      grub_uint64_t size;
+
+      address = available[i++];
+      if (address_cells == 2)
+       address = (address << 32) | available[i++];
+
+      size = available[i++];
+      if (size_cells == 2)
+       size = (size << 32) | available[i++];
+
+      if (hook (address, size, GRUB_MACHINE_MEMORY_AVAILABLE))
+       break;
+    }
+
+  return grub_errno;
+}
diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c
new file mode 100644 (file)
index 0000000..cf9e1a8
--- /dev/null
@@ -0,0 +1,435 @@
+/*  openfw.c -- Open firmware support functions.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/machine/kernel.h>
+#include <grub/ieee1275/ieee1275.h>
+
+enum grub_ieee1275_parse_type
+{
+  GRUB_PARSE_FILENAME,
+  GRUB_PARSE_PARTITION,
+};
+
+/* Walk children of 'devpath', calling hook for each.  */
+int
+grub_children_iterate (char *devpath,
+                      int (*hook) (struct grub_ieee1275_devalias *alias))
+{
+  grub_ieee1275_phandle_t dev;
+  grub_ieee1275_phandle_t child;
+  char *childtype, *childpath;
+  char *childname;
+  int ret = 0;
+
+  if (grub_ieee1275_finddevice (devpath, &dev))
+    return 0;
+
+  if (grub_ieee1275_child (dev, &child))
+    return 0;
+
+  childtype = grub_malloc (IEEE1275_MAX_PROP_LEN);
+  if (!childtype)
+    return 0;
+  childpath = grub_malloc (IEEE1275_MAX_PATH_LEN);
+  if (!childpath)
+    {
+      grub_free (childtype);
+      return 0;
+    }
+  childname = grub_malloc (IEEE1275_MAX_PROP_LEN);
+  if (!childname)
+    {
+      grub_free (childpath);
+      grub_free (childtype);
+      return 0;
+    }
+
+  do
+    {
+      struct grub_ieee1275_devalias alias;
+      grub_ssize_t actual;
+
+      if (grub_ieee1275_get_property (child, "device_type", childtype,
+                                     IEEE1275_MAX_PROP_LEN, &actual))
+       childtype[0] = 0;
+
+      if (dev == child)
+       continue;
+
+      if (grub_ieee1275_package_to_path (child, childpath,
+                                        IEEE1275_MAX_PATH_LEN, &actual))
+       continue;
+
+      if (grub_strcmp (devpath, childpath) == 0)
+       continue;
+
+      if (grub_ieee1275_get_property (child, "name", childname,
+                                     IEEE1275_MAX_PROP_LEN, &actual))
+       continue;
+
+      alias.type = childtype;
+      alias.path = childpath;
+      alias.name = childname;
+      ret = hook (&alias);
+      if (ret)
+       break;
+    }
+  while (grub_ieee1275_peer (child, &child) != -1);
+
+  grub_free (childname);
+  grub_free (childpath);
+  grub_free (childtype);
+
+  return ret;
+}
+
+int
+grub_ieee1275_devices_iterate (int (*hook) (struct grub_ieee1275_devalias *alias))
+{
+  auto int it_through (struct grub_ieee1275_devalias *alias);
+  int it_through (struct grub_ieee1275_devalias *alias)
+  {
+    if (hook (alias))
+      return 1;
+    return grub_children_iterate (alias->path, it_through);
+  }
+
+  return grub_children_iterate ("/", it_through);
+}
+
+/* Iterate through all device aliases.  This function can be used to
+   find a device of a specific type.  */
+int
+grub_devalias_iterate (int (*hook) (struct grub_ieee1275_devalias *alias))
+{
+  grub_ieee1275_phandle_t aliases;
+  char *aliasname, *devtype;
+  grub_ssize_t actual;
+  struct grub_ieee1275_devalias alias;
+  int ret = 0;
+
+  if (grub_ieee1275_finddevice ("/aliases", &aliases))
+    return 0;
+
+  aliasname = grub_malloc (IEEE1275_MAX_PROP_LEN);
+  if (!aliasname)
+    return 0;
+  devtype = grub_malloc (IEEE1275_MAX_PROP_LEN);
+  if (!devtype)
+    {
+      grub_free (aliasname);
+      return 0;
+    }
+
+  /* Find the first property.  */
+  aliasname[0] = '\0';
+
+  while (grub_ieee1275_next_property (aliases, aliasname, aliasname) > 0)
+    {
+      grub_ieee1275_phandle_t dev;
+      grub_ssize_t pathlen;
+      char *devpath;
+
+      grub_dprintf ("devalias", "devalias name = %s\n", aliasname);
+
+      grub_ieee1275_get_property_length (aliases, aliasname, &pathlen);
+
+      /* The property `name' is a special case we should skip.  */
+      if (!grub_strcmp (aliasname, "name"))
+       continue;
+
+      /* Sun's OpenBoot often doesn't zero terminate the device alias
+        strings, so we will add a NULL byte at the end explicitly.  */
+      pathlen += 1;
+
+      devpath = grub_malloc (pathlen);
+      if (! devpath)
+       {
+         grub_free (devtype);
+         grub_free (aliasname);
+         return 0;
+       }
+
+      if (grub_ieee1275_get_property (aliases, aliasname, devpath, pathlen,
+                                     &actual))
+       {
+         grub_dprintf ("devalias", "get_property (%s) failed\n", aliasname);
+         goto nextprop;
+       }
+      devpath [actual] = '\0';
+
+      if (grub_ieee1275_finddevice (devpath, &dev))
+       {
+         grub_dprintf ("devalias", "finddevice (%s) failed\n", devpath);
+         goto nextprop;
+       }
+
+      if (grub_ieee1275_get_property (dev, "device_type", devtype,
+                                     IEEE1275_MAX_PROP_LEN, &actual))
+       {
+         /* NAND device don't have device_type property.  */
+          devtype[0] = 0;
+       }
+
+      alias.name = aliasname;
+      alias.path = devpath;
+      alias.type = devtype;
+      ret = hook (&alias);
+
+nextprop:
+      grub_free (devpath);
+      if (ret)
+       break;
+    }
+
+  grub_free (devtype);
+  grub_free (aliasname);
+  return ret;
+}
+
+/* Call the "map" method of /chosen/mmu.  */
+int
+grub_ieee1275_map (grub_addr_t phys, grub_addr_t virt, grub_size_t size,
+                  grub_uint32_t mode)
+{
+  struct map_args {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t method;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t mode;
+    grub_ieee1275_cell_t size;
+    grub_ieee1275_cell_t virt;
+#ifdef GRUB_MACHINE_SPARC64
+    grub_ieee1275_cell_t phys_high;
+#endif
+    grub_ieee1275_cell_t phys_low;
+    grub_ieee1275_cell_t catch_result;
+  } args;
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method",
+#ifdef GRUB_MACHINE_SPARC64
+                       7,
+#else
+                       6,
+#endif
+                       1);
+  args.method = (grub_ieee1275_cell_t) "map";
+  args.ihandle = grub_ieee1275_mmu;
+#ifdef GRUB_MACHINE_SPARC64
+  args.phys_high = 0;
+#endif
+  args.phys_low = phys;
+  args.virt = virt;
+  args.size = size;
+  args.mode = mode; /* Format is WIMG0PP.  */
+  args.catch_result = (grub_ieee1275_cell_t) -1;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+
+  return args.catch_result;
+}
+
+int
+grub_claimmap (grub_addr_t addr, grub_size_t size)
+{
+  if (grub_ieee1275_claim (addr, size, 0, 0))
+    return -1;
+
+  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_REAL_MODE)
+      && grub_ieee1275_map (addr, addr, size, 0x00))
+    {
+      grub_printf ("map failed: address 0x%llx, size 0x%llx\n",
+                  (long long) addr, (long long) size);
+      grub_ieee1275_release (addr, size);
+      return -1;
+    }
+
+  return 0;
+}
+
+/* Get the device arguments of the Open Firmware node name `path'.  */
+static char *
+grub_ieee1275_get_devargs (const char *path)
+{
+  char *colon = grub_strchr (path, ':');
+
+  if (! colon)
+    return 0;
+
+  return grub_strdup (colon + 1);
+}
+
+/* Get the device path of the Open Firmware node name `path'.  */
+static char *
+grub_ieee1275_get_devname (const char *path)
+{
+  char *colon = grub_strchr (path, ':');
+  char *newpath = 0;
+  int pathlen = grub_strlen (path);
+  auto int match_alias (struct grub_ieee1275_devalias *alias);
+
+  int match_alias (struct grub_ieee1275_devalias *curalias)
+    {
+      /* briQ firmware can change capitalization in /chosen/bootpath.  */
+      if (! grub_strncasecmp (curalias->path, path, pathlen))
+        {
+         newpath = grub_strdup (curalias->name);
+         return 1;
+       }
+
+      return 0;
+    }
+
+  if (colon)
+    pathlen = (int)(colon - path);
+
+  /* Try to find an alias for this device.  */
+  grub_devalias_iterate (match_alias);
+
+  if (! newpath)
+    newpath = grub_strndup (path, pathlen);
+
+  return newpath;
+}
+
+static char *
+grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype)
+{
+  char type[64]; /* XXX check size.  */
+  char *device = grub_ieee1275_get_devname (path);
+  char *args = grub_ieee1275_get_devargs (path);
+  char *ret = 0;
+  grub_ieee1275_phandle_t dev;
+
+  if (!args)
+    /* Shouldn't happen.  */
+    return 0;
+
+  /* We need to know what type of device it is in order to parse the full
+     file path properly.  */
+  if (grub_ieee1275_finddevice (device, &dev))
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "device %s not found", device);
+      goto fail;
+    }
+  if (grub_ieee1275_get_property (dev, "device_type", &type, sizeof type, 0))
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                 "device %s lacks a device_type property", device);
+      goto fail;
+    }
+
+  if (!grub_strcmp ("block", type))
+    {
+      /* The syntax of the device arguments is defined in the CHRP and PReP
+         IEEE1275 bindings: "[partition][,[filename]]".  */
+      char *comma = grub_strchr (args, ',');
+
+      if (ptype == GRUB_PARSE_FILENAME)
+       {
+         if (comma)
+           {
+             char *filepath = comma + 1;
+
+             /* Make sure filepath has leading backslash.  */
+             if (filepath[0] != '\\')
+               ret = grub_xasprintf ("\\%s", filepath);
+             else
+               ret = grub_strdup (filepath);
+           }
+       }
+      else if (ptype == GRUB_PARSE_PARTITION)
+        {
+         if (!comma)
+           ret = grub_strdup (args);
+         else
+           ret = grub_strndup (args, (grub_size_t)(comma - args));
+       }
+    }
+  else
+    {
+      /* XXX Handle net devices by configuring & registering a grub_net_dev
+        here, then return its name?
+        Example path: "net:<server ip>,<file name>,<client ip>,<gateway
+        ip>,<bootp retries>,<tftp retries>".  */
+      grub_printf ("Unsupported type %s for device %s\n", type, device);
+    }
+
+fail:
+  grub_free (device);
+  grub_free (args);
+  return ret;
+}
+
+char *
+grub_ieee1275_get_filename (const char *path)
+{
+  return grub_ieee1275_parse_args (path, GRUB_PARSE_FILENAME);
+}
+
+/* Convert a device name from IEEE1275 syntax to GRUB syntax.  */
+char *
+grub_ieee1275_encode_devname (const char *path)
+{
+  char *device = grub_ieee1275_get_devname (path);
+  char *partition = grub_ieee1275_parse_args (path, GRUB_PARSE_PARTITION);
+  char *encoding;
+
+  if (partition && partition[0])
+    {
+      unsigned int partno = grub_strtoul (partition, 0, 0);
+
+      if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS))
+       /* GRUB partition 1 is OF partition 0.  */
+       partno++;
+
+      encoding = grub_xasprintf ("(%s,%d)", device, partno);
+    }
+  else
+    encoding = grub_xasprintf ("(%s)", device);
+
+  grub_free (partition);
+  grub_free (device);
+
+  return encoding;
+}
+
+/* On i386, a firmware-independant grub_reboot() is provided by realmode.S.  */
+#ifndef __i386__
+void
+grub_reboot (void)
+{
+  grub_ieee1275_interpret ("reset-all", 0);
+}
+#endif
+
+void
+grub_halt (void)
+{
+  /* Not standardized.  We try three known commands.  */
+
+  grub_ieee1275_interpret ("shut-down", 0);
+  grub_ieee1275_interpret ("power-off", 0);
+  grub_ieee1275_interpret ("poweroff", 0);
+}
diff --git a/grub-core/kern/list.c b/grub-core/kern/list.c
new file mode 100644 (file)
index 0000000..379b0d8
--- /dev/null
@@ -0,0 +1,131 @@
+/* list.c - grub list function */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/list.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+void
+grub_list_push (grub_list_t *head, grub_list_t item)
+{
+  item->next = *head;
+  *head = item;
+}
+
+void *
+grub_list_pop (grub_list_t *head)
+{
+  grub_list_t item;
+
+  item = *head;
+  if (item)
+    *head = item->next;
+
+  return item;
+}
+
+void
+grub_list_remove (grub_list_t *head, grub_list_t item)
+{
+  grub_list_t *p, q;
+
+  for (p = head, q = *p; q; p = &(q->next), q = q->next)
+    if (q == item)
+      {
+       *p = q->next;
+       break;
+      }
+}
+
+int
+grub_list_iterate (grub_list_t head, grub_list_hook_t hook)
+{
+  grub_list_t p;
+
+  for (p = head; p; p = p->next)
+    if (hook (p))
+      return 1;
+
+  return 0;
+}
+
+void
+grub_list_insert (grub_list_t *head, grub_list_t item,
+                 grub_list_test_t test)
+{
+  grub_list_t *p, q;
+
+  for (p = head, q = *p; q; p = &(q->next), q = q->next)
+    if (test (item, q))
+      break;
+
+  *p = item;
+  item->next = q;
+}
+
+void *
+grub_named_list_find (grub_named_list_t head, const char *name)
+{
+  grub_named_list_t result = NULL;
+
+  auto int list_find (grub_named_list_t item);
+  int list_find (grub_named_list_t item)
+    {
+      if (! grub_strcmp (item->name, name))
+       {
+         result = item;
+         return 1;
+       }
+
+      return 0;
+    }
+
+  grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_find);
+  return result;
+}
+
+void
+grub_prio_list_insert (grub_prio_list_t *head, grub_prio_list_t nitem)
+{
+  int inactive = 0;
+
+  auto int test (grub_prio_list_t new_item, grub_prio_list_t item);
+  int test (grub_prio_list_t new_item, grub_prio_list_t item)
+    {
+      int r;
+
+      r = grub_strcmp (new_item->name, item->name);
+      if (r)
+       return (r < 0);
+
+      if (new_item->prio >= (item->prio & GRUB_PRIO_LIST_PRIO_MASK))
+       {
+         item->prio &= ~GRUB_PRIO_LIST_FLAG_ACTIVE;
+         return 1;
+       }
+
+      inactive = 1;
+      return 0;
+    }
+
+  grub_list_insert (GRUB_AS_LIST_P (head), GRUB_AS_LIST (nitem),
+                   (grub_list_test_t) test);
+  if (! inactive)
+    nitem->prio |= GRUB_PRIO_LIST_FLAG_ACTIVE;
+}
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
new file mode 100644 (file)
index 0000000..1fdf4ab
--- /dev/null
@@ -0,0 +1,199 @@
+/* main.c - the kernel main routine */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2006,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/symbol.h>
+#include <grub/dl.h>
+#include <grub/term.h>
+#include <grub/file.h>
+#include <grub/device.h>
+#include <grub/env.h>
+#include <grub/mm.h>
+#include <grub/command.h>
+#include <grub/reader.h>
+#include <grub/parser.h>
+
+void
+grub_module_iterate (int (*hook) (struct grub_module_header *header))
+{
+  struct grub_module_info *modinfo;
+  struct grub_module_header *header;
+  grub_addr_t modbase;
+
+  modbase = grub_arch_modules_addr ();
+  modinfo = (struct grub_module_info *) modbase;
+
+  /* Check if there are any modules.  */
+  if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC)
+    return;
+
+  for (header = (struct grub_module_header *) (modbase + modinfo->offset);
+       header < (struct grub_module_header *) (modbase + modinfo->size);
+       header = (struct grub_module_header *) ((char *) header + header->size))
+    {
+      if (hook (header))
+       break;
+    }
+}
+
+/* This is actualy platform-independant but used only on yeeloong and sparc.  */
+#if defined (GRUB_MACHINE_MIPS_YEELOONG) || defined (GRUB_MACHINE_SPARC64)
+grub_addr_t
+grub_modules_get_end (void)
+{
+  struct grub_module_info *modinfo;
+  grub_addr_t modbase;
+
+  modbase = grub_arch_modules_addr ();
+  modinfo = (struct grub_module_info *) modbase;
+
+  /* Check if there are any modules.  */
+  if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC)
+    return modbase;
+
+  return modbase + modinfo->size;
+}
+#endif
+
+/* Load all modules in core.  */
+static void
+grub_load_modules (void)
+{
+  auto int hook (struct grub_module_header *);
+  int hook (struct grub_module_header *header)
+    {
+      /* Not an ELF module, skip.  */
+      if (header->type != OBJ_TYPE_ELF)
+        return 0;
+
+      if (! grub_dl_load_core ((char *) header + sizeof (struct grub_module_header),
+                              (header->size - sizeof (struct grub_module_header))))
+       grub_fatal ("%s", grub_errmsg);
+
+      if (grub_errno)
+       grub_print_error ();
+
+      return 0;
+    }
+
+  grub_module_iterate (hook);
+}
+
+static void
+grub_load_config (void)
+{
+  auto int hook (struct grub_module_header *);
+  int hook (struct grub_module_header *header)
+    {
+      /* Not an embedded config, skip.  */
+      if (header->type != OBJ_TYPE_CONFIG)
+       return 0;
+
+      grub_parser_execute ((char *) header +
+                          sizeof (struct grub_module_header));
+      return 1;
+    }
+
+  grub_module_iterate (hook);
+}
+
+/* Write hook for the environment variables of root. Remove surrounding
+   parentheses, if any.  */
+static char *
+grub_env_write_root (struct grub_env_var *var __attribute__ ((unused)),
+                    const char *val)
+{
+  /* XXX Is it better to check the existence of the device?  */
+  grub_size_t len = grub_strlen (val);
+
+  if (val[0] == '(' && val[len - 1] == ')')
+    return grub_strndup (val + 1, len - 2);
+
+  return grub_strdup (val);
+}
+
+/* Set the root device according to the dl prefix.  */
+static void
+grub_set_root_dev (void)
+{
+  const char *prefix;
+
+  grub_register_variable_hook ("root", 0, grub_env_write_root);
+
+  prefix = grub_env_get ("prefix");
+
+  if (prefix)
+    {
+      char *dev;
+
+      dev = grub_file_get_device_name (prefix);
+      if (dev)
+       {
+         grub_env_set ("root", dev);
+         grub_free (dev);
+       }
+    }
+}
+
+/* Load the normal mode module and execute the normal mode if possible.  */
+static void
+grub_load_normal_mode (void)
+{
+  /* Load the module.  */
+  grub_dl_load ("normal");
+
+  /* Something went wrong.  Print errors here to let user know why we're entering rescue mode.  */
+  grub_print_error ();
+  grub_errno = 0;
+
+  grub_command_execute ("normal", 0, 0);
+}
+
+/* The main routine.  */
+void
+grub_main (void)
+{
+  /* First of all, initialize the machine.  */
+  grub_machine_init ();
+
+  /* Hello.  */
+  grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
+  grub_printf ("Welcome to GRUB!\n\n");
+  grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
+
+  /* Load pre-loaded modules and free the space.  */
+  grub_register_exported_symbols ();
+#ifdef GRUB_LINKER_HAVE_INIT
+  grub_arch_dl_init_linker ();
+#endif  
+  grub_load_modules ();
+
+  /* It is better to set the root device as soon as possible,
+     for convenience.  */
+  grub_machine_set_prefix ();
+  grub_set_root_dev ();
+
+  grub_register_core_commands ();
+  grub_register_rescue_parser ();
+
+  grub_load_config ();
+  grub_load_normal_mode ();
+  grub_rescue_run ();
+}
diff --git a/grub-core/kern/mips/cache.S b/grub-core/kern/mips/cache.S
new file mode 100644 (file)
index 0000000..2c35b6d
--- /dev/null
@@ -0,0 +1,7 @@
+
+#include <grub/symbol.h>
+
+FUNCTION (grub_cpu_flush_cache)
+FUNCTION (grub_arch_sync_caches)
+#include "cache_flush.S"
+       j $ra
diff --git a/grub-core/kern/mips/cache_flush.S b/grub-core/kern/mips/cache_flush.S
new file mode 100644 (file)
index 0000000..5667ee7
--- /dev/null
@@ -0,0 +1,23 @@
+       move $t2, $a0
+       addu $t3, $a0, $a1
+       srl $t2, $t2, 5
+       sll $t2, $t2, 5
+       addu $t3, $t3, 0x1f
+       srl $t3, $t3, 5
+       sll $t3, $t3, 5
+       move $t0, $t2
+       subu $t1, $t3, $t2
+1:
+       cache 1, 0($t0)
+       addiu $t0, $t0, 0x1
+       addiu $t1, $t1, 0xffff
+       bne $t1, $zero, 1b
+       sync
+       move $t0, $t2
+       subu $t1, $t3, $t2
+2:
+       cache 0, 0($t0)
+       addiu $t0, $t0, 0x1
+       addiu $t1, $t1, 0xffff
+       bne $t1, $zero, 2b
+       sync
diff --git a/grub-core/kern/mips/dl.c b/grub-core/kern/mips/dl.c
new file mode 100644 (file)
index 0000000..485955e
--- /dev/null
@@ -0,0 +1,237 @@
+/* dl-386.c - arch-dependent part of loadable module support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/cpu/types.h>
+#include <grub/mm.h>
+
+/* Dummy __gnu_local_gp. Resolved by linker.  */
+static char __gnu_local_gp_dummy;
+
+/* Check if EHDR is a valid ELF header.  */
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+
+  /* Check the magic numbers.  */
+#ifdef WORDS_BIGENDIAN
+  if (e->e_ident[EI_CLASS] != ELFCLASS32
+      || e->e_ident[EI_DATA] != ELFDATA2MSB
+      || e->e_machine != EM_MIPS)
+#else
+  if (e->e_ident[EI_CLASS] != ELFCLASS32
+      || e->e_ident[EI_DATA] != ELFDATA2LSB
+      || e->e_machine != EM_MIPS)
+#endif
+    return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
+
+  return GRUB_ERR_NONE;
+}
+
+/* Relocate symbols.  */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+  Elf_Shdr *s;
+  Elf_Word entsize;
+  unsigned i;
+  grub_size_t gp_size = 0;
+  /* FIXME: suboptimal.  */
+  grub_uint32_t *gp, *gpptr;
+  grub_uint32_t gp0;
+
+  /* Find a symbol table.  */
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
+
+  entsize = s->sh_entsize;
+
+  /* Find reginfo. */
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_MIPS_REGINFO)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_MODULE, "no reginfo found");
+
+  gp0 = ((grub_uint32_t *)((char *) e + s->sh_offset))[5];
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_REL)
+      {
+       grub_dl_segment_t seg;
+
+       /* Find the target segment.  */
+       for (seg = mod->segment; seg; seg = seg->next)
+         if (seg->section == s->sh_info)
+           break;
+
+       if (seg)
+         {
+           Elf_Rel *rel, *max;
+
+           for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
+                  max = rel + s->sh_size / s->sh_entsize;
+                rel < max;
+                rel++)
+               switch (ELF_R_TYPE (rel->r_info))
+                 {
+                 case R_MIPS_GOT16:
+                 case R_MIPS_CALL16:
+                 case R_MIPS_GPREL32:
+                   gp_size += 4;
+                   break;
+                 }
+         }
+      }
+
+  if (gp_size > 0x08000)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "__gnu_local_gp is too big\n");
+
+  gpptr = gp = grub_malloc (gp_size);
+  if (!gp)
+    return grub_errno;
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_REL)
+      {
+       grub_dl_segment_t seg;
+
+       /* Find the target segment.  */
+       for (seg = mod->segment; seg; seg = seg->next)
+         if (seg->section == s->sh_info)
+           break;
+
+       if (seg)
+         {
+           Elf_Rel *rel, *max;
+
+           for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
+                  max = rel + s->sh_size / s->sh_entsize;
+                rel < max;
+                rel++)
+             {
+               Elf_Word *addr;
+               Elf_Sym *sym;
+
+               if (seg->size < rel->r_offset)
+                 return grub_error (GRUB_ERR_BAD_MODULE,
+                                    "reloc offset is out of the segment");
+
+               addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
+               sym = (Elf_Sym *) ((char *) mod->symtab
+                                    + entsize * ELF_R_SYM (rel->r_info));
+               if (sym->st_value == (grub_addr_t) &__gnu_local_gp_dummy)
+                 sym->st_value = (grub_addr_t) gp;
+
+               switch (ELF_R_TYPE (rel->r_info))
+                 {
+                 case R_MIPS_HI16:
+                   {
+                     grub_uint32_t value;
+                     Elf_Rel *rel2;
+                     
+                     /* Handle partner lo16 relocation. Lower part is
+                        treated as signed. Hence add 0x8000 to compensate. 
+                      */
+                     value = (*(grub_uint16_t *) addr << 16)
+                       + sym->st_value + 0x8000;
+                     for (rel2 = rel + 1; rel2 < max; rel2++)
+                       if (ELF_R_SYM (rel2->r_info)
+                           == ELF_R_SYM (rel->r_info)
+                           && ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16)
+                         {
+                           value += *(grub_int16_t *)
+                             ((char *) seg->addr + rel2->r_offset);
+                           break;
+                         }
+                     *(grub_uint16_t *) addr = (value >> 16) & 0xffff;
+                   }
+                   break;
+                 case R_MIPS_LO16:
+                   *(grub_uint16_t *) addr += (sym->st_value) & 0xffff;
+                   break;
+                 case R_MIPS_32:
+                   *(grub_uint32_t *) addr += sym->st_value;
+                   break;
+                 case R_MIPS_GPREL32:
+                   *(grub_uint32_t *) addr = sym->st_value
+                     + *(grub_uint32_t *) addr + gp0 - (grub_uint32_t)gp;
+                   break;
+
+                 case R_MIPS_26:
+                   {
+                     grub_uint32_t value;
+                     grub_uint32_t raw;
+                     raw = (*(grub_uint32_t *) addr) & 0x3ffffff;
+                     value = raw << 2;
+                     value += sym->st_value;
+                     raw = (value >> 2) & 0x3ffffff;
+                       
+                     *(grub_uint32_t *) addr = 
+                       raw | ((*(grub_uint32_t *) addr) & 0xfc000000);
+                   }
+                   break;
+                 case R_MIPS_GOT16:
+                 case R_MIPS_CALL16:
+                   /* FIXME: reuse*/
+                   *gpptr = sym->st_value + *(grub_uint16_t *) addr;
+                   *(grub_uint16_t *) addr
+                     = sizeof (grub_uint32_t) * (gpptr - gp);
+                   gpptr++;
+                   break;
+                 default:
+                   {
+                     grub_free (gp);
+                     return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                                        "Unknown relocation type %d\n",
+                                        ELF_R_TYPE (rel->r_info));
+                   }
+                   break;
+                 }
+             }
+         }
+      }
+
+  return GRUB_ERR_NONE;
+}
+
+void 
+grub_arch_dl_init_linker (void)
+{
+  grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0);
+}
+
diff --git a/grub-core/kern/mips/init.c b/grub-core/kern/mips/init.c
new file mode 100644 (file)
index 0000000..5adcedc
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/env.h>
+#include <grub/mips/kernel.h>
+
+void
+grub_machine_set_prefix (void)
+{
+  grub_env_set ("prefix", grub_prefix);
+}
+
+extern char _end[];
+
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+  return (grub_addr_t) _end;
+}
diff --git a/grub-core/kern/mips/qemu-mips/init.c b/grub-core/kern/mips/qemu-mips/init.c
new file mode 100644 (file)
index 0000000..866c7a8
--- /dev/null
@@ -0,0 +1,61 @@
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/time.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/time.h>
+#include <grub/machine/kernel.h>
+#include <grub/machine/memory.h>
+#include <grub/cpu/kernel.h>
+
+#define RAMSIZE (*(grub_uint32_t *) ((16 << 20) - 264))
+
+grub_uint32_t
+grub_get_rtc (void)
+{
+  static int calln = 0;
+  return calln++;
+}
+
+void
+grub_machine_init (void)
+{
+  grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_USABLE,
+                      RAMSIZE - (GRUB_MACHINE_MEMORY_USABLE & 0x7fffffff));
+  grub_install_get_time_ms (grub_rtc_get_time_ms);
+}
+
+void
+grub_machine_fini (void)
+{
+}
+
+void
+grub_exit (void)
+{
+  while (1);
+}
+
+void
+grub_halt (void)
+{
+  while (1);
+}
+
+void
+grub_reboot (void)
+{
+  while (1);
+}
+
+grub_err_t 
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, 
+                                                        grub_uint64_t, 
+                                                        grub_uint32_t))
+{
+  hook (0, RAMSIZE,
+       GRUB_MACHINE_MEMORY_AVAILABLE);
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S
new file mode 100644 (file)
index 0000000..5e3fb7a
--- /dev/null
@@ -0,0 +1,218 @@
+/* startup.S - Startup code for the MIPS.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/cpu/kernel.h>
+#include <grub/machine/memory.h>
+
+#define BASE_ADDR 8
+       
+.extern __bss_start
+.extern _end
+       
+       .globl __start, _start, start
+__start:
+_start:
+start: 
+       bal codestart
+base:  
+       . = _start + GRUB_KERNEL_CPU_COMPRESSED_SIZE
+compressed_size:
+       .long 0
+       . = _start + GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE
+total_module_size:
+       .long 0
+       . = _start + GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE
+kernel_image_size:     
+       .long   0
+codestart:
+       /* Save our base.  */
+       move $s0, $ra
+
+       /* Parse arguments. Has to be done before relocation.
+       So need to do it in asm.  */
+#ifdef GRUB_MACHINE_MIPS_YEELOONG
+       /* $a2 has the environment.  */
+       move $t0, $a2
+argcont:       
+       lw $t1, 0($t0)
+       beq $t1, $zero, argdone
+#define DO_PARSE(str, reg) \
+       addiu $t2, $s0, (str-base);\
+       bal parsestr;\
+       beq $v0, $zero, 1f;\
+       move reg, $v0;\
+       b 2f;\
+1:     
+       DO_PARSE (busclockstr, $s2)
+       DO_PARSE (cpuclockstr, $s3)
+       DO_PARSE (memsizestr, $s4)
+       DO_PARSE (highmemsizestr, $s5)
+2:     
+       addiu $t0, $t0, 4
+       b argcont
+parsestr:
+       move $v0, $zero
+       move $t3, $t1
+3:     
+       lb $t4, 0($t2)
+       lb $t5, 0($t3)
+       addiu $t2, $t2, 1
+       addiu $t3, $t3, 1
+       beq $t5, $zero, 1f
+       beq $t5, $t4, 3b
+       bne $t4, $zero, 1f
+
+       addiu $t3, $t3, 0xffff
+digcont:       
+       lb $t5, 0($t3)
+       /* Substract '0' from digit.  */
+       addiu $t5, $t5, 0xffd0
+       bltz $t5, 1f
+       addiu $t4, $t5, 0xfff7
+       bgtz $t4, 1f
+       /* Multiply $v0 by 10 with bitshifts. */
+       sll $v0, $v0, 1
+       sll $t4, $v0, 2
+       addu $v0, $v0, $t4
+       addu $v0, $v0, $t5
+       addiu $t3, $t3, 1
+       b digcont
+1:
+       jr $ra
+busclockstr:   .asciiz "busclock="
+cpuclockstr:   .asciiz "cpuclock="
+memsizestr:    .asciiz "memsize="
+highmemsizestr:        .asciiz "highmemsize="
+       .p2align 2
+argdone:
+#endif
+
+       /* Decompress the payload. */
+       addiu $a0, $s0, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR
+       lui $a1, %hi(compressed)
+       addiu $a1, %lo(compressed)
+       lw $a2, (GRUB_KERNEL_CPU_COMPRESSED_SIZE - BASE_ADDR)($s0)
+       move $s1, $a1
+
+       /* $a0 contains source compressed address, $a1 is destination,
+          $a2 is compressed size. FIXME: put LZMA here. Don't clober $s0,
+          $s1, $s2, $s3, $s4 and $s5.
+          On return $v0 contains uncompressed size.
+       */
+       move $v0, $a2
+reloccont:
+       lb $t4, 0($a0)
+       sb $t4, 0($a1)
+       addiu $a1,$a1,1
+       addiu $a0,$a0,1
+       addiu $a2, 0xffff
+       bne $a2, $0, reloccont
+
+       move $a0, $s1
+       move $a1, $v0
+
+#include "cache_flush.S"
+
+       lui $t1, %hi(cont)
+       addiu $t1, %lo(cont)
+
+       jr $t1
+       . = _start + GRUB_KERNEL_CPU_RAW_SIZE
+compressed:    
+       . = _start + GRUB_KERNEL_CPU_PREFIX
+
+VARIABLE(grub_prefix)
+
+       /* to be filled by grub-mkelfimage */
+
+       /*
+        *  Leave some breathing room for the prefix.
+        */
+
+       . = _start + GRUB_KERNEL_CPU_DATA_END
+#ifdef GRUB_MACHINE_MIPS_YEELOONG
+VARIABLE (grub_arch_busclock)
+       .long 0
+VARIABLE (grub_arch_cpuclock)
+       .long 0
+VARIABLE (grub_arch_memsize)
+       .long 0
+VARIABLE (grub_arch_highmemsize)
+       .long 0
+#endif
+cont:
+
+#ifdef GRUB_MACHINE_MIPS_YEELOONG
+       lui $t1, %hi(grub_arch_busclock)
+       addiu $t1, %lo(grub_arch_busclock)
+       sw $s2, 0($t1)
+       sw $s3, 4($t1)
+       sw $s4, 8($t1)
+       sw $s5, 12($t1)
+#endif
+
+       /* Move the modules out of BSS.  */
+       lui $t1, %hi(_start)
+       addiu $t1, %lo(_start)
+       lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0)
+       addu $t2, $t1, $t2
+       
+       lui $t1, %hi(_end)
+       addiu $t1, %lo(_end)
+       addiu $t1, (GRUB_MOD_ALIGN-1)
+       li $t3, (GRUB_MOD_ALIGN-1)
+       nor $t3, $t3, $0
+       and $t1, $t1, $t3
+       
+       lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($s0)
+
+       /* Backward copy.  */
+       add $t1, $t1, $t3
+       add $t2, $t2, $t3
+       addiu $t1, $t1, 0xffff
+       addiu $t2, $t2, 0xffff
+
+       /* $t2 is source. $t1 is destination. $t3 is size.  */
+modulesmovcont:
+       lb $t4, 0($t2)
+       sb $t4, 0($t1)
+       addiu $t1,$t1,0xffff
+       addiu $t2,$t2,0xffff
+       addiu $t3, 0xffff
+       bne $t3, $0, modulesmovcont
+
+       /* Clean BSS.  */
+       
+       lui $t1, %hi(__bss_start)
+       addiu $t1, %lo(__bss_start)
+       lui $t2, %hi(_end)
+       addiu $t2, %lo(_end)
+bsscont:
+       sb $0,0($t1)
+       addiu $t1,$t1,1
+       sltu $t3,$t1,$t2
+       bne $t3, $0, bsscont
+
+       li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH
+       lui $t1, %hi(grub_main)
+       addiu $t1, %lo(grub_main)
+
+       jr $t1
+
diff --git a/grub-core/kern/mips/yeeloong/init.c b/grub-core/kern/mips/yeeloong/init.c
new file mode 100644 (file)
index 0000000..6bba27b
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/time.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/time.h>
+#include <grub/machine/kernel.h>
+#include <grub/machine/memory.h>
+#include <grub/cpu/kernel.h>
+
+extern void grub_video_sm712_init (void);
+extern void grub_video_init (void);
+extern void grub_bitmap_init (void);
+extern void grub_font_init (void);
+extern void grub_gfxterm_init (void);
+extern void grub_at_keyboard_init (void);
+
+/* FIXME: use interrupt to count high.  */
+grub_uint64_t
+grub_get_rtc (void)
+{
+  static grub_uint32_t high = 0;
+  static grub_uint32_t last = 0;
+  grub_uint32_t low;
+
+  asm volatile ("mfc0 %0, $9": "=r" (low));
+  if (low < last)
+    high++;
+  last = low;
+
+  return (((grub_uint64_t) high) << 32) | low;
+}
+
+grub_err_t
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+                                                        grub_uint64_t,
+                                                        grub_uint32_t))
+{
+  hook (GRUB_ARCH_LOWMEMPSTART, grub_arch_memsize << 20,
+       GRUB_MACHINE_MEMORY_AVAILABLE);
+  hook (GRUB_ARCH_HIGHMEMPSTART, grub_arch_highmemsize << 20,
+       GRUB_MACHINE_MEMORY_AVAILABLE);
+  return GRUB_ERR_NONE;
+}
+
+void
+grub_machine_init (void)
+{
+  grub_addr_t modend;
+  modend = grub_modules_get_end ();
+  grub_mm_init_region ((void *) modend, (grub_arch_memsize << 20)
+                      - (modend - GRUB_ARCH_LOWMEMVSTART));
+  /* FIXME: use upper memory as well.  */
+  grub_install_get_time_ms (grub_rtc_get_time_ms);
+
+  /* Initialize output terminal (can't be done earlier, as gfxterm
+     relies on a working heap.  */
+  grub_video_sm712_init ();
+  grub_video_init ();
+  grub_bitmap_init ();
+  grub_font_init ();
+  grub_gfxterm_init ();
+
+  grub_at_keyboard_init ();
+}
+
+void
+grub_machine_fini (void)
+{
+}
+
+void
+grub_exit (void)
+{
+  while (1);
+}
+
+void
+grub_halt (void)
+{
+  while (1);
+}
+
+void
+grub_reboot (void)
+{
+  while (1);
+}
+
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
new file mode 100644 (file)
index 0000000..ccc01d4
--- /dev/null
@@ -0,0 +1,1077 @@
+/* misc.c - definitions of misc functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <stdarg.h>
+#include <grub/term.h>
+#include <grub/env.h>
+#include <grub/i18n.h>
+
+static int
+grub_vsnprintf_real (char *str, grub_size_t n, const char *fmt, va_list args);
+
+static int
+grub_iswordseparator (int c)
+{
+  return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&');
+}
+
+/* grub_gettext_dummy is not translating anything.  */
+static const char *
+grub_gettext_dummy (const char *s)
+{
+  return s;
+}
+
+const char* (*grub_gettext) (const char *s) = grub_gettext_dummy;
+
+void *
+grub_memmove (void *dest, const void *src, grub_size_t n)
+{
+  char *d = (char *) dest;
+  const char *s = (const char *) src;
+
+  if (d < s)
+    while (n--)
+      *d++ = *s++;
+  else
+    {
+      d += n;
+      s += n;
+
+      while (n--)
+       *--d = *--s;
+    }
+
+  return dest;
+}
+
+#ifndef APPLE_CC
+void *memmove (void *dest, const void *src, grub_size_t n)
+  __attribute__ ((alias ("grub_memmove")));
+/* GCC emits references to memcpy() for struct copies etc.  */
+void *memcpy (void *dest, const void *src, grub_size_t n)
+  __attribute__ ((alias ("grub_memmove")));
+#else
+void *memcpy (void *dest, const void *src, grub_size_t n)
+{
+       return grub_memmove (dest, src, n);
+}
+void *memmove (void *dest, const void *src, grub_size_t n)
+{
+       return grub_memmove (dest, src, n);
+}
+#endif
+
+char *
+grub_strcpy (char *dest, const char *src)
+{
+  char *p = dest;
+
+  while ((*p++ = *src++) != '\0')
+    ;
+
+  return dest;
+}
+
+char *
+grub_strncpy (char *dest, const char *src, int c)
+{
+  char *p = dest;
+
+  while ((*p++ = *src++) != '\0' && --c)
+    ;
+
+  return dest;
+}
+
+char *
+grub_stpcpy (char *dest, const char *src)
+{
+  char *d = dest;
+  const char *s = src;
+
+  do
+    *d++ = *s;
+  while (*s++ != '\0');
+
+  return d - 1;
+}
+
+int
+grub_printf (const char *fmt, ...)
+{
+  va_list ap;
+  int ret;
+
+  va_start (ap, fmt);
+  ret = grub_vprintf (fmt, ap);
+  va_end (ap);
+
+  return ret;
+}
+
+int
+grub_printf_ (const char *fmt, ...)
+{
+  va_list ap;
+  int ret;
+
+  va_start (ap, fmt);
+  ret = grub_vprintf (_(fmt), ap);
+  va_end (ap);
+
+  return ret;
+}
+
+int
+grub_puts (const char *s)
+{
+  while (*s)
+    {
+      grub_putchar (*s);
+      s++;
+    }
+  grub_putchar ('\n');
+
+  return 1;    /* Cannot fail.  */
+}
+
+int
+grub_puts_ (const char *s)
+{
+  return grub_puts (_(s));
+}
+
+#if defined (APPLE_CC) && ! defined (GRUB_UTIL)
+int
+grub_err_printf (const char *fmt, ...)
+{
+       va_list ap;
+       int ret;
+
+       va_start (ap, fmt);
+       ret = grub_vprintf (fmt, ap);
+       va_end (ap);
+
+       return ret;
+}
+#endif
+
+#if ! defined (APPLE_CC) && ! defined (GRUB_UTIL)
+int grub_err_printf (const char *fmt, ...)
+__attribute__ ((alias("grub_printf")));
+#endif
+
+void
+grub_real_dprintf (const char *file, const int line, const char *condition,
+                  const char *fmt, ...)
+{
+  va_list args;
+  const char *debug = grub_env_get ("debug");
+
+  if (! debug)
+    return;
+
+  if (grub_strword (debug, "all") || grub_strword (debug, condition))
+    {
+      grub_printf ("%s:%d: ", file, line);
+      va_start (args, fmt);
+      grub_vprintf (fmt, args);
+      va_end (args);
+    }
+}
+
+int
+grub_vprintf (const char *fmt, va_list args)
+{
+  int ret;
+
+  ret = grub_vsnprintf_real (0, 0, fmt, args);
+  return ret;
+}
+
+int
+grub_memcmp (const void *s1, const void *s2, grub_size_t n)
+{
+  const char *t1 = s1;
+  const char *t2 = s2;
+
+  while (n--)
+    {
+      if (*t1 != *t2)
+       return (int) *t1 - (int) *t2;
+
+      t1++;
+      t2++;
+    }
+
+  return 0;
+}
+#ifndef APPLE_CC
+int memcmp (const void *s1, const void *s2, grub_size_t n)
+  __attribute__ ((alias ("grub_memcmp")));
+#else
+int memcmp (const void *s1, const void *s2, grub_size_t n)
+{
+  return grub_memcmp (s1, s2, n);
+}
+#endif
+
+int
+grub_strcmp (const char *s1, const char *s2)
+{
+  while (*s1 && *s2)
+    {
+      if (*s1 != *s2)
+       break;
+
+      s1++;
+      s2++;
+    }
+
+  return (int) *s1 - (int) *s2;
+}
+
+int
+grub_strncmp (const char *s1, const char *s2, grub_size_t n)
+{
+  if (n == 0)
+    return 0;
+
+  while (*s1 && *s2 && --n)
+    {
+      if (*s1 != *s2)
+       break;
+
+      s1++;
+      s2++;
+    }
+
+  return (int) *s1 - (int) *s2;
+}
+
+char *
+grub_strchr (const char *s, int c)
+{
+  do
+    {
+      if (*s == c)
+       return (char *) s;
+    }
+  while (*s++);
+
+  return 0;
+}
+
+char *
+grub_strrchr (const char *s, int c)
+{
+  char *p = NULL;
+
+  do
+    {
+      if (*s == c)
+       p = (char *) s;
+    }
+  while (*s++);
+
+  return p;
+}
+
+/* Copied from gnulib.
+   Written by Bruno Haible <bruno@clisp.org>, 2005. */
+char *
+grub_strstr (const char *haystack, const char *needle)
+{
+  /* Be careful not to look at the entire extent of haystack or needle
+     until needed.  This is useful because of these two cases:
+       - haystack may be very long, and a match of needle found early,
+       - needle may be very long, and not even a short initial segment of
+       needle may be found in haystack.  */
+  if (*needle != '\0')
+    {
+      /* Speed up the following searches of needle by caching its first
+        character.  */
+      char b = *needle++;
+
+      for (;; haystack++)
+       {
+         if (*haystack == '\0')
+           /* No match.  */
+           return NULL;
+         if (*haystack == b)
+           /* The first character matches.  */
+           {
+             const char *rhaystack = haystack + 1;
+             const char *rneedle = needle;
+
+             for (;; rhaystack++, rneedle++)
+               {
+                 if (*rneedle == '\0')
+                   /* Found a match.  */
+                   return (char *) haystack;
+                 if (*rhaystack == '\0')
+                   /* No match.  */
+                   return NULL;
+                 if (*rhaystack != *rneedle)
+                   /* Nothing in this round.  */
+                   break;
+               }
+           }
+       }
+    }
+  else
+    return (char *) haystack;
+}
+
+int
+grub_strword (const char *haystack, const char *needle)
+{
+  const char *n_pos = needle;
+
+  while (grub_iswordseparator (*haystack))
+    haystack++;
+
+  while (*haystack)
+    {
+      /* Crawl both the needle and the haystack word we're on.  */
+      while(*haystack && !grub_iswordseparator (*haystack)
+            && *haystack == *n_pos)
+        {
+          haystack++;
+          n_pos++;
+        }
+
+      /* If we reached the end of both words at the same time, the word
+      is found. If not, eat everything in the haystack that isn't the
+      next word (or the end of string) and "reset" the needle.  */
+      if ( (!*haystack || grub_iswordseparator (*haystack))
+         && (!*n_pos || grub_iswordseparator (*n_pos)))
+        return 1;
+      else
+        {
+          n_pos = needle;
+          while (*haystack && !grub_iswordseparator (*haystack))
+            haystack++;
+          while (grub_iswordseparator (*haystack))
+            haystack++;
+        }
+    }
+
+  return 0;
+}
+
+int
+grub_isspace (int c)
+{
+  return (c == '\n' || c == '\r' || c == ' ' || c == '\t');
+}
+
+int
+grub_isprint (int c)
+{
+  return (c >= ' ' && c <= '~');
+}
+
+
+unsigned long
+grub_strtoul (const char *str, char **end, int base)
+{
+  unsigned long long num;
+
+  num = grub_strtoull (str, end, base);
+  if (num > ~0UL)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
+      return ~0UL;
+    }
+
+  return (unsigned long) num;
+}
+
+unsigned long long
+grub_strtoull (const char *str, char **end, int base)
+{
+  unsigned long long num = 0;
+  int found = 0;
+
+  /* Skip white spaces.  */
+  while (*str && grub_isspace (*str))
+    str++;
+
+  /* Guess the base, if not specified. The prefix `0x' means 16, and
+     the prefix `0' means 8.  */
+  if (str[0] == '0')
+    {
+      if (str[1] == 'x')
+       {
+         if (base == 0 || base == 16)
+           {
+             base = 16;
+             str += 2;
+           }
+       }
+      else if (base == 0 && str[1] >= '0' && str[1] <= '7')
+       base = 8;
+    }
+
+  if (base == 0)
+    base = 10;
+
+  while (*str)
+    {
+      unsigned long digit;
+
+      digit = grub_tolower (*str) - '0';
+      if (digit > 9)
+       {
+         digit += '0' - 'a' + 10;
+         if (digit >= (unsigned long) base)
+           break;
+       }
+
+      found = 1;
+
+      /* NUM * BASE + DIGIT > ~0ULL */
+      if (num > grub_divmod64 (~0ULL - digit, base, 0))
+       {
+         grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
+         return ~0ULL;
+       }
+
+      num = num * base + digit;
+      str++;
+    }
+
+  if (! found)
+    {
+      grub_error (GRUB_ERR_BAD_NUMBER, "unrecognized number");
+      return 0;
+    }
+
+  if (end)
+    *end = (char *) str;
+
+  return num;
+}
+
+char *
+grub_strdup (const char *s)
+{
+  grub_size_t len;
+  char *p;
+
+  len = grub_strlen (s) + 1;
+  p = (char *) grub_malloc (len);
+  if (! p)
+    return 0;
+
+  return grub_memcpy (p, s, len);
+}
+
+char *
+grub_strndup (const char *s, grub_size_t n)
+{
+  grub_size_t len;
+  char *p;
+
+  len = grub_strlen (s);
+  if (len > n)
+    len = n;
+  p = (char *) grub_malloc (len + 1);
+  if (! p)
+    return 0;
+
+  grub_memcpy (p, s, len);
+  p[len] = '\0';
+  return p;
+}
+
+void *
+grub_memset (void *s, int c, grub_size_t n)
+{
+  unsigned char *p = (unsigned char *) s;
+
+  while (n--)
+    *p++ = (unsigned char) c;
+
+  return s;
+}
+#ifndef APPLE_CC
+void *memset (void *s, int c, grub_size_t n)
+  __attribute__ ((alias ("grub_memset")));
+#else
+void *memset (void *s, int c, grub_size_t n)
+{
+  return grub_memset (s, c, n);
+}
+#endif
+
+grub_size_t
+grub_strlen (const char *s)
+{
+  const char *p = s;
+
+  while (*p)
+    p++;
+
+  return p - s;
+}
+
+static inline void
+grub_reverse (char *str)
+{
+  char *p = str + grub_strlen (str) - 1;
+
+  while (str < p)
+    {
+      char tmp;
+
+      tmp = *str;
+      *str = *p;
+      *p = tmp;
+      str++;
+      p--;
+    }
+}
+
+/* Divide N by D, return the quotient, and store the remainder in *R.  */
+grub_uint64_t
+grub_divmod64 (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r)
+{
+  /* This algorithm is typically implemented by hardware. The idea
+     is to get the highest bit in N, 64 times, by keeping
+     upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
+     represents the high 64 bits in 128-bits space.  */
+  unsigned bits = 64;
+  unsigned long long q = 0;
+  unsigned m = 0;
+
+  /* Skip the slow computation if 32-bit arithmetic is possible.  */
+  if (n < 0xffffffff)
+    {
+      if (r)
+       *r = ((grub_uint32_t) n) % d;
+
+      return ((grub_uint32_t) n) / d;
+    }
+
+  while (bits--)
+    {
+      m <<= 1;
+
+      if (n & (1ULL << 63))
+       m |= 1;
+
+      q <<= 1;
+      n <<= 1;
+
+      if (m >= d)
+       {
+         q |= 1;
+         m -= d;
+       }
+    }
+
+  if (r)
+    *r = m;
+
+  return q;
+}
+
+/* Convert a long long value to a string. This function avoids 64-bit
+   modular arithmetic or divisions.  */
+static char *
+grub_lltoa (char *str, int c, unsigned long long n)
+{
+  unsigned base = (c == 'x') ? 16 : 10;
+  char *p;
+
+  if ((long long) n < 0 && c == 'd')
+    {
+      n = (unsigned long long) (-((long long) n));
+      *str++ = '-';
+    }
+
+  p = str;
+
+  if (base == 16)
+    do
+      {
+       unsigned d = (unsigned) (n & 0xf);
+       *p++ = (d > 9) ? d + 'a' - 10 : d + '0';
+      }
+    while (n >>= 4);
+  else
+    /* BASE == 10 */
+    do
+      {
+       unsigned m;
+
+       n = grub_divmod64 (n, 10, &m);
+       *p++ = m + '0';
+      }
+    while (n);
+
+  *p = 0;
+
+  grub_reverse (str);
+  return p;
+}
+
+static int
+grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list args)
+{
+  char c;
+  grub_size_t count = 0;
+  auto void write_char (unsigned char ch);
+  auto void write_str (const char *s);
+  auto void write_fill (const char ch, int n);
+
+  void write_char (unsigned char ch)
+    {
+      if (str)
+       {
+         if (count < max_len)
+           *str++ = ch;
+       }
+      else
+       grub_putchar (ch);
+
+      count++;
+    }
+
+  void write_str (const char *s)
+    {
+      while (*s)
+       write_char (*s++);
+    }
+
+  void write_fill (const char ch, int n)
+    {
+      int i;
+      for (i = 0; i < n; i++)
+       write_char (ch);
+    }
+
+  while ((c = *fmt++) != 0)
+    {
+      if (c != '%')
+       write_char (c);
+      else
+       {
+         char tmp[32];
+         char *p;
+         unsigned int format1 = 0;
+         unsigned int format2 = ~ 0U;
+         char zerofill = ' ';
+         int rightfill = 0;
+         int n;
+         int longfmt = 0;
+         int longlongfmt = 0;
+         int unsig = 0;
+
+         if (*fmt && *fmt =='-')
+           {
+             rightfill = 1;
+             fmt++;
+           }
+
+         p = (char *) fmt;
+         /* Read formatting parameters.  */
+         while (*p && grub_isdigit (*p))
+           p++;
+
+         if (p > fmt)
+           {
+             char s[p - fmt + 1];
+             grub_strncpy (s, fmt, p - fmt);
+             s[p - fmt] = 0;
+             if (s[0] == '0')
+               zerofill = '0';
+             format1 = grub_strtoul (s, 0, 10);
+             fmt = p;
+           }
+
+         if (*p && *p == '.')
+           {
+             p++;
+             fmt++;
+             while (*p && grub_isdigit (*p))
+               p++;
+
+             if (p > fmt)
+               {
+                 char fstr[p - fmt + 1];
+                 grub_strncpy (fstr, fmt, p - fmt);
+                 fstr[p - fmt] = 0;
+                 format2 = grub_strtoul (fstr, 0, 10);
+                 fmt = p;
+               }
+           }
+
+         c = *fmt++;
+         if (c == 'l')
+           {
+             longfmt = 1;
+             c = *fmt++;
+             if (c == 'l')
+               {
+                 longlongfmt = 1;
+                 c = *fmt++;
+               }
+           }
+
+         switch (c)
+           {
+           case 'p':
+             write_str ("0x");
+             c = 'x';
+             longlongfmt |= (sizeof (void *) == sizeof (long long));
+             /* Fall through. */
+           case 'x':
+           case 'u':
+             unsig = 1;
+             /* Fall through. */
+           case 'd':
+             if (longlongfmt)
+               {
+                 long long ll;
+
+                 ll = va_arg (args, long long);
+                 grub_lltoa (tmp, c, ll);
+               }
+             else if (longfmt && unsig)
+               {
+                 unsigned long l = va_arg (args, unsigned long);
+                 grub_lltoa (tmp, c, l);
+               }
+             else if (longfmt)
+               {
+                 long l = va_arg (args, long);
+                 grub_lltoa (tmp, c, l);
+               }
+             else if (unsig)
+               {
+                 unsigned u = va_arg (args, unsigned);
+                 grub_lltoa (tmp, c, u);
+               }
+             else
+               {
+                 n = va_arg (args, int);
+                 grub_lltoa (tmp, c, n);
+               }
+             if (! rightfill && grub_strlen (tmp) < format1)
+               write_fill (zerofill, format1 - grub_strlen (tmp));
+             write_str (tmp);
+             if (rightfill && grub_strlen (tmp) < format1)
+               write_fill (zerofill, format1 - grub_strlen (tmp));
+             break;
+
+           case 'c':
+             n = va_arg (args, int);
+             write_char (n & 0xff);
+             break;
+
+           case 'C':
+             {
+               grub_uint32_t code = va_arg (args, grub_uint32_t);
+               int shift;
+               unsigned mask;
+
+               if (code <= 0x7f)
+                 {
+                   shift = 0;
+                   mask = 0;
+                 }
+               else if (code <= 0x7ff)
+                 {
+                   shift = 6;
+                   mask = 0xc0;
+                 }
+               else if (code <= 0xffff)
+                 {
+                   shift = 12;
+                   mask = 0xe0;
+                 }
+               else if (code <= 0x1fffff)
+                 {
+                   shift = 18;
+                   mask = 0xf0;
+                 }
+               else if (code <= 0x3ffffff)
+                 {
+                   shift = 24;
+                   mask = 0xf8;
+                 }
+               else if (code <= 0x7fffffff)
+                 {
+                   shift = 30;
+                   mask = 0xfc;
+                 }
+               else
+                 {
+                   code = '?';
+                   shift = 0;
+                   mask = 0;
+                 }
+
+               write_char (mask | (code >> shift));
+
+               for (shift -= 6; shift >= 0; shift -= 6)
+                 write_char (0x80 | (0x3f & (code >> shift)));
+             }
+             break;
+
+           case 's':
+             p = va_arg (args, char *);
+             if (p)
+               {
+                 grub_size_t len = 0;
+                 while (len < format2 && p[len])
+                   len++;
+
+                 if (!rightfill && len < format1)
+                   write_fill (zerofill, format1 - len);
+
+                 grub_size_t i;
+                 for (i = 0; i < len; i++)
+                   write_char (*p++);
+
+                 if (rightfill && len < format1)
+                   write_fill (zerofill, format1 - len);
+               }
+             else
+               write_str ("(null)");
+
+             break;
+
+           default:
+             write_char (c);
+             break;
+           }
+       }
+    }
+
+  if (str)
+    *str = '\0';
+
+  return count;
+}
+
+int
+grub_vsnprintf (char *str, grub_size_t n, const char *fmt, va_list ap)
+{
+  grub_size_t ret;
+
+  if (!n)
+    return 0;
+
+  n--;
+
+  ret = grub_vsnprintf_real (str, n, fmt, ap);
+
+  return ret < n ? ret : n;
+}
+
+int
+grub_snprintf (char *str, grub_size_t n, const char *fmt, ...)
+{
+  va_list ap;
+  int ret;
+
+  va_start (ap, fmt);
+  ret = grub_vsnprintf (str, n, fmt, ap);
+  va_end (ap);
+
+  return ret;
+}
+
+#define PREALLOC_SIZE 255
+
+char *
+grub_xvasprintf (const char *fmt, va_list ap)
+{
+  grub_size_t s, as = PREALLOC_SIZE;
+  char *ret;
+
+  while (1)
+    {
+      ret = grub_malloc (as + 1);
+      if (!ret)
+       return NULL;
+
+      s = grub_vsnprintf_real (ret, as, fmt, ap);
+      if (s <= as)
+       return ret;
+
+      grub_free (ret);
+      as = s;
+    }
+}
+
+char *
+grub_xasprintf (const char *fmt, ...)
+{
+  va_list ap;
+  char *ret;
+
+  va_start (ap, fmt);
+  ret = grub_xvasprintf (fmt, ap);
+  va_end (ap);
+
+  return ret;
+}
+
+/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
+   bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string.
+   Return the number of characters converted. DEST must be able to hold
+   at least DESTSIZE characters.
+   If SRCEND is not NULL, then *SRCEND is set to the next byte after the
+   last byte used in SRC.  */
+grub_size_t
+grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
+                  const grub_uint8_t *src, grub_size_t srcsize,
+                  const grub_uint8_t **srcend)
+{
+  grub_uint32_t *p = dest;
+  int count = 0;
+  grub_uint32_t code = 0;
+
+  if (srcend)
+    *srcend = src;
+
+  while (srcsize && destsize)
+    {
+      grub_uint32_t c = *src++;
+      if (srcsize != (grub_size_t)-1)
+       srcsize--;
+      if (count)
+       {
+         if ((c & 0xc0) != 0x80)
+           {
+             /* invalid */
+             code = '?';
+             /* Character c may be valid, don't eat it.  */
+             src--;
+             if (srcsize != (grub_size_t)-1)
+               srcsize++;
+             count = 0;
+           }
+         else
+           {
+             code <<= 6;
+             code |= (c & 0x3f);
+             count--;
+           }
+       }
+      else
+       {
+         if (c == 0)
+           break;
+
+         if ((c & 0x80) == 0x00)
+           code = c;
+         else if ((c & 0xe0) == 0xc0)
+           {
+             count = 1;
+             code = c & 0x1f;
+           }
+         else if ((c & 0xf0) == 0xe0)
+           {
+             count = 2;
+             code = c & 0x0f;
+           }
+         else if ((c & 0xf8) == 0xf0)
+           {
+             count = 3;
+             code = c & 0x07;
+           }
+         else if ((c & 0xfc) == 0xf8)
+           {
+             count = 4;
+             code = c & 0x03;
+           }
+         else if ((c & 0xfe) == 0xfc)
+           {
+             count = 5;
+             code = c & 0x01;
+           }
+         else
+           {
+             /* invalid */
+             code = '?';
+             count = 0;
+           }
+       }
+
+      if (count == 0)
+       {
+         *p++ = code;
+         destsize--;
+       }
+    }
+
+  if (srcend)
+    *srcend = src;
+  return p - dest;
+}
+
+/* Abort GRUB. This function does not return.  */
+void
+grub_abort (void)
+{
+  grub_printf ("\nAborted.");
+  
+#ifndef GRUB_UTIL
+  if (grub_term_inputs)
+#endif
+    {
+      grub_printf (" Press any key to exit.");
+      grub_getkey ();
+    }
+
+  grub_exit ();
+}
+
+#ifndef APPLE_CC
+/* GCC emits references to abort().  */
+void abort (void) __attribute__ ((alias ("grub_abort")));
+#endif
+
+#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL)
+/* Some gcc versions generate a call to this function
+   in trampolines for nested functions.  */
+void __enable_execute_stack (void *addr __attribute__ ((unused)))
+{
+}
+#endif
+
+#if defined (NEED_REGISTER_FRAME_INFO) && !defined(GRUB_UTIL)
+void __register_frame_info (void)
+{
+}
+
+void __deregister_frame_info (void)
+{
+}
+#endif
diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c
new file mode 100644 (file)
index 0000000..47324a6
--- /dev/null
@@ -0,0 +1,600 @@
+/* mm.c - functions for memory manager */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+  The design of this memory manager.
+
+  This is a simple implementation of malloc with a few extensions. These are
+  the extensions:
+
+  - memalign is implemented efficiently.
+
+  - multiple regions may be used as free space. They may not be
+  contiguous.
+
+  Regions are managed by a singly linked list, and the meta information is
+  stored in the beginning of each region. Space after the meta information
+  is used to allocate memory.
+
+  The memory space is used as cells instead of bytes for simplicity. This
+  is important for some CPUs which may not access multiple bytes at a time
+  when the first byte is not aligned at a certain boundary (typically,
+  4-byte or 8-byte). The size of each cell is equal to the size of struct
+  grub_mm_header, so the header of each allocated/free block fits into one
+  cell precisely. One cell is 16 bytes on 32-bit platforms and 32 bytes
+  on 64-bit platforms.
+
+  There are two types of blocks: allocated blocks and free blocks.
+
+  In allocated blocks, the header of each block has only its size. Note that
+  this size is based on cells but not on bytes. The header is located right
+  before the returned pointer, that is, the header resides at the previous
+  cell.
+
+  Free blocks constitutes a ring, using a singly linked list. The first free
+  block is pointed to by the meta information of a region. The allocator
+  attempts to pick up the second block instead of the first one. This is
+  a typical optimization against defragmentation, and makes the
+  implementation a bit easier.
+
+  For safety, both allocated blocks and free ones are marked by magic
+  numbers. Whenever anything unexpected is detected, GRUB aborts the
+  operation.
+ */
+
+#include <config.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/disk.h>
+#include <grub/dl.h>
+
+#ifdef MM_DEBUG
+# undef grub_malloc
+# undef grub_zalloc
+# undef grub_realloc
+# undef grub_free
+# undef grub_memalign
+#endif
+
+/* Magic words.  */
+#define GRUB_MM_FREE_MAGIC     0x2d3c2808
+#define GRUB_MM_ALLOC_MAGIC    0x6db08fa4
+
+typedef struct grub_mm_header
+{
+  struct grub_mm_header *next;
+  grub_size_t size;
+  grub_size_t magic;
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+  char padding[4];
+#elif GRUB_CPU_SIZEOF_VOID_P == 8
+  char padding[8];
+#else
+# error "unknown word size"
+#endif
+}
+*grub_mm_header_t;
+
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+# define GRUB_MM_ALIGN_LOG2    4
+#elif GRUB_CPU_SIZEOF_VOID_P == 8
+# define GRUB_MM_ALIGN_LOG2    5
+#endif
+
+#define GRUB_MM_ALIGN  (1 << GRUB_MM_ALIGN_LOG2)
+
+typedef struct grub_mm_region
+{
+  struct grub_mm_header *first;
+  struct grub_mm_region *next;
+  grub_addr_t addr;
+  grub_size_t size;
+}
+*grub_mm_region_t;
+
+\f
+
+static grub_mm_region_t base;
+
+/* Get a header from the pointer PTR, and set *P and *R to a pointer
+   to the header and a pointer to its region, respectively. PTR must
+   be allocated.  */
+static void
+get_header_from_pointer (void *ptr, grub_mm_header_t *p, grub_mm_region_t *r)
+{
+  if ((grub_addr_t) ptr & (GRUB_MM_ALIGN - 1))
+    grub_fatal ("unaligned pointer %p", ptr);
+
+  for (*r = base; *r; *r = (*r)->next)
+    if ((grub_addr_t) ptr > (*r)->addr
+       && (grub_addr_t) ptr <= (*r)->addr + (*r)->size)
+      break;
+
+  if (! *r)
+    grub_fatal ("out of range pointer %p", ptr);
+
+  *p = (grub_mm_header_t) ptr - 1;
+  if ((*p)->magic != GRUB_MM_ALLOC_MAGIC)
+    grub_fatal ("alloc magic is broken at %p", *p);
+}
+
+/* Initialize a region starting from ADDR and whose size is SIZE,
+   to use it as free space.  */
+void
+grub_mm_init_region (void *addr, grub_size_t size)
+{
+  grub_mm_header_t h;
+  grub_mm_region_t r, *p, q;
+
+#if 0
+  grub_printf ("Using memory for heap: start=%p, end=%p\n", addr, addr + (unsigned int) size);
+#endif
+
+  /* Allocate a region from the head.  */
+  r = (grub_mm_region_t) ALIGN_UP ((grub_addr_t) addr, GRUB_MM_ALIGN);
+  size -= (char *) r - (char *) addr + sizeof (*r);
+
+  /* If this region is too small, ignore it.  */
+  if (size < GRUB_MM_ALIGN)
+    return;
+
+  h = (grub_mm_header_t) ((char *) r + GRUB_MM_ALIGN);
+  h->next = h;
+  h->magic = GRUB_MM_FREE_MAGIC;
+  h->size = (size >> GRUB_MM_ALIGN_LOG2);
+
+  r->first = h;
+  r->addr = (grub_addr_t) h;
+  r->size = (h->size << GRUB_MM_ALIGN_LOG2);
+
+  /* Find where to insert this region. Put a smaller one before bigger ones,
+     to prevent fragmentation.  */
+  for (p = &base, q = *p; q; p = &(q->next), q = *p)
+    if (q->size > r->size)
+      break;
+
+  *p = r;
+  r->next = q;
+}
+
+/* Allocate the number of units N with the alignment ALIGN from the ring
+   buffer starting from *FIRST.  ALIGN must be a power of two. Both N and
+   ALIGN are in units of GRUB_MM_ALIGN.  Return a non-NULL if successful,
+   otherwise return NULL.  */
+static void *
+grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align)
+{
+  grub_mm_header_t p, q;
+
+  /* When everything is allocated side effect is that *first will have alloc
+     magic marked, meaning that there is no room in this region.  */
+  if ((*first)->magic == GRUB_MM_ALLOC_MAGIC)
+    return 0;
+
+  /* Try to search free slot for allocation in this memory region.  */
+  for (q = *first, p = q->next; ; q = p, p = p->next)
+    {
+      grub_off_t extra;
+
+      extra = ((grub_addr_t) (p + 1) >> GRUB_MM_ALIGN_LOG2) % align;
+      if (extra)
+       extra = align - extra;
+
+      if (! p)
+       grub_fatal ("null in the ring");
+
+      if (p->magic != GRUB_MM_FREE_MAGIC)
+       grub_fatal ("free magic is broken at %p: 0x%x", p, p->magic);
+
+      if (p->size >= n + extra)
+       {
+         if (extra == 0 && p->size == n)
+           {
+             /* There is no special alignment requirement and memory block
+                is complete match.
+
+                1. Just mark memory block as allocated and remove it from
+                   free list.
+
+                Result:
+                +---------------+ previous block's next
+                | alloc, size=n |          |
+                +---------------+          v
+              */
+             q->next = p->next;
+           }
+         else if (align == 1 || p->size == n + extra)
+           {
+             /* There might be alignment requirement, when taking it into
+                account memory block fits in.
+
+                1. Allocate new area at end of memory block.
+                2. Reduce size of available blocks from original node.
+                3. Mark new area as allocated and "remove" it from free
+                   list.
+
+                Result:
+                +---------------+
+                | free, size-=n | next --+
+                +---------------+        |
+                | alloc, size=n |        |
+                +---------------+        v
+              */
+
+             p->size -= n;
+             p += p->size;
+           }
+         else if (extra == 0)
+           {
+             grub_mm_header_t r;
+             
+             r = p + extra + n;
+             r->magic = GRUB_MM_FREE_MAGIC;
+             r->size = p->size - extra - n;
+             r->next = p->next;
+             q->next = r;
+
+             if (q == p)
+               {
+                 q = r;
+                 r->next = r;
+               }
+           }
+         else
+           {
+             /* There is alignment requirement and there is room in memory
+                block.  Split memory block to three pieces.
+
+                1. Create new memory block right after section being
+                   allocated.  Mark it as free.
+                2. Add new memory block to free chain.
+                3. Mark current memory block having only extra blocks.
+                4. Advance to aligned block and mark that as allocated and
+                   "remove" it from free list.
+
+                Result:
+                +------------------------------+
+                | free, size=extra             | next --+
+                +------------------------------+        |
+                | alloc, size=n                |        |
+                +------------------------------+        |
+                | free, size=orig.size-extra-n | <------+, next --+
+                +------------------------------+                  v
+              */
+             grub_mm_header_t r;
+
+             r = p + extra + n;
+             r->magic = GRUB_MM_FREE_MAGIC;
+             r->size = p->size - extra - n;
+             r->next = p->next;
+
+             p->size = extra;
+             p->next = r;
+             p += extra;
+           }
+
+         p->magic = GRUB_MM_ALLOC_MAGIC;
+         p->size = n;
+
+         /* Mark find as a start marker for next allocation to fasten it.
+            This will have side effect of fragmenting memory as small
+            pieces before this will be un-used.  */
+         *first = q;
+
+         return p + 1;
+       }
+
+      /* Search was completed without result.  */
+      if (p == *first)
+       break;
+    }
+
+  return 0;
+}
+
+/* Allocate SIZE bytes with the alignment ALIGN and return the pointer.  */
+void *
+grub_memalign (grub_size_t align, grub_size_t size)
+{
+  grub_mm_region_t r;
+  grub_size_t n = ((size + GRUB_MM_ALIGN - 1) >> GRUB_MM_ALIGN_LOG2) + 1;
+  int count = 0;
+
+  align = (align >> GRUB_MM_ALIGN_LOG2);
+  if (align == 0)
+    align = 1;
+
+ again:
+
+  for (r = base; r; r = r->next)
+    {
+      void *p;
+
+      p = grub_real_malloc (&(r->first), n, align);
+      if (p)
+       return p;
+    }
+
+  /* If failed, increase free memory somehow.  */
+  switch (count)
+    {
+    case 0:
+      /* Invalidate disk caches.  */
+      grub_disk_cache_invalidate_all ();
+      count++;
+      goto again;
+
+    case 1:
+      /* Unload unneeded modules.  */
+      grub_dl_unload_unneeded ();
+      count++;
+      goto again;
+
+    default:
+      break;
+    }
+
+  grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
+  return 0;
+}
+
+/* Allocate SIZE bytes and return the pointer.  */
+void *
+grub_malloc (grub_size_t size)
+{
+  return grub_memalign (0, size);
+}
+
+/* Allocate SIZE bytes, clear them and return the pointer.  */
+void *
+grub_zalloc (grub_size_t size)
+{
+  void *ret;
+
+  ret = grub_memalign (0, size);
+  if (ret)
+    grub_memset (ret, 0, size);
+
+  return ret;
+}
+
+/* Deallocate the pointer PTR.  */
+void
+grub_free (void *ptr)
+{
+  grub_mm_header_t p;
+  grub_mm_region_t r;
+
+  if (! ptr)
+    return;
+
+  get_header_from_pointer (ptr, &p, &r);
+
+  if (r->first->magic == GRUB_MM_ALLOC_MAGIC)
+    {
+      p->magic = GRUB_MM_FREE_MAGIC;
+      r->first = p->next = p;
+    }
+  else
+    {
+      grub_mm_header_t q;
+
+#if 0
+      q = r->first;
+      do
+       {
+         grub_printf ("%s:%d: q=%p, q->size=0x%x, q->magic=0x%x\n",
+                      GRUB_FILE, __LINE__, q, q->size, q->magic);
+         q = q->next;
+       }
+      while (q != r->first);
+#endif
+
+      for (q = r->first; q >= p || q->next <= p; q = q->next)
+       {
+         if (q->magic != GRUB_MM_FREE_MAGIC)
+           grub_fatal ("free magic is broken at %p: 0x%x", q, q->magic);
+
+         if (q >= q->next && (q < p || q->next > p))
+           break;
+       }
+
+      p->magic = GRUB_MM_FREE_MAGIC;
+      p->next = q->next;
+      q->next = p;
+
+      if (p + p->size == p->next)
+       {
+         if (p->next == q)
+           q = p;
+
+         p->next->magic = 0;
+         p->size += p->next->size;
+         p->next = p->next->next;
+       }
+
+      if (q + q->size == p)
+       {
+         p->magic = 0;
+         q->size += p->size;
+         q->next = p->next;
+       }
+
+      r->first = q;
+    }
+}
+
+/* Reallocate SIZE bytes and return the pointer. The contents will be
+   the same as that of PTR.  */
+void *
+grub_realloc (void *ptr, grub_size_t size)
+{
+  grub_mm_header_t p;
+  grub_mm_region_t r;
+  void *q;
+  grub_size_t n;
+
+  if (! ptr)
+    return grub_malloc (size);
+
+  if (! size)
+    {
+      grub_free (ptr);
+      return 0;
+    }
+
+  /* FIXME: Not optimal.  */
+  n = ((size + GRUB_MM_ALIGN - 1) >> GRUB_MM_ALIGN_LOG2) + 1;
+  get_header_from_pointer (ptr, &p, &r);
+
+  if (p->size >= n)
+    return ptr;
+
+  q = grub_malloc (size);
+  if (! q)
+    return q;
+
+  grub_memcpy (q, ptr, size);
+  grub_free (ptr);
+  return q;
+}
+
+#ifdef MM_DEBUG
+int grub_mm_debug = 0;
+
+void
+grub_mm_dump_free (void)
+{
+  grub_mm_region_t r;
+
+  for (r = base; r; r = r->next)
+    {
+      grub_mm_header_t p;
+
+      /* Follow the free list.  */
+      p = r->first;
+      do
+       {
+         if (p->magic != GRUB_MM_FREE_MAGIC)
+           grub_fatal ("free magic is broken at %p: 0x%x", p, p->magic);
+
+         grub_printf ("F:%p:%u:%p\n",
+                      p, (unsigned int) p->size << GRUB_MM_ALIGN_LOG2, p->next);
+         p = p->next;
+       }
+      while (p != r->first);
+    }
+
+  grub_printf ("\n");
+}
+
+void
+grub_mm_dump (unsigned lineno)
+{
+  grub_mm_region_t r;
+
+  grub_printf ("called at line %u\n", lineno);
+  for (r = base; r; r = r->next)
+    {
+      grub_mm_header_t p;
+
+      for (p = (grub_mm_header_t) ((r->addr + GRUB_MM_ALIGN - 1)
+                                  & (~(GRUB_MM_ALIGN - 1)));
+          (grub_addr_t) p < r->addr + r->size;
+          p++)
+       {
+         switch (p->magic)
+           {
+           case GRUB_MM_FREE_MAGIC:
+             grub_printf ("F:%p:%u:%p\n",
+                          p, (unsigned int) p->size << GRUB_MM_ALIGN_LOG2, p->next);
+             break;
+           case GRUB_MM_ALLOC_MAGIC:
+             grub_printf ("A:%p:%u\n", p, (unsigned int) p->size << GRUB_MM_ALIGN_LOG2);
+             break;
+           }
+       }
+    }
+
+  grub_printf ("\n");
+}
+
+void *
+grub_debug_malloc (const char *file, int line, grub_size_t size)
+{
+  void *ptr;
+
+  if (grub_mm_debug)
+    grub_printf ("%s:%d: malloc (0x%zx) = ", file, line, size);
+  ptr = grub_malloc (size);
+  if (grub_mm_debug)
+    grub_printf ("%p\n", ptr);
+  return ptr;
+}
+
+void *
+grub_debug_zalloc (const char *file, int line, grub_size_t size)
+{
+  void *ptr;
+
+  if (grub_mm_debug)
+    grub_printf ("%s:%d: zalloc (0x%zx) = ", file, line, size);
+  ptr = grub_zalloc (size);
+  if (grub_mm_debug)
+    grub_printf ("%p\n", ptr);
+  return ptr;
+}
+
+void
+grub_debug_free (const char *file, int line, void *ptr)
+{
+  if (grub_mm_debug)
+    grub_printf ("%s:%d: free (%p)\n", file, line, ptr);
+  grub_free (ptr);
+}
+
+void *
+grub_debug_realloc (const char *file, int line, void *ptr, grub_size_t size)
+{
+  if (grub_mm_debug)
+    grub_printf ("%s:%d: realloc (%p, 0x%zx) = ", file, line, ptr, size);
+  ptr = grub_realloc (ptr, size);
+  if (grub_mm_debug)
+    grub_printf ("%p\n", ptr);
+  return ptr;
+}
+
+void *
+grub_debug_memalign (const char *file, int line, grub_size_t align,
+                   grub_size_t size)
+{
+  void *ptr;
+
+  if (grub_mm_debug)
+    grub_printf ("%s:%d: memalign (0x%zx, 0x%zx) = ",
+                file, line, align, size);
+  ptr = grub_memalign (align, size);
+  if (grub_mm_debug)
+    grub_printf ("%p\n", ptr);
+  return ptr;
+}
+
+#endif /* MM_DEBUG */
diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c
new file mode 100644 (file)
index 0000000..07597a1
--- /dev/null
@@ -0,0 +1,273 @@
+/* parser.c - the part of the parser that can return partial tokens */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/parser.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+
+/* All the possible state transitions on the command line.  If a
+   transition can not be found, it is assumed that there is no
+   transition and keep_value is assumed to be 1.  */
+static struct grub_parser_state_transition state_transitions[] = {
+  {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_QUOTE, '\'', 0},
+  {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_DQUOTE, '\"', 0},
+  {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_VAR, '$', 0},
+  {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_ESC, '\\', 0},
+
+  {GRUB_PARSER_STATE_ESC, GRUB_PARSER_STATE_TEXT, 0, 1},
+
+  {GRUB_PARSER_STATE_QUOTE, GRUB_PARSER_STATE_TEXT, '\'', 0},
+
+  {GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_TEXT, '\"', 0},
+  {GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_QVAR, '$', 0},
+
+  {GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME2, '{', 0},
+  {GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME, 0, 1},
+  {GRUB_PARSER_STATE_VARNAME, GRUB_PARSER_STATE_TEXT, ' ', 1},
+  {GRUB_PARSER_STATE_VARNAME2, GRUB_PARSER_STATE_TEXT, '}', 0},
+
+  {GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME2, '{', 0},
+  {GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME, 0, 1},
+  {GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_TEXT, '\"', 0},
+  {GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_DQUOTE, ' ', 1},
+  {GRUB_PARSER_STATE_QVARNAME2, GRUB_PARSER_STATE_DQUOTE, '}', 0},
+
+  {0, 0, 0, 0}
+};
+
+
+/* Determines the state following STATE, determined by C.  */
+grub_parser_state_t
+grub_parser_cmdline_state (grub_parser_state_t state, char c, char *result)
+{
+  struct grub_parser_state_transition *transition;
+  struct grub_parser_state_transition default_transition;
+
+  default_transition.to_state = state;
+  default_transition.keep_value = 1;
+
+  /* Look for a good translation.  */
+  for (transition = state_transitions; transition->from_state; transition++)
+    {
+      if (transition->from_state != state)
+       continue;
+      /* An exact match was found, use it.  */
+      if (transition->input == c)
+       break;
+
+      if (transition->input == ' ' && !grub_isalpha (c)
+         && !grub_isdigit (c) && c != '_')
+       break;
+
+      /* A less perfect match was found, use this one if no exact
+         match can be found.  */
+      if (transition->input == 0)
+       break;
+    }
+
+  if (!transition->from_state)
+    transition = &default_transition;
+
+  if (transition->keep_value)
+    *result = c;
+  else
+    *result = 0;
+  return transition->to_state;
+}
+
+
+grub_err_t
+grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline,
+                          int *argc, char ***argv)
+{
+  grub_parser_state_t state = GRUB_PARSER_STATE_TEXT;
+  /* XXX: Fixed size buffer, perhaps this buffer should be dynamically
+     allocated.  */
+  char buffer[1024];
+  char *bp = buffer;
+  char *rd = (char *) cmdline;
+  char varname[200];
+  char *vp = varname;
+  char *args;
+  int i;
+
+  auto int check_varstate (grub_parser_state_t s);
+
+  int check_varstate (grub_parser_state_t s)
+  {
+    return (s == GRUB_PARSER_STATE_VARNAME
+           || s == GRUB_PARSER_STATE_VARNAME2
+           || s == GRUB_PARSER_STATE_QVARNAME
+           || s == GRUB_PARSER_STATE_QVARNAME2);
+  }
+
+  auto void add_var (grub_parser_state_t newstate);
+
+  void add_var (grub_parser_state_t newstate)
+  {
+    char *val;
+
+    /* Check if a variable was being read in and the end of the name
+       was reached.  */
+    if (!(check_varstate (state) && !check_varstate (newstate)))
+      return;
+
+    *(vp++) = '\0';
+    val = grub_env_get (varname);
+    vp = varname;
+    if (!val)
+      return;
+
+    /* Insert the contents of the variable in the buffer.  */
+    for (; *val; val++)
+      *(bp++) = *val;
+  }
+
+  *argc = 0;
+  do
+    {
+      if (!rd || !*rd)
+       {
+         if (getline)
+           getline (&rd, 1);
+         else
+           break;
+       }
+
+      if (!rd)
+       break;
+
+      for (; *rd; rd++)
+       {
+         grub_parser_state_t newstate;
+         char use;
+
+         newstate = grub_parser_cmdline_state (state, *rd, &use);
+
+         /* If a variable was being processed and this character does
+            not describe the variable anymore, write the variable to
+            the buffer.  */
+         add_var (newstate);
+
+         if (check_varstate (newstate))
+           {
+             if (use)
+               *(vp++) = use;
+           }
+         else
+           {
+             if (newstate == GRUB_PARSER_STATE_TEXT
+                 && state != GRUB_PARSER_STATE_ESC && use == ' ')
+               {
+                 /* Don't add more than one argument if multiple
+                    spaces are used.  */
+                 if (bp != buffer && *(bp - 1))
+                   {
+                     *(bp++) = '\0';
+                     (*argc)++;
+                   }
+               }
+             else if (use)
+               *(bp++) = use;
+           }
+         state = newstate;
+       }
+    }
+  while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state));
+
+  /* A special case for when the last character was part of a
+     variable.  */
+  add_var (GRUB_PARSER_STATE_TEXT);
+
+  if (bp != buffer && *(bp - 1))
+    {
+      *(bp++) = '\0';
+      (*argc)++;
+    }
+
+  /* Reserve memory for the return values.  */
+  args = grub_malloc (bp - buffer);
+  if (!args)
+    return grub_errno;
+  grub_memcpy (args, buffer, bp - buffer);
+
+  *argv = grub_malloc (sizeof (char *) * (*argc + 1));
+  if (!*argv)
+    {
+      grub_free (args);
+      return grub_errno;
+    }
+
+  /* The arguments are separated with 0's, setup argv so it points to
+     the right values.  */
+  bp = args;
+  for (i = 0; i < *argc; i++)
+    {
+      (*argv)[i] = bp;
+      while (*bp)
+       bp++;
+      bp++;
+    }
+
+  return 0;
+}
+
+struct grub_handler_class grub_parser_class = {
+  .name = "parser"
+};
+
+grub_err_t
+grub_parser_execute (char *source)
+{
+  auto grub_err_t getline (char **line, int cont);
+  grub_err_t getline (char **line, int cont __attribute__ ((unused)))
+  {
+    char *p;
+
+    if (!source)
+      {
+       *line = 0;
+       return 0;
+      }
+
+    p = grub_strchr (source, '\n');
+
+    if (p)
+      *line = grub_strndup (source, p - source);
+    else
+      *line = grub_strdup (source);
+    source = p ? p + 1 : 0;
+    return 0;
+  }
+
+  while (source)
+    {
+      char *line;
+      grub_parser_t parser;
+
+      getline (&line, 0);
+      parser = grub_parser_get_current ();
+      parser->parse_line (line, getline);
+      grub_free (line);
+    }
+
+  return grub_errno;
+}
diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c
new file mode 100644 (file)
index 0000000..2a33ac3
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+#include <grub/disk.h>
+
+grub_partition_map_t grub_partition_map_list;
+
+static grub_partition_t
+grub_partition_map_probe (const grub_partition_map_t partmap,
+                         grub_disk_t disk, int partnum)
+{
+  grub_partition_t p = 0;
+
+  auto int find_func (grub_disk_t d, const grub_partition_t partition);
+
+  int find_func (grub_disk_t d __attribute__ ((unused)),
+                const grub_partition_t partition)
+    {
+      if (partnum == partition->number)
+       {
+         p = (grub_partition_t) grub_malloc (sizeof (*p));
+         if (! p)
+           return 1;
+
+         grub_memcpy (p, partition, sizeof (*p));
+         return 1;
+       }
+
+      return 0;
+    }
+
+  partmap->iterate (disk, find_func);
+  if (grub_errno)
+    goto fail;
+
+  return p;
+
+ fail:
+  grub_free (p);
+  return 0;
+}
+
+grub_partition_t
+grub_partition_probe (struct grub_disk *disk, const char *str)
+{
+  grub_partition_t part = 0;
+  grub_partition_t curpart = 0;
+  grub_partition_t tail;
+  const char *ptr;
+
+  part = tail = disk->partition;
+
+  for (ptr = str; *ptr;)
+    {
+      grub_partition_map_t partmap;
+      int num;
+      const char *partname, *partname_end;
+
+      partname = ptr;
+      while (*ptr && grub_isalpha (*ptr))
+       ptr++;
+      partname_end = ptr; 
+      num = grub_strtoul (ptr, (char **) &ptr, 0) - 1;
+
+      curpart = 0;
+      /* Use the first partition map type found.  */
+      FOR_PARTITION_MAPS(partmap)
+      {
+       if (partname_end != partname &&
+           (grub_strncmp (partmap->name, partname, partname_end - partname)
+            != 0 || partmap->name[partname_end - partname] != 0))
+         continue;
+
+       disk->partition = part;
+       curpart = grub_partition_map_probe (partmap, disk, num);
+       disk->partition = tail;
+       if (curpart)
+         break;
+
+       if (grub_errno == GRUB_ERR_BAD_PART_TABLE)
+         {
+           /* Continue to next partition map type.  */
+           grub_errno = GRUB_ERR_NONE;
+           continue;
+         }
+
+       break;
+      }
+
+      if (! curpart)
+       {
+         while (part)
+           {
+             curpart = part->parent;
+             grub_free (part);
+             part = curpart;
+           }
+         return 0;
+       }
+      curpart->parent = part;
+      part = curpart;
+      if (! ptr || *ptr != ',')
+       break;
+      ptr++;
+    }
+
+  return part;
+}
+
+int
+grub_partition_iterate (struct grub_disk *disk,
+                       int (*hook) (grub_disk_t disk,
+                                    const grub_partition_t partition))
+{
+  int ret = 0;
+
+  auto int part_iterate (grub_disk_t dsk, const grub_partition_t p);
+
+  int part_iterate (grub_disk_t dsk,
+                   const grub_partition_t partition)
+    {
+      struct grub_partition p = *partition;
+      p.parent = dsk->partition;
+      dsk->partition = 0;
+      if (hook (dsk, &p))
+       {
+         ret = 1;
+         return 1;
+       }
+      if (p.start != 0)
+       {
+         const struct grub_partition_map *partmap;
+         dsk->partition = &p;
+         FOR_PARTITION_MAPS(partmap)
+         {
+           grub_err_t err;
+           err = partmap->iterate (dsk, part_iterate);
+           if (err)
+             grub_errno = GRUB_ERR_NONE;
+           if (ret)
+             break;
+         }
+       }
+      dsk->partition = p.parent;
+      return ret;
+    }
+
+  {
+    const struct grub_partition_map *partmap;
+    FOR_PARTITION_MAPS(partmap)
+    {
+      grub_err_t err;
+      err = partmap->iterate (disk, part_iterate);
+      if (err)
+       grub_errno = GRUB_ERR_NONE;
+      if (ret)
+       break;
+    }
+  }
+
+  return ret;
+}
+
+char *
+grub_partition_get_name (const grub_partition_t partition)
+{
+  char *out = 0;
+  int curlen = 0;
+  grub_partition_t part;
+  for (part = partition; part; part = part->parent)
+    {
+      /* Even on 64-bit machines this buffer is enough to hold
+        longest number.  */
+      char buf[grub_strlen (part->partmap->name) + 25];
+      int strl;
+      grub_snprintf (buf, sizeof (buf), "%s%d", part->partmap->name,
+                    part->number + 1);
+      strl = grub_strlen (buf);
+      if (curlen)
+       {
+         out = grub_realloc (out, curlen + strl + 2);
+         grub_memcpy (out + strl + 1, out, curlen);
+         out[curlen + 1 + strl] = 0;
+         grub_memcpy (out, buf, strl);
+         out[strl] = ',';
+         curlen = curlen + 1 + strl;
+       }
+      else
+       {
+         curlen = strl;
+         out = grub_strdup (buf);
+       }
+    }
+  return out;
+}
diff --git a/grub-core/kern/powerpc/cache.S b/grub-core/kern/powerpc/cache.S
new file mode 100644 (file)
index 0000000..da982af
--- /dev/null
@@ -0,0 +1,48 @@
+/* cache.S - Flush the processor cache for a specific region.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define CACHE_LINE_BYTES 32
+
+       .text
+
+       .align 2
+       .globl grub_arch_sync_caches
+grub_arch_sync_caches:
+       /* `address' may not be CACHE_LINE_BYTES-aligned.  */
+       andi. 6, 3, CACHE_LINE_BYTES - 1 /* Find the misalignment.  */
+       add 4, 4, 6 /* Adjust `size' to compensate.  */
+
+       /* Force the dcache lines to memory.  */
+       li 5, 0
+1:     dcbst 5, 3
+       addi 5, 5, CACHE_LINE_BYTES
+       cmpw 5, 4
+       blt 1b
+       sync            /* Force all dcbsts to complete.  */
+
+       /* Invalidate the icache lines.  */
+       li 5, 0
+1:     icbi 5, 3
+       addi 5, 5, CACHE_LINE_BYTES
+       cmpw 5, 4
+       blt 1b
+       sync            /* Force all icbis to complete.  */
+       isync           /* Discard partially executed instructions that were
+                          loaded from the invalid icache.  */
+       blr
diff --git a/grub-core/kern/powerpc/dl.c b/grub-core/kern/powerpc/dl.c
new file mode 100644 (file)
index 0000000..ad19e56
--- /dev/null
@@ -0,0 +1,136 @@
+/* dl.c - arch-dependent part of loadable module support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+
+/* Check if EHDR is a valid ELF header.  */
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+
+  /* Check the magic numbers.  */
+  if (e->e_ident[EI_CLASS] != ELFCLASS32
+      || e->e_ident[EI_DATA] != ELFDATA2MSB
+      || e->e_machine != EM_PPC)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
+
+  return GRUB_ERR_NONE;
+}
+
+
+/* Relocate symbols.  */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+  Elf_Shdr *s;
+  Elf_Word entsize;
+  unsigned i;
+
+  /* Find a symbol table.  */
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
+
+  entsize = s->sh_entsize;
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_RELA)
+      {
+       grub_dl_segment_t seg;
+
+       /* Find the target segment.  */
+       for (seg = mod->segment; seg; seg = seg->next)
+         if (seg->section == s->sh_info)
+           break;
+
+       if (seg)
+         {
+           Elf_Rela *rel, *max;
+
+           for (rel = (Elf_Rela *) ((char *) e + s->sh_offset),
+                  max = rel + s->sh_size / s->sh_entsize;
+                rel < max;
+                rel++)
+             {
+               Elf_Word *addr;
+               Elf_Sym *sym;
+               grub_uint32_t value;
+
+               if (seg->size < rel->r_offset)
+                 return grub_error (GRUB_ERR_BAD_MODULE,
+                                    "reloc offset is out of the segment");
+
+               addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
+               sym = (Elf_Sym *) ((char *) mod->symtab
+                                    + entsize * ELF_R_SYM (rel->r_info));
+
+               /* On the PPC the value does not have an explicit
+                  addend, add it.  */
+               value = sym->st_value + rel->r_addend;
+               switch (ELF_R_TYPE (rel->r_info))
+                 {
+                 case R_PPC_ADDR16_LO:
+                   *(Elf_Half *) addr = value;
+                   break;
+
+                 case R_PPC_REL24:
+                   {
+                     Elf_Sword delta = value - (Elf_Word) addr;
+
+                     if (delta << 6 >> 6 != delta)
+                       return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow");
+                     *addr = (*addr & 0xfc000003) | (delta & 0x3fffffc);
+                     break;
+                   }
+
+                 case R_PPC_ADDR16_HA:
+                   *(Elf_Half *) addr = (value + 0x8000) >> 16;
+                   break;
+
+                 case R_PPC_ADDR32:
+                   *addr = value;
+                   break;
+
+                 case R_PPC_REL32:
+                   *addr = value - (Elf_Word) addr;
+                   break;
+
+                 default:
+                   return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                                      "this relocation (%d) is not implemented yet",
+                                      ELF_R_TYPE (rel->r_info));
+                 }
+             }
+         }
+      }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/kern/powerpc/ieee1275/startup.S b/grub-core/kern/powerpc/ieee1275/startup.S
new file mode 100644 (file)
index 0000000..75e1ed8
--- /dev/null
@@ -0,0 +1,64 @@
+/* startup.S - Startup code for the PowerPC.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/cpu/kernel.h>
+
+.extern __bss_start
+.extern _end
+
+       .text
+       .align  2
+       .globl  start, _start
+start:
+_start:
+       b       codestart
+
+       . = _start + GRUB_KERNEL_CPU_PREFIX
+
+VARIABLE(grub_prefix)
+       /* to be filled by grub-mkelfimage */
+
+       /*
+        *  Leave some breathing room for the prefix.
+        */
+
+       . = _start + GRUB_KERNEL_CPU_DATA_END
+
+codestart:
+       li      2, 0
+       li      13, 0
+
+       /* Stage1 won't zero BSS for us. In other cases, why not do it again?  */
+       lis     6, (__bss_start - 4)@h
+       ori     6, 6, (__bss_start - 4)@l
+       lis     7, (_end - 4)@h
+       ori     7, 7, (_end - 4)@l
+       subf    7, 6, 7
+       srwi    7, 7, 2 /* We store 4 bytes at a time.  */
+       mtctr   7
+2:     stwu    2, 4(6) /* We know r2 is already 0 from above.  */
+       bdnz    2b
+
+       /* Store r5 in grub_ieee1275_entry_fn.  */
+       lis     9, grub_ieee1275_entry_fn@ha
+       stw     5, grub_ieee1275_entry_fn@l(9)
+
+       bl      grub_main
+1:     b       1b
diff --git a/grub-core/kern/rescue_parser.c b/grub-core/kern/rescue_parser.c
new file mode 100644 (file)
index 0000000..d3725e7
--- /dev/null
@@ -0,0 +1,88 @@
+/* rescue_parser.c - rescue mode parser  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/parser.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+
+static grub_err_t
+grub_rescue_parse_line (char *line, grub_reader_getline_t getline)
+{
+  char *name;
+  int n;
+  grub_command_t cmd;
+  char **args;
+
+  if (grub_parser_split_cmdline (line, getline, &n, &args) || n < 0)
+    return grub_errno;
+
+  if (n == 0)
+    return GRUB_ERR_NONE;
+
+  /* In case of an assignment set the environment accordingly
+     instead of calling a function.  */
+  if (n == 1 && grub_strchr (line, '='))
+    {
+      char *val = grub_strchr (args[0], '=');
+      val[0] = 0;
+      grub_env_set (args[0], val + 1);
+      val[0] = '=';
+      goto quit;
+    }
+
+  /* Get the command name.  */
+  name = args[0];
+
+  /* If nothing is specified, restart.  */
+  if (*name == '\0')
+    goto quit;
+
+  cmd = grub_command_find (name);
+  if (cmd)
+    {
+      (cmd->func) (cmd, n - 1, &args[1]);
+    }
+  else
+    {
+      grub_printf ("Unknown command `%s'\n", name);
+      if (grub_command_find ("help"))
+       grub_printf ("Try `help' for usage\n");
+    }
+
+ quit:
+  grub_free (args[0]);
+  grub_free (args);
+
+  return grub_errno;
+}
+
+static struct grub_parser grub_rescue_parser =
+  {
+    .name = "rescue",
+    .parse_line = grub_rescue_parse_line
+  };
+
+void
+grub_register_rescue_parser (void)
+{
+  grub_parser_register ("rescue", &grub_rescue_parser);
+}
diff --git a/grub-core/kern/rescue_reader.c b/grub-core/kern/rescue_reader.c
new file mode 100644 (file)
index 0000000..f573cf4
--- /dev/null
@@ -0,0 +1,92 @@
+/* rescue_reader.c - rescue mode reader  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/reader.h>
+#include <grub/parser.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/mm.h>
+
+#define GRUB_RESCUE_BUF_SIZE   256
+
+static char linebuf[GRUB_RESCUE_BUF_SIZE];
+
+/* Prompt to input a command and read the line.  */
+static grub_err_t
+grub_rescue_read_line (char **line, int cont)
+{
+  int c;
+  int pos = 0;
+
+  grub_printf ((cont) ? "> " : "grub rescue> ");
+  grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE);
+
+  while ((c = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && c != '\r')
+    {
+      if (grub_isprint (c))
+       {
+         if (pos < GRUB_RESCUE_BUF_SIZE - 1)
+           {
+             linebuf[pos++] = c;
+             grub_putchar (c);
+           }
+       }
+      else if (c == '\b')
+       {
+         if (pos > 0)
+           {
+             linebuf[--pos] = 0;
+             grub_putchar (c);
+             grub_putchar (' ');
+             grub_putchar (c);
+           }
+       }
+      grub_refresh ();
+    }
+
+  grub_putchar ('\n');
+  grub_refresh ();
+
+  *line = grub_strdup (linebuf);
+
+  return 0;
+}
+
+void
+grub_rescue_run (void)
+{
+  grub_printf ("Entering rescue mode...\n");
+
+  while (1)
+    {
+      char *line;
+
+      /* Print an error, if any.  */
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+
+      grub_rescue_read_line (&line, 0);
+      if (! line || line[0] == '\0')
+       continue;
+
+      grub_parser_get_current ()->parse_line (line, grub_rescue_read_line);
+      grub_free (line);
+    }
+}
diff --git a/grub-core/kern/sparc64/cache.S b/grub-core/kern/sparc64/cache.S
new file mode 100644 (file)
index 0000000..1a16add
--- /dev/null
@@ -0,0 +1,41 @@
+/* cache.S - Flush the processor cache for a specific region.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+        .file   "cache.S"
+
+        .text
+
+/*
+ * void grub_arch_sync_caches (void *address, grub_size_t len)
+ */
+FUNCTION(grub_arch_sync_caches)
+       brz,pn          %o1, 2f
+        add            %o0, %o1, %o1
+       add             %o1, 7, %o1
+       andn            %o1, 7, %o1
+       andn            %o0, 7, %o0
+       sub             %o1, %o0, %o1
+1:     subcc           %o1, 8, %o1
+       bne,pt          %icc, 1b
+        flush          %o0 + %o1
+2:     retl
+        nop
+
diff --git a/grub-core/kern/sparc64/dl.c b/grub-core/kern/sparc64/dl.c
new file mode 100644 (file)
index 0000000..7b6266c
--- /dev/null
@@ -0,0 +1,142 @@
+/* dl.c - arch-dependent part of loadable module support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+
+/* Check if EHDR is a valid ELF header.  */
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+
+  /* Check the magic numbers.  */
+  if (e->e_ident[EI_CLASS] != ELFCLASS64
+      || e->e_ident[EI_DATA] != ELFDATA2MSB
+      || e->e_machine != EM_SPARCV9)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
+
+  return GRUB_ERR_NONE;
+}
+
+
+/* Relocate symbols.  */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+{
+  Elf_Ehdr *e = ehdr;
+  Elf_Shdr *s;
+  Elf_Word entsize;
+  unsigned i;
+
+  /* Find a symbol table.  */
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
+
+  entsize = s->sh_entsize;
+
+  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_RELA)
+      {
+       grub_dl_segment_t seg;
+
+       /* Find the target segment.  */
+       for (seg = mod->segment; seg; seg = seg->next)
+         if (seg->section == s->sh_info)
+           break;
+
+       if (seg)
+         {
+           Elf_Rela *rel, *max;
+
+           for (rel = (Elf_Rela *) ((char *) e + s->sh_offset),
+                  max = rel + s->sh_size / s->sh_entsize;
+                rel < max;
+                rel++)
+             {
+               Elf_Word *addr;
+               Elf_Sym *sym;
+               Elf_Addr value;
+
+               if (seg->size < rel->r_offset)
+                 return grub_error (GRUB_ERR_BAD_MODULE,
+                                    "reloc offset is out of the segment");
+
+               addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
+               sym = (Elf_Sym *) ((char *) mod->symtab
+                                    + entsize * ELF_R_SYM (rel->r_info));
+
+               value = sym->st_value + rel->r_addend;
+               switch (ELF_R_TYPE (rel->r_info) & 0xff)
+                 {
+                  case R_SPARC_32: /* 3 V-word32 */
+                    if (value & 0xFFFFFFFF00000000)
+                      return grub_error (GRUB_ERR_BAD_MODULE,
+                                         "address out of 32 bits range");
+                    *addr = value;
+                    break;
+                  case R_SPARC_WDISP30: /* 7 V-disp30 */
+                    if (((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000) &&
+                        (((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000)
+                        != 0xFFFFFFFF00000000))
+                      return grub_error (GRUB_ERR_BAD_MODULE,
+                                         "displacement out of 30 bits range");
+                    *addr = (*addr & 0xC0000000) |
+                      (((grub_int32_t) ((value - (Elf_Addr) addr) >> 2)) &
+                       0x3FFFFFFF);
+                    break;
+                  case R_SPARC_HI22: /* 9 V-imm22 */
+                    if (((grub_int32_t) value) & 0xFF00000000)
+                      return grub_error (GRUB_ERR_BAD_MODULE,
+                                         "high address out of 22 bits range");
+                    *addr = (*addr & 0xFFC00000) | ((value >> 10) & 0x3FFFFF);
+                    break;
+                  case R_SPARC_LO10: /* 12 T-simm13 */
+                    *addr = (*addr & 0xFFFFFC00) | (value & 0x3FF);
+                    break;
+                  case R_SPARC_64: /* 32 V-xwords64 */
+                    *(Elf_Xword *) addr = value;
+                    break;
+                 case R_SPARC_OLO10:
+                   *addr = (*addr & ~0x1fff)
+                     | (((value & 0x3ff) +
+                         (ELF_R_TYPE (rel->r_info) >> 8))
+                        & 0x1fff);
+                   break;
+                 default:
+                   return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                                      "this relocation (%d) is not implemented yet",
+                                      ELF_R_TYPE (rel->r_info));
+                 }
+             }
+         }
+      }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/kern/sparc64/ieee1275/crt0.S b/grub-core/kern/sparc64/ieee1275/crt0.S
new file mode 100644 (file)
index 0000000..d5a1722
--- /dev/null
@@ -0,0 +1,91 @@
+/* crt0.S - Startup code for the Sparc64.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <grub/symbol.h>
+#include <grub/machine/kernel.h>
+
+       .text
+       .align  4
+       .globl  _start
+_start:
+       ba      codestart
+        mov  %o4, %o0
+
+       . = EXT_C(_start) + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
+
+VARIABLE(grub_total_module_size)
+       .word   0
+VARIABLE(grub_kernel_image_size)
+       .word   0
+VARIABLE(grub_compressed_size)
+       .word   0
+VARIABLE(grub_prefix)
+       /* to be filled by grub-mkimage */
+
+       /*
+        *  Leave some breathing room for the prefix.
+        */
+
+       . = EXT_C(_start) + GRUB_KERNEL_MACHINE_DATA_END
+
+codestart:
+       /* Copy the modules past the end of the kernel image.
+        * They are currently sitting in the BSS.
+        */
+       sethi   %hi(__bss_start), %o2
+       or      %o2, %lo(__bss_start), %o2
+       sethi   %hi(_end), %o3
+       or      %o3, %lo(_end), %o3
+       sethi   %hi(grub_total_module_size), %o4
+       lduw    [%o4 + %lo(grub_total_module_size)], %o4
+
+       add     %o2, %o4, %o2
+       add     %o3, %o4, %o3
+
+       /* Save ieee1275 stack for future use by booter.  */
+       mov     %o6, %o1
+       /* Our future stack.  */
+       sethi   %hi(GRUB_KERNEL_MACHINE_STACK_SIZE - 2047), %o5
+       or      %o5, %lo(GRUB_KERNEL_MACHINE_STACK_SIZE - 2047), %o5
+       add     %o3, %o5, %o6
+       
+       sub     %o2, 4, %o2
+       sub     %o3, 4, %o3
+1:     lduw    [%o2], %o5
+       stw     %o5, [%o3]
+       subcc   %o4, 4, %o4
+       sub     %o2, 4, %o2
+       bne,pt  %icc, 1b
+        sub    %o3, 4, %o3
+
+       /* Now it's safe to clear out the BSS.  */
+       sethi   %hi(__bss_start), %o2
+       or      %o2, %lo(__bss_start), %o2
+       sethi   %hi(_end), %o3
+       or      %o3, %lo(_end), %o3
+1:     stx     %g0, [%o2]
+       add     %o2, 8, %o2
+       cmp     %o2, %o3
+       blt,pt  %xcc, 1b
+        nop
+       sethi   %hi(grub_ieee1275_original_stack), %o2
+       stx     %o1, [%o2 + %lo(grub_ieee1275_original_stack)]
+       sethi   %hi(grub_ieee1275_entry_fn), %o2
+       call    grub_main
+        stx    %o0, [%o2 + %lo(grub_ieee1275_entry_fn)]
+1:     ba,a    1b
diff --git a/grub-core/kern/sparc64/ieee1275/ieee1275.c b/grub-core/kern/sparc64/ieee1275/ieee1275.c
new file mode 100644 (file)
index 0000000..53be692
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/types.h>
+
+/* Sun specific ieee1275 interfaces used by GRUB.  */
+
+int
+grub_ieee1275_claim_vaddr (grub_addr_t vaddr, grub_size_t size)
+{
+  struct claim_vaddr_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t method;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t align;
+    grub_ieee1275_cell_t size;
+    grub_ieee1275_cell_t virt;
+    grub_ieee1275_cell_t catch_result;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 5, 2);
+  args.method = (grub_ieee1275_cell_t) "claim";
+  args.ihandle = grub_ieee1275_mmu;
+  args.align = 0;
+  args.size = size;
+  args.virt = vaddr;
+  args.catch_result = (grub_ieee1275_cell_t) -1;
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+  return args.catch_result;
+}
+
+int
+grub_ieee1275_alloc_physmem (grub_addr_t *paddr, grub_size_t size,
+                            grub_uint32_t align)
+{
+  grub_uint32_t memory_ihandle;
+  struct alloc_physmem_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t method;
+    grub_ieee1275_cell_t ihandle;
+    grub_ieee1275_cell_t align;
+    grub_ieee1275_cell_t size;
+    grub_ieee1275_cell_t catch_result;
+    grub_ieee1275_cell_t phys_high;
+    grub_ieee1275_cell_t phys_low;
+  }
+  args;
+  grub_ssize_t actual = 0;
+
+  grub_ieee1275_get_property (grub_ieee1275_chosen, "memory",
+                             &memory_ihandle, sizeof (memory_ihandle),
+                             &actual);
+  if (actual != sizeof (memory_ihandle))
+    return -1;
+
+  if (!align)
+    align = 1;
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 3);
+  args.method = (grub_ieee1275_cell_t) "claim";
+  args.ihandle = memory_ihandle;
+  args.align = (align ? align : 1);
+  args.size = size;
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+
+  *paddr = args.phys_low;
+
+  return args.catch_result;
+}
diff --git a/grub-core/kern/sparc64/ieee1275/init.c b/grub-core/kern/sparc64/ieee1275/init.c
new file mode 100644 (file)
index 0000000..a995217
--- /dev/null
@@ -0,0 +1,173 @@
+/*  init.c -- Initialize GRUB on SPARC64.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/time.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/console.h>
+#include <grub/machine/kernel.h>
+#include <grub/machine/time.h>
+#include <grub/ieee1275/ofdisk.h>
+#include <grub/ieee1275/ieee1275.h>
+
+grub_addr_t grub_ieee1275_original_stack;
+
+void
+grub_exit (void)
+{
+  grub_ieee1275_exit ();
+}
+
+static grub_uint64_t
+ieee1275_get_time_ms (void)
+{
+  grub_uint32_t msecs = 0;
+
+  grub_ieee1275_milliseconds (&msecs);
+
+  return msecs;
+}
+
+grub_uint32_t
+grub_get_rtc (void)
+{
+  return ieee1275_get_time_ms ();
+}
+
+grub_addr_t
+grub_arch_modules_addr (void)
+{
+  extern char _end[];
+  return (grub_addr_t) _end;
+}
+
+void
+grub_machine_set_prefix (void)
+{
+  if (grub_prefix[0] != '(')
+    {
+      char bootpath[IEEE1275_MAX_PATH_LEN];
+      char *prefix, *path, *colon;
+      grub_ssize_t actual;
+
+      if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath",
+                                     &bootpath, sizeof (bootpath), &actual))
+       {
+         /* Should never happen.  */
+         grub_printf ("/chosen/bootpath property missing!\n");
+         grub_env_set ("prefix", "");
+         return;
+       }
+
+      /* Transform an OF device path to a GRUB path.  */
+      colon = grub_strchr (bootpath, ':');
+      if (colon)
+       {
+         char *part = colon + 1;
+
+         /* Consistently provide numbered partitions to GRUB.
+            OpenBOOT traditionally uses alphabetical partition
+            specifiers.  */
+         if (part[0] >= 'a' && part[0] <= 'z')
+           part[0] = '1' + (part[0] - 'a');
+       }
+      prefix = grub_ieee1275_encode_devname (bootpath);
+
+      path = grub_xasprintf("%s%s", prefix, grub_prefix);
+
+      grub_strcpy (grub_prefix, path);
+
+      grub_free (path);
+      grub_free (prefix);
+    }
+
+  grub_env_set ("prefix", grub_prefix);
+}
+
+static void
+grub_heap_init (void)
+{
+  grub_mm_init_region ((void *) (grub_modules_get_end ()
+                                + GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000);
+}
+
+static void
+grub_parse_cmdline (void)
+{
+  grub_ssize_t actual;
+  char args[256];
+
+  if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args,
+                                 sizeof args, &actual) == 0
+      && actual > 1)
+    {
+      int i = 0;
+
+      while (i < actual)
+       {
+         char *command = &args[i];
+         char *end;
+         char *val;
+
+         end = grub_strchr (command, ';');
+         if (end == 0)
+           i = actual; /* No more commands after this one.  */
+         else
+           {
+             *end = '\0';
+             i += end - command + 1;
+             while (grub_isspace(args[i]))
+               i++;
+           }
+
+         /* Process command.  */
+         val = grub_strchr (command, '=');
+         if (val)
+           {
+             *val = '\0';
+             grub_env_set (command, val + 1);
+           }
+       }
+    }
+}
+
+void
+grub_machine_init (void)
+{
+  grub_ieee1275_init ();
+  grub_console_init ();
+  grub_heap_init ();
+
+  grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
+  grub_ofdisk_init ();
+
+  grub_parse_cmdline ();
+  grub_install_get_time_ms (ieee1275_get_time_ms);
+}
+
+void
+grub_machine_fini (void)
+{
+  grub_ofdisk_fini ();
+  grub_console_fini ();
+}
diff --git a/grub-core/kern/term.c b/grub-core/kern/term.c
new file mode 100644 (file)
index 0000000..6e3a2b4
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/term.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/time.h>
+
+struct grub_term_output *grub_term_outputs_disabled;
+struct grub_term_input *grub_term_inputs_disabled;
+struct grub_term_output *grub_term_outputs;
+struct grub_term_input *grub_term_inputs;
+
+void (*grub_newline_hook) (void) = NULL;
+
+/* Put a Unicode character.  */
+void
+grub_putcode (grub_uint32_t code, struct grub_term_output *term)
+{
+  if (code == '\t' && term->getxy)
+    {
+      int n;
+
+      n = 8 - ((term->getxy () >> 8) & 7);
+      while (n--)
+       grub_putcode (' ', term);
+
+      return;
+    }
+
+  (term->putchar) (code);
+  if (code == '\n')
+    (term->putchar) ('\r');
+}
+
+/* Put a character. C is one byte of a UTF-8 stream.
+   This function gathers bytes until a valid Unicode character is found.  */
+void
+grub_putchar (int c)
+{
+  static grub_size_t size = 0;
+  static grub_uint8_t buf[6];
+  grub_uint8_t *rest;
+  grub_uint32_t code;
+
+  buf[size++] = c;
+
+  while (grub_utf8_to_ucs4 (&code, 1, buf, size, (const grub_uint8_t **) &rest) 
+        != 0)
+    {
+      struct grub_term_output *term;
+      size -= rest - buf;
+      grub_memmove (buf, rest, size);
+      FOR_ACTIVE_TERM_OUTPUTS(term)
+       grub_putcode (code, term);
+      if (code == '\n' && grub_newline_hook)
+       grub_newline_hook ();
+    }
+}
+
+int
+grub_getkey (void)
+{
+  grub_term_input_t term;
+
+  grub_refresh ();
+
+  while (1)
+    {
+      FOR_ACTIVE_TERM_INPUTS(term)
+      {
+       int key = term->checkkey ();
+       if (key != -1)
+         return term->getkey ();
+      }
+
+      grub_cpu_idle ();
+    }
+}
+
+int
+grub_checkkey (void)
+{
+  grub_term_input_t term;
+
+  FOR_ACTIVE_TERM_INPUTS(term)
+  {
+    int key = term->checkkey ();
+    if (key != -1)
+      return key;
+  }
+
+  return -1;
+}
+
+int
+grub_getkeystatus (void)
+{
+  int status = 0;
+  grub_term_input_t term;
+
+  FOR_ACTIVE_TERM_INPUTS(term)
+  {
+    if (term->getkeystatus)
+      status |= term->getkeystatus ();
+  }
+
+  return status;
+}
+
+void
+grub_cls (void)
+{
+  struct grub_term_output *term;
+
+  FOR_ACTIVE_TERM_OUTPUTS(term)  
+  {
+    if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
+      {
+       grub_putcode ('\n', term);
+       grub_term_refresh (term);
+      }
+    else
+      (term->cls) ();
+  }
+}
+
+void
+grub_setcolorstate (grub_term_color_state state)
+{
+  struct grub_term_output *term;
+  
+  FOR_ACTIVE_TERM_OUTPUTS(term)
+    grub_term_setcolorstate (term, state);
+}
+
+void
+grub_refresh (void)
+{
+  struct grub_term_output *term;
+
+  FOR_ACTIVE_TERM_OUTPUTS(term)
+    grub_term_refresh (term);
+}
diff --git a/grub-core/kern/time.c b/grub-core/kern/time.c
new file mode 100644 (file)
index 0000000..6521ec6
--- /dev/null
@@ -0,0 +1,37 @@
+/* time.c - kernel time functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/time.h>
+
+typedef grub_uint64_t (*get_time_ms_func_t) (void);
+
+/* Function pointer to the implementation in use.  */
+static get_time_ms_func_t get_time_ms_func;
+
+grub_uint64_t
+grub_get_time_ms (void)
+{
+  return get_time_ms_func ();
+}
+
+void
+grub_install_get_time_ms (get_time_ms_func_t func)
+{
+  get_time_ms_func = func;
+}
diff --git a/grub-core/kern/x86_64/dl.c b/grub-core/kern/x86_64/dl.c
new file mode 100644 (file)
index 0000000..090ad78
--- /dev/null
@@ -0,0 +1,119 @@
+/* dl-x86_64.c - arch-dependent part of loadable module support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+
+/* Check if EHDR is a valid ELF header.  */
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+  Elf64_Ehdr *e = ehdr;
+
+  /* Check the magic numbers.  */
+  if (e->e_ident[EI_CLASS] != ELFCLASS64
+      || e->e_ident[EI_DATA] != ELFDATA2LSB
+      || e->e_machine != EM_X86_64)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
+
+  return GRUB_ERR_NONE;
+}
+
+/* Relocate symbols.  */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
+{
+  Elf64_Ehdr *e = ehdr;
+  Elf64_Shdr *s;
+  Elf64_Word entsize;
+  unsigned i;
+
+  /* Find a symbol table.  */
+  for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_SYMTAB)
+      break;
+
+  if (i == e->e_shnum)
+    return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
+
+  entsize = s->sh_entsize;
+
+  for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
+       i < e->e_shnum;
+       i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize))
+    if (s->sh_type == SHT_RELA)
+      {
+       grub_dl_segment_t seg;
+
+       /* Find the target segment.  */
+       for (seg = mod->segment; seg; seg = seg->next)
+         if (seg->section == s->sh_info)
+           break;
+
+       if (seg)
+         {
+           Elf64_Rela *rel, *max;
+
+           for (rel = (Elf64_Rela *) ((char *) e + s->sh_offset),
+                  max = rel + s->sh_size / s->sh_entsize;
+                rel < max;
+                rel++)
+             {
+               Elf64_Word *addr32;
+               Elf64_Xword *addr64;
+               Elf64_Sym *sym;
+
+               if (seg->size < rel->r_offset)
+                 return grub_error (GRUB_ERR_BAD_MODULE,
+                                    "reloc offset is out of the segment");
+
+               addr32 = (Elf64_Word *) ((char *) seg->addr + rel->r_offset);
+               addr64 = (Elf64_Xword *) addr32;
+               sym = (Elf64_Sym *) ((char *) mod->symtab
+                                    + entsize * ELF_R_SYM (rel->r_info));
+
+               switch (ELF_R_TYPE (rel->r_info))
+                 {
+                 case R_X86_64_64:
+                   *addr64 += rel->r_addend + sym->st_value;
+                   break;
+
+                 case R_X86_64_PC32:
+                   *addr32 += rel->r_addend + sym->st_value -
+                             (Elf64_Xword) seg->addr - rel->r_offset;
+                   break;
+
+                  case R_X86_64_32:
+                  case R_X86_64_32S:
+                    *addr32 += rel->r_addend + sym->st_value;
+                    break;
+
+                  default:
+                    grub_fatal ("Unrecognized relocation: %d\n", ELF_R_TYPE (rel->r_info));
+                 }
+             }
+         }
+      }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/kern/x86_64/efi/callwrap.S b/grub-core/kern/x86_64/efi/callwrap.S
new file mode 100644 (file)
index 0000000..1946732
--- /dev/null
@@ -0,0 +1,116 @@
+/* callwrap.S - wrapper for x86_64 efi calls */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/boot.h>
+
+/*
+ * x86_64 uses registry to pass parameters. Unfortunately, gcc and efi use
+ * different call conversion, so we need to do some conversion.
+ *
+ * gcc:
+ *   %rdi,  %esi,  %rdx,  %rcx, %r8, %r9, 8(%rsp), 16(%rsp), ...
+ *
+ * efi:
+ *   %rcx,  %rdx,  %r8,  %r9,  32(%rsp), 40(%rsp), 48(%rsp), ...
+ *
+ */
+
+        .file   "callwrap.S"
+        .text
+
+FUNCTION(efi_wrap_0)
+       subq $40, %rsp
+       call *%rdi
+       addq $40, %rsp
+       ret
+
+FUNCTION(efi_wrap_1)
+       subq $40, %rsp
+       mov  %rsi, %rcx
+       call *%rdi
+       addq $40, %rsp
+       ret
+
+FUNCTION(efi_wrap_2)
+       subq $40, %rsp
+       mov  %rsi, %rcx
+       call *%rdi
+       addq $40, %rsp
+       ret
+
+FUNCTION(efi_wrap_3)
+       subq $40, %rsp
+       mov  %rcx, %r8
+       mov  %rsi, %rcx
+       call *%rdi
+       addq $40, %rsp
+       ret
+
+FUNCTION(efi_wrap_4)
+       subq $40, %rsp
+       mov %r8, %r9
+       mov %rcx, %r8
+       mov %rsi, %rcx
+       call *%rdi
+       addq $40, %rsp
+       ret
+
+FUNCTION(efi_wrap_5)
+       subq $40, %rsp
+       mov %r9, 32(%rsp)
+       mov %r8, %r9
+       mov %rcx, %r8
+       mov %rsi, %rcx
+       call *%rdi
+       addq $40, %rsp
+       ret
+
+FUNCTION(efi_wrap_6)
+       subq $56, %rsp
+       mov 56+8(%rsp), %rax
+       mov %rax, 40(%rsp)
+       mov %r9, 32(%rsp)
+       mov %r8, %r9
+       mov %rcx, %r8
+       mov %rsi, %rcx
+       call *%rdi
+       addq $56, %rsp
+       ret
+
+FUNCTION(efi_wrap_10)
+       subq $88, %rsp
+       mov 88+40(%rsp), %rax
+       mov %rax, 72(%rsp)
+       mov 88+32(%rsp), %rax
+       mov %rax, 64(%rsp)
+       mov 88+24(%rsp), %rax
+       mov %rax, 56(%rsp)
+       mov 88+16(%rsp), %rax
+       mov %rax, 48(%rsp)
+       mov 88+8(%rsp), %rax
+       mov %rax, 40(%rsp)
+       mov %r9, 32(%rsp)
+       mov %r8, %r9
+       mov %rcx, %r8
+       mov %rsi, %rcx
+       call *%rdi
+       addq $88, %rsp
+       ret
diff --git a/grub-core/kern/x86_64/efi/startup.S b/grub-core/kern/x86_64/efi/startup.S
new file mode 100644 (file)
index 0000000..fb4fc7b
--- /dev/null
@@ -0,0 +1,63 @@
+/* startup.S - bootstrap GRUB itself */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/boot.h>
+
+        .file   "startup.S"
+        .text
+        .globl  start, _start
+        .code64
+
+start:
+_start:
+       jmp codestart
+
+        /*
+         *  Compatibility version number
+         *
+         *  These MUST be at byte offset 6 and 7 of the executable
+         *  DO NOT MOVE !!!
+         */
+        . = _start + 0x6
+        .byte   GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
+
+        /*
+         *  This is a special data area 8 bytes from the beginning.
+         */
+
+        . = _start + 0x8
+
+VARIABLE(grub_prefix)
+       /* to be filled by grub-mkimage */
+
+        /*
+         *  Leave some breathing room for the prefix.
+         */
+
+        . = _start + 0x50
+
+codestart:
+       movq    %rcx, EXT_C(grub_efi_image_handle)(%rip)
+       movq    %rdx, EXT_C(grub_efi_system_table)(%rip)
+
+       call    EXT_C(grub_main)
+       ret
+
diff --git a/grub-core/lib/LzFind.c b/grub-core/lib/LzFind.c
new file mode 100644 (file)
index 0000000..cd7a1cb
--- /dev/null
@@ -0,0 +1,774 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#include <string.h>
+
+#include <grub/lib/LzFind.h>
+#include <grub/lib/LzHash.h>
+
+#define kEmptyHashValue 0
+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
+#define kNormalizeMask (~(kNormalizeStepMin - 1))
+#define kMaxHistorySize ((UInt32)3 << 30)
+
+#define kStartMaxLen 3
+
+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
+{
+  if (!p->directInput)
+  {
+    alloc->Free(alloc, p->bufferBase);
+    p->bufferBase = 0;
+  }
+}
+
+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
+
+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
+{
+  UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
+  if (p->directInput)
+  {
+    p->blockSize = blockSize;
+    return 1;
+  }
+  if (p->bufferBase == 0 || p->blockSize != blockSize)
+  {
+    LzInWindow_Free(p, alloc);
+    p->blockSize = blockSize;
+    p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
+  }
+  return (p->bufferBase != 0);
+}
+
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
+
+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
+
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
+{
+  p->posLimit -= subValue;
+  p->pos -= subValue;
+  p->streamPos -= subValue;
+}
+
+static void MatchFinder_ReadBlock(CMatchFinder *p)
+{
+  if (p->streamEndWasReached || p->result != SZ_OK)
+    return;
+  for (;;)
+  {
+    Byte *dest = p->buffer + (p->streamPos - p->pos);
+    size_t size = (p->bufferBase + p->blockSize - dest);
+    if (size == 0)
+      return;
+    p->result = p->stream->Read(p->stream, dest, &size);
+    if (p->result != SZ_OK)
+      return;
+    if (size == 0)
+    {
+      p->streamEndWasReached = 1;
+      return;
+    }
+    p->streamPos += (UInt32)size;
+    if (p->streamPos - p->pos > p->keepSizeAfter)
+      return;
+  }
+}
+
+void MatchFinder_MoveBlock(CMatchFinder *p)
+{
+  memmove(p->bufferBase,
+    p->buffer - p->keepSizeBefore,
+    (size_t)(p->streamPos - p->pos + p->keepSizeBefore));
+  p->buffer = p->bufferBase + p->keepSizeBefore;
+}
+
+int MatchFinder_NeedMove(CMatchFinder *p)
+{
+  /* if (p->streamEndWasReached) return 0; */
+  return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
+}
+
+void MatchFinder_ReadIfRequired(CMatchFinder *p)
+{
+  if (p->streamEndWasReached)
+    return;
+  if (p->keepSizeAfter >= p->streamPos - p->pos)
+    MatchFinder_ReadBlock(p);
+}
+
+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
+{
+  if (MatchFinder_NeedMove(p))
+    MatchFinder_MoveBlock(p);
+  MatchFinder_ReadBlock(p);
+}
+
+static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
+{
+  p->cutValue = 32;
+  p->btMode = 1;
+  p->numHashBytes = 4;
+  /* p->skipModeBits = 0; */
+  p->directInput = 0;
+  p->bigHash = 0;
+}
+
+#define kCrcPoly 0xEDB88320
+
+void MatchFinder_Construct(CMatchFinder *p)
+{
+  UInt32 i;
+  p->bufferBase = 0;
+  p->directInput = 0;
+  p->hash = 0;
+  MatchFinder_SetDefaultSettings(p);
+
+  for (i = 0; i < 256; i++)
+  {
+    UInt32 r = i;
+    int j;
+    for (j = 0; j < 8; j++)
+      r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+    p->crc[i] = r;
+  }
+}
+
+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->hash);
+  p->hash = 0;
+}
+
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
+{
+  MatchFinder_FreeThisClassMemory(p, alloc);
+  LzInWindow_Free(p, alloc);
+}
+
+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
+{
+  size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
+  if (sizeInBytes / sizeof(CLzRef) != num)
+    return 0;
+  return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
+}
+
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
+    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
+    ISzAlloc *alloc)
+{
+  UInt32 sizeReserv;
+  if (historySize > kMaxHistorySize)
+  {
+    MatchFinder_Free(p, alloc);
+    return 0;
+  }
+  sizeReserv = historySize >> 1;
+  if (historySize > ((UInt32)2 << 30))
+    sizeReserv = historySize >> 2;
+  sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
+
+  p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
+  p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
+  /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
+  if (LzInWindow_Create(p, sizeReserv, alloc))
+  {
+    UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1;
+    UInt32 hs;
+    p->matchMaxLen = matchMaxLen;
+    {
+      p->fixedHashSize = 0;
+      if (p->numHashBytes == 2)
+        hs = (1 << 16) - 1;
+      else
+      {
+        hs = historySize - 1;
+        hs |= (hs >> 1);
+        hs |= (hs >> 2);
+        hs |= (hs >> 4);
+        hs |= (hs >> 8);
+        hs >>= 1;
+        /* hs >>= p->skipModeBits; */
+        hs |= 0xFFFF; /* don't change it! It's required for Deflate */
+        if (hs > (1 << 24))
+        {
+          if (p->numHashBytes == 3)
+            hs = (1 << 24) - 1;
+          else
+            hs >>= 1;
+        }
+      }
+      p->hashMask = hs;
+      hs++;
+      if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
+      if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
+      if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
+      hs += p->fixedHashSize;
+    }
+
+    {
+      UInt32 prevSize = p->hashSizeSum + p->numSons;
+      UInt32 newSize;
+      p->historySize = historySize;
+      p->hashSizeSum = hs;
+      p->cyclicBufferSize = newCyclicBufferSize;
+      p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
+      newSize = p->hashSizeSum + p->numSons;
+      if (p->hash != 0 && prevSize == newSize)
+        return 1;
+      MatchFinder_FreeThisClassMemory(p, alloc);
+      p->hash = AllocRefs(newSize, alloc);
+      if (p->hash != 0)
+      {
+        p->son = p->hash + p->hashSizeSum;
+        return 1;
+      }
+    }
+  }
+  MatchFinder_Free(p, alloc);
+  return 0;
+}
+
+static void MatchFinder_SetLimits(CMatchFinder *p)
+{
+  UInt32 limit = kMaxValForNormalize - p->pos;
+  UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
+  if (limit2 < limit)
+    limit = limit2;
+  limit2 = p->streamPos - p->pos;
+  if (limit2 <= p->keepSizeAfter)
+  {
+    if (limit2 > 0)
+      limit2 = 1;
+  }
+  else
+    limit2 -= p->keepSizeAfter;
+  if (limit2 < limit)
+    limit = limit2;
+  {
+    UInt32 lenLimit = p->streamPos - p->pos;
+    if (lenLimit > p->matchMaxLen)
+      lenLimit = p->matchMaxLen;
+    p->lenLimit = lenLimit;
+  }
+  p->posLimit = p->pos + limit;
+}
+
+void MatchFinder_Init(CMatchFinder *p)
+{
+  UInt32 i;
+  for(i = 0; i < p->hashSizeSum; i++)
+    p->hash[i] = kEmptyHashValue;
+  p->cyclicBufferPos = 0;
+  p->buffer = p->bufferBase;
+  p->pos = p->streamPos = p->cyclicBufferSize;
+  p->result = SZ_OK;
+  p->streamEndWasReached = 0;
+  MatchFinder_ReadBlock(p);
+  MatchFinder_SetLimits(p);
+}
+
+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
+{
+  return (p->pos - p->historySize - 1) & kNormalizeMask;
+}
+
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
+{
+  UInt32 i;
+  for (i = 0; i < numItems; i++)
+  {
+    UInt32 value = items[i];
+    if (value <= subValue)
+      value = kEmptyHashValue;
+    else
+      value -= subValue;
+    items[i] = value;
+  }
+}
+
+static void MatchFinder_Normalize(CMatchFinder *p)
+{
+  UInt32 subValue = MatchFinder_GetSubValue(p);
+  MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
+  MatchFinder_ReduceOffsets(p, subValue);
+}
+
+static void MatchFinder_CheckLimits(CMatchFinder *p)
+{
+  if (p->pos == kMaxValForNormalize)
+    MatchFinder_Normalize(p);
+  if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
+    MatchFinder_CheckAndMoveAndRead(p);
+  if (p->cyclicBufferPos == p->cyclicBufferSize)
+    p->cyclicBufferPos = 0;
+  MatchFinder_SetLimits(p);
+}
+
+static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
+    UInt32 *distances, UInt32 maxLen)
+{
+  son[_cyclicBufferPos] = curMatch;
+  for (;;)
+  {
+    UInt32 delta = pos - curMatch;
+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+      return distances;
+    {
+      const Byte *pb = cur - delta;
+      curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
+      if (pb[maxLen] == cur[maxLen] && *pb == *cur)
+      {
+        UInt32 len = 0;
+        while(++len != lenLimit)
+          if (pb[len] != cur[len])
+            break;
+        if (maxLen < len)
+        {
+          *distances++ = maxLen = len;
+          *distances++ = delta - 1;
+          if (len == lenLimit)
+            return distances;
+        }
+      }
+    }
+  }
+}
+
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
+    UInt32 *distances, UInt32 maxLen)
+{
+  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
+  UInt32 len0 = 0, len1 = 0;
+  for (;;)
+  {
+    UInt32 delta = pos - curMatch;
+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+    {
+      *ptr0 = *ptr1 = kEmptyHashValue;
+      return distances;
+    }
+    {
+      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+      const Byte *pb = cur - delta;
+      UInt32 len = (len0 < len1 ? len0 : len1);
+      if (pb[len] == cur[len])
+      {
+        if (++len != lenLimit && pb[len] == cur[len])
+          while(++len != lenLimit)
+            if (pb[len] != cur[len])
+              break;
+        if (maxLen < len)
+        {
+          *distances++ = maxLen = len;
+          *distances++ = delta - 1;
+          if (len == lenLimit)
+          {
+            *ptr1 = pair[0];
+            *ptr0 = pair[1];
+            return distances;
+          }
+        }
+      }
+      if (pb[len] < cur[len])
+      {
+        *ptr1 = curMatch;
+        ptr1 = pair + 1;
+        curMatch = *ptr1;
+        len1 = len;
+      }
+      else
+      {
+        *ptr0 = curMatch;
+        ptr0 = pair;
+        curMatch = *ptr0;
+        len0 = len;
+      }
+    }
+  }
+}
+
+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
+{
+  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
+  UInt32 len0 = 0, len1 = 0;
+  for (;;)
+  {
+    UInt32 delta = pos - curMatch;
+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+    {
+      *ptr0 = *ptr1 = kEmptyHashValue;
+      return;
+    }
+    {
+      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+      const Byte *pb = cur - delta;
+      UInt32 len = (len0 < len1 ? len0 : len1);
+      if (pb[len] == cur[len])
+      {
+        while(++len != lenLimit)
+          if (pb[len] != cur[len])
+            break;
+        {
+          if (len == lenLimit)
+          {
+            *ptr1 = pair[0];
+            *ptr0 = pair[1];
+            return;
+          }
+        }
+      }
+      if (pb[len] < cur[len])
+      {
+        *ptr1 = curMatch;
+        ptr1 = pair + 1;
+        curMatch = *ptr1;
+        len1 = len;
+      }
+      else
+      {
+        *ptr0 = curMatch;
+        ptr0 = pair;
+        curMatch = *ptr0;
+        len0 = len;
+      }
+    }
+  }
+}
+
+#define MOVE_POS \
+  ++p->cyclicBufferPos; \
+  p->buffer++; \
+  if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
+
+#define MOVE_POS_RET MOVE_POS return offset;
+
+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
+
+#define GET_MATCHES_HEADER2(minLen, ret_op) \
+  UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
+  lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
+  cur = p->buffer;
+
+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
+#define SKIP_HEADER(minLen)        GET_MATCHES_HEADER2(minLen, continue)
+
+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
+
+#define GET_MATCHES_FOOTER(offset, maxLen) \
+  offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
+  distances + offset, maxLen) - distances); MOVE_POS_RET;
+
+#define SKIP_FOOTER \
+  SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
+
+static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 offset;
+  GET_MATCHES_HEADER(2)
+  HASH2_CALC;
+  curMatch = p->hash[hashValue];
+  p->hash[hashValue] = p->pos;
+  offset = 0;
+  GET_MATCHES_FOOTER(offset, 1)
+}
+
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 offset;
+  GET_MATCHES_HEADER(3)
+  HASH_ZIP_CALC;
+  curMatch = p->hash[hashValue];
+  p->hash[hashValue] = p->pos;
+  offset = 0;
+  GET_MATCHES_FOOTER(offset, 2)
+}
+
+static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 hash2Value, delta2, maxLen, offset;
+  GET_MATCHES_HEADER(3)
+
+  HASH3_CALC;
+
+  delta2 = p->pos - p->hash[hash2Value];
+  curMatch = p->hash[kFix3HashSize + hashValue];
+
+  p->hash[hash2Value] =
+  p->hash[kFix3HashSize + hashValue] = p->pos;
+
+
+  maxLen = 2;
+  offset = 0;
+  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+  {
+    for (; maxLen != lenLimit; maxLen++)
+      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
+        break;
+    distances[0] = maxLen;
+    distances[1] = delta2 - 1;
+    offset = 2;
+    if (maxLen == lenLimit)
+    {
+      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
+      MOVE_POS_RET;
+    }
+  }
+  GET_MATCHES_FOOTER(offset, maxLen)
+}
+
+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+  GET_MATCHES_HEADER(4)
+
+  HASH4_CALC;
+
+  delta2 = p->pos - p->hash[                hash2Value];
+  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
+  curMatch = p->hash[kFix4HashSize + hashValue];
+
+  p->hash[                hash2Value] =
+  p->hash[kFix3HashSize + hash3Value] =
+  p->hash[kFix4HashSize + hashValue] = p->pos;
+
+  maxLen = 1;
+  offset = 0;
+  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+  {
+    distances[0] = maxLen = 2;
+    distances[1] = delta2 - 1;
+    offset = 2;
+  }
+  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+  {
+    maxLen = 3;
+    distances[offset + 1] = delta3 - 1;
+    offset += 2;
+    delta2 = delta3;
+  }
+  if (offset != 0)
+  {
+    for (; maxLen != lenLimit; maxLen++)
+      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
+        break;
+    distances[offset - 2] = maxLen;
+    if (maxLen == lenLimit)
+    {
+      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
+      MOVE_POS_RET;
+    }
+  }
+  if (maxLen < 3)
+    maxLen = 3;
+  GET_MATCHES_FOOTER(offset, maxLen)
+}
+
+static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+  GET_MATCHES_HEADER(4)
+
+  HASH4_CALC;
+
+  delta2 = p->pos - p->hash[                hash2Value];
+  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
+  curMatch = p->hash[kFix4HashSize + hashValue];
+
+  p->hash[                hash2Value] =
+  p->hash[kFix3HashSize + hash3Value] =
+  p->hash[kFix4HashSize + hashValue] = p->pos;
+
+  maxLen = 1;
+  offset = 0;
+  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+  {
+    distances[0] = maxLen = 2;
+    distances[1] = delta2 - 1;
+    offset = 2;
+  }
+  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+  {
+    maxLen = 3;
+    distances[offset + 1] = delta3 - 1;
+    offset += 2;
+    delta2 = delta3;
+  }
+  if (offset != 0)
+  {
+    for (; maxLen != lenLimit; maxLen++)
+      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
+        break;
+    distances[offset - 2] = maxLen;
+    if (maxLen == lenLimit)
+    {
+      p->son[p->cyclicBufferPos] = curMatch;
+      MOVE_POS_RET;
+    }
+  }
+  if (maxLen < 3)
+    maxLen = 3;
+  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+    distances + offset, maxLen) - (distances));
+  MOVE_POS_RET
+}
+
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 offset;
+  GET_MATCHES_HEADER(3)
+  HASH_ZIP_CALC;
+  curMatch = p->hash[hashValue];
+  p->hash[hashValue] = p->pos;
+  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+    distances, 2) - (distances));
+  MOVE_POS_RET
+}
+
+static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    SKIP_HEADER(2)
+    HASH2_CALC;
+    curMatch = p->hash[hashValue];
+    p->hash[hashValue] = p->pos;
+    SKIP_FOOTER
+  }
+  while (--num != 0);
+}
+
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    SKIP_HEADER(3)
+    HASH_ZIP_CALC;
+    curMatch = p->hash[hashValue];
+    p->hash[hashValue] = p->pos;
+    SKIP_FOOTER
+  }
+  while (--num != 0);
+}
+
+static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    UInt32 hash2Value;
+    SKIP_HEADER(3)
+    HASH3_CALC;
+    curMatch = p->hash[kFix3HashSize + hashValue];
+    p->hash[hash2Value] =
+    p->hash[kFix3HashSize + hashValue] = p->pos;
+    SKIP_FOOTER
+  }
+  while (--num != 0);
+}
+
+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    UInt32 hash2Value, hash3Value;
+    SKIP_HEADER(4)
+    HASH4_CALC;
+    curMatch = p->hash[kFix4HashSize + hashValue];
+    p->hash[                hash2Value] =
+    p->hash[kFix3HashSize + hash3Value] = p->pos;
+    p->hash[kFix4HashSize + hashValue] = p->pos;
+    SKIP_FOOTER
+  }
+  while (--num != 0);
+}
+
+static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    UInt32 hash2Value, hash3Value;
+    SKIP_HEADER(4)
+    HASH4_CALC;
+    curMatch = p->hash[kFix4HashSize + hashValue];
+    p->hash[                hash2Value] =
+    p->hash[kFix3HashSize + hash3Value] =
+    p->hash[kFix4HashSize + hashValue] = p->pos;
+    p->son[p->cyclicBufferPos] = curMatch;
+    MOVE_POS
+  }
+  while (--num != 0);
+}
+
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    SKIP_HEADER(3)
+    HASH_ZIP_CALC;
+    curMatch = p->hash[hashValue];
+    p->hash[hashValue] = p->pos;
+    p->son[p->cyclicBufferPos] = curMatch;
+    MOVE_POS
+  }
+  while (--num != 0);
+}
+
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
+{
+  vTable->Init = (Mf_Init_Func)MatchFinder_Init;
+  vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
+  vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
+  vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
+  if (!p->btMode)
+  {
+    vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
+    vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
+  }
+  else if (p->numHashBytes == 2)
+  {
+    vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
+    vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
+  }
+  else if (p->numHashBytes == 3)
+  {
+    vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
+    vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
+  }
+  else
+  {
+    vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
+    vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
+  }
+}
diff --git a/grub-core/lib/LzmaDec.c b/grub-core/lib/LzmaDec.c
new file mode 100644 (file)
index 0000000..62ebee6
--- /dev/null
@@ -0,0 +1,1035 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#include <grub/lib/LzmaDec.h>
+
+#include <string.h>
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_INIT_SIZE 5
+
+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
+  { UPDATE_0(p); i = (i + i); A0; } else \
+  { UPDATE_1(p); i = (i + i) + 1; A1; }
+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
+
+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
+#define TREE_DECODE(probs, limit, i) \
+  { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
+
+/* #define _LZMA_SIZE_OPT */
+
+#ifdef _LZMA_SIZE_OPT
+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
+#else
+#define TREE_6_DECODE(probs, i) \
+  { i = 1; \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  TREE_GET_BIT(probs, i); \
+  i -= 0x40; }
+#endif
+
+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0_CHECK range = bound;
+#define UPDATE_1_CHECK range -= bound; code -= bound;
+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
+  { UPDATE_0_CHECK; i = (i + i); A0; } else \
+  { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
+#define TREE_DECODE_CHECK(probs, limit, i) \
+  { i = 1; do { GET_BIT_CHECK(probs + i, i) } while(i < limit); i -= limit; }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+/*
+#define LZMA_STREAM_WAS_FINISHED_ID (-1)
+#define LZMA_SPEC_LEN_OFFSET (-3)
+*/
+
+Byte kLiteralNextStates[kNumStates * 2] =
+{
+  0, 0, 0, 0, 1, 2, 3,  4,  5,  6,  4,  5,
+  7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
+};
+
+#define LZMA_DIC_MIN (1 << 12)
+
+/* First LZMA-symbol is always decoded.
+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
+Out:
+  Result:
+    0 - OK
+    1 - Error
+  p->remainLen:
+    < kMatchSpecLenStart : normal remain
+    = kMatchSpecLenStart : finished
+    = kMatchSpecLenStart + 1 : Flush marker
+    = kMatchSpecLenStart + 2 : State Init Marker
+*/
+
+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+  CLzmaProb *probs = p->probs;
+
+  unsigned state = p->state;
+  UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
+  unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
+  unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
+  unsigned lc = p->prop.lc;
+
+  Byte *dic = p->dic;
+  SizeT dicBufSize = p->dicBufSize;
+  SizeT dicPos = p->dicPos;
+
+  UInt32 processedPos = p->processedPos;
+  UInt32 checkDicSize = p->checkDicSize;
+  unsigned len = 0;
+
+  const Byte *buf = p->buf;
+  UInt32 range = p->range;
+  UInt32 code = p->code;
+
+  do
+  {
+    CLzmaProb *prob;
+    UInt32 bound;
+    unsigned ttt;
+    unsigned posState = processedPos & pbMask;
+
+    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+    IF_BIT_0(prob)
+    {
+      unsigned symbol;
+      UPDATE_0(prob);
+      prob = probs + Literal;
+      if (checkDicSize != 0 || processedPos != 0)
+        prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
+        (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
+
+      if (state < kNumLitStates)
+      {
+        symbol = 1;
+        do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
+      }
+      else
+      {
+        unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+        unsigned offs = 0x100;
+        symbol = 1;
+        do
+        {
+          unsigned bit;
+          CLzmaProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & offs);
+          probLit = prob + offs + bit + symbol;
+          GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
+        }
+        while (symbol < 0x100);
+      }
+      dic[dicPos++] = (Byte)symbol;
+      processedPos++;
+
+      state = kLiteralNextStates[state];
+      /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
+      continue;
+    }
+    else
+    {
+      UPDATE_1(prob);
+      prob = probs + IsRep + state;
+      IF_BIT_0(prob)
+      {
+        UPDATE_0(prob);
+        state += kNumStates;
+        prob = probs + LenCoder;
+      }
+      else
+      {
+        UPDATE_1(prob);
+        if (checkDicSize == 0 && processedPos == 0)
+          return SZ_ERROR_DATA;
+        prob = probs + IsRepG0 + state;
+        IF_BIT_0(prob)
+        {
+          UPDATE_0(prob);
+          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IF_BIT_0(prob)
+          {
+            UPDATE_0(prob);
+            dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+            dicPos++;
+            processedPos++;
+            state = state < kNumLitStates ? 9 : 11;
+            continue;
+          }
+          UPDATE_1(prob);
+        }
+        else
+        {
+          UInt32 distance;
+          UPDATE_1(prob);
+          prob = probs + IsRepG1 + state;
+          IF_BIT_0(prob)
+          {
+            UPDATE_0(prob);
+            distance = rep1;
+          }
+          else
+          {
+            UPDATE_1(prob);
+            prob = probs + IsRepG2 + state;
+            IF_BIT_0(prob)
+            {
+              UPDATE_0(prob);
+              distance = rep2;
+            }
+            else
+            {
+              UPDATE_1(prob);
+              distance = rep3;
+              rep3 = rep2;
+            }
+            rep2 = rep1;
+          }
+          rep1 = rep0;
+          rep0 = distance;
+        }
+        state = state < kNumLitStates ? 8 : 11;
+        prob = probs + RepLenCoder;
+      }
+      {
+        unsigned limit, offset;
+        CLzmaProb *probLen = prob + LenChoice;
+        IF_BIT_0(probLen)
+        {
+          UPDATE_0(probLen);
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          limit = (1 << kLenNumLowBits);
+        }
+        else
+        {
+          UPDATE_1(probLen);
+          probLen = prob + LenChoice2;
+          IF_BIT_0(probLen)
+          {
+            UPDATE_0(probLen);
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            limit = (1 << kLenNumMidBits);
+          }
+          else
+          {
+            UPDATE_1(probLen);
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            limit = (1 << kLenNumHighBits);
+          }
+        }
+        TREE_DECODE(probLen, limit, len);
+        len += offset;
+      }
+
+      if (state >= kNumStates)
+      {
+        UInt32 distance;
+        prob = probs + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
+        TREE_6_DECODE(prob, distance);
+        if (distance >= kStartPosModelIndex)
+        {
+          unsigned posSlot = (unsigned)distance;
+          int numDirectBits = (int)(((distance >> 1) - 1));
+          distance = (2 | (distance & 1));
+          if (posSlot < kEndPosModelIndex)
+          {
+            distance <<= numDirectBits;
+            prob = probs + SpecPos + distance - posSlot - 1;
+            {
+              UInt32 mask = 1;
+              unsigned i = 1;
+              do
+              {
+                GET_BIT2(prob + i, i, ; , distance |= mask);
+                mask <<= 1;
+              }
+              while(--numDirectBits != 0);
+            }
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              NORMALIZE
+              range >>= 1;
+
+              {
+                UInt32 t;
+                code -= range;
+                t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
+                distance = (distance << 1) + (t + 1);
+                code += range & t;
+              }
+              /*
+              distance <<= 1;
+              if (code >= range)
+              {
+                code -= range;
+                distance |= 1;
+              }
+              */
+            }
+            while (--numDirectBits != 0);
+            prob = probs + Align;
+            distance <<= kNumAlignBits;
+            {
+              unsigned i = 1;
+              GET_BIT2(prob + i, i, ; , distance |= 1);
+              GET_BIT2(prob + i, i, ; , distance |= 2);
+              GET_BIT2(prob + i, i, ; , distance |= 4);
+              GET_BIT2(prob + i, i, ; , distance |= 8);
+            }
+            if (distance == (UInt32)0xFFFFFFFF)
+            {
+              len += kMatchSpecLenStart;
+              state -= kNumStates;
+              break;
+            }
+          }
+        }
+        rep3 = rep2;
+        rep2 = rep1;
+        rep1 = rep0;
+        rep0 = distance + 1;
+        if (checkDicSize == 0)
+        {
+          if (distance >= processedPos)
+            return SZ_ERROR_DATA;
+        }
+        else if (distance >= checkDicSize)
+          return SZ_ERROR_DATA;
+        state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
+        /* state = kLiteralNextStates[state]; */
+      }
+
+      len += kMatchMinLen;
+
+      {
+        SizeT rem = limit - dicPos;
+        unsigned curLen = ((rem < len) ? (unsigned)rem : len);
+        SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
+
+        processedPos += curLen;
+
+        len -= curLen;
+        if (pos + curLen <= dicBufSize)
+        {
+          Byte *dest = dic + dicPos;
+          ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
+          const Byte *lim = dest + curLen;
+          dicPos += curLen;
+          do
+            *(dest) = (Byte)*(dest + src);
+          while (++dest != lim);
+        }
+        else
+        {
+          do
+          {
+            dic[dicPos++] = dic[pos];
+            if (++pos == dicBufSize)
+              pos = 0;
+          }
+          while (--curLen != 0);
+        }
+      }
+    }
+  }
+  while (dicPos < limit && buf < bufLimit);
+  NORMALIZE;
+  p->buf = buf;
+  p->range = range;
+  p->code = code;
+  p->remainLen = len;
+  p->dicPos = dicPos;
+  p->processedPos = processedPos;
+  p->reps[0] = rep0;
+  p->reps[1] = rep1;
+  p->reps[2] = rep2;
+  p->reps[3] = rep3;
+  p->state = state;
+
+  return SZ_OK;
+}
+
+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
+{
+  if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
+  {
+    Byte *dic = p->dic;
+    SizeT dicPos = p->dicPos;
+    SizeT dicBufSize = p->dicBufSize;
+    unsigned len = p->remainLen;
+    UInt32 rep0 = p->reps[0];
+    if (limit - dicPos < len)
+      len = (unsigned)(limit - dicPos);
+
+    if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
+      p->checkDicSize = p->prop.dicSize;
+
+    p->processedPos += len;
+    p->remainLen -= len;
+    while (len-- != 0)
+    {
+      dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+      dicPos++;
+    }
+    p->dicPos = dicPos;
+  }
+}
+
+/* LzmaDec_DecodeReal2 decodes LZMA-symbols and sets p->needFlush and p->needInit, if required. */
+
+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+  do
+  {
+    SizeT limit2 = limit;
+    if (p->checkDicSize == 0)
+    {
+      UInt32 rem = p->prop.dicSize - p->processedPos;
+      if (limit - p->dicPos > rem)
+        limit2 = p->dicPos + rem;
+    }
+    RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
+    if (p->processedPos >= p->prop.dicSize)
+      p->checkDicSize = p->prop.dicSize;
+    LzmaDec_WriteRem(p, limit);
+  }
+  while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
+
+  if (p->remainLen > kMatchSpecLenStart)
+  {
+    p->remainLen = kMatchSpecLenStart;
+  }
+  return 0;
+}
+
+typedef enum
+{
+  DUMMY_ERROR, /* unexpected end of input stream */
+  DUMMY_LIT,
+  DUMMY_MATCH,
+  DUMMY_REP
+} ELzmaDummy;
+
+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
+{
+  UInt32 range = p->range;
+  UInt32 code = p->code;
+  const Byte *bufLimit = buf + inSize;
+  CLzmaProb *probs = p->probs;
+  unsigned state = p->state;
+  ELzmaDummy res;
+
+  {
+    CLzmaProb *prob;
+    UInt32 bound;
+    unsigned ttt;
+    unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
+
+    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+    IF_BIT_0_CHECK(prob)
+    {
+      UPDATE_0_CHECK
+
+      /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
+
+      prob = probs + Literal;
+      if (p->checkDicSize != 0 || p->processedPos != 0)
+        prob += (LZMA_LIT_SIZE *
+          ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
+          (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
+
+      if (state < kNumLitStates)
+      {
+        unsigned symbol = 1;
+        do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
+      }
+      else
+      {
+        unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
+            ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
+        unsigned offs = 0x100;
+        unsigned symbol = 1;
+        do
+        {
+          unsigned bit;
+          CLzmaProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & offs);
+          probLit = prob + offs + bit + symbol;
+          GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
+        }
+        while (symbol < 0x100);
+      }
+      res = DUMMY_LIT;
+    }
+    else
+    {
+      unsigned len;
+      UPDATE_1_CHECK;
+
+      prob = probs + IsRep + state;
+      IF_BIT_0_CHECK(prob)
+      {
+        UPDATE_0_CHECK;
+        state = 0;
+        prob = probs + LenCoder;
+        res = DUMMY_MATCH;
+      }
+      else
+      {
+        UPDATE_1_CHECK;
+        res = DUMMY_REP;
+        prob = probs + IsRepG0 + state;
+        IF_BIT_0_CHECK(prob)
+        {
+          UPDATE_0_CHECK;
+          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IF_BIT_0_CHECK(prob)
+          {
+            UPDATE_0_CHECK;
+            NORMALIZE_CHECK;
+            return DUMMY_REP;
+          }
+          else
+          {
+            UPDATE_1_CHECK;
+          }
+        }
+        else
+        {
+          UPDATE_1_CHECK;
+          prob = probs + IsRepG1 + state;
+          IF_BIT_0_CHECK(prob)
+          {
+            UPDATE_0_CHECK;
+          }
+          else
+          {
+            UPDATE_1_CHECK;
+            prob = probs + IsRepG2 + state;
+            IF_BIT_0_CHECK(prob)
+            {
+              UPDATE_0_CHECK;
+            }
+            else
+            {
+              UPDATE_1_CHECK;
+            }
+          }
+        }
+        state = kNumStates;
+        prob = probs + RepLenCoder;
+      }
+      {
+        unsigned limit, offset;
+        CLzmaProb *probLen = prob + LenChoice;
+        IF_BIT_0_CHECK(probLen)
+        {
+          UPDATE_0_CHECK;
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          limit = 1 << kLenNumLowBits;
+        }
+        else
+        {
+          UPDATE_1_CHECK;
+          probLen = prob + LenChoice2;
+          IF_BIT_0_CHECK(probLen)
+          {
+            UPDATE_0_CHECK;
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            limit = 1 << kLenNumMidBits;
+          }
+          else
+          {
+            UPDATE_1_CHECK;
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            limit = 1 << kLenNumHighBits;
+          }
+        }
+        TREE_DECODE_CHECK(probLen, limit, len);
+        len += offset;
+      }
+
+      if (state < 4)
+      {
+        unsigned posSlot;
+        prob = probs + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+            kNumPosSlotBits);
+        TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
+        if (posSlot >= kStartPosModelIndex)
+        {
+          int numDirectBits = ((posSlot >> 1) - 1);
+
+          /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
+
+          if (posSlot < kEndPosModelIndex)
+          {
+            prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              NORMALIZE_CHECK
+              range >>= 1;
+              code -= range & (((code - range) >> 31) - 1);
+              /* if (code >= range) code -= range; */
+            }
+            while (--numDirectBits != 0);
+            prob = probs + Align;
+            numDirectBits = kNumAlignBits;
+          }
+          {
+            unsigned i = 1;
+            do
+            {
+              GET_BIT_CHECK(prob + i, i);
+            }
+            while(--numDirectBits != 0);
+          }
+        }
+      }
+    }
+  }
+  NORMALIZE_CHECK;
+  return res;
+}
+
+
+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
+{
+  p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
+  p->range = 0xFFFFFFFF;
+  p->needFlush = 0;
+}
+
+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
+{
+  p->needFlush = 1;
+  p->remainLen = 0;
+  p->tempBufSize = 0;
+
+  if (initDic)
+  {
+    p->processedPos = 0;
+    p->checkDicSize = 0;
+    p->needInitState = 1;
+  }
+  if (initState)
+    p->needInitState = 1;
+}
+
+void LzmaDec_Init(CLzmaDec *p)
+{
+  p->dicPos = 0;
+  LzmaDec_InitDicAndState(p, True, True);
+}
+
+static void LzmaDec_InitStateReal(CLzmaDec *p)
+{
+  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
+  UInt32 i;
+  CLzmaProb *probs = p->probs;
+  for (i = 0; i < numProbs; i++)
+    probs[i] = kBitModelTotal >> 1;
+  p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
+  p->state = 0;
+  p->needInitState = 0;
+}
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
+    ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+  SizeT inSize = *srcLen;
+  (*srcLen) = 0;
+  LzmaDec_WriteRem(p, dicLimit);
+
+  *status = LZMA_STATUS_NOT_SPECIFIED;
+
+  while (p->remainLen != kMatchSpecLenStart)
+  {
+      int checkEndMarkNow;
+
+      if (p->needFlush != 0)
+      {
+        for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
+          p->tempBuf[p->tempBufSize++] = *src++;
+        if (p->tempBufSize < RC_INIT_SIZE)
+        {
+          *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+          return SZ_OK;
+        }
+        if (p->tempBuf[0] != 0)
+          return SZ_ERROR_DATA;
+
+        LzmaDec_InitRc(p, p->tempBuf);
+        p->tempBufSize = 0;
+      }
+
+      checkEndMarkNow = 0;
+      if (p->dicPos >= dicLimit)
+      {
+        if (p->remainLen == 0 && p->code == 0)
+        {
+          *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
+          return SZ_OK;
+        }
+        if (finishMode == LZMA_FINISH_ANY)
+        {
+          *status = LZMA_STATUS_NOT_FINISHED;
+          return SZ_OK;
+        }
+        if (p->remainLen != 0)
+        {
+          *status = LZMA_STATUS_NOT_FINISHED;
+          return SZ_ERROR_DATA;
+        }
+        checkEndMarkNow = 1;
+      }
+
+      if (p->needInitState)
+        LzmaDec_InitStateReal(p);
+
+      if (p->tempBufSize == 0)
+      {
+        SizeT processed;
+        const Byte *bufLimit;
+        if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+        {
+          int dummyRes = LzmaDec_TryDummy(p, src, inSize);
+          if (dummyRes == DUMMY_ERROR)
+          {
+            memcpy(p->tempBuf, src, inSize);
+            p->tempBufSize = (unsigned)inSize;
+            (*srcLen) += inSize;
+            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+            return SZ_OK;
+          }
+          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+          {
+            *status = LZMA_STATUS_NOT_FINISHED;
+            return SZ_ERROR_DATA;
+          }
+          bufLimit = src;
+        }
+        else
+          bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
+        p->buf = src;
+        if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
+          return SZ_ERROR_DATA;
+        processed = p->buf - src;
+        (*srcLen) += processed;
+        src += processed;
+        inSize -= processed;
+      }
+      else
+      {
+        unsigned rem = p->tempBufSize, lookAhead = 0;
+        while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
+          p->tempBuf[rem++] = src[lookAhead++];
+        p->tempBufSize = rem;
+        if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+        {
+          int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
+          if (dummyRes == DUMMY_ERROR)
+          {
+            (*srcLen) += lookAhead;
+            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+            return SZ_OK;
+          }
+          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+          {
+            *status = LZMA_STATUS_NOT_FINISHED;
+            return SZ_ERROR_DATA;
+          }
+        }
+        p->buf = p->tempBuf;
+        if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
+          return SZ_ERROR_DATA;
+        lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
+        (*srcLen) += lookAhead;
+        src += lookAhead;
+        inSize -= lookAhead;
+        p->tempBufSize = 0;
+      }
+  }
+  if (p->code == 0)
+    *status = LZMA_STATUS_FINISHED_WITH_MARK;
+  return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
+}
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+  SizeT outSize = *destLen;
+  SizeT inSize = *srcLen;
+  *srcLen = *destLen = 0;
+  for (;;)
+  {
+    SizeT inSizeCur = inSize, outSizeCur, dicPos;
+    ELzmaFinishMode curFinishMode;
+    SRes res;
+    if (p->dicPos == p->dicBufSize)
+      p->dicPos = 0;
+    dicPos = p->dicPos;
+    if (outSize > p->dicBufSize - dicPos)
+    {
+      outSizeCur = p->dicBufSize;
+      curFinishMode = LZMA_FINISH_ANY;
+    }
+    else
+    {
+      outSizeCur = dicPos + outSize;
+      curFinishMode = finishMode;
+    }
+
+    res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
+    src += inSizeCur;
+    inSize -= inSizeCur;
+    *srcLen += inSizeCur;
+    outSizeCur = p->dicPos - dicPos;
+    memcpy(dest, p->dic + dicPos, outSizeCur);
+    dest += outSizeCur;
+    outSize -= outSizeCur;
+    *destLen += outSizeCur;
+    if (res != 0)
+      return res;
+    if (outSizeCur == 0 || outSize == 0)
+      return SZ_OK;
+  }
+}
+
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->probs);
+  p->probs = 0;
+}
+
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->dic);
+  p->dic = 0;
+}
+
+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
+{
+  LzmaDec_FreeProbs(p, alloc);
+  LzmaDec_FreeDict(p, alloc);
+}
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
+{
+  UInt32 dicSize;
+  Byte d;
+
+  if (size < LZMA_PROPS_SIZE)
+    return SZ_ERROR_UNSUPPORTED;
+  else
+    dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
+
+  if (dicSize < LZMA_DIC_MIN)
+    dicSize = LZMA_DIC_MIN;
+  p->dicSize = dicSize;
+
+  d = data[0];
+  if (d >= (9 * 5 * 5))
+    return SZ_ERROR_UNSUPPORTED;
+
+  p->lc = d % 9;
+  d /= 9;
+  p->pb = d / 5;
+  p->lp = d % 5;
+
+  return SZ_OK;
+}
+
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
+{
+  UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
+  if (p->probs == 0 || numProbs != p->numProbs)
+  {
+    LzmaDec_FreeProbs(p, alloc);
+    p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
+    p->numProbs = numProbs;
+    if (p->probs == 0)
+      return SZ_ERROR_MEM;
+  }
+  return SZ_OK;
+}
+
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+  CLzmaProps propNew;
+  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+  p->prop = propNew;
+  return SZ_OK;
+}
+
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+  CLzmaProps propNew;
+  SizeT dicBufSize;
+  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+  dicBufSize = propNew.dicSize;
+  if (p->dic == 0 || dicBufSize != p->dicBufSize)
+  {
+    LzmaDec_FreeDict(p, alloc);
+    p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
+    if (p->dic == 0)
+    {
+      LzmaDec_FreeProbs(p, alloc);
+      return SZ_ERROR_MEM;
+    }
+  }
+  p->dicBufSize = dicBufSize;
+  p->prop = propNew;
+  return SZ_OK;
+}
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+    ELzmaStatus *status, ISzAlloc *alloc)
+{
+  CLzmaDec p;
+  SRes res;
+  SizeT inSize = *srcLen;
+  SizeT outSize = *destLen;
+  *srcLen = *destLen = 0;
+  if (inSize < RC_INIT_SIZE)
+    return SZ_ERROR_INPUT_EOF;
+
+  LzmaDec_Construct(&p);
+  res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
+  if (res != 0)
+    return res;
+  p.dic = dest;
+  p.dicBufSize = outSize;
+
+  LzmaDec_Init(&p);
+
+  *srcLen = inSize;
+  res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
+
+  if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
+    res = SZ_ERROR_INPUT_EOF;
+
+  (*destLen) = p.dicPos;
+  LzmaDec_FreeProbs(&p, alloc);
+  return res;
+}
diff --git a/grub-core/lib/LzmaEnc.c b/grub-core/lib/LzmaEnc.c
new file mode 100644 (file)
index 0000000..842d43a
--- /dev/null
@@ -0,0 +1,2355 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1999-2008 Igor Pavlov
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
+ * to adapt it to GRUB's requirement.
+ *
+ * See <http://www.7-zip.org>, for more information about LZMA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grub/lib/LzmaEnc.h>
+
+#include <grub/lib/LzFind.h>
+#ifdef COMPRESS_MF_MT
+#include <grub/lib/LzFindMt.h>
+#endif
+
+/* #define SHOW_STAT */
+/* #define SHOW_STAT2 */
+
+#ifdef SHOW_STAT
+static int ttt = 0;
+#endif
+
+#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
+
+#define kBlockSize (9 << 10)
+#define kUnpackBlockSize (1 << 18)
+#define kMatchArraySize (1 << 21)
+#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
+
+#define kNumMaxDirectBits (31)
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+#define kProbInitValue (kBitModelTotal >> 1)
+
+#define kNumMoveReducingBits 4
+#define kNumBitPriceShiftBits 4
+#define kBitPrice (1 << kNumBitPriceShiftBits)
+
+void LzmaEncProps_Init(CLzmaEncProps *p)
+{
+  p->level = 5;
+  p->dictSize = p->mc = 0;
+  p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
+  p->writeEndMark = 0;
+}
+
+void LzmaEncProps_Normalize(CLzmaEncProps *p)
+{
+  int level = p->level;
+  if (level < 0) level = 5;
+  p->level = level;
+  if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
+  if (p->lc < 0) p->lc = 3;
+  if (p->lp < 0) p->lp = 0;
+  if (p->pb < 0) p->pb = 2;
+  if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
+  if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
+  if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
+  if (p->numHashBytes < 0) p->numHashBytes = 4;
+  if (p->mc == 0)  p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
+  if (p->numThreads < 0) p->numThreads = ((p->btMode && p->algo) ? 2 : 1);
+}
+
+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
+{
+  CLzmaEncProps props = *props2;
+  LzmaEncProps_Normalize(&props);
+  return props.dictSize;
+}
+
+/* #define LZMA_LOG_BSR */
+/* Define it for Intel's CPU */
+
+
+#ifdef LZMA_LOG_BSR
+
+#define kDicLogSizeMaxCompress 30
+
+#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
+
+UInt32 GetPosSlot1(UInt32 pos)
+{
+  UInt32 res;
+  BSR2_RET(pos, res);
+  return res;
+}
+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
+
+#else
+
+#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
+
+void LzmaEnc_FastPosInit(Byte *g_FastPos)
+{
+  int c = 2, slotFast;
+  g_FastPos[0] = 0;
+  g_FastPos[1] = 1;
+
+  for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
+  {
+    UInt32 k = (1 << ((slotFast >> 1) - 1));
+    UInt32 j;
+    for (j = 0; j < k; j++, c++)
+      g_FastPos[c] = (Byte)slotFast;
+  }
+}
+
+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
+  (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
+  res = p->g_FastPos[pos >> i] + (i * 2); }
+/*
+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
+  p->g_FastPos[pos >> 6] + 12 : \
+  p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
+*/
+
+#define GetPosSlot1(pos) p->g_FastPos[pos]
+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
+
+#endif
+
+
+#define LZMA_NUM_REPS 4
+
+typedef unsigned CState;
+
+typedef struct _COptimal
+{
+  UInt32 price;
+
+  CState state;
+  int prev1IsChar;
+  int prev2;
+
+  UInt32 posPrev2;
+  UInt32 backPrev2;
+
+  UInt32 posPrev;
+  UInt32 backPrev;
+  UInt32 backs[LZMA_NUM_REPS];
+} COptimal;
+
+#define kNumOpts (1 << 12)
+
+#define kNumLenToPosStates 4
+#define kNumPosSlotBits 6
+#define kDicLogSizeMin 0
+#define kDicLogSizeMax 32
+#define kDistTableSizeMax (kDicLogSizeMax * 2)
+
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+#define kAlignMask (kAlignTableSize - 1)
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
+
+#define kNumFullDistances (1 << (kEndPosModelIndex / 2))
+
+#ifdef _LZMA_PROB32
+#define CLzmaProb UInt32
+#else
+#define CLzmaProb UInt16
+#endif
+
+#define LZMA_PB_MAX 4
+#define LZMA_LC_MAX 8
+#define LZMA_LP_MAX 4
+
+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
+
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
+
+#define LZMA_MATCH_LEN_MIN 2
+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
+
+#define kNumStates 12
+
+typedef struct
+{
+  CLzmaProb choice;
+  CLzmaProb choice2;
+  CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
+  CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
+  CLzmaProb high[kLenNumHighSymbols];
+} CLenEnc;
+
+typedef struct
+{
+  CLenEnc p;
+  UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
+  UInt32 tableSize;
+  UInt32 counters[LZMA_NUM_PB_STATES_MAX];
+} CLenPriceEnc;
+
+typedef struct _CRangeEnc
+{
+  UInt32 range;
+  Byte cache;
+  UInt64 low;
+  UInt64 cacheSize;
+  Byte *buf;
+  Byte *bufLim;
+  Byte *bufBase;
+  ISeqOutStream *outStream;
+  UInt64 processed;
+  SRes res;
+} CRangeEnc;
+
+typedef struct _CSeqInStreamBuf
+{
+  ISeqInStream funcTable;
+  const Byte *data;
+  SizeT rem;
+} CSeqInStreamBuf;
+
+static SRes MyRead(void *pp, void *data, size_t *size)
+{
+  size_t curSize = *size;
+  CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp;
+  if (p->rem < curSize)
+    curSize = p->rem;
+  memcpy(data, p->data, curSize);
+  p->rem -= curSize;
+  p->data += curSize;
+  *size = curSize;
+  return SZ_OK;
+}
+
+typedef struct
+{
+  CLzmaProb *litProbs;
+
+  CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
+  CLzmaProb isRep[kNumStates];
+  CLzmaProb isRepG0[kNumStates];
+  CLzmaProb isRepG1[kNumStates];
+  CLzmaProb isRepG2[kNumStates];
+  CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
+
+  CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
+  CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
+  CLzmaProb posAlignEncoder[1 << kNumAlignBits];
+
+  CLenPriceEnc lenEnc;
+  CLenPriceEnc repLenEnc;
+
+  UInt32 reps[LZMA_NUM_REPS];
+  UInt32 state;
+} CSaveState;
+
+typedef struct _CLzmaEnc
+{
+  IMatchFinder matchFinder;
+  void *matchFinderObj;
+
+  #ifdef COMPRESS_MF_MT
+  Bool mtMode;
+  CMatchFinderMt matchFinderMt;
+  #endif
+
+  CMatchFinder matchFinderBase;
+
+  #ifdef COMPRESS_MF_MT
+  Byte pad[128];
+  #endif
+
+  UInt32 optimumEndIndex;
+  UInt32 optimumCurrentIndex;
+
+  Bool longestMatchWasFound;
+  UInt32 longestMatchLength;
+  UInt32 numDistancePairs;
+
+  COptimal opt[kNumOpts];
+
+  #ifndef LZMA_LOG_BSR
+  Byte g_FastPos[1 << kNumLogBits];
+  #endif
+
+  UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+  UInt32 matchDistances[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
+  UInt32 numFastBytes;
+  UInt32 additionalOffset;
+  UInt32 reps[LZMA_NUM_REPS];
+  UInt32 state;
+
+  UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
+  UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
+  UInt32 alignPrices[kAlignTableSize];
+  UInt32 alignPriceCount;
+
+  UInt32 distTableSize;
+
+  unsigned lc, lp, pb;
+  unsigned lpMask, pbMask;
+
+  CLzmaProb *litProbs;
+
+  CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
+  CLzmaProb isRep[kNumStates];
+  CLzmaProb isRepG0[kNumStates];
+  CLzmaProb isRepG1[kNumStates];
+  CLzmaProb isRepG2[kNumStates];
+  CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
+
+  CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
+  CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
+  CLzmaProb posAlignEncoder[1 << kNumAlignBits];
+
+  CLenPriceEnc lenEnc;
+  CLenPriceEnc repLenEnc;
+
+  unsigned lclp;
+
+  Bool fastMode;
+
+  CRangeEnc rc;
+
+  Bool writeEndMark;
+  UInt64 nowPos64;
+  UInt32 matchPriceCount;
+  Bool finished;
+  Bool multiThread;
+
+  SRes result;
+  UInt32 dictSize;
+  UInt32 matchFinderCycles;
+
+  ISeqInStream *inStream;
+  CSeqInStreamBuf seqBufInStream;
+
+  CSaveState saveState;
+} CLzmaEnc;
+
+void LzmaEnc_SaveState(CLzmaEncHandle pp)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  CSaveState *dest = &p->saveState;
+  int i;
+  dest->lenEnc = p->lenEnc;
+  dest->repLenEnc = p->repLenEnc;
+  dest->state = p->state;
+
+  for (i = 0; i < kNumStates; i++)
+  {
+    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
+    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
+  }
+  for (i = 0; i < kNumLenToPosStates; i++)
+    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
+  memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
+  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
+  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
+  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
+  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
+  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
+  memcpy(dest->reps, p->reps, sizeof(p->reps));
+  memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
+}
+
+void LzmaEnc_RestoreState(CLzmaEncHandle pp)
+{
+  CLzmaEnc *dest = (CLzmaEnc *)pp;
+  const CSaveState *p = &dest->saveState;
+  int i;
+  dest->lenEnc = p->lenEnc;
+  dest->repLenEnc = p->repLenEnc;
+  dest->state = p->state;
+
+  for (i = 0; i < kNumStates; i++)
+  {
+    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
+    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
+  }
+  for (i = 0; i < kNumLenToPosStates; i++)
+    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
+  memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
+  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
+  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
+  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
+  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
+  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
+  memcpy(dest->reps, p->reps, sizeof(p->reps));
+  memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
+}
+
+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  CLzmaEncProps props = *props2;
+  LzmaEncProps_Normalize(&props);
+
+  if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
+      props.dictSize > (1U << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
+    return SZ_ERROR_PARAM;
+  p->dictSize = props.dictSize;
+  p->matchFinderCycles = props.mc;
+  {
+    unsigned fb = props.fb;
+    if (fb < 5)
+      fb = 5;
+    if (fb > LZMA_MATCH_LEN_MAX)
+      fb = LZMA_MATCH_LEN_MAX;
+    p->numFastBytes = fb;
+  }
+  p->lc = props.lc;
+  p->lp = props.lp;
+  p->pb = props.pb;
+  p->fastMode = (props.algo == 0);
+  p->matchFinderBase.btMode = props.btMode;
+  {
+    UInt32 numHashBytes = 4;
+    if (props.btMode)
+    {
+      if (props.numHashBytes < 2)
+        numHashBytes = 2;
+      else if (props.numHashBytes < 4)
+        numHashBytes = props.numHashBytes;
+    }
+    p->matchFinderBase.numHashBytes = numHashBytes;
+  }
+
+  p->matchFinderBase.cutValue = props.mc;
+
+  p->writeEndMark = props.writeEndMark;
+
+  #ifdef COMPRESS_MF_MT
+  /*
+  if (newMultiThread != _multiThread)
+  {
+    ReleaseMatchFinder();
+    _multiThread = newMultiThread;
+  }
+  */
+  p->multiThread = (props.numThreads > 1);
+  #endif
+
+  return SZ_OK;
+}
+
+static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4,  5,  6,   4, 5};
+static const int kMatchNextStates[kNumStates]   = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+static const int kRepNextStates[kNumStates]     = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+
+/*
+  void UpdateChar() { Index = kLiteralNextStates[Index]; }
+  void UpdateMatch() { Index = kMatchNextStates[Index]; }
+  void UpdateRep() { Index = kRepNextStates[Index]; }
+  void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
+*/
+
+#define IsCharState(s) ((s) < 7)
+
+
+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
+
+#define kInfinityPrice (1 << 30)
+
+static void RangeEnc_Construct(CRangeEnc *p)
+{
+  p->outStream = 0;
+  p->bufBase = 0;
+}
+
+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
+
+#define RC_BUF_SIZE (1 << 16)
+static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
+{
+  if (p->bufBase == 0)
+  {
+    p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
+    if (p->bufBase == 0)
+      return 0;
+    p->bufLim = p->bufBase + RC_BUF_SIZE;
+  }
+  return 1;
+}
+
+static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->bufBase);
+  p->bufBase = 0;
+}
+
+static void RangeEnc_Init(CRangeEnc *p)
+{
+  /* Stream.Init(); */
+  p->low = 0;
+  p->range = 0xFFFFFFFF;
+  p->cacheSize = 1;
+  p->cache = 0;
+
+  p->buf = p->bufBase;
+
+  p->processed = 0;
+  p->res = SZ_OK;
+}
+
+static void RangeEnc_FlushStream(CRangeEnc *p)
+{
+  size_t num;
+  if (p->res != SZ_OK)
+    return;
+  num = p->buf - p->bufBase;
+  if (num != p->outStream->Write(p->outStream, p->bufBase, num))
+    p->res = SZ_ERROR_WRITE;
+  p->processed += num;
+  p->buf = p->bufBase;
+}
+
+static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
+{
+  if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
+  {
+    Byte temp = p->cache;
+    do
+    {
+      Byte *buf = p->buf;
+      *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
+      p->buf = buf;
+      if (buf == p->bufLim)
+        RangeEnc_FlushStream(p);
+      temp = 0xFF;
+    }
+    while (--p->cacheSize != 0);
+    p->cache = (Byte)((UInt32)p->low >> 24);
+  }
+  p->cacheSize++;
+  p->low = (UInt32)p->low << 8;
+}
+
+static void RangeEnc_FlushData(CRangeEnc *p)
+{
+  int i;
+  for (i = 0; i < 5; i++)
+    RangeEnc_ShiftLow(p);
+}
+
+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
+{
+  do
+  {
+    p->range >>= 1;
+    p->low += p->range & (0 - ((value >> --numBits) & 1));
+    if (p->range < kTopValue)
+    {
+      p->range <<= 8;
+      RangeEnc_ShiftLow(p);
+    }
+  }
+  while (numBits != 0);
+}
+
+static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
+{
+  UInt32 ttt = *prob;
+  UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
+  if (symbol == 0)
+  {
+    p->range = newBound;
+    ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
+  }
+  else
+  {
+    p->low += newBound;
+    p->range -= newBound;
+    ttt -= ttt >> kNumMoveBits;
+  }
+  *prob = (CLzmaProb)ttt;
+  if (p->range < kTopValue)
+  {
+    p->range <<= 8;
+    RangeEnc_ShiftLow(p);
+  }
+}
+
+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
+{
+  symbol |= 0x100;
+  do
+  {
+    RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
+    symbol <<= 1;
+  }
+  while (symbol < 0x10000);
+}
+
+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
+{
+  UInt32 offs = 0x100;
+  symbol |= 0x100;
+  do
+  {
+    matchByte <<= 1;
+    RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
+    symbol <<= 1;
+    offs &= ~(matchByte ^ symbol);
+  }
+  while (symbol < 0x10000);
+}
+
+void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
+{
+  UInt32 i;
+  for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
+  {
+    const int kCyclesBits = kNumBitPriceShiftBits;
+    UInt32 w = i;
+    UInt32 bitCount = 0;
+    int j;
+    for (j = 0; j < kCyclesBits; j++)
+    {
+      w = w * w;
+      bitCount <<= 1;
+      while (w >= ((UInt32)1 << 16))
+      {
+        w >>= 1;
+        bitCount++;
+      }
+    }
+    ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
+  }
+}
+
+
+#define GET_PRICE(prob, symbol) \
+  p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
+
+#define GET_PRICEa(prob, symbol) \
+  ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
+
+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
+
+#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
+#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
+
+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
+{
+  UInt32 price = 0;
+  symbol |= 0x100;
+  do
+  {
+    price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
+    symbol <<= 1;
+  }
+  while (symbol < 0x10000);
+  return price;
+};
+
+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
+{
+  UInt32 price = 0;
+  UInt32 offs = 0x100;
+  symbol |= 0x100;
+  do
+  {
+    matchByte <<= 1;
+    price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);
+    symbol <<= 1;
+    offs &= ~(matchByte ^ symbol);
+  }
+  while (symbol < 0x10000);
+  return price;
+};
+
+
+static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
+{
+  UInt32 m = 1;
+  int i;
+  for (i = numBitLevels; i != 0 ;)
+  {
+    UInt32 bit;
+    i--;
+    bit = (symbol >> i) & 1;
+    RangeEnc_EncodeBit(rc, probs + m, bit);
+    m = (m << 1) | bit;
+  }
+};
+
+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
+{
+  UInt32 m = 1;
+  int i;
+  for (i = 0; i < numBitLevels; i++)
+  {
+    UInt32 bit = symbol & 1;
+    RangeEnc_EncodeBit(rc, probs + m, bit);
+    m = (m << 1) | bit;
+    symbol >>= 1;
+  }
+}
+
+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
+{
+  UInt32 price = 0;
+  symbol |= (1 << numBitLevels);
+  while (symbol != 1)
+  {
+    price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
+    symbol >>= 1;
+  }
+  return price;
+}
+
+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
+{
+  UInt32 price = 0;
+  UInt32 m = 1;
+  int i;
+  for (i = numBitLevels; i != 0; i--)
+  {
+    UInt32 bit = symbol & 1;
+    symbol >>= 1;
+    price += GET_PRICEa(probs[m], bit);
+    m = (m << 1) | bit;
+  }
+  return price;
+}
+
+
+static void LenEnc_Init(CLenEnc *p)
+{
+  unsigned i;
+  p->choice = p->choice2 = kProbInitValue;
+  for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
+    p->low[i] = kProbInitValue;
+  for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
+    p->mid[i] = kProbInitValue;
+  for (i = 0; i < kLenNumHighSymbols; i++)
+    p->high[i] = kProbInitValue;
+}
+
+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
+{
+  if (symbol < kLenNumLowSymbols)
+  {
+    RangeEnc_EncodeBit(rc, &p->choice, 0);
+    RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
+  }
+  else
+  {
+    RangeEnc_EncodeBit(rc, &p->choice, 1);
+    if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
+    {
+      RangeEnc_EncodeBit(rc, &p->choice2, 0);
+      RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
+    }
+    else
+    {
+      RangeEnc_EncodeBit(rc, &p->choice2, 1);
+      RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
+    }
+  }
+}
+
+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
+{
+  UInt32 a0 = GET_PRICE_0a(p->choice);
+  UInt32 a1 = GET_PRICE_1a(p->choice);
+  UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
+  UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
+  UInt32 i = 0;
+  for (i = 0; i < kLenNumLowSymbols; i++)
+  {
+    if (i >= numSymbols)
+      return;
+    prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
+  }
+  for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
+  {
+    if (i >= numSymbols)
+      return;
+    prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
+  }
+  for (; i < numSymbols; i++)
+    prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
+}
+
+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
+{
+  LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
+  p->counters[posState] = p->tableSize;
+}
+
+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
+{
+  UInt32 posState;
+  for (posState = 0; posState < numPosStates; posState++)
+    LenPriceEnc_UpdateTable(p, posState, ProbPrices);
+}
+
+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
+{
+  LenEnc_Encode(&p->p, rc, symbol, posState);
+  if (updatePrice)
+    if (--p->counters[posState] == 0)
+      LenPriceEnc_UpdateTable(p, posState, ProbPrices);
+}
+
+
+
+
+static void MovePos(CLzmaEnc *p, UInt32 num)
+{
+  #ifdef SHOW_STAT
+  ttt += num;
+  printf("\n MovePos %d", num);
+  #endif
+  if (num != 0)
+  {
+    p->additionalOffset += num;
+    p->matchFinder.Skip(p->matchFinderObj, num);
+  }
+}
+
+static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
+{
+  UInt32 lenRes = 0, numDistancePairs;
+  numDistancePairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matchDistances);
+  #ifdef SHOW_STAT
+  printf("\n i = %d numPairs = %d    ", ttt, numDistancePairs / 2);
+  if (ttt >= 61994)
+    ttt = ttt;
+
+  ttt++;
+  {
+    UInt32 i;
+  for (i = 0; i < numDistancePairs; i += 2)
+    printf("%2d %6d   | ", p->matchDistances[i], p->matchDistances[i + 1]);
+  }
+  #endif
+  if (numDistancePairs > 0)
+  {
+    lenRes = p->matchDistances[numDistancePairs - 2];
+    if (lenRes == p->numFastBytes)
+    {
+      UInt32 numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) + 1;
+      const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+      UInt32 distance = p->matchDistances[numDistancePairs - 1] + 1;
+      if (numAvail > LZMA_MATCH_LEN_MAX)
+        numAvail = LZMA_MATCH_LEN_MAX;
+
+      {
+        const Byte *pby2 = pby - distance;
+        for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
+      }
+    }
+  }
+  p->additionalOffset++;
+  *numDistancePairsRes = numDistancePairs;
+  return lenRes;
+}
+
+
+#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
+#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
+#define IsShortRep(p) ((p)->backPrev == 0)
+
+static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
+{
+  return
+    GET_PRICE_0(p->isRepG0[state]) +
+    GET_PRICE_0(p->isRep0Long[state][posState]);
+}
+
+static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
+{
+  UInt32 price;
+  if (repIndex == 0)
+  {
+    price = GET_PRICE_0(p->isRepG0[state]);
+    price += GET_PRICE_1(p->isRep0Long[state][posState]);
+  }
+  else
+  {
+    price = GET_PRICE_1(p->isRepG0[state]);
+    if (repIndex == 1)
+      price += GET_PRICE_0(p->isRepG1[state]);
+    else
+    {
+      price += GET_PRICE_1(p->isRepG1[state]);
+      price += GET_PRICE(p->isRepG2[state], repIndex - 2);
+    }
+  }
+  return price;
+}
+
+static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
+{
+  return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
+    GetPureRepPrice(p, repIndex, state, posState);
+}
+
+static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
+{
+  UInt32 posMem = p->opt[cur].posPrev;
+  UInt32 backMem = p->opt[cur].backPrev;
+  p->optimumEndIndex = cur;
+  do
+  {
+    if (p->opt[cur].prev1IsChar)
+    {
+      MakeAsChar(&p->opt[posMem])
+      p->opt[posMem].posPrev = posMem - 1;
+      if (p->opt[cur].prev2)
+      {
+        p->opt[posMem - 1].prev1IsChar = False;
+        p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
+        p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
+      }
+    }
+    {
+      UInt32 posPrev = posMem;
+      UInt32 backCur = backMem;
+
+      backMem = p->opt[posPrev].backPrev;
+      posMem = p->opt[posPrev].posPrev;
+
+      p->opt[posPrev].backPrev = backCur;
+      p->opt[posPrev].posPrev = cur;
+      cur = posPrev;
+    }
+  }
+  while (cur != 0);
+  *backRes = p->opt[0].backPrev;
+  p->optimumCurrentIndex  = p->opt[0].posPrev;
+  return p->optimumCurrentIndex;
+}
+
+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
+
+static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
+{
+  UInt32 numAvailableBytes, lenMain, numDistancePairs;
+  const Byte *data;
+  UInt32 reps[LZMA_NUM_REPS];
+  UInt32 repLens[LZMA_NUM_REPS];
+  UInt32 repMaxIndex, i;
+  UInt32 *matchDistances;
+  Byte currentByte, matchByte;
+  UInt32 posState;
+  UInt32 matchPrice, repMatchPrice;
+  UInt32 lenEnd;
+  UInt32 len;
+  UInt32 normalMatchPrice;
+  UInt32 cur;
+  if (p->optimumEndIndex != p->optimumCurrentIndex)
+  {
+    const COptimal *opt = &p->opt[p->optimumCurrentIndex];
+    UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
+    *backRes = opt->backPrev;
+    p->optimumCurrentIndex = opt->posPrev;
+    return lenRes;
+  }
+  p->optimumCurrentIndex = p->optimumEndIndex = 0;
+
+  numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+
+  if (!p->longestMatchWasFound)
+  {
+    lenMain = ReadMatchDistances(p, &numDistancePairs);
+  }
+  else
+  {
+    lenMain = p->longestMatchLength;
+    numDistancePairs = p->numDistancePairs;
+    p->longestMatchWasFound = False;
+  }
+
+  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+  if (numAvailableBytes < 2)
+  {
+    *backRes = (UInt32)(-1);
+    return 1;
+  }
+  if (numAvailableBytes > LZMA_MATCH_LEN_MAX)
+    numAvailableBytes = LZMA_MATCH_LEN_MAX;
+
+  repMaxIndex = 0;
+  for (i = 0; i < LZMA_NUM_REPS; i++)
+  {
+    UInt32 lenTest;
+    const Byte *data2;
+    reps[i] = p->reps[i];
+    data2 = data - (reps[i] + 1);
+    if (data[0] != data2[0] || data[1] != data2[1])
+    {
+      repLens[i] = 0;
+      continue;
+    }
+    for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++);
+    repLens[i] = lenTest;
+    if (lenTest > repLens[repMaxIndex])
+      repMaxIndex = i;
+  }
+  if (repLens[repMaxIndex] >= p->numFastBytes)
+  {
+    UInt32 lenRes;
+    *backRes = repMaxIndex;
+    lenRes = repLens[repMaxIndex];
+    MovePos(p, lenRes - 1);
+    return lenRes;
+  }
+
+  matchDistances = p->matchDistances;
+  if (lenMain >= p->numFastBytes)
+  {
+    *backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS;
+    MovePos(p, lenMain - 1);
+    return lenMain;
+  }
+  currentByte = *data;
+  matchByte = *(data - (reps[0] + 1));
+
+  if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
+  {
+    *backRes = (UInt32)-1;
+    return 1;
+  }
+
+  p->opt[0].state = (CState)p->state;
+
+  posState = (position & p->pbMask);
+
+  {
+    const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
+    p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
+        (!IsCharState(p->state) ?
+          LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) :
+          LitEnc_GetPrice(probs, currentByte, p->ProbPrices));
+  }
+
+  MakeAsChar(&p->opt[1]);
+
+  matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
+  repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
+
+  if (matchByte == currentByte)
+  {
+    UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
+    if (shortRepPrice < p->opt[1].price)
+    {
+      p->opt[1].price = shortRepPrice;
+      MakeAsShortRep(&p->opt[1]);
+    }
+  }
+  lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
+
+  if (lenEnd < 2)
+  {
+    *backRes = p->opt[1].backPrev;
+    return 1;
+  }
+
+  p->opt[1].posPrev = 0;
+  for (i = 0; i < LZMA_NUM_REPS; i++)
+    p->opt[0].backs[i] = reps[i];
+
+  len = lenEnd;
+  do
+    p->opt[len--].price = kInfinityPrice;
+  while (len >= 2);
+
+  for (i = 0; i < LZMA_NUM_REPS; i++)
+  {
+    UInt32 repLen = repLens[i];
+    UInt32 price;
+    if (repLen < 2)
+      continue;
+    price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
+    do
+    {
+      UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
+      COptimal *opt = &p->opt[repLen];
+      if (curAndLenPrice < opt->price)
+      {
+        opt->price = curAndLenPrice;
+        opt->posPrev = 0;
+        opt->backPrev = i;
+        opt->prev1IsChar = False;
+      }
+    }
+    while (--repLen >= 2);
+  }
+
+  normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
+
+  len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
+  if (len <= lenMain)
+  {
+    UInt32 offs = 0;
+    while (len > matchDistances[offs])
+      offs += 2;
+    for (; ; len++)
+    {
+      COptimal *opt;
+      UInt32 distance = matchDistances[offs + 1];
+
+      UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
+      UInt32 lenToPosState = GetLenToPosState(len);
+      if (distance < kNumFullDistances)
+        curAndLenPrice += p->distancesPrices[lenToPosState][distance];
+      else
+      {
+        UInt32 slot;
+        GetPosSlot2(distance, slot);
+        curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
+      }
+      opt = &p->opt[len];
+      if (curAndLenPrice < opt->price)
+      {
+        opt->price = curAndLenPrice;
+        opt->posPrev = 0;
+        opt->backPrev = distance + LZMA_NUM_REPS;
+        opt->prev1IsChar = False;
+      }
+      if (len == matchDistances[offs])
+      {
+        offs += 2;
+        if (offs == numDistancePairs)
+          break;
+      }
+    }
+  }
+
+  cur = 0;
+
+    #ifdef SHOW_STAT2
+    if (position >= 0)
+    {
+      unsigned i;
+      printf("\n pos = %4X", position);
+      for (i = cur; i <= lenEnd; i++)
+      printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);
+    }
+    #endif
+
+  for (;;)
+  {
+    UInt32 numAvailableBytesFull, newLen, numDistancePairs;
+    COptimal *curOpt;
+    UInt32 posPrev;
+    UInt32 state;
+    UInt32 curPrice;
+    Bool nextIsChar;
+    const Byte *data;
+    Byte currentByte, matchByte;
+    UInt32 posState;
+    UInt32 curAnd1Price;
+    COptimal *nextOpt;
+    UInt32 matchPrice, repMatchPrice;
+    UInt32 numAvailableBytes;
+    UInt32 startLen;
+
+    cur++;
+    if (cur == lenEnd)
+      return Backward(p, backRes, cur);
+
+    numAvailableBytesFull = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+    newLen = ReadMatchDistances(p, &numDistancePairs);
+    if (newLen >= p->numFastBytes)
+    {
+      p->numDistancePairs = numDistancePairs;
+      p->longestMatchLength = newLen;
+      p->longestMatchWasFound = True;
+      return Backward(p, backRes, cur);
+    }
+    position++;
+    curOpt = &p->opt[cur];
+    posPrev = curOpt->posPrev;
+    if (curOpt->prev1IsChar)
+    {
+      posPrev--;
+      if (curOpt->prev2)
+      {
+        state = p->opt[curOpt->posPrev2].state;
+        if (curOpt->backPrev2 < LZMA_NUM_REPS)
+          state = kRepNextStates[state];
+        else
+          state = kMatchNextStates[state];
+      }
+      else
+        state = p->opt[posPrev].state;
+      state = kLiteralNextStates[state];
+    }
+    else
+      state = p->opt[posPrev].state;
+    if (posPrev == cur - 1)
+    {
+      if (IsShortRep(curOpt))
+        state = kShortRepNextStates[state];
+      else
+        state = kLiteralNextStates[state];
+    }
+    else
+    {
+      UInt32 pos;
+      const COptimal *prevOpt;
+      if (curOpt->prev1IsChar && curOpt->prev2)
+      {
+        posPrev = curOpt->posPrev2;
+        pos = curOpt->backPrev2;
+        state = kRepNextStates[state];
+      }
+      else
+      {
+        pos = curOpt->backPrev;
+        if (pos < LZMA_NUM_REPS)
+          state = kRepNextStates[state];
+        else
+          state = kMatchNextStates[state];
+      }
+      prevOpt = &p->opt[posPrev];
+      if (pos < LZMA_NUM_REPS)
+      {
+        UInt32 i;
+        reps[0] = prevOpt->backs[pos];
+        for (i = 1; i <= pos; i++)
+          reps[i] = prevOpt->backs[i - 1];
+        for (; i < LZMA_NUM_REPS; i++)
+          reps[i] = prevOpt->backs[i];
+      }
+      else
+      {
+        UInt32 i;
+        reps[0] = (pos - LZMA_NUM_REPS);
+        for (i = 1; i < LZMA_NUM_REPS; i++)
+          reps[i] = prevOpt->backs[i - 1];
+      }
+    }
+    curOpt->state = (CState)state;
+
+    curOpt->backs[0] = reps[0];
+    curOpt->backs[1] = reps[1];
+    curOpt->backs[2] = reps[2];
+    curOpt->backs[3] = reps[3];
+
+    curPrice = curOpt->price;
+    nextIsChar = False;
+    data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+    currentByte = *data;
+    matchByte = *(data - (reps[0] + 1));
+
+    posState = (position & p->pbMask);
+
+    curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
+    {
+      const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
+      curAnd1Price +=
+        (!IsCharState(state) ?
+          LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) :
+          LitEnc_GetPrice(probs, currentByte, p->ProbPrices));
+    }
+
+    nextOpt = &p->opt[cur + 1];
+
+    if (curAnd1Price < nextOpt->price)
+    {
+      nextOpt->price = curAnd1Price;
+      nextOpt->posPrev = cur;
+      MakeAsChar(nextOpt);
+      nextIsChar = True;
+    }
+
+    matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
+    repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
+
+    if (matchByte == currentByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
+    {
+      UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
+      if (shortRepPrice <= nextOpt->price)
+      {
+        nextOpt->price = shortRepPrice;
+        nextOpt->posPrev = cur;
+        MakeAsShortRep(nextOpt);
+        nextIsChar = True;
+      }
+    }
+
+    {
+      UInt32 temp = kNumOpts - 1 - cur;
+      if (temp <  numAvailableBytesFull)
+        numAvailableBytesFull = temp;
+    }
+    numAvailableBytes = numAvailableBytesFull;
+
+    if (numAvailableBytes < 2)
+      continue;
+    if (numAvailableBytes > p->numFastBytes)
+      numAvailableBytes = p->numFastBytes;
+    if (!nextIsChar && matchByte != currentByte) /* speed optimization */
+    {
+      /* try Literal + rep0 */
+      UInt32 temp;
+      UInt32 lenTest2;
+      const Byte *data2 = data - (reps[0] + 1);
+      UInt32 limit = p->numFastBytes + 1;
+      if (limit > numAvailableBytesFull)
+        limit = numAvailableBytesFull;
+
+      for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
+      lenTest2 = temp - 1;
+      if (lenTest2 >= 2)
+      {
+        UInt32 state2 = kLiteralNextStates[state];
+        UInt32 posStateNext = (position + 1) & p->pbMask;
+        UInt32 nextRepMatchPrice = curAnd1Price +
+            GET_PRICE_1(p->isMatch[state2][posStateNext]) +
+            GET_PRICE_1(p->isRep[state2]);
+        /* for (; lenTest2 >= 2; lenTest2--) */
+        {
+          UInt32 curAndLenPrice;
+          COptimal *opt;
+          UInt32 offset = cur + 1 + lenTest2;
+          while (lenEnd < offset)
+            p->opt[++lenEnd].price = kInfinityPrice;
+          curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+          opt = &p->opt[offset];
+          if (curAndLenPrice < opt->price)
+          {
+            opt->price = curAndLenPrice;
+            opt->posPrev = cur + 1;
+            opt->backPrev = 0;
+            opt->prev1IsChar = True;
+            opt->prev2 = False;
+          }
+        }
+      }
+    }
+
+    startLen = 2; /* speed optimization */
+    {
+    UInt32 repIndex;
+    for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
+    {
+      UInt32 lenTest;
+      UInt32 lenTestTemp;
+      UInt32 price;
+      const Byte *data2 = data - (reps[repIndex] + 1);
+      if (data[0] != data2[0] || data[1] != data2[1])
+        continue;
+      for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++);
+      while (lenEnd < cur + lenTest)
+        p->opt[++lenEnd].price = kInfinityPrice;
+      lenTestTemp = lenTest;
+      price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
+      do
+      {
+        UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
+        COptimal *opt = &p->opt[cur + lenTest];
+        if (curAndLenPrice < opt->price)
+        {
+          opt->price = curAndLenPrice;
+          opt->posPrev = cur;
+          opt->backPrev = repIndex;
+          opt->prev1IsChar = False;
+        }
+      }
+      while (--lenTest >= 2);
+      lenTest = lenTestTemp;
+
+      if (repIndex == 0)
+        startLen = lenTest + 1;
+
+      /* if (_maxMode) */
+        {
+          UInt32 lenTest2 = lenTest + 1;
+          UInt32 limit = lenTest2 + p->numFastBytes;
+          UInt32 nextRepMatchPrice;
+          if (limit > numAvailableBytesFull)
+            limit = numAvailableBytesFull;
+          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
+          lenTest2 -= lenTest + 1;
+          if (lenTest2 >= 2)
+          {
+            UInt32 state2 = kRepNextStates[state];
+            UInt32 posStateNext = (position + lenTest) & p->pbMask;
+            UInt32 curAndLenCharPrice =
+                price + p->repLenEnc.prices[posState][lenTest - 2] +
+                GET_PRICE_0(p->isMatch[state2][posStateNext]) +
+                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
+                    data[lenTest], data2[lenTest], p->ProbPrices);
+            state2 = kLiteralNextStates[state2];
+            posStateNext = (position + lenTest + 1) & p->pbMask;
+            nextRepMatchPrice = curAndLenCharPrice +
+                GET_PRICE_1(p->isMatch[state2][posStateNext]) +
+                GET_PRICE_1(p->isRep[state2]);
+
+            /* for (; lenTest2 >= 2; lenTest2--) */
+            {
+              UInt32 curAndLenPrice;
+              COptimal *opt;
+              UInt32 offset = cur + lenTest + 1 + lenTest2;
+              while (lenEnd < offset)
+                p->opt[++lenEnd].price = kInfinityPrice;
+              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+              opt = &p->opt[offset];
+              if (curAndLenPrice < opt->price)
+              {
+                opt->price = curAndLenPrice;
+                opt->posPrev = cur + lenTest + 1;
+                opt->backPrev = 0;
+                opt->prev1IsChar = True;
+                opt->prev2 = True;
+                opt->posPrev2 = cur;
+                opt->backPrev2 = repIndex;
+              }
+            }
+          }
+        }
+    }
+    }
+    /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
+    if (newLen > numAvailableBytes)
+    {
+      newLen = numAvailableBytes;
+      for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2);
+      matchDistances[numDistancePairs] = newLen;
+      numDistancePairs += 2;
+    }
+    if (newLen >= startLen)
+    {
+      UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
+      UInt32 offs, curBack, posSlot;
+      UInt32 lenTest;
+      while (lenEnd < cur + newLen)
+        p->opt[++lenEnd].price = kInfinityPrice;
+
+      offs = 0;
+      while (startLen > matchDistances[offs])
+        offs += 2;
+      curBack = matchDistances[offs + 1];
+      GetPosSlot2(curBack, posSlot);
+      for (lenTest = /*2*/ startLen; ; lenTest++)
+      {
+        UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
+        UInt32 lenToPosState = GetLenToPosState(lenTest);
+        COptimal *opt;
+        if (curBack < kNumFullDistances)
+          curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
+        else
+          curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
+
+        opt = &p->opt[cur + lenTest];
+        if (curAndLenPrice < opt->price)
+        {
+          opt->price = curAndLenPrice;
+          opt->posPrev = cur;
+          opt->backPrev = curBack + LZMA_NUM_REPS;
+          opt->prev1IsChar = False;
+        }
+
+        if (/*_maxMode && */lenTest == matchDistances[offs])
+        {
+          /* Try Match + Literal + Rep0 */
+          const Byte *data2 = data - (curBack + 1);
+          UInt32 lenTest2 = lenTest + 1;
+          UInt32 limit = lenTest2 + p->numFastBytes;
+          UInt32 nextRepMatchPrice;
+          if (limit > numAvailableBytesFull)
+            limit = numAvailableBytesFull;
+          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
+          lenTest2 -= lenTest + 1;
+          if (lenTest2 >= 2)
+          {
+            UInt32 state2 = kMatchNextStates[state];
+            UInt32 posStateNext = (position + lenTest) & p->pbMask;
+            UInt32 curAndLenCharPrice = curAndLenPrice +
+                GET_PRICE_0(p->isMatch[state2][posStateNext]) +
+                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
+                    data[lenTest], data2[lenTest], p->ProbPrices);
+            state2 = kLiteralNextStates[state2];
+            posStateNext = (posStateNext + 1) & p->pbMask;
+            nextRepMatchPrice = curAndLenCharPrice +
+                GET_PRICE_1(p->isMatch[state2][posStateNext]) +
+                GET_PRICE_1(p->isRep[state2]);
+
+            /* for (; lenTest2 >= 2; lenTest2--) */
+            {
+              UInt32 offset = cur + lenTest + 1 + lenTest2;
+              UInt32 curAndLenPrice;
+              COptimal *opt;
+              while (lenEnd < offset)
+                p->opt[++lenEnd].price = kInfinityPrice;
+              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+              opt = &p->opt[offset];
+              if (curAndLenPrice < opt->price)
+              {
+                opt->price = curAndLenPrice;
+                opt->posPrev = cur + lenTest + 1;
+                opt->backPrev = 0;
+                opt->prev1IsChar = True;
+                opt->prev2 = True;
+                opt->posPrev2 = cur;
+                opt->backPrev2 = curBack + LZMA_NUM_REPS;
+              }
+            }
+          }
+          offs += 2;
+          if (offs == numDistancePairs)
+            break;
+          curBack = matchDistances[offs + 1];
+          if (curBack >= kNumFullDistances)
+            GetPosSlot2(curBack, posSlot);
+        }
+      }
+    }
+  }
+}
+
+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
+
+static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
+{
+  UInt32 numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+  UInt32 lenMain, numDistancePairs;
+  const Byte *data;
+  UInt32 repLens[LZMA_NUM_REPS];
+  UInt32 repMaxIndex, i;
+  UInt32 *matchDistances;
+  UInt32 backMain;
+
+  if (!p->longestMatchWasFound)
+  {
+    lenMain = ReadMatchDistances(p, &numDistancePairs);
+  }
+  else
+  {
+    lenMain = p->longestMatchLength;
+    numDistancePairs = p->numDistancePairs;
+    p->longestMatchWasFound = False;
+  }
+
+  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+  if (numAvailableBytes > LZMA_MATCH_LEN_MAX)
+    numAvailableBytes = LZMA_MATCH_LEN_MAX;
+  if (numAvailableBytes < 2)
+  {
+    *backRes = (UInt32)(-1);
+    return 1;
+  }
+
+  repMaxIndex = 0;
+
+  for (i = 0; i < LZMA_NUM_REPS; i++)
+  {
+    const Byte *data2 = data - (p->reps[i] + 1);
+    UInt32 len;
+    if (data[0] != data2[0] || data[1] != data2[1])
+    {
+      repLens[i] = 0;
+      continue;
+    }
+    for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++);
+    if (len >= p->numFastBytes)
+    {
+      *backRes = i;
+      MovePos(p, len - 1);
+      return len;
+    }
+    repLens[i] = len;
+    if (len > repLens[repMaxIndex])
+      repMaxIndex = i;
+  }
+  matchDistances = p->matchDistances;
+  if (lenMain >= p->numFastBytes)
+  {
+    *backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS;
+    MovePos(p, lenMain - 1);
+    return lenMain;
+  }
+
+  backMain = 0; /* for GCC */
+  if (lenMain >= 2)
+  {
+    backMain = matchDistances[numDistancePairs - 1];
+    while (numDistancePairs > 2 && lenMain == matchDistances[numDistancePairs - 4] + 1)
+    {
+      if (!ChangePair(matchDistances[numDistancePairs - 3], backMain))
+        break;
+      numDistancePairs -= 2;
+      lenMain = matchDistances[numDistancePairs - 2];
+      backMain = matchDistances[numDistancePairs - 1];
+    }
+    if (lenMain == 2 && backMain >= 0x80)
+      lenMain = 1;
+  }
+
+  if (repLens[repMaxIndex] >= 2)
+  {
+    if (repLens[repMaxIndex] + 1 >= lenMain ||
+        (repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1 << 9))) ||
+        (repLens[repMaxIndex] + 3 >= lenMain && (backMain > (1 << 15))))
+    {
+      UInt32 lenRes;
+      *backRes = repMaxIndex;
+      lenRes = repLens[repMaxIndex];
+      MovePos(p, lenRes - 1);
+      return lenRes;
+    }
+  }
+
+  if (lenMain >= 2 && numAvailableBytes > 2)
+  {
+    UInt32 i;
+    numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+    p->longestMatchLength = ReadMatchDistances(p, &p->numDistancePairs);
+    if (p->longestMatchLength >= 2)
+    {
+      UInt32 newDistance = matchDistances[p->numDistancePairs - 1];
+      if ((p->longestMatchLength >= lenMain && newDistance < backMain) ||
+          (p->longestMatchLength == lenMain + 1 && !ChangePair(backMain, newDistance)) ||
+          (p->longestMatchLength > lenMain + 1) ||
+          (p->longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(newDistance, backMain)))
+      {
+        p->longestMatchWasFound = True;
+        *backRes = (UInt32)(-1);
+        return 1;
+      }
+    }
+    data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+    for (i = 0; i < LZMA_NUM_REPS; i++)
+    {
+      UInt32 len;
+      const Byte *data2 = data - (p->reps[i] + 1);
+      if (data[1] != data2[1] || data[2] != data2[2])
+      {
+        repLens[i] = 0;
+        continue;
+      }
+      for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++);
+      if (len + 1 >= lenMain)
+      {
+        p->longestMatchWasFound = True;
+        *backRes = (UInt32)(-1);
+        return 1;
+      }
+    }
+    *backRes = backMain + LZMA_NUM_REPS;
+    MovePos(p, lenMain - 2);
+    return lenMain;
+  }
+  *backRes = (UInt32)(-1);
+  return 1;
+}
+
+static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
+{
+  UInt32 len;
+  RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
+  RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
+  p->state = kMatchNextStates[p->state];
+  len = LZMA_MATCH_LEN_MIN;
+  LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+  RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
+  RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
+  RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
+}
+
+static SRes CheckErrors(CLzmaEnc *p)
+{
+  if (p->result != SZ_OK)
+    return p->result;
+  if (p->rc.res != SZ_OK)
+    p->result = SZ_ERROR_WRITE;
+  if (p->matchFinderBase.result != SZ_OK)
+    p->result = SZ_ERROR_READ;
+  if (p->result != SZ_OK)
+    p->finished = True;
+  return p->result;
+}
+
+static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
+{
+  /* ReleaseMFStream(); */
+  p->finished = True;
+  if (p->writeEndMark)
+    WriteEndMarker(p, nowPos & p->pbMask);
+  RangeEnc_FlushData(&p->rc);
+  RangeEnc_FlushStream(&p->rc);
+  return CheckErrors(p);
+}
+
+static void FillAlignPrices(CLzmaEnc *p)
+{
+  UInt32 i;
+  for (i = 0; i < kAlignTableSize; i++)
+    p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
+  p->alignPriceCount = 0;
+}
+
+static void FillDistancesPrices(CLzmaEnc *p)
+{
+  UInt32 tempPrices[kNumFullDistances];
+  UInt32 i, lenToPosState;
+  for (i = kStartPosModelIndex; i < kNumFullDistances; i++)
+  {
+    UInt32 posSlot = GetPosSlot1(i);
+    UInt32 footerBits = ((posSlot >> 1) - 1);
+    UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+    tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);
+  }
+
+  for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
+  {
+    UInt32 posSlot;
+    const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
+    UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
+    for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
+      posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
+    for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
+      posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
+
+    {
+      UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
+      UInt32 i;
+      for (i = 0; i < kStartPosModelIndex; i++)
+        distancesPrices[i] = posSlotPrices[i];
+      for (; i < kNumFullDistances; i++)
+        distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];
+    }
+  }
+  p->matchPriceCount = 0;
+}
+
+void LzmaEnc_Construct(CLzmaEnc *p)
+{
+  RangeEnc_Construct(&p->rc);
+  MatchFinder_Construct(&p->matchFinderBase);
+  #ifdef COMPRESS_MF_MT
+  MatchFinderMt_Construct(&p->matchFinderMt);
+  p->matchFinderMt.MatchFinder = &p->matchFinderBase;
+  #endif
+
+  {
+    CLzmaEncProps props;
+    LzmaEncProps_Init(&props);
+    LzmaEnc_SetProps(p, &props);
+  }
+
+  #ifndef LZMA_LOG_BSR
+  LzmaEnc_FastPosInit(p->g_FastPos);
+  #endif
+
+  LzmaEnc_InitPriceTables(p->ProbPrices);
+  p->litProbs = 0;
+  p->saveState.litProbs = 0;
+}
+
+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
+{
+  void *p;
+  p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
+  if (p != 0)
+    LzmaEnc_Construct((CLzmaEnc *)p);
+  return p;
+}
+
+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->litProbs);
+  alloc->Free(alloc, p->saveState.litProbs);
+  p->litProbs = 0;
+  p->saveState.litProbs = 0;
+}
+
+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  #ifdef COMPRESS_MF_MT
+  MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
+  #endif
+  MatchFinder_Free(&p->matchFinderBase, allocBig);
+  LzmaEnc_FreeLits(p, alloc);
+  RangeEnc_Free(&p->rc, alloc);
+}
+
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
+  alloc->Free(alloc, p);
+}
+
+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
+{
+  UInt32 nowPos32, startPos32;
+  if (p->inStream != 0)
+  {
+    p->matchFinderBase.stream = p->inStream;
+    p->matchFinder.Init(p->matchFinderObj);
+    p->inStream = 0;
+  }
+
+  if (p->finished)
+    return p->result;
+  RINOK(CheckErrors(p));
+
+  nowPos32 = (UInt32)p->nowPos64;
+  startPos32 = nowPos32;
+
+  if (p->nowPos64 == 0)
+  {
+    UInt32 numDistancePairs;
+    Byte curByte;
+    if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
+      return Flush(p, nowPos32);
+    ReadMatchDistances(p, &numDistancePairs);
+    RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
+    p->state = kLiteralNextStates[p->state];
+    curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
+    LitEnc_Encode(&p->rc, p->litProbs, curByte);
+    p->additionalOffset--;
+    nowPos32++;
+  }
+
+  if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
+  for (;;)
+  {
+    UInt32 pos, len, posState;
+
+    if (p->fastMode)
+      len = GetOptimumFast(p, &pos);
+    else
+      len = GetOptimum(p, nowPos32, &pos);
+
+    #ifdef SHOW_STAT2
+    printf("\n pos = %4X,   len = %d   pos = %d", nowPos32, len, pos);
+    #endif
+
+    posState = nowPos32 & p->pbMask;
+    if (len == 1 && pos == 0xFFFFFFFF)
+    {
+      Byte curByte;
+      CLzmaProb *probs;
+      const Byte *data;
+
+      RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
+      data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
+      curByte = *data;
+      probs = LIT_PROBS(nowPos32, *(data - 1));
+      if (IsCharState(p->state))
+        LitEnc_Encode(&p->rc, probs, curByte);
+      else
+        LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
+      p->state = kLiteralNextStates[p->state];
+    }
+    else
+    {
+      RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
+      if (pos < LZMA_NUM_REPS)
+      {
+        RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
+        if (pos == 0)
+        {
+          RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
+          RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
+        }
+        else
+        {
+          UInt32 distance = p->reps[pos];
+          RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
+          if (pos == 1)
+            RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
+          else
+          {
+            RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
+            RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
+            if (pos == 3)
+              p->reps[3] = p->reps[2];
+            p->reps[2] = p->reps[1];
+          }
+          p->reps[1] = p->reps[0];
+          p->reps[0] = distance;
+        }
+        if (len == 1)
+          p->state = kShortRepNextStates[p->state];
+        else
+        {
+          LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+          p->state = kRepNextStates[p->state];
+        }
+      }
+      else
+      {
+        UInt32 posSlot;
+        RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
+        p->state = kMatchNextStates[p->state];
+        LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+        pos -= LZMA_NUM_REPS;
+        GetPosSlot(pos, posSlot);
+        RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
+
+        if (posSlot >= kStartPosModelIndex)
+        {
+          UInt32 footerBits = ((posSlot >> 1) - 1);
+          UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+          UInt32 posReduced = pos - base;
+
+          if (posSlot < kEndPosModelIndex)
+            RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
+          else
+          {
+            RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+            RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
+            p->alignPriceCount++;
+          }
+        }
+        p->reps[3] = p->reps[2];
+        p->reps[2] = p->reps[1];
+        p->reps[1] = p->reps[0];
+        p->reps[0] = pos;
+        p->matchPriceCount++;
+      }
+    }
+    p->additionalOffset -= len;
+    nowPos32 += len;
+    if (p->additionalOffset == 0)
+    {
+      UInt32 processed;
+      if (!p->fastMode)
+      {
+        if (p->matchPriceCount >= (1 << 7))
+          FillDistancesPrices(p);
+        if (p->alignPriceCount >= kAlignTableSize)
+          FillAlignPrices(p);
+      }
+      if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
+        break;
+      processed = nowPos32 - startPos32;
+      if (useLimits)
+      {
+        if (processed + kNumOpts + 300 >= maxUnpackSize ||
+            RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
+          break;
+      }
+      else if (processed >= (1 << 15))
+      {
+        p->nowPos64 += nowPos32 - startPos32;
+        return CheckErrors(p);
+      }
+    }
+  }
+  p->nowPos64 += nowPos32 - startPos32;
+  return Flush(p, nowPos32);
+}
+
+#define kBigHashDicLimit ((UInt32)1 << 24)
+
+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  UInt32 beforeSize = kNumOpts;
+  Bool btMode;
+  if (!RangeEnc_Alloc(&p->rc, alloc))
+    return SZ_ERROR_MEM;
+  btMode = (p->matchFinderBase.btMode != 0);
+  #ifdef COMPRESS_MF_MT
+  p->mtMode = (p->multiThread && !p->fastMode && btMode);
+  #endif
+
+  {
+    unsigned lclp = p->lc + p->lp;
+    if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
+    {
+      LzmaEnc_FreeLits(p, alloc);
+      p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
+      p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
+      if (p->litProbs == 0 || p->saveState.litProbs == 0)
+      {
+        LzmaEnc_FreeLits(p, alloc);
+        return SZ_ERROR_MEM;
+      }
+      p->lclp = lclp;
+    }
+  }
+
+  p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
+
+  if (beforeSize + p->dictSize < keepWindowSize)
+    beforeSize = keepWindowSize - p->dictSize;
+
+  #ifdef COMPRESS_MF_MT
+  if (p->mtMode)
+  {
+    RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
+    p->matchFinderObj = &p->matchFinderMt;
+    MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
+  }
+  else
+  #endif
+  {
+    if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
+      return SZ_ERROR_MEM;
+    p->matchFinderObj = &p->matchFinderBase;
+    MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
+  }
+  return SZ_OK;
+}
+
+void LzmaEnc_Init(CLzmaEnc *p)
+{
+  UInt32 i;
+  p->state = 0;
+  for(i = 0 ; i < LZMA_NUM_REPS; i++)
+    p->reps[i] = 0;
+
+  RangeEnc_Init(&p->rc);
+
+
+  for (i = 0; i < kNumStates; i++)
+  {
+    UInt32 j;
+    for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
+    {
+      p->isMatch[i][j] = kProbInitValue;
+      p->isRep0Long[i][j] = kProbInitValue;
+    }
+    p->isRep[i] = kProbInitValue;
+    p->isRepG0[i] = kProbInitValue;
+    p->isRepG1[i] = kProbInitValue;
+    p->isRepG2[i] = kProbInitValue;
+  }
+
+  {
+    UInt32 num = 0x300 << (p->lp + p->lc);
+    for (i = 0; i < num; i++)
+      p->litProbs[i] = kProbInitValue;
+  }
+
+  {
+    for (i = 0; i < kNumLenToPosStates; i++)
+    {
+      CLzmaProb *probs = p->posSlotEncoder[i];
+      UInt32 j;
+      for (j = 0; j < (1 << kNumPosSlotBits); j++)
+        probs[j] = kProbInitValue;
+    }
+  }
+  {
+    for(i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+      p->posEncoders[i] = kProbInitValue;
+  }
+
+  LenEnc_Init(&p->lenEnc.p);
+  LenEnc_Init(&p->repLenEnc.p);
+
+  for (i = 0; i < (1 << kNumAlignBits); i++)
+    p->posAlignEncoder[i] = kProbInitValue;
+
+  p->longestMatchWasFound = False;
+  p->optimumEndIndex = 0;
+  p->optimumCurrentIndex = 0;
+  p->additionalOffset = 0;
+
+  p->pbMask = (1 << p->pb) - 1;
+  p->lpMask = (1 << p->lp) - 1;
+}
+
+void LzmaEnc_InitPrices(CLzmaEnc *p)
+{
+  if (!p->fastMode)
+  {
+    FillDistancesPrices(p);
+    FillAlignPrices(p);
+  }
+
+  p->lenEnc.tableSize =
+  p->repLenEnc.tableSize =
+      p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
+  LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
+  LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
+}
+
+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  UInt32 i;
+  for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
+    if (p->dictSize <= ((UInt32)1 << i))
+      break;
+  p->distTableSize = i * 2;
+
+  p->finished = False;
+  p->result = SZ_OK;
+  RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
+  LzmaEnc_Init(p);
+  LzmaEnc_InitPrices(p);
+  p->nowPos64 = 0;
+  return SZ_OK;
+}
+
+static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream,
+    ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  p->inStream = inStream;
+  p->rc.outStream = outStream;
+  return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
+}
+
+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
+    ISeqInStream *inStream, UInt32 keepWindowSize,
+    ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  p->inStream = inStream;
+  return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
+}
+
+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
+{
+  p->seqBufInStream.funcTable.Read = MyRead;
+  p->seqBufInStream.data = src;
+  p->seqBufInStream.rem = srcLen;
+}
+
+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
+    UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  LzmaEnc_SetInputBuf(p, src, srcLen);
+  p->inStream = &p->seqBufInStream.funcTable;
+  return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
+}
+
+void LzmaEnc_Finish(CLzmaEncHandle pp)
+{
+  #ifdef COMPRESS_MF_MT
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  if (p->mtMode)
+    MatchFinderMt_ReleaseStream(&p->matchFinderMt);
+  #else
+  (void)pp;
+  #endif
+}
+
+typedef struct _CSeqOutStreamBuf
+{
+  ISeqOutStream funcTable;
+  Byte *data;
+  SizeT rem;
+  Bool overflow;
+} CSeqOutStreamBuf;
+
+static size_t MyWrite(void *pp, const void *data, size_t size)
+{
+  CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
+  if (p->rem < size)
+  {
+    size = p->rem;
+    p->overflow = True;
+  }
+  memcpy(p->data, data, size);
+  p->rem -= size;
+  p->data += size;
+  return size;
+}
+
+
+UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
+{
+  const CLzmaEnc *p = (CLzmaEnc *)pp;
+  return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+}
+
+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
+{
+  const CLzmaEnc *p = (CLzmaEnc *)pp;
+  return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
+}
+
+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
+    Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  UInt64 nowPos64;
+  SRes res;
+  CSeqOutStreamBuf outStream;
+
+  outStream.funcTable.Write = MyWrite;
+  outStream.data = dest;
+  outStream.rem = *destLen;
+  outStream.overflow = False;
+
+  p->writeEndMark = False;
+  p->finished = False;
+  p->result = SZ_OK;
+
+  if (reInit)
+    LzmaEnc_Init(p);
+  LzmaEnc_InitPrices(p);
+  nowPos64 = p->nowPos64;
+  RangeEnc_Init(&p->rc);
+  p->rc.outStream = &outStream.funcTable;
+
+  res = LzmaEnc_CodeOneBlock(pp, True, desiredPackSize, *unpackSize);
+
+  *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
+  *destLen -= outStream.rem;
+  if (outStream.overflow)
+    return SZ_ERROR_OUTPUT_EOF;
+
+  return res;
+}
+
+SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
+    ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  SRes res = SZ_OK;
+
+  #ifdef COMPRESS_MF_MT
+  Byte allocaDummy[0x300];
+  int i = 0;
+  for (i = 0; i < 16; i++)
+    allocaDummy[i] = (Byte)i;
+  #endif
+
+  RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig));
+
+  for (;;)
+  {
+    res = LzmaEnc_CodeOneBlock(pp, False, 0, 0);
+    if (res != SZ_OK || p->finished != 0)
+      break;
+    if (progress != 0)
+    {
+      res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
+      if (res != SZ_OK)
+      {
+        res = SZ_ERROR_PROGRESS;
+        break;
+      }
+    }
+  }
+  LzmaEnc_Finish(pp);
+  return res;
+}
+
+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  int i;
+  UInt32 dictSize = p->dictSize;
+  if (*size < LZMA_PROPS_SIZE)
+    return SZ_ERROR_PARAM;
+  *size = LZMA_PROPS_SIZE;
+  props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
+
+  for (i = 11; i <= 30; i++)
+  {
+    if (dictSize <= ((UInt32)2 << i))
+    {
+      dictSize = (2 << i);
+      break;
+    }
+    if (dictSize <= ((UInt32)3 << i))
+    {
+      dictSize = (3 << i);
+      break;
+    }
+  }
+
+  for (i = 0; i < 4; i++)
+    props[1 + i] = (Byte)(dictSize >> (8 * i));
+  return SZ_OK;
+}
+
+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  SRes res;
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+
+  CSeqOutStreamBuf outStream;
+
+  LzmaEnc_SetInputBuf(p, src, srcLen);
+
+  outStream.funcTable.Write = MyWrite;
+  outStream.data = dest;
+  outStream.rem = *destLen;
+  outStream.overflow = False;
+
+  p->writeEndMark = writeEndMark;
+  res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable,
+      progress, alloc, allocBig);
+
+  *destLen -= outStream.rem;
+  if (outStream.overflow)
+    return SZ_ERROR_OUTPUT_EOF;
+  return res;
+}
+
+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
+    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+  CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
+  SRes res;
+  if (p == 0)
+    return SZ_ERROR_MEM;
+
+  res = LzmaEnc_SetProps(p, props);
+  if (res == SZ_OK)
+  {
+    res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
+    if (res == SZ_OK)
+      res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
+          writeEndMark, progress, alloc, allocBig);
+  }
+
+  LzmaEnc_Destroy(p, alloc, allocBig);
+  return res;
+}
diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c
new file mode 100644 (file)
index 0000000..6a7bb8b
--- /dev/null
@@ -0,0 +1,403 @@
+/* arg.c - argument parser */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/term.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+
+/* Built-in parser for default options.  */
+#define SHORT_ARG_HELP -100
+#define SHORT_ARG_USAGE        -101
+
+static const struct grub_arg_option help_options[] =
+  {
+    {"help", SHORT_ARG_HELP, 0,
+     N_("Display this help and exit."), 0, ARG_TYPE_NONE},
+    {"usage", SHORT_ARG_USAGE, 0,
+     N_("Display the usage of this command and exit."), 0, ARG_TYPE_NONE},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static struct grub_arg_option *
+find_short (const struct grub_arg_option *options, char c)
+{
+  struct grub_arg_option *found = 0;
+  auto struct grub_arg_option *fnd_short (const struct grub_arg_option *opt);
+
+  struct grub_arg_option *fnd_short (const struct grub_arg_option *opt)
+    {
+      while (opt->doc)
+       {
+         if (opt->shortarg == c)
+           return (struct grub_arg_option *) opt;
+         opt++;
+       }
+      return 0;
+    }
+
+  if (options)
+    found = fnd_short (options);
+
+  if (! found)
+    {
+      switch (c)
+       {
+       case 'h':
+         found = (struct grub_arg_option *) help_options;
+         break;
+
+       case 'u':
+         found = (struct grub_arg_option *) (help_options + 1);
+         break;
+
+       default:
+         break;
+       }
+    }
+
+  return found;
+}
+
+static struct grub_arg_option *
+find_long (const struct grub_arg_option *options, const char *s, int len)
+{
+  struct grub_arg_option *found = 0;
+  auto struct grub_arg_option *fnd_long (const struct grub_arg_option *opt);
+
+  struct grub_arg_option *fnd_long (const struct grub_arg_option *opt)
+    {
+      while (opt->doc)
+       {
+         if (opt->longarg && ! grub_strncmp (opt->longarg, s, len) &&
+             opt->longarg[len] == '\0')
+           return (struct grub_arg_option *) opt;
+         opt++;
+       }
+      return 0;
+    }
+
+  if (options)
+    found = fnd_long (options);
+
+  if (! found)
+    found = fnd_long (help_options);
+
+  return found;
+}
+
+static void
+show_usage (grub_extcmd_t cmd)
+{
+  grub_printf ("%s %s %s\n", _("Usage:"), cmd->cmd->name, _(cmd->cmd->summary));
+}
+
+void
+grub_arg_show_help (grub_extcmd_t cmd)
+{
+  auto void showargs (const struct grub_arg_option *opt);
+  int h_is_used = 0;
+  int u_is_used = 0;
+
+  auto void showargs (const struct grub_arg_option *opt)
+    {
+      for (; opt->doc; opt++)
+       {
+         int spacing = 20;
+
+         if (opt->shortarg && grub_isgraph (opt->shortarg))
+           grub_printf ("-%c%c ", opt->shortarg, opt->longarg ? ',':' ');
+         else if (opt->shortarg == SHORT_ARG_HELP && ! h_is_used)
+           grub_printf ("-h, ");
+         else if (opt->shortarg == SHORT_ARG_USAGE && ! u_is_used)
+           grub_printf ("-u, ");
+         else
+           grub_printf ("    ");
+
+         if (opt->longarg)
+           {
+             grub_printf ("--%s", opt->longarg);
+             spacing -= grub_strlen (opt->longarg) + 2;
+
+             if (opt->arg)
+               {
+                 grub_printf ("=%s", opt->arg);
+                 spacing -= grub_strlen (opt->arg) + 1;
+               }
+           }
+
+         const char *doc = _(opt->doc);
+         for (;;)
+           {
+             while (spacing-- > 0)
+               grub_putchar (' ');
+
+             while (*doc && *doc != '\n')
+               grub_putchar (*doc++);
+             grub_putchar ('\n');
+
+             if (! *doc)
+               break;
+             doc++;
+             spacing = 4 + 20;
+           }
+
+         switch (opt->shortarg)
+           {
+           case 'h':
+             h_is_used = 1;
+             break;
+
+           case 'u':
+             u_is_used = 1;
+             break;
+
+           default:
+             break;
+           }
+       }
+    }
+
+  show_usage (cmd);
+  grub_printf ("%s\n\n", _(cmd->cmd->description));
+  if (cmd->options)
+    showargs (cmd->options);
+  showargs (help_options);
+#if 0
+  grub_printf ("\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
+#endif
+}
+
+
+static int
+parse_option (grub_extcmd_t cmd, int key, char *arg, struct grub_arg_list *usr)
+{
+  switch (key)
+    {
+    case SHORT_ARG_HELP:
+      grub_arg_show_help (cmd);
+      return -1;
+
+    case SHORT_ARG_USAGE:
+      show_usage (cmd);
+      return -1;
+
+    default:
+      {
+       int found = -1;
+       int i = 0;
+       const struct grub_arg_option *opt = cmd->options;
+
+       while (opt->doc)
+         {
+           if (opt->shortarg && key == opt->shortarg)
+             {
+               found = i;
+               break;
+             }
+           opt++;
+           i++;
+         }
+
+       if (found == -1)
+         return -1;
+
+       usr[found].set = 1;
+       usr[found].arg = arg;
+      }
+    }
+
+  return 0;
+}
+
+int
+grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv,
+               struct grub_arg_list *usr, char ***args, int *argnum)
+{
+  int curarg;
+  int arglen;
+  int complete = 0;
+  char **argl = 0;
+  int num = 0;
+  auto grub_err_t add_arg (char *s);
+
+  grub_err_t add_arg (char *s)
+    {
+      argl = grub_realloc (argl, (++num) * sizeof (char *));
+      if (! argl)
+       return grub_errno;
+      argl[num - 1] = s;
+      return 0;
+    }
+
+
+  for (curarg = 0; curarg < argc; curarg++)
+    {
+      char *arg = argv[curarg];
+      struct grub_arg_option *opt;
+      char *option = 0;
+
+      /* No option is used.  */
+      if (arg[0] != '-' || grub_strlen (arg) == 1)
+       {
+         if (add_arg (arg) != 0)
+           goto fail;
+
+         continue;
+       }
+
+      /* One or more short options.  */
+      if (arg[1] != '-')
+       {
+         char *curshort = arg + 1;
+
+         while (1)
+           {
+             opt = find_short (cmd->options, *curshort);
+             if (! opt)
+               {
+                 grub_error (GRUB_ERR_BAD_ARGUMENT,
+                             "unknown argument `-%c'", *curshort);
+                 goto fail;
+               }
+
+             curshort++;
+
+             /* Parse all arguments here except the last one because
+                it can have an argument value.  */
+             if (*curshort)
+               {
+                 if (parse_option (cmd, opt->shortarg, 0, usr) || grub_errno)
+                   goto fail;
+               }
+             else
+               {
+                 if (opt->type != ARG_TYPE_NONE)
+                   {
+                     if (curarg + 1 < argc)
+                       {
+                         char *nextarg = argv[curarg + 1];
+                         if (!(opt->flags & GRUB_ARG_OPTION_OPTIONAL)
+                             || (grub_strlen (nextarg) < 2 || nextarg[0] != '-'))
+                           option = argv[++curarg];
+                       }
+                   }
+                 break;
+               }
+           }
+
+       }
+      else /* The argument starts with "--".  */
+       {
+         /* If the argument "--" is used just pass the other
+            arguments.  */
+         if (grub_strlen (arg) == 2)
+           {
+             for (curarg++; curarg < argc; curarg++)
+               if (add_arg (argv[curarg]) != 0)
+                 goto fail;
+             break;
+           }
+
+         option = grub_strchr (arg, '=');
+         if (option) {
+           arglen = option - arg - 2;
+           option++;
+         } else
+           arglen = grub_strlen (arg) - 2;
+
+         opt = find_long (cmd->options, arg + 2, arglen);
+         if (! opt)
+           {
+             grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown argument `%s'", arg);
+             goto fail;
+           }
+       }
+
+      if (! (opt->type == ARG_TYPE_NONE
+            || (! option && (opt->flags & GRUB_ARG_OPTION_OPTIONAL))))
+       {
+         if (! option)
+           {
+             grub_error (GRUB_ERR_BAD_ARGUMENT,
+                         "missing mandatory option for `%s'", opt->longarg);
+             goto fail;
+           }
+
+         switch (opt->type)
+           {
+           case ARG_TYPE_NONE:
+             /* This will never happen.  */
+             break;
+
+           case ARG_TYPE_STRING:
+                 /* No need to do anything.  */
+             break;
+
+           case ARG_TYPE_INT:
+             {
+               char *tail;
+
+               grub_strtoull (option, &tail, 0);
+               if (tail == 0 || tail == option || *tail != '\0' || grub_errno)
+                 {
+                   grub_error (GRUB_ERR_BAD_ARGUMENT,
+                               "the argument `%s' requires an integer",
+                               arg);
+
+                   goto fail;
+                 }
+               break;
+             }
+
+           case ARG_TYPE_DEVICE:
+           case ARG_TYPE_DIR:
+           case ARG_TYPE_FILE:
+           case ARG_TYPE_PATHNAME:
+             /* XXX: Not implemented.  */
+             break;
+           }
+         if (parse_option (cmd, opt->shortarg, option, usr) || grub_errno)
+           goto fail;
+       }
+      else
+       {
+         if (option)
+           {
+             grub_error (GRUB_ERR_BAD_ARGUMENT,
+                         "a value was assigned to the argument `%s' while it "
+                         "doesn't require an argument", arg);
+             goto fail;
+           }
+
+         if (parse_option (cmd, opt->shortarg, 0, usr) || grub_errno)
+           goto fail;
+       }
+    }
+
+  complete = 1;
+
+  *args = argl;
+  *argnum = num;
+
+ fail:
+  return complete;
+}
diff --git a/grub-core/lib/charset.c b/grub-core/lib/charset.c
new file mode 100644 (file)
index 0000000..f2e1b03
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
+   bytes (if SRCSIZE is -1, it is ignored) in length to a UTF-16 string.
+   Return the number of characters converted. DEST must be able to hold
+   at least DESTSIZE characters. If an invalid sequence is found, return -1.
+   If SRCEND is not NULL, then *SRCEND is set to the next byte after the
+   last byte used in SRC.  */
+
+#include <grub/charset.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+grub_ssize_t
+grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
+                   const grub_uint8_t *src, grub_size_t srcsize,
+                   const grub_uint8_t **srcend)
+{
+  grub_uint16_t *p = dest;
+  int count = 0;
+  grub_uint32_t code = 0;
+
+  if (srcend)
+    *srcend = src;
+
+  while (srcsize && destsize)
+    {
+      grub_uint32_t c = *src++;
+      if (srcsize != (grub_size_t)-1)
+       srcsize--;
+      if (count)
+       {
+         if ((c & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT)
+           {
+             /* invalid */
+             return -1;
+           }
+         else
+           {
+             code <<= 6;
+             code |= (c & GRUB_UINT8_6_TRAILINGBITS);
+             count--;
+           }
+       }
+      else
+       {
+         if (c == 0)
+           break;
+
+         if ((c & GRUB_UINT8_1_LEADINGBIT) == 0)
+           code = c;
+         else if ((c & GRUB_UINT8_3_LEADINGBITS) == GRUB_UINT8_2_LEADINGBITS)
+           {
+             count = 1;
+             code = c & GRUB_UINT8_5_TRAILINGBITS;
+           }
+         else if ((c & GRUB_UINT8_4_LEADINGBITS) == GRUB_UINT8_3_LEADINGBITS)
+           {
+             count = 2;
+             code = c & GRUB_UINT8_4_TRAILINGBITS;
+           }
+         else if ((c & GRUB_UINT8_5_LEADINGBITS) == GRUB_UINT8_4_LEADINGBITS)
+           {
+             count = 3;
+             code = c & GRUB_UINT8_3_TRAILINGBITS;
+           }
+         else if ((c & GRUB_UINT8_6_LEADINGBITS) == GRUB_UINT8_5_LEADINGBITS)
+           {
+             count = 4;
+             code = c & GRUB_UINT8_2_TRAILINGBITS;
+           }
+         else if ((c & GRUB_UINT8_7_LEADINGBITS) == GRUB_UINT8_6_LEADINGBITS)
+           {
+             count = 5;
+             code = c & GRUB_UINT8_1_TRAILINGBIT;
+           }
+         else
+           return -1;
+       }
+
+      if (count == 0)
+       {
+         if (destsize < 2 && code >= GRUB_UCS2_LIMIT)
+           break;
+         if (code >= GRUB_UCS2_LIMIT)
+           {
+             *p++ = GRUB_UTF16_UPPER_SURROGATE (code);
+             *p++ = GRUB_UTF16_LOWER_SURROGATE (code);
+             destsize -= 2;
+           }
+         else
+           {
+             *p++ = code;
+             destsize--;
+           }
+       }
+    }
+
+  if (srcend)
+    *srcend = src;
+  return p - dest;
+}
+
+/* Convert UCS-4 to UTF-8.  */
+char *
+grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size)
+{
+  grub_size_t remaining;
+  grub_uint32_t *ptr;
+  grub_size_t cnt = 0;
+  grub_uint8_t *ret, *dest;
+
+  remaining = size;
+  ptr = src;
+  while (remaining--)
+    {
+      grub_uint32_t code = *ptr++;
+      
+      if (code <= 0x007F)
+       cnt++;
+      else if (code <= 0x07FF)
+       cnt += 2;
+      else if ((code >= 0xDC00 && code <= 0xDFFF)
+              || (code >= 0xD800 && code <= 0xDBFF))
+       /* No surrogates in UCS-4... */
+       cnt++;
+      else
+       cnt += 3;
+    }
+  cnt++;
+
+  ret = grub_malloc (cnt);
+  if (!ret)
+    return 0;
+
+  dest = ret;
+  remaining = size;
+  ptr = src;
+  while (remaining--)
+    {
+      grub_uint32_t code = *ptr++;
+
+      if (code <= 0x007F)
+       *dest++ = code;
+      else if (code <= 0x07FF)
+       {
+         *dest++ = (code >> 6) | 0xC0;
+         *dest++ = (code & 0x3F) | 0x80;
+       }
+      else if ((code >= 0xDC00 && code <= 0xDFFF)
+              || (code >= 0xD800 && code <= 0xDBFF))
+       {
+         /* No surrogates in UCS-4... */
+         *dest++ = '?';
+       }
+      else
+       {
+         *dest++ = (code >> 12) | 0xE0;
+         *dest++ = ((code >> 6) & 0x3F) | 0x80;
+         *dest++ = (code & 0x3F) | 0x80;
+       }
+    }
+  *dest = 0;
+
+  return (char *) ret;
+}
+
+int
+grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize)
+{
+  grub_uint32_t code = 0;
+  int count = 0;
+
+  while (srcsize)
+    {
+      grub_uint32_t c = *src++;
+      if (srcsize != (grub_size_t)-1)
+       srcsize--;
+      if (count)
+       {
+         if ((c & 0xc0) != 0x80)
+           {
+             /* invalid */
+             return 0;
+           }
+         else
+           {
+             code <<= 6;
+             code |= (c & 0x3f);
+             count--;
+           }
+       }
+      else
+       {
+         if (c == 0)
+           break;
+
+         if ((c & 0x80) == 0x00)
+           code = c;
+         else if ((c & 0xe0) == 0xc0)
+           {
+             count = 1;
+             code = c & 0x1f;
+           }
+         else if ((c & 0xf0) == 0xe0)
+           {
+             count = 2;
+             code = c & 0x0f;
+           }
+         else if ((c & 0xf8) == 0xf0)
+           {
+             count = 3;
+             code = c & 0x07;
+           }
+         else if ((c & 0xfc) == 0xf8)
+           {
+             count = 4;
+             code = c & 0x03;
+           }
+         else if ((c & 0xfe) == 0xfc)
+           {
+             count = 5;
+             code = c & 0x01;
+           }
+         else
+           return 0;
+       }
+    }
+
+  return 1;
+}
+
+int
+grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
+                       grub_uint32_t **last_position)
+{
+  grub_size_t msg_len = grub_strlen (msg);
+
+  *unicode_msg = grub_malloc (grub_strlen (msg) * sizeof (grub_uint32_t));
+  if (!*unicode_msg)
+    {
+      grub_printf ("utf8_to_ucs4 ERROR1: %s", msg);
+      return -1;
+    }
+
+  msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len,
+                             (grub_uint8_t *) msg, -1, 0);
+
+  *last_position = *unicode_msg + msg_len;
+
+  return msg_len;
+}
diff --git a/grub-core/lib/cmos_datetime.c b/grub-core/lib/cmos_datetime.c
new file mode 100644 (file)
index 0000000..8db60b4
--- /dev/null
@@ -0,0 +1,155 @@
+/* kern/cmos_datetime.c - CMOS datetime function.
+ *
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/datetime.h>
+#include <grub/cmos.h>
+
+grub_err_t
+grub_get_datetime (struct grub_datetime *datetime)
+{
+  int is_bcd, is_12hour;
+  grub_uint8_t value, flag;
+
+  flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B);
+
+  is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY);
+
+  value = grub_cmos_read (GRUB_CMOS_INDEX_YEAR);
+  if (is_bcd)
+    value = grub_bcd_to_num (value);
+
+  datetime->year = value;
+  datetime->year += (value < 80) ? 2000 : 1900;
+
+  value = grub_cmos_read (GRUB_CMOS_INDEX_MONTH);
+  if (is_bcd)
+    value = grub_bcd_to_num (value);
+
+  datetime->month = value;
+
+  value = grub_cmos_read (GRUB_CMOS_INDEX_DAY_OF_MONTH);
+  if (is_bcd)
+    value = grub_bcd_to_num (value);
+
+  datetime->day = value;
+
+  is_12hour = ! (flag & GRUB_CMOS_STATUS_B_24HOUR);
+
+  value = grub_cmos_read (GRUB_CMOS_INDEX_HOUR);
+  if (is_12hour)
+    {
+      is_12hour = (value & 0x80);
+
+      value &= 0x7F;
+      value--;
+    }
+
+  if (is_bcd)
+    value = grub_bcd_to_num (value);
+
+  if (is_12hour)
+    value += 12;
+
+  datetime->hour = value;
+
+  value = grub_cmos_read (GRUB_CMOS_INDEX_MINUTE);
+  if (is_bcd)
+    value = grub_bcd_to_num (value);
+
+  datetime->minute = value;
+
+  value = grub_cmos_read (GRUB_CMOS_INDEX_SECOND);
+  if (is_bcd)
+    value = grub_bcd_to_num (value);
+
+  datetime->second = value;
+
+  return 0;
+}
+
+grub_err_t
+grub_set_datetime (struct grub_datetime *datetime)
+{
+  int is_bcd, is_12hour;
+  grub_uint8_t value, flag;
+
+  flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B);
+
+  is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY);
+
+  value = ((datetime->year >= 2000) ? datetime->year - 2000 :
+           datetime->year - 1900);
+
+  if (is_bcd)
+    value = grub_num_to_bcd (value);
+
+  grub_cmos_write (GRUB_CMOS_INDEX_YEAR, value);
+
+  value = datetime->month;
+
+  if (is_bcd)
+    value = grub_num_to_bcd (value);
+
+  grub_cmos_write (GRUB_CMOS_INDEX_MONTH, value);
+
+  value = datetime->day;
+
+  if (is_bcd)
+    value = grub_num_to_bcd (value);
+
+  grub_cmos_write (GRUB_CMOS_INDEX_DAY_OF_MONTH, value);
+
+  value = datetime->hour;
+
+  is_12hour = (! (flag & GRUB_CMOS_STATUS_B_24HOUR));
+
+  if (is_12hour)
+    {
+      value++;
+
+      if (value > 12)
+        value -= 12;
+      else
+        is_12hour = 0;
+    }
+
+  if (is_bcd)
+    value = grub_num_to_bcd (value);
+
+  if (is_12hour)
+    value |= 0x80;
+
+  grub_cmos_write (GRUB_CMOS_INDEX_HOUR, value);
+
+  value = datetime->minute;
+
+  if (is_bcd)
+    value = grub_num_to_bcd (value);
+
+  grub_cmos_write (GRUB_CMOS_INDEX_MINUTE, value);
+
+  value = datetime->second;
+
+  if (is_bcd)
+    value = grub_num_to_bcd (value);
+
+  grub_cmos_write (GRUB_CMOS_INDEX_SECOND, value);
+
+  return 0;
+}
diff --git a/grub-core/lib/crc.c b/grub-core/lib/crc.c
new file mode 100644 (file)
index 0000000..bc0d8aa
--- /dev/null
@@ -0,0 +1,75 @@
+/* crc.c - crc function  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/lib/crc.h>
+
+static grub_uint32_t crc32_table [256];
+
+static void
+init_crc32_table (void)
+{
+  auto grub_uint32_t reflect (grub_uint32_t ref, int len);
+  grub_uint32_t reflect (grub_uint32_t ref, int len)
+    {
+      grub_uint32_t result = 0;
+      int i;
+
+      for (i = 1; i <= len; i++)
+        {
+          if (ref & 1)
+            result |= 1 << (len - i);
+          ref >>= 1;
+        }
+
+      return result;
+    }
+
+  grub_uint32_t polynomial = 0x04c11db7;
+  int i, j;
+
+  for(i = 0; i < 256; i++)
+    {
+      crc32_table[i] = reflect(i, 8) << 24;
+      for (j = 0; j < 8; j++)
+        crc32_table[i] = (crc32_table[i] << 1) ^
+            (crc32_table[i] & (1 << 31) ? polynomial : 0);
+      crc32_table[i] = reflect(crc32_table[i], 32);
+    }
+}
+
+grub_uint32_t
+grub_getcrc32 (grub_uint32_t crc, void *buf, int size)
+{
+  int i;
+  grub_uint8_t *data = buf;
+
+  if (! crc32_table[1])
+    init_crc32_table ();
+
+  crc^= 0xffffffff;
+
+  for (i = 0; i < size; i++)
+    {
+      crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ *data];
+      data++;
+    }
+
+  return crc ^ 0xffffffff;
+}
diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c
new file mode 100644 (file)
index 0000000..d11f099
--- /dev/null
@@ -0,0 +1,453 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
+ *                2007, 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/crypto.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/term.h>
+
+struct grub_crypto_hmac_handle
+{
+  const struct gcry_md_spec *md;
+  void *ctx;
+  void *opad;
+};
+
+static gcry_cipher_spec_t *grub_ciphers = NULL;
+static gcry_md_spec_t *grub_digests = NULL;
+
+void (*grub_crypto_autoload_hook) (const char *name) = NULL;
+
+/* Based on libgcrypt-1.4.4/src/misc.c.  */
+void
+grub_burn_stack (grub_size_t size)
+{
+  char buf[64];
+
+  grub_memset (buf, 0, sizeof (buf));
+  if (size > sizeof (buf))
+    grub_burn_stack (size - sizeof (buf));
+}
+
+
+void 
+grub_cipher_register (gcry_cipher_spec_t *cipher)
+{
+  cipher->next = grub_ciphers;
+  grub_ciphers = cipher;
+}
+
+void
+grub_cipher_unregister (gcry_cipher_spec_t *cipher)
+{
+  gcry_cipher_spec_t **ciph;
+  for (ciph = &grub_ciphers; *ciph; ciph = &((*ciph)->next))
+    if (*ciph == cipher)
+      {
+       *ciph = (*ciph)->next;
+       break;
+      }
+}
+
+void 
+grub_md_register (gcry_md_spec_t *digest)
+{
+  digest->next = grub_digests;
+  grub_digests = digest;
+}
+
+void 
+grub_md_unregister (gcry_md_spec_t *cipher)
+{
+  gcry_md_spec_t **ciph;
+  for (ciph = &grub_digests; *ciph; ciph = &((*ciph)->next))
+    if (*ciph == cipher)
+      {
+       *ciph = (*ciph)->next;
+       break;
+      }
+}
+
+void
+grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in,
+                 grub_size_t inlen)
+{
+  grub_uint8_t ctx[hash->contextsize];
+  hash->init (&ctx);
+  hash->write (&ctx, in, inlen);
+  hash->final (&ctx);
+  grub_memcpy (out, hash->read (&ctx), hash->mdlen);
+}
+
+const gcry_md_spec_t *
+grub_crypto_lookup_md_by_name (const char *name)
+{
+  const gcry_md_spec_t *md;
+  int first = 1;
+  while (1)
+    {
+      for (md = grub_digests; md; md = md->next)
+       if (grub_strcasecmp (name, md->name) == 0)
+         return md;
+      if (grub_crypto_autoload_hook && first)
+       grub_crypto_autoload_hook (name);
+      else
+       return NULL;
+      first = 0;
+    }
+}
+
+const gcry_cipher_spec_t *
+grub_crypto_lookup_cipher_by_name (const char *name)
+{
+  const gcry_cipher_spec_t *ciph;
+  int first = 1;
+  while (1)
+    {
+      for (ciph = grub_ciphers; ciph; ciph = ciph->next)
+       {
+         const char **alias;
+         if (grub_strcasecmp (name, ciph->name) == 0)
+           return ciph;
+         if (!ciph->aliases)
+           continue;
+         for (alias = ciph->aliases; *alias; alias++)
+           if (grub_strcasecmp (name, *alias) == 0)
+             return ciph;
+       }
+      if (grub_crypto_autoload_hook && first)
+       grub_crypto_autoload_hook (name);
+      else
+       return NULL;
+      first = 0;
+    }
+}
+
+
+grub_crypto_cipher_handle_t
+grub_crypto_cipher_open (const struct gcry_cipher_spec *cipher)
+{
+  grub_crypto_cipher_handle_t ret;
+  ret = grub_malloc (sizeof (*ret) + cipher->contextsize);
+  if (!ret)
+    return NULL;
+  ret->cipher = cipher;
+  return ret;
+}
+
+gcry_err_code_t
+grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher,
+                           const unsigned char *key,
+                           unsigned keylen)
+{
+  return cipher->cipher->setkey (cipher->ctx, key, keylen);
+}
+
+
+void
+grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher)
+{
+  grub_free (cipher);
+}
+
+
+void
+grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size)
+{
+  const grub_uint8_t *in1ptr = in1, *in2ptr = in2;
+  grub_uint8_t *outptr = out;
+  while (size--)
+    {
+      *outptr = *in1ptr ^ *in2ptr;
+      in1ptr++;
+      in2ptr++;
+      outptr++;
+    }
+}
+
+gcry_err_code_t
+grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
+                        void *out, void *in, grub_size_t size)
+{
+  grub_uint8_t *inptr, *outptr, *end;
+  if (!cipher->cipher->decrypt)
+    return GPG_ERR_NOT_SUPPORTED;
+  if (size % cipher->cipher->blocksize != 0)
+    return GPG_ERR_INV_ARG;
+  end = (grub_uint8_t *) in + size;
+  for (inptr = in, outptr = out; inptr < end;
+       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
+    cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
+  return GPG_ERR_NO_ERROR;
+}
+
+gcry_err_code_t
+grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher,
+                        void *out, void *in, grub_size_t size)
+{
+  grub_uint8_t *inptr, *outptr, *end;
+  if (!cipher->cipher->encrypt)
+    return GPG_ERR_NOT_SUPPORTED;
+  if (size % cipher->cipher->blocksize != 0)
+    return GPG_ERR_INV_ARG;
+  end = (grub_uint8_t *) in + size;
+  for (inptr = in, outptr = out; inptr < end;
+       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
+    cipher->cipher->encrypt (cipher->ctx, outptr, inptr);
+  return GPG_ERR_NO_ERROR;
+}
+
+gcry_err_code_t
+grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher,
+                        void *out, void *in, grub_size_t size,
+                        void *iv_in)
+{
+  grub_uint8_t *inptr, *outptr, *end;
+  void *iv;
+  if (!cipher->cipher->decrypt)
+    return GPG_ERR_NOT_SUPPORTED;
+  if (size % cipher->cipher->blocksize != 0)
+    return GPG_ERR_INV_ARG;
+  end = (grub_uint8_t *) in + size;
+  iv = iv_in;
+  for (inptr = in, outptr = out; inptr < end;
+       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
+    {
+      grub_crypto_xor (outptr, inptr, iv, cipher->cipher->blocksize);
+      cipher->cipher->encrypt (cipher->ctx, outptr, outptr);
+      iv = outptr;
+    }
+  grub_memcpy (iv_in, iv, cipher->cipher->blocksize);
+  return GPG_ERR_NO_ERROR;
+}
+
+gcry_err_code_t
+grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher,
+                        void *out, void *in, grub_size_t size,
+                        void *iv)
+{
+  grub_uint8_t *inptr, *outptr, *end;
+  grub_uint8_t ivt[cipher->cipher->blocksize];
+  if (!cipher->cipher->decrypt)
+    return GPG_ERR_NOT_SUPPORTED;
+  if (size % cipher->cipher->blocksize != 0)
+    return GPG_ERR_INV_ARG;
+  end = (grub_uint8_t *) in + size;
+  for (inptr = in, outptr = out; inptr < end;
+       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
+    {
+      grub_memcpy (ivt, inptr, cipher->cipher->blocksize);
+      cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
+      grub_crypto_xor (outptr, outptr, iv, cipher->cipher->blocksize);
+      grub_memcpy (iv, ivt, cipher->cipher->blocksize);
+    }
+  return GPG_ERR_NO_ERROR;
+}
+
+/* Based on gcry/cipher/md.c.  */
+struct grub_crypto_hmac_handle *
+grub_crypto_hmac_init (const struct gcry_md_spec *md,
+                      const void *key, grub_size_t keylen)
+{
+  grub_uint8_t *helpkey = NULL;
+  grub_uint8_t *ipad = NULL, *opad = NULL;
+  void *ctx = NULL;
+  struct grub_crypto_hmac_handle *ret = NULL;
+  unsigned i;
+
+  if (md->mdlen > md->blocksize)
+    return NULL;
+
+  ctx = grub_malloc (md->contextsize);
+  if (!ctx)
+    goto err;
+
+  if ( keylen > md->blocksize ) 
+    {
+      helpkey = grub_malloc (md->mdlen);
+      if (!helpkey)
+       goto err;
+      grub_crypto_hash (md, helpkey, key, keylen);
+
+      key = helpkey;
+      keylen = md->mdlen;
+    }
+
+  ipad = grub_zalloc (md->blocksize);
+  if (!ipad)
+    goto err;
+
+  opad = grub_zalloc (md->blocksize);
+  if (!opad)
+    goto err;
+
+  grub_memcpy ( ipad, key, keylen );
+  grub_memcpy ( opad, key, keylen );
+  for (i=0; i < md->blocksize; i++ ) 
+    {
+      ipad[i] ^= 0x36;
+      opad[i] ^= 0x5c;
+    }
+  grub_free (helpkey);
+  helpkey = NULL;
+
+  md->init (ctx);
+
+  md->write (ctx, ipad, md->blocksize); /* inner pad */
+  grub_memset (ipad, 0, md->blocksize);
+  grub_free (ipad);
+  ipad = NULL;
+
+  ret = grub_malloc (sizeof (*ret));
+  if (!ret)
+    goto err;
+
+  ret->md = md;
+  ret->ctx = ctx;
+  ret->opad = opad;
+
+  return ret;
+
+ err:
+  grub_free (helpkey);
+  grub_free (ctx);
+  grub_free (ipad);
+  grub_free (opad);
+  return NULL;
+}
+
+void
+grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd, void *data,
+                       grub_size_t datalen)
+{
+  hnd->md->write (hnd->ctx, data, datalen);
+}
+
+gcry_err_code_t
+grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out)
+{
+  grub_uint8_t *p;
+  grub_uint8_t *ctx2;
+
+  ctx2 = grub_malloc (hnd->md->contextsize);
+  if (!ctx2)
+    return GPG_ERR_OUT_OF_MEMORY;
+
+  hnd->md->final (hnd->ctx);
+  hnd->md->read (hnd->ctx);
+  p = hnd->md->read (hnd->ctx);
+
+  hnd->md->init (ctx2);
+  hnd->md->write (ctx2, hnd->opad, hnd->md->blocksize);
+  hnd->md->write (ctx2, p, hnd->md->mdlen);
+  hnd->md->final (ctx2);
+  grub_memset (hnd->opad, 0, hnd->md->blocksize);
+  grub_free (hnd->opad);
+  grub_memset (hnd->ctx, 0, hnd->md->contextsize);
+  grub_free (hnd->ctx);
+
+  grub_memcpy (out, hnd->md->read (ctx2), hnd->md->mdlen);
+  grub_memset (ctx2, 0, hnd->md->contextsize);
+  grub_free (ctx2);
+
+  grub_memset (hnd, 0, sizeof (*hnd));
+  grub_free (hnd);
+
+  return GPG_ERR_NO_ERROR;
+}
+
+gcry_err_code_t
+grub_crypto_hmac_buffer (const struct gcry_md_spec *md,
+                        const void *key, grub_size_t keylen,
+                        void *data, grub_size_t datalen, void *out)
+{
+  struct grub_crypto_hmac_handle *hnd;
+
+  hnd = grub_crypto_hmac_init (md, key, keylen);
+  if (!hnd)
+    return GPG_ERR_OUT_OF_MEMORY;
+
+  grub_crypto_hmac_write (hnd, data, datalen);
+  return grub_crypto_hmac_fini (hnd, out);
+}
+
+
+grub_err_t
+grub_crypto_gcry_error (gcry_err_code_t in)
+{
+  if (in == GPG_ERR_NO_ERROR)
+    return GRUB_ERR_NONE;
+  return GRUB_ACCESS_DENIED;
+}
+
+int
+grub_crypto_memcmp (const void *a, const void *b, grub_size_t n)
+{
+  register grub_size_t counter = 0;
+  const grub_uint8_t *pa, *pb;
+
+  for (pa = a, pb = b; n; pa++, pb++, n--)
+    {
+      if (*pa != *pb)
+       counter++;
+    }
+
+  return !!counter;
+}
+
+#ifndef GRUB_MKPASSWD
+int
+grub_password_get (char buf[], unsigned buf_size)
+{
+  unsigned cur_len = 0;
+  int key;
+
+  while (1)
+    {
+      key = GRUB_TERM_ASCII_CHAR (grub_getkey ()); 
+      if (key == '\n' || key == '\r')
+       break;
+
+      if (key == '\e')
+       {
+         cur_len = 0;
+         break;
+       }
+
+      if (key == '\b')
+       {
+         cur_len--;
+         continue;
+       }
+
+      if (!grub_isprint (key))
+       continue;
+
+      if (cur_len + 2 < buf_size)
+       buf[cur_len++] = key;
+    }
+
+  grub_memset (buf + cur_len, 0, buf_size - cur_len);
+
+  grub_putchar ('\n');
+  grub_refresh ();
+
+  return (key != '\e');
+}
+#endif
diff --git a/grub-core/lib/efi/datetime.c b/grub-core/lib/efi/datetime.c
new file mode 100644 (file)
index 0000000..0a91c34
--- /dev/null
@@ -0,0 +1,79 @@
+/* kern/efi/datetime.c - efi datetime function.
+ *
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/symbol.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/datetime.h>
+
+grub_err_t
+grub_get_datetime (struct grub_datetime *datetime)
+{
+  grub_efi_status_t status;
+  struct grub_efi_time efi_time;
+
+  status = efi_call_2 (grub_efi_system_table->runtime_services->get_time,
+                       &efi_time, 0);
+
+  if (status)
+    return grub_error (GRUB_ERR_INVALID_COMMAND,
+                       "can\'t get datetime using efi");
+  else
+    {
+      datetime->year = efi_time.year;
+      datetime->month = efi_time.month;
+      datetime->day = efi_time.day;
+      datetime->hour = efi_time.hour;
+      datetime->minute = efi_time.minute;
+      datetime->second = efi_time.second;
+    }
+
+  return 0;
+}
+
+grub_err_t
+grub_set_datetime (struct grub_datetime *datetime)
+{
+  grub_efi_status_t status;
+  struct grub_efi_time efi_time;
+
+  status = efi_call_2 (grub_efi_system_table->runtime_services->get_time,
+                       &efi_time, 0);
+
+  if (status)
+    return grub_error (GRUB_ERR_INVALID_COMMAND,
+                       "can\'t get datetime using efi");
+
+  efi_time.year = datetime->year;
+  efi_time.month = datetime->month;
+  efi_time.day = datetime->day;
+  efi_time.hour = datetime->hour;
+  efi_time.minute = datetime->minute;
+  efi_time.second = datetime->second;
+
+  status = efi_call_1 (grub_efi_system_table->runtime_services->set_time,
+                       &efi_time);
+
+  if (status)
+    return grub_error (GRUB_ERR_INVALID_COMMAND,
+                       "can\'t set datetime using efi");
+
+  return 0;
+}
diff --git a/grub-core/lib/envblk.c b/grub-core/lib/envblk.c
new file mode 100644 (file)
index 0000000..311927b
--- /dev/null
@@ -0,0 +1,296 @@
+/* envblk.c - Common functions for environment block.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/lib/envblk.h>
+
+grub_envblk_t
+grub_envblk_open (char *buf, grub_size_t size)
+{
+  grub_envblk_t envblk;
+
+  if (size < sizeof (GRUB_ENVBLK_SIGNATURE)
+      || grub_memcmp (buf, GRUB_ENVBLK_SIGNATURE,
+                      sizeof (GRUB_ENVBLK_SIGNATURE) - 1))
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block");
+      return 0;
+    }
+
+  envblk = grub_malloc (sizeof (*envblk));
+  if (envblk)
+    {
+      envblk->buf = buf;
+      envblk->size = size;
+    }
+
+  return envblk;
+}
+
+void
+grub_envblk_close (grub_envblk_t envblk)
+{
+  grub_free (envblk->buf);
+  grub_free (envblk);
+}
+
+static int
+escaped_value_len (const char *value)
+{
+  int n = 0;
+  char *p;
+
+  for (p = (char *) value; *p; p++)
+    {
+      if (*p == '\\' || *p == '\n')
+        n += 2;
+      else
+        n++;
+    }
+
+  return n;
+}
+
+static char *
+find_next_line (char *p, const char *pend)
+{
+  while (p < pend)
+    {
+      if (*p == '\\')
+        p += 2;
+      else if (*p == '\n')
+        break;
+      else
+        p++;
+    }
+
+  return p + 1;
+}
+
+int
+grub_envblk_set (grub_envblk_t envblk, const char *name, const char *value)
+{
+  char *p, *pend;
+  char *space;
+  int found = 0;
+  int nl;
+  int vl;
+  int i;
+
+  nl = grub_strlen (name);
+  vl = escaped_value_len (value);
+  p = envblk->buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
+  pend = envblk->buf + envblk->size;
+
+  /* First, look at free space.  */
+  for (space = pend - 1; *space == '#'; space--)
+    ;
+
+  if (*space != '\n')
+    /* Broken.  */
+    return 0;
+
+  space++;
+
+  while (p + nl + 1 < space)
+    {
+      if (grub_memcmp (p, name, nl) == 0 && p[nl] == '=')
+        {
+          int len;
+
+          /* Found the same name.  */
+          p += nl + 1;
+
+          /* Check the length of the current value.  */
+          len = 0;
+          while (p + len < pend && p[len] != '\n')
+            {
+              if (p[len] == '\\')
+                len += 2;
+              else
+                len++;
+            }
+
+          if (p + len >= pend)
+            /* Broken.  */
+            return 0;
+
+          if (pend - space < vl - len)
+            /* No space.  */
+            return 0;
+
+          if (vl < len)
+            {
+              /* Move the following characters backward, and fill the new
+                 space with harmless characters.  */
+              grub_memmove (p + vl, p + len, pend - (p + len));
+              grub_memset (space + len - vl, '#', len - vl);
+            }
+          else
+            /* Move the following characters forward.  */
+            grub_memmove (p + vl, p + len, pend - (p + vl));
+
+          found = 1;
+          break;
+        }
+
+      p = find_next_line (p, pend);
+    }
+
+  if (! found)
+    {
+      /* Append a new variable.  */
+
+      if (pend - space < nl + 1 + vl + 1)
+        /* No space.  */
+        return 0;
+
+      grub_memcpy (space, name, nl);
+      p = space + nl;
+      *p++ = '=';
+    }
+
+  /* Write the value.  */
+  for (i = 0; value[i]; i++)
+    {
+      if (value[i] == '\\' || value[i] == '\n')
+        *p++ = '\\';
+
+      *p++ = value[i];
+    }
+
+  *p = '\n';
+  return 1;
+}
+
+void
+grub_envblk_delete (grub_envblk_t envblk, const char *name)
+{
+  char *p, *pend;
+  int nl;
+
+  nl = grub_strlen (name);
+  p = envblk->buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
+  pend = envblk->buf + envblk->size;
+
+  while (p + nl + 1 < pend)
+    {
+      if (grub_memcmp (p, name, nl) == 0 && p[nl] == '=')
+        {
+          /* Found.  */
+          int len = nl + 1;
+
+          while (p + len < pend)
+            {
+              if (p[len] == '\n')
+                break;
+              else if (p[len] == '\\')
+                len += 2;
+              else
+                len++;
+            }
+
+          if (p + len >= pend)
+            /* Broken.  */
+            return;
+
+          len++;
+          grub_memmove (p, p + len, pend - (p + len));
+          grub_memset (pend - len, '#', len);
+          break;
+        }
+
+      p = find_next_line (p, pend);
+    }
+}
+
+void
+grub_envblk_iterate (grub_envblk_t envblk,
+                     int hook (const char *name, const char *value))
+{
+  char *p, *pend;
+
+  p = envblk->buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
+  pend = envblk->buf + envblk->size;
+
+  while (p < pend)
+    {
+      if (*p != '#')
+        {
+          char *name;
+          char *value;
+          char *name_start, *name_end, *value_start;
+          char *q;
+          int ret;
+
+          name_start = p;
+          while (p < pend && *p != '=')
+            p++;
+          if (p == pend)
+            /* Broken.  */
+            return;
+          name_end = p;
+
+          p++;
+          value_start = p;
+          while (p < pend)
+            {
+              if (*p == '\n')
+                break;
+              else if (*p == '\\')
+                p += 2;
+              else
+                p++;
+            }
+
+          if (p >= pend)
+            /* Broken.  */
+            return;
+
+          name = grub_malloc (p - name_start + 1);
+          if (! name)
+            /* out of memory.  */
+            return;
+
+          value = name + (value_start - name_start);
+
+          grub_memcpy (name, name_start, name_end - name_start);
+          name[name_end - name_start] = '\0';
+
+          for (p = value_start, q = value; *p != '\n'; ++p)
+            {
+              if (*p == '\\')
+                *q++ = *++p;
+              else
+                *q++ = *p;
+            }
+          *q = '\0';
+
+          ret = hook (name, value);
+          grub_free (name);
+          if (ret)
+            return;
+        }
+
+      p = find_next_line (p, pend);
+    }
+}
diff --git a/grub-core/lib/hexdump.c b/grub-core/lib/hexdump.c
new file mode 100644 (file)
index 0000000..317635a
--- /dev/null
@@ -0,0 +1,85 @@
+/* hexdump.c - hexdump function */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/lib/hexdump.h>
+
+void
+hexdump (unsigned long bse, char *buf, int len)
+{
+  int pos;
+  char line[80];
+
+  while (len > 0)
+    {
+      int cnt, i;
+
+      pos = grub_snprintf (line, sizeof (line), "%08lx  ", bse);
+      cnt = 16;
+      if (cnt > len)
+       cnt = len;
+
+      for (i = 0; i < cnt; i++)
+       {
+         pos += grub_snprintf (&line[pos], sizeof (line) - pos,
+                               "%02x ", (unsigned char) buf[i]);
+         if ((i & 7) == 7)
+           line[pos++] = ' ';
+       }
+
+      for (; i < 16; i++)
+       {
+         pos += grub_snprintf (&line[pos], sizeof (line) - pos, "   ");
+         if ((i & 7) == 7)
+           line[pos++] = ' ';
+       }
+
+      line[pos++] = '|';
+
+      for (i = 0; i < cnt; i++)
+       line[pos++] = ((buf[i] >= 32) && (buf[i] < 127)) ? buf[i] : '.';
+
+      line[pos++] = '|';
+
+      line[pos] = 0;
+
+      grub_printf ("%s\n", line);
+
+      /* Print only first and last line if more than 3 lines are identical.  */
+      if (len >= 4 * 16
+         && ! grub_memcmp (buf, buf + 1 * 16, 16)
+         && ! grub_memcmp (buf, buf + 2 * 16, 16)
+         && ! grub_memcmp (buf, buf + 3 * 16, 16))
+       {
+         grub_printf ("*\n");
+         do
+           {
+             bse += 16;
+             buf += 16;
+             len -= 16;
+           }
+         while (len >= 3 * 16 && ! grub_memcmp (buf, buf + 2 * 16, 16));
+       }
+
+      bse += 16;
+      buf += 16;
+      len -= cnt;
+    }
+}
diff --git a/grub-core/lib/i386/pc/biosnum.c b/grub-core/lib/i386/pc/biosnum.c
new file mode 100644 (file)
index 0000000..058c9d3
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/disk.h>
+
+static int
+grub_get_root_biosnumber_default (void)
+{
+  char *biosnum;
+  int ret = -1;
+  grub_device_t dev;
+
+  biosnum = grub_env_get ("biosnum");
+
+  if (biosnum)
+    return grub_strtoul (biosnum, 0, 0);
+
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->dev
+      && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID)
+    ret = (int) dev->disk->id;
+
+  if (dev)
+    grub_device_close (dev);
+
+  return ret;
+}
+
+int (*grub_get_root_biosnumber) (void) = grub_get_root_biosnumber_default;
diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c
new file mode 100644 (file)
index 0000000..453f73f
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+#include <grub/types.h>
+#include <grub/types.h>
+#include <grub/err.h>
+
+#include <grub/i386/relocator.h>
+
+extern grub_uint8_t grub_relocator32_forward_start;
+extern grub_uint8_t grub_relocator32_forward_end;
+extern grub_uint8_t grub_relocator32_backward_start;
+extern grub_uint8_t grub_relocator32_backward_end;
+
+extern grub_uint32_t grub_relocator32_backward_dest;
+extern grub_uint32_t grub_relocator32_backward_size;
+extern grub_addr_t grub_relocator32_backward_src;
+
+extern grub_uint32_t grub_relocator32_forward_dest;
+extern grub_uint32_t grub_relocator32_forward_size;
+extern grub_addr_t grub_relocator32_forward_src;
+
+extern grub_uint32_t grub_relocator32_forward_eax;
+extern grub_uint32_t grub_relocator32_forward_ebx;
+extern grub_uint32_t grub_relocator32_forward_ecx;
+extern grub_uint32_t grub_relocator32_forward_edx;
+extern grub_uint32_t grub_relocator32_forward_eip;
+extern grub_uint32_t grub_relocator32_forward_esp;
+
+extern grub_uint32_t grub_relocator32_backward_eax;
+extern grub_uint32_t grub_relocator32_backward_ebx;
+extern grub_uint32_t grub_relocator32_backward_ecx;
+extern grub_uint32_t grub_relocator32_backward_edx;
+extern grub_uint32_t grub_relocator32_backward_eip;
+extern grub_uint32_t grub_relocator32_backward_esp;
+
+#define RELOCATOR_SIZEOF(x)    (&grub_relocator32_##x##_end - &grub_relocator32_##x##_start)
+#define RELOCATOR_ALIGN 16
+#define PREFIX(x) grub_relocator32_ ## x
+
+static void
+write_call_relocator_bw (void *ptr, void *src, grub_uint32_t dest,
+                        grub_size_t size, struct grub_relocator32_state state)
+{
+  grub_relocator32_backward_dest = dest;
+  grub_relocator32_backward_src = PTR_TO_UINT64 (src);
+  grub_relocator32_backward_size = size;
+
+  grub_relocator32_backward_eax = state.eax;
+  grub_relocator32_backward_ebx = state.ebx;
+  grub_relocator32_backward_ecx = state.ecx;
+  grub_relocator32_backward_edx = state.edx;
+  grub_relocator32_backward_eip = state.eip;
+  grub_relocator32_backward_esp = state.esp;
+
+  grub_memmove (ptr,
+               &grub_relocator32_backward_start,
+               RELOCATOR_SIZEOF (backward));
+  ((void (*) (void)) ptr) ();
+}
+
+static void
+write_call_relocator_fw (void *ptr, void *src, grub_uint32_t dest,
+                        grub_size_t size, struct grub_relocator32_state state)
+{
+
+  grub_relocator32_forward_dest = dest;
+  grub_relocator32_forward_src = PTR_TO_UINT64 (src);
+  grub_relocator32_forward_size = size;
+
+  grub_relocator32_forward_eax = state.eax;
+  grub_relocator32_forward_ebx = state.ebx;
+  grub_relocator32_forward_ecx = state.ecx;
+  grub_relocator32_forward_edx = state.edx;
+  grub_relocator32_forward_eip = state.eip;
+  grub_relocator32_forward_esp = state.esp;
+
+  grub_memmove (ptr,
+               &grub_relocator32_forward_start,
+               RELOCATOR_SIZEOF (forward));
+  ((void (*) (void)) ptr) ();
+}
+
+#include "../relocator.c"
diff --git a/grub-core/lib/i386/relocator_asm.S b/grub-core/lib/i386/relocator_asm.S
new file mode 100644 (file)
index 0000000..6b803db
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/i386/memory.h>
+
+#ifdef BACKWARD
+#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_backward_ ## x)
+#else
+#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_forward_ ## x)
+#endif
+#ifdef __x86_64__
+#define RAX %rax
+#define RCX %rcx
+#define RDI %rdi
+#define RSI %rdi
+#else
+#define RAX %eax
+#define RCX %ecx
+#define RDI %edi
+#define RSI %esi
+#endif
+
+/* The code segment of the protected mode.  */
+#define CODE_SEGMENT   0x10
+
+/* The data segment of the protected mode.  */
+#define DATA_SEGMENT   0x18
+
+       .p2align        4       /* force 16-byte alignment */
+
+RELOCATOR_VARIABLE(start)
+#ifdef BACKWARD
+LOCAL(base):
+#endif
+       cli
+
+#ifndef __x86_64__
+       /* mov imm32, %eax */
+       .byte   0xb8
+RELOCATOR_VARIABLE(dest)
+       .long   0
+       movl    %eax, %edi
+
+       /* mov imm32, %eax */
+       .byte   0xb8
+RELOCATOR_VARIABLE(src)
+       .long   0
+       movl    %eax, %esi
+
+       /* mov imm32, %ecx */
+       .byte   0xb9
+RELOCATOR_VARIABLE(size)
+       .long   0
+#else
+       xorq    %rax, %rax
+
+       /* mov imm32, %eax */
+       .byte   0xb8
+RELOCATOR_VARIABLE(dest)
+       .long   0
+       movq    %rax, %rdi
+
+       /* mov imm64, %rax */
+       .byte   0x48
+       .byte   0xb8
+RELOCATOR_VARIABLE(src)
+       .long   0, 0
+       movq    %rax, %rsi
+
+       xorq    %rcx, %rcx
+       /* mov imm32, %ecx */
+       .byte   0xb9
+RELOCATOR_VARIABLE(size)
+       .long   0
+
+#endif
+
+       mov     RDI, RAX
+
+#ifdef BACKWARD
+       add     RCX, RSI
+       add     RCX, RDI
+#endif
+
+#ifndef BACKWARD
+       add     RCX, RAX
+#endif
+       add     $0x3, RCX
+       shr     $2, RCX
+
+
+#ifdef BACKWARD
+       /* Backward movsl is implicitly off-by-four.  compensate that.  */
+       sub     $4,     RSI
+       sub     $4,     RDI
+
+       /* Backward copy.  */
+       std
+
+       rep
+       movsl
+
+#else
+       /* Forward copy.  */
+       cld
+       rep
+       movsl
+#endif
+
+       /* %rax contains now our new 'base'.  */
+       mov     RAX, RSI
+       add     $(LOCAL(cont0) - LOCAL(base)), RAX
+       jmp     *RAX
+LOCAL(cont0):
+       lea     (LOCAL(cont1) - LOCAL(base)) (RSI, 1), RAX
+       movl    %eax, (LOCAL(jump_vector) - LOCAL(base)) (RSI, 1)
+
+       lea     (LOCAL(gdt) - LOCAL(base)) (RSI, 1), RAX
+       mov     RAX, (LOCAL(gdt_addr) - LOCAL(base)) (RSI, 1)
+
+       /* Switch to compatibility mode. */
+
+       lgdt    (LOCAL(gdtdesc) - LOCAL(base)) (RSI, 1)
+
+       /* Update %cs.  */
+       ljmp    *(LOCAL(jump_vector) - LOCAL(base)) (RSI, 1)
+
+LOCAL(cont1):
+       .code32
+
+       /* Update other registers. */
+       movl    $DATA_SEGMENT, %eax
+       movl    %eax, %ds
+       movl    %eax, %es
+       movl    %eax, %fs
+       movl    %eax, %gs
+       movl    %eax, %ss
+
+       /* Disable paging. */
+       movl    %cr0, %eax
+       andl    $(~GRUB_MEMORY_CPU_CR0_PAGING_ON), %eax
+       movl    %eax, %cr0
+
+       /* Disable amd64. */
+       movl    $GRUB_MEMORY_CPU_AMD64_MSR, %ecx
+       rdmsr
+       andl    $(~GRUB_MEMORY_CPU_AMD64_MSR_ON), %eax
+       wrmsr
+
+       /* Turn off PAE. */
+       movl    %cr4, %eax
+       andl    $GRUB_MEMORY_CPU_CR4_PAE_ON, %eax
+       movl    %eax, %cr4
+
+       jmp     LOCAL(cont2)
+LOCAL(cont2):
+       .code32
+
+       /* mov imm32, %eax */
+       .byte   0xb8
+RELOCATOR_VARIABLE (esp)
+       .long   0
+
+       movl    %eax, %esp
+
+       /* mov imm32, %eax */
+       .byte   0xb8
+RELOCATOR_VARIABLE (eax)
+       .long   0
+
+       /* mov imm32, %ebx */
+       .byte   0xbb
+RELOCATOR_VARIABLE (ebx)
+       .long   0
+
+       /* mov imm32, %ecx */
+       .byte   0xb9
+RELOCATOR_VARIABLE (ecx)
+       .long   0
+
+       /* mov imm32, %edx */
+       .byte   0xba
+RELOCATOR_VARIABLE (edx)
+       .long   0
+
+       /* Cleared direction flag is of no problem with any current
+          payload and makes this implementation easier.  */
+       cld
+
+       .byte   0xea
+RELOCATOR_VARIABLE (eip)
+       .long   0
+       .word   CODE_SEGMENT
+
+       /* GDT. Copied from loader/i386/linux.c. */
+       .p2align        4
+LOCAL(gdt):
+       /* NULL.  */
+       .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+       /* Reserved.  */
+       .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+       /* Code segment.  */
+       .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
+
+       /* Data segment.  */
+       .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
+
+       .p2align        4
+LOCAL(gdtdesc):
+       .word   0x27
+LOCAL(gdt_addr):
+#ifdef __x86_64__
+       /* Filled by the code. */
+       .quad   0
+#else
+       /* Filled by the code. */
+       .long   0
+#endif
+
+       .p2align        4
+LOCAL(jump_vector):
+       /* Jump location. Is filled by the code */
+       .long   0
+       .long   CODE_SEGMENT
+
+#ifndef BACKWARD
+LOCAL(base):
+#endif
+
+RELOCATOR_VARIABLE(end)
diff --git a/grub-core/lib/i386/relocator_backward.S b/grub-core/lib/i386/relocator_backward.S
new file mode 100644 (file)
index 0000000..0691347
--- /dev/null
@@ -0,0 +1,2 @@
+#define BACKWARD
+#include "relocator_asm.S"
diff --git a/grub-core/lib/i386/setjmp.S b/grub-core/lib/i386/setjmp.S
new file mode 100644 (file)
index 0000000..a2002ae
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+       .file   "setjmp.S"
+
+       .text
+
+/*
+ * int grub_setjmp (grub_jmp_buf env)
+ */
+FUNCTION(grub_setjmp)
+       movl    %ebx, 0(%eax)   /* EBX */
+       movl    %esi, 4(%eax)   /* ESI */
+       movl    %edi, 8(%eax)   /* EDI */
+       movl    %ebp, 12(%eax)  /* EBP */
+       popl    %ecx
+       movl    %esp, 16(%eax)  /* ESP */
+       movl    %ecx, 20(%eax)  /* EIP */
+       xorl    %eax, %eax
+       jmp     *%ecx
+
+
+/*
+ * int grub_longjmp (grub_jmp_buf env, int val)
+ */
+FUNCTION(grub_longjmp)
+       movl    0(%eax), %ebx
+       movl    4(%eax), %esi
+       movl    8(%eax), %edi
+       movl    12(%eax), %ebp
+       movl    16(%eax), %esp
+       movl    20(%eax), %ecx
+
+       movl    %edx, %eax
+       testl   %eax, %eax
+       jnz     1f
+       incl    %eax
+1:     jmp     *%ecx
+
diff --git a/grub-core/lib/ieee1275/datetime.c b/grub-core/lib/ieee1275/datetime.c
new file mode 100644 (file)
index 0000000..7e6f8d1
--- /dev/null
@@ -0,0 +1,142 @@
+/* kern/cmos_datetime.c - CMOS datetime function.
+ *
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/datetime.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/misc.h>
+
+static char *rtc = 0;
+
+static void
+find_rtc (void)
+{
+  auto int hook (struct grub_ieee1275_devalias *alias);
+  int hook (struct grub_ieee1275_devalias *alias)
+  {
+    if (grub_strcmp (alias->type, "rtc") == 0)
+      {
+       grub_dprintf ("datetime", "Found RTC %s\n", alias->path);
+       rtc = grub_strdup (alias->path);
+       return 1;
+      }
+    return 0;
+  }
+  
+  grub_ieee1275_devices_iterate (hook);
+}
+
+grub_err_t
+grub_get_datetime (struct grub_datetime *datetime)
+{
+  struct get_time_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t method;
+    grub_ieee1275_cell_t device;
+    grub_ieee1275_cell_t catch_result;
+    grub_ieee1275_cell_t year;
+    grub_ieee1275_cell_t month;
+    grub_ieee1275_cell_t day;
+    grub_ieee1275_cell_t hour;
+    grub_ieee1275_cell_t minute;
+    grub_ieee1275_cell_t second;
+  }
+  args;
+  int status;
+  grub_ieee1275_ihandle_t ihandle;
+
+  if (!rtc)
+    find_rtc ();
+  if (!rtc)
+    return grub_error (GRUB_ERR_IO, "no RTC found");
+
+  status = grub_ieee1275_open (rtc, &ihandle);
+  if (status == -1)
+    return grub_error (GRUB_ERR_IO, "couldn't open RTC");
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 7);
+  args.device = (grub_ieee1275_cell_t) ihandle;
+  args.method = (grub_ieee1275_cell_t) "get-time";
+
+  status = IEEE1275_CALL_ENTRY_FN (&args);
+
+  grub_ieee1275_close (ihandle);
+
+  if (status == -1)
+    return grub_error (GRUB_ERR_IO, "get-time failed");
+
+  datetime->year = args.year;
+  datetime->month = args.month;
+  datetime->day = args.day;
+  datetime->hour = args.hour;
+  datetime->minute = args.minute;
+  datetime->second = args.second;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_set_datetime (struct grub_datetime *datetime)
+{
+  struct set_time_args
+  {
+    struct grub_ieee1275_common_hdr common;
+    grub_ieee1275_cell_t method;
+    grub_ieee1275_cell_t device;
+    grub_ieee1275_cell_t year;
+    grub_ieee1275_cell_t month;
+    grub_ieee1275_cell_t day;
+    grub_ieee1275_cell_t hour;
+    grub_ieee1275_cell_t minute;
+    grub_ieee1275_cell_t second;
+    grub_ieee1275_cell_t catch_result;
+  }
+  args;
+  int status;
+  grub_ieee1275_ihandle_t ihandle;
+
+  if (!rtc)
+    find_rtc ();
+  if (!rtc)
+    return grub_error (GRUB_ERR_IO, "no RTC found");
+
+  status = grub_ieee1275_open (rtc, &ihandle);
+  if (status == -1)
+    return grub_error (GRUB_ERR_IO, "couldn't open RTC");
+
+  INIT_IEEE1275_COMMON (&args.common, "call-method", 8, 1);
+  args.device = (grub_ieee1275_cell_t) ihandle;
+  args.method = (grub_ieee1275_cell_t) "set-time";
+
+  args.year = datetime->year;
+  args.month = datetime->month;
+  args.day = datetime->day;
+  args.hour = datetime->hour;
+  args.minute = datetime->minute;
+  args.second = datetime->second;
+
+  status = IEEE1275_CALL_ENTRY_FN (&args);
+
+  grub_ieee1275_close (ihandle);
+
+  if (status == -1)
+    return grub_error (GRUB_ERR_IO, "set-time failed");
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/lib/libgcrypt/cipher/ChangeLog b/grub-core/lib/libgcrypt/cipher/ChangeLog
new file mode 100644 (file)
index 0000000..8924f17
--- /dev/null
@@ -0,0 +1,3900 @@
+2009-01-22  Werner Koch  <wk@g10code.com>
+
+       * ecc.c (compute_keygrip): Remove superfluous const.
+
+2009-01-06  Werner Koch  <wk@g10code.com>
+
+       * rmd160.c (oid_spec_rmd160): Add TeleTrust identifier.
+
+2008-12-10  Werner Koch  <wk@g10code.com>
+
+       * dsa.c (generate): Add arg DOMAIN and use it if specified.
+       (generate_fips186): Ditto.
+       (dsa_generate_ext): Parse and check the optional "domain"
+       parameter and pass them to the generate functions.
+
+       * rijndael.c (rijndael_names): Add "AES128" and "AES-128".
+       (rijndael192_names): Add "AES-192".
+       (rijndael256_names): Add "AES-256".
+
+2008-12-05  Werner Koch  <wk@g10code.com>
+
+       * dsa.c (generate): Add arg TRANSIENT_KEY and use it to detrmine
+       the RNG quality needed.
+       (dsa_generate_ext): Parse the transient-key flag und pass it to
+       generate.
+
+2008-11-28  Werner Koch  <wk@g10code.com>
+
+       * dsa.c (generate_fips186): Add arg DERIVEPARMS and use the seed
+       value if available.
+
+       * primegen.c (_gcry_generate_fips186_2_prime): Fix inner p loop.
+
+2008-11-26  Werner Koch  <wk@g10code.com>
+
+       * primegen.c (_gcry_generate_fips186_3_prime): New.
+       * dsa.c (generate_fips186): Add arg USE_FIPS186_2.
+       (dsa_generate_ext): Parse new flag use-fips183-2.
+
+2008-11-25  Werner Koch  <wk@g10code.com>
+
+       * dsa.c (generate_fips186): New.
+       (dsa_generate_ext): Use new function if derive-parms are given or
+       if in FIPS mode.
+       * primegen.c (_gcry_generate_fips186_2_prime): New.
+
+2008-11-24  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (gcry_pk_genkey): Insert code to output extrainfo.
+       (pubkey_generate): Add arg R_EXTRAINFO and pass it to the extended
+       key generation function.
+       * rsa.c (gen_x931_parm_xp, gen_x931_parm_xi): New.
+       (generate_x931): Generate params if not given.
+       (rsa_generate_ext): Parse use-x931 flag.  Return p-q-swapped
+       indicator.
+       * dsa.c (dsa_generate_ext): Put RETFACTORS into R_EXTRAINFO if
+       possible.
+
+       * pubkey.c (gcry_pk_genkey): Remove parsing of almost all
+       parameters and pass the parameter S-expression to pubkey_generate.
+       (pubkey_generate): Simplify by requitring modules to parse the
+       parameters. Remove the special cases for Elgamal and ECC.
+       (sexp_elements_extract_ecc): Add arg EXTRASPEC and use it.  Fix
+       small memory leak.
+       (sexp_to_key): Pass EXTRASPEC to sexp_elements_extract_ecc.
+       (pubkey_table) [USE_ELGAMAL]: Add real extraspec.
+       * rsa.c (rsa_generate_ext): Adjust for new calling convention.
+       * dsa.c (dsa_generate_ext): Ditto.
+       * elgamal.c (_gcry_elg_generate): Ditto. Rename to elg_generate_ext.
+       (elg_generate): New.
+       (_gcry_elg_generate_using_x): Remove after merging code with
+       elg_generate_ext.
+       (_gcry_pubkey_extraspec_elg): New.
+       (_gcry_elg_check_secret_key, _gcry_elg_encrypt, _gcry_elg_sign) 
+       (_gcry_elg_verify, _gcry_elg_get_nbits): Make static and remove
+       _gcry_ prefix.
+       * ecc.c (_gcry_ecc_generate): Rename to ecc_generate_ext and
+       adjust for new calling convention.
+       (_gcry_ecc_get_param): Rename to ecc_get_param and make static.
+       (_gcry_pubkey_extraspec_ecdsa): Add ecc_generate_ext and
+       ecc_get_param.
+       
+2008-11-20  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (pubkey_generate): Add arg DERIVEPARMS.
+       (gcry_pk_genkey): Parse derive-parms and pass it to above.
+       * rsa.c (generate_x931): New.
+       (rsa_generate_ext): Add arg DERIVEPARMS and call new function in
+       fips mode or if DERIVEPARMS is given.
+       * primegen.c (_gcry_derive_x931_prime, find_x931_prime): New.
+
+2008-11-19  Werner Koch  <wk@g10code.com>
+
+       * rsa.c (rsa_decrypt): Use gcry_create_nonce for blinding.
+       (generate): Rename to generate_std.
+
+2008-11-05  Werner Koch  <wk@g10code.com>
+
+       * md.c (md_open): Use a switch to set the Bsize.
+       (prepare_macpads): Fix long key case for SHA384 and SHA512.
+
+       * cipher.c (gcry_cipher_handle): Add field EXTRASPEC.
+       (gcry_cipher_open): Set it.
+       (gcry_cipher_ctl): Add private control code to disable weak key
+       detection and to return the current input block.
+       * des.c (_tripledes_ctx): Add field FLAGS.
+       (do_tripledes_set_extra_info): New.
+       (_gcry_cipher_extraspec_tripledes): Add new function.
+       (do_tripledes_setkey): Disable weak key detection.
+
+2008-10-24  Werner Koch  <wk@g10code.com>
+
+       * md.c (digest_table): Allow MD5 in fips mode.
+       (md_register_default): Take special action for MD5.
+       (md_enable, gcry_md_hash_buffer): Ditto.
+
+2008-09-30  Werner Koch  <wk@g10code.com>
+
+       * rijndael.c (do_setkey): Properly align "t" and "tk".
+       (prepare_decryption): Properly align "w".  Fixes bug #936.
+
+2008-09-18  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (gcry_pk_genkey): Parse domain parameter.
+       (pubkey_generate): Add new arg DOMAIN and remove special case for
+       DSA with qbits.
+       * rsa.c (rsa_generate): Add dummy args QBITS, NAME and DOMAIN and
+       rename to rsa_generate_ext.  Change caller.
+       (_gcry_rsa_generate, _gcry_rsa_check_secret_key) 
+       (_gcry_rsa_encrypt, _gcry_rsa_decrypt, _gcry_rsa_sign) 
+       (_gcry_rsa_verify, _gcry_rsa_get_nbits): Make static and remove
+       _gcry_ prefix.
+       (_gcry_pubkey_spec_rsa, _gcry_pubkey_extraspec_rsa): Adjust names.
+       * dsa.c (dsa_generate_ext): New.
+       (_gcry_dsa_generate): Replace code by a call to dsa_generate.
+       (_gcry_dsa_check_secret_key, _gcry_dsa_sign, _gcry_dsa_verify)
+       (_gcry_dsa_get_nbits): Make static and remove _gcry prefix.
+       (_gcry_dsa_generate2): Remove.
+       (_gcry_pubkey_spec_dsa): Adjust to name changes.
+       (_gcry_pubkey_extraspec_rsa): Add dsa_generate_ext.
+
+2008-09-16  Werner Koch  <wk@g10code.com>
+
+       * ecc.c (run_selftests): Add arg EXTENDED.
+
+2008-09-12  Werner Koch  <wk@g10code.com>
+
+       * rsa.c (test_keys): Do a bad case signature check.
+       * dsa.c (test_keys): Do a bad case check.
+
+       * cipher.c (_gcry_cipher_selftest): Add arg EXTENDED and pass it
+       to the called tests.
+       * md.c (_gcry_md_selftest): Ditto.
+       * pubkey.c (_gcry_pk_selftest): Ditto.
+       * rijndael.c (run_selftests): Add arg EXTENDED and pass it to the
+       called tests.
+       (selftest_fips_128): Add arg EXTENDED and run only one test
+       non-extended mode.
+       (selftest_fips_192): Add dummy arg EXTENDED.
+       (selftest_fips_256): Ditto.
+       * hmac-tests.c (_gcry_hmac_selftest): Ditto.
+       (run_selftests): Ditto.
+       (selftests_sha1): Add arg EXTENDED and run only one test
+       non-extended mode.
+       (selftests_sha224, selftests_sha256): Ditto.
+       (selftests_sha384, selftests_sha512): Ditto.
+       * sha1.c (run_selftests): Add arg EXTENDED and pass it to the
+       called test.
+       (selftests_sha1): Add arg EXTENDED and run only one test
+       non-extended mode.
+       * sha256.c (run_selftests): Add arg EXTENDED and pass it to the
+       called tests.
+       (selftests_sha224): Add arg EXTENDED and run only one test
+       non-extended mode.
+       (selftests_sha256): Ditto.
+       * sha512.c (run_selftests): Add arg EXTENDED and pass it to the
+       called tests.
+       (selftests_sha384): Add arg EXTENDED and run only one test
+       non-extended mode.
+       (selftests_sha512): Ditto.
+       * des.c (run_selftests): Add arg EXTENDED and pass it to the
+       called test.
+       (selftest_fips): Add dummy arg EXTENDED.
+       * rsa.c (run_selftests): Add dummy arg EXTENDED.
+
+       * dsa.c (run_selftests): Add dummy arg EXTENDED.
+
+       * rsa.c (extract_a_from_sexp): New.
+       (selftest_encr_1024): Check that the ciphertext does not match the
+       plaintext.
+       (test_keys): Improve tests and return an error status.
+       (generate): Return an error if test_keys fails.
+       * dsa.c (test_keys): Add comments and return an error status.
+       (generate): Return an error if test_keys failed.
+
+2008-09-11  Werner Koch  <wk@g10code.com>
+
+       * rsa.c (_gcry_rsa_decrypt): Return an error instead of calling
+       BUG in case of a practically impossible condition.
+       (sample_secret_key, sample_public_key): New.
+       (selftest_sign_1024, selftest_encr_1024): New.
+       (selftests_rsa): Implement tests.
+       * dsa.c (sample_secret_key, sample_public_key): New.
+       (selftest_sign_1024): New.
+       (selftests_dsa): Implement tests.
+
+2008-09-09  Werner Koch  <wk@g10code.com>
+
+       * hmac-tests.c (selftests_sha1): Add tests.
+       (selftests_sha224, selftests_sha384, selftests_sha512): Make up tests.
+
+       * hash-common.c, hash-common.h: New.
+       * sha1.c (selftests_sha1): Add 3 tests.
+       * sha256.c (selftests_sha256, selftests_sha224): Ditto.
+       * sha512.c (selftests_sha512, selftests_sha384): Ditto.
+
+2008-08-29  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (gcry_pk_get_keygrip): Remove the special case for RSA
+       and check whether a custom computation function has been setup.
+       * rsa.c (compute_keygrip): New.
+       (_gcry_pubkey_extraspec_rsa): Setup this function.
+       * ecc.c (compute_keygrip): New.
+       (_gcry_pubkey_extraspec_ecdsa): Setup this function.
+
+2008-08-28  Werner Koch  <wk@g10code.com>
+
+       * cipher.c (cipher_decrypt, cipher_encrypt): Return an error if
+       mode NONE is used.
+       (gcry_cipher_open): Allow mode NONE only with a debug flag set and
+       if not in FIPS mode.
+
+2008-08-26  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (pubkey_generate): Add arg KEYGEN_FLAGS.
+       (gcry_pk_genkey): Implement new parameter "transient-key" and
+       pass it as flags to pubkey_generate.
+       (pubkey_generate): Make use of an ext_generate function.
+       * rsa.c (generate): Add new arg transient_key and pass appropriate
+       args to the prime generator.
+       (_gcry_rsa_generate): Factor all code out to ...
+       (rsa_generate): .. new func with extra arg KEYGEN_FLAGS.
+       (_gcry_pubkey_extraspec_ecdsa): Setup rsa_generate.
+       * primegen.c (_gcry_generate_secret_prime) 
+       (_gcry_generate_public_prime): Add new arg RANDOM_LEVEL.
+
+2008-08-21  Werner Koch  <wk@g10code.com>
+
+       * primegen.c (_gcry_generate_secret_prime)
+       (_gcry_generate_public_prime): Use a constant macro for the random
+       level.
+       
+2008-08-19  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (sexp_elements_extract_ecc) [!USE_ECC]: Do not allow
+       allow "curve" parameter.
+
+2008-08-15  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (_gcry_pk_selftest): New.
+       * dsa.c (selftests_dsa, run_selftests): New.
+       * rsa.c (selftests_rsa, run_selftests): New.
+       * ecc.c (selftests_ecdsa, run_selftests): New.
+
+       * md.c (_gcry_md_selftest): New.
+       * sha1.c (run_selftests, selftests_sha1): New.
+       * sha256.c (selftests_sha224, selftests_sha256, run_selftests): New.
+       * sha512.c (selftests_sha384, selftests_sha512, run_selftests): New.
+
+       * des.c (selftest): Remove static variable form selftest.
+       (des_setkey): No on-the-fly self test in fips mode.
+       (tripledes_set3keys): Ditto.
+
+       * cipher.c (_gcry_cipher_setkey, _gcry_cipher_setiv): 
+
+       * dsa.c (generate): Bail out in fips mode if NBITS is less than 1024.
+       * rsa.c (generate): Return an error code if the the requested size
+       is less than 1024 and we are in fpis mode.
+       (_gcry_rsa_generate): Take care of that error code.
+
+       * ecc.c (generate_curve): In fips mode enable only NIST curves.
+
+       * cipher.c (_gcry_cipher_selftest): New.
+
+       * sha512.c (_gcry_digest_extraspec_sha384)
+       (_gcry_digest_extraspec_sha512): New.
+       * sha256.c (_gcry_digest_extraspec_sha224)
+       (_gcry_digest_extraspec_sha256): New.
+       * sha1.c (_gcry_digest_extraspec_sha1): New.
+       * ecc.c (_gcry_pubkey_extraspec_ecdsa): New.
+       * dsa.c (_gcry_pubkey_extraspec_dsa): New.
+       * rsa.c (_gcry_pubkey_extraspec_rsa): New.
+       * rijndael.c (_gcry_cipher_extraspec_aes)
+       (_gcry_cipher_extraspec_aes192, _gcry_cipher_extraspec_aes256): New.
+       * des.c (_gcry_cipher_extraspec_tripledes): New.
+
+       * cipher.c (gcry_cipher_register): Rename to _gcry_cipher_register.
+       Add arg EXTRASPEC.
+       (dummy_extra_spec): New.
+       (cipher_table_entry): Add extraspec field.
+       * md.c (_gcry_md_register): Rename to _gcry_md_register.  Add
+       arg EXTRASPEC.
+       (dummy_extra_spec): New.
+       (digest_table_entry): Add extraspec field.
+       * pubkey.c (gcry_pk_register): Rename to _gcry_pk_register.  Add
+       arg EXTRASPEC.
+       (dummy_extra_spec): New.
+       (pubkey_table_entry): Add extraspec field.
+
+       * ac.c: Let most public functions return GPG_ERR_UNSUPPORTED in
+       fips mode.
+
+       * pubkey.c (pubkey_table_entry): Add field FIPS_ALLOWED and mark
+       appropriate algorithms.
+       (dummy_generate, dummy_check_secret_key, dummy_encrypt) 
+       (dummy_decrypt, dummy_sign, dummy_verify, dummy_get_nbits): Signal
+       a fips error when used.
+       (gcry_pk_register): In fips mode do not allow to register new
+       algorithms.
+
+       * md.c (digest_table): Add field FIPS_ALLOWED and mark appropriate
+       algorithms.
+       (md_register_default): In fips mode register only fips algorithms.
+       (gcry_md_register): In fips mode do not allow to register new
+       algorithms.
+       (gcry_md_get): Signal a fips error if called.
+       (gcry_md_hash_buffer): Do not allow rmd160 when not in fips mode.
+       (md_start_debug): Disable in fips_mode.
+
+       * md.c (gcry_md_register_default): Rename to ..
+       (md_register_default): .. this.
+       (md_digest): Remove this commented fucntion.
+       * pubkey.c (gcry_pk_register_default): Rename to ..
+       (pk_register_default): .. this.
+
+       * cipher.c (cipher_table_entry): Add field FIPS_ALLOWED.
+       (gcry_cipher_register_default): Register only fips approved
+       algorithms.
+       (gcry_cipher_register): Do not allow to register new ciphers.
+       (cipher_setiv): Signal fips error.
+       
+       * cipher (gcry_cipher_register_default): Rename to ..
+       (cipher_register_default): .. this.
+       (REGISTER_DEFAULT_CIPHERS): Adjust for that change.
+
+2008-07-05  Werner Koch  <wk@g10code.com>
+
+       * random-daemon.c, random.h, rndhw.c, rndunix.c, rand-internal.h
+       * random.c, rndegd.c, rndlinux.c, rndw32.c: Move to ../cipher.
+       * Makefile.am: Remove random stuff.
+
+2008-06-24  Szakats Istvan <szaki.ms@gmail.com>  (wk)
+
+       * ac.c (_gcry_ac_key_destroy, _gcry_ac_key_pair_generate): Relase
+       some more memory.
+
+2008-04-22  Werner Koch  <wk@g10code.com>
+
+       * rijndael.c (_gcry_aes_cfb_enc, _gcry_aes_cbc_enc) 
+       (_gcry_aes_cfb_dec, _gcry_aes_cbc_dec): Use Padlock if possible.
+
+2008-04-18  Werner Koch  <wk@g10code.com>
+
+       * sha1.c (transform_aligned): Remove.  That is will obviosuly not
+       work because we need a scratch working area and our internal API
+       does not allow to modify the buffers.
+
+       * rijndael.c: Factor tables out to ..
+       * rijndael-tables.h: .. new.
+
+       * ac.c (ac_data_extract): Make static.
+
+       * camellia.h [HAVE_CONFIG_H]: Include config.h.
+
+       * rndw32.c (registry_poll): Only print the performance data
+       problem warning once.  Suggested by Simon Josefsson.
+
+2008-03-19  Werner Koch  <wk@g10code.com>
+
+       * cipher.c (gcry_cipher_open) [USE_AES]: Init bulk encryption only
+       if requested.  Suggested by Dirk Stoecker.
+
+2008-03-18  Werner Koch  <wk@g10code.com>
+
+       * sha1.c: Include stdint.h.
+       (transform): Add arg NBLOCKS so that we can work on more than one
+       block and avoid updates of the chaining variables.  Changed all
+       callers to use 1.
+       (sha1_write): Replace loop around transform.
+       (transform_aligned) [WORDS_BIGENDIAN]: New.
+       (TRANSFORM): New macro to replace all direct calls of transform.
+
+2008-03-17  Werner Koch  <wk@g10code.com>
+
+       * rijndael.c (_gcry_aes_cfb_dec): New.
+       (do_encrypt): Factor code out to ..
+       (do_encrypt_aligned): .. New.
+       (_gcry_aes_cfb_enc, _gcry_aes_cfb_dec): Use new function.
+       (do_decrypt): Factor code out to ..
+       (do_decrypt_aligned): .. new.
+       (_gcry_aes_cbc_enc, _gcry_aes_cbc_dec): New.
+       * cipher.c (struct gcry_cipher_handle): Put field IV into new
+       union U_IV to enforce proper alignment.  Change all users.
+       (do_cfb_decrypt): Optimize.
+       (do_cbc_encrypt, do_cbc_decrypt): Optimize.
+
+2008-03-15  Werner Koch  <wk@g10code.com>
+
+       * rijndael.c (_gcry_aes_cfb_enc): New.
+       * cipher.c (struct gcry_cipher_handle): Add field ALGO and BULK.
+       (gcry_cipher_open): Set ALGO and BULK.
+       (do_cfb_encrypt): Optimize.
+
+2008-02-18  Werner Koch  <wk@g10code.com>
+
+       * rsa.c (_gcry_rsa_verify) [IS_DEVELOPMENT_VERSION]: Print
+       intermediate results.
+
+2008-01-08  Werner Koch  <wk@g10code.com>
+
+       * random.c (add_randomness): Do not just increment
+       POOL_FILLED_COUNTER but update it by the actual amount of data.
+
+2007-12-13  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (sexp_data_to_mpi): Support SHA-224.
+
+2007-12-05  Werner Koch  <wk@g10code.com>
+
+       * rijndael.c (USE_PADLOCK): Depend on ENABLE_PADLOCK_SUPPORT.
+       * rndhw.c (USE_PADLOCK): Ditto
+
+       * rsa.c (secret): Fixed condition test for using CRT.  Reported by
+       Dean Scarff.  Fixes bug#864.
+       (_gcry_rsa_check_secret_key): Return an erro if the optional
+       parameters are missing.
+       * pubkey.c (sexp_elements_extract): Add arg ALGO_NAME. Changed all
+       callers to pass NULL. Add hack to allow for optional RSA
+       parameters.
+       (sexp_to_key): Pass algo name to sexp_elements_extract.
+
+2007-12-03  Werner Koch  <wk@g10code.com>
+
+       * random.c (gcry_random_add_bytes): Implement it.
+       * rand-internal.h (RANDOM_ORIGIN_EXTERNAL): New.
+
+2007-11-30  Werner Koch  <wk@g10code.com>
+
+       * rndhw.c: New.
+       * rndlinux.c (_gcry_rndlinux_gather_random): Try to read 50%
+       directly from the hwrng.
+       * random.c (do_fast_random_poll): Also run the hw rng fast poll.
+       (_gcry_random_dump_stats): Tell whether the hw rng failed.
+
+2007-11-29  Werner Koch  <wk@g10code.com>
+
+       * rijndael.c (USE_PADLOCK): Define new macro used for ia32.
+       (RIJNDAEL_context) [USE_PADLOCK]: Add fields USE_PADLOCK and
+       PADLOCK_KEY.
+       (do_setkey) [USE_PADLOCK]: Enable padlock if available for 128 bit
+       AES.
+       (do_padlock) [USE_PADLOCK]: New.
+       (rijndael_encrypt, rijndael_decrypt) [USE_PADLOCK]: Divert to
+       do_padlock.
+       * cipher.c (cipher_context_alignment_t): New.  Use it in this
+       module in place of PROPERLY_ALIGNED_TYPE.
+       (NEED_16BYTE_ALIGNED_CONTEXT): Define macro for ia32.
+       (struct gcry_cipher_handle): Add field HANDLE_OFFSET.
+       (gcry_cipher_open): Take care of increased alignment requirements.
+       (gcry_cipher_close): Ditto.
+
+2007-11-28  Werner Koch  <wk@g10code.com>
+
+       * sha256.c (asn224): Fixed wrong template.  It happened due to a
+       bug in RFC4880.  SHA-224 is not in the stable version of libgcrypt
+       so the consequences are limited to users of this devel version.
+
+2007-10-31  Werner Koch  <wk@g10code.com>
+
+       * ac.c (gcry_ac_data_new): Remove due to the visibility wrapper.
+       (gcry_ac_data_destroy, gcry_ac_data_copy, gcry_ac_data_length) 
+       (gcry_ac_data_set, gcry_ac_data_get_name, gcry_ac_data_get_index) 
+       (gcry_ac_data_to_sexp, gcry_ac_data_from_sexp) 
+       (gcry_ac_data_clear, gcry_ac_io_init, gcry_ac_open) 
+       (gcry_ac_close, gcry_ac_key_init, gcry_ac_key_pair_generate) 
+       (gcry_ac_key_pair_extract, gcry_ac_key_destroy) 
+       (gcry_ac_key_pair_destroy, gcry_ac_key_data_get) 
+       (gcry_ac_key_test, gcry_ac_key_get_nbits, gcry_ac_key_get_grip) 
+       (gcry_ac_data_encrypt, gcry_ac_data_decrypt, gcry_ac_data_sign) 
+       (gcry_ac_data_verify, gcry_ac_data_encode, gcry_ac_data_decode) 
+       (gcry_ac_mpi_to_os, gcry_ac_mpi_to_os_alloc, gcry_ac_os_to_mpi) 
+       (gcry_ac_data_encrypt_scheme, gcry_ac_data_decrypt_scheme) 
+       (gcry_ac_data_sign_scheme, gcry_ac_data_verify_scheme) 
+       (gcry_ac_io_init_va): Ditto.
+       (gcry_ac_id_to_name, gcry_ac_name_to_id): Remove as these
+       deprecated functions are now implemented by visibility.c.
+
+2007-10-26  Werner Koch  <wk@g10code.com>
+
+       * rndw32.c: Disable debug flag.
+
+2007-10-25  Werner Koch  <wk@g10code.com>
+
+       * rndw32.c: Updated from current cryptlib snapshot and modified
+       for our use.  Removed support from pre NT systems.
+       (slow_gatherer_windows95): Remove.
+       (_gcry_rndw32_gather_random): Require an NT platform.
+       (init_system_rng, read_system_rng, read_mbm_data): New.
+       (slow_gatherer_windowsNT): Rename to ...
+       (slow_gatherer): .. this.  Read system RNG and MBM.
+       (registry_poll): New with code factored out from slow_gatherer.
+
+2007-08-23  Werner Koch  <wk@g10code.com>
+
+       * random.c (pool_filled_counter): New.
+       (add_randomness): Use it.
+
+2007-08-22  Werner Koch  <wk@g10code.com>
+
+       * rndw32.c, rndunix.c: Switched to LGPL.
+
+2007-05-30  Werner Koch  <wk@g10code.com>
+
+       * camellia.h, camellia.c: Replace by new LGPL version and adjusted
+       camellia.h.
+
+2007-05-09  Marcus Brinkmann  <marcus@g10code.de>
+
+       * ac.c (_gcry_ac_io_init_va, _gcry_ac_io_write, _gcry_ac_io_read):
+       Adjust users of gcry_ac_io_t because union is not anonymous
+       anymore.
+
+2007-05-02  Werner Koch  <wk@g10code.com>
+
+       * camellia-glue.c (camellia_setkey, camellia_encrypt)
+       (camellia_decrypt): Recalculated used stack size in called
+       functions.
+       * camellia.h: Redefine external symbols.
+
+2007-05-02  David Shaw  <dshaw@jabberwocky.com>
+
+       * Makefile.am, cipher.c: Add Camellia.
+
+       * camellia-glue.c: New.  The necessary glue to interface libgcrypt
+       to the stock NTT Camellia distribution.
+
+       * camellia.h, camellia.c: The stock NTT Camellia distribution
+       (GPL).
+
+2007-04-30  David Shaw  <dshaw@jabberwocky.com>
+
+       * cipher.c: Use #if instead of #ifdef as configure defines the
+       USE_cipher defines as 0 for disabled.
+
+2007-04-30  Werner Koch  <wk@g10code.com>
+
+       * rndegd.c (_gcry_rndegd_set_socket_name): New.
+
+2007-04-30  Marcus Brinkmann  <marcus@g10code.de>
+
+       * ecc.c (ec2os): Fix relocation of short numbers.
+
+       * ecc.c (generate_key): Do not allocate D, which will be allocated
+       by GEN_K.  Remove G.  Fix test if g_x, g_y resp. q_x, q_y are
+       requested.
+       (_gcry_ecc_generate): Release unneeded members of SK.
+       * pubkey.c (sexp_to_key): Release NAME.
+
+2007-04-28  Marcus Brinkmann  <marcus@g10code.de>
+
+       * ac.c (gcry_ac_mpi): Remove member NAME_PROVIDED.
+       (ac_data_mpi_copy, _gcry_ac_data_set, _gcry_ac_data_get_name)
+       (_gcry_ac_data_get_index, ac_data_construct): Adjust handling of
+       NAME accordingly.
+
+2007-04-20  Werner Koch  <wk@g10code.com>
+
+       * ecc.c (domain_parms): Add standard brainpool curves.
+
+2007-04-18  Werner Koch  <wk@g10code.com>
+
+       * ecc.c (generate_curve): Implement alias mechanism.
+
+       * pubkey.c (sexp_elements_extract_ecc): New.
+       (sexp_to_key): Add special case for ecc.
+       (sexp_to_key, sexp_to_sig, sexp_to_enc, gcry_pk_genkey): Replace
+       name_terminated stuff by a call to _gcry_sexp_nth_string.
+       (gcry_pk_get_keygrip): Ditto.
+
+2007-04-16  Werner Koch  <wk@g10code.com>
+
+       * ecc.c (_gcry_ecc_generate): Renamed DUMMY to CURVE and use it.
+
+2007-04-13  Marcus Brinkmann  <marcus@g10code.de>
+
+       * ac.c (ac_data_construct): Cast const away to suppress compiler
+       warning.
+
+       * ecc.c (ecc_generate): Avoid compiler warning for unused argument
+       DUMMY.
+       (ecc_verify): Avoid compiler warning for unused arguments CMP and
+       OPAQUEV.
+
+2007-04-06  Werner Koch  <wk@g10code.com>
+
+       * sha1.c (oid_spec_sha1): Add another oid from X9.62.
+
+2007-03-28  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (gcry_pk_genkey): Do not issue misc-key-info if it is
+       empty.
+       (gcry_pk_genkey): New parameter "curve".
+
+       * ecc.c: Entirely rewritten with only a few traces of the old
+       code left.
+       (_gcry_ecc_generate): New.
+       (generate_key) New arg NAME.
+       (generate_curve): Ditto.  Return actual number of NBITS.
+
+2007-03-26  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (gcry_pk_genkey): Increase size of SKEY array and add a
+       runtime bounds check.
+
+2007-03-23  Werner Koch  <wk@g10code.com>
+
+       * ecc.c (ecc_ctx_init, ecc_ctx_free, ecc_mod, ecc_mulm): New.
+       (duplicate_point, sum_points, escalar_mult): Don't use a
+       copy of base->p.  Replaced all mpi_mulm by ecc_mulm so that we can
+       experiment with different algorithms.
+       (generate_key, check_secret_key, sign, verify): Initialize a
+       computation context for use by ecc_mulm.
+
+2007-03-22  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (pubkey_table): Initialize ECC.
+       * Makefile.am (EXTRA_libcipher_la_SOURCES): Add ecc.c.
+       * ecc.c: New. Heavily reformatted and changed for use in libgcrypt.
+       (point_init): New.
+       (escalar_mult): Make arg R the first arg to be similar to the mpi
+       functions.
+       (duplicate_point): Ditto
+       (sum_points): Ditto
+       (sign, verify): Remove unneeded copy operations.
+       (sum_points): Removed memory leaks and optimized some compares.
+       (verify): Simplified input check.
+
+2007-03-14  Werner Koch  <wk@g10code.com>
+
+       * random.c (MASK_LEVEL): Removed macro as it was used only at one
+       place.  Open coded it there.
+       (gcry_randomize, _gcry_update_random_seed_file)
+       (_gcry_fast_random_poll): Factor lock code out to ..
+       (lock_pool, unlock_pool): .. new.
+       (initialize): Look the pool while allocating. 
+       (read_random_source, do_fast_random_poll): Moved intialization to ...
+       (initialize): .. here.
+       (_gcry_enable_quick_random_gen): No more need for initialization.
+       (is_initialized):  Moved this global flag to ..
+       (initialize): .. here and changed all users to unconditionally call
+       initialize.
+       (add_randomness): Remove initalization here.  It simply can't
+       happen. 
+
+       * random.c (enum random_origins): Moved to ..
+       * rand-internal.h: .. here.
+       * rndunix.c (_gcry_rndunix_gather_random): Use enum in prototype
+       for ORIGIN and renamed REQUESTOR to ORIGIN.
+       * rndegd.c (_gcry_rndegd_gather_random): Ditto.
+       * rndlinux.c (_gcry_rndlinux_gather_random): Ditto.
+       * rndw32.c (_gcry_rndw32_gather_random): Ditto.
+       (_gcry_rndw32_gather_random_fast): Ditto.
+
+2007-03-13  Werner Koch  <wk@g10code.com>
+
+       * random.c (enum random_origins): New.
+       (add_randomness): Renamed arg SOURCE to ORIGIN.
+       (read_random_source): Renamed arg REQUESTOR to ORIGIN.
+       (getfnc_gather_random): Removed static variable because this
+       function is only called one and thus we don't need this
+       optimization.
+       (_gcry_quick_random_gen): Removed and replaced by..
+       (_gcry_enable_quick_random_gen): .. this.  It is onlyu used to
+       enable it and it does not make sense to disable it later. Changed
+       the only one caller too.
+       (get_random_bytes): Removed.
+       (gcry_random_bytes, gcry_random_bytes_secure): Implement in terms
+       of gcry_randomize.
+       * random-daemon.c (_gcry_daemon_get_random_bytes): Removed.
+
+2007-02-23  Werner Koch  <wk@g10code.com>
+
+       * elgamal.c (generate): Removed unused variable TEMP.
+       (test_keys): New arg NODIE.
+       (generate_using_x, _gcry_elg_generate_using_x): New.
+       * pubkey.c (pubkey_generate): New arg XVALUE and direct call to
+       the new elgamal generate fucntion.
+       (gcry_pk_genkey): Parse the new "xvalue" tag.
+
+2007-02-22  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (sexp_data_to_mpi): Handle dynamically allocated
+       algorithms.  Suggested by Neil Dunbar.  Fixes bug#596.
+
+       * rndw32.c (_gcry_rndw32_gather_random_fast): Make it return void.
+
+       * cipher.c (gcry_cipher_algo_name): Simplified.
+
+       * random.c: Use the daemon only if compiled with USE_RANDOM_DAEMON. 
+
+       * Makefile.am (libcipher_la_SOURCES): Build random-daemon support
+       only if requested.
+
+2007-02-21  Werner Koch  <wk@g10code.com>
+
+       * random.c (rndpool, keypool): Make unsigned.
+       (mix_pool): Change char* variables to unsigned char*.
+       (gcry_randomize): Make arg BUFFER a void*.
+       (gcry_create_nonce): Ditto.
+
+       * rmd160.c (gcry_rmd160_mixblock): Make BUFFER a void*.
+       (_gcry_rmd160_hash_buffer): Make OUTBUF and BUFFER void*.
+       * sha1.c (_gcry_sha1_hash_buffer): Ditto.
+
+       * cipher.c (gcry_cipher_encrypt, cry_cipher_decrypt): Change
+       buffer args to void*.
+       (gcry_cipher_register): Make ALGORITHM_ID a int *.
+
+       * md.c (md_start_debug): Make SUFFIX a const char*.  Use snprintf.
+       (gcry_md_debug): New.
+       (gcry_md_ctl): Changed arg BUFFER from unsigned char*.
+
+       * md.c (md_write): Make INBUF a const void*.
+       (gcry_md_write): Remove needless cast.
+       * crc.c (crc32_write): Make INBUF a const void*
+       (update_crc32, crc24rfc2440_write): Ditto.
+       * sha512.c (sha512_write, transform): Ditto.
+       * sha256.c (sha256_write, transform): Ditto.
+       * rmd160.c (rmd160_write, transform): Ditto.
+       * md5.c (md5_write, transform): Ditto.
+       * md4.c (md4_write, transform): Ditto.
+       * sha1.c (sha1_write, transform): Ditto.
+
+       * tiger.c (tiger_write, transform): Ditto.
+       * whirlpool.c (whirlpool_write, whirlpool_add, transform): Ditto.
+
+       * elgamal.c (elg_names): Change to a const*.
+       * dsa.c (dsa_names): Ditto.
+       * rsa.c (rsa_names): Ditto.
+       * pubkey.c (gcry_pk_lookup_func_name): Make ALIASES a const.
+
+2007-02-20  Werner Koch  <wk@g10code.com>
+
+       * rndlinux.c (open_device): Remove unsused arg MINOR.
+
+2007-01-30  Werner Koch  <wk@g10code.com>
+
+       * sha256.c (oid_spec_sha256): Add alias from pkcs#1.
+       * sha512.c (oid_spec_sha512): Ditto.
+       (oid_spec_sha384): Ditto.
+
+2006-12-18  Werner Koch  <wk@g10code.com>
+
+       * rndlinux.c (set_cloexec_flag): New.
+       (open_device): Set close-on-exit flags.  Suggested by Max
+       Kellermann.  Fixes Debian#403613.
+
+       * Makefile.am (AM_CPPFLAGS, AM_CFLAGS): Splitted and merged
+       Moritz' changes.
+       (INCLUDES): Removed.
+
+2006-11-30  Werner Koch  <wk@g10code.com>
+
+       * serpent.c (byte_swap_32): Remove trailing semicolon.
+
+2006-11-15  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (INCLUDES): Include ../src/
+
+2006-11-03  Werner Koch  <wk@g10code.com>
+
+       * random.c [HAVE_GETTIMEOFDAY]: Included sys/time.h and not
+       sys/times.h.  Reported by Rafaël Carré.
+
+2006-11-05  Moritz Schulte  <moritz@g10code.com>
+
+       * Makefile.am (AM_CFLAGS): Added -I$(top_builddir)/src so that the
+       new gcrypt.h is used, not the one installed in the system.
+
+2006-10-25  Werner Koch  <wk@g10code.com>
+
+       * primegen.c (prime_generate_internal): Tweaked use of secure
+       memory and entropy use. Safe unused primes from the pool. Allocate
+       at least a pool of 30.
+       (save_pool_prime, get_pool_prime): New.
+
+2006-10-23  Werner Koch  <wk@g10code.com>
+
+       * ac.c (_gcry_ac_data_from_sexp): Reset sexp_tmp for failsafe
+       means.  Release sexp_cur if needed.  Reported by Dirk Stoecker.
+
+       * pubkey.c (pubkeys_registered_lock): Intialized it.  It is not
+        realy needed because this is a mere initialization to 0 anyway.
+        Noted by Victor Stinner.
+
+2006-10-17  Werner Koch  <wk@g10code.com>
+
+       * dsa.c (_gcry_dsa_generate2): New.
+       (generate): New arg QBITS.  Add sanity checks for reasonable qbits
+       and nbits.
+       * pubkey.c (gcry_pk_genkey): Parse an qbits element.
+       (pubkey_generate): New arg QBITS.  Pass it to the DSA generation.
+
+2006-10-05  Werner Koch  <wk@g10code.com>
+
+       * md.c (gcry_md_algo_info) <get_asnoid>: Check that the algo is
+       available.
+
+2006-10-04  David Shaw  <dshaw@jabberwocky.com>  (wk)
+       * tiger.c (round): Rename to tiger_round as gcc 4 has a built-in
+       round function that this conflicts with.
+2006-09-11  Werner Koch  <wk@g10code.com>
+
+       * rndw32.c (slow_gatherer_windowsNT): While adding data use the
+       size of the diskPerformance and not its address. Has been fixed in
+       GnuPG more than a year ago.  Noted by Lee Fisher.
+
+2006-08-30  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (sexp_data_to_mpi): Need to allow "ripemd160" here as
+       this is the canonical name.
+
+2006-08-29  Hye-Shik Chang <perky@FreeBSD.org>  (wk)
+
+       * seed.c: New.
+
+2006-08-03  Werner Koch  <wk@g10code.com>
+
+       * random-daemon.c (_gcry_daemon_initialize_basics): Don't
+       initialize the socket.  Remove arg SOCKETNAME.
+       (connect_to_socket): Make sure that daemon is set to -1 on error.
+       (call_daemon): Initialize the socket on the first call.
+       (_gcry_daemon_randomize, _gcry_daemon_get_random_bytes) 
+       (_gcry_daemon_create_nonce): New arg SOCKETNAME.
+       * random.c (initialize): Call new daemon initializator.
+       (get_random_bytes, gcry_randomize, gcry_create_nonce): Pass socket
+       name to daemon call and reset allow_daemon on failure.
+
+2006-07-26  Werner Koch  <wk@g10code.com>
+
+       * rmd160.c (_gcry_rmd160_mixblock): Add cast to transform call.
+
+       * blowfish.c (selftest): Cast string to usnigned char*.
+
+       * primegen.c (prime_generate_internal): Cast unsigned/char*
+       mismatch in calling m_out_of_n.
+       (is_prime): Changed COUNT to unsigned int *.
+
+       * ac.c (_gcry_ac_data_copy): Initialize DATA_MPIS.
+
+       * random.c (gcry_create_nonce): Update the pid after a fork.
+       Reported by Uoti Urpala.
+
+2006-07-04  Marcus Brinkmann  <marcus@g10code.de>
+
+       * sha512.c: Fix typo in copyright notice.
+
+2006-06-21  Werner Koch  <wk@g10code.com>
+
+       * rsa.c (_gcry_rsa_generate): Replace xcalloc by calloc.
+       * pubkey.c (gcry_pk_encrypt, gcry_pk_sign): Ditto.
+       (sexp_to_key, sexp_to_sig, sexp_to_enc, gcry_pk_encrypt) 
+       (gcry_pk_sign, gcry_pk_genkey, gcry_pk_get_keygrip): Ditto. 
+       * md.c (md_copy): Ditto.
+       
+2006-04-22  Moritz Schulte  <moritz@g10code.com>
+
+       * random-daemon.c (_gcry_daemon_initialize_basics): New argument:
+       SOCKETNAME.  Passing on to connect_to_socket() if non-NULL.
+       (connect_to_socket, writen, readn, call_daemon): New functions.
+       (_gcry_daemon_randomize, _gcry_daemon_get_random_bytes) 
+       (_gcry_daemon_create_nonce): Call call_daemon().
+       (RANDOM_DAEMON_SOCKET): New symbol.
+       (daemon_socket): New static variable.
+
+       * random.h (_gcry_daemon_initialize_basics): New parameter:
+       SOCKETNAME.
+       (_gcry_set_random_daemon_socket): New declaration.
+
+       * random.c (initialize_basics): Pass DAEMON_SOCKET_NAME to
+       _gcry_daemon_initialize_basics.
+       (_gcry_set_random_daemon_socket): New function, setting
+       DAEMON_SOCKET_NAME.
+
+2006-04-01  Moritz Schulte  <moritz@g10code.com>
+
+       * ac.c (eme_pkcs_v1_5_encode): Use KEY_SIZE directly, no need to
+       call gcry_ac_key_get_nbits.
+       (eme_pkcs_v1_5_decode): Likewise.
+       (ac_es_dencode_prepare_pkcs_v1_5): Fill options_em structure with
+       key_size.
+       (_gcry_ac_data_dump, gcry_ac_data_dump): New functions.
+       (_gcry_ac_data_to_sexp, _gcry_ac_data_from_sexp): More or less
+       rewritten; changed S-Expression format so that it matches the one
+       used in pubkey.c.
+
+2006-03-15  Werner Koch  <wk@g10code.com>
+
+       * random-daemon.c: New.
+       * random.c (_gcry_use_random_daemon): New.
+       (get_random_bytes, gcry_randomize, gcry_create_nonce): Try
+       diverting to the daemon functions.
+
+2006-03-14  Werner Koch  <wk@g10code.com>
+
+       * random.c (lock_seed_file): New.
+       (read_seed_file, _gcry_update_random_seed_file): Use it.
+
+       * random.c (gcry_create_nonce):  Detect a fork and re-seed.
+       (read_pool): Fixed the fork detection; it used to work only for
+       multi-threaded processes.
+
+2006-03-12  Brad Hards  <bradh@frogmouth.net>  (wk)
+
+       * md.c (md_open): Use new variable macpads_Bsize instead of
+       hardwiring the block size.  Changed at all places.
+
+2006-03-10  Brad Hards  <bradh@frogmouth.net>  (wk, patch 2005-04-22)
+
+       * md.c, sha256.c:  Add support for SHA-224.
+       (sha224_init): New.
+       
+2006-01-18  Brad Hards  <bradh@frogmouth.net>  (wk 2006-03-07)
+
+       * cipher.c (cipher_encrypt, cipher_decrypt, do_ofb_encrypt)
+       (do_ofb_decrypt, gcry_cipher_open): Implement Output Feedback Mode.
+
+2005-11-02  Moritz Schulte  <moritz@g10code.com>
+
+       * pubkey.c (gcry_pk_algo_name): Return "?" instead of NULL for
+       unknown algorithm IDs.
+       * cipher.c (cipher_algo_to_string): Likewise.
+
+2005-11-01  Moritz Schulte  <moritz@g10code.com>
+
+       * pubkey.c (gcry_pk_algo_info): Don't forget to break after switch
+       case.
+
+2005-09-19  Werner Koch  <wk@g10code.com>
+
+       * dsa.c (generate): Add preliminary support for 2 and 4 keys.
+       Return an error code if the key size is not supported.
+       (_gcry_dsa_generate): Return an error.
+
+2005-08-22  Werner Koch  <wk@g10code.com>
+
+       * primegen.c (check_prime): New arg RM_ROUNDS.
+       (prime_generate_internal): Call it here with 5 rounds as used
+       before.
+       (gcry_prime_check): But here with 64 rounds.
+       (is_prime): Make sure never to use less than 5 rounds.
+
+2005-04-16  Moritz Schulte  <moritz@g10code.com>
+
+       * ac.c (_gcry_ac_init): New function.
+
+2005-04-12  Moritz Schulte  <moritz@g10code.com>
+
+       * ac.c (_gcry_ac_io_write, _gcry_ac_io_read): Initialize err to
+       make the compiler happy.
+       Always use errno, now that gcry_malloc() is guaranteed to set
+       errno on failure.
+       (_gcry_ac_data_to_sexp): Don't forget to goto out after error in
+       loop.
+       (_gcry_ac_data_to_sexp): Remove unused variable: mpi_list;
+       (_gcry_ac_data_to_sexp): Always deallocate sexp_buffer.
+       (_gcry_ac_data_from_sexp): Don't forget to initialize data_set_new.
+       (_gcry_ac_data_from_sexp): Handle special case, which is
+       necessary, since gcry_sexp_nth() does not distinguish between
+       "element does not exist" and "element is the empty list".
+       (_gcry_ac_io_init_va): Use assert to make sure that mode and type
+       are correct.
+       Use gcry_error_t types where gcry_err_code_t types have been used
+       before.
+
+2005-04-11  Moritz Schulte  <moritz@g10code.com>
+
+       * ac.c (_gcry_ac_data_sign_scheme): Don't forget to initialize
+       buffer.
+
+       * whirlpool.c: New file.
+       * md.c (digest_table): Add whirlpool.
+       * Makefile.am (EXTRA_libcipher_la_SOURCES): Added: whirlpool.c.
+
+2005-03-30  Moritz Schulte  <moritz@g10code.com>
+
+       * ac.c (_gcry_ac_data_from_sexp): Use length of SEXP_CUR, not
+       length of SEXP; do not forget to set SEXP_TMP to NULL after it has
+       been released.
+
+       (struct gcry_ac_mpi): New member: name_provided.
+       (_gcry_ac_data_set): Rename variable `name_final' to `name_cp';
+       remove const qualifier; change code to not cast away const
+       qualifiers; use name_provided member as well.
+       (_gcry_ac_data_set, _gcry_ac_data_get_name): Use name_provided
+       member of named mpi structure.
+
+       (gcry_ac_name_to_id): Do not forget to initialize err.
+       (_gcry_ac_data_get_index): Do not forget to initialize mpi_return;
+       use gcry_free() instead of free(); remove unnecessary cast; rename
+       mpi_return and name_return to mpi_cp and name_cp; adjust code.
+       (ac_data_mpi_copy): Do not cast away const qualifier.
+       (ac_data_values_destroy): Likewise.
+       (ac_data_construct): Likewise.
+
+       (ac_data_mpi_copy): Initialize flags to GCRY_AC_FLAG_DEALLOC.
+       (ac_data_extract): Use GCRY_AC_FLAG_DEALLOC instead of
+       GCRY_AC_FLAG_COPY.
+
+       (_gcry_ac_io_init_va, _gcry_ac_io_init, gcry_ac_io_init)
+       (gcry_ac_io_init_va, _gcry_ac_io_write, _gcry_ac_io_read)
+       (_gcry_ac_io_read_all, _gcry_ac_io_process): New functions.
+       (gry_ac_em_dencode_t): Use gcry_ac_io_t in prototype instead of
+       memroy strings directly; adjust encode/decode functions to use io
+       objects.
+       (emsa_pkcs_v1_5_encode_data_cb): New function ...
+       (emsa_pkcs_v1_5_encode): ... use it here.
+       (ac_data_dencode): Use io objects.
+       (_gcry_ac_data_encode, _gcry_ac_data_decode, gcry_ac_data_encode)
+       (gcry_ac_data_decode): Likewise.
+       (_gcry_ac_data_encrypt_scheme, gcry_ac_data_encrypt_scheme)
+       (_gcry_ac_data_decrypt_scheme, gcry_ac_data_decrypt_scheme)
+       (_gcry_ac_data_sign_scheme, gcry_ac_data_sign_scheme)
+       (_gcry_ac_data_verify_scheme, gcry_ac_data_verify_scheme):
+       Likewise.
+
+2005-03-23  Werner Koch  <wk@g10code.com>
+
+       * rndw32.c (_gcry_rndw32_gather_random_fast): While adding data
+       use the size of the object and not the one of its address.  Bug
+       reported by Sascha Kiefer.
+
+2005-03-19  Moritz Schulte  <moritz@g10code.com>
+
+       * cipher.c (do_cbc_encrypt): Be careful to not overwrite data,
+       which is to be used later on.  This happend, in case CTS is
+       enabled and OUTBUF is equal to INBUF.
+
+2005-02-25  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (gcry_pk_get_keygrip): Allow for shadowed-private-key.
+
+2005-02-13  Moritz Schulte  <moritz@g10code.com>
+
+       * serpent.c: Updated from 1.2 branch:
+
+       s/u32_t/u32/ and s/byte_t/byte/.  Too match what we have always
+       used and are using in all other files too
+       (serpent_test): Moved prototype out of a fucntion.
+
+2005-02-07  Moritz Schulte  <moritz@g10code.com>
+
+       * ac.c: Major parts rewritten.
+       * pubkey.c (_gcry_pk_get_elements): New function.
+
+2004-12-09  Werner Koch  <wk@g10code.com>
+
+       * serpent.c (serpent_setkey): Moved prototype of serpent_test to
+       outer scope.
+
+2004-09-11  Moritz Schulte  <moritz@g10code.com>
+
+       * pubkey.c (pubkey_table): Added an alias entry for GCRY_PK_ELG_E.
+
+2004-08-23  Moritz Schulte  <moritz@g10code.com>
+
+       * ac.c: Do not include <assert.h>.
+       * rndegd.c: Likewise.
+       * sha1.c: Likewise.
+       * rndunix.c: Likewise.
+       * rndlinux.c: Likewise.
+       * rmd160.c: Likewise.
+       * md5.c: Likewise.
+       * md4.c: Likewise.
+       * cipher.c: Likewise.
+       * crc.c: Likewise.
+       * blowfish.c: Likewise.
+
+       * pubkey.c (dummy_generate, dummy_check_secret_key)
+       (dummy_encrypt, dummy_decrypt, dummy_sign, dummy_verify): Return
+       err code GPG_ERR_NOT_IMPLEMENTED instead of aborting through
+       log_bug().
+       (dummy_get_nbits): Return 0 instead of aborting though log_bug().
+
+2004-08-19  Werner Koch  <wk@g10code.de>
+
+       * pubkey.c (sexp_data_to_mpi): Changed the zero random byte
+       substituting code to actually do clever things.  Thanks to
+       Matthias Urlichs for noting the implementation problem.
+
+2004-08-09  Moritz Schulte  <moritz@g10code.com>
+
+       * pubkey.c (gcry_pk_sign): Fixed memory leak; fix provided by
+       Modestas Vainius.
+
+2004-07-16  Werner Koch  <wk@gnupg.org>
+
+       * rijndael.c (do_encrypt): Fix alignment problem.  Bugs found by
+       Matthias Urlichs.
+       (do_decrypt): Ditto.
+       (keySched, keySched2): Use 2 macros along with unions in the key
+       schedule context.
+
+2004-07-14  Moritz Schulte  <moritz@g10code.com>
+
+       * rsa.c (_gcry_rsa_decrypt): Don't forget to free "a".  Thanks to
+       Nikos Mavroyanopoulos.
+
+2004-05-09  Werner Koch  <wk@gnupg.org>
+
+       * random.c (read_pool): Mix the PID in to better protect after a
+       fork.
+
+2004-07-04  Moritz Schulte  <moritz@g10code.com>
+
+       * serpent.c: Use "u32_t" instead of "unsigned long", do not
+       declare S-Box variables as "register".  Fixes failure on
+       OpenBSD/sparc64, reported by Nikolay Sturm.
+
+2004-05-07  Werner Koch  <wk@gnupg.org>
+
+       * random.c (initialize): Factored out some code to ..
+       (initialize_basics): .. new function.
+       (_gcry_random_initialize): Just call initialize_basics unless the
+       new arg FULL is set to TRUE.
+       (_gcry_fast_random_poll): Don't do anything unless the random
+       system has been really initialized.
+
+2004-05-07  Moritz Schulte  <moritz@g10code.de>
+
+       * ac.c (gcry_ac_open): Do not dereference NULL pointer.  Reported
+       by Umberto Salsi.
+
+2004-02-20  Werner Koch  <wk@gnupg.org>
+
+       * primegen.c (check_prime): New args CB_FUNC and CB_ARG; call them
+       at different stages.  Pass these arguments through all callers.
+
+2004-02-06  Werner Koch  <wk@gnupg.org>
+
+       * des.c: Add a new OID as used by pkcs#12.
+
+       * rfc2268.c: New. Taken from libgcrypt. 
+       * cipher.c: Setup the rfc2268 algorithm.
+
+2004-01-25  Moritz Schulte  <mo@g10code.com>
+
+       * primegen.c (prime_generate_internal): Do not forget to free
+       `q_factor'; fixed by Brieuc Jeunhomme.
+       (prime_generate_internal): Do not forget to free `prime'.
+
+2004-01-14  Moritz Schulte  <mo@g10code.com>
+
+       * ac.c (gcry_ac_data_set): New argument: flags; slightly
+       rewritten.
+       (gcry_ac_data_get_name, gcry_ac_data_get_index): Likewise.
+       (gcry_ac_key_pair_generate): New argument: misc_data; modified
+       order of arguments.
+       (gcry_ac_key_test): New argument: handle.
+       (gcry_ac_key_get_nbits, gcry_ac_key_get_grip): Likewise.
+       Use GCRY_AC_FLAG_NO_BLINDING instead of
+       GCRY_AC_DATA_FLAG_NO_BLINDING.
+       (gcry_ac_mpi): New member: flags.
+       (gcry_ac_data_search, gcry_ac_data_add): Removed functions.
+
+2003-12-22  Werner Koch  <wk@gnupg.org>
+
+       * primegen.c (is_prime): Release A2.
+
+2003-12-19  Werner Koch  <wk@gnupg.org>
+
+       * md.c: Moved a couple of functions down below the data structure
+       definitions.
+       (struct gcry_md_context): New field ACTUAL_HANDLE_SIZE.
+       (md_open): Set it here.
+       (strcut gcry_md_list): New field ACTUAL_STRUCT_SIZE.
+       (md_enable): Set it here.
+       (md_close): Wipe the context memory.
+       secure memory.
+       * cipher.c (struct gcry_cipher_handle): New field ACTUAL_HANDLE_SIZE.
+       (gcry_cipher_open): Set it here.
+       (gcry_cipher_close): Use it to always wipe out the handle data.
+
+       * ac.c (gcry_ac_open): Make sure HANDLE gets initialized even when
+       the function is not successful.
+       (gcry_ac_close): Allow a NULL handle.
+       (gcry_ac_key_destroy, gcry_ac_key_pair_destroy): Ditto.
+       (gcry_ac_key_get_grip): Return INV_OBJ on error.
+
+       * primegen.c (prime_generate_internal): Fixed error code for
+       failed malloc.  Replaced the !err if chain by gotos.
+       (gcry_prime_group_generator): Remove the extra sanity check.
+
+       * md.c: Minor code and comment cleanups.
+
+2003-12-16  Werner Koch  <wk@gnupg.org>
+
+       * primegen.c (gen_prime): Doc fix.  Thanks to Newton Hammet.
+
+2003-12-11  Werner Koch  <wk@gnupg.org>
+
+       * rndunix.c (slow_poll): Don't use #warning but #error.
+
+       * rndegd.c: Changed indentation.
+       (my_make_filename): Removd the var_arg cruft becuase we
+       don't need it here.  Changed caller.  
+
+       * rndlinux.c: Changed indentation.
+       (open_device): Remove the superfluous stat call and clarify
+       comment.
+
+       * rsa.c: Changed indentation.
+       (secret): Use the standard algorithm if p, q and u are not
+       available.
+       (rsa_blind, rsa_unblind): Renamed from _gcry_rsa_blind,
+       _gcry_rsa_unblind and moved more to the top.
+
+       * md4.c: Changed indentation.  Removed unnecessary casts.
+       * md5.c, rmd160.c, sha1.c, tiger.c: Ditto.
+       * rijndael.c, twofish.c: Ditto.
+       * serpent.c: Removed unnecessary casts.
+       * sha256.c, sha512.c: Ditto.
+
+2003-12-09  Werner Koch  <wk@gnupg.org>
+
+       * dsa.c: Unified indentation style.
+       * elgamal.c: Ditto. 
+       * des.c (des_key_schedule): Code beautifications.
+       * blowfish.c: Changed indentation style.
+       * cast5.c (do_cast_setkey): Ditto.
+
+       * pubkey.c (gcry_pk_encrypt): Replaced the chain of if(!err) tests
+       by straightforward gotos. Other cleanups.
+       (gcry_pk_decrypt): Ditto.
+       (gcry_pk_sign): Ditto.
+       (gcry_pk_verify): Ditto.
+       (gcry_pk_genkey): Ditto.  Use strtoul instead of strtol.
+       (gcry_pk_ctl): Use GPG_ERR_INV_ARG to indicate bad arguments.
+
+2003-12-07  Werner Koch  <wk@gnupg.org>
+
+       * pubkey.c (gcry_pk_register_default): Undef the helper macro.
+       (gcry_pk_map_name): Allow NULL for string.
+       (sexp_to_key): Use memcpy and not strncpy.  Use gcry_free and not
+       free.
+       (sexp_to_sig): Ditto.
+       (sexp_to_enc): Ditto.  Replaced the chain of if(!err) tests by
+       straightforward gotos.
+
+2003-12-05  Werner Koch  <wk@gnupg.org>
+
+       * cipher.c: Documentation cleanups.
+       (gcry_cipher_mode_from_oid): Allow NULL for STRING.
+
+2003-12-03  Werner Koch  <wk@gnupg.org>
+
+       * elgamal.c (sign, do_encrypt, gen_k): Make sure that a small K is
+       only used for encryption.
+
+2003-11-18  Werner Koch  <wk@gnupg.org>
+
+       * random.h (rndw32_set_dll_name): Removed unused prototype.
+
+       * Makefile.am (EXTRA_DIST): Added Manifest.
+
+2003-11-11  Werner Koch  <wk@gnupg.org>
+
+       * Manifest: New.
+
+2003-11-04  Werner Koch  <wk@gnupg.org>
+
+       * md.c (gcry_md_hash_buffer): Use shortcut for SHA1
+       * sha1.c (_gcry_sha1_hash_buffer): New.
+
+       * random.c: Reformatted most functions.
+       (mix_pool): Moved the failsafe_digest from global
+       scope to here.
+       (do_fast_random_poll): Use the generic fucntions even if a fast
+       gathering function has been used.
+       (read_pool): Detect a fork and retry.
+       (gcry_randomize, get_random_bytes): Don't distinguish anymore
+       between weak and strong random.
+       (gcry_create_nonce): New.
+
+2003-10-31  Werner Koch  <wk@gnupg.org>
+
+       * rndw32.c (slow_gatherer_windowsNT): Use a plain buffer for the
+       disk performance values and not the W32 API structure.
+
+       * dsa.c (verify): s/exp/ex/ due to shadowing of a builtin.
+       * elgamal.c (verify): Ditto.
+
+       * ac.c (gcry_ac_data_get_index): s/index/idx/
+       (gcry_ac_data_copy_internal): Remove the cast in _gcry_malloc.
+       (gcry_ac_data_add): Must use gcry_realloc instead of realloc.
+       * pubkey.c (sexp_elements_extract): s/index/idx/ as tribute to the
+       forehackers.
+       (gcry_pk_encrypt): Removed shadowed definition of I. Reordered
+       arguments to malloc for clarity.
+       (gcry_pk_sign, gcry_pk_genkey): Ditto.
+       * primegen.c (prime_generate_internal): s/random/randomlevel/.
+
+2003-10-27  Moritz Schulte  <mo@g10code.com>
+
+       * pubkey.c (gcry_pk_encrypt): Don't forget to deallocate pkey.
+
+2003-10-27  Werner Koch  <wk@gnupg.org>
+
+       * random.c (gcry_random_add_bytes): Return if buflen is zero to
+       avoid gcc warning about unsed parameter.
+       (MASK_LEVEL): Simplified; does now work for signed and unsigned
+       w/o warnings.
+
+       * md.c (md_start_debug): Removed the const from SUFFIX, because
+       this function is called from the control fucntion which does not
+       require const.
+
+       Prefixed all (pubkey,digest,cipher}_spec_* globale variables with
+       _gcry_.
+
+       * ac.c (ac_key_identifiers): Made static.
+
+       * random.c (getfnc_gather_random,getfnc_fast_random_poll): Move
+       prototypes to ..
+       * rand-internal.h: .. here 
+       * random.c (getfnc_gather_random): Include rndw32 gatherer.
+       * rndunix.c, rndw32.c, rndegd.c: Include them here.
+       * rndlinux.c (_gcry_rndlinux_gather_random): Prepend the _gcry_
+       prefix.  Changed all callers.
+       * rndegd.c (_gcry_rndegd_gather_random): Likewise.
+       (_gcry_rndegd_connect_socket): Likewise.
+       * rndunix.c (_gcry_rndunix_gather_random): Likewise.
+       (waitpid): Made static.
+       * rndw32.c: Removed the old and unused winseed.dll cruft.
+       (_gcry_rndw32_gather_random_fast): Renamed from
+       gather_random_fast.
+       (_gcry_rndw32_gather_random): Renamed from gather_random.  Note,
+       that the changes 2003-04-08 somehow got lost.
+
+       * sha512.c (sha512_init, sha384_init): Made static.
+
+       * cipher.c (do_ctr_decrypt): Removed "return" from this void
+       function.
+
+2003-10-24  Moritz Schulte  <mo@g10code.com>
+
+       * serpent.c: Fix an issue on big-endian systems.
+
+       * rndw32.c: Removed IS_MODULE -cruft.
+       * rndlinux.c (rndlinux_gather_random): Likewise.
+
+2003-10-10  Werner Koch  <wk@gnupg.org>
+
+       * primegen.c (gen_prime): Bail out if NBITS is less than 16.
+       (prime_generate_internal): Initialize prime variable to suppress
+       compiler warning.  Check pbits, initialize qbits when passed as
+       zero.
+
+       * primegen.c (prime_generate_internal): New arg
+       ALL_FACTORS. Changed all callers.
+       (gcry_prime_generate): Make the factors arg optional. Request
+       all_factors.  Make sure PRIME is set to NULL even on error.
+       (gcry_prime_group_generator): New.
+       (gcry_prime_release_factors): New.
+
+2003-10-06  Werner Koch  <wk@gnupg.org>
+
+       * primegen.c (gen_prime): Assert that NBITS is never zero, it
+       would cause a segv.
+
+2003-09-28  Moritz Schulte  <mo@g10code.com>
+
+       * ac.c: Include "cipher.h".
+
+2003-09-27  Moritz Schulte  <mo@g10code.com>
+
+       * rndegd.c (do_read): Return nread instead of nbytes; thanks to
+       Michael Caerwyn.
+
+2003-09-04  Werner Koch  <wk@gnupg.org>
+
+       * pubkey.c (_gcry_pk_aliased_algo_name): New.
+       * ac.c (gcry_ac_open): Use it here.
+
+       * Makefile.am (EXTRA_libcipher_la_SOURCES): Add serpent.c
+
+2003-09-02  Moritz Schulte  <mo@g10code.com>
+
+       * primegen.c (gcry_prime_check, gcry_prime_generate): New
+       functions.
+       (prime_generate_internal): New function, based on
+       _gcry_generate_elg_prime.
+       (_gcry_generate_elg_prime): Rewritten as a wrapper for
+       prime_generate_internal.
+
+2003-08-28  Werner Koch  <wk@gnupg.org>
+
+       * pubkey.c (gcry_pk_encrypt): Don't include the flags list in the
+       return value.  This does not make sense and breaks any programs
+       parsing the output strictly (e.g. current gpgsm).
+       (gcry_pk_encrypt): If aliases for the algorithm name exists, take
+       the first one instead of the regular name to adhere to SPKI
+       conventions.
+       (gcry_pk_genkey): Ditto.
+       (gcry_pk_sign): Ditto. Removed unused KEY_ALGO_NAME.
+
+2003-08-19  Moritz Schulte  <mo@g10code.com>
+
+       * cipher.c: Add support for Serpent
+       * serpent.c: New file.
+
+2003-08-10  Moritz Schulte  <moritz@g10code.com>
+
+       * rsa.c (_gcry_rsa_blind, _gcry_rsa_unblind): Declare static.
+
+2003-08-09  Timo Schulz  <twoaday@freakmail.de>
+
+       * random.c (getfnc_gather_random): Don't check NAME_OF_DEV_RANDOM
+       two times, but also the NAME_OF_DEV_URANDOM device.
+       
+2003-08-08  Moritz Schulte  <moritz@g10code.com>
+
+       * pubkey.c (sexp_to_enc): Fixed extraction of S-Expression: do not
+       fail if no `flags' sub S-Expression is found.
+
+2003-07-27  Werner Koch  <wk@gnupg.org>
+
+       * md.c (gcry_md_lookup_func_oid): Allow for empty OID lists.
+
+2003-07-23  Moritz Schulte  <moritz@g10code.com>
+
+       * ac.c (gcry_ac_data_construct): New argument: include_flags, only
+       include `flags' S-expression, if include_flags is true.  Adjust
+       callers.  Thanks for triggering a bug caused by `flags'
+       sub-S-expression where they are not expected to Ralf Schneider.
+
+2003-07-21  Moritz Schulte  <moritz@g10code.com>
+
+       * pubkey.c (gcry_pk_lookup_func_name): Use new member name
+       `aliases' instead of `sexp_names'.
+
+       * ac.c (gcry_ac_key_data_get): New function.
+
+       * cipher.c (gcry_cipher_lookup_func_name): Fix return value.
+
+2003-07-20  Moritz Schulte  <moritz@g10code.com>
+
+       * blowfish.c: Adjusted for new gcry_cipher_spec_t structure.
+       * cast5.c: Likewise.
+       * twofish.c: Likewise.
+       * arcfour.c: Likewise.
+       * rijndael.c (rijndael_oids, rijndael192_oids, rijndael256_oids):
+       New variables, adjust for new gcry_cipher_spec_t structure.
+       * des.c (oids_tripledes): New variable, adjust for new
+       gcry_cipher_spec_t structure.
+
+       * md.c (oid_table): Removed.
+
+       * tiger.c (oid_spec_tiger): New variable.
+       (digest_spec_tiger): Adjusted for new gry_md_spec_t structure.
+
+       * sha512.c (oid_spec_sha512): New variable.
+       (digest_spec_sha512): Adjusted for new gry_md_spec_t structure.
+
+       * sha512.c (oid_spec_sha384): New variable.
+       (digest_spec_sha384): Adjusted for new gry_md_spec_t structure.
+
+       * sha256.c (oid_spec_sha256): New variable.
+       (digest_spec_sha256): Adjusted for new gry_md_spec_t structure.
+
+       * sha1.c (oid_spec_sha1): New variable.
+       (digest_spec_sha1): Adjusted for new gry_md_spec_t structure.
+
+       * rmd160.c (oid_spec_rmd160): New variable.
+       (digest_spec_rnd160): Adjusted for new gry_md_spec_t structure.
+
+       * md5.c (oid_spec_md5): New variable.
+       (digest_spec_md5): Adjusted for new gry_md_spec_t structure.
+
+       * md4.c (oid_spec_md4): New variable.
+       (digest_spec_md4): Adjusted for new gry_md_spec_t structure.
+
+       * crc.c (digest_spec_crc32, digest_spec_crc32_rfc1510,
+       digest_spec_crc32_rfc2440): Adjusted for new gry_md_spec_t
+       structure.
+
+2003-07-19  Moritz Schulte  <moritz@g10code.com>
+
+       * md.c (gcry_md_lookup_func_oid): New function.
+       (search_oid): New function, copied from cipher.c.
+       (gcry_md_map_name): Adjust for new search_oid_interface.
+
+       * cipher.c (oid_table): Removed table.
+       (gcry_cipher_lookup_func_oid): New function.
+       (search_oid): Rewritten to use the module functions.
+       (gcry_cipher_map_name): Adjust for new search_oid interface.
+       (gcry_cipher_mode_from_oid): Likewise.
+
+2003-07-18  Werner Koch  <wk@gnupg.org>
+
+       * md.c (gcry_md_hash_buffer): Convert ERR to gpg_error_t in
+       gpg_strerror.
+
+2003-07-14  Moritz Schulte  <moritz@g10code.com>
+
+       * cipher.c (gcry_cipher_lookup_func_name): Also check the cipher
+       name aliases, not just the primary name.
+       (gcry_cipher_map_name): Remove kludge for aliasing Rijndael to
+       AES.
+
+       * arcfour.c, blowfish.c, cast5.c, des.c, twofish.c: Adjust cipher
+       specification structures.
+
+       * rijndael.c (rijndael_names, rijndael192_names,
+       rijndael256_names): New variables, use them in the cipher
+       specifications.
+
+       * rmd160test.c: Removed file.
+
+       * ac.c, arcfour.c, blowfish.c, cast5.c, cipher.c, des.c, dsa.c,
+       elgamal.c, md.c, pubkey.c, random.c, rijndael.c, rsa.c, twofish.c:
+       Used gcry_err* wrappers for libgpg symbols.
+
+       * primegen.c (gen_prime): Correct the order arguments to
+       extra_check.
+
+2003-07-12  Moritz Schulte  <moritz@g10code.com>
+
+       * ac.c: Replaced all public occurences of gpg_error_t with
+       gcry_error_t.
+       * cipher.c: Likewise.
+       * md.c: Likewise.
+       * pubkey.c: Likewise.
+       * random.c: Likewise.
+
+       * cipher.c: Added support for TWOFISH128.
+
+2003-07-08  Moritz Schulte  <moritz@g10code.com>
+
+       * ac.c (gcry_ac_data_copy_internal): New function, based on
+       gcry_ac_data_copy.
+       (gcry_ac_data_copy): Made public, use gcry_ac_data_copy_internal.
+       (gcry_ac_key_init): Use gcry_ac_data_copy_internal.
+
+2003-07-07  Moritz Schulte  <moritz@g10code.com>
+
+       * ac.c (gcry_ac_data_set): Only release old MPI value if it is
+       different from the new value.  Bug reported by Simon Josefsson
+       <jas@extundo.com>.
+
+       * pubkey.c (gcry_pk_list): New function.
+       * md.c (gcry_md_list): New function.
+
+       * ac.c (gcry_ac_key_pair_generate): Fix calculation of format
+       string size.
+
+2003-07-05  Moritz Schulte  <moritz@g10code.com>
+
+       * md.c: Named struct of digest_table `digest_table_entry'.
+       (digest_table_entry): New member: algorithm; filled in.
+       (digest_table_entry): Removed unused member: flags.
+       (gcry_md_register): New argument: algorithm_id, filled in.
+       (gcry_md_register_default): Used algorithm ID from module
+       structure.
+       (gcry_md_map_name): Likewise.
+       (md_enable): Likewise.
+       (md_read): Likewise.
+       (gcry_md_info): Likewise.
+
+       * pubkey.c: Named truct for pubkey_table `pubkey_table_entry'.
+       (pubkey_table_entry): New member: algorithm; filled in.
+       (gcry_pk_register_default): Used algorithm ID from pubkey_table.
+       (gcry_pk_register): New argument: algorithm_id, filled in.
+       (gcry_pk_map_name): Used algorithm ID from module structure.
+       (gcry_pk_decrypt): Likewise.
+       (gcry_pk_encrypt): Likewise.
+       (gcry_pk_verify): Likewise.
+       (gcry_pk_sign): Likewise.
+       (gcry_pk_testkey): Likewise.
+       (gcry_pk_genkey): Likewise.
+       (gcry_pk_get_nbits): Likewise.
+       (sexp_to_key): Removed unused variable: algo.
+       (sexp_to_sig): Likewise.
+
+       * cipher.c: Named struct for cipher_table `cipher_table_entry'.
+       (cipher_table_entry): New member: algorithm; filled in.
+       (gcry_cipher_register_default): Used algorithm ID from
+       cipher_table.
+       (gcry_cipher_register): New argument: algorithm_id, filled in.
+       (gcry_cipher_map_name): Used algorithm ID from module structure.
+
+       * arcfour.c (cipher_spec_arcfour): Removed algorithm ID.
+       * blowfish.c (cipher_spec_blowfish): Likewise.
+       * cast5.c (cipher_spec_cast5): Likewise.
+       * crc.c (digest_spec_crc32): Likewise.
+       * crc.c (digest_spec_crc32_rfc1510): Likewise.
+       * crc.c (digest_spec_crc32_rfc2440): Likewise.
+       * des.c (cipher_spec_des): Likewise.
+       * des.c (cipher_spec_tripledes): Likewise.
+       * dsa.c (pubkey_spec_dsa): Likewise.
+       * elgamal.c (pubkey_spec_elg): Likewise.
+       * md4.c (digest_spec_md4): Likewise.
+       * md5.c (digest_spec_md5): Likewise.
+       * aes.c (cipher_spec_aes): Likewise.
+       * aes.c (cipher_spec_aes192): Likewise.
+       * aes.c (cipher_spec_aes256): Likewise.
+       * rsa.c (pubkey_spec_rsa): Likewise.
+       * sha1.c (digest_spec_sha1): Likewise.
+       * sha256.c (digest_spec_sha256): Likewise.
+       * sha512.c (digest_spec_sha512): Likewise.
+       * tiger.c (digest_spec_tiger): Likewise.
+       * twofish.c (cipher_spec_twofish): Likewise.
+       * twofish.c (cipher_spec_twofish128): Likewise.
+
+       * Makefile.am (EXTRA_libcipher_la_SOURCES): Fix list of source
+       files; reported by Simon Josefsson <jas@extundo.com>.
+
+       * pubkey.c: Replaced all occurences of `id' with `algorithm',
+       since `id' is a keyword in obj-c.
+       * md.c: Likewise.
+       * cipher.c: Likewise.
+
+       * crc.c, md4.c, md5.c, rmd160.c, sha1.c, sha256.c, tiger.c:
+       Replaced all occurences of gcry_digest_spec_t with gcry_md_spec_t.
+
+       * dsa.c, rsa.c, elgamal.c: Replaced all occurencens of
+       gcry_pubkey_spec_t with gcry_pk_spec_t.
+
+       * md.c: Replaced all occurences of gcry_digest_spec_t with
+       gcry_md_spec_t.
+       (gcry_digest_register_default): Renamed to ...
+       (gcry_md_register_default): ... this; adjusted callers.
+       (gcry_digest_lookup_func_name): Renamed to ...
+       (gcry_md_lookup_func_name): ... this; adjusted callers.
+       (gcry_digest_lookup_name): Renamed to ...
+       (gcry_md_lookup_name): ... this; adjusted callers.
+       (gcry_digest_register): Renamed to ...
+       (gcry_md_register): ... this.
+       (gcry_digest_unregister): Renamed to ...
+       (gcry_md_unregister): ... this.
+
+       * pubkey.c (gcry_pubkey_register): Renamed to ...
+       (gcry_pk_register): ... this.
+       (gcry_pubkey_unregister): Renamed to ...
+       (gcry_pk_unregister): ... this.
+       Replaced all occurences of gcry_pubkey_spec_t with gcry_pk_spec_t.
+       (gcry_pubkey_register_default): Renamed to ...
+       (gcry_pk_register_default): ... this; adjusted callers.
+       (gcry_pubkey_lookup_func_name): Renamed to ...
+       (gcry_pk_lookup_func_name): ... this; adjusted callers.
+       (gcry_pubkey_lookup_name): Renamed to ...
+       (gcry_pk_lookup_name): ... this; adjusted callers.
+
+       * md.c (gcry_md_hash_buffer): Fix error checking.  Thanks to Simon
+       Josefsson <jas@extunde.com>.
+
+2003-07-04  Moritz Schulte  <moritz@g10code.com>
+
+       * cipher.c (gcry_cipher_list): New function.
+
+2003-07-01  Moritz Schulte  <moritz@g10code.com>
+
+       * pubkey.c (sexp_to_sig): Accept a `flags' S-expression to be more
+       consistent with sexp_to_enc.
+
+2003-06-30  Moritz Schulte  <moritz@g10code.com>
+
+       * Makefile.am (libcipher_la_SOURCES): Added: ac.c.
+
+       * pubkey.c (_gcry_pk_module_lookup): New function.
+       (_gcry_pk_module_release): New function.
+
+2003-06-29  Moritz Schulte  <moritz@g10code.com>
+
+       * ac.c: New file.
+
+2003-06-26  Werner Koch  <wk@gnupg.org>
+
+       * md.c (gcry_md_hash_buffer): Trigger BUG correcly with new API.
+
+2003-06-19  Werner Koch  <wk@gnupg.org>
+
+       * md.c (gcry_md_is_enabled): Fixed. 
+
+2003-06-18  Werner Koch  <wk@gnupg.org>
+
+       * cipher.c (gcry_cipher_get_algo_keylen): New.
+       (gcry_cipher_get_algo_blklen): New.
+
+2003-06-18  Moritz Schulte  <moritz@g10code.com>
+
+       * arcfour.c, cipher.c, blowfish.c, md.c, cast5.c, pubkey.c, crc.c,
+       des.c, dsa.c, elgamal.c, md4.c, md5.c, random.c, rijndael.c,
+       rmd160.c, rsa.c, sha1.c, sha256.c, sha512.c, tiger.c, twofish.c:
+       Replaced older types GcryDigestSpec, GcryCipherSpec and
+       GcryPubkeySpec with newer types: gcry_digest_spec_t,
+       gcry_cipher_spec_t and gcry_pubkey_spec_t.
+
+       * md.c (gcry_digest_id_new): Removed function.
+       (gcry_digest_register): Removed code for generating a new module
+       ID.
+
+       * pubkey.c (gcry_pubkey_id_new): Removed function.
+       (gcry_pubkey_register): Removed code for generating a new module
+       ID.
+
+       * cipher.c, md.c, pubkey.c: Replace old type GcryModule with newer
+       one: gcry_module_t.
+       (gcry_cipher_id_new): Removed function.
+       (gcry_cipher_register): Removed code for generating a new module
+       ID.
+
+       * cipher.c (gcry_cipher_register): Adjust call to
+       _gcry_module_add.
+       (gcry_cipher_register_default): Likewise.
+       * pubkey.c (gcry_pubkey_register_default): Likewise.
+       (gcry_pubkey_register): Likewise.
+       * md.c (gcry_digest_register_default): Likewise.
+       (gcry_digest_register): Likewise.
+
+       * md.c (gcry_digest_lookup_func_id): Removed function.
+       (gcry_digest_lookup_id): Likewise.
+       (gcry_digest_id_new): Use _gcry_module_lookup_id instead of
+       gcry_digest_lookup_id.
+       (digest_algo_to_string): Likewise.
+       (check_digest_algo): Likewise.
+       (md_enable): Likewise.
+       (md_digest_length): Likewise.
+       (md_asn_oid): Likewise.
+
+       * pubkey.c (gcry_pubkey_lookup_id): Removed function.
+       (gcry_pubkey_lookup_func_id): Likewise.
+       (gcry_pubkey_id_new): Use _gcry_module_lookup_id instead of
+       gcry_pubkey_id_new.
+       (gcry_pk_algo_name): Likewise.
+       (disable_pubkey_algo): Likewise.
+       (check_pubkey_algo): Likewise.
+       (pubkey_get_npkey): Likewise.
+       (pubkey_get_nskey): Likewise.
+       (pubkey_get_nsig): Likewise.
+       (pubkey_get_nenc): Likewise.
+       (pubkey_generate): Likewise.
+       (pubkey_check_secret_key): Likewise.
+       (pubkey_encrypt): Likewise.
+       (pubkey_decrypt): Likewise.
+       (pubkey_sign): Likewise.
+       (pubkey_verify): Likewise.
+       (gcry_pk_algo_info): Likewise.
+
+       * cipher.c (gcry_cipher_lookup_func_id): Removed function.
+       (gcry_cipher_lookup_id): Likewise.
+       (cipher_algo_to_string): use _gcry_module_lookup_id instead of
+       gcry_cipher_lookup_id.
+       (disable_cipher_algo): Likewise.
+       (check_cipher_algo): Likewise.
+       (cipher_get_blocksize): Likewise.
+       (gcry_cipher_open): Likewise.
+       (gcry_cipher_id_new): Likewise.
+
+2003-06-17  Moritz Schulte  <moritz@g10code.com>
+
+       * Makefile.am (GCRYPT_MODULES): Set to @GCRYPT_CIPHERS@,
+       @GCRYPT_PUBKEY_CIPHERS@, @GCRYPT_DIGESTS@ and @GCRYPT_RANDOM@.
+       (libcipher_la_DEPENDENCIES): Set to $(GCRYPT_MODULES).
+       (libcipher_la_LIBADD): Likewise.
+       (AM_CFLAGS): Added: @GPG_ERROR_CFLAGS@.
+       (EXTRA_libcipher_la_SOURCES): Added all conditional sources.
+
+       * md.c (md_open): Use _gcry_fast_random_poll instead of
+       fast_random_poll.
+       * cipher.c (gcry_cipher_open): Likewise.
+
+       * random.h (fast_random_poll): Removed macro.
+
+       * blowfish.c, md4.c, md5.c, rmd160.c, sha1.c, sha256.c, sha512.c,
+       tiger.c: Use Autoconf's WORDS_BIGENDIAN instead of our own
+       BIG_ENDIAN_HOST.
+
+2003-06-16  Moritz Schulte  <moritz@g10code.com>
+
+       * random.c (getfnc_gather_random): Do not special-case
+       USE_ALL_RANDOM_MODULES, make it the default.
+
+       * dsa.c: Replace last occurences of old type names with newer
+       names (i.e. replace MPI with gcry_mpi_t).
+       * elgamal.c: Likewise.
+       * primegen.c: Likewise.
+       * pubkey.c: Likewise.
+       * rsa.c: Likewise.
+
+2003-06-14  Moritz Schulte  <moritz@g10code.com>
+
+       * des.c (des_setkey): Add selftest check.
+       (tripledes_set3keys): Likewise.
+       (do_tripledes_setkey): Remove selftest check.
+       (do_des_setkey): Likewise.
+
+2003-06-11  Moritz Schulte  <moritz@g10code.com>
+
+       * md.c (_gcry_md_init): New function.
+       * cipher.c (_gcry_cipher_init): New function.
+       * pubkey.c (_gcry_pk_init): New function.
+
+2003-06-13  Werner Koch  <wk@gnupg.org>
+
+       * md.c (gcry_md_get_algo): Reverted to old API.  This is a
+       convenience function anyway and error checking is not approriate.
+       (gcry_md_is_secure): New.
+       (gcry_md_is_enabled): New.
+
+2003-06-12  Werner Koch  <wk@gnupg.org>
+
+       * cipher.c (gcry_cipher_open): Make sure HANDLE is set to NULL on
+       error.
+
+2003-06-11  Werner Koch  <wk@gnupg.org>
+
+       * md.c (gcry_md_open): Make sure H receives either NULL or an
+       valid handle.
+       (gcry_md_copy): Swapped arguments so that it is more in lione with
+       md_open and most other API fucntions like memcpy (destination
+       comes first).  Make sure HANDLE is set to NULL on error.
+       
+       * rijndael.c (do_encrypt): Hack to force correct alignment.  It
+       seems not to be not sufficient, though.  We should rework this
+       fucntions and remove all these ugly casts.  Let the compiler
+       optimize or have an assembler implementation.
+
+2003-06-09  Moritz Schulte  <moritz@g10code.com>
+
+       * Makefile.am: Removed rules serpent, since that is not commited
+       yet.
+
+2003-06-08  Moritz Schulte  <moritz@g10code.com>
+
+       * pubkey.c (gcry_pk_encrypt): Improve calculation for size of the
+       format string.
+
+2003-06-07  Moritz Schulte  <moritz@g10code.com>
+
+       * arcfour.c, bithelp.h, blowfish.c, cast5.c, cipher.c, crc.c,
+       des.c, dsa.c, elgamal.c, md4.c, md5.c, md.c, primegen.c, pubkey.c,
+       rand-internal.h, random.c, random.h, rijndael.c, rmd160.c,
+       rmd160test.c, rmd.h, rndeged.c, rndlinux.c, rndunix.c, rndw32.c,
+       rsa.c, sha1.c, sha256.c, sha512.c, tiger.c, twofish.c: Edited all
+       preprocessor instructions to remove whitespace before the '#'.
+       This is not required by C89, but there are some compilers out
+       there that don't like it.  Replaced any occurence of the now
+       deprecated type names with the new ones.
+       
+2003-06-04  Moritz Schulte  <moritz@g10code.com>
+
+       * pubkey.c (gcry_pk_encrypt): Construct an arg_list and use
+       gcry_sexp_build_array instead of gcry_sexp_build.
+       (gcry_pk_sign): Likewise.
+       (gcry_pk_genkey): Likewise.
+
+2003-06-01  Moritz Schulte  <moritz@g10code.com>
+
+       * dsa.c (_gcry_dsa_generate): Do not check wether the algorithm ID
+       does indeed belong to DSA.
+       (_gcry_dsa_sign): Likewise.
+       (_gcry_dsa_verify): Likewise.
+       (_gcry_dsa_get_nbits): Likewise.
+
+       * elgamal.c (_gcry_elg_check_secret_key): Do not check wether the
+       algorithm ID does indeed belong to ElGamal.
+       (_gcry_elg_encrypt): Likewise.
+       (_gcry_elg_decrypt): Likewise.
+       (_gcry_elg_sign): Likewise.
+       (_gcry_elg_verify): Likewise.
+       (_gcry_elg_get_nbits): Likewise.
+       (_gcry_elg_generate): Likewise.
+
+       * rsa.c (_gcry_rsa_generate): Do not check wether the algorithm ID
+       does indeed belong to RSA.
+       (_gcry_rsa_encrypt): Likewise.
+       (_gcry_rsa_decrypt): Likewise.
+       (_gcry_rsa_sign): Likewise.
+       (_gcry_rsa_verify): Likewise.
+       (_gcry_rsa_get_nbits): Likewise.
+
+2003-05-30  Moritz Schulte  <moritz@g10code.com>
+
+       * md.c (md_get_algo): Return zero in case to algorithm is enabled.
+
+       * md.c (gcry_md_info): Adjusted for new no-errno-API.
+       (md_final): Likewise.
+       (gcry_md_get_algo): Likewise.
+       * pubkey.c (gcry_pk_get_keygrip): Likewise.
+       (gcry_pk_ctl): Likewise.
+       (gcry_pk_algo_info): Likewise.
+       * des.c (selftest): Likewise.
+
+2003-05-29  Moritz Schulte  <moritz@g10code.com>
+
+       * md.c (md_enable): Do not forget to release module on error.
+       (gcry_md_open): Adjusted for new no-errno-API.
+       (md_open): Likewise.
+       (md_copy): Likewise.
+       (gcry_md_copy): Likewise.
+       (gcry_md_setkey): Likewise.
+       (gcry_md_algo_info): Likewise.
+
+       * cipher.c (gcry_cipher_open): Adjusted for new no-errno-API and
+       also fixed a locking bug.
+       (gcry_cipher_encrypt): Adjusted for new no-errno-API.
+       (gcry_cipher_decrypt): Likewise.
+       (gcry_cipher_ctl): Likewise.
+       (gcry_cipher_info): Likewise.
+       (gcry_cipher_algo_info): Likewise.
+
+2003-05-28  Moritz Schulte  <moritz@g10code.com>
+
+       * md.c (md_enable): Adjusted for libgpg-error.
+       (gcry_md_enable): Likewise.
+       (gcry_digest_register_default): Likewise.
+       (gcry_digest_register): Likewise.
+       (check_digest_algo): Likewise.
+       (prepare_macpads): Likewise.
+       (gcry_md_setkey): Likewise.
+       (gcry_md_ctl): Likewise.
+       (gcry_md_get): Likewise.
+       (gcry_md_algo_info): Likewise.
+       (gcry_md_info): Likewise.
+       * dsa.c (_gcry_dsa_generate): Likewise.
+       (_gcry_dsa_check_secret_key): Likewise.
+       (_gcry_dsa_sign): Likewie.
+       (_gcry_dsa_verify): Likewise.
+       * twofish.c (do_twofish_setkey): Likewise.
+       (twofish_setkey): Likewise.
+       * cipher.c (gcry_cipher_register): Likewise.
+
+2003-05-25  Moritz Schulte  <moritz@g10code.com>
+
+       * rijndael.c (do_setkey): Adjusted for libgpg-error.
+       (rijndael_setkey): Likewise.
+       * random.c (gcry_random_add_bytes): Likewise.
+       * elgamal.c (_gcry_elg_generate): Likewise.
+       (_gcry_elg_check_secret_key): Likewise.
+       (_gcry_elg_encrypt): Likewise.
+       (_gcry_elg_decrypt): Likewise.
+       (_gcry_elg_sign): Likewise.
+       (_gcry_elg_verify): Likewise.
+       * rsa.c (_gcry_rsa_generate): Likewise.
+       (_gcry_rsa_check_secret_key): Likewise.
+       (_gcry_rsa_encrypt): Likewise.
+       (_gcry_rsa_decrypt): Likewise.
+       (_gcry_rsa_sign): Likewise.
+       (_gcry_rsa_verify): Likewise.
+       * pubkey.c (dummy_generate, dummy_check_secret_key, dummy_encrypt,
+       dummy_decrypt, dummy_sign, dummy_verify): Likewise.
+       (gcry_pubkey_register): Likewise.
+       (check_pubkey_algo): Likewise.
+       (pubkey_generate): Likewise.
+       (pubkey_check_secret_key): Likewise.
+       (pubkey_encrypt): Likewise.
+       (pubkey_decrypt): Likewise.
+       (pubkey_sign): Likewise.
+       (pubkey_verify): Likewise.
+       (sexp_elements_extract): Likewise.
+       (sexp_to_key): Likewise.
+       (sexp_to_sig): Likewise.
+       (sexp_to_enc): Likewise.
+       (sexp_data_to_mpi): Likewise.
+       (gcry_pk_encrypt): Likewise.
+       (gcry_pk_decrypt): Likewise.
+       (gcry_pk_sign): Likewise.
+       (gcry_pk_verify): Likewise.
+       (gcry_pk_testkey): Likewise.
+       (gcry_pk_genkey): Likewise.
+       (gcry_pk_ctl): Likewise.
+       * cipher.c (dummy_setkey): Likewise.
+       (check_cipher_algo): Likewise.
+       (gcry_cipher_open): Likewise.
+       (cipher_setkey): Likewise.
+       (gcry_cipher_ctl): Likewise.
+       (cipher_encrypt): Likewise.
+       (gcry_cipher_encrypt): Likewise.
+       (cipher_decrypt): Likewise.
+       (gcry_cipher_decrypt): Likewise.
+       (gcry_cipher_info): Likewise.
+       (gcry_cipher_algo_info): Likewise.
+       * cast5.c (cast_setkey): Likewise.
+       (do_cast_setkey): Likewise.
+       * arcfour.c (arcfour_setkey): Likewise.
+       (do_arcfour_setkey): Likewise.
+       * blowfish.c (do_bf_setkey): Likewise.
+       (bf_setkey): Likewise.
+       * des.c (do_des_setkey): Likewise.
+       (do_tripledes_setkey): Likewise.
+
+2003-05-22  Moritz Schulte  <moritz@g10code.com>
+
+       * tiger.c: Merged code ussing the U64_C macro from GnuPG.
+
+       * sha512.c: Likewise.
+
+2003-05-17  Moritz Schulte  <moritz@g10code.com>
+
+       * pubkey.c (gcry_pk_genkey): Fix type: acquire a lock, instead of
+       releasing it.
+
+2003-05-11  Moritz Schulte  <moritz@g10code.com>
+
+       * pubkey.c (gcry_pk_testkey): Call REGISTER_DEFAULT_CIPHERS.
+       (gcry_pk_ctl): Likewise.
+
+2003-04-27  Moritz Schulte  <moritz@g10code.com>
+
+       * pubkey.c (gcry_pk_genkey): Release sexp after extracted data has
+       been used.
+
+       * md.c (gcry_md_get_algo_dlen): Simplified, simply call
+       md_digest_length to do the job.
+
+       * des.c (do_des_setkey): Check for selftest failure not only
+       during initialization.
+       (do_tripledes_setkey): Include check for selftest failure.
+
+       * pubkey.c (gcry_pubkey_register_default): New macro
+       `pubkey_use_dummy', use it.
+
+       * elgamal.c (elg_names): New variable.
+       (pubkey_spec_elg): Include elg_names.
+
+       * dsa.c (dsa_names): New variable.
+       (pubkey_spec_dsa): Include dsa_names.
+
+       * rsa.c (rsa_names): New variable.
+       (pubkey_spec_rsa): Include rsa_names.
+
+       * pubkey.c (gcry_pubkey_lookup_func_name): Compare name also with
+       the names listed in `sexp_names'.
+
+2003-04-24  Moritz Schulte  <moritz@g10code.com>
+
+       * pubkey.c (sexp_to_key): New variables: module, pubkey.  Adjusted
+       to new module interface.
+       (sexp_to_key): Changend type of argument `retalgo' from `int *' to
+       `GcryModule **'.  Adjusted all callers.  Removed argument:
+       r_algotblidx.
+       (sexp_to_sig): Changend type of argument `retalgo' from `int *' to
+       `GcryModule **'.  Adjusted all callers.
+       (sexp_to_enc): Likewise.
+
+       (pubkey_get_npkey, pubkey_get_nskey, pubkey_get_nsig,
+       pubkey_get_nenc): Use strlen to find out the number.
+
+       * rsa.c: Adjust pubkey_spec_rsa to new internal interface.
+       * dsa.c: Likewise.
+       * elgamal.c: Likewise.
+
+2003-04-17  Moritz Schulte  <moritz@g10code.com>
+
+       * pubkey.c (sexp_elements_extract): New function.
+       * pubkey.c (sexp_to_key): Removed variable `idx', added `err', use
+       sexp_elements_extract.
+       (sexp_to_sig): Likewise.
+       (sexp_to_enc): Likewise.
+
+       * pubkey.c: Terminate list correctly.
+       * md.c: Include sha512/sha384 in digest_table.
+
+2003-04-16  Moritz Schulte  <moritz@g10code.com>
+
+       * Makefile.am: Include support for sha512.c.
+
+       * sha512.c: New file, merged from GnuPG, with few modifications
+       for libgcrypt.
+
+       * rand-internal.h: Removed declarations for constructor functions.
+
+       * md.c (md_copy): Call _gcry_module_use for incrementing the usage
+       counter of the digest modules.
+
+       * rsa.c: Do not include "rsa.h".
+       * dsa.c: Do not include "dsa.h".
+       * elgamal.c: Do not include "elgamal.h".
+       * des.c: Do not include "des.h".
+       * cast5.c: Do not include "cast5.h".
+       * blowfish.c: Do not include "blowfish.h".
+       * arcfour.c: Do not include "arcfour.h".
+
+       * Makefile.am (libcipher_la_DEPENDENCIES): Removed.
+       (libcipher_la_LIBADD): Removed.
+       Use Automake conditionals for conditional compilation.
+
+2003-04-13  Moritz Schulte  <moritz@g10code.com>
+
+       * cipher.c (gcry_cipher_open): Call REGISTER_DEFAULT_CIPHERS.
+
+       * md.c (gcry_md_list): New member: module.
+       (md_enable): New variable: module, changed use of module and
+       digest.
+       (md_enable): Initialize member: module.
+       (md_close): Call _gcry_module_release.
+
+       * cipher.c (gcry_cipher_open): New variable: module, changed use of
+       module and cipher.
+       (struct gcry_cipher_handle): New member: module.
+       (gcry_cipher_open): Initialize member: module.
+       (gcry_cipher_close): Call _gcry_module_release.
+
+2003-04-09  Moritz Schulte  <moritz@g10code.com>
+       
+       * cipher.c: Include "ath.h".
+       * md.c: Likewise.
+       * pubkey.c: Likewise.
+
+       * cipher.c (ciphers_registered_lock): New variable.
+       * md.c (digests_registered_lock): New variable.
+       * pubkey.c (pubkeys_registered_lock): New variable.
+
+       * rndlinux.c (gnupgext_version, func_table): Removed definitions.
+       (gnupgext_enum_func): Removed function.
+       (_gcry_rndlinux_constructor): Removed function.
+
+       * rndegd.c (gnupgext_version, func_table): Removed definitions.
+       (gnupgext_enum_func): Removed function.
+       (_gcry_rndegd_constructor): Removed function.
+
+       * rndunix.c (gnupgext_version, func_table): Removed definitions.
+       (gnupgext_enum_func): Removed function.
+       (_gcry_rndunix_constructor): Removed function.
+
+       * rndw32.c (gnupgext_version, func_table): Removed definitions.
+       (gnupgext_enum_func): Removed function.
+       (_gcry_rndw32_constructor): Removed function.
+
+       * rndegd.c (rndegd_connect_socket): Simplify code for creating the
+       egd socket address.
+       (rndegd_connect_socket): Call log_fatal use instead of
+       g10_log_fatal.
+       (egd_gather_random): Renamed to ...
+       (rndegd_gather_random): ... here.
+
+2003-04-08  Moritz Schulte  <moritz@g10code.com>
+
+       * rndlinux.c: Do not include "dynload.h".
+       * rndunix.c: Likewise.
+       * rndw32.c: Likewise.
+
+       * rndegd.c (rndegd_connect_socket): Factored out from ...
+       (egd_gather_random): here; call it.
+       (egd_socket): New variable.
+       (egd_gather_random): Initialize fd with egd_socket, do not declare
+       fd static.
+       (do_read): Merged few changes from GnuPG. FIXME - not finished?
+       Do not include "dynload.h".
+
+       * rndw32.c (gather_random): Renamed to rndw32_gather_random, do
+       not declare static.
+       (gather_random_fast): Renamed to rndw32_gather_random_fast, do not
+       declare static.
+
+       * rndunix.c (gather_random): Renamed to rndunix_gather_random, do
+       not declare static.
+       * rndegd.c (gather_random): Renamed to rndegd_gather_random, do
+       not declare static.
+       * rndlinux.c (gather_random): Renamed to rndlinux_gather_random,
+       do not declare static.
+
+2003-04-07  Moritz Schulte  <moritz@g10code.com>
+
+       * Makefile.am (libcipher_la_SOURCES): Removed construct.c.
+       (libcipher_la_SOURCES): Added sha1.c, sha256.c, rmd160.c, md4.c,
+       md5.c, tiger.c and crc.c
+       (EXTRA_PROGRAMS): Removed sha1, sha256, rmd160, md4, md5, tiger
+       and crc.  Removed definitions: EXTRA_md4_SOURCES,
+       EXTRA_md5_SOURCES, EXTRA_rmd160_SOURCES, EXTRA_sha1_SOURCES,
+       EXTRA_sha256_SOURCES, EXTRA_tiger_SOURCES and EXTRA_crc_SOURCES,
+       BUILT_SOURCES, DISTCLEANFILES.
+
+       * pubkey.c: Do not include "elgamal.h", "dsa.h" and "rsa.h".
+
+       * Makefile.am (libcipher_la_SOURCES): Removed rsa.h, elgamal.h,
+       dsa.h, des.h, cast5.h, arcfour.h and blowfish.h.
+
+       * rsa.h: Removed file.
+       * elgamal.h: Removed file.
+       * dsa.h: Removed file.
+       * des.h: Removed file.
+       * cast5.h: Removed file.
+       * arcfour.h: Removed file.
+       * blowfish.h: Removed file.
+
+       * Makefile.am (libcipher_la_SOURCES): Removed dynload.c and
+       dynload.h.
+
+       * rsa.c (pubkey_spec_rsa): New variable.
+       * dsa.c (pubkey_spec_rsa): New variable.
+       * elgamal.c (pubkey_spec_elg): New variable.
+       
+       * rsa.c (_gcry_rsa_get_info): Removed function.
+       * elgamal.c (_gcry_elg_get_info): Removed function.
+       * dsa.c (_gcry_dsa_get_info): Removed function.
+
+       * tiger.c (tiger_get_info): Removed function.
+       (gnupgext_version, func_table): Removed definitions.
+       (gnupgext_enum_func): Removed function.
+       (_gcry_tiger_constructor): Removed function.
+       
+       * sha1.c (sha1_get_info): Removed function.
+       (gnupgext_version, func_table): Removed definitions.
+       (gnupgext_enum_func): Removed function.
+       (_gcry_sha1_constructor): Removed function.
+
+       * sha256.c (sha256_get_info): Removed function.
+       (gnupgext_version, func_table): Removed definitions.
+       (gnupgext_enum_func): Removed function.
+       (_gcry_sha256_constructor): Removed function.
+
+       * rmd160.c (rmd160_get_info): Removed function.
+       (gnupgext_version, func_table): Removed definitions.
+       (gnupgext_enum_func): Removed function.
+       (_gcry_rmd160_constructor): Removed function.
+
+       * md5.c (md5_get_info): Removed function.
+       (gnupgext_version, func_table): Removed definitions.
+       (gnupgext_enum_func): Removed function.
+       (_gcry_md5_constructor): Removed function.
+
+       * md4.c (md4_get_info): Removed function.
+       (gnupgext_version, func_table): Removed definitions.
+       (gnupgext_enum_func): Removed function.
+       (_gcry_md4_constructor): Removed function.
+
+       * crc.c (crc_get_info): Removed function.
+
+       * arcfour.c (do_arcfour_setkey): Changed type of context argument
+       to `void *', added local variable for cast, adjusted callers.
+       (arcfour_setkey): Likewise.
+       (encrypt_stream): Likewise.
+       * cast5.c (cast_setkey): Likewise.
+       (encrypt_block): Likewise.
+       * rijndael.c (rijndael_setkey): Likewise.
+       (rijndael_encrypt): Likewise.
+       (rijndael_decrypt): Likewise.
+       * twofish.c (twofish_setkey): Likewise.
+       (twofish_encrypt): Likewise.
+       (twofish_decrypt): Likewise.
+       * des.c (do_des_setkey): Likewise.
+       (do_des_encrypt): Likewise.
+       (do_des_encrypt): Likewise.
+       (do_tripledes_encrypt): Likewise.
+       (do_tripledes_encrypt): Likewise.
+       * blowfish.c (bf_setkey: Likewise.
+       (encrypt_block): Likewise.
+       (decrypt_block): Likewise.
+       
+       * arcfour.c (encrypt_stream): Likewise.
+
+       * rijndael.c (gnupgext_version, func_table): Removed definitions.
+       (gnupgext_enum_func) Removed function.  
+       
+       * twofish.c (gnupgext_version, func_table): Removed definitions.
+       (gnupgext_enum_func) Removed function.  
+
+       * cast5.c (CIPHER_ALGO_CAST5): Removed.
+
+       * blowfish.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Removed macros.
+       (CIPHER_ALGO_BLOWFISH): Removed symbol.
+       * cast5.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Likewise.
+       * des.c (selftest_failed): Removed.
+       (initialized): New variable.
+       (do_des_setkey): Run selftest, if not yet done.
+       (FNCCAST_SETKEY, FNCCAST_CRYPT): Removed macros.
+
+       * arcfour.c (_gcry_arcfour_get_info): Removed function.
+       * blowfish.c (_gcry_blowfish_get_info): Removed function.
+       * cast5.c (_gcry_cast5_get_info): Removed function.
+       * des.c (_gcry_des_get_info): Removed function.
+       * rijndael.c (_gcry_rijndael_get_info): Removed function.
+       * twofish.c (_gcry_twofish_get_info): Removed function.
+
+       * arcfour.c (cipher_spec_arcfour): New variable.
+       * twofish.c (cipher_spec_twofish, cipher_spec_twofish128): New
+       variables.
+       * rijndael.c (cipher_spec_aes, cipher_spec_aes192,
+       cipher_spec256): New variables.
+       * des.c (cipher_spec_des, cipher_spec_tripledes): New variables.
+       * cast5.c (cipher_spec_cast5): New variable.
+       * blowfish.c (cipher_spec_blowfish): Likewise.
+       
+       * twofish.c: Do not include "dynload.h".
+       * rijndael.c: Likewise.
+       * des.c: Likewise.
+       * cast5.c: Likewise.
+       * blowfish.c: Likewise.
+       * cipher.c: Likewise.
+       * crc.c: Likewise.
+       * md4.c: Likewise.
+       * md5.c: Likewise.
+       * md.c: Likewise.
+       * pubkey.c: Likewise.
+       * rijndael.c: Likewise.
+       * sha1.c: Likewise.
+       * sha256.c: Likewise.
+
+       * arcfour.c: Include "cipher.h".
+       * twofish.c: Likewise.
+       * rijndael.c: Likewise.
+       * des.c: Likewise.
+       * cast5.c: Likewise.
+       * blowfish.c: Likewise.
+
+       * twofish.c (twofish_setkey): Declared argument `key' const.
+       (twofish_encrypt): Declared argument `inbuf' const.
+       (twofish_decrypt): Likewise.
+
+       * rijndael.c (rijndael_setkey): Declared argument `key' const.
+       (rijndael_encrypt): Declared argument `inbuf' const.
+       (rijndael_decrypt): Likewise.
+
+       * des.c (do_des_setkey): Declared argument `key' const.
+       (do_tripledes_setkey): Likewise.
+       (do_des_encrypt): Declared argument `inbuf' const.
+       (do_des_decrypt): Likewise.
+       (do_tripledes_encrypt): Likewise.
+       (do_tripledes_decrypt): Likewise.
+
+       * cast5.c (encrypt_block): Declared argument `inbuf' const.
+       (decrypt_block): Likewise.
+       (cast_setkey): Declared argument `key' const.
+
+       * blowfish.c (do_bf_setkey): Declared argument `key' const.
+       (encrypt_block): Declared argument `inbuf' const.
+       (encrypt_block): Likewise.
+
+       
+
+       * cipher.c: Remove CIPHER_ALGO_DUMMY related code.
+       Removed struct cipher_table_s.
+       Changed definition of cipher_table.
+       Removed definition of disabled_algos.
+       (ciphers_registered, default_ciphers_registered): New variables.
+       (REGISTER_DEFAULT_CIPHERS): New macro.
+       (dummy_setkey): Declared argument `key' const.
+       (dummy_encrypt_block): Declared argument `inbuf' const.
+       (dummy_encrypt_block): Likewise.
+       (dummy_encrypt_stream): Likewise.
+       (dummy_encrypt_stream): Likewise.
+       (dummy_setkey): Use `unsigned char' instead of `byte'.
+       (dummy_encrypt_block): Likewise.
+       (dummy_decrypt_block): Likewise.
+       (dummy_encrypt_stream): Likewise.
+       (dummy_decrypt_stream): Likewise.
+       (gcry_cipher_register_default): New function.
+       (gcry_cipher_lookup_func_id): New function.
+       (gcry_cipher_lookup_func_name): New function.
+       (gcry_cipher_lookup_id): New function.
+       (gcry_cipher_lookup_name): New function.
+       (gcry_cipher_id_new): New function.
+       (gcry_cipher_register): New function.
+       (gcry_cipher_unregister): New function.
+       (setup_cipher_table): Removed function.
+       (load_cipher_modules): Removed function.
+       (gcry_cipher_map_name): Adjusted to use new module management.
+       (cipher_algo_to_string): Likewise.
+       (disable_cipher_algo): Likewise.
+       (check_cipher_algo): Likewise.
+       (cipher_get_keylen): Likewise.
+       (cipher_get_blocksize): Likewise.
+       (gcry_cipher_open): Likewise.
+       (struct gcry_cipher_handle): Replaced members algo, algo_index,
+       blocksize, setkey, encrypt, decrypt, stencrypt, stdecrypt with one
+       member: cipher.
+       (gcry_cipher_open): Adjusted code for new handle structure.
+       (cipher_setkey): Likewise.
+       (cipher_setiv): Likewise.
+       (cipher_reset): Likewise.
+       (do_ecb_encrypt): Likewise.
+       (do_ecb_decrypt): Likewise.
+       (do_cbc_encrypt): Likewise.
+       (do_cbc_decrypt): Likewise.
+       (do_cfb_encrypt): Likewise.
+       (do_cfb_decrypt): Likewise.
+       (do_ctr_encrypt): Likewise.
+       (cipher_encrypt): Likewise.
+       (gcry_cipher_encrypt): Likewise.
+       (cipher_decrypt): Likewise.
+       (gcry_cipher_decrypt): Likewise.
+       (cipher_sync): Likewise.
+       (gcry_cipher_ctl): Likewise.
+
+       * pubkey.c: Removed struct pubkey_table_s.
+       Changed definition of pubkey_table.
+       Removed definition of disabled_algos.
+       (pubkeys_registered, default_pubkeys_registered): New variables.
+       (REGISTER_DEFAULT_PUBKEYS): New macro.
+       (setup_pubkey_table): Removed function.
+       (load_pubkey_modules): Removed function.
+       (gcry_pubkey_register_default): New function.
+       (gcry_pubkey_lookup_func_id): New function.
+       (gcry_pubkey_lookup_func_name): New function.
+       (gcry_pubkey_lookup_id): New function.
+       (gcry_pubkey_lookup_name): New function.
+       (gcry_pubkey_id_new): New function.
+       (gcry_pubkey_register): New function.
+       (gcry_pubkey_unregister): New function.
+       (gcry_pk_map_name): Adjusted to use new module management.
+       (gcry_pk_algo_name): Likewise.
+       (disable_pubkey_algo): Likewise.
+       (check_pubkey_algo): Likewise.
+       (pubkey_get_npkey): Likewise.
+       (pubkey_get_nskey): Likewise.
+       (pubkey_get_nsig): Likewise.
+       (pubkey_get_nenc): Likewise.
+       (pubkey_generate): Likewise.
+       (pubkey_check_secret_key): Likewise.
+       (pubkey_encrypt): Likewise.
+       (pubkey_decrypt): Likewise.
+       (pubkey_sign): Likewise.
+       (pubkey_verify): Likewise.
+       (gcry_pk_get_nbits): Likewise.
+       (gcry_pk_algo_info): Likewise.
+
+       * md.c: Removed struct md_digest_list_s.
+       (digest_list): Changed definition.
+       (digests_registered, default_digests_registered): New variables.
+       (REGISTER_DEFAULT_DIGESTS): New macro.
+       (new_list_item): Removed function.
+       (setup_md_table): Removed function.
+       (load_digest_module): Removed function.
+       (gcry_digest_register_default): New function.
+       (gcry_digest_lookup_func_id): New function.
+       (gcry_digest_lookup_func_name): New function.
+       (gcry_digest_lookup_id): New function.
+       (gcry_digest_lookup_name): New function.
+       (gcry_digest_id_new): New function.
+       (gcry_digest_register): New function.
+       (gcry_digest_unregister): New function.
+       (GcryDigestEntry): New type.
+       (struct gcry_md_context): Adjusted type of `list'.
+       (gcry_md_map_name): Adjusted to use new module management.
+       (digest_algo_to_string): Likewise.
+       (check_digest_algo): Likewise.
+       (md_enable): Likewise.
+       (md_digest_length): Likewise.
+       (md_asn_oid): Likewise.
+
+2003-04-07  Moritz Schulte  <moritz@g10code.com>
+
+       * pubkey.c: Replaced PUBKEY_ALGO_DSA with GCRY_PK_DSA,
+       PUBKEY_ALGO_RSA with GCRY_PK_RSA and PUBKEY_ALGO_ELGAMAL with
+       GCRY_PK_ELG.
+
+       * dsa.c: Replaced PUBKEY_ALGO_DSA with GCRY_PK_DSA.
+
+2003-04-01  Moritz Schulte  <moritz@g10code.com>
+
+       * des.c: Removed checks for GCRY_CIPHER_3DES and GCRY_CIPHER_DES.
+
+2003-03-31  Moritz Schulte  <moritz@g10code.com>
+
+       * tiger.c (tiger_get_info): Do not declare static.
+       * sha256.c (sha256_get_info): Likewise.
+       * sha1.c (sha1_get_info): Likewise.
+       * rmd160.c (rmd160_get_info): Likewise.
+       * md5.c (md5_get_info): Likewise.
+       * md4.c (md4_get_info): Likewise.
+       * crc.c (crc_get_info): Likewise.
+
+       * md.c (load_digest_module): Call setup_md_table during
+       initialization.
+       (new_list_item): Link new element into digest_list.
+
+       * cipher.c (do_ctr_decrypt): Made do_ctr_encrypt act as a wrapper
+       for do_ctr_encrypt, since these functions are identical.
+
+2003-03-30  Simon Josefsson  <jas@extundo.com>
+
+       * cipher.c (struct gcry_cipher_handle): Add counter field.
+       (gcry_cipher_open): Add CTR.
+       (cipher_reset): Clear counter field.
+       (do_ctr_encrypt, do_ctr_decrypt): New functions.
+       (cipher_encrypt, cipher_decrypt): Call CTR functions.
+       (gcry_cipher_ctl): Add SET_CTR to set counter.
+
+2003-03-30  Moritz Schulte  <moritz@g10code.com>
+
+       * rsa.c (_gcry_rsa_blind): New function.
+       (_gcry_rsa_unblind): New function.
+       (_gcry_rsa_decrypt): Use _gcry_rsa_blind and _gcry_rsa_decrypt.
+
+2003-03-26  Moritz Schulte  <moritz@g10code.com>
+
+       * dynload.c (_gcry_enum_gnupgext_pubkeys): Adjust `encrypt' and
+       `decrypt' function arguments.
+       (_gcry_enum_gnupgext_pubkeys): Likewise.
+       * dynload.h: Likewise.
+       
+       * pubkey.c (dummy_decrypt): Add argument: int flags.
+       (dummy_encrypt): Likewise.
+
+       * elgamal.c (_gcry_elg_encrypt): Add argument: int flags.
+       (_gcry_elg_decrypt): Likewise.
+
+       * rsa.c (_gcry_rsa_encrypt): Add argument: int flags.
+       (_gcry_rsa_decrypt): Likewise.
+
+       * pubkey.c: Add `flags' argument to members `encrypt' and
+       `decrypt' of struct `pubkey_table_s'.
+
+       * rsa.h: Add `flags' argument to function declarations.
+       * elgamal.h: Likewise.
+
+       * pubkey.c (sexp_data_to_mpi): New variable: int parsed_flags.
+       (sexp_data_to_mpi): Set `parsed_flags'.
+       (sexp_data_to_mpi): New argument: int *flags.
+       (gcry_pk_encrypt): New variable: int flags.
+       (gcry_pk_encrypt): Pass `flags' to pubkey_encrypt.
+       (pubkey_encrypt): New variable: int flags.
+       (pubkey_encrypt): Pass `flags' to pubkey encrypt function.
+       (pubkey_decrypt): Likewise.
+       (pubkey_decrypt): Pass `flags' to pubkey encrypt function.
+       (gcry_pk_encrypt): Include `flags' s-exp in return list.
+       (sexp_to_enc): New argument: int *flags.
+       (gcry_pk_decrypt): New variable: int flags.
+       (gcry_pk_decrypt): Pass `flags' to pubkey_decrypt.
+       (sexp_to_enc): New variable: int parsed_flags.
+       (sexp_to_enc): Set `parsed_flags'.
+
+2003-03-22  Simon Josefsson  <jas@extundo.com>
+
+       * cipher.c (gcry_cipher_open, do_cbc_encrypt)
+       (gcry_cipher_encrypt): Support GCRY_CIPHER_CBC_MAC.
+       (gcry_cipher_ctl): Support GCRYCTL_SET_CBC_MAC.
+
+2003-03-19  Werner Koch  <wk@gnupg.org>
+
+       * primegen.c (gen_prime): New args EXTRA_CHECK and EXTRA_CHECK_ARG
+       to allow for a user callback.  Changed all callers.
+       (_gcry_generate_secret_prime)
+       (_gcry_generate_public_prime): Ditto, pass them to gen_prime.
+       * rsa.c (check_exponent): New.
+       (generate): Use a callback to ensure that a given exponent is
+       actually generated.
+
+2003-03-12  Moritz Schulte  <moritz@g10code.com>
+
+       * primegen.c: Initialize `no_of_small_prime_numbers' statically.
+       (gen_prime): Remove calculation of `no_of_small_prime_numbers'.
+
+2003-03-03  Moritz Schulte  <moritz@g10code.com>
+
+       * md.c (gcry_md_ctl): Rewritten to use same style like the other
+       functions dispatchers.
+
+2003-03-02  Moritz Schulte  <moritz@g10code.com>
+
+       * cipher.c (struct gcry_cipher_handle): New member: algo_index.
+       (gcry_cipher_open): Allocate memory for two cipher contexts.
+       Initialize algo_index.
+       (cipher_setkey): Duplicate context into reserved memory.
+       (cipher_reset): New function, which resets the context and clear
+       the IV.
+       (gcry_cipher_ctl): Call cipher_reset.
+
+2003-02-23  Moritz Schulte  <moritz@g10code.com>
+
+       * cipher.c: Remove (bogus) `digitp' macro definition.
+       * md.c: Likewise.
+
+       * blowfish.c (burn_stack): Removed.
+       * arcfour.c (burn_stack): Likewise.
+       * cast5.c (burn_stack): Likewise.
+       * des.c (burn_stack): Likewise.
+       * md4.c (burn_stack): Likewise.
+       * md5.c (burn_stack): Likewise.
+       * random.c (burn_stack): Likewise.
+       * rijndael.c (burn_stack): Likewise.
+       * rmd160.c (burn_stack): Likewise.
+       * sha1.c (burn_stack): Likewise.
+       * sha256.c (burn_stack): Likewise.
+       * tiger.c (burn_stack): Likewise.
+       * twofish.c (burn_stack): Likewise.
+
+       * blowfish.c: Changed all occurences of burn_stack to
+       _gcry_burn_stack.
+       * arcfour.c: Likewise.
+       * cast5.c: Likewise.
+       * des.c: Likewise.
+       * md4.c: Likewise.
+       * md5.c: Likewise.
+       * random.c: Likewise.
+       * rijndael.c: Likewise.
+       * rmd160.c: Likewise.
+       * sha1.c: Likewise.
+       * sha256.c: Likewise.
+       * tiger.c: Likewise.
+       * twofish.c: Likewise.
+
+       * arcfour.c (_gcry_arcfour_get_info): Use GCRY_CIPHER_ARCFOUR
+       instead of hard-coded value `301'.
+
+2003-01-24  Werner Koch  <wk@gnupg.org>
+
+       * random.c (_gcry_register_random_progress): New.
+       (_gcry_random_progress): New.
+
+       * rndlinux.c (gather_random): Call the random progress function. 
+
+2003-01-23  Werner Koch  <wk@gnupg.org>
+
+       * rsa.c (generate): New arg USE_E to request a specific public
+       exponent.
+       (_gcry_rsa_generate): Ditto.
+       * elgamal.c (_gcry_elg_generate): Must add an dummy argument
+       instead of USE_E.
+       * dsa.c (_gcry_dsa_generate): Ditto.
+       * pubkey.c (dummy_generate): Ditto.
+       (pubkey_generate): Add USE_E arg and pass it down.
+       (gcry_pk_genkey): Detect "rsa-use-e" parameter and pass it to generate.
+
+       * pubkey.c (sexp_to_enc): New arg RET_MODERN.
+       (gcry_pk_decrypt): Make use of it to return a real S-expression.
+       Return better error codes.
+       (gcry_pk_verify): Return better error codes.
+
+2003-01-21  Werner Koch  <wk@gnupg.org>
+
+       * random.c (gcry_random_add_bytes): Add QUALITY argument, let
+       function return an error code and disable its core for now.
+
+2003-01-21  Timo Schulz  <twoaday@freakmail.de>
+
+       * random.c (gcry_random_add_bytes): New. Function to add external
+       random to the pool.
+       
+2003-01-20  Simon Josefsson  <jas@extundo.com>
+
+       * crc.c: New.
+       * Makefile.am (EXTRA_PROGRAMS, EXTRA_crc_SOURCES): Add crc.c.
+       * md.c (gcry_md_get_algo_dlen): Add values for CRC.
+
+2003-01-20  Werner Koch  <wk@gnupg.org>
+
+       * sha256.c: New.
+       * bithelp.h (ror): New.
+       * Makfile.am: Add sha256.c.
+       * md.c (oid_table): Add values for SHA256 et al.
+       (gcry_md_get_algo_dlen): Likewise
+
+2003-01-20  Werner Koch  <wk@gnupg.org>
+
+       * pubkey.c (gcry_pk_get_keygrip): Implemented keygrips for DSA
+       and ElGamal.
+
+2003-01-17  Werner Koch  <wk@gnupg.org>
+
+       * cipher.c (gcry_cipher_encrypt): Reworked so that the output will
+       never contain the plaintext even if the caller did not checked the
+       return value.
+
+       * md.c (gcry_md_get_algo): Changed error code to GCRYERR_GENERAL
+       because we don't have an invalid md algo but no algorithm enabled.
+
+       * pubkey.c (gcry_pk_genkey): Changed error code for bounds check
+       of table parameters to GCRYERR_INTERNAL.
+
+       * md.c (gcry_md_open): Partly reverted Timo's change from
+       2002-10-10 by removing the check for the algorithm.  An algorithm
+       of 0 is allowed and anyway we should not double check it or check
+       it using a different function.  Also fixed the flags check.
+
+       * pubkey.c (gcry_pk_encrypt): Make sure that R_CIPH points to NULL
+       on error.
+       (gcry_pk_decrypt): Ditto for R_PLAIN.
+       (gcry_pk_sign): Ditto for R_SIG.
+       (gcry_pk_genkey): Ditto for R_KEY.
+
+2003-01-16  Werner Koch  <wk@gnupg.org>
+
+       * md.c (gcry_md_write): Changed 2nd argument type to void*.
+       (gcry_md_hash_buffer): Changed type of boths buffers to void*.
+       (gcry_md_setkey): Changed 2nd argument type to void*.
+
+2003-01-15  Werner Koch  <wk@gnupg.org>
+
+       * pubkey.c (sexp_data_to_mpi): New.  This handles pkcs1 padding.
+       (gcry_pk_sign, gcry_pk_verify): Use it here.
+       (gcry_pk_encrypt): And here.
+       (pubkey_verify): Add debug code.
+       (sexp_to_enc): Handle flags in the input and return the pkcs1 flag
+       in a new parameter.
+       (gcry_pk_decrypt): Prepare for future pkcs1 handling.
+
+2002-12-19  Werner Koch  <wk@gnupg.org>
+
+       * random.c (_gcry_random_initialize): New.
+
+2002-12-16  Werner Koch  <wk@gnupg.org>
+
+       * cipher.c: Added a Teletrust specific OID for 3DES.
+
+2002-12-12  Werner Koch  <wk@gnupg.org>
+
+       * md.c: Added another oddball OIW OID (sha-1WithRSAEncryption).
+
+2002-11-23  Werner Koch  <wk@gnupg.org>
+
+       * md.c (load_digest_module): Enlarged checked_algos bitmap.
+       * md4.c (func_table):  Fixed entry for md4. 
+       Both by Simon Josephson.
+       (transform): Copy data to get the alignment straight. Tested only
+       on i386.
+
+2002-11-10  Simon Josefsson  <jas@extundo.com>
+
+       * cipher.c (gcry_cipher_open): Don't reject CTS flag.
+       (do_cbc_encrypt, do_cbc_decrypt, cipher_encrypt) 
+       (gcry_cipher_encrypt, cipher_decrypt)
+       (gcry_cipher_decrypt): Support CTS flag.
+       (gcry_cipher_ctl): Toggle CTS flag.
+
+2002-11-10  Werner Koch  <wk@gnupg.org>
+
+       * md4.c: New. By Simon Josefsson.
+       * Makefile.am (EXTRA_PROGRAMS): Add md4.c. 
+       * md.c (oid_table,gcry_md_get_algo_dlen): MD4 support. 
+
+2002-10-14  Werner Koch  <wk@gnupg.org>
+
+       * arcfour.c (do_encrypt_stream): Don't use increment op when
+       assigning to the same variable.
+
+2002-10-10  Timo Schulz  <ts@winpt.org>
+
+       * pubkey.c (gcry_pk_genkey): Check boundaries.
+       
+       * md.c (gcry_md_open): Check that algo is available and only
+       valid flag values are used.
+       (gcry_md_get_algo): Add error handling.
+       
+2002-09-26  Werner Koch  <wk@gnupg.org>
+
+       * md.c: Include an OID for TIGER.
+       * tiger.c (tiger_get_info): Use a regular OID.
+
+2002-09-17  Werner Koch  <wk@gnupg.org>
+
+       * random.c: Replaced mutex.h by the new ath.h.  Changed all calls.
+
+2002-09-16  Werner Koch  <wk@gnupg.org>
+
+       * arcfour.c (do_encrypt_stream): Use register modifier and modulo.
+       According to Nikos Mavroyanopoulos this increases perfromace on
+       i386 system noticable.  And I always tought gcc is clever enough.
+       * md5.c (transform): Use register modifier.
+       * rmd160.c (transform): Ditto.
+       * sha1.c (transform): Ditto.  We hope that there are 6 free registers.
+       * random.c (gcry_randomize): Rewrote to avoid malloc calls.
+
+       * rndlinux.c (gather_random): Replaced remaining fprintfs by log_*.
+       * arcfour.c (do_arcfour_setkey): Ditto.
+       * twofish.c (do_twofish_setkey): Ditto.
+       * rndegd.c (gather_random): Ditto.
+       * rijndael.c (do_setkey): Ditto.
+       * random.c (_gcry_random_dump_stats): Ditto. 
+       * primegen.c (_gcry_generate_elg_prime): Ditto.
+       * des.c (_gcry_des_get_info): Ditto.
+       * cast5.c (do_cast_setkey): Ditto.
+       * blowfish.c (do_bf_setkey): Ditto.
+
+2002-08-26  Werner Koch  <wk@gnupg.org>
+
+       * des.c (weak_keys): Fixed one entry in the table and compared
+       all entries against the literature.
+       (selftest): Checksum the weak key table.
+
+2002-08-21  Werner Koch  <wk@gnupg.org>
+
+       * pubkey.c: Enable keygrip calculation for "openpgp-rsa".
+
+2002-08-17  Werner Koch  <wk@gnupg.org>
+
+       * cipher.c (setup_cipher_table): Don't overwrite the DES entry
+       with the entry for DUMMY.
+
+2002-08-14  Werner Koch  <wk@gnupg.org>
+
+       * des.c (do_des_setkey,do_des_encrypt, do_des_decrypt): New.
+       (_gcry_des_get_info): Support plain old DES.
+       * cipher.c (setup_cipher_table): Put DES into the table.
+
+2002-07-25  Werner Koch  <wk@gnupg.org>
+
+       * rndunix.c (_gcry_rndunix_constructor): Prefixed with _gcry_.
+       Noted by Stephan Austermuehle.
+
+2002-07-08  Timo Schulz  <ts@winpt.org>
+
+       * rndw32.c: Replaced the m_ memory functions with the real 
+       gcry_ functions. Renamed all g10_ prefixed functions to log_.
+       
+2002-06-12  Werner Koch  <wk@gnupg.org>
+
+       * rsa.c (generate): Use e = 65537 for now.
+
+2002-06-11  Werner Koch  <wk@gnupg.org>
+
+       * pubkey.c (gcry_pk_get_keygrip): Allow a "protected-private-key".
+
+2002-06-05  Timo Schulz  <ts@winpt.org>
+
+       * cipher.c (gcry_cipher_encrypt, gcry_cipher_decrypt):
+       Check that the input size is a multiple of the blocksize.
+       
+2002-05-23  Werner Koch  <wk@gnupg.org>
+
+       * md.c (oid_table): Add an rsadsi OID for MD5.
+
+2002-05-21  Werner Koch  <wk@gnupg.org>
+
+       * primegen.c, elgamal.c, dsa.c (progress): Do not print anything
+       by default.  Pass an extra identifying string to the callback and
+       reserved 2 argumenst for current and total counters.  Changed the
+       register function prototype.
+
+2002-05-17  Werner Koch  <wk@gnupg.org>
+
+       * rndegd.c (rndegd_constructor): Fixed name of register function
+       and prefixed the function name with _gcry_.
+       * rndw32.c (rndw32_constructor): Ditto.
+       * tiger.c (tiger_constructor): Ditto.
+
+       * Makefile.am: Removed all dynamic loading stuff.
+       * dynload.c: Ditto. Now only used for the constructor system.
+
+2002-05-15  Werner Koch  <wk@gnupg.org>
+
+       * random.c (gcry_random_bytes,gcry_random_bytes_secure)
+       (gcry_randomize): Make sure we are initialized.
+
+2002-05-14  Werner Koch  <wk@gnupg.org>
+
+       Changed license of most files to the LGPL.
+
+2002-05-02  Werner Koch  <wk@gnupg.org>
+
+       * random.c (_gcry_fast_random_poll): Initialize the module so the
+       mutex can be used.
+
+       * primegen.c (small_prime_numbers): Moved table from smallprime.c
+       * smallprime.c: File removed.
+
+       * des.c (leftkey_swap, rightkey_swap, working_memcmp): Made static.
+
+       * cipher.c (gcry_cipher_map_name): Map "RIJNDAEL" to "AES".
+       * rijndael.c (rijndael_get_info): We do only support a 128 bit
+       blocksize so it makes sense to change the algorithm strings to
+       AES.
+
+       * tiger.c (tiger_final): Removed superfluous token pasting operators.
+       * md5.c (md5_final): Ditto.
+
+2002-04-30  Werner Koch  <wk@gnupg.org>
+
+       * cipher.c: Fixed list of copyright years.
+
+2002-03-18  Werner Koch  <wk@gnupg.org>
+
+       * random.c (initialize): Initialize the new pool lock mutex.
+       (_gcry_fast_random_poll): Add locking and moved main
+       code out to...
+       (do_fast_random_poll): new function.
+       (read_pool): Use the new function here.
+       (get_random_bytes): Add locking.
+       (_gcry_update_random_seed_file): Ditto.
+
+2002-03-11  Werner Koch  <wk@gnupg.org>
+
+       * md.c: Add rsaSignatureWithripemd160 to OID table.
+
+2002-02-20  Werner Koch  <wk@gnupg.org>
+
+       * sha1.c: Removed a left over comment note.  The code has been
+       rewritten from scratch in 1998.  Thanks to Niels Möller for
+       reporting this misleading comment.
+
+2002-02-18  Werner Koch  <wk@gnupg.org>
+
+       * rndunix.c (rndunix_constructor): Use the the new prefixed
+       function name.  Reported by Jordi Mallach.
+
+2002-02-10  Werner Koch  <wk@gnupg.org>
+
+       * random.c (mix_pool): Carry an extra failsafe_digest buffer
+       around to make the function more robust.
+
+2002-02-08  Werner Koch  <wk@gnupg.org>
+
+       * random.c (add_randomness): Xor new data into the pool and not
+       just copy it.  This avoids any choosen input attacks which are not
+       serious in our setting because an outsider won't be able to mix
+       data in and even then we keep going with a PRNG.  Thanks to Stefan
+       Keller for pointing this out.
+
+2002-01-04  Werner Koch  <wk@gnupg.org>
+
+       * pubkey.c (gcry_pk_genkey): Do not release skey - it is static.
+
+       * primegen.c (gen_prime): Of course we should use set_bit
+       and not set_highbit to set the second high bit.
+
+2001-12-18  Werner Koch  <wk@gnupg.org>
+
+       * rsa.c (generate): Loop until we find the exact modulus size.
+       Changed the exponent to 41.
+       (rsa_get_info): s/usage/r_usage/ to avoid shadow warnings.
+       * primegen.c (gen_prime): Set 2 high order bits for secret primes.
+
+       * Makefile.am (DISTCLEANFILES): Include construct.c.
+
+2001-12-17  Werner Koch  <wk@gnupg.org>
+
+       * pubkey.c (gcry_pk_get_keygrip): New - experimental.
+
+2001-12-11  Werner Koch  <wk@gnupg.org>
+
+       * cipher.c: Added OIDs for AES.
+       (gcry_cipher_mode_from_oid): New.
+       (gcry_cipher_map_name): Moved OID search code to ..
+       (search_oid): .. new function.
+
+2001-12-10  Werner Koch  <wk@gnupg.org>
+
+       * pubkey.c (gcry_pk_encrypt): Find the signature algorithm by name
+       and not by number.
+       
+       * pubkey.c (gcry_pk_encrypt,gcry_pk_decrypt,gcry_pk_sign)
+       (gcry_pk_verify,gcry_pk_testkey, gcry_pk_genkey)
+       (gcry_pk_get_nbits): Release the arrays.  Noted by Nikos
+       Mavroyanopoulos.
+
+2001-12-06  Werner Koch  <wk@gnupg.org>
+
+       * cipher.c (gcry_cipher_map_name): Look also for OIDs prefixed
+       with "oid."  or "OID.".
+
+2001-12-05  Werner Koch  <wk@gnupg.org>
+
+       * pubkey.c (algo_info_table): Fixed entry for openpgp-rsa. 
+
+2001-11-24  Werner Koch  <wk@gnupg.org>
+
+       * pubkey.c: Added the rsaEncryption OID to the tables.
+       (sexp_to_key): Add an arg to return the index of the algorithm,
+       changed all callers.
+       (gcry_pk_sign): Find the signature algorithm by name and not by
+       number.
+       (gcry_pk_get_nbits): Fixed so that we can now really pass a secret
+       key to get the result.
+       
+       * md.c (gcry_md_map_name): Look also for OIDs prefixed with "oid."
+       or "OID." so that an OID string can be used as an S-Exp token.
+
+2001-11-20  Werner Koch  <wk@gnupg.org>
+
+       * md.c (gcry_md_map_name): Lookup by OID if the the name begins
+       with a digit.
+       (oid_table): New.
+       
+2001-11-16  Werner Koch  <wk@gnupg.org>
+
+       * md.c (gcry_md_info): New operator GCRYCTL_IS_ALGO_ENABLED.
+
+2001-11-07  Werner Koch  <wk@gnupg.org>
+
+       * md.c (gcry_md_hash_buffer): Close the handle which was left open
+       for algorithms other than rmd160.
+
+2001-08-08  Werner Koch  <wk@gnupg.org>
+
+       * rndw32.c (gather_random): Use toolhelp in addition to the NT
+       gatherer for Windows2000.  Suggested by Sami Tolvanen.
+
+       * random.c (read_pool): Fixed length check, this used to be one
+       byte to strict.  Made an assert out of it because the caller has
+       already made sure that only poolsize bytes are requested.
+       Reported by Marcus Brinkmann.
+
+2001-08-03  Werner Koch  <wk@gnupg.org>
+
+       * cipher.c (cipher_encrypt, cipher_decrypt): Prepare to return
+       errors. We have to change the interface to all ciphers to make
+       this really work but we should do so to prepare for hardware
+       encryption modules.
+       (gcry_cipher_encrypt, gcry_cipher_decrypt): Return the error and
+       set lasterr. 
+       (gcry_cipher_ctl): Make sure that errors from setkey are returned.
+
+2001-08-02  Werner Koch  <wk@gnupg.org>
+
+       * rndlinux.c (gather_random): casted a size_t arg to int so that
+       the format string is correct.  Casting is okay here and avoids
+       translation changes. 
+
+       * random.c (fast_random_poll): Do not check the return code of
+       getrusage.
+
+       * rndunix.c: Add a signal.h header to avoid warnings on Solaris 7
+       and 8.
+
+       * tiger.c (print_abc,print_data): Removed.
+
+       * rijndael.c, des.c, blowfish.c, twofish.c, cast5.c, arcfour.c
+       (burn_stack): New.  Add wrappers for most functions to be able to
+       call burn_stack after the function invocation. This methods seems
+       to be the most portable way to zeroise the stack used. It does
+       only work on stack frame based machines but it is highly portable
+       and has no side effects.  Just setting the automatic variables at
+       the end of a function to zero does not work well because the
+       compiler will optimize them away - marking them as volatile would
+       be bad for performance.
+       * md5.c, sha1.c, rmd160.c, tiger.c (burn_stack): Likewise.
+       * random.c (burn_stack): New.
+       (mix_pool): Use it here to burn the stack of the mixblock function.
+
+       * primegen.c (_gcry_generate_elg_prime): Freed q at 3 places.
+       Thanks to Tommi Komulainen.
+
+       * arcfour.c (arcfour_setkey): Check the minimim keylength against
+       bytes and not bits.
+       (selftest): Must reset the key before decryption. 
+
+2001-05-31  Werner Koch  <wk@gnupg.org>
+
+       * sha1.c (sha1_init): Made static.
+
+        Changed all g10_ prefixed function names as well as some mpi_
+       function names to cope with the introduced naming changes.
+       
+       * md.c (prepare_macpads): Made key const.
+
+2001-05-28  Werner Koch  <wk@gnupg.org>
+
+       * rndegd.c (gather_random): Removed the use of tty_printf.
+
+2001-03-29  Werner Koch  <wk@gnupg.org>
+
+       * md5.c (md5_final): Fixed calculation of hashed length.  Thanks
+       to disastry@saiknes.lv for pointing out that it was horrible wrong
+       for more than 512MB of input.
+       * sha1.c (sha1_final): Ditto.
+       * rmd160.c (rmd160_final): Ditto.
+       * tiger.c (tiger_final): Ditto.
+
+       * blowfish.c (encrypt,do_encrypt): Changed name to do_encrypt to
+       avoid name clashes with an encrypt function in stdlib.h of
+       Dynix/PIX.  Thanks to Gene Carter.
+       * elgamal.c (encrypt,do_encrypt): Ditto.
+
+       * twofish.c (gnupgext_enum_func): Use only when when compiled as a
+       module.
+       * rijndael.c (gnupgext_enum_func): Ditto.
+
+       * tiger.c (tiger_get_info): Return "TIGER192" and not just
+       "TIGER".  By Edwin Woudt.
+       
+       * random.c: Always include time.h - standard requirement.  Thanks
+       to James Troup.
+
+       * rndw32.c: Fixes to the macros.
+
+2001-01-11  Werner Koch  <wk@gnupg.org>
+
+       * cipher.c (cipher_encrypt,gcry_cipher_encrypt): Use blocksize and
+       not 8.
+
+2000-12-19  Werner Koch  <wk@gnupg.org>
+
+       Major change:
+       Removed all GnuPG stuff and renamed this piece of software
+       to gcrypt. 
+
+2000-11-14  Werner Koch  <wk@gnupg.org>
+
+       * dsa.c (test_keys): Replaced mpi_alloc by gcry_mpi_new and
+       mpi_free by gcry_mpi_release.
+       * elgamal.c (test_keys,generate): Ditto, also for mpi_alloc_secure.
+       * rsa.c (test_keys,generate,rsa_verify): Ditto.
+       * primegen.c (generate_elg_prime): Ditto.
+       (gen_prime): Ditto and removed nlimbs.
+
+       * rsa.c (generate): Allocate 2 more vars in secure memory.
+
+       * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency
+       problems.
+
+2000-10-09  Werner Koch  <wk@gnupg.org>
+
+       * arcfour.c, arcfour.h: New.
+       * cipher.c (cipher_encrypt, cipher_decrypt): Add stream mode.
+       (setup_cipher_table): Add Arcfour.
+       (gcry_cipher_open): Kludge to allow stream mode.
+
+Wed Oct  4 13:16:18 CEST 2000  Werner Koch  <wk@openit.de>
+
+        * sha1.c (transform): Use rol() macro.  Actually this is not needed
+        for a newer gcc but there are still aoter compilers.
+
+        * rsa.c (test_keys): Use new random function. 
+
+        * md.c (gcry_md_setkey): New function to overcome problems with
+        const conflics.  
+        (gcry_md_ctl): Pass set key to the new functions.
+
+        * rijndael.c: New.
+        * cipher.c: Add Rijndael support.
+
+Mon Sep 18 16:35:45 CEST 2000  Werner Koch  <wk@openit.de>
+
+        * rndlinux.c (open_device): Loose random device checking.
+        By Nils Ellmenreich.
+
+        * random.c (fast_random_poll): Check ENOSYS for getrusage.
+        * rndunix.c:  Add 2 sources for QNX. By Sam Roberts.
+
+        * pubkey.c (gcry_pk_algo_info): Add GCRYCTL_GET_ALGO_USAGE.
+
+        * rsa.c: Changed the comment about the patent.
+        (secret): Speed up by using the CRT.  For a 2k keys this
+        is about 3 times faster.
+        (stronger_key_check): New but unused code to check the secret key.
+        * Makefile.am: Included rsa.[ch].
+        * pubkey.c: Enabled RSA support.
+        (pubkey_get_npkey): Removed RSA workaround.
+
+Mon Jul 31 10:04:47 CEST 2000  Werner Koch  <wk@openit.de>
+
+  * pubkey.c: Replaced all gcry_sexp_{car,cdr}_{data,mpi} by the new
+  gcry_sexp_nth_{data,mpi} functions.
+
+Tue Jul 25 17:44:15 CEST 2000  Werner Koch  <wk@openit.de>
+
+  * pubkey.c (exp_to_key,sexp_to_sig,sexp_to_enc,gcry_pk_encrypt,
+    gcry_pk_decrypt,gcry_pk_sign,gcry_pk_genkey): Changed to work with
+    the new S-Exp interface.
+
+Mon Jul 17 16:35:47 CEST 2000  Werner Koch  <wk@>
+
+  * random.c (gather_faked): Replaced make_timestamp by time(2) again.
+
+Fri Jul 14 19:38:23 CEST 2000  Werner Koch  <wk@>
+
+  * md.c (gcry_md_ctl): Support GCRYCTL_{START,STOP}_DUMP.
+
+  * Makefile.am: Never compile mingw32 as module.
+
+  * Makefile.am: Tweaked module build and removed libtool
+
+  * Makefile.am:  Replaced -O1 by -O. Suggested by Alec Habig.
+
+  * elgamal.c (sign): Removed inactive code.
+
+  * rsa.c, rsa.h: New based on the old module version (only in CVS for now).
+  * pubkey.c (setup_pubkey_table): Added commented support for RSA.
+
+  * rndunix.c (waitpid): New. For UTS 2.1.  All by Dave Dykstra.
+  (my_popen): Do the FD_CLOEXEC only if it is available
+  (start_gatherer): Cope with missing _SC_OPEN_MAX
+
+  * rndunix.c: Add some more headers for QNX. By Sam Roberts.
+
+  * rndegd.c (gather_random): Shortcut level 0.
+  * rndunix.c (gather_random): Ditto.
+  * rndw32.c (gather_random): Ditto.
+
+  * rndw32.c: Replaced with code from Cryptlib and commented the old stuff.
+  * rndw32.c: Add some debuging code enabled by an environment variable.
+
+  * random.c (read_seed_file): Binary open for DOSish system
+  (update_random_seed_file): Ditto.
+  * random.c [MINGW32]: Include process.h for getpid.
+  * random.c (fast_random_poll): Add clock_gettime() as fallback for
+  system which support this POSIX.4 fucntion. By Sam Roberts.
+
+  * random.c (read_seed_file): Removed the S_ISLNK test becuase it
+  is already covered by !S_ISREG and is not defined in Unixware.
+  Reported by Dave Dykstra.
+  (update_random_seed_file): Silently ignore update request when pool
+  is not filled.
+
+  * random.c (read_seed_file): New.
+  (set_random_seed_file): New.
+  (read_pool): Try to read the seeding file.
+  (update_random_seed_file): New.
+
+  (read_pool): Do an initial extra seeding when level 2 quality random
+  is requested the first time. This requestes at least POOLSIZE/2 bytes
+  of entropy.  Compined with the seeding file this should make normal
+  random bytes cheaper and increase the quality of the random bytes
+  used for key generation.
+
+  * random.c (read_pool): Print a more friendly error message in
+  cases when too much random is requested in one call.
+
+  * random.c (fast_random_poll): Check whether RUSAGE_SELF is defined;
+  this is not the case for some ESIX and Unixware, although they have
+  getrusage().
+
+  * primegen.c (generate_elg_prime): All primes are now generated with
+  the lowest random quality level.  Because they are public anyway we
+  don't need stronger random and by this we do not drain the systems
+  entropy so much.
+
+  * primegen.c (register_primegen_progress): New.
+  * dsa.c (register_pk_dsa_progress): New.
+  * elgamal.c (register_pk_elg_progress): New.
+
+  * elgamal.c (wiener_map): New.
+  (gen_k): Use a much smaller k.
+  (generate): Calculate the qbits using the wiener map and
+  choose an x at a size comparable to the one choosen in gen_k
+
+  * rmd160.c (rmd160_get_info): Moved casting to the left side due to a
+  problem with UTS4.3. Suggested by Dave Dykstra.
+  * sha1.c (sha1_get_info): Ditto.
+  * tiger.c (tiger_get_info): Ditto.
+  * md5.c (md5_get_info): Ditto
+  * des.c (des_get_info): Ditto.
+  * blowfish.c (blowfish_get_info): Ditto.
+  * cast5.c (cast5_get_info): Ditto.
+  * twofish.c (twofish_get_info): Ditto.
+
+Fri Mar 24 11:25:45 CET 2000  Werner Koch  <wk@openit.de>
+
+       * md.c (md_open): Add hmac arg and allocate space for the pads.
+       (md_finalize): Add HMAC support.
+       (md_copy): Ditto.
+       (md_close): Ditto.
+       (gcry_md_reset): Ditto.
+       (gcry_md_ctl): Ditto.
+       (prepare_macpdas): New.
+
+Mon Mar 13 19:22:46 CET 2000  Werner Koch  <wk@openit.de>
+
+       * md.c (gcry_md_hash_buffer): Add support for the other algorithms.
+
+Mon Jan 31 16:37:34 CET 2000  Werner Koch  <wk@gnupg.de>
+
+       * genprime.c (generate_elg_prime): Fixed returned factors which never
+       worked for non-DSA keys.
+
+Thu Jan 27 18:00:44 CET 2000  Werner Koch  <wk@gnupg.de>
+
+       * pubkey.c (sexp_to_key): Fixed mem leaks in case of errors.
+
+Mon Jan 24 22:24:38 CET 2000  Werner Koch  <wk@gnupg.de>
+
+       * pubkey.c (gcry_pk_decrypt): Implemented.
+       (gcry_pk_encrypt): Implemented.
+       (gcry_pk_testkey): New.
+       (gcry_pk_genkey): New.
+       (pubkey_decrypt): Made static.
+       (pubkey_encrypt): Ditto.
+       (pubkey_check_secret_key): Ditto.
+       (pubkey_generate): Ditto.
+
+Mon Jan 24 13:04:28 CET 2000  Werner Koch  <wk@gnupg.de>
+
+       * pubkey.c (pubkey_nbits): Removed and replaced by ...
+       (gcry_pk_get_nbits): this new one.
+
+Wed Dec  8 21:58:32 CET 1999  Werner Koch  <wk@gnupg.de>
+
+       * dsa.c: s/mpi_powm/gcry_mpi_powm/g
+       * elgamal.c: Ditto.
+       * primegen.c: Ditto.
+
+       * : Replaced g10_opt_verbose by g10_log_verbosity().
+
+       * Makefile.am (INCLUDES): removed intl, add ../gcrypt
+
+Fri Nov 19 17:15:20 CET 1999  Werner Koch  <wk@gnupg.de>
+
+       * dynload.c (cmp_filenames): New to replaced compare_filename() in
+       module.
+       (register_cipher_extension): Removed the tilde expansion stuff.
+       * rndeg.c (my_make_filename): New.
+
+       * : Replaced header util.h by g10lib.h
+
+       * random.c (gather_faked): Replaced make_timestamp by time(2).
+       Disabled wrning printed with tty_printf.
+       * rndlinux.c (gather_random): Always use fprintf instead of tty_xxx;
+       this should be replaced by a callback function.
+
+       * primegen.c (gen_prime): Use gcry_mpi_randomize.
+       (is_prime): Ditto.
+       * elgamal.c (test_keys): Ditto.
+       * dsa.c (test_keys): Ditto.
+
+       * cipher.c (gcry_cipher_close): Die on invalid handle.
+
+Mon Nov 15 21:36:02 CET 1999  Werner Koch  <wk@gnupg.de>
+
+       * elgamal.c (gen_k): Use the new random API.
+       (generate): Ditto.
+       * dsa.c (gen_k): Ditto.
+       (generate): Ditto.
+
+Sat Nov 13 17:44:23 CET 1999  Werner Koch  <wk@gnupg.de>
+
+       * pubkey.c (disable_pubkey_algo): Made static.
+       (gcry_pk_ctl): New.
+
+       * random.c (get_random_bits): Renamed to ...
+       (get_random_bytes): ... this and made static.
+       (gcry_random_bytes): New.
+       (gcry_random_bytes_secure): New.
+       (randomize_buffer): Renamed to ...
+       (gcry_randomize): ...this.
+
+       * md.c (gcry_md_hash_buffer): New.
+
+       * pubkey.c (gcry_pk_algo_info): 4 new commands.
+       (pubkey_get_npkey): Made static.
+       (pubkey_get_nskey): Made static.
+       (pubkey_get_nsig): Made static.
+       (pubkey_get_nenc): Made static.
+
+       * pubkey.c: Removed all G10ERR_xxx.
+       * cipher.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_CIPHER_ALGO.
+       * md.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_MD_ALGO.
+       * cast5.c (cast_setkey): Changed errocodes to GCRYERR_xxx.
+       * blowfish.c: Ditto.
+       * des.c: Ditto.
+       * twofish.c: Ditto.
+       * dsa.c: Ditto.
+       * elgamal.c: Ditto.
+
+       * g10c.c: Removed
+
+       * cipher.c (gcry_cipher_open): Replaced alloc functions and return NULL
+       if we are out of core.
+       * dynload.c: Replaced all memory allocation functions.
+       * md.c: Ditto.
+       * primegen.c: Ditto.
+       * pubkey.c: Ditto.
+       * random.c: Ditto.
+       * rndw32.c: Ditto.
+       * elgamal.c: Ditto.
+       * dsa.c: Ditto.
+
+Tue Oct 26 14:10:21 CEST 1999  Werner Koch  <wk@gnupg.de>
+
+       * elgamal.c (sign): Hugh found strange code here. Replaced by BUG().
+
+       * cipher.c: Merged with gcrypt/symapi.c.
+
+       * pubkey.c (string_to_pubkey_algo): Renamed function to ...
+       (gcry_pk_map_name): ... this.
+       (pubkey_algo_to_string): Renamed function to ...
+       (gcry_pk_algo_name): ... this.
+       (gcry_pk_algo_info): New.
+       * pubkey.c: Merged with gcrypt/pkapi.c.
+
+       * md.c (md_reset): Clear finalized; thanks to Ulf Moeller for
+       fixing this bug.
+
+       * md.c: Merged with gcrypt/mdapi.c
+
+Wed Sep 15 14:39:59 CEST 1999  Michael Roth <mroth@nessie.de>
+
+       * des.c: Various speed improvements: One bit pre rotation
+         trick after initial permutation (Richard Outerbridge).
+         Finished test of SSLeay Tripple-DES patterns.
+
+Wed Sep 15 16:22:17 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * rndw32.c: New.
+
+Mon Sep 13 10:51:29 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * bithelp.h: New.
+       * rmd160.h, sha1.h, md5.h: Use the rol macro from bithelp.h
+
+Tue Sep  7 16:23:36 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * Makefile.am: Fixed seds for latest egcc. By Ollivier Robert.
+
+Mon Sep  6 19:59:08 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * des.c (selftest): Add some testpattern
+
+Mon Aug 30 20:38:33 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * cipher.c (do_cbc_encrypt): Fixed serious bug occuring when not using
+       in place encryption. Pointed out by Frank Stajano.
+
+Mon Jul 26 09:34:46 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * md5.c (md5_final): Fix for a SCO cpp bug.
+
+Thu Jul 15 10:15:35 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * elgamal.c (elg_check_secret_key,elg_encrypt
+       elg_decrypt,elg_sign,elg_verify): Sanity check on the args.
+       * dsa.c (dsa_check_secret_key,dsa_sign,dsa_verify): Ditto.
+
+       * pubkey.c (disable_pubkey_algo): New.
+       (check_pubkey_algo2): Look at disabled algo table.
+       * cipher.c (disable_cipher_algo): New.
+       (check_cipher_algo): Look at disabled algo table.
+
+Wed Jul  7 13:08:40 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * Makefile.am: Support for libtool.
+
+Fri Jul  2 11:45:54 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * dsa.c (gen_k): Changed algorithm to consume less random bytes
+       * elgamal.c (gen_k): Ditto.
+
+       * random.c (random_dump_stats): New.
+
+Thu Jul  1 12:47:31 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * primegen.c, elgamal.c, dsa.c (progess): New and replaced all
+       fputc with a call to this function.
+
+Sat Jun 26 12:15:59 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * rndegd.c (do_write): s/ssize_t/int/ due to SunOS 4.1 probs.
+
+       * cipher.c (do_cbc_encrypt, do_cbc_decrypt): New.
+
+       * dynload.c (HAVE_DL_SHL_LOAD): Map hpux API to dlopen (Dave Dykstra).
+       * Makefile.am (install-exec-hook): Removed.
+
+Sun May 23 14:20:22 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * cipher.c (setup_cipher_table): Enable Twofish
+
+       * random.c (fast_random_poll): Disable use of times() for mingw32.
+
+Mon May 17 21:54:43 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * dynload.c (register_internal_cipher_extension): Minor init fix.
+
+Tue May  4 15:47:53 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * primegen.c (gen_prime): Readded the Fermat test. Fixed the bug
+       that we didn't correct for step when passing the prime to the
+       Rabin-Miller test which led to bad performance (Stefan Keller).
+       (check_prime): Add a first Fermat test.
+
+Sun Apr 18 10:11:28 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * cipher.c (cipher_setiv): Add ivlen arg, changed all callers.
+
+       * random.c (randomize_buffer): alway use secure memory because
+       we can't use m_is_secure() on a statically allocated buffer.
+
+       * twofish.c: Replaced some macros by a loop to reduce text size.
+       * Makefile.am (twofish): No more need for sed editing.
+
+Fri Apr  9 12:26:25 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * cipher.c (cipher_open): Reversed the changes for AUTO_CFB.
+
+       * blowfish.c: Dropped the Blowfish 160 mode.
+       * cipher.c (cipher_open): Ditto.
+       (setup_cipher_table): Ditto.  And removed support of twofish128
+
+Wed Apr  7 20:51:39 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * random.c (get_random_bits): Can now handle requests > POOLSIZE
+
+       * cipher.c (cipher_open): Now uses standard CFB for automode if
+       the blocksize is gt 8 (according to rfc2440).
+
+       * twofish.c: Applied Matthew Skala's patches for 256 bit key.
+
+Tue Apr  6 19:58:12 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * random.c (get_random_bits): Can now handle requests > POOLSIZE
+
+       * cipher.c (cipher_open): Now uses standard CFB for automode if
+       the blocksize is gt 8 (according to rfc2440).
+
+Sat Mar 20 11:44:21 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * rndlinux.c (tty_printf) [IS_MODULE]: Removed.
+
+       * rndegd.c (gather_random): Some fixes.
+
+Wed Mar 17 13:09:03 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * rndegd.c (do_read): New.
+       (gather_random): Changed the implementation.
+
+Mon Mar  8 20:47:17 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * dynload.c (DLSYM_NEEDS_UNDERSCORE): Renamed.
+
+Fri Feb 26 17:55:41 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * md.c: Nearly a total rewrote.
+
+Wed Feb 24 11:07:27 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * cipher.c (context): Fixed alignment
+       * md.c: Ditto.
+
+       * rndegd.c: New
+
+Mon Feb 22 20:04:00 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * rndegd.c: New.
+
+Wed Feb 10 17:15:39 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * Makefile.am: Modules are now figured out by configure
+       * construct.c: New. Generated by configure. Changed all modules
+       to work with that.
+       * sha1.h: Removed.
+       * md5.h: Removed.
+
+       * twofish.c: Changed interface to allow Twofish/256
+
+       * rndunix.c (start_gatherer): Die on SIGPIPE.
+
+Wed Jan 20 18:59:49 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * rndunix.c (gather_random): Fix to avoid infinite loop.
+
+Sun Jan 17 11:04:33 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * des.c (is_weak_key): Replace system memcmp due to bugs
+       in SunOS's memcmp.
+       (des_get_info): Return error on failed selftest.
+       * twofish.c (twofish_setkey): Return error on failed selftest or
+       invalid keylength.
+       * cast5.c (cast_setkey): Ditto.
+       * blowfish.c (bf_setkey): Return error on failed selftest.
+
+Tue Jan 12 11:17:18 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * random.c (random_is_faked): New.
+
+       * tiger.c: Only compile if we have the u64 type
+
+Sat Jan  9 16:02:23 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * rndunix.c (gather_random): check for setuid.
+
+       * Makefile.am: Add a way to staically link random modules
+
+Thu Jan  7 18:00:58 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * md.c (md_stop_debug): Do a flush first.
+       (md_open): size of buffer now depends on the secure parameter
+
+Sun Jan  3 15:28:44 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * rndunix.c (start_gatherer): Fixed stupid ==/= bug
+
+1998-12-31  Geoff Keating  <geoffk@ozemail.com.au>
+
+       * des.c (is_weak_key): Rewrite loop end condition.
+
+Tue Dec 29 14:41:47 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * random.c: add unistd.h for getpid().
+       (RAND_MAX): Fallback value for Sun.
+
+Wed Dec 23 17:12:24 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * md.c (md_copy): Reset debug.
+
+Mon Dec 14 21:18:49 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * random.c (read_random_source): Changed the interface to the
+       random gathering function.
+       (gather_faked): Use new interface.
+       * dynload.c (dynload_getfnc_fast_random_poll): Ditto.
+       (dynload_getfnc_gather_random): Ditto.
+       * rndlinux.c (gather_random): Ditto.
+       * rndunix.c (gather_random): Ditto.
+
+Sat Dec 12 18:40:32 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * dynload.c (SYMBOL_VERSION): New to cope with system which needs
+       underscores.
+
+       * rndunix.c: Rewrote large parts
+
+Thu Dec 10 20:15:36 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * dynload.c (load_extension): increased needed verbosity level.
+
+       * random.c (fast_random_poll): Fallback to a default fast random
+       poll function.
+       (read_random_source): Always use the faked entroy gatherer if no
+       gather module is available.
+       * rndlinux.c (fast_poll): Removed.
+       * rndunix.c (fast_poll): Removed.
+
+
+Wed Nov 25 12:33:41 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * rand-*.c: Removed.
+       * rndlinux.c : New.
+       * rndunix.c : New.
+       * random.c : Restructured the interface to the gather modules.
+       (intialize): Call constructor functions
+       (read_radnom_source): Moved to here.
+       * dynload.c (dynload_getfnc_gather_random): New.
+       (dynload_getfnc_fast_random_poll): New.
+       (register_internal_cipher_extension): New.
+       (register_cipher_extension): Support of internal modules.
+
+Sun Nov  8 17:44:36 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * rand-unix.c (read_random_source): Removed the assert.
+
+Mon Oct 19 18:34:30 1998  me,,,  (wk@tobold)
+
+       * pubkey.c: Hack to allow us to give some info about RSA keys back.
+
+Thu Oct 15 11:47:57 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * dynload.c: Support for DLD
+
+Wed Oct 14 12:13:07 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * rand-unix.c: Now uses names from configure for /dev/random.
+
+1998-10-10  SL Baur  <steve@altair.xemacs.org>
+
+       * Makefile.am: fix sed -O substitutions to catch -O6, etc.
+
+Tue Oct  6 10:06:32 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * rand-unix.c (HAVE_GETTIMEOFDAY): Fixed (was ..GETTIMEOFTIME :-)
+       * rand-dummy.c (HAVE_GETTIMEOFDAY): Ditto.
+
+Mon Sep 28 13:23:09 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * md.c (md_digest): New.
+       (md_reset): New.
+
+Wed Sep 23 12:27:02 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * tiger.c (TIGER_CONTEXT): moved "buf", so that it is 64 bit aligned.
+
+Mon Sep 21 06:22:53 1998  Werner Koch  (wk@(none))
+
+       * des.c: Some patches from Michael.
+
+Thu Sep 17 19:00:06 1998  Werner Koch  (wk@(none))
+
+       * des.c : New file from Michael Roth <mroth@nessie.de>
+
+Mon Sep 14 11:10:55 1998  Werner Koch  (wk@(none))
+
+       * blowfish.c (bf_setkey): Niklas Hernaeus patch to detect weak keys.
+
+Mon Sep 14 09:19:25 1998  Werner Koch  (wk@(none))
+
+       * dynload.c (RTLD_NOW): Now defined to 1 if it is undefined.
+
+Mon Sep  7 17:04:33 1998  Werner Koch  (wk@(none))
+
+       * Makefile.am: Fixes to allow a different build directory
+
+Thu Aug  6 17:25:38 1998  Werner Koch,mobil,,, (wk@tobold)
+
+       * random.c (get_random_byte): Removed and changed all callers
+       to use get_random_bits()
+
+Mon Jul 27 10:30:22 1998  Werner Koch  (wk@(none))
+
+       * cipher.c : Support for other blocksizes
+       (cipher_get_blocksize): New.
+       * twofish.c: New.
+       * Makefile.am: Add twofish module.
+
+Mon Jul 13 21:30:52 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * random.c (read_pool): Simple alloc if secure_alloc is not set.
+       (get_random_bits): Ditto.
+
+Thu Jul  9 13:01:14 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * dynload.c (load_extension): Function now nbails out if
+       the program is run setuid.
+
+Wed Jul  8 18:58:23 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * rmd160.c (rmd160_hash_buffer): New.
+
+Thu Jul  2 10:50:30 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * cipher.c (cipher_open): algos >=100 use standard CFB
+
+Thu Jun 25 11:18:25 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * Makefile.am: Support for extensions
+
+Thu Jun 18 12:09:38 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * random.c (mix_pool): simpler handling for level 0
+
+Mon Jun 15 14:40:48 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * tiger.c: Removed from dist, will reappear as dynload module
+
+Sat Jun 13 14:16:57 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * pubkey.c: Major changes to allow extensions. Changed the inteface
+       of all public key ciphers and added the ability to load extensions
+       on demand.
+
+       * misc.c: Removed.
+
+Wed Jun 10 07:52:08 1998  Werner Koch,mobil,,, (wk@tobold)
+
+       * dynload.c: New.
+       * cipher.c: Major changes to allow extensions.
+
+Mon Jun  8 22:43:00 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * cipher.c: Major internal chnages to support extensions.
+       * blowfish.c (blowfish_get_info): New and made all internal
+       functions static, changed heder.
+       * cast5.c (cast5_get_info): Likewise.
+
+Mon Jun  8 12:27:52 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * tiger.c (transform): Fix for big endian
+
+       * cipher.c (do_cfb_decrypt): Big endian fix.
+
+Fri May 22 07:30:39 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * md.c (md_get_oid): Add a new one for TIGER.
+
+Thu May 21 13:24:52 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * cipher.c: Add support for a dummy cipher
+
+Thu May 14 15:40:36 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * rmd160.c (transform): fixed sigbus - I should better
+       add Christian von Roques's new implemenation of rmd160_write.
+
+Fri May  8 18:07:44 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * rand-internal.h, rand-unix.c, rand-w32.c, rand_dummy.c: New
+       * random.c: Moved system specific functions to rand-****.c
+
+Fri May  8 14:01:17 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * random.c (fast_random_poll): add call to gethrtime.
+
+Tue May  5 21:28:55 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * elgamal.c (elg_generate): choosing x was not correct, could
+       yield 6 bytes which are not from the random pool, tsss, tsss..
+
+Tue May  5 14:09:06 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * primegen.c (generate_elg_prime): Add arg mode, changed all
+       callers and implemented mode 1.
+
+Mon Apr 27 14:41:58 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * cipher.c (cipher_get_keylen): New.
+
+Sun Apr 26 14:44:52 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * tiger.c, tiger.h: New.
+
+Wed Apr  8 14:57:11 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * misc.c (check_pubkey_algo2): New.
+
+Tue Apr  7 18:46:49 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * cipher.c: New
+       * misc.c (check_cipher_algo): Moved to cipher.c
+       * cast5.c: Moved many functions to cipher.c
+       * blowfish.c: Likewise.
+
+Sat Apr  4 19:52:08 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * cast5.c: Implemented and tested.
+
+Wed Apr  1 16:38:27 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * elgamal.c (elg_generate): Faster generation of x in some cases.
+
+Thu Mar 19 13:54:48 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * blowfish.c (blowfish_decode_cfb): changed XOR operation
+       (blowfish_encode_cfb): Ditto.
+
+Thu Mar 12 14:04:05 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * sha1.c (transform): Rewrote
+
+       * blowfish.c (encrypt): Unrolled for rounds == 16
+       (decrypt): Ditto.
+
+Tue Mar 10 16:32:08 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * rmd160.c (transform): Unrolled the loop.
+
+Tue Mar 10 13:05:14 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * random.c (read_pool): Add pool_balance stuff.
+       (get_random_bits): New.
+
+       * elgamal.c (elg_generate): Now uses get_random_bits to generate x.
+
+
+Tue Mar 10 11:33:51 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * md.c (md_digest_length): New.
+
+Tue Mar 10 11:27:41 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * dsa.c (dsa_verify): Works.
+
+Mon Mar  9 12:59:08 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * dsa.c, dsa.h: Removed some unused code.
+
+Wed Mar  4 10:39:22 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * md.c (md_open): Add call to fast_random_poll.
+       blowfish.c (blowfish_setkey): Ditto.
+
+Tue Mar  3 13:32:54 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * rmd160.c (rmd160_mixblock): New.
+       * random.c: Restructured to start with a new RNG implementation.
+       * random.h: New.
+
+Mon Mar  2 19:21:46 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * gost.c, gost.h: Removed because they did only contain trash.
+
+Sun Mar  1 16:42:29 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * random.c (fill_buffer): removed error message if n == -1.
+
+Fri Feb 27 16:39:34 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * md.c (md_enable): No init if called twice.
+
+Thu Feb 26 07:57:02 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * primegen.c (generate_elg_prime): Changed the progress printing.
+       (gen_prime): Ditto.
+
+Tue Feb 24 12:28:42 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * md5.c, md.5 : Replaced by a modified version of md5.c from
+       GNU textutils 1.22.
+
+Wed Feb 18 14:08:30 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * md.c, md.h : New debugging support
+
+Mon Feb 16 10:08:47 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * misc.c (cipher_algo_to_string): New
+       (pubkey_algo_to_string): New.
+       (digest_algo_to_string): New.
+
+
+ Copyright 1998,1999,2000,2001,2002,2003,2004,2005,2006
+          2007, 2008, 2009 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/grub-core/lib/libgcrypt/cipher/ac.c b/grub-core/lib/libgcrypt/cipher/ac.c
new file mode 100644 (file)
index 0000000..ee9498b
--- /dev/null
@@ -0,0 +1,3301 @@
+/* ac.c - Alternative interface for asymmetric cryptography.
+   Copyright (C) 2003, 2004, 2005, 2006
+                 2007, 2008  Free Software Foundation, Inc.
+   This file is part of Libgcrypt.
+  
+   Libgcrypt is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser general Public License as
+   published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+  
+   Libgcrypt 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 Lesser General Public License for more details.
+  
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "mpi.h"
+
+\f
+
+/* At the moment the ac interface is a wrapper around the pk
+   interface, but this might change somewhen in the future, depending
+   on how many people prefer the ac interface.  */
+
+/* Mapping of flag numbers to the according strings as it is expected
+   for S-expressions.  */
+static struct number_string
+{
+  int number;
+  const char *string;
+} ac_flags[] =
+  {
+    { GCRY_AC_FLAG_NO_BLINDING, "no-blinding" },
+  };
+
+/* The positions in this list correspond to the values contained in
+   the gcry_ac_key_type_t enumeration list.  */
+static const char *ac_key_identifiers[] =
+  {
+    "private-key",
+    "public-key"
+  };
+
+/* These specifications are needed for key-pair generation; the caller
+   is allowed to pass additional, algorithm-specific `specs' to
+   gcry_ac_key_pair_generate.  This list is used for decoding the
+   provided values according to the selected algorithm.  */
+struct gcry_ac_key_generate_spec
+{
+  int algorithm;               /* Algorithm for which this flag is
+                                  relevant.  */
+  const char *name;            /* Name of this flag.  */
+  size_t offset;               /* Offset in the cipher-specific spec
+                                  structure at which the MPI value
+                                  associated with this flag is to be
+                                  found.  */
+} ac_key_generate_specs[] =
+  {
+    { GCRY_AC_RSA, "rsa-use-e", offsetof (gcry_ac_key_spec_rsa_t, e) },
+    { 0 }
+  };
+
+/* Handle structure.  */
+struct gcry_ac_handle
+{
+  int algorithm;               /* Algorithm ID associated with this
+                                  handle.  */
+  const char *algorithm_name;  /* Name of the algorithm.  */
+  unsigned int flags;          /* Flags, not used yet.  */
+  gcry_module_t module;                /* Reference to the algorithm
+                                  module.  */
+};
+
+/* A named MPI value.  */
+typedef struct gcry_ac_mpi
+{
+  char *name;                  /* Self-maintained copy of name.  */
+  gcry_mpi_t mpi;              /* MPI value.         */
+  unsigned int flags;          /* Flags.             */
+} gcry_ac_mpi_t;
+
+/* A data set, that is simply a list of named MPI values.  */
+struct gcry_ac_data
+{
+  gcry_ac_mpi_t *data;         /* List of named values.      */
+  unsigned int data_n;         /* Number of values in DATA.  */
+};
+
+/* A single key.  */
+struct gcry_ac_key
+{
+  gcry_ac_data_t data;         /* Data in native ac structure.  */
+  gcry_ac_key_type_t type;     /* Type of the key.              */
+};
+
+/* A key pair.  */
+struct gcry_ac_key_pair
+{
+  gcry_ac_key_t public;
+  gcry_ac_key_t secret;
+};
+
+\f
+
+/* 
+ * Functions for working with data sets.
+ */
+
+/* Creates a new, empty data set and store it in DATA.  */
+gcry_error_t
+_gcry_ac_data_new (gcry_ac_data_t *data)
+{
+  gcry_ac_data_t data_new;
+  gcry_error_t err;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  data_new = gcry_malloc (sizeof (*data_new));
+  if (! data_new)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+
+  data_new->data = NULL;
+  data_new->data_n = 0;
+  *data = data_new;
+  err = 0;
+
+ out:
+
+  return err;
+}
+
+/* Destroys all the entries in DATA, but not DATA itself.  */
+static void
+ac_data_values_destroy (gcry_ac_data_t data)
+{
+  unsigned int i;
+  
+  for (i = 0; i < data->data_n; i++)
+    if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
+      {
+       gcry_mpi_release (data->data[i].mpi);
+       gcry_free (data->data[i].name);
+      }
+}
+
+/* Destroys the data set DATA.  */
+void
+_gcry_ac_data_destroy (gcry_ac_data_t data)
+{
+  if (data)
+    {
+      ac_data_values_destroy (data);
+      gcry_free (data->data);
+      gcry_free (data);
+    }
+}
+
+/* This function creates a copy of the array of named MPIs DATA_MPIS,
+   which is of length DATA_MPIS_N; the copy is stored in
+   DATA_MPIS_CP.  */
+static gcry_error_t
+ac_data_mpi_copy (gcry_ac_mpi_t *data_mpis, unsigned int data_mpis_n,
+                 gcry_ac_mpi_t **data_mpis_cp)
+{
+  gcry_ac_mpi_t *data_mpis_new;
+  gcry_error_t err;
+  unsigned int i;
+  gcry_mpi_t mpi;
+  char *label;
+
+  data_mpis_new = gcry_malloc (sizeof (*data_mpis_new) * data_mpis_n);
+  if (! data_mpis_new)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+  memset (data_mpis_new, 0, sizeof (*data_mpis_new) * data_mpis_n);
+
+  err = 0;
+  for (i = 0; i < data_mpis_n; i++)
+    {
+      /* Copy values.  */
+
+      label = gcry_strdup (data_mpis[i].name);
+      mpi = gcry_mpi_copy (data_mpis[i].mpi);
+      if (! (label && mpi))
+       {
+         err = gcry_error_from_errno (errno);
+         gcry_mpi_release (mpi);
+         gcry_free (label);
+         break;
+       }
+
+      data_mpis_new[i].flags = GCRY_AC_FLAG_DEALLOC;
+      data_mpis_new[i].name = label;
+      data_mpis_new[i].mpi = mpi;
+    }
+  if (err)
+    goto out;
+
+  *data_mpis_cp = data_mpis_new;
+  err = 0;
+
+ out:
+
+  if (err)
+    if (data_mpis_new)
+      {
+       for (i = 0; i < data_mpis_n; i++)
+         {
+           gcry_mpi_release (data_mpis_new[i].mpi);
+           gcry_free (data_mpis_new[i].name);
+         }
+       gcry_free (data_mpis_new);
+      }
+
+  return err;
+}
+
+/* Create a copy of the data set DATA and store it in DATA_CP.  */
+gcry_error_t
+_gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data)
+{
+  gcry_ac_mpi_t *data_mpis = NULL;
+  gcry_ac_data_t data_new;
+  gcry_error_t err;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  /* Allocate data set.  */
+  data_new = gcry_malloc (sizeof (*data_new));
+  if (! data_new)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+
+  err = ac_data_mpi_copy (data->data, data->data_n, &data_mpis);
+  if (err)
+    goto out;
+  
+  data_new->data_n = data->data_n;
+  data_new->data = data_mpis;
+  *data_cp = data_new;
+
+ out:
+
+  if (err)
+    gcry_free (data_new);
+
+  return err;
+}
+
+/* Returns the number of named MPI values inside of the data set
+   DATA.  */
+unsigned int
+_gcry_ac_data_length (gcry_ac_data_t data)
+{
+  return data->data_n;
+}
+
+
+/* Add the value MPI to DATA with the label NAME.  If FLAGS contains
+   GCRY_AC_FLAG_COPY, the data set will contain copies of NAME
+   and MPI.  If FLAGS contains GCRY_AC_FLAG_DEALLOC or
+   GCRY_AC_FLAG_COPY, the values contained in the data set will
+   be deallocated when they are to be removed from the data set.  */
+gcry_error_t
+_gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
+                  const char *name, gcry_mpi_t mpi)
+{
+  gcry_error_t err;
+  gcry_mpi_t mpi_cp;
+  char *name_cp;
+  unsigned int i;
+
+  name_cp = NULL;
+  mpi_cp = NULL;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  if (flags & ~(GCRY_AC_FLAG_DEALLOC | GCRY_AC_FLAG_COPY))
+    {
+      err = gcry_error (GPG_ERR_INV_ARG);
+      goto out;
+    }
+
+  if (flags & GCRY_AC_FLAG_COPY)
+    {
+      /* Create copies.  */
+
+      flags |= GCRY_AC_FLAG_DEALLOC;
+      name_cp = gcry_strdup (name);
+      mpi_cp = gcry_mpi_copy (mpi);
+      if (! (name_cp && mpi_cp))
+       {
+         err = gcry_error_from_errno (errno);
+         goto out;
+       }
+    }
+
+  /* Search for existing entry.  */
+  for (i = 0; i < data->data_n; i++)
+    if (! strcmp (name, data->data[i].name))
+      break;
+  if (i < data->data_n)
+    {
+      /* An entry for NAME does already exist.  */
+      if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
+       {
+         gcry_mpi_release (data->data[i].mpi);
+         gcry_free (data->data[i].name);
+       }
+    }
+  else
+    {
+      /* Create a new entry.  */
+
+      gcry_ac_mpi_t *ac_mpis;
+
+      ac_mpis = gcry_realloc (data->data,
+                             sizeof (*data->data) * (data->data_n + 1));
+      if (! ac_mpis)
+       {
+         err = gcry_error_from_errno (errno);
+         goto out;
+       }
+
+      if (data->data != ac_mpis)
+       data->data = ac_mpis;
+      data->data_n++;
+    }
+
+  data->data[i].name = name_cp ? name_cp : ((char *) name);
+  data->data[i].mpi = mpi_cp ? mpi_cp : mpi;
+  data->data[i].flags = flags;
+  err = 0;
+
+ out:
+
+  if (err)
+    {
+      gcry_mpi_release (mpi_cp);
+      gcry_free (name_cp);
+    }
+
+  return err;
+}
+
+/* Stores the value labelled with NAME found in the data set DATA in
+   MPI.  The returned MPI value will be released in case
+   gcry_ac_data_set is used to associate the label NAME with a
+   different MPI value.  */
+gcry_error_t
+_gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
+                       const char *name, gcry_mpi_t *mpi)
+{
+  gcry_mpi_t mpi_return;
+  gcry_error_t err;
+  unsigned int i;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  if (flags & ~(GCRY_AC_FLAG_COPY))
+    {
+      err = gcry_error (GPG_ERR_INV_ARG);
+      goto out;
+    }
+
+  for (i = 0; i < data->data_n; i++)
+    if (! strcmp (name, data->data[i].name))
+      break;
+  if (i == data->data_n)
+    {
+      err = gcry_error (GPG_ERR_NOT_FOUND);
+      goto out;
+    }
+
+  if (flags & GCRY_AC_FLAG_COPY)
+    {
+      mpi_return = gcry_mpi_copy (data->data[i].mpi);
+      if (! mpi_return)
+       {
+         err = gcry_error_from_errno (errno); /* FIXME? */
+         goto out;
+       }
+    }
+  else
+    mpi_return = data->data[i].mpi;
+
+  *mpi = mpi_return;
+  err = 0;
+
+ out:
+
+  return err;
+}
+
+/* Stores in NAME and MPI the named MPI value contained in the data
+   set DATA with the index IDX.  NAME or MPI may be NULL.  The
+   returned MPI value will be released in case gcry_ac_data_set is
+   used to associate the label NAME with a different MPI value.  */
+gcry_error_t
+_gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
+                        unsigned int idx,
+                        const char **name, gcry_mpi_t *mpi)
+{
+  gcry_error_t err;
+  gcry_mpi_t mpi_cp;
+  char *name_cp;
+
+  name_cp = NULL;
+  mpi_cp = NULL;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  if (flags & ~(GCRY_AC_FLAG_COPY))
+    {
+      err = gcry_error (GPG_ERR_INV_ARG);
+      goto out;
+    }
+
+  if (idx >= data->data_n)
+    {
+      err = gcry_error (GPG_ERR_INV_ARG);
+      goto out;
+    }
+
+  if (flags & GCRY_AC_FLAG_COPY)
+    {
+      /* Return copies to the user.  */
+      if (name)
+       {
+         name_cp = gcry_strdup (data->data[idx].name);
+         if (! name_cp)
+           {
+             err = gcry_error_from_errno (errno);
+             goto out;
+           }
+       }
+      if (mpi)
+       {
+         mpi_cp = gcry_mpi_copy (data->data[idx].mpi);
+         if (! mpi_cp)
+           {
+             err = gcry_error_from_errno (errno);
+             goto out;
+           }
+       }
+    }
+
+  if (name)
+    *name = name_cp ? name_cp : data->data[idx].name;
+  if (mpi)
+    *mpi = mpi_cp ? mpi_cp : data->data[idx].mpi;
+  err = 0;
+
+ out:
+
+  if (err)
+    {
+      gcry_mpi_release (mpi_cp);
+      gcry_free (name_cp);
+    }
+
+  return err;
+}
+
+/* Convert the data set DATA into a new S-Expression, which is to be
+   stored in SEXP, according to the identifiers contained in
+   IDENTIFIERS.  */
+gcry_error_t
+_gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
+                      const char **identifiers)
+{
+  gcry_sexp_t sexp_new;
+  gcry_error_t err;
+  char *sexp_buffer;
+  size_t sexp_buffer_n;
+  size_t identifiers_n;
+  const char *label;
+  gcry_mpi_t mpi;
+  void **arg_list;
+  size_t data_n;
+  unsigned int i;
+
+  sexp_buffer_n = 1;
+  sexp_buffer = NULL;
+  arg_list = NULL;
+  err = 0;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  /* Calculate size of S-expression representation.  */
+
+  i = 0;
+  if (identifiers)
+    while (identifiers[i])
+      {
+       /* For each identifier, we add "(<IDENTIFIER>)".  */
+       sexp_buffer_n += 1 + strlen (identifiers[i]) + 1;
+       i++;
+      }
+  identifiers_n = i;
+  
+  if (! identifiers_n)
+    /* If there are NO identifiers, we still add surrounding braces so
+       that we have a list of named MPI value lists.  Otherwise it
+       wouldn't be too much fun to process these lists.  */
+    sexp_buffer_n += 2;
+  
+  data_n = _gcry_ac_data_length (data);
+  for (i = 0; i < data_n; i++)
+    {
+      err = gcry_ac_data_get_index (data, 0, i, &label, NULL);
+      if (err)
+       break;
+      /* For each MPI we add "(<LABEL> %m)".  */
+      sexp_buffer_n += 1 + strlen (label) + 4;
+    }
+  if (err)
+    goto out;
+
+  /* Allocate buffer.  */
+
+  sexp_buffer = gcry_malloc (sexp_buffer_n);
+  if (! sexp_buffer)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+
+  /* Fill buffer.  */
+
+  *sexp_buffer = 0;
+  sexp_buffer_n = 0;
+
+  /* Add identifiers: (<IDENTIFIER0>(<IDENTIFIER1>...)).  */
+  if (identifiers_n)
+    {
+      /* Add nested identifier lists as usual.  */
+      for (i = 0; i < identifiers_n; i++)
+       sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(%s",
+                                 identifiers[i]);
+    }
+  else
+    {
+      /* Add special list.  */
+      sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(");
+    }
+
+  /* Add MPI list.  */
+  arg_list = gcry_malloc (sizeof (*arg_list) * (data_n + 1));
+  if (! arg_list)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+  for (i = 0; i < data_n; i++)
+    {
+      err = gcry_ac_data_get_index (data, 0, i, &label, &mpi);
+      if (err)
+       break;
+      sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n,
+                               "(%s %%m)", label);
+      arg_list[i] = &data->data[i].mpi;
+    }
+  if (err)
+    goto out;
+
+  if (identifiers_n)
+    {
+      /* Add closing braces for identifier lists as usual.  */
+      for (i = 0; i < identifiers_n; i++)
+       sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")");
+    }
+  else
+    {
+      /* Add closing braces for special list.  */
+      sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")");
+    }
+
+  /* Construct.  */
+  err = gcry_sexp_build_array (&sexp_new, NULL, sexp_buffer, arg_list);
+  if (err)
+    goto out;
+
+  *sexp = sexp_new;
+
+ out:
+
+  gcry_free (sexp_buffer);
+  gcry_free (arg_list);
+
+  return err;
+}
+
+/* Create a new data set, which is to be stored in DATA_SET, from the
+   S-Expression SEXP, according to the identifiers contained in
+   IDENTIFIERS.  */
+gcry_error_t
+_gcry_ac_data_from_sexp (gcry_ac_data_t *data_set, gcry_sexp_t sexp,
+                        const char **identifiers)
+{
+  gcry_ac_data_t data_set_new;
+  gcry_error_t err;
+  gcry_sexp_t sexp_cur;
+  gcry_sexp_t sexp_tmp;
+  gcry_mpi_t mpi;
+  char *string;
+  const char *data;
+  size_t data_n;
+  size_t sexp_n;
+  unsigned int i;
+  int skip_name;
+
+  data_set_new = NULL;
+  sexp_cur = sexp;
+  sexp_tmp = NULL;
+  string = NULL;
+  mpi = NULL;
+  err = 0;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  /* Process S-expression/identifiers.  */
+
+  if (identifiers)
+    {
+      for (i = 0; identifiers[i]; i++)
+       {
+         /* Next identifier.  Extract first data item from
+            SEXP_CUR.  */
+         data = gcry_sexp_nth_data (sexp_cur, 0, &data_n);
+
+         if (! ((data_n == strlen (identifiers[i]))
+                && (! strncmp (data, identifiers[i], data_n))))
+           {
+             /* Identifier mismatch -> error.  */
+             err = gcry_error (GPG_ERR_INV_SEXP);
+             break;
+           }
+
+         /* Identifier matches.  Now we have to distinguish two
+            cases:
+            
+            (i)  we are at the last identifier:
+            leave loop
+
+            (ii) we are not at the last identifier:
+            extract next element, which is supposed to be a
+            sublist.  */
+
+         if (! identifiers[i + 1])
+           /* Last identifier.  */
+           break;
+         else
+           {
+             /* Not the last identifier, extract next sublist.  */
+
+             sexp_tmp = gcry_sexp_nth (sexp_cur, 1);
+             if (! sexp_tmp)
+               {
+                 /* Missing sublist.  */
+                 err = gcry_error (GPG_ERR_INV_SEXP);
+                 break;
+               }
+
+             /* Release old SEXP_CUR, in case it is not equal to the
+                original SEXP.  */
+             if (sexp_cur != sexp)
+               gcry_sexp_release (sexp_cur);
+
+             /* Make SEXP_CUR point to the new current sublist.  */
+             sexp_cur = sexp_tmp;
+              sexp_tmp = NULL;
+           }
+       }
+      if (err)
+       goto out;
+
+      if (i)
+        {
+          /* We have at least one identifier in the list, this means
+             the the list of named MPI values is prefixed, this means
+             that we need to skip the first item (the list name), when
+             processing the MPI values.  */
+          skip_name = 1;
+        }
+      else
+        {
+          /* Since there is no identifiers list, the list of named MPI
+             values is not prefixed with a list name, therefore the
+             offset to use is zero.  */
+          skip_name = 0;
+        }
+    }
+  else
+    /* Since there is no identifiers list, the list of named MPI
+       values is not prefixed with a list name, therefore the offset
+       to use is zero.  */
+    skip_name = 0;
+
+  /* Create data set from S-expression data.  */
+  
+  err = gcry_ac_data_new (&data_set_new);
+  if (err)
+    goto out;
+
+  /* Figure out amount of named MPIs in SEXP_CUR.  */
+  if (sexp_cur)
+    sexp_n = gcry_sexp_length (sexp_cur) - skip_name;
+  else
+    sexp_n = 0;
+
+  /* Extracte the named MPIs sequentially.  */
+  for (i = 0; i < sexp_n; i++)
+    {
+      /* Store next S-Expression pair, which is supposed to consist of
+        a name and an MPI value, in SEXP_TMP.  */
+
+      sexp_tmp = gcry_sexp_nth (sexp_cur, i + skip_name);
+      if (! sexp_tmp)
+       {
+         err = gcry_error (GPG_ERR_INV_SEXP);
+         break;
+       }
+
+      /* Extract name from current S-Expression pair.  */
+      data = gcry_sexp_nth_data (sexp_tmp, 0, &data_n);
+      string = gcry_malloc (data_n + 1);
+      if (! string)
+       {
+         err = gcry_error_from_errno (errno);
+         break;
+       }
+      memcpy (string, data, data_n);
+      string[data_n] = 0;
+
+      /* Extract MPI value.  */
+      mpi = gcry_sexp_nth_mpi (sexp_tmp, 1, 0);
+      if (! mpi)
+       {
+         err = gcry_error (GPG_ERR_INV_SEXP); /* FIXME? */
+         break;
+       }
+
+      /* Store named MPI in data_set_new.  */
+      err = gcry_ac_data_set (data_set_new, GCRY_AC_FLAG_DEALLOC, string, mpi);
+      if (err)
+       break;
+
+/*       gcry_free (string); */
+      string = NULL;
+/*       gcry_mpi_release (mpi); */
+      mpi = NULL;
+
+      gcry_sexp_release (sexp_tmp);
+      sexp_tmp = NULL;
+    }
+  if (err)
+    goto out;
+
+  *data_set = data_set_new;
+
+ out:
+
+  if (sexp_cur != sexp)
+    gcry_sexp_release (sexp_cur);
+  gcry_sexp_release (sexp_tmp);
+  gcry_mpi_release (mpi);
+  gcry_free (string);
+  
+  if (err)
+    gcry_ac_data_destroy (data_set_new);
+
+  return err;
+}
+
+
+static void
+_gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data)
+{
+  unsigned char *mpi_buffer;
+  size_t mpi_buffer_n;
+  unsigned int data_n;
+  gcry_error_t err;
+  const char *name;
+  gcry_mpi_t mpi;
+  unsigned int i;
+
+  if (! data)
+    return;
+
+  if (fips_mode ())
+    return;
+
+  mpi_buffer = NULL;
+
+  data_n = _gcry_ac_data_length (data);
+  for (i = 0; i < data_n; i++)
+    {
+      err = gcry_ac_data_get_index (data, 0, i, &name, &mpi);
+      if (err)
+       {
+         log_error ("failed to dump data set");
+         break;
+       }
+
+      err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &mpi_buffer, &mpi_buffer_n, mpi);
+      if (err)
+       {
+         log_error ("failed to dump data set");
+         break;
+       }
+
+      log_printf ("%s%s%s: %s\n",
+                 prefix ? prefix : "",
+                 prefix ? ": " : ""
+                 , name, mpi_buffer);
+
+      gcry_free (mpi_buffer);
+      mpi_buffer = NULL;
+    }
+
+  gcry_free (mpi_buffer);
+}
+
+/* Dump the named MPI values contained in the data set DATA to
+   Libgcrypt's logging stream.  */
+void
+gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data)
+{
+  _gcry_ac_data_dump (prefix, data);
+}
+
+/* Destroys any values contained in the data set DATA.  */
+void
+_gcry_ac_data_clear (gcry_ac_data_t data)
+{
+  ac_data_values_destroy (data);
+  gcry_free (data->data);
+  data->data = NULL;
+  data->data_n = 0;
+}
+
+\f
+
+/*
+ * Implementation of `ac io' objects.
+ */
+
+/* Initialize AC_IO according to MODE, TYPE and the variable list of
+   arguments AP.  The list of variable arguments to specify depends on
+   the given TYPE.  */
+void
+_gcry_ac_io_init_va (gcry_ac_io_t *ac_io,
+                    gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, va_list ap)
+{
+  memset (ac_io, 0, sizeof (*ac_io));
+
+  if (fips_mode ())
+    return;
+
+  gcry_assert ((mode == GCRY_AC_IO_READABLE) || (mode == GCRY_AC_IO_WRITABLE));
+  gcry_assert ((type == GCRY_AC_IO_STRING) || (type == GCRY_AC_IO_STRING));
+
+  ac_io->mode = mode;
+  ac_io->type = type;
+
+  switch (mode)
+    {
+    case GCRY_AC_IO_READABLE:
+      switch (type)
+       {
+       case GCRY_AC_IO_STRING:
+         ac_io->io.readable.string.data = va_arg (ap, unsigned char *);
+         ac_io->io.readable.string.data_n = va_arg (ap, size_t);
+         break;
+
+       case GCRY_AC_IO_CALLBACK:
+         ac_io->io.readable.callback.cb = va_arg (ap, gcry_ac_data_read_cb_t);
+         ac_io->io.readable.callback.opaque = va_arg (ap, void *);
+         break;
+       }
+      break;
+    case GCRY_AC_IO_WRITABLE:
+      switch (type)
+       {
+       case GCRY_AC_IO_STRING:
+         ac_io->io.writable.string.data = va_arg (ap, unsigned char **);
+         ac_io->io.writable.string.data_n = va_arg (ap, size_t *);
+         break;
+
+       case GCRY_AC_IO_CALLBACK:
+         ac_io->io.writable.callback.cb = va_arg (ap, gcry_ac_data_write_cb_t);
+         ac_io->io.writable.callback.opaque = va_arg (ap, void *);
+         break;
+       }
+      break;
+    }
+}
+
+/* Initialize AC_IO according to MODE, TYPE and the variable list of
+   arguments.  The list of variable arguments to specify depends on
+   the given TYPE. */
+void
+_gcry_ac_io_init (gcry_ac_io_t *ac_io,
+                 gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, ...)
+{
+  va_list ap;
+
+  va_start (ap, type);
+  _gcry_ac_io_init_va (ac_io, mode, type, ap);
+  va_end (ap);
+}
+
+
+/* Write to the IO object AC_IO BUFFER_N bytes from BUFFER.  Return
+   zero on success or error code.  */
+static gcry_error_t
+_gcry_ac_io_write (gcry_ac_io_t *ac_io, unsigned char *buffer, size_t buffer_n)
+{
+  gcry_error_t err;
+
+  gcry_assert (ac_io->mode == GCRY_AC_IO_WRITABLE);
+  err = 0;
+
+  switch (ac_io->type)
+    {
+    case GCRY_AC_IO_STRING:
+      {
+       unsigned char *p;
+
+       if (*ac_io->io.writable.string.data)
+         {
+           p = gcry_realloc (*ac_io->io.writable.string.data,
+                             *ac_io->io.writable.string.data_n + buffer_n);
+           if (! p)
+             err = gcry_error_from_errno (errno);
+           else
+             {
+               if (*ac_io->io.writable.string.data != p)
+                 *ac_io->io.writable.string.data = p;
+               memcpy (p + *ac_io->io.writable.string.data_n, buffer, buffer_n);
+               *ac_io->io.writable.string.data_n += buffer_n;
+             }
+         }
+       else
+         {
+           if (gcry_is_secure (buffer))
+             p = gcry_malloc_secure (buffer_n);
+           else
+             p = gcry_malloc (buffer_n);
+           if (! p)
+             err = gcry_error_from_errno (errno);
+           else
+             {
+               memcpy (p, buffer, buffer_n);
+               *ac_io->io.writable.string.data = p;
+               *ac_io->io.writable.string.data_n = buffer_n;
+             }
+         }
+      }
+      break;
+
+    case GCRY_AC_IO_CALLBACK:
+      err = (*ac_io->io.writable.callback.cb) (ac_io->io.writable.callback.opaque,
+                                              buffer, buffer_n);
+      break;
+    }
+
+  return err;
+}
+
+/* Read *BUFFER_N bytes from the IO object AC_IO into BUFFER; NREAD
+   bytes have already been read from the object; on success, store the
+   amount of bytes read in *BUFFER_N; zero bytes read means EOF.
+   Return zero on success or error code.  */
+static gcry_error_t
+_gcry_ac_io_read (gcry_ac_io_t *ac_io,
+                 unsigned int nread, unsigned char *buffer, size_t *buffer_n)
+{
+  gcry_error_t err;
+  
+  gcry_assert (ac_io->mode == GCRY_AC_IO_READABLE);
+  err = 0;
+
+  switch (ac_io->type)
+    {
+    case GCRY_AC_IO_STRING:
+      {
+       size_t bytes_available;
+       size_t bytes_to_read;
+       size_t bytes_wanted;
+
+       bytes_available = ac_io->io.readable.string.data_n - nread;
+       bytes_wanted = *buffer_n;
+
+       if (bytes_wanted > bytes_available)
+         bytes_to_read = bytes_available;
+       else
+         bytes_to_read = bytes_wanted;
+
+       memcpy (buffer, ac_io->io.readable.string.data + nread, bytes_to_read);
+       *buffer_n = bytes_to_read;
+       err = 0;
+       break;
+      }
+
+    case GCRY_AC_IO_CALLBACK:
+      err = (*ac_io->io.readable.callback.cb)
+       (ac_io->io.readable.callback.opaque, buffer, buffer_n);
+      break;
+    }
+
+  return err;
+}
+
+/* Read all data available from the IO object AC_IO into newly
+   allocated memory, storing an appropriate pointer in *BUFFER and the
+   amount of bytes read in *BUFFER_N.  Return zero on success or error
+   code.  */
+static gcry_error_t
+_gcry_ac_io_read_all (gcry_ac_io_t *ac_io, unsigned char **buffer, size_t *buffer_n)
+{
+  unsigned char *buffer_new;
+  size_t buffer_new_n;
+  unsigned char buf[BUFSIZ];
+  size_t buf_n;
+  unsigned char *p;
+  gcry_error_t err;
+
+  buffer_new = NULL;
+  buffer_new_n = 0;
+
+  while (1)
+    {
+      buf_n = sizeof (buf);
+      err = _gcry_ac_io_read (ac_io, buffer_new_n, buf, &buf_n);
+      if (err)
+       break;
+
+      if (buf_n)
+       {
+         p = gcry_realloc (buffer_new, buffer_new_n + buf_n);
+         if (! p)
+           {
+             err = gcry_error_from_errno (errno);
+             break;
+           }
+         
+         if (buffer_new != p)
+           buffer_new = p;
+
+         memcpy (buffer_new + buffer_new_n, buf, buf_n);
+         buffer_new_n += buf_n;
+       }
+      else
+       break;
+    }
+  if (err)
+    goto out;
+
+  *buffer_n = buffer_new_n;
+  *buffer = buffer_new;
+
+ out:
+
+  if (err)
+    gcry_free (buffer_new);
+
+  return err;
+}
+
+/* Read data chunks from the IO object AC_IO until EOF, feeding them
+   to the callback function CB.  Return zero on success or error
+   code.  */
+static gcry_error_t
+_gcry_ac_io_process (gcry_ac_io_t *ac_io,
+                    gcry_ac_data_write_cb_t cb, void *opaque)
+{
+  unsigned char buffer[BUFSIZ];
+  unsigned int nread;
+  size_t buffer_n;
+  gcry_error_t err;
+
+  nread = 0;
+
+  while (1)
+    {
+      buffer_n = sizeof (buffer);
+      err = _gcry_ac_io_read (ac_io, nread, buffer, &buffer_n);
+      if (err)
+       break;
+      if (buffer_n)
+       {
+         err = (*cb) (opaque, buffer, buffer_n);
+         if (err)
+           break;
+         nread += buffer_n;
+       }
+      else
+       break;
+    }
+
+  return err;
+}
+
+\f
+
+/* 
+ * Functions for converting data between the native ac and the
+ * S-expression structure used by the pk interface.
+ */
+
+/* Extract the S-Expression DATA_SEXP into DATA under the control of
+   TYPE and NAME.  This function assumes that S-Expressions are of the
+   following structure:
+
+   (IDENTIFIER [...]
+   (ALGORITHM <list of named MPI values>)) */
+static gcry_error_t
+ac_data_extract (const char *identifier, const char *algorithm,
+                gcry_sexp_t sexp, gcry_ac_data_t *data)
+{
+  gcry_error_t err;
+  gcry_sexp_t value_sexp;
+  gcry_sexp_t data_sexp;
+  size_t data_sexp_n;
+  gcry_mpi_t value_mpi;
+  char *value_name;
+  const char *data_raw;
+  size_t data_raw_n;
+  gcry_ac_data_t data_new;
+  unsigned int i;
+
+  value_sexp = NULL;
+  data_sexp = NULL;
+  value_name = NULL;
+  value_mpi = NULL;
+  data_new = NULL;
+
+  /* Verify that the S-expression contains the correct identifier.  */
+  data_raw = gcry_sexp_nth_data (sexp, 0, &data_raw_n);
+  if ((! data_raw) || strncmp (identifier, data_raw, data_raw_n))
+    {
+      err = gcry_error (GPG_ERR_INV_SEXP);
+      goto out;
+    }
+
+  /* Extract inner S-expression.  */
+  data_sexp = gcry_sexp_find_token (sexp, algorithm, 0);
+  if (! data_sexp)
+    {
+      err = gcry_error (GPG_ERR_INV_SEXP);
+      goto out;
+    }
+
+  /* Count data elements.  */
+  data_sexp_n = gcry_sexp_length (data_sexp);
+  data_sexp_n--;
+
+  /* Allocate new data set.  */
+  err = _gcry_ac_data_new (&data_new);
+  if (err)
+    goto out;
+
+  /* Iterate through list of data elements and add them to the data
+     set.  */
+  for (i = 0; i < data_sexp_n; i++)
+    {
+      /* Get the S-expression of the named MPI, that contains the name
+        and the MPI value.  */
+      value_sexp = gcry_sexp_nth (data_sexp, i + 1);
+      if (! value_sexp)
+       {
+         err = gcry_error (GPG_ERR_INV_SEXP);
+         break;
+       }
+
+      /* Extract the name.  */
+      data_raw = gcry_sexp_nth_data (value_sexp, 0, &data_raw_n);
+      if (! data_raw)
+       {
+         err = gcry_error (GPG_ERR_INV_SEXP);
+         break;
+       }
+
+      /* Extract the MPI value.  */
+      value_mpi = gcry_sexp_nth_mpi (value_sexp, 1, GCRYMPI_FMT_USG);
+      if (! value_mpi)
+       {
+         err = gcry_error (GPG_ERR_INTERNAL); /* FIXME? */
+         break;
+       }
+
+      /* Duplicate the name.  */
+      value_name = gcry_malloc (data_raw_n + 1);
+      if (! value_name)
+       {
+         err = gcry_error_from_errno (errno);
+         break;
+       }
+      strncpy (value_name, data_raw, data_raw_n);
+      value_name[data_raw_n] = 0;
+
+      err = _gcry_ac_data_set (data_new, GCRY_AC_FLAG_DEALLOC, value_name, value_mpi);
+      if (err)
+       break;
+
+      gcry_sexp_release (value_sexp);
+      value_sexp = NULL;
+      value_name = NULL;
+      value_mpi = NULL;
+    }
+  if (err)
+    goto out;
+
+  /* Copy out.  */
+  *data = data_new;
+
+ out:
+
+  /* Deallocate resources.  */
+  if (err)
+    {
+      _gcry_ac_data_destroy (data_new);
+      gcry_mpi_release (value_mpi);
+      gcry_free (value_name);
+      gcry_sexp_release (value_sexp);
+    }
+  gcry_sexp_release (data_sexp);
+
+  return err;
+}
+
+/* Construct an S-expression from the DATA and store it in
+   DATA_SEXP. The S-expression will be of the following structure:
+
+   (IDENTIFIER [(flags [...])]
+   (ALGORITHM <list of named MPI values>))  */
+static gcry_error_t
+ac_data_construct (const char *identifier, int include_flags,
+                  unsigned int flags, const char *algorithm,
+                  gcry_ac_data_t data, gcry_sexp_t *sexp)
+{
+  unsigned int data_length;
+  gcry_sexp_t sexp_new;
+  gcry_error_t err;
+  size_t sexp_format_n;
+  char *sexp_format;
+  void **arg_list;
+  unsigned int i;
+
+  arg_list = NULL;
+  sexp_new = NULL;
+  sexp_format = NULL;
+
+  /* We build a list of arguments to pass to
+     gcry_sexp_build_array().  */
+  data_length = _gcry_ac_data_length (data);
+  arg_list = gcry_malloc (sizeof (*arg_list) * (data_length * 2));
+  if (! arg_list)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+
+  /* Fill list with MPIs.  */
+  for (i = 0; i < data_length; i++)
+    {
+      char **nameaddr  = &data->data[i].name;
+
+      arg_list[(i * 2) + 0] = nameaddr;
+      arg_list[(i * 2) + 1] = &data->data[i].mpi;
+    }
+
+  /* Calculate size of format string.  */
+  sexp_format_n = (3
+                  + (include_flags ? 7 : 0)
+                  + (algorithm ? (2 + strlen (algorithm)) : 0)
+                  + strlen (identifier));
+
+  for (i = 0; i < data_length; i++)
+    /* Per-element sizes.  */
+    sexp_format_n += 6;
+
+  if (include_flags)
+    /* Add flags.  */
+    for (i = 0; i < DIM (ac_flags); i++)
+      if (flags & ac_flags[i].number)
+       sexp_format_n += strlen (ac_flags[i].string) + 1;
+
+  /* Done.  */
+  sexp_format = gcry_malloc (sexp_format_n);
+  if (! sexp_format)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+
+  /* Construct the format string.  */
+
+  *sexp_format = 0;
+  strcat (sexp_format, "(");
+  strcat (sexp_format, identifier);
+  if (include_flags)
+    {
+      strcat (sexp_format, "(flags");
+      for (i = 0; i < DIM (ac_flags); i++)
+       if (flags & ac_flags[i].number)
+         {
+           strcat (sexp_format, " ");
+           strcat (sexp_format, ac_flags[i].string);
+         }
+      strcat (sexp_format, ")");
+    }
+  if (algorithm)
+    {
+      strcat (sexp_format, "(");
+      strcat (sexp_format, algorithm);
+    }
+  for (i = 0; i < data_length; i++)
+    strcat (sexp_format, "(%s%m)");
+  if (algorithm)
+    strcat (sexp_format, ")");
+  strcat (sexp_format, ")");
+
+  /* Create final S-expression.  */
+  err = gcry_sexp_build_array (&sexp_new, NULL, sexp_format, arg_list);
+  if (err)
+    goto out;
+
+  *sexp = sexp_new;
+
+ out:
+
+  /* Deallocate resources.  */
+  gcry_free (sexp_format);
+  gcry_free (arg_list);
+  if (err)
+    gcry_sexp_release (sexp_new);
+
+  return err;
+}
+
+\f
+
+/*
+ * Handle management.
+ */
+
+/* Creates a new handle for the algorithm ALGORITHM and stores it in
+   HANDLE.  FLAGS is not used yet.  */
+gcry_error_t
+_gcry_ac_open (gcry_ac_handle_t *handle,
+              gcry_ac_id_t algorithm, unsigned int flags)
+{
+  gcry_ac_handle_t handle_new;
+  const char *algorithm_name;
+  gcry_module_t module;
+  gcry_error_t err;
+
+  *handle = NULL;
+  module = NULL;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  /* Get name.  */
+  algorithm_name = _gcry_pk_aliased_algo_name (algorithm);
+  if (! algorithm_name)
+    {
+      err = gcry_error (GPG_ERR_PUBKEY_ALGO);
+      goto out;
+    }
+
+  /* Acquire reference to the pubkey module.  */
+  err = _gcry_pk_module_lookup (algorithm, &module);
+  if (err)
+    goto out;
+  
+  /* Allocate.  */
+  handle_new = gcry_malloc (sizeof (*handle_new));
+  if (! handle_new)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+
+  /* Done.  */
+  handle_new->algorithm = algorithm;
+  handle_new->algorithm_name = algorithm_name;
+  handle_new->flags = flags;
+  handle_new->module = module;
+  *handle = handle_new;
+
+ out:
+  
+  /* Deallocate resources.  */
+  if (err)
+    _gcry_pk_module_release (module);
+
+  return err;
+}
+
+
+/* Destroys the handle HANDLE.  */
+void
+_gcry_ac_close (gcry_ac_handle_t handle)
+{
+  /* Release reference to pubkey module.  */
+  if (handle)
+    {
+      _gcry_pk_module_release (handle->module);
+      gcry_free (handle);
+    }
+}
+
+
+\f
+/* 
+ * Key management.
+ */
+
+/* Initialize a key from a given data set.  */
+/* FIXME/Damn: the argument HANDLE is not only unnecessary, it is
+   completely WRONG here.  */
+gcry_error_t
+_gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
+                  gcry_ac_key_type_t type, gcry_ac_data_t data)
+{
+  gcry_ac_data_t data_new;
+  gcry_ac_key_t key_new;
+  gcry_error_t err;
+
+  (void)handle;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  /* Allocate.  */
+  key_new = gcry_malloc (sizeof (*key_new));
+  if (! key_new)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+
+  /* Copy data set.  */
+  err = _gcry_ac_data_copy (&data_new, data);
+  if (err)
+    goto out;
+
+  /* Done.  */
+  key_new->data = data_new;
+  key_new->type = type;
+  *key = key_new;
+
+ out:
+
+  if (err)
+    /* Deallocate resources.  */
+    gcry_free (key_new);
+
+  return err;
+}
+
+
+/* Generates a new key pair via the handle HANDLE of NBITS bits and
+   stores it in KEY_PAIR.  In case non-standard settings are wanted, a
+   pointer to a structure of type gcry_ac_key_spec_<algorithm>_t,
+   matching the selected algorithm, can be given as KEY_SPEC.
+   MISC_DATA is not used yet.  */
+gcry_error_t
+_gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits,
+                           void *key_spec,
+                           gcry_ac_key_pair_t *key_pair,
+                           gcry_mpi_t **misc_data)
+{
+  gcry_sexp_t genkey_sexp_request;
+  gcry_sexp_t genkey_sexp_reply;
+  gcry_ac_data_t key_data_secret;
+  gcry_ac_data_t key_data_public;
+  gcry_ac_key_pair_t key_pair_new;
+  gcry_ac_key_t key_secret;
+  gcry_ac_key_t key_public;
+  gcry_sexp_t key_sexp;
+  gcry_error_t err;
+  char *genkey_format;
+  size_t genkey_format_n;
+  void **arg_list;
+  size_t arg_list_n;
+  unsigned int i;
+  unsigned int j;
+
+  (void)misc_data;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  key_data_secret = NULL;
+  key_data_public = NULL;
+  key_secret = NULL;
+  key_public = NULL;
+  genkey_format = NULL;
+  arg_list = NULL;
+  genkey_sexp_request = NULL;
+  genkey_sexp_reply = NULL;
+  key_sexp = NULL;
+
+  /* Allocate key pair.  */
+  key_pair_new = gcry_malloc (sizeof (struct gcry_ac_key_pair));
+  if (! key_pair_new)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+
+  /* Allocate keys.  */
+  key_secret = gcry_malloc (sizeof (*key_secret));
+  if (! key_secret)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+  key_public = gcry_malloc (sizeof (*key_public));
+  if (! key_public)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+
+  /* Calculate size of the format string, that is used for creating
+     the request S-expression.  */
+  genkey_format_n = 22;
+
+  /* Respect any relevant algorithm specific commands.  */
+  if (key_spec)
+    for (i = 0; i < DIM (ac_key_generate_specs); i++)
+      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
+       genkey_format_n += 6;
+
+  /* Create format string.  */
+  genkey_format = gcry_malloc (genkey_format_n);
+  if (! genkey_format)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+
+  /* Fill format string.  */
+  *genkey_format = 0;
+  strcat (genkey_format, "(genkey(%s(nbits%d)");
+  if (key_spec)
+    for (i = 0; i < DIM (ac_key_generate_specs); i++)
+      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
+       strcat (genkey_format, "(%s%m)");
+  strcat (genkey_format, "))");
+
+  /* Build list of argument pointers, the algorithm name and the nbits
+     are always needed.  */
+  arg_list_n = 2;
+
+  /* Now the algorithm specific arguments.  */
+  if (key_spec)
+    for (i = 0; i < DIM (ac_key_generate_specs); i++)
+      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
+       arg_list_n += 2;
+
+  /* Allocate list.  */
+  arg_list = gcry_malloc (sizeof (*arg_list) * arg_list_n);
+  if (! arg_list)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+
+  arg_list[0] = (void *) &handle->algorithm_name;
+  arg_list[1] = (void *) &nbits;
+  if (key_spec)
+    for (j = 2, i = 0; i < DIM (ac_key_generate_specs); i++)
+      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
+       {
+         /* Add name of this specification flag and the
+            according member of the spec strucuture.  */
+         arg_list[j++] = (void *)(&ac_key_generate_specs[i].name);
+         arg_list[j++] = (void *)
+           (((char *) key_spec)
+            + ac_key_generate_specs[i].offset);
+         /* FIXME: above seems to suck.  */
+       }
+
+  /* Construct final request S-expression.  */
+  err = gcry_sexp_build_array (&genkey_sexp_request,
+                              NULL, genkey_format, arg_list);
+  if (err)
+    goto out;
+
+  /* Perform genkey operation.  */
+  err = gcry_pk_genkey (&genkey_sexp_reply, genkey_sexp_request);
+  if (err)
+    goto out;
+
+  key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "private-key", 0);
+  if (! key_sexp)
+    {
+      err = gcry_error (GPG_ERR_INTERNAL);
+      goto out;
+    }
+  err = ac_data_extract ("private-key", handle->algorithm_name,
+                        key_sexp, &key_data_secret);
+  if (err)
+    goto out;
+
+  gcry_sexp_release (key_sexp);
+  key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "public-key", 0);
+  if (! key_sexp)
+    {
+      err = gcry_error (GPG_ERR_INTERNAL);
+      goto out;
+    }
+  err = ac_data_extract ("public-key", handle->algorithm_name,
+                        key_sexp, &key_data_public);
+  if (err)
+    goto out;
+
+  /* Done.  */
+
+  key_secret->type = GCRY_AC_KEY_SECRET;
+  key_secret->data = key_data_secret;
+  key_public->type = GCRY_AC_KEY_PUBLIC;
+  key_public->data = key_data_public;
+  key_pair_new->secret = key_secret;
+  key_pair_new->public = key_public;
+  *key_pair = key_pair_new;
+
+ out:
+
+  /* Deallocate resources.  */
+  
+  gcry_free (genkey_format);
+  gcry_free (arg_list);
+  gcry_sexp_release (genkey_sexp_request);
+  gcry_sexp_release (genkey_sexp_reply);
+  gcry_sexp_release (key_sexp);
+  if (err)
+    {
+      _gcry_ac_data_destroy (key_data_secret);
+      _gcry_ac_data_destroy (key_data_public);
+      gcry_free (key_secret);
+      gcry_free (key_public);
+      gcry_free (key_pair_new);
+    }
+
+  return err;
+}
+
+/* Returns the key of type WHICH out of the key pair KEY_PAIR.  */
+gcry_ac_key_t
+_gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair, 
+                           gcry_ac_key_type_t which)
+{
+  gcry_ac_key_t key;
+
+  if (fips_mode ())
+    return NULL;
+
+  switch (which)
+    {
+    case GCRY_AC_KEY_SECRET:
+      key = key_pair->secret;
+      break;
+
+    case GCRY_AC_KEY_PUBLIC:
+      key = key_pair->public;
+      break;
+
+    default:
+      key = NULL;
+      break;
+    }
+
+  return key;
+}
+
+/* Destroys the key KEY.  */
+void
+_gcry_ac_key_destroy (gcry_ac_key_t key)
+{
+  unsigned int i;
+
+  if (key)
+    {
+      if (key->data)
+        {
+          for (i = 0; i < key->data->data_n; i++)
+            {
+              if (key->data->data[i].mpi)
+                gcry_mpi_release (key->data->data[i].mpi);
+              if (key->data->data[i].name)
+                gcry_free (key->data->data[i].name);
+            }
+          gcry_free (key->data->data);
+          gcry_free (key->data);
+        }
+      gcry_free (key);
+    }
+}
+
+/* Destroys the key pair KEY_PAIR.  */
+void
+_gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
+{
+  if (key_pair)
+    {
+      gcry_ac_key_destroy (key_pair->secret);
+      gcry_ac_key_destroy (key_pair->public);
+      gcry_free (key_pair);
+    }
+}
+
+/* Returns the data set contained in the key KEY.  */
+gcry_ac_data_t
+_gcry_ac_key_data_get (gcry_ac_key_t key)
+{
+  if (fips_mode ())
+    return NULL;
+  return key->data;
+}
+
+/* Verifies that the key KEY is sane via HANDLE.  */
+gcry_error_t
+_gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
+{
+  gcry_sexp_t key_sexp;
+  gcry_error_t err;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  key_sexp = NULL;
+  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
+                          handle->algorithm_name, key->data, &key_sexp);
+  if (err)
+    goto out;
+
+  err = gcry_pk_testkey (key_sexp);
+
+ out:
+
+  gcry_sexp_release (key_sexp);
+
+  return gcry_error (err);
+}
+
+/* Stores the number of bits of the key KEY in NBITS via HANDLE.  */
+gcry_error_t
+_gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
+                       gcry_ac_key_t key, unsigned int *nbits)
+{
+  gcry_sexp_t key_sexp;
+  gcry_error_t err;
+  unsigned int n;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  key_sexp = NULL;
+
+  err = ac_data_construct (ac_key_identifiers[key->type],
+                          0, 0, handle->algorithm_name, key->data, &key_sexp);
+  if (err)
+    goto out;
+
+  n = gcry_pk_get_nbits (key_sexp);
+  if (! n)
+    {
+      err = gcry_error (GPG_ERR_PUBKEY_ALGO);
+      goto out;
+    }
+
+  *nbits = n;
+
+ out:
+
+  gcry_sexp_release (key_sexp);
+
+  return err;
+}
+
+/* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
+   HANDLE.  */
+gcry_error_t
+_gcry_ac_key_get_grip (gcry_ac_handle_t handle,
+                      gcry_ac_key_t key, unsigned char *key_grip)
+{
+  gcry_sexp_t key_sexp;
+  gcry_error_t err;
+  unsigned char *ret;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  key_sexp = NULL;
+  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
+                          handle->algorithm_name, key->data, &key_sexp);
+  if (err)
+    goto out;
+
+  ret = gcry_pk_get_keygrip (key_sexp, key_grip);
+  if (! ret)
+    {
+      err = gcry_error (GPG_ERR_INV_OBJ);
+      goto out;
+    }
+
+  err = 0;
+
+ out:
+
+  gcry_sexp_release (key_sexp);
+
+  return err;
+}
+
+
+\f
+
+/* 
+ * Functions performing cryptographic operations.
+ */
+
+/* Encrypts the plain text MPI value DATA_PLAIN with the key public
+   KEY under the control of the flags FLAGS and stores the resulting
+   data set into DATA_ENCRYPTED.  */
+gcry_error_t
+_gcry_ac_data_encrypt (gcry_ac_handle_t handle,
+                      unsigned int flags,
+                      gcry_ac_key_t key,
+                      gcry_mpi_t data_plain,
+                      gcry_ac_data_t *data_encrypted)
+{
+  gcry_ac_data_t data_encrypted_new;
+  gcry_ac_data_t data_value;
+  gcry_sexp_t sexp_request;
+  gcry_sexp_t sexp_reply;
+  gcry_sexp_t sexp_key;
+  gcry_error_t err;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  data_encrypted_new = NULL;
+  sexp_request = NULL;
+  sexp_reply = NULL;
+  data_value = NULL;
+  sexp_key = NULL;
+
+  if (key->type != GCRY_AC_KEY_PUBLIC)
+    {
+      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+      goto out;
+    }
+
+  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
+                          handle->algorithm_name, key->data, &sexp_key);
+  if (err)
+    goto out;
+
+  err = _gcry_ac_data_new (&data_value);
+  if (err)
+    goto out;
+
+  err = _gcry_ac_data_set (data_value, 0, "value", data_plain);
+  if (err)
+    goto out;
+
+  err = ac_data_construct ("data", 1, flags, handle->algorithm_name,
+                          data_value, &sexp_request);
+  if (err)
+    goto out;
+
+  /* FIXME: error vs. errcode? */
+
+  err = gcry_pk_encrypt (&sexp_reply, sexp_request, sexp_key);
+  if (err)
+    goto out;
+
+  /* Extract data.  */
+  err = ac_data_extract ("enc-val", handle->algorithm_name,
+                        sexp_reply, &data_encrypted_new);
+  if (err)
+    goto out;
+
+  *data_encrypted = data_encrypted_new;
+
+ out:
+
+  /* Deallocate resources.  */
+
+  gcry_sexp_release (sexp_request);
+  gcry_sexp_release (sexp_reply);
+  gcry_sexp_release (sexp_key);
+  _gcry_ac_data_destroy (data_value);
+
+  return err;
+}
+
+/* Decrypts the encrypted data contained in the data set
+   DATA_ENCRYPTED with the secret key KEY under the control of the
+   flags FLAGS and stores the resulting plain text MPI value in
+   DATA_PLAIN.  */
+gcry_error_t
+_gcry_ac_data_decrypt (gcry_ac_handle_t handle,
+                      unsigned int flags,
+                      gcry_ac_key_t key,
+                      gcry_mpi_t *data_plain,
+                      gcry_ac_data_t data_encrypted)
+{
+  gcry_mpi_t data_decrypted;
+  gcry_sexp_t sexp_request;
+  gcry_sexp_t sexp_reply;
+  gcry_sexp_t sexp_value;
+  gcry_sexp_t sexp_key;
+  gcry_error_t err;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  sexp_request = NULL;
+  sexp_reply = NULL;
+  sexp_value = NULL;
+  sexp_key = NULL;
+
+  if (key->type != GCRY_AC_KEY_SECRET)
+    {
+      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+      goto out;
+    }
+
+  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
+                          handle->algorithm_name, key->data, &sexp_key);
+  if (err)
+    goto out;
+
+  /* Create S-expression from data.  */
+  err = ac_data_construct ("enc-val", 1, flags, handle->algorithm_name,
+                          data_encrypted, &sexp_request);
+  if (err)
+    goto out;
+
+  /* Decrypt.  */
+  err = gcry_pk_decrypt (&sexp_reply, sexp_request, sexp_key);
+  if (err)
+    goto out;
+
+  /* Extract plain text. */
+  sexp_value = gcry_sexp_find_token (sexp_reply, "value", 0);
+  if (! sexp_value)
+    {
+      /* FIXME?  */
+      err = gcry_error (GPG_ERR_GENERAL);
+      goto out;
+    }
+
+  data_decrypted = gcry_sexp_nth_mpi (sexp_value, 1, GCRYMPI_FMT_USG);
+  if (! data_decrypted)
+    {
+      err = gcry_error (GPG_ERR_GENERAL);
+      goto out;
+    }
+
+  *data_plain = data_decrypted;
+
+ out:
+
+  /* Deallocate resources.  */
+  gcry_sexp_release (sexp_request);
+  gcry_sexp_release (sexp_reply);
+  gcry_sexp_release (sexp_value);
+  gcry_sexp_release (sexp_key);
+
+  return gcry_error (err);
+
+}
+
+/* Signs the data contained in DATA with the secret key KEY and stores
+   the resulting signature data set in DATA_SIGNATURE.  */
+gcry_error_t
+_gcry_ac_data_sign (gcry_ac_handle_t handle,
+                   gcry_ac_key_t key,
+                   gcry_mpi_t data,
+                   gcry_ac_data_t *data_signature)
+{
+  gcry_ac_data_t data_signed;
+  gcry_ac_data_t data_value;
+  gcry_sexp_t sexp_request;
+  gcry_sexp_t sexp_reply;
+  gcry_sexp_t sexp_key;
+  gcry_error_t err;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  data_signed = NULL;
+  data_value = NULL;
+  sexp_request = NULL;
+  sexp_reply = NULL;
+  sexp_key = NULL;
+
+  if (key->type != GCRY_AC_KEY_SECRET)
+    {
+      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+      goto out;
+    }
+
+  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
+                          handle->algorithm_name, key->data, &sexp_key);
+  if (err)
+    goto out;
+
+  err = _gcry_ac_data_new (&data_value);
+  if (err)
+    goto out;
+
+  err = _gcry_ac_data_set (data_value, 0, "value", data);
+  if (err)
+    goto out;
+
+  /* Create S-expression holding the data.  */
+  err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_request);
+  if (err)
+    goto out;
+
+  /* Sign.  */
+  err = gcry_pk_sign (&sexp_reply, sexp_request, sexp_key);
+  if (err)
+    goto out;
+
+  /* Extract data.  */
+  err = ac_data_extract ("sig-val", handle->algorithm_name,
+                        sexp_reply, &data_signed);
+  if (err)
+    goto out;
+
+  /* Done.  */
+  *data_signature = data_signed;
+
+ out:
+
+  gcry_sexp_release (sexp_request);
+  gcry_sexp_release (sexp_reply);
+  gcry_sexp_release (sexp_key);
+  _gcry_ac_data_destroy (data_value);
+
+  return gcry_error (err);
+}
+
+
+/* Verifies that the signature contained in the data set
+   DATA_SIGNATURE is indeed the result of signing the data contained
+   in DATA with the secret key belonging to the public key KEY.  */
+gcry_error_t
+_gcry_ac_data_verify (gcry_ac_handle_t handle,
+                     gcry_ac_key_t key,
+                     gcry_mpi_t data,
+                     gcry_ac_data_t data_signature)
+{
+  gcry_sexp_t sexp_signature;
+  gcry_ac_data_t data_value;
+  gcry_sexp_t sexp_data;
+  gcry_sexp_t sexp_key;
+  gcry_error_t err;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  sexp_signature = NULL;
+  data_value = NULL;
+  sexp_data = NULL;
+  sexp_key = NULL;
+
+  err = ac_data_construct ("public-key", 0, 0,
+                          handle->algorithm_name, key->data, &sexp_key);
+  if (err)
+    goto out;
+
+  if (key->type != GCRY_AC_KEY_PUBLIC)
+    {
+      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+      goto out;
+    }
+
+  /* Construct S-expression holding the signature data.  */
+  err = ac_data_construct ("sig-val", 1, 0, handle->algorithm_name,
+                          data_signature, &sexp_signature);
+  if (err)
+    goto out;
+
+  err = _gcry_ac_data_new (&data_value);
+  if (err)
+    goto out;
+
+  err = _gcry_ac_data_set (data_value, 0, "value", data);
+  if (err)
+    goto out;
+
+  /* Construct S-expression holding the data.  */
+  err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_data);
+  if (err)
+    goto out;
+
+  /* Verify signature.  */
+  err = gcry_pk_verify (sexp_signature, sexp_data, sexp_key);
+
+ out:
+
+  gcry_sexp_release (sexp_signature);
+  gcry_sexp_release (sexp_data);
+  gcry_sexp_release (sexp_key);
+  _gcry_ac_data_destroy (data_value);
+
+  return gcry_error (err);
+}
+
+
+
+\f
+/*
+ * Implementation of encoding methods (em).
+ */
+
+/* Type for functions that encode or decode (hence the name) a
+   message.  */
+typedef gcry_error_t (*gcry_ac_em_dencode_t) (unsigned int flags,
+                                                void *options,
+                                                gcry_ac_io_t *ac_io_read,
+                                                gcry_ac_io_t *ac_io_write);
+
+/* Fill the buffer BUFFER which is BUFFER_N bytes long with non-zero
+   random bytes of random level LEVEL.  */
+static void
+em_randomize_nonzero (unsigned char *buffer, size_t buffer_n,
+                     gcry_random_level_t level)
+{
+  unsigned char *buffer_rand;
+  unsigned int buffer_rand_n;
+  unsigned int zeros;
+  unsigned int i;
+  unsigned int j;
+
+  for (i = 0; i < buffer_n; i++)
+    buffer[i] = 0;
+  
+  do
+    {
+      /* Count zeros.  */
+      for (i = zeros = 0; i < buffer_n; i++)
+       if (! buffer[i])
+         zeros++;
+
+      if (zeros)
+       {
+         /* Get random bytes.  */
+         buffer_rand_n = zeros + (zeros / 128);
+         buffer_rand = gcry_random_bytes_secure (buffer_rand_n, level);
+
+         /* Substitute zeros with non-zero random bytes.  */
+         for (i = j = 0; zeros && (i < buffer_n) && (j < buffer_rand_n); i++)
+           if (! buffer[i])
+             {
+               while ((j < buffer_rand_n) && (! buffer_rand[j]))
+                 j++;
+               if (j < buffer_rand_n)
+                 {
+                   buffer[i] = buffer_rand[j++];
+                   zeros--;
+                 }
+               else
+                 break;
+             }
+         gcry_free (buffer_rand);
+       }
+    }
+  while (zeros);
+}
+
+/* Encode a message according to the Encoding Method for Encryption
+   `PKCS-V1_5' (EME-PKCS-V1_5).  */
+static gcry_error_t
+eme_pkcs_v1_5_encode (unsigned int flags, void *opts,
+                     gcry_ac_io_t *ac_io_read,
+                     gcry_ac_io_t *ac_io_write)
+{
+  gcry_ac_eme_pkcs_v1_5_t *options;
+  gcry_error_t err;
+  unsigned char *buffer;
+  unsigned char *ps;
+  unsigned char *m;
+  size_t m_n;
+  unsigned int ps_n;
+  unsigned int k;
+
+  (void)flags;
+
+  options = opts;
+  buffer = NULL;
+  m = NULL;
+
+  err = _gcry_ac_io_read_all (ac_io_read, &m, &m_n);
+  if (err)
+    goto out;
+
+  /* Figure out key length in bytes.  */
+  k = options->key_size / 8;
+
+  if (m_n > k - 11)
+    {
+      /* Key is too short for message.  */
+      err = gcry_error (GPG_ERR_TOO_SHORT);
+      goto out;
+    }
+
+  /* According to this encoding method, the first byte of the encoded
+     message is zero.  This byte will be lost anyway, when the encoded
+     message is to be converted into an MPI, that's why we skip
+     it.  */
+
+  /* Allocate buffer.  */
+  buffer = gcry_malloc (k - 1);
+  if (! buffer)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+
+  /* Generate an octet string PS of length k - mLen - 3 consisting
+     of pseudorandomly generated nonzero octets.  The length of PS
+     will be at least eight octets.  */
+  ps_n = k - m_n - 3;
+  ps = buffer + 1;
+  em_randomize_nonzero (ps, ps_n, GCRY_STRONG_RANDOM);
+
+  /* Concatenate PS, the message M, and other padding to form an
+     encoded message EM of length k octets as:
+
+     EM = 0x00 || 0x02 || PS || 0x00 || M.  */
+
+  buffer[0] = 0x02;
+  buffer[ps_n + 1] = 0x00;
+  memcpy (buffer + ps_n + 2, m, m_n);
+
+  err = _gcry_ac_io_write (ac_io_write, buffer, k - 1);
+
+ out:
+
+  gcry_free (buffer);
+  gcry_free (m);
+
+  return err;
+}
+
+/* Decode a message according to the Encoding Method for Encryption
+   `PKCS-V1_5' (EME-PKCS-V1_5).  */
+static gcry_error_t
+eme_pkcs_v1_5_decode (unsigned int flags, void *opts,
+                     gcry_ac_io_t *ac_io_read,
+                     gcry_ac_io_t *ac_io_write)
+{
+  gcry_ac_eme_pkcs_v1_5_t *options;
+  unsigned char *buffer;
+  unsigned char *em;
+  size_t em_n;
+  gcry_error_t err;
+  unsigned int i;
+  unsigned int k;
+
+  (void)flags;
+
+  options = opts;
+  buffer = NULL;
+  em = NULL;
+
+  err = _gcry_ac_io_read_all (ac_io_read, &em, &em_n);
+  if (err)
+    goto out;
+
+  /* Figure out key size.  */
+  k = options->key_size / 8;
+
+  /* Search for zero byte.  */
+  for (i = 0; (i < em_n) && em[i]; i++);
+
+  /* According to this encoding method, the first byte of the encoded
+     message should be zero.  This byte is lost.  */
+
+  if (! ((em_n >= 10)
+        && (em_n == (k - 1))
+        && (em[0] == 0x02)
+        && (i < em_n)
+        && ((i - 1) >= 8)))
+    {
+      err = gcry_error (GPG_ERR_DECRYPT_FAILED);
+      goto out;
+    }
+
+  i++;
+  buffer = gcry_malloc (em_n - i);
+  if (! buffer)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+
+  memcpy (buffer, em + i, em_n - i);
+  err = _gcry_ac_io_write (ac_io_write, buffer, em_n - i);
+
+ out:
+
+  gcry_free (buffer);
+  gcry_free (em);
+
+  return err;
+}
+
+static gcry_error_t
+emsa_pkcs_v1_5_encode_data_cb (void *opaque,
+                              unsigned char *buffer, size_t buffer_n)
+{
+  gcry_md_hd_t md_handle;
+
+  md_handle = opaque;
+  gcry_md_write (md_handle, buffer, buffer_n);
+
+  return 0;
+}
+
+
+/* Encode a message according to the Encoding Method for Signatures
+   with Appendix `PKCS-V1_5' (EMSA-PKCS-V1_5).  */
+static gcry_error_t
+emsa_pkcs_v1_5_encode (unsigned int flags, void *opts,
+                      gcry_ac_io_t *ac_io_read,
+                      gcry_ac_io_t *ac_io_write)
+{
+  gcry_ac_emsa_pkcs_v1_5_t *options;
+  gcry_error_t err;
+  gcry_md_hd_t md;
+  unsigned char *t;
+  size_t t_n;
+  unsigned char *h;
+  size_t h_n;
+  unsigned char *ps;
+  size_t ps_n;
+  unsigned char *buffer;
+  size_t buffer_n;
+  unsigned char asn[100];      /* FIXME, always enough?  */
+  size_t asn_n;
+  unsigned int i;
+
+  (void)flags;
+  
+  options = opts;
+  buffer = NULL;
+  md = NULL;
+  ps = NULL;
+  t = NULL;
+
+  /* Create hashing handle and get the necessary information.  */
+  err = gcry_md_open (&md, options->md, 0);
+  if (err)
+    goto out;
+
+  asn_n = DIM (asn);
+  err = gcry_md_algo_info (options->md, GCRYCTL_GET_ASNOID, asn, &asn_n);
+  if (err)
+    goto out;
+
+  h_n = gcry_md_get_algo_dlen (options->md);
+
+  err = _gcry_ac_io_process (ac_io_read, emsa_pkcs_v1_5_encode_data_cb, md);
+  if (err)
+    goto out;
+
+  h = gcry_md_read (md, 0);
+
+  /* Encode the algorithm ID for the hash function and the hash value
+     into an ASN.1 value of type DigestInfo with the Distinguished
+     Encoding Rules (DER), where the type DigestInfo has the syntax:
+
+     DigestInfo ::== SEQUENCE {
+     digestAlgorithm AlgorithmIdentifier,
+     digest OCTET STRING
+     }
+
+     The first field identifies the hash function and the second
+     contains the hash value.  Let T be the DER encoding of the
+     DigestInfo value and let tLen be the length in octets of T.  */
+
+  t_n = asn_n + h_n;
+  t = gcry_malloc (t_n);
+  if (! t)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+
+  for (i = 0; i < asn_n; i++)
+    t[i] = asn[i];
+  for (i = 0; i < h_n; i++)
+    t[asn_n + i] = h[i];
+
+  /* If emLen < tLen + 11, output "intended encoded message length
+     too short" and stop.  */
+  if (options->em_n < t_n + 11)
+    {
+      err = gcry_error (GPG_ERR_TOO_SHORT);
+      goto out;
+    }
+
+  /* Generate an octet string PS consisting of emLen - tLen - 3 octets
+     with hexadecimal value 0xFF.  The length of PS will be at least 8
+     octets.  */
+  ps_n = options->em_n - t_n - 3;
+  ps = gcry_malloc (ps_n);
+  if (! ps)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+  for (i = 0; i < ps_n; i++)
+    ps[i] = 0xFF;
+
+  /* Concatenate PS, the DER encoding T, and other padding to form the
+     encoded message EM as:
+
+     EM = 0x00 || 0x01 || PS || 0x00 || T.  */
+
+  buffer_n = ps_n + t_n + 3;
+  buffer = gcry_malloc (buffer_n);
+  if (! buffer)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+
+  buffer[0] = 0x00;
+  buffer[1] = 0x01;
+  for (i = 0; i < ps_n; i++)
+    buffer[2 + i] = ps[i];
+  buffer[2 + ps_n] = 0x00;
+  for (i = 0; i < t_n; i++)
+    buffer[3 + ps_n + i] = t[i];
+
+  err = _gcry_ac_io_write (ac_io_write, buffer, buffer_n);
+
+ out:
+
+  gcry_md_close (md);
+
+  gcry_free (buffer);
+  gcry_free (ps);
+  gcry_free (t);
+
+  return err;
+}
+
+/* `Actions' for data_dencode().  */
+typedef enum dencode_action
+  {
+    DATA_ENCODE,
+    DATA_DECODE,
+  }
+dencode_action_t;
+
+/* Encode or decode a message according to the the encoding method
+   METHOD; ACTION specifies wether the message that is contained in
+   BUFFER_IN and of length BUFFER_IN_N should be encoded or decoded.
+   The resulting message will be stored in a newly allocated buffer in
+   BUFFER_OUT and BUFFER_OUT_N.  */
+static gcry_error_t
+ac_data_dencode (gcry_ac_em_t method, dencode_action_t action,
+                unsigned int flags, void *options,
+                gcry_ac_io_t *ac_io_read,
+                gcry_ac_io_t *ac_io_write)
+{
+  struct
+  {
+    gcry_ac_em_t method;
+    gcry_ac_em_dencode_t encode;
+    gcry_ac_em_dencode_t decode;
+  } methods[] =
+    {
+      { GCRY_AC_EME_PKCS_V1_5,
+       eme_pkcs_v1_5_encode, eme_pkcs_v1_5_decode },
+      { GCRY_AC_EMSA_PKCS_V1_5,
+       emsa_pkcs_v1_5_encode, NULL },
+    };
+  size_t methods_n;
+  gcry_error_t err;
+  unsigned int i;
+
+  methods_n = sizeof (methods) / sizeof (*methods);
+
+  for (i = 0; i < methods_n; i++)
+    if (methods[i].method == method)
+      break;
+  if (i == methods_n)
+    {
+      err = gcry_error (GPG_ERR_NOT_FOUND);    /* FIXME? */
+      goto out;
+    }
+
+  err = 0;
+  switch (action)
+    {
+    case DATA_ENCODE:
+      if (methods[i].encode)
+       /* FIXME? */
+       err = (*methods[i].encode) (flags, options, ac_io_read, ac_io_write);
+      break;
+
+    case DATA_DECODE:
+      if (methods[i].decode)
+       /* FIXME? */
+       err = (*methods[i].decode) (flags, options, ac_io_read, ac_io_write);
+      break;
+
+    default:
+      err = gcry_error (GPG_ERR_INV_ARG);
+      break;
+    }
+
+ out:
+
+  return err;
+}
+
+/* Encode a message according to the encoding method METHOD.  OPTIONS
+   must be a pointer to a method-specific structure
+   (gcry_ac_em*_t).  */
+gcry_error_t
+_gcry_ac_data_encode (gcry_ac_em_t method,
+                     unsigned int flags, void *options,
+                     gcry_ac_io_t *ac_io_read,
+                     gcry_ac_io_t *ac_io_write)
+{
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  return ac_data_dencode (method, DATA_ENCODE, flags, options,
+                         ac_io_read, ac_io_write);
+}
+
+/* Dencode a message according to the encoding method METHOD.  OPTIONS
+   must be a pointer to a method-specific structure
+   (gcry_ac_em*_t).  */
+gcry_error_t
+_gcry_ac_data_decode (gcry_ac_em_t method,
+                     unsigned int flags, void *options,
+                     gcry_ac_io_t *ac_io_read,
+                     gcry_ac_io_t *ac_io_write)
+{
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  return ac_data_dencode (method, DATA_DECODE, flags, options,
+                         ac_io_read, ac_io_write);
+}
+
+/* Convert an MPI into an octet string.  */
+void
+_gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
+{
+  unsigned long digit;
+  gcry_mpi_t base;
+  unsigned int i;
+  unsigned int n;
+  gcry_mpi_t m;
+  gcry_mpi_t d;
+
+  if (fips_mode ())
+    return;
+
+  base = gcry_mpi_new (0);
+  gcry_mpi_set_ui (base, 256);
+
+  n = 0;
+  m = gcry_mpi_copy (mpi);
+  while (gcry_mpi_cmp_ui (m, 0))
+    {
+      n++;
+      gcry_mpi_div (m, NULL, m, base, 0);
+    }
+
+  gcry_mpi_set (m, mpi);
+  d = gcry_mpi_new (0);
+  for (i = 0; (i < n) && (i < os_n); i++)
+    {
+      gcry_mpi_mod (d, m, base);
+      _gcry_mpi_get_ui (d, &digit);
+      gcry_mpi_div (m, NULL, m, base, 0);
+      os[os_n - i - 1] = (digit & 0xFF);
+    }
+
+  for (; i < os_n; i++)
+    os[os_n - i - 1] = 0;
+
+  gcry_mpi_release (base);
+  gcry_mpi_release (d);
+  gcry_mpi_release (m);
+}
+
+/* Convert an MPI into an newly allocated octet string.  */
+gcry_error_t
+_gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os, size_t *os_n)
+{
+  unsigned char *buffer;
+  size_t buffer_n;
+  gcry_error_t err;
+  unsigned int nbits;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  nbits = gcry_mpi_get_nbits (mpi);
+  buffer_n = (nbits + 7) / 8;
+  buffer = gcry_malloc (buffer_n);
+  if (! buffer)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+      
+  _gcry_ac_mpi_to_os (mpi, buffer, buffer_n);
+  *os = buffer;
+  *os_n = buffer_n;
+  err = 0;
+
+ out:
+
+  return err;
+}
+
+
+/* Convert an octet string into an MPI.  */
+void
+_gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
+{
+  unsigned int i;
+  gcry_mpi_t xi;
+  gcry_mpi_t x;
+  gcry_mpi_t a;
+  
+  if (fips_mode ())
+    return;
+
+  a = gcry_mpi_new (0);
+  gcry_mpi_set_ui (a, 1);
+  x = gcry_mpi_new (0);
+  gcry_mpi_set_ui (x, 0);
+  xi = gcry_mpi_new (0);
+
+  for (i = 0; i < os_n; i++)
+    {
+      gcry_mpi_mul_ui (xi, a, os[os_n - i - 1]);
+      gcry_mpi_add (x, x, xi);
+      gcry_mpi_mul_ui (a, a, 256);
+    }
+      
+  gcry_mpi_release (xi);
+  gcry_mpi_release (a);
+
+  gcry_mpi_set (mpi, x);
+  gcry_mpi_release (x);                /* FIXME: correct? */
+}
+
+
+\f
+/* 
+ * Implementation of Encryption Schemes (ES) and Signature Schemes
+ * with Appendix (SSA).
+ */
+
+/* Schemes consist of two things: encoding methods and cryptographic
+   primitives.
+
+   Since encoding methods are accessible through a common API with
+   method-specific options passed as an anonymous struct, schemes have
+   to provide functions that construct this method-specific structure;
+   this is what the functions of type `gcry_ac_dencode_prepare_t' are
+   there for.  */
+
+typedef gcry_error_t (*gcry_ac_dencode_prepare_t) (gcry_ac_handle_t handle,
+                                                  gcry_ac_key_t key,
+                                                  void *opts,
+                                                  void *opts_em);
+
+/* The `dencode_prepare' function for ES-PKCS-V1_5.  */
+static gcry_error_t
+ac_es_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
+                                void *opts, void *opts_em)
+{
+  gcry_ac_eme_pkcs_v1_5_t *options_em;
+  unsigned int nbits;
+  gcry_error_t err;
+
+  (void)opts;
+
+  err = _gcry_ac_key_get_nbits (handle, key, &nbits);
+  if (err)
+    goto out;
+
+  options_em = opts_em;
+  options_em->key_size = nbits;
+
+ out:
+
+  return err;
+}
+
+/* The `dencode_prepare' function for SSA-PKCS-V1_5.  */
+static gcry_error_t
+ac_ssa_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
+                                 void *opts, void *opts_em)
+{
+  gcry_ac_emsa_pkcs_v1_5_t *options_em;
+  gcry_ac_ssa_pkcs_v1_5_t *options;
+  gcry_error_t err;
+  unsigned int k;
+
+  options_em = opts_em;
+  options = opts;
+
+  err = _gcry_ac_key_get_nbits (handle, key, &k);
+  if (err)
+    goto out;
+
+  k = (k + 7) / 8;
+  options_em->md = options->md;
+  options_em->em_n = k;
+
+ out:
+
+  return err;
+}
+
+/* Type holding the information about each supported
+   Encryption/Signature Scheme.  */
+typedef struct ac_scheme
+{
+  gcry_ac_scheme_t scheme;
+  gcry_ac_em_t scheme_encoding;
+  gcry_ac_dencode_prepare_t dencode_prepare;
+  size_t options_em_n;
+} ac_scheme_t;
+
+/* List of supported Schemes.  */
+static ac_scheme_t ac_schemes[] =
+  {
+    { GCRY_AC_ES_PKCS_V1_5, GCRY_AC_EME_PKCS_V1_5,
+      ac_es_dencode_prepare_pkcs_v1_5,
+      sizeof (gcry_ac_eme_pkcs_v1_5_t) },
+    { GCRY_AC_SSA_PKCS_V1_5, GCRY_AC_EMSA_PKCS_V1_5,
+      ac_ssa_dencode_prepare_pkcs_v1_5,
+      sizeof (gcry_ac_emsa_pkcs_v1_5_t) }
+  };
+
+/* Lookup a scheme by it's ID.  */
+static ac_scheme_t *
+ac_scheme_get (gcry_ac_scheme_t scheme)
+{
+  ac_scheme_t *ac_scheme;
+  unsigned int i;
+
+  for (i = 0; i < DIM (ac_schemes); i++)
+    if (scheme == ac_schemes[i].scheme)
+      break;
+  if (i == DIM (ac_schemes))
+    ac_scheme = NULL;
+  else
+    ac_scheme = ac_schemes + i;
+
+  return ac_scheme;
+}
+
+/* Prepares the encoding/decoding by creating an according option
+   structure.  */
+static gcry_error_t
+ac_dencode_prepare (gcry_ac_handle_t handle, gcry_ac_key_t key, void *opts,
+                   ac_scheme_t scheme, void **opts_em)
+{
+  gcry_error_t err;
+  void *options_em;
+
+  options_em = gcry_malloc (scheme.options_em_n);
+  if (! options_em)
+    {
+      err = gcry_error_from_errno (errno);
+      goto out;
+    }
+  
+  err = (*scheme.dencode_prepare) (handle, key, opts, options_em);
+  if (err)
+    goto out;
+
+  *opts_em = options_em;
+
+ out:
+
+  if (err)
+    free (options_em);
+
+  return err;
+}
+
+/* Convert a data set into a single MPI; currently, this is only
+   supported for data sets containing a single MPI.  */
+static gcry_error_t
+ac_data_set_to_mpi (gcry_ac_data_t data, gcry_mpi_t *mpi)
+{
+  gcry_error_t err;
+  gcry_mpi_t mpi_new;
+  unsigned int elems;
+
+  elems = _gcry_ac_data_length (data);
+
+  if (elems != 1)
+    {
+      /* FIXME: I guess, we should be more flexible in this respect by
+        allowing the actual encryption/signature schemes to implement
+        this conversion mechanism.  */
+      err = gcry_error (GPG_ERR_CONFLICT);
+      goto out;
+    }
+
+  err = _gcry_ac_data_get_index (data, GCRY_AC_FLAG_COPY, 0, NULL, &mpi_new);
+  if (err)
+    goto out;
+
+  *mpi = mpi_new;
+
+ out:
+
+  return err;
+}
+
+/* Encrypts the plain text message contained in M, which is of size
+   M_N, with the public key KEY_PUBLIC according to the Encryption
+   Scheme SCHEME_ID.  HANDLE is used for accessing the low-level
+   cryptographic primitives.  If OPTS is not NULL, it has to be an
+   anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
+   The encrypted message will be stored in C and C_N.  */
+gcry_error_t
+_gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
+                             gcry_ac_scheme_t scheme_id,
+                             unsigned int flags, void *opts,
+                             gcry_ac_key_t key,
+                             gcry_ac_io_t *io_message,
+                             gcry_ac_io_t *io_cipher)
+{
+  gcry_error_t err;
+  gcry_ac_io_t io_em;
+  unsigned char *em;
+  size_t em_n;
+  gcry_mpi_t mpi_plain;
+  gcry_ac_data_t data_encrypted;
+  gcry_mpi_t mpi_encrypted;
+  unsigned char *buffer;
+  size_t buffer_n;
+  void *opts_em;
+  ac_scheme_t *scheme;
+
+  (void)flags;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  data_encrypted = NULL;
+  mpi_encrypted = NULL;
+  mpi_plain = NULL;
+  opts_em = NULL;
+  buffer = NULL;
+  em = NULL;
+
+  scheme = ac_scheme_get (scheme_id);
+  if (! scheme)
+    {
+      err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
+      goto out;
+    }
+
+  if (key->type != GCRY_AC_KEY_PUBLIC)
+    {
+      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+      goto out;
+    }
+
+  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
+  if (err)
+    goto out;
+
+  _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
+                   GCRY_AC_IO_STRING, &em, &em_n);
+
+  err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
+                             io_message, &io_em);
+  if (err)
+    goto out;
+
+  mpi_plain = gcry_mpi_snew (0);
+  gcry_ac_os_to_mpi (mpi_plain, em, em_n);
+
+  err = _gcry_ac_data_encrypt (handle, 0, key, mpi_plain, &data_encrypted);
+  if (err)
+    goto out;
+
+  err = ac_data_set_to_mpi (data_encrypted, &mpi_encrypted);
+  if (err)
+    goto out;
+
+  err = _gcry_ac_mpi_to_os_alloc (mpi_encrypted, &buffer, &buffer_n);
+  if (err)
+    goto out;
+
+  err = _gcry_ac_io_write (io_cipher, buffer, buffer_n);
+
+ out:
+
+  gcry_ac_data_destroy (data_encrypted);
+  gcry_mpi_release (mpi_encrypted);
+  gcry_mpi_release (mpi_plain);
+  gcry_free (opts_em);
+  gcry_free (buffer);
+  gcry_free (em);
+
+  return err;
+}
+
+/* Decryptes the cipher message contained in C, which is of size C_N,
+   with the secret key KEY_SECRET according to the Encryption Scheme
+   SCHEME_ID.  Handle is used for accessing the low-level
+   cryptographic primitives.  If OPTS is not NULL, it has to be an
+   anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
+   The decrypted message will be stored in M and M_N.  */
+gcry_error_t
+_gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
+                             gcry_ac_scheme_t scheme_id,
+                             unsigned int flags, void *opts,
+                             gcry_ac_key_t key,
+                             gcry_ac_io_t *io_cipher,
+                             gcry_ac_io_t *io_message)
+{
+  gcry_ac_io_t io_em;
+  gcry_error_t err;
+  gcry_ac_data_t data_encrypted;
+  unsigned char *em;
+  size_t em_n;
+  gcry_mpi_t mpi_encrypted;
+  gcry_mpi_t mpi_decrypted;
+  void *opts_em;
+  ac_scheme_t *scheme;
+  char *elements_enc;
+  size_t elements_enc_n;
+  unsigned char *c;
+  size_t c_n;
+
+  (void)flags;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  data_encrypted = NULL;
+  mpi_encrypted = NULL;
+  mpi_decrypted = NULL;
+  elements_enc = NULL;
+  opts_em = NULL;
+  em = NULL;
+  c = NULL;
+
+  scheme = ac_scheme_get (scheme_id);
+  if (! scheme)
+    {
+      err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
+      goto out;
+    }
+
+  if (key->type != GCRY_AC_KEY_SECRET)
+    {
+      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+      goto out;
+    }
+
+  err = _gcry_ac_io_read_all (io_cipher, &c, &c_n);
+  if (err)
+    goto out;
+
+  mpi_encrypted = gcry_mpi_snew (0);
+  gcry_ac_os_to_mpi (mpi_encrypted, c, c_n);
+
+  err = _gcry_pk_get_elements (handle->algorithm, &elements_enc, NULL);
+  if (err)
+    goto out;
+
+  elements_enc_n = strlen (elements_enc);
+  if (elements_enc_n != 1)
+    {
+      /* FIXME? */
+      err = gcry_error (GPG_ERR_CONFLICT);
+      goto out;
+    }
+
+  err = _gcry_ac_data_new (&data_encrypted);
+  if (err)
+    goto out;
+
+  err = _gcry_ac_data_set (data_encrypted, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
+                          elements_enc, mpi_encrypted);
+  if (err)
+    goto out;
+
+  err = _gcry_ac_data_decrypt (handle, 0, key, &mpi_decrypted, data_encrypted);
+  if (err)
+    goto out;
+
+  err = _gcry_ac_mpi_to_os_alloc (mpi_decrypted, &em, &em_n);
+  if (err)
+    goto out;
+
+  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
+  if (err)
+    goto out;
+
+  _gcry_ac_io_init (&io_em, GCRY_AC_IO_READABLE,
+                   GCRY_AC_IO_STRING, em, em_n);
+
+  err = _gcry_ac_data_decode (scheme->scheme_encoding, 0, opts_em,
+                             &io_em, io_message);
+  if (err)
+    goto out;
+
+ out:
+  
+  _gcry_ac_data_destroy (data_encrypted);
+  gcry_mpi_release (mpi_encrypted);
+  gcry_mpi_release (mpi_decrypted);
+  free (elements_enc);
+  gcry_free (opts_em);
+  gcry_free (em);
+  gcry_free (c);
+
+  return err;
+}
+
+
+/* Signs the message contained in M, which is of size M_N, with the
+   secret key KEY according to the Signature Scheme SCHEME_ID.  Handle
+   is used for accessing the low-level cryptographic primitives.  If
+   OPTS is not NULL, it has to be an anonymous structure specific to
+   the chosen scheme (gcry_ac_ssa_*_t).  The signed message will be
+   stored in S and S_N.  */
+gcry_error_t
+_gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
+                          gcry_ac_scheme_t scheme_id,
+                          unsigned int flags, void *opts,
+                          gcry_ac_key_t key,
+                          gcry_ac_io_t *io_message,
+                          gcry_ac_io_t *io_signature)
+{
+  gcry_ac_io_t io_em;
+  gcry_error_t err;
+  gcry_ac_data_t data_signed;
+  unsigned char *em;
+  size_t em_n;
+  gcry_mpi_t mpi;
+  void *opts_em;
+  unsigned char *buffer;
+  size_t buffer_n;
+  gcry_mpi_t mpi_signed;
+  ac_scheme_t *scheme;
+
+  (void)flags;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  data_signed = NULL;
+  mpi_signed = NULL;
+  opts_em = NULL;
+  buffer = NULL;
+  mpi = NULL;
+  em = NULL;
+
+  if (key->type != GCRY_AC_KEY_SECRET)
+    {
+      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+      goto out;
+    }
+
+  scheme = ac_scheme_get (scheme_id);
+  if (! scheme)
+    {
+      /* FIXME: adjust api of scheme_get in respect to err codes.  */
+      err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
+      goto out;
+    }
+
+  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
+  if (err)
+    goto out;
+
+  _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
+                   GCRY_AC_IO_STRING, &em, &em_n);
+
+  err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
+                             io_message, &io_em);
+  if (err)
+    goto out;
+
+  mpi = gcry_mpi_new (0);
+  _gcry_ac_os_to_mpi (mpi, em, em_n);
+
+  err = _gcry_ac_data_sign (handle, key, mpi, &data_signed);
+  if (err)
+    goto out;
+
+  err = ac_data_set_to_mpi (data_signed, &mpi_signed);
+  if (err)
+    goto out;
+
+  err = _gcry_ac_mpi_to_os_alloc (mpi_signed, &buffer, &buffer_n);
+  if (err)
+    goto out;
+
+  err = _gcry_ac_io_write (io_signature, buffer, buffer_n);
+
+ out:
+
+  _gcry_ac_data_destroy (data_signed);
+  gcry_mpi_release (mpi_signed);
+  gcry_mpi_release (mpi);
+  gcry_free (opts_em);
+  gcry_free (buffer);
+  gcry_free (em);
+
+  return err;
+}
+
+/* Verifies that the signature contained in S, which is of length S_N,
+   is indeed the result of signing the message contained in M, which
+   is of size M_N, with the secret key belonging to the public key
+   KEY_PUBLIC.  If OPTS is not NULL, it has to be an anonymous
+   structure (gcry_ac_ssa_*_t) specific to the Signature Scheme, whose
+   ID is contained in SCHEME_ID.  */
+gcry_error_t
+_gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
+                            gcry_ac_scheme_t scheme_id,
+                            unsigned int flags, void *opts,
+                            gcry_ac_key_t key,
+                            gcry_ac_io_t *io_message,
+                            gcry_ac_io_t *io_signature)
+{
+  gcry_ac_io_t io_em;
+  gcry_error_t err;
+  gcry_ac_data_t data_signed;
+  unsigned char *em;
+  size_t em_n;
+  void *opts_em;
+  gcry_mpi_t mpi_signature;
+  gcry_mpi_t mpi_data;
+  ac_scheme_t *scheme;
+  char *elements_sig;
+  size_t elements_sig_n;
+  unsigned char *s;
+  size_t s_n;
+
+  (void)flags;
+
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  mpi_signature = NULL;
+  elements_sig = NULL;
+  data_signed = NULL;
+  mpi_data = NULL;
+  opts_em = NULL;
+  em = NULL;
+  s = NULL;
+
+  if (key->type != GCRY_AC_KEY_PUBLIC)
+    {
+      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+      goto out;
+    }
+
+  scheme = ac_scheme_get (scheme_id);
+  if (! scheme)
+    {
+      err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
+      goto out;
+    }
+
+  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
+  if (err)
+    goto out;
+
+  _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
+                   GCRY_AC_IO_STRING, &em, &em_n);
+
+  err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
+                             io_message, &io_em);
+  if (err)
+    goto out;
+
+  mpi_data = gcry_mpi_new (0);
+  _gcry_ac_os_to_mpi (mpi_data, em, em_n);
+
+  err = _gcry_ac_io_read_all (io_signature, &s, &s_n);
+  if (err)
+    goto out;
+
+  mpi_signature = gcry_mpi_new (0);
+  _gcry_ac_os_to_mpi (mpi_signature, s, s_n);
+
+  err = _gcry_pk_get_elements (handle->algorithm, NULL, &elements_sig);
+  if (err)
+    goto out;
+
+  elements_sig_n = strlen (elements_sig);
+  if (elements_sig_n != 1)
+    {
+      /* FIXME? */
+      err = gcry_error (GPG_ERR_CONFLICT);
+      goto out;
+    }
+
+  err = _gcry_ac_data_new (&data_signed);
+  if (err)
+    goto out;
+
+  err = _gcry_ac_data_set (data_signed, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
+                          elements_sig, mpi_signature);
+  if (err)
+    goto out;
+
+  gcry_mpi_release (mpi_signature);
+  mpi_signature = NULL;
+  
+  err = _gcry_ac_data_verify (handle, key, mpi_data, data_signed);
+
+ out:
+
+  _gcry_ac_data_destroy (data_signed);
+  gcry_mpi_release (mpi_signature);
+  gcry_mpi_release (mpi_data);
+  free (elements_sig);
+  gcry_free (opts_em);
+  gcry_free (em);
+  gcry_free (s);
+
+  return err;
+}
+
+
+/* 
+ * General functions.
+ */
+
+gcry_err_code_t
+_gcry_ac_init (void)
+{
+  if (fips_mode ())
+    return GPG_ERR_NOT_SUPPORTED;
+
+  return 0;
+}
diff --git a/grub-core/lib/libgcrypt/cipher/arcfour.c b/grub-core/lib/libgcrypt/cipher/arcfour.c
new file mode 100644 (file)
index 0000000..6bb0555
--- /dev/null
@@ -0,0 +1,156 @@
+/* arcfour.c  -  The arcfour stream cipher
+ *     Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * For a description of the algorithm, see:
+ *   Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
+ *   ISBN 0-471-11709-9. Pages 397 ff.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+
+static const char *selftest(void);
+
+typedef struct {
+    int idx_i, idx_j;
+    byte sbox[256];
+} ARCFOUR_context;
+
+static void
+do_encrypt_stream( ARCFOUR_context *ctx,
+                  byte *outbuf, const byte *inbuf, unsigned int length )
+{
+  register int i = ctx->idx_i;
+  register int j = ctx->idx_j;
+  register byte *sbox = ctx->sbox;
+  register int t;  
+
+  while ( length-- )
+    {
+      i++;
+      i = i & 255; /* The and-op seems to be faster than the mod-op. */
+      j += sbox[i];
+      j &= 255;
+      t = sbox[i]; sbox[i] = sbox[j]; sbox[j] = t;
+      *outbuf++ = *inbuf++ ^ sbox[(sbox[i] + sbox[j]) & 255];
+    }
+  
+  ctx->idx_i = i;
+  ctx->idx_j = j;
+}
+
+static void
+encrypt_stream (void *context,
+                byte *outbuf, const byte *inbuf, unsigned int length)
+{
+  ARCFOUR_context *ctx = (ARCFOUR_context *) context;
+  do_encrypt_stream (ctx, outbuf, inbuf, length );
+  _gcry_burn_stack (64);
+}
+
+
+static gcry_err_code_t
+do_arcfour_setkey (void *context, const byte *key, unsigned int keylen)
+{
+  static int initialized;
+  static const char* selftest_failed;
+  int i, j;
+  byte karr[256];
+  ARCFOUR_context *ctx = (ARCFOUR_context *) context;
+
+  if (!initialized ) 
+    {
+      initialized = 1;
+      selftest_failed = selftest();
+      if( selftest_failed )
+        log_error ("ARCFOUR selftest failed (%s)\n", selftest_failed );
+    }
+  if( selftest_failed )
+    return GPG_ERR_SELFTEST_FAILED;
+
+  if( keylen < 40/8 ) /* we want at least 40 bits */
+    return GPG_ERR_INV_KEYLEN;
+
+  ctx->idx_i = ctx->idx_j = 0;
+  for (i=0; i < 256; i++ )
+    ctx->sbox[i] = i;
+  for (i=0; i < 256; i++ )
+    karr[i] = key[i%keylen];
+  for (i=j=0; i < 256; i++ ) 
+    {
+      int t;
+      j = (j + ctx->sbox[i] + karr[i]) % 256;
+      t = ctx->sbox[i];
+      ctx->sbox[i] = ctx->sbox[j];
+      ctx->sbox[j] = t;
+    } 
+  memset( karr, 0, 256 );
+
+  return GPG_ERR_NO_ERROR;
+}
+
+static gcry_err_code_t
+arcfour_setkey ( void *context, const byte *key, unsigned int keylen )
+{
+  ARCFOUR_context *ctx = (ARCFOUR_context *) context;
+  gcry_err_code_t rc = do_arcfour_setkey (ctx, key, keylen );
+  _gcry_burn_stack (300);
+  return rc;
+}
+
+
+static const char*
+selftest(void)
+{
+  ARCFOUR_context ctx;
+  byte scratch[16];       
+    
+  /* Test vector from Cryptlib labeled there: "from the
+     State/Commerce Department". */
+  static byte key_1[] =
+    { 0x61, 0x8A, 0x63, 0xD2, 0xFB };
+  static byte plaintext_1[] =
+    { 0xDC, 0xEE, 0x4C, 0xF9, 0x2C };
+  static const byte ciphertext_1[] =
+    { 0xF1, 0x38, 0x29, 0xC9, 0xDE };
+
+  arcfour_setkey( &ctx, key_1, sizeof(key_1));
+  encrypt_stream( &ctx, scratch, plaintext_1, sizeof(plaintext_1));
+  if ( memcmp (scratch, ciphertext_1, sizeof (ciphertext_1)))
+    return "Arcfour encryption test 1 failed.";
+  arcfour_setkey( &ctx, key_1, sizeof(key_1));
+  encrypt_stream(&ctx, scratch, scratch, sizeof(plaintext_1)); /* decrypt */
+  if ( memcmp (scratch, plaintext_1, sizeof (plaintext_1)))
+    return "Arcfour decryption test 1 failed.";
+  return NULL;
+}
+
+
+gcry_cipher_spec_t _gcry_cipher_spec_arcfour =
+  {
+    "ARCFOUR", NULL, NULL, 1, 128, sizeof (ARCFOUR_context),
+    arcfour_setkey, NULL, NULL, encrypt_stream, encrypt_stream,
+  };
+
diff --git a/grub-core/lib/libgcrypt/cipher/bithelp.h b/grub-core/lib/libgcrypt/cipher/bithelp.h
new file mode 100644 (file)
index 0000000..1505324
--- /dev/null
@@ -0,0 +1,54 @@
+/* bithelp.h  -  Some bit manipulation helpers
+ *     Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#ifndef G10_BITHELP_H
+#define G10_BITHELP_H
+
+
+/****************
+ * Rotate the 32 bit unsigned integer X by N bits left/right
+ */
+#if defined(__GNUC__) && defined(__i386__)
+static inline u32
+rol( u32 x, int n)
+{
+       __asm__("roll %%cl,%0"
+               :"=r" (x)
+               :"0" (x),"c" (n));
+       return x;
+}
+#else
+#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
+#endif
+
+#if defined(__GNUC__) && defined(__i386__)
+static inline u32
+ror(u32 x, int n)
+{
+       __asm__("rorl %%cl,%0"
+               :"=r" (x)
+               :"0" (x),"c" (n));
+       return x;
+}
+#else
+#define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) )
+#endif
+
+
+#endif /*G10_BITHELP_H*/
diff --git a/grub-core/lib/libgcrypt/cipher/blowfish.c b/grub-core/lib/libgcrypt/cipher/blowfish.c
new file mode 100644 (file)
index 0000000..6ef68e3
--- /dev/null
@@ -0,0 +1,605 @@
+/* blowfish.c  -  Blowfish encryption
+ *     Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * For a description of the algorithm, see:
+ *   Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
+ *   ISBN 0-471-11709-9. Pages 336 ff.
+ */
+
+/* Test values:
+ * key   "abcdefghijklmnopqrstuvwxyz";
+ * plain  "BLOWFISH"
+ * cipher 32 4E D0 FE F4 13 A2 03
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+
+#define BLOWFISH_BLOCKSIZE 8
+#define BLOWFISH_ROUNDS 16
+
+typedef struct {
+    u32 s0[256];
+    u32 s1[256];
+    u32 s2[256];
+    u32 s3[256];
+    u32 p[BLOWFISH_ROUNDS+2];
+} BLOWFISH_context;
+
+static gcry_err_code_t bf_setkey (void *c, const byte *key, unsigned keylen);
+static void encrypt_block (void *bc, byte *outbuf, const byte *inbuf);
+static void decrypt_block (void *bc, byte *outbuf, const byte *inbuf);
+
+
+/* precomputed S boxes */
+static const u32 ks0[256] = {
+    0xD1310BA6,0x98DFB5AC,0x2FFD72DB,0xD01ADFB7,0xB8E1AFED,0x6A267E96,
+    0xBA7C9045,0xF12C7F99,0x24A19947,0xB3916CF7,0x0801F2E2,0x858EFC16,
+    0x636920D8,0x71574E69,0xA458FEA3,0xF4933D7E,0x0D95748F,0x728EB658,
+    0x718BCD58,0x82154AEE,0x7B54A41D,0xC25A59B5,0x9C30D539,0x2AF26013,
+    0xC5D1B023,0x286085F0,0xCA417918,0xB8DB38EF,0x8E79DCB0,0x603A180E,
+    0x6C9E0E8B,0xB01E8A3E,0xD71577C1,0xBD314B27,0x78AF2FDA,0x55605C60,
+    0xE65525F3,0xAA55AB94,0x57489862,0x63E81440,0x55CA396A,0x2AAB10B6,
+    0xB4CC5C34,0x1141E8CE,0xA15486AF,0x7C72E993,0xB3EE1411,0x636FBC2A,
+    0x2BA9C55D,0x741831F6,0xCE5C3E16,0x9B87931E,0xAFD6BA33,0x6C24CF5C,
+    0x7A325381,0x28958677,0x3B8F4898,0x6B4BB9AF,0xC4BFE81B,0x66282193,
+    0x61D809CC,0xFB21A991,0x487CAC60,0x5DEC8032,0xEF845D5D,0xE98575B1,
+    0xDC262302,0xEB651B88,0x23893E81,0xD396ACC5,0x0F6D6FF3,0x83F44239,
+    0x2E0B4482,0xA4842004,0x69C8F04A,0x9E1F9B5E,0x21C66842,0xF6E96C9A,
+    0x670C9C61,0xABD388F0,0x6A51A0D2,0xD8542F68,0x960FA728,0xAB5133A3,
+    0x6EEF0B6C,0x137A3BE4,0xBA3BF050,0x7EFB2A98,0xA1F1651D,0x39AF0176,
+    0x66CA593E,0x82430E88,0x8CEE8619,0x456F9FB4,0x7D84A5C3,0x3B8B5EBE,
+    0xE06F75D8,0x85C12073,0x401A449F,0x56C16AA6,0x4ED3AA62,0x363F7706,
+    0x1BFEDF72,0x429B023D,0x37D0D724,0xD00A1248,0xDB0FEAD3,0x49F1C09B,
+    0x075372C9,0x80991B7B,0x25D479D8,0xF6E8DEF7,0xE3FE501A,0xB6794C3B,
+    0x976CE0BD,0x04C006BA,0xC1A94FB6,0x409F60C4,0x5E5C9EC2,0x196A2463,
+    0x68FB6FAF,0x3E6C53B5,0x1339B2EB,0x3B52EC6F,0x6DFC511F,0x9B30952C,
+    0xCC814544,0xAF5EBD09,0xBEE3D004,0xDE334AFD,0x660F2807,0x192E4BB3,
+    0xC0CBA857,0x45C8740F,0xD20B5F39,0xB9D3FBDB,0x5579C0BD,0x1A60320A,
+    0xD6A100C6,0x402C7279,0x679F25FE,0xFB1FA3CC,0x8EA5E9F8,0xDB3222F8,
+    0x3C7516DF,0xFD616B15,0x2F501EC8,0xAD0552AB,0x323DB5FA,0xFD238760,
+    0x53317B48,0x3E00DF82,0x9E5C57BB,0xCA6F8CA0,0x1A87562E,0xDF1769DB,
+    0xD542A8F6,0x287EFFC3,0xAC6732C6,0x8C4F5573,0x695B27B0,0xBBCA58C8,
+    0xE1FFA35D,0xB8F011A0,0x10FA3D98,0xFD2183B8,0x4AFCB56C,0x2DD1D35B,
+    0x9A53E479,0xB6F84565,0xD28E49BC,0x4BFB9790,0xE1DDF2DA,0xA4CB7E33,
+    0x62FB1341,0xCEE4C6E8,0xEF20CADA,0x36774C01,0xD07E9EFE,0x2BF11FB4,
+    0x95DBDA4D,0xAE909198,0xEAAD8E71,0x6B93D5A0,0xD08ED1D0,0xAFC725E0,
+    0x8E3C5B2F,0x8E7594B7,0x8FF6E2FB,0xF2122B64,0x8888B812,0x900DF01C,
+    0x4FAD5EA0,0x688FC31C,0xD1CFF191,0xB3A8C1AD,0x2F2F2218,0xBE0E1777,
+    0xEA752DFE,0x8B021FA1,0xE5A0CC0F,0xB56F74E8,0x18ACF3D6,0xCE89E299,
+    0xB4A84FE0,0xFD13E0B7,0x7CC43B81,0xD2ADA8D9,0x165FA266,0x80957705,
+    0x93CC7314,0x211A1477,0xE6AD2065,0x77B5FA86,0xC75442F5,0xFB9D35CF,
+    0xEBCDAF0C,0x7B3E89A0,0xD6411BD3,0xAE1E7E49,0x00250E2D,0x2071B35E,
+    0x226800BB,0x57B8E0AF,0x2464369B,0xF009B91E,0x5563911D,0x59DFA6AA,
+    0x78C14389,0xD95A537F,0x207D5BA2,0x02E5B9C5,0x83260376,0x6295CFA9,
+    0x11C81968,0x4E734A41,0xB3472DCA,0x7B14A94A,0x1B510052,0x9A532915,
+    0xD60F573F,0xBC9BC6E4,0x2B60A476,0x81E67400,0x08BA6FB5,0x571BE91F,
+    0xF296EC6B,0x2A0DD915,0xB6636521,0xE7B9F9B6,0xFF34052E,0xC5855664,
+    0x53B02D5D,0xA99F8FA1,0x08BA4799,0x6E85076A };
+
+static const u32 ks1[256] = {
+    0x4B7A70E9,0xB5B32944,0xDB75092E,0xC4192623,0xAD6EA6B0,0x49A7DF7D,
+    0x9CEE60B8,0x8FEDB266,0xECAA8C71,0x699A17FF,0x5664526C,0xC2B19EE1,
+    0x193602A5,0x75094C29,0xA0591340,0xE4183A3E,0x3F54989A,0x5B429D65,
+    0x6B8FE4D6,0x99F73FD6,0xA1D29C07,0xEFE830F5,0x4D2D38E6,0xF0255DC1,
+    0x4CDD2086,0x8470EB26,0x6382E9C6,0x021ECC5E,0x09686B3F,0x3EBAEFC9,
+    0x3C971814,0x6B6A70A1,0x687F3584,0x52A0E286,0xB79C5305,0xAA500737,
+    0x3E07841C,0x7FDEAE5C,0x8E7D44EC,0x5716F2B8,0xB03ADA37,0xF0500C0D,
+    0xF01C1F04,0x0200B3FF,0xAE0CF51A,0x3CB574B2,0x25837A58,0xDC0921BD,
+    0xD19113F9,0x7CA92FF6,0x94324773,0x22F54701,0x3AE5E581,0x37C2DADC,
+    0xC8B57634,0x9AF3DDA7,0xA9446146,0x0FD0030E,0xECC8C73E,0xA4751E41,
+    0xE238CD99,0x3BEA0E2F,0x3280BBA1,0x183EB331,0x4E548B38,0x4F6DB908,
+    0x6F420D03,0xF60A04BF,0x2CB81290,0x24977C79,0x5679B072,0xBCAF89AF,
+    0xDE9A771F,0xD9930810,0xB38BAE12,0xDCCF3F2E,0x5512721F,0x2E6B7124,
+    0x501ADDE6,0x9F84CD87,0x7A584718,0x7408DA17,0xBC9F9ABC,0xE94B7D8C,
+    0xEC7AEC3A,0xDB851DFA,0x63094366,0xC464C3D2,0xEF1C1847,0x3215D908,
+    0xDD433B37,0x24C2BA16,0x12A14D43,0x2A65C451,0x50940002,0x133AE4DD,
+    0x71DFF89E,0x10314E55,0x81AC77D6,0x5F11199B,0x043556F1,0xD7A3C76B,
+    0x3C11183B,0x5924A509,0xF28FE6ED,0x97F1FBFA,0x9EBABF2C,0x1E153C6E,
+    0x86E34570,0xEAE96FB1,0x860E5E0A,0x5A3E2AB3,0x771FE71C,0x4E3D06FA,
+    0x2965DCB9,0x99E71D0F,0x803E89D6,0x5266C825,0x2E4CC978,0x9C10B36A,
+    0xC6150EBA,0x94E2EA78,0xA5FC3C53,0x1E0A2DF4,0xF2F74EA7,0x361D2B3D,
+    0x1939260F,0x19C27960,0x5223A708,0xF71312B6,0xEBADFE6E,0xEAC31F66,
+    0xE3BC4595,0xA67BC883,0xB17F37D1,0x018CFF28,0xC332DDEF,0xBE6C5AA5,
+    0x65582185,0x68AB9802,0xEECEA50F,0xDB2F953B,0x2AEF7DAD,0x5B6E2F84,
+    0x1521B628,0x29076170,0xECDD4775,0x619F1510,0x13CCA830,0xEB61BD96,
+    0x0334FE1E,0xAA0363CF,0xB5735C90,0x4C70A239,0xD59E9E0B,0xCBAADE14,
+    0xEECC86BC,0x60622CA7,0x9CAB5CAB,0xB2F3846E,0x648B1EAF,0x19BDF0CA,
+    0xA02369B9,0x655ABB50,0x40685A32,0x3C2AB4B3,0x319EE9D5,0xC021B8F7,
+    0x9B540B19,0x875FA099,0x95F7997E,0x623D7DA8,0xF837889A,0x97E32D77,
+    0x11ED935F,0x16681281,0x0E358829,0xC7E61FD6,0x96DEDFA1,0x7858BA99,
+    0x57F584A5,0x1B227263,0x9B83C3FF,0x1AC24696,0xCDB30AEB,0x532E3054,
+    0x8FD948E4,0x6DBC3128,0x58EBF2EF,0x34C6FFEA,0xFE28ED61,0xEE7C3C73,
+    0x5D4A14D9,0xE864B7E3,0x42105D14,0x203E13E0,0x45EEE2B6,0xA3AAABEA,
+    0xDB6C4F15,0xFACB4FD0,0xC742F442,0xEF6ABBB5,0x654F3B1D,0x41CD2105,
+    0xD81E799E,0x86854DC7,0xE44B476A,0x3D816250,0xCF62A1F2,0x5B8D2646,
+    0xFC8883A0,0xC1C7B6A3,0x7F1524C3,0x69CB7492,0x47848A0B,0x5692B285,
+    0x095BBF00,0xAD19489D,0x1462B174,0x23820E00,0x58428D2A,0x0C55F5EA,
+    0x1DADF43E,0x233F7061,0x3372F092,0x8D937E41,0xD65FECF1,0x6C223BDB,
+    0x7CDE3759,0xCBEE7460,0x4085F2A7,0xCE77326E,0xA6078084,0x19F8509E,
+    0xE8EFD855,0x61D99735,0xA969A7AA,0xC50C06C2,0x5A04ABFC,0x800BCADC,
+    0x9E447A2E,0xC3453484,0xFDD56705,0x0E1E9EC9,0xDB73DBD3,0x105588CD,
+    0x675FDA79,0xE3674340,0xC5C43465,0x713E38D8,0x3D28F89E,0xF16DFF20,
+    0x153E21E7,0x8FB03D4A,0xE6E39F2B,0xDB83ADF7 };
+
+static const u32 ks2[256] = {
+    0xE93D5A68,0x948140F7,0xF64C261C,0x94692934,0x411520F7,0x7602D4F7,
+    0xBCF46B2E,0xD4A20068,0xD4082471,0x3320F46A,0x43B7D4B7,0x500061AF,
+    0x1E39F62E,0x97244546,0x14214F74,0xBF8B8840,0x4D95FC1D,0x96B591AF,
+    0x70F4DDD3,0x66A02F45,0xBFBC09EC,0x03BD9785,0x7FAC6DD0,0x31CB8504,
+    0x96EB27B3,0x55FD3941,0xDA2547E6,0xABCA0A9A,0x28507825,0x530429F4,
+    0x0A2C86DA,0xE9B66DFB,0x68DC1462,0xD7486900,0x680EC0A4,0x27A18DEE,
+    0x4F3FFEA2,0xE887AD8C,0xB58CE006,0x7AF4D6B6,0xAACE1E7C,0xD3375FEC,
+    0xCE78A399,0x406B2A42,0x20FE9E35,0xD9F385B9,0xEE39D7AB,0x3B124E8B,
+    0x1DC9FAF7,0x4B6D1856,0x26A36631,0xEAE397B2,0x3A6EFA74,0xDD5B4332,
+    0x6841E7F7,0xCA7820FB,0xFB0AF54E,0xD8FEB397,0x454056AC,0xBA489527,
+    0x55533A3A,0x20838D87,0xFE6BA9B7,0xD096954B,0x55A867BC,0xA1159A58,
+    0xCCA92963,0x99E1DB33,0xA62A4A56,0x3F3125F9,0x5EF47E1C,0x9029317C,
+    0xFDF8E802,0x04272F70,0x80BB155C,0x05282CE3,0x95C11548,0xE4C66D22,
+    0x48C1133F,0xC70F86DC,0x07F9C9EE,0x41041F0F,0x404779A4,0x5D886E17,
+    0x325F51EB,0xD59BC0D1,0xF2BCC18F,0x41113564,0x257B7834,0x602A9C60,
+    0xDFF8E8A3,0x1F636C1B,0x0E12B4C2,0x02E1329E,0xAF664FD1,0xCAD18115,
+    0x6B2395E0,0x333E92E1,0x3B240B62,0xEEBEB922,0x85B2A20E,0xE6BA0D99,
+    0xDE720C8C,0x2DA2F728,0xD0127845,0x95B794FD,0x647D0862,0xE7CCF5F0,
+    0x5449A36F,0x877D48FA,0xC39DFD27,0xF33E8D1E,0x0A476341,0x992EFF74,
+    0x3A6F6EAB,0xF4F8FD37,0xA812DC60,0xA1EBDDF8,0x991BE14C,0xDB6E6B0D,
+    0xC67B5510,0x6D672C37,0x2765D43B,0xDCD0E804,0xF1290DC7,0xCC00FFA3,
+    0xB5390F92,0x690FED0B,0x667B9FFB,0xCEDB7D9C,0xA091CF0B,0xD9155EA3,
+    0xBB132F88,0x515BAD24,0x7B9479BF,0x763BD6EB,0x37392EB3,0xCC115979,
+    0x8026E297,0xF42E312D,0x6842ADA7,0xC66A2B3B,0x12754CCC,0x782EF11C,
+    0x6A124237,0xB79251E7,0x06A1BBE6,0x4BFB6350,0x1A6B1018,0x11CAEDFA,
+    0x3D25BDD8,0xE2E1C3C9,0x44421659,0x0A121386,0xD90CEC6E,0xD5ABEA2A,
+    0x64AF674E,0xDA86A85F,0xBEBFE988,0x64E4C3FE,0x9DBC8057,0xF0F7C086,
+    0x60787BF8,0x6003604D,0xD1FD8346,0xF6381FB0,0x7745AE04,0xD736FCCC,
+    0x83426B33,0xF01EAB71,0xB0804187,0x3C005E5F,0x77A057BE,0xBDE8AE24,
+    0x55464299,0xBF582E61,0x4E58F48F,0xF2DDFDA2,0xF474EF38,0x8789BDC2,
+    0x5366F9C3,0xC8B38E74,0xB475F255,0x46FCD9B9,0x7AEB2661,0x8B1DDF84,
+    0x846A0E79,0x915F95E2,0x466E598E,0x20B45770,0x8CD55591,0xC902DE4C,
+    0xB90BACE1,0xBB8205D0,0x11A86248,0x7574A99E,0xB77F19B6,0xE0A9DC09,
+    0x662D09A1,0xC4324633,0xE85A1F02,0x09F0BE8C,0x4A99A025,0x1D6EFE10,
+    0x1AB93D1D,0x0BA5A4DF,0xA186F20F,0x2868F169,0xDCB7DA83,0x573906FE,
+    0xA1E2CE9B,0x4FCD7F52,0x50115E01,0xA70683FA,0xA002B5C4,0x0DE6D027,
+    0x9AF88C27,0x773F8641,0xC3604C06,0x61A806B5,0xF0177A28,0xC0F586E0,
+    0x006058AA,0x30DC7D62,0x11E69ED7,0x2338EA63,0x53C2DD94,0xC2C21634,
+    0xBBCBEE56,0x90BCB6DE,0xEBFC7DA1,0xCE591D76,0x6F05E409,0x4B7C0188,
+    0x39720A3D,0x7C927C24,0x86E3725F,0x724D9DB9,0x1AC15BB4,0xD39EB8FC,
+    0xED545578,0x08FCA5B5,0xD83D7CD3,0x4DAD0FC4,0x1E50EF5E,0xB161E6F8,
+    0xA28514D9,0x6C51133C,0x6FD5C7E7,0x56E14EC4,0x362ABFCE,0xDDC6C837,
+    0xD79A3234,0x92638212,0x670EFA8E,0x406000E0 };
+
+static const u32 ks3[256] = {
+    0x3A39CE37,0xD3FAF5CF,0xABC27737,0x5AC52D1B,0x5CB0679E,0x4FA33742,
+    0xD3822740,0x99BC9BBE,0xD5118E9D,0xBF0F7315,0xD62D1C7E,0xC700C47B,
+    0xB78C1B6B,0x21A19045,0xB26EB1BE,0x6A366EB4,0x5748AB2F,0xBC946E79,
+    0xC6A376D2,0x6549C2C8,0x530FF8EE,0x468DDE7D,0xD5730A1D,0x4CD04DC6,
+    0x2939BBDB,0xA9BA4650,0xAC9526E8,0xBE5EE304,0xA1FAD5F0,0x6A2D519A,
+    0x63EF8CE2,0x9A86EE22,0xC089C2B8,0x43242EF6,0xA51E03AA,0x9CF2D0A4,
+    0x83C061BA,0x9BE96A4D,0x8FE51550,0xBA645BD6,0x2826A2F9,0xA73A3AE1,
+    0x4BA99586,0xEF5562E9,0xC72FEFD3,0xF752F7DA,0x3F046F69,0x77FA0A59,
+    0x80E4A915,0x87B08601,0x9B09E6AD,0x3B3EE593,0xE990FD5A,0x9E34D797,
+    0x2CF0B7D9,0x022B8B51,0x96D5AC3A,0x017DA67D,0xD1CF3ED6,0x7C7D2D28,
+    0x1F9F25CF,0xADF2B89B,0x5AD6B472,0x5A88F54C,0xE029AC71,0xE019A5E6,
+    0x47B0ACFD,0xED93FA9B,0xE8D3C48D,0x283B57CC,0xF8D56629,0x79132E28,
+    0x785F0191,0xED756055,0xF7960E44,0xE3D35E8C,0x15056DD4,0x88F46DBA,
+    0x03A16125,0x0564F0BD,0xC3EB9E15,0x3C9057A2,0x97271AEC,0xA93A072A,
+    0x1B3F6D9B,0x1E6321F5,0xF59C66FB,0x26DCF319,0x7533D928,0xB155FDF5,
+    0x03563482,0x8ABA3CBB,0x28517711,0xC20AD9F8,0xABCC5167,0xCCAD925F,
+    0x4DE81751,0x3830DC8E,0x379D5862,0x9320F991,0xEA7A90C2,0xFB3E7BCE,
+    0x5121CE64,0x774FBE32,0xA8B6E37E,0xC3293D46,0x48DE5369,0x6413E680,
+    0xA2AE0810,0xDD6DB224,0x69852DFD,0x09072166,0xB39A460A,0x6445C0DD,
+    0x586CDECF,0x1C20C8AE,0x5BBEF7DD,0x1B588D40,0xCCD2017F,0x6BB4E3BB,
+    0xDDA26A7E,0x3A59FF45,0x3E350A44,0xBCB4CDD5,0x72EACEA8,0xFA6484BB,
+    0x8D6612AE,0xBF3C6F47,0xD29BE463,0x542F5D9E,0xAEC2771B,0xF64E6370,
+    0x740E0D8D,0xE75B1357,0xF8721671,0xAF537D5D,0x4040CB08,0x4EB4E2CC,
+    0x34D2466A,0x0115AF84,0xE1B00428,0x95983A1D,0x06B89FB4,0xCE6EA048,
+    0x6F3F3B82,0x3520AB82,0x011A1D4B,0x277227F8,0x611560B1,0xE7933FDC,
+    0xBB3A792B,0x344525BD,0xA08839E1,0x51CE794B,0x2F32C9B7,0xA01FBAC9,
+    0xE01CC87E,0xBCC7D1F6,0xCF0111C3,0xA1E8AAC7,0x1A908749,0xD44FBD9A,
+    0xD0DADECB,0xD50ADA38,0x0339C32A,0xC6913667,0x8DF9317C,0xE0B12B4F,
+    0xF79E59B7,0x43F5BB3A,0xF2D519FF,0x27D9459C,0xBF97222C,0x15E6FC2A,
+    0x0F91FC71,0x9B941525,0xFAE59361,0xCEB69CEB,0xC2A86459,0x12BAA8D1,
+    0xB6C1075E,0xE3056A0C,0x10D25065,0xCB03A442,0xE0EC6E0E,0x1698DB3B,
+    0x4C98A0BE,0x3278E964,0x9F1F9532,0xE0D392DF,0xD3A0342B,0x8971F21E,
+    0x1B0A7441,0x4BA3348C,0xC5BE7120,0xC37632D8,0xDF359F8D,0x9B992F2E,
+    0xE60B6F47,0x0FE3F11D,0xE54CDA54,0x1EDAD891,0xCE6279CF,0xCD3E7E6F,
+    0x1618B166,0xFD2C1D05,0x848FD2C5,0xF6FB2299,0xF523F357,0xA6327623,
+    0x93A83531,0x56CCCD02,0xACF08162,0x5A75EBB5,0x6E163697,0x88D273CC,
+    0xDE966292,0x81B949D0,0x4C50901B,0x71C65614,0xE6C6C7BD,0x327A140A,
+    0x45E1D006,0xC3F27B9A,0xC9AA53FD,0x62A80F00,0xBB25BFE2,0x35BDD2F6,
+    0x71126905,0xB2040222,0xB6CBCF7C,0xCD769C2B,0x53113EC0,0x1640E3D3,
+    0x38ABBD60,0x2547ADF0,0xBA38209C,0xF746CE76,0x77AFA1C5,0x20756060,
+    0x85CBFE4E,0x8AE88DD8,0x7AAAF9B0,0x4CF9AA7E,0x1948C25C,0x02FB8A8C,
+    0x01C36AE4,0xD6EBE1F9,0x90D4F869,0xA65CDEA0,0x3F09252D,0xC208E69F,
+    0xB74E6132,0xCE77E25B,0x578FDFE3,0x3AC372E6 };
+
+static const u32 ps[BLOWFISH_ROUNDS+2] = {
+    0x243F6A88,0x85A308D3,0x13198A2E,0x03707344,0xA4093822,0x299F31D0,
+    0x082EFA98,0xEC4E6C89,0x452821E6,0x38D01377,0xBE5466CF,0x34E90C6C,
+    0xC0AC29B7,0xC97C50DD,0x3F84D5B5,0xB5470917,0x9216D5D9,0x8979FB1B };
+
+
+
+#if BLOWFISH_ROUNDS != 16
+static inline u32
+function_F( BLOWFISH_context *bc, u32 x )
+{
+    u16 a, b, c, d;
+
+#ifdef WORDS_BIGENDIAN
+    a = ((byte*)&x)[0];
+    b = ((byte*)&x)[1];
+    c = ((byte*)&x)[2];
+    d = ((byte*)&x)[3];
+#else
+    a = ((byte*)&x)[3];
+    b = ((byte*)&x)[2];
+    c = ((byte*)&x)[1];
+    d = ((byte*)&x)[0];
+#endif
+
+    return ((bc->s0[a] + bc->s1[b]) ^ bc->s2[c] ) + bc->s3[d];
+}
+#endif
+
+#ifdef WORDS_BIGENDIAN
+#define F(x) ((( s0[((byte*)&x)[0]] + s1[((byte*)&x)[1]])       \
+                  ^ s2[((byte*)&x)[2]]) + s3[((byte*)&x)[3]] )
+#else
+#define F(x) ((( s0[((byte*)&x)[3]] + s1[((byte*)&x)[2]])       \
+                  ^ s2[((byte*)&x)[1]]) + s3[((byte*)&x)[0]] )
+#endif
+#define R(l,r,i)  do { l ^= p[i]; r ^= F(l); } while(0)
+
+
+static void
+do_encrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
+{
+#if BLOWFISH_ROUNDS == 16
+  u32 xl, xr, *s0, *s1, *s2, *s3, *p;
+
+  xl = *ret_xl;
+  xr = *ret_xr;
+  p = bc->p;
+  s0 = bc->s0;
+  s1 = bc->s1;
+  s2 = bc->s2;
+  s3 = bc->s3;
+
+  R( xl, xr,   0);
+  R( xr, xl,   1);
+  R( xl, xr,   2);
+  R( xr, xl,   3);
+  R( xl, xr,   4);
+  R( xr, xl,   5);
+  R( xl, xr,   6);
+  R( xr, xl,   7);
+  R( xl, xr,   8);
+  R( xr, xl,   9);
+  R( xl, xr, 10);
+  R( xr, xl, 11);
+  R( xl, xr, 12);
+  R( xr, xl, 13);
+  R( xl, xr, 14);
+  R( xr, xl, 15);
+
+  xl ^= p[BLOWFISH_ROUNDS];
+  xr ^= p[BLOWFISH_ROUNDS+1];
+
+  *ret_xl = xr;
+  *ret_xr = xl;
+
+#else
+  u32 xl, xr, temp, *p;
+  int i;
+
+  xl = *ret_xl;
+  xr = *ret_xr;
+  p = bc->p;
+
+  for(i=0; i < BLOWFISH_ROUNDS; i++ )
+    {
+      xl ^= p[i];
+      xr ^= function_F(bc, xl);
+      temp = xl;
+      xl = xr;
+      xr = temp;
+    }
+  temp = xl;
+  xl = xr;
+  xr = temp;
+
+  xr ^= p[BLOWFISH_ROUNDS];
+  xl ^= p[BLOWFISH_ROUNDS+1];
+
+  *ret_xl = xl;
+  *ret_xr = xr;
+#endif
+}
+
+
+static void
+decrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
+{
+#if BLOWFISH_ROUNDS == 16
+  u32 xl, xr, *s0, *s1, *s2, *s3, *p;
+
+  xl = *ret_xl;
+  xr = *ret_xr;
+  p = bc->p;
+  s0 = bc->s0;
+  s1 = bc->s1;
+  s2 = bc->s2;
+  s3 = bc->s3;
+
+  R( xl, xr, 17);
+  R( xr, xl, 16);
+  R( xl, xr, 15);
+  R( xr, xl, 14);
+  R( xl, xr, 13);
+  R( xr, xl, 12);
+  R( xl, xr, 11);
+  R( xr, xl, 10);
+  R( xl, xr,   9);
+  R( xr, xl,   8);
+  R( xl, xr,   7);
+  R( xr, xl,   6);
+  R( xl, xr,   5);
+  R( xr, xl,   4);
+  R( xl, xr,   3);
+  R( xr, xl,   2);
+
+  xl ^= p[1];
+  xr ^= p[0];
+
+  *ret_xl = xr;
+  *ret_xr = xl;
+
+#else
+  u32 xl, xr, temp, *p;
+  int i;
+
+  xl = *ret_xl;
+  xr = *ret_xr;
+  p = bc->p;
+
+  for (i=BLOWFISH_ROUNDS+1; i > 1; i-- )
+    {
+      xl ^= p[i];
+      xr ^= function_F(bc, xl);
+      temp = xl;
+      xl = xr;
+      xr = temp;
+    }
+
+  temp = xl;
+  xl = xr;
+  xr = temp;
+
+  xr ^= p[1];
+  xl ^= p[0];
+
+  *ret_xl = xl;
+  *ret_xr = xr;
+#endif
+}
+
+#undef F
+#undef R
+
+static void
+do_encrypt_block ( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf )
+{
+  u32 d1, d2;
+
+  d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
+  d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
+  do_encrypt( bc, &d1, &d2 );
+  outbuf[0] = (d1 >> 24) & 0xff;
+  outbuf[1] = (d1 >> 16) & 0xff;
+  outbuf[2] = (d1 >>   8) & 0xff;
+  outbuf[3] =  d1         & 0xff;
+  outbuf[4] = (d2 >> 24) & 0xff;
+  outbuf[5] = (d2 >> 16) & 0xff;
+  outbuf[6] = (d2 >>   8) & 0xff;
+  outbuf[7] =  d2         & 0xff;
+}
+
+static void
+encrypt_block (void *context, byte *outbuf, const byte *inbuf)
+{
+  BLOWFISH_context *bc = (BLOWFISH_context *) context;
+  do_encrypt_block (bc, outbuf, inbuf);
+  _gcry_burn_stack (64);
+}
+
+
+static void
+do_decrypt_block (BLOWFISH_context *bc, byte *outbuf, const byte *inbuf)
+{
+  u32 d1, d2;
+
+  d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
+  d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
+  decrypt( bc, &d1, &d2 );
+  outbuf[0] = (d1 >> 24) & 0xff;
+  outbuf[1] = (d1 >> 16) & 0xff;
+  outbuf[2] = (d1 >>   8) & 0xff;
+  outbuf[3] =  d1         & 0xff;
+  outbuf[4] = (d2 >> 24) & 0xff;
+  outbuf[5] = (d2 >> 16) & 0xff;
+  outbuf[6] = (d2 >>   8) & 0xff;
+  outbuf[7] =  d2         & 0xff;
+}
+
+static void
+decrypt_block (void *context, byte *outbuf, const byte *inbuf)
+{
+  BLOWFISH_context *bc = (BLOWFISH_context *) context;
+  do_decrypt_block (bc, outbuf, inbuf);
+  _gcry_burn_stack (64);
+}
+
+
+static const char*
+selftest(void)
+{
+  BLOWFISH_context c;
+  byte plain[] = "BLOWFISH";
+  byte buffer[8];
+  byte plain3[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 };
+  byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 };
+  byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 };
+
+  bf_setkey( (void *) &c,
+             (const unsigned char*)"abcdefghijklmnopqrstuvwxyz", 26 );
+  encrypt_block( (void *) &c, buffer, plain );
+  if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) )
+    return "Blowfish selftest failed (1).";
+  decrypt_block( (void *) &c, buffer, buffer );
+  if( memcmp( buffer, plain, 8 ) )
+    return "Blowfish selftest failed (2).";
+
+  bf_setkey( (void *) &c, key3, 8 );
+  encrypt_block( (void *) &c, buffer, plain3 );
+  if( memcmp( buffer, cipher3, 8 ) )
+    return "Blowfish selftest failed (3).";
+  decrypt_block( (void *) &c, buffer, buffer );
+  if( memcmp( buffer, plain3, 8 ) )
+    return "Blowfish selftest failed (4).";
+  return NULL;
+}
+
+
+
+static gcry_err_code_t
+do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen)
+{
+  int i, j;
+  u32 data, datal, datar;
+  static int initialized;
+  static const char *selftest_failed;
+
+  if( !initialized ) 
+    {
+      initialized = 1;
+      selftest_failed = selftest();
+      if( selftest_failed )
+        log_error ("%s\n", selftest_failed );
+    }
+  if( selftest_failed )
+    return GPG_ERR_SELFTEST_FAILED;
+
+  for(i=0; i < BLOWFISH_ROUNDS+2; i++ )
+    c->p[i] = ps[i];
+  for(i=0; i < 256; i++ ) 
+    {
+      c->s0[i] = ks0[i];
+      c->s1[i] = ks1[i];
+      c->s2[i] = ks2[i];
+      c->s3[i] = ks3[i];
+    }
+
+  for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ ) 
+    {
+#ifdef WORDS_BIGENDIAN
+      ((byte*)&data)[0] = key[j];
+      ((byte*)&data)[1] = key[(j+1)%keylen];
+      ((byte*)&data)[2] = key[(j+2)%keylen];
+      ((byte*)&data)[3] = key[(j+3)%keylen];
+#else
+      ((byte*)&data)[3] = key[j];
+      ((byte*)&data)[2] = key[(j+1)%keylen];
+      ((byte*)&data)[1] = key[(j+2)%keylen];
+      ((byte*)&data)[0] = key[(j+3)%keylen];
+#endif
+      c->p[i] ^= data;
+      j = (j+4) % keylen;
+    }
+
+  datal = datar = 0;
+  for(i=0; i < BLOWFISH_ROUNDS+2; i += 2 )
+    {
+      do_encrypt( c, &datal, &datar );
+      c->p[i]   = datal;
+      c->p[i+1] = datar;
+    }
+  for(i=0; i < 256; i += 2 )   
+    {
+      do_encrypt( c, &datal, &datar );
+      c->s0[i]   = datal;
+      c->s0[i+1] = datar;
+    }
+  for(i=0; i < 256; i += 2 )
+    {
+      do_encrypt( c, &datal, &datar );
+      c->s1[i]   = datal;
+      c->s1[i+1] = datar;
+    }
+  for(i=0; i < 256; i += 2 )
+    {
+      do_encrypt( c, &datal, &datar );
+      c->s2[i]   = datal;
+      c->s2[i+1] = datar;
+    }
+  for(i=0; i < 256; i += 2 )
+    {
+      do_encrypt( c, &datal, &datar );
+      c->s3[i]   = datal;
+      c->s3[i+1] = datar;
+    }
+
+
+  /* Check for weak key.  A weak key is a key in which a value in
+     the P-array (here c) occurs more than once per table.  */
+  for(i=0; i < 255; i++ )
+    {
+      for( j=i+1; j < 256; j++)
+        {
+          if( (c->s0[i] == c->s0[j]) || (c->s1[i] == c->s1[j]) ||
+              (c->s2[i] == c->s2[j]) || (c->s3[i] == c->s3[j]) )
+            return GPG_ERR_WEAK_KEY;
+        }
+    }
+
+  return GPG_ERR_NO_ERROR;
+}
+
+
+static gcry_err_code_t
+bf_setkey (void *context, const byte *key, unsigned keylen)
+{
+  BLOWFISH_context *c = (BLOWFISH_context *) context;
+  gcry_err_code_t rc = do_bf_setkey (c, key, keylen);
+  _gcry_burn_stack (64);
+  return rc;
+}
+
+
+gcry_cipher_spec_t _gcry_cipher_spec_blowfish =
+  {
+    "BLOWFISH", NULL, NULL, BLOWFISH_BLOCKSIZE, 128,
+    sizeof (BLOWFISH_context),
+    bf_setkey, encrypt_block, decrypt_block
+  };
diff --git a/grub-core/lib/libgcrypt/cipher/camellia-glue.c b/grub-core/lib/libgcrypt/cipher/camellia-glue.c
new file mode 100644 (file)
index 0000000..067af85
--- /dev/null
@@ -0,0 +1,253 @@
+/* camellia-glue.c - Glue for the Camellia cipher
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/* I put all the libgcrypt-specific stuff in this file to keep the
+   camellia.c/camellia.h files exactly as provided by NTT.  If they
+   update their code, this should make it easier to bring the changes
+   in. - dshaw
+
+   There is one small change which needs to be done: Include the
+   following code at the top of camellia.h: */
+#if 0
+
+/* To use Camellia with libraries it is often useful to keep the name
+ * space of the library clean.  The following macro is thus useful:
+ *
+ *     #define CAMELLIA_EXT_SYM_PREFIX foo_
+ *  
+ * This prefixes all external symbols with "foo_".
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef CAMELLIA_EXT_SYM_PREFIX
+#define CAMELLIA_PREFIX1(x,y) x ## y
+#define CAMELLIA_PREFIX2(x,y) CAMELLIA_PREFIX1(x,y)
+#define CAMELLIA_PREFIX(x)    CAMELLIA_PREFIX2(CAMELLIA_EXT_SYM_PREFIX,x)
+#define Camellia_Ekeygen      CAMELLIA_PREFIX(Camellia_Ekeygen)
+#define Camellia_EncryptBlock CAMELLIA_PREFIX(Camellia_EncryptBlock)
+#define Camellia_DecryptBlock CAMELLIA_PREFIX(Camellia_DecryptBlock)
+#define camellia_decrypt128   CAMELLIA_PREFIX(camellia_decrypt128)
+#define camellia_decrypt256   CAMELLIA_PREFIX(camellia_decrypt256)
+#define camellia_encrypt128   CAMELLIA_PREFIX(camellia_encrypt128)
+#define camellia_encrypt256   CAMELLIA_PREFIX(camellia_encrypt256)
+#define camellia_setup128     CAMELLIA_PREFIX(camellia_setup128)
+#define camellia_setup192     CAMELLIA_PREFIX(camellia_setup192) 
+#define camellia_setup256     CAMELLIA_PREFIX(camellia_setup256)
+#endif /*CAMELLIA_EXT_SYM_PREFIX*/
+
+#endif /* Code sample. */
+
+
+#include <config.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "camellia.h"
+
+typedef struct
+{
+  int keybitlength;
+  KEY_TABLE_TYPE keytable;
+} CAMELLIA_context;
+
+static const char *selftest(void);
+
+static gcry_err_code_t
+camellia_setkey(void *c, const byte *key, unsigned keylen)
+{
+  CAMELLIA_context *ctx=c;
+  static int initialized=0;
+  static const char *selftest_failed=NULL;
+
+  if(keylen!=16 && keylen!=24 && keylen!=32)
+    return GPG_ERR_INV_KEYLEN;
+
+  if(!initialized)
+    {
+      initialized=1;
+      selftest_failed=selftest();
+      if(selftest_failed)
+       log_error("%s\n",selftest_failed);
+    }
+
+  if(selftest_failed)
+    return GPG_ERR_SELFTEST_FAILED;
+
+  ctx->keybitlength=keylen*8;
+  Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable);
+  _gcry_burn_stack
+    ((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */
+     +(4+32)*sizeof(u32)+2*sizeof(void*)    /* camellia_setup192 */
+     +0+sizeof(int)+2*sizeof(void*)         /* Camellia_Ekeygen */
+     +3*2*sizeof(void*)                     /* Function calls.  */
+     );  
+
+  return 0;
+}
+
+static void
+camellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
+{
+  CAMELLIA_context *ctx=c;
+
+  Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
+  _gcry_burn_stack
+    (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
+     +4*sizeof(u32)
+     +2*sizeof(u32*)+4*sizeof(u32)
+     +2*2*sizeof(void*) /* Function calls.  */
+    );
+}
+
+static void
+camellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
+{
+  CAMELLIA_context *ctx=c;
+
+  Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
+  _gcry_burn_stack
+    (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
+     +4*sizeof(u32)
+     +2*sizeof(u32*)+4*sizeof(u32)
+     +2*2*sizeof(void*) /* Function calls.  */
+    );
+}
+
+static const char *
+selftest(void)
+{
+  CAMELLIA_context ctx;
+  byte scratch[16];
+  
+  /* These test vectors are from RFC-3713 */
+  const byte plaintext[]=
+    {
+      0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+      0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
+    };
+  const byte key_128[]=
+    {
+      0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+      0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
+    };
+  const byte ciphertext_128[]=
+    {
+      0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,
+      0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43
+    };
+  const byte key_192[]=
+    {
+      0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,
+      0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77
+    };
+  const byte ciphertext_192[]=
+    {
+      0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,
+      0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9
+    };
+  const byte key_256[]=
+    {
+      0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,
+      0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,
+      0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
+    };
+  const byte ciphertext_256[]=
+    {
+      0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,
+      0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09
+    };
+
+  camellia_setkey(&ctx,key_128,sizeof(key_128));
+  camellia_encrypt(&ctx,scratch,plaintext);
+  if(memcmp(scratch,ciphertext_128,sizeof(ciphertext_128))!=0)
+    return "CAMELLIA-128 test encryption failed.";
+  camellia_decrypt(&ctx,scratch,scratch);
+  if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
+    return "CAMELLIA-128 test decryption failed.";
+
+  camellia_setkey(&ctx,key_192,sizeof(key_192));
+  camellia_encrypt(&ctx,scratch,plaintext);
+  if(memcmp(scratch,ciphertext_192,sizeof(ciphertext_192))!=0)
+    return "CAMELLIA-192 test encryption failed.";
+  camellia_decrypt(&ctx,scratch,scratch);
+  if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
+    return "CAMELLIA-192 test decryption failed.";
+
+  camellia_setkey(&ctx,key_256,sizeof(key_256));
+  camellia_encrypt(&ctx,scratch,plaintext);
+  if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0)
+    return "CAMELLIA-256 test encryption failed.";
+  camellia_decrypt(&ctx,scratch,scratch);
+  if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
+    return "CAMELLIA-256 test decryption failed.";
+
+  return NULL;
+}
+
+/* These oids are from
+   <http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications_oid.html>,
+   retrieved May 1, 2007. */
+
+static gcry_cipher_oid_spec_t camellia128_oids[] =
+  {
+    {"1.2.392.200011.61.1.1.1.2", GCRY_CIPHER_MODE_CBC},
+    {"0.3.4401.5.3.1.9.1", GCRY_CIPHER_MODE_ECB},
+    {"0.3.4401.5.3.1.9.3", GCRY_CIPHER_MODE_OFB},
+    {"0.3.4401.5.3.1.9.4", GCRY_CIPHER_MODE_CFB},
+    { NULL }
+  };
+
+static gcry_cipher_oid_spec_t camellia192_oids[] =
+  {
+    {"1.2.392.200011.61.1.1.1.3", GCRY_CIPHER_MODE_CBC},
+    {"0.3.4401.5.3.1.9.21", GCRY_CIPHER_MODE_ECB},
+    {"0.3.4401.5.3.1.9.23", GCRY_CIPHER_MODE_OFB},
+    {"0.3.4401.5.3.1.9.24", GCRY_CIPHER_MODE_CFB},
+    { NULL }
+  };
+
+static gcry_cipher_oid_spec_t camellia256_oids[] =
+  {
+    {"1.2.392.200011.61.1.1.1.4", GCRY_CIPHER_MODE_CBC},
+    {"0.3.4401.5.3.1.9.41", GCRY_CIPHER_MODE_ECB},
+    {"0.3.4401.5.3.1.9.43", GCRY_CIPHER_MODE_OFB},
+    {"0.3.4401.5.3.1.9.44", GCRY_CIPHER_MODE_CFB},
+    { NULL }
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_camellia128 =
+  {
+    "CAMELLIA128",NULL,camellia128_oids,CAMELLIA_BLOCK_SIZE,128,
+    sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_camellia192 =
+  {
+    "CAMELLIA192",NULL,camellia192_oids,CAMELLIA_BLOCK_SIZE,192,
+    sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_camellia256 =
+  {
+    "CAMELLIA256",NULL,camellia256_oids,CAMELLIA_BLOCK_SIZE,256,
+    sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
+  };
diff --git a/grub-core/lib/libgcrypt/cipher/camellia.c b/grub-core/lib/libgcrypt/cipher/camellia.c
new file mode 100644 (file)
index 0000000..79cd49b
--- /dev/null
@@ -0,0 +1,1461 @@
+/* camellia.h  ver 1.2.0
+ *
+ * Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * Algorithm Specification 
+ *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "camellia.h"
+
+/* u32 must be 32bit word */
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+/* key constants */
+
+#define CAMELLIA_SIGMA1L (0xA09E667FL)
+#define CAMELLIA_SIGMA1R (0x3BCC908BL)
+#define CAMELLIA_SIGMA2L (0xB67AE858L)
+#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
+#define CAMELLIA_SIGMA3L (0xC6EF372FL)
+#define CAMELLIA_SIGMA3R (0xE94F82BEL)
+#define CAMELLIA_SIGMA4L (0x54FF53A5L)
+#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
+#define CAMELLIA_SIGMA5L (0x10E527FAL)
+#define CAMELLIA_SIGMA5R (0xDE682D1DL)
+#define CAMELLIA_SIGMA6L (0xB05688C2L)
+#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
+
+/*
+ *  macros
+ */
+
+
+#if defined(_MSC_VER)
+
+# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+# define GETU32(p) SWAP(*((u32 *)(p)))
+# define PUTU32(ct, st) {*((u32 *)(ct)) = SWAP((st));}
+
+#else /* not MS-VC */
+
+# define GETU32(pt)                            \
+    (((u32)(pt)[0] << 24)                      \
+     ^ ((u32)(pt)[1] << 16)                    \
+     ^ ((u32)(pt)[2] <<  8)                    \
+     ^ ((u32)(pt)[3]))
+
+# define PUTU32(ct, st)  {                     \
+       (ct)[0] = (u8)((st) >> 24);             \
+       (ct)[1] = (u8)((st) >> 16);             \
+       (ct)[2] = (u8)((st) >>  8);             \
+       (ct)[3] = (u8)(st); }
+
+#endif
+
+#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])
+#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])
+
+/* rotation right shift 1byte */
+#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
+/* rotation left shift 1bit */
+#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
+/* rotation left shift 1byte */
+#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
+
+#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits)   \
+    do {                                               \
+       w0 = ll;                                        \
+       ll = (ll << bits) + (lr >> (32 - bits));        \
+       lr = (lr << bits) + (rl >> (32 - bits));        \
+       rl = (rl << bits) + (rr >> (32 - bits));        \
+       rr = (rr << bits) + (w0 >> (32 - bits));        \
+    } while(0)
+
+#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits)        \
+    do {                                               \
+       w0 = ll;                                        \
+       w1 = lr;                                        \
+       ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
+       lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
+       rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
+       rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
+    } while(0)
+
+#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
+#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
+#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
+#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
+
+#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)     \
+    do {                                                       \
+       il = xl ^ kl;                                           \
+       ir = xr ^ kr;                                           \
+       t0 = il >> 16;                                          \
+       t1 = ir >> 16;                                          \
+       yl = CAMELLIA_SP1110(ir & 0xff)                         \
+           ^ CAMELLIA_SP0222((t1 >> 8) & 0xff)                 \
+           ^ CAMELLIA_SP3033(t1 & 0xff)                        \
+           ^ CAMELLIA_SP4404((ir >> 8) & 0xff);                \
+       yr = CAMELLIA_SP1110((t0 >> 8) & 0xff)                  \
+           ^ CAMELLIA_SP0222(t0 & 0xff)                        \
+           ^ CAMELLIA_SP3033((il >> 8) & 0xff)                 \
+           ^ CAMELLIA_SP4404(il & 0xff);                       \
+       yl ^= yr;                                               \
+       yr = CAMELLIA_RR8(yr);                                  \
+       yr ^= yl;                                               \
+    } while(0)
+
+
+/*
+ * for speed up
+ *
+ */
+#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
+    do {                                                               \
+       t0 = kll;                                                       \
+       t0 &= ll;                                                       \
+       lr ^= CAMELLIA_RL1(t0);                                         \
+       t1 = klr;                                                       \
+       t1 |= lr;                                                       \
+       ll ^= t1;                                                       \
+                                                                       \
+       t2 = krr;                                                       \
+       t2 |= rr;                                                       \
+       rl ^= t2;                                                       \
+       t3 = krl;                                                       \
+       t3 &= rl;                                                       \
+       rr ^= CAMELLIA_RL1(t3);                                         \
+    } while(0)
+
+#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)       \
+    do {                                                               \
+       ir = CAMELLIA_SP1110(xr & 0xff)                                 \
+           ^ CAMELLIA_SP0222((xr >> 24) & 0xff)                        \
+           ^ CAMELLIA_SP3033((xr >> 16) & 0xff)                        \
+           ^ CAMELLIA_SP4404((xr >> 8) & 0xff);                        \
+       il = CAMELLIA_SP1110((xl >> 24) & 0xff)                         \
+           ^ CAMELLIA_SP0222((xl >> 16) & 0xff)                        \
+           ^ CAMELLIA_SP3033((xl >> 8) & 0xff)                         \
+           ^ CAMELLIA_SP4404(xl & 0xff);                               \
+       il ^= kl;                                                       \
+       ir ^= kr;                                                       \
+       ir ^= il;                                                       \
+       il = CAMELLIA_RR8(il);                                          \
+       il ^= ir;                                                       \
+       yl ^= ir;                                                       \
+       yr ^= il;                                                       \
+    } while(0)
+
+
+static const u32 camellia_sp1110[256] = {
+    0x70707000,0x82828200,0x2c2c2c00,0xececec00,
+    0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
+    0xe4e4e400,0x85858500,0x57575700,0x35353500,
+    0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
+    0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
+    0x45454500,0x19191900,0xa5a5a500,0x21212100,
+    0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
+    0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
+    0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
+    0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
+    0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
+    0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
+    0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
+    0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
+    0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
+    0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
+    0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
+    0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
+    0x74747400,0x12121200,0x2b2b2b00,0x20202000,
+    0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
+    0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
+    0x34343400,0x7e7e7e00,0x76767600,0x05050500,
+    0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
+    0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
+    0x14141400,0x58585800,0x3a3a3a00,0x61616100,
+    0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
+    0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
+    0x53535300,0x18181800,0xf2f2f200,0x22222200,
+    0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
+    0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
+    0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
+    0x60606000,0xfcfcfc00,0x69696900,0x50505000,
+    0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
+    0xa1a1a100,0x89898900,0x62626200,0x97979700,
+    0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
+    0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
+    0x10101000,0xc4c4c400,0x00000000,0x48484800,
+    0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
+    0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
+    0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
+    0x87878700,0x5c5c5c00,0x83838300,0x02020200,
+    0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
+    0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
+    0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
+    0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
+    0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
+    0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
+    0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
+    0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
+    0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
+    0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
+    0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
+    0x78787800,0x98989800,0x06060600,0x6a6a6a00,
+    0xe7e7e700,0x46464600,0x71717100,0xbababa00,
+    0xd4d4d400,0x25252500,0xababab00,0x42424200,
+    0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
+    0x72727200,0x07070700,0xb9b9b900,0x55555500,
+    0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
+    0x36363600,0x49494900,0x2a2a2a00,0x68686800,
+    0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
+    0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
+    0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
+    0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
+    0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
+};
+
+static const u32 camellia_sp0222[256] = {
+    0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
+    0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
+    0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
+    0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
+    0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
+    0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
+    0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
+    0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
+    0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
+    0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
+    0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
+    0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
+    0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
+    0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
+    0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
+    0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
+    0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
+    0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
+    0x00e8e8e8,0x00242424,0x00565656,0x00404040,
+    0x00e1e1e1,0x00636363,0x00090909,0x00333333,
+    0x00bfbfbf,0x00989898,0x00979797,0x00858585,
+    0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
+    0x00dadada,0x006f6f6f,0x00535353,0x00626262,
+    0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
+    0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
+    0x00bdbdbd,0x00363636,0x00222222,0x00383838,
+    0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
+    0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
+    0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
+    0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
+    0x00484848,0x00101010,0x00d1d1d1,0x00515151,
+    0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
+    0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
+    0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
+    0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
+    0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
+    0x00202020,0x00898989,0x00000000,0x00909090,
+    0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
+    0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
+    0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
+    0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
+    0x009b9b9b,0x00949494,0x00212121,0x00666666,
+    0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
+    0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
+    0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
+    0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
+    0x00030303,0x002d2d2d,0x00dedede,0x00969696,
+    0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
+    0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
+    0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
+    0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
+    0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
+    0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
+    0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
+    0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
+    0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
+    0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
+    0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
+    0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
+    0x00787878,0x00707070,0x00e3e3e3,0x00494949,
+    0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
+    0x00777777,0x00939393,0x00868686,0x00838383,
+    0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
+    0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
+};
+
+static const u32 camellia_sp3033[256] = {
+    0x38003838,0x41004141,0x16001616,0x76007676,
+    0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
+    0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
+    0x75007575,0x06000606,0x57005757,0xa000a0a0,
+    0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
+    0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
+    0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
+    0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
+    0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
+    0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
+    0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
+    0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
+    0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
+    0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
+    0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
+    0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
+    0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
+    0xfd00fdfd,0x66006666,0x58005858,0x96009696,
+    0x3a003a3a,0x09000909,0x95009595,0x10001010,
+    0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
+    0xef00efef,0x26002626,0xe500e5e5,0x61006161,
+    0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
+    0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
+    0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
+    0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
+    0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
+    0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
+    0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
+    0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
+    0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
+    0x12001212,0x04000404,0x74007474,0x54005454,
+    0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
+    0x55005555,0x68006868,0x50005050,0xbe00bebe,
+    0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
+    0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
+    0x70007070,0xff00ffff,0x32003232,0x69006969,
+    0x08000808,0x62006262,0x00000000,0x24002424,
+    0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
+    0x45004545,0x81008181,0x73007373,0x6d006d6d,
+    0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
+    0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
+    0xe600e6e6,0x25002525,0x48004848,0x99009999,
+    0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
+    0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
+    0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
+    0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
+    0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
+    0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
+    0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
+    0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
+    0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
+    0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
+    0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
+    0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
+    0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
+    0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
+    0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
+    0x7c007c7c,0x77007777,0x56005656,0x05000505,
+    0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
+    0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
+    0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
+    0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
+    0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
+    0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
+};
+
+static const u32 camellia_sp4404[256] = {
+    0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
+    0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
+    0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
+    0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
+    0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
+    0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
+    0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
+    0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
+    0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
+    0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
+    0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
+    0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
+    0x14140014,0x3a3a003a,0xdede00de,0x11110011,
+    0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
+    0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
+    0x24240024,0xe8e800e8,0x60600060,0x69690069,
+    0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
+    0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
+    0x10100010,0x00000000,0xa3a300a3,0x75750075,
+    0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
+    0x87870087,0x83830083,0xcdcd00cd,0x90900090,
+    0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
+    0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
+    0x81810081,0x6f6f006f,0x13130013,0x63630063,
+    0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
+    0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
+    0x78780078,0x06060006,0xe7e700e7,0x71710071,
+    0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
+    0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
+    0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
+    0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
+    0x15150015,0xadad00ad,0x77770077,0x80800080,
+    0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
+    0x85850085,0x35350035,0x0c0c000c,0x41410041,
+    0xefef00ef,0x93930093,0x19190019,0x21210021,
+    0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
+    0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
+    0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
+    0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
+    0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
+    0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
+    0x12120012,0x20200020,0xb1b100b1,0x99990099,
+    0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
+    0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
+    0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
+    0x0f0f000f,0x16160016,0x18180018,0x22220022,
+    0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
+    0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
+    0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
+    0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
+    0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
+    0x03030003,0xdada00da,0x3f3f003f,0x94940094,
+    0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
+    0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
+    0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
+    0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
+    0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
+    0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
+    0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
+    0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
+    0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
+    0x49490049,0x68680068,0x38380038,0xa4a400a4,
+    0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
+    0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
+};
+
+
+/**
+ * Stuff related to the Camellia key schedule
+ */
+#define subl(x) subL[(x)]
+#define subr(x) subR[(x)]
+
+void camellia_setup128(const unsigned char *key, u32 *subkey)
+{
+    u32 kll, klr, krl, krr;
+    u32 il, ir, t0, t1, w0, w1;
+    u32 kw4l, kw4r, dw, tl, tr;
+    u32 subL[26];
+    u32 subR[26];
+
+    /**
+     *  k == kll || klr || krl || krr (|| is concatination)
+     */
+    kll = GETU32(key     );
+    klr = GETU32(key +  4);
+    krl = GETU32(key +  8);
+    krr = GETU32(key + 12);
+    /**
+     * generate KL dependent subkeys
+     */
+    subl(0) = kll; subr(0) = klr;
+    subl(1) = krl; subr(1) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(4) = kll; subr(4) = klr;
+    subl(5) = krl; subr(5) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+    subl(10) = kll; subr(10) = klr;
+    subl(11) = krl; subr(11) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(13) = krl; subr(13) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(16) = kll; subr(16) = klr;
+    subl(17) = krl; subr(17) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(18) = kll; subr(18) = klr;
+    subl(19) = krl; subr(19) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(22) = kll; subr(22) = klr;
+    subl(23) = krl; subr(23) = krr;
+
+    /* generate KA */
+    kll = subl(0); klr = subr(0);
+    krl = subl(1); krr = subr(1);
+    CAMELLIA_F(kll, klr,
+              CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+              w0, w1, il, ir, t0, t1);
+    krl ^= w0; krr ^= w1;
+    CAMELLIA_F(krl, krr,
+              CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+              kll, klr, il, ir, t0, t1);
+    CAMELLIA_F(kll, klr,
+              CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+              krl, krr, il, ir, t0, t1);
+    krl ^= w0; krr ^= w1;
+    CAMELLIA_F(krl, krr,
+              CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+              w0, w1, il, ir, t0, t1);
+    kll ^= w0; klr ^= w1;
+
+    /* generate KA dependent subkeys */
+    subl(2) = kll; subr(2) = klr;
+    subl(3) = krl; subr(3) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(6) = kll; subr(6) = klr;
+    subl(7) = krl; subr(7) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(8) = kll; subr(8) = klr;
+    subl(9) = krl; subr(9) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(12) = kll; subr(12) = klr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(14) = kll; subr(14) = klr;
+    subl(15) = krl; subr(15) = krr;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+    subl(20) = kll; subr(20) = klr;
+    subl(21) = krl; subr(21) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(24) = kll; subr(24) = klr;
+    subl(25) = krl; subr(25) = krr;
+
+
+    /* absorb kw2 to other subkeys */
+    subl(3) ^= subl(1); subr(3) ^= subr(1);
+    subl(5) ^= subl(1); subr(5) ^= subr(1);
+    subl(7) ^= subl(1); subr(7) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(9);
+    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(11) ^= subl(1); subr(11) ^= subr(1);
+    subl(13) ^= subl(1); subr(13) ^= subr(1);
+    subl(15) ^= subl(1); subr(15) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(17);
+    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(19) ^= subl(1); subr(19) ^= subr(1);
+    subl(21) ^= subl(1); subr(21) ^= subr(1);
+    subl(23) ^= subl(1); subr(23) ^= subr(1);
+    subl(24) ^= subl(1); subr(24) ^= subr(1);
+
+    /* absorb kw4 to other subkeys */
+    kw4l = subl(25); kw4r = subr(25);
+    subl(22) ^= kw4l; subr(22) ^= kw4r;
+    subl(20) ^= kw4l; subr(20) ^= kw4r;
+    subl(18) ^= kw4l; subr(18) ^= kw4r;
+    kw4l ^= kw4r & ~subr(16);
+    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+    subl(14) ^= kw4l; subr(14) ^= kw4r;
+    subl(12) ^= kw4l; subr(12) ^= kw4r;
+    subl(10) ^= kw4l; subr(10) ^= kw4r;
+    kw4l ^= kw4r & ~subr(8);
+    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+    subl(6) ^= kw4l; subr(6) ^= kw4r;
+    subl(4) ^= kw4l; subr(4) ^= kw4r;
+    subl(2) ^= kw4l; subr(2) ^= kw4r;
+    subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+    /* key XOR is end of F-function */
+    CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+    CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+    CamelliaSubkeyL(2) = subl(3);
+    CamelliaSubkeyR(2) = subr(3);
+    CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+    CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+    CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+    CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+    CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+    CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+    CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+    CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+    tl = subl(10) ^ (subr(10) & ~subr(8));
+    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(7) = subl(6) ^ tl;
+    CamelliaSubkeyR(7) = subr(6) ^ tr;
+    CamelliaSubkeyL(8) = subl(8);
+    CamelliaSubkeyR(8) = subr(8);
+    CamelliaSubkeyL(9) = subl(9);
+    CamelliaSubkeyR(9) = subr(9);
+    tl = subl(7) ^ (subr(7) & ~subr(9));
+    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(10) = tl ^ subl(11);
+    CamelliaSubkeyR(10) = tr ^ subr(11);
+    CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+    CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+    CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+    CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+    CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+    CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+    CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+    CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+    tl = subl(18) ^ (subr(18) & ~subr(16));
+    dw = tl & subl(16),        tr = subr(18) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(15) = subl(14) ^ tl;
+    CamelliaSubkeyR(15) = subr(14) ^ tr;
+    CamelliaSubkeyL(16) = subl(16);
+    CamelliaSubkeyR(16) = subr(16);
+    CamelliaSubkeyL(17) = subl(17);
+    CamelliaSubkeyR(17) = subr(17);
+    tl = subl(15) ^ (subr(15) & ~subr(17));
+    dw = tl & subl(17),        tr = subr(15) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(18) = tl ^ subl(19);
+    CamelliaSubkeyR(18) = tr ^ subr(19);
+    CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+    CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+    CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+    CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+    CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+    CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+    CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+    CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+    CamelliaSubkeyL(23) = subl(22);
+    CamelliaSubkeyR(23) = subr(22);
+    CamelliaSubkeyL(24) = subl(24) ^ subl(23);
+    CamelliaSubkeyR(24) = subr(24) ^ subr(23);
+
+    /* apply the inverse of the last half of P-function */
+    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+
+    return;
+}
+
+void camellia_setup256(const unsigned char *key, u32 *subkey)
+{
+    u32 kll,klr,krl,krr;           /* left half of key */
+    u32 krll,krlr,krrl,krrr;       /* right half of key */
+    u32 il, ir, t0, t1, w0, w1;    /* temporary variables */
+    u32 kw4l, kw4r, dw, tl, tr;
+    u32 subL[34];
+    u32 subR[34];
+
+    /**
+     *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
+     *  (|| is concatination)
+     */
+
+    kll  = GETU32(key     );
+    klr  = GETU32(key +  4);
+    krl  = GETU32(key +  8);
+    krr  = GETU32(key + 12);
+    krll = GETU32(key + 16);
+    krlr = GETU32(key + 20);
+    krrl = GETU32(key + 24);
+    krrr = GETU32(key + 28);
+
+    /* generate KL dependent subkeys */
+    subl(0) = kll; subr(0) = klr;
+    subl(1) = krl; subr(1) = krr;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
+    subl(12) = kll; subr(12) = klr;
+    subl(13) = krl; subr(13) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(16) = kll; subr(16) = klr;
+    subl(17) = krl; subr(17) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(22) = kll; subr(22) = klr;
+    subl(23) = krl; subr(23) = krr;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+    subl(30) = kll; subr(30) = klr;
+    subl(31) = krl; subr(31) = krr;
+
+    /* generate KR dependent subkeys */
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+    subl(4) = krll; subr(4) = krlr;
+    subl(5) = krrl; subr(5) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+    subl(8) = krll; subr(8) = krlr;
+    subl(9) = krrl; subr(9) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+    subl(18) = krll; subr(18) = krlr;
+    subl(19) = krrl; subr(19) = krrr;
+    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+    subl(26) = krll; subr(26) = krlr;
+    subl(27) = krrl; subr(27) = krrr;
+    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+
+    /* generate KA */
+    kll = subl(0) ^ krll; klr = subr(0) ^ krlr;
+    krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;
+    CAMELLIA_F(kll, klr,
+              CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+              w0, w1, il, ir, t0, t1);
+    krl ^= w0; krr ^= w1;
+    CAMELLIA_F(krl, krr,
+              CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+              kll, klr, il, ir, t0, t1);
+    kll ^= krll; klr ^= krlr;
+    CAMELLIA_F(kll, klr,
+              CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+              krl, krr, il, ir, t0, t1);
+    krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
+    CAMELLIA_F(krl, krr,
+              CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+              w0, w1, il, ir, t0, t1);
+    kll ^= w0; klr ^= w1;
+
+    /* generate KB */
+    krll ^= kll; krlr ^= klr;
+    krrl ^= krl; krrr ^= krr;
+    CAMELLIA_F(krll, krlr,
+              CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
+              w0, w1, il, ir, t0, t1);
+    krrl ^= w0; krrr ^= w1;
+    CAMELLIA_F(krrl, krrr,
+              CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
+              w0, w1, il, ir, t0, t1);
+    krll ^= w0; krlr ^= w1;
+
+    /* generate KA dependent subkeys */
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(6) = kll; subr(6) = klr;
+    subl(7) = krl; subr(7) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+    subl(14) = kll; subr(14) = klr;
+    subl(15) = krl; subr(15) = krr;
+    subl(24) = klr; subr(24) = krl;
+    subl(25) = krr; subr(25) = kll;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
+    subl(28) = kll; subr(28) = klr;
+    subl(29) = krl; subr(29) = krr;
+
+    /* generate KB dependent subkeys */
+    subl(2) = krll; subr(2) = krlr;
+    subl(3) = krrl; subr(3) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+    subl(10) = krll; subr(10) = krlr;
+    subl(11) = krrl; subr(11) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+    subl(20) = krll; subr(20) = krlr;
+    subl(21) = krrl; subr(21) = krrr;
+    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
+    subl(32) = krll; subr(32) = krlr;
+    subl(33) = krrl; subr(33) = krrr;
+
+    /* absorb kw2 to other subkeys */
+    subl(3) ^= subl(1); subr(3) ^= subr(1);
+    subl(5) ^= subl(1); subr(5) ^= subr(1);
+    subl(7) ^= subl(1); subr(7) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(9);
+    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(11) ^= subl(1); subr(11) ^= subr(1);
+    subl(13) ^= subl(1); subr(13) ^= subr(1);
+    subl(15) ^= subl(1); subr(15) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(17);
+    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(19) ^= subl(1); subr(19) ^= subr(1);
+    subl(21) ^= subl(1); subr(21) ^= subr(1);
+    subl(23) ^= subl(1); subr(23) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(25);
+    dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(27) ^= subl(1); subr(27) ^= subr(1);
+    subl(29) ^= subl(1); subr(29) ^= subr(1);
+    subl(31) ^= subl(1); subr(31) ^= subr(1);
+    subl(32) ^= subl(1); subr(32) ^= subr(1);
+
+    /* absorb kw4 to other subkeys */
+    kw4l = subl(33); kw4r = subr(33);
+    subl(30) ^= kw4l; subr(30) ^= kw4r;
+    subl(28) ^= kw4l; subr(28) ^= kw4r;
+    subl(26) ^= kw4l; subr(26) ^= kw4r;
+    kw4l ^= kw4r & ~subr(24);
+    dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw);
+    subl(22) ^= kw4l; subr(22) ^= kw4r;
+    subl(20) ^= kw4l; subr(20) ^= kw4r;
+    subl(18) ^= kw4l; subr(18) ^= kw4r;
+    kw4l ^= kw4r & ~subr(16);
+    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+    subl(14) ^= kw4l; subr(14) ^= kw4r;
+    subl(12) ^= kw4l; subr(12) ^= kw4r;
+    subl(10) ^= kw4l; subr(10) ^= kw4r;
+    kw4l ^= kw4r & ~subr(8);
+    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+    subl(6) ^= kw4l; subr(6) ^= kw4r;
+    subl(4) ^= kw4l; subr(4) ^= kw4r;
+    subl(2) ^= kw4l; subr(2) ^= kw4r;
+    subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+    /* key XOR is end of F-function */
+    CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+    CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+    CamelliaSubkeyL(2) = subl(3);
+    CamelliaSubkeyR(2) = subr(3);
+    CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+    CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+    CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+    CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+    CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+    CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+    CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+    CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+    tl = subl(10) ^ (subr(10) & ~subr(8));
+    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(7) = subl(6) ^ tl;
+    CamelliaSubkeyR(7) = subr(6) ^ tr;
+    CamelliaSubkeyL(8) = subl(8);
+    CamelliaSubkeyR(8) = subr(8);
+    CamelliaSubkeyL(9) = subl(9);
+    CamelliaSubkeyR(9) = subr(9);
+    tl = subl(7) ^ (subr(7) & ~subr(9));
+    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(10) = tl ^ subl(11);
+    CamelliaSubkeyR(10) = tr ^ subr(11);
+    CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+    CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+    CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+    CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+    CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+    CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+    CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+    CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+    tl = subl(18) ^ (subr(18) & ~subr(16));
+    dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(15) = subl(14) ^ tl;
+    CamelliaSubkeyR(15) = subr(14) ^ tr;
+    CamelliaSubkeyL(16) = subl(16);
+    CamelliaSubkeyR(16) = subr(16);
+    CamelliaSubkeyL(17) = subl(17);
+    CamelliaSubkeyR(17) = subr(17);
+    tl = subl(15) ^ (subr(15) & ~subr(17));
+    dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(18) = tl ^ subl(19);
+    CamelliaSubkeyR(18) = tr ^ subr(19);
+    CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+    CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+    CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+    CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+    CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+    CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+    CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+    CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+    tl = subl(26) ^ (subr(26) & ~subr(24));
+    dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(23) = subl(22) ^ tl;
+    CamelliaSubkeyR(23) = subr(22) ^ tr;
+    CamelliaSubkeyL(24) = subl(24);
+    CamelliaSubkeyR(24) = subr(24);
+    CamelliaSubkeyL(25) = subl(25);
+    CamelliaSubkeyR(25) = subr(25);
+    tl = subl(23) ^ (subr(23) &  ~subr(25));
+    dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(26) = tl ^ subl(27);
+    CamelliaSubkeyR(26) = tr ^ subr(27);
+    CamelliaSubkeyL(27) = subl(26) ^ subl(28);
+    CamelliaSubkeyR(27) = subr(26) ^ subr(28);
+    CamelliaSubkeyL(28) = subl(27) ^ subl(29);
+    CamelliaSubkeyR(28) = subr(27) ^ subr(29);
+    CamelliaSubkeyL(29) = subl(28) ^ subl(30);
+    CamelliaSubkeyR(29) = subr(28) ^ subr(30);
+    CamelliaSubkeyL(30) = subl(29) ^ subl(31);
+    CamelliaSubkeyR(30) = subr(29) ^ subr(31);
+    CamelliaSubkeyL(31) = subl(30);
+    CamelliaSubkeyR(31) = subr(30);
+    CamelliaSubkeyL(32) = subl(32) ^ subl(31);
+    CamelliaSubkeyR(32) = subr(32) ^ subr(31);
+
+    /* apply the inverse of the last half of P-function */
+    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+    dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw;
+    dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw;
+    dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw;
+    dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw;
+    dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw;
+    dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw;
+    
+    return;
+}
+
+void camellia_setup192(const unsigned char *key, u32 *subkey)
+{
+    unsigned char kk[32];
+    u32 krll, krlr, krrl,krrr;
+
+    memcpy(kk, key, 24);
+    memcpy((unsigned char *)&krll, key+16,4);
+    memcpy((unsigned char *)&krlr, key+20,4);
+    krrl = ~krll;
+    krrr = ~krlr;
+    memcpy(kk+24, (unsigned char *)&krrl, 4);
+    memcpy(kk+28, (unsigned char *)&krrr, 4);
+    camellia_setup256(kk, subkey);
+    return;
+}
+
+
+/**
+ * Stuff related to camellia encryption/decryption
+ *
+ * "io" must be 4byte aligned and big-endian data.
+ */
+void camellia_encrypt128(const u32 *subkey, u32 *io)
+{
+    u32 il, ir, t0, t1;
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(0);
+    io[1] ^= CamelliaSubkeyR(0);
+    /* main iteration */
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+                    io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(24);
+    io[3] ^= CamelliaSubkeyR(24);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+       
+    return;
+}
+
+void camellia_decrypt128(const u32 *subkey, u32 *io)
+{
+    u32 il,ir,t0,t1;               /* temporary valiables */
+    
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(24);
+    io[1] ^= CamelliaSubkeyR(24);
+
+    /* main iteration */
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+                    io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(0);
+    io[3] ^= CamelliaSubkeyR(0);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+/**
+ * stuff for 192 and 256bit encryption/decryption
+ */
+void camellia_encrypt256(const u32 *subkey, u32 *io)
+{
+    u32 il,ir,t0,t1;           /* temporary valiables */
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(0);
+    io[1] ^= CamelliaSubkeyR(0);
+
+    /* main iteration */
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+                CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+                    io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(32);
+    io[3] ^= CamelliaSubkeyR(32);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+void camellia_decrypt256(const u32 *subkey, u32 *io)
+{
+    u32 il,ir,t0,t1;           /* temporary valiables */
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(32);
+    io[1] ^= CamelliaSubkeyR(32);
+       
+    /* main iteration */
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+                CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+                    io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(0);
+    io[3] ^= CamelliaSubkeyR(0);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+/***
+ *
+ * API for compatibility
+ */
+
+void Camellia_Ekeygen(const int keyBitLength, 
+                     const unsigned char *rawKey, 
+                     KEY_TABLE_TYPE keyTable)
+{
+    switch(keyBitLength) {
+    case 128:
+       camellia_setup128(rawKey, keyTable);
+       break;
+    case 192:
+       camellia_setup192(rawKey, keyTable);
+       break;
+    case 256:
+       camellia_setup256(rawKey, keyTable);
+       break;
+    default:
+       break;
+    }
+}
+
+
+void Camellia_EncryptBlock(const int keyBitLength, 
+                          const unsigned char *plaintext, 
+                          const KEY_TABLE_TYPE keyTable, 
+                          unsigned char *ciphertext)
+{
+    u32 tmp[4];
+
+    tmp[0] = GETU32(plaintext);
+    tmp[1] = GETU32(plaintext + 4);
+    tmp[2] = GETU32(plaintext + 8);
+    tmp[3] = GETU32(plaintext + 12);
+
+    switch (keyBitLength) {
+    case 128:
+       camellia_encrypt128(keyTable, tmp);
+       break;
+    case 192:
+       /* fall through */
+    case 256:
+       camellia_encrypt256(keyTable, tmp);
+       break;
+    default:
+       break;
+    }
+
+    PUTU32(ciphertext, tmp[0]);
+    PUTU32(ciphertext + 4, tmp[1]);
+    PUTU32(ciphertext + 8, tmp[2]);
+    PUTU32(ciphertext + 12, tmp[3]);
+}
+
+void Camellia_DecryptBlock(const int keyBitLength, 
+                          const unsigned char *ciphertext, 
+                          const KEY_TABLE_TYPE keyTable, 
+                          unsigned char *plaintext)
+{
+    u32 tmp[4];
+
+    tmp[0] = GETU32(ciphertext);
+    tmp[1] = GETU32(ciphertext + 4);
+    tmp[2] = GETU32(ciphertext + 8);
+    tmp[3] = GETU32(ciphertext + 12);
+
+    switch (keyBitLength) {
+    case 128:
+       camellia_decrypt128(keyTable, tmp);
+       break;
+    case 192:
+       /* fall through */
+    case 256:
+       camellia_decrypt256(keyTable, tmp);
+       break;
+    default:
+       break;
+    }
+    PUTU32(plaintext, tmp[0]);
+    PUTU32(plaintext + 4, tmp[1]);
+    PUTU32(plaintext + 8, tmp[2]);
+    PUTU32(plaintext + 12, tmp[3]);
+}
diff --git a/grub-core/lib/libgcrypt/cipher/camellia.h b/grub-core/lib/libgcrypt/cipher/camellia.h
new file mode 100644 (file)
index 0000000..4425a3a
--- /dev/null
@@ -0,0 +1,81 @@
+/* camellia.h  ver 1.2.0
+ *
+ * Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef HEADER_CAMELLIA_H
+#define HEADER_CAMELLIA_H
+
+/* To use Camellia with libraries it is often useful to keep the name
+ * space of the library clean.  The following macro is thus useful:
+ *
+ *     #define CAMELLIA_EXT_SYM_PREFIX foo_
+ *  
+ * This prefixes all external symbols with "foo_".
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef CAMELLIA_EXT_SYM_PREFIX
+#define CAMELLIA_PREFIX1(x,y) x ## y
+#define CAMELLIA_PREFIX2(x,y) CAMELLIA_PREFIX1(x,y)
+#define CAMELLIA_PREFIX(x)    CAMELLIA_PREFIX2(CAMELLIA_EXT_SYM_PREFIX,x)
+#define Camellia_Ekeygen      CAMELLIA_PREFIX(Camellia_Ekeygen)
+#define Camellia_EncryptBlock CAMELLIA_PREFIX(Camellia_EncryptBlock)
+#define Camellia_DecryptBlock CAMELLIA_PREFIX(Camellia_DecryptBlock)
+#define camellia_decrypt128   CAMELLIA_PREFIX(camellia_decrypt128)
+#define camellia_decrypt256   CAMELLIA_PREFIX(camellia_decrypt256)
+#define camellia_encrypt128   CAMELLIA_PREFIX(camellia_encrypt128)
+#define camellia_encrypt256   CAMELLIA_PREFIX(camellia_encrypt256)
+#define camellia_setup128     CAMELLIA_PREFIX(camellia_setup128)
+#define camellia_setup192     CAMELLIA_PREFIX(camellia_setup192) 
+#define camellia_setup256     CAMELLIA_PREFIX(camellia_setup256)
+#endif /*CAMELLIA_EXT_SYM_PREFIX*/
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define CAMELLIA_BLOCK_SIZE 16
+#define CAMELLIA_TABLE_BYTE_LEN 272
+#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
+
+typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
+
+
+void Camellia_Ekeygen(const int keyBitLength,
+                     const unsigned char *rawKey, 
+                     KEY_TABLE_TYPE keyTable);
+
+void Camellia_EncryptBlock(const int keyBitLength,
+                          const unsigned char *plaintext, 
+                          const KEY_TABLE_TYPE keyTable, 
+                          unsigned char *cipherText);
+
+void Camellia_DecryptBlock(const int keyBitLength, 
+                          const unsigned char *cipherText, 
+                          const KEY_TABLE_TYPE keyTable, 
+                          unsigned char *plaintext);
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* HEADER_CAMELLIA_H */
diff --git a/grub-core/lib/libgcrypt/cipher/cast5.c b/grub-core/lib/libgcrypt/cipher/cast5.c
new file mode 100644 (file)
index 0000000..333d55e
--- /dev/null
@@ -0,0 +1,620 @@
+/* cast5.c  -  CAST5 cipher (RFC2144)
+ *     Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* Test vectors:
+ *
+ * 128-bit key        = 01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A
+ *        plaintext   = 01 23 45 67 89 AB CD EF
+ *        ciphertext  = 23 8B 4F E5 84 7E 44 B2
+ *
+ * 80-bit  key        = 01 23 45 67 12 34 56 78 23 45
+ *                    = 01 23 45 67 12 34 56 78 23 45 00 00 00 00 00 00
+ *        plaintext   = 01 23 45 67 89 AB CD EF
+ *        ciphertext  = EB 6A 71 1A 2C 02 27 1B
+ *
+ * 40-bit  key        = 01 23 45 67 12
+ *                    = 01 23 45 67 12 00 00 00 00 00 00 00 00 00 00 00
+ *        plaintext   = 01 23 45 67 89 AB CD EF
+ *        ciphertext  = 7A C8 16 D1 6E 9B 30 2E
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "g10lib.h"
+#include "types.h"
+#include "cipher.h"
+
+#define CAST5_BLOCKSIZE 8
+
+typedef struct {
+    u32  Km[16];
+    byte Kr[16];
+} CAST5_context;
+
+static gcry_err_code_t cast_setkey (void *c, const byte *key, unsigned keylen);
+static void encrypt_block (void *c, byte *outbuf, const byte *inbuf);
+static void decrypt_block (void *c, byte *outbuf, const byte *inbuf);
+
+
+
+
+static const u32 s1[256] = {
+0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
+0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
+0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
+0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
+0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
+0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
+0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
+0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
+0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
+0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
+0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
+0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
+0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
+0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
+0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
+0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
+0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
+0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
+0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
+0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
+0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
+0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
+0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
+0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
+0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
+0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
+0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
+0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
+0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
+0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
+0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
+0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
+};
+static const u32 s2[256] = {
+0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
+0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
+0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
+0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
+0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
+0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
+0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
+0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
+0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
+0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
+0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
+0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
+0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
+0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
+0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
+0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
+0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
+0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
+0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
+0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
+0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
+0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
+0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
+0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
+0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
+0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
+0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
+0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
+0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
+0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
+0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
+0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1
+};
+static const u32 s3[256] = {
+0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
+0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
+0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
+0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
+0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
+0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
+0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
+0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
+0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
+0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
+0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
+0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
+0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
+0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
+0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
+0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
+0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
+0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
+0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
+0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
+0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
+0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
+0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
+0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
+0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
+0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
+0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
+0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
+0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
+0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
+0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
+0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783
+};
+static const u32 s4[256] = {
+0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
+0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
+0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
+0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
+0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
+0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
+0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
+0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
+0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
+0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
+0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
+0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
+0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
+0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
+0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
+0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
+0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
+0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
+0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
+0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
+0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
+0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
+0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
+0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
+0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
+0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
+0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
+0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
+0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
+0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
+0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
+0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
+};
+static const u32 s5[256] = {
+0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
+0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
+0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
+0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
+0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
+0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
+0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
+0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
+0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
+0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
+0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
+0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
+0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
+0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
+0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
+0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
+0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
+0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
+0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
+0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
+0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
+0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
+0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
+0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
+0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
+0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
+0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
+0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
+0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
+0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
+0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
+0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4
+};
+static const u32 s6[256] = {
+0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
+0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
+0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
+0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
+0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
+0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
+0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
+0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
+0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
+0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
+0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
+0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
+0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
+0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
+0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
+0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
+0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
+0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
+0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
+0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
+0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
+0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
+0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
+0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
+0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
+0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
+0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
+0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
+0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
+0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
+0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
+0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f
+};
+static const u32 s7[256] = {
+0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
+0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
+0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
+0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
+0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
+0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
+0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
+0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
+0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
+0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
+0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
+0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
+0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
+0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
+0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
+0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
+0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
+0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
+0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
+0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
+0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
+0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
+0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
+0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
+0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
+0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
+0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
+0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
+0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
+0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
+0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
+0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3
+};
+static const u32 s8[256] = {
+0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
+0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
+0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
+0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
+0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
+0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
+0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
+0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
+0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
+0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
+0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
+0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
+0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
+0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
+0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
+0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
+0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
+0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
+0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
+0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
+0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
+0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
+0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
+0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
+0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
+0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
+0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
+0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
+0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
+0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
+0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
+0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e
+};
+
+
+#if defined(__GNUC__) && defined(__i386__)
+static inline u32
+rol(int n, u32 x)
+{
+       __asm__("roll %%cl,%0"
+               :"=r" (x)
+               :"0" (x),"c" (n));
+       return x;
+}
+#else
+#define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
+#endif
+
+#define F1(D,m,r)  (  (I = ((m) + (D))), (I=rol((r),I)),   \
+    (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) )
+#define F2(D,m,r)  (  (I = ((m) ^ (D))), (I=rol((r),I)),   \
+    (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) )
+#define F3(D,m,r)  (  (I = ((m) - (D))), (I=rol((r),I)),   \
+    (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
+
+static void
+do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf )
+{
+    u32 l, r, t;
+    u32 I;   /* used by the Fx macros */
+    u32 *Km;
+    byte *Kr;
+
+    Km = c->Km;
+    Kr = c->Kr;
+
+    /* (L0,R0) <-- (m1...m64). (Split the plaintext into left and
+     * right 32-bit halves L0 = m1...m32 and R0 = m33...m64.)
+     */
+    l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
+    r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
+
+    /* (16 rounds) for i from 1 to 16, compute Li and Ri as follows:
+     * Li = Ri-1;
+     * Ri = Li-1 ^ f(Ri-1,Kmi,Kri), where f is defined in Section 2.2
+     * Rounds 1, 4, 7, 10, 13, and 16 use f function Type 1.
+     * Rounds 2, 5, 8, 11, and 14 use f function Type 2.
+     * Rounds 3, 6, 9, 12, and 15 use f function Type 3.
+     */
+
+    t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
+    t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
+    t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
+    t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
+    t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
+    t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
+    t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
+    t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
+    t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
+    t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
+    t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
+    t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
+    t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
+    t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
+    t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
+    t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
+
+    /* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and
+     * concatenate to form the ciphertext.) */
+    outbuf[0] = (r >> 24) & 0xff;
+    outbuf[1] = (r >> 16) & 0xff;
+    outbuf[2] = (r >>  8) & 0xff;
+    outbuf[3] =  r       & 0xff;
+    outbuf[4] = (l >> 24) & 0xff;
+    outbuf[5] = (l >> 16) & 0xff;
+    outbuf[6] = (l >>  8) & 0xff;
+    outbuf[7] =  l       & 0xff;
+}
+
+static void
+encrypt_block (void *context , byte *outbuf, const byte *inbuf)
+{
+  CAST5_context *c = (CAST5_context *) context;
+  do_encrypt_block (c, outbuf, inbuf);
+  _gcry_burn_stack (20+4*sizeof(void*));
+}
+
+
+static void
+do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf )
+{
+    u32 l, r, t;
+    u32 I;
+    u32 *Km;
+    byte *Kr;
+
+    Km = c->Km;
+    Kr = c->Kr;
+
+    l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
+    r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
+
+    t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
+    t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
+    t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
+    t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
+    t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
+    t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
+    t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
+    t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
+    t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
+    t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
+    t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
+    t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
+    t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
+    t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
+    t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
+    t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
+
+    outbuf[0] = (r >> 24) & 0xff;
+    outbuf[1] = (r >> 16) & 0xff;
+    outbuf[2] = (r >>  8) & 0xff;
+    outbuf[3] =  r       & 0xff;
+    outbuf[4] = (l >> 24) & 0xff;
+    outbuf[5] = (l >> 16) & 0xff;
+    outbuf[6] = (l >>  8) & 0xff;
+    outbuf[7] =  l       & 0xff;
+}
+
+static void
+decrypt_block (void *context, byte *outbuf, const byte *inbuf)
+{
+  CAST5_context *c = (CAST5_context *) context;
+  do_decrypt_block (c, outbuf, inbuf);
+  _gcry_burn_stack (20+4*sizeof(void*));
+}
+
+
+static const char*
+selftest(void)
+{
+    CAST5_context c;
+    byte key[16]  = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
+                     0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A  };
+    byte plain[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
+    byte cipher[8]= { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };
+    byte buffer[8];
+
+    cast_setkey( &c, key, 16 );
+    encrypt_block( &c, buffer, plain );
+    if( memcmp( buffer, cipher, 8 ) )
+       return "1";
+    decrypt_block( &c, buffer, buffer );
+    if( memcmp( buffer, plain, 8 ) )
+       return "2";
+
+#if 0 /* full maintenance test */
+    {
+       int i;
+       byte a0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
+                       0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A };
+       byte b0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
+                       0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A };
+       byte a1[16] = { 0xEE,0xA9,0xD0,0xA2,0x49,0xFD,0x3B,0xA6,
+                       0xB3,0x43,0x6F,0xB8,0x9D,0x6D,0xCA,0x92 };
+       byte b1[16] = { 0xB2,0xC9,0x5E,0xB0,0x0C,0x31,0xAD,0x71,
+                       0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E };
+
+       for(i=0; i < 1000000; i++ ) {
+           cast_setkey( &c, b0, 16 );
+           encrypt_block( &c, a0, a0 );
+           encrypt_block( &c, a0+8, a0+8 );
+           cast_setkey( &c, a0, 16 );
+           encrypt_block( &c, b0, b0 );
+           encrypt_block( &c, b0+8, b0+8 );
+       }
+       if( memcmp( a0, a1, 16 ) || memcmp( b0, b1, 16 ) )
+           return "3";
+
+    }
+#endif
+    return NULL;
+}
+
+
+static void
+key_schedule( u32 *x, u32 *z, u32 *k )
+{
+
+#define xi(i)   ((x[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
+#define zi(i)   ((z[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
+
+    z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)];
+    z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)];
+    z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)];
+    z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)];
+    k[0] = s5[zi( 8)]^s6[zi( 9)]^s7[zi( 7)]^s8[zi( 6)]^s5[zi( 2)];
+    k[1] = s5[zi(10)]^s6[zi(11)]^s7[zi( 5)]^s8[zi( 4)]^s6[zi( 6)];
+    k[2] = s5[zi(12)]^s6[zi(13)]^s7[zi( 3)]^s8[zi( 2)]^s7[zi( 9)];
+    k[3] = s5[zi(14)]^s6[zi(15)]^s7[zi( 1)]^s8[zi( 0)]^s8[zi(12)];
+
+    x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)];
+    x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)];
+    x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)];
+    x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)];
+    k[4] = s5[xi( 3)]^s6[xi( 2)]^s7[xi(12)]^s8[xi(13)]^s5[xi( 8)];
+    k[5] = s5[xi( 1)]^s6[xi( 0)]^s7[xi(14)]^s8[xi(15)]^s6[xi(13)];
+    k[6] = s5[xi( 7)]^s6[xi( 6)]^s7[xi( 8)]^s8[xi( 9)]^s7[xi( 3)];
+    k[7] = s5[xi( 5)]^s6[xi( 4)]^s7[xi(10)]^s8[xi(11)]^s8[xi( 7)];
+
+    z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)];
+    z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)];
+    z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)];
+    z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)];
+    k[8] = s5[zi( 3)]^s6[zi( 2)]^s7[zi(12)]^s8[zi(13)]^s5[zi( 9)];
+    k[9] = s5[zi( 1)]^s6[zi( 0)]^s7[zi(14)]^s8[zi(15)]^s6[zi(12)];
+    k[10]= s5[zi( 7)]^s6[zi( 6)]^s7[zi( 8)]^s8[zi( 9)]^s7[zi( 2)];
+    k[11]= s5[zi( 5)]^s6[zi( 4)]^s7[zi(10)]^s8[zi(11)]^s8[zi( 6)];
+
+    x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)];
+    x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)];
+    x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)];
+    x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)];
+    k[12]= s5[xi( 8)]^s6[xi( 9)]^s7[xi( 7)]^s8[xi( 6)]^s5[xi( 3)];
+    k[13]= s5[xi(10)]^s6[xi(11)]^s7[xi( 5)]^s8[xi( 4)]^s6[xi( 7)];
+    k[14]= s5[xi(12)]^s6[xi(13)]^s7[xi( 3)]^s8[xi( 2)]^s7[xi( 8)];
+    k[15]= s5[xi(14)]^s6[xi(15)]^s7[xi( 1)]^s8[xi( 0)]^s8[xi(13)];
+
+#undef xi
+#undef zi
+}
+
+
+static gcry_err_code_t
+do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen )
+{
+  static int initialized;
+  static const char* selftest_failed;
+  int i;
+  u32 x[4];
+  u32 z[4];
+  u32 k[16];
+
+  if( !initialized ) 
+    {
+      initialized = 1;
+      selftest_failed = selftest();
+      if( selftest_failed )
+        log_error ("CAST5 selftest failed (%s).\n", selftest_failed );
+    }
+  if( selftest_failed )
+    return GPG_ERR_SELFTEST_FAILED;
+
+  if( keylen != 16 )
+    return GPG_ERR_INV_KEYLEN;
+
+  x[0] = key[0]  << 24 | key[1]  << 16 | key[2]  << 8 | key[3];
+  x[1] = key[4]  << 24 | key[5]  << 16 | key[6]  << 8 | key[7];
+  x[2] = key[8]  << 24 | key[9]  << 16 | key[10] << 8 | key[11];
+  x[3] = key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15];
+
+  key_schedule( x, z, k );
+  for(i=0; i < 16; i++ )
+    c->Km[i] = k[i];
+  key_schedule( x, z, k );
+  for(i=0; i < 16; i++ )
+    c->Kr[i] = k[i] & 0x1f;
+
+  memset(&x,0, sizeof x);
+  memset(&z,0, sizeof z);
+  memset(&k,0, sizeof k);
+
+#undef xi
+#undef zi
+  return GPG_ERR_NO_ERROR;
+}
+
+static gcry_err_code_t
+cast_setkey (void *context, const byte *key, unsigned keylen )
+{
+  CAST5_context *c = (CAST5_context *) context;
+  gcry_err_code_t rc = do_cast_setkey (c, key, keylen);
+  _gcry_burn_stack (96+7*sizeof(void*));
+  return rc;
+}
+
+
+gcry_cipher_spec_t _gcry_cipher_spec_cast5 =
+  {
+    "CAST5", NULL, NULL, CAST5_BLOCKSIZE, 128, sizeof (CAST5_context),
+    cast_setkey, encrypt_block, decrypt_block
+  };
diff --git a/grub-core/lib/libgcrypt/cipher/cipher.c b/grub-core/lib/libgcrypt/cipher/cipher.c
new file mode 100644 (file)
index 0000000..2c33ee9
--- /dev/null
@@ -0,0 +1,1932 @@
+/* cipher.c  - cipher dispatcher
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ *               2005, 2007, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "ath.h"
+
+#define MAX_BLOCKSIZE 16
+#define TABLE_SIZE 14
+#define CTX_MAGIC_NORMAL 0x24091964
+#define CTX_MAGIC_SECURE 0x46919042
+
+#undef NEED_16BYTE_ALIGNED_CONTEXT
+#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
+#define NEED_16BYTE_ALIGNED_CONTEXT 1
+#endif
+
+/* A dummy extraspec so that we do not need to tests the extraspec
+   field from the module specification against NULL and instead
+   directly test the respective fields of extraspecs.  */
+static cipher_extra_spec_t dummy_extra_spec;
+
+/* This is the list of the default ciphers, which are included in
+   libgcrypt.  */
+static struct cipher_table_entry
+{
+  gcry_cipher_spec_t *cipher;
+  cipher_extra_spec_t *extraspec;
+  unsigned int algorithm;
+  int fips_allowed;
+} cipher_table[] =
+  {
+#if USE_BLOWFISH
+    { &_gcry_cipher_spec_blowfish,
+      &dummy_extra_spec,                  GCRY_CIPHER_BLOWFISH },
+#endif
+#if USE_DES
+    { &_gcry_cipher_spec_des,       
+      &dummy_extra_spec,                  GCRY_CIPHER_DES },
+    { &_gcry_cipher_spec_tripledes,
+      &_gcry_cipher_extraspec_tripledes,  GCRY_CIPHER_3DES, 1 },
+#endif
+#if USE_ARCFOUR
+    { &_gcry_cipher_spec_arcfour,    
+      &dummy_extra_spec,                  GCRY_CIPHER_ARCFOUR },
+#endif
+#if USE_CAST5
+    { &_gcry_cipher_spec_cast5,      
+      &dummy_extra_spec,                  GCRY_CIPHER_CAST5 },
+#endif
+#if USE_AES
+    { &_gcry_cipher_spec_aes,        
+      &_gcry_cipher_extraspec_aes,        GCRY_CIPHER_AES,    1 },
+    { &_gcry_cipher_spec_aes192,     
+      &_gcry_cipher_extraspec_aes192,     GCRY_CIPHER_AES192, 1 },
+    { &_gcry_cipher_spec_aes256,     
+      &_gcry_cipher_extraspec_aes256,     GCRY_CIPHER_AES256, 1 },
+#endif
+#if USE_TWOFISH
+    { &_gcry_cipher_spec_twofish,
+      &dummy_extra_spec,                  GCRY_CIPHER_TWOFISH },
+    { &_gcry_cipher_spec_twofish128,     
+      &dummy_extra_spec,                  GCRY_CIPHER_TWOFISH128 },
+#endif
+#if USE_SERPENT
+    { &_gcry_cipher_spec_serpent128, 
+      &dummy_extra_spec,                  GCRY_CIPHER_SERPENT128 },
+    { &_gcry_cipher_spec_serpent192,
+      &dummy_extra_spec,                  GCRY_CIPHER_SERPENT192 },
+    { &_gcry_cipher_spec_serpent256, 
+      &dummy_extra_spec,                  GCRY_CIPHER_SERPENT256 },
+#endif
+#if USE_RFC2268
+    { &_gcry_cipher_spec_rfc2268_40,
+      &dummy_extra_spec,                  GCRY_CIPHER_RFC2268_40 },
+#endif
+#if USE_SEED
+    { &_gcry_cipher_spec_seed, 
+      &dummy_extra_spec,                  GCRY_CIPHER_SEED },
+#endif
+#if USE_CAMELLIA
+    { &_gcry_cipher_spec_camellia128,
+      &dummy_extra_spec,                  GCRY_CIPHER_CAMELLIA128 },
+    { &_gcry_cipher_spec_camellia192, 
+      &dummy_extra_spec,                  GCRY_CIPHER_CAMELLIA192 },
+    { &_gcry_cipher_spec_camellia256,
+      &dummy_extra_spec,                  GCRY_CIPHER_CAMELLIA256 },
+#endif
+    { NULL                    }
+  };
+
+/* List of registered ciphers.  */
+static gcry_module_t ciphers_registered;
+
+/* This is the lock protecting CIPHERS_REGISTERED.  */
+static ath_mutex_t ciphers_registered_lock = ATH_MUTEX_INITIALIZER;
+
+/* Flag to check wether the default ciphers have already been
+   registered.  */
+static int default_ciphers_registered;
+
+/* Convenient macro for registering the default ciphers.  */
+#define REGISTER_DEFAULT_CIPHERS                   \
+  do                                               \
+    {                                              \
+      ath_mutex_lock (&ciphers_registered_lock);   \
+      if (! default_ciphers_registered)            \
+        {                                          \
+          cipher_register_default ();              \
+          default_ciphers_registered = 1;          \
+        }                                          \
+      ath_mutex_unlock (&ciphers_registered_lock); \
+    }                                              \
+  while (0)
+
+
+/* A VIA processor with the Padlock engine requires an alignment of
+   most data on a 16 byte boundary.  Because we trick out the compiler
+   while allocating the context, the align attribute as used in
+   rijndael.c does not work on its own.  Thus we need to make sure
+   that the entire context structure is a aligned on that boundary.
+   We achieve this by defining a new type and use that instead of our
+   usual alignment type.  */
+typedef union 
+{
+  PROPERLY_ALIGNED_TYPE foo;
+#ifdef NEED_16BYTE_ALIGNED_CONTEXT
+  char bar[16] __attribute__ ((aligned (16)));
+#endif  
+  char c[1];
+} cipher_context_alignment_t;
+
+
+/* The handle structure.  */
+struct gcry_cipher_handle
+{
+  int magic;
+  size_t actual_handle_size;     /* Allocated size of this handle. */
+  size_t handle_offset;          /* Offset to the malloced block.  */
+  gcry_cipher_spec_t *cipher;
+  cipher_extra_spec_t *extraspec;
+  gcry_module_t module;
+
+  /* The algorithm id.  This is a hack required because the module
+     interface does not easily allow to retrieve this value. */
+  int algo;  
+
+  /* A structure with function pointers for bulk operations.  Due to
+     limitations of the module system (we don't want to change the
+     API) we need to keep these function pointers here.  The cipher
+     open function intializes them and the actual encryption routines
+     use them if they are not NULL.  */
+  struct {
+    void (*cfb_enc)(void *context, unsigned char *iv, 
+                    void *outbuf_arg, const void *inbuf_arg,
+                    unsigned int nblocks);
+    void (*cfb_dec)(void *context, unsigned char *iv, 
+                    void *outbuf_arg, const void *inbuf_arg,
+                    unsigned int nblocks);
+    void (*cbc_enc)(void *context, unsigned char *iv, 
+                    void *outbuf_arg, const void *inbuf_arg,
+                    unsigned int nblocks, int cbc_mac);
+    void (*cbc_dec)(void *context, unsigned char *iv, 
+                    void *outbuf_arg, const void *inbuf_arg,
+                    unsigned int nblocks);
+  } bulk;
+
+
+  int mode;
+  unsigned int flags;
+
+  /* The initialization vector.  To help code optimization we make
+     sure that it is aligned on an unsigned long and u32 boundary.  */
+  union {
+    unsigned long dummy_iv;         
+    u32 dummy_u32_iv;
+    unsigned char iv[MAX_BLOCKSIZE];   
+  } u_iv;
+
+  unsigned char lastiv[MAX_BLOCKSIZE];
+  int unused;  /* Number of unused bytes in the IV. */
+
+  unsigned char ctr[MAX_BLOCKSIZE];     /* For Counter (CTR) mode. */
+
+
+  /* What follows are two contexts of the cipher in use.  The first
+     one needs to be aligned well enough for the cipher operation
+     whereas the second one is a copy created by cipher_setkey and
+     used by cipher_reset.  That second copy has no need for proper
+     aligment because it is only accessed by memcpy.  */
+  cipher_context_alignment_t context;
+};
+
+
+\f
+/* These dummy functions are used in case a cipher implementation
+   refuses to provide it's own functions.  */
+
+static gcry_err_code_t
+dummy_setkey (void *c, const unsigned char *key, unsigned int keylen)
+{
+  (void)c; 
+  (void)key;
+  (void)keylen;
+  return GPG_ERR_NO_ERROR;
+}
+
+static void
+dummy_encrypt_block (void *c,
+                    unsigned char *outbuf, const unsigned char *inbuf)
+{
+  (void)c;
+  (void)outbuf;
+  (void)inbuf;
+  BUG();
+}
+
+static void
+dummy_decrypt_block (void *c,
+                    unsigned char *outbuf, const unsigned char *inbuf)
+{
+  (void)c;
+  (void)outbuf;
+  (void)inbuf;
+  BUG();
+}
+
+static void
+dummy_encrypt_stream (void *c,
+                     unsigned char *outbuf, const unsigned char *inbuf,
+                     unsigned int n)
+{
+  (void)c;
+  (void)outbuf;
+  (void)inbuf;
+  (void)n;
+  BUG();
+}
+
+static void
+dummy_decrypt_stream (void *c,
+                     unsigned char *outbuf, const unsigned char *inbuf,
+                     unsigned int n)
+{
+  (void)c;
+  (void)outbuf;
+  (void)inbuf;
+  (void)n;
+  BUG();
+}
+
+\f
+/* Internal function.  Register all the ciphers included in
+   CIPHER_TABLE.  Note, that this function gets only used by the macro
+   REGISTER_DEFAULT_CIPHERS which protects it using a mutex. */
+static void
+cipher_register_default (void)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  int i;
+  
+  for (i = 0; !err && cipher_table[i].cipher; i++)
+    {
+      if (! cipher_table[i].cipher->setkey)
+       cipher_table[i].cipher->setkey = dummy_setkey;
+      if (! cipher_table[i].cipher->encrypt)
+       cipher_table[i].cipher->encrypt = dummy_encrypt_block;
+      if (! cipher_table[i].cipher->decrypt)
+       cipher_table[i].cipher->decrypt = dummy_decrypt_block;
+      if (! cipher_table[i].cipher->stencrypt)
+       cipher_table[i].cipher->stencrypt = dummy_encrypt_stream;
+      if (! cipher_table[i].cipher->stdecrypt)
+       cipher_table[i].cipher->stdecrypt = dummy_decrypt_stream;
+
+      if ( fips_mode () && !cipher_table[i].fips_allowed )
+        continue;
+
+      err = _gcry_module_add (&ciphers_registered,
+                             cipher_table[i].algorithm,
+                             (void *) cipher_table[i].cipher,
+                             (void *) cipher_table[i].extraspec,
+                             NULL);
+    }
+
+  if (err)
+    BUG ();
+}
+
+/* Internal callback function.  Used via _gcry_module_lookup.  */
+static int
+gcry_cipher_lookup_func_name (void *spec, void *data)
+{
+  gcry_cipher_spec_t *cipher = (gcry_cipher_spec_t *) spec;
+  char *name = (char *) data;
+  const char **aliases = cipher->aliases;
+  int i, ret = ! stricmp (name, cipher->name);
+
+  if (aliases)
+    for (i = 0; aliases[i] && (! ret); i++)
+      ret = ! stricmp (name, aliases[i]);
+
+  return ret;
+}
+
+/* Internal callback function.  Used via _gcry_module_lookup.  */
+static int
+gcry_cipher_lookup_func_oid (void *spec, void *data)
+{
+  gcry_cipher_spec_t *cipher = (gcry_cipher_spec_t *) spec;
+  char *oid = (char *) data;
+  gcry_cipher_oid_spec_t *oid_specs = cipher->oids;
+  int ret = 0, i;
+
+  if (oid_specs)
+    for (i = 0; oid_specs[i].oid && (! ret); i++)
+      if (! stricmp (oid, oid_specs[i].oid))
+       ret = 1;
+
+  return ret;
+}
+
+/* Internal function.  Lookup a cipher entry by it's name.  */
+static gcry_module_t
+gcry_cipher_lookup_name (const char *name)
+{
+  gcry_module_t cipher;
+
+  cipher = _gcry_module_lookup (ciphers_registered, (void *) name,
+                               gcry_cipher_lookup_func_name);
+
+  return cipher;
+}
+
+/* Internal function.  Lookup a cipher entry by it's oid.  */
+static gcry_module_t
+gcry_cipher_lookup_oid (const char *oid)
+{
+  gcry_module_t cipher;
+
+  cipher = _gcry_module_lookup (ciphers_registered, (void *) oid,
+                               gcry_cipher_lookup_func_oid);
+
+  return cipher;
+}
+
+/* Register a new cipher module whose specification can be found in
+   CIPHER.  On success, a new algorithm ID is stored in ALGORITHM_ID
+   and a pointer representhing this module is stored in MODULE.  */
+gcry_error_t
+_gcry_cipher_register (gcry_cipher_spec_t *cipher,
+                       cipher_extra_spec_t *extraspec,
+                       int *algorithm_id,
+                       gcry_module_t *module)
+{
+  gcry_err_code_t err = 0;
+  gcry_module_t mod;
+
+  /* We do not support module loading in fips mode.  */
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  ath_mutex_lock (&ciphers_registered_lock);
+  err = _gcry_module_add (&ciphers_registered, 0,
+                         (void *)cipher, 
+                         (void *)(extraspec? extraspec : &dummy_extra_spec), 
+                          &mod);
+  ath_mutex_unlock (&ciphers_registered_lock);
+
+  if (! err)
+    {
+      *module = mod;
+      *algorithm_id = mod->mod_id;
+    }
+
+  return gcry_error (err);
+}
+
+/* Unregister the cipher identified by MODULE, which must have been
+   registered with gcry_cipher_register.  */
+void
+gcry_cipher_unregister (gcry_module_t module)
+{
+  ath_mutex_lock (&ciphers_registered_lock);
+  _gcry_module_release (module);
+  ath_mutex_unlock (&ciphers_registered_lock);
+}
+
+/* Locate the OID in the oid table and return the index or -1 when not
+   found.  An opitonal "oid." or "OID." prefix in OID is ignored, the
+   OID is expected to be in standard IETF dotted notation.  The
+   internal algorithm number is returned in ALGORITHM unless it
+   ispassed as NULL.  A pointer to the specification of the module
+   implementing this algorithm is return in OID_SPEC unless passed as
+   NULL.*/
+static int 
+search_oid (const char *oid, int *algorithm, gcry_cipher_oid_spec_t *oid_spec)
+{
+  gcry_module_t module;
+  int ret = 0;
+
+  if (oid && ((! strncmp (oid, "oid.", 4))
+             || (! strncmp (oid, "OID.", 4))))
+    oid += 4;
+
+  module = gcry_cipher_lookup_oid (oid);
+  if (module)
+    {
+      gcry_cipher_spec_t *cipher = module->spec;
+      int i;
+
+      for (i = 0; cipher->oids[i].oid && !ret; i++)
+       if (! stricmp (oid, cipher->oids[i].oid))
+         {
+           if (algorithm)
+             *algorithm = module->mod_id;
+           if (oid_spec)
+             *oid_spec = cipher->oids[i];
+           ret = 1;
+         }
+      _gcry_module_release (module);
+    }
+
+  return ret;
+}
+
+/* Map STRING to the cipher algorithm identifier.  Returns the
+   algorithm ID of the cipher for the given name or 0 if the name is
+   not known.  It is valid to pass NULL for STRING which results in a
+   return value of 0. */
+int
+gcry_cipher_map_name (const char *string)
+{
+  gcry_module_t cipher;
+  int ret, algorithm = 0;
+
+  if (! string)
+    return 0;
+
+  REGISTER_DEFAULT_CIPHERS;
+
+  /* If the string starts with a digit (optionally prefixed with
+     either "OID." or "oid."), we first look into our table of ASN.1
+     object identifiers to figure out the algorithm */
+
+  ath_mutex_lock (&ciphers_registered_lock);
+
+  ret = search_oid (string, &algorithm, NULL);
+  if (! ret)
+    {
+      cipher = gcry_cipher_lookup_name (string);
+      if (cipher)
+       {
+         algorithm = cipher->mod_id;
+         _gcry_module_release (cipher);
+       }
+    }
+
+  ath_mutex_unlock (&ciphers_registered_lock);
+  
+  return algorithm;
+}
+
+
+/* Given a STRING with an OID in dotted decimal notation, this
+   function returns the cipher mode (GCRY_CIPHER_MODE_*) associated
+   with that OID or 0 if no mode is known.  Passing NULL for string
+   yields a return value of 0. */
+int
+gcry_cipher_mode_from_oid (const char *string)
+{
+  gcry_cipher_oid_spec_t oid_spec;
+  int ret = 0, mode = 0;
+
+  if (!string)
+    return 0;
+
+  ath_mutex_lock (&ciphers_registered_lock);
+  ret = search_oid (string, NULL, &oid_spec);
+  if (ret)
+    mode = oid_spec.mode;
+  ath_mutex_unlock (&ciphers_registered_lock);
+
+  return mode;
+}
+
+
+/* Map the cipher algorithm whose ID is contained in ALGORITHM to a
+   string representation of the algorithm name.  For unknown algorithm
+   IDs this function returns "?".  */
+static const char *
+cipher_algo_to_string (int algorithm)
+{
+  gcry_module_t cipher;
+  const char *name;
+
+  REGISTER_DEFAULT_CIPHERS;
+
+  ath_mutex_lock (&ciphers_registered_lock);
+  cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
+  if (cipher)
+    {
+      name = ((gcry_cipher_spec_t *) cipher->spec)->name;
+      _gcry_module_release (cipher);
+    }
+  else
+    name = "?";
+  ath_mutex_unlock (&ciphers_registered_lock);
+
+  return name;
+}
+
+/* Map the cipher algorithm identifier ALGORITHM to a string
+   representing this algorithm.  This string is the default name as
+   used by Libgcrypt.  An pointer to an empty string is returned for
+   an unknown algorithm.  NULL is never returned. */
+const char *
+gcry_cipher_algo_name (int algorithm)
+{
+  return cipher_algo_to_string (algorithm);
+}
+
+
+/* Flag the cipher algorithm with the identifier ALGORITHM as
+   disabled.  There is no error return, the function does nothing for
+   unknown algorithms.  Disabled algorithms are vitually not available
+   in Libgcrypt. */
+static void
+disable_cipher_algo (int algorithm)
+{
+  gcry_module_t cipher;
+
+  REGISTER_DEFAULT_CIPHERS;
+
+  ath_mutex_lock (&ciphers_registered_lock);
+  cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
+  if (cipher)
+    {
+      if (! (cipher->flags & FLAG_MODULE_DISABLED))
+       cipher->flags |= FLAG_MODULE_DISABLED;
+      _gcry_module_release (cipher);
+    }
+  ath_mutex_unlock (&ciphers_registered_lock);
+}
+
+
+/* Return 0 if the cipher algorithm with identifier ALGORITHM is
+   available. Returns a basic error code value if it is not
+   available.  */
+static gcry_err_code_t
+check_cipher_algo (int algorithm)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_module_t cipher;
+
+  REGISTER_DEFAULT_CIPHERS;
+
+  ath_mutex_lock (&ciphers_registered_lock);
+  cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
+  if (cipher)
+    {
+      if (cipher->flags & FLAG_MODULE_DISABLED)
+       err = GPG_ERR_CIPHER_ALGO;
+      _gcry_module_release (cipher);
+    }
+  else
+    err = GPG_ERR_CIPHER_ALGO;
+  ath_mutex_unlock (&ciphers_registered_lock);
+  
+  return err;
+}
+
+
+/* Return the standard length of the key for the cipher algorithm with
+   the identifier ALGORITHM.  This function expects a valid algorithm
+   and will abort if the algorithm is not available or the length of
+   the key is not known. */
+static unsigned int
+cipher_get_keylen (int algorithm)
+{
+  gcry_module_t cipher;
+  unsigned len = 0;
+
+  REGISTER_DEFAULT_CIPHERS;
+
+  ath_mutex_lock (&ciphers_registered_lock);
+  cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
+  if (cipher)
+    {
+      len = ((gcry_cipher_spec_t *) cipher->spec)->keylen;
+      if (!len)
+       log_bug ("cipher %d w/o key length\n", algorithm);
+      _gcry_module_release (cipher);
+    }
+  else
+    log_bug ("cipher %d not found\n", algorithm);
+  ath_mutex_unlock (&ciphers_registered_lock);
+
+  return len;
+}
+
+/* Return the block length of the cipher algorithm with the identifier
+   ALGORITHM.  This function expects a valid algorithm and will abort
+   if the algorithm is not available or the length of the key is not
+   known. */
+static unsigned int
+cipher_get_blocksize (int algorithm)
+{
+  gcry_module_t cipher;
+  unsigned len = 0;
+
+  REGISTER_DEFAULT_CIPHERS;
+
+  ath_mutex_lock (&ciphers_registered_lock);
+  cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
+  if (cipher)
+    {
+      len = ((gcry_cipher_spec_t *) cipher->spec)->blocksize;
+      if (! len)
+         log_bug ("cipher %d w/o blocksize\n", algorithm);
+      _gcry_module_release (cipher);
+    }
+  else
+    log_bug ("cipher %d not found\n", algorithm);
+  ath_mutex_unlock (&ciphers_registered_lock);
+
+  return len;
+}
+
+
+/*
+   Open a cipher handle for use with cipher algorithm ALGORITHM, using
+   the cipher mode MODE (one of the GCRY_CIPHER_MODE_*) and return a
+   handle in HANDLE.  Put NULL into HANDLE and return an error code if
+   something goes wrong.  FLAGS may be used to modify the
+   operation.  The defined flags are:
+
+   GCRY_CIPHER_SECURE:  allocate all internal buffers in secure memory.
+   GCRY_CIPHER_ENABLE_SYNC:  Enable the sync operation as used in OpenPGP.
+   GCRY_CIPHER_CBC_CTS:  Enable CTS mode.
+   GCRY_CIPHER_CBC_MAC:  Enable MAC mode.
+
+   Values for these flags may be combined using OR.
+ */
+gcry_error_t
+gcry_cipher_open (gcry_cipher_hd_t *handle,
+                 int algo, int mode, unsigned int flags)
+{
+  int secure = (flags & GCRY_CIPHER_SECURE);
+  gcry_cipher_spec_t *cipher = NULL;
+  cipher_extra_spec_t *extraspec = NULL;
+  gcry_module_t module = NULL;
+  gcry_cipher_hd_t h = NULL;
+  gcry_err_code_t err = 0;
+
+  /* If the application missed to call the random poll function, we do
+     it here to ensure that it is used once in a while. */
+  _gcry_fast_random_poll ();
+  
+  REGISTER_DEFAULT_CIPHERS;
+
+  /* Fetch the according module and check wether the cipher is marked
+     available for use.  */
+  ath_mutex_lock (&ciphers_registered_lock);
+  module = _gcry_module_lookup_id (ciphers_registered, algo);
+  if (module)
+    {
+      /* Found module.  */
+
+      if (module->flags & FLAG_MODULE_DISABLED)
+       {
+         /* Not available for use.  */
+         err = GPG_ERR_CIPHER_ALGO;
+         _gcry_module_release (module);
+       }
+      else
+        {
+          cipher = (gcry_cipher_spec_t *) module->spec;
+          extraspec = module->extraspec;
+        }
+    }
+  else
+    err = GPG_ERR_CIPHER_ALGO;
+  ath_mutex_unlock (&ciphers_registered_lock);
+
+  /* check flags */
+  if ((! err)
+      && ((flags & ~(0 
+                    | GCRY_CIPHER_SECURE
+                    | GCRY_CIPHER_ENABLE_SYNC
+                    | GCRY_CIPHER_CBC_CTS
+                    | GCRY_CIPHER_CBC_MAC))
+         || (flags & GCRY_CIPHER_CBC_CTS & GCRY_CIPHER_CBC_MAC)))
+    err = GPG_ERR_CIPHER_ALGO;
+
+  /* check that a valid mode has been requested */
+  if (! err)
+    switch (mode)
+      {
+      case GCRY_CIPHER_MODE_ECB:
+      case GCRY_CIPHER_MODE_CBC:
+      case GCRY_CIPHER_MODE_CFB:
+      case GCRY_CIPHER_MODE_OFB:
+      case GCRY_CIPHER_MODE_CTR:
+       if ((cipher->encrypt == dummy_encrypt_block)
+           || (cipher->decrypt == dummy_decrypt_block))
+         err = GPG_ERR_INV_CIPHER_MODE;
+       break;
+
+      case GCRY_CIPHER_MODE_STREAM:
+       if ((cipher->stencrypt == dummy_encrypt_stream)
+           || (cipher->stdecrypt == dummy_decrypt_stream))
+         err = GPG_ERR_INV_CIPHER_MODE;
+       break;
+
+      case GCRY_CIPHER_MODE_NONE:
+        /* This mode may be used for debugging.  It copies the main
+           text verbatim to the ciphertext.  We do not allow this in
+           fips mode or if no debug flag has been set.  */
+       if (fips_mode () || !_gcry_get_debug_flag (0))
+          err = GPG_ERR_INV_CIPHER_MODE;
+       break;
+
+      default:
+       err = GPG_ERR_INV_CIPHER_MODE;
+      }
+
+  /* Perform selftest here and mark this with a flag in cipher_table?
+     No, we should not do this as it takes too long.  Further it does
+     not make sense to exclude algorithms with failing selftests at
+     runtime: If a selftest fails there is something seriously wrong
+     with the system and thus we better die immediately. */
+
+  if (! err)
+    {
+      size_t size = (sizeof (*h)
+                     + 2 * cipher->contextsize
+                     - sizeof (cipher_context_alignment_t)
+#ifdef NEED_16BYTE_ALIGNED_CONTEXT
+                     + 15  /* Space for leading alignment gap.  */
+#endif /*NEED_16BYTE_ALIGNED_CONTEXT*/
+                     );
+
+      if (secure)
+       h = gcry_calloc_secure (1, size);
+      else
+       h = gcry_calloc (1, size);
+
+      if (! h)
+       err = gpg_err_code_from_errno (errno);
+      else
+       {
+          size_t off = 0;
+
+#ifdef NEED_16BYTE_ALIGNED_CONTEXT
+          if ( ((unsigned long)h & 0x0f) )
+            {
+              /* The malloced block is not aligned on a 16 byte
+                 boundary.  Correct for this.  */
+              off = 16 - ((unsigned long)h & 0x0f);
+              h = (void*)((char*)h + off);
+            }
+#endif /*NEED_16BYTE_ALIGNED_CONTEXT*/
+
+         h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
+          h->actual_handle_size = size - off;
+          h->handle_offset = off;
+         h->cipher = cipher;
+         h->extraspec = extraspec;
+         h->module = module;
+          h->algo = algo;
+         h->mode = mode;
+         h->flags = flags;
+
+          /* Setup bulk encryption routines.  */
+          switch (algo)
+            {
+#ifdef USE_AES
+            case GCRY_CIPHER_AES128:
+            case GCRY_CIPHER_AES192:
+            case GCRY_CIPHER_AES256:
+              h->bulk.cfb_enc = _gcry_aes_cfb_enc;
+              h->bulk.cfb_dec = _gcry_aes_cfb_dec;
+              h->bulk.cbc_enc = _gcry_aes_cbc_enc;
+              h->bulk.cbc_dec = _gcry_aes_cbc_dec;
+              break;
+#endif /*USE_AES*/
+              
+            default:
+              break;
+            }
+       }
+    }
+
+  /* Done.  */
+
+  if (err)
+    {
+      if (module)
+       {
+         /* Release module.  */
+         ath_mutex_lock (&ciphers_registered_lock);
+         _gcry_module_release (module);
+         ath_mutex_unlock (&ciphers_registered_lock);
+       }
+    }
+
+  *handle = err ? NULL : h;
+
+  return gcry_error (err);
+}
+
+
+/* Release all resources associated with the cipher handle H. H may be
+   NULL in which case this is a no-operation. */
+void
+gcry_cipher_close (gcry_cipher_hd_t h)
+{
+  size_t off;
+
+  if (!h)
+    return;
+
+  if ((h->magic != CTX_MAGIC_SECURE)
+      && (h->magic != CTX_MAGIC_NORMAL))
+    _gcry_fatal_error(GPG_ERR_INTERNAL,
+                     "gcry_cipher_close: already closed/invalid handle");
+  else
+    h->magic = 0;
+
+  /* Release module.  */
+  ath_mutex_lock (&ciphers_registered_lock);
+  _gcry_module_release (h->module);
+  ath_mutex_unlock (&ciphers_registered_lock);
+
+  /* We always want to wipe out the memory even when the context has
+     been allocated in secure memory.  The user might have disabled
+     secure memory or is using his own implementation which does not
+     do the wiping.  To accomplish this we need to keep track of the
+     actual size of this structure because we have no way to known
+     how large the allocated area was when using a standard malloc. */
+  off = h->handle_offset;
+  wipememory (h, h->actual_handle_size);
+
+  gcry_free ((char*)h - off);
+}
+
+
+/* Set the key to be used for the encryption context C to KEY with
+   length KEYLEN.  The length should match the required length. */
+static gcry_error_t
+cipher_setkey (gcry_cipher_hd_t c, byte *key, unsigned int keylen)
+{
+  gcry_err_code_t ret;
+
+  ret = (*c->cipher->setkey) (&c->context.c, key, keylen);
+  if (!ret)
+    {
+      /* Duplicate initial context.  */
+      memcpy ((void *) ((char *) &c->context.c + c->cipher->contextsize),
+              (void *) &c->context.c,
+              c->cipher->contextsize);
+    }
+
+  return gcry_error (ret);
+}
+
+
+/* Set the IV to be used for the encryption context C to IV with
+   length IVLEN.  The length should match the required length. */
+static void
+cipher_setiv( gcry_cipher_hd_t c, const byte *iv, unsigned ivlen )
+{
+  memset (c->u_iv.iv, 0, c->cipher->blocksize);
+  if (iv) 
+    {
+      if (ivlen != c->cipher->blocksize)
+        {
+          log_info ("WARNING: cipher_setiv: ivlen=%u blklen=%u\n",
+                    ivlen, (unsigned int)c->cipher->blocksize);
+          fips_signal_error ("IV length does not match blocklength");
+        }
+      if (ivlen > c->cipher->blocksize)
+        ivlen = c->cipher->blocksize;
+      memcpy (c->u_iv.iv, iv, ivlen);
+    }
+  c->unused = 0;
+}
+
+
+/* Reset the cipher context to the initial context.  This is basically
+   the same as an release followed by a new. */
+static void
+cipher_reset (gcry_cipher_hd_t c)
+{
+  memcpy (&c->context.c,
+         (char *) &c->context.c + c->cipher->contextsize,
+         c->cipher->contextsize);
+  memset (c->u_iv.iv, 0, c->cipher->blocksize);
+  memset (c->lastiv, 0, c->cipher->blocksize);
+  memset (c->ctr, 0, c->cipher->blocksize);
+}
+
+
+static void
+do_ecb_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+                unsigned int nblocks )
+{
+  unsigned int n;
+  
+  for (n=0; n < nblocks; n++ )
+    {
+      c->cipher->encrypt ( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
+      inbuf  += c->cipher->blocksize;
+      outbuf += c->cipher->blocksize;
+    }
+}
+
+static void
+do_ecb_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+                unsigned int nblocks )
+{
+  unsigned int n;
+
+  for (n=0; n < nblocks; n++ ) 
+    {
+      c->cipher->decrypt ( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
+      inbuf  += c->cipher->blocksize;
+      outbuf += c->cipher->blocksize;
+    }
+}
+
+
+static void
+do_cbc_encrypt (gcry_cipher_hd_t c, unsigned char *outbuf, 
+                const unsigned char *inbuf, unsigned int nbytes )
+{
+  unsigned int n;
+  unsigned char *ivp;
+  int i;
+  size_t blocksize = c->cipher->blocksize;
+  unsigned nblocks = nbytes / blocksize;
+
+  if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) 
+    {
+      if ((nbytes % blocksize) == 0)
+       nblocks--;
+    }
+
+  if (c->bulk.cbc_enc)
+    {
+      c->bulk.cbc_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks,
+                       (c->flags & GCRY_CIPHER_CBC_MAC)); 
+      inbuf  += nblocks * blocksize;
+      if (!(c->flags & GCRY_CIPHER_CBC_MAC))
+        outbuf += nblocks * blocksize;
+    }
+  else
+    {
+      for (n=0; n < nblocks; n++ )
+        {
+          for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+            outbuf[i] = inbuf[i] ^ *ivp++;
+          c->cipher->encrypt ( &c->context.c, outbuf, outbuf );
+          memcpy (c->u_iv.iv, outbuf, blocksize );
+          inbuf  += blocksize;
+          if (!(c->flags & GCRY_CIPHER_CBC_MAC))
+            outbuf += blocksize;
+        }
+    }
+
+  if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize)
+    {
+      /* We have to be careful here, since outbuf might be equal to
+         inbuf.  */
+      int restbytes;
+      unsigned char b;
+
+      if ((nbytes % blocksize) == 0)
+        restbytes = blocksize;
+      else
+        restbytes = nbytes % blocksize;
+
+      outbuf -= blocksize;
+      for (ivp = c->u_iv.iv, i = 0; i < restbytes; i++)
+        {
+          b = inbuf[i];
+          outbuf[blocksize + i] = outbuf[i];
+          outbuf[i] = b ^ *ivp++;
+        }
+      for (; i < blocksize; i++)
+        outbuf[i] = 0 ^ *ivp++;
+      
+      c->cipher->encrypt (&c->context.c, outbuf, outbuf);
+      memcpy (c->u_iv.iv, outbuf, blocksize);
+    }
+}
+
+
+static void
+do_cbc_decrypt (gcry_cipher_hd_t c, unsigned char *outbuf, 
+                const unsigned char *inbuf, unsigned int nbytes)
+{
+  unsigned int n;
+  unsigned char *ivp;
+  int i;
+  size_t blocksize = c->cipher->blocksize;
+  unsigned int nblocks = nbytes / blocksize;
+
+  if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize)
+    {
+      nblocks--;
+      if ((nbytes % blocksize) == 0)
+       nblocks--;
+      memcpy (c->lastiv, c->u_iv.iv, blocksize);
+    }
+
+  if (c->bulk.cbc_dec)
+    {
+      c->bulk.cbc_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks); 
+      inbuf  += nblocks * blocksize;
+      outbuf += nblocks * blocksize;
+    }
+  else
+    {
+      for (n=0; n < nblocks; n++ ) 
+        {
+          /* Because outbuf and inbuf might be the same, we have to
+           * save the original ciphertext block.  We use LASTIV for
+           * this here because it is not used otherwise. */
+          memcpy (c->lastiv, inbuf, blocksize);
+          c->cipher->decrypt ( &c->context.c, outbuf, inbuf );
+          for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+           outbuf[i] ^= *ivp++;
+          memcpy(c->u_iv.iv, c->lastiv, blocksize );
+          inbuf  += c->cipher->blocksize;
+          outbuf += c->cipher->blocksize;
+        }
+    }
+
+  if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) 
+    {
+      int restbytes;
+      
+      if ((nbytes % blocksize) == 0)
+        restbytes = blocksize;
+      else
+        restbytes = nbytes % blocksize;
+      
+      memcpy (c->lastiv, c->u_iv.iv, blocksize );         /* Save Cn-2. */
+      memcpy (c->u_iv.iv, inbuf + blocksize, restbytes ); /* Save Cn. */
+
+      c->cipher->decrypt ( &c->context.c, outbuf, inbuf );
+      for (ivp=c->u_iv.iv,i=0; i < restbytes; i++ )
+        outbuf[i] ^= *ivp++;
+      
+      memcpy(outbuf + blocksize, outbuf, restbytes);
+      for(i=restbytes; i < blocksize; i++)
+        c->u_iv.iv[i] = outbuf[i];
+      c->cipher->decrypt (&c->context.c, outbuf, c->u_iv.iv);
+      for(ivp=c->lastiv,i=0; i < blocksize; i++ )
+        outbuf[i] ^= *ivp++;
+      /* c->lastiv is now really lastlastiv, does this matter? */
+    }
+}
+
+
+static void
+do_cfb_encrypt( gcry_cipher_hd_t c, unsigned char *outbuf, 
+                const unsigned char *inbuf, unsigned int nbytes )
+{
+  unsigned char *ivp;
+  size_t blocksize = c->cipher->blocksize;
+  size_t blocksize_x_2 = blocksize + blocksize;
+  
+  if ( nbytes <= c->unused )
+    {
+      /* Short enough to be encoded by the remaining XOR mask. */
+      /* XOR the input with the IV and store input into IV. */
+      for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused;
+           nbytes;
+           nbytes--, c->unused-- )
+        *outbuf++ = (*ivp++ ^= *inbuf++);
+      return;
+    }
+
+  if ( c->unused )
+    {
+      /* XOR the input with the IV and store input into IV */
+      nbytes -= c->unused;
+      for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
+        *outbuf++ = (*ivp++ ^= *inbuf++);
+    }
+
+  /* Now we can process complete blocks.  We use a loop as long as we
+     have at least 2 blocks and use conditions for the rest.  This
+     also allows to use a bulk encryption function if available.  */
+  if (nbytes >= blocksize_x_2 && c->bulk.cfb_enc)
+    {
+      unsigned int nblocks = nbytes / blocksize;
+      c->bulk.cfb_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks); 
+      outbuf += nblocks * blocksize;
+      inbuf  += nblocks * blocksize;
+      nbytes -= nblocks * blocksize;
+    }
+  else
+    {
+      while ( nbytes >= blocksize_x_2 )
+        {
+          int i;
+          /* Encrypt the IV. */
+          c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+          /* XOR the input with the IV and store input into IV.  */
+          for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+            *outbuf++ = (*ivp++ ^= *inbuf++);
+          nbytes -= blocksize;
+        }
+    }
+
+  if ( nbytes >= blocksize )
+    {
+      int i;
+      /* Save the current IV and then encrypt the IV. */
+      memcpy( c->lastiv, c->u_iv.iv, blocksize );
+      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      /* XOR the input with the IV and store input into IV */
+      for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+        *outbuf++ = (*ivp++ ^= *inbuf++);
+      nbytes -= blocksize;
+    }
+  if ( nbytes ) 
+    {
+      /* Save the current IV and then encrypt the IV. */
+      memcpy( c->lastiv, c->u_iv.iv, blocksize );
+      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      c->unused = blocksize;
+      /* Apply the XOR. */
+      c->unused -= nbytes;
+      for(ivp=c->u_iv.iv; nbytes; nbytes-- )
+        *outbuf++ = (*ivp++ ^= *inbuf++);
+    }
+}
+
+
+static void
+do_cfb_decrypt( gcry_cipher_hd_t c, unsigned char *outbuf, 
+                const unsigned char *inbuf, unsigned int nbytes )
+{
+  unsigned char *ivp;
+  unsigned long temp;
+  int i;
+  size_t blocksize = c->cipher->blocksize;
+  size_t blocksize_x_2 = blocksize + blocksize;
+  
+  if (nbytes <= c->unused)
+    {
+      /* Short enough to be encoded by the remaining XOR mask. */
+      /* XOR the input with the IV and store input into IV. */
+      for (ivp=c->u_iv.iv+blocksize - c->unused;
+           nbytes; 
+           nbytes--, c->unused--)
+        {
+          temp = *inbuf++;
+          *outbuf++ = *ivp ^ temp;
+          *ivp++ = temp;
+        }
+      return;
+    }
+  
+  if (c->unused)
+    {
+      /* XOR the input with the IV and store input into IV. */
+      nbytes -= c->unused;
+      for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
+        {
+          temp = *inbuf++;
+          *outbuf++ = *ivp ^ temp;
+          *ivp++ = temp;
+        }
+    }
+  
+  /* Now we can process complete blocks.  We use a loop as long as we
+     have at least 2 blocks and use conditions for the rest.  This
+     also allows to use a bulk encryption function if available.  */
+  if (nbytes >= blocksize_x_2 && c->bulk.cfb_dec)
+    {
+      unsigned int nblocks = nbytes / blocksize;
+      c->bulk.cfb_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks); 
+      outbuf += nblocks * blocksize;
+      inbuf  += nblocks * blocksize;
+      nbytes -= nblocks * blocksize;
+    }
+  else
+    {
+      while (nbytes >= blocksize_x_2 )
+        {
+          /* Encrypt the IV. */
+          c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+          /* XOR the input with the IV and store input into IV. */
+          for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+            {
+              temp = *inbuf++;
+              *outbuf++ = *ivp ^ temp;
+              *ivp++ = temp;
+            }
+          nbytes -= blocksize;
+        }
+    }
+
+  if (nbytes >= blocksize )
+    {
+      /* Save the current IV and then encrypt the IV. */
+      memcpy ( c->lastiv, c->u_iv.iv, blocksize);
+      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      /* XOR the input with the IV and store input into IV */
+      for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+        {
+          temp = *inbuf++;
+          *outbuf++ = *ivp ^ temp;
+          *ivp++ = temp;
+        }
+      nbytes -= blocksize;
+    }
+
+  if (nbytes)
+    { 
+      /* Save the current IV and then encrypt the IV. */
+      memcpy ( c->lastiv, c->u_iv.iv, blocksize );
+      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      c->unused = blocksize;
+      /* Apply the XOR. */
+      c->unused -= nbytes;
+      for (ivp=c->u_iv.iv; nbytes; nbytes-- )
+        {
+          temp = *inbuf++;
+          *outbuf++ = *ivp ^ temp;
+          *ivp++ = temp;
+        }
+    }
+}
+
+
+static void
+do_ofb_encrypt( gcry_cipher_hd_t c,
+                byte *outbuf, const byte *inbuf, unsigned nbytes )
+{
+  byte *ivp;
+  size_t blocksize = c->cipher->blocksize;
+
+  if ( nbytes <= c->unused )
+    {
+      /* Short enough to be encoded by the remaining XOR mask. */
+      /* XOR the input with the IV */
+      for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused;
+           nbytes;
+           nbytes--, c->unused-- )
+        *outbuf++ = (*ivp++ ^ *inbuf++);
+      return;
+    }
+
+  if( c->unused )
+    {
+      nbytes -= c->unused;
+      for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
+        *outbuf++ = (*ivp++ ^ *inbuf++);
+    }
+
+  /* Now we can process complete blocks. */
+  while ( nbytes >= blocksize )
+    {
+      int i;
+      /* Encrypt the IV (and save the current one). */
+      memcpy( c->lastiv, c->u_iv.iv, blocksize );
+      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      
+      for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+        *outbuf++ = (*ivp++ ^ *inbuf++);
+      nbytes -= blocksize;
+    }
+  if ( nbytes )
+    { /* process the remaining bytes */
+      memcpy( c->lastiv, c->u_iv.iv, blocksize );
+      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      c->unused = blocksize;
+      c->unused -= nbytes;
+      for(ivp=c->u_iv.iv; nbytes; nbytes-- )
+        *outbuf++ = (*ivp++ ^ *inbuf++);
+    }
+}
+
+static void
+do_ofb_decrypt( gcry_cipher_hd_t c,
+                byte *outbuf, const byte *inbuf, unsigned int nbytes )
+{
+  byte *ivp;
+  size_t blocksize = c->cipher->blocksize;
+  
+  if( nbytes <= c->unused )
+    {
+      /* Short enough to be encoded by the remaining XOR mask. */
+      for (ivp=c->u_iv.iv+blocksize - c->unused; nbytes; nbytes--,c->unused--)
+        *outbuf++ = *ivp++ ^ *inbuf++;
+      return;
+    }
+
+  if ( c->unused )
+    {
+      nbytes -= c->unused;
+      for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
+        *outbuf++ = *ivp++ ^ *inbuf++;
+    }
+
+  /* Now we can process complete blocks. */
+  while ( nbytes >= blocksize )
+    {
+      int i;
+      /* Encrypt the IV (and save the current one). */
+      memcpy( c->lastiv, c->u_iv.iv, blocksize );
+      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+        *outbuf++ = *ivp++ ^ *inbuf++;
+      nbytes -= blocksize;
+    }
+  if ( nbytes ) 
+    { /* Process the remaining bytes. */
+      /* Encrypt the IV (and save the current one). */
+      memcpy( c->lastiv, c->u_iv.iv, blocksize );
+      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      c->unused = blocksize;
+      c->unused -= nbytes;
+      for (ivp=c->u_iv.iv; nbytes; nbytes-- )
+        *outbuf++ = *ivp++ ^ *inbuf++;
+    }
+}
+
+
+static void
+do_ctr_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+                unsigned int nbytes )
+{
+  unsigned int n;
+  byte tmp[MAX_BLOCKSIZE];
+  int i;
+
+  for(n=0; n < nbytes; n++)
+    {
+      if ((n % c->cipher->blocksize) == 0)
+       {
+         c->cipher->encrypt (&c->context.c, tmp, c->ctr);
+
+         for (i = c->cipher->blocksize; i > 0; i--)
+           {
+             c->ctr[i-1]++;
+             if (c->ctr[i-1] != 0)
+               break;
+           }
+       }
+
+      /* XOR input with encrypted counter and store in output. */
+      outbuf[n] = inbuf[n] ^ tmp[n % c->cipher->blocksize];
+    }
+}
+
+static void
+do_ctr_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+                unsigned int nbytes )
+{
+  do_ctr_encrypt (c, outbuf, inbuf, nbytes);
+}
+
+
+/****************
+ * Encrypt INBUF to OUTBUF with the mode selected at open.
+ * inbuf and outbuf may overlap or be the same.
+ * Depending on the mode some contraints apply to NBYTES.
+ */
+static gcry_err_code_t
+cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf,
+               const byte *inbuf, unsigned int nbytes)
+{
+    gcry_err_code_t rc = GPG_ERR_NO_ERROR;
+
+    switch( c->mode ) {
+      case GCRY_CIPHER_MODE_ECB:
+       if (!(nbytes%c->cipher->blocksize))
+            do_ecb_encrypt(c, outbuf, inbuf, nbytes/c->cipher->blocksize );
+        else 
+            rc = GPG_ERR_INV_ARG;
+       break;
+      case GCRY_CIPHER_MODE_CBC:
+       if (!(nbytes%c->cipher->blocksize)
+            || (nbytes > c->cipher->blocksize
+                && (c->flags & GCRY_CIPHER_CBC_CTS)))
+            do_cbc_encrypt(c, outbuf, inbuf, nbytes );
+        else 
+            rc = GPG_ERR_INV_ARG;
+       break;
+      case GCRY_CIPHER_MODE_CFB:
+       do_cfb_encrypt(c, outbuf, inbuf, nbytes );
+       break;
+      case GCRY_CIPHER_MODE_OFB:
+       do_ofb_encrypt(c, outbuf, inbuf, nbytes );
+       break;
+      case GCRY_CIPHER_MODE_CTR:
+       do_ctr_encrypt(c, outbuf, inbuf, nbytes );
+       break;
+      case GCRY_CIPHER_MODE_STREAM:
+        c->cipher->stencrypt ( &c->context.c,
+                               outbuf, (byte*)/*arggg*/inbuf, nbytes );
+        break;
+      case GCRY_CIPHER_MODE_NONE:
+               if (fips_mode () || !_gcry_get_debug_flag (0))
+          {
+            fips_signal_error ("cipher mode NONE used");
+            rc = GPG_ERR_INV_CIPHER_MODE;
+          }
+        else
+          {
+            if ( inbuf != outbuf )
+              memmove (outbuf, inbuf, nbytes);
+          }
+       break;
+      default:
+        log_fatal("cipher_encrypt: invalid mode %d\n", c->mode );
+        rc = GPG_ERR_INV_CIPHER_MODE;
+        break;
+    }
+    return rc;
+}
+
+
+/****************
+ * Encrypt IN and write it to OUT.  If IN is NULL, in-place encryption has
+ * been requested.
+ */
+gcry_error_t
+gcry_cipher_encrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
+                     const void *in, size_t inlen)
+{
+  gcry_err_code_t err;
+
+  if (!in)
+    {
+      /* Caller requested in-place encryption. */
+      /* Actually cipher_encrypt() does not need to know about it, but
+       * we may change it in the future to get better performance.  */
+      err = cipher_encrypt (h, out, out, outsize);
+    }
+  else if (outsize < ((h->flags & GCRY_CIPHER_CBC_MAC) ?
+                      h->cipher->blocksize : inlen))
+    err = GPG_ERR_TOO_SHORT;
+  else if ((h->mode == GCRY_CIPHER_MODE_ECB
+           || (h->mode == GCRY_CIPHER_MODE_CBC
+               && (! ((h->flags & GCRY_CIPHER_CBC_CTS)
+                      && (inlen > h->cipher->blocksize)))))
+          && (inlen % h->cipher->blocksize))
+    err = GPG_ERR_INV_ARG;
+  else
+    err = cipher_encrypt (h, out, in, inlen);
+
+  if (err && out)
+    memset (out, 0x42, outsize); /* Failsafe: Make sure that the
+                                    plaintext will never make it into
+                                    OUT. */
+
+  return gcry_error (err);
+}
+
+
+
+/****************
+ * Decrypt INBUF to OUTBUF with the mode selected at open.
+ * inbuf and outbuf may overlap or be the same.
+ * Depending on the mode some some contraints apply to NBYTES.
+ */
+static gcry_err_code_t
+cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+               unsigned int nbytes)
+{
+    gcry_err_code_t rc = GPG_ERR_NO_ERROR;
+
+    switch( c->mode ) {
+      case GCRY_CIPHER_MODE_ECB:
+       if (!(nbytes%c->cipher->blocksize))
+            do_ecb_decrypt(c, outbuf, inbuf, nbytes/c->cipher->blocksize );
+        else 
+            rc = GPG_ERR_INV_ARG;
+       break;
+      case GCRY_CIPHER_MODE_CBC:
+       if (!(nbytes%c->cipher->blocksize)
+            || (nbytes > c->cipher->blocksize
+                && (c->flags & GCRY_CIPHER_CBC_CTS)))
+            do_cbc_decrypt(c, outbuf, inbuf, nbytes );
+        else 
+            rc = GPG_ERR_INV_ARG;
+       break;
+      case GCRY_CIPHER_MODE_CFB:
+       do_cfb_decrypt(c, outbuf, inbuf, nbytes );
+       break;
+      case GCRY_CIPHER_MODE_OFB:
+       do_ofb_decrypt(c, outbuf, inbuf, nbytes );
+       break;
+      case GCRY_CIPHER_MODE_CTR:
+       do_ctr_decrypt(c, outbuf, inbuf, nbytes );
+       break;
+      case GCRY_CIPHER_MODE_STREAM:
+        c->cipher->stdecrypt ( &c->context.c,
+                               outbuf, (byte*)/*arggg*/inbuf, nbytes );
+        break;
+      case GCRY_CIPHER_MODE_NONE:
+               if (fips_mode () || !_gcry_get_debug_flag (0))
+          {
+            fips_signal_error ("cipher mode NONE used");
+            rc = GPG_ERR_INV_CIPHER_MODE;
+          }
+        else
+          {
+            if (inbuf != outbuf)
+              memmove (outbuf, inbuf, nbytes);
+          }
+       break;
+      default:
+        log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode );
+        rc = GPG_ERR_INV_CIPHER_MODE;
+        break;
+    }
+    return rc;
+}
+
+
+gcry_error_t
+gcry_cipher_decrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
+                    const void *in, size_t inlen)
+{
+  gcry_err_code_t err = 0;
+
+  if (!in)
+    {
+      /* Caller requested in-place encryption. */
+      /* Actually cipher_encrypt() does not need to know about it, but
+       * we may change it in the future to get better performance.  */
+      err = cipher_decrypt (h, out, out, outsize);
+    }
+  else if (outsize < inlen)
+    err = GPG_ERR_TOO_SHORT;
+  else if (((h->mode == GCRY_CIPHER_MODE_ECB)
+           || ((h->mode == GCRY_CIPHER_MODE_CBC)
+               && (! ((h->flags & GCRY_CIPHER_CBC_CTS)
+                      && (inlen > h->cipher->blocksize)))))
+          && (inlen % h->cipher->blocksize) != 0)
+    err = GPG_ERR_INV_ARG;
+  else
+    err = cipher_decrypt (h, out, in, inlen);
+
+  return gcry_error (err);
+}
+
+
+
+/****************
+ * Used for PGP's somewhat strange CFB mode. Only works if
+ * the corresponding flag is set.
+ */
+static void
+cipher_sync (gcry_cipher_hd_t c)
+{
+  if ((c->flags & GCRY_CIPHER_ENABLE_SYNC) && c->unused)
+    {
+      memmove (c->u_iv.iv + c->unused,
+               c->u_iv.iv, c->cipher->blocksize - c->unused);
+      memcpy (c->u_iv.iv,
+              c->lastiv + c->cipher->blocksize - c->unused, c->unused);
+      c->unused = 0;
+    }
+}
+
+
+gcry_error_t
+_gcry_cipher_setkey (gcry_cipher_hd_t hd, const void *key, size_t keylen)
+{
+  return cipher_setkey (hd, (void*)key, keylen);
+}
+
+
+gcry_error_t
+_gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen)
+{
+  cipher_setiv (hd, iv, ivlen);
+  return 0;
+}
+
+/* Set counter for CTR mode.  (CTR,CTRLEN) must denote a buffer of
+   block size length, or (NULL,0) to set the CTR to the all-zero
+   block. */
+gpg_error_t
+_gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen)
+{
+  if (ctr && ctrlen == hd->cipher->blocksize)
+    memcpy (hd->ctr, ctr, hd->cipher->blocksize);
+  else if (!ctr || !ctrlen)
+    memset (hd->ctr, 0, hd->cipher->blocksize);
+  else
+    return gpg_error (GPG_ERR_INV_ARG);
+  return 0;
+}
+
+
+gcry_error_t
+gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
+{
+  gcry_err_code_t rc = GPG_ERR_NO_ERROR;
+
+  switch (cmd)
+    {
+    case GCRYCTL_SET_KEY:  /* Deprecated; use gcry_cipher_setkey.  */
+      rc = cipher_setkey( h, buffer, buflen );
+      break;
+
+    case GCRYCTL_SET_IV:   /* Deprecated; use gcry_cipher_setiv.  */
+      cipher_setiv( h, buffer, buflen );
+      break;
+
+    case GCRYCTL_RESET:
+      cipher_reset (h);
+      break;
+
+    case GCRYCTL_CFB_SYNC:
+      cipher_sync( h );
+      break;
+
+    case GCRYCTL_SET_CBC_CTS:
+      if (buflen)
+       if (h->flags & GCRY_CIPHER_CBC_MAC)
+         rc = GPG_ERR_INV_FLAG;
+       else
+         h->flags |= GCRY_CIPHER_CBC_CTS;
+      else
+       h->flags &= ~GCRY_CIPHER_CBC_CTS;
+      break;
+
+    case GCRYCTL_SET_CBC_MAC:
+      if (buflen)
+       if (h->flags & GCRY_CIPHER_CBC_CTS)
+         rc = GPG_ERR_INV_FLAG;
+       else
+         h->flags |= GCRY_CIPHER_CBC_MAC;
+      else
+       h->flags &= ~GCRY_CIPHER_CBC_MAC;
+      break;
+
+    case GCRYCTL_DISABLE_ALGO:
+      /* This command expects NULL for H and BUFFER to point to an
+         integer with the algo number.  */
+      if( h || !buffer || buflen != sizeof(int) )
+       return gcry_error (GPG_ERR_CIPHER_ALGO);
+      disable_cipher_algo( *(int*)buffer );
+      break;
+
+    case GCRYCTL_SET_CTR: /* Deprecated; use gcry_cipher_setctr.  */
+      if (buffer && buflen == h->cipher->blocksize)
+       memcpy (h->ctr, buffer, h->cipher->blocksize);
+      else if (buffer == NULL || buflen == 0)
+       memset (h->ctr, 0, h->cipher->blocksize);
+      else
+       rc = GPG_ERR_INV_ARG;
+      break;
+
+    case 61:  /* Disable weak key detection (private).  */
+      if (h->extraspec->set_extra_info)
+        rc = h->extraspec->set_extra_info 
+          (&h->context.c, CIPHER_INFO_NO_WEAK_KEY, NULL, 0);
+      else
+        rc = GPG_ERR_NOT_SUPPORTED;
+      break;
+
+    case 62: /* Return current input vector (private).  */
+      /* This is the input block as used in CFB and OFB mode which has
+         initially been set as IV.  The returned format is: 
+           1 byte  Actual length of the block in bytes.
+           n byte  The block.
+         If the provided buffer is too short, an error is returned. */
+      if (buflen < (1 + h->cipher->blocksize))
+        rc = GPG_ERR_TOO_SHORT;
+      else
+        {
+          unsigned char *ivp;
+          unsigned char *dst = buffer;
+          int n = h->unused;
+          
+          if (!n)
+            n = h->cipher->blocksize;
+          gcry_assert (n <= h->cipher->blocksize);
+          *dst++ = n;
+          ivp = h->u_iv.iv + h->cipher->blocksize - n;
+          while (n--)
+            *dst++ = *ivp++;
+        }
+      break;
+
+    default:
+      rc = GPG_ERR_INV_OP;
+    }
+
+  return gcry_error (rc);
+}
+
+
+/* Return information about the cipher handle H.  CMD is the kind of
+   information requested.  BUFFER and NBYTES are reserved for now.
+
+   There are no values for CMD yet defined.  
+
+   The fucntion always returns GPG_ERR_INV_OP.
+   
+ */
+gcry_error_t
+gcry_cipher_info (gcry_cipher_hd_t h, int cmd, void *buffer, size_t *nbytes)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+  (void)h;
+  (void)buffer;
+  (void)nbytes;
+
+  switch (cmd)
+    {
+    default:
+      err = GPG_ERR_INV_OP;
+    }
+
+  return gcry_error (err);
+}
+
+/* Return information about the given cipher algorithm ALGO.
+
+   WHAT select the kind of information returned:
+
+    GCRYCTL_GET_KEYLEN:
+       Return the length of the key.  If the algorithm ALGO
+       supports multiple key lengths, the maximum supported key length
+       is returned.  The key length is returned as number of octets.
+       BUFFER and NBYTES must be zero.
+
+    GCRYCTL_GET_BLKLEN:
+       Return the blocklength of the algorithm ALGO counted in octets.
+       BUFFER and NBYTES must be zero.
+
+    GCRYCTL_TEST_ALGO:
+       Returns 0 if the specified algorithm ALGO is available for use.
+       BUFFER and NBYTES must be zero.
+  
+   Note: Because this function is in most cases used to return an
+   integer value, we can make it easier for the caller to just look at
+   the return value.  The caller will in all cases consult the value
+   and thereby detecting whether a error occured or not (i.e. while
+   checking the block size)
+ */
+gcry_error_t
+gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  unsigned int ui;
+
+  switch (what)
+    {
+    case GCRYCTL_GET_KEYLEN:
+      if (buffer || (! nbytes))
+       err = GPG_ERR_CIPHER_ALGO;
+      else
+       {
+         ui = cipher_get_keylen (algo);
+         if ((ui > 0) && (ui <= 512))
+           *nbytes = (size_t) ui / 8;
+         else
+           /* The only reason is an invalid algo or a strange
+              blocksize.  */
+           err = GPG_ERR_CIPHER_ALGO;
+       }
+      break;
+
+    case GCRYCTL_GET_BLKLEN:
+      if (buffer || (! nbytes))
+       err = GPG_ERR_CIPHER_ALGO;
+      else
+       {
+         ui = cipher_get_blocksize (algo);
+         if ((ui > 0) && (ui < 10000))
+           *nbytes = ui;
+         else
+           /* The only reason is an invalid algo or a strange
+              blocksize.  */
+           err = GPG_ERR_CIPHER_ALGO;
+       }
+      break;
+
+    case GCRYCTL_TEST_ALGO:
+      if (buffer || nbytes)
+       err = GPG_ERR_INV_ARG;
+      else
+       err = check_cipher_algo (algo);
+      break;
+
+      default:
+       err = GPG_ERR_INV_OP;
+    }
+
+  return gcry_error (err);
+}
+
+
+/* This function returns length of the key for algorithm ALGO.  If the
+   algorithm supports multiple key lengths, the maximum supported key
+   length is returned.  On error 0 is returned.  The key length is
+   returned as number of octets.
+
+   This is a convenience functions which should be preferred over
+   gcry_cipher_algo_info because it allows for proper type
+   checking.  */
+size_t
+gcry_cipher_get_algo_keylen (int algo) 
+{
+  size_t n;
+
+  if (gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, &n))
+    n = 0;
+  return n;
+}
+
+/* This functions returns the blocklength of the algorithm ALGO
+   counted in octets.  On error 0 is returned.
+
+   This is a convenience functions which should be preferred over
+   gcry_cipher_algo_info because it allows for proper type
+   checking.  */
+size_t
+gcry_cipher_get_algo_blklen (int algo) 
+{
+  size_t n;
+
+  if (gcry_cipher_algo_info( algo, GCRYCTL_GET_BLKLEN, NULL, &n))
+    n = 0;
+  return n;
+}
+
+/* Explicitly initialize this module.  */
+gcry_err_code_t
+_gcry_cipher_init (void)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+  REGISTER_DEFAULT_CIPHERS;
+
+  return err;
+}
+
+/* Get a list consisting of the IDs of the loaded cipher modules.  If
+   LIST is zero, write the number of loaded cipher modules to
+   LIST_LENGTH and return.  If LIST is non-zero, the first
+   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+   according size.  In case there are less cipher modules than
+   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
+gcry_error_t
+gcry_cipher_list (int *list, int *list_length)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+  ath_mutex_lock (&ciphers_registered_lock);
+  err = _gcry_module_list (ciphers_registered, list, list_length);
+  ath_mutex_unlock (&ciphers_registered_lock);
+
+  return err;
+}
+
+
+/* Run the selftests for cipher algorithm ALGO with optional reporting
+   function REPORT.  */
+gpg_error_t
+_gcry_cipher_selftest (int algo, int extended, selftest_report_func_t report)
+{
+  gcry_module_t module = NULL;
+  cipher_extra_spec_t *extraspec = NULL;
+  gcry_err_code_t ec = 0;
+
+  REGISTER_DEFAULT_CIPHERS;
+
+  ath_mutex_lock (&ciphers_registered_lock);
+  module = _gcry_module_lookup_id (ciphers_registered, algo);
+  if (module && !(module->flags & FLAG_MODULE_DISABLED))
+    extraspec = module->extraspec;
+  ath_mutex_unlock (&ciphers_registered_lock);
+  if (extraspec && extraspec->selftest)
+    ec = extraspec->selftest (algo, extended, report);
+  else
+    {
+      ec = GPG_ERR_CIPHER_ALGO;
+      if (report)
+        report ("cipher", algo, "module", 
+                module && !(module->flags & FLAG_MODULE_DISABLED)?
+                "no selftest available" :
+                module? "algorithm disabled" : "algorithm not found");
+    }
+
+  if (module)
+    {
+      ath_mutex_lock (&ciphers_registered_lock);
+      _gcry_module_release (module);
+      ath_mutex_unlock (&ciphers_registered_lock);
+    }
+  return gpg_error (ec);
+}
diff --git a/grub-core/lib/libgcrypt/cipher/crc.c b/grub-core/lib/libgcrypt/cipher/crc.c
new file mode 100644 (file)
index 0000000..d04fff8
--- /dev/null
@@ -0,0 +1,297 @@
+/* crc.c - Cyclic redundancy checks.
+ * Copyright (C) 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "memory.h"
+#include "cipher.h"
+
+#include "bithelp.h"
+
+/* Table of CRCs of all 8-bit messages.  Generated by running code
+   from RFC 1952 modified to print out the table. */
+static u32 crc32_table[256] = {
+  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+  0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+  0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+  0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+  0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+  0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+  0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+  0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+  0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+  0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+  0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+  0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+  0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+  0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+  0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+  0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+  0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+  0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+  0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+  0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+  0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+  0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+  0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+  0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+  0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+  0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+  0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+  0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+  0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+  0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+  0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+  0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+  0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+  0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+  0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+  0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+  0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+  0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+  0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+/*
+ * The following function was extracted from RFC 1952 by Simon
+ * Josefsson, for the Shishi project, and modified to be compatible
+ * with the modified CRC-32 used by RFC 1510, and subsequently
+ * modified for GNU Libgcrypt to allow it to be used for calculating
+ * both unmodified CRC-32 and modified CRC-32 values.  Original
+ * copyright and notice from the document follows:
+ *
+ *    Copyright (c) 1996 L. Peter Deutsch
+ *
+ *    Permission is granted to copy and distribute this document for
+ *    any purpose and without charge, including translations into
+ *    other languages and incorporation into compilations, provided
+ *    that the copyright notice and this notice are preserved, and
+ *    that any substantive changes or deletions from the original are
+ *    clearly marked.
+ *
+ * The copyright on RFCs, and consequently the function below, are
+ * supposedly also retroactively claimed by the Internet Society
+ * (according to rfc-editor@rfc-editor.org), with the following
+ * copyright notice:
+ *
+ *    Copyright (C) The Internet Society.  All Rights Reserved.
+ *
+ *    This document and translations of it may be copied and furnished
+ *    to others, and derivative works that comment on or otherwise
+ *    explain it or assist in its implementation may be prepared,
+ *    copied, published and distributed, in whole or in part, without
+ *    restriction of any kind, provided that the above copyright
+ *    notice and this paragraph are included on all such copies and
+ *    derivative works.  However, this document itself may not be
+ *    modified in any way, such as by removing the copyright notice or
+ *    references to the Internet Society or other Internet
+ *    organizations, except as needed for the purpose of developing
+ *    Internet standards in which case the procedures for copyrights
+ *    defined in the Internet Standards process must be followed, or
+ *    as required to translate it into languages other than English.
+ *
+ *    The limited permissions granted above are perpetual and will not be
+ *    revoked by the Internet Society or its successors or assigns.
+ *
+ *    This document and the information contained herein is provided
+ *    on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
+ *    ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR
+ *    IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE
+ *    OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
+ *    IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
+ *    PARTICULAR PURPOSE.
+ *
+ */
+static u32
+update_crc32 (u32 crc, const void *buf_arg, size_t len)
+{
+  const char *buf = buf_arg;
+  size_t n;
+
+  for (n = 0; n < len; n++)
+    crc = crc32_table[(crc ^ buf[n]) & 0xff] ^ (crc >> 8);
+
+  return crc;
+}
+
+typedef struct
+{
+  u32 CRC;
+  byte buf[4];
+}
+CRC_CONTEXT;
+
+/* CRC32 */
+
+static void
+crc32_init (void *context)
+{
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+  ctx->CRC = 0 ^ 0xffffffffL;
+}
+
+static void
+crc32_write (void *context, const void *inbuf, size_t inlen)
+{
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+  if (!inbuf)
+    return;
+  ctx->CRC = update_crc32 (ctx->CRC, inbuf, inlen);
+}
+
+static byte *
+crc32_read (void *context)
+{
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+  return ctx->buf;
+}
+
+static void
+crc32_final (void *context)
+{
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+  ctx->CRC ^= 0xffffffffL;
+  ctx->buf[0] = (ctx->CRC >> 24) & 0xFF;
+  ctx->buf[1] = (ctx->CRC >> 16) & 0xFF;
+  ctx->buf[2] = (ctx->CRC >>  8) & 0xFF;
+  ctx->buf[3] = (ctx->CRC      ) & 0xFF;
+}
+
+/* CRC32 a'la RFC 1510 */
+static void
+crc32rfc1510_init (void *context)
+{
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+  ctx->CRC = 0;
+}
+
+static void
+crc32rfc1510_final (void *context)
+{
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+  ctx->buf[0] = (ctx->CRC >> 24) & 0xFF;
+  ctx->buf[1] = (ctx->CRC >> 16) & 0xFF;
+  ctx->buf[2] = (ctx->CRC >>  8) & 0xFF;
+  ctx->buf[3] = (ctx->CRC      ) & 0xFF;
+}
+
+/* CRC24 a'la RFC 2440 */
+/*
+ * The following CRC 24 routines are adapted from RFC 2440, which has
+ * the following copyright notice:
+ *
+ *   Copyright (C) The Internet Society (1998).  All Rights Reserved.
+ *
+ *   This document and translations of it may be copied and furnished
+ *   to others, and derivative works that comment on or otherwise
+ *   explain it or assist in its implementation may be prepared,
+ *   copied, published and distributed, in whole or in part, without
+ *   restriction of any kind, provided that the above copyright notice
+ *   and this paragraph are included on all such copies and derivative
+ *   works.  However, this document itself may not be modified in any
+ *   way, such as by removing the copyright notice or references to
+ *   the Internet Society or other Internet organizations, except as
+ *   needed for the purpose of developing Internet standards in which
+ *   case the procedures for copyrights defined in the Internet
+ *   Standards process must be followed, or as required to translate
+ *   it into languages other than English.
+ *
+ *   The limited permissions granted above are perpetual and will not be
+ *   revoked by the Internet Society or its successors or assigns.
+ *
+ *   This document and the information contained herein is provided on
+ *   an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
+ *   ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR
+ *   IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE
+ *   OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
+ *   IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+ *   PURPOSE.
+ */
+
+#define CRC24_INIT 0xb704ceL
+#define CRC24_POLY 0x1864cfbL
+
+static void
+crc24rfc2440_init (void *context)
+{
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+  ctx->CRC = CRC24_INIT;
+}
+
+static void
+crc24rfc2440_write (void *context, const void *inbuf_arg, size_t inlen)
+{
+  const unsigned char *inbuf = inbuf_arg;
+  int i;
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+
+  if (!inbuf)
+    return;
+
+  while (inlen--) {
+    ctx->CRC ^= (*inbuf++) << 16;
+    for (i = 0; i < 8; i++) {
+      ctx->CRC <<= 1;
+      if (ctx->CRC & 0x1000000)
+       ctx->CRC ^= CRC24_POLY;
+    }
+  }
+}
+
+static void
+crc24rfc2440_final (void *context)
+{
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+  ctx->buf[0] = (ctx->CRC >> 16) & 0xFF;
+  ctx->buf[1] = (ctx->CRC >>  8) & 0xFF;
+  ctx->buf[2] = (ctx->CRC      ) & 0xFF;
+}
+
+gcry_md_spec_t _gcry_digest_spec_crc32 =
+  {
+    "CRC32", NULL, 0, NULL, 4,
+    crc32_init, crc32_write, crc32_final, crc32_read,
+    sizeof (CRC_CONTEXT)
+  };
+
+gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510 =
+  {
+    "CRC32RFC1510", NULL, 0, NULL, 4,
+    crc32rfc1510_init, crc32_write,
+    crc32rfc1510_final, crc32_read,
+    sizeof (CRC_CONTEXT)
+  };
+
+gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440 =
+  {
+    "CRC24RFC2440", NULL, 0, NULL, 3,
+    crc24rfc2440_init, crc24rfc2440_write,
+    crc24rfc2440_final, crc32_read,
+    sizeof (CRC_CONTEXT)
+  };
diff --git a/grub-core/lib/libgcrypt/cipher/des.c b/grub-core/lib/libgcrypt/cipher/des.c
new file mode 100644 (file)
index 0000000..f91df77
--- /dev/null
@@ -0,0 +1,1196 @@
+/* des.c - DES and Triple-DES encryption/decryption Algorithm
+ * Copyright (C) 1998, 1999, 2001, 2002, 2003,
+ *               2008  Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * For a description of triple encryption, see:
+ *   Bruce Schneier: Applied Cryptography. Second Edition.
+ *   John Wiley & Sons, 1996. ISBN 0-471-12845-7. Pages 358 ff.
+ * This implementation is according to the definition of DES in FIPS
+ * PUB 46-2 from December 1993. 
+ */
+
+
+/*
+ * Written by Michael Roth <mroth@nessie.de>, September 1998
+ */
+
+
+/*
+ *  U S A G E
+ * ===========
+ *
+ * For DES or Triple-DES encryption/decryption you must initialize a proper
+ * encryption context with a key.
+ *
+ * A DES key is 64bit wide but only 56bits of the key are used. The remaining
+ * bits are parity bits and they will _not_ checked in this implementation, but
+ * simply ignored.
+ *
+ * For Triple-DES you could use either two 64bit keys or three 64bit keys.
+ * The parity bits will _not_ checked, too.
+ *
+ * After initializing a context with a key you could use this context to
+ * encrypt or decrypt data in 64bit blocks in Electronic Codebook Mode.
+ *
+ * (In the examples below the slashes at the beginning and ending of comments
+ * are omited.)
+ *
+ * DES Example
+ * -----------
+ *     unsigned char key[8];
+ *     unsigned char plaintext[8];
+ *     unsigned char ciphertext[8];
+ *     unsigned char recoverd[8];
+ *     des_ctx context;
+ *
+ *     * Fill 'key' and 'plaintext' with some data *
+ *     ....
+ *
+ *     * Set up the DES encryption context *
+ *     des_setkey(context, key);
+ *
+ *     * Encrypt the plaintext *
+ *     des_ecb_encrypt(context, plaintext, ciphertext);
+ *
+ *     * To recover the orginal plaintext from ciphertext use: *
+ *     des_ecb_decrypt(context, ciphertext, recoverd);
+ *
+ *
+ * Triple-DES Example
+ * ------------------
+ *     unsigned char key1[8];
+ *     unsigned char key2[8];
+ *     unsigned char key3[8];
+ *     unsigned char plaintext[8];
+ *     unsigned char ciphertext[8];
+ *     unsigned char recoverd[8];
+ *     tripledes_ctx context;
+ *
+ *     * If you would like to use two 64bit keys, fill 'key1' and'key2'
+ *      then setup the encryption context: *
+ *     tripledes_set2keys(context, key1, key2);
+ *
+ *     * To use three 64bit keys with Triple-DES use: *
+ *     tripledes_set3keys(context, key1, key2, key3);
+ *
+ *     * Encrypting plaintext with Triple-DES *
+ *     tripledes_ecb_encrypt(context, plaintext, ciphertext);
+ *
+ *     * Decrypting ciphertext to recover the plaintext with Triple-DES *
+ *     tripledes_ecb_decrypt(context, ciphertext, recoverd);
+ *
+ *
+ * Selftest
+ * --------
+ *     char *error_msg;
+ *
+ *     * To perform a selftest of this DES/Triple-DES implementation use the
+ *      function selftest(). It will return an error string if there are
+ *      some problems with this library. *
+ *
+ *     if ( (error_msg = selftest()) )
+ *     {
+ *        fprintf(stderr, "An error in the DES/Tripple-DES implementation occured: %s\n", error_msg);
+ *        abort();
+ *     }
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>           /* memcpy, memcmp */
+#include "types.h"             /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+
+#if defined(__GNUC__) && defined(__GNU_LIBRARY__)
+#define working_memcmp memcmp
+#else
+/*
+ * According to the SunOS man page, memcmp returns indeterminate sign
+ * depending on whether characters are signed or not.
+ */
+static int
+working_memcmp( const char *a, const char *b, size_t n )
+{
+    for( ; n; n--, a++, b++ )
+       if( *a != *b )
+           return (int)(*(byte*)a) - (int)(*(byte*)b);
+    return 0;
+}
+#endif
+
+/*
+ * Encryption/Decryption context of DES
+ */
+typedef struct _des_ctx
+  {
+    u32 encrypt_subkeys[32];
+    u32 decrypt_subkeys[32];
+  }
+des_ctx[1];
+
+/*
+ * Encryption/Decryption context of Triple-DES
+ */
+typedef struct _tripledes_ctx
+  {
+    u32 encrypt_subkeys[96];
+    u32 decrypt_subkeys[96];
+    struct {
+      int no_weak_key;
+    } flags;
+  }
+tripledes_ctx[1];
+
+static void des_key_schedule (const byte *, u32 *);
+static int des_setkey (struct _des_ctx *, const byte *);
+static int des_ecb_crypt (struct _des_ctx *, const byte *, byte *, int);
+static int tripledes_set2keys (struct _tripledes_ctx *,
+                               const byte *, const byte *);
+static int tripledes_set3keys (struct _tripledes_ctx *,
+                               const byte *, const byte *, const byte *);
+static int tripledes_ecb_crypt (struct _tripledes_ctx *,
+                                const byte *, byte *, int);
+static int is_weak_key ( const byte *key );
+static const char *selftest (void);
+
+static int initialized;
+
+
+
+
+/*
+ * The s-box values are permuted according to the 'primitive function P'
+ * and are rotated one bit to the left.
+ */
+static u32 sbox1[64] =
+{
+  0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000,
+  0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
+  0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
+  0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000,
+  0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400,
+  0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
+  0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400,
+  0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004
+};
+
+static u32 sbox2[64] =
+{
+  0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020,
+  0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
+  0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
+  0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020,
+  0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000,
+  0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
+  0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020,
+  0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000
+};
+
+static u32 sbox3[64] =
+{
+  0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200,
+  0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
+  0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
+  0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000,
+  0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000,
+  0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
+  0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008,
+  0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200
+};
+
+static u32 sbox4[64] =
+{
+  0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001,
+  0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
+  0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
+  0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081,
+  0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000,
+  0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
+  0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081,
+  0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080
+};
+
+static u32 sbox5[64] =
+{
+  0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000,
+  0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
+  0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
+  0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100,
+  0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100,
+  0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
+  0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000,
+  0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100
+};
+
+static u32 sbox6[64] =
+{
+  0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000,
+  0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
+  0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
+  0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000,
+  0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010,
+  0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
+  0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010,
+  0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010
+};
+
+static u32 sbox7[64] =
+{
+  0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800,
+  0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
+  0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
+  0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800,
+  0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002,
+  0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
+  0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802,
+  0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002
+};
+
+static u32 sbox8[64] =
+{
+  0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000,
+  0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
+  0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
+  0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000,
+  0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040,
+  0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
+  0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000,
+  0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000
+};
+
+
+/*
+ * These two tables are part of the 'permuted choice 1' function.
+ * In this implementation several speed improvements are done.
+ */
+static u32 leftkey_swap[16] =
+{
+  0x00000000, 0x00000001, 0x00000100, 0x00000101,
+  0x00010000, 0x00010001, 0x00010100, 0x00010101,
+  0x01000000, 0x01000001, 0x01000100, 0x01000101,
+  0x01010000, 0x01010001, 0x01010100, 0x01010101
+};
+
+static u32 rightkey_swap[16] =
+{
+  0x00000000, 0x01000000, 0x00010000, 0x01010000,
+  0x00000100, 0x01000100, 0x00010100, 0x01010100,
+  0x00000001, 0x01000001, 0x00010001, 0x01010001,
+  0x00000101, 0x01000101, 0x00010101, 0x01010101,
+};
+
+
+
+/*
+ * Numbers of left shifts per round for encryption subkeys.
+ * To calculate the decryption subkeys we just reverse the
+ * ordering of the calculated encryption subkeys. So their
+ * is no need for a decryption rotate tab.
+ */
+static byte encrypt_rotate_tab[16] =
+{
+  1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+};
+
+
+
+/*
+ * Table with weak DES keys sorted in ascending order.
+ * In DES their are 64 known keys which are weak. They are weak
+ * because they produce only one, two or four different
+ * subkeys in the subkey scheduling process.
+ * The keys in this table have all their parity bits cleared.
+ */
+static byte weak_keys[64][8] =
+{
+  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*w*/
+  { 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e },
+  { 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0 },
+  { 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe },
+  { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e }, /*sw*/
+  { 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00 },
+  { 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe },
+  { 0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0 },
+  { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0 }, /*sw*/
+  { 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe },
+  { 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00 },
+  { 0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e },
+  { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe }, /*sw*/
+  { 0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0 },
+  { 0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e },
+  { 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00 },
+  { 0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e },
+  { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 }, /*sw*/
+  { 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe },
+  { 0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0 },
+  { 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00 },
+  { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e }, /*w*/
+  { 0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0 },
+  { 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe },
+  { 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe },
+  { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 }, /*sw*/
+  { 0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e },
+  { 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00 },
+  { 0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0 },
+  { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe }, /*sw*/
+  { 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00 },
+  { 0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e },
+  { 0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0 },
+  { 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe },
+  { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 }, /*sw*/
+  { 0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e },
+  { 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe },
+  { 0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0 },
+  { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e }, /*sw*/
+  { 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00 },
+  { 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00 },
+  { 0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e },
+  { 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 }, /*w*/
+  { 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe },
+  { 0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e },
+  { 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00 },
+  { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe }, /*sw*/
+  { 0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0 },
+  { 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe },
+  { 0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0 },
+  { 0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e },
+  { 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00 }, /*sw*/
+  { 0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0 },
+  { 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe },
+  { 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00 },
+  { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e }, /*sw*/
+  { 0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e },
+  { 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00 },
+  { 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe },
+  { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 }, /*sw*/
+  { 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00 },
+  { 0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e },
+  { 0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0 },
+  { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe }  /*w*/
+};
+static unsigned char weak_keys_chksum[20] = {
+  0xD0, 0xCF, 0x07, 0x38, 0x93, 0x70, 0x8A, 0x83, 0x7D, 0xD7,
+  0x8A, 0x36, 0x65, 0x29, 0x6C, 0x1F, 0x7C, 0x3F, 0xD3, 0x41 
+};
+
+
+
+/*
+ * Macro to swap bits across two words.
+ */
+#define DO_PERMUTATION(a, temp, b, offset, mask)       \
+    temp = ((a>>offset) ^ b) & mask;                   \
+    b ^= temp;                                         \
+    a ^= temp<<offset;
+
+
+/*
+ * This performs the 'initial permutation' of the data to be encrypted
+ * or decrypted. Additionally the resulting two words are rotated one bit
+ * to the left.
+ */
+#define INITIAL_PERMUTATION(left, temp, right)         \
+    DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f)   \
+    DO_PERMUTATION(left, temp, right, 16, 0x0000ffff)  \
+    DO_PERMUTATION(right, temp, left, 2, 0x33333333)   \
+    DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff)   \
+    right =  (right << 1) | (right >> 31);             \
+    temp  =  (left ^ right) & 0xaaaaaaaa;              \
+    right ^= temp;                                     \
+    left  ^= temp;                                     \
+    left  =  (left << 1) | (left >> 31);
+
+/*
+ * The 'inverse initial permutation'.
+ */
+#define FINAL_PERMUTATION(left, temp, right)           \
+    left  =  (left << 31) | (left >> 1);               \
+    temp  =  (left ^ right) & 0xaaaaaaaa;              \
+    left  ^= temp;                                     \
+    right ^= temp;                                     \
+    right  =  (right << 31) | (right >> 1);            \
+    DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff)   \
+    DO_PERMUTATION(right, temp, left, 2, 0x33333333)   \
+    DO_PERMUTATION(left, temp, right, 16, 0x0000ffff)  \
+    DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f)
+
+
+/*
+ * A full DES round including 'expansion function', 'sbox substitution'
+ * and 'primitive function P' but without swapping the left and right word.
+ * Please note: The data in 'from' and 'to' is already rotated one bit to
+ * the left, done in the initial permutation.
+ */
+#define DES_ROUND(from, to, work, subkey)              \
+    work = from ^ *subkey++;                           \
+    to ^= sbox8[  work     & 0x3f ];                   \
+    to ^= sbox6[ (work>>8)  & 0x3f ];                  \
+    to ^= sbox4[ (work>>16) & 0x3f ];                  \
+    to ^= sbox2[ (work>>24) & 0x3f ];                  \
+    work = ((from << 28) | (from >> 4)) ^ *subkey++;   \
+    to ^= sbox7[  work     & 0x3f ];                   \
+    to ^= sbox5[ (work>>8)  & 0x3f ];                  \
+    to ^= sbox3[ (work>>16) & 0x3f ];                  \
+    to ^= sbox1[ (work>>24) & 0x3f ];
+
+/*
+ * Macros to convert 8 bytes from/to 32bit words.
+ */
+#define READ_64BIT_DATA(data, left, right)                                \
+    left  = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];  \
+    right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
+
+#define WRITE_64BIT_DATA(data, left, right)                               \
+    data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff;           \
+    data[2] = (left >> 8) &0xff; data[3] = left &0xff;                    \
+    data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff;         \
+    data[6] = (right >> 8) &0xff; data[7] = right &0xff;
+
+/*
+ * Handy macros for encryption and decryption of data
+ */
+#define des_ecb_encrypt(ctx, from, to)       des_ecb_crypt(ctx, from, to, 0)
+#define des_ecb_decrypt(ctx, from, to)       des_ecb_crypt(ctx, from, to, 1)
+#define tripledes_ecb_encrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,0)
+#define tripledes_ecb_decrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,1)
+
+
+
+
+
+
+/*
+ * des_key_schedule():   Calculate 16 subkeys pairs (even/odd) for
+ *                       16 encryption rounds.
+ *                       To calculate subkeys for decryption the caller
+ *                       have to reorder the generated subkeys.
+ *
+ *    rawkey:      8 Bytes of key data
+ *    subkey:      Array of at least 32 u32s. Will be filled
+ *                 with calculated subkeys.
+ *
+ */
+static void
+des_key_schedule (const byte * rawkey, u32 * subkey)
+{
+  u32 left, right, work;
+  int round;
+
+  READ_64BIT_DATA (rawkey, left, right)
+
+  DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f)
+  DO_PERMUTATION (right, work, left, 0, 0x10101010)
+
+  left = ((leftkey_swap[(left >> 0) & 0xf] << 3)
+          | (leftkey_swap[(left >> 8) & 0xf] << 2)
+          | (leftkey_swap[(left >> 16) & 0xf] << 1)
+          | (leftkey_swap[(left >> 24) & 0xf])
+          | (leftkey_swap[(left >> 5) & 0xf] << 7)
+          | (leftkey_swap[(left >> 13) & 0xf] << 6)
+          | (leftkey_swap[(left >> 21) & 0xf] << 5)
+          | (leftkey_swap[(left >> 29) & 0xf] << 4));
+
+  left &= 0x0fffffff;
+
+  right = ((rightkey_swap[(right >> 1) & 0xf] << 3)
+           | (rightkey_swap[(right >> 9) & 0xf] << 2)
+           | (rightkey_swap[(right >> 17) & 0xf] << 1)
+           | (rightkey_swap[(right >> 25) & 0xf])
+           | (rightkey_swap[(right >> 4) & 0xf] << 7)
+           | (rightkey_swap[(right >> 12) & 0xf] << 6)
+           | (rightkey_swap[(right >> 20) & 0xf] << 5)
+           | (rightkey_swap[(right >> 28) & 0xf] << 4));
+
+  right &= 0x0fffffff;
+
+  for (round = 0; round < 16; ++round)
+    {
+      left = ((left << encrypt_rotate_tab[round])
+              | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
+      right = ((right << encrypt_rotate_tab[round])
+               | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
+
+      *subkey++ = (((left << 4) & 0x24000000)
+                   | ((left << 28) & 0x10000000)
+                   | ((left << 14) & 0x08000000)
+                   | ((left << 18) & 0x02080000)
+                   | ((left << 6) & 0x01000000)
+                   | ((left << 9) & 0x00200000)
+                   | ((left >> 1) & 0x00100000)
+                   | ((left << 10) & 0x00040000)
+                   | ((left << 2) & 0x00020000)
+                   | ((left >> 10) & 0x00010000)
+                   | ((right >> 13) & 0x00002000)
+                   | ((right >> 4) & 0x00001000)
+                   | ((right << 6) & 0x00000800)
+                   | ((right >> 1) & 0x00000400)
+                   | ((right >> 14) & 0x00000200)
+                   | (right & 0x00000100)
+                   | ((right >> 5) & 0x00000020)
+                   | ((right >> 10) & 0x00000010)
+                   | ((right >> 3) & 0x00000008)
+                   | ((right >> 18) & 0x00000004)
+                   | ((right >> 26) & 0x00000002)
+                   | ((right >> 24) & 0x00000001));
+
+      *subkey++ = (((left << 15) & 0x20000000)
+                   | ((left << 17) & 0x10000000)
+                   | ((left << 10) & 0x08000000)
+                   | ((left << 22) & 0x04000000)
+                   | ((left >> 2) & 0x02000000)
+                   | ((left << 1) & 0x01000000)
+                   | ((left << 16) & 0x00200000)
+                   | ((left << 11) & 0x00100000)
+                   | ((left << 3) & 0x00080000)
+                   | ((left >> 6) & 0x00040000)
+                   | ((left << 15) & 0x00020000)
+                   | ((left >> 4) & 0x00010000)
+                   | ((right >> 2) & 0x00002000)
+                   | ((right << 8) & 0x00001000)
+                   | ((right >> 14) & 0x00000808)
+                   | ((right >> 9) & 0x00000400)
+                   | ((right) & 0x00000200)
+                   | ((right << 7) & 0x00000100)
+                   | ((right >> 7) & 0x00000020)
+                   | ((right >> 3) & 0x00000011)
+                   | ((right << 2) & 0x00000004)
+                   | ((right >> 21) & 0x00000002));
+    }
+}
+
+
+/*
+ * Fill a DES context with subkeys calculated from a 64bit key.
+ * Does not check parity bits, but simply ignore them.
+ * Does not check for weak keys.
+ */
+static int
+des_setkey (struct _des_ctx *ctx, const byte * key)
+{
+  static const char *selftest_failed;
+  int i;
+
+  if (!fips_mode () && !initialized)
+    {
+      initialized = 1;
+      selftest_failed = selftest ();
+
+      if (selftest_failed)
+       log_error ("%s\n", selftest_failed);
+    }
+  if (selftest_failed)
+    return GPG_ERR_SELFTEST_FAILED;
+
+  des_key_schedule (key, ctx->encrypt_subkeys);
+  _gcry_burn_stack (32);
+
+  for(i=0; i<32; i+=2)
+    {
+      ctx->decrypt_subkeys[i]  = ctx->encrypt_subkeys[30-i];
+      ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[31-i];
+    }
+
+  return 0;
+}
+
+
+
+/*
+ * Electronic Codebook Mode DES encryption/decryption of data according
+ * to 'mode'.
+ */
+static int
+des_ecb_crypt (struct _des_ctx *ctx, const byte * from, byte * to, int mode)
+{
+  u32 left, right, work;
+  u32 *keys;
+
+  keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
+
+  READ_64BIT_DATA (from, left, right)
+  INITIAL_PERMUTATION (left, work, right)
+
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+
+  FINAL_PERMUTATION (right, work, left)
+  WRITE_64BIT_DATA (to, right, left)
+
+  return 0;
+}
+
+
+
+/*
+ * Fill a Triple-DES context with subkeys calculated from two 64bit keys.
+ * Does not check the parity bits of the keys, but simply ignore them.
+ * Does not check for weak keys.
+ */
+static int
+tripledes_set2keys (struct _tripledes_ctx *ctx,
+                   const byte * key1,
+                   const byte * key2)
+{
+  int i;
+
+  des_key_schedule (key1, ctx->encrypt_subkeys);
+  des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
+  _gcry_burn_stack (32);
+
+  for(i=0; i<32; i+=2)
+    {
+      ctx->decrypt_subkeys[i]   = ctx->encrypt_subkeys[30-i];
+      ctx->decrypt_subkeys[i+1]  = ctx->encrypt_subkeys[31-i];
+
+      ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i];
+      ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i];
+
+      ctx->encrypt_subkeys[i+64] = ctx->encrypt_subkeys[i];
+      ctx->encrypt_subkeys[i+65] = ctx->encrypt_subkeys[i+1];
+
+      ctx->decrypt_subkeys[i+64] = ctx->decrypt_subkeys[i];
+      ctx->decrypt_subkeys[i+65] = ctx->decrypt_subkeys[i+1];
+    }
+
+  return 0;
+}
+
+
+
+/*
+ * Fill a Triple-DES context with subkeys calculated from three 64bit keys.
+ * Does not check the parity bits of the keys, but simply ignore them.
+ * Does not check for weak keys.
+ */
+static int
+tripledes_set3keys (struct _tripledes_ctx *ctx,
+                   const byte * key1,
+                   const byte * key2,
+                   const byte * key3)
+{
+  static const char *selftest_failed;
+  int i;
+
+  if (!fips_mode () && !initialized)
+    {
+      initialized = 1;
+      selftest_failed = selftest ();
+
+      if (selftest_failed)
+       log_error ("%s\n", selftest_failed);
+    }
+  if (selftest_failed)
+    return GPG_ERR_SELFTEST_FAILED;
+
+  des_key_schedule (key1, ctx->encrypt_subkeys);
+  des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
+  des_key_schedule (key3, &(ctx->encrypt_subkeys[64]));
+  _gcry_burn_stack (32);
+
+  for(i=0; i<32; i+=2)
+    {
+      ctx->decrypt_subkeys[i]   = ctx->encrypt_subkeys[94-i];
+      ctx->decrypt_subkeys[i+1]  = ctx->encrypt_subkeys[95-i];
+
+      ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i];
+      ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i];
+
+      ctx->decrypt_subkeys[i+64] = ctx->encrypt_subkeys[30-i];
+      ctx->decrypt_subkeys[i+65] = ctx->encrypt_subkeys[31-i];
+     }
+
+  return 0;
+}
+
+
+
+/*
+ * Electronic Codebook Mode Triple-DES encryption/decryption of data
+ * according to 'mode'.  Sometimes this mode is named 'EDE' mode
+ * (Encryption-Decryption-Encryption).
+ */
+static int
+tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from,
+                     byte * to, int mode)
+{
+  u32 left, right, work;
+  u32 *keys;
+
+  keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
+
+  READ_64BIT_DATA (from, left, right)
+  INITIAL_PERMUTATION (left, work, right)
+
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+
+  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+
+  FINAL_PERMUTATION (right, work, left)
+  WRITE_64BIT_DATA (to, right, left)
+
+  return 0;
+}
+
+
+
+
+
+/*
+ * Check whether the 8 byte key is weak.
+ * Does not check the parity bits of the key but simple ignore them.
+ */
+static int
+is_weak_key ( const byte *key )
+{
+  byte work[8];
+  int i, left, right, middle, cmp_result;
+
+  /* clear parity bits */
+  for(i=0; i<8; ++i)
+     work[i] = key[i] & 0xfe;
+
+  /* binary search in the weak key table */
+  left = 0;
+  right = 63;
+  while(left <= right)
+    {
+      middle = (left + right) / 2;
+
+      if ( !(cmp_result=working_memcmp(work, weak_keys[middle], 8)) )
+         return -1;
+
+      if ( cmp_result > 0 )
+         left = middle + 1;
+      else
+         right = middle - 1;
+    }
+
+  return 0;
+}
+
+
+
+/*
+ * Performs a selftest of this DES/Triple-DES implementation.
+ * Returns an string with the error text on failure.
+ * Returns NULL if all is ok.
+ */
+static const char *
+selftest (void)
+{
+  /*
+   * Check if 'u32' is really 32 bits wide. This DES / 3DES implementation
+   * need this.
+   */
+  if (sizeof (u32) != 4)
+    return "Wrong word size for DES configured.";
+
+  /*
+   * DES Maintenance Test
+   */
+  {
+    int i;
+    byte key[8] =
+      {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
+    byte input[8] =
+      {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+    byte result[8] =
+      {0x24, 0x6e, 0x9d, 0xb9, 0xc5, 0x50, 0x38, 0x1a};
+    byte temp1[8], temp2[8], temp3[8];
+    des_ctx des;
+
+    for (i = 0; i < 64; ++i)
+      {
+       des_setkey (des, key);
+       des_ecb_encrypt (des, input, temp1);
+       des_ecb_encrypt (des, temp1, temp2);
+       des_setkey (des, temp2);
+       des_ecb_decrypt (des, temp1, temp3);
+       memcpy (key, temp3, 8);
+       memcpy (input, temp1, 8);
+      }
+    if (memcmp (temp3, result, 8))
+      return "DES maintenance test failed.";
+  }
+
+
+  /*
+   * Self made Triple-DES test (Does somebody know an official test?)
+   */
+  {
+    int i;
+    byte input[8] =
+      {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
+    byte key1[8] =
+      {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
+    byte key2[8] =
+      {0x11, 0x22, 0x33, 0x44, 0xff, 0xaa, 0xcc, 0xdd};
+    byte result[8] =
+      {0x7b, 0x38, 0x3b, 0x23, 0xa2, 0x7d, 0x26, 0xd3};
+
+    tripledes_ctx des3;
+
+    for (i = 0; i < 16; ++i)
+      {
+       tripledes_set2keys (des3, key1, key2);
+       tripledes_ecb_encrypt (des3, input, key1);
+       tripledes_ecb_decrypt (des3, input, key2);
+       tripledes_set3keys (des3, key1, input, key2);
+       tripledes_ecb_encrypt (des3, input, input);
+      }
+    if (memcmp (input, result, 8))
+      return "Triple-DES test failed.";
+  }
+  
+  /*
+   * More Triple-DES test.  These are testvectors as used by SSLeay,
+   * thanks to Jeroen C. van Gelderen.
+   */
+  { 
+    struct { byte key[24]; byte plain[8]; byte cipher[8]; } testdata[] = {
+      { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+          0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+          0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01  },
+        { 0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00  },
+        { 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00  }
+      },
+      
+      { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+          0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+          0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01  },
+        { 0x9D,0x64,0x55,0x5A,0x9A,0x10,0xB8,0x52, },
+        { 0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00  }
+      },
+      { { 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E,
+          0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E,
+          0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E  },
+        { 0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A  },
+        { 0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A  }
+      },
+      { { 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6,
+          0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6,
+          0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6  },
+        { 0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2  },
+        { 0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95  }
+      },
+      { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+          0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+          0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF  },
+        { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61  },
+        { 0x3D,0x12,0x4F,0xE2,0x19,0x8B,0xA3,0x18  }
+      },
+      { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+          0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+          0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF  },
+        { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61  },
+        { 0xFB,0xAB,0xA1,0xFF,0x9D,0x05,0xE9,0xB1  }
+      },
+      { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+          0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+          0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10  },
+        { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61  },
+        { 0x18,0xd7,0x48,0xe5,0x63,0x62,0x05,0x72  }
+      },
+      { { 0x03,0x52,0x02,0x07,0x67,0x20,0x82,0x17,
+          0x86,0x02,0x87,0x66,0x59,0x08,0x21,0x98,
+          0x64,0x05,0x6A,0xBD,0xFE,0xA9,0x34,0x57  },
+        { 0x73,0x71,0x75,0x69,0x67,0x67,0x6C,0x65  },
+        { 0xc0,0x7d,0x2a,0x0f,0xa5,0x66,0xfa,0x30  }
+      },
+      { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+          0x80,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+          0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02  },
+        { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00  },
+        { 0xe6,0xe6,0xdd,0x5b,0x7e,0x72,0x29,0x74  }
+      },
+      { { 0x10,0x46,0x10,0x34,0x89,0x98,0x80,0x20,
+          0x91,0x07,0xD0,0x15,0x89,0x19,0x01,0x01,
+          0x19,0x07,0x92,0x10,0x98,0x1A,0x01,0x01  },
+        { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00  },
+        { 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b  }
+      }
+    };
+
+    byte               result[8];
+    int                i;
+    tripledes_ctx      des3;
+
+    for (i=0; i<sizeof(testdata)/sizeof(*testdata); ++i)
+      {
+        tripledes_set3keys (des3, testdata[i].key,
+                            testdata[i].key + 8, testdata[i].key + 16);
+        
+        tripledes_ecb_encrypt (des3, testdata[i].plain, result);
+        if (memcmp (testdata[i].cipher, result, 8))
+          return "Triple-DES SSLeay test failed on encryption.";
+
+        tripledes_ecb_decrypt (des3, testdata[i].cipher, result);
+        if (memcmp (testdata[i].plain, result, 8))
+          return  "Triple-DES SSLeay test failed on decryption.";;
+      }
+  }
+
+  /*
+   * Check the weak key detection. We simply assume that the table
+   * with weak keys is ok and check every key in the table if it is
+   * detected... (This test is a little bit stupid).
+   */
+  {
+    int i;
+    unsigned char *p;
+    gcry_md_hd_t h;
+
+    if (_gcry_md_open (&h, GCRY_MD_SHA1, 0))
+      return "SHA1 not available";
+
+    for (i = 0; i < 64; ++i)
+      _gcry_md_write (h, weak_keys[i], 8);
+    p = _gcry_md_read (h, GCRY_MD_SHA1);
+    i = memcmp (p, weak_keys_chksum, 20);
+    _gcry_md_close (h);
+    if (i)
+      return "weak key table defect";
+
+    for (i = 0; i < 64; ++i)
+      if (!is_weak_key(weak_keys[i]))
+        return "DES weak key detection failed";
+  }
+
+  return 0;
+}
+
+
+static gcry_err_code_t
+do_tripledes_setkey ( void *context, const byte *key, unsigned keylen )
+{
+  struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
+
+  if( keylen != 24 )
+    return GPG_ERR_INV_KEYLEN;
+
+  tripledes_set3keys ( ctx, key, key+8, key+16);
+
+  if (ctx->flags.no_weak_key)
+    ; /* Detection has been disabled.  */
+  else if (is_weak_key (key) || is_weak_key (key+8) || is_weak_key (key+16))
+    {
+      _gcry_burn_stack (64);
+      return GPG_ERR_WEAK_KEY;
+    }
+  _gcry_burn_stack (64);
+
+  return GPG_ERR_NO_ERROR;
+}
+
+
+static gcry_err_code_t
+do_tripledes_set_extra_info (void *context, int what,
+                             const void *buffer, size_t buflen)
+{
+  struct _tripledes_ctx *ctx = (struct _tripledes_ctx *)context;
+  gpg_err_code_t ec = 0;
+
+  (void)buffer;
+  (void)buflen;
+
+  switch (what)
+    {
+    case CIPHER_INFO_NO_WEAK_KEY:
+      ctx->flags.no_weak_key = 1;
+      break;
+
+    default:
+      ec = GPG_ERR_INV_OP; 
+      break;
+    }
+  return ec;
+}
+
+
+static void
+do_tripledes_encrypt( void *context, byte *outbuf, const byte *inbuf )
+{
+  struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
+
+  tripledes_ecb_encrypt ( ctx, inbuf, outbuf );
+  _gcry_burn_stack (32);
+}
+
+static void
+do_tripledes_decrypt( void *context, byte *outbuf, const byte *inbuf )
+{
+  struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
+  tripledes_ecb_decrypt ( ctx, inbuf, outbuf );
+  _gcry_burn_stack (32);
+}
+
+static gcry_err_code_t
+do_des_setkey (void *context, const byte *key, unsigned keylen)
+{
+  struct _des_ctx *ctx = (struct _des_ctx *) context;
+
+  if (keylen != 8)
+    return GPG_ERR_INV_KEYLEN;
+
+  des_setkey (ctx, key);
+
+  if (is_weak_key (key)) {
+    _gcry_burn_stack (64);
+    return GPG_ERR_WEAK_KEY;
+  }
+  _gcry_burn_stack (64);
+
+  return GPG_ERR_NO_ERROR;
+}
+
+
+static void
+do_des_encrypt( void *context, byte *outbuf, const byte *inbuf )
+{
+  struct _des_ctx *ctx = (struct _des_ctx *) context;
+
+  des_ecb_encrypt ( ctx, inbuf, outbuf );
+  _gcry_burn_stack (32);
+}
+
+static void
+do_des_decrypt( void *context, byte *outbuf, const byte *inbuf )
+{
+  struct _des_ctx *ctx = (struct _des_ctx *) context;
+
+  des_ecb_decrypt ( ctx, inbuf, outbuf );
+  _gcry_burn_stack (32);
+}
+
+
+
+\f
+/* 
+     Self-test section.
+ */
+
+
+/* Selftest for TripleDES.  */
+static gpg_err_code_t
+selftest_fips (int extended, selftest_report_func_t report)
+{
+  const char *what;
+  const char *errtxt;
+  
+  (void)extended; /* No extended tests available.  */
+
+  what = "low-level";
+  errtxt = selftest ();
+  if (errtxt)
+    goto failed;
+
+  /* The low-level self-tests are quite extensive and thus we can do
+     without high level tests.  This is also justified because we have
+     no custom block code implementation for 3des but always use the
+     standard high level block code.  */
+
+  return 0; /* Succeeded. */
+
+ failed:
+  if (report)
+    report ("cipher", GCRY_CIPHER_3DES, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+
+/* Run a full self-test for ALGO and return 0 on success.  */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+  gpg_err_code_t ec;
+
+  switch (algo)
+    {
+    case GCRY_CIPHER_3DES:
+      ec = selftest_fips (extended, report);
+      break;
+    default:
+      ec = GPG_ERR_CIPHER_ALGO;
+      break;
+        
+    }
+  return ec;
+}
+
+
+\f
+gcry_cipher_spec_t _gcry_cipher_spec_des =
+  {
+    "DES", NULL, NULL, 8, 64, sizeof (struct _des_ctx),
+    do_des_setkey, do_des_encrypt, do_des_decrypt
+  };
+
+static gcry_cipher_oid_spec_t oids_tripledes[] =
+  {
+    { "1.2.840.113549.3.7", GCRY_CIPHER_MODE_CBC },
+    /* Teletrust specific OID for 3DES. */
+    { "1.3.36.3.1.3.2.1",   GCRY_CIPHER_MODE_CBC },
+    /* pbeWithSHAAnd3_KeyTripleDES_CBC */
+    { "1.2.840.113549.1.12.1.3", GCRY_CIPHER_MODE_CBC },
+    { NULL }
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_tripledes =
+  {
+    "3DES", NULL, oids_tripledes, 8, 192, sizeof (struct _tripledes_ctx),
+    do_tripledes_setkey, do_tripledes_encrypt, do_tripledes_decrypt
+  };
+
+cipher_extra_spec_t _gcry_cipher_extraspec_tripledes = 
+  {
+    run_selftests,
+    do_tripledes_set_extra_info
+  };
diff --git a/grub-core/lib/libgcrypt/cipher/dsa.c b/grub-core/lib/libgcrypt/cipher/dsa.c
new file mode 100644 (file)
index 0000000..100710f
--- /dev/null
@@ -0,0 +1,1181 @@
+/* dsa.c - DSA signature algorithm
+ * Copyright (C) 1998, 2000, 2001, 2002, 2003,
+ *               2006, 2008  Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+
+typedef struct
+{
+  gcry_mpi_t p;            /* prime */
+  gcry_mpi_t q;            /* group order */
+  gcry_mpi_t g;            /* group generator */
+  gcry_mpi_t y;            /* g^x mod p */
+} DSA_public_key;
+
+
+typedef struct
+{
+  gcry_mpi_t p;            /* prime */
+  gcry_mpi_t q;            /* group order */
+  gcry_mpi_t g;            /* group generator */
+  gcry_mpi_t y;            /* g^x mod p */
+  gcry_mpi_t x;            /* secret exponent */
+} DSA_secret_key;
+
+
+/* A structure used to hold domain parameters.  */
+typedef struct
+{
+  gcry_mpi_t p;            /* prime */
+  gcry_mpi_t q;            /* group order */
+  gcry_mpi_t g;            /* group generator */
+} dsa_domain_t;
+
+
+/* A sample 1024 bit DSA key used for the selftests.  */
+static const char sample_secret_key[] =
+"(private-key"
+" (dsa"
+"  (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
+"      96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
+"      CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
+"      44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)"
+"  (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)"
+"  (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
+"      AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
+"      B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
+"      3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)"
+"  (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
+"      A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
+"      6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
+"      42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)"
+"  (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))";
+/* A sample 1024 bit DSA key used for the selftests (public only).  */
+static const char sample_public_key[] = 
+"(public-key"
+" (dsa"
+"  (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
+"      96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
+"      CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
+"      44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)"
+"  (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)"
+"  (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
+"      AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
+"      B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
+"      3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)"
+"  (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
+"      A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
+"      6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
+"      42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))";
+
+
+
+\f
+static gcry_mpi_t gen_k (gcry_mpi_t q);
+static int test_keys (DSA_secret_key *sk, unsigned int qbits);
+static int check_secret_key (DSA_secret_key *sk);
+static gpg_err_code_t generate (DSA_secret_key *sk,
+                                unsigned int nbits,
+                                unsigned int qbits,
+                                int transient_key,
+                                dsa_domain_t *domain,
+                                gcry_mpi_t **ret_factors);
+static void sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
+                  DSA_secret_key *skey);
+static int verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
+                   DSA_public_key *pkey);
+
+static void (*progress_cb) (void *,const char *, int, int, int );
+static void *progress_cb_data;
+
+
+void
+_gcry_register_pk_dsa_progress (void (*cb) (void *, const char *,
+                                            int, int, int),
+                               void *cb_data)
+{
+  progress_cb = cb;
+  progress_cb_data = cb_data;
+}
+
+
+static void
+progress (int c)
+{
+  if (progress_cb)
+    progress_cb (progress_cb_data, "pk_dsa", c, 0, 0);
+}
+
+
+/*
+ * Generate a random secret exponent k less than q.
+ */
+static gcry_mpi_t
+gen_k( gcry_mpi_t q )
+{
+  gcry_mpi_t k = mpi_alloc_secure( mpi_get_nlimbs(q) );
+  unsigned int nbits = mpi_get_nbits(q);
+  unsigned int nbytes = (nbits+7)/8;
+  char *rndbuf = NULL;
+
+  if ( DBG_CIPHER )
+    log_debug("choosing a random k ");
+  for (;;) 
+    {
+      if( DBG_CIPHER )
+        progress('.');
+
+      if ( !rndbuf || nbits < 32 ) 
+        {
+          gcry_free(rndbuf);
+          rndbuf = gcry_random_bytes_secure( (nbits+7)/8, GCRY_STRONG_RANDOM );
+       }
+      else
+        { /* Change only some of the higher bits.  We could improve
+            this by directly requesting more memory at the first call
+            to get_random_bytes() and use this the here maybe it is
+            easier to do this directly in random.c. */
+          char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
+          memcpy( rndbuf,pp, 4 );
+          gcry_free(pp);
+       }
+      _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
+      if ( mpi_test_bit( k, nbits-1 ) )
+        mpi_set_highbit( k, nbits-1 );
+      else
+        {
+          mpi_set_highbit( k, nbits-1 );
+          mpi_clear_bit( k, nbits-1 );
+       }
+
+      if( !(mpi_cmp( k, q ) < 0) ) /* check: k < q */
+        {      
+          if( DBG_CIPHER )
+            progress('+');
+          continue; /* no  */
+        }
+      if( !(mpi_cmp_ui( k, 0 ) > 0) )  /* check: k > 0 */
+        {
+          if( DBG_CIPHER )
+            progress('-');
+          continue; /* no */
+        }
+      break;   /* okay */
+    }
+  gcry_free(rndbuf);
+  if( DBG_CIPHER )
+    progress('\n');
+  
+  return k;
+}
+
+
+/* Check that a freshly generated key actually works.  Returns 0 on success. */
+static int
+test_keys (DSA_secret_key *sk, unsigned int qbits)
+{
+  int result = -1;  /* Default to failure.  */
+  DSA_public_key pk;
+  gcry_mpi_t data  = gcry_mpi_new (qbits);
+  gcry_mpi_t sig_a = gcry_mpi_new (qbits);
+  gcry_mpi_t sig_b = gcry_mpi_new (qbits);
+
+  /* Put the relevant parameters into a public key structure.  */
+  pk.p = sk->p;
+  pk.q = sk->q;
+  pk.g = sk->g;
+  pk.y = sk->y;
+
+  /* Create a random plaintext.  */
+  gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
+
+  /* Sign DATA using the secret key.  */
+  sign (sig_a, sig_b, data, sk);
+
+  /* Verify the signature using the public key.  */
+  if ( !verify (sig_a, sig_b, data, &pk) )
+    goto leave; /* Signature does not match.  */
+
+  /* Modify the data and check that the signing fails.  */
+  gcry_mpi_add_ui (data, data, 1);
+  if ( verify (sig_a, sig_b, data, &pk) )
+    goto leave; /* Signature matches but should not.  */
+
+  result = 0; /* The test succeeded.  */
+
+ leave:
+  gcry_mpi_release (sig_b);
+  gcry_mpi_release (sig_a);
+  gcry_mpi_release (data);
+  return result;
+}
+
+
+
+/*
+   Generate a DSA key pair with a key of size NBITS.  If transient_key
+   is true the key is generated using the standard RNG and not the
+   very secure one.
+
+   Returns: 2 structures filled with all needed values
+           and an array with the n-1 factors of (p-1)
+ */
+static gpg_err_code_t
+generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
+          int transient_key, dsa_domain_t *domain, gcry_mpi_t **ret_factors )
+{
+  gcry_mpi_t p;    /* the prime */
+  gcry_mpi_t q;    /* the 160 bit prime factor */
+  gcry_mpi_t g;    /* the generator */
+  gcry_mpi_t y;    /* g^x mod p */
+  gcry_mpi_t x;    /* the secret exponent */
+  gcry_mpi_t h, e;  /* helper */
+  unsigned char *rndbuf;
+  gcry_random_level_t random_level;
+
+  if (qbits)
+    ; /* Caller supplied qbits.  Use this value.  */
+  else if ( nbits >= 512 && nbits <= 1024 )
+    qbits = 160;
+  else if ( nbits == 2048 )
+    qbits = 224;
+  else if ( nbits == 3072 )
+    qbits = 256;
+  else if ( nbits == 7680 )
+    qbits = 384;
+  else if ( nbits == 15360 )
+    qbits = 512;
+  else
+    return GPG_ERR_INV_VALUE;
+
+  if (qbits < 160 || qbits > 512 || (qbits%8) )
+    return GPG_ERR_INV_VALUE;
+  if (nbits < 2*qbits || nbits > 15360)
+    return GPG_ERR_INV_VALUE;
+
+  if (fips_mode ())
+    {
+      if (nbits < 1024)
+        return GPG_ERR_INV_VALUE;
+      if (transient_key)
+        return GPG_ERR_INV_VALUE;
+    }
+
+  if (domain->p && domain->q && domain->g)
+    {
+      /* Domain parameters are given; use them.  */
+      p = mpi_copy (domain->p);
+      q = mpi_copy (domain->q);
+      g = mpi_copy (domain->g);
+      gcry_assert (mpi_get_nbits (p) == nbits);
+      gcry_assert (mpi_get_nbits (q) == qbits);
+      h = mpi_alloc (0);
+      e = NULL;
+    }
+  else
+    {
+      /* Generate new domain parameters.  */
+      p = _gcry_generate_elg_prime (1, nbits, qbits, NULL, ret_factors);
+      /* Get q out of factors.  */
+      q = mpi_copy ((*ret_factors)[0]);
+      gcry_assert (mpi_get_nbits (q) == qbits);
+
+      /* Find a generator g (h and e are helpers).
+         e = (p-1)/q */
+      e = mpi_alloc (mpi_get_nlimbs (p));
+      mpi_sub_ui (e, p, 1);
+      mpi_fdiv_q (e, e, q);
+      g = mpi_alloc (mpi_get_nlimbs (p));
+      h = mpi_alloc_set_ui (1); /* (We start with 2.) */
+      do
+        {
+          mpi_add_ui (h, h, 1);
+          /* g = h^e mod p */
+          gcry_mpi_powm (g, h, e, p);
+        } 
+      while (!mpi_cmp_ui (g, 1));  /* Continue until g != 1. */
+    }
+
+  /* Select a random number X with the property:
+   *    0 < x < q-1
+   * This must be a very good random number because this is the secret
+   * part.  The random quality depends on the transient_key flag.  */
+  random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
+  if (DBG_CIPHER)
+    log_debug("choosing a random x%s", transient_key? " (transient-key)":"");
+  gcry_assert( qbits >= 160 );
+  x = mpi_alloc_secure( mpi_get_nlimbs(q) );
+  mpi_sub_ui( h, q, 1 );  /* put q-1 into h */
+  rndbuf = NULL;
+  do 
+    {
+      if( DBG_CIPHER )
+        progress('.');
+      if( !rndbuf )
+        rndbuf = gcry_random_bytes_secure ((qbits+7)/8, random_level);
+      else 
+        { /* Change only some of the higher bits (= 2 bytes)*/
+          char *r = gcry_random_bytes_secure (2, random_level);
+          memcpy(rndbuf, r, 2 );
+          gcry_free(r);
+        }
+
+      _gcry_mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
+      mpi_clear_highbit( x, qbits+1 );
+    } 
+  while ( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
+  gcry_free(rndbuf);
+  mpi_free( e );
+  mpi_free( h );
+
+  /* y = g^x mod p */
+  y = mpi_alloc( mpi_get_nlimbs(p) );
+  gcry_mpi_powm( y, g, x, p );
+
+  if( DBG_CIPHER ) 
+    {
+      progress('\n');
+      log_mpidump("dsa  p", p );
+      log_mpidump("dsa  q", q );
+      log_mpidump("dsa  g", g );
+      log_mpidump("dsa  y", y );
+      log_mpidump("dsa  x", x );
+    }
+
+  /* Copy the stuff to the key structures. */
+  sk->p = p;
+  sk->q = q;
+  sk->g = g;
+  sk->y = y;
+  sk->x = x;
+
+  /* Now we can test our keys (this should never fail!). */
+  if ( test_keys (sk, qbits) )
+    {
+      gcry_mpi_release (sk->p); sk->p = NULL;
+      gcry_mpi_release (sk->q); sk->q = NULL;
+      gcry_mpi_release (sk->g); sk->g = NULL;
+      gcry_mpi_release (sk->y); sk->y = NULL;
+      gcry_mpi_release (sk->x); sk->x = NULL;
+      fips_signal_error ("self-test after key generation failed");
+      return GPG_ERR_SELFTEST_FAILED;
+    }
+  return 0;
+}
+
+
+/* Generate a DSA key pair with a key of size NBITS using the
+   algorithm given in FIPS-186-3.  If USE_FIPS186_2 is true,
+   FIPS-186-2 is used and thus the length is restricted to 1024/160.
+   If DERIVEPARMS is not NULL it may contain a seed value.  If domain
+   parameters are specified in DOMAIN, DERIVEPARMS may not be given
+   and NBITS and QBITS must match the specified domain parameters.  */
+static gpg_err_code_t
+generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
+                  gcry_sexp_t deriveparms, int use_fips186_2,
+                  dsa_domain_t *domain,
+                  int *r_counter, void **r_seed, size_t *r_seedlen,
+                  gcry_mpi_t *r_h)
+{
+  gpg_err_code_t ec;
+  struct {
+    gcry_sexp_t sexp;
+    const void *seed;
+    size_t seedlen;
+  } initial_seed = { NULL, NULL, 0 };
+  gcry_mpi_t prime_q = NULL; 
+  gcry_mpi_t prime_p = NULL; 
+  gcry_mpi_t value_g = NULL; /* The generator. */
+  gcry_mpi_t value_y = NULL; /* g^x mod p */
+  gcry_mpi_t value_x = NULL; /* The secret exponent. */
+  gcry_mpi_t value_h = NULL; /* Helper.  */
+  gcry_mpi_t value_e = NULL; /* Helper.  */
+
+  /* Preset return values.  */
+  *r_counter = 0;
+  *r_seed = NULL;
+  *r_seedlen = 0;
+  *r_h = NULL;
+
+  /* Derive QBITS from NBITS if requested  */
+  if (!qbits)
+    {
+      if (nbits == 1024)
+        qbits = 160;
+      else if (nbits == 2048)
+        qbits = 224;
+      else if (nbits == 3072)
+        qbits = 256;
+    }
+
+  /* Check that QBITS and NBITS match the standard.  Note that FIPS
+     186-3 uses N for QBITS and L for NBITS.  */
+  if (nbits == 1024 && qbits == 160)
+    ;
+  else if (nbits == 2048 && qbits == 224)
+    ;
+  else if (nbits == 2048 && qbits == 256)
+    ;
+  else if (nbits == 3072 && qbits == 256)
+    ;
+  else
+    return GPG_ERR_INV_VALUE;
+
+  if (domain->p && domain->q && domain->g)
+    {
+      /* Domain parameters are given; use them.  */
+      prime_p = mpi_copy (domain->p);
+      prime_q = mpi_copy (domain->q);
+      value_g = mpi_copy (domain->g);
+      gcry_assert (mpi_get_nbits (prime_p) == nbits);
+      gcry_assert (mpi_get_nbits (prime_q) == qbits);
+      gcry_assert (!deriveparms);
+      ec = 0;
+    }
+  else
+    {
+      /* Generate new domain parameters.  */
+
+      /* Get an initial seed value.  */
+      if (deriveparms)
+        {
+          initial_seed.sexp = gcry_sexp_find_token (deriveparms, "seed", 0);
+          if (initial_seed.sexp)
+            initial_seed.seed = gcry_sexp_nth_data (initial_seed.sexp, 1,
+                                                    &initial_seed.seedlen);
+        }
+      
+      /* Fixme: Enable 186-3 after it has been approved and after fixing
+         the generation function.  */
+      /*   if (use_fips186_2) */
+      (void)use_fips186_2;
+      ec = _gcry_generate_fips186_2_prime (nbits, qbits, 
+                                           initial_seed.seed, 
+                                           initial_seed.seedlen,
+                                           &prime_q, &prime_p, 
+                                           r_counter,
+                                           r_seed, r_seedlen);
+      /*   else */
+      /*     ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, */
+      /*                                          &prime_q, &prime_p, */
+      /*                                          r_counter, */
+      /*                                          r_seed, r_seedlen, NULL); */
+      gcry_sexp_release (initial_seed.sexp);
+      if (ec)
+        goto leave;
+
+      /* Find a generator g (h and e are helpers).
+         e = (p-1)/q */
+      value_e = mpi_alloc_like (prime_p);
+      mpi_sub_ui (value_e, prime_p, 1);
+      mpi_fdiv_q (value_e, value_e, prime_q );
+      value_g = mpi_alloc_like (prime_p);
+      value_h = mpi_alloc_set_ui (1); 
+      do
+        {
+          mpi_add_ui (value_h, value_h, 1);
+          /* g = h^e mod p */
+          mpi_powm (value_g, value_h, value_e, prime_p);
+        } 
+      while (!mpi_cmp_ui (value_g, 1));  /* Continue until g != 1.  */
+    }
+
+
+  /* Select a random number x with:  0 < x < q  */
+  value_x = gcry_mpi_snew (qbits);
+  do 
+    {
+      if( DBG_CIPHER )
+        progress('.');
+      gcry_mpi_randomize (value_x, qbits, GCRY_VERY_STRONG_RANDOM);
+      mpi_clear_highbit (value_x, qbits+1);
+    } 
+  while (!(mpi_cmp_ui (value_x, 0) > 0 && mpi_cmp (value_x, prime_q) < 0));
+
+  /* y = g^x mod p */
+  value_y = mpi_alloc_like (prime_p);
+  gcry_mpi_powm (value_y, value_g, value_x, prime_p);
+
+  if (DBG_CIPHER) 
+    {
+      progress('\n');
+      log_mpidump("dsa  p", prime_p );
+      log_mpidump("dsa  q", prime_q );
+      log_mpidump("dsa  g", value_g );
+      log_mpidump("dsa  y", value_y );
+      log_mpidump("dsa  x", value_x );
+      log_mpidump("dsa  h", value_h );
+    }
+
+  /* Copy the stuff to the key structures. */
+  sk->p = prime_p; prime_p = NULL;
+  sk->q = prime_q; prime_q = NULL;
+  sk->g = value_g; value_g = NULL;
+  sk->y = value_y; value_y = NULL;
+  sk->x = value_x; value_x = NULL;
+  *r_h = value_h; value_h = NULL;
+
+ leave:
+  gcry_mpi_release (prime_p);
+  gcry_mpi_release (prime_q);
+  gcry_mpi_release (value_g);
+  gcry_mpi_release (value_y);
+  gcry_mpi_release (value_x);
+  gcry_mpi_release (value_h);
+  gcry_mpi_release (value_e);
+
+  /* As a last step test this keys (this should never fail of course). */
+  if (!ec && test_keys (sk, qbits) )
+    {
+      gcry_mpi_release (sk->p); sk->p = NULL;
+      gcry_mpi_release (sk->q); sk->q = NULL;
+      gcry_mpi_release (sk->g); sk->g = NULL;
+      gcry_mpi_release (sk->y); sk->y = NULL;
+      gcry_mpi_release (sk->x); sk->x = NULL;
+      fips_signal_error ("self-test after key generation failed");
+      ec = GPG_ERR_SELFTEST_FAILED;
+    }
+
+  if (ec)
+    {
+      *r_counter = 0;
+      gcry_free (*r_seed); *r_seed = NULL;
+      *r_seedlen = 0;
+      gcry_mpi_release (*r_h); *r_h = NULL;
+    }
+
+  return ec;
+}
+
+
+
+/*
+   Test whether the secret key is valid.
+   Returns: if this is a valid key.
+ */
+static int
+check_secret_key( DSA_secret_key *sk )
+{
+  int rc;
+  gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
+
+  gcry_mpi_powm( y, sk->g, sk->x, sk->p );
+  rc = !mpi_cmp( y, sk->y );
+  mpi_free( y );
+  return rc;
+}
+
+
+
+/*
+   Make a DSA signature from HASH and put it into r and s.
+ */
+static void
+sign(gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_secret_key *skey )
+{
+  gcry_mpi_t k;
+  gcry_mpi_t kinv;
+  gcry_mpi_t tmp;
+
+  /* Select a random k with 0 < k < q */
+  k = gen_k( skey->q );
+
+  /* r = (a^k mod p) mod q */
+  gcry_mpi_powm( r, skey->g, k, skey->p );
+  mpi_fdiv_r( r, r, skey->q );
+
+  /* kinv = k^(-1) mod q */
+  kinv = mpi_alloc( mpi_get_nlimbs(k) );
+  mpi_invm(kinv, k, skey->q );
+
+  /* s = (kinv * ( hash + x * r)) mod q */
+  tmp = mpi_alloc( mpi_get_nlimbs(skey->p) );
+  mpi_mul( tmp, skey->x, r );
+  mpi_add( tmp, tmp, hash );
+  mpi_mulm( s , kinv, tmp, skey->q );
+
+  mpi_free(k);
+  mpi_free(kinv);
+  mpi_free(tmp);
+}
+
+
+/*
+   Returns true if the signature composed from R and S is valid.
+ */
+static int
+verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_public_key *pkey )
+{
+  int rc;
+  gcry_mpi_t w, u1, u2, v;
+  gcry_mpi_t base[3];
+  gcry_mpi_t ex[3];
+
+  if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
+    return 0; /* assertion     0 < r < q  failed */
+  if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
+    return 0; /* assertion     0 < s < q  failed */
+
+  w  = mpi_alloc( mpi_get_nlimbs(pkey->q) );
+  u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
+  u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
+  v  = mpi_alloc( mpi_get_nlimbs(pkey->p) );
+
+  /* w = s^(-1) mod q */
+  mpi_invm( w, s, pkey->q );
+
+  /* u1 = (hash * w) mod q */
+  mpi_mulm( u1, hash, w, pkey->q );
+
+  /* u2 = r * w mod q  */
+  mpi_mulm( u2, r, w, pkey->q );
+
+  /* v =  g^u1 * y^u2 mod p mod q */
+  base[0] = pkey->g; ex[0] = u1;
+  base[1] = pkey->y; ex[1] = u2;
+  base[2] = NULL;    ex[2] = NULL;
+  mpi_mulpowm( v, base, ex, pkey->p );
+  mpi_fdiv_r( v, v, pkey->q );
+
+  rc = !mpi_cmp( v, r );
+
+  mpi_free(w);
+  mpi_free(u1);
+  mpi_free(u2);
+  mpi_free(v);
+
+  return rc;
+}
+
+
+/*********************************************
+ **************  interface  ******************
+ *********************************************/
+
+static gcry_err_code_t
+dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
+                  const gcry_sexp_t genparms,
+                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
+                  gcry_sexp_t *r_extrainfo)
+{
+  gpg_err_code_t ec;
+  DSA_secret_key sk;
+  gcry_sexp_t l1;
+  unsigned int qbits = 0;
+  gcry_sexp_t deriveparms = NULL;
+  gcry_sexp_t seedinfo = NULL;
+  int transient_key = 0;
+  int use_fips186_2 = 0;
+  int use_fips186 = 0;
+  dsa_domain_t domain;
+  (void)algo;    /* No need to check it.  */
+  (void)evalue;  /* Not required for DSA. */
+
+  memset (&domain, 0, sizeof domain);
+
+  if (genparms)
+    {
+      gcry_sexp_t domainsexp;
+  
+      /* Parse the optional qbits element.  */
+      l1 = gcry_sexp_find_token (genparms, "qbits", 0);
+      if (l1)
+        {
+          char buf[50];
+          const char *s;
+          size_t n;
+          
+          s = gcry_sexp_nth_data (l1, 1, &n);
+          if (!s || n >= DIM (buf) - 1 )
+            {
+              gcry_sexp_release (l1);
+              return GPG_ERR_INV_OBJ; /* No value or value too large.  */
+            }
+          memcpy (buf, s, n);
+          buf[n] = 0;
+          qbits = (unsigned int)strtoul (buf, NULL, 0);
+          gcry_sexp_release (l1);
+        }
+
+      /* Parse the optional transient-key flag.  */
+      l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
+      if (l1)
+        {
+          transient_key = 1;
+          gcry_sexp_release (l1);
+        }
+
+      /* Get the optional derive parameters.  */
+      deriveparms = gcry_sexp_find_token (genparms, "derive-parms", 0);
+
+      /* Parse the optional "use-fips186" flags.  */
+      l1 = gcry_sexp_find_token (genparms, "use-fips186", 0);
+      if (l1)
+        {
+          use_fips186 = 1;
+          gcry_sexp_release (l1);
+        }
+      l1 = gcry_sexp_find_token (genparms, "use-fips186-2", 0);
+      if (l1)
+        {
+          use_fips186_2 = 1;
+          gcry_sexp_release (l1);
+        }
+
+      /* Check whether domain parameters are given.  */
+      domainsexp = gcry_sexp_find_token (genparms, "domain", 0);
+      if (domainsexp)
+        {
+          /* DERIVEPARMS can't be used together with domain
+             parameters.  NBITS abnd QBITS may not be specified
+             because there values are derived from the domain
+             parameters.  */
+          if (deriveparms || qbits || nbits)
+            {
+              gcry_sexp_release (domainsexp);
+              gcry_sexp_release (deriveparms);
+              return GPG_ERR_INV_VALUE;
+            }
+          
+          /* Put all domain parameters into the domain object.  */
+          l1 = gcry_sexp_find_token (domainsexp, "p", 0);
+          domain.p = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+          gcry_sexp_release (l1);
+          l1 = gcry_sexp_find_token (domainsexp, "q", 0);
+          domain.q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+          gcry_sexp_release (l1);
+          l1 = gcry_sexp_find_token (domainsexp, "g", 0);
+          domain.g = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+          gcry_sexp_release (l1);
+          gcry_sexp_release (domainsexp);
+
+          /* Check that all domain parameters are available.  */
+          if (!domain.p || !domain.q || !domain.g)
+            {
+              gcry_mpi_release (domain.p);
+              gcry_mpi_release (domain.q);
+              gcry_mpi_release (domain.g);
+              gcry_sexp_release (deriveparms);
+              return GPG_ERR_MISSING_VALUE;
+            }
+
+          /* Get NBITS and QBITS from the domain parameters.  */
+          nbits = mpi_get_nbits (domain.p);
+          qbits = mpi_get_nbits (domain.q);
+        }
+    }
+
+  if (deriveparms || use_fips186 || use_fips186_2 || fips_mode ())
+    {
+      int counter;
+      void *seed;
+      size_t seedlen;
+      gcry_mpi_t h_value;
+
+      ec = generate_fips186 (&sk, nbits, qbits, deriveparms, use_fips186_2,
+                             &domain,
+                             &counter, &seed, &seedlen, &h_value);
+      gcry_sexp_release (deriveparms);
+      if (!ec && h_value)
+        {
+          /* Format the seed-values unless domain parameters are used
+             for which a H_VALUE of NULL is an indication.  */
+          ec = gpg_err_code (gcry_sexp_build 
+                             (&seedinfo, NULL,
+                              "(seed-values(counter %d)(seed %b)(h %m))",
+                              counter, (int)seedlen, seed, h_value));
+          if (ec)
+            {
+              gcry_mpi_release (sk.p); sk.p = NULL;
+              gcry_mpi_release (sk.q); sk.q = NULL;
+              gcry_mpi_release (sk.g); sk.g = NULL;
+              gcry_mpi_release (sk.y); sk.y = NULL;
+              gcry_mpi_release (sk.x); sk.x = NULL;
+            }
+          gcry_free (seed);
+          gcry_mpi_release (h_value);
+        }
+    }
+  else
+    {
+      ec = generate (&sk, nbits, qbits, transient_key, &domain, retfactors);
+    }
+
+  gcry_mpi_release (domain.p);
+  gcry_mpi_release (domain.q);
+  gcry_mpi_release (domain.g);
+
+  if (!ec)
+    {
+      skey[0] = sk.p;
+      skey[1] = sk.q;
+      skey[2] = sk.g;
+      skey[3] = sk.y;
+      skey[4] = sk.x;
+
+      if (!r_extrainfo)
+        {
+          /* Old style interface - return the factors - if any - at
+             retfactors.  */
+        }
+      else if (!*retfactors && !seedinfo)
+        {
+          /* No factors and no seedinfo, thus there is nothing to return.  */
+          *r_extrainfo = NULL;
+        }
+      else
+        {
+          /* Put the factors into extrainfo and set retfactors to NULL
+             to make use of the new interface.  Note that the factors
+             are not confidential thus we can store them in standard
+             memory.  */
+          int nfactors, i, j;
+          char *p;
+          char *format = NULL;
+          void **arg_list = NULL;
+
+          for (nfactors=0; *retfactors && (*retfactors)[nfactors]; nfactors++)
+            ;
+          /* Allocate space for the format string:
+               "(misc-key-info%S(pm1-factors%m))"
+             with one "%m" for each factor and construct it.  */
+          format = gcry_malloc (50 + 2*nfactors);
+          if (!format)
+            ec = gpg_err_code_from_syserror ();
+          else
+            {
+              p = stpcpy (format, "(misc-key-info");
+              if (seedinfo)
+                p = stpcpy (p, "%S");
+              if (nfactors)
+                {
+                  p = stpcpy (p, "(pm1-factors");
+                  for (i=0; i < nfactors; i++)
+                    p = stpcpy (p, "%m");
+                  p = stpcpy (p, ")");
+                }
+              p = stpcpy (p, ")");
+              
+              /* Allocate space for the list of factors plus one for
+                 an S-expression plus an extra NULL entry for safety
+                 and fill it with the factors.  */
+              arg_list = gcry_calloc (nfactors+1+1, sizeof *arg_list);
+              if (!arg_list)
+                ec = gpg_err_code_from_syserror ();
+              else
+                {
+                  i = 0;
+                  if (seedinfo)
+                    arg_list[i++] = &seedinfo;
+                  for (j=0; j < nfactors; j++)
+                    arg_list[i++] = (*retfactors) + j;
+                  arg_list[i] = NULL;
+                  
+                  ec = gpg_err_code (gcry_sexp_build_array 
+                                     (r_extrainfo, NULL, format, arg_list));
+                }
+            }
+
+          gcry_free (arg_list);
+          gcry_free (format);
+          for (i=0; i < nfactors; i++)
+            {
+              gcry_mpi_release ((*retfactors)[i]);
+              (*retfactors)[i] = NULL;
+            }
+          *retfactors = NULL;
+          if (ec)
+            {
+              for (i=0; i < 5; i++)
+                {
+                  gcry_mpi_release (skey[i]);
+                  skey[i] = NULL;
+                }
+            }
+        }
+    }
+
+  gcry_sexp_release (seedinfo);
+  return ec;
+}
+
+
+static gcry_err_code_t
+dsa_generate (int algo, unsigned int nbits, unsigned long evalue,
+              gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+{
+  (void)evalue;
+  return dsa_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
+}
+
+
+
+static gcry_err_code_t
+dsa_check_secret_key (int algo, gcry_mpi_t *skey)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  DSA_secret_key sk;
+
+  (void)algo;
+
+  if ((! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]) || (! skey[4]))
+    err = GPG_ERR_BAD_MPI;
+  else
+    {
+      sk.p = skey[0];
+      sk.q = skey[1];
+      sk.g = skey[2];
+      sk.y = skey[3];
+      sk.x = skey[4];
+      if (! check_secret_key (&sk))
+       err = GPG_ERR_BAD_SECKEY;
+    }
+
+  return err;
+}
+
+
+static gcry_err_code_t
+dsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  DSA_secret_key sk;
+
+  (void)algo;
+
+  if ((! data)
+      || (! skey[0]) || (! skey[1]) || (! skey[2])
+      || (! skey[3]) || (! skey[4]))
+    err = GPG_ERR_BAD_MPI;
+  else
+    {
+      sk.p = skey[0];
+      sk.q = skey[1];
+      sk.g = skey[2];
+      sk.y = skey[3];
+      sk.x = skey[4];
+      resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p));
+      resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
+      sign (resarr[0], resarr[1], data, &sk);
+    }
+  return err;
+}
+
+static gcry_err_code_t
+dsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
+            int (*cmp) (void *, gcry_mpi_t), void *opaquev)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  DSA_public_key pk;
+
+  (void)algo;
+  (void)cmp;
+  (void)opaquev;
+
+  if ((! data[0]) || (! data[1]) || (! hash)
+      || (! pkey[0]) || (! pkey[1]) || (! pkey[2]) || (! pkey[3]))
+    err = GPG_ERR_BAD_MPI;
+  else
+    {
+      pk.p = pkey[0];
+      pk.q = pkey[1];
+      pk.g = pkey[2];
+      pk.y = pkey[3];
+      if (! verify (data[0], data[1], hash, &pk))
+       err = GPG_ERR_BAD_SIGNATURE;
+    }
+  return err;
+}
+
+
+static unsigned int
+dsa_get_nbits (int algo, gcry_mpi_t *pkey)
+{
+  (void)algo;
+
+  return mpi_get_nbits (pkey[0]);
+}
+
+
+\f
+/* 
+     Self-test section.
+ */
+
+static const char *
+selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
+{
+  static const char sample_data[] = 
+    "(data (flags pkcs1)"
+    " (hash sha1 #a0b1c2d3e4f500102030405060708090a1b2c3d4#))";
+  static const char sample_data_bad[] = 
+    "(data (flags pkcs1)"
+    " (hash sha1 #a0b1c2d3e4f510102030405060708090a1b2c3d4#))";
+
+  const char *errtxt = NULL;
+  gcry_error_t err;
+  gcry_sexp_t data = NULL;
+  gcry_sexp_t data_bad = NULL;
+  gcry_sexp_t sig = NULL;
+
+  err = gcry_sexp_sscan (&data, NULL,
+                         sample_data, strlen (sample_data));
+  if (!err)
+    err = gcry_sexp_sscan (&data_bad, NULL, 
+                           sample_data_bad, strlen (sample_data_bad));
+  if (err)
+    {
+      errtxt = "converting data failed";
+      goto leave;
+    }
+
+  err = gcry_pk_sign (&sig, data, skey);
+  if (err)
+    {
+      errtxt = "signing failed";
+      goto leave;
+    }
+  err = gcry_pk_verify (sig, data, pkey);
+  if (err)
+    {
+      errtxt = "verify failed";
+      goto leave;
+    }
+  err = gcry_pk_verify (sig, data_bad, pkey);
+  if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
+    {
+      errtxt = "bad signature not detected";
+      goto leave;
+    }
+
+
+ leave:
+  gcry_sexp_release (sig);
+  gcry_sexp_release (data_bad);
+  gcry_sexp_release (data);
+  return errtxt;
+}
+
+
+static gpg_err_code_t
+selftests_dsa (selftest_report_func_t report)
+{
+  const char *what;
+  const char *errtxt;
+  gcry_error_t err;
+  gcry_sexp_t skey = NULL;
+  gcry_sexp_t pkey = NULL;
+
+  /* Convert the S-expressions into the internal representation.  */
+  what = "convert";
+  err = gcry_sexp_sscan (&skey, NULL, 
+                         sample_secret_key, strlen (sample_secret_key));
+  if (!err)
+    err = gcry_sexp_sscan (&pkey, NULL, 
+                           sample_public_key, strlen (sample_public_key));
+  if (err)
+    {
+      errtxt = gcry_strerror (err);
+      goto failed;
+    }
+
+  what = "key consistency";
+  err = gcry_pk_testkey (skey);
+  if (err)
+    {
+      errtxt = gcry_strerror (err);
+      goto failed;
+    }
+
+  what = "sign";
+  errtxt = selftest_sign_1024 (pkey, skey);
+  if (errtxt)
+    goto failed;
+
+  gcry_sexp_release (pkey);
+  gcry_sexp_release (skey);
+  return 0; /* Succeeded. */
+
+ failed:
+  gcry_sexp_release (pkey);
+  gcry_sexp_release (skey);
+  if (report)
+    report ("pubkey", GCRY_PK_DSA, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Run a full self-test for ALGO and return 0 on success.  */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+  gpg_err_code_t ec;
+
+  (void)extended;
+
+  switch (algo)
+    {
+    case GCRY_PK_DSA:
+      ec = selftests_dsa (report);
+      break;
+    default:
+      ec = GPG_ERR_PUBKEY_ALGO;
+      break;
+        
+    }
+  return ec;
+}
+
+
+
+\f
+static const char *dsa_names[] =
+  {
+    "dsa",
+    "openpgp-dsa",
+    NULL,
+  };
+
+gcry_pk_spec_t _gcry_pubkey_spec_dsa =
+  {
+    "DSA", dsa_names, 
+    "pqgy", "pqgyx", "", "rs", "pqgy",
+    GCRY_PK_USAGE_SIGN,
+    dsa_generate,
+    dsa_check_secret_key,
+    NULL,
+    NULL,
+    dsa_sign,
+    dsa_verify,
+    dsa_get_nbits
+  };
+pk_extra_spec_t _gcry_pubkey_extraspec_dsa = 
+  {
+    run_selftests,
+    dsa_generate_ext
+  };
+
diff --git a/grub-core/lib/libgcrypt/cipher/ecc.c b/grub-core/lib/libgcrypt/cipher/ecc.c
new file mode 100644 (file)
index 0000000..fcbd8e3
--- /dev/null
@@ -0,0 +1,1390 @@
+/* ecc.c  -  Elliptic Curve Cryptography
+   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+
+   This file is part of Libgcrypt.
+  
+   Libgcrypt is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+  
+   Libgcrypt 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 Lesser General Public License for more details.
+  
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+   USA.  */
+
+/* This code is originally based on the Patch 0.1.6 for the gnupg
+   1.4.x branch as retrieved on 2007-03-21 from
+   http://www.calcurco.cat/eccGnuPG/src/gnupg-1.4.6-ecc0.2.0beta1.diff.bz2
+   The original authors are:
+     Written by
+      Sergi Blanch i Torne <d4372211 at alumnes.eup.udl.es>,
+      Ramiro Moreno Chiral <ramiro at eup.udl.es>
+     Maintainers
+      Sergi Blanch i Torne
+      Ramiro Moreno Chiral
+      Mikael Mylnikov (mmr)
+  For use in Libgcrypt the code has been heavily modified and cleaned
+  up. In fact there is not much left of the orginally code except for
+  some variable names and the text book implementaion of the sign and
+  verification algorithms.  The arithmetic functions have entirely
+  been rewritten and moved to mpi/ec.c.  */
+
+
+/* TODO:
+
+  - If we support point compression we need to decide how to compute
+    the keygrip - it should not change due to compression.
+
+  - In mpi/ec.c we use mpi_powm for x^2 mod p: Either implement a
+    special case in mpi_powm or check whether mpi_mulm is faster.
+
+  - Decide whether we should hide the mpi_point_t definition.
+
+  - Support more than just ECDSA.
+*/
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+
+
+/* Definition of a curve.  */
+typedef struct
+{
+  gcry_mpi_t p;   /* Prime specifying the field GF(p).  */
+  gcry_mpi_t a;   /* First coefficient of the Weierstrass equation.  */
+  gcry_mpi_t b;   /* Second coefficient of the Weierstrass equation.  */
+  mpi_point_t G;  /* Base point (generator).  */
+  gcry_mpi_t n;   /* Order of G.  */
+} elliptic_curve_t; 
+
+
+typedef struct
+{
+  elliptic_curve_t E;
+  mpi_point_t Q;  /* Q = [d]G  */
+} ECC_public_key;
+
+typedef struct
+{
+  elliptic_curve_t E;
+  mpi_point_t Q;
+  gcry_mpi_t d;
+} ECC_secret_key;
+
+
+/* This tables defines aliases for curve names.  */
+static const struct
+{
+  const char *name;  /* Our name.  */
+  const char *other; /* Other name. */
+} curve_aliases[] = 
+  {
+    { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID  */
+    { "NIST P-192", "prime192v1" },          /* X9.62 name.  */
+    { "NIST P-192", "secp192r1"  },          /* SECP name.  */
+
+    { "NIST P-224", "secp224r1" },
+    { "NIST P-224", "1.3.132.0.33" },        /* SECP OID.  */
+
+    { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1.  */
+    { "NIST P-256", "prime256v1" },          
+    { "NIST P-256", "secp256r1"  },
+
+    { "NIST P-384", "secp384r1" },
+    { "NIST P-384", "1.3.132.0.34" },       
+
+    { "NIST P-521", "secp521r1" },
+    { "NIST P-521", "1.3.132.0.35" },
+
+    { "brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1" },
+    { "brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3" },
+    { "brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5" },
+    { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7" },
+    { "brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9" },
+    { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11"},
+    { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13"},
+
+    { NULL, NULL}
+  };
+
+
+
+/* This static table defines all available curves.  */
+static const struct
+{
+  const char *desc;           /* Description of the curve.  */
+  unsigned int nbits;         /* Number of bits.  */
+  unsigned int fips:1;        /* True if this is a FIPS140-2 approved curve. */
+  const char  *p;             /* Order of the prime field.  */
+  const char *a, *b;          /* The coefficients. */
+  const char *n;              /* The order of the base point.  */
+  const char *g_x, *g_y;      /* Base point.  */
+} domain_parms[] =
+  {
+    {
+      "NIST P-192", 192, 1,
+      "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
+      "0xfffffffffffffffffffffffffffffffefffffffffffffffc",
+      "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
+      "0xffffffffffffffffffffffff99def836146bc9b1b4d22831",
+
+      "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
+      "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811"
+    },
+    {
+      "NIST P-224", 224, 1,
+      "0xffffffffffffffffffffffffffffffff000000000000000000000001",
+      "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe",
+      "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
+      "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
+
+      "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
+      "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"
+    },
+    {
+      "NIST P-256", 256, 1,
+      "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+      "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
+      "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
+      "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+
+      "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
+      "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
+    },
+    {
+      "NIST P-384", 384, 1,
+      "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
+      "ffffffff0000000000000000ffffffff",
+      "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
+      "ffffffff0000000000000000fffffffc",
+      "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a"
+      "c656398d8a2ed19d2a85c8edd3ec2aef",
+      "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf"
+      "581a0db248b0a77aecec196accc52973",
+
+      "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38"
+      "5502f25dbf55296c3a545e3872760ab7",
+      "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0"
+      "0a60b1ce1d7e819d7a431d7c90ea0e5f"
+    },
+    {
+      "NIST P-521", 521, 1,
+      "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+      "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+      "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+      "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
+      "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10"
+      "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
+      "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+      "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+
+      "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d"
+      "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
+      "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6"
+      "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650"
+    },
+
+    { "brainpoolP160r1", 160, 0, 
+      "0xe95e4a5f737059dc60dfc7ad95b3d8139515620f",
+      "0x340e7be2a280eb74e2be61bada745d97e8f7c300",
+      "0x1e589a8595423412134faa2dbdec95c8d8675e58",
+      "0xe95e4a5f737059dc60df5991d45029409e60fc09",
+      "0xbed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3",
+      "0x1667cb477a1a8ec338f94741669c976316da6321"
+    },
+
+    { "brainpoolP192r1", 192, 0, 
+      "0xc302f41d932a36cda7a3463093d18db78fce476de1a86297",
+      "0x6a91174076b1e0e19c39c031fe8685c1cae040e5c69a28ef",
+      "0x469a28ef7c28cca3dc721d044f4496bcca7ef4146fbf25c9",
+      "0xc302f41d932a36cda7a3462f9e9e916b5be8f1029ac4acc1",
+      "0xc0a0647eaab6a48753b033c56cb0f0900a2f5c4853375fd6",
+      "0x14b690866abd5bb88b5f4828c1490002e6773fa2fa299b8f"
+    },
+
+    { "brainpoolP224r1", 224, 0,
+      "0xd7c134aa264366862a18302575d1d787b09f075797da89f57ec8c0ff",
+      "0x68a5e62ca9ce6c1c299803a6c1530b514e182ad8b0042a59cad29f43",
+      "0x2580f63ccfe44138870713b1a92369e33e2135d266dbb372386c400b",
+      "0xd7c134aa264366862a18302575d0fb98d116bc4b6ddebca3a5a7939f",
+      "0x0d9029ad2c7e5cf4340823b2a87dc68c9e4ce3174c1e6efdee12c07d",
+      "0x58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd"
+    },
+
+    { "brainpoolP256r1", 256, 0,
+      "0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377",
+      "0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9",
+      "0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6",
+      "0xa9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7",
+      "0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262",
+      "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997"
+    },
+
+    { "brainpoolP320r1", 320, 0,
+      "0xd35e472036bc4fb7e13c785ed201e065f98fcfa6f6f40def4f92b9ec7893ec28"
+      "fcd412b1f1b32e27",
+      "0x3ee30b568fbab0f883ccebd46d3f3bb8a2a73513f5eb79da66190eb085ffa9f4"
+      "92f375a97d860eb4",
+      "0x520883949dfdbc42d3ad198640688a6fe13f41349554b49acc31dccd88453981"
+      "6f5eb4ac8fb1f1a6",
+      "0xd35e472036bc4fb7e13c785ed201e065f98fcfa5b68f12a32d482ec7ee8658e9"
+      "8691555b44c59311",
+      "0x43bd7e9afb53d8b85289bcc48ee5bfe6f20137d10a087eb6e7871e2a10a599c7"
+      "10af8d0d39e20611",
+      "0x14fdd05545ec1cc8ab4093247f77275e0743ffed117182eaa9c77877aaac6ac7"
+      "d35245d1692e8ee1"
+    },
+
+    { "brainpoolP384r1", 384, 0,
+      "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123"
+      "acd3a729901d1a71874700133107ec53",
+      "0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f"
+      "8aa5814a503ad4eb04a8c7dd22ce2826",
+      "0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d5"
+      "7cb4390295dbc9943ab78696fa504c11",
+      "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b31f166e6cac0425a7"
+      "cf3ab6af6b7fc3103b883202e9046565",
+      "0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8"
+      "e826e03436d646aaef87b2e247d4af1e",
+      "0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff9912928"
+      "0e4646217791811142820341263c5315"
+    },
+
+    { "brainpoolP512r1", 512, 0,
+      "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330871"
+      "7d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3",
+      "0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc"
+      "2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca",
+      "0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a7"
+      "2bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723",
+      "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330870"
+      "553e5c414ca92619418661197fac10471db1d381085ddaddb58796829ca90069",
+      "0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098e"
+      "ff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822",
+      "0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111"
+      "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892"
+    },
+
+    { NULL, 0, 0, NULL, NULL, NULL, NULL }
+  };
+
+
+/* Registered progress function and its callback value. */
+static void (*progress_cb) (void *, const char*, int, int, int);
+static void *progress_cb_data;
+
+
+#define point_init(a)  _gcry_mpi_ec_point_init ((a))
+#define point_free(a)  _gcry_mpi_ec_point_free ((a))
+
+
+\f
+/* Local prototypes. */
+static gcry_mpi_t gen_k (gcry_mpi_t p, int security_level);
+static void test_keys (ECC_secret_key * sk, unsigned int nbits);
+static int check_secret_key (ECC_secret_key * sk);
+static gpg_err_code_t sign (gcry_mpi_t input, ECC_secret_key *skey,
+                            gcry_mpi_t r, gcry_mpi_t s);
+static gpg_err_code_t verify (gcry_mpi_t input, ECC_public_key *pkey,
+                              gcry_mpi_t r, gcry_mpi_t s);
+
+
+static gcry_mpi_t gen_y_2 (gcry_mpi_t x, elliptic_curve_t * base);
+
+
+
+\f
+void
+_gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
+                                            int, int, int),
+                                void *cb_data)
+{
+  progress_cb = cb;
+  progress_cb_data = cb_data;
+}
+
+/* static void */
+/* progress (int c) */
+/* { */
+/*   if (progress_cb) */
+/*     progress_cb (progress_cb_data, "pk_ecc", c, 0, 0); */
+/* } */
+
+
+\f
+
+/* Set the value from S into D.  */
+static void
+point_set (mpi_point_t *d, mpi_point_t *s)
+{
+  mpi_set (d->x, s->x);
+  mpi_set (d->y, s->y);
+  mpi_set (d->z, s->z);
+}
+
+
+/*
+ * Release a curve object.
+ */
+static void
+curve_free (elliptic_curve_t *E)
+{
+  mpi_free (E->p); E->p = NULL;
+  mpi_free (E->a); E->a = NULL;
+  mpi_free (E->b);  E->b = NULL;
+  point_free (&E->G);
+  mpi_free (E->n);  E->n = NULL;
+}
+
+
+/*
+ * Return a copy of a curve object.
+ */
+static elliptic_curve_t
+curve_copy (elliptic_curve_t E)
+{
+  elliptic_curve_t R;
+
+  R.p = mpi_copy (E.p);
+  R.a = mpi_copy (E.a);
+  R.b = mpi_copy (E.b);
+  point_init (&R.G);
+  point_set (&R.G, &E.G);
+  R.n = mpi_copy (E.n);
+
+  return R;
+}
+
+
+
+/* Helper to scan a hex string. */
+static gcry_mpi_t
+scanval (const char *string)
+{
+  gpg_error_t err;
+  gcry_mpi_t val;
+
+  err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
+  if (err)
+    log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (err));
+  return val;
+}
+
+
+
+\f
+
+/****************
+ * Solve the right side of the equation that defines a curve.
+ */
+static gcry_mpi_t
+gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base)
+{
+  gcry_mpi_t three, x_3, axb, y;
+
+  three = mpi_alloc_set_ui (3);
+  x_3 = mpi_new (0);
+  axb = mpi_new (0);
+  y   = mpi_new (0);
+
+  mpi_powm (x_3, x, three, base->p);  
+  mpi_mulm (axb, base->a, x, base->p); 
+  mpi_addm (axb, axb, base->b, base->p);     
+  mpi_addm (y, x_3, axb, base->p);    
+
+  mpi_free (x_3);
+  mpi_free (axb);
+  mpi_free (three);
+  return y; /* The quadratic value of the coordinate if it exist. */
+}
+
+
+
+
+
+/* Generate a random secret scalar k with an order of p
+
+   At the beginning this was identical to the code is in elgamal.c.
+   Later imporved by mmr.   Further simplified by wk.  */
+static gcry_mpi_t
+gen_k (gcry_mpi_t p, int security_level)
+{
+  gcry_mpi_t k;
+  unsigned int nbits;
+
+  nbits = mpi_get_nbits (p);
+  k = mpi_snew (nbits);
+  if (DBG_CIPHER)
+    log_debug ("choosing a random k of %u bits\n", nbits);
+
+  gcry_mpi_randomize (k, nbits, security_level);
+
+  mpi_mod (k, k, p);  /*  k = k mod p  */
+
+  return k;
+}
+
+/****************
+ * Generate the crypto system setup.
+ * As of now the fix NIST recommended values are used.
+ * The subgroup generator point is in another function: gen_big_point.
+ */
+static gpg_err_code_t
+generate_curve (unsigned int nbits, const char *name, 
+                elliptic_curve_t *curve, unsigned int *r_nbits)
+{
+  int idx, aliasno;
+
+  if (name)
+    {
+      /* First check nor native curves.  */
+      for (idx = 0; domain_parms[idx].desc; idx++)
+        if (!strcmp (name, domain_parms[idx].desc))
+          break;
+      /* If not found consult the alias table.  */
+      if (!domain_parms[idx].desc)
+        {
+          for (aliasno = 0; curve_aliases[aliasno].name; aliasno++)
+            if (!strcmp (name, curve_aliases[aliasno].other))
+              break;
+          if (curve_aliases[aliasno].name)
+            {
+              for (idx = 0; domain_parms[idx].desc; idx++)
+                if (!strcmp (curve_aliases[aliasno].name,
+                             domain_parms[idx].desc))
+                  break;
+            }
+        }
+    }
+  else
+    {
+      for (idx = 0; domain_parms[idx].desc; idx++)
+        if (nbits == domain_parms[idx].nbits)
+          break;
+    }
+  if (!domain_parms[idx].desc)
+    return GPG_ERR_INV_VALUE;
+
+  /* In fips mode we only support NIST curves.  Note that it is
+     possible to bypass this check by specifying the curve parameters
+     directly.  */
+  if (fips_mode () && !domain_parms[idx].fips )
+    return GPG_ERR_NOT_SUPPORTED; 
+  
+
+  *r_nbits = domain_parms[idx].nbits;
+  curve->p = scanval (domain_parms[idx].p);
+  curve->a = scanval (domain_parms[idx].a);
+  curve->b = scanval (domain_parms[idx].b);
+  curve->n = scanval (domain_parms[idx].n);
+  curve->G.x = scanval (domain_parms[idx].g_x);
+  curve->G.y = scanval (domain_parms[idx].g_y);
+  curve->G.z = mpi_alloc_set_ui (1);
+
+  return 0;
+}
+
+
+/*
+ * First obtain the setup.  Over the finite field randomize an scalar
+ * secret value, and calculate the public point.
+ */
+static gpg_err_code_t
+generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
+              gcry_mpi_t g_x, gcry_mpi_t g_y,
+              gcry_mpi_t q_x, gcry_mpi_t q_y)
+{
+  gpg_err_code_t err;
+  elliptic_curve_t E;
+  gcry_mpi_t d;
+  mpi_point_t Q;
+  mpi_ec_t ctx;
+
+  err = generate_curve (nbits, name, &E, &nbits);
+  if (err)
+    return err;
+
+  if (DBG_CIPHER)
+    {
+      log_mpidump ("ecc generation   p", E.p);
+      log_mpidump ("ecc generation   a", E.a);
+      log_mpidump ("ecc generation   b", E.b);
+      log_mpidump ("ecc generation   n", E.n);
+      log_mpidump ("ecc generation  Gx", E.G.x);
+      log_mpidump ("ecc generation  Gy", E.G.y);
+      log_mpidump ("ecc generation  Gz", E.G.z);
+    }
+
+  if (DBG_CIPHER)
+    log_debug ("choosing a random x of size %u\n", nbits);
+  d = gen_k (E.n, GCRY_VERY_STRONG_RANDOM); 
+
+  /* Compute Q.  */
+  point_init (&Q);
+  ctx = _gcry_mpi_ec_init (E.p, E.a);
+  _gcry_mpi_ec_mul_point (&Q, d, &E.G, ctx);
+
+  /* Copy the stuff to the key structures. */
+  sk->E.p = mpi_copy (E.p);
+  sk->E.a = mpi_copy (E.a);
+  sk->E.b = mpi_copy (E.b);
+  point_init (&sk->E.G);
+  point_set (&sk->E.G, &E.G);
+  sk->E.n = mpi_copy (E.n);
+  point_init (&sk->Q);
+  point_set (&sk->Q, &Q);
+  sk->d    = mpi_copy (d);
+  /* We also return copies of G and Q in affine coordinates if
+     requested.  */
+  if (g_x && g_y)
+    {
+      if (_gcry_mpi_ec_get_affine (g_x, g_y, &sk->E.G, ctx))
+        log_fatal ("ecc generate: Failed to get affine coordinates\n");
+    }
+  if (q_x && q_y)
+    {
+      if (_gcry_mpi_ec_get_affine (q_x, q_y, &sk->Q, ctx))
+        log_fatal ("ecc generate: Failed to get affine coordinates\n");
+    }
+  _gcry_mpi_ec_free (ctx);
+
+  point_free (&Q);
+  mpi_free (d);
+  curve_free (&E);
+
+  /* Now we can test our keys (this should never fail!). */
+  test_keys (sk, nbits - 64);
+
+  return 0;
+}
+
+
+/****************
+ * To verify correct skey it use a random information.
+ * First, encrypt and decrypt this dummy value,
+ * test if the information is recuperated.
+ * Second, test with the sign and verify functions.
+ */
+static void
+test_keys (ECC_secret_key *sk, unsigned int nbits)
+{
+  ECC_public_key pk;
+  gcry_mpi_t test = mpi_new (nbits);
+  mpi_point_t R_;
+  gcry_mpi_t c = mpi_new (nbits);
+  gcry_mpi_t out = mpi_new (nbits);
+  gcry_mpi_t r = mpi_new (nbits);
+  gcry_mpi_t s = mpi_new (nbits);
+
+  if (DBG_CIPHER)
+    log_debug ("Testing key.\n");
+
+  point_init (&R_);
+
+  pk.E = curve_copy (sk->E);
+  point_init (&pk.Q);
+  point_set (&pk.Q, &sk->Q);
+
+  gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
+
+  if (sign (test, sk, r, s) )
+    log_fatal ("ECDSA operation: sign failed\n");
+
+  if (verify (test, &pk, r, s))
+    {
+      log_fatal ("ECDSA operation: sign, verify failed\n");
+    }
+
+  if (DBG_CIPHER)
+    log_debug ("ECDSA operation: sign, verify ok.\n");
+
+  point_free (&pk.Q);
+  curve_free (&pk.E);
+
+  point_free (&R_);
+  mpi_free (s);
+  mpi_free (r);
+  mpi_free (out);
+  mpi_free (c);
+  mpi_free (test);
+}
+
+/****************
+ * To check the validity of the value, recalculate the correspondence
+ * between the public value and the secret one.
+ */
+static int
+check_secret_key (ECC_secret_key * sk)
+{
+  mpi_point_t Q;
+  gcry_mpi_t y_2, y2 = mpi_alloc (0);
+  mpi_ec_t ctx;
+
+  /* ?primarity test of 'p' */
+  /*  (...) //!! */
+  /* G in E(F_p) */
+  y_2 = gen_y_2 (sk->E.G.x, &sk->E);   /*  y^2=x^3+a*x+b */
+  mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p);      /*  y^2=y*y */
+  if (mpi_cmp (y_2, y2))
+    {
+      if (DBG_CIPHER)
+        log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
+      return (1);
+    }
+  /* G != PaI */
+  if (!mpi_cmp_ui (sk->E.G.z, 0))
+    {
+      if (DBG_CIPHER)
+        log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
+      return (1);
+    }
+
+  point_init (&Q);
+  ctx = _gcry_mpi_ec_init (sk->E.p, sk->E.a);
+  _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx);
+  if (mpi_cmp_ui (Q.z, 0))
+    {
+      if (DBG_CIPHER)
+        log_debug ("check_secret_key: E is not a curve of order n\n");
+      point_free (&Q);
+      _gcry_mpi_ec_free (ctx);
+      return 1;
+    }
+  /* pubkey cannot be PaI */
+  if (!mpi_cmp_ui (sk->Q.z, 0))
+    {
+      if (DBG_CIPHER)
+        log_debug ("Bad check: Q can not be a Point at Infinity!\n");
+      _gcry_mpi_ec_free (ctx);
+      return (1);
+    }
+  /* pubkey = [d]G over E */
+  _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx);
+  if ((Q.x == sk->Q.x) && (Q.y == sk->Q.y) && (Q.z == sk->Q.z))
+    {
+      if (DBG_CIPHER)
+        log_debug
+          ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
+      _gcry_mpi_ec_free (ctx);
+      return (1);
+    }
+  _gcry_mpi_ec_free (ctx);
+  point_free (&Q);
+  return 0;
+}
+
+
+/*
+ * Return the signature struct (r,s) from the message hash.  The caller
+ * must have allocated R and S.
+ */
+static gpg_err_code_t
+sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s)
+{
+  gpg_err_code_t err = 0;
+  gcry_mpi_t k, dr, sum, k_1, x;
+  mpi_point_t I;
+  mpi_ec_t ctx;
+
+  k = NULL;
+  dr = mpi_alloc (0);
+  sum = mpi_alloc (0);
+  k_1 = mpi_alloc (0);
+  x = mpi_alloc (0);
+  point_init (&I);
+
+  mpi_set_ui (s, 0);
+  mpi_set_ui (r, 0);
+
+  ctx = _gcry_mpi_ec_init (skey->E.p, skey->E.a);
+
+  while (!mpi_cmp_ui (s, 0)) /* s == 0 */
+    {
+      while (!mpi_cmp_ui (r, 0)) /* r == 0 */
+        {
+          /* Note, that we are guaranteed to enter this loop at least
+             once because r has been intialized to 0.  We can't use a
+             do_while because we want to keep the value of R even if S
+             has to be recomputed.  */
+          mpi_free (k);
+          k = gen_k (skey->E.n, GCRY_STRONG_RANDOM);
+          _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx); 
+          if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx))
+            {
+              if (DBG_CIPHER)
+                log_debug ("ecc sign: Failed to get affine coordinates\n");
+              err = GPG_ERR_BAD_SIGNATURE;
+              goto leave;
+            }
+          mpi_mod (r, x, skey->E.n);  /* r = x mod n */
+        }
+      mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n  */
+      mpi_addm (sum, input, dr, skey->E.n); /* sum = hash + (d*r) mod n  */
+      mpi_invm (k_1, k, skey->E.n);         /* k_1 = k^(-1) mod n  */
+      mpi_mulm (s, k_1, sum, skey->E.n);    /* s = k^(-1)*(hash+(d*r)) mod n */
+    }
+
+ leave:
+  _gcry_mpi_ec_free (ctx);
+  point_free (&I);
+  mpi_free (x);
+  mpi_free (k_1);
+  mpi_free (sum);
+  mpi_free (dr);
+  mpi_free (k);
+
+  return err;
+}
+
+/*
+ * Check if R and S verifies INPUT.
+ */
+static gpg_err_code_t
+verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s)
+{
+  gpg_err_code_t err = 0;
+  gcry_mpi_t h, h1, h2, x, y;
+  mpi_point_t Q, Q1, Q2;
+  mpi_ec_t ctx;
+
+  if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) )
+    return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n  failed.  */
+  if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) )
+    return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n  failed.  */
+
+  h  = mpi_alloc (0);
+  h1 = mpi_alloc (0);
+  h2 = mpi_alloc (0);
+  x = mpi_alloc (0);
+  y = mpi_alloc (0);
+  point_init (&Q);
+  point_init (&Q1);
+  point_init (&Q2);
+
+  ctx = _gcry_mpi_ec_init (pkey->E.p, pkey->E.a);
+
+  /* h  = s^(-1) (mod n) */
+  mpi_invm (h, s, pkey->E.n);
+/*   log_mpidump ("   h", h); */
+  /* h1 = hash * s^(-1) (mod n) */
+  mpi_mulm (h1, input, h, pkey->E.n);
+/*   log_mpidump ("  h1", h1); */
+  /* Q1 = [ hash * s^(-1) ]G  */
+  _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx);
+/*   log_mpidump ("Q1.x", Q1.x); */
+/*   log_mpidump ("Q1.y", Q1.y); */
+/*   log_mpidump ("Q1.z", Q1.z); */
+  /* h2 = r * s^(-1) (mod n) */
+  mpi_mulm (h2, r, h, pkey->E.n);
+/*   log_mpidump ("  h2", h2); */
+  /* Q2 = [ r * s^(-1) ]Q */
+  _gcry_mpi_ec_mul_point (&Q2, h2, &pkey->Q, ctx);
+/*   log_mpidump ("Q2.x", Q2.x); */
+/*   log_mpidump ("Q2.y", Q2.y); */
+/*   log_mpidump ("Q2.z", Q2.z); */
+  /* Q  = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */
+  _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx);
+/*   log_mpidump (" Q.x", Q.x); */
+/*   log_mpidump (" Q.y", Q.y); */
+/*   log_mpidump (" Q.z", Q.z); */
+
+  if (!mpi_cmp_ui (Q.z, 0))
+    {
+      if (DBG_CIPHER)
+          log_debug ("ecc verify: Rejected\n");
+      err = GPG_ERR_BAD_SIGNATURE;
+      goto leave;
+    }
+  if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx))
+    {
+      if (DBG_CIPHER)
+        log_debug ("ecc verify: Failed to get affine coordinates\n");
+      err = GPG_ERR_BAD_SIGNATURE;
+      goto leave;
+    }
+  mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */
+  if (mpi_cmp (x, r))   /* x != r */
+    {
+      if (DBG_CIPHER)
+        {
+          log_mpidump ("   x", x);
+          log_mpidump ("   y", y);
+          log_mpidump ("   r", r);
+          log_mpidump ("   s", s);
+          log_debug ("ecc verify: Not verified\n");
+        }
+      err = GPG_ERR_BAD_SIGNATURE;
+      goto leave;
+    }
+  if (DBG_CIPHER)
+    log_debug ("ecc verify: Accepted\n");
+
+ leave:
+  _gcry_mpi_ec_free (ctx);
+  point_free (&Q2);
+  point_free (&Q1);
+  point_free (&Q);
+  mpi_free (y);
+  mpi_free (x);
+  mpi_free (h2);
+  mpi_free (h1);
+  mpi_free (h);
+  return err;
+}
+
+
+
+/*********************************************
+ **************  interface  ******************
+ *********************************************/
+static gcry_mpi_t
+ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p)
+{
+  gpg_error_t err;
+  int pbytes = (mpi_get_nbits (p)+7)/8;
+  size_t n;
+  unsigned char *buf, *ptr;
+  gcry_mpi_t result;
+
+  buf = gcry_xmalloc ( 1 + 2*pbytes );
+  *buf = 04; /* Uncompressed point.  */
+  ptr = buf+1;
+  err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, x);
+  if (err)
+    log_fatal ("mpi_print failed: %s\n", gpg_strerror (err));
+  if (n < pbytes)
+    {
+      memmove (ptr+(pbytes-n), ptr, n);
+      memset (ptr, 0, (pbytes-n));
+    }
+  ptr += pbytes;
+  err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, y);
+  if (err)
+    log_fatal ("mpi_print failed: %s\n", gpg_strerror (err));
+  if (n < pbytes)
+    {
+      memmove (ptr+(pbytes-n), ptr, n);
+      memset (ptr, 0, (pbytes-n));
+    }
+  
+  err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, buf, 1+2*pbytes, NULL);
+  if (err)
+    log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err));
+  gcry_free (buf);
+
+  mpi_free (x);
+  mpi_free (y);
+
+  return result;
+}
+
+/* RESULT must have been initialized and is set on success to the
+   point given by VALUE.  */
+static gcry_error_t
+os2ec (mpi_point_t *result, gcry_mpi_t value)
+{
+  gcry_error_t err;
+  size_t n;
+  unsigned char *buf;
+  gcry_mpi_t x, y;
+
+  n = (mpi_get_nbits (value)+7)/8;
+  buf = gcry_xmalloc (n);
+  err = gcry_mpi_print (GCRYMPI_FMT_USG, buf, n, &n, value);
+  if (err)
+    {
+      gcry_free (buf);
+      return err;
+    }
+  if (n < 1) 
+    {
+      gcry_free (buf);
+      return GPG_ERR_INV_OBJ;
+    }
+  if (*buf != 4)
+    {
+      gcry_free (buf);
+      return GPG_ERR_NOT_IMPLEMENTED; /* No support for point compression.  */
+    }
+  if ( ((n-1)%2) ) 
+    {
+      gcry_free (buf);
+      return GPG_ERR_INV_OBJ;
+    }
+  n = (n-1)/2;
+  err = gcry_mpi_scan (&x, GCRYMPI_FMT_USG, buf+1, n, NULL);
+  if (err)
+    {
+      gcry_free (buf);
+      return err;
+    }
+  err = gcry_mpi_scan (&y, GCRYMPI_FMT_USG, buf+1+n, n, NULL);
+  gcry_free (buf);
+  if (err)
+    {
+      mpi_free (x);
+      return err;
+    }
+
+  mpi_set (result->x, x);
+  mpi_set (result->y, y);
+  mpi_set_ui (result->z, 1);
+
+  mpi_free (x);
+  mpi_free (y);
+  
+  return 0;
+}
+
+
+/* Extended version of ecc_generate.  */
+static gcry_err_code_t
+ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
+                  const gcry_sexp_t genparms,
+                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
+                  gcry_sexp_t *r_extrainfo)
+{
+  gpg_err_code_t ec;
+  ECC_secret_key sk;
+  gcry_mpi_t g_x, g_y, q_x, q_y;
+  char *curve_name = NULL;
+  gcry_sexp_t l1;
+
+  (void)algo;
+  (void)evalue;
+  (void)r_extrainfo;
+
+  if (genparms)
+    {
+      /* Parse the optional "curve" parameter. */
+      l1 = gcry_sexp_find_token (genparms, "curve", 0);
+      if (l1)
+        {
+          curve_name = _gcry_sexp_nth_string (l1, 1);
+          gcry_sexp_release (l1);
+          if (!curve_name)
+            return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
+        }
+    }
+
+  /* NBITS is required if no curve name has been given.  */
+  if (!nbits && !curve_name)
+    return GPG_ERR_NO_OBJ; /* No NBITS parameter. */
+
+  g_x = mpi_new (0);
+  g_y = mpi_new (0);
+  q_x = mpi_new (0);
+  q_y = mpi_new (0);
+  ec = generate_key (&sk, nbits, curve_name, g_x, g_y, q_x, q_y);
+  gcry_free (curve_name);
+  if (ec)
+    return ec;
+
+  skey[0] = sk.E.p;
+  skey[1] = sk.E.a;
+  skey[2] = sk.E.b;
+  /* The function ec2os releases g_x and g_y.  */
+  skey[3] = ec2os (g_x, g_y, sk.E.p);
+  skey[4] = sk.E.n;
+  /* The function ec2os releases g_x and g_y.  */
+  skey[5] = ec2os (q_x, q_y, sk.E.p);
+  skey[6] = sk.d;
+
+  point_free (&sk.E.G);
+  point_free (&sk.Q);
+
+  /* Make an empty list of factors.  */
+  *retfactors = gcry_calloc ( 1, sizeof **retfactors );
+  if (!*retfactors)
+    return gpg_err_code_from_syserror ();
+
+  return 0;
+}
+
+
+static gcry_err_code_t
+ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
+              gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+{
+  (void)evalue;
+  return ecc_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
+}
+
+
+/* Return the parameters of the curve NAME.  */
+static gcry_err_code_t
+ecc_get_param (const char *name, gcry_mpi_t *pkey)
+{
+  gpg_err_code_t err;
+  unsigned int nbits;
+  elliptic_curve_t E;
+  mpi_ec_t ctx;
+  gcry_mpi_t g_x, g_y;
+  
+  err = generate_curve (0, name, &E, &nbits);
+  if (err)
+    return err;
+
+  g_x = mpi_new (0);
+  g_y = mpi_new (0);
+  ctx = _gcry_mpi_ec_init (E.p, E.a);
+  if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx))
+    log_fatal ("ecc get param: Failed to get affine coordinates\n");
+  _gcry_mpi_ec_free (ctx);
+  point_free (&E.G);
+
+  pkey[0] = E.p;
+  pkey[1] = E.a;
+  pkey[2] = E.b;
+  pkey[3] = ec2os (g_x, g_y, E.p);
+  pkey[4] = E.n;
+  pkey[5] = NULL;
+
+  return 0;
+}
+
+
+static gcry_err_code_t
+ecc_check_secret_key (int algo, gcry_mpi_t *skey)
+{
+  gpg_err_code_t err;
+  ECC_secret_key sk;
+
+  (void)algo;
+
+  if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5]
+      || !skey[6] || !skey[7] || !skey[8] || !skey[9] || !skey[10])
+    return GPG_ERR_BAD_MPI;
+
+  sk.E.p = skey[0];
+  sk.E.a = skey[1];
+  sk.E.b = skey[2];
+  point_init (&sk.E.G);
+  err = os2ec (&sk.E.G, skey[3]);
+  if (err)
+    {
+      point_free (&sk.E.G);
+      return err;
+    }
+  sk.E.n = skey[4];
+  point_init (&sk.Q);
+  err = os2ec (&sk.Q, skey[5]);
+  if (err)
+    {
+      point_free (&sk.E.G);
+      point_free (&sk.Q);
+      return err;
+    }
+
+  sk.d = skey[6];
+
+  if (check_secret_key (&sk))
+    {
+      point_free (&sk.E.G);
+      point_free (&sk.Q);
+      return GPG_ERR_BAD_SECKEY;
+    }
+  point_free (&sk.E.G);
+  point_free (&sk.Q);
+  return 0;
+}
+
+
+static gcry_err_code_t
+ecc_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
+{
+  gpg_err_code_t err;
+  ECC_secret_key sk;
+
+  (void)algo;
+
+  if (!data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
+      || !skey[5] || !skey[6] )
+    return GPG_ERR_BAD_MPI;
+
+  sk.E.p = skey[0];
+  sk.E.a = skey[1];
+  sk.E.b = skey[2];
+  point_init (&sk.E.G);
+  err = os2ec (&sk.E.G, skey[3]);
+  if (err)
+    {
+      point_free (&sk.E.G);
+      return err;
+    }
+  sk.E.n = skey[4];
+  point_init (&sk.Q);
+  err = os2ec (&sk.Q, skey[5]);
+  if (err)
+    {
+      point_free (&sk.E.G);
+      point_free (&sk.Q);
+      return err;
+    }
+  sk.d = skey[6];
+
+  resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
+  resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
+  err = sign (data, &sk, resarr[0], resarr[1]);
+  if (err)
+    {
+      mpi_free (resarr[0]);
+      mpi_free (resarr[1]);
+      resarr[0] = NULL; /* Mark array as released.  */
+    }
+  point_free (&sk.E.G);
+  point_free (&sk.Q);
+  return err;
+}
+
+static gcry_err_code_t
+ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
+            int (*cmp)(void *, gcry_mpi_t), void *opaquev)
+{
+  gpg_err_code_t err;
+  ECC_public_key pk;
+
+  (void)algo;
+  (void)cmp;
+  (void)opaquev;
+
+  if (!data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2]
+      || !pkey[3] || !pkey[4] || !pkey[5] )
+    return GPG_ERR_BAD_MPI;
+
+  pk.E.p = pkey[0];
+  pk.E.a = pkey[1];
+  pk.E.b = pkey[2];
+  point_init (&pk.E.G);
+  err = os2ec (&pk.E.G, pkey[3]);
+  if (err)
+    {
+      point_free (&pk.E.G);
+      return err;
+    }
+  pk.E.n = pkey[4];
+  point_init (&pk.Q);
+  err = os2ec (&pk.Q, pkey[5]);
+  if (err)
+    {
+      point_free (&pk.E.G);
+      point_free (&pk.Q);
+      return err;
+    }
+
+  err = verify (hash, &pk, data[0], data[1]);
+
+  point_free (&pk.E.G);
+  point_free (&pk.Q);
+  return err;
+}
+
+
+
+static unsigned int
+ecc_get_nbits (int algo, gcry_mpi_t *pkey)
+{
+  (void)algo;
+
+  return mpi_get_nbits (pkey[0]);
+}
+
+
+
+/* See rsa.c for a description of this function.  */
+static gpg_err_code_t
+compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
+{
+  static const char names[] = "pabgnq";
+  gpg_err_code_t ec = 0;
+  gcry_sexp_t l1;
+  gcry_mpi_t values[6];
+  int idx;
+
+  /* Clear the values for easier error cleanup.  */
+  for (idx=0; idx < 6; idx++)
+    values[idx] = NULL;
+    
+  /* Fill values with all available parameters.  */
+  for (idx=0; idx < 6; idx++)
+    {
+      l1 = gcry_sexp_find_token (keyparam, names+idx, 1);
+      if (l1)
+        {
+          values[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+         gcry_sexp_release (l1);
+         if (!values[idx])
+            {
+              ec = GPG_ERR_INV_OBJ;
+              goto leave;
+            }
+       }
+    }
+  
+  /* Check whether a curve parameter is available and use that to fill
+     in missing values.  */
+  l1 = gcry_sexp_find_token (keyparam, "curve", 5);
+  if (l1)
+    {
+      char *curve;
+      gcry_mpi_t tmpvalues[6];
+      
+      for (idx = 0; idx < 6; idx++)
+        tmpvalues[idx] = NULL;
+
+      curve = _gcry_sexp_nth_string (l1, 1);
+      if (!curve)
+        {
+          ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
+          goto leave;
+        }
+      ec = ecc_get_param (curve, tmpvalues);
+      gcry_free (curve);
+      if (ec)
+        goto leave;
+
+      for (idx = 0; idx < 6; idx++)
+        {
+          if (!values[idx])
+            values[idx] = tmpvalues[idx];
+          else
+            mpi_free (tmpvalues[idx]);
+        }
+    }
+
+  /* Check that all parameters are known and normalize all MPIs (that
+     should not be required but we use an internal fucntion later and
+     thus we better make 100% sure that they are normalized). */
+  for (idx = 0; idx < 6; idx++)
+    if (!values[idx])
+      {
+        ec = GPG_ERR_NO_OBJ;
+        goto leave;
+      }
+    else
+      _gcry_mpi_normalize (values[idx]);
+      
+  /* Hash them all.  */
+  for (idx = 0; idx < 6; idx++)
+    {
+      char buf[30];
+      unsigned char *rawmpi;
+      unsigned int rawmpilen;
+      
+      rawmpi = _gcry_mpi_get_buffer (values[idx], &rawmpilen, NULL);
+      if (!rawmpi)
+        {
+          ec = gpg_err_code_from_syserror ();
+          goto leave;
+        }
+      snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
+      gcry_md_write (md, buf, strlen (buf));
+      gcry_md_write (md, rawmpi, rawmpilen);
+      gcry_md_write (md, ")", 1);
+      gcry_free (rawmpi);
+    }
+
+ leave:
+  for (idx = 0; idx < 6; idx++)
+    _gcry_mpi_release (values[idx]);
+  
+  return ec;
+}
+
+
+
+
+\f
+/* 
+     Self-test section.
+ */
+
+
+static gpg_err_code_t
+selftests_ecdsa (selftest_report_func_t report)
+{
+  const char *what;
+  const char *errtxt;
+  
+  what = "low-level";
+  errtxt = NULL; /*selftest ();*/
+  if (errtxt)
+    goto failed;
+
+  /* FIXME:  need more tests.  */
+
+  return 0; /* Succeeded. */
+
+ failed:
+  if (report)
+    report ("pubkey", GCRY_PK_ECDSA, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Run a full self-test for ALGO and return 0 on success.  */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+  gpg_err_code_t ec;
+
+  (void)extended;
+
+  switch (algo)
+    {
+    case GCRY_PK_ECDSA:
+      ec = selftests_ecdsa (report);
+      break;
+    default:
+      ec = GPG_ERR_PUBKEY_ALGO;
+      break;
+        
+    }
+  return ec;
+}
+
+
+
+\f
+static const char *ecdsa_names[] =
+  {
+    "ecdsa",
+    "ecc",
+    NULL,
+  };
+
+gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
+  {
+    "ECDSA", ecdsa_names,
+    "pabgnq", "pabgnqd", "", "rs", "pabgnq",
+    GCRY_PK_USAGE_SIGN,
+    ecc_generate,
+    ecc_check_secret_key,
+    NULL,
+    NULL,
+    ecc_sign,
+    ecc_verify,
+    ecc_get_nbits
+  };
+
+pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa = 
+  {
+    run_selftests,
+    ecc_generate_ext,
+    compute_keygrip,
+    ecc_get_param
+  };
+
diff --git a/grub-core/lib/libgcrypt/cipher/elgamal.c b/grub-core/lib/libgcrypt/cipher/elgamal.c
new file mode 100644 (file)
index 0000000..0b0c07c
--- /dev/null
@@ -0,0 +1,846 @@
+/* Elgamal.c  -  Elgamal Public Key encryption
+ * Copyright (C) 1998, 2000, 2001, 2002, 2003,
+ *               2008  Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * For a description of the algorithm, see:
+ *   Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
+ *   ISBN 0-471-11709-9. Pages 476 ff.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+
+typedef struct
+{
+  gcry_mpi_t p;            /* prime */
+  gcry_mpi_t g;            /* group generator */
+  gcry_mpi_t y;            /* g^x mod p */
+} ELG_public_key;
+
+
+typedef struct
+{
+  gcry_mpi_t p;            /* prime */
+  gcry_mpi_t g;            /* group generator */
+  gcry_mpi_t y;            /* g^x mod p */
+  gcry_mpi_t x;            /* secret exponent */
+} ELG_secret_key;
+
+
+static int test_keys (ELG_secret_key *sk, unsigned int nbits, int nodie);
+static gcry_mpi_t gen_k (gcry_mpi_t p, int small_k);
+static void generate (ELG_secret_key *sk, unsigned nbits, gcry_mpi_t **factors);
+static int  check_secret_key (ELG_secret_key *sk);
+static void do_encrypt (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
+                        ELG_public_key *pkey);
+static void decrypt (gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b,
+                     ELG_secret_key *skey);
+static void sign (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
+                  ELG_secret_key *skey);
+static int  verify (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
+                    ELG_public_key *pkey);
+
+
+static void (*progress_cb) (void *, const char *, int, int, int);
+static void *progress_cb_data;
+
+void
+_gcry_register_pk_elg_progress (void (*cb) (void *, const char *,
+                                            int, int, int),
+                               void *cb_data)
+{
+  progress_cb = cb;
+  progress_cb_data = cb_data;
+}
+
+
+static void
+progress (int c)
+{
+  if (progress_cb)
+    progress_cb (progress_cb_data, "pk_elg", c, 0, 0);
+}
+
+
+/****************
+ * Michael Wiener's table on subgroup sizes to match field sizes.
+ * (floating around somewhere, probably based on the paper from
+ * Eurocrypt 96, page 332)
+ */
+static unsigned int
+wiener_map( unsigned int n )
+{
+  static struct { unsigned int p_n, q_n; } t[] =
+    { /*   p     q      attack cost */
+      {  512, 119 },   /* 9 x 10^17 */
+      {  768, 145 },   /* 6 x 10^21 */
+      { 1024, 165 },   /* 7 x 10^24 */
+      { 1280, 183 },   /* 3 x 10^27 */
+      { 1536, 198 },   /* 7 x 10^29 */
+      { 1792, 212 },   /* 9 x 10^31 */
+      { 2048, 225 },   /* 8 x 10^33 */
+      { 2304, 237 },   /* 5 x 10^35 */
+      { 2560, 249 },   /* 3 x 10^37 */
+      { 2816, 259 },   /* 1 x 10^39 */
+      { 3072, 269 },   /* 3 x 10^40 */
+      { 3328, 279 },   /* 8 x 10^41 */
+      { 3584, 288 },   /* 2 x 10^43 */
+      { 3840, 296 },   /* 4 x 10^44 */
+      { 4096, 305 },   /* 7 x 10^45 */
+      { 4352, 313 },   /* 1 x 10^47 */
+      { 4608, 320 },   /* 2 x 10^48 */
+      { 4864, 328 },   /* 2 x 10^49 */
+      { 5120, 335 },   /* 3 x 10^50 */
+      { 0, 0 }
+    };
+  int i;
+
+  for(i=0; t[i].p_n; i++ )  
+    {
+      if( n <= t[i].p_n )
+        return t[i].q_n;
+    }
+  /* Not in table - use an arbitrary high number. */
+  return  n / 8 + 200;
+}
+
+static int
+test_keys ( ELG_secret_key *sk, unsigned int nbits, int nodie )
+{
+  ELG_public_key pk;
+  gcry_mpi_t test = gcry_mpi_new ( 0 );
+  gcry_mpi_t out1_a = gcry_mpi_new ( nbits );
+  gcry_mpi_t out1_b = gcry_mpi_new ( nbits );
+  gcry_mpi_t out2 = gcry_mpi_new ( nbits );
+  int failed = 0;
+
+  pk.p = sk->p;
+  pk.g = sk->g;
+  pk.y = sk->y;
+
+  gcry_mpi_randomize ( test, nbits, GCRY_WEAK_RANDOM );
+
+  do_encrypt ( out1_a, out1_b, test, &pk );
+  decrypt ( out2, out1_a, out1_b, sk );
+  if ( mpi_cmp( test, out2 ) )
+    failed |= 1;
+
+  sign ( out1_a, out1_b, test, sk );
+  if ( !verify( out1_a, out1_b, test, &pk ) )
+    failed |= 2;
+
+  gcry_mpi_release ( test );
+  gcry_mpi_release ( out1_a );
+  gcry_mpi_release ( out1_b );
+  gcry_mpi_release ( out2 );
+
+  if (failed && !nodie)
+    log_fatal ("Elgamal test key for %s %s failed\n",
+               (failed & 1)? "encrypt+decrypt":"",
+               (failed & 2)? "sign+verify":"");
+  if (failed && DBG_CIPHER) 
+    log_debug ("Elgamal test key for %s %s failed\n",
+               (failed & 1)? "encrypt+decrypt":"",
+               (failed & 2)? "sign+verify":"");
+
+  return failed;
+}
+
+
+/****************
+ * Generate a random secret exponent k from prime p, so that k is
+ * relatively prime to p-1.  With SMALL_K set, k will be selected for
+ * better encryption performance - this must never be used signing!
+ */
+static gcry_mpi_t
+gen_k( gcry_mpi_t p, int small_k )
+{
+  gcry_mpi_t k = mpi_alloc_secure( 0 );
+  gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(p) );
+  gcry_mpi_t p_1 = mpi_copy(p);
+  unsigned int orig_nbits = mpi_get_nbits(p);
+  unsigned int nbits, nbytes;
+  char *rndbuf = NULL;
+
+  if (small_k)
+    {
+      /* Using a k much lesser than p is sufficient for encryption and
+       * it greatly improves the encryption performance.  We use
+       * Wiener's table and add a large safety margin. */
+      nbits = wiener_map( orig_nbits ) * 3 / 2;
+      if( nbits >= orig_nbits )
+        BUG();
+    }
+  else
+    nbits = orig_nbits;
+
+
+  nbytes = (nbits+7)/8;
+  if( DBG_CIPHER )
+    log_debug("choosing a random k ");
+  mpi_sub_ui( p_1, p, 1);
+  for(;;) 
+    {
+      if( !rndbuf || nbits < 32 ) 
+        {
+          gcry_free(rndbuf);
+          rndbuf = gcry_random_bytes_secure( nbytes, GCRY_STRONG_RANDOM );
+        }
+      else
+        { 
+          /* Change only some of the higher bits.  We could improve
+             this by directly requesting more memory at the first call
+             to get_random_bytes() and use this the here maybe it is
+             easier to do this directly in random.c Anyway, it is
+             highly inlikely that we will ever reach this code. */
+          char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
+          memcpy( rndbuf, pp, 4 );
+          gcry_free(pp);
+       }
+      _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
+        
+      for(;;)
+        {
+          if( !(mpi_cmp( k, p_1 ) < 0) )  /* check: k < (p-1) */
+            {
+              if( DBG_CIPHER )
+                progress('+');
+              break; /* no  */
+            }
+          if( !(mpi_cmp_ui( k, 0 ) > 0) )  /* check: k > 0 */
+            {
+              if( DBG_CIPHER )
+                progress('-');
+              break; /* no */
+            }
+          if (gcry_mpi_gcd( temp, k, p_1 ))
+            goto found;  /* okay, k is relative prime to (p-1) */
+          mpi_add_ui( k, k, 1 );
+          if( DBG_CIPHER )
+            progress('.');
+       }
+    }
+ found:
+  gcry_free(rndbuf);
+  if( DBG_CIPHER )
+    progress('\n');
+  mpi_free(p_1);
+  mpi_free(temp);
+
+  return k;
+}
+
+/****************
+ * Generate a key pair with a key of size NBITS
+ * Returns: 2 structures filled with all needed values
+ *         and an array with n-1 factors of (p-1)
+ */
+static void
+generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
+{
+  gcry_mpi_t p;    /* the prime */
+  gcry_mpi_t p_min1;
+  gcry_mpi_t g;
+  gcry_mpi_t x;    /* the secret exponent */
+  gcry_mpi_t y;
+  unsigned int qbits;
+  unsigned int xbits;
+  byte *rndbuf;
+
+  p_min1 = gcry_mpi_new ( nbits );
+  qbits = wiener_map( nbits );
+  if( qbits & 1 ) /* better have a even one */
+    qbits++;
+  g = mpi_alloc(1);
+  p = _gcry_generate_elg_prime( 0, nbits, qbits, g, ret_factors );
+  mpi_sub_ui(p_min1, p, 1);
+
+
+  /* Select a random number which has these properties:
+   *    0 < x < p-1
+   * This must be a very good random number because this is the
+   * secret part.  The prime is public and may be shared anyway,
+   * so a random generator level of 1 is used for the prime.
+   *
+   * I don't see a reason to have a x of about the same size
+   * as the p.  It should be sufficient to have one about the size
+   * of q or the later used k plus a large safety margin. Decryption
+   * will be much faster with such an x.
+   */
+  xbits = qbits * 3 / 2;
+  if( xbits >= nbits )
+    BUG();
+  x = gcry_mpi_snew ( xbits );
+  if( DBG_CIPHER )
+    log_debug("choosing a random x of size %u", xbits );
+  rndbuf = NULL;
+  do 
+    {
+      if( DBG_CIPHER )
+        progress('.');
+      if( rndbuf )
+        { /* Change only some of the higher bits */
+          if( xbits < 16 ) /* should never happen ... */
+            {
+              gcry_free(rndbuf);
+              rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
+                                                 GCRY_VERY_STRONG_RANDOM );
+            }
+          else
+            {
+              char *r = gcry_random_bytes_secure( 2,
+                                                  GCRY_VERY_STRONG_RANDOM );
+              memcpy(rndbuf, r, 2 );
+              gcry_free(r);
+            }
+       }
+      else 
+        {
+          rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
+                                             GCRY_VERY_STRONG_RANDOM );
+       }
+      _gcry_mpi_set_buffer( x, rndbuf, (xbits+7)/8, 0 );
+      mpi_clear_highbit( x, xbits+1 );
+    } 
+  while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
+  gcry_free(rndbuf);
+
+  y = gcry_mpi_new (nbits);
+  gcry_mpi_powm( y, g, x, p );
+
+  if( DBG_CIPHER ) 
+    {
+      progress('\n');
+      log_mpidump("elg  p= ", p );
+      log_mpidump("elg  g= ", g );
+      log_mpidump("elg  y= ", y );
+      log_mpidump("elg  x= ", x );
+    }
+
+  /* Copy the stuff to the key structures */
+  sk->p = p;
+  sk->g = g;
+  sk->y = y;
+  sk->x = x;
+
+  gcry_mpi_release ( p_min1 );
+
+  /* Now we can test our keys (this should never fail!) */
+  test_keys ( sk, nbits - 64, 0 );
+}
+
+
+/* Generate a key pair with a key of size NBITS not using a random
+   value for the secret key but the one given as X.  This is useful to
+   implement a passphrase based decryption for a public key based
+   encryption.  It has appliactions in backup systems.
+   Returns: A structure filled with all needed values and an array
+           with n-1 factors of (p-1).  */
+static gcry_err_code_t
+generate_using_x (ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t x,
+                  gcry_mpi_t **ret_factors )
+{
+  gcry_mpi_t p;      /* The prime.  */
+  gcry_mpi_t p_min1; /* The prime minus 1.  */
+  gcry_mpi_t g;      /* The generator.  */
+  gcry_mpi_t y;      /* g^x mod p.  */
+  unsigned int qbits;
+  unsigned int xbits;
+
+  sk->p = NULL;
+  sk->g = NULL;
+  sk->y = NULL;
+  sk->x = NULL;
+
+  /* Do a quick check to see whether X is suitable.  */
+  xbits = mpi_get_nbits (x);
+  if ( xbits < 64 || xbits >= nbits )
+    return GPG_ERR_INV_VALUE;
+
+  p_min1 = gcry_mpi_new ( nbits );
+  qbits  = wiener_map ( nbits );
+  if ( (qbits & 1) ) /* Better have an even one.  */
+    qbits++;
+  g = mpi_alloc (1);
+  p = _gcry_generate_elg_prime ( 0, nbits, qbits, g, ret_factors );
+  mpi_sub_ui (p_min1, p, 1);
+
+  if (DBG_CIPHER)
+    log_debug ("using a supplied x of size %u", xbits );
+  if ( !(mpi_cmp_ui ( x, 0 ) > 0 && mpi_cmp ( x, p_min1 ) <0 ) )
+    {
+      gcry_mpi_release ( p_min1 );
+      gcry_mpi_release ( p );
+      gcry_mpi_release ( g );
+      return GPG_ERR_INV_VALUE;
+    }
+
+  y = gcry_mpi_new (nbits);
+  gcry_mpi_powm ( y, g, x, p );
+
+  if ( DBG_CIPHER ) 
+    {
+      progress ('\n');
+      log_mpidump ("elg  p= ", p );
+      log_mpidump ("elg  g= ", g );
+      log_mpidump ("elg  y= ", y );
+      log_mpidump ("elg  x= ", x );
+    }
+
+  /* Copy the stuff to the key structures */
+  sk->p = p;
+  sk->g = g;
+  sk->y = y;
+  sk->x = gcry_mpi_copy (x);
+
+  gcry_mpi_release ( p_min1 );
+
+  /* Now we can test our keys. */
+  if ( test_keys ( sk, nbits - 64, 1 ) )
+    {
+      gcry_mpi_release ( sk->p ); sk->p = NULL;
+      gcry_mpi_release ( sk->g ); sk->g = NULL;
+      gcry_mpi_release ( sk->y ); sk->y = NULL;
+      gcry_mpi_release ( sk->x ); sk->x = NULL;
+      return GPG_ERR_BAD_SECKEY;
+    }
+
+  return 0;
+}
+
+
+/****************
+ * Test whether the secret key is valid.
+ * Returns: if this is a valid key.
+ */
+static int
+check_secret_key( ELG_secret_key *sk )
+{
+  int rc;
+  gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
+
+  gcry_mpi_powm( y, sk->g, sk->x, sk->p );
+  rc = !mpi_cmp( y, sk->y );
+  mpi_free( y );
+  return rc;
+}
+
+
+static void
+do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
+{
+  gcry_mpi_t k;
+
+  /* Note: maybe we should change the interface, so that it
+   * is possible to check that input is < p and return an
+   * error code.
+   */
+
+  k = gen_k( pkey->p, 1 );
+  gcry_mpi_powm( a, pkey->g, k, pkey->p );
+  /* b = (y^k * input) mod p
+   *    = ((y^k mod p) * (input mod p)) mod p
+   * and because input is < p
+   *    = ((y^k mod p) * input) mod p
+   */
+  gcry_mpi_powm( b, pkey->y, k, pkey->p );
+  gcry_mpi_mulm( b, b, input, pkey->p );
+#if 0
+  if( DBG_CIPHER )
+    {
+      log_mpidump("elg encrypted y= ", pkey->y);
+      log_mpidump("elg encrypted p= ", pkey->p);
+      log_mpidump("elg encrypted k= ", k);
+      log_mpidump("elg encrypted M= ", input);
+      log_mpidump("elg encrypted a= ", a);
+      log_mpidump("elg encrypted b= ", b);
+    }
+#endif
+  mpi_free(k);
+}
+
+
+
+
+static void
+decrypt(gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, ELG_secret_key *skey )
+{
+  gcry_mpi_t t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
+
+  /* output = b/(a^x) mod p */
+  gcry_mpi_powm( t1, a, skey->x, skey->p );
+  mpi_invm( t1, t1, skey->p );
+  mpi_mulm( output, b, t1, skey->p );
+#if 0
+  if( DBG_CIPHER ) 
+    {
+      log_mpidump("elg decrypted x= ", skey->x);
+      log_mpidump("elg decrypted p= ", skey->p);
+      log_mpidump("elg decrypted a= ", a);
+      log_mpidump("elg decrypted b= ", b);
+      log_mpidump("elg decrypted M= ", output);
+    }
+#endif
+  mpi_free(t1);
+}
+
+
+/****************
+ * Make an Elgamal signature out of INPUT
+ */
+
+static void
+sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey )
+{
+    gcry_mpi_t k;
+    gcry_mpi_t t   = mpi_alloc( mpi_get_nlimbs(a) );
+    gcry_mpi_t inv = mpi_alloc( mpi_get_nlimbs(a) );
+    gcry_mpi_t p_1 = mpi_copy(skey->p);
+
+   /*
+    * b = (t * inv) mod (p-1)
+    * b = (t * inv(k,(p-1),(p-1)) mod (p-1)
+    * b = (((M-x*a) mod (p-1)) * inv(k,(p-1),(p-1))) mod (p-1)
+    *
+    */
+    mpi_sub_ui(p_1, p_1, 1);
+    k = gen_k( skey->p, 0 /* no small K ! */ );
+    gcry_mpi_powm( a, skey->g, k, skey->p );
+    mpi_mul(t, skey->x, a );
+    mpi_subm(t, input, t, p_1 );
+    mpi_invm(inv, k, p_1 );
+    mpi_mulm(b, t, inv, p_1 );
+
+#if 0
+    if( DBG_CIPHER ) 
+      {
+       log_mpidump("elg sign p= ", skey->p);
+       log_mpidump("elg sign g= ", skey->g);
+       log_mpidump("elg sign y= ", skey->y);
+       log_mpidump("elg sign x= ", skey->x);
+       log_mpidump("elg sign k= ", k);
+       log_mpidump("elg sign M= ", input);
+       log_mpidump("elg sign a= ", a);
+       log_mpidump("elg sign b= ", b);
+      }
+#endif
+    mpi_free(k);
+    mpi_free(t);
+    mpi_free(inv);
+    mpi_free(p_1);
+}
+
+
+/****************
+ * Returns true if the signature composed of A and B is valid.
+ */
+static int
+verify(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
+{
+  int rc;
+  gcry_mpi_t t1;
+  gcry_mpi_t t2;
+  gcry_mpi_t base[4];
+  gcry_mpi_t ex[4];
+
+  if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) )
+    return 0; /* assertion     0 < a < p  failed */
+
+  t1 = mpi_alloc( mpi_get_nlimbs(a) );
+  t2 = mpi_alloc( mpi_get_nlimbs(a) );
+
+#if 0
+  /* t1 = (y^a mod p) * (a^b mod p) mod p */
+  gcry_mpi_powm( t1, pkey->y, a, pkey->p );
+  gcry_mpi_powm( t2, a, b, pkey->p );
+  mpi_mulm( t1, t1, t2, pkey->p );
+
+  /* t2 = g ^ input mod p */
+  gcry_mpi_powm( t2, pkey->g, input, pkey->p );
+
+  rc = !mpi_cmp( t1, t2 );
+#elif 0
+  /* t1 = (y^a mod p) * (a^b mod p) mod p */
+  base[0] = pkey->y; ex[0] = a;
+  base[1] = a;       ex[1] = b;
+  base[2] = NULL;    ex[2] = NULL;
+  mpi_mulpowm( t1, base, ex, pkey->p );
+
+  /* t2 = g ^ input mod p */
+  gcry_mpi_powm( t2, pkey->g, input, pkey->p );
+
+  rc = !mpi_cmp( t1, t2 );
+#else
+  /* t1 = g ^ - input * y ^ a * a ^ b  mod p */
+  mpi_invm(t2, pkey->g, pkey->p );
+  base[0] = t2     ; ex[0] = input;
+  base[1] = pkey->y; ex[1] = a;
+  base[2] = a;       ex[2] = b;
+  base[3] = NULL;    ex[3] = NULL;
+  mpi_mulpowm( t1, base, ex, pkey->p );
+  rc = !mpi_cmp_ui( t1, 1 );
+
+#endif
+
+  mpi_free(t1);
+  mpi_free(t2);
+  return rc;
+}
+
+/*********************************************
+ **************  interface  ******************
+ *********************************************/
+
+static gpg_err_code_t
+elg_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
+                  const gcry_sexp_t genparms,
+                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
+                  gcry_sexp_t *r_extrainfo)
+{
+  gpg_err_code_t ec;
+  ELG_secret_key sk;
+  gcry_mpi_t xvalue = NULL;
+  gcry_sexp_t l1;
+
+  (void)algo;
+  (void)evalue;
+  (void)r_extrainfo;
+
+  if (genparms)
+    {
+      /* Parse the optional xvalue element. */
+      l1 = gcry_sexp_find_token (genparms, "xvalue", 0);
+      if (l1)
+        {
+          xvalue = gcry_sexp_nth_mpi (l1, 1, 0);
+          gcry_sexp_release (l1);
+          if (!xvalue)
+            return GPG_ERR_BAD_MPI;
+        }
+    }
+
+  if (xvalue)
+    ec = generate_using_x (&sk, nbits, xvalue, retfactors);
+  else
+    {
+      generate (&sk, nbits, retfactors);
+      ec = 0;
+    }
+
+  skey[0] = sk.p;
+  skey[1] = sk.g;
+  skey[2] = sk.y;
+  skey[3] = sk.x;
+  
+  return ec;
+}
+
+
+static gcry_err_code_t
+elg_generate (int algo, unsigned int nbits, unsigned long evalue,
+              gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+{
+  ELG_secret_key sk;
+
+  (void)algo;
+  (void)evalue;
+
+  generate (&sk, nbits, retfactors);
+  skey[0] = sk.p;
+  skey[1] = sk.g;
+  skey[2] = sk.y;
+  skey[3] = sk.x;
+  
+  return GPG_ERR_NO_ERROR;
+}
+
+
+static gcry_err_code_t
+elg_check_secret_key (int algo, gcry_mpi_t *skey)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  ELG_secret_key sk;
+
+  (void)algo;
+
+  if ((! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
+    err = GPG_ERR_BAD_MPI;
+  else
+    {
+      sk.p = skey[0];
+      sk.g = skey[1];
+      sk.y = skey[2];
+      sk.x = skey[3];
+      
+      if (! check_secret_key (&sk))
+       err = GPG_ERR_BAD_SECKEY;
+    }
+
+  return err;
+}
+
+
+static gcry_err_code_t
+elg_encrypt (int algo, gcry_mpi_t *resarr,
+             gcry_mpi_t data, gcry_mpi_t *pkey, int flags)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  ELG_public_key pk;
+
+  (void)algo;
+  (void)flags;
+
+  if ((! data) || (! pkey[0]) || (! pkey[1]) || (! pkey[2]))
+    err = GPG_ERR_BAD_MPI;
+  else
+    {
+      pk.p = pkey[0];
+      pk.g = pkey[1];
+      pk.y = pkey[2];
+      resarr[0] = mpi_alloc (mpi_get_nlimbs (pk.p));
+      resarr[1] = mpi_alloc (mpi_get_nlimbs (pk.p));
+      do_encrypt (resarr[0], resarr[1], data, &pk);
+    }
+  return err;
+}
+
+
+static gcry_err_code_t
+elg_decrypt (int algo, gcry_mpi_t *result,
+             gcry_mpi_t *data, gcry_mpi_t *skey, int flags)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  ELG_secret_key sk;
+
+  (void)algo;
+  (void)flags;
+
+  if ((! data[0]) || (! data[1])
+      || (! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
+    err = GPG_ERR_BAD_MPI;
+  else
+    {
+      sk.p = skey[0];
+      sk.g = skey[1];
+      sk.y = skey[2];
+      sk.x = skey[3];
+      *result = mpi_alloc_secure (mpi_get_nlimbs (sk.p));
+      decrypt (*result, data[0], data[1], &sk);
+    }
+  return err;
+}
+
+
+static gcry_err_code_t
+elg_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  ELG_secret_key sk;
+
+  (void)algo;
+
+  if ((! data)
+      || (! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
+    err = GPG_ERR_BAD_MPI;
+  else
+    {
+      sk.p = skey[0];
+      sk.g = skey[1];
+      sk.y = skey[2];
+      sk.x = skey[3];
+      resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p));
+      resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
+      sign (resarr[0], resarr[1], data, &sk);
+    }
+  
+  return err;
+}
+
+
+static gcry_err_code_t
+elg_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
+            int (*cmp) (void *, gcry_mpi_t), void *opaquev)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  ELG_public_key pk;
+
+  (void)algo;
+  (void)cmp;
+  (void)opaquev;
+
+  if ((! data[0]) || (! data[1]) || (! hash)
+      || (! pkey[0]) || (! pkey[1]) || (! pkey[2]))
+    err = GPG_ERR_BAD_MPI;
+  else
+    {
+      pk.p = pkey[0];
+      pk.g = pkey[1];
+      pk.y = pkey[2];
+      if (! verify (data[0], data[1], hash, &pk))
+       err = GPG_ERR_BAD_SIGNATURE;
+    }
+
+  return err;
+}
+
+
+static unsigned int
+elg_get_nbits (int algo, gcry_mpi_t *pkey)
+{
+  (void)algo;
+
+  return mpi_get_nbits (pkey[0]);
+}
+
+
+static const char *elg_names[] =
+  {
+    "elg",
+    "openpgp-elg",
+    "openpgp-elg-sig",
+    NULL,
+  };
+
+
+gcry_pk_spec_t _gcry_pubkey_spec_elg =
+  {
+    "ELG", elg_names,
+    "pgy", "pgyx", "ab", "rs", "pgy",
+    GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR,
+    elg_generate,
+    elg_check_secret_key,
+    elg_encrypt,
+    elg_decrypt,
+    elg_sign,
+    elg_verify,
+    elg_get_nbits
+  };
+
+pk_extra_spec_t _gcry_pubkey_extraspec_elg = 
+  {
+    NULL,
+    elg_generate_ext,
+    NULL
+  };
+
diff --git a/grub-core/lib/libgcrypt/cipher/hash-common.c b/grub-core/lib/libgcrypt/cipher/hash-common.c
new file mode 100644 (file)
index 0000000..656e180
--- /dev/null
@@ -0,0 +1,94 @@
+/* hash-common.c - Common code for hash algorithms
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STDINT_H 
+# include <stdint.h>
+#endif
+
+#include "g10lib.h"
+#include "hash-common.h"
+
+
+/* Run a selftest for hash algorithm ALGO.  If the resulting digest
+   matches EXPECT/EXPECTLEN and everything else is fine as well,
+   return NULL.  If an error occurs, return a static text string
+   describing the error.
+
+   DATAMODE controls what will be hashed according to this table:
+   
+     0 - Hash the supplied DATA of DATALEN.
+     1 - Hash one million times a 'a'.  DATA and DATALEN are ignored.
+   
+*/
+const char *
+_gcry_hash_selftest_check_one (int algo,
+                               int datamode, const void *data, size_t datalen,
+                               const void *expect, size_t expectlen)
+{
+  const char *result = NULL;
+  gcry_error_t err = 0;
+  gcry_md_hd_t hd;
+  unsigned char *digest;
+  
+  if (_gcry_md_get_algo_dlen (algo) != expectlen)
+    return "digest size does not match expected size";
+    
+  err = _gcry_md_open (&hd, algo, 0);
+  if (err)
+    return "gcry_md_open failed";
+  
+  switch (datamode)
+    {
+    case 0:
+      _gcry_md_write (hd, data, datalen);
+      break;
+
+    case 1: /* Hash one million times an "a". */
+      {                
+        char aaa[1000];
+        int i;
+
+        /* Write in odd size chunks so that we test the buffering.  */
+        memset (aaa, 'a', 1000);
+        for (i = 0; i < 1000; i++)
+          _gcry_md_write (hd, aaa, 1000);
+      }
+      break;
+
+    default:
+      result = "invalid DATAMODE";
+    }
+
+  if (!result)
+    {
+      digest = _gcry_md_read (hd, algo);
+      
+      if ( memcmp (digest, expect, expectlen) )
+        result = "digest mismatch";
+    }
+
+  _gcry_md_close (hd);
+
+  return result;
+}
+
diff --git a/grub-core/lib/libgcrypt/cipher/hash-common.h b/grub-core/lib/libgcrypt/cipher/hash-common.h
new file mode 100644 (file)
index 0000000..9c4e333
--- /dev/null
@@ -0,0 +1,33 @@
+/* hash-common.h - Declarations of common code for hash algorithms.
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_HASH_COMMON_H
+#define GCRY_HASH_COMMON_H
+
+
+const char * _gcry_hash_selftest_check_one 
+/**/         (int algo, 
+              int datamode, const void *data, size_t datalen,
+              const void *expect, size_t expectlen);
+     
+
+
+
+
+#endif /*GCRY_HASH_COMMON_H*/
diff --git a/grub-core/lib/libgcrypt/cipher/hmac-tests.c b/grub-core/lib/libgcrypt/cipher/hmac-tests.c
new file mode 100644 (file)
index 0000000..56c9b20
--- /dev/null
@@ -0,0 +1,732 @@
+/* hmac-tests.c - HMAC selftests.
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* 
+   Although algorithm self-tests are usually implemented in the module
+   implementing the algorithm, the case for HMAC is different because
+   HMAC is implemnetd on a higher level using a special feature of the
+   gcry_md_ functions.  It would be possible to do this also in the
+   digest algorithm modules, but that would blow up the code too much
+   and spread the hmac tests over several modules.
+
+   Thus we implement all HMAC tests in this test module and provide a
+   function to run the tests.
+*/
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STDINT_H 
+# include <stdint.h>
+#endif
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "hmac256.h"
+
+/* Check one HMAC with digest ALGO using the regualr HAMC
+   API. (DATA,DATALEN) is the data to be MACed, (KEY,KEYLEN) the key
+   and (EXPECT,EXPECTLEN) the expected result.  Returns NULL on
+   succdess or a string describing the failure.  */
+static const char *
+check_one (int algo,
+           const void *data, size_t datalen, 
+           const void *key, size_t keylen,
+           const void *expect, size_t expectlen)
+{
+  gcry_md_hd_t hd;
+  const unsigned char *digest;
+
+/*   printf ("HMAC algo %d\n", algo); */
+  if (_gcry_md_get_algo_dlen (algo) != expectlen)
+    return "invalid tests data";
+  if (_gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC))
+    return "gcry_md_open failed";
+  if (_gcry_md_setkey (hd, key, keylen))
+    {
+      _gcry_md_close (hd);
+      return "gcry_md_setkey failed";
+    }
+  _gcry_md_write (hd, data, datalen);
+  digest = _gcry_md_read (hd, algo);
+  if (!digest)
+    {
+      _gcry_md_close (hd);
+      return "gcry_md_read failed";
+    }
+  if (memcmp (digest, expect, expectlen))
+    {
+/*       int i; */
+
+/*       fputs ("        {", stdout); */
+/*       for (i=0; i < expectlen-1; i++) */
+/*         { */
+/*           if (i && !(i % 8)) */
+/*             fputs ("\n         ", stdout); */
+/*           printf (" 0x%02x,", digest[i]); */
+/*         } */
+/*       printf (" 0x%02x } },\n", digest[i]); */
+
+      _gcry_md_close (hd);
+      return "does not match";
+    }
+  _gcry_md_close (hd);
+  return NULL;  
+}
+
+
+static gpg_err_code_t
+selftests_sha1 (int extended, selftest_report_func_t report)
+{
+  const char *what;
+  const char *errtxt;
+  unsigned char key[128];
+  int i, j;
+
+  what = "FIPS-198a, A.1";
+  for (i=0; i < 64; i++)
+    key[i] = i;
+  errtxt = check_one (GCRY_MD_SHA1,
+                      "Sample #1", 9,
+                      key, 64,
+                      "\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12"
+                      "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a", 20);
+  if (errtxt)
+    goto failed;
+
+  if (extended)
+    {
+      what = "FIPS-198a, A.2";
+      for (i=0, j=0x30; i < 20; i++)
+        key[i] = j++;
+      errtxt = check_one (GCRY_MD_SHA1,
+                          "Sample #2", 9,
+                          key, 20,
+                          "\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82"
+                          "\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24", 20);
+      if (errtxt)
+        goto failed;
+      
+      what = "FIPS-198a, A.3";
+      for (i=0, j=0x50; i < 100; i++)
+        key[i] = j++;
+      errtxt = check_one (GCRY_MD_SHA1,
+                          "Sample #3", 9,
+                          key, 100,
+                          "\xbc\xf4\x1e\xab\x8b\xb2\xd8\x02\xf3\xd0"
+                          "\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa", 20 );
+      if (errtxt)
+        goto failed;
+      
+      what = "FIPS-198a, A.4";
+      for (i=0, j=0x70; i < 49; i++)
+        key[i] = j++;
+      errtxt = check_one (GCRY_MD_SHA1,
+                          "Sample #4", 9,
+                          key, 49,
+                          "\x9e\xa8\x86\xef\xe2\x68\xdb\xec\xce\x42"
+                          "\x0c\x75\x24\xdf\x32\xe0\x75\x1a\x2a\x26", 20 );
+      if (errtxt)
+        goto failed;
+    }
+
+  return 0; /* Succeeded. */
+
+ failed:
+  if (report)
+    report ("hmac", GCRY_MD_SHA1, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+
+static gpg_err_code_t
+selftests_sha224 (int extended, selftest_report_func_t report)
+{
+  static struct 
+  {
+    const char * const desc;
+    const char * const data;
+    const char * const key;
+    const char expect[28];
+  } tv[] =
+    {
+      { "data-28 key-4",
+        "what do ya want for nothing?", 
+        "Jefe",
+        { 0xa3, 0x0e, 0x01, 0x09, 0x8b, 0xc6, 0xdb, 0xbf,
+          0x45, 0x69, 0x0f, 0x3a, 0x7e, 0x9e, 0x6d, 0x0f,
+          0x8b, 0xbe, 0xa2, 0xa3, 0x9e, 0x61, 0x48, 0x00,
+          0x8f, 0xd0, 0x5e, 0x44 } },
+
+      { "data-9 key-20",
+        "Hi There",
+       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+        "\x0b\x0b\x0b\x0b",
+        { 0x89, 0x6f, 0xb1, 0x12, 0x8a, 0xbb, 0xdf, 0x19,
+          0x68, 0x32, 0x10, 0x7c, 0xd4, 0x9d, 0xf3, 0x3f,
+          0x47, 0xb4, 0xb1, 0x16, 0x99, 0x12, 0xba, 0x4f,
+          0x53, 0x68, 0x4b, 0x22 } },
+
+      { "data-50 key-20",
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa",
+        { 0x7f, 0xb3, 0xcb, 0x35, 0x88, 0xc6, 0xc1, 0xf6,
+          0xff, 0xa9, 0x69, 0x4d, 0x7d, 0x6a, 0xd2, 0x64,
+          0x93, 0x65, 0xb0, 0xc1, 0xf6, 0x5d, 0x69, 0xd1,
+          0xec, 0x83, 0x33, 0xea } },
+
+      { "data-50 key-26",
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd",
+       "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+        "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+        { 0x6c, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3c, 0xac,
+          0x6a, 0x2a, 0xbc, 0x1b, 0xb3, 0x82, 0x62, 0x7c,
+          0xec, 0x6a, 0x90, 0xd8, 0x6e, 0xfc, 0x01, 0x2d,
+          0xe7, 0xaf, 0xec, 0x5a } },
+
+      { "data-54 key-131",
+        "Test Using Larger Than Block-Size Key - Hash Key First",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa",
+        { 0x95, 0xe9, 0xa0, 0xdb, 0x96, 0x20, 0x95, 0xad,
+          0xae, 0xbe, 0x9b, 0x2d, 0x6f, 0x0d, 0xbc, 0xe2,
+          0xd4, 0x99, 0xf1, 0x12, 0xf2, 0xd2, 0xb7, 0x27,
+          0x3f, 0xa6, 0x87, 0x0e } },
+
+      { "data-152 key-131",
+        "This is a test using a larger than block-size key and a larger "
+        "than block-size data. The key needs to be hashed before being "
+        "used by the HMAC algorithm.",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa",
+        { 0x3a, 0x85, 0x41, 0x66, 0xac, 0x5d, 0x9f, 0x02,
+          0x3f, 0x54, 0xd5, 0x17, 0xd0, 0xb3, 0x9d, 0xbd,
+          0x94, 0x67, 0x70, 0xdb, 0x9c, 0x2b, 0x95, 0xc9,
+          0xf6, 0xf5, 0x65, 0xd1 } },
+
+      { NULL }
+    };
+  const char *what;
+  const char *errtxt;
+  int tvidx;
+  
+  for (tvidx=0; tv[tvidx].desc; tvidx++)
+    {
+      what = tv[tvidx].desc;
+      errtxt = check_one (GCRY_MD_SHA224,
+                          tv[tvidx].data, strlen (tv[tvidx].data),
+                          tv[tvidx].key, strlen (tv[tvidx].key),
+                          tv[tvidx].expect, DIM (tv[tvidx].expect) );
+      if (errtxt)
+        goto failed;
+      if (!extended)
+        break;
+    }
+
+  return 0; /* Succeeded. */
+
+ failed:
+  if (report)
+    report ("hmac", GCRY_MD_SHA224, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+static gpg_err_code_t
+selftests_sha256 (int extended, selftest_report_func_t report)
+{
+  static struct 
+  {
+    const char * const desc;
+    const char * const data;
+    const char * const key;
+    const char expect[32];
+  } tv[] =
+    {
+      { "data-28 key-4",
+        "what do ya want for nothing?", 
+        "Jefe",
+       { 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
+          0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
+          0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
+          0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 } },
+
+      { "data-9 key-20",
+        "Hi There",
+       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+        "\x0b\x0b\x0b\x0b",
+        { 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
+          0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
+          0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
+          0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 } },
+
+      { "data-50 key-20",
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa",
+        { 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46,
+          0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7,
+          0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22,
+          0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe } },
+
+      { "data-50 key-26",
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd",
+       "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+        "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+       { 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e,
+          0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a,
+          0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07,
+          0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b } },
+
+      { "data-54 key-131",
+        "Test Using Larger Than Block-Size Key - Hash Key First",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa",
+       { 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
+          0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
+          0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
+          0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 } },
+
+      { "data-152 key-131",
+        "This is a test using a larger than block-size key and a larger "
+        "than block-size data. The key needs to be hashed before being "
+        "used by the HMAC algorithm.",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa",
+       { 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb,
+          0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44,
+          0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93,
+          0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2 } },
+
+      { NULL }
+    };
+  const char *what;
+  const char *errtxt;
+  int tvidx;
+  
+  for (tvidx=0; tv[tvidx].desc; tvidx++)
+    {
+      hmac256_context_t hmachd;
+      const unsigned char *digest;
+      size_t dlen;
+
+      what = tv[tvidx].desc;
+      errtxt = check_one (GCRY_MD_SHA256,
+                          tv[tvidx].data, strlen (tv[tvidx].data),
+                          tv[tvidx].key, strlen (tv[tvidx].key),
+                          tv[tvidx].expect, DIM (tv[tvidx].expect) );
+      if (errtxt)
+        goto failed;
+
+      hmachd = _gcry_hmac256_new (tv[tvidx].key, strlen (tv[tvidx].key));
+      if (!hmachd)
+        {
+          errtxt = "_gcry_hmac256_new failed";
+          goto failed;
+        }
+      _gcry_hmac256_update (hmachd, tv[tvidx].data, strlen (tv[tvidx].data));
+      digest = _gcry_hmac256_finalize (hmachd, &dlen);
+      if (!digest)
+        {
+          errtxt = "_gcry_hmac256_finalize failed";
+          _gcry_hmac256_release (hmachd);
+          goto failed;
+        }
+      if (dlen != DIM (tv[tvidx].expect)
+          || memcmp (digest, tv[tvidx].expect, DIM (tv[tvidx].expect)))
+        {
+          errtxt = "does not match in second implementation";
+          _gcry_hmac256_release (hmachd);
+          goto failed;
+        }
+      _gcry_hmac256_release (hmachd);
+
+      if (!extended)
+        break;
+    }
+
+  return 0; /* Succeeded. */
+
+ failed:
+  if (report)
+    report ("hmac", GCRY_MD_SHA256, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+static gpg_err_code_t
+selftests_sha384 (int extended, selftest_report_func_t report)
+{
+  static struct 
+  {
+    const char * const desc;
+    const char * const data;
+    const char * const key;
+    const char expect[48];
+  } tv[] =
+    {
+      { "data-28 key-4",
+        "what do ya want for nothing?", 
+        "Jefe",
+        { 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31,
+          0x61, 0x7f, 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b,
+          0x9c, 0x7e, 0xf4, 0x64, 0xf5, 0xa0, 0x1b, 0x47,
+          0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22, 0x44, 0x5e,
+          0x8e, 0x22, 0x40, 0xca, 0x5e, 0x69, 0xe2, 0xc7,
+          0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49 } },
+
+      { "data-9 key-20",
+        "Hi There",
+       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+        "\x0b\x0b\x0b\x0b",
+        { 0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62,
+          0x6b, 0x08, 0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f,
+          0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6,
+          0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c,
+          0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f,
+          0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6 } },
+
+      { "data-50 key-20",
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa",
+        { 0x88, 0x06, 0x26, 0x08, 0xd3, 0xe6, 0xad, 0x8a,
+          0x0a, 0xa2, 0xac, 0xe0, 0x14, 0xc8, 0xa8, 0x6f,
+          0x0a, 0xa6, 0x35, 0xd9, 0x47, 0xac, 0x9f, 0xeb,
+          0xe8, 0x3e, 0xf4, 0xe5, 0x59, 0x66, 0x14, 0x4b,
+          0x2a, 0x5a, 0xb3, 0x9d, 0xc1, 0x38, 0x14, 0xb9,
+          0x4e, 0x3a, 0xb6, 0xe1, 0x01, 0xa3, 0x4f, 0x27 } },
+
+      { "data-50 key-26",
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd",
+       "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+        "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+        { 0x3e, 0x8a, 0x69, 0xb7, 0x78, 0x3c, 0x25, 0x85,
+          0x19, 0x33, 0xab, 0x62, 0x90, 0xaf, 0x6c, 0xa7,
+          0x7a, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9c,
+          0xc5, 0x57, 0x7c, 0x6e, 0x1f, 0x57, 0x3b, 0x4e,
+          0x68, 0x01, 0xdd, 0x23, 0xc4, 0xa7, 0xd6, 0x79,
+          0xcc, 0xf8, 0xa3, 0x86, 0xc6, 0x74, 0xcf, 0xfb } },
+
+      { "data-54 key-131",
+        "Test Using Larger Than Block-Size Key - Hash Key First",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa",
+        { 0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90,
+          0x88, 0xd2, 0xc6, 0x3a, 0x04, 0x1b, 0xc5, 0xb4,
+          0x4f, 0x9e, 0xf1, 0x01, 0x2a, 0x2b, 0x58, 0x8f,
+          0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, 0xc4, 0xc6,
+          0x0c, 0x2e, 0xf6, 0xab, 0x40, 0x30, 0xfe, 0x82,
+          0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52 } },
+
+      { "data-152 key-131",
+        "This is a test using a larger than block-size key and a larger "
+        "than block-size data. The key needs to be hashed before being "
+        "used by the HMAC algorithm.",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa",
+        { 0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d,
+          0x35, 0x1e, 0x2f, 0x25, 0x4e, 0x8f, 0xd3, 0x2c,
+          0x60, 0x24, 0x20, 0xfe, 0xb0, 0xb8, 0xfb, 0x9a,
+          0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e, 0x99, 0xc5,
+          0xa6, 0x78, 0xcc, 0x31, 0xe7, 0x99, 0x17, 0x6d,
+          0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e } },
+
+      { NULL }
+    };
+  const char *what;
+  const char *errtxt;
+  int tvidx;
+  
+  for (tvidx=0; tv[tvidx].desc; tvidx++)
+    {
+      what = tv[tvidx].desc;
+      errtxt = check_one (GCRY_MD_SHA384,
+                          tv[tvidx].data, strlen (tv[tvidx].data),
+                          tv[tvidx].key, strlen (tv[tvidx].key),
+                          tv[tvidx].expect, DIM (tv[tvidx].expect) );
+      if (errtxt)
+        goto failed;
+      if (!extended)
+        break;
+    }
+
+  return 0; /* Succeeded. */
+
+ failed:
+  if (report)
+    report ("hmac", GCRY_MD_SHA384, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+static gpg_err_code_t
+selftests_sha512 (int extended, selftest_report_func_t report)
+{
+  static struct 
+  {
+    const char * const desc;
+    const char * const data;
+    const char * const key;
+    const char expect[64];
+  } tv[] =
+    {
+      { "data-28 key-4",
+        "what do ya want for nothing?", 
+        "Jefe",
+        { 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2,
+          0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3,
+          0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6,
+          0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54,
+          0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a,
+          0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd,
+          0xca, 0xea, 0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b,
+          0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37 } },
+
+      { "data-9 key-20",
+        "Hi There",
+       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+        "\x0b\x0b\x0b\x0b",
+        { 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d,
+          0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0,
+          0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78,
+          0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde,
+          0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02,
+          0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4,
+          0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70,
+          0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54 } },
+
+      { "data-50 key-20",
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa",
+        { 0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84,
+          0xef, 0xb0, 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9,
+          0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36,
+          0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39,
+          0xbf, 0x3e, 0x84, 0x82, 0x79, 0xa7, 0x22, 0xc8,
+          0x06, 0xb4, 0x85, 0xa4, 0x7e, 0x67, 0xc8, 0x07,
+          0xb9, 0x46, 0xa3, 0x37, 0xbe, 0xe8, 0x94, 0x26,
+          0x74, 0x27, 0x88, 0x59, 0xe1, 0x32, 0x92, 0xfb } },
+
+      { "data-50 key-26",
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd",
+       "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+        "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+        { 0xb0, 0xba, 0x46, 0x56, 0x37, 0x45, 0x8c, 0x69,
+          0x90, 0xe5, 0xa8, 0xc5, 0xf6, 0x1d, 0x4a, 0xf7,
+          0xe5, 0x76, 0xd9, 0x7f, 0xf9, 0x4b, 0x87, 0x2d,
+          0xe7, 0x6f, 0x80, 0x50, 0x36, 0x1e, 0xe3, 0xdb,
+          0xa9, 0x1c, 0xa5, 0xc1, 0x1a, 0xa2, 0x5e, 0xb4,
+          0xd6, 0x79, 0x27, 0x5c, 0xc5, 0x78, 0x80, 0x63,
+          0xa5, 0xf1, 0x97, 0x41, 0x12, 0x0c, 0x4f, 0x2d,
+          0xe2, 0xad, 0xeb, 0xeb, 0x10, 0xa2, 0x98, 0xdd } },
+
+      { "data-54 key-131",
+        "Test Using Larger Than Block-Size Key - Hash Key First",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa",
+        { 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb,
+          0xb7, 0x14, 0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4,
+          0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1,
+          0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52,
+          0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98,
+          0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52,
+          0x95, 0xe6, 0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec,
+          0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98 } },
+
+      { "data-152 key-131",
+        "This is a test using a larger than block-size key and a larger "
+        "than block-size data. The key needs to be hashed before being "
+        "used by the HMAC algorithm.",
+       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa",
+        { 0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba,
+          0xa4, 0xdf, 0xa9, 0xf9, 0x6e, 0x5e, 0x3f, 0xfd,
+          0xde, 0xbd, 0x71, 0xf8, 0x86, 0x72, 0x89, 0x86,
+          0x5d, 0xf5, 0xa3, 0x2d, 0x20, 0xcd, 0xc9, 0x44,
+          0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, 0xb1,
+          0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15,
+          0x13, 0x46, 0x76, 0xfb, 0x6d, 0xe0, 0x44, 0x60,
+          0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58 } },
+
+      { NULL }
+    };
+  const char *what;
+  const char *errtxt;
+  int tvidx;
+  
+  for (tvidx=0; tv[tvidx].desc; tvidx++)
+    {
+      what = tv[tvidx].desc;
+      errtxt = check_one (GCRY_MD_SHA512,
+                          tv[tvidx].data, strlen (tv[tvidx].data),
+                          tv[tvidx].key, strlen (tv[tvidx].key),
+                          tv[tvidx].expect, DIM (tv[tvidx].expect) );
+      if (errtxt)
+        goto failed;
+      if (!extended)
+        break;
+    }
+
+  return 0; /* Succeeded. */
+
+ failed:
+  if (report)
+    report ("hmac", GCRY_MD_SHA512, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+
+/* Run a full self-test for ALGO and return 0 on success.  */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+  gpg_err_code_t ec;
+
+  switch (algo)
+    {
+    case GCRY_MD_SHA1:
+      ec = selftests_sha1 (extended, report);
+      break;
+    case GCRY_MD_SHA224:
+      ec = selftests_sha224 (extended, report);
+      break;
+    case GCRY_MD_SHA256:
+      ec = selftests_sha256 (extended, report);
+      break;
+    case GCRY_MD_SHA384:
+      ec = selftests_sha384 (extended, report);
+      break;
+    case GCRY_MD_SHA512:
+      ec = selftests_sha512 (extended, report);
+      break;
+    default:
+      ec = GPG_ERR_DIGEST_ALGO;
+      break;
+    }
+  return ec;
+}
+
+
+
+
+/* Run the selftests for HMAC with digest algorithm ALGO with optional
+   reporting function REPORT.  */
+gpg_error_t
+_gcry_hmac_selftest (int algo, int extended, selftest_report_func_t report)
+{
+  gcry_err_code_t ec = 0;
+
+  if (!gcry_md_test_algo (algo))
+    {
+      ec = run_selftests (algo, extended, report);
+    }
+  else
+    {
+      ec = GPG_ERR_DIGEST_ALGO;
+      if (report)
+        report ("hmac", algo, "module", "algorithm not available");
+    }
+  return gpg_error (ec);
+}
diff --git a/grub-core/lib/libgcrypt/cipher/md.c b/grub-core/lib/libgcrypt/cipher/md.c
new file mode 100644 (file)
index 0000000..5dfbbd9
--- /dev/null
@@ -0,0 +1,1375 @@
+/* md.c  -  message digest dispatcher
+ * Copyright (C) 1998, 1999, 2002, 2003, 2006,
+ *               2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "ath.h"
+
+#include "rmd.h"
+
+/* A dummy extraspec so that we do not need to tests the extraspec
+   field from the module specification against NULL and instead
+   directly test the respective fields of extraspecs.  */
+static md_extra_spec_t dummy_extra_spec;
+
+
+/* This is the list of the digest implementations included in
+   libgcrypt.  */
+static struct digest_table_entry
+{
+  gcry_md_spec_t *digest;
+  md_extra_spec_t *extraspec;
+  unsigned int algorithm;
+  int fips_allowed; 
+} digest_table[] =
+  {
+#if USE_CRC    
+    /* We allow the CRC algorithms even in FIPS mode because they are
+       actually no cryptographic primitives.  */
+    { &_gcry_digest_spec_crc32,   
+      &dummy_extra_spec,                 GCRY_MD_CRC32, 1 },
+    { &_gcry_digest_spec_crc32_rfc1510,  
+      &dummy_extra_spec,                 GCRY_MD_CRC32_RFC1510, 1 },
+    { &_gcry_digest_spec_crc24_rfc2440,
+      &dummy_extra_spec,                 GCRY_MD_CRC24_RFC2440, 1 },
+#endif
+#if USE_MD4
+    { &_gcry_digest_spec_md4,
+      &dummy_extra_spec,                 GCRY_MD_MD4 },
+#endif
+#if USE_MD5
+    { &_gcry_digest_spec_md5,
+      &dummy_extra_spec,                 GCRY_MD_MD5, 1 },
+#endif
+#if USE_RMD160
+    { &_gcry_digest_spec_rmd160,
+      &dummy_extra_spec,                 GCRY_MD_RMD160 },
+#endif
+#if USE_SHA1
+    { &_gcry_digest_spec_sha1, 
+      &_gcry_digest_extraspec_sha1,      GCRY_MD_SHA1, 1 },
+#endif
+#if USE_SHA256
+    { &_gcry_digest_spec_sha256,
+      &_gcry_digest_extraspec_sha256,    GCRY_MD_SHA256, 1 },
+    { &_gcry_digest_spec_sha224,
+      &_gcry_digest_extraspec_sha224,    GCRY_MD_SHA224, 1 },
+#endif
+#if USE_SHA512
+    { &_gcry_digest_spec_sha512,
+      &_gcry_digest_extraspec_sha512,    GCRY_MD_SHA512, 1 },
+    { &_gcry_digest_spec_sha384,
+      &_gcry_digest_extraspec_sha384,    GCRY_MD_SHA384, 1 },
+#endif
+#if USE_TIGER
+    { &_gcry_digest_spec_tiger,
+      &dummy_extra_spec,                 GCRY_MD_TIGER },
+#endif
+#if USE_WHIRLPOOL
+    { &_gcry_digest_spec_whirlpool,
+      &dummy_extra_spec,                 GCRY_MD_WHIRLPOOL },
+#endif
+    { NULL },
+  };
+
+/* List of registered digests.  */
+static gcry_module_t digests_registered;
+
+/* This is the lock protecting DIGESTS_REGISTERED.  */
+static ath_mutex_t digests_registered_lock = ATH_MUTEX_INITIALIZER;
+
+/* Flag to check wether the default ciphers have already been
+   registered.  */
+static int default_digests_registered;
+
+typedef struct gcry_md_list
+{
+  gcry_md_spec_t *digest;
+  gcry_module_t module;
+  struct gcry_md_list *next;
+  size_t actual_struct_size;     /* Allocated size of this structure. */
+  PROPERLY_ALIGNED_TYPE context;
+} GcryDigestEntry;
+
+/* this structure is put right after the gcry_md_hd_t buffer, so that
+ * only one memory block is needed. */
+struct gcry_md_context
+{
+  int  magic;
+  size_t actual_handle_size;     /* Allocated size of this handle. */
+  int  secure;
+  FILE  *debug;
+  int finalized;
+  GcryDigestEntry *list;
+  byte *macpads;
+  int macpads_Bsize;             /* Blocksize as used for the HMAC pads. */
+};
+
+
+#define CTX_MAGIC_NORMAL 0x11071961
+#define CTX_MAGIC_SECURE 0x16917011
+
+/* Convenient macro for registering the default digests.  */
+#define REGISTER_DEFAULT_DIGESTS                   \
+  do                                               \
+    {                                              \
+      ath_mutex_lock (&digests_registered_lock);   \
+      if (! default_digests_registered)            \
+        {                                          \
+          md_register_default ();                  \
+          default_digests_registered = 1;          \
+        }                                          \
+      ath_mutex_unlock (&digests_registered_lock); \
+    }                                              \
+  while (0)
+
+
+static const char * digest_algo_to_string( int algo );
+static gcry_err_code_t check_digest_algo (int algo);
+static gcry_err_code_t md_open (gcry_md_hd_t *h, int algo,
+                                int secure, int hmac);
+static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo);
+static gcry_err_code_t md_copy (gcry_md_hd_t a, gcry_md_hd_t *b);
+static void md_close (gcry_md_hd_t a);
+static void md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen);
+static void md_final(gcry_md_hd_t a);
+static byte *md_read( gcry_md_hd_t a, int algo );
+static int md_get_algo( gcry_md_hd_t a );
+static int md_digest_length( int algo );
+static const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen );
+static void md_start_debug ( gcry_md_hd_t a, const char *suffix );
+static void md_stop_debug ( gcry_md_hd_t a );
+
+
+
+
+/* Internal function.  Register all the ciphers included in
+   CIPHER_TABLE.  Returns zero on success or an error code.  */
+static void
+md_register_default (void)
+{
+  gcry_err_code_t err = 0;
+  int i;
+  
+  for (i = 0; !err && digest_table[i].digest; i++)
+    {
+      if ( fips_mode ())
+        {
+          if (!digest_table[i].fips_allowed)
+            continue;
+          if (digest_table[i].algorithm == GCRY_MD_MD5
+              && _gcry_enforced_fips_mode () )
+            continue;  /* Do not register in enforced fips mode.  */
+        }
+
+      err = _gcry_module_add (&digests_registered,
+                              digest_table[i].algorithm,
+                              (void *) digest_table[i].digest,
+                              (void *) digest_table[i].extraspec,
+                              NULL);
+    }
+
+  if (err)
+    BUG ();
+}
+
+/* Internal callback function.  */
+static int
+gcry_md_lookup_func_name (void *spec, void *data)
+{
+  gcry_md_spec_t *digest = (gcry_md_spec_t *) spec;
+  char *name = (char *) data;
+
+  return (! stricmp (digest->name, name));
+}
+
+/* Internal callback function.  Used via _gcry_module_lookup.  */
+static int
+gcry_md_lookup_func_oid (void *spec, void *data)
+{
+  gcry_md_spec_t *digest = (gcry_md_spec_t *) spec;
+  char *oid = (char *) data;
+  gcry_md_oid_spec_t *oid_specs = digest->oids;
+  int ret = 0, i;
+
+  if (oid_specs)
+    {
+      for (i = 0; oid_specs[i].oidstring && (! ret); i++)
+        if (! stricmp (oid, oid_specs[i].oidstring))
+          ret = 1;
+    }
+
+  return ret;
+}
+
+/* Internal function.  Lookup a digest entry by it's name.  */
+static gcry_module_t 
+gcry_md_lookup_name (const char *name)
+{
+  gcry_module_t digest;
+
+  digest = _gcry_module_lookup (digests_registered, (void *) name,
+                               gcry_md_lookup_func_name);
+
+  return digest;
+}
+
+/* Internal function.  Lookup a cipher entry by it's oid.  */
+static gcry_module_t
+gcry_md_lookup_oid (const char *oid)
+{
+  gcry_module_t digest;
+
+  digest = _gcry_module_lookup (digests_registered, (void *) oid,
+                               gcry_md_lookup_func_oid);
+
+  return digest;
+}
+
+/* Register a new digest module whose specification can be found in
+   DIGEST.  On success, a new algorithm ID is stored in ALGORITHM_ID
+   and a pointer representhing this module is stored in MODULE.  */
+gcry_error_t
+_gcry_md_register (gcry_md_spec_t *digest,
+                   md_extra_spec_t *extraspec,
+                   unsigned int *algorithm_id,
+                   gcry_module_t *module)
+{
+  gcry_err_code_t err = 0;
+  gcry_module_t mod;
+
+  /* We do not support module loading in fips mode.  */
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  ath_mutex_lock (&digests_registered_lock);
+  err = _gcry_module_add (&digests_registered, 0,
+                         (void *) digest, 
+                         (void *)(extraspec? extraspec : &dummy_extra_spec), 
+                          &mod);
+  ath_mutex_unlock (&digests_registered_lock);
+  
+  if (! err)
+    {
+      *module = mod;
+      *algorithm_id = mod->mod_id;
+    }
+
+  return gcry_error (err);
+}
+
+/* Unregister the digest identified by ID, which must have been
+   registered with gcry_digest_register.  */
+void
+gcry_md_unregister (gcry_module_t module)
+{
+  ath_mutex_lock (&digests_registered_lock);
+  _gcry_module_release (module);
+  ath_mutex_unlock (&digests_registered_lock);
+}
+
+
+static int 
+search_oid (const char *oid, int *algorithm, gcry_md_oid_spec_t *oid_spec)
+{
+  gcry_module_t module;
+  int ret = 0;
+
+  if (oid && ((! strncmp (oid, "oid.", 4))
+             || (! strncmp (oid, "OID.", 4))))
+    oid += 4;
+
+  module = gcry_md_lookup_oid (oid);
+  if (module)
+    {
+      gcry_md_spec_t *digest = module->spec;
+      int i;
+
+      for (i = 0; digest->oids[i].oidstring && !ret; i++)
+       if (! stricmp (oid, digest->oids[i].oidstring))
+         {
+           if (algorithm)
+             *algorithm = module->mod_id;
+           if (oid_spec)
+             *oid_spec = digest->oids[i];
+           ret = 1;
+         }
+      _gcry_module_release (module);
+    }
+
+  return ret;
+}
+
+/****************
+ * Map a string to the digest algo
+ */
+int
+gcry_md_map_name (const char *string)
+{
+  gcry_module_t digest;
+  int ret, algorithm = 0;
+
+  if (! string)
+    return 0;
+
+  REGISTER_DEFAULT_DIGESTS;
+
+  /* If the string starts with a digit (optionally prefixed with
+     either "OID." or "oid."), we first look into our table of ASN.1
+     object identifiers to figure out the algorithm */
+
+  ath_mutex_lock (&digests_registered_lock);
+
+  ret = search_oid (string, &algorithm, NULL);
+  if (! ret)
+    {
+      /* Not found, search a matching digest name.  */
+      digest = gcry_md_lookup_name (string);
+      if (digest)
+       {
+         algorithm = digest->mod_id;
+         _gcry_module_release (digest);
+       }
+    }
+  ath_mutex_unlock (&digests_registered_lock);
+
+  return algorithm;
+}
+
+
+/****************
+ * Map a digest algo to a string
+ */
+static const char *
+digest_algo_to_string (int algorithm)
+{
+  const char *name = NULL;
+  gcry_module_t digest;
+
+  REGISTER_DEFAULT_DIGESTS;
+
+  ath_mutex_lock (&digests_registered_lock);
+  digest = _gcry_module_lookup_id (digests_registered, algorithm);
+  if (digest)
+    {
+      name = ((gcry_md_spec_t *) digest->spec)->name;
+      _gcry_module_release (digest);
+    }
+  ath_mutex_unlock (&digests_registered_lock);
+
+  return name;
+}
+
+/****************
+ * This function simply returns the name of the algorithm or some constant
+ * string when there is no algo.  It will never return NULL.
+ * Use the macro gcry_md_test_algo() to check whether the algorithm
+ * is valid.
+ */
+const char *
+gcry_md_algo_name (int algorithm)
+{
+  const char *s = digest_algo_to_string (algorithm);
+  return s ? s : "?";
+}
+
+
+static gcry_err_code_t
+check_digest_algo (int algorithm)
+{
+  gcry_err_code_t rc = 0;
+  gcry_module_t digest;
+
+  REGISTER_DEFAULT_DIGESTS;
+
+  ath_mutex_lock (&digests_registered_lock);
+  digest = _gcry_module_lookup_id (digests_registered, algorithm);
+  if (digest)
+    _gcry_module_release (digest);
+  else
+    rc = GPG_ERR_DIGEST_ALGO;
+  ath_mutex_unlock (&digests_registered_lock);
+
+  return rc;
+}
+
+
+
+/****************
+ * Open a message digest handle for use with algorithm ALGO.
+ * More algorithms may be added by md_enable(). The initial algorithm
+ * may be 0.
+ */
+static gcry_err_code_t
+md_open (gcry_md_hd_t *h, int algo, int secure, int hmac)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  int bufsize = secure ? 512 : 1024;
+  struct gcry_md_context *ctx;
+  gcry_md_hd_t hd;
+  size_t n;
+
+  /* Allocate a memory area to hold the caller visible buffer with it's
+   * control information and the data required by this module. Set the
+   * context pointer at the beginning to this area.
+   * We have to use this strange scheme because we want to hide the
+   * internal data but have a variable sized buffer.
+   *
+   *   +---+------+---........------+-------------+
+   *   !ctx! bctl !  buffer         ! private     !
+   *   +---+------+---........------+-------------+
+   *     !                           ^
+   *     !---------------------------!
+   *
+   * We have to make sure that private is well aligned.
+   */
+  n = sizeof (struct gcry_md_handle) + bufsize;
+  n = ((n + sizeof (PROPERLY_ALIGNED_TYPE) - 1)
+       / sizeof (PROPERLY_ALIGNED_TYPE)) * sizeof (PROPERLY_ALIGNED_TYPE);
+
+  /* Allocate and set the Context pointer to the private data */
+  if (secure)
+    hd = gcry_malloc_secure (n + sizeof (struct gcry_md_context));
+  else
+    hd = gcry_malloc (n + sizeof (struct gcry_md_context));
+
+  if (! hd)
+    err = gpg_err_code_from_errno (errno);
+
+  if (! err)
+    {
+      hd->ctx = ctx = (struct gcry_md_context *) ((char *) hd + n);
+      /* Setup the globally visible data (bctl in the diagram).*/
+      hd->bufsize = n - sizeof (struct gcry_md_handle) + 1;
+      hd->bufpos = 0;
+
+      /* Initialize the private data. */
+      memset (hd->ctx, 0, sizeof *hd->ctx);
+      ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
+      ctx->actual_handle_size = n + sizeof (struct gcry_md_context);
+      ctx->secure = secure;
+
+      if (hmac)
+       {
+         switch (algo)
+            {
+              case GCRY_MD_SHA384:
+              case GCRY_MD_SHA512:
+                ctx->macpads_Bsize = 128;
+                break;
+              default:
+                ctx->macpads_Bsize = 64;
+                break;
+            }
+          ctx->macpads = gcry_malloc_secure (2*(ctx->macpads_Bsize));
+         if (!ctx->macpads)
+           {
+             err = gpg_err_code_from_errno (errno);
+             md_close (hd);
+           }
+       }
+    }
+
+  if (! err)
+    {
+      /* Hmmm, should we really do that? - yes [-wk] */
+      _gcry_fast_random_poll ();
+
+      if (algo)
+       {
+         err = md_enable (hd, algo);
+         if (err)
+           md_close (hd);
+       }
+    }
+
+  if (! err)
+    *h = hd;
+
+  return err;
+}
+
+/* Create a message digest object for algorithm ALGO.  FLAGS may be
+   given as an bitwise OR of the gcry_md_flags values.  ALGO may be
+   given as 0 if the algorithms to be used are later set using
+   gcry_md_enable. H is guaranteed to be a valid handle or NULL on
+   error.  */
+gcry_error_t
+gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_md_hd_t hd;
+
+  if ((flags & ~(GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC)))
+    err = GPG_ERR_INV_ARG;
+  else
+    {
+      err = md_open (&hd, algo, (flags & GCRY_MD_FLAG_SECURE),
+                    (flags & GCRY_MD_FLAG_HMAC));
+    }
+
+  *h = err? NULL : hd;
+  return gcry_error (err);
+}
+
+
+
+static gcry_err_code_t
+md_enable (gcry_md_hd_t hd, int algorithm)
+{
+  struct gcry_md_context *h = hd->ctx;
+  gcry_md_spec_t *digest = NULL;
+  GcryDigestEntry *entry;
+  gcry_module_t module;
+  gcry_err_code_t err = 0;
+
+  for (entry = h->list; entry; entry = entry->next)
+    if (entry->module->mod_id == algorithm)
+      return err; /* already enabled */
+
+  REGISTER_DEFAULT_DIGESTS;
+
+  ath_mutex_lock (&digests_registered_lock);
+  module = _gcry_module_lookup_id (digests_registered, algorithm);
+  ath_mutex_unlock (&digests_registered_lock);
+  if (! module)
+    {
+      log_debug ("md_enable: algorithm %d not available\n", algorithm);
+      err = GPG_ERR_DIGEST_ALGO;
+    }
+ else
+    digest = (gcry_md_spec_t *) module->spec;
+
+  
+  if (!err && algorithm == GCRY_MD_MD5 && fips_mode ())
+    {
+      _gcry_inactivate_fips_mode ("MD5 used");
+      if (_gcry_enforced_fips_mode () )
+        {
+          /* We should never get to here because we do not register
+             MD5 in enforced fips mode. But better throw an error.  */
+          err = GPG_ERR_DIGEST_ALGO;
+        }
+    }
+  
+  if (!err)
+    {
+      size_t size = (sizeof (*entry)
+                     + digest->contextsize
+                     - sizeof (entry->context));
+
+      /* And allocate a new list entry. */
+      if (h->secure)
+       entry = gcry_malloc_secure (size);
+      else
+       entry = gcry_malloc (size);
+
+      if (! entry)
+       err = gpg_err_code_from_errno (errno);
+      else
+       {
+         entry->digest = digest;
+         entry->module = module;
+         entry->next = h->list;
+          entry->actual_struct_size = size;
+         h->list = entry;
+
+         /* And init this instance. */
+         entry->digest->init (&entry->context.c);
+       }
+    }
+
+  if (err)
+    {
+      if (module)
+       {
+          ath_mutex_lock (&digests_registered_lock);
+          _gcry_module_release (module);
+          ath_mutex_unlock (&digests_registered_lock);
+       }
+    }
+
+  return err;
+}
+
+
+gcry_error_t
+gcry_md_enable (gcry_md_hd_t hd, int algorithm)
+{
+  return gcry_error (md_enable (hd, algorithm));
+}
+
+static gcry_err_code_t
+md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  struct gcry_md_context *a = ahd->ctx;
+  struct gcry_md_context *b;
+  GcryDigestEntry *ar, *br;
+  gcry_md_hd_t bhd;
+  size_t n;
+  
+  if (ahd->bufpos)
+    md_write (ahd, NULL, 0);
+
+  n = (char *) ahd->ctx - (char *) ahd;
+  if (a->secure)
+    bhd = gcry_malloc_secure (n + sizeof (struct gcry_md_context));
+  else
+    bhd = gcry_malloc (n + sizeof (struct gcry_md_context));
+
+  if (! bhd)
+    err = gpg_err_code_from_errno (errno);
+
+  if (! err)
+    {
+      bhd->ctx = b = (struct gcry_md_context *) ((char *) bhd + n);
+      /* No need to copy the buffer due to the write above. */
+      gcry_assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1));
+      bhd->bufsize = ahd->bufsize;
+      bhd->bufpos = 0;
+      gcry_assert (! ahd->bufpos);
+      memcpy (b, a, sizeof *a);
+      b->list = NULL;
+      b->debug = NULL;
+      if (a->macpads)
+       {
+         b->macpads = gcry_malloc_secure (2*(a->macpads_Bsize));
+         if (! b->macpads)
+           {
+             err = gpg_err_code_from_errno (errno);
+             md_close (bhd);
+           }
+         else
+           memcpy (b->macpads, a->macpads, (2*(a->macpads_Bsize)));
+       }
+    }
+
+  /* Copy the complete list of algorithms.  The copied list is
+     reversed, but that doesn't matter. */
+  if (!err)
+    {
+      for (ar = a->list; ar; ar = ar->next)
+        {
+          if (a->secure)
+            br = gcry_malloc_secure (sizeof *br
+                                     + ar->digest->contextsize
+                                     - sizeof(ar->context));
+          else
+            br = gcry_malloc (sizeof *br
+                              + ar->digest->contextsize
+                              - sizeof (ar->context));
+          if (!br)
+            {
+             err = gpg_err_code_from_errno (errno);
+              md_close (bhd);
+              break;
+            }
+
+          memcpy (br, ar, (sizeof (*br) + ar->digest->contextsize
+                           - sizeof (ar->context)));
+          br->next = b->list;
+          b->list = br;
+          
+          /* Add a reference to the module.  */
+          ath_mutex_lock (&digests_registered_lock);
+          _gcry_module_use (br->module);
+          ath_mutex_unlock (&digests_registered_lock);
+        }
+    }
+
+  if (a->debug && !err)
+    md_start_debug (bhd, "unknown");
+
+  if (!err)
+    *b_hd = bhd;
+
+  return err;
+}
+
+gcry_error_t
+gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
+{
+  gcry_err_code_t err;
+
+  err = md_copy (hd, handle);
+  if (err)
+    *handle = NULL;
+  return gcry_error (err);
+}
+
+/*
+ * Reset all contexts and discard any buffered stuff.  This may be used
+ * instead of a md_close(); md_open().
+ */
+void
+gcry_md_reset (gcry_md_hd_t a)
+{
+  GcryDigestEntry *r;
+
+  /* Note: We allow this even in fips non operational mode.  */
+
+  a->bufpos = a->ctx->finalized = 0;
+
+  for (r = a->ctx->list; r; r = r->next)
+    {
+      memset (r->context.c, 0, r->digest->contextsize);
+      (*r->digest->init) (&r->context.c);
+    }
+  if (a->ctx->macpads)
+    md_write (a, a->ctx->macpads, a->ctx->macpads_Bsize); /* inner pad */
+}
+
+static void
+md_close (gcry_md_hd_t a)
+{
+  GcryDigestEntry *r, *r2;
+
+  if (! a)
+    return;
+  if (a->ctx->debug)
+    md_stop_debug (a);
+  for (r = a->ctx->list; r; r = r2)
+    {
+      r2 = r->next;
+      ath_mutex_lock (&digests_registered_lock);
+      _gcry_module_release (r->module);
+      ath_mutex_unlock (&digests_registered_lock);
+      wipememory (r, r->actual_struct_size);
+      gcry_free (r);
+    }
+
+  if (a->ctx->macpads)
+    {
+      wipememory (a->ctx->macpads, 2*(a->ctx->macpads_Bsize));
+      gcry_free(a->ctx->macpads);
+    }
+
+  wipememory (a, a->ctx->actual_handle_size);
+  gcry_free(a);
+}
+
+void
+gcry_md_close (gcry_md_hd_t hd)
+{
+  /* Note: We allow this even in fips non operational mode.  */
+  md_close (hd);
+}
+
+static void
+md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
+{
+  GcryDigestEntry *r;
+  
+  if (a->ctx->debug)
+    {
+      if (a->bufpos && fwrite (a->buf, a->bufpos, 1, a->ctx->debug) != 1)
+       BUG();
+      if (inlen && fwrite (inbuf, inlen, 1, a->ctx->debug) != 1)
+       BUG();
+    }
+
+  for (r = a->ctx->list; r; r = r->next)
+    {
+      if (a->bufpos)
+       (*r->digest->write) (&r->context.c, a->buf, a->bufpos);
+      (*r->digest->write) (&r->context.c, inbuf, inlen);
+    }
+  a->bufpos = 0;
+}
+
+void
+gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen)
+{
+  md_write (hd, inbuf, inlen);
+}
+
+static void
+md_final (gcry_md_hd_t a)
+{
+  GcryDigestEntry *r;
+
+  if (a->ctx->finalized)
+    return;
+
+  if (a->bufpos)
+    md_write (a, NULL, 0);
+
+  for (r = a->ctx->list; r; r = r->next)
+    (*r->digest->final) (&r->context.c);
+
+  a->ctx->finalized = 1;
+
+  if (a->ctx->macpads)
+    {
+      /* Finish the hmac. */
+      int algo = md_get_algo (a);
+      byte *p = md_read (a, algo);
+      size_t dlen = md_digest_length (algo);
+      gcry_md_hd_t om;
+      gcry_err_code_t err = md_open (&om, algo, a->ctx->secure, 0);
+
+      if (err)
+       _gcry_fatal_error (err, NULL);
+      md_write (om, 
+                (a->ctx->macpads)+(a->ctx->macpads_Bsize), 
+                a->ctx->macpads_Bsize);
+      md_write (om, p, dlen);
+      md_final (om);
+      /* Replace our digest with the mac (they have the same size). */
+      memcpy (p, md_read (om, algo), dlen);
+      md_close (om);
+    }
+}
+
+static gcry_err_code_t
+prepare_macpads (gcry_md_hd_t hd, const unsigned char *key, size_t keylen)
+{
+  int i;
+  int algo = md_get_algo (hd);
+  unsigned char *helpkey = NULL;
+  unsigned char *ipad, *opad;
+
+  if (!algo)
+    return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled.  */
+
+  if ( keylen > hd->ctx->macpads_Bsize ) 
+    {
+      helpkey = gcry_malloc_secure (md_digest_length (algo));
+      if (!helpkey)
+        return gpg_err_code_from_errno (errno);
+      gcry_md_hash_buffer (algo, helpkey, key, keylen);
+      key = helpkey;
+      keylen = md_digest_length (algo);
+      gcry_assert ( keylen <= hd->ctx->macpads_Bsize );
+    }
+
+  memset ( hd->ctx->macpads, 0, 2*(hd->ctx->macpads_Bsize) );
+  ipad = hd->ctx->macpads;
+  opad = (hd->ctx->macpads)+(hd->ctx->macpads_Bsize);
+  memcpy ( ipad, key, keylen );
+  memcpy ( opad, key, keylen );
+  for (i=0; i < hd->ctx->macpads_Bsize; i++ ) 
+    {
+      ipad[i] ^= 0x36;
+      opad[i] ^= 0x5c;
+    }
+  gcry_free (helpkey);
+
+  return GPG_ERR_NO_ERROR;
+}
+
+gcry_error_t
+gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
+{
+  gcry_err_code_t rc = 0;
+  
+  switch (cmd)
+    {
+    case GCRYCTL_FINALIZE:
+      md_final (hd);
+      break;
+    case GCRYCTL_SET_KEY:
+      rc = gcry_err_code (gcry_md_setkey (hd, buffer, buflen));
+      break;
+    case GCRYCTL_START_DUMP:
+      md_start_debug (hd, buffer);
+      break;
+    case GCRYCTL_STOP_DUMP:
+      md_stop_debug ( hd );
+      break;
+    default:
+      rc = GPG_ERR_INV_OP;
+    }
+  return gcry_error (rc);
+}
+
+gcry_error_t
+gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
+{
+  gcry_err_code_t rc = GPG_ERR_NO_ERROR;
+
+  if (!hd->ctx->macpads)
+    rc = GPG_ERR_CONFLICT;
+  else
+    {
+      rc = prepare_macpads (hd, key, keylen);
+      if (! rc)
+       gcry_md_reset (hd);
+    }
+
+  return gcry_error (rc);
+}
+
+/* The new debug interface.  If SUFFIX is a string it creates an debug
+   file for the context HD.  IF suffix is NULL, the file is closed and
+   debugging is stopped.  */
+void
+gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
+{
+  if (suffix)
+    md_start_debug (hd, suffix);
+  else
+    md_stop_debug (hd);
+}
+
+
+
+/****************
+ * if ALGO is null get the digest for the used algo (which should be only one)
+ */
+static byte *
+md_read( gcry_md_hd_t a, int algo )
+{
+  GcryDigestEntry *r = a->ctx->list;
+
+  if (! algo)
+    {
+      /* return the first algorithm */
+      if (r && r->next)
+       log_debug ("more than one algorithm in md_read(0)\n");
+      return r->digest->read( &r->context.c );
+    }
+  else
+    {
+      for (r = a->ctx->list; r; r = r->next)
+       if (r->module->mod_id == algo)
+         return r->digest->read (&r->context.c);
+    }
+  BUG();
+  return NULL;
+}
+
+/*
+ * Read out the complete digest, this function implictly finalizes
+ * the hash.
+ */
+byte *
+gcry_md_read (gcry_md_hd_t hd, int algo)
+{
+  /* This function is expected to always return a digest, thus we
+     can't return an error which we actually should do in
+     non-operational state.  */
+  gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
+  return md_read (hd, algo);
+}
+
+
+/*
+ * Read out an intermediate digest.  Not yet functional.
+ */
+gcry_err_code_t
+gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen)
+{
+  (void)hd;
+  (void)algo;
+  (void)buffer;
+  (void)buflen;
+
+  /*md_digest ... */
+  fips_signal_error ("unimplemented function called");
+  return GPG_ERR_INTERNAL;
+}
+
+
+/*
+ * Shortcut function to hash a buffer with a given algo. The only
+ * guaranteed supported algorithms are RIPE-MD160 and SHA-1. The
+ * supplied digest buffer must be large enough to store the resulting
+ * hash.  No error is returned, the function will abort on an invalid
+ * algo.  DISABLED_ALGOS are ignored here.  */
+void
+gcry_md_hash_buffer (int algo, void *digest,
+                     const void *buffer, size_t length)
+{
+  if (algo == GCRY_MD_SHA1)
+    _gcry_sha1_hash_buffer (digest, buffer, length);
+  else if (algo == GCRY_MD_RMD160 && !fips_mode () )
+    _gcry_rmd160_hash_buffer (digest, buffer, length);
+  else
+    {
+      /* For the others we do not have a fast function, so we use the
+        normal functions. */
+      gcry_md_hd_t h;
+      gpg_err_code_t err;
+
+      if (algo == GCRY_MD_MD5 && fips_mode ())
+        {
+          _gcry_inactivate_fips_mode ("MD5 used");
+          if (_gcry_enforced_fips_mode () )
+            {
+              /* We should never get to here because we do not register
+                 MD5 in enforced fips mode.  */
+              _gcry_fips_noreturn ();
+            }
+        }
+
+      err = md_open (&h, algo, 0, 0);
+      if (err)
+       log_bug ("gcry_md_open failed for algo %d: %s",
+                 algo, gpg_strerror (gcry_error(err)));
+      md_write (h, (byte *) buffer, length);
+      md_final (h);
+      memcpy (digest, md_read (h, algo), md_digest_length (algo));
+      md_close (h);
+    }
+}
+
+static int
+md_get_algo (gcry_md_hd_t a)
+{
+  GcryDigestEntry *r = a->ctx->list;
+
+  if (r && r->next)
+    {
+      fips_signal_error ("possible usage error");
+      log_error ("WARNING: more than one algorithm in md_get_algo()\n");
+    }
+  return r ? r->module->mod_id : 0;
+}
+
+int
+gcry_md_get_algo (gcry_md_hd_t hd)
+{
+  return md_get_algo (hd);
+}
+
+
+/****************
+ * Return the length of the digest
+ */
+static int
+md_digest_length (int algorithm)
+{
+  gcry_module_t digest;
+  int mdlen = 0;
+
+  REGISTER_DEFAULT_DIGESTS;
+
+  ath_mutex_lock (&digests_registered_lock);
+  digest = _gcry_module_lookup_id (digests_registered, algorithm);
+  if (digest)
+    {
+      mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen;
+      _gcry_module_release (digest);
+    }
+  ath_mutex_unlock (&digests_registered_lock);
+
+  return mdlen;
+}
+
+/****************
+ * Return the length of the digest in bytes.
+ * This function will return 0 in case of errors.
+ */
+unsigned int
+gcry_md_get_algo_dlen (int algorithm)
+{
+  return md_digest_length (algorithm);
+}
+
+
+/* Hmmm: add a mode to enumerate the OIDs
+ *     to make g10/sig-check.c more portable */
+static const byte *
+md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
+{
+  const byte *asnoid = NULL;
+  gcry_module_t digest;
+
+  REGISTER_DEFAULT_DIGESTS;
+
+  ath_mutex_lock (&digests_registered_lock);
+  digest = _gcry_module_lookup_id (digests_registered, algorithm);
+  if (digest)
+    {
+      if (asnlen)
+       *asnlen = ((gcry_md_spec_t *) digest->spec)->asnlen;
+      if (mdlen)
+       *mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen;
+      asnoid = ((gcry_md_spec_t *) digest->spec)->asnoid;
+      _gcry_module_release (digest);
+    }
+  else
+    log_bug ("no ASN.1 OID for md algo %d\n", algorithm);
+  ath_mutex_unlock (&digests_registered_lock);
+
+  return asnoid;
+}
+
+
+
+/****************
+ * Return information about the given cipher algorithm
+ * WHAT select the kind of information returned:
+ *  GCRYCTL_TEST_ALGO:
+ *     Returns 0 when the specified algorithm is available for use.
+ *     buffer and nbytes must be zero.
+ *  GCRYCTL_GET_ASNOID:
+ *     Return the ASNOID of the algorithm in buffer. if buffer is NULL, only
+ *     the required length is returned.
+ *
+ * Note:  Because this function is in most cases used to return an
+ * integer value, we can make it easier for the caller to just look at
+ * the return value.  The caller will in all cases consult the value
+ * and thereby detecting whether a error occured or not (i.e. while checking
+ * the block size)
+ */
+gcry_error_t
+gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+  switch (what)
+    {
+    case GCRYCTL_TEST_ALGO:
+      if (buffer || nbytes)
+       err = GPG_ERR_INV_ARG;
+      else
+       err = check_digest_algo (algo);
+      break;
+
+    case GCRYCTL_GET_ASNOID:
+      /* We need to check that the algo is available because
+         md_asn_oid would otherwise raise an assertion. */
+      err = check_digest_algo (algo);
+      if (!err)
+        {
+          const char unsigned *asn;
+          size_t asnlen;
+          
+          asn = md_asn_oid (algo, &asnlen, NULL);
+          if (buffer && (*nbytes >= asnlen))
+         {
+           memcpy (buffer, asn, asnlen);
+           *nbytes = asnlen;
+         }
+          else if (!buffer && nbytes)
+            *nbytes = asnlen;
+          else
+            {
+              if (buffer)
+                err = GPG_ERR_TOO_SHORT;
+              else
+                err = GPG_ERR_INV_ARG;
+            }
+        }
+      break;
+
+  default:
+    err = GPG_ERR_INV_OP;
+  }
+
+  return gcry_error (err);
+}
+
+
+static void
+md_start_debug ( gcry_md_hd_t md, const char *suffix )
+{
+  static int idx=0;
+  char buf[50];
+
+  if (fips_mode ())
+    return;
+  
+  if ( md->ctx->debug )
+    {
+      log_debug("Oops: md debug already started\n");
+      return;
+    }
+  idx++;
+  snprintf (buf, DIM(buf)-1, "dbgmd-%05d.%.10s", idx, suffix );
+  md->ctx->debug = fopen(buf, "w");
+  if ( !md->ctx->debug )
+    log_debug("md debug: can't open %s\n", buf );
+}
+
+static void
+md_stop_debug( gcry_md_hd_t md )
+{
+  if ( md->ctx->debug )
+    {
+      if ( md->bufpos )
+        md_write ( md, NULL, 0 );
+      fclose (md->ctx->debug);
+      md->ctx->debug = NULL;
+    }
+
+#ifdef HAVE_U64_TYPEDEF
+  {  /* a kludge to pull in the __muldi3 for Solaris */
+    volatile u32 a = (u32)(ulong)md;
+    volatile u64 b = 42;
+    volatile u64 c;
+    c = a * b;
+  }
+#endif
+}
+
+
+
+/*
+ * Return information about the digest handle.
+ *  GCRYCTL_IS_SECURE:
+ *     Returns 1 when the handle works on secured memory
+ *     otherwise 0 is returned.  There is no error return.
+ *  GCRYCTL_IS_ALGO_ENABLED:
+ *     Returns 1 if the algo is enabled for that handle.
+ *     The algo must be passed as the address of an int.
+ */
+gcry_error_t
+gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+  switch (cmd)
+    {
+    case GCRYCTL_IS_SECURE:
+      *nbytes = h->ctx->secure;
+      break;
+
+    case GCRYCTL_IS_ALGO_ENABLED:
+      {
+       GcryDigestEntry *r;
+       int algo;
+
+       if ( !buffer || (nbytes && (*nbytes != sizeof (int))))
+         err = GPG_ERR_INV_ARG;
+       else
+         {
+           algo = *(int*)buffer;
+           
+           *nbytes = 0;
+           for(r=h->ctx->list; r; r = r->next ) {
+             if (r->module->mod_id == algo)
+               {
+                 *nbytes = 1;
+                 break;
+               }
+           }
+         }
+       break;
+      }
+
+  default:
+    err = GPG_ERR_INV_OP;
+  }
+
+  return gcry_error (err);
+}
+
+
+/* Explicitly initialize this module.  */
+gcry_err_code_t
+_gcry_md_init (void)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+  REGISTER_DEFAULT_DIGESTS;
+
+  return err;
+}
+
+
+int
+gcry_md_is_secure (gcry_md_hd_t a) 
+{
+  size_t value;
+
+  if (gcry_md_info (a, GCRYCTL_IS_SECURE, NULL, &value))
+    value = 1; /* It seems to be better to assume secure memory on
+                  error. */
+  return value;
+}
+
+
+int
+gcry_md_is_enabled (gcry_md_hd_t a, int algo) 
+{
+  size_t value;
+
+  value = sizeof algo;
+  if (gcry_md_info (a, GCRYCTL_IS_ALGO_ENABLED, &algo, &value))
+    value = 0;
+  return value;
+}
+
+/* Get a list consisting of the IDs of the loaded message digest
+   modules.  If LIST is zero, write the number of loaded message
+   digest modules to LIST_LENGTH and return.  If LIST is non-zero, the
+   first *LIST_LENGTH algorithm IDs are stored in LIST, which must be
+   of according size.  In case there are less message digest modules
+   than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
+   number.  */
+gcry_error_t
+gcry_md_list (int *list, int *list_length)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+  ath_mutex_lock (&digests_registered_lock);
+  err = _gcry_module_list (digests_registered, list, list_length);
+  ath_mutex_unlock (&digests_registered_lock);
+
+  return err;
+}
+
+
+/* Run the selftests for digest algorithm ALGO with optional reporting
+   function REPORT.  */
+gpg_error_t
+_gcry_md_selftest (int algo, int extended, selftest_report_func_t report)
+{
+  gcry_module_t module = NULL;
+  cipher_extra_spec_t *extraspec = NULL;
+  gcry_err_code_t ec = 0;
+
+  REGISTER_DEFAULT_DIGESTS;
+
+  ath_mutex_lock (&digests_registered_lock);
+  module = _gcry_module_lookup_id (digests_registered, algo);
+  if (module && !(module->flags & FLAG_MODULE_DISABLED))
+    extraspec = module->extraspec;
+  ath_mutex_unlock (&digests_registered_lock);
+  if (extraspec && extraspec->selftest)
+    ec = extraspec->selftest (algo, extended, report);
+  else
+    {
+      ec = GPG_ERR_DIGEST_ALGO;
+      if (report)
+        report ("digest", algo, "module", 
+                module && !(module->flags & FLAG_MODULE_DISABLED)?
+                "no selftest available" :
+                module? "algorithm disabled" : "algorithm not found");
+    }
+
+  if (module)
+    {
+      ath_mutex_lock (&digests_registered_lock);
+      _gcry_module_release (module);
+      ath_mutex_unlock (&digests_registered_lock);
+    }
+  return gpg_error (ec);
+}
diff --git a/grub-core/lib/libgcrypt/cipher/md4.c b/grub-core/lib/libgcrypt/cipher/md4.c
new file mode 100644 (file)
index 0000000..680cf87
--- /dev/null
@@ -0,0 +1,328 @@
+/* md4.c - MD4 Message-Digest Algorithm
+ * Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Based on md5.c in libgcrypt, but rewritten to compute md4 checksums
+ * using a public domain md4 implementation with the following comments:
+ *
+ * Modified by Wei Dai from Andrew M. Kuchling's md4.c
+ * The original code and all modifications are in the public domain.
+ *
+ * This is the original introductory comment:
+ *
+ *  md4.c : MD4 hash algorithm.
+ *
+ * Part of the Python Cryptography Toolkit, version 1.1
+ *
+ * Distribute and use freely; there are no restrictions on further
+ * dissemination and usage except those imposed by the laws of your
+ * country of residence.
+ *
+ */
+
+/* MD4 test suite:
+ * MD4 ("") = 31d6cfe0d16ae931b73c59d7e0c089c0
+ * MD4 ("a") = bde52cb31de33e46245e05fbdbd6fb24
+ * MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d
+ * MD4 ("message digest") = d9130a8164549fe818874806e1c7014b
+ * MD4 ("abcdefghijklmnopqrstuvwxyz") = d79e1c308aa5bbcdeea8ed63df412da9
+ * MD4 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
+ * 043f8582f241db351ce627e153e7f0e4
+ * MD4 ("123456789012345678901234567890123456789012345678901234567890123456
+ * 78901234567890") = e33b4ddc9c38f2199c3e7b164fcc0536
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "memory.h"
+#include "cipher.h"
+
+#include "bithelp.h"
+
+
+typedef struct {
+    u32 A,B,C,D;         /* chaining variables */
+    u32  nblocks;
+    byte buf[64];
+    int  count;
+} MD4_CONTEXT;
+
+
+static void
+md4_init( void *context )
+{
+  MD4_CONTEXT *ctx = context;
+
+  ctx->A = 0x67452301;
+  ctx->B = 0xefcdab89;
+  ctx->C = 0x98badcfe;
+  ctx->D = 0x10325476;
+
+  ctx->nblocks = 0;
+  ctx->count = 0;
+}
+
+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+
+
+/****************
+ * transform 64 bytes
+ */
+static void
+transform ( MD4_CONTEXT *ctx, const unsigned char *data )
+{
+  u32 in[16];
+  register u32 A = ctx->A;
+  register u32 B = ctx->B;
+  register u32 C = ctx->C;
+  register u32 D = ctx->D;
+
+#ifdef WORDS_BIGENDIAN
+  {
+    int i;
+    byte *p2, *p1;
+    for(i=0, p1=data, p2=(byte*)in; i < 16; i++, p2 += 4 )
+      {
+       p2[3] = *p1++;
+       p2[2] = *p1++;
+       p2[1] = *p1++;
+       p2[0] = *p1++;
+      }
+  }
+#else
+  memcpy (in, data, 64);
+#endif
+
+  /* Round 1.  */
+#define function(a,b,c,d,k,s) a=rol(a+F(b,c,d)+in[k],s);
+  function(A,B,C,D, 0, 3);
+  function(D,A,B,C, 1, 7);
+  function(C,D,A,B, 2,11);
+  function(B,C,D,A, 3,19);
+  function(A,B,C,D, 4, 3);
+  function(D,A,B,C, 5, 7);
+  function(C,D,A,B, 6,11);
+  function(B,C,D,A, 7,19);
+  function(A,B,C,D, 8, 3);
+  function(D,A,B,C, 9, 7);
+  function(C,D,A,B,10,11);
+  function(B,C,D,A,11,19);
+  function(A,B,C,D,12, 3);
+  function(D,A,B,C,13, 7);
+  function(C,D,A,B,14,11);
+  function(B,C,D,A,15,19);
+
+#undef function
+
+  /* Round 2.  */
+#define function(a,b,c,d,k,s) a=rol(a+G(b,c,d)+in[k]+0x5a827999,s);
+
+  function(A,B,C,D, 0, 3);
+  function(D,A,B,C, 4, 5);
+  function(C,D,A,B, 8, 9);
+  function(B,C,D,A,12,13);
+  function(A,B,C,D, 1, 3);
+  function(D,A,B,C, 5, 5);
+  function(C,D,A,B, 9, 9);
+  function(B,C,D,A,13,13);
+  function(A,B,C,D, 2, 3);
+  function(D,A,B,C, 6, 5);
+  function(C,D,A,B,10, 9);
+  function(B,C,D,A,14,13);
+  function(A,B,C,D, 3, 3);
+  function(D,A,B,C, 7, 5);
+  function(C,D,A,B,11, 9);
+  function(B,C,D,A,15,13);
+
+#undef function
+
+  /* Round 3.  */
+#define function(a,b,c,d,k,s) a=rol(a+H(b,c,d)+in[k]+0x6ed9eba1,s);
+
+  function(A,B,C,D, 0, 3);
+  function(D,A,B,C, 8, 9);
+  function(C,D,A,B, 4,11);
+  function(B,C,D,A,12,15);
+  function(A,B,C,D, 2, 3);
+  function(D,A,B,C,10, 9);
+  function(C,D,A,B, 6,11);
+  function(B,C,D,A,14,15);
+  function(A,B,C,D, 1, 3);
+  function(D,A,B,C, 9, 9);
+  function(C,D,A,B, 5,11);
+  function(B,C,D,A,13,15);
+  function(A,B,C,D, 3, 3);
+  function(D,A,B,C,11, 9);
+  function(C,D,A,B, 7,11);
+  function(B,C,D,A,15,15);
+
+
+  /* Put checksum in context given as argument.  */
+  ctx->A += A;
+  ctx->B += B;
+  ctx->C += C;
+  ctx->D += D;
+}
+
+
+
+/* The routine updates the message-digest context to
+ * account for the presence of each of the characters inBuf[0..inLen-1]
+ * in the message whose digest is being computed.
+ */
+static void
+md4_write ( void *context, const void *inbuf_arg, size_t inlen)
+{
+  const unsigned char *inbuf = inbuf_arg;
+  MD4_CONTEXT *hd = context;
+
+  if( hd->count == 64 ) /* flush the buffer */
+    { 
+      transform( hd, hd->buf );
+      _gcry_burn_stack (80+6*sizeof(void*));
+      hd->count = 0;
+      hd->nblocks++;
+    }
+  if( !inbuf )
+    return;
+
+  if( hd->count )
+    {
+      for( ; inlen && hd->count < 64; inlen-- )
+        hd->buf[hd->count++] = *inbuf++;
+      md4_write( hd, NULL, 0 );
+      if( !inlen )
+        return;
+    }
+  _gcry_burn_stack (80+6*sizeof(void*));
+
+  while( inlen >= 64 )
+    {
+      transform( hd, inbuf );
+      hd->count = 0;
+      hd->nblocks++;
+      inlen -= 64;
+      inbuf += 64;
+    }
+  for( ; inlen && hd->count < 64; inlen-- )
+    hd->buf[hd->count++] = *inbuf++;
+}
+
+
+
+/* The routine final terminates the message-digest computation and
+ * ends with the desired message digest in mdContext->digest[0...15].
+ * The handle is prepared for a new MD4 cycle.
+ * Returns 16 bytes representing the digest.
+ */
+
+static void
+md4_final( void *context )
+{
+  MD4_CONTEXT *hd = context;
+  u32 t, msb, lsb;
+  byte *p;
+
+  md4_write(hd, NULL, 0); /* flush */;
+
+  t = hd->nblocks;
+  /* multiply by 64 to make a byte count */
+  lsb = t << 6;
+  msb = t >> 26;
+  /* add the count */
+  t = lsb;
+  if( (lsb += hd->count) < t )
+    msb++;
+  /* multiply by 8 to make a bit count */
+  t = lsb;
+  lsb <<= 3;
+  msb <<= 3;
+  msb |= t >> 29;
+  
+  if( hd->count < 56 )  /* enough room */
+    {
+      hd->buf[hd->count++] = 0x80; /* pad */
+      while( hd->count < 56 )
+        hd->buf[hd->count++] = 0;  /* pad */
+    }
+  else /* need one extra block */ 
+    { 
+      hd->buf[hd->count++] = 0x80; /* pad character */
+      while( hd->count < 64 )
+        hd->buf[hd->count++] = 0;
+      md4_write(hd, NULL, 0);  /* flush */;
+      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+    }
+  /* append the 64 bit count */
+  hd->buf[56] = lsb       ;
+  hd->buf[57] = lsb >>  8;
+  hd->buf[58] = lsb >> 16;
+  hd->buf[59] = lsb >> 24;
+  hd->buf[60] = msb       ;
+  hd->buf[61] = msb >>  8;
+  hd->buf[62] = msb >> 16;
+  hd->buf[63] = msb >> 24;
+  transform( hd, hd->buf );
+  _gcry_burn_stack (80+6*sizeof(void*));
+
+  p = hd->buf;
+#ifdef WORDS_BIGENDIAN
+#define X(a) do { *p++ = hd->a      ; *p++ = hd->a >> 8;      \
+                 *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
+#else /* little endian */
+#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0)
+#endif
+  X(A);
+  X(B);
+  X(C);
+  X(D);
+#undef X
+
+}
+
+static byte *
+md4_read (void *context)
+{
+  MD4_CONTEXT *hd = context;
+  return hd->buf;
+}
+
+static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */
+  { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
+    0x86, 0xf7, 0x0d, 0x02, 0x04, 0x05, 0x00, 0x04, 0x10 };
+
+static gcry_md_oid_spec_t oid_spec_md4[] =
+  {
+    /* iso.member-body.us.rsadsi.digestAlgorithm.md4 */
+    { "1.2.840.113549.2.4" },
+    { NULL },
+  };
+
+gcry_md_spec_t _gcry_digest_spec_md4 =
+  {
+    "MD4", asn, DIM (asn), oid_spec_md4,16,
+    md4_init, md4_write, md4_final, md4_read,
+    sizeof (MD4_CONTEXT)
+  };
+
diff --git a/grub-core/lib/libgcrypt/cipher/md5.c b/grub-core/lib/libgcrypt/cipher/md5.c
new file mode 100644 (file)
index 0000000..899dce8
--- /dev/null
@@ -0,0 +1,355 @@
+/* md5.c - MD5 Message-Digest Algorithm
+ * Copyright (C) 1995,1996,1998,1999,2001,2002,
+ *               2003  Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * According to the definition of MD5 in RFC 1321 from April 1992.
+ * NOTE: This is *not* the same file as the one from glibc.
+ * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. 
+ * heavily modified for GnuPG by Werner Koch <wk@gnupg.org> 
+ */
+
+/* Test values:
+ * ""                  D4 1D 8C D9 8F 00 B2 04  E9 80 09 98 EC F8 42 7E
+ * "a"                 0C C1 75 B9 C0 F1 B6 A8  31 C3 99 E2 69 77 26 61
+ * "abc                90 01 50 98 3C D2 4F B0  D6 96 3F 7D 28 E1 7F 72
+ * "message digest"    F9 6B 69 7D 7C B7 93 8D  52 5A 2F 31 AA F1 61 D0
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "memory.h"
+#include "cipher.h"
+
+#include "bithelp.h"
+
+
+typedef struct {
+    u32 A,B,C,D;         /* chaining variables */
+    u32  nblocks;
+    byte buf[64];
+    int  count;
+} MD5_CONTEXT;
+
+
+static void
+md5_init( void *context )
+{
+  MD5_CONTEXT *ctx = context;
+
+  ctx->A = 0x67452301;
+  ctx->B = 0xefcdab89;
+  ctx->C = 0x98badcfe;
+  ctx->D = 0x10325476;
+
+  ctx->nblocks = 0;
+  ctx->count = 0;
+}
+
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+   and defined in the RFC 1321.  The first function is a little bit optimized
+   (as found in Colin Plumbs public domain implementation).  */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF (d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+
+/****************
+ * transform n*64 bytes
+ */
+static void
+transform ( MD5_CONTEXT *ctx, const unsigned char *data )
+{
+  u32 correct_words[16];
+  register u32 A = ctx->A;
+  register u32 B = ctx->B;
+  register u32 C = ctx->C;
+  register u32 D = ctx->D;
+  u32 *cwp = correct_words;
+    
+#ifdef WORDS_BIGENDIAN
+  { 
+    int i;
+    byte *p2, *p1;
+    for(i=0, p1=data, p2=(byte*)correct_words; i < 16; i++, p2 += 4 )
+      {
+        p2[3] = *p1++;
+       p2[2] = *p1++;
+       p2[1] = *p1++;
+       p2[0] = *p1++;
+      }
+  }
+#else
+  memcpy( correct_words, data, 64 );
+#endif
+
+
+#define OP(a, b, c, d, s, T) \
+  do                                      \
+    {                                     \
+      a += FF (b, c, d) + (*cwp++) + T;    \
+      a = rol(a, s);                      \
+      a += b;                             \
+    }                                     \
+  while (0)
+
+  /* Before we start, one word about the strange constants.
+     They are defined in RFC 1321 as
+
+     T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
+  */
+
+  /* Round 1.  */
+  OP (A, B, C, D,  7, 0xd76aa478);
+  OP (D, A, B, C, 12, 0xe8c7b756);
+  OP (C, D, A, B, 17, 0x242070db);
+  OP (B, C, D, A, 22, 0xc1bdceee);
+  OP (A, B, C, D,  7, 0xf57c0faf);
+  OP (D, A, B, C, 12, 0x4787c62a);
+  OP (C, D, A, B, 17, 0xa8304613);
+  OP (B, C, D, A, 22, 0xfd469501);
+  OP (A, B, C, D,  7, 0x698098d8);
+  OP (D, A, B, C, 12, 0x8b44f7af);
+  OP (C, D, A, B, 17, 0xffff5bb1);
+  OP (B, C, D, A, 22, 0x895cd7be);
+  OP (A, B, C, D,  7, 0x6b901122);
+  OP (D, A, B, C, 12, 0xfd987193);
+  OP (C, D, A, B, 17, 0xa679438e);
+  OP (B, C, D, A, 22, 0x49b40821);
+
+#undef OP
+#define OP(f, a, b, c, d, k, s, T)  \
+    do                                                               \
+      {                                                              \
+       a += f (b, c, d) + correct_words[k] + T;                      \
+       a = rol(a, s);                                                \
+       a += b;                                                       \
+      }                                                              \
+    while (0)
+
+  /* Round 2.  */
+  OP (FG, A, B, C, D,  1,  5, 0xf61e2562);
+  OP (FG, D, A, B, C,  6,  9, 0xc040b340);
+  OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
+  OP (FG, B, C, D, A,  0, 20, 0xe9b6c7aa);
+  OP (FG, A, B, C, D,  5,  5, 0xd62f105d);
+  OP (FG, D, A, B, C, 10,  9, 0x02441453);
+  OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
+  OP (FG, B, C, D, A,  4, 20, 0xe7d3fbc8);
+  OP (FG, A, B, C, D,  9,  5, 0x21e1cde6);
+  OP (FG, D, A, B, C, 14,  9, 0xc33707d6);
+  OP (FG, C, D, A, B,  3, 14, 0xf4d50d87);
+  OP (FG, B, C, D, A,  8, 20, 0x455a14ed);
+  OP (FG, A, B, C, D, 13,  5, 0xa9e3e905);
+  OP (FG, D, A, B, C,  2,  9, 0xfcefa3f8);
+  OP (FG, C, D, A, B,  7, 14, 0x676f02d9);
+  OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+  /* Round 3.  */
+  OP (FH, A, B, C, D,  5,  4, 0xfffa3942);
+  OP (FH, D, A, B, C,  8, 11, 0x8771f681);
+  OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
+  OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
+  OP (FH, A, B, C, D,  1,  4, 0xa4beea44);
+  OP (FH, D, A, B, C,  4, 11, 0x4bdecfa9);
+  OP (FH, C, D, A, B,  7, 16, 0xf6bb4b60);
+  OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
+  OP (FH, A, B, C, D, 13,  4, 0x289b7ec6);
+  OP (FH, D, A, B, C,  0, 11, 0xeaa127fa);
+  OP (FH, C, D, A, B,  3, 16, 0xd4ef3085);
+  OP (FH, B, C, D, A,  6, 23, 0x04881d05);
+  OP (FH, A, B, C, D,  9,  4, 0xd9d4d039);
+  OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
+  OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+  OP (FH, B, C, D, A,  2, 23, 0xc4ac5665);
+
+  /* Round 4.  */
+  OP (FI, A, B, C, D,  0,  6, 0xf4292244);
+  OP (FI, D, A, B, C,  7, 10, 0x432aff97);
+  OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
+  OP (FI, B, C, D, A,  5, 21, 0xfc93a039);
+  OP (FI, A, B, C, D, 12,  6, 0x655b59c3);
+  OP (FI, D, A, B, C,  3, 10, 0x8f0ccc92);
+  OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
+  OP (FI, B, C, D, A,  1, 21, 0x85845dd1);
+  OP (FI, A, B, C, D,  8,  6, 0x6fa87e4f);
+  OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+  OP (FI, C, D, A, B,  6, 15, 0xa3014314);
+  OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
+  OP (FI, A, B, C, D,  4,  6, 0xf7537e82);
+  OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
+  OP (FI, C, D, A, B,  2, 15, 0x2ad7d2bb);
+  OP (FI, B, C, D, A,  9, 21, 0xeb86d391);
+
+  /* Put checksum in context given as argument.  */
+  ctx->A += A;
+  ctx->B += B;
+  ctx->C += C;
+  ctx->D += D;
+}
+
+
+
+/* The routine updates the message-digest context to
+ * account for the presence of each of the characters inBuf[0..inLen-1]
+ * in the message whose digest is being computed.
+ */
+static void
+md5_write( void *context, const void *inbuf_arg , size_t inlen)
+{
+  const unsigned char *inbuf = inbuf_arg;
+  MD5_CONTEXT *hd = context;
+  
+  if( hd->count == 64 )  /* flush the buffer */
+    {
+      transform( hd, hd->buf );
+      _gcry_burn_stack (80+6*sizeof(void*));
+      hd->count = 0;
+      hd->nblocks++;
+    }
+  if( !inbuf )
+    return;
+
+  if( hd->count )
+    {
+      for( ; inlen && hd->count < 64; inlen-- )
+        hd->buf[hd->count++] = *inbuf++;
+      md5_write( hd, NULL, 0 );
+      if( !inlen )
+        return;
+    }
+  _gcry_burn_stack (80+6*sizeof(void*));
+
+  while( inlen >= 64 ) 
+    {
+      transform( hd, inbuf );
+      hd->count = 0;
+      hd->nblocks++;
+      inlen -= 64;
+      inbuf += 64;
+    }
+  for( ; inlen && hd->count < 64; inlen-- )
+    hd->buf[hd->count++] = *inbuf++;
+
+}
+
+
+
+/* The routine final terminates the message-digest computation and
+ * ends with the desired message digest in mdContext->digest[0...15].
+ * The handle is prepared for a new MD5 cycle.
+ * Returns 16 bytes representing the digest.
+ */
+
+static void
+md5_final( void *context)
+{
+  MD5_CONTEXT *hd = context;
+  u32 t, msb, lsb;
+  byte *p;
+  
+  md5_write(hd, NULL, 0); /* flush */;
+
+  t = hd->nblocks;
+  /* multiply by 64 to make a byte count */
+  lsb = t << 6;
+  msb = t >> 26;
+  /* add the count */
+  t = lsb;
+  if( (lsb += hd->count) < t )
+    msb++;
+  /* multiply by 8 to make a bit count */
+  t = lsb;
+  lsb <<= 3;
+  msb <<= 3;
+  msb |= t >> 29;
+
+  if( hd->count < 56 )  /* enough room */
+    {
+      hd->buf[hd->count++] = 0x80; /* pad */
+      while( hd->count < 56 )
+        hd->buf[hd->count++] = 0;  /* pad */
+    }
+  else  /* need one extra block */
+    {
+      hd->buf[hd->count++] = 0x80; /* pad character */
+      while( hd->count < 64 )
+        hd->buf[hd->count++] = 0;
+      md5_write(hd, NULL, 0);  /* flush */;
+      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+    }
+  /* append the 64 bit count */
+  hd->buf[56] = lsb       ;
+  hd->buf[57] = lsb >>  8;
+  hd->buf[58] = lsb >> 16;
+  hd->buf[59] = lsb >> 24;
+  hd->buf[60] = msb       ;
+  hd->buf[61] = msb >>  8;
+  hd->buf[62] = msb >> 16;
+  hd->buf[63] = msb >> 24;
+  transform( hd, hd->buf );
+  _gcry_burn_stack (80+6*sizeof(void*));
+
+  p = hd->buf;
+#ifdef WORDS_BIGENDIAN
+#define X(a) do { *p++ = hd->a      ; *p++ = hd->a >> 8;      \
+                 *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
+#else /* little endian */
+#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0)
+#endif
+  X(A);
+  X(B);
+  X(C);
+  X(D);
+#undef X
+
+}
+
+static byte *
+md5_read( void *context )
+{
+  MD5_CONTEXT *hd = (MD5_CONTEXT *) context;
+  return hd->buf;
+}
+
+static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */
+  { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
+    0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
+
+static gcry_md_oid_spec_t oid_spec_md5[] =
+  {
+    /* iso.member-body.us.rsadsi.pkcs.pkcs-1.4 (md5WithRSAEncryption) */
+    { "1.2.840.113549.1.1.4" },
+    /* RSADSI digestAlgorithm MD5 */
+    { "1.2.840.113549.2.5" },
+    { NULL },
+  };
+
+gcry_md_spec_t _gcry_digest_spec_md5 =
+  {
+    "MD5", asn, DIM (asn), oid_spec_md5, 16,
+    md5_init, md5_write, md5_final, md5_read,
+    sizeof (MD5_CONTEXT)
+  };
diff --git a/grub-core/lib/libgcrypt/cipher/primegen.c b/grub-core/lib/libgcrypt/cipher/primegen.c
new file mode 100644 (file)
index 0000000..b869bee
--- /dev/null
@@ -0,0 +1,1862 @@
+/* primegen.c - prime number generator
+ * Copyright (C) 1998, 2000, 2001, 2002, 2003
+ *               2004, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "ath.h"
+
+static gcry_mpi_t gen_prime (unsigned int nbits, int secret, int randomlevel, 
+                             int (*extra_check)(void *, gcry_mpi_t),
+                             void *extra_check_arg);
+static int check_prime( gcry_mpi_t prime, gcry_mpi_t val_2, int rm_rounds,
+                        gcry_prime_check_func_t cb_func, void *cb_arg );
+static int is_prime (gcry_mpi_t n, int steps, unsigned int *count);
+static void m_out_of_n( char *array, int m, int n );
+
+static void (*progress_cb) (void *,const char*,int,int, int );
+static void *progress_cb_data;
+
+/* Note: 2 is not included because it can be tested more easily by
+   looking at bit 0. The last entry in this list is marked by a zero */
+static ushort small_prime_numbers[] = {
+    3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
+    47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
+    103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
+    157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
+    211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
+    269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
+    331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
+    389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
+    449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
+    509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
+    587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
+    643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
+    709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
+    773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
+    853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
+    919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
+    991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
+    1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
+    1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
+    1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
+    1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
+    1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
+    1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
+    1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
+    1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
+    1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
+    1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
+    1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
+    1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
+    1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
+    1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
+    1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
+    1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
+    1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
+    2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
+    2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
+    2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
+    2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
+    2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
+    2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
+    2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
+    2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
+    2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
+    2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
+    2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
+    2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
+    2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
+    2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
+    2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
+    3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
+    3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
+    3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
+    3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
+    3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
+    3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
+    3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
+    3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
+    3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
+    3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
+    3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
+    3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
+    3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
+    3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
+    3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
+    4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
+    4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
+    4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
+    4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
+    4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
+    4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
+    4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
+    4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
+    4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
+    4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
+    4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
+    4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
+    4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
+    4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
+    4957, 4967, 4969, 4973, 4987, 4993, 4999,
+    0
+};
+static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1;
+
+
+\f
+/* An object and a list to build up a global pool of primes.  See
+   save_pool_prime and get_pool_prime. */
+struct primepool_s 
+{
+  struct primepool_s *next;
+  gcry_mpi_t prime;      /* If this is NULL the entry is not used. */
+  unsigned int nbits;
+  gcry_random_level_t randomlevel;
+};
+struct primepool_s *primepool;
+/* Mutex used to protect access to the primepool.  */
+static ath_mutex_t primepool_lock = ATH_MUTEX_INITIALIZER;
+
+
+
+/* Save PRIME which has been generated at RANDOMLEVEL for later
+   use. Needs to be called while primepool_lock is being hold.  Note
+   that PRIME should be considered released after calling this
+   function. */
+static void
+save_pool_prime (gcry_mpi_t prime, gcry_random_level_t randomlevel)
+{
+  struct primepool_s *item, *item2;
+  size_t n;
+
+  for (n=0, item = primepool; item; item = item->next, n++)
+    if (!item->prime)
+      break;
+  if (!item && n > 100)
+    {
+      /* Remove some of the entries.  Our strategy is removing
+         the last third from the list. */
+      int i;
+      
+      for (i=0, item2 = primepool; item2; item2 = item2->next)
+        {
+          if (i >= n/3*2)
+            {
+              gcry_mpi_release (item2->prime);
+              item2->prime = NULL;
+              if (!item)
+                item = item2;
+            }
+        }
+    }
+  if (!item)
+    {
+      item = gcry_calloc (1, sizeof *item);
+      if (!item)
+        {
+          /* Out of memory.  Silently giving up. */
+          gcry_mpi_release (prime);
+          return; 
+        }
+      item->next = primepool;
+      primepool = item;
+    }
+  item->prime = prime;
+  item->nbits = mpi_get_nbits (prime);
+  item->randomlevel = randomlevel;
+}
+
+
+/* Return a prime for the prime pool or NULL if none has been found.
+   The prime needs to match NBITS and randomlevel. This function needs
+   to be called why the primepool_look is being hold. */
+static gcry_mpi_t
+get_pool_prime (unsigned int nbits, gcry_random_level_t randomlevel)
+{
+  struct primepool_s *item;
+
+  for (item = primepool; item; item = item->next)
+    if (item->prime
+        && item->nbits == nbits && item->randomlevel == randomlevel)
+      {
+        gcry_mpi_t prime = item->prime;
+        item->prime = NULL;
+        gcry_assert (nbits == mpi_get_nbits (prime));
+        return prime;
+      }
+  return NULL;
+}
+
+
+
+
+
+\f
+void
+_gcry_register_primegen_progress ( void (*cb)(void *,const char*,int,int,int),
+                                   void *cb_data )
+{
+  progress_cb = cb;
+  progress_cb_data = cb_data;
+}
+
+
+static void
+progress( int c )
+{
+  if ( progress_cb )
+    progress_cb ( progress_cb_data, "primegen", c, 0, 0 );
+}
+
+
+/****************
+ * Generate a prime number (stored in secure memory)
+ */
+gcry_mpi_t
+_gcry_generate_secret_prime (unsigned int nbits,
+                             gcry_random_level_t random_level,
+                             int (*extra_check)(void*, gcry_mpi_t),
+                             void *extra_check_arg)
+{
+  gcry_mpi_t prime;
+
+  prime = gen_prime (nbits, 1, random_level, extra_check, extra_check_arg);
+  progress('\n');
+  return prime;
+}
+
+
+/* Generate a prime number which may be public, i.e. not allocated in
+   secure memory.  */
+gcry_mpi_t
+_gcry_generate_public_prime (unsigned int nbits,
+                             gcry_random_level_t random_level,
+                             int (*extra_check)(void*, gcry_mpi_t),
+                             void *extra_check_arg)
+{
+  gcry_mpi_t prime;
+
+  prime = gen_prime (nbits, 0, random_level, extra_check, extra_check_arg);
+  progress('\n');
+  return prime;
+}
+
+
+/* Core prime generation function.  The algorithm used to generate
+   practically save primes is due to Lim and Lee as described in the
+   CRYPTO '97 proceedings (ISBN3540633847) page 260.
+
+   NEED_Q_FACTOR: If true make sure that at least one factor is of
+                  size qbits.  This is for example required for DSA.
+   PRIME_GENERATED: Adresss of a variable where the resulting prime
+                    number will be stored.
+   PBITS: Requested size of the prime number.  At least 48.
+   QBITS: One factor of the prime needs to be of this size.  Maybe 0
+          if this is not required.  See also MODE.
+   G: If not NULL an MPI which will receive a generator for the prime
+      for use with Elgamal.
+   RET_FACTORS: if not NULL, an array with all factors are stored at
+                that address.
+   ALL_FACTORS: If set to true all factors of prime-1 are returned.
+   RANDOMLEVEL:  How strong should the random numers be.
+   FLAGS: Prime generation bit flags. Currently supported:
+          GCRY_PRIME_FLAG_SECRET - The prime needs to be kept secret.
+   CB_FUNC, CB_ARG:  Callback to be used for extra checks.
+
+ */
+static gcry_err_code_t
+prime_generate_internal (int need_q_factor,
+                        gcry_mpi_t *prime_generated, unsigned int pbits,
+                        unsigned int qbits, gcry_mpi_t g,
+                        gcry_mpi_t **ret_factors,
+                        gcry_random_level_t randomlevel, unsigned int flags,
+                         int all_factors,
+                         gcry_prime_check_func_t cb_func, void *cb_arg)
+{
+  gcry_err_code_t err = 0;
+  gcry_mpi_t *factors_new = NULL; /* Factors to return to the
+                                    caller.  */
+  gcry_mpi_t *factors = NULL;  /* Current factors.  */
+  gcry_random_level_t poolrandomlevel; /* Random level used for pool primes. */
+  gcry_mpi_t *pool = NULL;     /* Pool of primes.  */
+  int *pool_in_use = NULL;      /* Array with currently used POOL elements. */
+  unsigned char *perms = NULL; /* Permutations of POOL.  */
+  gcry_mpi_t q_factor = NULL;  /* Used if QBITS is non-zero.  */
+  unsigned int fbits = 0;      /* Length of prime factors.  */
+  unsigned int n = 0;          /* Number of factors.  */
+  unsigned int m = 0;          /* Number of primes in pool.  */
+  gcry_mpi_t q = NULL;         /* First prime factor.  */
+  gcry_mpi_t prime = NULL;     /* Prime candidate.  */
+  unsigned int nprime = 0;     /* Bits of PRIME.  */
+  unsigned int req_qbits;       /* The original QBITS value.  */
+  gcry_mpi_t val_2;             /* For check_prime().  */
+  int is_locked = 0;            /* Flag to help unlocking the primepool. */
+  unsigned int is_secret = (flags & GCRY_PRIME_FLAG_SECRET);
+  unsigned int count1 = 0, count2 = 0;
+  unsigned int i = 0, j = 0;
+
+  if (pbits < 48)
+    return GPG_ERR_INV_ARG;
+
+  /* We won't use a too strong random elvel for the pooled subprimes. */
+  poolrandomlevel = (randomlevel > GCRY_STRONG_RANDOM?
+                     GCRY_STRONG_RANDOM : randomlevel);
+
+
+  /* If QBITS is not given, assume a reasonable value. */
+  if (!qbits)
+    qbits = pbits / 3;
+
+  req_qbits = qbits;
+
+  /* Find number of needed prime factors N.  */
+  for (n = 1; (pbits - qbits - 1) / n  >= qbits; n++)
+    ;
+  n--;
+
+  val_2 = mpi_alloc_set_ui (2);
+
+  if ((! n) || ((need_q_factor) && (n < 2)))
+    {
+      err = GPG_ERR_INV_ARG;
+      goto leave;
+    }
+
+  if (need_q_factor)
+    {
+      n--;  /* Need one factor less because we want a specific Q-FACTOR. */
+      fbits = (pbits - 2 * req_qbits -1) / n;
+      qbits =  pbits - req_qbits - n * fbits;
+    }
+  else
+    {
+      fbits = (pbits - req_qbits -1) / n;
+      qbits = pbits - n * fbits;
+    }
+  
+  if (DBG_CIPHER)
+    log_debug ("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
+               pbits, req_qbits, qbits, fbits, n);
+
+  /* Allocate an integer to old the new prime. */
+  prime = gcry_mpi_new (pbits);
+
+  /* Generate first prime factor.  */
+  q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
+
+  /* Generate a specific Q-Factor if requested. */
+  if (need_q_factor)
+    q_factor = gen_prime (req_qbits, is_secret, randomlevel, NULL, NULL);
+  
+  /* Allocate an array to hold all factors + 2 for later usage.  */
+  factors = gcry_calloc (n + 2, sizeof (*factors));
+  if (!factors)
+    {
+      err = gpg_err_code_from_errno (errno);
+      goto leave;
+    }
+
+  /* Allocate an array to track pool usage. */
+  pool_in_use = gcry_malloc (n * sizeof *pool_in_use);
+  if (!pool_in_use)
+    {
+      err = gpg_err_code_from_errno (errno);
+      goto leave;
+    }
+  for (i=0; i < n; i++)
+    pool_in_use[i] = -1;
+      
+  /* Make a pool of 3n+5 primes (this is an arbitrary value).  We
+     require at least 30 primes for are useful selection process. 
+     
+     Fixme: We need to research the best formula for sizing the pool.
+  */
+  m = n * 3 + 5;
+  if (need_q_factor) /* Need some more in this case. */
+    m += 5;
+  if (m < 30)
+    m = 30;
+  pool = gcry_calloc (m , sizeof (*pool));
+  if (! pool)
+    {
+      err = gpg_err_code_from_errno (errno);
+      goto leave;
+    }
+
+  /* Permutate over the pool of primes until we find a prime of the
+     requested length.  */
+  do
+    {
+    next_try:
+      for (i=0; i < n; i++)
+        pool_in_use[i] = -1;
+
+      if (!perms)
+        {
+          /* Allocate new primes.  This is done right at the beginning
+             of the loop and if we have later run out of primes. */
+          for (i = 0; i < m; i++)
+            {
+              mpi_free (pool[i]);
+              pool[i] = NULL;
+            }
+
+          /* Init m_out_of_n().  */
+          perms = gcry_calloc (1, m);
+          if (!perms)
+            {
+              err = gpg_err_code_from_errno (errno);
+              goto leave;
+            }
+
+          if (ath_mutex_lock (&primepool_lock))
+            {
+              err = GPG_ERR_INTERNAL;
+              goto leave;
+            }
+          is_locked = 1;
+          for (i = 0; i < n; i++)
+            {
+              perms[i] = 1; 
+              /* At a maximum we use strong random for the factors.
+                 This saves us a lot of entropy. Given that Q and
+                 possible Q-factor are also used in the final prime
+                 this should be acceptable.  We also don't allocate in
+                 secure memory to save on that scare resource too.  If
+                 Q has been allocated in secure memory, the final
+                 prime will be saved there anyway.  This is because
+                 our MPI routines take care of that.  GnuPG has worked
+                 this way ever since.  */
+              pool[i] = NULL;
+              if (is_locked)
+                {
+                  pool[i] = get_pool_prime (fbits, poolrandomlevel);
+                  if (!pool[i])
+                    {
+                      if (ath_mutex_unlock (&primepool_lock))
+                        {
+                          err = GPG_ERR_INTERNAL;
+                          goto leave;
+                        }
+                      is_locked = 0;
+                    }
+                }
+              if (!pool[i])
+                pool[i] = gen_prime (fbits, 0, poolrandomlevel, NULL, NULL);
+              pool_in_use[i] = i;
+              factors[i] = pool[i];
+            }
+          if (is_locked && ath_mutex_unlock (&primepool_lock))
+            {
+              err = GPG_ERR_INTERNAL;
+              goto leave;
+            }
+          is_locked = 0;
+        }
+      else
+        {
+          /* Get next permutation. */
+          m_out_of_n ( (char*)perms, n, m);
+          if (ath_mutex_lock (&primepool_lock))
+            {
+              err = GPG_ERR_INTERNAL;
+              goto leave;
+            }
+          is_locked = 1;
+          for (i = j = 0; (i < m) && (j < n); i++)
+            if (perms[i])
+              {
+                /* If the subprime has not yet beed generated do it now. */
+                if (!pool[i] && is_locked)
+                  {
+                    pool[i] = get_pool_prime (fbits, poolrandomlevel);
+                    if (!pool[i])
+                      {
+                        if (ath_mutex_unlock (&primepool_lock))
+                          {
+                            err = GPG_ERR_INTERNAL;
+                            goto leave;
+                          }
+                        is_locked = 0;
+                      }
+                  }
+                if (!pool[i])
+                  pool[i] = gen_prime (fbits, 0, poolrandomlevel, NULL, NULL);
+                pool_in_use[j] = i;
+                factors[j++] = pool[i];
+              }
+          if (is_locked && ath_mutex_unlock (&primepool_lock))
+            {
+              err = GPG_ERR_INTERNAL;
+              goto leave;
+            }
+          is_locked = 0;
+          if (i == n)
+            {
+              /* Ran out of permutations: Allocate new primes.  */
+              gcry_free (perms);
+              perms = NULL;
+              progress ('!');
+              goto next_try;   
+            }
+        }
+
+       /* Generate next prime candidate:
+          p = 2 * q [ * q_factor] * factor_0 * factor_1 * ... * factor_n + 1. 
+         */
+       mpi_set (prime, q);
+       mpi_mul_ui (prime, prime, 2);
+       if (need_q_factor)
+         mpi_mul (prime, prime, q_factor);
+       for(i = 0; i < n; i++)
+         mpi_mul (prime, prime, factors[i]);
+       mpi_add_ui (prime, prime, 1);
+       nprime = mpi_get_nbits (prime);
+
+       if (nprime < pbits)
+         {
+           if (++count1 > 20)
+             {
+               count1 = 0;
+               qbits++;
+               progress('>');
+               mpi_free (q);
+               q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
+               goto next_try;
+             }
+         }
+       else
+         count1 = 0;
+        
+       if (nprime > pbits)
+         {
+           if (++count2 > 20)
+             {
+               count2 = 0;
+               qbits--;
+               progress('<');
+               mpi_free (q);
+               q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
+               goto next_try;
+             }
+         }
+       else
+         count2 = 0;
+    }
+  while (! ((nprime == pbits) && check_prime (prime, val_2, 5,
+                                              cb_func, cb_arg)));
+
+  if (DBG_CIPHER)
+    {
+      progress ('\n');
+      log_mpidump ("prime    : ", prime);
+      log_mpidump ("factor  q: ", q);
+      if (need_q_factor)
+        log_mpidump ("factor q0: ", q_factor);
+      for (i = 0; i < n; i++)
+        log_mpidump ("factor pi: ", factors[i]);
+      log_debug ("bit sizes: prime=%u, q=%u",
+                 mpi_get_nbits (prime), mpi_get_nbits (q));
+      if (need_q_factor)
+        log_debug (", q0=%u", mpi_get_nbits (q_factor));
+      for (i = 0; i < n; i++)
+        log_debug (", p%d=%u", i, mpi_get_nbits (factors[i]));
+      progress('\n');
+    }
+
+  if (ret_factors)
+    {
+      /* Caller wants the factors.  */
+      factors_new = gcry_calloc (n + 4, sizeof (*factors_new));
+      if (! factors_new)
+        {
+          err = gpg_err_code_from_errno (errno);
+          goto leave;
+        }
+
+      if (all_factors)
+        {
+          i = 0;
+          factors_new[i++] = gcry_mpi_set_ui (NULL, 2);
+          factors_new[i++] = mpi_copy (q);
+          if (need_q_factor)
+            factors_new[i++] = mpi_copy (q_factor);
+          for(j=0; j < n; j++)
+            factors_new[i++] = mpi_copy (factors[j]);
+        }
+      else
+        {
+          i = 0;
+          if (need_q_factor)
+            {
+              factors_new[i++] = mpi_copy (q_factor);
+              for (; i <= n; i++)
+                factors_new[i] = mpi_copy (factors[i]);
+            }
+          else
+            for (; i < n; i++ )
+              factors_new[i] = mpi_copy (factors[i]);
+        }
+    }
+  
+  if (g)
+    {
+      /* Create a generator (start with 3).  */
+      gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs (prime));
+      gcry_mpi_t b = mpi_alloc (mpi_get_nlimbs (prime));
+      gcry_mpi_t pmin1 = mpi_alloc (mpi_get_nlimbs (prime));
+      
+      if (need_q_factor)
+        err = GPG_ERR_NOT_IMPLEMENTED;
+      else
+        {
+          factors[n] = q;
+          factors[n + 1] = mpi_alloc_set_ui (2);
+          mpi_sub_ui (pmin1, prime, 1);
+          mpi_set_ui (g, 2);
+          do
+            {
+              mpi_add_ui (g, g, 1);
+              if (DBG_CIPHER)
+                {
+                  log_debug ("checking g:");
+                  gcry_mpi_dump (g);
+                  log_printf ("\n");
+                }
+              else
+                progress('^');
+              for (i = 0; i < n + 2; i++)
+                {
+                  mpi_fdiv_q (tmp, pmin1, factors[i]);
+                  /* No mpi_pow(), but it is okay to use this with mod
+                     prime.  */
+                  gcry_mpi_powm (b, g, tmp, prime);
+                  if (! mpi_cmp_ui (b, 1))
+                    break;
+                }
+              if (DBG_CIPHER)
+                progress('\n');
+            } 
+          while (i < n + 2);
+
+          mpi_free (factors[n+1]);
+          mpi_free (tmp);
+          mpi_free (b);
+          mpi_free (pmin1);
+        }
+    }
+  
+  if (! DBG_CIPHER)
+    progress ('\n');
+
+
+ leave:
+  if (pool)
+    {
+      is_locked = !ath_mutex_lock (&primepool_lock);
+      for(i = 0; i < m; i++)
+        {
+          if (pool[i])
+            {
+              for (j=0; j < n; j++)
+                if (pool_in_use[j] == i)
+                  break;
+              if (j == n && is_locked)
+                {
+                  /* This pooled subprime has not been used. */
+                  save_pool_prime (pool[i], poolrandomlevel);
+                }
+              else
+                mpi_free (pool[i]);
+            }
+        }
+      if (is_locked && ath_mutex_unlock (&primepool_lock))
+        err = GPG_ERR_INTERNAL;
+      is_locked = 0;
+      gcry_free (pool);
+    }
+  gcry_free (pool_in_use);
+  if (factors)
+    gcry_free (factors);  /* Factors are shallow copies.  */
+  if (perms)
+    gcry_free (perms);
+
+  mpi_free (val_2);
+  mpi_free (q);
+  mpi_free (q_factor);
+
+  if (! err)
+    {
+      *prime_generated = prime;
+      if (ret_factors)
+       *ret_factors = factors_new;
+    }
+  else
+    {
+      if (factors_new)
+       {
+         for (i = 0; factors_new[i]; i++)
+           mpi_free (factors_new[i]);
+         gcry_free (factors_new);
+       }
+      mpi_free (prime);
+    }
+
+  return err;
+}
+
+
+/* Generate a prime used for discrete logarithm algorithms; i.e. this
+   prime will be public and no strong random is required.  */
+gcry_mpi_t
+_gcry_generate_elg_prime (int mode, unsigned pbits, unsigned qbits,
+                         gcry_mpi_t g, gcry_mpi_t **ret_factors)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_mpi_t prime = NULL;
+  
+  err = prime_generate_internal ((mode == 1), &prime, pbits, qbits, g,
+                                ret_factors, GCRY_WEAK_RANDOM, 0, 0,
+                                 NULL, NULL);
+
+  return prime;
+}
+
+
+static gcry_mpi_t
+gen_prime (unsigned int nbits, int secret, int randomlevel, 
+           int (*extra_check)(void *, gcry_mpi_t), void *extra_check_arg)
+{
+  gcry_mpi_t prime, ptest, pminus1, val_2, val_3, result;
+  int i;
+  unsigned int x, step;
+  unsigned int count1, count2;
+  int *mods;
+  
+/*   if (  DBG_CIPHER ) */
+/*     log_debug ("generate a prime of %u bits ", nbits ); */
+
+  if (nbits < 16)
+    log_fatal ("can't generate a prime with less than %d bits\n", 16);
+
+  mods = gcry_xmalloc( no_of_small_prime_numbers * sizeof *mods );
+  /* Make nbits fit into gcry_mpi_t implementation. */
+  val_2  = mpi_alloc_set_ui( 2 );
+  val_3 = mpi_alloc_set_ui( 3);
+  prime  = secret? gcry_mpi_snew ( nbits ): gcry_mpi_new ( nbits );
+  result = mpi_alloc_like( prime );
+  pminus1= mpi_alloc_like( prime );
+  ptest  = mpi_alloc_like( prime );
+  count1 = count2 = 0;
+  for (;;)
+    {  /* try forvever */
+      int dotcount=0;
+      
+      /* generate a random number */
+      gcry_mpi_randomize( prime, nbits, randomlevel );
+      
+      /* Set high order bit to 1, set low order bit to 1.  If we are
+         generating a secret prime we are most probably doing that
+         for RSA, to make sure that the modulus does have the
+         requested key size we set the 2 high order bits. */
+      mpi_set_highbit (prime, nbits-1);
+      if (secret)
+        mpi_set_bit (prime, nbits-2);
+      mpi_set_bit(prime, 0);
+      
+      /* Calculate all remainders. */
+      for (i=0; (x = small_prime_numbers[i]); i++ )
+        mods[i] = mpi_fdiv_r_ui(NULL, prime, x);
+      
+      /* Now try some primes starting with prime. */
+      for(step=0; step < 20000; step += 2 ) 
+        {
+          /* Check against all the small primes we have in mods. */
+          count1++;
+          for (i=0; (x = small_prime_numbers[i]); i++ ) 
+            {
+              while ( mods[i] + step >= x )
+                mods[i] -= x;
+              if ( !(mods[i] + step) )
+                break;
+           }
+          if ( x )
+            continue;   /* Found a multiple of an already known prime. */
+          
+          mpi_add_ui( ptest, prime, step );
+
+          /* Do a fast Fermat test now. */
+          count2++;
+          mpi_sub_ui( pminus1, ptest, 1);
+          gcry_mpi_powm( result, val_2, pminus1, ptest );
+          if ( !mpi_cmp_ui( result, 1 ) )
+            { 
+              /* Not composite, perform stronger tests */
+              if (is_prime(ptest, 5, &count2 ))
+                {
+                  if (!mpi_test_bit( ptest, nbits-1-secret ))
+                    {
+                      progress('\n');
+                      log_debug ("overflow in prime generation\n");
+                      break; /* Stop loop, continue with a new prime. */
+                    }
+
+                  if (extra_check && extra_check (extra_check_arg, ptest))
+                    { 
+                      /* The extra check told us that this prime is
+                         not of the caller's taste. */
+                      progress ('/');
+                    }
+                  else
+                    { 
+                      /* Got it. */
+                      mpi_free(val_2);
+                      mpi_free(val_3);
+                      mpi_free(result);
+                      mpi_free(pminus1);
+                      mpi_free(prime);
+                      gcry_free(mods);
+                      return ptest; 
+                    }
+                }
+           }
+          if (++dotcount == 10 )
+            {
+              progress('.');
+              dotcount = 0;
+           }
+       }
+      progress(':'); /* restart with a new random value */
+    }
+}
+
+/****************
+ * Returns: true if this may be a prime
+ * RM_ROUNDS gives the number of Rabin-Miller tests to run.
+ */
+static int
+check_prime( gcry_mpi_t prime, gcry_mpi_t val_2, int rm_rounds,
+             gcry_prime_check_func_t cb_func, void *cb_arg)
+{
+  int i;
+  unsigned int x;
+  unsigned int count=0;
+
+  /* Check against small primes. */
+  for (i=0; (x = small_prime_numbers[i]); i++ )
+    {
+      if ( mpi_divisible_ui( prime, x ) )
+        return 0;
+    }
+
+  /* A quick Fermat test. */
+  {
+    gcry_mpi_t result = mpi_alloc_like( prime );
+    gcry_mpi_t pminus1 = mpi_alloc_like( prime );
+    mpi_sub_ui( pminus1, prime, 1);
+    gcry_mpi_powm( result, val_2, pminus1, prime );
+    mpi_free( pminus1 );
+    if ( mpi_cmp_ui( result, 1 ) )
+      { 
+        /* Is composite. */
+        mpi_free( result );
+        progress('.');
+        return 0;
+      }
+    mpi_free( result );
+  }
+
+  if (!cb_func || cb_func (cb_arg, GCRY_PRIME_CHECK_AT_MAYBE_PRIME, prime))
+    {
+      /* Perform stronger tests. */
+      if ( is_prime( prime, rm_rounds, &count ) )
+        {
+          if (!cb_func
+              || cb_func (cb_arg, GCRY_PRIME_CHECK_AT_GOT_PRIME, prime))
+            return 1; /* Probably a prime. */
+        }
+    }
+  progress('.');
+  return 0;
+}
+
+
+/*
+ * Return true if n is probably a prime
+ */
+static int
+is_prime (gcry_mpi_t n, int steps, unsigned int *count)
+{
+  gcry_mpi_t x = mpi_alloc( mpi_get_nlimbs( n ) );
+  gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs( n ) );
+  gcry_mpi_t z = mpi_alloc( mpi_get_nlimbs( n ) );
+  gcry_mpi_t nminus1 = mpi_alloc( mpi_get_nlimbs( n ) );
+  gcry_mpi_t a2 = mpi_alloc_set_ui( 2 );
+  gcry_mpi_t q;
+  unsigned i, j, k;
+  int rc = 0;
+  unsigned nbits = mpi_get_nbits( n );
+
+  if (steps < 5) /* Make sure that we do at least 5 rounds. */
+    steps = 5; 
+
+  mpi_sub_ui( nminus1, n, 1 );
+
+  /* Find q and k, so that n = 1 + 2^k * q . */
+  q = mpi_copy ( nminus1 );
+  k = mpi_trailing_zeros ( q );
+  mpi_tdiv_q_2exp (q, q, k);
+
+  for (i=0 ; i < steps; i++ )
+    {
+      ++*count;
+      if( !i )
+        {
+          mpi_set_ui( x, 2 );
+        }
+      else
+        {
+          gcry_mpi_randomize( x, nbits, GCRY_WEAK_RANDOM );
+
+          /* Make sure that the number is smaller than the prime and
+             keep the randomness of the high bit. */
+          if ( mpi_test_bit ( x, nbits-2) )
+            {
+              mpi_set_highbit ( x, nbits-2); /* Clear all higher bits. */
+            }
+          else
+            {
+              mpi_set_highbit( x, nbits-2 );
+              mpi_clear_bit( x, nbits-2 );
+            }
+          gcry_assert (mpi_cmp (x, nminus1) < 0 && mpi_cmp_ui (x, 1) > 0);
+       }
+      gcry_mpi_powm ( y, x, q, n);
+      if ( mpi_cmp_ui(y, 1) && mpi_cmp( y, nminus1 ) )
+        {
+          for ( j=1; j < k && mpi_cmp( y, nminus1 ); j++ )
+            {
+              gcry_mpi_powm(y, y, a2, n);
+              if( !mpi_cmp_ui( y, 1 ) )
+                goto leave; /* Not a prime. */
+            }
+          if (mpi_cmp( y, nminus1 ) )
+            goto leave; /* Not a prime. */
+       }
+      progress('+');
+    }
+  rc = 1; /* May be a prime. */
+
+ leave:
+  mpi_free( x );
+  mpi_free( y );
+  mpi_free( z );
+  mpi_free( nminus1 );
+  mpi_free( q );
+  mpi_free( a2 );
+
+  return rc;
+}
+
+
+/* Given ARRAY of size N with M elements set to true produce a
+   modified array with the next permutation of M elements.  Note, that
+   ARRAY is used in a one-bit-per-byte approach.  To detected the last
+   permutation it is useful to intialize the array with the first M
+   element set to true and use this test:
+       m_out_of_n (array, m, n);
+       for (i = j = 0; i < n && j < m; i++)
+         if (array[i])
+           j++;
+       if (j == m)
+         goto ready;
+     
+   This code is based on the algorithm 452 from the "Collected
+   Algorithms From ACM, Volume II" by C. N. Liu and D. T. Tang.
+*/
+static void
+m_out_of_n ( char *array, int m, int n )
+{
+  int i=0, i1=0, j=0, jp=0,  j1=0, k1=0, k2=0;
+
+  if( !m || m >= n )
+    return;
+
+  /* Need to handle this simple case separately. */
+  if( m == 1 )
+    { 
+      for (i=0; i < n; i++ )
+        {
+          if ( array[i] )
+            {
+              array[i++] = 0;
+              if( i >= n )
+                i = 0;
+              array[i] = 1;
+              return;
+            }
+        }
+      BUG();
+    }
+
+
+  for (j=1; j < n; j++ )
+    {
+      if ( array[n-1] == array[n-j-1])
+        continue;
+      j1 = j;
+      break;
+    }
+
+  if ( (m & 1) )
+    {
+      /* M is odd. */
+      if( array[n-1] )
+        {
+          if( j1 & 1 )
+            {
+              k1 = n - j1;
+              k2 = k1+2;
+              if( k2 > n )
+                k2 = n;
+              goto leave;
+            }
+          goto scan;
+        }
+      k2 = n - j1 - 1;
+      if( k2 == 0 )
+        {
+          k1 = i;
+          k2 = n - j1;
+        }
+      else if( array[k2] && array[k2-1] )
+        k1 = n;
+      else
+        k1 = k2 + 1;
+    }
+  else 
+    {
+      /* M is even. */
+      if( !array[n-1] )
+        {
+          k1 = n - j1;
+          k2 = k1 + 1;
+          goto leave;
+        }
+        
+      if( !(j1 & 1) )
+        {
+          k1 = n - j1;
+          k2 = k1+2;
+          if( k2 > n )
+            k2 = n;
+          goto leave;
+        }
+    scan:
+      jp = n - j1 - 1;
+      for (i=1; i <= jp; i++ ) 
+        {
+          i1 = jp + 2 - i;
+          if( array[i1-1]  )
+            {
+              if( array[i1-2] )
+                {
+                  k1 = i1 - 1;
+                  k2 = n - j1;
+               }
+              else
+                {
+                  k1 = i1 - 1;
+                  k2 = n + 1 - j1;
+                }
+              goto leave;
+            }
+        }
+      k1 = 1;
+      k2 = n + 1 - m;
+    }
+ leave:
+  /* Now complement the two selected bits. */
+  array[k1-1] = !array[k1-1];
+  array[k2-1] = !array[k2-1];
+}
+
+
+/* Generate a new prime number of PRIME_BITS bits and store it in
+   PRIME.  If FACTOR_BITS is non-zero, one of the prime factors of
+   (prime - 1) / 2 must be FACTOR_BITS bits long.  If FACTORS is
+   non-zero, allocate a new, NULL-terminated array holding the prime
+   factors and store it in FACTORS.  FLAGS might be used to influence
+   the prime number generation process.  */
+gcry_error_t
+gcry_prime_generate (gcry_mpi_t *prime, unsigned int prime_bits,
+                    unsigned int factor_bits, gcry_mpi_t **factors,
+                    gcry_prime_check_func_t cb_func, void *cb_arg,
+                    gcry_random_level_t random_level,
+                    unsigned int flags)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_mpi_t *factors_generated = NULL;
+  gcry_mpi_t prime_generated = NULL;
+  unsigned int mode = 0;
+
+  if (!prime)
+    return gpg_error (GPG_ERR_INV_ARG);
+  *prime = NULL; 
+
+  if (flags & GCRY_PRIME_FLAG_SPECIAL_FACTOR)
+    mode = 1;
+
+  /* Generate.  */
+  err = prime_generate_internal ((mode==1), &prime_generated, prime_bits,
+                                factor_bits, NULL,
+                                 factors? &factors_generated : NULL,
+                                random_level, flags, 1,
+                                 cb_func, cb_arg);
+
+  if (! err)
+    if (cb_func)
+      {
+       /* Additional check. */
+       if ( !cb_func (cb_arg, GCRY_PRIME_CHECK_AT_FINISH, prime_generated))
+         {
+           /* Failed, deallocate resources.  */
+           unsigned int i;
+
+           mpi_free (prime_generated);
+            if (factors)
+              {
+                for (i = 0; factors_generated[i]; i++)
+                  mpi_free (factors_generated[i]);
+                gcry_free (factors_generated);
+              }
+           err = GPG_ERR_GENERAL; 
+         }
+      }
+
+  if (! err)
+    {
+      if (factors)
+        *factors = factors_generated;
+      *prime = prime_generated;
+    }
+
+  return gcry_error (err);
+}
+
+/* Check wether the number X is prime.  */
+gcry_error_t
+gcry_prime_check (gcry_mpi_t x, unsigned int flags)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_mpi_t val_2 = mpi_alloc_set_ui (2); /* Used by the Fermat test. */
+
+  (void)flags;
+
+  /* We use 64 rounds because the prime we are going to test is not
+     guaranteed to be a random one. */
+  if (! check_prime (x, val_2, 64, NULL, NULL))
+    err = GPG_ERR_NO_PRIME;
+
+  mpi_free (val_2);
+
+  return gcry_error (err);
+}
+
+/* Find a generator for PRIME where the factorization of (prime-1) is
+   in the NULL terminated array FACTORS. Return the generator as a
+   newly allocated MPI in R_G.  If START_G is not NULL, use this as s
+   atart for the search. Returns 0 on success.*/
+gcry_error_t
+gcry_prime_group_generator (gcry_mpi_t *r_g,
+                            gcry_mpi_t prime, gcry_mpi_t *factors,
+                            gcry_mpi_t start_g)
+{
+  gcry_mpi_t tmp = gcry_mpi_new (0);
+  gcry_mpi_t b = gcry_mpi_new (0);
+  gcry_mpi_t pmin1 = gcry_mpi_new (0);
+  gcry_mpi_t g = start_g? gcry_mpi_copy (start_g) : gcry_mpi_set_ui (NULL, 3);
+  int first = 1;
+  int i, n;
+
+  if (!factors || !r_g || !prime)
+    return gpg_error (GPG_ERR_INV_ARG);
+  *r_g = NULL; 
+
+  for (n=0; factors[n]; n++)
+    ;
+  if (n < 2)
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  /* Extra sanity check - usually disabled. */  
+/*   mpi_set (tmp, factors[0]); */
+/*   for(i = 1; i < n; i++) */
+/*     mpi_mul (tmp, tmp, factors[i]); */
+/*   mpi_add_ui (tmp, tmp, 1); */
+/*   if (mpi_cmp (prime, tmp)) */
+/*     return gpg_error (GPG_ERR_INV_ARG); */
+  
+  gcry_mpi_sub_ui (pmin1, prime, 1);      
+  do         
+    {
+      if (first)
+        first = 0;
+      else
+        gcry_mpi_add_ui (g, g, 1);
+      
+      if (DBG_CIPHER)
+        {
+          log_debug ("checking g:");
+          gcry_mpi_dump (g);
+          log_debug ("\n");
+        }
+      else
+        progress('^');
+      
+      for (i = 0; i < n; i++)
+        {
+          mpi_fdiv_q (tmp, pmin1, factors[i]);
+          gcry_mpi_powm (b, g, tmp, prime);
+          if (! mpi_cmp_ui (b, 1))
+            break;
+        }
+      if (DBG_CIPHER)
+        progress('\n');
+    }
+  while (i < n);
+  
+  gcry_mpi_release (tmp);
+  gcry_mpi_release (b); 
+  gcry_mpi_release (pmin1); 
+  *r_g = g; 
+
+  return 0; 
+}
+
+/* Convenience function to release the factors array. */
+void
+gcry_prime_release_factors (gcry_mpi_t *factors)
+{
+  if (factors)
+    {
+      int i;
+      
+      for (i=0; factors[i]; i++)
+        mpi_free (factors[i]);
+      gcry_free (factors);
+    }
+}
+
+
+\f
+/* Helper for _gcry_derive_x931_prime.  */
+static gcry_mpi_t
+find_x931_prime (const gcry_mpi_t pfirst)
+{
+  gcry_mpi_t val_2 = mpi_alloc_set_ui (2); 
+  gcry_mpi_t prime;
+  
+  prime = gcry_mpi_copy (pfirst);
+  /* If P is even add 1.  */ 
+  mpi_set_bit (prime, 0);
+
+  /* We use 64 Rabin-Miller rounds which is better and thus
+     sufficient.  We do not have a Lucas test implementaion thus we
+     can't do it in the X9.31 preferred way of running a few
+     Rabin-Miller followed by one Lucas test.  */
+  while ( !check_prime (prime, val_2, 64, NULL, NULL) )
+    mpi_add_ui (prime, prime, 2);
+
+  mpi_free (val_2);
+
+  return prime;
+}
+
+
+/* Generate a prime using the algorithm from X9.31 appendix B.4. 
+
+   This function requires that the provided public exponent E is odd.
+   XP, XP1 and XP2 are the seed values.  All values are mandatory.
+
+   On success the prime is returned.  If R_P1 or R_P2 are given the
+   internal values P1 and P2 are saved at these addresses.  On error
+   NULL is returned.  */
+gcry_mpi_t
+_gcry_derive_x931_prime (const gcry_mpi_t xp, 
+                         const gcry_mpi_t xp1, const gcry_mpi_t xp2,
+                         const gcry_mpi_t e,
+                         gcry_mpi_t *r_p1, gcry_mpi_t *r_p2)
+{
+  gcry_mpi_t p1, p2, p1p2, yp0;
+
+  if (!xp || !xp1 || !xp2)
+    return NULL;
+  if (!e || !mpi_test_bit (e, 0))
+    return NULL;  /* We support only odd values for E.  */
+
+  p1 = find_x931_prime (xp1);
+  p2 = find_x931_prime (xp2);
+  p1p2 = mpi_alloc_like (xp);
+  mpi_mul (p1p2, p1, p2);
+
+  {
+    gcry_mpi_t r1, tmp;
+  
+    /* r1 = (p2^{-1} mod p1)p2 - (p1^{-1} mod p2) */
+    tmp = mpi_alloc_like (p1);
+    mpi_invm (tmp, p2, p1);
+    mpi_mul (tmp, tmp, p2);
+    r1 = tmp;
+    
+    tmp = mpi_alloc_like (p2);
+    mpi_invm (tmp, p1, p2);
+    mpi_mul (tmp, tmp, p1);
+    mpi_sub (r1, r1, tmp);
+
+    /* Fixup a negative value.  */
+    if (mpi_is_neg (r1)) 
+      mpi_add (r1, r1, p1p2);
+
+    /* yp0 = xp + (r1 - xp mod p1*p2)  */
+    yp0 = tmp; tmp = NULL;
+    mpi_subm (yp0, r1, xp, p1p2);
+    mpi_add (yp0, yp0, xp);
+    mpi_free (r1);
+
+    /* Fixup a negative value.  */
+    if (mpi_cmp (yp0, xp) < 0 ) 
+      mpi_add (yp0, yp0, p1p2);
+  }
+
+  /* yp0 is now the first integer greater than xp with p1 being a
+     large prime factor of yp0-1 and p2 a large prime factor of yp0+1.  */
+
+  /* Note that the first example from X9.31 (D.1.1) which uses
+       (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)
+       (Xq2 #134E4CAA16D2350A21D775C404#)
+       (Xq  #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
+             7C9953388F97DDDC3E1CA19C35CA659EDC2FC325
+             6D29C2627479C086A699A49C4C9CEE7EF7BD1B34
+             321DE34A#))))
+     returns an yp0 of
+            #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
+             7C9953388F97DDDC3E1CA19C35CA659EDC2FC4E3
+             BF20CB896EE37E098A906313271422162CB6C642
+             75C1201F#
+     and not
+            #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
+             7C9953388F97DDDC3E1CA19C35CA659EDC2FC2E6
+             C88FE299D52D78BE405A97E01FD71DD7819ECB91
+             FA85A076#
+     as stated in the standard.  This seems to be a bug in X9.31.
+   */
+
+  {
+    gcry_mpi_t val_2 = mpi_alloc_set_ui (2); 
+    gcry_mpi_t gcdtmp = mpi_alloc_like (yp0);
+    int gcdres;
+  
+    mpi_sub_ui (p1p2, p1p2, 1); /* Adjust for loop body.  */
+    mpi_sub_ui (yp0, yp0, 1);   /* Ditto.  */
+    for (;;)
+      {
+        gcdres = gcry_mpi_gcd (gcdtmp, e, yp0);
+        mpi_add_ui (yp0, yp0, 1);
+        if (!gcdres)
+          progress ('/');  /* gcd (e, yp0-1) != 1  */
+        else if (check_prime (yp0, val_2, 64, NULL, NULL))
+          break; /* Found.  */
+        /* We add p1p2-1 because yp0 is incremented after the gcd test.  */
+        mpi_add (yp0, yp0, p1p2);
+      }
+    mpi_free (gcdtmp);
+    mpi_free (val_2);
+  }
+
+  mpi_free (p1p2);
+
+  progress('\n');
+  if (r_p1)
+    *r_p1 = p1;
+  else
+    mpi_free (p1);
+  if (r_p2)
+    *r_p2 = p2;
+  else
+    mpi_free (p2);
+  return yp0;
+}
+
+
+\f
+/* Generate the two prime used for DSA using the algorithm specified
+   in FIPS 186-2.  PBITS is the desired length of the prime P and a
+   QBITS the length of the prime Q.  If SEED is not supplied and
+   SEEDLEN is 0 the function generates an appropriate SEED.  On
+   success the generated primes are stored at R_Q and R_P, the counter
+   value is stored at R_COUNTER and the seed actually used for
+   generation is stored at R_SEED and R_SEEDVALUE.  */
+gpg_err_code_t
+_gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
+                                const void *seed, size_t seedlen,
+                                gcry_mpi_t *r_q, gcry_mpi_t *r_p,
+                                int *r_counter,
+                                void **r_seed, size_t *r_seedlen)
+{
+  gpg_err_code_t ec;
+  unsigned char seed_help_buffer[160/8];  /* Used to hold a generated SEED. */
+  unsigned char *seed_plus;     /* Malloced buffer to hold SEED+x.  */
+  unsigned char digest[160/8];  /* Helper buffer for SHA-1 digest.  */
+  gcry_mpi_t val_2 = NULL;      /* Helper for the prime test.  */
+  gcry_mpi_t tmpval = NULL;     /* Helper variable.  */
+  int i;
+
+  unsigned char value_u[160/8];
+  int value_n, value_b, value_k;
+  int counter;
+  gcry_mpi_t value_w = NULL;
+  gcry_mpi_t value_x = NULL;
+  gcry_mpi_t prime_q = NULL;
+  gcry_mpi_t prime_p = NULL;
+
+  /* FIPS 186-2 allows only for 1024/160 bit.  */
+  if (pbits != 1024 || qbits != 160)
+    return GPG_ERR_INV_KEYLEN;
+
+  if (!seed && !seedlen)
+    ; /* No seed value given:  We are asked to generate it.  */
+  else if (!seed || seedlen < qbits/8)
+    return GPG_ERR_INV_ARG;
+  
+  /* Allocate a buffer to later compute SEED+some_increment. */
+  seed_plus = gcry_malloc (seedlen < 20? 20:seedlen);
+  if (!seed_plus)
+    {
+      ec = gpg_err_code_from_syserror ();
+      goto leave;
+    }
+
+  val_2   = mpi_alloc_set_ui (2);
+  value_n = (pbits - 1) / qbits;
+  value_b = (pbits - 1) - value_n * qbits;
+  value_w = gcry_mpi_new (pbits);
+  value_x = gcry_mpi_new (pbits);
+
+ restart:  
+  /* Generate Q.  */
+  for (;;)
+    {
+      /* Step 1: Generate a (new) seed unless one has been supplied.  */
+      if (!seed)
+        {
+          seedlen = sizeof seed_help_buffer;
+          gcry_create_nonce (seed_help_buffer, seedlen);
+          seed = seed_help_buffer;
+        }
+      
+      /* Step 2: U = sha1(seed) ^ sha1((seed+1) mod 2^{qbits})  */
+      memcpy (seed_plus, seed, seedlen);
+      for (i=seedlen-1; i >= 0; i--)
+        {
+          seed_plus[i]++;
+          if (seed_plus[i])
+            break;
+        }
+      gcry_md_hash_buffer (GCRY_MD_SHA1, value_u, seed, seedlen);
+      gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
+      for (i=0; i < sizeof value_u; i++)
+        value_u[i] ^= digest[i];
+  
+      /* Step 3:  Form q from U  */
+      gcry_mpi_release (prime_q); prime_q = NULL;
+      ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG, 
+                                        value_u, sizeof value_u, NULL));
+      if (ec)
+        goto leave;
+      mpi_set_highbit (prime_q, qbits-1 );
+      mpi_set_bit (prime_q, 0);
+      
+      /* Step 4:  Test whether Q is prime using 64 round of Rabin-Miller.  */
+      if (check_prime (prime_q, val_2, 64, NULL, NULL))
+        break; /* Yes, Q is prime.  */
+
+      /* Step 5.  */
+      seed = NULL;  /* Force a new seed at Step 1.  */
+    }
+  
+  /* Step 6.  Note that we do no use an explicit offset but increment
+     SEED_PLUS accordingly.  SEED_PLUS is currently SEED+1.  */
+  counter = 0;
+
+  /* Generate P. */
+  prime_p = gcry_mpi_new (pbits);
+  for (;;)
+    {
+      /* Step 7: For k = 0,...n let 
+                   V_k = sha1(seed+offset+k) mod 2^{qbits}  
+         Step 8: W = V_0 + V_1*2^160 + 
+                         ... 
+                         + V_{n-1}*2^{(n-1)*160}
+                         + (V_{n} mod 2^b)*2^{n*160}                
+       */
+      mpi_set_ui (value_w, 0);
+      for (value_k=0; value_k <= value_n; value_k++)
+        {
+          /* There is no need to have an explicit offset variable:  In
+             the first round we shall have an offset of 2, this is
+             achieved by using SEED_PLUS which is already at SEED+1,
+             thus we just need to increment it once again.  The
+             requirement for the next round is to update offset by N,
+             which we implictly did at the end of this loop, and then
+             to add one; this one is the same as in the first round.  */
+          for (i=seedlen-1; i >= 0; i--)
+            {
+              seed_plus[i]++;
+              if (seed_plus[i])
+                break;
+            }
+          gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
+          
+          gcry_mpi_release (tmpval); tmpval = NULL;
+          ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
+                                            digest, sizeof digest, NULL));
+          if (ec)
+            goto leave;
+          if (value_k == value_n)
+            mpi_clear_highbit (tmpval, value_b); /* (V_n mod 2^b) */
+          mpi_lshift (tmpval, tmpval, value_k*qbits);
+          mpi_add (value_w, value_w, tmpval);
+        }
+
+      /* Step 8 continued: X = W + 2^{L-1}  */
+      mpi_set_ui (value_x, 0);
+      mpi_set_highbit (value_x, pbits-1);
+      mpi_add (value_x, value_x, value_w);
+
+      /* Step 9:  c = X mod 2q,  p = X - (c - 1)  */
+      mpi_mul_2exp (tmpval, prime_q, 1);
+      mpi_mod (tmpval, value_x, tmpval);
+      mpi_sub_ui (tmpval, tmpval, 1);
+      mpi_sub (prime_p, value_x, tmpval);
+
+      /* Step 10: If  p < 2^{L-1}  skip the primality test.  */
+      /* Step 11 and 12: Primality test.  */
+      if (mpi_get_nbits (prime_p) >= pbits-1
+          && check_prime (prime_p, val_2, 64, NULL, NULL) )
+        break; /* Yes, P is prime, continue with Step 15.  */
+
+      /* Step 13: counter = counter + 1, offset = offset + n + 1. */
+      counter++;
+
+      /* Step 14: If counter >= 2^12  goto Step 1.  */
+      if (counter >= 4096)
+        goto restart;
+    }
+
+  /* Step 15:  Save p, q, counter and seed.  */
+/*   log_debug ("fips186-2 pbits p=%u q=%u counter=%d\n", */
+/*              mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter); */
+/*   log_printhex("fips186-2 seed:", seed, seedlen); */
+/*   log_mpidump ("fips186-2 prime p", prime_p); */
+/*   log_mpidump ("fips186-2 prime q", prime_q); */
+  if (r_q)
+    {
+      *r_q = prime_q;
+      prime_q = NULL;
+    }
+  if (r_p)
+    {
+      *r_p = prime_p;
+      prime_p = NULL;
+    }
+  if (r_counter)
+    *r_counter = counter;
+  if (r_seed && r_seedlen)
+    {
+      memcpy (seed_plus, seed, seedlen);
+      *r_seed = seed_plus;
+      seed_plus = NULL;
+      *r_seedlen = seedlen;
+    }
+
+
+ leave:
+  gcry_mpi_release (tmpval);
+  gcry_mpi_release (value_x);
+  gcry_mpi_release (value_w);
+  gcry_mpi_release (prime_p);
+  gcry_mpi_release (prime_q);
+  gcry_free (seed_plus);
+  gcry_mpi_release (val_2);
+  return ec;
+}
+
+
+\f
+/* WARNING: The code below has not yet been tested!  However, it is
+   not yet used.  We need to wait for FIPS 186-3 final and for test
+   vectors.
+
+   Generate the two prime used for DSA using the algorithm specified
+   in FIPS 186-3, A.1.1.2.  PBITS is the desired length of the prime P
+   and a QBITS the length of the prime Q.  If SEED is not supplied and
+   SEEDLEN is 0 the function generates an appropriate SEED.  On
+   success the generated primes are stored at R_Q and R_P, the counter
+   value is stored at R_COUNTER and the seed actually used for
+   generation is stored at R_SEED and R_SEEDVALUE.  The hash algorithm
+   used is stored at R_HASHALGO.
+   
+   Note that this function is very similar to the fips186_2 code.  Due
+   to the minor differences, other buffer sizes and for documentarion,
+   we use a separate function.
+*/
+gpg_err_code_t
+_gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
+                                const void *seed, size_t seedlen,
+                                gcry_mpi_t *r_q, gcry_mpi_t *r_p,
+                                int *r_counter,
+                                void **r_seed, size_t *r_seedlen,
+                                int *r_hashalgo)
+{
+  gpg_err_code_t ec;
+  unsigned char seed_help_buffer[256/8];  /* Used to hold a generated SEED. */
+  unsigned char *seed_plus;     /* Malloced buffer to hold SEED+x.  */
+  unsigned char digest[256/8];  /* Helper buffer for SHA-1 digest.  */
+  gcry_mpi_t val_2 = NULL;      /* Helper for the prime test.  */
+  gcry_mpi_t tmpval = NULL;     /* Helper variable.  */
+  int hashalgo;                 /* The id of the Approved Hash Function.  */
+  int i;
+  
+  unsigned char value_u[256/8];
+  int value_n, value_b, value_j;
+  int counter;
+  gcry_mpi_t value_w = NULL;
+  gcry_mpi_t value_x = NULL;
+  gcry_mpi_t prime_q = NULL;
+  gcry_mpi_t prime_p = NULL;
+
+  gcry_assert (sizeof seed_help_buffer == sizeof digest
+               && sizeof seed_help_buffer == sizeof value_u);
+
+  /* Step 1:  Check the requested prime lengths.  */
+  /* Note that due to the size of our buffers QBITS is limited to 256.  */
+  if (pbits == 1024 && qbits == 160)
+    hashalgo = GCRY_MD_SHA1;
+  else if (pbits == 2048 && qbits == 224)
+    hashalgo = GCRY_MD_SHA224;
+  else if (pbits == 2048 && qbits == 256)
+    hashalgo = GCRY_MD_SHA256;
+  else if (pbits == 3072 && qbits == 256)
+    hashalgo = GCRY_MD_SHA256;
+  else
+    return GPG_ERR_INV_KEYLEN;
+
+  /* Also check that the hash algorithm is available.  */
+  ec = gpg_err_code (gcry_md_test_algo (hashalgo));
+  if (ec)
+    return ec;
+  gcry_assert (qbits/8 <= sizeof digest);
+  gcry_assert (gcry_md_get_algo_dlen (hashalgo) == qbits/8);
+
+
+  /* Step 2:  Check seedlen.  */
+  if (!seed && !seedlen)
+    ; /* No seed value given:  We are asked to generate it.  */
+  else if (!seed || seedlen < qbits/8)
+    return GPG_ERR_INV_ARG;
+  
+  /* Allocate a buffer to later compute SEED+some_increment and a few
+     helper variables.  */
+  seed_plus = gcry_malloc (seedlen < sizeof seed_help_buffer? 
+                           sizeof seed_help_buffer : seedlen);
+  if (!seed_plus)
+    {
+      ec = gpg_err_code_from_syserror ();
+      goto leave;
+    }
+  val_2   = mpi_alloc_set_ui (2);
+  value_w = gcry_mpi_new (pbits);
+  value_x = gcry_mpi_new (pbits);
+
+  /* Step 3: n = \lceil L / outlen \rceil - 1  */
+  value_n = (pbits + qbits - 1) / qbits - 1;
+  /* Step 4: b = L - 1 - (n * outlen)  */
+  value_b = pbits - 1 - (value_n * qbits);
+
+ restart:  
+  /* Generate Q.  */
+  for (;;)
+    {
+      /* Step 5:  Generate a (new) seed unless one has been supplied.  */
+      if (!seed)
+        {
+          seedlen = qbits/8;
+          gcry_assert (seedlen <= sizeof seed_help_buffer);
+          gcry_create_nonce (seed_help_buffer, seedlen);
+          seed = seed_help_buffer;
+        }
+      
+      /* Step 6:  U = hash(seed)  */
+      gcry_md_hash_buffer (hashalgo, value_u, seed, seedlen);
+
+      /* Step 7:  q = 2^{N-1} + U + 1 - (U mod 2)  */
+      if ( !(value_u[qbits/8-1] & 0x01) )
+        {
+          for (i=qbits/8-1; i >= 0; i--)
+            {
+              value_u[i]++;
+              if (value_u[i])
+                break;
+            }
+        }
+      gcry_mpi_release (prime_q); prime_q = NULL;
+      ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG, 
+                                        value_u, sizeof value_u, NULL));
+      if (ec)
+        goto leave;
+      mpi_set_highbit (prime_q, qbits-1 );
+      
+      /* Step 8:  Test whether Q is prime using 64 round of Rabin-Miller.
+                  According to table C.1 this is sufficient for all
+                  supported prime sizes (i.e. up 3072/256).  */
+      if (check_prime (prime_q, val_2, 64, NULL, NULL))
+        break; /* Yes, Q is prime.  */
+
+      /* Step 8.  */
+      seed = NULL;  /* Force a new seed at Step 5.  */
+    }
+  
+  /* Step 11.  Note that we do no use an explicit offset but increment
+     SEED_PLUS accordingly.  */
+  memcpy (seed_plus, seed, seedlen);
+  counter = 0;
+
+  /* Generate P. */
+  prime_p = gcry_mpi_new (pbits);
+  for (;;)
+    {
+      /* Step 11.1: For j = 0,...n let 
+                      V_j = hash(seed+offset+j)  
+         Step 11.2: W = V_0 + V_1*2^outlen + 
+                            ... 
+                            + V_{n-1}*2^{(n-1)*outlen}
+                            + (V_{n} mod 2^b)*2^{n*outlen}                
+       */
+      mpi_set_ui (value_w, 0);
+      for (value_j=0; value_j <= value_n; value_j++)
+        {
+          /* There is no need to have an explicit offset variable: In
+             the first round we shall have an offset of 1 and a j of
+             0.  This is achieved by incrementing SEED_PLUS here.  For
+             the next round offset is implicitly updated by using
+             SEED_PLUS again.  */
+          for (i=seedlen-1; i >= 0; i--)
+            {
+              seed_plus[i]++;
+              if (seed_plus[i])
+                break;
+            }
+          gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
+          
+          gcry_mpi_release (tmpval); tmpval = NULL;
+          ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
+                                            digest, sizeof digest, NULL));
+          if (ec)
+            goto leave;
+          if (value_j == value_n)
+            mpi_clear_highbit (tmpval, value_b); /* (V_n mod 2^b) */
+          mpi_lshift (tmpval, tmpval, value_j*qbits);
+          mpi_add (value_w, value_w, tmpval);
+        }
+
+      /* Step 11.3: X = W + 2^{L-1}  */
+      mpi_set_ui (value_x, 0);
+      mpi_set_highbit (value_x, pbits-1);
+      mpi_add (value_x, value_x, value_w);
+
+      /* Step 11.4:  c = X mod 2q  */
+      mpi_mul_2exp (tmpval, prime_q, 1);
+      mpi_mod (tmpval, value_x, tmpval);
+
+      /* Step 11.5:  p = X - (c - 1)  */
+      mpi_sub_ui (tmpval, tmpval, 1);
+      mpi_sub (prime_p, value_x, tmpval);
+
+      /* Step 11.6: If  p < 2^{L-1}  skip the primality test.  */
+      /* Step 11.7 and 11.8: Primality test.  */
+      if (mpi_get_nbits (prime_p) >= pbits-1
+          && check_prime (prime_p, val_2, 64, NULL, NULL) )
+        break; /* Yes, P is prime, continue with Step 15.  */
+      
+      /* Step 11.9: counter = counter + 1, offset = offset + n + 1.
+                    If counter >= 4L  goto Step 5.  */
+      counter++;
+      if (counter >= 4*pbits)
+        goto restart;
+    }
+
+  /* Step 12:  Save p, q, counter and seed.  */
+  log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n",
+             mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter);
+  log_printhex("fips186-3 seed:", seed, seedlen);
+  log_mpidump ("fips186-3 prime p", prime_p);
+  log_mpidump ("fips186-3 prime q", prime_q);
+  if (r_q)
+    {
+      *r_q = prime_q;
+      prime_q = NULL;
+    }
+  if (r_p)
+    {
+      *r_p = prime_p;
+      prime_p = NULL;
+    }
+  if (r_counter)
+    *r_counter = counter;
+  if (r_seed && r_seedlen)
+    {
+      memcpy (seed_plus, seed, seedlen);
+      *r_seed = seed_plus;
+      seed_plus = NULL;
+      *r_seedlen = seedlen;
+    }
+  if (r_hashalgo)
+    *r_hashalgo = hashalgo;
+
+ leave:
+  gcry_mpi_release (tmpval);
+  gcry_mpi_release (value_x);
+  gcry_mpi_release (value_w);
+  gcry_mpi_release (prime_p);
+  gcry_mpi_release (prime_q);
+  gcry_free (seed_plus);
+  gcry_mpi_release (val_2);
+  return ec;
+}
+
diff --git a/grub-core/lib/libgcrypt/cipher/pubkey.c b/grub-core/lib/libgcrypt/cipher/pubkey.c
new file mode 100644 (file)
index 0000000..08abcbf
--- /dev/null
@@ -0,0 +1,2749 @@
+/* pubkey.c  - pubkey dispatcher
+ * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005, 
+ *               2007, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "ath.h"
+
+
+static gcry_err_code_t pubkey_decrypt (int algo, gcry_mpi_t *result,
+                                       gcry_mpi_t *data, gcry_mpi_t *skey,
+                                       int flags);
+static gcry_err_code_t pubkey_sign (int algo, gcry_mpi_t *resarr,
+                                    gcry_mpi_t hash, gcry_mpi_t *skey);
+static gcry_err_code_t pubkey_verify (int algo, gcry_mpi_t hash,
+                                      gcry_mpi_t *data, gcry_mpi_t *pkey,
+                                    int (*cmp) (void *, gcry_mpi_t),
+                                      void *opaque);
+
+
+/* A dummy extraspec so that we do not need to tests the extraspec
+   field from the module specification against NULL and instead
+   directly test the respective fields of extraspecs.  */
+static pk_extra_spec_t dummy_extra_spec;
+
+
+/* This is the list of the default public-key ciphers included in
+   libgcrypt.  FIPS_ALLOWED indicated whether the algorithm is used in
+   FIPS mode. */
+static struct pubkey_table_entry
+{
+  gcry_pk_spec_t *pubkey;
+  pk_extra_spec_t *extraspec;
+  unsigned int algorithm;
+  int fips_allowed; 
+} pubkey_table[] =
+  {
+#if USE_RSA
+    { &_gcry_pubkey_spec_rsa,
+      &_gcry_pubkey_extraspec_rsa,   GCRY_PK_RSA, 1},
+#endif
+#if USE_ELGAMAL
+    { &_gcry_pubkey_spec_elg,
+      &_gcry_pubkey_extraspec_elg,    GCRY_PK_ELG   },
+    { &_gcry_pubkey_spec_elg,
+      &_gcry_pubkey_extraspec_elg,    GCRY_PK_ELG_E },
+#endif
+#if USE_DSA
+    { &_gcry_pubkey_spec_dsa,
+      &_gcry_pubkey_extraspec_dsa,   GCRY_PK_DSA, 1   },
+#endif
+#if USE_ECC
+    { &_gcry_pubkey_spec_ecdsa,
+      &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDSA, 0 },
+#endif
+    { NULL, 0 },
+  };
+
+/* List of registered ciphers.  */
+static gcry_module_t pubkeys_registered;
+
+/* This is the lock protecting PUBKEYS_REGISTERED.  */
+static ath_mutex_t pubkeys_registered_lock = ATH_MUTEX_INITIALIZER;;
+
+/* Flag to check wether the default pubkeys have already been
+   registered.  */
+static int default_pubkeys_registered;
+
+/* Convenient macro for registering the default digests.  */
+#define REGISTER_DEFAULT_PUBKEYS                   \
+  do                                               \
+    {                                              \
+      ath_mutex_lock (&pubkeys_registered_lock);   \
+      if (! default_pubkeys_registered)            \
+        {                                          \
+          pk_register_default ();                  \
+          default_pubkeys_registered = 1;          \
+        }                                          \
+      ath_mutex_unlock (&pubkeys_registered_lock); \
+    }                                              \
+  while (0)
+
+/* These dummy functions are used in case a cipher implementation
+   refuses to provide it's own functions.  */
+
+static gcry_err_code_t
+dummy_generate (int algorithm, unsigned int nbits, unsigned long dummy,
+                gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+{
+  (void)algorithm;
+  (void)nbits;
+  (void)dummy;
+  (void)skey;
+  (void)retfactors;
+  fips_signal_error ("using dummy public key function");
+  return GPG_ERR_NOT_IMPLEMENTED;
+}
+
+static gcry_err_code_t
+dummy_check_secret_key (int algorithm, gcry_mpi_t *skey)
+{
+  (void)algorithm;
+  (void)skey;
+  fips_signal_error ("using dummy public key function");
+  return GPG_ERR_NOT_IMPLEMENTED;
+}
+
+static gcry_err_code_t
+dummy_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
+               gcry_mpi_t *pkey, int flags)
+{
+  (void)algorithm;
+  (void)resarr;
+  (void)data;
+  (void)pkey;
+  (void)flags;
+  fips_signal_error ("using dummy public key function");
+  return GPG_ERR_NOT_IMPLEMENTED;
+}
+
+static gcry_err_code_t
+dummy_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
+               gcry_mpi_t *skey, int flags)
+{
+  (void)algorithm;
+  (void)result;
+  (void)data;
+  (void)skey;
+  (void)flags;
+  fips_signal_error ("using dummy public key function");
+  return GPG_ERR_NOT_IMPLEMENTED;
+}
+
+static gcry_err_code_t
+dummy_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
+            gcry_mpi_t *skey)
+{
+  (void)algorithm;
+  (void)resarr;
+  (void)data;
+  (void)skey;
+  fips_signal_error ("using dummy public key function");
+  return GPG_ERR_NOT_IMPLEMENTED;
+}
+
+static gcry_err_code_t
+dummy_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
+              gcry_mpi_t *pkey,
+             int (*cmp) (void *, gcry_mpi_t), void *opaquev)
+{
+  (void)algorithm;
+  (void)hash;
+  (void)data;
+  (void)pkey;
+  (void)cmp;
+  (void)opaquev;
+  fips_signal_error ("using dummy public key function");
+  return GPG_ERR_NOT_IMPLEMENTED;
+}
+
+static unsigned
+dummy_get_nbits (int algorithm, gcry_mpi_t *pkey)
+{
+  (void)algorithm;
+  (void)pkey;
+  fips_signal_error ("using dummy public key function");
+  return 0;
+}
+
+/* Internal function.  Register all the pubkeys included in
+   PUBKEY_TABLE.  Returns zero on success or an error code.  */
+static void
+pk_register_default (void)
+{
+  gcry_err_code_t err = 0;
+  int i;
+  
+  for (i = 0; (! err) && pubkey_table[i].pubkey; i++)
+    {
+#define pubkey_use_dummy(func)                       \
+      if (! pubkey_table[i].pubkey->func)            \
+       pubkey_table[i].pubkey->func = dummy_##func;
+
+      pubkey_use_dummy (generate);
+      pubkey_use_dummy (check_secret_key);
+      pubkey_use_dummy (encrypt);
+      pubkey_use_dummy (decrypt);
+      pubkey_use_dummy (sign);
+      pubkey_use_dummy (verify);
+      pubkey_use_dummy (get_nbits);
+#undef pubkey_use_dummy
+
+      err = _gcry_module_add (&pubkeys_registered,
+                             pubkey_table[i].algorithm,
+                             (void *) pubkey_table[i].pubkey, 
+                             (void *) pubkey_table[i].extraspec, 
+                              NULL);
+    }
+
+  if (err)
+    BUG ();
+}
+
+/* Internal callback function.  Used via _gcry_module_lookup.  */
+static int
+gcry_pk_lookup_func_name (void *spec, void *data)
+{
+  gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) spec;
+  char *name = (char *) data;
+  const char **aliases = pubkey->aliases;
+  int ret = stricmp (name, pubkey->name);
+
+  while (ret && *aliases)
+    ret = stricmp (name, *aliases++);
+
+  return ! ret;
+}
+
+/* Internal function.  Lookup a pubkey entry by it's name.  */
+static gcry_module_t 
+gcry_pk_lookup_name (const char *name)
+{
+  gcry_module_t pubkey;
+
+  pubkey = _gcry_module_lookup (pubkeys_registered, (void *) name,
+                               gcry_pk_lookup_func_name);
+
+  return pubkey;
+}
+
+/* Register a new pubkey module whose specification can be found in
+   PUBKEY.  On success, a new algorithm ID is stored in ALGORITHM_ID
+   and a pointer representhing this module is stored in MODULE.  */
+gcry_error_t
+_gcry_pk_register (gcry_pk_spec_t *pubkey,
+                   pk_extra_spec_t *extraspec,
+                   unsigned int *algorithm_id,
+                   gcry_module_t *module)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_module_t mod;
+
+  /* We do not support module loading in fips mode.  */
+  if (fips_mode ())
+    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  err = _gcry_module_add (&pubkeys_registered, 0,
+                         (void *) pubkey, 
+                         (void *)(extraspec? extraspec : &dummy_extra_spec), 
+                          &mod);
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  if (! err)
+    {
+      *module = mod;
+      *algorithm_id = mod->mod_id;
+    }
+
+  return err;
+}
+
+/* Unregister the pubkey identified by ID, which must have been
+   registered with gcry_pk_register.  */
+void
+gcry_pk_unregister (gcry_module_t module)
+{
+  ath_mutex_lock (&pubkeys_registered_lock);
+  _gcry_module_release (module);
+  ath_mutex_unlock (&pubkeys_registered_lock);
+}
+
+static void
+release_mpi_array (gcry_mpi_t *array)
+{
+  for (; *array; array++)
+    {
+      mpi_free(*array);
+      *array = NULL;
+    }
+}
+
+/****************
+ * Map a string to the pubkey algo
+ */
+int
+gcry_pk_map_name (const char *string)
+{
+  gcry_module_t pubkey;
+  int algorithm = 0;
+
+  if (!string)
+    return 0;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = gcry_pk_lookup_name (string);
+  if (pubkey)
+    {
+      algorithm = pubkey->mod_id;
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return algorithm;
+}
+
+
+/* Map the public key algorithm whose ID is contained in ALGORITHM to
+   a string representation of the algorithm name.  For unknown
+   algorithm IDs this functions returns "?". */
+const char *
+gcry_pk_algo_name (int algorithm)
+{
+  gcry_module_t pubkey;
+  const char *name;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+  if (pubkey)
+    {
+      name = ((gcry_pk_spec_t *) pubkey->spec)->name;
+      _gcry_module_release (pubkey);
+    }
+  else
+    name = "?";
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return name;
+}
+
+
+/* A special version of gcry_pk_algo name to return the first aliased
+   name of the algorithm.  This is required to adhere to the spki
+   specs where the algorithm names are lowercase. */
+const char *
+_gcry_pk_aliased_algo_name (int algorithm)
+{
+  const char *name = NULL;
+  gcry_module_t module;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+  if (module)
+    {
+      gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) module->spec;
+
+      name = pubkey->aliases? *pubkey->aliases : NULL;
+      if (!name || !*name)
+        name = pubkey->name;
+      _gcry_module_release (module);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return name;
+}
+
+
+static void
+disable_pubkey_algo (int algorithm)
+{
+  gcry_module_t pubkey;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+  if (pubkey)
+    {
+      if (! (pubkey-> flags & FLAG_MODULE_DISABLED))
+       pubkey->flags |= FLAG_MODULE_DISABLED;
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+}
+
+
+/****************
+ * A USE of 0 means: don't care.
+ */
+static gcry_err_code_t
+check_pubkey_algo (int algorithm, unsigned use)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_pk_spec_t *pubkey;
+  gcry_module_t module;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+  if (module)
+    {
+      pubkey = (gcry_pk_spec_t *) module->spec;
+
+      if (((use & GCRY_PK_USAGE_SIGN)
+          && (! (pubkey->use & GCRY_PK_USAGE_SIGN)))
+         || ((use & GCRY_PK_USAGE_ENCR)
+             && (! (pubkey->use & GCRY_PK_USAGE_ENCR))))
+       err = GPG_ERR_WRONG_PUBKEY_ALGO;
+      else if (module->flags & FLAG_MODULE_DISABLED)
+       err = GPG_ERR_PUBKEY_ALGO;
+      _gcry_module_release (module);
+    }
+  else
+    err = GPG_ERR_PUBKEY_ALGO;
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return err;
+}
+
+
+/****************
+ * Return the number of public key material numbers
+ */
+static int
+pubkey_get_npkey (int algorithm)
+{
+  gcry_module_t pubkey;
+  int npkey = 0;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+  if (pubkey)
+    {
+      npkey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_pkey);
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return npkey;
+}
+
+/****************
+ * Return the number of secret key material numbers
+ */
+static int
+pubkey_get_nskey (int algorithm)
+{
+  gcry_module_t pubkey;
+  int nskey = 0;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+  if (pubkey)
+    {
+      nskey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_skey);
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return nskey;
+}
+
+/****************
+ * Return the number of signature material numbers
+ */
+static int
+pubkey_get_nsig (int algorithm)
+{
+  gcry_module_t pubkey;
+  int nsig = 0;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+  if (pubkey)
+    {
+      nsig = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_sig);
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return nsig;
+}
+
+/****************
+ * Return the number of encryption material numbers
+ */
+static int
+pubkey_get_nenc (int algorithm)
+{
+  gcry_module_t pubkey;
+  int nenc = 0;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+  if (pubkey)
+    {
+      nenc = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_enc);
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return nenc;
+}
+
+
+/* Generate a new public key with algorithm ALGORITHM of size NBITS
+   and return it at SKEY.  USE_E depends on the ALGORITHM.  GENPARMS
+   is passed to the algorithm module if it features an extended
+   generation function.  RETFACTOR is used by some algorithms to
+   return certain additional information which are in general not
+   required.
+
+   The function returns the error code number or 0 on success. */
+static gcry_err_code_t
+pubkey_generate (int algorithm,
+                 unsigned int nbits,
+                 unsigned long use_e,
+                 gcry_sexp_t genparms,
+                 gcry_mpi_t *skey, gcry_mpi_t **retfactors,
+                 gcry_sexp_t *r_extrainfo)
+{
+  gcry_err_code_t ec = GPG_ERR_PUBKEY_ALGO;
+  gcry_module_t pubkey;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+  if (pubkey)
+    {
+      pk_extra_spec_t *extraspec = pubkey->extraspec;
+
+      if (extraspec && extraspec->ext_generate)
+        {
+          /* Use the extended generate function.  */
+          ec = extraspec->ext_generate 
+            (algorithm, nbits, use_e, genparms, skey, retfactors, r_extrainfo);
+        }
+      else
+        {
+          /* Use the standard generate function.  */
+          ec = ((gcry_pk_spec_t *) pubkey->spec)->generate 
+            (algorithm, nbits, use_e, skey, retfactors);
+        }
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return ec;
+}
+
+
+static gcry_err_code_t
+pubkey_check_secret_key (int algorithm, gcry_mpi_t *skey)
+{
+  gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO;
+  gcry_module_t pubkey;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+  if (pubkey)
+    {
+      err = ((gcry_pk_spec_t *) pubkey->spec)->check_secret_key
+        (algorithm, skey);
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return err;
+}
+
+
+/****************
+ * This is the interface to the public key encryption.  Encrypt DATA
+ * with PKEY and put it into RESARR which should be an array of MPIs
+ * of size PUBKEY_MAX_NENC (or less if the algorithm allows this -
+ * check with pubkey_get_nenc() )
+ */
+static gcry_err_code_t
+pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
+                gcry_mpi_t *pkey, int flags)
+{
+  gcry_pk_spec_t *pubkey;
+  gcry_module_t module;
+  gcry_err_code_t rc;
+  int i;
+
+  /* Note: In fips mode DBG_CIPHER will enver evaluate to true but as
+     an extra failsafe protection we explicitly test for fips mode
+     here. */ 
+  if (DBG_CIPHER && !fips_mode ())
+    {
+      log_debug ("pubkey_encrypt: algo=%d\n", algorithm);
+      for(i = 0; i < pubkey_get_npkey (algorithm); i++)
+       log_mpidump ("  pkey:", pkey[i]);
+      log_mpidump ("  data:", data);
+    }
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+  if (module)
+    {
+      pubkey = (gcry_pk_spec_t *) module->spec;
+      rc = pubkey->encrypt (algorithm, resarr, data, pkey, flags);
+      _gcry_module_release (module);
+      goto ready;
+    }
+  rc = GPG_ERR_PUBKEY_ALGO;
+
+ ready:
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  if (!rc && DBG_CIPHER && !fips_mode ())
+    {
+      for(i = 0; i < pubkey_get_nenc (algorithm); i++)
+       log_mpidump("  encr:", resarr[i] );
+    }
+  return rc;
+}
+
+
+/****************
+ * This is the interface to the public key decryption.
+ * ALGO gives the algorithm to use and this implicitly determines
+ * the size of the arrays.
+ * result is a pointer to a mpi variable which will receive a
+ * newly allocated mpi or NULL in case of an error.
+ */
+static gcry_err_code_t
+pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
+                gcry_mpi_t *skey, int flags)
+{
+  gcry_pk_spec_t *pubkey;
+  gcry_module_t module;
+  gcry_err_code_t rc;
+  int i;
+
+  *result = NULL; /* so the caller can always do a mpi_free */
+  if (DBG_CIPHER && !fips_mode ())
+    {
+      log_debug ("pubkey_decrypt: algo=%d\n", algorithm);
+      for(i = 0; i < pubkey_get_nskey (algorithm); i++)
+       log_mpidump ("  skey:", skey[i]);
+      for(i = 0; i < pubkey_get_nenc (algorithm); i++)
+       log_mpidump ("  data:", data[i]);
+    }
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+  if (module)
+    {
+      pubkey = (gcry_pk_spec_t *) module->spec;
+      rc = pubkey->decrypt (algorithm, result, data, skey, flags);
+      _gcry_module_release (module);
+      goto ready;
+    }
+
+  rc = GPG_ERR_PUBKEY_ALGO;
+  
+ ready:
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  if (!rc && DBG_CIPHER && !fips_mode ())
+    log_mpidump (" plain:", *result);
+
+  return rc;
+}
+
+
+/****************
+ * This is the interface to the public key signing.
+ * Sign data with skey and put the result into resarr which
+ * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
+ * algorithm allows this - check with pubkey_get_nsig() )
+ */
+static gcry_err_code_t
+pubkey_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
+             gcry_mpi_t *skey)
+{
+  gcry_pk_spec_t *pubkey;
+  gcry_module_t module;
+  gcry_err_code_t rc;
+  int i;
+
+  if (DBG_CIPHER && !fips_mode ())
+    {
+      log_debug ("pubkey_sign: algo=%d\n", algorithm);
+      for(i = 0; i < pubkey_get_nskey (algorithm); i++)
+       log_mpidump ("  skey:", skey[i]);
+      log_mpidump("  data:", data );
+    }
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+  if (module)
+    {
+      pubkey = (gcry_pk_spec_t *) module->spec;
+      rc = pubkey->sign (algorithm, resarr, data, skey);
+      _gcry_module_release (module);
+      goto ready;
+    }
+
+  rc = GPG_ERR_PUBKEY_ALGO;
+
+ ready:
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  if (!rc && DBG_CIPHER && !fips_mode ())
+    for (i = 0; i < pubkey_get_nsig (algorithm); i++)
+      log_mpidump ("   sig:", resarr[i]);
+
+  return rc;
+}
+
+/****************
+ * Verify a public key signature.
+ * Return 0 if the signature is good
+ */
+static gcry_err_code_t
+pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
+               gcry_mpi_t *pkey,
+              int (*cmp)(void *, gcry_mpi_t), void *opaquev)
+{
+  gcry_pk_spec_t *pubkey;
+  gcry_module_t module;
+  gcry_err_code_t rc;
+  int i;
+
+  if (DBG_CIPHER && !fips_mode ())
+    {
+      log_debug ("pubkey_verify: algo=%d\n", algorithm);
+      for (i = 0; i < pubkey_get_npkey (algorithm); i++)
+       log_mpidump ("  pkey:", pkey[i]);
+      for (i = 0; i < pubkey_get_nsig (algorithm); i++)
+       log_mpidump ("   sig:", data[i]);
+      log_mpidump ("  hash:", hash);
+    }
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+  if (module)
+    {
+      pubkey = (gcry_pk_spec_t *) module->spec;
+      rc = pubkey->verify (algorithm, hash, data, pkey, cmp, opaquev);
+      _gcry_module_release (module);
+      goto ready;
+    }
+
+  rc = GPG_ERR_PUBKEY_ALGO;
+
+ ready:
+  ath_mutex_unlock (&pubkeys_registered_lock);
+  return rc;
+}
+
+
+/* Internal function.   */
+static gcry_err_code_t
+sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
+                      gcry_mpi_t *elements, const char *algo_name)
+{
+  gcry_err_code_t err = 0;
+  int i, idx;
+  const char *name;
+  gcry_sexp_t list;
+
+  for (name = element_names, idx = 0; *name && !err; name++, idx++)
+    {
+      list = gcry_sexp_find_token (key_sexp, name, 1);
+      if (!list)
+       elements[idx] = NULL;
+      else
+       {
+         elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
+         gcry_sexp_release (list);
+         if (!elements[idx])
+           err = GPG_ERR_INV_OBJ;
+       }
+    }
+
+  if (!err)
+    {
+      /* Check that all elements are available.  */
+      for (name = element_names, idx = 0; *name; name++, idx++)
+        if (!elements[idx])
+          break;
+      if (*name)
+        {
+          err = GPG_ERR_NO_OBJ;
+          /* Some are missing.  Before bailing out we test for
+             optional parameters.  */
+          if (algo_name && !strcmp (algo_name, "RSA")
+              && !strcmp (element_names, "nedpqu") )
+            {
+              /* This is RSA.  Test whether we got N, E and D and that
+                 the optional P, Q and U are all missing.  */
+              if (elements[0] && elements[1] && elements[2]
+                  && !elements[3] && !elements[4] && !elements[5])
+                err = 0;
+            }
+        }
+    }
+
+
+  if (err)
+    {
+      for (i = 0; i < idx; i++)
+        if (elements[i])
+          gcry_free (elements[i]);
+    }
+  return err;
+}
+
+
+/* Internal function used for ecc.  Note, that this function makes use
+   of its intimate knowledge about the ECC parameters from ecc.c. */
+static gcry_err_code_t
+sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
+                           gcry_mpi_t *elements, pk_extra_spec_t *extraspec)
+
+{
+  gcry_err_code_t err = 0;
+  int idx;
+  const char *name;
+  gcry_sexp_t list;
+
+  /* Clear the array for easier error cleanup. */
+  for (name = element_names, idx = 0; *name; name++, idx++)
+    elements[idx] = NULL;
+  gcry_assert (idx >= 6); /* We know that ECC has at least 6 elements.  */
+
+  /* Init the array with the available curve parameters. */
+  for (name = element_names, idx = 0; *name && !err; name++, idx++)
+    {
+      list = gcry_sexp_find_token (key_sexp, name, 1);
+      if (!list)
+       elements[idx] = NULL;
+      else
+       {
+         elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
+         gcry_sexp_release (list);
+         if (!elements[idx])
+            {
+              err = GPG_ERR_INV_OBJ;
+              goto leave;
+            }
+       }
+    }
+
+  /* Check whether a curve parameter has been given and then fill any
+     missing elements.  */
+  list = gcry_sexp_find_token (key_sexp, "curve", 5);
+  if (list)
+    {
+      if (extraspec->get_param)
+        {
+          char *curve;
+          gcry_mpi_t params[6];
+          
+          for (idx = 0; idx < DIM(params); idx++)
+            params[idx] = NULL;
+          
+          curve = _gcry_sexp_nth_string (list, 1);
+          gcry_sexp_release (list);
+          if (!curve)
+            {
+              /* No curve name given (or out of core). */
+              err = GPG_ERR_INV_OBJ; 
+              goto leave;
+            }
+          err = extraspec->get_param (curve, params);
+          gcry_free (curve);
+          if (err)
+            goto leave;
+          
+          for (idx = 0; idx < DIM(params); idx++)
+            {
+              if (!elements[idx])
+                elements[idx] = params[idx];
+              else
+                mpi_free (params[idx]);
+            }
+        }
+      else
+        {
+          gcry_sexp_release (list);
+          err = GPG_ERR_INV_OBJ; /* "curve" given but ECC not supported. */
+          goto leave;
+        }
+    }
+
+  /* Check that all parameters are known.  */
+  for (name = element_names, idx = 0; *name; name++, idx++)
+    if (!elements[idx])
+      {
+        err = GPG_ERR_NO_OBJ;
+        goto leave;
+      }
+  
+ leave:
+  if (err)
+    {
+      for (name = element_names, idx = 0; *name; name++, idx++)
+        if (elements[idx])
+          gcry_free (elements[idx]);
+    }
+  return err;
+}
+
+
+
+/****************
+ * Convert a S-Exp with either a private or a public key to our
+ * internal format. Currently we do only support the following
+ * algorithms:
+ *    dsa
+ *    rsa
+ *    openpgp-dsa
+ *    openpgp-rsa
+ *    openpgp-elg
+ *    openpgp-elg-sig
+ *    ecdsa
+ * Provide a SE with the first element be either "private-key" or
+ * or "public-key". It is followed by a list with its first element
+ * be one of the above algorithm identifiers and the remaning
+ * elements are pairs with parameter-id and value.
+ * NOTE: we look through the list to find a list beginning with
+ * "private-key" or "public-key" - the first one found is used.
+ *
+ * Returns: A pointer to an allocated array of MPIs if the return value is
+ *         zero; the caller has to release this array.
+ *
+ * Example of a DSA public key:
+ *  (private-key
+ *    (dsa
+ *     (p <mpi>)
+ *     (g <mpi>)
+ *     (y <mpi>)
+ *     (x <mpi>)
+ *    )
+ *  )
+ * The <mpi> are expected to be in GCRYMPI_FMT_USG
+ */
+static gcry_err_code_t
+sexp_to_key (gcry_sexp_t sexp, int want_private, gcry_mpi_t **retarray,
+             gcry_module_t *retalgo)
+{
+  gcry_err_code_t err = 0;
+  gcry_sexp_t list, l2;
+  char *name;
+  const char *elems;
+  gcry_mpi_t *array;
+  gcry_module_t module;
+  gcry_pk_spec_t *pubkey;
+  pk_extra_spec_t *extraspec;
+  int is_ecc;
+
+  /* Check that the first element is valid.  */
+  list = gcry_sexp_find_token (sexp, 
+                               want_private? "private-key":"public-key", 0);
+  if (!list)
+    return GPG_ERR_INV_OBJ; /* Does not contain a key object.  */
+
+  l2 = gcry_sexp_cadr( list );
+  gcry_sexp_release ( list );
+  list = l2;
+  name = _gcry_sexp_nth_string (list, 0);
+  if (!name)
+    {
+      gcry_sexp_release ( list );
+      return GPG_ERR_INV_OBJ;      /* Invalid structure of object. */
+    }
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = gcry_pk_lookup_name (name);
+  ath_mutex_unlock (&pubkeys_registered_lock);
+  
+  /* Fixme: We should make sure that an ECC key is always named "ecc"
+     and not "ecdsa".  "ecdsa" should be used for the signature
+     itself.  We need a function to test whether an algorithm given
+     with a key is compatible with an application of the key (signing,
+     encryption).  For RSA this is easy, but ECC is the first
+     algorithm which has many flavours. */
+  is_ecc = ( !strcmp (name, "ecdsa") || !strcmp (name, "ecc") );
+  gcry_free (name);
+  
+  if (!module)
+    {
+      gcry_sexp_release (list);
+      return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
+    }
+  else
+    {
+      pubkey = (gcry_pk_spec_t *) module->spec;
+      extraspec = module->extraspec;
+    }
+
+  elems = want_private ? pubkey->elements_skey : pubkey->elements_pkey;
+  array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
+  if (!array)
+    err = gpg_err_code_from_errno (errno);
+  if (!err)
+    {
+      if (is_ecc)
+        err = sexp_elements_extract_ecc (list, elems, array, extraspec);
+      else
+        err = sexp_elements_extract (list, elems, array, pubkey->name);
+    }
+  
+  gcry_sexp_release (list);
+  
+  if (err)
+    {
+      gcry_free (array);
+
+      ath_mutex_lock (&pubkeys_registered_lock);
+      _gcry_module_release (module);
+      ath_mutex_unlock (&pubkeys_registered_lock);
+    }
+  else
+    {
+      *retarray = array;
+      *retalgo = module;
+    }
+  
+  return err;
+}
+
+
+static gcry_err_code_t
+sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
+            gcry_module_t *retalgo)
+{
+  gcry_err_code_t err = 0;
+  gcry_sexp_t list, l2;
+  char *name;
+  const char *elems;
+  gcry_mpi_t *array;
+  gcry_module_t module;
+  gcry_pk_spec_t *pubkey;
+  
+  /* Check that the first element is valid.  */
+  list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
+  if (!list)
+    return GPG_ERR_INV_OBJ; /* Does not contain a signature value object.  */
+
+  l2 = gcry_sexp_nth (list, 1);
+  if (!l2)
+    {
+      gcry_sexp_release (list);
+      return GPG_ERR_NO_OBJ;   /* No cadr for the sig object.  */
+    }
+  name = _gcry_sexp_nth_string (l2, 0);
+  if (!name)
+    {
+      gcry_sexp_release (list);
+      gcry_sexp_release (l2);
+      return GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
+    }
+  else if (!strcmp (name, "flags")) 
+    {
+      /* Skip flags, since they are not used but here just for the
+        sake of consistent S-expressions.  */
+      gcry_free (name);
+      gcry_sexp_release (l2);
+      l2 = gcry_sexp_nth (list, 2);
+      if (!l2)
+       {
+         gcry_sexp_release (list);
+         return GPG_ERR_INV_OBJ;
+       }
+      name = _gcry_sexp_nth_string (l2, 0);
+    }
+      
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = gcry_pk_lookup_name (name);
+  ath_mutex_unlock (&pubkeys_registered_lock);
+  gcry_free (name);
+  name = NULL;
+
+  if (!module)
+    {
+      gcry_sexp_release (l2);
+      gcry_sexp_release (list);
+      return GPG_ERR_PUBKEY_ALGO;  /* Unknown algorithm. */
+    }
+  else
+    pubkey = (gcry_pk_spec_t *) module->spec;
+
+  elems = pubkey->elements_sig;
+  array = gcry_calloc (strlen (elems) + 1 , sizeof *array );
+  if (!array)
+    err = gpg_err_code_from_errno (errno);
+
+  if (!err)
+    err = sexp_elements_extract (list, elems, array, NULL);
+
+  gcry_sexp_release (l2);
+  gcry_sexp_release (list);
+
+  if (err)
+    {
+      ath_mutex_lock (&pubkeys_registered_lock);
+      _gcry_module_release (module);
+      ath_mutex_unlock (&pubkeys_registered_lock);
+      
+      gcry_free (array);
+    }
+  else
+    {
+      *retarray = array;
+      *retalgo = module;
+    }
+  
+  return err;
+}
+
+
+/****************
+ * Take sexp and return an array of MPI as used for our internal decrypt
+ * function.
+ * s_data = (enc-val
+ *           [(flags [pkcs1])]
+ *           (<algo>
+ *             (<param_name1> <mpi>)
+ *             ...
+ *             (<param_namen> <mpi>)
+ *           ))
+ * RET_MODERN is set to true when at least an empty flags list has been found.
+ */
+static gcry_err_code_t
+sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
+             int *ret_modern, int *ret_want_pkcs1, int *flags)
+{
+  gcry_err_code_t err = 0;
+  gcry_sexp_t list = NULL, l2 = NULL;
+  gcry_pk_spec_t *pubkey = NULL;
+  gcry_module_t module = NULL;
+  char *name = NULL;
+  size_t n;
+  int parsed_flags = 0;
+  const char *elems;
+  gcry_mpi_t *array = NULL;
+
+  *ret_want_pkcs1 = 0;
+  *ret_modern = 0;
+
+  /* Check that the first element is valid.  */
+  list = gcry_sexp_find_token (sexp, "enc-val" , 0);
+  if (!list)
+    {
+      err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
+      goto leave;
+    }
+
+  l2 = gcry_sexp_nth (list, 1);
+  if (!l2)
+    {
+      err = GPG_ERR_NO_OBJ; /* No cdr for the data object.  */
+      goto leave;
+    }
+
+  /* Extract identifier of sublist.  */
+  name = _gcry_sexp_nth_string (l2, 0);
+  if (!name)
+    {
+      err = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
+      goto leave;
+    }
+  
+  if (!strcmp (name, "flags"))
+    {
+      /* There is a flags element - process it.  */
+      const char *s;
+      int i;
+      
+      *ret_modern = 1;
+      for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
+        {
+          s = gcry_sexp_nth_data (l2, i, &n);
+          if (! s)
+            ; /* Not a data element - ignore.  */
+          else if (n == 3 && !memcmp (s, "raw", 3))
+            ; /* This is just a dummy as it is the default.  */
+          else if (n == 5 && !memcmp (s, "pkcs1", 5))
+            *ret_want_pkcs1 = 1;
+          else if (n == 11 && ! memcmp (s, "no-blinding", 11))
+            parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
+          else
+            {
+              err = GPG_ERR_INV_FLAG;
+              goto leave;
+            }
+        }
+      
+      /* Get the next which has the actual data. */
+      gcry_sexp_release (l2);
+      l2 = gcry_sexp_nth (list, 2);
+      if (!l2)
+        {
+          err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
+          goto leave;
+        }
+
+      /* Extract sublist identifier.  */
+      gcry_free (name);
+      name = _gcry_sexp_nth_string (l2, 0);
+      if (!name)
+        {
+          err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
+          goto leave;
+        }
+
+      gcry_sexp_release (list);
+      list = l2;
+      l2 = NULL;
+    }
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = gcry_pk_lookup_name (name);
+  ath_mutex_unlock (&pubkeys_registered_lock);
+  
+  if (!module)
+    {
+      err = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
+      goto leave;
+    }
+  pubkey = (gcry_pk_spec_t *) module->spec;
+
+  elems = pubkey->elements_enc;
+  array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
+  if (!array)
+    {
+      err = gpg_err_code_from_errno (errno);
+      goto leave;
+    }
+
+  err = sexp_elements_extract (list, elems, array, NULL);
+
+ leave:
+  gcry_sexp_release (list);
+  gcry_sexp_release (l2);
+  gcry_free (name);
+
+  if (err)
+    {
+      ath_mutex_lock (&pubkeys_registered_lock);
+      _gcry_module_release (module);
+      ath_mutex_unlock (&pubkeys_registered_lock);
+      gcry_free (array);
+    }
+  else
+    {
+      *retarray = array;
+      *retalgo = module;
+      *flags = parsed_flags;
+    }
+
+  return err;
+}
+
+/* Take the hash value and convert into an MPI, suitable for
+   passing to the low level functions.  We currently support the
+   old style way of passing just a MPI and the modern interface which
+   allows to pass flags so that we can choose between raw and pkcs1
+   padding - may be more padding options later. 
+
+   (<mpi>)
+   or
+   (data
+    [(flags [pkcs1])]
+    [(hash <algo> <value>)]
+    [(value <text>)]
+   )
+   
+   Either the VALUE or the HASH element must be present for use
+   with signatures.  VALUE is used for encryption.
+
+   NBITS is the length of the key in bits. 
+
+*/
+static gcry_err_code_t
+sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
+                  int for_encryption, int *flags)
+{
+  gcry_err_code_t rc = 0;
+  gcry_sexp_t ldata, lhash, lvalue;
+  int i;
+  size_t n;
+  const char *s;
+  int is_raw = 0, is_pkcs1 = 0, unknown_flag=0; 
+  int parsed_flags = 0, dummy_flags;
+
+  if (! flags)
+    flags = &dummy_flags;
+  
+  *ret_mpi = NULL;
+  ldata = gcry_sexp_find_token (input, "data", 0);
+  if (!ldata)
+    { /* assume old style */
+      *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
+      return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
+    }
+
+  /* see whether there is a flags object */
+  {
+    gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
+    if (lflags)
+      { /* parse the flags list. */
+        for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
+          {
+            s = gcry_sexp_nth_data (lflags, i, &n);
+            if (!s)
+              ; /* not a data element*/
+            else if ( n == 3 && !memcmp (s, "raw", 3))
+              is_raw = 1;
+            else if ( n == 5 && !memcmp (s, "pkcs1", 5))
+              is_pkcs1 = 1;
+           else if (n == 11 && ! memcmp (s, "no-blinding", 11))
+             parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
+            else
+              unknown_flag = 1;
+          }
+        gcry_sexp_release (lflags);
+      }
+  }
+
+  if (!is_pkcs1 && !is_raw)
+    is_raw = 1; /* default to raw */
+
+  /* Get HASH or MPI */
+  lhash = gcry_sexp_find_token (ldata, "hash", 0);
+  lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
+
+  if (!(!lhash ^ !lvalue))
+    rc = GPG_ERR_INV_OBJ; /* none or both given */
+  else if (unknown_flag)
+    rc = GPG_ERR_INV_FLAG;
+  else if (is_raw && is_pkcs1 && !for_encryption)
+    rc = GPG_ERR_CONFLICT;
+  else if (is_raw && lvalue)
+    {
+      *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, 0);
+      if (!*ret_mpi)
+        rc = GPG_ERR_INV_OBJ;
+    }
+  else if (is_pkcs1 && lvalue && for_encryption)
+    { 
+      /* Create pkcs#1 block type 2 padding. */
+      unsigned char *frame = NULL;
+      size_t nframe = (nbits+7) / 8;
+      const void * value;
+      size_t valuelen;
+      unsigned char *p;
+
+      if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
+        rc = GPG_ERR_INV_OBJ;
+      else if (valuelen + 7 > nframe || !nframe)
+        {
+          /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
+          rc = GPG_ERR_TOO_SHORT; /* the key is too short */
+        }
+      else if ( !(frame = gcry_malloc_secure (nframe)))
+        rc = gpg_err_code_from_errno (errno);
+      else
+        {
+          n = 0;
+          frame[n++] = 0;
+          frame[n++] = 2; /* block type */
+          i = nframe - 3 - valuelen;
+          gcry_assert (i > 0);
+          p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
+          /* Replace zero bytes by new values. */
+          for (;;)
+            {
+              int j, k;
+              unsigned char *pp;
+              
+              /* Count the zero bytes. */
+              for (j=k=0; j < i; j++)
+                {
+                  if (!p[j])
+                    k++;
+                }
+              if (!k)
+                break; /* Okay: no (more) zero bytes. */
+              
+              k += k/128 + 3; /* Better get some more. */
+              pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
+              for (j=0; j < i && k; )
+                {
+                  if (!p[j])
+                    p[j] = pp[--k];
+                  if (p[j])
+                    j++;
+                }
+              gcry_free (pp);
+            }
+          memcpy (frame+n, p, i);
+          n += i;
+          gcry_free (p);
+          
+          frame[n++] = 0;
+          memcpy (frame+n, value, valuelen);
+          n += valuelen;
+          gcry_assert (n == nframe);
+
+         /* FIXME, error checking?  */
+          gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
+        }
+
+      gcry_free(frame);
+    }
+  else if (is_pkcs1 && lhash && !for_encryption)
+    { 
+      /* Create pkcs#1 block type 1 padding. */
+      if (gcry_sexp_length (lhash) != 3)
+        rc = GPG_ERR_INV_OBJ;
+      else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
+        rc = GPG_ERR_INV_OBJ;
+      else
+        {
+          static struct { const char *name; int algo; } hashnames[] = 
+          { { "sha1",   GCRY_MD_SHA1 },
+            { "md5",    GCRY_MD_MD5 },
+            { "sha256", GCRY_MD_SHA256 },
+            { "ripemd160", GCRY_MD_RMD160 },
+            { "rmd160", GCRY_MD_RMD160 },
+            { "sha384", GCRY_MD_SHA384 },
+            { "sha512", GCRY_MD_SHA512 },
+            { "sha224", GCRY_MD_SHA224 },
+            { "md2",    GCRY_MD_MD2 },
+            { "md4",    GCRY_MD_MD4 },
+            { "tiger",  GCRY_MD_TIGER },
+            { "haval",  GCRY_MD_HAVAL },
+            { NULL, 0 }
+          };
+          int algo;
+          byte asn[100];
+          byte *frame = NULL;
+          size_t nframe = (nbits+7) / 8;
+          const void * value;
+          size_t valuelen;
+          size_t asnlen, dlen;
+            
+          for (i=0; hashnames[i].name; i++)
+            {
+              if ( strlen (hashnames[i].name) == n
+                   && !memcmp (hashnames[i].name, s, n))
+                break;
+            }
+          if (hashnames[i].name)
+            algo = hashnames[i].algo;
+          else
+            {
+              /* In case of not listed or dynamically allocated hash
+                 algorithm we fall back to this somewhat slower
+                 method.  Further, it also allows to use OIDs as
+                 algorithm names. */
+              char *tmpname;
+
+              tmpname = gcry_malloc (n+1);
+              if (!tmpname)
+                algo = 0;  /* Out of core - silently give up.  */
+              else
+                {
+                  memcpy (tmpname, s, n);
+                  tmpname[n] = 0;
+                  algo = gcry_md_map_name (tmpname);
+                  gcry_free (tmpname);
+                }
+            }
+
+          asnlen = DIM(asn);
+          dlen = gcry_md_get_algo_dlen (algo);
+
+          if (!algo)
+            rc = GPG_ERR_DIGEST_ALGO;
+          else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
+                    || !valuelen )
+            rc = GPG_ERR_INV_OBJ;
+          else if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
+            {
+              /* We don't have yet all of the above algorithms.  */
+              rc = GPG_ERR_NOT_IMPLEMENTED;
+            }
+          else if ( valuelen != dlen )
+            {
+              /* Hash value does not match the length of digest for
+                 the given algorithm. */
+              rc = GPG_ERR_CONFLICT;
+            }
+          else if( !dlen || dlen + asnlen + 4 > nframe)
+            {
+              /* Can't encode an DLEN byte digest MD into a NFRAME
+                 byte frame. */
+              rc = GPG_ERR_TOO_SHORT;
+            }
+          else if ( !(frame = gcry_malloc (nframe)) )
+            rc = gpg_err_code_from_errno (errno);
+          else
+            { /* Assemble the pkcs#1 block type 1. */
+              n = 0;
+              frame[n++] = 0;
+              frame[n++] = 1; /* block type */
+              i = nframe - valuelen - asnlen - 3 ;
+              gcry_assert (i > 1);
+              memset (frame+n, 0xff, i );
+              n += i;
+              frame[n++] = 0;
+              memcpy (frame+n, asn, asnlen);
+              n += asnlen;
+              memcpy (frame+n, value, valuelen );
+              n += valuelen;
+              gcry_assert (n == nframe);
+      
+              /* Convert it into an MPI.  FIXME: error checking?  */
+              gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
+            }
+          
+          gcry_free (frame);
+        }
+    }
+  else
+    rc = GPG_ERR_CONFLICT;
+   
+  gcry_sexp_release (ldata);
+  gcry_sexp_release (lhash);
+  gcry_sexp_release (lvalue);
+
+  if (!rc)
+    *flags = parsed_flags;
+
+  return rc;
+}
+
+
+/*
+   Do a PK encrypt operation
+  
+   Caller has to provide a public key as the SEXP pkey and data as a
+   SEXP with just one MPI in it. Alternativly S_DATA might be a
+   complex S-Expression, similar to the one used for signature
+   verification.  This provides a flag which allows to handle PKCS#1
+   block type 2 padding.  The function returns a a sexp which may be
+   passed to to pk_decrypt.
+  
+   Returns: 0 or an errorcode.
+  
+   s_data = See comment for sexp_data_to_mpi
+   s_pkey = <key-as-defined-in-sexp_to_key>
+   r_ciph = (enc-val
+               (<algo>
+                 (<param_name1> <mpi>)
+                 ...
+                 (<param_namen> <mpi>)
+               ))
+
+*/
+gcry_error_t
+gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
+{
+  gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL;
+  const char *algo_name, *algo_elems;
+  int flags;
+  gcry_err_code_t rc;
+  gcry_pk_spec_t *pubkey = NULL;
+  gcry_module_t module = NULL;
+
+  *r_ciph = NULL;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  /* Get the key. */
+  rc = sexp_to_key (s_pkey, 0, &pkey, &module);
+  if (rc)
+    goto leave;
+
+  gcry_assert (module);
+  pubkey = (gcry_pk_spec_t *) module->spec;
+
+  /* If aliases for the algorithm name exists, take the first one
+     instead of the regular name to adhere to SPKI conventions.  We
+     assume that the first alias name is the lowercase version of the
+     regular one.  This change is required for compatibility with
+     1.1.12 generated S-expressions. */
+  algo_name = pubkey->aliases? *pubkey->aliases : NULL;
+  if (!algo_name || !*algo_name)
+    algo_name = pubkey->name;
+  
+  algo_elems = pubkey->elements_enc;
+  
+  /* Get the stuff we want to encrypt. */
+  rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1,
+                         &flags);
+  if (rc)
+    goto leave;
+
+  /* Now we can encrypt DATA to CIPH. */
+  ciph = gcry_calloc (strlen (algo_elems) + 1, sizeof (*ciph));
+  if (!ciph)
+    {
+      rc = gpg_err_code_from_errno (errno);
+      goto leave;
+    }
+  rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, flags);
+  mpi_free (data);
+  data = NULL;
+  if (rc)
+    goto leave;
+
+  /* We did it.  Now build the return list */
+  {
+    char *string, *p;
+    int i;
+    size_t nelem = strlen (algo_elems);
+    size_t needed = 19 + strlen (algo_name) + (nelem * 5);
+    void **arg_list;
+    
+    /* Build the string.  */
+    string = p = gcry_malloc (needed);
+    if (!string)
+      {
+        rc = gpg_err_code_from_errno (errno);
+        goto leave;
+      }
+    p = stpcpy ( p, "(enc-val(" );
+    p = stpcpy ( p, algo_name );
+    for (i=0; algo_elems[i]; i++ )
+      {
+        *p++ = '(';
+        *p++ = algo_elems[i];
+        p = stpcpy ( p, "%m)" );
+      }
+    strcpy ( p, "))" );
+    
+    /* And now the ugly part: We don't have a function to pass an
+     * array to a format string, so we have to do it this way :-(.  */
+    /* FIXME: There is now such a format specifier, so we can
+       change the code to be more clear. */
+    arg_list = malloc (nelem * sizeof *arg_list);
+    if (!arg_list)
+      {
+        rc = gpg_err_code_from_errno (errno);
+        goto leave;
+      }
+
+    for (i = 0; i < nelem; i++)
+      arg_list[i] = ciph + i;
+    
+    rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
+    free (arg_list);
+    if (rc)
+      BUG ();
+    gcry_free (string);
+  }
+
+ leave:
+  if (pkey)
+    {
+      release_mpi_array (pkey);
+      gcry_free (pkey);
+    }
+
+  if (ciph)
+    {
+      release_mpi_array (ciph);
+      gcry_free (ciph);
+    }
+
+  if (module)
+    {
+      ath_mutex_lock (&pubkeys_registered_lock);
+      _gcry_module_release (module);
+      ath_mutex_unlock (&pubkeys_registered_lock);
+    }
+
+  return gcry_error (rc);
+}
+
+/* 
+   Do a PK decrypt operation
+  
+   Caller has to provide a secret key as the SEXP skey and data in a
+   format as created by gcry_pk_encrypt.  For historic reasons the
+   function returns simply an MPI as an S-expression part; this is
+   deprecated and the new method should be used which returns a real
+   S-expressionl this is selected by adding at least an empty flags
+   list to S_DATA.
+   
+   Returns: 0 or an errorcode.
+  
+   s_data = (enc-val
+              [(flags)]
+              (<algo>
+                (<param_name1> <mpi>)
+                ...
+                (<param_namen> <mpi>)
+              ))
+   s_skey = <key-as-defined-in-sexp_to_key>
+   r_plain= Either an incomplete S-expression without the parentheses
+            or if the flags list is used (even if empty) a real S-expression:
+            (value PLAIN). 
+ */
+gcry_error_t
+gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
+{
+  gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL;
+  int modern, want_pkcs1, flags;
+  gcry_err_code_t rc;
+  gcry_module_t module_enc = NULL, module_key = NULL;
+  gcry_pk_spec_t *pubkey = NULL;
+
+  *r_plain = NULL;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  rc = sexp_to_key (s_skey, 1, &skey, &module_key);
+  if (rc)
+    goto leave;
+
+  rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &want_pkcs1, &flags);
+  if (rc)
+    goto leave;
+  
+  if (module_key->mod_id != module_enc->mod_id)
+    {
+      rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
+      goto leave;
+    }
+
+  pubkey = (gcry_pk_spec_t *) module_key->spec;
+
+  rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
+  if (rc)
+    goto leave;
+
+  if (gcry_sexp_build (r_plain, NULL, modern? "(value %m)" : "%m", plain))
+    BUG ();
+  
+ leave:
+  if (skey)
+    {
+      release_mpi_array (skey);
+      gcry_free (skey);
+    }
+
+  if (plain)
+    mpi_free (plain);
+
+  if (data)
+    {
+      release_mpi_array (data);
+      gcry_free (data);
+    }
+
+  if (module_key || module_enc)
+    {
+      ath_mutex_lock (&pubkeys_registered_lock);
+      if (module_key)
+       _gcry_module_release (module_key);
+      if (module_enc)
+       _gcry_module_release (module_enc);
+      ath_mutex_unlock (&pubkeys_registered_lock);
+    }
+
+  return gcry_error (rc);
+}
+
+
+
+/*
+   Create a signature.
+  
+   Caller has to provide a secret key as the SEXP skey and data
+   expressed as a SEXP list hash with only one element which should
+   instantly be available as a MPI. Alternatively the structure given
+   below may be used for S_HASH, it provides the abiliy to pass flags
+   to the operation; the only flag defined by now is "pkcs1" which
+   does PKCS#1 block type 1 style padding.
+  
+   Returns: 0 or an errorcode.
+            In case of 0 the function returns a new SEXP with the
+            signature value; the structure of this signature depends on the
+            other arguments but is always suitable to be passed to
+            gcry_pk_verify
+  
+   s_hash = See comment for sexp_data_to_mpi
+               
+   s_skey = <key-as-defined-in-sexp_to_key>
+   r_sig  = (sig-val
+              (<algo>
+                (<param_name1> <mpi>)
+                ...
+                (<param_namen> <mpi>))
+             [(hash algo)]) 
+
+  Note that (hash algo) in R_SIG is not used.
+*/
+gcry_error_t
+gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
+{
+  gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL;
+  gcry_pk_spec_t *pubkey = NULL;
+  gcry_module_t module = NULL;
+  const char *algo_name, *algo_elems;
+  int i;
+  gcry_err_code_t rc;
+
+  *r_sig = NULL;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  rc = sexp_to_key (s_skey, 1, &skey, &module);
+  if (rc)
+    goto leave;
+
+  gcry_assert (module);
+  pubkey = (gcry_pk_spec_t *) module->spec;
+  algo_name = pubkey->aliases? *pubkey->aliases : NULL;
+  if (!algo_name || !*algo_name)
+    algo_name = pubkey->name;
+  
+  algo_elems = pubkey->elements_sig;
+
+  /* Get the stuff we want to sign.  Note that pk_get_nbits does also
+      work on a private key. */
+  rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey),
+                             &hash, 0, NULL);
+  if (rc)
+    goto leave;
+
+  result = gcry_calloc (strlen (algo_elems) + 1, sizeof (*result));
+  if (!result)
+    {
+      rc = gpg_err_code_from_errno (errno);
+      goto leave;
+    }
+  rc = pubkey_sign (module->mod_id, result, hash, skey);
+  if (rc)
+    goto leave;
+
+  {
+    char *string, *p;
+    size_t nelem, needed = strlen (algo_name) + 20;
+    void **arg_list;
+
+    nelem = strlen (algo_elems);
+    
+    /* Count elements, so that we can allocate enough space. */
+    needed += 10 * nelem;
+
+    /* Build the string. */
+    string = p = gcry_malloc (needed);
+    if (!string)
+      {
+        rc = gpg_err_code_from_errno (errno);
+        goto leave;
+      }
+    p = stpcpy (p, "(sig-val(");
+    p = stpcpy (p, algo_name);
+    for (i = 0; algo_elems[i]; i++)
+      {
+        *p++ = '(';
+        *p++ = algo_elems[i];
+        p = stpcpy (p, "%m)");
+      }
+    strcpy (p, "))");
+
+    arg_list = malloc (nelem * sizeof *arg_list);
+    if (!arg_list)
+      {
+        rc = gpg_err_code_from_errno (errno);
+        goto leave;
+      }
+
+    for (i = 0; i < nelem; i++)
+      arg_list[i] = result + i;
+
+    rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
+    free (arg_list);
+    if (rc)
+      BUG ();
+    gcry_free (string);
+  }
+
+ leave:
+  if (skey)
+    {
+      release_mpi_array (skey);
+      gcry_free (skey);
+    }
+
+  if (hash)
+    mpi_free (hash);
+
+  if (result)
+    {
+      release_mpi_array (result);
+      gcry_free (result);
+    }
+
+  return gcry_error (rc);
+}
+
+
+/*
+   Verify a signature.
+
+   Caller has to supply the public key pkey, the signature sig and his
+   hashvalue data.  Public key has to be a standard public key given
+   as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
+   must be an S-Exp like the one in sign too.  */
+gcry_error_t
+gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
+{
+  gcry_module_t module_key = NULL, module_sig = NULL;
+  gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
+  gcry_err_code_t rc;
+
+  REGISTER_DEFAULT_PUBKEYS;
+  rc = sexp_to_key (s_pkey, 0, &pkey, &module_key);
+  if (rc)
+    goto leave;
+
+  rc = sexp_to_sig (s_sig, &sig, &module_sig);
+  if (rc)
+    goto leave;
+
+  /* Fixme: Check that the algorithm of S_SIG is compatible to the one
+     of S_PKEY.  */
+
+  if (module_key->mod_id != module_sig->mod_id)
+    {
+      rc = GPG_ERR_CONFLICT;
+      goto leave;
+    }
+
+  rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0);
+  if (rc)
+    goto leave;
+
+  rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, NULL, NULL);
+
+ leave:
+  if (pkey)
+    {
+      release_mpi_array (pkey);
+      gcry_free (pkey);
+    }
+  if (sig)
+    {
+      release_mpi_array (sig);
+      gcry_free (sig);
+    }
+  if (hash)
+    mpi_free (hash);
+
+  if (module_key || module_sig)
+    {
+      ath_mutex_lock (&pubkeys_registered_lock);
+      if (module_key)
+       _gcry_module_release (module_key);
+      if (module_sig)
+       _gcry_module_release (module_sig);
+      ath_mutex_unlock (&pubkeys_registered_lock);
+    }
+
+  return gcry_error (rc);
+}
+
+
+/*
+   Test a key.
+
+   This may be used either for a public or a secret key to see whether
+   the internal structure is okay.
+  
+   Returns: 0 or an errorcode.
+  
+   s_key = <key-as-defined-in-sexp_to_key> */
+gcry_error_t
+gcry_pk_testkey (gcry_sexp_t s_key)
+{
+  gcry_module_t module = NULL;
+  gcry_mpi_t *key = NULL;
+  gcry_err_code_t rc;
+  
+  REGISTER_DEFAULT_PUBKEYS;
+
+  /* Note we currently support only secret key checking. */
+  rc = sexp_to_key (s_key, 1, &key, &module);
+  if (! rc)
+    {
+      rc = pubkey_check_secret_key (module->mod_id, key);
+      release_mpi_array (key);
+      gcry_free (key);
+    }
+  return gcry_error (rc);
+}
+
+
+/*
+  Create a public key pair and return it in r_key.
+  How the key is created depends on s_parms:
+  (genkey
+   (algo
+     (parameter_name_1 ....)
+      ....
+     (parameter_name_n ....)
+  ))
+  The key is returned in a format depending on the
+  algorithm. Both, private and secret keys are returned
+  and optionally some additional informatin.
+  For elgamal we return this structure:
+  (key-data
+   (public-key
+     (elg
+       (p <mpi>)
+       (g <mpi>)
+       (y <mpi>)
+     )
+   )
+   (private-key
+     (elg
+       (p <mpi>)
+       (g <mpi>)
+       (y <mpi>)
+       (x <mpi>)
+     )
+   )
+   (misc-key-info
+      (pm1-factors n1 n2 ... nn)
+   ))
+ */
+gcry_error_t
+gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
+{
+  gcry_pk_spec_t *pubkey = NULL;
+  gcry_module_t module = NULL;
+  gcry_sexp_t list = NULL;
+  gcry_sexp_t l2 = NULL;
+  gcry_sexp_t l3 = NULL;
+  char *name = NULL;
+  size_t n;
+  gcry_err_code_t rc = GPG_ERR_NO_ERROR;
+  int i;
+  const char *algo_name = NULL;
+  int algo;
+  const char *sec_elems = NULL, *pub_elems = NULL;
+  gcry_mpi_t skey[12];
+  gcry_mpi_t *factors = NULL;
+  gcry_sexp_t extrainfo = NULL;
+  unsigned int nbits = 0;
+  unsigned long use_e = 0;
+
+  skey[0] = NULL;
+  *r_key = NULL;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  list = gcry_sexp_find_token (s_parms, "genkey", 0);
+  if (!list)
+    {
+      rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
+      goto leave;
+    }
+
+  l2 = gcry_sexp_cadr (list);
+  gcry_sexp_release (list);
+  list = l2;
+  l2 = NULL;
+  if (! list)
+    {
+      rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
+      goto leave;
+    }
+
+  name = _gcry_sexp_nth_string (list, 0);
+  if (!name)
+    {
+      rc = GPG_ERR_INV_OBJ; /* Algo string missing.  */
+      goto leave;
+    }
+  
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = gcry_pk_lookup_name (name);
+  ath_mutex_unlock (&pubkeys_registered_lock);
+  gcry_free (name);
+  name = NULL;
+  if (!module)
+    {
+      rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
+      goto leave;
+    }
+  
+  pubkey = (gcry_pk_spec_t *) module->spec;
+  algo = module->mod_id;
+  algo_name = pubkey->aliases? *pubkey->aliases : NULL;
+  if (!algo_name || !*algo_name)
+    algo_name = pubkey->name;
+  pub_elems = pubkey->elements_pkey;
+  sec_elems = pubkey->elements_skey;
+  if (strlen (sec_elems) >= DIM(skey))
+    BUG ();
+
+  /* Handle the optional rsa-use-e element.  Actually this belong into
+     the algorithm module but we have this parameter in the public
+     module API, so we need to parse it right here.  */
+  l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
+  if (l2)
+    {
+      char buf[50];
+      const char *s;
+
+      s = gcry_sexp_nth_data (l2, 1, &n);
+      if ( !s || n >= DIM (buf) - 1 )
+        {
+          rc = GPG_ERR_INV_OBJ; /* No value or value too large.  */
+          goto leave;
+        }
+      memcpy (buf, s, n);
+      buf[n] = 0;
+      use_e = strtoul (buf, NULL, 0);
+      gcry_sexp_release (l2);
+      l2 = NULL;
+    }
+  else
+    use_e = 65537; /* Not given, use the value generated by old versions. */
+
+
+  /* Get the "nbits" parameter.  */
+  l2 = gcry_sexp_find_token (list, "nbits", 0);
+  if (l2)
+    {
+      char buf[50];
+      const char *s;
+
+      s = gcry_sexp_nth_data (l2, 1, &n);
+      if (!s || n >= DIM (buf) - 1 )
+        {
+          rc = GPG_ERR_INV_OBJ; /* NBITS given without a cdr.  */
+          goto leave;
+        }
+      memcpy (buf, s, n);
+      buf[n] = 0;
+      nbits = (unsigned int)strtoul (buf, NULL, 0);
+      gcry_sexp_release (l2); l2 = NULL;
+    }
+  else 
+    nbits = 0;
+
+  /* Pass control to the algorithm module. */
+  rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey, 
+                        &factors, &extrainfo);
+  gcry_sexp_release (list); list = NULL;
+  if (rc)
+    goto leave;
+
+  /* Key generation succeeded: Build an S-expression.  */
+  {
+    char *string, *p;
+    size_t nelem=0, nelem_cp = 0, needed=0;
+    gcry_mpi_t mpis[30];
+    
+    /* Estimate size of format string.  */
+    nelem = strlen (pub_elems) + strlen (sec_elems);
+    if (factors)
+      {
+        for (i = 0; factors[i]; i++)
+          nelem++;
+      }
+    nelem_cp = nelem;
+
+    needed += nelem * 10;
+    /* (+5 is for EXTRAINFO ("%S")).  */
+    needed += 2 * strlen (algo_name) + 300 + 5;
+    if (nelem > DIM (mpis))
+      BUG ();
+
+    /* Build the string. */
+    nelem = 0;
+    string = p = gcry_malloc (needed);
+    if (!string)
+      {
+        rc = gpg_err_code_from_errno (errno);
+        goto leave;
+      }
+    p = stpcpy (p, "(key-data");
+    p = stpcpy (p, "(public-key(");
+    p = stpcpy (p, algo_name);
+    for(i = 0; pub_elems[i]; i++)
+      {
+        *p++ = '(';
+        *p++ = pub_elems[i];
+        p = stpcpy (p, "%m)");
+        mpis[nelem++] = skey[i];
+      }
+    p = stpcpy (p, "))");
+    p = stpcpy (p, "(private-key(");
+    p = stpcpy (p, algo_name);
+    for (i = 0; sec_elems[i]; i++)
+      {
+        *p++ = '(';
+        *p++ = sec_elems[i];
+        p = stpcpy (p, "%m)");
+        mpis[nelem++] = skey[i];
+      }
+    p = stpcpy (p, "))");
+
+    /* Hack to make release_mpi_array() work.  */
+    skey[i] = NULL;
+
+    if (extrainfo)
+      {
+        /* If we have extrainfo we should not have any factors.  */
+        p = stpcpy (p, "%S");
+      }
+    else if (factors && factors[0])
+      {
+        p = stpcpy (p, "(misc-key-info(pm1-factors");
+        for(i = 0; factors[i]; i++)
+          {
+            p = stpcpy (p, "%m");
+            mpis[nelem++] = factors[i];
+          }
+        p = stpcpy (p, "))");
+      }
+    strcpy (p, ")");
+    gcry_assert (p - string < needed);
+
+    while (nelem < DIM (mpis))
+      mpis[nelem++] = NULL;
+
+    {
+      int elem_n = strlen (pub_elems) + strlen (sec_elems);
+      void **arg_list;
+
+      /* Allocate one extra for EXTRAINFO ("%S").  */
+      arg_list = gcry_calloc (nelem_cp+1, sizeof *arg_list);
+      if (!arg_list)
+        {
+          rc = gpg_err_code_from_errno (errno);
+          goto leave;
+        }
+      for (i = 0; i < elem_n; i++)
+        arg_list[i] = mpis + i;
+      if (extrainfo)
+        arg_list[i] = &extrainfo;
+      else if (factors && factors[0])
+        {
+          for (; i < nelem_cp; i++)
+            arg_list[i] = factors + i - elem_n;
+        }
+      
+      rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
+      gcry_free (arg_list);
+      if (rc)
+       BUG ();
+      gcry_assert (DIM (mpis) == 30); /* Reminder to make sure that
+                                         the array gets increased if
+                                         new parameters are added. */
+    }
+    gcry_free (string);
+  }
+
+ leave:
+  gcry_free (name);
+  gcry_sexp_release (extrainfo);
+  release_mpi_array (skey);
+  /* Don't free SKEY itself, it is an stack allocated array. */
+
+  if (factors)
+    {
+      release_mpi_array ( factors );
+      gcry_free (factors);
+    }
+  
+  gcry_sexp_release (l3);
+  gcry_sexp_release (l2);
+  gcry_sexp_release (list);
+
+  if (module)
+    {
+      ath_mutex_lock (&pubkeys_registered_lock);
+      _gcry_module_release (module);
+      ath_mutex_unlock (&pubkeys_registered_lock);
+    }
+
+  return gcry_error (rc);
+}
+
+
+/* 
+   Get the number of nbits from the public key.
+
+   Hmmm: Should we have really this function or is it better to have a
+   more general function to retrieve different properties of the key?  */
+unsigned int
+gcry_pk_get_nbits (gcry_sexp_t key)
+{
+  gcry_module_t module = NULL;
+  gcry_pk_spec_t *pubkey;
+  gcry_mpi_t *keyarr = NULL;
+  unsigned int nbits = 0;
+  gcry_err_code_t rc;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  rc = sexp_to_key (key, 0, &keyarr, &module);
+  if (rc == GPG_ERR_INV_OBJ)
+    rc = sexp_to_key (key, 1, &keyarr, &module);
+  if (rc)
+    return 0; /* Error - 0 is a suitable indication for that. */
+
+  pubkey = (gcry_pk_spec_t *) module->spec;
+  nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
+  
+  ath_mutex_lock (&pubkeys_registered_lock);
+  _gcry_module_release (module);
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  release_mpi_array (keyarr);
+  gcry_free (keyarr);
+
+  return nbits;
+}
+
+
+/* Return the so called KEYGRIP which is the SHA-1 hash of the public
+   key parameters expressed in a way depended on the algorithm.
+
+   ARRAY must either be 20 bytes long or NULL; in the latter case a
+   newly allocated array of that size is returned, otherwise ARRAY or
+   NULL is returned to indicate an error which is most likely an
+   unknown algorithm.  The function accepts public or secret keys. */
+unsigned char *
+gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
+{
+  gcry_sexp_t list = NULL, l2 = NULL;
+  gcry_pk_spec_t *pubkey = NULL;
+  gcry_module_t module = NULL;
+  pk_extra_spec_t *extraspec;
+  const char *s;
+  char *name = NULL;
+  int idx;
+  const char *elems;
+  gcry_md_hd_t md = NULL;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  /* Check that the first element is valid. */
+  list = gcry_sexp_find_token (key, "public-key", 0);
+  if (! list)
+    list = gcry_sexp_find_token (key, "private-key", 0);
+  if (! list)
+    list = gcry_sexp_find_token (key, "protected-private-key", 0);
+  if (! list)
+    list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
+  if (! list)
+    return NULL; /* No public- or private-key object. */
+
+  l2 = gcry_sexp_cadr (list);
+  gcry_sexp_release (list);
+  list = l2;
+  l2 = NULL;
+
+  name = _gcry_sexp_nth_string (list, 0);
+  if (!name)
+    goto fail; /* Invalid structure of object. */
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = gcry_pk_lookup_name (name);
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  if (!module)
+    goto fail; /* Unknown algorithm.  */
+
+  pubkey = (gcry_pk_spec_t *) module->spec;
+  extraspec = module->extraspec;
+
+  elems = pubkey->elements_grip;
+  if (!elems)
+    goto fail; /* No grip parameter.  */
+    
+  if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
+    goto fail;
+
+  if (extraspec && extraspec->comp_keygrip)
+    {
+      /* Module specific method to compute a keygrip.  */
+      if (extraspec->comp_keygrip (md, list))
+        goto fail;
+    }
+  else
+    {
+      /* Generic method to compute a keygrip.  */
+      for (idx = 0, s = elems; *s; s++, idx++)
+        {
+          const char *data;
+          size_t datalen;
+          char buf[30];
+          
+          l2 = gcry_sexp_find_token (list, s, 1);
+          if (! l2)
+            goto fail;
+          data = gcry_sexp_nth_data (l2, 1, &datalen);
+          if (! data)
+            goto fail;
+          
+          snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
+          gcry_md_write (md, buf, strlen (buf));
+          gcry_md_write (md, data, datalen);
+          gcry_sexp_release (l2);
+          gcry_md_write (md, ")", 1);
+        }
+    }
+  
+  if (!array)
+    {
+      array = gcry_malloc (20);
+      if (! array)
+        goto fail;
+    }
+
+  memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
+  gcry_md_close (md);
+  gcry_sexp_release (list);
+  return array;
+
+ fail:
+  gcry_free (name);
+  gcry_sexp_release (l2);
+  gcry_md_close (md);
+  gcry_sexp_release (list);
+  return NULL;
+}
+
+
+gcry_error_t
+gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  switch (cmd)
+    {
+    case GCRYCTL_DISABLE_ALGO:
+      /* This one expects a buffer pointing to an integer with the
+         algo number.  */
+      if ((! buffer) || (buflen != sizeof (int)))
+       err = GPG_ERR_INV_ARG;
+      else
+       disable_pubkey_algo (*((int *) buffer));
+      break;
+
+    default:
+      err = GPG_ERR_INV_OP;
+    }
+
+  return gcry_error (err);
+}
+
+
+/* Return information about the given algorithm
+
+   WHAT selects the kind of information returned:
+
+    GCRYCTL_TEST_ALGO:
+        Returns 0 when the specified algorithm is available for use.
+        Buffer must be NULL, nbytes  may have the address of a variable
+        with the required usage of the algorithm. It may be 0 for don't
+        care or a combination of the GCRY_PK_USAGE_xxx flags;
+
+    GCRYCTL_GET_ALGO_USAGE:
+        Return the usage glafs for the give algo.  An invalid alog
+        does return 0.  Disabled algos are ignored here becuase we
+        only want to know whether the algo is at all capable of
+        the usage.
+  
+   Note: Because this function is in most cases used to return an
+   integer value, we can make it easier for the caller to just look at
+   the return value.  The caller will in all cases consult the value
+   and thereby detecting whether a error occured or not (i.e. while
+   checking the block size) */
+gcry_error_t
+gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+  switch (what)
+    {
+    case GCRYCTL_TEST_ALGO:
+      {
+       int use = nbytes ? *nbytes : 0;
+       if (buffer)
+         err = GPG_ERR_INV_ARG;
+       else if (check_pubkey_algo (algorithm, use))
+         err = GPG_ERR_PUBKEY_ALGO;
+       break;
+      }
+
+    case GCRYCTL_GET_ALGO_USAGE:
+      {
+       gcry_module_t pubkey;
+       int use = 0;
+
+       REGISTER_DEFAULT_PUBKEYS;
+
+       ath_mutex_lock (&pubkeys_registered_lock);
+       pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+       if (pubkey)
+         {
+           use = ((gcry_pk_spec_t *) pubkey->spec)->use;
+           _gcry_module_release (pubkey);
+         }
+       ath_mutex_unlock (&pubkeys_registered_lock);
+
+       /* FIXME? */
+       *nbytes = use;
+
+       break;
+      }
+
+    case GCRYCTL_GET_ALGO_NPKEY:
+      {
+       /* FIXME?  */
+       int npkey = pubkey_get_npkey (algorithm);
+       *nbytes = npkey;
+       break;
+      }
+    case GCRYCTL_GET_ALGO_NSKEY:
+      {
+       /* FIXME?  */
+       int nskey = pubkey_get_nskey (algorithm);
+       *nbytes = nskey;
+       break;
+      }
+    case GCRYCTL_GET_ALGO_NSIGN:
+      {
+       /* FIXME?  */
+       int nsign = pubkey_get_nsig (algorithm);
+       *nbytes = nsign;
+       break;
+      }
+    case GCRYCTL_GET_ALGO_NENCR:
+      {
+       /* FIXME?  */
+       int nencr = pubkey_get_nenc (algorithm);
+       *nbytes = nencr;
+       break;
+      }
+
+    default:
+      err = GPG_ERR_INV_OP;
+    }
+
+  return gcry_error (err);
+}
+
+
+/* Explicitly initialize this module.  */
+gcry_err_code_t
+_gcry_pk_init (void)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  return err;
+}
+
+
+gcry_err_code_t
+_gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_module_t pubkey;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+  if (pubkey)
+    *module = pubkey;
+  else
+    err = GPG_ERR_PUBKEY_ALGO;
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return err;
+}
+
+
+void
+_gcry_pk_module_release (gcry_module_t module)
+{
+  ath_mutex_lock (&pubkeys_registered_lock);
+  _gcry_module_release (module);
+  ath_mutex_unlock (&pubkeys_registered_lock);
+}
+
+/* Get a list consisting of the IDs of the loaded pubkey modules.  If
+   LIST is zero, write the number of loaded pubkey modules to
+   LIST_LENGTH and return.  If LIST is non-zero, the first
+   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+   according size.  In case there are less pubkey modules than
+   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
+gcry_error_t
+gcry_pk_list (int *list, int *list_length)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  err = _gcry_module_list (pubkeys_registered, list, list_length);
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return err;
+}
+
+
+/* Run the selftests for pubkey algorithm ALGO with optional reporting
+   function REPORT.  */
+gpg_error_t
+_gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
+{
+  gcry_module_t module = NULL;
+  pk_extra_spec_t *extraspec = NULL;
+  gcry_err_code_t ec = 0;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = _gcry_module_lookup_id (pubkeys_registered, algo);
+  if (module && !(module->flags & FLAG_MODULE_DISABLED))
+    extraspec = module->extraspec;
+  ath_mutex_unlock (&pubkeys_registered_lock);
+  if (extraspec && extraspec->selftest)
+    ec = extraspec->selftest (algo, extended, report);
+  else
+    {
+      ec = GPG_ERR_PUBKEY_ALGO;
+      if (report)
+        report ("pubkey", algo, "module", 
+                module && !(module->flags & FLAG_MODULE_DISABLED)?
+                "no selftest available" :
+                module? "algorithm disabled" : "algorithm not found");
+    }
+
+  if (module)
+    {
+      ath_mutex_lock (&pubkeys_registered_lock);
+      _gcry_module_release (module);
+      ath_mutex_unlock (&pubkeys_registered_lock);
+    }
+  return gpg_error (ec);
+}
+
+
+/* This function is only used by ac.c!  */
+gcry_err_code_t
+_gcry_pk_get_elements (int algo, char **enc, char **sig)
+{
+  gcry_module_t pubkey;
+  gcry_pk_spec_t *spec;
+  gcry_err_code_t err;
+  char *enc_cp;
+  char *sig_cp;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  enc_cp = NULL;
+  sig_cp = NULL;
+  spec = NULL;
+
+  pubkey = _gcry_module_lookup_id (pubkeys_registered, algo);
+  if (! pubkey)
+    {
+      err = GPG_ERR_INTERNAL;
+      goto out;
+    }
+  spec = pubkey->spec;
+
+  if (enc)
+    {
+      enc_cp = strdup (spec->elements_enc);
+      if (! enc_cp)
+       {
+         err = gpg_err_code_from_errno (errno);
+         goto out;
+       }
+    }
+  
+  if (sig)
+    {
+      sig_cp = strdup (spec->elements_sig);
+      if (! sig_cp)
+       {
+         err = gpg_err_code_from_errno (errno);
+         goto out;
+       }
+    }
+
+  if (enc)
+    *enc = enc_cp;
+  if (sig)
+    *sig = sig_cp;
+  err = 0;
+
+ out:
+
+  _gcry_module_release (pubkey);
+  if (err)
+    {
+      free (enc_cp);
+      free (sig_cp);
+    }
+
+  return err;
+}
diff --git a/grub-core/lib/libgcrypt/cipher/rfc2268.c b/grub-core/lib/libgcrypt/cipher/rfc2268.c
new file mode 100644 (file)
index 0000000..7d63fce
--- /dev/null
@@ -0,0 +1,345 @@
+/* rfc2268.c  - The cipher described in rfc2268; aka Ron's Cipher 2.
+ * Copyright (C) 2003 Nikos Mavroyanopoulos
+ * Copyright (C) 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* This implementation was written by Nikos Mavroyanopoulos for GNUTLS
+ * as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for
+ * direct use by Libgcrypt by Werner Koch.  This implementation is
+ * only useful for pkcs#12 descryption.
+ *
+ * The implementation here is based on Peter Gutmann's RRC.2 paper.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "g10lib.h"
+#include "types.h"
+#include "cipher.h"
+
+#define RFC2268_BLOCKSIZE 8
+
+typedef struct 
+{
+  u16 S[64];
+} RFC2268_context;
+
+static const unsigned char rfc2268_sbox[] = { 
+  217, 120, 249, 196,  25, 221, 181, 237, 
+   40, 233, 253, 121,  74, 160, 216, 157,
+  198, 126,  55, 131,  43, 118,  83, 142, 
+   98,  76, 100, 136,  68, 139, 251, 162,
+   23, 154,  89, 245, 135, 179,  79,  19,
+   97,  69, 109, 141,   9, 129, 125,  50,
+  189, 143,  64, 235, 134, 183, 123,  11,
+  240, 149,  33,  34,  92, 107,  78, 130,
+   84, 214, 101, 147, 206,  96, 178,  28,
+  115,  86, 192,  20, 167, 140, 241, 220,
+   18, 117, 202,  31,  59, 190, 228, 209,
+   66,  61, 212,  48, 163,  60, 182,  38,
+  111, 191,  14, 218,  70, 105,   7,  87,
+   39, 242,  29, 155, 188, 148,  67,   3,
+  248,  17, 199, 246, 144, 239,  62, 231,
+    6, 195, 213,  47, 200, 102,  30, 215,
+    8, 232, 234, 222, 128,  82, 238, 247,
+  132, 170, 114, 172,  53,  77, 106,  42,
+  150,  26, 210, 113,  90,  21,  73, 116,
+   75, 159, 208,  94,   4,  24, 164, 236,
+  194, 224,  65, 110,  15,  81, 203, 204,
+   36, 145, 175,  80, 161, 244, 112,  57,
+  153, 124,  58, 133,  35, 184, 180, 122,
+  252,   2,  54,  91,  37,  85, 151,  49,
+   45,  93, 250, 152, 227, 138, 146, 174,
+    5, 223,  41,  16, 103, 108, 186, 201,
+  211,   0, 230, 207, 225, 158, 168,  44,
+   99,  22,   1,  63,  88, 226, 137, 169,
+   13,  56,  52,  27, 171,  51, 255, 176,
+  187,  72,  12,  95, 185, 177, 205,  46,
+  197, 243, 219,  71, 229, 165, 156, 119,
+   10, 166,  32, 104, 254, 127, 193, 173
+};
+
+#define rotl16(x,n)   (((x) << ((u16)(n))) | ((x) >> (16 - (u16)(n))))
+#define rotr16(x,n)   (((x) >> ((u16)(n))) | ((x) << (16 - (u16)(n))))
+
+static const char *selftest (void);
+
+
+static void
+do_encrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
+{
+  RFC2268_context *ctx = context;
+  register int i, j;
+  u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
+
+  word0 = (word0 << 8) | inbuf[1];
+  word0 = (word0 << 8) | inbuf[0];
+  word1 = (word1 << 8) | inbuf[3];
+  word1 = (word1 << 8) | inbuf[2];
+  word2 = (word2 << 8) | inbuf[5];
+  word2 = (word2 << 8) | inbuf[4];
+  word3 = (word3 << 8) | inbuf[7];
+  word3 = (word3 << 8) | inbuf[6];
+
+  for (i = 0; i < 16; i++)
+    {
+      j = i * 4;
+      /* For some reason I cannot combine those steps. */
+      word0 += (word1 & ~word3) + (word2 & word3) + ctx->S[j];
+      word0 = rotl16(word0, 1);
+               
+      word1 += (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
+      word1 = rotl16(word1, 2);
+               
+      word2 += (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
+      word2 = rotl16(word2, 3);
+
+      word3 += (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
+      word3 = rotl16(word3, 5);
+
+      if (i == 4 || i == 10)
+        {
+          word0 += ctx->S[word3 & 63];
+          word1 += ctx->S[word0 & 63];
+          word2 += ctx->S[word1 & 63];
+          word3 += ctx->S[word2 & 63];
+        }
+
+    }
+
+  outbuf[0] = word0 & 255;
+  outbuf[1] = word0 >> 8;
+  outbuf[2] = word1 & 255;
+  outbuf[3] = word1 >> 8;
+  outbuf[4] = word2 & 255;
+  outbuf[5] = word2 >> 8;
+  outbuf[6] = word3 & 255;
+  outbuf[7] = word3 >> 8;
+}
+
+static void
+do_decrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
+{
+  RFC2268_context *ctx = context;
+  register int i, j;
+  u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
+
+  word0 = (word0 << 8) | inbuf[1];
+  word0 = (word0 << 8) | inbuf[0];
+  word1 = (word1 << 8) | inbuf[3];
+  word1 = (word1 << 8) | inbuf[2];
+  word2 = (word2 << 8) | inbuf[5];
+  word2 = (word2 << 8) | inbuf[4];
+  word3 = (word3 << 8) | inbuf[7];
+  word3 = (word3 << 8) | inbuf[6];
+
+  for (i = 15; i >= 0; i--) 
+    {
+      j = i * 4;
+
+      word3 = rotr16(word3, 5);
+      word3 -= (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
+
+      word2 = rotr16(word2, 3);
+      word2 -= (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
+
+      word1 = rotr16(word1, 2);
+      word1 -= (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
+
+      word0 = rotr16(word0, 1);
+      word0 -= (word1 & ~word3) + (word2 & word3) + ctx->S[j];
+
+      if (i == 5 || i == 11) 
+        {
+          word3 = word3 - ctx->S[word2 & 63];
+          word2 = word2 - ctx->S[word1 & 63];
+          word1 = word1 - ctx->S[word0 & 63];
+          word0 = word0 - ctx->S[word3 & 63];
+        }
+
+    }
+
+  outbuf[0] = word0 & 255;
+  outbuf[1] = word0 >> 8;
+  outbuf[2] = word1 & 255;
+  outbuf[3] = word1 >> 8;
+  outbuf[4] = word2 & 255;
+  outbuf[5] = word2 >> 8;
+  outbuf[6] = word3 & 255;
+  outbuf[7] = word3 >> 8;
+}
+
+
+static gpg_err_code_t
+setkey_core (void *context, const unsigned char *key, unsigned int keylen, int with_phase2)
+{
+  static int initialized;
+  static const char *selftest_failed;
+  RFC2268_context *ctx = context;
+  unsigned int i;
+  unsigned char *S, x;
+  int len;
+  int bits = keylen * 8;
+
+  if (!initialized)
+    {
+      initialized = 1;
+      selftest_failed = selftest ();
+      if (selftest_failed)
+        log_error ("RFC2268 selftest failed (%s).\n", selftest_failed);
+    }
+  if (selftest_failed)
+    return GPG_ERR_SELFTEST_FAILED;
+
+  if (keylen < 40 / 8) /* We want at least 40 bits. */
+    return GPG_ERR_INV_KEYLEN;
+
+  S = (unsigned char *) ctx->S;
+  
+  for (i = 0; i < keylen; i++)
+    S[i] = key[i];
+
+  for (i = keylen; i < 128; i++)
+    S[i] = rfc2268_sbox[(S[i - keylen] + S[i - 1]) & 255];
+
+  S[0] = rfc2268_sbox[S[0]];
+
+  /* Phase 2 - reduce effective key size to "bits". This was not
+   * discussed in Gutmann's paper. I've copied that from the public
+   * domain code posted in sci.crypt. */
+  if (with_phase2)
+    {
+      len = (bits + 7) >> 3;
+      i = 128 - len;
+      x = rfc2268_sbox[S[i] & (255 >> (7 & -bits))];
+      S[i] = x;
+      
+      while (i--) 
+        {
+          x = rfc2268_sbox[x ^ S[i + len]];
+          S[i] = x;
+        }
+    }
+
+  /* Make the expanded key, endian independent. */
+  for (i = 0; i < 64; i++) 
+    ctx->S[i] = ( (u16) S[i * 2] | (((u16) S[i * 2 + 1]) << 8));
+
+  return 0;
+}
+
+static gpg_err_code_t
+do_setkey (void *context, const unsigned char *key, unsigned int keylen)
+{
+  return setkey_core (context, key, keylen, 1);
+}
+
+static const char *
+selftest (void)
+{
+  RFC2268_context ctx;
+  unsigned char scratch[16];
+
+  /* Test vectors from Peter Gutmann's paper. */
+  static unsigned char key_1[] =
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+  static unsigned char plaintext_1[] =
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+  static const unsigned char ciphertext_1[] =
+    { 0x1C, 0x19, 0x8A, 0x83, 0x8D, 0xF0, 0x28, 0xB7 };
+
+  static unsigned char key_2[] =
+    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+      0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+    };
+  static unsigned char plaintext_2[] =
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+  static unsigned char ciphertext_2[] =
+    { 0x50, 0xDC, 0x01, 0x62, 0xBD, 0x75, 0x7F, 0x31 };
+
+  /* This one was checked against libmcrypt's RFC2268. */
+  static unsigned char key_3[] =
+    { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+  static unsigned char plaintext_3[] =
+    { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+  static unsigned char ciphertext_3[] =
+    { 0x8f, 0xd1, 0x03, 0x89, 0x33, 0x6b, 0xf9, 0x5e };
+
+
+  /* First test. */
+  setkey_core (&ctx, key_1, sizeof(key_1), 0);
+  do_encrypt (&ctx, scratch, plaintext_1);
+
+  if (memcmp (scratch, ciphertext_1, sizeof(ciphertext_1)))
+    return "RFC2268 encryption test 1 failed.";
+
+  setkey_core (&ctx, key_1, sizeof(key_1), 0);
+  do_decrypt (&ctx, scratch, scratch); 
+  if (memcmp (scratch, plaintext_1, sizeof(plaintext_1)))
+    return "RFC2268 decryption test 1 failed.";
+
+  /* Second test. */
+  setkey_core (&ctx, key_2, sizeof(key_2), 0);
+  do_encrypt (&ctx, scratch, plaintext_2);
+  if (memcmp (scratch, ciphertext_2, sizeof(ciphertext_2)))
+    return "RFC2268 encryption test 2 failed.";
+
+  setkey_core (&ctx, key_2, sizeof(key_2), 0);
+  do_decrypt (&ctx, scratch, scratch); 
+  if (memcmp (scratch, plaintext_2, sizeof(plaintext_2)))
+    return "RFC2268 decryption test 2 failed.";
+
+  /* Third test. */
+  setkey_core(&ctx, key_3, sizeof(key_3), 0);
+  do_encrypt(&ctx, scratch, plaintext_3);
+
+  if (memcmp(scratch, ciphertext_3, sizeof(ciphertext_3)))
+    return "RFC2268 encryption test 3 failed.";
+
+  setkey_core (&ctx, key_3, sizeof(key_3), 0);
+  do_decrypt (&ctx, scratch, scratch); 
+  if (memcmp(scratch, plaintext_3, sizeof(plaintext_3)))
+    return "RFC2268 decryption test 3 failed.";
+
+  return NULL;
+}
+
+
+
+static gcry_cipher_oid_spec_t oids_rfc2268_40[] =
+  {
+    /*{ "1.2.840.113549.3.2", GCRY_CIPHER_MODE_CBC },*/
+    /* pbeWithSHAAnd40BitRC2_CBC */
+    { "1.2.840.113549.1.12.1.6", GCRY_CIPHER_MODE_CBC },
+    { NULL }
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40 = {
+  "RFC2268_40", NULL, oids_rfc2268_40,
+  RFC2268_BLOCKSIZE, 40, sizeof(RFC2268_context),
+  do_setkey, do_encrypt, do_decrypt
+};
+
diff --git a/grub-core/lib/libgcrypt/cipher/rijndael-tables.h b/grub-core/lib/libgcrypt/cipher/rijndael-tables.h
new file mode 100644 (file)
index 0000000..c9b6d77
--- /dev/null
@@ -0,0 +1,1687 @@
+/* rijndael-tables.h - Rijndael (AES) for GnuPG, 
+ * Copyright (C) 2000, 2001, 2002, 2003, 2007,
+ *               2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* To keep the actual implementation at a readable size we use this
+   include file to define the tables.  */
+
+static const unsigned char S[256] = 
+  {
+     99, 124, 119, 123, 242, 107, 111, 197,
+     48,   1, 103,  43, 254, 215, 171, 118, 
+    202, 130, 201, 125, 250,  89,  71, 240,
+    173, 212, 162, 175, 156, 164, 114, 192, 
+    183, 253, 147,  38,  54,  63, 247, 204,
+     52, 165, 229, 241, 113, 216,  49,  21, 
+      4, 199,  35, 195,  24, 150,   5, 154,
+      7,  18, 128, 226, 235,  39, 178, 117, 
+      9, 131,  44,  26,  27, 110,  90, 160, 
+     82,  59, 214, 179,  41, 227,  47, 132, 
+     83, 209,   0, 237,  32, 252, 177,  91,
+    106, 203, 190,  57,  74,  76,  88, 207, 
+    208, 239, 170, 251,  67,  77,  51, 133,
+     69, 249,   2, 127,  80,  60, 159, 168, 
+     81, 163,  64, 143, 146, 157,  56, 245,
+    188, 182, 218,  33,  16, 255, 243, 210, 
+    205,  12,  19, 236,  95, 151,  68,  23,
+    196, 167, 126,  61, 100,  93,  25, 115, 
+     96, 129,  79, 220,  34,  42, 144, 136,
+     70, 238, 184,  20, 222,  94,  11, 219, 
+    224,  50,  58,  10,  73,   6,  36,  92,
+    194, 211, 172,  98, 145, 149, 228, 121, 
+    231, 200,  55, 109, 141, 213,  78, 169, 
+    108,  86, 244, 234, 101, 122, 174,   8, 
+    186, 120,  37,  46,  28, 166, 180, 198, 
+    232, 221, 116,  31,  75, 189, 139, 138, 
+    112,  62, 181, 102,  72,   3, 246,  14,
+     97,  53,  87, 185, 134, 193,  29, 158, 
+    225, 248, 152,  17, 105, 217, 142, 148,
+    155,  30, 135, 233, 206,  85,  40, 223, 
+    140, 161, 137,  13, 191, 230,  66, 104, 
+     65, 153,  45,  15, 176,  84, 187,  22
+  };
+
+
+static const unsigned char T1[256][4] = 
+  {
+    { 0xc6,0x63,0x63,0xa5 }, { 0xf8,0x7c,0x7c,0x84 },
+    { 0xee,0x77,0x77,0x99 }, { 0xf6,0x7b,0x7b,0x8d }, 
+    { 0xff,0xf2,0xf2,0x0d }, { 0xd6,0x6b,0x6b,0xbd },
+    { 0xde,0x6f,0x6f,0xb1 }, { 0x91,0xc5,0xc5,0x54 }, 
+    { 0x60,0x30,0x30,0x50 }, { 0x02,0x01,0x01,0x03 },
+    { 0xce,0x67,0x67,0xa9 }, { 0x56,0x2b,0x2b,0x7d }, 
+    { 0xe7,0xfe,0xfe,0x19 }, { 0xb5,0xd7,0xd7,0x62 },
+    { 0x4d,0xab,0xab,0xe6 }, { 0xec,0x76,0x76,0x9a }, 
+    { 0x8f,0xca,0xca,0x45 }, { 0x1f,0x82,0x82,0x9d },
+    { 0x89,0xc9,0xc9,0x40 }, { 0xfa,0x7d,0x7d,0x87 }, 
+    { 0xef,0xfa,0xfa,0x15 }, { 0xb2,0x59,0x59,0xeb }, 
+    { 0x8e,0x47,0x47,0xc9 }, { 0xfb,0xf0,0xf0,0x0b }, 
+    { 0x41,0xad,0xad,0xec }, { 0xb3,0xd4,0xd4,0x67 },
+    { 0x5f,0xa2,0xa2,0xfd }, { 0x45,0xaf,0xaf,0xea }, 
+    { 0x23,0x9c,0x9c,0xbf }, { 0x53,0xa4,0xa4,0xf7 },
+    { 0xe4,0x72,0x72,0x96 }, { 0x9b,0xc0,0xc0,0x5b }, 
+    { 0x75,0xb7,0xb7,0xc2 }, { 0xe1,0xfd,0xfd,0x1c },
+    { 0x3d,0x93,0x93,0xae }, { 0x4c,0x26,0x26,0x6a }, 
+    { 0x6c,0x36,0x36,0x5a }, { 0x7e,0x3f,0x3f,0x41 },
+    { 0xf5,0xf7,0xf7,0x02 }, { 0x83,0xcc,0xcc,0x4f }, 
+    { 0x68,0x34,0x34,0x5c }, { 0x51,0xa5,0xa5,0xf4 }, 
+    { 0xd1,0xe5,0xe5,0x34 }, { 0xf9,0xf1,0xf1,0x08 }, 
+    { 0xe2,0x71,0x71,0x93 }, { 0xab,0xd8,0xd8,0x73 },
+    { 0x62,0x31,0x31,0x53 }, { 0x2a,0x15,0x15,0x3f }, 
+    { 0x08,0x04,0x04,0x0c }, { 0x95,0xc7,0xc7,0x52 },
+    { 0x46,0x23,0x23,0x65 }, { 0x9d,0xc3,0xc3,0x5e }, 
+    { 0x30,0x18,0x18,0x28 }, { 0x37,0x96,0x96,0xa1 },
+    { 0x0a,0x05,0x05,0x0f }, { 0x2f,0x9a,0x9a,0xb5 }, 
+    { 0x0e,0x07,0x07,0x09 }, { 0x24,0x12,0x12,0x36 },
+    { 0x1b,0x80,0x80,0x9b }, { 0xdf,0xe2,0xe2,0x3d }, 
+    { 0xcd,0xeb,0xeb,0x26 }, { 0x4e,0x27,0x27,0x69 },
+    { 0x7f,0xb2,0xb2,0xcd }, { 0xea,0x75,0x75,0x9f }, 
+    { 0x12,0x09,0x09,0x1b }, { 0x1d,0x83,0x83,0x9e },
+    { 0x58,0x2c,0x2c,0x74 }, { 0x34,0x1a,0x1a,0x2e }, 
+    { 0x36,0x1b,0x1b,0x2d }, { 0xdc,0x6e,0x6e,0xb2 }, 
+    { 0xb4,0x5a,0x5a,0xee }, { 0x5b,0xa0,0xa0,0xfb }, 
+    { 0xa4,0x52,0x52,0xf6 }, { 0x76,0x3b,0x3b,0x4d },
+    { 0xb7,0xd6,0xd6,0x61 }, { 0x7d,0xb3,0xb3,0xce }, 
+    { 0x52,0x29,0x29,0x7b }, { 0xdd,0xe3,0xe3,0x3e }, 
+    { 0x5e,0x2f,0x2f,0x71 }, { 0x13,0x84,0x84,0x97 }, 
+    { 0xa6,0x53,0x53,0xf5 }, { 0xb9,0xd1,0xd1,0x68 }, 
+    { 0x00,0x00,0x00,0x00 }, { 0xc1,0xed,0xed,0x2c }, 
+    { 0x40,0x20,0x20,0x60 }, { 0xe3,0xfc,0xfc,0x1f },
+    { 0x79,0xb1,0xb1,0xc8 }, { 0xb6,0x5b,0x5b,0xed }, 
+    { 0xd4,0x6a,0x6a,0xbe }, { 0x8d,0xcb,0xcb,0x46 },
+    { 0x67,0xbe,0xbe,0xd9 }, { 0x72,0x39,0x39,0x4b }, 
+    { 0x94,0x4a,0x4a,0xde }, { 0x98,0x4c,0x4c,0xd4 },
+    { 0xb0,0x58,0x58,0xe8 }, { 0x85,0xcf,0xcf,0x4a }, 
+    { 0xbb,0xd0,0xd0,0x6b }, { 0xc5,0xef,0xef,0x2a },
+    { 0x4f,0xaa,0xaa,0xe5 }, { 0xed,0xfb,0xfb,0x16 }, 
+    { 0x86,0x43,0x43,0xc5 }, { 0x9a,0x4d,0x4d,0xd7 },
+    { 0x66,0x33,0x33,0x55 }, { 0x11,0x85,0x85,0x94 }, 
+    { 0x8a,0x45,0x45,0xcf }, { 0xe9,0xf9,0xf9,0x10 },
+    { 0x04,0x02,0x02,0x06 }, { 0xfe,0x7f,0x7f,0x81 }, 
+    { 0xa0,0x50,0x50,0xf0 }, { 0x78,0x3c,0x3c,0x44 },
+    { 0x25,0x9f,0x9f,0xba }, { 0x4b,0xa8,0xa8,0xe3 }, 
+    { 0xa2,0x51,0x51,0xf3 }, { 0x5d,0xa3,0xa3,0xfe },
+    { 0x80,0x40,0x40,0xc0 }, { 0x05,0x8f,0x8f,0x8a }, 
+    { 0x3f,0x92,0x92,0xad }, { 0x21,0x9d,0x9d,0xbc },
+    { 0x70,0x38,0x38,0x48 }, { 0xf1,0xf5,0xf5,0x04 }, 
+    { 0x63,0xbc,0xbc,0xdf }, { 0x77,0xb6,0xb6,0xc1 },
+    { 0xaf,0xda,0xda,0x75 }, { 0x42,0x21,0x21,0x63 }, 
+    { 0x20,0x10,0x10,0x30 }, { 0xe5,0xff,0xff,0x1a },
+    { 0xfd,0xf3,0xf3,0x0e }, { 0xbf,0xd2,0xd2,0x6d }, 
+    { 0x81,0xcd,0xcd,0x4c }, { 0x18,0x0c,0x0c,0x14 },
+    { 0x26,0x13,0x13,0x35 }, { 0xc3,0xec,0xec,0x2f }, 
+    { 0xbe,0x5f,0x5f,0xe1 }, { 0x35,0x97,0x97,0xa2 },
+    { 0x88,0x44,0x44,0xcc }, { 0x2e,0x17,0x17,0x39 }, 
+    { 0x93,0xc4,0xc4,0x57 }, { 0x55,0xa7,0xa7,0xf2 },
+    { 0xfc,0x7e,0x7e,0x82 }, { 0x7a,0x3d,0x3d,0x47 }, 
+    { 0xc8,0x64,0x64,0xac }, { 0xba,0x5d,0x5d,0xe7 },
+    { 0x32,0x19,0x19,0x2b }, { 0xe6,0x73,0x73,0x95 }, 
+    { 0xc0,0x60,0x60,0xa0 }, { 0x19,0x81,0x81,0x98 },
+    { 0x9e,0x4f,0x4f,0xd1 }, { 0xa3,0xdc,0xdc,0x7f }, 
+    { 0x44,0x22,0x22,0x66 }, { 0x54,0x2a,0x2a,0x7e },
+    { 0x3b,0x90,0x90,0xab }, { 0x0b,0x88,0x88,0x83 }, 
+    { 0x8c,0x46,0x46,0xca }, { 0xc7,0xee,0xee,0x29 },
+    { 0x6b,0xb8,0xb8,0xd3 }, { 0x28,0x14,0x14,0x3c }, 
+    { 0xa7,0xde,0xde,0x79 }, { 0xbc,0x5e,0x5e,0xe2 },
+    { 0x16,0x0b,0x0b,0x1d }, { 0xad,0xdb,0xdb,0x76 }, 
+    { 0xdb,0xe0,0xe0,0x3b }, { 0x64,0x32,0x32,0x56 },
+    { 0x74,0x3a,0x3a,0x4e }, { 0x14,0x0a,0x0a,0x1e }, 
+    { 0x92,0x49,0x49,0xdb }, { 0x0c,0x06,0x06,0x0a },
+    { 0x48,0x24,0x24,0x6c }, { 0xb8,0x5c,0x5c,0xe4 }, 
+    { 0x9f,0xc2,0xc2,0x5d }, { 0xbd,0xd3,0xd3,0x6e },
+    { 0x43,0xac,0xac,0xef }, { 0xc4,0x62,0x62,0xa6 }, 
+    { 0x39,0x91,0x91,0xa8 }, { 0x31,0x95,0x95,0xa4 },
+    { 0xd3,0xe4,0xe4,0x37 }, { 0xf2,0x79,0x79,0x8b }, 
+    { 0xd5,0xe7,0xe7,0x32 }, { 0x8b,0xc8,0xc8,0x43 },
+    { 0x6e,0x37,0x37,0x59 }, { 0xda,0x6d,0x6d,0xb7 }, 
+    { 0x01,0x8d,0x8d,0x8c }, { 0xb1,0xd5,0xd5,0x64 },
+    { 0x9c,0x4e,0x4e,0xd2 }, { 0x49,0xa9,0xa9,0xe0 }, 
+    { 0xd8,0x6c,0x6c,0xb4 }, { 0xac,0x56,0x56,0xfa },
+    { 0xf3,0xf4,0xf4,0x07 }, { 0xcf,0xea,0xea,0x25 }, 
+    { 0xca,0x65,0x65,0xaf }, { 0xf4,0x7a,0x7a,0x8e },
+    { 0x47,0xae,0xae,0xe9 }, { 0x10,0x08,0x08,0x18 }, 
+    { 0x6f,0xba,0xba,0xd5 }, { 0xf0,0x78,0x78,0x88 },
+    { 0x4a,0x25,0x25,0x6f }, { 0x5c,0x2e,0x2e,0x72 }, 
+    { 0x38,0x1c,0x1c,0x24 }, { 0x57,0xa6,0xa6,0xf1 },
+    { 0x73,0xb4,0xb4,0xc7 }, { 0x97,0xc6,0xc6,0x51 }, 
+    { 0xcb,0xe8,0xe8,0x23 }, { 0xa1,0xdd,0xdd,0x7c },
+    { 0xe8,0x74,0x74,0x9c }, { 0x3e,0x1f,0x1f,0x21 }, 
+    { 0x96,0x4b,0x4b,0xdd }, { 0x61,0xbd,0xbd,0xdc }, 
+    { 0x0d,0x8b,0x8b,0x86 }, { 0x0f,0x8a,0x8a,0x85 }, 
+    { 0xe0,0x70,0x70,0x90 }, { 0x7c,0x3e,0x3e,0x42 },
+    { 0x71,0xb5,0xb5,0xc4 }, { 0xcc,0x66,0x66,0xaa }, 
+    { 0x90,0x48,0x48,0xd8 }, { 0x06,0x03,0x03,0x05 },
+    { 0xf7,0xf6,0xf6,0x01 }, { 0x1c,0x0e,0x0e,0x12 }, 
+    { 0xc2,0x61,0x61,0xa3 }, { 0x6a,0x35,0x35,0x5f },
+    { 0xae,0x57,0x57,0xf9 }, { 0x69,0xb9,0xb9,0xd0 }, 
+    { 0x17,0x86,0x86,0x91 }, { 0x99,0xc1,0xc1,0x58 },
+    { 0x3a,0x1d,0x1d,0x27 }, { 0x27,0x9e,0x9e,0xb9 }, 
+    { 0xd9,0xe1,0xe1,0x38 }, { 0xeb,0xf8,0xf8,0x13 },
+    { 0x2b,0x98,0x98,0xb3 }, { 0x22,0x11,0x11,0x33 }, 
+    { 0xd2,0x69,0x69,0xbb }, { 0xa9,0xd9,0xd9,0x70 },
+    { 0x07,0x8e,0x8e,0x89 }, { 0x33,0x94,0x94,0xa7 }, 
+    { 0x2d,0x9b,0x9b,0xb6 }, { 0x3c,0x1e,0x1e,0x22 },
+    { 0x15,0x87,0x87,0x92 }, { 0xc9,0xe9,0xe9,0x20 }, 
+    { 0x87,0xce,0xce,0x49 }, { 0xaa,0x55,0x55,0xff },
+    { 0x50,0x28,0x28,0x78 }, { 0xa5,0xdf,0xdf,0x7a }, 
+    { 0x03,0x8c,0x8c,0x8f }, { 0x59,0xa1,0xa1,0xf8 },
+    { 0x09,0x89,0x89,0x80 }, { 0x1a,0x0d,0x0d,0x17 }, 
+    { 0x65,0xbf,0xbf,0xda }, { 0xd7,0xe6,0xe6,0x31 },
+    { 0x84,0x42,0x42,0xc6 }, { 0xd0,0x68,0x68,0xb8 }, 
+    { 0x82,0x41,0x41,0xc3 }, { 0x29,0x99,0x99,0xb0 },
+    { 0x5a,0x2d,0x2d,0x77 }, { 0x1e,0x0f,0x0f,0x11 }, 
+    { 0x7b,0xb0,0xb0,0xcb }, { 0xa8,0x54,0x54,0xfc },
+    { 0x6d,0xbb,0xbb,0xd6 }, { 0x2c,0x16,0x16,0x3a }
+  };
+
+static const unsigned char T2[256][4] = 
+  {
+    { 0xa5,0xc6,0x63,0x63 }, { 0x84,0xf8,0x7c,0x7c },
+    { 0x99,0xee,0x77,0x77 }, { 0x8d,0xf6,0x7b,0x7b }, 
+    { 0x0d,0xff,0xf2,0xf2 }, { 0xbd,0xd6,0x6b,0x6b },
+    { 0xb1,0xde,0x6f,0x6f }, { 0x54,0x91,0xc5,0xc5 }, 
+    { 0x50,0x60,0x30,0x30 }, { 0x03,0x02,0x01,0x01 },
+    { 0xa9,0xce,0x67,0x67 }, { 0x7d,0x56,0x2b,0x2b }, 
+    { 0x19,0xe7,0xfe,0xfe }, { 0x62,0xb5,0xd7,0xd7 }, 
+    { 0xe6,0x4d,0xab,0xab }, { 0x9a,0xec,0x76,0x76 }, 
+    { 0x45,0x8f,0xca,0xca }, { 0x9d,0x1f,0x82,0x82 }, 
+    { 0x40,0x89,0xc9,0xc9 }, { 0x87,0xfa,0x7d,0x7d }, 
+    { 0x15,0xef,0xfa,0xfa }, { 0xeb,0xb2,0x59,0x59 }, 
+    { 0xc9,0x8e,0x47,0x47 }, { 0x0b,0xfb,0xf0,0xf0 }, 
+    { 0xec,0x41,0xad,0xad }, { 0x67,0xb3,0xd4,0xd4 }, 
+    { 0xfd,0x5f,0xa2,0xa2 }, { 0xea,0x45,0xaf,0xaf }, 
+    { 0xbf,0x23,0x9c,0x9c }, { 0xf7,0x53,0xa4,0xa4 }, 
+    { 0x96,0xe4,0x72,0x72 }, { 0x5b,0x9b,0xc0,0xc0 }, 
+    { 0xc2,0x75,0xb7,0xb7 }, { 0x1c,0xe1,0xfd,0xfd }, 
+    { 0xae,0x3d,0x93,0x93 }, { 0x6a,0x4c,0x26,0x26 }, 
+    { 0x5a,0x6c,0x36,0x36 }, { 0x41,0x7e,0x3f,0x3f },
+    { 0x02,0xf5,0xf7,0xf7 }, { 0x4f,0x83,0xcc,0xcc }, 
+    { 0x5c,0x68,0x34,0x34 }, { 0xf4,0x51,0xa5,0xa5 },
+    { 0x34,0xd1,0xe5,0xe5 }, { 0x08,0xf9,0xf1,0xf1 }, 
+    { 0x93,0xe2,0x71,0x71 }, { 0x73,0xab,0xd8,0xd8 },
+    { 0x53,0x62,0x31,0x31 }, { 0x3f,0x2a,0x15,0x15 }, 
+    { 0x0c,0x08,0x04,0x04 }, { 0x52,0x95,0xc7,0xc7 }, 
+    { 0x65,0x46,0x23,0x23 }, { 0x5e,0x9d,0xc3,0xc3 }, 
+    { 0x28,0x30,0x18,0x18 }, { 0xa1,0x37,0x96,0x96 }, 
+    { 0x0f,0x0a,0x05,0x05 }, { 0xb5,0x2f,0x9a,0x9a }, 
+    { 0x09,0x0e,0x07,0x07 }, { 0x36,0x24,0x12,0x12 },
+    { 0x9b,0x1b,0x80,0x80 }, { 0x3d,0xdf,0xe2,0xe2 }, 
+    { 0x26,0xcd,0xeb,0xeb }, { 0x69,0x4e,0x27,0x27 }, 
+    { 0xcd,0x7f,0xb2,0xb2 }, { 0x9f,0xea,0x75,0x75 }, 
+    { 0x1b,0x12,0x09,0x09 }, { 0x9e,0x1d,0x83,0x83 },
+    { 0x74,0x58,0x2c,0x2c }, { 0x2e,0x34,0x1a,0x1a }, 
+    { 0x2d,0x36,0x1b,0x1b }, { 0xb2,0xdc,0x6e,0x6e },
+    { 0xee,0xb4,0x5a,0x5a }, { 0xfb,0x5b,0xa0,0xa0 }, 
+    { 0xf6,0xa4,0x52,0x52 }, { 0x4d,0x76,0x3b,0x3b },
+    { 0x61,0xb7,0xd6,0xd6 }, { 0xce,0x7d,0xb3,0xb3 }, 
+    { 0x7b,0x52,0x29,0x29 }, { 0x3e,0xdd,0xe3,0xe3 }, 
+    { 0x71,0x5e,0x2f,0x2f }, { 0x97,0x13,0x84,0x84 }, 
+    { 0xf5,0xa6,0x53,0x53 }, { 0x68,0xb9,0xd1,0xd1 }, 
+    { 0x00,0x00,0x00,0x00 }, { 0x2c,0xc1,0xed,0xed }, 
+    { 0x60,0x40,0x20,0x20 }, { 0x1f,0xe3,0xfc,0xfc }, 
+    { 0xc8,0x79,0xb1,0xb1 }, { 0xed,0xb6,0x5b,0x5b }, 
+    { 0xbe,0xd4,0x6a,0x6a }, { 0x46,0x8d,0xcb,0xcb }, 
+    { 0xd9,0x67,0xbe,0xbe }, { 0x4b,0x72,0x39,0x39 }, 
+    { 0xde,0x94,0x4a,0x4a }, { 0xd4,0x98,0x4c,0x4c }, 
+    { 0xe8,0xb0,0x58,0x58 }, { 0x4a,0x85,0xcf,0xcf }, 
+    { 0x6b,0xbb,0xd0,0xd0 }, { 0x2a,0xc5,0xef,0xef },
+    { 0xe5,0x4f,0xaa,0xaa }, { 0x16,0xed,0xfb,0xfb }, 
+    { 0xc5,0x86,0x43,0x43 }, { 0xd7,0x9a,0x4d,0x4d }, 
+    { 0x55,0x66,0x33,0x33 }, { 0x94,0x11,0x85,0x85 }, 
+    { 0xcf,0x8a,0x45,0x45 }, { 0x10,0xe9,0xf9,0xf9 }, 
+    { 0x06,0x04,0x02,0x02 }, { 0x81,0xfe,0x7f,0x7f }, 
+    { 0xf0,0xa0,0x50,0x50 }, { 0x44,0x78,0x3c,0x3c },
+    { 0xba,0x25,0x9f,0x9f }, { 0xe3,0x4b,0xa8,0xa8 }, 
+    { 0xf3,0xa2,0x51,0x51 }, { 0xfe,0x5d,0xa3,0xa3 },
+    { 0xc0,0x80,0x40,0x40 }, { 0x8a,0x05,0x8f,0x8f }, 
+    { 0xad,0x3f,0x92,0x92 }, { 0xbc,0x21,0x9d,0x9d },
+    { 0x48,0x70,0x38,0x38 }, { 0x04,0xf1,0xf5,0xf5 }, 
+    { 0xdf,0x63,0xbc,0xbc }, { 0xc1,0x77,0xb6,0xb6 },
+    { 0x75,0xaf,0xda,0xda }, { 0x63,0x42,0x21,0x21 }, 
+    { 0x30,0x20,0x10,0x10 }, { 0x1a,0xe5,0xff,0xff },
+    { 0x0e,0xfd,0xf3,0xf3 }, { 0x6d,0xbf,0xd2,0xd2 }, 
+    { 0x4c,0x81,0xcd,0xcd }, { 0x14,0x18,0x0c,0x0c },
+    { 0x35,0x26,0x13,0x13 }, { 0x2f,0xc3,0xec,0xec }, 
+    { 0xe1,0xbe,0x5f,0x5f }, { 0xa2,0x35,0x97,0x97 },
+    { 0xcc,0x88,0x44,0x44 }, { 0x39,0x2e,0x17,0x17 }, 
+    { 0x57,0x93,0xc4,0xc4 }, { 0xf2,0x55,0xa7,0xa7 },
+    { 0x82,0xfc,0x7e,0x7e }, { 0x47,0x7a,0x3d,0x3d }, 
+    { 0xac,0xc8,0x64,0x64 }, { 0xe7,0xba,0x5d,0x5d },
+    { 0x2b,0x32,0x19,0x19 }, { 0x95,0xe6,0x73,0x73 }, 
+    { 0xa0,0xc0,0x60,0x60 }, { 0x98,0x19,0x81,0x81 }, 
+    { 0xd1,0x9e,0x4f,0x4f }, { 0x7f,0xa3,0xdc,0xdc }, 
+    { 0x66,0x44,0x22,0x22 }, { 0x7e,0x54,0x2a,0x2a }, 
+    { 0xab,0x3b,0x90,0x90 }, { 0x83,0x0b,0x88,0x88 }, 
+    { 0xca,0x8c,0x46,0x46 }, { 0x29,0xc7,0xee,0xee },
+    { 0xd3,0x6b,0xb8,0xb8 }, { 0x3c,0x28,0x14,0x14 }, 
+    { 0x79,0xa7,0xde,0xde }, { 0xe2,0xbc,0x5e,0x5e },
+    { 0x1d,0x16,0x0b,0x0b }, { 0x76,0xad,0xdb,0xdb }, 
+    { 0x3b,0xdb,0xe0,0xe0 }, { 0x56,0x64,0x32,0x32 },
+    { 0x4e,0x74,0x3a,0x3a }, { 0x1e,0x14,0x0a,0x0a }, 
+    { 0xdb,0x92,0x49,0x49 }, { 0x0a,0x0c,0x06,0x06 },
+    { 0x6c,0x48,0x24,0x24 }, { 0xe4,0xb8,0x5c,0x5c }, 
+    { 0x5d,0x9f,0xc2,0xc2 }, { 0x6e,0xbd,0xd3,0xd3 }, 
+    { 0xef,0x43,0xac,0xac }, { 0xa6,0xc4,0x62,0x62 }, 
+    { 0xa8,0x39,0x91,0x91 }, { 0xa4,0x31,0x95,0x95 },
+    { 0x37,0xd3,0xe4,0xe4 }, { 0x8b,0xf2,0x79,0x79 }, 
+    { 0x32,0xd5,0xe7,0xe7 }, { 0x43,0x8b,0xc8,0xc8 },
+    { 0x59,0x6e,0x37,0x37 }, { 0xb7,0xda,0x6d,0x6d }, 
+    { 0x8c,0x01,0x8d,0x8d }, { 0x64,0xb1,0xd5,0xd5 },
+    { 0xd2,0x9c,0x4e,0x4e }, { 0xe0,0x49,0xa9,0xa9 }, 
+    { 0xb4,0xd8,0x6c,0x6c }, { 0xfa,0xac,0x56,0x56 },
+    { 0x07,0xf3,0xf4,0xf4 }, { 0x25,0xcf,0xea,0xea }, 
+    { 0xaf,0xca,0x65,0x65 }, { 0x8e,0xf4,0x7a,0x7a },
+    { 0xe9,0x47,0xae,0xae }, { 0x18,0x10,0x08,0x08 }, 
+    { 0xd5,0x6f,0xba,0xba }, { 0x88,0xf0,0x78,0x78 }, 
+    { 0x6f,0x4a,0x25,0x25 }, { 0x72,0x5c,0x2e,0x2e }, 
+    { 0x24,0x38,0x1c,0x1c }, { 0xf1,0x57,0xa6,0xa6 }, 
+    { 0xc7,0x73,0xb4,0xb4 }, { 0x51,0x97,0xc6,0xc6 }, 
+    { 0x23,0xcb,0xe8,0xe8 }, { 0x7c,0xa1,0xdd,0xdd },
+    { 0x9c,0xe8,0x74,0x74 }, { 0x21,0x3e,0x1f,0x1f }, 
+    { 0xdd,0x96,0x4b,0x4b }, { 0xdc,0x61,0xbd,0xbd },
+    { 0x86,0x0d,0x8b,0x8b }, { 0x85,0x0f,0x8a,0x8a }, 
+    { 0x90,0xe0,0x70,0x70 }, { 0x42,0x7c,0x3e,0x3e }, 
+    { 0xc4,0x71,0xb5,0xb5 }, { 0xaa,0xcc,0x66,0x66 }, 
+    { 0xd8,0x90,0x48,0x48 }, { 0x05,0x06,0x03,0x03 },
+    { 0x01,0xf7,0xf6,0xf6 }, { 0x12,0x1c,0x0e,0x0e }, 
+    { 0xa3,0xc2,0x61,0x61 }, { 0x5f,0x6a,0x35,0x35 },
+    { 0xf9,0xae,0x57,0x57 }, { 0xd0,0x69,0xb9,0xb9 }, 
+    { 0x91,0x17,0x86,0x86 }, { 0x58,0x99,0xc1,0xc1 }, 
+    { 0x27,0x3a,0x1d,0x1d }, { 0xb9,0x27,0x9e,0x9e }, 
+    { 0x38,0xd9,0xe1,0xe1 }, { 0x13,0xeb,0xf8,0xf8 },
+    { 0xb3,0x2b,0x98,0x98 }, { 0x33,0x22,0x11,0x11 }, 
+    { 0xbb,0xd2,0x69,0x69 }, { 0x70,0xa9,0xd9,0xd9 },
+    { 0x89,0x07,0x8e,0x8e }, { 0xa7,0x33,0x94,0x94 }, 
+    { 0xb6,0x2d,0x9b,0x9b }, { 0x22,0x3c,0x1e,0x1e },
+    { 0x92,0x15,0x87,0x87 }, { 0x20,0xc9,0xe9,0xe9 }, 
+    { 0x49,0x87,0xce,0xce }, { 0xff,0xaa,0x55,0x55 },
+    { 0x78,0x50,0x28,0x28 }, { 0x7a,0xa5,0xdf,0xdf }, 
+    { 0x8f,0x03,0x8c,0x8c }, { 0xf8,0x59,0xa1,0xa1 }, 
+    { 0x80,0x09,0x89,0x89 }, { 0x17,0x1a,0x0d,0x0d }, 
+    { 0xda,0x65,0xbf,0xbf }, { 0x31,0xd7,0xe6,0xe6 },
+    { 0xc6,0x84,0x42,0x42 }, { 0xb8,0xd0,0x68,0x68 }, 
+    { 0xc3,0x82,0x41,0x41 }, { 0xb0,0x29,0x99,0x99 }, 
+    { 0x77,0x5a,0x2d,0x2d }, { 0x11,0x1e,0x0f,0x0f }, 
+    { 0xcb,0x7b,0xb0,0xb0 }, { 0xfc,0xa8,0x54,0x54 }, 
+    { 0xd6,0x6d,0xbb,0xbb }, { 0x3a,0x2c,0x16,0x16 }
+  };
+
+static const unsigned char T3[256][4] = 
+  {
+    { 0x63,0xa5,0xc6,0x63 }, { 0x7c,0x84,0xf8,0x7c },
+    { 0x77,0x99,0xee,0x77 }, { 0x7b,0x8d,0xf6,0x7b }, 
+    { 0xf2,0x0d,0xff,0xf2 }, { 0x6b,0xbd,0xd6,0x6b },
+    { 0x6f,0xb1,0xde,0x6f }, { 0xc5,0x54,0x91,0xc5 }, 
+    { 0x30,0x50,0x60,0x30 }, { 0x01,0x03,0x02,0x01 },
+    { 0x67,0xa9,0xce,0x67 }, { 0x2b,0x7d,0x56,0x2b }, 
+    { 0xfe,0x19,0xe7,0xfe }, { 0xd7,0x62,0xb5,0xd7 }, 
+    { 0xab,0xe6,0x4d,0xab }, { 0x76,0x9a,0xec,0x76 }, 
+    { 0xca,0x45,0x8f,0xca }, { 0x82,0x9d,0x1f,0x82 },
+    { 0xc9,0x40,0x89,0xc9 }, { 0x7d,0x87,0xfa,0x7d }, 
+    { 0xfa,0x15,0xef,0xfa }, { 0x59,0xeb,0xb2,0x59 }, 
+    { 0x47,0xc9,0x8e,0x47 }, { 0xf0,0x0b,0xfb,0xf0 }, 
+    { 0xad,0xec,0x41,0xad }, { 0xd4,0x67,0xb3,0xd4 }, 
+    { 0xa2,0xfd,0x5f,0xa2 }, { 0xaf,0xea,0x45,0xaf }, 
+    { 0x9c,0xbf,0x23,0x9c }, { 0xa4,0xf7,0x53,0xa4 },
+    { 0x72,0x96,0xe4,0x72 }, { 0xc0,0x5b,0x9b,0xc0 }, 
+    { 0xb7,0xc2,0x75,0xb7 }, { 0xfd,0x1c,0xe1,0xfd }, 
+    { 0x93,0xae,0x3d,0x93 }, { 0x26,0x6a,0x4c,0x26 }, 
+    { 0x36,0x5a,0x6c,0x36 }, { 0x3f,0x41,0x7e,0x3f },
+    { 0xf7,0x02,0xf5,0xf7 }, { 0xcc,0x4f,0x83,0xcc }, 
+    { 0x34,0x5c,0x68,0x34 }, { 0xa5,0xf4,0x51,0xa5 },
+    { 0xe5,0x34,0xd1,0xe5 }, { 0xf1,0x08,0xf9,0xf1 }, 
+    { 0x71,0x93,0xe2,0x71 }, { 0xd8,0x73,0xab,0xd8 },
+    { 0x31,0x53,0x62,0x31 }, { 0x15,0x3f,0x2a,0x15 }, 
+    { 0x04,0x0c,0x08,0x04 }, { 0xc7,0x52,0x95,0xc7 }, 
+    { 0x23,0x65,0x46,0x23 }, { 0xc3,0x5e,0x9d,0xc3 }, 
+    { 0x18,0x28,0x30,0x18 }, { 0x96,0xa1,0x37,0x96 },
+    { 0x05,0x0f,0x0a,0x05 }, { 0x9a,0xb5,0x2f,0x9a }, 
+    { 0x07,0x09,0x0e,0x07 }, { 0x12,0x36,0x24,0x12 }, 
+    { 0x80,0x9b,0x1b,0x80 }, { 0xe2,0x3d,0xdf,0xe2 }, 
+    { 0xeb,0x26,0xcd,0xeb }, { 0x27,0x69,0x4e,0x27 },
+    { 0xb2,0xcd,0x7f,0xb2 }, { 0x75,0x9f,0xea,0x75 }, 
+    { 0x09,0x1b,0x12,0x09 }, { 0x83,0x9e,0x1d,0x83 },
+    { 0x2c,0x74,0x58,0x2c }, { 0x1a,0x2e,0x34,0x1a }, 
+    { 0x1b,0x2d,0x36,0x1b }, { 0x6e,0xb2,0xdc,0x6e },
+    { 0x5a,0xee,0xb4,0x5a }, { 0xa0,0xfb,0x5b,0xa0 }, 
+    { 0x52,0xf6,0xa4,0x52 }, { 0x3b,0x4d,0x76,0x3b },
+    { 0xd6,0x61,0xb7,0xd6 }, { 0xb3,0xce,0x7d,0xb3 }, 
+    { 0x29,0x7b,0x52,0x29 }, { 0xe3,0x3e,0xdd,0xe3 }, 
+    { 0x2f,0x71,0x5e,0x2f }, { 0x84,0x97,0x13,0x84 }, 
+    { 0x53,0xf5,0xa6,0x53 }, { 0xd1,0x68,0xb9,0xd1 },
+    { 0x00,0x00,0x00,0x00 }, { 0xed,0x2c,0xc1,0xed }, 
+    { 0x20,0x60,0x40,0x20 }, { 0xfc,0x1f,0xe3,0xfc },
+    { 0xb1,0xc8,0x79,0xb1 }, { 0x5b,0xed,0xb6,0x5b }, 
+    { 0x6a,0xbe,0xd4,0x6a }, { 0xcb,0x46,0x8d,0xcb },
+    { 0xbe,0xd9,0x67,0xbe }, { 0x39,0x4b,0x72,0x39 }, 
+    { 0x4a,0xde,0x94,0x4a }, { 0x4c,0xd4,0x98,0x4c },
+    { 0x58,0xe8,0xb0,0x58 }, { 0xcf,0x4a,0x85,0xcf }, 
+    { 0xd0,0x6b,0xbb,0xd0 }, { 0xef,0x2a,0xc5,0xef },
+    { 0xaa,0xe5,0x4f,0xaa }, { 0xfb,0x16,0xed,0xfb }, 
+    { 0x43,0xc5,0x86,0x43 }, { 0x4d,0xd7,0x9a,0x4d },
+    { 0x33,0x55,0x66,0x33 }, { 0x85,0x94,0x11,0x85 }, 
+    { 0x45,0xcf,0x8a,0x45 }, { 0xf9,0x10,0xe9,0xf9 },
+    { 0x02,0x06,0x04,0x02 }, { 0x7f,0x81,0xfe,0x7f }, 
+    { 0x50,0xf0,0xa0,0x50 }, { 0x3c,0x44,0x78,0x3c },
+    { 0x9f,0xba,0x25,0x9f }, { 0xa8,0xe3,0x4b,0xa8 }, 
+    { 0x51,0xf3,0xa2,0x51 }, { 0xa3,0xfe,0x5d,0xa3 },
+    { 0x40,0xc0,0x80,0x40 }, { 0x8f,0x8a,0x05,0x8f }, 
+    { 0x92,0xad,0x3f,0x92 }, { 0x9d,0xbc,0x21,0x9d },
+    { 0x38,0x48,0x70,0x38 }, { 0xf5,0x04,0xf1,0xf5 }, 
+    { 0xbc,0xdf,0x63,0xbc }, { 0xb6,0xc1,0x77,0xb6 },
+    { 0xda,0x75,0xaf,0xda }, { 0x21,0x63,0x42,0x21 }, 
+    { 0x10,0x30,0x20,0x10 }, { 0xff,0x1a,0xe5,0xff },
+    { 0xf3,0x0e,0xfd,0xf3 }, { 0xd2,0x6d,0xbf,0xd2 }, 
+    { 0xcd,0x4c,0x81,0xcd }, { 0x0c,0x14,0x18,0x0c }, 
+    { 0x13,0x35,0x26,0x13 }, { 0xec,0x2f,0xc3,0xec }, 
+    { 0x5f,0xe1,0xbe,0x5f }, { 0x97,0xa2,0x35,0x97 },
+    { 0x44,0xcc,0x88,0x44 }, { 0x17,0x39,0x2e,0x17 }, 
+    { 0xc4,0x57,0x93,0xc4 }, { 0xa7,0xf2,0x55,0xa7 },
+    { 0x7e,0x82,0xfc,0x7e }, { 0x3d,0x47,0x7a,0x3d }, 
+    { 0x64,0xac,0xc8,0x64 }, { 0x5d,0xe7,0xba,0x5d },
+    { 0x19,0x2b,0x32,0x19 }, { 0x73,0x95,0xe6,0x73 }, 
+    { 0x60,0xa0,0xc0,0x60 }, { 0x81,0x98,0x19,0x81 },
+    { 0x4f,0xd1,0x9e,0x4f }, { 0xdc,0x7f,0xa3,0xdc }, 
+    { 0x22,0x66,0x44,0x22 }, { 0x2a,0x7e,0x54,0x2a },
+    { 0x90,0xab,0x3b,0x90 }, { 0x88,0x83,0x0b,0x88 }, 
+    { 0x46,0xca,0x8c,0x46 }, { 0xee,0x29,0xc7,0xee },
+    { 0xb8,0xd3,0x6b,0xb8 }, { 0x14,0x3c,0x28,0x14 }, 
+    { 0xde,0x79,0xa7,0xde }, { 0x5e,0xe2,0xbc,0x5e }, 
+    { 0x0b,0x1d,0x16,0x0b }, { 0xdb,0x76,0xad,0xdb }, 
+    { 0xe0,0x3b,0xdb,0xe0 }, { 0x32,0x56,0x64,0x32 },
+    { 0x3a,0x4e,0x74,0x3a }, { 0x0a,0x1e,0x14,0x0a }, 
+    { 0x49,0xdb,0x92,0x49 }, { 0x06,0x0a,0x0c,0x06 },
+    { 0x24,0x6c,0x48,0x24 }, { 0x5c,0xe4,0xb8,0x5c }, 
+    { 0xc2,0x5d,0x9f,0xc2 }, { 0xd3,0x6e,0xbd,0xd3 },
+    { 0xac,0xef,0x43,0xac }, { 0x62,0xa6,0xc4,0x62 }, 
+    { 0x91,0xa8,0x39,0x91 }, { 0x95,0xa4,0x31,0x95 },
+    { 0xe4,0x37,0xd3,0xe4 }, { 0x79,0x8b,0xf2,0x79 }, 
+    { 0xe7,0x32,0xd5,0xe7 }, { 0xc8,0x43,0x8b,0xc8 }, 
+    { 0x37,0x59,0x6e,0x37 }, { 0x6d,0xb7,0xda,0x6d }, 
+    { 0x8d,0x8c,0x01,0x8d }, { 0xd5,0x64,0xb1,0xd5 }, 
+    { 0x4e,0xd2,0x9c,0x4e }, { 0xa9,0xe0,0x49,0xa9 }, 
+    { 0x6c,0xb4,0xd8,0x6c }, { 0x56,0xfa,0xac,0x56 },
+    { 0xf4,0x07,0xf3,0xf4 }, { 0xea,0x25,0xcf,0xea }, 
+    { 0x65,0xaf,0xca,0x65 }, { 0x7a,0x8e,0xf4,0x7a }, 
+    { 0xae,0xe9,0x47,0xae }, { 0x08,0x18,0x10,0x08 }, 
+    { 0xba,0xd5,0x6f,0xba }, { 0x78,0x88,0xf0,0x78 }, 
+    { 0x25,0x6f,0x4a,0x25 }, { 0x2e,0x72,0x5c,0x2e }, 
+    { 0x1c,0x24,0x38,0x1c }, { 0xa6,0xf1,0x57,0xa6 }, 
+    { 0xb4,0xc7,0x73,0xb4 }, { 0xc6,0x51,0x97,0xc6 }, 
+    { 0xe8,0x23,0xcb,0xe8 }, { 0xdd,0x7c,0xa1,0xdd },
+    { 0x74,0x9c,0xe8,0x74 }, { 0x1f,0x21,0x3e,0x1f }, 
+    { 0x4b,0xdd,0x96,0x4b }, { 0xbd,0xdc,0x61,0xbd },
+    { 0x8b,0x86,0x0d,0x8b }, { 0x8a,0x85,0x0f,0x8a }, 
+    { 0x70,0x90,0xe0,0x70 }, { 0x3e,0x42,0x7c,0x3e },
+    { 0xb5,0xc4,0x71,0xb5 }, { 0x66,0xaa,0xcc,0x66 }, 
+    { 0x48,0xd8,0x90,0x48 }, { 0x03,0x05,0x06,0x03 },
+    { 0xf6,0x01,0xf7,0xf6 }, { 0x0e,0x12,0x1c,0x0e }, 
+    { 0x61,0xa3,0xc2,0x61 }, { 0x35,0x5f,0x6a,0x35 },
+    { 0x57,0xf9,0xae,0x57 }, { 0xb9,0xd0,0x69,0xb9 }, 
+    { 0x86,0x91,0x17,0x86 }, { 0xc1,0x58,0x99,0xc1 }, 
+    { 0x1d,0x27,0x3a,0x1d }, { 0x9e,0xb9,0x27,0x9e }, 
+    { 0xe1,0x38,0xd9,0xe1 }, { 0xf8,0x13,0xeb,0xf8 },
+    { 0x98,0xb3,0x2b,0x98 }, { 0x11,0x33,0x22,0x11 }, 
+    { 0x69,0xbb,0xd2,0x69 }, { 0xd9,0x70,0xa9,0xd9 },
+    { 0x8e,0x89,0x07,0x8e }, { 0x94,0xa7,0x33,0x94 }, 
+    { 0x9b,0xb6,0x2d,0x9b }, { 0x1e,0x22,0x3c,0x1e },
+    { 0x87,0x92,0x15,0x87 }, { 0xe9,0x20,0xc9,0xe9 }, 
+    { 0xce,0x49,0x87,0xce }, { 0x55,0xff,0xaa,0x55 },
+    { 0x28,0x78,0x50,0x28 }, { 0xdf,0x7a,0xa5,0xdf }, 
+    { 0x8c,0x8f,0x03,0x8c }, { 0xa1,0xf8,0x59,0xa1 },
+    { 0x89,0x80,0x09,0x89 }, { 0x0d,0x17,0x1a,0x0d }, 
+    { 0xbf,0xda,0x65,0xbf }, { 0xe6,0x31,0xd7,0xe6 },
+    { 0x42,0xc6,0x84,0x42 }, { 0x68,0xb8,0xd0,0x68 }, 
+    { 0x41,0xc3,0x82,0x41 }, { 0x99,0xb0,0x29,0x99 },
+    { 0x2d,0x77,0x5a,0x2d }, { 0x0f,0x11,0x1e,0x0f }, 
+    { 0xb0,0xcb,0x7b,0xb0 }, { 0x54,0xfc,0xa8,0x54 },
+    { 0xbb,0xd6,0x6d,0xbb }, { 0x16,0x3a,0x2c,0x16 }
+  };
+
+static const unsigned char T4[256][4] = 
+  {
+    { 0x63,0x63,0xa5,0xc6 }, { 0x7c,0x7c,0x84,0xf8 },
+    { 0x77,0x77,0x99,0xee }, { 0x7b,0x7b,0x8d,0xf6 }, 
+    { 0xf2,0xf2,0x0d,0xff }, { 0x6b,0x6b,0xbd,0xd6 }, 
+    { 0x6f,0x6f,0xb1,0xde }, { 0xc5,0xc5,0x54,0x91 }, 
+    { 0x30,0x30,0x50,0x60 }, { 0x01,0x01,0x03,0x02 },
+    { 0x67,0x67,0xa9,0xce }, { 0x2b,0x2b,0x7d,0x56 }, 
+    { 0xfe,0xfe,0x19,0xe7 }, { 0xd7,0xd7,0x62,0xb5 },
+    { 0xab,0xab,0xe6,0x4d }, { 0x76,0x76,0x9a,0xec }, 
+    { 0xca,0xca,0x45,0x8f }, { 0x82,0x82,0x9d,0x1f },
+    { 0xc9,0xc9,0x40,0x89 }, { 0x7d,0x7d,0x87,0xfa }, 
+    { 0xfa,0xfa,0x15,0xef }, { 0x59,0x59,0xeb,0xb2 },
+    { 0x47,0x47,0xc9,0x8e }, { 0xf0,0xf0,0x0b,0xfb }, 
+    { 0xad,0xad,0xec,0x41 }, { 0xd4,0xd4,0x67,0xb3 },
+    { 0xa2,0xa2,0xfd,0x5f }, { 0xaf,0xaf,0xea,0x45 }, 
+    { 0x9c,0x9c,0xbf,0x23 }, { 0xa4,0xa4,0xf7,0x53 },
+    { 0x72,0x72,0x96,0xe4 }, { 0xc0,0xc0,0x5b,0x9b }, 
+    { 0xb7,0xb7,0xc2,0x75 }, { 0xfd,0xfd,0x1c,0xe1 },
+    { 0x93,0x93,0xae,0x3d }, { 0x26,0x26,0x6a,0x4c }, 
+    { 0x36,0x36,0x5a,0x6c }, { 0x3f,0x3f,0x41,0x7e },
+    { 0xf7,0xf7,0x02,0xf5 }, { 0xcc,0xcc,0x4f,0x83 }, 
+    { 0x34,0x34,0x5c,0x68 }, { 0xa5,0xa5,0xf4,0x51 },
+    { 0xe5,0xe5,0x34,0xd1 }, { 0xf1,0xf1,0x08,0xf9 }, 
+    { 0x71,0x71,0x93,0xe2 }, { 0xd8,0xd8,0x73,0xab },
+    { 0x31,0x31,0x53,0x62 }, { 0x15,0x15,0x3f,0x2a }, 
+    { 0x04,0x04,0x0c,0x08 }, { 0xc7,0xc7,0x52,0x95 },
+    { 0x23,0x23,0x65,0x46 }, { 0xc3,0xc3,0x5e,0x9d }, 
+    { 0x18,0x18,0x28,0x30 }, { 0x96,0x96,0xa1,0x37 },
+    { 0x05,0x05,0x0f,0x0a }, { 0x9a,0x9a,0xb5,0x2f }, 
+    { 0x07,0x07,0x09,0x0e }, { 0x12,0x12,0x36,0x24 },
+    { 0x80,0x80,0x9b,0x1b }, { 0xe2,0xe2,0x3d,0xdf }, 
+    { 0xeb,0xeb,0x26,0xcd }, { 0x27,0x27,0x69,0x4e },
+    { 0xb2,0xb2,0xcd,0x7f }, { 0x75,0x75,0x9f,0xea }, 
+    { 0x09,0x09,0x1b,0x12 }, { 0x83,0x83,0x9e,0x1d },
+    { 0x2c,0x2c,0x74,0x58 }, { 0x1a,0x1a,0x2e,0x34 }, 
+    { 0x1b,0x1b,0x2d,0x36 }, { 0x6e,0x6e,0xb2,0xdc },
+    { 0x5a,0x5a,0xee,0xb4 }, { 0xa0,0xa0,0xfb,0x5b }, 
+    { 0x52,0x52,0xf6,0xa4 }, { 0x3b,0x3b,0x4d,0x76 },
+    { 0xd6,0xd6,0x61,0xb7 }, { 0xb3,0xb3,0xce,0x7d }, 
+    { 0x29,0x29,0x7b,0x52 }, { 0xe3,0xe3,0x3e,0xdd },
+    { 0x2f,0x2f,0x71,0x5e }, { 0x84,0x84,0x97,0x13 }, 
+    { 0x53,0x53,0xf5,0xa6 }, { 0xd1,0xd1,0x68,0xb9 },
+    { 0x00,0x00,0x00,0x00 }, { 0xed,0xed,0x2c,0xc1 }, 
+    { 0x20,0x20,0x60,0x40 }, { 0xfc,0xfc,0x1f,0xe3 },
+    { 0xb1,0xb1,0xc8,0x79 }, { 0x5b,0x5b,0xed,0xb6 }, 
+    { 0x6a,0x6a,0xbe,0xd4 }, { 0xcb,0xcb,0x46,0x8d },
+    { 0xbe,0xbe,0xd9,0x67 }, { 0x39,0x39,0x4b,0x72 }, 
+    { 0x4a,0x4a,0xde,0x94 }, { 0x4c,0x4c,0xd4,0x98 },
+    { 0x58,0x58,0xe8,0xb0 }, { 0xcf,0xcf,0x4a,0x85 }, 
+    { 0xd0,0xd0,0x6b,0xbb }, { 0xef,0xef,0x2a,0xc5 },
+    { 0xaa,0xaa,0xe5,0x4f }, { 0xfb,0xfb,0x16,0xed }, 
+    { 0x43,0x43,0xc5,0x86 }, { 0x4d,0x4d,0xd7,0x9a },
+    { 0x33,0x33,0x55,0x66 }, { 0x85,0x85,0x94,0x11 }, 
+    { 0x45,0x45,0xcf,0x8a }, { 0xf9,0xf9,0x10,0xe9 },
+    { 0x02,0x02,0x06,0x04 }, { 0x7f,0x7f,0x81,0xfe }, 
+    { 0x50,0x50,0xf0,0xa0 }, { 0x3c,0x3c,0x44,0x78 },
+    { 0x9f,0x9f,0xba,0x25 }, { 0xa8,0xa8,0xe3,0x4b }, 
+    { 0x51,0x51,0xf3,0xa2 }, { 0xa3,0xa3,0xfe,0x5d },
+    { 0x40,0x40,0xc0,0x80 }, { 0x8f,0x8f,0x8a,0x05 }, 
+    { 0x92,0x92,0xad,0x3f }, { 0x9d,0x9d,0xbc,0x21 },
+    { 0x38,0x38,0x48,0x70 }, { 0xf5,0xf5,0x04,0xf1 }, 
+    { 0xbc,0xbc,0xdf,0x63 }, { 0xb6,0xb6,0xc1,0x77 },
+    { 0xda,0xda,0x75,0xaf }, { 0x21,0x21,0x63,0x42 }, 
+    { 0x10,0x10,0x30,0x20 }, { 0xff,0xff,0x1a,0xe5 },
+    { 0xf3,0xf3,0x0e,0xfd }, { 0xd2,0xd2,0x6d,0xbf }, 
+    { 0xcd,0xcd,0x4c,0x81 }, { 0x0c,0x0c,0x14,0x18 },
+    { 0x13,0x13,0x35,0x26 }, { 0xec,0xec,0x2f,0xc3 }, 
+    { 0x5f,0x5f,0xe1,0xbe }, { 0x97,0x97,0xa2,0x35 },
+    { 0x44,0x44,0xcc,0x88 }, { 0x17,0x17,0x39,0x2e }, 
+    { 0xc4,0xc4,0x57,0x93 }, { 0xa7,0xa7,0xf2,0x55 },
+    { 0x7e,0x7e,0x82,0xfc }, { 0x3d,0x3d,0x47,0x7a }, 
+    { 0x64,0x64,0xac,0xc8 }, { 0x5d,0x5d,0xe7,0xba },
+    { 0x19,0x19,0x2b,0x32 }, { 0x73,0x73,0x95,0xe6 }, 
+    { 0x60,0x60,0xa0,0xc0 }, { 0x81,0x81,0x98,0x19 },
+    { 0x4f,0x4f,0xd1,0x9e }, { 0xdc,0xdc,0x7f,0xa3 }, 
+    { 0x22,0x22,0x66,0x44 }, { 0x2a,0x2a,0x7e,0x54 },
+    { 0x90,0x90,0xab,0x3b }, { 0x88,0x88,0x83,0x0b }, 
+    { 0x46,0x46,0xca,0x8c }, { 0xee,0xee,0x29,0xc7 },
+    { 0xb8,0xb8,0xd3,0x6b }, { 0x14,0x14,0x3c,0x28 }, 
+    { 0xde,0xde,0x79,0xa7 }, { 0x5e,0x5e,0xe2,0xbc },
+    { 0x0b,0x0b,0x1d,0x16 }, { 0xdb,0xdb,0x76,0xad }, 
+    { 0xe0,0xe0,0x3b,0xdb }, { 0x32,0x32,0x56,0x64 },
+    { 0x3a,0x3a,0x4e,0x74 }, { 0x0a,0x0a,0x1e,0x14 }, 
+    { 0x49,0x49,0xdb,0x92 }, { 0x06,0x06,0x0a,0x0c },
+    { 0x24,0x24,0x6c,0x48 }, { 0x5c,0x5c,0xe4,0xb8 }, 
+    { 0xc2,0xc2,0x5d,0x9f }, { 0xd3,0xd3,0x6e,0xbd },
+    { 0xac,0xac,0xef,0x43 }, { 0x62,0x62,0xa6,0xc4 }, 
+    { 0x91,0x91,0xa8,0x39 }, { 0x95,0x95,0xa4,0x31 },
+    { 0xe4,0xe4,0x37,0xd3 }, { 0x79,0x79,0x8b,0xf2 }, 
+    { 0xe7,0xe7,0x32,0xd5 }, { 0xc8,0xc8,0x43,0x8b },
+    { 0x37,0x37,0x59,0x6e }, { 0x6d,0x6d,0xb7,0xda }, 
+    { 0x8d,0x8d,0x8c,0x01 }, { 0xd5,0xd5,0x64,0xb1 }, 
+    { 0x4e,0x4e,0xd2,0x9c }, { 0xa9,0xa9,0xe0,0x49 }, 
+    { 0x6c,0x6c,0xb4,0xd8 }, { 0x56,0x56,0xfa,0xac }, 
+    { 0xf4,0xf4,0x07,0xf3 }, { 0xea,0xea,0x25,0xcf }, 
+    { 0x65,0x65,0xaf,0xca }, { 0x7a,0x7a,0x8e,0xf4 }, 
+    { 0xae,0xae,0xe9,0x47 }, { 0x08,0x08,0x18,0x10 }, 
+    { 0xba,0xba,0xd5,0x6f }, { 0x78,0x78,0x88,0xf0 }, 
+    { 0x25,0x25,0x6f,0x4a }, { 0x2e,0x2e,0x72,0x5c }, 
+    { 0x1c,0x1c,0x24,0x38 }, { 0xa6,0xa6,0xf1,0x57 },
+    { 0xb4,0xb4,0xc7,0x73 }, { 0xc6,0xc6,0x51,0x97 }, 
+    { 0xe8,0xe8,0x23,0xcb }, { 0xdd,0xdd,0x7c,0xa1 },
+    { 0x74,0x74,0x9c,0xe8 }, { 0x1f,0x1f,0x21,0x3e }, 
+    { 0x4b,0x4b,0xdd,0x96 }, { 0xbd,0xbd,0xdc,0x61 },
+    { 0x8b,0x8b,0x86,0x0d }, { 0x8a,0x8a,0x85,0x0f }, 
+    { 0x70,0x70,0x90,0xe0 }, { 0x3e,0x3e,0x42,0x7c },
+    { 0xb5,0xb5,0xc4,0x71 }, { 0x66,0x66,0xaa,0xcc }, 
+    { 0x48,0x48,0xd8,0x90 }, { 0x03,0x03,0x05,0x06 },
+    { 0xf6,0xf6,0x01,0xf7 }, { 0x0e,0x0e,0x12,0x1c }, 
+    { 0x61,0x61,0xa3,0xc2 }, { 0x35,0x35,0x5f,0x6a },
+    { 0x57,0x57,0xf9,0xae }, { 0xb9,0xb9,0xd0,0x69 }, 
+    { 0x86,0x86,0x91,0x17 }, { 0xc1,0xc1,0x58,0x99 },
+    { 0x1d,0x1d,0x27,0x3a }, { 0x9e,0x9e,0xb9,0x27 }, 
+    { 0xe1,0xe1,0x38,0xd9 }, { 0xf8,0xf8,0x13,0xeb },
+    { 0x98,0x98,0xb3,0x2b }, { 0x11,0x11,0x33,0x22 }, 
+    { 0x69,0x69,0xbb,0xd2 }, { 0xd9,0xd9,0x70,0xa9 },
+    { 0x8e,0x8e,0x89,0x07 }, { 0x94,0x94,0xa7,0x33 }, 
+    { 0x9b,0x9b,0xb6,0x2d }, { 0x1e,0x1e,0x22,0x3c },
+    { 0x87,0x87,0x92,0x15 }, { 0xe9,0xe9,0x20,0xc9 }, 
+    { 0xce,0xce,0x49,0x87 }, { 0x55,0x55,0xff,0xaa },
+    { 0x28,0x28,0x78,0x50 }, { 0xdf,0xdf,0x7a,0xa5 }, 
+    { 0x8c,0x8c,0x8f,0x03 }, { 0xa1,0xa1,0xf8,0x59 },
+    { 0x89,0x89,0x80,0x09 }, { 0x0d,0x0d,0x17,0x1a }, 
+    { 0xbf,0xbf,0xda,0x65 }, { 0xe6,0xe6,0x31,0xd7 }, 
+    { 0x42,0x42,0xc6,0x84 }, { 0x68,0x68,0xb8,0xd0 }, 
+    { 0x41,0x41,0xc3,0x82 }, { 0x99,0x99,0xb0,0x29 },
+    { 0x2d,0x2d,0x77,0x5a }, { 0x0f,0x0f,0x11,0x1e }, 
+    { 0xb0,0xb0,0xcb,0x7b }, { 0x54,0x54,0xfc,0xa8 },
+    { 0xbb,0xbb,0xd6,0x6d }, { 0x16,0x16,0x3a,0x2c }
+  };
+
+static const unsigned char T5[256][4] = 
+  {
+    { 0x51,0xf4,0xa7,0x50 }, { 0x7e,0x41,0x65,0x53 }, 
+    { 0x1a,0x17,0xa4,0xc3 }, { 0x3a,0x27,0x5e,0x96 }, 
+    { 0x3b,0xab,0x6b,0xcb }, { 0x1f,0x9d,0x45,0xf1 },
+    { 0xac,0xfa,0x58,0xab }, { 0x4b,0xe3,0x03,0x93 }, 
+    { 0x20,0x30,0xfa,0x55 }, { 0xad,0x76,0x6d,0xf6 },
+    { 0x88,0xcc,0x76,0x91 }, { 0xf5,0x02,0x4c,0x25 }, 
+    { 0x4f,0xe5,0xd7,0xfc }, { 0xc5,0x2a,0xcb,0xd7 },
+    { 0x26,0x35,0x44,0x80 }, { 0xb5,0x62,0xa3,0x8f }, 
+    { 0xde,0xb1,0x5a,0x49 }, { 0x25,0xba,0x1b,0x67 },
+    { 0x45,0xea,0x0e,0x98 }, { 0x5d,0xfe,0xc0,0xe1 }, 
+    { 0xc3,0x2f,0x75,0x02 }, { 0x81,0x4c,0xf0,0x12 },
+    { 0x8d,0x46,0x97,0xa3 }, { 0x6b,0xd3,0xf9,0xc6 }, 
+    { 0x03,0x8f,0x5f,0xe7 }, { 0x15,0x92,0x9c,0x95 },
+    { 0xbf,0x6d,0x7a,0xeb }, { 0x95,0x52,0x59,0xda }, 
+    { 0xd4,0xbe,0x83,0x2d }, { 0x58,0x74,0x21,0xd3 },
+    { 0x49,0xe0,0x69,0x29 }, { 0x8e,0xc9,0xc8,0x44 }, 
+    { 0x75,0xc2,0x89,0x6a }, { 0xf4,0x8e,0x79,0x78 },
+    { 0x99,0x58,0x3e,0x6b }, { 0x27,0xb9,0x71,0xdd }, 
+    { 0xbe,0xe1,0x4f,0xb6 }, { 0xf0,0x88,0xad,0x17 },
+    { 0xc9,0x20,0xac,0x66 }, { 0x7d,0xce,0x3a,0xb4 }, 
+    { 0x63,0xdf,0x4a,0x18 }, { 0xe5,0x1a,0x31,0x82 },
+    { 0x97,0x51,0x33,0x60 }, { 0x62,0x53,0x7f,0x45 }, 
+    { 0xb1,0x64,0x77,0xe0 }, { 0xbb,0x6b,0xae,0x84 }, 
+    { 0xfe,0x81,0xa0,0x1c }, { 0xf9,0x08,0x2b,0x94 }, 
+    { 0x70,0x48,0x68,0x58 }, { 0x8f,0x45,0xfd,0x19 }, 
+    { 0x94,0xde,0x6c,0x87 }, { 0x52,0x7b,0xf8,0xb7 }, 
+    { 0xab,0x73,0xd3,0x23 }, { 0x72,0x4b,0x02,0xe2 },
+    { 0xe3,0x1f,0x8f,0x57 }, { 0x66,0x55,0xab,0x2a }, 
+    { 0xb2,0xeb,0x28,0x07 }, { 0x2f,0xb5,0xc2,0x03 },
+    { 0x86,0xc5,0x7b,0x9a }, { 0xd3,0x37,0x08,0xa5 }, 
+    { 0x30,0x28,0x87,0xf2 }, { 0x23,0xbf,0xa5,0xb2 },
+    { 0x02,0x03,0x6a,0xba }, { 0xed,0x16,0x82,0x5c }, 
+    { 0x8a,0xcf,0x1c,0x2b }, { 0xa7,0x79,0xb4,0x92 },
+    { 0xf3,0x07,0xf2,0xf0 }, { 0x4e,0x69,0xe2,0xa1 }, 
+    { 0x65,0xda,0xf4,0xcd }, { 0x06,0x05,0xbe,0xd5 },
+    { 0xd1,0x34,0x62,0x1f }, { 0xc4,0xa6,0xfe,0x8a }, 
+    { 0x34,0x2e,0x53,0x9d }, { 0xa2,0xf3,0x55,0xa0 },
+    { 0x05,0x8a,0xe1,0x32 }, { 0xa4,0xf6,0xeb,0x75 }, 
+    { 0x0b,0x83,0xec,0x39 }, { 0x40,0x60,0xef,0xaa },
+    { 0x5e,0x71,0x9f,0x06 }, { 0xbd,0x6e,0x10,0x51 }, 
+    { 0x3e,0x21,0x8a,0xf9 }, { 0x96,0xdd,0x06,0x3d }, 
+    { 0xdd,0x3e,0x05,0xae }, { 0x4d,0xe6,0xbd,0x46 }, 
+    { 0x91,0x54,0x8d,0xb5 }, { 0x71,0xc4,0x5d,0x05 }, 
+    { 0x04,0x06,0xd4,0x6f }, { 0x60,0x50,0x15,0xff }, 
+    { 0x19,0x98,0xfb,0x24 }, { 0xd6,0xbd,0xe9,0x97 },
+    { 0x89,0x40,0x43,0xcc }, { 0x67,0xd9,0x9e,0x77 }, 
+    { 0xb0,0xe8,0x42,0xbd }, { 0x07,0x89,0x8b,0x88 },
+    { 0xe7,0x19,0x5b,0x38 }, { 0x79,0xc8,0xee,0xdb }, 
+    { 0xa1,0x7c,0x0a,0x47 }, { 0x7c,0x42,0x0f,0xe9 },
+    { 0xf8,0x84,0x1e,0xc9 }, { 0x00,0x00,0x00,0x00 }, 
+    { 0x09,0x80,0x86,0x83 }, { 0x32,0x2b,0xed,0x48 },
+    { 0x1e,0x11,0x70,0xac }, { 0x6c,0x5a,0x72,0x4e }, 
+    { 0xfd,0x0e,0xff,0xfb }, { 0x0f,0x85,0x38,0x56 },
+    { 0x3d,0xae,0xd5,0x1e }, { 0x36,0x2d,0x39,0x27 }, 
+    { 0x0a,0x0f,0xd9,0x64 }, { 0x68,0x5c,0xa6,0x21 },
+    { 0x9b,0x5b,0x54,0xd1 }, { 0x24,0x36,0x2e,0x3a }, 
+    { 0x0c,0x0a,0x67,0xb1 }, { 0x93,0x57,0xe7,0x0f },
+    { 0xb4,0xee,0x96,0xd2 }, { 0x1b,0x9b,0x91,0x9e }, 
+    { 0x80,0xc0,0xc5,0x4f }, { 0x61,0xdc,0x20,0xa2 },
+    { 0x5a,0x77,0x4b,0x69 }, { 0x1c,0x12,0x1a,0x16 }, 
+    { 0xe2,0x93,0xba,0x0a }, { 0xc0,0xa0,0x2a,0xe5 }, 
+    { 0x3c,0x22,0xe0,0x43 }, { 0x12,0x1b,0x17,0x1d }, 
+    { 0x0e,0x09,0x0d,0x0b }, { 0xf2,0x8b,0xc7,0xad }, 
+    { 0x2d,0xb6,0xa8,0xb9 }, { 0x14,0x1e,0xa9,0xc8 }, 
+    { 0x57,0xf1,0x19,0x85 }, { 0xaf,0x75,0x07,0x4c }, 
+    { 0xee,0x99,0xdd,0xbb }, { 0xa3,0x7f,0x60,0xfd }, 
+    { 0xf7,0x01,0x26,0x9f }, { 0x5c,0x72,0xf5,0xbc },
+    { 0x44,0x66,0x3b,0xc5 }, { 0x5b,0xfb,0x7e,0x34 }, 
+    { 0x8b,0x43,0x29,0x76 }, { 0xcb,0x23,0xc6,0xdc },
+    { 0xb6,0xed,0xfc,0x68 }, { 0xb8,0xe4,0xf1,0x63 }, 
+    { 0xd7,0x31,0xdc,0xca }, { 0x42,0x63,0x85,0x10 },
+    { 0x13,0x97,0x22,0x40 }, { 0x84,0xc6,0x11,0x20 }, 
+    { 0x85,0x4a,0x24,0x7d }, { 0xd2,0xbb,0x3d,0xf8 }, 
+    { 0xae,0xf9,0x32,0x11 }, { 0xc7,0x29,0xa1,0x6d }, 
+    { 0x1d,0x9e,0x2f,0x4b }, { 0xdc,0xb2,0x30,0xf3 },
+    { 0x0d,0x86,0x52,0xec }, { 0x77,0xc1,0xe3,0xd0 }, 
+    { 0x2b,0xb3,0x16,0x6c }, { 0xa9,0x70,0xb9,0x99 },
+    { 0x11,0x94,0x48,0xfa }, { 0x47,0xe9,0x64,0x22 }, 
+    { 0xa8,0xfc,0x8c,0xc4 }, { 0xa0,0xf0,0x3f,0x1a },
+    { 0x56,0x7d,0x2c,0xd8 }, { 0x22,0x33,0x90,0xef }, 
+    { 0x87,0x49,0x4e,0xc7 }, { 0xd9,0x38,0xd1,0xc1 }, 
+    { 0x8c,0xca,0xa2,0xfe }, { 0x98,0xd4,0x0b,0x36 }, 
+    { 0xa6,0xf5,0x81,0xcf }, { 0xa5,0x7a,0xde,0x28 }, 
+    { 0xda,0xb7,0x8e,0x26 }, { 0x3f,0xad,0xbf,0xa4 }, 
+    { 0x2c,0x3a,0x9d,0xe4 }, { 0x50,0x78,0x92,0x0d }, 
+    { 0x6a,0x5f,0xcc,0x9b }, { 0x54,0x7e,0x46,0x62 }, 
+    { 0xf6,0x8d,0x13,0xc2 }, { 0x90,0xd8,0xb8,0xe8 }, 
+    { 0x2e,0x39,0xf7,0x5e }, { 0x82,0xc3,0xaf,0xf5 }, 
+    { 0x9f,0x5d,0x80,0xbe }, { 0x69,0xd0,0x93,0x7c },
+    { 0x6f,0xd5,0x2d,0xa9 }, { 0xcf,0x25,0x12,0xb3 }, 
+    { 0xc8,0xac,0x99,0x3b }, { 0x10,0x18,0x7d,0xa7 },
+    { 0xe8,0x9c,0x63,0x6e }, { 0xdb,0x3b,0xbb,0x7b }, 
+    { 0xcd,0x26,0x78,0x09 }, { 0x6e,0x59,0x18,0xf4 },
+    { 0xec,0x9a,0xb7,0x01 }, { 0x83,0x4f,0x9a,0xa8 }, 
+    { 0xe6,0x95,0x6e,0x65 }, { 0xaa,0xff,0xe6,0x7e }, 
+    { 0x21,0xbc,0xcf,0x08 }, { 0xef,0x15,0xe8,0xe6 }, 
+    { 0xba,0xe7,0x9b,0xd9 }, { 0x4a,0x6f,0x36,0xce }, 
+    { 0xea,0x9f,0x09,0xd4 }, { 0x29,0xb0,0x7c,0xd6 }, 
+    { 0x31,0xa4,0xb2,0xaf }, { 0x2a,0x3f,0x23,0x31 }, 
+    { 0xc6,0xa5,0x94,0x30 }, { 0x35,0xa2,0x66,0xc0 }, 
+    { 0x74,0x4e,0xbc,0x37 }, { 0xfc,0x82,0xca,0xa6 }, 
+    { 0xe0,0x90,0xd0,0xb0 }, { 0x33,0xa7,0xd8,0x15 }, 
+    { 0xf1,0x04,0x98,0x4a }, { 0x41,0xec,0xda,0xf7 },
+    { 0x7f,0xcd,0x50,0x0e }, { 0x17,0x91,0xf6,0x2f }, 
+    { 0x76,0x4d,0xd6,0x8d }, { 0x43,0xef,0xb0,0x4d },
+    { 0xcc,0xaa,0x4d,0x54 }, { 0xe4,0x96,0x04,0xdf }, 
+    { 0x9e,0xd1,0xb5,0xe3 }, { 0x4c,0x6a,0x88,0x1b },
+    { 0xc1,0x2c,0x1f,0xb8 }, { 0x46,0x65,0x51,0x7f }, 
+    { 0x9d,0x5e,0xea,0x04 }, { 0x01,0x8c,0x35,0x5d },
+    { 0xfa,0x87,0x74,0x73 }, { 0xfb,0x0b,0x41,0x2e }, 
+    { 0xb3,0x67,0x1d,0x5a }, { 0x92,0xdb,0xd2,0x52 },
+    { 0xe9,0x10,0x56,0x33 }, { 0x6d,0xd6,0x47,0x13 }, 
+    { 0x9a,0xd7,0x61,0x8c }, { 0x37,0xa1,0x0c,0x7a },
+    { 0x59,0xf8,0x14,0x8e }, { 0xeb,0x13,0x3c,0x89 }, 
+    { 0xce,0xa9,0x27,0xee }, { 0xb7,0x61,0xc9,0x35 },
+    { 0xe1,0x1c,0xe5,0xed }, { 0x7a,0x47,0xb1,0x3c }, 
+    { 0x9c,0xd2,0xdf,0x59 }, { 0x55,0xf2,0x73,0x3f }, 
+    { 0x18,0x14,0xce,0x79 }, { 0x73,0xc7,0x37,0xbf }, 
+    { 0x53,0xf7,0xcd,0xea }, { 0x5f,0xfd,0xaa,0x5b },
+    { 0xdf,0x3d,0x6f,0x14 }, { 0x78,0x44,0xdb,0x86 }, 
+    { 0xca,0xaf,0xf3,0x81 }, { 0xb9,0x68,0xc4,0x3e }, 
+    { 0x38,0x24,0x34,0x2c }, { 0xc2,0xa3,0x40,0x5f }, 
+    { 0x16,0x1d,0xc3,0x72 }, { 0xbc,0xe2,0x25,0x0c }, 
+    { 0x28,0x3c,0x49,0x8b }, { 0xff,0x0d,0x95,0x41 }, 
+    { 0x39,0xa8,0x01,0x71 }, { 0x08,0x0c,0xb3,0xde }, 
+    { 0xd8,0xb4,0xe4,0x9c }, { 0x64,0x56,0xc1,0x90 }, 
+    { 0x7b,0xcb,0x84,0x61 }, { 0xd5,0x32,0xb6,0x70 },
+    { 0x48,0x6c,0x5c,0x74 }, { 0xd0,0xb8,0x57,0x42 }
+  };
+
+static const unsigned char T6[256][4] = 
+  {
+    { 0x50,0x51,0xf4,0xa7 }, { 0x53,0x7e,0x41,0x65 }, 
+    { 0xc3,0x1a,0x17,0xa4 }, { 0x96,0x3a,0x27,0x5e }, 
+    { 0xcb,0x3b,0xab,0x6b }, { 0xf1,0x1f,0x9d,0x45 },
+    { 0xab,0xac,0xfa,0x58 }, { 0x93,0x4b,0xe3,0x03 }, 
+    { 0x55,0x20,0x30,0xfa }, { 0xf6,0xad,0x76,0x6d },
+    { 0x91,0x88,0xcc,0x76 }, { 0x25,0xf5,0x02,0x4c }, 
+    { 0xfc,0x4f,0xe5,0xd7 }, { 0xd7,0xc5,0x2a,0xcb },
+    { 0x80,0x26,0x35,0x44 }, { 0x8f,0xb5,0x62,0xa3 }, 
+    { 0x49,0xde,0xb1,0x5a }, { 0x67,0x25,0xba,0x1b }, 
+    { 0x98,0x45,0xea,0x0e }, { 0xe1,0x5d,0xfe,0xc0 }, 
+    { 0x02,0xc3,0x2f,0x75 }, { 0x12,0x81,0x4c,0xf0 },
+    { 0xa3,0x8d,0x46,0x97 }, { 0xc6,0x6b,0xd3,0xf9 }, 
+    { 0xe7,0x03,0x8f,0x5f }, { 0x95,0x15,0x92,0x9c },
+    { 0xeb,0xbf,0x6d,0x7a }, { 0xda,0x95,0x52,0x59 }, 
+    { 0x2d,0xd4,0xbe,0x83 }, { 0xd3,0x58,0x74,0x21 },
+    { 0x29,0x49,0xe0,0x69 }, { 0x44,0x8e,0xc9,0xc8 }, 
+    { 0x6a,0x75,0xc2,0x89 }, { 0x78,0xf4,0x8e,0x79 },
+    { 0x6b,0x99,0x58,0x3e }, { 0xdd,0x27,0xb9,0x71 }, 
+    { 0xb6,0xbe,0xe1,0x4f }, { 0x17,0xf0,0x88,0xad },
+    { 0x66,0xc9,0x20,0xac }, { 0xb4,0x7d,0xce,0x3a }, 
+    { 0x18,0x63,0xdf,0x4a }, { 0x82,0xe5,0x1a,0x31 },
+    { 0x60,0x97,0x51,0x33 }, { 0x45,0x62,0x53,0x7f }, 
+    { 0xe0,0xb1,0x64,0x77 }, { 0x84,0xbb,0x6b,0xae },
+    { 0x1c,0xfe,0x81,0xa0 }, { 0x94,0xf9,0x08,0x2b }, 
+    { 0x58,0x70,0x48,0x68 }, { 0x19,0x8f,0x45,0xfd },
+    { 0x87,0x94,0xde,0x6c }, { 0xb7,0x52,0x7b,0xf8 }, 
+    { 0x23,0xab,0x73,0xd3 }, { 0xe2,0x72,0x4b,0x02 },
+    { 0x57,0xe3,0x1f,0x8f }, { 0x2a,0x66,0x55,0xab }, 
+    { 0x07,0xb2,0xeb,0x28 }, { 0x03,0x2f,0xb5,0xc2 },
+    { 0x9a,0x86,0xc5,0x7b }, { 0xa5,0xd3,0x37,0x08 }, 
+    { 0xf2,0x30,0x28,0x87 }, { 0xb2,0x23,0xbf,0xa5 },
+    { 0xba,0x02,0x03,0x6a }, { 0x5c,0xed,0x16,0x82 }, 
+    { 0x2b,0x8a,0xcf,0x1c }, { 0x92,0xa7,0x79,0xb4 },
+    { 0xf0,0xf3,0x07,0xf2 }, { 0xa1,0x4e,0x69,0xe2 }, 
+    { 0xcd,0x65,0xda,0xf4 }, { 0xd5,0x06,0x05,0xbe },
+    { 0x1f,0xd1,0x34,0x62 }, { 0x8a,0xc4,0xa6,0xfe }, 
+    { 0x9d,0x34,0x2e,0x53 }, { 0xa0,0xa2,0xf3,0x55 },
+    { 0x32,0x05,0x8a,0xe1 }, { 0x75,0xa4,0xf6,0xeb }, 
+    { 0x39,0x0b,0x83,0xec }, { 0xaa,0x40,0x60,0xef },
+    { 0x06,0x5e,0x71,0x9f }, { 0x51,0xbd,0x6e,0x10 }, 
+    { 0xf9,0x3e,0x21,0x8a }, { 0x3d,0x96,0xdd,0x06 },
+    { 0xae,0xdd,0x3e,0x05 }, { 0x46,0x4d,0xe6,0xbd }, 
+    { 0xb5,0x91,0x54,0x8d }, { 0x05,0x71,0xc4,0x5d },
+    { 0x6f,0x04,0x06,0xd4 }, { 0xff,0x60,0x50,0x15 }, 
+    { 0x24,0x19,0x98,0xfb }, { 0x97,0xd6,0xbd,0xe9 },
+    { 0xcc,0x89,0x40,0x43 }, { 0x77,0x67,0xd9,0x9e }, 
+    { 0xbd,0xb0,0xe8,0x42 }, { 0x88,0x07,0x89,0x8b },
+    { 0x38,0xe7,0x19,0x5b }, { 0xdb,0x79,0xc8,0xee }, 
+    { 0x47,0xa1,0x7c,0x0a }, { 0xe9,0x7c,0x42,0x0f },
+    { 0xc9,0xf8,0x84,0x1e }, { 0x00,0x00,0x00,0x00 }, 
+    { 0x83,0x09,0x80,0x86 }, { 0x48,0x32,0x2b,0xed },
+    { 0xac,0x1e,0x11,0x70 }, { 0x4e,0x6c,0x5a,0x72 }, 
+    { 0xfb,0xfd,0x0e,0xff }, { 0x56,0x0f,0x85,0x38 },
+    { 0x1e,0x3d,0xae,0xd5 }, { 0x27,0x36,0x2d,0x39 }, 
+    { 0x64,0x0a,0x0f,0xd9 }, { 0x21,0x68,0x5c,0xa6 },
+    { 0xd1,0x9b,0x5b,0x54 }, { 0x3a,0x24,0x36,0x2e }, 
+    { 0xb1,0x0c,0x0a,0x67 }, { 0x0f,0x93,0x57,0xe7 },
+    { 0xd2,0xb4,0xee,0x96 }, { 0x9e,0x1b,0x9b,0x91 }, 
+    { 0x4f,0x80,0xc0,0xc5 }, { 0xa2,0x61,0xdc,0x20 }, 
+    { 0x69,0x5a,0x77,0x4b }, { 0x16,0x1c,0x12,0x1a }, 
+    { 0x0a,0xe2,0x93,0xba }, { 0xe5,0xc0,0xa0,0x2a },
+    { 0x43,0x3c,0x22,0xe0 }, { 0x1d,0x12,0x1b,0x17 }, 
+    { 0x0b,0x0e,0x09,0x0d }, { 0xad,0xf2,0x8b,0xc7 },
+    { 0xb9,0x2d,0xb6,0xa8 }, { 0xc8,0x14,0x1e,0xa9 }, 
+    { 0x85,0x57,0xf1,0x19 }, { 0x4c,0xaf,0x75,0x07 },
+    { 0xbb,0xee,0x99,0xdd }, { 0xfd,0xa3,0x7f,0x60 }, 
+    { 0x9f,0xf7,0x01,0x26 }, { 0xbc,0x5c,0x72,0xf5 },
+    { 0xc5,0x44,0x66,0x3b }, { 0x34,0x5b,0xfb,0x7e }, 
+    { 0x76,0x8b,0x43,0x29 }, { 0xdc,0xcb,0x23,0xc6 },
+    { 0x68,0xb6,0xed,0xfc }, { 0x63,0xb8,0xe4,0xf1 }, 
+    { 0xca,0xd7,0x31,0xdc }, { 0x10,0x42,0x63,0x85 },
+    { 0x40,0x13,0x97,0x22 }, { 0x20,0x84,0xc6,0x11 }, 
+    { 0x7d,0x85,0x4a,0x24 }, { 0xf8,0xd2,0xbb,0x3d },
+    { 0x11,0xae,0xf9,0x32 }, { 0x6d,0xc7,0x29,0xa1 }, 
+    { 0x4b,0x1d,0x9e,0x2f }, { 0xf3,0xdc,0xb2,0x30 },
+    { 0xec,0x0d,0x86,0x52 }, { 0xd0,0x77,0xc1,0xe3 }, 
+    { 0x6c,0x2b,0xb3,0x16 }, { 0x99,0xa9,0x70,0xb9 }, 
+    { 0xfa,0x11,0x94,0x48 }, { 0x22,0x47,0xe9,0x64 }, 
+    { 0xc4,0xa8,0xfc,0x8c }, { 0x1a,0xa0,0xf0,0x3f }, 
+    { 0xd8,0x56,0x7d,0x2c }, { 0xef,0x22,0x33,0x90 }, 
+    { 0xc7,0x87,0x49,0x4e }, { 0xc1,0xd9,0x38,0xd1 },
+    { 0xfe,0x8c,0xca,0xa2 }, { 0x36,0x98,0xd4,0x0b }, 
+    { 0xcf,0xa6,0xf5,0x81 }, { 0x28,0xa5,0x7a,0xde }, 
+    { 0x26,0xda,0xb7,0x8e }, { 0xa4,0x3f,0xad,0xbf }, 
+    { 0xe4,0x2c,0x3a,0x9d }, { 0x0d,0x50,0x78,0x92 }, 
+    { 0x9b,0x6a,0x5f,0xcc }, { 0x62,0x54,0x7e,0x46 }, 
+    { 0xc2,0xf6,0x8d,0x13 }, { 0xe8,0x90,0xd8,0xb8 }, 
+    { 0x5e,0x2e,0x39,0xf7 }, { 0xf5,0x82,0xc3,0xaf }, 
+    { 0xbe,0x9f,0x5d,0x80 }, { 0x7c,0x69,0xd0,0x93 },
+    { 0xa9,0x6f,0xd5,0x2d }, { 0xb3,0xcf,0x25,0x12 }, 
+    { 0x3b,0xc8,0xac,0x99 }, { 0xa7,0x10,0x18,0x7d }, 
+    { 0x6e,0xe8,0x9c,0x63 }, { 0x7b,0xdb,0x3b,0xbb }, 
+    { 0x09,0xcd,0x26,0x78 }, { 0xf4,0x6e,0x59,0x18 },
+    { 0x01,0xec,0x9a,0xb7 }, { 0xa8,0x83,0x4f,0x9a }, 
+    { 0x65,0xe6,0x95,0x6e }, { 0x7e,0xaa,0xff,0xe6 }, 
+    { 0x08,0x21,0xbc,0xcf }, { 0xe6,0xef,0x15,0xe8 }, 
+    { 0xd9,0xba,0xe7,0x9b }, { 0xce,0x4a,0x6f,0x36 },
+    { 0xd4,0xea,0x9f,0x09 }, { 0xd6,0x29,0xb0,0x7c }, 
+    { 0xaf,0x31,0xa4,0xb2 }, { 0x31,0x2a,0x3f,0x23 },
+    { 0x30,0xc6,0xa5,0x94 }, { 0xc0,0x35,0xa2,0x66 }, 
+    { 0x37,0x74,0x4e,0xbc }, { 0xa6,0xfc,0x82,0xca }, 
+    { 0xb0,0xe0,0x90,0xd0 }, { 0x15,0x33,0xa7,0xd8 }, 
+    { 0x4a,0xf1,0x04,0x98 }, { 0xf7,0x41,0xec,0xda },
+    { 0x0e,0x7f,0xcd,0x50 }, { 0x2f,0x17,0x91,0xf6 }, 
+    { 0x8d,0x76,0x4d,0xd6 }, { 0x4d,0x43,0xef,0xb0 },
+    { 0x54,0xcc,0xaa,0x4d }, { 0xdf,0xe4,0x96,0x04 }, 
+    { 0xe3,0x9e,0xd1,0xb5 }, { 0x1b,0x4c,0x6a,0x88 },
+    { 0xb8,0xc1,0x2c,0x1f }, { 0x7f,0x46,0x65,0x51 }, 
+    { 0x04,0x9d,0x5e,0xea }, { 0x5d,0x01,0x8c,0x35 },
+    { 0x73,0xfa,0x87,0x74 }, { 0x2e,0xfb,0x0b,0x41 }, 
+    { 0x5a,0xb3,0x67,0x1d }, { 0x52,0x92,0xdb,0xd2 },
+    { 0x33,0xe9,0x10,0x56 }, { 0x13,0x6d,0xd6,0x47 }, 
+    { 0x8c,0x9a,0xd7,0x61 }, { 0x7a,0x37,0xa1,0x0c }, 
+    { 0x8e,0x59,0xf8,0x14 }, { 0x89,0xeb,0x13,0x3c }, 
+    { 0xee,0xce,0xa9,0x27 }, { 0x35,0xb7,0x61,0xc9 },
+    { 0xed,0xe1,0x1c,0xe5 }, { 0x3c,0x7a,0x47,0xb1 }, 
+    { 0x59,0x9c,0xd2,0xdf }, { 0x3f,0x55,0xf2,0x73 },
+    { 0x79,0x18,0x14,0xce }, { 0xbf,0x73,0xc7,0x37 }, 
+    { 0xea,0x53,0xf7,0xcd }, { 0x5b,0x5f,0xfd,0xaa },
+    { 0x14,0xdf,0x3d,0x6f }, { 0x86,0x78,0x44,0xdb }, 
+    { 0x81,0xca,0xaf,0xf3 }, { 0x3e,0xb9,0x68,0xc4 },
+    { 0x2c,0x38,0x24,0x34 }, { 0x5f,0xc2,0xa3,0x40 }, 
+    { 0x72,0x16,0x1d,0xc3 }, { 0x0c,0xbc,0xe2,0x25 },
+    { 0x8b,0x28,0x3c,0x49 }, { 0x41,0xff,0x0d,0x95 }, 
+    { 0x71,0x39,0xa8,0x01 }, { 0xde,0x08,0x0c,0xb3 },
+    { 0x9c,0xd8,0xb4,0xe4 }, { 0x90,0x64,0x56,0xc1 }, 
+    { 0x61,0x7b,0xcb,0x84 }, { 0x70,0xd5,0x32,0xb6 },
+    { 0x74,0x48,0x6c,0x5c }, { 0x42,0xd0,0xb8,0x57 }
+  };
+
+static const unsigned char T7[256][4] = 
+  {
+    { 0xa7,0x50,0x51,0xf4 }, { 0x65,0x53,0x7e,0x41 },
+    { 0xa4,0xc3,0x1a,0x17 }, { 0x5e,0x96,0x3a,0x27 }, 
+    { 0x6b,0xcb,0x3b,0xab }, { 0x45,0xf1,0x1f,0x9d },
+    { 0x58,0xab,0xac,0xfa }, { 0x03,0x93,0x4b,0xe3 }, 
+    { 0xfa,0x55,0x20,0x30 }, { 0x6d,0xf6,0xad,0x76 },
+    { 0x76,0x91,0x88,0xcc }, { 0x4c,0x25,0xf5,0x02 }, 
+    { 0xd7,0xfc,0x4f,0xe5 }, { 0xcb,0xd7,0xc5,0x2a },
+    { 0x44,0x80,0x26,0x35 }, { 0xa3,0x8f,0xb5,0x62 }, 
+    { 0x5a,0x49,0xde,0xb1 }, { 0x1b,0x67,0x25,0xba }, 
+    { 0x0e,0x98,0x45,0xea }, { 0xc0,0xe1,0x5d,0xfe }, 
+    { 0x75,0x02,0xc3,0x2f }, { 0xf0,0x12,0x81,0x4c },
+    { 0x97,0xa3,0x8d,0x46 }, { 0xf9,0xc6,0x6b,0xd3 }, 
+    { 0x5f,0xe7,0x03,0x8f }, { 0x9c,0x95,0x15,0x92 },
+    { 0x7a,0xeb,0xbf,0x6d }, { 0x59,0xda,0x95,0x52 }, 
+    { 0x83,0x2d,0xd4,0xbe }, { 0x21,0xd3,0x58,0x74 },
+    { 0x69,0x29,0x49,0xe0 }, { 0xc8,0x44,0x8e,0xc9 }, 
+    { 0x89,0x6a,0x75,0xc2 }, { 0x79,0x78,0xf4,0x8e }, 
+    { 0x3e,0x6b,0x99,0x58 }, { 0x71,0xdd,0x27,0xb9 }, 
+    { 0x4f,0xb6,0xbe,0xe1 }, { 0xad,0x17,0xf0,0x88 },
+    { 0xac,0x66,0xc9,0x20 }, { 0x3a,0xb4,0x7d,0xce }, 
+    { 0x4a,0x18,0x63,0xdf }, { 0x31,0x82,0xe5,0x1a },
+    { 0x33,0x60,0x97,0x51 }, { 0x7f,0x45,0x62,0x53 }, 
+    { 0x77,0xe0,0xb1,0x64 }, { 0xae,0x84,0xbb,0x6b },
+    { 0xa0,0x1c,0xfe,0x81 }, { 0x2b,0x94,0xf9,0x08 }, 
+    { 0x68,0x58,0x70,0x48 }, { 0xfd,0x19,0x8f,0x45 },
+    { 0x6c,0x87,0x94,0xde }, { 0xf8,0xb7,0x52,0x7b }, 
+    { 0xd3,0x23,0xab,0x73 }, { 0x02,0xe2,0x72,0x4b },
+    { 0x8f,0x57,0xe3,0x1f }, { 0xab,0x2a,0x66,0x55 }, 
+    { 0x28,0x07,0xb2,0xeb }, { 0xc2,0x03,0x2f,0xb5 },
+    { 0x7b,0x9a,0x86,0xc5 }, { 0x08,0xa5,0xd3,0x37 }, 
+    { 0x87,0xf2,0x30,0x28 }, { 0xa5,0xb2,0x23,0xbf },
+    { 0x6a,0xba,0x02,0x03 }, { 0x82,0x5c,0xed,0x16 }, 
+    { 0x1c,0x2b,0x8a,0xcf }, { 0xb4,0x92,0xa7,0x79 }, 
+    { 0xf2,0xf0,0xf3,0x07 }, { 0xe2,0xa1,0x4e,0x69 }, 
+    { 0xf4,0xcd,0x65,0xda }, { 0xbe,0xd5,0x06,0x05 },
+    { 0x62,0x1f,0xd1,0x34 }, { 0xfe,0x8a,0xc4,0xa6 }, 
+    { 0x53,0x9d,0x34,0x2e }, { 0x55,0xa0,0xa2,0xf3 },
+    { 0xe1,0x32,0x05,0x8a }, { 0xeb,0x75,0xa4,0xf6 }, 
+    { 0xec,0x39,0x0b,0x83 }, { 0xef,0xaa,0x40,0x60 },
+    { 0x9f,0x06,0x5e,0x71 }, { 0x10,0x51,0xbd,0x6e }, 
+    { 0x8a,0xf9,0x3e,0x21 }, { 0x06,0x3d,0x96,0xdd },
+    { 0x05,0xae,0xdd,0x3e }, { 0xbd,0x46,0x4d,0xe6 }, 
+    { 0x8d,0xb5,0x91,0x54 }, { 0x5d,0x05,0x71,0xc4 },
+    { 0xd4,0x6f,0x04,0x06 }, { 0x15,0xff,0x60,0x50 }, 
+    { 0xfb,0x24,0x19,0x98 }, { 0xe9,0x97,0xd6,0xbd }, 
+    { 0x43,0xcc,0x89,0x40 }, { 0x9e,0x77,0x67,0xd9 }, 
+    { 0x42,0xbd,0xb0,0xe8 }, { 0x8b,0x88,0x07,0x89 },
+    { 0x5b,0x38,0xe7,0x19 }, { 0xee,0xdb,0x79,0xc8 }, 
+    { 0x0a,0x47,0xa1,0x7c }, { 0x0f,0xe9,0x7c,0x42 },
+    { 0x1e,0xc9,0xf8,0x84 }, { 0x00,0x00,0x00,0x00 }, 
+    { 0x86,0x83,0x09,0x80 }, { 0xed,0x48,0x32,0x2b },
+    { 0x70,0xac,0x1e,0x11 }, { 0x72,0x4e,0x6c,0x5a }, 
+    { 0xff,0xfb,0xfd,0x0e }, { 0x38,0x56,0x0f,0x85 },
+    { 0xd5,0x1e,0x3d,0xae }, { 0x39,0x27,0x36,0x2d }, 
+    { 0xd9,0x64,0x0a,0x0f }, { 0xa6,0x21,0x68,0x5c },
+    { 0x54,0xd1,0x9b,0x5b }, { 0x2e,0x3a,0x24,0x36 }, 
+    { 0x67,0xb1,0x0c,0x0a }, { 0xe7,0x0f,0x93,0x57 },
+    { 0x96,0xd2,0xb4,0xee }, { 0x91,0x9e,0x1b,0x9b }, 
+    { 0xc5,0x4f,0x80,0xc0 }, { 0x20,0xa2,0x61,0xdc },
+    { 0x4b,0x69,0x5a,0x77 }, { 0x1a,0x16,0x1c,0x12 }, 
+    { 0xba,0x0a,0xe2,0x93 }, { 0x2a,0xe5,0xc0,0xa0 },
+    { 0xe0,0x43,0x3c,0x22 }, { 0x17,0x1d,0x12,0x1b }, 
+    { 0x0d,0x0b,0x0e,0x09 }, { 0xc7,0xad,0xf2,0x8b },
+    { 0xa8,0xb9,0x2d,0xb6 }, { 0xa9,0xc8,0x14,0x1e }, 
+    { 0x19,0x85,0x57,0xf1 }, { 0x07,0x4c,0xaf,0x75 },
+    { 0xdd,0xbb,0xee,0x99 }, { 0x60,0xfd,0xa3,0x7f }, 
+    { 0x26,0x9f,0xf7,0x01 }, { 0xf5,0xbc,0x5c,0x72 },
+    { 0x3b,0xc5,0x44,0x66 }, { 0x7e,0x34,0x5b,0xfb }, 
+    { 0x29,0x76,0x8b,0x43 }, { 0xc6,0xdc,0xcb,0x23 },
+    { 0xfc,0x68,0xb6,0xed }, { 0xf1,0x63,0xb8,0xe4 }, 
+    { 0xdc,0xca,0xd7,0x31 }, { 0x85,0x10,0x42,0x63 },
+    { 0x22,0x40,0x13,0x97 }, { 0x11,0x20,0x84,0xc6 }, 
+    { 0x24,0x7d,0x85,0x4a }, { 0x3d,0xf8,0xd2,0xbb },
+    { 0x32,0x11,0xae,0xf9 }, { 0xa1,0x6d,0xc7,0x29 }, 
+    { 0x2f,0x4b,0x1d,0x9e }, { 0x30,0xf3,0xdc,0xb2 },
+    { 0x52,0xec,0x0d,0x86 }, { 0xe3,0xd0,0x77,0xc1 }, 
+    { 0x16,0x6c,0x2b,0xb3 }, { 0xb9,0x99,0xa9,0x70 },
+    { 0x48,0xfa,0x11,0x94 }, { 0x64,0x22,0x47,0xe9 }, 
+    { 0x8c,0xc4,0xa8,0xfc }, { 0x3f,0x1a,0xa0,0xf0 },
+    { 0x2c,0xd8,0x56,0x7d }, { 0x90,0xef,0x22,0x33 }, 
+    { 0x4e,0xc7,0x87,0x49 }, { 0xd1,0xc1,0xd9,0x38 },
+    { 0xa2,0xfe,0x8c,0xca }, { 0x0b,0x36,0x98,0xd4 }, 
+    { 0x81,0xcf,0xa6,0xf5 }, { 0xde,0x28,0xa5,0x7a },
+    { 0x8e,0x26,0xda,0xb7 }, { 0xbf,0xa4,0x3f,0xad }, 
+    { 0x9d,0xe4,0x2c,0x3a }, { 0x92,0x0d,0x50,0x78 },
+    { 0xcc,0x9b,0x6a,0x5f }, { 0x46,0x62,0x54,0x7e }, 
+    { 0x13,0xc2,0xf6,0x8d }, { 0xb8,0xe8,0x90,0xd8 },
+    { 0xf7,0x5e,0x2e,0x39 }, { 0xaf,0xf5,0x82,0xc3 }, 
+    { 0x80,0xbe,0x9f,0x5d }, { 0x93,0x7c,0x69,0xd0 },
+    { 0x2d,0xa9,0x6f,0xd5 }, { 0x12,0xb3,0xcf,0x25 }, 
+    { 0x99,0x3b,0xc8,0xac }, { 0x7d,0xa7,0x10,0x18 },
+    { 0x63,0x6e,0xe8,0x9c }, { 0xbb,0x7b,0xdb,0x3b }, 
+    { 0x78,0x09,0xcd,0x26 }, { 0x18,0xf4,0x6e,0x59 }, 
+    { 0xb7,0x01,0xec,0x9a }, { 0x9a,0xa8,0x83,0x4f }, 
+    { 0x6e,0x65,0xe6,0x95 }, { 0xe6,0x7e,0xaa,0xff },
+    { 0xcf,0x08,0x21,0xbc }, { 0xe8,0xe6,0xef,0x15 }, 
+    { 0x9b,0xd9,0xba,0xe7 }, { 0x36,0xce,0x4a,0x6f },
+    { 0x09,0xd4,0xea,0x9f }, { 0x7c,0xd6,0x29,0xb0 }, 
+    { 0xb2,0xaf,0x31,0xa4 }, { 0x23,0x31,0x2a,0x3f },
+    { 0x94,0x30,0xc6,0xa5 }, { 0x66,0xc0,0x35,0xa2 }, 
+    { 0xbc,0x37,0x74,0x4e }, { 0xca,0xa6,0xfc,0x82 },
+    { 0xd0,0xb0,0xe0,0x90 }, { 0xd8,0x15,0x33,0xa7 }, 
+    { 0x98,0x4a,0xf1,0x04 }, { 0xda,0xf7,0x41,0xec },
+    { 0x50,0x0e,0x7f,0xcd }, { 0xf6,0x2f,0x17,0x91 }, 
+    { 0xd6,0x8d,0x76,0x4d }, { 0xb0,0x4d,0x43,0xef }, 
+    { 0x4d,0x54,0xcc,0xaa }, { 0x04,0xdf,0xe4,0x96 }, 
+    { 0xb5,0xe3,0x9e,0xd1 }, { 0x88,0x1b,0x4c,0x6a },
+    { 0x1f,0xb8,0xc1,0x2c }, { 0x51,0x7f,0x46,0x65 }, 
+    { 0xea,0x04,0x9d,0x5e }, { 0x35,0x5d,0x01,0x8c },
+    { 0x74,0x73,0xfa,0x87 }, { 0x41,0x2e,0xfb,0x0b }, 
+    { 0x1d,0x5a,0xb3,0x67 }, { 0xd2,0x52,0x92,0xdb },
+    { 0x56,0x33,0xe9,0x10 }, { 0x47,0x13,0x6d,0xd6 }, 
+    { 0x61,0x8c,0x9a,0xd7 }, { 0x0c,0x7a,0x37,0xa1 },
+    { 0x14,0x8e,0x59,0xf8 }, { 0x3c,0x89,0xeb,0x13 }, 
+    { 0x27,0xee,0xce,0xa9 }, { 0xc9,0x35,0xb7,0x61 },
+    { 0xe5,0xed,0xe1,0x1c }, { 0xb1,0x3c,0x7a,0x47 }, 
+    { 0xdf,0x59,0x9c,0xd2 }, { 0x73,0x3f,0x55,0xf2 },
+    { 0xce,0x79,0x18,0x14 }, { 0x37,0xbf,0x73,0xc7 }, 
+    { 0xcd,0xea,0x53,0xf7 }, { 0xaa,0x5b,0x5f,0xfd },
+    { 0x6f,0x14,0xdf,0x3d }, { 0xdb,0x86,0x78,0x44 }, 
+    { 0xf3,0x81,0xca,0xaf }, { 0xc4,0x3e,0xb9,0x68 },
+    { 0x34,0x2c,0x38,0x24 }, { 0x40,0x5f,0xc2,0xa3 }, 
+    { 0xc3,0x72,0x16,0x1d }, { 0x25,0x0c,0xbc,0xe2 },
+    { 0x49,0x8b,0x28,0x3c }, { 0x95,0x41,0xff,0x0d }, 
+    { 0x01,0x71,0x39,0xa8 }, { 0xb3,0xde,0x08,0x0c },
+    { 0xe4,0x9c,0xd8,0xb4 }, { 0xc1,0x90,0x64,0x56 }, 
+    { 0x84,0x61,0x7b,0xcb }, { 0xb6,0x70,0xd5,0x32 },
+    { 0x5c,0x74,0x48,0x6c }, { 0x57,0x42,0xd0,0xb8 }
+  };
+
+static const unsigned char T8[256][4] = 
+  {
+    { 0xf4,0xa7,0x50,0x51 }, { 0x41,0x65,0x53,0x7e },
+    { 0x17,0xa4,0xc3,0x1a }, { 0x27,0x5e,0x96,0x3a }, 
+    { 0xab,0x6b,0xcb,0x3b }, { 0x9d,0x45,0xf1,0x1f },
+    { 0xfa,0x58,0xab,0xac }, { 0xe3,0x03,0x93,0x4b }, 
+    { 0x30,0xfa,0x55,0x20 }, { 0x76,0x6d,0xf6,0xad },
+    { 0xcc,0x76,0x91,0x88 }, { 0x02,0x4c,0x25,0xf5 }, 
+    { 0xe5,0xd7,0xfc,0x4f }, { 0x2a,0xcb,0xd7,0xc5 },
+    { 0x35,0x44,0x80,0x26 }, { 0x62,0xa3,0x8f,0xb5 }, 
+    { 0xb1,0x5a,0x49,0xde }, { 0xba,0x1b,0x67,0x25 },
+    { 0xea,0x0e,0x98,0x45 }, { 0xfe,0xc0,0xe1,0x5d }, 
+    { 0x2f,0x75,0x02,0xc3 }, { 0x4c,0xf0,0x12,0x81 },
+    { 0x46,0x97,0xa3,0x8d }, { 0xd3,0xf9,0xc6,0x6b }, 
+    { 0x8f,0x5f,0xe7,0x03 }, { 0x92,0x9c,0x95,0x15 },
+    { 0x6d,0x7a,0xeb,0xbf }, { 0x52,0x59,0xda,0x95 }, 
+    { 0xbe,0x83,0x2d,0xd4 }, { 0x74,0x21,0xd3,0x58 },
+    { 0xe0,0x69,0x29,0x49 }, { 0xc9,0xc8,0x44,0x8e }, 
+    { 0xc2,0x89,0x6a,0x75 }, { 0x8e,0x79,0x78,0xf4 },
+    { 0x58,0x3e,0x6b,0x99 }, { 0xb9,0x71,0xdd,0x27 }, 
+    { 0xe1,0x4f,0xb6,0xbe }, { 0x88,0xad,0x17,0xf0 },
+    { 0x20,0xac,0x66,0xc9 }, { 0xce,0x3a,0xb4,0x7d }, 
+    { 0xdf,0x4a,0x18,0x63 }, { 0x1a,0x31,0x82,0xe5 },
+    { 0x51,0x33,0x60,0x97 }, { 0x53,0x7f,0x45,0x62 }, 
+    { 0x64,0x77,0xe0,0xb1 }, { 0x6b,0xae,0x84,0xbb },
+    { 0x81,0xa0,0x1c,0xfe }, { 0x08,0x2b,0x94,0xf9 }, 
+    { 0x48,0x68,0x58,0x70 }, { 0x45,0xfd,0x19,0x8f },
+    { 0xde,0x6c,0x87,0x94 }, { 0x7b,0xf8,0xb7,0x52 }, 
+    { 0x73,0xd3,0x23,0xab }, { 0x4b,0x02,0xe2,0x72 },
+    { 0x1f,0x8f,0x57,0xe3 }, { 0x55,0xab,0x2a,0x66 }, 
+    { 0xeb,0x28,0x07,0xb2 }, { 0xb5,0xc2,0x03,0x2f },
+    { 0xc5,0x7b,0x9a,0x86 }, { 0x37,0x08,0xa5,0xd3 }, 
+    { 0x28,0x87,0xf2,0x30 }, { 0xbf,0xa5,0xb2,0x23 },
+    { 0x03,0x6a,0xba,0x02 }, { 0x16,0x82,0x5c,0xed }, 
+    { 0xcf,0x1c,0x2b,0x8a }, { 0x79,0xb4,0x92,0xa7 },
+    { 0x07,0xf2,0xf0,0xf3 }, { 0x69,0xe2,0xa1,0x4e }, 
+    { 0xda,0xf4,0xcd,0x65 }, { 0x05,0xbe,0xd5,0x06 },
+    { 0x34,0x62,0x1f,0xd1 }, { 0xa6,0xfe,0x8a,0xc4 }, 
+    { 0x2e,0x53,0x9d,0x34 }, { 0xf3,0x55,0xa0,0xa2 },
+    { 0x8a,0xe1,0x32,0x05 }, { 0xf6,0xeb,0x75,0xa4 }, 
+    { 0x83,0xec,0x39,0x0b }, { 0x60,0xef,0xaa,0x40 },
+    { 0x71,0x9f,0x06,0x5e }, { 0x6e,0x10,0x51,0xbd }, 
+    { 0x21,0x8a,0xf9,0x3e }, { 0xdd,0x06,0x3d,0x96 },
+    { 0x3e,0x05,0xae,0xdd }, { 0xe6,0xbd,0x46,0x4d }, 
+    { 0x54,0x8d,0xb5,0x91 }, { 0xc4,0x5d,0x05,0x71 },
+    { 0x06,0xd4,0x6f,0x04 }, { 0x50,0x15,0xff,0x60 }, 
+    { 0x98,0xfb,0x24,0x19 }, { 0xbd,0xe9,0x97,0xd6 },
+    { 0x40,0x43,0xcc,0x89 }, { 0xd9,0x9e,0x77,0x67 }, 
+    { 0xe8,0x42,0xbd,0xb0 }, { 0x89,0x8b,0x88,0x07 },
+    { 0x19,0x5b,0x38,0xe7 }, { 0xc8,0xee,0xdb,0x79 }, 
+    { 0x7c,0x0a,0x47,0xa1 }, { 0x42,0x0f,0xe9,0x7c },
+    { 0x84,0x1e,0xc9,0xf8 }, { 0x00,0x00,0x00,0x00 }, 
+    { 0x80,0x86,0x83,0x09 }, { 0x2b,0xed,0x48,0x32 },
+    { 0x11,0x70,0xac,0x1e }, { 0x5a,0x72,0x4e,0x6c }, 
+    { 0x0e,0xff,0xfb,0xfd }, { 0x85,0x38,0x56,0x0f }, 
+    { 0xae,0xd5,0x1e,0x3d }, { 0x2d,0x39,0x27,0x36 }, 
+    { 0x0f,0xd9,0x64,0x0a }, { 0x5c,0xa6,0x21,0x68 },
+    { 0x5b,0x54,0xd1,0x9b }, { 0x36,0x2e,0x3a,0x24 }, 
+    { 0x0a,0x67,0xb1,0x0c }, { 0x57,0xe7,0x0f,0x93 },
+    { 0xee,0x96,0xd2,0xb4 }, { 0x9b,0x91,0x9e,0x1b }, 
+    { 0xc0,0xc5,0x4f,0x80 }, { 0xdc,0x20,0xa2,0x61 },
+    { 0x77,0x4b,0x69,0x5a }, { 0x12,0x1a,0x16,0x1c }, 
+    { 0x93,0xba,0x0a,0xe2 }, { 0xa0,0x2a,0xe5,0xc0 },
+    { 0x22,0xe0,0x43,0x3c }, { 0x1b,0x17,0x1d,0x12 }, 
+    { 0x09,0x0d,0x0b,0x0e }, { 0x8b,0xc7,0xad,0xf2 },
+    { 0xb6,0xa8,0xb9,0x2d }, { 0x1e,0xa9,0xc8,0x14 }, 
+    { 0xf1,0x19,0x85,0x57 }, { 0x75,0x07,0x4c,0xaf },
+    { 0x99,0xdd,0xbb,0xee }, { 0x7f,0x60,0xfd,0xa3 }, 
+    { 0x01,0x26,0x9f,0xf7 }, { 0x72,0xf5,0xbc,0x5c },
+    { 0x66,0x3b,0xc5,0x44 }, { 0xfb,0x7e,0x34,0x5b }, 
+    { 0x43,0x29,0x76,0x8b }, { 0x23,0xc6,0xdc,0xcb },
+    { 0xed,0xfc,0x68,0xb6 }, { 0xe4,0xf1,0x63,0xb8 }, 
+    { 0x31,0xdc,0xca,0xd7 }, { 0x63,0x85,0x10,0x42 },
+    { 0x97,0x22,0x40,0x13 }, { 0xc6,0x11,0x20,0x84 }, 
+    { 0x4a,0x24,0x7d,0x85 }, { 0xbb,0x3d,0xf8,0xd2 }, 
+    { 0xf9,0x32,0x11,0xae }, { 0x29,0xa1,0x6d,0xc7 }, 
+    { 0x9e,0x2f,0x4b,0x1d }, { 0xb2,0x30,0xf3,0xdc },
+    { 0x86,0x52,0xec,0x0d }, { 0xc1,0xe3,0xd0,0x77 }, 
+    { 0xb3,0x16,0x6c,0x2b }, { 0x70,0xb9,0x99,0xa9 },
+    { 0x94,0x48,0xfa,0x11 }, { 0xe9,0x64,0x22,0x47 }, 
+    { 0xfc,0x8c,0xc4,0xa8 }, { 0xf0,0x3f,0x1a,0xa0 },
+    { 0x7d,0x2c,0xd8,0x56 }, { 0x33,0x90,0xef,0x22 }, 
+    { 0x49,0x4e,0xc7,0x87 }, { 0x38,0xd1,0xc1,0xd9 },
+    { 0xca,0xa2,0xfe,0x8c }, { 0xd4,0x0b,0x36,0x98 }, 
+    { 0xf5,0x81,0xcf,0xa6 }, { 0x7a,0xde,0x28,0xa5 },
+    { 0xb7,0x8e,0x26,0xda }, { 0xad,0xbf,0xa4,0x3f }, 
+    { 0x3a,0x9d,0xe4,0x2c }, { 0x78,0x92,0x0d,0x50 },
+    { 0x5f,0xcc,0x9b,0x6a }, { 0x7e,0x46,0x62,0x54 }, 
+    { 0x8d,0x13,0xc2,0xf6 }, { 0xd8,0xb8,0xe8,0x90 },
+    { 0x39,0xf7,0x5e,0x2e }, { 0xc3,0xaf,0xf5,0x82 }, 
+    { 0x5d,0x80,0xbe,0x9f }, { 0xd0,0x93,0x7c,0x69 },
+    { 0xd5,0x2d,0xa9,0x6f }, { 0x25,0x12,0xb3,0xcf }, 
+    { 0xac,0x99,0x3b,0xc8 }, { 0x18,0x7d,0xa7,0x10 },
+    { 0x9c,0x63,0x6e,0xe8 }, { 0x3b,0xbb,0x7b,0xdb }, 
+    { 0x26,0x78,0x09,0xcd }, { 0x59,0x18,0xf4,0x6e },
+    { 0x9a,0xb7,0x01,0xec }, { 0x4f,0x9a,0xa8,0x83 }, 
+    { 0x95,0x6e,0x65,0xe6 }, { 0xff,0xe6,0x7e,0xaa },
+    { 0xbc,0xcf,0x08,0x21 }, { 0x15,0xe8,0xe6,0xef }, 
+    { 0xe7,0x9b,0xd9,0xba }, { 0x6f,0x36,0xce,0x4a },
+    { 0x9f,0x09,0xd4,0xea }, { 0xb0,0x7c,0xd6,0x29 }, 
+    { 0xa4,0xb2,0xaf,0x31 }, { 0x3f,0x23,0x31,0x2a },
+    { 0xa5,0x94,0x30,0xc6 }, { 0xa2,0x66,0xc0,0x35 }, 
+    { 0x4e,0xbc,0x37,0x74 }, { 0x82,0xca,0xa6,0xfc },
+    { 0x90,0xd0,0xb0,0xe0 }, { 0xa7,0xd8,0x15,0x33 }, 
+    { 0x04,0x98,0x4a,0xf1 }, { 0xec,0xda,0xf7,0x41 },
+    { 0xcd,0x50,0x0e,0x7f }, { 0x91,0xf6,0x2f,0x17 }, 
+    { 0x4d,0xd6,0x8d,0x76 }, { 0xef,0xb0,0x4d,0x43 }, 
+    { 0xaa,0x4d,0x54,0xcc }, { 0x96,0x04,0xdf,0xe4 }, 
+    { 0xd1,0xb5,0xe3,0x9e }, { 0x6a,0x88,0x1b,0x4c },
+    { 0x2c,0x1f,0xb8,0xc1 }, { 0x65,0x51,0x7f,0x46 }, 
+    { 0x5e,0xea,0x04,0x9d }, { 0x8c,0x35,0x5d,0x01 },
+    { 0x87,0x74,0x73,0xfa }, { 0x0b,0x41,0x2e,0xfb }, 
+    { 0x67,0x1d,0x5a,0xb3 }, { 0xdb,0xd2,0x52,0x92 },
+    { 0x10,0x56,0x33,0xe9 }, { 0xd6,0x47,0x13,0x6d }, 
+    { 0xd7,0x61,0x8c,0x9a }, { 0xa1,0x0c,0x7a,0x37 },
+    { 0xf8,0x14,0x8e,0x59 }, { 0x13,0x3c,0x89,0xeb }, 
+    { 0xa9,0x27,0xee,0xce }, { 0x61,0xc9,0x35,0xb7 },
+    { 0x1c,0xe5,0xed,0xe1 }, { 0x47,0xb1,0x3c,0x7a }, 
+    { 0xd2,0xdf,0x59,0x9c }, { 0xf2,0x73,0x3f,0x55 },
+    { 0x14,0xce,0x79,0x18 }, { 0xc7,0x37,0xbf,0x73 }, 
+    { 0xf7,0xcd,0xea,0x53 }, { 0xfd,0xaa,0x5b,0x5f },
+    { 0x3d,0x6f,0x14,0xdf }, { 0x44,0xdb,0x86,0x78 }, 
+    { 0xaf,0xf3,0x81,0xca }, { 0x68,0xc4,0x3e,0xb9 },
+    { 0x24,0x34,0x2c,0x38 }, { 0xa3,0x40,0x5f,0xc2 }, 
+    { 0x1d,0xc3,0x72,0x16 }, { 0xe2,0x25,0x0c,0xbc },
+    { 0x3c,0x49,0x8b,0x28 }, { 0x0d,0x95,0x41,0xff }, 
+    { 0xa8,0x01,0x71,0x39 }, { 0x0c,0xb3,0xde,0x08 },
+    { 0xb4,0xe4,0x9c,0xd8 }, { 0x56,0xc1,0x90,0x64 }, 
+    { 0xcb,0x84,0x61,0x7b }, { 0x32,0xb6,0x70,0xd5 },
+    { 0x6c,0x5c,0x74,0x48 }, { 0xb8,0x57,0x42,0xd0 }
+  };
+
+static const unsigned char S5[256] = 
+  {
+    0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,
+    0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
+    0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,
+    0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
+    0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,
+    0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
+    0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,
+    0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
+    0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,
+    0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
+    0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,
+    0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
+    0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,
+    0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
+    0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,
+    0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
+    0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,
+    0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
+    0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,
+    0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
+    0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,
+    0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
+    0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,
+    0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
+    0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,
+    0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
+    0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,
+    0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
+    0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,
+    0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
+    0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,
+    0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
+  };
+
+static const unsigned char U1[256][4] = 
+  {
+    { 0x00,0x00,0x00,0x00 }, { 0x0e,0x09,0x0d,0x0b },
+    { 0x1c,0x12,0x1a,0x16 }, { 0x12,0x1b,0x17,0x1d }, 
+    { 0x38,0x24,0x34,0x2c }, { 0x36,0x2d,0x39,0x27 },
+    { 0x24,0x36,0x2e,0x3a }, { 0x2a,0x3f,0x23,0x31 }, 
+    { 0x70,0x48,0x68,0x58 }, { 0x7e,0x41,0x65,0x53 },
+    { 0x6c,0x5a,0x72,0x4e }, { 0x62,0x53,0x7f,0x45 }, 
+    { 0x48,0x6c,0x5c,0x74 }, { 0x46,0x65,0x51,0x7f },
+    { 0x54,0x7e,0x46,0x62 }, { 0x5a,0x77,0x4b,0x69 }, 
+    { 0xe0,0x90,0xd0,0xb0 }, { 0xee,0x99,0xdd,0xbb },
+    { 0xfc,0x82,0xca,0xa6 }, { 0xf2,0x8b,0xc7,0xad }, 
+    { 0xd8,0xb4,0xe4,0x9c }, { 0xd6,0xbd,0xe9,0x97 },
+    { 0xc4,0xa6,0xfe,0x8a }, { 0xca,0xaf,0xf3,0x81 }, 
+    { 0x90,0xd8,0xb8,0xe8 }, { 0x9e,0xd1,0xb5,0xe3 },
+    { 0x8c,0xca,0xa2,0xfe }, { 0x82,0xc3,0xaf,0xf5 }, 
+    { 0xa8,0xfc,0x8c,0xc4 }, { 0xa6,0xf5,0x81,0xcf },
+    { 0xb4,0xee,0x96,0xd2 }, { 0xba,0xe7,0x9b,0xd9 }, 
+    { 0xdb,0x3b,0xbb,0x7b }, { 0xd5,0x32,0xb6,0x70 },
+    { 0xc7,0x29,0xa1,0x6d }, { 0xc9,0x20,0xac,0x66 }, 
+    { 0xe3,0x1f,0x8f,0x57 }, { 0xed,0x16,0x82,0x5c },
+    { 0xff,0x0d,0x95,0x41 }, { 0xf1,0x04,0x98,0x4a }, 
+    { 0xab,0x73,0xd3,0x23 }, { 0xa5,0x7a,0xde,0x28 },
+    { 0xb7,0x61,0xc9,0x35 }, { 0xb9,0x68,0xc4,0x3e }, 
+    { 0x93,0x57,0xe7,0x0f }, { 0x9d,0x5e,0xea,0x04 },
+    { 0x8f,0x45,0xfd,0x19 }, { 0x81,0x4c,0xf0,0x12 }, 
+    { 0x3b,0xab,0x6b,0xcb }, { 0x35,0xa2,0x66,0xc0 },
+    { 0x27,0xb9,0x71,0xdd }, { 0x29,0xb0,0x7c,0xd6 }, 
+    { 0x03,0x8f,0x5f,0xe7 }, { 0x0d,0x86,0x52,0xec },
+    { 0x1f,0x9d,0x45,0xf1 }, { 0x11,0x94,0x48,0xfa }, 
+    { 0x4b,0xe3,0x03,0x93 }, { 0x45,0xea,0x0e,0x98 },
+    { 0x57,0xf1,0x19,0x85 }, { 0x59,0xf8,0x14,0x8e }, 
+    { 0x73,0xc7,0x37,0xbf }, { 0x7d,0xce,0x3a,0xb4 },
+    { 0x6f,0xd5,0x2d,0xa9 }, { 0x61,0xdc,0x20,0xa2 }, 
+    { 0xad,0x76,0x6d,0xf6 }, { 0xa3,0x7f,0x60,0xfd },
+    { 0xb1,0x64,0x77,0xe0 }, { 0xbf,0x6d,0x7a,0xeb }, 
+    { 0x95,0x52,0x59,0xda }, { 0x9b,0x5b,0x54,0xd1 },
+    { 0x89,0x40,0x43,0xcc }, { 0x87,0x49,0x4e,0xc7 }, 
+    { 0xdd,0x3e,0x05,0xae }, { 0xd3,0x37,0x08,0xa5 },
+    { 0xc1,0x2c,0x1f,0xb8 }, { 0xcf,0x25,0x12,0xb3 }, 
+    { 0xe5,0x1a,0x31,0x82 }, { 0xeb,0x13,0x3c,0x89 },
+    { 0xf9,0x08,0x2b,0x94 }, { 0xf7,0x01,0x26,0x9f }, 
+    { 0x4d,0xe6,0xbd,0x46 }, { 0x43,0xef,0xb0,0x4d },
+    { 0x51,0xf4,0xa7,0x50 }, { 0x5f,0xfd,0xaa,0x5b }, 
+    { 0x75,0xc2,0x89,0x6a }, { 0x7b,0xcb,0x84,0x61 },
+    { 0x69,0xd0,0x93,0x7c }, { 0x67,0xd9,0x9e,0x77 }, 
+    { 0x3d,0xae,0xd5,0x1e }, { 0x33,0xa7,0xd8,0x15 },
+    { 0x21,0xbc,0xcf,0x08 }, { 0x2f,0xb5,0xc2,0x03 }, 
+    { 0x05,0x8a,0xe1,0x32 }, { 0x0b,0x83,0xec,0x39 },
+    { 0x19,0x98,0xfb,0x24 }, { 0x17,0x91,0xf6,0x2f }, 
+    { 0x76,0x4d,0xd6,0x8d }, { 0x78,0x44,0xdb,0x86 },
+    { 0x6a,0x5f,0xcc,0x9b }, { 0x64,0x56,0xc1,0x90 }, 
+    { 0x4e,0x69,0xe2,0xa1 }, { 0x40,0x60,0xef,0xaa },
+    { 0x52,0x7b,0xf8,0xb7 }, { 0x5c,0x72,0xf5,0xbc }, 
+    { 0x06,0x05,0xbe,0xd5 }, { 0x08,0x0c,0xb3,0xde },
+    { 0x1a,0x17,0xa4,0xc3 }, { 0x14,0x1e,0xa9,0xc8 }, 
+    { 0x3e,0x21,0x8a,0xf9 }, { 0x30,0x28,0x87,0xf2 },
+    { 0x22,0x33,0x90,0xef }, { 0x2c,0x3a,0x9d,0xe4 }, 
+    { 0x96,0xdd,0x06,0x3d }, { 0x98,0xd4,0x0b,0x36 },
+    { 0x8a,0xcf,0x1c,0x2b }, { 0x84,0xc6,0x11,0x20 }, 
+    { 0xae,0xf9,0x32,0x11 }, { 0xa0,0xf0,0x3f,0x1a },
+    { 0xb2,0xeb,0x28,0x07 }, { 0xbc,0xe2,0x25,0x0c }, 
+    { 0xe6,0x95,0x6e,0x65 }, { 0xe8,0x9c,0x63,0x6e },
+    { 0xfa,0x87,0x74,0x73 }, { 0xf4,0x8e,0x79,0x78 }, 
+    { 0xde,0xb1,0x5a,0x49 }, { 0xd0,0xb8,0x57,0x42 },
+    { 0xc2,0xa3,0x40,0x5f }, { 0xcc,0xaa,0x4d,0x54 }, 
+    { 0x41,0xec,0xda,0xf7 }, { 0x4f,0xe5,0xd7,0xfc },
+    { 0x5d,0xfe,0xc0,0xe1 }, { 0x53,0xf7,0xcd,0xea }, 
+    { 0x79,0xc8,0xee,0xdb }, { 0x77,0xc1,0xe3,0xd0 },
+    { 0x65,0xda,0xf4,0xcd }, { 0x6b,0xd3,0xf9,0xc6 }, 
+    { 0x31,0xa4,0xb2,0xaf }, { 0x3f,0xad,0xbf,0xa4 },
+    { 0x2d,0xb6,0xa8,0xb9 }, { 0x23,0xbf,0xa5,0xb2 }, 
+    { 0x09,0x80,0x86,0x83 }, { 0x07,0x89,0x8b,0x88 },
+    { 0x15,0x92,0x9c,0x95 }, { 0x1b,0x9b,0x91,0x9e }, 
+    { 0xa1,0x7c,0x0a,0x47 }, { 0xaf,0x75,0x07,0x4c },
+    { 0xbd,0x6e,0x10,0x51 }, { 0xb3,0x67,0x1d,0x5a }, 
+    { 0x99,0x58,0x3e,0x6b }, { 0x97,0x51,0x33,0x60 },
+    { 0x85,0x4a,0x24,0x7d }, { 0x8b,0x43,0x29,0x76 }, 
+    { 0xd1,0x34,0x62,0x1f }, { 0xdf,0x3d,0x6f,0x14 },
+    { 0xcd,0x26,0x78,0x09 }, { 0xc3,0x2f,0x75,0x02 }, 
+    { 0xe9,0x10,0x56,0x33 }, { 0xe7,0x19,0x5b,0x38 },
+    { 0xf5,0x02,0x4c,0x25 }, { 0xfb,0x0b,0x41,0x2e }, 
+    { 0x9a,0xd7,0x61,0x8c }, { 0x94,0xde,0x6c,0x87 }, 
+    { 0x86,0xc5,0x7b,0x9a }, { 0x88,0xcc,0x76,0x91 }, 
+    { 0xa2,0xf3,0x55,0xa0 }, { 0xac,0xfa,0x58,0xab },
+    { 0xbe,0xe1,0x4f,0xb6 }, { 0xb0,0xe8,0x42,0xbd }, 
+    { 0xea,0x9f,0x09,0xd4 }, { 0xe4,0x96,0x04,0xdf },
+    { 0xf6,0x8d,0x13,0xc2 }, { 0xf8,0x84,0x1e,0xc9 }, 
+    { 0xd2,0xbb,0x3d,0xf8 }, { 0xdc,0xb2,0x30,0xf3 },
+    { 0xce,0xa9,0x27,0xee }, { 0xc0,0xa0,0x2a,0xe5 }, 
+    { 0x7a,0x47,0xb1,0x3c }, { 0x74,0x4e,0xbc,0x37 }, 
+    { 0x66,0x55,0xab,0x2a }, { 0x68,0x5c,0xa6,0x21 }, 
+    { 0x42,0x63,0x85,0x10 }, { 0x4c,0x6a,0x88,0x1b },
+    { 0x5e,0x71,0x9f,0x06 }, { 0x50,0x78,0x92,0x0d }, 
+    { 0x0a,0x0f,0xd9,0x64 }, { 0x04,0x06,0xd4,0x6f },
+    { 0x16,0x1d,0xc3,0x72 }, { 0x18,0x14,0xce,0x79 }, 
+    { 0x32,0x2b,0xed,0x48 }, { 0x3c,0x22,0xe0,0x43 },
+    { 0x2e,0x39,0xf7,0x5e }, { 0x20,0x30,0xfa,0x55 }, 
+    { 0xec,0x9a,0xb7,0x01 }, { 0xe2,0x93,0xba,0x0a },
+    { 0xf0,0x88,0xad,0x17 }, { 0xfe,0x81,0xa0,0x1c }, 
+    { 0xd4,0xbe,0x83,0x2d }, { 0xda,0xb7,0x8e,0x26 },
+    { 0xc8,0xac,0x99,0x3b }, { 0xc6,0xa5,0x94,0x30 }, 
+    { 0x9c,0xd2,0xdf,0x59 }, { 0x92,0xdb,0xd2,0x52 },
+    { 0x80,0xc0,0xc5,0x4f }, { 0x8e,0xc9,0xc8,0x44 }, 
+    { 0xa4,0xf6,0xeb,0x75 }, { 0xaa,0xff,0xe6,0x7e },
+    { 0xb8,0xe4,0xf1,0x63 }, { 0xb6,0xed,0xfc,0x68 }, 
+    { 0x0c,0x0a,0x67,0xb1 }, { 0x02,0x03,0x6a,0xba },
+    { 0x10,0x18,0x7d,0xa7 }, { 0x1e,0x11,0x70,0xac }, 
+    { 0x34,0x2e,0x53,0x9d }, { 0x3a,0x27,0x5e,0x96 },
+    { 0x28,0x3c,0x49,0x8b }, { 0x26,0x35,0x44,0x80 }, 
+    { 0x7c,0x42,0x0f,0xe9 }, { 0x72,0x4b,0x02,0xe2 },
+    { 0x60,0x50,0x15,0xff }, { 0x6e,0x59,0x18,0xf4 }, 
+    { 0x44,0x66,0x3b,0xc5 }, { 0x4a,0x6f,0x36,0xce },
+    { 0x58,0x74,0x21,0xd3 }, { 0x56,0x7d,0x2c,0xd8 }, 
+    { 0x37,0xa1,0x0c,0x7a }, { 0x39,0xa8,0x01,0x71 },
+    { 0x2b,0xb3,0x16,0x6c }, { 0x25,0xba,0x1b,0x67 }, 
+    { 0x0f,0x85,0x38,0x56 }, { 0x01,0x8c,0x35,0x5d },
+    { 0x13,0x97,0x22,0x40 }, { 0x1d,0x9e,0x2f,0x4b }, 
+    { 0x47,0xe9,0x64,0x22 }, { 0x49,0xe0,0x69,0x29 },
+    { 0x5b,0xfb,0x7e,0x34 }, { 0x55,0xf2,0x73,0x3f }, 
+    { 0x7f,0xcd,0x50,0x0e }, { 0x71,0xc4,0x5d,0x05 },
+    { 0x63,0xdf,0x4a,0x18 }, { 0x6d,0xd6,0x47,0x13 }, 
+    { 0xd7,0x31,0xdc,0xca }, { 0xd9,0x38,0xd1,0xc1 },
+    { 0xcb,0x23,0xc6,0xdc }, { 0xc5,0x2a,0xcb,0xd7 }, 
+    { 0xef,0x15,0xe8,0xe6 }, { 0xe1,0x1c,0xe5,0xed },
+    { 0xf3,0x07,0xf2,0xf0 }, { 0xfd,0x0e,0xff,0xfb }, 
+    { 0xa7,0x79,0xb4,0x92 }, { 0xa9,0x70,0xb9,0x99 },
+    { 0xbb,0x6b,0xae,0x84 }, { 0xb5,0x62,0xa3,0x8f }, 
+    { 0x9f,0x5d,0x80,0xbe }, { 0x91,0x54,0x8d,0xb5 },
+    { 0x83,0x4f,0x9a,0xa8 }, { 0x8d,0x46,0x97,0xa3 }
+  };
+
+static const unsigned char U2[256][4] = 
+  {
+    { 0x00,0x00,0x00,0x00 }, { 0x0b,0x0e,0x09,0x0d },
+    { 0x16,0x1c,0x12,0x1a }, { 0x1d,0x12,0x1b,0x17 }, 
+    { 0x2c,0x38,0x24,0x34 }, { 0x27,0x36,0x2d,0x39 },
+    { 0x3a,0x24,0x36,0x2e }, { 0x31,0x2a,0x3f,0x23 }, 
+    { 0x58,0x70,0x48,0x68 }, { 0x53,0x7e,0x41,0x65 }, 
+    { 0x4e,0x6c,0x5a,0x72 }, { 0x45,0x62,0x53,0x7f }, 
+    { 0x74,0x48,0x6c,0x5c }, { 0x7f,0x46,0x65,0x51 },
+    { 0x62,0x54,0x7e,0x46 }, { 0x69,0x5a,0x77,0x4b }, 
+    { 0xb0,0xe0,0x90,0xd0 }, { 0xbb,0xee,0x99,0xdd }, 
+    { 0xa6,0xfc,0x82,0xca }, { 0xad,0xf2,0x8b,0xc7 }, 
+    { 0x9c,0xd8,0xb4,0xe4 }, { 0x97,0xd6,0xbd,0xe9 }, 
+    { 0x8a,0xc4,0xa6,0xfe }, { 0x81,0xca,0xaf,0xf3 }, 
+    { 0xe8,0x90,0xd8,0xb8 }, { 0xe3,0x9e,0xd1,0xb5 },
+    { 0xfe,0x8c,0xca,0xa2 }, { 0xf5,0x82,0xc3,0xaf }, 
+    { 0xc4,0xa8,0xfc,0x8c }, { 0xcf,0xa6,0xf5,0x81 }, 
+    { 0xd2,0xb4,0xee,0x96 }, { 0xd9,0xba,0xe7,0x9b }, 
+    { 0x7b,0xdb,0x3b,0xbb }, { 0x70,0xd5,0x32,0xb6 }, 
+    { 0x6d,0xc7,0x29,0xa1 }, { 0x66,0xc9,0x20,0xac }, 
+    { 0x57,0xe3,0x1f,0x8f }, { 0x5c,0xed,0x16,0x82 }, 
+    { 0x41,0xff,0x0d,0x95 }, { 0x4a,0xf1,0x04,0x98 }, 
+    { 0x23,0xab,0x73,0xd3 }, { 0x28,0xa5,0x7a,0xde },
+    { 0x35,0xb7,0x61,0xc9 }, { 0x3e,0xb9,0x68,0xc4 }, 
+    { 0x0f,0x93,0x57,0xe7 }, { 0x04,0x9d,0x5e,0xea },
+    { 0x19,0x8f,0x45,0xfd }, { 0x12,0x81,0x4c,0xf0 }, 
+    { 0xcb,0x3b,0xab,0x6b }, { 0xc0,0x35,0xa2,0x66 },
+    { 0xdd,0x27,0xb9,0x71 }, { 0xd6,0x29,0xb0,0x7c }, 
+    { 0xe7,0x03,0x8f,0x5f }, { 0xec,0x0d,0x86,0x52 },
+    { 0xf1,0x1f,0x9d,0x45 }, { 0xfa,0x11,0x94,0x48 }, 
+    { 0x93,0x4b,0xe3,0x03 }, { 0x98,0x45,0xea,0x0e }, 
+    { 0x85,0x57,0xf1,0x19 }, { 0x8e,0x59,0xf8,0x14 }, 
+    { 0xbf,0x73,0xc7,0x37 }, { 0xb4,0x7d,0xce,0x3a },
+    { 0xa9,0x6f,0xd5,0x2d }, { 0xa2,0x61,0xdc,0x20 }, 
+    { 0xf6,0xad,0x76,0x6d }, { 0xfd,0xa3,0x7f,0x60 }, 
+    { 0xe0,0xb1,0x64,0x77 }, { 0xeb,0xbf,0x6d,0x7a }, 
+    { 0xda,0x95,0x52,0x59 }, { 0xd1,0x9b,0x5b,0x54 }, 
+    { 0xcc,0x89,0x40,0x43 }, { 0xc7,0x87,0x49,0x4e }, 
+    { 0xae,0xdd,0x3e,0x05 }, { 0xa5,0xd3,0x37,0x08 },
+    { 0xb8,0xc1,0x2c,0x1f }, { 0xb3,0xcf,0x25,0x12 }, 
+    { 0x82,0xe5,0x1a,0x31 }, { 0x89,0xeb,0x13,0x3c },
+    { 0x94,0xf9,0x08,0x2b }, { 0x9f,0xf7,0x01,0x26 }, 
+    { 0x46,0x4d,0xe6,0xbd }, { 0x4d,0x43,0xef,0xb0 },
+    { 0x50,0x51,0xf4,0xa7 }, { 0x5b,0x5f,0xfd,0xaa }, 
+    { 0x6a,0x75,0xc2,0x89 }, { 0x61,0x7b,0xcb,0x84 },
+    { 0x7c,0x69,0xd0,0x93 }, { 0x77,0x67,0xd9,0x9e }, 
+    { 0x1e,0x3d,0xae,0xd5 }, { 0x15,0x33,0xa7,0xd8 },
+    { 0x08,0x21,0xbc,0xcf }, { 0x03,0x2f,0xb5,0xc2 }, 
+    { 0x32,0x05,0x8a,0xe1 }, { 0x39,0x0b,0x83,0xec },
+    { 0x24,0x19,0x98,0xfb }, { 0x2f,0x17,0x91,0xf6 }, 
+    { 0x8d,0x76,0x4d,0xd6 }, { 0x86,0x78,0x44,0xdb },
+    { 0x9b,0x6a,0x5f,0xcc }, { 0x90,0x64,0x56,0xc1 }, 
+    { 0xa1,0x4e,0x69,0xe2 }, { 0xaa,0x40,0x60,0xef },
+    { 0xb7,0x52,0x7b,0xf8 }, { 0xbc,0x5c,0x72,0xf5 }, 
+    { 0xd5,0x06,0x05,0xbe }, { 0xde,0x08,0x0c,0xb3 },
+    { 0xc3,0x1a,0x17,0xa4 }, { 0xc8,0x14,0x1e,0xa9 }, 
+    { 0xf9,0x3e,0x21,0x8a }, { 0xf2,0x30,0x28,0x87 },
+    { 0xef,0x22,0x33,0x90 }, { 0xe4,0x2c,0x3a,0x9d }, 
+    { 0x3d,0x96,0xdd,0x06 }, { 0x36,0x98,0xd4,0x0b },
+    { 0x2b,0x8a,0xcf,0x1c }, { 0x20,0x84,0xc6,0x11 }, 
+    { 0x11,0xae,0xf9,0x32 }, { 0x1a,0xa0,0xf0,0x3f },
+    { 0x07,0xb2,0xeb,0x28 }, { 0x0c,0xbc,0xe2,0x25 }, 
+    { 0x65,0xe6,0x95,0x6e }, { 0x6e,0xe8,0x9c,0x63 },
+    { 0x73,0xfa,0x87,0x74 }, { 0x78,0xf4,0x8e,0x79 }, 
+    { 0x49,0xde,0xb1,0x5a }, { 0x42,0xd0,0xb8,0x57 },
+    { 0x5f,0xc2,0xa3,0x40 }, { 0x54,0xcc,0xaa,0x4d }, 
+    { 0xf7,0x41,0xec,0xda }, { 0xfc,0x4f,0xe5,0xd7 },
+    { 0xe1,0x5d,0xfe,0xc0 }, { 0xea,0x53,0xf7,0xcd }, 
+    { 0xdb,0x79,0xc8,0xee }, { 0xd0,0x77,0xc1,0xe3 },
+    { 0xcd,0x65,0xda,0xf4 }, { 0xc6,0x6b,0xd3,0xf9 }, 
+    { 0xaf,0x31,0xa4,0xb2 }, { 0xa4,0x3f,0xad,0xbf },
+    { 0xb9,0x2d,0xb6,0xa8 }, { 0xb2,0x23,0xbf,0xa5 }, 
+    { 0x83,0x09,0x80,0x86 }, { 0x88,0x07,0x89,0x8b },
+    { 0x95,0x15,0x92,0x9c }, { 0x9e,0x1b,0x9b,0x91 }, 
+    { 0x47,0xa1,0x7c,0x0a }, { 0x4c,0xaf,0x75,0x07 },
+    { 0x51,0xbd,0x6e,0x10 }, { 0x5a,0xb3,0x67,0x1d }, 
+    { 0x6b,0x99,0x58,0x3e }, { 0x60,0x97,0x51,0x33 },
+    { 0x7d,0x85,0x4a,0x24 }, { 0x76,0x8b,0x43,0x29 }, 
+    { 0x1f,0xd1,0x34,0x62 }, { 0x14,0xdf,0x3d,0x6f },
+    { 0x09,0xcd,0x26,0x78 }, { 0x02,0xc3,0x2f,0x75 }, 
+    { 0x33,0xe9,0x10,0x56 }, { 0x38,0xe7,0x19,0x5b },
+    { 0x25,0xf5,0x02,0x4c }, { 0x2e,0xfb,0x0b,0x41 }, 
+    { 0x8c,0x9a,0xd7,0x61 }, { 0x87,0x94,0xde,0x6c },
+    { 0x9a,0x86,0xc5,0x7b }, { 0x91,0x88,0xcc,0x76 }, 
+    { 0xa0,0xa2,0xf3,0x55 }, { 0xab,0xac,0xfa,0x58 },
+    { 0xb6,0xbe,0xe1,0x4f }, { 0xbd,0xb0,0xe8,0x42 }, 
+    { 0xd4,0xea,0x9f,0x09 }, { 0xdf,0xe4,0x96,0x04 },
+    { 0xc2,0xf6,0x8d,0x13 }, { 0xc9,0xf8,0x84,0x1e }, 
+    { 0xf8,0xd2,0xbb,0x3d }, { 0xf3,0xdc,0xb2,0x30 },
+    { 0xee,0xce,0xa9,0x27 }, { 0xe5,0xc0,0xa0,0x2a }, 
+    { 0x3c,0x7a,0x47,0xb1 }, { 0x37,0x74,0x4e,0xbc },
+    { 0x2a,0x66,0x55,0xab }, { 0x21,0x68,0x5c,0xa6 }, 
+    { 0x10,0x42,0x63,0x85 }, { 0x1b,0x4c,0x6a,0x88 },
+    { 0x06,0x5e,0x71,0x9f }, { 0x0d,0x50,0x78,0x92 }, 
+    { 0x64,0x0a,0x0f,0xd9 }, { 0x6f,0x04,0x06,0xd4 },
+    { 0x72,0x16,0x1d,0xc3 }, { 0x79,0x18,0x14,0xce }, 
+    { 0x48,0x32,0x2b,0xed }, { 0x43,0x3c,0x22,0xe0 },
+    { 0x5e,0x2e,0x39,0xf7 }, { 0x55,0x20,0x30,0xfa }, 
+    { 0x01,0xec,0x9a,0xb7 }, { 0x0a,0xe2,0x93,0xba },
+    { 0x17,0xf0,0x88,0xad }, { 0x1c,0xfe,0x81,0xa0 }, 
+    { 0x2d,0xd4,0xbe,0x83 }, { 0x26,0xda,0xb7,0x8e },
+    { 0x3b,0xc8,0xac,0x99 }, { 0x30,0xc6,0xa5,0x94 }, 
+    { 0x59,0x9c,0xd2,0xdf }, { 0x52,0x92,0xdb,0xd2 },
+    { 0x4f,0x80,0xc0,0xc5 }, { 0x44,0x8e,0xc9,0xc8 }, 
+    { 0x75,0xa4,0xf6,0xeb }, { 0x7e,0xaa,0xff,0xe6 },
+    { 0x63,0xb8,0xe4,0xf1 }, { 0x68,0xb6,0xed,0xfc }, 
+    { 0xb1,0x0c,0x0a,0x67 }, { 0xba,0x02,0x03,0x6a },
+    { 0xa7,0x10,0x18,0x7d }, { 0xac,0x1e,0x11,0x70 }, 
+    { 0x9d,0x34,0x2e,0x53 }, { 0x96,0x3a,0x27,0x5e },
+    { 0x8b,0x28,0x3c,0x49 }, { 0x80,0x26,0x35,0x44 }, 
+    { 0xe9,0x7c,0x42,0x0f }, { 0xe2,0x72,0x4b,0x02 },
+    { 0xff,0x60,0x50,0x15 }, { 0xf4,0x6e,0x59,0x18 }, 
+    { 0xc5,0x44,0x66,0x3b }, { 0xce,0x4a,0x6f,0x36 },
+    { 0xd3,0x58,0x74,0x21 }, { 0xd8,0x56,0x7d,0x2c }, 
+    { 0x7a,0x37,0xa1,0x0c }, { 0x71,0x39,0xa8,0x01 },
+    { 0x6c,0x2b,0xb3,0x16 }, { 0x67,0x25,0xba,0x1b }, 
+    { 0x56,0x0f,0x85,0x38 }, { 0x5d,0x01,0x8c,0x35 },
+    { 0x40,0x13,0x97,0x22 }, { 0x4b,0x1d,0x9e,0x2f }, 
+    { 0x22,0x47,0xe9,0x64 }, { 0x29,0x49,0xe0,0x69 },
+    { 0x34,0x5b,0xfb,0x7e }, { 0x3f,0x55,0xf2,0x73 }, 
+    { 0x0e,0x7f,0xcd,0x50 }, { 0x05,0x71,0xc4,0x5d },
+    { 0x18,0x63,0xdf,0x4a }, { 0x13,0x6d,0xd6,0x47 }, 
+    { 0xca,0xd7,0x31,0xdc }, { 0xc1,0xd9,0x38,0xd1 },
+    { 0xdc,0xcb,0x23,0xc6 }, { 0xd7,0xc5,0x2a,0xcb }, 
+    { 0xe6,0xef,0x15,0xe8 }, { 0xed,0xe1,0x1c,0xe5 },
+    { 0xf0,0xf3,0x07,0xf2 }, { 0xfb,0xfd,0x0e,0xff }, 
+    { 0x92,0xa7,0x79,0xb4 }, { 0x99,0xa9,0x70,0xb9 },
+    { 0x84,0xbb,0x6b,0xae }, { 0x8f,0xb5,0x62,0xa3 }, 
+    { 0xbe,0x9f,0x5d,0x80 }, { 0xb5,0x91,0x54,0x8d },
+    { 0xa8,0x83,0x4f,0x9a }, { 0xa3,0x8d,0x46,0x97 }
+  };
+
+static const unsigned char U3[256][4] = 
+  {
+    { 0x00,0x00,0x00,0x00 }, { 0x0d,0x0b,0x0e,0x09 },
+    { 0x1a,0x16,0x1c,0x12 }, { 0x17,0x1d,0x12,0x1b }, 
+    { 0x34,0x2c,0x38,0x24 }, { 0x39,0x27,0x36,0x2d },
+    { 0x2e,0x3a,0x24,0x36 }, { 0x23,0x31,0x2a,0x3f }, 
+    { 0x68,0x58,0x70,0x48 }, { 0x65,0x53,0x7e,0x41 },
+    { 0x72,0x4e,0x6c,0x5a }, { 0x7f,0x45,0x62,0x53 }, 
+    { 0x5c,0x74,0x48,0x6c }, { 0x51,0x7f,0x46,0x65 },
+    { 0x46,0x62,0x54,0x7e }, { 0x4b,0x69,0x5a,0x77 }, 
+    { 0xd0,0xb0,0xe0,0x90 }, { 0xdd,0xbb,0xee,0x99 },
+    { 0xca,0xa6,0xfc,0x82 }, { 0xc7,0xad,0xf2,0x8b }, 
+    { 0xe4,0x9c,0xd8,0xb4 }, { 0xe9,0x97,0xd6,0xbd },
+    { 0xfe,0x8a,0xc4,0xa6 }, { 0xf3,0x81,0xca,0xaf }, 
+    { 0xb8,0xe8,0x90,0xd8 }, { 0xb5,0xe3,0x9e,0xd1 },
+    { 0xa2,0xfe,0x8c,0xca }, { 0xaf,0xf5,0x82,0xc3 }, 
+    { 0x8c,0xc4,0xa8,0xfc }, { 0x81,0xcf,0xa6,0xf5 },
+    { 0x96,0xd2,0xb4,0xee }, { 0x9b,0xd9,0xba,0xe7 }, 
+    { 0xbb,0x7b,0xdb,0x3b }, { 0xb6,0x70,0xd5,0x32 },
+    { 0xa1,0x6d,0xc7,0x29 }, { 0xac,0x66,0xc9,0x20 }, 
+    { 0x8f,0x57,0xe3,0x1f }, { 0x82,0x5c,0xed,0x16 },
+    { 0x95,0x41,0xff,0x0d }, { 0x98,0x4a,0xf1,0x04 }, 
+    { 0xd3,0x23,0xab,0x73 }, { 0xde,0x28,0xa5,0x7a },
+    { 0xc9,0x35,0xb7,0x61 }, { 0xc4,0x3e,0xb9,0x68 }, 
+    { 0xe7,0x0f,0x93,0x57 }, { 0xea,0x04,0x9d,0x5e },
+    { 0xfd,0x19,0x8f,0x45 }, { 0xf0,0x12,0x81,0x4c }, 
+    { 0x6b,0xcb,0x3b,0xab }, { 0x66,0xc0,0x35,0xa2 },
+    { 0x71,0xdd,0x27,0xb9 }, { 0x7c,0xd6,0x29,0xb0 }, 
+    { 0x5f,0xe7,0x03,0x8f }, { 0x52,0xec,0x0d,0x86 },
+    { 0x45,0xf1,0x1f,0x9d }, { 0x48,0xfa,0x11,0x94 }, 
+    { 0x03,0x93,0x4b,0xe3 }, { 0x0e,0x98,0x45,0xea },
+    { 0x19,0x85,0x57,0xf1 }, { 0x14,0x8e,0x59,0xf8 }, 
+    { 0x37,0xbf,0x73,0xc7 }, { 0x3a,0xb4,0x7d,0xce }, 
+    { 0x2d,0xa9,0x6f,0xd5 }, { 0x20,0xa2,0x61,0xdc }, 
+    { 0x6d,0xf6,0xad,0x76 }, { 0x60,0xfd,0xa3,0x7f },
+    { 0x77,0xe0,0xb1,0x64 }, { 0x7a,0xeb,0xbf,0x6d }, 
+    { 0x59,0xda,0x95,0x52 }, { 0x54,0xd1,0x9b,0x5b },
+    { 0x43,0xcc,0x89,0x40 }, { 0x4e,0xc7,0x87,0x49 }, 
+    { 0x05,0xae,0xdd,0x3e }, { 0x08,0xa5,0xd3,0x37 },
+    { 0x1f,0xb8,0xc1,0x2c }, { 0x12,0xb3,0xcf,0x25 }, 
+    { 0x31,0x82,0xe5,0x1a }, { 0x3c,0x89,0xeb,0x13 }, 
+    { 0x2b,0x94,0xf9,0x08 }, { 0x26,0x9f,0xf7,0x01 }, 
+    { 0xbd,0x46,0x4d,0xe6 }, { 0xb0,0x4d,0x43,0xef }, 
+    { 0xa7,0x50,0x51,0xf4 }, { 0xaa,0x5b,0x5f,0xfd }, 
+    { 0x89,0x6a,0x75,0xc2 }, { 0x84,0x61,0x7b,0xcb }, 
+    { 0x93,0x7c,0x69,0xd0 }, { 0x9e,0x77,0x67,0xd9 }, 
+    { 0xd5,0x1e,0x3d,0xae }, { 0xd8,0x15,0x33,0xa7 },
+    { 0xcf,0x08,0x21,0xbc }, { 0xc2,0x03,0x2f,0xb5 }, 
+    { 0xe1,0x32,0x05,0x8a }, { 0xec,0x39,0x0b,0x83 },
+    { 0xfb,0x24,0x19,0x98 }, { 0xf6,0x2f,0x17,0x91 }, 
+    { 0xd6,0x8d,0x76,0x4d }, { 0xdb,0x86,0x78,0x44 }, 
+    { 0xcc,0x9b,0x6a,0x5f }, { 0xc1,0x90,0x64,0x56 }, 
+    { 0xe2,0xa1,0x4e,0x69 }, { 0xef,0xaa,0x40,0x60 }, 
+    { 0xf8,0xb7,0x52,0x7b }, { 0xf5,0xbc,0x5c,0x72 }, 
+    { 0xbe,0xd5,0x06,0x05 }, { 0xb3,0xde,0x08,0x0c }, 
+    { 0xa4,0xc3,0x1a,0x17 }, { 0xa9,0xc8,0x14,0x1e }, 
+    { 0x8a,0xf9,0x3e,0x21 }, { 0x87,0xf2,0x30,0x28 },
+    { 0x90,0xef,0x22,0x33 }, { 0x9d,0xe4,0x2c,0x3a }, 
+    { 0x06,0x3d,0x96,0xdd }, { 0x0b,0x36,0x98,0xd4 },
+    { 0x1c,0x2b,0x8a,0xcf }, { 0x11,0x20,0x84,0xc6 }, 
+    { 0x32,0x11,0xae,0xf9 }, { 0x3f,0x1a,0xa0,0xf0 },
+    { 0x28,0x07,0xb2,0xeb }, { 0x25,0x0c,0xbc,0xe2 }, 
+    { 0x6e,0x65,0xe6,0x95 }, { 0x63,0x6e,0xe8,0x9c },
+    { 0x74,0x73,0xfa,0x87 }, { 0x79,0x78,0xf4,0x8e }, 
+    { 0x5a,0x49,0xde,0xb1 }, { 0x57,0x42,0xd0,0xb8 },
+    { 0x40,0x5f,0xc2,0xa3 }, { 0x4d,0x54,0xcc,0xaa }, 
+    { 0xda,0xf7,0x41,0xec }, { 0xd7,0xfc,0x4f,0xe5 },
+    { 0xc0,0xe1,0x5d,0xfe }, { 0xcd,0xea,0x53,0xf7 }, 
+    { 0xee,0xdb,0x79,0xc8 }, { 0xe3,0xd0,0x77,0xc1 },
+    { 0xf4,0xcd,0x65,0xda }, { 0xf9,0xc6,0x6b,0xd3 }, 
+    { 0xb2,0xaf,0x31,0xa4 }, { 0xbf,0xa4,0x3f,0xad },
+    { 0xa8,0xb9,0x2d,0xb6 }, { 0xa5,0xb2,0x23,0xbf }, 
+    { 0x86,0x83,0x09,0x80 }, { 0x8b,0x88,0x07,0x89 },
+    { 0x9c,0x95,0x15,0x92 }, { 0x91,0x9e,0x1b,0x9b }, 
+    { 0x0a,0x47,0xa1,0x7c }, { 0x07,0x4c,0xaf,0x75 },
+    { 0x10,0x51,0xbd,0x6e }, { 0x1d,0x5a,0xb3,0x67 }, 
+    { 0x3e,0x6b,0x99,0x58 }, { 0x33,0x60,0x97,0x51 },
+    { 0x24,0x7d,0x85,0x4a }, { 0x29,0x76,0x8b,0x43 }, 
+    { 0x62,0x1f,0xd1,0x34 }, { 0x6f,0x14,0xdf,0x3d },
+    { 0x78,0x09,0xcd,0x26 }, { 0x75,0x02,0xc3,0x2f }, 
+    { 0x56,0x33,0xe9,0x10 }, { 0x5b,0x38,0xe7,0x19 },
+    { 0x4c,0x25,0xf5,0x02 }, { 0x41,0x2e,0xfb,0x0b }, 
+    { 0x61,0x8c,0x9a,0xd7 }, { 0x6c,0x87,0x94,0xde },
+    { 0x7b,0x9a,0x86,0xc5 }, { 0x76,0x91,0x88,0xcc }, 
+    { 0x55,0xa0,0xa2,0xf3 }, { 0x58,0xab,0xac,0xfa },
+    { 0x4f,0xb6,0xbe,0xe1 }, { 0x42,0xbd,0xb0,0xe8 }, 
+    { 0x09,0xd4,0xea,0x9f }, { 0x04,0xdf,0xe4,0x96 },
+    { 0x13,0xc2,0xf6,0x8d }, { 0x1e,0xc9,0xf8,0x84 }, 
+    { 0x3d,0xf8,0xd2,0xbb }, { 0x30,0xf3,0xdc,0xb2 },
+    { 0x27,0xee,0xce,0xa9 }, { 0x2a,0xe5,0xc0,0xa0 }, 
+    { 0xb1,0x3c,0x7a,0x47 }, { 0xbc,0x37,0x74,0x4e },
+    { 0xab,0x2a,0x66,0x55 }, { 0xa6,0x21,0x68,0x5c }, 
+    { 0x85,0x10,0x42,0x63 }, { 0x88,0x1b,0x4c,0x6a },
+    { 0x9f,0x06,0x5e,0x71 }, { 0x92,0x0d,0x50,0x78 }, 
+    { 0xd9,0x64,0x0a,0x0f }, { 0xd4,0x6f,0x04,0x06 },
+    { 0xc3,0x72,0x16,0x1d }, { 0xce,0x79,0x18,0x14 }, 
+    { 0xed,0x48,0x32,0x2b }, { 0xe0,0x43,0x3c,0x22 },
+    { 0xf7,0x5e,0x2e,0x39 }, { 0xfa,0x55,0x20,0x30 }, 
+    { 0xb7,0x01,0xec,0x9a }, { 0xba,0x0a,0xe2,0x93 },
+    { 0xad,0x17,0xf0,0x88 }, { 0xa0,0x1c,0xfe,0x81 }, 
+    { 0x83,0x2d,0xd4,0xbe }, { 0x8e,0x26,0xda,0xb7 },
+    { 0x99,0x3b,0xc8,0xac }, { 0x94,0x30,0xc6,0xa5 }, 
+    { 0xdf,0x59,0x9c,0xd2 }, { 0xd2,0x52,0x92,0xdb },
+    { 0xc5,0x4f,0x80,0xc0 }, { 0xc8,0x44,0x8e,0xc9 }, 
+    { 0xeb,0x75,0xa4,0xf6 }, { 0xe6,0x7e,0xaa,0xff },
+    { 0xf1,0x63,0xb8,0xe4 }, { 0xfc,0x68,0xb6,0xed }, 
+    { 0x67,0xb1,0x0c,0x0a }, { 0x6a,0xba,0x02,0x03 },
+    { 0x7d,0xa7,0x10,0x18 }, { 0x70,0xac,0x1e,0x11 }, 
+    { 0x53,0x9d,0x34,0x2e }, { 0x5e,0x96,0x3a,0x27 },
+    { 0x49,0x8b,0x28,0x3c }, { 0x44,0x80,0x26,0x35 }, 
+    { 0x0f,0xe9,0x7c,0x42 }, { 0x02,0xe2,0x72,0x4b },
+    { 0x15,0xff,0x60,0x50 }, { 0x18,0xf4,0x6e,0x59 }, 
+    { 0x3b,0xc5,0x44,0x66 }, { 0x36,0xce,0x4a,0x6f },
+    { 0x21,0xd3,0x58,0x74 }, { 0x2c,0xd8,0x56,0x7d }, 
+    { 0x0c,0x7a,0x37,0xa1 }, { 0x01,0x71,0x39,0xa8 },
+    { 0x16,0x6c,0x2b,0xb3 }, { 0x1b,0x67,0x25,0xba }, 
+    { 0x38,0x56,0x0f,0x85 }, { 0x35,0x5d,0x01,0x8c },
+    { 0x22,0x40,0x13,0x97 }, { 0x2f,0x4b,0x1d,0x9e }, 
+    { 0x64,0x22,0x47,0xe9 }, { 0x69,0x29,0x49,0xe0 },
+    { 0x7e,0x34,0x5b,0xfb }, { 0x73,0x3f,0x55,0xf2 }, 
+    { 0x50,0x0e,0x7f,0xcd }, { 0x5d,0x05,0x71,0xc4 },
+    { 0x4a,0x18,0x63,0xdf }, { 0x47,0x13,0x6d,0xd6 }, 
+    { 0xdc,0xca,0xd7,0x31 }, { 0xd1,0xc1,0xd9,0x38 },
+    { 0xc6,0xdc,0xcb,0x23 }, { 0xcb,0xd7,0xc5,0x2a }, 
+    { 0xe8,0xe6,0xef,0x15 }, { 0xe5,0xed,0xe1,0x1c },
+    { 0xf2,0xf0,0xf3,0x07 }, { 0xff,0xfb,0xfd,0x0e }, 
+    { 0xb4,0x92,0xa7,0x79 }, { 0xb9,0x99,0xa9,0x70 },
+    { 0xae,0x84,0xbb,0x6b }, { 0xa3,0x8f,0xb5,0x62 }, 
+    { 0x80,0xbe,0x9f,0x5d }, { 0x8d,0xb5,0x91,0x54 },
+    { 0x9a,0xa8,0x83,0x4f }, { 0x97,0xa3,0x8d,0x46 }
+  };
+
+static const unsigned char U4[256][4] =
+  {
+    { 0x00,0x00,0x00,0x00 }, { 0x09,0x0d,0x0b,0x0e },
+    { 0x12,0x1a,0x16,0x1c }, { 0x1b,0x17,0x1d,0x12 }, 
+    { 0x24,0x34,0x2c,0x38 }, { 0x2d,0x39,0x27,0x36 },
+    { 0x36,0x2e,0x3a,0x24 }, { 0x3f,0x23,0x31,0x2a }, 
+    { 0x48,0x68,0x58,0x70 }, { 0x41,0x65,0x53,0x7e },
+    { 0x5a,0x72,0x4e,0x6c }, { 0x53,0x7f,0x45,0x62 }, 
+    { 0x6c,0x5c,0x74,0x48 }, { 0x65,0x51,0x7f,0x46 },
+    { 0x7e,0x46,0x62,0x54 }, { 0x77,0x4b,0x69,0x5a }, 
+    { 0x90,0xd0,0xb0,0xe0 }, { 0x99,0xdd,0xbb,0xee },
+    { 0x82,0xca,0xa6,0xfc }, { 0x8b,0xc7,0xad,0xf2 }, 
+    { 0xb4,0xe4,0x9c,0xd8 }, { 0xbd,0xe9,0x97,0xd6 },
+    { 0xa6,0xfe,0x8a,0xc4 }, { 0xaf,0xf3,0x81,0xca }, 
+    { 0xd8,0xb8,0xe8,0x90 }, { 0xd1,0xb5,0xe3,0x9e },
+    { 0xca,0xa2,0xfe,0x8c }, { 0xc3,0xaf,0xf5,0x82 }, 
+    { 0xfc,0x8c,0xc4,0xa8 }, { 0xf5,0x81,0xcf,0xa6 },
+    { 0xee,0x96,0xd2,0xb4 }, { 0xe7,0x9b,0xd9,0xba }, 
+    { 0x3b,0xbb,0x7b,0xdb }, { 0x32,0xb6,0x70,0xd5 },
+    { 0x29,0xa1,0x6d,0xc7 }, { 0x20,0xac,0x66,0xc9 }, 
+    { 0x1f,0x8f,0x57,0xe3 }, { 0x16,0x82,0x5c,0xed },
+    { 0x0d,0x95,0x41,0xff }, { 0x04,0x98,0x4a,0xf1 }, 
+    { 0x73,0xd3,0x23,0xab }, { 0x7a,0xde,0x28,0xa5 },
+    { 0x61,0xc9,0x35,0xb7 }, { 0x68,0xc4,0x3e,0xb9 }, 
+    { 0x57,0xe7,0x0f,0x93 }, { 0x5e,0xea,0x04,0x9d },
+    { 0x45,0xfd,0x19,0x8f }, { 0x4c,0xf0,0x12,0x81 }, 
+    { 0xab,0x6b,0xcb,0x3b }, { 0xa2,0x66,0xc0,0x35 },
+    { 0xb9,0x71,0xdd,0x27 }, { 0xb0,0x7c,0xd6,0x29 }, 
+    { 0x8f,0x5f,0xe7,0x03 }, { 0x86,0x52,0xec,0x0d },
+    { 0x9d,0x45,0xf1,0x1f }, { 0x94,0x48,0xfa,0x11 }, 
+    { 0xe3,0x03,0x93,0x4b }, { 0xea,0x0e,0x98,0x45 },
+    { 0xf1,0x19,0x85,0x57 }, { 0xf8,0x14,0x8e,0x59 }, 
+    { 0xc7,0x37,0xbf,0x73 }, { 0xce,0x3a,0xb4,0x7d },
+    { 0xd5,0x2d,0xa9,0x6f }, { 0xdc,0x20,0xa2,0x61 }, 
+    { 0x76,0x6d,0xf6,0xad }, { 0x7f,0x60,0xfd,0xa3 },
+    { 0x64,0x77,0xe0,0xb1 }, { 0x6d,0x7a,0xeb,0xbf }, 
+    { 0x52,0x59,0xda,0x95 }, { 0x5b,0x54,0xd1,0x9b },
+    { 0x40,0x43,0xcc,0x89 }, { 0x49,0x4e,0xc7,0x87 }, 
+    { 0x3e,0x05,0xae,0xdd }, { 0x37,0x08,0xa5,0xd3 },
+    { 0x2c,0x1f,0xb8,0xc1 }, { 0x25,0x12,0xb3,0xcf }, 
+    { 0x1a,0x31,0x82,0xe5 }, { 0x13,0x3c,0x89,0xeb },
+    { 0x08,0x2b,0x94,0xf9 }, { 0x01,0x26,0x9f,0xf7 }, 
+    { 0xe6,0xbd,0x46,0x4d }, { 0xef,0xb0,0x4d,0x43 },
+    { 0xf4,0xa7,0x50,0x51 }, { 0xfd,0xaa,0x5b,0x5f }, 
+    { 0xc2,0x89,0x6a,0x75 }, { 0xcb,0x84,0x61,0x7b },
+    { 0xd0,0x93,0x7c,0x69 }, { 0xd9,0x9e,0x77,0x67 }, 
+    { 0xae,0xd5,0x1e,0x3d }, { 0xa7,0xd8,0x15,0x33 },
+    { 0xbc,0xcf,0x08,0x21 }, { 0xb5,0xc2,0x03,0x2f }, 
+    { 0x8a,0xe1,0x32,0x05 }, { 0x83,0xec,0x39,0x0b },
+    { 0x98,0xfb,0x24,0x19 }, { 0x91,0xf6,0x2f,0x17 }, 
+    { 0x4d,0xd6,0x8d,0x76 }, { 0x44,0xdb,0x86,0x78 },
+    { 0x5f,0xcc,0x9b,0x6a }, { 0x56,0xc1,0x90,0x64 }, 
+    { 0x69,0xe2,0xa1,0x4e }, { 0x60,0xef,0xaa,0x40 },
+    { 0x7b,0xf8,0xb7,0x52 }, { 0x72,0xf5,0xbc,0x5c }, 
+    { 0x05,0xbe,0xd5,0x06 }, { 0x0c,0xb3,0xde,0x08 },
+    { 0x17,0xa4,0xc3,0x1a }, { 0x1e,0xa9,0xc8,0x14 }, 
+    { 0x21,0x8a,0xf9,0x3e }, { 0x28,0x87,0xf2,0x30 },
+    { 0x33,0x90,0xef,0x22 }, { 0x3a,0x9d,0xe4,0x2c }, 
+    { 0xdd,0x06,0x3d,0x96 }, { 0xd4,0x0b,0x36,0x98 },
+    { 0xcf,0x1c,0x2b,0x8a }, { 0xc6,0x11,0x20,0x84 }, 
+    { 0xf9,0x32,0x11,0xae }, { 0xf0,0x3f,0x1a,0xa0 },
+    { 0xeb,0x28,0x07,0xb2 }, { 0xe2,0x25,0x0c,0xbc }, 
+    { 0x95,0x6e,0x65,0xe6 }, { 0x9c,0x63,0x6e,0xe8 },
+    { 0x87,0x74,0x73,0xfa }, { 0x8e,0x79,0x78,0xf4 }, 
+    { 0xb1,0x5a,0x49,0xde }, { 0xb8,0x57,0x42,0xd0 },
+    { 0xa3,0x40,0x5f,0xc2 }, { 0xaa,0x4d,0x54,0xcc }, 
+    { 0xec,0xda,0xf7,0x41 }, { 0xe5,0xd7,0xfc,0x4f },
+    { 0xfe,0xc0,0xe1,0x5d }, { 0xf7,0xcd,0xea,0x53 }, 
+    { 0xc8,0xee,0xdb,0x79 }, { 0xc1,0xe3,0xd0,0x77 },
+    { 0xda,0xf4,0xcd,0x65 }, { 0xd3,0xf9,0xc6,0x6b }, 
+    { 0xa4,0xb2,0xaf,0x31 }, { 0xad,0xbf,0xa4,0x3f },
+    { 0xb6,0xa8,0xb9,0x2d }, { 0xbf,0xa5,0xb2,0x23 }, 
+    { 0x80,0x86,0x83,0x09 }, { 0x89,0x8b,0x88,0x07 },
+    { 0x92,0x9c,0x95,0x15 }, { 0x9b,0x91,0x9e,0x1b }, 
+    { 0x7c,0x0a,0x47,0xa1 }, { 0x75,0x07,0x4c,0xaf },
+    { 0x6e,0x10,0x51,0xbd }, { 0x67,0x1d,0x5a,0xb3 }, 
+    { 0x58,0x3e,0x6b,0x99 }, { 0x51,0x33,0x60,0x97 },
+    { 0x4a,0x24,0x7d,0x85 }, { 0x43,0x29,0x76,0x8b }, 
+    { 0x34,0x62,0x1f,0xd1 }, { 0x3d,0x6f,0x14,0xdf },
+    { 0x26,0x78,0x09,0xcd }, { 0x2f,0x75,0x02,0xc3 }, 
+    { 0x10,0x56,0x33,0xe9 }, { 0x19,0x5b,0x38,0xe7 },
+    { 0x02,0x4c,0x25,0xf5 }, { 0x0b,0x41,0x2e,0xfb }, 
+    { 0xd7,0x61,0x8c,0x9a }, { 0xde,0x6c,0x87,0x94 },
+    { 0xc5,0x7b,0x9a,0x86 }, { 0xcc,0x76,0x91,0x88 }, 
+    { 0xf3,0x55,0xa0,0xa2 }, { 0xfa,0x58,0xab,0xac },
+    { 0xe1,0x4f,0xb6,0xbe }, { 0xe8,0x42,0xbd,0xb0 }, 
+    { 0x9f,0x09,0xd4,0xea }, { 0x96,0x04,0xdf,0xe4 },
+    { 0x8d,0x13,0xc2,0xf6 }, { 0x84,0x1e,0xc9,0xf8 }, 
+    { 0xbb,0x3d,0xf8,0xd2 }, { 0xb2,0x30,0xf3,0xdc },
+    { 0xa9,0x27,0xee,0xce }, { 0xa0,0x2a,0xe5,0xc0 }, 
+    { 0x47,0xb1,0x3c,0x7a }, { 0x4e,0xbc,0x37,0x74 },
+    { 0x55,0xab,0x2a,0x66 }, { 0x5c,0xa6,0x21,0x68 }, 
+    { 0x63,0x85,0x10,0x42 }, { 0x6a,0x88,0x1b,0x4c },
+    { 0x71,0x9f,0x06,0x5e }, { 0x78,0x92,0x0d,0x50 }, 
+    { 0x0f,0xd9,0x64,0x0a }, { 0x06,0xd4,0x6f,0x04 },
+    { 0x1d,0xc3,0x72,0x16 }, { 0x14,0xce,0x79,0x18 }, 
+    { 0x2b,0xed,0x48,0x32 }, { 0x22,0xe0,0x43,0x3c },
+    { 0x39,0xf7,0x5e,0x2e }, { 0x30,0xfa,0x55,0x20 }, 
+    { 0x9a,0xb7,0x01,0xec }, { 0x93,0xba,0x0a,0xe2 }, 
+    { 0x88,0xad,0x17,0xf0 }, { 0x81,0xa0,0x1c,0xfe }, 
+    { 0xbe,0x83,0x2d,0xd4 }, { 0xb7,0x8e,0x26,0xda },
+    { 0xac,0x99,0x3b,0xc8 }, { 0xa5,0x94,0x30,0xc6 }, 
+    { 0xd2,0xdf,0x59,0x9c }, { 0xdb,0xd2,0x52,0x92 }, 
+    { 0xc0,0xc5,0x4f,0x80 }, { 0xc9,0xc8,0x44,0x8e }, 
+    { 0xf6,0xeb,0x75,0xa4 }, { 0xff,0xe6,0x7e,0xaa },
+    { 0xe4,0xf1,0x63,0xb8 }, { 0xed,0xfc,0x68,0xb6 }, 
+    { 0x0a,0x67,0xb1,0x0c }, { 0x03,0x6a,0xba,0x02 },
+    { 0x18,0x7d,0xa7,0x10 }, { 0x11,0x70,0xac,0x1e }, 
+    { 0x2e,0x53,0x9d,0x34 }, { 0x27,0x5e,0x96,0x3a },
+    { 0x3c,0x49,0x8b,0x28 }, { 0x35,0x44,0x80,0x26 }, 
+    { 0x42,0x0f,0xe9,0x7c }, { 0x4b,0x02,0xe2,0x72 }, 
+    { 0x50,0x15,0xff,0x60 }, { 0x59,0x18,0xf4,0x6e }, 
+    { 0x66,0x3b,0xc5,0x44 }, { 0x6f,0x36,0xce,0x4a },
+    { 0x74,0x21,0xd3,0x58 }, { 0x7d,0x2c,0xd8,0x56 }, 
+    { 0xa1,0x0c,0x7a,0x37 }, { 0xa8,0x01,0x71,0x39 },
+    { 0xb3,0x16,0x6c,0x2b }, { 0xba,0x1b,0x67,0x25 }, 
+    { 0x85,0x38,0x56,0x0f }, { 0x8c,0x35,0x5d,0x01 },
+    { 0x97,0x22,0x40,0x13 }, { 0x9e,0x2f,0x4b,0x1d }, 
+    { 0xe9,0x64,0x22,0x47 }, { 0xe0,0x69,0x29,0x49 }, 
+    { 0xfb,0x7e,0x34,0x5b }, { 0xf2,0x73,0x3f,0x55 }, 
+    { 0xcd,0x50,0x0e,0x7f }, { 0xc4,0x5d,0x05,0x71 },
+    { 0xdf,0x4a,0x18,0x63 }, { 0xd6,0x47,0x13,0x6d }, 
+    { 0x31,0xdc,0xca,0xd7 }, { 0x38,0xd1,0xc1,0xd9 },
+    { 0x23,0xc6,0xdc,0xcb }, { 0x2a,0xcb,0xd7,0xc5 }, 
+    { 0x15,0xe8,0xe6,0xef }, { 0x1c,0xe5,0xed,0xe1 },
+    { 0x07,0xf2,0xf0,0xf3 }, { 0x0e,0xff,0xfb,0xfd }, 
+    { 0x79,0xb4,0x92,0xa7 }, { 0x70,0xb9,0x99,0xa9 },
+    { 0x6b,0xae,0x84,0xbb }, { 0x62,0xa3,0x8f,0xb5 }, 
+    { 0x5d,0x80,0xbe,0x9f }, { 0x54,0x8d,0xb5,0x91 },
+    { 0x4f,0x9a,0xa8,0x83 }, { 0x46,0x97,0xa3,0x8d }
+  };
+
+static const u32 rcon[30] = 
+  { 
+    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c,
+    0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
+    0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
+  };
+
diff --git a/grub-core/lib/libgcrypt/cipher/rijndael.c b/grub-core/lib/libgcrypt/cipher/rijndael.c
new file mode 100644 (file)
index 0000000..d43b349
--- /dev/null
@@ -0,0 +1,1253 @@
+/* Rijndael (AES) for GnuPG
+ * Copyright (C) 2000, 2001, 2002, 2003, 2007,
+ *               2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *******************************************************************
+ * The code here is based on the optimized implementation taken from
+ * http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ on Oct 2, 2000,
+ * which carries this notice:
+ *------------------------------------------
+ * rijndael-alg-fst.c   v2.3   April '2000
+ *
+ * Optimised ANSI C code
+ *
+ * authors: v1.0: Antoon Bosselaers
+ *          v2.0: Vincent Rijmen
+ *          v2.3: Paulo Barreto
+ *
+ * This code is placed in the public domain.
+ *------------------------------------------
+ *
+ * The SP800-38a document is available at:
+ *   http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* for memcmp() */
+
+#include "types.h"  /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+
+#define MAXKC                  (256/32)
+#define MAXROUNDS              14
+#define BLOCKSIZE               (128/8)
+
+
+/* USE_PADLOCK indicates whether to compile the padlock specific
+   code.  */
+#undef USE_PADLOCK
+#ifdef ENABLE_PADLOCK_SUPPORT
+# if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
+# define USE_PADLOCK
+# endif
+#endif /*ENABLE_PADLOCK_SUPPORT*/
+
+static const char *selftest(void);
+
+typedef struct 
+{
+  int   ROUNDS;             /* Key-length-dependent number of rounds.  */
+  int decryption_prepared;  /* The decryption key schedule is available.  */
+#ifdef USE_PADLOCK
+  int use_padlock;          /* Padlock shall be used.  */
+  /* The key as passed to the padlock engine.  */
+  unsigned char padlock_key[16] __attribute__ ((aligned (16)));
+#endif
+  union
+  {
+    PROPERLY_ALIGNED_TYPE dummy;
+    byte keyschedule[MAXROUNDS+1][4][4];
+  } u1;
+  union
+  {
+    PROPERLY_ALIGNED_TYPE dummy;
+    byte keyschedule[MAXROUNDS+1][4][4];       
+  } u2;
+} RIJNDAEL_context;
+
+#define keySched  u1.keyschedule
+#define keySched2 u2.keyschedule
+
+/* All the numbers.  */
+#include "rijndael-tables.h"
+
+
+/* Perform the key setup.  */  
+static gcry_err_code_t
+do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
+{
+  static int initialized = 0;
+  static const char *selftest_failed=0;
+  int ROUNDS;
+  int i,j, r, t, rconpointer = 0;
+  int KC;
+  union
+  {
+    PROPERLY_ALIGNED_TYPE dummy;
+    byte k[MAXKC][4];
+  } k;
+#define k k.k
+  union
+  {
+    PROPERLY_ALIGNED_TYPE dummy;
+    byte tk[MAXKC][4];
+  } tk;
+#define tk tk.tk  
+
+  /* The on-the-fly self tests are only run in non-fips mode. In fips
+     mode explicit self-tests are required.  Actually the on-the-fly
+     self-tests are not fully thread-safe and it might happen that a
+     failed self-test won't get noticed in another thread.  
+
+     FIXME: We might want to have a central registry of succeeded
+     self-tests. */
+  if (!fips_mode () && !initialized)
+    {
+      initialized = 1;
+      selftest_failed = selftest ();
+      if (selftest_failed)
+        log_error ("%s\n", selftest_failed );
+    }
+  if (selftest_failed)
+    return GPG_ERR_SELFTEST_FAILED;
+
+  ctx->decryption_prepared = 0;
+#ifdef USE_PADLOCK
+  ctx->use_padlock = 0;
+#endif
+
+  if( keylen == 128/8 )
+    {
+      ROUNDS = 10;
+      KC = 4;
+#ifdef USE_PADLOCK
+      if ((_gcry_get_hw_features () & HWF_PADLOCK_AES))
+        {
+          ctx->use_padlock = 1;
+          memcpy (ctx->padlock_key, key, keylen);
+        }
+#endif
+    }
+  else if ( keylen == 192/8 )
+    {
+      ROUNDS = 12;
+      KC = 6;
+    }
+  else if ( keylen == 256/8 )
+    {
+      ROUNDS = 14;
+      KC = 8;
+    }
+  else
+    return GPG_ERR_INV_KEYLEN;
+
+  ctx->ROUNDS = ROUNDS;
+
+#ifdef USE_PADLOCK
+  if (ctx->use_padlock)
+    {
+      /* Nothing to do as we support only hardware key generation for
+         now.  */
+    }
+  else
+#endif /*USE_PADLOCK*/
+    {
+#define W (ctx->keySched)
+      for (i = 0; i < keylen; i++) 
+        {
+          k[i >> 2][i & 3] = key[i]; 
+        }
+      
+      for (j = KC-1; j >= 0; j--) 
+        {
+          *((u32*)tk[j]) = *((u32*)k[j]);
+        }
+      r = 0;
+      t = 0;
+      /* Copy values into round key array.  */
+      for (j = 0; (j < KC) && (r < ROUNDS + 1); )
+        {
+          for (; (j < KC) && (t < 4); j++, t++)
+            {
+              *((u32*)W[r][t]) = *((u32*)tk[j]);
+            }
+          if (t == 4)
+            {
+              r++;
+              t = 0;
+            }
+        }
+      
+      while (r < ROUNDS + 1)
+        {
+          /* While not enough round key material calculated calculate
+             new values.  */
+          tk[0][0] ^= S[tk[KC-1][1]];
+          tk[0][1] ^= S[tk[KC-1][2]];
+          tk[0][2] ^= S[tk[KC-1][3]];
+          tk[0][3] ^= S[tk[KC-1][0]];
+          tk[0][0] ^= rcon[rconpointer++];
+          
+          if (KC != 8)
+            {
+              for (j = 1; j < KC; j++) 
+                {
+                  *((u32*)tk[j]) ^= *((u32*)tk[j-1]);
+                }
+            } 
+          else 
+            {
+              for (j = 1; j < KC/2; j++)
+                {
+                  *((u32*)tk[j]) ^= *((u32*)tk[j-1]);
+                }
+              tk[KC/2][0] ^= S[tk[KC/2 - 1][0]];
+              tk[KC/2][1] ^= S[tk[KC/2 - 1][1]];
+              tk[KC/2][2] ^= S[tk[KC/2 - 1][2]];
+              tk[KC/2][3] ^= S[tk[KC/2 - 1][3]];
+              for (j = KC/2 + 1; j < KC; j++)
+                {
+                  *((u32*)tk[j]) ^= *((u32*)tk[j-1]);
+                }
+            }
+          
+          /* Copy values into round key array.  */
+          for (j = 0; (j < KC) && (r < ROUNDS + 1); )
+            {
+              for (; (j < KC) && (t < 4); j++, t++)
+                {
+                  *((u32*)W[r][t]) = *((u32*)tk[j]);
+                }
+              if (t == 4)
+                {
+                  r++;
+                  t = 0;
+                }
+            }
+        }              
+#undef W    
+    }
+
+  return 0;
+#undef tk
+#undef k
+}
+
+
+static gcry_err_code_t
+rijndael_setkey (void *context, const byte *key, const unsigned keylen)
+{
+  RIJNDAEL_context *ctx = context;
+
+  int rc = do_setkey (ctx, key, keylen);
+  _gcry_burn_stack ( 100 + 16*sizeof(int));
+  return rc;
+}
+
+
+/* Make a decryption key from an encryption key. */
+static void
+prepare_decryption( RIJNDAEL_context *ctx )
+{
+  int r;
+  union
+  {
+    PROPERLY_ALIGNED_TYPE dummy;
+    byte *w;
+  } w;
+#define w w.w
+
+  for (r=0; r < MAXROUNDS+1; r++ )
+    {
+      *((u32*)ctx->keySched2[r][0]) = *((u32*)ctx->keySched[r][0]);
+      *((u32*)ctx->keySched2[r][1]) = *((u32*)ctx->keySched[r][1]);
+      *((u32*)ctx->keySched2[r][2]) = *((u32*)ctx->keySched[r][2]);
+      *((u32*)ctx->keySched2[r][3]) = *((u32*)ctx->keySched[r][3]);
+    }
+#define W (ctx->keySched2)
+  for (r = 1; r < ctx->ROUNDS; r++)
+    {
+      w = W[r][0];
+      *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
+        ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
+       
+      w = W[r][1];
+      *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
+        ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
+        
+      w = W[r][2];
+      *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
+        ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
+        
+      w = W[r][3];
+      *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
+        ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
+    }
+#undef W
+#undef w
+}      
+
+
+\f
+/* Encrypt one block.  A and B need to be aligned on a 4 byte
+   boundary.  A and B may be the same. */
+static void
+do_encrypt_aligned (const RIJNDAEL_context *ctx, 
+                    unsigned char *b, const unsigned char *a)
+{
+#define rk (ctx->keySched)
+  int ROUNDS = ctx->ROUNDS;
+  int r;
+  union
+  {
+    u32  tempu32[4];  /* Force correct alignment. */
+    byte temp[4][4];
+  } u;
+
+  *((u32*)u.temp[0]) = *((u32*)(a   )) ^ *((u32*)rk[0][0]);
+  *((u32*)u.temp[1]) = *((u32*)(a+ 4)) ^ *((u32*)rk[0][1]);
+  *((u32*)u.temp[2]) = *((u32*)(a+ 8)) ^ *((u32*)rk[0][2]);
+  *((u32*)u.temp[3]) = *((u32*)(a+12)) ^ *((u32*)rk[0][3]);
+  *((u32*)(b    ))   = (*((u32*)T1[u.temp[0][0]])
+                        ^ *((u32*)T2[u.temp[1][1]])
+                        ^ *((u32*)T3[u.temp[2][2]]) 
+                        ^ *((u32*)T4[u.temp[3][3]]));
+  *((u32*)(b + 4))   = (*((u32*)T1[u.temp[1][0]])
+                        ^ *((u32*)T2[u.temp[2][1]])
+                        ^ *((u32*)T3[u.temp[3][2]]) 
+                        ^ *((u32*)T4[u.temp[0][3]]));
+  *((u32*)(b + 8))   = (*((u32*)T1[u.temp[2][0]])
+                        ^ *((u32*)T2[u.temp[3][1]])
+                        ^ *((u32*)T3[u.temp[0][2]]) 
+                        ^ *((u32*)T4[u.temp[1][3]]));
+  *((u32*)(b +12))   = (*((u32*)T1[u.temp[3][0]])
+                        ^ *((u32*)T2[u.temp[0][1]])
+                        ^ *((u32*)T3[u.temp[1][2]]) 
+                        ^ *((u32*)T4[u.temp[2][3]]));
+
+  for (r = 1; r < ROUNDS-1; r++)
+    {
+      *((u32*)u.temp[0]) = *((u32*)(b   )) ^ *((u32*)rk[r][0]);
+      *((u32*)u.temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[r][1]);
+      *((u32*)u.temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[r][2]);
+      *((u32*)u.temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[r][3]);
+
+      *((u32*)(b    ))   = (*((u32*)T1[u.temp[0][0]])
+                            ^ *((u32*)T2[u.temp[1][1]])
+                            ^ *((u32*)T3[u.temp[2][2]]) 
+                            ^ *((u32*)T4[u.temp[3][3]]));
+      *((u32*)(b + 4))   = (*((u32*)T1[u.temp[1][0]])
+                            ^ *((u32*)T2[u.temp[2][1]])
+                            ^ *((u32*)T3[u.temp[3][2]]) 
+                            ^ *((u32*)T4[u.temp[0][3]]));
+      *((u32*)(b + 8))   = (*((u32*)T1[u.temp[2][0]])
+                            ^ *((u32*)T2[u.temp[3][1]])
+                            ^ *((u32*)T3[u.temp[0][2]]) 
+                            ^ *((u32*)T4[u.temp[1][3]]));
+      *((u32*)(b +12))   = (*((u32*)T1[u.temp[3][0]])
+                            ^ *((u32*)T2[u.temp[0][1]])
+                            ^ *((u32*)T3[u.temp[1][2]]) 
+                            ^ *((u32*)T4[u.temp[2][3]]));
+    }
+
+  /* Last round is special. */   
+  *((u32*)u.temp[0]) = *((u32*)(b   )) ^ *((u32*)rk[ROUNDS-1][0]);
+  *((u32*)u.temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[ROUNDS-1][1]);
+  *((u32*)u.temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[ROUNDS-1][2]);
+  *((u32*)u.temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[ROUNDS-1][3]);
+  b[ 0] = T1[u.temp[0][0]][1];
+  b[ 1] = T1[u.temp[1][1]][1];
+  b[ 2] = T1[u.temp[2][2]][1];
+  b[ 3] = T1[u.temp[3][3]][1];
+  b[ 4] = T1[u.temp[1][0]][1];
+  b[ 5] = T1[u.temp[2][1]][1];
+  b[ 6] = T1[u.temp[3][2]][1];
+  b[ 7] = T1[u.temp[0][3]][1];
+  b[ 8] = T1[u.temp[2][0]][1];
+  b[ 9] = T1[u.temp[3][1]][1];
+  b[10] = T1[u.temp[0][2]][1];
+  b[11] = T1[u.temp[1][3]][1];
+  b[12] = T1[u.temp[3][0]][1];
+  b[13] = T1[u.temp[0][1]][1];
+  b[14] = T1[u.temp[1][2]][1];
+  b[15] = T1[u.temp[2][3]][1];
+  *((u32*)(b   )) ^= *((u32*)rk[ROUNDS][0]);
+  *((u32*)(b+ 4)) ^= *((u32*)rk[ROUNDS][1]);
+  *((u32*)(b+ 8)) ^= *((u32*)rk[ROUNDS][2]);
+  *((u32*)(b+12)) ^= *((u32*)rk[ROUNDS][3]);
+#undef rk
+}
+
+
+static void
+do_encrypt (const RIJNDAEL_context *ctx,
+            unsigned char *bx, const unsigned char *ax)
+{
+  /* BX and AX are not necessary correctly aligned.  Thus we need to
+     copy them here. */
+  union
+  {
+    u32  dummy[4]; 
+    byte a[16];
+  } a;
+  union
+  {
+    u32  dummy[4]; 
+    byte b[16];
+  } b;
+
+  memcpy (a.a, ax, 16);
+  do_encrypt_aligned (ctx, b.b, a.a);
+  memcpy (bx, b.b, 16);
+}
+
+
+/* Encrypt or decrypt one block using the padlock engine.  A and B may
+   be the same. */
+#ifdef USE_PADLOCK
+static void
+do_padlock (const RIJNDAEL_context *ctx, int decrypt_flag,
+            unsigned char *bx, const unsigned char *ax)
+{
+  /* BX and AX are not necessary correctly aligned.  Thus we need to
+     copy them here. */
+  unsigned char a[16] __attribute__ ((aligned (16)));
+  unsigned char b[16] __attribute__ ((aligned (16)));
+  unsigned int cword[4] __attribute__ ((aligned (16)));
+
+  /* The control word fields are:
+      127:12   11:10 9     8     7     6     5     4     3:0
+      RESERVED KSIZE CRYPT INTER KEYGN CIPHR ALIGN DGEST ROUND  */
+  cword[0] = (ctx->ROUNDS & 15);  /* (The mask is just a safeguard.)  */
+  cword[1] = 0;
+  cword[2] = 0;
+  cword[3] = 0;
+  if (decrypt_flag)
+    cword[0] |= 0x00000200;
+
+  memcpy (a, ax, 16);
+   
+  asm volatile 
+    ("pushfl\n\t"          /* Force key reload.  */            
+     "popfl\n\t"
+     "xchg %3, %%ebx\n\t"  /* Load key.  */
+     "movl $1, %%ecx\n\t"  /* Init counter for just one block.  */
+     ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XSTORE ECB. */
+     "xchg %3, %%ebx\n"    /* Restore GOT register.  */
+     : /* No output */
+     : "S" (a), "D" (b), "d" (cword), "r" (ctx->padlock_key)
+     : "%ecx", "cc", "memory"
+     );
+
+  memcpy (bx, b, 16);
+
+}
+#endif /*USE_PADLOCK*/
+
+
+static void
+rijndael_encrypt (void *context, byte *b, const byte *a)
+{
+  RIJNDAEL_context *ctx = context;
+
+#ifdef USE_PADLOCK
+  if (ctx->use_padlock)
+    {
+      do_padlock (ctx, 0, b, a);
+      _gcry_burn_stack (48 + 15 /* possible padding for alignment */);
+    }
+  else
+#endif /*USE_PADLOCK*/
+    {
+      do_encrypt (ctx, b, a);
+      _gcry_burn_stack (48 + 2*sizeof(int));
+    }
+}
+
+
+/* Bulk encryption of complete blocks in CFB mode.  Caller needs to
+   make sure that IV is aligned on an unsigned long boundary.  This
+   function is only intended for the bulk encryption feature of
+   cipher.c. */
+void
+_gcry_aes_cfb_enc (void *context, unsigned char *iv, 
+                   void *outbuf_arg, const void *inbuf_arg,
+                   unsigned int nblocks)
+{
+  RIJNDAEL_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char *ivp;
+  int i;
+
+#ifdef USE_PADLOCK
+  if (ctx->use_padlock)
+    {
+      /* Fixme: Let Padlock do the CFBing.  */
+      for ( ;nblocks; nblocks-- )
+        {
+          /* Encrypt the IV. */
+          do_padlock (ctx, 0, iv, iv);
+          /* XOR the input with the IV and store input into IV.  */
+          for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
+            *outbuf++ = (*ivp++ ^= *inbuf++);
+        }
+    }
+  else
+#endif /* USE_PADLOCK*/
+    {
+      for ( ;nblocks; nblocks-- )
+        {
+          /* Encrypt the IV. */
+          do_encrypt_aligned (ctx, iv, iv);
+          /* XOR the input with the IV and store input into IV.  */
+          for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
+            *outbuf++ = (*ivp++ ^= *inbuf++);
+        }
+    }
+
+  _gcry_burn_stack (48 + 2*sizeof(int));
+}
+
+
+/* Bulk encryption of complete blocks in CBC mode.  Caller needs to
+   make sure that IV is aligned on an unsigned long boundary.  This
+   function is only intended for the bulk encryption feature of
+   cipher.c. */
+void
+_gcry_aes_cbc_enc (void *context, unsigned char *iv, 
+                   void *outbuf_arg, const void *inbuf_arg,
+                   unsigned int nblocks, int cbc_mac)
+{
+  RIJNDAEL_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char *ivp;
+  int i;
+
+  for ( ;nblocks; nblocks-- )
+    {
+      for (ivp=iv, i=0; i < BLOCKSIZE; i++ )
+        outbuf[i] = inbuf[i] ^ *ivp++;
+
+#ifdef USE_PADLOCK
+      if (ctx->use_padlock)
+        do_padlock (ctx, 0, outbuf, outbuf);
+      else
+#endif /*USE_PADLOCK*/
+        do_encrypt (ctx, outbuf, outbuf );
+
+      memcpy (iv, outbuf, BLOCKSIZE);
+      inbuf += BLOCKSIZE;
+      if (!cbc_mac)
+        outbuf += BLOCKSIZE;
+    }
+
+  _gcry_burn_stack (48 + 2*sizeof(int));
+}
+
+
+\f
+/* Decrypt one block.  A and B need to be aligned on a 4 byte boundary
+   and the decryption must have been prepared.  A and B may be the
+   same. */
+static void
+do_decrypt_aligned (RIJNDAEL_context *ctx, 
+                    unsigned char *b, const unsigned char *a)
+{
+#define rk  (ctx->keySched2)
+  int ROUNDS = ctx->ROUNDS; 
+  int r;
+  union 
+  {
+    u32  tempu32[4];  /* Force correct alignment. */
+    byte temp[4][4];
+  } u;
+
+
+  *((u32*)u.temp[0]) = *((u32*)(a   )) ^ *((u32*)rk[ROUNDS][0]);
+  *((u32*)u.temp[1]) = *((u32*)(a+ 4)) ^ *((u32*)rk[ROUNDS][1]);
+  *((u32*)u.temp[2]) = *((u32*)(a+ 8)) ^ *((u32*)rk[ROUNDS][2]);
+  *((u32*)u.temp[3]) = *((u32*)(a+12)) ^ *((u32*)rk[ROUNDS][3]);
+  
+  *((u32*)(b   ))    = (*((u32*)T5[u.temp[0][0]])
+                        ^ *((u32*)T6[u.temp[3][1]])
+                        ^ *((u32*)T7[u.temp[2][2]]) 
+                        ^ *((u32*)T8[u.temp[1][3]]));
+  *((u32*)(b+ 4))    = (*((u32*)T5[u.temp[1][0]])
+                        ^ *((u32*)T6[u.temp[0][1]])
+                        ^ *((u32*)T7[u.temp[3][2]]) 
+                        ^ *((u32*)T8[u.temp[2][3]]));
+  *((u32*)(b+ 8))    = (*((u32*)T5[u.temp[2][0]])
+                        ^ *((u32*)T6[u.temp[1][1]])
+                        ^ *((u32*)T7[u.temp[0][2]]) 
+                        ^ *((u32*)T8[u.temp[3][3]]));
+  *((u32*)(b+12))    = (*((u32*)T5[u.temp[3][0]])
+                        ^ *((u32*)T6[u.temp[2][1]])
+                        ^ *((u32*)T7[u.temp[1][2]]) 
+                        ^ *((u32*)T8[u.temp[0][3]]));
+
+  for (r = ROUNDS-1; r > 1; r--)
+    {
+      *((u32*)u.temp[0]) = *((u32*)(b   )) ^ *((u32*)rk[r][0]);
+      *((u32*)u.temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[r][1]);
+      *((u32*)u.temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[r][2]);
+      *((u32*)u.temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[r][3]);
+      *((u32*)(b   ))    = (*((u32*)T5[u.temp[0][0]])
+                            ^ *((u32*)T6[u.temp[3][1]])
+                            ^ *((u32*)T7[u.temp[2][2]]) 
+                            ^ *((u32*)T8[u.temp[1][3]]));
+      *((u32*)(b+ 4))    = (*((u32*)T5[u.temp[1][0]])
+                            ^ *((u32*)T6[u.temp[0][1]])
+                            ^ *((u32*)T7[u.temp[3][2]]) 
+                            ^ *((u32*)T8[u.temp[2][3]]));
+      *((u32*)(b+ 8))    = (*((u32*)T5[u.temp[2][0]])
+                            ^ *((u32*)T6[u.temp[1][1]])
+                            ^ *((u32*)T7[u.temp[0][2]]) 
+                            ^ *((u32*)T8[u.temp[3][3]]));
+      *((u32*)(b+12))    = (*((u32*)T5[u.temp[3][0]])
+                            ^ *((u32*)T6[u.temp[2][1]])
+                            ^ *((u32*)T7[u.temp[1][2]]) 
+                            ^ *((u32*)T8[u.temp[0][3]]));
+    }
+
+  /* Last round is special. */   
+  *((u32*)u.temp[0]) = *((u32*)(b   )) ^ *((u32*)rk[1][0]);
+  *((u32*)u.temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[1][1]);
+  *((u32*)u.temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[1][2]);
+  *((u32*)u.temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[1][3]);
+  b[ 0] = S5[u.temp[0][0]];
+  b[ 1] = S5[u.temp[3][1]];
+  b[ 2] = S5[u.temp[2][2]];
+  b[ 3] = S5[u.temp[1][3]];
+  b[ 4] = S5[u.temp[1][0]];
+  b[ 5] = S5[u.temp[0][1]];
+  b[ 6] = S5[u.temp[3][2]];
+  b[ 7] = S5[u.temp[2][3]];
+  b[ 8] = S5[u.temp[2][0]];
+  b[ 9] = S5[u.temp[1][1]];
+  b[10] = S5[u.temp[0][2]];
+  b[11] = S5[u.temp[3][3]];
+  b[12] = S5[u.temp[3][0]];
+  b[13] = S5[u.temp[2][1]];
+  b[14] = S5[u.temp[1][2]];
+  b[15] = S5[u.temp[0][3]];
+  *((u32*)(b   )) ^= *((u32*)rk[0][0]);
+  *((u32*)(b+ 4)) ^= *((u32*)rk[0][1]);
+  *((u32*)(b+ 8)) ^= *((u32*)rk[0][2]);
+  *((u32*)(b+12)) ^= *((u32*)rk[0][3]);
+#undef rk
+}
+
+
+/* Decrypt one block.  AX and BX may be the same. */
+static void
+do_decrypt (RIJNDAEL_context *ctx, byte *bx, const byte *ax)
+{
+  /* BX and AX are not necessary correctly aligned.  Thus we need to
+     copy them here. */
+  union
+  {
+    u32  dummy[4]; 
+    byte a[16];
+  } a;
+  union
+  {
+    u32  dummy[4]; 
+    byte b[16];
+  } b;
+
+  if ( !ctx->decryption_prepared )
+    {
+      prepare_decryption ( ctx );
+      _gcry_burn_stack (64);
+      ctx->decryption_prepared = 1;
+    }
+
+  memcpy (a.a, ax, 16);
+  do_decrypt_aligned (ctx, b.b, a.a);
+  memcpy (bx, b.b, 16);
+#undef rk
+}
+    
+
+
+
+static void
+rijndael_decrypt (void *context, byte *b, const byte *a)
+{
+  RIJNDAEL_context *ctx = context;
+
+#ifdef USE_PADLOCK
+  if (ctx->use_padlock)
+    {
+      do_padlock (ctx, 1, b, a);
+      _gcry_burn_stack (48 + 2*sizeof(int) /* FIXME */);
+    }
+  else
+#endif /*USE_PADLOCK*/
+    {
+      do_decrypt (ctx, b, a);
+      _gcry_burn_stack (48+2*sizeof(int));
+    }
+}
+
+
+/* Bulk decryption of complete blocks in CFB mode.  Caller needs to
+   make sure that IV is aligned on an unisgned lonhg boundary.  This
+   function is only intended for the bulk encryption feature of
+   cipher.c. */
+void
+_gcry_aes_cfb_dec (void *context, unsigned char *iv, 
+                   void *outbuf_arg, const void *inbuf_arg,
+                   unsigned int nblocks)
+{
+  RIJNDAEL_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char *ivp;
+  unsigned char temp;
+  int i;
+
+#ifdef USE_PADLOCK
+  if (ctx->use_padlock)
+    {
+      /* Fixme:  Let Padlock do the CFBing.  */
+      for ( ;nblocks; nblocks-- )
+        {
+          do_padlock (ctx, 0, iv, iv);
+          for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
+            {
+              temp = *inbuf++;
+              *outbuf++ = *ivp ^ temp;
+              *ivp++ = temp;
+            }
+        }
+    }
+  else
+#endif /*USE_PADLOCK*/
+    {
+      for ( ;nblocks; nblocks-- )
+        {
+          do_encrypt_aligned (ctx, iv, iv);
+          for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
+            {
+              temp = *inbuf++;
+              *outbuf++ = *ivp ^ temp;
+              *ivp++ = temp;
+            }
+        }
+    }
+
+  _gcry_burn_stack (48 + 2*sizeof(int));
+}
+
+
+/* Bulk decryption of complete blocks in CBC mode.  Caller needs to
+   make sure that IV is aligned on an unsigned long boundary.  This
+   function is only intended for the bulk encryption feature of
+   cipher.c. */
+void
+_gcry_aes_cbc_dec (void *context, unsigned char *iv, 
+                   void *outbuf_arg, const void *inbuf_arg,
+                   unsigned int nblocks)
+{
+  RIJNDAEL_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char *ivp;
+  int i;
+  unsigned char savebuf[BLOCKSIZE];
+
+  for ( ;nblocks; nblocks-- )
+    {
+      /* We need to save INBUF away because it may be identical to
+         OUTBUF.  */
+      memcpy (savebuf, inbuf, BLOCKSIZE);
+
+#ifdef USE_PADLOCK
+      if (ctx->use_padlock)
+        do_padlock (ctx, 1, outbuf, inbuf);
+      else
+#endif /*USE_PADLOCK*/
+        do_decrypt (ctx, outbuf, inbuf);
+
+      for (ivp=iv, i=0; i < BLOCKSIZE; i++ )
+        outbuf[i] ^= *ivp++;
+      memcpy (iv, savebuf, BLOCKSIZE);
+      inbuf += BLOCKSIZE;
+      outbuf += BLOCKSIZE;
+    }
+
+  _gcry_burn_stack (48 + 2*sizeof(int) + BLOCKSIZE + 4*sizeof (char*));
+}
+
+
+
+\f
+/* Run the self-tests for AES 128.  Returns NULL on success. */
+static const char*
+selftest_basic_128 (void)
+{
+  RIJNDAEL_context ctx;
+  unsigned char scratch[16];      
+
+  /* The test vectors are from the AES supplied ones; more or less
+     randomly taken from ecb_tbl.txt (I=42,81,14) */
+  static const unsigned char plaintext_128[16] = 
+    {
+      0x01,0x4B,0xAF,0x22,0x78,0xA6,0x9D,0x33,
+      0x1D,0x51,0x80,0x10,0x36,0x43,0xE9,0x9A
+    };
+  static const unsigned char key_128[16] =
+    {
+      0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF,0xF0,
+      0xF2,0xF3,0xF4,0xF5,0xF7,0xF8,0xF9,0xFA
+    };
+  static const unsigned char ciphertext_128[16] =
+    {
+      0x67,0x43,0xC3,0xD1,0x51,0x9A,0xB4,0xF2,
+      0xCD,0x9A,0x78,0xAB,0x09,0xA5,0x11,0xBD
+    };
+  
+  rijndael_setkey (&ctx, key_128, sizeof (key_128));
+  rijndael_encrypt (&ctx, scratch, plaintext_128);
+  if (memcmp (scratch, ciphertext_128, sizeof (ciphertext_128)))
+     return "AES-128 test encryption failed.";
+  rijndael_decrypt (&ctx, scratch, scratch);
+  if (memcmp (scratch, plaintext_128, sizeof (plaintext_128)))
+    return "AES-128 test decryption failed.";
+  
+  return NULL;
+}
+
+/* Run the self-tests for AES 192.  Returns NULL on success. */
+static const char*
+selftest_basic_192 (void)
+{
+  RIJNDAEL_context ctx;
+  unsigned char scratch[16];      
+  
+  static unsigned char plaintext_192[16] = 
+    {
+      0x76,0x77,0x74,0x75,0xF1,0xF2,0xF3,0xF4,
+      0xF8,0xF9,0xE6,0xE7,0x77,0x70,0x71,0x72
+    };
+  static unsigned char key_192[24] = 
+    {
+      0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C,
+      0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16,
+      0x18,0x19,0x1A,0x1B,0x1D,0x1E,0x1F,0x20
+    };
+  static const unsigned char ciphertext_192[16] =
+    {
+      0x5D,0x1E,0xF2,0x0D,0xCE,0xD6,0xBC,0xBC,
+      0x12,0x13,0x1A,0xC7,0xC5,0x47,0x88,0xAA
+    };
+    
+  rijndael_setkey (&ctx, key_192, sizeof(key_192));
+  rijndael_encrypt (&ctx, scratch, plaintext_192);
+  if (memcmp (scratch, ciphertext_192, sizeof (ciphertext_192)))
+    return "AES-192 test encryption failed.";
+  rijndael_decrypt (&ctx, scratch, scratch);
+  if (memcmp (scratch, plaintext_192, sizeof (plaintext_192)))
+    return "AES-192 test decryption failed.";
+  
+  return NULL;
+}
+
+
+/* Run the self-tests for AES 256.  Returns NULL on success. */
+static const char*
+selftest_basic_256 (void)
+{
+  RIJNDAEL_context ctx;
+  unsigned char scratch[16];      
+
+  static unsigned char plaintext_256[16] = 
+    {
+      0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
+      0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21
+    };
+  static unsigned char key_256[32] = 
+    {
+      0x08,0x09,0x0A,0x0B,0x0D,0x0E,0x0F,0x10,
+      0x12,0x13,0x14,0x15,0x17,0x18,0x19,0x1A,
+      0x1C,0x1D,0x1E,0x1F,0x21,0x22,0x23,0x24,
+      0x26,0x27,0x28,0x29,0x2B,0x2C,0x2D,0x2E
+    };
+  static const unsigned char ciphertext_256[16] = 
+    {
+      0x08,0x0E,0x95,0x17,0xEB,0x16,0x77,0x71,
+      0x9A,0xCF,0x72,0x80,0x86,0x04,0x0A,0xE3
+    };
+
+  rijndael_setkey (&ctx, key_256, sizeof(key_256));
+  rijndael_encrypt (&ctx, scratch, plaintext_256);
+  if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256)))
+    return "AES-256 test encryption failed.";
+  rijndael_decrypt (&ctx, scratch, scratch);
+  if (memcmp (scratch, plaintext_256, sizeof (plaintext_256)))
+    return "AES-256 test decryption failed.";
+    
+  return NULL;
+}
+
+/* Run all the self-tests and return NULL on success.  This function
+   is used for the on-the-fly self-tests. */
+static const char *
+selftest (void)
+{
+  const char *r;
+
+  if ( (r = selftest_basic_128 ())
+       || (r = selftest_basic_192 ())
+       || (r = selftest_basic_256 ()) )
+    return r;
+
+  return r;
+}
+
+
+/* SP800-38a.pdf for AES-128.  */
+static const char *
+selftest_fips_128_38a (int requested_mode)
+{
+  struct tv
+  {
+    int mode;
+    const unsigned char key[16];
+    const unsigned char iv[16];
+    struct 
+    {
+      const unsigned char input[16];
+      const unsigned char output[16];
+    } data[4];
+  } tv[2] =
+    {
+      {
+        GCRY_CIPHER_MODE_CFB,  /* F.3.13, CFB128-AES128 */
+        { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+          0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
+        { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
+          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+        {
+          { { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+              0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a },
+            { 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
+              0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a } },
+          
+          { { 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+              0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 },
+            { 0xc8, 0xa6, 0x45, 0x37, 0xa0, 0xb3, 0xa9, 0x3f,
+              0xcd, 0xe3, 0xcd, 0xad, 0x9f, 0x1c, 0xe5, 0x8b } },
+          
+          { { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 
+              0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef },
+            { 0x26, 0x75, 0x1f, 0x67, 0xa3, 0xcb, 0xb1, 0x40,
+              0xb1, 0x80, 0x8c, 0xf1, 0x87, 0xa4, 0xf4, 0xdf } },
+          
+          { { 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+              0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
+            { 0xc0, 0x4b, 0x05, 0x35, 0x7c, 0x5d, 0x1c, 0x0e,
+              0xea, 0xc4, 0xc6, 0x6f, 0x9f, 0xf7, 0xf2, 0xe6 } }
+        }
+      },
+      {
+        GCRY_CIPHER_MODE_OFB,
+        { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+          0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
+        { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
+          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+        {
+          { { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+              0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a },
+            { 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
+              0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a } },
+
+          { { 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+              0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 },
+            { 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
+              0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25 } },
+          
+          { { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+              0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef },
+            { 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
+              0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc } },
+
+          { { 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+              0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
+            { 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
+              0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e } },
+        }
+      }
+    };
+  unsigned char scratch[16];
+  gpg_error_t err;
+  int tvi, idx;
+  gcry_cipher_hd_t hdenc = NULL;
+  gcry_cipher_hd_t hddec = NULL;
+
+#define Fail(a) do {           \
+    _gcry_cipher_close (hdenc);  \
+    _gcry_cipher_close (hddec);  \
+    return a;                    \
+  } while (0)
+
+  gcry_assert (sizeof tv[0].data[0].input == sizeof scratch);
+  gcry_assert (sizeof tv[0].data[0].output == sizeof scratch);
+
+  for (tvi=0; tvi < DIM (tv); tvi++)
+    if (tv[tvi].mode == requested_mode)
+      break;
+  if (tvi == DIM (tv))
+    Fail ("no test data for this mode");
+
+  err = _gcry_cipher_open (&hdenc, GCRY_CIPHER_AES, tv[tvi].mode, 0);
+  if (err)
+    Fail ("open");
+  err = _gcry_cipher_open (&hddec, GCRY_CIPHER_AES, tv[tvi].mode, 0);
+  if (err)
+    Fail ("open");
+  err = _gcry_cipher_setkey (hdenc, tv[tvi].key,  sizeof tv[tvi].key);
+  if (!err)
+    err = _gcry_cipher_setkey (hddec, tv[tvi].key, sizeof tv[tvi].key);
+  if (err)
+    Fail ("set key");
+  err = _gcry_cipher_setiv (hdenc, tv[tvi].iv, sizeof tv[tvi].iv);
+  if (!err)
+    err = _gcry_cipher_setiv (hddec, tv[tvi].iv, sizeof tv[tvi].iv);
+  if (err)
+    Fail ("set IV");
+  for (idx=0; idx < DIM (tv[tvi].data); idx++)
+    {
+      err = _gcry_cipher_encrypt (hdenc, scratch, sizeof scratch,
+                                  tv[tvi].data[idx].input,
+                                  sizeof tv[tvi].data[idx].input);
+      if (err)
+        Fail ("encrypt command");
+      if (memcmp (scratch, tv[tvi].data[idx].output, sizeof scratch))
+        Fail ("encrypt mismatch");
+      err = _gcry_cipher_decrypt (hddec, scratch, sizeof scratch,
+                                  tv[tvi].data[idx].output,
+                                  sizeof tv[tvi].data[idx].output);
+      if (err)
+        Fail ("decrypt command");
+      if (memcmp (scratch, tv[tvi].data[idx].input, sizeof scratch))
+        Fail ("decrypt mismatch");
+    }
+
+#undef Fail
+  _gcry_cipher_close (hdenc);
+  _gcry_cipher_close (hddec); 
+  return NULL;
+}
+
+
+/* Complete selftest for AES-128 with all modes and driver code.  */
+static gpg_err_code_t
+selftest_fips_128 (int extended, selftest_report_func_t report)
+{
+  const char *what;
+  const char *errtxt;
+  
+  what = "low-level";
+  errtxt = selftest_basic_128 ();
+  if (errtxt)
+    goto failed;
+
+  if (extended)
+    {
+      what = "cfb";
+      errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_CFB);
+      if (errtxt)
+        goto failed;
+      
+      what = "ofb";
+      errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_OFB);
+      if (errtxt)
+        goto failed;
+    }
+
+  return 0; /* Succeeded. */
+
+ failed:
+  if (report)
+    report ("cipher", GCRY_CIPHER_AES128, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+/* Complete selftest for AES-192.  */
+static gpg_err_code_t
+selftest_fips_192 (int extended, selftest_report_func_t report)
+{
+  const char *what;
+  const char *errtxt;
+
+  (void)extended; /* No extended tests available.  */
+
+  what = "low-level";
+  errtxt = selftest_basic_192 ();
+  if (errtxt)
+    goto failed;
+
+
+  return 0; /* Succeeded. */
+
+ failed:
+  if (report)
+    report ("cipher", GCRY_CIPHER_AES192, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Complete selftest for AES-256.  */
+static gpg_err_code_t
+selftest_fips_256 (int extended, selftest_report_func_t report)
+{
+  const char *what;
+  const char *errtxt;
+  
+  (void)extended; /* No extended tests available.  */
+
+  what = "low-level";
+  errtxt = selftest_basic_256 ();
+  if (errtxt)
+    goto failed;
+
+  return 0; /* Succeeded. */
+
+ failed:
+  if (report)
+    report ("cipher", GCRY_CIPHER_AES256, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+
+/* Run a full self-test for ALGO and return 0 on success.  */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+  gpg_err_code_t ec;
+
+  switch (algo)
+    {
+    case GCRY_CIPHER_AES128:
+      ec = selftest_fips_128 (extended, report);
+      break;
+    case GCRY_CIPHER_AES192:
+      ec = selftest_fips_192 (extended, report);
+      break;
+    case GCRY_CIPHER_AES256:
+      ec = selftest_fips_256 (extended, report);
+      break;
+    default:
+      ec = GPG_ERR_CIPHER_ALGO;
+      break;
+        
+    }
+  return ec;
+}
+
+
+\f
+
+static const char *rijndael_names[] =
+  {
+    "RIJNDAEL",
+    "AES128",
+    "AES-128",
+    NULL
+  };
+
+static gcry_cipher_oid_spec_t rijndael_oids[] =
+  {
+    { "2.16.840.1.101.3.4.1.1", GCRY_CIPHER_MODE_ECB },
+    { "2.16.840.1.101.3.4.1.2", GCRY_CIPHER_MODE_CBC },
+    { "2.16.840.1.101.3.4.1.3", GCRY_CIPHER_MODE_OFB },
+    { "2.16.840.1.101.3.4.1.4", GCRY_CIPHER_MODE_CFB },
+    { NULL }
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_aes =
+  {
+    "AES", rijndael_names, rijndael_oids, 16, 128, sizeof (RIJNDAEL_context),
+    rijndael_setkey, rijndael_encrypt, rijndael_decrypt
+  };
+cipher_extra_spec_t _gcry_cipher_extraspec_aes = 
+  {
+    run_selftests
+  };
+
+static const char *rijndael192_names[] =
+  {
+    "RIJNDAEL192",
+    "AES-192",
+    NULL
+  };
+
+static gcry_cipher_oid_spec_t rijndael192_oids[] =
+  {
+    { "2.16.840.1.101.3.4.1.21", GCRY_CIPHER_MODE_ECB },
+    { "2.16.840.1.101.3.4.1.22", GCRY_CIPHER_MODE_CBC },
+    { "2.16.840.1.101.3.4.1.23", GCRY_CIPHER_MODE_OFB },
+    { "2.16.840.1.101.3.4.1.24", GCRY_CIPHER_MODE_CFB },
+    { NULL }
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_aes192 =
+  {
+    "AES192", rijndael192_names, rijndael192_oids, 16, 192, sizeof (RIJNDAEL_context),
+    rijndael_setkey, rijndael_encrypt, rijndael_decrypt
+  };
+cipher_extra_spec_t _gcry_cipher_extraspec_aes192 = 
+  {
+    run_selftests
+  };
+
+static const char *rijndael256_names[] =
+  {
+    "RIJNDAEL256",
+    "AES-256",
+    NULL
+  };
+
+static gcry_cipher_oid_spec_t rijndael256_oids[] =
+  {
+    { "2.16.840.1.101.3.4.1.41", GCRY_CIPHER_MODE_ECB },
+    { "2.16.840.1.101.3.4.1.42", GCRY_CIPHER_MODE_CBC },
+    { "2.16.840.1.101.3.4.1.43", GCRY_CIPHER_MODE_OFB },
+    { "2.16.840.1.101.3.4.1.44", GCRY_CIPHER_MODE_CFB },
+    { NULL }
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_aes256 =
+  {
+    "AES256", rijndael256_names, rijndael256_oids, 16, 256,
+    sizeof (RIJNDAEL_context),
+    rijndael_setkey, rijndael_encrypt, rijndael_decrypt
+  };
+
+cipher_extra_spec_t _gcry_cipher_extraspec_aes256 = 
+  {
+    run_selftests
+  };
diff --git a/grub-core/lib/libgcrypt/cipher/rmd.h b/grub-core/lib/libgcrypt/cipher/rmd.h
new file mode 100644 (file)
index 0000000..f4ce9c6
--- /dev/null
@@ -0,0 +1,37 @@
+/* rmd.h - RIPE-MD hash functions
+ *     Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#ifndef G10_RMD_H
+#define G10_RMD_H
+
+
+/* We need this here because random.c must have direct access. */
+typedef struct 
+{
+  u32  h0,h1,h2,h3,h4;
+  u32  nblocks;
+  byte buf[64];
+  int  count;
+} RMD160_CONTEXT;
+
+void _gcry_rmd160_init ( void *context );
+void _gcry_rmd160_mixblock ( RMD160_CONTEXT *hd, void *blockof64byte );
+
+#endif /*G10_RMD_H*/
+
diff --git a/grub-core/lib/libgcrypt/cipher/rmd160.c b/grub-core/lib/libgcrypt/cipher/rmd160.c
new file mode 100644 (file)
index 0000000..7805bf5
--- /dev/null
@@ -0,0 +1,572 @@
+/* rmd160.c  - RIPE-MD160
+ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "memory.h"
+#include "rmd.h"
+#include "cipher.h" /* Only used for the rmd160_hash_buffer() prototype. */
+
+#include "bithelp.h"
+
+/*********************************
+ * RIPEMD-160 is not patented, see (as of 25.10.97)
+ *   http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
+ * Note that the code uses Little Endian byteorder, which is good for
+ * 386 etc, but we must add some conversion when used on a big endian box.
+ *
+ *
+ * Pseudo-code for RIPEMD-160
+ *
+ * RIPEMD-160 is an iterative hash function that operates on 32-bit words.
+ * The round function takes as input a 5-word chaining variable and a 16-word
+ * message block and maps this to a new chaining variable. All operations are
+ * defined on 32-bit words. Padding is identical to that of MD4.
+ *
+ *
+ * RIPEMD-160: definitions
+ *
+ *
+ *   nonlinear functions at bit level: exor, mux, -, mux, -
+ *
+ *   f(j, x, y, z) = x XOR y XOR z               (0 <= j <= 15)
+ *   f(j, x, y, z) = (x AND y) OR (NOT(x) AND z)  (16 <= j <= 31)
+ *   f(j, x, y, z) = (x OR NOT(y)) XOR z         (32 <= j <= 47)
+ *   f(j, x, y, z) = (x AND z) OR (y AND NOT(z))  (48 <= j <= 63)
+ *   f(j, x, y, z) = x XOR (y OR NOT(z))         (64 <= j <= 79)
+ *
+ *
+ *   added constants (hexadecimal)
+ *
+ *   K(j) = 0x00000000     (0 <= j <= 15)
+ *   K(j) = 0x5A827999    (16 <= j <= 31)      int(2**30 x sqrt(2))
+ *   K(j) = 0x6ED9EBA1    (32 <= j <= 47)      int(2**30 x sqrt(3))
+ *   K(j) = 0x8F1BBCDC    (48 <= j <= 63)      int(2**30 x sqrt(5))
+ *   K(j) = 0xA953FD4E    (64 <= j <= 79)      int(2**30 x sqrt(7))
+ *   K'(j) = 0x50A28BE6     (0 <= j <= 15)      int(2**30 x cbrt(2))
+ *   K'(j) = 0x5C4DD124    (16 <= j <= 31)      int(2**30 x cbrt(3))
+ *   K'(j) = 0x6D703EF3    (32 <= j <= 47)      int(2**30 x cbrt(5))
+ *   K'(j) = 0x7A6D76E9    (48 <= j <= 63)      int(2**30 x cbrt(7))
+ *   K'(j) = 0x00000000    (64 <= j <= 79)
+ *
+ *
+ *   selection of message word
+ *
+ *   r(j)      = j                   (0 <= j <= 15)
+ *   r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
+ *   r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
+ *   r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
+ *   r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
+ *   r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
+ *   r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
+ *   r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
+ *   r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
+ *   r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
+ *
+ *
+ *   amount for rotate left (rol)
+ *
+ *   s(0..15)  = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
+ *   s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
+ *   s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
+ *   s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
+ *   s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
+ *   s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
+ *   s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
+ *   s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
+ *   s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
+ *   s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
+ *
+ *
+ *   initial value (hexadecimal)
+ *
+ *   h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
+ *                                                     h4 = 0xC3D2E1F0;
+ *
+ *
+ * RIPEMD-160: pseudo-code
+ *
+ *   It is assumed that the message after padding consists of t 16-word blocks
+ *   that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15.
+ *   The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left
+ *   shift (rotate) over s positions.
+ *
+ *
+ *   for i := 0 to t-1 {
+ *      A := h0; B := h1; C := h2; D = h3; E = h4;
+ *      A' := h0; B' := h1; C' := h2; D' = h3; E' = h4;
+ *      for j := 0 to 79 {
+ *          T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E;
+ *          A := E; E := D; D := rol_10(C); C := B; B := T;
+ *          T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)]
+                                                      [+] K'(j)) [+] E';
+ *          A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
+ *      }
+ *      T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
+ *      h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
+ *   }
+ */
+
+/* Some examples:
+ * ""                    9c1185a5c5e9fc54612808977ee8f548b2258d31
+ * "a"                   0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
+ * "abc"                 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
+ * "message digest"      5d0689ef49d2fae572b881b123a85ffa21595f36
+ * "a...z"               f71c27109c692c1b56bbdceb5b9d2865b3708dbc
+ * "abcdbcde...nopq"     12a053384a9c0c88e405a06c27dcf49ada62eb2b
+ * "A...Za...z0...9"     b0e20b6e3116640286ed3a87a5713079b21f5189
+ * 8 times "1234567890"  9b752e45573d4b39f4dbd3323cab82bf63326bfb
+ * 1 million times "a"   52783243c1697bdbe16d37f97f68f08325dc1528
+ */
+
+
+void
+_gcry_rmd160_init (void *context)
+{
+  RMD160_CONTEXT *hd = context;
+
+  hd->h0 = 0x67452301;
+  hd->h1 = 0xEFCDAB89;
+  hd->h2 = 0x98BADCFE;
+  hd->h3 = 0x10325476;
+  hd->h4 = 0xC3D2E1F0;
+  hd->nblocks = 0;
+  hd->count = 0;
+}
+
+
+
+/****************
+ * Transform the message X which consists of 16 32-bit-words
+ */
+static void
+transform ( RMD160_CONTEXT *hd, const unsigned char *data )
+{
+  register u32 a,b,c,d,e;
+  u32 aa,bb,cc,dd,ee,t;
+#ifdef WORDS_BIGENDIAN
+  u32 x[16];
+  {
+    int i;
+    byte *p2, *p1;
+    for (i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 )
+      {
+        p2[3] = *p1++;
+        p2[2] = *p1++;
+        p2[1] = *p1++;
+        p2[0] = *p1++;
+      }
+  }
+#else
+  /* This version is better because it is always aligned;
+   * The performance penalty on a 586-100 is about 6% which
+   * is acceptable - because the data is more local it might
+   * also be possible that this is faster on some machines.
+   * This function (when compiled with -02 on gcc 2.7.2)
+   * executes on a 586-100 (39.73 bogomips) at about 1900kb/sec;
+   * [measured with a 4MB data and "gpgm --print-md rmd160"] */
+  u32 x[16];
+  memcpy( x, data, 64 );
+#endif
+
+
+#define K0  0x00000000
+#define K1  0x5A827999
+#define K2  0x6ED9EBA1
+#define K3  0x8F1BBCDC
+#define K4  0xA953FD4E
+#define KK0 0x50A28BE6
+#define KK1 0x5C4DD124
+#define KK2 0x6D703EF3
+#define KK3 0x7A6D76E9
+#define KK4 0x00000000
+#define F0(x,y,z)   ( (x) ^ (y) ^ (z) )
+#define F1(x,y,z)   ( ((x) & (y)) | (~(x) & (z)) )
+#define F2(x,y,z)   ( ((x) | ~(y)) ^ (z) )
+#define F3(x,y,z)   ( ((x) & (z)) | ((y) & ~(z)) )
+#define F4(x,y,z)   ( (x) ^ ((y) | ~(z)) )
+#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
+                                 a = rol(t,s) + e;            \
+                                 c = rol(c,10);               \
+                               } while(0)
+
+  /* left lane */
+  a = hd->h0;
+  b = hd->h1;
+  c = hd->h2;
+  d = hd->h3;
+  e = hd->h4;
+  R( a, b, c, d, e, F0, K0,  0, 11 );
+  R( e, a, b, c, d, F0, K0,  1, 14 );
+  R( d, e, a, b, c, F0, K0,  2, 15 );
+  R( c, d, e, a, b, F0, K0,  3, 12 );
+  R( b, c, d, e, a, F0, K0,  4,  5 );
+  R( a, b, c, d, e, F0, K0,  5,  8 );
+  R( e, a, b, c, d, F0, K0,  6,  7 );
+  R( d, e, a, b, c, F0, K0,  7,  9 );
+  R( c, d, e, a, b, F0, K0,  8, 11 );
+  R( b, c, d, e, a, F0, K0,  9, 13 );
+  R( a, b, c, d, e, F0, K0, 10, 14 );
+  R( e, a, b, c, d, F0, K0, 11, 15 );
+  R( d, e, a, b, c, F0, K0, 12,  6 );
+  R( c, d, e, a, b, F0, K0, 13,  7 );
+  R( b, c, d, e, a, F0, K0, 14,  9 );
+  R( a, b, c, d, e, F0, K0, 15,  8 );
+  R( e, a, b, c, d, F1, K1,  7,  7 );
+  R( d, e, a, b, c, F1, K1,  4,  6 );
+  R( c, d, e, a, b, F1, K1, 13,  8 );
+  R( b, c, d, e, a, F1, K1,  1, 13 );
+  R( a, b, c, d, e, F1, K1, 10, 11 );
+  R( e, a, b, c, d, F1, K1,  6,  9 );
+  R( d, e, a, b, c, F1, K1, 15,  7 );
+  R( c, d, e, a, b, F1, K1,  3, 15 );
+  R( b, c, d, e, a, F1, K1, 12,  7 );
+  R( a, b, c, d, e, F1, K1,  0, 12 );
+  R( e, a, b, c, d, F1, K1,  9, 15 );
+  R( d, e, a, b, c, F1, K1,  5,  9 );
+  R( c, d, e, a, b, F1, K1,  2, 11 );
+  R( b, c, d, e, a, F1, K1, 14,  7 );
+  R( a, b, c, d, e, F1, K1, 11, 13 );
+  R( e, a, b, c, d, F1, K1,  8, 12 );
+  R( d, e, a, b, c, F2, K2,  3, 11 );
+  R( c, d, e, a, b, F2, K2, 10, 13 );
+  R( b, c, d, e, a, F2, K2, 14,  6 );
+  R( a, b, c, d, e, F2, K2,  4,  7 );
+  R( e, a, b, c, d, F2, K2,  9, 14 );
+  R( d, e, a, b, c, F2, K2, 15,  9 );
+  R( c, d, e, a, b, F2, K2,  8, 13 );
+  R( b, c, d, e, a, F2, K2,  1, 15 );
+  R( a, b, c, d, e, F2, K2,  2, 14 );
+  R( e, a, b, c, d, F2, K2,  7,  8 );
+  R( d, e, a, b, c, F2, K2,  0, 13 );
+  R( c, d, e, a, b, F2, K2,  6,  6 );
+  R( b, c, d, e, a, F2, K2, 13,  5 );
+  R( a, b, c, d, e, F2, K2, 11, 12 );
+  R( e, a, b, c, d, F2, K2,  5,  7 );
+  R( d, e, a, b, c, F2, K2, 12,  5 );
+  R( c, d, e, a, b, F3, K3,  1, 11 );
+  R( b, c, d, e, a, F3, K3,  9, 12 );
+  R( a, b, c, d, e, F3, K3, 11, 14 );
+  R( e, a, b, c, d, F3, K3, 10, 15 );
+  R( d, e, a, b, c, F3, K3,  0, 14 );
+  R( c, d, e, a, b, F3, K3,  8, 15 );
+  R( b, c, d, e, a, F3, K3, 12,  9 );
+  R( a, b, c, d, e, F3, K3,  4,  8 );
+  R( e, a, b, c, d, F3, K3, 13,  9 );
+  R( d, e, a, b, c, F3, K3,  3, 14 );
+  R( c, d, e, a, b, F3, K3,  7,  5 );
+  R( b, c, d, e, a, F3, K3, 15,  6 );
+  R( a, b, c, d, e, F3, K3, 14,  8 );
+  R( e, a, b, c, d, F3, K3,  5,  6 );
+  R( d, e, a, b, c, F3, K3,  6,  5 );
+  R( c, d, e, a, b, F3, K3,  2, 12 );
+  R( b, c, d, e, a, F4, K4,  4,  9 );
+  R( a, b, c, d, e, F4, K4,  0, 15 );
+  R( e, a, b, c, d, F4, K4,  5,  5 );
+  R( d, e, a, b, c, F4, K4,  9, 11 );
+  R( c, d, e, a, b, F4, K4,  7,  6 );
+  R( b, c, d, e, a, F4, K4, 12,  8 );
+  R( a, b, c, d, e, F4, K4,  2, 13 );
+  R( e, a, b, c, d, F4, K4, 10, 12 );
+  R( d, e, a, b, c, F4, K4, 14,  5 );
+  R( c, d, e, a, b, F4, K4,  1, 12 );
+  R( b, c, d, e, a, F4, K4,  3, 13 );
+  R( a, b, c, d, e, F4, K4,  8, 14 );
+  R( e, a, b, c, d, F4, K4, 11, 11 );
+  R( d, e, a, b, c, F4, K4,  6,  8 );
+  R( c, d, e, a, b, F4, K4, 15,  5 );
+  R( b, c, d, e, a, F4, K4, 13,  6 );
+
+  aa = a; bb = b; cc = c; dd = d; ee = e;
+
+  /* right lane */
+  a = hd->h0;
+  b = hd->h1;
+  c = hd->h2;
+  d = hd->h3;
+  e = hd->h4;
+  R( a, b, c, d, e, F4, KK0,   5,  8);
+  R( e, a, b, c, d, F4, KK0, 14,  9);
+  R( d, e, a, b, c, F4, KK0,   7,  9);
+  R( c, d, e, a, b, F4, KK0,   0, 11);
+  R( b, c, d, e, a, F4, KK0,   9, 13);
+  R( a, b, c, d, e, F4, KK0,   2, 15);
+  R( e, a, b, c, d, F4, KK0, 11, 15);
+  R( d, e, a, b, c, F4, KK0,   4,  5);
+  R( c, d, e, a, b, F4, KK0, 13,  7);
+  R( b, c, d, e, a, F4, KK0,   6,  7);
+  R( a, b, c, d, e, F4, KK0, 15,  8);
+  R( e, a, b, c, d, F4, KK0,   8, 11);
+  R( d, e, a, b, c, F4, KK0,   1, 14);
+  R( c, d, e, a, b, F4, KK0, 10, 14);
+  R( b, c, d, e, a, F4, KK0,   3, 12);
+  R( a, b, c, d, e, F4, KK0, 12,  6);
+  R( e, a, b, c, d, F3, KK1,   6,  9);
+  R( d, e, a, b, c, F3, KK1, 11, 13);
+  R( c, d, e, a, b, F3, KK1,   3, 15);
+  R( b, c, d, e, a, F3, KK1,   7,  7);
+  R( a, b, c, d, e, F3, KK1,   0, 12);
+  R( e, a, b, c, d, F3, KK1, 13,  8);
+  R( d, e, a, b, c, F3, KK1,   5,  9);
+  R( c, d, e, a, b, F3, KK1, 10, 11);
+  R( b, c, d, e, a, F3, KK1, 14,  7);
+  R( a, b, c, d, e, F3, KK1, 15,  7);
+  R( e, a, b, c, d, F3, KK1,   8, 12);
+  R( d, e, a, b, c, F3, KK1, 12,  7);
+  R( c, d, e, a, b, F3, KK1,   4,  6);
+  R( b, c, d, e, a, F3, KK1,   9, 15);
+  R( a, b, c, d, e, F3, KK1,   1, 13);
+  R( e, a, b, c, d, F3, KK1,   2, 11);
+  R( d, e, a, b, c, F2, KK2, 15,  9);
+  R( c, d, e, a, b, F2, KK2,   5,  7);
+  R( b, c, d, e, a, F2, KK2,   1, 15);
+  R( a, b, c, d, e, F2, KK2,   3, 11);
+  R( e, a, b, c, d, F2, KK2,   7,  8);
+  R( d, e, a, b, c, F2, KK2, 14,  6);
+  R( c, d, e, a, b, F2, KK2,   6,  6);
+  R( b, c, d, e, a, F2, KK2,   9, 14);
+  R( a, b, c, d, e, F2, KK2, 11, 12);
+  R( e, a, b, c, d, F2, KK2,   8, 13);
+  R( d, e, a, b, c, F2, KK2, 12,  5);
+  R( c, d, e, a, b, F2, KK2,   2, 14);
+  R( b, c, d, e, a, F2, KK2, 10, 13);
+  R( a, b, c, d, e, F2, KK2,   0, 13);
+  R( e, a, b, c, d, F2, KK2,   4,  7);
+  R( d, e, a, b, c, F2, KK2, 13,  5);
+  R( c, d, e, a, b, F1, KK3,   8, 15);
+  R( b, c, d, e, a, F1, KK3,   6,  5);
+  R( a, b, c, d, e, F1, KK3,   4,  8);
+  R( e, a, b, c, d, F1, KK3,   1, 11);
+  R( d, e, a, b, c, F1, KK3,   3, 14);
+  R( c, d, e, a, b, F1, KK3, 11, 14);
+  R( b, c, d, e, a, F1, KK3, 15,  6);
+  R( a, b, c, d, e, F1, KK3,   0, 14);
+  R( e, a, b, c, d, F1, KK3,   5,  6);
+  R( d, e, a, b, c, F1, KK3, 12,  9);
+  R( c, d, e, a, b, F1, KK3,   2, 12);
+  R( b, c, d, e, a, F1, KK3, 13,  9);
+  R( a, b, c, d, e, F1, KK3,   9, 12);
+  R( e, a, b, c, d, F1, KK3,   7,  5);
+  R( d, e, a, b, c, F1, KK3, 10, 15);
+  R( c, d, e, a, b, F1, KK3, 14,  8);
+  R( b, c, d, e, a, F0, KK4, 12,  8);
+  R( a, b, c, d, e, F0, KK4, 15,  5);
+  R( e, a, b, c, d, F0, KK4, 10, 12);
+  R( d, e, a, b, c, F0, KK4,   4,  9);
+  R( c, d, e, a, b, F0, KK4,   1, 12);
+  R( b, c, d, e, a, F0, KK4,   5,  5);
+  R( a, b, c, d, e, F0, KK4,   8, 14);
+  R( e, a, b, c, d, F0, KK4,   7,  6);
+  R( d, e, a, b, c, F0, KK4,   6,  8);
+  R( c, d, e, a, b, F0, KK4,   2, 13);
+  R( b, c, d, e, a, F0, KK4, 13,  6);
+  R( a, b, c, d, e, F0, KK4, 14,  5);
+  R( e, a, b, c, d, F0, KK4,   0, 15);
+  R( d, e, a, b, c, F0, KK4,   3, 13);
+  R( c, d, e, a, b, F0, KK4,   9, 11);
+  R( b, c, d, e, a, F0, KK4, 11, 11);
+
+
+  t       = hd->h1 + d + cc;
+  hd->h1 = hd->h2 + e + dd;
+  hd->h2 = hd->h3 + a + ee;
+  hd->h3 = hd->h4 + b + aa;
+  hd->h4 = hd->h0 + c + bb;
+  hd->h0 = t;
+}
+
+
+/* Update the message digest with the contents
+ * of INBUF with length INLEN.
+ */
+static void
+rmd160_write ( void *context, const void *inbuf_arg, size_t inlen)
+{
+  const unsigned char *inbuf = inbuf_arg;
+  RMD160_CONTEXT *hd = context;
+
+  if( hd->count == 64 )  /* flush the buffer */
+    {
+      transform( hd, hd->buf );
+      _gcry_burn_stack (108+5*sizeof(void*));
+      hd->count = 0;
+      hd->nblocks++;
+    }
+  if( !inbuf )
+    return;
+  if( hd->count ) 
+    {
+      for( ; inlen && hd->count < 64; inlen-- )
+        hd->buf[hd->count++] = *inbuf++;
+      rmd160_write( hd, NULL, 0 );
+      if( !inlen )
+        return;
+    }
+
+  while( inlen >= 64 )
+    {
+      transform( hd, inbuf );
+      hd->count = 0;
+      hd->nblocks++;
+      inlen -= 64;
+      inbuf += 64;
+    }
+  _gcry_burn_stack (108+5*sizeof(void*));
+  for( ; inlen && hd->count < 64; inlen-- )
+    hd->buf[hd->count++] = *inbuf++;
+}
+
+/****************
+ * Apply the rmd160 transform function on the buffer which must have
+ * a length 64 bytes. Do not use this function together with the
+ * other functions, use rmd160_init to initialize internal variables.
+ * Returns: 16 bytes in buffer with the mixed contentes of buffer.
+ */
+void
+_gcry_rmd160_mixblock ( RMD160_CONTEXT *hd, void *blockof64byte )
+{
+  char *p = blockof64byte;
+
+  transform ( hd, blockof64byte );
+#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
+  X(0);
+  X(1);
+  X(2);
+  X(3);
+  X(4);
+#undef X
+}
+
+
+/* The routine terminates the computation
+ */
+
+static void
+rmd160_final( void *context )
+{
+  RMD160_CONTEXT *hd = context;
+  u32 t, msb, lsb;
+  byte *p;
+  
+  rmd160_write(hd, NULL, 0); /* flush */;
+
+  t = hd->nblocks;
+  /* multiply by 64 to make a byte count */
+  lsb = t << 6;
+  msb = t >> 26;
+  /* add the count */
+  t = lsb;
+  if( (lsb += hd->count) < t )
+    msb++;
+  /* multiply by 8 to make a bit count */
+  t = lsb;
+  lsb <<= 3;
+  msb <<= 3;
+  msb |= t >> 29;
+
+  if( hd->count < 56 )  /* enough room */
+    {
+      hd->buf[hd->count++] = 0x80; /* pad */
+      while( hd->count < 56 )
+        hd->buf[hd->count++] = 0;  /* pad */
+    }
+  else  /* need one extra block */
+    {
+      hd->buf[hd->count++] = 0x80; /* pad character */
+      while( hd->count < 64 )
+        hd->buf[hd->count++] = 0;
+      rmd160_write(hd, NULL, 0);  /* flush */;
+      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+    }
+  /* append the 64 bit count */
+  hd->buf[56] = lsb       ;
+  hd->buf[57] = lsb >>  8;
+  hd->buf[58] = lsb >> 16;
+  hd->buf[59] = lsb >> 24;
+  hd->buf[60] = msb       ;
+  hd->buf[61] = msb >>  8;
+  hd->buf[62] = msb >> 16;
+  hd->buf[63] = msb >> 24;
+  transform( hd, hd->buf );
+  _gcry_burn_stack (108+5*sizeof(void*));
+
+  p = hd->buf;
+#ifdef WORDS_BIGENDIAN
+#define X(a) do { *p++ = hd->h##a         ; *p++ = hd->h##a >> 8;      \
+                 *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
+#else /* little endian */
+#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
+#endif
+  X(0);
+  X(1);
+  X(2);
+  X(3);
+  X(4);
+#undef X
+}
+
+static byte *
+rmd160_read( void *context )
+{
+  RMD160_CONTEXT *hd = context;
+
+  return hd->buf;
+}
+
+
+
+/****************
+ * Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 20 bytes.
+ */
+void
+_gcry_rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length )
+{
+  RMD160_CONTEXT hd;
+
+  _gcry_rmd160_init ( &hd );
+  rmd160_write ( &hd, buffer, length );
+  rmd160_final ( &hd );
+  memcpy ( outbuf, hd.buf, 20 );
+}
+
+static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */
+  { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
+    0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
+
+static gcry_md_oid_spec_t oid_spec_rmd160[] =
+  {
+    /* rsaSignatureWithripemd160 */
+    { "1.3.36.3.3.1.2" },
+    /* TeleTrust hash algorithm.  */
+    { "1.3.36.3.2.1" },
+    { NULL }
+  };
+
+gcry_md_spec_t _gcry_digest_spec_rmd160 =
+  {
+    "RIPEMD160", asn, DIM (asn), oid_spec_rmd160, 20,
+    _gcry_rmd160_init, rmd160_write, rmd160_final, rmd160_read,
+    sizeof (RMD160_CONTEXT)
+  };
diff --git a/grub-core/lib/libgcrypt/cipher/rsa.c b/grub-core/lib/libgcrypt/cipher/rsa.c
new file mode 100644 (file)
index 0000000..cf278c2
--- /dev/null
@@ -0,0 +1,1379 @@
+/* rsa.c - RSA implementation
+ * Copyright (C) 1997, 1998, 1999 by Werner Koch (dd9jn)
+ * Copyright (C) 2000, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This code uses an algorithm protected by U.S. Patent #4,405,829
+   which expired on September 20, 2000.  The patent holder placed that
+   patent into the public domain on Sep 6th, 2000.
+*/
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+
+
+typedef struct
+{
+  gcry_mpi_t n;            /* modulus */
+  gcry_mpi_t e;            /* exponent */
+} RSA_public_key;
+
+
+typedef struct
+{
+  gcry_mpi_t n;            /* public modulus */
+  gcry_mpi_t e;            /* public exponent */
+  gcry_mpi_t d;            /* exponent */
+  gcry_mpi_t p;            /* prime  p. */
+  gcry_mpi_t q;            /* prime  q. */
+  gcry_mpi_t u;            /* inverse of p mod q. */
+} RSA_secret_key;
+
+
+/* A sample 1024 bit RSA key used for the selftests.  */
+static const char sample_secret_key[] =
+"(private-key"
+" (rsa"
+"  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+"      2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+"      ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+"      891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)"
+"  (e #010001#)"
+"  (d #046129f2489d71579be0a75fe029bd6cdb574ebf57ea8a5b0fda942cab943b11"
+"      7d7bb95e5d28875e0f9fc5fcc06a72f6d502464dabded78ef6b716177b83d5bd"
+"      c543dc5d3fed932e59f5897e92e6f58a0f33424106a3b6fa2cbf877510e4ac21"
+"      c3ee47851e97d12996222ac3566d4ccb0b83d164074abf7de655fc2446da1781#)"
+"  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
+"      fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)"
+"  (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
+"      35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)"
+"  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
+"      ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))";
+/* A sample 1024 bit RSA key used for the selftests (public only).  */
+static const char sample_public_key[] = 
+"(public-key"
+" (rsa"
+"  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+"      2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+"      ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+"      891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)"
+"  (e #010001#)))";
+
+
+
+\f
+static int test_keys (RSA_secret_key *sk, unsigned nbits);
+static int  check_secret_key (RSA_secret_key *sk);
+static void public (gcry_mpi_t output, gcry_mpi_t input, RSA_public_key *skey);
+static void secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey);
+
+
+/* Check that a freshly generated key actually works.  Returns 0 on success. */
+static int
+test_keys (RSA_secret_key *sk, unsigned int nbits)
+{
+  int result = -1; /* Default to failure.  */
+  RSA_public_key pk;
+  gcry_mpi_t plaintext = gcry_mpi_new (nbits);
+  gcry_mpi_t ciphertext = gcry_mpi_new (nbits);
+  gcry_mpi_t decr_plaintext = gcry_mpi_new (nbits);
+  gcry_mpi_t signature = gcry_mpi_new (nbits);
+
+  /* Put the relevant parameters into a public key structure.  */
+  pk.n = sk->n;
+  pk.e = sk->e;
+
+  /* Create a random plaintext.  */
+  gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
+
+  /* Encrypt using the public key.  */
+  public (ciphertext, plaintext, &pk);
+
+  /* Check that the cipher text does not match the plaintext.  */
+  if (!gcry_mpi_cmp (ciphertext, plaintext))
+    goto leave; /* Ciphertext is identical to the plaintext.  */
+
+  /* Decrypt using the secret key.  */
+  secret (decr_plaintext, ciphertext, sk);
+
+  /* Check that the decrypted plaintext matches the original plaintext.  */
+  if (gcry_mpi_cmp (decr_plaintext, plaintext))
+    goto leave; /* Plaintext does not match.  */
+
+  /* Create another random plaintext as data for signature checking.  */
+  gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
+
+  /* Use the RSA secret function to create a signature of the plaintext.  */
+  secret (signature, plaintext, sk);
+  
+  /* Use the RSA public function to verify this signature.  */
+  public (decr_plaintext, signature, &pk);
+  if (gcry_mpi_cmp (decr_plaintext, plaintext))
+    goto leave; /* Signature does not match.  */
+
+  /* Modify the signature and check that the signing fails.  */
+  gcry_mpi_add_ui (signature, signature, 1);
+  public (decr_plaintext, signature, &pk);
+  if (!gcry_mpi_cmp (decr_plaintext, plaintext))
+    goto leave; /* Signature matches but should not.  */
+
+  result = 0; /* All tests succeeded.  */
+
+ leave:
+  gcry_mpi_release (signature);
+  gcry_mpi_release (decr_plaintext);
+  gcry_mpi_release (ciphertext);
+  gcry_mpi_release (plaintext);
+  return result;
+}
+
+
+/* Callback used by the prime generation to test whether the exponent
+   is suitable. Returns 0 if the test has been passed. */
+static int
+check_exponent (void *arg, gcry_mpi_t a)
+{
+  gcry_mpi_t e = arg;
+  gcry_mpi_t tmp;
+  int result;
+  
+  mpi_sub_ui (a, a, 1);
+  tmp = _gcry_mpi_alloc_like (a);
+  result = !gcry_mpi_gcd(tmp, e, a); /* GCD is not 1. */
+  gcry_mpi_release (tmp);
+  mpi_add_ui (a, a, 1);
+  return result;
+}
+
+/****************
+ * Generate a key pair with a key of size NBITS.  
+ * USE_E = 0 let Libcgrypt decide what exponent to use.
+ *       = 1 request the use of a "secure" exponent; this is required by some 
+ *           specification to be 65537.
+ *       > 2 Use this public exponent.  If the given exponent
+ *           is not odd one is internally added to it. 
+ * TRANSIENT_KEY:  If true, generate the primes using the standard RNG.
+ * Returns: 2 structures filled with all needed values
+ */
+static gpg_err_code_t
+generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
+              int transient_key)
+{
+  gcry_mpi_t p, q; /* the two primes */
+  gcry_mpi_t d;    /* the private key */
+  gcry_mpi_t u;
+  gcry_mpi_t t1, t2;
+  gcry_mpi_t n;    /* the public key */
+  gcry_mpi_t e;    /* the exponent */
+  gcry_mpi_t phi;  /* helper: (p-1)(q-1) */
+  gcry_mpi_t g;
+  gcry_mpi_t f;
+  gcry_random_level_t random_level;
+
+  if (fips_mode ())
+    {
+      if (nbits < 1024)
+        return GPG_ERR_INV_VALUE;
+      if (transient_key)
+        return GPG_ERR_INV_VALUE;
+    }
+
+  /* The random quality depends on the transient_key flag.  */
+  random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
+
+  /* Make sure that nbits is even so that we generate p, q of equal size. */
+  if ( (nbits&1) )
+    nbits++; 
+
+  if (use_e == 1)   /* Alias for a secure value */
+    use_e = 65537;  /* as demanded by Sphinx. */
+
+  /* Public exponent:
+     In general we use 41 as this is quite fast and more secure than the
+     commonly used 17.  Benchmarking the RSA verify function
+     with a 1024 bit key yields (2001-11-08): 
+     e=17    0.54 ms
+     e=41    0.75 ms
+     e=257   0.95 ms
+     e=65537 1.80 ms
+  */
+  e = mpi_alloc( (32+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
+  if (!use_e)
+    mpi_set_ui (e, 41);     /* This is a reasonable secure and fast value */
+  else 
+    {
+      use_e |= 1; /* make sure this is odd */
+      mpi_set_ui (e, use_e); 
+    }
+    
+  n = gcry_mpi_new (nbits);
+
+  p = q = NULL;
+  do
+    {
+      /* select two (very secret) primes */
+      if (p)
+        gcry_mpi_release (p);
+      if (q)
+        gcry_mpi_release (q);
+      if (use_e)
+        { /* Do an extra test to ensure that the given exponent is
+             suitable. */
+          p = _gcry_generate_secret_prime (nbits/2, random_level,
+                                           check_exponent, e);
+          q = _gcry_generate_secret_prime (nbits/2, random_level,
+                                           check_exponent, e);
+        }
+      else
+        { /* We check the exponent later. */
+          p = _gcry_generate_secret_prime (nbits/2, random_level, NULL, NULL);
+          q = _gcry_generate_secret_prime (nbits/2, random_level, NULL, NULL);
+        }
+      if (mpi_cmp (p, q) > 0 ) /* p shall be smaller than q (for calc of u)*/
+        mpi_swap(p,q);
+      /* calculate the modulus */
+      mpi_mul( n, p, q );
+    }
+  while ( mpi_get_nbits(n) != nbits );
+
+  /* calculate Euler totient: phi = (p-1)(q-1) */
+  t1 = mpi_alloc_secure( mpi_get_nlimbs(p) );
+  t2 = mpi_alloc_secure( mpi_get_nlimbs(p) );
+  phi = gcry_mpi_snew ( nbits );
+  g    = gcry_mpi_snew ( nbits );
+  f    = gcry_mpi_snew ( nbits );
+  mpi_sub_ui( t1, p, 1 );
+  mpi_sub_ui( t2, q, 1 );
+  mpi_mul( phi, t1, t2 );
+  gcry_mpi_gcd(g, t1, t2);
+  mpi_fdiv_q(f, phi, g);
+
+  while (!gcry_mpi_gcd(t1, e, phi)) /* (while gcd is not 1) */
+    {
+      if (use_e)
+        BUG (); /* The prime generator already made sure that we
+                   never can get to here. */
+      mpi_add_ui (e, e, 2);
+    }
+
+  /* calculate the secret key d = e^1 mod phi */
+  d = gcry_mpi_snew ( nbits );
+  mpi_invm(d, e, f );
+  /* calculate the inverse of p and q (used for chinese remainder theorem)*/
+  u = gcry_mpi_snew ( nbits );
+  mpi_invm(u, p, q );
+
+  if( DBG_CIPHER )
+    {
+      log_mpidump("  p= ", p );
+      log_mpidump("  q= ", q );
+      log_mpidump("phi= ", phi );
+      log_mpidump("  g= ", g );
+      log_mpidump("  f= ", f );
+      log_mpidump("  n= ", n );
+      log_mpidump("  e= ", e );
+      log_mpidump("  d= ", d );
+      log_mpidump("  u= ", u );
+    }
+
+  gcry_mpi_release (t1);
+  gcry_mpi_release (t2);
+  gcry_mpi_release (phi);
+  gcry_mpi_release (f);
+  gcry_mpi_release (g);
+
+  sk->n = n;
+  sk->e = e;
+  sk->p = p;
+  sk->q = q;
+  sk->d = d;
+  sk->u = u;
+
+  /* Now we can test our keys. */
+  if (test_keys (sk, nbits - 64))
+    {
+      gcry_mpi_release (sk->n); sk->n = NULL;
+      gcry_mpi_release (sk->e); sk->e = NULL;
+      gcry_mpi_release (sk->p); sk->p = NULL;
+      gcry_mpi_release (sk->q); sk->q = NULL;
+      gcry_mpi_release (sk->d); sk->d = NULL;
+      gcry_mpi_release (sk->u); sk->u = NULL;
+      fips_signal_error ("self-test after key generation failed");
+      return GPG_ERR_SELFTEST_FAILED;
+    }
+
+  return 0;
+}
+
+
+/* Helper for generate_x931.  */
+static gcry_mpi_t 
+gen_x931_parm_xp (unsigned int nbits)
+{
+  gcry_mpi_t xp;
+
+  xp = gcry_mpi_snew (nbits);
+  gcry_mpi_randomize (xp, nbits, GCRY_VERY_STRONG_RANDOM);
+      
+  /* The requirement for Xp is:
+
+       sqrt{2}*2^{nbits-1} <= xp <= 2^{nbits} - 1
+
+     We set the two high order bits to 1 to satisfy the lower bound.
+     By using mpi_set_highbit we make sure that the upper bound is
+     satisfied as well.  */
+  mpi_set_highbit (xp, nbits-1);
+  mpi_set_bit (xp, nbits-2);
+  gcry_assert ( mpi_get_nbits (xp) == nbits );
+  
+  return xp;
+}     
+
+
+/* Helper for generate_x931.  */
+static gcry_mpi_t 
+gen_x931_parm_xi (void)
+{
+  gcry_mpi_t xi;
+
+  xi = gcry_mpi_snew (101);
+  gcry_mpi_randomize (xi, 101, GCRY_VERY_STRONG_RANDOM);
+  mpi_set_highbit (xi, 100);
+  gcry_assert ( mpi_get_nbits (xi) == 101 );
+  
+  return xi;
+}     
+
+
+
+/* Variant of the standard key generation code using the algorithm
+   from X9.31.  Using this algorithm has the advantage that the
+   generation can be made deterministic which is required for CAVS
+   testing.  */
+static gpg_err_code_t
+generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value,
+               gcry_sexp_t deriveparms, int *swapped)
+{
+  gcry_mpi_t p, q; /* The two primes.  */
+  gcry_mpi_t e;    /* The public exponent.  */
+  gcry_mpi_t n;    /* The public key.  */
+  gcry_mpi_t d;    /* The private key */
+  gcry_mpi_t u;    /* The inverse of p and q.  */
+  gcry_mpi_t pm1;  /* p - 1  */
+  gcry_mpi_t qm1;  /* q - 1  */
+  gcry_mpi_t phi;  /* Euler totient.  */
+  gcry_mpi_t f, g; /* Helper.  */
+
+  *swapped = 0;
+
+  if (e_value == 1)   /* Alias for a secure value. */
+    e_value = 65537; 
+
+  /* Point 1 of section 4.1:  k = 1024 + 256s with S >= 0  */
+  if (nbits < 1024 || (nbits % 256))
+    return GPG_ERR_INV_VALUE;
+  
+  /* Point 2:  2 <= bitlength(e) < 2^{k-2}
+     Note that we do not need to check the upper bound because we use
+     an unsigned long for E and thus there is no way for E to reach
+     that limit.  */
+  if (e_value < 3)
+    return GPG_ERR_INV_VALUE;
+     
+  /* Our implementaion requires E to be odd.  */
+  if (!(e_value & 1))
+    return GPG_ERR_INV_VALUE;
+
+  /* Point 3:  e > 0 or e 0 if it is to be randomly generated.
+     We support only a fixed E and thus there is no need for an extra test.  */
+
+
+  /* Compute or extract the derive parameters.  */
+  {
+    gcry_mpi_t xp1 = NULL;
+    gcry_mpi_t xp2 = NULL;
+    gcry_mpi_t xp  = NULL;
+    gcry_mpi_t xq1 = NULL;
+    gcry_mpi_t xq2 = NULL;
+    gcry_mpi_t xq  = NULL;
+    gcry_mpi_t tmpval;
+
+    if (!deriveparms)
+      {
+        /* Not given: Generate them.  */
+        xp = gen_x931_parm_xp (nbits/2);
+        /* Make sure that |xp - xq| > 2^{nbits - 100} holds.  */
+        tmpval = gcry_mpi_snew (nbits/2);
+        do
+          {
+            gcry_mpi_release (xq);
+            xq = gen_x931_parm_xp (nbits/2);
+            mpi_sub (tmpval, xp, xq);
+          }
+        while (mpi_get_nbits (tmpval) <= (nbits/2 - 100));
+        gcry_mpi_release (tmpval);
+
+        xp1 = gen_x931_parm_xi ();
+        xp2 = gen_x931_parm_xi ();
+        xq1 = gen_x931_parm_xi ();
+        xq2 = gen_x931_parm_xi ();
+
+      }
+    else
+      {
+        /* Parameters to derive the key are given.  */
+        struct { const char *name; gcry_mpi_t *value; } tbl[] = {
+          { "Xp1", &xp1 },
+          { "Xp2", &xp2 },
+          { "Xp",  &xp  },
+          { "Xq1", &xq1 },
+          { "Xq2", &xq2 },
+          { "Xq",  &xq  },
+          { NULL,  NULL }
+        };
+        int idx;
+        gcry_sexp_t oneparm;
+        
+        for (idx=0; tbl[idx].name; idx++)
+          {
+            oneparm = gcry_sexp_find_token (deriveparms, tbl[idx].name, 0);
+            if (oneparm)
+              {
+                *tbl[idx].value = gcry_sexp_nth_mpi (oneparm, 1,
+                                                     GCRYMPI_FMT_USG);
+                gcry_sexp_release (oneparm);
+              }
+          }
+        for (idx=0; tbl[idx].name; idx++)
+          if (!*tbl[idx].value)
+            break;
+        if (tbl[idx].name)
+          {
+            /* At least one parameter is missing.  */
+            for (idx=0; tbl[idx].name; idx++)
+              gcry_mpi_release (*tbl[idx].value);
+            return GPG_ERR_MISSING_VALUE;
+          }
+      }
+    
+    e = mpi_alloc_set_ui (e_value); 
+
+    /* Find two prime numbers.  */
+    p = _gcry_derive_x931_prime (xp, xp1, xp2, e, NULL, NULL);
+    q = _gcry_derive_x931_prime (xq, xq1, xq2, e, NULL, NULL);
+    gcry_mpi_release (xp);  xp  = NULL;
+    gcry_mpi_release (xp1); xp1 = NULL;
+    gcry_mpi_release (xp2); xp2 = NULL;
+    gcry_mpi_release (xq);  xq  = NULL; 
+    gcry_mpi_release (xq1); xq1 = NULL;
+    gcry_mpi_release (xq2); xq2 = NULL;
+    if (!p || !q)
+      {
+        gcry_mpi_release (p);
+        gcry_mpi_release (q);
+        gcry_mpi_release (e);
+        return GPG_ERR_NO_PRIME;
+      }
+  }
+
+
+  /* Compute the public modulus.  We make sure that p is smaller than
+     q to allow the use of the CRT.  */
+  if (mpi_cmp (p, q) > 0 )
+    {
+      mpi_swap (p, q);
+      *swapped = 1;
+    }
+  n = gcry_mpi_new (nbits);
+  mpi_mul (n, p, q);
+
+  /* Compute the Euler totient:  phi = (p-1)(q-1)  */
+  pm1 = gcry_mpi_snew (nbits/2);
+  qm1 = gcry_mpi_snew (nbits/2);
+  phi = gcry_mpi_snew (nbits);
+  mpi_sub_ui (pm1, p, 1);
+  mpi_sub_ui (qm1, q, 1);
+  mpi_mul (phi, pm1, qm1);
+
+  g = gcry_mpi_snew (nbits);
+  gcry_assert (gcry_mpi_gcd (g, e, phi));
+
+  /* Compute: f = lcm(p-1,q-1) = phi / gcd(p-1,q-1) */
+  gcry_mpi_gcd (g, pm1, qm1);
+  f = pm1; pm1 = NULL;
+  gcry_mpi_release (qm1); qm1 = NULL;
+  mpi_fdiv_q (f, phi, g);
+  gcry_mpi_release (phi); phi = NULL;
+  d = g; g = NULL;
+  /* Compute the secret key:  d = e^{-1} mod lcm(p-1,q-1) */
+  mpi_invm (d, e, f);
+
+  /* Compute the inverse of p and q.  */
+  u = f; f = NULL;
+  mpi_invm (u, p, q );
+
+  if( DBG_CIPHER )
+    {
+      if (*swapped)
+        log_debug ("p and q are swapped\n");
+      log_mpidump("  p", p );
+      log_mpidump("  q", q );
+      log_mpidump("  n", n );
+      log_mpidump("  e", e );
+      log_mpidump("  d", d );
+      log_mpidump("  u", u );
+    }
+
+
+  sk->n = n;
+  sk->e = e;
+  sk->p = p;
+  sk->q = q;
+  sk->d = d;
+  sk->u = u;
+
+  /* Now we can test our keys. */
+  if (test_keys (sk, nbits - 64))
+    {
+      gcry_mpi_release (sk->n); sk->n = NULL;
+      gcry_mpi_release (sk->e); sk->e = NULL;
+      gcry_mpi_release (sk->p); sk->p = NULL;
+      gcry_mpi_release (sk->q); sk->q = NULL;
+      gcry_mpi_release (sk->d); sk->d = NULL;
+      gcry_mpi_release (sk->u); sk->u = NULL;
+      fips_signal_error ("self-test after key generation failed");
+      return GPG_ERR_SELFTEST_FAILED;
+    }
+
+  return 0;
+}
+
+
+/****************
+ * Test wether the secret key is valid.
+ * Returns: true if this is a valid key.
+ */
+static int
+check_secret_key( RSA_secret_key *sk )
+{
+  int rc;
+  gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(sk->p)*2 );
+  
+  mpi_mul(temp, sk->p, sk->q );
+  rc = mpi_cmp( temp, sk->n );
+  mpi_free(temp);
+  return !rc;
+}
+
+
+
+/****************
+ * Public key operation. Encrypt INPUT with PKEY and put result into OUTPUT.
+ *
+ *     c = m^e mod n
+ *
+ * Where c is OUTPUT, m is INPUT and e,n are elements of PKEY.
+ */
+static void
+public(gcry_mpi_t output, gcry_mpi_t input, RSA_public_key *pkey )
+{
+  if( output == input )  /* powm doesn't like output and input the same */
+    {
+      gcry_mpi_t x = mpi_alloc( mpi_get_nlimbs(input)*2 );
+      mpi_powm( x, input, pkey->e, pkey->n );
+      mpi_set(output, x);
+      mpi_free(x);
+    }
+  else
+    mpi_powm( output, input, pkey->e, pkey->n );
+}
+
+#if 0
+static void
+stronger_key_check ( RSA_secret_key *skey )
+{
+  gcry_mpi_t t = mpi_alloc_secure ( 0 );
+  gcry_mpi_t t1 = mpi_alloc_secure ( 0 );
+  gcry_mpi_t t2 = mpi_alloc_secure ( 0 );
+  gcry_mpi_t phi = mpi_alloc_secure ( 0 );
+
+  /* check that n == p * q */
+  mpi_mul( t, skey->p, skey->q);
+  if (mpi_cmp( t, skey->n) )
+    log_info ( "RSA Oops: n != p * q\n" );
+
+  /* check that p is less than q */
+  if( mpi_cmp( skey->p, skey->q ) > 0 )
+    {
+      log_info ("RSA Oops: p >= q - fixed\n");
+      _gcry_mpi_swap ( skey->p, skey->q);
+    }
+
+    /* check that e divides neither p-1 nor q-1 */
+    mpi_sub_ui(t, skey->p, 1 );
+    mpi_fdiv_r(t, t, skey->e );
+    if ( !mpi_cmp_ui( t, 0) )
+        log_info ( "RSA Oops: e divides p-1\n" );
+    mpi_sub_ui(t, skey->q, 1 );
+    mpi_fdiv_r(t, t, skey->e );
+    if ( !mpi_cmp_ui( t, 0) )
+        log_info ( "RSA Oops: e divides q-1\n" );
+
+    /* check that d is correct */
+    mpi_sub_ui( t1, skey->p, 1 );
+    mpi_sub_ui( t2, skey->q, 1 );
+    mpi_mul( phi, t1, t2 );
+    gcry_mpi_gcd(t, t1, t2);
+    mpi_fdiv_q(t, phi, t);
+    mpi_invm(t, skey->e, t );
+    if ( mpi_cmp(t, skey->d ) )
+      {
+        log_info ( "RSA Oops: d is wrong - fixed\n");
+        mpi_set (skey->d, t);
+        _gcry_log_mpidump ("  fixed d", skey->d);
+      }
+
+    /* check for correctness of u */
+    mpi_invm(t, skey->p, skey->q );
+    if ( mpi_cmp(t, skey->u ) )
+      {
+        log_info ( "RSA Oops: u is wrong - fixed\n");
+        mpi_set (skey->u, t);
+        _gcry_log_mpidump ("  fixed u", skey->u);
+      }
+
+    log_info ( "RSA secret key check finished\n");
+
+    mpi_free (t);
+    mpi_free (t1);
+    mpi_free (t2);
+    mpi_free (phi);
+}
+#endif
+
+
+
+/****************
+ * Secret key operation. Encrypt INPUT with SKEY and put result into OUTPUT.
+ *
+ *     m = c^d mod n
+ *
+ * Or faster:
+ *
+ *      m1 = c ^ (d mod (p-1)) mod p 
+ *      m2 = c ^ (d mod (q-1)) mod q 
+ *      h = u * (m2 - m1) mod q 
+ *      m = m1 + h * p
+ *
+ * Where m is OUTPUT, c is INPUT and d,n,p,q,u are elements of SKEY.
+ */
+static void
+secret(gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
+{
+  if (!skey->p || !skey->q || !skey->u)
+    {
+      mpi_powm (output, input, skey->d, skey->n);
+    }
+  else
+    {
+      gcry_mpi_t m1 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
+      gcry_mpi_t m2 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
+      gcry_mpi_t h  = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
+      
+      /* m1 = c ^ (d mod (p-1)) mod p */
+      mpi_sub_ui( h, skey->p, 1  );
+      mpi_fdiv_r( h, skey->d, h );   
+      mpi_powm( m1, input, h, skey->p );
+      /* m2 = c ^ (d mod (q-1)) mod q */
+      mpi_sub_ui( h, skey->q, 1  );
+      mpi_fdiv_r( h, skey->d, h );
+      mpi_powm( m2, input, h, skey->q );
+      /* h = u * ( m2 - m1 ) mod q */
+      mpi_sub( h, m2, m1 );
+      if ( mpi_is_neg( h ) ) 
+        mpi_add ( h, h, skey->q );
+      mpi_mulm( h, skey->u, h, skey->q ); 
+      /* m = m2 + h * p */
+      mpi_mul ( h, h, skey->p );
+      mpi_add ( output, m1, h );
+    
+      mpi_free ( h );
+      mpi_free ( m1 );
+      mpi_free ( m2 );
+    }
+}
+
+
+
+/* Perform RSA blinding.  */
+static gcry_mpi_t
+rsa_blind (gcry_mpi_t x, gcry_mpi_t r, gcry_mpi_t e, gcry_mpi_t n)
+{
+  /* A helper.  */
+  gcry_mpi_t a;
+
+  /* Result.  */
+  gcry_mpi_t y;
+
+  a = gcry_mpi_snew (gcry_mpi_get_nbits (n));
+  y = gcry_mpi_snew (gcry_mpi_get_nbits (n));
+  
+  /* Now we calculate: y = (x * r^e) mod n, where r is the random
+     number, e is the public exponent, x is the non-blinded data and n
+     is the RSA modulus.  */
+  gcry_mpi_powm (a, r, e, n);
+  gcry_mpi_mulm (y, a, x, n);
+
+  gcry_mpi_release (a);
+
+  return y;
+}
+
+/* Undo RSA blinding.  */
+static gcry_mpi_t
+rsa_unblind (gcry_mpi_t x, gcry_mpi_t ri, gcry_mpi_t n)
+{
+  gcry_mpi_t y;
+
+  y = gcry_mpi_snew (gcry_mpi_get_nbits (n));
+
+  /* Here we calculate: y = (x * r^-1) mod n, where x is the blinded
+     decrypted data, ri is the modular multiplicative inverse of r and
+     n is the RSA modulus.  */
+
+  gcry_mpi_mulm (y, ri, x, n);
+
+  return y;
+}
+
+/*********************************************
+ **************  interface  ******************
+ *********************************************/
+
+static gcry_err_code_t
+rsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
+                  const gcry_sexp_t genparms,
+                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
+                  gcry_sexp_t *r_extrainfo)
+{
+  RSA_secret_key sk;
+  gpg_err_code_t ec;
+  gcry_sexp_t deriveparms;
+  int transient_key = 0;
+  int use_x931 = 0;
+  gcry_sexp_t l1;
+
+  (void)algo;
+  
+  *retfactors = NULL; /* We don't return them.  */
+
+  deriveparms = (genparms?
+                 gcry_sexp_find_token (genparms, "derive-parms", 0) : NULL);
+  if (!deriveparms)
+    {
+      /* Parse the optional "use-x931" flag. */
+      l1 = gcry_sexp_find_token (genparms, "use-x931", 0);
+      if (l1)
+        {
+          use_x931 = 1;
+          gcry_sexp_release (l1);
+        }
+    }
+
+  if (deriveparms || use_x931 || fips_mode ())
+    {
+      int swapped;
+      ec = generate_x931 (&sk, nbits, evalue, deriveparms, &swapped);
+      gcry_sexp_release (deriveparms);
+      if (!ec && r_extrainfo && swapped)
+        {
+          ec = gcry_sexp_new (r_extrainfo, 
+                              "(misc-key-info(p-q-swapped))", 0, 1);
+          if (ec)
+            {
+              gcry_mpi_release (sk.n); sk.n = NULL;
+              gcry_mpi_release (sk.e); sk.e = NULL;
+              gcry_mpi_release (sk.p); sk.p = NULL;
+              gcry_mpi_release (sk.q); sk.q = NULL;
+              gcry_mpi_release (sk.d); sk.d = NULL;
+              gcry_mpi_release (sk.u); sk.u = NULL;
+            }
+        }
+    }
+  else
+    {
+      /* Parse the optional "transient-key" flag. */
+      l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
+      if (l1)
+        {
+          transient_key = 1;
+          gcry_sexp_release (l1);
+        }
+      /* Generate.  */
+      ec = generate_std (&sk, nbits, evalue, transient_key);
+    }
+
+  if (!ec)
+    {
+      skey[0] = sk.n;
+      skey[1] = sk.e;
+      skey[2] = sk.d;
+      skey[3] = sk.p;
+      skey[4] = sk.q;
+      skey[5] = sk.u;
+    }
+  
+  return ec;
+}
+
+
+static gcry_err_code_t
+rsa_generate (int algo, unsigned int nbits, unsigned long evalue,
+              gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+{
+  return rsa_generate_ext (algo, nbits, evalue, NULL, skey, retfactors, NULL);
+}
+
+
+static gcry_err_code_t
+rsa_check_secret_key (int algo, gcry_mpi_t *skey)
+{
+  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  RSA_secret_key sk;
+
+  (void)algo;
+
+  sk.n = skey[0];
+  sk.e = skey[1];
+  sk.d = skey[2];
+  sk.p = skey[3];
+  sk.q = skey[4];
+  sk.u = skey[5];
+
+  if (!sk.p || !sk.q || !sk.u)
+    err = GPG_ERR_NO_OBJ;  /* To check the key we need the optional
+                              parameters. */
+  else if (!check_secret_key (&sk))
+    err = GPG_ERR_PUBKEY_ALGO;
+
+  return err;
+}
+
+
+static gcry_err_code_t
+rsa_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
+             gcry_mpi_t *pkey, int flags)
+{
+  RSA_public_key pk;
+
+  (void)algo;
+  (void)flags;
+  
+  pk.n = pkey[0];
+  pk.e = pkey[1];
+  resarr[0] = mpi_alloc (mpi_get_nlimbs (pk.n));
+  public (resarr[0], data, &pk);
+  
+  return GPG_ERR_NO_ERROR;
+}
+
+
+static gcry_err_code_t
+rsa_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
+             gcry_mpi_t *skey, int flags)
+{
+  RSA_secret_key sk;
+  gcry_mpi_t r = MPI_NULL;     /* Random number needed for blinding.  */
+  gcry_mpi_t ri = MPI_NULL;    /* Modular multiplicative inverse of
+                                  r.  */
+  gcry_mpi_t x = MPI_NULL;     /* Data to decrypt.  */
+  gcry_mpi_t y;                        /* Result.  */
+
+  (void)algo;
+
+  /* Extract private key.  */
+  sk.n = skey[0];
+  sk.e = skey[1];
+  sk.d = skey[2];
+  sk.p = skey[3]; /* Optional. */
+  sk.q = skey[4]; /* Optional. */
+  sk.u = skey[5]; /* Optional. */
+
+  y = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
+
+  /* We use blinding by default to mitigate timing attacks which can
+     be practically mounted over the network as shown by Brumley and
+     Boney in 2003.  */ 
+  if (! (flags & PUBKEY_FLAG_NO_BLINDING))
+    {
+      /* Initialize blinding.  */
+      
+      /* First, we need a random number r between 0 and n - 1, which
+        is relatively prime to n (i.e. it is neither p nor q).  The
+        random number needs to be only unpredictable, thus we employ
+        the gcry_create_nonce function by using GCRY_WEAK_RANDOM with
+        gcry_mpi_randomize.  */
+      r = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
+      ri = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
+      
+      gcry_mpi_randomize (r, gcry_mpi_get_nbits (sk.n), GCRY_WEAK_RANDOM);
+      gcry_mpi_mod (r, r, sk.n);
+
+      /* Calculate inverse of r.  It practically impossible that the
+         follwing test fails, thus we do not add code to release
+         allocated resources.  */
+      if (!gcry_mpi_invm (ri, r, sk.n))
+       return GPG_ERR_INTERNAL;
+    }
+
+  if (! (flags & PUBKEY_FLAG_NO_BLINDING))
+    x = rsa_blind (data[0], r, sk.e, sk.n);
+  else
+    x = data[0];
+
+  /* Do the encryption.  */
+  secret (y, x, &sk);
+
+  if (! (flags & PUBKEY_FLAG_NO_BLINDING))
+    {
+      /* Undo blinding.  */
+      gcry_mpi_t a = gcry_mpi_copy (y);
+      
+      gcry_mpi_release (y);
+      y = rsa_unblind (a, ri, sk.n);
+
+      gcry_mpi_release (a);
+    }
+
+  if (! (flags & PUBKEY_FLAG_NO_BLINDING))
+    {
+      /* Deallocate resources needed for blinding.  */
+      gcry_mpi_release (x);
+      gcry_mpi_release (r);
+      gcry_mpi_release (ri);
+    }
+
+  /* Copy out result.  */
+  *result = y;
+  
+  return GPG_ERR_NO_ERROR;
+}
+
+
+static gcry_err_code_t
+rsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
+{
+  RSA_secret_key sk;
+
+  (void)algo;
+  
+  sk.n = skey[0];
+  sk.e = skey[1];
+  sk.d = skey[2];
+  sk.p = skey[3];
+  sk.q = skey[4];
+  sk.u = skey[5];
+  resarr[0] = mpi_alloc( mpi_get_nlimbs (sk.n));
+  secret (resarr[0], data, &sk);
+
+  return GPG_ERR_NO_ERROR;
+}
+
+
+static gcry_err_code_t
+rsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
+                 int (*cmp) (void *opaque, gcry_mpi_t tmp),
+                 void *opaquev)
+{
+  RSA_public_key pk;
+  gcry_mpi_t result;
+  gcry_err_code_t rc;
+
+  (void)algo;
+  (void)cmp;
+  (void)opaquev;
+
+  pk.n = pkey[0];
+  pk.e = pkey[1];
+  result = gcry_mpi_new ( 160 );
+  public( result, data[0], &pk );
+#ifdef IS_DEVELOPMENT_VERSION
+  if (DBG_CIPHER)
+    {
+      log_mpidump ("rsa verify result:", result );
+      log_mpidump ("             hash:", hash );
+    }
+#endif /*IS_DEVELOPMENT_VERSION*/
+  /*rc = (*cmp)( opaquev, result );*/
+  rc = mpi_cmp (result, hash) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR;
+  gcry_mpi_release (result);
+  
+  return rc;
+}
+
+
+static unsigned int
+rsa_get_nbits (int algo, gcry_mpi_t *pkey)
+{
+  (void)algo;
+
+  return mpi_get_nbits (pkey[0]);
+}
+
+
+/* Compute a keygrip.  MD is the hash context which we are going to
+   update.  KEYPARAM is an S-expression with the key parameters, this
+   is usually a public key but may also be a secret key.  An example
+   of such an S-expression is:
+
+      (rsa
+        (n #00B...#)
+        (e #010001#))
+        
+   PKCS-15 says that for RSA only the modulus should be hashed -
+   however, it is not clear wether this is meant to use the raw bytes
+   (assuming this is an unsigned integer) or whether the DER required
+   0 should be prefixed.  We hash the raw bytes.  */
+static gpg_err_code_t
+compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
+{
+  gcry_sexp_t l1;
+  const char *data;
+  size_t datalen;
+
+  l1 = gcry_sexp_find_token (keyparam, "n", 1);
+  if (!l1)
+    return GPG_ERR_NO_OBJ;
+
+  data = gcry_sexp_nth_data (l1, 1, &datalen);
+  if (!data)
+    {
+      gcry_sexp_release (l1);
+      return GPG_ERR_NO_OBJ;
+    }
+
+  gcry_md_write (md, data, datalen);
+  gcry_sexp_release (l1);
+
+  return 0;
+}
+
+
+
+\f
+/* 
+     Self-test section.
+ */
+
+static const char *
+selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
+{
+  static const char sample_data[] = 
+    "(data (flags pkcs1)"
+    " (hash sha1 #11223344556677889900aabbccddeeff10203040#))";
+  static const char sample_data_bad[] = 
+    "(data (flags pkcs1)"
+    " (hash sha1 #11223344556677889900aabbccddeeff80203040#))";
+
+  const char *errtxt = NULL;
+  gcry_error_t err;
+  gcry_sexp_t data = NULL;
+  gcry_sexp_t data_bad = NULL;
+  gcry_sexp_t sig = NULL;
+
+  err = gcry_sexp_sscan (&data, NULL,
+                         sample_data, strlen (sample_data));
+  if (!err)
+    err = gcry_sexp_sscan (&data_bad, NULL, 
+                           sample_data_bad, strlen (sample_data_bad));
+  if (err)
+    {
+      errtxt = "converting data failed";
+      goto leave;
+    }
+
+  err = gcry_pk_sign (&sig, data, skey);
+  if (err)
+    {
+      errtxt = "signing failed";
+      goto leave;
+    }
+  err = gcry_pk_verify (sig, data, pkey);
+  if (err)
+    {
+      errtxt = "verify failed";
+      goto leave;
+    }
+  err = gcry_pk_verify (sig, data_bad, pkey);
+  if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
+    {
+      errtxt = "bad signature not detected";
+      goto leave;
+    }
+
+
+ leave:
+  gcry_sexp_release (sig);
+  gcry_sexp_release (data_bad);
+  gcry_sexp_release (data);
+  return errtxt;
+}
+
+
+
+/* Given an S-expression ENCR_DATA of the form:
+
+   (enc-val
+    (rsa
+     (a a-value)))
+
+   as returned by gcry_pk_decrypt, return the the A-VALUE.  On error,
+   return NULL.  */
+static gcry_mpi_t
+extract_a_from_sexp (gcry_sexp_t encr_data)
+{
+  gcry_sexp_t l1, l2, l3;
+  gcry_mpi_t a_value;
+
+  l1 = gcry_sexp_find_token (encr_data, "enc-val", 0);
+  if (!l1)
+    return NULL;
+  l2 = gcry_sexp_find_token (l1, "rsa", 0);
+  gcry_sexp_release (l1);
+  if (!l2)
+    return NULL;
+  l3 = gcry_sexp_find_token (l2, "a", 0);
+  gcry_sexp_release (l2);
+  if (!l3)
+    return NULL;
+  a_value = gcry_sexp_nth_mpi (l3, 1, 0);
+  gcry_sexp_release (l3);
+
+  return a_value;
+}
+
+
+static const char *
+selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
+{
+  const char *errtxt = NULL;
+  gcry_error_t err;
+  const unsigned int nbits = 1000; /* Encrypt 1000 random bits.  */
+  gcry_mpi_t plaintext = NULL;
+  gcry_sexp_t plain = NULL;
+  gcry_sexp_t encr  = NULL;
+  gcry_mpi_t  ciphertext = NULL;
+  gcry_sexp_t decr  = NULL;
+  gcry_mpi_t  decr_plaintext = NULL;
+  gcry_sexp_t tmplist = NULL;
+
+  /* Create plaintext.  The plaintext is actually a big integer number.  */
+  plaintext = gcry_mpi_new (nbits);
+  gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
+  
+  /* Put the plaintext into an S-expression.  */
+  err = gcry_sexp_build (&plain, NULL,
+                         "(data (flags raw) (value %m))", plaintext);
+  if (err)
+    {
+      errtxt = "converting data failed";
+      goto leave;
+    }
+
+  /* Encrypt.  */
+  err = gcry_pk_encrypt (&encr, plain, pkey);
+  if (err)
+    {
+      errtxt = "encrypt failed";
+      goto leave;
+    }
+
+  /* Extraxt the ciphertext from the returned S-expression.  */
+  /*gcry_sexp_dump (encr);*/
+  ciphertext = extract_a_from_sexp (encr);
+  if (!ciphertext)
+    {
+      errtxt = "gcry_pk_decrypt returned garbage";
+      goto leave;
+    }
+
+  /* Check that the ciphertext does no match the plaintext.  */
+  /* _gcry_log_mpidump ("plaintext", plaintext); */
+  /* _gcry_log_mpidump ("ciphertxt", ciphertext); */
+  if (!gcry_mpi_cmp (plaintext, ciphertext))
+    {
+      errtxt = "ciphertext matches plaintext";
+      goto leave;
+    }
+
+  /* Decrypt.  */
+  err = gcry_pk_decrypt (&decr, encr, skey);
+  if (err)
+    {
+      errtxt = "decrypt failed";
+      goto leave;
+    }
+
+  /* Extract the decrypted data from the S-expression.  Note that the
+     output of gcry_pk_decrypt depends on whether a flags lists occurs
+     in its input data.  Because we passed the output of
+     gcry_pk_encrypt directly to gcry_pk_decrypt, such a flag value
+     won't be there as of today.  To be prepared for future changes we
+     take care of it anyway.  */
+  tmplist = gcry_sexp_find_token (decr, "value", 0);
+  if (tmplist)
+    decr_plaintext = gcry_sexp_nth_mpi (tmplist, 1, GCRYMPI_FMT_USG);
+  else
+    decr_plaintext = gcry_sexp_nth_mpi (decr, 0, GCRYMPI_FMT_USG);
+  if (!decr_plaintext)
+    {
+      errtxt = "decrypt returned no plaintext";
+      goto leave;
+    }
+  
+  /* Check that the decrypted plaintext matches the original  plaintext.  */
+  if (gcry_mpi_cmp (plaintext, decr_plaintext))
+    {
+      errtxt = "mismatch";
+      goto leave;
+    }
+
+ leave:
+  gcry_sexp_release (tmplist);
+  gcry_mpi_release (decr_plaintext);
+  gcry_sexp_release (decr);
+  gcry_mpi_release (ciphertext);
+  gcry_sexp_release (encr);
+  gcry_sexp_release (plain);
+  gcry_mpi_release (plaintext);
+  return errtxt;
+}
+
+
+static gpg_err_code_t
+selftests_rsa (selftest_report_func_t report)
+{
+  const char *what;
+  const char *errtxt;
+  gcry_error_t err;
+  gcry_sexp_t skey = NULL;
+  gcry_sexp_t pkey = NULL;
+  
+  /* Convert the S-expressions into the internal representation.  */
+  what = "convert";
+  err = gcry_sexp_sscan (&skey, NULL, 
+                         sample_secret_key, strlen (sample_secret_key));
+  if (!err)
+    err = gcry_sexp_sscan (&pkey, NULL, 
+                           sample_public_key, strlen (sample_public_key));
+  if (err)
+    {
+      errtxt = gcry_strerror (err);
+      goto failed;
+    }
+
+  what = "key consistency";
+  err = gcry_pk_testkey (skey);
+  if (err)
+    {
+      errtxt = gcry_strerror (err);
+      goto failed;
+    }
+
+  what = "sign";
+  errtxt = selftest_sign_1024 (pkey, skey);
+  if (errtxt)
+    goto failed;
+
+  what = "encrypt";
+  errtxt = selftest_encr_1024 (pkey, skey);
+  if (errtxt)
+    goto failed;
+
+  gcry_sexp_release (pkey);
+  gcry_sexp_release (skey);
+  return 0; /* Succeeded. */
+
+ failed:
+  gcry_sexp_release (pkey);
+  gcry_sexp_release (skey);
+  if (report)
+    report ("pubkey", GCRY_PK_RSA, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Run a full self-test for ALGO and return 0 on success.  */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+  gpg_err_code_t ec;
+
+  (void)extended;
+
+  switch (algo)
+    {
+    case GCRY_PK_RSA:
+      ec = selftests_rsa (report);
+      break;
+    default:
+      ec = GPG_ERR_PUBKEY_ALGO;
+      break;
+        
+    }
+  return ec;
+}
+
+
+
+\f
+static const char *rsa_names[] =
+  {
+    "rsa",
+    "openpgp-rsa",
+    "oid.1.2.840.113549.1.1.1",
+    NULL,
+  };
+
+gcry_pk_spec_t _gcry_pubkey_spec_rsa =
+  {
+    "RSA", rsa_names,
+    "ne", "nedpqu", "a", "s", "n",
+    GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR,
+    rsa_generate,
+    rsa_check_secret_key,
+    rsa_encrypt,
+    rsa_decrypt,
+    rsa_sign,
+    rsa_verify,
+    rsa_get_nbits,
+  };
+pk_extra_spec_t _gcry_pubkey_extraspec_rsa = 
+  {
+    run_selftests,
+    rsa_generate_ext,
+    compute_keygrip
+  };
+
diff --git a/grub-core/lib/libgcrypt/cipher/seed.c b/grub-core/lib/libgcrypt/cipher/seed.c
new file mode 100644 (file)
index 0000000..b0980d6
--- /dev/null
@@ -0,0 +1,478 @@
+/* SEED for libgcrypt
+ *     Copyright (C) 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --
+ * This implementation was provided for libgcrypt in public domain
+ * by Hye-Shik Chang <perky@FreeBSD.org>, July 2006.
+ */
+\f
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "types.h"  /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+
+#define NUMKC  16
+
+#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \
+                   ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
+#define PUTU32(ct, st) { (ct)[0] = (byte)((st) >> 24); \
+                        (ct)[1] = (byte)((st) >> 16); \
+                        (ct)[2] = (byte)((st) >>  8); \
+                        (ct)[3] = (byte)(st); }
+
+union wordbuf
+{
+  u32 w;
+  byte b[4];
+};
+
+#ifdef WORDS_BIGENDIAN
+#define b0  b[3]
+#define b1  b[2]
+#define b2  b[1]
+#define b3  b[0]
+#else
+#define b0  b[0]
+#define b1  b[1]
+#define b2  b[2]
+#define b3  b[3]
+#endif
+
+static const char *selftest(void);
+
+typedef struct 
+{
+  u32 keyschedule[32];
+} SEED_context;
+
+static const u32 SS0[256] = {
+    0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c,
+    0x2c8ca0ac, 0x25052124, 0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c,
+    0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360, 0x28082028, 0x04444044,
+    0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
+    0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310,
+    0x12c2d2d0, 0x2ecee2ec, 0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8,
+    0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074, 0x2ccce0ec, 0x15859194,
+    0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
+    0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc,
+    0x32c2f2f0, 0x19c9d1d8, 0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380,
+    0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8, 0x20406060, 0x10405050,
+    0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
+    0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210,
+    0x2f8fa3ac, 0x15c5d1d4, 0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140,
+    0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008, 0x1f0f131c, 0x19899198,
+    0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
+    0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388,
+    0x0e0e020c, 0x2b8ba3a8, 0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c,
+    0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208, 0x3f8fb3bc, 0x2fcfe3ec,
+    0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
+    0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120,
+    0x2b4b6368, 0x26466264, 0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288,
+    0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0, 0x3a4a7278, 0x07474344,
+    0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
+    0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114,
+    0x22022220, 0x38083038, 0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c,
+    0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394, 0x35053134, 0x0bcbc3c8,
+    0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
+    0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158,
+    0x02828280, 0x04c4c0c4, 0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364,
+    0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8, 0x0f0f030c, 0x0e8e828c,
+    0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
+    0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c,
+    0x2d0d212c, 0x00404040, 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0,
+    0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154, 0x3b0b3338, 0x1cccd0dc,
+    0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
+    0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328,
+    0x25456164, 0x3acaf2f8, 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c,
+    0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0, 0x31013130, 0x2acae2e8,
+    0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
+    0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128,
+    0x07070304, 0x33033330, 0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178,
+    0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298,
+};
+
+static const u32 SS1[256] = {
+    0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2,
+    0xb03383b3, 0xb83888b0, 0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3,
+    0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53, 0xc003c3c3, 0x60224262,
+    0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
+    0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0,
+    0x34360632, 0x480b4b43, 0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0,
+    0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0, 0xc002c2c2, 0x44054541,
+    0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
+    0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1,
+    0x0c0d0d01, 0xdc1fcfd3, 0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72,
+    0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272, 0x40024242, 0xd414c4d0,
+    0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
+    0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20,
+    0xa82a8aa2, 0x34340430, 0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1,
+    0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0, 0x54174753, 0xac2e8ea2,
+    0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
+    0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82,
+    0x682a4a62, 0xb03181b1, 0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202,
+    0x20220222, 0x04040400, 0x68284860, 0x70314171, 0x04070703, 0xd81bcbd3,
+    0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
+    0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3,
+    0xa82b8ba3, 0xd010c0d0, 0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12,
+    0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3, 0x94168692, 0x783b4b73,
+    0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
+    0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22,
+    0xb83a8ab2, 0x6c2e4e62, 0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292,
+    0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0, 0x14150511, 0xf83bcbf3,
+    0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
+    0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0,
+    0xe82acae2, 0x08090901, 0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040,
+    0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501, 0xf83acaf2, 0x00010101,
+    0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
+    0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1,
+    0x48084840, 0x78394971, 0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282,
+    0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53, 0x74374773, 0x54144450,
+    0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
+    0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2,
+    0xc809c9c1, 0xfc3dcdf1, 0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30,
+    0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70, 0x0c0e0e02, 0x50104050,
+    0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393,
+    0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353,
+    0x080a0a02, 0x84078783, 0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83,
+    0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3,
+};
+
+static const u32 SS2[256] = {
+    0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d,
+    0xa0ac2c8c, 0x21242505, 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e,
+    0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343, 0x20282808, 0x40440444,
+    0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
+    0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303,
+    0xd2d012c2, 0xe2ec2ece, 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888,
+    0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444, 0xe0ec2ccc, 0x91941585,
+    0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
+    0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc,
+    0xf2f032c2, 0xd1d819c9, 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383,
+    0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9, 0x60602040, 0x50501040,
+    0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
+    0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202,
+    0xa3ac2f8f, 0xd1d415c5, 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141,
+    0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808, 0x131c1f0f, 0x91981989,
+    0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
+    0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b,
+    0x020c0e0e, 0xa3a82b8b, 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d,
+    0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a, 0xb3bc3f8f, 0xe3ec2fcf,
+    0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
+    0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101,
+    0x63682b4b, 0x62642646, 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a,
+    0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0, 0x72783a4a, 0x43440747,
+    0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
+    0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505,
+    0x22202202, 0x30383808, 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c,
+    0x81800181, 0xe1e829c9, 0x80840484, 0x93941787, 0x31343505, 0xc3c80bcb,
+    0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
+    0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949,
+    0x82800282, 0xc0c404c4, 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747,
+    0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888, 0x030c0f0f, 0x828c0e8e,
+    0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
+    0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d,
+    0x212c2d0d, 0x40400040, 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1,
+    0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545, 0x33383b0b, 0xd0dc1ccc,
+    0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
+    0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b,
+    0x61642545, 0xf2f83aca, 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f,
+    0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282, 0x31303101, 0xe2e82aca,
+    0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
+    0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909,
+    0x03040707, 0x33303303, 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949,
+    0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a,
+};
+
+static const u32 SS3[256] = {
+    0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e,
+    0x83b3b033, 0x88b0b838, 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407,
+    0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b, 0xc3c3c003, 0x42626022,
+    0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
+    0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c,
+    0x06323436, 0x4b43480b, 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828,
+    0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434, 0xc2c2c002, 0x45414405,
+    0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
+    0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839,
+    0x0d010c0d, 0xcfd3dc1f, 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a,
+    0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032, 0x42424002, 0xc4d0d414,
+    0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
+    0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c,
+    0x8aa2a82a, 0x04303434, 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829,
+    0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838, 0x47535417, 0x8ea2ac2e,
+    0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
+    0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a,
+    0x4a62682a, 0x81b1b031, 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002,
+    0x02222022, 0x04000404, 0x48606828, 0x41717031, 0x07030407, 0xcbd3d81b,
+    0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
+    0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023,
+    0x8ba3a82b, 0xc0d0d010, 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a,
+    0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f, 0x86929416, 0x4b73783b,
+    0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
+    0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e,
+    0x8ab2b83a, 0x4e626c2e, 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012,
+    0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c, 0x05111415, 0xcbf3f83b,
+    0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
+    0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434,
+    0xcae2e82a, 0x09010809, 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000,
+    0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405, 0xcaf2f83a, 0x01010001,
+    0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
+    0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425,
+    0x48404808, 0x49717839, 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002,
+    0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f, 0x47737437, 0x44505414,
+    0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
+    0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a,
+    0xc9c1c809, 0xcdf1fc3d, 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c,
+    0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c, 0x0e020c0e, 0x40505010,
+    0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013,
+    0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013,
+    0x0a02080a, 0x87838407, 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f,
+    0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437,
+};
+
+static const u32 KC[NUMKC] = {
+    0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc,
+    0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf,
+    0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1,
+    0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b,
+};
+\f
+
+
+/* Perform the key setup.
+ */  
+static gcry_err_code_t
+do_setkey (SEED_context *ctx, const byte *key, const unsigned keylen)
+{
+  static int initialized = 0;
+  static const char *selftest_failed=0;
+  u32 x1, x2, x3, x4;
+  union wordbuf t0, t1;
+  u32 *keyout = ctx->keyschedule;
+  int i;
+
+  if (!initialized)
+    {
+      initialized = 1;
+      selftest_failed = selftest ();
+      if( selftest_failed )
+        log_error ("%s\n", selftest_failed );
+    }
+  if (selftest_failed)
+    return GPG_ERR_SELFTEST_FAILED;
+
+  if (keylen != 16)
+    return GPG_ERR_INV_KEYLEN;
+
+  x1 = GETU32 (key);
+  x2 = GETU32 (key+4);
+  x3 = GETU32 (key+8);
+  x4 = GETU32 (key+12);
+
+  for (i = 0; i < NUMKC; i++)
+    {
+      t0.w = x1 + x3 - KC[i];
+      t1.w = x2 + KC[i] - x4;
+      *(keyout++) = SS0[t0.b0] ^ SS1[t0.b1] ^ SS2[t0.b2] ^ SS3[t0.b3];
+      *(keyout++) = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3];
+
+      if (i % 2 == 0)
+       {
+         t0.w = x1;
+         x1 = (x1>>8) ^ (x2<<24);
+         x2 = (x2>>8) ^ (t0.w<<24);
+       }
+      else
+       {
+         t0.w = x3;
+         x3 = (x3<<8) ^ (x4>>24);
+         x4 = (x4<<8) ^ (t0.w>>24);
+       }
+    }
+
+  return 0;
+}
+
+static gcry_err_code_t
+seed_setkey (void *context, const byte *key, const unsigned keylen)
+{
+  SEED_context *ctx = context;
+
+  int rc = do_setkey (ctx, key, keylen);
+  _gcry_burn_stack (4*6 + sizeof(void*)*2 + sizeof(int)*2);
+  return rc;
+}
+
+
+\f
+#define OP(X1, X2, X3, X4, rbase)                              \
+    t0.w = X3 ^ ctx->keyschedule[rbase];                       \
+    t1.w = X4 ^ ctx->keyschedule[rbase+1];                     \
+    t1.w ^= t0.w;                                              \
+    t1.w = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3];  \
+    t0.w += t1.w;                                              \
+    t0.w = SS0[t0.b0] ^ SS1[t0.b1] ^ SS2[t0.b2] ^ SS3[t0.b3];  \
+    t1.w += t0.w;                                              \
+    t1.w = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3];  \
+    t0.w += t1.w;                                              \
+    X1 ^= t0.w;                                                        \
+    X2 ^= t1.w;
+
+/* Encrypt one block.  inbuf and outbuf may be the same. */
+static void
+do_encrypt (const SEED_context *ctx, byte *outbuf, const byte *inbuf)
+{
+  u32 x1, x2, x3, x4;
+  union wordbuf t0, t1;
+
+  x1 = GETU32 (inbuf);
+  x2 = GETU32 (inbuf+4);
+  x3 = GETU32 (inbuf+8);
+  x4 = GETU32 (inbuf+12);
+
+  OP (x1, x2, x3, x4, 0);
+  OP (x3, x4, x1, x2, 2);
+  OP (x1, x2, x3, x4, 4);
+  OP (x3, x4, x1, x2, 6);
+  OP (x1, x2, x3, x4, 8);
+  OP (x3, x4, x1, x2, 10);
+  OP (x1, x2, x3, x4, 12);
+  OP (x3, x4, x1, x2, 14);
+  OP (x1, x2, x3, x4, 16);
+  OP (x3, x4, x1, x2, 18);
+  OP (x1, x2, x3, x4, 20);
+  OP (x3, x4, x1, x2, 22);
+  OP (x1, x2, x3, x4, 24);
+  OP (x3, x4, x1, x2, 26);
+  OP (x1, x2, x3, x4, 28);
+  OP (x3, x4, x1, x2, 30);
+
+  PUTU32 (outbuf, x3);
+  PUTU32 (outbuf+4, x4);
+  PUTU32 (outbuf+8, x1);
+  PUTU32 (outbuf+12, x2);
+}
+
+static void
+seed_encrypt (void *context, byte *outbuf, const byte *inbuf)
+{
+  SEED_context *ctx = context;
+
+  do_encrypt (ctx, outbuf, inbuf);
+  _gcry_burn_stack (4*6);
+}
+
+
+\f
+/* Decrypt one block.  inbuf and outbuf may be the same. */
+static void
+do_decrypt (SEED_context *ctx, byte *outbuf, const byte *inbuf)
+{
+  u32 x1, x2, x3, x4;
+  union wordbuf t0, t1;
+
+  x1 = GETU32 (inbuf);
+  x2 = GETU32 (inbuf+4);
+  x3 = GETU32 (inbuf+8);
+  x4 = GETU32 (inbuf+12);
+
+  OP (x1, x2, x3, x4, 30);
+  OP (x3, x4, x1, x2, 28);
+  OP (x1, x2, x3, x4, 26);
+  OP (x3, x4, x1, x2, 24);
+  OP (x1, x2, x3, x4, 22);
+  OP (x3, x4, x1, x2, 20);
+  OP (x1, x2, x3, x4, 18);
+  OP (x3, x4, x1, x2, 16);
+  OP (x1, x2, x3, x4, 14);
+  OP (x3, x4, x1, x2, 12);
+  OP (x1, x2, x3, x4, 10);
+  OP (x3, x4, x1, x2, 8);
+  OP (x1, x2, x3, x4, 6);
+  OP (x3, x4, x1, x2, 4);
+  OP (x1, x2, x3, x4, 2);
+  OP (x3, x4, x1, x2, 0);
+
+  PUTU32 (outbuf, x3);
+  PUTU32 (outbuf+4, x4);
+  PUTU32 (outbuf+8, x1);
+  PUTU32 (outbuf+12, x2);
+}
+
+static void
+seed_decrypt (void *context, byte *outbuf, const byte *inbuf)
+{
+  SEED_context *ctx = context;
+
+  do_decrypt (ctx, outbuf, inbuf);
+  _gcry_burn_stack (4*6);
+}
+
+\f
+/* Test a single encryption and decryption with each key size. */
+static const char*
+selftest (void)
+{
+  SEED_context ctx;
+  byte scratch[16];       
+
+  /* The test vector is taken from the appendix section B.3 of RFC4269.
+   */
+  static const byte plaintext[16] = {
+    0x83, 0xA2, 0xF8, 0xA2, 0x88, 0x64, 0x1F, 0xB9,
+    0xA4, 0xE9, 0xA5, 0xCC, 0x2F, 0x13, 0x1C, 0x7D
+  };
+  static const byte key[16] = {
+    0x47, 0x06, 0x48, 0x08, 0x51, 0xE6, 0x1B, 0xE8,
+    0x5D, 0x74, 0xBF, 0xB3, 0xFD, 0x95, 0x61, 0x85
+  };
+  static const byte ciphertext[16] = {
+    0xEE, 0x54, 0xD1, 0x3E, 0xBC, 0xAE, 0x70, 0x6D,
+    0x22, 0x6B, 0xC3, 0x14, 0x2C, 0xD4, 0x0D, 0x4A,
+  };
+
+  seed_setkey (&ctx, key, sizeof(key));
+  seed_encrypt (&ctx, scratch, plaintext);
+  if (memcmp (scratch, ciphertext, sizeof (ciphertext)))
+    return "SEED test encryption failed.";
+  seed_decrypt (&ctx, scratch, scratch);
+  if (memcmp (scratch, plaintext, sizeof (plaintext)))
+    return "SEED test decryption failed.";
+
+  return NULL;
+}
+
+\f
+
+static gcry_cipher_oid_spec_t seed_oids[] =
+  {
+    { "1.2.410.200004.1.3", GCRY_CIPHER_MODE_ECB },
+    { "1.2.410.200004.1.4", GCRY_CIPHER_MODE_CBC },
+    { "1.2.410.200004.1.5", GCRY_CIPHER_MODE_CFB },
+    { "1.2.410.200004.1.6", GCRY_CIPHER_MODE_OFB },
+    { NULL }
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_seed =
+  {
+    "SEED", NULL, seed_oids, 16, 128, sizeof (SEED_context),
+    seed_setkey, seed_encrypt, seed_decrypt,
+  };
diff --git a/grub-core/lib/libgcrypt/cipher/serpent.c b/grub-core/lib/libgcrypt/cipher/serpent.c
new file mode 100644 (file)
index 0000000..6b7e655
--- /dev/null
@@ -0,0 +1,978 @@
+/* serpent.c - Implementation of the Serpent encryption algorithm.
+ *     Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include <stdio.h>
+
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "bithelp.h"
+
+/* Number of rounds per Serpent encrypt/decrypt operation.  */
+#define ROUNDS 32
+
+/* Magic number, used during generating of the subkeys.  */
+#define PHI 0x9E3779B9
+
+/* Serpent works on 128 bit blocks.  */
+typedef u32 serpent_block_t[4];
+
+/* Serpent key, provided by the user.  If the original key is shorter
+   than 256 bits, it is padded.  */
+typedef u32 serpent_key_t[8];
+
+/* The key schedule consists of 33 128 bit subkeys.  */
+typedef u32 serpent_subkeys_t[ROUNDS + 1][4];
+
+/* A Serpent context.  */
+typedef struct serpent_context
+{
+  serpent_subkeys_t keys;      /* Generated subkeys.  */
+} serpent_context_t;
+
+
+/* A prototype.  */
+static const char *serpent_test (void);
+      
+
+#define byte_swap_32(x) \
+  (0 \
+   | (((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) \
+   | (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
+
+/* These are the S-Boxes of Serpent.  They are copied from Serpents
+   reference implementation (the optimized one, contained in
+   `floppy2') and are therefore:
+
+     Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen.
+
+  To quote the Serpent homepage
+  (http://www.cl.cam.ac.uk/~rja14/serpent.html):
+
+  "Serpent is now completely in the public domain, and we impose no
+   restrictions on its use.  This was announced on the 21st August at
+   the First AES Candidate Conference. The optimised implementations
+   in the submission package are now under the GNU PUBLIC LICENSE
+   (GPL), although some comments in the code still say otherwise. You
+   are welcome to use Serpent for any application."  */
+
+#define SBOX0(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t05, t06, t07, t08, t09; \
+    u32 t11, t12, t13, t14, t15, t17, t01; \
+    t01 = b   ^ c  ; \
+    t02 = a   | d  ; \
+    t03 = a   ^ b  ; \
+    z   = t02 ^ t01; \
+    t05 = c   | z  ; \
+    t06 = a   ^ d  ; \
+    t07 = b   | c  ; \
+    t08 = d   & t05; \
+    t09 = t03 & t07; \
+    y   = t09 ^ t08; \
+    t11 = t09 & y  ; \
+    t12 = c   ^ d  ; \
+    t13 = t07 ^ t11; \
+    t14 = b   & t06; \
+    t15 = t06 ^ t13; \
+    w   =     ~ t15; \
+    t17 = w   ^ t14; \
+    x   = t12 ^ t17; \
+  }
+
+#define SBOX0_INVERSE(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t04, t05, t06, t08, t09, t10; \
+    u32 t12, t13, t14, t15, t17, t18, t01; \
+    t01 = c   ^ d  ; \
+    t02 = a   | b  ; \
+    t03 = b   | c  ; \
+    t04 = c   & t01; \
+    t05 = t02 ^ t01; \
+    t06 = a   | t04; \
+    y   =     ~ t05; \
+    t08 = b   ^ d  ; \
+    t09 = t03 & t08; \
+    t10 = d   | y  ; \
+    x   = t09 ^ t06; \
+    t12 = a   | t05; \
+    t13 = x   ^ t12; \
+    t14 = t03 ^ t10; \
+    t15 = a   ^ c  ; \
+    z   = t14 ^ t13; \
+    t17 = t05 & t13; \
+    t18 = t14 | t17; \
+    w   = t15 ^ t18; \
+  }
+
+#define SBOX1(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t04, t05, t06, t07, t08; \
+    u32 t10, t11, t12, t13, t16, t17, t01; \
+    t01 = a   | d  ; \
+    t02 = c   ^ d  ; \
+    t03 =     ~ b  ; \
+    t04 = a   ^ c  ; \
+    t05 = a   | t03; \
+    t06 = d   & t04; \
+    t07 = t01 & t02; \
+    t08 = b   | t06; \
+    y   = t02 ^ t05; \
+    t10 = t07 ^ t08; \
+    t11 = t01 ^ t10; \
+    t12 = y   ^ t11; \
+    t13 = b   & d  ; \
+    z   =     ~ t10; \
+    x   = t13 ^ t12; \
+    t16 = t10 | x  ; \
+    t17 = t05 & t16; \
+    w   = c   ^ t17; \
+  }
+
+#define SBOX1_INVERSE(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t04, t05, t06, t07, t08; \
+    u32 t09, t10, t11, t14, t15, t17, t01; \
+    t01 = a   ^ b  ; \
+    t02 = b   | d  ; \
+    t03 = a   & c  ; \
+    t04 = c   ^ t02; \
+    t05 = a   | t04; \
+    t06 = t01 & t05; \
+    t07 = d   | t03; \
+    t08 = b   ^ t06; \
+    t09 = t07 ^ t06; \
+    t10 = t04 | t03; \
+    t11 = d   & t08; \
+    y   =     ~ t09; \
+    x   = t10 ^ t11; \
+    t14 = a   | y  ; \
+    t15 = t06 ^ x  ; \
+    z   = t01 ^ t04; \
+    t17 = c   ^ t15; \
+    w   = t14 ^ t17; \
+  }
+
+#define SBOX2(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t05, t06, t07, t08; \
+    u32 t09, t10, t12, t13, t14, t01; \
+    t01 = a   | c  ; \
+    t02 = a   ^ b  ; \
+    t03 = d   ^ t01; \
+    w   = t02 ^ t03; \
+    t05 = c   ^ w  ; \
+    t06 = b   ^ t05; \
+    t07 = b   | t05; \
+    t08 = t01 & t06; \
+    t09 = t03 ^ t07; \
+    t10 = t02 | t09; \
+    x   = t10 ^ t08; \
+    t12 = a   | d  ; \
+    t13 = t09 ^ x  ; \
+    t14 = b   ^ t13; \
+    z   =     ~ t09; \
+    y   = t12 ^ t14; \
+  }
+
+#define SBOX2_INVERSE(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t04, t06, t07, t08, t09; \
+    u32 t10, t11, t12, t15, t16, t17, t01; \
+    t01 = a   ^ d  ; \
+    t02 = c   ^ d  ; \
+    t03 = a   & c  ; \
+    t04 = b   | t02; \
+    w   = t01 ^ t04; \
+    t06 = a   | c  ; \
+    t07 = d   | w  ; \
+    t08 =     ~ d  ; \
+    t09 = b   & t06; \
+    t10 = t08 | t03; \
+    t11 = b   & t07; \
+    t12 = t06 & t02; \
+    z   = t09 ^ t10; \
+    x   = t12 ^ t11; \
+    t15 = c   & z  ; \
+    t16 = w   ^ x  ; \
+    t17 = t10 ^ t15; \
+    y   = t16 ^ t17; \
+  }
+
+#define SBOX3(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t04, t05, t06, t07, t08; \
+    u32 t09, t10, t11, t13, t14, t15, t01; \
+    t01 = a   ^ c  ; \
+    t02 = a   | d  ; \
+    t03 = a   & d  ; \
+    t04 = t01 & t02; \
+    t05 = b   | t03; \
+    t06 = a   & b  ; \
+    t07 = d   ^ t04; \
+    t08 = c   | t06; \
+    t09 = b   ^ t07; \
+    t10 = d   & t05; \
+    t11 = t02 ^ t10; \
+    z   = t08 ^ t09; \
+    t13 = d   | z  ; \
+    t14 = a   | t07; \
+    t15 = b   & t13; \
+    y   = t08 ^ t11; \
+    w   = t14 ^ t15; \
+    x   = t05 ^ t04; \
+  }
+
+#define SBOX3_INVERSE(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t04, t05, t06, t07, t09; \
+    u32 t11, t12, t13, t14, t16, t01; \
+    t01 = c   | d  ; \
+    t02 = a   | d  ; \
+    t03 = c   ^ t02; \
+    t04 = b   ^ t02; \
+    t05 = a   ^ d  ; \
+    t06 = t04 & t03; \
+    t07 = b   & t01; \
+    y   = t05 ^ t06; \
+    t09 = a   ^ t03; \
+    w   = t07 ^ t03; \
+    t11 = w   | t05; \
+    t12 = t09 & t11; \
+    t13 = a   & y  ; \
+    t14 = t01 ^ t05; \
+    x   = b   ^ t12; \
+    t16 = b   | t13; \
+    z   = t14 ^ t16; \
+  }
+
+#define SBOX4(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t04, t05, t06, t08, t09; \
+    u32 t10, t11, t12, t13, t14, t15, t16, t01; \
+    t01 = a   | b  ; \
+    t02 = b   | c  ; \
+    t03 = a   ^ t02; \
+    t04 = b   ^ d  ; \
+    t05 = d   | t03; \
+    t06 = d   & t01; \
+    z   = t03 ^ t06; \
+    t08 = z   & t04; \
+    t09 = t04 & t05; \
+    t10 = c   ^ t06; \
+    t11 = b   & c  ; \
+    t12 = t04 ^ t08; \
+    t13 = t11 | t03; \
+    t14 = t10 ^ t09; \
+    t15 = a   & t05; \
+    t16 = t11 | t12; \
+    y   = t13 ^ t08; \
+    x   = t15 ^ t16; \
+    w   =     ~ t14; \
+  }
+
+#define SBOX4_INVERSE(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t04, t05, t06, t07, t09; \
+    u32 t10, t11, t12, t13, t15, t01; \
+    t01 = b   | d  ; \
+    t02 = c   | d  ; \
+    t03 = a   & t01; \
+    t04 = b   ^ t02; \
+    t05 = c   ^ d  ; \
+    t06 =     ~ t03; \
+    t07 = a   & t04; \
+    x   = t05 ^ t07; \
+    t09 = x   | t06; \
+    t10 = a   ^ t07; \
+    t11 = t01 ^ t09; \
+    t12 = d   ^ t04; \
+    t13 = c   | t10; \
+    z   = t03 ^ t12; \
+    t15 = a   ^ t04; \
+    y   = t11 ^ t13; \
+    w   = t15 ^ t09; \
+  }
+
+#define SBOX5(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t04, t05, t07, t08, t09; \
+    u32 t10, t11, t12, t13, t14, t01; \
+    t01 = b   ^ d  ; \
+    t02 = b   | d  ; \
+    t03 = a   & t01; \
+    t04 = c   ^ t02; \
+    t05 = t03 ^ t04; \
+    w   =     ~ t05; \
+    t07 = a   ^ t01; \
+    t08 = d   | w  ; \
+    t09 = b   | t05; \
+    t10 = d   ^ t08; \
+    t11 = b   | t07; \
+    t12 = t03 | w  ; \
+    t13 = t07 | t10; \
+    t14 = t01 ^ t11; \
+    y   = t09 ^ t13; \
+    x   = t07 ^ t08; \
+    z   = t12 ^ t14; \
+  }
+
+#define SBOX5_INVERSE(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t04, t05, t07, t08, t09; \
+    u32 t10, t12, t13, t15, t16, t01; \
+    t01 = a   & d  ; \
+    t02 = c   ^ t01; \
+    t03 = a   ^ d  ; \
+    t04 = b   & t02; \
+    t05 = a   & c  ; \
+    w   = t03 ^ t04; \
+    t07 = a   & w  ; \
+    t08 = t01 ^ w  ; \
+    t09 = b   | t05; \
+    t10 =     ~ b  ; \
+    x   = t08 ^ t09; \
+    t12 = t10 | t07; \
+    t13 = w   | x  ; \
+    z   = t02 ^ t12; \
+    t15 = t02 ^ t13; \
+    t16 = b   ^ d  ; \
+    y   = t16 ^ t15; \
+  }
+
+#define SBOX6(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t04, t05, t07, t08, t09, t10; \
+    u32 t11, t12, t13, t15, t17, t18, t01; \
+    t01 = a   & d  ; \
+    t02 = b   ^ c  ; \
+    t03 = a   ^ d  ; \
+    t04 = t01 ^ t02; \
+    t05 = b   | c  ; \
+    x   =     ~ t04; \
+    t07 = t03 & t05; \
+    t08 = b   & x  ; \
+    t09 = a   | c  ; \
+    t10 = t07 ^ t08; \
+    t11 = b   | d  ; \
+    t12 = c   ^ t11; \
+    t13 = t09 ^ t10; \
+    y   =     ~ t13; \
+    t15 = x   & t03; \
+    z   = t12 ^ t07; \
+    t17 = a   ^ b  ; \
+    t18 = y   ^ t15; \
+    w   = t17 ^ t18; \
+  }
+
+#define SBOX6_INVERSE(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t04, t05, t06, t07, t08, t09; \
+    u32 t12, t13, t14, t15, t16, t17, t01; \
+    t01 = a   ^ c  ; \
+    t02 =     ~ c  ; \
+    t03 = b   & t01; \
+    t04 = b   | t02; \
+    t05 = d   | t03; \
+    t06 = b   ^ d  ; \
+    t07 = a   & t04; \
+    t08 = a   | t02; \
+    t09 = t07 ^ t05; \
+    x   = t06 ^ t08; \
+    w   =     ~ t09; \
+    t12 = b   & w  ; \
+    t13 = t01 & t05; \
+    t14 = t01 ^ t12; \
+    t15 = t07 ^ t13; \
+    t16 = d   | t02; \
+    t17 = a   ^ x  ; \
+    z   = t17 ^ t15; \
+    y   = t16 ^ t14; \
+  }
+
+#define SBOX7(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t04, t05, t06, t08, t09, t10; \
+    u32 t11, t13, t14, t15, t16, t17, t01; \
+    t01 = a   & c  ; \
+    t02 =     ~ d  ; \
+    t03 = a   & t02; \
+    t04 = b   | t01; \
+    t05 = a   & b  ; \
+    t06 = c   ^ t04; \
+    z   = t03 ^ t06; \
+    t08 = c   | z  ; \
+    t09 = d   | t05; \
+    t10 = a   ^ t08; \
+    t11 = t04 & z  ; \
+    x   = t09 ^ t10; \
+    t13 = b   ^ x  ; \
+    t14 = t01 ^ x  ; \
+    t15 = c   ^ t05; \
+    t16 = t11 | t13; \
+    t17 = t02 | t14; \
+    w   = t15 ^ t17; \
+    y   = a   ^ t16; \
+  }
+
+#define SBOX7_INVERSE(a, b, c, d, w, x, y, z) \
+  { \
+    u32 t02, t03, t04, t06, t07, t08, t09; \
+    u32 t10, t11, t13, t14, t15, t16, t01; \
+    t01 = a   & b  ; \
+    t02 = a   | b  ; \
+    t03 = c   | t01; \
+    t04 = d   & t02; \
+    z   = t03 ^ t04; \
+    t06 = b   ^ t04; \
+    t07 = d   ^ z  ; \
+    t08 =     ~ t07; \
+    t09 = t06 | t08; \
+    t10 = b   ^ d  ; \
+    t11 = a   | d  ; \
+    x   = a   ^ t09; \
+    t13 = c   ^ t06; \
+    t14 = c   & t11; \
+    t15 = d   | x  ; \
+    t16 = t01 | t10; \
+    w   = t13 ^ t15; \
+    y   = t14 ^ t16; \
+  }
+
+/* XOR BLOCK1 into BLOCK0.  */
+#define BLOCK_XOR(block0, block1) \
+  {                               \
+    block0[0] ^= block1[0];       \
+    block0[1] ^= block1[1];       \
+    block0[2] ^= block1[2];       \
+    block0[3] ^= block1[3];       \
+  }
+
+/* Copy BLOCK_SRC to BLOCK_DST.  */
+#define BLOCK_COPY(block_dst, block_src) \
+  {                                      \
+    block_dst[0] = block_src[0];         \
+    block_dst[1] = block_src[1];         \
+    block_dst[2] = block_src[2];         \
+    block_dst[3] = block_src[3];         \
+  }
+
+/* Apply SBOX number WHICH to to the block found in ARRAY0 at index
+   INDEX, writing the output to the block found in ARRAY1 at index
+   INDEX.  */
+#define SBOX(which, array0, array1, index)            \
+  SBOX##which (array0[index + 0], array0[index + 1],  \
+               array0[index + 2], array0[index + 3],  \
+               array1[index + 0], array1[index + 1],  \
+               array1[index + 2], array1[index + 3]);
+
+/* Apply inverse SBOX number WHICH to to the block found in ARRAY0 at
+   index INDEX, writing the output to the block found in ARRAY1 at
+   index INDEX.  */
+#define SBOX_INVERSE(which, array0, array1, index)              \
+  SBOX##which##_INVERSE (array0[index + 0], array0[index + 1],  \
+                         array0[index + 2], array0[index + 3],  \
+                         array1[index + 0], array1[index + 1],  \
+                         array1[index + 2], array1[index + 3]);
+
+/* Apply the linear transformation to BLOCK.  */
+#define LINEAR_TRANSFORMATION(block)                  \
+  {                                                   \
+    block[0] = rol (block[0], 13);                    \
+    block[2] = rol (block[2], 3);                     \
+    block[1] = block[1] ^ block[0] ^ block[2];        \
+    block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
+    block[1] = rol (block[1], 1);                     \
+    block[3] = rol (block[3], 7);                     \
+    block[0] = block[0] ^ block[1] ^ block[3];        \
+    block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
+    block[0] = rol (block[0], 5);                     \
+    block[2] = rol (block[2], 22);                    \
+  }
+
+/* Apply the inverse linear transformation to BLOCK.  */
+#define LINEAR_TRANSFORMATION_INVERSE(block)          \
+  {                                                   \
+    block[2] = ror (block[2], 22);                    \
+    block[0] = ror (block[0] , 5);                    \
+    block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
+    block[0] = block[0] ^ block[1] ^ block[3];        \
+    block[3] = ror (block[3], 7);                     \
+    block[1] = ror (block[1], 1);                     \
+    block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
+    block[1] = block[1] ^ block[0] ^ block[2];        \
+    block[2] = ror (block[2], 3);                     \
+    block[0] = ror (block[0], 13);                    \
+  }
+
+/* Apply a Serpent round to BLOCK, using the SBOX number WHICH and the
+   subkeys contained in SUBKEYS.  Use BLOCK_TMP as temporary storage.
+   This macro increments `round'.  */
+#define ROUND(which, subkeys, block, block_tmp) \
+  {                                             \
+    BLOCK_XOR (block, subkeys[round]);          \
+    round++;                                    \
+    SBOX (which, block, block_tmp, 0);          \
+    LINEAR_TRANSFORMATION (block_tmp);          \
+    BLOCK_COPY (block, block_tmp);              \
+  }
+
+/* Apply the last Serpent round to BLOCK, using the SBOX number WHICH
+   and the subkeys contained in SUBKEYS.  Use BLOCK_TMP as temporary
+   storage.  The result will be stored in BLOCK_TMP.  This macro
+   increments `round'.  */
+#define ROUND_LAST(which, subkeys, block, block_tmp) \
+  {                                                  \
+    BLOCK_XOR (block, subkeys[round]);               \
+    round++;                                         \
+    SBOX (which, block, block_tmp, 0);               \
+    BLOCK_XOR (block_tmp, subkeys[round]);           \
+    round++;                                         \
+  }
+
+/* Apply an inverse Serpent round to BLOCK, using the SBOX number
+   WHICH and the subkeys contained in SUBKEYS.  Use BLOCK_TMP as
+   temporary storage.  This macro increments `round'.  */
+#define ROUND_INVERSE(which, subkey, block, block_tmp) \
+  {                                                    \
+    LINEAR_TRANSFORMATION_INVERSE (block);             \
+    SBOX_INVERSE (which, block, block_tmp, 0);         \
+    BLOCK_XOR (block_tmp, subkey[round]);              \
+    round--;                                           \
+    BLOCK_COPY (block, block_tmp);                     \
+  }
+
+/* Apply the first Serpent round to BLOCK, using the SBOX number WHICH
+   and the subkeys contained in SUBKEYS.  Use BLOCK_TMP as temporary
+   storage.  The result will be stored in BLOCK_TMP.  This macro
+   increments `round'.  */
+#define ROUND_FIRST_INVERSE(which, subkeys, block, block_tmp) \
+  {                                                           \
+    BLOCK_XOR (block, subkeys[round]);                        \
+    round--;                                                  \
+    SBOX_INVERSE (which, block, block_tmp, 0);                \
+    BLOCK_XOR (block_tmp, subkeys[round]);                    \
+    round--;                                                  \
+  }
+
+/* Convert the user provided key KEY of KEY_LENGTH bytes into the
+   internally used format.  */
+static void
+serpent_key_prepare (const byte *key, unsigned int key_length,
+                    serpent_key_t key_prepared)
+{
+  int i;
+
+  /* Copy key.  */
+  for (i = 0; i < key_length / 4; i++)
+    {
+#ifdef WORDS_BIGENDIAN
+      key_prepared[i] = byte_swap_32 (((u32 *) key)[i]);
+#else
+      key_prepared[i] = ((u32 *) key)[i];
+#endif
+    }
+
+  if (i < 8)
+    {
+      /* Key must be padded according to the Serpent
+        specification.  */
+      key_prepared[i] = 0x00000001;
+
+      for (i++; i < 8; i++)
+       key_prepared[i] = 0;
+    }
+}
+
+/* Derive the 33 subkeys from KEY and store them in SUBKEYS.  */
+static void
+serpent_subkeys_generate (serpent_key_t key, serpent_subkeys_t subkeys)
+{
+  u32 w_real[140];             /* The `prekey'.  */
+  u32 k[132];
+  u32 *w = &w_real[8];
+  int i, j;
+
+  /* Initialize with key values.  */
+  for (i = 0; i < 8; i++)
+    w[i - 8] = key[i];
+
+  /* Expand to intermediate key using the affine recurrence.  */
+  for (i = 0; i < 132; i++)
+    w[i] = rol (w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11);
+
+  /* Calculate subkeys via S-Boxes, in bitslice mode.  */
+  SBOX (3, w, k,   0);
+  SBOX (2, w, k,   4);
+  SBOX (1, w, k,   8);
+  SBOX (0, w, k,  12);
+  SBOX (7, w, k,  16);
+  SBOX (6, w, k,  20);
+  SBOX (5, w, k,  24);
+  SBOX (4, w, k,  28);
+  SBOX (3, w, k,  32);
+  SBOX (2, w, k,  36);
+  SBOX (1, w, k,  40);
+  SBOX (0, w, k,  44);
+  SBOX (7, w, k,  48);
+  SBOX (6, w, k,  52);
+  SBOX (5, w, k,  56);
+  SBOX (4, w, k,  60);
+  SBOX (3, w, k,  64);
+  SBOX (2, w, k,  68);
+  SBOX (1, w, k,  72);
+  SBOX (0, w, k,  76);
+  SBOX (7, w, k,  80);
+  SBOX (6, w, k,  84);
+  SBOX (5, w, k,  88);
+  SBOX (4, w, k,  92);
+  SBOX (3, w, k,  96);
+  SBOX (2, w, k, 100);
+  SBOX (1, w, k, 104);
+  SBOX (0, w, k, 108);
+  SBOX (7, w, k, 112);
+  SBOX (6, w, k, 116);
+  SBOX (5, w, k, 120);
+  SBOX (4, w, k, 124);
+  SBOX (3, w, k, 128);
+
+  /* Renumber subkeys.  */
+  for (i = 0; i < ROUNDS + 1; i++)
+    for (j = 0; j < 4; j++)
+      subkeys[i][j] = k[4 * i + j];
+}
+
+/* Initialize CONTEXT with the key KEY of KEY_LENGTH bits.  */
+static void
+serpent_setkey_internal (serpent_context_t *context,
+                        const byte *key, unsigned int key_length)
+{
+  serpent_key_t key_prepared;
+
+  serpent_key_prepare (key, key_length, key_prepared);
+  serpent_subkeys_generate (key_prepared, context->keys);
+  _gcry_burn_stack (272 * sizeof (u32));
+}
+
+/* Initialize CTX with the key KEY of KEY_LENGTH bytes.  */
+static gcry_err_code_t
+serpent_setkey (void *ctx,
+               const byte *key, unsigned int key_length)
+{
+  serpent_context_t *context = ctx;
+  static const char *serpent_test_ret;
+  static int serpent_init_done;
+  gcry_err_code_t ret = GPG_ERR_NO_ERROR;
+  
+  if (! serpent_init_done)
+    {
+      /* Execute a self-test the first time, Serpent is used.  */
+      serpent_test_ret = serpent_test ();
+      if (serpent_test_ret)
+       log_error ("Serpent test failure: %s\n", serpent_test_ret);
+      serpent_init_done = 1;
+    }
+
+  if (serpent_test_ret)
+    ret = GPG_ERR_SELFTEST_FAILED;
+  else
+    {
+      serpent_setkey_internal (context, key, key_length);
+      _gcry_burn_stack (sizeof (serpent_key_t));
+    }
+
+  return ret;
+}
+
+static void
+serpent_encrypt_internal (serpent_context_t *context,
+                         const serpent_block_t input, serpent_block_t output)
+{
+  serpent_block_t b, b_next;
+  int round = 0;
+
+#ifdef WORDS_BIGENDIAN
+  b[0] = byte_swap_32 (input[0]);
+  b[1] = byte_swap_32 (input[1]);
+  b[2] = byte_swap_32 (input[2]);
+  b[3] = byte_swap_32 (input[3]);
+#else
+  b[0] = input[0];
+  b[1] = input[1];
+  b[2] = input[2];
+  b[3] = input[3];
+#endif
+
+  ROUND (0, context->keys, b, b_next);
+  ROUND (1, context->keys, b, b_next);
+  ROUND (2, context->keys, b, b_next);
+  ROUND (3, context->keys, b, b_next);
+  ROUND (4, context->keys, b, b_next);
+  ROUND (5, context->keys, b, b_next);
+  ROUND (6, context->keys, b, b_next);
+  ROUND (7, context->keys, b, b_next);
+  ROUND (0, context->keys, b, b_next);
+  ROUND (1, context->keys, b, b_next);
+  ROUND (2, context->keys, b, b_next);
+  ROUND (3, context->keys, b, b_next);
+  ROUND (4, context->keys, b, b_next);
+  ROUND (5, context->keys, b, b_next);
+  ROUND (6, context->keys, b, b_next);
+  ROUND (7, context->keys, b, b_next);
+  ROUND (0, context->keys, b, b_next);
+  ROUND (1, context->keys, b, b_next);
+  ROUND (2, context->keys, b, b_next);
+  ROUND (3, context->keys, b, b_next);
+  ROUND (4, context->keys, b, b_next);
+  ROUND (5, context->keys, b, b_next);
+  ROUND (6, context->keys, b, b_next);
+  ROUND (7, context->keys, b, b_next);
+  ROUND (0, context->keys, b, b_next);
+  ROUND (1, context->keys, b, b_next);
+  ROUND (2, context->keys, b, b_next);
+  ROUND (3, context->keys, b, b_next);
+  ROUND (4, context->keys, b, b_next);
+  ROUND (5, context->keys, b, b_next);
+  ROUND (6, context->keys, b, b_next);
+
+  ROUND_LAST (7, context->keys, b, b_next);
+
+#ifdef WORDS_BIGENDIAN
+  output[0] = byte_swap_32 (b_next[0]);
+  output[1] = byte_swap_32 (b_next[1]);
+  output[2] = byte_swap_32 (b_next[2]);
+  output[3] = byte_swap_32 (b_next[3]);
+#else
+  output[0] = b_next[0];
+  output[1] = b_next[1];
+  output[2] = b_next[2];
+  output[3] = b_next[3];
+#endif
+}
+
+static void
+serpent_decrypt_internal (serpent_context_t *context,
+                         const serpent_block_t input, serpent_block_t output)
+{
+  serpent_block_t b, b_next;
+  int round = ROUNDS;
+
+#ifdef WORDS_BIGENDIAN
+  b_next[0] = byte_swap_32 (input[0]);
+  b_next[1] = byte_swap_32 (input[1]);
+  b_next[2] = byte_swap_32 (input[2]);
+  b_next[3] = byte_swap_32 (input[3]);
+#else
+  b_next[0] = input[0];
+  b_next[1] = input[1];
+  b_next[2] = input[2];
+  b_next[3] = input[3];
+#endif
+
+  ROUND_FIRST_INVERSE (7, context->keys, b_next, b);
+
+  ROUND_INVERSE (6, context->keys, b, b_next);
+  ROUND_INVERSE (5, context->keys, b, b_next);
+  ROUND_INVERSE (4, context->keys, b, b_next);
+  ROUND_INVERSE (3, context->keys, b, b_next);
+  ROUND_INVERSE (2, context->keys, b, b_next);
+  ROUND_INVERSE (1, context->keys, b, b_next);
+  ROUND_INVERSE (0, context->keys, b, b_next);
+  ROUND_INVERSE (7, context->keys, b, b_next);
+  ROUND_INVERSE (6, context->keys, b, b_next);
+  ROUND_INVERSE (5, context->keys, b, b_next);
+  ROUND_INVERSE (4, context->keys, b, b_next);
+  ROUND_INVERSE (3, context->keys, b, b_next);
+  ROUND_INVERSE (2, context->keys, b, b_next);
+  ROUND_INVERSE (1, context->keys, b, b_next);
+  ROUND_INVERSE (0, context->keys, b, b_next);
+  ROUND_INVERSE (7, context->keys, b, b_next);
+  ROUND_INVERSE (6, context->keys, b, b_next);
+  ROUND_INVERSE (5, context->keys, b, b_next);
+  ROUND_INVERSE (4, context->keys, b, b_next);
+  ROUND_INVERSE (3, context->keys, b, b_next);
+  ROUND_INVERSE (2, context->keys, b, b_next);
+  ROUND_INVERSE (1, context->keys, b, b_next);
+  ROUND_INVERSE (0, context->keys, b, b_next);
+  ROUND_INVERSE (7, context->keys, b, b_next);
+  ROUND_INVERSE (6, context->keys, b, b_next);
+  ROUND_INVERSE (5, context->keys, b, b_next);
+  ROUND_INVERSE (4, context->keys, b, b_next);
+  ROUND_INVERSE (3, context->keys, b, b_next);
+  ROUND_INVERSE (2, context->keys, b, b_next);
+  ROUND_INVERSE (1, context->keys, b, b_next);
+  ROUND_INVERSE (0, context->keys, b, b_next);
+
+
+#ifdef WORDS_BIGENDIAN
+  output[0] = byte_swap_32 (b_next[0]);
+  output[1] = byte_swap_32 (b_next[1]);
+  output[2] = byte_swap_32 (b_next[2]);
+  output[3] = byte_swap_32 (b_next[3]);
+#else
+  output[0] = b_next[0];
+  output[1] = b_next[1];
+  output[2] = b_next[2];
+  output[3] = b_next[3];
+#endif
+}
+
+static void
+serpent_encrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
+{
+  serpent_context_t *context = ctx;
+
+  serpent_encrypt_internal (context,
+                           (const u32 *) buffer_in, (u32 *) buffer_out);
+  _gcry_burn_stack (2 * sizeof (serpent_block_t));
+}
+
+static void
+serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
+{
+  serpent_context_t *context = ctx;
+
+  serpent_decrypt_internal (context,
+                           (const u32 *) buffer_in,
+                           (u32 *) buffer_out);
+  _gcry_burn_stack (2 * sizeof (serpent_block_t));
+}
+
+\f
+
+/* Serpent test.  */
+
+static const char *
+serpent_test (void)
+{
+  serpent_context_t context;
+  unsigned char scratch[16];
+  unsigned int i;
+
+  static struct test
+  {
+    int key_length;
+    unsigned char key[32];
+    unsigned char text_plain[16];
+    unsigned char text_cipher[16];
+  } test_data[] =
+    {
+      {
+       16,
+       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+       "\xD2\x9D\x57\x6F\xCE\xA3\xA3\xA7\xED\x90\x99\xF2\x92\x73\xD7\x8E",
+       "\xB2\x28\x8B\x96\x8A\xE8\xB0\x86\x48\xD1\xCE\x96\x06\xFD\x99\x2D"
+      },
+      {
+       24,
+       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+       "\x00\x00\x00\x00\x00\x00\x00\x00",
+       "\xD2\x9D\x57\x6F\xCE\xAB\xA3\xA7\xED\x98\x99\xF2\x92\x7B\xD7\x8E",
+       "\x13\x0E\x35\x3E\x10\x37\xC2\x24\x05\xE8\xFA\xEF\xB2\xC3\xC3\xE9"
+      },
+      {
+       32,
+       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+       "\xD0\x95\x57\x6F\xCE\xA3\xE3\xA7\xED\x98\xD9\xF2\x90\x73\xD7\x8E",
+       "\xB9\x0E\xE5\x86\x2D\xE6\x91\x68\xF2\xBD\xD5\x12\x5B\x45\x47\x2B"
+      },
+      {
+       32,
+       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+       "\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00",
+       "\x20\x61\xA4\x27\x82\xBD\x52\xEC\x69\x1E\xC3\x83\xB0\x3B\xA7\x7C"
+      },
+      {
+       0
+      },
+    };
+
+  for (i = 0; test_data[i].key_length; i++)
+    {
+      serpent_setkey_internal (&context, test_data[i].key,
+                               test_data[i].key_length);
+      serpent_encrypt_internal (&context,
+                               (const u32 *) test_data[i].text_plain,
+                               (u32 *) scratch);
+
+      if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t)))
+       switch (test_data[i].key_length)
+         {
+         case 16:
+           return "Serpent-128 test encryption failed.";
+         case  24:
+           return "Serpent-192 test encryption failed.";
+         case 32:
+           return "Serpent-256 test encryption failed.";
+         }
+
+    serpent_decrypt_internal (&context,
+                             (const u32 *) test_data[i].text_cipher,
+                             (u32 *) scratch);
+    if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t)))
+      switch (test_data[i].key_length)
+       {
+       case 16:
+         return "Serpent-128 test decryption failed.";
+       case  24:
+         return "Serpent-192 test decryption failed.";
+       case 32:
+         return "Serpent-256 test decryption failed.";
+       }
+    }
+
+  return NULL;
+}
+
+\f
+
+/* "SERPENT" is an alias for "SERPENT128".  */
+static const char *cipher_spec_serpent128_aliases[] =
+  {
+    "SERPENT",
+    NULL
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_serpent128 =
+  {
+    "SERPENT128", cipher_spec_serpent128_aliases, NULL, 16, 128,
+    sizeof (serpent_context_t),
+    serpent_setkey, serpent_encrypt, serpent_decrypt
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_serpent192 =
+  {
+    "SERPENT192", NULL, NULL, 16, 192,
+    sizeof (serpent_context_t),
+    serpent_setkey, serpent_encrypt, serpent_decrypt
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_serpent256 =
+  {
+    "SERPENT256", NULL, NULL, 16, 256,
+    sizeof (serpent_context_t),
+    serpent_setkey, serpent_encrypt, serpent_decrypt
+  };
diff --git a/grub-core/lib/libgcrypt/cipher/sha1.c b/grub-core/lib/libgcrypt/cipher/sha1.c
new file mode 100644 (file)
index 0000000..8862c64
--- /dev/null
@@ -0,0 +1,479 @@
+/* sha1.c - SHA1 hash function
+ * Copyright (C) 1998, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/*  Test vectors:
+ *
+ *  "abc"
+ *  A999 3E36 4706 816A BA3E  2571 7850 C26C 9CD0 D89D
+ *
+ *  "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ *  8498 3E44 1C3B D26E BAAE  4AA1 F951 29E5 E546 70F1
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STDINT_H 
+# include <stdint.h>
+#endif
+
+#include "g10lib.h"
+#include "memory.h"
+#include "bithelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+
+/* A macro to test whether P is properly aligned for an u32 type.
+   Note that config.h provides a suitable replacement for uintptr_t if
+   it does not exist in stdint.h.  */
+/* #if __GNUC__ >= 2 */
+/* # define U32_ALIGNED_P(p) (!(((uintptr_t)p) % __alignof__ (u32))) */
+/* #else */
+/* # define U32_ALIGNED_P(p) (!(((uintptr_t)p) % sizeof (u32))) */
+/* #endif */
+
+#define TRANSFORM(x,d,n) transform ((x), (d), (n))
+
+
+typedef struct 
+{
+  u32           h0,h1,h2,h3,h4;
+  u32           nblocks;
+  unsigned char buf[64];
+  int           count;
+} SHA1_CONTEXT;
+
+
+
+static void
+sha1_init (void *context)
+{
+  SHA1_CONTEXT *hd = context;
+
+  hd->h0 = 0x67452301;
+  hd->h1 = 0xefcdab89;
+  hd->h2 = 0x98badcfe;
+  hd->h3 = 0x10325476;
+  hd->h4 = 0xc3d2e1f0;
+  hd->nblocks = 0;
+  hd->count = 0;
+}
+
+
+/* Round function macros. */
+#define K1  0x5A827999L
+#define K2  0x6ED9EBA1L
+#define K3  0x8F1BBCDCL
+#define K4  0xCA62C1D6L
+#define F1(x,y,z)   ( z ^ ( x & ( y ^ z ) ) )
+#define F2(x,y,z)   ( x ^ y ^ z )
+#define F3(x,y,z)   ( ( x & y ) | ( z & ( x | y ) ) )
+#define F4(x,y,z)   ( x ^ y ^ z )
+#define M(i) ( tm =    x[ i    &0x0f]  \
+                     ^ x[(i-14)&0x0f]  \
+                    ^ x[(i-8) &0x0f]  \
+                     ^ x[(i-3) &0x0f], \
+                     (x[i&0x0f] = rol(tm, 1)))
+#define R(a,b,c,d,e,f,k,m)  do { e += rol( a, 5 )     \
+                                     + f( b, c, d )  \
+                                     + k             \
+                                     + m;            \
+                                b = rol( b, 30 );    \
+                              } while(0)
+
+
+/*
+ * Transform NBLOCKS of each 64 bytes (16 32-bit words) at DATA.
+ */
+static void
+transform (SHA1_CONTEXT *hd, const unsigned char *data, size_t nblocks)
+{
+  register u32 a, b, c, d, e; /* Local copies of the chaining variables.  */
+  register u32 tm;            /* Helper.  */
+  u32 x[16];                  /* The array we work on. */
+  
+  /* Loop over all blocks.  */
+  for ( ;nblocks; nblocks--)
+    {
+#ifdef WORDS_BIGENDIAN
+      memcpy (x, data, 64);
+      data += 64;
+#else
+      {
+        int i;
+        unsigned char *p;
+
+        for(i=0, p=(unsigned char*)x; i < 16; i++, p += 4 )
+          {
+            p[3] = *data++;
+            p[2] = *data++;
+            p[1] = *data++;
+            p[0] = *data++;
+          }
+      }
+#endif
+      /* Get the values of the chaining variables. */
+      a = hd->h0;
+      b = hd->h1;
+      c = hd->h2;
+      d = hd->h3;
+      e = hd->h4;
+
+      /* Transform. */
+      R( a, b, c, d, e, F1, K1, x[ 0] );
+      R( e, a, b, c, d, F1, K1, x[ 1] );
+      R( d, e, a, b, c, F1, K1, x[ 2] );
+      R( c, d, e, a, b, F1, K1, x[ 3] );
+      R( b, c, d, e, a, F1, K1, x[ 4] );
+      R( a, b, c, d, e, F1, K1, x[ 5] );
+      R( e, a, b, c, d, F1, K1, x[ 6] );
+      R( d, e, a, b, c, F1, K1, x[ 7] );
+      R( c, d, e, a, b, F1, K1, x[ 8] );
+      R( b, c, d, e, a, F1, K1, x[ 9] );
+      R( a, b, c, d, e, F1, K1, x[10] );
+      R( e, a, b, c, d, F1, K1, x[11] );
+      R( d, e, a, b, c, F1, K1, x[12] );
+      R( c, d, e, a, b, F1, K1, x[13] );
+      R( b, c, d, e, a, F1, K1, x[14] );
+      R( a, b, c, d, e, F1, K1, x[15] );
+      R( e, a, b, c, d, F1, K1, M(16) );
+      R( d, e, a, b, c, F1, K1, M(17) );
+      R( c, d, e, a, b, F1, K1, M(18) );
+      R( b, c, d, e, a, F1, K1, M(19) );
+      R( a, b, c, d, e, F2, K2, M(20) );
+      R( e, a, b, c, d, F2, K2, M(21) );
+      R( d, e, a, b, c, F2, K2, M(22) );
+      R( c, d, e, a, b, F2, K2, M(23) );
+      R( b, c, d, e, a, F2, K2, M(24) );
+      R( a, b, c, d, e, F2, K2, M(25) );
+      R( e, a, b, c, d, F2, K2, M(26) );
+      R( d, e, a, b, c, F2, K2, M(27) );
+      R( c, d, e, a, b, F2, K2, M(28) );
+      R( b, c, d, e, a, F2, K2, M(29) );
+      R( a, b, c, d, e, F2, K2, M(30) );
+      R( e, a, b, c, d, F2, K2, M(31) );
+      R( d, e, a, b, c, F2, K2, M(32) );
+      R( c, d, e, a, b, F2, K2, M(33) );
+      R( b, c, d, e, a, F2, K2, M(34) );
+      R( a, b, c, d, e, F2, K2, M(35) );
+      R( e, a, b, c, d, F2, K2, M(36) );
+      R( d, e, a, b, c, F2, K2, M(37) );
+      R( c, d, e, a, b, F2, K2, M(38) );
+      R( b, c, d, e, a, F2, K2, M(39) );
+      R( a, b, c, d, e, F3, K3, M(40) );
+      R( e, a, b, c, d, F3, K3, M(41) );
+      R( d, e, a, b, c, F3, K3, M(42) );
+      R( c, d, e, a, b, F3, K3, M(43) );
+      R( b, c, d, e, a, F3, K3, M(44) );
+      R( a, b, c, d, e, F3, K3, M(45) );
+      R( e, a, b, c, d, F3, K3, M(46) );
+      R( d, e, a, b, c, F3, K3, M(47) );
+      R( c, d, e, a, b, F3, K3, M(48) );
+      R( b, c, d, e, a, F3, K3, M(49) );
+      R( a, b, c, d, e, F3, K3, M(50) );
+      R( e, a, b, c, d, F3, K3, M(51) );
+      R( d, e, a, b, c, F3, K3, M(52) );
+      R( c, d, e, a, b, F3, K3, M(53) );
+      R( b, c, d, e, a, F3, K3, M(54) );
+      R( a, b, c, d, e, F3, K3, M(55) );
+      R( e, a, b, c, d, F3, K3, M(56) );
+      R( d, e, a, b, c, F3, K3, M(57) );
+      R( c, d, e, a, b, F3, K3, M(58) );
+      R( b, c, d, e, a, F3, K3, M(59) );
+      R( a, b, c, d, e, F4, K4, M(60) );
+      R( e, a, b, c, d, F4, K4, M(61) );
+      R( d, e, a, b, c, F4, K4, M(62) );
+      R( c, d, e, a, b, F4, K4, M(63) );
+      R( b, c, d, e, a, F4, K4, M(64) );
+      R( a, b, c, d, e, F4, K4, M(65) );
+      R( e, a, b, c, d, F4, K4, M(66) );
+      R( d, e, a, b, c, F4, K4, M(67) );
+      R( c, d, e, a, b, F4, K4, M(68) );
+      R( b, c, d, e, a, F4, K4, M(69) );
+      R( a, b, c, d, e, F4, K4, M(70) );
+      R( e, a, b, c, d, F4, K4, M(71) );
+      R( d, e, a, b, c, F4, K4, M(72) );
+      R( c, d, e, a, b, F4, K4, M(73) );
+      R( b, c, d, e, a, F4, K4, M(74) );
+      R( a, b, c, d, e, F4, K4, M(75) );
+      R( e, a, b, c, d, F4, K4, M(76) );
+      R( d, e, a, b, c, F4, K4, M(77) );
+      R( c, d, e, a, b, F4, K4, M(78) );
+      R( b, c, d, e, a, F4, K4, M(79) );
+
+      /* Update the chaining variables. */
+      hd->h0 += a;
+      hd->h1 += b;
+      hd->h2 += c;
+      hd->h3 += d;
+      hd->h4 += e;
+    }
+}
+
+
+/* Update the message digest with the contents
+ * of INBUF with length INLEN.
+ */
+static void
+sha1_write( void *context, const void *inbuf_arg, size_t inlen)
+{
+  const unsigned char *inbuf = inbuf_arg;
+  SHA1_CONTEXT *hd = context;
+  size_t nblocks;
+
+  if (hd->count == 64)  /* Flush the buffer. */
+    {
+      TRANSFORM( hd, hd->buf, 1 );
+      _gcry_burn_stack (88+4*sizeof(void*));
+      hd->count = 0;
+      hd->nblocks++;
+    }
+  if (!inbuf)
+    return;
+
+  if (hd->count)
+    {
+      for (; inlen && hd->count < 64; inlen--)
+        hd->buf[hd->count++] = *inbuf++;
+      sha1_write (hd, NULL, 0);
+      if (!inlen)
+        return;
+    }
+
+  nblocks = inlen / 64;
+  if (nblocks)
+    {
+      TRANSFORM (hd, inbuf, nblocks);
+      hd->count = 0;
+      hd->nblocks += nblocks;
+      inlen -= nblocks * 64;
+      inbuf += nblocks * 64;
+    }
+  _gcry_burn_stack (88+4*sizeof(void*));
+
+  /* Save remaining bytes.  */
+  for (; inlen && hd->count < 64; inlen--)
+    hd->buf[hd->count++] = *inbuf++;
+}
+
+
+/* The routine final terminates the computation and
+ * returns the digest.
+ * The handle is prepared for a new cycle, but adding bytes to the
+ * handle will the destroy the returned buffer.
+ * Returns: 20 bytes representing the digest.
+ */
+
+static void
+sha1_final(void *context)
+{
+  SHA1_CONTEXT *hd = context;
+  
+  u32 t, msb, lsb;
+  unsigned char *p;
+
+  sha1_write(hd, NULL, 0); /* flush */;
+
+  t = hd->nblocks;
+  /* multiply by 64 to make a byte count */
+  lsb = t << 6;
+  msb = t >> 26;
+  /* add the count */
+  t = lsb;
+  if( (lsb += hd->count) < t )
+    msb++;
+  /* multiply by 8 to make a bit count */
+  t = lsb;
+  lsb <<= 3;
+  msb <<= 3;
+  msb |= t >> 29;
+
+  if( hd->count < 56 )  /* enough room */
+    {
+      hd->buf[hd->count++] = 0x80; /* pad */
+      while( hd->count < 56 )
+        hd->buf[hd->count++] = 0;  /* pad */
+    }
+  else  /* need one extra block */
+    {
+      hd->buf[hd->count++] = 0x80; /* pad character */
+      while( hd->count < 64 )
+        hd->buf[hd->count++] = 0;
+      sha1_write(hd, NULL, 0);  /* flush */;
+      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+    }
+  /* append the 64 bit count */
+  hd->buf[56] = msb >> 24;
+  hd->buf[57] = msb >> 16;
+  hd->buf[58] = msb >>  8;
+  hd->buf[59] = msb       ;
+  hd->buf[60] = lsb >> 24;
+  hd->buf[61] = lsb >> 16;
+  hd->buf[62] = lsb >>  8;
+  hd->buf[63] = lsb       ;
+  TRANSFORM( hd, hd->buf, 1 );
+  _gcry_burn_stack (88+4*sizeof(void*));
+
+  p = hd->buf;
+#ifdef WORDS_BIGENDIAN
+#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
+#else /* little endian */
+#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;         \
+                  *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
+#endif
+  X(0);
+  X(1);
+  X(2);
+  X(3);
+  X(4);
+#undef X
+
+}
+
+static unsigned char *
+sha1_read( void *context )
+{
+  SHA1_CONTEXT *hd = context;
+
+  return hd->buf;
+}
+
+/****************
+ * Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 20 bytes.
+ */
+void
+_gcry_sha1_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+  SHA1_CONTEXT hd;
+
+  sha1_init (&hd);
+  sha1_write (&hd, buffer, length);
+  sha1_final (&hd);
+  memcpy (outbuf, hd.buf, 20);
+}
+
+
+\f
+/* 
+     Self-test section.
+ */
+
+
+static gpg_err_code_t
+selftests_sha1 (int extended, selftest_report_func_t report)
+{
+  const char *what;
+  const char *errtxt;
+  
+  what = "short string";
+  errtxt = _gcry_hash_selftest_check_one
+    (GCRY_MD_SHA1, 0, 
+     "abc", 3,
+     "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E"
+     "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D", 20);
+  if (errtxt)
+    goto failed;
+
+  if (extended)
+    {
+      what = "long string";
+      errtxt = _gcry_hash_selftest_check_one
+        (GCRY_MD_SHA1, 0, 
+         "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
+         "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE"
+         "\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1", 20);
+      if (errtxt)
+        goto failed;
+      
+      what = "one million \"a\"";
+      errtxt = _gcry_hash_selftest_check_one
+        (GCRY_MD_SHA1, 1,
+         NULL, 0,
+         "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E"
+         "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F", 20);
+      if (errtxt)
+        goto failed;
+    }
+
+  return 0; /* Succeeded. */
+
+ failed:
+  if (report)
+    report ("digest", GCRY_MD_SHA1, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Run a full self-test for ALGO and return 0 on success.  */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+  gpg_err_code_t ec;
+
+  switch (algo)
+    {
+    case GCRY_MD_SHA1:
+      ec = selftests_sha1 (extended, report);
+      break;
+    default:
+      ec = GPG_ERR_DIGEST_ALGO;
+      break;
+        
+    }
+  return ec;
+}
+
+
+
+\f
+static unsigned char asn[15] = /* Object ID is 1.3.14.3.2.26 */
+  { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
+    0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
+
+static gcry_md_oid_spec_t oid_spec_sha1[] =
+  {
+    /* iso.member-body.us.rsadsi.pkcs.pkcs-1.5 (sha1WithRSAEncryption) */
+    { "1.2.840.113549.1.1.5" },
+    /* iso.member-body.us.x9-57.x9cm.3 (dsaWithSha1)*/
+    { "1.2.840.10040.4.3" },
+    /* from NIST's OIW  (sha1) */
+    { "1.3.14.3.2.26" },
+    /* from NIST OIW (sha-1WithRSAEncryption) */
+    { "1.3.14.3.2.29" },
+    /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha1 */
+    { "1.2.840.10045.4.1" },
+    { NULL },
+  };
+
+gcry_md_spec_t _gcry_digest_spec_sha1 =
+  {
+    "SHA1", asn, DIM (asn), oid_spec_sha1, 20,
+    sha1_init, sha1_write, sha1_final, sha1_read,
+    sizeof (SHA1_CONTEXT)
+  };
+md_extra_spec_t _gcry_digest_extraspec_sha1 = 
+  {
+    run_selftests
+  };
+
diff --git a/grub-core/lib/libgcrypt/cipher/sha256.c b/grub-core/lib/libgcrypt/cipher/sha256.c
new file mode 100644 (file)
index 0000000..5d61d2f
--- /dev/null
@@ -0,0 +1,487 @@
+/* sha256.c - SHA256 hash function
+ *     Copyright (C) 2003, 2006, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/*  Test vectors:
+    
+    "abc"
+    SHA224: 23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7
+    SHA256: ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
+
+    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+    SHA224: 75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525
+    SHA256: 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
+    "a" one million times
+    SHA224: 20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67
+    SHA256: cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0
+
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "memory.h"
+#include "bithelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+typedef struct {
+  u32  h0,h1,h2,h3,h4,h5,h6,h7;
+  u32  nblocks;
+  byte buf[64];
+  int  count;
+} SHA256_CONTEXT;
+
+
+static void
+sha256_init (void *context)
+{
+  SHA256_CONTEXT *hd = context;
+
+  hd->h0 = 0x6a09e667;
+  hd->h1 = 0xbb67ae85;
+  hd->h2 = 0x3c6ef372;
+  hd->h3 = 0xa54ff53a;
+  hd->h4 = 0x510e527f;
+  hd->h5 = 0x9b05688c;
+  hd->h6 = 0x1f83d9ab;
+  hd->h7 = 0x5be0cd19;
+
+  hd->nblocks = 0;
+  hd->count = 0;
+}
+
+
+static void
+sha224_init (void *context)
+{
+  SHA256_CONTEXT *hd = context;
+
+  hd->h0 = 0xc1059ed8;
+  hd->h1 = 0x367cd507;
+  hd->h2 = 0x3070dd17;
+  hd->h3 = 0xf70e5939;
+  hd->h4 = 0xffc00b31;
+  hd->h5 = 0x68581511;
+  hd->h6 = 0x64f98fa7;
+  hd->h7 = 0xbefa4fa4;
+
+  hd->nblocks = 0;
+  hd->count = 0;
+}
+
+
+/*
+  Transform the message X which consists of 16 32-bit-words. See FIPS
+  180-2 for details.  */
+#define Cho(x,y,z) (z ^ (x & (y ^ z)))      /* (4.2) same as SHA-1's F1 */
+#define Maj(x,y,z) ((x & y) | (z & (x|y)))  /* (4.3) same as SHA-1's F3 */
+#define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22))  /* (4.4) */
+#define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25))  /* (4.5) */
+#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3))       /* (4.6) */
+#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10))     /* (4.7) */
+#define R(a,b,c,d,e,f,g,h,k,w) do                                 \
+          {                                                       \
+            t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w);  \
+            t2 = Sum0((a)) + Maj((a),(b),(c));                    \
+            h = g;                                                \
+            g = f;                                                \
+            f = e;                                                \
+            e = d + t1;                                           \
+            d = c;                                                \
+            c = b;                                                \
+            b = a;                                                \
+            a = t1 + t2;                                          \
+          } while (0)
+static void
+transform (SHA256_CONTEXT *hd, const unsigned char *data)
+{
+  static const u32 K[64] = {
+    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 
+    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+  };
+
+  u32 a,b,c,d,e,f,g,h,t1,t2;
+  u32 x[16];
+  u32 w[64];
+  int i;
+  
+  a = hd->h0;
+  b = hd->h1;
+  c = hd->h2;
+  d = hd->h3;
+  e = hd->h4;
+  f = hd->h5;
+  g = hd->h6;
+  h = hd->h7;
+  
+#ifdef WORDS_BIGENDIAN
+  memcpy (x, data, 64);
+#else
+  { 
+    byte *p2;
+  
+    for (i=0, p2=(byte*)x; i < 16; i++, p2 += 4 ) 
+      {
+        p2[3] = *data++;
+        p2[2] = *data++;
+        p2[1] = *data++;
+        p2[0] = *data++;
+      }
+  }
+#endif
+
+  for (i=0; i < 16; i++)
+    w[i] = x[i];
+  for (; i < 64; i++)
+    w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
+
+  for (i=0; i < 64; i++)
+    R(a,b,c,d,e,f,g,h,K[i],w[i]);
+
+  hd->h0 += a;
+  hd->h1 += b;
+  hd->h2 += c;
+  hd->h3 += d;
+  hd->h4 += e;
+  hd->h5 += f;
+  hd->h6 += g;
+  hd->h7 += h;
+}
+#undef Cho
+#undef Maj
+#undef Sum0
+#undef Sum1
+#undef S0
+#undef S1
+#undef R
+
+
+/* Update the message digest with the contents of INBUF with length
+  INLEN.  */
+static void
+sha256_write (void *context, const void *inbuf_arg, size_t inlen)
+{
+  const unsigned char *inbuf = inbuf_arg;
+  SHA256_CONTEXT *hd = context;
+
+  if (hd->count == 64)
+    { /* flush the buffer */
+      transform (hd, hd->buf);
+      _gcry_burn_stack (74*4+32);
+      hd->count = 0;
+      hd->nblocks++;
+    }
+  if (!inbuf)
+    return;
+  if (hd->count)
+    {
+      for (; inlen && hd->count < 64; inlen--)
+        hd->buf[hd->count++] = *inbuf++;
+      sha256_write (hd, NULL, 0);
+      if (!inlen)
+        return;
+    }
+
+  while (inlen >= 64)
+    {
+      transform (hd, inbuf);
+      hd->count = 0;
+      hd->nblocks++;
+      inlen -= 64;
+      inbuf += 64;
+    }
+  _gcry_burn_stack (74*4+32);
+  for (; inlen && hd->count < 64; inlen--)
+    hd->buf[hd->count++] = *inbuf++;
+}
+
+
+/*
+   The routine finally terminates the computation and returns the
+   digest.  The handle is prepared for a new cycle, but adding bytes
+   to the handle will the destroy the returned buffer.  Returns: 32
+   bytes with the message the digest.  */
+static void
+sha256_final(void *context)
+{
+  SHA256_CONTEXT *hd = context;
+  u32 t, msb, lsb;
+  byte *p;
+  
+  sha256_write (hd, NULL, 0); /* flush */;
+
+  t = hd->nblocks;
+  /* multiply by 64 to make a byte count */
+  lsb = t << 6;
+  msb = t >> 26;
+  /* add the count */
+  t = lsb;
+  if ((lsb += hd->count) < t)
+    msb++;
+  /* multiply by 8 to make a bit count */
+  t = lsb;
+  lsb <<= 3;
+  msb <<= 3;
+  msb |= t >> 29;
+
+  if (hd->count < 56)
+    { /* enough room */
+      hd->buf[hd->count++] = 0x80; /* pad */
+      while (hd->count < 56)
+        hd->buf[hd->count++] = 0;  /* pad */
+    }
+  else
+    { /* need one extra block */
+      hd->buf[hd->count++] = 0x80; /* pad character */
+      while (hd->count < 64)
+        hd->buf[hd->count++] = 0;
+      sha256_write (hd, NULL, 0);  /* flush */;
+      memset (hd->buf, 0, 56 ); /* fill next block with zeroes */
+    }
+  /* append the 64 bit count */
+  hd->buf[56] = msb >> 24;
+  hd->buf[57] = msb >> 16;
+  hd->buf[58] = msb >>  8;
+  hd->buf[59] = msb;
+  hd->buf[60] = lsb >> 24;
+  hd->buf[61] = lsb >> 16;
+  hd->buf[62] = lsb >>  8;
+  hd->buf[63] = lsb;
+  transform (hd, hd->buf);
+  _gcry_burn_stack (74*4+32);
+
+  p = hd->buf;
+#ifdef WORDS_BIGENDIAN
+#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
+#else /* little endian */
+#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;         \
+                 *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
+#endif
+  X(0);
+  X(1);
+  X(2);
+  X(3);
+  X(4);
+  X(5);
+  X(6);
+  X(7);
+#undef X
+}
+
+static byte *
+sha256_read (void *context)
+{
+  SHA256_CONTEXT *hd = context;
+
+  return hd->buf;
+}
+
+
+\f
+/* 
+     Self-test section.
+ */
+
+
+static gpg_err_code_t
+selftests_sha224 (int extended, selftest_report_func_t report)
+{
+  const char *what;
+  const char *errtxt;
+  
+  what = "short string";
+  errtxt = _gcry_hash_selftest_check_one
+    (GCRY_MD_SHA224, 0, 
+     "abc", 3,
+     "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3"
+     "\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7", 28);
+  if (errtxt)
+    goto failed;
+
+  if (extended)
+    {
+      what = "long string";
+      errtxt = _gcry_hash_selftest_check_one
+        (GCRY_MD_SHA224, 0, 
+         "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
+         "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50"
+         "\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25", 28);
+      if (errtxt)
+        goto failed;
+      
+      what = "one million \"a\"";
+      errtxt = _gcry_hash_selftest_check_one
+        (GCRY_MD_SHA224, 1,
+         NULL, 0,
+         "\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b"
+         "\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67", 28);
+      if (errtxt)
+        goto failed;
+    }
+
+  return 0; /* Succeeded. */
+
+ failed:
+  if (report)
+    report ("digest", GCRY_MD_SHA224, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+static gpg_err_code_t
+selftests_sha256 (int extended, selftest_report_func_t report)
+{
+  const char *what;
+  const char *errtxt;
+  
+  what = "short string";
+  errtxt = _gcry_hash_selftest_check_one
+    (GCRY_MD_SHA256, 0, 
+     "abc", 3,
+     "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23"
+     "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad", 32);
+  if (errtxt)
+    goto failed;
+
+  if (extended)
+    {
+      what = "long string";
+      errtxt = _gcry_hash_selftest_check_one
+        (GCRY_MD_SHA256, 0, 
+         "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
+         "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
+         "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1",
+         32);
+      if (errtxt)
+        goto failed;
+      
+      what = "one million \"a\"";
+      errtxt = _gcry_hash_selftest_check_one
+        (GCRY_MD_SHA256, 1,
+         NULL, 0,
+         "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
+         "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0",
+         32);
+      if (errtxt)
+        goto failed;
+    }
+
+  return 0; /* Succeeded. */
+
+ failed:
+  if (report)
+    report ("digest", GCRY_MD_SHA256, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Run a full self-test for ALGO and return 0 on success.  */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+  gpg_err_code_t ec;
+
+  switch (algo)
+    {
+    case GCRY_MD_SHA224:
+      ec = selftests_sha224 (extended, report);
+      break;
+    case GCRY_MD_SHA256:
+      ec = selftests_sha256 (extended, report);
+      break;
+    default:
+      ec = GPG_ERR_DIGEST_ALGO;
+      break;
+        
+    }
+  return ec;
+}
+
+
+
+\f
+static byte asn224[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */
+  { 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+    0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
+    0x1C
+  };
+
+static gcry_md_oid_spec_t oid_spec_sha224[] =
+  {
+    /* From RFC3874, Section 4 */
+    { "2.16.840.1.101.3.4.2.4" }, 
+    { NULL },
+  };
+
+static byte asn256[19] = /* Object ID is  2.16.840.1.101.3.4.2.1 */
+  { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+    0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+    0x00, 0x04, 0x20 };
+
+static gcry_md_oid_spec_t oid_spec_sha256[] =
+  {
+    /* According to the OpenPGP draft rfc2440-bis06 */
+    { "2.16.840.1.101.3.4.2.1" }, 
+    /* PKCS#1 sha256WithRSAEncryption */
+    { "1.2.840.113549.1.1.11" },
+
+    { NULL },
+  };
+
+gcry_md_spec_t _gcry_digest_spec_sha224 =
+  {
+    "SHA224", asn224, DIM (asn224), oid_spec_sha224, 28,
+    sha224_init, sha256_write, sha256_final, sha256_read,
+    sizeof (SHA256_CONTEXT)
+  };
+md_extra_spec_t _gcry_digest_extraspec_sha224 = 
+  {
+    run_selftests
+  };
+
+gcry_md_spec_t _gcry_digest_spec_sha256 =
+  {
+    "SHA256", asn256, DIM (asn256), oid_spec_sha256, 32,
+    sha256_init, sha256_write, sha256_final, sha256_read,
+    sizeof (SHA256_CONTEXT)
+  };
+md_extra_spec_t _gcry_digest_extraspec_sha256 = 
+  {
+    run_selftests
+  };
diff --git a/grub-core/lib/libgcrypt/cipher/sha512.c b/grub-core/lib/libgcrypt/cipher/sha512.c
new file mode 100644 (file)
index 0000000..bbbd4c5
--- /dev/null
@@ -0,0 +1,553 @@
+/* sha512.c - SHA384 and SHA512 hash functions
+ *     Copyright (C) 2003, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/*  Test vectors from FIPS-180-2:
+ *
+ *  "abc"
+ * 384:
+ *  CB00753F 45A35E8B B5A03D69 9AC65007 272C32AB 0EDED163
+ *  1A8B605A 43FF5BED 8086072B A1E7CC23 58BAECA1 34C825A7
+ * 512:
+ *  DDAF35A1 93617ABA CC417349 AE204131 12E6FA4E 89A97EA2 0A9EEEE6 4B55D39A
+ *  2192992A 274FC1A8 36BA3C23 A3FEEBBD 454D4423 643CE80E 2A9AC94F A54CA49F
+ *
+ *  "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
+ * 384:
+ *  09330C33 F71147E8 3D192FC7 82CD1B47 53111B17 3B3B05D2
+ *  2FA08086 E3B0F712 FCC7C71A 557E2DB9 66C3E9FA 91746039
+ * 512:
+ *  8E959B75 DAE313DA 8CF4F728 14FC143F 8F7779C6 EB9F7FA1 7299AEAD B6889018
+ *  501D289E 4900F7E4 331B99DE C4B5433A C7D329EE B6DD2654 5E96E55B 874BE909
+ *
+ *  "a" x 1000000
+ * 384:
+ *  9D0E1809 716474CB 086E834E 310A4A1C ED149E9C 00F24852
+ *  7972CEC5 704C2A5B 07B8B3DC 38ECC4EB AE97DDD8 7F3D8985
+ * 512:
+ *  E718483D 0CE76964 4E2E42C7 BC15B463 8E1F98B1 3B204428 5632A803 AFA973EB
+ *  DE0FF244 877EA60A 4CB0432C E577C31B EB009C5C 2C49AA2E 4EADB217 AD8CC09B
+ */
+
+
+#include <config.h>
+#include <string.h>
+#include "g10lib.h"
+#include "bithelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+typedef struct
+{
+  u64 h0, h1, h2, h3, h4, h5, h6, h7;
+  u64 nblocks;
+  byte buf[128];
+  int count;
+} SHA512_CONTEXT;
+
+static void
+sha512_init (void *context)
+{
+  SHA512_CONTEXT *hd = context;
+
+  hd->h0 = U64_C(0x6a09e667f3bcc908);
+  hd->h1 = U64_C(0xbb67ae8584caa73b);
+  hd->h2 = U64_C(0x3c6ef372fe94f82b);
+  hd->h3 = U64_C(0xa54ff53a5f1d36f1);
+  hd->h4 = U64_C(0x510e527fade682d1);
+  hd->h5 = U64_C(0x9b05688c2b3e6c1f);
+  hd->h6 = U64_C(0x1f83d9abfb41bd6b);
+  hd->h7 = U64_C(0x5be0cd19137e2179);
+
+  hd->nblocks = 0;
+  hd->count = 0;
+}
+
+static void
+sha384_init (void *context)
+{
+  SHA512_CONTEXT *hd = context;
+
+  hd->h0 = U64_C(0xcbbb9d5dc1059ed8);
+  hd->h1 = U64_C(0x629a292a367cd507);
+  hd->h2 = U64_C(0x9159015a3070dd17);
+  hd->h3 = U64_C(0x152fecd8f70e5939);
+  hd->h4 = U64_C(0x67332667ffc00b31);
+  hd->h5 = U64_C(0x8eb44a8768581511);
+  hd->h6 = U64_C(0xdb0c2e0d64f98fa7);
+  hd->h7 = U64_C(0x47b5481dbefa4fa4);
+
+  hd->nblocks = 0;
+  hd->count = 0;
+}
+
+
+/****************
+ * Transform the message W which consists of 16 64-bit-words
+ */
+static void
+transform (SHA512_CONTEXT *hd, const unsigned char *data)
+{
+  u64 a, b, c, d, e, f, g, h;
+  u64 w[80];
+  int t;
+  static const u64 k[] =
+    {
+      U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd),
+      U64_C(0xb5c0fbcfec4d3b2f), U64_C(0xe9b5dba58189dbbc),
+      U64_C(0x3956c25bf348b538), U64_C(0x59f111f1b605d019),
+      U64_C(0x923f82a4af194f9b), U64_C(0xab1c5ed5da6d8118),
+      U64_C(0xd807aa98a3030242), U64_C(0x12835b0145706fbe),
+      U64_C(0x243185be4ee4b28c), U64_C(0x550c7dc3d5ffb4e2),
+      U64_C(0x72be5d74f27b896f), U64_C(0x80deb1fe3b1696b1),
+      U64_C(0x9bdc06a725c71235), U64_C(0xc19bf174cf692694),
+      U64_C(0xe49b69c19ef14ad2), U64_C(0xefbe4786384f25e3),
+      U64_C(0x0fc19dc68b8cd5b5), U64_C(0x240ca1cc77ac9c65),
+      U64_C(0x2de92c6f592b0275), U64_C(0x4a7484aa6ea6e483),
+      U64_C(0x5cb0a9dcbd41fbd4), U64_C(0x76f988da831153b5),
+      U64_C(0x983e5152ee66dfab), U64_C(0xa831c66d2db43210),
+      U64_C(0xb00327c898fb213f), U64_C(0xbf597fc7beef0ee4),
+      U64_C(0xc6e00bf33da88fc2), U64_C(0xd5a79147930aa725),
+      U64_C(0x06ca6351e003826f), U64_C(0x142929670a0e6e70),
+      U64_C(0x27b70a8546d22ffc), U64_C(0x2e1b21385c26c926),
+      U64_C(0x4d2c6dfc5ac42aed), U64_C(0x53380d139d95b3df),
+      U64_C(0x650a73548baf63de), U64_C(0x766a0abb3c77b2a8),
+      U64_C(0x81c2c92e47edaee6), U64_C(0x92722c851482353b),
+      U64_C(0xa2bfe8a14cf10364), U64_C(0xa81a664bbc423001),
+      U64_C(0xc24b8b70d0f89791), U64_C(0xc76c51a30654be30),
+      U64_C(0xd192e819d6ef5218), U64_C(0xd69906245565a910),
+      U64_C(0xf40e35855771202a), U64_C(0x106aa07032bbd1b8),
+      U64_C(0x19a4c116b8d2d0c8), U64_C(0x1e376c085141ab53),
+      U64_C(0x2748774cdf8eeb99), U64_C(0x34b0bcb5e19b48a8),
+      U64_C(0x391c0cb3c5c95a63), U64_C(0x4ed8aa4ae3418acb),
+      U64_C(0x5b9cca4f7763e373), U64_C(0x682e6ff3d6b2b8a3),
+      U64_C(0x748f82ee5defb2fc), U64_C(0x78a5636f43172f60),
+      U64_C(0x84c87814a1f0ab72), U64_C(0x8cc702081a6439ec),
+      U64_C(0x90befffa23631e28), U64_C(0xa4506cebde82bde9),
+      U64_C(0xbef9a3f7b2c67915), U64_C(0xc67178f2e372532b),
+      U64_C(0xca273eceea26619c), U64_C(0xd186b8c721c0c207),
+      U64_C(0xeada7dd6cde0eb1e), U64_C(0xf57d4f7fee6ed178),
+      U64_C(0x06f067aa72176fba), U64_C(0x0a637dc5a2c898a6),
+      U64_C(0x113f9804bef90dae), U64_C(0x1b710b35131c471b),
+      U64_C(0x28db77f523047d84), U64_C(0x32caab7b40c72493),
+      U64_C(0x3c9ebe0a15c9bebc), U64_C(0x431d67c49c100d4c),
+      U64_C(0x4cc5d4becb3e42b6), U64_C(0x597f299cfc657e2a),
+      U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817)
+    };
+
+  /* get values from the chaining vars */
+  a = hd->h0;
+  b = hd->h1;
+  c = hd->h2;
+  d = hd->h3;
+  e = hd->h4;
+  f = hd->h5;
+  g = hd->h6;
+  h = hd->h7;
+
+#ifdef WORDS_BIGENDIAN
+  memcpy (w, data, 128);
+#else
+  {
+    int i;
+    byte *p2;
+
+    for (i = 0, p2 = (byte *) w; i < 16; i++, p2 += 8)
+      {
+       p2[7] = *data++;
+       p2[6] = *data++;
+       p2[5] = *data++;
+       p2[4] = *data++;
+       p2[3] = *data++;
+       p2[2] = *data++;
+       p2[1] = *data++;
+       p2[0] = *data++;
+      }
+  }
+#endif
+
+#define ROTR(x,n) (((x)>>(n)) | ((x)<<(64-(n))))
+#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+#define Sum0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
+#define Sum1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
+#define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
+#define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
+
+  for (t = 16; t < 80; t++)
+    w[t] = S1 (w[t - 2]) + w[t - 7] + S0 (w[t - 15]) + w[t - 16];
+
+  for (t = 0; t < 80; t++)
+    {
+      u64 t1, t2;
+
+      t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t];
+      t2 = Sum0 (a) + Maj (a, b, c);
+      h = g;
+      g = f;
+      f = e;
+      e = d + t1;
+      d = c;
+      c = b;
+      b = a;
+      a = t1 + t2;
+
+      /* printf("t=%d a=%016llX b=%016llX c=%016llX d=%016llX "
+          "e=%016llX f=%016llX g=%016llX h=%016llX\n",t,a,b,c,d,e,f,g,h); */
+    }
+
+  /* update chaining vars */
+  hd->h0 += a;
+  hd->h1 += b;
+  hd->h2 += c;
+  hd->h3 += d;
+  hd->h4 += e;
+  hd->h5 += f;
+  hd->h6 += g;
+  hd->h7 += h;
+}
+
+
+/* Update the message digest with the contents
+ * of INBUF with length INLEN.
+ */
+static void
+sha512_write (void *context, const void *inbuf_arg, size_t inlen)
+{
+  const unsigned char *inbuf = inbuf_arg;
+  SHA512_CONTEXT *hd = context;
+
+  if (hd->count == 128)
+    {                          /* flush the buffer */
+      transform (hd, hd->buf);
+      _gcry_burn_stack (768);
+      hd->count = 0;
+      hd->nblocks++;
+    }
+  if (!inbuf)
+    return;
+  if (hd->count)
+    {
+      for (; inlen && hd->count < 128; inlen--)
+       hd->buf[hd->count++] = *inbuf++;
+      sha512_write (context, NULL, 0);
+      if (!inlen)
+       return;
+    }
+
+  while (inlen >= 128)
+    {
+      transform (hd, inbuf);
+      hd->count = 0;
+      hd->nblocks++;
+      inlen -= 128;
+      inbuf += 128;
+    }
+  _gcry_burn_stack (768);
+  for (; inlen && hd->count < 128; inlen--)
+    hd->buf[hd->count++] = *inbuf++;
+}
+
+
+/* The routine final terminates the computation and
+ * returns the digest.
+ * The handle is prepared for a new cycle, but adding bytes to the
+ * handle will the destroy the returned buffer.
+ * Returns: 64 bytes representing the digest.  When used for sha384,
+ * we take the leftmost 48 of those bytes.
+ */
+
+static void
+sha512_final (void *context)
+{
+  SHA512_CONTEXT *hd = context;
+  u64 t, msb, lsb;
+  byte *p;
+
+  sha512_write (context, NULL, 0); /* flush */ ;
+
+  t = hd->nblocks;
+  /* multiply by 128 to make a byte count */
+  lsb = t << 7;
+  msb = t >> 57;
+  /* add the count */
+  t = lsb;
+  if ((lsb += hd->count) < t)
+    msb++;
+  /* multiply by 8 to make a bit count */
+  t = lsb;
+  lsb <<= 3;
+  msb <<= 3;
+  msb |= t >> 61;
+
+  if (hd->count < 112)
+    {                          /* enough room */
+      hd->buf[hd->count++] = 0x80;     /* pad */
+      while (hd->count < 112)
+       hd->buf[hd->count++] = 0;       /* pad */
+    }
+  else
+    {                          /* need one extra block */
+      hd->buf[hd->count++] = 0x80;     /* pad character */
+      while (hd->count < 128)
+       hd->buf[hd->count++] = 0;
+      sha512_write (context, NULL, 0); /* flush */ ;
+      memset (hd->buf, 0, 112);        /* fill next block with zeroes */
+    }
+  /* append the 128 bit count */
+  hd->buf[112] = msb >> 56;
+  hd->buf[113] = msb >> 48;
+  hd->buf[114] = msb >> 40;
+  hd->buf[115] = msb >> 32;
+  hd->buf[116] = msb >> 24;
+  hd->buf[117] = msb >> 16;
+  hd->buf[118] = msb >> 8;
+  hd->buf[119] = msb;
+
+  hd->buf[120] = lsb >> 56;
+  hd->buf[121] = lsb >> 48;
+  hd->buf[122] = lsb >> 40;
+  hd->buf[123] = lsb >> 32;
+  hd->buf[124] = lsb >> 24;
+  hd->buf[125] = lsb >> 16;
+  hd->buf[126] = lsb >> 8;
+  hd->buf[127] = lsb;
+  transform (hd, hd->buf);
+  _gcry_burn_stack (768);
+
+  p = hd->buf;
+#ifdef WORDS_BIGENDIAN
+#define X(a) do { *(u64*)p = hd->h##a ; p += 8; } while (0)
+#else /* little endian */
+#define X(a) do { *p++ = hd->h##a >> 56; *p++ = hd->h##a >> 48;              \
+                  *p++ = hd->h##a >> 40; *p++ = hd->h##a >> 32;              \
+                  *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;              \
+                  *p++ = hd->h##a >> 8;  *p++ = hd->h##a; } while (0)
+#endif
+  X (0);
+  X (1);
+  X (2);
+  X (3);
+  X (4);
+  X (5);
+  /* Note that these last two chunks are included even for SHA384.
+     We just ignore them. */
+  X (6);
+  X (7);
+#undef X
+}
+
+static byte *
+sha512_read (void *context)
+{
+  SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context;
+  return hd->buf;
+}
+
+
+\f
+/* 
+     Self-test section.
+ */
+
+
+static gpg_err_code_t
+selftests_sha384 (int extended, selftest_report_func_t report)
+{
+  const char *what;
+  const char *errtxt;
+  
+  what = "short string";
+  errtxt = _gcry_hash_selftest_check_one
+    (GCRY_MD_SHA384, 0, 
+     "abc", 3,
+     "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07"
+     "\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed"
+     "\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7", 48);
+  if (errtxt)
+    goto failed;
+
+  if (extended)
+    {
+      what = "long string";
+      errtxt = _gcry_hash_selftest_check_one
+        (GCRY_MD_SHA384, 0, 
+         "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+         "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, 
+         "\x09\x33\x0C\x33\xF7\x11\x47\xE8\x3D\x19\x2F\xC7\x82\xCD\x1B\x47"
+         "\x53\x11\x1B\x17\x3B\x3B\x05\xD2\x2F\xA0\x80\x86\xE3\xB0\xF7\x12"
+         "\xFC\xC7\xC7\x1A\x55\x7E\x2D\xB9\x66\xC3\xE9\xFA\x91\x74\x60\x39",
+         48);
+      if (errtxt)
+        goto failed;
+
+      what = "one million \"a\"";
+      errtxt = _gcry_hash_selftest_check_one
+        (GCRY_MD_SHA384, 1,
+         NULL, 0,
+         "\x9D\x0E\x18\x09\x71\x64\x74\xCB\x08\x6E\x83\x4E\x31\x0A\x4A\x1C"
+         "\xED\x14\x9E\x9C\x00\xF2\x48\x52\x79\x72\xCE\xC5\x70\x4C\x2A\x5B"
+         "\x07\xB8\xB3\xDC\x38\xEC\xC4\xEB\xAE\x97\xDD\xD8\x7F\x3D\x89\x85",
+         48);
+      if (errtxt)
+        goto failed;
+    }
+
+  return 0; /* Succeeded. */
+
+ failed:
+  if (report)
+    report ("digest", GCRY_MD_SHA384, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+static gpg_err_code_t
+selftests_sha512 (int extended, selftest_report_func_t report)
+{
+  const char *what;
+  const char *errtxt;
+  
+  what = "short string";
+  errtxt = _gcry_hash_selftest_check_one
+    (GCRY_MD_SHA512, 0, 
+     "abc", 3,
+     "\xDD\xAF\x35\xA1\x93\x61\x7A\xBA\xCC\x41\x73\x49\xAE\x20\x41\x31"
+     "\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A"
+     "\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD"
+     "\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F", 64);
+  if (errtxt)
+    goto failed;
+
+  if (extended)
+    {
+      what = "long string";
+      errtxt = _gcry_hash_selftest_check_one
+        (GCRY_MD_SHA512, 0, 
+         "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+         "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, 
+         "\x8E\x95\x9B\x75\xDA\xE3\x13\xDA\x8C\xF4\xF7\x28\x14\xFC\x14\x3F"
+         "\x8F\x77\x79\xC6\xEB\x9F\x7F\xA1\x72\x99\xAE\xAD\xB6\x88\x90\x18"
+         "\x50\x1D\x28\x9E\x49\x00\xF7\xE4\x33\x1B\x99\xDE\xC4\xB5\x43\x3A"
+         "\xC7\xD3\x29\xEE\xB6\xDD\x26\x54\x5E\x96\xE5\x5B\x87\x4B\xE9\x09",
+         64);
+      if (errtxt)
+        goto failed;
+      
+      what = "one million \"a\"";
+      errtxt = _gcry_hash_selftest_check_one
+        (GCRY_MD_SHA512, 1,
+         NULL, 0,
+         "\xE7\x18\x48\x3D\x0C\xE7\x69\x64\x4E\x2E\x42\xC7\xBC\x15\xB4\x63"
+         "\x8E\x1F\x98\xB1\x3B\x20\x44\x28\x56\x32\xA8\x03\xAF\xA9\x73\xEB"
+         "\xDE\x0F\xF2\x44\x87\x7E\xA6\x0A\x4C\xB0\x43\x2C\xE5\x77\xC3\x1B"
+         "\xEB\x00\x9C\x5C\x2C\x49\xAA\x2E\x4E\xAD\xB2\x17\xAD\x8C\xC0\x9B",
+         64);
+      if (errtxt)
+        goto failed;
+    }
+
+  return 0; /* Succeeded. */
+
+ failed:
+  if (report)
+    report ("digest", GCRY_MD_SHA512, what, errtxt);
+  return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Run a full self-test for ALGO and return 0 on success.  */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+  gpg_err_code_t ec;
+
+  switch (algo)
+    {
+    case GCRY_MD_SHA384:
+      ec = selftests_sha384 (extended, report);
+      break;
+    case GCRY_MD_SHA512:
+      ec = selftests_sha512 (extended, report);
+      break;
+    default:
+      ec = GPG_ERR_DIGEST_ALGO;
+      break;
+        
+    }
+  return ec;
+}
+
+
+
+\f
+static byte sha512_asn[] =     /* Object ID is 2.16.840.1.101.3.4.2.3 */
+  {
+    0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+    0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
+    0x00, 0x04, 0x40
+  };
+
+static gcry_md_oid_spec_t oid_spec_sha512[] =
+  {
+    { "2.16.840.1.101.3.4.2.3" },
+
+    /* PKCS#1 sha512WithRSAEncryption */
+    { "1.2.840.113549.1.1.13" },
+
+    { NULL }
+  };
+
+gcry_md_spec_t _gcry_digest_spec_sha512 = 
+  {
+    "SHA512", sha512_asn, DIM (sha512_asn), oid_spec_sha512, 64,
+    sha512_init, sha512_write, sha512_final, sha512_read,
+    sizeof (SHA512_CONTEXT),
+  };
+md_extra_spec_t _gcry_digest_extraspec_sha512 = 
+  {
+    run_selftests
+  };
+
+static byte sha384_asn[] =     /* Object ID is 2.16.840.1.101.3.4.2.2 */
+  {
+    0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+    0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
+    0x00, 0x04, 0x30
+  };
+
+static gcry_md_oid_spec_t oid_spec_sha384[] =
+  {
+    { "2.16.840.1.101.3.4.2.2" }, 
+
+    /* PKCS#1 sha384WithRSAEncryption */
+    { "1.2.840.113549.1.1.12" },
+
+    { NULL },
+  };
+
+gcry_md_spec_t _gcry_digest_spec_sha384 = 
+  {
+    "SHA384", sha384_asn, DIM (sha384_asn), oid_spec_sha384, 48,
+    sha384_init, sha512_write, sha512_final, sha512_read,
+    sizeof (SHA512_CONTEXT),
+  };
+md_extra_spec_t _gcry_digest_extraspec_sha384 = 
+  {
+    run_selftests
+  };
diff --git a/grub-core/lib/libgcrypt/cipher/tiger.c b/grub-core/lib/libgcrypt/cipher/tiger.c
new file mode 100644 (file)
index 0000000..a620045
--- /dev/null
@@ -0,0 +1,851 @@
+/* tiger.c  -  The TIGER hash function
+ *     Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "memory.h"
+#include "cipher.h"
+
+#ifdef HAVE_U64_TYPEDEF
+
+/* we really need it here, but as this is only experiment we
+ * can live without Tiger */
+
+typedef struct {
+    u64  a, b, c;
+    byte buf[64];
+    int  count;
+    u32  nblocks;
+} TIGER_CONTEXT;
+
+
+/*********************************
+ * Okay, okay, this is not the fastest code - improvements are welcome.
+ *
+ */
+
+/* Some test vectors:
+ * ""                   24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A
+ * "abc"                F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951
+ * "Tiger"              9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF
+ * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"
+ *                     87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386
+ * "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789"
+ *                     467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197
+ * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham"
+ *                     0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303
+ * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proc"
+ * "eedings of Fast Software Encryption 3, Cambridge."
+ *                     EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193
+ * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proc"
+ * "eedings of Fast Software Encryption 3, Cambridge, 1996."
+ *                     3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC
+ * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEF"
+ * "GHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"
+ *                     00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4
+ */
+
+static u64 sbox1[256] = {
+  U64_C(0x02aab17cf7e90c5e) /*    0 */, U64_C(0xac424b03e243a8ec) /*    1 */,
+  U64_C(0x72cd5be30dd5fcd3) /*    2 */, U64_C(0x6d019b93f6f97f3a) /*    3 */,
+  U64_C(0xcd9978ffd21f9193) /*    4 */, U64_C(0x7573a1c9708029e2) /*    5 */,
+  U64_C(0xb164326b922a83c3) /*    6 */, U64_C(0x46883eee04915870) /*    7 */,
+  U64_C(0xeaace3057103ece6) /*    8 */, U64_C(0xc54169b808a3535c) /*    9 */,
+  U64_C(0x4ce754918ddec47c) /*   10 */, U64_C(0x0aa2f4dfdc0df40c) /*   11 */,
+  U64_C(0x10b76f18a74dbefa) /*   12 */, U64_C(0xc6ccb6235ad1ab6a) /*   13 */,
+  U64_C(0x13726121572fe2ff) /*   14 */, U64_C(0x1a488c6f199d921e) /*   15 */,
+  U64_C(0x4bc9f9f4da0007ca) /*   16 */, U64_C(0x26f5e6f6e85241c7) /*   17 */,
+  U64_C(0x859079dbea5947b6) /*   18 */, U64_C(0x4f1885c5c99e8c92) /*   19 */,
+  U64_C(0xd78e761ea96f864b) /*   20 */, U64_C(0x8e36428c52b5c17d) /*   21 */,
+  U64_C(0x69cf6827373063c1) /*   22 */, U64_C(0xb607c93d9bb4c56e) /*   23 */,
+  U64_C(0x7d820e760e76b5ea) /*   24 */, U64_C(0x645c9cc6f07fdc42) /*   25 */,
+  U64_C(0xbf38a078243342e0) /*   26 */, U64_C(0x5f6b343c9d2e7d04) /*   27 */,
+  U64_C(0xf2c28aeb600b0ec6) /*   28 */, U64_C(0x6c0ed85f7254bcac) /*   29 */,
+  U64_C(0x71592281a4db4fe5) /*   30 */, U64_C(0x1967fa69ce0fed9f) /*   31 */,
+  U64_C(0xfd5293f8b96545db) /*   32 */, U64_C(0xc879e9d7f2a7600b) /*   33 */,
+  U64_C(0x860248920193194e) /*   34 */, U64_C(0xa4f9533b2d9cc0b3) /*   35 */,
+  U64_C(0x9053836c15957613) /*   36 */, U64_C(0xdb6dcf8afc357bf1) /*   37 */,
+  U64_C(0x18beea7a7a370f57) /*   38 */, U64_C(0x037117ca50b99066) /*   39 */,
+  U64_C(0x6ab30a9774424a35) /*   40 */, U64_C(0xf4e92f02e325249b) /*   41 */,
+  U64_C(0x7739db07061ccae1) /*   42 */, U64_C(0xd8f3b49ceca42a05) /*   43 */,
+  U64_C(0xbd56be3f51382f73) /*   44 */, U64_C(0x45faed5843b0bb28) /*   45 */,
+  U64_C(0x1c813d5c11bf1f83) /*   46 */, U64_C(0x8af0e4b6d75fa169) /*   47 */,
+  U64_C(0x33ee18a487ad9999) /*   48 */, U64_C(0x3c26e8eab1c94410) /*   49 */,
+  U64_C(0xb510102bc0a822f9) /*   50 */, U64_C(0x141eef310ce6123b) /*   51 */,
+  U64_C(0xfc65b90059ddb154) /*   52 */, U64_C(0xe0158640c5e0e607) /*   53 */,
+  U64_C(0x884e079826c3a3cf) /*   54 */, U64_C(0x930d0d9523c535fd) /*   55 */,
+  U64_C(0x35638d754e9a2b00) /*   56 */, U64_C(0x4085fccf40469dd5) /*   57 */,
+  U64_C(0xc4b17ad28be23a4c) /*   58 */, U64_C(0xcab2f0fc6a3e6a2e) /*   59 */,
+  U64_C(0x2860971a6b943fcd) /*   60 */, U64_C(0x3dde6ee212e30446) /*   61 */,
+  U64_C(0x6222f32ae01765ae) /*   62 */, U64_C(0x5d550bb5478308fe) /*   63 */,
+  U64_C(0xa9efa98da0eda22a) /*   64 */, U64_C(0xc351a71686c40da7) /*   65 */,
+  U64_C(0x1105586d9c867c84) /*   66 */, U64_C(0xdcffee85fda22853) /*   67 */,
+  U64_C(0xccfbd0262c5eef76) /*   68 */, U64_C(0xbaf294cb8990d201) /*   69 */,
+  U64_C(0xe69464f52afad975) /*   70 */, U64_C(0x94b013afdf133e14) /*   71 */,
+  U64_C(0x06a7d1a32823c958) /*   72 */, U64_C(0x6f95fe5130f61119) /*   73 */,
+  U64_C(0xd92ab34e462c06c0) /*   74 */, U64_C(0xed7bde33887c71d2) /*   75 */,
+  U64_C(0x79746d6e6518393e) /*   76 */, U64_C(0x5ba419385d713329) /*   77 */,
+  U64_C(0x7c1ba6b948a97564) /*   78 */, U64_C(0x31987c197bfdac67) /*   79 */,
+  U64_C(0xde6c23c44b053d02) /*   80 */, U64_C(0x581c49fed002d64d) /*   81 */,
+  U64_C(0xdd474d6338261571) /*   82 */, U64_C(0xaa4546c3e473d062) /*   83 */,
+  U64_C(0x928fce349455f860) /*   84 */, U64_C(0x48161bbacaab94d9) /*   85 */,
+  U64_C(0x63912430770e6f68) /*   86 */, U64_C(0x6ec8a5e602c6641c) /*   87 */,
+  U64_C(0x87282515337ddd2b) /*   88 */, U64_C(0x2cda6b42034b701b) /*   89 */,
+  U64_C(0xb03d37c181cb096d) /*   90 */, U64_C(0xe108438266c71c6f) /*   91 */,
+  U64_C(0x2b3180c7eb51b255) /*   92 */, U64_C(0xdf92b82f96c08bbc) /*   93 */,
+  U64_C(0x5c68c8c0a632f3ba) /*   94 */, U64_C(0x5504cc861c3d0556) /*   95 */,
+  U64_C(0xabbfa4e55fb26b8f) /*   96 */, U64_C(0x41848b0ab3baceb4) /*   97 */,
+  U64_C(0xb334a273aa445d32) /*   98 */, U64_C(0xbca696f0a85ad881) /*   99 */,
+  U64_C(0x24f6ec65b528d56c) /*  100 */, U64_C(0x0ce1512e90f4524a) /*  101 */,
+  U64_C(0x4e9dd79d5506d35a) /*  102 */, U64_C(0x258905fac6ce9779) /*  103 */,
+  U64_C(0x2019295b3e109b33) /*  104 */, U64_C(0xf8a9478b73a054cc) /*  105 */,
+  U64_C(0x2924f2f934417eb0) /*  106 */, U64_C(0x3993357d536d1bc4) /*  107 */,
+  U64_C(0x38a81ac21db6ff8b) /*  108 */, U64_C(0x47c4fbf17d6016bf) /*  109 */,
+  U64_C(0x1e0faadd7667e3f5) /*  110 */, U64_C(0x7abcff62938beb96) /*  111 */,
+  U64_C(0xa78dad948fc179c9) /*  112 */, U64_C(0x8f1f98b72911e50d) /*  113 */,
+  U64_C(0x61e48eae27121a91) /*  114 */, U64_C(0x4d62f7ad31859808) /*  115 */,
+  U64_C(0xeceba345ef5ceaeb) /*  116 */, U64_C(0xf5ceb25ebc9684ce) /*  117 */,
+  U64_C(0xf633e20cb7f76221) /*  118 */, U64_C(0xa32cdf06ab8293e4) /*  119 */,
+  U64_C(0x985a202ca5ee2ca4) /*  120 */, U64_C(0xcf0b8447cc8a8fb1) /*  121 */,
+  U64_C(0x9f765244979859a3) /*  122 */, U64_C(0xa8d516b1a1240017) /*  123 */,
+  U64_C(0x0bd7ba3ebb5dc726) /*  124 */, U64_C(0xe54bca55b86adb39) /*  125 */,
+  U64_C(0x1d7a3afd6c478063) /*  126 */, U64_C(0x519ec608e7669edd) /*  127 */,
+  U64_C(0x0e5715a2d149aa23) /*  128 */, U64_C(0x177d4571848ff194) /*  129 */,
+  U64_C(0xeeb55f3241014c22) /*  130 */, U64_C(0x0f5e5ca13a6e2ec2) /*  131 */,
+  U64_C(0x8029927b75f5c361) /*  132 */, U64_C(0xad139fabc3d6e436) /*  133 */,
+  U64_C(0x0d5df1a94ccf402f) /*  134 */, U64_C(0x3e8bd948bea5dfc8) /*  135 */,
+  U64_C(0xa5a0d357bd3ff77e) /*  136 */, U64_C(0xa2d12e251f74f645) /*  137 */,
+  U64_C(0x66fd9e525e81a082) /*  138 */, U64_C(0x2e0c90ce7f687a49) /*  139 */,
+  U64_C(0xc2e8bcbeba973bc5) /*  140 */, U64_C(0x000001bce509745f) /*  141 */,
+  U64_C(0x423777bbe6dab3d6) /*  142 */, U64_C(0xd1661c7eaef06eb5) /*  143 */,
+  U64_C(0xa1781f354daacfd8) /*  144 */, U64_C(0x2d11284a2b16affc) /*  145 */,
+  U64_C(0xf1fc4f67fa891d1f) /*  146 */, U64_C(0x73ecc25dcb920ada) /*  147 */,
+  U64_C(0xae610c22c2a12651) /*  148 */, U64_C(0x96e0a810d356b78a) /*  149 */,
+  U64_C(0x5a9a381f2fe7870f) /*  150 */, U64_C(0xd5ad62ede94e5530) /*  151 */,
+  U64_C(0xd225e5e8368d1427) /*  152 */, U64_C(0x65977b70c7af4631) /*  153 */,
+  U64_C(0x99f889b2de39d74f) /*  154 */, U64_C(0x233f30bf54e1d143) /*  155 */,
+  U64_C(0x9a9675d3d9a63c97) /*  156 */, U64_C(0x5470554ff334f9a8) /*  157 */,
+  U64_C(0x166acb744a4f5688) /*  158 */, U64_C(0x70c74caab2e4aead) /*  159 */,
+  U64_C(0xf0d091646f294d12) /*  160 */, U64_C(0x57b82a89684031d1) /*  161 */,
+  U64_C(0xefd95a5a61be0b6b) /*  162 */, U64_C(0x2fbd12e969f2f29a) /*  163 */,
+  U64_C(0x9bd37013feff9fe8) /*  164 */, U64_C(0x3f9b0404d6085a06) /*  165 */,
+  U64_C(0x4940c1f3166cfe15) /*  166 */, U64_C(0x09542c4dcdf3defb) /*  167 */,
+  U64_C(0xb4c5218385cd5ce3) /*  168 */, U64_C(0xc935b7dc4462a641) /*  169 */,
+  U64_C(0x3417f8a68ed3b63f) /*  170 */, U64_C(0xb80959295b215b40) /*  171 */,
+  U64_C(0xf99cdaef3b8c8572) /*  172 */, U64_C(0x018c0614f8fcb95d) /*  173 */,
+  U64_C(0x1b14accd1a3acdf3) /*  174 */, U64_C(0x84d471f200bb732d) /*  175 */,
+  U64_C(0xc1a3110e95e8da16) /*  176 */, U64_C(0x430a7220bf1a82b8) /*  177 */,
+  U64_C(0xb77e090d39df210e) /*  178 */, U64_C(0x5ef4bd9f3cd05e9d) /*  179 */,
+  U64_C(0x9d4ff6da7e57a444) /*  180 */, U64_C(0xda1d60e183d4a5f8) /*  181 */,
+  U64_C(0xb287c38417998e47) /*  182 */, U64_C(0xfe3edc121bb31886) /*  183 */,
+  U64_C(0xc7fe3ccc980ccbef) /*  184 */, U64_C(0xe46fb590189bfd03) /*  185 */,
+  U64_C(0x3732fd469a4c57dc) /*  186 */, U64_C(0x7ef700a07cf1ad65) /*  187 */,
+  U64_C(0x59c64468a31d8859) /*  188 */, U64_C(0x762fb0b4d45b61f6) /*  189 */,
+  U64_C(0x155baed099047718) /*  190 */, U64_C(0x68755e4c3d50baa6) /*  191 */,
+  U64_C(0xe9214e7f22d8b4df) /*  192 */, U64_C(0x2addbf532eac95f4) /*  193 */,
+  U64_C(0x32ae3909b4bd0109) /*  194 */, U64_C(0x834df537b08e3450) /*  195 */,
+  U64_C(0xfa209da84220728d) /*  196 */, U64_C(0x9e691d9b9efe23f7) /*  197 */,
+  U64_C(0x0446d288c4ae8d7f) /*  198 */, U64_C(0x7b4cc524e169785b) /*  199 */,
+  U64_C(0x21d87f0135ca1385) /*  200 */, U64_C(0xcebb400f137b8aa5) /*  201 */,
+  U64_C(0x272e2b66580796be) /*  202 */, U64_C(0x3612264125c2b0de) /*  203 */,
+  U64_C(0x057702bdad1efbb2) /*  204 */, U64_C(0xd4babb8eacf84be9) /*  205 */,
+  U64_C(0x91583139641bc67b) /*  206 */, U64_C(0x8bdc2de08036e024) /*  207 */,
+  U64_C(0x603c8156f49f68ed) /*  208 */, U64_C(0xf7d236f7dbef5111) /*  209 */,
+  U64_C(0x9727c4598ad21e80) /*  210 */, U64_C(0xa08a0896670a5fd7) /*  211 */,
+  U64_C(0xcb4a8f4309eba9cb) /*  212 */, U64_C(0x81af564b0f7036a1) /*  213 */,
+  U64_C(0xc0b99aa778199abd) /*  214 */, U64_C(0x959f1ec83fc8e952) /*  215 */,
+  U64_C(0x8c505077794a81b9) /*  216 */, U64_C(0x3acaaf8f056338f0) /*  217 */,
+  U64_C(0x07b43f50627a6778) /*  218 */, U64_C(0x4a44ab49f5eccc77) /*  219 */,
+  U64_C(0x3bc3d6e4b679ee98) /*  220 */, U64_C(0x9cc0d4d1cf14108c) /*  221 */,
+  U64_C(0x4406c00b206bc8a0) /*  222 */, U64_C(0x82a18854c8d72d89) /*  223 */,
+  U64_C(0x67e366b35c3c432c) /*  224 */, U64_C(0xb923dd61102b37f2) /*  225 */,
+  U64_C(0x56ab2779d884271d) /*  226 */, U64_C(0xbe83e1b0ff1525af) /*  227 */,
+  U64_C(0xfb7c65d4217e49a9) /*  228 */, U64_C(0x6bdbe0e76d48e7d4) /*  229 */,
+  U64_C(0x08df828745d9179e) /*  230 */, U64_C(0x22ea6a9add53bd34) /*  231 */,
+  U64_C(0xe36e141c5622200a) /*  232 */, U64_C(0x7f805d1b8cb750ee) /*  233 */,
+  U64_C(0xafe5c7a59f58e837) /*  234 */, U64_C(0xe27f996a4fb1c23c) /*  235 */,
+  U64_C(0xd3867dfb0775f0d0) /*  236 */, U64_C(0xd0e673de6e88891a) /*  237 */,
+  U64_C(0x123aeb9eafb86c25) /*  238 */, U64_C(0x30f1d5d5c145b895) /*  239 */,
+  U64_C(0xbb434a2dee7269e7) /*  240 */, U64_C(0x78cb67ecf931fa38) /*  241 */,
+  U64_C(0xf33b0372323bbf9c) /*  242 */, U64_C(0x52d66336fb279c74) /*  243 */,
+  U64_C(0x505f33ac0afb4eaa) /*  244 */, U64_C(0xe8a5cd99a2cce187) /*  245 */,
+  U64_C(0x534974801e2d30bb) /*  246 */, U64_C(0x8d2d5711d5876d90) /*  247 */,
+  U64_C(0x1f1a412891bc038e) /*  248 */, U64_C(0xd6e2e71d82e56648) /*  249 */,
+  U64_C(0x74036c3a497732b7) /*  250 */, U64_C(0x89b67ed96361f5ab) /*  251 */,
+  U64_C(0xffed95d8f1ea02a2) /*  252 */, U64_C(0xe72b3bd61464d43d) /*  253 */,
+  U64_C(0xa6300f170bdc4820) /*  254 */, U64_C(0xebc18760ed78a77a) /*  255 */
+};
+static u64 sbox2[256] = {
+  U64_C(0xe6a6be5a05a12138) /*  256 */, U64_C(0xb5a122a5b4f87c98) /*  257 */,
+  U64_C(0x563c6089140b6990) /*  258 */, U64_C(0x4c46cb2e391f5dd5) /*  259 */,
+  U64_C(0xd932addbc9b79434) /*  260 */, U64_C(0x08ea70e42015aff5) /*  261 */,
+  U64_C(0xd765a6673e478cf1) /*  262 */, U64_C(0xc4fb757eab278d99) /*  263 */,
+  U64_C(0xdf11c6862d6e0692) /*  264 */, U64_C(0xddeb84f10d7f3b16) /*  265 */,
+  U64_C(0x6f2ef604a665ea04) /*  266 */, U64_C(0x4a8e0f0ff0e0dfb3) /*  267 */,
+  U64_C(0xa5edeef83dbcba51) /*  268 */, U64_C(0xfc4f0a2a0ea4371e) /*  269 */,
+  U64_C(0xe83e1da85cb38429) /*  270 */, U64_C(0xdc8ff882ba1b1ce2) /*  271 */,
+  U64_C(0xcd45505e8353e80d) /*  272 */, U64_C(0x18d19a00d4db0717) /*  273 */,
+  U64_C(0x34a0cfeda5f38101) /*  274 */, U64_C(0x0be77e518887caf2) /*  275 */,
+  U64_C(0x1e341438b3c45136) /*  276 */, U64_C(0xe05797f49089ccf9) /*  277 */,
+  U64_C(0xffd23f9df2591d14) /*  278 */, U64_C(0x543dda228595c5cd) /*  279 */,
+  U64_C(0x661f81fd99052a33) /*  280 */, U64_C(0x8736e641db0f7b76) /*  281 */,
+  U64_C(0x15227725418e5307) /*  282 */, U64_C(0xe25f7f46162eb2fa) /*  283 */,
+  U64_C(0x48a8b2126c13d9fe) /*  284 */, U64_C(0xafdc541792e76eea) /*  285 */,
+  U64_C(0x03d912bfc6d1898f) /*  286 */, U64_C(0x31b1aafa1b83f51b) /*  287 */,
+  U64_C(0xf1ac2796e42ab7d9) /*  288 */, U64_C(0x40a3a7d7fcd2ebac) /*  289 */,
+  U64_C(0x1056136d0afbbcc5) /*  290 */, U64_C(0x7889e1dd9a6d0c85) /*  291 */,
+  U64_C(0xd33525782a7974aa) /*  292 */, U64_C(0xa7e25d09078ac09b) /*  293 */,
+  U64_C(0xbd4138b3eac6edd0) /*  294 */, U64_C(0x920abfbe71eb9e70) /*  295 */,
+  U64_C(0xa2a5d0f54fc2625c) /*  296 */, U64_C(0xc054e36b0b1290a3) /*  297 */,
+  U64_C(0xf6dd59ff62fe932b) /*  298 */, U64_C(0x3537354511a8ac7d) /*  299 */,
+  U64_C(0xca845e9172fadcd4) /*  300 */, U64_C(0x84f82b60329d20dc) /*  301 */,
+  U64_C(0x79c62ce1cd672f18) /*  302 */, U64_C(0x8b09a2add124642c) /*  303 */,
+  U64_C(0xd0c1e96a19d9e726) /*  304 */, U64_C(0x5a786a9b4ba9500c) /*  305 */,
+  U64_C(0x0e020336634c43f3) /*  306 */, U64_C(0xc17b474aeb66d822) /*  307 */,
+  U64_C(0x6a731ae3ec9baac2) /*  308 */, U64_C(0x8226667ae0840258) /*  309 */,
+  U64_C(0x67d4567691caeca5) /*  310 */, U64_C(0x1d94155c4875adb5) /*  311 */,
+  U64_C(0x6d00fd985b813fdf) /*  312 */, U64_C(0x51286efcb774cd06) /*  313 */,
+  U64_C(0x5e8834471fa744af) /*  314 */, U64_C(0xf72ca0aee761ae2e) /*  315 */,
+  U64_C(0xbe40e4cdaee8e09a) /*  316 */, U64_C(0xe9970bbb5118f665) /*  317 */,
+  U64_C(0x726e4beb33df1964) /*  318 */, U64_C(0x703b000729199762) /*  319 */,
+  U64_C(0x4631d816f5ef30a7) /*  320 */, U64_C(0xb880b5b51504a6be) /*  321 */,
+  U64_C(0x641793c37ed84b6c) /*  322 */, U64_C(0x7b21ed77f6e97d96) /*  323 */,
+  U64_C(0x776306312ef96b73) /*  324 */, U64_C(0xae528948e86ff3f4) /*  325 */,
+  U64_C(0x53dbd7f286a3f8f8) /*  326 */, U64_C(0x16cadce74cfc1063) /*  327 */,
+  U64_C(0x005c19bdfa52c6dd) /*  328 */, U64_C(0x68868f5d64d46ad3) /*  329 */,
+  U64_C(0x3a9d512ccf1e186a) /*  330 */, U64_C(0x367e62c2385660ae) /*  331 */,
+  U64_C(0xe359e7ea77dcb1d7) /*  332 */, U64_C(0x526c0773749abe6e) /*  333 */,
+  U64_C(0x735ae5f9d09f734b) /*  334 */, U64_C(0x493fc7cc8a558ba8) /*  335 */,
+  U64_C(0xb0b9c1533041ab45) /*  336 */, U64_C(0x321958ba470a59bd) /*  337 */,
+  U64_C(0x852db00b5f46c393) /*  338 */, U64_C(0x91209b2bd336b0e5) /*  339 */,
+  U64_C(0x6e604f7d659ef19f) /*  340 */, U64_C(0xb99a8ae2782ccb24) /*  341 */,
+  U64_C(0xccf52ab6c814c4c7) /*  342 */, U64_C(0x4727d9afbe11727b) /*  343 */,
+  U64_C(0x7e950d0c0121b34d) /*  344 */, U64_C(0x756f435670ad471f) /*  345 */,
+  U64_C(0xf5add442615a6849) /*  346 */, U64_C(0x4e87e09980b9957a) /*  347 */,
+  U64_C(0x2acfa1df50aee355) /*  348 */, U64_C(0xd898263afd2fd556) /*  349 */,
+  U64_C(0xc8f4924dd80c8fd6) /*  350 */, U64_C(0xcf99ca3d754a173a) /*  351 */,
+  U64_C(0xfe477bacaf91bf3c) /*  352 */, U64_C(0xed5371f6d690c12d) /*  353 */,
+  U64_C(0x831a5c285e687094) /*  354 */, U64_C(0xc5d3c90a3708a0a4) /*  355 */,
+  U64_C(0x0f7f903717d06580) /*  356 */, U64_C(0x19f9bb13b8fdf27f) /*  357 */,
+  U64_C(0xb1bd6f1b4d502843) /*  358 */, U64_C(0x1c761ba38fff4012) /*  359 */,
+  U64_C(0x0d1530c4e2e21f3b) /*  360 */, U64_C(0x8943ce69a7372c8a) /*  361 */,
+  U64_C(0xe5184e11feb5ce66) /*  362 */, U64_C(0x618bdb80bd736621) /*  363 */,
+  U64_C(0x7d29bad68b574d0b) /*  364 */, U64_C(0x81bb613e25e6fe5b) /*  365 */,
+  U64_C(0x071c9c10bc07913f) /*  366 */, U64_C(0xc7beeb7909ac2d97) /*  367 */,
+  U64_C(0xc3e58d353bc5d757) /*  368 */, U64_C(0xeb017892f38f61e8) /*  369 */,
+  U64_C(0xd4effb9c9b1cc21a) /*  370 */, U64_C(0x99727d26f494f7ab) /*  371 */,
+  U64_C(0xa3e063a2956b3e03) /*  372 */, U64_C(0x9d4a8b9a4aa09c30) /*  373 */,
+  U64_C(0x3f6ab7d500090fb4) /*  374 */, U64_C(0x9cc0f2a057268ac0) /*  375 */,
+  U64_C(0x3dee9d2dedbf42d1) /*  376 */, U64_C(0x330f49c87960a972) /*  377 */,
+  U64_C(0xc6b2720287421b41) /*  378 */, U64_C(0x0ac59ec07c00369c) /*  379 */,
+  U64_C(0xef4eac49cb353425) /*  380 */, U64_C(0xf450244eef0129d8) /*  381 */,
+  U64_C(0x8acc46e5caf4deb6) /*  382 */, U64_C(0x2ffeab63989263f7) /*  383 */,
+  U64_C(0x8f7cb9fe5d7a4578) /*  384 */, U64_C(0x5bd8f7644e634635) /*  385 */,
+  U64_C(0x427a7315bf2dc900) /*  386 */, U64_C(0x17d0c4aa2125261c) /*  387 */,
+  U64_C(0x3992486c93518e50) /*  388 */, U64_C(0xb4cbfee0a2d7d4c3) /*  389 */,
+  U64_C(0x7c75d6202c5ddd8d) /*  390 */, U64_C(0xdbc295d8e35b6c61) /*  391 */,
+  U64_C(0x60b369d302032b19) /*  392 */, U64_C(0xce42685fdce44132) /*  393 */,
+  U64_C(0x06f3ddb9ddf65610) /*  394 */, U64_C(0x8ea4d21db5e148f0) /*  395 */,
+  U64_C(0x20b0fce62fcd496f) /*  396 */, U64_C(0x2c1b912358b0ee31) /*  397 */,
+  U64_C(0xb28317b818f5a308) /*  398 */, U64_C(0xa89c1e189ca6d2cf) /*  399 */,
+  U64_C(0x0c6b18576aaadbc8) /*  400 */, U64_C(0xb65deaa91299fae3) /*  401 */,
+  U64_C(0xfb2b794b7f1027e7) /*  402 */, U64_C(0x04e4317f443b5beb) /*  403 */,
+  U64_C(0x4b852d325939d0a6) /*  404 */, U64_C(0xd5ae6beefb207ffc) /*  405 */,
+  U64_C(0x309682b281c7d374) /*  406 */, U64_C(0xbae309a194c3b475) /*  407 */,
+  U64_C(0x8cc3f97b13b49f05) /*  408 */, U64_C(0x98a9422ff8293967) /*  409 */,
+  U64_C(0x244b16b01076ff7c) /*  410 */, U64_C(0xf8bf571c663d67ee) /*  411 */,
+  U64_C(0x1f0d6758eee30da1) /*  412 */, U64_C(0xc9b611d97adeb9b7) /*  413 */,
+  U64_C(0xb7afd5887b6c57a2) /*  414 */, U64_C(0x6290ae846b984fe1) /*  415 */,
+  U64_C(0x94df4cdeacc1a5fd) /*  416 */, U64_C(0x058a5bd1c5483aff) /*  417 */,
+  U64_C(0x63166cc142ba3c37) /*  418 */, U64_C(0x8db8526eb2f76f40) /*  419 */,
+  U64_C(0xe10880036f0d6d4e) /*  420 */, U64_C(0x9e0523c9971d311d) /*  421 */,
+  U64_C(0x45ec2824cc7cd691) /*  422 */, U64_C(0x575b8359e62382c9) /*  423 */,
+  U64_C(0xfa9e400dc4889995) /*  424 */, U64_C(0xd1823ecb45721568) /*  425 */,
+  U64_C(0xdafd983b8206082f) /*  426 */, U64_C(0xaa7d29082386a8cb) /*  427 */,
+  U64_C(0x269fcd4403b87588) /*  428 */, U64_C(0x1b91f5f728bdd1e0) /*  429 */,
+  U64_C(0xe4669f39040201f6) /*  430 */, U64_C(0x7a1d7c218cf04ade) /*  431 */,
+  U64_C(0x65623c29d79ce5ce) /*  432 */, U64_C(0x2368449096c00bb1) /*  433 */,
+  U64_C(0xab9bf1879da503ba) /*  434 */, U64_C(0xbc23ecb1a458058e) /*  435 */,
+  U64_C(0x9a58df01bb401ecc) /*  436 */, U64_C(0xa070e868a85f143d) /*  437 */,
+  U64_C(0x4ff188307df2239e) /*  438 */, U64_C(0x14d565b41a641183) /*  439 */,
+  U64_C(0xee13337452701602) /*  440 */, U64_C(0x950e3dcf3f285e09) /*  441 */,
+  U64_C(0x59930254b9c80953) /*  442 */, U64_C(0x3bf299408930da6d) /*  443 */,
+  U64_C(0xa955943f53691387) /*  444 */, U64_C(0xa15edecaa9cb8784) /*  445 */,
+  U64_C(0x29142127352be9a0) /*  446 */, U64_C(0x76f0371fff4e7afb) /*  447 */,
+  U64_C(0x0239f450274f2228) /*  448 */, U64_C(0xbb073af01d5e868b) /*  449 */,
+  U64_C(0xbfc80571c10e96c1) /*  450 */, U64_C(0xd267088568222e23) /*  451 */,
+  U64_C(0x9671a3d48e80b5b0) /*  452 */, U64_C(0x55b5d38ae193bb81) /*  453 */,
+  U64_C(0x693ae2d0a18b04b8) /*  454 */, U64_C(0x5c48b4ecadd5335f) /*  455 */,
+  U64_C(0xfd743b194916a1ca) /*  456 */, U64_C(0x2577018134be98c4) /*  457 */,
+  U64_C(0xe77987e83c54a4ad) /*  458 */, U64_C(0x28e11014da33e1b9) /*  459 */,
+  U64_C(0x270cc59e226aa213) /*  460 */, U64_C(0x71495f756d1a5f60) /*  461 */,
+  U64_C(0x9be853fb60afef77) /*  462 */, U64_C(0xadc786a7f7443dbf) /*  463 */,
+  U64_C(0x0904456173b29a82) /*  464 */, U64_C(0x58bc7a66c232bd5e) /*  465 */,
+  U64_C(0xf306558c673ac8b2) /*  466 */, U64_C(0x41f639c6b6c9772a) /*  467 */,
+  U64_C(0x216defe99fda35da) /*  468 */, U64_C(0x11640cc71c7be615) /*  469 */,
+  U64_C(0x93c43694565c5527) /*  470 */, U64_C(0xea038e6246777839) /*  471 */,
+  U64_C(0xf9abf3ce5a3e2469) /*  472 */, U64_C(0x741e768d0fd312d2) /*  473 */,
+  U64_C(0x0144b883ced652c6) /*  474 */, U64_C(0xc20b5a5ba33f8552) /*  475 */,
+  U64_C(0x1ae69633c3435a9d) /*  476 */, U64_C(0x97a28ca4088cfdec) /*  477 */,
+  U64_C(0x8824a43c1e96f420) /*  478 */, U64_C(0x37612fa66eeea746) /*  479 */,
+  U64_C(0x6b4cb165f9cf0e5a) /*  480 */, U64_C(0x43aa1c06a0abfb4a) /*  481 */,
+  U64_C(0x7f4dc26ff162796b) /*  482 */, U64_C(0x6cbacc8e54ed9b0f) /*  483 */,
+  U64_C(0xa6b7ffefd2bb253e) /*  484 */, U64_C(0x2e25bc95b0a29d4f) /*  485 */,
+  U64_C(0x86d6a58bdef1388c) /*  486 */, U64_C(0xded74ac576b6f054) /*  487 */,
+  U64_C(0x8030bdbc2b45805d) /*  488 */, U64_C(0x3c81af70e94d9289) /*  489 */,
+  U64_C(0x3eff6dda9e3100db) /*  490 */, U64_C(0xb38dc39fdfcc8847) /*  491 */,
+  U64_C(0x123885528d17b87e) /*  492 */, U64_C(0xf2da0ed240b1b642) /*  493 */,
+  U64_C(0x44cefadcd54bf9a9) /*  494 */, U64_C(0x1312200e433c7ee6) /*  495 */,
+  U64_C(0x9ffcc84f3a78c748) /*  496 */, U64_C(0xf0cd1f72248576bb) /*  497 */,
+  U64_C(0xec6974053638cfe4) /*  498 */, U64_C(0x2ba7b67c0cec4e4c) /*  499 */,
+  U64_C(0xac2f4df3e5ce32ed) /*  500 */, U64_C(0xcb33d14326ea4c11) /*  501 */,
+  U64_C(0xa4e9044cc77e58bc) /*  502 */, U64_C(0x5f513293d934fcef) /*  503 */,
+  U64_C(0x5dc9645506e55444) /*  504 */, U64_C(0x50de418f317de40a) /*  505 */,
+  U64_C(0x388cb31a69dde259) /*  506 */, U64_C(0x2db4a83455820a86) /*  507 */,
+  U64_C(0x9010a91e84711ae9) /*  508 */, U64_C(0x4df7f0b7b1498371) /*  509 */,
+  U64_C(0xd62a2eabc0977179) /*  510 */, U64_C(0x22fac097aa8d5c0e) /*  511 */
+};
+static u64 sbox3[256] = {
+  U64_C(0xf49fcc2ff1daf39b) /*  512 */, U64_C(0x487fd5c66ff29281) /*  513 */,
+  U64_C(0xe8a30667fcdca83f) /*  514 */, U64_C(0x2c9b4be3d2fcce63) /*  515 */,
+  U64_C(0xda3ff74b93fbbbc2) /*  516 */, U64_C(0x2fa165d2fe70ba66) /*  517 */,
+  U64_C(0xa103e279970e93d4) /*  518 */, U64_C(0xbecdec77b0e45e71) /*  519 */,
+  U64_C(0xcfb41e723985e497) /*  520 */, U64_C(0xb70aaa025ef75017) /*  521 */,
+  U64_C(0xd42309f03840b8e0) /*  522 */, U64_C(0x8efc1ad035898579) /*  523 */,
+  U64_C(0x96c6920be2b2abc5) /*  524 */, U64_C(0x66af4163375a9172) /*  525 */,
+  U64_C(0x2174abdcca7127fb) /*  526 */, U64_C(0xb33ccea64a72ff41) /*  527 */,
+  U64_C(0xf04a4933083066a5) /*  528 */, U64_C(0x8d970acdd7289af5) /*  529 */,
+  U64_C(0x8f96e8e031c8c25e) /*  530 */, U64_C(0xf3fec02276875d47) /*  531 */,
+  U64_C(0xec7bf310056190dd) /*  532 */, U64_C(0xf5adb0aebb0f1491) /*  533 */,
+  U64_C(0x9b50f8850fd58892) /*  534 */, U64_C(0x4975488358b74de8) /*  535 */,
+  U64_C(0xa3354ff691531c61) /*  536 */, U64_C(0x0702bbe481d2c6ee) /*  537 */,
+  U64_C(0x89fb24057deded98) /*  538 */, U64_C(0xac3075138596e902) /*  539 */,
+  U64_C(0x1d2d3580172772ed) /*  540 */, U64_C(0xeb738fc28e6bc30d) /*  541 */,
+  U64_C(0x5854ef8f63044326) /*  542 */, U64_C(0x9e5c52325add3bbe) /*  543 */,
+  U64_C(0x90aa53cf325c4623) /*  544 */, U64_C(0xc1d24d51349dd067) /*  545 */,
+  U64_C(0x2051cfeea69ea624) /*  546 */, U64_C(0x13220f0a862e7e4f) /*  547 */,
+  U64_C(0xce39399404e04864) /*  548 */, U64_C(0xd9c42ca47086fcb7) /*  549 */,
+  U64_C(0x685ad2238a03e7cc) /*  550 */, U64_C(0x066484b2ab2ff1db) /*  551 */,
+  U64_C(0xfe9d5d70efbf79ec) /*  552 */, U64_C(0x5b13b9dd9c481854) /*  553 */,
+  U64_C(0x15f0d475ed1509ad) /*  554 */, U64_C(0x0bebcd060ec79851) /*  555 */,
+  U64_C(0xd58c6791183ab7f8) /*  556 */, U64_C(0xd1187c5052f3eee4) /*  557 */,
+  U64_C(0xc95d1192e54e82ff) /*  558 */, U64_C(0x86eea14cb9ac6ca2) /*  559 */,
+  U64_C(0x3485beb153677d5d) /*  560 */, U64_C(0xdd191d781f8c492a) /*  561 */,
+  U64_C(0xf60866baa784ebf9) /*  562 */, U64_C(0x518f643ba2d08c74) /*  563 */,
+  U64_C(0x8852e956e1087c22) /*  564 */, U64_C(0xa768cb8dc410ae8d) /*  565 */,
+  U64_C(0x38047726bfec8e1a) /*  566 */, U64_C(0xa67738b4cd3b45aa) /*  567 */,
+  U64_C(0xad16691cec0dde19) /*  568 */, U64_C(0xc6d4319380462e07) /*  569 */,
+  U64_C(0xc5a5876d0ba61938) /*  570 */, U64_C(0x16b9fa1fa58fd840) /*  571 */,
+  U64_C(0x188ab1173ca74f18) /*  572 */, U64_C(0xabda2f98c99c021f) /*  573 */,
+  U64_C(0x3e0580ab134ae816) /*  574 */, U64_C(0x5f3b05b773645abb) /*  575 */,
+  U64_C(0x2501a2be5575f2f6) /*  576 */, U64_C(0x1b2f74004e7e8ba9) /*  577 */,
+  U64_C(0x1cd7580371e8d953) /*  578 */, U64_C(0x7f6ed89562764e30) /*  579 */,
+  U64_C(0xb15926ff596f003d) /*  580 */, U64_C(0x9f65293da8c5d6b9) /*  581 */,
+  U64_C(0x6ecef04dd690f84c) /*  582 */, U64_C(0x4782275fff33af88) /*  583 */,
+  U64_C(0xe41433083f820801) /*  584 */, U64_C(0xfd0dfe409a1af9b5) /*  585 */,
+  U64_C(0x4325a3342cdb396b) /*  586 */, U64_C(0x8ae77e62b301b252) /*  587 */,
+  U64_C(0xc36f9e9f6655615a) /*  588 */, U64_C(0x85455a2d92d32c09) /*  589 */,
+  U64_C(0xf2c7dea949477485) /*  590 */, U64_C(0x63cfb4c133a39eba) /*  591 */,
+  U64_C(0x83b040cc6ebc5462) /*  592 */, U64_C(0x3b9454c8fdb326b0) /*  593 */,
+  U64_C(0x56f56a9e87ffd78c) /*  594 */, U64_C(0x2dc2940d99f42bc6) /*  595 */,
+  U64_C(0x98f7df096b096e2d) /*  596 */, U64_C(0x19a6e01e3ad852bf) /*  597 */,
+  U64_C(0x42a99ccbdbd4b40b) /*  598 */, U64_C(0xa59998af45e9c559) /*  599 */,
+  U64_C(0x366295e807d93186) /*  600 */, U64_C(0x6b48181bfaa1f773) /*  601 */,
+  U64_C(0x1fec57e2157a0a1d) /*  602 */, U64_C(0x4667446af6201ad5) /*  603 */,
+  U64_C(0xe615ebcacfb0f075) /*  604 */, U64_C(0xb8f31f4f68290778) /*  605 */,
+  U64_C(0x22713ed6ce22d11e) /*  606 */, U64_C(0x3057c1a72ec3c93b) /*  607 */,
+  U64_C(0xcb46acc37c3f1f2f) /*  608 */, U64_C(0xdbb893fd02aaf50e) /*  609 */,
+  U64_C(0x331fd92e600b9fcf) /*  610 */, U64_C(0xa498f96148ea3ad6) /*  611 */,
+  U64_C(0xa8d8426e8b6a83ea) /*  612 */, U64_C(0xa089b274b7735cdc) /*  613 */,
+  U64_C(0x87f6b3731e524a11) /*  614 */, U64_C(0x118808e5cbc96749) /*  615 */,
+  U64_C(0x9906e4c7b19bd394) /*  616 */, U64_C(0xafed7f7e9b24a20c) /*  617 */,
+  U64_C(0x6509eadeeb3644a7) /*  618 */, U64_C(0x6c1ef1d3e8ef0ede) /*  619 */,
+  U64_C(0xb9c97d43e9798fb4) /*  620 */, U64_C(0xa2f2d784740c28a3) /*  621 */,
+  U64_C(0x7b8496476197566f) /*  622 */, U64_C(0x7a5be3e6b65f069d) /*  623 */,
+  U64_C(0xf96330ed78be6f10) /*  624 */, U64_C(0xeee60de77a076a15) /*  625 */,
+  U64_C(0x2b4bee4aa08b9bd0) /*  626 */, U64_C(0x6a56a63ec7b8894e) /*  627 */,
+  U64_C(0x02121359ba34fef4) /*  628 */, U64_C(0x4cbf99f8283703fc) /*  629 */,
+  U64_C(0x398071350caf30c8) /*  630 */, U64_C(0xd0a77a89f017687a) /*  631 */,
+  U64_C(0xf1c1a9eb9e423569) /*  632 */, U64_C(0x8c7976282dee8199) /*  633 */,
+  U64_C(0x5d1737a5dd1f7abd) /*  634 */, U64_C(0x4f53433c09a9fa80) /*  635 */,
+  U64_C(0xfa8b0c53df7ca1d9) /*  636 */, U64_C(0x3fd9dcbc886ccb77) /*  637 */,
+  U64_C(0xc040917ca91b4720) /*  638 */, U64_C(0x7dd00142f9d1dcdf) /*  639 */,
+  U64_C(0x8476fc1d4f387b58) /*  640 */, U64_C(0x23f8e7c5f3316503) /*  641 */,
+  U64_C(0x032a2244e7e37339) /*  642 */, U64_C(0x5c87a5d750f5a74b) /*  643 */,
+  U64_C(0x082b4cc43698992e) /*  644 */, U64_C(0xdf917becb858f63c) /*  645 */,
+  U64_C(0x3270b8fc5bf86dda) /*  646 */, U64_C(0x10ae72bb29b5dd76) /*  647 */,
+  U64_C(0x576ac94e7700362b) /*  648 */, U64_C(0x1ad112dac61efb8f) /*  649 */,
+  U64_C(0x691bc30ec5faa427) /*  650 */, U64_C(0xff246311cc327143) /*  651 */,
+  U64_C(0x3142368e30e53206) /*  652 */, U64_C(0x71380e31e02ca396) /*  653 */,
+  U64_C(0x958d5c960aad76f1) /*  654 */, U64_C(0xf8d6f430c16da536) /*  655 */,
+  U64_C(0xc8ffd13f1be7e1d2) /*  656 */, U64_C(0x7578ae66004ddbe1) /*  657 */,
+  U64_C(0x05833f01067be646) /*  658 */, U64_C(0xbb34b5ad3bfe586d) /*  659 */,
+  U64_C(0x095f34c9a12b97f0) /*  660 */, U64_C(0x247ab64525d60ca8) /*  661 */,
+  U64_C(0xdcdbc6f3017477d1) /*  662 */, U64_C(0x4a2e14d4decad24d) /*  663 */,
+  U64_C(0xbdb5e6d9be0a1eeb) /*  664 */, U64_C(0x2a7e70f7794301ab) /*  665 */,
+  U64_C(0xdef42d8a270540fd) /*  666 */, U64_C(0x01078ec0a34c22c1) /*  667 */,
+  U64_C(0xe5de511af4c16387) /*  668 */, U64_C(0x7ebb3a52bd9a330a) /*  669 */,
+  U64_C(0x77697857aa7d6435) /*  670 */, U64_C(0x004e831603ae4c32) /*  671 */,
+  U64_C(0xe7a21020ad78e312) /*  672 */, U64_C(0x9d41a70c6ab420f2) /*  673 */,
+  U64_C(0x28e06c18ea1141e6) /*  674 */, U64_C(0xd2b28cbd984f6b28) /*  675 */,
+  U64_C(0x26b75f6c446e9d83) /*  676 */, U64_C(0xba47568c4d418d7f) /*  677 */,
+  U64_C(0xd80badbfe6183d8e) /*  678 */, U64_C(0x0e206d7f5f166044) /*  679 */,
+  U64_C(0xe258a43911cbca3e) /*  680 */, U64_C(0x723a1746b21dc0bc) /*  681 */,
+  U64_C(0xc7caa854f5d7cdd3) /*  682 */, U64_C(0x7cac32883d261d9c) /*  683 */,
+  U64_C(0x7690c26423ba942c) /*  684 */, U64_C(0x17e55524478042b8) /*  685 */,
+  U64_C(0xe0be477656a2389f) /*  686 */, U64_C(0x4d289b5e67ab2da0) /*  687 */,
+  U64_C(0x44862b9c8fbbfd31) /*  688 */, U64_C(0xb47cc8049d141365) /*  689 */,
+  U64_C(0x822c1b362b91c793) /*  690 */, U64_C(0x4eb14655fb13dfd8) /*  691 */,
+  U64_C(0x1ecbba0714e2a97b) /*  692 */, U64_C(0x6143459d5cde5f14) /*  693 */,
+  U64_C(0x53a8fbf1d5f0ac89) /*  694 */, U64_C(0x97ea04d81c5e5b00) /*  695 */,
+  U64_C(0x622181a8d4fdb3f3) /*  696 */, U64_C(0xe9bcd341572a1208) /*  697 */,
+  U64_C(0x1411258643cce58a) /*  698 */, U64_C(0x9144c5fea4c6e0a4) /*  699 */,
+  U64_C(0x0d33d06565cf620f) /*  700 */, U64_C(0x54a48d489f219ca1) /*  701 */,
+  U64_C(0xc43e5eac6d63c821) /*  702 */, U64_C(0xa9728b3a72770daf) /*  703 */,
+  U64_C(0xd7934e7b20df87ef) /*  704 */, U64_C(0xe35503b61a3e86e5) /*  705 */,
+  U64_C(0xcae321fbc819d504) /*  706 */, U64_C(0x129a50b3ac60bfa6) /*  707 */,
+  U64_C(0xcd5e68ea7e9fb6c3) /*  708 */, U64_C(0xb01c90199483b1c7) /*  709 */,
+  U64_C(0x3de93cd5c295376c) /*  710 */, U64_C(0xaed52edf2ab9ad13) /*  711 */,
+  U64_C(0x2e60f512c0a07884) /*  712 */, U64_C(0xbc3d86a3e36210c9) /*  713 */,
+  U64_C(0x35269d9b163951ce) /*  714 */, U64_C(0x0c7d6e2ad0cdb5fa) /*  715 */,
+  U64_C(0x59e86297d87f5733) /*  716 */, U64_C(0x298ef221898db0e7) /*  717 */,
+  U64_C(0x55000029d1a5aa7e) /*  718 */, U64_C(0x8bc08ae1b5061b45) /*  719 */,
+  U64_C(0xc2c31c2b6c92703a) /*  720 */, U64_C(0x94cc596baf25ef42) /*  721 */,
+  U64_C(0x0a1d73db22540456) /*  722 */, U64_C(0x04b6a0f9d9c4179a) /*  723 */,
+  U64_C(0xeffdafa2ae3d3c60) /*  724 */, U64_C(0xf7c8075bb49496c4) /*  725 */,
+  U64_C(0x9cc5c7141d1cd4e3) /*  726 */, U64_C(0x78bd1638218e5534) /*  727 */,
+  U64_C(0xb2f11568f850246a) /*  728 */, U64_C(0xedfabcfa9502bc29) /*  729 */,
+  U64_C(0x796ce5f2da23051b) /*  730 */, U64_C(0xaae128b0dc93537c) /*  731 */,
+  U64_C(0x3a493da0ee4b29ae) /*  732 */, U64_C(0xb5df6b2c416895d7) /*  733 */,
+  U64_C(0xfcabbd25122d7f37) /*  734 */, U64_C(0x70810b58105dc4b1) /*  735 */,
+  U64_C(0xe10fdd37f7882a90) /*  736 */, U64_C(0x524dcab5518a3f5c) /*  737 */,
+  U64_C(0x3c9e85878451255b) /*  738 */, U64_C(0x4029828119bd34e2) /*  739 */,
+  U64_C(0x74a05b6f5d3ceccb) /*  740 */, U64_C(0xb610021542e13eca) /*  741 */,
+  U64_C(0x0ff979d12f59e2ac) /*  742 */, U64_C(0x6037da27e4f9cc50) /*  743 */,
+  U64_C(0x5e92975a0df1847d) /*  744 */, U64_C(0xd66de190d3e623fe) /*  745 */,
+  U64_C(0x5032d6b87b568048) /*  746 */, U64_C(0x9a36b7ce8235216e) /*  747 */,
+  U64_C(0x80272a7a24f64b4a) /*  748 */, U64_C(0x93efed8b8c6916f7) /*  749 */,
+  U64_C(0x37ddbff44cce1555) /*  750 */, U64_C(0x4b95db5d4b99bd25) /*  751 */,
+  U64_C(0x92d3fda169812fc0) /*  752 */, U64_C(0xfb1a4a9a90660bb6) /*  753 */,
+  U64_C(0x730c196946a4b9b2) /*  754 */, U64_C(0x81e289aa7f49da68) /*  755 */,
+  U64_C(0x64669a0f83b1a05f) /*  756 */, U64_C(0x27b3ff7d9644f48b) /*  757 */,
+  U64_C(0xcc6b615c8db675b3) /*  758 */, U64_C(0x674f20b9bcebbe95) /*  759 */,
+  U64_C(0x6f31238275655982) /*  760 */, U64_C(0x5ae488713e45cf05) /*  761 */,
+  U64_C(0xbf619f9954c21157) /*  762 */, U64_C(0xeabac46040a8eae9) /*  763 */,
+  U64_C(0x454c6fe9f2c0c1cd) /*  764 */, U64_C(0x419cf6496412691c) /*  765 */,
+  U64_C(0xd3dc3bef265b0f70) /*  766 */, U64_C(0x6d0e60f5c3578a9e) /*  767 */
+};
+static u64 sbox4[256] = {
+  U64_C(0x5b0e608526323c55) /*  768 */, U64_C(0x1a46c1a9fa1b59f5) /*  769 */,
+  U64_C(0xa9e245a17c4c8ffa) /*  770 */, U64_C(0x65ca5159db2955d7) /*  771 */,
+  U64_C(0x05db0a76ce35afc2) /*  772 */, U64_C(0x81eac77ea9113d45) /*  773 */,
+  U64_C(0x528ef88ab6ac0a0d) /*  774 */, U64_C(0xa09ea253597be3ff) /*  775 */,
+  U64_C(0x430ddfb3ac48cd56) /*  776 */, U64_C(0xc4b3a67af45ce46f) /*  777 */,
+  U64_C(0x4ececfd8fbe2d05e) /*  778 */, U64_C(0x3ef56f10b39935f0) /*  779 */,
+  U64_C(0x0b22d6829cd619c6) /*  780 */, U64_C(0x17fd460a74df2069) /*  781 */,
+  U64_C(0x6cf8cc8e8510ed40) /*  782 */, U64_C(0xd6c824bf3a6ecaa7) /*  783 */,
+  U64_C(0x61243d581a817049) /*  784 */, U64_C(0x048bacb6bbc163a2) /*  785 */,
+  U64_C(0xd9a38ac27d44cc32) /*  786 */, U64_C(0x7fddff5baaf410ab) /*  787 */,
+  U64_C(0xad6d495aa804824b) /*  788 */, U64_C(0xe1a6a74f2d8c9f94) /*  789 */,
+  U64_C(0xd4f7851235dee8e3) /*  790 */, U64_C(0xfd4b7f886540d893) /*  791 */,
+  U64_C(0x247c20042aa4bfda) /*  792 */, U64_C(0x096ea1c517d1327c) /*  793 */,
+  U64_C(0xd56966b4361a6685) /*  794 */, U64_C(0x277da5c31221057d) /*  795 */,
+  U64_C(0x94d59893a43acff7) /*  796 */, U64_C(0x64f0c51ccdc02281) /*  797 */,
+  U64_C(0x3d33bcc4ff6189db) /*  798 */, U64_C(0xe005cb184ce66af1) /*  799 */,
+  U64_C(0xff5ccd1d1db99bea) /*  800 */, U64_C(0xb0b854a7fe42980f) /*  801 */,
+  U64_C(0x7bd46a6a718d4b9f) /*  802 */, U64_C(0xd10fa8cc22a5fd8c) /*  803 */,
+  U64_C(0xd31484952be4bd31) /*  804 */, U64_C(0xc7fa975fcb243847) /*  805 */,
+  U64_C(0x4886ed1e5846c407) /*  806 */, U64_C(0x28cddb791eb70b04) /*  807 */,
+  U64_C(0xc2b00be2f573417f) /*  808 */, U64_C(0x5c9590452180f877) /*  809 */,
+  U64_C(0x7a6bddfff370eb00) /*  810 */, U64_C(0xce509e38d6d9d6a4) /*  811 */,
+  U64_C(0xebeb0f00647fa702) /*  812 */, U64_C(0x1dcc06cf76606f06) /*  813 */,
+  U64_C(0xe4d9f28ba286ff0a) /*  814 */, U64_C(0xd85a305dc918c262) /*  815 */,
+  U64_C(0x475b1d8732225f54) /*  816 */, U64_C(0x2d4fb51668ccb5fe) /*  817 */,
+  U64_C(0xa679b9d9d72bba20) /*  818 */, U64_C(0x53841c0d912d43a5) /*  819 */,
+  U64_C(0x3b7eaa48bf12a4e8) /*  820 */, U64_C(0x781e0e47f22f1ddf) /*  821 */,
+  U64_C(0xeff20ce60ab50973) /*  822 */, U64_C(0x20d261d19dffb742) /*  823 */,
+  U64_C(0x16a12b03062a2e39) /*  824 */, U64_C(0x1960eb2239650495) /*  825 */,
+  U64_C(0x251c16fed50eb8b8) /*  826 */, U64_C(0x9ac0c330f826016e) /*  827 */,
+  U64_C(0xed152665953e7671) /*  828 */, U64_C(0x02d63194a6369570) /*  829 */,
+  U64_C(0x5074f08394b1c987) /*  830 */, U64_C(0x70ba598c90b25ce1) /*  831 */,
+  U64_C(0x794a15810b9742f6) /*  832 */, U64_C(0x0d5925e9fcaf8c6c) /*  833 */,
+  U64_C(0x3067716cd868744e) /*  834 */, U64_C(0x910ab077e8d7731b) /*  835 */,
+  U64_C(0x6a61bbdb5ac42f61) /*  836 */, U64_C(0x93513efbf0851567) /*  837 */,
+  U64_C(0xf494724b9e83e9d5) /*  838 */, U64_C(0xe887e1985c09648d) /*  839 */,
+  U64_C(0x34b1d3c675370cfd) /*  840 */, U64_C(0xdc35e433bc0d255d) /*  841 */,
+  U64_C(0xd0aab84234131be0) /*  842 */, U64_C(0x08042a50b48b7eaf) /*  843 */,
+  U64_C(0x9997c4ee44a3ab35) /*  844 */, U64_C(0x829a7b49201799d0) /*  845 */,
+  U64_C(0x263b8307b7c54441) /*  846 */, U64_C(0x752f95f4fd6a6ca6) /*  847 */,
+  U64_C(0x927217402c08c6e5) /*  848 */, U64_C(0x2a8ab754a795d9ee) /*  849 */,
+  U64_C(0xa442f7552f72943d) /*  850 */, U64_C(0x2c31334e19781208) /*  851 */,
+  U64_C(0x4fa98d7ceaee6291) /*  852 */, U64_C(0x55c3862f665db309) /*  853 */,
+  U64_C(0xbd0610175d53b1f3) /*  854 */, U64_C(0x46fe6cb840413f27) /*  855 */,
+  U64_C(0x3fe03792df0cfa59) /*  856 */, U64_C(0xcfe700372eb85e8f) /*  857 */,
+  U64_C(0xa7be29e7adbce118) /*  858 */, U64_C(0xe544ee5cde8431dd) /*  859 */,
+  U64_C(0x8a781b1b41f1873e) /*  860 */, U64_C(0xa5c94c78a0d2f0e7) /*  861 */,
+  U64_C(0x39412e2877b60728) /*  862 */, U64_C(0xa1265ef3afc9a62c) /*  863 */,
+  U64_C(0xbcc2770c6a2506c5) /*  864 */, U64_C(0x3ab66dd5dce1ce12) /*  865 */,
+  U64_C(0xe65499d04a675b37) /*  866 */, U64_C(0x7d8f523481bfd216) /*  867 */,
+  U64_C(0x0f6f64fcec15f389) /*  868 */, U64_C(0x74efbe618b5b13c8) /*  869 */,
+  U64_C(0xacdc82b714273e1d) /*  870 */, U64_C(0xdd40bfe003199d17) /*  871 */,
+  U64_C(0x37e99257e7e061f8) /*  872 */, U64_C(0xfa52626904775aaa) /*  873 */,
+  U64_C(0x8bbbf63a463d56f9) /*  874 */, U64_C(0xf0013f1543a26e64) /*  875 */,
+  U64_C(0xa8307e9f879ec898) /*  876 */, U64_C(0xcc4c27a4150177cc) /*  877 */,
+  U64_C(0x1b432f2cca1d3348) /*  878 */, U64_C(0xde1d1f8f9f6fa013) /*  879 */,
+  U64_C(0x606602a047a7ddd6) /*  880 */, U64_C(0xd237ab64cc1cb2c7) /*  881 */,
+  U64_C(0x9b938e7225fcd1d3) /*  882 */, U64_C(0xec4e03708e0ff476) /*  883 */,
+  U64_C(0xfeb2fbda3d03c12d) /*  884 */, U64_C(0xae0bced2ee43889a) /*  885 */,
+  U64_C(0x22cb8923ebfb4f43) /*  886 */, U64_C(0x69360d013cf7396d) /*  887 */,
+  U64_C(0x855e3602d2d4e022) /*  888 */, U64_C(0x073805bad01f784c) /*  889 */,
+  U64_C(0x33e17a133852f546) /*  890 */, U64_C(0xdf4874058ac7b638) /*  891 */,
+  U64_C(0xba92b29c678aa14a) /*  892 */, U64_C(0x0ce89fc76cfaadcd) /*  893 */,
+  U64_C(0x5f9d4e0908339e34) /*  894 */, U64_C(0xf1afe9291f5923b9) /*  895 */,
+  U64_C(0x6e3480f60f4a265f) /*  896 */, U64_C(0xeebf3a2ab29b841c) /*  897 */,
+  U64_C(0xe21938a88f91b4ad) /*  898 */, U64_C(0x57dfeff845c6d3c3) /*  899 */,
+  U64_C(0x2f006b0bf62caaf2) /*  900 */, U64_C(0x62f479ef6f75ee78) /*  901 */,
+  U64_C(0x11a55ad41c8916a9) /*  902 */, U64_C(0xf229d29084fed453) /*  903 */,
+  U64_C(0x42f1c27b16b000e6) /*  904 */, U64_C(0x2b1f76749823c074) /*  905 */,
+  U64_C(0x4b76eca3c2745360) /*  906 */, U64_C(0x8c98f463b91691bd) /*  907 */,
+  U64_C(0x14bcc93cf1ade66a) /*  908 */, U64_C(0x8885213e6d458397) /*  909 */,
+  U64_C(0x8e177df0274d4711) /*  910 */, U64_C(0xb49b73b5503f2951) /*  911 */,
+  U64_C(0x10168168c3f96b6b) /*  912 */, U64_C(0x0e3d963b63cab0ae) /*  913 */,
+  U64_C(0x8dfc4b5655a1db14) /*  914 */, U64_C(0xf789f1356e14de5c) /*  915 */,
+  U64_C(0x683e68af4e51dac1) /*  916 */, U64_C(0xc9a84f9d8d4b0fd9) /*  917 */,
+  U64_C(0x3691e03f52a0f9d1) /*  918 */, U64_C(0x5ed86e46e1878e80) /*  919 */,
+  U64_C(0x3c711a0e99d07150) /*  920 */, U64_C(0x5a0865b20c4e9310) /*  921 */,
+  U64_C(0x56fbfc1fe4f0682e) /*  922 */, U64_C(0xea8d5de3105edf9b) /*  923 */,
+  U64_C(0x71abfdb12379187a) /*  924 */, U64_C(0x2eb99de1bee77b9c) /*  925 */,
+  U64_C(0x21ecc0ea33cf4523) /*  926 */, U64_C(0x59a4d7521805c7a1) /*  927 */,
+  U64_C(0x3896f5eb56ae7c72) /*  928 */, U64_C(0xaa638f3db18f75dc) /*  929 */,
+  U64_C(0x9f39358dabe9808e) /*  930 */, U64_C(0xb7defa91c00b72ac) /*  931 */,
+  U64_C(0x6b5541fd62492d92) /*  932 */, U64_C(0x6dc6dee8f92e4d5b) /*  933 */,
+  U64_C(0x353f57abc4beea7e) /*  934 */, U64_C(0x735769d6da5690ce) /*  935 */,
+  U64_C(0x0a234aa642391484) /*  936 */, U64_C(0xf6f9508028f80d9d) /*  937 */,
+  U64_C(0xb8e319a27ab3f215) /*  938 */, U64_C(0x31ad9c1151341a4d) /*  939 */,
+  U64_C(0x773c22a57bef5805) /*  940 */, U64_C(0x45c7561a07968633) /*  941 */,
+  U64_C(0xf913da9e249dbe36) /*  942 */, U64_C(0xda652d9b78a64c68) /*  943 */,
+  U64_C(0x4c27a97f3bc334ef) /*  944 */, U64_C(0x76621220e66b17f4) /*  945 */,
+  U64_C(0x967743899acd7d0b) /*  946 */, U64_C(0xf3ee5bcae0ed6782) /*  947 */,
+  U64_C(0x409f753600c879fc) /*  948 */, U64_C(0x06d09a39b5926db6) /*  949 */,
+  U64_C(0x6f83aeb0317ac588) /*  950 */, U64_C(0x01e6ca4a86381f21) /*  951 */,
+  U64_C(0x66ff3462d19f3025) /*  952 */, U64_C(0x72207c24ddfd3bfb) /*  953 */,
+  U64_C(0x4af6b6d3e2ece2eb) /*  954 */, U64_C(0x9c994dbec7ea08de) /*  955 */,
+  U64_C(0x49ace597b09a8bc4) /*  956 */, U64_C(0xb38c4766cf0797ba) /*  957 */,
+  U64_C(0x131b9373c57c2a75) /*  958 */, U64_C(0xb1822cce61931e58) /*  959 */,
+  U64_C(0x9d7555b909ba1c0c) /*  960 */, U64_C(0x127fafdd937d11d2) /*  961 */,
+  U64_C(0x29da3badc66d92e4) /*  962 */, U64_C(0xa2c1d57154c2ecbc) /*  963 */,
+  U64_C(0x58c5134d82f6fe24) /*  964 */, U64_C(0x1c3ae3515b62274f) /*  965 */,
+  U64_C(0xe907c82e01cb8126) /*  966 */, U64_C(0xf8ed091913e37fcb) /*  967 */,
+  U64_C(0x3249d8f9c80046c9) /*  968 */, U64_C(0x80cf9bede388fb63) /*  969 */,
+  U64_C(0x1881539a116cf19e) /*  970 */, U64_C(0x5103f3f76bd52457) /*  971 */,
+  U64_C(0x15b7e6f5ae47f7a8) /*  972 */, U64_C(0xdbd7c6ded47e9ccf) /*  973 */,
+  U64_C(0x44e55c410228bb1a) /*  974 */, U64_C(0xb647d4255edb4e99) /*  975 */,
+  U64_C(0x5d11882bb8aafc30) /*  976 */, U64_C(0xf5098bbb29d3212a) /*  977 */,
+  U64_C(0x8fb5ea14e90296b3) /*  978 */, U64_C(0x677b942157dd025a) /*  979 */,
+  U64_C(0xfb58e7c0a390acb5) /*  980 */, U64_C(0x89d3674c83bd4a01) /*  981 */,
+  U64_C(0x9e2da4df4bf3b93b) /*  982 */, U64_C(0xfcc41e328cab4829) /*  983 */,
+  U64_C(0x03f38c96ba582c52) /*  984 */, U64_C(0xcad1bdbd7fd85db2) /*  985 */,
+  U64_C(0xbbb442c16082ae83) /*  986 */, U64_C(0xb95fe86ba5da9ab0) /*  987 */,
+  U64_C(0xb22e04673771a93f) /*  988 */, U64_C(0x845358c9493152d8) /*  989 */,
+  U64_C(0xbe2a488697b4541e) /*  990 */, U64_C(0x95a2dc2dd38e6966) /*  991 */,
+  U64_C(0xc02c11ac923c852b) /*  992 */, U64_C(0x2388b1990df2a87b) /*  993 */,
+  U64_C(0x7c8008fa1b4f37be) /*  994 */, U64_C(0x1f70d0c84d54e503) /*  995 */,
+  U64_C(0x5490adec7ece57d4) /*  996 */, U64_C(0x002b3c27d9063a3a) /*  997 */,
+  U64_C(0x7eaea3848030a2bf) /*  998 */, U64_C(0xc602326ded2003c0) /*  999 */,
+  U64_C(0x83a7287d69a94086) /* 1000 */, U64_C(0xc57a5fcb30f57a8a) /* 1001 */,
+  U64_C(0xb56844e479ebe779) /* 1002 */, U64_C(0xa373b40f05dcbce9) /* 1003 */,
+  U64_C(0xd71a786e88570ee2) /* 1004 */, U64_C(0x879cbacdbde8f6a0) /* 1005 */,
+  U64_C(0x976ad1bcc164a32f) /* 1006 */, U64_C(0xab21e25e9666d78b) /* 1007 */,
+  U64_C(0x901063aae5e5c33c) /* 1008 */, U64_C(0x9818b34448698d90) /* 1009 */,
+  U64_C(0xe36487ae3e1e8abb) /* 1010 */, U64_C(0xafbdf931893bdcb4) /* 1011 */,
+  U64_C(0x6345a0dc5fbbd519) /* 1012 */, U64_C(0x8628fe269b9465ca) /* 1013 */,
+  U64_C(0x1e5d01603f9c51ec) /* 1014 */, U64_C(0x4de44006a15049b7) /* 1015 */,
+  U64_C(0xbf6c70e5f776cbb1) /* 1016 */, U64_C(0x411218f2ef552bed) /* 1017 */,
+  U64_C(0xcb0c0708705a36a3) /* 1018 */, U64_C(0xe74d14754f986044) /* 1019 */,
+  U64_C(0xcd56d9430ea8280e) /* 1020 */, U64_C(0xc12591d7535f5065) /* 1021 */,
+  U64_C(0xc83223f1720aef96) /* 1022 */, U64_C(0xc3a0396f7363a51f) /* 1023 */
+};
+
+static void
+tiger_init( void *context )
+{
+  TIGER_CONTEXT *hd = context;
+
+  hd->a = 0x0123456789abcdefLL;
+  hd->b = 0xfedcba9876543210LL;
+  hd->c = 0xf096a5b4c3b2e187LL;
+  hd->nblocks = 0;
+  hd->count = 0;
+}
+
+static void
+tiger_round( u64 *ra, u64 *rb, u64 *rc, u64 x, int mul )
+{
+  u64 a = *ra;
+  u64 b = *rb;
+  u64 c = *rc;
+  
+  c ^= x;
+  a -= (  sbox1[  c        & 0xff ] ^ sbox2[ (c >> 16) & 0xff ]
+        ^ sbox3[ (c >> 32) & 0xff ] ^ sbox4[ (c >> 48) & 0xff ]);
+  b += (  sbox4[ (c >>  8) & 0xff ] ^ sbox3[ (c >> 24) & 0xff ]
+        ^ sbox2[ (c >> 40) & 0xff ] ^ sbox1[ (c >> 56) & 0xff ]);
+  b *= mul;
+  
+  *ra = a;
+  *rb = b;
+  *rc = c;
+}
+
+
+static void
+pass( u64 *ra, u64 *rb, u64 *rc, u64 *x, int mul )
+{
+  u64 a = *ra;
+  u64 b = *rb;
+  u64 c = *rc;
+
+  tiger_round( &a, &b, &c, x[0], mul );
+  tiger_round( &b, &c, &a, x[1], mul );
+  tiger_round( &c, &a, &b, x[2], mul );
+  tiger_round( &a, &b, &c, x[3], mul );
+  tiger_round( &b, &c, &a, x[4], mul );
+  tiger_round( &c, &a, &b, x[5], mul );
+  tiger_round( &a, &b, &c, x[6], mul );
+  tiger_round( &b, &c, &a, x[7], mul );
+
+  *ra = a;
+  *rb = b;
+  *rc = c;
+}
+
+
+static void
+key_schedule( u64 *x )
+{
+  x[0] -= x[7] ^ 0xa5a5a5a5a5a5a5a5LL;
+  x[1] ^= x[0];
+  x[2] += x[1];
+  x[3] -= x[2] ^ ((~x[1]) << 19 );
+  x[4] ^= x[3];
+  x[5] += x[4];
+  x[6] -= x[5] ^ ((~x[4]) >> 23 );
+  x[7] ^= x[6];
+  x[0] += x[7];
+  x[1] -= x[0] ^ ((~x[7]) << 19 );
+  x[2] ^= x[1];
+  x[3] += x[2];
+  x[4] -= x[3] ^ ((~x[2]) >> 23 );
+  x[5] ^= x[4];
+  x[6] += x[5];
+  x[7] -= x[6] ^ 0x0123456789abcdefLL;
+}
+
+
+/****************
+ * Transform the message DATA which consists of 512 bytes (8 words)
+ */
+static void
+transform ( TIGER_CONTEXT *hd, const unsigned char *data )
+{
+  u64 a,b,c,aa,bb,cc;
+  u64 x[8];
+#ifdef WORDS_BIGENDIAN
+#define MKWORD(d,n) \
+               (  ((u64)(d)[8*(n)+7]) << 56 | ((u64)(d)[8*(n)+6]) << 48  \
+                | ((u64)(d)[8*(n)+5]) << 40 | ((u64)(d)[8*(n)+4]) << 32  \
+                | ((u64)(d)[8*(n)+3]) << 24 | ((u64)(d)[8*(n)+2]) << 16  \
+                | ((u64)(d)[8*(n)+1]) << 8  | ((u64)(d)[8*(n)  ])       )
+  x[0] = MKWORD(data, 0);
+  x[1] = MKWORD(data, 1);
+  x[2] = MKWORD(data, 2);
+  x[3] = MKWORD(data, 3);
+  x[4] = MKWORD(data, 4);
+  x[5] = MKWORD(data, 5);
+  x[6] = MKWORD(data, 6);
+  x[7] = MKWORD(data, 7);
+#undef MKWORD
+#else
+  memcpy( &x[0], data, 64 );
+#endif
+
+  /* save */
+  a = aa = hd->a;
+  b = bb = hd->b;
+  c = cc = hd->c;
+
+  pass( &a, &b, &c, x, 5);
+  key_schedule( x );
+  pass( &c, &a, &b, x, 7);
+  key_schedule( x );
+  pass( &b, &c, &a, x, 9);
+
+  /* feedforward */
+  a ^= aa;
+  b -= bb;
+  c += cc;
+  /* store */
+  hd->a = a;
+  hd->b = b;
+  hd->c = c;
+}
+
+
+
+/* Update the message digest with the contents
+ * of INBUF with length INLEN.
+ */
+static void
+tiger_write ( void *context, const void *inbuf_arg, size_t inlen)
+{
+  const unsigned char *inbuf = inbuf_arg;
+  TIGER_CONTEXT *hd = context;
+
+  if( hd->count == 64 ) /* flush the buffer */
+    {
+      transform( hd, hd->buf );
+      _gcry_burn_stack (21*8+11*sizeof(void*));
+      hd->count = 0;
+      hd->nblocks++;
+    }
+  if( !inbuf )
+    return;
+  if( hd->count ) 
+    {
+      for( ; inlen && hd->count < 64; inlen-- )
+        hd->buf[hd->count++] = *inbuf++;
+      tiger_write( hd, NULL, 0 );
+      if( !inlen )
+        return;
+    }
+
+  while( inlen >= 64 )
+    {
+      transform( hd, inbuf );
+      hd->count = 0;
+      hd->nblocks++;
+      inlen -= 64;
+      inbuf += 64;
+    }
+  _gcry_burn_stack (21*8+11*sizeof(void*));
+  for( ; inlen && hd->count < 64; inlen-- )
+    hd->buf[hd->count++] = *inbuf++;
+}
+
+
+
+/* The routine terminates the computation
+ */
+static void
+tiger_final( void *context )
+{
+  TIGER_CONTEXT *hd = context;
+  u32 t, msb, lsb;
+  byte *p;
+
+  tiger_write(hd, NULL, 0); /* flush */;
+
+  t = hd->nblocks;
+  /* multiply by 64 to make a byte count */
+  lsb = t << 6;
+  msb = t >> 26;
+  /* add the count */
+  t = lsb;
+  if( (lsb += hd->count) < t )
+    msb++;
+  /* multiply by 8 to make a bit count */
+  t = lsb;
+  lsb <<= 3;
+  msb <<= 3;
+  msb |= t >> 29;
+
+  if( hd->count < 56 )  /* enough room */
+    {
+      hd->buf[hd->count++] = 0x01; /* pad */
+      while( hd->count < 56 )
+        hd->buf[hd->count++] = 0;  /* pad */
+    }
+  else  /* need one extra block */
+    {
+      hd->buf[hd->count++] = 0x01; /* pad character */
+      while( hd->count < 64 )
+        hd->buf[hd->count++] = 0;
+      tiger_write(hd, NULL, 0);  /* flush */;
+      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+    }
+  /* append the 64 bit count */
+  hd->buf[56] = lsb       ;
+  hd->buf[57] = lsb >>  8;
+  hd->buf[58] = lsb >> 16;
+  hd->buf[59] = lsb >> 24;
+  hd->buf[60] = msb       ;
+  hd->buf[61] = msb >>  8;
+  hd->buf[62] = msb >> 16;
+  hd->buf[63] = msb >> 24;
+  transform( hd, hd->buf );
+  _gcry_burn_stack (21*8+11*sizeof(void*));
+
+  p = hd->buf;
+#ifdef WORDS_BIGENDIAN
+#define X(a) do { *(u64*)p = hd->a ; p += 8; } while(0)
+#else /* little endian */
+#define X(a) do { *p++ = hd->a >> 56; *p++ = hd->a >> 48; \
+                 *p++ = hd->a >> 40; *p++ = hd->a >> 32; \
+                 *p++ = hd->a >> 24; *p++ = hd->a >> 16; \
+                 *p++ = hd->a >>  8; *p++ = hd->a;       } while(0)
+#endif
+  X(a);
+  X(b);
+  X(c);
+#undef X
+}
+
+static byte *
+tiger_read( void *context )
+{
+  TIGER_CONTEXT *hd = context;
+
+  return hd->buf;
+}
+
+static byte asn[19] = /* Object ID is 1.3.6.1.4.1.11591.12.2 */
+  { 0x30, 0x29, 0x30, 0x0d, 0x06, 0x09, 0x2b, 0x06,
+    0x01, 0x04, 0x01, 0xda, 0x47, 0x0c, 0x02,
+    0x05, 0x00, 0x04, 0x18 };
+
+static gcry_md_oid_spec_t oid_spec_tiger[] =
+  {
+    /* GNU.digestAlgorithm TIGER */
+    { "1.3.6.1.4.1.11591.12.2" },
+    { NULL }
+  };
+
+gcry_md_spec_t _gcry_digest_spec_tiger =
+  {
+    "TIGER192", asn, DIM (asn), oid_spec_tiger, 24,
+    tiger_init, tiger_write, tiger_final, tiger_read,
+    sizeof (TIGER_CONTEXT)
+  };
+
+#endif /* HAVE_U64_TYPEDEF */
diff --git a/grub-core/lib/libgcrypt/cipher/twofish.c b/grub-core/lib/libgcrypt/cipher/twofish.c
new file mode 100644 (file)
index 0000000..5274c40
--- /dev/null
@@ -0,0 +1,1040 @@
+/* Twofish for GPG
+ * Copyright (C) 1998, 2002, 2003 Free Software Foundation, Inc.
+ * Written by Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
+ * 256-bit key length added March 20, 1999
+ * Some modifications to reduce the text size by Werner Koch, April, 1998
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ ********************************************************************
+ *
+ * This code is a "clean room" implementation, written from the paper
+ * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
+ * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
+ * through http://www.counterpane.com/twofish.html
+ *
+ * For background information on multiplication in finite fields, used for
+ * the matrix operations in the key schedule, see the book _Contemporary
+ * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
+ * Third Edition.
+ *
+ * Only the 128- and 256-bit key sizes are supported.  This code is intended
+ * for GNU C on a 32-bit system, but it should work almost anywhere.  Loops
+ * are unrolled, precomputation tables are used, etc., for maximum speed at
+ * some cost in memory consumption. */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* for memcmp() */
+
+#include "types.h"  /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+
+/* Prototype for the self-test function. */
+static const char *selftest(void);
+
+/* Structure for an expanded Twofish key.  s contains the key-dependent
+ * S-boxes composed with the MDS matrix; w contains the eight "whitening"
+ * subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys.  Note
+ * that k[i] corresponds to what the Twofish paper calls K[i+8]. */
+typedef struct {
+   u32 s[4][256], w[8], k[32];
+} TWOFISH_context;
+\f
+/* These two tables are the q0 and q1 permutations, exactly as described in
+ * the Twofish paper. */
+
+static const byte q0[256] = {
+   0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
+   0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
+   0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
+   0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
+   0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
+   0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
+   0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
+   0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
+   0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
+   0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
+   0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
+   0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
+   0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
+   0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
+   0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
+   0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
+   0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
+   0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
+   0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
+   0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
+   0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
+   0x4A, 0x5E, 0xC1, 0xE0
+};
+
+static const byte q1[256] = {
+   0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
+   0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
+   0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
+   0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
+   0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
+   0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
+   0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
+   0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
+   0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
+   0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
+   0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
+   0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
+   0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
+   0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
+   0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
+   0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
+   0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
+   0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
+   0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
+   0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
+   0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
+   0x55, 0x09, 0xBE, 0x91
+};
+\f
+/* These MDS tables are actually tables of MDS composed with q0 and q1,
+ * because it is only ever used that way and we can save some time by
+ * precomputing.  Of course the main saving comes from precomputing the
+ * GF(2^8) multiplication involved in the MDS matrix multiply; by looking
+ * things up in these tables we reduce the matrix multiply to four lookups
+ * and three XORs.  Semi-formally, the definition of these tables is:
+ * mds[0][i] = MDS (q1[i] 0 0 0)^T  mds[1][i] = MDS (0 q0[i] 0 0)^T
+ * mds[2][i] = MDS (0 0 q1[i] 0)^T  mds[3][i] = MDS (0 0 0 q0[i])^T
+ * where ^T means "transpose", the matrix multiply is performed in GF(2^8)
+ * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described
+ * by Schneier et al, and I'm casually glossing over the byte/word
+ * conversion issues. */
+
+static const u32 mds[4][256] = {
+   {0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,
+    0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,
+    0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,
+    0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
+    0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA,
+    0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B,
+    0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1,
+    0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
+    0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490,
+    0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154,
+    0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0,
+    0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
+    0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228,
+    0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7,
+    0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3,
+    0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
+    0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477,
+    0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF,
+    0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C,
+    0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
+    0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA,
+    0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D,
+    0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72,
+    0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
+    0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76,
+    0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321,
+    0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39,
+    0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
+    0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D,
+    0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E,
+    0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5,
+    0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
+    0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7,
+    0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544,
+    0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E,
+    0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
+    0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A,
+    0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B,
+    0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2,
+    0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
+    0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504,
+    0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,
+    0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91},
+
+   {0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,
+    0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,
+    0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,
+    0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
+    0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444,
+    0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424,
+    0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A,
+    0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
+    0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383,
+    0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A,
+    0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9,
+    0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
+    0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1,
+    0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898,
+    0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414,
+    0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
+    0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1,
+    0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989,
+    0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5,
+    0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
+    0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E,
+    0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E,
+    0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202,
+    0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
+    0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565,
+    0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A,
+    0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808,
+    0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
+    0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A,
+    0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969,
+    0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505,
+    0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
+    0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D,
+    0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343,
+    0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF,
+    0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
+    0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F,
+    0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646,
+    0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6,
+    0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
+    0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A,
+    0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,
+    0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8},
+
+   {0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,
+    0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,
+    0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,
+    0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
+    0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70,
+    0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3,
+    0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB,
+    0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
+    0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4,
+    0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41,
+    0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C,
+    0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
+    0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622,
+    0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18,
+    0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035,
+    0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
+    0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84,
+    0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E,
+    0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F,
+    0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
+    0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558,
+    0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40,
+    0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA,
+    0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
+    0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF,
+    0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773,
+    0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D,
+    0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
+    0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C,
+    0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19,
+    0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086,
+    0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
+    0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74,
+    0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755,
+    0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691,
+    0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
+    0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4,
+    0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53,
+    0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E,
+    0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
+    0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705,
+    0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,
+    0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF},
+
+   {0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,
+    0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,
+    0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
+    0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
+    0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9,
+    0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C,
+    0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3,
+    0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
+    0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F,
+    0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25,
+    0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF,
+    0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
+    0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4,
+    0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E,
+    0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA,
+    0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
+    0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12,
+    0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A,
+    0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D,
+    0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
+    0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A,
+    0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C,
+    0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B,
+    0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
+    0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B,
+    0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3,
+    0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE,
+    0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
+    0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85,
+    0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA,
+    0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E,
+    0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
+    0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33,
+    0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC,
+    0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718,
+    0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
+    0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8,
+    0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872,
+    0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882,
+    0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
+    0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10,
+    0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6,
+    0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8}
+};
+\f
+/* The exp_to_poly and poly_to_exp tables are used to perform efficient
+ * operations in GF(2^8) represented as GF(2)[x]/w(x) where
+ * w(x)=x^8+x^6+x^3+x^2+1.  We care about doing that because it's part of the
+ * definition of the RS matrix in the key schedule.  Elements of that field
+ * are polynomials of degree not greater than 7 and all coefficients 0 or 1,
+ * which can be represented naturally by bytes (just substitute x=2).  In that
+ * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8)
+ * multiplication is inefficient without hardware support.  To multiply
+ * faster, I make use of the fact x is a generator for the nonzero elements,
+ * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for
+ * some n in 0..254.  Note that that caret is exponentiation in GF(2^8),
+ * *not* polynomial notation.  So if I want to compute pq where p and q are
+ * in GF(2^8), I can just say:
+ *    1. if p=0 or q=0 then pq=0
+ *    2. otherwise, find m and n such that p=x^m and q=x^n
+ *    3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq
+ * The translations in steps 2 and 3 are looked up in the tables
+ * poly_to_exp (for step 2) and exp_to_poly (for step 3).  To see this
+ * in action, look at the CALC_S macro.  As additional wrinkles, note that
+ * one of my operands is always a constant, so the poly_to_exp lookup on it
+ * is done in advance; I included the original values in the comments so
+ * readers can have some chance of recognizing that this *is* the RS matrix
+ * from the Twofish paper.  I've only included the table entries I actually
+ * need; I never do a lookup on a variable input of zero and the biggest
+ * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll
+ * never sum to more than 491. I'm repeating part of the exp_to_poly table
+ * so that I don't have to do mod-255 reduction in the exponent arithmetic.
+ * Since I know my constant operands are never zero, I only have to worry
+ * about zero values in the variable operand, and I do it with a simple
+ * conditional branch. I know conditionals are expensive, but I couldn't
+ * see a non-horrible way of avoiding them, and I did manage to group the
+ * statements so that each if covers four group multiplications. */
+
+static const byte poly_to_exp[255] = {
+   0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
+   0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
+   0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
+   0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B,
+   0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47,
+   0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D,
+   0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8,
+   0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C,
+   0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83,
+   0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48,
+   0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26,
+   0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E,
+   0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3,
+   0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9,
+   0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A,
+   0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D,
+   0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75,
+   0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84,
+   0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64,
+   0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49,
+   0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,
+   0x85, 0xC8, 0xA1
+};
+
+static const byte exp_to_poly[492] = {
+   0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
+   0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
+   0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
+   0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A,
+   0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63,
+   0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C,
+   0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07,
+   0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88,
+   0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12,
+   0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7,
+   0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C,
+   0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8,
+   0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25,
+   0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A,
+   0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE,
+   0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC,
+   0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E,
+   0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92,
+   0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89,
+   0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB,
+   0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,
+   0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D,
+   0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC,
+   0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3,
+   0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52,
+   0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0,
+   0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1,
+   0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A,
+   0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11,
+   0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51,
+   0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66,
+   0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB,
+   0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19,
+   0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D,
+   0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56,
+   0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE,
+   0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9,
+   0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE,
+   0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41,
+   0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E,
+   0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
+};
+\f
+
+/* The table constants are indices of
+ * S-box entries, preprocessed through q0 and q1. */
+static byte calc_sb_tbl[512] = {
+    0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4,
+    0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8,
+    0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B,
+    0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B,
+    0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD,
+    0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1,
+    0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B,
+    0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F,
+    0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B,
+    0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D,
+    0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E,
+    0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5,
+    0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14,
+    0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3,
+    0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54,
+    0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51,
+    0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A,
+    0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96,
+    0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10,
+    0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C,
+    0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7,
+    0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70,
+    0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB,
+    0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8,
+    0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF,
+    0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC,
+    0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF,
+    0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2,
+    0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82,
+    0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9,
+    0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97,
+    0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17,
+    0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D,
+    0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3,
+    0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C,
+    0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E,
+    0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F,
+    0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49,
+    0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21,
+    0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9,
+    0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD,
+    0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01,
+    0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F,
+    0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48,
+    0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E,
+    0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19,
+    0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57,
+    0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64,
+    0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE,
+    0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5,
+    0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44,
+    0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69,
+    0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15,
+    0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E,
+    0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34,
+    0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC,
+    0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B,
+    0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB,
+    0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52,
+    0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9,
+    0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4,
+    0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2,
+    0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
+    0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
+};
+/* Macro to perform one column of the RS matrix multiplication.  The
+ * parameters a, b, c, and d are the four bytes of output; i is the index
+ * of the key bytes, and w, x, y, and z, are the column of constants from
+ * the RS matrix, preprocessed through the poly_to_exp table. */
+
+#define CALC_S(a, b, c, d, i, w, x, y, z) \
+   if (key[i]) { \
+      tmp = poly_to_exp[key[i] - 1]; \
+      (a) ^= exp_to_poly[tmp + (w)]; \
+      (b) ^= exp_to_poly[tmp + (x)]; \
+      (c) ^= exp_to_poly[tmp + (y)]; \
+      (d) ^= exp_to_poly[tmp + (z)]; \
+   }
+
+/* Macros to calculate the key-dependent S-boxes for a 128-bit key using
+ * the S vector from CALC_S.  CALC_SB_2 computes a single entry in all
+ * four S-boxes, where i is the index of the entry to compute, and a and b
+ * are the index numbers preprocessed through the q0 and q1 tables
+ * respectively.  CALC_SB is simply a convenience to make the code shorter;
+ * it calls CALC_SB_2 four times with consecutive indices from i to i+3,
+ * using the remaining parameters two by two. */
+
+#define CALC_SB_2(i, a, b) \
+   ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \
+   ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \
+   ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \
+   ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh]
+
+#define CALC_SB(i, a, b, c, d, e, f, g, h) \
+   CALC_SB_2 (i, a, b); CALC_SB_2 ((i)+1, c, d); \
+   CALC_SB_2 ((i)+2, e, f); CALC_SB_2 ((i)+3, g, h)
+
+/* Macros exactly like CALC_SB and CALC_SB_2, but for 256-bit keys. */
+
+#define CALC_SB256_2(i, a, b) \
+   ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \
+   ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \
+   ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \
+   ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp];
+
+#define CALC_SB256(i, a, b, c, d, e, f, g, h) \
+   CALC_SB256_2 (i, a, b); CALC_SB256_2 ((i)+1, c, d); \
+   CALC_SB256_2 ((i)+2, e, f); CALC_SB256_2 ((i)+3, g, h)
+
+/* Macros to calculate the whitening and round subkeys.  CALC_K_2 computes the
+ * last two stages of the h() function for a given index (either 2i or 2i+1).
+ * a, b, c, and d are the four bytes going into the last two stages.  For
+ * 128-bit keys, this is the entire h() function and a and c are the index
+ * preprocessed through q0 and q1 respectively; for longer keys they are the
+ * output of previous stages.  j is the index of the first key byte to use.
+ * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
+ * twice, doing the Psuedo-Hadamard Transform, and doing the necessary
+ * rotations.  Its parameters are: a, the array to write the results into,
+ * j, the index of the first output entry, k and l, the preprocessed indices
+ * for index 2i, and m and n, the preprocessed indices for index 2i+1.
+ * CALC_K256_2 expands CALC_K_2 to handle 256-bit keys, by doing two
+ * additional lookup-and-XOR stages.  The parameters a and b are the index
+ * preprocessed through q0 and q1 respectively; j is the index of the first
+ * key byte to use.  CALC_K256 is identical to CALC_K but for using the
+ * CALC_K256_2 macro instead of CALC_K_2. */
+
+#define CALC_K_2(a, b, c, d, j) \
+     mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \
+   ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \
+   ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \
+   ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]
+
+#define CALC_K(a, j, k, l, m, n) \
+   x = CALC_K_2 (k, l, k, l, 0); \
+   y = CALC_K_2 (m, n, m, n, 4); \
+   y = (y << 8) + (y >> 24); \
+   x += y; y += x; ctx->a[j] = x; \
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+#define CALC_K256_2(a, b, j) \
+   CALC_K_2 (q0[q1[b ^ key[(j) + 24]] ^ key[(j) + 16]], \
+            q1[q1[a ^ key[(j) + 25]] ^ key[(j) + 17]], \
+            q0[q0[a ^ key[(j) + 26]] ^ key[(j) + 18]], \
+            q1[q0[b ^ key[(j) + 27]] ^ key[(j) + 19]], j)
+
+#define CALC_K256(a, j, k, l, m, n) \
+   x = CALC_K256_2 (k, l, 0); \
+   y = CALC_K256_2 (m, n, 4); \
+   y = (y << 8) + (y >> 24); \
+   x += y; y += x; ctx->a[j] = x; \
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+\f
+
+
+/* Perform the key setup.  Note that this works only with 128- and 256-bit
+ * keys, despite the API that looks like it might support other sizes. */
+
+static gcry_err_code_t
+do_twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
+{
+  int i, j, k;
+
+  /* Temporaries for CALC_K. */
+  u32 x, y;
+
+  /* The S vector used to key the S-boxes, split up into individual bytes.
+   * 128-bit keys use only sa through sh; 256-bit use all of them. */
+  byte sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
+  byte si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
+  
+  /* Temporary for CALC_S. */
+  byte tmp;
+  
+  /* Flags for self-test. */
+  static int initialized = 0;
+  static const char *selftest_failed=0;
+
+  /* Check key length. */
+  if( ( ( keylen - 16 ) | 16 ) != 16 )
+    return GPG_ERR_INV_KEYLEN;
+
+  /* Do self-test if necessary. */
+  if (!initialized)
+    {
+      initialized = 1;
+      selftest_failed = selftest ();
+      if( selftest_failed )
+        log_error("%s\n", selftest_failed );
+    }
+  if( selftest_failed )
+    return GPG_ERR_SELFTEST_FAILED;
+
+  /* Compute the first two words of the S vector.  The magic numbers are
+   * the entries of the RS matrix, preprocessed through poly_to_exp.   The
+   * numbers in the comments are the original (polynomial form) matrix
+   * entries. */
+  CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+  CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+  CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+  CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+  CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+  CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+  CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+  CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+  CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+  CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+  CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+  CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+  CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+  CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+  CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+  CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+  if (keylen == 32)  /* 256-bit key */
+    {
+      /* Calculate the remaining two words of the S vector */
+      CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+      CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+      CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+      CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+      CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+      CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+      CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+      CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+      CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+      CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+      CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+      CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+      CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+      CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+      CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+      CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+      /* Compute the S-boxes. */
+      for(i=j=0,k=1; i < 256; i++, j += 2, k += 2 )
+        {
+          CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+       }
+
+      /* Calculate whitening and round subkeys.  The constants are
+       * indices of subkeys, preprocessed through q0 and q1. */
+      CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+      CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+      CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+      CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+      CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+      CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+      CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+      CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+      CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+      CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+      CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
+      CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+      CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
+      CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+      CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+      CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
+      CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+      CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+      CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
+      CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+    }
+  else 
+    {
+      /* Compute the S-boxes. */
+      for(i=j=0,k=1; i < 256; i++, j += 2, k += 2 )
+        {
+          CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+        }
+
+      /* Calculate whitening and round subkeys.  The constants are
+       * indices of subkeys, preprocessed through q0 and q1. */
+      CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+      CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+      CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+      CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+      CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+      CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+      CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+      CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+      CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+      CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+      CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
+      CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+      CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
+      CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+      CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+      CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
+      CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+      CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+      CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
+      CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+    }
+
+  return 0;
+}
+
+static gcry_err_code_t
+twofish_setkey (void *context, const byte *key, unsigned int keylen)
+{
+  TWOFISH_context *ctx = context;
+  int rc = do_twofish_setkey (ctx, key, keylen);
+  _gcry_burn_stack (23+6*sizeof(void*));
+  return rc;
+}
+
+
+\f
+/* Macros to compute the g() function in the encryption and decryption
+ * rounds.  G1 is the straight g() function; G2 includes the 8-bit
+ * rotation for the high 32-bit word. */
+
+#define G1(a) \
+     (ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \
+   ^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24])
+
+#define G2(b) \
+     (ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \
+   ^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24])
+
+/* Encryption and decryption Feistel rounds.  Each one calls the two g()
+ * macros, does the PHT, and performs the XOR and the appropriate bit
+ * rotations.  The parameters are the round number (used to select subkeys),
+ * and the four 32-bit chunks of the text. */
+
+#define ENCROUND(n, a, b, c, d) \
+   x = G1 (a); y = G2 (b); \
+   x += y; y += x + ctx->k[2 * (n) + 1]; \
+   (c) ^= x + ctx->k[2 * (n)]; \
+   (c) = ((c) >> 1) + ((c) << 31); \
+   (d) = (((d) << 1)+((d) >> 31)) ^ y
+
+#define DECROUND(n, a, b, c, d) \
+   x = G1 (a); y = G2 (b); \
+   x += y; y += x; \
+   (d) ^= y + ctx->k[2 * (n) + 1]; \
+   (d) = ((d) >> 1) + ((d) << 31); \
+   (c) = (((c) << 1)+((c) >> 31)); \
+   (c) ^= (x + ctx->k[2 * (n)])
+
+/* Encryption and decryption cycles; each one is simply two Feistel rounds
+ * with the 32-bit chunks re-ordered to simulate the "swap" */
+
+#define ENCCYCLE(n) \
+   ENCROUND (2 * (n), a, b, c, d); \
+   ENCROUND (2 * (n) + 1, c, d, a, b)
+
+#define DECCYCLE(n) \
+   DECROUND (2 * (n) + 1, c, d, a, b); \
+   DECROUND (2 * (n), a, b, c, d)
+
+/* Macros to convert the input and output bytes into 32-bit words,
+ * and simultaneously perform the whitening step.  INPACK packs word
+ * number n into the variable named by x, using whitening subkey number m.
+ * OUTUNPACK unpacks word number n from the variable named by x, using
+ * whitening subkey number m. */
+
+#define INPACK(n, x, m) \
+   x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \
+     ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m]
+
+#define OUTUNPACK(n, x, m) \
+   x ^= ctx->w[m]; \
+   out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \
+   out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24
+\f
+/* Encrypt one block.  in and out may be the same. */
+
+static void
+do_twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
+{
+  /* The four 32-bit chunks of the text. */
+  u32 a, b, c, d;
+
+  /* Temporaries used by the round function. */
+  u32 x, y;
+
+  /* Input whitening and packing. */
+  INPACK (0, a, 0);
+  INPACK (1, b, 1);
+  INPACK (2, c, 2);
+  INPACK (3, d, 3);
+
+  /* Encryption Feistel cycles. */
+  ENCCYCLE (0);
+  ENCCYCLE (1);
+  ENCCYCLE (2);
+  ENCCYCLE (3);
+  ENCCYCLE (4);
+  ENCCYCLE (5);
+  ENCCYCLE (6);
+  ENCCYCLE (7);
+
+  /* Output whitening and unpacking. */
+  OUTUNPACK (0, c, 4);
+  OUTUNPACK (1, d, 5);
+  OUTUNPACK (2, a, 6);
+  OUTUNPACK (3, b, 7);
+}
+
+static void
+twofish_encrypt (void *context, byte *out, const byte *in)
+{
+  TWOFISH_context *ctx = context;
+  do_twofish_encrypt (ctx, out, in);
+  _gcry_burn_stack (24+3*sizeof (void*));
+}
+
+\f
+/* Decrypt one block.  in and out may be the same. */
+
+static void
+do_twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
+{
+  /* The four 32-bit chunks of the text. */
+  u32 a, b, c, d;
+
+  /* Temporaries used by the round function. */
+  u32 x, y;
+
+  /* Input whitening and packing. */
+  INPACK (0, c, 4);
+  INPACK (1, d, 5);
+  INPACK (2, a, 6);
+  INPACK (3, b, 7);
+
+  /* Encryption Feistel cycles. */
+  DECCYCLE (7);
+  DECCYCLE (6);
+  DECCYCLE (5);
+  DECCYCLE (4);
+  DECCYCLE (3);
+  DECCYCLE (2);
+  DECCYCLE (1);
+  DECCYCLE (0);
+
+  /* Output whitening and unpacking. */
+  OUTUNPACK (0, a, 0);
+  OUTUNPACK (1, b, 1);
+  OUTUNPACK (2, c, 2);
+  OUTUNPACK (3, d, 3);
+}
+
+static void
+twofish_decrypt (void *context, byte *out, const byte *in)
+{
+  TWOFISH_context *ctx = context;
+
+  do_twofish_decrypt (ctx, out, in);
+  _gcry_burn_stack (24+3*sizeof (void*));
+}
+
+\f
+/* Test a single encryption and decryption with each key size. */
+
+static const char*
+selftest (void)
+{
+  TWOFISH_context ctx; /* Expanded key. */
+  byte scratch[16];    /* Encryption/decryption result buffer. */
+
+  /* Test vectors for single encryption/decryption.  Note that I am using
+   * the vectors from the Twofish paper's "known answer test", I=3 for
+   * 128-bit and I=4 for 256-bit, instead of the all-0 vectors from the
+   * "intermediate value test", because an all-0 key would trigger all the
+   * special cases in the RS matrix multiply, leaving the math untested. */
+  static  byte plaintext[16] = {
+    0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,
+    0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19
+  };
+  static byte key[16] = {
+    0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
+    0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A
+  };
+  static const byte ciphertext[16] = {
+    0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,
+    0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3
+  };
+  static byte plaintext_256[16] = {
+    0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F,
+    0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6
+  };
+  static byte key_256[32] = {
+    0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
+    0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
+    0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
+    0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F
+  };
+  static const byte ciphertext_256[16] = {
+    0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97,
+    0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA
+  };
+
+  twofish_setkey (&ctx, key, sizeof(key));
+  twofish_encrypt (&ctx, scratch, plaintext);
+  if (memcmp (scratch, ciphertext, sizeof (ciphertext)))
+    return "Twofish-128 test encryption failed.";
+  twofish_decrypt (&ctx, scratch, scratch);
+  if (memcmp (scratch, plaintext, sizeof (plaintext)))
+    return "Twofish-128 test decryption failed.";
+
+  twofish_setkey (&ctx, key_256, sizeof(key_256));
+  twofish_encrypt (&ctx, scratch, plaintext_256);
+  if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256)))
+    return "Twofish-256 test encryption failed.";
+  twofish_decrypt (&ctx, scratch, scratch);
+  if (memcmp (scratch, plaintext_256, sizeof (plaintext_256)))
+    return "Twofish-256 test decryption failed.";
+
+  return NULL;
+}
+\f
+/* More complete test program. This does 1000 encryptions and decryptions
+ * with each of 250 128-bit keys and 2000 encryptions and decryptions with
+ * each of 125 256-bit keys, using a feedback scheme similar to a Feistel
+ * cipher, so as to be sure of testing all the table entries pretty
+ * thoroughly. We keep changing the keys so as to get a more meaningful
+ * performance number, since the key setup is non-trivial for Twofish. */
+
+#ifdef TEST
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+int
+main()
+{
+  TWOFISH_context ctx;     /* Expanded key. */
+  int i, j;                /* Loop counters. */
+
+  const char *encrypt_msg; /* Message to print regarding encryption test;
+                            * the printf is done outside the loop to avoid
+                            * stuffing up the timing. */
+  clock_t timer; /* For computing elapsed time. */
+
+  /* Test buffer. */
+  byte buffer[4][16] = {
+    {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+     0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
+    {0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x5A, 0x69, 0x78,
+     0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0},
+    {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54 ,0x32, 0x10},
+    {0x01, 0x23, 0x45, 0x67, 0x76, 0x54 ,0x32, 0x10,
+     0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98}
+  };
+
+  /* Expected outputs for the million-operation test */
+  static const byte test_encrypt[4][16] = {
+    {0xC8, 0x23, 0xB8, 0xB7, 0x6B, 0xFE, 0x91, 0x13,
+     0x2F, 0xA7, 0x5E, 0xE6, 0x94, 0x77, 0x6F, 0x6B},
+    {0x90, 0x36, 0xD8, 0x29, 0xD5, 0x96, 0xC2, 0x8E,
+     0xE4, 0xFF, 0x76, 0xBC, 0xE5, 0x77, 0x88, 0x27},
+    {0xB8, 0x78, 0x69, 0xAF, 0x42, 0x8B, 0x48, 0x64,
+     0xF7, 0xE9, 0xF3, 0x9C, 0x42, 0x18, 0x7B, 0x73},
+    {0x7A, 0x88, 0xFB, 0xEB, 0x90, 0xA4, 0xB4, 0xA8,
+     0x43, 0xA3, 0x1D, 0xF1, 0x26, 0xC4, 0x53, 0x57}
+  };
+  static const byte test_decrypt[4][16] = {
+    {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+     0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
+    {0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x5A, 0x69, 0x78,
+     0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0},
+    {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54 ,0x32, 0x10},
+    {0x01, 0x23, 0x45, 0x67, 0x76, 0x54 ,0x32, 0x10,
+     0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98}
+  };
+
+  /* Start the timer ticking. */
+  timer = clock ();
+
+  /* Encryption test. */
+  for (i = 0; i < 125; i++) 
+    {
+      twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]));
+      for (j = 0; j < 1000; j++)
+        twofish_encrypt (&ctx, buffer[2], buffer[2]);
+      twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]));
+      for (j = 0; j < 1000; j++)
+        twofish_encrypt (&ctx, buffer[3], buffer[3]);
+      twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2);
+      for (j = 0; j < 1000; j++) {
+        twofish_encrypt (&ctx, buffer[0], buffer[0]);
+        twofish_encrypt (&ctx, buffer[1], buffer[1]);
+      }
+    }
+  encrypt_msg = memcmp (buffer, test_encrypt, sizeof (test_encrypt)) ?
+    "encryption failure!\n" : "encryption OK!\n";
+
+  /* Decryption test. */
+  for (i = 0; i < 125; i++) 
+    {
+      twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2);
+      for (j = 0; j < 1000; j++) {
+        twofish_decrypt (&ctx, buffer[0], buffer[0]);
+        twofish_decrypt (&ctx, buffer[1], buffer[1]);
+      }
+      twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]));
+      for (j = 0; j < 1000; j++)
+        twofish_decrypt (&ctx, buffer[3], buffer[3]);
+      twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]));
+      for (j = 0; j < 1000; j++)
+        twofish_decrypt (&ctx, buffer[2], buffer[2]);
+    }
+
+  /* Stop the timer, and print results. */
+  timer = clock () - timer;
+  printf (encrypt_msg);
+  printf (memcmp (buffer, test_decrypt, sizeof (test_decrypt)) ?
+          "decryption failure!\n" : "decryption OK!\n");
+  printf ("elapsed time: %.1f s.\n", (float) timer / CLOCKS_PER_SEC);
+
+  return 0;
+}
+
+#endif /* TEST */
+
+\f
+
+gcry_cipher_spec_t _gcry_cipher_spec_twofish =
+  {
+    "TWOFISH", NULL, NULL, 16, 256, sizeof (TWOFISH_context),
+    twofish_setkey, twofish_encrypt, twofish_decrypt
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_twofish128 =
+  {
+    "TWOFISH128", NULL, NULL, 16, 128, sizeof (TWOFISH_context),
+    twofish_setkey, twofish_encrypt, twofish_decrypt
+  };
diff --git a/grub-core/lib/libgcrypt/cipher/whirlpool.c b/grub-core/lib/libgcrypt/cipher/whirlpool.c
new file mode 100644 (file)
index 0000000..9b029ee
--- /dev/null
@@ -0,0 +1,1406 @@
+/* whirlpool.c - Whirlpool hashing algorithm
+ * Copyright (C) 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+/* This is an implementation of the Whirlpool hashing algorithm, which
+   has been developed by Vincent Rijmen and Paulo S. L. M. Barreto;
+   it's homepage is located at:
+   http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html.
+
+   The S-Boxes and the structure of the main transformation function,
+   which implements an optimized version of the algorithm, is taken
+   from the reference implementation available from
+   http://planeta.terra.com.br/informatica/paulobarreto/whirlpool.zip.  */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "types.h"
+#include "g10lib.h"
+#include "memory.h"
+#include "cipher.h"
+
+#include "bithelp.h"
+
+/* Size of a whirlpool block (in bytes).  */
+#define BLOCK_SIZE 64
+
+/* Number of rounds.  */
+#define R 10
+
+\f
+
+/* Types.  */
+typedef u64 whirlpool_block_t[BLOCK_SIZE / 8];
+
+typedef struct {
+  whirlpool_block_t hash_state;
+  unsigned char buffer[BLOCK_SIZE];
+  size_t count;
+  unsigned char length[32];
+} whirlpool_context_t;
+
+\f
+
+/* Macros. */
+
+/* Convert the the buffer BUFFER into a block BLOCK, using I as
+   counter.  */
+#define buffer_to_block(buffer, block, i) \
+  for (i = 0; i < 8; i++) \
+    (block)[i] = ((u64) (0 \
+                         | (((u64) (buffer)[i * 8 + 0]) << 56) \
+                         | (((u64) (buffer)[i * 8 + 1]) << 48) \
+                         | (((u64) (buffer)[i * 8 + 2]) << 40) \
+                         | (((u64) (buffer)[i * 8 + 3]) << 32) \
+                         | (((u64) (buffer)[i * 8 + 4]) << 24) \
+                         | (((u64) (buffer)[i * 8 + 5]) << 16) \
+                         | (((u64) (buffer)[i * 8 + 6]) <<  8) \
+                         | (((u64) (buffer)[i * 8 + 7]) <<  0)));
+
+/* Convert the block BLOCK into a buffer BUFFER, using I as
+   counter.  */
+#define block_to_buffer(buffer, block, i) \
+  for (i = 0; i < 8; i++) \
+    { \
+      (buffer)[i * 8 + 0] = (block[i] >> 56) & 0xFF; \
+      (buffer)[i * 8 + 1] = (block[i] >> 48) & 0xFF; \
+      (buffer)[i * 8 + 2] = (block[i] >> 40) & 0xFF; \
+      (buffer)[i * 8 + 3] = (block[i] >> 32) & 0xFF; \
+      (buffer)[i * 8 + 4] = (block[i] >> 24) & 0xFF; \
+      (buffer)[i * 8 + 5] = (block[i] >> 16) & 0xFF; \
+      (buffer)[i * 8 + 6] = (block[i] >>  8) & 0xFF; \
+      (buffer)[i * 8 + 7] = (block[i] >>  0) & 0xFF; \
+    }
+
+/* Copy the block BLOCK_SRC to BLOCK_DST, using I as counter.  */
+#define block_copy(block_dst, block_src, i) \
+  for (i = 0; i < 8; i++) \
+    block_dst[i] = block_src[i];
+
+/* XOR the block BLOCK_SRC into BLOCK_DST, using I as counter.  */
+#define block_xor(block_dst, block_src, i) \
+  for (i = 0; i < 8; i++) \
+    block_dst[i] ^= block_src[i];
+
+\f
+
+/* Round constants.  */
+static const u64 rc[R] =
+  {
+    U64_C (0x1823c6e887b8014f),
+    U64_C (0x36a6d2f5796f9152),
+    U64_C (0x60bc9b8ea30c7b35),
+    U64_C (0x1de0d7c22e4bfe57),
+    U64_C (0x157737e59ff04ada),
+    U64_C (0x58c9290ab1a06b85),
+    U64_C (0xbd5d10f4cb3e0567),
+    U64_C (0xe427418ba77d95d8),
+    U64_C (0xfbee7c66dd17479e),
+    U64_C (0xca2dbf07ad5a8333),
+  };
+  
+\f
+
+/* Main lookup boxes.  */
+static const u64 C0[256] =
+  {
+    U64_C (0x18186018c07830d8), U64_C (0x23238c2305af4626),
+    U64_C (0xc6c63fc67ef991b8), U64_C (0xe8e887e8136fcdfb),
+    U64_C (0x878726874ca113cb), U64_C (0xb8b8dab8a9626d11),
+    U64_C (0x0101040108050209), U64_C (0x4f4f214f426e9e0d),
+    U64_C (0x3636d836adee6c9b), U64_C (0xa6a6a2a6590451ff),
+    U64_C (0xd2d26fd2debdb90c), U64_C (0xf5f5f3f5fb06f70e),
+    U64_C (0x7979f979ef80f296), U64_C (0x6f6fa16f5fcede30),
+    U64_C (0x91917e91fcef3f6d), U64_C (0x52525552aa07a4f8),
+    U64_C (0x60609d6027fdc047), U64_C (0xbcbccabc89766535),
+    U64_C (0x9b9b569baccd2b37), U64_C (0x8e8e028e048c018a),
+    U64_C (0xa3a3b6a371155bd2), U64_C (0x0c0c300c603c186c),
+    U64_C (0x7b7bf17bff8af684), U64_C (0x3535d435b5e16a80),
+    U64_C (0x1d1d741de8693af5), U64_C (0xe0e0a7e05347ddb3),
+    U64_C (0xd7d77bd7f6acb321), U64_C (0xc2c22fc25eed999c),
+    U64_C (0x2e2eb82e6d965c43), U64_C (0x4b4b314b627a9629),
+    U64_C (0xfefedffea321e15d), U64_C (0x575741578216aed5),
+    U64_C (0x15155415a8412abd), U64_C (0x7777c1779fb6eee8),
+    U64_C (0x3737dc37a5eb6e92), U64_C (0xe5e5b3e57b56d79e),
+    U64_C (0x9f9f469f8cd92313), U64_C (0xf0f0e7f0d317fd23),
+    U64_C (0x4a4a354a6a7f9420), U64_C (0xdada4fda9e95a944),
+    U64_C (0x58587d58fa25b0a2), U64_C (0xc9c903c906ca8fcf),
+    U64_C (0x2929a429558d527c), U64_C (0x0a0a280a5022145a),
+    U64_C (0xb1b1feb1e14f7f50), U64_C (0xa0a0baa0691a5dc9),
+    U64_C (0x6b6bb16b7fdad614), U64_C (0x85852e855cab17d9),
+    U64_C (0xbdbdcebd8173673c), U64_C (0x5d5d695dd234ba8f),
+    U64_C (0x1010401080502090), U64_C (0xf4f4f7f4f303f507),
+    U64_C (0xcbcb0bcb16c08bdd), U64_C (0x3e3ef83eedc67cd3),
+    U64_C (0x0505140528110a2d), U64_C (0x676781671fe6ce78),
+    U64_C (0xe4e4b7e47353d597), U64_C (0x27279c2725bb4e02),
+    U64_C (0x4141194132588273), U64_C (0x8b8b168b2c9d0ba7),
+    U64_C (0xa7a7a6a7510153f6), U64_C (0x7d7de97dcf94fab2),
+    U64_C (0x95956e95dcfb3749), U64_C (0xd8d847d88e9fad56),
+    U64_C (0xfbfbcbfb8b30eb70), U64_C (0xeeee9fee2371c1cd),
+    U64_C (0x7c7ced7cc791f8bb), U64_C (0x6666856617e3cc71),
+    U64_C (0xdddd53dda68ea77b), U64_C (0x17175c17b84b2eaf),
+    U64_C (0x4747014702468e45), U64_C (0x9e9e429e84dc211a),
+    U64_C (0xcaca0fca1ec589d4), U64_C (0x2d2db42d75995a58),
+    U64_C (0xbfbfc6bf9179632e), U64_C (0x07071c07381b0e3f),
+    U64_C (0xadad8ead012347ac), U64_C (0x5a5a755aea2fb4b0),
+    U64_C (0x838336836cb51bef), U64_C (0x3333cc3385ff66b6),
+    U64_C (0x636391633ff2c65c), U64_C (0x02020802100a0412),
+    U64_C (0xaaaa92aa39384993), U64_C (0x7171d971afa8e2de),
+    U64_C (0xc8c807c80ecf8dc6), U64_C (0x19196419c87d32d1),
+    U64_C (0x494939497270923b), U64_C (0xd9d943d9869aaf5f),
+    U64_C (0xf2f2eff2c31df931), U64_C (0xe3e3abe34b48dba8),
+    U64_C (0x5b5b715be22ab6b9), U64_C (0x88881a8834920dbc),
+    U64_C (0x9a9a529aa4c8293e), U64_C (0x262698262dbe4c0b),
+    U64_C (0x3232c8328dfa64bf), U64_C (0xb0b0fab0e94a7d59),
+    U64_C (0xe9e983e91b6acff2), U64_C (0x0f0f3c0f78331e77),
+    U64_C (0xd5d573d5e6a6b733), U64_C (0x80803a8074ba1df4),
+    U64_C (0xbebec2be997c6127), U64_C (0xcdcd13cd26de87eb),
+    U64_C (0x3434d034bde46889), U64_C (0x48483d487a759032),
+    U64_C (0xffffdbffab24e354), U64_C (0x7a7af57af78ff48d),
+    U64_C (0x90907a90f4ea3d64), U64_C (0x5f5f615fc23ebe9d),
+    U64_C (0x202080201da0403d), U64_C (0x6868bd6867d5d00f),
+    U64_C (0x1a1a681ad07234ca), U64_C (0xaeae82ae192c41b7),
+    U64_C (0xb4b4eab4c95e757d), U64_C (0x54544d549a19a8ce),
+    U64_C (0x93937693ece53b7f), U64_C (0x222288220daa442f),
+    U64_C (0x64648d6407e9c863), U64_C (0xf1f1e3f1db12ff2a),
+    U64_C (0x7373d173bfa2e6cc), U64_C (0x12124812905a2482),
+    U64_C (0x40401d403a5d807a), U64_C (0x0808200840281048),
+    U64_C (0xc3c32bc356e89b95), U64_C (0xecec97ec337bc5df),
+    U64_C (0xdbdb4bdb9690ab4d), U64_C (0xa1a1bea1611f5fc0),
+    U64_C (0x8d8d0e8d1c830791), U64_C (0x3d3df43df5c97ac8),
+    U64_C (0x97976697ccf1335b), U64_C (0x0000000000000000),
+    U64_C (0xcfcf1bcf36d483f9), U64_C (0x2b2bac2b4587566e),
+    U64_C (0x7676c57697b3ece1), U64_C (0x8282328264b019e6),
+    U64_C (0xd6d67fd6fea9b128), U64_C (0x1b1b6c1bd87736c3),
+    U64_C (0xb5b5eeb5c15b7774), U64_C (0xafaf86af112943be),
+    U64_C (0x6a6ab56a77dfd41d), U64_C (0x50505d50ba0da0ea),
+    U64_C (0x45450945124c8a57), U64_C (0xf3f3ebf3cb18fb38),
+    U64_C (0x3030c0309df060ad), U64_C (0xefef9bef2b74c3c4),
+    U64_C (0x3f3ffc3fe5c37eda), U64_C (0x55554955921caac7),
+    U64_C (0xa2a2b2a2791059db), U64_C (0xeaea8fea0365c9e9),
+    U64_C (0x656589650fecca6a), U64_C (0xbabad2bab9686903),
+    U64_C (0x2f2fbc2f65935e4a), U64_C (0xc0c027c04ee79d8e),
+    U64_C (0xdede5fdebe81a160), U64_C (0x1c1c701ce06c38fc),
+    U64_C (0xfdfdd3fdbb2ee746), U64_C (0x4d4d294d52649a1f),
+    U64_C (0x92927292e4e03976), U64_C (0x7575c9758fbceafa),
+    U64_C (0x06061806301e0c36), U64_C (0x8a8a128a249809ae),
+    U64_C (0xb2b2f2b2f940794b), U64_C (0xe6e6bfe66359d185),
+    U64_C (0x0e0e380e70361c7e), U64_C (0x1f1f7c1ff8633ee7),
+    U64_C (0x6262956237f7c455), U64_C (0xd4d477d4eea3b53a),
+    U64_C (0xa8a89aa829324d81), U64_C (0x96966296c4f43152),
+    U64_C (0xf9f9c3f99b3aef62), U64_C (0xc5c533c566f697a3),
+    U64_C (0x2525942535b14a10), U64_C (0x59597959f220b2ab),
+    U64_C (0x84842a8454ae15d0), U64_C (0x7272d572b7a7e4c5),
+    U64_C (0x3939e439d5dd72ec), U64_C (0x4c4c2d4c5a619816),
+    U64_C (0x5e5e655eca3bbc94), U64_C (0x7878fd78e785f09f),
+    U64_C (0x3838e038ddd870e5), U64_C (0x8c8c0a8c14860598),
+    U64_C (0xd1d163d1c6b2bf17), U64_C (0xa5a5aea5410b57e4),
+    U64_C (0xe2e2afe2434dd9a1), U64_C (0x616199612ff8c24e),
+    U64_C (0xb3b3f6b3f1457b42), U64_C (0x2121842115a54234),
+    U64_C (0x9c9c4a9c94d62508), U64_C (0x1e1e781ef0663cee),
+    U64_C (0x4343114322528661), U64_C (0xc7c73bc776fc93b1),
+    U64_C (0xfcfcd7fcb32be54f), U64_C (0x0404100420140824),
+    U64_C (0x51515951b208a2e3), U64_C (0x99995e99bcc72f25),
+    U64_C (0x6d6da96d4fc4da22), U64_C (0x0d0d340d68391a65),
+    U64_C (0xfafacffa8335e979), U64_C (0xdfdf5bdfb684a369),
+    U64_C (0x7e7ee57ed79bfca9), U64_C (0x242490243db44819),
+    U64_C (0x3b3bec3bc5d776fe), U64_C (0xabab96ab313d4b9a),
+    U64_C (0xcece1fce3ed181f0), U64_C (0x1111441188552299),
+    U64_C (0x8f8f068f0c890383), U64_C (0x4e4e254e4a6b9c04),
+    U64_C (0xb7b7e6b7d1517366), U64_C (0xebeb8beb0b60cbe0),
+    U64_C (0x3c3cf03cfdcc78c1), U64_C (0x81813e817cbf1ffd),
+    U64_C (0x94946a94d4fe3540), U64_C (0xf7f7fbf7eb0cf31c),
+    U64_C (0xb9b9deb9a1676f18), U64_C (0x13134c13985f268b),
+    U64_C (0x2c2cb02c7d9c5851), U64_C (0xd3d36bd3d6b8bb05),
+    U64_C (0xe7e7bbe76b5cd38c), U64_C (0x6e6ea56e57cbdc39),
+    U64_C (0xc4c437c46ef395aa), U64_C (0x03030c03180f061b),
+    U64_C (0x565645568a13acdc), U64_C (0x44440d441a49885e),
+    U64_C (0x7f7fe17fdf9efea0), U64_C (0xa9a99ea921374f88),
+    U64_C (0x2a2aa82a4d825467), U64_C (0xbbbbd6bbb16d6b0a),
+    U64_C (0xc1c123c146e29f87), U64_C (0x53535153a202a6f1),
+    U64_C (0xdcdc57dcae8ba572), U64_C (0x0b0b2c0b58271653),
+    U64_C (0x9d9d4e9d9cd32701), U64_C (0x6c6cad6c47c1d82b),
+    U64_C (0x3131c43195f562a4), U64_C (0x7474cd7487b9e8f3),
+    U64_C (0xf6f6fff6e309f115), U64_C (0x464605460a438c4c),
+    U64_C (0xacac8aac092645a5), U64_C (0x89891e893c970fb5),
+    U64_C (0x14145014a04428b4), U64_C (0xe1e1a3e15b42dfba),
+    U64_C (0x16165816b04e2ca6), U64_C (0x3a3ae83acdd274f7),
+    U64_C (0x6969b9696fd0d206), U64_C (0x09092409482d1241),
+    U64_C (0x7070dd70a7ade0d7), U64_C (0xb6b6e2b6d954716f),
+    U64_C (0xd0d067d0ceb7bd1e), U64_C (0xeded93ed3b7ec7d6),
+    U64_C (0xcccc17cc2edb85e2), U64_C (0x424215422a578468),
+    U64_C (0x98985a98b4c22d2c), U64_C (0xa4a4aaa4490e55ed),
+    U64_C (0x2828a0285d885075), U64_C (0x5c5c6d5cda31b886),
+    U64_C (0xf8f8c7f8933fed6b), U64_C (0x8686228644a411c2),
+  };
+
+static const u64 C1[256] =
+  {
+    U64_C (0xd818186018c07830), U64_C (0x2623238c2305af46),
+    U64_C (0xb8c6c63fc67ef991), U64_C (0xfbe8e887e8136fcd),
+    U64_C (0xcb878726874ca113), U64_C (0x11b8b8dab8a9626d),
+    U64_C (0x0901010401080502), U64_C (0x0d4f4f214f426e9e),
+    U64_C (0x9b3636d836adee6c), U64_C (0xffa6a6a2a6590451),
+    U64_C (0x0cd2d26fd2debdb9), U64_C (0x0ef5f5f3f5fb06f7),
+    U64_C (0x967979f979ef80f2), U64_C (0x306f6fa16f5fcede),
+    U64_C (0x6d91917e91fcef3f), U64_C (0xf852525552aa07a4),
+    U64_C (0x4760609d6027fdc0), U64_C (0x35bcbccabc897665),
+    U64_C (0x379b9b569baccd2b), U64_C (0x8a8e8e028e048c01),
+    U64_C (0xd2a3a3b6a371155b), U64_C (0x6c0c0c300c603c18),
+    U64_C (0x847b7bf17bff8af6), U64_C (0x803535d435b5e16a),
+    U64_C (0xf51d1d741de8693a), U64_C (0xb3e0e0a7e05347dd),
+    U64_C (0x21d7d77bd7f6acb3), U64_C (0x9cc2c22fc25eed99),
+    U64_C (0x432e2eb82e6d965c), U64_C (0x294b4b314b627a96),
+    U64_C (0x5dfefedffea321e1), U64_C (0xd5575741578216ae),
+    U64_C (0xbd15155415a8412a), U64_C (0xe87777c1779fb6ee),
+    U64_C (0x923737dc37a5eb6e), U64_C (0x9ee5e5b3e57b56d7),
+    U64_C (0x139f9f469f8cd923), U64_C (0x23f0f0e7f0d317fd),
+    U64_C (0x204a4a354a6a7f94), U64_C (0x44dada4fda9e95a9),
+    U64_C (0xa258587d58fa25b0), U64_C (0xcfc9c903c906ca8f),
+    U64_C (0x7c2929a429558d52), U64_C (0x5a0a0a280a502214),
+    U64_C (0x50b1b1feb1e14f7f), U64_C (0xc9a0a0baa0691a5d),
+    U64_C (0x146b6bb16b7fdad6), U64_C (0xd985852e855cab17),
+    U64_C (0x3cbdbdcebd817367), U64_C (0x8f5d5d695dd234ba),
+    U64_C (0x9010104010805020), U64_C (0x07f4f4f7f4f303f5),
+    U64_C (0xddcbcb0bcb16c08b), U64_C (0xd33e3ef83eedc67c),
+    U64_C (0x2d0505140528110a), U64_C (0x78676781671fe6ce),
+    U64_C (0x97e4e4b7e47353d5), U64_C (0x0227279c2725bb4e),
+    U64_C (0x7341411941325882), U64_C (0xa78b8b168b2c9d0b),
+    U64_C (0xf6a7a7a6a7510153), U64_C (0xb27d7de97dcf94fa),
+    U64_C (0x4995956e95dcfb37), U64_C (0x56d8d847d88e9fad),
+    U64_C (0x70fbfbcbfb8b30eb), U64_C (0xcdeeee9fee2371c1),
+    U64_C (0xbb7c7ced7cc791f8), U64_C (0x716666856617e3cc),
+    U64_C (0x7bdddd53dda68ea7), U64_C (0xaf17175c17b84b2e),
+    U64_C (0x454747014702468e), U64_C (0x1a9e9e429e84dc21),
+    U64_C (0xd4caca0fca1ec589), U64_C (0x582d2db42d75995a),
+    U64_C (0x2ebfbfc6bf917963), U64_C (0x3f07071c07381b0e),
+    U64_C (0xacadad8ead012347), U64_C (0xb05a5a755aea2fb4),
+    U64_C (0xef838336836cb51b), U64_C (0xb63333cc3385ff66),
+    U64_C (0x5c636391633ff2c6), U64_C (0x1202020802100a04),
+    U64_C (0x93aaaa92aa393849), U64_C (0xde7171d971afa8e2),
+    U64_C (0xc6c8c807c80ecf8d), U64_C (0xd119196419c87d32),
+    U64_C (0x3b49493949727092), U64_C (0x5fd9d943d9869aaf),
+    U64_C (0x31f2f2eff2c31df9), U64_C (0xa8e3e3abe34b48db),
+    U64_C (0xb95b5b715be22ab6), U64_C (0xbc88881a8834920d),
+    U64_C (0x3e9a9a529aa4c829), U64_C (0x0b262698262dbe4c),
+    U64_C (0xbf3232c8328dfa64), U64_C (0x59b0b0fab0e94a7d),
+    U64_C (0xf2e9e983e91b6acf), U64_C (0x770f0f3c0f78331e),
+    U64_C (0x33d5d573d5e6a6b7), U64_C (0xf480803a8074ba1d),
+    U64_C (0x27bebec2be997c61), U64_C (0xebcdcd13cd26de87),
+    U64_C (0x893434d034bde468), U64_C (0x3248483d487a7590),
+    U64_C (0x54ffffdbffab24e3), U64_C (0x8d7a7af57af78ff4),
+    U64_C (0x6490907a90f4ea3d), U64_C (0x9d5f5f615fc23ebe),
+    U64_C (0x3d202080201da040), U64_C (0x0f6868bd6867d5d0),
+    U64_C (0xca1a1a681ad07234), U64_C (0xb7aeae82ae192c41),
+    U64_C (0x7db4b4eab4c95e75), U64_C (0xce54544d549a19a8),
+    U64_C (0x7f93937693ece53b), U64_C (0x2f222288220daa44),
+    U64_C (0x6364648d6407e9c8), U64_C (0x2af1f1e3f1db12ff),
+    U64_C (0xcc7373d173bfa2e6), U64_C (0x8212124812905a24),
+    U64_C (0x7a40401d403a5d80), U64_C (0x4808082008402810),
+    U64_C (0x95c3c32bc356e89b), U64_C (0xdfecec97ec337bc5),
+    U64_C (0x4ddbdb4bdb9690ab), U64_C (0xc0a1a1bea1611f5f),
+    U64_C (0x918d8d0e8d1c8307), U64_C (0xc83d3df43df5c97a),
+    U64_C (0x5b97976697ccf133), U64_C (0x0000000000000000),
+    U64_C (0xf9cfcf1bcf36d483), U64_C (0x6e2b2bac2b458756),
+    U64_C (0xe17676c57697b3ec), U64_C (0xe68282328264b019),
+    U64_C (0x28d6d67fd6fea9b1), U64_C (0xc31b1b6c1bd87736),
+    U64_C (0x74b5b5eeb5c15b77), U64_C (0xbeafaf86af112943),
+    U64_C (0x1d6a6ab56a77dfd4), U64_C (0xea50505d50ba0da0),
+    U64_C (0x5745450945124c8a), U64_C (0x38f3f3ebf3cb18fb),
+    U64_C (0xad3030c0309df060), U64_C (0xc4efef9bef2b74c3),
+    U64_C (0xda3f3ffc3fe5c37e), U64_C (0xc755554955921caa),
+    U64_C (0xdba2a2b2a2791059), U64_C (0xe9eaea8fea0365c9),
+    U64_C (0x6a656589650fecca), U64_C (0x03babad2bab96869),
+    U64_C (0x4a2f2fbc2f65935e), U64_C (0x8ec0c027c04ee79d),
+    U64_C (0x60dede5fdebe81a1), U64_C (0xfc1c1c701ce06c38),
+    U64_C (0x46fdfdd3fdbb2ee7), U64_C (0x1f4d4d294d52649a),
+    U64_C (0x7692927292e4e039), U64_C (0xfa7575c9758fbcea),
+    U64_C (0x3606061806301e0c), U64_C (0xae8a8a128a249809),
+    U64_C (0x4bb2b2f2b2f94079), U64_C (0x85e6e6bfe66359d1),
+    U64_C (0x7e0e0e380e70361c), U64_C (0xe71f1f7c1ff8633e),
+    U64_C (0x556262956237f7c4), U64_C (0x3ad4d477d4eea3b5),
+    U64_C (0x81a8a89aa829324d), U64_C (0x5296966296c4f431),
+    U64_C (0x62f9f9c3f99b3aef), U64_C (0xa3c5c533c566f697),
+    U64_C (0x102525942535b14a), U64_C (0xab59597959f220b2),
+    U64_C (0xd084842a8454ae15), U64_C (0xc57272d572b7a7e4),
+    U64_C (0xec3939e439d5dd72), U64_C (0x164c4c2d4c5a6198),
+    U64_C (0x945e5e655eca3bbc), U64_C (0x9f7878fd78e785f0),
+    U64_C (0xe53838e038ddd870), U64_C (0x988c8c0a8c148605),
+    U64_C (0x17d1d163d1c6b2bf), U64_C (0xe4a5a5aea5410b57),
+    U64_C (0xa1e2e2afe2434dd9), U64_C (0x4e616199612ff8c2),
+    U64_C (0x42b3b3f6b3f1457b), U64_C (0x342121842115a542),
+    U64_C (0x089c9c4a9c94d625), U64_C (0xee1e1e781ef0663c),
+    U64_C (0x6143431143225286), U64_C (0xb1c7c73bc776fc93),
+    U64_C (0x4ffcfcd7fcb32be5), U64_C (0x2404041004201408),
+    U64_C (0xe351515951b208a2), U64_C (0x2599995e99bcc72f),
+    U64_C (0x226d6da96d4fc4da), U64_C (0x650d0d340d68391a),
+    U64_C (0x79fafacffa8335e9), U64_C (0x69dfdf5bdfb684a3),
+    U64_C (0xa97e7ee57ed79bfc), U64_C (0x19242490243db448),
+    U64_C (0xfe3b3bec3bc5d776), U64_C (0x9aabab96ab313d4b),
+    U64_C (0xf0cece1fce3ed181), U64_C (0x9911114411885522),
+    U64_C (0x838f8f068f0c8903), U64_C (0x044e4e254e4a6b9c),
+    U64_C (0x66b7b7e6b7d15173), U64_C (0xe0ebeb8beb0b60cb),
+    U64_C (0xc13c3cf03cfdcc78), U64_C (0xfd81813e817cbf1f),
+    U64_C (0x4094946a94d4fe35), U64_C (0x1cf7f7fbf7eb0cf3),
+    U64_C (0x18b9b9deb9a1676f), U64_C (0x8b13134c13985f26),
+    U64_C (0x512c2cb02c7d9c58), U64_C (0x05d3d36bd3d6b8bb),
+    U64_C (0x8ce7e7bbe76b5cd3), U64_C (0x396e6ea56e57cbdc),
+    U64_C (0xaac4c437c46ef395), U64_C (0x1b03030c03180f06),
+    U64_C (0xdc565645568a13ac), U64_C (0x5e44440d441a4988),
+    U64_C (0xa07f7fe17fdf9efe), U64_C (0x88a9a99ea921374f),
+    U64_C (0x672a2aa82a4d8254), U64_C (0x0abbbbd6bbb16d6b),
+    U64_C (0x87c1c123c146e29f), U64_C (0xf153535153a202a6),
+    U64_C (0x72dcdc57dcae8ba5), U64_C (0x530b0b2c0b582716),
+    U64_C (0x019d9d4e9d9cd327), U64_C (0x2b6c6cad6c47c1d8),
+    U64_C (0xa43131c43195f562), U64_C (0xf37474cd7487b9e8),
+    U64_C (0x15f6f6fff6e309f1), U64_C (0x4c464605460a438c),
+    U64_C (0xa5acac8aac092645), U64_C (0xb589891e893c970f),
+    U64_C (0xb414145014a04428), U64_C (0xbae1e1a3e15b42df),
+    U64_C (0xa616165816b04e2c), U64_C (0xf73a3ae83acdd274),
+    U64_C (0x066969b9696fd0d2), U64_C (0x4109092409482d12),
+    U64_C (0xd77070dd70a7ade0), U64_C (0x6fb6b6e2b6d95471),
+    U64_C (0x1ed0d067d0ceb7bd), U64_C (0xd6eded93ed3b7ec7),
+    U64_C (0xe2cccc17cc2edb85), U64_C (0x68424215422a5784),
+    U64_C (0x2c98985a98b4c22d), U64_C (0xeda4a4aaa4490e55),
+    U64_C (0x752828a0285d8850), U64_C (0x865c5c6d5cda31b8),
+    U64_C (0x6bf8f8c7f8933fed), U64_C (0xc28686228644a411),
+  };
+
+static const u64 C2[256] =
+  {
+    U64_C (0x30d818186018c078), U64_C (0x462623238c2305af),
+    U64_C (0x91b8c6c63fc67ef9), U64_C (0xcdfbe8e887e8136f),
+    U64_C (0x13cb878726874ca1), U64_C (0x6d11b8b8dab8a962),
+    U64_C (0x0209010104010805), U64_C (0x9e0d4f4f214f426e),
+    U64_C (0x6c9b3636d836adee), U64_C (0x51ffa6a6a2a65904),
+    U64_C (0xb90cd2d26fd2debd), U64_C (0xf70ef5f5f3f5fb06),
+    U64_C (0xf2967979f979ef80), U64_C (0xde306f6fa16f5fce),
+    U64_C (0x3f6d91917e91fcef), U64_C (0xa4f852525552aa07),
+    U64_C (0xc04760609d6027fd), U64_C (0x6535bcbccabc8976),
+    U64_C (0x2b379b9b569baccd), U64_C (0x018a8e8e028e048c),
+    U64_C (0x5bd2a3a3b6a37115), U64_C (0x186c0c0c300c603c),
+    U64_C (0xf6847b7bf17bff8a), U64_C (0x6a803535d435b5e1),
+    U64_C (0x3af51d1d741de869), U64_C (0xddb3e0e0a7e05347),
+    U64_C (0xb321d7d77bd7f6ac), U64_C (0x999cc2c22fc25eed),
+    U64_C (0x5c432e2eb82e6d96), U64_C (0x96294b4b314b627a),
+    U64_C (0xe15dfefedffea321), U64_C (0xaed5575741578216),
+    U64_C (0x2abd15155415a841), U64_C (0xeee87777c1779fb6),
+    U64_C (0x6e923737dc37a5eb), U64_C (0xd79ee5e5b3e57b56),
+    U64_C (0x23139f9f469f8cd9), U64_C (0xfd23f0f0e7f0d317),
+    U64_C (0x94204a4a354a6a7f), U64_C (0xa944dada4fda9e95),
+    U64_C (0xb0a258587d58fa25), U64_C (0x8fcfc9c903c906ca),
+    U64_C (0x527c2929a429558d), U64_C (0x145a0a0a280a5022),
+    U64_C (0x7f50b1b1feb1e14f), U64_C (0x5dc9a0a0baa0691a),
+    U64_C (0xd6146b6bb16b7fda), U64_C (0x17d985852e855cab),
+    U64_C (0x673cbdbdcebd8173), U64_C (0xba8f5d5d695dd234),
+    U64_C (0x2090101040108050), U64_C (0xf507f4f4f7f4f303),
+    U64_C (0x8bddcbcb0bcb16c0), U64_C (0x7cd33e3ef83eedc6),
+    U64_C (0x0a2d050514052811), U64_C (0xce78676781671fe6),
+    U64_C (0xd597e4e4b7e47353), U64_C (0x4e0227279c2725bb),
+    U64_C (0x8273414119413258), U64_C (0x0ba78b8b168b2c9d),
+    U64_C (0x53f6a7a7a6a75101), U64_C (0xfab27d7de97dcf94),
+    U64_C (0x374995956e95dcfb), U64_C (0xad56d8d847d88e9f),
+    U64_C (0xeb70fbfbcbfb8b30), U64_C (0xc1cdeeee9fee2371),
+    U64_C (0xf8bb7c7ced7cc791), U64_C (0xcc716666856617e3),
+    U64_C (0xa77bdddd53dda68e), U64_C (0x2eaf17175c17b84b),
+    U64_C (0x8e45474701470246), U64_C (0x211a9e9e429e84dc),
+    U64_C (0x89d4caca0fca1ec5), U64_C (0x5a582d2db42d7599),
+    U64_C (0x632ebfbfc6bf9179), U64_C (0x0e3f07071c07381b),
+    U64_C (0x47acadad8ead0123), U64_C (0xb4b05a5a755aea2f),
+    U64_C (0x1bef838336836cb5), U64_C (0x66b63333cc3385ff),
+    U64_C (0xc65c636391633ff2), U64_C (0x041202020802100a),
+    U64_C (0x4993aaaa92aa3938), U64_C (0xe2de7171d971afa8),
+    U64_C (0x8dc6c8c807c80ecf), U64_C (0x32d119196419c87d),
+    U64_C (0x923b494939497270), U64_C (0xaf5fd9d943d9869a),
+    U64_C (0xf931f2f2eff2c31d), U64_C (0xdba8e3e3abe34b48),
+    U64_C (0xb6b95b5b715be22a), U64_C (0x0dbc88881a883492),
+    U64_C (0x293e9a9a529aa4c8), U64_C (0x4c0b262698262dbe),
+    U64_C (0x64bf3232c8328dfa), U64_C (0x7d59b0b0fab0e94a),
+    U64_C (0xcff2e9e983e91b6a), U64_C (0x1e770f0f3c0f7833),
+    U64_C (0xb733d5d573d5e6a6), U64_C (0x1df480803a8074ba),
+    U64_C (0x6127bebec2be997c), U64_C (0x87ebcdcd13cd26de),
+    U64_C (0x68893434d034bde4), U64_C (0x903248483d487a75),
+    U64_C (0xe354ffffdbffab24), U64_C (0xf48d7a7af57af78f),
+    U64_C (0x3d6490907a90f4ea), U64_C (0xbe9d5f5f615fc23e),
+    U64_C (0x403d202080201da0), U64_C (0xd00f6868bd6867d5),
+    U64_C (0x34ca1a1a681ad072), U64_C (0x41b7aeae82ae192c),
+    U64_C (0x757db4b4eab4c95e), U64_C (0xa8ce54544d549a19),
+    U64_C (0x3b7f93937693ece5), U64_C (0x442f222288220daa),
+    U64_C (0xc86364648d6407e9), U64_C (0xff2af1f1e3f1db12),
+    U64_C (0xe6cc7373d173bfa2), U64_C (0x248212124812905a),
+    U64_C (0x807a40401d403a5d), U64_C (0x1048080820084028),
+    U64_C (0x9b95c3c32bc356e8), U64_C (0xc5dfecec97ec337b),
+    U64_C (0xab4ddbdb4bdb9690), U64_C (0x5fc0a1a1bea1611f),
+    U64_C (0x07918d8d0e8d1c83), U64_C (0x7ac83d3df43df5c9),
+    U64_C (0x335b97976697ccf1), U64_C (0x0000000000000000),
+    U64_C (0x83f9cfcf1bcf36d4), U64_C (0x566e2b2bac2b4587),
+    U64_C (0xece17676c57697b3), U64_C (0x19e68282328264b0),
+    U64_C (0xb128d6d67fd6fea9), U64_C (0x36c31b1b6c1bd877),
+    U64_C (0x7774b5b5eeb5c15b), U64_C (0x43beafaf86af1129),
+    U64_C (0xd41d6a6ab56a77df), U64_C (0xa0ea50505d50ba0d),
+    U64_C (0x8a5745450945124c), U64_C (0xfb38f3f3ebf3cb18),
+    U64_C (0x60ad3030c0309df0), U64_C (0xc3c4efef9bef2b74),
+    U64_C (0x7eda3f3ffc3fe5c3), U64_C (0xaac755554955921c),
+    U64_C (0x59dba2a2b2a27910), U64_C (0xc9e9eaea8fea0365),
+    U64_C (0xca6a656589650fec), U64_C (0x6903babad2bab968),
+    U64_C (0x5e4a2f2fbc2f6593), U64_C (0x9d8ec0c027c04ee7),
+    U64_C (0xa160dede5fdebe81), U64_C (0x38fc1c1c701ce06c),
+    U64_C (0xe746fdfdd3fdbb2e), U64_C (0x9a1f4d4d294d5264),
+    U64_C (0x397692927292e4e0), U64_C (0xeafa7575c9758fbc),
+    U64_C (0x0c3606061806301e), U64_C (0x09ae8a8a128a2498),
+    U64_C (0x794bb2b2f2b2f940), U64_C (0xd185e6e6bfe66359),
+    U64_C (0x1c7e0e0e380e7036), U64_C (0x3ee71f1f7c1ff863),
+    U64_C (0xc4556262956237f7), U64_C (0xb53ad4d477d4eea3),
+    U64_C (0x4d81a8a89aa82932), U64_C (0x315296966296c4f4),
+    U64_C (0xef62f9f9c3f99b3a), U64_C (0x97a3c5c533c566f6),
+    U64_C (0x4a102525942535b1), U64_C (0xb2ab59597959f220),
+    U64_C (0x15d084842a8454ae), U64_C (0xe4c57272d572b7a7),
+    U64_C (0x72ec3939e439d5dd), U64_C (0x98164c4c2d4c5a61),
+    U64_C (0xbc945e5e655eca3b), U64_C (0xf09f7878fd78e785),
+    U64_C (0x70e53838e038ddd8), U64_C (0x05988c8c0a8c1486),
+    U64_C (0xbf17d1d163d1c6b2), U64_C (0x57e4a5a5aea5410b),
+    U64_C (0xd9a1e2e2afe2434d), U64_C (0xc24e616199612ff8),
+    U64_C (0x7b42b3b3f6b3f145), U64_C (0x42342121842115a5),
+    U64_C (0x25089c9c4a9c94d6), U64_C (0x3cee1e1e781ef066),
+    U64_C (0x8661434311432252), U64_C (0x93b1c7c73bc776fc),
+    U64_C (0xe54ffcfcd7fcb32b), U64_C (0x0824040410042014),
+    U64_C (0xa2e351515951b208), U64_C (0x2f2599995e99bcc7),
+    U64_C (0xda226d6da96d4fc4), U64_C (0x1a650d0d340d6839),
+    U64_C (0xe979fafacffa8335), U64_C (0xa369dfdf5bdfb684),
+    U64_C (0xfca97e7ee57ed79b), U64_C (0x4819242490243db4),
+    U64_C (0x76fe3b3bec3bc5d7), U64_C (0x4b9aabab96ab313d),
+    U64_C (0x81f0cece1fce3ed1), U64_C (0x2299111144118855),
+    U64_C (0x03838f8f068f0c89), U64_C (0x9c044e4e254e4a6b),
+    U64_C (0x7366b7b7e6b7d151), U64_C (0xcbe0ebeb8beb0b60),
+    U64_C (0x78c13c3cf03cfdcc), U64_C (0x1ffd81813e817cbf),
+    U64_C (0x354094946a94d4fe), U64_C (0xf31cf7f7fbf7eb0c),
+    U64_C (0x6f18b9b9deb9a167), U64_C (0x268b13134c13985f),
+    U64_C (0x58512c2cb02c7d9c), U64_C (0xbb05d3d36bd3d6b8),
+    U64_C (0xd38ce7e7bbe76b5c), U64_C (0xdc396e6ea56e57cb),
+    U64_C (0x95aac4c437c46ef3), U64_C (0x061b03030c03180f),
+    U64_C (0xacdc565645568a13), U64_C (0x885e44440d441a49),
+    U64_C (0xfea07f7fe17fdf9e), U64_C (0x4f88a9a99ea92137),
+    U64_C (0x54672a2aa82a4d82), U64_C (0x6b0abbbbd6bbb16d),
+    U64_C (0x9f87c1c123c146e2), U64_C (0xa6f153535153a202),
+    U64_C (0xa572dcdc57dcae8b), U64_C (0x16530b0b2c0b5827),
+    U64_C (0x27019d9d4e9d9cd3), U64_C (0xd82b6c6cad6c47c1),
+    U64_C (0x62a43131c43195f5), U64_C (0xe8f37474cd7487b9),
+    U64_C (0xf115f6f6fff6e309), U64_C (0x8c4c464605460a43),
+    U64_C (0x45a5acac8aac0926), U64_C (0x0fb589891e893c97),
+    U64_C (0x28b414145014a044), U64_C (0xdfbae1e1a3e15b42),
+    U64_C (0x2ca616165816b04e), U64_C (0x74f73a3ae83acdd2),
+    U64_C (0xd2066969b9696fd0), U64_C (0x124109092409482d),
+    U64_C (0xe0d77070dd70a7ad), U64_C (0x716fb6b6e2b6d954),
+    U64_C (0xbd1ed0d067d0ceb7), U64_C (0xc7d6eded93ed3b7e),
+    U64_C (0x85e2cccc17cc2edb), U64_C (0x8468424215422a57),
+    U64_C (0x2d2c98985a98b4c2), U64_C (0x55eda4a4aaa4490e),
+    U64_C (0x50752828a0285d88), U64_C (0xb8865c5c6d5cda31),
+    U64_C (0xed6bf8f8c7f8933f), U64_C (0x11c28686228644a4),
+  };
+
+static const u64 C3[256] =
+  {
+    U64_C (0x7830d818186018c0), U64_C (0xaf462623238c2305),
+    U64_C (0xf991b8c6c63fc67e), U64_C (0x6fcdfbe8e887e813),
+    U64_C (0xa113cb878726874c), U64_C (0x626d11b8b8dab8a9),
+    U64_C (0x0502090101040108), U64_C (0x6e9e0d4f4f214f42),
+    U64_C (0xee6c9b3636d836ad), U64_C (0x0451ffa6a6a2a659),
+    U64_C (0xbdb90cd2d26fd2de), U64_C (0x06f70ef5f5f3f5fb),
+    U64_C (0x80f2967979f979ef), U64_C (0xcede306f6fa16f5f),
+    U64_C (0xef3f6d91917e91fc), U64_C (0x07a4f852525552aa),
+    U64_C (0xfdc04760609d6027), U64_C (0x766535bcbccabc89),
+    U64_C (0xcd2b379b9b569bac), U64_C (0x8c018a8e8e028e04),
+    U64_C (0x155bd2a3a3b6a371), U64_C (0x3c186c0c0c300c60),
+    U64_C (0x8af6847b7bf17bff), U64_C (0xe16a803535d435b5),
+    U64_C (0x693af51d1d741de8), U64_C (0x47ddb3e0e0a7e053),
+    U64_C (0xacb321d7d77bd7f6), U64_C (0xed999cc2c22fc25e),
+    U64_C (0x965c432e2eb82e6d), U64_C (0x7a96294b4b314b62),
+    U64_C (0x21e15dfefedffea3), U64_C (0x16aed55757415782),
+    U64_C (0x412abd15155415a8), U64_C (0xb6eee87777c1779f),
+    U64_C (0xeb6e923737dc37a5), U64_C (0x56d79ee5e5b3e57b),
+    U64_C (0xd923139f9f469f8c), U64_C (0x17fd23f0f0e7f0d3),
+    U64_C (0x7f94204a4a354a6a), U64_C (0x95a944dada4fda9e),
+    U64_C (0x25b0a258587d58fa), U64_C (0xca8fcfc9c903c906),
+    U64_C (0x8d527c2929a42955), U64_C (0x22145a0a0a280a50),
+    U64_C (0x4f7f50b1b1feb1e1), U64_C (0x1a5dc9a0a0baa069),
+    U64_C (0xdad6146b6bb16b7f), U64_C (0xab17d985852e855c),
+    U64_C (0x73673cbdbdcebd81), U64_C (0x34ba8f5d5d695dd2),
+    U64_C (0x5020901010401080), U64_C (0x03f507f4f4f7f4f3),
+    U64_C (0xc08bddcbcb0bcb16), U64_C (0xc67cd33e3ef83eed),
+    U64_C (0x110a2d0505140528), U64_C (0xe6ce78676781671f),
+    U64_C (0x53d597e4e4b7e473), U64_C (0xbb4e0227279c2725),
+    U64_C (0x5882734141194132), U64_C (0x9d0ba78b8b168b2c),
+    U64_C (0x0153f6a7a7a6a751), U64_C (0x94fab27d7de97dcf),
+    U64_C (0xfb374995956e95dc), U64_C (0x9fad56d8d847d88e),
+    U64_C (0x30eb70fbfbcbfb8b), U64_C (0x71c1cdeeee9fee23),
+    U64_C (0x91f8bb7c7ced7cc7), U64_C (0xe3cc716666856617),
+    U64_C (0x8ea77bdddd53dda6), U64_C (0x4b2eaf17175c17b8),
+    U64_C (0x468e454747014702), U64_C (0xdc211a9e9e429e84),
+    U64_C (0xc589d4caca0fca1e), U64_C (0x995a582d2db42d75),
+    U64_C (0x79632ebfbfc6bf91), U64_C (0x1b0e3f07071c0738),
+    U64_C (0x2347acadad8ead01), U64_C (0x2fb4b05a5a755aea),
+    U64_C (0xb51bef838336836c), U64_C (0xff66b63333cc3385),
+    U64_C (0xf2c65c636391633f), U64_C (0x0a04120202080210),
+    U64_C (0x384993aaaa92aa39), U64_C (0xa8e2de7171d971af),
+    U64_C (0xcf8dc6c8c807c80e), U64_C (0x7d32d119196419c8),
+    U64_C (0x70923b4949394972), U64_C (0x9aaf5fd9d943d986),
+    U64_C (0x1df931f2f2eff2c3), U64_C (0x48dba8e3e3abe34b),
+    U64_C (0x2ab6b95b5b715be2), U64_C (0x920dbc88881a8834),
+    U64_C (0xc8293e9a9a529aa4), U64_C (0xbe4c0b262698262d),
+    U64_C (0xfa64bf3232c8328d), U64_C (0x4a7d59b0b0fab0e9),
+    U64_C (0x6acff2e9e983e91b), U64_C (0x331e770f0f3c0f78),
+    U64_C (0xa6b733d5d573d5e6), U64_C (0xba1df480803a8074),
+    U64_C (0x7c6127bebec2be99), U64_C (0xde87ebcdcd13cd26),
+    U64_C (0xe468893434d034bd), U64_C (0x75903248483d487a),
+    U64_C (0x24e354ffffdbffab), U64_C (0x8ff48d7a7af57af7),
+    U64_C (0xea3d6490907a90f4), U64_C (0x3ebe9d5f5f615fc2),
+    U64_C (0xa0403d202080201d), U64_C (0xd5d00f6868bd6867),
+    U64_C (0x7234ca1a1a681ad0), U64_C (0x2c41b7aeae82ae19),
+    U64_C (0x5e757db4b4eab4c9), U64_C (0x19a8ce54544d549a),
+    U64_C (0xe53b7f93937693ec), U64_C (0xaa442f222288220d),
+    U64_C (0xe9c86364648d6407), U64_C (0x12ff2af1f1e3f1db),
+    U64_C (0xa2e6cc7373d173bf), U64_C (0x5a24821212481290),
+    U64_C (0x5d807a40401d403a), U64_C (0x2810480808200840),
+    U64_C (0xe89b95c3c32bc356), U64_C (0x7bc5dfecec97ec33),
+    U64_C (0x90ab4ddbdb4bdb96), U64_C (0x1f5fc0a1a1bea161),
+    U64_C (0x8307918d8d0e8d1c), U64_C (0xc97ac83d3df43df5),
+    U64_C (0xf1335b97976697cc), U64_C (0x0000000000000000),
+    U64_C (0xd483f9cfcf1bcf36), U64_C (0x87566e2b2bac2b45),
+    U64_C (0xb3ece17676c57697), U64_C (0xb019e68282328264),
+    U64_C (0xa9b128d6d67fd6fe), U64_C (0x7736c31b1b6c1bd8),
+    U64_C (0x5b7774b5b5eeb5c1), U64_C (0x2943beafaf86af11),
+    U64_C (0xdfd41d6a6ab56a77), U64_C (0x0da0ea50505d50ba),
+    U64_C (0x4c8a574545094512), U64_C (0x18fb38f3f3ebf3cb),
+    U64_C (0xf060ad3030c0309d), U64_C (0x74c3c4efef9bef2b),
+    U64_C (0xc37eda3f3ffc3fe5), U64_C (0x1caac75555495592),
+    U64_C (0x1059dba2a2b2a279), U64_C (0x65c9e9eaea8fea03),
+    U64_C (0xecca6a656589650f), U64_C (0x686903babad2bab9),
+    U64_C (0x935e4a2f2fbc2f65), U64_C (0xe79d8ec0c027c04e),
+    U64_C (0x81a160dede5fdebe), U64_C (0x6c38fc1c1c701ce0),
+    U64_C (0x2ee746fdfdd3fdbb), U64_C (0x649a1f4d4d294d52),
+    U64_C (0xe0397692927292e4), U64_C (0xbceafa7575c9758f),
+    U64_C (0x1e0c360606180630), U64_C (0x9809ae8a8a128a24),
+    U64_C (0x40794bb2b2f2b2f9), U64_C (0x59d185e6e6bfe663),
+    U64_C (0x361c7e0e0e380e70), U64_C (0x633ee71f1f7c1ff8),
+    U64_C (0xf7c4556262956237), U64_C (0xa3b53ad4d477d4ee),
+    U64_C (0x324d81a8a89aa829), U64_C (0xf4315296966296c4),
+    U64_C (0x3aef62f9f9c3f99b), U64_C (0xf697a3c5c533c566),
+    U64_C (0xb14a102525942535), U64_C (0x20b2ab59597959f2),
+    U64_C (0xae15d084842a8454), U64_C (0xa7e4c57272d572b7),
+    U64_C (0xdd72ec3939e439d5), U64_C (0x6198164c4c2d4c5a),
+    U64_C (0x3bbc945e5e655eca), U64_C (0x85f09f7878fd78e7),
+    U64_C (0xd870e53838e038dd), U64_C (0x8605988c8c0a8c14),
+    U64_C (0xb2bf17d1d163d1c6), U64_C (0x0b57e4a5a5aea541),
+    U64_C (0x4dd9a1e2e2afe243), U64_C (0xf8c24e616199612f),
+    U64_C (0x457b42b3b3f6b3f1), U64_C (0xa542342121842115),
+    U64_C (0xd625089c9c4a9c94), U64_C (0x663cee1e1e781ef0),
+    U64_C (0x5286614343114322), U64_C (0xfc93b1c7c73bc776),
+    U64_C (0x2be54ffcfcd7fcb3), U64_C (0x1408240404100420),
+    U64_C (0x08a2e351515951b2), U64_C (0xc72f2599995e99bc),
+    U64_C (0xc4da226d6da96d4f), U64_C (0x391a650d0d340d68),
+    U64_C (0x35e979fafacffa83), U64_C (0x84a369dfdf5bdfb6),
+    U64_C (0x9bfca97e7ee57ed7), U64_C (0xb44819242490243d),
+    U64_C (0xd776fe3b3bec3bc5), U64_C (0x3d4b9aabab96ab31),
+    U64_C (0xd181f0cece1fce3e), U64_C (0x5522991111441188),
+    U64_C (0x8903838f8f068f0c), U64_C (0x6b9c044e4e254e4a),
+    U64_C (0x517366b7b7e6b7d1), U64_C (0x60cbe0ebeb8beb0b),
+    U64_C (0xcc78c13c3cf03cfd), U64_C (0xbf1ffd81813e817c),
+    U64_C (0xfe354094946a94d4), U64_C (0x0cf31cf7f7fbf7eb),
+    U64_C (0x676f18b9b9deb9a1), U64_C (0x5f268b13134c1398),
+    U64_C (0x9c58512c2cb02c7d), U64_C (0xb8bb05d3d36bd3d6),
+    U64_C (0x5cd38ce7e7bbe76b), U64_C (0xcbdc396e6ea56e57),
+    U64_C (0xf395aac4c437c46e), U64_C (0x0f061b03030c0318),
+    U64_C (0x13acdc565645568a), U64_C (0x49885e44440d441a),
+    U64_C (0x9efea07f7fe17fdf), U64_C (0x374f88a9a99ea921),
+    U64_C (0x8254672a2aa82a4d), U64_C (0x6d6b0abbbbd6bbb1),
+    U64_C (0xe29f87c1c123c146), U64_C (0x02a6f153535153a2),
+    U64_C (0x8ba572dcdc57dcae), U64_C (0x2716530b0b2c0b58),
+    U64_C (0xd327019d9d4e9d9c), U64_C (0xc1d82b6c6cad6c47),
+    U64_C (0xf562a43131c43195), U64_C (0xb9e8f37474cd7487),
+    U64_C (0x09f115f6f6fff6e3), U64_C (0x438c4c464605460a),
+    U64_C (0x2645a5acac8aac09), U64_C (0x970fb589891e893c),
+    U64_C (0x4428b414145014a0), U64_C (0x42dfbae1e1a3e15b),
+    U64_C (0x4e2ca616165816b0), U64_C (0xd274f73a3ae83acd),
+    U64_C (0xd0d2066969b9696f), U64_C (0x2d12410909240948),
+    U64_C (0xade0d77070dd70a7), U64_C (0x54716fb6b6e2b6d9),
+    U64_C (0xb7bd1ed0d067d0ce), U64_C (0x7ec7d6eded93ed3b),
+    U64_C (0xdb85e2cccc17cc2e), U64_C (0x578468424215422a),
+    U64_C (0xc22d2c98985a98b4), U64_C (0x0e55eda4a4aaa449),
+    U64_C (0x8850752828a0285d), U64_C (0x31b8865c5c6d5cda),
+    U64_C (0x3fed6bf8f8c7f893), U64_C (0xa411c28686228644),
+  };
+
+static const u64 C4[256] =
+  {
+    U64_C (0xc07830d818186018), U64_C (0x05af462623238c23),
+    U64_C (0x7ef991b8c6c63fc6), U64_C (0x136fcdfbe8e887e8),
+    U64_C (0x4ca113cb87872687), U64_C (0xa9626d11b8b8dab8),
+    U64_C (0x0805020901010401), U64_C (0x426e9e0d4f4f214f),
+    U64_C (0xadee6c9b3636d836), U64_C (0x590451ffa6a6a2a6),
+    U64_C (0xdebdb90cd2d26fd2), U64_C (0xfb06f70ef5f5f3f5),
+    U64_C (0xef80f2967979f979), U64_C (0x5fcede306f6fa16f),
+    U64_C (0xfcef3f6d91917e91), U64_C (0xaa07a4f852525552),
+    U64_C (0x27fdc04760609d60), U64_C (0x89766535bcbccabc),
+    U64_C (0xaccd2b379b9b569b), U64_C (0x048c018a8e8e028e),
+    U64_C (0x71155bd2a3a3b6a3), U64_C (0x603c186c0c0c300c),
+    U64_C (0xff8af6847b7bf17b), U64_C (0xb5e16a803535d435),
+    U64_C (0xe8693af51d1d741d), U64_C (0x5347ddb3e0e0a7e0),
+    U64_C (0xf6acb321d7d77bd7), U64_C (0x5eed999cc2c22fc2),
+    U64_C (0x6d965c432e2eb82e), U64_C (0x627a96294b4b314b),
+    U64_C (0xa321e15dfefedffe), U64_C (0x8216aed557574157),
+    U64_C (0xa8412abd15155415), U64_C (0x9fb6eee87777c177),
+    U64_C (0xa5eb6e923737dc37), U64_C (0x7b56d79ee5e5b3e5),
+    U64_C (0x8cd923139f9f469f), U64_C (0xd317fd23f0f0e7f0),
+    U64_C (0x6a7f94204a4a354a), U64_C (0x9e95a944dada4fda),
+    U64_C (0xfa25b0a258587d58), U64_C (0x06ca8fcfc9c903c9),
+    U64_C (0x558d527c2929a429), U64_C (0x5022145a0a0a280a),
+    U64_C (0xe14f7f50b1b1feb1), U64_C (0x691a5dc9a0a0baa0),
+    U64_C (0x7fdad6146b6bb16b), U64_C (0x5cab17d985852e85),
+    U64_C (0x8173673cbdbdcebd), U64_C (0xd234ba8f5d5d695d),
+    U64_C (0x8050209010104010), U64_C (0xf303f507f4f4f7f4),
+    U64_C (0x16c08bddcbcb0bcb), U64_C (0xedc67cd33e3ef83e),
+    U64_C (0x28110a2d05051405), U64_C (0x1fe6ce7867678167),
+    U64_C (0x7353d597e4e4b7e4), U64_C (0x25bb4e0227279c27),
+    U64_C (0x3258827341411941), U64_C (0x2c9d0ba78b8b168b),
+    U64_C (0x510153f6a7a7a6a7), U64_C (0xcf94fab27d7de97d),
+    U64_C (0xdcfb374995956e95), U64_C (0x8e9fad56d8d847d8),
+    U64_C (0x8b30eb70fbfbcbfb), U64_C (0x2371c1cdeeee9fee),
+    U64_C (0xc791f8bb7c7ced7c), U64_C (0x17e3cc7166668566),
+    U64_C (0xa68ea77bdddd53dd), U64_C (0xb84b2eaf17175c17),
+    U64_C (0x02468e4547470147), U64_C (0x84dc211a9e9e429e),
+    U64_C (0x1ec589d4caca0fca), U64_C (0x75995a582d2db42d),
+    U64_C (0x9179632ebfbfc6bf), U64_C (0x381b0e3f07071c07),
+    U64_C (0x012347acadad8ead), U64_C (0xea2fb4b05a5a755a),
+    U64_C (0x6cb51bef83833683), U64_C (0x85ff66b63333cc33),
+    U64_C (0x3ff2c65c63639163), U64_C (0x100a041202020802),
+    U64_C (0x39384993aaaa92aa), U64_C (0xafa8e2de7171d971),
+    U64_C (0x0ecf8dc6c8c807c8), U64_C (0xc87d32d119196419),
+    U64_C (0x7270923b49493949), U64_C (0x869aaf5fd9d943d9),
+    U64_C (0xc31df931f2f2eff2), U64_C (0x4b48dba8e3e3abe3),
+    U64_C (0xe22ab6b95b5b715b), U64_C (0x34920dbc88881a88),
+    U64_C (0xa4c8293e9a9a529a), U64_C (0x2dbe4c0b26269826),
+    U64_C (0x8dfa64bf3232c832), U64_C (0xe94a7d59b0b0fab0),
+    U64_C (0x1b6acff2e9e983e9), U64_C (0x78331e770f0f3c0f),
+    U64_C (0xe6a6b733d5d573d5), U64_C (0x74ba1df480803a80),
+    U64_C (0x997c6127bebec2be), U64_C (0x26de87ebcdcd13cd),
+    U64_C (0xbde468893434d034), U64_C (0x7a75903248483d48),
+    U64_C (0xab24e354ffffdbff), U64_C (0xf78ff48d7a7af57a),
+    U64_C (0xf4ea3d6490907a90), U64_C (0xc23ebe9d5f5f615f),
+    U64_C (0x1da0403d20208020), U64_C (0x67d5d00f6868bd68),
+    U64_C (0xd07234ca1a1a681a), U64_C (0x192c41b7aeae82ae),
+    U64_C (0xc95e757db4b4eab4), U64_C (0x9a19a8ce54544d54),
+    U64_C (0xece53b7f93937693), U64_C (0x0daa442f22228822),
+    U64_C (0x07e9c86364648d64), U64_C (0xdb12ff2af1f1e3f1),
+    U64_C (0xbfa2e6cc7373d173), U64_C (0x905a248212124812),
+    U64_C (0x3a5d807a40401d40), U64_C (0x4028104808082008),
+    U64_C (0x56e89b95c3c32bc3), U64_C (0x337bc5dfecec97ec),
+    U64_C (0x9690ab4ddbdb4bdb), U64_C (0x611f5fc0a1a1bea1),
+    U64_C (0x1c8307918d8d0e8d), U64_C (0xf5c97ac83d3df43d),
+    U64_C (0xccf1335b97976697), U64_C (0x0000000000000000),
+    U64_C (0x36d483f9cfcf1bcf), U64_C (0x4587566e2b2bac2b),
+    U64_C (0x97b3ece17676c576), U64_C (0x64b019e682823282),
+    U64_C (0xfea9b128d6d67fd6), U64_C (0xd87736c31b1b6c1b),
+    U64_C (0xc15b7774b5b5eeb5), U64_C (0x112943beafaf86af),
+    U64_C (0x77dfd41d6a6ab56a), U64_C (0xba0da0ea50505d50),
+    U64_C (0x124c8a5745450945), U64_C (0xcb18fb38f3f3ebf3),
+    U64_C (0x9df060ad3030c030), U64_C (0x2b74c3c4efef9bef),
+    U64_C (0xe5c37eda3f3ffc3f), U64_C (0x921caac755554955),
+    U64_C (0x791059dba2a2b2a2), U64_C (0x0365c9e9eaea8fea),
+    U64_C (0x0fecca6a65658965), U64_C (0xb9686903babad2ba),
+    U64_C (0x65935e4a2f2fbc2f), U64_C (0x4ee79d8ec0c027c0),
+    U64_C (0xbe81a160dede5fde), U64_C (0xe06c38fc1c1c701c),
+    U64_C (0xbb2ee746fdfdd3fd), U64_C (0x52649a1f4d4d294d),
+    U64_C (0xe4e0397692927292), U64_C (0x8fbceafa7575c975),
+    U64_C (0x301e0c3606061806), U64_C (0x249809ae8a8a128a),
+    U64_C (0xf940794bb2b2f2b2), U64_C (0x6359d185e6e6bfe6),
+    U64_C (0x70361c7e0e0e380e), U64_C (0xf8633ee71f1f7c1f),
+    U64_C (0x37f7c45562629562), U64_C (0xeea3b53ad4d477d4),
+    U64_C (0x29324d81a8a89aa8), U64_C (0xc4f4315296966296),
+    U64_C (0x9b3aef62f9f9c3f9), U64_C (0x66f697a3c5c533c5),
+    U64_C (0x35b14a1025259425), U64_C (0xf220b2ab59597959),
+    U64_C (0x54ae15d084842a84), U64_C (0xb7a7e4c57272d572),
+    U64_C (0xd5dd72ec3939e439), U64_C (0x5a6198164c4c2d4c),
+    U64_C (0xca3bbc945e5e655e), U64_C (0xe785f09f7878fd78),
+    U64_C (0xddd870e53838e038), U64_C (0x148605988c8c0a8c),
+    U64_C (0xc6b2bf17d1d163d1), U64_C (0x410b57e4a5a5aea5),
+    U64_C (0x434dd9a1e2e2afe2), U64_C (0x2ff8c24e61619961),
+    U64_C (0xf1457b42b3b3f6b3), U64_C (0x15a5423421218421),
+    U64_C (0x94d625089c9c4a9c), U64_C (0xf0663cee1e1e781e),
+    U64_C (0x2252866143431143), U64_C (0x76fc93b1c7c73bc7),
+    U64_C (0xb32be54ffcfcd7fc), U64_C (0x2014082404041004),
+    U64_C (0xb208a2e351515951), U64_C (0xbcc72f2599995e99),
+    U64_C (0x4fc4da226d6da96d), U64_C (0x68391a650d0d340d),
+    U64_C (0x8335e979fafacffa), U64_C (0xb684a369dfdf5bdf),
+    U64_C (0xd79bfca97e7ee57e), U64_C (0x3db4481924249024),
+    U64_C (0xc5d776fe3b3bec3b), U64_C (0x313d4b9aabab96ab),
+    U64_C (0x3ed181f0cece1fce), U64_C (0x8855229911114411),
+    U64_C (0x0c8903838f8f068f), U64_C (0x4a6b9c044e4e254e),
+    U64_C (0xd1517366b7b7e6b7), U64_C (0x0b60cbe0ebeb8beb),
+    U64_C (0xfdcc78c13c3cf03c), U64_C (0x7cbf1ffd81813e81),
+    U64_C (0xd4fe354094946a94), U64_C (0xeb0cf31cf7f7fbf7),
+    U64_C (0xa1676f18b9b9deb9), U64_C (0x985f268b13134c13),
+    U64_C (0x7d9c58512c2cb02c), U64_C (0xd6b8bb05d3d36bd3),
+    U64_C (0x6b5cd38ce7e7bbe7), U64_C (0x57cbdc396e6ea56e),
+    U64_C (0x6ef395aac4c437c4), U64_C (0x180f061b03030c03),
+    U64_C (0x8a13acdc56564556), U64_C (0x1a49885e44440d44),
+    U64_C (0xdf9efea07f7fe17f), U64_C (0x21374f88a9a99ea9),
+    U64_C (0x4d8254672a2aa82a), U64_C (0xb16d6b0abbbbd6bb),
+    U64_C (0x46e29f87c1c123c1), U64_C (0xa202a6f153535153),
+    U64_C (0xae8ba572dcdc57dc), U64_C (0x582716530b0b2c0b),
+    U64_C (0x9cd327019d9d4e9d), U64_C (0x47c1d82b6c6cad6c),
+    U64_C (0x95f562a43131c431), U64_C (0x87b9e8f37474cd74),
+    U64_C (0xe309f115f6f6fff6), U64_C (0x0a438c4c46460546),
+    U64_C (0x092645a5acac8aac), U64_C (0x3c970fb589891e89),
+    U64_C (0xa04428b414145014), U64_C (0x5b42dfbae1e1a3e1),
+    U64_C (0xb04e2ca616165816), U64_C (0xcdd274f73a3ae83a),
+    U64_C (0x6fd0d2066969b969), U64_C (0x482d124109092409),
+    U64_C (0xa7ade0d77070dd70), U64_C (0xd954716fb6b6e2b6),
+    U64_C (0xceb7bd1ed0d067d0), U64_C (0x3b7ec7d6eded93ed),
+    U64_C (0x2edb85e2cccc17cc), U64_C (0x2a57846842421542),
+    U64_C (0xb4c22d2c98985a98), U64_C (0x490e55eda4a4aaa4),
+    U64_C (0x5d8850752828a028), U64_C (0xda31b8865c5c6d5c),
+    U64_C (0x933fed6bf8f8c7f8), U64_C (0x44a411c286862286),
+  };
+
+static const u64 C5[256] =
+  {
+    U64_C (0x18c07830d8181860), U64_C (0x2305af462623238c),
+    U64_C (0xc67ef991b8c6c63f), U64_C (0xe8136fcdfbe8e887),
+    U64_C (0x874ca113cb878726), U64_C (0xb8a9626d11b8b8da),
+    U64_C (0x0108050209010104), U64_C (0x4f426e9e0d4f4f21),
+    U64_C (0x36adee6c9b3636d8), U64_C (0xa6590451ffa6a6a2),
+    U64_C (0xd2debdb90cd2d26f), U64_C (0xf5fb06f70ef5f5f3),
+    U64_C (0x79ef80f2967979f9), U64_C (0x6f5fcede306f6fa1),
+    U64_C (0x91fcef3f6d91917e), U64_C (0x52aa07a4f8525255),
+    U64_C (0x6027fdc04760609d), U64_C (0xbc89766535bcbcca),
+    U64_C (0x9baccd2b379b9b56), U64_C (0x8e048c018a8e8e02),
+    U64_C (0xa371155bd2a3a3b6), U64_C (0x0c603c186c0c0c30),
+    U64_C (0x7bff8af6847b7bf1), U64_C (0x35b5e16a803535d4),
+    U64_C (0x1de8693af51d1d74), U64_C (0xe05347ddb3e0e0a7),
+    U64_C (0xd7f6acb321d7d77b), U64_C (0xc25eed999cc2c22f),
+    U64_C (0x2e6d965c432e2eb8), U64_C (0x4b627a96294b4b31),
+    U64_C (0xfea321e15dfefedf), U64_C (0x578216aed5575741),
+    U64_C (0x15a8412abd151554), U64_C (0x779fb6eee87777c1),
+    U64_C (0x37a5eb6e923737dc), U64_C (0xe57b56d79ee5e5b3),
+    U64_C (0x9f8cd923139f9f46), U64_C (0xf0d317fd23f0f0e7),
+    U64_C (0x4a6a7f94204a4a35), U64_C (0xda9e95a944dada4f),
+    U64_C (0x58fa25b0a258587d), U64_C (0xc906ca8fcfc9c903),
+    U64_C (0x29558d527c2929a4), U64_C (0x0a5022145a0a0a28),
+    U64_C (0xb1e14f7f50b1b1fe), U64_C (0xa0691a5dc9a0a0ba),
+    U64_C (0x6b7fdad6146b6bb1), U64_C (0x855cab17d985852e),
+    U64_C (0xbd8173673cbdbdce), U64_C (0x5dd234ba8f5d5d69),
+    U64_C (0x1080502090101040), U64_C (0xf4f303f507f4f4f7),
+    U64_C (0xcb16c08bddcbcb0b), U64_C (0x3eedc67cd33e3ef8),
+    U64_C (0x0528110a2d050514), U64_C (0x671fe6ce78676781),
+    U64_C (0xe47353d597e4e4b7), U64_C (0x2725bb4e0227279c),
+    U64_C (0x4132588273414119), U64_C (0x8b2c9d0ba78b8b16),
+    U64_C (0xa7510153f6a7a7a6), U64_C (0x7dcf94fab27d7de9),
+    U64_C (0x95dcfb374995956e), U64_C (0xd88e9fad56d8d847),
+    U64_C (0xfb8b30eb70fbfbcb), U64_C (0xee2371c1cdeeee9f),
+    U64_C (0x7cc791f8bb7c7ced), U64_C (0x6617e3cc71666685),
+    U64_C (0xdda68ea77bdddd53), U64_C (0x17b84b2eaf17175c),
+    U64_C (0x4702468e45474701), U64_C (0x9e84dc211a9e9e42),
+    U64_C (0xca1ec589d4caca0f), U64_C (0x2d75995a582d2db4),
+    U64_C (0xbf9179632ebfbfc6), U64_C (0x07381b0e3f07071c),
+    U64_C (0xad012347acadad8e), U64_C (0x5aea2fb4b05a5a75),
+    U64_C (0x836cb51bef838336), U64_C (0x3385ff66b63333cc),
+    U64_C (0x633ff2c65c636391), U64_C (0x02100a0412020208),
+    U64_C (0xaa39384993aaaa92), U64_C (0x71afa8e2de7171d9),
+    U64_C (0xc80ecf8dc6c8c807), U64_C (0x19c87d32d1191964),
+    U64_C (0x497270923b494939), U64_C (0xd9869aaf5fd9d943),
+    U64_C (0xf2c31df931f2f2ef), U64_C (0xe34b48dba8e3e3ab),
+    U64_C (0x5be22ab6b95b5b71), U64_C (0x8834920dbc88881a),
+    U64_C (0x9aa4c8293e9a9a52), U64_C (0x262dbe4c0b262698),
+    U64_C (0x328dfa64bf3232c8), U64_C (0xb0e94a7d59b0b0fa),
+    U64_C (0xe91b6acff2e9e983), U64_C (0x0f78331e770f0f3c),
+    U64_C (0xd5e6a6b733d5d573), U64_C (0x8074ba1df480803a),
+    U64_C (0xbe997c6127bebec2), U64_C (0xcd26de87ebcdcd13),
+    U64_C (0x34bde468893434d0), U64_C (0x487a75903248483d),
+    U64_C (0xffab24e354ffffdb), U64_C (0x7af78ff48d7a7af5),
+    U64_C (0x90f4ea3d6490907a), U64_C (0x5fc23ebe9d5f5f61),
+    U64_C (0x201da0403d202080), U64_C (0x6867d5d00f6868bd),
+    U64_C (0x1ad07234ca1a1a68), U64_C (0xae192c41b7aeae82),
+    U64_C (0xb4c95e757db4b4ea), U64_C (0x549a19a8ce54544d),
+    U64_C (0x93ece53b7f939376), U64_C (0x220daa442f222288),
+    U64_C (0x6407e9c86364648d), U64_C (0xf1db12ff2af1f1e3),
+    U64_C (0x73bfa2e6cc7373d1), U64_C (0x12905a2482121248),
+    U64_C (0x403a5d807a40401d), U64_C (0x0840281048080820),
+    U64_C (0xc356e89b95c3c32b), U64_C (0xec337bc5dfecec97),
+    U64_C (0xdb9690ab4ddbdb4b), U64_C (0xa1611f5fc0a1a1be),
+    U64_C (0x8d1c8307918d8d0e), U64_C (0x3df5c97ac83d3df4),
+    U64_C (0x97ccf1335b979766), U64_C (0x0000000000000000),
+    U64_C (0xcf36d483f9cfcf1b), U64_C (0x2b4587566e2b2bac),
+    U64_C (0x7697b3ece17676c5), U64_C (0x8264b019e6828232),
+    U64_C (0xd6fea9b128d6d67f), U64_C (0x1bd87736c31b1b6c),
+    U64_C (0xb5c15b7774b5b5ee), U64_C (0xaf112943beafaf86),
+    U64_C (0x6a77dfd41d6a6ab5), U64_C (0x50ba0da0ea50505d),
+    U64_C (0x45124c8a57454509), U64_C (0xf3cb18fb38f3f3eb),
+    U64_C (0x309df060ad3030c0), U64_C (0xef2b74c3c4efef9b),
+    U64_C (0x3fe5c37eda3f3ffc), U64_C (0x55921caac7555549),
+    U64_C (0xa2791059dba2a2b2), U64_C (0xea0365c9e9eaea8f),
+    U64_C (0x650fecca6a656589), U64_C (0xbab9686903babad2),
+    U64_C (0x2f65935e4a2f2fbc), U64_C (0xc04ee79d8ec0c027),
+    U64_C (0xdebe81a160dede5f), U64_C (0x1ce06c38fc1c1c70),
+    U64_C (0xfdbb2ee746fdfdd3), U64_C (0x4d52649a1f4d4d29),
+    U64_C (0x92e4e03976929272), U64_C (0x758fbceafa7575c9),
+    U64_C (0x06301e0c36060618), U64_C (0x8a249809ae8a8a12),
+    U64_C (0xb2f940794bb2b2f2), U64_C (0xe66359d185e6e6bf),
+    U64_C (0x0e70361c7e0e0e38), U64_C (0x1ff8633ee71f1f7c),
+    U64_C (0x6237f7c455626295), U64_C (0xd4eea3b53ad4d477),
+    U64_C (0xa829324d81a8a89a), U64_C (0x96c4f43152969662),
+    U64_C (0xf99b3aef62f9f9c3), U64_C (0xc566f697a3c5c533),
+    U64_C (0x2535b14a10252594), U64_C (0x59f220b2ab595979),
+    U64_C (0x8454ae15d084842a), U64_C (0x72b7a7e4c57272d5),
+    U64_C (0x39d5dd72ec3939e4), U64_C (0x4c5a6198164c4c2d),
+    U64_C (0x5eca3bbc945e5e65), U64_C (0x78e785f09f7878fd),
+    U64_C (0x38ddd870e53838e0), U64_C (0x8c148605988c8c0a),
+    U64_C (0xd1c6b2bf17d1d163), U64_C (0xa5410b57e4a5a5ae),
+    U64_C (0xe2434dd9a1e2e2af), U64_C (0x612ff8c24e616199),
+    U64_C (0xb3f1457b42b3b3f6), U64_C (0x2115a54234212184),
+    U64_C (0x9c94d625089c9c4a), U64_C (0x1ef0663cee1e1e78),
+    U64_C (0x4322528661434311), U64_C (0xc776fc93b1c7c73b),
+    U64_C (0xfcb32be54ffcfcd7), U64_C (0x0420140824040410),
+    U64_C (0x51b208a2e3515159), U64_C (0x99bcc72f2599995e),
+    U64_C (0x6d4fc4da226d6da9), U64_C (0x0d68391a650d0d34),
+    U64_C (0xfa8335e979fafacf), U64_C (0xdfb684a369dfdf5b),
+    U64_C (0x7ed79bfca97e7ee5), U64_C (0x243db44819242490),
+    U64_C (0x3bc5d776fe3b3bec), U64_C (0xab313d4b9aabab96),
+    U64_C (0xce3ed181f0cece1f), U64_C (0x1188552299111144),
+    U64_C (0x8f0c8903838f8f06), U64_C (0x4e4a6b9c044e4e25),
+    U64_C (0xb7d1517366b7b7e6), U64_C (0xeb0b60cbe0ebeb8b),
+    U64_C (0x3cfdcc78c13c3cf0), U64_C (0x817cbf1ffd81813e),
+    U64_C (0x94d4fe354094946a), U64_C (0xf7eb0cf31cf7f7fb),
+    U64_C (0xb9a1676f18b9b9de), U64_C (0x13985f268b13134c),
+    U64_C (0x2c7d9c58512c2cb0), U64_C (0xd3d6b8bb05d3d36b),
+    U64_C (0xe76b5cd38ce7e7bb), U64_C (0x6e57cbdc396e6ea5),
+    U64_C (0xc46ef395aac4c437), U64_C (0x03180f061b03030c),
+    U64_C (0x568a13acdc565645), U64_C (0x441a49885e44440d),
+    U64_C (0x7fdf9efea07f7fe1), U64_C (0xa921374f88a9a99e),
+    U64_C (0x2a4d8254672a2aa8), U64_C (0xbbb16d6b0abbbbd6),
+    U64_C (0xc146e29f87c1c123), U64_C (0x53a202a6f1535351),
+    U64_C (0xdcae8ba572dcdc57), U64_C (0x0b582716530b0b2c),
+    U64_C (0x9d9cd327019d9d4e), U64_C (0x6c47c1d82b6c6cad),
+    U64_C (0x3195f562a43131c4), U64_C (0x7487b9e8f37474cd),
+    U64_C (0xf6e309f115f6f6ff), U64_C (0x460a438c4c464605),
+    U64_C (0xac092645a5acac8a), U64_C (0x893c970fb589891e),
+    U64_C (0x14a04428b4141450), U64_C (0xe15b42dfbae1e1a3),
+    U64_C (0x16b04e2ca6161658), U64_C (0x3acdd274f73a3ae8),
+    U64_C (0x696fd0d2066969b9), U64_C (0x09482d1241090924),
+    U64_C (0x70a7ade0d77070dd), U64_C (0xb6d954716fb6b6e2),
+    U64_C (0xd0ceb7bd1ed0d067), U64_C (0xed3b7ec7d6eded93),
+    U64_C (0xcc2edb85e2cccc17), U64_C (0x422a578468424215),
+    U64_C (0x98b4c22d2c98985a), U64_C (0xa4490e55eda4a4aa),
+    U64_C (0x285d8850752828a0), U64_C (0x5cda31b8865c5c6d),
+    U64_C (0xf8933fed6bf8f8c7), U64_C (0x8644a411c2868622),
+  };
+
+static const u64 C6[256] =
+  {
+    U64_C (0x6018c07830d81818), U64_C (0x8c2305af46262323),
+    U64_C (0x3fc67ef991b8c6c6), U64_C (0x87e8136fcdfbe8e8),
+    U64_C (0x26874ca113cb8787), U64_C (0xdab8a9626d11b8b8),
+    U64_C (0x0401080502090101), U64_C (0x214f426e9e0d4f4f),
+    U64_C (0xd836adee6c9b3636), U64_C (0xa2a6590451ffa6a6),
+    U64_C (0x6fd2debdb90cd2d2), U64_C (0xf3f5fb06f70ef5f5),
+    U64_C (0xf979ef80f2967979), U64_C (0xa16f5fcede306f6f),
+    U64_C (0x7e91fcef3f6d9191), U64_C (0x5552aa07a4f85252),
+    U64_C (0x9d6027fdc0476060), U64_C (0xcabc89766535bcbc),
+    U64_C (0x569baccd2b379b9b), U64_C (0x028e048c018a8e8e),
+    U64_C (0xb6a371155bd2a3a3), U64_C (0x300c603c186c0c0c),
+    U64_C (0xf17bff8af6847b7b), U64_C (0xd435b5e16a803535),
+    U64_C (0x741de8693af51d1d), U64_C (0xa7e05347ddb3e0e0),
+    U64_C (0x7bd7f6acb321d7d7), U64_C (0x2fc25eed999cc2c2),
+    U64_C (0xb82e6d965c432e2e), U64_C (0x314b627a96294b4b),
+    U64_C (0xdffea321e15dfefe), U64_C (0x41578216aed55757),
+    U64_C (0x5415a8412abd1515), U64_C (0xc1779fb6eee87777),
+    U64_C (0xdc37a5eb6e923737), U64_C (0xb3e57b56d79ee5e5),
+    U64_C (0x469f8cd923139f9f), U64_C (0xe7f0d317fd23f0f0),
+    U64_C (0x354a6a7f94204a4a), U64_C (0x4fda9e95a944dada),
+    U64_C (0x7d58fa25b0a25858), U64_C (0x03c906ca8fcfc9c9),
+    U64_C (0xa429558d527c2929), U64_C (0x280a5022145a0a0a),
+    U64_C (0xfeb1e14f7f50b1b1), U64_C (0xbaa0691a5dc9a0a0),
+    U64_C (0xb16b7fdad6146b6b), U64_C (0x2e855cab17d98585),
+    U64_C (0xcebd8173673cbdbd), U64_C (0x695dd234ba8f5d5d),
+    U64_C (0x4010805020901010), U64_C (0xf7f4f303f507f4f4),
+    U64_C (0x0bcb16c08bddcbcb), U64_C (0xf83eedc67cd33e3e),
+    U64_C (0x140528110a2d0505), U64_C (0x81671fe6ce786767),
+    U64_C (0xb7e47353d597e4e4), U64_C (0x9c2725bb4e022727),
+    U64_C (0x1941325882734141), U64_C (0x168b2c9d0ba78b8b),
+    U64_C (0xa6a7510153f6a7a7), U64_C (0xe97dcf94fab27d7d),
+    U64_C (0x6e95dcfb37499595), U64_C (0x47d88e9fad56d8d8),
+    U64_C (0xcbfb8b30eb70fbfb), U64_C (0x9fee2371c1cdeeee),
+    U64_C (0xed7cc791f8bb7c7c), U64_C (0x856617e3cc716666),
+    U64_C (0x53dda68ea77bdddd), U64_C (0x5c17b84b2eaf1717),
+    U64_C (0x014702468e454747), U64_C (0x429e84dc211a9e9e),
+    U64_C (0x0fca1ec589d4caca), U64_C (0xb42d75995a582d2d),
+    U64_C (0xc6bf9179632ebfbf), U64_C (0x1c07381b0e3f0707),
+    U64_C (0x8ead012347acadad), U64_C (0x755aea2fb4b05a5a),
+    U64_C (0x36836cb51bef8383), U64_C (0xcc3385ff66b63333),
+    U64_C (0x91633ff2c65c6363), U64_C (0x0802100a04120202),
+    U64_C (0x92aa39384993aaaa), U64_C (0xd971afa8e2de7171),
+    U64_C (0x07c80ecf8dc6c8c8), U64_C (0x6419c87d32d11919),
+    U64_C (0x39497270923b4949), U64_C (0x43d9869aaf5fd9d9),
+    U64_C (0xeff2c31df931f2f2), U64_C (0xabe34b48dba8e3e3),
+    U64_C (0x715be22ab6b95b5b), U64_C (0x1a8834920dbc8888),
+    U64_C (0x529aa4c8293e9a9a), U64_C (0x98262dbe4c0b2626),
+    U64_C (0xc8328dfa64bf3232), U64_C (0xfab0e94a7d59b0b0),
+    U64_C (0x83e91b6acff2e9e9), U64_C (0x3c0f78331e770f0f),
+    U64_C (0x73d5e6a6b733d5d5), U64_C (0x3a8074ba1df48080),
+    U64_C (0xc2be997c6127bebe), U64_C (0x13cd26de87ebcdcd),
+    U64_C (0xd034bde468893434), U64_C (0x3d487a7590324848),
+    U64_C (0xdbffab24e354ffff), U64_C (0xf57af78ff48d7a7a),
+    U64_C (0x7a90f4ea3d649090), U64_C (0x615fc23ebe9d5f5f),
+    U64_C (0x80201da0403d2020), U64_C (0xbd6867d5d00f6868),
+    U64_C (0x681ad07234ca1a1a), U64_C (0x82ae192c41b7aeae),
+    U64_C (0xeab4c95e757db4b4), U64_C (0x4d549a19a8ce5454),
+    U64_C (0x7693ece53b7f9393), U64_C (0x88220daa442f2222),
+    U64_C (0x8d6407e9c8636464), U64_C (0xe3f1db12ff2af1f1),
+    U64_C (0xd173bfa2e6cc7373), U64_C (0x4812905a24821212),
+    U64_C (0x1d403a5d807a4040), U64_C (0x2008402810480808),
+    U64_C (0x2bc356e89b95c3c3), U64_C (0x97ec337bc5dfecec),
+    U64_C (0x4bdb9690ab4ddbdb), U64_C (0xbea1611f5fc0a1a1),
+    U64_C (0x0e8d1c8307918d8d), U64_C (0xf43df5c97ac83d3d),
+    U64_C (0x6697ccf1335b9797), U64_C (0x0000000000000000),
+    U64_C (0x1bcf36d483f9cfcf), U64_C (0xac2b4587566e2b2b),
+    U64_C (0xc57697b3ece17676), U64_C (0x328264b019e68282),
+    U64_C (0x7fd6fea9b128d6d6), U64_C (0x6c1bd87736c31b1b),
+    U64_C (0xeeb5c15b7774b5b5), U64_C (0x86af112943beafaf),
+    U64_C (0xb56a77dfd41d6a6a), U64_C (0x5d50ba0da0ea5050),
+    U64_C (0x0945124c8a574545), U64_C (0xebf3cb18fb38f3f3),
+    U64_C (0xc0309df060ad3030), U64_C (0x9bef2b74c3c4efef),
+    U64_C (0xfc3fe5c37eda3f3f), U64_C (0x4955921caac75555),
+    U64_C (0xb2a2791059dba2a2), U64_C (0x8fea0365c9e9eaea),
+    U64_C (0x89650fecca6a6565), U64_C (0xd2bab9686903baba),
+    U64_C (0xbc2f65935e4a2f2f), U64_C (0x27c04ee79d8ec0c0),
+    U64_C (0x5fdebe81a160dede), U64_C (0x701ce06c38fc1c1c),
+    U64_C (0xd3fdbb2ee746fdfd), U64_C (0x294d52649a1f4d4d),
+    U64_C (0x7292e4e039769292), U64_C (0xc9758fbceafa7575),
+    U64_C (0x1806301e0c360606), U64_C (0x128a249809ae8a8a),
+    U64_C (0xf2b2f940794bb2b2), U64_C (0xbfe66359d185e6e6),
+    U64_C (0x380e70361c7e0e0e), U64_C (0x7c1ff8633ee71f1f),
+    U64_C (0x956237f7c4556262), U64_C (0x77d4eea3b53ad4d4),
+    U64_C (0x9aa829324d81a8a8), U64_C (0x6296c4f431529696),
+    U64_C (0xc3f99b3aef62f9f9), U64_C (0x33c566f697a3c5c5),
+    U64_C (0x942535b14a102525), U64_C (0x7959f220b2ab5959),
+    U64_C (0x2a8454ae15d08484), U64_C (0xd572b7a7e4c57272),
+    U64_C (0xe439d5dd72ec3939), U64_C (0x2d4c5a6198164c4c),
+    U64_C (0x655eca3bbc945e5e), U64_C (0xfd78e785f09f7878),
+    U64_C (0xe038ddd870e53838), U64_C (0x0a8c148605988c8c),
+    U64_C (0x63d1c6b2bf17d1d1), U64_C (0xaea5410b57e4a5a5),
+    U64_C (0xafe2434dd9a1e2e2), U64_C (0x99612ff8c24e6161),
+    U64_C (0xf6b3f1457b42b3b3), U64_C (0x842115a542342121),
+    U64_C (0x4a9c94d625089c9c), U64_C (0x781ef0663cee1e1e),
+    U64_C (0x1143225286614343), U64_C (0x3bc776fc93b1c7c7),
+    U64_C (0xd7fcb32be54ffcfc), U64_C (0x1004201408240404),
+    U64_C (0x5951b208a2e35151), U64_C (0x5e99bcc72f259999),
+    U64_C (0xa96d4fc4da226d6d), U64_C (0x340d68391a650d0d),
+    U64_C (0xcffa8335e979fafa), U64_C (0x5bdfb684a369dfdf),
+    U64_C (0xe57ed79bfca97e7e), U64_C (0x90243db448192424),
+    U64_C (0xec3bc5d776fe3b3b), U64_C (0x96ab313d4b9aabab),
+    U64_C (0x1fce3ed181f0cece), U64_C (0x4411885522991111),
+    U64_C (0x068f0c8903838f8f), U64_C (0x254e4a6b9c044e4e),
+    U64_C (0xe6b7d1517366b7b7), U64_C (0x8beb0b60cbe0ebeb),
+    U64_C (0xf03cfdcc78c13c3c), U64_C (0x3e817cbf1ffd8181),
+    U64_C (0x6a94d4fe35409494), U64_C (0xfbf7eb0cf31cf7f7),
+    U64_C (0xdeb9a1676f18b9b9), U64_C (0x4c13985f268b1313),
+    U64_C (0xb02c7d9c58512c2c), U64_C (0x6bd3d6b8bb05d3d3),
+    U64_C (0xbbe76b5cd38ce7e7), U64_C (0xa56e57cbdc396e6e),
+    U64_C (0x37c46ef395aac4c4), U64_C (0x0c03180f061b0303),
+    U64_C (0x45568a13acdc5656), U64_C (0x0d441a49885e4444),
+    U64_C (0xe17fdf9efea07f7f), U64_C (0x9ea921374f88a9a9),
+    U64_C (0xa82a4d8254672a2a), U64_C (0xd6bbb16d6b0abbbb),
+    U64_C (0x23c146e29f87c1c1), U64_C (0x5153a202a6f15353),
+    U64_C (0x57dcae8ba572dcdc), U64_C (0x2c0b582716530b0b),
+    U64_C (0x4e9d9cd327019d9d), U64_C (0xad6c47c1d82b6c6c),
+    U64_C (0xc43195f562a43131), U64_C (0xcd7487b9e8f37474),
+    U64_C (0xfff6e309f115f6f6), U64_C (0x05460a438c4c4646),
+    U64_C (0x8aac092645a5acac), U64_C (0x1e893c970fb58989),
+    U64_C (0x5014a04428b41414), U64_C (0xa3e15b42dfbae1e1),
+    U64_C (0x5816b04e2ca61616), U64_C (0xe83acdd274f73a3a),
+    U64_C (0xb9696fd0d2066969), U64_C (0x2409482d12410909),
+    U64_C (0xdd70a7ade0d77070), U64_C (0xe2b6d954716fb6b6),
+    U64_C (0x67d0ceb7bd1ed0d0), U64_C (0x93ed3b7ec7d6eded),
+    U64_C (0x17cc2edb85e2cccc), U64_C (0x15422a5784684242),
+    U64_C (0x5a98b4c22d2c9898), U64_C (0xaaa4490e55eda4a4),
+    U64_C (0xa0285d8850752828), U64_C (0x6d5cda31b8865c5c),
+    U64_C (0xc7f8933fed6bf8f8), U64_C (0x228644a411c28686),
+  };
+
+static const u64 C7[256] =
+  {
+    U64_C (0x186018c07830d818), U64_C (0x238c2305af462623),
+    U64_C (0xc63fc67ef991b8c6), U64_C (0xe887e8136fcdfbe8),
+    U64_C (0x8726874ca113cb87), U64_C (0xb8dab8a9626d11b8),
+    U64_C (0x0104010805020901), U64_C (0x4f214f426e9e0d4f),
+    U64_C (0x36d836adee6c9b36), U64_C (0xa6a2a6590451ffa6),
+    U64_C (0xd26fd2debdb90cd2), U64_C (0xf5f3f5fb06f70ef5),
+    U64_C (0x79f979ef80f29679), U64_C (0x6fa16f5fcede306f),
+    U64_C (0x917e91fcef3f6d91), U64_C (0x525552aa07a4f852),
+    U64_C (0x609d6027fdc04760), U64_C (0xbccabc89766535bc),
+    U64_C (0x9b569baccd2b379b), U64_C (0x8e028e048c018a8e),
+    U64_C (0xa3b6a371155bd2a3), U64_C (0x0c300c603c186c0c),
+    U64_C (0x7bf17bff8af6847b), U64_C (0x35d435b5e16a8035),
+    U64_C (0x1d741de8693af51d), U64_C (0xe0a7e05347ddb3e0),
+    U64_C (0xd77bd7f6acb321d7), U64_C (0xc22fc25eed999cc2),
+    U64_C (0x2eb82e6d965c432e), U64_C (0x4b314b627a96294b),
+    U64_C (0xfedffea321e15dfe), U64_C (0x5741578216aed557),
+    U64_C (0x155415a8412abd15), U64_C (0x77c1779fb6eee877),
+    U64_C (0x37dc37a5eb6e9237), U64_C (0xe5b3e57b56d79ee5),
+    U64_C (0x9f469f8cd923139f), U64_C (0xf0e7f0d317fd23f0),
+    U64_C (0x4a354a6a7f94204a), U64_C (0xda4fda9e95a944da),
+    U64_C (0x587d58fa25b0a258), U64_C (0xc903c906ca8fcfc9),
+    U64_C (0x29a429558d527c29), U64_C (0x0a280a5022145a0a),
+    U64_C (0xb1feb1e14f7f50b1), U64_C (0xa0baa0691a5dc9a0),
+    U64_C (0x6bb16b7fdad6146b), U64_C (0x852e855cab17d985),
+    U64_C (0xbdcebd8173673cbd), U64_C (0x5d695dd234ba8f5d),
+    U64_C (0x1040108050209010), U64_C (0xf4f7f4f303f507f4),
+    U64_C (0xcb0bcb16c08bddcb), U64_C (0x3ef83eedc67cd33e),
+    U64_C (0x05140528110a2d05), U64_C (0x6781671fe6ce7867),
+    U64_C (0xe4b7e47353d597e4), U64_C (0x279c2725bb4e0227),
+    U64_C (0x4119413258827341), U64_C (0x8b168b2c9d0ba78b),
+    U64_C (0xa7a6a7510153f6a7), U64_C (0x7de97dcf94fab27d),
+    U64_C (0x956e95dcfb374995), U64_C (0xd847d88e9fad56d8),
+    U64_C (0xfbcbfb8b30eb70fb), U64_C (0xee9fee2371c1cdee),
+    U64_C (0x7ced7cc791f8bb7c), U64_C (0x66856617e3cc7166),
+    U64_C (0xdd53dda68ea77bdd), U64_C (0x175c17b84b2eaf17),
+    U64_C (0x47014702468e4547), U64_C (0x9e429e84dc211a9e),
+    U64_C (0xca0fca1ec589d4ca), U64_C (0x2db42d75995a582d),
+    U64_C (0xbfc6bf9179632ebf), U64_C (0x071c07381b0e3f07),
+    U64_C (0xad8ead012347acad), U64_C (0x5a755aea2fb4b05a),
+    U64_C (0x8336836cb51bef83), U64_C (0x33cc3385ff66b633),
+    U64_C (0x6391633ff2c65c63), U64_C (0x020802100a041202),
+    U64_C (0xaa92aa39384993aa), U64_C (0x71d971afa8e2de71),
+    U64_C (0xc807c80ecf8dc6c8), U64_C (0x196419c87d32d119),
+    U64_C (0x4939497270923b49), U64_C (0xd943d9869aaf5fd9),
+    U64_C (0xf2eff2c31df931f2), U64_C (0xe3abe34b48dba8e3),
+    U64_C (0x5b715be22ab6b95b), U64_C (0x881a8834920dbc88),
+    U64_C (0x9a529aa4c8293e9a), U64_C (0x2698262dbe4c0b26),
+    U64_C (0x32c8328dfa64bf32), U64_C (0xb0fab0e94a7d59b0),
+    U64_C (0xe983e91b6acff2e9), U64_C (0x0f3c0f78331e770f),
+    U64_C (0xd573d5e6a6b733d5), U64_C (0x803a8074ba1df480),
+    U64_C (0xbec2be997c6127be), U64_C (0xcd13cd26de87ebcd),
+    U64_C (0x34d034bde4688934), U64_C (0x483d487a75903248),
+    U64_C (0xffdbffab24e354ff), U64_C (0x7af57af78ff48d7a),
+    U64_C (0x907a90f4ea3d6490), U64_C (0x5f615fc23ebe9d5f),
+    U64_C (0x2080201da0403d20), U64_C (0x68bd6867d5d00f68),
+    U64_C (0x1a681ad07234ca1a), U64_C (0xae82ae192c41b7ae),
+    U64_C (0xb4eab4c95e757db4), U64_C (0x544d549a19a8ce54),
+    U64_C (0x937693ece53b7f93), U64_C (0x2288220daa442f22),
+    U64_C (0x648d6407e9c86364), U64_C (0xf1e3f1db12ff2af1),
+    U64_C (0x73d173bfa2e6cc73), U64_C (0x124812905a248212),
+    U64_C (0x401d403a5d807a40), U64_C (0x0820084028104808),
+    U64_C (0xc32bc356e89b95c3), U64_C (0xec97ec337bc5dfec),
+    U64_C (0xdb4bdb9690ab4ddb), U64_C (0xa1bea1611f5fc0a1),
+    U64_C (0x8d0e8d1c8307918d), U64_C (0x3df43df5c97ac83d),
+    U64_C (0x976697ccf1335b97), U64_C (0x0000000000000000),
+    U64_C (0xcf1bcf36d483f9cf), U64_C (0x2bac2b4587566e2b),
+    U64_C (0x76c57697b3ece176), U64_C (0x82328264b019e682),
+    U64_C (0xd67fd6fea9b128d6), U64_C (0x1b6c1bd87736c31b),
+    U64_C (0xb5eeb5c15b7774b5), U64_C (0xaf86af112943beaf),
+    U64_C (0x6ab56a77dfd41d6a), U64_C (0x505d50ba0da0ea50),
+    U64_C (0x450945124c8a5745), U64_C (0xf3ebf3cb18fb38f3),
+    U64_C (0x30c0309df060ad30), U64_C (0xef9bef2b74c3c4ef),
+    U64_C (0x3ffc3fe5c37eda3f), U64_C (0x554955921caac755),
+    U64_C (0xa2b2a2791059dba2), U64_C (0xea8fea0365c9e9ea),
+    U64_C (0x6589650fecca6a65), U64_C (0xbad2bab9686903ba),
+    U64_C (0x2fbc2f65935e4a2f), U64_C (0xc027c04ee79d8ec0),
+    U64_C (0xde5fdebe81a160de), U64_C (0x1c701ce06c38fc1c),
+    U64_C (0xfdd3fdbb2ee746fd), U64_C (0x4d294d52649a1f4d),
+    U64_C (0x927292e4e0397692), U64_C (0x75c9758fbceafa75),
+    U64_C (0x061806301e0c3606), U64_C (0x8a128a249809ae8a),
+    U64_C (0xb2f2b2f940794bb2), U64_C (0xe6bfe66359d185e6),
+    U64_C (0x0e380e70361c7e0e), U64_C (0x1f7c1ff8633ee71f),
+    U64_C (0x62956237f7c45562), U64_C (0xd477d4eea3b53ad4),
+    U64_C (0xa89aa829324d81a8), U64_C (0x966296c4f4315296),
+    U64_C (0xf9c3f99b3aef62f9), U64_C (0xc533c566f697a3c5),
+    U64_C (0x25942535b14a1025), U64_C (0x597959f220b2ab59),
+    U64_C (0x842a8454ae15d084), U64_C (0x72d572b7a7e4c572),
+    U64_C (0x39e439d5dd72ec39), U64_C (0x4c2d4c5a6198164c),
+    U64_C (0x5e655eca3bbc945e), U64_C (0x78fd78e785f09f78),
+    U64_C (0x38e038ddd870e538), U64_C (0x8c0a8c148605988c),
+    U64_C (0xd163d1c6b2bf17d1), U64_C (0xa5aea5410b57e4a5),
+    U64_C (0xe2afe2434dd9a1e2), U64_C (0x6199612ff8c24e61),
+    U64_C (0xb3f6b3f1457b42b3), U64_C (0x21842115a5423421),
+    U64_C (0x9c4a9c94d625089c), U64_C (0x1e781ef0663cee1e),
+    U64_C (0x4311432252866143), U64_C (0xc73bc776fc93b1c7),
+    U64_C (0xfcd7fcb32be54ffc), U64_C (0x0410042014082404),
+    U64_C (0x515951b208a2e351), U64_C (0x995e99bcc72f2599),
+    U64_C (0x6da96d4fc4da226d), U64_C (0x0d340d68391a650d),
+    U64_C (0xfacffa8335e979fa), U64_C (0xdf5bdfb684a369df),
+    U64_C (0x7ee57ed79bfca97e), U64_C (0x2490243db4481924),
+    U64_C (0x3bec3bc5d776fe3b), U64_C (0xab96ab313d4b9aab),
+    U64_C (0xce1fce3ed181f0ce), U64_C (0x1144118855229911),
+    U64_C (0x8f068f0c8903838f), U64_C (0x4e254e4a6b9c044e),
+    U64_C (0xb7e6b7d1517366b7), U64_C (0xeb8beb0b60cbe0eb),
+    U64_C (0x3cf03cfdcc78c13c), U64_C (0x813e817cbf1ffd81),
+    U64_C (0x946a94d4fe354094), U64_C (0xf7fbf7eb0cf31cf7),
+    U64_C (0xb9deb9a1676f18b9), U64_C (0x134c13985f268b13),
+    U64_C (0x2cb02c7d9c58512c), U64_C (0xd36bd3d6b8bb05d3),
+    U64_C (0xe7bbe76b5cd38ce7), U64_C (0x6ea56e57cbdc396e),
+    U64_C (0xc437c46ef395aac4), U64_C (0x030c03180f061b03),
+    U64_C (0x5645568a13acdc56), U64_C (0x440d441a49885e44),
+    U64_C (0x7fe17fdf9efea07f), U64_C (0xa99ea921374f88a9),
+    U64_C (0x2aa82a4d8254672a), U64_C (0xbbd6bbb16d6b0abb),
+    U64_C (0xc123c146e29f87c1), U64_C (0x535153a202a6f153),
+    U64_C (0xdc57dcae8ba572dc), U64_C (0x0b2c0b582716530b),
+    U64_C (0x9d4e9d9cd327019d), U64_C (0x6cad6c47c1d82b6c),
+    U64_C (0x31c43195f562a431), U64_C (0x74cd7487b9e8f374),
+    U64_C (0xf6fff6e309f115f6), U64_C (0x4605460a438c4c46),
+    U64_C (0xac8aac092645a5ac), U64_C (0x891e893c970fb589),
+    U64_C (0x145014a04428b414), U64_C (0xe1a3e15b42dfbae1),
+    U64_C (0x165816b04e2ca616), U64_C (0x3ae83acdd274f73a),
+    U64_C (0x69b9696fd0d20669), U64_C (0x092409482d124109),
+    U64_C (0x70dd70a7ade0d770), U64_C (0xb6e2b6d954716fb6),
+    U64_C (0xd067d0ceb7bd1ed0), U64_C (0xed93ed3b7ec7d6ed),
+    U64_C (0xcc17cc2edb85e2cc), U64_C (0x4215422a57846842),
+    U64_C (0x985a98b4c22d2c98), U64_C (0xa4aaa4490e55eda4),
+    U64_C (0x28a0285d88507528), U64_C (0x5c6d5cda31b8865c),
+    U64_C (0xf8c7f8933fed6bf8), U64_C (0x86228644a411c286),
+  };
+
+\f
+
+static void
+whirlpool_init (void *ctx)
+{
+  whirlpool_context_t *context = ctx;
+
+  memset (context, 0, sizeof (*context));
+}
+
+
+/*
+ * Transform block.
+ */
+static void
+whirlpool_transform (whirlpool_context_t *context, const unsigned char *data)
+{
+  whirlpool_block_t data_block;
+  whirlpool_block_t key;
+  whirlpool_block_t state;
+  whirlpool_block_t block;
+  unsigned int r;
+  unsigned int i;
+
+  buffer_to_block (data, data_block, i);
+  block_copy (key, context->hash_state, i);
+  block_copy (state, context->hash_state, i);
+  block_xor (state, data_block, i);
+
+  for (r = 0; r < R; r++)
+    {
+      /* Compute round key K^r.  */
+
+      block[0] = (C0[(key[0] >> 56) & 0xFF] ^ C1[(key[7] >> 48) & 0xFF] ^
+                 C2[(key[6] >> 40) & 0xFF] ^ C3[(key[5] >> 32) & 0xFF] ^
+                 C4[(key[4] >> 24) & 0xFF] ^ C5[(key[3] >> 16) & 0xFF] ^
+                 C6[(key[2] >>  8) & 0xFF] ^ C7[(key[1] >>  0) & 0xFF] ^ rc[r]);
+      block[1] = (C0[(key[1] >> 56) & 0xFF] ^ C1[(key[0] >> 48) & 0xFF] ^
+                 C2[(key[7] >> 40) & 0xFF] ^ C3[(key[6] >> 32) & 0xFF] ^
+                 C4[(key[5] >> 24) & 0xFF] ^ C5[(key[4] >> 16) & 0xFF] ^
+                 C6[(key[3] >>  8) & 0xFF] ^ C7[(key[2] >>  0) & 0xFF]);
+      block[2] = (C0[(key[2] >> 56) & 0xFF] ^ C1[(key[1] >> 48) & 0xFF] ^
+                 C2[(key[0] >> 40) & 0xFF] ^ C3[(key[7] >> 32) & 0xFF] ^
+                 C4[(key[6] >> 24) & 0xFF] ^ C5[(key[5] >> 16) & 0xFF] ^
+                 C6[(key[4] >>  8) & 0xFF] ^ C7[(key[3] >>  0) & 0xFF]);
+      block[3] = (C0[(key[3] >> 56) & 0xFF] ^ C1[(key[2] >> 48) & 0xFF] ^
+                 C2[(key[1] >> 40) & 0xFF] ^ C3[(key[0] >> 32) & 0xFF] ^
+                 C4[(key[7] >> 24) & 0xFF] ^ C5[(key[6] >> 16) & 0xFF] ^
+                 C6[(key[5] >>  8) & 0xFF] ^ C7[(key[4] >>  0) & 0xFF]);
+      block[4] = (C0[(key[4] >> 56) & 0xFF] ^ C1[(key[3] >> 48) & 0xFF] ^
+                 C2[(key[2] >> 40) & 0xFF] ^ C3[(key[1] >> 32) & 0xFF] ^
+                 C4[(key[0] >> 24) & 0xFF] ^ C5[(key[7] >> 16) & 0xFF] ^
+                 C6[(key[6] >>  8) & 0xFF] ^ C7[(key[5] >>  0) & 0xFF]);
+      block[5] = (C0[(key[5] >> 56) & 0xFF] ^ C1[(key[4] >> 48) & 0xFF] ^
+                 C2[(key[3] >> 40) & 0xFF] ^ C3[(key[2] >> 32) & 0xFF] ^
+                 C4[(key[1] >> 24) & 0xFF] ^ C5[(key[0] >> 16) & 0xFF] ^
+                 C6[(key[7] >>  8) & 0xFF] ^ C7[(key[6] >>  0) & 0xFF]);
+      block[6] = (C0[(key[6] >> 56) & 0xFF] ^ C1[(key[5] >> 48) & 0xFF] ^
+                 C2[(key[4] >> 40) & 0xFF] ^ C3[(key[3] >> 32) & 0xFF] ^
+                 C4[(key[2] >> 24) & 0xFF] ^ C5[(key[1] >> 16) & 0xFF] ^
+                 C6[(key[0] >>  8) & 0xFF] ^ C7[(key[7] >>  0) & 0xFF]);
+      block[7] = (C0[(key[7] >> 56) & 0xFF] ^ C1[(key[6] >> 48) & 0xFF] ^
+                 C2[(key[5] >> 40) & 0xFF] ^ C3[(key[4] >> 32) & 0xFF] ^
+                 C4[(key[3] >> 24) & 0xFF] ^ C5[(key[2] >> 16) & 0xFF] ^
+                 C6[(key[1] >>  8) & 0xFF] ^ C7[(key[0] >>  0) & 0xFF]);
+      block_copy (key, block, i);
+
+      /* Apply r-th round transformation.  */
+
+      block[0] = (C0[(state[0] >> 56) & 0xFF] ^ C1[(state[7] >> 48) & 0xFF] ^
+                 C2[(state[6] >> 40) & 0xFF] ^ C3[(state[5] >> 32) & 0xFF] ^
+                 C4[(state[4] >> 24) & 0xFF] ^ C5[(state[3] >> 16) & 0xFF] ^
+                 C6[(state[2] >>  8) & 0xFF] ^ C7[(state[1] >>  0) & 0xFF] ^ key[0]);
+      block[1] = (C0[(state[1] >> 56) & 0xFF] ^ C1[(state[0] >> 48) & 0xFF] ^
+                 C2[(state[7] >> 40) & 0xFF] ^ C3[(state[6] >> 32) & 0xFF] ^
+                 C4[(state[5] >> 24) & 0xFF] ^ C5[(state[4] >> 16) & 0xFF] ^
+                 C6[(state[3] >>  8) & 0xFF] ^ C7[(state[2] >>  0) & 0xFF] ^ key[1]);
+      block[2] = (C0[(state[2] >> 56) & 0xFF] ^ C1[(state[1] >> 48) & 0xFF] ^
+                 C2[(state[0] >> 40) & 0xFF] ^ C3[(state[7] >> 32) & 0xFF] ^
+                 C4[(state[6] >> 24) & 0xFF] ^ C5[(state[5] >> 16) & 0xFF] ^
+                 C6[(state[4] >>  8) & 0xFF] ^ C7[(state[3] >>  0) & 0xFF] ^ key[2]);
+      block[3] = (C0[(state[3] >> 56) & 0xFF] ^ C1[(state[2] >> 48) & 0xFF] ^
+                 C2[(state[1] >> 40) & 0xFF] ^ C3[(state[0] >> 32) & 0xFF] ^
+                 C4[(state[7] >> 24) & 0xFF] ^ C5[(state[6] >> 16) & 0xFF] ^
+                 C6[(state[5] >>  8) & 0xFF] ^ C7[(state[4] >>  0) & 0xFF] ^ key[3]);
+      block[4] = (C0[(state[4] >> 56) & 0xFF] ^ C1[(state[3] >> 48) & 0xFF] ^
+                 C2[(state[2] >> 40) & 0xFF] ^ C3[(state[1] >> 32) & 0xFF] ^
+                 C4[(state[0] >> 24) & 0xFF] ^ C5[(state[7] >> 16) & 0xFF] ^
+                 C6[(state[6] >>  8) & 0xFF] ^ C7[(state[5] >>  0) & 0xFF] ^ key[4]);
+      block[5] = (C0[(state[5] >> 56) & 0xFF] ^ C1[(state[4] >> 48) & 0xFF] ^
+                 C2[(state[3] >> 40) & 0xFF] ^ C3[(state[2] >> 32) & 0xFF] ^
+                 C4[(state[1] >> 24) & 0xFF] ^ C5[(state[0] >> 16) & 0xFF] ^
+                 C6[(state[7] >>  8) & 0xFF] ^ C7[(state[6] >>  0) & 0xFF] ^ key[5]);
+      block[6] = (C0[(state[6] >> 56) & 0xFF] ^ C1[(state[5] >> 48) & 0xFF] ^
+                 C2[(state[4] >> 40) & 0xFF] ^ C3[(state[3] >> 32) & 0xFF] ^
+                 C4[(state[2] >> 24) & 0xFF] ^ C5[(state[1] >> 16) & 0xFF] ^
+                 C6[(state[0] >>  8) & 0xFF] ^ C7[(state[7] >>  0) & 0xFF] ^ key[6]);
+      block[7] = (C0[(state[7] >> 56) & 0xFF] ^ C1[(state[6] >> 48) & 0xFF] ^
+                 C2[(state[5] >> 40) & 0xFF] ^ C3[(state[4] >> 32) & 0xFF] ^
+                 C4[(state[3] >> 24) & 0xFF] ^ C5[(state[2] >> 16) & 0xFF] ^
+                 C6[(state[1] >>  8) & 0xFF] ^ C7[(state[0] >>  0) & 0xFF] ^ key[7]);
+      block_copy (state, block, i);
+    }
+
+  /* Compression.  */
+
+  block_xor (context->hash_state, data_block, i);
+  block_xor (context->hash_state, state, i);
+}
+
+static void
+whirlpool_add (whirlpool_context_t *context,
+              const void *buffer_arg, size_t buffer_n)
+{
+  const unsigned char *buffer = buffer_arg;
+  u64 buffer_size;
+  unsigned int carry;
+  unsigned int i;
+
+  buffer_size = buffer_n;
+
+  if (context->count == BLOCK_SIZE)
+    {
+      /* Flush the buffer.  */
+      whirlpool_transform (context, context->buffer);
+      /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */
+      context->count = 0;
+    }
+  if (! buffer)
+    return; /* Nothing to add.  */
+
+  if (context->count)
+    {
+      while (buffer_n && (context->count < BLOCK_SIZE))
+       {
+         context->buffer[context->count++] = *buffer++;
+         buffer_n--;
+       }
+      whirlpool_add (context, NULL, 0);
+      if (!buffer_n)
+       /* Done.  */
+        return;
+    }
+  /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */
+
+  while (buffer_n >= BLOCK_SIZE) 
+    {
+      whirlpool_transform (context, buffer);
+      context->count = 0;
+      buffer_n -= BLOCK_SIZE;
+      buffer += BLOCK_SIZE;
+    }
+  while (buffer_n && (context->count < BLOCK_SIZE))
+    {
+      context->buffer[context->count++] = *buffer++;
+      buffer_n--;
+    }
+
+  /* Update bit counter.  */
+  carry = 0;
+  buffer_size <<= 3;
+  for (i = 1; i <= 32; i++)
+    {
+      if (! (buffer_size || carry))
+       break;
+
+      carry += context->length[32 - i] + (buffer_size & 0xFF);
+      context->length[32 - i] = carry;
+      buffer_size >>= 8;
+      carry >>= 8;
+    }
+  gcry_assert (! (buffer_size || carry));
+}
+
+static void
+whirlpool_write (void *ctx, const void *buffer, size_t buffer_n)
+{
+  whirlpool_context_t *context = ctx;
+
+  whirlpool_add (context, buffer, buffer_n);
+}
+
+static void
+whirlpool_final (void *ctx)
+{
+  whirlpool_context_t *context = ctx;
+  unsigned int i;
+
+  /* Flush.  */
+  whirlpool_add (context, NULL, 0);
+
+  /* Pad.  */
+  context->buffer[context->count++] = 0x80;
+
+  if (context->count > 32)
+    {
+      /* An extra block is necessary.  */
+      while (context->count < 64)
+       context->buffer[context->count++] = 0;
+      whirlpool_add (context, NULL, 0);
+    }
+  while (context->count < 32)
+    context->buffer[context->count++] = 0;
+
+  /* Add length of message.  */
+  memcpy (context->buffer + context->count, context->length, 32);
+  context->count += 32;
+  whirlpool_add (context, NULL, 0);
+
+  block_to_buffer (context->buffer, context->hash_state, i);
+}
+
+static byte *
+whirlpool_read (void *ctx)
+{
+  whirlpool_context_t *context = ctx;
+
+  return context->buffer;
+}
+
+gcry_md_spec_t _gcry_digest_spec_whirlpool =
+  {
+    "WHIRLPOOL", NULL, 0, NULL, 64,
+    whirlpool_init, whirlpool_write, whirlpool_final, whirlpool_read,
+    sizeof (whirlpool_context_t)
+  };
diff --git a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h
new file mode 100644 (file)
index 0000000..b4530c1
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_GCRY_WRAP_HEADER
+#define GRUB_GCRY_WRAP_HEADER 1
+
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/dl.h>
+#include <grub/crypto.h>
+
+#define __GNU_LIBRARY__
+
+#define DIM ARRAY_SIZE
+
+typedef grub_uint64_t u64;
+typedef grub_uint32_t u32;
+typedef grub_uint16_t u16;
+typedef grub_uint8_t byte;
+typedef grub_size_t size_t;
+
+#define U64_C(c) (c ## ULL)
+
+#define _gcry_burn_stack grub_burn_stack
+#define log_error(fmt, args...) grub_dprintf ("crypto", fmt, ## args)
+
+
+#define PUBKEY_FLAG_NO_BLINDING    (1 << 0)
+
+#define CIPHER_INFO_NO_WEAK_KEY    1
+
+#define HAVE_U64_TYPEDEF 1
+
+typedef union {
+    int a;
+    short b;
+    char c[1];
+    long d;
+#ifdef HAVE_U64_TYPEDEF
+    u64 e;
+#endif
+    float f;
+    double g;
+} PROPERLY_ALIGNED_TYPE;
+
+#define gcry_assert(x) grub_assert_real(GRUB_FILE, __LINE__, x)
+
+static inline void
+grub_assert_real (const char *file, int line, int cond)
+{
+  if (!cond)
+    grub_fatal ("Assertion failed at %s:%d\n", file, line);
+}
+
+/* Selftests are in separate modules.  */
+static inline char *
+selftest (void)
+{
+  return NULL;
+}
+
+static inline int
+fips_mode (void)
+{
+  return 0;
+}
+
+#define memset grub_memset
+
+#endif
diff --git a/grub-core/lib/mips/relocator.c b/grub-core/lib/mips/relocator.c
new file mode 100644 (file)
index 0000000..118ddbd
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+#include <grub/types.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/cache.h>
+
+#include <grub/mips/relocator.h>
+
+/* Remark: doesn't work with source outside of 4G.
+   Use relocator64 in this case. 
+ */
+
+extern grub_uint8_t grub_relocator32_forward_start;
+extern grub_uint8_t grub_relocator32_forward_end;
+extern grub_uint8_t grub_relocator32_backward_start;
+extern grub_uint8_t grub_relocator32_backward_end;
+
+#define REGW_SIZEOF (2 * sizeof (grub_uint32_t))
+#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t))
+
+#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator32_##x##_end \
+                                - &grub_relocator32_##x##_start)
+#define RELOCATOR_SIZEOF(x)    (RELOCATOR_SRC_SIZEOF(x) \
+                                + REGW_SIZEOF * (31 + 3) + JUMP_SIZEOF)
+#define RELOCATOR_ALIGN 16
+
+#define PREFIX(x) grub_relocator32_ ## x
+
+static void
+write_reg (int regn, grub_uint32_t val, void **target)
+{
+  /* lui $r, (val+0x8000).  */
+  *(grub_uint32_t *) *target = ((0x3c00 | regn) << 16) | ((val + 0x8000) >> 16);
+  *target = ((grub_uint32_t *) *target) + 1;
+  /* addiu $r, $r, val. */
+  *(grub_uint32_t *) *target = (((0x2400 | regn << 5 | regn) << 16)
+                               | (val & 0xffff));
+  *target = ((grub_uint32_t *) *target) + 1;
+}
+
+static void
+write_jump (int regn, void **target)
+{
+  /* j $r.  */
+  *(grub_uint32_t *) *target = (regn<<21) | 0x8;
+  *target = ((grub_uint32_t *) *target) + 1;
+  /* nop.  */
+  *(grub_uint32_t *) *target = 0;
+  *target = ((grub_uint32_t *) *target) + 1;
+}
+
+static void
+write_call_relocator_bw (void *ptr0, void *src, grub_uint32_t dest,
+                        grub_size_t size, struct grub_relocator32_state state)
+{
+  void *ptr = ptr0;
+  int i;
+  write_reg (8, (grub_uint32_t) src, &ptr);
+  write_reg (9, dest, &ptr);
+  write_reg (10, size, &ptr);
+  grub_memcpy (ptr, &grub_relocator32_backward_start,
+              RELOCATOR_SRC_SIZEOF (backward));
+  ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (backward);
+  for (i = 1; i < 32; i++)
+    write_reg (i, state.gpr[i], &ptr);
+  write_jump (state.jumpreg, &ptr);
+  grub_arch_sync_caches (ptr0, (grub_uint8_t *) ptr -  (grub_uint8_t *) ptr0);
+  grub_dprintf ("relocator", "Backward relocator: about to jump to %p\n", ptr0);
+  ((void (*) (void)) ptr0) ();
+}
+
+static void
+write_call_relocator_fw (void *ptr0, void *src, grub_uint32_t dest,
+                        grub_size_t size, struct grub_relocator32_state state)
+{
+  void *ptr = ptr0;
+  int i;
+  write_reg (8, (grub_uint32_t) src, &ptr);
+  write_reg (9, dest, &ptr);
+  write_reg (10, size, &ptr);
+  grub_memcpy (ptr, &grub_relocator32_forward_start,
+              RELOCATOR_SRC_SIZEOF (forward));
+  ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (forward);
+  for (i = 1; i < 32; i++)
+    write_reg (i, state.gpr[i], &ptr);
+  write_jump (state.jumpreg, &ptr);
+  grub_arch_sync_caches (ptr0, (grub_uint8_t *) ptr -  (grub_uint8_t *) ptr0);
+  grub_dprintf ("relocator", "Forward relocator: about to jump to %p\n", ptr0);
+  ((void (*) (void)) ptr0) ();
+}
+
+#include "../relocator.c"
diff --git a/grub-core/lib/mips/relocator_asm.S b/grub-core/lib/mips/relocator_asm.S
new file mode 100644 (file)
index 0000000..ff4fa31
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+       
+       .p2align        4       /* force 16-byte alignment */
+
+VARIABLE (grub_relocator32_forward_start)
+       move $a0, $9
+       move $a1, $10
+
+copycont1:     
+       lb $11,0($8)
+       sb $11,0($9)
+       addiu $8, $8, 0x1
+       addiu $9, $9, 0x1
+       addiu $10, $10, 0xffff
+       bne $10, $0, copycont1
+
+#include "../../kern/mips/cache_flush.S"
+
+VARIABLE (grub_relocator32_forward_end)
+
+VARIABLE (grub_relocator32_backward_start)
+       move $a0, $9
+       move $a1, $10
+
+       addu $9, $9, $10
+       addu $8, $8, $10
+       /* Backward movsl is implicitly off-by-one.  compensate that.  */
+       addiu $9, $9, 0xffff
+       addiu $8, $8, 0xffff
+copycont2:     
+       lb $11,0($8)
+       sb $11,0($9)
+       addiu $8, $8, 0xffff
+       addiu $9, $9, 0xffff
+       addiu $10, 0xffff
+       bne $10, $0, copycont2
+
+#include "../../kern/mips/cache_flush.S"
+
+VARIABLE (grub_relocator32_backward_end)
diff --git a/grub-core/lib/mips/setjmp.S b/grub-core/lib/mips/setjmp.S
new file mode 100644 (file)
index 0000000..8ab6222
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+       .file   "setjmp.S"
+
+       .text
+
+/*
+ * int grub_setjmp (grub_jmp_buf env)
+ */
+FUNCTION(grub_setjmp)
+       sw $s0, 0($a0)
+       sw $s1, 4($a0)
+       sw $s2, 8($a0)
+       sw $s3, 12($a0)
+       sw $s4, 16($a0)
+       sw $s5, 20($a0)
+       sw $s6, 24($a0)
+       sw $s7, 28($a0)
+       sw $s8, 32($a0)
+       sw $gp, 36($a0)
+       sw $sp, 40($a0)
+       sw $ra, 44($a0)
+       move $v0, $zero
+       move $v1, $zero
+       jr $ra
+/*
+ * int grub_longjmp (grub_jmp_buf env, int val)
+ */
+FUNCTION(grub_longjmp)
+       lw $s0, 0($a0)
+       lw $s1, 4($a0)
+       lw $s2, 8($a0)
+       lw $s3, 12($a0)
+       lw $s4, 16($a0)
+       lw $s5, 20($a0)
+       lw $s6, 24($a0)
+       lw $s7, 28($a0)
+       lw $s8, 32($a0)
+       lw $gp, 36($a0)
+       lw $sp, 40($a0)
+       lw $ra, 44($a0)
+       move $v0, $a1
+       bne  $v0, $zero, 1f
+       addiu $v0, $v0, 1
+1:     
+       move $v1, $zero
+       jr $ra
diff --git a/grub-core/lib/pbkdf2.c b/grub-core/lib/pbkdf2.c
new file mode 100644 (file)
index 0000000..083446a
--- /dev/null
@@ -0,0 +1,102 @@
+/* gc-pbkdf2-sha1.c --- Password-Based Key Derivation Function a'la PKCS#5
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2009 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* Written by Simon Josefsson.  */
+/* Imported from gnulib.  */
+
+#include <grub/crypto.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+/* Implement PKCS#5 PBKDF2 as per RFC 2898.  The PRF to use is HMAC variant
+   of digest supplied by MD.  Inputs are the password P of length PLEN,
+   the salt S of length SLEN, the iteration counter C (> 0), and the
+   desired derived output length DKLEN.  Output buffer is DK which
+   must have room for at least DKLEN octets.  The output buffer will
+   be filled with the derived data.  */
+gcry_err_code_t
+grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
+                   const grub_uint8_t *P, grub_size_t Plen,
+                   const grub_uint8_t *S, grub_size_t Slen,
+                   unsigned int c,
+                   grub_uint8_t *DK, grub_size_t dkLen)
+{
+  unsigned int hLen = md->mdlen;
+  grub_uint8_t U[md->mdlen];
+  grub_uint8_t T[md->mdlen];
+  unsigned int u;
+  unsigned int l;
+  unsigned int r;
+  unsigned int i;
+  unsigned int k;
+  gcry_err_code_t rc;
+  grub_uint8_t *tmp;
+  grub_size_t tmplen = Slen + 4;
+
+  if (c == 0)
+    return GPG_ERR_INV_ARG;
+
+  if (dkLen == 0)
+    return GPG_ERR_INV_ARG;
+
+  if (dkLen > 4294967295U)
+    return GPG_ERR_INV_ARG;
+
+  l = ((dkLen - 1) / hLen) + 1;
+  r = dkLen - (l - 1) * hLen;
+
+  tmp = grub_malloc (tmplen);
+  if (tmp == NULL)
+    return GPG_ERR_OUT_OF_MEMORY;
+
+  grub_memcpy (tmp, S, Slen);
+
+  for (i = 1; i <= l; i++)
+    {
+      grub_memset (T, 0, hLen);
+
+      for (u = 1; u <= c; u++)
+       {
+         if (u == 1)
+           {
+             tmp[Slen + 0] = (i & 0xff000000) >> 24;
+             tmp[Slen + 1] = (i & 0x00ff0000) >> 16;
+             tmp[Slen + 2] = (i & 0x0000ff00) >> 8;
+             tmp[Slen + 3] = (i & 0x000000ff) >> 0;
+
+             rc = grub_crypto_hmac_buffer (md, P, Plen, tmp, tmplen, U);
+           }
+         else
+           rc = grub_crypto_hmac_buffer (md, P, Plen, U, hLen, U);
+
+         if (rc != GPG_ERR_NO_ERROR)
+           {
+             grub_free (tmp);
+             return rc;
+           }
+
+         for (k = 0; k < hLen; k++)
+           T[k] ^= U[k];
+       }
+
+      grub_memcpy (DK + (i - 1) * hLen, T, i == l ? r : hLen);
+    }
+
+  grub_free (tmp);
+
+  return GPG_ERR_NO_ERROR;
+}
diff --git a/grub-core/lib/posix_wrap/assert.h b/grub-core/lib/posix_wrap/assert.h
new file mode 100644 (file)
index 0000000..94cfdd5
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_POSIX_ASSERT_H
+#define GRUB_POSIX_ASSERT_H    1
+
+#include <grub/misc.h>
+
+#define assert(x) assert_real(__FILE__, __LINE__, x)
+
+static inline void
+assert_real (const char *file, int line, int cond)
+{
+  if (!cond)
+    grub_fatal ("Assertion failed at %s:%d\n", file, line);
+}
+
+#endif
diff --git a/grub-core/lib/posix_wrap/ctype.h b/grub-core/lib/posix_wrap/ctype.h
new file mode 100644 (file)
index 0000000..2dc3e53
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_POSIX_CTYPE_H
+#define GRUB_POSIX_CTYPE_H     1
+
+#include <grub/misc.h>
+
+static inline int
+toupper (int c)
+{
+  return grub_toupper (c);
+}
+
+static inline int 
+isspace (int c)
+{
+  return grub_isspace (c);
+}
+
+static inline int 
+isdigit (int c)
+{
+  return grub_isdigit (c);
+}
+
+static inline int
+islower (int c)
+{
+  return (c >= 'a' && c <= 'z');
+}
+
+static inline int
+isupper (int c)
+{
+  return (c >= 'A' && c <= 'Z');
+}
+
+static inline int
+isxdigit (int c)
+{
+  return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')
+    || (c >= '0' && c <= '9');
+}
+
+static inline int 
+isprint (int c)
+{
+  return grub_isprint (c);
+}
+
+static inline int 
+iscntrl (int c)
+{
+  return !grub_isprint (c);
+}
+
+static inline int 
+isgraph (int c)
+{
+  return grub_isprint (c) && !grub_isspace (c);
+}
+
+static inline int
+isalnum (int c)
+{
+  return grub_isalpha (c) || grub_isdigit (c);
+}
+
+static inline int 
+ispunct (int c)
+{
+  return grub_isprint (c) && !grub_isspace (c) && !isalnum (c);
+}
+
+static inline int 
+isalpha (int c)
+{
+  return grub_isalpha (c);
+}
+
+static inline int
+tolower (int c)
+{
+  return grub_tolower (c);
+}
+
+#endif
diff --git a/grub-core/lib/posix_wrap/errno.h b/grub-core/lib/posix_wrap/errno.h
new file mode 100644 (file)
index 0000000..9031722
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_POSIX_ERRNO_H
+#define GRUB_POSIX_ERRNO_H     1
+
+#include <grub/err.h>
+
+#define errno  grub_errno
+#define EINVAL GRUB_ERR_BAD_NUMBER
+#define ENOMEM GRUB_ERR_OUT_OF_MEMORY
+
+#endif
diff --git a/grub-core/lib/posix_wrap/langinfo.h b/grub-core/lib/posix_wrap/langinfo.h
new file mode 100644 (file)
index 0000000..14833c0
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_POSIX_LANGINFO_H
+#define GRUB_POSIX_LANGINFO_H  1
+
+#include <localcharset.h>
+
+typedef enum { CODESET } nl_item;
+
+static inline char *
+nl_langinfo (nl_item item)
+{
+  switch (item)
+    {
+    case CODESET:
+      return locale_charset ();
+    default:
+      return "";
+    }
+}
+
+#endif
diff --git a/grub-core/lib/posix_wrap/limits.h b/grub-core/lib/posix_wrap/limits.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/grub-core/lib/posix_wrap/localcharset.h b/grub-core/lib/posix_wrap/localcharset.h
new file mode 100644 (file)
index 0000000..92eb815
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_POSIX_LOCALCHARSET_H
+#define GRUB_POSIX_LOCALCHARSET_H      1
+
+static inline char *
+locale_charset (void)
+{
+  return "UTF-8";
+}
+
+#endif
diff --git a/grub-core/lib/posix_wrap/locale.h b/grub-core/lib/posix_wrap/locale.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/grub-core/lib/posix_wrap/stdint.h b/grub-core/lib/posix_wrap/stdint.h
new file mode 100644 (file)
index 0000000..a12c43b
--- /dev/null
@@ -0,0 +1 @@
+#include <sys/types.h>
diff --git a/grub-core/lib/posix_wrap/stdio.h b/grub-core/lib/posix_wrap/stdio.h
new file mode 100644 (file)
index 0000000..701fcea
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_POSIX_STDIO_H
+#define GRUB_POSIX_STDIO_H     1
+
+#include <grub/misc.h>
+#include <grub/file.h>
+
+typedef struct grub_file FILE;
+
+#define EOF    -1
+
+#endif
diff --git a/grub-core/lib/posix_wrap/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h
new file mode 100644 (file)
index 0000000..4c725f6
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_POSIX_STDLIB_H
+#define GRUB_POSIX_STDLIB_H    1
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+static inline void 
+free (void *ptr)
+{
+  grub_free (ptr);
+}
+
+static inline void *
+malloc (grub_size_t size)
+{
+  return grub_malloc (size);
+}
+
+static inline void *
+calloc (grub_size_t size, grub_size_t nelem)
+{
+  return grub_zalloc (size * nelem);
+}
+
+static inline void *
+realloc (void *ptr, grub_size_t size)
+{
+  return grub_realloc (ptr, size);
+}
+
+static inline void
+abort (void)
+{
+  grub_abort ();
+}
+
+#define MB_CUR_MAX 6
+
+#endif
diff --git a/grub-core/lib/posix_wrap/string.h b/grub-core/lib/posix_wrap/string.h
new file mode 100644 (file)
index 0000000..4224836
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_POSIX_STRING_H
+#define GRUB_POSIX_STRING_H    1
+
+#include <grub/misc.h>
+
+static inline grub_size_t
+strlen (const char *s)
+{
+  return grub_strlen (s);
+}
+
+static inline int 
+strcmp (const char *s1, const char *s2)
+{
+  return grub_strcmp (s1, s2);
+}
+
+static inline int 
+strcasecmp (const char *s1, const char *s2)
+{
+  return grub_strcasecmp (s1, s2);
+}
+
+#endif
diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h
new file mode 100644 (file)
index 0000000..ce37940
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_POSIX_SYS_TYPES_H
+#define GRUB_POSIX_SYS_TYPES_H 1
+
+#include <grub/misc.h>
+
+typedef grub_size_t size_t;
+typedef int bool;
+static const bool true = 1;
+static const bool false = 0;
+
+#define ULONG_MAX GRUB_ULONG_MAX
+#define UCHAR_MAX 0xff
+
+#endif
diff --git a/grub-core/lib/posix_wrap/unistd.h b/grub-core/lib/posix_wrap/unistd.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/grub-core/lib/posix_wrap/wchar.h b/grub-core/lib/posix_wrap/wchar.h
new file mode 100644 (file)
index 0000000..fd56fd3
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_POSIX_WCHAR_H
+#define GRUB_POSIX_WCHAR_H     1
+
+/* UCS-4.  */
+typedef grub_uint32_t wchar_t;
+
+#endif
diff --git a/grub-core/lib/posix_wrap/wctype.h b/grub-core/lib/posix_wrap/wctype.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/grub-core/lib/powerpc/setjmp.S b/grub-core/lib/powerpc/setjmp.S
new file mode 100644 (file)
index 0000000..25cbaa3
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+       .file   "setjmp.S"
+
+       .text
+
+/*
+ * int grub_setjmp (grub_jmp_buf env)
+ */
+FUNCTION(grub_setjmp)
+       stw     1, 0(3)
+       stw     14, 4(3)
+       stw     15, 8(3)
+       stw     16, 12(3)
+       stw     17, 16(3)
+       stw     18, 20(3)
+       stw     19, 24(3)
+       stw     20, 28(3)
+       stw     21, 32(3)
+       stw     22, 36(3)
+       stw     23, 40(3)
+       stw     24, 44(3)
+       stw     25, 48(3)
+       stw     26, 52(3)
+       stw     27, 56(3)
+       stw     28, 60(3)
+       stw     29, 64(3)
+       stw     30, 68(3)
+       mflr    4
+       stw     4, 72(3)
+       mfcr    4
+       stw     4, 76(3)
+       li      3, 0
+       blr
+
+/*
+ * int grub_longjmp (grub_jmp_buf env, int val)
+ */
+FUNCTION(grub_longjmp)
+       lwz     1, 0(3)
+       lwz     14, 4(3)
+       lwz     15, 8(3)
+       lwz     16, 12(3)
+       lwz     17, 16(3)
+       lwz     18, 20(3)
+       lwz     19, 24(3)
+       lwz     20, 28(3)
+       lwz     21, 32(3)
+       lwz     22, 36(3)
+       lwz     23, 40(3)
+       lwz     24, 44(3)
+       lwz     25, 48(3)
+       lwz     26, 52(3)
+       lwz     27, 56(3)
+       lwz     28, 60(3)
+       lwz     29, 64(3)
+       lwz     30, 68(3)
+       lwz     5, 72(3)
+       mtlr    5
+       lwz     5, 76(3)
+       mtcr    5
+       mr.     3, 4
+       bne     1f
+       li      3, 1
+1:     blr
+
diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c
new file mode 100644 (file)
index 0000000..6a5acc5
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define MAX_OVERHEAD ((RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) \
+                     + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN) \
+                     + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)  \
+                     + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN))
+#define PRE_REGION_SIZE (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN)
+
+void *
+PREFIX (alloc) (grub_size_t size)
+{
+  char *playground;
+
+  playground = grub_malloc (size + MAX_OVERHEAD);
+  if (!playground)
+    return 0;
+
+  *(grub_size_t *) playground = size;
+
+  return playground + PRE_REGION_SIZE;
+}
+
+void *
+PREFIX (realloc) (void *relocator, grub_size_t size)
+{
+  char *playground;
+
+  if (!relocator)
+    return PREFIX (alloc) (size);
+
+  playground = (char *) relocator - PRE_REGION_SIZE;
+
+  playground = grub_realloc (playground, size + MAX_OVERHEAD);
+  if (!playground)
+    return 0;
+
+  *(grub_size_t *) playground = size;
+
+  return playground + PRE_REGION_SIZE;
+}
+
+void
+PREFIX(free) (void *relocator)
+{
+  if (relocator)
+    grub_free ((char *) relocator - PRE_REGION_SIZE);
+}
+
+grub_err_t
+PREFIX (boot) (void *relocator, grub_uint32_t dest,
+              struct grub_relocator32_state state)
+{
+  grub_size_t size;
+  char *playground;
+
+  playground = (char *) relocator - PRE_REGION_SIZE;
+  size = *(grub_size_t *) playground;
+
+  grub_dprintf ("relocator",
+               "Relocator: source: %p, destination: 0x%x, size: 0x%lx\n",
+               relocator, (unsigned) dest, (unsigned long) size);
+
+  /* Very unlikely condition: Relocator may risk overwrite itself.
+     Just move it a bit up.  */
+  if ((grub_addr_t) dest < (grub_addr_t) relocator
+      + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN)
+      && (grub_addr_t) dest + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)
+      > (grub_addr_t) relocator)
+    {
+      void *relocator_new = ((grub_uint8_t *) relocator)
+       + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)
+       + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN);
+      grub_dprintf ("relocator", "Overwrite condition detected moving "
+                   "relocator from %p to %p\n", relocator, relocator_new);
+      grub_memmove (relocator_new, relocator,
+                   (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)
+                   + size
+                   + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN));
+      relocator = relocator_new;
+    }
+
+  if ((grub_addr_t) dest >= (grub_addr_t) relocator)
+    {
+      int overhead;
+      overhead = dest -
+       ALIGN_UP (dest - RELOCATOR_SIZEOF (backward) - RELOCATOR_ALIGN,
+                 RELOCATOR_ALIGN);
+      grub_dprintf ("relocator",
+                   "Backward relocator: code %p, source: %p, "
+                   "destination: 0x%x, size: 0x%lx\n",
+                   (char *) relocator - overhead,
+                   (char *) relocator - overhead,
+                   (unsigned) dest - overhead,
+                   (unsigned long) size + overhead);
+
+      write_call_relocator_bw ((char *) relocator - overhead,
+                              (char *) relocator - overhead,
+                              dest - overhead, size + overhead, state);
+    }
+  else
+    {
+      int overhead;
+
+      overhead = ALIGN_UP (dest + size, RELOCATOR_ALIGN)
+       + RELOCATOR_SIZEOF (forward) - (dest + size);
+      grub_dprintf ("relocator",
+                   "Forward relocator: code %p, source: %p, "
+                   "destination: 0x%x, size: 0x%lx\n",
+                   (char *) relocator + size + overhead
+                   - RELOCATOR_SIZEOF (forward),
+                   relocator, (unsigned) dest,
+                   (unsigned long) size + overhead);
+
+      write_call_relocator_fw ((char *) relocator + size + overhead
+                              - RELOCATOR_SIZEOF (forward),
+                              relocator, dest, size + overhead, state);
+    }
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/lib/sparc64/setjmp.S b/grub-core/lib/sparc64/setjmp.S
new file mode 100644 (file)
index 0000000..0e23ecf
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+        .file   "setjmp.S"
+
+        .text
+
+/*
+ * int grub_setjmp (grub_jmp_buf env)
+ */
+FUNCTION(grub_setjmp)
+       stx     %o7, [%o0 + 0x00]
+       stx     %sp, [%o0 + 0x08]
+       stx     %fp, [%o0 + 0x10]
+       retl
+        clr    %o0
+
+/*
+ * int grub_longjmp (grub_jmp_buf env, int val)
+ */
+FUNCTION(grub_longjmp)
+       ldx     [%o0 + 0x10], %g1
+       movrz   %o1, 1, %o1
+       flushw
+       ldx     [%o0 + 0x00], %o7
+       ldx     [%o0 + 0x08], %fp
+       sub     %fp, 192, %sp
+       stx     %g1, [%sp + 2047 + (14 * 8)]
+       retl
+        restore %o1, 0, %o0
diff --git a/grub-core/lib/x86_64/setjmp.S b/grub-core/lib/x86_64/setjmp.S
new file mode 100644 (file)
index 0000000..621b09b
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+       .file   "setjmp.S"
+
+       .text
+
+/*
+ *  jmp_buf:
+ *   rbx rsp rbp r12 r13 r14 r15 rip
+ *   0   8   16  24  32  40  48  56
+ */
+
+/*
+ * int grub_setjmp (grub_jmp_buf env)
+ */
+FUNCTION(grub_setjmp)
+       pop     %rsi            /* Return address, and adjust the stack */
+       xorq    %rax, %rax
+       movq    %rbx, 0(%rdi)   /* RBX */
+       movq    %rsp, 8(%rdi)   /* RSP */
+       push    %rsi
+       movq    %rbp, 16(%rdi)  /* RBP */
+       movq    %r12, 24(%rdi)  /* R12 */
+       movq    %r13, 32(%rdi)  /* R13 */
+       movq    %r14, 40(%rdi)  /* R14 */
+       movq    %r15, 48(%rdi)  /* R15 */
+       movq    %rsi, 56(%rdi)  /* RSI */
+       ret
+
+/*
+ * int grub_longjmp (grub_jmp_buf env, int val)
+ */
+FUNCTION(grub_longjmp)
+       movl    %esi, %eax
+       orl     %eax, %eax
+       jnz     1f
+       incl    %eax
+1:
+
+       movq    (%rdi), %rbx
+       movq    8(%rdi), %rsp
+       movq    16(%rdi), %rbp
+       movq    24(%rdi), %r12
+       movq    32(%rdi), %r13
+       movq    40(%rdi), %r14
+       movq    48(%rdi), %r15
+       jmp     *56(%rdi)
diff --git a/grub-core/loader/aout.c b/grub-core/loader/aout.c
new file mode 100644 (file)
index 0000000..0254b6a
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *  Copyright (C) 2008 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/aout.h>
+
+int
+grub_aout_get_type (union grub_aout_header *header)
+{
+  int magic;
+
+  magic = AOUT_GETMAGIC (header->aout32);
+  if ((magic == AOUT32_OMAGIC) || (magic == AOUT32_NMAGIC) ||
+      (magic == AOUT32_ZMAGIC) || (magic == AOUT32_QMAGIC))
+    return AOUT_TYPE_AOUT32;
+  else if ((magic == AOUT64_OMAGIC) || (magic == AOUT64_NMAGIC) ||
+          (magic == AOUT64_ZMAGIC))
+    return AOUT_TYPE_AOUT64;
+  else
+    return AOUT_TYPE_NONE;
+}
+
+grub_err_t
+grub_aout_load (grub_file_t file, int offset,
+                grub_addr_t load_addr,
+               int load_size,
+                grub_addr_t bss_end_addr)
+{
+  if ((grub_file_seek (file, offset)) == (grub_off_t) - 1)
+    return grub_errno;
+
+  if (!load_size)
+    load_size = file->size - offset;
+
+  grub_file_read (file, (void *) load_addr, load_size);
+
+  if (grub_errno)
+    return grub_errno;
+
+  if (bss_end_addr)
+    grub_memset ((char *) load_addr + load_size, 0,
+                 bss_end_addr - load_addr - load_size);
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/loader/efi/appleloader.c b/grub-core/loader/efi/appleloader.c
new file mode 100644 (file)
index 0000000..dc42683
--- /dev/null
@@ -0,0 +1,332 @@
+/* appleloader.c - apple legacy boot loader.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static grub_dl_t my_mod;
+
+static grub_efi_handle_t image_handle;
+static grub_efi_char16_t *cmdline;
+
+static grub_err_t
+grub_appleloader_unload (void)
+{
+  grub_efi_boot_services_t *b;
+
+  b = grub_efi_system_table->boot_services;
+  efi_call_1 (b->unload_image, image_handle);
+
+  grub_free (cmdline);
+  cmdline = 0;
+
+  grub_dl_unref (my_mod);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_appleloader_boot (void)
+{
+  grub_efi_boot_services_t *b;
+
+  b = grub_efi_system_table->boot_services;
+  efi_call_3 (b->start_image, image_handle, 0, 0);
+
+  grub_appleloader_unload ();
+
+  return grub_errno;
+}
+
+struct piwg_full_device_path
+{
+  struct grub_efi_memory_mapped_device_path comp1;
+  struct grub_efi_piwg_device_path comp2;
+  struct grub_efi_device_path end;
+};
+
+/* early 2006 Core Duo / Core Solo models  */
+static struct piwg_full_device_path devpath_1 =
+{
+  .comp1 =
+  {
+    .header = {
+      .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE,
+      .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE,
+      .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0}
+    },
+    .memory_type = GRUB_EFI_MEMORY_MAPPED_IO,
+    .start_address = 0xffe00000,
+    .end_address = 0xfff9ffff
+  },
+  .comp2 =
+  {
+    .header = {
+      .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
+      .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE,
+      .length = {sizeof (struct grub_efi_piwg_device_path), 0}
+    },
+    .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B,
+                                         0x01, 0xAE, 0xF2, 0xB7}}
+  },
+  .end =
+  {
+    .type = GRUB_EFI_END_DEVICE_PATH_TYPE,
+    .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    .length = {sizeof (struct grub_efi_device_path), 0}
+  }
+};
+
+/* mid-2006 Mac Pro (and probably other Core 2 models)  */
+static struct piwg_full_device_path devpath_2 =
+{
+  .comp1 =
+  {
+    .header = {
+      .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE,
+      .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE,
+      .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0}
+    },
+    .memory_type = GRUB_EFI_MEMORY_MAPPED_IO,
+    .start_address = 0xffe00000,
+    .end_address = 0xfff7ffff
+  },
+  .comp2 =
+  {
+    .header = {
+      .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
+      .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE,
+      .length = {sizeof (struct grub_efi_piwg_device_path), 0}
+    },
+    .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B,
+                                         0x01, 0xAE, 0xF2, 0xB7}}
+  },
+  .end =
+  {
+    .type = GRUB_EFI_END_DEVICE_PATH_TYPE,
+    .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    .length = {sizeof (struct grub_efi_device_path), 0}
+  }
+};
+
+/* mid-2007 MBP ("Santa Rosa" based models)  */
+static struct piwg_full_device_path devpath_3 =
+{
+  .comp1 =
+  {
+    .header = {
+      .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE,
+      .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE,
+      .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0}
+    },
+    .memory_type = GRUB_EFI_MEMORY_MAPPED_IO,
+    .start_address = 0xffe00000,
+    .end_address = 0xfff8ffff
+  },
+  .comp2 =
+  {
+    .header = {
+      .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
+      .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE,
+      .length = {sizeof (struct grub_efi_piwg_device_path), 0}
+    },
+    .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B,
+                                         0x01, 0xAE, 0xF2, 0xB7}}
+  },
+  .end =
+  {
+    .type = GRUB_EFI_END_DEVICE_PATH_TYPE,
+    .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    .length = {sizeof (struct grub_efi_device_path), 0}
+  }
+};
+
+/* early-2008 MBA  */
+static struct piwg_full_device_path devpath_4 =
+{
+  .comp1 =
+  {
+    .header = {
+      .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE,
+      .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE,
+      .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0}
+    },
+    .memory_type = GRUB_EFI_MEMORY_MAPPED_IO,
+    .start_address = 0xffc00000,
+    .end_address = 0xfff8ffff
+  },
+  .comp2 =
+  {
+    .header = {
+      .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
+      .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE,
+      .length = {sizeof (struct grub_efi_piwg_device_path), 0}
+    },
+    .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B,
+                                         0x01, 0xAE, 0xF2, 0xB7}}
+  },
+  .end =
+  {
+    .type = GRUB_EFI_END_DEVICE_PATH_TYPE,
+    .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    .length = {sizeof (struct grub_efi_device_path), 0}
+  }
+};
+
+/* late-2008 MB/MBP (NVidia chipset)  */
+static struct piwg_full_device_path devpath_5 =
+{
+  .comp1 =
+  {
+    .header = {
+      .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE,
+      .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE,
+      .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0}
+    },
+    .memory_type = GRUB_EFI_MEMORY_MAPPED_IO,
+    .start_address = 0xffcb4000,
+    .end_address = 0xffffbfff
+  },
+  .comp2 =
+  {
+    .header = {
+      .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
+      .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE,
+      .length = {sizeof (struct grub_efi_piwg_device_path), 0}
+    },
+    .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B,
+                                         0x01, 0xAE, 0xF2, 0xB7}}
+  },
+  .end =
+  {
+    .type = GRUB_EFI_END_DEVICE_PATH_TYPE,
+    .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    .length = {sizeof (struct grub_efi_device_path), 0}
+  }
+};
+
+struct devdata
+{
+  char *model;
+  grub_efi_device_path_t *devpath;
+};
+
+struct devdata devs[] =
+{
+  {"Core Duo/Solo", (grub_efi_device_path_t *) &devpath_1},
+  {"Mac Pro", (grub_efi_device_path_t *) &devpath_2},
+  {"MBP", (grub_efi_device_path_t *) &devpath_3},
+  {"MBA", (grub_efi_device_path_t *) &devpath_4},
+  {"MB NV", (grub_efi_device_path_t *) &devpath_5},
+  {NULL, NULL},
+};
+
+static grub_err_t
+grub_cmd_appleloader (grub_command_t cmd __attribute__ ((unused)),
+                      int argc, char *argv[])
+{
+  grub_efi_boot_services_t *b;
+  grub_efi_loaded_image_t *loaded_image;
+  struct devdata *pdev;
+
+  grub_dl_ref (my_mod);
+
+  /* Initialize some global variables.  */
+  image_handle = 0;
+
+  b = grub_efi_system_table->boot_services;
+
+  for (pdev = devs ; pdev->devpath ; pdev++)
+    if (efi_call_6 (b->load_image, 0, grub_efi_image_handle, pdev->devpath,
+                    NULL, 0, &image_handle) == GRUB_EFI_SUCCESS)
+      break;
+
+  if (! pdev->devpath)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "can't find model");
+      goto fail;
+    }
+
+  grub_printf ("Model : %s\n", pdev->model);
+
+  loaded_image = grub_efi_get_loaded_image (image_handle);
+  if (! loaded_image)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
+      goto fail;
+    }
+
+  if (argc > 0)
+    {
+      int i, len;
+      grub_efi_char16_t *p16;
+
+      for (i = 0, len = 0; i < argc; i++)
+        len += grub_strlen (argv[i]) + 1;
+
+      len *= sizeof (grub_efi_char16_t);
+      cmdline = p16 = grub_malloc (len);
+      if (! cmdline)
+        goto fail;
+
+      for (i = 0; i < argc; i++)
+        {
+          char *p8;
+
+          p8 = argv[i];
+          while (*p8)
+            *(p16++) = *(p8++);
+
+          *(p16++) = ' ';
+        }
+      *(--p16) = 0;
+
+      loaded_image->load_options = cmdline;
+      loaded_image->load_options_size = len;
+    }
+
+  grub_loader_set (grub_appleloader_boot, grub_appleloader_unload, 0);
+
+  return 0;
+
+ fail:
+
+  grub_dl_unref (my_mod);
+  return grub_errno;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(appleloader)
+{
+  cmd = grub_register_command ("appleloader", grub_cmd_appleloader,
+                              "[OPTS]", N_("Boot legacy system."));
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(appleloader)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
new file mode 100644 (file)
index 0000000..a095ad9
--- /dev/null
@@ -0,0 +1,347 @@
+/* chainloader.c - boot another boot loader */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* TODO: support load options.  */
+
+#include <grub/loader.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/charset.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/disk.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static grub_dl_t my_mod;
+
+static grub_efi_physical_address_t address;
+static grub_efi_uintn_t pages;
+static grub_efi_device_path_t *file_path;
+static grub_efi_handle_t image_handle;
+static grub_efi_char16_t *cmdline;
+
+static grub_err_t
+grub_chainloader_unload (void)
+{
+  grub_efi_boot_services_t *b;
+
+  b = grub_efi_system_table->boot_services;
+  efi_call_1 (b->unload_image, image_handle);
+  efi_call_2 (b->free_pages, address, pages);
+
+  grub_free (file_path);
+  grub_free (cmdline);
+  cmdline = 0;
+
+  grub_dl_unref (my_mod);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_chainloader_boot (void)
+{
+  grub_efi_boot_services_t *b;
+  grub_efi_status_t status;
+  grub_efi_uintn_t exit_data_size;
+  grub_efi_char16_t *exit_data;
+
+  b = grub_efi_system_table->boot_services;
+  status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data);
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      if (exit_data)
+       {
+         char *buf;
+
+         buf = grub_malloc (exit_data_size * 4 + 1);
+         if (buf)
+           {
+             *grub_utf16_to_utf8 ((grub_uint8_t *) buf,
+                                  exit_data, exit_data_size) = 0;
+
+             grub_error (GRUB_ERR_BAD_OS, buf);
+             grub_free (buf);
+           }
+         else
+           grub_error (GRUB_ERR_BAD_OS, "unknown error");
+       }
+    }
+
+  if (exit_data)
+    efi_call_1 (b->free_pool, exit_data);
+
+  grub_chainloader_unload ();
+
+  return grub_errno;
+}
+
+static void
+copy_file_path (grub_efi_file_path_device_path_t *fp,
+               const char *str, grub_efi_uint16_t len)
+{
+  grub_efi_char16_t *p;
+  grub_efi_uint16_t size;
+
+  fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
+  fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
+  size = len * sizeof (grub_efi_char16_t) + sizeof (*fp);
+  fp->header.length[0] = (grub_efi_uint8_t) (size & 0xff);
+  fp->header.length[1] = (grub_efi_uint8_t) (size >> 8);
+  for (p = fp->path_name; len > 0; len--, p++, str++)
+    {
+      /* FIXME: this assumes that the path is in ASCII.  */
+      *p = (grub_efi_char16_t) (*str == '/' ? '\\' : *str);
+    }
+}
+
+static grub_efi_device_path_t *
+make_file_path (grub_efi_device_path_t *dp, const char *filename)
+{
+  char *dir_start;
+  char *dir_end;
+  grub_size_t size;
+  grub_efi_device_path_t *d;
+
+  dir_start = grub_strchr (filename, ')');
+  if (! dir_start)
+    dir_start = (char *) filename;
+  else
+    dir_start++;
+
+  dir_end = grub_strrchr (dir_start, '/');
+  if (! dir_end)
+    {
+      grub_error (GRUB_ERR_BAD_FILENAME, "invalid EFI file path");
+      return 0;
+    }
+
+  size = 0;
+  d = dp;
+  while (1)
+    {
+      size += GRUB_EFI_DEVICE_PATH_LENGTH (d);
+      if ((GRUB_EFI_END_ENTIRE_DEVICE_PATH (d)))
+       break;
+      d = GRUB_EFI_NEXT_DEVICE_PATH (d);
+    }
+
+  file_path = grub_malloc (size
+                          + ((grub_strlen (dir_start) + 1)
+                             * sizeof (grub_efi_char16_t))
+                          + sizeof (grub_efi_file_path_device_path_t) * 2);
+  if (! file_path)
+    return 0;
+
+  grub_memcpy (file_path, dp, size);
+
+  /* Fill the file path for the directory.  */
+  d = (grub_efi_device_path_t *) ((char *) file_path
+                                 + ((char *) d - (char *) dp));
+  grub_efi_print_device_path (d);
+  copy_file_path ((grub_efi_file_path_device_path_t *) d,
+                 dir_start, dir_end - dir_start);
+
+  /* Fill the file path for the file.  */
+  d = GRUB_EFI_NEXT_DEVICE_PATH (d);
+  copy_file_path ((grub_efi_file_path_device_path_t *) d,
+                 dir_end + 1, grub_strlen (dir_end + 1));
+
+  /* Fill the end of device path nodes.  */
+  d = GRUB_EFI_NEXT_DEVICE_PATH (d);
+  d->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+  d->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+  d->length[0] = sizeof (*d);
+  d->length[1] = 0;
+
+  return file_path;
+}
+
+static grub_err_t
+grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
+                     int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  grub_efi_status_t status;
+  grub_efi_boot_services_t *b;
+  grub_efi_handle_t dev_handle = 0;
+  grub_device_t dev = 0;
+  grub_efi_device_path_t *dp = 0;
+  grub_efi_loaded_image_t *loaded_image;
+  char *filename;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
+  filename = argv[0];
+
+  grub_dl_ref (my_mod);
+
+  /* Initialize some global variables.  */
+  address = 0;
+  image_handle = 0;
+  file_path = 0;
+
+  b = grub_efi_system_table->boot_services;
+
+  file = grub_file_open (filename);
+  if (! file)
+    goto fail;
+
+  /* Get the root device's device path.  */
+  dev = grub_device_open (0);
+  if (! dev)
+    goto fail;
+
+  if (dev->disk)
+    {
+      dev_handle = grub_efidisk_get_device_handle (dev->disk);
+      if (dev_handle)
+       dp = grub_efi_get_device_path (dev_handle);
+    }
+
+  if (! dev->disk || ! dev_handle || ! dp)
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "not a valid root device");
+      goto fail;
+    }
+
+  file_path = make_file_path (dp, filename);
+  if (! file_path)
+    goto fail;
+
+  grub_printf ("file path: ");
+  grub_efi_print_device_path (file_path);
+
+  size = grub_file_size (file);
+  pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12);
+
+  status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES,
+                             GRUB_EFI_LOADER_CODE,
+                             pages, &address);
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate %u pages", pages);
+      goto fail;
+    }
+
+  if (grub_file_read (file, (void *) ((grub_addr_t) address), size) != size)
+    {
+      if (grub_errno == GRUB_ERR_NONE)
+       grub_error (GRUB_ERR_BAD_OS, "too small");
+
+      goto fail;
+    }
+
+  status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path,
+                         (void *) ((grub_addr_t) address), size,
+                         &image_handle);
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      if (status == GRUB_EFI_OUT_OF_RESOURCES)
+       grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources");
+      else
+       grub_error (GRUB_ERR_BAD_OS, "cannot load image");
+
+      goto fail;
+    }
+
+  /* LoadImage does not set a device handler when the image is
+     loaded from memory, so it is necessary to set it explicitly here.
+     This is a mess.  */
+  loaded_image = grub_efi_get_loaded_image (image_handle);
+  if (! loaded_image)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
+      goto fail;
+    }
+  loaded_image->device_handle = dev_handle;
+
+  grub_file_close (file);
+
+  if (argc > 1)
+    {
+      int i, len;
+      grub_efi_char16_t *p16;
+
+      for (i = 1, len = 0; i < argc; i++)
+        len += grub_strlen (argv[i]) + 1;
+
+      len *= sizeof (grub_efi_char16_t);
+      cmdline = p16 = grub_malloc (len);
+      if (! cmdline)
+        goto fail;
+
+      for (i = 1; i < argc; i++)
+        {
+          char *p8;
+
+          p8 = argv[i];
+          while (*p8)
+            *(p16++) = *(p8++);
+
+          *(p16++) = ' ';
+        }
+      *(--p16) = 0;
+
+      loaded_image->load_options = cmdline;
+      loaded_image->load_options_size = len;
+    }
+
+  grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
+  return 0;
+
+ fail:
+
+  if (dev)
+    grub_device_close (dev);
+
+  if (file)
+    grub_file_close (file);
+
+  if (file_path)
+    grub_free (file_path);
+
+  if (address)
+    efi_call_2 (b->free_pages, address, pages);
+
+  grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(chainloader)
+{
+  cmd = grub_register_command ("chainloader", grub_cmd_chainloader,
+                              0, N_("Load another boot loader."));
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(chainloader)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c
new file mode 100644 (file)
index 0000000..3c7fe2f
--- /dev/null
@@ -0,0 +1,1326 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/cpu/loader.h>
+#include <grub/cpu/bsd.h>
+#include <grub/i386/cpuid.h>
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/memory.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/elfload.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/gzio.h>
+#include <grub/aout.h>
+#include <grub/command.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+#include <grub/video.h>
+#ifdef GRUB_MACHINE_PCBIOS
+#include <grub/machine/biosnum.h>
+#endif
+#include <grub/disk.h>
+#include <grub/device.h>
+#include <grub/partition.h>
+
+#define ALIGN_DWORD(a) ALIGN_UP (a, 4)
+#define ALIGN_QWORD(a) ALIGN_UP (a, 8)
+#define ALIGN_VAR(a)   ((is_64bit) ? (ALIGN_QWORD(a)) : (ALIGN_DWORD(a)))
+#define ALIGN_PAGE(a)  ALIGN_UP (a, 4096)
+
+#define MOD_BUF_ALLOC_UNIT     4096
+
+static int kernel_type = KERNEL_TYPE_NONE;
+static grub_dl_t my_mod;
+static grub_addr_t entry, entry_hi, kern_start, kern_end;
+static grub_uint32_t bootflags;
+static char *mod_buf;
+static grub_uint32_t mod_buf_len, mod_buf_max, kern_end_mdofs;
+static int is_elf_kernel, is_64bit;
+static char *netbsd_root = NULL;
+static grub_uint32_t openbsd_root;
+
+static const struct grub_arg_option freebsd_opts[] =
+  {
+    {"dual", 'D', 0, N_("Display output on all consoles."), 0, 0},
+    {"serial", 'h', 0, N_("Use serial console."), 0, 0},
+    {"askname", 'a', 0, N_("Ask for file name to reboot from."), 0, 0},
+    {"cdrom", 'C', 0, N_("Use CDROM as root."), 0, 0},
+    {"config", 'c', 0, N_("Invoke user configuration routing."), 0, 0},
+    {"kdb", 'd', 0, N_("Enter in KDB on boot."), 0, 0},
+    {"gdb", 'g', 0, N_("Use GDB remote debugger instead of DDB."), 0, 0},
+    {"mute", 'm', 0, N_("Disable all boot output."), 0, 0},
+    {"nointr", 'n', 0, "", 0, 0},
+    {"pause", 'p', 0, N_("Wait for keypress after every line of output."), 0, 0},
+    {"quiet", 'q', 0, "", 0, 0},
+    {"dfltroot", 'r', 0, N_("Use compiled-in rootdev."), 0, 0},
+    {"single", 's', 0, N_("Boot into single mode."), 0, 0},
+    {"verbose", 'v', 0, N_("Boot with verbose messages."), 0, 0},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static const grub_uint32_t freebsd_flags[] =
+{
+  FREEBSD_RB_DUAL, FREEBSD_RB_SERIAL, FREEBSD_RB_ASKNAME,
+  FREEBSD_RB_CDROM, FREEBSD_RB_CONFIG, FREEBSD_RB_KDB,
+  FREEBSD_RB_GDB, FREEBSD_RB_MUTE, FREEBSD_RB_NOINTR,
+  FREEBSD_RB_PAUSE, FREEBSD_RB_QUIET, FREEBSD_RB_DFLTROOT,
+  FREEBSD_RB_SINGLE, FREEBSD_RB_VERBOSE, 0
+};
+
+static const struct grub_arg_option openbsd_opts[] =
+  {
+    {"askname", 'a', 0, N_("Ask for file name to reboot from."), 0, 0},
+    {"halt", 'b', 0, N_("Don't reboot, just halt."), 0, 0},
+    {"config", 'c', 0, N_("Change configured devices."), 0, 0},
+    {"single", 's', 0, N_("Boot into single mode."), 0, 0},
+    {"kdb", 'd', 0, N_("Enter in KDB on boot."), 0, 0},
+    {"root", 'r', 0, N_("Set root device."), "wdXY", ARG_TYPE_STRING},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static const grub_uint32_t openbsd_flags[] =
+{
+  OPENBSD_RB_ASKNAME, OPENBSD_RB_HALT, OPENBSD_RB_CONFIG,
+  OPENBSD_RB_SINGLE, OPENBSD_RB_KDB, 0
+};
+
+#define OPENBSD_ROOT_ARG (ARRAY_SIZE (openbsd_flags) - 1)
+
+static const struct grub_arg_option netbsd_opts[] =
+  {
+    {"no-smp", '1', 0, N_("Disable SMP."), 0, 0},
+    {"no-acpi", '2', 0, N_("Disable ACPI."), 0, 0},
+    {"askname", 'a', 0, N_("Ask for file name to reboot from."), 0, 0},
+    {"halt", 'b', 0, N_("Don't reboot, just halt."), 0, 0},
+    {"config", 'c', 0, N_("Change configured devices."), 0, 0},
+    {"kdb", 'd', 0, N_("Enter in KDB on boot."), 0, 0},
+    {"miniroot", 'm', 0, "", 0, 0},
+    {"quiet", 'q', 0, N_("Don't display boot diagnostic messages."), 0, 0},
+    {"single", 's', 0, N_("Boot into single mode."), 0, 0},
+    {"verbose", 'v', 0, N_("Boot with verbose messages."), 0, 0},
+    {"debug", 'x', 0, N_("Boot with debug messages."), 0, 0},
+    {"silent", 'z', 0, N_("Supress normal output (warnings remain)."), 0, 0},
+    {"root", 'r', 0, N_("Set root device."), N_("DEVICE"), ARG_TYPE_STRING},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static const grub_uint32_t netbsd_flags[] =
+{
+  NETBSD_AB_NOSMP, NETBSD_AB_NOACPI, NETBSD_RB_ASKNAME,
+  NETBSD_RB_HALT, NETBSD_RB_USERCONFIG, NETBSD_RB_KDB,
+  NETBSD_RB_MINIROOT, NETBSD_AB_QUIET, NETBSD_RB_SINGLE,
+  NETBSD_AB_VERBOSE, NETBSD_AB_DEBUG, NETBSD_AB_SILENT, 0
+};
+
+#define NETBSD_ROOT_ARG (ARRAY_SIZE (netbsd_flags) - 1)
+
+static void
+grub_bsd_get_device (grub_uint32_t * biosdev,
+                    grub_uint32_t * unit,
+                    grub_uint32_t * slice, grub_uint32_t * part)
+{
+  grub_device_t dev;
+
+#ifdef GRUB_MACHINE_PCBIOS
+  *biosdev = grub_get_root_biosnumber () & 0xff;
+#else
+  *biosdev = 0xff;
+#endif
+  *unit = (*biosdev & 0x7f);
+  *slice = 0xff;
+  *part = 0xff;
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->partition)
+    {
+      if (dev->disk->partition->parent)
+       {
+         *part = dev->disk->partition->number;
+         *slice = dev->disk->partition->parent->number + 1;
+       }
+      else
+       *slice = dev->disk->partition->number + 1;
+    }
+  if (dev)
+    grub_device_close (dev);
+}
+
+grub_err_t
+grub_freebsd_add_meta (grub_uint32_t type, void *data, grub_uint32_t len)
+{
+  if (mod_buf_max < mod_buf_len + len + 8)
+    {
+      char *new_buf;
+
+      do
+       {
+         mod_buf_max += MOD_BUF_ALLOC_UNIT;
+       }
+      while (mod_buf_max < mod_buf_len + len + 8);
+
+      new_buf = grub_malloc (mod_buf_max);
+      if (!new_buf)
+       return grub_errno;
+
+      grub_memcpy (new_buf, mod_buf, mod_buf_len);
+      grub_free (mod_buf);
+
+      mod_buf = new_buf;
+    }
+
+  *((grub_uint32_t *) (mod_buf + mod_buf_len)) = type;
+  *((grub_uint32_t *) (mod_buf + mod_buf_len + 4)) = len;
+  mod_buf_len += 8;
+
+  if (len)
+    grub_memcpy (mod_buf + mod_buf_len, data, len);
+
+  mod_buf_len = ALIGN_VAR (mod_buf_len + len);
+
+  return GRUB_ERR_NONE;
+}
+
+struct grub_e820_mmap
+{
+  grub_uint64_t addr;
+  grub_uint64_t size;
+  grub_uint32_t type;
+} __attribute__((packed));
+#define GRUB_E820_RAM        1
+#define GRUB_E820_RESERVED   2
+#define GRUB_E820_ACPI       3
+#define GRUB_E820_NVS        4
+#define GRUB_E820_EXEC_CODE  5
+
+static grub_err_t
+grub_freebsd_add_mmap (void)
+{
+  grub_size_t len = 0;
+  struct grub_e820_mmap *mmap_buf = 0;
+  struct grub_e820_mmap *mmap = 0;
+  int isfirstrun = 1;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
+                            grub_uint32_t type)
+    {
+      /* FreeBSD assumes that first 64KiB are available.
+        Not always true but try to prevent panic somehow. */
+      if (isfirstrun && addr != 0)
+       {
+         if (mmap)
+           {
+             mmap->addr = 0;
+             mmap->size = (addr < 0x10000) ? addr : 0x10000;
+             mmap->type = GRUB_E820_RAM;
+             mmap++;
+           }
+         else
+           len += sizeof (struct grub_e820_mmap);
+       }
+      isfirstrun = 0;
+      if (mmap)
+       {
+         mmap->addr = addr;
+         mmap->size = size;
+         switch (type)
+           {
+           case GRUB_MACHINE_MEMORY_AVAILABLE:
+             mmap->type = GRUB_E820_RAM;
+             break;
+
+#ifdef GRUB_MACHINE_MEMORY_ACPI
+           case GRUB_MACHINE_MEMORY_ACPI:
+             mmap->type = GRUB_E820_ACPI;
+             break;
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_NVS
+           case GRUB_MACHINE_MEMORY_NVS:
+             mmap->type = GRUB_E820_NVS;
+             break;
+#endif
+
+           default:
+#ifdef GRUB_MACHINE_MEMORY_CODE
+           case GRUB_MACHINE_MEMORY_CODE:
+#endif
+#ifdef GRUB_MACHINE_MEMORY_RESERVED
+           case GRUB_MACHINE_MEMORY_RESERVED:
+#endif
+             mmap->type = GRUB_E820_RESERVED;
+             break;
+           }
+
+         /* Merge regions if possible. */
+         if (mmap != mmap_buf && mmap->type == mmap[-1].type &&
+             mmap->addr == mmap[-1].addr + mmap[-1].size)
+           mmap[-1].size += mmap->size;
+         else
+           mmap++;
+       }
+      else
+       len += sizeof (struct grub_e820_mmap);
+
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+  mmap_buf = mmap = grub_malloc (len);
+  if (! mmap)
+    return grub_errno;
+
+  isfirstrun = 1;
+  grub_mmap_iterate (hook);
+
+  len = (mmap - mmap_buf) * sizeof (struct grub_e820_mmap);
+  int i;
+  for (i = 0; i < mmap - mmap_buf; i++)
+    grub_dprintf ("bsd", "smap %d, %d:%llx - %llx\n", i,
+                 mmap_buf[i].type,
+                 (unsigned long long) mmap_buf[i].addr,
+                 (unsigned long long) mmap_buf[i].size);
+
+  grub_dprintf ("bsd", "%d entries in smap\n", mmap - mmap_buf);
+  grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+                        FREEBSD_MODINFOMD_SMAP, mmap_buf, len);
+
+  grub_free (mmap_buf);
+
+  return grub_errno;
+}
+
+grub_err_t
+grub_freebsd_add_meta_module (char *filename, char *type, int argc, char **argv,
+                             grub_addr_t addr, grub_uint32_t size)
+{
+  char *name;
+  name = grub_strrchr (filename, '/');
+  if (name)
+    name++;
+  else
+    name = filename;
+  if (grub_strcmp (type, "/boot/zfs/zpool.cache") == 0)
+    name = "/boot/zfs/zpool.cache";
+
+  if (grub_freebsd_add_meta (FREEBSD_MODINFO_NAME, name,
+                            grub_strlen (name) + 1))
+    return grub_errno;
+
+  if (is_64bit)
+    {
+      grub_uint64_t addr64 = addr, size64 = size;
+      if ((grub_freebsd_add_meta (FREEBSD_MODINFO_TYPE, type,
+                             grub_strlen (type) + 1)) ||
+         (grub_freebsd_add_meta (FREEBSD_MODINFO_ADDR, &addr64,
+                                 sizeof (addr64))) ||
+         (grub_freebsd_add_meta (FREEBSD_MODINFO_SIZE, &size64,
+                                 sizeof (size64))))
+       return grub_errno;
+    }
+  else
+    {
+      if ((grub_freebsd_add_meta (FREEBSD_MODINFO_TYPE, type,
+                                 grub_strlen (type) + 1)) ||
+         (grub_freebsd_add_meta (FREEBSD_MODINFO_ADDR, &addr,
+                                 sizeof (addr))) ||
+         (grub_freebsd_add_meta (FREEBSD_MODINFO_SIZE, &size,
+                                 sizeof (size))))
+       return grub_errno;
+    }
+
+  if (argc)
+    {
+      int i, n;
+
+      n = 0;
+      for (i = 0; i < argc; i++)
+       {
+         n += grub_strlen (argv[i]) + 1;
+       }
+
+      if (n)
+       {
+         char cmdline[n], *p;
+
+         p = cmdline;
+         for (i = 0; i < argc; i++)
+           {
+             grub_strcpy (p, argv[i]);
+             p += grub_strlen (argv[i]);
+             *(p++) = ' ';
+           }
+         *p = 0;
+
+         if (grub_freebsd_add_meta (FREEBSD_MODINFO_ARGS, cmdline, n))
+           return grub_errno;
+       }
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_freebsd_list_modules (void)
+{
+  grub_uint32_t pos = 0;
+
+  grub_printf ("  %-18s  %-18s%14s%14s\n", "name", "type", "addr", "size");
+  while (pos < mod_buf_len)
+    {
+      grub_uint32_t type, size;
+
+      type = *((grub_uint32_t *) (mod_buf + pos));
+      size = *((grub_uint32_t *) (mod_buf + pos + 4));
+      pos += 8;
+      switch (type)
+       {
+       case FREEBSD_MODINFO_NAME:
+       case FREEBSD_MODINFO_TYPE:
+         grub_printf ("  %-18s", mod_buf + pos);
+         break;
+       case FREEBSD_MODINFO_ADDR:
+         {
+           grub_addr_t addr;
+
+           addr = *((grub_addr_t *) (mod_buf + pos));
+           grub_printf ("    0x%08x", addr);
+           break;
+         }
+       case FREEBSD_MODINFO_SIZE:
+         {
+           grub_uint32_t len;
+
+           len = *((grub_uint32_t *) (mod_buf + pos));
+           grub_printf ("    0x%08x\n", len);
+         }
+       }
+
+      pos = ALIGN_VAR (pos + size);
+    }
+}
+
+/* This function would be here but it's under different license. */
+#include "bsd_pagetable.c"
+
+struct gdt_descriptor
+{
+  grub_uint16_t limit;
+  void *base;
+} __attribute__ ((packed));
+
+static grub_err_t
+grub_freebsd_boot (void)
+{
+  struct grub_freebsd_bootinfo bi;
+  char *p;
+  grub_uint32_t bootdev, biosdev, unit, slice, part;
+
+  auto int iterate_env (struct grub_env_var *var);
+  int iterate_env (struct grub_env_var *var)
+  {
+    if ((!grub_memcmp (var->name, "kFreeBSD.", sizeof("kFreeBSD.") - 1)) && (var->name[sizeof("kFreeBSD.") - 1]))
+      {
+       grub_strcpy (p, &var->name[sizeof("kFreeBSD.") - 1]);
+       p += grub_strlen (p);
+       *(p++) = '=';
+       grub_strcpy (p, var->value);
+       p += grub_strlen (p) + 1;
+      }
+
+    return 0;
+  }
+
+  grub_memset (&bi, 0, sizeof (bi));
+  bi.version = FREEBSD_BOOTINFO_VERSION;
+  bi.length = sizeof (bi);
+
+  grub_bsd_get_device (&biosdev, &unit, &slice, &part);
+  bootdev = (FREEBSD_B_DEVMAGIC + ((slice + 1) << FREEBSD_B_SLICESHIFT) +
+            (unit << FREEBSD_B_UNITSHIFT) + (part << FREEBSD_B_PARTSHIFT));
+
+  bi.boot_device = biosdev;
+
+  p = (char *) kern_end;
+
+  grub_env_iterate (iterate_env);
+
+  if (p != (char *) kern_end)
+    {
+      *(p++) = 0;
+
+      bi.environment = kern_end;
+      kern_end = ALIGN_PAGE ((grub_uint32_t) p);
+    }
+
+  if (is_elf_kernel)
+    {
+      grub_addr_t md_ofs;
+      int ofs;
+
+      if (grub_freebsd_add_meta (FREEBSD_MODINFO_END, 0, 0))
+       return grub_errno;
+
+      grub_memcpy ((char *) kern_end, mod_buf, mod_buf_len);
+      bi.tags = kern_end;
+
+      kern_end = ALIGN_PAGE (kern_end + mod_buf_len);
+
+      if (is_64bit)
+       kern_end += 4096 * 4;
+
+      md_ofs = bi.tags + kern_end_mdofs;
+      ofs = (is_64bit) ? 16 : 12;
+      *((grub_uint32_t *) md_ofs) = kern_end;
+      md_ofs -= ofs;
+      *((grub_uint32_t *) md_ofs) = bi.environment;
+      md_ofs -= ofs;
+      *((grub_uint32_t *) md_ofs) = bootflags;
+    }
+
+  bi.kern_end = kern_end;
+
+  grub_video_set_mode ("text", 0, 0);
+
+  if (is_64bit)
+    {
+      grub_uint32_t *gdt;
+      grub_uint8_t *trampoline;
+      void (*launch_trampoline) (grub_addr_t entry_lo, ...)
+       __attribute__ ((cdecl, regparm (0)));
+      grub_uint8_t *pagetable;
+
+      struct gdt_descriptor *gdtdesc;
+
+      pagetable = (grub_uint8_t *) (kern_end - 16384);
+      fill_bsd64_pagetable (pagetable);
+
+      /* Create GDT. */
+      gdt = (grub_uint32_t *) (kern_end - 4096);
+      gdt[0] = 0;
+      gdt[1] = 0;
+      gdt[2] = 0;
+      gdt[3] = 0x00209800;
+      gdt[4] = 0;
+      gdt[5] = 0x00008000;
+
+      /* Create GDT descriptor. */
+      gdtdesc = (struct gdt_descriptor *) (kern_end - 4096 + 24);
+      gdtdesc->limit = 24;
+      gdtdesc->base = gdt;
+
+      /* Prepare trampoline. */
+      trampoline = (grub_uint8_t *) (kern_end - 4096 + 24
+                                    + sizeof (struct gdt_descriptor));
+      launch_trampoline = (void  __attribute__ ((cdecl, regparm (0)))
+                          (*) (grub_addr_t entry_lo, ...)) trampoline;
+      grub_bsd64_trampoline_gdt = (grub_uint32_t) gdtdesc;
+      grub_bsd64_trampoline_selfjump
+       = (grub_uint32_t) (trampoline + 6
+                          + ((grub_uint8_t *) &grub_bsd64_trampoline_selfjump
+                             - &grub_bsd64_trampoline_start));
+
+      /* Copy trampoline. */
+      grub_memcpy (trampoline, &grub_bsd64_trampoline_start,
+                  &grub_bsd64_trampoline_end - &grub_bsd64_trampoline_start);
+
+      /* Launch trampoline. */
+      launch_trampoline (entry, entry_hi, pagetable, bi.tags,
+                        kern_end);
+    }
+  else
+    grub_unix_real_boot (entry, bootflags | FREEBSD_RB_BOOTINFO, bootdev,
+                        0, 0, 0, &bi, bi.tags, kern_end);
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_openbsd_boot (void)
+{
+  char *buf = (char *) GRUB_BSD_TEMP_BUFFER;
+  struct grub_openbsd_bios_mmap *pm;
+  struct grub_openbsd_bootargs *pa;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      pm->addr = addr;
+      pm->len = size;
+
+      switch (type)
+        {
+        case GRUB_MACHINE_MEMORY_AVAILABLE:
+         pm->type = OPENBSD_MMAP_AVAILABLE;
+         break;
+
+        case GRUB_MACHINE_MEMORY_ACPI:
+         pm->type = OPENBSD_MMAP_ACPI;
+         break;
+
+        case GRUB_MACHINE_MEMORY_NVS:
+         pm->type = OPENBSD_MMAP_NVS;
+         break;
+
+       default:
+         pm->type = OPENBSD_MMAP_RESERVED;
+         break;
+       }
+      pm++;
+
+      return 0;
+    }
+
+  pa = (struct grub_openbsd_bootargs *) buf;
+
+  pa->ba_type = OPENBSD_BOOTARG_MMAP;
+  pm = (struct grub_openbsd_bios_mmap *) (pa + 1);
+  grub_mmap_iterate (hook);
+
+  /* Memory map terminator.  */
+  pm->addr = 0;
+  pm->len = 0;
+  pm->type = 0;
+  pm++;
+
+  pa->ba_size = (char *) pm - (char *) pa;
+  pa->ba_next = (struct grub_openbsd_bootargs *) pm;
+  pa = pa->ba_next;
+  pa->ba_type = OPENBSD_BOOTARG_END;
+  pa++;
+
+  grub_video_set_mode ("text", 0, 0);
+
+  grub_unix_real_boot (entry, bootflags, openbsd_root, OPENBSD_BOOTARG_APIVER,
+                      0, (grub_uint32_t) (grub_mmap_get_upper () >> 10),
+                      (grub_uint32_t) (grub_mmap_get_lower () >> 10),
+                      (char *) pa - buf, buf);
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_netbsd_boot (void)
+{
+  struct grub_netbsd_bootinfo *bootinfo;
+  int count = 0;
+  struct grub_netbsd_btinfo_mmap_header *mmap;
+  struct grub_netbsd_btinfo_mmap_entry *pm;
+  void *curarg;
+
+  auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
+                                  grub_uint64_t size __attribute__ ((unused)),
+                                  grub_uint32_t type __attribute__ ((unused)))
+  {
+    count++;
+    return 0;
+  }
+
+  auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+  {
+    pm->addr = addr;
+    pm->len = size;
+
+    switch (type)
+      {
+      case GRUB_MACHINE_MEMORY_AVAILABLE:
+       pm->type = NETBSD_MMAP_AVAILABLE;
+       break;
+
+      case GRUB_MACHINE_MEMORY_ACPI:
+       pm->type = NETBSD_MMAP_ACPI;
+       break;
+
+      case GRUB_MACHINE_MEMORY_NVS:
+       pm->type = NETBSD_MMAP_NVS;
+       break;
+
+      default:
+       pm->type = NETBSD_MMAP_RESERVED;
+       break;
+      }
+    pm++;
+
+    return 0;
+  }
+
+  grub_mmap_iterate (count_hook);
+
+  if (kern_end + sizeof (struct grub_netbsd_btinfo_rootdevice)
+      + sizeof (struct grub_netbsd_bootinfo)
+      + sizeof (struct grub_netbsd_btinfo_mmap_header)
+      + count * sizeof (struct grub_netbsd_btinfo_mmap_entry)
+      > grub_os_area_addr + grub_os_area_size)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
+
+  curarg = mmap = (struct grub_netbsd_btinfo_mmap_header *) kern_end;
+  pm = (struct grub_netbsd_btinfo_mmap_entry *) (mmap + 1);
+
+  grub_mmap_iterate (fill_hook);
+  mmap->common.type = NETBSD_BTINFO_MEMMAP;
+  mmap->common.len = (char *) pm - (char *) mmap;
+  mmap->count = count;
+  curarg = pm;
+
+  if (netbsd_root)
+    {
+      struct grub_netbsd_btinfo_rootdevice *rootdev;
+
+      rootdev = (struct grub_netbsd_btinfo_rootdevice *) curarg;
+
+      rootdev->common.len = sizeof (struct grub_netbsd_btinfo_rootdevice);
+      rootdev->common.type = NETBSD_BTINFO_ROOTDEVICE;
+      grub_strncpy (rootdev->devname, netbsd_root, sizeof (rootdev->devname));
+
+      bootinfo = (struct grub_netbsd_bootinfo *) (rootdev + 1);
+      bootinfo->bi_count = 2;
+      bootinfo->bi_data[0] = mmap;
+      bootinfo->bi_data[1] = rootdev;
+    }
+  else
+    {
+      bootinfo = (struct grub_netbsd_bootinfo *) curarg;
+      bootinfo->bi_count = 1;
+      bootinfo->bi_data[0] = mmap;
+    }
+
+  grub_video_set_mode ("text", 0, 0);
+
+  grub_unix_real_boot (entry, bootflags, 0, bootinfo,
+                      0, (grub_uint32_t) (grub_mmap_get_upper () >> 10),
+                      (grub_uint32_t) (grub_mmap_get_lower () >> 10));
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_bsd_unload (void)
+{
+  if (mod_buf)
+    {
+      grub_free (mod_buf);
+      mod_buf = 0;
+      mod_buf_max = 0;
+    }
+
+  kernel_type = KERNEL_TYPE_NONE;
+  grub_dl_unref (my_mod);
+
+  grub_free (netbsd_root);
+  netbsd_root = NULL;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_bsd_load_aout (grub_file_t file)
+{
+  grub_addr_t load_addr, bss_end_addr;
+  int ofs, align_page;
+  union grub_aout_header ah;
+
+  if ((grub_file_seek (file, 0)) == (grub_off_t) - 1)
+    return grub_errno;
+
+  if (grub_file_read (file, &ah, sizeof (ah)) != sizeof (ah))
+    return grub_error (GRUB_ERR_READ_ERROR, "cannot read the a.out header");
+
+  if (grub_aout_get_type (&ah) != AOUT_TYPE_AOUT32)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid a.out header");
+
+  entry = ah.aout32.a_entry & 0xFFFFFF;
+
+  if (AOUT_GETMAGIC (ah.aout32) == AOUT32_ZMAGIC)
+    {
+      load_addr = entry;
+      ofs = 0x1000;
+      align_page = 0;
+    }
+  else
+    {
+      load_addr = entry & 0xF00000;
+      ofs = sizeof (struct grub_aout32_header);
+      align_page = 1;
+    }
+
+  if (load_addr < 0x100000)
+    return grub_error (GRUB_ERR_BAD_OS, "load address below 1M");
+
+  kern_start = load_addr;
+  kern_end = load_addr + ah.aout32.a_text + ah.aout32.a_data;
+  if (align_page)
+    kern_end = ALIGN_PAGE (kern_end);
+
+  if (ah.aout32.a_bss)
+    {
+      kern_end += ah.aout32.a_bss;
+      if (align_page)
+       kern_end = ALIGN_PAGE (kern_end);
+
+      bss_end_addr = kern_end;
+    }
+  else
+    bss_end_addr = 0;
+
+  return grub_aout_load (file, ofs, load_addr,
+                        ah.aout32.a_text + ah.aout32.a_data, bss_end_addr);
+}
+
+static grub_err_t
+grub_bsd_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr, int *do_load)
+{
+  Elf32_Addr paddr;
+
+  if (phdr->p_type != PT_LOAD
+      && phdr->p_type != PT_DYNAMIC)
+    {
+      *do_load = 0;
+      return 0;
+    }
+
+  *do_load = 1;
+  phdr->p_paddr &= 0xFFFFFF;
+  paddr = phdr->p_paddr;
+
+  if ((paddr < grub_os_area_addr)
+      || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "address 0x%x is out of range",
+                      paddr);
+
+  if ((!kern_start) || (paddr < kern_start))
+    kern_start = paddr;
+
+  if (paddr + phdr->p_memsz > kern_end)
+    kern_end = paddr + phdr->p_memsz;
+
+  *addr = paddr;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_bsd_elf64_hook (Elf64_Phdr * phdr, grub_addr_t * addr, int *do_load)
+{
+  Elf64_Addr paddr;
+
+  if (phdr->p_type != PT_LOAD
+      && phdr->p_type != PT_DYNAMIC)
+    {
+      *do_load = 0;
+      return 0;
+    }
+
+  *do_load = 1;
+  paddr = phdr->p_paddr & 0xffffff;
+
+  if ((paddr < grub_os_area_addr)
+      || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "address 0x%x is out of range",
+                      paddr);
+
+  if ((!kern_start) || (paddr < kern_start))
+    kern_start = paddr;
+
+  if (paddr + phdr->p_memsz > kern_end)
+    kern_end = paddr + phdr->p_memsz;
+
+  *addr = paddr;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_bsd_load_elf (grub_elf_t elf)
+{
+  kern_start = kern_end = 0;
+
+  if (grub_elf_is_elf32 (elf))
+    {
+      entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFF;
+      return grub_elf32_load (elf, grub_bsd_elf32_hook, 0, 0);
+    }
+  else if (grub_elf_is_elf64 (elf))
+    {
+      is_64bit = 1;
+
+      if (! grub_cpuid_has_longmode)
+       return grub_error (GRUB_ERR_BAD_OS, "your CPU does not implement AMD64 architecture");
+
+      /* FreeBSD has 64-bit entry point.  */
+      if (kernel_type == KERNEL_TYPE_FREEBSD)
+       {
+         entry = elf->ehdr.ehdr64.e_entry & 0xffffffff;
+         entry_hi = (elf->ehdr.ehdr64.e_entry >> 32) & 0xffffffff;
+       }
+      else
+       {
+         entry = elf->ehdr.ehdr64.e_entry & 0x0fffffff;
+         entry_hi = 0;
+       }
+      return grub_elf64_load (elf, grub_bsd_elf64_hook, 0, 0);
+    }
+  else
+    return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
+}
+
+static grub_err_t
+grub_bsd_load (int argc, char *argv[])
+{
+  grub_file_t file;
+  grub_elf_t elf;
+
+  grub_dl_ref (my_mod);
+
+  grub_loader_unset ();
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
+      goto fail;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (!file)
+    goto fail;
+
+  elf = grub_elf_file (file);
+  if (elf)
+    {
+      is_elf_kernel = 1;
+      grub_bsd_load_elf (elf);
+      grub_elf_close (elf);
+    }
+  else
+    {
+      is_elf_kernel = 0;
+      grub_errno = 0;
+      grub_bsd_load_aout (file);
+      grub_file_close (file);
+    }
+
+fail:
+
+  if (grub_errno != GRUB_ERR_NONE)
+    grub_dl_unref (my_mod);
+
+  return grub_errno;
+}
+
+static grub_uint32_t
+grub_bsd_parse_flags (const struct grub_arg_list *state,
+                     const grub_uint32_t * flags)
+{
+  grub_uint32_t result = 0;
+  unsigned i;
+
+  for (i = 0; flags[i]; i++)
+    if (state[i].set)
+      result |= flags[i];
+
+  return result;
+}
+
+static grub_err_t
+grub_cmd_freebsd (grub_extcmd_t cmd, int argc, char *argv[])
+{
+  kernel_type = KERNEL_TYPE_FREEBSD;
+  bootflags = grub_bsd_parse_flags (cmd->state, freebsd_flags);
+
+  if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
+    {
+      kern_end = ALIGN_PAGE (kern_end);
+      if (is_elf_kernel)
+       {
+         grub_err_t err;
+         grub_uint64_t data = 0;
+         grub_file_t file;
+         int len = is_64bit ? 8 : 4;
+
+         err = grub_freebsd_add_meta_module (argv[0], is_64bit
+                                             ? FREEBSD_MODTYPE_KERNEL64
+                                             : FREEBSD_MODTYPE_KERNEL,
+                                             argc - 1, argv + 1,
+                                             kern_start,
+                                             kern_end - kern_start);
+         if (err)
+           return err;
+
+         file = grub_gzfile_open (argv[0], 1);
+         if (! file)
+           return grub_errno;
+
+         if (is_64bit)
+           err = grub_freebsd_load_elf_meta64 (file, &kern_end);
+         else
+           err = grub_freebsd_load_elf_meta32 (file, &kern_end);
+         if (err)
+           return err;
+
+         err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+                                      FREEBSD_MODINFOMD_HOWTO, &data, 4);
+         if (err)
+           return err;
+
+         err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+                                      FREEBSD_MODINFOMD_ENVP, &data, len);
+         if (err)
+           return err;
+
+         err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+                                      FREEBSD_MODINFOMD_KERNEND, &data, len);
+         if (err)
+           return err;
+
+         kern_end_mdofs = mod_buf_len - len;
+
+         err = grub_freebsd_add_mmap ();
+         if (err)
+           return err;
+       }
+      grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 1);
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_openbsd (grub_extcmd_t cmd, int argc, char *argv[])
+{
+  grub_uint32_t bootdev;
+
+  kernel_type = KERNEL_TYPE_OPENBSD;
+  bootflags = grub_bsd_parse_flags (cmd->state, openbsd_flags);
+
+  if (cmd->state[OPENBSD_ROOT_ARG].set)
+    {
+      const char *arg = cmd->state[OPENBSD_ROOT_ARG].arg;
+      int unit, part;
+      if (*(arg++) != 'w' || *(arg++) != 'd')
+       return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                          "only device specifications of form "
+                          "wd<number><lowercase letter> are supported");
+
+      unit = grub_strtoul (arg, (char **) &arg, 10);
+      if (! (arg && *arg >= 'a' && *arg <= 'z'))
+       return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                          "only device specifications of form "
+                          "wd<number><lowercase letter> are supported");
+
+      part = *arg - 'a';
+
+      bootdev = (OPENBSD_B_DEVMAGIC + (unit << OPENBSD_B_UNITSHIFT) +
+                (part << OPENBSD_B_PARTSHIFT));
+    }
+  else
+    bootdev = 0;
+
+  if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
+    {
+      grub_loader_set (grub_openbsd_boot, grub_bsd_unload, 1);
+      openbsd_root = bootdev;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_netbsd (grub_extcmd_t cmd, int argc, char *argv[])
+{
+  kernel_type = KERNEL_TYPE_NETBSD;
+  bootflags = grub_bsd_parse_flags (cmd->state, netbsd_flags);
+
+  if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
+    {
+      grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 1);
+      if (cmd->state[NETBSD_ROOT_ARG].set)
+       netbsd_root = grub_strdup (cmd->state[NETBSD_ROOT_ARG].arg);
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_freebsd_loadenv (grub_command_t cmd __attribute__ ((unused)),
+                         int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  char *buf = 0, *curr, *next;
+  int len;
+
+  if (kernel_type == KERNEL_TYPE_NONE)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "you need to load the kernel first");
+
+  if (kernel_type != KERNEL_TYPE_FREEBSD)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "only FreeBSD supports environment");
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no filename");
+      goto fail;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if ((!file) || (!file->size))
+    goto fail;
+
+  len = file->size;
+  buf = grub_malloc (len + 1);
+  if (!buf)
+    goto fail;
+
+  if (grub_file_read (file, buf, len) != len)
+    goto fail;
+
+  buf[len] = 0;
+
+  next = buf;
+  while (next)
+    {
+      char *p;
+
+      curr = next;
+      next = grub_strchr (curr, '\n');
+      if (next)
+       {
+
+         p = next - 1;
+         while (p > curr)
+           {
+             if ((*p != '\r') && (*p != ' ') && (*p != '\t'))
+               break;
+             p--;
+           }
+
+         if ((p > curr) && (*p == '"'))
+           p--;
+
+         *(p + 1) = 0;
+         next++;
+       }
+
+      if (*curr == '#')
+       continue;
+
+      p = grub_strchr (curr, '=');
+      if (!p)
+       continue;
+
+      *(p++) = 0;
+
+      if (*curr)
+       {
+         char *name;
+
+         if (*p == '"')
+           p++;
+
+         name = grub_xasprintf ("kFreeBSD.%s", curr);
+         if (!name)
+           goto fail;
+         if (grub_env_set (name, p))
+           {
+             grub_free (name);
+             goto fail;
+           }
+         grub_free (name);
+       }
+    }
+
+fail:
+  grub_free (buf);
+
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)),
+                        int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_err_t err;
+  int modargc;
+  char **modargv;
+  char *type;
+
+  if (kernel_type == KERNEL_TYPE_NONE)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "you need to load the kernel first");
+
+  if (kernel_type != KERNEL_TYPE_FREEBSD)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "only FreeBSD supports module");
+
+  if (!is_elf_kernel)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "only ELF kernel supports module");
+
+  /* List the current modules if no parameter.  */
+  if (!argc)
+    {
+      grub_freebsd_list_modules ();
+      return 0;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if ((!file) || (!file->size))
+    goto fail;
+
+  if (kern_end + file->size > grub_os_area_addr + grub_os_area_size)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "not enough memory for the module");
+      goto fail;
+    }
+
+  grub_file_read (file, (void *) kern_end, file->size);
+  if (grub_errno)
+    goto fail;
+
+  modargc = argc - 1;
+  modargv = argv + 1;
+
+  if (modargc && (! grub_memcmp (modargv[0], "type=", 5)))
+    {
+      type = &modargv[0][5];
+      modargc--;
+      modargv++;
+    }
+  else
+    type = FREEBSD_MODTYPE_RAW;
+
+  err = grub_freebsd_add_meta_module (argv[0], type, modargc, modargv,
+                                     kern_end, file->size);
+  if (err)
+    goto fail;
+
+  kern_end = ALIGN_PAGE (kern_end + file->size);
+
+fail:
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_freebsd_module_elf (grub_command_t cmd __attribute__ ((unused)),
+                            int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_err_t err;
+
+  if (kernel_type == KERNEL_TYPE_NONE)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "you need to load the kernel first");
+
+  if (kernel_type != KERNEL_TYPE_FREEBSD)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "only FreeBSD supports module");
+
+  if (! is_elf_kernel)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "only ELF kernel supports module");
+
+  /* List the current modules if no parameter.  */
+  if (! argc)
+    {
+      grub_freebsd_list_modules ();
+      return 0;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (!file)
+    return grub_errno;
+  if (!file->size)
+    {
+      grub_file_close (file);
+      return grub_errno;
+    }
+
+  if (is_64bit)
+    err = grub_freebsd_load_elfmodule_obj64 (file, argc, argv, &kern_end);
+  else
+    err = grub_freebsd_load_elfmodule32 (file, argc, argv, &kern_end);
+  grub_file_close (file);
+
+  return err;
+}
+
+
+static grub_extcmd_t cmd_freebsd, cmd_openbsd, cmd_netbsd;
+static grub_command_t cmd_freebsd_loadenv, cmd_freebsd_module;
+static grub_command_t cmd_freebsd_module_elf;
+
+GRUB_MOD_INIT (bsd)
+{
+  cmd_freebsd = grub_register_extcmd ("kfreebsd", grub_cmd_freebsd,
+                                     GRUB_COMMAND_FLAG_BOTH,
+                                     N_("FILE"), N_("Load kernel of FreeBSD."),
+                                     freebsd_opts);
+  cmd_openbsd = grub_register_extcmd ("kopenbsd", grub_cmd_openbsd,
+                                     GRUB_COMMAND_FLAG_BOTH,
+                                     N_("FILE"), N_("Load kernel of OpenBSD."),
+                                     openbsd_opts);
+  cmd_netbsd = grub_register_extcmd ("knetbsd", grub_cmd_netbsd,
+                                    GRUB_COMMAND_FLAG_BOTH,
+                                    N_("FILE"), N_("Load kernel of NetBSD."),
+                                    netbsd_opts);
+  cmd_freebsd_loadenv =
+    grub_register_command ("kfreebsd_loadenv", grub_cmd_freebsd_loadenv,
+                          0, N_("Load FreeBSD env."));
+  cmd_freebsd_module =
+    grub_register_command ("kfreebsd_module", grub_cmd_freebsd_module,
+                          0, N_("Load FreeBSD kernel module."));
+  cmd_freebsd_module_elf =
+    grub_register_command ("kfreebsd_module_elf", grub_cmd_freebsd_module_elf,
+                          0, N_("Load FreeBSD kernel module (ELF)."));
+
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI (bsd)
+{
+  grub_unregister_extcmd (cmd_freebsd);
+  grub_unregister_extcmd (cmd_openbsd);
+  grub_unregister_extcmd (cmd_netbsd);
+
+  grub_unregister_command (cmd_freebsd_loadenv);
+  grub_unregister_command (cmd_freebsd_module);
+  grub_unregister_command (cmd_freebsd_module_elf);
+
+  if (mod_buf)
+    {
+      grub_free (mod_buf);
+      mod_buf = 0;
+      mod_buf_max = 0;
+    }
+}
diff --git a/grub-core/loader/i386/bsd32.c b/grub-core/loader/i386/bsd32.c
new file mode 100644 (file)
index 0000000..26704c4
--- /dev/null
@@ -0,0 +1,6 @@
+#define SUFFIX(x) x ## 32
+#define GRUB_TARGET_WORDSIZE 32
+#define OBJSYM 0
+#include <grub/types.h>
+typedef grub_uint32_t grub_freebsd_addr_t;
+#include "bsdXX.c"
diff --git a/grub-core/loader/i386/bsd64.c b/grub-core/loader/i386/bsd64.c
new file mode 100644 (file)
index 0000000..f8aad1c
--- /dev/null
@@ -0,0 +1,6 @@
+#define SUFFIX(x) x ## 64
+#define GRUB_TARGET_WORDSIZE 64
+#define OBJSYM 1
+#include <grub/types.h>
+typedef grub_uint64_t grub_freebsd_addr_t;
+#include "bsdXX.c"
diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c
new file mode 100644 (file)
index 0000000..cd5ba85
--- /dev/null
@@ -0,0 +1,329 @@
+#include <grub/loader.h>
+#include <grub/cpu/bsd.h>
+#include <grub/mm.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/i386/loader.h>
+
+#define ALIGN_PAGE(a)  ALIGN_UP (a, 4096)
+
+static inline grub_err_t
+load (grub_file_t file, void *where, grub_off_t off, grub_size_t size)
+{
+  if (PTR_TO_UINT32 (where) + size > grub_os_area_addr + grub_os_area_size)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
+                      "not enough memory for the module");
+  if (grub_file_seek (file, off) == (grub_off_t) -1)
+    return grub_errno;
+  if (grub_file_read (file, where, size)
+      != (grub_ssize_t) size)
+    {
+      if (grub_errno)
+       return grub_errno;
+      else
+       return grub_error (GRUB_ERR_BAD_OS, "file is truncated");
+    }
+  return GRUB_ERR_NONE;
+}
+
+static inline grub_err_t
+read_headers (grub_file_t file, Elf_Ehdr *e, char **shdr)
+{
+ if (grub_file_seek (file, 0) == (grub_off_t) -1)
+    return grub_errno;
+
+  if (grub_file_read (file, (char *) e, sizeof (*e)) != sizeof (*e))
+    {
+      if (grub_errno)
+       return grub_errno;
+      else
+       return grub_error (GRUB_ERR_BAD_OS, "file is too short");
+    }
+
+  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");
+
+  if (e->e_ident[EI_CLASS] != SUFFIX (ELFCLASS))
+    return grub_error (GRUB_ERR_BAD_OS, "invalid arch dependent ELF magic");
+
+  *shdr = grub_malloc (e->e_shnum * e->e_shentsize);
+  if (! *shdr)
+    return grub_errno;
+
+  if (grub_file_seek (file, e->e_shoff) == (grub_off_t) -1)
+    return grub_errno;
+
+  if (grub_file_read (file, *shdr, e->e_shnum * e->e_shentsize)
+      != e->e_shnum * e->e_shentsize)
+    {
+      if (grub_errno)
+       return grub_errno;
+      else
+       return grub_error (GRUB_ERR_BAD_OS, "file is truncated");
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* On i386 FreeBSD uses "elf module" approarch for 32-bit variant
+   and "elf obj module" for 64-bit variant. However it may differ on other
+   platforms. So I keep both versions.  */
+#if OBJSYM
+grub_err_t
+SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc,
+                                         char *argv[], grub_addr_t *kern_end)
+{
+  Elf_Ehdr e;
+  Elf_Shdr *s;
+  char *shdr = 0;
+  grub_addr_t curload, module;
+  grub_err_t err;
+
+  err = read_headers (file, &e, &shdr);
+  if (err)
+    return err;
+
+  curload = module = ALIGN_PAGE (*kern_end);
+
+  for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
+                                               + e.e_shnum * e.e_shentsize);
+       s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
+    {
+      if (s->sh_size == 0)
+       continue;
+
+      if (s->sh_addralign)
+       curload = ALIGN_UP (curload, s->sh_addralign);
+      s->sh_addr = curload;
+
+      grub_dprintf ("bsd", "loading section to %x, size %d, align %d\n",
+                   (unsigned) curload, (int) s->sh_size,
+                   (int) s->sh_addralign);
+
+      switch (s->sh_type)
+       {
+       default:
+       case SHT_PROGBITS:
+         err = load (file, UINT_TO_PTR (curload), s->sh_offset, s->sh_size);
+         if (err)
+           return err;
+         break;
+       case SHT_NOBITS:
+         if (curload + s->sh_size > grub_os_area_addr + grub_os_area_size)
+           return grub_error (GRUB_ERR_OUT_OF_RANGE,
+                              "not enough memory for the module");
+         grub_memset (UINT_TO_PTR (curload), 0, s->sh_size);
+         break;
+       }
+      curload += s->sh_size;
+    }
+
+  *kern_end = ALIGN_PAGE (curload);
+
+  err = grub_freebsd_add_meta_module (argv[0], FREEBSD_MODTYPE_ELF_MODULE_OBJ,
+                                     argc - 1, argv + 1, module,
+                                     curload - module);
+  if (! err)
+    err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA
+                                | FREEBSD_MODINFOMD_ELFHDR,
+                                &e, sizeof (e));
+  if (! err)
+    err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA
+                                | FREEBSD_MODINFOMD_SHDR,
+                                shdr, e.e_shnum * e.e_shentsize);
+
+  return err;
+}
+
+#else
+
+grub_err_t
+SUFFIX (grub_freebsd_load_elfmodule) (grub_file_t file, int argc, char *argv[],
+                                     grub_addr_t *kern_end)
+{
+  Elf_Ehdr e;
+  Elf_Shdr *s;
+  char *shdr = 0;
+  grub_addr_t curload, module;
+  grub_err_t err;
+
+  err = read_headers (file, &e, &shdr);
+  if (err)
+    return err;
+
+  curload = module = ALIGN_PAGE (*kern_end);
+
+  for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
+                                               + e.e_shnum * e.e_shentsize);
+       s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
+    {
+      if (s->sh_size == 0)
+       continue;
+
+      if (! (s->sh_flags & SHF_ALLOC))
+       continue;
+
+      grub_dprintf ("bsd", "loading section to %x, size %d, align %d\n",
+                   (unsigned) curload, (int) s->sh_size,
+                   (int) s->sh_addralign);
+
+      switch (s->sh_type)
+       {
+       default:
+       case SHT_PROGBITS:
+         err = load (file, UINT_TO_PTR (module + s->sh_addr),
+                     s->sh_offset, s->sh_size);
+         if (err)
+           return err;
+         break;
+       case SHT_NOBITS:
+         if (module + s->sh_addr + s->sh_size
+             > grub_os_area_addr + grub_os_area_size)
+           return grub_error (GRUB_ERR_OUT_OF_RANGE,
+                              "not enough memory for the module");
+         grub_memset (UINT_TO_PTR (module + s->sh_addr), 0, s->sh_size);
+         break;
+       }
+      if (curload < module + s->sh_addr + s->sh_size)
+       curload = module + s->sh_addr + s->sh_size;
+    }
+
+  load (file, UINT_TO_PTR (module), 0, sizeof (e));
+  if (curload < module + sizeof (e))
+    curload = module + sizeof (e);
+
+  load (file, UINT_TO_PTR (curload), e.e_shoff,
+       e.e_shnum * e.e_shentsize);
+  e.e_shoff = curload - module;
+  curload +=  e.e_shnum * e.e_shentsize;
+
+  load (file, UINT_TO_PTR (curload), e.e_phoff,
+       e.e_phnum * e.e_phentsize);
+  e.e_phoff = curload - module;
+  curload +=  e.e_phnum * e.e_phentsize;
+
+  *kern_end = curload;
+
+  grub_freebsd_add_meta_module (argv[0], FREEBSD_MODTYPE_ELF_MODULE,
+                               argc - 1, argv + 1, module,
+                               curload - module);
+  return SUFFIX (grub_freebsd_load_elf_meta) (file, kern_end);
+}
+
+#endif
+
+grub_err_t
+SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end)
+{
+  grub_err_t err;
+  Elf_Ehdr e;
+  Elf_Shdr *s;
+  char *shdr = 0;
+  unsigned symoff, stroff, symsize, strsize;
+  grub_addr_t curload;
+  grub_freebsd_addr_t symstart, symend, symentsize, dynamic;
+  Elf_Sym *sym;
+  const char *str;
+  unsigned i;
+
+  err = read_headers (file, &e, &shdr);
+  if (err)
+    return err;
+
+  err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+                              FREEBSD_MODINFOMD_ELFHDR, &e,
+                              sizeof (e));
+  if (err)
+    return err;
+
+  for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr
+                                               + e.e_shnum * e.e_shentsize);
+       s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
+      if (s->sh_type == SHT_SYMTAB)
+       break;
+  if (s >= (Elf_Shdr *) ((char *) shdr
+                       + e.e_shnum * e.e_shentsize))
+    return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
+  symoff = s->sh_offset;
+  symsize = s->sh_size;
+  symentsize = s->sh_entsize;
+  s = (Elf_Shdr *) (shdr + e.e_shentsize * s->sh_link);
+  stroff = s->sh_offset;
+  strsize = s->sh_size;
+
+  if (*kern_end + 4 * sizeof (grub_freebsd_addr_t) + symsize + strsize
+      > grub_os_area_addr + grub_os_area_size)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
+                      "not enough memory for kernel symbols");
+
+  symstart = curload = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t));
+  *((grub_freebsd_addr_t *) UINT_TO_PTR (curload)) = symsize;
+  curload += sizeof (grub_freebsd_addr_t);
+  if (grub_file_seek (file, symoff) == (grub_off_t) -1)
+    return grub_errno;
+  sym = (Elf_Sym *) UINT_TO_PTR (curload);
+  if (grub_file_read (file, UINT_TO_PTR (curload), symsize) !=
+      (grub_ssize_t) symsize)
+    {
+      if (! grub_errno)
+       return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
+      return grub_errno;
+    }
+  curload += symsize;
+
+  *((grub_freebsd_addr_t *) UINT_TO_PTR (curload)) = strsize;
+  curload += sizeof (grub_freebsd_addr_t);
+  if (grub_file_seek (file, stroff) == (grub_off_t) -1)
+    return grub_errno;
+  str = (char *) UINT_TO_PTR (curload);
+  if (grub_file_read (file, UINT_TO_PTR (curload), strsize)
+      != (grub_ssize_t) strsize)
+    {
+      if (! grub_errno)
+       return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
+      return grub_errno;
+    }
+  curload += strsize;
+  curload = ALIGN_UP (curload, sizeof (grub_freebsd_addr_t));
+  symend = curload;
+
+  for (i = 0;
+       i * symentsize < symsize;
+       i++, sym = (Elf_Sym *) ((char *) sym + symentsize))
+    {
+      const char *name = str + sym->st_name;
+      if (grub_strcmp (name, "_DYNAMIC") == 0)
+       break;
+    }
+
+  if (i * symentsize < symsize)
+    {
+      dynamic = sym->st_value;
+      grub_dprintf ("bsd", "dynamic = %llx\n", (unsigned long long) dynamic);
+      err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+                                  FREEBSD_MODINFOMD_DYNAMIC, &dynamic,
+                                  sizeof (dynamic));
+      if (err)
+       return err;
+    }
+
+  err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+                              FREEBSD_MODINFOMD_SSYM, &symstart,
+                              sizeof (symstart));
+  if (err)
+    return err;
+
+  err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
+                              FREEBSD_MODINFOMD_ESYM, &symend,
+                              sizeof (symend));
+  if (err)
+    return err;
+  *kern_end = ALIGN_PAGE (curload);
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/loader/i386/bsd_helper.S b/grub-core/loader/i386/bsd_helper.S
new file mode 100644 (file)
index 0000000..25aee3a
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008, 2009 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+       .p2align        2
+
+
+       .code32
+
+/*
+ * Use cdecl calling convention for *BSD kernels.
+ */
+
+FUNCTION(grub_unix_real_boot)
+
+       /* Interrupts should be disabled.  */
+        cli
+
+       /* Discard `grub_unix_real_boot' return address.  */
+        popl    %eax
+
+        /* Fetch `entry' address ...  */
+        popl   %eax
+
+        /*
+         * ... and put our return address in its place. The kernel will
+         * ignore it, but it expects %esp to point to it.
+         */
+        call   *%eax
diff --git a/grub-core/loader/i386/bsd_pagetable.c b/grub-core/loader/i386/bsd_pagetable.c
new file mode 100644 (file)
index 0000000..0fd3937
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 1998  Michael Smith <msmith@freebsd.org>
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Based on the code from FreeBSD originally distributed under the
+   following terms: */
+
+/*-
+ * Copyright (c) 1998  Michael Smith <msmith@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+
+static void
+fill_bsd64_pagetable (grub_uint8_t *target)
+{
+  grub_uint64_t *pt2, *pt3, *pt4;
+  int i;
+
+#define PG_V           0x001
+#define PG_RW          0x002
+#define PG_U           0x004
+#define PG_PS          0x080
+
+  pt4 = (grub_uint64_t *) target;
+  pt3 = (grub_uint64_t *) (target + 4096);
+  pt2 = (grub_uint64_t *) (target + 8192);
+
+  grub_memset ((char *) target, 0, 4096 * 3);
+
+  /*
+   * This is kinda brutal, but every single 1GB VM memory segment points to
+   * the same first 1GB of physical memory.  But it is how BSD expects
+   * it to be.
+   */
+  for (i = 0; i < 512; i++)
+    {
+      /* Each slot of the level 4 pages points to the same level 3 page */
+      pt4[i] = (grub_addr_t) &pt3[0];
+      pt4[i] |= PG_V | PG_RW | PG_U;
+
+      /* Each slot of the level 3 pages points to the same level 2 page */
+      pt3[i] = (grub_addr_t) &pt2[0];
+      pt3[i] |= PG_V | PG_RW | PG_U;
+
+      /* The level 2 page slots are mapped with 2MB pages for 1GB. */
+      pt2[i] = i * (2 * 1024 * 1024);
+      pt2[i] |= PG_V | PG_RW | PG_PS | PG_U;
+    }
+}
diff --git a/grub-core/loader/i386/bsd_trampoline.S b/grub-core/loader/i386/bsd_trampoline.S
new file mode 100644 (file)
index 0000000..a568fff
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (c) 2003  Peter Wemm <peter@FreeBSD.org>
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Based on the code from FreeBSD originally distributed under the
+   following terms: */
+
+/*-
+ * Copyright (c) 2003  Peter Wemm <peter@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+
+#define MSR_EFER       0xc0000080
+#define EFER_LME       0x00000100
+#define CR4_PAE                0x00000020
+#define CR4_PSE                0x00000010
+#define CR0_PG         0x80000000
+
+#include <grub/symbol.h>
+
+       .p2align        2
+
+       .code32
+
+
+VARIABLE(grub_bsd64_trampoline_start)
+
+       /* Discard `grub_unix_real_boot' return address.  */
+        popl    %eax
+
+        /* entry  */
+        popl   %edi
+
+        /* entry_hi  */
+        popl   %esi
+
+       cli
+
+       /* Turn on EFER.LME.  */
+       movl    $MSR_EFER, %ecx
+       rdmsr
+       orl     $EFER_LME, %eax
+        wrmsr
+
+       /* Turn on PAE.  */
+       movl    %cr4, %eax
+       orl     $(CR4_PAE | CR4_PSE), %eax
+       movl    %eax, %cr4
+
+       /* Set %cr3 for PT4.  */
+       popl    %eax
+       movl    %eax, %cr3
+
+       /* Push a dummy return address.  */
+       pushl   %eax
+
+       /* Turn on paging (implicitly sets EFER.LMA).  */
+       movl    %cr0, %eax
+       orl     $CR0_PG, %eax
+       movl    %eax, %cr0
+
+       /* Now we're in compatibility mode. set %cs for long mode.  */
+       /* lgdt */
+       .byte 0x0f
+       .byte 0x01
+       .byte 0x15
+VARIABLE (grub_bsd64_trampoline_gdt)
+       .long 0x0
+
+       /* ljmp */
+       .byte 0xea
+VARIABLE (grub_bsd64_trampoline_selfjump)
+       .long 0x0
+       .word 0x08
+
+       .code64
+
+bsd64_longmode:
+         /* We're still running V=P, jump to entry point.  */
+       movl    %esi, %eax
+       salq    $32, %rax
+       orq     %rdi, %rax
+       pushq   %rax
+       ret
+VARIABLE(grub_bsd64_trampoline_end)
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
new file mode 100644 (file)
index 0000000..a6db22e
--- /dev/null
@@ -0,0 +1,1021 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/term.h>
+#include <grub/cpu/linux.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/uga_draw.h>
+#include <grub/pci.h>
+#include <grub/command.h>
+#include <grub/memory.h>
+#include <grub/i18n.h>
+
+#define GRUB_LINUX_CL_OFFSET           0x1000
+#define GRUB_LINUX_CL_END_OFFSET       0x2000
+
+#define NEXT_MEMORY_DESCRIPTOR(desc, size)      \
+  ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
+
+static grub_dl_t my_mod;
+
+static grub_size_t linux_mem_size;
+static int loaded;
+static void *real_mode_mem;
+static void *prot_mode_mem;
+static void *initrd_mem;
+static grub_efi_uintn_t real_mode_pages;
+static grub_efi_uintn_t prot_mode_pages;
+static grub_efi_uintn_t initrd_pages;
+static void *mmap_buf;
+
+static grub_uint8_t gdt[] __attribute__ ((aligned(16))) =
+  {
+    /* NULL.  */
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    /* Reserved.  */
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    /* Code segment.  */
+    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00,
+    /* Data segment.  */
+    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
+  };
+
+struct gdt_descriptor
+{
+  grub_uint16_t limit;
+  void *base;
+} __attribute__ ((packed));
+
+static struct gdt_descriptor gdt_desc =
+  {
+    sizeof (gdt) - 1,
+    gdt
+  };
+
+struct idt_descriptor
+{
+  grub_uint16_t limit;
+  void *base;
+} __attribute__ ((packed));
+
+static struct idt_descriptor idt_desc =
+  {
+    0,
+    0
+  };
+
+static inline grub_size_t
+page_align (grub_size_t size)
+{
+  return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
+}
+
+/* Find the optimal number of pages for the memory map. Is it better to
+   move this code to efi/mm.c?  */
+static grub_efi_uintn_t
+find_mmap_size (void)
+{
+  static grub_efi_uintn_t mmap_size = 0;
+
+  if (mmap_size != 0)
+    return mmap_size;
+
+  mmap_size = (1 << 12);
+  while (1)
+    {
+      int ret;
+      grub_efi_memory_descriptor_t *mmap;
+      grub_efi_uintn_t desc_size;
+
+      mmap = grub_malloc (mmap_size);
+      if (! mmap)
+       return 0;
+
+      ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
+      grub_free (mmap);
+
+      if (ret < 0)
+       grub_fatal ("cannot get memory map");
+      else if (ret > 0)
+       break;
+
+      mmap_size += (1 << 12);
+    }
+
+  /* Increase the size a bit for safety, because GRUB allocates more on
+     later, and EFI itself may allocate more.  */
+  mmap_size += (1 << 12);
+
+  return page_align (mmap_size);
+}
+
+static void
+free_pages (void)
+{
+  if (real_mode_mem)
+    {
+      grub_efi_free_pages ((grub_addr_t) real_mode_mem, real_mode_pages);
+      real_mode_mem = 0;
+    }
+
+  if (prot_mode_mem)
+    {
+      grub_efi_free_pages ((grub_addr_t) prot_mode_mem, prot_mode_pages);
+      prot_mode_mem = 0;
+    }
+
+  if (initrd_mem)
+    {
+      grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
+      initrd_mem = 0;
+    }
+}
+
+/* Allocate pages for the real mode code and the protected mode code
+   for linux as well as a memory map buffer.  */
+static int
+allocate_pages (grub_size_t prot_size)
+{
+  grub_efi_uintn_t desc_size;
+  grub_efi_memory_descriptor_t *mmap, *mmap_end;
+  grub_efi_uintn_t mmap_size, tmp_mmap_size;
+  grub_efi_memory_descriptor_t *desc;
+  grub_size_t real_size;
+
+  /* Make sure that each size is aligned to a page boundary.  */
+  real_size = GRUB_LINUX_CL_END_OFFSET;
+  prot_size = page_align (prot_size);
+  mmap_size = find_mmap_size ();
+
+  grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
+               (unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
+
+  /* Calculate the number of pages; Combine the real mode code with
+     the memory map buffer for simplicity.  */
+  real_mode_pages = ((real_size + mmap_size) >> 12);
+  prot_mode_pages = (prot_size >> 12);
+
+  /* Initialize the memory pointers with NULL for convenience.  */
+  real_mode_mem = 0;
+  prot_mode_mem = 0;
+
+  /* Read the memory map temporarily, to find free space.  */
+  mmap = grub_malloc (mmap_size);
+  if (! mmap)
+    return 0;
+
+  tmp_mmap_size = mmap_size;
+  if (grub_efi_get_memory_map (&tmp_mmap_size, mmap, 0, &desc_size, 0) <= 0)
+    grub_fatal ("cannot get memory map");
+
+  mmap_end = NEXT_MEMORY_DESCRIPTOR (mmap, tmp_mmap_size);
+
+  /* First, find free pages for the real mode code
+     and the memory map buffer.  */
+  for (desc = mmap;
+       desc < mmap_end;
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+    {
+      /* Probably it is better to put the real mode code in the traditional
+        space for safety.  */
+      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
+         && desc->physical_start <= 0x90000
+         && desc->num_pages >= real_mode_pages)
+       {
+         grub_efi_physical_address_t physical_end;
+         grub_efi_physical_address_t addr;
+
+         physical_end = desc->physical_start + (desc->num_pages << 12);
+         if (physical_end > 0x90000)
+           physical_end = 0x90000;
+
+         grub_dprintf ("linux", "physical_start = %x, physical_end = %x\n",
+                       (unsigned) desc->physical_start,
+                       (unsigned) physical_end);
+         addr = physical_end - real_size - mmap_size;
+         if (addr < 0x10000)
+           continue;
+
+         grub_dprintf ("linux", "trying to allocate %u pages at %lx\n",
+                       (unsigned) real_mode_pages, (unsigned long) addr);
+         real_mode_mem = grub_efi_allocate_pages (addr, real_mode_pages);
+         if (! real_mode_mem)
+           grub_fatal ("cannot allocate pages");
+
+         desc->num_pages -= real_mode_pages;
+         break;
+       }
+    }
+
+  if (! real_mode_mem)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
+      goto fail;
+    }
+
+  mmap_buf = (void *) ((char *) real_mode_mem + real_size);
+
+  /* Next, find free pages for the protected mode code.  */
+  /* XXX what happens if anything is using this address?  */
+  prot_mode_mem = grub_efi_allocate_pages (0x100000, prot_mode_pages + 1);
+  if (! prot_mode_mem)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                 "cannot allocate protected mode pages");
+      goto fail;
+    }
+
+  grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
+               "prot_mode_mem = %lx, prot_mode_pages = %x\n",
+               (unsigned long) real_mode_mem, (unsigned) real_mode_pages,
+               (unsigned long) prot_mode_mem, (unsigned) prot_mode_pages);
+
+  grub_free (mmap);
+  return 1;
+
+ fail:
+  grub_free (mmap);
+  free_pages ();
+  return 0;
+}
+
+static void
+grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num,
+                     grub_uint64_t start, grub_uint64_t size,
+                     grub_uint32_t type)
+{
+  int n = *e820_num;
+
+  if (n >= GRUB_E820_MAX_ENTRY)
+    grub_fatal ("Too many e820 memory map entries");
+
+  if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) &&
+      (e820_map[n - 1].type == type))
+      e820_map[n - 1].size += size;
+  else
+    {
+      e820_map[n].addr = start;
+      e820_map[n].size = size;
+      e820_map[n].type = type;
+      (*e820_num)++;
+    }
+}
+
+#ifdef __x86_64__
+extern grub_uint8_t grub_linux_trampoline_start[];
+extern grub_uint8_t grub_linux_trampoline_end[];
+#endif
+
+static grub_err_t
+grub_linux_boot (void)
+{
+  struct linux_kernel_params *params;
+  grub_efi_uintn_t mmap_size;
+  grub_efi_uintn_t map_key;
+  grub_efi_uintn_t desc_size;
+  grub_efi_uint32_t desc_version;
+  int e820_num;
+
+  params = real_mode_mem;
+
+  grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n",
+               (unsigned) params->code32_start,
+               (unsigned long) &(idt_desc.limit),
+               (unsigned long) &(gdt_desc.limit));
+  grub_dprintf ("linux", "idt = %x:%lx, gdt = %x:%lx\n",
+               (unsigned) idt_desc.limit, (unsigned long) idt_desc.base,
+               (unsigned) gdt_desc.limit, (unsigned long) gdt_desc.base);
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      switch (type)
+        {
+        case GRUB_MACHINE_MEMORY_AVAILABLE:
+         grub_e820_add_region (params->e820_map, &e820_num,
+                               addr, size, GRUB_E820_RAM);
+         break;
+
+#ifdef GRUB_MACHINE_MEMORY_ACPI
+        case GRUB_MACHINE_MEMORY_ACPI:
+         grub_e820_add_region (params->e820_map, &e820_num,
+                               addr, size, GRUB_E820_ACPI);
+         break;
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_NVS
+        case GRUB_MACHINE_MEMORY_NVS:
+         grub_e820_add_region (params->e820_map, &e820_num,
+                               addr, size, GRUB_E820_NVS);
+         break;
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_CODE
+        case GRUB_MACHINE_MEMORY_CODE:
+         grub_e820_add_region (params->e820_map, &e820_num,
+                               addr, size, GRUB_E820_EXEC_CODE);
+         break;
+#endif
+
+        default:
+          grub_e820_add_region (params->e820_map, &e820_num,
+                                addr, size, GRUB_E820_RESERVED);
+        }
+      return 0;
+    }
+
+  e820_num = 0;
+  grub_mmap_iterate (hook);
+  params->mmap_size = e820_num;
+
+  mmap_size = find_mmap_size ();
+  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
+                              &desc_size, &desc_version) <= 0)
+    grub_fatal ("cannot get memory map");
+
+  if (! grub_efi_exit_boot_services (map_key))
+     grub_fatal ("cannot exit boot services");
+
+  /* Note that no boot services are available from here.  */
+
+  /* Pass EFI parameters.  */
+  if (grub_le_to_cpu16 (params->version) >= 0x0206)
+    {
+      params->v0206.efi_mem_desc_size = desc_size;
+      params->v0206.efi_mem_desc_version = desc_version;
+      params->v0206.efi_mmap = (grub_uint32_t) (unsigned long) mmap_buf;
+      params->v0206.efi_mmap_size = mmap_size;
+#ifdef __x86_64__
+      params->v0206.efi_mmap_hi = (grub_uint32_t) ((grub_uint64_t) mmap_buf >> 32);
+#endif
+    }
+  else if (grub_le_to_cpu16 (params->version) >= 0x0204)
+    {
+      params->v0204.efi_mem_desc_size = desc_size;
+      params->v0204.efi_mem_desc_version = desc_version;
+      params->v0204.efi_mmap = (grub_uint32_t) (unsigned long) mmap_buf;
+      params->v0204.efi_mmap_size = mmap_size;
+    }
+
+#ifdef __x86_64__
+
+  grub_memcpy ((char *) prot_mode_mem + (prot_mode_pages << 12),
+              grub_linux_trampoline_start,
+              grub_linux_trampoline_end - grub_linux_trampoline_start);
+
+  ((void (*) (unsigned long, void *)) ((char *) prot_mode_mem
+                                     + (prot_mode_pages << 12)))
+    (params->code32_start, real_mode_mem);
+
+#else
+
+  /* Hardware interrupts are not safe any longer.  */
+  asm volatile ("cli" : : );
+
+  /* Load the IDT and the GDT for the bootstrap.  */
+  asm volatile ("lidt %0" : : "m" (idt_desc));
+  asm volatile ("lgdt %0" : : "m" (gdt_desc));
+
+  /* Pass parameters.  */
+  asm volatile ("movl %0, %%ecx" : : "m" (params->code32_start));
+  asm volatile ("movl %0, %%esi" : : "m" (real_mode_mem));
+
+  asm volatile ("xorl %%ebx, %%ebx" : : );
+
+  /* Enter Linux.  */
+  asm volatile ("jmp *%%ecx" : : );
+
+#endif
+
+  /* Never reach here.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  free_pages ();
+  grub_dl_unref (my_mod);
+  loaded = 0;
+  return GRUB_ERR_NONE;
+}
+
+static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
+
+
+#define RGB_MASK       0xffffff
+#define RGB_MAGIC      0x121314
+#define LINE_MIN       800
+#define LINE_MAX       4096
+#define FBTEST_STEP    (0x10000 >> 2)
+#define FBTEST_COUNT   8
+
+static int
+find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
+{
+  grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base;
+  int i;
+
+  for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP)
+    {
+      if ((*base & RGB_MASK) == RGB_MAGIC)
+       {
+         int j;
+
+         for (j = LINE_MIN; j <= LINE_MAX; j++)
+           {
+             if ((base[j] & RGB_MASK) == RGB_MAGIC)
+               {
+                 *fb_base = (grub_uint32_t) (grub_target_addr_t) base;
+                 *line_len = j << 2;
+
+                 return 1;
+               }
+           }
+
+         break;
+       }
+    }
+
+  return 0;
+}
+
+static int
+find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
+{
+  int found = 0;
+
+  auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
+                                      grub_pci_id_t pciid);
+
+  int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
+                                 grub_pci_id_t pciid)
+    {
+      grub_pci_address_t addr;
+
+      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+      if (grub_pci_read (addr) >> 24 == 0x3)
+       {
+         int i;
+
+         grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n",
+                      grub_pci_get_bus (dev), grub_pci_get_device (dev),
+                      grub_pci_get_function (dev), pciid);
+         addr += 8;
+         for (i = 0; i < 6; i++, addr += 4)
+           {
+             grub_uint32_t old_bar1, old_bar2, type;
+             grub_uint64_t base64;
+
+             old_bar1 = grub_pci_read (addr);
+             if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
+               continue;
+
+             type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
+             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+               {
+                 if (i == 5)
+                   break;
+
+                 old_bar2 = grub_pci_read (addr + 4);
+               }
+             else
+               old_bar2 = 0;
+
+             base64 = old_bar2;
+             base64 <<= 32;
+             base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
+
+             grub_printf ("%s(%d): 0x%llx\n",
+                          ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
+                           "VMEM" : "MMIO"), i,
+                          (unsigned long long) base64);
+
+             if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found))
+               {
+                 *fb_base = base64;
+                 if (find_line_len (fb_base, line_len))
+                   found++;
+               }
+
+             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+               {
+                 i++;
+                 addr += 4;
+               }
+           }
+       }
+
+      return found;
+    }
+
+  grub_pci_iterate (find_card);
+  return found;
+}
+
+static int
+grub_linux_setup_video (struct linux_kernel_params *params)
+{
+  grub_efi_uga_draw_protocol_t *c;
+  grub_uint32_t width, height, depth, rate, pixel, fb_base, line_len;
+  int ret;
+
+  c = grub_efi_locate_protocol (&uga_draw_guid, 0);
+  if (! c)
+    return 1;
+
+  if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate))
+    return 1;
+
+  grub_printf ("Video mode: %ux%u-%u@%u\n", width, height, depth, rate);
+
+  grub_efi_set_text_mode (0);
+  pixel = RGB_MAGIC;
+  efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel,
+              GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0);
+  ret = find_framebuf (&fb_base, &line_len);
+  grub_efi_set_text_mode (1);
+
+  if (! ret)
+    {
+      grub_printf ("Can\'t find frame buffer address\n");
+      return 1;
+    }
+
+  grub_printf ("Frame buffer base: 0x%x\n", fb_base);
+  grub_printf ("Video line length: %d\n", line_len);
+
+  params->lfb_width = width;
+  params->lfb_height = height;
+  params->lfb_depth = depth;
+  params->lfb_line_len = line_len;
+
+  params->lfb_base = fb_base;
+  params->lfb_size = ALIGN_UP (line_len * params->lfb_height, 65536);
+
+  params->red_mask_size = 8;
+  params->red_field_pos = 16;
+  params->green_mask_size = 8;
+  params->green_field_pos = 8;
+  params->blue_mask_size = 8;
+  params->blue_field_pos = 0;
+  params->reserved_mask_size = 8;
+  params->reserved_field_pos = 24;
+
+  params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA;
+  params->vid_mode = 0x338;  /* 1024x768x32  */
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+               int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  struct linux_kernel_header lh;
+  struct linux_kernel_params *params;
+  grub_uint8_t setup_sects;
+  grub_size_t real_size, prot_size;
+  grub_ssize_t len;
+  int i;
+  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, &lh, sizeof (lh)) != sizeof (lh))
+    {
+      grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
+      goto fail;
+    }
+
+  if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
+      goto fail;
+    }
+
+  if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "too many setup sectors");
+      goto fail;
+    }
+
+  /* EFI support is quite new, so reject old versions.  */
+  if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
+      || grub_le_to_cpu16 (lh.version) < 0x0203)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "too old version");
+      goto fail;
+    }
+
+  /* I'm not sure how to support zImage on EFI.  */
+  if (! (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "zImage is not supported");
+      goto fail;
+    }
+
+  setup_sects = lh.setup_sects;
+
+  /* If SETUP_SECTS is not set, set it to the default (4).  */
+  if (! setup_sects)
+    setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
+
+  real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
+  prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
+
+  if (! allocate_pages (prot_size))
+    goto fail;
+
+  params = (struct linux_kernel_params *) real_mode_mem;
+  grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET);
+  grub_memcpy (&params->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
+
+  params->ps_mouse = params->padding10 =  0;
+
+  len = 0x400 - sizeof (lh);
+  if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != len)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+      goto fail;
+    }
+
+  params->type_of_loader = (LINUX_LOADER_ID_GRUB << 4);
+
+  params->cl_magic = GRUB_LINUX_CL_MAGIC;
+  params->cl_offset = 0x1000;
+  params->cmd_line_ptr = (unsigned long) real_mode_mem + 0x1000;
+  params->ramdisk_image = 0;
+  params->ramdisk_size = 0;
+
+  params->heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET;
+  params->loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP;
+
+  /* These are not needed to be precise, because Linux uses these values
+     only to raise an error when the decompression code cannot find good
+     space.  */
+  params->ext_mem = ((32 * 0x100000) >> 10);
+  params->alt_mem = ((32 * 0x100000) >> 10);
+
+  {
+    grub_term_output_t term;
+    int found = 0;
+    FOR_ACTIVE_TERM_OUTPUTS(term)
+      if (grub_strcmp (term->name, "vga_text") == 0
+         || grub_strcmp (term->name, "console") == 0)
+       {
+         grub_uint16_t pos = grub_term_getxy (term);
+         params->video_cursor_x = pos >> 8;
+         params->video_cursor_y = pos & 0xff;
+         params->video_width = grub_term_width (term);
+         params->video_height = grub_term_height (term);
+         found = 1;
+         break;
+       }
+    if (!found)
+      {
+       params->video_cursor_x = 0;
+       params->video_cursor_y = 0;
+       params->video_width = 80;
+       params->video_height = 25;
+      }
+  }
+  params->video_page = 0; /* ??? */
+  params->video_mode = grub_efi_system_table->con_out->mode->mode;
+  params->video_ega_bx = 0;
+  params->have_vga = 0;
+  params->font_size = 16; /* XXX */
+
+  if (grub_le_to_cpu16 (params->version) >= 0x0206)
+    {
+      params->v0206.efi_signature = GRUB_LINUX_EFI_SIGNATURE;
+      params->v0206.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table;
+#ifdef __x86_64__
+      params->v0206.efi_system_table_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32);
+#endif
+    }
+  else if (grub_le_to_cpu16 (params->version) >= 0x0204)
+    {
+      params->v0204.efi_signature = GRUB_LINUX_EFI_SIGNATURE_0204;
+      params->v0204.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table;
+    }
+
+#if 0
+  /* The structure is zeroed already.  */
+
+  /* No VBE on EFI.  */
+  params->lfb_width = 0;
+  params->lfb_height = 0;
+  params->lfb_depth = 0;
+  params->lfb_base = 0;
+  params->lfb_size = 0;
+  params->lfb_line_len = 0;
+  params->red_mask_size = 0;
+  params->red_field_pos = 0;
+  params->green_mask_size = 0;
+  params->green_field_pos = 0;
+  params->blue_mask_size = 0;
+  params->blue_field_pos = 0;
+  params->reserved_mask_size = 0;
+  params->reserved_field_pos = 0;
+  params->vesapm_segment = 0;
+  params->vesapm_offset = 0;
+  params->lfb_pages = 0;
+  params->vesa_attrib = 0;
+
+  /* No APM on EFI.  */
+  params->apm_version = 0;
+  params->apm_code_segment = 0;
+  params->apm_entry = 0;
+  params->apm_16bit_code_segment = 0;
+  params->apm_data_segment = 0;
+  params->apm_flags = 0;
+  params->apm_code_len = 0;
+  params->apm_data_len = 0;
+
+  /* XXX is there any way to use SpeedStep on EFI?  */
+  params->ist_signature = 0;
+  params->ist_command = 0;
+  params->ist_event = 0;
+  params->ist_perf_level = 0;
+
+  /* Let the kernel probe the information.  */
+  grub_memset (params->hd0_drive_info, 0, sizeof (params->hd0_drive_info));
+  grub_memset (params->hd1_drive_info, 0, sizeof (params->hd1_drive_info));
+
+  /* No MCA on EFI.  */
+  params->rom_config_len = 0;
+
+  /* No need to fake the BIOS's memory map.  */
+  params->mmap_size = 0;
+
+  /* Let the kernel probe the information.  */
+  params->ps_mouse = 0;
+
+  /* Clear padding for future compatibility.  */
+  grub_memset (params->padding1, 0, sizeof (params->padding1));
+  grub_memset (params->padding2, 0, sizeof (params->padding2));
+  grub_memset (params->padding3, 0, sizeof (params->padding3));
+  grub_memset (params->padding4, 0, sizeof (params->padding4));
+  grub_memset (params->padding5, 0, sizeof (params->padding5));
+  grub_memset (params->padding6, 0, sizeof (params->padding6));
+  grub_memset (params->padding7, 0, sizeof (params->padding7));
+  grub_memset (params->padding8, 0, sizeof (params->padding8));
+  grub_memset (params->padding9, 0, sizeof (params->padding9));
+
+#endif
+
+  /* The other EFI parameters are filled when booting.  */
+
+  grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
+
+  /* XXX there is no way to know if the kernel really supports EFI.  */
+  grub_printf ("   [Linux-bzImage, setup=0x%x, size=0x%x]\n",
+              (unsigned) real_size, (unsigned) prot_size);
+
+  grub_linux_setup_video (params);
+
+  /* Detect explicitly specified memory size, if any.  */
+  linux_mem_size = 0;
+  for (i = 1; i < argc; i++)
+    if (grub_memcmp (argv[i], "mem=", 4) == 0)
+      {
+       char *val = argv[i] + 4;
+
+       linux_mem_size = grub_strtoul (val, &val, 0);
+
+       if (grub_errno)
+         {
+           grub_errno = GRUB_ERR_NONE;
+           linux_mem_size = 0;
+         }
+       else
+         {
+           int shift = 0;
+
+           switch (grub_tolower (val[0]))
+             {
+             case 'g':
+               shift += 10;
+             case 'm':
+               shift += 10;
+             case 'k':
+               shift += 10;
+             default:
+               break;
+             }
+
+           /* Check an overflow.  */
+           if (linux_mem_size > (~0UL >> shift))
+             linux_mem_size = 0;
+           else
+             linux_mem_size <<= shift;
+         }
+      }
+    else if (grub_memcmp (argv[i], "video=efifb", 11) == 0)
+      {
+       if (params->have_vga)
+         params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
+      }
+
+  /* Specify the boot file.  */
+  dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET,
+                     "BOOT_IMAGE=");
+  dest = grub_stpcpy (dest, argv[0]);
+
+  /* Copy kernel parameters.  */
+  for (i = 1;
+       i < argc
+        && dest + grub_strlen (argv[i]) + 1 < ((char *) real_mode_mem
+                                               + GRUB_LINUX_CL_END_OFFSET);
+       i++)
+    {
+      *dest++ = ' ';
+      dest = grub_stpcpy (dest, argv[i]);
+    }
+
+  len = prot_size;
+  if (grub_file_read (file, (void *) GRUB_LINUX_BZIMAGE_ADDR, len) != len)
+    grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+
+  if (grub_errno == GRUB_ERR_NONE)
+    {
+      grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
+      loaded = 1;
+    }
+
+ fail:
+
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_dl_unref (my_mod);
+      loaded = 0;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+                int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  grub_addr_t addr_min, addr_max;
+  grub_addr_t addr;
+  grub_efi_uintn_t mmap_size;
+  grub_efi_memory_descriptor_t *desc;
+  grub_efi_uintn_t desc_size;
+  struct linux_kernel_header *lh;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
+      goto fail;
+    }
+
+  if (! loaded)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    goto fail;
+
+  size = grub_file_size (file);
+  initrd_pages = (page_align (size) >> 12);
+
+  lh = (struct linux_kernel_header *) real_mode_mem;
+
+  addr_max = (grub_cpu_to_le32 (lh->initrd_addr_max) << 10);
+  if (linux_mem_size != 0 && linux_mem_size < addr_max)
+    addr_max = linux_mem_size;
+
+  /* Linux 2.3.xx has a bug in the memory range check, so avoid
+     the last page.
+     Linux 2.2.xx has a bug in the memory range check, which is
+     worse than that of Linux 2.3.xx, so avoid the last 64kb.  */
+  addr_max -= 0x10000;
+
+  /* Usually, the compression ratio is about 50%.  */
+  addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
+            + page_align (size);
+
+  /* Find the highest address to put the initrd.  */
+  mmap_size = find_mmap_size ();
+  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0) <= 0)
+    grub_fatal ("cannot get memory map");
+
+  addr = 0;
+  for (desc = mmap_buf;
+       desc < NEXT_MEMORY_DESCRIPTOR (mmap_buf, mmap_size);
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+    {
+      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
+         && desc->num_pages >= initrd_pages)
+       {
+         grub_efi_physical_address_t physical_end;
+
+         physical_end = desc->physical_start + (desc->num_pages << 12);
+         if (physical_end > addr_max)
+           physical_end = addr_max;
+
+         if (physical_end < page_align (size))
+           continue;
+
+         physical_end -= page_align (size);
+
+         if ((physical_end >= addr_min) &&
+             (physical_end >= desc->physical_start) &&
+             (physical_end > addr))
+           addr = physical_end;
+       }
+    }
+
+  if (addr == 0)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "no free pages available");
+      goto fail;
+    }
+
+  initrd_mem = grub_efi_allocate_pages (addr, initrd_pages);
+  if (! initrd_mem)
+    grub_fatal ("cannot allocate pages");
+
+  if (grub_file_read (file, initrd_mem, size) != size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+      goto fail;
+    }
+
+  grub_printf ("   [Initrd, addr=0x%x, size=0x%x]\n",
+              (unsigned) addr, (unsigned) size);
+
+  lh->ramdisk_image = addr;
+  lh->ramdisk_size = size;
+  lh->root_dev = 0x0100; /* XXX */
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT(linux)
+{
+  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
+                                    0, N_("Load Linux."));
+  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
+                                     0, N_("Load initrd."));
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux)
+{
+  grub_unregister_command (cmd_linux);
+  grub_unregister_command (cmd_initrd);
+}
diff --git a/grub-core/loader/i386/efi/xnu.c b/grub-core/loader/i386/efi/xnu.c
new file mode 100644 (file)
index 0000000..e80f7f3
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/xnu.h>
+#include <grub/cpu/xnu.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/uga_draw.h>
+#include <grub/pci.h>
+#include <grub/misc.h>
+
+/* Setup video for xnu. Big parts are copied from linux.c. */
+
+static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
+
+#define RGB_MASK       0xffffff
+#define RGB_MAGIC      0x121314
+#define LINE_MIN       800
+#define LINE_MAX       4096
+#define FBTEST_STEP    (0x10000 >> 2)
+#define FBTEST_COUNT   8
+
+static int
+find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
+{
+  grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base;
+  int i;
+
+  for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP)
+    {
+      if ((*base & RGB_MASK) == RGB_MAGIC)
+       {
+         int j;
+
+         for (j = LINE_MIN; j <= LINE_MAX; j++)
+           {
+             if ((base[j] & RGB_MASK) == RGB_MAGIC)
+               {
+                 *fb_base = (grub_uint32_t) (grub_target_addr_t) base;
+                 *line_len = j << 2;
+
+                 return 1;
+               }
+           }
+
+         break;
+       }
+    }
+
+  return 0;
+}
+
+static int
+find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
+{
+  int found = 0;
+
+  auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
+                                      grub_pci_id_t pciid);
+
+  int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
+                                 grub_pci_id_t pciid)
+    {
+      grub_pci_address_t addr;
+
+      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+      if (grub_pci_read (addr) >> 24 == 0x3)
+       {
+         int i;
+
+         grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n",
+                      grub_pci_get_bus (dev), grub_pci_get_device (dev),
+                      grub_pci_get_function (dev), pciid);
+         addr += 8;
+         for (i = 0; i < 6; i++, addr += 4)
+           {
+             grub_uint32_t old_bar1, old_bar2, type;
+             grub_uint64_t base64;
+
+             old_bar1 = grub_pci_read (addr);
+             if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
+               continue;
+
+             type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
+             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+               {
+                 if (i == 5)
+                   break;
+
+                 old_bar2 = grub_pci_read (addr + 4);
+               }
+             else
+               old_bar2 = 0;
+
+             base64 = old_bar2;
+             base64 <<= 32;
+             base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
+
+             grub_printf ("%s(%d): 0x%llx\n",
+                          ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
+                           "VMEM" : "MMIO"), i,
+                          (unsigned long long) base64);
+
+             if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found))
+               {
+                 *fb_base = base64;
+                 if (find_line_len (fb_base, line_len))
+                   found++;
+               }
+
+             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+               {
+                 i++;
+                 addr += 4;
+               }
+           }
+       }
+
+      return found;
+    }
+
+  grub_pci_iterate (find_card);
+  return found;
+}
+
+grub_err_t
+grub_xnu_set_video (struct grub_xnu_boot_params *params)
+{
+  grub_efi_uga_draw_protocol_t *c;
+  grub_uint32_t width, height, depth, rate, pixel, fb_base, line_len;
+  int ret;
+
+  c = grub_efi_locate_protocol (&uga_draw_guid, 0);
+  if (! c)
+    return grub_error (GRUB_ERR_IO, "couldn't find UGADraw");
+
+  if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate))
+    return grub_error (GRUB_ERR_IO, "couldn't retrieve video mode");
+
+  grub_printf ("Video mode: %ux%u-%u@%u\n", width, height, depth, rate);
+
+  grub_efi_set_text_mode (0);
+  pixel = RGB_MAGIC;
+  efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel,
+              GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0);
+  ret = find_framebuf (&fb_base, &line_len);
+  grub_efi_set_text_mode (1);
+
+  if (! ret)
+    return grub_error (GRUB_ERR_IO, "can\'t find frame buffer address");
+
+  grub_printf ("Frame buffer base: 0x%x\n", fb_base);
+  grub_printf ("Video line length: %d\n", line_len);
+
+  params->lfb_width = width;
+  params->lfb_height = height;
+  params->lfb_depth = depth;
+  params->lfb_line_len = line_len;
+  params->lfb_mode = GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
+  params->lfb_base = fb_base;
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/loader/i386/ieee1275/linux.c b/grub-core/loader/i386/ieee1275/linux.c
new file mode 100644 (file)
index 0000000..8780804
--- /dev/null
@@ -0,0 +1,311 @@
+/* linux.c - boot Linux zImage or bzImage */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/machine/memory.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/env.h>
+#include <grub/term.h>
+#include <grub/cpu/linux.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+#define GRUB_OFW_LINUX_PARAMS_ADDR     0x90000
+#define GRUB_OFW_LINUX_KERNEL_ADDR     0x100000
+#define GRUB_OFW_LINUX_INITRD_ADDR     0x800000
+
+#define GRUB_OFW_LINUX_CL_OFFSET       0x1e00
+#define GRUB_OFW_LINUX_CL_LENGTH       0x100
+
+static grub_dl_t my_mod;
+
+static grub_size_t kernel_size;
+static char *kernel_addr, *kernel_cmdline;
+static grub_size_t initrd_size;
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  grub_free (kernel_cmdline);
+  grub_free (kernel_addr);
+  kernel_cmdline = 0;
+  kernel_addr = 0;
+  initrd_size = 0;
+
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+/*
+static int
+grub_ieee1275_debug (void)
+{
+  struct enter_args
+  {
+    struct grub_ieee1275_common_hdr common;
+  }
+  args;
+
+  INIT_IEEE1275_COMMON (&args.common, "enter", 0, 0);
+
+  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+    return -1;
+
+  return 0;
+}
+*/
+
+static grub_err_t
+grub_linux_boot (void)
+{
+  struct linux_kernel_params *params;
+  struct linux_kernel_header *lh;
+  char *prot_code;
+  char *bootpath;
+  grub_ssize_t len;
+
+  bootpath = grub_env_get ("root");
+  if (bootpath)
+    grub_ieee1275_set_property (grub_ieee1275_chosen,
+                                "bootpath", bootpath,
+                                grub_strlen (bootpath) + 1,
+                                &len);
+
+  params = (struct linux_kernel_params *) GRUB_OFW_LINUX_PARAMS_ADDR;
+  lh = (struct linux_kernel_header *) params;
+
+  grub_memset ((char *) params, 0, GRUB_OFW_LINUX_CL_OFFSET);
+
+  params->alt_mem = grub_mmap_get_upper () >> 10;
+  params->ext_mem = params->alt_mem;
+
+  lh->cmd_line_ptr = (char *)
+        (GRUB_OFW_LINUX_PARAMS_ADDR + GRUB_OFW_LINUX_CL_OFFSET);
+
+  params->cl_magic = GRUB_LINUX_CL_MAGIC;
+  params->cl_offset = GRUB_OFW_LINUX_CL_OFFSET;
+
+  {
+    grub_term_output_t term;
+    int found = 0;
+    FOR_ACTIVE_TERM_OUTPUTS(term)
+      if (grub_strcmp (term->name, "ofconsole") == 0)
+        {
+          grub_uint16_t pos = grub_term_getxy (term);
+          params->video_cursor_x = pos >> 8;
+          params->video_cursor_y = pos & 0xff;
+          params->video_width = grub_term_width (term);
+          params->video_height = grub_term_height (term);
+          found = 1;
+          break;
+        }
+    if (!found)
+      {
+        params->video_cursor_x = 0;
+        params->video_cursor_y = 0;
+        params->video_width = 80;
+        params->video_height = 25;
+      }
+  }
+
+  params->font_size = 16;
+
+  params->ofw_signature = GRUB_LINUX_OFW_SIGNATURE;
+  params->ofw_num_items = 1;
+  params->ofw_cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn;
+  params->ofw_idt = 0;
+
+  if (initrd_size)
+    {
+      lh->type_of_loader = 1;
+      lh->ramdisk_image = GRUB_OFW_LINUX_INITRD_ADDR;
+      lh->ramdisk_size = initrd_size;
+    }
+
+  if (kernel_cmdline)
+    grub_strcpy (lh->cmd_line_ptr, kernel_cmdline);
+
+  prot_code = (char *) GRUB_OFW_LINUX_KERNEL_ADDR;
+  grub_memcpy (prot_code, kernel_addr, kernel_size);
+
+  asm volatile ("movl %0, %%esi" : : "m" (params));
+  asm volatile ("movl %%esi, %%esp" : : );
+  asm volatile ("movl %0, %%ecx" : : "m" (prot_code));
+  asm volatile ("xorl %%ebx, %%ebx" : : );
+  asm volatile ("jmp *%%ecx" : : );
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+               int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  struct linux_kernel_header lh;
+  grub_uint8_t setup_sects;
+  grub_size_t real_size, prot_size;
+  int i;
+  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, &lh, sizeof (lh)) != sizeof (lh))
+    {
+      grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
+      goto fail;
+    }
+
+  if ((lh.boot_flag != grub_cpu_to_le16 (0xaa55)) ||
+      (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
+      goto fail;
+    }
+
+  setup_sects = lh.setup_sects;
+  if (! setup_sects)
+    setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
+
+  real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
+  prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
+
+  grub_printf ("   [Linux-%s, setup=0x%x, size=0x%x]\n",
+               "bzImage", real_size, prot_size);
+
+  grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
+  if (grub_errno)
+    goto fail;
+
+  kernel_cmdline = grub_malloc (GRUB_OFW_LINUX_CL_LENGTH);
+  if (! kernel_cmdline)
+    goto fail;
+
+  dest = kernel_cmdline;
+  for (i = 1;
+       i < argc
+       && dest + grub_strlen (argv[i]) + 1 < (kernel_cmdline
+                                              + GRUB_OFW_LINUX_CL_LENGTH);
+       i++)
+    {
+      *dest++ = ' ';
+      dest = grub_stpcpy (dest, argv[i]);
+    }
+
+  kernel_addr = grub_malloc (prot_size);
+  if (! kernel_addr)
+    goto fail;
+
+  kernel_size = prot_size;
+  if (grub_file_read (file, kernel_addr, prot_size) != (int) prot_size)
+    grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+
+  if (grub_errno == GRUB_ERR_NONE)
+    grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
+
+fail:
+
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_free (kernel_cmdline);
+      grub_free (kernel_addr);
+      kernel_cmdline = 0;
+      kernel_addr = 0;
+
+      grub_dl_unref (my_mod);
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+                int argc, char *argv[])
+{
+  grub_file_t file = 0;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
+      goto fail;
+    }
+
+  if (! kernel_addr)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    goto fail;
+
+  initrd_size = grub_file_size (file);
+  if (grub_file_read (file, (void *) GRUB_OFW_LINUX_INITRD_ADDR,
+                      initrd_size) != (int) initrd_size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+      goto fail;
+    }
+
+fail:
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT(linux)
+{
+  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
+                                    0, N_("Load Linux."));
+  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
+                                     0, N_("Load initrd."));
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux)
+{
+  grub_unregister_command (cmd_linux);
+  grub_unregister_command (cmd_initrd);
+}
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
new file mode 100644 (file)
index 0000000..d3d9351
--- /dev/null
@@ -0,0 +1,1022 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/loader.h>
+#include <grub/normal.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/term.h>
+#include <grub/cpu/linux.h>
+#include <grub/video.h>
+#include <grub/video_fb.h>
+#include <grub/command.h>
+#include <grub/i386/pc/vbe.h>
+#include <grub/i386/pc/console.h>
+#include <grub/i18n.h>
+
+#define GRUB_LINUX_CL_OFFSET           0x1000
+#define GRUB_LINUX_CL_END_OFFSET       0x2000
+
+static grub_dl_t my_mod;
+
+static grub_size_t linux_mem_size;
+static int loaded;
+static void *real_mode_mem;
+static void *prot_mode_mem;
+static void *initrd_mem;
+static grub_uint32_t real_mode_pages;
+static grub_uint32_t prot_mode_pages;
+static grub_uint32_t initrd_pages;
+
+static grub_uint8_t gdt[] __attribute__ ((aligned(16))) =
+  {
+    /* NULL.  */
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    /* Reserved.  */
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    /* Code segment.  */
+    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00,
+    /* Data segment.  */
+    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
+  };
+
+struct gdt_descriptor
+{
+  grub_uint16_t limit;
+  void *base;
+} __attribute__ ((packed));
+
+static struct gdt_descriptor gdt_desc =
+  {
+    sizeof (gdt) - 1,
+    gdt
+  };
+
+struct idt_descriptor
+{
+  grub_uint16_t limit;
+  void *base;
+} __attribute__ ((packed));
+
+static struct idt_descriptor idt_desc =
+  {
+    0,
+    0
+  };
+
+#ifdef GRUB_MACHINE_PCBIOS
+struct linux_vesafb_res
+{
+  grub_uint16_t width;
+  grub_uint16_t height;
+};
+
+struct linux_vesafb_mode
+{
+  grub_uint8_t res_index;
+  grub_uint8_t depth;
+};
+
+enum vga_modes
+  {
+    VGA_320_200,
+    VGA_640_400,
+    VGA_640_480,
+    VGA_800_500,
+    VGA_800_600,
+    VGA_896_672,
+    VGA_1024_640,
+    VGA_1024_768,
+    VGA_1152_720,
+    VGA_1280_1024,
+    VGA_1440_900,
+    VGA_1600_1200,
+  };
+
+static struct linux_vesafb_res linux_vesafb_res[] =
+  {
+    { 320, 200 },
+    { 640, 400 },
+    { 640, 480 },
+    { 800, 500 },
+    { 800, 600 },
+    { 896, 672 },
+    { 1024, 640 },
+    { 1024, 768 },
+    { 1152, 720 },
+    { 1280, 1024 },
+    { 1440, 900 },
+    { 1600, 1200 },
+  };
+
+/* This is the reverse of the table in [linux]/Documentation/fb/vesafb.txt
+   plus a few more modes based on the table in
+   http://en.wikipedia.org/wiki/VESA_BIOS_Extensions  */
+struct linux_vesafb_mode linux_vesafb_modes[] =
+  {
+    { VGA_640_400, 8 },                /* 0x300 */
+    { VGA_640_480, 8 },                /* 0x301 */
+    { VGA_800_600, 4 },                /* 0x302 */
+    { VGA_800_600, 8 },                /* 0x303 */
+    { VGA_1024_768, 4 },       /* 0x304 */
+    { VGA_1024_768, 8 },       /* 0x305 */
+    { VGA_1280_1024, 4 },      /* 0x306 */
+    { VGA_1280_1024, 8 },      /* 0x307 */
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { VGA_320_200, 15 },       /* 0x30d */
+    { VGA_320_200, 16 },       /* 0x30e */
+    { VGA_320_200, 24 },       /* 0x30f */
+    { VGA_640_480, 15 },       /* 0x310 */
+    { VGA_640_480, 16 },       /* 0x311 */
+    { VGA_640_480, 24 },       /* 0x312 */
+    { VGA_800_600, 15 },       /* 0x313 */
+    { VGA_800_600, 16 },       /* 0x314 */
+    { VGA_800_600, 24 },       /* 0x315 */
+    { VGA_1024_768, 15 },      /* 0x316 */
+    { VGA_1024_768, 16 },      /* 0x317 */
+    { VGA_1024_768, 24 },      /* 0x318 */
+    { VGA_1280_1024, 15 },     /* 0x319 */
+    { VGA_1280_1024, 16 },     /* 0x31a */
+    { VGA_1280_1024, 24 },     /* 0x31b */
+    { VGA_1600_1200, 8 },      /* 0x31c */
+    { VGA_1600_1200, 15 },     /* 0x31d */
+    { VGA_1600_1200, 16 },     /* 0x31e */
+    { VGA_1600_1200, 24 },     /* 0x31f */
+    { 0, 0 },
+    { VGA_640_400, 15 },       /* 0x321 */
+    { VGA_640_400, 16 },       /* 0x322 */
+    { VGA_640_400, 24 },       /* 0x323 */
+    { VGA_640_400, 32 },       /* 0x324 */
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { VGA_640_480, 32 },       /* 0x329 */
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { VGA_896_672, 8 },                /* 0x32f */
+    { VGA_896_672, 15 },       /* 0x330 */
+    { VGA_896_672, 16 },       /* 0x331 */
+    { VGA_896_672, 24 },       /* 0x332 */
+    { VGA_896_672, 32 },       /* 0x333 */
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { VGA_1600_1200, 32 },     /* 0x342 */
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { 0, 0 },
+    { VGA_1440_900, 8 },       /* 0x360 */
+    { VGA_1440_900, 15 },      /* 0x361 */
+    { VGA_1440_900, 16 },      /* 0x362 */
+    { VGA_1440_900, 24 },      /* 0x363 */
+    { VGA_1440_900, 32 },      /* 0x364 */
+    { VGA_1152_720, 8 },       /* 0x365 */
+    { VGA_1152_720, 15 },      /* 0x366 */
+    { VGA_1152_720, 16 },      /* 0x367 */
+    { VGA_1152_720, 24 },      /* 0x368 */
+    { VGA_1152_720, 32 },      /* 0x369 */
+    { VGA_1024_640, 8 },       /* 0x36a */
+    { VGA_1024_640, 15 },      /* 0x36b */
+    { VGA_1024_640, 16 },      /* 0x36c */
+    { VGA_1024_640, 24 },      /* 0x36d */
+    { VGA_1024_640, 32 },      /* 0x36e */
+    { VGA_800_500, 8 },                /* 0x36f */
+    { VGA_800_500, 15 },       /* 0x370 */
+    { VGA_800_500, 16 },       /* 0x371 */
+    { VGA_800_500, 24 },       /* 0x372 */
+    { VGA_800_500, 32 },       /* 0x373 */
+  };
+#endif
+
+static inline grub_size_t
+page_align (grub_size_t size)
+{
+  return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
+}
+
+/* Find the optimal number of pages for the memory map. */
+static grub_size_t
+find_mmap_size (void)
+{
+  grub_size_t count = 0, mmap_size;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
+                            grub_uint64_t size __attribute__ ((unused)),
+                            grub_uint32_t type __attribute__ ((unused)))
+    {
+      count++;
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+
+  mmap_size = count * sizeof (struct grub_e820_mmap);
+
+  /* Increase the size a bit for safety, because GRUB allocates more on
+     later.  */
+  mmap_size += (1 << 12);
+
+  return page_align (mmap_size);
+}
+
+static void
+free_pages (void)
+{
+  real_mode_mem = prot_mode_mem = initrd_mem = 0;
+}
+
+/* Allocate pages for the real mode code and the protected mode code
+   for linux as well as a memory map buffer.  */
+static int
+allocate_pages (grub_size_t prot_size)
+{
+  grub_size_t real_size, mmap_size;
+
+  /* Make sure that each size is aligned to a page boundary.  */
+  real_size = GRUB_LINUX_CL_END_OFFSET;
+  prot_size = page_align (prot_size);
+  mmap_size = find_mmap_size ();
+
+  grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
+               (unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
+
+  /* Calculate the number of pages; Combine the real mode code with
+     the memory map buffer for simplicity.  */
+  real_mode_pages = ((real_size + mmap_size) >> 12);
+  prot_mode_pages = (prot_size >> 12);
+
+  /* Initialize the memory pointers with NULL for convenience.  */
+  free_pages ();
+
+  /* FIXME: Should request low memory from the heap when this feature is
+     implemented.  */
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      /* We must put real mode code in the traditional space.  */
+
+      if (type == GRUB_MACHINE_MEMORY_AVAILABLE
+         && addr <= 0x90000)
+       {
+         if (addr < 0x10000)
+           {
+             size += addr - 0x10000;
+             addr = 0x10000;
+           }
+
+         if (addr + size > 0x90000)
+           size = 0x90000 - addr;
+
+         if (real_size + mmap_size > size)
+           return 0;
+
+         real_mode_mem =
+           (void *) (grub_size_t) ((addr + size) - (real_size + mmap_size));
+         return 1;
+       }
+
+      return 0;
+    }
+  grub_mmap_iterate (hook);
+  if (! real_mode_mem)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
+      goto fail;
+    }
+
+  prot_mode_mem = (void *) 0x100000;
+
+  grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
+                "prot_mode_mem = %lx, prot_mode_pages = %x\n",
+                (unsigned long) real_mode_mem, (unsigned) real_mode_pages,
+                (unsigned long) prot_mode_mem, (unsigned) prot_mode_pages);
+
+  return 1;
+
+ fail:
+  free_pages ();
+  return 0;
+}
+
+static void
+grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num,
+                      grub_uint64_t start, grub_uint64_t size,
+                      grub_uint32_t type)
+{
+  int n = *e820_num;
+
+  if (n >= GRUB_E820_MAX_ENTRY)
+    grub_fatal ("Too many e820 memory map entries");
+
+  if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) &&
+      (e820_map[n - 1].type == type))
+      e820_map[n - 1].size += size;
+  else
+    {
+      e820_map[n].addr = start;
+      e820_map[n].size = size;
+      e820_map[n].type = type;
+      (*e820_num)++;
+    }
+}
+
+static int
+grub_linux_setup_video (struct linux_kernel_params *params)
+{
+  struct grub_video_mode_info mode_info;
+  void *framebuffer;
+  grub_err_t err;
+
+  err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
+
+  if (err)
+    {
+      grub_errno = GRUB_ERR_NONE;
+      return 1;
+    }
+
+  params->lfb_width = mode_info.width;
+  params->lfb_height = mode_info.height;
+  params->lfb_depth = mode_info.bpp;
+  params->lfb_line_len = mode_info.pitch;
+
+  params->lfb_base = (grub_size_t) framebuffer;
+  params->lfb_size = ALIGN_UP (params->lfb_line_len * params->lfb_height, 65536);
+
+  params->red_mask_size = mode_info.red_mask_size;
+  params->red_field_pos = mode_info.red_field_pos;
+  params->green_mask_size = mode_info.green_mask_size;
+  params->green_field_pos = mode_info.green_field_pos;
+  params->blue_mask_size = mode_info.blue_mask_size;
+  params->blue_field_pos = mode_info.blue_field_pos;
+  params->reserved_mask_size = mode_info.reserved_mask_size;
+  params->reserved_field_pos = mode_info.reserved_field_pos;
+
+
+#ifdef GRUB_MACHINE_PCBIOS
+  /* VESA packed modes may come with zeroed mask sizes, which need
+     to be set here according to DAC Palette width.  If we don't,
+     this results in Linux displaying a black screen.  */
+  if (mode_info.bpp <= 8)
+    {
+      struct grub_vbe_info_block controller_info;
+      int status;
+      int width = 8;
+
+      status = grub_vbe_bios_get_controller_info (&controller_info);
+
+      if (status == GRUB_VBE_STATUS_OK &&
+         (controller_info.capabilities & GRUB_VBE_CAPABILITY_DACWIDTH))
+       status = grub_vbe_bios_set_dac_palette_width (&width);
+
+      if (status != GRUB_VBE_STATUS_OK)
+       /* 6 is default after mode reset.  */
+       width = 6;
+
+      params->red_mask_size = params->green_mask_size
+       = params->blue_mask_size = width;
+      params->reserved_mask_size = 0;
+    }
+#endif
+
+  return 0;
+}
+
+#ifdef __x86_64__
+extern grub_uint8_t grub_linux_trampoline_start[];
+extern grub_uint8_t grub_linux_trampoline_end[];
+#endif
+
+static grub_err_t
+grub_linux_boot (void)
+{
+  struct linux_kernel_params *params;
+  int e820_num;
+  grub_err_t err = 0;
+  char *modevar, *tmp;
+
+  params = real_mode_mem;
+
+  grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n",
+               (unsigned) params->code32_start,
+                (unsigned long) &(idt_desc.limit),
+               (unsigned long) &(gdt_desc.limit));
+  grub_dprintf ("linux", "idt = %x:%lx, gdt = %x:%lx\n",
+               (unsigned) idt_desc.limit, (unsigned long) idt_desc.base,
+               (unsigned) gdt_desc.limit, (unsigned long) gdt_desc.base);
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      switch (type)
+        {
+        case GRUB_MACHINE_MEMORY_AVAILABLE:
+         grub_e820_add_region (params->e820_map, &e820_num,
+                               addr, size, GRUB_E820_RAM);
+         break;
+
+#ifdef GRUB_MACHINE_MEMORY_ACPI
+        case GRUB_MACHINE_MEMORY_ACPI:
+         grub_e820_add_region (params->e820_map, &e820_num,
+                               addr, size, GRUB_E820_ACPI);
+         break;
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_NVS
+        case GRUB_MACHINE_MEMORY_NVS:
+         grub_e820_add_region (params->e820_map, &e820_num,
+                               addr, size, GRUB_E820_NVS);
+         break;
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_CODE
+        case GRUB_MACHINE_MEMORY_CODE:
+         grub_e820_add_region (params->e820_map, &e820_num,
+                               addr, size, GRUB_E820_EXEC_CODE);
+         break;
+#endif
+
+        default:
+          grub_e820_add_region (params->e820_map, &e820_num,
+                                addr, size, GRUB_E820_RESERVED);
+        }
+      return 0;
+    }
+
+  e820_num = 0;
+  grub_mmap_iterate (hook);
+  params->mmap_size = e820_num;
+
+  modevar = grub_env_get ("gfxpayload");
+
+  /* Now all graphical modes are acceptable.
+     May change in future if we have modes without framebuffer.  */
+  if (modevar && *modevar != 0)
+    {
+      tmp = grub_xasprintf ("%s;text", modevar);
+      if (! tmp)
+       return grub_errno;
+      err = grub_video_set_mode (tmp, 0, 0);
+      grub_free (tmp);
+    }
+  else
+    err = grub_video_set_mode ("text", 0, 0);
+
+  if (err)
+    {
+      grub_print_error ();
+      grub_printf ("Booting however\n");
+      grub_errno = GRUB_ERR_NONE;
+    }
+
+  if (! grub_linux_setup_video (params))
+    {
+      /* Use generic framebuffer unless VESA is known to be supported.  */
+      if (params->have_vga != GRUB_VIDEO_LINUX_TYPE_VESA)
+       params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
+      else
+       params->lfb_size >>= 16;
+    }
+  else
+    {
+      params->have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT;
+      params->video_width = 80;
+      params->video_height = 25;
+    }
+
+  /* Initialize these last, because terminal position could be affected by printfs above.  */
+  if (params->have_vga == GRUB_VIDEO_LINUX_TYPE_TEXT)
+    {
+      grub_term_output_t term;
+      int found = 0;
+      FOR_ACTIVE_TERM_OUTPUTS(term)
+       if (grub_strcmp (term->name, "vga_text") == 0
+           || grub_strcmp (term->name, "console") == 0)
+         {
+           grub_uint16_t pos = grub_term_getxy (term);
+           params->video_cursor_x = pos >> 8;
+           params->video_cursor_y = pos & 0xff;
+           found = 1;
+           break;
+         }
+      if (!found)
+       {
+         params->video_cursor_x = 0;
+         params->video_cursor_y = 0;
+       }
+    }
+
+#ifdef __x86_64__
+
+  grub_memcpy ((char *) prot_mode_mem + (prot_mode_pages << 12),
+              grub_linux_trampoline_start,
+              grub_linux_trampoline_end - grub_linux_trampoline_start);
+
+  ((void (*) (unsigned long, void *)) ((char *) prot_mode_mem
+                                      + (prot_mode_pages << 12)))
+    (params->code32_start, real_mode_mem);
+#else
+
+  /* Hardware interrupts are not safe any longer.  */
+  asm volatile ("cli" : : );
+
+  /* Load the IDT and the GDT for the bootstrap.  */
+  asm volatile ("lidt %0" : : "m" (idt_desc));
+  asm volatile ("lgdt %0" : : "m" (gdt_desc));
+
+  /* Enter Linux.  */
+  asm volatile ("jmp *%2" : : "b" (0), "S" (real_mode_mem), "g" (params->code32_start));
+
+#endif
+
+  /* Never reach here.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  grub_dl_unref (my_mod);
+  loaded = 0;
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+               int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  struct linux_kernel_header lh;
+  struct linux_kernel_params *params;
+  grub_uint8_t setup_sects;
+  grub_size_t real_size, prot_size;
+  grub_ssize_t len;
+  int i;
+  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, &lh, sizeof (lh)) != sizeof (lh))
+    {
+      grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
+      goto fail;
+    }
+
+  if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
+      goto fail;
+    }
+
+  if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "too many setup sectors");
+      goto fail;
+    }
+
+  if (! (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "zImage doesn't support 32-bit boot"
+#ifdef GRUB_MACHINE_PCBIOS
+                 " (try with `linux16')"
+#endif
+                 );
+      goto fail;
+    }
+
+  /* FIXME: 2.03 is not always good enough (Linux 2.4 can be 2.03 and
+     still not support 32-bit boot.  */
+  if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
+      || grub_le_to_cpu16 (lh.version) < 0x0203)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "version too old for 32-bit boot"
+#ifdef GRUB_MACHINE_PCBIOS
+                 " (try with `linux16')"
+#endif
+                 );
+      goto fail;
+    }
+
+  setup_sects = lh.setup_sects;
+
+  /* If SETUP_SECTS is not set, set it to the default (4).  */
+  if (! setup_sects)
+    setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
+
+  real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
+  prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
+
+  if (! allocate_pages (prot_size))
+    goto fail;
+
+  params = (struct linux_kernel_params *) real_mode_mem;
+  grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET);
+  grub_memcpy (&params->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
+
+  params->ps_mouse = params->padding10 =  0;
+
+  len = 0x400 - sizeof (lh);
+  if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != len)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+      goto fail;
+    }
+
+  params->type_of_loader = (LINUX_LOADER_ID_GRUB << 4);
+
+  /* These two are used (instead of cmd_line_ptr) by older versions of Linux,
+     and otherwise ignored.  */
+  params->cl_magic = GRUB_LINUX_CL_MAGIC;
+  params->cl_offset = 0x1000;
+
+  params->cmd_line_ptr = (unsigned long) real_mode_mem + 0x1000;
+  params->ramdisk_image = 0;
+  params->ramdisk_size = 0;
+
+  params->heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET;
+  params->loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP;
+
+  /* These are not needed to be precise, because Linux uses these values
+     only to raise an error when the decompression code cannot find good
+     space.  */
+  params->ext_mem = ((32 * 0x100000) >> 10);
+  params->alt_mem = ((32 * 0x100000) >> 10);
+
+  /* Ignored by Linux.  */
+  params->video_page = 0;
+
+  /* Must be non-zero even in text mode, or Linux will think there's no VGA.  */
+  params->video_mode = 0x3;
+
+  /* Only used when `video_mode == 0x7', otherwise ignored.  */
+  params->video_ega_bx = 0;
+
+  params->font_size = 16; /* XXX */
+
+  /* The other parameters are filled when booting.  */
+
+  grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
+
+  grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n",
+               (unsigned) real_size, (unsigned) prot_size);
+
+  /* Look for memory size and video mode specified on the command line.  */
+  linux_mem_size = 0;
+  for (i = 1; i < argc; i++)
+#ifdef GRUB_MACHINE_PCBIOS
+    if (grub_memcmp (argv[i], "vga=", 4) == 0)
+      {
+       /* Video mode selection support.  */
+       char *val = argv[i] + 4;
+       unsigned vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
+       struct linux_vesafb_mode *linux_mode;
+       grub_err_t err;
+       char *buf;
+
+       if (grub_strcmp (val, "normal") == 0)
+         vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
+       else if (grub_strcmp (val, "ext") == 0)
+         vid_mode = GRUB_LINUX_VID_MODE_EXTENDED;
+       else if (grub_strcmp (val, "ask") == 0)
+         {
+           grub_printf ("Legacy `ask' parameter no longer supported.\n");
+
+           /* We usually would never do this in a loader, but "vga=ask" means user
+              requested interaction, so it can't hurt to request keyboard input.  */
+           grub_wait_after_message ();
+
+           goto fail;
+         }
+       else
+         vid_mode = (grub_uint16_t) grub_strtoul (val, 0, 0);
+
+       switch (vid_mode)
+         {
+         case 0:
+         case GRUB_LINUX_VID_MODE_NORMAL:
+           grub_env_set ("gfxpayload", "text");
+           grub_printf ("%s is deprecated. "
+                        "Use set gfxpayload=text before "
+                        "linux command instead.\n",
+                        argv[i]);
+           break;
+
+         case 1:
+         case GRUB_LINUX_VID_MODE_EXTENDED:
+           /* FIXME: support 80x50 text. */
+           grub_env_set ("gfxpayload", "text");
+           grub_printf ("%s is deprecated. "
+                        "Use set gfxpayload=text before "
+                        "linux command instead.\n",
+                        argv[i]);
+           break;
+         default:
+           /* Ignore invalid values.  */
+           if (vid_mode < GRUB_LINUX_VID_MODE_VESA_START ||
+               vid_mode >= GRUB_LINUX_VID_MODE_VESA_START +
+               ARRAY_SIZE (linux_vesafb_modes))
+             {
+               grub_env_set ("gfxpayload", "text");
+               grub_printf ("%s is deprecated. Mode %d isn't recognized. "
+                            "Use set gfxpayload=WIDTHxHEIGHT[xDEPTH] before "
+                            "linux command instead.\n",
+                            argv[i], vid_mode);
+               break;
+             }
+
+           /* We can't detect VESA, but user is implicitly telling us that it
+              is built-in because `vga=' parameter was used.  */
+           params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA;
+
+           linux_mode
+             = &linux_vesafb_modes[vid_mode - GRUB_LINUX_VID_MODE_VESA_START];
+
+           buf = grub_xasprintf ("%ux%ux%u,%ux%u",
+                                linux_vesafb_res[linux_mode->res_index].width,
+                                linux_vesafb_res[linux_mode->res_index].height,
+                                linux_mode->depth,
+                                linux_vesafb_res[linux_mode->res_index].width,
+                                linux_vesafb_res[linux_mode->res_index].height);
+           if (! buf)
+             goto fail;
+
+           grub_printf ("%s is deprecated. "
+                        "Use set gfxpayload=%s before "
+                        "linux command instead.\n",
+                        argv[i], buf);
+           err = grub_env_set ("gfxpayload", buf);
+           grub_free (buf);
+           if (err)
+             goto fail;
+         }
+      }
+    else
+#endif /* GRUB_MACHINE_PCBIOS */
+    if (grub_memcmp (argv[i], "mem=", 4) == 0)
+      {
+       char *val = argv[i] + 4;
+
+       linux_mem_size = grub_strtoul (val, &val, 0);
+
+       if (grub_errno)
+         {
+           grub_errno = GRUB_ERR_NONE;
+           linux_mem_size = 0;
+         }
+       else
+         {
+           int shift = 0;
+
+           switch (grub_tolower (val[0]))
+             {
+             case 'g':
+               shift += 10;
+             case 'm':
+               shift += 10;
+             case 'k':
+               shift += 10;
+             default:
+               break;
+             }
+
+           /* Check an overflow.  */
+           if (linux_mem_size > (~0UL >> shift))
+             linux_mem_size = 0;
+           else
+             linux_mem_size <<= shift;
+         }
+      }
+    else if (grub_memcmp (argv[i], "quiet", sizeof ("quiet") - 1) == 0)
+      {
+       params->loadflags |= GRUB_LINUX_FLAG_QUIET;
+      }
+
+
+  /* Specify the boot file.  */
+  dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET,
+                     "BOOT_IMAGE=");
+  dest = grub_stpcpy (dest, argv[0]);
+
+  /* Copy kernel parameters.  */
+  for (i = 1;
+       i < argc
+        && dest + grub_strlen (argv[i]) + 1 < ((char *) real_mode_mem
+                                               + GRUB_LINUX_CL_END_OFFSET);
+       i++)
+    {
+      *dest++ = ' ';
+      dest = grub_stpcpy (dest, argv[i]);
+    }
+
+  len = prot_size;
+  if (grub_file_read (file, (void *) GRUB_LINUX_BZIMAGE_ADDR, len) != len)
+    grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+
+  if (grub_errno == GRUB_ERR_NONE)
+    {
+      grub_loader_set (grub_linux_boot, grub_linux_unload,
+                      0 /* set noreturn=0 in order to avoid grub_console_fini() */);
+      loaded = 1;
+    }
+
+ fail:
+
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_dl_unref (my_mod);
+      loaded = 0;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+                int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  grub_addr_t addr_min, addr_max;
+  grub_addr_t addr;
+  struct linux_kernel_header *lh;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
+      goto fail;
+    }
+
+  if (! loaded)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    goto fail;
+
+  size = grub_file_size (file);
+  initrd_pages = (page_align (size) >> 12);
+
+  lh = (struct linux_kernel_header *) real_mode_mem;
+
+  /* Get the highest address available for the initrd.  */
+  if (grub_le_to_cpu16 (lh->version) >= 0x0203)
+    {
+      addr_max = grub_cpu_to_le32 (lh->initrd_addr_max);
+
+      /* XXX in reality, Linux specifies a bogus value, so
+        it is necessary to make sure that ADDR_MAX does not exceed
+        0x3fffffff.  */
+      if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS)
+       addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
+    }
+  else
+    addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
+
+  if (linux_mem_size != 0 && linux_mem_size < addr_max)
+    addr_max = linux_mem_size;
+
+  /* Linux 2.3.xx has a bug in the memory range check, so avoid
+     the last page.
+     Linux 2.2.xx has a bug in the memory range check, which is
+     worse than that of Linux 2.3.xx, so avoid the last 64kb.  */
+  addr_max -= 0x10000;
+
+  /* Usually, the compression ratio is about 50%.  */
+  addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
+             + page_align (size);
+
+  if (addr_max > grub_os_area_addr + grub_os_area_size)
+    addr_max = grub_os_area_addr + grub_os_area_size;
+
+  /* Put the initrd as high as possible, 4KiB aligned.  */
+  addr = (addr_max - size) & ~0xFFF;
+
+  if (addr < addr_min)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "the initrd is too big");
+      goto fail;
+    }
+
+  initrd_mem = (void *) addr;
+
+  if (grub_file_read (file, initrd_mem, size) != size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+      goto fail;
+    }
+
+  grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n",
+               (unsigned) addr, (unsigned) size);
+
+  lh->ramdisk_image = addr;
+  lh->ramdisk_size = size;
+  lh->root_dev = 0x0100; /* XXX */
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT(linux)
+{
+  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
+                                    0, N_("Load Linux."));
+  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
+                                     0, N_("Load initrd."));
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux)
+{
+  grub_unregister_command (cmd_linux);
+  grub_unregister_command (cmd_initrd);
+}
diff --git a/grub-core/loader/i386/linux_trampoline.S b/grub-core/loader/i386/linux_trampoline.S
new file mode 100644 (file)
index 0000000..4acea7b
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+
+       .p2align        4       /* force 16-byte alignment */
+VARIABLE(grub_linux_trampoline_start)
+       cli
+       /* %rdi contains protected memory start and %rsi
+       contains real memory start. */
+
+       mov %rsi, %rbx
+
+       call base
+base:
+       pop %rsi
+
+#ifdef APPLE_CC
+       lea (cont1 - base) (%esi, 1), %rax
+       mov %eax, (jump_vector - base) (%esi, 1)
+
+       lea (gdt - base) (%esi, 1), %rax
+       mov %rax, (gdtaddr - base) (%esi, 1)
+
+       /* Switch to compatibility mode. */
+
+       lidt (idtdesc - base) (%esi, 1)
+       lgdt (gdtdesc - base) (%esi, 1)
+
+       /* Update %cs. Thanks to David Miller for pointing this mistake out. */
+       ljmp *(jump_vector - base) (%esi, 1)
+#else
+       lea (cont1 - base) (%rsi, 1), %rax
+       mov %eax, (jump_vector - base) (%rsi, 1)
+
+       lea (gdt - base) (%rsi, 1), %rax
+       mov %rax, (gdtaddr - base) (%rsi, 1)
+
+       /* Switch to compatibility mode. */
+
+       lidt (idtdesc - base) (%rsi, 1)
+       lgdt (gdtdesc - base) (%rsi, 1)
+
+       /* Update %cs. Thanks to David Miller for pointing this mistake out. */
+       ljmp *(jump_vector - base) (%rsi, 1)
+#endif
+
+cont1:
+       .code32
+
+       /* Update other registers. */
+       mov $0x18, %eax
+       mov %eax, %ds
+       mov %eax, %es
+       mov %eax, %fs
+       mov %eax, %gs
+       mov %eax, %ss
+
+       /* Disable paging. */
+       mov %cr0, %eax
+       and $0x7fffffff, %eax
+       mov %eax, %cr0
+
+       /* Disable amd64. */
+       mov $0xc0000080, %ecx
+       rdmsr
+       and $0xfffffeff, %eax
+       wrmsr
+
+       /* Turn off PAE. */
+       movl %cr4, %eax
+       and $0xffffffcf, %eax
+       mov %eax, %cr4
+
+       jmp cont2
+cont2:
+       .code32
+
+       mov %ebx, %esi
+
+       jmp *%edi
+
+       /* GDT. */
+       .p2align 4
+gdt:
+       /* NULL.  */
+       .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+       /* Reserved.  */
+       .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+       /* Code segment.  */
+       .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
+
+       /* Data segment.  */
+       .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
+
+gdtdesc:
+       .word 31
+gdtaddr:
+       .quad gdt
+
+idtdesc:
+       .word 0
+idtaddr:
+       .quad 0
+
+       .p2align 4
+jump_vector:
+       /* Jump location. Is filled by the code */
+       .long 0
+       .long 0x10
+VARIABLE(grub_linux_trampoline_end)
diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c
new file mode 100644 (file)
index 0000000..3d974f0
--- /dev/null
@@ -0,0 +1,541 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/memory.h>
+#ifdef GRUB_MACHINE_PCBIOS
+#include <grub/machine/biosnum.h>
+#endif
+#include <grub/multiboot.h>
+#include <grub/cpu/multiboot.h>
+#include <grub/cpu/relocator.h>
+#include <grub/disk.h>
+#include <grub/device.h>
+#include <grub/partition.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/video.h>
+#include <grub/file.h>
+
+/* The bits in the required part of flags field we don't support.  */
+#define UNSUPPORTED_FLAGS                      0x0000fff8
+
+struct module
+{
+  struct module *next;
+  grub_addr_t start;
+  grub_size_t size;
+  char *cmdline;
+  int cmdline_size;
+};
+
+struct module *modules, *modules_last;
+static grub_size_t cmdline_size;
+static grub_size_t total_modcmd;
+static unsigned modcnt;
+static char *cmdline = NULL;
+static grub_uint32_t bootdev;
+static int bootdev_set;
+
+grub_err_t
+grub_multiboot_load (grub_file_t file)
+{
+  char *buffer;
+  grub_ssize_t len;
+  struct multiboot_header *header;
+  grub_err_t err;
+
+  buffer = grub_malloc (MULTIBOOT_SEARCH);
+  if (!buffer)
+    return grub_errno;
+
+  len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
+  if (len < 32)
+    {
+      grub_free (buffer);
+      return grub_error (GRUB_ERR_BAD_OS, "file too small");
+    }
+
+  /* Look for the multiboot header in the buffer.  The header should
+     be at least 12 bytes and aligned on a 4-byte boundary.  */
+  for (header = (struct multiboot_header *) buffer;
+       ((char *) header <= buffer + len - 12) || (header = 0);
+       header = (struct multiboot_header *) ((char *) header + MULTIBOOT_HEADER_ALIGN))
+    {
+      if (header->magic == MULTIBOOT_HEADER_MAGIC
+         && !(header->magic + header->flags + header->checksum))
+       break;
+    }
+
+  if (header == 0)
+    {
+      grub_free (buffer);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found");
+    }
+
+  if (header->flags & UNSUPPORTED_FLAGS)
+    {
+      grub_free (buffer);
+      return grub_error (GRUB_ERR_UNKNOWN_OS,
+                        "unsupported flag: 0x%x", header->flags);
+    }
+
+  if (header->flags & MULTIBOOT_AOUT_KLUDGE)
+    {
+      int offset = ((char *) header - buffer -
+                   (header->header_addr - header->load_addr));
+      int load_size = ((header->load_end_addr == 0) ? file->size - offset :
+                      header->load_end_addr - header->load_addr);
+      grub_size_t code_size;
+
+      if (header->bss_end_addr)
+       code_size = (header->bss_end_addr - header->load_addr);
+      else
+       code_size = load_size;
+      grub_multiboot_payload_dest = header->load_addr;
+
+      grub_multiboot_pure_size += code_size;
+
+      /* Allocate a bit more to avoid relocations in most cases.  */
+      grub_multiboot_alloc_mbi = grub_multiboot_get_mbi_size () + 65536;
+      grub_multiboot_payload_orig
+       = grub_relocator32_alloc (grub_multiboot_pure_size + grub_multiboot_alloc_mbi);
+
+      if (! grub_multiboot_payload_orig)
+       {
+         grub_free (buffer);
+         return grub_errno;
+       }
+
+      if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
+       {
+         grub_free (buffer);
+         return grub_errno;
+       }
+
+      grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size);
+      if (grub_errno)
+       {
+         grub_free (buffer);
+         return grub_errno;
+       }
+
+      if (header->bss_end_addr)
+       grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0,
+                    header->bss_end_addr - header->load_addr - load_size);
+
+      grub_multiboot_payload_eip = header->entry_addr;
+
+    }
+  else
+    {
+      err = grub_multiboot_load_elf (file, buffer);
+      if (err)
+       {
+         grub_free (buffer);
+         return err;
+       }
+    }
+
+  if (header->flags & MULTIBOOT_VIDEO_MODE)
+    {
+      switch (header->mode_type)
+       {
+       case 1:
+         err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, 
+                                           GRUB_MULTIBOOT_CONSOLE_EGA_TEXT
+                                           | GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
+                                           0, 0, 0, 0);
+         break;
+       case 0:
+         err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
+                                           GRUB_MULTIBOOT_CONSOLE_EGA_TEXT
+                                           | GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
+                                           header->width, header->height,
+                                           header->depth, 0);
+         break;
+       default:
+         err = grub_error (GRUB_ERR_BAD_OS, 
+                           "unsupported graphical mode type %d",
+                           header->mode_type);
+         break;
+       }
+    }
+  else
+    err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, 
+                                     GRUB_MULTIBOOT_CONSOLE_EGA_TEXT,
+                                     0, 0, 0, 0);
+  return err;
+}
+
+grub_size_t
+grub_multiboot_get_mbi_size (void)
+{
+  return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4)
+    + modcnt * sizeof (struct multiboot_mod_list) + total_modcmd
+    + ALIGN_UP (sizeof(PACKAGE_STRING), 4) 
+    + grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry)
+    + 256 * sizeof (struct multiboot_color);
+}
+
+/* Fill previously allocated Multiboot mmap.  */
+static void
+grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry)
+{
+  struct multiboot_mmap_entry *mmap_entry = (struct multiboot_mmap_entry *) first_entry;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      mmap_entry->addr = addr;
+      mmap_entry->len = size;
+      switch (type)
+       {
+       case GRUB_MACHINE_MEMORY_AVAILABLE:
+         mmap_entry->type = MULTIBOOT_MEMORY_AVAILABLE;
+         break;
+
+#ifdef GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE
+       case GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE:
+         mmap_entry->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE;
+         break;
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_NVS
+       case GRUB_MACHINE_MEMORY_NVS:
+         mmap_entry->type = MULTIBOOT_MEMORY_NVS;
+         break;
+#endif   
+         
+       default:
+         mmap_entry->type = MULTIBOOT_MEMORY_RESERVED;
+         break;
+       }
+      mmap_entry->size = sizeof (struct multiboot_mmap_entry) - sizeof (mmap_entry->size);
+      mmap_entry++;
+
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+}
+
+static grub_err_t
+retrieve_video_parameters (struct multiboot_info *mbi,
+                          grub_uint8_t *ptrorig, grub_uint32_t ptrdest)
+{
+  grub_err_t err;
+  struct grub_video_mode_info mode_info;
+  void *framebuffer;
+  grub_video_driver_id_t driv_id;
+  struct grub_video_palette_data palette[256];
+
+  err = grub_multiboot_set_video_mode ();
+  if (err)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+    }
+
+  grub_video_get_palette (0, ARRAY_SIZE (palette), palette);
+
+  driv_id = grub_video_get_driver_id ();
+  if (driv_id == GRUB_VIDEO_DRIVER_NONE)
+    return GRUB_ERR_NONE;
+
+  err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
+  if (err)
+    return err;
+
+  mbi->framebuffer_addr = (grub_addr_t) framebuffer;
+  mbi->framebuffer_pitch = mode_info.pitch;
+
+  mbi->framebuffer_width = mode_info.width;
+  mbi->framebuffer_height = mode_info.height;
+
+  mbi->framebuffer_bpp = mode_info.bpp;
+      
+  if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
+    {
+      struct multiboot_color *mb_palette;
+      unsigned i;
+      mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED;
+      mbi->framebuffer_palette_addr = ptrdest;
+      mbi->framebuffer_palette_num_colors = mode_info.number_of_colors;
+      if (mbi->framebuffer_palette_num_colors > ARRAY_SIZE (palette))
+       mbi->framebuffer_palette_num_colors = ARRAY_SIZE (palette);
+      mb_palette = (struct multiboot_color *) ptrorig;
+      for (i = 0; i < mbi->framebuffer_palette_num_colors; i++)
+       {
+         mb_palette[i].red = palette[i].r;
+         mb_palette[i].green = palette[i].g;
+         mb_palette[i].blue = palette[i].b;
+       }
+      ptrorig += mbi->framebuffer_palette_num_colors
+       * sizeof (struct multiboot_color);
+      ptrdest += mbi->framebuffer_palette_num_colors
+       * sizeof (struct multiboot_color);
+    }
+  else
+    {
+      mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
+      mbi->framebuffer_red_field_position = mode_info.green_field_pos;
+      mbi->framebuffer_red_mask_size = mode_info.green_mask_size;
+      mbi->framebuffer_green_field_position = mode_info.green_field_pos;
+      mbi->framebuffer_green_mask_size = mode_info.green_mask_size;
+      mbi->framebuffer_blue_field_position = mode_info.blue_field_pos;
+      mbi->framebuffer_blue_mask_size = mode_info.blue_mask_size;
+    }
+
+  mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
+                        grub_size_t bufsize)
+{
+  grub_uint8_t *ptrorig = (grub_uint8_t *) orig + buf_off;
+  grub_uint32_t ptrdest = dest + buf_off;
+  struct multiboot_info *mbi;
+  struct multiboot_mod_list *modlist;
+  unsigned i;
+  struct module *cur;
+  grub_size_t mmap_size;
+  grub_err_t err;
+
+  if (bufsize < grub_multiboot_get_mbi_size ())
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small");
+
+  mbi = (struct multiboot_info *) ptrorig;
+  ptrorig += sizeof (*mbi);
+  ptrdest += sizeof (*mbi);
+  grub_memset (mbi, 0, sizeof (*mbi));
+
+  grub_memcpy (ptrorig, cmdline, cmdline_size);
+  mbi->flags |= MULTIBOOT_INFO_CMDLINE;
+  mbi->cmdline = ptrdest;
+  ptrorig += ALIGN_UP (cmdline_size, 4);
+  ptrdest += ALIGN_UP (cmdline_size, 4);
+
+  grub_memcpy (ptrorig, PACKAGE_STRING, sizeof(PACKAGE_STRING));
+  mbi->flags |= MULTIBOOT_INFO_BOOT_LOADER_NAME;
+  mbi->boot_loader_name = ptrdest;
+  ptrorig += ALIGN_UP (sizeof(PACKAGE_STRING), 4);
+  ptrdest += ALIGN_UP (sizeof(PACKAGE_STRING), 4);
+
+  if (modcnt)
+    {
+      mbi->flags |= MULTIBOOT_INFO_MODS;
+      mbi->mods_addr = ptrdest;
+      mbi->mods_count = modcnt;
+      modlist = (struct multiboot_mod_list *) ptrorig;
+      ptrorig += modcnt * sizeof (struct multiboot_mod_list);
+      ptrdest += modcnt * sizeof (struct multiboot_mod_list);
+
+      for (i = 0, cur = modules; i < modcnt; i++, cur = cur->next)
+       {
+         modlist[i].mod_start = cur->start;
+         modlist[i].mod_end = modlist[i].mod_start + cur->size;
+         modlist[i].cmdline = ptrdest;
+         grub_memcpy (ptrorig, cur->cmdline, cur->cmdline_size);
+         ptrorig += ALIGN_UP (cur->cmdline_size, 4);
+         ptrdest += ALIGN_UP (cur->cmdline_size, 4);
+       }
+    }
+  else
+    {
+      mbi->mods_addr = 0;
+      mbi->mods_count = 0;
+    }
+
+  mmap_size = grub_get_multiboot_mmap_count () 
+    * sizeof (struct multiboot_mmap_entry);
+  grub_fill_multiboot_mmap ((struct multiboot_mmap_entry *) ptrorig);
+  mbi->mmap_length = mmap_size;
+  mbi->mmap_addr = ptrdest;
+  mbi->flags |= MULTIBOOT_INFO_MEM_MAP;
+  ptrorig += mmap_size;
+  ptrdest += mmap_size;
+
+  /* Convert from bytes to kilobytes.  */
+  mbi->mem_lower = grub_mmap_get_lower () / 1024;
+  mbi->mem_upper = grub_mmap_get_upper () / 1024;
+  mbi->flags |= MULTIBOOT_INFO_MEMORY;
+
+  if (bootdev_set)
+    {
+      mbi->boot_device = bootdev;
+      mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
+    }
+
+  err = retrieve_video_parameters (mbi, ptrorig, ptrdest);
+  if (err)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+void
+grub_multiboot_free_mbi (void)
+{
+  struct module *cur, *next;
+
+  cmdline_size = 0;
+  total_modcmd = 0;
+  modcnt = 0;
+  grub_free (cmdline);
+  cmdline = NULL;
+  bootdev_set = 0;
+
+  for (cur = modules; cur; cur = next)
+    {
+      next = cur->next;
+      grub_free (cur->cmdline);
+      grub_free (cur);
+    }
+  modules = NULL;
+  modules_last = NULL;
+}
+
+grub_err_t
+grub_multiboot_init_mbi (int argc, char *argv[])
+{
+  grub_ssize_t len = 0;
+  char *p;
+  int i;
+
+  grub_multiboot_free_mbi ();
+
+  for (i = 0; i < argc; i++)
+    len += grub_strlen (argv[i]) + 1;
+  if (len == 0)
+    len = 1;
+
+  cmdline = p = grub_malloc (len);
+  if (! cmdline)
+    return grub_errno;
+  cmdline_size = len;
+
+  for (i = 0; i < argc; i++)
+    {
+      p = grub_stpcpy (p, argv[i]);
+      *(p++) = ' ';
+    }
+
+  /* Remove the space after the last word.  */
+  if (p != cmdline)
+    p--;
+  *p = '\0';
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
+                          int argc, char *argv[])
+{
+  struct module *newmod;
+  char *p;
+  grub_ssize_t len = 0;
+  int i;
+
+  newmod = grub_malloc (sizeof (*newmod));
+  if (!newmod)
+    return grub_errno;
+  newmod->start = start;
+  newmod->size = size;
+
+  for (i = 0; i < argc; i++)
+    len += grub_strlen (argv[i]) + 1;
+
+  if (len == 0)
+    len = 1;
+
+  newmod->cmdline = p = grub_malloc (len);
+  if (! newmod->cmdline)
+    {
+      grub_free (newmod);
+      return grub_errno;
+    }
+  newmod->cmdline_size = len;
+  total_modcmd += ALIGN_UP (len, 4);
+
+  for (i = 0; i < argc; i++)
+    {
+      p = grub_stpcpy (p, argv[i]);
+      *(p++) = ' ';
+    }
+
+  /* Remove the space after the last word.  */
+  if (p != newmod->cmdline)
+    p--;
+  *p = '\0';
+
+  if (modules_last)
+    modules_last->next = newmod;
+  else
+    {
+      modules = newmod;
+      modules_last->next = NULL;
+    }
+  modules_last = newmod;
+
+  modcnt++;
+
+  return GRUB_ERR_NONE;
+}
+
+void
+grub_multiboot_set_bootdev (void)
+{
+  grub_uint32_t biosdev, slice = ~0, part = ~0;
+  grub_device_t dev;
+
+#ifdef GRUB_MACHINE_PCBIOS
+  biosdev = grub_get_root_biosnumber ();
+#else
+  biosdev = 0xffffffff;
+#endif
+
+  if (biosdev == 0xffffffff)
+    return;
+
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->partition)
+    {
+      if (dev->disk->partition->parent)
+       {
+         part = dev->disk->partition->number;
+         slice = dev->disk->partition->parent->number;
+       }
+      else
+       slice = dev->disk->partition->number;
+    }
+  if (dev)
+    grub_device_close (dev);
+
+  bootdev = ((biosdev & 0xff) << 24) | ((slice & 0xff) << 16) 
+    | ((part & 0xff) << 8) | 0xff;
+  bootdev_set = 1;
+}
diff --git a/grub-core/loader/i386/pc/chainloader.c b/grub-core/loader/i386/pc/chainloader.c
new file mode 100644 (file)
index 0000000..502031d
--- /dev/null
@@ -0,0 +1,173 @@
+/* chainloader.c - boot another boot loader */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2007,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/machine/chainloader.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/machine/init.h>
+#include <grub/partition.h>
+#include <grub/machine/memory.h>
+#include <grub/dl.h>
+#include <grub/command.h>
+#include <grub/msdos_partition.h>
+#include <grub/machine/biosnum.h>
+#include <grub/i18n.h>
+#include <grub/video.h>
+#include <grub/mm.h>
+
+static grub_dl_t my_mod;
+static int boot_drive;
+static void *boot_part_addr;
+
+static grub_err_t
+grub_chainloader_boot (void)
+{
+  grub_video_set_mode ("text", 0, 0);
+  grub_chainloader_real_boot (boot_drive, boot_part_addr);
+
+  /* Never reach here.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_chainloader_unload (void)
+{
+  grub_dl_unref (my_mod);
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
+{
+  grub_file_t file = 0;
+  grub_uint16_t signature;
+  grub_device_t dev;
+  int drive = -1;
+  void *part_addr = 0;
+
+  grub_dl_ref (my_mod);
+
+  file = grub_file_open (filename);
+  if (! file)
+    goto fail;
+
+  /* Read the first block.  */
+  if (grub_file_read (file, (void *) 0x7C00, GRUB_DISK_SECTOR_SIZE)
+      != GRUB_DISK_SECTOR_SIZE)
+    {
+      if (grub_errno == GRUB_ERR_NONE)
+       grub_error (GRUB_ERR_BAD_OS, "too small");
+
+      goto fail;
+    }
+
+  /* Check the signature.  */
+  signature = *((grub_uint16_t *) (0x7C00 + GRUB_DISK_SECTOR_SIZE - 2));
+  if (signature != grub_le_to_cpu16 (0xaa55)
+      && ! (flags & GRUB_CHAINLOADER_FORCE))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "invalid signature");
+      goto fail;
+    }
+
+  grub_file_close (file);
+
+  /* Obtain the partition table from the root device.  */
+  drive = grub_get_root_biosnumber ();
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->partition)
+    {
+      grub_disk_t disk = dev->disk;
+
+      if (disk)
+       {
+         grub_partition_t p = disk->partition;
+
+         if (p && grub_strcmp (p->partmap->name, "msdos") == 0)
+           {
+             disk->partition = p->parent;
+             grub_disk_read (disk, p->offset, 446, 64,
+                             (void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR);
+             part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR
+                                   + (p->index << 4));
+             disk->partition = p;
+           }
+       }
+    }
+
+  if (dev)
+    grub_device_close (dev);
+  /* Ignore errors. Perhaps it's not fatal.  */
+  grub_errno = GRUB_ERR_NONE;
+
+  boot_drive = drive;
+  boot_part_addr = part_addr;
+
+  grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 1);
+  return;
+
+ fail:
+
+  if (file)
+    grub_file_close (file);
+
+  grub_dl_unref (my_mod);
+}
+
+static grub_err_t
+grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
+                     int argc, char *argv[])
+{
+  grub_chainloader_flags_t flags = 0;
+
+  if (argc > 0 && grub_strcmp (argv[0], "--force") == 0)
+    {
+      flags |= GRUB_CHAINLOADER_FORCE;
+      argc--;
+      argv++;
+    }
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
+  else
+    grub_chainloader_cmd (argv[0], flags);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(chainloader)
+{
+  cmd = grub_register_command ("chainloader", grub_cmd_chainloader,
+                              0, N_("Load another boot loader."));
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(chainloader)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
new file mode 100644 (file)
index 0000000..0fa9abc
--- /dev/null
@@ -0,0 +1,410 @@
+/* linux.c - boot Linux zImage or bzImage */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/loader.h>
+#include <grub/machine/loader.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/dl.h>
+#include <grub/cpu/linux.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+#include <grub/mm.h>
+#include <grub/video.h>
+
+#define GRUB_LINUX_CL_OFFSET           0x9000
+#define GRUB_LINUX_CL_END_OFFSET       0x90FF
+
+static grub_dl_t my_mod;
+
+static grub_size_t linux_mem_size;
+static int loaded;
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  grub_dl_unref (my_mod);
+  loaded = 0;
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux16_boot (void)
+{
+  grub_video_set_mode ("text", 0, 0);
+  grub_linux16_real_boot ();
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+               int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  struct linux_kernel_header lh;
+  grub_uint8_t setup_sects;
+  grub_size_t real_size, prot_size;
+  grub_ssize_t len;
+  int i;
+  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_size_t) grub_file_size (file) > grub_os_area_size)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "too big kernel (0x%x > 0x%x)",
+                 (grub_size_t) grub_file_size (file),
+                 grub_os_area_size);
+      goto fail;
+    }
+
+  if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
+    {
+      grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
+      goto fail;
+    }
+
+  if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
+      goto fail;
+    }
+
+  if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "too many setup sectors");
+      goto fail;
+    }
+
+  grub_linux_is_bzimage = 0;
+  setup_sects = lh.setup_sects;
+  linux_mem_size = 0;
+
+  if (lh.header == grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
+      && grub_le_to_cpu16 (lh.version) >= 0x0200)
+    {
+      grub_linux_is_bzimage = (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL);
+      lh.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;
+
+      /* Put the real mode part at as a high location as possible.  */
+      grub_linux_real_addr
+       = (char *) UINT_TO_PTR (grub_mmap_get_lower ()
+                               - GRUB_LINUX_SETUP_MOVE_SIZE);
+      /* But it must not exceed the traditional area.  */
+      if (grub_linux_real_addr > (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR)
+       grub_linux_real_addr = (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR;
+
+      if (grub_le_to_cpu16 (lh.version) >= 0x0201)
+       {
+         lh.heap_end_ptr = grub_cpu_to_le16 (GRUB_LINUX_HEAP_END_OFFSET);
+         lh.loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP;
+       }
+
+      if (grub_le_to_cpu16 (lh.version) >= 0x0202)
+       lh.cmd_line_ptr = grub_linux_real_addr + GRUB_LINUX_CL_OFFSET;
+      else
+       {
+         lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC);
+         lh.cl_offset = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET);
+         lh.setup_move_size = grub_cpu_to_le16 (GRUB_LINUX_SETUP_MOVE_SIZE);
+       }
+    }
+  else
+    {
+      /* Your kernel is quite old...  */
+      lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC);
+      lh.cl_offset = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET);
+
+      setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
+
+      grub_linux_real_addr = (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR;
+    }
+
+  /* If SETUP_SECTS is not set, set it to the default (4).  */
+  if (! setup_sects)
+    setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
+
+  real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
+  prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
+
+  grub_linux_tmp_addr = (char *) GRUB_LINUX_BZIMAGE_ADDR + prot_size;
+
+  if (! grub_linux_is_bzimage
+      && ((char *) GRUB_LINUX_ZIMAGE_ADDR + prot_size > grub_linux_real_addr))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "too big zImage (0x%x > 0x%x), use bzImage instead",
+                 (char *) GRUB_LINUX_ZIMAGE_ADDR + prot_size,
+                 (grub_size_t) grub_linux_real_addr);
+      goto fail;
+    }
+
+  if (grub_linux_real_addr + GRUB_LINUX_SETUP_MOVE_SIZE
+      > (char *) UINT_TO_PTR (grub_mmap_get_lower ()))
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE,
+                "too small lower memory (0x%x > 0x%x)",
+                 grub_linux_real_addr + GRUB_LINUX_SETUP_MOVE_SIZE,
+                 (int) grub_mmap_get_lower ());
+      goto fail;
+    }
+
+  grub_printf ("   [Linux-%s, setup=0x%x, size=0x%x]\n",
+              grub_linux_is_bzimage ? "bzImage" : "zImage", real_size, prot_size);
+
+  for (i = 1; i < argc; i++)
+    if (grub_memcmp (argv[i], "vga=", 4) == 0)
+      {
+       /* Video mode selection support.  */
+       grub_uint16_t vid_mode;
+       char *val = argv[i] + 4;
+
+       if (grub_strcmp (val, "normal") == 0)
+         vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
+       else if (grub_strcmp (val, "ext") == 0)
+         vid_mode = GRUB_LINUX_VID_MODE_EXTENDED;
+       else if (grub_strcmp (val, "ask") == 0)
+         vid_mode = GRUB_LINUX_VID_MODE_ASK;
+       else
+         vid_mode = (grub_uint16_t) grub_strtoul (val, 0, 0);
+
+       if (grub_errno)
+         goto fail;
+
+       lh.vid_mode = grub_cpu_to_le16 (vid_mode);
+      }
+    else if (grub_memcmp (argv[i], "mem=", 4) == 0)
+      {
+       char *val = argv[i] + 4;
+
+       linux_mem_size = grub_strtoul (val, &val, 0);
+
+       if (grub_errno)
+         {
+           grub_errno = GRUB_ERR_NONE;
+           linux_mem_size = 0;
+         }
+       else
+         {
+           int shift = 0;
+
+           switch (grub_tolower (val[0]))
+             {
+             case 'g':
+               shift += 10;
+             case 'm':
+               shift += 10;
+             case 'k':
+               shift += 10;
+             default:
+               break;
+             }
+
+           /* Check an overflow.  */
+           if (linux_mem_size > (~0UL >> shift))
+             linux_mem_size = 0;
+           else
+             linux_mem_size <<= shift;
+         }
+      }
+
+  /* Put the real mode code at the temporary address.  */
+  grub_memmove (grub_linux_tmp_addr, &lh, sizeof (lh));
+
+  len = real_size + GRUB_DISK_SECTOR_SIZE - sizeof (lh);
+  if (grub_file_read (file, grub_linux_tmp_addr + sizeof (lh), len) != len)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+      goto fail;
+    }
+
+  if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
+      || grub_le_to_cpu16 (lh.version) < 0x0200)
+    /* Clear the heap space.  */
+    grub_memset (grub_linux_tmp_addr
+                + ((setup_sects + 1) << GRUB_DISK_SECTOR_BITS),
+                0,
+                ((GRUB_LINUX_MAX_SETUP_SECTS - setup_sects - 1)
+                 << GRUB_DISK_SECTOR_BITS));
+
+  /* Specify the boot file.  */
+  dest = grub_stpcpy (grub_linux_tmp_addr + GRUB_LINUX_CL_OFFSET,
+                     "BOOT_IMAGE=");
+  dest = grub_stpcpy (dest, argv[0]);
+
+  /* Copy kernel parameters.  */
+  for (i = 1;
+       i < argc
+        && dest + grub_strlen (argv[i]) + 1 < (grub_linux_tmp_addr
+                                               + GRUB_LINUX_CL_END_OFFSET);
+       i++)
+    {
+      *dest++ = ' ';
+      dest = grub_stpcpy (dest, argv[i]);
+    }
+
+  len = prot_size;
+  if (grub_file_read (file, (void *) GRUB_LINUX_BZIMAGE_ADDR, len) != len)
+    grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+
+  if (grub_errno == GRUB_ERR_NONE)
+    {
+      grub_linux_prot_size = prot_size;
+      grub_loader_set (grub_linux16_boot, grub_linux_unload, 1);
+      loaded = 1;
+    }
+
+ fail:
+
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_dl_unref (my_mod);
+      loaded = 0;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+                int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  grub_addr_t addr_max, addr_min, addr;
+  struct linux_kernel_header *lh;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
+      goto fail;
+    }
+
+  if (!loaded)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
+      goto fail;
+    }
+
+  lh = (struct linux_kernel_header *) grub_linux_tmp_addr;
+
+  if (!(lh->header == grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
+       && grub_le_to_cpu16 (lh->version) >= 0x0200))
+    {
+      grub_error (GRUB_ERR_BAD_OS, "the kernel is too old for initrd");
+      goto fail;
+    }
+
+  /* Get the highest address available for the initrd.  */
+  if (grub_le_to_cpu16 (lh->version) >= 0x0203)
+    {
+      addr_max = grub_cpu_to_le32 (lh->initrd_addr_max);
+
+      /* XXX in reality, Linux specifies a bogus value, so
+        it is necessary to make sure that ADDR_MAX does not exceed
+        0x3fffffff.  */
+      if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS)
+       addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
+    }
+  else
+    addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
+
+  if (linux_mem_size != 0 && linux_mem_size < addr_max)
+    addr_max = linux_mem_size;
+
+  /* Linux 2.3.xx has a bug in the memory range check, so avoid
+     the last page.
+     Linux 2.2.xx has a bug in the memory range check, which is
+     worse than that of Linux 2.3.xx, so avoid the last 64kb.  */
+  addr_max -= 0x10000;
+
+  if (addr_max > grub_os_area_addr + grub_os_area_size)
+    addr_max = grub_os_area_addr + grub_os_area_size;
+
+  addr_min = (grub_addr_t) grub_linux_tmp_addr + GRUB_LINUX_CL_END_OFFSET;
+
+  file = grub_file_open (argv[0]);
+  if (!file)
+    goto fail;
+
+  size = grub_file_size (file);
+
+  /* Put the initrd as high as possible, 4KiB aligned.  */
+  addr = (addr_max - size) & ~0xFFF;
+
+  if (addr < addr_min)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "the initrd is too big");
+      goto fail;
+    }
+
+  if (grub_file_read (file, (void *) addr, size) != size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+      goto fail;
+    }
+
+  lh->ramdisk_image = addr;
+  lh->ramdisk_size = size;
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT(linux16)
+{
+  cmd_linux =
+    grub_register_command ("linux16", grub_cmd_linux,
+                          0, N_("Load Linux."));
+  cmd_initrd =
+    grub_register_command ("initrd16", grub_cmd_initrd,
+                          0, N_("Load initrd."));
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux16)
+{
+  grub_unregister_command (cmd_linux);
+  grub_unregister_command (cmd_initrd);
+}
diff --git a/grub-core/loader/i386/pc/xnu.c b/grub-core/loader/i386/pc/xnu.c
new file mode 100644 (file)
index 0000000..39a595d
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/xnu.h>
+#include <grub/mm.h>
+#include <grub/cpu/xnu.h>
+#include <grub/video_fb.h>
+#include <grub/bitmap_scale.h>
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+
+#define DEFAULT_VIDEO_MODE "auto"
+
+/* Setup video for xnu. */
+grub_err_t
+grub_xnu_set_video (struct grub_xnu_boot_params *params)
+{
+  struct grub_video_mode_info mode_info;
+  int ret;
+  char *tmp;
+  const char *modevar;
+  void *framebuffer;
+  grub_err_t err;
+  struct grub_video_bitmap *bitmap = NULL;
+
+  modevar = grub_env_get ("gfxpayload");
+  /* Consider only graphical 32-bit deep modes.  */
+  if (! modevar || *modevar == 0)
+    err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
+                              GRUB_VIDEO_MODE_TYPE_PURE_TEXT
+                              | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
+                              32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
+  else
+    {
+      tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
+      if (! tmp)
+       return grub_errno;
+      err = grub_video_set_mode (tmp,
+                                GRUB_VIDEO_MODE_TYPE_PURE_TEXT
+                                | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
+                                32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
+      grub_free (tmp);
+    }
+
+  if (err)
+    return err;
+
+  ret = grub_video_get_info (&mode_info);
+  if (ret)
+    return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
+
+  if (grub_xnu_bitmap)
+    {
+      if (grub_xnu_bitmap_mode == GRUB_XNU_BITMAP_STRETCH)
+       err = grub_video_bitmap_create_scaled (&bitmap,
+                                              mode_info.width,
+                                              mode_info.height,
+                                              grub_xnu_bitmap,
+                                              GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
+      else
+       bitmap = grub_xnu_bitmap;
+    }
+
+  if (bitmap)
+    {
+      int x, y;
+
+      x = mode_info.width - bitmap->mode_info.width;
+      x /= 2;
+      y = mode_info.height - bitmap->mode_info.height;
+      y /= 2;
+      err = grub_video_blit_bitmap (bitmap,
+                                   GRUB_VIDEO_BLIT_REPLACE,
+                                   x > 0 ? x : 0,
+                                   y > 0 ? y : 0,
+                                   x < 0 ? -x : 0,
+                                   y < 0 ? -y : 0,
+                                   min (bitmap->mode_info.width,
+                                        mode_info.width),
+                                   min (bitmap->mode_info.height,
+                                        mode_info.height));
+    }
+  if (err)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      bitmap = 0;
+    }
+
+  ret = grub_video_get_info_and_fini (&mode_info, &framebuffer);
+  if (ret)
+    return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
+
+  params->lfb_width = mode_info.width;
+  params->lfb_height = mode_info.height;
+  params->lfb_depth = mode_info.bpp;
+  params->lfb_line_len = mode_info.pitch;
+
+  params->lfb_base = PTR_TO_UINT32 (framebuffer);
+  params->lfb_mode = bitmap ? GRUB_XNU_VIDEO_SPLASH 
+    : GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
+
+  return GRUB_ERR_NONE;
+}
+
diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c
new file mode 100644 (file)
index 0000000..8000579
--- /dev/null
@@ -0,0 +1,1039 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/xnu.h>
+#include <grub/cpu/xnu.h>
+#include <grub/mm.h>
+#include <grub/loader.h>
+#include <grub/autoefi.h>
+#include <grub/i386/tsc.h>
+#include <grub/efi/api.h>
+#include <grub/i386/pit.h>
+#include <grub/misc.h>
+#include <grub/charset.h>
+#include <grub/term.h>
+#include <grub/command.h>
+#include <grub/gzio.h>
+#include <grub/i18n.h>
+
+char grub_xnu_cmdline[1024];
+grub_uint32_t grub_xnu_heap_will_be_at;
+grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack;
+
+/* Aliases set for some tables. */
+struct tbl_alias
+{
+  grub_efi_guid_t guid;
+  char *name;
+};
+
+struct tbl_alias table_aliases[] =
+  {
+    {GRUB_EFI_ACPI_20_TABLE_GUID, "ACPI_20"},
+    {GRUB_EFI_ACPI_TABLE_GUID, "ACPI"},
+  };
+
+struct grub_xnu_devprop_device_descriptor
+{
+  struct grub_xnu_devprop_device_descriptor *next;
+  struct property_descriptor *properties;
+  struct grub_efi_device_path *path;
+  int pathlen;
+};
+
+static int
+utf16_strlen (grub_uint16_t *in)
+{
+  int i;
+  for (i = 0; in[i]; i++);
+  return i;
+}
+
+/* Read frequency from a string in MHz and return it in Hz. */
+static grub_uint64_t
+readfrequency (const char *str)
+{
+  grub_uint64_t num = 0;
+  int mul = 1000000;
+  int found = 0;
+
+  while (*str)
+    {
+      unsigned long digit;
+
+      digit = grub_tolower (*str) - '0';
+      if (digit > 9)
+       break;
+
+      found = 1;
+
+      num = num * 10 + digit;
+      str++;
+    }
+  num *= 1000000;
+  if (*str == '.')
+    {
+      str++;
+      while (*str)
+       {
+         unsigned long digit;
+
+         digit = grub_tolower (*str) - '0';
+         if (digit > 9)
+           break;
+
+         found = 1;
+
+         mul /= 10;
+         num = num + mul * digit;
+         str++;
+       }
+    }
+  if (! found)
+    return 0;
+
+  return num;
+}
+
+/* Thanks to Kabyl for precious information about Intel architecture. */
+static grub_uint64_t
+guessfsb (void)
+{
+  const grub_uint64_t sane_value = 100000000;
+  grub_uint32_t manufacturer[3], max_cpuid, capabilities, msrlow;
+  grub_uint64_t start_tsc;
+  grub_uint64_t end_tsc;
+  grub_uint64_t tsc_ticks_per_ms;
+
+  if (! grub_cpu_is_cpuid_supported ())
+    return sane_value;
+
+#ifdef APPLE_CC
+  asm volatile ("movl $0, %%eax\n"
+#ifdef __x86_64__
+               "push %%rbx\n"
+#else
+               "push %%ebx\n"
+#endif
+               "cpuid\n"
+#ifdef __x86_64__
+               "pop %%rbx\n"
+#else
+               "pop %%ebx\n"
+#endif
+               : "=a" (max_cpuid),
+                 "=d" (manufacturer[1]), "=c" (manufacturer[2]));
+
+  /* Only Intel for now is done. */
+  if (grub_memcmp (manufacturer + 1, "ineIntel", 12) != 0)
+    return sane_value;
+
+#else
+  asm volatile ("movl $0, %%eax\n"
+               "cpuid"
+               : "=a" (max_cpuid), "=b" (manufacturer[0]),
+                 "=d" (manufacturer[1]), "=c" (manufacturer[2]));
+
+  /* Only Intel for now is done. */
+  if (grub_memcmp (manufacturer, "GenuineIntel", 12) != 0)
+    return sane_value;
+#endif
+
+  /* Check Speedstep. */
+  if (max_cpuid < 1)
+    return sane_value;
+
+#ifdef APPLE_CC
+  asm volatile ("movl $1, %%eax\n"
+#ifdef __x86_64__
+               "push %%rbx\n"
+#else
+               "push %%ebx\n"
+#endif
+               "cpuid\n"
+#ifdef __x86_64__
+               "pop %%rbx\n"
+#else
+               "pop %%ebx\n"
+#endif
+               : "=c" (capabilities):
+               : "%rax", "%rdx");
+#else
+  asm volatile ("movl $1, %%eax\n"
+               "cpuid"
+               : "=c" (capabilities):
+               : "%rax", "%rbx", "%rdx");
+#endif
+
+  if (! (capabilities & (1 << 7)))
+    return sane_value;
+
+  /* Calibrate the TSC rate. */
+
+  start_tsc = grub_get_tsc ();
+  grub_pit_wait (0xffff);
+  end_tsc = grub_get_tsc ();
+
+  tsc_ticks_per_ms = grub_divmod64 (end_tsc - start_tsc, 55, 0);
+
+  /* Read the multiplier. */
+  asm volatile ("movl $0x198, %%ecx\n"
+               "rdmsr"
+               : "=d" (msrlow)
+               :
+               : "%ecx", "%eax");
+
+  return grub_divmod64 (2000 * tsc_ticks_per_ms,
+                       ((msrlow >> 7) & 0x3e) + ((msrlow >> 14) & 1), 0);
+}
+
+struct property_descriptor
+{
+  struct property_descriptor *next;
+  grub_uint8_t *name;
+  grub_uint16_t *name16;
+  int name16len;
+  int length;
+  void *data;
+};
+
+struct grub_xnu_devprop_device_descriptor *devices = 0;
+
+grub_err_t
+grub_xnu_devprop_remove_property (struct grub_xnu_devprop_device_descriptor *dev,
+                                 char *name)
+{
+  struct property_descriptor *prop;
+  prop = grub_named_list_find (GRUB_AS_NAMED_LIST_P (&dev->properties), name);
+  if (!prop)
+    return GRUB_ERR_NONE;
+
+  grub_free (prop->name);
+  grub_free (prop->name16);
+  grub_free (prop->data);
+
+  grub_list_remove (GRUB_AS_LIST_P (&dev->properties), GRUB_AS_LIST (prop));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_xnu_devprop_remove_device (struct grub_xnu_devprop_device_descriptor *dev)
+{
+  void *t;
+  struct property_descriptor *prop;
+
+  grub_list_remove (GRUB_AS_LIST_P (&devices), GRUB_AS_LIST (dev));
+
+  for (prop = dev->properties; prop; )
+    {
+      grub_free (prop->name);
+      grub_free (prop->name16);
+      grub_free (prop->data);
+      t = prop;
+      prop = prop->next;
+      grub_free (t);
+    }
+
+  grub_free (dev->path);
+  grub_free (dev);
+
+  return GRUB_ERR_NONE;
+}
+
+struct grub_xnu_devprop_device_descriptor *
+grub_xnu_devprop_add_device (struct grub_efi_device_path *path, int length)
+{
+  struct grub_xnu_devprop_device_descriptor *ret;
+
+  ret = grub_zalloc (sizeof (*ret));
+  if (!ret)
+    return 0;
+
+  ret->path = grub_malloc (length);
+  if (!ret->path)
+    {
+      grub_free (ret);
+      return 0;
+    }
+  ret->pathlen = length;
+  grub_memcpy (ret->path, path, length);
+
+  grub_list_push (GRUB_AS_LIST_P (&devices), GRUB_AS_LIST (ret));
+
+  return ret;
+}
+
+static grub_err_t
+grub_xnu_devprop_add_property (struct grub_xnu_devprop_device_descriptor *dev,
+                              grub_uint8_t *utf8, grub_uint16_t *utf16,
+                              int utf16len, void *data, int datalen)
+{
+  struct property_descriptor *prop;
+
+  prop = grub_malloc (sizeof (*prop));
+  if (!prop)
+    return grub_errno;
+
+  prop->name = utf8;
+  prop->name16 = utf16;
+  prop->name16len = utf16len;
+
+  prop->length = datalen;
+  prop->data = grub_malloc (prop->length);
+  if (!prop->data)
+    {
+      grub_free (prop);
+      grub_free (prop->name);
+      grub_free (prop->name16);
+      return grub_errno;
+    }
+  grub_memcpy (prop->data, data, prop->length);
+  grub_list_push (GRUB_AS_LIST_P (&dev->properties),
+                 GRUB_AS_LIST (prop));
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *dev,
+                                   char *name, void *data, int datalen)
+{
+  grub_uint8_t *utf8;
+  grub_uint16_t *utf16;
+  int len, utf16len;
+  grub_err_t err;
+
+  utf8 = (grub_uint8_t *) grub_strdup (name);
+  if (!utf8)
+    return grub_errno;
+
+  len = grub_strlen (name);
+  utf16 = grub_malloc (sizeof (grub_uint16_t) * len);
+  if (!utf16)
+    {
+      grub_free (utf8);
+      return grub_errno;
+    }
+
+  utf16len = grub_utf8_to_utf16 (utf16, len, utf8, len, NULL);
+  if (utf16len < 0)
+    {
+      grub_free (utf8);
+      grub_free (utf16);
+      return grub_errno;
+    }
+
+  err = grub_xnu_devprop_add_property (dev, utf8, utf16,
+                                      utf16len, data, datalen);
+  if (err)
+    {
+      grub_free (utf8);
+      grub_free (utf16);
+      return err;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor *dev,
+                                    grub_uint16_t *name, int namelen,
+                                    void *data, int datalen)
+{
+  grub_uint8_t *utf8;
+  grub_uint16_t *utf16;
+  grub_err_t err;
+
+  utf16 = grub_malloc (sizeof (grub_uint16_t) * namelen);
+  if (!utf16)
+    return grub_errno;
+  grub_memcpy (utf16, name, sizeof (grub_uint16_t) * namelen);
+
+  utf8 = grub_malloc (namelen * 4 + 1);
+  if (!utf8)
+    {
+      grub_free (utf8);
+      return grub_errno;
+    }
+
+  *grub_utf16_to_utf8 ((grub_uint8_t *) utf8, name, namelen) = '\0';
+
+  err = grub_xnu_devprop_add_property (dev, utf8, utf16,
+                                      namelen, data, datalen);
+  if (err)
+    {
+      grub_free (utf8);
+      grub_free (utf16);
+      return err;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static inline int
+hextoval (char c)
+{
+  if (c >= '0' && c <= '9')
+    return c - '0';
+  if (c >= 'a' && c <= 'z')
+    return c - 'a' + 10;
+  if (c >= 'A' && c <= 'Z')
+    return c - 'A' + 10;
+  return 0;
+}
+
+void
+grub_cpu_xnu_unload (void)
+{
+  struct grub_xnu_devprop_device_descriptor *dev1, *dev2;
+
+  for (dev1 = devices; dev1; )
+    {
+      dev2 = dev1->next;
+      grub_xnu_devprop_remove_device (dev1);
+      dev1 = dev2;
+    }
+}
+
+static grub_err_t
+grub_cpu_xnu_fill_devprop (void)
+{
+  struct grub_xnu_devtree_key *efikey;
+  int total_length = sizeof (struct grub_xnu_devprop_header);
+  struct grub_xnu_devtree_key *devprop;
+  struct grub_xnu_devprop_device_descriptor *device;
+  void *ptr;
+  struct grub_xnu_devprop_header *head;
+  void *t;
+  int numdevs = 0;
+
+  /* The key "efi". */
+  efikey = grub_xnu_create_key (&grub_xnu_devtree_root, "efi");
+  if (! efikey)
+    return grub_errno;
+
+  for (device = devices; device; device = device->next)
+    {
+      struct property_descriptor *propdesc;
+      total_length += sizeof (struct grub_xnu_devprop_device_header);
+      total_length += device->pathlen;
+
+      for (propdesc = device->properties; propdesc; propdesc = propdesc->next)
+       {
+         total_length += sizeof (grub_uint32_t);
+         total_length += sizeof (grub_uint16_t)
+           * (propdesc->name16len + 1);
+         total_length += sizeof (grub_uint32_t);
+         total_length += propdesc->length;
+       }
+      numdevs++;
+    }
+
+  devprop = grub_xnu_create_value (&(efikey->first_child), "device-properties");
+  if (devprop)
+    {
+      devprop->data = grub_malloc (total_length);
+      devprop->datasize = total_length;
+    }
+
+  ptr = devprop->data;
+  head = ptr;
+  ptr = head + 1;
+  head->length = total_length;
+  head->alwaysone = 1;
+  head->num_devices = numdevs;
+  for (device = devices; device; )
+    {
+      struct grub_xnu_devprop_device_header *devhead;
+      struct property_descriptor *propdesc;
+      devhead = ptr;
+      devhead->num_values = 0;
+      ptr = devhead + 1;
+
+      grub_memcpy (ptr, device->path, device->pathlen);
+      ptr = (char *) ptr + device->pathlen;
+
+      for (propdesc = device->properties; propdesc; )
+       {
+         grub_uint32_t *len;
+         grub_uint16_t *name;
+         void *data;
+
+         len = ptr;
+         *len = 2 * propdesc->name16len + sizeof (grub_uint16_t)
+           + sizeof (grub_uint32_t);
+         ptr = len + 1;
+
+         name = ptr;
+         grub_memcpy (name, propdesc->name16, 2 * propdesc->name16len);
+         name += propdesc->name16len;
+
+         /* NUL terminator.  */
+         *name = 0;
+         ptr = name + 1;
+
+         len = ptr;
+         *len = propdesc->length + sizeof (grub_uint32_t);
+         data = len + 1;
+         ptr = data;
+         grub_memcpy (ptr, propdesc->data, propdesc->length);
+         ptr = (char *) ptr + propdesc->length;
+
+         grub_free (propdesc->name);
+         grub_free (propdesc->name16);
+         grub_free (propdesc->data);
+         t = propdesc;
+         propdesc = propdesc->next;
+         grub_free (t);
+         devhead->num_values++;
+       }
+
+      devhead->length = (char *) ptr - (char *) devhead;
+      t = device;
+      device = device->next;
+      grub_free (t);
+    }
+
+  devices = 0;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_devprop_load (grub_command_t cmd __attribute__ ((unused)),
+                      int argc, char *args[])
+{
+  grub_file_t file;
+  void *buf, *bufstart, *bufend;
+  struct grub_xnu_devprop_header *head;
+  grub_size_t size;
+  unsigned i, j;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  file = grub_gzfile_open (args[0], 1);
+  if (! file)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
+                      "couldn't load device-propertie dump");
+  size = grub_file_size (file);
+  buf = grub_malloc (size);
+  if (!buf)
+    {
+      grub_file_close (file);
+      return grub_errno;
+    }
+  if (grub_file_read (file, buf, size) != (grub_ssize_t) size)
+    {
+      grub_file_close (file);
+      return grub_errno;
+    }
+  grub_file_close (file);
+
+  bufstart = buf;
+  bufend = (char *) buf + size;
+  head = buf;
+  buf = head + 1;
+  for (i = 0; i < grub_le_to_cpu32 (head->num_devices) && buf < bufend; i++)
+    {
+      struct grub_efi_device_path *dp, *dpstart;
+      struct grub_xnu_devprop_device_descriptor *dev;
+      struct grub_xnu_devprop_device_header *devhead;
+
+      devhead = buf;
+      buf = devhead + 1;
+      dpstart = buf;
+
+      do
+       {
+         dp = buf;
+         buf = (char *) buf + GRUB_EFI_DEVICE_PATH_LENGTH (dp);
+       }
+      while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp) && buf < bufend);
+
+      dev = grub_xnu_devprop_add_device (dpstart, (char *) buf
+                                        - (char *) dpstart);
+
+      for (j = 0; j < grub_le_to_cpu32 (devhead->num_values) && buf < bufend;
+          j++)
+       {
+         grub_uint32_t *namelen;
+         grub_uint32_t *datalen;
+         grub_uint16_t *utf16;
+         void *data;
+         grub_err_t err;
+
+         namelen = buf;
+         buf = namelen + 1;
+         if (buf >= bufend)
+           break;
+
+         utf16 = buf;
+         buf = (char *) buf + *namelen - sizeof (grub_uint32_t);
+         if (buf >= bufend)
+           break;
+
+         datalen = buf;
+         buf = datalen + 1;
+         if (buf >= bufend)
+           break;
+
+         data = buf;
+         buf = (char *) buf + *datalen - sizeof (grub_uint32_t);
+         if (buf >= bufend)
+           break;
+         err = grub_xnu_devprop_add_property_utf16
+           (dev, utf16, (*namelen - sizeof (grub_uint32_t)
+                         - sizeof (grub_uint16_t)) / sizeof (grub_uint16_t),
+            data, *datalen - sizeof (grub_uint32_t));
+         if (err)
+           {
+             grub_free (bufstart);
+             return err;
+           }
+       }
+    }
+
+  grub_free (bufstart);
+  return GRUB_ERR_NONE;
+}
+
+/* Fill device tree. */
+/* FIXME: some entries may be platform-agnostic. Move them to loader/xnu.c. */
+grub_err_t
+grub_cpu_xnu_fill_devicetree (void)
+{
+  struct grub_xnu_devtree_key *efikey;
+  struct grub_xnu_devtree_key *cfgtablekey;
+  struct grub_xnu_devtree_key *curval;
+  struct grub_xnu_devtree_key *runtimesrvkey;
+  struct grub_xnu_devtree_key *platformkey;
+  unsigned i, j;
+
+  /* The value "model". */
+  /* FIXME: may this value be sometimes different? */
+  curval = grub_xnu_create_value (&grub_xnu_devtree_root, "model");
+  if (! curval)
+    return grub_errno;
+  curval->datasize = sizeof ("ACPI");
+  curval->data = grub_strdup ("ACPI");
+  curval = grub_xnu_create_value (&grub_xnu_devtree_root, "compatible");
+  if (! curval)
+    return grub_errno;
+  curval->datasize = sizeof ("ACPI");
+  curval->data = grub_strdup ("ACPI");
+
+  /* The key "efi". */
+  efikey = grub_xnu_create_key (&grub_xnu_devtree_root, "efi");
+  if (! efikey)
+    return grub_errno;
+
+  /* Information about firmware. */
+  curval = grub_xnu_create_value (&(efikey->first_child), "firmware-revision");
+  if (! curval)
+    return grub_errno;
+  curval->datasize = (SYSTEM_TABLE_SIZEOF (firmware_revision));
+  curval->data = grub_malloc (curval->datasize);
+  if (! curval->data)
+    return grub_errno;
+  grub_memcpy (curval->data, (SYSTEM_TABLE_VAR(firmware_revision)),
+              curval->datasize);
+
+  curval = grub_xnu_create_value (&(efikey->first_child), "firmware-vendor");
+  if (! curval)
+    return grub_errno;
+  curval->datasize =
+    2 * (utf16_strlen (SYSTEM_TABLE_PTR (firmware_vendor)) + 1);
+  curval->data = grub_malloc (curval->datasize);
+  if (! curval->data)
+    return grub_errno;
+  grub_memcpy (curval->data, SYSTEM_TABLE_PTR (firmware_vendor),
+              curval->datasize);
+
+  curval = grub_xnu_create_value (&(efikey->first_child), "firmware-abi");
+  if (! curval)
+    return grub_errno;
+  curval->datasize = sizeof ("EFI32");
+  curval->data = grub_malloc (curval->datasize);
+  if (! curval->data)
+    return grub_errno;
+  if (SIZEOF_OF_UINTN == 4)
+    grub_memcpy (curval->data, "EFI32", curval->datasize);
+  else
+    grub_memcpy (curval->data, "EFI64", curval->datasize);
+
+  /* The key "platform". */
+  platformkey = grub_xnu_create_key (&(efikey->first_child),
+                                    "platform");
+  if (! platformkey)
+    return grub_errno;
+
+  /* Pass FSB frequency to the kernel. */
+  curval = grub_xnu_create_value (&(platformkey->first_child), "FSBFrequency");
+  if (! curval)
+    return grub_errno;
+  curval->datasize = sizeof (grub_uint64_t);
+  curval->data = grub_malloc (curval->datasize);
+  if (!curval->data)
+    return grub_errno;
+
+  /* First see if user supplies the value. */
+  char *fsbvar = grub_env_get ("fsb");
+  if (! fsbvar)
+    *((grub_uint64_t *) curval->data) = 0;
+  else
+    *((grub_uint64_t *) curval->data) = readfrequency (fsbvar);
+  /* Try autodetect. */
+  if (! *((grub_uint64_t *) curval->data))
+    *((grub_uint64_t *) curval->data) = guessfsb ();
+  grub_dprintf ("xnu", "fsb autodetected as %llu\n",
+               (unsigned long long) *((grub_uint64_t *) curval->data));
+
+  cfgtablekey = grub_xnu_create_key (&(efikey->first_child),
+                                    "configuration-table");
+  if (!cfgtablekey)
+    return grub_errno;
+
+  /* Fill "configuration-table" key. */
+  for (i = 0; i < SYSTEM_TABLE (num_table_entries); i++)
+    {
+      void *ptr;
+      struct grub_xnu_devtree_key *curkey;
+      grub_efi_guid_t guid;
+      char guidbuf[64];
+
+      /* Retrieve current key. */
+#ifdef GRUB_MACHINE_EFI
+      {
+       ptr = (void *)
+         grub_efi_system_table->configuration_table[i].vendor_table;
+       guid = grub_efi_system_table->configuration_table[i].vendor_guid;
+      }
+#else
+      if (SIZEOF_OF_UINTN == 4)
+       {
+         ptr = UINT_TO_PTR (((grub_efiemu_configuration_table32_t *)
+                             SYSTEM_TABLE_PTR (configuration_table))[i]
+                            .vendor_table);
+         guid =
+           ((grub_efiemu_configuration_table32_t *)
+            SYSTEM_TABLE_PTR (configuration_table))[i].vendor_guid;
+       }
+      else
+       {
+         ptr = UINT_TO_PTR (((grub_efiemu_configuration_table64_t *)
+                             SYSTEM_TABLE_PTR (configuration_table))[i]
+                            .vendor_table);
+         guid =
+           ((grub_efiemu_configuration_table64_t *)
+            SYSTEM_TABLE_PTR (configuration_table))[i].vendor_guid;
+       }
+#endif
+
+      /* The name of key for new table. */
+      grub_snprintf (guidbuf, sizeof (guidbuf), "%08x-%04x-%04x-%02x%02x-",
+                    guid.data1, guid.data2, guid.data3, guid.data4[0],
+                    guid.data4[1]);
+      for (j = 2; j < 8; j++)
+       grub_snprintf (guidbuf + grub_strlen (guidbuf),
+                      sizeof (guidbuf) - grub_strlen (guidbuf),
+                      "%02x", guid.data4[j]);
+      /* For some reason GUID has to be in uppercase. */
+      for (j = 0; guidbuf[j] ; j++)
+       if (guidbuf[j] >= 'a' && guidbuf[j] <= 'f')
+         guidbuf[j] += 'A' - 'a';
+      curkey = grub_xnu_create_key (&(cfgtablekey->first_child), guidbuf);
+      if (! curkey)
+       return grub_errno;
+
+      curval = grub_xnu_create_value (&(curkey->first_child), "guid");
+      if (! curval)
+       return grub_errno;
+      curval->datasize = sizeof (guid);
+      curval->data = grub_malloc (curval->datasize);
+      if (! curval->data)
+       return grub_errno;
+      grub_memcpy (curval->data, &guid, curval->datasize);
+
+      /* The value "table". */
+      curval = grub_xnu_create_value (&(curkey->first_child), "table");
+      if (! curval)
+       return grub_errno;
+      curval->datasize = SIZEOF_OF_UINTN;
+      curval->data = grub_malloc (curval->datasize);
+      if (! curval->data)
+       return grub_errno;
+      if (SIZEOF_OF_UINTN == 4)
+       *((grub_uint32_t *)curval->data) = PTR_TO_UINT32 (ptr);
+      else
+       *((grub_uint64_t *)curval->data) = PTR_TO_UINT64 (ptr);
+
+      /* Create alias. */
+      for (j = 0; j < sizeof (table_aliases) / sizeof (table_aliases[0]); j++)
+       if (grub_memcmp (&table_aliases[j].guid, &guid, sizeof (guid)) == 0)
+         break;
+      if (j != sizeof (table_aliases) / sizeof (table_aliases[0]))
+       {
+         curval = grub_xnu_create_value (&(curkey->first_child), "alias");
+         if (!curval)
+           return grub_errno;
+         curval->datasize = grub_strlen (table_aliases[j].name) + 1;
+         curval->data = grub_malloc (curval->datasize);
+         if (!curval->data)
+           return grub_errno;
+         grub_memcpy (curval->data, table_aliases[j].name, curval->datasize);
+       }
+    }
+
+  /* Create and fill "runtime-services" key. */
+  runtimesrvkey = grub_xnu_create_key (&(efikey->first_child),
+                                      "runtime-services");
+  if (! runtimesrvkey)
+    return grub_errno;
+  curval = grub_xnu_create_value (&(runtimesrvkey->first_child), "table");
+  if (! curval)
+    return grub_errno;
+  curval->datasize = SIZEOF_OF_UINTN;
+  curval->data = grub_malloc (curval->datasize);
+  if (! curval->data)
+    return grub_errno;
+  if (SIZEOF_OF_UINTN == 4)
+    *((grub_uint32_t *) curval->data)
+      = PTR_TO_UINT32 (SYSTEM_TABLE_PTR (runtime_services));
+  else
+    *((grub_uint64_t *) curval->data)
+      = PTR_TO_UINT64 (SYSTEM_TABLE_PTR (runtime_services));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_xnu_boot_resume (void)
+{
+  struct grub_relocator32_state state;
+
+  state.esp = grub_xnu_stack;
+  state.eip = grub_xnu_entry_point;
+  state.eax = grub_xnu_arg1;
+
+  return grub_relocator32_boot (grub_xnu_heap_start, grub_xnu_heap_will_be_at,
+                               state); 
+}
+
+/* Boot xnu. */
+grub_err_t
+grub_xnu_boot (void)
+{
+  struct grub_xnu_boot_params *bootparams_relloc;
+  grub_off_t bootparams_relloc_off;
+  grub_off_t mmap_relloc_off;
+  grub_err_t err;
+  grub_efi_uintn_t memory_map_size = 0;
+  grub_efi_memory_descriptor_t *memory_map;
+  grub_efi_uintn_t map_key = 0;
+  grub_efi_uintn_t descriptor_size = 0;
+  grub_efi_uint32_t descriptor_version = 0;
+  grub_uint64_t firstruntimepage, lastruntimepage;
+  grub_uint64_t curruntimepage;
+  void *devtree;
+  grub_size_t devtreelen;
+  int i;
+  struct grub_relocator32_state state;
+
+  err = grub_autoefi_prepare ();
+  if (err)
+    return err;
+
+  err = grub_cpu_xnu_fill_devprop ();
+  if (err)
+    return err;
+
+  err = grub_cpu_xnu_fill_devicetree ();
+  if (err)
+    return err;
+
+  err = grub_xnu_fill_devicetree ();
+  if (err)
+    return err;
+
+  /* Page-align to avoid following parts to be inadvertently freed. */
+  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
+  if (err)
+    return err;
+
+  /* Pass memory map to kernel. */
+  memory_map_size = 0;
+  memory_map = 0;
+  map_key = 0;
+  descriptor_size = 0;
+  descriptor_version = 0;
+
+  grub_dprintf ("xnu", "eip=%x\n", grub_xnu_entry_point);
+
+  const char *debug = grub_env_get ("debug");
+
+  if (debug && (grub_strword (debug, "all") || grub_strword (debug, "xnu")))
+    {
+      grub_printf ("Press any key to launch xnu\n");
+      grub_getkey ();
+    }
+
+  /* Relocate the boot parameters to heap. */
+  bootparams_relloc = grub_xnu_heap_malloc (sizeof (*bootparams_relloc));
+  if (! bootparams_relloc)
+    return grub_errno;
+  bootparams_relloc_off = (grub_uint8_t *) bootparams_relloc
+    - (grub_uint8_t *) grub_xnu_heap_start;
+
+  /* Set video. */
+  err = grub_xnu_set_video (bootparams_relloc);
+  if (err != GRUB_ERR_NONE)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      grub_printf ("Booting in blind mode\n");
+
+      bootparams_relloc->lfb_mode = 0;
+      bootparams_relloc->lfb_width = 0;
+      bootparams_relloc->lfb_height = 0;
+      bootparams_relloc->lfb_depth = 0;
+      bootparams_relloc->lfb_line_len = 0;
+      bootparams_relloc->lfb_base = 0;
+    }
+
+  if (grub_autoefi_get_memory_map (&memory_map_size, memory_map,
+                                  &map_key, &descriptor_size,
+                                  &descriptor_version) < 0)
+    return grub_errno;
+
+  /* We will do few allocations later. Reserve some space for possible
+     memory map growth.  */
+  memory_map_size += 20 * descriptor_size;
+  memory_map = grub_xnu_heap_malloc (memory_map_size);
+  if (! memory_map)
+    return grub_errno;
+  mmap_relloc_off = (grub_uint8_t *) memory_map
+    - (grub_uint8_t *) grub_xnu_heap_start;
+
+  err = grub_xnu_writetree_toheap (&devtree, &devtreelen);
+  if (err)
+    return err;
+  bootparams_relloc = (struct grub_xnu_boot_params *)
+    (bootparams_relloc_off + (grub_uint8_t *) grub_xnu_heap_start);
+
+  grub_memcpy (bootparams_relloc->cmdline, grub_xnu_cmdline,
+              sizeof (bootparams_relloc->cmdline));
+
+  bootparams_relloc->devtree
+    = ((grub_uint8_t *) devtree - (grub_uint8_t *) grub_xnu_heap_start)
+    + grub_xnu_heap_will_be_at;
+  bootparams_relloc->devtreelen = devtreelen;
+
+  memory_map = (grub_efi_memory_descriptor_t *)
+    ((grub_uint8_t *) grub_xnu_heap_start + mmap_relloc_off);
+
+  if (grub_autoefi_get_memory_map (&memory_map_size, memory_map,
+                                  &map_key, &descriptor_size,
+                                  &descriptor_version) <= 0)
+    return grub_errno;
+
+  bootparams_relloc->efi_system_table
+    = PTR_TO_UINT32 (grub_autoefi_system_table);
+
+  firstruntimepage = (((grub_addr_t) grub_xnu_heap_will_be_at
+                      + grub_xnu_heap_size + GRUB_XNU_PAGESIZE - 1)
+                     / GRUB_XNU_PAGESIZE) + 20;
+  curruntimepage = firstruntimepage;
+
+  for (i = 0; (unsigned) i < memory_map_size / descriptor_size; i++)
+    {
+      grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *)
+       ((char *) memory_map + descriptor_size * i);
+
+      curdesc->virtual_start = curdesc->physical_start;
+
+      if (curdesc->type == GRUB_EFI_RUNTIME_SERVICES_DATA
+         || curdesc->type == GRUB_EFI_RUNTIME_SERVICES_CODE)
+       {
+         curdesc->virtual_start = curruntimepage << 12;
+         curruntimepage += curdesc->num_pages;
+         if (curdesc->physical_start
+             <= PTR_TO_UINT64 (grub_autoefi_system_table)
+             && curdesc->physical_start + (curdesc->num_pages << 12)
+             > PTR_TO_UINT64 (grub_autoefi_system_table))
+           bootparams_relloc->efi_system_table
+             = PTR_TO_UINT64 (grub_autoefi_system_table)
+             - curdesc->physical_start + curdesc->virtual_start;
+         if (SIZEOF_OF_UINTN == 8 && grub_xnu_is_64bit)
+           curdesc->virtual_start |= 0xffffff8000000000ULL;
+       }
+    }
+
+  lastruntimepage = curruntimepage;
+
+  bootparams_relloc->efi_mmap = grub_xnu_heap_will_be_at + mmap_relloc_off;
+  bootparams_relloc->efi_mmap_size = memory_map_size;
+  bootparams_relloc->efi_mem_desc_size = descriptor_size;
+  bootparams_relloc->efi_mem_desc_version = descriptor_version;
+
+  bootparams_relloc->heap_start = grub_xnu_heap_will_be_at;
+  bootparams_relloc->heap_size = grub_xnu_heap_size;
+  bootparams_relloc->efi_runtime_first_page = firstruntimepage;
+
+  bootparams_relloc->efi_runtime_npages = lastruntimepage - firstruntimepage;
+  bootparams_relloc->efi_uintnbits = SIZEOF_OF_UINTN * 8;
+
+  bootparams_relloc->verminor = GRUB_XNU_BOOTARGS_VERMINOR;
+  bootparams_relloc->vermajor = GRUB_XNU_BOOTARGS_VERMAJOR;
+
+  /* Parameters for asm helper. */
+  grub_xnu_stack = bootparams_relloc->heap_start
+    + bootparams_relloc->heap_size + GRUB_XNU_PAGESIZE;
+  grub_xnu_arg1 = bootparams_relloc_off + grub_xnu_heap_will_be_at;
+
+  if (! grub_autoefi_exit_boot_services (map_key))
+    return grub_error (GRUB_ERR_IO, "can't exit boot services");
+
+  grub_autoefi_set_virtual_address_map (memory_map_size, descriptor_size,
+                                       descriptor_version,memory_map);
+
+  state.eip = grub_xnu_entry_point;
+  state.eax = grub_xnu_arg1;
+  state.esp = grub_xnu_stack;
+  return grub_relocator32_boot (grub_xnu_heap_start, grub_xnu_heap_will_be_at,
+                               state);
+}
+
+static grub_command_t cmd_devprop_load;
+
+void
+grub_cpu_xnu_init (void)
+{
+  cmd_devprop_load = grub_register_command ("xnu_devprop_load",
+                                           grub_cmd_devprop_load,
+                                           0, N_("Load device-properties dump."));
+}
+
+void
+grub_cpu_xnu_fini (void)
+{
+  grub_unregister_command (cmd_devprop_load);
+}
diff --git a/grub-core/loader/macho.c b/grub-core/loader/macho.c
new file mode 100644 (file)
index 0000000..199d6f1
--- /dev/null
@@ -0,0 +1,161 @@
+/* macho.c - load Mach-O files. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This Mach-O loader is incomplete and can load only non-relocatable segments.
+   This is however enough to boot xnu (otool -l and Mach-O specs for more info).
+*/
+
+#include <grub/err.h>
+#include <grub/macho.h>
+#include <grub/cpu/macho.h>
+#include <grub/machoload.h>
+#include <grub/file.h>
+#include <grub/gzio.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+grub_err_t
+grub_macho_close (grub_macho_t macho)
+{
+  grub_file_t file = macho->file;
+
+  grub_free (macho->cmds32);
+  grub_free (macho->cmds64);
+
+  grub_free (macho);
+
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+grub_macho_t
+grub_macho_file (grub_file_t file)
+{
+  grub_macho_t macho;
+  union grub_macho_filestart filestart;
+
+  macho = grub_malloc (sizeof (*macho));
+  if (! macho)
+    return 0;
+
+  macho->file = file;
+  macho->offset32 = -1;
+  macho->offset64 = -1;
+  macho->end32 = -1;
+  macho->end64 = -1;
+  macho->cmds32 = 0;
+  macho->cmds64 = 0;
+
+  if (grub_file_seek (macho->file, 0) == (grub_off_t) -1)
+    goto fail;
+
+  if (grub_file_read (macho->file, &filestart, sizeof (filestart))
+      != sizeof (filestart))
+    {
+      grub_error_push ();
+      grub_error (GRUB_ERR_READ_ERROR, "cannot read Mach-O header");
+      goto fail;
+    }
+
+  /* Is it a fat file? */
+  if (filestart.fat.magic == grub_be_to_cpu32 (GRUB_MACHO_FAT_MAGIC))
+    {
+      struct grub_macho_fat_arch *archs;
+      int i, narchs;
+
+      /* Load architecture description. */
+      narchs = grub_be_to_cpu32 (filestart.fat.nfat_arch);
+      if (grub_file_seek (macho->file, sizeof (struct grub_macho_fat_header))
+         == (grub_off_t) -1)
+       goto fail;
+      archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs);
+      if (!archs)
+       goto fail;
+      if (grub_file_read (macho->file, archs,
+                         sizeof (struct grub_macho_fat_arch) * narchs)
+         != (grub_ssize_t)sizeof(struct grub_macho_fat_arch) * narchs)
+       {
+         grub_free (archs);
+         grub_error_push ();
+         grub_error (GRUB_ERR_READ_ERROR, "cannot read Mach-O header");
+         goto fail;
+       }
+
+      for (i = 0; i < narchs; i++)
+       {
+         if (GRUB_MACHO_CPUTYPE_IS_HOST32
+             (grub_be_to_cpu32 (archs[i].cputype)))
+           {
+             macho->offset32 = grub_be_to_cpu32 (archs[i].offset);
+             macho->end32 = grub_be_to_cpu32 (archs[i].offset)
+               + grub_be_to_cpu32 (archs[i].size);
+           }
+         if (GRUB_MACHO_CPUTYPE_IS_HOST64
+             (grub_be_to_cpu32 (archs[i].cputype)))
+           {
+             macho->offset64 = grub_be_to_cpu32 (archs[i].offset);
+             macho->end64 = grub_be_to_cpu32 (archs[i].offset)
+               + grub_be_to_cpu32 (archs[i].size);
+           }
+       }
+      grub_free (archs);
+    }
+
+  /* Is it a thin 32-bit file? */
+  if (filestart.thin32.magic == GRUB_MACHO_MAGIC32)
+    {
+      macho->offset32 = 0;
+      macho->end32 = grub_file_size (file);
+    }
+
+  /* Is it a thin 64-bit file? */
+  if (filestart.thin64.magic == GRUB_MACHO_MAGIC64)
+    {
+      macho->offset64 = 0;
+      macho->end64 = grub_file_size (file);
+    }
+
+  grub_macho_parse32 (macho);
+  grub_macho_parse64 (macho);
+
+  return macho;
+
+fail:
+  grub_macho_close (macho);
+  return 0;
+}
+
+grub_macho_t
+grub_macho_open (const char *name)
+{
+  grub_file_t file;
+  grub_macho_t macho;
+
+  file = grub_gzfile_open (name, 1);
+  if (! file)
+    return 0;
+
+  macho = grub_macho_file (file);
+  if (! macho)
+    grub_file_close (file);
+
+  return macho;
+}
diff --git a/grub-core/loader/macho32.c b/grub-core/loader/macho32.c
new file mode 100644 (file)
index 0000000..0d740ed
--- /dev/null
@@ -0,0 +1,18 @@
+#include <grub/cpu/macho.h>
+#include <grub/machoload.h>
+
+#define SUFFIX(x) x ## 32
+typedef struct grub_macho_header32 grub_macho_header_t;
+typedef struct grub_macho_segment32 grub_macho_segment_t;
+typedef grub_uint32_t grub_macho_addr_t;
+typedef struct grub_macho_thread32 grub_macho_thread_t;
+#define offsetXX offset32
+#define ncmdsXX ncmds32
+#define cmdsizeXX cmdsize32
+#define cmdsXX cmds32
+#define endXX end32
+#define XX "32"
+#define GRUB_MACHO_MAGIC GRUB_MACHO_MAGIC32
+#define GRUB_MACHO_CMD_SEGMENT GRUB_MACHO_CMD_SEGMENT32
+#include "machoXX.c"
+
diff --git a/grub-core/loader/macho64.c b/grub-core/loader/macho64.c
new file mode 100644 (file)
index 0000000..17a8021
--- /dev/null
@@ -0,0 +1,18 @@
+#include <grub/cpu/macho.h>
+#include <grub/machoload.h>
+
+#define SUFFIX(x) x ## 64
+typedef struct grub_macho_header64 grub_macho_header_t;
+typedef struct grub_macho_segment64 grub_macho_segment_t;
+typedef grub_uint64_t grub_macho_addr_t;
+typedef struct grub_macho_thread64 grub_macho_thread_t;
+#define offsetXX offset64
+#define ncmdsXX ncmds64
+#define cmdsizeXX cmdsize64
+#define cmdsXX cmds64
+#define endXX end64
+#define XX "64"
+#define GRUB_MACHO_MAGIC GRUB_MACHO_MAGIC64
+#define GRUB_MACHO_CMD_SEGMENT GRUB_MACHO_CMD_SEGMENT64
+#include "machoXX.c"
+
diff --git a/grub-core/loader/machoXX.c b/grub-core/loader/machoXX.c
new file mode 100644 (file)
index 0000000..918ddbb
--- /dev/null
@@ -0,0 +1,239 @@
+
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+int
+SUFFIX (grub_macho_contains_macho) (grub_macho_t macho)
+{
+  return macho->offsetXX != -1;
+}
+
+void
+SUFFIX (grub_macho_parse) (grub_macho_t macho)
+{
+  grub_macho_header_t head;
+
+  /* Is there any candidate at all? */
+  if (macho->offsetXX == -1)
+    return;
+
+  /* Read header and check magic*/
+  if (grub_file_seek (macho->file, macho->offsetXX) == (grub_off_t) -1
+      || grub_file_read (macho->file, &head, sizeof (head))
+      != sizeof(head))
+    {
+      grub_error (GRUB_ERR_READ_ERROR, "cannot read Mach-O header");
+      macho->offsetXX = -1;
+      return;
+    }
+  if (head.magic != GRUB_MACHO_MAGIC)
+    {
+      grub_error (GRUB_ERR_BAD_OS, "invalid Mach-O " XX "-bit header");
+      macho->offsetXX = -1;
+      return;
+    }
+
+  /* Read commands. */
+  macho->ncmdsXX = head.ncmds;
+  macho->cmdsizeXX = head.sizeofcmds;
+  macho->cmdsXX = grub_malloc(macho->cmdsizeXX);
+  if (! macho->cmdsXX)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "not enough memory to read commands");
+      return;
+    }
+  if (grub_file_read (macho->file, macho->cmdsXX,
+                     (grub_size_t) macho->cmdsizeXX)
+      != (grub_ssize_t) macho->cmdsizeXX)
+    {
+      grub_error (GRUB_ERR_READ_ERROR, "cannot read Mach-O header");
+      macho->offsetXX = -1;
+    }
+}
+
+typedef int NESTED_FUNC_ATTR (*grub_macho_iter_hook_t)
+(grub_macho_t , struct grub_macho_cmd *,
+              void *);
+
+static grub_err_t
+grub_macho_cmds_iterate (grub_macho_t macho,
+                        grub_macho_iter_hook_t hook,
+                        void *hook_arg)
+{
+  grub_uint8_t *hdrs = macho->cmdsXX;
+  int i;
+  if (! macho->cmdsXX)
+    return grub_error (GRUB_ERR_BAD_OS, "couldn't find " XX "-bit Mach-O");
+  for (i = 0; i < macho->ncmdsXX; i++)
+    {
+      struct grub_macho_cmd *hdr = (struct grub_macho_cmd *) hdrs;
+      if (hook (macho, hdr, hook_arg))
+       break;
+      hdrs += hdr->cmdsize;
+    }
+
+  return grub_errno;
+}
+
+grub_size_t
+SUFFIX (grub_macho_filesize) (grub_macho_t macho)
+{
+  if (SUFFIX (grub_macho_contains_macho) (macho))
+    return macho->endXX - macho->offsetXX;
+  return 0;
+}
+
+grub_err_t
+SUFFIX (grub_macho_readfile) (grub_macho_t macho, void *dest)
+{
+  grub_ssize_t read;
+  if (! SUFFIX (grub_macho_contains_macho) (macho))
+    return grub_error (GRUB_ERR_BAD_OS,
+                      "couldn't read architecture-specific part");
+
+  if (grub_file_seek (macho->file, macho->offsetXX) == (grub_off_t) -1)
+    {
+      grub_error_push ();
+      return grub_error (GRUB_ERR_BAD_OS,
+                        "invalid offset in program header");
+    }
+
+  read = grub_file_read (macho->file, dest,
+                        macho->endXX - macho->offsetXX);
+  if (read != (grub_ssize_t) (macho->endXX - macho->offsetXX))
+    {
+      grub_error_push ();
+      return grub_error (GRUB_ERR_BAD_OS,
+                        "couldn't read architecture-specific part");
+    }
+  return GRUB_ERR_NONE;
+}
+
+/* Calculate the amount of memory spanned by the segments. */
+grub_err_t
+SUFFIX (grub_macho_size) (grub_macho_t macho, grub_macho_addr_t *segments_start,
+                         grub_macho_addr_t *segments_end, int flags)
+{
+  int nr_phdrs = 0;
+
+  /* Run through the program headers to calculate the total memory size we
+     should claim.  */
+  auto int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho,
+                                     struct grub_macho_cmd *phdr, void *_arg);
+  int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho __attribute__ ((unused)),
+                                struct grub_macho_cmd *hdr0,
+                                void *_arg __attribute__ ((unused)))
+    {
+      grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0;
+      if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT)
+       return 0;
+
+      if (! hdr->vmsize)
+       return 0;
+
+      if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS))
+       return 0;
+
+      nr_phdrs++;
+      if (hdr->vmaddr < *segments_start)
+       *segments_start = hdr->vmaddr;
+      if (hdr->vmaddr + hdr->vmsize > *segments_end)
+       *segments_end = hdr->vmaddr + hdr->vmsize;
+      return 0;
+    }
+
+  *segments_start = (grub_macho_addr_t) -1;
+  *segments_end = 0;
+
+  grub_macho_cmds_iterate (macho, calcsize, 0);
+
+  if (nr_phdrs == 0)
+    return grub_error (GRUB_ERR_BAD_OS, "no program headers present");
+
+  if (*segments_end < *segments_start)
+    /* Very bad addresses.  */
+    return grub_error (GRUB_ERR_BAD_OS, "bad program header load addresses");
+
+  return GRUB_ERR_NONE;
+}
+
+/* Load every loadable segment into memory specified by `_load_hook'.  */
+grub_err_t
+SUFFIX (grub_macho_load) (grub_macho_t macho, char *offset, int flags)
+{
+  grub_err_t err = 0;
+  auto int NESTED_FUNC_ATTR do_load(grub_macho_t _macho,
+                              struct grub_macho_cmd *hdr0,
+                              void *_arg __attribute__ ((unused)));
+  int NESTED_FUNC_ATTR do_load(grub_macho_t _macho,
+                              struct grub_macho_cmd *hdr0,
+                              void *_arg __attribute__ ((unused)))
+  {
+    grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0;
+
+    if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT)
+      return 0;
+
+    if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS))
+      return 0;
+    if (! hdr->vmsize)
+      return 0;
+
+    if (grub_file_seek (_macho->file, hdr->fileoff
+                       + _macho->offsetXX) == (grub_off_t) -1)
+      {
+       grub_error_push ();
+       grub_error (GRUB_ERR_BAD_OS,
+                   "invalid offset in program header");
+       return 1;
+      }
+
+    if (hdr->filesize)
+      {
+       grub_ssize_t read;
+       read = grub_file_read (_macho->file, offset + hdr->vmaddr,
+                                  min (hdr->filesize, hdr->vmsize));
+       if (read != (grub_ssize_t) min (hdr->filesize, hdr->vmsize))
+         {
+           /* XXX How can we free memory from `load_hook'? */
+           grub_error_push ();
+           err=grub_error (GRUB_ERR_BAD_OS,
+                           "couldn't read segment from file: "
+                           "wanted 0x%lx bytes; read 0x%lx bytes",
+                           hdr->filesize, read);
+           return 1;
+         }
+      }
+
+    if (hdr->filesize < hdr->vmsize)
+      grub_memset (offset + hdr->vmaddr + hdr->filesize,
+                  0, hdr->vmsize - hdr->filesize);
+    return 0;
+  }
+
+  grub_macho_cmds_iterate (macho, do_load, 0);
+
+  return err;
+}
+
+grub_macho_addr_t
+SUFFIX (grub_macho_get_entry_point) (grub_macho_t macho)
+{
+  grub_macho_addr_t entry_point = 0;
+  auto int NESTED_FUNC_ATTR hook(grub_macho_t _macho,
+                                struct grub_macho_cmd *hdr,
+                                void *_arg __attribute__ ((unused)));
+  int NESTED_FUNC_ATTR hook(grub_macho_t _macho __attribute__ ((unused)),
+                           struct grub_macho_cmd *hdr,
+                           void *_arg __attribute__ ((unused)))
+  {
+    if (hdr->cmd == GRUB_MACHO_CMD_THREAD)
+      entry_point = ((grub_macho_thread_t *) hdr)->entry_point;
+    return 0;
+  }
+  grub_macho_cmds_iterate (macho, hook, 0);
+  return entry_point;
+}
diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c
new file mode 100644 (file)
index 0000000..64497f4
--- /dev/null
@@ -0,0 +1,398 @@
+/* linux.c - boot Linux */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/elf.h>
+#include <grub/elfload.h>
+#include <grub/loader.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/machine/loader.h>
+#include <grub/command.h>
+#include <grub/mips/relocator.h>
+#include <grub/machine/memory.h>
+#include <grub/i18n.h>
+
+/* For frequencies.  */
+#include <grub/pci.h>
+#include <grub/machine/time.h>
+
+#define ELF32_LOADMASK (0x00000000UL)
+#define ELF64_LOADMASK (0x0000000000000000ULL)
+
+static grub_dl_t my_mod;
+
+static int loaded;
+
+static grub_size_t linux_size;
+
+static grub_uint8_t *playground;
+static grub_addr_t target_addr, entry_addr;
+static int linux_argc;
+static grub_off_t argv_off, envp_off;
+static grub_off_t rd_addr_arg_off, rd_size_arg_off;
+static int initrd_loaded = 0;
+
+static grub_err_t
+grub_linux_boot (void)
+{
+  struct grub_relocator32_state state;
+
+  /* Boot the kernel.  */
+  state.gpr[1] = entry_addr;
+  state.gpr[4] = linux_argc;
+  state.gpr[5] = target_addr + argv_off;
+  state.gpr[6] = target_addr + envp_off;
+  state.jumpreg = 1;
+  grub_relocator32_boot (playground, target_addr, state);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_release_mem (void)
+{
+  grub_relocator32_free (playground);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  grub_err_t err;
+
+  err = grub_linux_release_mem ();
+  grub_dl_unref (my_mod);
+
+  loaded = 0;
+
+  return err;
+}
+
+static grub_err_t
+grub_linux_load32 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size)
+{
+  Elf32_Addr base;
+  int extraoff;
+
+  /* Linux's entry point incorrectly contains a virtual address.  */
+  entry_addr = elf->ehdr.ehdr32.e_entry & ~ELF32_LOADMASK;
+
+  linux_size = grub_elf32_size (elf, &base);
+  if (linux_size == 0)
+    return grub_errno;
+  target_addr = base;
+  /* Pad it; the kernel scribbles over memory beyond its load address.  */
+  linux_size += 0x100000;
+  linux_size = ALIGN_UP (base + linux_size, 4) - base;
+  extraoff = linux_size;
+  linux_size += extra_size;
+
+  playground = grub_relocator32_alloc (linux_size);
+  if (!playground)
+    return grub_errno;
+
+  *extra_mem = playground + extraoff;
+
+  /* Now load the segments into the area we claimed.  */
+  auto grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load);
+  grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load)
+    {
+      if (phdr->p_type != PT_LOAD)
+       {
+         *do_load = 0;
+         return 0;
+       }
+      *do_load = 1;
+
+      /* Linux's program headers incorrectly contain virtual addresses.
+       * Translate those to physical, and offset to the area we claimed.  */
+      *addr = (grub_addr_t) (phdr->p_paddr - base + playground);
+      return 0;
+    }
+  return grub_elf32_load (elf, offset_phdr, 0, 0);
+}
+
+static grub_err_t
+grub_linux_load64 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size)
+{
+  Elf64_Addr base;
+  int extraoff;
+
+  /* Linux's entry point incorrectly contains a virtual address.  */
+  entry_addr = elf->ehdr.ehdr64.e_entry & ~ELF64_LOADMASK;
+
+  linux_size = grub_elf64_size (elf, &base);
+  if (linux_size == 0)
+    return grub_errno;
+  target_addr = base;
+  /* Pad it; the kernel scribbles over memory beyond its load address.  */
+  linux_size += 0x100000;
+  linux_size = ALIGN_UP (base + linux_size, 4) - base;
+  extraoff = linux_size;
+  linux_size += extra_size;
+
+  playground = grub_relocator32_alloc (linux_size);
+  if (!playground)
+    return grub_errno;
+
+  *extra_mem = playground + extraoff;
+
+  /* Now load the segments into the area we claimed.  */
+  auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load);
+  grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load)
+    {
+      if (phdr->p_type != PT_LOAD)
+       {
+         *do_load = 0;
+         return 0;
+       }
+      *do_load = 1;
+      /* Linux's program headers incorrectly contain virtual addresses.
+       * Translate those to physical, and offset to the area we claimed.  */
+      *addr = (grub_addr_t) (phdr->p_paddr - base + playground);
+      return 0;
+    }
+  return grub_elf64_load (elf, offset_phdr, 0, 0);
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+               int argc, char *argv[])
+{
+  grub_elf_t elf = 0;
+  int i;
+  int size;
+  void *extra = NULL;
+  grub_uint32_t *linux_argv, *linux_envp;
+  char *linux_args, *linux_envs;
+  grub_err_t err;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
+
+  elf = grub_elf_open (argv[0]);
+  if (! elf)
+    return grub_errno;
+
+  if (elf->ehdr.ehdr32.e_type != ET_EXEC)
+    {
+      grub_elf_close (elf);
+      return grub_error (GRUB_ERR_UNKNOWN_OS,
+                        "this ELF file is not of the right type\n");
+    }
+
+  /* Release the previously used memory.  */
+  grub_loader_unset ();
+  loaded = 0;
+
+  /* For arguments.  */
+  linux_argc = argc;
+  /* Main arguments.  */
+  size = (linux_argc) * sizeof (grub_uint32_t); 
+  /* Initrd address and size.  */
+  size += 2 * sizeof (grub_uint32_t); 
+  /* NULL terminator.  */
+  size += sizeof (grub_uint32_t); 
+
+  /* First argument is always "a0".  */
+  size += ALIGN_UP (sizeof ("a0"), 4);
+  /* Normal arguments.  */
+  for (i = 1; i < argc; i++)
+    size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4);
+  
+  /* rd arguments.  */
+  size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4);
+  size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4);
+
+  /* For the environment.  */
+  size += sizeof (grub_uint32_t);
+  size += 4 * sizeof (grub_uint32_t);
+  size += ALIGN_UP (sizeof ("memsize=XXXXXXXXXXXXXXXXXXXX"), 4)
+    + ALIGN_UP (sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"), 4)
+    + ALIGN_UP (sizeof ("busclock=XXXXXXXXXX"), 4)
+    + ALIGN_UP (sizeof ("cpuclock=XXXXXXXXXX"), 4);
+
+  if (grub_elf_is_elf32 (elf))
+    err = grub_linux_load32 (elf, &extra, size);
+  else
+  if (grub_elf_is_elf64 (elf))
+    err = grub_linux_load64 (elf, &extra, size);
+  else
+    err = grub_error (GRUB_ERR_BAD_FILE_TYPE, "unknown ELF class");
+
+  grub_elf_close (elf);
+
+  if (err)
+    return err;
+
+  linux_argv = extra;
+  argv_off = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground;
+  extra = linux_argv + (linux_argc + 1 + 2);
+  linux_args = extra;
+
+  grub_memcpy (linux_args, "a0", sizeof ("a0"));
+  *linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground
+    + target_addr;
+  linux_argv++;
+  linux_args += ALIGN_UP (sizeof ("a0"), 4);
+
+  for (i = 1; i < argc; i++)
+    {
+      grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1);
+      *linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground
+       + target_addr;
+      linux_argv++;
+      linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4);
+    }
+
+  /* Reserve space for rd arguments.  */
+  rd_addr_arg_off = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground;
+  linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4);
+  *linux_argv = 0;
+  linux_argv++;
+
+  rd_size_arg_off = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground;
+  linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4);
+  *linux_argv = 0;
+  linux_argv++;
+
+  *linux_argv = 0;
+
+  extra = linux_args;
+
+  linux_envp = extra;
+  envp_off = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground;
+  linux_envs = (char *) (linux_envp + 5);
+  grub_snprintf (linux_envs, sizeof ("memsize=XXXXXXXXXXXXXXXXXXXX"),
+                "memsize=%lld",
+                (unsigned long long) grub_mmap_get_lower () >> 20);
+  linux_envp[0] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
+    + target_addr;
+  linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
+  grub_snprintf (linux_envs, sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"),
+                "highmemsize=%lld",
+                (unsigned long long) grub_mmap_get_upper () >> 20);
+  linux_envp[1] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
+    + target_addr;
+  linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
+
+  grub_snprintf (linux_envs, sizeof ("busclock=XXXXXXXXXX"),
+                "busclock=%d", grub_arch_busclock);
+  linux_envp[2] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
+    + target_addr;
+  linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
+  grub_snprintf (linux_envs, sizeof ("cpuclock=XXXXXXXXXX"),
+                "cpuclock=%d", grub_arch_cpuclock);
+  linux_envp[3] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
+    + target_addr;
+  linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
+
+
+  linux_envp[4] = 0;
+
+  grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
+  initrd_loaded = 0;
+  loaded = 1;
+  grub_dl_ref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+                int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  grub_size_t overhead;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified");
+
+  if (!loaded)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load Linux first.");
+
+  if (initrd_loaded)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "only one initrd can be loaded.");
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    return grub_errno;
+
+  size = grub_file_size (file);
+
+  overhead = ALIGN_UP (target_addr + linux_size + 0x10000, 0x10000)
+    - (target_addr + linux_size);
+
+  playground = grub_relocator32_realloc (playground,
+                                        linux_size + overhead + size);
+
+  if (!playground)
+    {
+      grub_file_close (file);
+      return grub_errno;
+    }
+
+  if (grub_file_read (file, playground + linux_size + overhead, size) != size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+      grub_file_close (file);
+
+      return grub_errno;
+    }
+
+  grub_snprintf ((char *) playground + rd_addr_arg_off,
+                sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), "rd_start=0x%llx",
+               (unsigned long long) target_addr + linux_size  + overhead);
+  ((grub_uint32_t *) (playground + argv_off))[linux_argc]
+    = target_addr + rd_addr_arg_off;
+  linux_argc++;
+
+  grub_snprintf ((char *) playground + rd_size_arg_off,
+               sizeof ("rd_size=0xXXXXXXXXXXXXXXXXX"), "rd_size=0x%llx",
+               (unsigned long long) size);
+  ((grub_uint32_t *) (playground + argv_off))[linux_argc]
+    = target_addr + rd_size_arg_off;
+  linux_argc++;
+
+  initrd_loaded = 1;
+
+  grub_file_close (file);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+\f
+GRUB_MOD_INIT(linux)
+{
+  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
+                                    0, N_("Load Linux."));
+  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
+                                     0, N_("Load initrd."));
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux)
+{
+  grub_unregister_command (cmd_linux);
+  grub_unregister_command (cmd_initrd);
+}
diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c
new file mode 100644 (file)
index 0000000..592289c
--- /dev/null
@@ -0,0 +1,356 @@
+/* multiboot.c - boot a multiboot OS image. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ *  FIXME: The following features from the Multiboot specification still
+ *         need to be implemented:
+ *  - VBE support
+ *  - symbol table
+ *  - drives table
+ *  - ROM configuration table
+ *  - APM table
+ */
+
+#include <grub/loader.h>
+#include <grub/command.h>
+#include <grub/machine/loader.h>
+#include <grub/multiboot.h>
+#include <grub/cpu/multiboot.h>
+#include <grub/elf.h>
+#include <grub/aout.h>
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/gzio.h>
+#include <grub/env.h>
+#include <grub/cpu/relocator.h>
+#include <grub/video.h>
+#include <grub/memory.h>
+#include <grub/i18n.h>
+
+#ifdef GRUB_MACHINE_EFI
+#include <grub/efi/efi.h>
+#endif
+
+#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
+#define DEFAULT_VIDEO_MODE "text"
+#else
+#define DEFAULT_VIDEO_MODE "auto"
+#endif
+
+grub_size_t grub_multiboot_alloc_mbi;
+
+char *grub_multiboot_payload_orig;
+grub_addr_t grub_multiboot_payload_dest;
+grub_size_t grub_multiboot_pure_size;
+grub_uint32_t grub_multiboot_payload_eip;
+static int accepts_video;
+static int accepts_ega_text;
+static int console_required;
+static grub_dl_t my_mod;
+
+
+/* Return the length of the Multiboot mmap that will be needed to allocate
+   our platform's map.  */
+grub_uint32_t
+grub_get_multiboot_mmap_count (void)
+{
+  grub_size_t count = 0;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
+                            grub_uint64_t size __attribute__ ((unused)),
+                            grub_uint32_t type __attribute__ ((unused)))
+    {
+      count++;
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+
+  return count;
+}
+
+grub_err_t
+grub_multiboot_set_video_mode (void)
+{
+  grub_err_t err;
+  const char *modevar;
+
+  if (accepts_video || !GRUB_MACHINE_HAS_VGA_TEXT)
+    {
+      modevar = grub_env_get ("gfxpayload");
+      if (! modevar || *modevar == 0)
+       err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0);
+      else
+       {
+         char *tmp;
+         tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
+         if (! tmp)
+           return grub_errno;
+         err = grub_video_set_mode (tmp, 0, 0);
+         grub_free (tmp);
+       }
+    }
+  else
+    err = grub_video_set_mode ("text", 0, 0);
+
+  return err;
+}
+
+static grub_err_t
+grub_multiboot_boot (void)
+{
+  grub_size_t mbi_size;
+  grub_err_t err;
+  struct grub_relocator32_state state = MULTIBOOT_INITIAL_STATE;
+
+  state.MULTIBOOT_ENTRY_REGISTER = grub_multiboot_payload_eip;
+
+  mbi_size = grub_multiboot_get_mbi_size ();
+  if (grub_multiboot_alloc_mbi < mbi_size)
+    {
+      grub_multiboot_payload_orig
+       = grub_relocator32_realloc (grub_multiboot_payload_orig,
+                                   grub_multiboot_pure_size + mbi_size);
+      if (!grub_multiboot_payload_orig)
+       return grub_errno;
+      grub_multiboot_alloc_mbi = mbi_size;
+    }
+
+  state.MULTIBOOT_MBI_REGISTER = grub_multiboot_payload_dest
+    + grub_multiboot_pure_size;
+  err = grub_multiboot_make_mbi (grub_multiboot_payload_orig,
+                                grub_multiboot_payload_dest,
+                                grub_multiboot_pure_size, mbi_size);
+  if (err)
+    return err;
+
+#ifdef GRUB_MACHINE_EFI
+  if (! grub_efi_finish_boot_services ())
+     grub_fatal ("cannot exit boot services");
+#endif
+
+  grub_relocator32_boot (grub_multiboot_payload_orig,
+                        grub_multiboot_payload_dest,
+                        state);
+
+  /* Not reached.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_multiboot_unload (void)
+{
+  grub_multiboot_free_mbi ();
+
+  grub_relocator32_free (grub_multiboot_payload_orig);
+
+  grub_multiboot_alloc_mbi = 0;
+
+  grub_multiboot_payload_orig = NULL;
+  grub_dl_unref (my_mod);
+
+  return GRUB_ERR_NONE;
+}
+
+#define MULTIBOOT_LOAD_ELF64
+#include "multiboot_elfxx.c"
+#undef MULTIBOOT_LOAD_ELF64
+
+#define MULTIBOOT_LOAD_ELF32
+#include "multiboot_elfxx.c"
+#undef MULTIBOOT_LOAD_ELF32
+
+/* Load ELF32 or ELF64.  */
+grub_err_t
+grub_multiboot_load_elf (grub_file_t file, void *buffer)
+{
+  if (grub_multiboot_is_elf32 (buffer))
+    return grub_multiboot_load_elf32 (file, buffer);
+  else if (grub_multiboot_is_elf64 (buffer))
+    return grub_multiboot_load_elf64 (file, buffer);
+
+  return grub_error (GRUB_ERR_UNKNOWN_OS, "unknown ELF class");
+}
+
+grub_err_t
+grub_multiboot_set_console (int console_type, int accepted_consoles,
+                           int width, int height, int depth,
+                           int console_req)
+{
+  console_required = console_req;
+  if (!(accepted_consoles 
+       & (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER
+          | (GRUB_MACHINE_HAS_VGA_TEXT ? GRUB_MULTIBOOT_CONSOLE_EGA_TEXT : 0))))
+    {
+      if (console_required)
+       return grub_error (GRUB_ERR_BAD_OS,
+                          "OS requires a console but none is available");
+      grub_printf ("WARNING: no console will be available to OS");
+      accepts_video = 0;
+      accepts_ega_text = 0;
+      return GRUB_ERR_NONE;
+    }
+
+  if (console_type == GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER)
+    {
+      char *buf;
+      if (depth && width && height)
+       buf = grub_xasprintf ("%dx%dx%d,%dx%d,auto", width,
+                             height, depth, width, height);
+      else if (width && height)
+       buf = grub_xasprintf ("%dx%d,auto", width, height);
+      else
+       buf = grub_strdup ("auto");
+
+      if (!buf)
+       return grub_errno;
+      grub_env_set ("gfxpayload", buf);
+      grub_free (buf);
+    }
+ else
+   grub_env_set ("gfxpayload", "text");
+
+  accepts_video = !!(accepted_consoles & GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER);
+  accepts_ega_text = !!(accepted_consoles & GRUB_MULTIBOOT_CONSOLE_EGA_TEXT);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_multiboot (grub_command_t cmd __attribute__ ((unused)),
+                   int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_err_t err;
+
+  grub_loader_unset ();
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (! file)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file");
+
+  grub_dl_ref (my_mod);
+
+  /* Skip filename.  */
+  grub_multiboot_init_mbi (argc - 1, argv + 1);
+
+  grub_relocator32_free (grub_multiboot_payload_orig);
+  grub_multiboot_payload_orig = NULL;
+
+  err = grub_multiboot_load (file);
+  if (err)
+    goto fail;
+
+  grub_multiboot_set_bootdev ();
+
+  grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0);
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_relocator32_free (grub_multiboot_payload_orig);
+      grub_multiboot_free_mbi ();
+      grub_dl_unref (my_mod);
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
+                int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  char *module = 0;
+  grub_err_t err;
+
+  if (argc == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
+
+  if (!grub_multiboot_payload_orig)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "you need to load the multiboot kernel first");
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (! file)
+    return grub_errno;
+
+  size = grub_file_size (file);
+  module = grub_memalign (MULTIBOOT_MOD_ALIGN, size);
+  if (! module)
+    {
+      grub_file_close (file);
+      return grub_errno;
+    }
+
+  err = grub_multiboot_add_module ((grub_addr_t) module, size,
+                                  argc - 1, argv + 1);
+  if (err)
+    {
+      grub_file_close (file);
+      return err;
+    }
+
+  if (grub_file_read (file, module, size) != size)
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+    }
+
+  grub_file_close (file);
+  return GRUB_ERR_NONE;;
+}
+
+static grub_command_t cmd_multiboot, cmd_module;
+
+GRUB_MOD_INIT(multiboot)
+{
+  cmd_multiboot =
+#ifdef GRUB_USE_MULTIBOOT2
+    grub_register_command ("multiboot2", grub_cmd_multiboot,
+                          0, N_("Load a multiboot 2 kernel."));
+  cmd_module =
+    grub_register_command ("module2", grub_cmd_module,
+                          0, N_("Load a multiboot 2 module."));
+#else
+    grub_register_command ("multiboot", grub_cmd_multiboot,
+                          0, N_("Load a multiboot kernel."));
+  cmd_module =
+    grub_register_command ("module", grub_cmd_module,
+                          0, N_("Load a multiboot module."));
+#endif
+
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(multiboot)
+{
+  grub_unregister_command (cmd_multiboot);
+  grub_unregister_command (cmd_module);
+}
diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c
new file mode 100644 (file)
index 0000000..92a52d3
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if defined(MULTIBOOT_LOAD_ELF32)
+# define XX            32
+# define E_MACHINE     MULTIBOOT_ELF32_MACHINE
+# define ELFCLASSXX    ELFCLASS32
+# define Elf_Ehdr      Elf32_Ehdr
+# define Elf_Phdr      Elf32_Phdr
+#elif defined(MULTIBOOT_LOAD_ELF64)
+# define XX            64
+# define E_MACHINE     MULTIBOOT_ELF64_MACHINE
+# define ELFCLASSXX    ELFCLASS64
+# define Elf_Ehdr      Elf64_Ehdr
+# define Elf_Phdr      Elf64_Phdr
+#else
+#error "I'm confused"
+#endif
+
+#include <grub/i386/relocator.h>
+
+#define CONCAT(a,b)    CONCAT_(a, b)
+#define CONCAT_(a,b)   a ## b
+
+/* Check if BUFFER contains ELF32 (or ELF64).  */
+static int
+CONCAT(grub_multiboot_is_elf, XX) (void *buffer)
+{
+  Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer;
+
+  return ehdr->e_ident[EI_CLASS] == ELFCLASSXX;
+}
+
+static grub_err_t
+CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
+{
+  Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer;
+  char *phdr_base;
+  int lowest_segment = -1, highest_segment = -1;
+  int i;
+  grub_size_t code_size;
+
+  if (ehdr->e_ident[EI_CLASS] != ELFCLASSXX)
+    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class");
+
+  if (ehdr->e_ident[EI_MAG0] != ELFMAG0
+      || ehdr->e_ident[EI_MAG1] != ELFMAG1
+      || ehdr->e_ident[EI_MAG2] != ELFMAG2
+      || ehdr->e_ident[EI_MAG3] != ELFMAG3
+      || ehdr->e_version != EV_CURRENT
+      || ehdr->e_ident[EI_DATA] != ELFDATA2LSB
+      || ehdr->e_machine != E_MACHINE)
+    return grub_error(GRUB_ERR_UNKNOWN_OS, "no valid ELF header found");
+
+  if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
+    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type");
+
+  /* FIXME: Should we support program headers at strange locations?  */
+  if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
+    return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
+
+#ifdef MULTIBOOT_LOAD_ELF64
+  /* We still in 32-bit mode.  */
+  if (ehdr->e_entry > 0xffffffff)
+    return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64");
+#endif
+
+  phdr_base = (char *) buffer + ehdr->e_phoff;
+#define phdr(i)                        ((Elf_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
+
+  for (i = 0; i < ehdr->e_phnum; i++)
+    if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0)
+      {
+       /* Beware that segment 0 isn't necessarily loadable */
+       if (lowest_segment == -1
+           || phdr(i)->p_paddr < phdr(lowest_segment)->p_paddr)
+         lowest_segment = i;
+       if (highest_segment == -1
+           || phdr(i)->p_paddr > phdr(highest_segment)->p_paddr)
+         highest_segment = i;
+      }
+
+  if (lowest_segment == -1)
+    return grub_error (GRUB_ERR_BAD_OS, "ELF contains no loadable segments");
+
+  code_size = (phdr(highest_segment)->p_paddr + phdr(highest_segment)->p_memsz) - phdr(lowest_segment)->p_paddr;
+  grub_multiboot_payload_dest = phdr(lowest_segment)->p_paddr;
+
+  grub_multiboot_pure_size += code_size;
+
+  grub_multiboot_alloc_mbi = grub_multiboot_get_mbi_size () + 65536;
+  grub_multiboot_payload_orig
+    = grub_relocator32_alloc (grub_multiboot_pure_size + grub_multiboot_alloc_mbi);
+
+  if (!grub_multiboot_payload_orig)
+    return grub_errno;
+
+  /* Load every loadable segment in memory.  */
+  for (i = 0; i < ehdr->e_phnum; i++)
+    {
+      if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0)
+        {
+         char *load_this_module_at = (char *) (grub_multiboot_payload_orig + (long) (phdr(i)->p_paddr - phdr(lowest_segment)->p_paddr));
+
+         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);
+
+         if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
+             == (grub_off_t) -1)
+           return grub_error (GRUB_ERR_BAD_OS,
+                              "invalid offset in program header");
+
+          if (grub_file_read (file, load_this_module_at, phdr(i)->p_filesz)
+              != (grub_ssize_t) phdr(i)->p_filesz)
+           return grub_error (GRUB_ERR_BAD_OS,
+                              "couldn't read segment from file");
+
+          if (phdr(i)->p_filesz < phdr(i)->p_memsz)
+            grub_memset (load_this_module_at + phdr(i)->p_filesz, 0,
+                        phdr(i)->p_memsz - phdr(i)->p_filesz);
+        }
+    }
+
+  for (i = 0; i < ehdr->e_phnum; i++)
+    if (phdr(i)->p_vaddr <= ehdr->e_entry
+       && phdr(i)->p_vaddr + phdr(i)->p_memsz > ehdr->e_entry)
+      {
+       grub_multiboot_payload_eip = grub_multiboot_payload_dest
+         + (ehdr->e_entry - phdr(i)->p_vaddr) + (phdr(i)->p_paddr  - phdr(lowest_segment)->p_paddr);
+       break;
+      }
+
+  if (i == ehdr->e_phnum)
+    return grub_error (GRUB_ERR_BAD_OS, "entry point isn't in a segment");
+
+#undef phdr
+
+  return grub_errno;
+}
+
+#undef XX
+#undef E_MACHINE
+#undef ELFCLASSXX
+#undef Elf_Ehdr
+#undef Elf_Phdr
diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
new file mode 100644 (file)
index 0000000..7e9cebe
--- /dev/null
@@ -0,0 +1,701 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/memory.h>
+#ifdef GRUB_MACHINE_PCBIOS
+#include <grub/machine/biosnum.h>
+#endif
+#include <grub/multiboot.h>
+#include <grub/cpu/multiboot.h>
+#include <grub/cpu/relocator.h>
+#include <grub/disk.h>
+#include <grub/device.h>
+#include <grub/partition.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/video.h>
+
+#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU)
+#include <grub/i386/pc/vbe.h>
+#define HAS_VGA_TEXT 1
+#else
+#define HAS_VGA_TEXT 0
+#endif
+
+struct module
+{
+  struct module *next;
+  grub_addr_t start;
+  grub_size_t size;
+  char *cmdline;
+  int cmdline_size;
+};
+
+struct module *modules, *modules_last;
+static grub_size_t cmdline_size;
+static grub_size_t total_modcmd;
+static unsigned modcnt;
+static char *cmdline = NULL;
+static int bootdev_set;
+static grub_uint32_t biosdev, slice, part;
+
+grub_err_t
+grub_multiboot_load (grub_file_t file)
+{
+  char *buffer;
+  grub_ssize_t len;
+  struct multiboot_header *header;
+  grub_err_t err;
+  struct multiboot_header_tag *tag;
+  struct multiboot_header_tag_address *addr_tag = NULL;
+  int entry_specified = 0;
+  grub_addr_t entry = 0;
+  grub_uint32_t console_required = 0;
+  struct multiboot_header_tag_framebuffer *fbtag = NULL;
+  int accepted_consoles = GRUB_MULTIBOOT_CONSOLE_EGA_TEXT;
+
+  buffer = grub_malloc (MULTIBOOT_SEARCH);
+  if (!buffer)
+    return grub_errno;
+
+  len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
+  if (len < 32)
+    {
+      grub_free (buffer);
+      return grub_error (GRUB_ERR_BAD_OS, "file too small");
+    }
+
+  /* Look for the multiboot header in the buffer.  The header should
+     be at least 12 bytes and aligned on a 4-byte boundary.  */
+  for (header = (struct multiboot_header *) buffer;
+       ((char *) header <= buffer + len - 12) || (header = 0);
+       header = (struct multiboot_header *) ((char *) header + MULTIBOOT_HEADER_ALIGN))
+    {
+      if (header->magic == MULTIBOOT_HEADER_MAGIC
+         && !(header->magic + header->architecture
+              + header->header_length + header->checksum)
+         && header->architecture == MULTIBOOT_ARCHITECTURE_CURRENT)
+       break;
+    }
+
+  if (header == 0)
+    {
+      grub_free (buffer);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found");
+    }
+
+  for (tag = (struct multiboot_header_tag *) (header + 1);
+       tag->type != MULTIBOOT_TAG_TYPE_END;
+       tag = (struct multiboot_header_tag *) ((char *) tag + tag->size))
+    switch (tag->type)
+      {
+      case MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST:
+       {
+         unsigned i;
+         struct multiboot_header_tag_information_request *request_tag
+           = (struct multiboot_header_tag_information_request *) tag;
+         if (request_tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL)
+           break;
+         for (i = 0; i < (request_tag->size - sizeof (request_tag))
+                / sizeof (request_tag->requests[0]); i++)
+           switch (request_tag->requests[i])
+             {
+             case MULTIBOOT_TAG_TYPE_END:
+             case MULTIBOOT_TAG_TYPE_CMDLINE:
+             case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
+             case MULTIBOOT_TAG_TYPE_MODULE:
+             case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
+             case MULTIBOOT_TAG_TYPE_BOOTDEV:
+             case MULTIBOOT_TAG_TYPE_MMAP:
+             case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
+               break;
+
+             case MULTIBOOT_TAG_TYPE_VBE:
+             case MULTIBOOT_TAG_TYPE_ELF_SECTIONS:
+             case MULTIBOOT_TAG_TYPE_APM:
+             default:
+               grub_free (buffer);
+               return grub_error (GRUB_ERR_UNKNOWN_OS,
+                                  "unsupported information tag: 0x%x",
+                                  request_tag->requests[i]);
+             }
+         break;
+       }
+              
+      case MULTIBOOT_HEADER_TAG_ADDRESS:
+       addr_tag = (struct multiboot_header_tag_address *) tag;
+       break;
+
+      case MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS:
+       entry_specified = 1;
+       entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr;
+       break;
+
+      case MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS:
+       if (!(((struct multiboot_header_tag_console_flags *) tag)->console_flags
+           & MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED))
+         accepted_consoles &= ~GRUB_MULTIBOOT_CONSOLE_EGA_TEXT;
+       if (((struct multiboot_header_tag_console_flags *) tag)->console_flags
+           & MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED)
+         console_required = 1;
+       break;
+
+      case MULTIBOOT_HEADER_TAG_FRAMEBUFFER:
+       fbtag = (struct multiboot_header_tag_framebuffer *) tag;
+       accepted_consoles |= GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER;
+       break;
+
+       /* GRUB always page-aligns modules.  */
+      case MULTIBOOT_HEADER_TAG_MODULE_ALIGN:
+       break;
+
+      default:
+       if (! (tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL))
+         {
+           grub_free (buffer);
+           return grub_error (GRUB_ERR_UNKNOWN_OS,
+                              "unsupported tag: 0x%x", tag->type);
+         }
+       break;
+      }
+
+  if (addr_tag && !entry_specified)
+    {
+      grub_free (buffer);
+      return grub_error (GRUB_ERR_UNKNOWN_OS,
+                        "load address tag without entry address tag");
+    }
+  if (addr_tag)
+    {
+      int offset = ((char *) header - buffer -
+                   (addr_tag->header_addr - addr_tag->load_addr));
+      int load_size = ((addr_tag->load_end_addr == 0) ? file->size - offset :
+                      addr_tag->load_end_addr - addr_tag->load_addr);
+      grub_size_t code_size;
+
+      if (addr_tag->bss_end_addr)
+       code_size = (addr_tag->bss_end_addr - addr_tag->load_addr);
+      else
+       code_size = load_size;
+      grub_multiboot_payload_dest = addr_tag->load_addr;
+
+      grub_multiboot_pure_size += code_size;
+
+      /* Allocate a bit more to avoid relocations in most cases.  */
+      grub_multiboot_alloc_mbi = grub_multiboot_get_mbi_size () + 65536;
+      grub_multiboot_payload_orig
+       = grub_relocator32_alloc (grub_multiboot_pure_size + grub_multiboot_alloc_mbi);
+
+      if (! grub_multiboot_payload_orig)
+       {
+         grub_free (buffer);
+         return grub_errno;
+       }
+
+      if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
+       {
+         grub_free (buffer);
+         return grub_errno;
+       }
+
+      grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size);
+      if (grub_errno)
+       {
+         grub_free (buffer);
+         return grub_errno;
+       }
+
+      if (addr_tag->bss_end_addr)
+       grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0,
+                    addr_tag->bss_end_addr - addr_tag->load_addr - load_size);
+    }
+  else
+    {
+      err = grub_multiboot_load_elf (file, buffer);
+      if (err)
+       {
+         grub_free (buffer);
+         return err;
+       }
+    }
+
+  if (entry_specified)
+    grub_multiboot_payload_eip = entry;
+
+  if (fbtag)
+    err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
+                                     accepted_consoles,
+                                     fbtag->width, fbtag->height,
+                                     fbtag->depth, console_required);
+  else
+    err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT,
+                                     accepted_consoles,
+                                     0, 0, 0, console_required);
+  return err;
+}
+
+grub_size_t
+grub_multiboot_get_mbi_size (void)
+{
+  return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
+    + (sizeof (struct multiboot_tag_string)
+       + ALIGN_UP (cmdline_size, MULTIBOOT_TAG_ALIGN))
+    + (sizeof (struct multiboot_tag_string)
+       + ALIGN_UP (sizeof (PACKAGE_STRING), MULTIBOOT_TAG_ALIGN))
+    + (modcnt * sizeof (struct multiboot_tag_module) + total_modcmd)
+    + sizeof (struct multiboot_tag_basic_meminfo)
+    + ALIGN_UP (sizeof (struct multiboot_tag_bootdev), MULTIBOOT_TAG_ALIGN)
+    + (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_count ()
+       * sizeof (struct multiboot_mmap_entry))
+    + sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1;
+}
+
+/* Fill previously allocated Multiboot mmap.  */
+static void
+grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag)
+{
+  struct multiboot_mmap_entry *mmap_entry = tag->entries;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
+    {
+      mmap_entry->addr = addr;
+      mmap_entry->len = size;
+      switch (type)
+       {
+       case GRUB_MACHINE_MEMORY_AVAILABLE:
+         mmap_entry->type = MULTIBOOT_MEMORY_AVAILABLE;
+         break;
+
+#ifdef GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE
+       case GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE:
+         mmap_entry->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE;
+         break;
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_NVS
+       case GRUB_MACHINE_MEMORY_NVS:
+         mmap_entry->type = MULTIBOOT_MEMORY_NVS;
+         break;
+#endif   
+         
+       default:
+         mmap_entry->type = MULTIBOOT_MEMORY_RESERVED;
+         break;
+       }
+      mmap_entry++;
+
+      return 0;
+    }
+
+  tag->type = MULTIBOOT_TAG_TYPE_MMAP;
+  tag->size = sizeof (struct multiboot_tag_mmap)
+    + sizeof (struct multiboot_mmap_entry) * grub_get_multiboot_mmap_count (); 
+  tag->entry_size = sizeof (struct multiboot_mmap_entry);
+  tag->entry_version = 0;
+
+  grub_mmap_iterate (hook);
+}
+
+static grub_err_t
+retrieve_video_parameters (grub_uint8_t **ptrorig)
+{
+  grub_err_t err;
+  struct grub_video_mode_info mode_info;
+  void *framebuffer;
+  grub_video_driver_id_t driv_id;
+  struct grub_video_palette_data palette[256];
+  struct multiboot_tag_framebuffer *tag
+    = (struct multiboot_tag_framebuffer *) *ptrorig;
+
+  err = grub_multiboot_set_video_mode ();
+  if (err)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+    }
+
+  grub_video_get_palette (0, ARRAY_SIZE (palette), palette);
+
+  driv_id = grub_video_get_driver_id ();
+#if HAS_VGA_TEXT
+  if (driv_id == GRUB_VIDEO_DRIVER_NONE)
+    {
+      struct grub_vbe_mode_info_block vbe_mode_info;
+      grub_uint32_t vbe_mode;
+
+#if defined (GRUB_MACHINE_PCBIOS)
+      {
+       grub_vbe_status_t status;
+       void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+       status = grub_vbe_bios_get_mode (scratch);
+       vbe_mode = *(grub_uint32_t *) scratch;
+       if (status != GRUB_VBE_STATUS_OK)
+         return GRUB_ERR_NONE;
+      }
+#else
+      vbe_mode = 3;
+#endif
+
+      /* get_mode_info isn't available for mode 3.  */
+      if (vbe_mode == 3)
+       {
+         grub_memset (&vbe_mode_info, 0,
+                      sizeof (struct grub_vbe_mode_info_block));
+         vbe_mode_info.memory_model = GRUB_VBE_MEMORY_MODEL_TEXT;
+         vbe_mode_info.x_resolution = 80;
+         vbe_mode_info.y_resolution = 25;
+       }
+#if defined (GRUB_MACHINE_PCBIOS)
+      else
+       {
+         grub_vbe_status_t status;
+         void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+         status = grub_vbe_bios_get_mode_info (vbe_mode, scratch);
+         if (status != GRUB_VBE_STATUS_OK)
+           return GRUB_ERR_NONE;
+         grub_memcpy (&vbe_mode_info, scratch,
+                      sizeof (struct grub_vbe_mode_info_block));
+       }
+#endif
+
+      if (vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_TEXT)
+       {
+         tag = (struct multiboot_tag_framebuffer *) *ptrorig;
+         tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER;
+         tag->common.size = 0;
+
+         tag->common.framebuffer_addr = 0xb8000;
+         
+         tag->common.framebuffer_pitch = 2 * vbe_mode_info.x_resolution;       
+         tag->common.framebuffer_width = vbe_mode_info.x_resolution;
+         tag->common.framebuffer_height = vbe_mode_info.y_resolution;
+
+         tag->common.framebuffer_bpp = 16;
+         
+         tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT;
+         tag->common.size = sizeof (tag->common);
+         tag->common.reserved = 0;
+         *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN);
+       }
+      return GRUB_ERR_NONE;
+    }
+#else
+  if (driv_id == GRUB_VIDEO_DRIVER_NONE)
+    return GRUB_ERR_NONE;
+#endif
+
+  err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
+  if (err)
+    return err;
+
+  tag = (struct multiboot_tag_framebuffer *) *ptrorig;
+  tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER;
+  tag->common.size = 0;
+
+  tag->common.framebuffer_addr = (grub_addr_t) framebuffer;
+  tag->common.framebuffer_pitch = mode_info.pitch;
+
+  tag->common.framebuffer_width = mode_info.width;
+  tag->common.framebuffer_height = mode_info.height;
+
+  tag->common.framebuffer_bpp = mode_info.bpp;
+
+  tag->common.reserved = 0;
+      
+  if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
+    {
+      unsigned i;
+      tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED;
+      tag->framebuffer_palette_num_colors = mode_info.number_of_colors;
+      if (tag->framebuffer_palette_num_colors > ARRAY_SIZE (palette))
+       tag->framebuffer_palette_num_colors = ARRAY_SIZE (palette);
+      tag->common.size = sizeof (struct multiboot_tag_framebuffer_common)
+       + sizeof (multiboot_uint16_t) + tag->framebuffer_palette_num_colors
+       * sizeof (struct multiboot_color);
+      for (i = 0; i < tag->framebuffer_palette_num_colors; i++)
+       {
+         tag->framebuffer_palette[i].red = palette[i].r;
+         tag->framebuffer_palette[i].green = palette[i].g;
+         tag->framebuffer_palette[i].blue = palette[i].b;
+       }
+    }
+  else
+    {
+      tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
+      tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
+      tag->framebuffer_red_field_position = mode_info.green_field_pos;
+      tag->framebuffer_red_mask_size = mode_info.green_mask_size;
+      tag->framebuffer_green_field_position = mode_info.green_field_pos;
+      tag->framebuffer_green_mask_size = mode_info.green_mask_size;
+      tag->framebuffer_blue_field_position = mode_info.blue_field_pos;
+      tag->framebuffer_blue_mask_size = mode_info.blue_mask_size;
+
+      tag->common.size = sizeof (struct multiboot_tag_framebuffer_common) + 6;
+    }
+  *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
+                        grub_size_t bufsize)
+{
+  grub_uint8_t *ptrorig;
+  grub_uint8_t *mbistart = (grub_uint8_t *) orig + buf_off 
+    + (ALIGN_UP (dest + buf_off, MULTIBOOT_TAG_ALIGN) - (dest + buf_off));
+  grub_err_t err;
+
+  if (bufsize < grub_multiboot_get_mbi_size ())
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small");
+
+  ptrorig = mbistart + 2 * sizeof (grub_uint32_t);
+
+  {
+    struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
+    tag->type = MULTIBOOT_TAG_TYPE_CMDLINE;
+    tag->size = sizeof (struct multiboot_tag_string) + cmdline_size; 
+    grub_memcpy (tag->string, cmdline, cmdline_size);
+    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
+  }
+
+  {
+    struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
+    tag->type = MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME;
+    tag->size = sizeof (struct multiboot_tag_string) + sizeof (PACKAGE_STRING); 
+    grub_memcpy (tag->string, PACKAGE_STRING, sizeof (PACKAGE_STRING));
+    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
+  }
+
+  {
+    unsigned i;
+    struct module *cur;
+
+    for (i = 0, cur = modules; i < modcnt; i++, cur = cur->next)
+      {
+       struct multiboot_tag_module *tag
+         = (struct multiboot_tag_module *) ptrorig;
+       tag->type = MULTIBOOT_TAG_TYPE_MODULE;
+       tag->size = sizeof (struct multiboot_tag_module) + cur->cmdline_size;
+       tag->mod_start = dest + cur->start;
+       tag->mod_end = tag->mod_start + cur->size;
+       grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size);
+       ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
+      }
+  }
+
+  {
+    struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
+    grub_fill_multiboot_mmap (tag);
+    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
+  }
+
+  {
+    struct multiboot_tag_basic_meminfo *tag
+      = (struct multiboot_tag_basic_meminfo *) ptrorig;
+    tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
+    tag->size = sizeof (struct multiboot_tag_basic_meminfo); 
+
+    /* Convert from bytes to kilobytes.  */
+    tag->mem_lower = grub_mmap_get_lower () / 1024;
+    tag->mem_upper = grub_mmap_get_upper () / 1024;
+    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
+  }
+
+  if (bootdev_set)
+    {
+      struct multiboot_tag_bootdev *tag
+       = (struct multiboot_tag_bootdev *) ptrorig;
+      tag->type = MULTIBOOT_TAG_TYPE_BOOTDEV;
+      tag->size = sizeof (struct multiboot_tag_bootdev); 
+
+      tag->biosdev = biosdev;
+      tag->slice = slice;
+      tag->part = part;
+      ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
+    }
+
+  {
+    err = retrieve_video_parameters (&ptrorig);
+    if (err)
+      {
+       grub_print_error ();
+       grub_errno = GRUB_ERR_NONE;
+      }
+  }
+  
+  {
+    struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
+    tag->type = MULTIBOOT_TAG_TYPE_END;
+    tag->size = sizeof (struct multiboot_tag);
+    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
+  }
+
+  ((grub_uint32_t *) mbistart)[0] = ptrorig - mbistart;
+  ((grub_uint32_t *) mbistart)[1] = 0;
+
+  return GRUB_ERR_NONE;
+}
+
+void
+grub_multiboot_free_mbi (void)
+{
+  struct module *cur, *next;
+
+  cmdline_size = 0;
+  total_modcmd = 0;
+  modcnt = 0;
+  grub_free (cmdline);
+  cmdline = NULL;
+  bootdev_set = 0;
+
+  for (cur = modules; cur; cur = next)
+    {
+      next = cur->next;
+      grub_free (cur->cmdline);
+      grub_free (cur);
+    }
+  modules = NULL;
+  modules_last = NULL;
+}
+
+grub_err_t
+grub_multiboot_init_mbi (int argc, char *argv[])
+{
+  grub_ssize_t len = 0;
+  char *p;
+  int i;
+
+  grub_multiboot_free_mbi ();
+
+  for (i = 0; i < argc; i++)
+    len += grub_strlen (argv[i]) + 1;
+  if (len == 0)
+    len = 1;
+
+  cmdline = p = grub_malloc (len);
+  if (! cmdline)
+    return grub_errno;
+  cmdline_size = len;
+
+  for (i = 0; i < argc; i++)
+    {
+      p = grub_stpcpy (p, argv[i]);
+      *(p++) = ' ';
+    }
+
+  /* Remove the space after the last word.  */
+  if (p != cmdline)
+    p--;
+  *p = '\0';
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
+                          int argc, char *argv[])
+{
+  struct module *newmod;
+  char *p;
+  grub_ssize_t len = 0;
+  int i;
+
+  newmod = grub_malloc (sizeof (*newmod));
+  if (!newmod)
+    return grub_errno;
+  newmod->start = start;
+  newmod->size = size;
+
+  for (i = 0; i < argc; i++)
+    len += grub_strlen (argv[i]) + 1;
+
+  if (len == 0)
+    len = 1;
+
+  newmod->cmdline = p = grub_malloc (len);
+  if (! newmod->cmdline)
+    {
+      grub_free (newmod);
+      return grub_errno;
+    }
+  newmod->cmdline_size = len;
+  total_modcmd += ALIGN_UP (len, MULTIBOOT_TAG_ALIGN);
+
+  for (i = 0; i < argc; i++)
+    {
+      p = grub_stpcpy (p, argv[i]);
+      *(p++) = ' ';
+    }
+
+  /* Remove the space after the last word.  */
+  if (p != newmod->cmdline)
+    p--;
+  *p = '\0';
+
+  if (modules_last)
+    modules_last->next = newmod;
+  else
+    {
+      modules = newmod;
+      modules_last->next = NULL;
+    }
+  modules_last = newmod;
+
+  modcnt++;
+
+  return GRUB_ERR_NONE;
+}
+
+void
+grub_multiboot_set_bootdev (void)
+{
+  grub_device_t dev;
+
+  slice = ~0;
+  part = ~0;
+
+#ifdef GRUB_MACHINE_PCBIOS
+  biosdev = grub_get_root_biosnumber ();
+#else
+  biosdev = 0xffffffff;
+#endif
+
+  if (biosdev == 0xffffffff)
+    return;
+
+  dev = grub_device_open (0);
+  if (dev && dev->disk && dev->disk->partition)
+    {
+      if (dev->disk->partition->parent)
+       {
+         part = dev->disk->partition->number;
+         slice = dev->disk->partition->parent->number;
+       }
+      else
+       slice = dev->disk->partition->number;
+    }
+  if (dev)
+    grub_device_close (dev);
+
+  bootdev_set = 1;
+}
diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c
new file mode 100644 (file)
index 0000000..930c0cb
--- /dev/null
@@ -0,0 +1,363 @@
+/* linux.c - boot Linux */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/elf.h>
+#include <grub/elfload.h>
+#include <grub/loader.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/machine/loader.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+#define ELF32_LOADMASK (0xc0000000UL)
+#define ELF64_LOADMASK (0xc000000000000000ULL)
+
+static grub_dl_t my_mod;
+
+static int loaded;
+
+static grub_addr_t initrd_addr;
+static grub_size_t initrd_size;
+
+static grub_addr_t linux_addr;
+static grub_size_t linux_size;
+
+static char *linux_args;
+
+typedef void (*kernel_entry_t) (void *, unsigned long, int (void *),
+                               unsigned long, unsigned long);
+
+static grub_err_t
+grub_linux_boot (void)
+{
+  kernel_entry_t linuxmain;
+  grub_ssize_t actual;
+
+  /* Set the command line arguments.  */
+  grub_ieee1275_set_property (grub_ieee1275_chosen, "bootargs", linux_args,
+                             grub_strlen (linux_args) + 1, &actual);
+
+  grub_dprintf ("loader", "Entry point: 0x%x\n", linux_addr);
+  grub_dprintf ("loader", "Initrd at: 0x%x, size 0x%x\n", initrd_addr,
+               initrd_size);
+  grub_dprintf ("loader", "Boot arguments: %s\n", linux_args);
+  grub_dprintf ("loader", "Jumping to Linux...\n");
+
+  /* Boot the kernel.  */
+  linuxmain = (kernel_entry_t) linux_addr;
+  linuxmain ((void *) initrd_addr, initrd_size, grub_ieee1275_entry_fn, 0, 0);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_release_mem (void)
+{
+  grub_free (linux_args);
+  linux_args = 0;
+
+  if (linux_addr && grub_ieee1275_release (linux_addr, linux_size))
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot release memory");
+
+  if (initrd_addr && grub_ieee1275_release (initrd_addr, initrd_size))
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot release memory");
+
+  linux_addr = 0;
+  initrd_addr = 0;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  grub_err_t err;
+
+  err = grub_linux_release_mem ();
+  grub_dl_unref (my_mod);
+
+  loaded = 0;
+
+  return err;
+}
+
+static grub_err_t
+grub_linux_load32 (grub_elf_t elf)
+{
+  Elf32_Addr entry;
+  int found_addr = 0;
+
+  /* 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, 0);
+  if (linux_size == 0)
+    return grub_errno;
+  /* Pad it; the kernel scribbles over memory beyond its load address.  */
+  linux_size += 0x100000;
+
+  /* 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",
+                   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, "couldn't claim memory");
+
+  /* Now load the segments into the area we claimed.  */
+  auto grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load);
+  grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load)
+    {
+      if (phdr->p_type != PT_LOAD)
+       {
+         *do_load = 0;
+         return 0;
+       }
+      *do_load = 1;
+
+      /* 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;
+    }
+  return grub_elf32_load (elf, offset_phdr, 0, 0);
+}
+
+static grub_err_t
+grub_linux_load64 (grub_elf_t elf)
+{
+  Elf64_Addr entry;
+  int found_addr = 0;
+
+  /* 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, 0);
+  if (linux_size == 0)
+    return grub_errno;
+  /* Pad it; the kernel scribbles over memory beyond its load address.  */
+  linux_size += 0x100000;
+
+  /* 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",
+                   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, "couldn't claim memory");
+
+  /* Now load the segments into the area we claimed.  */
+  auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load);
+  grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load)
+    {
+      if (phdr->p_type != PT_LOAD)
+       {
+         *do_load = 0;
+         return 0;
+       }
+      *do_load = 1;
+      /* 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;
+    }
+  return grub_elf64_load (elf, offset_phdr, 0, 0);
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+               int argc, char *argv[])
+{
+  grub_elf_t elf = 0;
+  int i;
+  int size;
+  char *dest;
+
+  grub_dl_ref (my_mod);
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
+      goto out;
+    }
+
+  elf = grub_elf_open (argv[0]);
+  if (! elf)
+    goto out;
+
+  if (elf->ehdr.ehdr32.e_type != ET_EXEC)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_OS,
+                 "this ELF file is not of the right type");
+      goto out;
+    }
+
+  /* Release the previously used memory.  */
+  grub_loader_unset ();
+
+  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]);
+  for (i = 0; i < argc; i++)
+    size += grub_strlen (argv[i]) + 1;
+
+  linux_args = grub_malloc (size);
+  if (! linux_args)
+    goto out;
+
+  /* Specify the boot file.  */
+  dest = grub_stpcpy (linux_args, "BOOT_IMAGE=");
+  dest = grub_stpcpy (dest, argv[0]);
+
+  for (i = 1; i < argc; i++)
+    {
+      *dest++ = ' ';
+      dest = grub_stpcpy (dest, argv[i]);
+    }
+
+out:
+
+  if (elf)
+    grub_elf_close (elf);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_linux_release_mem ();
+      grub_dl_unref (my_mod);
+      loaded = 0;
+    }
+  else
+    {
+      grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
+      initrd_addr = 0;
+      loaded = 1;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+                int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  grub_addr_t first_addr;
+  grub_addr_t addr;
+  int found_addr = 0;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified");
+      goto fail;
+    }
+
+  if (!loaded)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    goto fail;
+
+  first_addr = linux_addr + linux_size;
+  size = grub_file_size (file);
+
+  /* Attempt to claim at a series of addresses until successful in
+     the same way that grub_rescue_cmd_linux does.  */
+  for (addr = first_addr; addr < first_addr + 200 * 0x100000; addr += 0x100000)
+    {
+      grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n",
+                   addr, size);
+      found_addr = grub_claimmap (addr, size);
+      if (found_addr != -1)
+       break;
+    }
+
+  if (found_addr == -1)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot claim memory");
+      goto fail;
+    }
+
+  grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size);
+
+  if (grub_file_read (file, (void *) addr, size) != size)
+    {
+      grub_ieee1275_release (addr, size);
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+      goto fail;
+    }
+
+  initrd_addr = addr;
+  initrd_size = size;
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static grub_command_t cmd_linux, cmd_initrd;
+\f
+GRUB_MOD_INIT(linux)
+{
+  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
+                                    0, N_("Load Linux."));
+  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
+                                     0, N_("Load initrd."));
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux)
+{
+  grub_unregister_command (cmd_linux);
+  grub_unregister_command (cmd_initrd);
+}
diff --git a/grub-core/loader/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c
new file mode 100644 (file)
index 0000000..f55b4fa
--- /dev/null
@@ -0,0 +1,529 @@
+/* linux.c - boot Linux */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003, 2004, 2005, 2007, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/elf.h>
+#include <grub/elfload.h>
+#include <grub/loader.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/machine/loader.h>
+#include <grub/gzio.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+static grub_dl_t my_mod;
+
+static int loaded;
+
+/* /virtual-memory/translations property layout  */
+struct grub_ieee1275_translation {
+  grub_uint64_t vaddr;
+  grub_uint64_t size;
+  grub_uint64_t data;
+};
+
+static struct grub_ieee1275_translation *of_trans;
+static int of_num_trans;
+
+static grub_addr_t phys_base;
+static grub_addr_t grub_phys_start;
+static grub_addr_t grub_phys_end;
+
+static grub_addr_t initrd_addr;
+static grub_addr_t initrd_paddr;
+static grub_size_t initrd_size;
+
+static Elf64_Addr linux_entry;
+static grub_addr_t linux_addr;
+static grub_addr_t linux_paddr;
+static grub_size_t linux_size;
+
+static char *linux_args;
+
+struct linux_bootstr_info {
+       int len, valid;
+       char buf[];
+};
+
+struct linux_hdrs {
+       /* All HdrS versions support these fields.  */
+       unsigned int start_insns[2];
+       char magic[4]; /* "HdrS" */
+       unsigned int linux_kernel_version; /* LINUX_VERSION_CODE */
+       unsigned short hdrs_version;
+       unsigned short root_flags;
+       unsigned short root_dev;
+       unsigned short ram_flags;
+       unsigned int __deprecated_ramdisk_image;
+       unsigned int ramdisk_size;
+
+       /* HdrS versions 0x0201 and higher only */
+       char *reboot_command;
+
+       /* HdrS versions 0x0202 and higher only */
+       struct linux_bootstr_info *bootstr_info;
+
+       /* HdrS versions 0x0301 and higher only */
+       unsigned long ramdisk_image;
+};
+
+static grub_err_t
+grub_linux_boot (void)
+{
+  struct linux_bootstr_info *bp;
+  struct linux_hdrs *hp;
+  grub_addr_t addr;
+
+  hp = (struct linux_hdrs *) linux_addr;
+
+  /* Any pointer we dereference in the kernel image must be relocated
+     to where we actually loaded the kernel.  */
+  addr = (grub_addr_t) hp->bootstr_info;
+  addr += (linux_addr - linux_entry);
+  bp = (struct linux_bootstr_info *) addr;
+
+  /* Set the command line arguments, unless the kernel has been
+     built with a fixed CONFIG_CMDLINE.  */
+  if (!bp->valid)
+    {
+      int len = grub_strlen (linux_args) + 1;
+      if (bp->len < len)
+       len = bp->len;
+      memcpy(bp->buf, linux_args, len);
+      bp->buf[len-1] = '\0';
+      bp->valid = 1;
+    }
+
+  if (initrd_addr)
+    {
+      /* The kernel expects the physical address, adjusted relative
+        to the lowest address advertised in "/memory"'s available
+        property.
+
+        The history of this is that back when the kernel only supported
+        specifying a 32-bit ramdisk address, this was the way to still
+        be able to specify the ramdisk physical address even if memory
+        started at some place above 4GB.
+
+        The magic 0x400000 is KERNBASE, I have no idea why SILO adds
+        that term into the address, but it does and thus we have to do
+        it too as this is what the kernel expects.  */
+      hp->ramdisk_image = initrd_paddr - phys_base + 0x400000;
+      hp->ramdisk_size = initrd_size;
+    }
+
+  grub_dprintf ("loader", "Entry point: 0x%lx\n", linux_addr);
+  grub_dprintf ("loader", "Initrd at: 0x%lx, size 0x%lx\n", initrd_addr,
+               initrd_size);
+  grub_dprintf ("loader", "Boot arguments: %s\n", linux_args);
+  grub_dprintf ("loader", "Jumping to Linux...\n");
+
+  /* Boot the kernel.  */
+  asm volatile ("sethi %hi(grub_ieee1275_entry_fn), %o1\n"
+               "ldx    [%o1 + %lo(grub_ieee1275_entry_fn)], %o4\n"
+               "sethi  %hi(grub_ieee1275_original_stack), %o1\n"
+               "ldx    [%o1 + %lo(grub_ieee1275_original_stack)], %o6\n"
+               "sethi  %hi(linux_addr), %o1\n"
+               "ldx    [%o1 + %lo(linux_addr)], %o5\n"
+               "mov    %g0, %o0\n"
+               "mov    %g0, %o2\n"
+               "mov    %g0, %o3\n"
+               "jmp    %o5\n"
+               "mov    %g0, %o1\n");
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_release_mem (void)
+{
+  grub_free (linux_args);
+  linux_args = 0;
+  linux_addr = 0;
+  initrd_addr = 0;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_linux_unload (void)
+{
+  grub_err_t err;
+
+  err = grub_linux_release_mem ();
+  grub_dl_unref (my_mod);
+
+  loaded = 0;
+
+  return err;
+}
+
+#define FOUR_MB        (4 * 1024 * 1024)
+
+static grub_addr_t
+alloc_phys (grub_addr_t size)
+{
+  grub_addr_t ret = (grub_addr_t) -1;
+
+  auto int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type);
+  int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type)
+  {
+    grub_addr_t end = addr + len;
+
+    if (type != 1)
+      return 0;
+
+    addr = ALIGN_UP (addr, FOUR_MB);
+    if (addr + size >= end)
+      return 0;
+
+    if (addr >= grub_phys_start && addr < grub_phys_end)
+      {
+       addr = ALIGN_UP (grub_phys_end, FOUR_MB);
+       if (addr + size >= end)
+         return 0;
+      }
+    if ((addr + size) >= grub_phys_start
+       && (addr + size) < grub_phys_end)
+      {
+       addr = ALIGN_UP (grub_phys_end, FOUR_MB);
+       if (addr + size >= end)
+         return 0;
+      }
+
+    if (loaded)
+      {
+       grub_addr_t linux_end = ALIGN_UP (linux_paddr + linux_size, FOUR_MB);
+
+       if (addr >= linux_paddr && addr < linux_end)
+         {
+           addr = linux_end;
+           if (addr + size >= end)
+             return 0;
+         }
+       if ((addr + size) >= linux_paddr
+           && (addr + size) < linux_end)
+         {
+           addr = linux_end;
+           if (addr + size >= end)
+             return 0;
+         }
+      }
+
+    ret = addr;
+    return 1;
+  }
+
+  grub_machine_mmap_iterate (choose);
+
+  return ret;
+}
+
+static grub_err_t
+grub_linux_load64 (grub_elf_t elf)
+{
+  grub_addr_t off, paddr, base;
+  int ret;
+
+  linux_entry = elf->ehdr.ehdr64.e_entry;
+  linux_addr = 0x40004000;
+  off = 0x4000;
+  linux_size = grub_elf64_size (elf, 0);
+  if (linux_size == 0)
+    return grub_errno;
+
+  grub_dprintf ("loader", "Attempting to claim at 0x%lx, size 0x%lx.\n",
+               linux_addr, linux_size);
+
+  paddr = alloc_phys (linux_size + off);
+  if (paddr == (grub_addr_t) -1)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                      "couldn't allocate physical memory");
+  ret = grub_ieee1275_map (paddr, linux_addr - off,
+                          linux_size + off, IEEE1275_MAP_DEFAULT);
+  if (ret)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                      "couldn't map physical memory");
+
+  grub_dprintf ("loader", "Loading Linux at vaddr 0x%lx, paddr 0x%lx, size 0x%lx\n",
+               linux_addr, paddr, linux_size);
+
+  linux_paddr = paddr;
+
+  base = linux_entry - off;
+
+  /* Now load the segments into the area we claimed.  */
+  auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load);
+  grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load)
+    {
+      if (phdr->p_type != PT_LOAD)
+       {
+         *do_load = 0;
+         return 0;
+       }
+      *do_load = 1;
+
+      /* Adjust the program load address to linux_addr.  */
+      *addr = (phdr->p_paddr - base) + (linux_addr - off);
+      return 0;
+    }
+  return grub_elf64_load (elf, offset_phdr, 0, 0);
+}
+
+static grub_err_t
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
+               int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_elf_t elf = 0;
+  int i;
+  int size;
+  char *dest;
+
+  grub_dl_ref (my_mod);
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
+      goto out;
+    }
+
+  file = grub_gzfile_open (argv[0], 1);
+  if (!file)
+    goto out;
+
+  elf = grub_elf_file (file);
+  if (! elf)
+    goto out;
+
+  if (elf->ehdr.ehdr32.e_type != ET_EXEC)
+    {
+      grub_error (GRUB_ERR_UNKNOWN_OS,
+                 "this ELF file is not of the right type");
+      goto out;
+    }
+
+  /* Release the previously used memory.  */
+  grub_loader_unset ();
+
+  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]);
+  for (i = 0; i < argc; i++)
+    size += grub_strlen (argv[i]) + 1;
+
+  linux_args = grub_malloc (size);
+  if (! linux_args)
+    goto out;
+
+  /* Specify the boot file.  */
+  dest = grub_stpcpy (linux_args, "BOOT_IMAGE=");
+  dest = grub_stpcpy (dest, argv[0]);
+
+  for (i = 1; i < argc; i++)
+    {
+      *dest++ = ' ';
+      dest = grub_stpcpy (dest, argv[i]);
+    }
+
+out:
+  if (elf)
+    grub_elf_close (elf);
+  else if (file)
+    grub_file_close (file);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_linux_release_mem ();
+      grub_dl_unref (my_mod);
+      loaded = 0;
+    }
+  else
+    {
+      grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
+      initrd_addr = 0;
+      loaded = 1;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
+                int argc, char *argv[])
+{
+  grub_file_t file = 0;
+  grub_ssize_t size;
+  grub_addr_t paddr;
+  grub_addr_t addr;
+  int ret;
+
+  if (argc == 0)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified");
+      goto fail;
+    }
+
+  if (!loaded)
+    {
+      grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
+      goto fail;
+    }
+
+  file = grub_file_open (argv[0]);
+  if (! file)
+    goto fail;
+
+  addr = 0x60000000;
+  size = grub_file_size (file);
+
+  paddr = alloc_phys (size);
+  if (paddr == (grub_addr_t) -1)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                 "couldn't allocate physical memory");
+      goto fail;
+    }
+  ret = grub_ieee1275_map (paddr, addr, size, IEEE1275_MAP_DEFAULT);
+  if (ret)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                 "couldn't map physical memory");
+      goto fail;
+    }
+
+  grub_dprintf ("loader", "Loading initrd at vaddr 0x%lx, paddr 0x%lx, size 0x%lx\n",
+               addr, paddr, size);
+
+  if (grub_file_read (file, (void *) addr, size) != size)
+    {
+      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
+      goto fail;
+    }
+
+  initrd_addr = addr;
+  initrd_paddr = paddr;
+  initrd_size = size;
+
+ fail:
+  if (file)
+    grub_file_close (file);
+
+  return grub_errno;
+}
+
+static void
+determine_phys_base (void)
+{
+  auto int NESTED_FUNC_ATTR get_physbase (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type);
+  int NESTED_FUNC_ATTR get_physbase (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type)
+  {
+    if (type != 1)
+      return 0;
+    if (addr < phys_base)
+      phys_base = addr;
+    return 0;
+  }
+
+  phys_base = ~(grub_uint64_t) 0;
+  grub_machine_mmap_iterate (get_physbase);
+}
+
+static void
+fetch_translations (void)
+{
+  grub_ieee1275_phandle_t node;
+  grub_ssize_t actual;
+  int i;
+
+  if (grub_ieee1275_finddevice ("/virtual-memory", &node))
+    {
+      grub_printf ("Cannot find /virtual-memory node.\n");
+      return;
+    }
+
+  if (grub_ieee1275_get_property_length (node, "translations", &actual))
+    {
+      grub_printf ("Cannot find /virtual-memory/translations size.\n");
+      return;
+    }
+
+  of_trans = grub_malloc (actual);
+  if (!of_trans)
+    {
+      grub_printf ("Cannot allocate translations buffer.\n");
+      return;
+    }
+
+  if (grub_ieee1275_get_property (node, "translations", of_trans, actual, &actual))
+    {
+      grub_printf ("Cannot fetch /virtual-memory/translations property.\n");
+      return;
+    }
+
+  of_num_trans = actual / sizeof(struct grub_ieee1275_translation);
+
+  for (i = 0; i < of_num_trans; i++)
+    {
+      struct grub_ieee1275_translation *p = &of_trans[i];
+
+      if (p->vaddr == 0x2000)
+       {
+         grub_addr_t phys, tte = p->data;
+
+         phys = tte & ~(0xff00000000001fffULL);
+
+         grub_phys_start = phys;
+         grub_phys_end = grub_phys_start + p->size;
+         grub_dprintf ("loader", "Grub lives at phys_start[%lx] phys_end[%lx]\n",
+                       (unsigned long) grub_phys_start,
+                       (unsigned long) grub_phys_end);
+         break;
+       }
+    }
+}
+
+\f
+static grub_command_t cmd_linux, cmd_initrd;
+
+GRUB_MOD_INIT(linux)
+{
+  determine_phys_base ();
+  fetch_translations ();
+
+  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
+                                    0, N_("Load Linux."));
+  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
+                                     0, N_("Load initrd."));
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(linux)
+{
+  grub_unregister_command (cmd_linux);
+  grub_unregister_command (cmd_initrd);
+}
diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c
new file mode 100644 (file)
index 0000000..8f1d0c6
--- /dev/null
@@ -0,0 +1,1471 @@
+/* xnu.c - load xnu kernel. Thanks to Florian Idelberger for all the
+   time he spent testing this
+ */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/file.h>
+#include <grub/xnu.h>
+#include <grub/cpu/xnu.h>
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/loader.h>
+#include <grub/machoload.h>
+#include <grub/macho.h>
+#include <grub/cpu/macho.h>
+#include <grub/gzio.h>
+#include <grub/command.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+#include <grub/env.h>
+#include <grub/i18n.h>
+
+struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0;
+static int driverspackagenum = 0;
+static int driversnum = 0;
+int grub_xnu_is_64bit = 0;
+
+void *grub_xnu_heap_start = 0;
+grub_size_t grub_xnu_heap_size = 0;
+
+/* Allocate heap by 32MB-blocks. */
+#define GRUB_XNU_HEAP_ALLOC_BLOCK 0x2000000
+
+static grub_err_t
+grub_xnu_register_memory (char *prefix, int *suffix,
+                         void *addr, grub_size_t size);
+void *
+grub_xnu_heap_malloc (int size)
+{
+  void *val;
+  int oldblknum, newblknum;
+
+  /* The page after the heap is used for stack. Ensure it's usable. */
+  if (grub_xnu_heap_size)
+    oldblknum = (grub_xnu_heap_size + GRUB_XNU_PAGESIZE
+                + GRUB_XNU_HEAP_ALLOC_BLOCK - 1) / GRUB_XNU_HEAP_ALLOC_BLOCK;
+  else
+    oldblknum = 0;
+  newblknum = (grub_xnu_heap_size + size + GRUB_XNU_PAGESIZE
+              + GRUB_XNU_HEAP_ALLOC_BLOCK - 1) / GRUB_XNU_HEAP_ALLOC_BLOCK;
+  if (oldblknum != newblknum)
+    {
+      /* FIXME: instruct realloc to allocate at 1MB if possible once
+        advanced mm is ready. */
+      grub_xnu_heap_start
+       = XNU_RELOCATOR (realloc) (grub_xnu_heap_start,
+                                  newblknum
+                                  * GRUB_XNU_HEAP_ALLOC_BLOCK);
+      if (!grub_xnu_heap_start)
+       return NULL;
+    }
+
+  val = (grub_uint8_t *) grub_xnu_heap_start + grub_xnu_heap_size;
+  grub_xnu_heap_size += size;
+  grub_dprintf ("xnu", "val=%p\n", val);
+  return val;
+}
+
+/* Make sure next block of the heap will be aligned.
+   Please notice: aligned are pointers AFTER relocation
+   and not the current ones. */
+grub_err_t
+grub_xnu_align_heap (int align)
+{
+  int align_overhead = align - grub_xnu_heap_size % align;
+  if (align_overhead == align)
+    return GRUB_ERR_NONE;
+  if (! grub_xnu_heap_malloc (align_overhead))
+    return grub_errno;
+  return GRUB_ERR_NONE;
+}
+
+/* Free subtree pointed by CUR. */
+void
+grub_xnu_free_devtree (struct grub_xnu_devtree_key *cur)
+{
+  struct grub_xnu_devtree_key *d;
+  while (cur)
+    {
+      grub_free (cur->name);
+      if (cur->datasize == -1)
+       grub_xnu_free_devtree (cur->first_child);
+      else if (cur->data)
+       grub_free (cur->data);
+      d = cur->next;
+      grub_free (cur);
+      cur = d;
+    }
+}
+
+/* Compute the size of device tree in xnu format. */
+static grub_size_t
+grub_xnu_writetree_get_size (struct grub_xnu_devtree_key *start, char *name)
+{
+  grub_size_t ret;
+  struct grub_xnu_devtree_key *cur;
+
+  /* Key header. */
+  ret = 2 * sizeof (grub_uint32_t);
+
+  /* "name" value. */
+  ret += 32 + sizeof (grub_uint32_t)
+    + grub_strlen (name) + 4
+    - (grub_strlen (name) % 4);
+
+  for (cur = start; cur; cur = cur->next)
+    if (cur->datasize != -1)
+      {
+       int align_overhead;
+
+       align_overhead = 4 - (cur->datasize % 4);
+       if (align_overhead == 4)
+         align_overhead = 0;
+       ret += 32 + sizeof (grub_uint32_t) + cur->datasize + align_overhead;
+      }
+    else
+      ret += grub_xnu_writetree_get_size (cur->first_child, cur->name);
+  return ret;
+}
+
+/* Write devtree in XNU format at curptr assuming the head is named NAME.*/
+static void *
+grub_xnu_writetree_toheap_real (void *curptr,
+                               struct grub_xnu_devtree_key *start, char *name)
+{
+  struct grub_xnu_devtree_key *cur;
+  int nkeys = 0, nvals = 0;
+  for (cur = start; cur; cur = cur->next)
+    {
+      if (cur->datasize == -1)
+       nkeys++;
+      else
+       nvals++;
+    }
+  /* For the name. */
+  nvals++;
+
+  *((grub_uint32_t *) curptr) = nvals;
+  curptr = ((grub_uint32_t *) curptr) + 1;
+  *((grub_uint32_t *) curptr) = nkeys;
+  curptr = ((grub_uint32_t *) curptr) + 1;
+
+  /* First comes "name" value. */
+  grub_memset (curptr, 0, 32);
+  grub_memcpy (curptr, "name", 4);
+  curptr = ((grub_uint8_t *) curptr) + 32;
+  *((grub_uint32_t *)curptr) = grub_strlen (name) + 1;
+  curptr = ((grub_uint32_t *) curptr) + 1;
+  grub_memcpy (curptr, name, grub_strlen (name));
+  curptr = ((grub_uint8_t *) curptr) + grub_strlen (name);
+  grub_memset (curptr, 0, 4 - (grub_strlen (name) % 4));
+  curptr = ((grub_uint8_t *) curptr) + (4 - (grub_strlen (name) % 4));
+
+  /* Then the other values. */
+  for (cur = start; cur; cur = cur->next)
+    if (cur->datasize != -1)
+      {
+       int align_overhead;
+
+       align_overhead = 4 - (cur->datasize % 4);
+       if (align_overhead == 4)
+         align_overhead = 0;
+       grub_memset (curptr, 0, 32);
+       grub_strncpy (curptr, cur->name, 31);
+       curptr = ((grub_uint8_t *) curptr) + 32;
+       *((grub_uint32_t *) curptr) = cur->datasize;
+       curptr = ((grub_uint32_t *) curptr) + 1;
+       grub_memcpy (curptr, cur->data, cur->datasize);
+       curptr = ((grub_uint8_t *) curptr) + cur->datasize;
+       grub_memset (curptr, 0, align_overhead);
+       curptr = ((grub_uint8_t *) curptr) + align_overhead;
+      }
+
+  /* And then the keys. Recursively use this function. */
+  for (cur = start; cur; cur = cur->next)
+    if (cur->datasize == -1)
+      if (!(curptr = grub_xnu_writetree_toheap_real (curptr,
+                                                    cur->first_child,
+                                                    cur->name)))
+       return 0;
+  return curptr;
+}
+
+grub_err_t
+grub_xnu_writetree_toheap (void **start, grub_size_t *size)
+{
+  struct grub_xnu_devtree_key *chosen;
+  struct grub_xnu_devtree_key *memorymap;
+  struct grub_xnu_devtree_key *driverkey;
+  struct grub_xnu_extdesc *extdesc;
+  grub_err_t err;
+
+  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
+  if (err)
+    return err;
+
+  /* Device tree itself is in the memory map of device tree. */
+  /* Create a dummy value in memory-map. */
+  chosen = grub_xnu_create_key (&grub_xnu_devtree_root, "chosen");
+  if (! chosen)
+    return grub_errno;
+  memorymap = grub_xnu_create_key (&(chosen->first_child), "memory-map");
+  if (! memorymap)
+    return grub_errno;
+
+  driverkey = (struct grub_xnu_devtree_key *) grub_malloc (sizeof (*driverkey));
+  if (! driverkey)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't write device tree");
+  driverkey->name = grub_strdup ("DeviceTree");
+  if (! driverkey->name)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't write device tree");
+  driverkey->datasize = sizeof (*extdesc);
+  driverkey->next = memorymap->first_child;
+  memorymap->first_child = driverkey;
+  driverkey->data = extdesc
+    = (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc));
+  if (! driverkey->data)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't write device tree");
+
+  /* Allocate the space based on the size with dummy value. */
+  *size = grub_xnu_writetree_get_size (grub_xnu_devtree_root, "/");
+  *start = grub_xnu_heap_malloc (*size + GRUB_XNU_PAGESIZE
+                                - *size % GRUB_XNU_PAGESIZE);
+
+  /* Put real data in the dummy. */
+  extdesc->addr = (grub_uint8_t *) *start - (grub_uint8_t *) grub_xnu_heap_start
+    + grub_xnu_heap_will_be_at;
+  extdesc->size = (grub_uint32_t) *size;
+
+  /* Write the tree to heap. */
+  grub_xnu_writetree_toheap_real (*start, grub_xnu_devtree_root, "/");
+  return GRUB_ERR_NONE;
+}
+
+/* Find a key or value in parent key. */
+struct grub_xnu_devtree_key *
+grub_xnu_find_key (struct grub_xnu_devtree_key *parent, char *name)
+{
+  struct grub_xnu_devtree_key *cur;
+  for (cur = parent; cur; cur = cur->next)
+    if (grub_strcmp (cur->name, name) == 0)
+      return cur;
+  return 0;
+}
+
+struct grub_xnu_devtree_key *
+grub_xnu_create_key (struct grub_xnu_devtree_key **parent, char *name)
+{
+  struct grub_xnu_devtree_key *ret;
+  ret = grub_xnu_find_key (*parent, name);
+  if (ret)
+    return ret;
+  ret = (struct grub_xnu_devtree_key *) grub_zalloc (sizeof (*ret));
+  if (! ret)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create key %s", name);
+      return 0;
+    }
+  ret->name = grub_strdup (name);
+  if (! ret->name)
+    {
+      grub_free (ret);
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create key %s", name);
+      return 0;
+    }
+  ret->datasize = -1;
+  ret->next = *parent;
+  *parent = ret;
+  return ret;
+}
+
+struct grub_xnu_devtree_key *
+grub_xnu_create_value (struct grub_xnu_devtree_key **parent, char *name)
+{
+  struct grub_xnu_devtree_key *ret;
+  ret = grub_xnu_find_key (*parent, name);
+  if (ret)
+    {
+      if (ret->datasize == -1)
+       grub_xnu_free_devtree (ret->first_child);
+      else if (ret->datasize)
+       grub_free (ret->data);
+      ret->datasize = 0;
+      ret->data = 0;
+      return ret;
+    }
+  ret = (struct grub_xnu_devtree_key *) grub_zalloc (sizeof (*ret));
+  if (! ret)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create value %s", name);
+      return 0;
+    }
+  ret->name = grub_strdup (name);
+  if (! ret->name)
+    {
+      grub_free (ret);
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create value %s", name);
+      return 0;
+    }
+  ret->next = *parent;
+  *parent = ret;
+  return ret;
+}
+
+static grub_err_t
+grub_xnu_unload (void)
+{
+  grub_cpu_xnu_unload ();
+
+  grub_xnu_free_devtree (grub_xnu_devtree_root);
+  grub_xnu_devtree_root = 0;
+
+  /* Free loaded image. */
+  driversnum = 0;
+  driverspackagenum = 0;
+  grub_free (grub_xnu_heap_start);
+  grub_xnu_heap_start = 0;
+  grub_xnu_heap_size = 0;
+  grub_xnu_unlock ();
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
+                    int argc, char *args[])
+{
+  grub_err_t err;
+  grub_macho_t macho;
+  grub_uint32_t startcode, endcode;
+  int i;
+  char *ptr, *loadaddr;
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  grub_xnu_unload ();
+
+  macho = grub_macho_open (args[0]);
+  if (! macho)
+    return grub_errno;
+  if (! grub_macho_contains_macho32 (macho))
+    {
+      grub_macho_close (macho);
+      return grub_error (GRUB_ERR_BAD_OS,
+                        "kernel doesn't contain suitable 32-bit architecture");
+    }
+
+  err = grub_macho_size32 (macho, &startcode, &endcode, GRUB_MACHO_NOBSS);
+  if (err)
+    {
+      grub_macho_close (macho);
+      grub_xnu_unload ();
+      return err;
+    }
+
+  grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n",
+               (unsigned long) endcode, (unsigned long) startcode);
+
+  loadaddr = grub_xnu_heap_malloc (endcode - startcode);
+  grub_xnu_heap_will_be_at = startcode;
+
+  if (! loadaddr)
+    {
+      grub_macho_close (macho);
+      grub_xnu_unload ();
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                        "not enough memory to load kernel");
+    }
+
+  /* Load kernel. */
+  err = grub_macho_load32 (macho, loadaddr - startcode, GRUB_MACHO_NOBSS);
+  if (err)
+    {
+      grub_macho_close (macho);
+      grub_xnu_unload ();
+      return err;
+    }
+
+  grub_xnu_entry_point = grub_macho_get_entry_point32 (macho);
+  if (! grub_xnu_entry_point)
+    {
+      grub_macho_close (macho);
+      grub_xnu_unload ();
+      return grub_error (GRUB_ERR_BAD_OS, "couldn't find entry point");
+    }
+
+  grub_macho_close (macho);
+
+  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
+  if (err)
+    {
+      grub_xnu_unload ();
+      return err;
+    }
+
+  /* Copy parameters to kernel command line. */
+  ptr = grub_xnu_cmdline;
+  for (i = 1; i < argc; i++)
+    {
+      if (ptr + grub_strlen (args[i]) + 1
+         >= grub_xnu_cmdline + sizeof (grub_xnu_cmdline))
+       break;
+      grub_memcpy (ptr, args[i], grub_strlen (args[i]));
+      ptr += grub_strlen (args[i]);
+      *ptr = ' ';
+      ptr++;
+    }
+
+  /* Replace last space by '\0'. */
+  if (ptr != grub_xnu_cmdline)
+    *(ptr - 1) = 0;
+
+  grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0);
+
+  grub_xnu_lock ();
+  grub_xnu_is_64bit = 0;
+
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
+                      int argc, char *args[])
+{
+  grub_err_t err;
+  grub_macho_t macho;
+  grub_uint64_t startcode, endcode;
+  int i;
+  char *ptr, *loadaddr;
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  grub_xnu_unload ();
+
+  macho = grub_macho_open (args[0]);
+  if (! macho)
+    return grub_errno;
+  if (! grub_macho_contains_macho64 (macho))
+    {
+      grub_macho_close (macho);
+      return grub_error (GRUB_ERR_BAD_OS,
+                        "kernel doesn't contain suitable 64-bit architecture");
+    }
+
+  err = grub_macho_size64 (macho, &startcode, &endcode, GRUB_MACHO_NOBSS);
+  if (err)
+    {
+      grub_macho_close (macho);
+      grub_xnu_unload ();
+      return err;
+    }
+
+  startcode &= 0x0fffffff;
+  endcode &= 0x0fffffff;
+
+  grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n",
+               (unsigned long) endcode, (unsigned long) startcode);
+
+  loadaddr = grub_xnu_heap_malloc (endcode - startcode);
+  grub_xnu_heap_will_be_at = startcode;
+
+  if (! loadaddr)
+    {
+      grub_macho_close (macho);
+      grub_xnu_unload ();
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                        "not enough memory to load kernel");
+    }
+
+  /* Load kernel. */
+  err = grub_macho_load64 (macho, loadaddr - startcode, GRUB_MACHO_NOBSS);
+  if (err)
+    {
+      grub_macho_close (macho);
+      grub_xnu_unload ();
+      return err;
+    }
+
+  grub_xnu_entry_point = grub_macho_get_entry_point64 (macho) & 0x0fffffff;
+  if (! grub_xnu_entry_point)
+    {
+      grub_macho_close (macho);
+      grub_xnu_unload ();
+      return grub_error (GRUB_ERR_BAD_OS, "couldn't find entry point");
+    }
+
+  grub_macho_close (macho);
+
+  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
+  if (err)
+    {
+      grub_xnu_unload ();
+      return err;
+    }
+
+  /* Copy parameters to kernel command line. */
+  ptr = grub_xnu_cmdline;
+  for (i = 1; i < argc; i++)
+    {
+      if (ptr + grub_strlen (args[i]) + 1
+         >= grub_xnu_cmdline + sizeof (grub_xnu_cmdline))
+       break;
+      grub_memcpy (ptr, args[i], grub_strlen (args[i]));
+      ptr += grub_strlen (args[i]);
+      *ptr = ' ';
+      ptr++;
+    }
+
+  /* Replace last space by '\0'. */
+  if (ptr != grub_xnu_cmdline)
+    *(ptr - 1) = 0;
+
+  grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0);
+
+  grub_xnu_lock ();
+  grub_xnu_is_64bit = 1;
+
+  return 0;
+}
+
+/* Register a memory in a memory map under name PREFIXSUFFIX
+   and increment SUFFIX. */
+static grub_err_t
+grub_xnu_register_memory (char *prefix, int *suffix,
+                         void *addr, grub_size_t size)
+{
+  struct grub_xnu_devtree_key *chosen;
+  struct grub_xnu_devtree_key *memorymap;
+  struct grub_xnu_devtree_key *driverkey;
+  struct grub_xnu_extdesc *extdesc;
+
+  if (! grub_xnu_heap_size)
+    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
+
+  chosen = grub_xnu_create_key (&grub_xnu_devtree_root, "chosen");
+  if (! chosen)
+    return grub_errno;
+  memorymap = grub_xnu_create_key (&(chosen->first_child), "memory-map");
+  if (! memorymap)
+    return grub_errno;
+
+  driverkey = (struct grub_xnu_devtree_key *) grub_malloc (sizeof (*driverkey));
+  if (! driverkey)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register memory");
+  if (suffix)
+    {
+      driverkey->name = grub_xasprintf ("%s%d", prefix, (*suffix)++);
+      if (!driverkey->name)
+       return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register memory");
+    }
+  else
+    driverkey->name = grub_strdup (prefix);
+  if (! driverkey->name)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register extension");
+  driverkey->datasize = sizeof (*extdesc);
+  driverkey->next = memorymap->first_child;
+  memorymap->first_child = driverkey;
+  driverkey->data = extdesc
+    = (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc));
+  if (! driverkey->data)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register extension");
+  extdesc->addr = grub_xnu_heap_will_be_at +
+    ((grub_uint8_t *) addr - (grub_uint8_t *) grub_xnu_heap_start);
+  extdesc->size = (grub_uint32_t) size;
+  return GRUB_ERR_NONE;
+}
+
+static inline char *
+get_name_ptr (char *name)
+{
+  char *p = name, *p2;
+  /* Skip Info.plist.  */
+  p2 = grub_strrchr (p, '/');
+  if (!p2)
+    return name;
+  if (p2 == name)
+    return name + 1;
+  p = p2 - 1;
+
+  p2 = grub_strrchr (p, '/');
+  if (!p2)
+    return name;
+  if (p2 == name)
+    return name + 1;
+  if (grub_memcmp (p2, "/Contents/", sizeof ("/Contents/") - 1) != 0)
+    return p2 + 1;
+
+  p = p2 - 1;
+
+  p2 = grub_strrchr (p, '/');
+  if (!p2)
+    return name;
+  return p2 + 1;
+}
+
+/* Load .kext. */
+static grub_err_t
+grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
+{
+  grub_macho_t macho;
+  grub_err_t err;
+  grub_file_t infoplist;
+  struct grub_xnu_extheader *exthead;
+  int neededspace = sizeof (*exthead);
+  grub_uint8_t *buf;
+  grub_size_t infoplistsize = 0, machosize = 0;
+  char *name, *nameend;
+  int namelen;
+
+  name = get_name_ptr (infoplistname);
+  nameend = grub_strchr (name, '/');
+
+  if (nameend)
+    namelen = nameend - name;
+  else
+    namelen = grub_strlen (name);
+
+  neededspace += namelen + 1;
+
+  if (! grub_xnu_heap_size)
+    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
+
+  /* Compute the needed space. */
+  if (binaryfile)
+    {
+      macho = grub_macho_file (binaryfile);
+      if (! macho || ! grub_macho_contains_macho32 (macho))
+       {
+         if (macho)
+           grub_macho_close (macho);
+         return grub_error (GRUB_ERR_BAD_OS,
+                            "extension doesn't contain suitable architecture");
+       }
+      if (grub_xnu_is_64bit)
+       machosize = grub_macho_filesize64 (macho);
+      else
+       machosize = grub_macho_filesize32 (macho);
+      neededspace += machosize;
+    }
+  else
+    macho = 0;
+
+  if (infoplistname)
+    infoplist = grub_gzfile_open (infoplistname, 1);
+  else
+    infoplist = 0;
+  grub_errno = GRUB_ERR_NONE;
+  if (infoplist)
+    {
+      infoplistsize = grub_file_size (infoplist);
+      neededspace += infoplistsize + 1;
+    }
+  else
+    infoplistsize = 0;
+
+  /* Allocate the space. */
+  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
+  if (err)
+    return err;
+  buf = grub_xnu_heap_malloc (neededspace);
+
+  exthead = (struct grub_xnu_extheader *) buf;
+  grub_memset (exthead, 0, sizeof (*exthead));
+  buf += sizeof (*exthead);
+
+  /* Load the binary. */
+  if (macho)
+    {
+      exthead->binaryaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start)
+       + grub_xnu_heap_will_be_at;
+      exthead->binarysize = machosize;
+      if (grub_xnu_is_64bit)
+       err = grub_macho_readfile64 (macho, buf);
+      else
+       err = grub_macho_readfile32 (macho, buf);
+      if (err)
+       {
+         grub_macho_close (macho);
+         return err;
+       }
+      grub_macho_close (macho);
+      buf += machosize;
+    }
+  grub_errno = GRUB_ERR_NONE;
+
+  /* Load the plist. */
+  if (infoplist)
+    {
+      exthead->infoplistaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start)
+       + grub_xnu_heap_will_be_at;
+      exthead->infoplistsize = infoplistsize + 1;
+      if (grub_file_read (infoplist, buf, infoplistsize)
+         != (grub_ssize_t) (infoplistsize))
+       {
+         grub_file_close (infoplist);
+         grub_error_push ();
+         return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s: ",
+                            infoplistname);
+       }
+      grub_file_close (infoplist);
+      buf[infoplistsize] = 0;
+      buf += infoplistsize + 1;
+    }
+  grub_errno = GRUB_ERR_NONE;
+
+  exthead->nameaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start)
+    + grub_xnu_heap_will_be_at;
+  exthead->namesize = namelen + 1;
+  grub_memcpy (buf, name, namelen);
+  buf[namelen] = 0;
+  buf += namelen + 1;
+
+  /* Announce to kernel */
+  return grub_xnu_register_memory ("Driver-", &driversnum, exthead,
+                                  neededspace);
+}
+
+/* Load mkext. */
+static grub_err_t
+grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)),
+                   int argc, char *args[])
+{
+  grub_file_t file;
+  void *loadto;
+  grub_err_t err;
+  grub_off_t readoff = 0;
+  grub_ssize_t readlen = -1;
+  struct grub_macho_fat_header head;
+  struct grub_macho_fat_arch *archs;
+  int narchs, i;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  if (! grub_xnu_heap_size)
+    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
+
+  file = grub_gzfile_open (args[0], 1);
+  if (! file)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
+                      "couldn't load driver package");
+
+  /* Sometimes caches are fat binary. Errgh. */
+  if (grub_file_read (file, &head, sizeof (head))
+      != (grub_ssize_t) (sizeof (head)))
+    {
+      /* I don't know the internal structure of package but
+        can hardly imagine a valid package shorter than 20 bytes. */
+      grub_file_close (file);
+      grub_error_push ();
+      return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[0]);
+    }
+
+  /* Find the corresponding architecture. */
+  if (grub_be_to_cpu32 (head.magic) == GRUB_MACHO_FAT_MAGIC)
+    {
+      narchs = grub_be_to_cpu32 (head.nfat_arch);
+      archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs);
+      if (! archs)
+       {
+         grub_file_close (file);
+         grub_error_push ();
+         return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                            "couldn't read file %s", args[0]);
+
+       }
+      if (grub_file_read (file, archs,
+                         sizeof (struct grub_macho_fat_arch) * narchs)
+         != (grub_ssize_t) sizeof(struct grub_macho_fat_arch) * narchs)
+       {
+         grub_free (archs);
+         grub_error_push ();
+         return grub_error (GRUB_ERR_READ_ERROR, "cannot read fat header");
+       }
+      for (i = 0; i < narchs; i++)
+       {
+         if (!grub_xnu_is_64bit && GRUB_MACHO_CPUTYPE_IS_HOST32
+             (grub_be_to_cpu32 (archs[i].cputype)))
+           {
+             readoff = grub_be_to_cpu32 (archs[i].offset);
+             readlen = grub_be_to_cpu32 (archs[i].size);
+           }
+         if (grub_xnu_is_64bit && GRUB_MACHO_CPUTYPE_IS_HOST64
+             (grub_be_to_cpu32 (archs[i].cputype)))
+           {
+             readoff = grub_be_to_cpu32 (archs[i].offset);
+             readlen = grub_be_to_cpu32 (archs[i].size);
+           }
+       }
+      grub_free (archs);
+    }
+  else
+    {
+      /* It's a flat file. Some sane people still exist. */
+      readoff = 0;
+      readlen = grub_file_size (file);
+    }
+
+  if (readlen == -1)
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_BAD_OS, "no suitable architecture is found");
+    }
+
+  /* Allocate space. */
+  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
+  if (err)
+    {
+      grub_file_close (file);
+      return err;
+    }
+
+  loadto = grub_xnu_heap_malloc (readlen);
+  if (! loadto)
+    {
+      grub_file_close (file);
+      return grub_errno;
+    }
+
+  /* Read the file. */
+  grub_file_seek (file, readoff);
+  if (grub_file_read (file, loadto, readlen) != (grub_ssize_t) (readlen))
+    {
+      grub_file_close (file);
+      grub_error_push ();
+      return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[0]);
+    }
+  grub_file_close (file);
+
+  /* Pass it to kernel. */
+  return grub_xnu_register_memory ("DriversPackage-", &driverspackagenum,
+                                  loadto, readlen);
+}
+
+static grub_err_t
+grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)),
+                     int argc, char *args[])
+{
+  grub_file_t file;
+  void *loadto;
+  grub_err_t err;
+  grub_size_t size;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  if (! grub_xnu_heap_size)
+    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
+
+  file = grub_gzfile_open (args[0], 1);
+  if (! file)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
+                      "couldn't load ramdisk");
+
+  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
+  if (err)
+    return err;
+
+  size = grub_file_size (file);
+
+  loadto = grub_xnu_heap_malloc (size);
+  if (! loadto)
+    return grub_errno;
+  if (grub_file_read (file, loadto, size)
+      != (grub_ssize_t) (size))
+    {
+      grub_file_close (file);
+      grub_error_push ();
+      return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[0]);
+    }
+  return grub_xnu_register_memory ("RAMDisk", 0, loadto, size);
+}
+
+/* Returns true if the kext should be loaded according to plist
+   and osbundlereq. Also fill BINNAME. */
+static int
+grub_xnu_check_os_bundle_required (char *plistname, char *osbundlereq,
+                                  char **binname)
+{
+  grub_file_t file;
+  char *buf = 0, *tagstart = 0, *ptr1 = 0, *keyptr = 0;
+  char *stringptr = 0, *ptr2 = 0;
+  grub_size_t size;
+  int depth = 0;
+  int ret;
+  int osbundlekeyfound = 0, binnamekeyfound = 0;
+  if (binname)
+    *binname = 0;
+
+  file = grub_gzfile_open (plistname, 1);
+  if (! file)
+    {
+      grub_file_close (file);
+      grub_error_push ();
+      grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", plistname);
+      return 0;
+    }
+
+  size = grub_file_size (file);
+  buf = grub_malloc (size);
+  if (! buf)
+    {
+      grub_file_close (file);
+      grub_error_push ();
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't read file %s", plistname);
+      return 0;
+    }
+  if (grub_file_read (file, buf, size) != (grub_ssize_t) (size))
+    {
+      grub_file_close (file);
+      grub_error_push ();
+      grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", plistname);
+      return 0;
+    }
+  grub_file_close (file);
+
+  /* Set the return value for the case when no OSBundleRequired tag is found. */
+  if (osbundlereq)
+    ret = grub_strword (osbundlereq, "all") || grub_strword (osbundlereq, "-");
+  else
+    ret = 1;
+
+  /* Parse plist. It's quite dirty and inextensible but does its job. */
+  for (ptr1 = buf; ptr1 < buf + size; ptr1++)
+    switch (*ptr1)
+      {
+      case '<':
+       tagstart = ptr1;
+       *ptr1 = 0;
+       if (keyptr && depth == 4
+           && grub_strcmp (keyptr, "OSBundleRequired") == 0)
+         osbundlekeyfound = 1;
+       if (keyptr && depth == 4 &&
+           grub_strcmp (keyptr, "CFBundleExecutable") == 0)
+         binnamekeyfound = 1;
+       if (stringptr && osbundlekeyfound && osbundlereq && depth == 4)
+         {
+           for (ptr2 = stringptr; *ptr2; ptr2++)
+             *ptr2 = grub_tolower (*ptr2);
+           ret = grub_strword (osbundlereq, stringptr)
+             || grub_strword (osbundlereq, "all");
+         }
+       if (stringptr && binnamekeyfound && binname && depth == 4)
+         {
+           if (*binname)
+             grub_free (*binname);
+           *binname = grub_strdup (stringptr);
+         }
+
+       *ptr1 = '<';
+       keyptr = 0;
+       stringptr = 0;
+       break;
+      case '>':
+       if (! tagstart)
+         {
+           grub_free (buf);
+           grub_error (GRUB_ERR_BAD_OS, "can't parse %s", plistname);
+           return 0;
+         }
+       *ptr1 = 0;
+       if (tagstart[1] == '?' || ptr1[-1] == '/')
+         {
+           osbundlekeyfound = 0;
+           *ptr1 = '>';
+           break;
+         }
+       if (depth == 3 && grub_strcmp (tagstart + 1, "key") == 0)
+         keyptr = ptr1 + 1;
+       if (depth == 3 && grub_strcmp (tagstart + 1, "string") == 0)
+         stringptr = ptr1 + 1;
+       else if (grub_strcmp (tagstart + 1, "/key") != 0)
+         {
+           osbundlekeyfound = 0;
+           binnamekeyfound = 0;
+         }
+       *ptr1 = '>';
+
+       if (tagstart[1] == '/')
+         depth--;
+       else
+         depth++;
+       break;
+      }
+  grub_free (buf);
+
+  return ret;
+}
+
+/* Load all loadable kexts placed under DIRNAME and matching OSBUNDLEREQUIRED */
+grub_err_t
+grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired,
+                            int maxrecursion)
+{
+  grub_device_t dev;
+  char *device_name;
+  grub_fs_t fs;
+  const char *path;
+
+  auto int load_hook (const char *filename,
+                     const struct grub_dirhook_info *info);
+  int load_hook (const char *filename, const struct grub_dirhook_info *info)
+  {
+    char *newdirname;
+    if (! info->dir)
+      return 0;
+    if (filename[0] == '.')
+      return 0;
+
+    if (grub_strlen (filename) < 5 ||
+       grub_memcmp (filename + grub_strlen (filename) - 5, ".kext", 5) != 0)
+      return 0;
+
+    newdirname
+      = grub_malloc (grub_strlen (dirname) + grub_strlen (filename) + 2);
+
+    /* It's a .kext. Try to load it. */
+    if (newdirname)
+      {
+       grub_strcpy (newdirname, dirname);
+       newdirname[grub_strlen (newdirname) + 1] = 0;
+       newdirname[grub_strlen (newdirname)] = '/';
+       grub_strcpy (newdirname + grub_strlen (newdirname), filename);
+       grub_xnu_load_kext_from_dir (newdirname, osbundlerequired,
+                                    maxrecursion);
+       if (grub_errno == GRUB_ERR_BAD_OS)
+         grub_errno = GRUB_ERR_NONE;
+       grub_free (newdirname);
+      }
+    return 0;
+  }
+
+  if (! grub_xnu_heap_size)
+    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
+
+  device_name = grub_file_get_device_name (dirname);
+  dev = grub_device_open (device_name);
+  if (dev)
+    {
+      fs = grub_fs_probe (dev);
+      path = grub_strchr (dirname, ')');
+      if (! path)
+       path = dirname;
+      else
+       path++;
+
+      if (fs)
+       (fs->dir) (dev, path, load_hook);
+      grub_device_close (dev);
+    }
+  grub_free (device_name);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Load extension DIRNAME. (extensions are directories in xnu) */
+grub_err_t
+grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired,
+                            int maxrecursion)
+{
+  grub_device_t dev;
+  char *plistname = 0;
+  char *newdirname;
+  char *newpath;
+  char *device_name;
+  grub_fs_t fs;
+  const char *path;
+  char *binsuffix;
+  int usemacos = 0;
+  grub_file_t binfile;
+
+  auto int load_hook (const char *filename,
+                     const struct grub_dirhook_info *info);
+
+  int load_hook (const char *filename, const struct grub_dirhook_info *info)
+  {
+    if (grub_strlen (filename) > 15)
+      return 0;
+    grub_strcpy (newdirname + grub_strlen (dirname) + 1, filename);
+
+    /* If the kext contains directory "Contents" all real stuff is in
+       this directory. */
+    if (info->dir && grub_strcasecmp (filename, "Contents") == 0)
+      grub_xnu_load_kext_from_dir (newdirname, osbundlerequired,
+                                  maxrecursion - 1);
+
+    /* Directory "Plugins" contains nested kexts. */
+    if (info->dir && grub_strcasecmp (filename, "Plugins") == 0)
+      grub_xnu_scan_dir_for_kexts (newdirname, osbundlerequired,
+                                  maxrecursion - 1);
+
+    /* Directory "MacOS" contains executable, otherwise executable is
+       on the top. */
+    if (info->dir && grub_strcasecmp (filename, "MacOS") == 0)
+      usemacos = 1;
+
+    /* Info.plist is the file which governs our future actions. */
+    if (! info->dir && grub_strcasecmp (filename, "Info.plist") == 0
+       && ! plistname)
+      plistname = grub_strdup (newdirname);
+    return 0;
+  }
+
+  newdirname = grub_malloc (grub_strlen (dirname) + 20);
+  if (! newdirname)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't allocate buffer");
+  grub_strcpy (newdirname, dirname);
+  newdirname[grub_strlen (dirname)] = '/';
+  newdirname[grub_strlen (dirname) + 1] = 0;
+  device_name = grub_file_get_device_name (dirname);
+  dev = grub_device_open (device_name);
+  if (dev)
+    {
+      fs = grub_fs_probe (dev);
+      path = grub_strchr (dirname, ')');
+      if (! path)
+       path = dirname;
+      else
+       path++;
+
+      newpath = grub_strchr (newdirname, ')');
+      if (! newpath)
+       newpath = newdirname;
+      else
+       newpath++;
+
+      /* Look at the directory. */
+      if (fs)
+       (fs->dir) (dev, path, load_hook);
+
+      if (plistname && grub_xnu_check_os_bundle_required
+         (plistname, osbundlerequired, &binsuffix))
+       {
+         if (binsuffix)
+           {
+             /* Open the binary. */
+             char *binname = grub_malloc (grub_strlen (dirname)
+                                          + grub_strlen (binsuffix)
+                                          + sizeof ("/MacOS/"));
+             grub_strcpy (binname, dirname);
+             if (usemacos)
+               grub_strcpy (binname + grub_strlen (binname), "/MacOS/");
+             else
+               grub_strcpy (binname + grub_strlen (binname), "/");
+             grub_strcpy (binname + grub_strlen (binname), binsuffix);
+             grub_dprintf ("xnu", "%s:%s\n", plistname, binname);
+             binfile = grub_gzfile_open (binname, 1);
+             if (! binfile)
+               grub_errno = GRUB_ERR_NONE;
+
+             /* Load the extension. */
+             grub_xnu_load_driver (plistname, binfile);
+             grub_free (binname);
+             grub_free (binsuffix);
+           }
+         else
+           {
+             grub_dprintf ("xnu", "%s:0\n", plistname);
+             grub_xnu_load_driver (plistname, 0);
+           }
+       }
+      grub_free (plistname);
+      grub_device_close (dev);
+    }
+  grub_free (device_name);
+
+  return GRUB_ERR_NONE;
+}
+
+
+static int locked=0;
+static grub_dl_t my_mod;
+
+/* Load the kext. */
+static grub_err_t
+grub_cmd_xnu_kext (grub_command_t cmd __attribute__ ((unused)),
+                  int argc, char *args[])
+{
+  grub_file_t binfile = 0;
+  if (argc == 2)
+    {
+      /* User explicitly specified plist and binary. */
+      if (grub_strcmp (args[1], "-") != 0)
+       {
+         binfile = grub_gzfile_open (args[1], 1);
+         if (! binfile)
+           {
+             grub_error (GRUB_ERR_BAD_OS, "can't open file");
+             return GRUB_ERR_NONE;
+           }
+       }
+      return grub_xnu_load_driver (grub_strcmp (args[0], "-") ? args[0] : 0,
+                                  binfile);
+    }
+
+  /* load kext normally. */
+  if (argc == 1)
+    return grub_xnu_load_kext_from_dir (args[0], 0, 10);
+
+  return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+}
+
+/* Load a directory containing kexts. */
+static grub_err_t
+grub_cmd_xnu_kextdir (grub_command_t cmd __attribute__ ((unused)),
+                     int argc, char *args[])
+{
+  if (argc != 1 && argc != 2)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "directory name required");
+
+  if (argc == 1)
+    return grub_xnu_scan_dir_for_kexts (args[0],
+                                       "console,root,local-root,network-root",
+                                       10);
+  else
+    {
+      char *osbundlerequired = grub_strdup (args[1]), *ptr;
+      grub_err_t err;
+      if (! osbundlerequired)
+       return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                          "couldn't allocate string temporary space");
+      for (ptr = osbundlerequired; *ptr; ptr++)
+       *ptr = grub_tolower (*ptr);
+      err = grub_xnu_scan_dir_for_kexts (args[0], osbundlerequired, 10);
+      grub_free (osbundlerequired);
+      return err;
+    }
+}
+
+static inline int
+hextoval (char c)
+{
+  if (c >= '0' && c <= '9')
+    return c - '0';
+  if (c >= 'a' && c <= 'z')
+    return c - 'a' + 10;
+  if (c >= 'A' && c <= 'Z')
+    return c - 'A' + 10;
+  return 0;
+}
+
+static inline void
+unescape (char *name, char *curdot, char *nextdot, int *len)
+{
+  char *ptr, *dptr;
+  dptr = name;
+  for (ptr = curdot; ptr < nextdot;)
+    if (ptr + 2 < nextdot && *ptr == '%')
+      {
+       *dptr = (hextoval (ptr[1]) << 4) | (hextoval (ptr[2]));
+       ptr += 3;
+       dptr++;
+      }
+    else
+      {
+       *dptr = *ptr;
+       ptr++;
+       dptr++;
+      }
+  *len = dptr - name;
+}
+
+grub_err_t
+grub_xnu_fill_devicetree (void)
+{
+  auto int iterate_env (struct grub_env_var *var);
+  int iterate_env (struct grub_env_var *var)
+  {
+    char *nextdot = 0, *curdot;
+    struct grub_xnu_devtree_key **curkey = &grub_xnu_devtree_root;
+    struct grub_xnu_devtree_key *curvalue;
+    char *name = 0, *data;
+    int len;
+
+    if (grub_memcmp (var->name, "XNU.DeviceTree.",
+                    sizeof ("XNU.DeviceTree.") - 1) != 0)
+      return 0;
+
+    curdot = var->name + sizeof ("XNU.DeviceTree.") - 1;
+    nextdot = grub_strchr (curdot, '.');
+    if (nextdot)
+      nextdot++;
+    while (nextdot)
+      {
+       name = grub_realloc (name, nextdot - curdot + 1);
+
+       if (!name)
+         return 1;
+
+       unescape (name, curdot, nextdot, &len);
+       name[len - 1] = 0;
+
+       curkey = &(grub_xnu_create_key (curkey, name)->first_child);
+
+       curdot = nextdot;
+       nextdot = grub_strchr (nextdot, '.');
+       if (nextdot)
+         nextdot++;
+      }
+
+    nextdot = curdot + grub_strlen (curdot) + 1;
+
+    name = grub_realloc (name, nextdot - curdot + 1);
+   
+    if (!name)
+      return 1;
+   
+    unescape (name, curdot, nextdot, &len);
+    name[len] = 0;
+
+    curvalue = grub_xnu_create_value (curkey, name);
+    grub_free (name);
+   
+    data = grub_malloc (grub_strlen (var->value) + 1);
+    if (!data)
+      return 1;
+   
+    unescape (data, var->value, var->value + grub_strlen (var->value),
+             &len);
+    curvalue->datasize = len;
+    curvalue->data = data;
+
+    return 0;
+  }
+
+  grub_env_iterate (iterate_env);
+
+  return grub_errno;
+}
+
+struct grub_video_bitmap *grub_xnu_bitmap = 0;
+grub_xnu_bitmap_mode_t grub_xnu_bitmap_mode;
+
+/* Option array indices.  */
+#define XNU_SPLASH_CMD_ARGINDEX_MODE 0
+
+static const struct grub_arg_option xnu_splash_cmd_options[] =
+  {
+    {"mode", 'm', 0, "Background image mode.", "stretch|normal",
+     ARG_TYPE_STRING},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static grub_err_t
+grub_cmd_xnu_splash (grub_extcmd_t cmd,
+                    int argc, char *args[])
+{
+  grub_err_t err;
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  if (cmd->state[XNU_SPLASH_CMD_ARGINDEX_MODE].set &&
+      grub_strcmp (cmd->state[XNU_SPLASH_CMD_ARGINDEX_MODE].arg,
+                  "stretch") == 0)
+    grub_xnu_bitmap_mode = GRUB_XNU_BITMAP_STRETCH;
+  else
+    grub_xnu_bitmap_mode = GRUB_XNU_BITMAP_CENTER;
+
+  err = grub_video_bitmap_load (&grub_xnu_bitmap, args[0]);
+  if (err)
+    grub_xnu_bitmap = 0;
+
+  return err;
+}
+
+
+#ifndef GRUB_MACHINE_EMU
+static grub_err_t
+grub_cmd_xnu_resume (grub_command_t cmd __attribute__ ((unused)),
+                    int argc, char *args[])
+{
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  return grub_xnu_resume (args[0]);
+}
+#endif
+
+void
+grub_xnu_lock ()
+{
+  if (!locked)
+    grub_dl_ref (my_mod);
+  locked = 1;
+}
+
+void
+grub_xnu_unlock ()
+{
+  if (locked)
+    grub_dl_unref (my_mod);
+  locked = 0;
+}
+
+static grub_command_t cmd_kernel64, cmd_kernel, cmd_mkext, cmd_kext;
+static grub_command_t cmd_kextdir, cmd_ramdisk, cmd_resume;
+static grub_extcmd_t cmd_splash;
+
+GRUB_MOD_INIT(xnu)
+{
+  cmd_kernel = grub_register_command ("xnu_kernel", grub_cmd_xnu_kernel, 0,
+                                     N_("Load XNU image."));
+  cmd_kernel64 = grub_register_command ("xnu_kernel64", grub_cmd_xnu_kernel64,
+                                       0, N_("Load 64-bit XNU image."));
+  cmd_mkext = grub_register_command ("xnu_mkext", grub_cmd_xnu_mkext, 0,
+                                    N_("Load XNU extension package."));
+  cmd_kext = grub_register_command ("xnu_kext", grub_cmd_xnu_kext, 0,
+                                   N_("Load XNU extension."));
+  cmd_kextdir = grub_register_command ("xnu_kextdir", grub_cmd_xnu_kextdir,
+                                      N_("DIRECTORY [OSBundleRequired]"),
+                                      N_("Load XNU extension directory."));
+  cmd_ramdisk = grub_register_command ("xnu_ramdisk", grub_cmd_xnu_ramdisk, 0,
+                                      "Load XNU ramdisk. "
+                                      "It will be seen as md0.");
+  cmd_splash = grub_register_extcmd ("xnu_splash",
+                                    grub_cmd_xnu_splash,
+                                    GRUB_COMMAND_FLAG_BOTH, 0,
+                                    N_("Load a splash image for XNU."),
+                                    xnu_splash_cmd_options);
+
+#ifndef GRUB_MACHINE_EMU
+  cmd_resume = grub_register_command ("xnu_resume", grub_cmd_xnu_resume,
+                                     0, N_("Load XNU hibernate image."));
+#endif
+
+  grub_cpu_xnu_init ();
+
+  my_mod = mod;
+}
+
+GRUB_MOD_FINI(xnu)
+{
+#ifndef GRUB_MACHINE_EMU
+  grub_unregister_command (cmd_resume);
+#endif
+  grub_unregister_command (cmd_mkext);
+  grub_unregister_command (cmd_kext);
+  grub_unregister_command (cmd_kextdir);
+  grub_unregister_command (cmd_ramdisk);
+  grub_unregister_command (cmd_kernel);
+  grub_unregister_extcmd (cmd_splash);
+  grub_unregister_command (cmd_kernel64);
+
+  grub_cpu_xnu_fini ();
+}
diff --git a/grub-core/loader/xnu_resume.c b/grub-core/loader/xnu_resume.c
new file mode 100644 (file)
index 0000000..e6620e7
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/xnu.h>
+#include <grub/cpu/xnu.h>
+#include <grub/mm.h>
+#include <grub/loader.h>
+
+static void *grub_xnu_hibernate_image;
+
+static grub_err_t
+grub_xnu_resume_unload (void)
+{
+  /* Free loaded image */
+  if (grub_xnu_hibernate_image)
+    grub_free (grub_xnu_hibernate_image);
+  grub_xnu_hibernate_image = 0;
+  grub_xnu_unlock ();
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_xnu_resume (char *imagename)
+{
+  grub_file_t file;
+  grub_size_t total_header_size;
+  struct grub_xnu_hibernate_header hibhead;
+  grub_uint8_t *buf;
+
+  grub_uint32_t codedest;
+  grub_uint32_t codesize;
+
+  file = grub_file_open (imagename);
+  if (! file)
+    return 0;
+
+  /* Read the header. */
+  if (grub_file_read (file, &hibhead, sizeof (hibhead))
+      !=sizeof (hibhead))
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_READ_ERROR,
+                        "cannot read the hibernate header");
+    }
+
+  /* Check the header. */
+  if (hibhead.magic != GRUB_XNU_HIBERNATE_MAGIC)
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_BAD_OS,
+                        "hibernate header has incorrect magic number");
+    }
+  if (hibhead.encoffset)
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_BAD_OS,
+                        "encrypted images aren't supported yet");
+    }
+
+  codedest = hibhead.launchcode_target_page;
+  codedest *= GRUB_XNU_PAGESIZE;
+  codesize = hibhead.launchcode_numpages;
+  codesize *= GRUB_XNU_PAGESIZE;
+
+  /* FIXME: check that codedest..codedest+codesize is available. */
+
+  /* Calculate total size before pages to copy. */
+  total_header_size = hibhead.extmapsize + sizeof (hibhead);
+
+  /* Unload image if any. */
+  if (grub_xnu_hibernate_image)
+    grub_free (grub_xnu_hibernate_image);
+
+  /* Try to allocate necessary space.
+     FIXME: mm isn't good enough yet to handle huge allocations.
+   */
+  grub_xnu_hibernate_image = buf = XNU_RELOCATOR (alloc) (hibhead.image_size
+                                                         + codesize
+                                                         + GRUB_XNU_PAGESIZE);
+  if (! buf)
+    {
+      grub_file_close (file);
+      return grub_errno;
+    }
+
+  /* Read code part. */
+  if (grub_file_seek (file, total_header_size) == (grub_off_t) -1
+      || grub_file_read (file, buf, codesize)
+      != (grub_ssize_t) codesize)
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_READ_ERROR, "cannot read resume image");
+    }
+
+  /* Read image. */
+  if (grub_file_seek (file, 0) == (grub_off_t) -1
+      || grub_file_read (file, buf + codesize + GRUB_XNU_PAGESIZE,
+                        hibhead.image_size)
+      != (grub_ssize_t) hibhead.image_size)
+    {
+      grub_file_close (file);
+      return grub_error (GRUB_ERR_READ_ERROR, "cannot read resume image");
+    }
+  grub_file_close (file);
+
+  /* Setup variables needed by asm helper. */
+  grub_xnu_heap_will_be_at = codedest;
+  grub_xnu_heap_start = buf;
+  grub_xnu_heap_size = codesize + GRUB_XNU_PAGESIZE + hibhead.image_size;
+  grub_xnu_stack = (codedest + hibhead.stack);
+  grub_xnu_entry_point = (codedest + hibhead.entry_point);
+  grub_xnu_arg1 = codedest + codesize + GRUB_XNU_PAGESIZE;
+
+  grub_dprintf ("xnu", "entry point 0x%x\n", codedest + hibhead.entry_point);
+  grub_dprintf ("xnu", "image at 0x%x\n",
+               codedest + codesize + GRUB_XNU_PAGESIZE);
+
+  /* We're ready now. */
+  grub_loader_set (grub_xnu_boot_resume,
+                  grub_xnu_resume_unload, 0);
+
+  /* Prevent module from unloading. */
+  grub_xnu_lock ();
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/mmap/efi/mmap.c b/grub-core/mmap/efi/mmap.c
new file mode 100644 (file)
index 0000000..316c997
--- /dev/null
@@ -0,0 +1,284 @@
+/* Mmap management. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/memory.h>
+#include <grub/err.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+#define NEXT_MEMORY_DESCRIPTOR(desc, size)      \
+  ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
+
+grub_err_t
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+                                                        grub_uint64_t,
+                                                        grub_uint32_t))
+{
+  grub_efi_uintn_t mmap_size = 0;
+  grub_efi_memory_descriptor_t *map_buf = 0;
+  grub_efi_uintn_t map_key = 0;
+  grub_efi_uintn_t desc_size = 0;
+  grub_efi_uint32_t desc_version = 0;
+  grub_efi_memory_descriptor_t *desc;
+
+  if (grub_efi_get_memory_map (&mmap_size, map_buf,
+                              &map_key, &desc_size,
+                              &desc_version) < 0)
+    return grub_errno;
+
+  map_buf = grub_malloc (mmap_size);
+  if (! map_buf)
+    return grub_errno;
+
+  if (grub_efi_get_memory_map (&mmap_size, map_buf,
+                              &map_key, &desc_size,
+                              &desc_version) <= 0)
+    {
+      grub_free (map_buf);
+      return grub_errno;
+    }
+
+  for (desc = map_buf;
+       desc < NEXT_MEMORY_DESCRIPTOR (map_buf, mmap_size);
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+    {
+      grub_dprintf ("mmap", "EFI memory region 0x%llx-0x%llx: %d\n",
+                   (unsigned long long) desc->physical_start,
+                   (unsigned long long) desc->physical_start
+                   + desc->num_pages * 4096, desc->type);
+      switch (desc->type)
+       {
+       case GRUB_EFI_RUNTIME_SERVICES_CODE:
+         hook (desc->physical_start, desc->num_pages * 4096,
+               GRUB_MACHINE_MEMORY_CODE);
+         break;
+
+       default:
+         grub_printf ("Unknown memory type %d, considering reserved\n",
+                      desc->type);
+
+       case GRUB_EFI_RESERVED_MEMORY_TYPE:
+       case GRUB_EFI_RUNTIME_SERVICES_DATA:
+       case GRUB_EFI_UNUSABLE_MEMORY:
+       case GRUB_EFI_MEMORY_MAPPED_IO:
+       case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+       case GRUB_EFI_PAL_CODE:
+         hook (desc->physical_start, desc->num_pages * 4096,
+               GRUB_MACHINE_MEMORY_RESERVED);
+         break;
+
+       case GRUB_EFI_LOADER_CODE:
+       case GRUB_EFI_LOADER_DATA:
+       case GRUB_EFI_BOOT_SERVICES_CODE:
+       case GRUB_EFI_BOOT_SERVICES_DATA:
+       case GRUB_EFI_CONVENTIONAL_MEMORY:
+         hook (desc->physical_start, desc->num_pages * 4096,
+               GRUB_MACHINE_MEMORY_AVAILABLE);
+         break;
+
+       case GRUB_EFI_ACPI_RECLAIM_MEMORY:
+         hook (desc->physical_start, desc->num_pages * 4096,
+               GRUB_MACHINE_MEMORY_ACPI);
+         break;
+
+       case GRUB_EFI_ACPI_MEMORY_NVS:
+         hook (desc->physical_start, desc->num_pages * 4096,
+               GRUB_MACHINE_MEMORY_NVS);
+         break;
+       }
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static inline grub_efi_memory_type_t
+make_efi_memtype (int type)
+{
+  switch (type)
+    {
+    case GRUB_MACHINE_MEMORY_CODE:
+      return GRUB_EFI_RUNTIME_SERVICES_CODE;
+
+      /* No way to remove a chunk of memory from EFI mmap.
+        So mark it as unusable. */
+    case GRUB_MACHINE_MEMORY_HOLE:
+
+    default:
+
+    case GRUB_MACHINE_MEMORY_RESERVED:
+      return GRUB_EFI_UNUSABLE_MEMORY;
+
+    case GRUB_MACHINE_MEMORY_AVAILABLE:
+      return GRUB_EFI_CONVENTIONAL_MEMORY;
+
+    case GRUB_MACHINE_MEMORY_ACPI:
+      return GRUB_EFI_ACPI_RECLAIM_MEMORY;
+
+    case GRUB_MACHINE_MEMORY_NVS:
+      return GRUB_EFI_ACPI_RECLAIM_MEMORY;
+
+    }
+
+}
+
+struct overlay
+{
+  struct overlay *next;
+  grub_efi_physical_address_t address;
+  grub_efi_uintn_t pages;
+  int handle;
+};
+
+static struct overlay *overlays = 0;
+static int curhandle = 1;
+
+int
+grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type)
+{
+  grub_uint64_t end = start + size;
+  grub_efi_physical_address_t address;
+  grub_efi_boot_services_t *b;
+  grub_efi_uintn_t pages;
+  grub_efi_status_t status;
+  struct overlay *curover;
+
+  curover = (struct overlay *) grub_malloc (sizeof (struct overlay));
+  if (! curover)
+    return 0;
+
+  b = grub_efi_system_table->boot_services;
+  address = start & (~0x3ffULL);
+  pages = (end - address  + 0x3ff) >> 12;
+  status = efi_call_2 (b->free_pages, address, pages);
+  if (status != GRUB_EFI_SUCCESS && status != GRUB_EFI_NOT_FOUND)
+    {
+      grub_free (curover);
+      return 0;
+    }
+  status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ADDRESS,
+                      make_efi_memtype (type), pages, &address);
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      grub_free (curover);
+      return 0;
+    }
+  curover->next = overlays;
+  curover->handle = curhandle++;
+  curover->address = address;
+  curover->pages = pages;
+  overlays = curover;
+
+  return curover->handle;
+}
+
+grub_err_t
+grub_mmap_unregister (int handle)
+{
+  struct overlay *curover, *prevover;
+  grub_efi_boot_services_t *b;
+  grub_efi_status_t status;
+
+  b = grub_efi_system_table->boot_services;
+
+
+  for (curover = overlays, prevover = 0; curover;
+       prevover = curover, curover = curover->next)
+    {
+      if (curover->handle == handle)
+       {
+         status = efi_call_2 (b->free_pages, curover->address, curover->pages);
+         if (prevover != 0)
+           prevover->next = curover->next;
+         else
+           overlays = curover->next;
+         grub_free (curover);
+         return GRUB_ERR_NONE;
+       }
+    }
+  return grub_error (GRUB_ERR_BAD_ARGUMENT, "handle %d not found", handle);
+}
+
+/* Result is always page-aligned. */
+void *
+grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)),
+                              grub_uint64_t size,
+                              int *handle, int type,
+                              int flags __attribute__ ((unused)))
+{
+  grub_efi_physical_address_t address;
+  grub_efi_boot_services_t *b;
+  grub_efi_uintn_t pages;
+  grub_efi_status_t status;
+  struct overlay *curover;
+  grub_efi_allocate_type_t atype;
+
+  curover = (struct overlay *) grub_malloc (sizeof (struct overlay));
+  if (! curover)
+    return 0;
+
+  b = grub_efi_system_table->boot_services;
+
+  address = 0xffffffff;
+
+#if GRUB_TARGET_SIZEOF_VOID_P < 8
+  /* Limit the memory access to less than 4GB for 32-bit platforms.  */
+  atype = GRUB_EFI_ALLOCATE_MAX_ADDRESS;
+#else
+  atype = GRUB_EFI_ALLOCATE_ANY_PAGES;
+#endif
+
+  pages = (size + 0x3ff) >> 12;
+  status = efi_call_4 (b->allocate_pages, atype,
+                      make_efi_memtype (type), pages, &address);
+  if (status != GRUB_EFI_SUCCESS)
+    {
+      grub_free (curover);
+      return 0;
+    }
+
+  if (address == 0)
+    {
+      /* Uggh, the address 0 was allocated... This is too annoying,
+        so reallocate another one.  */
+      address = 0xffffffff;
+      status = efi_call_4 (b->allocate_pages, atype,
+                          make_efi_memtype (type), pages, &address);
+      grub_efi_free_pages (0, pages);
+      if (status != GRUB_EFI_SUCCESS)
+       return 0;
+    }
+
+  curover->next = overlays;
+  curover->handle = curhandle++;
+  curover->address = address;
+  curover->pages = pages;
+  overlays = curover;
+  *handle = curover->handle;
+
+  return UINT_TO_PTR (curover->address);
+}
+
+void
+grub_mmap_free_and_unregister (int handle)
+{
+  grub_mmap_unregister (handle);
+}
diff --git a/grub-core/mmap/i386/mmap.c b/grub-core/mmap/i386/mmap.c
new file mode 100644 (file)
index 0000000..f6e1612
--- /dev/null
@@ -0,0 +1,98 @@
+/* Mmap management. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/memory.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+
+void *
+grub_mmap_malign_and_register (grub_uint64_t align, grub_uint64_t size,
+                              int *handle, int type, int flags)
+{
+  grub_uint64_t highestlow = 0;
+
+  auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t,
+                                      grub_uint32_t);
+  int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t rangesize,
+                                 grub_uint32_t memtype)
+  {
+    grub_uint64_t end = start + rangesize;
+    if (memtype != GRUB_MACHINE_MEMORY_AVAILABLE)
+      return 0;
+    if (end > 0x100000)
+      end = 0x100000;
+    if (end > start + size
+       && highestlow < ((end - size) - ((end - size) & (align - 1))))
+      highestlow = (end - size)  - ((end - size) & (align - 1));
+    return 0;
+  }
+
+  void *ret;
+  if (flags & GRUB_MMAP_MALLOC_LOW)
+    {
+      /* FIXME: use low-memory mm allocation once it's available. */
+      grub_mmap_iterate (find_hook);
+      ret = UINT_TO_PTR (highestlow);
+    }
+  else
+    ret = grub_memalign (align, size);
+
+  if (! ret)
+    {
+      *handle = 0;
+      return 0;
+    }
+
+  *handle = grub_mmap_register (PTR_TO_UINT64 (ret), size, type);
+  if (! *handle)
+    {
+      grub_free (ret);
+      return 0;
+    }
+
+  return ret;
+}
+
+void
+grub_mmap_free_and_unregister (int handle)
+{
+  struct grub_mmap_region *cur;
+  grub_uint64_t addr;
+
+  for (cur = grub_mmap_overlays; cur; cur = cur->next)
+    if (cur->handle == handle)
+      break;
+
+  if (! cur)
+    return;
+
+  addr = cur->start;
+
+  grub_mmap_unregister (handle);
+
+  if (addr >= 0x100000)
+    grub_free (UINT_TO_PTR (addr));
+}
+
+#endif
diff --git a/grub-core/mmap/i386/pc/mmap.c b/grub-core/mmap/i386/pc/mmap.c
new file mode 100644 (file)
index 0000000..7d5a43f
--- /dev/null
@@ -0,0 +1,216 @@
+/* Mmap management. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/memory.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/loader.h>
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+static void *hooktarget = 0;
+
+extern grub_uint8_t grub_machine_mmaphook_start;
+extern grub_uint8_t grub_machine_mmaphook_end;
+extern grub_uint8_t grub_machine_mmaphook_int12;
+extern grub_uint8_t grub_machine_mmaphook_int15;
+
+static grub_uint16_t grub_machine_mmaphook_int12offset = 0;
+static grub_uint16_t grub_machine_mmaphook_int12segment = 0;
+extern grub_uint16_t grub_machine_mmaphook_int15offset;
+extern grub_uint16_t grub_machine_mmaphook_int15segment;
+
+extern grub_uint16_t grub_machine_mmaphook_mmap_num;
+extern grub_uint16_t grub_machine_mmaphook_kblow;
+extern grub_uint16_t grub_machine_mmaphook_kbin16mb;
+extern grub_uint16_t grub_machine_mmaphook_64kbin4gb;
+
+struct grub_e820_mmap_entry
+{
+  grub_uint64_t addr;
+  grub_uint64_t len;
+  grub_uint32_t type;
+} __attribute__((packed));
+
+
+static grub_err_t
+preboot (int noreturn __attribute__ ((unused)))
+{
+  struct grub_e820_mmap_entry *hookmmap, *hookmmapcur;
+  auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t,
+                                      grub_uint32_t);
+  int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size,
+                                 grub_uint32_t type)
+  {
+    grub_dprintf ("mmap", "mmap chunk %llx-%llx:%x\n", addr, addr + size, type);
+    hookmmapcur->addr = addr;
+    hookmmapcur->len = size;
+    hookmmapcur->type = type;
+    hookmmapcur++;
+    return 0;
+  }
+
+  if (! hooktarget)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                      "no space is allocated for memory hook");
+
+  grub_dprintf ("mmap", "installing preboot handlers\n");
+
+  hookmmapcur = hookmmap = (struct grub_e820_mmap_entry *)
+    ((grub_uint8_t *) hooktarget + (&grub_machine_mmaphook_end
+                                   - &grub_machine_mmaphook_start));
+
+  grub_mmap_iterate (fill_hook);
+  grub_machine_mmaphook_mmap_num = hookmmapcur - hookmmap;
+
+  grub_machine_mmaphook_kblow = grub_mmap_get_lower () >> 10;
+  grub_machine_mmaphook_kbin16mb
+    = min (grub_mmap_get_upper (),0x3f00000ULL) >> 10;
+  grub_machine_mmaphook_64kbin4gb
+    = min (grub_mmap_get_post64 (), 0xfc000000ULL) >> 16;
+
+  /* Correct BDA. */
+  *((grub_uint16_t *) 0x413) = grub_mmap_get_lower () >> 10;
+
+  /* Save old interrupt handlers. */
+  grub_machine_mmaphook_int12offset = *((grub_uint16_t *) 0x48);
+  grub_machine_mmaphook_int12segment = *((grub_uint16_t *) 0x4a);
+  grub_machine_mmaphook_int15offset = *((grub_uint16_t *) 0x54);
+  grub_machine_mmaphook_int15segment = *((grub_uint16_t *) 0x56);
+
+  grub_dprintf ("mmap", "hooktarget = %p\n", hooktarget);
+
+  /* Install the interrupt handlers. */
+  grub_memcpy (hooktarget, &grub_machine_mmaphook_start,
+              &grub_machine_mmaphook_end - &grub_machine_mmaphook_start);
+
+  *((grub_uint16_t *) 0x4a) = PTR_TO_UINT32 (hooktarget) >> 4;
+  *((grub_uint16_t *) 0x56) = PTR_TO_UINT32 (hooktarget) >> 4;
+  *((grub_uint16_t *) 0x48) = &grub_machine_mmaphook_int12
+    - &grub_machine_mmaphook_start;
+  *((grub_uint16_t *) 0x54) = &grub_machine_mmaphook_int15
+    - &grub_machine_mmaphook_start;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+preboot_rest (void)
+{
+  /* Restore old interrupt handlers. */
+  *((grub_uint16_t *) 0x48) = grub_machine_mmaphook_int12offset;
+  *((grub_uint16_t *) 0x4a) = grub_machine_mmaphook_int12segment;
+  *((grub_uint16_t *) 0x54) = grub_machine_mmaphook_int15offset;
+  *((grub_uint16_t *) 0x56) = grub_machine_mmaphook_int15segment;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+malloc_hook (void)
+{
+  static int reentry = 0;
+  static int mmapregion = 0;
+  static int slots_available = 0;
+  int hooksize;
+  int regcount = 0;
+  auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t,
+                                       grub_uint32_t);
+  int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
+                                  grub_uint64_t size __attribute__ ((unused)),
+                                  grub_uint32_t type __attribute__ ((unused)))
+  {
+    regcount++;
+    return 0;
+  }
+
+  if (reentry)
+    return GRUB_ERR_NONE;
+
+  grub_dprintf ("mmap", "registering\n");
+
+  grub_mmap_iterate (count_hook);
+
+  /* Mapping hook itself may introduce up to 2 additional regions. */
+  regcount += 2;
+
+  if (regcount <= slots_available)
+    return GRUB_ERR_NONE;
+
+  if (mmapregion)
+    {
+      grub_mmap_free_and_unregister (mmapregion);
+      mmapregion = 0;
+      hooktarget = 0;
+    }
+
+  hooksize = &grub_machine_mmaphook_end - &grub_machine_mmaphook_start
+    + regcount * sizeof (struct grub_e820_mmap_entry);
+  /* Allocate an integer number of KiB. */
+  hooksize = ((hooksize - 1) | 0x3ff) + 1;
+  slots_available = (hooksize - (&grub_machine_mmaphook_end
+                                - &grub_machine_mmaphook_start))
+    / sizeof (struct grub_e820_mmap_entry);
+
+  reentry = 1;
+  hooktarget
+    = grub_mmap_malign_and_register (16, hooksize, &mmapregion,
+                                    GRUB_MACHINE_MEMORY_RESERVED,
+                                    GRUB_MMAP_MALLOC_LOW);
+  reentry = 0;
+
+  if (! hooktarget)
+    {
+      slots_available = 0;
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY, "no space for mmap hook");
+    }
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
+                           grub_uint64_t size __attribute__ ((unused)),
+                           int type __attribute__ ((unused)),
+                           int handle  __attribute__ ((unused)))
+{
+  grub_err_t err;
+  static void *preb_handle = 0;
+
+  err = malloc_hook ();
+  if (err)
+    return err;
+
+  if (! preb_handle)
+    {
+      grub_dprintf ("mmap", "adding preboot\n");
+      preb_handle
+       = grub_loader_register_preboot_hook (preboot, preboot_rest,
+                                            GRUB_LOADER_PREBOOT_HOOK_PRIO_MEMORY);
+      if (! preb_handle)
+       return grub_errno;
+    }
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_machine_mmap_unregister (int handle __attribute__ ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/mmap/i386/pc/mmap_helper.S b/grub-core/mmap/i386/pc/mmap_helper.S
new file mode 100644 (file)
index 0000000..7439545
--- /dev/null
@@ -0,0 +1,127 @@
+/* Mmap management. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+
+#define DS(x) ((x) - LOCAL (segstart))
+
+LOCAL (segstart):
+VARIABLE(grub_machine_mmaphook_start)
+       .code16
+VARIABLE(grub_machine_mmaphook_int12)
+       push %ds
+       push %cs
+       pop %ds
+       movw DS (LOCAL (kblow)), %ax
+       pop %ds
+       iret
+
+VARIABLE(grub_machine_mmaphook_int15)
+       pushf
+       cmpw $0xe801, %ax
+       jz LOCAL (e801)
+       cmpw $0xe820, %ax
+       jz LOCAL (e820)
+       cmpb $0x88, %ah
+       jz LOCAL (h88)
+       popf
+       /* ljmp */
+       .byte   0xea
+VARIABLE (grub_machine_mmaphook_int15offset)
+       .word   0
+VARIABLE (grub_machine_mmaphook_int15segment)
+       .word   0
+
+LOCAL (e801):
+       popf
+       push %ds
+       push %cs
+       pop %ds
+       movw DS (LOCAL (kbin16mb)), %ax
+       movw DS (LOCAL (m64kbin4gb)), %bx
+       movw %ax, %cx
+       movw %bx, %dx
+       pop %ds
+       clc
+       iret
+
+LOCAL (h88):
+       popf
+       push %ds
+       push %cs
+       pop %ds
+       movw DS (LOCAL (kbin16mb)), %ax
+       pop %ds
+       clc
+       iret
+
+LOCAL (e820):
+       popf
+       push %ds
+       push %cs
+       pop %ds
+       cmpw $20, %cx
+       jb LOCAL (errexit)
+       cmpw DS (LOCAL (mmap_num)), %bx
+       jae LOCAL (errexit)
+       cmp $0x534d4150, %edx
+       jne LOCAL (errexit)
+       push %si
+       push %di
+       movw $20, %cx
+       movw $(DS(LOCAL (mmaphook_mmap))), %si
+       mov %bx, %ax
+       imul $20, %ax
+       add %ax, %si
+       rep movsb
+       pop %di
+       pop %si
+       movl $20, %ecx
+       inc %bx
+       cmpw DS(LOCAL (mmap_num)), %bx
+       jb LOCAL (noclean)
+       xor %bx, %bx
+LOCAL (noclean):
+       mov $0x534d4150, %eax
+       pop %ds
+       clc
+       iret
+LOCAL (errexit):
+       mov $0x534d4150, %eax
+       pop %ds
+       stc
+       xor %bx, %bx
+       iret
+
+VARIABLE(grub_machine_mmaphook_mmap_num)
+LOCAL (mmap_num):
+       .word 0
+VARIABLE(grub_machine_mmaphook_kblow)
+LOCAL (kblow):
+       .word 0
+VARIABLE (grub_machine_mmaphook_kbin16mb)
+LOCAL (kbin16mb):
+       .word 0
+VARIABLE (grub_machine_mmaphook_64kbin4gb)
+LOCAL (m64kbin4gb):
+       .word 0
+LOCAL (mmaphook_mmap):
+       /* Memory map is placed just after the interrupt handlers. */
+VARIABLE(grub_machine_mmaphook_end)
+       .byte 0
diff --git a/grub-core/mmap/i386/uppermem.c b/grub-core/mmap/i386/uppermem.c
new file mode 100644 (file)
index 0000000..cd1a452
--- /dev/null
@@ -0,0 +1,85 @@
+/* Compute amount of lower and upper memory till the first hole. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/memory.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+grub_uint64_t
+grub_mmap_get_lower (void)
+{
+  grub_uint64_t lower = 0;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
+                            grub_uint32_t type)
+    {
+      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+       return 0;
+      if (addr == 0)
+       lower = size;
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+  if (lower > 0x100000)
+    lower =  0x100000;
+  return lower;
+}
+
+grub_uint64_t
+grub_mmap_get_upper (void)
+{
+  grub_uint64_t upper = 0;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
+                            grub_uint32_t type)
+    {
+      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+       return 0;
+      if (addr <= 0x100000 && addr + size > 0x100000)
+       upper = addr + size - 0x100000;
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+  return upper;
+}
+
+/* Count the continuous bytes after 64 MiB. */
+grub_uint64_t
+grub_mmap_get_post64 (void)
+{
+  grub_uint64_t post64 = 0;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
+                            grub_uint32_t type)
+    {
+      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+       return 0;
+      if (addr <= 0x4000000 && addr + size > 0x4000000)
+       post64 = addr + size - 0x4000000;
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+  return post64;
+}
diff --git a/grub-core/mmap/mips/yeeloong/uppermem.c b/grub-core/mmap/mips/yeeloong/uppermem.c
new file mode 100644 (file)
index 0000000..3c5f814
--- /dev/null
@@ -0,0 +1,66 @@
+/* Compute amount of lower and upper memory till the first hole. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/memory.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/machine/memory.h>
+
+grub_uint64_t
+grub_mmap_get_lower (void)
+{
+  grub_uint64_t lower = 0;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
+                            grub_uint32_t type)
+    {
+      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+       return 0;
+      if (addr == 0)
+       lower = size;
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+  if (lower > GRUB_ARCH_LOWMEMMAXSIZE)
+    lower = GRUB_ARCH_LOWMEMMAXSIZE;
+  return lower;
+}
+
+grub_uint64_t
+grub_mmap_get_upper (void)
+{
+  grub_uint64_t upper = 0;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
+                            grub_uint32_t type)
+    {
+      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+       return 0;
+      if (addr <= GRUB_ARCH_HIGHMEMPSTART && addr + size
+         > GRUB_ARCH_HIGHMEMPSTART)
+       upper = addr + size - GRUB_ARCH_HIGHMEMPSTART;
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+  return upper;
+}
diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c
new file mode 100644 (file)
index 0000000..a1afc8b
--- /dev/null
@@ -0,0 +1,426 @@
+/* Mmap management. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/memory.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/command.h>
+#include <grub/dl.h>
+#include <grub/i18n.h>
+
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+
+struct grub_mmap_region *grub_mmap_overlays = 0;
+static int curhandle = 1;
+
+#endif
+
+grub_err_t
+grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+                                                grub_uint64_t, grub_uint32_t))
+{
+
+  /* This function resolves overlapping regions and sorts the memory map.
+     It uses scanline (sweeping) algorithm.
+  */
+  /* If same page is used by multiple types it's resolved
+     according to priority:
+     1 - free memory
+     2 - memory usable by firmware-aware code
+     3 - unusable memory
+     4 - a range deliberately empty
+  */
+  int priority[GRUB_MACHINE_MEMORY_MAX_TYPE + 2] =
+    {
+#ifdef GRUB_MACHINE_MEMORY_AVAILABLE
+      [GRUB_MACHINE_MEMORY_AVAILABLE] = 1,
+#endif
+#if defined (GRUB_MACHINE_MEMORY_RESERVED) && GRUB_MACHINE_MEMORY_RESERVED != GRUB_MACHINE_MEMORY_HOLE
+      [GRUB_MACHINE_MEMORY_RESERVED] = 3,
+#endif
+#ifdef GRUB_MACHINE_MEMORY_ACPI
+      [GRUB_MACHINE_MEMORY_ACPI] = 2,
+#endif
+#ifdef GRUB_MACHINE_MEMORY_CODE
+      [GRUB_MACHINE_MEMORY_CODE] = 3,
+#endif
+#ifdef GRUB_MACHINE_MEMORY_NVS
+      [GRUB_MACHINE_MEMORY_NVS] = 3,
+#endif
+      [GRUB_MACHINE_MEMORY_HOLE] = 4,
+    };
+
+  int i, k, done;
+
+  /* Scanline events. */
+  struct grub_mmap_scan
+  {
+    /* At which memory address. */
+    grub_uint64_t pos;
+    /* 0 = region starts, 1 = region ends. */
+    int type;
+    /* Which type of memory region? */
+    int memtype;
+  };
+  struct grub_mmap_scan *scanline_events;
+  struct grub_mmap_scan t;
+
+  /* Previous scanline event. */
+  grub_uint64_t lastaddr;
+  int lasttype;
+  /* Current scanline event. */
+  int curtype;
+  /* How many regions of given type overlap at current location? */
+  int present[GRUB_MACHINE_MEMORY_MAX_TYPE + 2];
+  /* Number of mmap chunks. */
+  int mmap_num;
+
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+  struct grub_mmap_region *cur;
+#endif
+
+  auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t,
+                                       grub_uint32_t);
+  int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
+                                  grub_uint64_t size __attribute__ ((unused)),
+                                  grub_uint32_t type __attribute__ ((unused)))
+  {
+    mmap_num++;
+    return 0;
+  }
+
+  auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t,
+                                       grub_uint32_t);
+  int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr,
+                                 grub_uint64_t size,
+                                 grub_uint32_t type)
+  {
+    scanline_events[i].pos = addr;
+    scanline_events[i].type = 0;
+    if (type <= GRUB_MACHINE_MEMORY_MAX_TYPE && priority[type])
+      scanline_events[i].memtype = type;
+    else
+      {
+       grub_dprintf ("mmap", "Unknown memory type %d. Assuming unusable\n",
+                     type);
+       scanline_events[i].memtype = GRUB_MACHINE_MEMORY_RESERVED;
+      }
+    i++;
+
+    scanline_events[i].pos = addr + size;
+    scanline_events[i].type = 1;
+    scanline_events[i].memtype = scanline_events[i - 1].memtype;
+    i++;
+
+    return 0;
+  }
+
+  mmap_num = 0;
+
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+  for (cur = grub_mmap_overlays; cur; cur = cur->next)
+    mmap_num++;
+#endif
+
+  grub_machine_mmap_iterate (count_hook);
+
+  /* Initialize variables. */
+  grub_memset (present, 0, sizeof (present));
+  scanline_events = (struct grub_mmap_scan *)
+    grub_malloc (sizeof (struct grub_mmap_scan) * 2 * mmap_num);
+
+  if (! scanline_events)
+    {
+      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                        "couldn't allocate space for new memory map");
+    }
+
+  i = 0;
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+  /* Register scanline events. */
+  for (cur = grub_mmap_overlays; cur; cur = cur->next)
+    {
+      scanline_events[i].pos = cur->start;
+      scanline_events[i].type = 0;
+      if (cur->type == GRUB_MACHINE_MEMORY_HOLE
+         || (cur->type >= 0 && cur->type <= GRUB_MACHINE_MEMORY_MAX_TYPE
+             && priority[cur->type]))
+       scanline_events[i].memtype = cur->type;
+      else
+       scanline_events[i].memtype = GRUB_MACHINE_MEMORY_RESERVED;
+      i++;
+
+      scanline_events[i].pos = cur->end;
+      scanline_events[i].type = 1;
+      scanline_events[i].memtype = scanline_events[i - 1].memtype;
+      i++;
+    }
+#endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */
+
+  grub_machine_mmap_iterate (fill_hook);
+
+  /* Primitive bubble sort. It has complexity O(n^2) but since we're
+     unlikely to have more than 100 chunks it's probably one of the
+     fastest for one purpose. */
+  done = 1;
+  while (done)
+    {
+      done = 0;
+      for (i = 0; i < 2 * mmap_num - 1; i++)
+       if (scanline_events[i + 1].pos < scanline_events[i].pos
+           || (scanline_events[i + 1].pos == scanline_events[i].pos
+               && scanline_events[i + 1].type == 0
+               && scanline_events[i].type == 1))
+         {
+           t = scanline_events[i + 1];
+           scanline_events[i + 1] = scanline_events[i];
+           scanline_events[i] = t;
+           done = 1;
+         }
+    }
+
+  lastaddr = scanline_events[0].pos;
+  lasttype = scanline_events[0].memtype;
+  for (i = 0; i < 2 * mmap_num; i++)
+    {
+      /* Process event. */
+      if (scanline_events[i].type)
+       present[scanline_events[i].memtype]--;
+      else
+       present[scanline_events[i].memtype]++;
+
+      /* Determine current region type. */
+      curtype = -1;
+      for (k = 0; k <= GRUB_MACHINE_MEMORY_MAX_TYPE + 1; k++)
+       if (present[k] && (curtype == -1 || priority[k] > priority[curtype]))
+         curtype = k;
+
+      /* Announce region to the hook if necessary. */
+      if ((curtype == -1 || curtype != lasttype)
+         && lastaddr != scanline_events[i].pos
+         && lasttype != -1
+         && lasttype != GRUB_MACHINE_MEMORY_HOLE
+         && hook (lastaddr, scanline_events[i].pos - lastaddr, lasttype))
+       {
+         grub_free (scanline_events);
+         return GRUB_ERR_NONE;
+       }
+
+      /* Update last values if necessary. */
+      if (curtype == -1 || curtype != lasttype)
+       {
+         lasttype = curtype;
+         lastaddr = scanline_events[i].pos;
+       }
+    }
+
+  grub_free (scanline_events);
+  return GRUB_ERR_NONE;
+}
+
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+int
+grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type)
+{
+  struct grub_mmap_region *cur;
+
+  grub_dprintf ("mmap", "registering\n");
+
+  cur = (struct grub_mmap_region *)
+    grub_malloc (sizeof (struct grub_mmap_region));
+  if (! cur)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                 "couldn't allocate memory map overlay");
+      return 0;
+    }
+
+  cur->next = grub_mmap_overlays;
+  cur->start = start;
+  cur->end = start + size;
+  cur->type = type;
+  cur->handle = curhandle++;
+  grub_mmap_overlays = cur;
+
+  if (grub_machine_mmap_register (start, size, type, curhandle))
+    {
+      grub_mmap_overlays = cur->next;
+      grub_free (cur);
+      return 0;
+    }
+
+  return cur->handle;
+}
+
+grub_err_t
+grub_mmap_unregister (int handle)
+{
+  struct grub_mmap_region *cur, *prev;
+
+  for (cur = grub_mmap_overlays, prev = 0; cur; prev= cur, cur = cur->next)
+    if (handle == cur->handle)
+      {
+       grub_err_t err;
+       if ((err = grub_machine_mmap_unregister (handle)))
+         return err;
+
+       if (prev)
+         prev->next = cur->next;
+       else
+         grub_mmap_overlays = cur->next;
+       grub_free (cur);
+       return GRUB_ERR_NONE;
+      }
+  return grub_error (GRUB_ERR_BAD_ARGUMENT, "mmap overlay not found");
+}
+
+#endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */
+
+#define CHUNK_SIZE     0x400
+
+static inline grub_uint64_t
+fill_mask (grub_uint64_t addr, grub_uint64_t mask, grub_uint64_t iterator)
+{
+  int i, j;
+  grub_uint64_t ret = (addr & mask);
+
+  /* Find first fixed bit. */
+  for (i = 0; i < 64; i++)
+    if ((mask & (1ULL << i)) != 0)
+      break;
+  j = 0;
+  for (; i < 64; i++)
+    if ((mask & (1ULL << i)) == 0)
+      {
+       if ((iterator & (1ULL << j)) != 0)
+         ret |= 1ULL << i;
+       j++;
+      }
+  return ret;
+}
+
+static grub_err_t
+grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)),
+                int argc, char **args)
+{
+  char * str;
+  grub_uint64_t badaddr, badmask;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr,
+                            grub_uint64_t size,
+                            grub_uint32_t type __attribute__ ((unused)))
+  {
+    grub_uint64_t iterator, low, high, cur;
+    int tail, var;
+    int i;
+    grub_dprintf ("badram", "hook %llx+%llx\n", (unsigned long long) addr,
+                 (unsigned long long) size);
+
+    /* How many trailing zeros? */
+    for (tail = 0; ! (badmask & (1ULL << tail)); tail++);
+
+    /* How many zeros in mask? */
+    var = 0;
+    for (i = 0; i < 64; i++)
+      if (! (badmask & (1ULL << i)))
+       var++;
+
+    if (fill_mask (badaddr, badmask, 0) >= addr)
+      iterator = 0;
+    else
+      {
+       low = 0;
+       high = ~0ULL;
+       /* Find starting value. Keep low and high such that
+          fill_mask (low) < addr and fill_mask (high) >= addr;
+       */
+       while (high - low > 1)
+         {
+           cur = (low + high) / 2;
+           if (fill_mask (badaddr, badmask, cur) >= addr)
+             high = cur;
+           else
+             low = cur;
+         }
+       iterator = high;
+      }
+
+    for (; iterator < (1ULL << (var - tail))
+          && (cur = fill_mask (badaddr, badmask, iterator)) < addr + size;
+        iterator++)
+      {
+       grub_dprintf ("badram", "%llx (size %llx) is a badram range\n",
+                     (unsigned long long) cur, (1ULL << tail));
+       grub_mmap_register (cur, (1ULL << tail), GRUB_MACHINE_MEMORY_HOLE);
+      }
+    return 0;
+  }
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "badram string required");
+
+  grub_dprintf ("badram", "executing badram\n");
+
+  str = args[0];
+
+  while (1)
+    {
+      /* Parse address and mask.  */
+      badaddr = grub_strtoull (str, &str, 16);
+      if (*str == ',')
+       str++;
+      badmask = grub_strtoull (str, &str, 16);
+      if (*str == ',')
+       str++;
+
+      if (grub_errno == GRUB_ERR_BAD_NUMBER)
+       {
+         grub_errno = 0;
+         return GRUB_ERR_NONE;
+       }
+
+      /* When part of a page is tainted, we discard the whole of it.  There's
+        no point in providing sub-page chunks.  */
+      badmask &= ~(CHUNK_SIZE - 1);
+
+      grub_dprintf ("badram", "badram %llx:%llx\n",
+                   (unsigned long long) badaddr, (unsigned long long) badmask);
+
+      grub_mmap_iterate (hook);
+    }
+}
+
+static grub_command_t cmd;
+
+\f
+GRUB_MOD_INIT(mmap)
+{
+  cmd = grub_register_command ("badram", grub_cmd_badram,
+                              N_("ADDR1,MASK1[,ADDR2,MASK2[,...]]"),
+                              N_("Declare memory regions as badram."));
+}
+
+GRUB_MOD_FINI(mmap)
+{
+  grub_unregister_command (cmd);
+}
+
diff --git a/grub-core/modules.def b/grub-core/modules.def
new file mode 100644 (file)
index 0000000..ae3ede5
--- /dev/null
@@ -0,0 +1,1592 @@
+AutoGen definitions Makefile.tpl;
+
+kernel = {
+  name = kernel;
+
+  emu_ldflags              = '-Wl,-r';
+  x86_efi_ldflags          = '-Wl,-r';
+  i386_pc_ldflags          = '-Wl,-Ttext=$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
+  i386_coreboot_ldflags    = '-Wl,-Ttext=$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
+  i386_qemu_ldflags        = '-Wl,-Ttext=$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
+  i386_ieee1275_ldflags    = '-Wl,-Ttext=$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
+  mips_yeeloong_ldflags    = '-Wl,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
+  powerpc_ieee1275_ldflags = '-Wl,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
+
+  mips_yeeloong_cppflags = '-DUSE_ASCII_FAILBACK';
+  i386_qemu_cppflags     = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
+  i386_qemu_ccasflags    = '-DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
+
+  mips_ldadd = '-lgcc';
+  powerpc_ldadd = '-lgcc';
+  sparc64_ldadd = '-lgcc';
+
+  nonemu_nodist = symlist.c;
+
+  shared = kern/command.c;
+  shared = kern/corecmd.c;
+  shared = kern/device.c;
+  shared = kern/disk.c;
+  shared = kern/dl.c;
+  shared = kern/env.c;
+  shared = kern/err.c;
+  shared = kern/file.c;
+  shared = kern/fs.c;
+  shared = kern/handler.c;
+  shared = kern/list.c;
+  shared = kern/main.c;
+  shared = kern/misc.c;
+  shared = kern/parser.c;
+  shared = kern/partition.c;
+  shared = kern/rescue_parser.c;
+  shared = kern/rescue_reader.c;
+  shared = kern/term.c;
+
+  i386_pc = kern/i386/pc/startup.S;
+  i386_pc = kern/i386/misc.S;
+  i386_pc = kern/mm.c;
+  i386_pc = kern/time.c;
+  i386_pc = kern/i386/dl.c;
+  i386_pc = kern/i386/pc/init.c;
+  i386_pc = kern/i386/pc/mmap.c;
+  i386_pc = kern/i386/tsc.c;
+  i386_pc = kern/i386/pit.c;
+  i386_pc = kern/generic/rtc_get_time_ms.c;
+  i386_pc = kern/generic/millisleep.c;
+  i386_pc = term/i386/pc/console.c;
+  i386_pc = term/i386/vga_common.c;
+
+  i386_efi = kern/i386/efi/startup.S;
+  i386_efi = kern/mm.c;
+  i386_efi = kern/i386/dl.c;
+  i386_efi = kern/i386/efi/init.c;
+  i386_efi = kern/efi/efi.c;
+  i386_efi = kern/efi/init.c;
+  i386_efi = kern/efi/mm.c;
+  i386_efi = kern/time.c;
+  i386_efi = kern/i386/tsc.c;
+  i386_efi = kern/i386/pit.c;
+  i386_efi = kern/generic/rtc_get_time_ms.c;
+  i386_efi = kern/generic/millisleep.c;
+  i386_efi = term/efi/console.c;
+  i386_efi = disk/efi/efidisk.c;
+
+  i386_coreboot = kern/i386/coreboot/startup.S;
+  i386_coreboot = kern/i386/misc.S;
+  i386_coreboot = kern/i386/coreboot/init.c;
+  i386_coreboot = kern/i386/coreboot/mmap.c;
+  i386_coreboot = kern/i386/halt.c;
+  i386_coreboot = kern/mm.c;
+  i386_coreboot = kern/time.c;
+  i386_coreboot = kern/i386/dl.c;
+  i386_coreboot = kern/i386/tsc.c;
+  i386_coreboot = kern/i386/pit.c;
+  i386_coreboot = kern/generic/rtc_get_time_ms.c;
+  i386_coreboot = kern/generic/millisleep.c;
+  i386_coreboot = term/i386/pc/vga_text.c;
+  i386_coreboot = term/i386/vga_common.c;
+
+  i386_qemu = kern/i386/qemu/startup.S;
+  i386_qemu = kern/i386/misc.S;
+  i386_qemu = kern/i386/coreboot/init.c;
+  i386_qemu = kern/i386/qemu/mmap.c;
+  i386_qemu = kern/i386/halt.c;
+  i386_qemu = kern/mm.c;
+  i386_qemu = kern/time.c;
+  i386_qemu = kern/i386/dl.c;
+  i386_qemu = kern/i386/tsc.c;
+  i386_qemu = kern/i386/pit.c;
+  i386_qemu = kern/generic/rtc_get_time_ms.c;
+  i386_qemu = kern/generic/millisleep.c;
+  i386_qemu = term/i386/pc/vga_text.c;
+  i386_qemu = term/i386/vga_common.c;
+
+  i386_ieee1275 = kern/i386/ieee1275/startup.S;
+  i386_ieee1275 = kern/i386/misc.S;
+  i386_ieee1275 = kern/i386/ieee1275/init.c;
+  i386_ieee1275 = kern/ieee1275/init.c;
+  i386_ieee1275 = kern/ieee1275/mmap.c;
+  i386_ieee1275 = kern/ieee1275/cmain.c;
+  i386_ieee1275 = kern/ieee1275/openfw.c;
+  i386_ieee1275 = kern/mm.c;
+  i386_ieee1275 = kern/i386/dl.c;
+  i386_ieee1275 = kern/time.c;
+  i386_ieee1275 = kern/generic/millisleep.c;
+  i386_ieee1275 = kern/ieee1275/ieee1275.c;
+  i386_ieee1275 = term/ieee1275/ofconsole.c;
+  i386_ieee1275 = disk/ieee1275/ofdisk.c;
+
+  x86_64_efi = kern/x86_64/efi/startup.S;
+  x86_64_efi = kern/x86_64/efi/callwrap.S;
+  x86_64_efi = kern/mm.c;
+  x86_64_efi = kern/x86_64/dl.c;
+  x86_64_efi = kern/i386/efi/init.c;
+  x86_64_efi = kern/efi/efi.c;
+  x86_64_efi = kern/efi/init.c;
+  x86_64_efi = kern/efi/mm.c;
+  x86_64_efi = kern/time.c;
+  x86_64_efi = kern/i386/tsc.c;
+  x86_64_efi = kern/i386/pit.c;
+  x86_64_efi = kern/generic/millisleep.c;
+  x86_64_efi = kern/generic/rtc_get_time_ms.c;
+  x86_64_efi = term/efi/console.c;
+  x86_64_efi = disk/efi/efidisk.c;
+
+  mips_yeeloong = kern/mips/startup.S;
+  mips_yeeloong = kern/mips/init.c;
+  mips_yeeloong = kern/mips/yeeloong/init.c;
+  mips_yeeloong = kern/mm.c;
+  mips_yeeloong = kern/mips/dl.c;
+  mips_yeeloong = kern/generic/millisleep.c;
+  mips_yeeloong = kern/generic/rtc_get_time_ms.c;
+  mips_yeeloong = kern/time.c;
+  mips_yeeloong = kern/mips/cache.S;
+  mips_yeeloong = io/bufio.c;
+  mips_yeeloong = lib/arg.c;
+  mips_yeeloong = commands/extcmd.c;
+  mips_yeeloong = bus/pci.c;
+  mips_yeeloong = bus/bonito.c;
+  mips_yeeloong = font/font_cmd.c;
+  mips_yeeloong = font/font.c;
+  mips_yeeloong = term/at_keyboard.c;
+  mips_yeeloong = term/gfxterm.c;
+  mips_yeeloong = video/video.c;
+  mips_yeeloong = video/fb/video_fb.c;
+  mips_yeeloong = video/fb/fbblit.c;
+  mips_yeeloong = video/fb/fbfill.c;
+  mips_yeeloong = video/fb/fbutil.c;
+  mips_yeeloong = video/bitmap.c;
+  mips_yeeloong = video/bitmap_scale.c;
+  mips_yeeloong = video/sm712.c;
+
+  powerpc_ieee1275 = kern/powerpc/ieee1275/startup.S;
+  powerpc_ieee1275 = kern/ieee1275/cmain.c;
+  powerpc_ieee1275 = kern/ieee1275/ieee1275.c;
+  powerpc_ieee1275 = kern/mm.c;
+  powerpc_ieee1275 = kern/ieee1275/init.c;
+  powerpc_ieee1275 = kern/ieee1275/mmap.c;
+  powerpc_ieee1275 = kern/ieee1275/openfw.c;
+  powerpc_ieee1275 = kern/powerpc/dl.c;
+  powerpc_ieee1275 = kern/generic/millisleep.c;
+  powerpc_ieee1275 = kern/time.c;
+  powerpc_ieee1275 = kern/powerpc/cache.S;
+  powerpc_ieee1275 = term/ieee1275/ofconsole.c;
+  powerpc_ieee1275 = disk/ieee1275/ofdisk.c;
+
+  sparc64_ieee1275 = kern/sparc64/ieee1275/crt0.S;
+  sparc64_ieee1275 = kern/ieee1275/cmain.c;
+  sparc64_ieee1275 = kern/ieee1275/ieee1275.c;
+  sparc64_ieee1275 = kern/mm.c;
+  sparc64_ieee1275 = kern/sparc64/ieee1275/ieee1275.c;
+  sparc64_ieee1275 = kern/sparc64/ieee1275/init.c;
+  sparc64_ieee1275 = kern/ieee1275/mmap.c;
+  sparc64_ieee1275 = kern/ieee1275/openfw.c;
+  sparc64_ieee1275 = kern/sparc64/dl.c;
+  sparc64_ieee1275 = kern/generic/millisleep.c;
+  sparc64_ieee1275 = kern/time.c;
+  sparc64_ieee1275 = kern/sparc64/cache.S;
+  sparc64_ieee1275 = disk/ieee1275/ofdisk.c;
+  sparc64_ieee1275 = term/ieee1275/ofconsole.c;
+
+  emu = kern/emu/misc.c;
+  emu = kern/emu/getroot.c;
+  emu = kern/emu/time.c;
+  emu = kern/emu/hostdisk.c;
+  emu = kern/emu/hostfs.c;
+  emu = kern/emu/console.c;
+  emu = disk/host.c;
+
+  image_nostrip = { emu; };
+  image_strip_keep_kernel = { i386_efi; x86_64_efi; };
+  image_strip = { powerpc_ieee1275; i386_coreboot; i386_ieee1275; };
+  image_strip_macho2img = { mips_yeeloong; i386_pc; i386_qemu; sparc64_ieee1275; };
+};
+
+program = {
+  name = grub-emu;
+  mansection = 1;
+
+  source = kern/emu/main.c;
+  source = kern/emu/dummy/dl.c;
+  source = kern/emu/dummy/symlist.c;
+  source = gnulib/progname.c;
+
+  nodist = grub_emu_init.c;
+
+  cflags = '$(CFLAGS_GNULIB)';
+  cppflags = '$(CPPFLAGS_GNULIB)';
+
+  ldadd = kernel.exec;
+  ldadd = '$(MODULE_FILES)';
+  ldadd = '$(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS)';
+
+  emu;
+};
+
+program = {
+  name = grub-emu-lite;
+
+  source = kern/emu/main.c;
+  source = kern/emu/lite.c;
+  source = kern/emu/dl.c;
+  source = kern/emu/cache.S;
+  source = gnulib/progname.c;
+  nodist = symlist.c;
+
+  cflags = '$(CFLAGS_GNULIB)';
+  cppflags = '$(CPPFLAGS_GNULIB)';
+
+  ldadd = kernel.exec;
+  ldadd = '$(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS)';
+
+  emu;
+};
+
+module = {
+  name = trig;
+  nodist = trigtables.c;
+  common;
+};
+
+image = {
+  name = boot;
+  i386_pc = boot/i386/pc/boot.S;
+  i386_pc_ldflags = "-Wl,-Ttext=0x7C00";
+
+  i386_qemu = boot/i386/qemu/boot.S;
+  i386_qemu_ldflags = '-Wl,-Ttext,$(GRUB_BOOT_MACHINE_LINK_ADDR)';
+  i386_qemu_ccasflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
+
+  sparc64_ieee1275 = boot/sparc64/ieee1275/boot.S;
+  sparc64_ieee1275_format = a.out-sunos-big;
+  sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x4000';
+};
+
+image = {
+  name = cdboot;
+  source = boot/i386/pc/cdboot.S;
+  ldflags = "-Wl,-Ttext=0x7C00";
+
+  i386_pc;
+};
+
+image = {
+  name = pxeboot;
+  source = boot/i386/pc/pxeboot.S;
+  ldflags = '-Wl,-Ttext=0x7C00';
+
+  i386_pc;
+};
+
+image = {
+  name = diskboot;
+  i386_pc = boot/i386/pc/diskboot.S;
+  i386_pc_ldflags = '-Wl,-Ttext=0x8000';
+
+  sparc64_ieee1275 = boot/sparc64/ieee1275/diskboot.S;
+  sparc64_ieee1275_ldflags = '-Wl,-Ttext=0x4200';
+};
+
+image = {
+  name = lnxboot;
+  source = boot/i386/pc/lnxboot.S;
+  ldflags = '-Wl,-Ttext=0x6000';
+
+  i386_pc;
+};
+
+module = {
+  name = libusb;
+  source = bus/usb/emu/usb.c;
+  emu;
+  enable = COND_GRUB_EMU_USB;
+};
+
+module = {
+  name = pci;
+  source = bus/emu/pci.c;
+  source = commands/lspci.c;
+  emu;
+  enable = COND_GRUB_EMU_PCI;
+};
+
+module = {
+  name = usb;
+  source = bus/usb/usb.c;
+  source = bus/usb/usbtrans.c;
+  source = bus/usb/usbhub.c;
+  i386;
+};
+
+module = {
+  name = usb;
+  source = bus/usb/usb.c;
+  emu;
+  enable = COND_GRUB_EMU_USB;
+};
+
+module = {
+  name = uhci;
+  source = bus/usb/uhci.c;
+  x86;
+};
+
+module = {
+  name = ohci;
+  source = bus/usb/ohci.c;
+  x86;
+};
+
+module = {
+  name = pci;
+  source = bus/pci.c;
+  x86;
+};
+
+library = {
+  name = libgnulib.a;
+  source = gnulib/regex.c;
+  cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
+  cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)';
+  common;
+};
+
+module = {
+  name = iorw;
+  source = commands/iorw.c;
+  i386;
+};
+
+module = {
+  name = regexp;
+  source = commands/regexp.c;
+  ldadd = libgnulib.a;
+  cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
+  cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)';
+  common;
+};
+
+module = {
+  name = acpi;
+
+  x86_efi = commands/acpi.c;
+  x86_efi = commands/efi/acpi.c;
+
+  i386_pc = commands/acpi.c;
+  i386_pc = commands/i386/pc/acpi.c;
+};
+
+module = {
+  common;
+  name = blocklist;
+  source = commands/blocklist.c;
+};
+
+module = {
+  common;
+  name = boot;
+  source = commands/boot.c;
+
+  i386_pc = commands/boot.c;
+  i386_pc = lib/i386/pc/biosnum.c;
+};
+
+module = {
+  common;
+  name = cat;
+  source = commands/cat.c;
+};
+
+module = {
+  common;
+  name = cmp;
+  source = commands/cmp.c;
+};
+
+module = {
+  common;
+  name = configfile;
+  source = commands/configfile.c;
+};
+
+module = {
+  name = cpuid;
+  source = commands/i386/cpuid.c;
+
+  x86;
+};
+
+module = {
+  common;
+  name = crc;
+  source = commands/crc.c;
+  source = lib/crc.c;
+};
+
+module = {
+  common;
+  name = date;
+  source = commands/date.c;
+
+  x86;
+  mips;
+};
+
+module = {
+  name = drivemap;
+
+  i386_pc = commands/i386/pc/drivemap.c;
+  i386_pc = commands/i386/pc/drivemap_int13h.S;
+};
+
+module = {
+  common;
+  name = echo;
+  source = commands/echo.c;
+};
+
+module = {
+  common;
+  name = extcmd;
+  source = commands/extcmd.c;
+  source = lib/arg.c;
+};
+
+module = {
+  name = fixvideo;
+  x86_efi = commands/efi/fixvideo.c;
+};
+
+module = {
+  common;
+  name = gptsync;
+  source = commands/gptsync.c;
+};
+
+module = {
+  name = halt;
+  source = commands/halt.c;
+
+  i386_pc = commands/i386/pc/halt.c;
+  emu;
+  x86;
+  sparc64;
+  powerpc;
+};
+
+module = {
+  common;
+  name = handler;
+  source = commands/handler.c;
+};
+
+module = {
+  common;
+  name = hashsum;
+  source = commands/hashsum.c;
+};
+
+module = {
+  name = hdparm;
+  source = commands/hdparm.c;
+  source = lib/hexdump.c;
+
+  i386_pc;
+};
+
+module = {
+  common;
+  name = help;
+  source = commands/help.c;
+};
+
+module = {
+  common;
+  name = hexdump;
+  source = commands/hexdump.c;
+  source = lib/hexdump.c;
+};
+
+module = {
+  common;
+  name = keystatus;
+  source = commands/keystatus.c;
+};
+
+module = {
+  name = loadbios;
+  x86_efi = commands/efi/loadbios.c;
+};
+
+module = {
+  common;
+  name = loadenv;
+  source = commands/loadenv.c;
+  source = lib/envblk.c;
+};
+
+module = {
+  common;
+  name = ls;
+  source = commands/ls.c;
+};
+
+module = {
+  common;
+  name = lsmmap;
+  source = commands/lsmmap.c;
+
+  i386_pc;
+  i386_qemu;
+  i386_coreboot;
+  i386_ieee1275;
+  mips_yeeloong;
+  powerpc_ieee1275;
+};
+
+module = {
+  name = lspci;
+  source = commands/lspci.c;
+
+  x86;
+  mips;
+};
+
+module = {
+  common;
+  name = memrw;
+  source = commands/memrw.c;
+};
+
+module = {
+  common;
+  name = minicmd;
+  source = commands/minicmd.c;
+};
+
+module = {
+  common;
+  name = parttool;
+  source = commands/parttool.c;
+};
+
+module = {
+  common;
+  name = password;
+  source = commands/password.c;
+};
+
+module = {
+  common;
+  name = password_pbkdf2;
+  source = commands/password_pbkdf2.c;
+};
+
+module = {
+  name = play;
+  source = commands/i386/pc/play.c;
+  i386;
+};
+
+module = {
+  common;
+  name = probe;
+  source = commands/probe.c;
+};
+
+module = {
+  name = pxecmd;
+  i386_pc = commands/i386/pc/pxecmd.c;
+};
+
+module = {
+  common;
+  name = read;
+  source = commands/read.c;
+};
+
+module = {
+  common;
+  name = reboot;
+  source = commands/reboot.c;
+
+  x86; powerpc; sparc64;
+};
+
+module = {
+  common;
+  name = search;
+  source = commands/search_wrap.c;
+};
+
+module = {
+  common;
+  name = search_fs_file;
+  source = commands/search_file.c;
+};
+
+module = {
+  common;
+  name = search_fs_uuid;
+  source = commands/search_uuid.c;
+};
+
+module = {
+  common;
+  name = search_label;
+  source = commands/search_label.c;
+};
+
+module = {
+  name = setpci;
+  source = commands/setpci.c;
+
+  x86;
+};
+
+module = {
+  common;
+  name = sleep;
+  source = commands/sleep.c;
+};
+
+module = {
+  name = suspend;
+  source = commands/ieee1275/suspend.c;
+  i386_ieee1275;
+  powerpc_ieee1275;
+};
+
+module = {
+  common;
+  name = terminal;
+  source = commands/terminal.c;
+};
+
+module = {
+  common;
+  name = test;
+  source = commands/test.c;
+};
+
+module = {
+  common;
+  name = true;
+  source = commands/true.c;
+};
+
+module = {
+  name = usbtest;
+  source = commands/usbtest.c;
+  i386_pc;
+};
+
+module = {
+  name = usbtest;
+  source = commands/usbtest.c;
+  emu;
+  enable = COND_GRUB_EMU_USB;
+};
+
+module = {
+  name = vbeinfo;
+  i386_pc = commands/i386/pc/vbeinfo.c;
+};
+
+module = {
+  name = vbetest;
+  i386_pc = commands/i386/pc/vbetest.c;
+};
+
+module = {
+  common;
+  name = videotest;
+  source = commands/videotest.c;
+};
+
+module = {
+  common;
+  name = xnu_uuid;
+  source = commands/xnu_uuid.c;
+};
+
+module = {
+  common;
+  name = dm_nv;
+  source = disk/dmraid_nvidia.c;
+};
+
+module = {
+  common;
+  name = loopback;
+  source = disk/loopback.c;
+};
+
+module = {
+  common;
+  name = lvm;
+  source = disk/lvm.c;
+};
+
+module = {
+  common;
+  name = mdraid;
+  source = disk/mdraid_linux.c;
+};
+
+module = {
+  common;
+  name = raid;
+  source = disk/raid.c;
+};
+
+module = {
+  common;
+  name = raid5rec;
+  source = disk/raid5_recover.c;
+};
+
+module = {
+  common;
+  name = raid6rec;
+  source = disk/raid6_recover.c;
+};
+
+module = {
+  common;
+  name = scsi;
+  source = disk/scsi.c;
+};
+
+module = {
+  common;
+  name = memdisk;
+  source = disk/memdisk.c;
+};
+
+module = {
+  name = ata;
+  source = disk/ata.c;
+
+  x86;
+  mips;
+};
+
+module = {
+  name = ata_pthru;
+  source = disk/ata_pthru.c;
+
+  x86;
+  mips_yeeloong;
+};
+
+module = {
+  name = biosdisk;
+  i386_pc = disk/i386/pc/biosdisk.c;
+};
+
+module = {
+  name = usbms;
+  source = disk/usbms.c;
+  i386_pc;
+};
+
+module = {
+  name = usbms;
+  source = disk/usbms.c;
+  emu;
+  enable = COND_GRUB_EMU_USB;
+};
+
+module = {
+  name = nand;
+  source = disk/ieee1275/nand.c;
+
+  i386_ieee1275;
+};
+
+module = {
+  name = efiemu;
+  i386_pc = efiemu/main.c;
+  i386_pc = efiemu/i386/loadcore32.c;
+  i386_pc = efiemu/i386/loadcore64.c;
+  i386_pc = efiemu/i386/pc/cfgtables.c;
+  i386_pc = efiemu/mm.c;
+  i386_pc = efiemu/loadcore_common.c;
+  i386_pc = efiemu/symbols.c;
+  i386_pc = efiemu/loadcore32.c;
+  i386_pc = efiemu/loadcore64.c;
+  i386_pc = efiemu/prepare32.c;
+  i386_pc = efiemu/prepare64.c;
+  i386_pc = efiemu/pnvram.c;
+  i386_pc = efiemu/i386/coredetect.c;
+};
+
+module = {
+  name = font;
+  source = font/font.c;
+  source = font/font_cmd.c;
+  emu;
+  x86;
+  sparc64;
+  powerpc;
+};
+
+module = {
+  common;
+  name = affs;
+  source = fs/affs.c;
+};
+
+module = {
+  common;
+  name = afs;
+  source = fs/afs.c;
+};
+
+module = {
+  common;
+  name = afs_be;
+  source = fs/afs_be.c;
+};
+
+module = {
+  common;
+  name = befs;
+  source = fs/befs.c;
+};
+
+module = {
+  common;
+  name = befs_be;
+  source = fs/befs_be.c;
+};
+
+module = {
+  common;
+  name = cpio;
+  source = fs/cpio.c;
+};
+
+module = {
+  common;
+  name = ext2;
+  source = fs/ext2.c;
+};
+
+module = {
+  common;
+  name = fat;
+  source = fs/fat.c;
+};
+
+module = {
+  common;
+  name = fshelp;
+  source = fs/fshelp.c;
+};
+
+module = {
+  common;
+  name = hfs;
+  source = fs/hfs.c;
+};
+
+module = {
+  common;
+  name = hfsplus;
+  source = fs/hfsplus.c;
+};
+
+module = {
+  common;
+  name = iso9660;
+  source = fs/iso9660.c;
+};
+
+module = {
+  common;
+  name = jfs;
+  source = fs/jfs.c;
+};
+
+module = {
+  common;
+  name = minix;
+  source = fs/minix.c;
+};
+
+module = {
+  common;
+  name = nilfs2;
+  source = fs/nilfs2.c;
+};
+
+module = {
+  common;
+  name = ntfs;
+  source = fs/ntfs.c;
+};
+
+module = {
+  common;
+  name = ntfscomp;
+  source = fs/ntfscomp.c;
+};
+
+module = {
+  common;
+  name = reiserfs;
+  source = fs/reiserfs.c;
+};
+
+module = {
+  common;
+  name = sfs;
+  source = fs/sfs.c;
+};
+
+module = {
+  common;
+  name = tar;
+  source = fs/tar.c;
+};
+
+module = {
+  common;
+  name = udf;
+  source = fs/udf.c;
+};
+
+module = {
+  common;
+  name = ufs1;
+  source = fs/ufs.c;
+};
+
+module = {
+  common;
+  name = ufs2;
+  source = fs/ufs2.c;
+};
+
+module = {
+  common;
+  name = xfs;
+  source = fs/xfs.c;
+};
+
+module = {
+  name = pxe;
+  i386_pc = fs/i386/pc/pxe.c;
+};
+
+module = {
+  name = gettext;
+  source = gettext/gettext.c;
+  common;
+};
+
+module = {
+  common;
+  name = gfxmenu;
+  source = gfxmenu/gfxmenu.c;
+  source = gfxmenu/model.c;
+  source = gfxmenu/view.c;
+  source = gfxmenu/icon_manager.c;
+  source = gfxmenu/theme_loader.c;
+  source = gfxmenu/widget-box.c;
+  source = gfxmenu/gui_canvas.c;
+  source = gfxmenu/gui_circular_progress.c;
+  source = gfxmenu/gui_box.c;
+  source = gfxmenu/gui_label.c;
+  source = gfxmenu/gui_list.c;
+  source = gfxmenu/gui_image.c;
+  source = gfxmenu/gui_progress_bar.c;
+  source = gfxmenu/gui_util.c;
+  source = gfxmenu/gui_string_util.c;
+  source = gfxmenu/named_colors.c;
+};
+
+module = {
+  common;
+  name = hello;
+  source = hello/hello.c;
+};
+
+module = {
+  common;
+  name = gzio;
+  source = io/gzio.c;
+};
+
+module = {
+  name = bufio;
+  source = io/bufio.c;
+  emu;
+  x86;
+  sparc64;
+  powerpc;
+};
+
+module = {
+  common;
+  name = elf;
+  source = kern/elf.c;
+};
+
+module = {
+  common;
+  name = charset;
+  source = lib/charset.c;
+};
+
+module = {
+  common;
+  name = crypto;
+  source = lib/crypto.c;
+};
+
+module = {
+  common;
+  name = gcry_arcfour;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/arcfour.c;
+};
+
+module = {
+  common;
+  name = gcry_blowfish;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/blowfish.c;
+};
+
+module = {
+  common;
+  name = gcry_camellia;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/camellia.c;
+  source = lib/libgcrypt-grub/cipher/camellia-glue.c;
+};
+
+module = {
+  common;
+  name = gcry_cast5;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/cast5.c;
+};
+
+module = {
+  common;
+  name = gcry_crc;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/crc.c;
+};
+
+module = {
+  common;
+  name = gcry_des;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/des.c;
+};
+
+module = {
+  common;
+  name = gcry_md4;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/md4.c;
+};
+
+module = {
+  common;
+  name = gcry_md5;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/md5.c;
+};
+
+module = {
+  common;
+  name = gcry_rfc2268;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/rfc2268.c;
+};
+
+module = {
+  common;
+  name = gcry_rijndael;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/rijndael.c;
+};
+
+module = {
+  common;
+  name = gcry_rmd160;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/rmd160.c;
+};
+
+module = {
+  common;
+  name = gcry_seed;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/seed.c;
+};
+
+module = {
+  common;
+  name = gcry_serpent;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/serpent.c;
+};
+
+module = {
+  common;
+  name = gcry_sha1;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/sha1.c;
+};
+
+module = {
+  common;
+  name = gcry_sha256;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/sha256.c;
+};
+
+module = {
+  common;
+  name = gcry_sha512;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/sha512.c;
+};
+
+module = {
+  common;
+  name = gcry_tiger;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/tiger.c;
+};
+
+module = {
+  common;
+  name = gcry_twofish;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/twofish.c;
+};
+
+module = {
+  common;
+  name = gcry_whirlpool;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  source = lib/libgcrypt-grub/cipher/whirlpool.c;
+};
+
+module = {
+  common;
+  name = pbkdf2;
+  source = lib/pbkdf2.c;
+};
+
+module = {
+  name = relocator;
+  mips = lib/mips/relocator.c;
+  mips = lib/mips/relocator_asm.S;
+  x86 = lib/i386/relocator.c;
+  x86 = lib/i386/relocator_asm.S;
+  x86 = lib/i386/relocator_backward.S;
+};
+
+module = {
+  name = datetime;
+  source = lib/cmos_datetime.c;
+  x86_efi = lib/efi/datetime.c;
+  sparc64_ieee1275 = lib/ieee1275/datetime.c;
+  powerpc_ieee1275 = lib/ieee1275/datetime.c;
+  x86;
+  mips;
+};
+
+module = {
+  name = setjmp;
+  i386 = lib/i386/setjmp.S;
+  x86_64 = lib/x86_64/setjmp.S;
+  mips = lib/mips/setjmp.S;
+  sparc64 = lib/sparc64/setjmp.S;
+  powerpc = lib/powerpc/setjmp.S;
+};
+
+module = {
+  name = aout;
+  source = loader/aout.c;
+  i386_pc;
+  i386_qemu;
+  i386_coreboot;
+  i386_ieee1275;
+};
+
+module = {
+  name = bsd;
+  source = loader/i386/bsd.c;
+  source = loader/i386/bsd32.c;
+  source = loader/i386/bsd64.c;
+  source = loader/i386/bsd_helper.S;
+  source = loader/i386/bsd_trampoline.S;
+  i386_pc;
+  i386_qemu;
+  i386_coreboot;
+};
+
+module = {
+  name = linux16;
+  source = loader/i386/pc/linux.c;
+  i386_pc;
+};
+
+module = {
+  name = multiboot2;
+  cppflags = "-DGRUB_USE_MULTIBOOT2";
+
+  source = loader/multiboot.c;
+  source = loader/multiboot_mbi2.c;
+  x86;
+  mips;
+};
+
+module = {
+  name = multiboot;
+  source = loader/multiboot.c;
+  source = loader/i386/multiboot_mbi.c;
+  x86;
+};
+
+module = {
+  name = linux;
+  i386 = loader/i386/linux.c;
+  i386_efi = loader/i386/efi/linux.c;
+  i386_ieee1275 = loader/i386/ieee1275/linux.c;
+  x86_64_efi = loader/i386/efi/linux.c;
+  x86_64_efi = loader/i386/linux_trampoline.S;
+  mips = loader/mips/linux.c;
+  powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
+  sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
+};
+
+module = {
+  name = xnu;
+  x86_efi = loader/xnu_resume.c;
+  x86_efi = loader/i386/xnu.c;
+  x86_efi = loader/i386/efi/xnu.c;
+  x86_efi = loader/macho32.c;
+  x86_efi = loader/macho64.c;
+  x86_efi = loader/macho.c;
+  x86_efi = loader/xnu.c;
+
+  i386_pc = loader/xnu_resume.c;
+  i386_pc = loader/i386/xnu.c;
+  i386_pc = loader/i386/pc/xnu.c;
+  i386_pc = loader/macho32.c;
+  i386_pc = loader/macho64.c;
+  i386_pc = loader/macho.c;
+  i386_pc = loader/xnu.c;
+};
+
+module = {
+  name = appleldr;
+  x86_efi = loader/efi/appleloader.c;
+};
+
+module = {
+  name = chain;
+  x86_efi = loader/efi/chainloader.c;
+  i386_pc = loader/i386/pc/chainloader.c;
+};
+
+module = {
+  name = mmap;
+  i386_pc = mmap/mmap.c;
+  i386_pc = mmap/i386/uppermem.c;
+  i386_pc = mmap/i386/mmap.c;
+  i386_pc = mmap/i386/pc/mmap.c;
+  i386_pc = mmap/i386/pc/mmap_helper.S;
+
+  x86_efi = mmap/mmap.c;
+  x86_efi = mmap/i386/uppermem.c;
+  x86_efi = mmap/i386/mmap.c;
+  x86_efi = mmap/efi/mmap.c;
+
+  i386_coreboot = mmap/mmap.c;
+  i386_coreboot = mmap/i386/uppermem.c;
+  i386_coreboot = mmap/i386/mmap.c;
+
+  i386_qemu = mmap/mmap.c;
+  i386_qemu = mmap/i386/uppermem.c;
+  i386_qemu = mmap/i386/mmap.c;
+
+  i386_ieee1275 = mmap/mmap.c;
+  i386_ieee1275 = mmap/i386/uppermem.c;
+  i386_ieee1275 = mmap/i386/mmap.c;
+
+  mips_yeeloong = mmap/mmap.c;
+  mips_yeeloong = mmap/mips/yeeloong/uppermem.c;
+};
+
+module = {
+  common;
+  name = normal;
+  source = normal/main.c;
+  source = normal/cmdline.c;
+  source = normal/dyncmd.c;
+  source = normal/auth.c;
+  source = normal/autofs.c;
+  source = normal/handler.c;
+  source = normal/color.c;
+  source = normal/completion.c;
+  source = normal/datetime.c;
+  source = normal/menu.c;
+  source = normal/menu_entry.c;
+  source = normal/menu_text.c;
+  source = normal/misc.c;
+  source = normal/crypto.c;
+  source = normal/term.c;
+  source = normal/context.c;
+};
+
+module = {
+  common;
+  name = part_acorn;
+  source = partmap/acorn.c;
+};
+
+module = {
+  common;
+  name = part_amiga;
+  source = partmap/amiga.c;
+};
+
+module = {
+  common;
+  name = part_apple;
+  source = partmap/apple.c;
+};
+
+module = {
+  common;
+  name = part_gpt;
+  source = partmap/gpt.c;
+};
+
+module = {
+  common;
+  name = part_msdos;
+  source = partmap/msdos.c;
+};
+
+module = {
+  common;
+  name = part_sun;
+  source = partmap/sun.c;
+};
+
+module = {
+  common;
+  name = part_bsd;
+  source = partmap/bsdlabel.c;
+};
+
+module = {
+  common;
+  name = part_sunpc;
+  source = partmap/sunpc.c;
+};
+
+module = {
+  common;
+  name = msdospart;
+  source = parttool/msdospart.c;
+};
+
+module = {
+  common;
+  name = sh;
+  source = script/main.c;
+  source = script/script.c;
+  source = script/execute.c;
+  source = script/function.c;
+  source = script/lexer.c;
+  nodist = grub_script.tab.c;
+  nodist = grub_script.yy.c;
+  nodist = grub_script.tab.h;
+  nodist = grub_script.yy.h;
+  cflags = '$(CFLAGS_POSIX) -Wno-error';
+  cppflags = '$(CPPFLAGS_POSIX)';
+};
+
+module = {
+  name = at_keyboard;
+  source = term/at_keyboard.c;
+  x86;
+};
+
+module = {
+  name = gfxterm;
+  source = term/gfxterm.c;
+  emu;
+  x86;
+  sparc64;
+  powerpc;
+};
+
+module = {
+  name = serial;
+  source = term/serial.c;
+  mips;
+  i386;
+};
+
+module = {
+  common;
+  name = terminfo;
+  source = term/terminfo.c;
+  source = term/tparm.c;
+};
+
+module = {
+  name = usb_keyboard;
+  source = term/usb_keyboard.c;
+  i386_pc;
+};
+
+module = {
+  name = vga;
+  i386_pc = term/i386/pc/vga.c;
+};
+
+module = {
+  name = vga_text;
+  x86 = term/i386/pc/vga_text.c;
+  x86 = term/i386/vga_common.c;
+};
+
+module = {
+  name = functional_test;
+  source = tests/lib/functional_test.c;
+  source = tests/lib/test.c;
+  common;
+};
+
+module = {
+  name = example_functional_test;
+  source = tests/example_functional_test.c;
+  cflags = -Wno-format;
+  common;
+};
+
+module = {
+  name = bitmap;
+  source = video/bitmap.c;
+  emu;
+  x86;
+  sparc64;
+  powerpc;
+};
+
+module = {
+  name = bitmap_scale;
+  source = video/bitmap_scale.c;
+  emu;
+  x86;
+  sparc64;
+  powerpc;
+};
+
+module = {
+  name = efi_gop;
+  x86_efi = video/efi_gop.c;
+};
+
+module = {
+  name = efi_uga;
+  x86_efi = video/efi_uga.c;
+};
+
+module = {
+  common;
+  name = jpeg;
+  source = video/readers/jpeg.c;
+};
+
+module = {
+  common;
+  name = png;
+  source = video/readers/png.c;
+};
+
+module = {
+  common;
+  name = tga;
+  source = video/readers/tga.c;
+};
+
+module = {
+  name = vbe;
+  i386_pc = video/i386/pc/vbe.c;
+};
+
+module = {
+  name = video_fb;
+  source = video/fb/video_fb.c;
+  source = video/fb/fbblit.c;
+  source = video/fb/fbfill.c;
+  source = video/fb/fbutil.c;
+  emu;
+  x86;
+  sparc64;
+  powerpc;
+};
+
+module = {
+  name = video;
+  source = video/video.c;
+  emu;
+  x86;
+  sparc64;
+  powerpc;
+};
+
+module = {
+  name = ieee1275_fb;
+  source = video/ieee1275.c;
+  powerpc;
+  sparc64;
+};
+
+module = {
+  name = sdl;
+  source = video/emu/sdl.c;
+  enable = COND_GRUB_EMU_SDL;
+  emu;
+};
+
+module = {
+  name = datehook;
+  source = hook/datehook.c;
+  common;
+};
diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c
new file mode 100644 (file)
index 0000000..156b84c
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/auth.h>
+#include <grub/list.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/normal.h>
+#include <grub/time.h>
+#include <grub/i18n.h>
+
+struct grub_auth_user
+{
+  struct grub_auth_user *next;
+  char *name;
+  grub_auth_callback_t callback;
+  void *arg;
+  int authenticated;
+};
+
+struct grub_auth_user *users = NULL;
+
+grub_err_t
+grub_auth_register_authentication (const char *user,
+                                  grub_auth_callback_t callback,
+                                  void *arg)
+{
+  struct grub_auth_user *cur;
+
+  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+  if (!cur)
+    cur = grub_zalloc (sizeof (*cur));
+  if (!cur)
+    return grub_errno;
+  cur->callback = callback;
+  cur->arg = arg;
+  if (! cur->name)
+    {
+      cur->name = grub_strdup (user);
+      if (!cur->name)
+       {
+         grub_free (cur);
+         return grub_errno;
+       }
+      grub_list_push (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+    }
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_auth_unregister_authentication (const char *user)
+{
+  struct grub_auth_user *cur;
+  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+  if (!cur)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "user '%s' not found", user);
+  if (!cur->authenticated)
+    {
+      grub_free (cur->name);
+      grub_list_remove (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+      grub_free (cur);
+    }
+  else
+    {
+      cur->callback = NULL;
+      cur->arg = NULL;
+    }
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_auth_authenticate (const char *user)
+{
+  struct grub_auth_user *cur;
+
+  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+  if (!cur)
+    cur = grub_zalloc (sizeof (*cur));
+  if (!cur)
+    return grub_errno;
+
+  cur->authenticated = 1;
+
+  if (! cur->name)
+    {
+      cur->name = grub_strdup (user);
+      if (!cur->name)
+       {
+         grub_free (cur);
+         return grub_errno;
+       }
+      grub_list_push (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_auth_deauthenticate (const char *user)
+{
+  struct grub_auth_user *cur;
+  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
+  if (!cur)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "user '%s' not found", user);
+  if (!cur->callback)
+    {
+      grub_free (cur->name);
+      grub_list_remove (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
+      grub_free (cur);
+    }
+  else
+    cur->authenticated = 0;
+  return GRUB_ERR_NONE;
+}
+
+static int
+is_authenticated (const char *userlist)
+{
+  const char *superusers;
+
+  auto int hook (grub_list_t item);
+  int hook (grub_list_t item)
+  {
+    const char *name;
+    if (!((struct grub_auth_user *) item)->authenticated)
+      return 0;
+    name = ((struct grub_auth_user *) item)->name;
+
+    return (userlist && grub_strword (userlist, name))
+      || grub_strword (superusers, name);
+  }
+
+  superusers = grub_env_get ("superusers");
+
+  if (!superusers)
+    return 1;
+
+  return grub_list_iterate (GRUB_AS_LIST (users), hook);
+}
+
+static int
+grub_username_get (char buf[], unsigned buf_size)
+{
+  unsigned cur_len = 0;
+  int key;
+
+  while (1)
+    {
+      key = GRUB_TERM_ASCII_CHAR (grub_getkey ()); 
+      if (key == '\n' || key == '\r')
+       break;
+
+      if (key == '\e')
+       {
+         cur_len = 0;
+         break;
+       }
+
+      if (key == '\b')
+       {
+         cur_len--;
+         grub_printf ("\b");
+         continue;
+       }
+
+      if (!grub_isprint (key))
+       continue;
+
+      if (cur_len + 2 < buf_size)
+       {
+         buf[cur_len++] = key;
+         grub_putchar (key);
+       }
+    }
+
+  grub_memset (buf + cur_len, 0, buf_size - cur_len);
+
+  grub_putchar ('\n');
+  grub_refresh ();
+
+  return (key != '\e');
+}
+
+grub_err_t
+grub_auth_check_authentication (const char *userlist)
+{
+  char login[1024];
+  struct grub_auth_user *cur = NULL;
+  grub_err_t err;
+  static unsigned long punishment_delay = 1;
+  char entered[GRUB_AUTH_MAX_PASSLEN];
+
+  auto int hook (grub_list_t item);
+  int hook (grub_list_t item)
+  {
+    if (grub_strcmp (login, ((struct grub_auth_user *) item)->name) == 0)
+      cur = (struct grub_auth_user *) item;
+    return 0;
+  }
+
+  auto int hook_any (grub_list_t item);
+  int hook_any (grub_list_t item)
+  {
+    if (((struct grub_auth_user *) item)->callback)
+      cur = (struct grub_auth_user *) item;
+    return 0;
+  }
+
+  grub_memset (login, 0, sizeof (login));
+
+  if (is_authenticated (userlist))
+    {
+      punishment_delay = 1;
+      return GRUB_ERR_NONE;
+    }
+
+  grub_puts_ (N_("Enter username: "));
+
+  if (!grub_username_get (login, sizeof (login) - 1))
+    goto access_denied;
+
+  grub_puts_ (N_("Enter password: "));
+
+  if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
+    goto access_denied;
+
+  grub_list_iterate (GRUB_AS_LIST (users), hook);
+
+  if (!cur || ! cur->callback)
+    goto access_denied;
+
+  err = cur->callback (login, entered, cur->arg);
+  if (is_authenticated (userlist))
+    {
+      punishment_delay = 1;
+      return GRUB_ERR_NONE;
+    }
+
+ access_denied:
+  grub_sleep (punishment_delay);
+
+  if (punishment_delay < GRUB_ULONG_MAX / 2)
+    punishment_delay *= 2;
+
+  return GRUB_ACCESS_DENIED;
+}
diff --git a/grub-core/normal/autofs.c b/grub-core/normal/autofs.c
new file mode 100644 (file)
index 0000000..e1d4c01
--- /dev/null
@@ -0,0 +1,136 @@
+/* autofs.c - support auto-loading from fs.lst */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/fs.h>
+#include <grub/normal.h>
+
+/* This is used to store the names of filesystem modules for auto-loading.  */
+static grub_named_list_t fs_module_list;
+
+/* The auto-loading hook for filesystems.  */
+static int
+autoload_fs_module (void)
+{
+  grub_named_list_t p;
+
+  while ((p = fs_module_list) != NULL)
+    {
+      if (! grub_dl_get (p->name) && grub_dl_load (p->name))
+       return 1;
+
+      if (grub_errno)
+       grub_print_error ();
+
+      fs_module_list = p->next;
+      grub_free (p->name);
+      grub_free (p);
+    }
+
+  return 0;
+}
+
+/* Read the file fs.lst for auto-loading.  */
+void
+read_fs_list (const char *prefix)
+{
+  if (prefix)
+    {
+      char *filename;
+
+      filename = grub_xasprintf ("%s/fs.lst", prefix);
+      if (filename)
+       {
+         grub_file_t file;
+         grub_fs_autoload_hook_t tmp_autoload_hook;
+
+         /* This rules out the possibility that read_fs_list() is invoked
+            recursively when we call grub_file_open() below.  */
+         tmp_autoload_hook = grub_fs_autoload_hook;
+         grub_fs_autoload_hook = NULL;
+
+         file = grub_file_open (filename);
+         if (file)
+           {
+             /* Override previous fs.lst.  */
+             while (fs_module_list)
+               {
+                 grub_named_list_t tmp;
+                 tmp = fs_module_list->next;
+                 grub_free (fs_module_list);
+                 fs_module_list = tmp;
+               }
+
+             while (1)
+               {
+                 char *buf;
+                 char *p;
+                 char *q;
+                 grub_named_list_t fs_mod;
+
+                 buf = grub_file_getline (file);
+                 if (! buf)
+                   break;
+
+                 p = buf;
+                 q = buf + grub_strlen (buf) - 1;
+
+                 /* Ignore space.  */
+                 while (grub_isspace (*p))
+                   p++;
+
+                 while (p < q && grub_isspace (*q))
+                   *q-- = '\0';
+
+                 /* If the line is empty, skip it.  */
+                 if (p >= q)
+                   continue;
+
+                 fs_mod = grub_malloc (sizeof (*fs_mod));
+                 if (! fs_mod)
+                   continue;
+
+                 fs_mod->name = grub_strdup (p);
+                 if (! fs_mod->name)
+                   {
+                     grub_free (fs_mod);
+                     continue;
+                   }
+
+                 fs_mod->next = fs_module_list;
+                 fs_module_list = fs_mod;
+               }
+
+             grub_file_close (file);
+             grub_fs_autoload_hook = tmp_autoload_hook;
+           }
+
+         grub_free (filename);
+       }
+    }
+
+  /* Ignore errors.  */
+  grub_errno = GRUB_ERR_NONE;
+
+  /* Set the hook.  */
+  grub_fs_autoload_hook = autoload_fs_module;
+}
diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c
new file mode 100644 (file)
index 0000000..05d6654
--- /dev/null
@@ -0,0 +1,636 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/env.h>
+#include <grub/i18n.h>
+#include <grub/charset.h>
+
+static grub_uint32_t *kill_buf;
+
+static int hist_size;
+static grub_uint32_t **hist_lines = 0;
+static int hist_pos = 0;
+static int hist_end = 0;
+static int hist_used = 0;
+
+grub_err_t
+grub_set_history (int newsize)
+{
+  grub_uint32_t **old_hist_lines = hist_lines;
+  hist_lines = grub_malloc (sizeof (grub_uint32_t *) * newsize);
+
+  /* Copy the old lines into the new buffer.  */
+  if (old_hist_lines)
+    {
+      /* Remove the lines that don't fit in the new buffer.  */
+      if (newsize < hist_used)
+       {
+         int i;
+         int delsize = hist_used - newsize;
+         hist_used = newsize;
+
+         for (i = 1; i <= delsize; i++)
+           {
+             int pos = hist_end - i;
+             if (pos < 0)
+               pos += hist_size;
+             grub_free (old_hist_lines[pos]);
+           }
+
+         hist_end -= delsize;
+         if (hist_end < 0)
+           hist_end += hist_size;
+       }
+
+      if (hist_pos < hist_end)
+       grub_memmove (hist_lines, old_hist_lines + hist_pos,
+                     (hist_end - hist_pos) * sizeof (grub_uint32_t *));
+      else if (hist_used)
+       {
+         /* Copy the older part.  */
+         grub_memmove (hist_lines, old_hist_lines + hist_pos,
+                       (hist_size - hist_pos) * sizeof (grub_uint32_t *));
+
+         /* Copy the newer part. */
+         grub_memmove (hist_lines + hist_size - hist_pos, old_hist_lines,
+                       hist_end * sizeof (grub_uint32_t *));
+       }
+    }
+
+  grub_free (old_hist_lines);
+
+  hist_size = newsize;
+  hist_pos = 0;
+  hist_end = hist_used;
+  return 0;
+}
+
+/* Get the entry POS from the history where `0' is the newest
+   entry.  */
+static grub_uint32_t *
+grub_history_get (int pos)
+{
+  pos = (hist_pos + pos) % hist_size;
+  return hist_lines[pos];
+}
+
+static grub_size_t
+strlen_ucs4 (const grub_uint32_t *s)
+{
+  const grub_uint32_t *p = s;
+
+  while (*p)
+    p++;
+
+  return p - s;
+}
+
+/* Replace the history entry on position POS with the string S.  */
+static void
+grub_history_set (int pos, grub_uint32_t *s, grub_size_t len)
+{
+  grub_free (hist_lines[pos]);
+  hist_lines[pos] = grub_malloc ((len + 1) * sizeof (grub_uint32_t));
+  if (!hist_lines[pos])
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      return ;
+    }
+  grub_memcpy (hist_lines[pos], s, len * sizeof (grub_uint32_t));
+  hist_lines[pos][len] = 0;
+}
+
+/* Insert a new history line S on the top of the history.  */
+static void
+grub_history_add (grub_uint32_t *s, grub_size_t len)
+{
+  /* Remove the oldest entry in the history to make room for a new
+     entry.  */
+  if (hist_used + 1 > hist_size)
+    {
+      hist_end--;
+      if (hist_end < 0)
+       hist_end = hist_size + hist_end;
+
+      grub_free (hist_lines[hist_end]);
+    }
+  else
+    hist_used++;
+
+  /* Move to the next position.  */
+  hist_pos--;
+  if (hist_pos < 0)
+    hist_pos = hist_size + hist_pos;
+
+  /* Insert into history.  */
+  hist_lines[hist_pos] = NULL;
+  grub_history_set (hist_pos, s, len);
+}
+
+/* Replace the history entry on position POS with the string S.  */
+static void
+grub_history_replace (int pos, grub_uint32_t *s, grub_size_t len)
+{
+  grub_history_set ((hist_pos + pos) % hist_size, s, len);
+}
+
+/* A completion hook to print items.  */
+static void
+print_completion (const char *item, grub_completion_type_t type, int count)
+{
+  if (count == 0)
+    {
+      /* If this is the first time, print a label.  */
+      
+      grub_puts ("");
+      switch (type)
+       {
+       case GRUB_COMPLETION_TYPE_COMMAND:
+         grub_puts_ (N_("Possible commands are:"));
+         break;
+       case GRUB_COMPLETION_TYPE_DEVICE:
+         grub_puts_ (N_("Possible devices are:"));
+         break;
+       case GRUB_COMPLETION_TYPE_FILE:
+         grub_puts_ (N_("Possible files are:"));
+         break;
+       case GRUB_COMPLETION_TYPE_PARTITION:
+         grub_puts_ (N_("Possible partitions are:"));
+         break;
+       case GRUB_COMPLETION_TYPE_ARGUMENT:
+         grub_puts_ (N_("Possible arguments are:"));
+         break;
+       default:
+         grub_puts_ (N_("Possible things are:"));
+         break;
+       }
+      grub_puts ("");
+    }
+
+  if (type == GRUB_COMPLETION_TYPE_PARTITION)
+    {
+      grub_normal_print_device_info (item);
+      grub_errno = GRUB_ERR_NONE;
+    }
+  else
+    grub_printf (" %s", item);
+}
+
+struct cmdline_term
+{
+  unsigned xpos, ypos, ystart, width, height;
+  struct grub_term_output *term;
+};
+
+/* Get a command-line. If ESC is pushed, return zero,
+   otherwise return command line.  */
+/* FIXME: The dumb interface is not supported yet.  */
+char *
+grub_cmdline_get (const char *prompt)
+{
+  grub_size_t lpos, llen;
+  grub_size_t plen;
+  grub_uint32_t *buf;
+  grub_size_t max_len = 256;
+  int key;
+  int histpos = 0;
+  auto void cl_insert (const grub_uint32_t *str);
+  auto void cl_delete (unsigned len);
+  auto inline void __attribute__ ((always_inline)) cl_print (struct cmdline_term *cl_term, int pos,
+                       grub_uint32_t c);
+  auto void cl_set_pos (struct cmdline_term *cl_term);
+  auto void cl_print_all (int pos, grub_uint32_t c);
+  auto void cl_set_pos_all (void);
+  auto void init_clterm (struct cmdline_term *cl_term_cur);
+  auto void init_clterm_all (void);
+  const char *prompt_translated = _(prompt);
+  struct cmdline_term *cl_terms;
+  char *ret;
+  unsigned nterms;
+
+  void cl_set_pos (struct cmdline_term *cl_term)
+  {
+    cl_term->xpos = (plen + lpos) % (cl_term->width - 1);
+    cl_term->ypos = cl_term->ystart + (plen + lpos) / (cl_term->width - 1);
+    grub_term_gotoxy (cl_term->term, cl_term->xpos, cl_term->ypos);
+  }
+
+  void cl_set_pos_all ()
+  {
+    unsigned i;
+    for (i = 0; i < nterms; i++)
+      cl_set_pos (&cl_terms[i]);
+  }
+
+  inline void __attribute__ ((always_inline)) cl_print (struct cmdline_term *cl_term, int pos, grub_uint32_t c)
+    {
+      grub_uint32_t *p;
+
+      for (p = buf + pos; p < buf + llen; p++)
+       {
+         if (c)
+           grub_putcode (c, cl_term->term);
+         else
+           grub_putcode (*p, cl_term->term);
+         cl_term->xpos++;
+         if (cl_term->xpos >= cl_term->width - 1)
+           {
+             cl_term->xpos = 0;
+             if (cl_term->ypos >= (unsigned) (cl_term->height - 1))
+               cl_term->ystart--;
+             else
+               cl_term->ypos++;
+             grub_putcode ('\n', cl_term->term);
+           }
+       }
+    }
+
+  void cl_print_all (int pos, grub_uint32_t c)
+  {
+    unsigned i;
+    for (i = 0; i < nterms; i++)
+      cl_print (&cl_terms[i], pos, c);
+  }
+
+  void cl_insert (const grub_uint32_t *str)
+    {
+      grub_size_t len = strlen_ucs4 (str);
+
+      if (len + llen >= max_len)
+       {
+         grub_uint32_t *nbuf;
+         max_len *= 2;
+         nbuf = grub_realloc (buf, sizeof (grub_uint32_t) * max_len);
+         if (nbuf)
+           buf = nbuf;
+         else
+           {
+             grub_print_error ();
+             grub_errno = GRUB_ERR_NONE;
+             max_len /= 2;
+           }
+       }
+
+      if (len + llen < max_len)
+       {
+         grub_memmove (buf + lpos + len, buf + lpos,
+                       (llen - lpos + 1) * sizeof (grub_uint32_t));
+         grub_memmove (buf + lpos, str, len * sizeof (grub_uint32_t));
+
+         llen += len;
+         cl_set_pos_all ();
+         cl_print_all (lpos, 0);
+         lpos += len;
+         cl_set_pos_all ();
+       }
+    }
+
+  void cl_delete (unsigned len)
+    {
+      if (lpos + len <= llen)
+       {
+         grub_size_t saved_lpos = lpos;
+
+         lpos = llen - len;
+         cl_set_pos_all ();
+         cl_print_all (lpos, ' ');
+         lpos = saved_lpos;
+         cl_set_pos_all ();
+
+         grub_memmove (buf + lpos, buf + lpos + len,
+                       sizeof (grub_uint32_t) * (llen - lpos + 1));
+         llen -= len;
+         cl_print_all (lpos, 0);
+         cl_set_pos_all ();
+       }
+    }
+
+  void init_clterm (struct cmdline_term *cl_term_cur)
+  {
+    cl_term_cur->xpos = plen;
+    cl_term_cur->ypos = (grub_term_getxy (cl_term_cur->term) & 0xFF);
+    cl_term_cur->ystart = cl_term_cur->ypos;
+    cl_term_cur->width = grub_term_width (cl_term_cur->term);
+    cl_term_cur->height = grub_term_height (cl_term_cur->term);
+  }
+
+  void init_clterm_all (void)
+  {
+    unsigned i;
+    for (i = 0; i < nterms; i++)
+      init_clterm (&cl_terms[i]);
+  }
+
+  buf = grub_malloc (max_len * sizeof (grub_uint32_t));
+  if (!buf)
+    return 0;
+
+  plen = grub_strlen (prompt_translated) + sizeof (" ") - 1;
+  lpos = llen = 0;
+  buf[0] = '\0';
+
+  {
+    grub_term_output_t term;
+
+    FOR_ACTIVE_TERM_OUTPUTS(term)
+      if ((grub_term_getxy (term) >> 8) != 0)
+       grub_putcode ('\n', term);
+  }
+  grub_printf ("%s ", prompt_translated);
+
+  {
+    struct cmdline_term *cl_term_cur;
+    struct grub_term_output *cur;
+    nterms = 0;
+    FOR_ACTIVE_TERM_OUTPUTS(cur)
+      nterms++;
+
+    cl_terms = grub_malloc (sizeof (cl_terms[0]) * nterms);
+    if (!cl_terms)
+      return 0;
+    cl_term_cur = cl_terms;
+    FOR_ACTIVE_TERM_OUTPUTS(cur)
+    {
+      cl_term_cur->term = cur;
+      init_clterm (cl_term_cur);
+      cl_term_cur++;
+    }
+  }
+
+  if (hist_used == 0)
+    grub_history_add (buf, llen);
+
+  grub_refresh ();
+
+  while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r')
+    {
+      switch (key)
+       {
+       case 1: /* Ctrl-a */
+         lpos = 0;
+         cl_set_pos_all ();
+         break;
+
+       case 2: /* Ctrl-b */
+         if (lpos > 0)
+           {
+             lpos--;
+             cl_set_pos_all ();
+           }
+         break;
+
+       case 5: /* Ctrl-e */
+         lpos = llen;
+         cl_set_pos_all ();
+         break;
+
+       case 6: /* Ctrl-f */
+         if (lpos < llen)
+           {
+             lpos++;
+             cl_set_pos_all ();
+           }
+         break;
+
+       case 9: /* Ctrl-i or TAB */
+         {
+           int restore;
+           char *insertu8;
+           char *bufu8;
+           grub_uint32_t c;
+
+           c = buf[lpos];
+           buf[lpos] = '\0';
+
+           bufu8 = grub_ucs4_to_utf8_alloc (buf, lpos);
+           buf[lpos] = c;
+           if (!bufu8)
+             {
+               grub_print_error ();
+               grub_errno = GRUB_ERR_NONE;
+               break;
+             }
+
+           insertu8 = grub_normal_do_completion (bufu8, &restore,
+                                                 print_completion);
+           grub_free (bufu8);
+
+           if (restore)
+             {
+               /* Restore the prompt.  */
+               grub_printf ("\n%s ", prompt_translated);
+               init_clterm_all ();
+               cl_print_all (0, 0);
+             }
+
+           if (insertu8)
+             {
+               grub_size_t insertlen;
+               grub_ssize_t t;
+               grub_uint32_t *insert;
+
+               insertlen = grub_strlen (insertu8);
+               insert = grub_malloc ((insertlen + 1) * sizeof (grub_uint32_t));
+               if (!insert)
+                 {
+                   grub_free (insertu8);
+                   grub_print_error ();
+                   grub_errno = GRUB_ERR_NONE;
+                   break;
+                 }
+               t = grub_utf8_to_ucs4 (insert, insertlen,
+                                      (grub_uint8_t *) insertu8,
+                                      insertlen, 0);
+               if (t > 0)
+                 {
+                   if (insert[t-1] == ' ' && buf[lpos] == ' ')
+                     {
+                       insert[t-1] = 0;
+                       if (t != 1)
+                         cl_insert (insert);
+                       lpos++;
+                     }
+                   else
+                     {
+                       insert[t] = 0;
+                       cl_insert (insert);
+                     }
+                 }
+
+               grub_free (insertu8);
+               grub_free (insert);
+             }
+           cl_set_pos_all ();
+         }
+         break;
+
+       case 11:        /* Ctrl-k */
+         if (lpos < llen)
+           {
+             if (kill_buf)
+               grub_free (kill_buf);
+
+             kill_buf = grub_malloc ((llen - lpos + 1)
+                                     * sizeof (grub_uint32_t));
+             if (grub_errno)
+               {
+                 grub_print_error ();
+                 grub_errno = GRUB_ERR_NONE;
+               }
+             else
+               {
+                 grub_memcpy (kill_buf, buf + lpos,
+                              (llen - lpos + 1) * sizeof (grub_uint32_t));
+                 kill_buf[llen - lpos] = 0;
+               }
+
+             cl_delete (llen - lpos);
+           }
+         break;
+
+       case 14:        /* Ctrl-n */
+         {
+           grub_uint32_t *hist;
+
+           lpos = 0;
+
+           if (histpos > 0)
+             {
+               grub_history_replace (histpos, buf, llen);
+               histpos--;
+             }
+
+           cl_delete (llen);
+           hist = grub_history_get (histpos);
+           cl_insert (hist);
+
+           break;
+         }
+       case 16:        /* Ctrl-p */
+         {
+           grub_uint32_t *hist;
+
+           lpos = 0;
+
+           if (histpos < hist_used - 1)
+             {
+               grub_history_replace (histpos, buf, llen);
+               histpos++;
+             }
+
+           cl_delete (llen);
+           hist = grub_history_get (histpos);
+
+           cl_insert (hist);
+         }
+         break;
+
+       case 21:        /* Ctrl-u */
+         if (lpos > 0)
+           {
+             grub_size_t n = lpos;
+
+             if (kill_buf)
+               grub_free (kill_buf);
+
+             kill_buf = grub_malloc (n + 1);
+             if (grub_errno)
+               {
+                 grub_print_error ();
+                 grub_errno = GRUB_ERR_NONE;
+               }
+             if (kill_buf)
+               {
+                 grub_memcpy (kill_buf, buf, n);
+                 kill_buf[n] = '\0';
+               }
+
+             lpos = 0;
+             cl_set_pos_all ();
+             cl_delete (n);
+           }
+         break;
+
+       case 25:        /* Ctrl-y */
+         if (kill_buf)
+           cl_insert (kill_buf);
+         break;
+
+       case '\e':
+         return 0;
+
+       case '\b':
+         if (lpos > 0)
+           {
+             lpos--;
+             cl_set_pos_all ();
+           }
+          else
+            break;
+         /* fall through */
+
+       case 4: /* Ctrl-d */
+         if (lpos < llen)
+           cl_delete (1);
+         break;
+
+       default:
+         if (grub_isprint (key))
+           {
+             grub_uint32_t str[2];
+
+             str[0] = key;
+             str[1] = '\0';
+             cl_insert (str);
+           }
+         break;
+       }
+
+      grub_refresh ();
+    }
+
+  grub_putchar ('\n');
+  grub_refresh ();
+
+  /* Remove leading spaces.  */
+  lpos = 0;
+  while (buf[lpos] == ' ')
+    lpos++;
+
+  histpos = 0;
+  if (strlen_ucs4 (buf) > 0)
+    {
+      grub_uint32_t empty[] = { 0 };
+      grub_history_replace (histpos, buf, llen);
+      grub_history_add (empty, 0);
+    }
+
+  ret = grub_ucs4_to_utf8_alloc (buf + lpos, llen - lpos + 1);
+  grub_free (buf);
+  return ret;
+}
diff --git a/grub-core/normal/color.c b/grub-core/normal/color.c
new file mode 100644 (file)
index 0000000..bae0829
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/normal.h>
+#include <grub/term.h>
+#include <grub/i18n.h>
+
+/* Borrowed from GRUB Legacy */
+static char *color_list[16] =
+{
+  "black",
+  "blue",
+  "green",
+  "cyan",
+  "red",
+  "magenta",
+  "brown",
+  "light-gray",
+  "dark-gray",
+  "light-blue",
+  "light-green",
+  "light-cyan",
+  "light-red",
+  "light-magenta",
+  "yellow",
+  "white"
+};
+
+static int
+parse_color_name (grub_uint8_t *ret, char *name)
+{
+  grub_uint8_t i;
+  for (i = 0; i < sizeof (color_list) / sizeof (*color_list); i++)
+    if (! grub_strcmp (name, color_list[i]))
+      {
+        *ret = i;
+        return 0;
+      }
+  return -1;
+}
+
+void
+grub_parse_color_name_pair (grub_uint8_t *ret, const char *name)
+{
+  grub_uint8_t fg, bg;
+  char *fg_name, *bg_name;
+
+  /* nothing specified by user */
+  if (name == NULL)
+    return;
+
+  fg_name = grub_strdup (name);
+  if (fg_name == NULL)
+    {
+      /* "out of memory" message was printed by grub_strdup() */
+      grub_wait_after_message ();
+      return;
+    }
+
+  bg_name = grub_strchr (fg_name, '/');
+  if (bg_name == NULL)
+    {
+      grub_printf_ (N_("Warning: syntax error (missing slash) in `%s'\n"), fg_name);
+      grub_wait_after_message ();
+      goto free_and_return;
+    }
+
+  *(bg_name++) = '\0';
+
+  if (parse_color_name (&fg, fg_name) == -1)
+    {
+      grub_printf_ (N_("Warning: invalid foreground color `%s'\n"), fg_name);
+      grub_wait_after_message ();
+      goto free_and_return;
+    }
+  if (parse_color_name (&bg, bg_name) == -1)
+    {
+      grub_printf_ (N_("Warning: invalid background color `%s'\n"), bg_name);
+      grub_wait_after_message ();
+      goto free_and_return;
+    }
+
+  *ret = (bg << 4) | fg;
+
+free_and_return:
+  grub_free (fg_name);
+}
+
+static grub_uint8_t color_normal, color_highlight;
+
+static void
+set_colors (void)
+{
+  struct grub_term_output *term;
+
+  FOR_ACTIVE_TERM_OUTPUTS(term)
+  {
+    /* Reloads terminal `normal' and `highlight' colors.  */
+    grub_term_setcolor (term, color_normal, color_highlight);
+
+    /* Propagates `normal' color to terminal current color.  */
+    grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
+  }
+}
+
+/* Replace default `normal' colors with the ones specified by user (if any).  */
+char *
+grub_env_write_color_normal (struct grub_env_var *var __attribute__ ((unused)),
+                            const char *val)
+{
+  grub_parse_color_name_pair (&color_normal, val);
+
+  set_colors ();
+
+  return grub_strdup (val);
+}
+
+/* Replace default `highlight' colors with the ones specified by user (if any).  */
+char *
+grub_env_write_color_highlight (struct grub_env_var *var __attribute__ ((unused)),
+                               const char *val)
+{
+  grub_parse_color_name_pair (&color_highlight, val);
+
+  set_colors ();
+
+  return grub_strdup (val);
+}
diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c
new file mode 100644 (file)
index 0000000..13e8f7a
--- /dev/null
@@ -0,0 +1,504 @@
+/* completion.c - complete a command, a disk, a partition or a file */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+#include <grub/disk.h>
+#include <grub/file.h>
+#include <grub/parser.h>
+#include <grub/extcmd.h>
+
+/* The current word.  */
+static char *current_word;
+
+/* The matched string.  */
+static char *match;
+
+/* The count of candidates.  */
+static int num_found;
+
+/* The string to be appended.  */
+static const char *suffix;
+
+/* The callback function to print items.  */
+static void (*print_func) (const char *, grub_completion_type_t, int);
+
+/* The state the command line is in.  */
+static grub_parser_state_t cmdline_state;
+\f
+
+/* Add a string to the list of possible completions. COMPLETION is the
+   string that should be added. EXTRA will be appended if COMPLETION
+   matches uniquely. The type TYPE specifies what kind of data is added.  */
+static int
+add_completion (const char *completion, const char *extra,
+               grub_completion_type_t type)
+{
+  if (grub_strncmp (current_word, completion, grub_strlen (current_word)) == 0)
+    {
+      num_found++;
+
+      switch (num_found)
+       {
+       case 1:
+         match = grub_strdup (completion);
+         if (! match)
+           return 1;
+         suffix = extra;
+         break;
+
+       case 2:
+         if (print_func)
+           print_func (match, type, 0);
+
+         /* Fall through.  */
+
+       default:
+         {
+           char *s = match;
+           const char *t = completion;
+
+           if (print_func)
+             print_func (completion, type, num_found - 1);
+
+           /* Detect the matched portion.  */
+           while (*s && *t && *s == *t)
+             {
+               s++;
+               t++;
+             }
+
+           *s = '\0';
+         }
+         break;
+       }
+    }
+
+  return 0;
+}
+
+static int
+iterate_partition (grub_disk_t disk, const grub_partition_t p)
+{
+  const char *disk_name = disk->name;
+  char *partition_name = grub_partition_get_name (p);
+  char *name;
+  int ret;
+
+  if (! partition_name)
+    return 1;
+
+  name = grub_xasprintf ("%s,%s", disk_name, partition_name);
+  grub_free (partition_name);
+
+  if (! name)
+    return 1;
+
+  ret = add_completion (name, ")", GRUB_COMPLETION_TYPE_PARTITION);
+  grub_free (name);
+  return ret;
+}
+
+static int
+iterate_dir (const char *filename, const struct grub_dirhook_info *info)
+{
+  if (! info->dir)
+    {
+      const char *prefix;
+      if (cmdline_state == GRUB_PARSER_STATE_DQUOTE)
+       prefix = "\" ";
+      else if (cmdline_state == GRUB_PARSER_STATE_QUOTE)
+       prefix = "\' ";
+      else
+       prefix = " ";
+
+      if (add_completion (filename, prefix, GRUB_COMPLETION_TYPE_FILE))
+       return 1;
+    }
+  else if (grub_strcmp (filename, ".") && grub_strcmp (filename, ".."))
+    {
+      char *fname;
+
+      fname = grub_xasprintf ("%s/", filename);
+      if (add_completion (fname, "", GRUB_COMPLETION_TYPE_FILE))
+       {
+         grub_free (fname);
+         return 1;
+       }
+      grub_free (fname);
+    }
+
+  return 0;
+}
+
+static int
+iterate_dev (const char *devname)
+{
+  grub_device_t dev;
+
+  /* Complete the partition part.  */
+  dev = grub_device_open (devname);
+
+  if (dev)
+    {
+      if (dev->disk && dev->disk->has_partitions)
+       {
+         if (add_completion (devname, ",", GRUB_COMPLETION_TYPE_DEVICE))
+           return 1;
+       }
+      else
+       {
+         if (add_completion (devname, ")", GRUB_COMPLETION_TYPE_DEVICE))
+           return 1;
+       }
+    }
+
+  grub_errno = GRUB_ERR_NONE;
+  return 0;
+}
+
+static int
+iterate_command (grub_command_t cmd)
+{
+  if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE)
+    {
+      if (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE)
+       {
+         if (add_completion (cmd->name, " ", GRUB_COMPLETION_TYPE_COMMAND))
+           return 1;
+       }
+    }
+
+  return 0;
+}
+
+/* Complete a device.  */
+static int
+complete_device (void)
+{
+  /* Check if this is a device or a partition.  */
+  char *p = grub_strchr (++current_word, ',');
+  grub_device_t dev;
+
+  if (! p)
+    {
+      /* Complete the disk part.  */
+      if (grub_disk_dev_iterate (iterate_dev))
+       return 1;
+    }
+  else
+    {
+      /* Complete the partition part.  */
+      *p = '\0';
+      dev = grub_device_open (current_word);
+      *p = ',';
+      grub_errno = GRUB_ERR_NONE;
+
+      if (dev)
+       {
+         if (dev->disk && dev->disk->has_partitions)
+           {
+             if (grub_partition_iterate (dev->disk, iterate_partition))
+               {
+                 grub_device_close (dev);
+                 return 1;
+               }
+           }
+
+         grub_device_close (dev);
+       }
+      else
+       return 1;
+    }
+
+  return 0;
+}
+
+/* Complete a file.  */
+static int
+complete_file (void)
+{
+  char *device;
+  char *dir;
+  char *last_dir;
+  grub_fs_t fs;
+  grub_device_t dev;
+  int ret = 0;
+
+  device = grub_file_get_device_name (current_word);
+  if (grub_errno != GRUB_ERR_NONE)
+    return 1;
+
+  dev = grub_device_open (device);
+  if (! dev)
+    {
+      ret = 1;
+      goto fail;
+    }
+
+  fs = grub_fs_probe (dev);
+  if (! fs)
+    {
+      ret = 1;
+      goto fail;
+    }
+
+  dir = grub_strchr (current_word, '/');
+  last_dir = grub_strrchr (current_word, '/');
+  if (dir)
+    {
+      char *dirfile;
+
+      current_word = last_dir + 1;
+
+      dir = grub_strdup (dir);
+      if (! dir)
+       {
+         ret = 1;
+         goto fail;
+       }
+
+      /* Cut away the filename part.  */
+      dirfile = grub_strrchr (dir, '/');
+      dirfile[1] = '\0';
+
+      /* Iterate the directory.  */
+      (fs->dir) (dev, dir, iterate_dir);
+
+      grub_free (dir);
+
+      if (grub_errno)
+       {
+         ret = 1;
+         goto fail;
+       }
+    }
+  else
+    {
+      current_word += grub_strlen (current_word);
+      match = grub_strdup ("/");
+      if (! match)
+       {
+         ret = 1;
+         goto fail;
+       }
+
+      suffix = "";
+      num_found = 1;
+    }
+
+ fail:
+  if (dev)
+    grub_device_close (dev);
+  grub_free (device);
+  return ret;
+}
+
+/* Complete an argument.  */
+static int
+complete_arguments (char *command)
+{
+  grub_command_t cmd;
+  grub_extcmd_t ext;
+  const struct grub_arg_option *option;
+  char shortarg[] = "- ";
+
+  cmd = grub_command_find (command);
+
+  if (!cmd || !(cmd->flags & GRUB_COMMAND_FLAG_EXTCMD))
+    return 0;
+
+  ext = cmd->data;
+  if (!ext->options)
+    return 0;
+
+  if (add_completion ("-u", " ", GRUB_COMPLETION_TYPE_ARGUMENT))
+    return 1;
+
+  /* Add the short arguments.  */
+  for (option = ext->options; option->doc; option++)
+    {
+      if (! option->shortarg)
+       continue;
+
+      shortarg[1] = option->shortarg;
+      if (add_completion (shortarg, " ", GRUB_COMPLETION_TYPE_ARGUMENT))
+       return 1;
+
+    }
+
+  /* First add the built-in arguments.  */
+  if (add_completion ("--help", " ", GRUB_COMPLETION_TYPE_ARGUMENT))
+    return 1;
+  if (add_completion ("--usage", " ", GRUB_COMPLETION_TYPE_ARGUMENT))
+    return 1;
+
+  /* Add the long arguments.  */
+  for (option = ext->options; option->doc; option++)
+    {
+      char *longarg;
+      if (!option->longarg)
+       continue;
+
+      longarg = grub_xasprintf ("--%s", option->longarg);
+      if (!longarg)
+       return 1;
+
+      if (add_completion (longarg, " ", GRUB_COMPLETION_TYPE_ARGUMENT))
+       {
+         grub_free (longarg);
+         return 1;
+       }
+      grub_free (longarg);
+    }
+
+  return 0;
+}
+
+
+static grub_parser_state_t
+get_state (const char *cmdline)
+{
+  grub_parser_state_t state = GRUB_PARSER_STATE_TEXT;
+  char use;
+
+  while (*cmdline)
+    state = grub_parser_cmdline_state (state, *(cmdline++), &use);
+  return state;
+}
+
+
+/* Try to complete the string in BUF. Return the characters that
+   should be added to the string.  This command outputs the possible
+   completions by calling HOOK, in that case set RESTORE to 1 so the
+   caller can restore the prompt.  */
+char *
+grub_normal_do_completion (char *buf, int *restore,
+                          void (*hook) (const char *, grub_completion_type_t, int))
+{
+  int argc;
+  char **argv;
+
+  /* Initialize variables.  */
+  match = 0;
+  num_found = 0;
+  suffix = "";
+  print_func = hook;
+
+  *restore = 1;
+
+  if (grub_parser_split_cmdline (buf, 0, &argc, &argv))
+    return 0;
+
+  if (argc == 0)
+    current_word = "";
+  else
+    current_word = argv[argc - 1];
+
+  /* Determine the state the command line is in, depending on the
+     state, it can be determined how to complete.  */
+  cmdline_state = get_state (buf);
+
+  if (argc == 1 || argc == 0)
+    {
+      /* Complete a command.  */
+      if (grub_command_iterate (iterate_command))
+       goto fail;
+    }
+  else if (*current_word == '-')
+    {
+      if (complete_arguments (buf))
+       goto fail;
+    }
+  else if (*current_word == '(' && ! grub_strchr (current_word, ')'))
+    {
+      /* Complete a device.  */
+      if (complete_device ())
+           goto fail;
+    }
+  else
+    {
+      /* Complete a file.  */
+      if (complete_file ())
+       goto fail;
+    }
+
+  /* If more than one match is found those matches will be printed and
+     the prompt should be restored.  */
+  if (num_found > 1)
+    *restore = 1;
+  else
+    *restore = 0;
+
+  /* Return the part that matches.  */
+  if (match)
+    {
+      char *ret;
+      char *escstr;
+      char *newstr;
+      int current_len;
+      int match_len;
+      int spaces = 0;
+
+      current_len = grub_strlen (current_word);
+      match_len = grub_strlen (match);
+
+      /* Count the number of spaces that have to be escaped.  XXX:
+        More than just spaces have to be escaped.  */
+      for (escstr = match + current_len; *escstr; escstr++)
+       if (*escstr == ' ')
+         spaces++;
+
+      ret = grub_malloc (match_len - current_len + grub_strlen (suffix) + spaces + 1);
+      newstr = ret;
+      for (escstr = match + current_len; *escstr; escstr++)
+       {
+         if (*escstr == ' ' && cmdline_state != GRUB_PARSER_STATE_QUOTE
+             && cmdline_state != GRUB_PARSER_STATE_QUOTE)
+           *(newstr++) = '\\';
+         *(newstr++) = *escstr;
+       }
+      *newstr = '\0';
+
+      if (num_found == 1)
+       grub_strcat (ret, suffix);
+
+      if (*ret == '\0')
+       {
+         grub_free (ret);
+          goto fail;
+       }
+
+      if (argc != 0)
+       grub_free (argv[0]);
+      grub_free (match);
+      return ret;
+    }
+
+ fail:
+  if (argc != 0)
+    grub_free (argv[0]);
+  grub_free (match);
+  grub_errno = GRUB_ERR_NONE;
+
+  return 0;
+}
diff --git a/grub-core/normal/context.c b/grub-core/normal/context.c
new file mode 100644 (file)
index 0000000..27adf28
--- /dev/null
@@ -0,0 +1,183 @@
+/* env.c - Environment variables */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/env.h>
+#include <grub/env_private.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/command.h>
+#include <grub/normal.h>
+#include <grub/i18n.h>
+
+struct menu_pointer
+{
+  grub_menu_t menu;
+  struct menu_pointer *prev;
+};
+
+struct menu_pointer initial_menu;
+struct menu_pointer *current_menu = &initial_menu;
+
+void
+grub_env_unset_menu (void)
+{
+  current_menu->menu = NULL;
+}
+
+grub_menu_t
+grub_env_get_menu (void)
+{
+  return current_menu->menu;
+}
+
+void
+grub_env_set_menu (grub_menu_t nmenu)
+{
+  current_menu->menu = nmenu;
+}
+
+grub_err_t
+grub_env_context_open (int export)
+{
+  struct grub_env_context *context;
+  int i;
+  struct menu_pointer *menu;
+
+  context = grub_zalloc (sizeof (*context));
+  if (! context)
+    return grub_errno;
+  menu = grub_zalloc (sizeof (*menu));
+  if (! menu)
+    return grub_errno;
+
+  context->prev = grub_current_context;
+  grub_current_context = context;
+
+  menu->prev = current_menu;
+  current_menu = menu;
+
+  /* Copy exported variables.  */
+  for (i = 0; i < HASHSZ; i++)
+    {
+      struct grub_env_var *var;
+
+      for (var = context->prev->vars[i]; var; var = var->next)
+       {
+         if (export && var->global)
+           {
+             if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE)
+               {
+                 grub_env_context_close ();
+                 return grub_errno;
+               }
+             grub_env_export (var->name);
+             grub_register_variable_hook (var->name, var->read_hook, var->write_hook);
+           }
+       }
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_env_context_close (void)
+{
+  struct grub_env_context *context;
+  int i;
+  struct menu_pointer *menu;
+
+  if (! grub_current_context->prev)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "cannot close the initial context");
+
+  /* Free the variables associated with this context.  */
+  for (i = 0; i < HASHSZ; i++)
+    {
+      struct grub_env_var *p, *q;
+
+      for (p = grub_current_context->vars[i]; p; p = q)
+       {
+         q = p->next;
+          grub_free (p->name);
+         grub_free (p->value);
+         grub_free (p);
+       }
+    }
+
+  /* Restore the previous context.  */
+  context = grub_current_context->prev;
+  grub_free (grub_current_context);
+  grub_current_context = context;
+
+  menu = current_menu->prev;
+  grub_free (current_menu);
+  current_menu = menu;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_env_export (const char *name)
+{
+  struct grub_env_var *var;
+
+  var = grub_env_find (name);
+  if (! var)
+    {
+      grub_err_t err;
+      
+      err = grub_env_set (name, "");
+      if (err)
+       return err;
+      var = grub_env_find (name);
+    }    
+  var->global = 1;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_command_t export_cmd;
+
+static grub_err_t
+grub_cmd_export (struct grub_command *cmd __attribute__ ((unused)),
+                int argc, char **args)
+{
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "no environment variable specified");
+
+  grub_env_export (args[0]);
+  return 0;
+}
+
+void
+grub_context_init (void)
+{
+  grub_env_export ("root");
+  grub_env_export ("prefix");
+
+  export_cmd = grub_register_command ("export", grub_cmd_export,
+                                     N_("ENVVAR"), N_("Export a variable."));
+}
+
+void
+grub_context_fini (void)
+{
+  grub_unregister_command (export_cmd);
+}
diff --git a/grub-core/normal/crypto.c b/grub-core/normal/crypto.c
new file mode 100644 (file)
index 0000000..465c9f8
--- /dev/null
@@ -0,0 +1,151 @@
+/* crypto.c - support crypto autoload */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/crypto.h>
+#include <grub/normal.h>
+
+struct load_spec
+{
+  struct load_spec *next;
+  char *name;
+  char *modname;
+};
+
+struct load_spec *crypto_specs = NULL;
+
+static void 
+grub_crypto_autoload (const char *name)
+{
+  struct load_spec *cur;
+  grub_dl_t mod;
+  
+  for (cur = crypto_specs; cur; cur = cur->next)
+    if (grub_strcasecmp (name, cur->name) == 0)
+      {
+       mod = grub_dl_load (cur->modname);
+       if (mod)
+         grub_dl_ref (mod);
+       grub_errno = GRUB_ERR_NONE;
+      }
+}
+
+static void 
+grub_crypto_spec_free (void)
+{
+  struct load_spec *cur, *next;
+  for (cur = crypto_specs; cur; cur = next)
+    {
+      next = cur->next;
+      grub_free (cur->name);
+      grub_free (cur->modname);
+      grub_free (cur);
+    }
+  crypto_specs = NULL;
+}
+
+
+/* Read the file crypto.lst for auto-loading.  */
+void
+read_crypto_list (const char *prefix)
+{
+  char *filename;
+  grub_file_t file;
+  char *buf = NULL;
+
+  if (!prefix)
+    {
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+  
+  filename = grub_xasprintf ("%s/crypto.lst", prefix);
+  if (!filename)
+    {
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+
+  file = grub_file_open (filename);
+  grub_free (filename);
+  if (!file)
+    {
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+
+  /* Override previous crypto.lst.  */
+  grub_crypto_spec_free ();
+
+  for (;; grub_free (buf))
+    {
+      char *p, *name;
+      struct load_spec *cur;
+      
+      buf = grub_file_getline (file);
+       
+      if (! buf)
+       break;
+      
+      name = buf;
+            
+      p = grub_strchr (name, ':');
+      if (! p)
+       continue;
+      
+      *p = '\0';
+      while (*++p == ' ')
+       ;
+
+      cur = grub_malloc (sizeof (*cur));
+      if (!cur)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         continue;
+       }
+      
+      cur->name = grub_strdup (name);
+      if (! name)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         grub_free (cur);
+         continue;
+       }
+       
+      cur->modname = grub_strdup (p);
+      if (! cur->modname)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         grub_free (cur);
+         grub_free (cur->name);
+         continue;
+       }
+      cur->next = crypto_specs;
+      crypto_specs = cur;
+    }
+  
+  grub_file_close (file);
+
+  grub_errno = GRUB_ERR_NONE;
+
+  grub_crypto_autoload_hook = grub_crypto_autoload;
+}
diff --git a/grub-core/normal/datetime.c b/grub-core/normal/datetime.c
new file mode 100644 (file)
index 0000000..44791e1
--- /dev/null
@@ -0,0 +1,100 @@
+/* datetime.c - Module for common datetime function.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/datetime.h>
+
+static char *grub_weekday_names[] =
+{
+  "Sunday",
+  "Monday",
+  "Tuesday",
+  "Wednesday",
+  "Thursday",
+  "Friday",
+  "Saturday",
+};
+
+int
+grub_get_weekday (struct grub_datetime *datetime)
+{
+  int a, y, m;
+
+  a = (14 - datetime->month) / 12;
+  y = datetime->year - a;
+  m = datetime->month + 12 * a - 2;
+
+  return (datetime->day + y + y / 4 - y / 100 + y / 400 + (31 * m / 12)) % 7;
+}
+
+char *
+grub_get_weekday_name (struct grub_datetime *datetime)
+{
+  return grub_weekday_names[grub_get_weekday (datetime)];
+}
+
+#define SECPERMIN 60
+#define SECPERHOUR (60*SECPERMIN)
+#define SECPERDAY (24*SECPERHOUR)
+#define SECPERYEAR (365*SECPERDAY)
+#define SECPER4YEARS (4*SECPERYEAR+SECPERDAY)
+
+
+void
+grub_unixtime2datetime (grub_int32_t nix, struct grub_datetime *datetime)
+{
+  int i;
+  int div;
+  grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+  /* In the period of validity of unixtime all years divisible by 4
+     are bissextile*/
+  /* Convenience: let's have 3 consecutive non-bissextile years
+     at the beginning of the epoch. So count from 1973 instead of 1970 */
+  nix -= 3*SECPERYEAR + SECPERDAY;
+  /* Transform C divisions and modulos to mathematical ones */
+  div = nix / SECPER4YEARS;
+  if (nix < 0)
+    div--;
+  datetime->year = 1973 + 4 * div;
+  nix -= div * SECPER4YEARS;
+
+  /* On 31st December of bissextile years 365 days from the beginning
+     of the year elapsed but year isn't finished yet */
+  if (nix / SECPERYEAR == 4)
+    {
+      datetime->year += 3;
+      nix -= 3*SECPERYEAR;
+    }
+  else
+    {
+      datetime->year += nix / SECPERYEAR;
+      nix %= SECPERYEAR;
+    }
+  for (i = 0; i < 12
+        && nix >= ((grub_int32_t) (i==1 && datetime->year % 4 == 0
+                                   ? 29 : months[i]))*SECPERDAY; i++)
+    nix -= ((grub_int32_t) (i==1 && datetime->year % 4 == 0
+                           ? 29 : months[i]))*SECPERDAY;
+  datetime->month = i + 1;
+  datetime->day = 1 + (nix / SECPERDAY);
+  nix %= SECPERDAY;
+  datetime->hour = (nix / SECPERHOUR);
+  nix %= SECPERHOUR;
+  datetime->minute = nix / SECPERMIN;
+  datetime->second = nix % SECPERMIN;
+}
diff --git a/grub-core/normal/dyncmd.c b/grub-core/normal/dyncmd.c
new file mode 100644 (file)
index 0000000..a3cafa5
--- /dev/null
@@ -0,0 +1,167 @@
+/* dyncmd.c - support dynamic command */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+#include <grub/normal.h>
+#include <grub/i18n.h>
+
+static grub_err_t
+grub_dyncmd_dispatcher (struct grub_command *cmd,
+                       int argc, char **args)
+{
+  char *modname = cmd->data;
+  grub_dl_t mod;
+  grub_err_t ret;
+
+  mod = grub_dl_load (modname);
+  if (mod)
+    {
+      char *name;
+
+      grub_free (modname);
+      grub_dl_ref (mod);
+
+      name = (char *) cmd->name;
+      grub_unregister_command (cmd);
+
+      cmd = grub_command_find (name);
+      if (cmd)
+       ret = (cmd->func) (cmd, argc, args);
+      else
+       ret = grub_errno;
+
+      grub_free (name);
+    }
+  else
+    ret = grub_errno;
+
+  return ret;
+}
+
+/* Read the file command.lst for auto-loading.  */
+void
+read_command_list (const char *prefix)
+{
+  if (prefix)
+    {
+      char *filename;
+
+      filename = grub_xasprintf ("%s/command.lst", prefix);
+      if (filename)
+       {
+         grub_file_t file;
+
+         file = grub_file_open (filename);
+         if (file)
+           {
+             char *buf = NULL;
+             grub_command_t ptr, last = 0, next;
+
+             /* Override previous commands.lst.  */
+             for (ptr = grub_command_list; ptr; ptr = next)
+               {
+                 next = ptr->next;
+                 if (ptr->func == grub_dyncmd_dispatcher)
+                   {
+                     if (last)
+                       last->next = ptr->next;
+                     else
+                       grub_command_list = ptr->next;
+                     grub_free (ptr);
+                   }
+                 else
+                   last = ptr;
+               }
+
+             for (;; grub_free (buf))
+               {
+                 char *p, *name, *modname;
+                 grub_command_t cmd;
+                 int prio = 0;
+
+                 buf = grub_file_getline (file);
+
+                 if (! buf)
+                   break;
+
+                 name = buf;
+                 if (*name == '*')
+                   {
+                     name++;
+                     prio++;
+                   }
+
+                 if (! grub_isgraph (name[0]))
+                   continue;
+
+                 p = grub_strchr (name, ':');
+                 if (! p)
+                   continue;
+
+                 *p = '\0';
+                 while (*++p == ' ')
+                   ;
+
+                 if (! grub_isgraph (*p))
+                   continue;
+
+                 if (grub_dl_get (p))
+                   continue;
+
+                 name = grub_strdup (name);
+                 if (! name)
+                   continue;
+
+                 modname = grub_strdup (p);
+                 if (! modname)
+                   {
+                     grub_free (name);
+                     continue;
+                   }
+
+                 cmd = grub_register_command_prio (name,
+                                                   grub_dyncmd_dispatcher,
+                                                   0, N_("not loaded"), prio);
+                 if (! cmd)
+                   {
+                     grub_free (name);
+                     grub_free (modname);
+                     continue;
+                   }
+                 cmd->flags |= GRUB_COMMAND_FLAG_DYNCMD;
+                 cmd->data = modname;
+
+                 /* Update the active flag.  */
+                 grub_command_find (name);
+               }
+
+             grub_file_close (file);
+           }
+
+         grub_free (filename);
+       }
+    }
+
+  /* Ignore errors.  */
+  grub_errno = GRUB_ERR_NONE;
+}
diff --git a/grub-core/normal/handler.c b/grub-core/normal/handler.c
new file mode 100644 (file)
index 0000000..6866269
--- /dev/null
@@ -0,0 +1,231 @@
+/* handler.c - support handler loading */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+#include <grub/handler.h>
+#include <grub/normal.h>
+
+struct grub_handler_list
+{
+  struct grub_handler_list *next;
+  char *name;
+  grub_command_t cmd;
+};
+
+static grub_list_t handler_list;
+
+static grub_err_t
+grub_handler_cmd (struct grub_command *cmd,
+                 int argc __attribute__ ((unused)),
+                 char **args __attribute__ ((unused)))
+{
+  char *p;
+  grub_handler_class_t class;
+  grub_handler_t handler;
+
+  p = grub_strchr (cmd->name, '.');
+  if (! p)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid command name");
+
+  if (cmd->data)
+    {
+      if (! grub_dl_get (cmd->data))
+       {
+         grub_dl_t mod;
+
+         mod = grub_dl_load (cmd->data);
+         if (mod)
+           grub_dl_ref (mod);
+         else
+           return grub_errno;
+       }
+      grub_free (cmd->data);
+      cmd->data = 0;
+    }
+
+  *p = 0;
+  class = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_handler_class_list),
+                               cmd->name);
+  *p = '.';
+
+  if (! class)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found");
+
+
+  handler = grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list),
+                                 p + 1);
+  if (! handler)
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found");
+
+  grub_handler_set_current (class, handler);
+
+  return 0;
+}
+
+static void
+insert_handler (char *name, char *module)
+{
+  struct grub_handler_list *item;
+  char *data;
+
+  if (grub_command_find (name))
+    return;
+
+  item = grub_malloc (sizeof (*item));
+  if (! item)
+    return;
+
+  item->name = grub_strdup (name);
+  if (! item->name)
+    {
+      grub_free (item);
+      return;
+    }
+
+  if (module)
+    {
+      data = grub_strdup (module);
+      if (! data)
+       {
+         grub_free (item->name);
+         grub_free (item);
+         return;
+       }
+    }
+  else
+    data = 0;
+
+  item->cmd = grub_register_command (item->name, grub_handler_cmd, 0,
+                                    "Set active handler.");
+  if (! item->cmd)
+    {
+      grub_free (data);
+      grub_free (item->name);
+      grub_free (item);
+      return;
+    }
+
+  item->cmd->data = data;
+  grub_list_push (&handler_list, GRUB_AS_LIST (item));
+}
+
+/* Read the file handler.lst for auto-loading.  */
+void
+read_handler_list (void)
+{
+  const char *prefix;
+  static int first_time = 1;
+  const char *class_name;
+
+  auto int iterate_handler (grub_handler_t handler);
+  int iterate_handler (grub_handler_t handler)
+    {
+      char name[grub_strlen (class_name) + grub_strlen (handler->name) + 2];
+
+      grub_strcpy (name, class_name);
+      grub_strcat (name, ".");
+      grub_strcat (name, handler->name);
+
+      insert_handler (name, 0);
+
+      return 0;
+    }
+
+  auto int iterate_class (grub_handler_class_t class);
+  int iterate_class (grub_handler_class_t class)
+    {
+      class_name = class->name;
+      grub_list_iterate (GRUB_AS_LIST (class->handler_list),
+                        (grub_list_hook_t) iterate_handler);
+
+      return 0;
+    }
+
+  /* Make sure that this function does not get executed twice.  */
+  if (! first_time)
+    return;
+  first_time = 0;
+
+  prefix = grub_env_get ("prefix");
+  if (prefix)
+    {
+      char *filename;
+
+      filename = grub_xasprintf ("%s/handler.lst", prefix);
+      if (filename)
+       {
+         grub_file_t file;
+
+         file = grub_file_open (filename);
+         if (file)
+           {
+             char *buf = NULL;
+             for (;; grub_free (buf))
+               {
+                 char *p;
+
+                 buf = grub_file_getline (file);
+
+                 if (! buf)
+                   break;
+
+                 if (! grub_isgraph (buf[0]))
+                   continue;
+
+                 p = grub_strchr (buf, ':');
+                 if (! p)
+                   continue;
+
+                 *p = '\0';
+                 while (*++p == ' ')
+                   ;
+
+                 insert_handler (buf, p);
+               }
+             grub_file_close (file);
+           }
+         grub_free (filename);
+       }
+    }
+
+  grub_list_iterate (GRUB_AS_LIST (grub_handler_class_list),
+                    (grub_list_hook_t) iterate_class);
+
+  /* Ignore errors.  */
+  grub_errno = GRUB_ERR_NONE;
+}
+
+void
+free_handler_list (void)
+{
+  struct grub_handler_list *item;
+
+  while ((item = grub_list_pop (&handler_list)) != 0)
+    {
+      grub_free (item->cmd->data);
+      grub_unregister_command (item->cmd);
+      grub_free (item->name);
+      grub_free (item);
+    }
+}
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
new file mode 100644 (file)
index 0000000..4ed17e8
--- /dev/null
@@ -0,0 +1,729 @@
+/* main.c - the normal mode main routine */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002,2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/file.h>
+#include <grub/mm.h>
+#include <grub/term.h>
+#include <grub/env.h>
+#include <grub/parser.h>
+#include <grub/reader.h>
+#include <grub/menu_viewer.h>
+#include <grub/auth.h>
+#include <grub/i18n.h>
+#include <grub/charset.h>
+
+#define GRUB_DEFAULT_HISTORY_SIZE      50
+
+static int nested_level = 0;
+int grub_normal_exit_level = 0;
+
+/* Read a line from the file FILE.  */
+char *
+grub_file_getline (grub_file_t file)
+{
+  char c;
+  int pos = 0;
+  int literal = 0;
+  char *cmdline;
+  int max_len = 64;
+
+  /* Initially locate some space.  */
+  cmdline = grub_malloc (max_len);
+  if (! cmdline)
+    return 0;
+
+  while (1)
+    {
+      if (grub_file_read (file, &c, 1) != 1)
+       break;
+
+      /* Skip all carriage returns.  */
+      if (c == '\r')
+       continue;
+
+      /* Replace tabs with spaces.  */
+      if (c == '\t')
+       c = ' ';
+
+      /* The previous is a backslash, then...  */
+      if (literal)
+       {
+         /* If it is a newline, replace it with a space and continue.  */
+         if (c == '\n')
+           {
+             c = ' ';
+
+             /* Go back to overwrite the backslash.  */
+             if (pos > 0)
+               pos--;
+           }
+
+         literal = 0;
+       }
+
+      if (c == '\\')
+       literal = 1;
+
+      if (pos == 0)
+       {
+         if (! grub_isspace (c))
+           cmdline[pos++] = c;
+       }
+      else
+       {
+         if (pos >= max_len)
+           {
+             char *old_cmdline = cmdline;
+             max_len = max_len * 2;
+             cmdline = grub_realloc (cmdline, max_len);
+             if (! cmdline)
+               {
+                 grub_free (old_cmdline);
+                 return 0;
+               }
+           }
+
+         if (c == '\n')
+           break;
+
+         cmdline[pos++] = c;
+       }
+    }
+
+  cmdline[pos] = '\0';
+
+  /* If the buffer is empty, don't return anything at all.  */
+  if (pos == 0)
+    {
+      grub_free (cmdline);
+      cmdline = 0;
+    }
+
+  return cmdline;
+}
+
+static void
+free_menu (grub_menu_t menu)
+{
+  grub_menu_entry_t entry = menu->entry_list;
+
+  while (entry)
+    {
+      grub_menu_entry_t next_entry = entry->next;
+
+      grub_free ((void *) entry->title);
+      grub_free ((void *) entry->sourcecode);
+      entry = next_entry;
+    }
+
+  grub_free (menu);
+  grub_env_unset_menu ();
+}
+
+static void
+free_menu_entry_classes (struct grub_menu_entry_class *head)
+{
+  /* Free all the classes.  */
+  while (head)
+    {
+      struct grub_menu_entry_class *next;
+
+      grub_free (head->name);
+      next = head->next;
+      grub_free (head);
+      head = next;
+    }
+}
+
+static struct
+{
+  char *name;
+  int key;
+} hotkey_aliases[] =
+  {
+    {"backspace", '\b'},
+    {"tab", '\t'},
+    {"delete", GRUB_TERM_DC}
+  };
+
+/* Add a menu entry to the current menu context (as given by the environment
+   variable data slot `menu').  As the configuration file is read, the script
+   parser calls this when a menu entry is to be created.  */
+grub_err_t
+grub_normal_add_menu_entry (int argc, const char **args,
+                           const char *sourcecode)
+{
+  const char *menutitle = 0;
+  const char *menusourcecode;
+  grub_menu_t menu;
+  grub_menu_entry_t *last;
+  int failed = 0;
+  int i;
+  struct grub_menu_entry_class *classes_head;  /* Dummy head node for list.  */
+  struct grub_menu_entry_class *classes_tail;
+  char *users = NULL;
+  int hotkey = 0;
+
+  /* Allocate dummy head node for class list.  */
+  classes_head = grub_zalloc (sizeof (struct grub_menu_entry_class));
+  if (! classes_head)
+    return grub_errno;
+  classes_tail = classes_head;
+
+  menu = grub_env_get_menu ();
+  if (! menu)
+    return grub_error (GRUB_ERR_MENU, "no menu context");
+
+  last = &menu->entry_list;
+
+  menusourcecode = grub_strdup (sourcecode);
+  if (! menusourcecode)
+    return grub_errno;
+
+  /* Parse menu arguments.  */
+  for (i = 0; i < argc; i++)
+    {
+      /* Capture arguments.  */
+      if (grub_strncmp ("--", args[i], 2) == 0)
+       {
+         const char *arg = &args[i][2];
+
+         /* Handle menu class.  */
+         if (grub_strcmp(arg, "class") == 0)
+           {
+             char *class_name;
+             struct grub_menu_entry_class *new_class;
+
+             i++;
+             class_name = grub_strdup (args[i]);
+             if (! class_name)
+               {
+                 failed = 1;
+                 break;
+               }
+
+             /* Create a new class and add it at the tail of the list.  */
+             new_class = grub_zalloc (sizeof (struct grub_menu_entry_class));
+             if (! new_class)
+               {
+                 grub_free (class_name);
+                 failed = 1;
+                 break;
+               }
+             /* Fill in the new class node.  */
+             new_class->name = class_name;
+             /* Link the tail to it, and make it the new tail.  */
+             classes_tail->next = new_class;
+             classes_tail = new_class;
+             continue;
+           }
+         else if (grub_strcmp(arg, "users") == 0)
+           {
+             i++;
+             users = grub_strdup (args[i]);
+             if (! users)
+               {
+                 failed = 1;
+                 break;
+               }
+
+             continue;
+           }
+         else if (grub_strcmp(arg, "hotkey") == 0)
+           {
+             unsigned j;
+
+             i++;
+             if (args[i][1] == 0)
+               {
+                 hotkey = args[i][0];
+                 continue;
+               }
+
+             for (j = 0; j < ARRAY_SIZE (hotkey_aliases); j++)
+               if (grub_strcmp (args[i], hotkey_aliases[j].name) == 0)
+                 {
+                   hotkey = hotkey_aliases[j].key;
+                   break;
+                 }
+
+             if (j < ARRAY_SIZE (hotkey_aliases))
+               continue;
+
+             failed = 1;
+             grub_error (GRUB_ERR_MENU,
+                         "Invalid hotkey: '%s'.", args[i]);
+             break;
+           }
+         else
+           {
+             /* Handle invalid argument.  */
+             failed = 1;
+             grub_error (GRUB_ERR_MENU,
+                         "invalid argument for menuentry: %s", args[i]);
+             break;
+           }
+       }
+
+      /* Capture title.  */
+      if (! menutitle)
+       {
+         menutitle = grub_strdup (args[i]);
+       }
+      else
+       {
+         failed = 1;
+         grub_error (GRUB_ERR_MENU,
+                     "too many titles for menuentry: %s", args[i]);
+         break;
+       }
+    }
+
+  /* Validate arguments.  */
+  if ((! failed) && (! menutitle))
+    {
+      grub_error (GRUB_ERR_MENU, "menuentry is missing title");
+      failed = 1;
+    }
+
+  /* If argument parsing failed, free any allocated resources.  */
+  if (failed)
+    {
+      free_menu_entry_classes (classes_head);
+      grub_free ((void *) menutitle);
+      grub_free ((void *) menusourcecode);
+
+      /* Here we assume that grub_error has been used to specify failure details.  */
+      return grub_errno;
+    }
+
+  /* Add the menu entry at the end of the list.  */
+  while (*last)
+    last = &(*last)->next;
+
+  *last = grub_zalloc (sizeof (**last));
+  if (! *last)
+    {
+      free_menu_entry_classes (classes_head);
+      grub_free ((void *) menutitle);
+      grub_free ((void *) menusourcecode);
+      return grub_errno;
+    }
+
+  (*last)->title = menutitle;
+  (*last)->hotkey = hotkey;
+  (*last)->classes = classes_head;
+  if (users)
+    (*last)->restricted = 1;
+  (*last)->users = users;
+  (*last)->sourcecode = menusourcecode;
+
+  menu->size++;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_menu_t
+read_config_file (const char *config)
+{
+  grub_file_t file;
+  grub_parser_t old_parser = 0;
+
+  auto grub_err_t getline (char **line, int cont);
+  grub_err_t getline (char **line, int cont __attribute__ ((unused)))
+    {
+      while (1)
+       {
+         char *buf;
+
+         *line = buf = grub_file_getline (file);
+         if (! buf)
+           return grub_errno;
+
+         if (buf[0] == '#')
+           {
+             if (buf[1] == '!')
+               {
+                 grub_parser_t parser;
+                 grub_named_list_t list;
+
+                 buf += 2;
+                 while (grub_isspace (*buf))
+                   buf++;
+
+                 if (! old_parser)
+                   old_parser = grub_parser_get_current ();
+
+                 list = GRUB_AS_NAMED_LIST (grub_parser_class.handler_list);
+                 parser = grub_named_list_find (list, buf);
+                 if (parser)
+                   grub_parser_set_current (parser);
+                 else
+                   {
+                     char cmd_name[8 + grub_strlen (buf)];
+
+                     /* Perhaps it's not loaded yet, try the autoload
+                        command.  */
+                     grub_strcpy (cmd_name, "parser.");
+                     grub_strcat (cmd_name, buf);
+                     grub_command_execute (cmd_name, 0, 0);
+                   }
+               }
+             grub_free (*line);
+           }
+         else
+           break;
+       }
+
+      return GRUB_ERR_NONE;
+    }
+
+  grub_menu_t newmenu;
+
+  newmenu = grub_env_get_menu ();
+  if (! newmenu)
+    {
+      newmenu = grub_zalloc (sizeof (*newmenu));
+      if (! newmenu)
+       return 0;
+
+      grub_env_set_menu (newmenu);
+    }
+
+  /* Try to open the config file.  */
+  file = grub_file_open (config);
+  if (! file)
+    return 0;
+
+  while (1)
+    {
+      char *line;
+
+      /* Print an error, if any.  */
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+
+      if ((getline (&line, 0)) || (! line))
+       break;
+
+      grub_parser_get_current ()->parse_line (line, getline);
+      grub_free (line);
+    }
+
+  grub_file_close (file);
+
+  if (old_parser)
+    grub_parser_set_current (old_parser);
+
+  return newmenu;
+}
+
+/* Initialize the screen.  */
+void
+grub_normal_init_page (struct grub_term_output *term)
+{
+  int msg_len;
+  int posx;
+  const char *msg = _("GNU GRUB  version %s");
+  char *msg_formatted;
+  grub_uint32_t *unicode_msg;
+  grub_uint32_t *last_position;
+  grub_term_cls (term);
+
+  msg_formatted = grub_xasprintf (msg, PACKAGE_VERSION);
+  if (!msg_formatted)
+    return;
+  msg_len = grub_utf8_to_ucs4_alloc (msg_formatted,
+                                    &unicode_msg, &last_position);
+  grub_free (msg_formatted);
+  if (msg_len < 0)
+    {
+      return;
+    }
+
+  posx = grub_getstringwidth (unicode_msg, last_position, term);
+  posx = (grub_term_width (term) - posx) / 2;
+  grub_term_gotoxy (term, posx, 1);
+
+  grub_print_ucs4 (unicode_msg, last_position, term);
+  grub_printf("\n\n");
+  grub_free (unicode_msg);
+}
+
+static void
+read_lists (const char *val)
+{
+  read_command_list (val);
+  read_fs_list (val);
+  read_crypto_list (val);
+  read_terminal_list (val);
+}
+
+static char *
+read_lists_hook (struct grub_env_var *var __attribute__ ((unused)),
+                const char *val)
+{
+  read_lists (val);
+  return val ? grub_strdup (val) : NULL;
+}
+
+/* Read the config file CONFIG and execute the menu interface or
+   the command line interface if BATCH is false.  */
+void
+grub_normal_execute (const char *config, int nested, int batch)
+{
+  grub_menu_t menu = 0;
+  const char *prefix = grub_env_get ("prefix");
+
+  read_lists (prefix);
+  read_handler_list ();
+  grub_register_variable_hook ("prefix", NULL, read_lists_hook);
+  grub_command_execute ("parser.grub", 0, 0);
+
+  if (config)
+    {
+      menu = read_config_file (config);
+
+      /* Ignore any error.  */
+      grub_errno = GRUB_ERR_NONE;
+    }
+
+  if (! batch)
+    {
+      if (menu && menu->size)
+       {
+         grub_show_menu (menu, nested);
+         if (nested)
+           free_menu (menu);
+       }
+    }
+}
+
+/* This starts the normal mode.  */
+void
+grub_enter_normal_mode (const char *config)
+{
+  nested_level++;
+  grub_normal_execute (config, 0, 0);
+  grub_cmdline_run (0);
+  nested_level--;
+  if (grub_normal_exit_level)
+    grub_normal_exit_level--;
+}
+
+/* Enter normal mode from rescue mode.  */
+static grub_err_t
+grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)),
+                int argc, char *argv[])
+{
+  if (argc == 0)
+    {
+      /* Guess the config filename. It is necessary to make CONFIG static,
+        so that it won't get broken by longjmp.  */
+      char *config;
+      const char *prefix;
+
+      prefix = grub_env_get ("prefix");
+      if (prefix)
+       {
+         config = grub_xasprintf ("%s/grub.cfg", prefix);
+         if (! config)
+           goto quit;
+
+         grub_enter_normal_mode (config);
+         grub_free (config);
+       }
+      else
+       grub_enter_normal_mode (0);
+    }
+  else
+    grub_enter_normal_mode (argv[0]);
+
+quit:
+  return 0;
+}
+
+/* Exit from normal mode to rescue mode.  */
+static grub_err_t
+grub_cmd_normal_exit (struct grub_command *cmd __attribute__ ((unused)),
+                     int argc __attribute__ ((unused)),
+                     char *argv[] __attribute__ ((unused)))
+{
+  if (nested_level <= grub_normal_exit_level)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "not in normal environment");
+  grub_normal_exit_level++;
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_normal_reader_init (int nested)
+{
+  struct grub_term_output *term;
+  const char *msg = _("Minimal BASH-like line editing is supported. For "
+                     "the first word, TAB lists possible command completions. Anywhere "
+                     "else TAB lists possible device or file completions. %s");
+  const char *msg_esc = _("ESC at any time exits.");
+  char *msg_formatted;
+
+  msg_formatted = grub_xasprintf (msg, nested ? msg_esc : "");
+  if (!msg_formatted)
+    return grub_errno;
+
+  FOR_ACTIVE_TERM_OUTPUTS(term)
+  {
+    grub_normal_init_page (term);
+    grub_term_setcursor (term, 1);
+    
+    grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN, term);
+    grub_puts ("\n");
+  }
+  grub_free (msg_formatted);
+  return 0;
+}
+
+
+static grub_err_t
+grub_normal_read_line_real (char **line, int cont, int nested)
+{
+  grub_parser_t parser = grub_parser_get_current ();
+  char *prompt;
+
+  if (cont)
+    prompt = grub_xasprintf (">");
+  else
+    prompt = grub_xasprintf ("%s>", parser->name);
+
+  if (!prompt)
+    return grub_errno;
+
+  while (1)
+    {
+      *line = grub_cmdline_get (prompt);
+      if (*line)
+       break;
+
+      if (cont || nested)
+       {
+         grub_free (*line);
+         grub_free (prompt);
+         *line = 0;
+         return grub_errno;
+       }
+    }
+  
+  grub_free (prompt);
+
+  return 0;
+}
+
+static grub_err_t
+grub_normal_read_line (char **line, int cont)
+{
+  return grub_normal_read_line_real (line, cont, 0);
+}
+
+void
+grub_cmdline_run (int nested)
+{
+  grub_err_t err = GRUB_ERR_NONE;
+
+  err = grub_auth_check_authentication (NULL);
+
+  if (err)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+
+  grub_normal_reader_init (nested);
+
+  while (1)
+    {
+      char *line;
+
+      if (grub_normal_exit_level)
+       break;
+
+      /* Print an error, if any.  */
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+
+      grub_normal_read_line_real (&line, 0, nested);
+      if (! line)
+       break;
+
+      grub_parser_get_current ()->parse_line (line, grub_normal_read_line);
+      grub_free (line);
+    }
+}
+
+static char *
+grub_env_write_pager (struct grub_env_var *var __attribute__ ((unused)),
+                     const char *val)
+{
+  grub_set_more ((*val == '1'));
+  return grub_strdup (val);
+}
+
+GRUB_MOD_INIT(normal)
+{
+  grub_context_init ();
+
+  /* Normal mode shouldn't be unloaded.  */
+  if (mod)
+    grub_dl_ref (mod);
+
+  grub_set_history (GRUB_DEFAULT_HISTORY_SIZE);
+
+  grub_install_newline_hook ();
+  grub_register_variable_hook ("pager", 0, grub_env_write_pager);
+
+  /* Register a command "normal" for the rescue mode.  */
+  grub_register_command ("normal", grub_cmd_normal,
+                        0, N_("Enter normal mode."));
+  grub_register_command ("normal_exit", grub_cmd_normal_exit,
+                        0, N_("Exit from normal mode."));
+
+  /* Reload terminal colors when these variables are written to.  */
+  grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal);
+  grub_register_variable_hook ("color_highlight", NULL, grub_env_write_color_highlight);
+
+  /* Preserve hooks after context changes.  */
+  grub_env_export ("color_normal");
+  grub_env_export ("color_highlight");
+}
+
+GRUB_MOD_FINI(normal)
+{
+  grub_context_fini ();
+
+  grub_set_history (0);
+  grub_register_variable_hook ("pager", 0, 0);
+  grub_fs_autoload_hook = 0;
+  free_handler_list ();
+}
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
new file mode 100644 (file)
index 0000000..09c5fd1
--- /dev/null
@@ -0,0 +1,613 @@
+/* menu.c - General supporting functionality for menus.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/misc.h>
+#include <grub/loader.h>
+#include <grub/mm.h>
+#include <grub/time.h>
+#include <grub/env.h>
+#include <grub/menu_viewer.h>
+#include <grub/command.h>
+#include <grub/parser.h>
+#include <grub/auth.h>
+#include <grub/i18n.h>
+#include <grub/term.h>
+
+/* Time to delay after displaying an error message about a default/fallback
+   entry failing to boot.  */
+#define DEFAULT_ENTRY_ERROR_DELAY_MS  2500
+
+grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu,
+                                    int nested) = NULL;
+
+/* Wait until the user pushes any key so that the user
+   can see what happened.  */
+void
+grub_wait_after_message (void)
+{
+  grub_putchar ('\n');
+  grub_printf_ (N_("Press any key to continue..."));
+  (void) grub_getkey ();
+  grub_putchar ('\n');
+}
+
+/* Get a menu entry by its index in the entry list.  */
+grub_menu_entry_t
+grub_menu_get_entry (grub_menu_t menu, int no)
+{
+  grub_menu_entry_t e;
+
+  for (e = menu->entry_list; e && no > 0; e = e->next, no--)
+    ;
+
+  return e;
+}
+
+/* Return the current timeout. If the variable "timeout" is not set or
+   invalid, return -1.  */
+int
+grub_menu_get_timeout (void)
+{
+  char *val;
+  int timeout;
+
+  val = grub_env_get ("timeout");
+  if (! val)
+    return -1;
+
+  grub_error_push ();
+
+  timeout = (int) grub_strtoul (val, 0, 0);
+
+  /* If the value is invalid, unset the variable.  */
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_env_unset ("timeout");
+      grub_errno = GRUB_ERR_NONE;
+      timeout = -1;
+    }
+
+  grub_error_pop ();
+
+  return timeout;
+}
+
+/* Set current timeout in the variable "timeout".  */
+void
+grub_menu_set_timeout (int timeout)
+{
+  /* Ignore TIMEOUT if it is zero, because it will be unset really soon.  */
+  if (timeout > 0)
+    {
+      char buf[16];
+
+      grub_snprintf (buf, sizeof (buf), "%d", timeout);
+      grub_env_set ("timeout", buf);
+    }
+}
+
+/* Get the first entry number from the value of the environment variable NAME,
+   which is a space-separated list of non-negative integers.  The entry number
+   which is returned is stripped from the value of NAME.  If no entry number
+   can be found, -1 is returned.  */
+static int
+get_and_remove_first_entry_number (const char *name)
+{
+  char *val;
+  char *tail;
+  int entry;
+
+  val = grub_env_get (name);
+  if (! val)
+    return -1;
+
+  grub_error_push ();
+
+  entry = (int) grub_strtoul (val, &tail, 0);
+
+  if (grub_errno == GRUB_ERR_NONE)
+    {
+      /* Skip whitespace to find the next digit.  */
+      while (*tail && grub_isspace (*tail))
+       tail++;
+      grub_env_set (name, tail);
+    }
+  else
+    {
+      grub_env_unset (name);
+      grub_errno = GRUB_ERR_NONE;
+      entry = -1;
+    }
+
+  grub_error_pop ();
+
+  return entry;
+}
+
+/* Run a menu entry.  */
+void
+grub_menu_execute_entry(grub_menu_entry_t entry)
+{
+  grub_err_t err = GRUB_ERR_NONE;
+
+  if (entry->restricted)
+    err = grub_auth_check_authentication (entry->users);
+
+  if (err)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+
+  grub_env_set ("chosen", entry->title);
+
+  grub_parser_execute ((char *) entry->sourcecode);
+
+  if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
+    /* Implicit execution of boot, only if something is loaded.  */
+    grub_command_execute ("boot", 0, 0);
+}
+
+/* Execute ENTRY from the menu MENU, falling back to entries specified
+   in the environment variable "fallback" if it fails.  CALLBACK is a
+   pointer to a struct of function pointers which are used to allow the
+   caller provide feedback to the user.  */
+void
+grub_menu_execute_with_fallback (grub_menu_t menu,
+                                grub_menu_entry_t entry,
+                                grub_menu_execute_callback_t callback,
+                                void *callback_data)
+{
+  int fallback_entry;
+
+  callback->notify_booting (entry, callback_data);
+
+  grub_menu_execute_entry (entry);
+
+  /* Deal with fallback entries.  */
+  while ((fallback_entry = get_and_remove_first_entry_number ("fallback"))
+        >= 0)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+
+      entry = grub_menu_get_entry (menu, fallback_entry);
+      callback->notify_fallback (entry, callback_data);
+      grub_menu_execute_entry (entry);
+      /* If the function call to execute the entry returns at all, then this is
+        taken to indicate a boot failure.  For menu entries that do something
+        other than actually boot an operating system, this could assume
+        incorrectly that something failed.  */
+    }
+
+  callback->notify_failure (callback_data);
+}
+
+static struct grub_menu_viewer *viewers;
+
+static void
+menu_set_chosen_entry (int entry)
+{
+  struct grub_menu_viewer *cur;
+  for (cur = viewers; cur; cur = cur->next)
+    cur->set_chosen_entry (entry, cur->data);
+}
+
+static void
+menu_print_timeout (int timeout)
+{
+  struct grub_menu_viewer *cur;
+  for (cur = viewers; cur; cur = cur->next)
+    cur->print_timeout (timeout, cur->data);
+}
+
+static void
+menu_fini (void)
+{
+  struct grub_menu_viewer *cur, *next;
+  for (cur = viewers; cur; cur = next)
+    {
+      next = cur->next;
+      cur->fini (cur->data);
+      grub_free (cur);
+    }
+  viewers = NULL;
+}
+
+static void
+menu_init (int entry, grub_menu_t menu, int nested)
+{
+  struct grub_term_output *term;
+
+  FOR_ACTIVE_TERM_OUTPUTS(term)
+  {
+    grub_err_t err;
+
+    if (grub_gfxmenu_try_hook && grub_strcmp (term->name, "gfxterm") == 0)
+      {
+       err = grub_gfxmenu_try_hook (entry, menu, nested);
+       if(!err)
+         continue;
+       grub_print_error ();
+       grub_errno = GRUB_ERR_NONE;
+      }
+
+    err = grub_menu_try_text (term, entry, menu, nested);
+    if(!err)
+      continue;
+    grub_print_error ();
+    grub_errno = GRUB_ERR_NONE;
+  }
+}
+
+static void
+clear_timeout (void)
+{
+  struct grub_menu_viewer *cur;
+  for (cur = viewers; cur; cur = cur->next)
+    cur->clear_timeout (cur->data);
+}
+
+void
+grub_menu_register_viewer (struct grub_menu_viewer *viewer)
+{
+  viewer->next = viewers;
+  viewers = viewer;
+}
+
+/* Get the entry number from the variable NAME.  */
+static int
+get_entry_number (grub_menu_t menu, const char *name)
+{
+  char *val;
+  int entry;
+
+  val = grub_env_get (name);
+  if (! val)
+    return -1;
+
+  grub_error_push ();
+
+  entry = (int) grub_strtoul (val, 0, 0);
+
+  if (grub_errno == GRUB_ERR_BAD_NUMBER)
+    {
+      /* See if the variable matches the title of a menu entry.  */
+      grub_menu_entry_t e = menu->entry_list;
+      int i;
+
+      grub_errno = GRUB_ERR_NONE;
+
+      for (i = 0; e; i++)
+       {
+         if (grub_strcmp (e->title, val) == 0)
+           {
+             entry = i;
+             break;
+           }
+         e = e->next;
+       }
+
+      if (! e)
+       entry = -1;
+    }
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_errno = GRUB_ERR_NONE;
+      entry = -1;
+    }
+
+  grub_error_pop ();
+
+  return entry;
+}
+
+#define GRUB_MENU_PAGE_SIZE 10
+
+/* Show the menu and handle menu entry selection.  Returns the menu entry
+   index that should be executed or -1 if no entry should be executed (e.g.,
+   Esc pressed to exit a sub-menu or switching menu viewers).
+   If the return value is not -1, then *AUTO_BOOT is nonzero iff the menu
+   entry to be executed is a result of an automatic default selection because
+   of the timeout.  */
+static int
+run_menu (grub_menu_t menu, int nested, int *auto_boot)
+{
+  grub_uint64_t saved_time;
+  int default_entry, current_entry;
+  int timeout;
+
+  default_entry = get_entry_number (menu, "default");
+
+  /* If DEFAULT_ENTRY is not within the menu entries, fall back to
+     the first entry.  */
+  if (default_entry < 0 || default_entry >= menu->size)
+    default_entry = 0;
+
+  /* If timeout is 0, drawing is pointless (and ugly).  */
+  if (grub_menu_get_timeout () == 0)
+    {
+      *auto_boot = 1;
+      return default_entry;
+    }
+
+  current_entry = default_entry;
+
+  /* Initialize the time.  */
+  saved_time = grub_get_time_ms ();
+
+ refresh:
+  menu_init (current_entry, menu, nested);
+
+  timeout = grub_menu_get_timeout ();
+
+  if (timeout > 0)
+    menu_print_timeout (timeout);
+  else
+    clear_timeout ();
+
+  while (1)
+    {
+      int c;
+      timeout = grub_menu_get_timeout ();
+
+      if (grub_normal_exit_level)
+       return -1;
+
+      if (timeout > 0)
+       {
+         grub_uint64_t current_time;
+
+         current_time = grub_get_time_ms ();
+         if (current_time - saved_time >= 1000)
+           {
+             timeout--;
+             grub_menu_set_timeout (timeout);
+             saved_time = current_time;
+             menu_print_timeout (timeout);
+           }
+       }
+
+      if (timeout == 0)
+       {
+         grub_env_unset ("timeout");
+          *auto_boot = 1;
+         menu_fini ();
+         return default_entry;
+       }
+
+      if (grub_checkkey () >= 0 || timeout < 0)
+       {
+         c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
+
+         if (timeout >= 0)
+           {
+             grub_env_unset ("timeout");
+             grub_env_unset ("fallback");
+             clear_timeout ();
+           }
+
+         switch (c)
+           {
+           case GRUB_TERM_HOME:
+             current_entry = 0;
+             menu_set_chosen_entry (current_entry);
+             break;
+
+           case GRUB_TERM_END:
+             current_entry = menu->size - 1;
+             menu_set_chosen_entry (current_entry);
+             break;
+
+           case GRUB_TERM_UP:
+           case '^':
+             if (current_entry > 0)
+               current_entry--;
+             menu_set_chosen_entry (current_entry);
+             break;
+
+           case GRUB_TERM_DOWN:
+           case 'v':
+             if (current_entry < menu->size - 1)
+               current_entry++;
+             menu_set_chosen_entry (current_entry);
+             break;
+
+           case GRUB_TERM_PPAGE:
+             if (current_entry < GRUB_MENU_PAGE_SIZE)
+               current_entry = 0;
+             else
+               current_entry -= GRUB_MENU_PAGE_SIZE;
+             menu_set_chosen_entry (current_entry);
+             break;
+
+           case GRUB_TERM_NPAGE:
+             if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size)
+               current_entry += GRUB_MENU_PAGE_SIZE;
+             else
+               current_entry = menu->size - 1;
+             menu_set_chosen_entry (current_entry);
+             break;
+
+           case '\n':
+           case '\r':
+           case 6:
+             menu_fini ();
+              *auto_boot = 0;
+             return current_entry;
+
+           case '\e':
+             if (nested)
+               {
+                 menu_fini ();
+                 return -1;
+               }
+             break;
+
+           case 'c':
+             menu_fini ();
+             grub_cmdline_run (1);
+             goto refresh;
+
+           case 'e':
+             menu_fini ();
+               {
+                 grub_menu_entry_t e = grub_menu_get_entry (menu, current_entry);
+                 if (e)
+                   grub_menu_entry_run (e);
+               }
+             goto refresh;
+
+           default:
+             {
+               grub_menu_entry_t entry;
+               int i;
+               for (i = 0, entry = menu->entry_list; i < menu->size;
+                    i++, entry = entry->next)
+                 if (entry->hotkey == c)
+                   {
+                     menu_fini ();
+                     *auto_boot = 0;
+                     return i;
+                   }
+             }
+             break;
+           }
+       }
+    }
+
+  /* Never reach here.  */
+  return -1;
+}
+
+/* Callback invoked immediately before a menu entry is executed.  */
+static void
+notify_booting (grub_menu_entry_t entry,
+               void *userdata __attribute__((unused)))
+{
+  grub_printf ("  ");
+  grub_printf_ (N_("Booting \'%s\'"), entry->title);
+  grub_printf ("\n\n");
+}
+
+/* Callback invoked when a default menu entry executed because of a timeout
+   has failed and an attempt will be made to execute the next fallback
+   entry, ENTRY.  */
+static void
+notify_fallback (grub_menu_entry_t entry,
+                void *userdata __attribute__((unused)))
+{
+  grub_printf ("\n   ");
+  grub_printf_ (N_("Falling back to \'%s\'"), entry->title);
+  grub_printf ("\n\n");
+  grub_millisleep (DEFAULT_ENTRY_ERROR_DELAY_MS);
+}
+
+/* Callback invoked when a menu entry has failed and there is no remaining
+   fallback entry to attempt.  */
+static void
+notify_execution_failure (void *userdata __attribute__((unused)))
+{
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+    }
+  grub_printf ("\n  ");
+  grub_printf_ (N_("Failed to boot both default and fallback entries.\n"));
+  grub_wait_after_message ();
+}
+
+/* Callbacks used by the text menu to provide user feedback when menu entries
+   are executed.  */
+static struct grub_menu_execute_callback execution_callback =
+{
+  .notify_booting = notify_booting,
+  .notify_fallback = notify_fallback,
+  .notify_failure = notify_execution_failure
+};
+
+static grub_err_t
+show_menu (grub_menu_t menu, int nested)
+{
+  while (1)
+    {
+      int boot_entry;
+      grub_menu_entry_t e;
+      int auto_boot;
+
+      boot_entry = run_menu (menu, nested, &auto_boot);
+      if (boot_entry < 0)
+       break;
+
+      e = grub_menu_get_entry (menu, boot_entry);
+      if (! e)
+       continue; /* Menu is empty.  */
+
+      grub_cls ();
+
+      if (auto_boot)
+        {
+          grub_menu_execute_with_fallback (menu, e, &execution_callback, 0);
+        }
+      else
+        {
+         int lines_before = grub_normal_get_line_counter ();
+          grub_errno = GRUB_ERR_NONE;
+          grub_menu_execute_entry (e);
+         grub_print_error ();
+         grub_errno = GRUB_ERR_NONE;
+
+          if (lines_before != grub_normal_get_line_counter ())
+           grub_wait_after_message ();
+        }
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_show_menu (grub_menu_t menu, int nested)
+{
+  grub_err_t err1, err2;
+
+  while (1)
+    {
+      err1 = show_menu (menu, nested);
+      grub_print_error ();
+
+      if (grub_normal_exit_level)
+       break;
+
+      err2 = grub_auth_check_authentication (NULL);
+      if (err2)
+       {
+         grub_print_error ();
+         grub_errno = GRUB_ERR_NONE;
+         continue;
+       }
+
+      break;
+    }
+
+  return err1;
+}
diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
new file mode 100644 (file)
index 0000000..644fe90
--- /dev/null
@@ -0,0 +1,1399 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/loader.h>
+#include <grub/command.h>
+#include <grub/parser.h>
+#include <grub/auth.h>
+#include <grub/i18n.h>
+
+enum update_mode
+  {
+    NO_LINE,
+    SINGLE_LINE,
+    ALL_LINES
+  };
+
+struct line
+{
+  /* The line buffer.  */
+  char *buf;
+  /* The length of the line.  */
+  int len;
+  /* The maximum length of the line.  */
+  int max_len;
+};
+
+struct per_term_screen
+{
+  struct grub_term_output *term;
+  /* The X coordinate.  */
+  int x;
+  /* The Y coordinate.  */
+  int y;
+};
+
+struct screen
+{
+  /* The array of lines.  */
+  struct line *lines;
+  /* The number of lines.  */
+  int num_lines;
+  /* The current column.  */
+  int column;
+  /* The real column.  */
+  int real_column;
+  /* The current line.  */
+  int line;
+  /* The kill buffer.  */
+  char *killed_text;
+  /* The flag of a completion window.  */
+  int completion_shown;
+
+  struct per_term_screen *terms;
+  unsigned nterms;
+};
+
+/* Used for storing completion items temporarily.  */
+static struct line completion_buffer;
+static int completion_type;
+
+/* Initialize a line.  */
+static int
+init_line (struct line *linep)
+{
+  linep->len = 0;
+  linep->max_len = 80; /* XXX */
+  linep->buf = grub_malloc (linep->max_len);
+  if (! linep->buf)
+    return 0;
+
+  return 1;
+}
+
+/* Allocate extra space if necessary.  */
+static int
+ensure_space (struct line *linep, int extra)
+{
+  if (linep->max_len < linep->len + extra)
+    {
+      linep->max_len = linep->len + extra + 80; /* XXX */
+      linep->buf = grub_realloc (linep->buf, linep->max_len + 1);
+      if (! linep->buf)
+       return 0;
+    }
+
+  return 1;
+}
+
+/* Return the number of lines occupied by this line on the screen.  */
+static int
+get_logical_num_lines (struct line *linep, struct per_term_screen *term_screen)
+{
+  return (linep->len / grub_term_entry_width (term_screen->term)) + 1;
+}
+
+/* Print a line.  */
+static void
+print_line (struct line *linep, int offset, int start, int y,
+           struct per_term_screen *term_screen)
+{
+  grub_term_gotoxy (term_screen->term, 
+                   GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + start + 1,
+                   y + GRUB_TERM_FIRST_ENTRY_Y);
+
+  if (linep->len >= offset + grub_term_entry_width (term_screen->term))
+    {
+      char *p, c;
+      p = linep->buf + offset + grub_term_entry_width (term_screen->term);
+      c = *p;
+      *p = 0;
+      grub_puts_terminal (linep->buf + offset + start, term_screen->term);
+      *p = c;
+      grub_putcode ('\\', term_screen->term);
+    }
+  else
+    {
+      int i;
+      char *p, c;
+
+      p = linep->buf + linep->len;
+      c = *p;
+      *p = 0;
+      grub_puts_terminal (linep->buf + offset + start, term_screen->term);
+      *p = c;
+
+      for (i = 0;
+          i <= grub_term_entry_width (term_screen->term) - linep->len + offset;
+          i++)
+       grub_putcode (' ', term_screen->term);
+    }
+}
+
+/* Print an empty line.  */
+static void
+print_empty_line (int y, struct per_term_screen *term_screen)
+{
+  int i;
+
+  grub_term_gotoxy (term_screen->term,
+                   GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1,
+                   y + GRUB_TERM_FIRST_ENTRY_Y);
+
+  for (i = 0; i < grub_term_entry_width (term_screen->term) + 1; i++)
+    grub_putcode (' ', term_screen->term);
+}
+
+/* Print an up arrow.  */
+static void
+print_up (int flag, struct per_term_screen *term_screen)
+{
+  grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X 
+                   + grub_term_entry_width (term_screen->term),
+                   GRUB_TERM_FIRST_ENTRY_Y);
+
+  if (flag)
+    grub_putcode (GRUB_TERM_DISP_UP, term_screen->term);
+  else
+    grub_putcode (' ', term_screen->term);
+}
+
+/* Print a down arrow.  */
+static void
+print_down (int flag, struct per_term_screen *term_screen)
+{
+  grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X
+                   + grub_term_border_width (term_screen->term),
+                   GRUB_TERM_TOP_BORDER_Y 
+                   + grub_term_num_entries (term_screen->term));
+
+  if (flag)
+    grub_putcode (GRUB_TERM_DISP_DOWN, term_screen->term);
+  else
+    grub_putcode (' ', term_screen->term);
+}
+
+/* Draw the lines of the screen SCREEN.  */
+static void
+update_screen (struct screen *screen, struct per_term_screen *term_screen,
+              int region_start, int region_column,
+              int up, int down, enum update_mode mode)
+{
+  int up_flag = 0;
+  int down_flag = 0;
+  int y;
+  int i;
+  struct line *linep;
+
+  /* Check if scrolling is necessary.  */
+  if (term_screen->y < 0 || term_screen->y
+      >= grub_term_num_entries (term_screen->term))
+    {
+      if (term_screen->y < 0)
+       term_screen->y = 0;
+      else
+       term_screen->y = grub_term_num_entries (term_screen->term) - 1;
+
+      region_start = 0;
+      region_column = 0;
+      up = 1;
+      down = 1;
+      mode = ALL_LINES;
+    }
+
+  if (mode != NO_LINE)
+    {
+      /* Draw lines. This code is tricky, because this must calculate logical
+        positions.  */
+      y = term_screen->y - screen->column
+       / grub_term_entry_width (term_screen->term);
+      i = screen->line;
+      linep = screen->lines + i;
+      while (y > 0)
+       {
+          i--;
+          linep--;
+          y -= get_logical_num_lines (linep, term_screen);
+       }
+
+      if (y < 0 || i > 0)
+       up_flag = 1;
+
+      do
+       {
+         int column;
+
+         for (column = 0;
+              column <= linep->len
+                && y < grub_term_num_entries (term_screen->term);
+              column += grub_term_entry_width (term_screen->term), y++)
+           {
+             if (y < 0)
+               continue;
+
+             if (i == region_start)
+               {
+                 if (region_column >= column
+                     && region_column
+                     < (column
+                        + grub_term_entry_width (term_screen->term)))
+                   print_line (linep, column, region_column - column, y,
+                               term_screen);
+                 else if (region_column < column)
+                   print_line (linep, column, 0, y, term_screen);
+               }
+             else if (i > region_start && mode == ALL_LINES)
+               print_line (linep, column, 0, y, term_screen);
+           }
+
+         if (y == grub_term_num_entries (term_screen->term))
+           {
+             if (column <= linep->len || i + 1 < screen->num_lines)
+               down_flag = 1;
+           }
+
+         linep++;
+         i++;
+
+         if (mode == ALL_LINES && i == screen->num_lines)
+           for (; y < grub_term_num_entries (term_screen->term); y++)
+             print_empty_line (y, term_screen);
+
+       }
+      while (y < grub_term_num_entries (term_screen->term));
+
+      /* Draw up and down arrows.  */
+      if (up)
+       print_up (up_flag, term_screen);
+      if (down)
+       print_down (down_flag, term_screen);
+    }
+
+  /* Place the cursor.  */
+  grub_term_gotoxy (term_screen->term, 
+                   GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1
+                   + term_screen->x,
+                   GRUB_TERM_FIRST_ENTRY_Y + term_screen->y);
+
+  grub_term_refresh (term_screen->term);
+}
+
+static void
+update_screen_all (struct screen *screen,
+                  int region_start, int region_column,
+                  int up, int down, enum update_mode mode)
+{
+  unsigned i;
+  for (i = 0; i < screen->nterms; i++)
+    update_screen (screen, &screen->terms[i], region_start, region_column,
+                  up, down, mode);
+}
+
+static int
+insert_string (struct screen *screen, char *s, int update)
+{
+  int region_start = screen->num_lines;
+  int region_column = 0;
+  int down[screen->nterms];
+  enum update_mode mode[screen->nterms];
+  unsigned i;
+
+  for (i = 0; i < screen->nterms; i++)
+    {
+      down[i] = 0;
+      mode[i] = NO_LINE;
+    }
+
+  while (*s)
+    {
+      if (*s == '\n')
+       {
+         /* LF is special because it creates a new line.  */
+         struct line *current_linep;
+         struct line *next_linep;
+         int size;
+
+         /* Make a new line.  */
+         screen->num_lines++;
+         screen->lines = grub_realloc (screen->lines,
+                                       screen->num_lines
+                                       * sizeof (struct line));
+         if (! screen->lines)
+           return 0;
+
+         /* Scroll down. */
+         grub_memmove (screen->lines + screen->line + 2,
+                       screen->lines + screen->line + 1,
+                       ((screen->num_lines - screen->line - 2)
+                        * sizeof (struct line)));
+
+         if (! init_line (screen->lines + screen->line + 1))
+           return 0;
+
+         /* Fold the line.  */
+         current_linep = screen->lines + screen->line;
+         next_linep = current_linep + 1;
+         size = current_linep->len - screen->column;
+
+         if (! ensure_space (next_linep, size))
+           return 0;
+
+         grub_memmove (next_linep->buf,
+                       current_linep->buf + screen->column,
+                       size);
+         current_linep->len = screen->column;
+         next_linep->len = size;
+
+         /* Update a dirty region.  */
+         if (region_start > screen->line)
+           {
+             region_start = screen->line;
+             region_column = screen->column;
+           }
+
+         for (i = 0; i < screen->nterms; i++)
+           {
+             mode[i] = ALL_LINES;
+             down[i] = 1; /* XXX not optimal.  */
+           }
+
+         /* Move the cursor.  */
+         screen->column = screen->real_column = 0;
+         screen->line++;
+         for (i = 0; i < screen->nterms; i++)
+           {
+             screen->terms[i].x = 0;
+             screen->terms[i].y++;
+           }
+         s++;
+       }
+      else
+       {
+         /* All but LF.  */
+         char *p;
+         struct line *current_linep;
+         int size;
+         int orig_num[screen->nterms], new_num[screen->nterms];
+
+         /* Find a string delimited by LF.  */
+         p = grub_strchr (s, '\n');
+         if (! p)
+           p = s + grub_strlen (s);
+
+         /* Insert the string.  */
+         current_linep = screen->lines + screen->line;
+         size = p - s;
+         if (! ensure_space (current_linep, size))
+           return 0;
+
+         grub_memmove (current_linep->buf + screen->column + size,
+                       current_linep->buf + screen->column,
+                       current_linep->len - screen->column);
+         grub_memmove (current_linep->buf + screen->column,
+                       s,
+                       size);
+         for (i = 0; i < screen->nterms; i++)
+           orig_num[i] = get_logical_num_lines (current_linep,
+                                                &screen->terms[i]);
+         current_linep->len += size;
+         for (i = 0; i < screen->nterms; i++)
+           new_num[i] = get_logical_num_lines (current_linep,
+                                               &screen->terms[i]);
+
+         /* Update the dirty region.  */
+         if (region_start > screen->line)
+           {
+             region_start = screen->line;
+             region_column = screen->column;
+           }
+
+         for (i = 0; i < screen->nterms; i++)
+           if (orig_num[i] != new_num[i])
+             {
+               mode[i] = ALL_LINES;
+               down[i] = 1; /* XXX not optimal.  */
+             }
+           else if (mode[i] != ALL_LINES)
+             mode[i] = SINGLE_LINE;
+
+         /* Move the cursor.  */
+         screen->column += size;
+         screen->real_column = screen->column;
+         for (i = 0; i < screen->nterms; i++)
+           {
+             screen->terms[i].x += size;
+             screen->terms[i].y += screen->terms[i].x
+               / grub_term_entry_width (screen->terms[i].term);
+             screen->terms[i].x
+               %= grub_term_entry_width (screen->terms[i].term);
+           }
+         s = p;
+       }
+    }
+
+  if (update)
+    for (i = 0; i < screen->nterms; i++)
+      update_screen (screen, &screen->terms[i],
+                    region_start, region_column, 0, down[i], mode[i]);
+
+  return 1;
+}
+
+/* Release the resource allocated for SCREEN.  */
+static void
+destroy_screen (struct screen *screen)
+{
+  int i;
+
+  if (screen->lines)
+    for (i = 0; i < screen->num_lines; i++)
+      {
+       struct line *linep = screen->lines + i;
+
+       if (linep)
+         grub_free (linep->buf);
+      }
+
+  grub_free (screen->killed_text);
+  grub_free (screen->lines);
+  grub_free (screen->terms);
+  grub_free (screen);
+}
+
+/* Make a new screen.  */
+static struct screen *
+make_screen (grub_menu_entry_t entry)
+{
+  struct screen *screen;
+  unsigned i;
+
+  /* Initialize the screen.  */
+  screen = grub_zalloc (sizeof (*screen));
+  if (! screen)
+    return 0;
+
+  screen->num_lines = 1;
+  screen->lines = grub_malloc (sizeof (struct line));
+  if (! screen->lines)
+    goto fail;
+
+  /* Initialize the first line which must be always present.  */
+  if (! init_line (screen->lines))
+    goto fail;
+
+  insert_string (screen, (char *) entry->sourcecode, 0);
+
+  /* Reset the cursor position.  */
+  screen->column = 0;
+  screen->real_column = 0;
+  screen->line = 0;
+  for (i = 0; i < screen->nterms; i++)
+    {
+      screen->terms[i].x = 0;
+      screen->terms[i].y = 0;
+    }
+
+  return screen;
+
+ fail:
+  destroy_screen (screen);
+  return 0;
+}
+
+static int
+forward_char (struct screen *screen, int update)
+{
+  struct line *linep;
+  unsigned i;
+
+  linep = screen->lines + screen->line;
+  if (screen->column < linep->len)
+    {
+      screen->column++;
+      for (i = 0; i < screen->nterms; i++)
+       {
+         screen->terms[i].x++;
+         if (screen->terms[i].x
+             == grub_term_entry_width (screen->terms[i].term))
+           {
+             screen->terms[i].x = 0;
+             screen->terms[i].y++;
+           }
+       }
+    }
+  else if (screen->num_lines > screen->line + 1)
+    {
+      screen->column = 0;
+      screen->line++;
+      for (i = 0; i < screen->nterms; i++)
+       {
+         screen->terms[i].x = 0;
+         screen->terms[i].y++;
+       }
+    }
+
+  screen->real_column = screen->column;
+
+  if (update)
+    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+  return 1;
+}
+
+static int
+backward_char (struct screen *screen, int update)
+{
+  unsigned i;
+
+  if (screen->column > 0)
+    {
+      screen->column--;
+      for (i = 0; i < screen->nterms; i++)
+       {
+         screen->terms[i].x--;
+         if (screen->terms[i].x == -1)
+           {
+             screen->terms[i].x
+               = grub_term_entry_width (screen->terms[i].term) - 1;
+             screen->terms[i].y--;
+           }
+       }
+    }
+  else if (screen->line > 0)
+    {
+      struct line *linep;
+
+      screen->line--;
+      linep = screen->lines + screen->line;
+      screen->column = linep->len;
+      for (i = 0; i < screen->nterms; i++)
+       {
+         screen->terms[i].x = screen->column
+           % grub_term_entry_width (screen->terms[i].term);
+         screen->terms[i].y--;
+       }
+    }
+
+  screen->real_column = screen->column;
+
+  if (update)
+    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+
+  return 1;
+}
+
+static int
+previous_line (struct screen *screen, int update)
+{
+  unsigned i;
+
+  if (screen->line > 0)
+    {
+      struct line *linep;
+      int col;
+
+      /* How many physical lines from the current position
+        to the first physical line?  */
+      col = screen->column;
+
+      screen->line--;
+
+      linep = screen->lines + screen->line;
+      if (linep->len < screen->real_column)
+       screen->column = linep->len;
+      else
+       screen->column = screen->real_column;
+
+      for (i = 0; i < screen->nterms; i++)
+       {
+         int dy;
+         dy = col / grub_term_entry_width (screen->terms[i].term);
+
+         /* How many physical lines from the current position
+            to the last physical line?  */
+         dy += (linep->len / grub_term_entry_width (screen->terms[i].term)
+                - screen->column
+                / grub_term_entry_width (screen->terms[i].term));
+       
+         screen->terms[i].y -= dy + 1;
+         screen->terms[i].x
+           = screen->column % grub_term_entry_width (screen->terms[i].term);
+      }
+    }
+  else
+    {
+      for (i = 0; i < screen->nterms; i++)
+       {
+         screen->terms[i].y
+           -= screen->column / grub_term_entry_width (screen->terms[i].term);
+         screen->terms[i].x = 0;
+       }
+      screen->column = 0;
+    }
+
+  if (update)
+    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+
+  return 1;
+}
+
+static int
+next_line (struct screen *screen, int update)
+{
+  unsigned i;
+
+  if (screen->line < screen->num_lines - 1)
+    {
+      struct line *linep;
+      int l1, c1;
+
+      /* How many physical lines from the current position
+        to the last physical line?  */
+      linep = screen->lines + screen->line;
+      l1 = linep->len;
+      c1 = screen->column;
+
+      screen->line++;
+
+      linep++;
+      if (linep->len < screen->real_column)
+       screen->column = linep->len;
+      else
+       screen->column = screen->real_column;
+
+      for (i = 0; i < screen->nterms; i++)
+       {
+         int dy;
+         dy = l1 / grub_term_entry_width (screen->terms[i].term)
+           - c1 / grub_term_entry_width (screen->terms[i].term);
+         /* How many physical lines from the current position
+            to the first physical line?  */
+         dy += screen->column / grub_term_entry_width (screen->terms[i].term);
+         screen->terms[i].y += dy + 1;
+         screen->terms[i].x = screen->column
+           % grub_term_entry_width (screen->terms[i].term);
+       }
+    }
+  else
+    {
+      struct line *linep;
+      int l, s;
+      
+      linep = screen->lines + screen->line;
+      l = linep->len;
+      s = screen->column;
+      screen->column = linep->len;
+      for (i = 0; i < screen->nterms; i++)
+       {
+         screen->terms[i].y 
+           += (l / grub_term_entry_width (screen->terms[i].term)
+               -  s / grub_term_entry_width (screen->terms[i].term));
+         screen->terms[i].x
+           = screen->column % grub_term_entry_width (screen->terms[i].term);
+       }
+    }
+
+  if (update)
+    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+
+  return 1;
+}
+
+static int
+beginning_of_line (struct screen *screen, int update)
+{
+  unsigned i;
+  int col;
+  
+  col = screen->column;
+  screen->column = screen->real_column = 0;
+  for (i = 0; i < screen->nterms; i++)
+    {
+      screen->terms[i].x = 0;
+      screen->terms[i].y -= col / grub_term_entry_width (screen->terms[i].term);
+    }
+
+  if (update)
+    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+
+  return 1;
+}
+
+static int
+end_of_line (struct screen *screen, int update)
+{
+  struct line *linep;
+  unsigned i;
+  int col;
+
+  linep = screen->lines + screen->line;
+  col = screen->column;
+  screen->column = screen->real_column = linep->len;
+  for (i = 0; i < screen->nterms; i++)
+    {
+      screen->terms[i].y 
+       += (linep->len / grub_term_entry_width (screen->terms->term)
+           - col / grub_term_entry_width (screen->terms->term));
+      screen->terms[i].x
+       = screen->column % grub_term_entry_width (screen->terms->term);
+    }
+
+  if (update)
+    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+
+  return 1;
+}
+
+static int
+delete_char (struct screen *screen, int update)
+{
+  struct line *linep;
+  int start = screen->num_lines;
+  int column = 0;
+
+  linep = screen->lines + screen->line;
+  if (linep->len > screen->column)
+    {
+      int orig_num[screen->nterms], new_num;
+      unsigned i;
+
+      for (i = 0; i < screen->nterms; i++)
+       orig_num[i] = get_logical_num_lines (linep, &screen->terms[i]);
+
+      grub_memmove (linep->buf + screen->column,
+                   linep->buf + screen->column + 1,
+                   linep->len - screen->column - 1);
+      linep->len--;
+
+      start = screen->line;
+      column = screen->column;
+
+      screen->real_column = screen->column;
+
+      if (update)
+       {
+         for (i = 0; i < screen->nterms; i++)
+           {
+             new_num = get_logical_num_lines (linep, &screen->terms[i]);
+             if (orig_num[i] != new_num)
+               update_screen (screen, &screen->terms[i],
+                              start, column, 0, 0, ALL_LINES);
+             else
+               update_screen (screen, &screen->terms[i],
+                              start, column, 0, 0, SINGLE_LINE);
+           }
+       }
+    }
+  else if (screen->num_lines > screen->line + 1)
+    {
+      struct line *next_linep;
+
+      next_linep = linep + 1;
+      if (! ensure_space (linep, next_linep->len))
+       return 0;
+
+      grub_memmove (linep->buf + linep->len, next_linep->buf, next_linep->len);
+      linep->len += next_linep->len;
+
+      grub_free (next_linep->buf);
+      grub_memmove (next_linep,
+                   next_linep + 1,
+                   (screen->num_lines - screen->line - 2)
+                   * sizeof (struct line));
+      screen->num_lines--;
+
+      start = screen->line;
+      column = screen->column;
+
+      screen->real_column = screen->column;
+      if (update)
+       update_screen_all (screen, start, column, 0, 1, ALL_LINES);
+    }
+
+  return 1;
+}
+
+static int
+backward_delete_char (struct screen *screen, int update)
+{
+  int saved_column;
+  int saved_line;
+
+  saved_column = screen->column;
+  saved_line = screen->line;
+
+  if (! backward_char (screen, 0))
+    return 0;
+
+  if (saved_column != screen->column || saved_line != screen->line)
+    if (! delete_char (screen, update))
+      return 0;
+
+  return 1;
+}
+
+static int
+kill_line (struct screen *screen, int continuous, int update)
+{
+  struct line *linep;
+  char *p;
+  int size;
+  int offset;
+
+  p = screen->killed_text;
+  if (! continuous && p)
+    p[0] = '\0';
+
+  linep = screen->lines + screen->line;
+  size = linep->len - screen->column;
+
+  if (p)
+    offset = grub_strlen (p);
+  else
+    offset = 0;
+
+  if (size > 0)
+    {
+      int orig_num[screen->nterms], new_num;
+      unsigned i;
+
+      p = grub_realloc (p, offset + size + 1);
+      if (! p)
+       return 0;
+
+      grub_memmove (p + offset, linep->buf + screen->column, size);
+      p[offset + size - 1] = '\0';
+
+      screen->killed_text = p;
+
+      for (i = 0; i < screen->nterms; i++)
+       orig_num[i] = get_logical_num_lines (linep, &screen->terms[i]);
+      linep->len = screen->column;
+
+      if (update)
+       {
+         new_num = get_logical_num_lines (linep, &screen->terms[i]);
+         for (i = 0; i < screen->nterms; i++)
+           {
+             if (orig_num[i] != new_num)
+               update_screen (screen, &screen->terms[i],
+                              screen->line, screen->column, 0, 1, ALL_LINES);
+             else
+               update_screen (screen, &screen->terms[i],
+                              screen->line, screen->column, 0, 0, SINGLE_LINE);
+           }
+       }
+    }
+  else if (screen->line + 1 < screen->num_lines)
+    {
+      p = grub_realloc (p, offset + 1 + 1);
+      if (! p)
+       return 0;
+
+      p[offset] = '\n';
+      p[offset + 1] = '\0';
+
+      screen->killed_text = p;
+
+      return delete_char (screen, update);
+    }
+
+  return 1;
+}
+
+static int
+yank (struct screen *screen, int update)
+{
+  if (screen->killed_text)
+    return insert_string (screen, screen->killed_text, update);
+
+  return 1;
+}
+
+static int
+open_line (struct screen *screen, int update)
+{
+  int saved_y[screen->nterms];
+  unsigned i;
+
+  for (i = 0; i < screen->nterms; i++)
+    saved_y[i] = screen->terms[i].y;
+
+  if (! insert_string (screen, "\n", 0))
+    return 0;
+
+  if (! backward_char (screen, 0))
+    return 0;
+
+  for (i = 0; i < screen->nterms; i++)
+    screen->terms[i].y = saved_y[i];
+
+  if (update)
+    update_screen_all (screen, screen->line, screen->column, 0, 1, ALL_LINES);
+
+  return 1;
+}
+
+/* A completion hook to print items.  */
+static void
+store_completion (const char *item, grub_completion_type_t type,
+                 int count __attribute__ ((unused)))
+{
+  char *p;
+
+  completion_type = type;
+
+  /* Make sure that the completion buffer has enough room.  */
+  if (completion_buffer.max_len < (completion_buffer.len
+                                  + (int) grub_strlen (item) + 1 + 1))
+    {
+      grub_size_t new_len;
+
+      new_len = completion_buffer.len + grub_strlen (item) + 80;
+      p = grub_realloc (completion_buffer.buf, new_len);
+      if (! p)
+       {
+         /* Possibly not fatal.  */
+         grub_errno = GRUB_ERR_NONE;
+         return;
+       }
+      p[completion_buffer.len] = 0;
+      completion_buffer.buf = p;
+      completion_buffer.max_len = new_len;
+    }
+
+  p = completion_buffer.buf + completion_buffer.len;
+  if (completion_buffer.len != 0)
+    {
+      *p++ = ' ';
+      completion_buffer.len++;
+    }
+  grub_strcpy (p, item);
+  completion_buffer.len += grub_strlen (item);
+}
+
+static int
+complete (struct screen *screen, int continuous, int update)
+{
+  char saved_char;
+  struct line *linep;
+  int restore;
+  char *insert;
+  static int count = -1;
+  unsigned i;
+  grub_uint32_t *ucs4;
+  grub_size_t buflen;
+  grub_ssize_t ucs4len;
+
+  if (continuous)
+    count++;
+  else
+    count = 0;
+
+  completion_buffer.buf = 0;
+  completion_buffer.len = 0;
+  completion_buffer.max_len = 0;
+
+  linep = screen->lines + screen->line;
+  saved_char = linep->buf[screen->column];
+  linep->buf[screen->column] = '\0';
+
+  insert = grub_normal_do_completion (linep->buf, &restore, store_completion);
+
+  linep->buf[screen->column] = saved_char;
+
+  buflen = grub_strlen (completion_buffer.buf);
+  ucs4 = grub_malloc (sizeof (grub_uint32_t) * (buflen + 1));
+
+  if (!ucs4)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      return 1;
+    }
+
+  ucs4len = grub_utf8_to_ucs4 (ucs4, buflen,
+                              (grub_uint8_t *) completion_buffer.buf,
+                              buflen, 0);
+  ucs4[ucs4len] = 0;
+
+  if (restore)
+    for (i = 0; i < screen->nterms; i++)
+      {
+       int num_sections = ((completion_buffer.len
+                            + grub_term_width (screen->terms[i].term) - 8 - 1)
+                           / (grub_term_width (screen->terms[i].term) - 8));
+       grub_uint32_t *endp;
+       grub_uint16_t pos;
+       grub_uint32_t *p = ucs4;
+
+       pos = grub_term_getxy (screen->terms[i].term);
+       grub_term_gotoxy (screen->terms[i].term, 0,
+                         grub_term_height (screen->terms[i].term) - 3);
+
+       screen->completion_shown = 1;
+
+       grub_term_gotoxy (screen->terms[i].term, 0,
+                         grub_term_height (screen->terms[i].term) - 3);
+       grub_puts_terminal ("   ", screen->terms[i].term);
+       switch (completion_type)
+         {
+         case GRUB_COMPLETION_TYPE_COMMAND:
+           grub_puts_terminal (_("Possible commands are:"),
+                               screen->terms[i].term);
+           break;
+         case GRUB_COMPLETION_TYPE_DEVICE:
+           grub_puts_terminal (_("Possible devices are:"),
+                               screen->terms[i].term);
+           break;
+         case GRUB_COMPLETION_TYPE_FILE:
+           grub_puts_terminal (_("Possible files are:"),
+                               screen->terms[i].term);
+           break;
+         case GRUB_COMPLETION_TYPE_PARTITION:
+           grub_puts_terminal (_("Possible partitions are:"),
+                               screen->terms[i].term);
+           break;
+         case GRUB_COMPLETION_TYPE_ARGUMENT:
+           grub_puts_terminal (_("Possible arguments are:"),
+                               screen->terms[i].term);
+           break;
+         default:
+           grub_puts_terminal (_("Possible things are:"),
+                               screen->terms[i].term);
+           break;
+         }
+
+       grub_puts_terminal ("\n    ", screen->terms[i].term);
+
+       p += (count % num_sections)
+         * (grub_term_width (screen->terms[i].term) - 8);
+       endp = p + (grub_term_width (screen->terms[i].term) - 8);
+
+       if (p != ucs4)
+         grub_putcode (GRUB_TERM_DISP_LEFT, screen->terms[i].term);
+       else
+         grub_putcode (' ', screen->terms[i].term);
+
+       while (*p && p < endp)
+         grub_putcode (*p++, screen->terms[i].term);
+
+       if (*p)
+         grub_putcode (GRUB_TERM_DISP_RIGHT, screen->terms[i].term);
+       grub_term_gotoxy (screen->terms[i].term, pos >> 8, pos & 0xFF);
+      }
+
+  if (insert)
+    {
+      insert_string (screen, insert, update);
+      count = -1;
+      grub_free (insert);
+    }
+  else if (update)
+    grub_refresh ();
+
+  grub_free (completion_buffer.buf);
+  return 1;
+}
+
+/* Clear displayed completions.  */
+static void
+clear_completions (struct per_term_screen *term_screen)
+{
+  grub_uint16_t pos;
+  unsigned i, j;
+
+  pos = grub_term_getxy (term_screen->term);
+  grub_term_gotoxy (term_screen->term, 0,
+                   grub_term_height (term_screen->term) - 3);
+
+  for (i = 0; i < 2; i++)
+    {
+      for (j = 0; j < grub_term_width (term_screen->term) - 1; j++)
+       grub_putcode (' ', term_screen->term);
+      grub_putcode ('\n', term_screen->term);
+    }
+
+  grub_term_gotoxy (term_screen->term, pos >> 8, pos & 0xFF);
+  grub_term_refresh (term_screen->term);
+}
+
+static void
+clear_completions_all (struct screen *screen)
+{
+  unsigned i;
+
+  for (i = 0; i < screen->nterms; i++)
+    clear_completions (&screen->terms[i]);
+}
+
+/* Execute the command list in the screen SCREEN.  */
+static int
+run (struct screen *screen)
+{
+  int currline = 0;
+  char *nextline;
+
+  auto grub_err_t editor_getline (char **line, int cont);
+  grub_err_t editor_getline (char **line, int cont __attribute__ ((unused)))
+    {
+      struct line *linep = screen->lines + currline;
+      char *p;
+
+      if (currline > screen->num_lines)
+       {
+         *line = 0;
+         return 0;
+       }
+
+      /* Trim down space characters.  */
+      for (p = linep->buf + linep->len - 1;
+          p >= linep->buf && grub_isspace (*p);
+          p--)
+       ;
+      *++p = '\0';
+
+      linep->len = p - linep->buf;
+      for (p = linep->buf; grub_isspace (*p); p++)
+       ;
+      *line = grub_strdup (p);
+      currline++;
+      return 0;
+    }
+
+  grub_cls ();
+  grub_printf ("  ");
+  grub_printf_ (N_("Booting a command list"));
+  grub_printf ("\n\n");
+
+
+  /* Execute the script, line for line.  */
+  while (currline < screen->num_lines)
+    {
+      editor_getline (&nextline, 0);
+      if (grub_parser_get_current ()->parse_line (nextline, editor_getline))
+       break;
+    }
+
+  if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
+    /* Implicit execution of boot, only if something is loaded.  */
+    grub_command_execute ("boot", 0, 0);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      grub_wait_after_message ();
+    }
+
+  return 1;
+}
+
+/* Edit a menu entry with an Emacs-like interface.  */
+void
+grub_menu_entry_run (grub_menu_entry_t entry)
+{
+  struct screen *screen;
+  int prev_c;
+  grub_err_t err = GRUB_ERR_NONE;
+  unsigned i;
+  grub_term_output_t term;
+
+  err = grub_auth_check_authentication (NULL);
+
+  if (err)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+
+  screen = make_screen (entry);
+  if (! screen)
+    return;
+
+  screen->terms = NULL;
+
+ refresh:
+  grub_free (screen->terms);
+  screen->nterms = 0;
+  FOR_ACTIVE_TERM_OUTPUTS(term)
+    screen->nterms++;
+  screen->terms = grub_malloc (screen->nterms * sizeof (screen->terms[0]));
+  if (!screen->terms)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+  i = 0;
+  FOR_ACTIVE_TERM_OUTPUTS(term)
+  {
+    screen->terms[i].term = term;
+    screen->terms[i].x = 0;
+    screen->terms[i].y = 0;
+    i++;
+  }
+  /* Draw the screen.  */
+  for (i = 0; i < screen->nterms; i++)
+    grub_menu_init_page (0, 1, screen->terms[i].term);
+  update_screen_all (screen, 0, 0, 1, 1, ALL_LINES);
+  for (i = 0; i < screen->nterms; i++)
+    grub_term_setcursor (screen->terms[i].term, 1);
+  prev_c = '\0';
+
+  while (1)
+    {
+      int c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
+
+      if (screen->completion_shown)
+       {
+         clear_completions_all (screen);
+         screen->completion_shown = 0;
+       }
+
+      if (grub_normal_exit_level)
+       {
+         destroy_screen (screen);
+         return;
+       }
+
+      switch (c)
+       {
+       case 16: /* C-p */
+         if (! previous_line (screen, 1))
+           goto fail;
+         break;
+
+       case 14: /* C-n */
+         if (! next_line (screen, 1))
+           goto fail;
+         break;
+
+       case 6: /* C-f */
+         if (! forward_char (screen, 1))
+           goto fail;
+         break;
+
+       case 2: /* C-b */
+         if (! backward_char (screen, 1))
+           goto fail;
+         break;
+
+       case 1: /* C-a */
+         if (! beginning_of_line (screen, 1))
+           goto fail;
+         break;
+
+       case 5: /* C-e */
+         if (! end_of_line (screen, 1))
+           goto fail;
+         break;
+
+       case '\t': /* C-i */
+         if (! complete (screen, prev_c == c, 1))
+           goto fail;
+         break;
+
+       case 4: /* C-d */
+         if (! delete_char (screen, 1))
+           goto fail;
+         break;
+
+       case 8: /* C-h */
+         if (! backward_delete_char (screen, 1))
+           goto fail;
+         break;
+
+       case 11: /* C-k */
+         if (! kill_line (screen, prev_c == c, 1))
+           goto fail;
+         break;
+
+       case 21: /* C-u */
+         /* FIXME: What behavior is good for this key?  */
+         break;
+
+       case 25: /* C-y */
+         if (! yank (screen, 1))
+           goto fail;
+         break;
+
+       case 12: /* C-l */
+         /* FIXME: centering.  */
+         goto refresh;
+
+       case 15: /* C-o */
+         if (! open_line (screen, 1))
+           goto fail;
+         break;
+
+       case '\n':
+       case '\r':
+         if (! insert_string (screen, "\n", 1))
+           goto fail;
+         break;
+
+       case '\e':
+         destroy_screen (screen);
+         return;
+
+       case 3: /* C-c */
+         grub_cmdline_run (1);
+         goto refresh;
+
+       case 24: /* C-x */
+         if (! run (screen))
+           goto fail;
+         goto refresh;
+
+       case 18: /* C-r */
+       case 19: /* C-s */
+       case 20: /* C-t */
+         /* FIXME */
+         break;
+
+       default:
+         if (grub_isprint (c))
+           {
+             char buf[2];
+
+             buf[0] = c;
+             buf[1] = '\0';
+             if (! insert_string (screen, buf, 1))
+               goto fail;
+           }
+         break;
+       }
+
+      prev_c = c;
+    }
+
+ fail:
+  destroy_screen (screen);
+
+  grub_cls ();
+  grub_print_error ();
+  grub_errno = GRUB_ERR_NONE;
+  grub_putchar ('\n');
+  grub_printf_ (N_("Press any key to continue..."));
+  (void) grub_getkey ();
+}
diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c
new file mode 100644 (file)
index 0000000..bb05875
--- /dev/null
@@ -0,0 +1,494 @@
+/* menu_text.c - Basic text menu implementation.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/loader.h>
+#include <grub/mm.h>
+#include <grub/time.h>
+#include <grub/env.h>
+#include <grub/menu_viewer.h>
+#include <grub/i18n.h>
+#include <grub/charset.h>
+
+static grub_uint8_t grub_color_menu_normal;
+static grub_uint8_t grub_color_menu_highlight;
+
+struct menu_viewer_data
+{
+  int first, offset;
+  grub_menu_t menu;
+  struct grub_term_output *term;
+};
+
+static void
+print_spaces (int number_spaces, struct grub_term_output *term)
+{
+  int i;
+  for (i = 0; i < number_spaces; i++)
+    grub_putcode (' ', term);
+}
+
+void
+grub_print_ucs4 (const grub_uint32_t * str,
+                const grub_uint32_t * last_position,
+                struct grub_term_output *term)
+{
+  while (str < last_position)
+    {
+      grub_putcode (*str, term);
+      str++;
+    }
+}
+
+grub_ssize_t
+grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position,
+                    struct grub_term_output *term)
+{
+  grub_ssize_t width = 0;
+
+  while (str < last_position)
+    {
+      width += grub_term_getcharwidth (term, *str);
+      str++;
+    }
+  return width;
+}
+
+void
+grub_print_message_indented (const char *msg, int margin_left, int margin_right,
+                            struct grub_term_output *term)
+{
+  int line_len;
+
+  grub_uint32_t *unicode_msg;
+  grub_uint32_t *last_position;
+
+  int msg_len;
+
+  line_len = grub_term_width (term) - grub_term_getcharwidth (term, 'm') *
+    (margin_left + margin_right);
+
+  msg_len = grub_utf8_to_ucs4_alloc (msg, &unicode_msg, &last_position);
+
+  if (msg_len < 0)
+    {
+      return;
+    }
+
+  grub_uint32_t *current_position = unicode_msg;
+
+  grub_uint32_t *next_new_line = unicode_msg;
+
+  int first_loop = 1;
+
+  while (current_position < last_position)
+    {
+      if (! first_loop)
+        grub_putcode ('\n', term);
+     
+      next_new_line = (grub_uint32_t *) last_position;
+
+      while (grub_getstringwidth (current_position, next_new_line,term) 
+            > line_len
+            || (next_new_line != last_position && *next_new_line != ' '
+               && next_new_line > current_position))
+       {
+         next_new_line--;
+       }
+
+      if (next_new_line == current_position)
+       {
+         next_new_line = (next_new_line + line_len > last_position) ?
+           (grub_uint32_t *) last_position : next_new_line + line_len;
+       }
+
+      print_spaces (margin_left, term);
+      grub_print_ucs4 (current_position, next_new_line, term);
+
+      next_new_line++;
+      current_position = next_new_line;
+      first_loop = 0;
+    }
+  grub_free (unicode_msg);
+}
+
+
+static void
+draw_border (struct grub_term_output *term)
+{
+  unsigned i;
+
+  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
+
+  grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y);
+  grub_putcode (GRUB_TERM_DISP_UL, term);
+  for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
+    grub_putcode (GRUB_TERM_DISP_HLINE, term);
+  grub_putcode (GRUB_TERM_DISP_UR, term);
+
+  for (i = 0; i < (unsigned) grub_term_num_entries (term); i++)
+    {
+      grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1);
+      grub_putcode (GRUB_TERM_DISP_VLINE, term);
+      grub_term_gotoxy (term, GRUB_TERM_MARGIN + grub_term_border_width (term)
+                       - 1,
+                       GRUB_TERM_TOP_BORDER_Y + i + 1);
+      grub_putcode (GRUB_TERM_DISP_VLINE, term);
+    }
+
+  grub_term_gotoxy (term, GRUB_TERM_MARGIN,
+                   GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term) + 1);
+  grub_putcode (GRUB_TERM_DISP_LL, term);
+  for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
+    grub_putcode (GRUB_TERM_DISP_HLINE, term);
+  grub_putcode (GRUB_TERM_DISP_LR, term);
+
+  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
+
+  grub_term_gotoxy (term, GRUB_TERM_MARGIN,
+                   (GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term)
+                    + GRUB_TERM_MARGIN + 1));
+}
+
+static void
+print_message (int nested, int edit, struct grub_term_output *term)
+{
+  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
+
+  if (edit)
+    {
+      grub_putcode ('\n', term);
+#ifdef GRUB_MACHINE_EFI
+      grub_print_message_indented (_("Minimum Emacs-like screen editing is \
+supported. TAB lists completions. Press F1 to boot, F2=Ctrl-a, F3=Ctrl-e, \
+F4 for a command-line or ESC to discard edits and return to the GRUB menu."),
+                                   STANDARD_MARGIN, STANDARD_MARGIN, term);
+#else
+      grub_print_message_indented (_("Minimum Emacs-like screen editing is \
+supported. TAB lists completions. Press Ctrl-x to boot, Ctrl-c for a \
+command-line or ESC to discard edits and return to the GRUB menu."),
+                                   STANDARD_MARGIN, STANDARD_MARGIN, term);
+#endif
+    }
+  else
+    {
+      const char *msg = _("Use the %C and %C keys to select which "
+                         "entry is highlighted.\n");
+      char *msg_translated;
+
+      msg_translated = grub_xasprintf (msg, (grub_uint32_t) GRUB_TERM_DISP_UP,
+                                    (grub_uint32_t) GRUB_TERM_DISP_DOWN);
+      if (!msg_translated)
+       return;
+      grub_putchar ('\n');
+      grub_print_message_indented (msg_translated, STANDARD_MARGIN,
+                                  STANDARD_MARGIN, term);
+
+      grub_free (msg_translated);
+
+      if (nested)
+       {
+         grub_print_message_indented
+           (_("Press enter to boot the selected OS, "
+              "\'e\' to edit the commands before booting "
+              "or \'c\' for a command-line. ESC to return previous menu.\n"),
+            STANDARD_MARGIN, STANDARD_MARGIN, term);
+       }
+      else
+       {
+         grub_print_message_indented
+           (_("Press enter to boot the selected OS, "
+              "\'e\' to edit the commands before booting "
+              "or \'c\' for a command-line.\n"),
+            STANDARD_MARGIN, STANDARD_MARGIN, term);
+       }       
+    }
+}
+
+static void
+print_entry (int y, int highlight, grub_menu_entry_t entry,
+            struct grub_term_output *term)
+{
+  int x;
+  const char *title;
+  grub_size_t title_len;
+  grub_ssize_t len;
+  grub_uint32_t *unicode_title;
+  grub_ssize_t i;
+  grub_uint8_t old_color_normal, old_color_highlight;
+
+  title = entry ? entry->title : "";
+  title_len = grub_strlen (title);
+  unicode_title = grub_malloc (title_len * sizeof (*unicode_title));
+  if (! unicode_title)
+    /* XXX How to show this error?  */
+    return;
+
+  len = grub_utf8_to_ucs4 (unicode_title, title_len,
+                           (grub_uint8_t *) title, -1, 0);
+  if (len < 0)
+    {
+      /* It is an invalid sequence.  */
+      grub_free (unicode_title);
+      return;
+    }
+
+  grub_term_getcolor (term, &old_color_normal, &old_color_highlight);
+  grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
+  grub_term_setcolorstate (term, highlight
+                          ? GRUB_TERM_COLOR_HIGHLIGHT
+                          : GRUB_TERM_COLOR_NORMAL);
+
+  grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN, y);
+
+  for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, i = 0;
+       x < (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
+                 - GRUB_TERM_MARGIN);
+       i++)
+    {
+      if (i < len
+         && x <= (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
+                        - GRUB_TERM_MARGIN - 1))
+       {
+         grub_ssize_t width;
+
+         width = grub_term_getcharwidth (term, unicode_title[i]);
+
+         if (x + width > (int) (GRUB_TERM_LEFT_BORDER_X 
+                                + grub_term_border_width (term)
+                                - GRUB_TERM_MARGIN - 1))
+           grub_putcode (GRUB_TERM_DISP_RIGHT, term);
+         else
+           grub_putcode (unicode_title[i], term);
+
+         x += width;
+       }
+      else
+       {
+         grub_putcode (' ', term);
+         x++;
+       }
+    }
+  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
+  grub_putcode (' ', term);
+
+  grub_term_gotoxy (term, grub_term_cursor_x (term), y);
+
+  grub_term_setcolor (term, old_color_normal, old_color_highlight);
+  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
+  grub_free (unicode_title);
+}
+
+static void
+print_entries (grub_menu_t menu, int first, int offset,
+              struct grub_term_output *term)
+{
+  grub_menu_entry_t e;
+  int i;
+
+  grub_term_gotoxy (term,
+                   GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term),
+                   GRUB_TERM_FIRST_ENTRY_Y);
+
+  if (first)
+    grub_putcode (GRUB_TERM_DISP_UP, term);
+  else
+    grub_putcode (' ', term);
+
+  e = grub_menu_get_entry (menu, first);
+
+  for (i = 0; i < grub_term_num_entries (term); i++)
+    {
+      print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, offset == i, e, term);
+      if (e)
+       e = e->next;
+    }
+
+  grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X
+                   + grub_term_border_width (term),
+                   GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term));
+
+  if (e)
+    grub_putcode (GRUB_TERM_DISP_DOWN, term);
+  else
+    grub_putcode (' ', term);
+
+  grub_term_gotoxy (term, grub_term_cursor_x (term),
+                   GRUB_TERM_FIRST_ENTRY_Y + offset);
+}
+
+/* Initialize the screen.  If NESTED is non-zero, assume that this menu
+   is run from another menu or a command-line. If EDIT is non-zero, show
+   a message for the menu entry editor.  */
+void
+grub_menu_init_page (int nested, int edit,
+                    struct grub_term_output *term)
+{
+  grub_uint8_t old_color_normal, old_color_highlight;
+
+  grub_term_getcolor (term, &old_color_normal, &old_color_highlight);
+
+  /* By default, use the same colors for the menu.  */
+  grub_color_menu_normal = old_color_normal;
+  grub_color_menu_highlight = old_color_highlight;
+
+  /* Then give user a chance to replace them.  */
+  grub_parse_color_name_pair (&grub_color_menu_normal,
+                             grub_env_get ("menu_color_normal"));
+  grub_parse_color_name_pair (&grub_color_menu_highlight,
+                             grub_env_get ("menu_color_highlight"));
+
+  grub_normal_init_page (term);
+  grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
+  draw_border (term);
+  grub_term_setcolor (term, old_color_normal, old_color_highlight);
+  print_message (nested, edit, term);
+}
+
+static void
+menu_text_print_timeout (int timeout, void *dataptr)
+{
+  const char *msg =
+    _("The highlighted entry will be executed automatically in %ds.");
+  struct menu_viewer_data *data = dataptr;
+  char *msg_translated;
+  int posx;
+
+  grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
+
+  msg_translated = grub_xasprintf (msg, timeout);
+  if (!msg_translated)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+
+  grub_print_message_indented (msg_translated, 3, 0, data->term);
+  posx = grub_term_getxy (data->term) >> 8;
+  print_spaces (grub_term_width (data->term) - posx - 1, data->term);
+
+  grub_term_gotoxy (data->term,
+                   grub_term_cursor_x (data->term),
+                   GRUB_TERM_FIRST_ENTRY_Y + data->offset);
+  grub_term_refresh (data->term);
+}
+
+static void
+menu_text_set_chosen_entry (int entry, void *dataptr)
+{
+  struct menu_viewer_data *data = dataptr;
+  int oldoffset = data->offset;
+  int complete_redraw = 0;
+
+  data->offset = entry - data->first;
+  if (data->offset > grub_term_num_entries (data->term) - 1)
+    {
+      data->first = entry - (grub_term_num_entries (data->term) - 1);
+      data->offset = grub_term_num_entries (data->term) - 1;
+      complete_redraw = 1;
+    }
+  if (data->offset < 0)
+    {
+      data->offset = 0;
+      data->first = entry;
+      complete_redraw = 1;
+    }
+  if (complete_redraw)
+    print_entries (data->menu, data->first, data->offset, data->term);
+  else
+    {
+      print_entry (GRUB_TERM_FIRST_ENTRY_Y + oldoffset, 0,
+                  grub_menu_get_entry (data->menu, data->first + oldoffset),
+                  data->term);
+      print_entry (GRUB_TERM_FIRST_ENTRY_Y + data->offset, 1,
+                  grub_menu_get_entry (data->menu, data->first + data->offset),
+                  data->term);
+    }
+  grub_term_refresh (data->term);
+}
+
+static void
+menu_text_fini (void *dataptr)
+{
+  struct menu_viewer_data *data = dataptr;
+
+  grub_term_setcursor (data->term, 1);
+  grub_term_cls (data->term);
+
+}
+
+static void
+menu_text_clear_timeout (void *dataptr)
+{
+  struct menu_viewer_data *data = dataptr;
+
+  grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
+  print_spaces (grub_term_width (data->term) - 1, data->term);
+  grub_term_gotoxy (data->term, grub_term_cursor_x (data->term),
+                   GRUB_TERM_FIRST_ENTRY_Y + data->offset);
+  grub_term_refresh (data->term);
+}
+
+grub_err_t 
+grub_menu_try_text (struct grub_term_output *term, 
+                   int entry, grub_menu_t menu, int nested)
+{
+  struct menu_viewer_data *data;
+  struct grub_menu_viewer *instance;
+
+  instance = grub_zalloc (sizeof (*instance));
+  if (!instance)
+    return grub_errno;
+
+  data = grub_zalloc (sizeof (*data));
+  if (!data)
+    {
+      grub_free (instance);
+      return grub_errno;
+    }
+
+  data->term = term;
+  instance->data = data;
+  instance->set_chosen_entry = menu_text_set_chosen_entry;
+  instance->print_timeout = menu_text_print_timeout;
+  instance->clear_timeout = menu_text_clear_timeout;
+  instance->fini = menu_text_fini;
+
+  data->menu = menu;
+
+  data->offset = entry;
+  data->first = 0;
+  if (data->offset > grub_term_num_entries (data->term) - 1)
+    {
+      data->first = data->offset - (grub_term_num_entries (data->term) - 1);
+      data->offset = grub_term_num_entries (data->term) - 1;
+    }
+
+  grub_term_setcursor (data->term, 0);
+  grub_menu_init_page (nested, 0, data->term);
+  print_entries (menu, data->first, data->offset, data->term);
+  grub_term_refresh (data->term);
+  grub_menu_register_viewer (instance);
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/normal/misc.c b/grub-core/normal/misc.c
new file mode 100644 (file)
index 0000000..17ba372
--- /dev/null
@@ -0,0 +1,120 @@
+/* misc.c - miscellaneous functions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/disk.h>
+#include <grub/fs.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/datetime.h>
+#include <grub/term.h>
+#include <grub/i18n.h>
+
+/* Print the information on the device NAME.  */
+grub_err_t
+grub_normal_print_device_info (const char *name)
+{
+  grub_device_t dev;
+  char *p;
+
+  p = grub_strchr (name, ',');
+  if (p)
+    {
+      grub_putchar ('\t');
+      grub_printf_ (N_("Partition %s:"), name);
+      grub_putchar (' ');
+    }
+  else
+    {
+      grub_printf_ (N_("Device %s:"), name);
+      grub_putchar (' ');
+    }
+
+  dev = grub_device_open (name);
+  if (! dev)
+    grub_printf ("%s", _("Filesystem cannot be accessed"));
+  else if (dev->disk)
+    {
+      grub_fs_t fs;
+
+      fs = grub_fs_probe (dev);
+      /* Ignore all errors.  */
+      grub_errno = 0;
+
+      if (fs)
+       {
+         grub_printf_ (N_("Filesystem type %s"), fs->name);
+         if (fs->label)
+           {
+             char *label;
+             (fs->label) (dev, &label);
+             if (grub_errno == GRUB_ERR_NONE)
+               {
+                 if (label && grub_strlen (label))
+                   {
+                     grub_putchar (' ');
+                     grub_printf_ (N_("- Label \"%s\""), label);
+                   }
+                 grub_free (label);
+               }
+             grub_errno = GRUB_ERR_NONE;
+           }
+         if (fs->mtime)
+           {
+             grub_int32_t tm;
+             struct grub_datetime datetime;
+             (fs->mtime) (dev, &tm);
+             if (grub_errno == GRUB_ERR_NONE)
+               {
+                 grub_unixtime2datetime (tm, &datetime);
+                 grub_putchar (' ');
+                 grub_printf_ (N_("- Last modification time %d-%02d-%02d "
+                              "%02d:%02d:%02d %s"),
+                              datetime.year, datetime.month, datetime.day,
+                              datetime.hour, datetime.minute, datetime.second,
+                              grub_get_weekday_name (&datetime));
+
+               }
+             grub_errno = GRUB_ERR_NONE;
+           }
+         if (fs->uuid)
+           {
+             char *uuid;
+             (fs->uuid) (dev, &uuid);
+             if (grub_errno == GRUB_ERR_NONE)
+               {
+                 if (uuid && grub_strlen (uuid))
+                   grub_printf (", UUID %s", uuid);
+                 grub_free (uuid);
+               }
+             grub_errno = GRUB_ERR_NONE;
+           }
+       }
+      else if (! dev->disk->has_partitions || dev->disk->partition)
+       grub_printf ("%s", _("Unknown filesystem"));
+      else
+       grub_printf ("%s", _("Partition table"));
+
+      grub_device_close (dev);
+    }
+
+  grub_putchar ('\n');
+  return grub_errno;
+}
diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c
new file mode 100644 (file)
index 0000000..688141d
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/file.h>
+#include <grub/dl.h>
+#include <grub/env.h>
+#include <grub/normal.h>
+
+/* The amount of lines counted by the pager.  */
+static unsigned grub_more_lines;
+
+/* If the more pager is active.  */
+static int grub_more;
+
+static int grub_normal_line_counter = 0;
+
+int
+grub_normal_get_line_counter (void)
+{
+  return grub_normal_line_counter;
+}
+
+static void
+process_newline (void)
+{
+  struct grub_term_output *cur;
+  unsigned height = -1;
+
+  FOR_ACTIVE_TERM_OUTPUTS(cur)
+    if (grub_term_height (cur) < height)
+      height = grub_term_height (cur);
+  grub_more_lines++;
+
+  grub_normal_line_counter++;
+
+  if (grub_more && grub_more_lines >= height - 1)
+    {
+      char key;
+      grub_uint16_t *pos;
+
+      pos = grub_term_save_pos ();
+
+      grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
+      grub_printf ("--MORE--");
+      grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
+
+      key = grub_getkey ();
+
+      /* Remove the message.  */
+      grub_term_restore_pos (pos);
+      grub_printf ("        ");
+      grub_term_restore_pos (pos);
+
+      /* Scroll one lines or an entire page, depending on the key.  */
+      if (key == '\r' || key =='\n')
+       grub_more_lines = height - 2;
+      else
+       grub_more_lines = 0;
+    }
+}
+
+void
+grub_set_more (int onoff)
+{
+  if (onoff == 1)
+    grub_more++;
+  else
+    grub_more--;
+
+  grub_more_lines = 0;
+}
+
+void
+grub_install_newline_hook (void)
+{
+  grub_newline_hook = process_newline;
+}
+
+void
+grub_puts_terminal (const char *str, struct grub_term_output *term)
+{
+  grub_uint32_t code;
+  grub_ssize_t ret;
+  const grub_uint8_t *ptr = (const grub_uint8_t *) str;
+  const grub_uint8_t *end;
+  end = (const grub_uint8_t *) (str + grub_strlen (str));
+
+  while (*ptr)
+    {
+      ret = grub_utf8_to_ucs4 (&code, 1, ptr, end - ptr, &ptr);
+      grub_putcode (code, term);       
+    }
+}
+
+grub_uint16_t *
+grub_term_save_pos (void)
+{
+  struct grub_term_output *cur;
+  unsigned cnt = 0;
+  grub_uint16_t *ret, *ptr;
+  
+  FOR_ACTIVE_TERM_OUTPUTS(cur)
+    cnt++;
+
+  ret = grub_malloc (cnt * sizeof (ret[0]));
+  if (!ret)
+    return NULL;
+
+  ptr = ret;
+  FOR_ACTIVE_TERM_OUTPUTS(cur)
+    *ptr++ = grub_term_getxy (cur);
+
+  return ret;
+}
+
+void
+grub_term_restore_pos (grub_uint16_t *pos)
+{
+  struct grub_term_output *cur;
+  grub_uint16_t *ptr = pos;
+
+  if (!pos)
+    return;
+
+  FOR_ACTIVE_TERM_OUTPUTS(cur)
+  {
+    grub_term_gotoxy (cur, (*ptr & 0xff00) >> 8, *ptr & 0xff);
+    ptr++;
+  }
+}
+
+static void 
+grub_terminal_autoload_free (void)
+{
+  struct grub_term_autoload *cur, *next;
+  unsigned i;
+  for (i = 0; i < 2; i++)
+    for (cur = i ? grub_term_input_autoload : grub_term_output_autoload;
+        cur; cur = next)
+      {
+       next = cur->next;
+       grub_free (cur->name);
+       grub_free (cur->modname);
+       grub_free (cur);
+      }
+  grub_term_input_autoload = NULL;
+  grub_term_output_autoload = NULL;
+}
+
+/* Read the file terminal.lst for auto-loading.  */
+void
+read_terminal_list (const char *prefix)
+{
+  char *filename;
+  grub_file_t file;
+  char *buf = NULL;
+
+  if (!prefix)
+    {
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+  
+  filename = grub_xasprintf ("%s/terminal.lst", prefix);
+  if (!filename)
+    {
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+
+  file = grub_file_open (filename);
+  grub_free (filename);
+  if (!file)
+    {
+      grub_errno = GRUB_ERR_NONE;
+      return;
+    }
+
+  /* Override previous terminal.lst.  */
+  grub_terminal_autoload_free ();
+
+  for (;; grub_free (buf))
+    {
+      char *p, *name;
+      struct grub_term_autoload *cur;
+      struct grub_term_autoload **target = NULL;
+      
+      buf = grub_file_getline (file);
+       
+      if (! buf)
+       break;
+
+      switch (buf[0])
+       {
+       case 'i':
+         target = &grub_term_input_autoload;
+         break;
+
+       case 'o':
+         target = &grub_term_output_autoload;
+         break;
+       }
+      if (!target)
+       continue;
+      
+      name = buf + 1;
+            
+      p = grub_strchr (name, ':');
+      if (! p)
+       continue;
+      
+      *p = '\0';
+      while (*++p == ' ')
+       ;
+
+      cur = grub_malloc (sizeof (*cur));
+      if (!cur)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         continue;
+       }
+      
+      cur->name = grub_strdup (name);
+      if (! name)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         grub_free (cur);
+         continue;
+       }
+       
+      cur->modname = grub_strdup (p);
+      if (! cur->modname)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         grub_free (cur);
+         grub_free (cur->name);
+         continue;
+       }
+      cur->next = *target;
+      *target = cur;
+    }
+  
+  grub_file_close (file);
+
+  grub_errno = GRUB_ERR_NONE;
+}
diff --git a/grub-core/partmap/acorn.c b/grub-core/partmap/acorn.c
new file mode 100644 (file)
index 0000000..677ec61
--- /dev/null
@@ -0,0 +1,145 @@
+/* acorn.c - Read Linux/ADFS partition tables.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+#include <grub/acorn_filecore.h>
+
+#define LINUX_NATIVE_MAGIC grub_cpu_to_le32 (0xdeafa1de)
+#define LINUX_SWAP_MAGIC   grub_cpu_to_le32 (0xdeafab1e)
+#define LINUX_MAP_ENTRIES  (512 / 12)
+
+#define NONADFS_PARTITION_TYPE_LINUX 9
+#define NONADFS_PARTITION_TYPE_MASK 15
+
+struct grub_acorn_boot_block
+{
+  grub_uint8_t misc[0x1C0];
+  struct grub_filecore_disc_record disc_record;
+  grub_uint8_t flags;
+  grub_uint16_t start_cylinder;
+  grub_uint8_t checksum;
+} __attribute__ ((packed, aligned));
+
+struct linux_part
+{
+  grub_uint32_t magic;
+  grub_uint32_t start;
+  grub_uint32_t size;
+};
+
+static struct grub_partition_map grub_acorn_partition_map;
+
+static grub_err_t
+acorn_partition_map_find (grub_disk_t disk, struct linux_part *m,
+                         grub_disk_addr_t *sector)
+{
+  struct grub_acorn_boot_block boot;
+  grub_err_t err;
+  unsigned int checksum = 0;
+  unsigned int heads;
+  unsigned int sectors_per_cylinder;
+  int i;
+
+  err = grub_disk_read (disk, 0xC00 / GRUB_DISK_SECTOR_SIZE, 0,
+                       sizeof (struct grub_acorn_boot_block),
+                       &boot);
+  if (err)
+    return err;
+
+  if ((boot.flags & NONADFS_PARTITION_TYPE_MASK) != NONADFS_PARTITION_TYPE_LINUX)
+    goto fail;
+
+  for (i = 0; i != 0x1ff; ++i)
+    checksum = (checksum & 0xff) + (checksum >> 8) + boot.misc[i];
+
+  if ((grub_uint8_t) checksum != boot.checksum)
+    goto fail;
+
+  heads = (boot.disc_record.heads
+                   + ((boot.disc_record.lowsector >> 6) & 1));
+  sectors_per_cylinder = boot.disc_record.secspertrack * heads;
+  *sector = grub_le_to_cpu16 (boot.start_cylinder) * sectors_per_cylinder;
+
+  return grub_disk_read (disk, *sector, 0,
+                        sizeof (struct linux_part) * LINUX_MAP_ENTRIES,
+                        m);
+
+fail:
+  return grub_error (GRUB_ERR_BAD_PART_TABLE,
+                    "Linux/ADFS partition map not found");
+
+}
+
+
+static grub_err_t
+acorn_partition_map_iterate (grub_disk_t disk,
+                            int (*hook) (grub_disk_t disk,
+                                         const grub_partition_t partition))
+{
+  struct grub_partition part;
+  struct linux_part map[LINUX_MAP_ENTRIES];
+  int i;
+  grub_disk_addr_t sector = 0;
+  grub_err_t err;
+
+  err = acorn_partition_map_find (disk, map, &sector);
+  if (err)
+    return err;
+
+  part.partmap = &grub_acorn_partition_map;
+
+  for (i = 0; i != LINUX_MAP_ENTRIES; ++i)
+    {
+      if (map[i].magic != LINUX_NATIVE_MAGIC
+         && map[i].magic != LINUX_SWAP_MAGIC)
+       return GRUB_ERR_NONE;
+
+      part.start = sector + map[i].start;
+      part.len = map[i].size;
+      part.offset = 6;
+      part.number = part.index = i;
+
+      if (hook (disk, &part))
+       return grub_errno;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+\f
+
+/* Partition map type.  */
+static struct grub_partition_map grub_acorn_partition_map =
+{
+  .name = "acorn",
+  .iterate = acorn_partition_map_iterate,
+};
+
+GRUB_MOD_INIT(part_acorn)
+{
+  grub_partition_map_register (&grub_acorn_partition_map);
+}
+
+GRUB_MOD_FINI(part_acorn)
+{
+  grub_partition_map_unregister (&grub_acorn_partition_map);
+}
diff --git a/grub-core/partmap/amiga.c b/grub-core/partmap/amiga.c
new file mode 100644 (file)
index 0000000..f21c5b2
--- /dev/null
@@ -0,0 +1,151 @@
+/* amiga.c - Read amiga partition tables (RDB).  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+#include <grub/dl.h>
+
+struct grub_amiga_rdsk
+{
+  /* "RDSK".  */
+  grub_uint8_t magic[4];
+  grub_uint32_t size;
+  grub_int32_t checksum;
+  grub_uint32_t scsihost;
+  grub_uint32_t blksz;
+  grub_uint32_t flags;
+  grub_uint32_t badblcklst;
+  grub_uint32_t partitionlst;
+  grub_uint32_t fslst;
+
+  /* The other information is not important for us.  */
+} __attribute__ ((packed));
+
+struct grub_amiga_partition
+{
+  /* "PART".  */
+  grub_uint8_t magic[4];
+  grub_int32_t size;
+  grub_int32_t checksum;
+  grub_uint32_t scsihost;
+  grub_uint32_t next;
+  grub_uint32_t flags;
+  grub_uint32_t unused1[2];
+  grub_uint32_t devflags;
+  grub_uint8_t namelen;
+  grub_uint8_t name[31];
+  grub_uint32_t unused2[15];
+
+  grub_uint32_t unused3[3];
+  grub_uint32_t heads;
+  grub_uint32_t unused4;
+  grub_uint32_t block_per_track;
+  grub_uint32_t unused5[3];
+  grub_uint32_t lowcyl;
+  grub_uint32_t highcyl;
+
+  grub_uint32_t firstcyl;
+} __attribute__ ((packed));
+
+static struct grub_partition_map grub_amiga_partition_map;
+
+\f
+
+static grub_err_t
+amiga_partition_map_iterate (grub_disk_t disk,
+                            int (*hook) (grub_disk_t disk,
+                                         const grub_partition_t partition))
+{
+  struct grub_partition part;
+  struct grub_amiga_rdsk rdsk;
+  int partno = 0;
+  int next = -1;
+  unsigned pos;
+
+  /* The RDSK block is one of the first 15 blocks.  */
+  for (pos = 0; pos < 15; pos++)
+    {
+      /* Read the RDSK block which is a descriptor for the entire disk.  */
+      if (grub_disk_read (disk, pos, 0, sizeof (rdsk), &rdsk))
+       return grub_errno;
+
+      if (grub_strcmp ((char *) rdsk.magic, "RDSK") == 0)
+       {
+         /* Found the first PART block.  */
+         next = grub_be_to_cpu32 (rdsk.partitionlst);
+         break;
+       }
+    }
+
+  if (next == -1)
+    return grub_error (GRUB_ERR_BAD_PART_TABLE,
+                      "Amiga partition map not found");
+
+  /* The end of the partition list is marked using "-1".  */
+  while (next != -1)
+    {
+      struct grub_amiga_partition apart;
+
+      /* Read the RDSK block which is a descriptor for the entire disk.  */
+      if (grub_disk_read (disk, next, 0, sizeof (apart), &apart))
+       return grub_errno;
+
+      /* Calculate the first block and the size of the partition.  */
+      part.start = (grub_be_to_cpu32 (apart.lowcyl)
+                   * grub_be_to_cpu32 (apart.heads)
+                   * grub_be_to_cpu32 (apart.block_per_track));
+      part.len = ((grub_be_to_cpu32 (apart.highcyl)
+                  - grub_be_to_cpu32 (apart.lowcyl) + 1)
+                 * grub_be_to_cpu32 (apart.heads)
+                 * grub_be_to_cpu32 (apart.block_per_track));
+
+      part.offset = (grub_off_t) next * 512;
+      part.number = partno;
+      part.index = 0;
+      part.partmap = &grub_amiga_partition_map;
+
+      if (hook (disk, &part))
+       return grub_errno;
+
+      next = grub_be_to_cpu32 (apart.next);
+      partno++;
+    }
+
+  return 0;
+}
+
+\f
+/* Partition map type.  */
+static struct grub_partition_map grub_amiga_partition_map =
+  {
+    .name = "amiga",
+    .iterate = amiga_partition_map_iterate,
+  };
+
+GRUB_MOD_INIT(part_amiga)
+{
+  grub_partition_map_register (&grub_amiga_partition_map);
+}
+
+GRUB_MOD_FINI(part_amiga)
+{
+  grub_partition_map_unregister (&grub_amiga_partition_map);
+}
diff --git a/grub-core/partmap/apple.c b/grub-core/partmap/apple.c
new file mode 100644 (file)
index 0000000..e162d18
--- /dev/null
@@ -0,0 +1,197 @@
+/* apple.c - Read macintosh partition tables.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+
+#define GRUB_APPLE_HEADER_MAGIC        0x4552
+#define GRUB_APPLE_PART_MAGIC  0x504D
+
+struct grub_apple_header
+{
+  /* The magic number to identify the partition map, it should have
+     the value `0x4552'.  */
+  grub_uint16_t magic;
+  grub_uint16_t blocksize;
+};
+
+struct grub_apple_part
+{
+  /* The magic number to identify this as a partition, it should have
+     the value `0x504D'.  */
+  grub_uint16_t magic;
+
+  /* Reserved.  */
+  grub_uint16_t reserved;
+
+  /* The size of the partition map in blocks.  */
+  grub_uint32_t partmap_size;
+
+  /* The first physical block of the partition.  */
+  grub_uint32_t first_phys_block;
+
+  /* The amount of blocks.  */
+  grub_uint32_t blockcnt;
+
+  /* The partition name.  */
+  char partname[32];
+
+  /* The partition type.  */
+  char parttype[32];
+
+  /* The first datablock of the partition.  */
+  grub_uint32_t datablocks_first;
+
+  /* The amount datablocks.  */
+  grub_uint32_t datablocks_count;
+
+  /* The status of the partition. (???)  */
+  grub_uint32_t status;
+
+  /* The first block on which the bootcode can be found.  */
+  grub_uint32_t bootcode_pos;
+
+  /* The size of the bootcode in bytes.  */
+  grub_uint32_t bootcode_size;
+
+  /* The load address of the bootcode.  */
+  grub_uint32_t bootcode_loadaddr;
+
+  /* Reserved.  */
+  grub_uint32_t reserved2;
+
+  /* The entry point of the bootcode.  */
+  grub_uint32_t bootcode_entrypoint;
+
+  /* Reserved.  */
+  grub_uint32_t reserved3;
+
+  /* A checksum of the bootcode.  */
+  grub_uint32_t bootcode_checksum;
+
+  /* The processor type.  */
+  char processor[16];
+
+  /* Padding.  */
+  grub_uint16_t pad[187];
+};
+
+static struct grub_partition_map grub_apple_partition_map;
+\f
+
+static grub_err_t
+apple_partition_map_iterate (grub_disk_t disk,
+                            int (*hook) (grub_disk_t disk,
+                                         const grub_partition_t partition))
+{
+  struct grub_partition part;
+  struct grub_apple_header aheader;
+  struct grub_apple_part apart;
+  int partno = 0, partnum = 0;
+  unsigned pos;
+
+  part.partmap = &grub_apple_partition_map;
+
+  if (grub_disk_read (disk, 0, 0, sizeof (aheader), &aheader))
+    return grub_errno;
+
+  if (grub_be_to_cpu16 (aheader.magic) != GRUB_APPLE_HEADER_MAGIC)
+    {
+      grub_dprintf ("partition",
+                   "bad magic (found 0x%x; wanted 0x%x\n",
+                   grub_be_to_cpu16 (aheader.magic),
+                   GRUB_APPLE_HEADER_MAGIC);
+      goto fail;
+    }
+
+  pos = grub_be_to_cpu16 (aheader.blocksize);
+
+  do
+    {
+      part.offset = pos / GRUB_DISK_SECTOR_SIZE;
+      part.index = pos % GRUB_DISK_SECTOR_SIZE;
+
+      if (grub_disk_read (disk, part.offset, part.index,
+                         sizeof (struct grub_apple_part),  &apart))
+       return grub_errno;
+
+      if (grub_be_to_cpu16 (apart.magic) != GRUB_APPLE_PART_MAGIC)
+       {
+         grub_dprintf ("partition",
+                       "partition %d: bad magic (found 0x%x; wanted 0x%x\n",
+                       partno, grub_be_to_cpu16 (apart.magic),
+                       GRUB_APPLE_PART_MAGIC);
+         break;
+       }
+
+      if (partnum == 0)
+       partnum = grub_be_to_cpu32 (apart.partmap_size);
+
+      part.start = ((grub_disk_addr_t) grub_be_to_cpu32 (apart.first_phys_block)
+                   * grub_be_to_cpu16 (aheader.blocksize))
+       / GRUB_DISK_SECTOR_SIZE;
+      part.len = ((grub_disk_addr_t) grub_be_to_cpu32 (apart.blockcnt)
+                 * grub_be_to_cpu16 (aheader.blocksize))
+       / GRUB_DISK_SECTOR_SIZE;
+      part.offset = pos;
+      part.index = partno;
+      part.number = partno;
+
+      grub_dprintf ("partition",
+                   "partition %d: name %s, type %s, start 0x%x, len 0x%x\n",
+                   partno, apart.partname, apart.parttype,
+                   grub_be_to_cpu32 (apart.first_phys_block),
+                   grub_be_to_cpu32 (apart.blockcnt));
+
+      if (hook (disk, &part))
+       return grub_errno;
+
+      pos += grub_be_to_cpu16 (aheader.blocksize);
+      partno++;
+    }
+  while (partno < partnum);
+
+  if (partno != 0)
+    return 0;
+
+ fail:
+  return grub_error (GRUB_ERR_BAD_PART_TABLE,
+                    "Apple partition map not found");
+}
+
+\f
+/* Partition map type.  */
+static struct grub_partition_map grub_apple_partition_map =
+  {
+    .name = "apple",
+    .iterate = apple_partition_map_iterate,
+  };
+
+GRUB_MOD_INIT(part_apple)
+{
+  grub_partition_map_register (&grub_apple_partition_map);
+}
+
+GRUB_MOD_FINI(part_apple)
+{
+  grub_partition_map_unregister (&grub_apple_partition_map);
+}
+
diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c
new file mode 100644 (file)
index 0000000..d28f36d
--- /dev/null
@@ -0,0 +1,97 @@
+/* bsdlabel.c - Read BSD style partition tables.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/partition.h>
+#include <grub/bsdlabel.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/dl.h>
+
+static struct grub_partition_map grub_bsdlabel_partition_map;
+\f
+
+static grub_err_t
+bsdlabel_partition_map_iterate (grub_disk_t disk,
+                               int (*hook) (grub_disk_t disk,
+                                            const grub_partition_t partition))
+{
+  struct grub_partition_bsd_disk_label label;
+  struct grub_partition p;
+  grub_disk_addr_t delta = 0;
+  unsigned pos;
+
+  /* BSDLabel offsets are absolute even when it's embed inside partition.  */
+  delta = grub_partition_get_start (disk->partition);
+
+  /* Read the BSD label.  */
+  if (grub_disk_read (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR,
+                     0, sizeof (label), &label))
+    return grub_errno;
+
+  /* Check if it is valid.  */
+  if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC))
+    return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
+
+  pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR
+    * GRUB_DISK_SECTOR_SIZE;
+
+  for (p.number = 0;
+       p.number < grub_cpu_to_le16 (label.num_partitions);
+       p.number++)
+    {
+      struct grub_partition_bsd_entry be;
+
+      p.offset = pos / GRUB_DISK_SECTOR_SIZE;
+      p.index = pos % GRUB_DISK_SECTOR_SIZE;
+
+      if (grub_disk_read (disk, p.offset, p.index, sizeof (be),  &be))
+       return grub_errno;
+
+      p.start = grub_le_to_cpu32 (be.offset) - delta;
+      p.len = grub_le_to_cpu32 (be.size);
+      p.partmap = &grub_bsdlabel_partition_map;
+
+      if (be.fs_type != GRUB_PC_PARTITION_BSD_TYPE_UNUSED)
+       if (hook (disk, &p))
+         return grub_errno;
+
+      pos += sizeof (struct grub_partition_bsd_entry);
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+\f
+/* Partition map type.  */
+static struct grub_partition_map grub_bsdlabel_partition_map =
+  {
+    .name = "bsd",
+    .iterate = bsdlabel_partition_map_iterate,
+  };
+
+GRUB_MOD_INIT(part_bsd)
+{
+  grub_partition_map_register (&grub_bsdlabel_partition_map);
+}
+
+GRUB_MOD_FINI(part_bsd)
+{
+  grub_partition_map_unregister (&grub_bsdlabel_partition_map);
+}
diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c
new file mode 100644 (file)
index 0000000..9dd88be
--- /dev/null
@@ -0,0 +1,127 @@
+/* gpt.c - Read GUID Partition Tables (GPT).  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+#include <grub/dl.h>
+#include <grub/msdos_partition.h>
+#include <grub/gpt_partition.h>
+
+static grub_uint8_t grub_gpt_magic[8] =
+  {
+    0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54
+  };
+
+static const grub_gpt_part_type_t grub_gpt_partition_type_empty = GRUB_GPT_PARTITION_TYPE_EMPTY;
+
+static struct grub_partition_map grub_gpt_partition_map;
+
+\f
+
+static grub_err_t
+gpt_partition_map_iterate (grub_disk_t disk,
+                          int (*hook) (grub_disk_t disk,
+                                       const grub_partition_t partition))
+{
+  struct grub_partition part;
+  struct grub_gpt_header gpt;
+  struct grub_gpt_partentry entry;
+  struct grub_msdos_partition_mbr mbr;
+  grub_uint64_t entries;
+  unsigned int i;
+  int last_offset = 0;
+
+  /* Read the protective MBR.  */
+  if (grub_disk_read (disk, 0, 0, sizeof (mbr), &mbr))
+    return grub_errno;
+
+  /* Check if it is valid.  */
+  if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE))
+    return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
+
+  /* Make sure the MBR is a protective MBR and not a normal MBR.  */
+  if (mbr.entries[0].type != GRUB_PC_PARTITION_TYPE_GPT_DISK)
+    return grub_error (GRUB_ERR_BAD_PART_TABLE, "no GPT partition map found");
+
+  /* Read the GPT header.  */
+  if (grub_disk_read (disk, 1, 0, sizeof (gpt), &gpt))
+    return grub_errno;
+
+  if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic)))
+    return grub_error (GRUB_ERR_BAD_PART_TABLE, "no valid GPT header");
+
+  grub_dprintf ("gpt", "Read a valid GPT header\n");
+
+  entries = grub_le_to_cpu64 (gpt.partitions);
+  for (i = 0; i < grub_le_to_cpu32 (gpt.maxpart); i++)
+    {
+      if (grub_disk_read (disk, entries, last_offset,
+                         sizeof (entry), &entry))
+       return grub_errno;
+
+      if (grub_memcmp (&grub_gpt_partition_type_empty, &entry.type,
+                      sizeof (grub_gpt_partition_type_empty)))
+       {
+         /* Calculate the first block and the size of the partition.  */
+         part.start = grub_le_to_cpu64 (entry.start);
+         part.len = (grub_le_to_cpu64 (entry.end)
+                     - grub_le_to_cpu64 (entry.start) + 1);
+         part.offset = entries;
+         part.number = i;
+         part.index = last_offset;
+         part.partmap = &grub_gpt_partition_map;
+
+         grub_dprintf ("gpt", "GPT entry %d: start=%lld, length=%lld\n", i,
+                       (unsigned long long) part.start,
+                       (unsigned long long) part.len);
+
+         if (hook (disk, &part))
+           return grub_errno;
+       }
+
+      last_offset += grub_le_to_cpu32 (gpt.partentry_size);
+      if (last_offset == GRUB_DISK_SECTOR_SIZE)
+       {
+         last_offset = 0;
+         entries++;
+       }
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+\f
+/* Partition map type.  */
+static struct grub_partition_map grub_gpt_partition_map =
+  {
+    .name = "gpt",
+    .iterate = gpt_partition_map_iterate,
+  };
+
+GRUB_MOD_INIT(part_gpt)
+{
+  grub_partition_map_register (&grub_gpt_partition_map);
+}
+
+GRUB_MOD_FINI(part_gpt)
+{
+  grub_partition_map_unregister (&grub_gpt_partition_map);
+}
diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c
new file mode 100644 (file)
index 0000000..3898d09
--- /dev/null
@@ -0,0 +1,152 @@
+/* pc.c - Read PC style partition tables.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/partition.h>
+#include <grub/msdos_partition.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/dl.h>
+
+static struct grub_partition_map grub_msdos_partition_map;
+\f
+
+static grub_err_t
+pc_partition_map_iterate (grub_disk_t disk,
+                         int (*hook) (grub_disk_t disk,
+                                      const grub_partition_t partition))
+{
+  struct grub_partition p;
+  struct grub_msdos_partition_mbr mbr;
+  int labeln = 0;
+  grub_disk_addr_t lastaddr;
+  grub_disk_addr_t ext_offset;
+
+  p.offset = 0;
+  ext_offset = 0;
+  p.number = -1;
+  p.partmap = &grub_msdos_partition_map;
+
+  /* Any value different than `p.offset' will satisfy the check during
+     first loop.  */
+  lastaddr = !p.offset;
+
+  while (1)
+    {
+      int i;
+      struct grub_msdos_partition_entry *e;
+
+      /* Read the MBR.  */
+      if (grub_disk_read (disk, p.offset, 0, sizeof (mbr), &mbr))
+       goto finish;
+
+      /* This is our loop-detection algorithm. It works the following way:
+        It saves last position which was a power of two. Then it compares the
+        saved value with a current one. This way it's guaranteed that the loop
+        will be broken by at most third walk.
+       */
+      if (labeln && lastaddr == p.offset)
+       return grub_error (GRUB_ERR_BAD_PART_TABLE, "loop detected");
+
+      labeln++;
+      if ((labeln & (labeln - 1)) == 0)
+       lastaddr = p.offset;
+
+      /* Check if it is valid.  */
+      if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE))
+       return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
+
+      for (i = 0; i < 4; i++)
+       if (mbr.entries[i].flag & 0x7f)
+         return grub_error (GRUB_ERR_BAD_PART_TABLE, "bad boot flag");
+
+      /* Analyze DOS partitions.  */
+      for (p.index = 0; p.index < 4; p.index++)
+       {
+         e = mbr.entries + p.index;
+
+         p.start = p.offset + grub_le_to_cpu32 (e->start);
+         p.len = grub_le_to_cpu32 (e->length);
+
+         grub_dprintf ("partition",
+                       "partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n",
+                       p.index, e->flag, e->type,
+                       (unsigned long long) p.start,
+                       (unsigned long long) p.len);
+
+         /* If this is a GPT partition, this MBR is just a dummy.  */
+         if (e->type == GRUB_PC_PARTITION_TYPE_GPT_DISK && p.index == 0)
+           return grub_error (GRUB_ERR_BAD_PART_TABLE, "dummy mbr");
+
+         /* If this partition is a normal one, call the hook.  */
+         if (! grub_msdos_partition_is_empty (e->type)
+             && ! grub_msdos_partition_is_extended (e->type))
+           {
+             p.number++;
+
+             if (hook (disk, &p))
+               return grub_errno;
+           }
+         else if (p.number < 4)
+           /* If this partition is a logical one, shouldn't increase the
+              partition number.  */
+           p.number++;
+       }
+
+      /* Find an extended partition.  */
+      for (i = 0; i < 4; i++)
+       {
+         e = mbr.entries + i;
+
+         if (grub_msdos_partition_is_extended (e->type))
+           {
+             p.offset = ext_offset + grub_le_to_cpu32 (e->start);
+             if (! ext_offset)
+               ext_offset = p.offset;
+
+             break;
+           }
+       }
+
+      /* If no extended partition, the end.  */
+      if (i == 4)
+       break;
+    }
+
+ finish:
+  return grub_errno;
+}
+
+\f
+/* Partition map type.  */
+static struct grub_partition_map grub_msdos_partition_map =
+  {
+    .name = "msdos",
+    .iterate = pc_partition_map_iterate,
+  };
+
+GRUB_MOD_INIT(part_msdos)
+{
+  grub_partition_map_register (&grub_msdos_partition_map);
+}
+
+GRUB_MOD_FINI(part_msdos)
+{
+  grub_partition_map_unregister (&grub_msdos_partition_map);
+}
diff --git a/grub-core/partmap/sun.c b/grub-core/partmap/sun.c
new file mode 100644 (file)
index 0000000..7a7eaef
--- /dev/null
@@ -0,0 +1,164 @@
+/* sun.c - Read SUN style partition tables.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/partition.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/dl.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/err.h>
+
+#define GRUB_PARTMAP_SUN_MAGIC 0xDABE
+#define GRUB_PARTMAP_SUN_MAX_PARTS 8
+#define GRUB_PARTMAP_SUN_WHOLE_DISK_ID 0x05
+
+struct grub_sun_partition_info
+{
+  grub_uint8_t spare1;
+  grub_uint8_t id;
+  grub_uint8_t spare2;
+  grub_uint8_t flags;
+} __attribute__ ((packed));
+
+struct grub_sun_partition_descriptor
+{
+  grub_uint32_t start_cylinder;
+  grub_uint32_t num_sectors;
+} __attribute__ ((packed));
+
+struct grub_sun_block
+{
+  grub_uint8_t  info[128];      /* Informative text string.  */
+  grub_uint8_t  spare0[14];
+  struct grub_sun_partition_info infos[8];
+  grub_uint8_t  spare1[246];    /* Boot information etc.  */
+  grub_uint16_t  rspeed;        /* Disk rotational speed.  */
+  grub_uint16_t  pcylcount;     /* Physical cylinder count.  */
+  grub_uint16_t  sparecyl;      /* extra sects per cylinder.  */
+  grub_uint8_t  spare2[4];      /* More magic...  */
+  grub_uint16_t  ilfact;        /* Interleave factor.  */
+  grub_uint16_t  ncyl;          /* Data cylinder count.  */
+  grub_uint16_t  nacyl;         /* Alt. cylinder count.  */
+  grub_uint16_t  ntrks;         /* Tracks per cylinder.  */
+  grub_uint16_t  nsect;         /* Sectors per track.  */
+  grub_uint8_t  spare3[4];      /* Even more magic...  */
+  struct grub_sun_partition_descriptor partitions[8];
+  grub_uint16_t  magic;         /* Magic number.  */
+  grub_uint16_t  csum;          /* Label xor'd checksum.  */
+} __attribute__ ((packed));
+
+static struct grub_partition_map grub_sun_partition_map;
+
+/* Verify checksum (true=ok).  */
+static int
+grub_sun_is_valid (struct grub_sun_block *label)
+{
+  grub_uint16_t *pos;
+  grub_uint16_t sum = 0;
+
+  for (pos = (grub_uint16_t *) label;
+       pos < (grub_uint16_t *) (label + 1);
+       pos++)
+    sum ^= *pos;
+
+  return ! sum;
+}
+
+static grub_err_t
+sun_partition_map_iterate (grub_disk_t disk,
+                           int (*hook) (grub_disk_t disk,
+                                       const grub_partition_t partition))
+{
+  grub_partition_t p;
+  struct grub_sun_block block;
+  int partnum;
+  grub_err_t err;
+
+  p = (grub_partition_t) grub_zalloc (sizeof (struct grub_partition));
+  if (! p)
+    return grub_errno;
+
+  p->partmap = &grub_sun_partition_map;
+  err = grub_disk_read (disk, 0, 0, sizeof (struct grub_sun_block),
+                       &block);
+  if (err)
+    {
+      grub_free (p);
+      return err;
+    }
+
+  if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.magic))
+    {
+      grub_free (p);
+      return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a sun partition table");
+    }
+
+  if (! grub_sun_is_valid (&block))
+    {
+      grub_free (p);      
+      return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum");
+    }
+
+  /* Maybe another error value would be better, because partition
+     table _is_ recognized but invalid.  */
+  for (partnum = 0; partnum < GRUB_PARTMAP_SUN_MAX_PARTS; partnum++)
+    {
+      struct grub_sun_partition_descriptor *desc;
+
+      if (block.infos[partnum].id == 0
+         || block.infos[partnum].id == GRUB_PARTMAP_SUN_WHOLE_DISK_ID)
+       continue;
+
+      desc = &block.partitions[partnum];
+      p->start = ((grub_uint64_t) grub_be_to_cpu32 (desc->start_cylinder)
+                 * grub_be_to_cpu16 (block.ntrks)
+                 * grub_be_to_cpu16 (block.nsect));
+      p->len = grub_be_to_cpu32 (desc->num_sectors);
+      p->number = p->index = partnum;
+      if (p->len)
+       {
+         if (hook (disk, p))
+           partnum = GRUB_PARTMAP_SUN_MAX_PARTS;
+       }
+    }
+
+  grub_free (p);
+
+  return grub_errno;
+}
+
+/* Partition map type.  */
+static struct grub_partition_map grub_sun_partition_map =
+  {
+    .name = "sun",
+    .iterate = sun_partition_map_iterate,
+  };
+
+GRUB_MOD_INIT(part_sun)
+{
+  grub_partition_map_register (&grub_sun_partition_map);
+}
+
+GRUB_MOD_FINI(part_sun)
+{
+  grub_partition_map_unregister (&grub_sun_partition_map);
+}
+
diff --git a/grub-core/partmap/sunpc.c b/grub-core/partmap/sunpc.c
new file mode 100644 (file)
index 0000000..ea69c28
--- /dev/null
@@ -0,0 +1,144 @@
+/* sunpc.c - Read SUN PC style partition tables.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/partition.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/dl.h>
+#include <grub/symbol.h>
+#include <grub/types.h>
+#include <grub/err.h>
+
+#define GRUB_PARTMAP_SUN_PC_MAGIC 0xDABE
+#define GRUB_PARTMAP_SUN_PC_MAX_PARTS 16
+#define GRUB_PARTMAP_SUN_PC_WHOLE_DISK_ID 0x05
+
+struct grub_sun_pc_partition_descriptor
+{
+  grub_uint16_t id;
+  grub_uint16_t unused;
+  grub_uint32_t start_sector;
+  grub_uint32_t num_sectors;
+} __attribute__ ((packed));
+
+struct grub_sun_pc_block
+{
+  grub_uint8_t unused[72];
+  struct grub_sun_pc_partition_descriptor partitions[GRUB_PARTMAP_SUN_PC_MAX_PARTS];
+  grub_uint8_t unused2[244];
+  grub_uint16_t  magic;         /* Magic number.  */
+  grub_uint16_t  csum;          /* Label xor'd checksum.  */
+} __attribute__ ((packed));
+
+static struct grub_partition_map grub_sun_pc_partition_map;
+
+/* Verify checksum (true=ok).  */
+static int
+grub_sun_is_valid (struct grub_sun_pc_block *label)
+{
+  grub_uint16_t *pos;
+  grub_uint16_t sum = 0;
+
+  for (pos = (grub_uint16_t *) label;
+       pos < (grub_uint16_t *) (label + 1);
+       pos++)
+    sum ^= *pos;
+
+  return ! sum;
+}
+
+static grub_err_t
+sun_pc_partition_map_iterate (grub_disk_t disk,
+                             int (*hook) (grub_disk_t disk,
+                                          const grub_partition_t partition))
+{
+  grub_partition_t p;
+  struct grub_sun_pc_block block;
+  int partnum;
+  grub_err_t err;
+
+  p = (grub_partition_t) grub_zalloc (sizeof (struct grub_partition));
+  if (! p)
+    return grub_errno;
+
+  p->partmap = &grub_sun_pc_partition_map;
+  err = grub_disk_read (disk, 1, 0, sizeof (struct grub_sun_pc_block), &block);
+  if (err)
+    {
+      grub_free (p);
+      return err;
+    }
+  
+  if (GRUB_PARTMAP_SUN_PC_MAGIC != grub_le_to_cpu16 (block.magic))
+    {
+      grub_free (p);
+      return grub_error (GRUB_ERR_BAD_PART_TABLE, 
+                        "not a sun_pc partition table");
+    }
+
+  if (! grub_sun_is_valid (&block))
+    {
+      grub_free (p);
+      return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum");
+    }
+
+  /* Maybe another error value would be better, because partition
+     table _is_ recognized but invalid.  */
+  for (partnum = 0; partnum < GRUB_PARTMAP_SUN_PC_MAX_PARTS; partnum++)
+    {
+      struct grub_sun_pc_partition_descriptor *desc;
+
+      if (block.partitions[partnum].id == 0
+         || block.partitions[partnum].id == GRUB_PARTMAP_SUN_PC_WHOLE_DISK_ID)
+       continue;
+
+      desc = &block.partitions[partnum];
+      p->start = grub_le_to_cpu32 (desc->start_sector);
+      p->len = grub_le_to_cpu32 (desc->num_sectors);
+      p->number = partnum;
+      if (p->len)
+       {
+         if (hook (disk, p))
+           partnum = GRUB_PARTMAP_SUN_PC_MAX_PARTS;
+       }
+    }
+
+  grub_free (p);
+
+  return grub_errno;
+}
+
+/* Partition map type.  */
+static struct grub_partition_map grub_sun_pc_partition_map =
+  {
+    .name = "sunpc",
+    .iterate = sun_pc_partition_map_iterate,
+  };
+
+GRUB_MOD_INIT(part_sunpc)
+{
+  grub_partition_map_register (&grub_sun_pc_partition_map);
+}
+
+GRUB_MOD_FINI(part_sunpc)
+{
+  grub_partition_map_unregister (&grub_sun_pc_partition_map);
+}
+
diff --git a/grub-core/parttool/msdospart.c b/grub-core/parttool/msdospart.c
new file mode 100644 (file)
index 0000000..006a87d
--- /dev/null
@@ -0,0 +1,155 @@
+/* pcpart.c - manipulate fdisk partitions */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  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/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/msdos_partition.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/parttool.h>
+
+static int activate_table_handle = -1;
+static int type_table_handle = -1;
+
+static struct grub_parttool_argdesc grub_pcpart_bootargs[] =
+{
+  {"boot", "Make partition active", GRUB_PARTTOOL_ARG_BOOL},
+  {0, 0, 0}
+};
+
+static grub_err_t grub_pcpart_boot (const grub_device_t dev,
+                                   const struct grub_parttool_args *args)
+{
+  int i, index;
+  grub_partition_t part;
+  struct grub_msdos_partition_mbr mbr;
+
+  if (dev->disk->partition->offset)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a primary partition");
+
+  index = dev->disk->partition->index;
+  part = dev->disk->partition;
+  dev->disk->partition = part->parent;
+
+  /* Read the MBR.  */
+  if (grub_disk_read (dev->disk, 0, 0, sizeof (mbr), &mbr))
+    {
+      dev->disk->partition = part;
+      return grub_errno;
+    }
+
+  if (args[0].set && args[0].bool)
+    {
+      for (i = 0; i < 4; i++)
+       mbr.entries[i].flag = 0x0;
+      mbr.entries[index].flag = 0x80;
+      grub_printf ("Partition %d is active now. \n", index);
+    }
+  else
+    {
+      mbr.entries[index].flag = 0x0;
+      grub_printf ("Cleared active flag on %d. \n", index);
+    }
+
+   /* Write the MBR.  */
+  grub_disk_write (dev->disk, 0, 0, sizeof (mbr), &mbr);
+
+  dev->disk->partition = part;
+
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_parttool_argdesc grub_pcpart_typeargs[] =
+{
+  {"type", "Change partition type", GRUB_PARTTOOL_ARG_VAL},
+  {"hidden", "Make partition hidden", GRUB_PARTTOOL_ARG_BOOL},
+  {0, 0, 0}
+};
+
+static grub_err_t grub_pcpart_type (const grub_device_t dev,
+                                   const struct grub_parttool_args *args)
+{
+  int index;
+  grub_uint8_t type;
+  grub_partition_t part;
+  struct grub_msdos_partition_mbr mbr;
+
+  index = dev->disk->partition->index;
+  part = dev->disk->partition;
+  dev->disk->partition = part->parent;
+
+  /* Read the parttable.  */
+  if (grub_disk_read (dev->disk, part->offset, 0,
+                     sizeof (mbr), &mbr))
+    {
+      dev->disk->partition = part;
+      return grub_errno;
+    }
+
+  if (args[0].set)
+    type = grub_strtoul (args[0].str, 0, 0);
+  else
+    type = mbr.entries[index].type;
+
+  if (args[1].set)
+    {
+      if (args[1].bool)
+       type |= GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
+      else
+       type &= ~GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
+    }
+
+  if (grub_msdos_partition_is_empty (type)
+      || grub_msdos_partition_is_extended (type))
+    {
+      dev->disk->partition = part;
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid type");
+    }
+
+  mbr.entries[index].type = type;
+  grub_printf ("Setting partition type to 0x%x\n", type);
+
+   /* Write the parttable.  */
+  grub_disk_write (dev->disk, part->offset, 0,
+                  sizeof (mbr), &mbr);
+
+  dev->disk->partition = part;
+
+  return GRUB_ERR_NONE;
+}
+
+GRUB_MOD_INIT (msdospart)
+{
+  activate_table_handle = grub_parttool_register ("msdos",
+                                                 grub_pcpart_boot,
+                                                 grub_pcpart_bootargs);
+  type_table_handle = grub_parttool_register ("msdos",
+                                             grub_pcpart_type,
+                                             grub_pcpart_typeargs);
+
+}
+GRUB_MOD_FINI(msdospart)
+{
+  grub_parttool_unregister (activate_table_handle);
+  grub_parttool_unregister (type_table_handle);
+}
diff --git a/grub-core/po/Makefile.am b/grub-core/po/Makefile.am
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/grub-core/po/POTFILES b/grub-core/po/POTFILES
new file mode 100644 (file)
index 0000000..0dfc3c0
--- /dev/null
@@ -0,0 +1,81 @@
+# List of files which contain translatable strings.
+commands/acpi.c
+commands/blocklist.c
+commands/boot.c
+commands/cat.c
+commands/cmp.c
+commands/configfile.c
+commands/crc.c
+commands/date.c
+commands/echo.c
+commands/efi/fixvideo.c
+commands/efi/loadbios.c
+commands/gptsync.c
+commands/halt.c
+commands/handler.c
+commands/hdparm.c
+commands/help.c
+commands/hexdump.c
+commands/i386/cpuid.c
+commands/i386/pc/drivemap.c
+commands/i386/pc/halt.c
+commands/i386/pc/play.c
+commands/i386/pc/pxecmd.c
+commands/i386/pc/vbeinfo.c
+commands/i386/pc/vbetest.c
+commands/ieee1275/suspend.c
+commands/keystatus.c
+commands/loadenv.c
+commands/ls.c
+commands/lsmmap.c
+commands/lspci.c
+commands/memrw.c
+commands/minicmd.c
+commands/parttool.c
+commands/password.c
+commands/probe.c
+commands/read.c
+commands/reboot.c
+commands/search.c
+commands/search_file.c
+commands/search_label.c
+commands/search_uuid.c
+commands/sleep.c
+commands/test.c
+commands/true.c
+commands/usbtest.c
+commands/videotest.c
+commands/xnu_uuid.c
+
+disk/loopback.c
+
+hello/hello.c
+
+lib/arg.c
+
+loader/efi/appleloader.c
+loader/efi/chainloader.c
+loader/i386/bsd.c
+loader/i386/efi/linux.c
+loader/i386/ieee1275/linux.c
+loader/i386/linux.c
+loader/i386/pc/chainloader.c
+loader/i386/pc/linux.c
+loader/i386/xnu.c
+loader/multiboot.c
+loader/powerpc/ieee1275/linux.c
+loader/sparc64/ieee1275/linux.c
+loader/xnu.c
+
+normal/auth.c
+normal/color.c
+normal/dyncmd.c
+normal/main.c
+normal/menu_entry.c
+normal/menu_text.c
+normal/misc.c
+
+term/serial.c
+
+util/grub-mkrawimage.c
+util/i386/pc/grub-setup.c
diff --git a/grub-core/po/POTFILES-shell b/grub-core/po/POTFILES-shell
new file mode 100644 (file)
index 0000000..90d2b97
--- /dev/null
@@ -0,0 +1,5 @@
+# List of files which contain translatable strings.  Only files written in
+# Shell language are included here.
+util/grub.d/10_kfreebsd.in
+util/grub.d/10_linux.in
+util/grub.d/10_netbsd.in
diff --git a/grub-core/po/README b/grub-core/po/README
new file mode 100644 (file)
index 0000000..8015995
--- /dev/null
@@ -0,0 +1,24 @@
+
+If you checked out this source tree directly from GRUB Bazaar, you might
+be wondering where are the POT and PO files.  Here are some instructions
+that will hopefully clarify the situation.
+
+  - If you're a user or a distributor, simply fill the po directory by
+    importing translations from the Translation Project:
+
+      rsync -Lrtvz  translationproject.org::tp/latest/grub/ po
+
+    GRUB's build system will automatically detect those and include them
+    in your install.
+
+  - If you're a translator and want to add a new translation or improve an
+    existing one, get in touch with the Translation Project
+    (http://translationproject.org/).  The GRUB project doesn't interact
+    with translators directly (but we dearly appreciate your work!).
+
+  - If you're a developer adding/removing/modifiing translatable strings,
+    you can check that these turn into a sane POT file by using the
+    `po/grub.pot' make rule.
+
+  - If you're the maintainer of GNU GRUB preparing a new release, don't
+    forget to include the latest PO files in your source tarball!
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
new file mode 100644 (file)
index 0000000..40f1612
--- /dev/null
@@ -0,0 +1,392 @@
+/* execute.c -- Execute a GRUB script.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/script_sh.h>
+#include <grub/command.h>
+#include <grub/menu.h>
+#include <grub/lib/arg.h>
+#include <grub/normal.h>
+
+/* Max digits for a char is 3 (0xFF is 255), similarly for an int it
+   is sizeof (int) * 3, and one extra for a possible -ve sign.  */
+#define ERRNO_DIGITS_MAX  (sizeof (int) * 3 + 1)
+
+static grub_err_t
+grub_script_execute_cmd (struct grub_script_cmd *cmd)
+{
+  int ret;
+  char errnobuf[ERRNO_DIGITS_MAX + 1];
+
+  if (cmd == 0)
+    return 0;
+
+  ret = cmd->exec (cmd);
+
+  grub_snprintf (errnobuf, sizeof (errnobuf), "%d", ret);
+  grub_env_set ("?", errnobuf);
+  return ret;
+}
+
+#define ARG_ALLOCATION_UNIT  (32 * sizeof (char))
+#define ARGV_ALLOCATION_UNIT (8 * sizeof (void*))
+
+/* Expand arguments in ARGLIST into multiple arguments.  */
+char **
+grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count)
+{
+  int i;
+  int oom;
+  int argc;
+  int empty;
+  char *ptr;
+  char **argv;
+  char *value;
+  struct grub_script_arg *arg;
+
+  auto void push (char *str);
+  void push (char *str)
+  {
+    char **p;
+
+    if (oom)
+      return;
+
+    p = grub_realloc (argv, ALIGN_UP (sizeof(char*) * (argc + 1), ARGV_ALLOCATION_UNIT));
+    if (!p)
+      oom = 1;
+    else
+      {
+       p[argc++] = str;
+       argv = p;
+      }
+  }
+
+  auto char* append (const char *str, grub_size_t nchar);
+  char* append (const char *str, grub_size_t nchar)
+  {
+    int len;
+    int old;
+    char *p;
+
+    if (oom || !str)
+      return 0;
+
+    len = nchar ?: grub_strlen (str);
+    old = argv[argc - 1] ? grub_strlen (argv[argc - 1]) : 0;
+    p = grub_realloc (argv[argc - 1], ALIGN_UP(old + len + 1, ARG_ALLOCATION_UNIT));
+
+    if (p)
+      {
+       grub_strncpy (p + old, str, len);
+       p[old + len] = '\0';
+      }
+    else
+      {
+       oom = 1;
+       grub_free (argv[argc - 1]);
+      }
+    argv[argc - 1] = p;
+    return argv[argc - 1];
+  }
+
+  /* Move *STR to the begining of next word, but return current word.  */
+  auto char* move_to_next (char **str);
+  char* move_to_next (char **str)
+  {
+    char *end;
+    char *start;
+
+    if (oom || !str || !*str)
+      return 0;
+
+    start = *str;
+    while (*start && grub_isspace (*start)) start++;
+    if (*start == '\0')
+      return 0;
+
+    end = start + 1;
+    while (*end && !grub_isspace (*end)) end++;
+
+    *str = end;
+    return start;
+  }
+
+  oom = 0;
+  argv = 0;
+  argc = 0;
+  push (0);
+  for (; arglist; arglist = arglist->next)
+    {
+      empty = 1;
+      arg = arglist->arg;
+      while (arg)
+       {
+         switch (arg->type)
+           {
+           case GRUB_SCRIPT_ARG_TYPE_VAR:
+             value = grub_env_get (arg->str);
+             while (value && *value && (ptr = move_to_next(&value)))
+               {
+                 empty = 0;
+                 append (ptr, value - ptr);
+                 if (*value) push(0);
+               }
+             break;
+
+           case GRUB_SCRIPT_ARG_TYPE_TEXT:
+             if (grub_strlen (arg->str) > 0)
+               {
+                 empty = 0;
+                 append (arg->str, 0);
+               }
+             break;
+
+           case GRUB_SCRIPT_ARG_TYPE_DQSTR:
+           case GRUB_SCRIPT_ARG_TYPE_SQSTR:
+             empty = 0;
+             append (arg->str, 0);
+             break;
+
+           case GRUB_SCRIPT_ARG_TYPE_DQVAR:
+             empty = 0;
+             append (grub_env_get (arg->str), 0);
+             break;
+           }
+         arg = arg->next;
+       }
+      if (!empty)
+       push (0);
+    }
+
+  if (oom)
+    {
+      for (i = 0; i < argc; i++)
+       grub_free (argv[i]);
+      grub_free (argv);
+      argv = 0;
+    }
+
+  if (argv)
+    *count = argc - 1;
+
+  return argv;
+}
+
+/* Execute a single command line.  */
+grub_err_t
+grub_script_execute_cmdline (struct grub_script_cmd *cmd)
+{
+  struct grub_script_cmdline *cmdline = (struct grub_script_cmdline *) cmd;
+  char **args = 0;
+  int i = 0;
+  grub_command_t grubcmd;
+  grub_err_t ret = 0;
+  int argcount = 0;
+  grub_script_function_t func = 0;
+  char errnobuf[18];
+  char *cmdname;
+
+  /* Lookup the command.  */
+  args = grub_script_execute_arglist_to_argv (cmdline->arglist, &argcount);
+  if (!args)
+    return grub_errno;
+
+  cmdname = args[0];
+  grubcmd = grub_command_find (cmdname);
+  if (! grubcmd)
+    {
+      grub_errno = GRUB_ERR_NONE;
+
+      /* It's not a GRUB command, try all functions.  */
+      func = grub_script_function_find (cmdname);
+      if (! func)
+       {
+         /* As a last resort, try if it is an assignment.  */
+         char *assign = grub_strdup (cmdname);
+         char *eq = grub_strchr (assign, '=');
+
+         if (eq)
+           {
+             /* This was set because the command was not found.  */
+             grub_errno = GRUB_ERR_NONE;
+
+             /* Create two strings and set the variable.  */
+             *eq = '\0';
+             eq++;
+             grub_env_set (assign, eq);
+           }
+         grub_free (assign);
+
+         grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno);
+         grub_env_set ("?", errnobuf);
+
+         grub_print_error ();
+
+         return 0;
+       }
+    }
+
+  /* Execute the GRUB command or function.  */
+  if (grubcmd)
+    ret = (grubcmd->func) (grubcmd, argcount - 1, args + 1);
+  else
+    ret = grub_script_function_call (func, argcount - 1, args + 1);
+
+  /* Free arguments.  */
+  for (i = 0; i < argcount; i++)
+    grub_free (args[i]);
+  grub_free (args);
+
+  if (grub_errno == GRUB_ERR_TEST_FAILURE)
+    grub_errno = GRUB_ERR_NONE;
+
+  grub_print_error ();
+
+  grub_snprintf (errnobuf, sizeof (errnobuf), "%d", ret);
+  grub_env_set ("?", errnobuf);
+
+  return ret;
+}
+
+/* Execute a block of one or more commands.  */
+grub_err_t
+grub_script_execute_cmdblock (struct grub_script_cmd *cmd)
+{
+  int ret = 0;
+  struct grub_script_cmdblock *cmdblock = (struct grub_script_cmdblock *) cmd;
+
+  /* Loop over every command and execute it.  */
+  for (cmd = cmdblock->cmdlist; cmd; cmd = cmd->next)
+    ret = grub_script_execute_cmd (cmd);
+
+  return ret;
+}
+
+/* Execute an if statement.  */
+grub_err_t
+grub_script_execute_cmdif (struct grub_script_cmd *cmd)
+{
+  struct grub_script_cmdif *cmdif = (struct grub_script_cmdif *) cmd;
+  char *result;
+
+  /* Check if the commands results in a true or a false.  The value is
+     read from the env variable `?'.  */
+  grub_script_execute_cmd (cmdif->exec_to_evaluate);
+  result = grub_env_get ("?");
+
+  grub_errno = GRUB_ERR_NONE;
+
+  /* Execute the `if' or the `else' part depending on the value of
+     `?'.  */
+  if (result && ! grub_strcmp (result, "0"))
+    return grub_script_execute_cmd (cmdif->exec_on_true);
+  else
+    return grub_script_execute_cmd (cmdif->exec_on_false);
+}
+
+/* Execute a for statement.  */
+grub_err_t
+grub_script_execute_cmdfor (struct grub_script_cmd *cmd)
+{
+  int i;
+  int result;
+  char **args;
+  int argcount;
+  struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd;
+
+  args = grub_script_execute_arglist_to_argv (cmdfor->words, &argcount);
+  if (!args)
+    return grub_errno;
+
+  result = 0;
+  for (i = 0; i < argcount; i++)
+    {
+      grub_env_set (cmdfor->name->str, args[i]);
+      result = grub_script_execute_cmd (cmdfor->list);
+      grub_free (args[i]);
+    }
+
+  grub_free (args);
+  return result;
+}
+
+/* Execute a "while" or "until" command.  */
+grub_err_t
+grub_script_execute_cmdwhile (struct grub_script_cmd *cmd)
+{
+  int cond;
+  int result;
+  struct grub_script_cmdwhile *cmdwhile = (struct grub_script_cmdwhile *) cmd;
+
+  result = 0;
+  do {
+    cond = grub_script_execute_cmd (cmdwhile->cond);
+    if (cmdwhile->until ? !cond : cond)
+      break;
+
+    result = grub_script_execute_cmd (cmdwhile->list);
+  } while (1); /* XXX Put a check for ^C here */
+
+  return result;
+}
+
+/* Execute the menu entry generate statement.  */
+grub_err_t
+grub_script_execute_menuentry (struct grub_script_cmd *cmd)
+{
+  struct grub_script_cmd_menuentry *cmd_menuentry;
+  char **args = 0;
+  int argcount = 0;
+  int i = 0;
+
+  cmd_menuentry = (struct grub_script_cmd_menuentry *) cmd;
+
+  if (cmd_menuentry->arglist)
+    {
+      args = grub_script_execute_arglist_to_argv (cmd_menuentry->arglist, &argcount);
+      if (!args)
+       return grub_errno;
+    }
+
+  grub_normal_add_menu_entry (argcount, (const char **) args,
+                             cmd_menuentry->sourcecode);
+
+  /* Free arguments.  */
+  for (i = 0; i < argcount; i++)
+    grub_free (args[i]);
+  grub_free (args);
+
+  return grub_errno;
+}
+
+
+
+/* Execute any GRUB pre-parsed command or script.  */
+grub_err_t
+grub_script_execute (struct grub_script *script)
+{
+  if (script == 0)
+    return 0;
+
+  return grub_script_execute_cmd (script->cmd);
+}
+
diff --git a/grub-core/script/function.c b/grub-core/script/function.c
new file mode 100644 (file)
index 0000000..ded470c
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/script_sh.h>
+#include <grub/parser.h>
+#include <grub/mm.h>
+
+static grub_script_function_t grub_script_function_list;
+
+grub_script_function_t
+grub_script_function_create (struct grub_script_arg *functionname_arg,
+                            struct grub_script *cmd)
+{
+  grub_script_function_t func;
+  grub_script_function_t *p;
+
+  func = (grub_script_function_t) grub_malloc (sizeof (*func));
+  if (! func)
+    return 0;
+
+  func->name = grub_strdup (functionname_arg->str);
+  if (! func->name)
+    {
+      grub_free (func);
+      return 0;
+    }
+
+  func->func = cmd;
+
+  /* Keep the list sorted for simplicity.  */
+  p = &grub_script_function_list;
+  while (*p)
+    {
+      if (grub_strcmp ((*p)->name, func->name) >= 0)
+       break;
+
+      p = &((*p)->next);
+    }
+
+  /* If the function already exists, overwrite the old function.  */
+  if (*p && grub_strcmp ((*p)->name, func->name) == 0)
+    {
+      grub_script_function_t q;
+
+      q = *p;
+      grub_script_free (q->func);
+      q->func = cmd;
+      grub_free (func);
+      func = q;
+    }
+  else
+    {
+      func->next = *p;
+      *p = func;
+    }
+
+  return func;
+}
+
+void
+grub_script_function_remove (const char *name)
+{
+  grub_script_function_t *p, q;
+
+  for (p = &grub_script_function_list, q = *p; q; p = &(q->next), q = q->next)
+    if (grub_strcmp (name, q->name) == 0)
+      {
+        *p = q->next;
+       grub_free (q->name);
+       grub_script_free (q->func);
+        grub_free (q);
+        break;
+      }
+}
+
+grub_script_function_t
+grub_script_function_find (char *functionname)
+{
+  grub_script_function_t func;
+
+  for (func = grub_script_function_list; func; func = func->next)
+    if (grub_strcmp (functionname, func->name) == 0)
+      break;
+
+  if (! func)
+    grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%.20s'", functionname);
+
+  return func;
+}
+
+int
+grub_script_function_iterate (int (*iterate) (grub_script_function_t))
+{
+  grub_script_function_t func;
+
+  for (func = grub_script_function_list; func; func = func->next)
+    if (iterate (func))
+      return 1;
+
+  return 0;
+}
+
+int
+grub_script_function_call (grub_script_function_t func,
+                          int argc __attribute__((unused)),
+                          char **args __attribute__((unused)))
+{
+  /* XXX: Arguments are not supported yet.  */
+  return grub_script_execute (func->func);
+}
diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c
new file mode 100644 (file)
index 0000000..42a5703
--- /dev/null
@@ -0,0 +1,346 @@
+/* lexer.c - The scripting lexer.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/parser.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/script_sh.h>
+
+#include "grub_script.tab.h"
+#include "grub_script.yy.h"
+
+void
+grub_script_lexer_ref (struct grub_lexer_param *state)
+{
+  state->refs++;
+}
+
+void
+grub_script_lexer_deref (struct grub_lexer_param *state)
+{
+  state->refs--;
+}
+
+/* Start recording all characters passing through the lexer.  */
+void
+grub_script_lexer_record_start (struct grub_parser_param *parser)
+{
+  struct grub_lexer_param *lexer = parser->lexerstate;
+
+  lexer->record = 1;
+  lexer->recordpos = 0;
+  if (lexer->recording) /* reuse last record */
+    return;
+
+  lexer->recordlen = GRUB_LEXER_INITIAL_RECORD_SIZE;
+  lexer->recording = grub_malloc (lexer->recordlen);
+  if (!lexer->recording)
+    {
+      grub_script_yyerror (parser, 0);
+      lexer->record = 0;
+      lexer->recordlen = 0;
+    }
+}
+
+char *
+grub_script_lexer_record_stop (struct grub_parser_param *parser)
+{
+  char *ptr;
+  char *result;
+  struct grub_lexer_param *lexer = parser->lexerstate;
+
+  auto char *compact (char *start, char *end);
+  char *compact (char *start, char *end)
+  {
+    /* Delete '{' and '}' characters and whitespaces.  */
+    while (*start && grub_isspace (*start)) start++;
+    if (*start == '{') start++;
+    while (*start && grub_isspace (*start)) start++;
+
+    while (*end && grub_isspace (*end)) end--;
+    if (*end == '}') end--;
+    while (*end && grub_isspace (*end)) end--;
+    end[1] = '\0';
+
+    return start;
+  }
+
+  if (!lexer->record || !lexer->recording)
+    return 0;
+
+  /* XXX This is not necessary in BASH.  */
+
+  ptr = compact (lexer->recording, lexer->recording + lexer->recordpos - 1);
+  lexer->record = 0;
+  lexer->recordpos = 0;
+
+  /* This memory would be freed by, grub_script_free.  */
+  result = grub_script_malloc (parser, grub_strlen (ptr) + 1);
+  if (result)
+    grub_strcpy (result, ptr);
+
+  return result;
+}
+
+#define MAX(a,b) ((a) < (b) ? (b) : (a))
+
+/* Record STR if input recording is enabled.  */
+void
+grub_script_lexer_record (struct grub_parser_param *parser, char *str)
+{
+  int len;
+  char *old;
+  struct grub_lexer_param *lexer = parser->lexerstate;
+
+  if (!lexer->record)
+    return;
+
+  len = grub_strlen (str);
+  if (lexer->recordpos + len + 1 > lexer->recordlen)
+    {
+      old = lexer->recording;
+      lexer->recordlen = MAX (len, lexer->recordlen) * 2;
+      lexer->recording = grub_realloc (lexer->recording, lexer->recordlen);
+      if (!lexer->recording)
+       {
+         grub_free (old);
+         lexer->record = 0;
+         lexer->recordpos = 0;
+         lexer->recordlen /= 2;
+         grub_script_yyerror (parser, 0);
+         return;
+       }
+    }
+  grub_strcpy (lexer->recording + lexer->recordpos, str);
+  lexer->recordpos += len;
+}
+
+/* Append '\n' to SRC, before '\0'  */
+static char *
+append_newline (const char *src)
+{
+  char *line;
+  grub_size_t len;
+
+  len = grub_strlen (src);
+  line = grub_malloc (len + 2);
+  if (!line)
+    return 0;
+
+  grub_strcpy (line, src);
+
+  line[len] = '\n';
+  line[len + 1] = '\0';
+  return line;
+}
+
+/* Read next line of input if necessary, and set yyscanner buffers.  */
+int
+grub_script_lexer_yywrap (struct grub_parser_param *parserstate)
+{
+  int len;
+  char *line;
+  char *line2;
+  YY_BUFFER_STATE buffer;
+  struct grub_lexer_param *lexerstate = parserstate->lexerstate;
+
+  if (!lexerstate->refs)
+    return 0;
+
+  if (!lexerstate->getline)
+    {
+      grub_script_yyerror (parserstate, "unexpected end of file");
+      return 0;
+    }
+
+  line = 0;
+  buffer = 0;
+  lexerstate->getline (&line, 1);
+  if (!line)
+    {
+      grub_script_yyerror (parserstate, 0); /* XXX this could be for ^C case? */
+      return 0;
+    }
+
+  len = grub_strlen (line);
+  if (line[len - 1] == '\n')
+    {
+      buffer = yy_scan_string (line, lexerstate->yyscanner);
+    }
+  else
+    {
+      line2 = append_newline (line);
+      if (line2)
+       {
+         buffer = yy_scan_string (line2, lexerstate->yyscanner);
+         grub_free (line2);
+       }
+    }
+
+  grub_free (line);
+  if (!buffer)
+    {
+      grub_script_yyerror (parserstate, 0);
+      return 0;
+    }
+
+  return 1;
+}
+
+struct grub_lexer_param *
+grub_script_lexer_init (struct grub_parser_param *parser, char *script,
+                       grub_reader_getline_t getline)
+{
+  int len;
+  char *script2;
+  YY_BUFFER_STATE buffer;
+  struct grub_lexer_param *lexerstate;
+
+  lexerstate = grub_zalloc (sizeof (*lexerstate));
+  if (!lexerstate)
+    return 0;
+
+  lexerstate->size = GRUB_LEXER_INITIAL_TEXT_SIZE;
+  lexerstate->text = grub_malloc (lexerstate->size);
+  if (!lexerstate->text)
+    {
+      grub_free (lexerstate);
+      return 0;
+    }
+
+  lexerstate->getline = getline;       /* rest are all zeros already */
+  if (yylex_init (&lexerstate->yyscanner))
+    {
+      grub_free (lexerstate->text);
+      grub_free (lexerstate);
+      return 0;
+    }
+
+  buffer = 0;
+  script = script ? : "\n";
+  len = grub_strlen (script);
+
+  if (script[len - 1] == '\n')
+    {
+      buffer = yy_scan_string (script, lexerstate->yyscanner);
+    }
+  else
+    {
+      script2 = append_newline (script);
+      if (script2)
+       {
+         buffer = yy_scan_string (script2, lexerstate->yyscanner);
+         grub_free (script2);
+       }
+    }
+
+  if (!buffer)
+    {
+      yylex_destroy (lexerstate->yyscanner);
+      grub_free (lexerstate->yyscanner);
+
+      grub_free (lexerstate->text);
+      grub_free (lexerstate);
+      return 0;
+    }
+  yyset_extra (parser, lexerstate->yyscanner);
+
+  return lexerstate;
+}
+
+void
+grub_script_lexer_fini (struct grub_lexer_param *lexerstate)
+{
+  if (!lexerstate)
+    return;
+
+  yylex_destroy (lexerstate->yyscanner);
+
+  grub_free (lexerstate->recording);
+  grub_free (lexerstate->text);
+  grub_free (lexerstate);
+}
+
+int
+grub_script_yylex (union YYSTYPE *value,
+                  struct grub_parser_param *parserstate)
+{
+  char *str;
+  int token;
+  grub_script_arg_type_t type;
+  struct grub_lexer_param *lexerstate = parserstate->lexerstate;
+
+  value->arg = 0;
+  if (parserstate->err)
+    return GRUB_PARSER_TOKEN_BAD;
+
+  if (lexerstate->eof)
+    return GRUB_PARSER_TOKEN_EOF;
+
+  /* 
+   * Words with environment variables, like foo${bar}baz needs
+   * multiple tokens to be merged into a single grub_script_arg.  We
+   * use two variables to achieve this: lexerstate->merge_start and
+   * lexerstate->merge_end
+   */
+
+  lexerstate->merge_start = 0;
+  lexerstate->merge_end = 0;
+  do
+    {
+      /* Empty lexerstate->text.  */
+      lexerstate->used = 1;
+      lexerstate->text[0] = '\0';
+
+      token = yylex (value, lexerstate->yyscanner);
+      if (token == GRUB_PARSER_TOKEN_BAD)
+       break;
+
+      /* Merging feature uses lexerstate->text instead of yytext.  */
+      if (lexerstate->merge_start)
+       {
+         str = lexerstate->text;
+         type = lexerstate->type;
+       }
+      else
+       {
+         str = yyget_text (lexerstate->yyscanner);
+         type = GRUB_SCRIPT_ARG_TYPE_TEXT;
+       }
+      grub_dprintf("lexer", "token %u text [%s]\n", token, str);
+
+      value->arg = grub_script_arg_add (parserstate, value->arg, type, str);
+    }
+  while (lexerstate->merge_start && !lexerstate->merge_end);
+
+  if (!value->arg || parserstate->err)
+    return GRUB_PARSER_TOKEN_BAD;
+
+  return token;
+}
+
+void
+grub_script_yyerror (struct grub_parser_param *state, char const *err)
+{
+  if (err)
+    grub_error (GRUB_ERR_INVALID_COMMAND, err);
+
+  grub_print_error ();
+  state->err++;
+}
diff --git a/grub-core/script/main.c b/grub-core/script/main.c
new file mode 100644 (file)
index 0000000..b5159dc
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/parser.h>
+#include <grub/script_sh.h>
+
+static grub_err_t
+grub_normal_parse_line (char *line, grub_reader_getline_t getline)
+{
+  struct grub_script *parsed_script;
+
+  /* Parse the script.  */
+  parsed_script = grub_script_parse (line, getline);
+
+  if (parsed_script)
+    {
+      /* Execute the command(s).  */
+      grub_script_execute (parsed_script);
+
+      /* The parsed script was executed, throw it away.  */
+      grub_script_free (parsed_script);
+    }
+
+  return grub_errno;
+}
+
+static struct grub_parser grub_sh_parser =
+  {
+    .name = "grub",
+    .parse_line = grub_normal_parse_line
+  };
+
+GRUB_MOD_INIT(sh)
+{
+  grub_parser_register ("grub", &grub_sh_parser);
+}
+
+GRUB_MOD_FINI(sh)
+{
+  grub_parser_unregister (&grub_sh_parser);
+}
diff --git a/grub-core/script/parser.y b/grub-core/script/parser.y
new file mode 100644 (file)
index 0000000..b5815ea
--- /dev/null
@@ -0,0 +1,286 @@
+/* parser.y - The scripting parser.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+%{
+#include <grub/script_sh.h>
+#include <grub/mm.h>
+
+#define YYFREE          grub_free
+#define YYMALLOC        grub_malloc
+#define YYLTYPE_IS_TRIVIAL      0
+#define YYENABLE_NLS    0
+
+%}
+
+%union {
+  struct grub_script_cmd *cmd;
+  struct grub_script_arglist *arglist;
+  struct grub_script_arg *arg;
+  char *string;
+}
+
+%token GRUB_PARSER_TOKEN_BAD
+%token GRUB_PARSER_TOKEN_EOF 0 "end-of-input"
+
+%token GRUB_PARSER_TOKEN_NEWLINE "\n"
+%token GRUB_PARSER_TOKEN_AND     "&&"
+%token GRUB_PARSER_TOKEN_OR      "||"
+%token GRUB_PARSER_TOKEN_SEMI2   ";;"
+%token GRUB_PARSER_TOKEN_PIPE    "|"
+%token GRUB_PARSER_TOKEN_AMP     "&"
+%token GRUB_PARSER_TOKEN_SEMI    ";"
+%token GRUB_PARSER_TOKEN_LBR     "{"
+%token GRUB_PARSER_TOKEN_RBR     "}"
+%token GRUB_PARSER_TOKEN_NOT     "!"
+%token GRUB_PARSER_TOKEN_LSQBR2  "["
+%token GRUB_PARSER_TOKEN_RSQBR2  "]"
+%token GRUB_PARSER_TOKEN_LT      "<"
+%token GRUB_PARSER_TOKEN_GT      ">"
+
+%token <arg> GRUB_PARSER_TOKEN_CASE      "case"
+%token <arg> GRUB_PARSER_TOKEN_DO        "do"
+%token <arg> GRUB_PARSER_TOKEN_DONE      "done"
+%token <arg> GRUB_PARSER_TOKEN_ELIF      "elif"
+%token <arg> GRUB_PARSER_TOKEN_ELSE      "else"
+%token <arg> GRUB_PARSER_TOKEN_ESAC      "esac"
+%token <arg> GRUB_PARSER_TOKEN_FI        "fi"
+%token <arg> GRUB_PARSER_TOKEN_FOR       "for"
+%token <arg> GRUB_PARSER_TOKEN_IF        "if"
+%token <arg> GRUB_PARSER_TOKEN_IN        "in"
+%token <arg> GRUB_PARSER_TOKEN_SELECT    "select"
+%token <arg> GRUB_PARSER_TOKEN_THEN      "then"
+%token <arg> GRUB_PARSER_TOKEN_UNTIL     "until"
+%token <arg> GRUB_PARSER_TOKEN_WHILE     "while"
+%token <arg> GRUB_PARSER_TOKEN_TIME      "time"
+%token <arg> GRUB_PARSER_TOKEN_FUNCTION  "function"
+%token <arg> GRUB_PARSER_TOKEN_MENUENTRY "menuentry"
+%token <arg> GRUB_PARSER_TOKEN_NAME      "name"
+%token <arg> GRUB_PARSER_TOKEN_WORD      "word"
+
+%type <arglist> word argument arguments0 arguments1
+
+%type <cmd> script_init script
+%type <cmd> grubcmd ifclause ifcmd forcmd whilecmd untilcmd
+%type <cmd> command commands1 menuentry statement
+
+%pure-parser
+%lex-param   { struct grub_parser_param *state };
+%parse-param { struct grub_parser_param *state };
+
+%start script_init
+
+%%
+/* It should be possible to do this in a clean way...  */
+script_init: { state->err = 0; } script { state->parsed = $2; state->err = 0; }
+;
+
+script: newlines0
+        {
+          $$ = 0;
+        }
+      | script statement delimiter newlines0
+        {
+          struct grub_script_cmdblock *cmdblock;
+          cmdblock = (struct grub_script_cmdblock *) $1;
+          $$ = grub_script_add_cmd (state, cmdblock, $2);
+        }
+      | error
+        {
+          $$ = 0;
+          yyerror (state, "Incorrect command");
+          yyerrok;
+        }
+;
+
+newlines0: /* Empty */ | newlines1 ;
+newlines1: newlines0 "\n" ;
+
+delimiter: ";"
+         | "\n"
+;
+delimiters0: /* Empty */ | delimiters1 ;
+delimiters1: delimiter
+          | delimiters1 "\n"
+;
+
+word: GRUB_PARSER_TOKEN_NAME { $$ = grub_script_add_arglist (state, 0, $1); }
+    | GRUB_PARSER_TOKEN_WORD { $$ = grub_script_add_arglist (state, 0, $1); }
+;
+
+statement: command   { $$ = $1; }
+         | function  { $$ = 0;  }
+         | menuentry { $$ = $1; }
+
+argument : "case"      { $$ = grub_script_add_arglist (state, 0, $1); }
+         | "do"        { $$ = grub_script_add_arglist (state, 0, $1); }
+         | "done"      { $$ = grub_script_add_arglist (state, 0, $1); }
+         | "elif"      { $$ = grub_script_add_arglist (state, 0, $1); }
+         | "else"      { $$ = grub_script_add_arglist (state, 0, $1); }
+         | "esac"      { $$ = grub_script_add_arglist (state, 0, $1); }
+         | "fi"        { $$ = grub_script_add_arglist (state, 0, $1); }
+         | "for"       { $$ = grub_script_add_arglist (state, 0, $1); }
+         | "if"        { $$ = grub_script_add_arglist (state, 0, $1); }
+         | "in"        { $$ = grub_script_add_arglist (state, 0, $1); }
+         | "select"    { $$ = grub_script_add_arglist (state, 0, $1); }
+         | "then"      { $$ = grub_script_add_arglist (state, 0, $1); }
+         | "until"     { $$ = grub_script_add_arglist (state, 0, $1); }
+         | "while"     { $$ = grub_script_add_arglist (state, 0, $1); }
+         | "function"  { $$ = grub_script_add_arglist (state, 0, $1); }
+         | "menuentry" { $$ = grub_script_add_arglist (state, 0, $1); }
+         | word { $$ = $1; }
+;
+
+arguments0: /* Empty */ { $$ = 0; }
+          | arguments1  { $$ = $1; }
+;
+arguments1: argument arguments0
+            {
+             if ($1 && $2)
+               {
+                 $1->next = $2;
+                 $1->argcount += $2->argcount;
+                 $2->argcount = 0;
+               }
+             $$ = $1;
+            }
+;
+
+grubcmd: word arguments0
+         {
+           if ($1 && $2) {
+             $1->next = $2;
+             $1->argcount += $2->argcount;
+             $2->argcount = 0;
+           }
+           $$ = grub_script_create_cmdline (state, $1);
+         }
+;
+
+/* A single command.  */
+command: grubcmd  { $$ = $1; }
+       | ifcmd    { $$ = $1; }
+       | forcmd   { $$ = $1; }
+       | whilecmd { $$ = $1; }
+       | untilcmd { $$ = $1; }
+;
+
+/* A list of commands. */
+commands1: newlines0 command
+           {
+             $$ = grub_script_add_cmd (state, 0, $2);
+           }
+         | commands1 delimiters1 command
+           {
+             struct grub_script_cmdblock *cmdblock;
+            cmdblock = (struct grub_script_cmdblock *) $1;
+            $$ = grub_script_add_cmd (state, cmdblock, $3);
+           }
+;
+
+function: "function" "name" 
+          {
+            grub_script_lexer_ref (state->lexerstate);
+            state->func_mem = grub_script_mem_record (state);
+          }
+          delimiters0 "{" commands1 delimiters1 "}"
+          {
+            struct grub_script *script;
+            state->func_mem = grub_script_mem_record_stop (state,
+                                                           state->func_mem);
+            script = grub_script_create ($6, state->func_mem);
+            if (script)
+              grub_script_function_create ($2, script);
+
+            grub_script_lexer_deref (state->lexerstate);
+          }
+;
+
+menuentry: "menuentry"
+           {
+             grub_script_lexer_ref (state->lexerstate);
+           }
+           arguments1
+           {
+             grub_script_lexer_record_start (state);
+           }
+           delimiters0 "{" commands1 delimiters1 "}"
+           {
+             char *menu_entry;
+             menu_entry = grub_script_lexer_record_stop (state);
+             grub_script_lexer_deref (state->lexerstate);
+             $$ = grub_script_create_cmdmenu (state, $3, menu_entry, 0);
+           }
+;
+
+ifcmd: "if"
+       {
+         grub_script_lexer_ref (state->lexerstate);
+       }
+       ifclause "fi"
+       {
+         $$ = $3;
+         grub_script_lexer_deref (state->lexerstate);
+       }
+;
+ifclause: commands1 delimiters1 "then" commands1 delimiters1
+         {
+           $$ = grub_script_create_cmdif (state, $1, $4, 0);
+         }
+       | commands1 delimiters1 "then" commands1 delimiters1 "else" commands1 delimiters1
+         {
+           $$ = grub_script_create_cmdif (state, $1, $4, $7);
+         }
+       | commands1 delimiters1 "then" commands1 delimiters1 "elif" ifclause
+         {
+           $$ = grub_script_create_cmdif (state, $1, $4, $7);
+         }
+;
+
+forcmd: "for" "name"
+        {
+         grub_script_lexer_ref (state->lexerstate);
+        }
+        "in" arguments0 delimiters1 "do" commands1 delimiters1 "done"
+       {
+         $$ = grub_script_create_cmdfor (state, $2, $5, $8);
+         grub_script_lexer_deref (state->lexerstate);
+       }
+;
+
+whilecmd: "while"
+          {
+           grub_script_lexer_ref (state->lexerstate);
+          }
+          commands1 delimiters1 "do" commands1 delimiters1 "done"
+         {
+           $$ = grub_script_create_cmdwhile (state, $3, $6, 0);
+           grub_script_lexer_deref (state->lexerstate);
+         }
+;
+
+untilcmd: "until"
+          {
+           grub_script_lexer_ref (state->lexerstate);
+          }
+          commands1 delimiters1 "do" commands1 delimiters1 "done"
+         {
+           $$ = grub_script_create_cmdwhile (state, $3, $6, 1);
+           grub_script_lexer_deref (state->lexerstate);
+         }
+;
diff --git a/grub-core/script/script.c b/grub-core/script/script.c
new file mode 100644 (file)
index 0000000..4c87d94
--- /dev/null
@@ -0,0 +1,407 @@
+/* script.c -- Functions to create an in memory description of the script. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/script_sh.h>
+#include <grub/parser.h>
+#include <grub/mm.h>
+
+/* It is not possible to deallocate the memory when a syntax error was
+   found.  Because of that it is required to keep track of all memory
+   allocations.  The memory is freed in case of an error, or assigned
+   to the parsed script when parsing was successful.
+
+   In case of the normal malloc, some additional bytes are allocated
+   for this datastructure.  All reserved memory is stored in a linked
+   list so it can be easily freed.  The original memory can be found
+   from &mem.  */
+struct grub_script_mem
+{
+  struct grub_script_mem *next;
+  char mem;
+};
+
+/* Return malloc'ed memory and keep track of the allocation.  */
+void *
+grub_script_malloc (struct grub_parser_param *state, grub_size_t size)
+{
+  struct grub_script_mem *mem;
+  mem = (struct grub_script_mem *) grub_malloc (size + sizeof (*mem)
+                                               - sizeof (char));
+  if (!mem)
+    return 0;
+
+  grub_dprintf ("scripting", "malloc %p\n", mem);
+  mem->next = state->memused;
+  state->memused = mem;
+  return (void *) &mem->mem;
+}
+
+/* Free all memory described by MEM.  */
+static void
+grub_script_mem_free (struct grub_script_mem *mem)
+{
+  struct grub_script_mem *memfree;
+
+  while (mem)
+    {
+      memfree = mem->next;
+      grub_dprintf ("scripting", "free %p\n", mem);
+      grub_free (mem);
+      mem = memfree;
+    }
+}
+
+/* Start recording memory usage.  Returns the memory that should be
+   restored when calling stop.  */
+struct grub_script_mem *
+grub_script_mem_record (struct grub_parser_param *state)
+{
+  struct grub_script_mem *mem = state->memused;
+  state->memused = 0;
+
+  return mem;
+}
+
+/* Stop recording memory usage.  Restore previous recordings using
+   RESTORE.  Return the recorded memory.  */
+struct grub_script_mem *
+grub_script_mem_record_stop (struct grub_parser_param *state,
+                            struct grub_script_mem *restore)
+{
+  struct grub_script_mem *mem = state->memused;
+  state->memused = restore;
+  return mem;
+}
+
+/* Free the memory reserved for CMD and all of it's children.  */
+void
+grub_script_free (struct grub_script *script)
+{
+  if (!script)
+    return;
+  grub_script_mem_free (script->mem);
+  grub_free (script);
+}
+\f
+
+
+/* Extend the argument arg with a variable or string of text.  If ARG
+   is zero a new list is created.  */
+struct grub_script_arg *
+grub_script_arg_add (struct grub_parser_param *state,
+                    struct grub_script_arg *arg, grub_script_arg_type_t type,
+                    char *str)
+{
+  struct grub_script_arg *argpart;
+  struct grub_script_arg *ll;
+  int len;
+
+  argpart =
+    (struct grub_script_arg *) grub_script_malloc (state, sizeof (*arg));
+  if (!argpart)
+    return arg;
+
+  argpart->type = type;
+  len = grub_strlen (str) + 1;
+  argpart->str = grub_script_malloc (state, len);
+  if (!argpart->str)
+    return arg; /* argpart is freed later, during grub_script_free.  */
+
+  grub_memcpy (argpart->str, str, len);
+  argpart->next = 0;
+
+  if (!arg)
+    return argpart;
+
+  for (ll = arg; ll->next; ll = ll->next);
+  ll->next = argpart;
+
+  return arg;
+}
+
+/* Add the argument ARG to the end of the argument list LIST.  If LIST
+   is zero, a new list will be created.  */
+struct grub_script_arglist *
+grub_script_add_arglist (struct grub_parser_param *state,
+                        struct grub_script_arglist *list,
+                        struct grub_script_arg *arg)
+{
+  struct grub_script_arglist *link;
+  struct grub_script_arglist *ll;
+
+  grub_dprintf ("scripting", "arglist\n");
+
+  link =
+    (struct grub_script_arglist *) grub_script_malloc (state, sizeof (*link));
+  if (!link)
+    return list;
+
+  link->next = 0;
+  link->arg = arg;
+  link->argcount = 0;
+
+  if (!list)
+    {
+      link->argcount++;
+      return link;
+    }
+
+  list->argcount++;
+
+  /* Look up the last link in the chain.  */
+  for (ll = list; ll->next; ll = ll->next);
+  ll->next = link;
+
+  return list;
+}
+
+/* Create a command that describes a single command line.  CMDLINE
+   contains the name of the command that should be executed.  ARGLIST
+   holds all arguments for this command.  */
+struct grub_script_cmd *
+grub_script_create_cmdline (struct grub_parser_param *state,
+                           struct grub_script_arglist *arglist)
+{
+  struct grub_script_cmdline *cmd;
+
+  grub_dprintf ("scripting", "cmdline\n");
+
+  cmd = grub_script_malloc (state, sizeof (*cmd));
+  if (!cmd)
+    return 0;
+
+  cmd->cmd.exec = grub_script_execute_cmdline;
+  cmd->cmd.next = 0;
+  cmd->arglist = arglist;
+
+  return (struct grub_script_cmd *) cmd;
+}
+
+/* Create a command that functions as an if statement.  If BOOL is
+   evaluated to true (the value is returned in envvar '?'), the
+   interpreter will run the command TRUE, otherwise the interpreter
+   runs the command FALSE.  */
+struct grub_script_cmd *
+grub_script_create_cmdif (struct grub_parser_param *state,
+                         struct grub_script_cmd *exec_to_evaluate,
+                         struct grub_script_cmd *exec_on_true,
+                         struct grub_script_cmd *exec_on_false)
+{
+  struct grub_script_cmdif *cmd;
+
+  grub_dprintf ("scripting", "cmdif\n");
+
+  cmd = grub_script_malloc (state, sizeof (*cmd));
+  if (!cmd)
+    return 0;
+
+  cmd->cmd.exec = grub_script_execute_cmdif;
+  cmd->cmd.next = 0;
+  cmd->exec_to_evaluate = exec_to_evaluate;
+  cmd->exec_on_true = exec_on_true;
+  cmd->exec_on_false = exec_on_false;
+
+  return (struct grub_script_cmd *) cmd;
+}
+
+/* Create a command that functions as a for statement.  */
+struct grub_script_cmd *
+grub_script_create_cmdfor (struct grub_parser_param *state,
+                          struct grub_script_arg *name,
+                          struct grub_script_arglist *words,
+                          struct grub_script_cmd *list)
+{
+  struct grub_script_cmdfor *cmd;
+
+  grub_dprintf ("scripting", "cmdfor\n");
+
+  cmd = grub_script_malloc (state, sizeof (*cmd));
+  if (! cmd)
+    return 0;
+
+  cmd->cmd.exec = grub_script_execute_cmdfor;
+  cmd->cmd.next = 0;
+  cmd->name = name;
+  cmd->words = words;
+  cmd->list = list;
+
+  return (struct grub_script_cmd *) cmd;
+}
+
+/* Create a "while" or "until" command.  */
+struct grub_script_cmd *
+grub_script_create_cmdwhile (struct grub_parser_param *state,
+                            struct grub_script_cmd *cond,
+                            struct grub_script_cmd *list,
+                            int is_an_until_loop)
+{
+  struct grub_script_cmdwhile *cmd;
+
+  cmd = grub_script_malloc (state, sizeof (*cmd));
+  if (! cmd)
+    return 0;
+
+  cmd->cmd.exec = grub_script_execute_cmdwhile;
+  cmd->cmd.next = 0;
+  cmd->cond = cond;
+  cmd->list = list;
+  cmd->until = is_an_until_loop;
+
+  return (struct grub_script_cmd *) cmd;
+}
+
+/* Create a command that adds a menu entry to the menu.  Title is an
+   argument that is parsed to generate a string that can be used as
+   the title.  The sourcecode for this entry is passed in SOURCECODE.
+   The options for this entry are passed in OPTIONS.  */
+struct grub_script_cmd *
+grub_script_create_cmdmenu (struct grub_parser_param *state,
+                           struct grub_script_arglist *arglist,
+                           char *sourcecode, int options)
+{
+  struct grub_script_cmd_menuentry *cmd;
+
+  cmd = grub_script_malloc (state, sizeof (*cmd));
+  if (!cmd)
+    return 0;
+    
+  cmd->cmd.exec = grub_script_execute_menuentry;
+  cmd->cmd.next = 0;
+  cmd->sourcecode = sourcecode;
+  cmd->arglist = arglist;
+  cmd->options = options;
+
+  return (struct grub_script_cmd *) cmd;
+}
+
+/* Create a block of commands.  CMD contains the command that should
+   be added at the end of CMDBLOCK's list.  If CMDBLOCK is zero, a new
+   cmdblock will be created.  */
+struct grub_script_cmd *
+grub_script_add_cmd (struct grub_parser_param *state,
+                    struct grub_script_cmdblock *cmdblock,
+                    struct grub_script_cmd *cmd)
+{
+  struct grub_script_cmd *ptr;
+
+  grub_dprintf ("scripting", "cmdblock\n");
+
+  if (!cmd)
+    return (struct grub_script_cmd *) cmdblock;
+
+  if (!cmdblock)
+    {
+      cmdblock = grub_script_malloc (state, sizeof (*cmdblock));
+      if (!cmdblock)
+       return 0;
+
+      cmdblock->cmd.exec = grub_script_execute_cmdblock;
+      cmdblock->cmd.next = 0;
+      cmdblock->cmdlist = cmd;
+      cmd->next = 0;
+    }
+  else
+    {
+      if (!cmdblock->cmdlist)
+       cmdblock->cmdlist = cmd;
+      else
+       {
+         ptr = cmdblock->cmdlist;
+         while (ptr->next)
+           ptr = ptr->next;
+         ptr->next = cmd;
+       }
+    }
+
+  return (struct grub_script_cmd *) cmdblock;
+}
+\f
+
+
+struct grub_script *
+grub_script_create (struct grub_script_cmd *cmd, struct grub_script_mem *mem)
+{
+  struct grub_script *parsed;
+
+  parsed = grub_malloc (sizeof (*parsed));
+  if (!parsed)
+    {
+      grub_script_mem_free (mem);
+      grub_free (cmd);
+
+      return 0;
+    }
+
+  parsed->mem = mem;
+  parsed->cmd = cmd;
+
+  return parsed;
+}
+
+/* Parse the script passed in SCRIPT and return the parsed
+   datastructure that is ready to be interpreted.  */
+struct grub_script *
+grub_script_parse (char *script, grub_reader_getline_t getline)
+{
+  struct grub_script *parsed;
+  struct grub_script_mem *membackup;
+  struct grub_lexer_param *lexstate;
+  struct grub_parser_param *parsestate;
+
+  parsed = grub_malloc (sizeof (*parsed));
+  if (!parsed)
+    return 0;
+
+  parsestate = grub_zalloc (sizeof (*parsestate));
+  if (!parsestate)
+    return 0;
+
+  /* Initialize the lexer.  */
+  lexstate = grub_script_lexer_init (parsestate, script, getline);
+  if (!lexstate)
+    {
+      grub_free (parsed);
+      grub_free (parsestate);
+      return 0;
+    }
+
+  parsestate->lexerstate = lexstate;
+
+  membackup = grub_script_mem_record (parsestate);
+
+  /* Parse the script.  */
+  if (grub_script_yyparse (parsestate) || parsestate->err)
+    {
+      struct grub_script_mem *memfree;
+      memfree = grub_script_mem_record_stop (parsestate, membackup);
+      grub_script_mem_free (memfree);
+      grub_script_lexer_fini (lexstate);
+      grub_free (parsestate);
+      return 0;
+    }
+
+  parsed->mem = grub_script_mem_record_stop (parsestate, membackup);
+  parsed->cmd = parsestate->parsed;
+
+  grub_script_lexer_fini (lexstate);
+  grub_free (parsestate);
+
+  return parsed;
+}
diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l
new file mode 100644 (file)
index 0000000..7d4ea9e
--- /dev/null
@@ -0,0 +1,327 @@
+%{
+/* yylex.l  The scripting lexer.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/parser.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/script_sh.h>
+#include "grub_script.tab.h"
+
+#define yyfree    grub_lexer_yyfree
+#define yyalloc   grub_lexer_yyalloc
+#define yyrealloc grub_lexer_yyrealloc
+
+/* 
+ * As we don't have access to yyscanner, we cannot do much except to
+ * print the fatal error.
+ */
+#define YY_FATAL_ERROR(msg)                     \
+  do {                                          \
+    grub_printf ("fatal error: %s\n", msg);     \
+  } while (0)
+
+#define COPY(str, hint)                         \
+  do {                                          \
+    copy_string (yyextra, str, hint);           \
+  } while (0)
+
+
+#define RECORD                                  \
+  do {                                          \
+    grub_script_lexer_record (yyextra, yytext); \
+  } while (0)
+
+#define ARG(t)                        \
+  do {                                \
+    yyextra->lexerstate->type = t;    \
+    return GRUB_PARSER_TOKEN_WORD;    \
+  } while (0)
+
+/* We don't need YY_INPUT, as we rely on yy_scan_strings */
+#define YY_INPUT(buf,res,max) do { res = 0; } while (0)
+
+/* forward declarations */
+static void  grub_lexer_yyfree (void *, yyscan_t yyscanner);
+static void* grub_lexer_yyalloc (yy_size_t, yyscan_t yyscanner);
+static void* grub_lexer_yyrealloc (void*, yy_size_t, yyscan_t yyscanner);
+static void  copy_string (struct grub_parser_param *, const char *,
+                          unsigned hint);
+
+%}
+
+%top{
+
+#include <sys/types.h>
+
+typedef size_t yy_size_t;
+#define YY_TYPEDEF_YY_SIZE_T 1
+
+/* 
+ * Some flex hacks for -nostdinc; XXX We need to fix these when libc
+ * support becomes availble in GRUB.
+ */
+
+#ifndef GRUB_UTIL
+#define stdin  0
+#define stdout 0
+
+#define fprintf(...) 0
+#define exit(...)
+#endif
+
+}
+
+%option ecs
+%option meta-ecs
+
+%option warn
+%option array
+%option stack
+%option reentrant
+%option bison-bridge
+%option never-interactive
+
+%option noyyfree noyyalloc noyyrealloc
+%option nounistd nostdinit nodefault noyylineno noyywrap
+
+/* Reduce lexer size, by not defining these.  */
+%option noyy_top_state
+%option noinput nounput
+%option noyyget_in noyyset_in
+%option noyyget_out noyyset_out
+%option noyyget_debug noyyset_debug
+%option noyyget_lineno noyyset_lineno
+
+%option extra-type="struct grub_parser_param*"
+
+BLANK           [ \t]
+COMMENT         #.*$
+
+CHAR            [^{}|&$;<> \t\n\'\"\\]
+DIGITS          [[:digit:]]+
+NAME            [[:alpha:]_][[:alnum:][:digit:]_]*
+
+ESC             \\.
+VARIABLE        ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|$\?|$\{\?\}
+DQSTR           \"([^\\\"]|{ESC})*\"
+SQSTR           \'[^\']*\'
+WORD            ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+
+
+%x              SPLIT
+%x              DQUOTE
+%x              SQUOTE
+%x              VAR
+
+%%
+
+ /* White spaces */
+{BLANK}+        { RECORD; }
+{COMMENT}       { RECORD; }
+
+ /* Special symbols */
+"\n"            { RECORD; return GRUB_PARSER_TOKEN_NEWLINE; }
+"||"            { RECORD; return GRUB_PARSER_TOKEN_OR;      }
+"&&"            { RECORD; return GRUB_PARSER_TOKEN_AND;     }
+";;"            { RECORD; return GRUB_PARSER_TOKEN_SEMI2;   }
+"|"             { RECORD; return GRUB_PARSER_TOKEN_PIPE;    }
+"&"             { RECORD; return GRUB_PARSER_TOKEN_AMP;     }
+";"             { RECORD; return GRUB_PARSER_TOKEN_SEMI;    }
+"<"             { RECORD; return GRUB_PARSER_TOKEN_LT;      }
+">"             { RECORD; return GRUB_PARSER_TOKEN_GT;      }
+
+ /* Reserved words */
+"!"             { RECORD; return GRUB_PARSER_TOKEN_NOT;       }
+"{"             { RECORD; return GRUB_PARSER_TOKEN_LBR;       }
+"}"             { RECORD; return GRUB_PARSER_TOKEN_RBR;       }
+"[["            { RECORD; return GRUB_PARSER_TOKEN_RSQBR2;    }
+"]]"            { RECORD; return GRUB_PARSER_TOKEN_LSQBR2;    }
+"time"          { RECORD; return GRUB_PARSER_TOKEN_TIME;      }
+"case"          { RECORD; return GRUB_PARSER_TOKEN_CASE;      }
+"do"            { RECORD; return GRUB_PARSER_TOKEN_DO;        }
+"done"          { RECORD; return GRUB_PARSER_TOKEN_DONE;      }
+"elif"          { RECORD; return GRUB_PARSER_TOKEN_ELIF;      }
+"else"          { RECORD; return GRUB_PARSER_TOKEN_ELSE;      }
+"esac"          { RECORD; return GRUB_PARSER_TOKEN_ESAC;      }
+"fi"            { RECORD; return GRUB_PARSER_TOKEN_FI;        }
+"for"           { RECORD; return GRUB_PARSER_TOKEN_FOR;       }
+"if"            { RECORD; return GRUB_PARSER_TOKEN_IF;        }
+"in"            { RECORD; return GRUB_PARSER_TOKEN_IN;        }
+"select"        { RECORD; return GRUB_PARSER_TOKEN_SELECT;    }
+"then"          { RECORD; return GRUB_PARSER_TOKEN_THEN;      }
+"until"         { RECORD; return GRUB_PARSER_TOKEN_UNTIL;     }
+"while"         { RECORD; return GRUB_PARSER_TOKEN_WHILE;     }
+"function"      { RECORD; return GRUB_PARSER_TOKEN_FUNCTION;  }
+"menuentry"     { RECORD; return GRUB_PARSER_TOKEN_MENUENTRY; }
+
+{NAME}          { RECORD; return GRUB_PARSER_TOKEN_NAME; }
+{WORD}          {
+                  RECORD;
+                  /* resplit yytext */
+                 grub_dprintf ("lexer", "word: [%s]\n", yytext);
+                  yypush_buffer_state (YY_CURRENT_BUFFER, yyscanner);
+                  if (yy_scan_string (yytext, yyscanner))
+                    {
+                      yyextra->lexerstate->merge_start = 1;
+                      yy_push_state (SPLIT, yyscanner);
+                    }
+                  else
+                    {
+                      grub_script_yyerror (yyextra, 0);
+                      yypop_buffer_state (yyscanner);
+                      return GRUB_PARSER_TOKEN_WORD;
+                    }
+                }
+
+.|\n            {
+                  grub_script_yyerror (yyextra, "unrecognized token");
+                  return GRUB_PARSER_TOKEN_BAD;
+                }
+
+ /* Split word into multiple args */
+
+<SPLIT>{
+  \\.           { COPY (yytext + 1, yyleng - 1); }
+  \"            {
+                  yy_push_state (DQUOTE, yyscanner);
+                  ARG (GRUB_SCRIPT_ARG_TYPE_TEXT);
+                }
+  \'            {
+                  yy_push_state (SQUOTE, yyscanner);
+                  ARG (GRUB_SCRIPT_ARG_TYPE_TEXT);
+                }
+  \$            {
+                  yy_push_state (VAR, yyscanner);
+                  ARG (GRUB_SCRIPT_ARG_TYPE_TEXT);
+                }
+  \\            |
+  [^\"\'\$\\]+  { COPY (yytext, yyleng); }
+  <<EOF>>       {
+                  yy_pop_state (yyscanner);
+                  yypop_buffer_state (yyscanner);
+                  yyextra->lexerstate->merge_end = 1;
+                  ARG (GRUB_SCRIPT_ARG_TYPE_TEXT);
+                }
+}
+
+<VAR>{
+  \?            |
+  {DIGITS}      |
+  {NAME}        {
+                  COPY (yytext, yyleng);
+                  yy_pop_state (yyscanner);
+                  if (YY_START == SPLIT)
+                    ARG (GRUB_SCRIPT_ARG_TYPE_VAR);
+                  else
+                    ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR);
+                }
+  \{\?\}        |
+  \{{DIGITS}\}  |
+  \{{NAME}\}    {
+                  yytext[yyleng - 1] = '\0';
+                  COPY (yytext + 1, yyleng - 2);
+                  yy_pop_state (yyscanner);
+                  if (YY_START == SPLIT)
+                    ARG (GRUB_SCRIPT_ARG_TYPE_VAR);
+                  else
+                    ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR);
+                }
+  .|\n          { return GRUB_PARSER_TOKEN_BAD; }
+}
+
+<SQUOTE>{
+  \'            {
+                  yy_pop_state (yyscanner);
+                  ARG (GRUB_SCRIPT_ARG_TYPE_SQSTR);
+                }
+  [^\']+        { COPY (yytext, yyleng); }
+}
+
+<DQUOTE>{
+  \\\$          { COPY ("$", 1); }
+  \\\\          { COPY ("\\", 1); }
+  \\\"          { COPY ("\"", 1); }
+  \\\n          { /* ignore */ }
+  [^\"\$\\\n]+  { COPY (yytext, yyleng); }
+  \"            {
+                  yy_pop_state (yyscanner);
+                  ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR);
+                }
+  \$            {
+                  yy_push_state (VAR, yyscanner);
+                  ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR);
+                }
+  (.|\n)        { COPY (yytext, yyleng); }
+}
+
+<<EOF>>         {
+                  yypop_buffer_state (yyscanner);
+                  if (! grub_script_lexer_yywrap (yyextra))
+                    {
+                      yyextra->lexerstate->eof = 1;
+                      return GRUB_PARSER_TOKEN_EOF;
+                    }
+                }
+
+%%
+
+static void
+grub_lexer_yyfree (void *ptr, yyscan_t yyscanner __attribute__ ((unused)))
+{
+  grub_free(ptr);
+}
+
+static void*
+grub_lexer_yyalloc (yy_size_t size, yyscan_t yyscanner __attribute__ ((unused)))
+{
+  return grub_malloc (size);
+}
+
+static void*
+grub_lexer_yyrealloc (void *ptr, yy_size_t size,
+                      yyscan_t yyscanner __attribute__ ((unused)))
+{
+  return grub_realloc (ptr, size);
+}
+
+#define MAX(a,b) ((a) < (b) ? (b) : (a))
+
+static void copy_string (struct grub_parser_param *parser, const char *str, unsigned hint)
+{
+  int size;
+  char *ptr;
+  unsigned len;
+
+  len = hint ? hint : grub_strlen (str);
+  if (parser->lexerstate->used + len >= parser->lexerstate->size)
+    {
+      size = MAX (len, parser->lexerstate->size) * 2;
+      ptr = grub_realloc (parser->lexerstate->text, size);
+      if (!ptr)
+        {
+          grub_script_yyerror (parser, 0);
+          return;
+        }
+
+      parser->lexerstate->text = ptr;
+      parser->lexerstate->size = size;
+    }
+  grub_strcpy (parser->lexerstate->text + parser->lexerstate->used - 1, str);
+  parser->lexerstate->used += len;
+}
diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c
new file mode 100644 (file)
index 0000000..1f84ae7
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/at_keyboard.h>
+#include <grub/cpu/at_keyboard.h>
+#include <grub/cpu/io.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+
+static short at_keyboard_status = 0;
+static int pending_key = -1;
+
+#define KEYBOARD_STATUS_SHIFT_L                (1 << 0)
+#define KEYBOARD_STATUS_SHIFT_R                (1 << 1)
+#define KEYBOARD_STATUS_ALT_L          (1 << 2)
+#define KEYBOARD_STATUS_ALT_R          (1 << 3)
+#define KEYBOARD_STATUS_CTRL_L         (1 << 4)
+#define KEYBOARD_STATUS_CTRL_R         (1 << 5)
+#define KEYBOARD_STATUS_CAPS_LOCK      (1 << 6)
+#define KEYBOARD_STATUS_NUM_LOCK       (1 << 7)
+
+static grub_uint8_t led_status;
+
+#define KEYBOARD_LED_SCROLL            (1 << 0)
+#define KEYBOARD_LED_NUM               (1 << 1)
+#define KEYBOARD_LED_CAPS              (1 << 2)
+
+static char keyboard_map[128] =
+{
+  '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6',
+  '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB,
+  'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
+  'o', 'p', '[', ']', '\n', '\0', 'a', 's',
+  'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
+  '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v',
+  'b', 'n', 'm', ',', '.', '/', '\0', '*',
+  '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0',
+  '\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_HOME,
+  GRUB_TERM_UP, GRUB_TERM_NPAGE, '-', GRUB_TERM_LEFT, '\0', GRUB_TERM_RIGHT, '+', GRUB_TERM_END,
+  GRUB_TERM_DOWN, GRUB_TERM_PPAGE, '\0', GRUB_TERM_DC, '\0', '\0', '\0', '\0',
+  '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+  '\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT,
+  OLPC_RIGHT
+};
+
+static char keyboard_map_shift[128] =
+{
+  '\0', '\0', '!', '@', '#', '$', '%', '^',
+  '&', '*', '(', ')', '_', '+', '\0', '\0',
+  'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
+  'O', 'P', '{', '}', '\n', '\0', 'A', 'S',
+  'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
+  '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V',
+  'B', 'N', 'M', '<', '>', '?'
+};
+
+static grub_uint8_t grub_keyboard_controller_orig;
+
+static void
+keyboard_controller_wait_until_ready (void)
+{
+  while (! KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS)));
+}
+
+static void
+grub_keyboard_controller_write (grub_uint8_t c)
+{
+  keyboard_controller_wait_until_ready ();
+  grub_outb (KEYBOARD_COMMAND_WRITE, KEYBOARD_REG_STATUS);
+  grub_outb (c, KEYBOARD_REG_DATA);
+}
+
+static grub_uint8_t
+grub_keyboard_controller_read (void)
+{
+  keyboard_controller_wait_until_ready ();
+  grub_outb (KEYBOARD_COMMAND_READ, KEYBOARD_REG_STATUS);
+  return grub_inb (KEYBOARD_REG_DATA);
+}
+
+static void
+keyboard_controller_led (grub_uint8_t leds)
+{
+  keyboard_controller_wait_until_ready ();
+  grub_outb (0xed, KEYBOARD_REG_DATA);
+  keyboard_controller_wait_until_ready ();
+  grub_outb (leds & 0x7, KEYBOARD_REG_DATA);
+}
+
+/* FIXME: This should become an interrupt service routine.  For now
+   it's just used to catch events from control keys.  */
+static void
+grub_keyboard_isr (char key)
+{
+  char is_make = KEYBOARD_ISMAKE (key);
+  key = KEYBOARD_SCANCODE (key);
+  if (is_make)
+    switch (key)
+      {
+       case SHIFT_L:
+         at_keyboard_status |= KEYBOARD_STATUS_SHIFT_L;
+         break;
+       case SHIFT_R:
+         at_keyboard_status |= KEYBOARD_STATUS_SHIFT_R;
+         break;
+       case CTRL:
+         at_keyboard_status |= KEYBOARD_STATUS_CTRL_L;
+         break;
+       case ALT:
+         at_keyboard_status |= KEYBOARD_STATUS_ALT_L;
+         break;
+       default:
+         /* Skip grub_dprintf.  */
+         return;
+      }
+  else
+    switch (key)
+      {
+       case SHIFT_L:
+         at_keyboard_status &= ~KEYBOARD_STATUS_SHIFT_L;
+         break;
+       case SHIFT_R:
+         at_keyboard_status &= ~KEYBOARD_STATUS_SHIFT_R;
+         break;
+       case CTRL:
+         at_keyboard_status &= ~KEYBOARD_STATUS_CTRL_L;
+         break;
+       case ALT:
+         at_keyboard_status &= ~KEYBOARD_STATUS_ALT_L;
+         break;
+       default:
+         /* Skip grub_dprintf.  */
+         return;
+      }
+#ifdef DEBUG_AT_KEYBOARD
+  grub_dprintf ("atkeyb", "Control key 0x%0x was %s\n", key, is_make ? "pressed" : "unpressed");
+#endif
+}
+
+/* If there is a raw key pending, return it; otherwise return -1.  */
+static int
+grub_keyboard_getkey (void)
+{
+  grub_uint8_t key;
+  if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS)))
+    return -1;
+  key = grub_inb (KEYBOARD_REG_DATA);
+  /* FIXME */ grub_keyboard_isr (key);
+  if (! KEYBOARD_ISMAKE (key))
+    return -1;
+  return (KEYBOARD_SCANCODE (key));
+}
+
+/* If there is a character pending, return it; otherwise return -1.  */
+static int
+grub_at_keyboard_getkey_noblock (void)
+{
+  int code, key;
+  code = grub_keyboard_getkey ();
+  if (code == -1)
+    return -1;
+#ifdef DEBUG_AT_KEYBOARD
+  grub_dprintf ("atkeyb", "Detected key 0x%x\n", key);
+#endif
+  switch (code)
+    {
+      case CAPS_LOCK:
+       /* Caps lock sends scan code twice.  Get the second one and discard it.  */
+       while (grub_keyboard_getkey () == -1);
+
+       at_keyboard_status ^= KEYBOARD_STATUS_CAPS_LOCK;
+       led_status ^= KEYBOARD_LED_CAPS;
+       keyboard_controller_led (led_status);
+
+#ifdef DEBUG_AT_KEYBOARD
+       grub_dprintf ("atkeyb", "caps_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK));
+#endif
+       key = -1;
+       break;
+      case NUM_LOCK:
+       /* Num lock sends scan code twice.  Get the second one and discard it.  */
+       while (grub_keyboard_getkey () == -1);
+
+       at_keyboard_status ^= KEYBOARD_STATUS_NUM_LOCK;
+       led_status ^= KEYBOARD_LED_NUM;
+       keyboard_controller_led (led_status);
+
+#ifdef DEBUG_AT_KEYBOARD
+       grub_dprintf ("atkeyb", "num_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_NUM_LOCK));
+#endif
+       key = -1;
+       break;
+      case SCROLL_LOCK:
+       /* For scroll lock we don't keep track of status.  Only update its led.  */
+       led_status ^= KEYBOARD_LED_SCROLL;
+       keyboard_controller_led (led_status);
+       key = -1;
+       break;
+      default:
+       if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L | KEYBOARD_STATUS_CTRL_R))
+         key = keyboard_map[code] - 'a' + 1;
+       else if ((at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L | KEYBOARD_STATUS_SHIFT_R))
+           && keyboard_map_shift[code])
+         key = keyboard_map_shift[code];
+       else
+         key = keyboard_map[code];
+
+       if (key == 0)
+         grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code);
+
+       if (at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK)
+         {
+           if ((key >= 'a') && (key <= 'z'))
+             key += 'A' - 'a';
+           else if ((key >= 'A') && (key <= 'Z'))
+             key += 'a' - 'A';
+         }
+    }
+  return key;
+}
+
+static int
+grub_at_keyboard_checkkey (void)
+{
+  if (pending_key != -1)
+    return 1;
+
+  pending_key = grub_at_keyboard_getkey_noblock ();
+
+  if (pending_key != -1)
+    return 1;
+
+  return -1;
+}
+
+static int
+grub_at_keyboard_getkey (void)
+{
+  int key;
+  if (pending_key != -1)
+    {
+      key = pending_key;
+      pending_key = -1;
+      return key;
+    }
+  do
+    {
+      key = grub_at_keyboard_getkey_noblock ();
+    } while (key == -1);
+  return key;
+}
+
+static grub_err_t
+grub_keyboard_controller_init (void)
+{
+  pending_key = -1;
+  at_keyboard_status = 0;
+  grub_keyboard_controller_orig = grub_keyboard_controller_read ();
+  grub_keyboard_controller_write (grub_keyboard_controller_orig | KEYBOARD_SCANCODE_SET1);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_keyboard_controller_fini (void)
+{
+  grub_keyboard_controller_write (grub_keyboard_controller_orig);
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_term_input grub_at_keyboard_term =
+  {
+    .name = "at_keyboard",
+    .init = grub_keyboard_controller_init,
+    .fini = grub_keyboard_controller_fini,
+    .checkkey = grub_at_keyboard_checkkey,
+    .getkey = grub_at_keyboard_getkey,
+  };
+
+GRUB_MOD_INIT(at_keyboard)
+{
+  grub_term_register_input ("at_keyboard", &grub_at_keyboard_term);
+}
+
+GRUB_MOD_FINI(at_keyboard)
+{
+  grub_term_unregister_input (&grub_at_keyboard_term);
+}
diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c
new file mode 100644 (file)
index 0000000..6648613
--- /dev/null
@@ -0,0 +1,380 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/api.h>
+#include <grub/efi/console.h>
+
+static grub_uint8_t
+grub_console_standard_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_YELLOW,
+                                                 GRUB_EFI_BACKGROUND_BLACK);
+static grub_uint8_t
+grub_console_normal_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_LIGHTGRAY,
+                                               GRUB_EFI_BACKGROUND_BLACK);
+static grub_uint8_t
+grub_console_highlight_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_BLACK,
+                                                  GRUB_EFI_BACKGROUND_LIGHTGRAY);
+
+static int read_key = -1;
+
+static grub_uint32_t
+map_char (grub_uint32_t c)
+{
+  if (c > 0x7f)
+    {
+      /* Map some unicode characters to the EFI character.  */
+      switch (c)
+       {
+       case 0x2190:    /* left arrow */
+         c = 0x25c4;
+         break;
+       case 0x2191:    /* up arrow */
+         c = 0x25b2;
+         break;
+       case 0x2192:    /* right arrow */
+         c = 0x25ba;
+         break;
+       case 0x2193:    /* down arrow */
+         c = 0x25bc;
+         break;
+       case 0x2501:    /* horizontal line */
+         c = 0x2500;
+         break;
+       case 0x2503:    /* vertical line */
+         c = 0x2502;
+         break;
+       case 0x250F:    /* upper-left corner */
+         c = 0x250c;
+         break;
+       case 0x2513:    /* upper-right corner */
+         c = 0x2510;
+         break;
+       case 0x2517:    /* lower-left corner */
+         c = 0x2514;
+         break;
+       case 0x251B:    /* lower-right corner */
+         c = 0x2518;
+         break;
+
+       default:
+         c = '?';
+         break;
+       }
+    }
+
+  return c;
+}
+
+static void
+grub_console_putchar (grub_uint32_t c)
+{
+  grub_efi_char16_t str[2];
+  grub_efi_simple_text_output_interface_t *o;
+
+  o = grub_efi_system_table->con_out;
+
+  /* For now, do not try to use a surrogate pair.  */
+  if (c > 0xffff)
+    c = '?';
+
+  str[0] = (grub_efi_char16_t)  map_char (c & 0xffff);
+  str[1] = 0;
+
+  /* Should this test be cached?  */
+  if (c > 0x7f && efi_call_2 (o->test_string, o, str) != GRUB_EFI_SUCCESS)
+    return;
+
+  efi_call_2 (o->output_string, o, str);
+}
+
+static grub_ssize_t
+grub_console_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
+{
+  /* For now, every printable character has the width 1.  */
+  return 1;
+}
+
+static int
+grub_console_checkkey (void)
+{
+  grub_efi_simple_input_interface_t *i;
+  grub_efi_input_key_t key;
+  grub_efi_status_t status;
+
+  if (read_key >= 0)
+    return 1;
+
+  i = grub_efi_system_table->con_in;
+  status = efi_call_2 (i->read_key_stroke, i, &key);
+#if 0
+  switch (status)
+    {
+    case GRUB_EFI_SUCCESS:
+      {
+       grub_uint16_t xy;
+
+       xy = grub_getxy ();
+       grub_gotoxy (0, 0);
+       grub_printf ("scan_code=%x,unicode_char=%x  ",
+                    (unsigned) key.scan_code,
+                    (unsigned) key.unicode_char);
+       grub_gotoxy (xy >> 8, xy & 0xff);
+      }
+      break;
+
+    case GRUB_EFI_NOT_READY:
+      //grub_printf ("not ready   ");
+      break;
+
+    default:
+      //grub_printf ("device error   ");
+      break;
+    }
+#endif
+
+  if (status == GRUB_EFI_SUCCESS)
+    {
+      switch (key.scan_code)
+       {
+       case 0x00:
+         read_key = key.unicode_char;
+         break;
+       case 0x01:
+         read_key = GRUB_TERM_UP;
+         break;
+       case 0x02:
+         read_key = GRUB_TERM_DOWN;
+         break;
+       case 0x03:
+         read_key = GRUB_TERM_RIGHT;
+         break;
+       case 0x04:
+         read_key = GRUB_TERM_LEFT;
+         break;
+       case 0x05:
+         read_key = GRUB_TERM_HOME;
+         break;
+       case 0x06:
+         read_key = GRUB_TERM_END;
+         break;
+       case 0x07:
+         break;
+       case 0x08:
+         read_key = GRUB_TERM_DC;
+         break;
+       case 0x09:
+         break;
+       case 0x0a:
+         break;
+       case 0x0b:
+         read_key = 24;
+         break;
+       case 0x0c:
+         read_key = 1;
+         break;
+       case 0x0d:
+         read_key = 5;
+         break;
+       case 0x0e:
+         read_key = 3;
+         break;
+       case 0x17:
+         read_key = '\e';
+         break;
+       default:
+         break;
+       }
+    }
+
+  return read_key;
+}
+
+static int
+grub_console_getkey (void)
+{
+  grub_efi_simple_input_interface_t *i;
+  grub_efi_boot_services_t *b;
+  grub_efi_uintn_t index;
+  grub_efi_status_t status;
+  int key;
+
+  if (read_key >= 0)
+    {
+      key = read_key;
+      read_key = -1;
+      return key;
+    }
+
+  i = grub_efi_system_table->con_in;
+  b = grub_efi_system_table->boot_services;
+
+  do
+    {
+      status = efi_call_3 (b->wait_for_event, 1, &(i->wait_for_key), &index);
+      if (status != GRUB_EFI_SUCCESS)
+        return -1;
+
+      grub_console_checkkey ();
+    }
+  while (read_key < 0);
+
+  key = read_key;
+  read_key = -1;
+  return key;
+}
+
+static grub_uint16_t
+grub_console_getwh (void)
+{
+  grub_efi_simple_text_output_interface_t *o;
+  grub_efi_uintn_t columns, rows;
+
+  o = grub_efi_system_table->con_out;
+  if (efi_call_4 (o->query_mode, o, o->mode->mode, &columns, &rows) != GRUB_EFI_SUCCESS)
+    {
+      /* Why does this fail?  */
+      columns = 80;
+      rows = 25;
+    }
+
+  return ((columns << 8) | rows);
+}
+
+static grub_uint16_t
+grub_console_getxy (void)
+{
+  grub_efi_simple_text_output_interface_t *o;
+
+  o = grub_efi_system_table->con_out;
+  return ((o->mode->cursor_column << 8) | o->mode->cursor_row);
+}
+
+static void
+grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  grub_efi_simple_text_output_interface_t *o;
+
+  o = grub_efi_system_table->con_out;
+  efi_call_3 (o->set_cursor_position, o, x, y);
+}
+
+static void
+grub_console_cls (void)
+{
+  grub_efi_simple_text_output_interface_t *o;
+  grub_efi_int32_t orig_attr;
+
+  o = grub_efi_system_table->con_out;
+  orig_attr = o->mode->attribute;
+  efi_call_2 (o->set_attributes, o, GRUB_EFI_BACKGROUND_BLACK);
+  efi_call_1 (o->clear_screen, o);
+  efi_call_2 (o->set_attributes, o, orig_attr);
+}
+
+static void
+grub_console_setcolorstate (grub_term_color_state state)
+{
+  grub_efi_simple_text_output_interface_t *o;
+
+  o = grub_efi_system_table->con_out;
+
+  switch (state) {
+    case GRUB_TERM_COLOR_STANDARD:
+      efi_call_2 (o->set_attributes, o, grub_console_standard_color);
+      break;
+    case GRUB_TERM_COLOR_NORMAL:
+      efi_call_2 (o->set_attributes, o, grub_console_normal_color);
+      break;
+    case GRUB_TERM_COLOR_HIGHLIGHT:
+      efi_call_2 (o->set_attributes, o, grub_console_highlight_color);
+      break;
+    default:
+      break;
+  }
+}
+
+static void
+grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
+{
+  grub_console_normal_color = normal_color;
+  grub_console_highlight_color = highlight_color;
+}
+
+static void
+grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
+{
+  *normal_color = grub_console_normal_color;
+  *highlight_color = grub_console_highlight_color;
+}
+
+static void
+grub_console_setcursor (int on)
+{
+  grub_efi_simple_text_output_interface_t *o;
+
+  o = grub_efi_system_table->con_out;
+  efi_call_2 (o->enable_cursor, o, on);
+}
+
+static struct grub_term_input grub_console_term_input =
+  {
+    .name = "console",
+    .checkkey = grub_console_checkkey,
+    .getkey = grub_console_getkey,
+  };
+
+static struct grub_term_output grub_console_term_output =
+  {
+    .name = "console",
+    .putchar = grub_console_putchar,
+    .getcharwidth = grub_console_getcharwidth,
+    .getwh = grub_console_getwh,
+    .getxy = grub_console_getxy,
+    .gotoxy = grub_console_gotoxy,
+    .cls = grub_console_cls,
+    .setcolorstate = grub_console_setcolorstate,
+    .setcolor = grub_console_setcolor,
+    .getcolor = grub_console_getcolor,
+    .setcursor = grub_console_setcursor
+  };
+
+void
+grub_console_init (void)
+{
+  /* FIXME: it is necessary to consider the case where no console control
+     is present but the default is already in text mode.  */
+  if (! grub_efi_set_text_mode (1))
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "cannot set text mode");
+      return;
+    }
+
+  grub_term_register_input ("console", &grub_console_term_input);
+  grub_term_register_output ("console", &grub_console_term_output);
+}
+
+void
+grub_console_fini (void)
+{
+  grub_term_unregister_input (&grub_console_term_input);
+  grub_term_unregister_output (&grub_console_term_output);
+}
diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c
new file mode 100644 (file)
index 0000000..ecfe4ff
--- /dev/null
@@ -0,0 +1,1200 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/term.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/font.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/video.h>
+#include <grub/gfxterm.h>
+#include <grub/bitmap.h>
+#include <grub/command.h>
+#include <grub/extcmd.h>
+#include <grub/bitmap_scale.h>
+#include <grub/i18n.h>
+
+#define DEFAULT_VIDEO_MODE     "auto"
+#define DEFAULT_BORDER_WIDTH   10
+
+#define DEFAULT_STANDARD_COLOR  0x07
+#define DEFAULT_NORMAL_COLOR    0x07
+#define DEFAULT_HIGHLIGHT_COLOR 0x70
+
+struct grub_dirty_region
+{
+  int top_left_x;
+  int top_left_y;
+  int bottom_right_x;
+  int bottom_right_y;
+};
+
+struct grub_colored_char
+{
+  /* An Unicode codepoint.  */
+  grub_uint32_t code;
+
+  /* Color values.  */
+  grub_video_color_t fg_color;
+  grub_video_color_t bg_color;
+
+  /* The width of this character minus one.  */
+  unsigned char width;
+
+  /* The column index of this character.  */
+  unsigned char index;
+};
+
+struct grub_virtual_screen
+{
+  /* Dimensions of the virtual screen in pixels.  */
+  unsigned int width;
+  unsigned int height;
+
+  /* Offset in the display in pixels.  */
+  unsigned int offset_x;
+  unsigned int offset_y;
+
+  /* TTY Character sizes in pixes.  */
+  unsigned int normal_char_width;
+  unsigned int normal_char_height;
+
+  /* Virtual screen TTY size in characters.  */
+  unsigned int columns;
+  unsigned int rows;
+
+  /* Current cursor location in characters.  */
+  unsigned int cursor_x;
+  unsigned int cursor_y;
+
+  /* Current cursor state. */
+  int cursor_state;
+
+  /* Font settings. */
+  grub_font_t font;
+
+  /* Terminal color settings.  */
+  grub_uint8_t standard_color_setting;
+  grub_uint8_t normal_color_setting;
+  grub_uint8_t highlight_color_setting;
+  grub_uint8_t term_color;
+
+  /* Color settings.  */
+  grub_video_color_t fg_color;
+  grub_video_color_t bg_color;
+  grub_video_color_t bg_color_display;
+
+  /* Text buffer for virtual screen.  Contains (columns * rows) number
+     of entries.  */
+  struct grub_colored_char *text_buffer;
+
+  int total_scroll;
+};
+
+struct grub_gfxterm_window
+{
+  unsigned x;
+  unsigned y;
+  unsigned width;
+  unsigned height;
+  int double_repaint;
+};
+
+static struct grub_video_render_target *render_target;
+void (*grub_gfxterm_decorator_hook) (void) = NULL;
+static struct grub_gfxterm_window window;
+static struct grub_virtual_screen virtual_screen;
+static grub_gfxterm_repaint_callback_t repaint_callback;
+static int repaint_schedulded = 0;
+static int repaint_was_schedulded = 0;
+
+static void destroy_window (void);
+
+static struct grub_video_render_target *text_layer;
+
+static unsigned int bitmap_width;
+static unsigned int bitmap_height;
+static struct grub_video_bitmap *bitmap;
+
+static struct grub_dirty_region dirty_region;
+
+static void dirty_region_reset (void);
+
+static int dirty_region_is_empty (void);
+
+static void dirty_region_add (int x, int y,
+                              unsigned int width, unsigned int height);
+
+static unsigned int calculate_normal_character_width (grub_font_t font);
+
+static unsigned char calculate_character_width (struct grub_font_glyph *glyph);
+
+static void grub_gfxterm_refresh (void);
+
+static void
+set_term_color (grub_uint8_t term_color)
+{
+  struct grub_video_render_target *old_target;
+
+  /* Save previous target and switch to text layer.  */
+  grub_video_get_active_render_target (&old_target);
+  grub_video_set_active_render_target (text_layer);
+
+  /* Map terminal color to text layer compatible video colors.  */
+  virtual_screen.fg_color = grub_video_map_color(term_color & 0x0f);
+
+  /* Special case: use black as transparent color.  */
+  if (((term_color >> 4) & 0x0f) == 0)
+    {
+      virtual_screen.bg_color = grub_video_map_rgba(0, 0, 0, 0);
+    }
+  else
+    {
+      virtual_screen.bg_color = grub_video_map_color((term_color >> 4) & 0x0f);
+    }
+
+  /* Restore previous target.  */
+  grub_video_set_active_render_target (old_target);
+}
+
+static void
+clear_char (struct grub_colored_char *c)
+{
+  c->code = ' ';
+  c->fg_color = virtual_screen.fg_color;
+  c->bg_color = virtual_screen.bg_color;
+  c->width = 0;
+  c->index = 0;
+}
+
+static void
+grub_virtual_screen_free (void)
+{
+  /* If virtual screen has been allocated, free it.  */
+  if (virtual_screen.text_buffer != 0)
+    grub_free (virtual_screen.text_buffer);
+
+  /* Reset virtual screen data.  */
+  grub_memset (&virtual_screen, 0, sizeof (virtual_screen));
+
+  /* Free render targets.  */
+  grub_video_delete_render_target (text_layer);
+  text_layer = 0;
+}
+
+static grub_err_t
+grub_virtual_screen_setup (unsigned int x, unsigned int y,
+                           unsigned int width, unsigned int height,
+                           const char *font_name)
+{
+  unsigned int i;
+
+  /* Free old virtual screen.  */
+  grub_virtual_screen_free ();
+
+  /* Initialize with default data.  */
+  virtual_screen.font = grub_font_get (font_name);
+  if (!virtual_screen.font)
+    return grub_error (GRUB_ERR_BAD_FONT,
+                       "no font loaded");
+  virtual_screen.width = width;
+  virtual_screen.height = height;
+  virtual_screen.offset_x = x;
+  virtual_screen.offset_y = y;
+  virtual_screen.normal_char_width =
+    calculate_normal_character_width (virtual_screen.font);
+  virtual_screen.normal_char_height =
+    grub_font_get_max_char_height (virtual_screen.font);
+  virtual_screen.cursor_x = 0;
+  virtual_screen.cursor_y = 0;
+  virtual_screen.cursor_state = 1;
+  virtual_screen.total_scroll = 0;
+
+  /* Calculate size of text buffer.  */
+  virtual_screen.columns = virtual_screen.width / virtual_screen.normal_char_width;
+  virtual_screen.rows = virtual_screen.height / virtual_screen.normal_char_height;
+
+  /* Allocate memory for text buffer.  */
+  virtual_screen.text_buffer =
+    (struct grub_colored_char *) grub_malloc (virtual_screen.columns
+                                              * virtual_screen.rows
+                                              * sizeof (*virtual_screen.text_buffer));
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* Create new render target for text layer.  */
+  grub_video_create_render_target (&text_layer,
+                                   virtual_screen.width,
+                                   virtual_screen.height,
+                                   GRUB_VIDEO_MODE_TYPE_RGB
+                                   | GRUB_VIDEO_MODE_TYPE_ALPHA);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* As we want to have colors compatible with rendering target,
+     we can only have those after mode is initialized.  */
+  grub_video_set_active_render_target (text_layer);
+
+  virtual_screen.standard_color_setting = DEFAULT_STANDARD_COLOR;
+  virtual_screen.normal_color_setting = DEFAULT_NORMAL_COLOR;
+  virtual_screen.highlight_color_setting = DEFAULT_HIGHLIGHT_COLOR;
+
+  virtual_screen.term_color = virtual_screen.normal_color_setting;
+
+  set_term_color (virtual_screen.term_color);
+
+  grub_video_set_active_render_target (render_target);
+
+  virtual_screen.bg_color_display = grub_video_map_rgba(0, 0, 0, 0);
+
+  /* Clear out text buffer. */
+  for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
+    clear_char (&(virtual_screen.text_buffer[i]));
+
+  return grub_errno;
+}
+
+void
+grub_gfxterm_schedule_repaint (void)
+{
+  repaint_schedulded = 1;
+}
+
+grub_err_t
+grub_gfxterm_set_window (struct grub_video_render_target *target,
+                        int x, int y, int width, int height,
+                        int double_repaint,
+                        const char *font_name, int border_width)
+{
+  /* Clean up any prior instance.  */
+  destroy_window ();
+
+  /* Set the render target.  */
+  render_target = target;
+
+  /* Create virtual screen.  */
+  if (grub_virtual_screen_setup (border_width, border_width, 
+                                 width - 2 * border_width, 
+                                 height - 2 * border_width, 
+                                 font_name) 
+      != GRUB_ERR_NONE)
+    {
+      return grub_errno;
+    }
+
+  /* Set window bounds.  */
+  window.x = x;
+  window.y = y;
+  window.width = width;
+  window.height = height;
+  window.double_repaint = double_repaint;
+
+  dirty_region_reset ();
+  grub_gfxterm_schedule_repaint ();
+
+  return grub_errno;
+}
+
+grub_err_t
+grub_gfxterm_fullscreen (void)
+{
+  const char *font_name;
+  struct grub_video_mode_info mode_info;
+  grub_video_color_t color;
+  grub_err_t err;
+  int double_redraw;
+
+  err = grub_video_get_info (&mode_info);
+  /* Figure out what mode we ended up.  */
+  if (err)
+    return err;
+
+  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
+
+  double_redraw = mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
+    && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
+
+  /* Make sure screen is black.  */
+  color = grub_video_map_rgb (0, 0, 0);
+  grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height);
+  if (double_redraw)
+    {
+      grub_video_swap_buffers ();
+      grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height);
+    }
+  bitmap = 0;
+
+  /* Select the font to use.  */
+  font_name = grub_env_get ("gfxterm_font");
+  if (! font_name)
+    font_name = "";   /* Allow fallback to any font.  */
+
+  grub_gfxterm_decorator_hook = NULL;
+
+  return grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY,
+                                 0, 0, mode_info.width, mode_info.height,
+                                 double_redraw,
+                                 font_name, DEFAULT_BORDER_WIDTH);
+}
+
+static grub_err_t
+grub_gfxterm_term_init (void)
+{
+  char *tmp;
+  grub_err_t err;
+  const char *modevar;
+
+  /* Parse gfxmode environment variable if set.  */
+  modevar = grub_env_get ("gfxmode");
+  if (! modevar || *modevar == 0)
+    err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
+                              GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
+  else
+    {
+      tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
+      if (!tmp)
+       return grub_errno;
+      err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
+      grub_free (tmp);
+    }
+
+  if (err)
+    return err;
+
+  err = grub_gfxterm_fullscreen ();
+  if (err)
+    grub_video_restore ();
+
+  return err;
+}
+
+static void
+destroy_window (void)
+{
+  if (bitmap)
+    {
+      grub_video_bitmap_destroy (bitmap);
+      bitmap = 0;
+    }
+
+  repaint_callback = 0;
+  grub_virtual_screen_free ();
+}
+
+static grub_err_t
+grub_gfxterm_term_fini (void)
+{
+  destroy_window ();
+  grub_video_restore ();
+
+  /* Clear error state.  */
+  grub_errno = GRUB_ERR_NONE;
+  return GRUB_ERR_NONE;
+}
+
+static void
+redraw_screen_rect (unsigned int x, unsigned int y,
+                    unsigned int width, unsigned int height)
+{
+  grub_video_color_t color;
+  grub_video_rect_t saved_view;
+
+  grub_video_set_active_render_target (render_target);
+  /* Save viewport and set it to our window.  */
+  grub_video_get_viewport ((unsigned *) &saved_view.x, 
+                           (unsigned *) &saved_view.y, 
+                           (unsigned *) &saved_view.width, 
+                           (unsigned *) &saved_view.height);
+  grub_video_set_viewport (window.x, window.y, window.width, window.height);
+
+  if (bitmap)
+    {
+      /* Render bitmap as background.  */
+      grub_video_blit_bitmap (bitmap, GRUB_VIDEO_BLIT_REPLACE, x, y,
+                             x, y,
+                              width, height);
+
+      /* If bitmap is smaller than requested blit area, use background
+         color.  */
+      color = virtual_screen.bg_color_display;
+
+      /* Fill right side of the bitmap if needed.  */
+      if ((x + width >= bitmap_width) && (y < bitmap_height))
+        {
+          int w = (x + width) - bitmap_width;
+          int h = height;
+          unsigned int tx = x;
+
+          if (y + height >= bitmap_height)
+            {
+              h = bitmap_height - y;
+            }
+
+          if (bitmap_width > tx)
+            {
+              tx = bitmap_width;
+            }
+
+          /* Render background layer.  */
+         grub_video_fill_rect (color, tx, y, w, h);
+        }
+
+      /* Fill bottom side of the bitmap if needed.  */
+      if (y + height >= bitmap_height)
+        {
+          int h = (y + height) - bitmap_height;
+          unsigned int ty = y;
+
+          if (bitmap_height > ty)
+            {
+              ty = bitmap_height;
+            }
+
+          /* Render background layer.  */
+         grub_video_fill_rect (color, x, ty, width, h);
+        }
+
+      /* Render text layer as blended.  */
+      grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, x, y,
+                                     x - virtual_screen.offset_x,
+                                     y - virtual_screen.offset_y,
+                                     width, height);
+    }
+  else
+    {
+      /* Render background layer.  */
+      color = virtual_screen.bg_color_display;
+      grub_video_fill_rect (color, x, y, width, height);
+
+      /* Render text layer as replaced (to get texts background color).  */
+      grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_REPLACE, x, y,
+                                     x - virtual_screen.offset_x,
+                                     y - virtual_screen.offset_y,
+                                    width, height);
+    }
+
+  /* Restore saved viewport.  */
+  grub_video_set_viewport (saved_view.x, saved_view.y,
+                           saved_view.width, saved_view.height);
+  grub_video_set_active_render_target (render_target);
+  
+  if (repaint_callback)
+    repaint_callback (x, y, width, height);
+}
+
+static void
+dirty_region_reset (void)
+{
+  dirty_region.top_left_x = -1;
+  dirty_region.top_left_y = -1;
+  dirty_region.bottom_right_x = -1;
+  dirty_region.bottom_right_y = -1;
+  repaint_was_schedulded = 0;
+}
+
+static int
+dirty_region_is_empty (void)
+{
+  if ((dirty_region.top_left_x == -1)
+      || (dirty_region.top_left_y == -1)
+      || (dirty_region.bottom_right_x == -1)
+      || (dirty_region.bottom_right_y == -1))
+    return 1;
+  return 0;
+}
+
+static void
+dirty_region_add (int x, int y, unsigned int width, unsigned int height)
+{
+  if ((width == 0) || (height == 0))
+    return;
+
+  if (repaint_schedulded)
+    {
+      x = virtual_screen.offset_x;
+      y = virtual_screen.offset_y;
+      width = virtual_screen.width;
+      height = virtual_screen.height;
+      repaint_schedulded = 0;
+      repaint_was_schedulded = 1;
+    }
+
+  if (dirty_region_is_empty ())
+    {
+      dirty_region.top_left_x = x;
+      dirty_region.top_left_y = y;
+      dirty_region.bottom_right_x = x + width - 1;
+      dirty_region.bottom_right_y = y + height - 1;
+    }
+  else
+    {
+      if (x < dirty_region.top_left_x)
+        dirty_region.top_left_x = x;
+      if (y < dirty_region.top_left_y)
+        dirty_region.top_left_y = y;
+      if ((x + (int)width - 1) > dirty_region.bottom_right_x)
+        dirty_region.bottom_right_x = x + width - 1;
+      if ((y + (int)height - 1) > dirty_region.bottom_right_y)
+        dirty_region.bottom_right_y = y + height - 1;
+    }
+}
+
+static void
+dirty_region_add_virtualscreen (void)
+{
+  /* Mark virtual screen as dirty.  */
+  dirty_region_add (virtual_screen.offset_x, virtual_screen.offset_y,
+                    virtual_screen.width, virtual_screen.height);
+}
+
+
+static void
+dirty_region_redraw (void)
+{
+  int x;
+  int y;
+  int width;
+  int height;
+
+  if (dirty_region_is_empty ())
+    return;
+
+  x = dirty_region.top_left_x;
+  y = dirty_region.top_left_y;
+
+  width = dirty_region.bottom_right_x - x + 1;
+  height = dirty_region.bottom_right_y - y + 1;
+
+  if (repaint_was_schedulded && grub_gfxterm_decorator_hook)
+    grub_gfxterm_decorator_hook ();
+
+  redraw_screen_rect (x, y, width, height);
+}
+
+static inline void
+paint_char (unsigned cx, unsigned cy)
+{
+  struct grub_colored_char *p;
+  struct grub_font_glyph *glyph;
+  grub_video_color_t color;
+  grub_video_color_t bgcolor;
+  unsigned int x;
+  unsigned int y;
+  int ascent;
+  unsigned int height;
+  unsigned int width;
+
+  if (cy + virtual_screen.total_scroll >= virtual_screen.rows)
+    return;
+
+  /* Find out active character.  */
+  p = (virtual_screen.text_buffer
+       + cx + (cy * virtual_screen.columns));
+
+  p -= p->index;
+
+  /* Get glyph for character.  */
+  glyph = grub_font_get_glyph (virtual_screen.font, p->code);
+  ascent = grub_font_get_ascent (virtual_screen.font);
+
+  width = virtual_screen.normal_char_width * calculate_character_width(glyph);
+  height = virtual_screen.normal_char_height;
+
+  color = p->fg_color;
+  bgcolor = p->bg_color;
+
+  x = cx * virtual_screen.normal_char_width;
+  y = (cy + virtual_screen.total_scroll) * virtual_screen.normal_char_height;
+
+  /* Render glyph to text layer.  */
+  grub_video_set_active_render_target (text_layer);
+  grub_video_fill_rect (bgcolor, x, y, width, height);
+  grub_font_draw_glyph (glyph, color, x, y + ascent);
+  grub_video_set_active_render_target (render_target);
+
+  /* Mark character to be drawn.  */
+  dirty_region_add (virtual_screen.offset_x + x, virtual_screen.offset_y + y,
+                    width, height);
+}
+
+static inline void
+write_char (void)
+{
+  paint_char (virtual_screen.cursor_x, virtual_screen.cursor_y);
+}
+
+static inline void
+draw_cursor (int show)
+{
+  unsigned int x;
+  unsigned int y;
+  unsigned int width;
+  unsigned int height;
+  grub_video_color_t color;
+  
+  write_char ();
+
+  if (!show)
+    return;
+
+  if (virtual_screen.cursor_y + virtual_screen.total_scroll
+      >= virtual_screen.rows)
+    return;
+
+  /* Determine cursor properties and position on text layer. */
+  x = virtual_screen.cursor_x * virtual_screen.normal_char_width;
+  width = virtual_screen.normal_char_width;
+  color = virtual_screen.fg_color;
+  y = ((virtual_screen.cursor_y + virtual_screen.total_scroll)
+       * virtual_screen.normal_char_height
+       + grub_font_get_ascent (virtual_screen.font));
+  height = 2;
+  
+  /* Render cursor to text layer.  */
+  grub_video_set_active_render_target (text_layer);
+  grub_video_fill_rect (color, x, y, width, height);
+  grub_video_set_active_render_target (render_target);
+  
+  /* Mark cursor to be redrawn.  */
+  dirty_region_add (virtual_screen.offset_x + x,
+                   virtual_screen.offset_y + y,
+                   width, height);
+}
+
+static void
+real_scroll (void)
+{
+  unsigned int i, j, was_scroll;
+  grub_video_color_t color;
+
+  if (!virtual_screen.total_scroll)
+    return;
+
+  /* If we have bitmap, re-draw screen, otherwise scroll physical screen too.  */
+  if (bitmap)
+    {
+      /* Scroll physical screen.  */
+      grub_video_set_active_render_target (text_layer);
+      color = virtual_screen.bg_color;
+      grub_video_scroll (color, 0, -virtual_screen.normal_char_height
+                        * virtual_screen.total_scroll);
+
+      /* Mark virtual screen to be redrawn.  */
+      dirty_region_add_virtualscreen ();
+    }
+  else
+    {
+      grub_video_rect_t saved_view;
+
+      /* Remove cursor.  */
+      draw_cursor (0);
+
+      grub_video_set_active_render_target (render_target);
+      /* Save viewport and set it to our window.  */
+      grub_video_get_viewport ((unsigned *) &saved_view.x, 
+                               (unsigned *) &saved_view.y, 
+                               (unsigned *) &saved_view.width, 
+                               (unsigned *) &saved_view.height);
+      grub_video_set_viewport (window.x, window.y, window.width, window.height);
+
+      i = window.double_repaint ? 2 : 1;
+
+      color = virtual_screen.bg_color;
+
+      while (i--)
+       {
+         /* Clear new border area.  */
+         grub_video_fill_rect (color,
+                               virtual_screen.offset_x,
+                               virtual_screen.offset_y,
+                               virtual_screen.width,
+                               virtual_screen.normal_char_height
+                               * virtual_screen.total_scroll);
+
+         grub_video_set_active_render_target (render_target);
+         dirty_region_redraw ();
+
+         /* Scroll physical screen.  */
+         grub_video_scroll (color, 0, -virtual_screen.normal_char_height
+                            * virtual_screen.total_scroll);
+
+         if (i)
+           grub_video_swap_buffers ();
+       }
+      dirty_region_reset ();
+
+      /* Scroll physical screen.  */
+      grub_video_set_active_render_target (text_layer);
+      color = virtual_screen.bg_color;
+      grub_video_scroll (color, 0, -virtual_screen.normal_char_height
+                        * virtual_screen.total_scroll);
+
+      /* Restore saved viewport.  */
+      grub_video_set_viewport (saved_view.x, saved_view.y,
+                               saved_view.width, saved_view.height);
+      grub_video_set_active_render_target (render_target);
+
+    }
+
+  was_scroll = virtual_screen.total_scroll;
+  virtual_screen.total_scroll = 0;
+
+  if (was_scroll > virtual_screen.rows)
+    was_scroll = virtual_screen.rows;
+
+  /* Draw shadow part.  */
+  for (i = virtual_screen.rows - was_scroll;
+       i < virtual_screen.rows; i++)
+    for (j = 0; j < virtual_screen.columns; j++)
+      paint_char (j, i);
+
+  /* Draw cursor if visible.  */
+  if (virtual_screen.cursor_state)
+    draw_cursor (1);
+
+  if (repaint_callback)
+    repaint_callback (window.x, window.y, window.width, window.height);
+}
+
+static void
+scroll_up (void)
+{
+  unsigned int i;
+
+  /* Scroll text buffer with one line to up.  */
+  grub_memmove (virtual_screen.text_buffer,
+                virtual_screen.text_buffer + virtual_screen.columns,
+                sizeof (*virtual_screen.text_buffer)
+                * virtual_screen.columns
+                * (virtual_screen.rows - 1));
+
+  /* Clear last line in text buffer.  */
+  for (i = virtual_screen.columns * (virtual_screen.rows - 1);
+       i < virtual_screen.columns * virtual_screen.rows;
+       i++)
+    clear_char (&(virtual_screen.text_buffer[i]));
+
+  virtual_screen.total_scroll++;
+}
+
+static void
+grub_gfxterm_putchar (grub_uint32_t c)
+{
+  if (c == '\a')
+    /* FIXME */
+    return;
+
+  /* Erase current cursor, if any.  */
+  if (virtual_screen.cursor_state)
+    draw_cursor (0);
+
+  if (c == '\b' || c == '\n' || c == '\r')
+    {
+      switch (c)
+        {
+        case '\b':
+          if (virtual_screen.cursor_x > 0)
+            virtual_screen.cursor_x--;
+          break;
+
+        case '\n':
+          if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
+            scroll_up ();
+          else
+            virtual_screen.cursor_y++;
+          break;
+
+        case '\r':
+          virtual_screen.cursor_x = 0;
+          break;
+        }
+    }
+  else
+    {
+      struct grub_font_glyph *glyph;
+      struct grub_colored_char *p;
+      unsigned char char_width;
+
+      /* Get properties of the character.  */
+      glyph = grub_font_get_glyph (virtual_screen.font, c);
+
+      /* Calculate actual character width for glyph. This is number of
+         times of normal_font_width.  */
+      char_width = calculate_character_width(glyph);
+
+      /* If we are about to exceed line length, wrap to next line.  */
+      if (virtual_screen.cursor_x + char_width > virtual_screen.columns)
+        grub_putchar ('\n');
+
+      /* Find position on virtual screen, and fill information.  */
+      p = (virtual_screen.text_buffer +
+           virtual_screen.cursor_x +
+           virtual_screen.cursor_y * virtual_screen.columns);
+      p->code = c;
+      p->fg_color = virtual_screen.fg_color;
+      p->bg_color = virtual_screen.bg_color;
+      p->width = char_width - 1;
+      p->index = 0;
+
+      /* If we have large glyph, add fixup info.  */
+      if (char_width > 1)
+        {
+          unsigned i;
+
+          for (i = 1; i < char_width; i++)
+            {
+              p[i].code = ' ';
+              p[i].width = char_width - 1;
+              p[i].index = i;
+            }
+        }
+
+      /* Draw glyph.  */
+      write_char ();
+
+      /* Make sure we scroll screen when needed and wrap line correctly.  */
+      virtual_screen.cursor_x += char_width;
+      if (virtual_screen.cursor_x >= virtual_screen.columns)
+        {
+          virtual_screen.cursor_x = 0;
+
+          if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
+            scroll_up ();
+          else
+            virtual_screen.cursor_y++;
+        }
+    }
+
+  /* Redraw cursor if it should be visible.  */
+  /* Note: This will redraw the character as well, which means that the
+     above call to write_char is redundant when the cursor is showing.  */
+  if (virtual_screen.cursor_state)
+    draw_cursor (1);
+}
+
+/* Use ASCII characters to determine normal character width.  */
+static unsigned int
+calculate_normal_character_width (grub_font_t font)
+{
+  struct grub_font_glyph *glyph;
+  unsigned int width = 0;
+  unsigned int i;
+
+  /* Get properties of every printable ASCII character.  */
+  for (i = 32; i < 127; i++)
+    {
+      glyph = grub_font_get_glyph (font, i);
+
+      /* Skip unknown characters.  Should never happen on normal conditions.  */
+      if (! glyph)
+       continue;
+
+      if (glyph->device_width > width)
+       width = glyph->device_width;
+    }
+
+  return width;
+}
+
+static unsigned char
+calculate_character_width (struct grub_font_glyph *glyph)
+{
+  if (! glyph || glyph->device_width == 0)
+    return 1;
+
+  return (glyph->device_width
+          + (virtual_screen.normal_char_width - 1))
+         / virtual_screen.normal_char_width;
+}
+
+static grub_ssize_t
+grub_gfxterm_getcharwidth (grub_uint32_t c)
+{
+  struct grub_font_glyph *glyph;
+  unsigned char char_width;
+
+  /* Get properties of the character.  */
+  glyph = grub_font_get_glyph (virtual_screen.font, c);
+
+  /* Calculate actual character width for glyph.  */
+  char_width = calculate_character_width (glyph);
+
+  return char_width;
+}
+
+static grub_uint16_t
+grub_virtual_screen_getwh (void)
+{
+  return (virtual_screen.columns << 8) | virtual_screen.rows;
+}
+
+static grub_uint16_t
+grub_virtual_screen_getxy (void)
+{
+  return ((virtual_screen.cursor_x << 8) | virtual_screen.cursor_y);
+}
+
+static void
+grub_gfxterm_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  if (x >= virtual_screen.columns)
+    x = virtual_screen.columns - 1;
+
+  if (y >= virtual_screen.rows)
+    y = virtual_screen.rows - 1;
+
+  /* Erase current cursor, if any.  */
+  if (virtual_screen.cursor_state)
+    draw_cursor (0);
+
+  virtual_screen.cursor_x = x;
+  virtual_screen.cursor_y = y;
+
+  /* Draw cursor if visible.  */
+  if (virtual_screen.cursor_state)
+    draw_cursor (1);
+}
+
+static void
+grub_virtual_screen_cls (void)
+{
+  grub_uint32_t i;
+
+  for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
+    clear_char (&(virtual_screen.text_buffer[i]));
+
+  virtual_screen.cursor_x = virtual_screen.cursor_y = 0;
+}
+
+static void
+grub_gfxterm_cls (void)
+{
+  grub_video_color_t color;
+
+  /* Clear virtual screen.  */
+  grub_virtual_screen_cls ();
+
+  /* Clear text layer.  */
+  grub_video_set_active_render_target (text_layer);
+  color = virtual_screen.bg_color;
+  grub_video_fill_rect (color, 0, 0,
+                        virtual_screen.width, virtual_screen.height);
+  grub_video_set_active_render_target (render_target);
+
+  /* Mark virtual screen to be redrawn.  */
+  dirty_region_add_virtualscreen ();
+
+  grub_gfxterm_refresh ();
+}
+
+static void
+grub_virtual_screen_setcolorstate (grub_term_color_state state)
+{
+  switch (state)
+    {
+    case GRUB_TERM_COLOR_STANDARD:
+      virtual_screen.term_color = virtual_screen.standard_color_setting;
+      break;
+
+    case GRUB_TERM_COLOR_NORMAL:
+      virtual_screen.term_color = virtual_screen.normal_color_setting;
+      break;
+
+    case GRUB_TERM_COLOR_HIGHLIGHT:
+      virtual_screen.term_color = virtual_screen.highlight_color_setting;
+      break;
+
+    default:
+      break;
+    }
+
+  /* Change color to virtual terminal.  */
+  set_term_color (virtual_screen.term_color);
+}
+
+static void
+grub_virtual_screen_setcolor (grub_uint8_t normal_color,
+                              grub_uint8_t highlight_color)
+{
+  virtual_screen.normal_color_setting = normal_color;
+  virtual_screen.highlight_color_setting = highlight_color;
+}
+
+static void
+grub_virtual_screen_getcolor (grub_uint8_t *normal_color,
+                              grub_uint8_t *highlight_color)
+{
+  *normal_color = virtual_screen.normal_color_setting;
+  *highlight_color = virtual_screen.highlight_color_setting;
+}
+
+static void
+grub_gfxterm_setcursor (int on)
+{
+  if (virtual_screen.cursor_state != on)
+    {
+      if (virtual_screen.cursor_state)
+       draw_cursor (0);
+      else
+       draw_cursor (1);
+
+      virtual_screen.cursor_state = on;
+    }
+}
+
+static void
+grub_gfxterm_refresh (void)
+{
+  real_scroll ();
+
+  /* Redraw only changed regions.  */
+  dirty_region_redraw ();
+
+  grub_video_swap_buffers ();
+
+  if (window.double_repaint)
+    dirty_region_redraw ();
+  dirty_region_reset ();
+}
+
+void 
+grub_gfxterm_set_repaint_callback (grub_gfxterm_repaint_callback_t func)
+{
+  repaint_callback = func;
+}
+
+/* Option array indices.  */
+#define BACKGROUND_CMD_ARGINDEX_MODE 0
+
+static const struct grub_arg_option background_image_cmd_options[] =
+  {
+    {"mode", 'm', 0, "Background image mode.", "stretch|normal",
+     ARG_TYPE_STRING},
+    {0, 0, 0, 0, 0, 0}
+  };
+
+static grub_err_t
+grub_gfxterm_background_image_cmd (grub_extcmd_t cmd __attribute__ ((unused)),
+                                   int argc,
+                                   char **args)
+{
+  struct grub_arg_list *state = cmd->state;
+
+  /* Check that we have video adapter active.  */
+  if (grub_video_get_info(NULL) != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* Destroy existing background bitmap if loaded.  */
+  if (bitmap)
+    {
+      grub_video_bitmap_destroy (bitmap);
+      bitmap = 0;
+
+      /* Mark whole screen as dirty.  */
+      dirty_region_add (0, 0, window.width, window.height);
+    }
+
+  /* If filename was provided, try to load that.  */
+  if (argc >= 1)
+    {
+    /* Try to load new one.  */
+    grub_video_bitmap_load (&bitmap, args[0]);
+    if (grub_errno != GRUB_ERR_NONE)
+      return grub_errno;
+
+    /* Determine if the bitmap should be scaled to fit the screen.  */
+    if (!state[BACKGROUND_CMD_ARGINDEX_MODE].set
+        || grub_strcmp (state[BACKGROUND_CMD_ARGINDEX_MODE].arg,
+                        "stretch") == 0)
+        {
+          if (window.width != grub_video_bitmap_get_width (bitmap)
+              || window.height != grub_video_bitmap_get_height (bitmap))
+            {
+              struct grub_video_bitmap *scaled_bitmap;
+              grub_video_bitmap_create_scaled (&scaled_bitmap,
+                                               window.width, 
+                                               window.height,
+                                               bitmap,
+                                               GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
+              if (grub_errno == GRUB_ERR_NONE)
+                {
+                  /* Replace the original bitmap with the scaled one.  */
+                  grub_video_bitmap_destroy (bitmap);
+                  bitmap = scaled_bitmap;
+                }
+            }
+        }
+
+    /* If bitmap was loaded correctly, display it.  */
+    if (bitmap)
+      {
+        /* Determine bitmap dimensions.  */
+        bitmap_width = grub_video_bitmap_get_width (bitmap);
+        bitmap_height = grub_video_bitmap_get_height (bitmap);
+
+        /* Mark whole screen as dirty.  */
+        dirty_region_add (0, 0, window.width, window.height);
+      }
+    }
+
+  /* All was ok.  */
+  grub_errno = GRUB_ERR_NONE;
+  return grub_errno;
+}
+
+static struct grub_term_output grub_video_term =
+  {
+    .name = "gfxterm",
+    .init = grub_gfxterm_term_init,
+    .fini = grub_gfxterm_term_fini,
+    .putchar = grub_gfxterm_putchar,
+    .getcharwidth = grub_gfxterm_getcharwidth,
+    .getwh = grub_virtual_screen_getwh,
+    .getxy = grub_virtual_screen_getxy,
+    .gotoxy = grub_gfxterm_gotoxy,
+    .cls = grub_gfxterm_cls,
+    .setcolorstate = grub_virtual_screen_setcolorstate,
+    .setcolor = grub_virtual_screen_setcolor,
+    .getcolor = grub_virtual_screen_getcolor,
+    .setcursor = grub_gfxterm_setcursor,
+    .refresh = grub_gfxterm_refresh,
+    .flags = 0,
+    .next = 0
+  };
+
+static grub_extcmd_t background_image_cmd_handle;
+
+GRUB_MOD_INIT(gfxterm)
+{
+  grub_term_register_output ("gfxterm", &grub_video_term);
+  background_image_cmd_handle =
+    grub_register_extcmd ("background_image",
+                          grub_gfxterm_background_image_cmd,
+                          GRUB_COMMAND_FLAG_BOTH,
+                          N_("[-m (stretch|normal)] FILE"),
+                          N_("Load background image for active terminal."),
+                          background_image_cmd_options);
+}
+
+GRUB_MOD_FINI(gfxterm)
+{
+  grub_unregister_extcmd (background_image_cmd_handle);
+  grub_term_unregister_output (&grub_video_term);
+}
diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c
new file mode 100644 (file)
index 0000000..43cfe2f
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/machine/console.h>
+#include <grub/term.h>
+#include <grub/types.h>
+
+static const struct grub_machine_bios_data_area *bios_data_area =
+  (struct grub_machine_bios_data_area *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR;
+
+#define KEYBOARD_LEFT_SHIFT    (1 << 0)
+#define KEYBOARD_RIGHT_SHIFT   (1 << 1)
+#define KEYBOARD_CTRL          (1 << 2)
+#define KEYBOARD_ALT           (1 << 3)
+
+static int
+grub_console_getkeystatus (void)
+{
+  grub_uint8_t status = bios_data_area->keyboard_flag_lower;
+  int mods = 0;
+
+  if (status & (KEYBOARD_LEFT_SHIFT | KEYBOARD_RIGHT_SHIFT))
+    mods |= GRUB_TERM_STATUS_SHIFT;
+  if (status & KEYBOARD_CTRL)
+    mods |= GRUB_TERM_STATUS_CTRL;
+  if (status & KEYBOARD_ALT)
+    mods |= GRUB_TERM_STATUS_ALT;
+
+  return mods;
+}
+
+static struct grub_term_input grub_console_term_input =
+  {
+    .name = "console",
+    .checkkey = grub_console_checkkey,
+    .getkey = grub_console_getkey,
+    .getkeystatus = grub_console_getkeystatus,
+  };
+
+static struct grub_term_output grub_console_term_output =
+  {
+    .name = "console",
+    .putchar = grub_console_putchar,
+    .getcharwidth = grub_console_getcharwidth,
+    .getwh = grub_console_getwh,
+    .getxy = grub_console_getxy,
+    .gotoxy = grub_console_gotoxy,
+    .cls = grub_console_cls,
+    .setcolorstate = grub_console_setcolorstate,
+    .setcolor = grub_console_setcolor,
+    .getcolor = grub_console_getcolor,
+    .setcursor = grub_console_setcursor
+  };
+
+void
+grub_console_init (void)
+{
+  grub_term_register_output ("console", &grub_console_term_output);
+  grub_term_register_input ("console", &grub_console_term_input);
+}
+
+void
+grub_console_fini (void)
+{
+  grub_term_unregister_input (&grub_console_term_input);
+  grub_term_unregister_output (&grub_console_term_output);
+}
diff --git a/grub-core/term/i386/pc/vga.c b/grub-core/term/i386/pc/vga.c
new file mode 100644 (file)
index 0000000..402b30f
--- /dev/null
@@ -0,0 +1,513 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// TODO: Deprecated and broken. Needs to be converted to Video Driver!
+
+#include <grub/machine/vga.h>
+#include <grub/machine/console.h>
+#include <grub/cpu/io.h>
+#include <grub/term.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/font.h>
+
+#define DEBUG_VGA      0
+
+#define VGA_WIDTH      640
+#define VGA_HEIGHT     350
+#define CHAR_WIDTH     8
+#define CHAR_HEIGHT    16
+#define TEXT_WIDTH     (VGA_WIDTH / CHAR_WIDTH)
+#define TEXT_HEIGHT    (VGA_HEIGHT / CHAR_HEIGHT)
+#define VGA_MEM                ((grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR)
+#define PAGE_OFFSET(x) ((x) * (VGA_WIDTH * VGA_HEIGHT / 8))
+
+#define DEFAULT_FG_COLOR       0xa
+#define DEFAULT_BG_COLOR       0x0
+
+struct colored_char
+{
+  /* An Unicode codepoint.  */
+  grub_uint32_t code;
+
+  /* Color indexes.  */
+  unsigned char fg_color;
+  unsigned char bg_color;
+
+  /* The width of this character minus one.  */
+  unsigned char width;
+
+  /* The column index of this character.  */
+  unsigned char index;
+};
+
+static unsigned char text_mode;
+static unsigned xpos, ypos;
+static int cursor_state;
+static unsigned char fg_color, bg_color;
+static struct colored_char text_buf[TEXT_WIDTH * TEXT_HEIGHT];
+static unsigned char saved_map_mask;
+static int page = 0;
+static grub_font_t font = 0;
+
+#define SEQUENCER_ADDR_PORT    0x3C4
+#define SEQUENCER_DATA_PORT    0x3C5
+#define MAP_MASK_REGISTER      0x02
+
+#define CRTC_ADDR_PORT         0x3D4
+#define CRTC_DATA_PORT         0x3D5
+#define START_ADDR_HIGH_REGISTER 0x0C
+#define START_ADDR_LOW_REGISTER        0x0D
+
+#define GRAPHICS_ADDR_PORT     0x3CE
+#define GRAPHICS_DATA_PORT     0x3CF
+#define READ_MAP_REGISTER      0x04
+
+#define INPUT_STATUS1_REGISTER 0x3DA
+#define INPUT_STATUS1_VERTR_BIT 0x08
+
+static inline void
+wait_vretrace (void)
+{
+  /* Wait until there is a vertical retrace.  */
+  while (! (grub_inb (INPUT_STATUS1_REGISTER) & INPUT_STATUS1_VERTR_BIT));
+}
+
+/* Get Map Mask Register.  */
+static unsigned char
+get_map_mask (void)
+{
+  unsigned char old_addr;
+  unsigned char old_data;
+
+  old_addr = grub_inb (SEQUENCER_ADDR_PORT);
+  grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT);
+
+  old_data = grub_inb (SEQUENCER_DATA_PORT);
+
+  grub_outb (old_addr, SEQUENCER_ADDR_PORT);
+
+  return old_data;
+}
+
+/* Set Map Mask Register.  */
+static void
+set_map_mask (unsigned char mask)
+{
+  unsigned char old_addr;
+
+  old_addr = grub_inb (SEQUENCER_ADDR_PORT);
+  grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT);
+
+  grub_outb (mask, SEQUENCER_DATA_PORT);
+
+  grub_outb (old_addr, SEQUENCER_ADDR_PORT);
+}
+
+/* Set Read Map Register.  */
+static void
+set_read_map (unsigned char map)
+{
+  unsigned char old_addr;
+
+  old_addr = grub_inb (GRAPHICS_ADDR_PORT);
+
+  grub_outb (READ_MAP_REGISTER, GRAPHICS_ADDR_PORT);
+  grub_outb (map, GRAPHICS_DATA_PORT);
+
+  grub_outb (old_addr, GRAPHICS_ADDR_PORT);
+}
+
+/* Set start address.  */
+static void
+set_start_address (unsigned int start)
+{
+  unsigned char old_addr;
+
+  old_addr = grub_inb (CRTC_ADDR_PORT);
+
+  grub_outb (START_ADDR_LOW_REGISTER, CRTC_ADDR_PORT);
+  grub_outb (start & 0xFF, CRTC_DATA_PORT);
+
+  grub_outb (START_ADDR_HIGH_REGISTER, CRTC_ADDR_PORT);
+  grub_outb (start >> 8, CRTC_DATA_PORT);
+
+  grub_outb (old_addr, CRTC_ADDR_PORT);
+}
+
+static grub_err_t
+grub_vga_mod_init (void)
+{
+  text_mode = grub_vga_set_mode (0x10);
+  cursor_state = 1;
+  fg_color = DEFAULT_FG_COLOR;
+  bg_color = DEFAULT_BG_COLOR;
+  saved_map_mask = get_map_mask ();
+  set_map_mask (0x0f);
+  set_start_address (PAGE_OFFSET (page));
+  font = grub_font_get ("");  /* Choose any font, for now. */
+  if (!font)
+    return grub_error (GRUB_ERR_BAD_FONT, "no font loaded");
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_vga_mod_fini (void)
+{
+  set_map_mask (saved_map_mask);
+  grub_vga_set_mode (text_mode);
+  return GRUB_ERR_NONE;
+}
+
+static int
+check_vga_mem (void *p)
+{
+  return (p >= (void *) (VGA_MEM + PAGE_OFFSET (page))
+         && p <= (void *) (VGA_MEM + PAGE_OFFSET (page)
+                           + VGA_WIDTH * VGA_HEIGHT / 8));
+}
+
+static void
+write_char (void)
+{
+  struct colored_char *p = text_buf + xpos + ypos * TEXT_WIDTH;
+  struct grub_font_glyph *glyph;
+  unsigned char *mem_base;
+  unsigned plane;
+
+  mem_base = (VGA_MEM + xpos +
+             ypos * CHAR_HEIGHT * TEXT_WIDTH + PAGE_OFFSET (page)) - p->index;
+  p -= p->index;
+
+  /* Get glyph for character.  */
+  glyph = grub_font_get_glyph (font, p->code);
+
+  for (plane = 0x01; plane <= 0x08; plane <<= 1)
+    {
+      unsigned y;
+      unsigned offset;
+      unsigned char *mem;
+
+      set_map_mask (plane);
+
+      for (y = 0, offset = 0, mem = mem_base;
+          y < CHAR_HEIGHT;
+          y++, mem += TEXT_WIDTH)
+       {
+          /* TODO Re-implement glyph drawing for vga module.  */
+#if 0
+         unsigned i;
+
+          unsigned char_width = 1; /* TODO Figure out wide characters.  */
+         for (i = 0; i < char_width && offset < 32; i++)
+           {
+             unsigned char fg_mask, bg_mask;
+
+             fg_mask = (p->fg_color & plane) ? glyph->bitmap[offset] : 0;
+             bg_mask = (p->bg_color & plane) ? ~(glyph->bitmap[offset]) : 0;
+             offset++;
+
+             if (check_vga_mem (mem + i))
+               mem[i] = (fg_mask | bg_mask);
+           }
+#endif /* 0 */
+       }
+    }
+
+  set_map_mask (0x0f);
+}
+
+static void
+write_cursor (void)
+{
+  unsigned char *mem = (VGA_MEM + PAGE_OFFSET (page) + xpos
+                       + (ypos * CHAR_HEIGHT + CHAR_HEIGHT - 3) * TEXT_WIDTH);
+  if (check_vga_mem (mem))
+    *mem = 0xff;
+
+  mem += TEXT_WIDTH;
+  if (check_vga_mem (mem))
+    *mem = 0xff;
+}
+
+static void
+scroll_up (void)
+{
+  unsigned i;
+  unsigned plane;
+
+  /* Do all the work in the other page.  */
+  grub_memmove (text_buf, text_buf + TEXT_WIDTH,
+               sizeof (struct colored_char) * TEXT_WIDTH * (TEXT_HEIGHT - 1));
+
+  for (i = TEXT_WIDTH * (TEXT_HEIGHT - 1); i < TEXT_WIDTH * TEXT_HEIGHT; i++)
+    {
+      text_buf[i].code = ' ';
+      text_buf[i].fg_color = 0;
+      text_buf[i].bg_color = 0;
+      text_buf[i].width = 0;
+      text_buf[i].index = 0;
+    }
+
+  for (plane = 1; plane <= 4; plane++)
+    {
+      set_read_map (plane);
+      set_map_mask (1 << plane);
+      grub_memmove (VGA_MEM + PAGE_OFFSET (1 - page), VGA_MEM
+                   + PAGE_OFFSET (page) + VGA_WIDTH * CHAR_HEIGHT / 8,
+                   VGA_WIDTH * (VGA_HEIGHT - CHAR_HEIGHT) / 8);
+    }
+
+  set_map_mask (0x0f);
+  grub_memset (VGA_MEM + PAGE_OFFSET (1 - page)
+              + VGA_WIDTH * (VGA_HEIGHT - CHAR_HEIGHT) / 8, 0,
+              VGA_WIDTH * CHAR_HEIGHT / 8);
+
+  /* Activate the other page.  */
+  page = 1 - page;
+  wait_vretrace ();
+  set_start_address (PAGE_OFFSET (page));
+}
+
+static void
+grub_vga_putchar (grub_uint32_t c)
+{
+#if DEBUG_VGA
+  static int show = 1;
+#endif
+
+  if (c == '\a')
+    /* FIXME */
+    return;
+
+  if (c == '\b' || c == '\n' || c == '\r')
+    {
+      /* Erase current cursor, if any.  */
+      if (cursor_state)
+       write_char ();
+
+      switch (c)
+       {
+       case '\b':
+         if (xpos > 0)
+           xpos--;
+         break;
+
+       case '\n':
+         if (ypos >= TEXT_HEIGHT - 1)
+           scroll_up ();
+         else
+           ypos++;
+         break;
+
+       case '\r':
+         xpos = 0;
+         break;
+       }
+
+      if (cursor_state)
+       write_cursor ();
+    }
+  else
+    {
+      struct grub_font_glyph *glyph;
+      struct colored_char *p;
+      unsigned char_width = 1;
+
+      glyph = grub_font_get_glyph(font, c);
+
+      if (xpos + char_width > TEXT_WIDTH)
+       grub_putchar ('\n');
+
+      p = text_buf + xpos + ypos * TEXT_WIDTH;
+      p->code = c;
+      p->fg_color = fg_color;
+      p->bg_color = bg_color;
+      p->width = char_width - 1;
+      p->index = 0;
+
+      if (char_width > 1)
+       {
+         unsigned i;
+
+         for (i = 1; i < char_width; i++)
+           {
+             p[i].code = ' ';
+             p[i].width = char_width - 1;
+             p[i].index = i;
+           }
+       }
+
+      write_char ();
+
+      xpos += char_width;
+      if (xpos >= TEXT_WIDTH)
+       {
+         xpos = 0;
+
+         if (ypos >= TEXT_HEIGHT - 1)
+           scroll_up ();
+         else
+           ypos++;
+       }
+
+      if (cursor_state)
+       write_cursor ();
+    }
+
+#if DEBUG_VGA
+  if (show)
+    {
+      grub_uint16_t pos = grub_getxy ();
+
+      show = 0;
+      grub_gotoxy (0, 0);
+      grub_printf ("[%u:%u]", (unsigned) (pos >> 8), (unsigned) (pos & 0xff));
+      grub_gotoxy (pos >> 8, pos & 0xff);
+      show = 1;
+    }
+#endif
+}
+
+static grub_ssize_t
+grub_vga_getcharwidth (grub_uint32_t c)
+{
+#if 0
+  struct grub_font_glyph glyph;
+
+  glyph = grub_font_get_glyph (c);
+
+  return glyph.char_width;
+#else
+  (void) c;   /* Prevent warning.  */
+  return 1;   /* TODO Fix wide characters?  */
+#endif
+}
+
+static grub_uint16_t
+grub_vga_getwh (void)
+{
+  return (TEXT_WIDTH << 8) | TEXT_HEIGHT;
+}
+
+static grub_uint16_t
+grub_vga_getxy (void)
+{
+  return ((xpos << 8) | ypos);
+}
+
+static void
+grub_vga_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  if (x >= TEXT_WIDTH || y >= TEXT_HEIGHT)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)",
+                 (unsigned) x, (unsigned) y);
+      return;
+    }
+
+  if (cursor_state)
+    write_char ();
+
+  xpos = x;
+  ypos = y;
+
+  if (cursor_state)
+    write_cursor ();
+}
+
+static void
+grub_vga_cls (void)
+{
+  unsigned i;
+
+  wait_vretrace ();
+  for (i = 0; i < TEXT_WIDTH * TEXT_HEIGHT; i++)
+    {
+      text_buf[i].code = ' ';
+      text_buf[i].fg_color = 0;
+      text_buf[i].bg_color = 0;
+      text_buf[i].width = 0;
+      text_buf[i].index = 0;
+    }
+
+  grub_memset (VGA_MEM + PAGE_OFFSET (page), 0, VGA_WIDTH * VGA_HEIGHT / 8);
+
+  xpos = ypos = 0;
+}
+
+static void
+grub_vga_setcolorstate (grub_term_color_state state)
+{
+  switch (state)
+    {
+    case GRUB_TERM_COLOR_STANDARD:
+    case GRUB_TERM_COLOR_NORMAL:
+      fg_color = DEFAULT_FG_COLOR;
+      bg_color = DEFAULT_BG_COLOR;
+      break;
+    case GRUB_TERM_COLOR_HIGHLIGHT:
+      fg_color = DEFAULT_BG_COLOR;
+      bg_color = DEFAULT_FG_COLOR;
+      break;
+    default:
+      break;
+    }
+}
+
+static void
+grub_vga_setcursor (int on)
+{
+  if (cursor_state != on)
+    {
+      if (cursor_state)
+       write_char ();
+      else
+       write_cursor ();
+
+      cursor_state = on;
+    }
+}
+
+static struct grub_term_output grub_vga_term =
+  {
+    .name = "vga",
+    .init = grub_vga_mod_init,
+    .fini = grub_vga_mod_fini,
+    .putchar = grub_vga_putchar,
+    .getcharwidth = grub_vga_getcharwidth,
+    .getwh = grub_vga_getwh,
+    .getxy = grub_vga_getxy,
+    .gotoxy = grub_vga_gotoxy,
+    .cls = grub_vga_cls,
+    .setcolorstate = grub_vga_setcolorstate,
+    .setcursor = grub_vga_setcursor,
+    .flags = 0,
+  };
+
+GRUB_MOD_INIT(vga)
+{
+  grub_term_register_output ("vga", &grub_vga_term);
+}
+
+GRUB_MOD_FINI(vga)
+{
+  grub_term_unregister_output (&grub_vga_term);
+}
diff --git a/grub-core/term/i386/pc/vga_text.c b/grub-core/term/i386/pc/vga_text.c
new file mode 100644 (file)
index 0000000..f954cab
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007, 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/i386/vga_common.h>
+#include <grub/i386/io.h>
+#include <grub/types.h>
+
+#define COLS   80
+#define ROWS   25
+
+static int grub_curr_x, grub_curr_y;
+
+#define VGA_TEXT_SCREEN                0xb8000
+
+#define CRTC_ADDR_PORT         0x3D4
+#define CRTC_DATA_PORT         0x3D5
+
+#define CRTC_CURSOR            0x0a
+#define CRTC_CURSOR_ADDR_HIGH  0x0e
+#define CRTC_CURSOR_ADDR_LOW   0x0f
+
+#define CRTC_CURSOR_DISABLE    (1 << 5)
+
+static void
+screen_write_char (int x, int y, short c)
+{
+  ((short *) VGA_TEXT_SCREEN)[y * COLS + x] = c;
+}
+
+static short
+screen_read_char (int x, int y)
+{
+  return ((short *) VGA_TEXT_SCREEN)[y * COLS + x];
+}
+
+static void
+update_cursor (void)
+{
+  unsigned int pos = grub_curr_y * COLS + grub_curr_x;
+  grub_outb (CRTC_CURSOR_ADDR_HIGH, CRTC_ADDR_PORT);
+  grub_outb (pos >> 8, CRTC_DATA_PORT);
+  grub_outb (CRTC_CURSOR_ADDR_LOW, CRTC_ADDR_PORT);
+  grub_outb (pos & 0xFF, CRTC_DATA_PORT);
+}
+
+static void
+inc_y (void)
+{
+  grub_curr_x = 0;
+  if (grub_curr_y < ROWS - 1)
+    grub_curr_y++;
+  else
+    {
+      int x, y;
+      for (y = 0; y < ROWS; y++)
+        for (x = 0; x < COLS; x++)
+          screen_write_char (x, y, screen_read_char (x, y + 1));
+    }
+}
+
+static void
+inc_x (void)
+{
+  if (grub_curr_x >= COLS - 1)
+    inc_y ();
+  else
+    grub_curr_x++;
+}
+
+void
+grub_console_real_putchar (int c)
+{
+  switch (c)
+    {
+      case '\b':
+       if (grub_curr_x != 0)
+         screen_write_char (grub_curr_x--, grub_curr_y, ' ');
+       break;
+      case '\n':
+       inc_y ();
+       break;
+      case '\r':
+       grub_curr_x = 0;
+       break;
+      default:
+       screen_write_char (grub_curr_x,
+                          grub_curr_y, c | (grub_console_cur_color << 8));
+       inc_x ();
+    }
+
+  update_cursor ();
+}
+
+static grub_uint16_t
+grub_vga_text_getxy (void)
+{
+  return (grub_curr_x << 8) | grub_curr_y;
+}
+
+static void
+grub_vga_text_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  grub_curr_x = x;
+  grub_curr_y = y;
+  update_cursor ();
+}
+
+static void
+grub_vga_text_cls (void)
+{
+  int i;
+  for (i = 0; i < ROWS * COLS; i++)
+    ((short *) VGA_TEXT_SCREEN)[i] = ' ' | (grub_console_cur_color << 8);
+  grub_vga_text_gotoxy (0, 0);
+}
+
+static void
+grub_vga_text_setcursor (int on)
+{
+  grub_uint8_t old;
+  grub_outb (CRTC_CURSOR, CRTC_ADDR_PORT);
+  old = grub_inb (CRTC_DATA_PORT);
+  if (on)
+    grub_outb (old & ~CRTC_CURSOR_DISABLE, CRTC_DATA_PORT);
+  else
+    grub_outb (old | CRTC_CURSOR_DISABLE, CRTC_DATA_PORT);
+}
+
+static grub_err_t
+grub_vga_text_init_fini (void)
+{
+  grub_vga_text_cls ();
+  return 0;
+}
+
+static struct grub_term_output grub_vga_text_term =
+  {
+    .name = "vga_text",
+    .init = grub_vga_text_init_fini,
+    .fini = grub_vga_text_init_fini,
+    .putchar = grub_console_putchar,
+    .getcharwidth = grub_console_getcharwidth,
+    .getwh = grub_console_getwh,
+    .getxy = grub_vga_text_getxy,
+    .gotoxy = grub_vga_text_gotoxy,
+    .cls = grub_vga_text_cls,
+    .setcolorstate = grub_console_setcolorstate,
+    .setcolor = grub_console_setcolor,
+    .getcolor = grub_console_getcolor,
+    .setcursor = grub_vga_text_setcursor,
+  };
+
+GRUB_MOD_INIT(vga_text)
+{
+  grub_term_register_output ("vga_text", &grub_vga_text_term);
+}
+
+GRUB_MOD_FINI(vga_text)
+{
+  grub_term_unregister_output (&grub_vga_text_term);
+}
diff --git a/grub-core/term/i386/vga_common.c b/grub-core/term/i386/vga_common.c
new file mode 100644 (file)
index 0000000..131b43a
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2005,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/i386/vga_common.h>
+#include <grub/term.h>
+#include <grub/types.h>
+
+grub_uint8_t grub_console_cur_color = 0x7;
+static grub_uint8_t grub_console_standard_color = 0x7;
+static grub_uint8_t grub_console_normal_color = 0x7;
+static grub_uint8_t grub_console_highlight_color = 0x70;
+
+static grub_uint32_t
+map_char (grub_uint32_t c)
+{
+  if (c > 0x7f)
+    {
+      /* Map some unicode characters to the VGA font, if possible.  */
+      switch (c)
+       {
+       case 0x2190:    /* left arrow */
+         c = 0x1b;
+         break;
+       case 0x2191:    /* up arrow */
+         c = 0x18;
+         break;
+       case 0x2192:    /* right arrow */
+         c = 0x1a;
+         break;
+       case 0x2193:    /* down arrow */
+         c = 0x19;
+         break;
+       case 0x2501:    /* horizontal line */
+         c = 0xc4;
+         break;
+       case 0x2503:    /* vertical line */
+         c = 0xb3;
+         break;
+       case 0x250F:    /* upper-left corner */
+         c = 0xda;
+         break;
+       case 0x2513:    /* upper-right corner */
+         c = 0xbf;
+         break;
+       case 0x2517:    /* lower-left corner */
+         c = 0xc0;
+         break;
+       case 0x251B:    /* lower-right corner */
+         c = 0xd9;
+         break;
+
+       default:
+         c = '?';
+         break;
+       }
+    }
+
+  return c;
+}
+
+void
+grub_console_putchar (grub_uint32_t c)
+{
+  grub_console_real_putchar (map_char (c));
+}
+
+grub_ssize_t
+grub_console_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
+{
+  /* For now, every printable character has the width 1.  */
+  return 1;
+}
+
+grub_uint16_t
+grub_console_getwh (void)
+{
+  return (80 << 8) | 25;
+}
+
+void
+grub_console_setcolorstate (grub_term_color_state state)
+{
+  switch (state) {
+    case GRUB_TERM_COLOR_STANDARD:
+      grub_console_cur_color = grub_console_standard_color;
+      break;
+    case GRUB_TERM_COLOR_NORMAL:
+      grub_console_cur_color = grub_console_normal_color;
+      break;
+    case GRUB_TERM_COLOR_HIGHLIGHT:
+      grub_console_cur_color = grub_console_highlight_color;
+      break;
+    default:
+      break;
+  }
+}
+
+void
+grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
+{
+  grub_console_normal_color = normal_color;
+  grub_console_highlight_color = highlight_color;
+}
+
+void
+grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
+{
+  *normal_color = grub_console_normal_color;
+  *highlight_color = grub_console_highlight_color;
+}
diff --git a/grub-core/term/ieee1275/ofconsole.c b/grub-core/term/ieee1275/ofconsole.c
new file mode 100644 (file)
index 0000000..c0f895a
--- /dev/null
@@ -0,0 +1,515 @@
+/*  ofconsole.c -- Open Firmware console for GRUB.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/term.h>
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/time.h>
+#include <grub/machine/console.h>
+#include <grub/ieee1275/ieee1275.h>
+
+static grub_ieee1275_ihandle_t stdout_ihandle;
+static grub_ieee1275_ihandle_t stdin_ihandle;
+
+static grub_uint8_t grub_ofconsole_width;
+static grub_uint8_t grub_ofconsole_height;
+
+static int grub_curr_x;
+static int grub_curr_y;
+
+static int grub_keybuf;
+static int grub_buflen;
+
+struct color
+{
+  int red;
+  int green;
+  int blue;
+};
+
+static struct color colors[] =
+  {
+    // {R, G, B}
+    {0x00, 0x00, 0x00},
+    {0x00, 0x00, 0xA8}, // 1 = blue
+    {0x00, 0xA8, 0x00}, // 2 = green
+    {0x00, 0xA8, 0xA8}, // 3 = cyan
+    {0xA8, 0x00, 0x00}, // 4 = red
+    {0xA8, 0x00, 0xA8}, // 5 = magenta
+    {0xFE, 0xFE, 0x54}, // 6 = yellow
+    {0xFE, 0xFE, 0xFE}  // 7 = white
+  };
+
+static grub_uint8_t grub_ofconsole_normal_color = 0x7;
+static grub_uint8_t grub_ofconsole_highlight_color = 0x70;
+
+/* Write control characters to the console.  */
+static void
+grub_ofconsole_writeesc (const char *str)
+{
+  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI))
+    return;
+
+  while (*str)
+    {
+      char chr = *(str++);
+      grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
+    }
+
+}
+
+static void
+grub_ofconsole_putchar (grub_uint32_t c)
+{
+  char chr;
+
+  if (c > 0x7F)
+    {
+      /* Better than nothing.  */
+      switch (c)
+       {
+       case GRUB_TERM_DISP_LEFT:
+         c = '<';
+         break;
+         
+       case GRUB_TERM_DISP_UP:
+         c = '^';
+         break;
+
+       case GRUB_TERM_DISP_RIGHT:
+         c = '>';
+         break;
+
+       case GRUB_TERM_DISP_DOWN:
+         c = 'v';
+         break;
+
+       case GRUB_TERM_DISP_HLINE:
+         c = '-';
+         break;
+
+       case GRUB_TERM_DISP_VLINE:
+         c = '|';
+         break;
+
+       case GRUB_TERM_DISP_UL:
+       case GRUB_TERM_DISP_UR:
+       case GRUB_TERM_DISP_LL:
+       case GRUB_TERM_DISP_LR:
+         c = '+';
+         break;
+
+       default:
+         c = '?';
+         break;
+       }
+    }
+
+  chr = c;
+
+  if (c == '\n')
+    {
+      grub_curr_y++;
+      grub_curr_x = 0;
+    }
+  else if (c == '\r')
+    {
+      grub_curr_x = 0;
+    }
+  else
+    {
+      grub_curr_x++;
+      if (grub_curr_x >= grub_ofconsole_width)
+        {
+          grub_ofconsole_putchar ('\n');
+          grub_ofconsole_putchar ('\r');
+          grub_curr_x++;
+        }
+    }
+  grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
+}
+
+static grub_ssize_t
+grub_ofconsole_getcharwidth (grub_uint32_t c __attribute__((unused)))
+{
+  return 1;
+}
+
+static void
+grub_ofconsole_setcolorstate (grub_term_color_state state)
+{
+  char setcol[256];
+  int fg;
+  int bg;
+
+  switch (state)
+    {
+    case GRUB_TERM_COLOR_STANDARD:
+    case GRUB_TERM_COLOR_NORMAL:
+      fg = grub_ofconsole_normal_color & 0x0f;
+      bg = grub_ofconsole_normal_color >> 4;
+      break;
+    case GRUB_TERM_COLOR_HIGHLIGHT:
+      fg = grub_ofconsole_highlight_color & 0x0f;
+      bg = grub_ofconsole_highlight_color >> 4;
+      break;
+    default:
+      return;
+    }
+
+  grub_snprintf (setcol, sizeof (setcol), "\e[3%dm\e[4%dm", fg, bg);
+  grub_ofconsole_writeesc (setcol);
+}
+
+static void
+grub_ofconsole_setcolor (grub_uint8_t normal_color,
+                        grub_uint8_t highlight_color)
+{
+  /* Discard bright bit.  */
+  grub_ofconsole_normal_color = normal_color & 0x77;
+  grub_ofconsole_highlight_color = highlight_color & 0x77;
+}
+
+static void
+grub_ofconsole_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
+{
+  *normal_color = grub_ofconsole_normal_color;
+  *highlight_color = grub_ofconsole_highlight_color;
+}
+
+static int
+grub_ofconsole_readkey (int *key)
+{
+  char c;
+  grub_ssize_t actual = 0;
+
+  grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
+
+  if (actual > 0)
+    switch(c)
+      {
+      case 0x7f:
+        /* Backspace: Ctrl-h.  */
+        c = '\b'; 
+        break;
+      case '\e':
+       {
+         grub_uint64_t start;
+         grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
+
+         /* On 9600 we have to wait up to 12 milliseconds.  */
+         start = grub_get_time_ms ();
+         while (actual <= 0 && grub_get_time_ms () - start < 12)
+           grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
+
+         if (actual <= 0)
+           {
+             *key = '\e';
+             return 1;
+           }
+
+         if (c != '[')
+           return 0;
+         
+         grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
+
+         /* On 9600 we have to wait up to 12 milliseconds.  */
+         start = grub_get_time_ms ();
+         while (actual <= 0 && grub_get_time_ms () - start < 12)
+           grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
+         if (actual <= 0)
+           return 0;
+
+         switch (c)
+           {
+           case 'A':
+             /* Up: Ctrl-p.  */
+             c = GRUB_TERM_UP;
+             break;
+           case 'B':
+             /* Down: Ctrl-n.  */
+             c = GRUB_TERM_DOWN;
+             break;
+           case 'C':
+             /* Right: Ctrl-f.  */
+             c = GRUB_TERM_RIGHT;
+             break;
+           case 'D':
+             /* Left: Ctrl-b.  */
+             c = GRUB_TERM_LEFT;
+             break;
+           case '3':
+             {
+               grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
+               /* On 9600 we have to wait up to 12 milliseconds.  */
+               start = grub_get_time_ms ();
+               while (actual <= 0 && grub_get_time_ms () - start < 12)
+                 grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
+               
+               if (actual <= 0)
+                 return 0;
+           
+               /* Delete: Ctrl-d.  */
+               if (c == '~')
+                 c = GRUB_TERM_DC;
+               else
+                 return 0;
+               break;
+             }
+             break;
+           }
+       }
+      }
+
+  *key = c;
+  return actual > 0;
+}
+
+static int
+grub_ofconsole_checkkey (void)
+{
+  int key;
+  int read;
+
+  if (grub_buflen)
+    return 1;
+
+  read = grub_ofconsole_readkey (&key);
+  if (read)
+    {
+      grub_keybuf = key;
+      grub_buflen = 1;
+      return 1;
+    }
+
+  return -1;
+}
+
+static int
+grub_ofconsole_getkey (void)
+{
+  int key;
+
+  if (grub_buflen)
+    {
+      grub_buflen  =0;
+      return grub_keybuf;
+    }
+
+  while (! grub_ofconsole_readkey (&key));
+
+  return key;
+}
+
+static grub_uint16_t
+grub_ofconsole_getxy (void)
+{
+  return ((grub_curr_x - 1) << 8) | grub_curr_y;
+}
+
+static void
+grub_ofconsole_dimensions (void)
+{
+  grub_ieee1275_ihandle_t options;
+  grub_ssize_t lval;
+
+  if (! grub_ieee1275_finddevice ("/options", &options)
+      && options != (grub_ieee1275_ihandle_t) -1)
+    {
+      if (! grub_ieee1275_get_property_length (options, "screen-#columns",
+                                              &lval)
+         && lval >= 0 && lval < 1024)
+       {
+         char val[lval];
+
+         if (! grub_ieee1275_get_property (options, "screen-#columns",
+                                           val, lval, 0))
+           grub_ofconsole_width = (grub_uint8_t) grub_strtoul (val, 0, 10);
+       }
+      if (! grub_ieee1275_get_property_length (options, "screen-#rows", &lval)
+         && lval >= 0 && lval < 1024)
+       {
+         char val[lval];
+         if (! grub_ieee1275_get_property (options, "screen-#rows",
+                                           val, lval, 0))
+           grub_ofconsole_height = (grub_uint8_t) grub_strtoul (val, 0, 10);
+       }
+    }
+
+  /* Use a small console by default.  */
+  if (! grub_ofconsole_width)
+    grub_ofconsole_width = 80;
+  if (! grub_ofconsole_height)
+    grub_ofconsole_height = 24;
+}
+
+static grub_uint16_t
+grub_ofconsole_getwh (void)
+{
+  return (grub_ofconsole_width << 8) | grub_ofconsole_height;
+}
+
+static void
+grub_ofconsole_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI))
+    {
+      char s[256];
+      grub_curr_x = x;
+      grub_curr_y = y;
+
+      grub_snprintf (s, sizeof (s), "\e[%d;%dH", y + 1, x + 1);
+      grub_ofconsole_writeesc (s);
+    }
+  else
+    {
+      if ((y == grub_curr_y) && (x == grub_curr_x - 1))
+        {
+          char chr;
+
+          chr = '\b';
+          grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
+        }
+
+      grub_curr_x = x;
+      grub_curr_y = y;
+    }
+}
+
+static void
+grub_ofconsole_cls (void)
+{
+  /* Clear the screen.  Using serial console, screen(1) only recognizes the
+   * ANSI escape sequence.  Using video console, Apple Open Firmware (version
+   * 3.1.1) only recognizes the literal ^L.  So use both.  */
+  grub_ofconsole_writeesc ("\f\e[2J");
+  grub_ofconsole_gotoxy (0, 0);
+}
+
+static void
+grub_ofconsole_setcursor (int on)
+{
+  /* Understood by the Open Firmware flavour in OLPC.  */
+  if (on)
+    grub_ieee1275_interpret ("cursor-on", 0);
+  else
+    grub_ieee1275_interpret ("cursor-off", 0);
+}
+
+static void
+grub_ofconsole_refresh (void)
+{
+  /* Do nothing, the current console state is ok.  */
+}
+
+static grub_err_t
+grub_ofconsole_init_input (void)
+{
+  grub_ssize_t actual;
+
+  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdin", &stdin_ihandle,
+                                         sizeof stdin_ihandle, &actual)
+      || actual != sizeof stdin_ihandle)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot find stdin");
+
+  return 0;
+}
+
+static grub_err_t
+grub_ofconsole_init_output (void)
+{
+  grub_ssize_t actual;
+
+  /* The latest PowerMacs don't actually initialize the screen for us, so we
+   * use this trick to re-open the output device (but we avoid doing this on
+   * platforms where it's known to be broken). */
+  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT))
+    grub_ieee1275_interpret ("output-device output", 0);
+
+  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdout", &stdout_ihandle,
+                                         sizeof stdout_ihandle, &actual)
+      || actual != sizeof stdout_ihandle)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot find stdout");
+
+  /* Initialize colors.  */
+  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS))
+    {
+      unsigned col;
+      for (col = 0; col < ARRAY_SIZE (colors); col++)
+       grub_ieee1275_set_color (stdout_ihandle, col, colors[col].red,
+                                colors[col].green, colors[col].blue);
+
+    /* Set the right fg and bg colors.  */
+      grub_ofconsole_setcolorstate (GRUB_TERM_COLOR_NORMAL);
+    }
+
+  grub_ofconsole_dimensions ();
+
+  return 0;
+}
+
+static grub_err_t
+grub_ofconsole_fini (void)
+{
+  return 0;
+}
+
+
+\f
+static struct grub_term_input grub_ofconsole_term_input =
+  {
+    .name = "ofconsole",
+    .init = grub_ofconsole_init_input,
+    .fini = grub_ofconsole_fini,
+    .checkkey = grub_ofconsole_checkkey,
+    .getkey = grub_ofconsole_getkey,
+  };
+
+static struct grub_term_output grub_ofconsole_term_output =
+  {
+    .name = "ofconsole",
+    .init = grub_ofconsole_init_output,
+    .fini = grub_ofconsole_fini,
+    .putchar = grub_ofconsole_putchar,
+    .getcharwidth = grub_ofconsole_getcharwidth,
+    .getxy = grub_ofconsole_getxy,
+    .getwh = grub_ofconsole_getwh,
+    .gotoxy = grub_ofconsole_gotoxy,
+    .cls = grub_ofconsole_cls,
+    .setcolorstate = grub_ofconsole_setcolorstate,
+    .setcolor = grub_ofconsole_setcolor,
+    .getcolor = grub_ofconsole_getcolor,
+    .setcursor = grub_ofconsole_setcursor,
+    .refresh = grub_ofconsole_refresh
+  };
+
+void
+grub_console_init (void)
+{
+  grub_term_register_input ("ofconsole", &grub_ofconsole_term_input);
+  grub_term_register_output ("ofconsole", &grub_ofconsole_term_output);
+}
+
+void
+grub_console_fini (void)
+{
+  grub_term_unregister_input (&grub_ofconsole_term_input);
+  grub_term_unregister_output (&grub_ofconsole_term_output);
+}
diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c
new file mode 100644 (file)
index 0000000..2347bb3
--- /dev/null
@@ -0,0 +1,642 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/serial.h>
+#include <grub/term.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/terminfo.h>
+#include <grub/cpu/io.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+
+#define TEXT_WIDTH     80
+#define TEXT_HEIGHT    24
+
+static unsigned int xpos, ypos;
+static unsigned int keep_track = 1;
+static unsigned int registered = 0;
+
+/* An input buffer.  */
+static char input_buf[8];
+static unsigned int npending = 0;
+
+static struct grub_term_output grub_serial_term_output;
+
+/* Argument options.  */
+static const struct grub_arg_option options[] =
+{
+  {"unit",   'u', 0, N_("Set the serial unit."),             0, ARG_TYPE_INT},
+  {"port",   'p', 0, N_("Set the serial port address."),     0, ARG_TYPE_STRING},
+  {"speed",  's', 0, N_("Set the serial port speed."),       0, ARG_TYPE_INT},
+  {"word",   'w', 0, N_("Set the serial port word length."), 0, ARG_TYPE_INT},
+  {"parity", 'r', 0, N_("Set the serial port parity."),      0, ARG_TYPE_STRING},
+  {"stop",   't', 0, N_("Set the serial port stop bits."),   0, ARG_TYPE_INT},
+  {0, 0, 0, 0, 0, 0}
+};
+
+/* Serial port settings.  */
+struct serial_port
+{
+  grub_port_t port;
+  unsigned short divisor;
+  unsigned short word_len;
+  unsigned int   parity;
+  unsigned short stop_bits;
+};
+
+/* Serial port settings.  */
+static struct serial_port serial_settings;
+
+#ifdef GRUB_MACHINE_PCBIOS
+static const unsigned short *serial_hw_io_addr = (const unsigned short *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR;
+#define GRUB_SERIAL_PORT_NUM 4
+#else
+#include <grub/machine/serial.h>
+static const grub_port_t serial_hw_io_addr[] = GRUB_MACHINE_SERIAL_PORTS;
+#define GRUB_SERIAL_PORT_NUM (ARRAY_SIZE(serial_hw_io_addr))
+#endif
+
+/* Return the port number for the UNITth serial device.  */
+static inline grub_port_t
+serial_hw_get_port (const unsigned int unit)
+{
+  if (unit < GRUB_SERIAL_PORT_NUM)
+    return serial_hw_io_addr[unit];
+  else
+    return 0;
+}
+
+/* Fetch a key.  */
+static int
+serial_hw_fetch (void)
+{
+  if (grub_inb (serial_settings.port + UART_LSR) & UART_DATA_READY)
+    return grub_inb (serial_settings.port + UART_RX);
+
+  return -1;
+}
+
+/* Put a character.  */
+static void
+serial_hw_put (const int c)
+{
+  unsigned int timeout = 100000;
+
+  /* Wait until the transmitter holding register is empty.  */
+  while ((grub_inb (serial_settings.port + UART_LSR) & UART_EMPTY_TRANSMITTER) == 0)
+    {
+      if (--timeout == 0)
+        /* There is something wrong. But what can I do?  */
+        return;
+    }
+
+  grub_outb (c, serial_settings.port + UART_TX);
+}
+
+static void
+serial_translate_key_sequence (void)
+{
+  unsigned int i;
+  static struct
+  {
+    char key;
+    char ascii;
+  }
+  three_code_table[] =
+    {
+      {'A', 16},
+      {'B', 14},
+      {'C', 6},
+      {'D', 2},
+      {'F', 5},
+      {'H', 1},
+      {'4', 4}
+    };
+
+  static struct
+  {
+      short key;
+      char ascii;
+  }
+  four_code_table[] =
+    {
+      {('1' | ('~' << 8)), 1},
+      {('3' | ('~' << 8)), 4},
+      {('5' | ('~' << 8)), 7},
+      {('6' | ('~' << 8)), 3}
+    };
+
+  if (npending < 3)
+    return;
+
+  /* The buffer must start with "ESC [".  */
+  if (input_buf[0] != '\e' || input_buf[1] != '[')
+    return;
+
+  for (i = 0; i < ARRAY_SIZE (three_code_table); i++)
+    if (three_code_table[i].key == input_buf[2])
+      {
+       input_buf[0] = three_code_table[i].ascii;
+       npending -= 2;
+       grub_memmove (input_buf + 1, input_buf + 3, npending - 1);
+       return;
+      }
+
+  if (npending >= 4)
+    {
+      short key = input_buf[3] | (input_buf[4] << 8);
+
+      for (i = 0; i < ARRAY_SIZE (four_code_table); i++)
+       if (four_code_table[i].key == key)
+         {
+           input_buf[0] = four_code_table[i].ascii;
+           npending -= 3;
+           grub_memmove (input_buf + 1, input_buf + 4, npending - 1);
+           return;
+         }
+    }
+}
+
+static int
+fill_input_buf (const int nowait)
+{
+  int i;
+
+  for (i = 0; i < 10000 && npending < sizeof (input_buf); i++)
+    {
+      int c;
+
+      c = serial_hw_fetch ();
+      if (c >= 0)
+       {
+         input_buf[npending++] = c;
+
+         /* Reset the counter to zero, to wait for the same interval.  */
+         i = 0;
+       }
+
+      if (nowait)
+       break;
+    }
+
+  /* Translate some key sequences.  */
+  serial_translate_key_sequence ();
+
+  return npending;
+}
+
+/* Convert speed to divisor.  */
+static unsigned short
+serial_get_divisor (unsigned int speed)
+{
+  unsigned int i;
+
+  /* The structure for speed vs. divisor.  */
+  struct divisor
+  {
+    unsigned int speed;
+    unsigned short div;
+  };
+
+  /* The table which lists common configurations.  */
+  /* 1843200 / (speed * 16)  */
+  static struct divisor divisor_tab[] =
+    {
+      { 2400,   0x0030 },
+      { 4800,   0x0018 },
+      { 9600,   0x000C },
+      { 19200,  0x0006 },
+      { 38400,  0x0003 },
+      { 57600,  0x0002 },
+      { 115200, 0x0001 }
+    };
+
+  /* Set the baud rate.  */
+  for (i = 0; i < sizeof (divisor_tab) / sizeof (divisor_tab[0]); i++)
+    if (divisor_tab[i].speed == speed)
+  /* UART in Yeeloong runs twice the usual rate.  */
+#ifdef GRUB_MACHINE_MIPS_YEELOONG
+      return 2 * divisor_tab[i].div;
+#else
+      return divisor_tab[i].div;
+#endif
+  return 0;
+}
+
+/* The serial version of checkkey.  */
+static int
+grub_serial_checkkey (void)
+{
+  if (fill_input_buf (1))
+    return input_buf[0];
+  else
+    return -1;
+}
+
+/* The serial version of getkey.  */
+static int
+grub_serial_getkey (void)
+{
+  int c;
+
+  while (! fill_input_buf (0))
+    ;
+
+  c = input_buf[0];
+  if (c == 0x7f)
+    c = GRUB_TERM_BACKSPACE;
+
+  grub_memmove (input_buf, input_buf + 1, --npending);
+
+  return c;
+}
+
+/* Initialize a serial device. PORT is the port number for a serial device.
+   SPEED is a DTE-DTE speed which must be one of these: 2400, 4800, 9600,
+   19200, 38400, 57600 and 115200. WORD_LEN is the word length to be used
+   for the device. Likewise, PARITY is the type of the parity and
+   STOP_BIT_LEN is the length of the stop bit. The possible values for
+   WORD_LEN, PARITY and STOP_BIT_LEN are defined in the header file as
+   macros.  */
+static grub_err_t
+serial_hw_init (void)
+{
+  unsigned char status = 0;
+
+  /* Turn off the interrupt.  */
+  grub_outb (0, serial_settings.port + UART_IER);
+
+  /* Set DLAB.  */
+  grub_outb (UART_DLAB, serial_settings.port + UART_LCR);
+
+  /* Set the baud rate.  */
+  grub_outb (serial_settings.divisor & 0xFF, serial_settings.port + UART_DLL);
+  grub_outb (serial_settings.divisor >> 8, serial_settings.port + UART_DLH);
+
+  /* Set the line status.  */
+  status |= (serial_settings.parity
+            | serial_settings.word_len
+            | serial_settings.stop_bits);
+  grub_outb (status, serial_settings.port + UART_LCR);
+
+  /* In Yeeloong serial port has only 3 wires.  */
+#ifndef GRUB_MACHINE_MIPS_YEELOONG
+  /* Enable the FIFO.  */
+  grub_outb (UART_ENABLE_FIFO, serial_settings.port + UART_FCR);
+
+  /* Turn on DTR, RTS, and OUT2.  */
+  grub_outb (UART_ENABLE_MODEM, serial_settings.port + UART_MCR);
+#endif
+
+  /* Drain the input buffer.  */
+  while (grub_serial_checkkey () != -1)
+    (void) grub_serial_getkey ();
+
+  /*  FIXME: should check if the serial terminal was found.  */
+
+  return GRUB_ERR_NONE;
+}
+
+/* The serial version of putchar.  */
+static void
+grub_serial_putchar (grub_uint32_t c)
+{
+  /* Keep track of the cursor.  */
+  if (keep_track)
+    {
+      /* The serial terminal does not have VGA fonts.  */
+      if (c > 0x7F)
+       {
+         /* Better than nothing.  */
+         switch (c)
+           {
+           case GRUB_TERM_DISP_LEFT:
+             c = '<';
+             break;
+
+           case GRUB_TERM_DISP_UP:
+             c = '^';
+             break;
+
+           case GRUB_TERM_DISP_RIGHT:
+             c = '>';
+             break;
+
+           case GRUB_TERM_DISP_DOWN:
+             c = 'v';
+             break;
+
+           case GRUB_TERM_DISP_HLINE:
+             c = '-';
+             break;
+
+           case GRUB_TERM_DISP_VLINE:
+             c = '|';
+             break;
+
+           case GRUB_TERM_DISP_UL:
+           case GRUB_TERM_DISP_UR:
+           case GRUB_TERM_DISP_LL:
+           case GRUB_TERM_DISP_LR:
+             c = '+';
+             break;
+
+           default:
+             c = '?';
+             break;
+           }
+       }
+
+      switch (c)
+       {
+       case '\a':
+         break;
+
+       case '\b':
+       case 127:
+         if (xpos > 0)
+           xpos--;
+         break;
+
+       case '\n':
+         if (ypos < TEXT_HEIGHT - 1)
+           ypos++;
+         break;
+
+       case '\r':
+         xpos = 0;
+         break;
+
+       default:
+         if (xpos >= TEXT_WIDTH)
+           {
+             grub_putchar ('\r');
+             grub_putchar ('\n');
+           }
+         xpos++;
+         break;
+       }
+    }
+
+  serial_hw_put (c);
+}
+
+static grub_ssize_t
+grub_serial_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
+{
+  return 1;
+}
+
+static grub_uint16_t
+grub_serial_getwh (void)
+{
+  return (TEXT_WIDTH << 8) | TEXT_HEIGHT;
+}
+
+static grub_uint16_t
+grub_serial_getxy (void)
+{
+  return ((xpos << 8) | ypos);
+}
+
+static void
+grub_serial_gotoxy (grub_uint8_t x, grub_uint8_t y)
+{
+  if (x > TEXT_WIDTH || y > TEXT_HEIGHT)
+    {
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)", x, y);
+    }
+  else
+    {
+      keep_track = 0;
+      grub_terminfo_gotoxy (x, y, &grub_serial_term_output);
+      keep_track = 1;
+
+      xpos = x;
+      ypos = y;
+    }
+}
+
+static void
+grub_serial_cls (void)
+{
+  keep_track = 0;
+  grub_terminfo_cls (&grub_serial_term_output);
+  keep_track = 1;
+
+  xpos = ypos = 0;
+}
+
+static void
+grub_serial_setcolorstate (const grub_term_color_state state)
+{
+  keep_track = 0;
+  switch (state)
+    {
+    case GRUB_TERM_COLOR_STANDARD:
+    case GRUB_TERM_COLOR_NORMAL:
+      grub_terminfo_reverse_video_off (&grub_serial_term_output);
+      break;
+    case GRUB_TERM_COLOR_HIGHLIGHT:
+      grub_terminfo_reverse_video_on (&grub_serial_term_output);
+      break;
+    default:
+      break;
+    }
+  keep_track = 1;
+}
+
+static void
+grub_serial_setcursor (const int on)
+{
+  if (on)
+    grub_terminfo_cursor_on (&grub_serial_term_output);
+  else
+    grub_terminfo_cursor_off (&grub_serial_term_output);
+}
+
+static struct grub_term_input grub_serial_term_input =
+{
+  .name = "serial",
+  .checkkey = grub_serial_checkkey,
+  .getkey = grub_serial_getkey,
+};
+
+static struct grub_term_output grub_serial_term_output =
+{
+  .name = "serial",
+  .putchar = grub_serial_putchar,
+  .getcharwidth = grub_serial_getcharwidth,
+  .getwh = grub_serial_getwh,
+  .getxy = grub_serial_getxy,
+  .gotoxy = grub_serial_gotoxy,
+  .cls = grub_serial_cls,
+  .setcolorstate = grub_serial_setcolorstate,
+  .setcursor = grub_serial_setcursor,
+  .flags = 0,
+};
+
+\f
+
+static grub_err_t
+grub_cmd_serial (grub_extcmd_t cmd,
+                 int argc __attribute__ ((unused)),
+                char **args __attribute__ ((unused)))
+{
+  struct grub_arg_list *state = cmd->state;
+  struct serial_port backup_settings = serial_settings;
+  grub_err_t hwiniterr;
+
+  if (state[0].set)
+    {
+      unsigned int unit;
+
+      unit = grub_strtoul (state[0].arg, 0, 0);
+      serial_settings.port = serial_hw_get_port (unit);
+      if (!serial_settings.port)
+       return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad unit number");
+    }
+
+  if (state[1].set)
+    serial_settings.port = (grub_port_t) grub_strtoul (state[1].arg, 0, 0);
+
+  if (state[2].set)
+    {
+      unsigned long speed;
+
+      speed = grub_strtoul (state[2].arg, 0, 0);
+      serial_settings.divisor = serial_get_divisor ((unsigned int) speed);
+      if (serial_settings.divisor == 0)
+       {
+         serial_settings = backup_settings;
+         return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad speed");
+       }
+    }
+
+  if (state[3].set)
+    {
+      if (! grub_strcmp (state[3].arg, "5"))
+       serial_settings.word_len = UART_5BITS_WORD;
+      else if (! grub_strcmp (state[3].arg, "6"))
+       serial_settings.word_len = UART_6BITS_WORD;
+      else if (! grub_strcmp (state[3].arg, "7"))
+       serial_settings.word_len = UART_7BITS_WORD;
+      else if (! grub_strcmp (state[3].arg, "8"))
+       serial_settings.word_len = UART_8BITS_WORD;
+      else
+       {
+         serial_settings = backup_settings;
+         return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad word length");
+       }
+    }
+
+  if (state[4].set)
+    {
+      if (! grub_strcmp (state[4].arg, "no"))
+       serial_settings.parity = UART_NO_PARITY;
+      else if (! grub_strcmp (state[4].arg, "odd"))
+       serial_settings.parity = UART_ODD_PARITY;
+      else if (! grub_strcmp (state[4].arg, "even"))
+       serial_settings.parity = UART_EVEN_PARITY;
+      else
+       {
+         serial_settings = backup_settings;
+         return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad parity");
+       }
+    }
+
+  if (state[5].set)
+    {
+      if (! grub_strcmp (state[5].arg, "1"))
+       serial_settings.stop_bits = UART_1_STOP_BIT;
+      else if (! grub_strcmp (state[5].arg, "2"))
+       serial_settings.stop_bits = UART_2_STOP_BITS;
+      else
+       {
+         serial_settings = backup_settings;
+         return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad number of stop bits");
+       }
+    }
+
+  /* Initialize with new settings.  */
+  hwiniterr = serial_hw_init ();
+
+  if (hwiniterr == GRUB_ERR_NONE)
+    {
+      /* Register terminal if not yet registered.  */
+      if (registered == 0)
+       {
+         grub_term_register_input ("serial", &grub_serial_term_input);
+         grub_term_register_output ("serial", &grub_serial_term_output);
+         registered = 1;
+       }
+    }
+  else
+    {
+      /* Initialization with new settings failed.  */
+      if (registered == 1)
+       {
+         /* If the terminal is registered, attempt to restore previous
+            settings.  */
+         serial_settings = backup_settings;
+         if (serial_hw_init () != GRUB_ERR_NONE)
+           {
+             /* If unable to restore settings, unregister terminal.  */
+             grub_term_unregister_input (&grub_serial_term_input);
+             grub_term_unregister_output (&grub_serial_term_output);
+             registered = 0;
+           }
+       }
+    }
+
+  return hwiniterr;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(serial)
+{
+  cmd = grub_register_extcmd ("serial", grub_cmd_serial,
+                             GRUB_COMMAND_FLAG_BOTH,
+                             N_("[OPTIONS...]"),
+                             N_("Configure serial port."), options);
+
+  /* Set default settings.  */
+  serial_settings.port      = serial_hw_get_port (0);
+#ifdef GRUB_MACHINE_MIPS_YEELOONG
+  serial_settings.divisor   = serial_get_divisor (115200);
+#else
+  serial_settings.divisor   = serial_get_divisor (9600);
+#endif
+  serial_settings.word_len  = UART_8BITS_WORD;
+  serial_settings.parity    = UART_NO_PARITY;
+  serial_settings.stop_bits = UART_1_STOP_BIT;
+}
+
+GRUB_MOD_FINI(serial)
+{
+  grub_unregister_extcmd (cmd);
+  if (registered == 1)         /* Unregister terminal only if registered. */
+    {
+      grub_term_unregister_input (&grub_serial_term_input);
+      grub_term_unregister_output (&grub_serial_term_output);
+    }
+}
diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c
new file mode 100644 (file)
index 0000000..7402d23
--- /dev/null
@@ -0,0 +1,189 @@
+/* terminfo.c - simple terminfo module */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This file contains various functions dealing with different
+ * terminal capabilities. For example, vt52 and vt100.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/term.h>
+#include <grub/terminfo.h>
+#include <grub/tparm.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+
+struct terminfo
+{
+  char *name;
+
+  char *gotoxy;
+  char *cls;
+  char *reverse_video_on;
+  char *reverse_video_off;
+  char *cursor_on;
+  char *cursor_off;
+};
+
+static struct terminfo term;
+
+/* Get current terminfo name.  */
+char *
+grub_terminfo_get_current (void)
+{
+  return term.name;
+}
+
+/* Free *PTR and set *PTR to NULL, to prevent double-free.  */
+static void
+grub_terminfo_free (char **ptr)
+{
+  grub_free (*ptr);
+  *ptr = 0;
+}
+
+/* Set current terminfo type.  */
+grub_err_t
+grub_terminfo_set_current (const char *str)
+{
+  /* TODO
+   * Lookup user specified terminfo type. If found, set term variables
+   * as appropriate. Otherwise return an error.
+   *
+   * How should this be done?
+   *  a. A static table included in this module.
+   *     - I do not like this idea.
+   *  b. A table stored in the configuration directory.
+   *     - Users must convert their terminfo settings if we have not already.
+   *  c. Look for terminfo files in the configuration directory.
+   *     - /usr/share/terminfo is 6.3M on my system.
+   *     - /usr/share/terminfo is not on most users boot partition.
+   *     + Copying the terminfo files you want to use to the grub
+   *       configuration directory is easier then (b).
+   *  d. Your idea here.
+   */
+
+  /* Free previously allocated memory.  */
+  grub_terminfo_free (&term.name);
+  grub_terminfo_free (&term.gotoxy);
+  grub_terminfo_free (&term.cls);
+  grub_terminfo_free (&term.reverse_video_on);
+  grub_terminfo_free (&term.reverse_video_off);
+  grub_terminfo_free (&term.cursor_on);
+  grub_terminfo_free (&term.cursor_off);
+
+  if (grub_strcmp ("vt100", str) == 0)
+    {
+      term.name              = grub_strdup ("vt100");
+      term.gotoxy            = grub_strdup ("\e[%i%p1%d;%p2%dH");
+      term.cls               = grub_strdup ("\e[H\e[J");
+      term.reverse_video_on  = grub_strdup ("\e[7m");
+      term.reverse_video_off = grub_strdup ("\e[m");
+      term.cursor_on         = grub_strdup ("\e[?25h");
+      term.cursor_off        = grub_strdup ("\e[?25l");
+      return grub_errno;
+    }
+
+  return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminfo type");
+}
+
+/* Wrapper for grub_putchar to write strings.  */
+static void
+putstr (const char *str, grub_term_output_t oterm)
+{
+  while (*str)
+    grub_putcode (*str++, oterm);
+}
+
+/* Move the cursor to the given position starting with "0".  */
+void
+grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y, grub_term_output_t oterm)
+{
+  putstr (grub_terminfo_tparm (term.gotoxy, y, x), oterm);
+}
+
+/* Clear the screen.  */
+void
+grub_terminfo_cls (grub_term_output_t oterm)
+{
+  putstr (grub_terminfo_tparm (term.cls), oterm);
+}
+
+/* Set reverse video mode on.  */
+void
+grub_terminfo_reverse_video_on (grub_term_output_t oterm)
+{
+  putstr (grub_terminfo_tparm (term.reverse_video_on), oterm);
+}
+
+/* Set reverse video mode off.  */
+void
+grub_terminfo_reverse_video_off (grub_term_output_t oterm)
+{
+  putstr (grub_terminfo_tparm (term.reverse_video_off), oterm);
+}
+
+/* Show cursor.  */
+void
+grub_terminfo_cursor_on (grub_term_output_t oterm)
+{
+  putstr (grub_terminfo_tparm (term.cursor_on), oterm);
+}
+
+/* Hide cursor.  */
+void
+grub_terminfo_cursor_off (grub_term_output_t oterm)
+{
+  putstr (grub_terminfo_tparm (term.cursor_off), oterm);
+}
+
+/* GRUB Command.  */
+
+static grub_err_t
+grub_cmd_terminfo (grub_command_t cmd __attribute__ ((unused)),
+                  int argc, char **args)
+{
+  if (argc == 0)
+  {
+    grub_printf ("Current terminfo type: %s\n", grub_terminfo_get_current());
+    return GRUB_ERR_NONE;
+  }
+  else if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters");
+  else
+    return grub_terminfo_set_current (args[0]);
+}
+
+static grub_command_t cmd;
+
+GRUB_MOD_INIT(terminfo)
+{
+  cmd = grub_register_command ("terminfo", grub_cmd_terminfo,
+                              N_("[TERM]"), N_("Set terminfo type."));
+  grub_terminfo_set_current ("vt100");
+}
+
+GRUB_MOD_FINI(terminfo)
+{
+  grub_unregister_command (cmd);
+}
diff --git a/grub-core/term/tparm.c b/grub-core/term/tparm.c
new file mode 100644 (file)
index 0000000..adf0b3a
--- /dev/null
@@ -0,0 +1,758 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1998-2003,2004,2005 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**********************************************************************
+ * This code is a modification of lib_tparm.c found in ncurses-5.2. The
+ * modification are for use in grub by replacing all libc function through
+ * special grub functions. This also meant to delete all dynamic memory
+ * allocation and replace it by a number of fixed buffers.
+ *
+ * Modifications by Tilmann Bubeck <t.bubeck@reinform.de> 2002
+ *
+ * Resync with ncurses-5.4 by Omniflux <omniflux+devel@omniflux.com> 2005
+ **********************************************************************/
+
+/****************************************************************************
+ *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
+ *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
+ *     and: Thomas E. Dickey, 1996 on                                       *
+ ****************************************************************************/
+
+/*
+ *     tparm.c
+ *
+ */
+
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/tparm.h>
+
+/*
+ * Common/troublesome character definitions
+ */
+typedef char grub_bool_t;
+#ifndef FALSE
+# define FALSE (0)
+#endif
+#ifndef TRUE
+# define TRUE (!FALSE)
+#endif
+
+#define NUM_PARM 9
+#define NUM_VARS 26
+#define STACKSIZE 20
+#define MAX_FORMAT_LEN 256
+
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#define isdigit(c) ((c) >= '0' && (c) <= '9')
+#define isUPPER(c) ((c) >= 'A' && (c) <= 'Z')
+#define isLOWER(c) ((c) >= 'a' && (c) <= 'z')
+
+#define UChar(c) ((unsigned char)(c))
+
+//MODULE_ID("$Id$")
+
+/*
+ *     char *
+ *     tparm(string, ...)
+ *
+ *     Substitute the given parameters into the given string by the following
+ *     rules (taken from terminfo(5)):
+ *
+ *          Cursor addressing and other strings  requiring  parame-
+ *     ters in the terminal are described by a parameterized string
+ *     capability, with like escapes %x in  it.   For  example,  to
+ *     address  the  cursor, the cup capability is given, using two
+ *     parameters: the row and column to  address  to.   (Rows  and
+ *     columns  are  numbered  from  zero and refer to the physical
+ *     screen visible to the user, not to any  unseen  memory.)  If
+ *     the terminal has memory relative cursor addressing, that can
+ *     be indicated by
+ *
+ *          The parameter mechanism uses  a  stack  and  special  %
+ *     codes  to manipulate it.  Typically a sequence will push one
+ *     of the parameters onto the stack and then print it  in  some
+ *     format.  Often more complex operations are necessary.
+ *
+ *          The % encodings have the following meanings:
+ *
+ *          %%        outputs `%'
+ *          %c        print pop() like %c in printf()
+ *          %s        print pop() like %s in printf()
+ *           %[[:]flags][width[.precision]][doxXs]
+ *                     as in printf, flags are [-+#] and space
+ *                     The ':' is used to avoid making %+ or %-
+ *                     patterns (see below).
+ *
+ *          %p[1-9]   push ith parm
+ *          %P[a-z]   set dynamic variable [a-z] to pop()
+ *          %g[a-z]   get dynamic variable [a-z] and push it
+ *          %P[A-Z]   set static variable [A-Z] to pop()
+ *          %g[A-Z]   get static variable [A-Z] and push it
+ *          %l        push strlen(pop)
+ *          %'c'      push char constant c
+ *          %{nn}     push integer constant nn
+ *
+ *          %+ %- %* %/ %m
+ *                    arithmetic (%m is mod): push(pop() op pop())
+ *          %& %| %^  bit operations: push(pop() op pop())
+ *          %= %> %<  logical operations: push(pop() op pop())
+ *          %A %O     logical and & or operations for conditionals
+ *          %! %~     unary operations push(op pop())
+ *          %i        add 1 to first two parms (for ANSI terminals)
+ *
+ *          %? expr %t thenpart %e elsepart %;
+ *                    if-then-else, %e elsepart is optional.
+ *                    else-if's are possible ala Algol 68:
+ *                    %? c1 %t b1 %e c2 %t b2 %e c3 %t b3 %e c4 %t b4 %e b5 %;
+ *
+ *     For those of the above operators which are binary and not commutative,
+ *     the stack works in the usual way, with
+ *                     %gx %gy %m
+ *     resulting in x mod y, not the reverse.
+ */
+
+typedef struct {
+    union {
+       int num;
+       char *str;
+    } data;
+    grub_bool_t num_type;
+} stack_frame;
+
+static stack_frame stack[STACKSIZE];
+static int stack_ptr;
+static const char *tparam_base = "";
+
+static char *out_buff;
+static grub_size_t out_size;
+static grub_size_t out_used;
+
+static char *fmt_buff;
+static grub_size_t fmt_size;
+
+static inline void
+get_space(grub_size_t need)
+{
+    need += out_used;
+    if (need > out_size) {
+       out_size = need * 2;
+       out_buff = grub_realloc(out_buff, out_size*sizeof(char));
+       /* FIX ME! handle out_buff == 0.  */
+    }
+}
+
+static inline void
+save_text(const char *fmt, const char *s, int len)
+{
+    grub_size_t s_len = grub_strlen(s);
+    if (len > (int) s_len)
+       s_len = len;
+
+    get_space(s_len + 1);
+
+    (void) grub_snprintf(out_buff + out_used, s_len + 1, fmt, s);
+    out_used += grub_strlen(out_buff + out_used);
+}
+
+static inline void
+save_number(const char *fmt, int number, int len)
+{
+    if (len < 30)
+       len = 30;               /* actually log10(MAX_INT)+1 */
+
+    get_space((unsigned) len + 1);
+
+    (void) grub_snprintf(out_buff + out_used, len + 1, fmt, number);
+    out_used += grub_strlen(out_buff + out_used);
+}
+
+static inline void
+save_char(int c)
+{
+    if (c == 0)
+       c = 0200;
+    get_space(1);
+    out_buff[out_used++] = c;
+}
+
+static inline void
+npush(int x)
+{
+    if (stack_ptr < STACKSIZE) {
+       stack[stack_ptr].num_type = TRUE;
+       stack[stack_ptr].data.num = x;
+       stack_ptr++;
+    }
+}
+
+static inline int
+npop(void)
+{
+    int result = 0;
+    if (stack_ptr > 0) {
+       stack_ptr--;
+       if (stack[stack_ptr].num_type)
+           result = stack[stack_ptr].data.num;
+    }
+    return result;
+}
+
+static inline void
+spush(char *x)
+{
+    if (stack_ptr < STACKSIZE) {
+       stack[stack_ptr].num_type = FALSE;
+       stack[stack_ptr].data.str = x;
+       stack_ptr++;
+    }
+}
+
+static inline char *
+spop(void)
+{
+    static char dummy[] = "";  /* avoid const-cast */
+    char *result = dummy;
+    if (stack_ptr > 0) {
+       stack_ptr--;
+       if (!stack[stack_ptr].num_type && stack[stack_ptr].data.str != 0)
+           result = stack[stack_ptr].data.str;
+    }
+    return result;
+}
+
+static inline const char *
+parse_format(const char *s, char *format, int *len)
+{
+    *len = 0;
+    if (format != 0) {
+       grub_bool_t done = FALSE;
+       grub_bool_t allowminus = FALSE;
+       grub_bool_t dot = FALSE;
+       grub_bool_t err = FALSE;
+       char *fmt = format;
+       int my_width = 0;
+       int my_prec = 0;
+       int value = 0;
+
+       *len = 0;
+       *format++ = '%';
+       while (*s != '\0' && !done) {
+           switch (*s) {
+           case 'c':           /* FALLTHRU */
+           case 'd':           /* FALLTHRU */
+           case 'o':           /* FALLTHRU */
+           case 'x':           /* FALLTHRU */
+           case 'X':           /* FALLTHRU */
+           case 's':
+               *format++ = *s;
+               done = TRUE;
+               break;
+           case '.':
+               *format++ = *s++;
+               if (dot) {
+                   err = TRUE;
+               } else {        /* value before '.' is the width */
+                   dot = TRUE;
+                   my_width = value;
+               }
+               value = 0;
+               break;
+           case '#':
+               *format++ = *s++;
+               break;
+           case ' ':
+               *format++ = *s++;
+               break;
+           case ':':
+               s++;
+               allowminus = TRUE;
+               break;
+           case '-':
+               if (allowminus) {
+                   *format++ = *s++;
+               } else {
+                   done = TRUE;
+               }
+               break;
+           default:
+               if (isdigit(UChar(*s))) {
+                   value = (value * 10) + (*s - '0');
+                   if (value > 10000)
+                       err = TRUE;
+                   *format++ = *s++;
+               } else {
+                   done = TRUE;
+               }
+           }
+       }
+
+       /*
+        * If we found an error, ignore (and remove) the flags.
+        */
+       if (err) {
+           my_width = my_prec = value = 0;
+           format = fmt;
+           *format++ = '%';
+           *format++ = *s;
+       }
+
+       /*
+        * Any value after '.' is the precision.  If we did not see '.', then
+        * the value is the width.
+        */
+       if (dot)
+           my_prec = value;
+       else
+           my_width = value;
+
+       *format = '\0';
+       /* return maximum string length in print */
+       *len = (my_width > my_prec) ? my_width : my_prec;
+    }
+    return s;
+}
+
+/*
+ * Analyze the string to see how many parameters we need from the varargs list,
+ * and what their types are.  We will only accept string parameters if they
+ * appear as a %l or %s format following an explicit parameter reference (e.g.,
+ * %p2%s).  All other parameters are numbers.
+ *
+ * 'number' counts coarsely the number of pop's we see in the string, and
+ * 'popcount' shows the highest parameter number in the string.  We would like
+ * to simply use the latter count, but if we are reading termcap strings, there
+ * may be cases that we cannot see the explicit parameter numbers.
+ */
+static inline int
+analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount)
+{
+    grub_size_t len2;
+    int i;
+    int lastpop = -1;
+    int len;
+    int number = 0;
+    const char *cp = string;
+    static char dummy[] = "";
+
+    *popcount = 0;
+
+    if (cp == 0)
+       return 0;
+
+    if ((len2 = grub_strlen(cp)) > fmt_size) {
+       fmt_size = len2 + fmt_size + 2;
+       if ((fmt_buff = grub_realloc(fmt_buff, fmt_size*sizeof(char))) == 0)
+             return 0;
+    }
+
+    grub_memset(p_is_s, 0, sizeof(p_is_s[0]) * NUM_PARM);
+
+    while ((cp - string) < (int) len2) {
+       if (*cp == '%') {
+           cp++;
+           cp = parse_format(cp, fmt_buff, &len);
+           switch (*cp) {
+           default:
+               break;
+
+           case 'd':           /* FALLTHRU */
+           case 'o':           /* FALLTHRU */
+           case 'x':           /* FALLTHRU */
+           case 'X':           /* FALLTHRU */
+           case 'c':           /* FALLTHRU */
+               if (lastpop <= 0)
+                   number++;
+               lastpop = -1;
+               break;
+
+           case 'l':
+           case 's':
+               if (lastpop > 0)
+                   p_is_s[lastpop - 1] = dummy;
+               ++number;
+               break;
+
+           case 'p':
+               cp++;
+               i = (UChar(*cp) - '0');
+               if (i >= 0 && i <= NUM_PARM) {
+                   lastpop = i;
+                   if (lastpop > *popcount)
+                       *popcount = lastpop;
+               }
+               break;
+
+           case 'P':
+               ++number;
+               ++cp;
+               break;
+
+           case 'g':
+               cp++;
+               break;
+
+           case '\'':
+               cp += 2;
+               lastpop = -1;
+               break;
+
+           case '{':
+               cp++;
+               while (isdigit(UChar(*cp))) {
+                   cp++;
+               }
+               break;
+
+           case '+':
+           case '-':
+           case '*':
+           case '/':
+           case 'm':
+           case 'A':
+           case 'O':
+           case '&':
+           case '|':
+           case '^':
+           case '=':
+           case '<':
+           case '>':
+               lastpop = -1;
+               number += 2;
+               break;
+
+           case '!':
+           case '~':
+               lastpop = -1;
+               ++number;
+               break;
+
+           case 'i':
+               /* will add 1 to first (usually two) parameters */
+               break;
+           }
+       }
+       if (*cp != '\0')
+           cp++;
+    }
+
+    if (number > NUM_PARM)
+       number = NUM_PARM;
+    return number;
+}
+
+static inline char *
+tparam_internal(const char *string, va_list ap)
+{
+    char *p_is_s[NUM_PARM];
+    long param[NUM_PARM];
+    int popcount;
+    int number;
+    int len;
+    int level;
+    int x, y;
+    int i;
+    const char *cp = string;
+    grub_size_t len2;
+    static int dynamic_var[NUM_VARS];
+    static int static_vars[NUM_VARS];
+
+    if (cp == 0)
+       return 0;
+
+    out_used = out_size = fmt_size = 0;
+
+    len2 = (int) grub_strlen(cp);
+
+    /*
+     * Find the highest parameter-number referred to in the format string.
+     * Use this value to limit the number of arguments copied from the
+     * variable-length argument list.
+     */
+    number = analyze(cp, p_is_s, &popcount);
+    if (fmt_buff == 0)
+       return 0;
+
+    for (i = 0; i < max(popcount, number); i++) {
+       /*
+        * A few caps (such as plab_norm) have string-valued parms.
+        * We'll have to assume that the caller knows the difference, since
+        * a char* and an int may not be the same size on the stack.
+        */
+       if (p_is_s[i] != 0) {
+           p_is_s[i] = va_arg(ap, char *);
+       } else {
+           param[i] = va_arg(ap, long int);
+       }
+    }
+
+    /*
+     * This is a termcap compatibility hack.  If there are no explicit pop
+     * operations in the string, load the stack in such a way that
+     * successive pops will grab successive parameters.  That will make
+     * the expansion of (for example) \E[%d;%dH work correctly in termcap
+     * style, which means tparam() will expand termcap strings OK.
+     */
+    stack_ptr = 0;
+    if (popcount == 0) {
+       popcount = number;
+       for (i = number - 1; i >= 0; i--)
+           npush(param[i]);
+    }
+
+    while ((cp - string) < (int) len2) {
+       if (*cp != '%') {
+           save_char(UChar(*cp));
+       } else {
+           tparam_base = cp++;
+           cp = parse_format(cp, fmt_buff, &len);
+           switch (*cp) {
+           default:
+               break;
+           case '%':
+               save_char('%');
+               break;
+
+           case 'd':           /* FALLTHRU */
+           case 'o':           /* FALLTHRU */
+           case 'x':           /* FALLTHRU */
+           case 'X':           /* FALLTHRU */
+               save_number(fmt_buff, npop(), len);
+               break;
+
+           case 'c':           /* FALLTHRU */
+               save_char(npop());
+               break;
+
+           case 'l':
+               save_number("%d", (int) grub_strlen(spop()), 0);
+               break;
+
+           case 's':
+               save_text(fmt_buff, spop(), len);
+               break;
+
+           case 'p':
+               cp++;
+               i = (UChar(*cp) - '1');
+               if (i >= 0 && i < NUM_PARM) {
+                   if (p_is_s[i])
+                       spush(p_is_s[i]);
+                   else
+                       npush(param[i]);
+               }
+               break;
+
+           case 'P':
+               cp++;
+               if (isUPPER(*cp)) {
+                   i = (UChar(*cp) - 'A');
+                   static_vars[i] = npop();
+               } else if (isLOWER(*cp)) {
+                   i = (UChar(*cp) - 'a');
+                   dynamic_var[i] = npop();
+               }
+               break;
+
+           case 'g':
+               cp++;
+               if (isUPPER(*cp)) {
+                   i = (UChar(*cp) - 'A');
+                   npush(static_vars[i]);
+               } else if (isLOWER(*cp)) {
+                   i = (UChar(*cp) - 'a');
+                   npush(dynamic_var[i]);
+               }
+               break;
+
+           case '\'':
+               cp++;
+               npush(UChar(*cp));
+               cp++;
+               break;
+
+           case '{':
+               number = 0;
+               cp++;
+               while (isdigit(UChar(*cp))) {
+                   number = (number * 10) + (UChar(*cp) - '0');
+                   cp++;
+               }
+               npush(number);
+               break;
+
+           case '+':
+               npush(npop() + npop());
+               break;
+
+           case '-':
+               y = npop();
+               x = npop();
+               npush(x - y);
+               break;
+
+           case '*':
+               npush(npop() * npop());
+               break;
+
+           case '/':
+               y = npop();
+               x = npop();
+               npush(y ? (x / y) : 0);
+               break;
+
+           case 'm':
+               y = npop();
+               x = npop();
+               npush(y ? (x % y) : 0);
+               break;
+
+           case 'A':
+               npush(npop() && npop());
+               break;
+
+           case 'O':
+               npush(npop() || npop());
+               break;
+
+           case '&':
+               npush(npop() & npop());
+               break;
+
+           case '|':
+               npush(npop() | npop());
+               break;
+
+           case '^':
+               npush(npop() ^ npop());
+               break;
+
+           case '=':
+               y = npop();
+               x = npop();
+               npush(x == y);
+               break;
+
+           case '<':
+               y = npop();
+               x = npop();
+               npush(x < y);
+               break;
+
+           case '>':
+               y = npop();
+               x = npop();
+               npush(x > y);
+               break;
+
+           case '!':
+               npush(!npop());
+               break;
+
+           case '~':
+               npush(~npop());
+               break;
+
+           case 'i':
+               if (p_is_s[0] == 0)
+                   param[0]++;
+               if (p_is_s[1] == 0)
+                   param[1]++;
+               break;
+
+           case '?':
+               break;
+
+           case 't':
+               x = npop();
+               if (!x) {
+                   /* scan forward for %e or %; at level zero */
+                   cp++;
+                   level = 0;
+                   while (*cp) {
+                       if (*cp == '%') {
+                           cp++;
+                           if (*cp == '?')
+                               level++;
+                           else if (*cp == ';') {
+                               if (level > 0)
+                                   level--;
+                               else
+                                   break;
+                           } else if (*cp == 'e' && level == 0)
+                               break;
+                       }
+
+                       if (*cp)
+                           cp++;
+                   }
+               }
+               break;
+
+           case 'e':
+               /* scan forward for a %; at level zero */
+               cp++;
+               level = 0;
+               while (*cp) {
+                   if (*cp == '%') {
+                       cp++;
+                       if (*cp == '?')
+                           level++;
+                       else if (*cp == ';') {
+                           if (level > 0)
+                               level--;
+                           else
+                               break;
+                       }
+                   }
+
+                   if (*cp)
+                       cp++;
+               }
+               break;
+
+           case ';':
+               break;
+
+           }                   /* endswitch (*cp) */
+       }                       /* endelse (*cp == '%') */
+
+       if (*cp == '\0')
+           break;
+
+       cp++;
+    }                          /* endwhile (*cp) */
+
+    get_space(1);
+    out_buff[out_used] = '\0';
+
+    return (out_buff);
+}
+
+char *
+grub_terminfo_tparm (const char *string, ...)
+{
+    va_list ap;
+    char *result;
+
+    va_start (ap, string);
+    result = tparam_internal (string, ap);
+    va_end (ap);
+    return result;
+}
diff --git a/grub-core/term/usb_keyboard.c b/grub-core/term/usb_keyboard.c
new file mode 100644 (file)
index 0000000..5d76c5e
--- /dev/null
@@ -0,0 +1,329 @@
+/* Support for the HID Boot Protocol.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/term.h>
+#include <grub/machine/console.h>
+#include <grub/time.h>
+#include <grub/cpu/io.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/usb.h>
+#include <grub/dl.h>
+#include <grub/time.h>
+
+\f
+static char keyboard_map[128] =
+  {
+    '\0', '\0', '\0', '\0', 'a', 'b', 'c', 'd',
+    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
+    'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+    'u', 'v', 'w', 'x', 'y', 'z', '1', '2',
+    '3', '4', '5', '6', '7', '8', '9', '0',
+    '\n', GRUB_TERM_ESC, GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, ' ', '-', '=', '[',
+    ']', '\\', '#', ';', '\'', '`', ',', '.',
+    '/', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
+    '\0', '\0', GRUB_TERM_HOME, GRUB_TERM_PPAGE, GRUB_TERM_DC, GRUB_TERM_END, GRUB_TERM_NPAGE, GRUB_TERM_RIGHT,
+    GRUB_TERM_LEFT, GRUB_TERM_DOWN, GRUB_TERM_UP
+  };
+
+static char keyboard_map_shift[128] =
+  {
+    '\0', '\0', '\0', '\0', 'A', 'B', 'C', 'D',
+    'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+    'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+    'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@',
+    '#', '$', '%', '^', '&', '*', '(', ')',
+    '\n', '\0', '\0', '\0', ' ', '_', '+', '{',
+    '}', '|', '#', ':', '"', '`', '<', '>',
+    '?'
+  };
+
+static grub_usb_device_t usbdev;
+
+/* Valid values for bmRequestType.  See HID definition version 1.11 section
+   7.2.  */
+#define USB_HID_HOST_TO_DEVICE 0x21
+#define USB_HID_DEVICE_TO_HOST 0xA1
+
+/* Valid values for bRequest.  See HID definition version 1.11 section 7.2. */
+#define USB_HID_GET_REPORT     0x01
+#define USB_HID_GET_IDLE       0x02
+#define USB_HID_GET_PROTOCOL   0x03
+#define USB_HID_SET_REPORT     0x09
+#define USB_HID_SET_IDLE       0x0A
+#define USB_HID_SET_PROTOCOL   0x0B
+
+static void
+grub_usb_hid (void)
+{
+  struct grub_usb_desc_device *descdev;
+
+  auto int usb_iterate (grub_usb_device_t dev);
+  int usb_iterate (grub_usb_device_t dev)
+    {
+      descdev = &dev->descdev;
+
+      grub_dprintf ("usb_keyboard", "%x %x %x\n",
+                  descdev->class, descdev->subclass, descdev->protocol);
+
+#if 0
+      if (descdev->class != 0x09
+         || descdev->subclass == 0x01
+         || descdev->protocol != 0x02)
+       return 0;
+#endif
+
+      if (descdev->class != 0 || descdev->subclass != 0 || descdev->protocol != 0)
+       return 0;
+
+      grub_printf ("HID found!\n");
+
+      usbdev = dev;
+
+      return 1;
+    }
+  grub_usb_iterate (usb_iterate);
+
+  /* Place the device in boot mode.  */
+  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_PROTOCOL,
+                       0, 0, 0, 0);
+
+  /* Reports every time an event occurs and not more often than that.  */
+  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
+                       0<<8, 0, 0, 0);
+}
+
+static grub_err_t
+grub_usb_keyboard_getreport (grub_usb_device_t dev, grub_uint8_t *report)
+{
+  return grub_usb_control_msg (dev, USB_HID_DEVICE_TO_HOST, USB_HID_GET_REPORT,
+                              0, 0, 8, (char *) report);
+}
+
+\f
+
+static int
+grub_usb_keyboard_checkkey (void)
+{
+  grub_uint8_t data[8];
+  int key;
+  grub_err_t err;
+  grub_uint64_t currtime;
+  int timeout = 50;
+
+  data[2] = 0;
+  currtime = grub_get_time_ms ();
+  do
+    {
+      /* Get_Report.  */
+      err = grub_usb_keyboard_getreport (usbdev, data);
+
+      /* Implement a timeout.  */
+      if (grub_get_time_ms () > currtime + timeout)
+       break;
+    }
+  while (err || !data[2]);
+
+  if (err || !data[2])
+    return -1;
+
+  grub_dprintf ("usb_keyboard",
+               "report: 0x%02x 0x%02x 0x%02x 0x%02x"
+               " 0x%02x 0x%02x 0x%02x 0x%02x\n",
+               data[0], data[1], data[2], data[3],
+               data[4], data[5], data[6], data[7]);
+
+  /* Check if the Control or Shift key was pressed.  */
+  if (data[0] & 0x01 || data[0] & 0x10)
+    key = keyboard_map[data[2]] - 'a' + 1;
+  else if (data[0] & 0x02 || data[0] & 0x20)
+    key = keyboard_map_shift[data[2]];
+  else
+    key = keyboard_map[data[2]];
+
+  if (key == 0)
+    grub_printf ("Unknown key 0x%x detected\n", data[2]);
+
+#if 0
+  /* Wait until the key is released.  */
+  while (!err && data[2])
+    {
+      err = grub_usb_control_msg (usbdev, USB_HID_DEVICE_TO_HOST,
+                                 USB_HID_GET_REPORT, 0, 0,
+                                 sizeof (data), (char *) data);
+      grub_dprintf ("usb_keyboard",
+                   "report2: 0x%02x 0x%02x 0x%02x 0x%02x"
+                   " 0x%02x 0x%02x 0x%02x 0x%02x\n",
+                   data[0], data[1], data[2], data[3],
+                   data[4], data[5], data[6], data[7]);
+    }
+#endif
+
+  grub_errno = GRUB_ERR_NONE;
+
+  return key;
+}
+
+typedef enum
+{
+  GRUB_HIDBOOT_REPEAT_NONE,
+  GRUB_HIDBOOT_REPEAT_FIRST,
+  GRUB_HIDBOOT_REPEAT
+} grub_usb_keyboard_repeat_t;
+
+static int
+grub_usb_keyboard_getkey (void)
+{
+  int key;
+  grub_err_t err;
+  grub_uint8_t data[8];
+  grub_uint64_t currtime;
+  int timeout;
+  static grub_usb_keyboard_repeat_t repeat = GRUB_HIDBOOT_REPEAT_NONE;
+
+ again:
+
+  do
+    {
+      key = grub_usb_keyboard_checkkey ();
+    } while (key == -1);
+
+  data[2] = !0; /* Or whatever.  */
+  err = 0;
+
+  switch (repeat)
+    {
+    case GRUB_HIDBOOT_REPEAT_FIRST:
+      timeout = 500;
+      break;
+    case GRUB_HIDBOOT_REPEAT:
+      timeout = 50;
+      break;
+    default:
+      timeout = 100;
+      break;
+    }
+
+  /* Wait until the key is released.  */
+  currtime = grub_get_time_ms ();
+  while (!err && data[2])
+    {
+      /* Implement a timeout.  */
+      if (grub_get_time_ms () > currtime + timeout)
+       {
+         if (repeat == 0)
+           repeat = 1;
+         else
+           repeat = 2;
+
+         grub_errno = GRUB_ERR_NONE;
+         return key;
+       }
+
+      err = grub_usb_keyboard_getreport (usbdev, data);
+    }
+
+  if (repeat)
+    {
+      repeat = 0;
+      goto again;
+    }
+
+  repeat = 0;
+
+  grub_errno = GRUB_ERR_NONE;
+
+  return key;
+}
+
+static int
+grub_usb_keyboard_getkeystatus (void)
+{
+  grub_uint8_t data[8];
+  int mods = 0;
+  grub_err_t err;
+  grub_uint64_t currtime;
+  int timeout = 50;
+
+  /* Set idle time to the minimum offered by the spec (4 milliseconds) so
+     that we can find out the current state.  */
+  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
+                       0<<8, 0, 0, 0);
+
+  currtime = grub_get_time_ms ();
+  do
+    {
+      /* Get_Report.  */
+      err = grub_usb_keyboard_getreport (usbdev, data);
+
+      /* Implement a timeout.  */
+      if (grub_get_time_ms () > currtime + timeout)
+       break;
+    }
+  while (err || !data[0]);
+
+  /* Go back to reporting every time an event occurs and not more often than
+     that.  */
+  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
+                       0<<8, 0, 0, 0);
+
+  /* We allowed a while for modifiers to show up in the report, but it is
+     not an error if they never did.  */
+  if (err)
+    return -1;
+
+  grub_dprintf ("usb_keyboard",
+               "report: 0x%02x 0x%02x 0x%02x 0x%02x"
+               " 0x%02x 0x%02x 0x%02x 0x%02x\n",
+               data[0], data[1], data[2], data[3],
+               data[4], data[5], data[6], data[7]);
+
+  /* Check Shift, Control, and Alt status.  */
+  if (data[0] & 0x02 || data[0] & 0x20)
+    mods |= GRUB_TERM_STATUS_SHIFT;
+  if (data[0] & 0x01 || data[0] & 0x10)
+    mods |= GRUB_TERM_STATUS_CTRL;
+  if (data[0] & 0x04 || data[0] & 0x40)
+    mods |= GRUB_TERM_STATUS_ALT;
+
+  grub_errno = GRUB_ERR_NONE;
+
+  return mods;
+}
+
+static struct grub_term_input grub_usb_keyboard_term =
+  {
+    .name = "usb_keyboard",
+    .checkkey = grub_usb_keyboard_checkkey,
+    .getkey = grub_usb_keyboard_getkey,
+    .getkeystatus = grub_usb_keyboard_getkeystatus,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(usb_keyboard)
+{
+  grub_usb_hid ();
+  grub_term_register_input ("usb_keyboard", &grub_usb_keyboard_term);
+}
+
+GRUB_MOD_FINI(usb_keyboard)
+{
+  grub_term_unregister_input (&grub_usb_keyboard_term);
+}
diff --git a/grub-core/tests/example_functional_test.c b/grub-core/tests/example_functional_test.c
new file mode 100644 (file)
index 0000000..5259881
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* All tests need to include test.h for GRUB testing framework.  */
+#include <grub/test.h>
+
+/* Functional test main method.  */
+static void
+example_test (void)
+{
+  /* Check if 1st argument is true and report with default error message.  */
+  grub_test_assert (1 == 1);
+
+  /* Check if 1st argument is true and report with custom error message.  */
+  grub_test_assert (2 == 2, "2 equal 2 expected");
+  grub_test_assert (2 != 3, "2 matches %d", 3);
+}
+
+/* Register example_test method as a functional test.  */
+GRUB_FUNCTIONAL_TEST (example_functional_test, example_test);
diff --git a/grub-core/tests/lib/functional_test.c b/grub-core/tests/lib/functional_test.c
new file mode 100644 (file)
index 0000000..8ff08cf
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+#include <grub/test.h>
+
+static grub_err_t
+grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)),
+                     int argc __attribute__ ((unused)),
+                     char **args __attribute__ ((unused)))
+{
+  auto int run_test (grub_test_t test);
+  int run_test (grub_test_t test)
+  {
+    grub_test_run (test);
+    return 0;
+  }
+
+  grub_list_iterate (GRUB_AS_LIST (grub_test_list),
+                    (grub_list_hook_t) run_test);
+  return GRUB_ERR_NONE;
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT (functional_test)
+{
+  cmd = grub_register_extcmd ("functional_test", grub_functional_test,
+                             GRUB_COMMAND_FLAG_CMDLINE, 0,
+                             "Run all functional tests.", 0);
+}
+
+GRUB_MOD_FINI (functional_test)
+{
+  grub_unregister_extcmd (cmd);
+}
diff --git a/grub-core/tests/lib/test.c b/grub-core/tests/lib/test.c
new file mode 100644 (file)
index 0000000..b5c0543
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/test.h>
+
+struct grub_test_failure
+{
+  /* The next failure.  */
+  struct grub_test_failure *next;
+
+  /* The test source file name.  */
+  char *file;
+
+  /* The test function name.  */
+  char *funp;
+
+  /* The test call line number.  */
+  grub_uint32_t line;
+
+  /* The test failure message.  */
+  char *message;
+};
+typedef struct grub_test_failure *grub_test_failure_t;
+
+grub_test_t grub_test_list;
+static grub_test_failure_t failure_list;
+
+static void
+add_failure (const char *file,
+            const char *funp,
+            grub_uint32_t line, const char *fmt, va_list args)
+{
+  grub_test_failure_t failure;
+
+  failure = (grub_test_failure_t) grub_malloc (sizeof (*failure));
+  if (!failure)
+    return;
+
+  failure->file = grub_strdup (file ? : "<unknown_file>");
+  failure->funp = grub_strdup (funp ? : "<unknown_function>");
+  failure->line = line;
+  failure->message = grub_xvasprintf (fmt, args);
+
+  grub_list_push (GRUB_AS_LIST_P (&failure_list), GRUB_AS_LIST (failure));
+}
+
+static void
+free_failures (void)
+{
+  grub_test_failure_t item;
+
+  while ((item = grub_list_pop (GRUB_AS_LIST_P (&failure_list))) != 0)
+    {
+      if (item->message)
+       grub_free (item->message);
+
+      if (item->funp)
+       grub_free (item->funp);
+
+      if (item->file)
+       grub_free (item->file);
+
+      grub_free (item);
+    }
+  failure_list = 0;
+}
+
+void
+grub_test_nonzero (int cond,
+                  const char *file,
+                  const char *funp, grub_uint32_t line, const char *fmt, ...)
+{
+  va_list ap;
+
+  if (cond)
+    return;
+
+  va_start (ap, fmt);
+  add_failure (file, funp, line, fmt, ap);
+  va_end (ap);
+}
+
+void
+grub_test_register (const char *name, void (*test_main) (void))
+{
+  grub_test_t test;
+
+  test = (grub_test_t) grub_malloc (sizeof (*test));
+  if (!test)
+    return;
+
+  test->name = grub_strdup (name);
+  test->main = test_main;
+
+  grub_list_push (GRUB_AS_LIST_P (&grub_test_list), GRUB_AS_LIST (test));
+}
+
+void
+grub_test_unregister (const char *name)
+{
+  grub_test_t test;
+
+  test = (grub_test_t) grub_named_list_find
+    (GRUB_AS_NAMED_LIST (grub_test_list), name);
+
+  if (test)
+    {
+      grub_list_remove (GRUB_AS_LIST_P (&grub_test_list), GRUB_AS_LIST (test));
+
+      if (test->name)
+       grub_free (test->name);
+
+      grub_free (test);
+    }
+}
+
+int
+grub_test_run (grub_test_t test)
+{
+  auto int print_failure (grub_test_failure_t item);
+  int print_failure (grub_test_failure_t item)
+  {
+    grub_test_failure_t failure = (grub_test_failure_t) item;
+
+    grub_printf (" %s:%s:%u: %s\n",
+                (failure->file ? : "<unknown_file>"),
+                (failure->funp ? : "<unknown_function>"),
+                failure->line, (failure->message ? : "<no message>"));
+    return 0;
+  }
+
+  test->main ();
+
+  grub_printf ("%s:\n", test->name);
+  grub_list_iterate (GRUB_AS_LIST (failure_list),
+                    (grub_list_hook_t) print_failure);
+  if (!failure_list)
+    grub_printf ("%s: PASS\n", test->name);
+  else
+    grub_printf ("%s: FAIL\n", test->name);
+
+  free_failures ();
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/video/bitmap.c b/grub-core/video/bitmap.c
new file mode 100644 (file)
index 0000000..e06a5b6
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/video.h>
+#include <grub/bitmap.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+/* List of bitmap readers registered to system.  */
+static grub_video_bitmap_reader_t bitmap_readers_list;
+
+/* Register bitmap reader.  */
+void
+grub_video_bitmap_reader_register (grub_video_bitmap_reader_t reader)
+{
+  reader->next = bitmap_readers_list;
+  bitmap_readers_list = reader;
+}
+
+/* Unregister bitmap reader.  */
+void
+grub_video_bitmap_reader_unregister (grub_video_bitmap_reader_t reader)
+{
+  grub_video_bitmap_reader_t *p, q;
+
+  for (p = &bitmap_readers_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == reader)
+      {
+        *p = q->next;
+        break;
+      }
+}
+
+/* Creates new bitmap, saves created bitmap on success to *bitmap.  */
+grub_err_t
+grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
+                          unsigned int width, unsigned int height,
+                          enum grub_video_blit_format blit_format)
+{
+  struct grub_video_mode_info *mode_info;
+  unsigned int size;
+
+  if (!bitmap)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
+
+  *bitmap = 0;
+
+  if (width == 0 || height == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
+
+  *bitmap = (struct grub_video_bitmap *)grub_malloc (sizeof (struct grub_video_bitmap));
+  if (! *bitmap)
+    return grub_errno;
+
+  mode_info = &((*bitmap)->mode_info);
+
+  /* Populate mode_info.  */
+  mode_info->width = width;
+  mode_info->height = height;
+  mode_info->blit_format = blit_format;
+
+  switch (blit_format)
+    {
+      case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
+        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB
+                               | GRUB_VIDEO_MODE_TYPE_ALPHA;
+        mode_info->bpp = 32;
+        mode_info->bytes_per_pixel = 4;
+        mode_info->number_of_colors = 256;
+        mode_info->red_mask_size = 8;
+        mode_info->red_field_pos = 0;
+        mode_info->green_mask_size = 8;
+        mode_info->green_field_pos = 8;
+        mode_info->blue_mask_size = 8;
+        mode_info->blue_field_pos = 16;
+        mode_info->reserved_mask_size = 8;
+        mode_info->reserved_field_pos = 24;
+        break;
+
+      case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
+        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
+        mode_info->bpp = 24;
+        mode_info->bytes_per_pixel = 3;
+        mode_info->number_of_colors = 256;
+        mode_info->red_mask_size = 8;
+        mode_info->red_field_pos = 0;
+        mode_info->green_mask_size = 8;
+        mode_info->green_field_pos = 8;
+        mode_info->blue_mask_size = 8;
+        mode_info->blue_field_pos = 16;
+        mode_info->reserved_mask_size = 0;
+        mode_info->reserved_field_pos = 0;
+        break;
+
+      case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
+        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
+        mode_info->bpp = 8;
+        mode_info->bytes_per_pixel = 1;
+        mode_info->number_of_colors = 256;
+        mode_info->red_mask_size = 0;
+        mode_info->red_field_pos = 0;
+        mode_info->green_mask_size = 0;
+        mode_info->green_field_pos = 0;
+        mode_info->blue_mask_size = 0;
+        mode_info->blue_field_pos = 0;
+        mode_info->reserved_mask_size = 0;
+        mode_info->reserved_field_pos = 0;
+        break;
+
+      default:
+        grub_free (*bitmap);
+        *bitmap = 0;
+
+        return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                           "unsupported bitmap format");
+    }
+
+  mode_info->pitch = width * mode_info->bytes_per_pixel;
+
+  /* Calculate size needed for the data.  */
+  size = (width * mode_info->bytes_per_pixel) * height;
+
+  (*bitmap)->data = grub_zalloc (size);
+  if (! (*bitmap)->data)
+    {
+      grub_free (*bitmap);
+      *bitmap = 0;
+
+      return grub_errno;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Frees all resources allocated by bitmap.  */
+grub_err_t
+grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap)
+{
+  if (! bitmap)
+    return GRUB_ERR_NONE;
+
+  grub_free (bitmap->data);
+  grub_free (bitmap);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Match extension to filename.  */
+static int
+match_extension (const char *filename, const char *ext)
+{
+  int pos;
+  int ext_len;
+
+  pos = grub_strlen (filename);
+  ext_len = grub_strlen (ext);
+
+  if (! pos || ! ext_len || ext_len > pos)
+    return 0;
+
+  pos -= ext_len;
+
+  return grub_strcmp (filename + pos, ext) == 0;
+}
+
+/* Loads bitmap using registered bitmap readers.  */
+grub_err_t
+grub_video_bitmap_load (struct grub_video_bitmap **bitmap,
+                        const char *filename)
+{
+  grub_video_bitmap_reader_t reader = bitmap_readers_list;
+
+  if (!bitmap)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
+
+  *bitmap = 0;
+
+  while (reader)
+    {
+      if (match_extension (filename, reader->extension))
+        return reader->reader (bitmap, filename);
+
+      reader = reader->next;
+    }
+
+  return grub_error(GRUB_ERR_BAD_FILE_TYPE, "unsupported bitmap format");
+}
+
+/* Return bitmap width.  */
+unsigned int
+grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap)
+{
+  if (!bitmap)
+    return 0;
+
+  return bitmap->mode_info.width;
+}
+
+/* Return bitmap height.  */
+unsigned int
+grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap)
+{
+  if (!bitmap)
+    return 0;
+
+  return bitmap->mode_info.height;
+}
+
+/* Return mode info for bitmap.  */
+void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap,
+                                      struct grub_video_mode_info *mode_info)
+{
+  if (!bitmap)
+    return;
+
+  *mode_info = bitmap->mode_info;
+}
+
+/* Return pointer to bitmap's raw data.  */
+void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap)
+{
+  if (!bitmap)
+    return 0;
+
+  return bitmap->data;
+}
+
+/* Initialize bitmap module.  */
+GRUB_MOD_INIT(bitmap)
+{
+}
+
+/* Finalize bitmap module.  */
+GRUB_MOD_FINI(bitmap)
+{
+}
diff --git a/grub-core/video/bitmap_scale.c b/grub-core/video/bitmap_scale.c
new file mode 100644 (file)
index 0000000..6f8ff24
--- /dev/null
@@ -0,0 +1,308 @@
+/* bitmap_scale.c - Bitmap scaling. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/video.h>
+#include <grub/bitmap.h>
+#include <grub/bitmap_scale.h>
+#include <grub/types.h>
+
+/* Prototypes for module-local functions.  */
+static grub_err_t scale_nn (struct grub_video_bitmap *dst,
+                            struct grub_video_bitmap *src);
+static grub_err_t scale_bilinear (struct grub_video_bitmap *dst,
+                                  struct grub_video_bitmap *src);
+
+/* This function creates a new scaled version of the bitmap SRC.  The new
+   bitmap has dimensions DST_WIDTH by DST_HEIGHT.  The scaling algorithm
+   is given by SCALE_METHOD.  If an error is encountered, the return code is
+   not equal to GRUB_ERR_NONE, and the bitmap DST is either not created, or
+   it is destroyed before this function returns.
+
+   Supports only direct color modes which have components separated
+   into bytes (e.g., RGBA 8:8:8:8 or BGR 8:8:8 true color).
+   But because of this simplifying assumption, the implementation is
+   greatly simplified.  */
+grub_err_t
+grub_video_bitmap_create_scaled (struct grub_video_bitmap **dst,
+                                 int dst_width, int dst_height,
+                                 struct grub_video_bitmap *src,
+                                 enum grub_video_bitmap_scale_method
+                                 scale_method)
+{
+  *dst = 0;
+
+  /* Verify the simplifying assumptions. */
+  if (src == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                       "null src bitmap in grub_video_bitmap_create_scaled");
+  if (src->mode_info.red_field_pos % 8 != 0
+      || src->mode_info.green_field_pos % 8 != 0
+      || src->mode_info.blue_field_pos % 8 != 0
+      || src->mode_info.reserved_field_pos % 8 != 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                       "src format not supported for scale");
+  if (src->mode_info.width == 0 || src->mode_info.height == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                       "source bitmap has a zero dimension");
+  if (dst_width <= 0 || dst_height <= 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                       "requested to scale to a size w/ a zero dimension");
+  if (src->mode_info.bytes_per_pixel * 8 != src->mode_info.bpp)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                       "bitmap to scale has inconsistent Bpp and bpp");
+
+  /* Create the new bitmap. */
+  grub_err_t ret;
+  ret = grub_video_bitmap_create (dst, dst_width, dst_height,
+                                  src->mode_info.blit_format);
+  if (ret != GRUB_ERR_NONE)
+    return ret;                 /* Error. */
+
+  switch (scale_method)
+    {
+    case GRUB_VIDEO_BITMAP_SCALE_METHOD_FASTEST:
+    case GRUB_VIDEO_BITMAP_SCALE_METHOD_NEAREST:
+      ret = scale_nn (*dst, src);
+      break;
+    case GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST:
+    case GRUB_VIDEO_BITMAP_SCALE_METHOD_BILINEAR:
+      ret = scale_bilinear (*dst, src);
+      break;
+    default:
+      ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid scale_method value");
+      break;
+    }
+
+  if (ret == GRUB_ERR_NONE)
+    {
+      /* Success:  *dst is now a pointer to the scaled bitmap. */
+      return GRUB_ERR_NONE;
+    }
+  else
+    {
+      /* Destroy the bitmap and return the error code. */
+      grub_video_bitmap_destroy (*dst);
+      *dst = 0;
+      return ret;
+    }
+}
+
+/* Nearest neighbor bitmap scaling algorithm.
+
+   Copy the bitmap SRC to the bitmap DST, scaling the bitmap to fit the
+   dimensions of DST.  This function uses the nearest neighbor algorithm to
+   interpolate the pixels.
+
+   Supports only direct color modes which have components separated
+   into bytes (e.g., RGBA 8:8:8:8 or BGR 8:8:8 true color).
+   But because of this simplifying assumption, the implementation is
+   greatly simplified.  */
+static grub_err_t
+scale_nn (struct grub_video_bitmap *dst, struct grub_video_bitmap *src)
+{
+  /* Verify the simplifying assumptions. */
+  if (dst == 0 || src == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "null bitmap in scale_nn");
+  if (dst->mode_info.red_field_pos % 8 != 0
+      || dst->mode_info.green_field_pos % 8 != 0
+      || dst->mode_info.blue_field_pos % 8 != 0
+      || dst->mode_info.reserved_field_pos % 8 != 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst format not supported");
+  if (src->mode_info.red_field_pos % 8 != 0
+      || src->mode_info.green_field_pos % 8 != 0
+      || src->mode_info.blue_field_pos % 8 != 0
+      || src->mode_info.reserved_field_pos % 8 != 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "src format not supported");
+  if (dst->mode_info.red_field_pos != src->mode_info.red_field_pos
+      || dst->mode_info.red_mask_size != src->mode_info.red_mask_size
+      || dst->mode_info.green_field_pos != src->mode_info.green_field_pos
+      || dst->mode_info.green_mask_size != src->mode_info.green_mask_size
+      || dst->mode_info.blue_field_pos != src->mode_info.blue_field_pos
+      || dst->mode_info.blue_mask_size != src->mode_info.blue_mask_size
+      || dst->mode_info.reserved_field_pos !=
+      src->mode_info.reserved_field_pos
+      || dst->mode_info.reserved_mask_size !=
+      src->mode_info.reserved_mask_size)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible");
+  if (dst->mode_info.bytes_per_pixel != src->mode_info.bytes_per_pixel)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible");
+  if (dst->mode_info.width == 0 || dst->mode_info.height == 0
+      || src->mode_info.width == 0 || src->mode_info.height == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "bitmap has a zero dimension");
+
+  grub_uint8_t *ddata = dst->data;
+  grub_uint8_t *sdata = src->data;
+  int dw = dst->mode_info.width;
+  int dh = dst->mode_info.height;
+  int sw = src->mode_info.width;
+  int sh = src->mode_info.height;
+  int dstride = dst->mode_info.pitch;
+  int sstride = src->mode_info.pitch;
+  /* bytes_per_pixel is the same for both src and dst. */
+  int bytes_per_pixel = dst->mode_info.bytes_per_pixel;
+
+  int dy;
+  for (dy = 0; dy < dh; dy++)
+    {
+      int dx;
+      for (dx = 0; dx < dw; dx++)
+        {
+          grub_uint8_t *dptr;
+          grub_uint8_t *sptr;
+          int sx;
+          int sy;
+          int comp;
+
+          /* Compute the source coordinate that the destination coordinate
+             maps to.  Note: sx/sw = dx/dw  =>  sx = sw*dx/dw. */
+          sx = sw * dx / dw;
+          sy = sh * dy / dh;
+
+          /* Get the address of the pixels in src and dst. */
+          dptr = ddata + dy * dstride + dx * bytes_per_pixel;
+          sptr = sdata + sy * sstride + sx * bytes_per_pixel;
+
+          /* Copy the pixel color value. */
+          for (comp = 0; comp < bytes_per_pixel; comp++)
+            dptr[comp] = sptr[comp];
+        }
+    }
+  return GRUB_ERR_NONE;
+}
+
+/* Bilinear interpolation image scaling algorithm.
+
+   Copy the bitmap SRC to the bitmap DST, scaling the bitmap to fit the
+   dimensions of DST.  This function uses the bilinear interpolation algorithm
+   to interpolate the pixels.
+
+   Supports only direct color modes which have components separated
+   into bytes (e.g., RGBA 8:8:8:8 or BGR 8:8:8 true color).
+   But because of this simplifying assumption, the implementation is
+   greatly simplified.  */
+static grub_err_t
+scale_bilinear (struct grub_video_bitmap *dst, struct grub_video_bitmap *src)
+{
+  /* Verify the simplifying assumptions. */
+  if (dst == 0 || src == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "null bitmap in scale func");
+  if (dst->mode_info.red_field_pos % 8 != 0
+      || dst->mode_info.green_field_pos % 8 != 0
+      || dst->mode_info.blue_field_pos % 8 != 0
+      || dst->mode_info.reserved_field_pos % 8 != 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst format not supported");
+  if (src->mode_info.red_field_pos % 8 != 0
+      || src->mode_info.green_field_pos % 8 != 0
+      || src->mode_info.blue_field_pos % 8 != 0
+      || src->mode_info.reserved_field_pos % 8 != 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "src format not supported");
+  if (dst->mode_info.red_field_pos != src->mode_info.red_field_pos
+      || dst->mode_info.red_mask_size != src->mode_info.red_mask_size
+      || dst->mode_info.green_field_pos != src->mode_info.green_field_pos
+      || dst->mode_info.green_mask_size != src->mode_info.green_mask_size
+      || dst->mode_info.blue_field_pos != src->mode_info.blue_field_pos
+      || dst->mode_info.blue_mask_size != src->mode_info.blue_mask_size
+      || dst->mode_info.reserved_field_pos !=
+      src->mode_info.reserved_field_pos
+      || dst->mode_info.reserved_mask_size !=
+      src->mode_info.reserved_mask_size)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible");
+  if (dst->mode_info.bytes_per_pixel != src->mode_info.bytes_per_pixel)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible");
+  if (dst->mode_info.width == 0 || dst->mode_info.height == 0
+      || src->mode_info.width == 0 || src->mode_info.height == 0)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "bitmap has a zero dimension");
+
+  grub_uint8_t *ddata = dst->data;
+  grub_uint8_t *sdata = src->data;
+  int dw = dst->mode_info.width;
+  int dh = dst->mode_info.height;
+  int sw = src->mode_info.width;
+  int sh = src->mode_info.height;
+  int dstride = dst->mode_info.pitch;
+  int sstride = src->mode_info.pitch;
+  /* bytes_per_pixel is the same for both src and dst. */
+  int bytes_per_pixel = dst->mode_info.bytes_per_pixel;
+
+  int dy;
+  for (dy = 0; dy < dh; dy++)
+    {
+      int dx;
+      for (dx = 0; dx < dw; dx++)
+        {
+          grub_uint8_t *dptr;
+          grub_uint8_t *sptr;
+          int sx;
+          int sy;
+          int comp;
+
+          /* Compute the source coordinate that the destination coordinate
+             maps to.  Note: sx/sw = dx/dw  =>  sx = sw*dx/dw. */
+          sx = sw * dx / dw;
+          sy = sh * dy / dh;
+
+          /* Get the address of the pixels in src and dst. */
+          dptr = ddata + dy * dstride + dx * bytes_per_pixel;
+          sptr = sdata + sy * sstride + sx * bytes_per_pixel;
+
+          /* If we have enough space to do so, use bilinear interpolation.
+             Otherwise, fall back to nearest neighbor for this pixel. */
+          if (sx < sw - 1 && sy < sh - 1)
+            {
+              /* Do bilinear interpolation. */
+
+              /* Fixed-point .8 numbers representing the fraction of the
+                 distance in the x (u) and y (v) direction within the
+                 box of 4 pixels in the source. */
+              int u = (256 * sw * dx / dw) - (sx * 256);
+              int v = (256 * sh * dy / dh) - (sy * 256);
+
+              for (comp = 0; comp < bytes_per_pixel; comp++)
+                {
+                  /* Get the component's values for the
+                     four source corner pixels. */
+                  grub_uint8_t f00 = sptr[comp];
+                  grub_uint8_t f10 = sptr[comp + bytes_per_pixel];
+                  grub_uint8_t f01 = sptr[comp + sstride];
+                  grub_uint8_t f11 = sptr[comp + sstride + bytes_per_pixel];
+
+                  /* Do linear interpolations along the top and bottom
+                     rows of the box. */
+                  grub_uint8_t f0y = (256 - v) * f00 / 256 + v * f01 / 256;
+                  grub_uint8_t f1y = (256 - v) * f10 / 256 + v * f11 / 256;
+
+                  /* Interpolate vertically. */
+                  grub_uint8_t fxy = (256 - u) * f0y / 256 + u * f1y / 256;
+
+                  dptr[comp] = fxy;
+                }
+            }
+          else
+            {
+              /* Fall back to nearest neighbor interpolation. */
+              /* Copy the pixel color value. */
+              for (comp = 0; comp < bytes_per_pixel; comp++)
+                dptr[comp] = sptr[comp];
+            }
+        }
+    }
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/video/efi_gop.c b/grub-core/video/efi_gop.c
new file mode 100644 (file)
index 0000000..86a2881
--- /dev/null
@@ -0,0 +1,399 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define grub_video_render_target grub_video_fbrender_target
+
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/video.h>
+#include <grub/video_fb.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/graphics_output.h>
+
+static grub_efi_guid_t graphics_output_guid = GRUB_EFI_GOP_GUID;
+static struct grub_efi_gop *gop;
+static unsigned old_mode;
+static int restore_needed;
+
+static struct
+{
+  struct grub_video_mode_info mode_info;
+  struct grub_video_render_target *render_target;
+  grub_uint8_t *ptr;
+} framebuffer;
+
+
+static int
+check_protocol (void)
+{
+  gop = grub_efi_locate_protocol (&graphics_output_guid, 0);
+  if (gop)
+    return 1;
+
+  return 0;
+}
+
+static grub_err_t
+grub_video_gop_init (void)
+{
+  grub_memset (&framebuffer, 0, sizeof(framebuffer));
+  return grub_video_fb_init ();
+}
+
+static grub_err_t
+grub_video_gop_fini (void)
+{
+  if (restore_needed)
+    {
+      efi_call_2 (gop->set_mode, gop, old_mode);
+      restore_needed = 0;
+    }
+  return grub_video_fb_fini ();
+}
+
+static int
+grub_video_gop_get_bpp (struct grub_efi_gop_mode_info *in)
+{
+  grub_uint32_t total_mask;
+  int i;
+  switch (in->pixel_format)
+    {
+    case GRUB_EFI_GOT_BGRA8:
+    case GRUB_EFI_GOT_RGBA8:
+      return 32;
+
+    case GRUB_EFI_GOT_BITMASK:
+      /* Check overlaps.  */
+      if ((in->pixel_bitmask.r & in->pixel_bitmask.g)
+         || (in->pixel_bitmask.r & in->pixel_bitmask.b)
+         || (in->pixel_bitmask.g & in->pixel_bitmask.b)
+         || (in->pixel_bitmask.r & in->pixel_bitmask.a)
+         || (in->pixel_bitmask.g & in->pixel_bitmask.a)
+         || (in->pixel_bitmask.b & in->pixel_bitmask.a))
+       return 0;
+
+      total_mask = in->pixel_bitmask.r | in->pixel_bitmask.g
+       | in->pixel_bitmask.b | in->pixel_bitmask.a;
+
+      for (i = 31; i >= 0; i--)
+       if (total_mask & (1 << i))
+         return i + 1;
+
+      /* Fall through.  */
+    default:
+      return 0;
+    }
+}
+
+static void
+grub_video_gop_get_bitmask (grub_uint32_t mask, unsigned int *mask_size,
+                           unsigned int *field_pos)
+{
+  int i;
+  int last_p;
+  for (i = 31; i >= 0; i--)
+    if (mask & (1 << i))
+      break;
+  if (i == -1)
+    {
+      *mask_size = *field_pos = 0;
+      return;
+    }
+  last_p = i;
+  for (; i >= 0; i--)
+    if (!(mask & (1 << i)))
+      break;
+  *field_pos = i + 1;
+  *mask_size = last_p - *field_pos + 1;
+}
+
+static grub_err_t
+grub_video_gop_fill_mode_info (struct grub_efi_gop_mode_info *in,
+                              struct grub_video_mode_info *out)
+{
+  out->number_of_colors = 256;
+  out->width = in->width;
+  out->height = in->height;
+  out->mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
+  out->bpp = grub_video_gop_get_bpp (in);
+  out->bytes_per_pixel = out->bpp >> 3;
+  if (!out->bpp)
+    return grub_error (GRUB_ERR_IO, "unsupported video mode");
+  out->pitch = in->pixels_per_scanline * out->bytes_per_pixel;
+
+  switch (in->pixel_format)
+    {
+    case GRUB_EFI_GOT_RGBA8:
+      out->red_mask_size = 8;
+      out->red_field_pos = 0;
+      out->green_mask_size = 8;
+      out->green_field_pos = 8;
+      out->blue_mask_size = 8;
+      out->blue_field_pos = 16;
+      out->reserved_mask_size = 8;
+      out->reserved_field_pos = 24;
+      break;
+
+    case GRUB_EFI_GOT_BGRA8:
+      out->red_mask_size = 8;
+      out->red_field_pos = 16;
+      out->green_mask_size = 8;
+      out->green_field_pos = 8;
+      out->blue_mask_size = 8;
+      out->blue_field_pos = 0;
+      out->reserved_mask_size = 8;
+      out->reserved_field_pos = 24;
+      break;
+
+    case GRUB_EFI_GOT_BITMASK:
+      grub_video_gop_get_bitmask (in->pixel_bitmask.r, &out->red_mask_size,
+                                 &out->red_field_pos);
+      grub_video_gop_get_bitmask (in->pixel_bitmask.g, &out->green_mask_size,
+                                 &out->green_field_pos);
+      grub_video_gop_get_bitmask (in->pixel_bitmask.b, &out->blue_mask_size,
+                                 &out->blue_field_pos);
+      grub_video_gop_get_bitmask (in->pixel_bitmask.a, &out->reserved_mask_size,
+                                 &out->reserved_field_pos);
+      break;
+
+    default:
+      return grub_error (GRUB_ERR_IO, "unsupported video mode");
+    }
+
+  out->blit_format = grub_video_get_blit_format (out);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_gop_setup (unsigned int width, unsigned int height,
+                     unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused)))
+{
+  unsigned int depth;
+  struct grub_efi_gop_mode_info *info = NULL;
+  unsigned best_mode = 0;
+  grub_err_t err;
+  unsigned bpp;
+  int found = 0;
+  unsigned long long best_volume = 0;
+
+  depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
+    >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
+
+  /* Keep current mode if possible.  */
+  if (gop->mode->info)
+    {
+      bpp = grub_video_gop_get_bpp (gop->mode->info);
+      if (bpp && ((width == gop->mode->info->width
+                  && height == gop->mode->info->height)
+                 || (width == 0 && height == 0))
+         && (depth == bpp || depth == 0))
+       {
+         grub_dprintf ("video", "GOP: keeping mode %d\n", gop->mode->mode);
+         best_mode = gop->mode->mode;
+         found = 1;
+       }
+    }
+  if (!found)
+    {
+      unsigned mode;
+      grub_dprintf ("video", "GOP: %d modes detected\n", gop->mode->max_mode);
+      for (mode = 0; mode < gop->mode->max_mode; mode++)
+       {
+         grub_efi_uintn_t size;
+         grub_efi_status_t status;
+        
+         status = efi_call_4 (gop->query_mode, gop, mode, &size, &info);
+         if (status)
+           {
+             info = 0;
+             break;
+           }
+
+         grub_dprintf ("video", "GOP: mode %d: %dx%d\n", mode, info->width,
+                       info->height);
+
+         bpp = grub_video_gop_get_bpp (info);
+         if (!bpp)
+           {
+             grub_dprintf ("video", "GOP: mode %d: incompatible pixel mode\n",
+                           mode);
+             continue;
+           }
+
+         grub_dprintf ("video", "GOP: mode %d: depth %d\n", mode, bpp);
+
+         if (!(((info->width == width && info->height == height)
+               || (width == 0 && height == 0))
+               && (bpp == depth || depth == 0)))
+           {
+             grub_dprintf ("video", "GOP: mode %d: rejected\n", mode);
+             continue;
+           }
+
+         if (best_volume < ((unsigned long long) info->width)
+             * ((unsigned long long) info->height)
+             * ((unsigned long long) bpp))
+           {
+             best_volume = ((unsigned long long) info->width)
+               * ((unsigned long long) info->height)
+               * ((unsigned long long) bpp);
+             best_mode = mode;
+           }
+         found = 1;
+       }
+    }
+
+  if (!found)
+    {
+      grub_dprintf ("video", "GOP: no mode found\n");
+      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found");
+    }
+
+  if (best_mode != gop->mode->mode)
+    {
+      if (!restore_needed)
+       {
+         old_mode = gop->mode->mode;
+         restore_needed = 1;
+       }
+      efi_call_2 (gop->set_mode, gop, best_mode);
+    }
+
+  info = gop->mode->info;
+
+  err = grub_video_gop_fill_mode_info (info, &framebuffer.mode_info);
+  if (err)
+    {
+      grub_dprintf ("video", "GOP: couldn't fill mode info\n");
+      return err;
+    }
+
+  framebuffer.ptr = (void *) (grub_addr_t) gop->mode->fb_base;
+
+  grub_dprintf ("video", "GOP: initialising FB @ %p %dx%dx%d\n",
+               framebuffer.ptr, framebuffer.mode_info.width,
+               framebuffer.mode_info.height, framebuffer.mode_info.bpp);
+  err = grub_video_fb_create_render_target_from_pointer
+    (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr);
+
+  if (err)
+    {
+      grub_dprintf ("video", "GOP: Couldn't create FB target\n");
+      return err;
+    }
+  err = grub_video_fb_set_active_render_target (framebuffer.render_target);
+  if (err)
+    {
+      grub_dprintf ("video", "GOP: Couldn't set FB target\n");
+      return err;
+    }
+  err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
+                                  grub_video_fbstd_colors);
+
+  if (err)
+    grub_dprintf ("video", "GOP: Couldn't set palette\n");
+  else
+    grub_dprintf ("video", "GOP: Success\n");
+  return err;
+}
+
+static grub_err_t
+grub_video_gop_swap_buffers (void)
+{
+  /* TODO: Implement buffer swapping.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_gop_set_active_render_target (struct grub_video_render_target *target)
+{
+  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
+    target = framebuffer.render_target;
+
+  return grub_video_fb_set_active_render_target (target);
+}
+
+static grub_err_t
+grub_video_gop_get_info_and_fini (struct grub_video_mode_info *mode_info,
+                                 void **framebuf)
+{
+  grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
+  *framebuf = (char *) framebuffer.ptr;
+
+  grub_video_fb_fini ();
+
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_video_adapter grub_video_gop_adapter =
+  {
+    .name = "EFI GOP driver",
+    .id = GRUB_VIDEO_DRIVER_EFI_GOP,
+
+    .init = grub_video_gop_init,
+    .fini = grub_video_gop_fini,
+    .setup = grub_video_gop_setup,
+    .get_info = grub_video_fb_get_info,
+    .get_info_and_fini = grub_video_gop_get_info_and_fini,
+    .set_palette = grub_video_fb_set_palette,
+    .get_palette = grub_video_fb_get_palette,
+    .set_viewport = grub_video_fb_set_viewport,
+    .get_viewport = grub_video_fb_get_viewport,
+    .map_color = grub_video_fb_map_color,
+    .map_rgb = grub_video_fb_map_rgb,
+    .map_rgba = grub_video_fb_map_rgba,
+    .unmap_color = grub_video_fb_unmap_color,
+    .fill_rect = grub_video_fb_fill_rect,
+    .blit_bitmap = grub_video_fb_blit_bitmap,
+    .blit_render_target = grub_video_fb_blit_render_target,
+    .scroll = grub_video_fb_scroll,
+    .swap_buffers = grub_video_gop_swap_buffers,
+    .create_render_target = grub_video_fb_create_render_target,
+    .delete_render_target = grub_video_fb_delete_render_target,
+    .set_active_render_target = grub_video_gop_set_active_render_target,
+    .get_active_render_target = grub_video_fb_get_active_render_target,
+
+    .next = 0
+  };
+
+GRUB_MOD_INIT(efi_gop)
+{
+  if (check_protocol ())
+    grub_video_register (&grub_video_gop_adapter);
+}
+
+GRUB_MOD_FINI(efi_gop)
+{
+  if (restore_needed)
+    {
+      efi_call_2 (gop->set_mode, gop, old_mode);
+      restore_needed = 0;
+    }
+  if (gop)
+    grub_video_unregister (&grub_video_gop_adapter);
+}
diff --git a/grub-core/video/efi_uga.c b/grub-core/video/efi_uga.c
new file mode 100644 (file)
index 0000000..eb4e6b4
--- /dev/null
@@ -0,0 +1,339 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define grub_video_render_target grub_video_fbrender_target
+
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/video.h>
+#include <grub/video_fb.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/uga_draw.h>
+#include <grub/pci.h>
+
+static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
+static struct grub_efi_uga_draw_protocol *uga;
+static grub_uint32_t uga_fb;
+static grub_uint32_t uga_pitch;
+
+static struct
+{
+  struct grub_video_mode_info mode_info;
+  struct grub_video_render_target *render_target;
+  grub_uint8_t *ptr;
+} framebuffer;
+
+#define RGB_MASK       0xffffff
+#define RGB_MAGIC      0x121314
+#define LINE_MIN       800
+#define LINE_MAX       4096
+#define FBTEST_STEP    (0x10000 >> 2)
+#define FBTEST_COUNT   8
+
+static int
+find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
+{
+  grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base;
+  int i;
+
+  for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP)
+    {
+      if ((*base & RGB_MASK) == RGB_MAGIC)
+       {
+         int j;
+
+         for (j = LINE_MIN; j <= LINE_MAX; j++)
+           {
+             if ((base[j] & RGB_MASK) == RGB_MAGIC)
+               {
+                 *fb_base = (grub_uint32_t) (grub_target_addr_t) base;
+                 *line_len = j << 2;
+
+                 return 1;
+               }
+           }
+
+         break;
+       }
+    }
+
+  return 0;
+}
+
+static int
+find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
+{
+  int found = 0;
+
+  auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
+                                      grub_pci_id_t pciid);
+
+  int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
+                                 grub_pci_id_t pciid)
+    {
+      grub_pci_address_t addr;
+
+      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+      if (grub_pci_read (addr) >> 24 == 0x3)
+       {
+         int i;
+
+         grub_dprintf ("fb", "Display controller: %d:%d.%d\nDevice id: %x\n",
+                       grub_pci_get_bus (dev), grub_pci_get_device (dev),
+                       grub_pci_get_function (dev), pciid);
+         addr += 8;
+         for (i = 0; i < 6; i++, addr += 4)
+           {
+             grub_uint32_t old_bar1, old_bar2, type;
+             grub_uint64_t base64;
+
+             old_bar1 = grub_pci_read (addr);
+             if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
+               continue;
+
+             type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
+             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+               {
+                 if (i == 5)
+                   break;
+
+                 old_bar2 = grub_pci_read (addr + 4);
+               }
+             else
+               old_bar2 = 0;
+
+             base64 = old_bar2;
+             base64 <<= 32;
+             base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
+
+             grub_dprintf ("fb", "%s(%d): 0x%llx\n",
+                           ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
+                           "VMEM" : "MMIO"), i,
+                          (unsigned long long) base64);
+
+             if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found))
+               {
+                 *fb_base = base64;
+                 if (find_line_len (fb_base, line_len))
+                   found++;
+               }
+
+             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
+               {
+                 i++;
+                 addr += 4;
+               }
+           }
+       }
+
+      return found;
+    }
+
+  grub_pci_iterate (find_card);
+  return found;
+}
+
+static int
+check_protocol (void)
+{
+  grub_efi_uga_draw_protocol_t *c;
+
+  c = grub_efi_locate_protocol (&uga_draw_guid, 0);
+  if (c)
+    {
+      grub_uint32_t width, height, depth, rate, pixel;
+      int ret;
+
+      if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate))
+       return 0;
+
+      grub_efi_set_text_mode (0);
+      pixel = RGB_MAGIC;
+      efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel,
+                  GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0);
+      ret = find_framebuf (&uga_fb, &uga_pitch);
+      grub_efi_set_text_mode (1);
+
+      if (ret)
+       {
+         uga = c;
+         return 1;
+       }
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_video_uga_init (void)
+{
+  grub_memset (&framebuffer, 0, sizeof(framebuffer));
+  return grub_video_fb_init ();
+}
+
+static grub_err_t
+grub_video_uga_fini (void)
+{
+  return grub_video_fb_fini ();
+}
+
+static grub_err_t
+grub_video_uga_setup (unsigned int width, unsigned int height,
+                     unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused)))
+{
+  unsigned int depth;
+  int found = 0;
+
+  depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
+    >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
+
+  {
+    grub_uint32_t w;
+    grub_uint32_t h;
+    grub_uint32_t d;
+    grub_uint32_t r;
+
+    if ((! efi_call_5 (uga->get_mode, uga, &w, &h, &d, &r)) &&
+       ((! width) || (width == w)) &&
+       ((! height) || (height == h)) &&
+       ((! depth) || (depth == d)))
+      {
+       framebuffer.mode_info.width = w;
+       framebuffer.mode_info.height = h;
+       framebuffer.mode_info.pitch = uga_pitch;
+       framebuffer.ptr = (grub_uint8_t *) (grub_target_addr_t) uga_fb;
+
+       found = 1;
+      }
+  }
+
+  if (found)
+    {
+      grub_err_t err;
+
+      framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
+      framebuffer.mode_info.bpp = 32;
+      framebuffer.mode_info.bytes_per_pixel = 4;
+      framebuffer.mode_info.number_of_colors = 256; /* TODO: fix me.  */
+      framebuffer.mode_info.red_mask_size = 8;
+      framebuffer.mode_info.red_field_pos = 16;
+      framebuffer.mode_info.green_mask_size = 8;
+      framebuffer.mode_info.green_field_pos = 8;
+      framebuffer.mode_info.blue_mask_size = 8;
+      framebuffer.mode_info.blue_field_pos = 0;
+      framebuffer.mode_info.reserved_mask_size = 8;
+      framebuffer.mode_info.reserved_field_pos = 24;
+
+      framebuffer.mode_info.blit_format =
+       grub_video_get_blit_format (&framebuffer.mode_info);
+
+      err = grub_video_fb_create_render_target_from_pointer
+       (&framebuffer.render_target,
+        &framebuffer.mode_info,
+        framebuffer.ptr);
+
+      if (err)
+       return err;
+
+      err = grub_video_fb_set_active_render_target
+       (framebuffer.render_target);
+
+      if (err)
+       return err;
+
+      err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
+                                      grub_video_fbstd_colors);
+
+      return err;
+    }
+
+  return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found");
+}
+
+static grub_err_t
+grub_video_uga_swap_buffers (void)
+{
+  /* TODO: Implement buffer swapping.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_uga_set_active_render_target (struct grub_video_render_target *target)
+{
+  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
+    target = framebuffer.render_target;
+
+  return grub_video_fb_set_active_render_target (target);
+}
+
+static grub_err_t
+grub_video_uga_get_info_and_fini (struct grub_video_mode_info *mode_info,
+                                 void **framebuf)
+{
+  grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
+  *framebuf = (char *) framebuffer.ptr;
+
+  grub_video_fb_fini ();
+
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_video_adapter grub_video_uga_adapter =
+  {
+    .name = "EFI UGA driver",
+    .id = GRUB_VIDEO_DRIVER_EFI_UGA,
+
+    .init = grub_video_uga_init,
+    .fini = grub_video_uga_fini,
+    .setup = grub_video_uga_setup,
+    .get_info = grub_video_fb_get_info,
+    .get_info_and_fini = grub_video_uga_get_info_and_fini,
+    .set_palette = grub_video_fb_set_palette,
+    .get_palette = grub_video_fb_get_palette,
+    .set_viewport = grub_video_fb_set_viewport,
+    .get_viewport = grub_video_fb_get_viewport,
+    .map_color = grub_video_fb_map_color,
+    .map_rgb = grub_video_fb_map_rgb,
+    .map_rgba = grub_video_fb_map_rgba,
+    .unmap_color = grub_video_fb_unmap_color,
+    .fill_rect = grub_video_fb_fill_rect,
+    .blit_bitmap = grub_video_fb_blit_bitmap,
+    .blit_render_target = grub_video_fb_blit_render_target,
+    .scroll = grub_video_fb_scroll,
+    .swap_buffers = grub_video_uga_swap_buffers,
+    .create_render_target = grub_video_fb_create_render_target,
+    .delete_render_target = grub_video_fb_delete_render_target,
+    .set_active_render_target = grub_video_uga_set_active_render_target,
+    .get_active_render_target = grub_video_fb_get_active_render_target,
+  };
+
+GRUB_MOD_INIT(efi_uga)
+{
+  if (check_protocol ())
+    grub_video_register (&grub_video_uga_adapter);
+}
+
+GRUB_MOD_FINI(efi_uga)
+{
+  if (uga)
+    grub_video_unregister (&grub_video_uga_adapter);
+}
diff --git a/grub-core/video/emu/sdl.c b/grub-core/video/emu/sdl.c
new file mode 100644 (file)
index 0000000..d261db6
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define grub_video_render_target grub_video_fbrender_target
+
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/video.h>
+#include <grub/video_fb.h>
+#include <SDL/SDL.h>
+
+static SDL_Surface *window = 0;
+static struct grub_video_render_target *sdl_render_target;
+static struct grub_video_mode_info mode_info;
+
+static grub_err_t
+grub_video_sdl_set_palette (unsigned int start, unsigned int count,
+                            struct grub_video_palette_data *palette_data);
+
+static grub_err_t
+grub_video_sdl_init (void)
+{
+  window = 0;
+
+  if (SDL_Init (SDL_INIT_VIDEO) < 0)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "Couldn't init SDL: %s",
+                      SDL_GetError ());
+
+  grub_memset (&mode_info, 0, sizeof (mode_info));
+
+  return grub_video_fb_init ();
+}
+
+static grub_err_t
+grub_video_sdl_fini (void)
+{
+  SDL_Quit ();
+  window = 0;
+
+  grub_memset (&mode_info, 0, sizeof (mode_info));
+
+  return grub_video_fb_fini ();
+}
+
+static inline unsigned int
+get_mask_size (grub_uint32_t mask)
+{
+  unsigned i;
+  for (i = 0; mask > 1U << i; i++);
+  return i;
+}
+
+static grub_err_t
+grub_video_sdl_setup (unsigned int width, unsigned int height,
+                      unsigned int mode_type, unsigned int mode_mask)
+{
+  int depth;
+  int flags = 0;
+  grub_err_t err;
+
+  /* Decode depth from mode_type.  If it is zero, then autodetect.  */
+  depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
+          >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
+
+  if (depth == 0)
+    depth = 32;
+
+  if (width == 0 && height == 0)
+    {
+      width = 800;
+      height = 600;
+    }
+
+  if ((mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)
+      || !(mode_mask & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED))
+    flags |= SDL_DOUBLEBUF;
+
+  window = SDL_SetVideoMode (width, height, depth, flags | SDL_HWSURFACE);
+  if (! window)
+    window = SDL_SetVideoMode (width, height, depth, flags | SDL_SWSURFACE);
+  if (! window)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "Couldn't open window: %s",
+                      SDL_GetError ());
+
+  grub_memset (&sdl_render_target, 0, sizeof (sdl_render_target));
+
+  mode_info.width = window->w;
+  mode_info.height = window->h;
+  mode_info.mode_type = 0;
+  if (window->flags & SDL_DOUBLEBUF)
+    mode_info.mode_type
+      |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
+  if (window->format->palette)
+    mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
+  else
+    mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_RGB;
+
+  mode_info.bpp = window->format->BitsPerPixel;
+  mode_info.bytes_per_pixel = window->format->BytesPerPixel;
+  mode_info.pitch = window->pitch;
+
+  /* In index color mode, number of colors.  In RGB mode this is 256.  */
+  if (window->format->palette)
+    mode_info.number_of_colors
+      = 1 << window->format->BitsPerPixel;
+  else
+    mode_info.number_of_colors = 256;
+
+  if (! window->format->palette)
+    {
+      mode_info.red_mask_size
+       = get_mask_size (window->format->Rmask >> window->format->Rshift);
+      mode_info.red_field_pos = window->format->Rshift;
+      mode_info.green_mask_size
+       = get_mask_size (window->format->Gmask >> window->format->Gshift);
+      mode_info.green_field_pos = window->format->Gshift;
+      mode_info.blue_mask_size
+       = get_mask_size (window->format->Bmask >> window->format->Bshift);
+      mode_info.blue_field_pos = window->format->Bshift;
+      mode_info.reserved_mask_size
+       = get_mask_size (window->format->Amask >> window->format->Ashift);
+      mode_info.reserved_field_pos = window->format->Ashift;
+      mode_info.blit_format
+       = grub_video_get_blit_format (&mode_info);
+    }
+
+  err = grub_video_fb_create_render_target_from_pointer (&sdl_render_target,
+                                                        &mode_info,
+                                                        window->pixels);
+  if (err)
+    return err;
+
+  /* Copy default palette to initialize emulated palette.  */
+  grub_video_sdl_set_palette (0, (sizeof (grub_video_fbstd_colors)
+                                 / sizeof (grub_video_fbstd_colors[0])),
+                             grub_video_fbstd_colors);
+
+  /* Reset render target to SDL one.  */
+  return grub_video_fb_set_active_render_target (sdl_render_target);
+}
+
+static grub_err_t
+grub_video_sdl_set_palette (unsigned int start, unsigned int count,
+                            struct grub_video_palette_data *palette_data)
+{
+  unsigned i;
+  if (window->format->palette)
+    {
+      SDL_Color *tmp = grub_malloc (count * sizeof (tmp[0]));
+      for (i = 0; i < count; i++)
+       {
+         tmp[i].r = palette_data[i].r;
+         tmp[i].g = palette_data[i].g;
+         tmp[i].b = palette_data[i].b;
+         tmp[i].unused = palette_data[i].a;
+       }
+      SDL_SetColors (window, tmp, start, count);
+      grub_free (tmp);
+    }
+
+  return grub_video_fb_set_palette (start, count, palette_data);
+}
+
+static grub_err_t
+grub_video_sdl_swap_buffers (void)
+{
+  if (SDL_Flip (window) < 0)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "couldn't swap buffers: %s",
+                      SDL_GetError ());
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_sdl_set_active_render_target (struct grub_video_render_target *target)
+{
+  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
+    return grub_video_fb_set_active_render_target (sdl_render_target);
+
+  return grub_video_fb_set_active_render_target (target);
+}
+
+static struct grub_video_adapter grub_video_sdl_adapter =
+  {
+    .name = "SDL Video Driver",
+
+    .init = grub_video_sdl_init,
+    .fini = grub_video_sdl_fini,
+    .setup = grub_video_sdl_setup,
+    .get_info = grub_video_fb_get_info,
+    .set_palette = grub_video_sdl_set_palette,
+    .get_palette = grub_video_fb_get_palette,
+    .set_viewport = grub_video_fb_set_viewport,
+    .get_viewport = grub_video_fb_get_viewport,
+    .map_color = grub_video_fb_map_color,
+    .map_rgb = grub_video_fb_map_rgb,
+    .map_rgba = grub_video_fb_map_rgba,
+    .unmap_color = grub_video_fb_unmap_color,
+    .fill_rect = grub_video_fb_fill_rect,
+    .blit_bitmap = grub_video_fb_blit_bitmap,
+    .blit_render_target = grub_video_fb_blit_render_target,
+    .scroll = grub_video_fb_scroll,
+    .swap_buffers = grub_video_sdl_swap_buffers,
+    .create_render_target = grub_video_fb_create_render_target,
+    .delete_render_target = grub_video_fb_delete_render_target,
+    .set_active_render_target = grub_video_sdl_set_active_render_target,
+    .get_active_render_target = grub_video_fb_get_active_render_target,
+
+    .next = 0
+  };
+
+GRUB_MOD_INIT(sdl)
+{
+  grub_video_register (&grub_video_sdl_adapter);
+}
+
+GRUB_MOD_FINI(sdl)
+{
+  grub_video_unregister (&grub_video_sdl_adapter);
+}
diff --git a/grub-core/video/fb/fbblit.c b/grub-core/video/fb/fbblit.c
new file mode 100644 (file)
index 0000000..15797be
--- /dev/null
@@ -0,0 +1,1420 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* SPECIAL NOTES!
+
+   Please note following when reading the code below:
+
+   - In this driver we assume that every memory can be accessed by same memory
+   bus.  If there are different address spaces do not use this code as a base
+   code for other archs.
+
+   - Every function in this code assumes that bounds checking has been done in
+   previous phase and they are opted out in here.  */
+
+#include <grub/video_fb.h>
+#include <grub/fbblit.h>
+#include <grub/fbutil.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/video.h>
+
+/* Generic replacing blitter (slow).  Works for every supported format.  */
+void
+grub_video_fbblit_replace (struct grub_video_fbblit_info *dst,
+                          struct grub_video_fbblit_info *src,
+                          int x, int y, int width, int height,
+                          int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t src_red;
+  grub_uint8_t src_green;
+  grub_uint8_t src_blue;
+  grub_uint8_t src_alpha;
+  grub_video_color_t src_color;
+  grub_video_color_t dst_color;
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+       {
+         src_color = get_pixel (src, i + offset_x, j + offset_y);
+
+         grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
+                                        &src_blue, &src_alpha);
+
+         dst_color = grub_video_fb_map_rgba (src_red, src_green,
+                                             src_blue, src_alpha);
+
+         set_pixel (dst, x + i, y + j, dst_color);
+       }
+    }
+}
+
+/* Block copy replacing blitter.  Works with modes multiple of 8 bits.  */
+void
+grub_video_fbblit_replace_directN (struct grub_video_fbblit_info *dst,
+                                  struct grub_video_fbblit_info *src,
+                                  int x, int y, int width, int height,
+                                  int offset_x, int offset_y)
+{
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint32_t *dstptr;
+  int bpp;
+
+  bpp = src->mode_info->bytes_per_pixel;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      grub_memmove (dstptr, srcptr, width * bpp);
+    }
+}
+
+/* Optimized replacing blitter for 1-bit to 32bit.  */
+void
+grub_video_fbblit_replace_32bit_1bit (struct grub_video_fbblit_info *dst,
+                                     struct grub_video_fbblit_info *src,
+                                     int x, int y,
+                                     int width, int height,
+                                     int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint32_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+                                   src->mode_info->fg_green,
+                                   src->mode_info->fg_blue,
+                                   src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+                                   src->mode_info->bg_green,
+                                   src->mode_info->bg_blue,
+                                   src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+         if (*srcptr & srcmask)
+           *(grub_uint32_t *) dstptr = fgcolor;
+         else
+           *(grub_uint32_t *) dstptr = bgcolor;
+         srcmask >>= 1;
+         if (!srcmask)
+           {
+             srcptr++;
+             srcmask = 0x80;
+           }
+
+         dstptr += 4;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+       srcmask >>= srcrowskipbit;
+      else
+       {
+         srcptr++;
+         srcmask <<= 8 - srcrowskipbit;
+       }
+      dstptr += dstrowskip;
+    }
+}
+
+
+/* Optimized replacing blitter for 1-bit to 24-bit.  */
+void
+grub_video_fbblit_replace_24bit_1bit (struct grub_video_fbblit_info *dst,
+                                     struct grub_video_fbblit_info *src,
+                                     int x, int y,
+                                     int width, int height,
+                                     int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint32_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+                                   src->mode_info->fg_green,
+                                   src->mode_info->fg_blue,
+                                   src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+                                   src->mode_info->bg_green,
+                                   src->mode_info->bg_blue,
+                                   src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width - 1; i++)
+        {
+         if (*srcptr & srcmask)
+           *(grub_uint32_t *) dstptr = fgcolor;
+         else
+           *(grub_uint32_t *) dstptr = bgcolor;
+         srcmask >>= 1;
+         if (!srcmask)
+           {
+             srcptr++;
+             srcmask = 0x80;
+           }
+
+         dstptr += 3;
+        }
+
+      if (*srcptr & srcmask)
+       {
+         *dstptr++ = fgcolor & 0xff;
+         *dstptr++ = (fgcolor & 0xff00) >> 8;
+         *dstptr++ = (fgcolor & 0xff0000) >> 16;
+       }
+      else
+       {
+         *dstptr++ = bgcolor & 0xff;
+         *dstptr++ = (bgcolor & 0xff00) >> 8;
+         *dstptr++ = (bgcolor & 0xff0000) >> 16;
+       }
+      srcmask >>= 1;
+      if (!srcmask)
+       {
+         srcptr++;
+         srcmask = 0x80;
+       }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+       srcmask >>= srcrowskipbit;
+      else
+       {
+         srcptr++;
+         srcmask <<= 8 - srcrowskipbit;
+       }
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for 1-bit to 16-bit.  */
+void
+grub_video_fbblit_replace_16bit_1bit (struct grub_video_fbblit_info *dst,
+                                     struct grub_video_fbblit_info *src,
+                                     int x, int y,
+                                     int width, int height,
+                                     int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint16_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+                                   src->mode_info->fg_green,
+                                   src->mode_info->fg_blue,
+                                   src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+                                   src->mode_info->bg_green,
+                                   src->mode_info->bg_blue,
+                                   src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+         if (*srcptr & srcmask)
+           *(grub_uint16_t *) dstptr = fgcolor;
+         else
+           *(grub_uint16_t *) dstptr = bgcolor;
+         srcmask >>= 1;
+         if (!srcmask)
+           {
+             srcptr++;
+             srcmask = 0x80;
+           }
+
+         dstptr += 2;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+       srcmask >>= srcrowskipbit;
+      else
+       {
+         srcptr++;
+         srcmask <<= 8 - srcrowskipbit;
+       }
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for 1-bit to 8-bit.  */
+void
+grub_video_fbblit_replace_8bit_1bit (struct grub_video_fbblit_info *dst,
+                                     struct grub_video_fbblit_info *src,
+                                     int x, int y,
+                                     int width, int height,
+                                     int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint8_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+                                   src->mode_info->fg_green,
+                                   src->mode_info->fg_blue,
+                                   src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+                                   src->mode_info->bg_green,
+                                   src->mode_info->bg_blue,
+                                   src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+         if (*srcptr & srcmask)
+           *(grub_uint8_t *) dstptr = fgcolor;
+         else
+           *(grub_uint8_t *) dstptr = bgcolor;
+         srcmask >>= 1;
+         if (!srcmask)
+           {
+             srcptr++;
+             srcmask = 0x80;
+           }
+
+         dstptr++;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+       srcmask >>= srcrowskipbit;
+      else
+       {
+         srcptr++;
+         srcmask <<= 8 - srcrowskipbit;
+       }
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for RGBX8888 to BGRX8888.  */
+void
+grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
+                                            struct grub_video_fbblit_info *src,
+                                            int x, int y,
+                                            int width, int height,
+                                            int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint8_t r = *srcptr++;
+          grub_uint8_t g = *srcptr++;
+          grub_uint8_t b = *srcptr++;
+          grub_uint8_t a = *srcptr++;
+
+          *dstptr++ = b;
+          *dstptr++ = g;
+          *dstptr++ = r;
+          *dstptr++ = a;
+        }
+
+      srcptr += srcrowskip;
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for RGB888 to BGRX8888.  */
+void
+grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst,
+                                          struct grub_video_fbblit_info *src,
+                                          int x, int y,
+                                          int width, int height,
+                                          int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint8_t r = *srcptr++;
+          grub_uint8_t g = *srcptr++;
+          grub_uint8_t b = *srcptr++;
+
+          *dstptr++ = b;
+          *dstptr++ = g;
+          *dstptr++ = r;
+
+          /* Set alpha component as opaque.  */
+          *dstptr++ = 255;
+        }
+
+      srcptr += srcrowskip;
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for RGBX8888 to BGR888.  */
+void
+grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst,
+                                          struct grub_video_fbblit_info *src,
+                                          int x, int y,
+                                          int width, int height,
+                                          int offset_x, int offset_y)
+{
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+  int i;
+  int j;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint32_t color;
+          grub_uint8_t sr;
+          grub_uint8_t sg;
+          grub_uint8_t sb;
+
+          color = *srcptr++;
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          *dstptr++ = sb;
+          *dstptr++ = sg;
+          *dstptr++ = sr;
+        }
+
+      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for RGB888 to BGR888.  */
+void
+grub_video_fbblit_replace_BGR888_RGB888 (struct grub_video_fbblit_info *dst,
+                                        struct grub_video_fbblit_info *src,
+                                        int x, int y,
+                                        int width, int height,
+                                        int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint8_t r = *srcptr++;
+          grub_uint8_t g = *srcptr++;
+          grub_uint8_t b = *srcptr++;
+
+          *dstptr++ = b;
+          *dstptr++ = g;
+          *dstptr++ = r;
+        }
+
+      srcptr += srcrowskip;
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized replacing blitter for RGB888 to RGBX8888.  */
+void
+grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst,
+                                          struct grub_video_fbblit_info *src,
+                                          int x, int y,
+                                          int width, int height,
+                                          int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint32_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          sr = *srcptr++;
+          sg = *srcptr++;
+          sb = *srcptr++;
+
+          /* Set alpha as opaque.  */
+          color = 0xFF000000 | (sb << 16) | (sg << 8) | sr;
+
+          *dstptr++ = color;
+        }
+    }
+}
+
+/* Optimized replacing blitter for RGBX8888 to RGB888.  */
+void
+grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst,
+                                          struct grub_video_fbblit_info *src,
+                                          int x, int y,
+                                          int width, int height,
+                                          int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+       {
+         color = *srcptr++;
+
+         sr = (color >> 0) & 0xFF;
+         sg = (color >> 8) & 0xFF;
+         sb = (color >> 16) & 0xFF;
+
+         *dstptr++ = sr;
+         *dstptr++ = sg;
+         *dstptr++ = sb;
+       }
+    }
+}
+
+/* Optimized replacing blitter for RGBX8888 to indexed color.  */
+void
+grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
+                                         struct grub_video_fbblit_info *src,
+                                         int x, int y,
+                                         int width, int height,
+                                         int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+       {
+         color = *srcptr++;
+
+         sr = (color >> 0) & 0xFF;
+         sg = (color >> 8) & 0xFF;
+         sb = (color >> 16) & 0xFF;
+
+         color = grub_video_fb_map_rgb(sr, sg, sb);
+         *dstptr++ = color & 0xFF;
+       }
+    }
+}
+
+/* Optimized replacing blitter for RGB888 to indexed color.  */
+void
+grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
+                                       struct grub_video_fbblit_info *src,
+                                       int x, int y,
+                                       int width, int height,
+                                       int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          sr = *srcptr++;
+          sg = *srcptr++;
+          sb = *srcptr++;
+
+          color = grub_video_fb_map_rgb(sr, sg, sb);
+
+          *dstptr++ = color & 0xFF;
+        }
+    }
+}
+
+/* Generic blending blitter.  Works for every supported format.  */
+void
+grub_video_fbblit_blend (struct grub_video_fbblit_info *dst,
+                        struct grub_video_fbblit_info *src,
+                        int x, int y, int width, int height,
+                        int offset_x, int offset_y)
+{
+  int i;
+  int j;
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint8_t src_red;
+          grub_uint8_t src_green;
+          grub_uint8_t src_blue;
+          grub_uint8_t src_alpha;
+          grub_uint8_t dst_red;
+          grub_uint8_t dst_green;
+          grub_uint8_t dst_blue;
+          grub_uint8_t dst_alpha;
+          grub_video_color_t src_color;
+          grub_video_color_t dst_color;
+
+          src_color = get_pixel (src, i + offset_x, j + offset_y);
+          grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
+                                        &src_blue, &src_alpha);
+
+          if (src_alpha == 0)
+            continue;
+
+          if (src_alpha == 255)
+            {
+              dst_color = grub_video_fb_map_rgba (src_red, src_green,
+                                                 src_blue, src_alpha);
+              set_pixel (dst, x + i, y + j, dst_color);
+              continue;
+            }
+
+          dst_color = get_pixel (dst, x + i, y + j);
+
+          grub_video_fb_unmap_color_int (dst, dst_color, &dst_red,
+                                        &dst_green, &dst_blue, &dst_alpha);
+
+          dst_red = (((src_red * src_alpha)
+                      + (dst_red * (255 - src_alpha))) / 255);
+          dst_green = (((src_green * src_alpha)
+                        + (dst_green * (255 - src_alpha))) / 255);
+          dst_blue = (((src_blue * src_alpha)
+                       + (dst_blue * (255 - src_alpha))) / 255);
+
+          dst_alpha = src_alpha;
+          dst_color = grub_video_fb_map_rgba (dst_red, dst_green, dst_blue,
+                                             dst_alpha);
+
+          set_pixel (dst, x + i, y + j, dst_color);
+        }
+    }
+}
+
+/* Optimized blending blitter for RGBA8888 to BGRA8888.  */
+void
+grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+                                          struct grub_video_fbblit_info *src,
+                                          int x, int y,
+                                          int width, int height,
+                                          int offset_x, int offset_y)
+{
+  grub_uint32_t *srcptr;
+  grub_uint32_t *dstptr;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+  int i;
+  int j;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint32_t color;
+          unsigned int sr;
+          unsigned int sg;
+          unsigned int sb;
+          unsigned int a;
+          unsigned int dr;
+          unsigned int dg;
+          unsigned int db;
+
+          color = *srcptr++;
+
+          a = color >> 24;
+
+          if (a == 0)
+            {
+              /* Skip transparent source pixels.  */
+              dstptr++;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          if (a == 255)
+            {
+              /* Opaque pixel shortcut.  */
+              dr = sr;
+              dg = sg;
+              db = sb;
+            }
+          else
+            {
+              /* General pixel color blending.  */
+              color = *dstptr;
+
+              dr = (color >> 16) & 0xFF;
+              dr = (dr * (255 - a) + sr * a) / 255;
+              dg = (color >> 8) & 0xFF;
+              dg = (dg * (255 - a) + sg * a) / 255;
+              db = (color >> 0) & 0xFF;
+              db = (db * (255 - a) + sb * a) / 255;
+            }
+
+          color = (a << 24) | (dr << 16) | (dg << 8) | db;
+
+          *dstptr++ = color;
+        }
+
+      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
+      dstptr = (grub_uint32_t *) (((grub_uint8_t *) dstptr) + dstrowskip);
+    }
+}
+
+/* Optimized blending blitter for RGBA8888 to BGR888.  */
+void
+grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst,
+                                        struct grub_video_fbblit_info *src,
+                                        int x, int y,
+                                        int width, int height,
+                                        int offset_x, int offset_y)
+{
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int srcrowskip;
+  unsigned int dstrowskip;
+  int i;
+  int j;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          grub_uint32_t color;
+          unsigned int sr;
+          unsigned int sg;
+          unsigned int sb;
+          unsigned int a;
+          unsigned int dr;
+          unsigned int dg;
+          unsigned int db;
+
+          color = *srcptr++;
+
+          a = color >> 24;
+
+          if (a == 0)
+            {
+              /* Skip transparent source pixels.  */
+              dstptr += 3;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          if (a == 255)
+            {
+              /* Opaque pixel shortcut.  */
+              dr = sr;
+              dg = sg;
+              db = sb;
+            }
+          else
+            {
+              /* General pixel color blending.  */
+              color = *dstptr;
+
+              db = dstptr[0];
+              db = (db * (255 - a) + sb * a) / 255;
+              dg = dstptr[1];
+              dg = (dg * (255 - a) + sg * a) / 255;
+              dr = dstptr[2];
+              dr = (dr * (255 - a) + sr * a) / 255;
+            }
+
+          *dstptr++ = db;
+          *dstptr++ = dg;
+          *dstptr++ = dr;
+        }
+
+      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized blending blitter for RGBA888 to RGBA8888.  */
+void
+grub_video_fbblit_blend_RGBA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
+                                          struct grub_video_fbblit_info *src,
+                                          int x, int y,
+                                          int width, int height,
+                                          int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint32_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+  unsigned int a;
+  unsigned int dr;
+  unsigned int dg;
+  unsigned int db;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          color = *srcptr++;
+
+          a = color >> 24;
+
+          if (a == 0)
+            {
+              dstptr++;
+              continue;
+            }
+
+          if (a == 255)
+            {
+              *dstptr++ = color;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          color = *dstptr;
+
+          dr = (color >> 0) & 0xFF;
+          dg = (color >> 8) & 0xFF;
+          db = (color >> 16) & 0xFF;
+
+          dr = (dr * (255 - a) + sr * a) / 255;
+          dg = (dg * (255 - a) + sg * a) / 255;
+          db = (db * (255 - a) + sb * a) / 255;
+
+          color = (a << 24) | (db << 16) | (dg << 8) | dr;
+
+          *dstptr++ = color;
+        }
+    }
+}
+
+/* Optimized blending blitter for RGBA8888 to RGB888.  */
+void
+grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst,
+                                        struct grub_video_fbblit_info *src,
+                                        int x, int y,
+                                        int width, int height,
+                                        int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+  unsigned int a;
+  unsigned int dr;
+  unsigned int dg;
+  unsigned int db;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          color = *srcptr++;
+
+          a = color >> 24;
+
+          if (a == 0)
+            {
+              dstptr += 3;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          if (a == 255)
+            {
+              *dstptr++ = sr;
+              *dstptr++ = sg;
+              *dstptr++ = sb;
+
+              continue;
+            }
+
+          dr = dstptr[0];
+          dg = dstptr[1];
+          db = dstptr[2];
+
+          dr = (dr * (255 - a) + sr * a) / 255;
+          dg = (dg * (255 - a) + sg * a) / 255;
+          db = (db * (255 - a) + sb * a) / 255;
+
+          *dstptr++ = dr;
+          *dstptr++ = dg;
+          *dstptr++ = db;
+        }
+    }
+}
+
+/* Optimized blending blitter for RGBA8888 to indexed color.  */
+void
+grub_video_fbblit_blend_index_RGBA8888 (struct grub_video_fbblit_info *dst,
+                                       struct grub_video_fbblit_info *src,
+                                       int x, int y,
+                                       int width, int height,
+                                       int offset_x, int offset_y)
+{
+  grub_uint32_t color;
+  int i;
+  int j;
+  grub_uint32_t *srcptr;
+  grub_uint8_t *dstptr;
+  unsigned int sr;
+  unsigned int sg;
+  unsigned int sb;
+  unsigned int a;
+  unsigned char dr;
+  unsigned char dg;
+  unsigned char db;
+  unsigned char da;
+
+  for (j = 0; j < height; j++)
+    {
+      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
+      dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
+
+      for (i = 0; i < width; i++)
+        {
+          color = *srcptr++;
+
+          a = color >> 24;
+
+          if (a == 0)
+            {
+              dstptr++;
+              continue;
+            }
+
+          sr = (color >> 0) & 0xFF;
+          sg = (color >> 8) & 0xFF;
+          sb = (color >> 16) & 0xFF;
+
+          if (a == 255)
+            {
+              color = grub_video_fb_map_rgb(sr, sg, sb);
+              *dstptr++ = color & 0xFF;
+              continue;
+            }
+
+          grub_video_fb_unmap_color_int (dst, *dstptr, &dr, &dg, &db, &da);
+
+          dr = (dr * (255 - a) + sr * a) / 255;
+          dg = (dg * (255 - a) + sg * a) / 255;
+          db = (db * (255 - a) + sb * a) / 255;
+
+          color = grub_video_fb_map_rgb(dr, dg, db);
+
+          *dstptr++ = color & 0xFF;
+        }
+    }
+}
+
+/* Optimized blending blitter for 1-bit to XXXA8888.  */
+void
+grub_video_fbblit_blend_XXXA8888_1bit (struct grub_video_fbblit_info *dst,
+                                      struct grub_video_fbblit_info *src,
+                                      int x, int y,
+                                      int width, int height,
+                                      int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint32_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+                                   src->mode_info->fg_green,
+                                   src->mode_info->fg_blue,
+                                   src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+                                   src->mode_info->bg_green,
+                                   src->mode_info->bg_blue,
+                                   src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+         grub_uint32_t color;
+         grub_uint8_t a;
+
+         if (*srcptr & srcmask)
+           {
+             color = fgcolor;
+             a = src->mode_info->fg_alpha;
+           }
+         else
+           {
+             color = bgcolor;
+             a = src->mode_info->bg_alpha;
+           }
+
+         if (a == 255)
+           *(grub_uint32_t *) dstptr = color;
+         else if (a != 0)
+           {
+             grub_uint8_t s1 = (color >> 0) & 0xFF;
+             grub_uint8_t s2 = (color >> 8) & 0xFF;
+             grub_uint8_t s3 = (color >> 16) & 0xFF;
+
+             grub_uint8_t d1 = (*(grub_uint32_t *) dstptr >> 0) & 0xFF;
+             grub_uint8_t d2 = (*(grub_uint32_t *) dstptr >> 8) & 0xFF;
+             grub_uint8_t d3 = (*(grub_uint32_t *) dstptr >> 16) & 0xFF;
+
+             d1 = (d1 * (255 - a) + s1 * a) / 255;
+             d2 = (d2 * (255 - a) + s2 * a) / 255;
+             d3 = (d3 * (255 - a) + s3 * a) / 255;
+
+             *(grub_uint32_t *) dstptr = (a << 24) | (d3 << 16) | (d2 << 8)
+               | d1;
+           }
+
+         srcmask >>= 1;
+         if (!srcmask)
+           {
+             srcptr++;
+             srcmask = 0x80;
+           }
+
+         dstptr += 4;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+       srcmask >>= srcrowskipbit;
+      else
+       {
+         srcptr++;
+         srcmask <<= 8 - srcrowskipbit;
+       }
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized blending blitter for 1-bit to XXX888.  */
+void
+grub_video_fbblit_blend_XXX888_1bit (struct grub_video_fbblit_info *dst,
+                                    struct grub_video_fbblit_info *src,
+                                    int x, int y,
+                                    int width, int height,
+                                    int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint32_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+                                   src->mode_info->fg_green,
+                                   src->mode_info->fg_blue,
+                                   src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+                                   src->mode_info->bg_green,
+                                   src->mode_info->bg_blue,
+                                   src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+         grub_uint32_t color;
+         grub_uint8_t a;
+         if (*srcptr & srcmask)
+           {
+             color = fgcolor;
+             a = src->mode_info->fg_alpha;
+           }
+         else
+           {
+             color = bgcolor;
+             a = src->mode_info->bg_alpha;
+           }
+
+         if (a == 255)
+           {
+             ((grub_uint8_t *) dstptr)[0] = color & 0xff;
+             ((grub_uint8_t *) dstptr)[1] = (color & 0xff00) >> 8;
+             ((grub_uint8_t *) dstptr)[2] = (color & 0xff0000) >> 16;
+           }
+         else if (a != 0)
+           {
+             grub_uint8_t s1 = (color >> 0) & 0xFF;
+             grub_uint8_t s2 = (color >> 8) & 0xFF;
+             grub_uint8_t s3 = (color >> 16) & 0xFF;
+
+             grub_uint8_t d1 = (*(grub_uint32_t *) dstptr >> 0) & 0xFF;
+             grub_uint8_t d2 = (*(grub_uint32_t *) dstptr >> 8) & 0xFF;
+             grub_uint8_t d3 = (*(grub_uint32_t *) dstptr >> 16) & 0xFF;
+
+             ((grub_uint8_t *) dstptr)[0] = (d1 * (255 - a) + s1 * a) / 255;
+             ((grub_uint8_t *) dstptr)[1] = (d2 * (255 - a) + s2 * a) / 255;
+             ((grub_uint8_t *) dstptr)[2] = (d3 * (255 - a) + s3 * a) / 255;
+           }
+
+         srcmask >>= 1;
+         if (!srcmask)
+           {
+             srcptr++;
+             srcmask = 0x80;
+           }
+
+         dstptr += 3;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+       srcmask >>= srcrowskipbit;
+      else
+       {
+         srcptr++;
+         srcmask <<= 8 - srcrowskipbit;
+       }
+      dstptr += dstrowskip;
+    }
+}
+
+/* Optimized blending blitter for 1-bit to XXX888.  */
+void
+grub_video_fbblit_blend_XXX565_1bit (struct grub_video_fbblit_info *dst,
+                                    struct grub_video_fbblit_info *src,
+                                    int x, int y,
+                                    int width, int height,
+                                    int offset_x, int offset_y)
+{
+  int i;
+  int j;
+  grub_uint8_t *srcptr;
+  grub_uint8_t *dstptr;
+  grub_uint8_t srcmask;
+  unsigned int dstrowskip;
+  unsigned int srcrowskipbyte, srcrowskipbit;
+  grub_uint16_t fgcolor, bgcolor;
+  int bit_index;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+  srcrowskipbyte = (src->mode_info->width - width) >> 3;
+  srcrowskipbit = (src->mode_info->width - width) & 7;
+
+  bit_index = offset_y * src->mode_info->width + offset_x;
+  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
+  srcmask = 1 << (~bit_index & 7);
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
+                                   src->mode_info->fg_green,
+                                   src->mode_info->fg_blue,
+                                   src->mode_info->fg_alpha);
+
+  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
+                                   src->mode_info->bg_green,
+                                   src->mode_info->bg_blue,
+                                   src->mode_info->bg_alpha);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+         grub_uint32_t color;
+         grub_uint8_t a;
+         if (*srcptr & srcmask)
+           {
+             color = fgcolor;
+             a = src->mode_info->fg_alpha;
+           }
+         else
+           {
+             color = bgcolor;
+             a = src->mode_info->bg_alpha;
+           }
+
+         if (a == 255)
+           *(grub_uint16_t *) dstptr = color;
+         else if (a != 0)
+           {
+             grub_uint8_t s1 = (color >> 0) & 0x1F;
+             grub_uint8_t s2 = (color >> 5) & 0x3F;
+             grub_uint8_t s3 = (color >> 11) & 0x1F;
+
+             grub_uint8_t d1 = (*(grub_uint16_t *) dstptr >> 0) & 0x1F;
+             grub_uint8_t d2 = (*(grub_uint16_t *) dstptr >> 5) & 0x3F;
+             grub_uint8_t d3 = (*(grub_uint16_t *) dstptr >> 11) & 0x1F;
+
+             d1 = (d1 * (255 - a) + s1 * a) / 255;
+             d2 = (d2 * (255 - a) + s2 * a) / 255;
+             d3 = (d3 * (255 - a) + s3 * a) / 255;
+
+             *(grub_uint16_t *) dstptr = (d1 & 0x1f) | ((d2 & 0x3f) << 5)
+               | ((d3 & 0x1f) << 11);
+           }
+
+         srcmask >>= 1;
+         if (!srcmask)
+           {
+             srcptr++;
+             srcmask = 0x80;
+           }
+
+         dstptr += 2;
+        }
+
+      srcptr += srcrowskipbyte;
+      if (srcmask >> srcrowskipbit)
+       srcmask >>= srcrowskipbit;
+      else
+       {
+         srcptr++;
+         srcmask <<= 8 - srcrowskipbit;
+       }
+      dstptr += dstrowskip;
+    }
+}
diff --git a/grub-core/video/fb/fbfill.c b/grub-core/video/fb/fbfill.c
new file mode 100644 (file)
index 0000000..a4ca7c2
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* SPECIAL NOTES!
+
+   Please note following when reading the code below:
+
+   - In this driver we assume that every memory can be accessed by same memory
+     bus.  If there are different address spaces do not use this code as a base
+     code for other archs.
+
+   - Every function in this code assumes that bounds checking has been done in
+     previous phase and they are opted out in here.  */
+
+#include <grub/video_fb.h>
+#include <grub/fbfill.h>
+#include <grub/fbutil.h>
+#include <grub/types.h>
+#include <grub/video.h>
+
+/* Generic filler that works for every supported mode.  */
+void
+grub_video_fbfill (struct grub_video_fbblit_info *dst,
+                  grub_video_color_t color, int x, int y,
+                  int width, int height)
+{
+  int i;
+  int j;
+
+  for (j = 0; j < height; j++)
+    for (i = 0; i < width; i++)
+      set_pixel (dst, x + i, y + j, color);
+}
+
+/* Optimized filler for direct color 32 bit modes.  It is assumed that color
+   is already mapped to destination format.  */
+void
+grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst,
+                           grub_video_color_t color, int x, int y,
+                           int width, int height)
+{
+  int i;
+  int j;
+  grub_uint32_t *dstptr;
+  grub_size_t rowskip;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  /* Get the start address.  */
+  dstptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        *dstptr++ = color;
+
+      /* Advance the dest pointer to the right location on the next line.  */
+      dstptr = (grub_uint32_t *) (((char *) dstptr) + rowskip);
+    }
+}
+
+/* Optimized filler for direct color 24 bit modes.  It is assumed that color
+   is already mapped to destination format.  */
+void
+grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst,
+                           grub_video_color_t color, int x, int y,
+                           int width, int height)
+{
+  int i;
+  int j;
+  grub_size_t rowskip;
+  grub_uint8_t *dstptr;
+  grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
+  grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
+  grub_uint8_t fill2 = (grub_uint8_t)((color >> 16) & 0xFF);
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  /* Get the start address.  */
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          *dstptr++ = fill0;
+          *dstptr++ = fill1;
+          *dstptr++ = fill2;
+        }
+
+      /* Advance the dest pointer to the right location on the next line.  */
+      dstptr += rowskip;
+    }
+}
+
+/* Optimized filler for direct color 16 bit modes.  It is assumed that color
+   is already mapped to destination format.  */
+void
+grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst,
+                           grub_video_color_t color, int x, int y,
+                           int width, int height)
+{
+  int i;
+  int j;
+  grub_size_t rowskip;
+  grub_uint8_t *dstptr;
+  grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
+  grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  /* Get the start address.  */
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        {
+          *dstptr++ = fill0;
+          *dstptr++ = fill1;
+        }
+
+      /* Advance the dest pointer to the right location on the next line.  */
+      dstptr += rowskip;
+    }
+}
+
+/* Optimized filler for index color.  It is assumed that color
+   is already mapped to destination format.  */
+void
+grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst,
+                          grub_video_color_t color, int x, int y,
+                          int width, int height)
+{
+  int i;
+  int j;
+  grub_size_t rowskip;
+  grub_uint8_t *dstptr;
+  grub_uint8_t fill = (grub_uint8_t)color & 0xFF;
+
+  /* Calculate the number of bytes to advance from the end of one line
+     to the beginning of the next line.  */
+  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+
+  /* Get the start address.  */
+  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
+
+  for (j = 0; j < height; j++)
+    {
+      for (i = 0; i < width; i++)
+        *dstptr++ = fill;
+
+      /* Advance the dest pointer to the right location on the next line.  */
+      dstptr += rowskip;
+    }
+}
diff --git a/grub-core/video/fb/fbutil.c b/grub-core/video/fb/fbutil.c
new file mode 100644 (file)
index 0000000..511beaa
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* SPECIAL NOTES!
+
+   Please note following when reading the code below:
+
+   - In this driver we assume that every memory can be accessed by same memory
+     bus.  If there are different address spaces do not use this code as a base
+     code for other archs.
+
+   - Every function in this code assumes that bounds checking has been done in
+     previous phase and they are opted out in here.  */
+
+#include <grub/fbutil.h>
+#include <grub/types.h>
+#include <grub/video.h>
+
+grub_uint8_t *
+grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
+              unsigned int x, unsigned int y)
+{
+  grub_uint8_t *ptr = 0;
+
+  switch (source->mode_info->bpp)
+    {
+    case 32:
+      ptr = source->data + y * source->mode_info->pitch + x * 4;
+      break;
+
+    case 24:
+      ptr = source->data + y * source->mode_info->pitch + x * 3;
+      break;
+
+    case 16:
+    case 15:
+      ptr = source->data + y * source->mode_info->pitch + x * 2;
+      break;
+
+    case 8:
+      ptr = source->data + y * source->mode_info->pitch + x;
+      break;
+
+    case 1:
+      /* For 1-bit bitmaps, addressing needs to be done at the bit level
+         and it doesn't make sense, in general, to ask for a pointer
+         to a particular pixel's data.  */
+      break;
+    }
+
+  return ptr;
+}
+
+grub_video_color_t
+get_pixel (struct grub_video_fbblit_info *source,
+           unsigned int x, unsigned int y)
+{
+  grub_video_color_t color = 0;
+
+  switch (source->mode_info->bpp)
+    {
+    case 32:
+      color = *(grub_uint32_t *)grub_video_fb_get_video_ptr (source, x, y);
+      break;
+
+    case 24:
+      {
+        grub_uint8_t *ptr;
+        ptr = grub_video_fb_get_video_ptr (source, x, y);
+        color = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16);
+      }
+      break;
+
+    case 16:
+    case 15:
+      color = *(grub_uint16_t *)grub_video_fb_get_video_ptr (source, x, y);
+      break;
+
+    case 8:
+      color = *(grub_uint8_t *)grub_video_fb_get_video_ptr (source, x, y);
+      break;
+
+    case 1:
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
+        {
+          int bit_index = y * source->mode_info->width + x;
+          grub_uint8_t *ptr = source->data + bit_index / 8;
+          int bit_pos = 7 - bit_index % 8;
+          color = (*ptr >> bit_pos) & 0x01;
+        }
+      break;
+
+    default:
+      break;
+    }
+
+  return color;
+}
+
+void
+set_pixel (struct grub_video_fbblit_info *source,
+           unsigned int x, unsigned int y, grub_video_color_t color)
+{
+  switch (source->mode_info->bpp)
+    {
+    case 32:
+      {
+        grub_uint32_t *ptr;
+
+        ptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (source, x, y);
+
+        *ptr = color;
+      }
+      break;
+
+    case 24:
+      {
+        grub_uint8_t *ptr;
+        grub_uint8_t *colorptr = (grub_uint8_t *)&color;
+
+        ptr = grub_video_fb_get_video_ptr (source, x, y);
+
+        ptr[0] = colorptr[0];
+        ptr[1] = colorptr[1];
+        ptr[2] = colorptr[2];
+      }
+      break;
+
+    case 16:
+    case 15:
+      {
+        grub_uint16_t *ptr;
+
+        ptr = (grub_uint16_t *)grub_video_fb_get_video_ptr (source, x, y);
+
+        *ptr = (grub_uint16_t) (color & 0xFFFF);
+      }
+      break;
+
+    case 8:
+      {
+        grub_uint8_t *ptr;
+
+        ptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (source, x, y);
+
+        *ptr = (grub_uint8_t) (color & 0xFF);
+      }
+      break;
+
+    case 1:
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
+        {
+          int bit_index = y * source->mode_info->width + x;
+          grub_uint8_t *ptr = source->data + bit_index / 8;
+          int bit_pos = 7 - bit_index % 8;
+          *ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos);
+        }
+      break;
+
+    default:
+      break;
+    }
+}
diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c
new file mode 100644 (file)
index 0000000..9c5577b
--- /dev/null
@@ -0,0 +1,1289 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/video.h>
+#include <grub/video_fb.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/fbblit.h>
+#include <grub/fbfill.h>
+#include <grub/fbutil.h>
+#include <grub/bitmap.h>
+
+static struct grub_video_fbrender_target *render_target;
+struct grub_video_palette_data *palette;
+static unsigned int palette_size;
+
+/* Specify "standard" VGA palette, some video cards may
+   need this and this will also be used when using RGB modes.  */
+struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLORS] =
+  {
+    // {R, G, B, A}
+    {0x00, 0x00, 0x00, 0xFF}, // 0 = black
+    {0x00, 0x00, 0xA8, 0xFF}, // 1 = blue
+    {0x00, 0xA8, 0x00, 0xFF}, // 2 = green
+    {0x00, 0xA8, 0xA8, 0xFF}, // 3 = cyan
+    {0xA8, 0x00, 0x00, 0xFF}, // 4 = red
+    {0xA8, 0x00, 0xA8, 0xFF}, // 5 = magenta
+    {0xA8, 0x54, 0x00, 0xFF}, // 6 = brown
+    {0xA8, 0xA8, 0xA8, 0xFF}, // 7 = light gray
+
+    {0x54, 0x54, 0x54, 0xFF}, // 8 = dark gray
+    {0x54, 0x54, 0xFE, 0xFF}, // 9 = bright blue
+    {0x54, 0xFE, 0x54, 0xFF}, // 10 = bright green
+    {0x54, 0xFE, 0xFE, 0xFF}, // 11 = bright cyan
+    {0xFE, 0x54, 0x54, 0xFF}, // 12 = bright red
+    {0xFE, 0x54, 0xFE, 0xFF}, // 13 = bright magenta
+    {0xFE, 0xFE, 0x54, 0xFF}, // 14 = yellow
+    {0xFE, 0xFE, 0xFE, 0xFF}  // 15 = white
+  };
+
+grub_err_t
+grub_video_fb_init (void)
+{
+  grub_free (palette);
+  render_target = 0;
+  palette = 0;
+  palette_size = 0;
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_fini (void)
+{
+  /* TODO: destroy render targets.  */
+
+  grub_free (palette);
+  render_target = 0;
+  palette = 0;
+  palette_size = 0;
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_get_info (struct grub_video_mode_info *mode_info)
+{
+  /* Copy mode info from active render target.  */
+  grub_memcpy (mode_info, &render_target->mode_info,
+               sizeof (struct grub_video_mode_info));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_get_palette (unsigned int start, unsigned int count,
+                          struct grub_video_palette_data *palette_data)
+{
+  unsigned int i;
+
+  /* Assume that we know everything from index color palette.  */
+  for (i = 0; (i < count) && ((i + start) < palette_size); i++)
+    palette_data[i] = palette[start + i];
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_set_palette (unsigned int start, unsigned int count,
+                          struct grub_video_palette_data *palette_data)
+{
+  unsigned i;
+  if (start + count > palette_size)
+    {
+      palette_size = start + count;
+      palette = grub_realloc (palette, sizeof (palette[0]) * palette_size);
+      if (!palette)
+       {
+         grub_video_fb_fini ();
+         return grub_errno;
+       }
+    }
+  for (i = 0; (i < count) && ((i + start) < palette_size); i++)
+    palette[start + i] = palette_data[i];
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_set_viewport (unsigned int x, unsigned int y,
+                           unsigned int width, unsigned int height)
+{
+  /* Make sure viewport is withing screen dimensions.  If viewport was set
+     to be out of the region, mark its size as zero.  */
+  if (x > render_target->mode_info.width)
+    {
+      x = 0;
+      width = 0;
+    }
+
+  if (y > render_target->mode_info.height)
+    {
+      y = 0;
+      height = 0;
+    }
+
+  if (x + width > render_target->mode_info.width)
+    width = render_target->mode_info.width - x;
+
+  if (y + height > render_target->mode_info.height)
+    height = render_target->mode_info.height - y;
+
+  render_target->viewport.x = x;
+  render_target->viewport.y = y;
+  render_target->viewport.width = width;
+  render_target->viewport.height = height;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_get_viewport (unsigned int *x, unsigned int *y,
+                           unsigned int *width, unsigned int *height)
+{
+  if (x) *x = render_target->viewport.x;
+  if (y) *y = render_target->viewport.y;
+  if (width) *width = render_target->viewport.width;
+  if (height) *height = render_target->viewport.height;
+
+  return GRUB_ERR_NONE;
+}
+
+/* Maps color name to target optimized color format.  */
+grub_video_color_t
+grub_video_fb_map_color (grub_uint32_t color_name)
+{
+  /* TODO: implement color theme mapping code.  */
+
+  if (color_name < palette_size)
+    {
+      if ((render_target->mode_info.mode_type
+           & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+        return color_name;
+      else
+        {
+          grub_video_color_t color;
+
+          color = grub_video_fb_map_rgb (palette[color_name].r,
+                                        palette[color_name].g,
+                                        palette[color_name].b);
+
+          return color;
+        }
+    }
+
+  return 0;
+}
+
+/* Maps RGB to target optimized color format.  */
+grub_video_color_t
+grub_video_fb_map_rgb (grub_uint8_t red, grub_uint8_t green,
+                      grub_uint8_t blue)
+{
+  if ((render_target->mode_info.mode_type
+       & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+    {
+      int minindex = 0;
+      int delta = 0;
+      int tmp;
+      int val;
+      unsigned i;
+
+      /* Find best matching color.  */
+      for (i = 0; i < palette_size; i++)
+        {
+          val = palette[i].r - red;
+          tmp = val * val;
+          val = palette[i].g - green;
+          tmp += val * val;
+          val = palette[i].b - blue;
+          tmp += val * val;
+
+          if (i == 0)
+            delta = tmp;
+
+          if (tmp < delta)
+            {
+              delta = tmp;
+              minindex = i;
+              if (tmp == 0)
+                break;
+            }
+        }
+
+      return minindex;
+    }
+  else if ((render_target->mode_info.mode_type
+            & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
+    {
+       if (red == render_target->mode_info.fg_red
+           && green == render_target->mode_info.fg_green
+           && blue == render_target->mode_info.fg_blue)
+         return 1;
+       else
+         return 0;
+    }
+  else
+    {
+      grub_uint32_t value;
+      grub_uint8_t alpha = 255; /* Opaque color.  */
+
+      red >>= 8 - render_target->mode_info.red_mask_size;
+      green >>= 8 - render_target->mode_info.green_mask_size;
+      blue >>= 8 - render_target->mode_info.blue_mask_size;
+      alpha >>= 8 - render_target->mode_info.reserved_mask_size;
+
+      value = red << render_target->mode_info.red_field_pos;
+      value |= green << render_target->mode_info.green_field_pos;
+      value |= blue << render_target->mode_info.blue_field_pos;
+      value |= alpha << render_target->mode_info.reserved_field_pos;
+
+      return value;
+    }
+
+}
+
+/* Maps RGBA to target optimized color format.  */
+grub_video_color_t
+grub_video_fb_map_rgba (grub_uint8_t red, grub_uint8_t green,
+                       grub_uint8_t blue, grub_uint8_t alpha)
+{
+  if ((render_target->mode_info.mode_type
+       & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+    /* No alpha available in index color modes, just use
+       same value as in only RGB modes.  */
+    return grub_video_fb_map_rgb (red, green, blue);
+  else if ((render_target->mode_info.mode_type
+            & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
+    {
+      if (red == render_target->mode_info.fg_red
+          && green == render_target->mode_info.fg_green
+          && blue == render_target->mode_info.fg_blue
+          && alpha == render_target->mode_info.fg_alpha)
+        return 1;
+      else
+        return 0;
+    }
+  else
+    {
+      grub_uint32_t value;
+
+      red >>= 8 - render_target->mode_info.red_mask_size;
+      green >>= 8 - render_target->mode_info.green_mask_size;
+      blue >>= 8 - render_target->mode_info.blue_mask_size;
+      alpha >>= 8 - render_target->mode_info.reserved_mask_size;
+
+      value = red << render_target->mode_info.red_field_pos;
+      value |= green << render_target->mode_info.green_field_pos;
+      value |= blue << render_target->mode_info.blue_field_pos;
+      value |= alpha << render_target->mode_info.reserved_field_pos;
+
+      return value;
+    }
+}
+
+/* Splits target optimized format to components.  */
+grub_err_t
+grub_video_fb_unmap_color (grub_video_color_t color,
+                          grub_uint8_t *red, grub_uint8_t *green,
+                          grub_uint8_t *blue, grub_uint8_t *alpha)
+{
+  struct grub_video_fbblit_info target_info;
+
+  target_info.mode_info = &render_target->mode_info;
+  target_info.data = render_target->data;
+
+  grub_video_fb_unmap_color_int (&target_info, color, red, green, blue, alpha);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Splits color in source format to components.  */
+void
+grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source,
+                              grub_video_color_t color,
+                              grub_uint8_t *red, grub_uint8_t *green,
+                              grub_uint8_t *blue, grub_uint8_t *alpha)
+{
+  struct grub_video_mode_info *mode_info;
+  mode_info = source->mode_info;
+
+  if ((mode_info->mode_type
+       & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
+    {
+      /* If we have an out-of-bounds color, return transparent black.  */
+      if (color > 255)
+        {
+          *red = 0;
+          *green = 0;
+          *blue = 0;
+          *alpha = 0;
+          return;
+        }
+
+      *red = palette[color].r;
+      *green = palette[color].g;
+      *blue = palette[color].b;
+      *alpha = palette[color].a;
+      return;
+    }
+  else if ((mode_info->mode_type
+            & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
+    {
+      if (color & 1)
+        {
+          *red = mode_info->fg_red;
+          *green = mode_info->fg_green;
+          *blue = mode_info->fg_blue;
+          *alpha = mode_info->fg_alpha;
+        }
+      else
+        {
+          *red = mode_info->bg_red;
+          *green = mode_info->bg_green;
+          *blue = mode_info->bg_blue;
+          *alpha = mode_info->bg_alpha;
+        }
+    }
+  else
+    {
+      grub_uint32_t tmp;
+
+      /* Get red component.  */
+      tmp = color >> mode_info->red_field_pos;
+      tmp &= (1 << mode_info->red_mask_size) - 1;
+      tmp <<= 8 - mode_info->red_mask_size;
+      tmp |= (1 << (8 - mode_info->red_mask_size)) - 1;
+      *red = tmp & 0xFF;
+
+      /* Get green component.  */
+      tmp = color >> mode_info->green_field_pos;
+      tmp &= (1 << mode_info->green_mask_size) - 1;
+      tmp <<= 8 - mode_info->green_mask_size;
+      tmp |= (1 << (8 - mode_info->green_mask_size)) - 1;
+      *green = tmp & 0xFF;
+
+      /* Get blue component.  */
+      tmp = color >> mode_info->blue_field_pos;
+      tmp &= (1 << mode_info->blue_mask_size) - 1;
+      tmp <<= 8 - mode_info->blue_mask_size;
+      tmp |= (1 << (8 - mode_info->blue_mask_size)) - 1;
+      *blue = tmp & 0xFF;
+
+      /* Get alpha component.  */
+      if (source->mode_info->reserved_mask_size > 0)
+        {
+          tmp = color >> mode_info->reserved_field_pos;
+          tmp &= (1 << mode_info->reserved_mask_size) - 1;
+          tmp <<= 8 - mode_info->reserved_mask_size;
+          tmp |= (1 << (8 - mode_info->reserved_mask_size)) - 1;
+        }
+      else
+        /* If there is no alpha component, assume it opaque.  */
+        tmp = 255;
+
+      *alpha = tmp & 0xFF;
+    }
+}
+
+grub_err_t
+grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
+                        unsigned int width, unsigned int height)
+{
+  struct grub_video_fbblit_info target;
+
+  /* Make sure there is something to do.  */
+  if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
+    return GRUB_ERR_NONE;
+  if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
+    return GRUB_ERR_NONE;
+
+  /* Do not allow drawing out of viewport.  */
+  if (x < 0)
+    {
+      width += x;
+      x = 0;
+    }
+  if (y < 0)
+    {
+      height += y;
+      y = 0;
+    }
+
+  if ((x + width) > render_target->viewport.width)
+    width = render_target->viewport.width - x;
+  if ((y + height) > render_target->viewport.height)
+    height = render_target->viewport.height - y;
+
+  /* Add viewport offset.  */
+  x += render_target->viewport.x;
+  y += render_target->viewport.y;
+
+  /* Use fbblit_info to encapsulate rendering.  */
+  target.mode_info = &render_target->mode_info;
+  target.data = render_target->data;
+
+  /* Try to figure out more optimized version.  Note that color is already
+     mapped to target format so we can make assumptions based on that.  */
+  if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+    {
+      grub_video_fbfill_direct32 (&target, color, x, y,
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+    {
+      grub_video_fbfill_direct32 (&target, color, x, y,
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+    {
+      grub_video_fbfill_direct24 (&target, color, x, y,
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_565)
+    {
+      grub_video_fbfill_direct16 (&target, color, x, y,
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_565)
+    {
+      grub_video_fbfill_direct16 (&target, color, x, y,
+                                        width, height);
+      return GRUB_ERR_NONE;
+    }
+  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+    {
+      grub_video_fbfill_direct8 (&target, color, x, y,
+                                      width, height);
+      return GRUB_ERR_NONE;
+    }
+
+  /* No optimized version found, use default (slow) filler.  */
+  grub_video_fbfill (&target, color, x, y, width, height);
+
+  return GRUB_ERR_NONE;
+}
+
+/* NOTE: This function assumes that given coordinates are within bounds of
+   handled data.  */
+static void
+common_blitter (struct grub_video_fbblit_info *target,
+                struct grub_video_fbblit_info *source,
+                enum grub_video_blit_operators oper, int x, int y,
+                unsigned int width, unsigned int height,
+                int offset_x, int offset_y)
+{
+  if (oper == GRUB_VIDEO_BLIT_REPLACE)
+    {
+      /* Try to figure out more optimized version for replace operator.  */
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+       {
+         if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+           {
+             grub_video_fbblit_replace_directN (target, source,
+                                                      x, y, width, height,
+                                                      offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+           {
+             grub_video_fbblit_replace_BGRX8888_RGBX8888 (target, source,
+                                                                x, y, width, height,
+                                                                offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+           {
+             grub_video_fbblit_replace_BGR888_RGBX8888 (target, source,
+                                                              x, y, width, height,
+                                                              offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+           {
+             grub_video_fbblit_replace_RGB888_RGBX8888 (target, source,
+                                                              x, y, width, height,
+                                                              offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+           {
+             grub_video_fbblit_replace_index_RGBX8888 (target, source,
+                                                             x, y, width, height,
+                                                             offset_x, offset_y);
+             return;
+           }
+       }
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+       {
+         if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+           {
+             grub_video_fbblit_replace_BGRX8888_RGB888 (target, source,
+                                                              x, y, width, height,
+                                                              offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+           {
+             grub_video_fbblit_replace_RGBX8888_RGB888 (target, source,
+                                                              x, y, width, height,
+                                                              offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+           {
+             grub_video_fbblit_replace_BGR888_RGB888 (target, source,
+                                                            x, y, width, height,
+                                                            offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+           {
+             grub_video_fbblit_replace_directN (target, source,
+                                                      x, y, width, height,
+                                                      offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+           {
+             grub_video_fbblit_replace_index_RGB888 (target, source,
+                                                           x, y, width, height,
+                                                           offset_x, offset_y);
+             return;
+           }
+       }
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+       {
+         if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+           {
+             grub_video_fbblit_replace_directN (target, source,
+                                                      x, y, width, height,
+                                                      offset_x, offset_y);
+             return;
+           }
+       }
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+       {
+         if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+           {
+             grub_video_fbblit_replace_directN (target, source,
+                                                      x, y, width, height,
+                                                      offset_x, offset_y);
+             return;
+           }
+       }
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
+       {
+         if (target->mode_info->bpp == 32)
+           {
+             grub_video_fbblit_replace_32bit_1bit (target, source,
+                                                   x, y, width, height,
+                                                   offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->bpp == 24)
+           {
+             grub_video_fbblit_replace_24bit_1bit (target, source,
+                                                   x, y, width, height,
+                                                   offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->bpp == 16)
+           {
+             grub_video_fbblit_replace_16bit_1bit (target, source,
+                                                   x, y, width, height,
+                                                   offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->bpp == 8)
+           {
+             grub_video_fbblit_replace_8bit_1bit (target, source,
+                                                  x, y, width, height,
+                                                  offset_x, offset_y);
+             return;
+           }
+       }
+
+      /* No optimized replace operator found, use default (slow) blitter.  */
+      grub_video_fbblit_replace (target, source, x, y, width, height,
+                                      offset_x, offset_y);
+    }
+  else
+    {
+      /* Try to figure out more optimized blend operator.  */
+      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+       {
+         if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+           {
+             grub_video_fbblit_blend_BGRA8888_RGBA8888 (target, source,
+                                                              x, y, width, height,
+                                                              offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+           {
+             grub_video_fbblit_blend_RGBA8888_RGBA8888 (target, source,
+                                                              x, y, width, height,
+                                                              offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+           {
+             grub_video_fbblit_blend_BGR888_RGBA8888 (target, source,
+                                                            x, y, width, height,
+                                                            offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+           {
+             grub_video_fbblit_blend_RGB888_RGBA8888 (target, source,
+                                                            x, y, width, height,
+                                                            offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+           {
+             grub_video_fbblit_blend_index_RGBA8888 (target, source,
+                                                           x, y, width, height,
+                                                           offset_x, offset_y);
+             return;
+           }
+       }
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+       {
+         /* Note: There is really no alpha information here, so blend is
+            changed to replace.  */
+
+         if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
+           {
+             grub_video_fbblit_replace_BGRX8888_RGB888 (target, source,
+                                                              x, y, width, height,
+                                                              offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+           {
+             grub_video_fbblit_replace_RGBX8888_RGB888 (target, source,
+                                                              x, y, width, height,
+                                                              offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
+           {
+             grub_video_fbblit_replace_BGR888_RGB888 (target, source,
+                                                            x, y, width, height,
+                                                            offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+           {
+             grub_video_fbblit_replace_directN (target, source,
+                                                      x, y, width, height,
+                                                      offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
+           {
+             grub_video_fbblit_replace_index_RGB888 (target, source,
+                                                           x, y, width, height,
+                                                           offset_x, offset_y);
+             return;
+           }
+       }
+      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
+       {
+         if (target->mode_info->blit_format
+             == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888
+             || target->mode_info->blit_format
+             == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
+           {
+             grub_video_fbblit_blend_XXXA8888_1bit (target, source,
+                                                    x, y, width, height,
+                                                    offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format
+                  == GRUB_VIDEO_BLIT_FORMAT_BGR_888
+                  || target->mode_info->blit_format
+                  == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
+           {
+             grub_video_fbblit_blend_XXX888_1bit (target, source,
+                                                  x, y, width, height,
+                                                  offset_x, offset_y);
+             return;
+           }
+         else if (target->mode_info->blit_format
+                  == GRUB_VIDEO_BLIT_FORMAT_BGR_565
+                  || target->mode_info->blit_format
+                  == GRUB_VIDEO_BLIT_FORMAT_RGB_565)
+           {
+             grub_video_fbblit_blend_XXX565_1bit (target, source,
+                                                  x, y, width, height,
+                                                  offset_x, offset_y);
+             return;
+           }
+
+       }
+
+
+      /* No optimized blend operation found, use default (slow) blitter.  */
+      grub_video_fbblit_blend (target, source, x, y, width, height,
+                                    offset_x, offset_y);
+    }
+}
+
+grub_err_t
+grub_video_fb_blit_bitmap (struct grub_video_bitmap *bitmap,
+                          enum grub_video_blit_operators oper, int x, int y,
+                          int offset_x, int offset_y,
+                          unsigned int width, unsigned int height)
+{
+  struct grub_video_fbblit_info source;
+  struct grub_video_fbblit_info target;
+
+  /* Make sure there is something to do.  */
+  if ((width == 0) || (height == 0))
+    return GRUB_ERR_NONE;
+  if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
+    return GRUB_ERR_NONE;
+  if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
+    return GRUB_ERR_NONE;
+  if ((x + (int)bitmap->mode_info.width) < 0)
+    return GRUB_ERR_NONE;
+  if ((y + (int)bitmap->mode_info.height) < 0)
+    return GRUB_ERR_NONE;
+  if ((offset_x >= (int)bitmap->mode_info.width)
+      || (offset_x + (int)width < 0))
+    return GRUB_ERR_NONE;
+  if ((offset_y >= (int)bitmap->mode_info.height)
+      || (offset_y + (int)height < 0))
+    return GRUB_ERR_NONE;
+
+  /* If we have negative coordinates, optimize drawing to minimum.  */
+  if (offset_x < 0)
+    {
+      width += offset_x;
+      x -= offset_x;
+      offset_x = 0;
+    }
+
+  if (offset_y < 0)
+    {
+      height += offset_y;
+      y -= offset_y;
+      offset_y = 0;
+    }
+
+  if (x < 0)
+    {
+      width += x;
+      offset_x -= x;
+      x = 0;
+    }
+
+  if (y < 0)
+    {
+      height += y;
+      offset_y -= y;
+      y = 0;
+    }
+
+  /* Do not allow drawing out of viewport.  */
+  if ((x + width) > render_target->viewport.width)
+    width = render_target->viewport.width - x;
+  if ((y + height) > render_target->viewport.height)
+    height = render_target->viewport.height - y;
+
+  if ((offset_x + width) > bitmap->mode_info.width)
+    width = bitmap->mode_info.width - offset_x;
+  if ((offset_y + height) > bitmap->mode_info.height)
+    height = bitmap->mode_info.height - offset_y;
+
+  /* Limit drawing to source render target dimensions.  */
+  if (width > bitmap->mode_info.width)
+    width = bitmap->mode_info.width;
+
+  if (height > bitmap->mode_info.height)
+    height = bitmap->mode_info.height;
+
+  /* Add viewport offset.  */
+  x += render_target->viewport.x;
+  y += render_target->viewport.y;
+
+  /* Use fbblit_info to encapsulate rendering.  */
+  source.mode_info = &bitmap->mode_info;
+  source.data = bitmap->data;
+  target.mode_info = &render_target->mode_info;
+  target.data = render_target->data;
+
+  /* Do actual blitting.  */
+  common_blitter (&target, &source, oper, x, y, width, height,
+                  offset_x, offset_y);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source,
+                                   enum grub_video_blit_operators oper,
+                                   int x, int y, int offset_x, int offset_y,
+                                   unsigned int width, unsigned int height)
+{
+  struct grub_video_fbblit_info source_info;
+  struct grub_video_fbblit_info target_info;
+
+  /* Make sure there is something to do.  */
+  if ((width == 0) || (height == 0))
+    return GRUB_ERR_NONE;
+  if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
+    return GRUB_ERR_NONE;
+  if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
+    return GRUB_ERR_NONE;
+  if ((x + (int)source->mode_info.width) < 0)
+    return GRUB_ERR_NONE;
+  if ((y + (int)source->mode_info.height) < 0)
+    return GRUB_ERR_NONE;
+  if ((offset_x >= (int)source->mode_info.width)
+      || (offset_x + (int)width < 0))
+    return GRUB_ERR_NONE;
+  if ((offset_y >= (int)source->mode_info.height)
+      || (offset_y + (int)height < 0))
+    return GRUB_ERR_NONE;
+
+  /* If we have negative coordinates, optimize drawing to minimum.  */
+  if (offset_x < 0)
+    {
+      width += offset_x;
+      x -= offset_x;
+      offset_x = 0;
+    }
+
+  if (offset_y < 0)
+    {
+      height += offset_y;
+      y -= offset_y;
+      offset_y = 0;
+    }
+
+  if (x < 0)
+    {
+      width += x;
+      offset_x -= x;
+      x = 0;
+    }
+
+  if (y < 0)
+    {
+      height += y;
+      offset_y -= y;
+      y = 0;
+    }
+
+  /* Do not allow drawing out of viewport.  */
+  if ((x + width) > render_target->viewport.width)
+    width = render_target->viewport.width - x;
+  if ((y + height) > render_target->viewport.height)
+    height = render_target->viewport.height - y;
+
+  if ((offset_x + width) > source->mode_info.width)
+    width = source->mode_info.width - offset_x;
+  if ((offset_y + height) > source->mode_info.height)
+    height = source->mode_info.height - offset_y;
+
+  /* Limit drawing to source render target dimensions.  */
+  if (width > source->mode_info.width)
+    width = source->mode_info.width;
+
+  if (height > source->mode_info.height)
+    height = source->mode_info.height;
+
+  /* Add viewport offset.  */
+  x += render_target->viewport.x;
+  y += render_target->viewport.y;
+
+  /* Use fbblit_info to encapsulate rendering.  */
+  source_info.mode_info = &source->mode_info;
+  source_info.data = source->data;
+  target_info.mode_info = &render_target->mode_info;
+  target_info.data = render_target->data;
+
+  /* Do actual blitting.  */
+  common_blitter (&target_info, &source_info, oper, x, y, width, height,
+                  offset_x, offset_y);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
+{
+  int width;
+  int height;
+  int src_x;
+  int src_y;
+  int dst_x;
+  int dst_y;
+
+  /* 1. Check if we have something to do.  */
+  if ((dx == 0) && (dy == 0))
+    return GRUB_ERR_NONE;
+
+  width = render_target->viewport.width - grub_abs (dx);
+  height = render_target->viewport.height - grub_abs (dy);
+
+  if (dx < 0)
+    {
+      src_x = render_target->viewport.x - dx;
+      dst_x = render_target->viewport.x;
+    }
+  else
+    {
+      src_x = render_target->viewport.x;
+      dst_x = render_target->viewport.x + dx;
+    }
+
+  if (dy < 0)
+    {
+      src_y = render_target->viewport.y - dy;
+      dst_y = render_target->viewport.y;
+    }
+  else
+    {
+      src_y = render_target->viewport.y;
+      dst_y = render_target->viewport.y + dy;
+    }
+
+  /* 2. Check if there is need to copy data.  */
+  if ((grub_abs (dx) < render_target->viewport.width)
+       && (grub_abs (dy) < render_target->viewport.height))
+    {
+      /* 3. Move data in render target.  */
+      struct grub_video_fbblit_info target;
+      int i, j;
+      int linedelta, linelen;
+
+      target.mode_info = &render_target->mode_info;
+      target.data = render_target->data;
+
+      linedelta = target.mode_info->pitch
+       - width * target.mode_info->bytes_per_pixel;
+      linelen = width * target.mode_info->bytes_per_pixel;
+#define DO_SCROLL                                                    \
+      /* Check vertical direction of the move.  */                   \
+      if (dy < 0 || (dy == 0 && dx < 0))                             \
+       {                                                            \
+         dst = (void *) grub_video_fb_get_video_ptr (&target,       \
+                                                     dst_x, dst_y); \
+         src = (void *) grub_video_fb_get_video_ptr (&target,       \
+                                                     src_x, src_y); \
+         /* 3a. Move data upwards.  */                              \
+         for (j = 0; j < height; j++)                               \
+           {                                                        \
+             for (i = 0; i < linelen; i++)                          \
+               *(dst++) = *(src++);                                 \
+             dst += linedelta;                                      \
+             src += linedelta;                                      \
+           }                                                        \
+       }                                                            \
+      else                                                           \
+       {                                                            \
+         /* 3b. Move data downwards.  */                            \
+         dst = (void *) grub_video_fb_get_video_ptr (&target,       \
+                                                     dst_x + width, \
+                                            dst_y + height - 1);    \
+         src = (void *) grub_video_fb_get_video_ptr (&target,       \
+                                                     src_x + width, \
+                                            src_y + height - 1);    \
+         dst--;                                                     \
+          src--;                                                     \
+         for (j = 0; j < height; j++)                               \
+           {                                                        \
+             for (i = 0; i < linelen; i++)                          \
+               *(dst--) = *(src--);                                 \
+             dst -= linedelta;                                      \
+             src -= linedelta;                                      \
+           }                                                        \
+       }
+
+      /* If everything is aligned on 32-bit use 32-bit copy.  */
+      if ((grub_addr_t) grub_video_fb_get_video_ptr (&target, src_x, src_y)
+         % sizeof (grub_uint32_t) == 0
+         && (grub_addr_t) grub_video_fb_get_video_ptr (&target, dst_x, dst_y) 
+         % sizeof (grub_uint32_t) == 0
+         && linelen % sizeof (grub_uint32_t) == 0
+         && linedelta % sizeof (grub_uint32_t) == 0)
+       {
+         grub_uint32_t *src, *dst;
+         linelen /= sizeof (grub_uint32_t);
+         linedelta /= sizeof (grub_uint32_t);
+         DO_SCROLL
+       }
+      /* If everything is aligned on 16-bit use 16-bit copy.  */
+      else if ((grub_addr_t) grub_video_fb_get_video_ptr (&target, src_x, src_y)
+              % sizeof (grub_uint16_t) == 0
+              && (grub_addr_t) grub_video_fb_get_video_ptr (&target,
+                                                            dst_x, dst_y) 
+              % sizeof (grub_uint16_t) == 0
+              && linelen % sizeof (grub_uint16_t) == 0
+              && linedelta % sizeof (grub_uint16_t) == 0)
+       {
+         grub_uint16_t *src, *dst;
+         linelen /= sizeof (grub_uint16_t);
+         linedelta /= sizeof (grub_uint16_t);
+         DO_SCROLL
+       }
+      /* If not aligned at all use 8-bit copy.  */
+      else
+       {
+         grub_uint8_t *src, *dst;
+         DO_SCROLL
+       }       
+    }
+
+  /* 4. Fill empty space with specified color.  In this implementation
+     there might be colliding areas but at the moment there is no need
+     to optimize this.  */
+
+  /* 4a. Fill top & bottom parts.  */
+  if (dy > 0)
+    grub_video_fb_fill_rect (color, 0, 0, render_target->viewport.width, dy);
+  else if (dy < 0)
+    {
+      if (render_target->viewport.height < grub_abs (dy))
+        dy = -render_target->viewport.height;
+
+      grub_video_fb_fill_rect (color, 0, render_target->viewport.height + dy,
+                                render_target->viewport.width, -dy);
+    }
+
+  /* 4b. Fill left & right parts.  */
+  if (dx > 0)
+    grub_video_fb_fill_rect (color, 0, 0,
+                              dx, render_target->viewport.height);
+  else if (dx < 0)
+    {
+      if (render_target->viewport.width < grub_abs (dx))
+        dx = -render_target->viewport.width;
+
+      grub_video_fb_fill_rect (color, render_target->viewport.width + dx, 0,
+                                -dx, render_target->viewport.height);
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+
+grub_err_t
+grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
+                                   unsigned int width, unsigned int height,
+                                   unsigned int mode_type __attribute__ ((unused)))
+{
+  struct grub_video_fbrender_target *target;
+  unsigned int size;
+
+  /* Validate arguments.  */
+  if ((! result)
+      || (width == 0)
+      || (height == 0))
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                       "invalid argument given");
+
+  /* Allocate memory for render target.  */
+  target = grub_malloc (sizeof (struct grub_video_fbrender_target));
+  if (! target)
+    return grub_errno;
+
+  /* TODO: Implement other types too.
+     Currently only 32bit render targets are supported.  */
+
+  /* Mark render target as allocated.  */
+  target->is_allocated = 1;
+
+  /* Maximize viewport.  */
+  target->viewport.x = 0;
+  target->viewport.y = 0;
+  target->viewport.width = width;
+  target->viewport.height = height;
+
+  /* Setup render target format.  */
+  target->mode_info.width = width;
+  target->mode_info.height = height;
+  target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB
+                                | GRUB_VIDEO_MODE_TYPE_ALPHA;
+  target->mode_info.bpp = 32;
+  target->mode_info.bytes_per_pixel = 4;
+  target->mode_info.pitch = target->mode_info.bytes_per_pixel * width;
+  target->mode_info.number_of_colors = palette_size; /* Emulated palette.  */
+  target->mode_info.red_mask_size = 8;
+  target->mode_info.red_field_pos = 0;
+  target->mode_info.green_mask_size = 8;
+  target->mode_info.green_field_pos = 8;
+  target->mode_info.blue_mask_size = 8;
+  target->mode_info.blue_field_pos = 16;
+  target->mode_info.reserved_mask_size = 8;
+  target->mode_info.reserved_field_pos = 24;
+
+  target->mode_info.blit_format = grub_video_get_blit_format (&target->mode_info);
+
+  /* Calculate size needed for the data.  */
+  size = (width * target->mode_info.bytes_per_pixel) * height;
+
+  target->data = grub_malloc (size);
+  if (! target->data)
+    {
+      grub_free (target);
+      return grub_errno;
+    }
+
+  /* Clear render target with black and maximum transparency.  */
+  grub_memset (target->data, 0, size);
+
+  /* TODO: Add render target to render target list.  */
+
+  /* Save result to caller.  */
+  *result = target;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_create_render_target_from_pointer (struct grub_video_fbrender_target **result,
+                                                const struct grub_video_mode_info *mode_info,
+                                                void *ptr)
+{
+  struct grub_video_fbrender_target *target;
+  unsigned y;
+
+  /* Allocate memory for render target.  */
+  target = grub_malloc (sizeof (struct grub_video_fbrender_target));
+  if (! target)
+    return grub_errno;
+
+  /* Mark framebuffer memory as non allocated.  */
+  target->is_allocated = 0;
+  target->data = ptr;
+
+  grub_memcpy (&(target->mode_info), mode_info, sizeof (target->mode_info));
+
+  /* Reset viewport to match new mode.  */
+  target->viewport.x = 0;
+  target->viewport.y = 0;
+  target->viewport.width = mode_info->width;
+  target->viewport.height = mode_info->height;
+
+  /* Clear render target with black and maximum transparency.  */
+  for (y = 0; y < mode_info->height; y++)
+    grub_memset (target->data + mode_info->pitch * y, 0,
+                mode_info->bytes_per_pixel * mode_info->width);
+
+  /* Save result to caller.  */
+  *result = target;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_delete_render_target (struct grub_video_fbrender_target *target)
+{
+  /* If there is no target, then just return without error.  */
+  if (! target)
+    return GRUB_ERR_NONE;
+
+  /* TODO: Delist render target from render target list.  */
+
+  /* If this is software render target, free it's memory.  */
+  if (target->is_allocated)
+    grub_free (target->data);
+
+  /* Free render target.  */
+  grub_free (target);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *target)
+{
+  if (! target->data)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                       "invalid render target given");
+
+  render_target = target;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **target)
+{
+  *target = render_target;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+doublebuf_blit_update_screen (struct grub_video_fbrender_target *front,
+                             struct grub_video_fbrender_target *back)
+{
+  grub_memcpy (front->data, back->data,
+              front->mode_info.pitch * front->mode_info.height);
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **front,
+                                  struct grub_video_fbrender_target **back,
+                                  grub_video_fb_doublebuf_update_screen_t *update_screen,
+                                  struct grub_video_mode_info mode_info,
+                                  void *framebuf)
+{
+  grub_err_t err;
+  int page_size = mode_info.pitch * mode_info.height;
+  void *offscreen_buffer;
+
+  err = grub_video_fb_create_render_target_from_pointer (front, &mode_info,
+                                                        framebuf);
+  if (err)
+    return err;
+
+  offscreen_buffer = grub_malloc (page_size);
+  if (! offscreen_buffer)
+    {
+      grub_video_fb_delete_render_target (*front);
+      *front = 0;
+      return grub_errno;
+    }
+
+  err = grub_video_fb_create_render_target_from_pointer (back, &mode_info,
+                                                        offscreen_buffer);
+
+  if (err)
+    {
+      grub_video_fb_delete_render_target (*front);
+      grub_free (offscreen_buffer);
+      *front = 0;
+      return grub_errno;
+    }
+  (*back)->is_allocated = 1;
+
+  *update_screen = doublebuf_blit_update_screen;
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c
new file mode 100644 (file)
index 0000000..72b8f18
--- /dev/null
@@ -0,0 +1,820 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define grub_video_render_target grub_video_fbrender_target
+
+#include <grub/err.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/vga.h>
+#include <grub/machine/vbe.h>
+#include <grub/video_fb.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/video.h>
+
+static int vbe_detected = -1;
+
+static struct grub_vbe_info_block controller_info;
+static struct grub_vbe_mode_info_block active_vbe_mode_info;
+
+/* Track last mode to support cards which fail on get_mode.  */
+static grub_uint32_t last_set_mode = 3;
+
+static struct
+{
+  struct grub_video_mode_info mode_info;
+  struct grub_video_render_target *front_target;
+  struct grub_video_render_target *back_target;
+
+  unsigned int bytes_per_scan_line;
+  unsigned int bytes_per_pixel;
+  grub_uint32_t active_vbe_mode;
+  grub_uint8_t *ptr;
+  int index_color_mode;
+
+  char *offscreen_buffer;
+
+  grub_size_t page_size;        /* The size of a page in bytes.  */
+
+  /* For page flipping strategy.  */
+  int displayed_page;           /* The page # that is the front buffer.  */
+  int render_page;              /* The page # that is the back buffer.  */
+
+  /* Virtual functions.  */
+  grub_video_fb_doublebuf_update_screen_t update_screen;
+} framebuffer;
+
+static grub_uint32_t initial_vbe_mode;
+static grub_uint16_t *vbe_mode_list;
+
+static void *
+real2pm (grub_vbe_farptr_t ptr)
+{
+  return (void *) ((((unsigned long) ptr & 0xFFFF0000) >> 12UL)
+                   + ((unsigned long) ptr & 0x0000FFFF));
+}
+
+grub_err_t
+grub_vbe_probe (struct grub_vbe_info_block *info_block)
+{
+  struct grub_vbe_info_block *vbe_ib;
+  grub_vbe_status_t status;
+
+  /* Clear caller's controller info block.  */
+  if (info_block)
+    grub_memset (info_block, 0, sizeof (*info_block));
+
+  /* Do not probe more than one time, if not necessary.  */
+  if (vbe_detected == -1 || info_block)
+    {
+      /* Clear old copy of controller info block.  */
+      grub_memset (&controller_info, 0, sizeof (controller_info));
+
+      /* Mark VESA BIOS extension as undetected.  */
+      vbe_detected = 0;
+
+      /* Use low memory scratch area as temporary storage
+         for VESA BIOS call.  */
+      vbe_ib = (struct grub_vbe_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+
+      /* Prepare info block.  */
+      grub_memset (vbe_ib, 0, sizeof (*vbe_ib));
+
+      vbe_ib->signature[0] = 'V';
+      vbe_ib->signature[1] = 'B';
+      vbe_ib->signature[2] = 'E';
+      vbe_ib->signature[3] = '2';
+
+      /* Try to get controller info block.  */
+      status = grub_vbe_bios_get_controller_info (vbe_ib);
+      if (status == GRUB_VBE_STATUS_OK)
+        {
+          /* Copy it for later usage.  */
+          grub_memcpy (&controller_info, vbe_ib, sizeof (controller_info));
+
+          /* Mark VESA BIOS extension as detected.  */
+          vbe_detected = 1;
+        }
+    }
+
+  if (! vbe_detected)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "VESA BIOS Extension not found");
+
+  /* Make copy of controller info block to caller.  */
+  if (info_block)
+    grub_memcpy (info_block, &controller_info, sizeof (*info_block));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_vbe_set_video_mode (grub_uint32_t vbe_mode,
+                        struct grub_vbe_mode_info_block *vbe_mode_info)
+{
+  grub_vbe_status_t status;
+  grub_uint32_t old_vbe_mode;
+  struct grub_vbe_mode_info_block new_vbe_mode_info;
+  grub_err_t err;
+
+  /* Make sure that VBE is supported.  */
+  grub_vbe_probe (0);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* Try to get mode info.  */
+  grub_vbe_get_video_mode_info (vbe_mode, &new_vbe_mode_info);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* For all VESA BIOS modes, force linear frame buffer.  */
+  if (vbe_mode >= 0x100)
+    {
+      /* We only want linear frame buffer modes.  */
+      vbe_mode |= 1 << 14;
+
+      /* Determine frame buffer pixel format.  */
+      switch (new_vbe_mode_info.memory_model)
+        {
+        case GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL:
+          framebuffer.index_color_mode = 1;
+          break;
+
+        case GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR:
+          framebuffer.index_color_mode = 0;
+          break;
+
+        default:
+          return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                             "unsupported pixel format 0x%x",
+                             new_vbe_mode_info.memory_model);
+        }
+    }
+
+  /* Get current mode.  */
+  grub_vbe_get_video_mode (&old_vbe_mode);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* Try to set video mode.  */
+  status = grub_vbe_bios_set_mode (vbe_mode, 0);
+  if (status != GRUB_VBE_STATUS_OK)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "cannot set VBE mode %x", vbe_mode);
+  last_set_mode = vbe_mode;
+
+  /* Save information for later usage.  */
+  framebuffer.active_vbe_mode = vbe_mode;
+  grub_memcpy (&active_vbe_mode_info, &new_vbe_mode_info, sizeof (active_vbe_mode_info));
+
+  if (vbe_mode < 0x100)
+    {
+      /* If this is not a VESA mode, guess address.  */
+      framebuffer.ptr = (grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR;
+      framebuffer.index_color_mode = 1;
+    }
+  else
+    {
+      framebuffer.ptr = (grub_uint8_t *) new_vbe_mode_info.phys_base_addr;
+
+      if (controller_info.version >= 0x300)
+        framebuffer.bytes_per_scan_line = new_vbe_mode_info.lin_bytes_per_scan_line;
+      else
+        framebuffer.bytes_per_scan_line = new_vbe_mode_info.bytes_per_scan_line;
+    }
+
+  /* Check whether mode is text mode or graphics mode.  */
+  if (new_vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_TEXT)
+    {
+      /* Text mode.  */
+
+      /* No special action needed for text mode as it is not supported for
+         graphical support.  */
+    }
+  else
+    {
+      /* Graphics mode.  */
+
+      /* Calculate bytes_per_pixel value.  */
+      switch(new_vbe_mode_info.bits_per_pixel)
+       {
+       case 32: framebuffer.bytes_per_pixel = 4; break;
+       case 24: framebuffer.bytes_per_pixel = 3; break;
+       case 16: framebuffer.bytes_per_pixel = 2; break;
+       case 15: framebuffer.bytes_per_pixel = 2; break;
+       case 8: framebuffer.bytes_per_pixel = 1; break;
+       default:
+         grub_vbe_bios_set_mode (old_vbe_mode, 0);
+         last_set_mode = old_vbe_mode;
+         return grub_error (GRUB_ERR_BAD_DEVICE,
+                            "cannot set VBE mode %x",
+                            vbe_mode);
+         break;
+       }
+
+      /* If video mode is in indexed color, setup default VGA palette.  */
+      if (framebuffer.index_color_mode)
+       {
+         struct grub_vbe_palette_data *palette
+           = (struct grub_vbe_palette_data *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+         unsigned i;
+
+         /* Make sure that the BIOS can reach the palette.  */
+         for (i = 0; i < GRUB_VIDEO_FBSTD_NUMCOLORS; i++)
+           {
+             palette[i].red = grub_video_fbstd_colors[i].r;
+             palette[i].green = grub_video_fbstd_colors[i].g;
+             palette[i].blue = grub_video_fbstd_colors[i].b;
+             palette[i].alignment = 0;
+           }
+
+         status = grub_vbe_bios_set_palette_data (GRUB_VIDEO_FBSTD_NUMCOLORS,
+                                                  0, palette);
+
+         /* Just ignore the status.  */
+         err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
+                                          grub_video_fbstd_colors);
+         if (err)
+           return err;
+
+       }
+    }
+
+  /* Copy mode info for caller.  */
+  if (vbe_mode_info)
+    grub_memcpy (vbe_mode_info, &new_vbe_mode_info, sizeof (*vbe_mode_info));
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_vbe_get_video_mode (grub_uint32_t *mode)
+{
+  grub_vbe_status_t status;
+
+  /* Make sure that VBE is supported.  */
+  grub_vbe_probe (0);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* Try to query current mode from VESA BIOS.  */
+  status = grub_vbe_bios_get_mode (mode);
+  /* XXX: ATI cards don't support get_mode.  */
+  if (status != GRUB_VBE_STATUS_OK)
+    *mode = last_set_mode;
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_vbe_get_video_mode_info (grub_uint32_t mode,
+                              struct grub_vbe_mode_info_block *mode_info)
+{
+  struct grub_vbe_mode_info_block *mi_tmp
+    = (struct grub_vbe_mode_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+  grub_vbe_status_t status;
+
+  /* Make sure that VBE is supported.  */
+  grub_vbe_probe (0);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* If mode is not VESA mode, skip mode info query.  */
+  if (mode >= 0x100)
+    {
+      /* Try to get mode info from VESA BIOS.  */
+      status = grub_vbe_bios_get_mode_info (mode, mi_tmp);
+      if (status != GRUB_VBE_STATUS_OK)
+        return grub_error (GRUB_ERR_BAD_DEVICE,
+                           "cannot get information on the mode %x", mode);
+
+      /* Make copy of mode info block.  */
+      grub_memcpy (mode_info, mi_tmp, sizeof (*mode_info));
+    }
+  else
+    /* Just clear mode info block if it isn't a VESA mode.  */
+    grub_memset (mode_info, 0, sizeof (*mode_info));
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_vbe_init (void)
+{
+  grub_uint16_t *rm_vbe_mode_list;
+  grub_uint16_t *p;
+  grub_size_t vbe_mode_list_size;
+  struct grub_vbe_info_block info_block;
+
+  /* Check if there is adapter present.
+
+     Firmware note: There has been a report that some cards store video mode
+     list in temporary memory.  So we must first use vbe probe to get
+     refreshed information to receive valid pointers and data, and then
+     copy this information to somewhere safe.  */
+  grub_vbe_probe (&info_block);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  /* Copy modelist to local memory.  */
+  p = rm_vbe_mode_list = real2pm (info_block.video_mode_ptr);
+  while(*p++ != 0xFFFF)
+    ;
+
+  vbe_mode_list_size = (grub_addr_t) p - (grub_addr_t) rm_vbe_mode_list;
+  vbe_mode_list = grub_malloc (vbe_mode_list_size);
+  if (! vbe_mode_list)
+    return grub_errno;
+  grub_memcpy (vbe_mode_list, rm_vbe_mode_list, vbe_mode_list_size);
+
+  /* Adapter could be found, figure out initial video mode.  */
+  grub_vbe_get_video_mode (&initial_vbe_mode);
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      /* Free allocated resources.  */
+      grub_free (vbe_mode_list);
+      vbe_mode_list = NULL;
+
+      return grub_errno;
+    }
+
+  /* Reset frame buffer.  */
+  grub_memset (&framebuffer, 0, sizeof(framebuffer));
+
+  return grub_video_fb_init ();
+}
+
+static grub_err_t
+grub_video_vbe_fini (void)
+{
+  grub_vbe_status_t status;
+  grub_err_t err;
+
+  /* Restore old video mode.  */
+  status = grub_vbe_bios_set_mode (initial_vbe_mode, 0);
+  if (status != GRUB_VBE_STATUS_OK)
+    /* TODO: Decide, is this something we want to do.  */
+    return grub_errno;
+  last_set_mode = initial_vbe_mode;
+
+  /* TODO: Free any resources allocated by driver.  */
+  grub_free (vbe_mode_list);
+  vbe_mode_list = NULL;
+
+  err = grub_video_fb_fini ();
+  grub_free (framebuffer.offscreen_buffer);
+  return err;
+}
+
+/*
+  Set framebuffer render target page and display the proper page, based on
+  `doublebuf_state.render_page' and `doublebuf_state.displayed_page',
+  respectively.
+*/
+static grub_err_t
+doublebuf_pageflipping_commit (void)
+{
+  /* Tell the video adapter to display the new front page.  */
+  int display_start_line
+    = framebuffer.mode_info.height * framebuffer.displayed_page;
+
+  grub_vbe_status_t vbe_err =
+    grub_vbe_bios_set_display_start (0, display_start_line);
+
+  if (vbe_err != GRUB_VBE_STATUS_OK)
+    return grub_error (GRUB_ERR_IO, "couldn't commit pageflip");
+
+  return 0;
+}
+
+static grub_err_t
+doublebuf_pageflipping_update_screen (struct grub_video_fbrender_target *front
+                                     __attribute__ ((unused)),
+                                     struct grub_video_fbrender_target *back
+                                     __attribute__ ((unused)))
+{
+  int new_displayed_page;
+  struct grub_video_fbrender_target *target;
+  grub_err_t err;
+
+  /* Swap the page numbers in the framebuffer struct.  */
+  new_displayed_page = framebuffer.render_page;
+  framebuffer.render_page = framebuffer.displayed_page;
+  framebuffer.displayed_page = new_displayed_page;
+
+  err = doublebuf_pageflipping_commit ();
+  if (err)
+    {
+      /* Restore previous state.  */
+      framebuffer.render_page = framebuffer.displayed_page;
+      framebuffer.displayed_page = new_displayed_page;
+      return err;
+    }
+
+  if (framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP)
+    grub_memcpy (framebuffer.ptr + framebuffer.render_page
+                * framebuffer.page_size, framebuffer.ptr
+                + framebuffer.displayed_page * framebuffer.page_size,
+                framebuffer.page_size);
+
+  target = framebuffer.back_target;
+  framebuffer.back_target = framebuffer.front_target;
+  framebuffer.front_target = target;
+
+  err = grub_video_fb_get_active_render_target (&target);
+  if (err)
+    return err;
+
+  if (target == framebuffer.back_target)
+    err = grub_video_fb_set_active_render_target (framebuffer.front_target);
+  else if (target == framebuffer.front_target)
+    err = grub_video_fb_set_active_render_target (framebuffer.back_target);
+
+  return err;
+}
+
+static grub_err_t
+doublebuf_pageflipping_init (void)
+{
+  /* Get video RAM size in bytes.  */
+  grub_size_t vram_size = controller_info.total_memory << 16;
+  grub_err_t err;
+
+  framebuffer.page_size =
+    framebuffer.mode_info.pitch * framebuffer.mode_info.height;
+
+  if (2 * framebuffer.page_size > vram_size)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                      "Not enough video memory for double buffering.");
+
+  framebuffer.displayed_page = 0;
+  framebuffer.render_page = 1;
+
+  framebuffer.update_screen = doublebuf_pageflipping_update_screen;
+
+  err = grub_video_fb_create_render_target_from_pointer (&framebuffer.front_target, &framebuffer.mode_info, framebuffer.ptr);
+  if (err)
+    return err;
+
+  err = grub_video_fb_create_render_target_from_pointer (&framebuffer.back_target, &framebuffer.mode_info, framebuffer.ptr + framebuffer.page_size);
+  if (err)
+    {
+      grub_video_fb_delete_render_target (framebuffer.front_target);
+      return err;
+    }
+
+  /* Set the framebuffer memory data pointer and display the right page.  */
+  err = doublebuf_pageflipping_commit ();
+  if (err)
+    {
+      grub_video_fb_delete_render_target (framebuffer.front_target);
+      grub_video_fb_delete_render_target (framebuffer.back_target);
+      return err;
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+/* Select the best double buffering mode available.  */
+static grub_err_t
+double_buffering_init (unsigned int mode_type, unsigned int mode_mask)
+{
+  grub_err_t err;
+  int updating_swap_needed;
+
+  updating_swap_needed
+    = grub_video_check_mode_flag (mode_type, mode_mask,
+                                 GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP, 0);
+
+  /* Do double buffering only if it's either requested or efficient.  */
+  if (grub_video_check_mode_flag (mode_type, mode_mask,
+                                 GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED,
+                                 !updating_swap_needed))
+    {
+      framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
+      if (updating_swap_needed)
+       framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP;
+      err = doublebuf_pageflipping_init ();
+      if (!err)
+       return GRUB_ERR_NONE;
+      
+      framebuffer.mode_info.mode_type
+       &= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
+            | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
+
+      grub_errno = GRUB_ERR_NONE;
+    }
+
+  if (grub_video_check_mode_flag (mode_type, mode_mask,
+                                 GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED,
+                                 0))
+    {
+      framebuffer.mode_info.mode_type 
+       |= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
+           | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
+
+      err = grub_video_fb_doublebuf_blit_init (&framebuffer.front_target,
+                                              &framebuffer.back_target,
+                                              &framebuffer.update_screen,
+                                              framebuffer.mode_info,
+                                              framebuffer.ptr);
+
+      if (!err)
+       return GRUB_ERR_NONE;
+
+      framebuffer.mode_info.mode_type
+       &= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
+            | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
+
+      grub_errno = GRUB_ERR_NONE;
+    }
+
+  /* Fall back to no double buffering.  */
+  err = grub_video_fb_create_render_target_from_pointer (&framebuffer.front_target, &framebuffer.mode_info, framebuffer.ptr);
+
+  if (err)
+    return err;
+
+  framebuffer.back_target = framebuffer.front_target;
+  framebuffer.update_screen = 0;
+
+  framebuffer.mode_info.mode_type &= ~GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
+
+  return GRUB_ERR_NONE;
+}
+
+
+
+static grub_err_t
+grub_video_vbe_setup (unsigned int width, unsigned int height,
+                      unsigned int mode_type, unsigned int mode_mask)
+{
+  grub_uint16_t *p;
+  struct grub_vbe_mode_info_block vbe_mode_info;
+  struct grub_vbe_mode_info_block best_vbe_mode_info;
+  grub_uint32_t best_vbe_mode = 0;
+  int depth;
+
+  /* Decode depth from mode_type.  If it is zero, then autodetect.  */
+  depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
+          >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
+
+  /* Walk thru mode list and try to find matching mode.  */
+  for (p = vbe_mode_list; *p != 0xFFFF; p++)
+    {
+      grub_uint32_t vbe_mode = *p;
+
+      grub_vbe_get_video_mode_info (vbe_mode, &vbe_mode_info);
+      if (grub_errno != GRUB_ERR_NONE)
+        {
+          /* Could not retrieve mode info, retreat.  */
+          grub_errno = GRUB_ERR_NONE;
+          break;
+        }
+
+      if ((vbe_mode_info.mode_attributes & 0x001) == 0)
+        /* If not available, skip it.  */
+        continue;
+
+      if ((vbe_mode_info.mode_attributes & 0x008) == 0)
+        /* Monochrome is unusable.  */
+        continue;
+
+      if ((vbe_mode_info.mode_attributes & 0x080) == 0)
+        /* We support only linear frame buffer modes.  */
+        continue;
+
+      if ((vbe_mode_info.mode_attributes & 0x010) == 0)
+        /* We allow only graphical modes.  */
+        continue;
+
+      if ((vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL)
+          && (vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR))
+        /* Not compatible memory model.  */
+        continue;
+
+      if (((vbe_mode_info.x_resolution != width)
+          || (vbe_mode_info.y_resolution != height)) && width != 0 && height != 0)
+        /* Non matching resolution.  */
+        continue;
+
+      /* Check if user requested RGB or index color mode.  */
+      if ((mode_mask & GRUB_VIDEO_MODE_TYPE_COLOR_MASK) != 0)
+        {
+         unsigned my_mode_type = 0;
+
+         if (vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL)
+           my_mode_type |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
+
+         if (vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR)
+           my_mode_type |= GRUB_VIDEO_MODE_TYPE_RGB;
+
+         if ((my_mode_type & mode_mask
+              & (GRUB_VIDEO_MODE_TYPE_RGB | GRUB_VIDEO_MODE_TYPE_INDEX_COLOR))
+             != (mode_type & mode_mask
+                 & (GRUB_VIDEO_MODE_TYPE_RGB
+                    | GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)))
+           continue;
+        }
+
+      /* If there is a request for specific depth, ignore others.  */
+      if ((depth != 0) && (vbe_mode_info.bits_per_pixel != depth))
+        continue;
+
+      /* Select mode with most of "volume" (size of framebuffer in bits).  */
+      if (best_vbe_mode != 0)
+        if ((grub_uint64_t) vbe_mode_info.bits_per_pixel
+           * vbe_mode_info.x_resolution * vbe_mode_info.y_resolution
+           < (grub_uint64_t) best_vbe_mode_info.bits_per_pixel
+           * best_vbe_mode_info.x_resolution * best_vbe_mode_info.y_resolution)
+          continue;
+
+      /* Save so far best mode information for later use.  */
+      best_vbe_mode = vbe_mode;
+      grub_memcpy (&best_vbe_mode_info, &vbe_mode_info, sizeof (vbe_mode_info));
+    }
+
+  /* Try to initialize best mode found.  */
+  if (best_vbe_mode != 0)
+    {
+      grub_err_t err;
+      /* If this fails, then we have mode selection heuristics problem,
+         or adapter failure.  */
+      /* grub_vbe_set_video_mode already sets active_vbe_mode_info. */
+      grub_vbe_set_video_mode (best_vbe_mode, NULL);
+      if (grub_errno != GRUB_ERR_NONE)
+        return grub_errno;
+
+      /* Fill mode info details.  */
+      framebuffer.mode_info.width = active_vbe_mode_info.x_resolution;
+      framebuffer.mode_info.height = active_vbe_mode_info.y_resolution;
+
+      if (framebuffer.index_color_mode)
+        framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
+      else
+        framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
+
+      framebuffer.mode_info.bpp = active_vbe_mode_info.bits_per_pixel;
+      framebuffer.mode_info.bytes_per_pixel = framebuffer.bytes_per_pixel;
+      framebuffer.mode_info.pitch = framebuffer.bytes_per_scan_line;
+      framebuffer.mode_info.number_of_colors = 256; /* TODO: fix me.  */
+      framebuffer.mode_info.red_mask_size = active_vbe_mode_info.red_mask_size;
+      framebuffer.mode_info.red_field_pos = active_vbe_mode_info.red_field_position;
+      framebuffer.mode_info.green_mask_size = active_vbe_mode_info.green_mask_size;
+      framebuffer.mode_info.green_field_pos = active_vbe_mode_info.green_field_position;
+      framebuffer.mode_info.blue_mask_size = active_vbe_mode_info.blue_mask_size;
+      framebuffer.mode_info.blue_field_pos = active_vbe_mode_info.blue_field_position;
+      framebuffer.mode_info.reserved_mask_size = active_vbe_mode_info.rsvd_mask_size;
+      framebuffer.mode_info.reserved_field_pos = active_vbe_mode_info.rsvd_field_position;
+
+      framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info);
+
+      /* Set up double buffering and targets.  */
+      err = double_buffering_init (mode_type, mode_mask);
+      if (err)
+       return err;
+
+      err = grub_video_fb_set_active_render_target (framebuffer.back_target);
+
+      if (err)
+       return err;
+
+      /* Copy default palette to initialize emulated palette.  */
+      err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
+                                      grub_video_fbstd_colors);
+      return err;
+    }
+
+  /* Couldn't found matching mode.  */
+  return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found");
+}
+
+static grub_err_t
+grub_video_vbe_set_palette (unsigned int start, unsigned int count,
+                            struct grub_video_palette_data *palette_data)
+{
+  if (framebuffer.index_color_mode)
+    {
+      /* TODO: Implement setting indexed color mode palette to hardware.  */
+      //status = grub_vbe_bios_set_palette_data (sizeof (vga_colors)
+      //                                         / sizeof (struct grub_vbe_palette_data),
+      //                                         0,
+      //                                         palette);
+
+    }
+
+  /* Then set color to emulated palette.  */
+
+  return grub_video_fb_set_palette (start, count, palette_data);
+}
+
+static grub_err_t
+grub_video_vbe_swap_buffers (void)
+{
+  grub_err_t err;
+  if (!framebuffer.update_screen)
+    return GRUB_ERR_NONE;
+
+  err = framebuffer.update_screen (framebuffer.front_target,
+                                  framebuffer.back_target);
+  if (err)
+    return err;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_vbe_set_active_render_target (struct grub_video_render_target *target)
+{
+  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
+      target = framebuffer.back_target;
+
+  return grub_video_fb_set_active_render_target (target);
+}
+
+static grub_err_t
+grub_video_vbe_get_active_render_target (struct grub_video_render_target **target)
+{
+  grub_err_t err;
+  err = grub_video_fb_get_active_render_target (target);
+  if (err)
+    return err;
+
+  if (*target == framebuffer.back_target)
+    *target = GRUB_VIDEO_RENDER_TARGET_DISPLAY;
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info,
+                                 void **framebuf)
+{
+  grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
+  *framebuf = (char *) framebuffer.ptr
+    + framebuffer.displayed_page * framebuffer.page_size;
+
+  grub_free (vbe_mode_list);
+  vbe_mode_list = NULL;
+
+  grub_video_fb_fini ();
+  grub_free (framebuffer.offscreen_buffer);
+
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_video_adapter grub_video_vbe_adapter =
+  {
+    .name = "VESA BIOS Extension Video Driver",
+    .id = GRUB_VIDEO_DRIVER_VBE,
+
+    .init = grub_video_vbe_init,
+    .fini = grub_video_vbe_fini,
+    .setup = grub_video_vbe_setup,
+    .get_info = grub_video_fb_get_info,
+    .get_info_and_fini = grub_video_vbe_get_info_and_fini,
+    .set_palette = grub_video_vbe_set_palette,
+    .get_palette = grub_video_fb_get_palette,
+    .set_viewport = grub_video_fb_set_viewport,
+    .get_viewport = grub_video_fb_get_viewport,
+    .map_color = grub_video_fb_map_color,
+    .map_rgb = grub_video_fb_map_rgb,
+    .map_rgba = grub_video_fb_map_rgba,
+    .unmap_color = grub_video_fb_unmap_color,
+    .fill_rect = grub_video_fb_fill_rect,
+    .blit_bitmap = grub_video_fb_blit_bitmap,
+    .blit_render_target = grub_video_fb_blit_render_target,
+    .scroll = grub_video_fb_scroll,
+    .swap_buffers = grub_video_vbe_swap_buffers,
+    .create_render_target = grub_video_fb_create_render_target,
+    .delete_render_target = grub_video_fb_delete_render_target,
+    .set_active_render_target = grub_video_vbe_set_active_render_target,
+    .get_active_render_target = grub_video_vbe_get_active_render_target,
+
+    .next = 0
+  };
+
+GRUB_MOD_INIT(video_i386_pc_vbe)
+{
+  grub_video_register (&grub_video_vbe_adapter);
+}
+
+GRUB_MOD_FINI(video_i386_pc_vbe)
+{
+  grub_video_unregister (&grub_video_vbe_adapter);
+}
diff --git a/grub-core/video/ieee1275.c b/grub-core/video/ieee1275.c
new file mode 100644 (file)
index 0000000..5c6bc15
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define grub_video_render_target grub_video_fbrender_target
+
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/video.h>
+#include <grub/video_fb.h>
+#include <grub/ieee1275/ieee1275.h>
+
+/* Only 8-bit indexed color is supported for now.  */
+
+static unsigned old_width, old_height;
+static int restore_needed;
+static char *display;
+
+static struct
+{
+  struct grub_video_mode_info mode_info;
+  struct grub_video_render_target *render_target;
+  grub_uint8_t *ptr;
+} framebuffer;
+
+static grub_err_t
+grub_video_ieee1275_set_palette (unsigned int start, unsigned int count,
+                                struct grub_video_palette_data *palette_data);
+
+static void
+set_video_mode (unsigned width __attribute__ ((unused)),
+               unsigned height __attribute__ ((unused)))
+{
+  /* TODO */
+}
+
+static void
+find_display (void)
+{
+  auto int hook (struct grub_ieee1275_devalias *alias);
+  int hook (struct grub_ieee1275_devalias *alias)
+  {
+    if (grub_strcmp (alias->type, "display") == 0)
+      {
+       grub_dprintf ("video", "Found display %s\n", alias->path);
+       display = grub_strdup (alias->path);
+       return 1;
+      }
+    return 0;
+  }
+  
+  grub_ieee1275_devices_iterate (hook);
+}
+
+static grub_err_t
+grub_video_ieee1275_init (void)
+{
+  grub_memset (&framebuffer, 0, sizeof(framebuffer));
+  return grub_video_fb_init ();
+}
+
+static grub_err_t
+grub_video_ieee1275_fini (void)
+{
+  if (restore_needed)
+    {
+      set_video_mode (old_width, old_height);
+      restore_needed = 0;
+    }
+  return grub_video_fb_fini ();
+}
+
+static grub_err_t
+grub_video_ieee1275_fill_mode_info (grub_ieee1275_phandle_t dev,
+                                   struct grub_video_mode_info *out)
+{
+  grub_uint32_t tmp;
+
+  grub_memset (out, 0, sizeof (*out));
+
+  if (grub_ieee1275_get_integer_property (dev, "width", &tmp,
+                                         sizeof (tmp), 0))
+    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display width.");
+  out->width = tmp;
+
+  if (grub_ieee1275_get_integer_property (dev, "height", &tmp,
+                                         sizeof (tmp), 0))
+    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display height.");
+  out->height = tmp;
+
+  if (grub_ieee1275_get_integer_property (dev, "linebytes", &tmp,
+                                         sizeof (tmp), 0))
+    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display pitch.");
+  out->pitch = tmp;
+
+  out->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
+  out->bpp = 8;
+  out->bytes_per_pixel = 1;
+  out->number_of_colors = 256;
+
+  out->blit_format = grub_video_get_blit_format (out);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_ieee1275_setup (unsigned int width, unsigned int height,
+                          unsigned int mode_type __attribute__ ((unused)),
+                          unsigned int mode_mask __attribute__ ((unused)))
+{
+  grub_uint32_t current_width, current_height, address;
+  grub_err_t err;
+  grub_ieee1275_phandle_t dev;
+
+  if (!display)
+    return grub_error (GRUB_ERR_IO, "Couldn't find display device.");
+
+  if (grub_ieee1275_finddevice (display, &dev))
+    return grub_error (GRUB_ERR_IO, "Couldn't open display device.");
+
+  if (grub_ieee1275_get_integer_property (dev, "width", &current_width,
+                                         sizeof (current_width), 0))
+    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display width.");
+
+  if (grub_ieee1275_get_integer_property (dev, "height", &current_height,
+                                         sizeof (current_width), 0))
+    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display height.");
+
+  if ((width == current_width && height == current_height)
+      || (width == 0 && height == 0))
+    {
+      grub_dprintf ("video", "IEEE1275: keeping current mode %dx%d\n",
+                   current_width, current_height);
+    }
+  else
+    {
+      grub_dprintf ("video", "IEEE1275: Setting mode %dx%d\n", width, height);
+      /* TODO. */
+      return grub_error (GRUB_ERR_IO, "can't set mode %dx%d", width, height);
+    }
+  
+  err = grub_video_ieee1275_fill_mode_info (dev, &framebuffer.mode_info);
+  if (err)
+    {
+      grub_dprintf ("video", "IEEE1275: couldn't fill mode info\n");
+      return err;
+    }
+
+  if (grub_ieee1275_get_integer_property (dev, "address", (void *) &address,
+                                         sizeof (address), 0))
+    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display address.");
+
+  /* For some reason sparc64 uses 32-bit pointer too.  */
+  framebuffer.ptr = (void *) (grub_addr_t) address;
+
+  grub_video_ieee1275_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
+                                  grub_video_fbstd_colors);
+
+  grub_dprintf ("video", "IEEE1275: initialising FB @ %p %dx%dx%d\n",
+               framebuffer.ptr, framebuffer.mode_info.width,
+               framebuffer.mode_info.height, framebuffer.mode_info.bpp);
+  
+  err = grub_video_fb_create_render_target_from_pointer 
+    (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr);
+
+  if (err)
+    {
+      grub_dprintf ("video", "IEEE1275: Couldn't create FB target\n");
+      return err;
+    }
+  
+  err = grub_video_fb_set_active_render_target (framebuffer.render_target);
+  
+  if (err)
+    {
+      grub_dprintf ("video", "IEEE1275: Couldn't set FB target\n");
+      return err;
+    }
+  
+  err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
+                                  grub_video_fbstd_colors);
+
+  if (err)
+    grub_dprintf ("video", "IEEE1275: Couldn't set palette\n");
+  else
+    grub_dprintf ("video", "IEEE1275: Success\n");
+  
+  return err;
+}
+
+static grub_err_t
+grub_video_ieee1275_swap_buffers (void)
+{
+  /* TODO: Implement buffer swapping.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_ieee1275_set_active_render_target (struct grub_video_render_target *target)
+{
+  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
+    target = framebuffer.render_target;
+
+  return grub_video_fb_set_active_render_target (target);
+}
+
+static grub_err_t
+grub_video_ieee1275_get_info_and_fini (struct grub_video_mode_info *mode_info,
+                                 void **framebuf)
+{
+  grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
+  *framebuf = (char *) framebuffer.ptr;
+
+  grub_video_fb_fini ();
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_ieee1275_set_palette (unsigned int start, unsigned int count,
+                                struct grub_video_palette_data *palette_data)
+{
+  grub_err_t err;
+  struct grub_video_palette_data fb_palette_data[256];
+
+  err = grub_video_fb_set_palette (start, count, palette_data);
+  if (err)
+    return err;
+
+  grub_video_fb_get_palette (0, 256, fb_palette_data);
+
+  /* TODO. */
+
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_video_adapter grub_video_ieee1275_adapter =
+  {
+    .name = "IEEE1275 video driver",
+
+    .init = grub_video_ieee1275_init,
+    .fini = grub_video_ieee1275_fini,
+    .setup = grub_video_ieee1275_setup,
+    .get_info = grub_video_fb_get_info,
+    .get_info_and_fini = grub_video_ieee1275_get_info_and_fini,
+    .set_palette = grub_video_ieee1275_set_palette,
+    .get_palette = grub_video_fb_get_palette,
+    .set_viewport = grub_video_fb_set_viewport,
+    .get_viewport = grub_video_fb_get_viewport,
+    .map_color = grub_video_fb_map_color,
+    .map_rgb = grub_video_fb_map_rgb,
+    .map_rgba = grub_video_fb_map_rgba,
+    .unmap_color = grub_video_fb_unmap_color,
+    .fill_rect = grub_video_fb_fill_rect,
+    .blit_bitmap = grub_video_fb_blit_bitmap,
+    .blit_render_target = grub_video_fb_blit_render_target,
+    .scroll = grub_video_fb_scroll,
+    .swap_buffers = grub_video_ieee1275_swap_buffers,
+    .create_render_target = grub_video_fb_create_render_target,
+    .delete_render_target = grub_video_fb_delete_render_target,
+    .set_active_render_target = grub_video_ieee1275_set_active_render_target,
+    .get_active_render_target = grub_video_fb_get_active_render_target,
+
+    .next = 0
+  };
+
+GRUB_MOD_INIT(ieee1275_fb)
+{
+  find_display ();
+  if (display)
+    grub_video_register (&grub_video_ieee1275_adapter);
+}
+
+GRUB_MOD_FINI(ieee1275_fb)
+{
+  if (restore_needed)
+    {
+      set_video_mode (old_width, old_height);
+      restore_needed = 0;
+    }
+  if (display)
+    grub_video_unregister (&grub_video_ieee1275_adapter);
+  grub_free (display);
+}
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
new file mode 100644 (file)
index 0000000..5e749b8
--- /dev/null
@@ -0,0 +1,750 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/bitmap.h>
+#include <grub/types.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/bufio.h>
+
+/* Uncomment following define to enable JPEG debug.  */
+//#define JPEG_DEBUG
+
+#define JPEG_ESC_CHAR          0xFF
+
+#define JPEG_SAMPLING_1x1      0x11
+
+#define JPEG_MARKER_SOI                0xd8
+#define JPEG_MARKER_EOI                0xd9
+#define JPEG_MARKER_DHT                0xc4
+#define JPEG_MARKER_DQT                0xdb
+#define JPEG_MARKER_SOF0       0xc0
+#define JPEG_MARKER_SOS                0xda
+
+#define SHIFT_BITS             8
+#define CONST(x)               ((int) ((x) * (1L << SHIFT_BITS) + 0.5))
+
+#define JPEG_UNIT_SIZE         8
+
+static const grub_uint8_t jpeg_zigzag_order[64] = {
+  0, 1, 8, 16, 9, 2, 3, 10,
+  17, 24, 32, 25, 18, 11, 4, 5,
+  12, 19, 26, 33, 40, 48, 41, 34,
+  27, 20, 13, 6, 7, 14, 21, 28,
+  35, 42, 49, 56, 57, 50, 43, 36,
+  29, 22, 15, 23, 30, 37, 44, 51,
+  58, 59, 52, 45, 38, 31, 39, 46,
+  53, 60, 61, 54, 47, 55, 62, 63
+};
+
+#ifdef JPEG_DEBUG
+static grub_command_t cmd;
+#endif
+
+typedef int jpeg_data_unit_t[64];
+
+struct grub_jpeg_data
+{
+  grub_file_t file;
+  struct grub_video_bitmap **bitmap;
+
+  int image_width;
+  int image_height;
+
+  grub_uint8_t *huff_value[4];
+  int huff_offset[4][16];
+  int huff_maxval[4][16];
+
+  grub_uint8_t quan_table[2][64];
+  int comp_index[3][3];
+
+  jpeg_data_unit_t ydu[4];
+  jpeg_data_unit_t crdu;
+  jpeg_data_unit_t cbdu;
+
+  int vs, hs;
+
+  int dc_value[3];
+
+  int bit_mask, bit_save;
+};
+
+static grub_uint8_t
+grub_jpeg_get_byte (struct grub_jpeg_data *data)
+{
+  grub_uint8_t r;
+
+  r = 0;
+  grub_file_read (data->file, &r, 1);
+
+  return r;
+}
+
+static grub_uint16_t
+grub_jpeg_get_word (struct grub_jpeg_data *data)
+{
+  grub_uint16_t r;
+
+  r = 0;
+  grub_file_read (data->file, &r, sizeof (grub_uint16_t));
+
+  return grub_be_to_cpu16 (r);
+}
+
+static int
+grub_jpeg_get_bit (struct grub_jpeg_data *data)
+{
+  int ret;
+
+  if (data->bit_mask == 0)
+    {
+      data->bit_save = grub_jpeg_get_byte (data);
+      if (data->bit_save == JPEG_ESC_CHAR)
+       {
+         if (grub_jpeg_get_byte (data) != 0)
+           {
+             grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                         "jpeg: invalid 0xFF in data stream");
+             return 0;
+           }
+       }
+      data->bit_mask = 0x80;
+    }
+
+  ret = ((data->bit_save & data->bit_mask) != 0);
+  data->bit_mask >>= 1;
+  return ret;
+}
+
+static int
+grub_jpeg_get_number (struct grub_jpeg_data *data, int num)
+{
+  int value, i, msb;
+
+  if (num == 0)
+    return 0;
+
+  msb = value = grub_jpeg_get_bit (data);
+  for (i = 1; i < num; i++)
+    value = (value << 1) + (grub_jpeg_get_bit (data) != 0);
+  if (!msb)
+    value += 1 - (1 << num);
+
+  return value;
+}
+
+static int
+grub_jpeg_get_huff_code (struct grub_jpeg_data *data, int id)
+{
+  int code, i;
+
+  code = 0;
+  for (i = 0; i < 16; i++)
+    {
+      code <<= 1;
+      if (grub_jpeg_get_bit (data))
+       code++;
+      if (code < data->huff_maxval[id][i])
+       return data->huff_value[id][code + data->huff_offset[id][i]];
+    }
+  grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: huffman decode fails");
+  return 0;
+}
+
+static grub_err_t
+grub_jpeg_decode_huff_table (struct grub_jpeg_data *data)
+{
+  int id, ac, i, n, base, ofs;
+  grub_uint32_t next_marker;
+  grub_uint8_t count[16];
+
+  next_marker = data->file->offset;
+  next_marker += grub_jpeg_get_word (data);
+
+  id = grub_jpeg_get_byte (data);
+  ac = (id >> 4);
+  id &= 0xF;
+  if (id > 1)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                      "jpeg: too many huffman tables");
+
+  if (grub_file_read (data->file, &count, sizeof (count)) !=
+      sizeof (count))
+    return grub_errno;
+
+  n = 0;
+  for (i = 0; i < 16; i++)
+    n += count[i];
+
+  id += ac * 2;
+  data->huff_value[id] = grub_malloc (n);
+  if (grub_errno)
+    return grub_errno;
+
+  if (grub_file_read (data->file, data->huff_value[id], n) != n)
+    return grub_errno;
+
+  base = 0;
+  ofs = 0;
+  for (i = 0; i < 16; i++)
+    {
+      base += count[i];
+      ofs += count[i];
+
+      data->huff_maxval[id][i] = base;
+      data->huff_offset[id][i] = ofs - base;
+
+      base <<= 1;
+    }
+
+  if (data->file->offset != next_marker)
+    grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in huffman table");
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_jpeg_decode_quan_table (struct grub_jpeg_data *data)
+{
+  int id;
+  grub_uint32_t next_marker;
+
+  next_marker = data->file->offset;
+  next_marker += grub_jpeg_get_word (data);
+
+  id = grub_jpeg_get_byte (data);
+  if (id >= 0x10)              /* Upper 4-bit is precision.  */
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                      "jpeg: only 8-bit precision is supported");
+
+  if (id > 1)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                      "jpeg: too many quantization tables");
+
+  if (grub_file_read (data->file, &data->quan_table[id], 64) != 64)
+    return grub_errno;
+
+  if (data->file->offset != next_marker)
+    grub_error (GRUB_ERR_BAD_FILE_TYPE,
+               "jpeg: extra byte in quantization table");
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_jpeg_decode_sof (struct grub_jpeg_data *data)
+{
+  int i, cc;
+  grub_uint32_t next_marker;
+
+  next_marker = data->file->offset;
+  next_marker += grub_jpeg_get_word (data);
+
+  if (grub_jpeg_get_byte (data) != 8)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                      "jpeg: only 8-bit precision is supported");
+
+  data->image_height = grub_jpeg_get_word (data);
+  data->image_width = grub_jpeg_get_word (data);
+
+  if ((!data->image_height) || (!data->image_width))
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid image size");
+
+  cc = grub_jpeg_get_byte (data);
+  if (cc != 3)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                      "jpeg: component count must be 3");
+
+  for (i = 0; i < cc; i++)
+    {
+      int id, ss;
+
+      id = grub_jpeg_get_byte (data) - 1;
+      if ((id < 0) || (id >= 3))
+       return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index");
+
+      ss = grub_jpeg_get_byte (data);  /* Sampling factor.  */
+      if (!id)
+       {
+         data->vs = ss & 0xF;  /* Vertical sampling.  */
+         data->hs = ss >> 4;   /* Horizontal sampling.  */
+         if ((data->vs > 2) || (data->hs > 2))
+           return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                              "jpeg: sampling method not supported");
+       }
+      else if (ss != JPEG_SAMPLING_1x1)
+       return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                          "jpeg: sampling method not supported");
+      data->comp_index[id][0] = grub_jpeg_get_byte (data);
+    }
+
+  if (data->file->offset != next_marker)
+    grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sof");
+
+  return grub_errno;
+}
+
+static void
+grub_jpeg_idct_transform (jpeg_data_unit_t du)
+{
+  int *pd;
+  int i;
+  int t0, t1, t2, t3, t4, t5, t6, t7;
+  int v0, v1, v2, v3, v4;
+
+  pd = du;
+  for (i = 0; i < JPEG_UNIT_SIZE; i++, pd++)
+    {
+      if ((pd[JPEG_UNIT_SIZE * 1] | pd[JPEG_UNIT_SIZE * 2] |
+          pd[JPEG_UNIT_SIZE * 3] | pd[JPEG_UNIT_SIZE * 4] |
+          pd[JPEG_UNIT_SIZE * 5] | pd[JPEG_UNIT_SIZE * 6] |
+          pd[JPEG_UNIT_SIZE * 7]) == 0)
+       {
+         pd[JPEG_UNIT_SIZE * 0] <<= SHIFT_BITS;
+
+         pd[JPEG_UNIT_SIZE * 1] = pd[JPEG_UNIT_SIZE * 2]
+           = pd[JPEG_UNIT_SIZE * 3] = pd[JPEG_UNIT_SIZE * 4]
+           = pd[JPEG_UNIT_SIZE * 5] = pd[JPEG_UNIT_SIZE * 6]
+           = pd[JPEG_UNIT_SIZE * 7] = pd[JPEG_UNIT_SIZE * 0];
+
+         continue;
+       }
+
+      t0 = pd[JPEG_UNIT_SIZE * 0];
+      t1 = pd[JPEG_UNIT_SIZE * 2];
+      t2 = pd[JPEG_UNIT_SIZE * 4];
+      t3 = pd[JPEG_UNIT_SIZE * 6];
+
+      v4 = (t1 + t3) * CONST (0.541196100);
+
+      v0 = ((t0 + t2) << SHIFT_BITS);
+      v1 = ((t0 - t2) << SHIFT_BITS);
+      v2 = v4 - t3 * CONST (1.847759065);
+      v3 = v4 + t1 * CONST (0.765366865);
+
+      t0 = v0 + v3;
+      t3 = v0 - v3;
+      t1 = v1 + v2;
+      t2 = v1 - v2;
+
+      t4 = pd[JPEG_UNIT_SIZE * 7];
+      t5 = pd[JPEG_UNIT_SIZE * 5];
+      t6 = pd[JPEG_UNIT_SIZE * 3];
+      t7 = pd[JPEG_UNIT_SIZE * 1];
+
+      v0 = t4 + t7;
+      v1 = t5 + t6;
+      v2 = t4 + t6;
+      v3 = t5 + t7;
+
+      v4 = (v2 + v3) * CONST (1.175875602);
+
+      v0 *= CONST (0.899976223);
+      v1 *= CONST (2.562915447);
+      v2 = v2 * CONST (1.961570560) - v4;
+      v3 = v3 * CONST (0.390180644) - v4;
+
+      t4 = t4 * CONST (0.298631336) - v0 - v2;
+      t5 = t5 * CONST (2.053119869) - v1 - v3;
+      t6 = t6 * CONST (3.072711026) - v1 - v2;
+      t7 = t7 * CONST (1.501321110) - v0 - v3;
+
+      pd[JPEG_UNIT_SIZE * 0] = t0 + t7;
+      pd[JPEG_UNIT_SIZE * 7] = t0 - t7;
+      pd[JPEG_UNIT_SIZE * 1] = t1 + t6;
+      pd[JPEG_UNIT_SIZE * 6] = t1 - t6;
+      pd[JPEG_UNIT_SIZE * 2] = t2 + t5;
+      pd[JPEG_UNIT_SIZE * 5] = t2 - t5;
+      pd[JPEG_UNIT_SIZE * 3] = t3 + t4;
+      pd[JPEG_UNIT_SIZE * 4] = t3 - t4;
+    }
+
+  pd = du;
+  for (i = 0; i < JPEG_UNIT_SIZE; i++, pd += JPEG_UNIT_SIZE)
+    {
+      if ((pd[1] | pd[2] | pd[3] | pd[4] | pd[5] | pd[6] | pd[7]) == 0)
+       {
+         pd[0] >>= (SHIFT_BITS + 3);
+         pd[1] = pd[2] = pd[3] = pd[4] = pd[5] = pd[6] = pd[7] = pd[0];
+         continue;
+       }
+
+      v4 = (pd[2] + pd[6]) * CONST (0.541196100);
+
+      v0 = (pd[0] + pd[4]) << SHIFT_BITS;
+      v1 = (pd[0] - pd[4]) << SHIFT_BITS;
+      v2 = v4 - pd[6] * CONST (1.847759065);
+      v3 = v4 + pd[2] * CONST (0.765366865);
+
+      t0 = v0 + v3;
+      t3 = v0 - v3;
+      t1 = v1 + v2;
+      t2 = v1 - v2;
+
+      t4 = pd[7];
+      t5 = pd[5];
+      t6 = pd[3];
+      t7 = pd[1];
+
+      v0 = t4 + t7;
+      v1 = t5 + t6;
+      v2 = t4 + t6;
+      v3 = t5 + t7;
+
+      v4 = (v2 + v3) * CONST (1.175875602);
+
+      v0 *= CONST (0.899976223);
+      v1 *= CONST (2.562915447);
+      v2 = v2 * CONST (1.961570560) - v4;
+      v3 = v3 * CONST (0.390180644) - v4;
+
+      t4 = t4 * CONST (0.298631336) - v0 - v2;
+      t5 = t5 * CONST (2.053119869) - v1 - v3;
+      t6 = t6 * CONST (3.072711026) - v1 - v2;
+      t7 = t7 * CONST (1.501321110) - v0 - v3;
+
+      pd[0] = (t0 + t7) >> (SHIFT_BITS * 2 + 3);
+      pd[7] = (t0 - t7) >> (SHIFT_BITS * 2 + 3);
+      pd[1] = (t1 + t6) >> (SHIFT_BITS * 2 + 3);
+      pd[6] = (t1 - t6) >> (SHIFT_BITS * 2 + 3);
+      pd[2] = (t2 + t5) >> (SHIFT_BITS * 2 + 3);
+      pd[5] = (t2 - t5) >> (SHIFT_BITS * 2 + 3);
+      pd[3] = (t3 + t4) >> (SHIFT_BITS * 2 + 3);
+      pd[4] = (t3 - t4) >> (SHIFT_BITS * 2 + 3);
+    }
+
+  for (i = 0; i < JPEG_UNIT_SIZE * JPEG_UNIT_SIZE; i++)
+    {
+      du[i] += 128;
+
+      if (du[i] < 0)
+       du[i] = 0;
+      if (du[i] > 255)
+       du[i] = 255;
+    }
+}
+
+static void
+grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
+{
+  int pos, h1, h2, qt;
+
+  grub_memset (du, 0, sizeof (jpeg_data_unit_t));
+
+  qt = data->comp_index[id][0];
+  h1 = data->comp_index[id][1];
+  h2 = data->comp_index[id][2];
+
+  data->dc_value[id] +=
+    grub_jpeg_get_number (data, grub_jpeg_get_huff_code (data, h1));
+
+  du[0] = data->dc_value[id] * (int) data->quan_table[qt][0];
+  pos = 1;
+  while (pos < 64)
+    {
+      int num, val;
+
+      num = grub_jpeg_get_huff_code (data, h2);
+      if (!num)
+       break;
+
+      val = grub_jpeg_get_number (data, num & 0xF);
+      num >>= 4;
+      pos += num;
+      du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos];
+      pos++;
+    }
+
+  grub_jpeg_idct_transform (du);
+}
+
+static void
+grub_jpeg_ycrcb_to_rgb (int yy, int cr, int cb, grub_uint8_t * rgb)
+{
+  int dd;
+
+  cr -= 128;
+  cb -= 128;
+
+  /* Red  */
+  dd = yy + ((cr * CONST (1.402)) >> SHIFT_BITS);
+  if (dd < 0)
+    dd = 0;
+  if (dd > 255)
+    dd = 255;
+  *(rgb++) = dd;
+
+  /* Green  */
+  dd = yy - ((cb * CONST (0.34414) + cr * CONST (0.71414)) >> SHIFT_BITS);
+  if (dd < 0)
+    dd = 0;
+  if (dd > 255)
+    dd = 255;
+  *(rgb++) = dd;
+
+  /* Blue  */
+  dd = yy + ((cb * CONST (1.772)) >> SHIFT_BITS);
+  if (dd < 0)
+    dd = 0;
+  if (dd > 255)
+    dd = 255;
+  *(rgb++) = dd;
+}
+
+static grub_err_t
+grub_jpeg_decode_sos (struct grub_jpeg_data *data)
+{
+  int i, cc, r1, c1, nr1, nc1, vb, hb;
+  grub_uint8_t *ptr1;
+  grub_uint32_t data_offset;
+
+  data_offset = data->file->offset;
+  data_offset += grub_jpeg_get_word (data);
+
+  cc = grub_jpeg_get_byte (data);
+
+  if (cc != 3)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                      "jpeg: component count must be 3");
+
+  for (i = 0; i < cc; i++)
+    {
+      int id, ht;
+
+      id = grub_jpeg_get_byte (data) - 1;
+      if ((id < 0) || (id >= 3))
+       return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index");
+
+      ht = grub_jpeg_get_byte (data);
+      data->comp_index[id][1] = (ht >> 4);
+      data->comp_index[id][2] = (ht & 0xF) + 2;
+    }
+
+  grub_jpeg_get_byte (data);   /* Skip 3 unused bytes.  */
+  grub_jpeg_get_word (data);
+
+  if (data->file->offset != data_offset)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos");
+
+  if (grub_video_bitmap_create (data->bitmap, data->image_width,
+                               data->image_height,
+                               GRUB_VIDEO_BLIT_FORMAT_RGB_888))
+    return grub_errno;
+
+  data->bit_mask = 0x0;
+
+  vb = data->vs * 8;
+  hb = data->hs * 8;
+  nr1 = (data->image_height + vb - 1) / vb;
+  nc1 = (data->image_width + hb - 1) / hb;
+
+  ptr1 = (*data->bitmap)->data;
+  for (r1 = 0; r1 < nr1;
+       r1++, ptr1 += (vb * data->image_width - hb * nc1) * 3)
+    for (c1 = 0; c1 < nc1; c1++, ptr1 += hb * 3)
+      {
+       int r2, c2, nr2, nc2;
+       grub_uint8_t *ptr2;
+
+       for (r2 = 0; r2 < data->vs; r2++)
+         for (c2 = 0; c2 < data->hs; c2++)
+           grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]);
+
+       grub_jpeg_decode_du (data, 1, data->cbdu);
+       grub_jpeg_decode_du (data, 2, data->crdu);
+
+       if (grub_errno)
+         return grub_errno;
+
+       nr2 = (r1 == nr1 - 1) ? (data->image_height - r1 * vb) : vb;
+       nc2 = (c1 == nc1 - 1) ? (data->image_width - c1 * hb) : hb;
+
+       ptr2 = ptr1;
+       for (r2 = 0; r2 < nr2; r2++, ptr2 += (data->image_width - nc2) * 3)
+         for (c2 = 0; c2 < nc2; c2++, ptr2 += 3)
+           {
+             int i0, yy, cr, cb;
+
+             i0 = (r2 / data->vs) * 8 + (c2 / data->hs);
+             cr = data->crdu[i0];
+             cb = data->cbdu[i0];
+             yy =
+               data->ydu[(r2 / 8) * 2 + (c2 / 8)][(r2 % 8) * 8 + (c2 % 8)];
+
+             grub_jpeg_ycrcb_to_rgb (yy, cr, cb, ptr2);
+           }
+      }
+
+  return grub_errno;
+}
+
+static grub_uint8_t
+grub_jpeg_get_marker (struct grub_jpeg_data *data)
+{
+  grub_uint8_t r;
+
+  r = grub_jpeg_get_byte (data);
+
+  if (r != JPEG_ESC_CHAR)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid maker");
+      return 0;
+    }
+
+  return grub_jpeg_get_byte (data);
+}
+
+static grub_err_t
+grub_jpeg_decode_jpeg (struct grub_jpeg_data *data)
+{
+  if (grub_jpeg_get_marker (data) != JPEG_MARKER_SOI)  /* Start Of Image.  */
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid jpeg file");
+
+  while (grub_errno == 0)
+    {
+      grub_uint8_t marker;
+
+      marker = grub_jpeg_get_marker (data);
+      if (grub_errno)
+       break;
+
+#ifdef JPEG_DEBUG
+      grub_printf ("jpeg marker: %x\n", marker);
+#endif
+
+      switch (marker)
+       {
+       case JPEG_MARKER_DHT:   /* Define Huffman Table.  */
+         grub_jpeg_decode_huff_table (data);
+         break;
+       case JPEG_MARKER_DQT:   /* Define Quantization Table.  */
+         grub_jpeg_decode_quan_table (data);
+         break;
+       case JPEG_MARKER_SOF0:  /* Start Of Frame 0.  */
+         grub_jpeg_decode_sof (data);
+         break;
+       case JPEG_MARKER_SOS:   /* Start Of Scan.  */
+         grub_jpeg_decode_sos (data);
+         break;
+       case JPEG_MARKER_EOI:   /* End Of Image.  */
+         return grub_errno;
+       default:                /* Skip unrecognized marker.  */
+         {
+           grub_uint16_t sz;
+
+           sz = grub_jpeg_get_word (data);
+           if (grub_errno)
+             return (grub_errno);
+           grub_file_seek (data->file, data->file->offset + sz - 2);
+         }
+       }
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_video_reader_jpeg (struct grub_video_bitmap **bitmap,
+                       const char *filename)
+{
+  grub_file_t file;
+  struct grub_jpeg_data *data;
+
+  file = grub_buffile_open (filename, 0);
+  if (!file)
+    return grub_errno;
+
+  data = grub_zalloc (sizeof (*data));
+  if (data != NULL)
+    {
+      int i;
+
+      data->file = file;
+      data->bitmap = bitmap;
+      grub_jpeg_decode_jpeg (data);
+
+      for (i = 0; i < 4; i++)
+       if (data->huff_value[i])
+         grub_free (data->huff_value[i]);
+
+      grub_free (data);
+    }
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_video_bitmap_destroy (*bitmap);
+      *bitmap = 0;
+    }
+
+  grub_file_close (file);
+  return grub_errno;
+}
+
+#if defined(JPEG_DEBUG)
+static grub_err_t
+grub_cmd_jpegtest (grub_command_t cmd __attribute__ ((unused)),
+                   int argc, char **args)
+{
+  struct grub_video_bitmap *bitmap = 0;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  grub_video_reader_jpeg (&bitmap, args[0]);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  grub_video_bitmap_destroy (bitmap);
+
+  return GRUB_ERR_NONE;
+}
+#endif
+
+static struct grub_video_bitmap_reader jpg_reader = {
+  .extension = ".jpg",
+  .reader = grub_video_reader_jpeg,
+  .next = 0
+};
+
+static struct grub_video_bitmap_reader jpeg_reader = {
+  .extension = ".jpeg",
+  .reader = grub_video_reader_jpeg,
+  .next = 0
+};
+
+GRUB_MOD_INIT (jpeg)
+{
+  grub_video_bitmap_reader_register (&jpg_reader);
+  grub_video_bitmap_reader_register (&jpeg_reader);
+#if defined(JPEG_DEBUG)
+  cmd = grub_register_command ("jpegtest", grub_cmd_jpegtest,
+                              "FILE",
+                              "Tests loading of JPEG bitmap.");
+#endif
+}
+
+GRUB_MOD_FINI (jpeg)
+{
+#if defined(JPEG_DEBUG)
+  grub_unregister_command (cmd);
+#endif
+  grub_video_bitmap_reader_unregister (&jpeg_reader);
+  grub_video_bitmap_reader_unregister (&jpg_reader);
+}
diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
new file mode 100644 (file)
index 0000000..2cec49e
--- /dev/null
@@ -0,0 +1,913 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/bitmap.h>
+#include <grub/types.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/bufio.h>
+
+/* Uncomment following define to enable PNG debug.  */
+//#define PNG_DEBUG
+
+#define PNG_COLOR_MASK_PALETTE 1
+#define PNG_COLOR_MASK_COLOR   2
+#define PNG_COLOR_MASK_ALPHA   4
+
+#define PNG_COLOR_TYPE_GRAY    0
+#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
+#define PNG_COLOR_TYPE_RGB     (PNG_COLOR_MASK_COLOR)
+#define PNG_COLOR_TYPE_RGBA    (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
+#define PNG_COLOR_TYPE_GRAYA   (PNG_COLOR_MASK_ALPHA)
+
+#define PNG_COMPRESSION_BASE   0
+
+#define PNG_INTERLACE_NONE     0
+#define PNG_INTERLACE_ADAM7    1
+
+#define PNG_FILTER_TYPE_BASE   0
+
+#define PNG_FILTER_VALUE_NONE  0
+#define PNG_FILTER_VALUE_SUB   1
+#define PNG_FILTER_VALUE_UP    2
+#define PNG_FILTER_VALUE_AVG   3
+#define PNG_FILTER_VALUE_PAETH 4
+#define PNG_FILTER_VALUE_LAST  5
+
+#define PNG_CHUNK_IHDR         0x49484452
+#define PNG_CHUNK_IDAT         0x49444154
+#define PNG_CHUNK_IEND         0x49454e44
+
+#define Z_DEFLATED             8
+#define Z_FLAG_DICT            32
+
+#define INFLATE_STORED         0
+#define INFLATE_FIXED          1
+#define INFLATE_DYNAMIC                2
+
+#define WSIZE                  0x8000
+
+#define DEFLATE_HCLEN_BASE     4
+#define DEFLATE_HCLEN_MAX      19
+#define DEFLATE_HLIT_BASE      257
+#define DEFLATE_HLIT_MAX       288
+#define DEFLATE_HDIST_BASE     1
+#define DEFLATE_HDIST_MAX      30
+
+#define DEFLATE_HUFF_LEN       16
+
+#ifdef PNG_DEBUG
+static grub_command_t cmd;
+#endif
+
+struct huff_table
+{
+  int *values, *maxval, *offset;
+  int num_values, max_length;
+};
+
+struct grub_png_data
+{
+  grub_file_t file;
+  struct grub_video_bitmap **bitmap;
+
+  int bit_count, bit_save;
+
+  grub_uint32_t next_offset;
+
+  int image_width, image_height, bpp, is_16bit, raw_bytes;
+  grub_uint8_t *image_data;
+
+  int inside_idat, idat_remain;
+
+  int code_values[DEFLATE_HLIT_MAX];
+  int code_maxval[DEFLATE_HUFF_LEN];
+  int code_offset[DEFLATE_HUFF_LEN];
+
+  int dist_values[DEFLATE_HDIST_MAX];
+  int dist_maxval[DEFLATE_HUFF_LEN];
+  int dist_offset[DEFLATE_HUFF_LEN];
+
+  struct huff_table code_table;
+  struct huff_table dist_table;
+
+  grub_uint8_t slide[WSIZE];
+  int wp;
+
+  grub_uint8_t *cur_rgb;
+
+  int cur_column, cur_filter, first_line;
+};
+
+static grub_uint32_t
+grub_png_get_dword (struct grub_png_data *data)
+{
+  grub_uint32_t r;
+
+  r = 0;
+  grub_file_read (data->file, &r, sizeof (grub_uint32_t));
+
+  return grub_be_to_cpu32 (r);
+}
+
+static grub_uint8_t
+grub_png_get_byte (struct grub_png_data *data)
+{
+  grub_uint8_t r;
+
+  if ((data->inside_idat) && (data->idat_remain == 0))
+    {
+      grub_uint32_t len, type;
+
+      do
+       {
+          /* Skip crc checksum.  */
+         grub_png_get_dword (data);
+
+          if (data->file->offset != data->next_offset)
+            {
+              grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                          "png: chunk size error");
+              return 0;
+            }
+
+         len = grub_png_get_dword (data);
+         type = grub_png_get_dword (data);
+         if (type != PNG_CHUNK_IDAT)
+           {
+             grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                         "png: unexpected end of data");
+             return 0;
+           }
+
+          data->next_offset = data->file->offset + len + 4;
+       }
+      while (len == 0);
+      data->idat_remain = len;
+    }
+
+  r = 0;
+  grub_file_read (data->file, &r, 1);
+
+  if (data->inside_idat)
+    data->idat_remain--;
+
+  return r;
+}
+
+static int
+grub_png_get_bits (struct grub_png_data *data, int num)
+{
+  int code, shift;
+
+  if (data->bit_count == 0)
+    {
+      data->bit_save = grub_png_get_byte (data);
+      data->bit_count = 8;
+    }
+
+  code = 0;
+  shift = 0;
+  while (grub_errno == 0)
+    {
+      int n;
+
+      n = data->bit_count;
+      if (n > num)
+       n = num;
+
+      code += (int) (data->bit_save & ((1 << n) - 1)) << shift;
+      num -= n;
+      if (!num)
+       {
+         data->bit_count -= n;
+         data->bit_save >>= n;
+         break;
+       }
+
+      shift += n;
+
+      data->bit_save = grub_png_get_byte (data);
+      data->bit_count = 8;
+    }
+
+  return code;
+}
+
+static grub_err_t
+grub_png_decode_image_header (struct grub_png_data *data)
+{
+  int color_type;
+  int color_bits;
+
+  data->image_width = grub_png_get_dword (data);
+  data->image_height = grub_png_get_dword (data);
+
+  if ((!data->image_height) || (!data->image_width))
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid image size");
+
+  color_bits = grub_png_get_byte (data);
+  if ((color_bits != 8) && (color_bits != 16))
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                       "png: bit depth must be 8 or 16");
+  data->is_16bit = (color_bits == 16);
+
+  color_type = grub_png_get_byte (data);
+  if (color_type == PNG_COLOR_TYPE_RGB)
+    {
+      if (grub_video_bitmap_create (data->bitmap, data->image_width,
+                                   data->image_height,
+                                   GRUB_VIDEO_BLIT_FORMAT_RGB_888))
+       return grub_errno;
+      data->bpp = 3;
+    }
+  else if (color_type == PNG_COLOR_TYPE_RGBA)
+    {
+      if (grub_video_bitmap_create (data->bitmap, data->image_width,
+                                   data->image_height,
+                                   GRUB_VIDEO_BLIT_FORMAT_RGBA_8888))
+       return grub_errno;
+      data->bpp = 4;
+    }
+  else
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                      "png: color type not supported");
+
+  if (data->is_16bit)
+    {
+      data->bpp <<= 1;
+
+      data->image_data = grub_malloc (data->image_height *
+                                      data->image_width *  data->bpp);
+      if (grub_errno)
+        return grub_errno;
+
+      data->cur_rgb = data->image_data;
+    }
+  else
+    {
+      data->image_data = 0;
+      data->cur_rgb = (*data->bitmap)->data;
+    }
+
+  data->raw_bytes = data->image_height * (data->image_width + 1) * data->bpp;
+
+  data->cur_column = 0;
+  data->first_line = 1;
+
+  if (grub_png_get_byte (data) != PNG_COMPRESSION_BASE)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                      "png: compression method not supported");
+
+  if (grub_png_get_byte (data) != PNG_FILTER_TYPE_BASE)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                      "png: filter method not supported");
+
+  if (grub_png_get_byte (data) != PNG_INTERLACE_NONE)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                      "png: interlace method not supported");
+
+  /* Skip crc checksum.  */
+  grub_png_get_dword (data);
+
+  return grub_errno;
+}
+
+/* Order of the bit length code lengths.  */
+static const grub_uint8_t bitorder[] = {
+  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
+};
+
+/* Copy lengths for literal codes 257..285.  */
+static const int cplens[] = {
+  3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
+};
+
+/* Extra bits for literal codes 257..285.  */
+static const grub_uint8_t cplext[] = {
+  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+  3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99
+};                             /* 99==invalid  */
+
+/* Copy offsets for distance codes 0..29.  */
+static const int cpdist[] = {
+  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+  257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+  8193, 12289, 16385, 24577
+};
+
+/* Extra bits for distance codes.  */
+static const grub_uint8_t cpdext[] = {
+  0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+  7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+  12, 12, 13, 13
+};
+
+static void
+grub_png_init_huff_table (struct huff_table *ht, int cur_maxlen,
+                         int *cur_values, int *cur_maxval, int *cur_offset)
+{
+  ht->values = cur_values;
+  ht->maxval = cur_maxval;
+  ht->offset = cur_offset;
+  ht->num_values = 0;
+  ht->max_length = cur_maxlen;
+  grub_memset (cur_maxval, 0, sizeof (int) * cur_maxlen);
+}
+
+static void
+grub_png_insert_huff_item (struct huff_table *ht, int code, int len)
+{
+  int i, n;
+
+  if (len == 0)
+    return;
+
+  if (len > ht->max_length)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid code length");
+      return;
+    }
+
+  n = 0;
+  for (i = len; i < ht->max_length; i++)
+    n += ht->maxval[i];
+
+  for (i = 0; i < n; i++)
+    ht->values[ht->num_values - i] = ht->values[ht->num_values - i - 1];
+
+  ht->values[ht->num_values - n] = code;
+  ht->num_values++;
+  ht->maxval[len - 1]++;
+}
+
+static void
+grub_png_build_huff_table (struct huff_table *ht)
+{
+  int base, ofs, i;
+
+  base = 0;
+  ofs = 0;
+  for (i = 0; i < ht->max_length; i++)
+    {
+      base += ht->maxval[i];
+      ofs += ht->maxval[i];
+
+      ht->maxval[i] = base;
+      ht->offset[i] = ofs - base;
+
+      base <<= 1;
+    }
+}
+
+static int
+grub_png_get_huff_code (struct grub_png_data *data, struct huff_table *ht)
+{
+  int code, i;
+
+  code = 0;
+  for (i = 0; i < ht->max_length; i++)
+    {
+      code = (code << 1) + grub_png_get_bits (data, 1);
+      if (code < ht->maxval[i])
+       return ht->values[code + ht->offset[i]];
+    }
+  return 0;
+}
+
+static grub_err_t
+grub_png_init_fixed_block (struct grub_png_data *data)
+{
+  int i;
+
+  grub_png_init_huff_table (&data->code_table, DEFLATE_HUFF_LEN,
+                           data->code_values, data->code_maxval,
+                           data->code_offset);
+
+  for (i = 0; i < 144; i++)
+    grub_png_insert_huff_item (&data->code_table, i, 8);
+
+  for (; i < 256; i++)
+    grub_png_insert_huff_item (&data->code_table, i, 9);
+
+  for (; i < 280; i++)
+    grub_png_insert_huff_item (&data->code_table, i, 7);
+
+  for (; i < DEFLATE_HLIT_MAX; i++)
+    grub_png_insert_huff_item (&data->code_table, i, 8);
+
+  grub_png_build_huff_table (&data->code_table);
+
+  grub_png_init_huff_table (&data->dist_table, DEFLATE_HUFF_LEN,
+                           data->dist_values, data->dist_maxval,
+                           data->dist_offset);
+
+  for (i = 0; i < DEFLATE_HDIST_MAX; i++)
+    grub_png_insert_huff_item (&data->dist_table, i, 5);
+
+  grub_png_build_huff_table (&data->dist_table);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_png_init_dynamic_block (struct grub_png_data *data)
+{
+  int nl, nd, nb, i, prev;
+  struct huff_table cl;
+  int cl_values[sizeof (bitorder)];
+  int cl_maxval[8];
+  int cl_offset[8];
+  grub_uint8_t lens[DEFLATE_HCLEN_MAX];
+
+  nl = DEFLATE_HLIT_BASE + grub_png_get_bits (data, 5);
+  nd = DEFLATE_HDIST_BASE + grub_png_get_bits (data, 5);
+  nb = DEFLATE_HCLEN_BASE + grub_png_get_bits (data, 4);
+
+  if ((nl > DEFLATE_HLIT_MAX) || (nd > DEFLATE_HDIST_MAX) ||
+      (nb > DEFLATE_HCLEN_MAX))
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: too much data");
+
+  grub_png_init_huff_table (&cl, 8, cl_values, cl_maxval, cl_offset);
+
+  for (i = 0; i < nb; i++)
+    lens[bitorder[i]] = grub_png_get_bits (data, 3);
+
+  for (; i < DEFLATE_HCLEN_MAX; i++)
+    lens[bitorder[i]] = 0;
+
+  for (i = 0; i < DEFLATE_HCLEN_MAX; i++)
+    grub_png_insert_huff_item (&cl, i, lens[i]);
+
+  grub_png_build_huff_table (&cl);
+
+  grub_png_init_huff_table (&data->code_table, DEFLATE_HUFF_LEN,
+                           data->code_values, data->code_maxval,
+                           data->code_offset);
+
+  grub_png_init_huff_table (&data->dist_table, DEFLATE_HUFF_LEN,
+                           data->dist_values, data->dist_maxval,
+                           data->dist_offset);
+
+  prev = 0;
+  for (i = 0; i < nl + nd; i++)
+    {
+      int n, code;
+      struct huff_table *ht;
+
+      if (grub_errno)
+       return grub_errno;
+
+      if (i < nl)
+       {
+         ht = &data->code_table;
+         code = i;
+       }
+      else
+       {
+         ht = &data->dist_table;
+         code = i - nl;
+       }
+
+      n = grub_png_get_huff_code (data, &cl);
+      if (n < 16)
+       {
+         grub_png_insert_huff_item (ht, code, n);
+         prev = n;
+       }
+      else if (n == 16)
+       {
+         int c;
+
+         c = 3 + grub_png_get_bits (data, 2);
+         while (c > 0)
+           {
+             grub_png_insert_huff_item (ht, code++, prev);
+             i++;
+             c--;
+           }
+         i--;
+       }
+      else if (n == 17)
+       i += 3 + grub_png_get_bits (data, 3) - 1;
+      else
+       i += 11 + grub_png_get_bits (data, 7) - 1;
+    }
+
+  grub_png_build_huff_table (&data->code_table);
+  grub_png_build_huff_table (&data->dist_table);
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_png_output_byte (struct grub_png_data *data, grub_uint8_t n)
+{
+  int row_bytes;
+
+  if (--data->raw_bytes < 0)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "image size overflown");
+
+  if (data->cur_column == 0)
+    {
+      if (n >= PNG_FILTER_VALUE_LAST)
+       return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid filter value");
+
+      data->cur_filter = n;
+    }
+  else
+    *(data->cur_rgb++) = n;
+
+  data->cur_column++;
+  row_bytes = data->image_width * data->bpp;
+  if (data->cur_column == row_bytes + 1)
+    {
+      grub_uint8_t *blank_line = NULL;
+      grub_uint8_t *cur = data->cur_rgb - row_bytes;
+      grub_uint8_t *left = cur;
+      grub_uint8_t *up;
+
+      if (data->first_line)
+       {
+         blank_line = grub_zalloc (row_bytes);
+         if (blank_line == NULL)
+           return grub_errno;
+
+         up = blank_line;
+       }
+      else
+       up = cur - row_bytes;
+
+      switch (data->cur_filter)
+       {
+       case PNG_FILTER_VALUE_SUB:
+         {
+           int i;
+
+           cur += data->bpp;
+           for (i = data->bpp; i < row_bytes; i++, cur++, left++)
+             *cur += *left;
+
+           break;
+         }
+       case PNG_FILTER_VALUE_UP:
+         {
+           int i;
+
+           for (i = 0; i < row_bytes; i++, cur++, up++)
+             *cur += *up;
+
+           break;
+         }
+       case PNG_FILTER_VALUE_AVG:
+         {
+           int i;
+
+           for (i = 0; i < data->bpp; i++, cur++, up++)
+             *cur += *up >> 1;
+
+           for (; i < row_bytes; i++, cur++, up++, left++)
+             *cur += ((int) *up + (int) *left) >> 1;
+
+           break;
+         }
+       case PNG_FILTER_VALUE_PAETH:
+         {
+           int i;
+           grub_uint8_t *upper_left = up;
+
+           for (i = 0; i < data->bpp; i++, cur++, up++)
+             *cur += *up;
+
+           for (; i < row_bytes; i++, cur++, up++, left++, upper_left++)
+             {
+               int a, b, c, pa, pb, pc;
+
+                a = *left;
+                b = *up;
+                c = *upper_left;
+
+                pa = b - c;
+                pb = a - c;
+                pc = pa + pb;
+
+                if (pa < 0)
+                  pa = -pa;
+
+                if (pb < 0)
+                  pb = -pb;
+
+                if (pc < 0)
+                  pc = -pc;
+
+                *cur += ((pa <= pb) && (pa <= pc)) ? a : (pb <= pc) ? b : c;
+             }
+         }
+       }
+
+      if (blank_line)
+       grub_free (blank_line);
+
+      data->cur_column = 0;
+      data->first_line = 0;
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_png_read_dynamic_block (struct grub_png_data *data)
+{
+  while (grub_errno == 0)
+    {
+      int n;
+
+      n = grub_png_get_huff_code (data, &data->code_table);
+      if (n < 256)
+       {
+         data->slide[data->wp] = n;
+         grub_png_output_byte (data, n);
+
+         data->wp++;
+         if (data->wp >= WSIZE)
+           data->wp = 0;
+       }
+      else if (n == 256)
+       break;
+      else
+       {
+         int len, dist, pos;
+
+         n -= 257;
+         len = cplens[n];
+         if (cplext[n])
+           len += grub_png_get_bits (data, cplext[n]);
+
+         n = grub_png_get_huff_code (data, &data->dist_table);
+         dist = cpdist[n];
+         if (cpdext[n])
+           dist += grub_png_get_bits (data, cpdext[n]);
+
+         pos = data->wp - dist;
+         if (pos < 0)
+           pos += WSIZE;
+
+         while (len > 0)
+           {
+             data->slide[data->wp] = data->slide[pos];
+             grub_png_output_byte (data, data->slide[data->wp]);
+
+             data->wp++;
+             if (data->wp >= WSIZE)
+               data->wp = 0;
+
+             pos++;
+             if (pos >= WSIZE)
+               pos = 0;
+
+             len--;
+           }
+       }
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_png_decode_image_data (struct grub_png_data *data)
+{
+  grub_uint8_t cmf, flg;
+  int final;
+
+  cmf = grub_png_get_byte (data);
+  flg = grub_png_get_byte (data);
+
+  if ((cmf & 0xF) != Z_DEFLATED)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                      "png: only support deflate compression method");
+
+  if (flg & Z_FLAG_DICT)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                      "png: dictionary not supported");
+
+  do
+    {
+      int block_type;
+
+      final = grub_png_get_bits (data, 1);
+      block_type = grub_png_get_bits (data, 2);
+
+      switch (block_type)
+       {
+       case INFLATE_STORED:
+         {
+           grub_uint16_t i, len;
+
+           data->bit_count = 0;
+           len = grub_png_get_byte (data);
+           len += ((grub_uint16_t) grub_png_get_byte (data)) << 8;
+
+            /* Skip NLEN field.  */
+           grub_png_get_byte (data);
+           grub_png_get_byte (data);
+
+           for (i = 0; i < len; i++)
+             grub_png_output_byte (data, grub_png_get_byte (data));
+
+           break;
+         }
+
+       case INFLATE_FIXED:
+          grub_png_init_fixed_block (data);
+         grub_png_read_dynamic_block (data);
+         break;
+
+       case INFLATE_DYNAMIC:
+         grub_png_init_dynamic_block (data);
+         grub_png_read_dynamic_block (data);
+         break;
+
+       default:
+         return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                            "png: unknown block type");
+       }
+    }
+  while ((!final) && (grub_errno == 0));
+
+  /* Skip adler checksum.  */
+  grub_png_get_dword (data);
+
+  /* Skip crc checksum.  */
+  grub_png_get_dword (data);
+
+  return grub_errno;
+}
+
+static const grub_uint8_t png_magic[8] =
+  { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0x0a };
+
+static void
+grub_png_convert_image (struct grub_png_data *data)
+{
+  int i;
+  grub_uint8_t *d1, *d2;
+
+  d1 = (*data->bitmap)->data;
+  d2 = data->image_data + 1;
+
+  /* Only copy the upper 8 bit.  */
+  for (i = 0; i < (data->image_width * data->image_height * data->bpp >> 1);
+       i++, d1++, d2+=2)
+    *d1 = *d2;
+}
+
+static grub_err_t
+grub_png_decode_png (struct grub_png_data *data)
+{
+  grub_uint8_t magic[8];
+
+  if (grub_file_read (data->file, &magic[0], 8) != 8)
+    return grub_errno;
+
+  if (grub_memcmp (magic, png_magic, sizeof (png_magic)))
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: not a png file");
+
+  while (1)
+    {
+      grub_uint32_t len, type;
+
+      len = grub_png_get_dword (data);
+      type = grub_png_get_dword (data);
+      data->next_offset = data->file->offset + len + 4;
+
+      switch (type)
+       {
+       case PNG_CHUNK_IHDR:
+         grub_png_decode_image_header (data);
+         break;
+
+       case PNG_CHUNK_IDAT:
+         data->inside_idat = 1;
+         data->idat_remain = len;
+         data->bit_count = 0;
+
+         grub_png_decode_image_data (data);
+
+         data->inside_idat = 0;
+         break;
+
+       case PNG_CHUNK_IEND:
+          if (data->is_16bit)
+            grub_png_convert_image (data);
+
+         return grub_errno;
+
+       default:
+         grub_file_seek (data->file, data->file->offset + len + 4);
+       }
+
+      if (grub_errno)
+        break;
+
+      if (data->file->offset != data->next_offset)
+        return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                           "png: chunk size error");
+    }
+
+  return grub_errno;
+}
+
+static grub_err_t
+grub_video_reader_png (struct grub_video_bitmap **bitmap,
+                      const char *filename)
+{
+  grub_file_t file;
+  struct grub_png_data *data;
+
+  file = grub_buffile_open (filename, 0);
+  if (!file)
+    return grub_errno;
+
+  data = grub_zalloc (sizeof (*data));
+  if (data != NULL)
+    {
+      data->file = file;
+      data->bitmap = bitmap;
+
+      grub_png_decode_png (data);
+
+      grub_free (data->image_data);
+      grub_free (data);
+    }
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_video_bitmap_destroy (*bitmap);
+      *bitmap = 0;
+    }
+
+  grub_file_close (file);
+  return grub_errno;
+}
+
+#if defined(PNG_DEBUG)
+static grub_err_t
+grub_cmd_pngtest (grub_command_t cmd __attribute__ ((unused)),
+                 int argc, char **args)
+{
+  struct grub_video_bitmap *bitmap = 0;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  grub_video_reader_png (&bitmap, args[0]);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  grub_video_bitmap_destroy (bitmap);
+
+  return GRUB_ERR_NONE;
+}
+#endif
+
+static struct grub_video_bitmap_reader png_reader = {
+  .extension = ".png",
+  .reader = grub_video_reader_png,
+  .next = 0
+};
+
+GRUB_MOD_INIT (png)
+{
+  grub_video_bitmap_reader_register (&png_reader);
+#if defined(PNG_DEBUG)
+  cmd = grub_register_command ("pngtest", grub_cmd_pngtest,
+                              "FILE",
+                              "Tests loading of PNG bitmap.");
+#endif
+}
+
+GRUB_MOD_FINI (png)
+{
+#if defined(PNG_DEBUG)
+  grub_unregister_command (cmd);
+#endif
+  grub_video_bitmap_reader_unregister (&png_reader);
+}
diff --git a/grub-core/video/readers/tga.c b/grub-core/video/readers/tga.c
new file mode 100644 (file)
index 0000000..6c9e9d6
--- /dev/null
@@ -0,0 +1,495 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/bitmap.h>
+#include <grub/types.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/bufio.h>
+
+/* Uncomment following define to enable TGA debug.  */
+//#define TGA_DEBUG
+
+#if defined(TGA_DEBUG)
+#define dump_int_field(x) grub_printf( #x " = %d (0x%04x)\n", x, x);
+static grub_command_t cmd;
+#endif
+
+enum
+{
+  GRUB_TGA_IMAGE_TYPE_NONE = 0,
+  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_INDEXCOLOR = 1,
+  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR = 2,
+  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_BLACK_AND_WHITE = 3,
+  GRUB_TGA_IMAGE_TYPE_RLE_INDEXCOLOR = 9,
+  GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR = 10,
+  GRUB_TGA_IMAGE_TYPE_RLE_BLACK_AND_WHITE = 11,
+};
+
+enum
+{
+  GRUB_TGA_COLOR_MAP_TYPE_NONE = 0,
+  GRUB_TGA_COLOR_MAP_TYPE_INCLUDED = 1
+};
+
+enum
+{
+  GRUB_TGA_IMAGE_ORIGIN_RIGHT = 0x10,
+  GRUB_TGA_IMAGE_ORIGIN_TOP   = 0x20
+};
+
+struct grub_tga_header
+{
+  grub_uint8_t id_length;
+  grub_uint8_t color_map_type;
+  grub_uint8_t image_type;
+
+  /* Color Map Specification.  */
+  grub_uint16_t color_map_first_index;
+  grub_uint16_t color_map_length;
+  grub_uint8_t color_map_bpp;
+
+  /* Image Specification.  */
+  grub_uint16_t image_x_origin;
+  grub_uint16_t image_y_origin;
+  grub_uint16_t image_width;
+  grub_uint16_t image_height;
+  grub_uint8_t image_bpp;
+  grub_uint8_t image_descriptor;
+} __attribute__ ((packed));
+
+static grub_err_t
+tga_load_truecolor_rle_R8G8B8 (struct grub_video_bitmap *bitmap,
+                               struct grub_tga_header *header,
+                               grub_file_t file)
+{
+  unsigned int x;
+  unsigned int y;
+  grub_uint8_t type;
+  grub_uint8_t *ptr;
+  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
+  grub_uint8_t bytes_per_pixel;
+
+  bytes_per_pixel = header->image_bpp / 8;
+
+  for (y = 0; y < header->image_height; y++)
+    {
+      ptr = bitmap->data;
+      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
+        ptr += y * bitmap->mode_info.pitch;
+      else
+        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
+
+      for (x = 0; x < header->image_width;)
+        {
+          if (grub_file_read (file, &type, sizeof (type)) != sizeof(type))
+            return grub_errno;
+
+          if (type & 0x80)
+            {
+              /* RLE-encoded packet.  */
+              type &= 0x7f;
+              type++;
+
+              if (grub_file_read (file, &tmp[0], bytes_per_pixel)
+                  != bytes_per_pixel)
+                return grub_errno;
+
+              while (type)
+                {
+                  if (x < header->image_width)
+                    {
+                      ptr[0] = tmp[2];
+                      ptr[1] = tmp[1];
+                      ptr[2] = tmp[0];
+                      ptr += 3;
+                    }
+
+                  type--;
+                  x++;
+                }
+            }
+          else
+            {
+              /* RAW-encoded packet.  */
+              type++;
+
+              while (type)
+                {
+                  if (grub_file_read (file, &tmp[0], bytes_per_pixel)
+                      != bytes_per_pixel)
+                    return grub_errno;
+
+                  if (x < header->image_width)
+                    {
+                      ptr[0] = tmp[2];
+                      ptr[1] = tmp[1];
+                      ptr[2] = tmp[0];
+                      ptr += 3;
+                    }
+
+                  type--;
+                  x++;
+                }
+            }
+        }
+    }
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+tga_load_truecolor_rle_R8G8B8A8 (struct grub_video_bitmap *bitmap,
+                                 struct grub_tga_header *header,
+                                 grub_file_t file)
+{
+  unsigned int x;
+  unsigned int y;
+  grub_uint8_t type;
+  grub_uint8_t *ptr;
+  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
+  grub_uint8_t bytes_per_pixel;
+
+  bytes_per_pixel = header->image_bpp / 8;
+
+  for (y = 0; y < header->image_height; y++)
+    {
+      ptr = bitmap->data;
+      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
+        ptr += y * bitmap->mode_info.pitch;
+      else
+        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
+
+      for (x = 0; x < header->image_width;)
+        {
+          if (grub_file_read (file, &type, sizeof (type)) != sizeof(type))
+            return grub_errno;
+
+          if (type & 0x80)
+            {
+              /* RLE-encoded packet.  */
+              type &= 0x7f;
+              type++;
+
+              if (grub_file_read (file, &tmp[0], bytes_per_pixel)
+                  != bytes_per_pixel)
+                return grub_errno;
+
+              while (type)
+                {
+                  if (x < header->image_width)
+                    {
+                      ptr[0] = tmp[2];
+                      ptr[1] = tmp[1];
+                      ptr[2] = tmp[0];
+                      ptr[3] = tmp[3];
+                      ptr += 4;
+                    }
+
+                  type--;
+                  x++;
+                }
+            }
+          else
+            {
+              /* RAW-encoded packet.  */
+              type++;
+
+              while (type)
+                {
+                  if (grub_file_read (file, &tmp[0], bytes_per_pixel)
+                      != bytes_per_pixel)
+                    return grub_errno;
+
+                  if (x < header->image_width)
+                    {
+                      ptr[0] = tmp[2];
+                      ptr[1] = tmp[1];
+                      ptr[2] = tmp[0];
+                      ptr[3] = tmp[3];
+                      ptr += 4;
+                    }
+
+                  type--;
+                  x++;
+                }
+            }
+        }
+    }
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+tga_load_truecolor_R8G8B8 (struct grub_video_bitmap *bitmap,
+                           struct grub_tga_header *header,
+                           grub_file_t file)
+{
+  unsigned int x;
+  unsigned int y;
+  grub_uint8_t *ptr;
+  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
+  grub_uint8_t bytes_per_pixel;
+
+  bytes_per_pixel = header->image_bpp / 8;
+
+  for (y = 0; y < header->image_height; y++)
+    {
+      ptr = bitmap->data;
+      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
+        ptr += y * bitmap->mode_info.pitch;
+      else
+        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
+
+      for (x = 0; x < header->image_width; x++)
+        {
+          if (grub_file_read (file, &tmp[0], bytes_per_pixel)
+              != bytes_per_pixel)
+            return grub_errno;
+
+          ptr[0] = tmp[2];
+          ptr[1] = tmp[1];
+          ptr[2] = tmp[0];
+
+          ptr += 3;
+        }
+    }
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+tga_load_truecolor_R8G8B8A8 (struct grub_video_bitmap *bitmap,
+                             struct grub_tga_header *header,
+                             grub_file_t file)
+{
+  unsigned int x;
+  unsigned int y;
+  grub_uint8_t *ptr;
+  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
+  grub_uint8_t bytes_per_pixel;
+
+  bytes_per_pixel = header->image_bpp / 8;
+
+  for (y = 0; y < header->image_height; y++)
+    {
+      ptr = bitmap->data;
+      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
+        ptr += y * bitmap->mode_info.pitch;
+      else
+        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
+
+      for (x = 0; x < header->image_width; x++)
+        {
+          if (grub_file_read (file, &tmp[0], bytes_per_pixel)
+              != bytes_per_pixel)
+            return grub_errno;
+
+          ptr[0] = tmp[2];
+          ptr[1] = tmp[1];
+          ptr[2] = tmp[0];
+          ptr[3] = tmp[3];
+
+          ptr += 4;
+        }
+    }
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_reader_tga (struct grub_video_bitmap **bitmap,
+                       const char *filename)
+{
+  grub_file_t file;
+  grub_ssize_t pos;
+  struct grub_tga_header header;
+  int has_alpha;
+
+  file = grub_buffile_open (filename, 0);
+  if (! file)
+    return grub_errno;
+
+  /* TGA Specification states that we SHOULD start by reading
+     ID from end of file, but we really don't care about that as we are
+     not going to support developer area & extensions at this point.  */
+
+  /* Read TGA header from beginning of file.  */
+  if (grub_file_read (file, &header, sizeof (header))
+      != sizeof (header))
+    {
+      grub_file_close (file);
+      return grub_errno;
+    }
+
+  /* Skip ID field.  */
+  pos = grub_file_tell (file);
+  pos += header.id_length;
+  grub_file_seek (file, pos);
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_file_close (file);
+      return grub_errno;
+    }
+
+#if defined(TGA_DEBUG)
+  grub_printf("tga: header\n");
+  dump_int_field(header.id_length);
+  dump_int_field(header.color_map_type);
+  dump_int_field(header.image_type);
+  dump_int_field(header.color_map_first_index);
+  dump_int_field(header.color_map_length);
+  dump_int_field(header.color_map_bpp);
+  dump_int_field(header.image_x_origin);
+  dump_int_field(header.image_y_origin);
+  dump_int_field(header.image_width);
+  dump_int_field(header.image_height);
+  dump_int_field(header.image_bpp);
+  dump_int_field(header.image_descriptor);
+#endif
+
+  /* Check that bitmap encoding is supported.  */
+  switch (header.image_type)
+    {
+      case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
+      case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
+        break;
+
+      default:
+        grub_file_close (file);
+        return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                           "unsupported bitmap format (unknown encoding)");
+    }
+
+  /* Check that bitmap depth is supported.  */
+  switch (header.image_bpp)
+    {
+      case 24:
+        has_alpha = 0;
+        break;
+
+      case 32:
+        has_alpha = 1;
+        break;
+
+      default:
+        grub_file_close (file);
+        return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+                           "unsupported bitmap format (bpp=%d)",
+                           header.image_bpp);
+    }
+
+  /* Allocate bitmap.  If there is alpha information store it too.  */
+  if (has_alpha)
+    {
+      grub_video_bitmap_create (bitmap, header.image_width,
+                                header.image_height,
+                                GRUB_VIDEO_BLIT_FORMAT_RGBA_8888);
+      if (grub_errno != GRUB_ERR_NONE)
+        {
+          grub_file_close (file);
+          return grub_errno;
+        }
+
+      /* Load bitmap data.  */
+      switch (header.image_type)
+        {
+          case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
+            tga_load_truecolor_R8G8B8A8 (*bitmap, &header, file);
+            break;
+
+          case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
+            tga_load_truecolor_rle_R8G8B8A8 (*bitmap, &header, file);
+            break;
+        }
+    }
+  else
+    {
+      grub_video_bitmap_create (bitmap, header.image_width,
+                                header.image_height,
+                                GRUB_VIDEO_BLIT_FORMAT_RGB_888);
+      if (grub_errno != GRUB_ERR_NONE)
+        {
+          grub_file_close (file);
+          return grub_errno;
+        }
+
+      /* Load bitmap data.  */
+      switch (header.image_type)
+        {
+          case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
+            tga_load_truecolor_R8G8B8 (*bitmap, &header, file);
+            break;
+
+          case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
+            tga_load_truecolor_rle_R8G8B8 (*bitmap, &header, file);
+            break;
+        }
+    }
+
+  /* If there was a loading problem, destroy bitmap.  */
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_video_bitmap_destroy (*bitmap);
+      *bitmap = 0;
+    }
+
+  grub_file_close (file);
+  return grub_errno;
+}
+
+#if defined(TGA_DEBUG)
+static grub_err_t
+grub_cmd_tgatest (grub_command_t cmd __attribute__ ((unused)),
+                  int argc, char **args)
+{
+  struct grub_video_bitmap *bitmap = 0;
+
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
+  grub_video_reader_tga (&bitmap, args[0]);
+  if (grub_errno != GRUB_ERR_NONE)
+    return grub_errno;
+
+  grub_video_bitmap_destroy (bitmap);
+
+  return GRUB_ERR_NONE;
+}
+#endif
+
+static struct grub_video_bitmap_reader tga_reader = {
+  .extension = ".tga",
+  .reader = grub_video_reader_tga,
+  .next = 0
+};
+
+GRUB_MOD_INIT(tga)
+{
+  grub_video_bitmap_reader_register (&tga_reader);
+#if defined(TGA_DEBUG)
+  cmd = grub_register_command ("tgatest", grub_cmd_tgatest,
+                               "FILE", "Tests loading of TGA bitmap.");
+#endif
+}
+
+GRUB_MOD_FINI(tga)
+{
+#if defined(TGA_DEBUG)
+  grub_unregister_command (cmd);
+#endif
+  grub_video_bitmap_reader_unregister (&tga_reader);
+}
diff --git a/grub-core/video/sm712.c b/grub-core/video/sm712.c
new file mode 100644 (file)
index 0000000..33861be
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define grub_video_render_target grub_video_fbrender_target
+
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/video.h>
+#include <grub/video_fb.h>
+#include <grub/pci.h>
+
+static struct
+{
+  struct grub_video_mode_info mode_info;
+  struct grub_video_render_target *render_target;
+
+  unsigned int bytes_per_scan_line;
+  unsigned int bytes_per_pixel;
+  grub_uint8_t *ptr;
+  int index_color_mode;
+  int mapped;
+  grub_uint32_t base;
+  grub_pci_device_t dev;
+} framebuffer;
+
+static grub_err_t
+grub_video_sm712_video_init (void)
+{
+  /* Reset frame buffer.  */
+  grub_memset (&framebuffer, 0, sizeof(framebuffer));
+
+  return grub_video_fb_init ();
+}
+
+static grub_err_t
+grub_video_sm712_video_fini (void)
+{
+  if (framebuffer.mapped)
+    grub_pci_device_unmap_range (framebuffer.dev, framebuffer.ptr,
+                                1024 * 600 * 2);
+
+  return grub_video_fb_fini ();
+}
+
+static grub_err_t
+grub_video_sm712_setup (unsigned int width, unsigned int height,
+                       unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused)))
+{
+  int depth;
+  grub_err_t err;
+  int found = 0;
+
+  auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)));
+  int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)))
+    {
+      grub_pci_address_t addr;
+      grub_uint32_t class;
+
+      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
+      class = grub_pci_read (addr);
+
+      if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x0712126f)
+       return 0;
+      
+      found = 1;
+
+      addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
+      framebuffer.base = grub_pci_read (addr);
+      framebuffer.dev = dev;
+
+      return 1;
+    }
+
+  /* Decode depth from mode_type.  If it is zero, then autodetect.  */
+  depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
+          >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
+
+  if ((width != 1024 && width != 0) || (height != 600 && height != 0)
+      || (depth != 16 && depth != 0))
+    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                      "Only 1024x600x16 is supported");
+
+  grub_pci_iterate (find_card);
+  if (!found)
+    return grub_error (GRUB_ERR_IO, "Couldn't find graphics card");
+
+  if (found && framebuffer.base == 0)
+    {
+      /* FIXME: change framebuffer base */
+    }
+
+  /* Fill mode info details.  */
+  framebuffer.mode_info.width = 1024;
+  framebuffer.mode_info.height = 600;
+  framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
+  framebuffer.mode_info.bpp = 16;
+  framebuffer.mode_info.bytes_per_pixel = 2;
+  framebuffer.mode_info.pitch = 1024 * 2;
+  framebuffer.mode_info.number_of_colors = 256;
+  framebuffer.mode_info.red_mask_size = 5;
+  framebuffer.mode_info.red_field_pos = 11;
+  framebuffer.mode_info.green_mask_size = 6;
+  framebuffer.mode_info.green_field_pos = 5;
+  framebuffer.mode_info.blue_mask_size = 5;
+  framebuffer.mode_info.blue_field_pos = 0;
+  framebuffer.mode_info.reserved_mask_size = 0;
+  framebuffer.mode_info.reserved_field_pos = 0;
+  framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info);
+  /* We can safely discard volatile attribute.  */
+  framebuffer.ptr = (void *) grub_pci_device_map_range (framebuffer.dev,
+                                                       framebuffer.base,
+                                                       1024 * 600 * 2);
+  framebuffer.mapped = 1;
+
+  err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr);
+
+  if (err)
+    return err;
+
+  err = grub_video_fb_set_active_render_target (framebuffer.render_target);
+  
+  if (err)
+    return err;
+
+  /* Copy default palette to initialize emulated palette.  */
+  err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
+                                  grub_video_fbstd_colors);
+  return err;
+}
+
+static grub_err_t
+grub_video_sm712_set_palette (unsigned int start, unsigned int count,
+                            struct grub_video_palette_data *palette_data)
+{
+  if (framebuffer.index_color_mode)
+    {
+      /* TODO: Implement setting indexed color mode palette to hardware.  */
+    }
+
+  /* Then set color to emulated palette.  */
+  return grub_video_fb_set_palette (start, count, palette_data);
+}
+
+static grub_err_t
+grub_video_sm712_swap_buffers (void)
+{
+  /* TODO: Implement buffer swapping.  */
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_video_sm712_set_active_render_target (struct grub_video_render_target *target)
+{
+  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
+      target = framebuffer.render_target;
+
+  return grub_video_fb_set_active_render_target (target);
+}
+
+static grub_err_t
+grub_video_sm712_get_info_and_fini (struct grub_video_mode_info *mode_info,
+                                   void **framebuf)
+{
+  grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
+  *framebuf = (char *) framebuffer.ptr;
+
+  grub_video_fb_fini ();
+
+  return GRUB_ERR_NONE;
+}
+
+
+static struct grub_video_adapter grub_video_sm712_adapter =
+  {
+    .name = "SM712 Video Driver",
+    .id = GRUB_VIDEO_DRIVER_SM712,
+
+    .init = grub_video_sm712_video_init,
+    .fini = grub_video_sm712_video_fini,
+    .setup = grub_video_sm712_setup,
+    .get_info = grub_video_fb_get_info,
+    .get_info_and_fini = grub_video_sm712_get_info_and_fini,
+    .set_palette = grub_video_sm712_set_palette,
+    .get_palette = grub_video_fb_get_palette,
+    .set_viewport = grub_video_fb_set_viewport,
+    .get_viewport = grub_video_fb_get_viewport,
+    .map_color = grub_video_fb_map_color,
+    .map_rgb = grub_video_fb_map_rgb,
+    .map_rgba = grub_video_fb_map_rgba,
+    .unmap_color = grub_video_fb_unmap_color,
+    .fill_rect = grub_video_fb_fill_rect,
+    .blit_bitmap = grub_video_fb_blit_bitmap,
+    .blit_render_target = grub_video_fb_blit_render_target,
+    .scroll = grub_video_fb_scroll,
+    .swap_buffers = grub_video_sm712_swap_buffers,
+    .create_render_target = grub_video_fb_create_render_target,
+    .delete_render_target = grub_video_fb_delete_render_target,
+    .set_active_render_target = grub_video_sm712_set_active_render_target,
+    .get_active_render_target = grub_video_fb_get_active_render_target,
+
+    .next = 0
+  };
+
+GRUB_MOD_INIT(video_sm712)
+{
+  grub_video_register (&grub_video_sm712_adapter);
+}
+
+GRUB_MOD_FINI(video_sm712)
+{
+  grub_video_unregister (&grub_video_sm712_adapter);
+}
diff --git a/grub-core/video/video.c b/grub-core/video/video.c
new file mode 100644 (file)
index 0000000..42418f9
--- /dev/null
@@ -0,0 +1,706 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/video.h>
+#include <grub/types.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+/* The list of video adapters registered to system.  */
+static grub_video_adapter_t grub_video_adapter_list;
+
+/* Active video adapter.  */
+static grub_video_adapter_t grub_video_adapter_active;
+
+/* Register video driver.  */
+void
+grub_video_register (grub_video_adapter_t adapter)
+{
+  adapter->next = grub_video_adapter_list;
+  grub_video_adapter_list = adapter;
+}
+
+/* Unregister video driver.  */
+void
+grub_video_unregister (grub_video_adapter_t adapter)
+{
+  grub_video_adapter_t *p, q;
+
+  for (p = &grub_video_adapter_list, q = *p; q; p = &(q->next), q = q->next)
+    if (q == adapter)
+      {
+        *p = q->next;
+        break;
+      }
+}
+
+/* Iterate thru all registered video drivers.  */
+void
+grub_video_iterate (int (*hook) (grub_video_adapter_t adapter))
+{
+  grub_video_adapter_t p;
+
+  for (p = grub_video_adapter_list; p; p = p->next)
+    if (hook (p))
+      break;
+}
+
+/* Restore back to initial mode (where applicable).  */
+grub_err_t
+grub_video_restore (void)
+{
+  if (grub_video_adapter_active)
+    {
+      grub_video_adapter_active->fini ();
+      if (grub_errno != GRUB_ERR_NONE)
+        return grub_errno;
+
+      grub_video_adapter_active = 0;
+    }
+  return GRUB_ERR_NONE;
+}
+
+/* Get information about active video mode.  */
+grub_err_t
+grub_video_get_info (struct grub_video_mode_info *mode_info)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  /* If mode_info is NULL just report that video adapter is active.  */
+  if (! mode_info)
+    {
+      grub_errno = GRUB_ERR_NONE;
+      return grub_errno;
+    }
+
+  return grub_video_adapter_active->get_info (mode_info);
+}
+
+grub_video_driver_id_t
+grub_video_get_driver_id (void)
+{
+  if (! grub_video_adapter_active)
+    return GRUB_VIDEO_DRIVER_NONE;
+  return grub_video_adapter_active->id;
+}
+
+/* Get information about active video mode.  */
+grub_err_t
+grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info,
+                             void **framebuffer)
+{
+  grub_err_t err;
+
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  err = grub_video_adapter_active->get_info_and_fini (mode_info, framebuffer);
+  if (err)
+    return err;
+
+  grub_video_adapter_active = 0;
+  return GRUB_ERR_NONE;
+}
+
+/* Determine optimized blitting formation for specified video mode info.  */
+enum grub_video_blit_format
+grub_video_get_blit_format (struct grub_video_mode_info *mode_info)
+{
+  /* Check if we have any known 32 bit modes.  */
+  if (mode_info->bpp == 32)
+    {
+      if ((mode_info->red_mask_size == 8)
+         && (mode_info->red_field_pos == 16)
+         && (mode_info->green_mask_size == 8)
+         && (mode_info->green_field_pos == 8)
+         && (mode_info->blue_mask_size == 8)
+         && (mode_info->blue_field_pos == 0))
+       {
+         return GRUB_VIDEO_BLIT_FORMAT_BGRA_8888;
+       }
+      else if ((mode_info->red_mask_size == 8)
+              && (mode_info->red_field_pos == 0)
+              && (mode_info->green_mask_size == 8)
+              && (mode_info->green_field_pos == 8)
+              && (mode_info->blue_mask_size == 8)
+              && (mode_info->blue_field_pos == 16))
+       {
+         return GRUB_VIDEO_BLIT_FORMAT_RGBA_8888;
+       }
+    }
+  /* Check if we have any known 24 bit modes.  */
+  else if (mode_info->bpp == 24)
+    {
+      if ((mode_info->red_mask_size == 8)
+         && (mode_info->red_field_pos == 16)
+         && (mode_info->green_mask_size == 8)
+         && (mode_info->green_field_pos == 8)
+         && (mode_info->blue_mask_size == 8)
+         && (mode_info->blue_field_pos == 0))
+       {
+         return GRUB_VIDEO_BLIT_FORMAT_BGR_888;
+       }
+      else if ((mode_info->red_mask_size == 8)
+              && (mode_info->red_field_pos == 0)
+              && (mode_info->green_mask_size == 8)
+              && (mode_info->green_field_pos == 8)
+              && (mode_info->blue_mask_size == 8)
+              && (mode_info->blue_field_pos == 16))
+       {
+         return GRUB_VIDEO_BLIT_FORMAT_RGB_888;
+       }
+    }
+  /* Check if we have any known 16 bit modes.  */
+  else if (mode_info->bpp == 16)
+    {
+      if ((mode_info->red_mask_size == 5)
+         && (mode_info->red_field_pos == 11)
+         && (mode_info->green_mask_size == 6)
+         && (mode_info->green_field_pos == 5)
+         && (mode_info->blue_mask_size == 5)
+         && (mode_info->blue_field_pos == 0))
+       {
+         return GRUB_VIDEO_BLIT_FORMAT_BGR_565;
+       }
+      else if ((mode_info->red_mask_size == 5)
+              && (mode_info->red_field_pos == 0)
+              && (mode_info->green_mask_size == 6)
+              && (mode_info->green_field_pos == 5)
+              && (mode_info->blue_mask_size == 5)
+              && (mode_info->blue_field_pos == 11))
+       {
+         return GRUB_VIDEO_BLIT_FORMAT_RGB_565;
+       }
+    }
+  else if (mode_info->bpp == 1)
+    return GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED;
+
+  /* Backup route.  Unknown format.  */
+
+  /* If there are more than 8 bits per color, assume RGB(A) mode.  */
+  if (mode_info->bpp > 8)
+    {
+      if (mode_info->reserved_mask_size > 0)
+       {
+         return GRUB_VIDEO_BLIT_FORMAT_RGBA;
+       }
+      else
+       {
+         return GRUB_VIDEO_BLIT_FORMAT_RGB;
+       }
+    }
+
+  /* Assume as indexcolor mode.  */
+  return GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR;
+}
+
+/* Set new indexed color palette entries.  */
+grub_err_t
+grub_video_set_palette (unsigned int start, unsigned int count,
+                        struct grub_video_palette_data *palette_data)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  return grub_video_adapter_active->set_palette (start, count, palette_data);
+}
+
+/* Get indexed color palette entries.  */
+grub_err_t
+grub_video_get_palette (unsigned int start, unsigned int count,
+                        struct grub_video_palette_data *palette_data)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  return grub_video_adapter_active->get_palette (start, count, palette_data);
+}
+
+/* Set viewport dimensions.  */
+grub_err_t
+grub_video_set_viewport (unsigned int x, unsigned int y,
+                         unsigned int width, unsigned int height)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  return grub_video_adapter_active->set_viewport (x, y, width, height);
+}
+
+/* Get viewport dimensions.  */
+grub_err_t
+grub_video_get_viewport (unsigned int *x, unsigned int *y,
+                         unsigned int *width, unsigned int *height)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  return grub_video_adapter_active->get_viewport (x, y, width, height);
+}
+
+/* Map color name to adapter specific color.  */
+grub_video_color_t
+grub_video_map_color (grub_uint32_t color_name)
+{
+  if (! grub_video_adapter_active)
+    return 0;
+
+  return grub_video_adapter_active->map_color (color_name);
+}
+
+/* Map RGB value to adapter specific color.  */
+grub_video_color_t
+grub_video_map_rgb (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue)
+{
+  if (! grub_video_adapter_active)
+    return 0;
+
+  return grub_video_adapter_active->map_rgb (red, green, blue);
+}
+
+/* Map RGBA value to adapter specific color.  */
+grub_video_color_t
+grub_video_map_rgba (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue,
+                     grub_uint8_t alpha)
+{
+  if (! grub_video_adapter_active)
+    return 0;
+
+  return grub_video_adapter_active->map_rgba (red, green, blue, alpha);
+}
+
+/* Unmap video color back to RGBA components.  */
+grub_err_t
+grub_video_unmap_color (grub_video_color_t color, grub_uint8_t *red,
+                        grub_uint8_t *green, grub_uint8_t *blue,
+                        grub_uint8_t *alpha)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  return grub_video_adapter_active->unmap_color (color,
+                                                 red,
+                                                 green,
+                                                 blue,
+                                                 alpha);
+}
+
+/* Fill rectangle using specified color.  */
+grub_err_t
+grub_video_fill_rect (grub_video_color_t color, int x, int y,
+                      unsigned int width, unsigned int height)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  return grub_video_adapter_active->fill_rect (color, x, y, width, height);
+}
+
+/* Blit bitmap to screen.  */
+grub_err_t
+grub_video_blit_bitmap (struct grub_video_bitmap *bitmap,
+                        enum grub_video_blit_operators oper,
+                        int x, int y, int offset_x, int offset_y,
+                        unsigned int width, unsigned int height)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  return grub_video_adapter_active->blit_bitmap (bitmap, oper, x, y,
+                                                 offset_x, offset_y,
+                                                 width, height);
+}
+
+/* Blit render target to active render target.  */
+grub_err_t
+grub_video_blit_render_target (struct grub_video_render_target *target,
+                               enum grub_video_blit_operators oper,
+                               int x, int y, int offset_x, int offset_y,
+                               unsigned int width, unsigned int height)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  return grub_video_adapter_active->blit_render_target (target, oper, x, y,
+                                                        offset_x, offset_y,
+                                                        width, height);
+}
+
+/* Scroll viewport and fill new areas with specified color.  */
+grub_err_t
+grub_video_scroll (grub_video_color_t color, int dx, int dy)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  return grub_video_adapter_active->scroll (color, dx, dy);
+}
+
+/* Swap buffers (swap active render target).  */
+grub_err_t
+grub_video_swap_buffers (void)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  return grub_video_adapter_active->swap_buffers ();
+}
+
+/* Create new render target.  */
+grub_err_t
+grub_video_create_render_target (struct grub_video_render_target **result,
+                                 unsigned int width, unsigned int height,
+                                 unsigned int mode_type)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  return grub_video_adapter_active->create_render_target (result,
+                                                          width, height,
+                                                          mode_type);
+}
+
+/* Delete render target.  */
+grub_err_t
+grub_video_delete_render_target (struct grub_video_render_target *target)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  return grub_video_adapter_active->delete_render_target (target);
+}
+
+/* Set active render target.  */
+grub_err_t
+grub_video_set_active_render_target (struct grub_video_render_target *target)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  return grub_video_adapter_active->set_active_render_target (target);
+}
+
+/* Get active render target.  */
+grub_err_t
+grub_video_get_active_render_target (struct grub_video_render_target **target)
+{
+  if (! grub_video_adapter_active)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
+
+  return grub_video_adapter_active->get_active_render_target (target);
+}
+
+/* Parse <width>x<height>[x<depth>]*/
+static grub_err_t
+parse_modespec (const char *current_mode, int *width, int *height, int *depth)
+{
+  const char *value;
+  const char *param = current_mode;
+
+  *width = *height = *depth = -1;
+
+  if (grub_strcmp (param, "auto") == 0)
+    {
+      *width = *height = 0;
+      return GRUB_ERR_NONE;
+    }
+
+  /* Find width value.  */
+  value = param;
+  param = grub_strchr(param, 'x');
+  if (param == NULL)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      "Invalid mode: %s\n",
+                      current_mode);
+
+  param++;
+  
+  *width = grub_strtoul (value, 0, 0);
+  if (grub_errno != GRUB_ERR_NONE)
+      return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                        "Invalid mode: %s\n",
+                        current_mode);
+  
+  /* Find height value.  */
+  value = param;
+  param = grub_strchr(param, 'x');
+  if (param == NULL)
+    {
+      *height = grub_strtoul (value, 0, 0);
+      if (grub_errno != GRUB_ERR_NONE)
+       return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                          "Invalid mode: %s\n",
+                          current_mode);
+    }
+  else
+    {
+      /* We have optional color depth value.  */
+      param++;
+      
+      *height = grub_strtoul (value, 0, 0);
+      if (grub_errno != GRUB_ERR_NONE)
+       return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                          "Invalid mode: %s\n",
+                          current_mode);
+      
+      /* Convert color depth value.  */
+      value = param;
+      *depth = grub_strtoul (value, 0, 0);
+      if (grub_errno != GRUB_ERR_NONE)
+       return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                          "Invalid mode: %s\n",
+                          current_mode);
+    }
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_video_set_mode (const char *modestring,
+                    unsigned int modemask,
+                    unsigned int modevalue)
+{
+  char *tmp;
+  char *next_mode;
+  char *current_mode;
+  char *modevar;
+
+  modevalue &= modemask;
+
+  /* Take copy of env.var. as we don't want to modify that.  */
+  modevar = grub_strdup (modestring);
+
+  /* Initialize next mode.  */
+  next_mode = modevar;
+
+  if (! modevar)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                      "couldn't allocate space for local modevar copy");
+
+  if (grub_memcmp (next_mode, "keep", sizeof ("keep")) == 0
+      || grub_memcmp (next_mode, "keep,", sizeof ("keep,") - 1) == 0
+      || grub_memcmp (next_mode, "keep;", sizeof ("keep;") - 1) == 0)
+    {
+      int suitable = 1;
+      grub_err_t err;
+
+      if (grub_video_adapter_active)
+       {
+         struct grub_video_mode_info mode_info;
+         grub_memset (&mode_info, 0, sizeof (mode_info));
+         err = grub_video_get_info (&mode_info);
+         if (err)
+           {
+             suitable = 0;
+             grub_errno = GRUB_ERR_NONE;
+           }
+         if ((mode_info.mode_type & modemask) != modevalue)
+           suitable = 0;
+       }
+      else if (((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modemask) != 0)
+              && ((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modevalue) == 0))
+       suitable = 0;
+
+      if (suitable)
+       {
+         grub_free (modevar);
+         return GRUB_ERR_NONE;
+       }
+      next_mode += sizeof ("keep") - 1;
+      if (! *next_mode)
+       {
+         grub_free (modevar);
+
+         return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                            "no suitable mode found");
+       }
+
+      /* Skip separator. */
+      next_mode++;
+    }
+
+  /* De-activate last set video adapter.  */
+  if (grub_video_adapter_active)
+    {
+      /* Finalize adapter.  */
+      grub_video_adapter_active->fini ();
+      if (grub_errno != GRUB_ERR_NONE)
+       grub_errno = GRUB_ERR_NONE;
+
+      /* Mark active adapter as not set.  */
+      grub_video_adapter_active = 0;
+    }
+
+  /* Loop until all modes has been tested out.  */
+  while (next_mode != NULL)
+    {
+      int width = -1;
+      int height = -1;
+      int depth = -1;
+      grub_err_t err;
+      unsigned int flags = modevalue;
+      unsigned int flagmask = modemask;
+
+      /* Use last next_mode as current mode.  */
+      tmp = next_mode;
+
+      /* Save position of next mode and separate modes.  */
+      for (; *next_mode; next_mode++)
+       if (*next_mode == ',' || *next_mode == ';')
+         break;
+      if (*next_mode)
+       {
+         *next_mode = 0;
+         next_mode++;
+       }
+      else
+       next_mode = 0;
+
+      /* Skip whitespace.  */
+      while (grub_isspace (*tmp))
+       tmp++;
+
+      /* Initialize token holders.  */
+      current_mode = tmp;
+
+      /* XXX: we assume that we're in pure text mode if
+        no video mode is initialized. Is it always true? */
+      if (grub_strcmp (current_mode, "text") == 0)
+       {
+         struct grub_video_mode_info mode_info;
+
+         grub_memset (&mode_info, 0, sizeof (mode_info));
+         if (((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modemask) == 0)
+             || ((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modevalue) != 0))
+           {
+             /* Valid mode found from adapter, and it has been activated.
+                Specify it as active adapter.  */
+             grub_video_adapter_active = NULL;
+
+             /* Free memory.  */
+             grub_free (modevar);
+
+             return GRUB_ERR_NONE;
+           }
+       }
+
+      err = parse_modespec (current_mode, &width, &height, &depth);
+      if (err)
+       {
+         /* Free memory before returning.  */
+         grub_free (modevar);
+
+         return err;
+       }
+
+      /* Try out video mode.  */
+
+      /* If user requested specific depth check if this depth is supported.  */
+      if (depth != -1 && (flagmask & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
+         &&
+         (((flags & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
+           != ((depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
+               & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK))))
+       continue;
+
+      if (depth != -1)
+       {
+         flags |= (depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
+           & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
+         flagmask |= GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
+       }
+
+      /* Try to initialize requested mode.  Ignore any errors.  */
+      grub_video_adapter_t p;
+
+      /* Loop thru all possible video adapter trying to find requested mode.  */
+      for (p = grub_video_adapter_list; p; p = p->next)
+       {
+         struct grub_video_mode_info mode_info;
+
+         grub_memset (&mode_info, 0, sizeof (mode_info));
+
+         /* Try to initialize adapter, if it fails, skip to next adapter.  */
+         err = p->init ();
+         if (err != GRUB_ERR_NONE)
+           {
+             grub_errno = GRUB_ERR_NONE;
+             continue;
+           }
+
+         /* Try to initialize video mode.  */
+         err = p->setup (width, height, flags, flagmask);
+         if (err != GRUB_ERR_NONE)
+           {
+             p->fini ();
+             grub_errno = GRUB_ERR_NONE;
+             continue;
+           }
+
+         err = p->get_info (&mode_info);
+         if (err != GRUB_ERR_NONE)
+           {
+             p->fini ();
+             grub_errno = GRUB_ERR_NONE;
+             continue;
+           }
+
+         flags = mode_info.mode_type & ~GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
+         flags |= (mode_info.bpp << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
+           & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
+
+         /* Check that mode is suitable for upper layer.  */
+         if ((flags & GRUB_VIDEO_MODE_TYPE_PURE_TEXT)
+             ? (((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modemask) != 0)
+                && ((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modevalue) == 0))
+             : ((flags & modemask) != modevalue))
+           {
+             p->fini ();
+             grub_errno = GRUB_ERR_NONE;
+             continue;
+           }
+
+         /* Valid mode found from adapter, and it has been activated.
+            Specify it as active adapter.  */
+         grub_video_adapter_active = p;
+
+         /* Free memory.  */
+         grub_free (modevar);
+
+         return GRUB_ERR_NONE;
+       }
+
+    }
+
+  /* Free memory.  */
+  grub_free (modevar);
+
+  return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                    "no suitable mode found");
+}
+
+/* Initialize Video API module.  */
+GRUB_MOD_INIT(video)
+{
+}
+
+/* Finalize Video API module.  */
+GRUB_MOD_FINI(video)
+{
+}
diff --git a/hello/hello.c b/hello/hello.c
deleted file mode 100644 (file)
index eff07d9..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/* hello.c - test module for dynamic loading */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2007  Free Software Foundation, Inc.
- *  Copyright (C) 2003  NIIBE Yutaka <gniibe@m17n.org>
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/extcmd.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-grub_cmd_hello (struct grub_extcmd *cmd __attribute__ ((unused)),
-               int argc __attribute__ ((unused)),
-               char **args __attribute__ ((unused)))
-{
-  grub_printf ("Hello World\n");
-  return 0;
-}
-
-static grub_extcmd_t cmd;
-
-GRUB_MOD_INIT(hello)
-{
-  cmd = grub_register_extcmd ("hello", grub_cmd_hello, GRUB_COMMAND_FLAG_BOTH,
-                             0, N_("Say \"Hello World\"."), 0);
-}
-
-GRUB_MOD_FINI(hello)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/hook/datehook.c b/hook/datehook.c
deleted file mode 100644 (file)
index 9b5b54b..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/* datehook.c - Module to install datetime hooks.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/env.h>
-#include <grub/misc.h>
-#include <grub/normal.h>
-#include <grub/datetime.h>
-
-static char *grub_datetime_names[] =
-{
-  "YEAR",
-  "MONTH",
-  "DAY",
-  "HOUR",
-  "MINUTE",
-  "SECOND",
-  "WEEKDAY",
-};
-
-static char *
-grub_read_hook_datetime (struct grub_env_var *var,
-                         const char *val __attribute__ ((unused)))
-{
-  struct grub_datetime datetime;
-  static char buf[6];
-
-  buf[0] = 0;
-  if (! grub_get_datetime (&datetime))
-    {
-      int i;
-
-      for (i = 0; i < 7; i++)
-        if (! grub_strcmp (var->name, grub_datetime_names[i]))
-          {
-            int n;
-
-            switch (i)
-              {
-              case 0:
-                n = datetime.year;
-                break;
-              case 1:
-                n = datetime.month;
-                break;
-              case 2:
-                n = datetime.day;
-                break;
-              case 3:
-                n = datetime.hour;
-                break;
-              case 4:
-                n = datetime.minute;
-                break;
-              case 5:
-                n = datetime.second;
-                break;
-              default:
-                return grub_get_weekday_name (&datetime);
-              }
-
-            grub_snprintf (buf, sizeof (buf), "%d", n);
-            break;
-          }
-    }
-
-  return buf;
-}
-
-GRUB_MOD_INIT(datehook)
-{
-  int i;
-
-  for (i = 0; i < 7; i++)
-    grub_register_variable_hook (grub_datetime_names[i],
-                                 grub_read_hook_datetime, 0);
-}
-
-GRUB_MOD_FINI(datehook)
-{
-  int i;
-
-  for (i = 0; i < 7; i++)
-    {
-      grub_register_variable_hook (grub_datetime_names[i], 0, 0);
-      grub_env_unset (grub_datetime_names[i]);
-    }
-}
diff --git a/include/grub/acorn_filecore.h b/include/grub/acorn_filecore.h
deleted file mode 100644 (file)
index 6cda6cf..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_ACORN_FILECORE_HEADER
-#define GRUB_ACORN_FILECORE_HEADER     1
-
-#include <grub/types.h>
-
-struct grub_filecore_disc_record
-{
-  grub_uint8_t log2secsize;
-  grub_uint8_t secspertrack;
-  grub_uint8_t heads;
-  grub_uint8_t density;
-  grub_uint8_t idlen;
-  grub_uint8_t log2bpmb;
-  grub_uint8_t skew;
-  grub_uint8_t bootoption;
-  /* In bits 0-5, flags in bits 6 and 7.  */
-  grub_uint8_t lowsector;
-  grub_uint8_t nzones;
-  grub_uint16_t zone_spare;
-  grub_uint32_t root_address;
-  /* Disc size in bytes.  */
-  grub_uint32_t disc_size;
-  grub_uint16_t cycle_id;
-  char disc_name[10];
-  /* Yes, it is 32 bits!  */
-  grub_uint32_t disctype;
-  /* Most significant part of the disc size.  */
-  grub_uint32_t disc_size2;
-  grub_uint8_t share_size;
-  grub_uint8_t big_flag;
-  grub_uint8_t reserved[18];
-};
-
-
-#endif /* ! GRUB_ACORN_FILECORE_HEADER */
diff --git a/include/grub/acpi.h b/include/grub/acpi.h
deleted file mode 100644 (file)
index 7933db8..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_ACPI_HEADER
-#define GRUB_ACPI_HEADER       1
-
-#include <grub/types.h>
-#include <grub/err.h>
-
-struct grub_acpi_rsdp_v10
-{
-  grub_uint8_t signature[8];
-  grub_uint8_t checksum;
-  grub_uint8_t oemid[6];
-  grub_uint8_t revision;
-  grub_uint32_t rsdt_addr;
-} __attribute__ ((packed));
-
-struct grub_acpi_rsdp_v20
-{
-  struct grub_acpi_rsdp_v10 rsdpv1;
-  grub_uint32_t length;
-  grub_uint64_t xsdt_addr;
-  grub_uint8_t checksum;
-  grub_uint8_t reserved[3];
-} __attribute__ ((packed));
-
-struct grub_acpi_table_header
-{
-  grub_uint8_t signature[4];
-  grub_uint32_t length;
-  grub_uint8_t revision;
-  grub_uint8_t checksum;
-  grub_uint8_t oemid[6];
-  grub_uint8_t oemtable[8];
-  grub_uint32_t oemrev;
-  grub_uint8_t creator_id[4];
-  grub_uint32_t creator_rev;
-} __attribute__ ((packed));
-
-struct grub_acpi_fadt
-{
-  struct grub_acpi_table_header hdr;
-  grub_uint32_t facs_addr;
-  grub_uint32_t dsdt_addr;
-  grub_uint8_t somefields1[88];
-  grub_uint64_t facs_xaddr;
-  grub_uint64_t dsdt_xaddr;
-  grub_uint8_t somefields2[96];
-} __attribute__ ((packed));
-
-struct grub_acpi_rsdp_v10 *grub_acpi_get_rsdpv1 (void);
-struct grub_acpi_rsdp_v20 *grub_acpi_get_rsdpv2 (void);
-struct grub_acpi_rsdp_v10 *grub_machine_acpi_get_rsdpv1 (void);
-struct grub_acpi_rsdp_v20 *grub_machine_acpi_get_rsdpv2 (void);
-grub_uint8_t grub_byte_checksum (void *base, grub_size_t size);
-
-grub_err_t grub_acpi_create_ebda (void);
-
-#endif /* ! GRUB_ACPI_HEADER */
diff --git a/include/grub/aout.h b/include/grub/aout.h
deleted file mode 100644 (file)
index f962a97..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*-
- * Copyright (c) 1992, 1993
- *      The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *      from: @(#)exec.h        8.1 (Berkeley) 6/11/93
- * $FreeBSD$
- */
-
-#ifndef GRUB_AOUT_HEADER
-#define GRUB_AOUT_HEADER 1
-
-#include <grub/types.h>
-
-struct grub_aout32_header
-{
-  grub_uint32_t a_midmag;      /* htonl(flags<<26 | mid<<16 | magic) */
-  grub_uint32_t a_text;                /* text segment size */
-  grub_uint32_t a_data;                /* initialized data size */
-  grub_uint32_t a_bss;         /* uninitialized data size */
-  grub_uint32_t a_syms;                /* symbol table size */
-  grub_uint32_t a_entry;       /* entry point */
-  grub_uint32_t a_trsize;      /* text relocation size */
-  grub_uint32_t a_drsize;      /* data relocation size */
-};
-
-struct grub_aout64_header
-{
-  grub_uint32_t a_midmag;      /* htonl(flags<<26 | mid<<16 | magic) */
-  grub_uint64_t a_text;                /* text segment size */
-  grub_uint64_t a_data;                /* initialized data size */
-  grub_uint64_t a_bss;         /* uninitialized data size */
-  grub_uint64_t a_syms;                /* symbol table size */
-  grub_uint64_t a_entry;       /* entry point */
-  grub_uint64_t a_trsize;      /* text relocation size */
-  grub_uint64_t a_drsize;      /* data relocation size */
-};
-
-union grub_aout_header
-{
-  struct grub_aout32_header aout32;
-  struct grub_aout64_header aout64;
-};
-
-#define AOUT_TYPE_NONE         0
-#define AOUT_TYPE_AOUT32       1
-#define AOUT_TYPE_AOUT64       6
-
-#define        AOUT32_OMAGIC           0x107   /* 0407 old impure format */
-#define        AOUT32_NMAGIC           0x108   /* 0410 read-only text */
-#define        AOUT32_ZMAGIC           0x10b   /* 0413 demand load format */
-#define AOUT32_QMAGIC          0xcc    /* 0314 "compact" demand load format */
-
-#define AOUT64_OMAGIC          0x1001
-#define AOUT64_ZMAGIC          0x1002
-#define AOUT64_NMAGIC          0x1003
-
-#define        AOUT_MID_ZERO           0       /* unknown - implementation dependent */
-#define        AOUT_MID_SUN010         1       /* sun 68010/68020 binary */
-#define        AOUT_MID_SUN020         2       /* sun 68020-only binary */
-#define AOUT_MID_I386          134     /* i386 BSD binary */
-#define AOUT_MID_SPARC         138     /* sparc */
-#define        AOUT_MID_HP200          200     /* hp200 (68010) BSD binary */
-#define        AOUT_MID_SUN            0x103
-#define        AOUT_MID_HP300          300     /* hp300 (68020+68881) BSD binary */
-#define        AOUT_MID_HPUX           0x20C   /* hp200/300 HP-UX binary */
-#define        AOUT_MID_HPUX800        0x20B   /* hp800 HP-UX binary */
-
-#define AOUT_FLAG_PIC          0x10    /* contains position independent code */
-#define AOUT_FLAG_DYNAMIC      0x20    /* contains run-time link-edit info */
-#define AOUT_FLAG_DPMASK       0x30    /* mask for the above */
-
-#define AOUT_GETMAGIC(header) ((header).a_midmag & 0xffff)
-#define AOUT_GETMID(header) ((header).a_midmag >> 16) & 0x03ff)
-#define AOUT_GETFLAG(header) ((header).a_midmag >> 26) & 0x3f)
-
-#ifndef GRUB_UTIL
-
-int EXPORT_FUNC(grub_aout_get_type) (union grub_aout_header *header);
-
-grub_err_t EXPORT_FUNC(grub_aout_load) (grub_file_t file, int offset,
-                                        grub_addr_t load_addr, int load_size,
-                                        grub_addr_t bss_end_addr);
-
-#endif
-
-#endif /* ! GRUB_AOUT_HEADER */
diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h
deleted file mode 100644 (file)
index 1042154..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_AT_KEYBOARD_HEADER
-#define GRUB_AT_KEYBOARD_HEADER        1
-
-#define SHIFT_L                0x2a
-#define SHIFT_R                0x36
-#define CTRL           0x1d
-#define ALT            0x38
-#define CAPS_LOCK      0x3a
-#define NUM_LOCK       0x45
-#define SCROLL_LOCK    0x46
-
-/* Used for sending commands to the controller.  */
-#define KEYBOARD_COMMAND_ISREADY(x)    !((x) & 0x02)
-#define KEYBOARD_COMMAND_READ          0x20
-#define KEYBOARD_COMMAND_WRITE         0x60
-#define KEYBOARD_COMMAND_REBOOT                0xfe
-
-#define KEYBOARD_SCANCODE_SET1         0x40
-
-#define KEYBOARD_ISMAKE(x)     !((x) & 0x80)
-#define KEYBOARD_ISREADY(x)    ((x) & 0x01)
-#define KEYBOARD_SCANCODE(x)   ((x) & 0x7f)
-
-#ifdef GRUB_MACHINE_IEEE1275
-#define OLPC_UP                GRUB_TERM_UP
-#define OLPC_DOWN      GRUB_TERM_DOWN
-#define OLPC_LEFT      GRUB_TERM_LEFT
-#define OLPC_RIGHT     GRUB_TERM_RIGHT
-#else
-#define OLPC_UP                '\0'
-#define OLPC_DOWN      '\0'
-#define OLPC_LEFT      '\0'
-#define OLPC_RIGHT     '\0'
-#endif
-
-#endif
diff --git a/include/grub/ata.h b/include/grub/ata.h
deleted file mode 100644 (file)
index 940e671..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/* ata.h - ATA disk access.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_ATA_HEADER
-#define GRUB_ATA_HEADER 1
-
-#include <grub/misc.h>
-#include <grub/symbol.h>
-/* XXX: For now this only works on i386.  */
-#include <grub/cpu/io.h>
-
-typedef enum
-  {
-    GRUB_ATA_CHS,
-    GRUB_ATA_LBA,
-    GRUB_ATA_LBA48
-  } grub_ata_addressing_t;
-
-#define GRUB_ATA_REG_DATA      0
-#define GRUB_ATA_REG_ERROR     1
-#define GRUB_ATA_REG_FEATURES  1
-#define GRUB_ATA_REG_SECTORS   2
-#define GRUB_ATAPI_REG_IREASON 2
-#define GRUB_ATA_REG_SECTNUM   3
-#define GRUB_ATA_REG_CYLLSB    4
-#define GRUB_ATA_REG_CYLMSB    5
-#define GRUB_ATA_REG_LBALOW    3
-#define GRUB_ATA_REG_LBAMID    4
-#define GRUB_ATAPI_REG_CNTLOW  4
-#define GRUB_ATA_REG_LBAHIGH   5
-#define GRUB_ATAPI_REG_CNTHIGH 5
-#define GRUB_ATA_REG_DISK      6
-#define GRUB_ATA_REG_CMD       7
-#define GRUB_ATA_REG_STATUS    7
-
-#define GRUB_ATA_REG2_CONTROL  0
-
-#define GRUB_ATA_STATUS_ERR    0x01
-#define GRUB_ATA_STATUS_INDEX  0x02
-#define GRUB_ATA_STATUS_ECC    0x04
-#define GRUB_ATA_STATUS_DRQ    0x08
-#define GRUB_ATA_STATUS_SEEK   0x10
-#define GRUB_ATA_STATUS_WRERR  0x20
-#define GRUB_ATA_STATUS_READY  0x40
-#define GRUB_ATA_STATUS_BUSY   0x80
-
-/* ATAPI interrupt reason values (I/O, D/C bits).  */
-#define GRUB_ATAPI_IREASON_MASK     0x3
-#define GRUB_ATAPI_IREASON_DATA_OUT 0x0
-#define GRUB_ATAPI_IREASON_CMD_OUT  0x1
-#define GRUB_ATAPI_IREASON_DATA_IN  0x2
-#define GRUB_ATAPI_IREASON_ERROR    0x3
-
-enum grub_ata_commands
-  {
-    GRUB_ATA_CMD_CHECK_POWER_MODE      = 0xe5,
-    GRUB_ATA_CMD_IDENTIFY_DEVICE       = 0xec,
-    GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE        = 0xa1,
-    GRUB_ATA_CMD_IDLE                  = 0xe3,
-    GRUB_ATA_CMD_PACKET                        = 0xa0,
-    GRUB_ATA_CMD_READ_SECTORS          = 0x20,
-    GRUB_ATA_CMD_READ_SECTORS_EXT      = 0x24,
-    GRUB_ATA_CMD_SECURITY_FREEZE_LOCK  = 0xf5,
-    GRUB_ATA_CMD_SET_FEATURES          = 0xef,
-    GRUB_ATA_CMD_SLEEP                 = 0xe6,
-    GRUB_ATA_CMD_SMART                 = 0xb0,
-    GRUB_ATA_CMD_STANDBY_IMMEDIATE     = 0xe0,
-    GRUB_ATA_CMD_WRITE_SECTORS         = 0x30,
-    GRUB_ATA_CMD_WRITE_SECTORS_EXT     = 0x34,
-  };
-
-enum grub_ata_timeout_milliseconds
-  {
-    GRUB_ATA_TOUT_STD  =  1000,  /* 1s standard timeout.  */
-    GRUB_ATA_TOUT_DATA = 10000   /* 10s DATA I/O timeout.  */
-  };
-
-struct grub_ata_device
-{
-  /* IDE port to use.  */
-  int port;
-
-  /* IO addresses on which the registers for this device can be
-     found.  */
-  grub_port_t ioaddress;
-  grub_port_t ioaddress2;
-
-  /* Two devices can be connected to a single cable.  Use this field
-     to select device 0 (commonly known as "master") or device 1
-     (commonly known as "slave").  */
-  int device;
-
-  /* Addressing methods available for accessing this device.  If CHS
-     is only available, use that.  Otherwise use LBA, except for the
-     high sectors.  In that case use LBA48.  */
-  grub_ata_addressing_t addr;
-
-  /* Sector count.  */
-  grub_uint64_t size;
-
-  /* CHS maximums.  */
-  grub_uint16_t cylinders;
-  grub_uint16_t heads;
-  grub_uint16_t sectors_per_track;
-
-  /* Set to 0 for ATA, set to 1 for ATAPI.  */
-  int atapi;
-
-  struct grub_ata_device *next;
-};
-
-grub_err_t EXPORT_FUNC(grub_ata_wait_not_busy) (struct grub_ata_device *dev,
-                                                int milliseconds);
-grub_err_t EXPORT_FUNC(grub_ata_wait_drq) (struct grub_ata_device *dev,
-                                          int rw, int milliseconds);
-void EXPORT_FUNC(grub_ata_pio_read) (struct grub_ata_device *dev,
-                                    char *buf, grub_size_t size);
-
-static inline void
-grub_ata_regset (struct grub_ata_device *dev, int reg, int val)
-{
-  grub_outb (val, dev->ioaddress + reg);
-}
-
-static inline grub_uint8_t
-grub_ata_regget (struct grub_ata_device *dev, int reg)
-{
-  return grub_inb (dev->ioaddress + reg);
-}
-
-static inline void
-grub_ata_regset2 (struct grub_ata_device *dev, int reg, int val)
-{
-  grub_outb (val, dev->ioaddress2 + reg);
-}
-
-static inline grub_uint8_t
-grub_ata_regget2 (struct grub_ata_device *dev, int reg)
-{
-  return grub_inb (dev->ioaddress2 + reg);
-}
-
-static inline grub_err_t
-grub_ata_check_ready (struct grub_ata_device *dev)
-{
-  if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY)
-    return grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_STD);
-
-  return GRUB_ERR_NONE;
-}
-
-#endif /* ! GRUB_ATA_HEADER */
diff --git a/include/grub/auth.h b/include/grub/auth.h
deleted file mode 100644 (file)
index 7473344..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef GRUB_AUTH_HEADER
-#define GRUB_AUTH_HEADER       1
-
-#include <grub/err.h>
-#include <grub/crypto.h>
-
-#define GRUB_AUTH_MAX_PASSLEN 1024
-
-typedef grub_err_t (*grub_auth_callback_t) (const char *, const char *, void *);
-
-grub_err_t grub_auth_register_authentication (const char *user,
-                                             grub_auth_callback_t callback,
-                                             void *arg);
-grub_err_t grub_auth_unregister_authentication (const char *user);
-
-grub_err_t grub_auth_authenticate (const char *user);
-grub_err_t grub_auth_deauthenticate (const char *user);
-grub_err_t grub_auth_check_authentication (const char *userlist);
-
-#endif /* ! GRUB_AUTH_HEADER */
diff --git a/include/grub/autoefi.h b/include/grub/autoefi.h
deleted file mode 100644 (file)
index 5ae4b3a..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-/* This file provides some abstractions so that the same code compiles with
-   both efi and efiemu
- */
-#ifndef GRUB_AUTOEFI_HEADER
-#define GRUB_AUTOEFI_HEADER    1
-
-
-#ifdef GRUB_MACHINE_EFI
-# include <grub/efi/efi.h>
-# define grub_autoefi_get_memory_map grub_efi_get_memory_map
-# define grub_autoefi_finish_boot_services grub_efi_finish_boot_services
-# define grub_autoefi_exit_boot_services grub_efi_exit_boot_services
-# define grub_autoefi_system_table grub_efi_system_table
-# define grub_autoefi_mmap_iterate grub_machine_mmap_iterate
-# define grub_autoefi_set_virtual_address_map grub_efi_set_virtual_address_map
-static inline grub_err_t grub_autoefi_prepare (void)
-{
-  return GRUB_ERR_NONE;
-};
-# define GRUB_AUTOEFI_MEMORY_AVAILABLE GRUB_MACHINE_MEMORY_AVAILABLE
-# define GRUB_AUTOEFI_MEMORY_RESERVED GRUB_MACHINE_MEMORY_RESERVED
-# ifdef GRUB_MACHINE_MEMORY_ACPI
-#  define GRUB_AUTOEFI_MEMORY_ACPI GRUB_MACHINE_MEMORY_ACPI
-# endif
-# ifdef GRUB_MACHINE_MEMORY_NVS
-#  define GRUB_AUTOEFI_MEMORY_NVS GRUB_MACHINE_MEMORY_NVS
-# endif
-# ifdef GRUB_MACHINE_MEMORY_CODE
-#  define GRUB_AUTOEFI_MEMORY_CODE GRUB_MACHINE_MEMORY_CODE
-# endif
-# define SYSTEM_TABLE_SIZEOF(x) (sizeof(grub_efi_system_table->x))
-# define SYSTEM_TABLE_VAR(x) ((void *)&(grub_efi_system_table->x))
-# define SYSTEM_TABLE_PTR(x) ((void *)(grub_efi_system_table->x))
-# define SIZEOF_OF_UINTN sizeof (grub_efi_uintn_t)
-# define SYSTEM_TABLE(x) (grub_efi_system_table->x)
-# define EFI_PRESENT 1
-#else
-# include <grub/efiemu/efiemu.h>
-# define grub_autoefi_get_memory_map grub_efiemu_get_memory_map
-# define grub_autoefi_finish_boot_services grub_efiemu_finish_boot_services
-# define grub_autoefi_exit_boot_services grub_efiemu_exit_boot_services
-# define grub_autoefi_system_table grub_efiemu_system_table
-# define grub_autoefi_mmap_iterate grub_efiemu_mmap_iterate
-# define grub_autoefi_prepare grub_efiemu_prepare
-# define grub_autoefi_set_virtual_address_map grub_efiemu_set_virtual_address_map
-# define GRUB_AUTOEFI_MEMORY_AVAILABLE GRUB_EFIEMU_MEMORY_AVAILABLE
-# define GRUB_AUTOEFI_MEMORY_RESERVED GRUB_EFIEMU_MEMORY_RESERVED
-# define GRUB_AUTOEFI_MEMORY_ACPI GRUB_EFIEMU_MEMORY_ACPI
-# define GRUB_AUTOEFI_MEMORY_NVS GRUB_EFIEMU_MEMORY_NVS
-# define GRUB_AUTOEFI_MEMORY_CODE GRUB_EFIEMU_MEMORY_CODE
-# define SYSTEM_TABLE_SIZEOF GRUB_EFIEMU_SYSTEM_TABLE_SIZEOF
-# define SYSTEM_TABLE_VAR GRUB_EFIEMU_SYSTEM_TABLE_VAR
-# define SYSTEM_TABLE_PTR GRUB_EFIEMU_SYSTEM_TABLE_PTR
-# define SIZEOF_OF_UINTN GRUB_EFIEMU_SIZEOF_OF_UINTN
-# define SYSTEM_TABLE GRUB_EFIEMU_SYSTEM_TABLE
-# define grub_efi_allocate_pages(x,y) (x)
-# define grub_efi_free_pages(x,y) GRUB_EFI_SUCCESS
-# define EFI_PRESENT 1
-#endif
-
-#endif
diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h
deleted file mode 100644 (file)
index 6e30039..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_BITMAP_HEADER
-#define GRUB_BITMAP_HEADER     1
-
-#include <grub/err.h>
-#include <grub/symbol.h>
-#include <grub/types.h>
-#include <grub/video.h>
-
-struct grub_video_bitmap
-{
-  /* Bitmap format description.  */
-  struct grub_video_mode_info mode_info;
-
-  /* Pointer to bitmap data formatted according to mode_info.  */
-  void *data;
-};
-
-struct grub_video_bitmap_reader
-{
-  /* File extension for this bitmap type (including dot).  */
-  const char *extension;
-
-  /* Reader function to load bitmap.  */
-  grub_err_t (*reader) (struct grub_video_bitmap **bitmap,
-                        const char *filename);
-
-  /* Next reader.  */
-  struct grub_video_bitmap_reader *next;
-};
-typedef struct grub_video_bitmap_reader *grub_video_bitmap_reader_t;
-
-void EXPORT_FUNC (grub_video_bitmap_reader_register) (grub_video_bitmap_reader_t reader);
-void EXPORT_FUNC (grub_video_bitmap_reader_unregister) (grub_video_bitmap_reader_t reader);
-
-grub_err_t EXPORT_FUNC (grub_video_bitmap_create) (struct grub_video_bitmap **bitmap,
-                                                  unsigned int width, unsigned int height,
-                                                  enum grub_video_blit_format blit_format);
-
-grub_err_t EXPORT_FUNC (grub_video_bitmap_destroy) (struct grub_video_bitmap *bitmap);
-
-grub_err_t EXPORT_FUNC (grub_video_bitmap_load) (struct grub_video_bitmap **bitmap,
-                                                const char *filename);
-
-unsigned int EXPORT_FUNC (grub_video_bitmap_get_width) (struct grub_video_bitmap *bitmap);
-unsigned int EXPORT_FUNC (grub_video_bitmap_get_height) (struct grub_video_bitmap *bitmap);
-
-void EXPORT_FUNC (grub_video_bitmap_get_mode_info) (struct grub_video_bitmap *bitmap,
-                                                   struct grub_video_mode_info *mode_info);
-
-void *EXPORT_FUNC (grub_video_bitmap_get_data) (struct grub_video_bitmap *bitmap);
-
-#endif /* ! GRUB_BITMAP_HEADER */
diff --git a/include/grub/bitmap_scale.h b/include/grub/bitmap_scale.h
deleted file mode 100644 (file)
index dce9fbb..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/* bitmap_scale.h - Bitmap scaling functions. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_BITMAP_SCALE_HEADER
-#define GRUB_BITMAP_SCALE_HEADER 1
-
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/bitmap_scale.h>
-
-enum grub_video_bitmap_scale_method
-{
-  /* Choose the fastest interpolation algorithm.  */
-  GRUB_VIDEO_BITMAP_SCALE_METHOD_FASTEST,
-  /* Choose the highest quality interpolation algorithm.  */
-  GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST,
-
-  /* Specific algorithms:  */
-  /* Nearest neighbor interpolation.  */
-  GRUB_VIDEO_BITMAP_SCALE_METHOD_NEAREST,
-  /* Bilinear interpolation.  */
-  GRUB_VIDEO_BITMAP_SCALE_METHOD_BILINEAR
-};
-
-grub_err_t
-EXPORT_FUNC (grub_video_bitmap_create_scaled) (struct grub_video_bitmap **dst,
-                                              int dst_width, int dst_height,
-                                              struct grub_video_bitmap *src,
-                                              enum 
-                                              grub_video_bitmap_scale_method
-                                              scale_method);
-
-#endif /* ! GRUB_BITMAP_SCALE_HEADER */
diff --git a/include/grub/boot.h b/include/grub/boot.h
deleted file mode 100644 (file)
index 2357748..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_BOOT_HEADER
-#define GRUB_BOOT_HEADER       1
-
-#define GRUB_BOOT_VERSION_MAJOR        4
-#define GRUB_BOOT_VERSION_MINOR        0
-#define GRUB_BOOT_VERSION      ((GRUB_BOOT_VERSION_MINOR << 8) \
-                                       | GRUB_BOOT_VERSION_MAJOR)
-
-#endif /* ! GRUB_BOOT_HEADER */
diff --git a/include/grub/bsdlabel.h b/include/grub/bsdlabel.h
deleted file mode 100644 (file)
index d88b253..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2004,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_BSDLABEL_PARTITION_HEADER
-#define GRUB_BSDLABEL_PARTITION_HEADER 1
-
-/* Constants for BSD disk label.  */
-#define GRUB_PC_PARTITION_BSD_LABEL_SECTOR     1
-#define GRUB_PC_PARTITION_BSD_LABEL_MAGIC      0x82564557
-
-/* BSD partition types.  */
-#define GRUB_PC_PARTITION_BSD_TYPE_UNUSED      0
-#define GRUB_PC_PARTITION_BSD_TYPE_SWAP                1
-#define GRUB_PC_PARTITION_BSD_TYPE_V6          2
-#define GRUB_PC_PARTITION_BSD_TYPE_V7          3
-#define GRUB_PC_PARTITION_BSD_TYPE_SYSV                4
-#define GRUB_PC_PARTITION_BSD_TYPE_V71K                5
-#define GRUB_PC_PARTITION_BSD_TYPE_V8          6
-#define GRUB_PC_PARTITION_BSD_TYPE_BSDFFS      7
-#define GRUB_PC_PARTITION_BSD_TYPE_MSDOS       8
-#define GRUB_PC_PARTITION_BSD_TYPE_BSDLFS      9
-#define GRUB_PC_PARTITION_BSD_TYPE_OTHER       10
-#define GRUB_PC_PARTITION_BSD_TYPE_HPFS                11
-#define GRUB_PC_PARTITION_BSD_TYPE_ISO9660     12
-#define GRUB_PC_PARTITION_BSD_TYPE_BOOT                13
-
-/* FreeBSD-specific types.  */
-#define GRUB_PC_PARTITION_FREEBSD_TYPE_VINUM   14
-#define GRUB_PC_PARTITION_FREEBSD_TYPE_RAID    15
-#define GRUB_PC_PARTITION_FREEBSD_TYPE_JFS2    21
-
-/* NetBSD-specific types.  */
-#define        GRUB_PC_PARTITION_NETBSD_TYPE_ADOS      14
-#define        GRUB_PC_PARTITION_NETBSD_TYPE_HFS       15
-#define        GRUB_PC_PARTITION_NETBSD_TYPE_FILECORE  16
-#define        GRUB_PC_PARTITION_NETBSD_TYPE_EXT2FS    17
-#define        GRUB_PC_PARTITION_NETBSD_TYPE_NTFS      18
-#define        GRUB_PC_PARTITION_NETBSD_TYPE_RAID      19
-#define        GRUB_PC_PARTITION_NETBSD_TYPE_CCD       20
-#define        GRUB_PC_PARTITION_NETBSD_TYPE_JFS2      21
-#define        GRUB_PC_PARTITION_NETBSD_TYPE_APPLEUFS  22
-
-/* OpenBSD-specific types.  */
-#define        GRUB_PC_PARTITION_OPENBSD_TYPE_ADOS     14
-#define        GRUB_PC_PARTITION_OPENBSD_TYPE_HFS      15
-#define        GRUB_PC_PARTITION_OPENBSD_TYPE_FILECORE 16
-#define        GRUB_PC_PARTITION_OPENBSD_TYPE_EXT2FS   17
-#define        GRUB_PC_PARTITION_OPENBSD_TYPE_NTFS     18
-#define        GRUB_PC_PARTITION_OPENBSD_TYPE_RAID     19
-
-/* The BSD partition entry.  */
-struct grub_partition_bsd_entry
-{
-  grub_uint32_t size;
-  grub_uint32_t offset;
-  grub_uint32_t fragment_size;
-  grub_uint8_t fs_type;
-  grub_uint8_t fs_fragments;
-  grub_uint16_t fs_cylinders;
-} __attribute__ ((packed));
-
-/* The BSD disk label. Only define members useful for GRUB.  */
-struct grub_partition_bsd_disk_label
-{
-  grub_uint32_t magic;
-  grub_uint8_t padding[128];
-  grub_uint32_t magic2;
-  grub_uint16_t checksum;
-  grub_uint16_t num_partitions;
-  grub_uint32_t boot_size;
-  grub_uint32_t superblock_size;
-} __attribute__ ((packed));
-
-#endif /* ! GRUB_PC_PARTITION_HEADER */
diff --git a/include/grub/bufio.h b/include/grub/bufio.h
deleted file mode 100644 (file)
index acdd0c8..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* bufio.h - prototypes for bufio */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_BUFIO_H
-#define GRUB_BUFIO_H   1
-
-#include <grub/file.h>
-
-grub_file_t EXPORT_FUNC (grub_bufio_open) (grub_file_t io, int size);
-grub_file_t EXPORT_FUNC (grub_buffile_open) (const char *name, int size);
-
-#endif /* ! GRUB_BUFIO_H */
diff --git a/include/grub/cache.h b/include/grub/cache.h
deleted file mode 100644 (file)
index 27e44f0..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* cache.h - Flush the processor's cache.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_CACHE_H
-#define GRUB_CACHE_H   1
-
-#include <grub/symbol.h>
-#include <grub/types.h>
-
-#if defined (__i386__) || defined (__x86_64__)
-static inline void
-grub_arch_sync_caches (void *address __attribute__ ((unused)),
-                      grub_size_t len __attribute__ ((unused)))
-{
-}
-#else
-void EXPORT_FUNC(grub_arch_sync_caches) (void *address, grub_size_t len);
-#endif
-
-#endif /* ! GRUB_CACHE_HEADER */
diff --git a/include/grub/charset.h b/include/grub/charset.h
deleted file mode 100644 (file)
index fc050da..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_CHARSET_HEADER
-#define GRUB_CHARSET_HEADER    1
-
-#include <grub/types.h>
-
-#define GRUB_UINT8_1_LEADINGBIT 0x80
-#define GRUB_UINT8_2_LEADINGBITS 0xc0
-#define GRUB_UINT8_3_LEADINGBITS 0xe0
-#define GRUB_UINT8_4_LEADINGBITS 0xf0
-#define GRUB_UINT8_5_LEADINGBITS 0xf8
-#define GRUB_UINT8_6_LEADINGBITS 0xfc
-#define GRUB_UINT8_7_LEADINGBITS 0xfe
-
-#define GRUB_UINT8_1_TRAILINGBIT 0x01
-#define GRUB_UINT8_2_TRAILINGBITS 0x03
-#define GRUB_UINT8_3_TRAILINGBITS 0x07
-#define GRUB_UINT8_4_TRAILINGBITS 0x0f
-#define GRUB_UINT8_5_TRAILINGBITS 0x1f
-#define GRUB_UINT8_6_TRAILINGBITS 0x3f
-
-#define GRUB_UCS2_LIMIT 0x10000
-#define GRUB_UTF16_UPPER_SURROGATE(code) \
-  (0xD800 + ((((code) - GRUB_UCS2_LIMIT) >> 12) & 0xfff))
-#define GRUB_UTF16_LOWER_SURROGATE(code) \
-  (0xDC00 + (((code) - GRUB_UCS2_LIMIT) & 0xfff))
-
-grub_ssize_t
-grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
-                   const grub_uint8_t *src, grub_size_t srcsize,
-                   const grub_uint8_t **srcend);
-
-/* Convert UTF-16 to UTF-8.  */
-static inline grub_uint8_t *
-grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src,
-                   grub_size_t size)
-{
-  grub_uint32_t code_high = 0;
-
-  while (size--)
-    {
-      grub_uint32_t code = *src++;
-
-      if (code_high)
-       {
-         if (code >= 0xDC00 && code <= 0xDFFF)
-           {
-             /* Surrogate pair.  */
-             code = ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000;
-
-             *dest++ = (code >> 18) | 0xF0;
-             *dest++ = ((code >> 12) & 0x3F) | 0x80;
-             *dest++ = ((code >> 6) & 0x3F) | 0x80;
-             *dest++ = (code & 0x3F) | 0x80;
-           }
-         else
-           {
-             /* Error...  */
-             *dest++ = '?';
-           }
-
-         code_high = 0;
-       }
-      else
-       {
-         if (code <= 0x007F)
-           *dest++ = code;
-         else if (code <= 0x07FF)
-           {
-             *dest++ = (code >> 6) | 0xC0;
-             *dest++ = (code & 0x3F) | 0x80;
-           }
-         else if (code >= 0xD800 && code <= 0xDBFF)
-           {
-             code_high = code;
-             continue;
-           }
-         else if (code >= 0xDC00 && code <= 0xDFFF)
-           {
-             /* Error... */
-             *dest++ = '?';
-           }
-         else
-           {
-             *dest++ = (code >> 12) | 0xE0;
-             *dest++ = ((code >> 6) & 0x3F) | 0x80;
-             *dest++ = (code & 0x3F) | 0x80;
-           }
-       }
-    }
-
-  return dest;
-}
-
-/* Convert UCS-4 to UTF-8.  */
-char *grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size);
-
-int
-grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize);
-
-int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
-                            grub_uint32_t **last_position);
-
-#endif
diff --git a/include/grub/cmos.h b/include/grub/cmos.h
deleted file mode 100644 (file)
index f508e3b..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef        GRUB_CMOS_H
-#define        GRUB_CMOS_H     1
-
-#include <grub/types.h>
-#include <grub/cpu/io.h>
-#include <grub/cpu/cmos.h>
-
-#define GRUB_CMOS_INDEX_SECOND         0
-#define GRUB_CMOS_INDEX_SECOND_ALARM   1
-#define GRUB_CMOS_INDEX_MINUTE         2
-#define GRUB_CMOS_INDEX_MINUTE_ALARM   3
-#define GRUB_CMOS_INDEX_HOUR           4
-#define GRUB_CMOS_INDEX_HOUR_ALARM     5
-#define GRUB_CMOS_INDEX_DAY_OF_WEEK    6
-#define GRUB_CMOS_INDEX_DAY_OF_MONTH   7
-#define GRUB_CMOS_INDEX_MONTH          8
-#define GRUB_CMOS_INDEX_YEAR           9
-
-#define GRUB_CMOS_INDEX_STATUS_A       0xA
-#define GRUB_CMOS_INDEX_STATUS_B       0xB
-#define GRUB_CMOS_INDEX_STATUS_C       0xC
-#define GRUB_CMOS_INDEX_STATUS_D       0xD
-
-#define GRUB_CMOS_STATUS_B_DAYLIGHT    1
-#define GRUB_CMOS_STATUS_B_24HOUR      2
-#define GRUB_CMOS_STATUS_B_BINARY      4
-
-static inline grub_uint8_t
-grub_bcd_to_num (grub_uint8_t a)
-{
-  return ((a >> 4) * 10 + (a & 0xF));
-}
-
-static inline grub_uint8_t
-grub_num_to_bcd (grub_uint8_t a)
-{
-  return (((a / 10) << 4) + (a % 10));
-}
-
-static inline grub_uint8_t
-grub_cmos_read (grub_uint8_t index)
-{
-  grub_outb (index, GRUB_CMOS_ADDR_REG);
-  return grub_inb (GRUB_CMOS_DATA_REG);
-}
-
-static inline void
-grub_cmos_write (grub_uint8_t index, grub_uint8_t value)
-{
-  grub_outb (index, GRUB_CMOS_ADDR_REG);
-  grub_outb (value, GRUB_CMOS_DATA_REG);
-}
-
-#endif /* GRUB_CMOS_H */
diff --git a/include/grub/command.h b/include/grub/command.h
deleted file mode 100644 (file)
index 6e9942b..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_COMMAND_HEADER
-#define GRUB_COMMAND_HEADER    1
-
-#include <grub/symbol.h>
-#include <grub/err.h>
-#include <grub/list.h>
-
-/* Can be run in the command-line.  */
-#define GRUB_COMMAND_FLAG_CMDLINE      0x1
-/* Can be run in the menu.  */
-#define GRUB_COMMAND_FLAG_MENU         0x2
-/* Can be run in both interfaces.  */
-#define GRUB_COMMAND_FLAG_BOTH         0x3
-/* Only for the command title.  */
-#define GRUB_COMMAND_FLAG_TITLE                0x4
-/* Don't print the command on booting.  */
-#define GRUB_COMMAND_FLAG_NO_ECHO      0x8
-/* This is an extended command.  */
-#define GRUB_COMMAND_FLAG_EXTCMD       0x10
-/* This is an dynamic command.  */
-#define GRUB_COMMAND_FLAG_DYNCMD       0x20
-
-struct grub_command;
-
-typedef grub_err_t (*grub_command_func_t) (struct grub_command *cmd,
-                                          int argc, char **argv);
-
-/* The command description.  */
-struct grub_command
-{
-  /* The next element.  */
-  struct grub_command *next;
-
-  /* The name.  */
-  const char *name;
-
-    /* The priority.  */
-  int prio;
-
-  /* The callback function.  */
-  grub_command_func_t func;
-
-  /* The flags.  */
-  unsigned flags;
-
-  /* The summary of the command usage.  */
-  const char *summary;
-
-  /* The description of the command.  */
-  const char *description;
-
-  /* Arbitrary data.  */
-  void *data;
-};
-typedef struct grub_command *grub_command_t;
-
-extern grub_command_t EXPORT_VAR(grub_command_list);
-
-grub_command_t
-EXPORT_FUNC(grub_register_command_prio) (const char *name,
-                                        grub_command_func_t func,
-                                        const char *summary,
-                                        const char *description,
-                                        int prio);
-void EXPORT_FUNC(grub_unregister_command) (grub_command_t cmd);
-
-static inline grub_command_t
-grub_register_command (const char *name,
-                      grub_command_func_t func,
-                      const char *summary,
-                      const char *description)
-{
-  return grub_register_command_prio (name, func, summary, description, 0);
-}
-
-static inline grub_command_t
-grub_register_command_p1 (const char *name,
-                         grub_command_func_t func,
-                         const char *summary,
-                         const char *description)
-{
-  return grub_register_command_prio (name, func, summary, description, 1);
-}
-
-static inline grub_command_t
-grub_command_find (const char *name)
-{
-  return grub_named_list_find (GRUB_AS_NAMED_LIST (grub_command_list), name);
-}
-
-static inline grub_err_t
-grub_command_execute (const char *name, int argc, char **argv)
-{
-  grub_command_t cmd;
-
-  cmd = grub_command_find (name);
-  return (cmd) ? cmd->func (cmd, argc, argv) : GRUB_ERR_FILE_NOT_FOUND;
-}
-
-static inline int
-grub_command_iterate (int (*func) (grub_command_t))
-{
-  return grub_list_iterate (GRUB_AS_LIST (grub_command_list),
-                           (grub_list_hook_t) func);
-}
-
-void grub_register_core_commands (void);
-
-#endif /* ! GRUB_COMMAND_HEADER */
diff --git a/include/grub/crypto.h b/include/grub/crypto.h
deleted file mode 100644 (file)
index 48b52ee..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
- *                2007, 2008, 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Contains elements based on gcrypt-module.h and gcrypt.h.in.
-   If it's changed please update this file.  */
-
-#ifndef GRUB_CRYPTO_HEADER
-#define GRUB_CRYPTO_HEADER 1
-
-#include <grub/symbol.h>
-#include <grub/types.h>
-#include <grub/err.h>
-
-typedef enum 
-  {
-    GPG_ERR_NO_ERROR,
-    GPG_ERR_BAD_MPI,
-    GPG_ERR_BAD_SECKEY,
-    GPG_ERR_BAD_SIGNATURE,
-    GPG_ERR_CIPHER_ALGO,
-    GPG_ERR_CONFLICT,
-    GPG_ERR_DECRYPT_FAILED,
-    GPG_ERR_DIGEST_ALGO,
-    GPG_ERR_GENERAL,
-    GPG_ERR_INTERNAL,
-    GPG_ERR_INV_ARG,
-    GPG_ERR_INV_CIPHER_MODE,
-    GPG_ERR_INV_FLAG,
-    GPG_ERR_INV_KEYLEN,
-    GPG_ERR_INV_OBJ,
-    GPG_ERR_INV_OP,
-    GPG_ERR_INV_SEXP,
-    GPG_ERR_INV_VALUE,
-    GPG_ERR_MISSING_VALUE,
-    GPG_ERR_NO_ENCRYPTION_SCHEME,
-    GPG_ERR_NO_OBJ,
-    GPG_ERR_NO_PRIME,
-    GPG_ERR_NO_SIGNATURE_SCHEME,
-    GPG_ERR_NOT_FOUND,
-    GPG_ERR_NOT_IMPLEMENTED,
-    GPG_ERR_NOT_SUPPORTED,
-    GPG_ERROR_CFLAGS,
-    GPG_ERR_PUBKEY_ALGO,
-    GPG_ERR_SELFTEST_FAILED,
-    GPG_ERR_TOO_SHORT,
-    GPG_ERR_UNSUPPORTED,
-    GPG_ERR_WEAK_KEY,
-    GPG_ERR_WRONG_KEY_USAGE,
-    GPG_ERR_WRONG_PUBKEY_ALGO,
-    GPG_ERR_OUT_OF_MEMORY
-  } gcry_err_code_t;
-#define gpg_err_code_t gcry_err_code_t
-#define gpg_error_t gcry_err_code_t
-
-enum gcry_cipher_modes 
-  {
-    GCRY_CIPHER_MODE_NONE   = 0,  /* Not yet specified. */
-    GCRY_CIPHER_MODE_ECB    = 1,  /* Electronic codebook. */
-    GCRY_CIPHER_MODE_CFB    = 2,  /* Cipher feedback. */
-    GCRY_CIPHER_MODE_CBC    = 3,  /* Cipher block chaining. */
-    GCRY_CIPHER_MODE_STREAM = 4,  /* Used with stream ciphers. */
-    GCRY_CIPHER_MODE_OFB    = 5,  /* Outer feedback. */
-    GCRY_CIPHER_MODE_CTR    = 6   /* Counter. */
-  };
-
-/* Type for the cipher_setkey function.  */
-typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c,
-                                                const unsigned char *key,
-                                                unsigned keylen);
-
-/* Type for the cipher_encrypt function.  */
-typedef void (*gcry_cipher_encrypt_t) (void *c,
-                                      unsigned char *outbuf,
-                                      const unsigned char *inbuf);
-
-/* Type for the cipher_decrypt function.  */
-typedef void (*gcry_cipher_decrypt_t) (void *c,
-                                      unsigned char *outbuf,
-                                      const unsigned char *inbuf);
-
-/* Type for the cipher_stencrypt function.  */
-typedef void (*gcry_cipher_stencrypt_t) (void *c,
-                                        unsigned char *outbuf,
-                                        const unsigned char *inbuf,
-                                        unsigned int n);
-
-/* Type for the cipher_stdecrypt function.  */
-typedef void (*gcry_cipher_stdecrypt_t) (void *c,
-                                        unsigned char *outbuf,
-                                        const unsigned char *inbuf,
-                                        unsigned int n);
-
-typedef struct gcry_cipher_oid_spec
-{
-  const char *oid;
-  int mode;
-} gcry_cipher_oid_spec_t;
-
-/* Module specification structure for ciphers.  */
-typedef struct gcry_cipher_spec
-{
-  const char *name;
-  const char **aliases;
-  gcry_cipher_oid_spec_t *oids;
-  grub_size_t blocksize;
-  grub_size_t keylen;
-  grub_size_t contextsize;
-  gcry_cipher_setkey_t setkey;
-  gcry_cipher_encrypt_t encrypt;
-  gcry_cipher_decrypt_t decrypt;
-  gcry_cipher_stencrypt_t stencrypt;
-  gcry_cipher_stdecrypt_t stdecrypt;
-  struct gcry_cipher_spec *next;
-} gcry_cipher_spec_t;
-
-/* Type for the md_init function.  */
-typedef void (*gcry_md_init_t) (void *c);
-
-/* Type for the md_write function.  */
-typedef void (*gcry_md_write_t) (void *c, const void *buf, grub_size_t nbytes);
-
-/* Type for the md_final function.  */
-typedef void (*gcry_md_final_t) (void *c);
-
-/* Type for the md_read function.  */
-typedef unsigned char *(*gcry_md_read_t) (void *c);
-
-typedef struct gcry_md_oid_spec
-{
-  const char *oidstring;
-} gcry_md_oid_spec_t;
-
-/* Module specification structure for message digests.  */
-typedef struct gcry_md_spec
-{
-  const char *name;
-  unsigned char *asnoid;
-  int asnlen;
-  gcry_md_oid_spec_t *oids;
-  grub_size_t mdlen;
-  gcry_md_init_t init;
-  gcry_md_write_t write;
-  gcry_md_final_t final;
-  gcry_md_read_t read;
-  grub_size_t contextsize; /* allocate this amount of context */
-  /* Block size, needed for HMAC.  */
-  grub_size_t blocksize;
-  struct gcry_md_spec *next;
-} gcry_md_spec_t;
-
-struct grub_crypto_cipher_handle
-{
-  const struct gcry_cipher_spec *cipher;
-  char ctx[0];
-};
-
-typedef struct grub_crypto_cipher_handle *grub_crypto_cipher_handle_t;
-
-struct grub_crypto_hmac_handle;
-
-const gcry_cipher_spec_t *
-grub_crypto_lookup_cipher_by_name (const char *name);
-
-grub_crypto_cipher_handle_t
-grub_crypto_cipher_open (const struct gcry_cipher_spec *cipher);
-
-gcry_err_code_t
-grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher,
-                           const unsigned char *key,
-                           unsigned keylen);
-
-void
-grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher);
-
-void
-grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size);
-
-gcry_err_code_t
-grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
-                        void *out, void *in, grub_size_t size);
-
-gcry_err_code_t
-grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher,
-                        void *out, void *in, grub_size_t size);
-gcry_err_code_t
-grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher,
-                        void *out, void *in, grub_size_t size,
-                        void *iv_in);
-gcry_err_code_t
-grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher,
-                        void *out, void *in, grub_size_t size,
-                        void *iv);
-void 
-grub_cipher_register (gcry_cipher_spec_t *cipher);
-void
-grub_cipher_unregister (gcry_cipher_spec_t *cipher);
-void 
-grub_md_register (gcry_md_spec_t *digest);
-void 
-grub_md_unregister (gcry_md_spec_t *cipher);
-void
-grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in,
-                 grub_size_t inlen);
-const gcry_md_spec_t *
-grub_crypto_lookup_md_by_name (const char *name);
-
-grub_err_t
-grub_crypto_gcry_error (gcry_err_code_t in);
-
-void grub_burn_stack (grub_size_t size);
-
-struct grub_crypto_hmac_handle *
-grub_crypto_hmac_init (const struct gcry_md_spec *md,
-                      const void *key, grub_size_t keylen);
-void
-grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd, void *data,
-                       grub_size_t datalen);
-gcry_err_code_t
-grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out);
-
-gcry_err_code_t
-grub_crypto_hmac_buffer (const struct gcry_md_spec *md,
-                        const void *key, grub_size_t keylen,
-                        void *data, grub_size_t datalen, void *out);
-
-extern gcry_md_spec_t _gcry_digest_spec_md5;
-extern gcry_md_spec_t _gcry_digest_spec_sha1;
-extern gcry_md_spec_t _gcry_digest_spec_sha256;
-extern gcry_md_spec_t _gcry_digest_spec_sha512;
-#define GRUB_MD_MD5 ((const gcry_md_spec_t *) &_gcry_digest_spec_md5)
-#define GRUB_MD_SHA1 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha1)
-#define GRUB_MD_SHA256 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha256)
-#define GRUB_MD_SHA512 ((const gcry_md_spec_t *) &_gcry_digest_spec_sha512)
-
-/* Implement PKCS#5 PBKDF2 as per RFC 2898.  The PRF to use is HMAC variant
-   of digest supplied by MD.  Inputs are the password P of length PLEN,
-   the salt S of length SLEN, the iteration counter C (> 0), and the
-   desired derived output length DKLEN.  Output buffer is DK which
-   must have room for at least DKLEN octets.  The output buffer will
-   be filled with the derived data.  */
-gcry_err_code_t
-grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
-                   const grub_uint8_t *P, grub_size_t Plen,
-                   const grub_uint8_t *S, grub_size_t Slen,
-                   unsigned int c,
-                   grub_uint8_t *DK, grub_size_t dkLen);
-
-int
-grub_crypto_memcmp (const void *a, const void *b, grub_size_t n);
-
-int
-grub_password_get (char buf[], unsigned buf_size);
-
-/* For indistinguishibility.  */
-#define GRUB_ACCESS_DENIED grub_error (GRUB_ERR_ACCESS_DENIED, "Access denied.")
-
-extern void (*grub_crypto_autoload_hook) (const char *name);
-
-#endif
diff --git a/include/grub/datetime.h b/include/grub/datetime.h
deleted file mode 100644 (file)
index e721e89..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KERNEL_DATETIME_HEADER
-#define KERNEL_DATETIME_HEADER 1
-
-#include <grub/types.h>
-#include <grub/err.h>
-
-struct grub_datetime
-{
-  grub_uint16_t year;
-  grub_uint8_t month;
-  grub_uint8_t day;
-  grub_uint8_t hour;
-  grub_uint8_t minute;
-  grub_uint8_t second;
-};
-
-/* Return date and time.  */
-#ifdef GRUB_MACHINE_EMU
-grub_err_t EXPORT_FUNC(grub_get_datetime) (struct grub_datetime *datetime);
-
-/* Set date and time.  */
-grub_err_t EXPORT_FUNC(grub_set_datetime) (struct grub_datetime *datetime);
-#else
-grub_err_t grub_get_datetime (struct grub_datetime *datetime);
-
-/* Set date and time.  */
-grub_err_t grub_set_datetime (struct grub_datetime *datetime);
-#endif
-
-int grub_get_weekday (struct grub_datetime *datetime);
-char *grub_get_weekday_name (struct grub_datetime *datetime);
-
-void grub_unixtime2datetime (grub_int32_t nix,
-                            struct grub_datetime *datetime);
-
-
-#endif /* ! KERNEL_DATETIME_HEADER */
diff --git a/include/grub/device.h b/include/grub/device.h
deleted file mode 100644 (file)
index f0e8a8c..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* device.h - device manager */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_DEVICE_HEADER
-#define GRUB_DEVICE_HEADER     1
-
-#include <grub/symbol.h>
-#include <grub/err.h>
-
-struct grub_disk;
-struct grub_net;
-struct grub_fs;
-
-struct grub_device
-{
-  struct grub_disk *disk;
-  struct grub_net *net;
-};
-typedef struct grub_device *grub_device_t;
-
-grub_device_t EXPORT_FUNC(grub_device_open) (const char *name);
-grub_err_t EXPORT_FUNC(grub_device_close) (grub_device_t device);
-int EXPORT_FUNC(grub_device_iterate) (int (*hook) (const char *name));
-
-#endif /* ! GRUB_DEVICE_HEADER */
diff --git a/include/grub/disk.h b/include/grub/disk.h
deleted file mode 100644 (file)
index e60b1f3..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_DISK_HEADER
-#define GRUB_DISK_HEADER       1
-
-#include <grub/symbol.h>
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/device.h>
-
-/* These are used to set a device id. When you add a new disk device,
-   you must define a new id for it here.  */
-enum grub_disk_dev_id
-  {
-    GRUB_DISK_DEVICE_BIOSDISK_ID,
-    GRUB_DISK_DEVICE_OFDISK_ID,
-    GRUB_DISK_DEVICE_LOOPBACK_ID,
-    GRUB_DISK_DEVICE_EFIDISK_ID,
-    GRUB_DISK_DEVICE_RAID_ID,
-    GRUB_DISK_DEVICE_LVM_ID,
-    GRUB_DISK_DEVICE_HOST_ID,
-    GRUB_DISK_DEVICE_ATA_ID,
-    GRUB_DISK_DEVICE_MEMDISK_ID,
-    GRUB_DISK_DEVICE_NAND_ID,
-    GRUB_DISK_DEVICE_UUID_ID,
-    GRUB_DISK_DEVICE_PXE_ID,
-    GRUB_DISK_DEVICE_SCSI_ID,
-    GRUB_DISK_DEVICE_FILE_ID,
-    GRUB_DISK_DEVICE_LUKS_ID
-  };
-
-struct grub_disk;
-#ifdef GRUB_UTIL
-struct grub_disk_memberlist;
-#endif
-
-/* Disk device.  */
-struct grub_disk_dev
-{
-  /* The device name.  */
-  const char *name;
-
-  /* The device id used by the cache manager.  */
-  enum grub_disk_dev_id id;
-
-  /* Call HOOK with each device name, until HOOK returns non-zero.  */
-  int (*iterate) (int (*hook) (const char *name));
-
-  /* Open the device named NAME, and set up DISK.  */
-  grub_err_t (*open) (const char *name, struct grub_disk *disk);
-
-  /* Close the disk DISK.  */
-  void (*close) (struct grub_disk *disk);
-
-  /* Read SIZE sectors from the sector SECTOR of the disk DISK into BUF.  */
-  grub_err_t (*read) (struct grub_disk *disk, grub_disk_addr_t sector,
-                     grub_size_t size, char *buf);
-
-  /* Write SIZE sectors from BUF into the sector SECTOR of the disk DISK.  */
-  grub_err_t (*write) (struct grub_disk *disk, grub_disk_addr_t sector,
-                      grub_size_t size, const char *buf);
-
-#ifdef GRUB_UTIL
-  struct grub_disk_memberlist *(*memberlist) (struct grub_disk *disk);
-#endif
-
-  /* The next disk device.  */
-  struct grub_disk_dev *next;
-};
-typedef struct grub_disk_dev *grub_disk_dev_t;
-
-struct grub_partition;
-
-/* Disk.  */
-struct grub_disk
-{
-  /* The disk name.  */
-  const char *name;
-
-  /* The underlying disk device.  */
-  grub_disk_dev_t dev;
-
-  /* The total number of sectors.  */
-  grub_uint64_t total_sectors;
-
-  /* If partitions can be stored.  */
-  int has_partitions;
-
-  /* The id used by the disk cache manager.  */
-  unsigned long id;
-
-  /* The partition information. This is machine-specific.  */
-  struct grub_partition *partition;
-
-  /* Called when a sector was read. OFFSET is between 0 and
-     the sector size minus 1, and LENGTH is between 0 and the sector size.  */
-  void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                    unsigned offset, unsigned length);
-
-  /* Device-specific data.  */
-  void *data;
-};
-typedef struct grub_disk *grub_disk_t;
-
-#ifdef GRUB_UTIL
-struct grub_disk_memberlist
-{
-  grub_disk_t disk;
-  struct grub_disk_memberlist *next;
-};
-typedef struct grub_disk_memberlist *grub_disk_memberlist_t;
-#endif
-
-/* The sector size.  */
-#define GRUB_DISK_SECTOR_SIZE  0x200
-#define GRUB_DISK_SECTOR_BITS  9
-
-/* The maximum number of disk caches.  */
-#define GRUB_DISK_CACHE_NUM    1021
-
-/* The size of a disk cache in sector units.  */
-#define GRUB_DISK_CACHE_SIZE   8
-#define GRUB_DISK_CACHE_BITS   3
-
-/* This is called from the memory manager.  */
-void grub_disk_cache_invalidate_all (void);
-
-void EXPORT_FUNC(grub_disk_dev_register) (grub_disk_dev_t dev);
-void EXPORT_FUNC(grub_disk_dev_unregister) (grub_disk_dev_t dev);
-int EXPORT_FUNC(grub_disk_dev_iterate) (int (*hook) (const char *name));
-
-grub_disk_t EXPORT_FUNC(grub_disk_open) (const char *name);
-void EXPORT_FUNC(grub_disk_close) (grub_disk_t disk);
-grub_err_t EXPORT_FUNC(grub_disk_read) (grub_disk_t disk,
-                                       grub_disk_addr_t sector,
-                                       grub_off_t offset,
-                                       grub_size_t size,
-                                       void *buf);
-grub_err_t EXPORT_FUNC(grub_disk_write) (grub_disk_t disk,
-                                        grub_disk_addr_t sector,
-                                        grub_off_t offset,
-                                        grub_size_t size,
-                                        const void *buf);
-
-grub_uint64_t EXPORT_FUNC(grub_disk_get_size) (grub_disk_t disk);
-
-extern void (* EXPORT_VAR(grub_disk_firmware_fini)) (void);
-extern int EXPORT_VAR(grub_disk_firmware_is_tainted);
-
-/* ATA pass through parameters and function.  */
-struct grub_disk_ata_pass_through_parms
-{
-  grub_uint8_t taskfile[8];
-  void * buffer;
-  int size;
-};
-
-extern grub_err_t (* EXPORT_VAR(grub_disk_ata_pass_through)) (grub_disk_t,
-                  struct grub_disk_ata_pass_through_parms *);
-
-#endif /* ! GRUB_DISK_HEADER */
diff --git a/include/grub/dl.h b/include/grub/dl.h
deleted file mode 100644 (file)
index cfb7c2f..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/* dl.h - types and prototypes for loadable module support */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_DL_H
-#define GRUB_DL_H      1
-
-#include <grub/symbol.h>
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/elf.h>
-
-#define GRUB_MOD_INIT(name)    \
-static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
-void grub_##name##_init (void); \
-void \
-grub_##name##_init (void) { grub_mod_init (0); } \
-static void \
-grub_mod_init (grub_dl_t mod __attribute__ ((unused)))
-
-#define GRUB_MOD_FINI(name)    \
-static void grub_mod_fini (void) __attribute__ ((used)); \
-void grub_##name##_fini (void); \
-void \
-grub_##name##_fini (void) { grub_mod_fini (); } \
-static void \
-grub_mod_fini (void)
-
-#ifdef APPLE_CC
-#define GRUB_MOD_NAME(name)    \
-static char grub_modname[] __attribute__ ((section ("_modname, _modname"), used)) = #name;
-
-#define GRUB_MOD_DEP(name)     \
-__asm__ (".section _moddeps, _moddeps\n.asciz \"" #name "\"\n")
-#else
-#define GRUB_MOD_NAME(name)    \
-__asm__ (".section .modname\n.asciz \"" #name "\"\n")
-
-#define GRUB_MOD_DEP(name)     \
-__asm__ (".section .moddeps\n.asciz \"" #name "\"\n")
-#endif
-
-struct grub_dl_segment
-{
-  struct grub_dl_segment *next;
-  void *addr;
-  grub_size_t size;
-  unsigned section;
-};
-typedef struct grub_dl_segment *grub_dl_segment_t;
-
-struct grub_dl;
-
-struct grub_dl_dep
-{
-  struct grub_dl_dep *next;
-  struct grub_dl *mod;
-};
-typedef struct grub_dl_dep *grub_dl_dep_t;
-
-struct grub_dl
-{
-  char *name;
-  int ref_count;
-  grub_dl_dep_t dep;
-  grub_dl_segment_t segment;
-  Elf_Sym *symtab;
-  void (*init) (struct grub_dl *mod);
-  void (*fini) (void);
-};
-typedef struct grub_dl *grub_dl_t;
-
-grub_dl_t EXPORT_FUNC(grub_dl_load_file) (const char *filename);
-grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name);
-grub_dl_t grub_dl_load_core (void *addr, grub_size_t size);
-int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod);
-void grub_dl_unload_unneeded (void);
-void grub_dl_unload_all (void);
-#if defined (GRUB_UTIL) || defined (GRUB_TARGET_NO_MODULES)
-#define GRUB_NO_MODULES 1
-#else
-#define GRUB_NO_MODULES 0
-#endif
-#if GRUB_NO_MODULES
-static inline int
-grub_dl_ref (grub_dl_t mod)
-{
-  (void) mod;
-  return 0;
-}
-static inline int
-grub_dl_unref (grub_dl_t mod)
-{
-  (void) mod;
-  return 0;
-}
-#else
-int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod);
-int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod);
-#endif
-void EXPORT_FUNC(grub_dl_iterate) (int (*hook) (grub_dl_t mod));
-grub_dl_t EXPORT_FUNC(grub_dl_get) (const char *name);
-grub_err_t grub_dl_register_symbol (const char *name, void *addr,
-                                   grub_dl_t mod);
-
-grub_err_t grub_arch_dl_check_header (void *ehdr);
-grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr);
-
-#if defined (_mips) && ! GRUB_NO_MODULES
-#define GRUB_LINKER_HAVE_INIT 1
-void grub_arch_dl_init_linker (void);
-#endif
-
-#endif /* ! GRUB_DL_H */
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
deleted file mode 100644 (file)
index 36363ae..0000000
+++ /dev/null
@@ -1,1191 +0,0 @@
-/* efi.h - declare EFI types and functions */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_EFI_API_HEADER
-#define GRUB_EFI_API_HEADER    1
-
-#include <grub/types.h>
-#include <grub/symbol.h>
-
-/* For consistency and safety, we name the EFI-defined types differently.
-   All names are transformed into lower case, _t appended, and
-   grub_efi_ prepended.  */
-
-/* Constants.  */
-#define GRUB_EFI_EVT_TIMER                             0x80000000
-#define GRUB_EFI_EVT_RUNTIME                           0x40000000
-#define GRUB_EFI_EVT_RUNTIME_CONTEXT                   0x20000000
-#define GRUB_EFI_EVT_NOTIFY_WAIT                       0x00000100
-#define GRUB_EFI_EVT_NOTIFY_SIGNAL                     0x00000200
-#define GRUB_EFI_EVT_SIGNAL_EXIT_BOOT_SERVICES         0x00000201
-#define GRUB_EFI_EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE     0x60000202
-
-#define GRUB_EFI_TPL_APPLICATION       4
-#define GRUB_EFI_TPL_CALLBACK          8
-#define GRUB_EFI_TPL_NOTIFY            16
-#define GRUB_EFI_TPL_HIGH_LEVEL                31
-
-#define GRUB_EFI_MEMORY_UC     0x0000000000000001LL
-#define GRUB_EFI_MEMORY_WC     0x0000000000000002LL
-#define GRUB_EFI_MEMORY_WT     0x0000000000000004LL
-#define GRUB_EFI_MEMORY_WB     0x0000000000000008LL
-#define GRUB_EFI_MEMORY_UCE    0x0000000000000010LL
-#define GRUB_EFI_MEMORY_WP     0x0000000000001000LL
-#define GRUB_EFI_MEMORY_RP     0x0000000000002000LL
-#define GRUB_EFI_MEMORY_XP     0x0000000000004000LL
-#define GRUB_EFI_MEMORY_RUNTIME        0x8000000000000000LL
-
-#define GRUB_EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL      0x00000001
-#define GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL            0x00000002
-#define GRUB_EFI_OPEN_PROTOCOL_TEST_PROTOCOL           0x00000004
-#define GRUB_EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER     0x00000008
-#define GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER               0x00000010
-#define GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE            0x00000020
-
-#define GRUB_EFI_VARIABLE_NON_VOLATILE         0x0000000000000001
-#define GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS   0x0000000000000002
-#define GRUB_EFI_VARIABLE_RUNTIME_ACCESS       0x0000000000000004
-
-#define GRUB_EFI_TIME_ADJUST_DAYLIGHT  0x01
-#define GRUB_EFI_TIME_IN_DAYLIGHT      0x02
-
-#define GRUB_EFI_UNSPECIFIED_TIMEZONE  0x07FF
-
-#define GRUB_EFI_OPTIONAL_PTR  0x00000001
-
-#define GRUB_EFI_LOADED_IMAGE_GUID     \
-  { 0x5b1b31a1, 0x9562, 0x11d2, \
-    { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
-  }
-
-#define GRUB_EFI_DISK_IO_GUID  \
-  { 0xce345171, 0xba0b, 0x11d2, \
-    { 0x8e, 0x4f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
-  }
-
-#define GRUB_EFI_BLOCK_IO_GUID \
-  { 0x964e5b21, 0x6459, 0x11d2, \
-    { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
-  }
-
-#define GRUB_EFI_DEVICE_PATH_GUID      \
-  { 0x09576e91, 0x6d3f, 0x11d2, \
-    { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
-  }
-
-#define GRUB_EFI_MPS_TABLE_GUID        \
-  { 0xeb9d2d2f, 0x2d88, 0x11d3, \
-    { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
-  }
-
-#define GRUB_EFI_ACPI_TABLE_GUID       \
-  { 0xeb9d2d30, 0x2d88, 0x11d3, \
-    { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
-  }
-
-#define GRUB_EFI_ACPI_20_TABLE_GUID    \
-  { 0x8868e871, 0xe4f1, 0x11d3, \
-    { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
-  }
-
-#define GRUB_EFI_SMBIOS_TABLE_GUID     \
-  { 0xeb9d2d31, 0x2d88, 0x11d3, \
-    { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
-  }
-
-/* Enumerations.  */
-enum grub_efi_timer_delay
-  {
-    GRUB_EFI_TIMER_CANCEL,
-    GRUB_EFI_TIMER_PERIODIC,
-    GRUB_EFI_TIMER_RELATIVE
-  };
-typedef enum grub_efi_timer_delay grub_efi_timer_delay_t;
-
-enum grub_efi_allocate_type
-  {
-    GRUB_EFI_ALLOCATE_ANY_PAGES,
-    GRUB_EFI_ALLOCATE_MAX_ADDRESS,
-    GRUB_EFI_ALLOCATE_ADDRESS,
-    GRUB_EFI_MAX_ALLOCATION_TYPE
-  };
-typedef enum grub_efi_allocate_type grub_efi_allocate_type_t;
-
-enum grub_efi_memory_type
-  {
-    GRUB_EFI_RESERVED_MEMORY_TYPE,
-    GRUB_EFI_LOADER_CODE,
-    GRUB_EFI_LOADER_DATA,
-    GRUB_EFI_BOOT_SERVICES_CODE,
-    GRUB_EFI_BOOT_SERVICES_DATA,
-    GRUB_EFI_RUNTIME_SERVICES_CODE,
-    GRUB_EFI_RUNTIME_SERVICES_DATA,
-    GRUB_EFI_CONVENTIONAL_MEMORY,
-    GRUB_EFI_UNUSABLE_MEMORY,
-    GRUB_EFI_ACPI_RECLAIM_MEMORY,
-    GRUB_EFI_ACPI_MEMORY_NVS,
-    GRUB_EFI_MEMORY_MAPPED_IO,
-    GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE,
-    GRUB_EFI_PAL_CODE,
-    GRUB_EFI_MAX_MEMORY_TYPE
-  };
-typedef enum grub_efi_memory_type grub_efi_memory_type_t;
-
-enum grub_efi_interface_type
-  {
-    GRUB_EFI_NATIVE_INTERFACE
-  };
-typedef enum grub_efi_interface_type grub_efi_interface_type_t;
-
-enum grub_efi_locate_search_type
-  {
-    GRUB_EFI_ALL_HANDLES,
-    GRUB_EFI_BY_REGISTER_NOTIFY,
-    GRUB_EFI_BY_PROTOCOL
-  };
-typedef enum grub_efi_locate_search_type grub_efi_locate_search_type_t;
-
-enum grub_efi_reset_type
-  {
-    GRUB_EFI_RESET_COLD,
-    GRUB_EFI_RESET_WARM,
-    GRUB_EFI_RESET_SHUTDOWN
-  };
-typedef enum grub_efi_reset_type grub_efi_reset_type_t;
-
-/* Types.  */
-typedef char grub_efi_boolean_t;
-typedef long grub_efi_intn_t;
-typedef unsigned long grub_efi_uintn_t;
-typedef grub_int8_t grub_efi_int8_t;
-typedef grub_uint8_t grub_efi_uint8_t;
-typedef grub_int16_t grub_efi_int16_t;
-typedef grub_uint16_t grub_efi_uint16_t;
-typedef grub_int32_t grub_efi_int32_t;
-typedef grub_uint32_t grub_efi_uint32_t;
-typedef grub_int64_t grub_efi_int64_t;
-typedef grub_uint64_t grub_efi_uint64_t;
-typedef grub_uint8_t grub_efi_char8_t;
-typedef grub_uint16_t grub_efi_char16_t;
-
-typedef grub_efi_intn_t grub_efi_status_t;
-
-#define GRUB_EFI_ERROR_CODE(value)     \
-  ((1L << (sizeof (grub_efi_status_t) * 8 - 1)) | (value))
-
-#define GRUB_EFI_WARNING_CODE(value)   (value)
-
-#define GRUB_EFI_SUCCESS               0
-
-#define GRUB_EFI_LOAD_ERROR            GRUB_EFI_ERROR_CODE (1)
-#define GRUB_EFI_INVALID_PARAMETER     GRUB_EFI_ERROR_CODE (2)
-#define GRUB_EFI_UNSUPPORTED           GRUB_EFI_ERROR_CODE (3)
-#define GRUB_EFI_BAD_BUFFER_SIZE       GRUB_EFI_ERROR_CODE (4)
-#define GRUB_EFI_BUFFER_TOO_SMALL      GRUB_EFI_ERROR_CODE (5)
-#define GRUB_EFI_NOT_READY             GRUB_EFI_ERROR_CODE (6)
-#define GRUB_EFI_DEVICE_ERROR          GRUB_EFI_ERROR_CODE (7)
-#define GRUB_EFI_WRITE_PROTECTED       GRUB_EFI_ERROR_CODE (8)
-#define GRUB_EFI_OUT_OF_RESOURCES      GRUB_EFI_ERROR_CODE (9)
-#define GRUB_EFI_VOLUME_CORRUPTED      GRUB_EFI_ERROR_CODE (10)
-#define GRUB_EFI_VOLUME_FULL           GRUB_EFI_ERROR_CODE (11)
-#define GRUB_EFI_NO_MEDIA              GRUB_EFI_ERROR_CODE (12)
-#define GRUB_EFI_MEDIA_CHANGED         GRUB_EFI_ERROR_CODE (13)
-#define GRUB_EFI_NOT_FOUND             GRUB_EFI_ERROR_CODE (14)
-#define GRUB_EFI_ACCESS_DENIED         GRUB_EFI_ERROR_CODE (15)
-#define GRUB_EFI_NO_RESPONSE           GRUB_EFI_ERROR_CODE (16)
-#define GRUB_EFI_NO_MAPPING            GRUB_EFI_ERROR_CODE (17)
-#define GRUB_EFI_TIMEOUT               GRUB_EFI_ERROR_CODE (18)
-#define GRUB_EFI_NOT_STARTED           GRUB_EFI_ERROR_CODE (19)
-#define GRUB_EFI_ALREADY_STARTED       GRUB_EFI_ERROR_CODE (20)
-#define GRUB_EFI_ABORTED               GRUB_EFI_ERROR_CODE (21)
-#define GRUB_EFI_ICMP_ERROR            GRUB_EFI_ERROR_CODE (22)
-#define GRUB_EFI_TFTP_ERROR            GRUB_EFI_ERROR_CODE (23)
-#define GRUB_EFI_PROTOCOL_ERROR                GRUB_EFI_ERROR_CODE (24)
-#define GRUB_EFI_INCOMPATIBLE_VERSION  GRUB_EFI_ERROR_CODE (25)
-#define GRUB_EFI_SECURITY_VIOLATION    GRUB_EFI_ERROR_CODE (26)
-#define GRUB_EFI_CRC_ERROR             GRUB_EFI_ERROR_CODE (27)
-
-#define GRUB_EFI_WARN_UNKNOWN_GLYPH    GRUB_EFI_WARNING_CODE (1)
-#define GRUB_EFI_WARN_DELETE_FAILURE   GRUB_EFI_WARNING_CODE (2)
-#define GRUB_EFI_WARN_WRITE_FAILURE    GRUB_EFI_WARNING_CODE (3)
-#define GRUB_EFI_WARN_BUFFER_TOO_SMALL GRUB_EFI_WARNING_CODE (4)
-
-typedef void *grub_efi_handle_t;
-typedef void *grub_efi_event_t;
-typedef grub_efi_uint64_t grub_efi_lba_t;
-typedef grub_efi_uintn_t grub_efi_tpl_t;
-typedef grub_uint8_t grub_efi_mac_address_t[32];
-typedef grub_uint8_t grub_efi_ipv4_address_t[4];
-typedef grub_uint16_t grub_efi_ipv6_address_t[8];
-typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4)));
-typedef grub_efi_uint64_t grub_efi_physical_address_t;
-typedef grub_efi_uint64_t grub_efi_virtual_address_t;
-
-struct grub_efi_guid
-{
-  grub_uint32_t data1;
-  grub_uint16_t data2;
-  grub_uint16_t data3;
-  grub_uint8_t data4[8];
-} __attribute__ ((aligned(8)));
-typedef struct grub_efi_guid grub_efi_guid_t;
-
-/* XXX although the spec does not specify the padding, this actually
-   must have the padding!  */
-struct grub_efi_memory_descriptor
-{
-  grub_efi_uint32_t type;
-  grub_efi_uint32_t padding;
-  grub_efi_physical_address_t physical_start;
-  grub_efi_virtual_address_t virtual_start;
-  grub_efi_uint64_t num_pages;
-  grub_efi_uint64_t attribute;
-};
-typedef struct grub_efi_memory_descriptor grub_efi_memory_descriptor_t;
-
-/* Device Path definitions.  */
-struct grub_efi_device_path
-{
-  grub_efi_uint8_t type;
-  grub_efi_uint8_t subtype;
-  grub_efi_uint8_t length[2];
-};
-typedef struct grub_efi_device_path grub_efi_device_path_t;
-/* XXX EFI does not define EFI_DEVICE_PATH_PROTOCOL but uses it.
-   It seems to be identical to EFI_DEVICE_PATH.  */
-typedef struct grub_efi_device_path grub_efi_device_path_protocol_t;
-
-#define GRUB_EFI_DEVICE_PATH_TYPE(dp)          ((dp)->type & 0x7f)
-#define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp)       ((dp)->subtype)
-#define GRUB_EFI_DEVICE_PATH_LENGTH(dp)                \
-  ((dp)->length[0] | ((grub_efi_uint16_t) ((dp)->length[1]) << 8))
-
-/* The End of Device Path nodes.  */
-#define GRUB_EFI_END_DEVICE_PATH_TYPE                  (0xff & 0x7f)
-
-#define GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE                0xff
-#define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE          0x01
-
-#define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp)    \
-  (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
-   && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
-       == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE))
-
-#define GRUB_EFI_NEXT_DEVICE_PATH(dp)  \
-  ((grub_efi_device_path_t *) ((char *) (dp) \
-                               + GRUB_EFI_DEVICE_PATH_LENGTH (dp)))
-
-/* Hardware Device Path.  */
-#define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE             1
-
-#define GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE               1
-
-struct grub_efi_pci_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint8_t function;
-  grub_efi_uint8_t device;
-};
-typedef struct grub_efi_pci_device_path grub_efi_pci_device_path_t;
-
-#define GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE            2
-
-struct grub_efi_pccard_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint8_t function;
-};
-typedef struct grub_efi_pccard_device_path grub_efi_pccard_device_path_t;
-
-#define GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE     3
-
-struct grub_efi_memory_mapped_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_memory_type_t memory_type;
-  grub_efi_physical_address_t start_address;
-  grub_efi_physical_address_t end_address;
-};
-typedef struct grub_efi_memory_mapped_device_path grub_efi_memory_mapped_device_path_t;
-
-#define GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE            4
-
-struct grub_efi_vendor_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_guid_t vendor_guid;
-  grub_efi_uint8_t vendor_defined_data[0];
-};
-typedef struct grub_efi_vendor_device_path grub_efi_vendor_device_path_t;
-
-#define GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE                5
-
-struct grub_efi_controller_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint32_t controller_number;
-};
-typedef struct grub_efi_controller_device_path grub_efi_controller_device_path_t;
-
-/* ACPI Device Path.  */
-#define GRUB_EFI_ACPI_DEVICE_PATH_TYPE                 2
-
-#define GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE              1
-
-struct grub_efi_acpi_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint32_t hid;
-  grub_efi_uint32_t uid;
-};
-typedef struct grub_efi_acpi_device_path grub_efi_acpi_device_path_t;
-
-#define GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE     2
-
-struct grub_efi_expanded_acpi_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint32_t hid;
-  grub_efi_uint32_t uid;
-  grub_efi_uint32_t cid;
-  char hidstr[1];
-};
-typedef struct grub_efi_expanded_acpi_device_path grub_efi_expanded_acpi_device_path_t;
-
-#define GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp)      \
-  (((grub_efi_expanded_acpi_device_path_t *) dp)->hidstr)
-#define GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp)      \
-  (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \
-   + grub_strlen (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp)) + 1)
-#define GRUB_EFI_EXPANDED_ACPI_CIDSTR(dp)      \
-  (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp) \
-   + grub_strlen (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp)) + 1)
-
-/* Messaging Device Path.  */
-#define GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE            3
-
-#define GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE             1
-
-struct grub_efi_atapi_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint8_t primary_secondary;
-  grub_efi_uint8_t slave_master;
-  grub_efi_uint16_t lun;
-};
-typedef struct grub_efi_atapi_device_path grub_efi_atapi_device_path_t;
-
-#define GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE              2
-
-struct grub_efi_scsi_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint16_t pun;
-  grub_efi_uint16_t lun;
-};
-typedef struct grub_efi_scsi_device_path grub_efi_scsi_device_path_t;
-
-#define GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE     3
-
-struct grub_efi_fibre_channel_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint32_t reserved;
-  grub_efi_uint64_t wwn;
-  grub_efi_uint64_t lun;
-};
-typedef struct grub_efi_fibre_channel_device_path grub_efi_fibre_channel_device_path_t;
-
-#define GRUB_EFI_1394_DEVICE_PATH_SUBTYPE              4
-
-struct grub_efi_1394_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint32_t reserved;
-  grub_efi_uint64_t guid;
-};
-typedef struct grub_efi_1394_device_path grub_efi_1394_device_path_t;
-
-#define GRUB_EFI_USB_DEVICE_PATH_SUBTYPE               5
-
-struct grub_efi_usb_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint8_t parent_port_number;
-  grub_efi_uint8_t interface;
-};
-typedef struct grub_efi_usb_device_path grub_efi_usb_device_path_t;
-
-#define GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE         15
-
-struct grub_efi_usb_class_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint16_t vendor_id;
-  grub_efi_uint16_t product_id;
-  grub_efi_uint8_t device_class;
-  grub_efi_uint8_t device_subclass;
-  grub_efi_uint8_t device_protocol;
-};
-typedef struct grub_efi_usb_class_device_path grub_efi_usb_class_device_path_t;
-
-#define GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE               6
-
-struct grub_efi_i2o_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint32_t tid;
-};
-typedef struct grub_efi_i2o_device_path grub_efi_i2o_device_path_t;
-
-#define GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE       11
-
-struct grub_efi_mac_address_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_mac_address_t mac_address;
-  grub_efi_uint8_t if_type;
-};
-typedef struct grub_efi_mac_address_device_path grub_efi_mac_address_device_path_t;
-
-#define GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE              12
-
-struct grub_efi_ipv4_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_ipv4_address_t local_ip_address;
-  grub_efi_ipv4_address_t remote_ip_address;
-  grub_efi_uint16_t local_port;
-  grub_efi_uint16_t remote_port;
-  grub_efi_uint16_t protocol;
-  grub_efi_uint8_t static_ip_address;
-};
-typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t;
-
-#define GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE              13
-
-struct grub_efi_ipv6_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_ipv6_address_t local_ip_address;
-  grub_efi_ipv6_address_t remote_ip_address;
-  grub_efi_uint16_t local_port;
-  grub_efi_uint16_t remote_port;
-  grub_efi_uint16_t protocol;
-  grub_efi_uint8_t static_ip_address;
-};
-typedef struct grub_efi_ipv6_device_path grub_efi_ipv6_device_path_t;
-
-#define GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE                9
-
-struct grub_efi_infiniband_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint32_t resource_flags;
-  grub_efi_uint8_t port_gid[16];
-  grub_efi_uint64_t remote_id;
-  grub_efi_uint64_t target_port_id;
-  grub_efi_uint64_t device_id;
-};
-typedef struct grub_efi_infiniband_device_path grub_efi_infiniband_device_path_t;
-
-#define GRUB_EFI_UART_DEVICE_PATH_SUBTYPE              14
-
-struct grub_efi_uart_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint32_t reserved;
-  grub_efi_uint64_t baud_rate;
-  grub_efi_uint8_t data_bits;
-  grub_efi_uint8_t parity;
-  grub_efi_uint8_t stop_bits;
-};
-typedef struct grub_efi_uart_device_path grub_efi_uart_device_path_t;
-
-#define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE  10
-
-struct grub_efi_vendor_messaging_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_guid_t vendor_guid;
-  grub_efi_uint8_t vendor_defined_data[0];
-};
-typedef struct grub_efi_vendor_messaging_device_path grub_efi_vendor_messaging_device_path_t;
-
-/* Media Device Path.  */
-#define GRUB_EFI_MEDIA_DEVICE_PATH_TYPE                        4
-
-#define GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE                1
-
-struct grub_efi_hard_drive_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint32_t partition_number;
-  grub_efi_lba_t partition_start;
-  grub_efi_lba_t partition_size;
-  grub_efi_uint8_t partition_signature[8];
-  grub_efi_uint8_t mbr_type;
-  grub_efi_uint8_t signature_type;
-};
-typedef struct grub_efi_hard_drive_device_path grub_efi_hard_drive_device_path_t;
-
-#define GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE             2
-
-struct grub_efi_cdrom_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint32_t boot_entry;
-  grub_efi_lba_t partition_start;
-  grub_efi_lba_t partition_size;
-};
-typedef struct grub_efi_cdrom_device_path grub_efi_cdrom_device_path_t;
-
-#define GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE      3
-
-struct grub_efi_vendor_media_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_guid_t vendor_guid;
-  grub_efi_uint8_t vendor_defined_data[0];
-};
-typedef struct grub_efi_vendor_media_device_path grub_efi_vendor_media_device_path_t;
-
-#define GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE         4
-
-struct grub_efi_file_path_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_char16_t path_name[0];
-};
-typedef struct grub_efi_file_path_device_path grub_efi_file_path_device_path_t;
-
-#define GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE          5
-
-struct grub_efi_protocol_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_guid_t guid;
-};
-typedef struct grub_efi_protocol_device_path grub_efi_protocol_device_path_t;
-
-#define GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE              6
-
-struct grub_efi_piwg_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_guid_t guid __attribute__ ((packed));
-};
-typedef struct grub_efi_piwg_device_path grub_efi_piwg_device_path_t;
-
-
-/* BIOS Boot Specification Device Path.  */
-#define GRUB_EFI_BIOS_DEVICE_PATH_TYPE                 5
-
-#define GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE              1
-
-struct grub_efi_bios_device_path
-{
-  grub_efi_device_path_t header;
-  grub_efi_uint16_t device_type;
-  grub_efi_uint16_t status_flags;
-  char description[0];
-};
-typedef struct grub_efi_bios_device_path grub_efi_bios_device_path_t;
-
-struct grub_efi_open_protocol_information_entry
-{
-  grub_efi_handle_t agent_handle;
-  grub_efi_handle_t controller_handle;
-  grub_efi_uint32_t attributes;
-  grub_efi_uint32_t open_count;
-};
-typedef struct grub_efi_open_protocol_information_entry grub_efi_open_protocol_information_entry_t;
-
-struct grub_efi_time
-{
-  grub_efi_uint16_t year;
-  grub_efi_uint8_t month;
-  grub_efi_uint8_t day;
-  grub_efi_uint8_t hour;
-  grub_efi_uint8_t minute;
-  grub_efi_uint8_t second;
-  grub_efi_uint8_t pad1;
-  grub_efi_uint32_t nanosecond;
-  grub_efi_int16_t time_zone;
-  grub_efi_uint8_t daylight;
-  grub_efi_uint8_t pad2;
-} __attribute__ ((packed));
-typedef struct grub_efi_time grub_efi_time_t;
-
-struct grub_efi_time_capabilities
-{
-  grub_efi_uint32_t resolution;
-  grub_efi_uint32_t accuracy;
-  grub_efi_boolean_t sets_to_zero;
-};
-typedef struct grub_efi_time_capabilities grub_efi_time_capabilities_t;
-
-struct grub_efi_input_key
-{
-  grub_efi_uint16_t scan_code;
-  grub_efi_char16_t unicode_char;
-};
-typedef struct grub_efi_input_key grub_efi_input_key_t;
-
-struct grub_efi_simple_text_output_mode
-{
-  grub_efi_int32_t max_mode;
-  grub_efi_int32_t mode;
-  grub_efi_int32_t attribute;
-  grub_efi_int32_t cursor_column;
-  grub_efi_int32_t cursor_row;
-  grub_efi_boolean_t cursor_visible;
-};
-typedef struct grub_efi_simple_text_output_mode grub_efi_simple_text_output_mode_t;
-
-/* Tables.  */
-struct grub_efi_table_header
-{
-  grub_efi_uint64_t signature;
-  grub_efi_uint32_t revision;
-  grub_efi_uint32_t header_size;
-  grub_efi_uint32_t crc32;
-  grub_efi_uint32_t reserved;
-};
-typedef struct grub_efi_table_header grub_efi_table_header_t;
-
-struct grub_efi_boot_services
-{
-  grub_efi_table_header_t hdr;
-
-  grub_efi_tpl_t
-  (*raise_tpl) (grub_efi_tpl_t new_tpl);
-
-  void
-  (*restore_tpl) (grub_efi_tpl_t old_tpl);
-
-  grub_efi_status_t
-  (*allocate_pages) (grub_efi_allocate_type_t type,
-                    grub_efi_memory_type_t memory_type,
-                    grub_efi_uintn_t pages,
-                    grub_efi_physical_address_t *memory);
-
-  grub_efi_status_t
-  (*free_pages) (grub_efi_physical_address_t memory,
-                grub_efi_uintn_t pages);
-
-  grub_efi_status_t
-  (*get_memory_map) (grub_efi_uintn_t *memory_map_size,
-                    grub_efi_memory_descriptor_t *memory_map,
-                    grub_efi_uintn_t *map_key,
-                    grub_efi_uintn_t *descriptor_size,
-                    grub_efi_uint32_t *descriptor_version);
-
-  grub_efi_status_t
-  (*allocate_pool) (grub_efi_memory_type_t pool_type,
-                   grub_efi_uintn_t size,
-                   void **buffer);
-
-  grub_efi_status_t
-  (*free_pool) (void *buffer);
-
-  grub_efi_status_t
-  (*create_event) (grub_efi_uint32_t type,
-                  grub_efi_tpl_t notify_tpl,
-                  void (*notify_function) (grub_efi_event_t event,
-                                           void *context),
-                  void *notify_context,
-                  grub_efi_event_t *event);
-
-  grub_efi_status_t
-  (*set_timer) (grub_efi_event_t event,
-               grub_efi_timer_delay_t type,
-               grub_efi_uint64_t trigger_time);
-
-   grub_efi_status_t
-   (*wait_for_event) (grub_efi_uintn_t num_events,
-                     grub_efi_event_t *event,
-                     grub_efi_uintn_t *index);
-
-  grub_efi_status_t
-  (*signal_event) (grub_efi_event_t event);
-
-  grub_efi_status_t
-  (*close_event) (grub_efi_event_t event);
-
-  grub_efi_status_t
-  (*check_event) (grub_efi_event_t event);
-
-   grub_efi_status_t
-   (*install_protocol_interface) (grub_efi_handle_t *handle,
-                                 grub_efi_guid_t *protocol,
-                                 grub_efi_interface_type_t interface_type,
-                                 void *interface);
-
-  grub_efi_status_t
-  (*reinstall_protocol_interface) (grub_efi_handle_t handle,
-                                  grub_efi_guid_t *protocol,
-                                  void *old_interface,
-                                  void *new_interface);
-
-  grub_efi_status_t
-  (*uninstall_protocol_interface) (grub_efi_handle_t handle,
-                                  grub_efi_guid_t *protocol,
-                                  void *interface);
-
-  grub_efi_status_t
-  (*handle_protocol) (grub_efi_handle_t handle,
-                     grub_efi_guid_t *protocol,
-                     void **interface);
-
-  void *reserved;
-
-  grub_efi_status_t
-  (*register_protocol_notify) (grub_efi_guid_t *protocol,
-                              grub_efi_event_t event,
-                              void **registration);
-
-  grub_efi_status_t
-  (*locate_handle) (grub_efi_locate_search_type_t search_type,
-                   grub_efi_guid_t *protocol,
-                   void *search_key,
-                   grub_efi_uintn_t *buffer_size,
-                   grub_efi_handle_t *buffer);
-
-  grub_efi_status_t
-  (*locate_device_path) (grub_efi_guid_t *protocol,
-                        grub_efi_device_path_t **device_path,
-                        grub_efi_handle_t *device);
-
-  grub_efi_status_t
-  (*install_configuration_table) (grub_efi_guid_t *guid, void *table);
-
-  grub_efi_status_t
-  (*load_image) (grub_efi_boolean_t boot_policy,
-                grub_efi_handle_t parent_image_handle,
-                grub_efi_device_path_t *file_path,
-                void *source_buffer,
-                grub_efi_uintn_t source_size,
-                grub_efi_handle_t *image_handle);
-
-  grub_efi_status_t
-  (*start_image) (grub_efi_handle_t image_handle,
-                 grub_efi_uintn_t *exit_data_size,
-                 grub_efi_char16_t **exit_data);
-
-  grub_efi_status_t
-  (*exit) (grub_efi_handle_t image_handle,
-          grub_efi_status_t exit_status,
-          grub_efi_uintn_t exit_data_size,
-          grub_efi_char16_t *exit_data) __attribute__((noreturn));
-
-  grub_efi_status_t
-  (*unload_image) (grub_efi_handle_t image_handle);
-
-  grub_efi_status_t
-  (*exit_boot_services) (grub_efi_handle_t image_handle,
-                        grub_efi_uintn_t map_key);
-
-  grub_efi_status_t
-  (*get_next_monotonic_count) (grub_efi_uint64_t *count);
-
-  grub_efi_status_t
-  (*stall) (grub_efi_uintn_t microseconds);
-
-  grub_efi_status_t
-  (*set_watchdog_timer) (grub_efi_uintn_t timeout,
-                        grub_efi_uint64_t watchdog_code,
-                        grub_efi_uintn_t data_size,
-                        grub_efi_char16_t *watchdog_data);
-
-  grub_efi_status_t
-  (*connect_controller) (grub_efi_handle_t controller_handle,
-                        grub_efi_handle_t *driver_image_handle,
-                        grub_efi_device_path_protocol_t *remaining_device_path,
-                        grub_efi_boolean_t recursive);
-
-  grub_efi_status_t
-  (*disconnect_controller) (grub_efi_handle_t controller_handle,
-                           grub_efi_handle_t driver_image_handle,
-                           grub_efi_handle_t child_handle);
-
-  grub_efi_status_t
-  (*open_protocol) (grub_efi_handle_t handle,
-                   grub_efi_guid_t *protocol,
-                   void **interface,
-                   grub_efi_handle_t agent_handle,
-                   grub_efi_handle_t controller_handle,
-                   grub_efi_uint32_t attributes);
-
-  grub_efi_status_t
-  (*close_protocol) (grub_efi_handle_t handle,
-                    grub_efi_guid_t *protocol,
-                    grub_efi_handle_t agent_handle,
-                    grub_efi_handle_t controller_handle);
-
-  grub_efi_status_t
-  (*open_protocol_information) (grub_efi_handle_t handle,
-                               grub_efi_guid_t *protocol,
-                               grub_efi_open_protocol_information_entry_t **entry_buffer,
-                               grub_efi_uintn_t *entry_count);
-
-  grub_efi_status_t
-  (*protocols_per_handle) (grub_efi_handle_t handle,
-                          grub_efi_guid_t ***protocol_buffer,
-                          grub_efi_uintn_t *protocol_buffer_count);
-
-  grub_efi_status_t
-  (*locate_handle_buffer) (grub_efi_locate_search_type_t search_type,
-                          grub_efi_guid_t *protocol,
-                          void *search_key,
-                          grub_efi_uintn_t *no_handles,
-                          grub_efi_handle_t **buffer);
-
-  grub_efi_status_t
-  (*locate_protocol) (grub_efi_guid_t *protocol,
-                     void *registration,
-                     void **interface);
-
-  grub_efi_status_t
-  (*install_multiple_protocol_interfaces) (grub_efi_handle_t *handle, ...);
-
-  grub_efi_status_t
-  (*uninstall_multiple_protocol_interfaces) (grub_efi_handle_t handle, ...);
-
-  grub_efi_status_t
-  (*calculate_crc32) (void *data,
-                     grub_efi_uintn_t data_size,
-                     grub_efi_uint32_t *crc32);
-
-  void
-  (*copy_mem) (void *destination, void *source, grub_efi_uintn_t length);
-
-  void
-  (*set_mem) (void *buffer, grub_efi_uintn_t size, grub_efi_uint8_t value);
-};
-typedef struct grub_efi_boot_services grub_efi_boot_services_t;
-
-struct grub_efi_runtime_services
-{
-  grub_efi_table_header_t hdr;
-
-  grub_efi_status_t
-  (*get_time) (grub_efi_time_t *time,
-              grub_efi_time_capabilities_t *capabilities);
-
-  grub_efi_status_t
-  (*set_time) (grub_efi_time_t *time);
-
-  grub_efi_status_t
-  (*get_wakeup_time) (grub_efi_boolean_t *enabled,
-                     grub_efi_boolean_t *pending,
-                     grub_efi_time_t *time);
-
-  grub_efi_status_t
-  (*set_wakeup_time) (grub_efi_boolean_t enabled,
-                     grub_efi_time_t *time);
-
-  grub_efi_status_t
-  (*set_virtual_address_map) (grub_efi_uintn_t memory_map_size,
-                             grub_efi_uintn_t descriptor_size,
-                             grub_efi_uint32_t descriptor_version,
-                             grub_efi_memory_descriptor_t *virtual_map);
-
-  grub_efi_status_t
-  (*convert_pointer) (grub_efi_uintn_t debug_disposition, void **address);
-
-  grub_efi_status_t
-  (*get_variable) (grub_efi_char16_t *variable_name,
-                  grub_efi_guid_t *vendor_guid,
-                  grub_efi_uint32_t *attributes,
-                  grub_efi_uintn_t *data_size,
-                  void *data);
-
-  grub_efi_status_t
-  (*get_next_variable_name) (grub_efi_uintn_t *variable_name_size,
-                            grub_efi_char16_t *variable_name,
-                            grub_efi_guid_t *vendor_guid);
-
-  grub_efi_status_t
-  (*set_variable) (grub_efi_char16_t *variable_name,
-                  grub_efi_guid_t *vendor_guid,
-                  grub_efi_uint32_t attributes,
-                  grub_efi_uintn_t data_size,
-                  void *data);
-
-  grub_efi_status_t
-  (*get_next_high_monotonic_count) (grub_efi_uint32_t *high_count);
-
-  void
-  (*reset_system) (grub_efi_reset_type_t reset_type,
-                  grub_efi_status_t reset_status,
-                  grub_efi_uintn_t data_size,
-                  grub_efi_char16_t *reset_data);
-};
-typedef struct grub_efi_runtime_services grub_efi_runtime_services_t;
-
-struct grub_efi_configuration_table
-{
-  grub_efi_guid_t vendor_guid;
-  void *vendor_table;
-} __attribute__ ((packed));
-typedef struct grub_efi_configuration_table grub_efi_configuration_table_t;
-
-#define GRUB_EFIEMU_SYSTEM_TABLE_SIGNATURE 0x5453595320494249LL
-#define GRUB_EFIEMU_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552LL
-
-struct grub_efi_simple_input_interface
-{
-  grub_efi_status_t
-  (*reset) (struct grub_efi_simple_input_interface *this,
-           grub_efi_boolean_t extended_verification);
-
-  grub_efi_status_t
-  (*read_key_stroke) (struct grub_efi_simple_input_interface *this,
-                     grub_efi_input_key_t *key);
-
-  grub_efi_event_t wait_for_key;
-};
-typedef struct grub_efi_simple_input_interface grub_efi_simple_input_interface_t;
-
-struct grub_efi_simple_text_output_interface
-{
-  grub_efi_status_t
-  (*reset) (struct grub_efi_simple_text_output_interface *this,
-           grub_efi_boolean_t extended_verification);
-
-  grub_efi_status_t
-  (*output_string) (struct grub_efi_simple_text_output_interface *this,
-                   grub_efi_char16_t *string);
-
-  grub_efi_status_t
-  (*test_string) (struct grub_efi_simple_text_output_interface *this,
-                 grub_efi_char16_t *string);
-
-  grub_efi_status_t
-  (*query_mode) (struct grub_efi_simple_text_output_interface *this,
-                grub_efi_uintn_t mode_number,
-                grub_efi_uintn_t *columns,
-                grub_efi_uintn_t *rows);
-
-  grub_efi_status_t
-  (*set_mode) (struct grub_efi_simple_text_output_interface *this,
-              grub_efi_uintn_t mode_number);
-
-  grub_efi_status_t
-  (*set_attributes) (struct grub_efi_simple_text_output_interface *this,
-                    grub_efi_uintn_t attribute);
-
-  grub_efi_status_t
-  (*clear_screen) (struct grub_efi_simple_text_output_interface *this);
-
-  grub_efi_status_t
-  (*set_cursor_position) (struct grub_efi_simple_text_output_interface *this,
-                         grub_efi_uintn_t column,
-                         grub_efi_uintn_t row);
-
-  grub_efi_status_t
-  (*enable_cursor) (struct grub_efi_simple_text_output_interface *this,
-                   grub_efi_boolean_t visible);
-
-  grub_efi_simple_text_output_mode_t *mode;
-};
-typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t;
-
-#define GRUB_EFI_BLACK         0x00
-#define GRUB_EFI_BLUE          0x01
-#define GRUB_EFI_GREEN         0x02
-#define GRUB_EFI_CYAN          0x03
-#define GRUB_EFI_RED           0x04
-#define GRUB_EFI_MAGENTA       0x05
-#define GRUB_EFI_BROWN         0x06
-#define GRUB_EFI_LIGHTGRAY     0x07
-#define GRUB_EFI_BRIGHT                0x08
-#define GRUB_EFI_DARKGRAY      0x08
-#define GRUB_EFI_LIGHTBLUE     0x09
-#define GRUB_EFI_LIGHTGREEN    0x0A
-#define GRUB_EFI_LIGHTCYAN     0x0B
-#define GRUB_EFI_LIGHTRED      0x0C
-#define GRUB_EFI_LIGHTMAGENTA  0x0D
-#define GRUB_EFI_YELLOW                0x0E
-#define GRUB_EFI_WHITE         0x0F
-
-#define GRUB_EFI_BACKGROUND_BLACK      0x00
-#define GRUB_EFI_BACKGROUND_BLUE       0x10
-#define GRUB_EFI_BACKGROUND_GREEN      0x20
-#define GRUB_EFI_BACKGROUND_CYAN       0x30
-#define GRUB_EFI_BACKGROUND_RED                0x40
-#define GRUB_EFI_BACKGROUND_MAGENTA    0x50
-#define GRUB_EFI_BACKGROUND_BROWN      0x60
-#define GRUB_EFI_BACKGROUND_LIGHTGRAY  0x70
-
-#define GRUB_EFI_TEXT_ATTR(fg, bg)     ((fg) | ((bg)))
-
-struct grub_efi_system_table
-{
-  grub_efi_table_header_t hdr;
-  grub_efi_char16_t *firmware_vendor;
-  grub_efi_uint32_t firmware_revision;
-  grub_efi_handle_t console_in_handler;
-  grub_efi_simple_input_interface_t *con_in;
-  grub_efi_handle_t console_out_handler;
-  grub_efi_simple_text_output_interface_t *con_out;
-  grub_efi_handle_t standard_error_handle;
-  grub_efi_simple_text_output_interface_t *std_err;
-  grub_efi_runtime_services_t *runtime_services;
-  grub_efi_boot_services_t *boot_services;
-  grub_efi_uintn_t num_table_entries;
-  grub_efi_configuration_table_t *configuration_table;
-};
-typedef struct grub_efi_system_table  grub_efi_system_table_t;
-
-struct grub_efi_loaded_image
-{
-  grub_efi_uint32_t revision;
-  grub_efi_handle_t parent_handle;
-  grub_efi_system_table_t *system_table;
-
-  grub_efi_handle_t device_handle;
-  grub_efi_device_path_t *file_path;
-  void *reserved;
-
-  grub_efi_uint32_t load_options_size;
-  void *load_options;
-
-  void *image_base;
-  grub_efi_uint64_t image_size;
-  grub_efi_memory_type_t image_code_type;
-  grub_efi_memory_type_t image_data_type;
-
-  grub_efi_status_t (*unload) (grub_efi_handle_t image_handle);
-};
-typedef struct grub_efi_loaded_image grub_efi_loaded_image_t;
-
-struct grub_efi_disk_io
-{
-  grub_efi_uint64_t revision;
-  grub_efi_status_t (*read) (struct grub_efi_disk_io *this,
-                            grub_efi_uint32_t media_id,
-                            grub_efi_uint64_t offset,
-                            grub_efi_uintn_t buffer_size,
-                            void *buffer);
-  grub_efi_status_t (*write) (struct grub_efi_disk_io *this,
-                            grub_efi_uint32_t media_id,
-                            grub_efi_uint64_t offset,
-                            grub_efi_uintn_t buffer_size,
-                            void *buffer);
-};
-typedef struct grub_efi_disk_io grub_efi_disk_io_t;
-
-struct grub_efi_block_io_media
-{
-  grub_efi_uint32_t media_id;
-  grub_efi_boolean_t removable_media;
-  grub_efi_boolean_t media_present;
-  grub_efi_boolean_t logical_partition;
-  grub_efi_boolean_t read_only;
-  grub_efi_boolean_t write_caching;
-  grub_efi_uint8_t pad[3];
-  grub_efi_uint32_t block_size;
-  grub_efi_uint32_t io_align;
-  grub_efi_uint8_t pad2[4];
-  grub_efi_lba_t last_block;
-};
-typedef struct grub_efi_block_io_media grub_efi_block_io_media_t;
-
-struct grub_efi_block_io
-{
-  grub_efi_uint64_t revision;
-  grub_efi_block_io_media_t *media;
-  grub_efi_status_t (*reset) (struct grub_efi_block_io *this,
-                             grub_efi_boolean_t extended_verification);
-  grub_efi_status_t (*read_blocks) (struct grub_efi_block_io *this,
-                                   grub_efi_uint32_t media_id,
-                                   grub_efi_lba_t lba,
-                                   grub_efi_uintn_t buffer_size,
-                                   void *buffer);
-  grub_efi_status_t (*write_blocks) (struct grub_efi_block_io *this,
-                                    grub_efi_uint32_t media_id,
-                                    grub_efi_lba_t lba,
-                                    grub_efi_uintn_t buffer_size,
-                                    void *buffer);
-  grub_efi_status_t (*flush_blocks) (struct grub_efi_block_io *this);
-};
-typedef struct grub_efi_block_io grub_efi_block_io_t;
-
-#if GRUB_TARGET_SIZEOF_VOID_P == 4
-
-#define efi_call_0(func)               func()
-#define efi_call_1(func, a)            func(a)
-#define efi_call_2(func, a, b)         func(a, b)
-#define efi_call_3(func, a, b, c)      func(a, b, c)
-#define efi_call_4(func, a, b, c, d)   func(a, b, c, d)
-#define efi_call_5(func, a, b, c, d, e)        func(a, b, c, d, e)
-#define efi_call_6(func, a, b, c, d, e, f) func(a, b, c, d, e, f)
-#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j)        func(a, b, c, d, e, f, g, h, i, j)
-
-#else
-
-#define efi_call_0(func) \
-  efi_wrap_0(func)
-#define efi_call_1(func, a) \
-  efi_wrap_1(func, (grub_uint64_t) a)
-#define efi_call_2(func, a, b) \
-  efi_wrap_2(func, (grub_uint64_t) a, (grub_uint64_t) b)
-#define efi_call_3(func, a, b, c) \
-  efi_wrap_3(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c)
-#define efi_call_4(func, a, b, c, d) \
-  efi_wrap_4(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \
-  (grub_uint64_t) d)
-#define efi_call_5(func, a, b, c, d, e)        \
-  efi_wrap_5(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \
-  (grub_uint64_t) d, (grub_uint64_t) e)
-#define efi_call_6(func, a, b, c, d, e, f) \
-  efi_wrap_6(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \
-  (grub_uint64_t) d, (grub_uint64_t) e, (grub_uint64_t) f)
-#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j) \
-  efi_wrap_10(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \
-  (grub_uint64_t) d, (grub_uint64_t) e, (grub_uint64_t) f, (grub_uint64_t) g, \
-  (grub_uint64_t) h, (grub_uint64_t) i, (grub_uint64_t) j)
-
-grub_uint64_t EXPORT_FUNC(efi_wrap_0) (void *func);
-grub_uint64_t EXPORT_FUNC(efi_wrap_1) (void *func, grub_uint64_t arg1);
-grub_uint64_t EXPORT_FUNC(efi_wrap_2) (void *func, grub_uint64_t arg1,
-                                       grub_uint64_t arg2);
-grub_uint64_t EXPORT_FUNC(efi_wrap_3) (void *func, grub_uint64_t arg1,
-                                       grub_uint64_t arg2, grub_uint64_t arg3);
-grub_uint64_t EXPORT_FUNC(efi_wrap_4) (void *func, grub_uint64_t arg1,
-                                       grub_uint64_t arg2, grub_uint64_t arg3,
-                                       grub_uint64_t arg4);
-grub_uint64_t EXPORT_FUNC(efi_wrap_5) (void *func, grub_uint64_t arg1,
-                                       grub_uint64_t arg2, grub_uint64_t arg3,
-                                       grub_uint64_t arg4, grub_uint64_t arg5);
-grub_uint64_t EXPORT_FUNC(efi_wrap_6) (void *func, grub_uint64_t arg1,
-                                       grub_uint64_t arg2, grub_uint64_t arg3,
-                                       grub_uint64_t arg4, grub_uint64_t arg5,
-                                       grub_uint64_t arg6);
-grub_uint64_t EXPORT_FUNC(efi_wrap_10) (void *func, grub_uint64_t arg1,
-                                        grub_uint64_t arg2, grub_uint64_t arg3,
-                                        grub_uint64_t arg4, grub_uint64_t arg5,
-                                        grub_uint64_t arg6, grub_uint64_t arg7,
-                                        grub_uint64_t arg8, grub_uint64_t arg9,
-                                        grub_uint64_t arg10);
-#endif
-
-#endif /* ! GRUB_EFI_API_HEADER */
diff --git a/include/grub/efi/console.h b/include/grub/efi/console.h
deleted file mode 100644 (file)
index f90b5b7..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_EFI_CONSOLE_HEADER
-#define GRUB_EFI_CONSOLE_HEADER        1
-
-#include <grub/types.h>
-#include <grub/symbol.h>
-
-/* Initialize the console system.  */
-void grub_console_init (void);
-
-/* Finish the console system.  */
-void grub_console_fini (void);
-
-#endif /* ! GRUB_EFI_CONSOLE_HEADER */
diff --git a/include/grub/efi/console_control.h b/include/grub/efi/console_control.h
deleted file mode 100644 (file)
index 7c358fc..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* console_control.h - definitions of the console control protocol */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* The console control protocol is not a part of the EFI spec,
-   but defined in Intel's Sample Implementation.  */
-
-#ifndef GRUB_EFI_CONSOLE_CONTROL_HEADER
-#define GRUB_EFI_CONSOLE_CONTROL_HEADER        1
-
-#define GRUB_EFI_CONSOLE_CONTROL_GUID  \
-  { 0xf42f7782, 0x12e, 0x4c12, \
-    { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } \
-  }
-
-enum grub_efi_screen_mode
-  {
-    GRUB_EFI_SCREEN_TEXT,
-    GRUB_EFI_SCREEN_GRAPHICS,
-    GRUB_EFI_SCREEN_TEXT_MAX_VALUE
-  };
-typedef enum grub_efi_screen_mode grub_efi_screen_mode_t;
-
-struct grub_efi_console_control_protocol
-{
-  grub_efi_status_t
-  (*get_mode) (struct grub_efi_console_control_protocol *this,
-              grub_efi_screen_mode_t *mode,
-              grub_efi_boolean_t *uga_exists,
-              grub_efi_boolean_t *std_in_locked);
-
-  grub_efi_status_t
-  (*set_mode) (struct grub_efi_console_control_protocol *this,
-              grub_efi_screen_mode_t mode);
-
-  grub_efi_status_t
-  (*lock_std_in) (struct grub_efi_console_control_protocol *this,
-                 grub_efi_char16_t *password);
-};
-typedef struct grub_efi_console_control_protocol grub_efi_console_control_protocol_t;
-
-#endif /* ! GRUB_EFI_CONSOLE_CONTROL_HEADER */
diff --git a/include/grub/efi/disk.h b/include/grub/efi/disk.h
deleted file mode 100644 (file)
index 254475c..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_EFI_DISK_HEADER
-#define GRUB_EFI_DISK_HEADER   1
-
-#include <grub/efi/api.h>
-#include <grub/symbol.h>
-#include <grub/disk.h>
-
-grub_efi_handle_t
-EXPORT_FUNC(grub_efidisk_get_device_handle) (grub_disk_t disk);
-char *EXPORT_FUNC(grub_efidisk_get_device_name) (grub_efi_handle_t *handle);
-
-void grub_efidisk_init (void);
-void grub_efidisk_fini (void);
-
-#endif /* ! GRUB_EFI_DISK_HEADER */
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
deleted file mode 100644 (file)
index 5852a47..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/* efi.h - declare variables and functions for EFI support */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_EFI_EFI_HEADER
-#define GRUB_EFI_EFI_HEADER    1
-
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/efi/api.h>
-
-/* Functions.  */
-void *EXPORT_FUNC(grub_efi_locate_protocol) (grub_efi_guid_t *protocol,
-                                            void *registration);
-grub_efi_handle_t *
-EXPORT_FUNC(grub_efi_locate_handle) (grub_efi_locate_search_type_t search_type,
-                                    grub_efi_guid_t *protocol,
-                                    void *search_key,
-                                    grub_efi_uintn_t *num_handles);
-void *EXPORT_FUNC(grub_efi_open_protocol) (grub_efi_handle_t handle,
-                                          grub_efi_guid_t *protocol,
-                                          grub_efi_uint32_t attributes);
-int EXPORT_FUNC(grub_efi_set_text_mode) (int on);
-void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds);
-void *
-EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address,
-                                     grub_efi_uintn_t pages);
-void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address,
-                                      grub_efi_uintn_t pages);
-int
-EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size,
-                                     grub_efi_memory_descriptor_t *memory_map,
-                                     grub_efi_uintn_t *map_key,
-                                     grub_efi_uintn_t *descriptor_size,
-                                     grub_efi_uint32_t *descriptor_version);
-grub_efi_loaded_image_t *EXPORT_FUNC(grub_efi_get_loaded_image) (grub_efi_handle_t image_handle);
-void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp);
-char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp);
-grub_efi_device_path_t *
-EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle);
-int EXPORT_FUNC(grub_efi_exit_boot_services) (grub_efi_uintn_t map_key);
-int EXPORT_FUNC (grub_efi_finish_boot_services) (void);
-grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memory_map_size,
-                                                          grub_efi_uintn_t descriptor_size,
-                                                          grub_efi_uint32_t descriptor_version,
-                                                          grub_efi_memory_descriptor_t *virtual_map);
-
-void grub_efi_mm_init (void);
-void grub_efi_mm_fini (void);
-void grub_efi_init (void);
-void grub_efi_fini (void);
-void grub_efi_set_prefix (void);
-
-/* Variables.  */
-extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table);
-extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle);
-
-#endif /* ! GRUB_EFI_EFI_HEADER */
diff --git a/include/grub/efi/graphics_output.h b/include/grub/efi/graphics_output.h
deleted file mode 100644 (file)
index a292219..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_EFI_GOP_HEADER
-#define GRUB_EFI_GOP_HEADER    1
-
-/* Based on UEFI specification.  */
-
-#define GRUB_EFI_GOP_GUID \
-  { 0x9042a9de, 0x23dc, 0x4a38, { 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a }}
-
-typedef enum
-  {
-    GRUB_EFI_GOT_RGBA8,
-    GRUB_EFI_GOT_BGRA8,
-    GRUB_EFI_GOT_BITMASK
-  }
-  grub_efi_gop_pixel_format_t;
-
-struct grub_efi_gop_pixel_bitmask
-{
-  grub_uint32_t r;
-  grub_uint32_t g;
-  grub_uint32_t b;
-  grub_uint32_t a;
-};
-
-struct grub_efi_gop_mode_info
-{
-  grub_efi_uint32_t version;
-  grub_efi_uint32_t width;
-  grub_efi_uint32_t height;
-  grub_efi_gop_pixel_format_t pixel_format;
-  struct grub_efi_gop_pixel_bitmask pixel_bitmask;
-  grub_efi_uint32_t pixels_per_scanline;
-};
-
-struct grub_efi_gop_mode
-{
-  grub_efi_uint32_t max_mode;
-  grub_efi_uint32_t mode;
-  struct grub_efi_gop_mode_info *info;
-  grub_efi_uintn_t info_size;
-  grub_efi_physical_address_t fb_base;
-  grub_efi_uintn_t fb_size;
-};
-
-/* Forward declaration.  */
-struct grub_efi_gop;
-
-typedef grub_efi_status_t
-(*grub_efi_gop_query_mode_t) (struct grub_efi_gop *this,
-                             grub_efi_uint32_t mode_number,
-                             grub_efi_uintn_t *size_of_info,
-                             struct grub_efi_gop_mode_info **info);
-
-typedef grub_efi_status_t
-(*grub_efi_gop_set_mode_t) (struct grub_efi_gop *this,
-                           grub_efi_uint32_t mode_number);
-
-typedef grub_efi_status_t
-(*grub_efi_gop_blt_t) (struct grub_efi_gop *this,
-                      void *buffer,
-                      grub_efi_uintn_t operation,
-                      grub_efi_uintn_t sx,
-                      grub_efi_uintn_t sy,
-                      grub_efi_uintn_t dx,
-                      grub_efi_uintn_t dy,
-                      grub_efi_uintn_t width,
-                      grub_efi_uintn_t height,
-                      grub_efi_uintn_t delta);
-
-struct grub_efi_gop
-{
-  grub_efi_gop_query_mode_t query_mode;
-  grub_efi_gop_set_mode_t set_mode;
-  grub_efi_gop_blt_t blt;
-  struct grub_efi_gop_mode *mode;
-};
-
-#endif
diff --git a/include/grub/efi/memory.h b/include/grub/efi/memory.h
deleted file mode 100644 (file)
index 285be83..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MEMORY_MACHINE_HEADER
-#define GRUB_MEMORY_MACHINE_HEADER     1
-
-#include <grub/err.h>
-#include <grub/types.h>
-
-#define GRUB_MMAP_REGISTER_BY_FIRMWARE  1
-
-#define GRUB_MACHINE_MEMORY_AVAILABLE  1
-#define GRUB_MACHINE_MEMORY_RESERVED   2
-#define GRUB_MACHINE_MEMORY_ACPI       3
-#define GRUB_MACHINE_MEMORY_NVS         4
-#define GRUB_MACHINE_MEMORY_CODE        5
-#define GRUB_MACHINE_MEMORY_MAX_TYPE   5
-  /* This one is special: it's used internally but is never reported
-     by firmware. */
-#define GRUB_MACHINE_MEMORY_HOLE       6
-
-grub_err_t grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
-                                                                   grub_uint64_t,
-                                                                   grub_uint32_t));
-grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t size,
-                                      int type, int handle);
-grub_err_t grub_machine_mmap_unregister (int handle);
-
-grub_uint64_t grub_mmap_get_post64 (void);
-grub_uint64_t grub_mmap_get_upper (void);
-grub_uint64_t grub_mmap_get_lower (void);
-
-#endif /* ! GRUB_MEMORY_MACHINE_HEADER */
diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
deleted file mode 100644 (file)
index 21b56ae..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_EFI_PE32_HEADER
-#define GRUB_EFI_PE32_HEADER   1
-
-#include <grub/types.h>
-
-/* The MSDOS compatibility stub. This was copied from the output of
-   objcopy, and it is not necessary to care about what this means.  */
-#define GRUB_PE32_MSDOS_STUB \
-  { \
-    0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, \
-    0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, \
-    0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
-    0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
-    0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, \
-    0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, \
-    0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, \
-    0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, \
-    0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, \
-    0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, \
-    0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, \
-    0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, \
-    0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  \
-  }
-
-#define GRUB_PE32_MSDOS_STUB_SIZE      0x80
-
-/* According to the spec, the minimal alignment is 512 bytes...
-   But some examples (such as EFI drivers in the Intel
-   Sample Implementation) use 32 bytes (0x20) instead, and it seems
-   to be working. For now, GRUB uses 512 bytes for safety.  */
-#define GRUB_PE32_SECTION_ALIGNMENT    0x200
-#define GRUB_PE32_FILE_ALIGNMENT       GRUB_PE32_SECTION_ALIGNMENT
-
-struct grub_pe32_coff_header
-{
-  grub_uint16_t machine;
-  grub_uint16_t num_sections;
-  grub_uint32_t time;
-  grub_uint32_t symtab_offset;
-  grub_uint32_t num_symbols;
-  grub_uint16_t optional_header_size;
-  grub_uint16_t characteristics;
-};
-
-#define GRUB_PE32_MACHINE_I386         0x14c
-#define GRUB_PE32_MACHINE_X86_64       0x8664
-
-#define GRUB_PE32_RELOCS_STRIPPED              0x0001
-#define GRUB_PE32_EXECUTABLE_IMAGE             0x0002
-#define GRUB_PE32_LINE_NUMS_STRIPPED           0x0004
-#define GRUB_PE32_LOCAL_SYMS_STRIPPED          0x0008
-#define GRUB_PE32_AGGRESSIVE_WS_TRIM           0x0010
-#define GRUB_PE32_LARGE_ADDRESS_AWARE          0x0020
-#define GRUB_PE32_16BIT_MACHINE                        0x0040
-#define GRUB_PE32_BYTES_REVERSED_LO            0x0080
-#define GRUB_PE32_32BIT_MACHINE                        0x0100
-#define GRUB_PE32_DEBUG_STRIPPED               0x0200
-#define GRUB_PE32_REMOVABLE_RUN_FROM_SWAP      0x0400
-#define GRUB_PE32_SYSTEM                       0x1000
-#define GRUB_PE32_DLL                          0x2000
-#define GRUB_PE32_UP_SYSTEM_ONLY               0x4000
-#define GRUB_PE32_BYTES_REVERSED_HI            0x8000
-
-struct grub_pe32_data_directory
-{
-  grub_uint32_t rva;
-  grub_uint32_t size;
-};
-
-struct grub_pe32_optional_header
-{
-  grub_uint16_t magic;
-  grub_uint8_t major_linker_version;
-  grub_uint8_t minor_linker_version;
-  grub_uint32_t code_size;
-  grub_uint32_t data_size;
-  grub_uint32_t bss_size;
-  grub_uint32_t entry_addr;
-  grub_uint32_t code_base;
-
-#if GRUB_TARGET_SIZEOF_VOID_P == 4
-  grub_uint32_t data_base;
-  grub_uint32_t image_base;
-#else
-  grub_uint64_t image_base;
-#endif
-
-  grub_uint32_t section_alignment;
-  grub_uint32_t file_alignment;
-  grub_uint16_t major_os_version;
-  grub_uint16_t minor_os_version;
-  grub_uint16_t major_image_version;
-  grub_uint16_t minor_image_version;
-  grub_uint16_t major_subsystem_version;
-  grub_uint16_t minor_subsystem_version;
-  grub_uint32_t reserved;
-  grub_uint32_t image_size;
-  grub_uint32_t header_size;
-  grub_uint32_t checksum;
-  grub_uint16_t subsystem;
-  grub_uint16_t dll_characteristics;
-
-#if GRUB_TARGET_SIZEOF_VOID_P == 4
-
-  grub_uint32_t stack_reserve_size;
-  grub_uint32_t stack_commit_size;
-  grub_uint32_t heap_reserve_size;
-  grub_uint32_t heap_commit_size;
-
-#else
-
-  grub_uint64_t stack_reserve_size;
-  grub_uint64_t stack_commit_size;
-  grub_uint64_t heap_reserve_size;
-  grub_uint64_t heap_commit_size;
-
-#endif
-
-  grub_uint32_t loader_flags;
-  grub_uint32_t num_data_directories;
-
-  /* Data directories.  */
-  struct grub_pe32_data_directory export_table;
-  struct grub_pe32_data_directory import_table;
-  struct grub_pe32_data_directory resource_table;
-  struct grub_pe32_data_directory exception_table;
-  struct grub_pe32_data_directory certificate_table;
-  struct grub_pe32_data_directory base_relocation_table;
-  struct grub_pe32_data_directory debug;
-  struct grub_pe32_data_directory architecture;
-  struct grub_pe32_data_directory global_ptr;
-  struct grub_pe32_data_directory tls_table;
-  struct grub_pe32_data_directory load_config_table;
-  struct grub_pe32_data_directory bound_import;
-  struct grub_pe32_data_directory iat;
-  struct grub_pe32_data_directory delay_import_descriptor;
-  struct grub_pe32_data_directory com_runtime_header;
-  struct grub_pe32_data_directory reserved_entry;
-};
-
-#if GRUB_TARGET_SIZEOF_VOID_P == 4
-
-#define GRUB_PE32_PE32_MAGIC   0x10b
-
-#else
-
-#define GRUB_PE32_PE32_MAGIC   0x20b
-
-#endif
-
-#define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION    10
-
-#define GRUB_PE32_NUM_DATA_DIRECTORIES 16
-
-struct grub_pe32_section_table
-{
-  char name[8];
-  grub_uint32_t virtual_size;
-  grub_uint32_t virtual_address;
-  grub_uint32_t raw_data_size;
-  grub_uint32_t raw_data_offset;
-  grub_uint32_t relocations_offset;
-  grub_uint32_t line_numbers_offset;
-  grub_uint16_t num_relocations;
-  grub_uint16_t num_line_numbers;
-  grub_uint32_t characteristics;
-};
-
-#define GRUB_PE32_SCN_CNT_CODE                 0x00000020
-#define GRUB_PE32_SCN_CNT_INITIALIZED_DATA     0x00000040
-#define GRUB_PE32_SCN_MEM_DISCARDABLE          0x02000000
-#define GRUB_PE32_SCN_MEM_EXECUTE              0x20000000
-#define GRUB_PE32_SCN_MEM_READ                 0x40000000
-#define GRUB_PE32_SCN_MEM_WRITE                        0x80000000
-
-#define GRUB_PE32_SCN_ALIGN_1BYTES             0x00100000
-#define GRUB_PE32_SCN_ALIGN_2BYTES             0x00200000
-#define GRUB_PE32_SCN_ALIGN_4BYTES             0x00300000
-#define GRUB_PE32_SCN_ALIGN_8BYTES             0x00400000
-#define GRUB_PE32_SCN_ALIGN_16BYTES            0x00500000
-#define GRUB_PE32_SCN_ALIGN_32BYTES            0x00600000
-#define GRUB_PE32_SCN_ALIGN_64BYTES            0x00700000
-
-#define GRUB_PE32_SCN_ALIGN_SHIFT              20
-#define GRUB_PE32_SCN_ALIGN_MASK               7
-
-
-struct grub_pe32_header
-{
-  /* This should be filled in with GRUB_PE32_MSDOS_STUB.  */
-  grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE];
-
-  /* This is always PE\0\0.  */
-  char signature[4];
-
-  /* The COFF file header.  */
-  struct grub_pe32_coff_header coff_header;
-
-  /* The Optional header.  */
-  struct grub_pe32_optional_header optional_header;
-};
-
-struct grub_pe32_fixup_block
-{
-  grub_uint32_t page_rva;
-  grub_uint32_t block_size;
-  grub_uint16_t entries[0];
-};
-
-#define GRUB_PE32_FIXUP_ENTRY(type, offset)    (((type) << 12) | (offset))
-
-#define GRUB_PE32_REL_BASED_ABSOLUTE   0
-#define GRUB_PE32_REL_BASED_HIGH       1
-#define GRUB_PE32_REL_BASED_LOW                2
-#define GRUB_PE32_REL_BASED_HIGHLOW    3
-#define GRUB_PE32_REL_BASED_HIGHADJ    4
-#define GRUB_PE32_REL_BASED_MIPS_JMPADDR 5
-#define GRUB_PE32_REL_BASED_SECTION    6
-#define GRUB_PE32_REL_BASED_REL                7
-#define GRUB_PE32_REL_BASED_IA64_IMM64 9
-#define GRUB_PE32_REL_BASED_DIR64      10
-#define GRUB_PE32_REL_BASED_HIGH3ADJ   11
-
-struct grub_pe32_symbol
-{
-  union
-  {
-    char short_name[8];
-    grub_uint32_t long_name[2];
-  };
-
-  grub_uint32_t value;
-  grub_uint16_t section;
-  grub_uint16_t type;
-  grub_uint8_t storage_class;
-  grub_uint8_t num_aux;
-} __attribute__ ((packed));
-
-#define GRUB_PE32_SYM_CLASS_EXTERNAL   2
-#define GRUB_PE32_SYM_CLASS_STATIC     3
-#define GRUB_PE32_SYM_CLASS_FILE       0x67
-
-#define GRUB_PE32_DT_FUNCTION          0x20
-
-struct grub_pe32_reloc
-{
-  grub_uint32_t offset;
-  grub_uint32_t symtab_index;
-  grub_uint16_t type;
-} __attribute__ ((packed));
-
-#define GRUB_PE32_REL_I386_DIR32       0x6
-#define GRUB_PE32_REL_I386_REL32       0x14
-
-#endif /* ! GRUB_EFI_PE32_HEADER */
diff --git a/include/grub/efi/time.h b/include/grub/efi/time.h
deleted file mode 100644 (file)
index 540f6fc..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_EFI_TIME_HEADER
-#define GRUB_EFI_TIME_HEADER   1
-
-#include <grub/symbol.h>
-
-/* This is destined to overflow when one hour passes by.  */
-#define GRUB_TICKS_PER_SECOND  ((1UL << 31) / 60 / 60 * 2)
-
-/* Return the real time in ticks.  */
-grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
-
-#endif /* ! GRUB_EFI_TIME_HEADER */
diff --git a/include/grub/efi/uga_draw.h b/include/grub/efi/uga_draw.h
deleted file mode 100644 (file)
index 9350430..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/* uga_draw.h - definitions of the uga draw protocol */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* The console control protocol is not a part of the EFI spec,
-   but defined in Intel's Sample Implementation.  */
-
-#ifndef GRUB_EFI_UGA_DRAW_HEADER
-#define GRUB_EFI_UGA_DRAW_HEADER       1
-
-#define GRUB_EFI_UGA_DRAW_GUID \
-  { 0x982c298b, 0xf4fa, 0x41cb, { 0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 }}
-
-enum grub_efi_uga_blt_operation
-{
-  GRUB_EFI_UGA_VIDEO_FILL,
-  GRUB_EFI_UGA_VIDEO_TO_BLT,
-  GRUB_EFI_UGA_BLT_TO_VIDEO,
-  GRUB_EFI_UGA_VIDEO_TO_VIDEO,
-  GRUB_EFI_UGA_GLT_MAX
-};
-
-struct grub_efi_uga_pixel
-{
-  grub_uint8_t Blue;
-  grub_uint8_t Green;
-  grub_uint8_t Red;
-  grub_uint8_t Reserved;
-};
-
-struct grub_efi_uga_draw_protocol
-{
-  grub_efi_status_t
-  (*get_mode) (struct grub_efi_uga_draw_protocol *this,
-              grub_uint32_t *width,
-              grub_uint32_t *height,
-              grub_uint32_t *depth,
-              grub_uint32_t *refresh_rate);
-
-  grub_efi_status_t
-  (*set_mode) (struct grub_efi_uga_draw_protocol *this,
-              grub_uint32_t width,
-              grub_uint32_t height,
-              grub_uint32_t depth,
-              grub_uint32_t refresh_rate);
-
-  grub_efi_status_t
-  (*blt) (struct grub_efi_uga_draw_protocol *this,
-         struct grub_efi_uga_pixel *blt_buffer,
-         enum grub_efi_uga_blt_operation blt_operation,
-         grub_efi_uintn_t src_x,
-         grub_efi_uintn_t src_y,
-         grub_efi_uintn_t dest_x,
-         grub_efi_uintn_t dest_y,
-         grub_efi_uintn_t width,
-         grub_efi_uintn_t height,
-         grub_efi_uintn_t delta);
-};
-typedef struct grub_efi_uga_draw_protocol grub_efi_uga_draw_protocol_t;
-
-#endif /* ! GRUB_EFI_UGA_DRAW_HEADER */
diff --git a/include/grub/efiemu/efiemu.h b/include/grub/efiemu/efiemu.h
deleted file mode 100644 (file)
index 3980d32..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_EFI_EMU_HEADER
-#define GRUB_EFI_EMU_HEADER    1
-
-#include <grub/efi/api.h>
-#include <grub/file.h>
-
-#define GRUB_EFIEMU_PAGESIZE 4096
-
-/* EFI api defined in 32-bit and 64-bit version*/
-struct grub_efi_system_table32
-{
-  grub_efi_table_header_t hdr;
-  grub_efi_uint32_t firmware_vendor;
-  grub_efi_uint32_t firmware_revision;
-  grub_efi_uint32_t console_in_handler;
-  grub_efi_uint32_t con_in;
-  grub_efi_uint32_t console_out_handler;
-  grub_efi_uint32_t con_out;
-  grub_efi_uint32_t standard_error_handle;
-  grub_efi_uint32_t std_err;
-  grub_efi_uint32_t runtime_services;
-  grub_efi_uint32_t boot_services;
-  grub_efi_uint32_t num_table_entries;
-  grub_efi_uint32_t configuration_table;
-} __attribute__ ((packed));
-typedef struct grub_efi_system_table32  grub_efi_system_table32_t;
-
-struct grub_efi_system_table64
-{
-  grub_efi_table_header_t hdr;
-  grub_efi_uint64_t firmware_vendor;
-  grub_efi_uint32_t firmware_revision;
-  grub_efi_uint32_t pad;
-  grub_efi_uint64_t console_in_handler;
-  grub_efi_uint64_t con_in;
-  grub_efi_uint64_t console_out_handler;
-  grub_efi_uint64_t con_out;
-  grub_efi_uint64_t standard_error_handle;
-  grub_efi_uint64_t std_err;
-  grub_efi_uint64_t runtime_services;
-  grub_efi_uint64_t boot_services;
-  grub_efi_uint64_t num_table_entries;
-  grub_efi_uint64_t configuration_table;
-} __attribute__ ((packed));
-typedef struct grub_efi_system_table64  grub_efi_system_table64_t;
-
-struct grub_efiemu_runtime_services32
-{
-  grub_efi_table_header_t hdr;
-  grub_efi_uint32_t get_time;
-  grub_efi_uint32_t set_time;
-  grub_efi_uint32_t get_wakeup_time;
-  grub_efi_uint32_t set_wakeup_time;
-  grub_efi_uint32_t set_virtual_address_map;
-  grub_efi_uint32_t convert_pointer;
-  grub_efi_uint32_t get_variable;
-  grub_efi_uint32_t get_next_variable_name;
-  grub_efi_uint32_t set_variable;
-  grub_efi_uint32_t get_next_high_monotonic_count;
-  grub_efi_uint32_t reset_system;
-} __attribute__ ((packed));
-typedef struct grub_efiemu_runtime_services32 grub_efiemu_runtime_services32_t;
-
-struct grub_efiemu_runtime_services64
-{
-  grub_efi_table_header_t hdr;
-  grub_efi_uint64_t get_time;
-  grub_efi_uint64_t set_time;
-  grub_efi_uint64_t get_wakeup_time;
-  grub_efi_uint64_t set_wakeup_time;
-  grub_efi_uint64_t set_virtual_address_map;
-  grub_efi_uint64_t convert_pointer;
-  grub_efi_uint64_t get_variable;
-  grub_efi_uint64_t get_next_variable_name;
-  grub_efi_uint64_t set_variable;
-  grub_efi_uint64_t get_next_high_monotonic_count;
-  grub_efi_uint64_t reset_system;
-} __attribute__ ((packed));
-typedef struct grub_efiemu_runtime_services64 grub_efiemu_runtime_services64_t;
-
-extern grub_efi_system_table32_t *grub_efiemu_system_table32;
-extern grub_efi_system_table64_t *grub_efiemu_system_table64;
-
-/* Convenience macros to access currently loaded efiemu */
-#define grub_efiemu_system_table ((grub_efiemu_sizeof_uintn_t () == 8) \
-                                 ? (void *) grub_efiemu_system_table64 \
-                                 : (void *) grub_efiemu_system_table32)
-#define GRUB_EFIEMU_SIZEOF_OF_UINTN (grub_efiemu_sizeof_uintn_t ())
-#define GRUB_EFIEMU_SYSTEM_TABLE(x) ((grub_efiemu_sizeof_uintn_t () == 8) \
-                                    ? grub_efiemu_system_table64->x \
-                                    : grub_efiemu_system_table32->x)
-#define GRUB_EFIEMU_SYSTEM_TABLE_SET(x,y) ((grub_efiemu_sizeof_uintn_t () == 8)\
-                                          ? (grub_efiemu_system_table64->x \
-                                             = (y)) \
-                                          : (grub_efiemu_system_table32->x \
-                                             = (y)))
-#define GRUB_EFIEMU_SYSTEM_TABLE_PTR(x) ((grub_efiemu_sizeof_uintn_t () == 8)\
-                                        ? UINT_TO_PTR \
-                                        (grub_efiemu_system_table64->x) \
-                                        : UINT_TO_PTR \
-                                        (grub_efiemu_system_table32->x))
-#define GRUB_EFIEMU_SYSTEM_TABLE_VAR(x) ((grub_efiemu_sizeof_uintn_t () == 8) \
-                                        ? (void *) \
-                                        &(grub_efiemu_system_table64->x) \
-                                        : (void *) \
-                                        &(grub_efiemu_system_table32->x))
-#define GRUB_EFIEMU_SYSTEM_TABLE_SIZEOF(x) \
-  ((grub_efiemu_sizeof_uintn_t () == 8) \
-   ? sizeof(grub_efiemu_system_table64->x)\
-   : sizeof(grub_efiemu_system_table32->x))
-#define GRUB_EFIEMU_SYSTEM_TABLE_SIZEOF_TOTAL ((grub_efiemu_sizeof_uintn_t () == 8) ? sizeof(*grub_efiemu_system_table64):sizeof(*grub_efiemu_system_table32))
-
-/* ELF management definitions and functions */
-
-struct grub_efiemu_segment
-{
-  struct grub_efiemu_segment *next;
-  grub_size_t size;
-  unsigned section;
-  int handle;
-  int ptv_rel_needed;
-  grub_off_t off;
-  void *srcptr;
-};
-typedef struct grub_efiemu_segment *grub_efiemu_segment_t;
-
-struct grub_efiemu_elf_sym
-{
-  int handle;
-  grub_off_t off;
-  unsigned section;
-};
-
-int grub_efiemu_check_header32 (void *ehdr, grub_size_t size);
-int grub_efiemu_check_header64 (void *ehdr, grub_size_t size);
-grub_err_t grub_efiemu_loadcore_init32 (void *core, grub_size_t core_size,
-                                       grub_efiemu_segment_t *segments);
-grub_err_t grub_efiemu_loadcore_init64 (void *core, grub_size_t core_size,
-                                       grub_efiemu_segment_t *segments);
-grub_err_t grub_efiemu_loadcore_load32 (void *core,
-                                       grub_size_t core_size,
-                                       grub_efiemu_segment_t segments);
-grub_err_t grub_efiemu_loadcore_load64 (void *core,
-                                       grub_size_t core_size,
-                                       grub_efiemu_segment_t segments);
-grub_err_t grub_efiemu_loadcore_unload32 (void);
-grub_err_t grub_efiemu_loadcore_unload64 (void);
-grub_err_t grub_efiemu_loadcore_unload(void);
-grub_err_t grub_efiemu_loadcore_init (grub_file_t file);
-grub_err_t grub_efiemu_loadcore_load (void);
-
-/* Configuration tables manipulation. Definitions and functions */
-struct grub_efiemu_configuration_table
-{
-  struct grub_efiemu_configuration_table *next;
-  grub_efi_guid_t guid;
-  void * (*get_table) (void *data);
-  void (*unload) (void *data);
-  void *data;
-};
-struct grub_efiemu_configuration_table32
-{
-  grub_efi_guid_t vendor_guid;
-  grub_efi_uint32_t vendor_table;
-} __attribute__ ((packed));
-typedef struct grub_efiemu_configuration_table32 grub_efiemu_configuration_table32_t;
-struct grub_efiemu_configuration_table64
-{
-  grub_efi_guid_t vendor_guid;
-  grub_efi_uint64_t vendor_table;
-} __attribute__ ((packed));
-typedef struct grub_efiemu_configuration_table64 grub_efiemu_configuration_table64_t;
-grub_err_t grub_efiemu_unregister_configuration_table (grub_efi_guid_t guid);
-grub_err_t
-grub_efiemu_register_configuration_table (grub_efi_guid_t guid,
-                                         void * (*get_table) (void *data),
-                                         void (*unload) (void *data),
-                                         void *data);
-
-/* Memory management functions */
-int grub_efiemu_request_memalign (grub_size_t align, grub_size_t size,
-                                 grub_efi_memory_type_t type);
-void *grub_efiemu_mm_obtain_request (int handle);
-int grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size,
-                               grub_efi_memory_descriptor_t *memory_map,
-                               grub_efi_uintn_t *map_key,
-                               grub_efi_uintn_t *descriptor_size,
-                               grub_efi_uint32_t *descriptor_version);
-grub_err_t grub_efiemu_mm_unload (void);
-grub_err_t grub_efiemu_mm_do_alloc (void);
-grub_err_t grub_efiemu_mm_init (void);
-void *grub_efiemu_mm_obtain_request (int handle);
-void grub_efiemu_mm_return_request (int handle);
-grub_efi_memory_type_t grub_efiemu_mm_get_type (int handle);
-
-/* Drop-in replacements for grub_efi_* and grub_machine_* */
-int grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size,
-                               grub_efi_memory_descriptor_t *memory_map,
-                               grub_efi_uintn_t *map_key,
-                               grub_efi_uintn_t *descriptor_size,
-                               grub_efi_uint32_t *descriptor_version);
-grub_err_t
-grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
-                                                       grub_uint64_t,
-                                                       grub_uint32_t));
-int grub_efiemu_sizeof_uintn_t (void);
-int grub_efiemu_exit_boot_services (grub_efi_uintn_t map_key);
-int grub_efiemu_finish_boot_services (void);
-grub_err_t
-grub_efiemu_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper);
-#define GRUB_EFIEMU_MEMORY_AVAILABLE   1
-#define GRUB_EFIEMU_MEMORY_RESERVED    2
-#define GRUB_EFIEMU_MEMORY_ACPI        3
-#define GRUB_EFIEMU_MEMORY_NVS         4
-#define GRUB_EFIEMU_MEMORY_CODE         5
-
-/* efiemu main control definitions and functions*/
-typedef enum {GRUB_EFIEMU_NOTLOADED,
-             GRUB_EFIEMU32, GRUB_EFIEMU64} grub_efiemu_mode_t;
-struct grub_efiemu_prepare_hook
-{
-  struct grub_efiemu_prepare_hook *next;
-  grub_err_t (*hook) (void *data);
-  void (*unload) (void *data);
-  void *data;
-};
-grub_err_t grub_efiemu_prepare32 (struct grub_efiemu_prepare_hook
-                                 *prepare_hooks,
-                                 struct grub_efiemu_configuration_table
-                                 *config_tables);
-grub_err_t grub_efiemu_prepare64 (struct grub_efiemu_prepare_hook
-                                 *prepare_hooks,
-                                 struct grub_efiemu_configuration_table
-                                 *config_tables);
-grub_err_t grub_efiemu_unload (void);
-grub_err_t grub_efiemu_prepare (void);
-grub_err_t
-grub_efiemu_register_prepare_hook (grub_err_t (*hook) (void *data),
-                                  void (*unload) (void *data),
-                                  void *data);
-
-/* symbols and pointers */
-grub_err_t grub_efiemu_alloc_syms (void);
-grub_err_t grub_efiemu_request_symbols (int num);
-grub_err_t grub_efiemu_resolve_symbol (const char *name,
-                                      int *handle, grub_off_t *off);
-grub_err_t grub_efiemu_register_symbol (const char *name,
-                                       int handle, grub_off_t off);
-void grub_efiemu_free_syms (void);
-grub_err_t grub_efiemu_write_value (void * addr, grub_uint32_t value,
-                                   int plus_handle,
-                                   int minus_handle, int ptv_needed, int size);
-grub_err_t grub_efiemu_write_sym_markers (void);
-grub_err_t grub_efiemu_pnvram (void);
-grub_err_t grub_efiemu_prepare (void);
-char *grub_efiemu_get_default_core_name (void);
-void grub_efiemu_pnvram_cmd_unregister (void);
-grub_err_t grub_efiemu_autocore (void);
-grub_err_t grub_efiemu_crc32 (void);
-grub_err_t grub_efiemu_crc64 (void);
-grub_err_t
-grub_efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
-                                    grub_efi_uintn_t descriptor_size,
-                                    grub_efi_uint32_t descriptor_version
-                                    __attribute__ ((unused)),
-                                    grub_efi_memory_descriptor_t *virtual_map);
-
-#endif /* ! GRUB_EFI_EMU_HEADER */
diff --git a/include/grub/efiemu/runtime.h b/include/grub/efiemu/runtime.h
deleted file mode 100644 (file)
index 1eb474a..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_EFI_EMU_RUNTIME_HEADER
-#define GRUB_EFI_EMU_RUNTIME_HEADER    1
-
-struct grub_efiemu_ptv_rel
-{
-  grub_uint64_t addr;
-  grub_efi_memory_type_t plustype;
-  grub_efi_memory_type_t minustype;
-  grub_uint32_t size;
-} __attribute__ ((packed));
-
-struct efi_variable
-{
-  grub_efi_guid_t guid;
-  grub_uint32_t namelen;
-  grub_uint32_t size;
-  grub_efi_uint32_t attributes;
-} __attribute__ ((packed));
-#endif /* ! GRUB_EFI_EMU_RUNTIME_HEADER */
diff --git a/include/grub/elf.h b/include/grub/elf.h
deleted file mode 100644 (file)
index e54989c..0000000
+++ /dev/null
@@ -1,2377 +0,0 @@
-/* This file defines standard ELF types, structures, and macros.
-   Copyright (C) 1995-1999,2000,2001,2002,2008,2009 Free Software Foundation, Inc.
-   This file was part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#ifndef GRUB_ELF_H
-#define        GRUB_ELF_H 1
-
-/* Standard ELF types.  */
-
-#include <grub/types.h>
-
-/* Type for a 16-bit quantity.  */
-typedef grub_uint16_t Elf32_Half;
-typedef grub_uint16_t Elf64_Half;
-
-/* Types for signed and unsigned 32-bit quantities.  */
-typedef grub_uint32_t Elf32_Word;
-typedef        grub_int32_t  Elf32_Sword;
-typedef grub_uint32_t Elf64_Word;
-typedef        grub_int32_t  Elf64_Sword;
-
-/* Types for signed and unsigned 64-bit quantities.  */
-typedef grub_uint64_t Elf32_Xword;
-typedef        grub_int64_t  Elf32_Sxword;
-typedef grub_uint64_t Elf64_Xword;
-typedef        grub_int64_t  Elf64_Sxword;
-
-/* Type of addresses.  */
-typedef grub_uint32_t Elf32_Addr;
-typedef grub_uint64_t Elf64_Addr;
-
-/* Type of file offsets.  */
-typedef grub_uint32_t Elf32_Off;
-typedef grub_uint64_t Elf64_Off;
-
-/* Type for section indices, which are 16-bit quantities.  */
-typedef grub_uint16_t Elf32_Section;
-typedef grub_uint16_t Elf64_Section;
-
-/* Type for version symbol information.  */
-typedef Elf32_Half Elf32_Versym;
-typedef Elf64_Half Elf64_Versym;
-
-
-/* The ELF file header.  This appears at the start of every ELF file.  */
-
-#define EI_NIDENT (16)
-
-typedef struct
-{
-  unsigned char        e_ident[EI_NIDENT];     /* Magic number and other info */
-  Elf32_Half   e_type;                 /* Object file type */
-  Elf32_Half   e_machine;              /* Architecture */
-  Elf32_Word   e_version;              /* Object file version */
-  Elf32_Addr   e_entry;                /* Entry point virtual address */
-  Elf32_Off    e_phoff;                /* Program header table file offset */
-  Elf32_Off    e_shoff;                /* Section header table file offset */
-  Elf32_Word   e_flags;                /* Processor-specific flags */
-  Elf32_Half   e_ehsize;               /* ELF header size in bytes */
-  Elf32_Half   e_phentsize;            /* Program header table entry size */
-  Elf32_Half   e_phnum;                /* Program header table entry count */
-  Elf32_Half   e_shentsize;            /* Section header table entry size */
-  Elf32_Half   e_shnum;                /* Section header table entry count */
-  Elf32_Half   e_shstrndx;             /* Section header string table index */
-} Elf32_Ehdr;
-
-typedef struct
-{
-  unsigned char        e_ident[EI_NIDENT];     /* Magic number and other info */
-  Elf64_Half   e_type;                 /* Object file type */
-  Elf64_Half   e_machine;              /* Architecture */
-  Elf64_Word   e_version;              /* Object file version */
-  Elf64_Addr   e_entry;                /* Entry point virtual address */
-  Elf64_Off    e_phoff;                /* Program header table file offset */
-  Elf64_Off    e_shoff;                /* Section header table file offset */
-  Elf64_Word   e_flags;                /* Processor-specific flags */
-  Elf64_Half   e_ehsize;               /* ELF header size in bytes */
-  Elf64_Half   e_phentsize;            /* Program header table entry size */
-  Elf64_Half   e_phnum;                /* Program header table entry count */
-  Elf64_Half   e_shentsize;            /* Section header table entry size */
-  Elf64_Half   e_shnum;                /* Section header table entry count */
-  Elf64_Half   e_shstrndx;             /* Section header string table index */
-} Elf64_Ehdr;
-
-/* Fields in the e_ident array.  The EI_* macros are indices into the
-   array.  The macros under each EI_* macro are the values the byte
-   may have.  */
-
-#define EI_MAG0                0               /* File identification byte 0 index */
-#define ELFMAG0                0x7f            /* Magic number byte 0 */
-
-#define EI_MAG1                1               /* File identification byte 1 index */
-#define ELFMAG1                'E'             /* Magic number byte 1 */
-
-#define EI_MAG2                2               /* File identification byte 2 index */
-#define ELFMAG2                'L'             /* Magic number byte 2 */
-
-#define EI_MAG3                3               /* File identification byte 3 index */
-#define ELFMAG3                'F'             /* Magic number byte 3 */
-
-/* Conglomeration of the identification bytes, for easy testing as a word.  */
-#define        ELFMAG          "\177ELF"
-#define        SELFMAG         4
-
-#define EI_CLASS       4               /* File class byte index */
-#define ELFCLASSNONE   0               /* Invalid class */
-#define ELFCLASS32     1               /* 32-bit objects */
-#define ELFCLASS64     2               /* 64-bit objects */
-#define ELFCLASSNUM    3
-
-#define EI_DATA                5               /* Data encoding byte index */
-#define ELFDATANONE    0               /* Invalid data encoding */
-#define ELFDATA2LSB    1               /* 2's complement, little endian */
-#define ELFDATA2MSB    2               /* 2's complement, big endian */
-#define ELFDATANUM     3
-
-#define EI_VERSION     6               /* File version byte index */
-                                       /* Value must be EV_CURRENT */
-
-#define EI_OSABI       7               /* OS ABI identification */
-#define ELFOSABI_NONE          0       /* UNIX System V ABI */
-#define ELFOSABI_SYSV          0       /* Alias.  */
-#define ELFOSABI_HPUX          1       /* HP-UX */
-#define ELFOSABI_NETBSD                2       /* NetBSD.  */
-#define ELFOSABI_LINUX         3       /* Linux.  */
-#define ELFOSABI_SOLARIS       6       /* Sun Solaris.  */
-#define ELFOSABI_AIX           7       /* IBM AIX.  */
-#define ELFOSABI_IRIX          8       /* SGI Irix.  */
-#define ELFOSABI_FREEBSD       9       /* FreeBSD.  */
-#define ELFOSABI_TRU64         10      /* Compaq TRU64 UNIX.  */
-#define ELFOSABI_MODESTO       11      /* Novell Modesto.  */
-#define ELFOSABI_OPENBSD       12      /* OpenBSD.  */
-#define ELFOSABI_ARM           97      /* ARM */
-#define ELFOSABI_STANDALONE    255     /* Standalone (embedded) application */
-
-#define EI_ABIVERSION  8               /* ABI version */
-
-#define EI_PAD         9               /* Byte index of padding bytes */
-
-/* Legal values for e_type (object file type).  */
-
-#define ET_NONE                0               /* No file type */
-#define ET_REL         1               /* Relocatable file */
-#define ET_EXEC                2               /* Executable file */
-#define ET_DYN         3               /* Shared object file */
-#define ET_CORE                4               /* Core file */
-#define        ET_NUM          5               /* Number of defined types */
-#define ET_LOOS                0xfe00          /* OS-specific range start */
-#define ET_HIOS                0xfeff          /* OS-specific range end */
-#define ET_LOPROC      0xff00          /* Processor-specific range start */
-#define ET_HIPROC      0xffff          /* Processor-specific range end */
-
-/* Legal values for e_machine (architecture).  */
-
-#define EM_NONE                 0              /* No machine */
-#define EM_M32          1              /* AT&T WE 32100 */
-#define EM_SPARC        2              /* SUN SPARC */
-#define EM_386          3              /* Intel 80386 */
-#define EM_68K          4              /* Motorola m68k family */
-#define EM_88K          5              /* Motorola m88k family */
-#define EM_860          7              /* Intel 80860 */
-#define EM_MIPS                 8              /* MIPS R3000 big-endian */
-#define EM_S370                 9              /* IBM System/370 */
-#define EM_MIPS_RS3_LE 10              /* MIPS R3000 little-endian */
-
-#define EM_PARISC      15              /* HPPA */
-#define EM_VPP500      17              /* Fujitsu VPP500 */
-#define EM_SPARC32PLUS 18              /* Sun's "v8plus" */
-#define EM_960         19              /* Intel 80960 */
-#define EM_PPC         20              /* PowerPC */
-#define EM_PPC64       21              /* PowerPC 64-bit */
-#define EM_S390                22              /* IBM S390 */
-
-#define EM_V800                36              /* NEC V800 series */
-#define EM_FR20                37              /* Fujitsu FR20 */
-#define EM_RH32                38              /* TRW RH-32 */
-#define EM_RCE         39              /* Motorola RCE */
-#define EM_ARM         40              /* ARM */
-#define EM_FAKE_ALPHA  41              /* Digital Alpha */
-#define EM_SH          42              /* Hitachi SH */
-#define EM_SPARCV9     43              /* SPARC v9 64-bit */
-#define EM_TRICORE     44              /* Siemens Tricore */
-#define EM_ARC         45              /* Argonaut RISC Core */
-#define EM_H8_300      46              /* Hitachi H8/300 */
-#define EM_H8_300H     47              /* Hitachi H8/300H */
-#define EM_H8S         48              /* Hitachi H8S */
-#define EM_H8_500      49              /* Hitachi H8/500 */
-#define EM_IA_64       50              /* Intel Merced */
-#define EM_MIPS_X      51              /* Stanford MIPS-X */
-#define EM_COLDFIRE    52              /* Motorola Coldfire */
-#define EM_68HC12      53              /* Motorola M68HC12 */
-#define EM_MMA         54              /* Fujitsu MMA Multimedia Accelerator*/
-#define EM_PCP         55              /* Siemens PCP */
-#define EM_NCPU                56              /* Sony nCPU embedded RISC */
-#define EM_NDR1                57              /* Denso NDR1 microprocessor */
-#define EM_STARCORE    58              /* Motorola Start*Core processor */
-#define EM_ME16                59              /* Toyota ME16 processor */
-#define EM_ST100       60              /* STMicroelectronics ST100 processor */
-#define EM_TINYJ       61              /* Advanced Logic Corp. Tinyj emb.fam*/
-#define EM_X86_64      62              /* AMD x86-64 architecture */
-#define EM_PDSP                63              /* Sony DSP Processor */
-
-#define EM_FX66                66              /* Siemens FX66 microcontroller */
-#define EM_ST9PLUS     67              /* STMicroelectronics ST9+ 8/16 mc */
-#define EM_ST7         68              /* STMicroelectronics ST7 8 bit mc */
-#define EM_68HC16      69              /* Motorola MC68HC16 microcontroller */
-#define EM_68HC11      70              /* Motorola MC68HC11 microcontroller */
-#define EM_68HC08      71              /* Motorola MC68HC08 microcontroller */
-#define EM_68HC05      72              /* Motorola MC68HC05 microcontroller */
-#define EM_SVX         73              /* Silicon Graphics SVx */
-#define EM_AT19                74              /* STMicroelectronics ST19 8 bit mc */
-#define EM_VAX         75              /* Digital VAX */
-#define EM_CRIS                76              /* Axis Communications 32-bit embedded processor */
-#define EM_JAVELIN     77              /* Infineon Technologies 32-bit embedded processor */
-#define EM_FIREPATH    78              /* Element 14 64-bit DSP Processor */
-#define EM_ZSP         79              /* LSI Logic 16-bit DSP Processor */
-#define EM_MMIX                80              /* Donald Knuth's educational 64-bit processor */
-#define EM_HUANY       81              /* Harvard University machine-independent object files */
-#define EM_PRISM       82              /* SiTera Prism */
-#define EM_AVR         83              /* Atmel AVR 8-bit microcontroller */
-#define EM_FR30                84              /* Fujitsu FR30 */
-#define EM_D10V                85              /* Mitsubishi D10V */
-#define EM_D30V                86              /* Mitsubishi D30V */
-#define EM_V850                87              /* NEC v850 */
-#define EM_M32R                88              /* Mitsubishi M32R */
-#define EM_MN10300     89              /* Matsushita MN10300 */
-#define EM_MN10200     90              /* Matsushita MN10200 */
-#define EM_PJ          91              /* picoJava */
-#define EM_OPENRISC    92              /* OpenRISC 32-bit embedded processor */
-#define EM_ARC_A5      93              /* ARC Cores Tangent-A5 */
-#define EM_XTENSA      94              /* Tensilica Xtensa Architecture */
-#define EM_NUM         95
-
-/* If it is necessary to assign new unofficial EM_* values, please
-   pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
-   chances of collision with official or non-GNU unofficial values.  */
-
-#define EM_ALPHA       0x9026
-
-/* Legal values for e_version (version).  */
-
-#define EV_NONE                0               /* Invalid ELF version */
-#define EV_CURRENT     1               /* Current version */
-#define EV_NUM         2
-
-/* Section header.  */
-
-typedef struct
-{
-  Elf32_Word   sh_name;                /* Section name (string tbl index) */
-  Elf32_Word   sh_type;                /* Section type */
-  Elf32_Word   sh_flags;               /* Section flags */
-  Elf32_Addr   sh_addr;                /* Section virtual addr at execution */
-  Elf32_Off    sh_offset;              /* Section file offset */
-  Elf32_Word   sh_size;                /* Section size in bytes */
-  Elf32_Word   sh_link;                /* Link to another section */
-  Elf32_Word   sh_info;                /* Additional section information */
-  Elf32_Word   sh_addralign;           /* Section alignment */
-  Elf32_Word   sh_entsize;             /* Entry size if section holds table */
-} Elf32_Shdr;
-
-typedef struct
-{
-  Elf64_Word   sh_name;                /* Section name (string tbl index) */
-  Elf64_Word   sh_type;                /* Section type */
-  Elf64_Xword  sh_flags;               /* Section flags */
-  Elf64_Addr   sh_addr;                /* Section virtual addr at execution */
-  Elf64_Off    sh_offset;              /* Section file offset */
-  Elf64_Xword  sh_size;                /* Section size in bytes */
-  Elf64_Word   sh_link;                /* Link to another section */
-  Elf64_Word   sh_info;                /* Additional section information */
-  Elf64_Xword  sh_addralign;           /* Section alignment */
-  Elf64_Xword  sh_entsize;             /* Entry size if section holds table */
-} Elf64_Shdr;
-
-/* Special section indices.  */
-
-#define SHN_UNDEF      0               /* Undefined section */
-#define SHN_LORESERVE  0xff00          /* Start of reserved indices */
-#define SHN_LOPROC     0xff00          /* Start of processor-specific */
-#define SHN_HIPROC     0xff1f          /* End of processor-specific */
-#define SHN_LOOS       0xff20          /* Start of OS-specific */
-#define SHN_HIOS       0xff3f          /* End of OS-specific */
-#define SHN_ABS                0xfff1          /* Associated symbol is absolute */
-#define SHN_COMMON     0xfff2          /* Associated symbol is common */
-#define SHN_XINDEX     0xffff          /* Index is in extra table.  */
-#define SHN_HIRESERVE  0xffff          /* End of reserved indices */
-
-/* Legal values for sh_type (section type).  */
-
-#define SHT_NULL         0             /* Section header table entry unused */
-#define SHT_PROGBITS     1             /* Program data */
-#define SHT_SYMTAB       2             /* Symbol table */
-#define SHT_STRTAB       3             /* String table */
-#define SHT_RELA         4             /* Relocation entries with addends */
-#define SHT_HASH         5             /* Symbol hash table */
-#define SHT_DYNAMIC      6             /* Dynamic linking information */
-#define SHT_NOTE         7             /* Notes */
-#define SHT_NOBITS       8             /* Program space with no data (bss) */
-#define SHT_REL                  9             /* Relocation entries, no addends */
-#define SHT_SHLIB        10            /* Reserved */
-#define SHT_DYNSYM       11            /* Dynamic linker symbol table */
-#define SHT_INIT_ARRAY   14            /* Array of constructors */
-#define SHT_FINI_ARRAY   15            /* Array of destructors */
-#define SHT_PREINIT_ARRAY 16           /* Array of pre-constructors */
-#define SHT_GROUP        17            /* Section group */
-#define SHT_SYMTAB_SHNDX  18           /* Extended section indices */
-#define        SHT_NUM           19            /* Number of defined types.  */
-#define SHT_LOOS         0x60000000    /* Start OS-specific */
-#define SHT_GNU_LIBLIST          0x6ffffff7    /* Prelink library list */
-#define SHT_CHECKSUM     0x6ffffff8    /* Checksum for DSO content.  */
-#define SHT_LOSUNW       0x6ffffffa    /* Sun-specific low bound.  */
-#define SHT_SUNW_move    0x6ffffffa
-#define SHT_SUNW_COMDAT   0x6ffffffb
-#define SHT_SUNW_syminfo  0x6ffffffc
-#define SHT_GNU_verdef   0x6ffffffd    /* Version definition section.  */
-#define SHT_GNU_verneed          0x6ffffffe    /* Version needs section.  */
-#define SHT_GNU_versym   0x6fffffff    /* Version symbol table.  */
-#define SHT_HISUNW       0x6fffffff    /* Sun-specific high bound.  */
-#define SHT_HIOS         0x6fffffff    /* End OS-specific type */
-#define SHT_LOPROC       0x70000000    /* Start of processor-specific */
-#define SHT_HIPROC       0x7fffffff    /* End of processor-specific */
-#define SHT_LOUSER       0x80000000    /* Start of application-specific */
-#define SHT_HIUSER       0x8fffffff    /* End of application-specific */
-
-/* Legal values for sh_flags (section flags).  */
-
-#define SHF_WRITE           (1 << 0)   /* Writable */
-#define SHF_ALLOC           (1 << 1)   /* Occupies memory during execution */
-#define SHF_EXECINSTR       (1 << 2)   /* Executable */
-#define SHF_MERGE           (1 << 4)   /* Might be merged */
-#define SHF_STRINGS         (1 << 5)   /* Contains nul-terminated strings */
-#define SHF_INFO_LINK       (1 << 6)   /* `sh_info' contains SHT index */
-#define SHF_LINK_ORDER      (1 << 7)   /* Preserve order after combining */
-#define SHF_OS_NONCONFORMING (1 << 8)  /* Non-standard OS specific handling
-                                          required */
-#define SHF_GROUP           (1 << 9)   /* Section is member of a group.  */
-#define SHF_TLS                     (1 << 10)  /* Section hold thread-local data.  */
-#define SHF_MASKOS          0x0ff00000 /* OS-specific.  */
-#define SHF_MASKPROC        0xf0000000 /* Processor-specific */
-
-/* Section group handling.  */
-#define GRP_COMDAT     0x1             /* Mark group as COMDAT.  */
-
-/* Symbol table entry.  */
-
-typedef struct
-{
-  Elf32_Word   st_name;                /* Symbol name (string tbl index) */
-  Elf32_Addr   st_value;               /* Symbol value */
-  Elf32_Word   st_size;                /* Symbol size */
-  unsigned char        st_info;                /* Symbol type and binding */
-  unsigned char        st_other;               /* Symbol visibility */
-  Elf32_Section        st_shndx;               /* Section index */
-} Elf32_Sym;
-
-typedef struct
-{
-  Elf64_Word   st_name;                /* Symbol name (string tbl index) */
-  unsigned char        st_info;                /* Symbol type and binding */
-  unsigned char st_other;              /* Symbol visibility */
-  Elf64_Section        st_shndx;               /* Section index */
-  Elf64_Addr   st_value;               /* Symbol value */
-  Elf64_Xword  st_size;                /* Symbol size */
-} Elf64_Sym;
-
-/* The syminfo section if available contains additional information about
-   every dynamic symbol.  */
-
-typedef struct
-{
-  Elf32_Half si_boundto;               /* Direct bindings, symbol bound to */
-  Elf32_Half si_flags;                 /* Per symbol flags */
-} Elf32_Syminfo;
-
-typedef struct
-{
-  Elf64_Half si_boundto;               /* Direct bindings, symbol bound to */
-  Elf64_Half si_flags;                 /* Per symbol flags */
-} Elf64_Syminfo;
-
-/* Possible values for si_boundto.  */
-#define SYMINFO_BT_SELF                0xffff  /* Symbol bound to self */
-#define SYMINFO_BT_PARENT      0xfffe  /* Symbol bound to parent */
-#define SYMINFO_BT_LOWRESERVE  0xff00  /* Beginning of reserved entries */
-
-/* Possible bitmasks for si_flags.  */
-#define SYMINFO_FLG_DIRECT     0x0001  /* Direct bound symbol */
-#define SYMINFO_FLG_PASSTHRU   0x0002  /* Pass-thru symbol for translator */
-#define SYMINFO_FLG_COPY       0x0004  /* Symbol is a copy-reloc */
-#define SYMINFO_FLG_LAZYLOAD   0x0008  /* Symbol bound to object to be lazy
-                                          loaded */
-/* Syminfo version values.  */
-#define SYMINFO_NONE           0
-#define SYMINFO_CURRENT                1
-#define SYMINFO_NUM            2
-
-
-/* How to extract and insert information held in the st_info field.  */
-
-#define ELF32_ST_BIND(val)             (((unsigned char) (val)) >> 4)
-#define ELF32_ST_TYPE(val)             ((val) & 0xf)
-#define ELF32_ST_INFO(bind, type)      (((bind) << 4) + ((type) & 0xf))
-
-/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
-#define ELF64_ST_BIND(val)             ELF32_ST_BIND (val)
-#define ELF64_ST_TYPE(val)             ELF32_ST_TYPE (val)
-#define ELF64_ST_INFO(bind, type)      ELF32_ST_INFO ((bind), (type))
-
-/* Legal values for ST_BIND subfield of st_info (symbol binding).  */
-
-#define STB_LOCAL      0               /* Local symbol */
-#define STB_GLOBAL     1               /* Global symbol */
-#define STB_WEAK       2               /* Weak symbol */
-#define        STB_NUM         3               /* Number of defined types.  */
-#define STB_LOOS       10              /* Start of OS-specific */
-#define STB_HIOS       12              /* End of OS-specific */
-#define STB_LOPROC     13              /* Start of processor-specific */
-#define STB_HIPROC     15              /* End of processor-specific */
-
-/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
-
-#define STT_NOTYPE     0               /* Symbol type is unspecified */
-#define STT_OBJECT     1               /* Symbol is a data object */
-#define STT_FUNC       2               /* Symbol is a code object */
-#define STT_SECTION    3               /* Symbol associated with a section */
-#define STT_FILE       4               /* Symbol's name is file name */
-#define STT_COMMON     5               /* Symbol is a common data object */
-#define STT_TLS                6               /* Symbol is thread-local data object*/
-#define        STT_NUM         7               /* Number of defined types.  */
-#define STT_LOOS       10              /* Start of OS-specific */
-#define STT_HIOS       12              /* End of OS-specific */
-#define STT_LOPROC     13              /* Start of processor-specific */
-#define STT_HIPROC     15              /* End of processor-specific */
-
-
-/* Symbol table indices are found in the hash buckets and chain table
-   of a symbol hash table section.  This special index value indicates
-   the end of a chain, meaning no further symbols are found in that bucket.  */
-
-#define STN_UNDEF      0               /* End of a chain.  */
-#define STN_ABS                65521
-
-
-/* How to extract and insert information held in the st_other field.  */
-
-#define ELF32_ST_VISIBILITY(o) ((o) & 0x03)
-
-/* For ELF64 the definitions are the same.  */
-#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o)
-
-/* Symbol visibility specification encoded in the st_other field.  */
-#define STV_DEFAULT    0               /* Default symbol visibility rules */
-#define STV_INTERNAL   1               /* Processor specific hidden class */
-#define STV_HIDDEN     2               /* Sym unavailable in other modules */
-#define STV_PROTECTED  3               /* Not preemptible, not exported */
-
-
-/* Relocation table entry without addend (in section of type SHT_REL).  */
-
-typedef struct
-{
-  Elf32_Addr   r_offset;               /* Address */
-  Elf32_Word   r_info;                 /* Relocation type and symbol index */
-} Elf32_Rel;
-
-/* I have seen two different definitions of the Elf64_Rel and
-   Elf64_Rela structures, so we'll leave them out until Novell (or
-   whoever) gets their act together.  */
-/* The following, at least, is used on Sparc v9, MIPS, and Alpha.  */
-
-typedef struct
-{
-  Elf64_Addr   r_offset;               /* Address */
-  Elf64_Xword  r_info;                 /* Relocation type and symbol index */
-} Elf64_Rel;
-
-/* Relocation table entry with addend (in section of type SHT_RELA).  */
-
-typedef struct
-{
-  Elf32_Addr   r_offset;               /* Address */
-  Elf32_Word   r_info;                 /* Relocation type and symbol index */
-  Elf32_Sword  r_addend;               /* Addend */
-} Elf32_Rela;
-
-typedef struct
-{
-  Elf64_Addr   r_offset;               /* Address */
-  Elf64_Xword  r_info;                 /* Relocation type and symbol index */
-  Elf64_Sxword r_addend;               /* Addend */
-} Elf64_Rela;
-
-/* How to extract and insert information held in the r_info field.  */
-
-#define ELF32_R_SYM(val)               ((val) >> 8)
-#define ELF32_R_TYPE(val)              ((val) & 0xff)
-#define ELF32_R_INFO(sym, type)                (((sym) << 8) + ((type) & 0xff))
-
-#define ELF64_R_SYM(i)                 ((i) >> 32)
-#define ELF64_R_TYPE(i)                        ((i) & 0xffffffff)
-#define ELF64_R_INFO(sym,type)         ((((Elf64_Xword) (sym)) << 32) + (type))
-
-/* Program segment header.  */
-
-typedef struct
-{
-  Elf32_Word   p_type;                 /* Segment type */
-  Elf32_Off    p_offset;               /* Segment file offset */
-  Elf32_Addr   p_vaddr;                /* Segment virtual address */
-  Elf32_Addr   p_paddr;                /* Segment physical address */
-  Elf32_Word   p_filesz;               /* Segment size in file */
-  Elf32_Word   p_memsz;                /* Segment size in memory */
-  Elf32_Word   p_flags;                /* Segment flags */
-  Elf32_Word   p_align;                /* Segment alignment */
-} Elf32_Phdr;
-
-typedef struct
-{
-  Elf64_Word   p_type;                 /* Segment type */
-  Elf64_Word   p_flags;                /* Segment flags */
-  Elf64_Off    p_offset;               /* Segment file offset */
-  Elf64_Addr   p_vaddr;                /* Segment virtual address */
-  Elf64_Addr   p_paddr;                /* Segment physical address */
-  Elf64_Xword  p_filesz;               /* Segment size in file */
-  Elf64_Xword  p_memsz;                /* Segment size in memory */
-  Elf64_Xword  p_align;                /* Segment alignment */
-} Elf64_Phdr;
-
-/* Legal values for p_type (segment type).  */
-
-#define        PT_NULL         0               /* Program header table entry unused */
-#define PT_LOAD                1               /* Loadable program segment */
-#define PT_DYNAMIC     2               /* Dynamic linking information */
-#define PT_INTERP      3               /* Program interpreter */
-#define PT_NOTE                4               /* Auxiliary information */
-#define PT_SHLIB       5               /* Reserved */
-#define PT_PHDR                6               /* Entry for header table itself */
-#define PT_TLS         7               /* Thread-local storage segment */
-#define        PT_NUM          8               /* Number of defined types */
-#define PT_LOOS                0x60000000      /* Start of OS-specific */
-#define PT_GNU_EH_FRAME        0x6474e550      /* GCC .eh_frame_hdr segment */
-#define PT_LOSUNW      0x6ffffffa
-#define PT_SUNWBSS     0x6ffffffa      /* Sun Specific segment */
-#define PT_SUNWSTACK   0x6ffffffb      /* Stack segment */
-#define PT_HISUNW      0x6fffffff
-#define PT_HIOS                0x6fffffff      /* End of OS-specific */
-#define PT_LOPROC      0x70000000      /* Start of processor-specific */
-#define PT_HIPROC      0x7fffffff      /* End of processor-specific */
-
-/* Legal values for p_flags (segment flags).  */
-
-#define PF_X           (1 << 0)        /* Segment is executable */
-#define PF_W           (1 << 1)        /* Segment is writable */
-#define PF_R           (1 << 2)        /* Segment is readable */
-#define PF_MASKOS      0x0ff00000      /* OS-specific */
-#define PF_MASKPROC    0xf0000000      /* Processor-specific */
-
-/* Legal values for note segment descriptor types for core files. */
-
-#define NT_PRSTATUS    1               /* Contains copy of prstatus struct */
-#define NT_FPREGSET    2               /* Contains copy of fpregset struct */
-#define NT_PRPSINFO    3               /* Contains copy of prpsinfo struct */
-#define NT_PRXREG      4               /* Contains copy of prxregset struct */
-#define NT_PLATFORM    5               /* String from sysinfo(SI_PLATFORM) */
-#define NT_AUXV                6               /* Contains copy of auxv array */
-#define NT_GWINDOWS    7               /* Contains copy of gwindows struct */
-#define NT_ASRS                8               /* Contains copy of asrset struct */
-#define NT_PSTATUS     10              /* Contains copy of pstatus struct */
-#define NT_PSINFO      13              /* Contains copy of psinfo struct */
-#define NT_PRCRED      14              /* Contains copy of prcred struct */
-#define NT_UTSNAME     15              /* Contains copy of utsname struct */
-#define NT_LWPSTATUS   16              /* Contains copy of lwpstatus struct */
-#define NT_LWPSINFO    17              /* Contains copy of lwpinfo struct */
-#define NT_PRFPXREG    20              /* Contains copy of fprxregset struct*/
-
-/* Legal values for the note segment descriptor types for object files.  */
-
-#define NT_VERSION     1               /* Contains a version string.  */
-
-
-/* Dynamic section entry.  */
-
-typedef struct
-{
-  Elf32_Sword  d_tag;                  /* Dynamic entry type */
-  union
-    {
-      Elf32_Word d_val;                        /* Integer value */
-      Elf32_Addr d_ptr;                        /* Address value */
-    } d_un;
-} Elf32_Dyn;
-
-typedef struct
-{
-  Elf64_Sxword d_tag;                  /* Dynamic entry type */
-  union
-    {
-      Elf64_Xword d_val;               /* Integer value */
-      Elf64_Addr d_ptr;                        /* Address value */
-    } d_un;
-} Elf64_Dyn;
-
-/* Legal values for d_tag (dynamic entry type).  */
-
-#define DT_NULL                0               /* Marks end of dynamic section */
-#define DT_NEEDED      1               /* Name of needed library */
-#define DT_PLTRELSZ    2               /* Size in bytes of PLT relocs */
-#define DT_PLTGOT      3               /* Processor defined value */
-#define DT_HASH                4               /* Address of symbol hash table */
-#define DT_STRTAB      5               /* Address of string table */
-#define DT_SYMTAB      6               /* Address of symbol table */
-#define DT_RELA                7               /* Address of Rela relocs */
-#define DT_RELASZ      8               /* Total size of Rela relocs */
-#define DT_RELAENT     9               /* Size of one Rela reloc */
-#define DT_STRSZ       10              /* Size of string table */
-#define DT_SYMENT      11              /* Size of one symbol table entry */
-#define DT_INIT                12              /* Address of init function */
-#define DT_FINI                13              /* Address of termination function */
-#define DT_SONAME      14              /* Name of shared object */
-#define DT_RPATH       15              /* Library search path (deprecated) */
-#define DT_SYMBOLIC    16              /* Start symbol search here */
-#define DT_REL         17              /* Address of Rel relocs */
-#define DT_RELSZ       18              /* Total size of Rel relocs */
-#define DT_RELENT      19              /* Size of one Rel reloc */
-#define DT_PLTREL      20              /* Type of reloc in PLT */
-#define DT_DEBUG       21              /* For debugging; unspecified */
-#define DT_TEXTREL     22              /* Reloc might modify .text */
-#define DT_JMPREL      23              /* Address of PLT relocs */
-#define        DT_BIND_NOW     24              /* Process relocations of object */
-#define        DT_INIT_ARRAY   25              /* Array with addresses of init fct */
-#define        DT_FINI_ARRAY   26              /* Array with addresses of fini fct */
-#define        DT_INIT_ARRAYSZ 27              /* Size in bytes of DT_INIT_ARRAY */
-#define        DT_FINI_ARRAYSZ 28              /* Size in bytes of DT_FINI_ARRAY */
-#define DT_RUNPATH     29              /* Library search path */
-#define DT_FLAGS       30              /* Flags for the object being loaded */
-#define DT_ENCODING    32              /* Start of encoded range */
-#define DT_PREINIT_ARRAY 32            /* Array with addresses of preinit fct*/
-#define DT_PREINIT_ARRAYSZ 33          /* size in bytes of DT_PREINIT_ARRAY */
-#define        DT_NUM          34              /* Number used */
-#define DT_LOOS                0x6000000d      /* Start of OS-specific */
-#define DT_HIOS                0x6ffff000      /* End of OS-specific */
-#define DT_LOPROC      0x70000000      /* Start of processor-specific */
-#define DT_HIPROC      0x7fffffff      /* End of processor-specific */
-#define        DT_PROCNUM      DT_MIPS_NUM     /* Most used by any processor */
-
-/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
-   Dyn.d_un.d_val field of the Elf*_Dyn structure.  This follows Sun's
-   approach.  */
-#define DT_VALRNGLO    0x6ffffd00
-#define DT_GNU_PRELINKED 0x6ffffdf5    /* Prelinking timestamp */
-#define DT_GNU_CONFLICTSZ 0x6ffffdf6   /* Size of conflict section */
-#define DT_GNU_LIBLISTSZ 0x6ffffdf7    /* Size of library list */
-#define DT_CHECKSUM    0x6ffffdf8
-#define DT_PLTPADSZ    0x6ffffdf9
-#define DT_MOVEENT     0x6ffffdfa
-#define DT_MOVESZ      0x6ffffdfb
-#define DT_FEATURE_1   0x6ffffdfc      /* Feature selection (DTF_*).  */
-#define DT_POSFLAG_1   0x6ffffdfd      /* Flags for DT_* entries, effecting
-                                          the following DT_* entry.  */
-#define DT_SYMINSZ     0x6ffffdfe      /* Size of syminfo table (in bytes) */
-#define DT_SYMINENT    0x6ffffdff      /* Entry size of syminfo */
-#define DT_VALRNGHI    0x6ffffdff
-#define DT_VALTAGIDX(tag)      (DT_VALRNGHI - (tag))   /* Reverse order! */
-#define DT_VALNUM 12
-
-/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
-   Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
-
-   If any adjustment is made to the ELF object after it has been
-   built these entries will need to be adjusted.  */
-#define DT_ADDRRNGLO   0x6ffffe00
-#define DT_GNU_CONFLICT        0x6ffffef8      /* Start of conflict section */
-#define DT_GNU_LIBLIST 0x6ffffef9      /* Library list */
-#define DT_CONFIG      0x6ffffefa      /* Configuration information.  */
-#define DT_DEPAUDIT    0x6ffffefb      /* Dependency auditing.  */
-#define DT_AUDIT       0x6ffffefc      /* Object auditing.  */
-#define        DT_PLTPAD       0x6ffffefd      /* PLT padding.  */
-#define        DT_MOVETAB      0x6ffffefe      /* Move table.  */
-#define DT_SYMINFO     0x6ffffeff      /* Syminfo table.  */
-#define DT_ADDRRNGHI   0x6ffffeff
-#define DT_ADDRTAGIDX(tag)     (DT_ADDRRNGHI - (tag))  /* Reverse order! */
-#define DT_ADDRNUM 10
-
-/* The versioning entry types.  The next are defined as part of the
-   GNU extension.  */
-#define DT_VERSYM      0x6ffffff0
-
-#define DT_RELACOUNT   0x6ffffff9
-#define DT_RELCOUNT    0x6ffffffa
-
-/* These were chosen by Sun.  */
-#define DT_FLAGS_1     0x6ffffffb      /* State flags, see DF_1_* below.  */
-#define        DT_VERDEF       0x6ffffffc      /* Address of version definition
-                                          table */
-#define        DT_VERDEFNUM    0x6ffffffd      /* Number of version definitions */
-#define        DT_VERNEED      0x6ffffffe      /* Address of table with needed
-                                          versions */
-#define        DT_VERNEEDNUM   0x6fffffff      /* Number of needed versions */
-#define DT_VERSIONTAGIDX(tag)  (DT_VERNEEDNUM - (tag)) /* Reverse order! */
-#define DT_VERSIONTAGNUM 16
-
-/* Sun added these machine-independent extensions in the "processor-specific"
-   range.  Be compatible.  */
-#define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
-#define DT_FILTER       0x7fffffff      /* Shared object to get values from */
-#define DT_EXTRATAGIDX(tag)    ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
-#define DT_EXTRANUM    3
-
-/* Values of `d_un.d_val' in the DT_FLAGS entry.  */
-#define DF_ORIGIN      0x00000001      /* Object may use DF_ORIGIN */
-#define DF_SYMBOLIC    0x00000002      /* Symbol resolutions starts here */
-#define DF_TEXTREL     0x00000004      /* Object contains text relocations */
-#define DF_BIND_NOW    0x00000008      /* No lazy binding for this object */
-#define DF_STATIC_TLS  0x00000010      /* Module uses the static TLS model */
-
-/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
-   entry in the dynamic section.  */
-#define DF_1_NOW       0x00000001      /* Set RTLD_NOW for this object.  */
-#define DF_1_GLOBAL    0x00000002      /* Set RTLD_GLOBAL for this object.  */
-#define DF_1_GROUP     0x00000004      /* Set RTLD_GROUP for this object.  */
-#define DF_1_NODELETE  0x00000008      /* Set RTLD_NODELETE for this object.*/
-#define DF_1_LOADFLTR  0x00000010      /* Trigger filtee loading at runtime.*/
-#define DF_1_INITFIRST 0x00000020      /* Set RTLD_INITFIRST for this object*/
-#define DF_1_NOOPEN    0x00000040      /* Set RTLD_NOOPEN for this object.  */
-#define DF_1_ORIGIN    0x00000080      /* $ORIGIN must be handled.  */
-#define DF_1_DIRECT    0x00000100      /* Direct binding enabled.  */
-#define DF_1_TRANS     0x00000200
-#define DF_1_INTERPOSE 0x00000400      /* Object is used to interpose.  */
-#define DF_1_NODEFLIB  0x00000800      /* Ignore default lib search path.  */
-#define DF_1_NODUMP    0x00001000      /* Object can't be dldump'ed.  */
-#define DF_1_CONFALT   0x00002000      /* Configuration alternative created.*/
-#define DF_1_ENDFILTEE 0x00004000      /* Filtee terminates filters search. */
-#define        DF_1_DISPRELDNE 0x00008000      /* Disp reloc applied at build time. */
-#define        DF_1_DISPRELPND 0x00010000      /* Disp reloc applied at run-time.  */
-
-/* Flags for the feature selection in DT_FEATURE_1.  */
-#define DTF_1_PARINIT  0x00000001
-#define DTF_1_CONFEXP  0x00000002
-
-/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry.  */
-#define DF_P1_LAZYLOAD 0x00000001      /* Lazyload following object.  */
-#define DF_P1_GROUPPERM        0x00000002      /* Symbols from next object are not
-                                          generally available.  */
-
-/* Version definition sections.  */
-
-typedef struct
-{
-  Elf32_Half   vd_version;             /* Version revision */
-  Elf32_Half   vd_flags;               /* Version information */
-  Elf32_Half   vd_ndx;                 /* Version Index */
-  Elf32_Half   vd_cnt;                 /* Number of associated aux entries */
-  Elf32_Word   vd_hash;                /* Version name hash value */
-  Elf32_Word   vd_aux;                 /* Offset in bytes to verdaux array */
-  Elf32_Word   vd_next;                /* Offset in bytes to next verdef
-                                          entry */
-} Elf32_Verdef;
-
-typedef struct
-{
-  Elf64_Half   vd_version;             /* Version revision */
-  Elf64_Half   vd_flags;               /* Version information */
-  Elf64_Half   vd_ndx;                 /* Version Index */
-  Elf64_Half   vd_cnt;                 /* Number of associated aux entries */
-  Elf64_Word   vd_hash;                /* Version name hash value */
-  Elf64_Word   vd_aux;                 /* Offset in bytes to verdaux array */
-  Elf64_Word   vd_next;                /* Offset in bytes to next verdef
-                                          entry */
-} Elf64_Verdef;
-
-
-/* Legal values for vd_version (version revision).  */
-#define VER_DEF_NONE   0               /* No version */
-#define VER_DEF_CURRENT        1               /* Current version */
-#define VER_DEF_NUM    2               /* Given version number */
-
-/* Legal values for vd_flags (version information flags).  */
-#define VER_FLG_BASE   0x1             /* Version definition of file itself */
-#define VER_FLG_WEAK   0x2             /* Weak version identifier */
-
-/* Versym symbol index values.  */
-#define        VER_NDX_LOCAL           0       /* Symbol is local.  */
-#define        VER_NDX_GLOBAL          1       /* Symbol is global.  */
-#define        VER_NDX_LORESERVE       0xff00  /* Beginning of reserved entries.  */
-#define        VER_NDX_ELIMINATE       0xff01  /* Symbol is to be eliminated.  */
-
-/* Auxiliary version information.  */
-
-typedef struct
-{
-  Elf32_Word   vda_name;               /* Version or dependency names */
-  Elf32_Word   vda_next;               /* Offset in bytes to next verdaux
-                                          entry */
-} Elf32_Verdaux;
-
-typedef struct
-{
-  Elf64_Word   vda_name;               /* Version or dependency names */
-  Elf64_Word   vda_next;               /* Offset in bytes to next verdaux
-                                          entry */
-} Elf64_Verdaux;
-
-
-/* Version dependency section.  */
-
-typedef struct
-{
-  Elf32_Half   vn_version;             /* Version of structure */
-  Elf32_Half   vn_cnt;                 /* Number of associated aux entries */
-  Elf32_Word   vn_file;                /* Offset of filename for this
-                                          dependency */
-  Elf32_Word   vn_aux;                 /* Offset in bytes to vernaux array */
-  Elf32_Word   vn_next;                /* Offset in bytes to next verneed
-                                          entry */
-} Elf32_Verneed;
-
-typedef struct
-{
-  Elf64_Half   vn_version;             /* Version of structure */
-  Elf64_Half   vn_cnt;                 /* Number of associated aux entries */
-  Elf64_Word   vn_file;                /* Offset of filename for this
-                                          dependency */
-  Elf64_Word   vn_aux;                 /* Offset in bytes to vernaux array */
-  Elf64_Word   vn_next;                /* Offset in bytes to next verneed
-                                          entry */
-} Elf64_Verneed;
-
-
-/* Legal values for vn_version (version revision).  */
-#define VER_NEED_NONE   0              /* No version */
-#define VER_NEED_CURRENT 1             /* Current version */
-#define VER_NEED_NUM    2              /* Given version number */
-
-/* Auxiliary needed version information.  */
-
-typedef struct
-{
-  Elf32_Word   vna_hash;               /* Hash value of dependency name */
-  Elf32_Half   vna_flags;              /* Dependency specific information */
-  Elf32_Half   vna_other;              /* Unused */
-  Elf32_Word   vna_name;               /* Dependency name string offset */
-  Elf32_Word   vna_next;               /* Offset in bytes to next vernaux
-                                          entry */
-} Elf32_Vernaux;
-
-typedef struct
-{
-  Elf64_Word   vna_hash;               /* Hash value of dependency name */
-  Elf64_Half   vna_flags;              /* Dependency specific information */
-  Elf64_Half   vna_other;              /* Unused */
-  Elf64_Word   vna_name;               /* Dependency name string offset */
-  Elf64_Word   vna_next;               /* Offset in bytes to next vernaux
-                                          entry */
-} Elf64_Vernaux;
-
-
-/* Legal values for vna_flags.  */
-#define VER_FLG_WEAK   0x2             /* Weak version identifier */
-
-
-/* Auxiliary vector.  */
-
-/* This vector is normally only used by the program interpreter.  The
-   usual definition in an ABI supplement uses the name auxv_t.  The
-   vector is not usually defined in a standard <elf.h> file, but it
-   can't hurt.  We rename it to avoid conflicts.  The sizes of these
-   types are an arrangement between the exec server and the program
-   interpreter, so we don't fully specify them here.  */
-
-typedef struct
-{
-  int a_type;                  /* Entry type */
-  union
-    {
-      long int a_val;          /* Integer value */
-      void *a_ptr;             /* Pointer value */
-      void (*a_fcn) (void);    /* Function pointer value */
-    } a_un;
-} Elf32_auxv_t;
-
-typedef struct
-{
-  long int a_type;             /* Entry type */
-  union
-    {
-      long int a_val;          /* Integer value */
-      void *a_ptr;             /* Pointer value */
-      void (*a_fcn) (void);    /* Function pointer value */
-    } a_un;
-} Elf64_auxv_t;
-
-/* Legal values for a_type (entry type).  */
-
-#define AT_NULL                0               /* End of vector */
-#define AT_IGNORE      1               /* Entry should be ignored */
-#define AT_EXECFD      2               /* File descriptor of program */
-#define AT_PHDR                3               /* Program headers for program */
-#define AT_PHENT       4               /* Size of program header entry */
-#define AT_PHNUM       5               /* Number of program headers */
-#define AT_PAGESZ      6               /* System page size */
-#define AT_BASE                7               /* Base address of interpreter */
-#define AT_FLAGS       8               /* Flags */
-#define AT_ENTRY       9               /* Entry point of program */
-#define AT_NOTELF      10              /* Program is not ELF */
-#define AT_UID         11              /* Real uid */
-#define AT_EUID                12              /* Effective uid */
-#define AT_GID         13              /* Real gid */
-#define AT_EGID                14              /* Effective gid */
-#define AT_CLKTCK      17              /* Frequency of times() */
-
-/* Some more special a_type values describing the hardware.  */
-#define AT_PLATFORM    15              /* String identifying platform.  */
-#define AT_HWCAP       16              /* Machine dependent hints about
-                                          processor capabilities.  */
-
-/* This entry gives some information about the FPU initialization
-   performed by the kernel.  */
-#define AT_FPUCW       18              /* Used FPU control word.  */
-
-/* Cache block sizes.  */
-#define AT_DCACHEBSIZE 19              /* Data cache block size.  */
-#define AT_ICACHEBSIZE 20              /* Instruction cache block size.  */
-#define AT_UCACHEBSIZE 21              /* Unified cache block size.  */
-
-/* A special ignored value for PPC, used by the kernel to control the
-   interpretation of the AUXV. Must be > 16.  */
-#define AT_IGNOREPPC   22              /* Entry should be ignored */
-
-
-/* Note section contents.  Each entry in the note section begins with
-   a header of a fixed form.  */
-
-typedef struct
-{
-  Elf32_Word n_namesz;                 /* Length of the note's name.  */
-  Elf32_Word n_descsz;                 /* Length of the note's descriptor.  */
-  Elf32_Word n_type;                   /* Type of the note.  */
-} Elf32_Nhdr;
-
-typedef struct
-{
-  Elf64_Word n_namesz;                 /* Length of the note's name.  */
-  Elf64_Word n_descsz;                 /* Length of the note's descriptor.  */
-  Elf64_Word n_type;                   /* Type of the note.  */
-} Elf64_Nhdr;
-
-/* Known names of notes.  */
-
-/* Solaris entries in the note section have this name.  */
-#define ELF_NOTE_SOLARIS       "SUNW Solaris"
-
-/* Note entries for GNU systems have this name.  */
-#define ELF_NOTE_GNU           "GNU"
-
-
-/* Defined types of notes for Solaris.  */
-
-/* Value of descriptor (one word) is desired pagesize for the binary.  */
-#define ELF_NOTE_PAGESIZE_HINT 1
-
-
-/* Defined note types for GNU systems.  */
-
-/* ABI information.  The descriptor consists of words:
-   word 0: OS descriptor
-   word 1: major version of the ABI
-   word 2: minor version of the ABI
-   word 3: subminor version of the ABI
-*/
-#define ELF_NOTE_ABI           1
-
-/* Known OSes.  These value can appear in word 0 of an ELF_NOTE_ABI
-   note section entry.  */
-#define ELF_NOTE_OS_LINUX      0
-#define ELF_NOTE_OS_GNU                1
-#define ELF_NOTE_OS_SOLARIS2   2
-
-
-/* Move records.  */
-typedef struct
-{
-  Elf32_Xword m_value;         /* Symbol value.  */
-  Elf32_Word m_info;           /* Size and index.  */
-  Elf32_Word m_poffset;                /* Symbol offset.  */
-  Elf32_Half m_repeat;         /* Repeat count.  */
-  Elf32_Half m_stride;         /* Stride info.  */
-} Elf32_Move;
-
-typedef struct
-{
-  Elf64_Xword m_value;         /* Symbol value.  */
-  Elf64_Xword m_info;          /* Size and index.  */
-  Elf64_Xword m_poffset;       /* Symbol offset.  */
-  Elf64_Half m_repeat;         /* Repeat count.  */
-  Elf64_Half m_stride;         /* Stride info.  */
-} Elf64_Move;
-
-/* Macro to construct move records.  */
-#define ELF32_M_SYM(info)      ((info) >> 8)
-#define ELF32_M_SIZE(info)     ((unsigned char) (info))
-#define ELF32_M_INFO(sym, size)        (((sym) << 8) + (unsigned char) (size))
-
-#define ELF64_M_SYM(info)      ELF32_M_SYM (info)
-#define ELF64_M_SIZE(info)     ELF32_M_SIZE (info)
-#define ELF64_M_INFO(sym, size)        ELF32_M_INFO (sym, size)
-
-
-/* Motorola 68k specific definitions.  */
-
-/* Values for Elf32_Ehdr.e_flags.  */
-#define EF_CPU32       0x00810000
-
-/* m68k relocs.  */
-
-#define R_68K_NONE     0               /* No reloc */
-#define R_68K_32       1               /* Direct 32 bit  */
-#define R_68K_16       2               /* Direct 16 bit  */
-#define R_68K_8                3               /* Direct 8 bit  */
-#define R_68K_PC32     4               /* PC relative 32 bit */
-#define R_68K_PC16     5               /* PC relative 16 bit */
-#define R_68K_PC8      6               /* PC relative 8 bit */
-#define R_68K_GOT32    7               /* 32 bit PC relative GOT entry */
-#define R_68K_GOT16    8               /* 16 bit PC relative GOT entry */
-#define R_68K_GOT8     9               /* 8 bit PC relative GOT entry */
-#define R_68K_GOT32O   10              /* 32 bit GOT offset */
-#define R_68K_GOT16O   11              /* 16 bit GOT offset */
-#define R_68K_GOT8O    12              /* 8 bit GOT offset */
-#define R_68K_PLT32    13              /* 32 bit PC relative PLT address */
-#define R_68K_PLT16    14              /* 16 bit PC relative PLT address */
-#define R_68K_PLT8     15              /* 8 bit PC relative PLT address */
-#define R_68K_PLT32O   16              /* 32 bit PLT offset */
-#define R_68K_PLT16O   17              /* 16 bit PLT offset */
-#define R_68K_PLT8O    18              /* 8 bit PLT offset */
-#define R_68K_COPY     19              /* Copy symbol at runtime */
-#define R_68K_GLOB_DAT 20              /* Create GOT entry */
-#define R_68K_JMP_SLOT 21              /* Create PLT entry */
-#define R_68K_RELATIVE 22              /* Adjust by program base */
-/* Keep this the last entry.  */
-#define R_68K_NUM      23
-
-/* Intel 80386 specific definitions.  */
-
-/* i386 relocs.  */
-
-#define R_386_NONE        0            /* No reloc */
-#define R_386_32          1            /* Direct 32 bit  */
-#define R_386_PC32        2            /* PC relative 32 bit */
-#define R_386_GOT32       3            /* 32 bit GOT entry */
-#define R_386_PLT32       4            /* 32 bit PLT address */
-#define R_386_COPY        5            /* Copy symbol at runtime */
-#define R_386_GLOB_DAT    6            /* Create GOT entry */
-#define R_386_JMP_SLOT    7            /* Create PLT entry */
-#define R_386_RELATIVE    8            /* Adjust by program base */
-#define R_386_GOTOFF      9            /* 32 bit offset to GOT */
-#define R_386_GOTPC       10           /* 32 bit PC relative offset to GOT */
-#define R_386_32PLT       11
-#define R_386_TLS_TPOFF           14           /* Offset in static TLS block */
-#define R_386_TLS_IE      15           /* Address of GOT entry for static TLS
-                                          block offset */
-#define R_386_TLS_GOTIE           16           /* GOT entry for static TLS block
-                                          offset */
-#define R_386_TLS_LE      17           /* Offset relative to static TLS
-                                          block */
-#define R_386_TLS_GD      18           /* Direct 32 bit for GNU version of
-                                          general dynamic thread local data */
-#define R_386_TLS_LDM     19           /* Direct 32 bit for GNU version of
-                                          local dynamic thread local data
-                                          in LE code */
-#define R_386_16          20
-#define R_386_PC16        21
-#define R_386_8                   22
-#define R_386_PC8         23
-#define R_386_TLS_GD_32           24           /* Direct 32 bit for general dynamic
-                                          thread local data */
-#define R_386_TLS_GD_PUSH  25          /* Tag for pushl in GD TLS code */
-#define R_386_TLS_GD_CALL  26          /* Relocation for call to
-                                          __tls_get_addr() */
-#define R_386_TLS_GD_POP   27          /* Tag for popl in GD TLS code */
-#define R_386_TLS_LDM_32   28          /* Direct 32 bit for local dynamic
-                                          thread local data in LE code */
-#define R_386_TLS_LDM_PUSH 29          /* Tag for pushl in LDM TLS code */
-#define R_386_TLS_LDM_CALL 30          /* Relocation for call to
-                                          __tls_get_addr() in LDM code */
-#define R_386_TLS_LDM_POP  31          /* Tag for popl in LDM TLS code */
-#define R_386_TLS_LDO_32   32          /* Offset relative to TLS block */
-#define R_386_TLS_IE_32           33           /* GOT entry for negated static TLS
-                                          block offset */
-#define R_386_TLS_LE_32           34           /* Negated offset relative to static
-                                          TLS block */
-#define R_386_TLS_DTPMOD32 35          /* ID of module containing symbol */
-#define R_386_TLS_DTPOFF32 36          /* Offset in TLS block */
-#define R_386_TLS_TPOFF32  37          /* Negated offset in static TLS block */
-/* Keep this the last entry.  */
-#define R_386_NUM         38
-
-
-/* SUN SPARC specific definitions.  */
-
-/* x86_64 specific definitions.  */
-#define R_X86_64_NONE          0
-#define R_X86_64_64            1
-#define R_X86_64_PC32          2
-#define R_X86_64_GOT32         3
-#define R_X86_64_PLT32         4
-#define R_X86_64_COPY          5
-#define R_X86_64_GLOB_DAT      6
-#define R_X86_64_JUMP_SLOT     7
-#define R_X86_64_RELATIVE      8
-#define R_X86_64_GOTPCREL      9
-#define R_X86_64_32            10
-#define R_X86_64_32S           11
-#define R_X86_64_16            12
-#define R_X86_64_PC16          13
-#define R_X86_64_8             14
-#define R_X86_64_PC8           15
-
-/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
-
-#define STT_REGISTER   13              /* Global register reserved to app. */
-
-/* Values for Elf64_Ehdr.e_flags.  */
-
-#define EF_SPARCV9_MM          3
-#define EF_SPARCV9_TSO         0
-#define EF_SPARCV9_PSO         1
-#define EF_SPARCV9_RMO         2
-#define EF_SPARC_LEDATA                0x800000 /* little endian data */
-#define EF_SPARC_EXT_MASK      0xFFFF00
-#define EF_SPARC_32PLUS                0x000100 /* generic V8+ features */
-#define EF_SPARC_SUN_US1       0x000200 /* Sun UltraSPARC1 extensions */
-#define EF_SPARC_HAL_R1                0x000400 /* HAL R1 extensions */
-#define EF_SPARC_SUN_US3       0x000800 /* Sun UltraSPARCIII extensions */
-
-/* SPARC relocs.  */
-
-#define R_SPARC_NONE           0       /* No reloc */
-#define R_SPARC_8              1       /* Direct 8 bit */
-#define R_SPARC_16             2       /* Direct 16 bit */
-#define R_SPARC_32             3       /* Direct 32 bit */
-#define R_SPARC_DISP8          4       /* PC relative 8 bit */
-#define R_SPARC_DISP16         5       /* PC relative 16 bit */
-#define R_SPARC_DISP32         6       /* PC relative 32 bit */
-#define R_SPARC_WDISP30                7       /* PC relative 30 bit shifted */
-#define R_SPARC_WDISP22                8       /* PC relative 22 bit shifted */
-#define R_SPARC_HI22           9       /* High 22 bit */
-#define R_SPARC_22             10      /* Direct 22 bit */
-#define R_SPARC_13             11      /* Direct 13 bit */
-#define R_SPARC_LO10           12      /* Truncated 10 bit */
-#define R_SPARC_GOT10          13      /* Truncated 10 bit GOT entry */
-#define R_SPARC_GOT13          14      /* 13 bit GOT entry */
-#define R_SPARC_GOT22          15      /* 22 bit GOT entry shifted */
-#define R_SPARC_PC10           16      /* PC relative 10 bit truncated */
-#define R_SPARC_PC22           17      /* PC relative 22 bit shifted */
-#define R_SPARC_WPLT30         18      /* 30 bit PC relative PLT address */
-#define R_SPARC_COPY           19      /* Copy symbol at runtime */
-#define R_SPARC_GLOB_DAT       20      /* Create GOT entry */
-#define R_SPARC_JMP_SLOT       21      /* Create PLT entry */
-#define R_SPARC_RELATIVE       22      /* Adjust by program base */
-#define R_SPARC_UA32           23      /* Direct 32 bit unaligned */
-
-/* Additional Sparc64 relocs.  */
-
-#define R_SPARC_PLT32          24      /* Direct 32 bit ref to PLT entry */
-#define R_SPARC_HIPLT22                25      /* High 22 bit PLT entry */
-#define R_SPARC_LOPLT10                26      /* Truncated 10 bit PLT entry */
-#define R_SPARC_PCPLT32                27      /* PC rel 32 bit ref to PLT entry */
-#define R_SPARC_PCPLT22                28      /* PC rel high 22 bit PLT entry */
-#define R_SPARC_PCPLT10                29      /* PC rel trunc 10 bit PLT entry */
-#define R_SPARC_10             30      /* Direct 10 bit */
-#define R_SPARC_11             31      /* Direct 11 bit */
-#define R_SPARC_64             32      /* Direct 64 bit */
-#define R_SPARC_OLO10          33      /* 10bit with secondary 13bit addend */
-#define R_SPARC_HH22           34      /* Top 22 bits of direct 64 bit */
-#define R_SPARC_HM10           35      /* High middle 10 bits of ... */
-#define R_SPARC_LM22           36      /* Low middle 22 bits of ... */
-#define R_SPARC_PC_HH22                37      /* Top 22 bits of pc rel 64 bit */
-#define R_SPARC_PC_HM10                38      /* High middle 10 bit of ... */
-#define R_SPARC_PC_LM22                39      /* Low middle 22 bits of ... */
-#define R_SPARC_WDISP16                40      /* PC relative 16 bit shifted */
-#define R_SPARC_WDISP19                41      /* PC relative 19 bit shifted */
-#define R_SPARC_7              43      /* Direct 7 bit */
-#define R_SPARC_5              44      /* Direct 5 bit */
-#define R_SPARC_6              45      /* Direct 6 bit */
-#define R_SPARC_DISP64         46      /* PC relative 64 bit */
-#define R_SPARC_PLT64          47      /* Direct 64 bit ref to PLT entry */
-#define R_SPARC_HIX22          48      /* High 22 bit complemented */
-#define R_SPARC_LOX10          49      /* Truncated 11 bit complemented */
-#define R_SPARC_H44            50      /* Direct high 12 of 44 bit */
-#define R_SPARC_M44            51      /* Direct mid 22 of 44 bit */
-#define R_SPARC_L44            52      /* Direct low 10 of 44 bit */
-#define R_SPARC_REGISTER       53      /* Global register usage */
-#define R_SPARC_UA64           54      /* Direct 64 bit unaligned */
-#define R_SPARC_UA16           55      /* Direct 16 bit unaligned */
-#define R_SPARC_TLS_GD_HI22    56
-#define R_SPARC_TLS_GD_LO10    57
-#define R_SPARC_TLS_GD_ADD     58
-#define R_SPARC_TLS_GD_CALL    59
-#define R_SPARC_TLS_LDM_HI22   60
-#define R_SPARC_TLS_LDM_LO10   61
-#define R_SPARC_TLS_LDM_ADD    62
-#define R_SPARC_TLS_LDM_CALL   63
-#define R_SPARC_TLS_LDO_HIX22  64
-#define R_SPARC_TLS_LDO_LOX10  65
-#define R_SPARC_TLS_LDO_ADD    66
-#define R_SPARC_TLS_IE_HI22    67
-#define R_SPARC_TLS_IE_LO10    68
-#define R_SPARC_TLS_IE_LD      69
-#define R_SPARC_TLS_IE_LDX     70
-#define R_SPARC_TLS_IE_ADD     71
-#define R_SPARC_TLS_LE_HIX22   72
-#define R_SPARC_TLS_LE_LOX10   73
-#define R_SPARC_TLS_DTPMOD32   74
-#define R_SPARC_TLS_DTPMOD64   75
-#define R_SPARC_TLS_DTPOFF32   76
-#define R_SPARC_TLS_DTPOFF64   77
-#define R_SPARC_TLS_TPOFF32    78
-#define R_SPARC_TLS_TPOFF64    79
-/* Keep this the last entry.  */
-#define R_SPARC_NUM            80
-
-/* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
-
-#define DT_SPARC_REGISTER 0x70000001
-#define DT_SPARC_NUM   2
-
-/* Bits present in AT_HWCAP, primarily for Sparc32.  */
-
-#define HWCAP_SPARC_FLUSH      1       /* The cpu supports flush insn.  */
-#define HWCAP_SPARC_STBAR      2
-#define HWCAP_SPARC_SWAP       4
-#define HWCAP_SPARC_MULDIV     8
-#define HWCAP_SPARC_V9         16      /* The cpu is v9, so v8plus is ok.  */
-#define HWCAP_SPARC_ULTRA3     32
-
-/* MIPS R3000 specific definitions.  */
-
-/* Legal values for e_flags field of Elf32_Ehdr.  */
-
-#define EF_MIPS_NOREORDER   1          /* A .noreorder directive was used */
-#define EF_MIPS_PIC        2           /* Contains PIC code */
-#define EF_MIPS_CPIC       4           /* Uses PIC calling sequence */
-#define EF_MIPS_XGOT       8
-#define EF_MIPS_64BIT_WHIRL 16
-#define EF_MIPS_ABI2       32
-#define EF_MIPS_ABI_ON32    64
-#define EF_MIPS_ARCH       0xf0000000  /* MIPS architecture level */
-
-/* Legal values for MIPS architecture level.  */
-
-#define EF_MIPS_ARCH_1     0x00000000  /* -mips1 code.  */
-#define EF_MIPS_ARCH_2     0x10000000  /* -mips2 code.  */
-#define EF_MIPS_ARCH_3     0x20000000  /* -mips3 code.  */
-#define EF_MIPS_ARCH_4     0x30000000  /* -mips4 code.  */
-#define EF_MIPS_ARCH_5     0x40000000  /* -mips5 code.  */
-#define EF_MIPS_ARCH_32            0x60000000  /* MIPS32 code.  */
-#define EF_MIPS_ARCH_64            0x70000000  /* MIPS64 code.  */
-
-/* The following are non-official names and should not be used.  */
-
-#define E_MIPS_ARCH_1    0x00000000    /* -mips1 code.  */
-#define E_MIPS_ARCH_2    0x10000000    /* -mips2 code.  */
-#define E_MIPS_ARCH_3    0x20000000    /* -mips3 code.  */
-#define E_MIPS_ARCH_4    0x30000000    /* -mips4 code.  */
-#define E_MIPS_ARCH_5    0x40000000    /* -mips5 code.  */
-#define E_MIPS_ARCH_32   0x60000000    /* MIPS32 code.  */
-#define E_MIPS_ARCH_64   0x70000000    /* MIPS64 code.  */
-
-/* Special section indices.  */
-
-#define SHN_MIPS_ACOMMON    0xff00     /* Allocated common symbols */
-#define SHN_MIPS_TEXT      0xff01      /* Allocated test symbols.  */
-#define SHN_MIPS_DATA      0xff02      /* Allocated data symbols.  */
-#define SHN_MIPS_SCOMMON    0xff03     /* Small common symbols */
-#define SHN_MIPS_SUNDEFINED 0xff04     /* Small undefined symbols */
-
-/* Legal values for sh_type field of Elf32_Shdr.  */
-
-#define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
-#define SHT_MIPS_MSYM         0x70000001
-#define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
-#define SHT_MIPS_GPTAB        0x70000003 /* Global data area sizes */
-#define SHT_MIPS_UCODE        0x70000004 /* Reserved for SGI/MIPS compilers */
-#define SHT_MIPS_DEBUG        0x70000005 /* MIPS ECOFF debugging information*/
-#define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
-#define SHT_MIPS_PACKAGE       0x70000007
-#define SHT_MIPS_PACKSYM       0x70000008
-#define SHT_MIPS_RELD         0x70000009
-#define SHT_MIPS_IFACE         0x7000000b
-#define SHT_MIPS_CONTENT       0x7000000c
-#define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
-#define SHT_MIPS_SHDR         0x70000010
-#define SHT_MIPS_FDESC        0x70000011
-#define SHT_MIPS_EXTSYM               0x70000012
-#define SHT_MIPS_DENSE        0x70000013
-#define SHT_MIPS_PDESC        0x70000014
-#define SHT_MIPS_LOCSYM               0x70000015
-#define SHT_MIPS_AUXSYM               0x70000016
-#define SHT_MIPS_OPTSYM               0x70000017
-#define SHT_MIPS_LOCSTR               0x70000018
-#define SHT_MIPS_LINE         0x70000019
-#define SHT_MIPS_RFDESC               0x7000001a
-#define SHT_MIPS_DELTASYM      0x7000001b
-#define SHT_MIPS_DELTAINST     0x7000001c
-#define SHT_MIPS_DELTACLASS    0x7000001d
-#define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
-#define SHT_MIPS_DELTADECL     0x7000001f
-#define SHT_MIPS_SYMBOL_LIB    0x70000020
-#define SHT_MIPS_EVENTS               0x70000021 /* Event section.  */
-#define SHT_MIPS_TRANSLATE     0x70000022
-#define SHT_MIPS_PIXIE        0x70000023
-#define SHT_MIPS_XLATE        0x70000024
-#define SHT_MIPS_XLATE_DEBUG   0x70000025
-#define SHT_MIPS_WHIRL        0x70000026
-#define SHT_MIPS_EH_REGION     0x70000027
-#define SHT_MIPS_XLATE_OLD     0x70000028
-#define SHT_MIPS_PDR_EXCEPTION 0x70000029
-
-/* Legal values for sh_flags field of Elf32_Shdr.  */
-
-#define SHF_MIPS_GPREL  0x10000000     /* Must be part of global data area */
-#define SHF_MIPS_MERGE  0x20000000
-#define SHF_MIPS_ADDR   0x40000000
-#define SHF_MIPS_STRINGS 0x80000000
-#define SHF_MIPS_NOSTRIP 0x08000000
-#define SHF_MIPS_LOCAL  0x04000000
-#define SHF_MIPS_NAMES  0x02000000
-#define SHF_MIPS_NODUPE         0x01000000
-
-
-/* Symbol tables.  */
-
-/* MIPS specific values for `st_other'.  */
-#define STO_MIPS_DEFAULT               0x0
-#define STO_MIPS_INTERNAL              0x1
-#define STO_MIPS_HIDDEN                        0x2
-#define STO_MIPS_PROTECTED             0x3
-#define STO_MIPS_SC_ALIGN_UNUSED       0xff
-
-/* MIPS specific values for `st_info'.  */
-#define STB_MIPS_SPLIT_COMMON          13
-
-/* Entries found in sections of type SHT_MIPS_GPTAB.  */
-
-typedef union
-{
-  struct
-    {
-      Elf32_Word gt_current_g_value;   /* -G value used for compilation */
-      Elf32_Word gt_unused;            /* Not used */
-    } gt_header;                       /* First entry in section */
-  struct
-    {
-      Elf32_Word gt_g_value;           /* If this value were used for -G */
-      Elf32_Word gt_bytes;             /* This many bytes would be used */
-    } gt_entry;                                /* Subsequent entries in section */
-} Elf32_gptab;
-
-/* Entry found in sections of type SHT_MIPS_REGINFO.  */
-
-typedef struct
-{
-  Elf32_Word   ri_gprmask;             /* General registers used */
-  Elf32_Word   ri_cprmask[4];          /* Coprocessor registers used */
-  Elf32_Sword  ri_gp_value;            /* $gp register value */
-} Elf32_RegInfo;
-
-/* Entries found in sections of type SHT_MIPS_OPTIONS.  */
-
-typedef struct
-{
-  unsigned char kind;          /* Determines interpretation of the
-                                  variable part of descriptor.  */
-  unsigned char size;          /* Size of descriptor, including header.  */
-  Elf32_Section section;       /* Section header index of section affected,
-                                  0 for global options.  */
-  Elf32_Word info;             /* Kind-specific information.  */
-} Elf_Options;
-
-/* Values for `kind' field in Elf_Options.  */
-
-#define ODK_NULL       0       /* Undefined.  */
-#define ODK_REGINFO    1       /* Register usage information.  */
-#define ODK_EXCEPTIONS 2       /* Exception processing options.  */
-#define ODK_PAD                3       /* Section padding options.  */
-#define ODK_HWPATCH    4       /* Hardware workarounds performed */
-#define ODK_FILL       5       /* record the fill value used by the linker. */
-#define ODK_TAGS       6       /* reserve space for desktop tools to write. */
-#define ODK_HWAND      7       /* HW workarounds.  'AND' bits when merging. */
-#define ODK_HWOR       8       /* HW workarounds.  'OR' bits when merging.  */
-
-/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
-
-#define OEX_FPU_MIN    0x1f    /* FPE's which MUST be enabled.  */
-#define OEX_FPU_MAX    0x1f00  /* FPE's which MAY be enabled.  */
-#define OEX_PAGE0      0x10000 /* page zero must be mapped.  */
-#define OEX_SMM                0x20000 /* Force sequential memory mode?  */
-#define OEX_FPDBUG     0x40000 /* Force floating point debug mode?  */
-#define OEX_PRECISEFP  OEX_FPDBUG
-#define OEX_DISMISS    0x80000 /* Dismiss invalid address faults?  */
-
-#define OEX_FPU_INVAL  0x10
-#define OEX_FPU_DIV0   0x08
-#define OEX_FPU_OFLO   0x04
-#define OEX_FPU_UFLO   0x02
-#define OEX_FPU_INEX   0x01
-
-/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
-
-#define OHW_R4KEOP     0x1     /* R4000 end-of-page patch.  */
-#define OHW_R8KPFETCH  0x2     /* may need R8000 prefetch patch.  */
-#define OHW_R5KEOP     0x4     /* R5000 end-of-page patch.  */
-#define OHW_R5KCVTL    0x8     /* R5000 cvt.[ds].l bug.  clean=1.  */
-
-#define OPAD_PREFIX    0x1
-#define OPAD_POSTFIX   0x2
-#define OPAD_SYMBOL    0x4
-
-/* Entry found in `.options' section.  */
-
-typedef struct
-{
-  Elf32_Word hwp_flags1;       /* Extra flags.  */
-  Elf32_Word hwp_flags2;       /* Extra flags.  */
-} Elf_Options_Hw;
-
-/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
-
-#define OHWA0_R4KEOP_CHECKED   0x00000001
-#define OHWA1_R4KEOP_CLEAN     0x00000002
-
-/* MIPS relocs.  */
-
-#define R_MIPS_NONE            0       /* No reloc */
-#define R_MIPS_16              1       /* Direct 16 bit */
-#define R_MIPS_32              2       /* Direct 32 bit */
-#define R_MIPS_REL32           3       /* PC relative 32 bit */
-#define R_MIPS_26              4       /* Direct 26 bit shifted */
-#define R_MIPS_HI16            5       /* High 16 bit */
-#define R_MIPS_LO16            6       /* Low 16 bit */
-#define R_MIPS_GPREL16         7       /* GP relative 16 bit */
-#define R_MIPS_LITERAL         8       /* 16 bit literal entry */
-#define R_MIPS_GOT16           9       /* 16 bit GOT entry */
-#define R_MIPS_PC16            10      /* PC relative 16 bit */
-#define R_MIPS_CALL16          11      /* 16 bit GOT entry for function */
-#define R_MIPS_GPREL32         12      /* GP relative 32 bit */
-
-#define R_MIPS_SHIFT5          16
-#define R_MIPS_SHIFT6          17
-#define R_MIPS_64              18
-#define R_MIPS_GOT_DISP                19
-#define R_MIPS_GOT_PAGE                20
-#define R_MIPS_GOT_OFST                21
-#define R_MIPS_GOT_HI16                22
-#define R_MIPS_GOT_LO16                23
-#define R_MIPS_SUB             24
-#define R_MIPS_INSERT_A                25
-#define R_MIPS_INSERT_B                26
-#define R_MIPS_DELETE          27
-#define R_MIPS_HIGHER          28
-#define R_MIPS_HIGHEST         29
-#define R_MIPS_CALL_HI16       30
-#define R_MIPS_CALL_LO16       31
-#define R_MIPS_SCN_DISP                32
-#define R_MIPS_REL16           33
-#define R_MIPS_ADD_IMMEDIATE   34
-#define R_MIPS_PJUMP           35
-#define R_MIPS_RELGOT          36
-#define R_MIPS_JALR            37
-/* Keep this the last entry.  */
-#define R_MIPS_NUM             38
-
-/* Legal values for p_type field of Elf32_Phdr.  */
-
-#define PT_MIPS_REGINFO        0x70000000      /* Register usage information */
-#define PT_MIPS_RTPROC  0x70000001     /* Runtime procedure table. */
-#define PT_MIPS_OPTIONS 0x70000002
-
-/* Special program header types.  */
-
-#define PF_MIPS_LOCAL  0x10000000
-
-/* Legal values for d_tag field of Elf32_Dyn.  */
-
-#define DT_MIPS_RLD_VERSION  0x70000001        /* Runtime linker interface version */
-#define DT_MIPS_TIME_STAMP   0x70000002        /* Timestamp */
-#define DT_MIPS_ICHECKSUM    0x70000003        /* Checksum */
-#define DT_MIPS_IVERSION     0x70000004        /* Version string (string tbl index) */
-#define DT_MIPS_FLAGS       0x70000005 /* Flags */
-#define DT_MIPS_BASE_ADDRESS 0x70000006        /* Base address */
-#define DT_MIPS_MSYM        0x70000007
-#define DT_MIPS_CONFLICT     0x70000008        /* Address of CONFLICT section */
-#define DT_MIPS_LIBLIST             0x70000009 /* Address of LIBLIST section */
-#define DT_MIPS_LOCAL_GOTNO  0x7000000a        /* Number of local GOT entries */
-#define DT_MIPS_CONFLICTNO   0x7000000b        /* Number of CONFLICT entries */
-#define DT_MIPS_LIBLISTNO    0x70000010        /* Number of LIBLIST entries */
-#define DT_MIPS_SYMTABNO     0x70000011        /* Number of DYNSYM entries */
-#define DT_MIPS_UNREFEXTNO   0x70000012        /* First external DYNSYM */
-#define DT_MIPS_GOTSYM      0x70000013 /* First GOT entry in DYNSYM */
-#define DT_MIPS_HIPAGENO     0x70000014        /* Number of GOT page table entries */
-#define DT_MIPS_RLD_MAP             0x70000016 /* Address of run time loader map.  */
-#define DT_MIPS_DELTA_CLASS  0x70000017        /* Delta C++ class definition.  */
-#define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
-                                               DT_MIPS_DELTA_CLASS.  */
-#define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
-#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
-                                               DT_MIPS_DELTA_INSTANCE.  */
-#define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
-#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
-                                            DT_MIPS_DELTA_RELOC.  */
-#define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
-                                          relocations refer to.  */
-#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
-                                          DT_MIPS_DELTA_SYM.  */
-#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
-                                            class declaration.  */
-#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
-                                               DT_MIPS_DELTA_CLASSSYM.  */
-#define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
-#define DT_MIPS_PIXIE_INIT   0x70000023
-#define DT_MIPS_SYMBOL_LIB   0x70000024
-#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
-#define DT_MIPS_LOCAL_GOTIDX 0x70000026
-#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
-#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
-#define DT_MIPS_OPTIONS             0x70000029 /* Address of .options.  */
-#define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
-#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
-#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
-#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
-                                                   function stored in GOT.  */
-#define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
-                                          by rld on dlopen() calls.  */
-#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
-#define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
-#define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
-#define DT_MIPS_NUM         0x32
-
-/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
-
-#define RHF_NONE                  0            /* No flags */
-#define RHF_QUICKSTART            (1 << 0)     /* Use quickstart */
-#define RHF_NOTPOT                (1 << 1)     /* Hash size not power of 2 */
-#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)    /* Ignore LD_LIBRARY_PATH */
-#define RHF_NO_MOVE               (1 << 3)
-#define RHF_SGI_ONLY              (1 << 4)
-#define RHF_GUARANTEE_INIT        (1 << 5)
-#define RHF_DELTA_C_PLUS_PLUS     (1 << 6)
-#define RHF_GUARANTEE_START_INIT   (1 << 7)
-#define RHF_PIXIE                 (1 << 8)
-#define RHF_DEFAULT_DELAY_LOAD    (1 << 9)
-#define RHF_REQUICKSTART          (1 << 10)
-#define RHF_REQUICKSTARTED        (1 << 11)
-#define RHF_CORD                  (1 << 12)
-#define RHF_NO_UNRES_UNDEF        (1 << 13)
-#define RHF_RLD_ORDER_SAFE        (1 << 14)
-
-/* Entries found in sections of type SHT_MIPS_LIBLIST.  */
-
-typedef struct
-{
-  Elf32_Word l_name;           /* Name (string table index) */
-  Elf32_Word l_time_stamp;     /* Timestamp */
-  Elf32_Word l_checksum;       /* Checksum */
-  Elf32_Word l_version;                /* Interface version */
-  Elf32_Word l_flags;          /* Flags */
-} Elf32_Lib;
-
-typedef struct
-{
-  Elf64_Word l_name;           /* Name (string table index) */
-  Elf64_Word l_time_stamp;     /* Timestamp */
-  Elf64_Word l_checksum;       /* Checksum */
-  Elf64_Word l_version;                /* Interface version */
-  Elf64_Word l_flags;          /* Flags */
-} Elf64_Lib;
-
-
-/* Legal values for l_flags.  */
-
-#define LL_NONE                  0
-#define LL_EXACT_MATCH   (1 << 0)      /* Require exact match */
-#define LL_IGNORE_INT_VER (1 << 1)     /* Ignore interface version */
-#define LL_REQUIRE_MINOR  (1 << 2)
-#define LL_EXPORTS       (1 << 3)
-#define LL_DELAY_LOAD    (1 << 4)
-#define LL_DELTA         (1 << 5)
-
-/* Entries found in sections of type SHT_MIPS_CONFLICT.  */
-
-typedef Elf32_Addr Elf32_Conflict;
-
-
-/* HPPA specific definitions.  */
-
-/* Legal values for e_flags field of Elf32_Ehdr.  */
-
-#define EF_PARISC_TRAPNIL      0x00010000 /* Trap nil pointer dereference.  */
-#define EF_PARISC_EXT          0x00020000 /* Program uses arch. extensions. */
-#define EF_PARISC_LSB          0x00040000 /* Program expects little endian. */
-#define EF_PARISC_WIDE         0x00080000 /* Program expects wide mode.  */
-#define EF_PARISC_NO_KABP      0x00100000 /* No kernel assisted branch
-                                             prediction.  */
-#define EF_PARISC_LAZYSWAP     0x00400000 /* Allow lazy swapping.  */
-#define EF_PARISC_ARCH         0x0000ffff /* Architecture version.  */
-
-/* Defined values for `e_flags & EF_PARISC_ARCH' are:  */
-
-#define EFA_PARISC_1_0             0x020b /* PA-RISC 1.0 big-endian.  */
-#define EFA_PARISC_1_1             0x0210 /* PA-RISC 1.1 big-endian.  */
-#define EFA_PARISC_2_0             0x0214 /* PA-RISC 2.0 big-endian.  */
-
-/* Additional section indices.  */
-
-#define SHN_PARISC_ANSI_COMMON 0xff00     /* Section for tentatively declared
-                                             symbols in ANSI C.  */
-#define SHN_PARISC_HUGE_COMMON 0xff01     /* Common blocks in huge model.  */
-
-/* Legal values for sh_type field of Elf32_Shdr.  */
-
-#define SHT_PARISC_EXT         0x70000000 /* Contains product specific ext. */
-#define SHT_PARISC_UNWIND      0x70000001 /* Unwind information.  */
-#define SHT_PARISC_DOC         0x70000002 /* Debug info for optimized code. */
-
-/* Legal values for sh_flags field of Elf32_Shdr.  */
-
-#define SHF_PARISC_SHORT       0x20000000 /* Section with short addressing. */
-#define SHF_PARISC_HUGE                0x40000000 /* Section far from gp.  */
-#define SHF_PARISC_SBP         0x80000000 /* Static branch prediction code. */
-
-/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
-
-#define STT_PARISC_MILLICODE   13      /* Millicode function entry point.  */
-
-#define STT_HP_OPAQUE          (STT_LOOS + 0x1)
-#define STT_HP_STUB            (STT_LOOS + 0x2)
-
-/* HPPA relocs.  */
-
-#define R_PARISC_NONE          0       /* No reloc.  */
-#define R_PARISC_DIR32         1       /* Direct 32-bit reference.  */
-#define R_PARISC_DIR21L                2       /* Left 21 bits of eff. address.  */
-#define R_PARISC_DIR17R                3       /* Right 17 bits of eff. address.  */
-#define R_PARISC_DIR17F                4       /* 17 bits of eff. address.  */
-#define R_PARISC_DIR14R                6       /* Right 14 bits of eff. address.  */
-#define R_PARISC_PCREL32       9       /* 32-bit rel. address.  */
-#define R_PARISC_PCREL21L      10      /* Left 21 bits of rel. address.  */
-#define R_PARISC_PCREL17R      11      /* Right 17 bits of rel. address.  */
-#define R_PARISC_PCREL17F      12      /* 17 bits of rel. address.  */
-#define R_PARISC_PCREL14R      14      /* Right 14 bits of rel. address.  */
-#define R_PARISC_DPREL21L      18      /* Left 21 bits of rel. address.  */
-#define R_PARISC_DPREL14R      22      /* Right 14 bits of rel. address.  */
-#define R_PARISC_GPREL21L      26      /* GP-relative, left 21 bits.  */
-#define R_PARISC_GPREL14R      30      /* GP-relative, right 14 bits.  */
-#define R_PARISC_LTOFF21L      34      /* LT-relative, left 21 bits.  */
-#define R_PARISC_LTOFF14R      38      /* LT-relative, right 14 bits.  */
-#define R_PARISC_SECREL32      41      /* 32 bits section rel. address.  */
-#define R_PARISC_SEGBASE       48      /* No relocation, set segment base.  */
-#define R_PARISC_SEGREL32      49      /* 32 bits segment rel. address.  */
-#define R_PARISC_PLTOFF21L     50      /* PLT rel. address, left 21 bits.  */
-#define R_PARISC_PLTOFF14R     54      /* PLT rel. address, right 14 bits.  */
-#define R_PARISC_LTOFF_FPTR32  57      /* 32 bits LT-rel. function pointer. */
-#define R_PARISC_LTOFF_FPTR21L 58      /* LT-rel. fct ptr, left 21 bits. */
-#define R_PARISC_LTOFF_FPTR14R 62      /* LT-rel. fct ptr, right 14 bits. */
-#define R_PARISC_FPTR64                64      /* 64 bits function address.  */
-#define R_PARISC_PLABEL32      65      /* 32 bits function address.  */
-#define R_PARISC_PCREL64       72      /* 64 bits PC-rel. address.  */
-#define R_PARISC_PCREL22F      74      /* 22 bits PC-rel. address.  */
-#define R_PARISC_PCREL14WR     75      /* PC-rel. address, right 14 bits.  */
-#define R_PARISC_PCREL14DR     76      /* PC rel. address, right 14 bits.  */
-#define R_PARISC_PCREL16F      77      /* 16 bits PC-rel. address.  */
-#define R_PARISC_PCREL16WF     78      /* 16 bits PC-rel. address.  */
-#define R_PARISC_PCREL16DF     79      /* 16 bits PC-rel. address.  */
-#define R_PARISC_DIR64         80      /* 64 bits of eff. address.  */
-#define R_PARISC_DIR14WR       83      /* 14 bits of eff. address.  */
-#define R_PARISC_DIR14DR       84      /* 14 bits of eff. address.  */
-#define R_PARISC_DIR16F                85      /* 16 bits of eff. address.  */
-#define R_PARISC_DIR16WF       86      /* 16 bits of eff. address.  */
-#define R_PARISC_DIR16DF       87      /* 16 bits of eff. address.  */
-#define R_PARISC_GPREL64       88      /* 64 bits of GP-rel. address.  */
-#define R_PARISC_GPREL14WR     91      /* GP-rel. address, right 14 bits.  */
-#define R_PARISC_GPREL14DR     92      /* GP-rel. address, right 14 bits.  */
-#define R_PARISC_GPREL16F      93      /* 16 bits GP-rel. address.  */
-#define R_PARISC_GPREL16WF     94      /* 16 bits GP-rel. address.  */
-#define R_PARISC_GPREL16DF     95      /* 16 bits GP-rel. address.  */
-#define R_PARISC_LTOFF64       96      /* 64 bits LT-rel. address.  */
-#define R_PARISC_LTOFF14WR     99      /* LT-rel. address, right 14 bits.  */
-#define R_PARISC_LTOFF14DR     100     /* LT-rel. address, right 14 bits.  */
-#define R_PARISC_LTOFF16F      101     /* 16 bits LT-rel. address.  */
-#define R_PARISC_LTOFF16WF     102     /* 16 bits LT-rel. address.  */
-#define R_PARISC_LTOFF16DF     103     /* 16 bits LT-rel. address.  */
-#define R_PARISC_SECREL64      104     /* 64 bits section rel. address.  */
-#define R_PARISC_SEGREL64      112     /* 64 bits segment rel. address.  */
-#define R_PARISC_PLTOFF14WR    115     /* PLT-rel. address, right 14 bits.  */
-#define R_PARISC_PLTOFF14DR    116     /* PLT-rel. address, right 14 bits.  */
-#define R_PARISC_PLTOFF16F     117     /* 16 bits LT-rel. address.  */
-#define R_PARISC_PLTOFF16WF    118     /* 16 bits PLT-rel. address.  */
-#define R_PARISC_PLTOFF16DF    119     /* 16 bits PLT-rel. address.  */
-#define R_PARISC_LTOFF_FPTR64  120     /* 64 bits LT-rel. function ptr.  */
-#define R_PARISC_LTOFF_FPTR14WR        123     /* LT-rel. fct. ptr., right 14 bits. */
-#define R_PARISC_LTOFF_FPTR14DR        124     /* LT-rel. fct. ptr., right 14 bits. */
-#define R_PARISC_LTOFF_FPTR16F 125     /* 16 bits LT-rel. function ptr.  */
-#define R_PARISC_LTOFF_FPTR16WF        126     /* 16 bits LT-rel. function ptr.  */
-#define R_PARISC_LTOFF_FPTR16DF        127     /* 16 bits LT-rel. function ptr.  */
-#define R_PARISC_LORESERVE     128
-#define R_PARISC_COPY          128     /* Copy relocation.  */
-#define R_PARISC_IPLT          129     /* Dynamic reloc, imported PLT */
-#define R_PARISC_EPLT          130     /* Dynamic reloc, exported PLT */
-#define R_PARISC_TPREL32       153     /* 32 bits TP-rel. address.  */
-#define R_PARISC_TPREL21L      154     /* TP-rel. address, left 21 bits.  */
-#define R_PARISC_TPREL14R      158     /* TP-rel. address, right 14 bits.  */
-#define R_PARISC_LTOFF_TP21L   162     /* LT-TP-rel. address, left 21 bits. */
-#define R_PARISC_LTOFF_TP14R   166     /* LT-TP-rel. address, right 14 bits.*/
-#define R_PARISC_LTOFF_TP14F   167     /* 14 bits LT-TP-rel. address.  */
-#define R_PARISC_TPREL64       216     /* 64 bits TP-rel. address.  */
-#define R_PARISC_TPREL14WR     219     /* TP-rel. address, right 14 bits.  */
-#define R_PARISC_TPREL14DR     220     /* TP-rel. address, right 14 bits.  */
-#define R_PARISC_TPREL16F      221     /* 16 bits TP-rel. address.  */
-#define R_PARISC_TPREL16WF     222     /* 16 bits TP-rel. address.  */
-#define R_PARISC_TPREL16DF     223     /* 16 bits TP-rel. address.  */
-#define R_PARISC_LTOFF_TP64    224     /* 64 bits LT-TP-rel. address.  */
-#define R_PARISC_LTOFF_TP14WR  227     /* LT-TP-rel. address, right 14 bits.*/
-#define R_PARISC_LTOFF_TP14DR  228     /* LT-TP-rel. address, right 14 bits.*/
-#define R_PARISC_LTOFF_TP16F   229     /* 16 bits LT-TP-rel. address.  */
-#define R_PARISC_LTOFF_TP16WF  230     /* 16 bits LT-TP-rel. address.  */
-#define R_PARISC_LTOFF_TP16DF  231     /* 16 bits LT-TP-rel. address.  */
-#define R_PARISC_HIRESERVE     255
-
-/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
-
-#define PT_HP_TLS              (PT_LOOS + 0x0)
-#define PT_HP_CORE_NONE                (PT_LOOS + 0x1)
-#define PT_HP_CORE_VERSION     (PT_LOOS + 0x2)
-#define PT_HP_CORE_KERNEL      (PT_LOOS + 0x3)
-#define PT_HP_CORE_COMM                (PT_LOOS + 0x4)
-#define PT_HP_CORE_PROC                (PT_LOOS + 0x5)
-#define PT_HP_CORE_LOADABLE    (PT_LOOS + 0x6)
-#define PT_HP_CORE_STACK       (PT_LOOS + 0x7)
-#define PT_HP_CORE_SHM         (PT_LOOS + 0x8)
-#define PT_HP_CORE_MMF         (PT_LOOS + 0x9)
-#define PT_HP_PARALLEL         (PT_LOOS + 0x10)
-#define PT_HP_FASTBIND         (PT_LOOS + 0x11)
-#define PT_HP_OPT_ANNOT                (PT_LOOS + 0x12)
-#define PT_HP_HSL_ANNOT                (PT_LOOS + 0x13)
-#define PT_HP_STACK            (PT_LOOS + 0x14)
-
-#define PT_PARISC_ARCHEXT      0x70000000
-#define PT_PARISC_UNWIND       0x70000001
-
-/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr.  */
-
-#define PF_PARISC_SBP          0x08000000
-
-#define PF_HP_PAGE_SIZE                0x00100000
-#define PF_HP_FAR_SHARED       0x00200000
-#define PF_HP_NEAR_SHARED      0x00400000
-#define PF_HP_CODE             0x01000000
-#define PF_HP_MODIFY           0x02000000
-#define PF_HP_LAZYSWAP         0x04000000
-#define PF_HP_SBP              0x08000000
-
-
-/* Alpha specific definitions.  */
-
-/* Legal values for e_flags field of Elf64_Ehdr.  */
-
-#define EF_ALPHA_32BIT         1       /* All addresses must be < 2GB.  */
-#define EF_ALPHA_CANRELAX      2       /* Relocations for relaxing exist.  */
-
-/* Legal values for sh_type field of Elf64_Shdr.  */
-
-/* These two are primarily concerned with ECOFF debugging info.  */
-#define SHT_ALPHA_DEBUG                0x70000001
-#define SHT_ALPHA_REGINFO      0x70000002
-
-/* Legal values for sh_flags field of Elf64_Shdr.  */
-
-#define SHF_ALPHA_GPREL                0x10000000
-
-/* Legal values for st_other field of Elf64_Sym.  */
-#define STO_ALPHA_NOPV         0x80    /* No PV required.  */
-#define STO_ALPHA_STD_GPLOAD   0x88    /* PV only used for initial ldgp.  */
-
-/* Alpha relocs.  */
-
-#define R_ALPHA_NONE           0       /* No reloc */
-#define R_ALPHA_REFLONG                1       /* Direct 32 bit */
-#define R_ALPHA_REFQUAD                2       /* Direct 64 bit */
-#define R_ALPHA_GPREL32                3       /* GP relative 32 bit */
-#define R_ALPHA_LITERAL                4       /* GP relative 16 bit w/optimization */
-#define R_ALPHA_LITUSE         5       /* Optimization hint for LITERAL */
-#define R_ALPHA_GPDISP         6       /* Add displacement to GP */
-#define R_ALPHA_BRADDR         7       /* PC+4 relative 23 bit shifted */
-#define R_ALPHA_HINT           8       /* PC+4 relative 16 bit shifted */
-#define R_ALPHA_SREL16         9       /* PC relative 16 bit */
-#define R_ALPHA_SREL32         10      /* PC relative 32 bit */
-#define R_ALPHA_SREL64         11      /* PC relative 64 bit */
-#define R_ALPHA_GPRELHIGH      17      /* GP relative 32 bit, high 16 bits */
-#define R_ALPHA_GPRELLOW       18      /* GP relative 32 bit, low 16 bits */
-#define R_ALPHA_GPREL16                19      /* GP relative 16 bit */
-#define R_ALPHA_COPY           24      /* Copy symbol at runtime */
-#define R_ALPHA_GLOB_DAT       25      /* Create GOT entry */
-#define R_ALPHA_JMP_SLOT       26      /* Create PLT entry */
-#define R_ALPHA_RELATIVE       27      /* Adjust by program base */
-#define R_ALPHA_TLS_GD_HI      28
-#define R_ALPHA_TLSGD          29
-#define R_ALPHA_TLS_LDM                30
-#define R_ALPHA_DTPMOD64       31
-#define R_ALPHA_GOTDTPREL      32
-#define R_ALPHA_DTPREL64       33
-#define R_ALPHA_DTPRELHI       34
-#define R_ALPHA_DTPRELLO       35
-#define R_ALPHA_DTPREL16       36
-#define R_ALPHA_GOTTPREL       37
-#define R_ALPHA_TPREL64                38
-#define R_ALPHA_TPRELHI                39
-#define R_ALPHA_TPRELLO                40
-#define R_ALPHA_TPREL16                41
-/* Keep this the last entry.  */
-#define R_ALPHA_NUM            46
-
-/* Magic values of the LITUSE relocation addend.  */
-#define LITUSE_ALPHA_ADDR      0
-#define LITUSE_ALPHA_BASE      1
-#define LITUSE_ALPHA_BYTOFF    2
-#define LITUSE_ALPHA_JSR       3
-#define LITUSE_ALPHA_TLS_GD    4
-#define LITUSE_ALPHA_TLS_LDM   5
-
-
-/* PowerPC specific declarations */
-
-/* Values for Elf32/64_Ehdr.e_flags.  */
-#define EF_PPC_EMB             0x80000000      /* PowerPC embedded flag */
-
-/* Cygnus local bits below */
-#define EF_PPC_RELOCATABLE     0x00010000      /* PowerPC -mrelocatable flag*/
-#define EF_PPC_RELOCATABLE_LIB 0x00008000      /* PowerPC -mrelocatable-lib
-                                                  flag */
-
-/* PowerPC relocations defined by the ABIs */
-#define R_PPC_NONE             0
-#define R_PPC_ADDR32           1       /* 32bit absolute address */
-#define R_PPC_ADDR24           2       /* 26bit address, 2 bits ignored.  */
-#define R_PPC_ADDR16           3       /* 16bit absolute address */
-#define R_PPC_ADDR16_LO                4       /* lower 16bit of absolute address */
-#define R_PPC_ADDR16_HI                5       /* high 16bit of absolute address */
-#define R_PPC_ADDR16_HA                6       /* adjusted high 16bit */
-#define R_PPC_ADDR14           7       /* 16bit address, 2 bits ignored */
-#define R_PPC_ADDR14_BRTAKEN   8
-#define R_PPC_ADDR14_BRNTAKEN  9
-#define R_PPC_REL24            10      /* PC relative 26 bit */
-#define R_PPC_REL14            11      /* PC relative 16 bit */
-#define R_PPC_REL14_BRTAKEN    12
-#define R_PPC_REL14_BRNTAKEN   13
-#define R_PPC_GOT16            14
-#define R_PPC_GOT16_LO         15
-#define R_PPC_GOT16_HI         16
-#define R_PPC_GOT16_HA         17
-#define R_PPC_PLTREL24         18
-#define R_PPC_COPY             19
-#define R_PPC_GLOB_DAT         20
-#define R_PPC_JMP_SLOT         21
-#define R_PPC_RELATIVE         22
-#define R_PPC_LOCAL24PC                23
-#define R_PPC_UADDR32          24
-#define R_PPC_UADDR16          25
-#define R_PPC_REL32            26
-#define R_PPC_PLT32            27
-#define R_PPC_PLTREL32         28
-#define R_PPC_PLT16_LO         29
-#define R_PPC_PLT16_HI         30
-#define R_PPC_PLT16_HA         31
-#define R_PPC_SDAREL16         32
-#define R_PPC_SECTOFF          33
-#define R_PPC_SECTOFF_LO       34
-#define R_PPC_SECTOFF_HI       35
-#define R_PPC_SECTOFF_HA       36
-/* Keep this the last entry.  */
-#define R_PPC_NUM              37
-
-/* PowerPC64 relocations defined by the ABIs */
-#define R_PPC64_NONE    R_PPC_NONE
-#define R_PPC64_ADDR32  R_PPC_ADDR32  /* 32bit absolute address.  */
-#define R_PPC64_ADDR24  R_PPC_ADDR24  /* 26bit address, word aligned.  */
-#define R_PPC64_ADDR16  R_PPC_ADDR16  /* 16bit absolute address. */
-#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of abs. address.  */
-#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of abs. address. */
-#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits.  */
-#define R_PPC64_ADDR14 R_PPC_ADDR14   /* 16bit address, word aligned.  */
-#define R_PPC64_ADDR14_BRTAKEN  R_PPC_ADDR14_BRTAKEN
-#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
-#define R_PPC64_REL24   R_PPC_REL24 /* PC relative 26 bit, word aligned.  */
-#define R_PPC64_REL14   R_PPC_REL14 /* PC relative 16 bit. */
-#define R_PPC64_REL14_BRTAKEN   R_PPC_REL14_BRTAKEN
-#define R_PPC64_REL14_BRNTAKEN  R_PPC_REL14_BRNTAKEN
-#define R_PPC64_GOT16     R_PPC_GOT16
-#define R_PPC64_GOT16_LO  R_PPC_GOT16_LO
-#define R_PPC64_GOT16_HI  R_PPC_GOT16_HI
-#define R_PPC64_GOT16_HA  R_PPC_GOT16_HA
-
-#define R_PPC64_COPY      R_PPC_COPY
-#define R_PPC64_GLOB_DAT  R_PPC_GLOB_DAT
-#define R_PPC64_JMP_SLOT  R_PPC_JMP_SLOT
-#define R_PPC64_RELATIVE  R_PPC_RELATIVE
-
-#define R_PPC64_UADDR32   R_PPC_UADDR32
-#define R_PPC64_UADDR16   R_PPC_UADDR16
-#define R_PPC64_REL32     R_PPC_REL32
-#define R_PPC64_PLT32     R_PPC_PLT32
-#define R_PPC64_PLTREL32  R_PPC_PLTREL32
-#define R_PPC64_PLT16_LO  R_PPC_PLT16_LO
-#define R_PPC64_PLT16_HI  R_PPC_PLT16_HI
-#define R_PPC64_PLT16_HA  R_PPC_PLT16_HA
-
-#define R_PPC64_SECTOFF     R_PPC_SECTOFF
-#define R_PPC64_SECTOFF_LO  R_PPC_SECTOFF_LO
-#define R_PPC64_SECTOFF_HI  R_PPC_SECTOFF_HI
-#define R_PPC64_SECTOFF_HA  R_PPC_SECTOFF_HA
-#define R_PPC64_ADDR30          37  /* word30 (S + A - P) >> 2.  */
-#define R_PPC64_ADDR64          38  /* doubleword64 S + A.  */
-#define R_PPC64_ADDR16_HIGHER   39  /* half16 #higher(S + A).  */
-#define R_PPC64_ADDR16_HIGHERA  40  /* half16 #highera(S + A).  */
-#define R_PPC64_ADDR16_HIGHEST  41  /* half16 #highest(S + A).  */
-#define R_PPC64_ADDR16_HIGHESTA 42  /* half16 #highesta(S + A). */
-#define R_PPC64_UADDR64     43  /* doubleword64 S + A.  */
-#define R_PPC64_REL64       44  /* doubleword64 S + A - P.  */
-#define R_PPC64_PLT64       45  /* doubleword64 L + A.  */
-#define R_PPC64_PLTREL64    46  /* doubleword64 L + A - P.  */
-#define R_PPC64_TOC16       47  /* half16* S + A - .TOC.  */
-#define R_PPC64_TOC16_LO    48  /* half16 #lo(S + A - .TOC.).  */
-#define R_PPC64_TOC16_HI    49  /* half16 #hi(S + A - .TOC.).  */
-#define R_PPC64_TOC16_HA    50  /* half16 #ha(S + A - .TOC.).  */
-#define R_PPC64_TOC         51  /* doubleword64 .TOC. */
-#define R_PPC64_PLTGOT16    52  /* half16* M + A.  */
-#define R_PPC64_PLTGOT16_LO 53  /* half16 #lo(M + A).  */
-#define R_PPC64_PLTGOT16_HI 54  /* half16 #hi(M + A).  */
-#define R_PPC64_PLTGOT16_HA 55  /* half16 #ha(M + A).  */
-
-#define R_PPC64_ADDR16_DS      56 /* half16ds* (S + A) >> 2.  */
-#define R_PPC64_ADDR16_LO_DS   57 /* half16ds  #lo(S + A) >> 2.  */
-#define R_PPC64_GOT16_DS       58 /* half16ds* (G + A) >> 2.  */
-#define R_PPC64_GOT16_LO_DS    59 /* half16ds  #lo(G + A) >> 2.  */
-#define R_PPC64_PLT16_LO_DS    60 /* half16ds  #lo(L + A) >> 2.  */
-#define R_PPC64_SECTOFF_DS     61 /* half16ds* (R + A) >> 2.  */
-#define R_PPC64_SECTOFF_LO_DS  62 /* half16ds  #lo(R + A) >> 2.  */
-#define R_PPC64_TOC16_DS       63 /* half16ds* (S + A - .TOC.) >> 2.  */
-#define R_PPC64_TOC16_LO_DS    64 /* half16ds  #lo(S + A - .TOC.) >> 2.  */
-#define R_PPC64_PLTGOT16_DS    65 /* half16ds* (M + A) >> 2.  */
-#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds  #lo(M + A) >> 2.  */
-/* Keep this the last entry.  */
-#define R_PPC64_NUM            67
-
-/* The remaining relocs are from the Embedded ELF ABI, and are not
-   in the SVR4 ELF ABI.  */
-#define R_PPC_EMB_NADDR32      101
-#define R_PPC_EMB_NADDR16      102
-#define R_PPC_EMB_NADDR16_LO   103
-#define R_PPC_EMB_NADDR16_HI   104
-#define R_PPC_EMB_NADDR16_HA   105
-#define R_PPC_EMB_SDAI16       106
-#define R_PPC_EMB_SDA2I16      107
-#define R_PPC_EMB_SDA2REL      108
-#define R_PPC_EMB_SDA21                109     /* 16 bit offset in SDA */
-#define R_PPC_EMB_MRKREF       110
-#define R_PPC_EMB_RELSEC16     111
-#define R_PPC_EMB_RELST_LO     112
-#define R_PPC_EMB_RELST_HI     113
-#define R_PPC_EMB_RELST_HA     114
-#define R_PPC_EMB_BIT_FLD      115
-#define R_PPC_EMB_RELSDA       116     /* 16 bit relative offset in SDA */
-
-/* Diab tool relocations.  */
-#define R_PPC_DIAB_SDA21_LO    180     /* like EMB_SDA21, but lower 16 bit */
-#define R_PPC_DIAB_SDA21_HI    181     /* like EMB_SDA21, but high 16 bit */
-#define R_PPC_DIAB_SDA21_HA    182     /* like EMB_SDA21, adjusted high 16 */
-#define R_PPC_DIAB_RELSDA_LO   183     /* like EMB_RELSDA, but lower 16 bit */
-#define R_PPC_DIAB_RELSDA_HI   184     /* like EMB_RELSDA, but high 16 bit */
-#define R_PPC_DIAB_RELSDA_HA   185     /* like EMB_RELSDA, adjusted high 16 */
-
-/* This is a phony reloc to handle any old fashioned TOC16 references
-   that may still be in object files.  */
-#define R_PPC_TOC16            255
-
-/* PowerPC64 specific values for the Dyn d_tag field.  */
-#define DT_PPC64_GLINK  (DT_LOPROC + 0)
-#define DT_PPC64_NUM    1
-
-/* ARM specific declarations */
-
-/* Processor specific flags for the ELF header e_flags field.  */
-#define EF_ARM_RELEXEC     0x01
-#define EF_ARM_HASENTRY    0x02
-#define EF_ARM_INTERWORK   0x04
-#define EF_ARM_APCS_26     0x08
-#define EF_ARM_APCS_FLOAT  0x10
-#define EF_ARM_PIC         0x20
-#define EF_ARM_ALIGN8      0x40                /* 8-bit structure alignment is in use */
-#define EF_ARM_NEW_ABI     0x80
-#define EF_ARM_OLD_ABI     0x100
-
-/* Other constants defined in the ARM ELF spec. version B-01.  */
-/* NB. These conflict with values defined above.  */
-#define EF_ARM_SYMSARESORTED   0x04
-#define EF_ARM_DYNSYMSUSESEGIDX 0x08
-#define EF_ARM_MAPSYMSFIRST    0x10
-#define EF_ARM_EABIMASK                0XFF000000
-
-#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
-#define EF_ARM_EABI_UNKNOWN  0x00000000
-#define EF_ARM_EABI_VER1     0x01000000
-#define EF_ARM_EABI_VER2     0x02000000
-
-/* Additional symbol types for Thumb */
-#define STT_ARM_TFUNC      0xd
-
-/* ARM-specific values for sh_flags */
-#define SHF_ARM_ENTRYSECT  0x10000000   /* Section contains an entry point */
-#define SHF_ARM_COMDEF     0x80000000   /* Section may be multiply defined
-                                          in the input to a link step */
-
-/* ARM-specific program header flags */
-#define PF_ARM_SB          0x10000000   /* Segment contains the location
-                                          addressed by the static base */
-
-/* ARM relocs.  */
-#define R_ARM_NONE             0       /* No reloc */
-#define R_ARM_PC24             1       /* PC relative 26 bit branch */
-#define R_ARM_ABS32            2       /* Direct 32 bit  */
-#define R_ARM_REL32            3       /* PC relative 32 bit */
-#define R_ARM_PC13             4
-#define R_ARM_ABS16            5       /* Direct 16 bit */
-#define R_ARM_ABS12            6       /* Direct 12 bit */
-#define R_ARM_THM_ABS5         7
-#define R_ARM_ABS8             8       /* Direct 8 bit */
-#define R_ARM_SBREL32          9
-#define R_ARM_THM_PC22         10
-#define R_ARM_THM_PC8          11
-#define R_ARM_AMP_VCALL9       12
-#define R_ARM_SWI24            13
-#define R_ARM_THM_SWI8         14
-#define R_ARM_XPC25            15
-#define R_ARM_THM_XPC22                16
-#define R_ARM_COPY             20      /* Copy symbol at runtime */
-#define R_ARM_GLOB_DAT         21      /* Create GOT entry */
-#define R_ARM_JUMP_SLOT                22      /* Create PLT entry */
-#define R_ARM_RELATIVE         23      /* Adjust by program base */
-#define R_ARM_GOTOFF           24      /* 32 bit offset to GOT */
-#define R_ARM_GOTPC            25      /* 32 bit PC relative offset to GOT */
-#define R_ARM_GOT32            26      /* 32 bit GOT entry */
-#define R_ARM_PLT32            27      /* 32 bit PLT address */
-#define R_ARM_ALU_PCREL_7_0    32
-#define R_ARM_ALU_PCREL_15_8   33
-#define R_ARM_ALU_PCREL_23_15  34
-#define R_ARM_LDR_SBREL_11_0   35
-#define R_ARM_ALU_SBREL_19_12  36
-#define R_ARM_ALU_SBREL_27_20  37
-#define R_ARM_GNU_VTENTRY      100
-#define R_ARM_GNU_VTINHERIT    101
-#define R_ARM_THM_PC11         102     /* thumb unconditional branch */
-#define R_ARM_THM_PC9          103     /* thumb conditional branch */
-#define R_ARM_RXPC25           249
-#define R_ARM_RSBREL32         250
-#define R_ARM_THM_RPC22                251
-#define R_ARM_RREL32           252
-#define R_ARM_RABS22           253
-#define R_ARM_RPC24            254
-#define R_ARM_RBASE            255
-/* Keep this the last entry.  */
-#define R_ARM_NUM              256
-
-/* IA-64 specific declarations.  */
-
-/* Processor specific flags for the Ehdr e_flags field.  */
-#define EF_IA_64_MASKOS                0x0000000f      /* os-specific flags */
-#define EF_IA_64_ABI64         0x00000010      /* 64-bit ABI */
-#define EF_IA_64_ARCH          0xff000000      /* arch. version mask */
-
-/* Processor specific values for the Phdr p_type field.  */
-#define PT_IA_64_ARCHEXT       (PT_LOPROC + 0) /* arch extension bits */
-#define PT_IA_64_UNWIND                (PT_LOPROC + 1) /* ia64 unwind bits */
-
-/* Processor specific flags for the Phdr p_flags field.  */
-#define PF_IA_64_NORECOV       0x80000000      /* spec insns w/o recovery */
-
-/* Processor specific values for the Shdr sh_type field.  */
-#define SHT_IA_64_EXT          (SHT_LOPROC + 0) /* extension bits */
-#define SHT_IA_64_UNWIND       (SHT_LOPROC + 1) /* unwind bits */
-
-/* Processor specific flags for the Shdr sh_flags field.  */
-#define SHF_IA_64_SHORT                0x10000000      /* section near gp */
-#define SHF_IA_64_NORECOV      0x20000000      /* spec insns w/o recovery */
-
-/* Processor specific values for the Dyn d_tag field.  */
-#define DT_IA_64_PLT_RESERVE   (DT_LOPROC + 0)
-#define DT_IA_64_NUM           1
-
-/* IA-64 relocations.  */
-#define R_IA64_NONE            0x00    /* none */
-#define R_IA64_IMM14           0x21    /* symbol + addend, add imm14 */
-#define R_IA64_IMM22           0x22    /* symbol + addend, add imm22 */
-#define R_IA64_IMM64           0x23    /* symbol + addend, mov imm64 */
-#define R_IA64_DIR32MSB                0x24    /* symbol + addend, data4 MSB */
-#define R_IA64_DIR32LSB                0x25    /* symbol + addend, data4 LSB */
-#define R_IA64_DIR64MSB                0x26    /* symbol + addend, data8 MSB */
-#define R_IA64_DIR64LSB                0x27    /* symbol + addend, data8 LSB */
-#define R_IA64_GPREL22         0x2a    /* @gprel(sym + add), add imm22 */
-#define R_IA64_GPREL64I                0x2b    /* @gprel(sym + add), mov imm64 */
-#define R_IA64_GPREL32MSB      0x2c    /* @gprel(sym + add), data4 MSB */
-#define R_IA64_GPREL32LSB      0x2d    /* @gprel(sym + add), data4 LSB */
-#define R_IA64_GPREL64MSB      0x2e    /* @gprel(sym + add), data8 MSB */
-#define R_IA64_GPREL64LSB      0x2f    /* @gprel(sym + add), data8 LSB */
-#define R_IA64_LTOFF22         0x32    /* @ltoff(sym + add), add imm22 */
-#define R_IA64_LTOFF64I                0x33    /* @ltoff(sym + add), mov imm64 */
-#define R_IA64_PLTOFF22                0x3a    /* @pltoff(sym + add), add imm22 */
-#define R_IA64_PLTOFF64I       0x3b    /* @pltoff(sym + add), mov imm64 */
-#define R_IA64_PLTOFF64MSB     0x3e    /* @pltoff(sym + add), data8 MSB */
-#define R_IA64_PLTOFF64LSB     0x3f    /* @pltoff(sym + add), data8 LSB */
-#define R_IA64_FPTR64I         0x43    /* @fptr(sym + add), mov imm64 */
-#define R_IA64_FPTR32MSB       0x44    /* @fptr(sym + add), data4 MSB */
-#define R_IA64_FPTR32LSB       0x45    /* @fptr(sym + add), data4 LSB */
-#define R_IA64_FPTR64MSB       0x46    /* @fptr(sym + add), data8 MSB */
-#define R_IA64_FPTR64LSB       0x47    /* @fptr(sym + add), data8 LSB */
-#define R_IA64_PCREL60B                0x48    /* @pcrel(sym + add), brl */
-#define R_IA64_PCREL21B                0x49    /* @pcrel(sym + add), ptb, call */
-#define R_IA64_PCREL21M                0x4a    /* @pcrel(sym + add), chk.s */
-#define R_IA64_PCREL21F                0x4b    /* @pcrel(sym + add), fchkf */
-#define R_IA64_PCREL32MSB      0x4c    /* @pcrel(sym + add), data4 MSB */
-#define R_IA64_PCREL32LSB      0x4d    /* @pcrel(sym + add), data4 LSB */
-#define R_IA64_PCREL64MSB      0x4e    /* @pcrel(sym + add), data8 MSB */
-#define R_IA64_PCREL64LSB      0x4f    /* @pcrel(sym + add), data8 LSB */
-#define R_IA64_LTOFF_FPTR22    0x52    /* @ltoff(@fptr(s+a)), imm22 */
-#define R_IA64_LTOFF_FPTR64I   0x53    /* @ltoff(@fptr(s+a)), imm64 */
-#define R_IA64_LTOFF_FPTR32MSB 0x54    /* @ltoff(@fptr(s+a)), data4 MSB */
-#define R_IA64_LTOFF_FPTR32LSB 0x55    /* @ltoff(@fptr(s+a)), data4 LSB */
-#define R_IA64_LTOFF_FPTR64MSB 0x56    /* @ltoff(@fptr(s+a)), data8 MSB */
-#define R_IA64_LTOFF_FPTR64LSB 0x57    /* @ltoff(@fptr(s+a)), data8 LSB */
-#define R_IA64_SEGREL32MSB     0x5c    /* @segrel(sym + add), data4 MSB */
-#define R_IA64_SEGREL32LSB     0x5d    /* @segrel(sym + add), data4 LSB */
-#define R_IA64_SEGREL64MSB     0x5e    /* @segrel(sym + add), data8 MSB */
-#define R_IA64_SEGREL64LSB     0x5f    /* @segrel(sym + add), data8 LSB */
-#define R_IA64_SECREL32MSB     0x64    /* @secrel(sym + add), data4 MSB */
-#define R_IA64_SECREL32LSB     0x65    /* @secrel(sym + add), data4 LSB */
-#define R_IA64_SECREL64MSB     0x66    /* @secrel(sym + add), data8 MSB */
-#define R_IA64_SECREL64LSB     0x67    /* @secrel(sym + add), data8 LSB */
-#define R_IA64_REL32MSB                0x6c    /* data 4 + REL */
-#define R_IA64_REL32LSB                0x6d    /* data 4 + REL */
-#define R_IA64_REL64MSB                0x6e    /* data 8 + REL */
-#define R_IA64_REL64LSB                0x6f    /* data 8 + REL */
-#define R_IA64_LTV32MSB                0x74    /* symbol + addend, data4 MSB */
-#define R_IA64_LTV32LSB                0x75    /* symbol + addend, data4 LSB */
-#define R_IA64_LTV64MSB                0x76    /* symbol + addend, data8 MSB */
-#define R_IA64_LTV64LSB                0x77    /* symbol + addend, data8 LSB */
-#define R_IA64_PCREL21BI       0x79    /* @pcrel(sym + add), 21bit inst */
-#define R_IA64_PCREL22         0x7a    /* @pcrel(sym + add), 22bit inst */
-#define R_IA64_PCREL64I                0x7b    /* @pcrel(sym + add), 64bit inst */
-#define R_IA64_IPLTMSB         0x80    /* dynamic reloc, imported PLT, MSB */
-#define R_IA64_IPLTLSB         0x81    /* dynamic reloc, imported PLT, LSB */
-#define R_IA64_COPY            0x84    /* copy relocation */
-#define R_IA64_SUB             0x85    /* Addend and symbol difference */
-#define R_IA64_LTOFF22X                0x86    /* LTOFF22, relaxable.  */
-#define R_IA64_LDXMOV          0x87    /* Use of LTOFF22X.  */
-#define R_IA64_TPREL14         0x91    /* @tprel(sym + add), imm14 */
-#define R_IA64_TPREL22         0x92    /* @tprel(sym + add), imm22 */
-#define R_IA64_TPREL64I                0x93    /* @tprel(sym + add), imm64 */
-#define R_IA64_TPREL64MSB      0x96    /* @tprel(sym + add), data8 MSB */
-#define R_IA64_TPREL64LSB      0x97    /* @tprel(sym + add), data8 LSB */
-#define R_IA64_LTOFF_TPREL22   0x9a    /* @ltoff(@tprel(s+a)), imm2 */
-#define R_IA64_DTPMOD64MSB     0xa6    /* @dtpmod(sym + add), data8 MSB */
-#define R_IA64_DTPMOD64LSB     0xa7    /* @dtpmod(sym + add), data8 LSB */
-#define R_IA64_LTOFF_DTPMOD22  0xaa    /* @ltoff(@dtpmod(sym + add)), imm22 */
-#define R_IA64_DTPREL14                0xb1    /* @dtprel(sym + add), imm14 */
-#define R_IA64_DTPREL22                0xb2    /* @dtprel(sym + add), imm22 */
-#define R_IA64_DTPREL64I       0xb3    /* @dtprel(sym + add), imm64 */
-#define R_IA64_DTPREL32MSB     0xb4    /* @dtprel(sym + add), data4 MSB */
-#define R_IA64_DTPREL32LSB     0xb5    /* @dtprel(sym + add), data4 LSB */
-#define R_IA64_DTPREL64MSB     0xb6    /* @dtprel(sym + add), data8 MSB */
-#define R_IA64_DTPREL64LSB     0xb7    /* @dtprel(sym + add), data8 LSB */
-#define R_IA64_LTOFF_DTPREL22  0xba    /* @ltoff(@dtprel(s+a)), imm22 */
-
-/* SH specific declarations */
-
-/* SH relocs.  */
-#define        R_SH_NONE               0
-#define        R_SH_DIR32              1
-#define        R_SH_REL32              2
-#define        R_SH_DIR8WPN            3
-#define        R_SH_IND12W             4
-#define        R_SH_DIR8WPL            5
-#define        R_SH_DIR8WPZ            6
-#define        R_SH_DIR8BP             7
-#define        R_SH_DIR8W              8
-#define        R_SH_DIR8L              9
-#define        R_SH_SWITCH16           25
-#define        R_SH_SWITCH32           26
-#define        R_SH_USES               27
-#define        R_SH_COUNT              28
-#define        R_SH_ALIGN              29
-#define        R_SH_CODE               30
-#define        R_SH_DATA               31
-#define        R_SH_LABEL              32
-#define        R_SH_SWITCH8            33
-#define        R_SH_GNU_VTINHERIT      34
-#define        R_SH_GNU_VTENTRY        35
-#define        R_SH_TLS_GD_32          144
-#define        R_SH_TLS_LD_32          145
-#define        R_SH_TLS_LDO_32         146
-#define        R_SH_TLS_IE_32          147
-#define        R_SH_TLS_LE_32          148
-#define        R_SH_TLS_DTPMOD32       149
-#define        R_SH_TLS_DTPOFF32       150
-#define        R_SH_TLS_TPOFF32        151
-#define        R_SH_TLS_GD_MOV         152
-#define        R_SH_TLS_LDM_MOV        153
-#define        R_SH_TLS_LDO_MOV        154
-#define        R_SH_TLS_IE_MOV         155
-#define        R_SH_TLS_LE_MOV         156
-#define        R_SH_GOT32              160
-#define        R_SH_PLT32              161
-#define        R_SH_COPY               162
-#define        R_SH_GLOB_DAT           163
-#define        R_SH_JMP_SLOT           164
-#define        R_SH_RELATIVE           165
-#define        R_SH_GOTOFF             166
-#define        R_SH_GOTPC              167
-/* Keep this the last entry.  */
-#define        R_SH_NUM                256
-
-/* Additional s390 relocs */
-
-#define R_390_NONE     0              /* No reloc.  */
-#define R_390_8                1              /* Direct 8 bit.  */
-#define R_390_12       2              /* Direct 12 bit.  */
-#define R_390_16       3              /* Direct 16 bit.  */
-#define R_390_32       4              /* Direct 32 bit.  */
-#define R_390_PC32     5              /* PC relative 32 bit.  */
-#define R_390_GOT12    6              /* 12 bit GOT offset.  */
-#define R_390_GOT32    7              /* 32 bit GOT offset.  */
-#define R_390_PLT32    8              /* 32 bit PC relative PLT address.  */
-#define R_390_COPY     9              /* Copy symbol at runtime.  */
-#define R_390_GLOB_DAT 10             /* Create GOT entry.  */
-#define R_390_JMP_SLOT 11             /* Create PLT entry.  */
-#define R_390_RELATIVE 12             /* Adjust by program base.  */
-#define R_390_GOTOFF   13             /* 32 bit offset to GOT.  */
-#define R_390_GOTPC    14             /* 32 bit PC relative offset to GOT.  */
-#define R_390_GOT16    15             /* 16 bit GOT offset.  */
-#define R_390_PC16     16             /* PC relative 16 bit.  */
-#define R_390_PC16DBL  17             /* PC relative 16 bit shifted by 1.  */
-#define R_390_PLT16DBL 18             /* 16 bit PC rel. PLT shifted by 1.  */
-#define R_390_PC32DBL  19             /* PC relative 32 bit shifted by 1.  */
-#define R_390_PLT32DBL 20             /* 32 bit PC rel. PLT shifted by 1.  */
-#define R_390_GOTPCDBL 21             /* 32 bit PC rel. GOT shifted by 1.  */
-#define R_390_64       22             /* Direct 64 bit.  */
-#define R_390_PC64     23             /* PC relative 64 bit.  */
-#define R_390_GOT64    24             /* 64 bit GOT offset.  */
-#define R_390_PLT64    25             /* 64 bit PC relative PLT address.  */
-#define R_390_GOTENT   26             /* 32 bit PC rel. to GOT entry >> 1. */
-
-/* Keep this the last entry.  */
-#define R_390_NUM      27
-
-/* CRIS relocations.  */
-#define R_CRIS_NONE            0
-#define R_CRIS_8               1
-#define R_CRIS_16              2
-#define R_CRIS_32              3
-#define R_CRIS_8_PCREL         4
-#define R_CRIS_16_PCREL                5
-#define R_CRIS_32_PCREL                6
-#define R_CRIS_GNU_VTINHERIT   7
-#define R_CRIS_GNU_VTENTRY     8
-#define R_CRIS_COPY            9
-#define R_CRIS_GLOB_DAT                10
-#define R_CRIS_JUMP_SLOT       11
-#define R_CRIS_RELATIVE                12
-#define R_CRIS_16_GOT          13
-#define R_CRIS_32_GOT          14
-#define R_CRIS_16_GOTPLT       15
-#define R_CRIS_32_GOTPLT       16
-#define R_CRIS_32_GOTREL       17
-#define R_CRIS_32_PLT_GOTREL   18
-#define R_CRIS_32_PLT_PCREL    19
-
-#define R_CRIS_NUM             20
-
-/* AMD x86-64 relocations.  */
-#define R_X86_64_NONE          0       /* No reloc */
-#define R_X86_64_64            1       /* Direct 64 bit  */
-#define R_X86_64_PC32          2       /* PC relative 32 bit signed */
-#define R_X86_64_GOT32         3       /* 32 bit GOT entry */
-#define R_X86_64_PLT32         4       /* 32 bit PLT address */
-#define R_X86_64_COPY          5       /* Copy symbol at runtime */
-#define R_X86_64_GLOB_DAT      6       /* Create GOT entry */
-#define R_X86_64_JUMP_SLOT     7       /* Create PLT entry */
-#define R_X86_64_RELATIVE      8       /* Adjust by program base */
-#define R_X86_64_GOTPCREL      9       /* 32 bit signed PC relative
-                                          offset to GOT */
-#define R_X86_64_32            10      /* Direct 32 bit zero extended */
-#define R_X86_64_32S           11      /* Direct 32 bit sign extended */
-#define R_X86_64_16            12      /* Direct 16 bit zero extended */
-#define R_X86_64_PC16          13      /* 16 bit sign extended pc relative */
-#define R_X86_64_8             14      /* Direct 8 bit sign extended  */
-#define R_X86_64_PC8           15      /* 8 bit sign extended pc relative */
-#define R_X86_64_DTPMOD64      16      /* ID of module containing symbol */
-#define R_X86_64_DTPOFF64      17      /* Offset in module's TLS block */
-#define R_X86_64_TPOFF64       18      /* Offset in initial TLS block */
-#define R_X86_64_TLSGD         19      /* 32 bit signed PC relative offset
-                                          to two GOT entries for GD symbol */
-#define R_X86_64_TLSLD         20      /* 32 bit signed PC relative offset
-                                          to two GOT entries for LD symbol */
-#define R_X86_64_DTPOFF32      21      /* Offset in TLS block */
-#define r_x86_64_GOTTPOFF      22      /* 32 bit signed PC relative offset
-                                          to GOT entry for IE symbol */
-#define R_X86_64_TPOFF32       23      /* Offset in initial TLS block */
-
-#define R_X86_64_NUM           24
-
-#if GRUB_TARGET_WORDSIZE == 32
-
-typedef Elf32_Addr Elf_Addr;
-typedef Elf32_Ehdr Elf_Ehdr;
-typedef Elf32_Half Elf_Half;
-typedef Elf32_Off Elf_Off;
-typedef Elf32_Rel Elf_Rel;
-typedef Elf32_Rela Elf_Rela;
-typedef Elf32_Section Elf_Section;
-typedef Elf32_Shdr Elf_Shdr;
-typedef Elf32_Sword Elf_Sword;
-typedef Elf32_Sym Elf_Sym;
-typedef Elf32_Word Elf_Word;
-typedef Elf32_Xword Elf_Xword;
-
-#define ELF_ST_BIND(val)       ELF32_ST_BIND(val)
-#define ELF_ST_TYPE(val)       ELF32_ST_TYPE(val)
-#define ELF_R_SYM(val)         ELF32_R_SYM(val)
-#define ELF_R_TYPE(val)                ELF32_R_TYPE(val)
-#define ELF_R_INFO(sym, type)  ELF32_R_INFO(sym, type)
-
-#elif GRUB_TARGET_WORDSIZE == 64
-
-typedef Elf64_Addr Elf_Addr;
-typedef Elf64_Ehdr Elf_Ehdr;
-typedef Elf64_Half Elf_Half;
-typedef Elf64_Off Elf_Off;
-typedef Elf64_Rel Elf_Rel;
-typedef Elf64_Rela Elf_Rela;
-typedef Elf64_Section Elf_Section;
-typedef Elf64_Shdr Elf_Shdr;
-typedef Elf64_Sword Elf_Sword;
-typedef Elf64_Sym Elf_Sym;
-typedef Elf64_Word Elf_Word;
-typedef Elf64_Xword Elf_Xword;
-
-#define ELF_ST_BIND(val)       ELF64_ST_BIND (val)
-#define ELF_ST_TYPE(val)       ELF64_ST_TYPE (val)
-#define ELF_R_SYM(val)         ELF64_R_SYM(val)
-#define ELF_R_TYPE(val)                ELF64_R_TYPE(val)
-#define ELF_R_INFO(sym, type)  ELF64_R_INFO(sym, type)
-
-#endif /* GRUB_TARGET_WORDSIZE == 64 */
-
-#endif /* ! GRUB_ELF_H */
diff --git a/include/grub/elfload.h b/include/grub/elfload.h
deleted file mode 100644 (file)
index 77ee416..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#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 grub_err_t (*grub_elf32_load_hook_t)
-  (Elf32_Phdr *phdr, grub_addr_t *addr, int *load);
-typedef grub_err_t (*grub_elf64_load_hook_t)
-  (Elf64_Phdr *phdr, grub_addr_t *addr, int *load);
-
-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, Elf32_Addr *);
-grub_err_t grub_elf32_load (grub_elf_t, grub_elf32_load_hook_t, grub_addr_t *,
-                           grub_size_t *);
-
-int grub_elf_is_elf64 (grub_elf_t);
-grub_size_t grub_elf64_size (grub_elf_t, Elf64_Addr *);
-grub_err_t grub_elf64_load (grub_elf_t, grub_elf64_load_hook_t, grub_addr_t *,
-                           grub_size_t *);
-
-#endif /* ! GRUB_ELFLOAD_HEADER */
diff --git a/include/grub/env.h b/include/grub/env.h
deleted file mode 100644 (file)
index ae4fd87..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2005,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_ENV_HEADER
-#define GRUB_ENV_HEADER        1
-
-#include <grub/symbol.h>
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/menu.h>
-
-struct grub_env_var;
-
-typedef char *(*grub_env_read_hook_t) (struct grub_env_var *var,
-                                      const char *val);
-typedef char *(*grub_env_write_hook_t) (struct grub_env_var *var,
-                                       const char *val);
-
-struct grub_env_var
-{
-  char *name;
-  char *value;
-  grub_env_read_hook_t read_hook;
-  grub_env_write_hook_t write_hook;
-  struct grub_env_var *next;
-  struct grub_env_var **prevp;
-  int global;
-};
-
-grub_err_t EXPORT_FUNC(grub_env_set) (const char *name, const char *val);
-char *EXPORT_FUNC(grub_env_get) (const char *name);
-void EXPORT_FUNC(grub_env_unset) (const char *name);
-void EXPORT_FUNC(grub_env_iterate) (int (*func) (struct grub_env_var *var));
-struct grub_env_var *EXPORT_FUNC(grub_env_find) (const char *name);
-grub_err_t EXPORT_FUNC(grub_register_variable_hook) (const char *name,
-                                                    grub_env_read_hook_t read_hook,
-                                                    grub_env_write_hook_t write_hook);
-
-grub_err_t grub_env_context_open (int export);
-grub_err_t grub_env_context_close (void);
-grub_err_t grub_env_export (const char *name);
-
-void grub_env_unset_menu (void);
-grub_menu_t grub_env_get_menu (void);
-void grub_env_set_menu (grub_menu_t nmenu);
-
-#endif /* ! GRUB_ENV_HEADER */
diff --git a/include/grub/env_private.h b/include/grub/env_private.h
deleted file mode 100644 (file)
index bb00153..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2005,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_ENV_PRIVATE_HEADER
-#define GRUB_ENV_PRIVATE_HEADER        1
-
-#include <grub/env.h>
-
-/* The size of the hash table.  */
-#define        HASHSZ  13
-
-/* A hashtable for quick lookup of variables.  */
-struct grub_env_context
-{
-  /* A hash table for variables.  */
-  struct grub_env_var *vars[HASHSZ];
-
-  /* One level deeper on the stack.  */
-  struct grub_env_context *prev;
-};
-
-/* This is used for sorting only.  */
-struct grub_env_sorted_var
-{
-  struct grub_env_var *var;
-  struct grub_env_sorted_var *next;
-};
-
-extern struct grub_env_context *EXPORT_VAR(grub_current_context);
-
-#endif /* ! GRUB_ENV_PRIVATE_HEADER */
diff --git a/include/grub/err.h b/include/grub/err.h
deleted file mode 100644 (file)
index e447053..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* err.h - error numbers and prototypes */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_ERR_HEADER
-#define GRUB_ERR_HEADER        1
-
-#include <grub/symbol.h>
-
-typedef enum
-  {
-    GRUB_ERR_NONE = 0,
-    GRUB_ERR_TEST_FAILURE,
-    GRUB_ERR_BAD_MODULE,
-    GRUB_ERR_OUT_OF_MEMORY,
-    GRUB_ERR_BAD_FILE_TYPE,
-    GRUB_ERR_FILE_NOT_FOUND,
-    GRUB_ERR_FILE_READ_ERROR,
-    GRUB_ERR_BAD_FILENAME,
-    GRUB_ERR_UNKNOWN_FS,
-    GRUB_ERR_BAD_FS,
-    GRUB_ERR_BAD_NUMBER,
-    GRUB_ERR_OUT_OF_RANGE,
-    GRUB_ERR_UNKNOWN_DEVICE,
-    GRUB_ERR_BAD_DEVICE,
-    GRUB_ERR_READ_ERROR,
-    GRUB_ERR_WRITE_ERROR,
-    GRUB_ERR_UNKNOWN_COMMAND,
-    GRUB_ERR_INVALID_COMMAND,
-    GRUB_ERR_BAD_ARGUMENT,
-    GRUB_ERR_BAD_PART_TABLE,
-    GRUB_ERR_UNKNOWN_OS,
-    GRUB_ERR_BAD_OS,
-    GRUB_ERR_NO_KERNEL,
-    GRUB_ERR_BAD_FONT,
-    GRUB_ERR_NOT_IMPLEMENTED_YET,
-    GRUB_ERR_SYMLINK_LOOP,
-    GRUB_ERR_BAD_GZIP_DATA,
-    GRUB_ERR_MENU,
-    GRUB_ERR_TIMEOUT,
-    GRUB_ERR_IO,
-    GRUB_ERR_ACCESS_DENIED
-  }
-grub_err_t;
-
-extern grub_err_t EXPORT_VAR(grub_errno);
-extern char EXPORT_VAR(grub_errmsg)[];
-
-grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...);
-void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn));
-void EXPORT_FUNC(grub_error_push) (void);
-int EXPORT_FUNC(grub_error_pop) (void);
-void EXPORT_FUNC(grub_print_error) (void);
-int grub_err_printf (const char *fmt, ...)
-     __attribute__ ((format (printf, 1, 2)));
-
-#endif /* ! GRUB_ERR_HEADER */
diff --git a/include/grub/extcmd.h b/include/grub/extcmd.h
deleted file mode 100644 (file)
index 03eaba8..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_EXTCMD_HEADER
-#define GRUB_EXTCMD_HEADER     1
-
-#include <grub/lib/arg.h>
-#include <grub/command.h>
-
-struct grub_extcmd;
-
-typedef grub_err_t (*grub_extcmd_func_t) (struct grub_extcmd *cmd,
-                                         int argc, char **args);
-
-/* The argcmd description.  */
-struct grub_extcmd
-{
-  grub_command_t cmd;
-
-  grub_extcmd_func_t func;
-
-  /* The argument parser optionlist.  */
-  const struct grub_arg_option *options;
-
-  void *data;
-
-  struct grub_arg_list *state;
-};
-typedef struct grub_extcmd *grub_extcmd_t;
-
-grub_extcmd_t grub_register_extcmd (const char *name,
-                                   grub_extcmd_func_t func,
-                                   unsigned flags,
-                                   const char *summary,
-                                   const char *description,
-                                   const struct grub_arg_option *parser);
-
-void grub_unregister_extcmd (grub_extcmd_t cmd);
-
-#endif /* ! GRUB_EXTCMD_HEADER */
diff --git a/include/grub/fbblit.h b/include/grub/fbblit.h
deleted file mode 100644 (file)
index af97dfb..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_FBBLIT_HEADER
-#define GRUB_FBBLIT_HEADER     1
-
-/* NOTE: This header is private header for fb driver and should not be used
-   in other parts of the code.  */
-
-struct grub_video_fbblit_info;
-
-void
-grub_video_fbblit_replace (struct grub_video_fbblit_info *dst,
-                          struct grub_video_fbblit_info *src,
-                          int x, int y, int width, int height,
-                          int offset_x, int offset_y);
-
-void
-grub_video_fbblit_replace_directN (struct grub_video_fbblit_info *dst,
-                                  struct grub_video_fbblit_info *src,
-                                  int x, int y, int width, int height,
-                                  int offset_x, int offset_y);
-
-void
-grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
-                                            struct grub_video_fbblit_info *src,
-                                            int x, int y, int width, int height,
-                                            int offset_x, int offset_y);
-
-void
-grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst,
-                                          struct grub_video_fbblit_info *src,
-                                          int x, int y,
-                                          int width, int height,
-                                          int offset_x, int offset_y);
-
-void
-grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst,
-                                          struct grub_video_fbblit_info *src,
-                                          int x, int y,
-                                          int width, int height,
-                                          int offset_x, int offset_y);
-
-void
-grub_video_fbblit_replace_BGR888_RGB888 (struct grub_video_fbblit_info *dst,
-                                        struct grub_video_fbblit_info *src,
-                                        int x, int y,
-                                        int width, int height,
-                                        int offset_x, int offset_y);
-
-void
-grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst,
-                                          struct grub_video_fbblit_info *src,
-                                          int x, int y,
-                                          int width, int height,
-                                          int offset_x, int offset_y);
-
-void
-grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst,
-                                          struct grub_video_fbblit_info *src,
-                                          int x, int y,
-                                          int width, int height,
-                                          int offset_x, int offset_y);
-
-void
-grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
-                                         struct grub_video_fbblit_info *src,
-                                         int x, int y,
-                                         int width, int height,
-                                         int offset_x, int offset_y);
-
-void
-grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
-                                       struct grub_video_fbblit_info *src,
-                                       int x, int y, int width, int height,
-                                       int offset_x, int offset_y);
-
-void
-grub_video_fbblit_blend (struct grub_video_fbblit_info *dst,
-                        struct grub_video_fbblit_info *src,
-                        int x, int y, int width, int height,
-                        int offset_x, int offset_y);
-
-void
-grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
-                                          struct grub_video_fbblit_info *src,
-                                          int x, int y,
-                                          int width, int height,
-                                          int offset_x, int offset_y);
-
-void
-grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst,
-                                        struct grub_video_fbblit_info *src,
-                                        int x, int y,
-                                        int width, int height,
-                                        int offset_x, int offset_y);
-
-void
-grub_video_fbblit_blend_RGBA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
-                                          struct grub_video_fbblit_info *src,
-                                          int x, int y,
-                                          int width, int height,
-                                          int offset_x, int offset_y);
-
-void
-grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst,
-                                        struct grub_video_fbblit_info *src,
-                                        int x, int y,
-                                        int width, int height,
-                                        int offset_x, int offset_y);
-
-void
-grub_video_fbblit_blend_index_RGBA8888 (struct grub_video_fbblit_info *dst,
-                                       struct grub_video_fbblit_info *src,
-                                       int x, int y,
-                                       int width, int height,
-                                       int offset_x, int offset_y);
-
-void
-grub_video_fbblit_replace_32bit_1bit (struct grub_video_fbblit_info *dst,
-                                     struct grub_video_fbblit_info *src,
-                                     int x, int y,
-                                     int width, int height,
-                                     int offset_x, int offset_y);
-
-void
-grub_video_fbblit_replace_24bit_1bit (struct grub_video_fbblit_info *dst,
-                                     struct grub_video_fbblit_info *src,
-                                     int x, int y,
-                                     int width, int height,
-                                     int offset_x, int offset_y);
-
-void
-grub_video_fbblit_replace_16bit_1bit (struct grub_video_fbblit_info *dst,
-                                     struct grub_video_fbblit_info *src,
-                                     int x, int y,
-                                     int width, int height,
-                                     int offset_x, int offset_y);
-
-void
-grub_video_fbblit_replace_8bit_1bit (struct grub_video_fbblit_info *dst,
-                                    struct grub_video_fbblit_info *src,
-                                    int x, int y,
-                                    int width, int height,
-                                    int offset_x, int offset_y);
-
-void
-grub_video_fbblit_blend_XXXA8888_1bit (struct grub_video_fbblit_info *dst,
-                                      struct grub_video_fbblit_info *src,
-                                      int x, int y,
-                                      int width, int height,
-                                      int offset_x, int offset_y);
-
-void
-grub_video_fbblit_blend_XXX888_1bit (struct grub_video_fbblit_info *dst,
-                                      struct grub_video_fbblit_info *src,
-                                      int x, int y,
-                                      int width, int height,
-                                      int offset_x, int offset_y);
-
-void
-grub_video_fbblit_blend_XXX565_1bit (struct grub_video_fbblit_info *dst,
-                                    struct grub_video_fbblit_info *src,
-                                    int x, int y,
-                                    int width, int height,
-                                    int offset_x, int offset_y);
-#endif /* ! GRUB_FBBLIT_HEADER */
diff --git a/include/grub/fbfill.h b/include/grub/fbfill.h
deleted file mode 100644 (file)
index c85fa12..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_FBFILL_HEADER
-#define GRUB_FBFILL_HEADER     1
-
-/* NOTE: This header is private header for fb driver and should not be used
-   in other parts of the code.  */
-
-struct grub_video_fbblit_info;
-
-struct grub_video_fbrender_target
-{
-  /* Copy of the screen's mode info structure, except that width, height and
-     mode_type has been re-adjusted to requested render target settings.  */
-  struct grub_video_mode_info mode_info;
-
-  struct
-  {
-    unsigned int x;
-    unsigned int y;
-    unsigned int width;
-    unsigned int height;
-  } viewport;
-
-  /* Indicates whether the data has been allocated by us and must be freed
-     when render target is destroyed.  */
-  int is_allocated;
-
-  /* Pointer to data.  Can either be in video card memory or in local host's
-     memory.  */
-  grub_uint8_t *data;
-};
-
-void
-grub_video_fbfill (struct grub_video_fbblit_info *dst,
-                  grub_video_color_t color, int x, int y,
-                  int width, int height);
-
-void
-grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst,
-                           grub_video_color_t color,  int x, int y,
-                           int width, int height);
-
-void
-grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst,
-                           grub_video_color_t color, int x, int y,
-                           int width, int height);
-
-void
-grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst,
-                           grub_video_color_t color, int x, int y,
-                           int width, int height);
-
-void
-grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst,
-                          grub_video_color_t color, int x, int y,
-                          int width, int height);
-
-#endif /* ! GRUB_FBFILL_HEADER */
diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h
deleted file mode 100644 (file)
index 065ccf9..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* NOTE: This header is private header for vbe driver and should not be used
-   in other parts of the code.  */
-
-#ifndef GRUB_VBEUTIL_MACHINE_HEADER
-#define GRUB_VBEUTIL_MACHINE_HEADER    1
-
-#include <grub/types.h>
-#include <grub/video.h>
-
-struct grub_video_fbblit_info
-{
-  struct grub_video_mode_info *mode_info;
-  grub_uint8_t *data;
-};
-
-grub_uint8_t *grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
-                            unsigned int x, unsigned int y);
-
-grub_video_color_t get_pixel (struct grub_video_fbblit_info *source,
-                              unsigned int x, unsigned int y);
-
-void set_pixel (struct grub_video_fbblit_info *source,
-                unsigned int x, unsigned int y, grub_video_color_t color);
-
-#endif /* ! GRUB_VBEUTIL_MACHINE_HEADER */
diff --git a/include/grub/file.h b/include/grub/file.h
deleted file mode 100644 (file)
index 2aacf93..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_FILE_HEADER
-#define GRUB_FILE_HEADER       1
-
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/device.h>
-#include <grub/fs.h>
-
-/* File description.  */
-struct grub_file
-{
-  /* The underlying device.  */
-  grub_device_t device;
-
-  /* The underlying filesystem.  */
-  grub_fs_t fs;
-
-  /* The current offset.  */
-  grub_off_t offset;
-
-  /* The file size.  */
-  grub_off_t size;
-
-  /* Filesystem-specific data.  */
-  void *data;
-
-  /* This is called when a sector is read. Used only for a disk device.  */
-  void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                    unsigned offset, unsigned length);
-};
-typedef struct grub_file *grub_file_t;
-
-/* Get a device name from NAME.  */
-char *EXPORT_FUNC(grub_file_get_device_name) (const char *name);
-
-grub_file_t EXPORT_FUNC(grub_file_open) (const char *name);
-grub_ssize_t EXPORT_FUNC(grub_file_read) (grub_file_t file, void *buf,
-                                         grub_size_t len);
-grub_off_t EXPORT_FUNC(grub_file_seek) (grub_file_t file, grub_off_t offset);
-grub_err_t EXPORT_FUNC(grub_file_close) (grub_file_t file);
-
-static inline grub_off_t
-grub_file_size (const grub_file_t file)
-{
-  return file->size;
-}
-
-static inline grub_off_t
-grub_file_tell (const grub_file_t file)
-{
-  return file->offset;
-}
-
-#endif /* ! GRUB_FILE_HEADER */
diff --git a/include/grub/font.h b/include/grub/font.h
deleted file mode 100644 (file)
index 7c5c174..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_FONT_HEADER
-#define GRUB_FONT_HEADER       1
-
-#include <grub/types.h>
-#include <grub/video.h>
-#include <grub/file.h>
-
-/* Forward declaration of opaque structure grub_font.
-   Users only pass struct grub_font pointers to the font module functions,
-   and do not have knowledge of the structure contents.  */
-struct grub_font;
-
-/* Font type used to access font functions.  */
-typedef struct grub_font *grub_font_t;
-
-struct grub_font_node
-{
-  struct grub_font_node *next;
-  grub_font_t value;
-};
-
-/* Global font registry.  */
-extern struct grub_font_node *grub_font_list;
-
-struct grub_font_glyph
-{
-  /* Reference to the font this glyph belongs to.  */
-  grub_font_t font;
-
-  /* Glyph bitmap width in pixels.  */
-  grub_uint16_t width;
-
-  /* Glyph bitmap height in pixels.  */
-  grub_uint16_t height;
-
-  /* Glyph bitmap x offset in pixels.  Add to screen coordinate.  */
-  grub_int16_t offset_x;
-
-  /* Glyph bitmap y offset in pixels.  Subtract from screen coordinate.  */
-  grub_int16_t offset_y;
-
-  /* Number of pixels to advance to start the next character.  */
-  grub_uint16_t device_width;
-
-  /* Row-major order, packed bits (no padding; rows can break within a byte).
-     The length of the array is (width * height + 7) / 8.  Within a
-     byte, the most significant bit is the first (leftmost/uppermost) pixel.
-     Pixels are coded as bits, value 1 meaning of opaque pixel and 0 is
-     transparent.  If the length of the array does not fit byte boundary, it
-     will be padded with 0 bits to make it fit.  */
-  grub_uint8_t bitmap[0];
-};
-
-/* Initialize the font loader.
-   Must be called before any fonts are loaded or used.  */
-void grub_font_loader_init (void);
-
-/* Load a font and add it to the beginning of the global font list.
-   Returns: 0 upon success; nonzero upon failure.  */
-int grub_font_load (const char *filename);
-
-/* Get the font that has the specified name.  Font names are in the form
-   "Family Name Bold Italic 14", where Bold and Italic are optional.
-   If no font matches the name specified, the most recently loaded font
-   is returned as a fallback.  */
-grub_font_t EXPORT_FUNC (grub_font_get) (const char *font_name);
-
-const char *EXPORT_FUNC (grub_font_get_name) (grub_font_t font);
-
-int EXPORT_FUNC (grub_font_get_max_char_width) (grub_font_t font);
-
-int EXPORT_FUNC (grub_font_get_max_char_height) (grub_font_t font);
-
-int EXPORT_FUNC (grub_font_get_ascent) (grub_font_t font);
-
-int EXPORT_FUNC (grub_font_get_descent) (grub_font_t font);
-
-int EXPORT_FUNC (grub_font_get_leading) (grub_font_t font);
-
-int EXPORT_FUNC (grub_font_get_height) (grub_font_t font);
-
-int EXPORT_FUNC (grub_font_get_string_width) (grub_font_t font,
-                                             const char *str);
-
-struct grub_font_glyph *EXPORT_FUNC (grub_font_get_glyph) (grub_font_t font,
-                                                          grub_uint32_t code);
-
-struct grub_font_glyph *EXPORT_FUNC (grub_font_get_glyph_with_fallback) (grub_font_t font,
-                                                                        grub_uint32_t code);
-
-grub_err_t EXPORT_FUNC (grub_font_draw_glyph) (struct grub_font_glyph *glyph,
-                                              grub_video_color_t color,
-                                              int left_x, int baseline_y);
-
-grub_err_t EXPORT_FUNC (grub_font_draw_string) (const char *str,
-                                               grub_font_t font,
-                                               grub_video_color_t color,
-                                               int left_x, int baseline_y);
-
-#endif /* ! GRUB_FONT_HEADER */
diff --git a/include/grub/fontformat.h b/include/grub/fontformat.h
deleted file mode 100644 (file)
index b506058..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2010 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_FONT_FORMAT_HEADER
-#define GRUB_FONT_FORMAT_HEADER        1
-
-/* FONT_FORMAT_PFF2_MAGIC use only 4 relevants bytes and the \0.  */
-#define FONT_FORMAT_PFF2_MAGIC "PFF2"
-#define FONT_FORMAT_SECTION_NAMES_FILE "FILE"
-#define FONT_FORMAT_SECTION_NAMES_FONT_NAME "NAME"
-#define FONT_FORMAT_SECTION_NAMES_POINT_SIZE "PTSZ"
-#define FONT_FORMAT_SECTION_NAMES_WEIGHT "WEIG"
-#define FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH "MAXW"
-#define FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT "MAXH"
-#define FONT_FORMAT_SECTION_NAMES_ASCENT "ASCE"
-#define FONT_FORMAT_SECTION_NAMES_DESCENT "DESC"
-#define FONT_FORMAT_SECTION_NAMES_CHAR_INDEX "CHIX"
-#define FONT_FORMAT_SECTION_NAMES_DATA "DATA"
-#define FONT_FORMAT_SECTION_NAMES_FAMILY "FAMI"
-#define FONT_FORMAT_SECTION_NAMES_SLAN "SLAN"
-
-#endif /* ! GRUB_FONT_FORMAT_HEADER */
-
diff --git a/include/grub/fs.h b/include/grub/fs.h
deleted file mode 100644 (file)
index 45f5157..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* fs.h - filesystem manager */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_FS_HEADER
-#define GRUB_FS_HEADER 1
-
-#include <grub/device.h>
-#include <grub/symbol.h>
-#include <grub/types.h>
-
-/* Forward declaration is required, because of mutual reference.  */
-struct grub_file;
-
-struct grub_dirhook_info
-{
-  int dir:1;
-  int mtimeset:1;
-  int case_insensitive:1;
-  grub_int32_t mtime;
-};
-
-/* Filesystem descriptor.  */
-struct grub_fs
-{
-  /* My name.  */
-  const char *name;
-
-  /* Call HOOK with each file under DIR.  */
-  grub_err_t (*dir) (grub_device_t device, const char *path,
-                    int (*hook) (const char *filename,
-                                 const struct grub_dirhook_info *info));
-
-  /* Open a file named NAME and initialize FILE.  */
-  grub_err_t (*open) (struct grub_file *file, const char *name);
-
-  /* Read LEN bytes data from FILE into BUF.  */
-  grub_ssize_t (*read) (struct grub_file *file, char *buf, grub_size_t len);
-
-  /* Close the file FILE.  */
-  grub_err_t (*close) (struct grub_file *file);
-
-  /* Return the label of the device DEVICE in LABEL.  The label is
-     returned in a grub_malloc'ed buffer and should be freed by the
-     caller.  */
-  grub_err_t (*label) (grub_device_t device, char **label);
-
-  /* Return the uuid of the device DEVICE in UUID.  The uuid is
-     returned in a grub_malloc'ed buffer and should be freed by the
-     caller.  */
-  grub_err_t (*uuid) (grub_device_t device, char **uuid);
-
-  /* Get writing time of filesystem. */
-  grub_err_t (*mtime) (grub_device_t device, grub_int32_t *timebuf);
-
-#ifdef GRUB_UTIL
-  /* Whether this filesystem reserves first sector for DOS-style boot.  */
-  int reserved_first_sector;
-#endif
-
-  /* The next filesystem.  */
-  struct grub_fs *next;
-};
-typedef struct grub_fs *grub_fs_t;
-
-/* This is special, because block lists are not files in usual sense.  */
-extern struct grub_fs grub_fs_blocklist;
-
-/* This hook is used to automatically load filesystem modules.
-   If this hook loads a module, return non-zero. Otherwise return zero.
-   The newly loaded filesystem is assumed to be inserted into the head of
-   the linked list GRUB_FS_LIST through the function grub_fs_register.  */
-typedef int (*grub_fs_autoload_hook_t) (void);
-extern grub_fs_autoload_hook_t EXPORT_VAR(grub_fs_autoload_hook);
-
-void EXPORT_FUNC(grub_fs_register) (grub_fs_t fs);
-void EXPORT_FUNC(grub_fs_unregister) (grub_fs_t fs);
-void EXPORT_FUNC(grub_fs_iterate) (int (*hook) (const grub_fs_t fs));
-grub_fs_t EXPORT_FUNC(grub_fs_probe) (grub_device_t device);
-
-#endif /* ! GRUB_FS_HEADER */
diff --git a/include/grub/fshelp.h b/include/grub/fshelp.h
deleted file mode 100644 (file)
index 42d8da5..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/* fshelp.h -- Filesystem helper functions */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2005,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_FSHELP_HEADER
-#define GRUB_FSHELP_HEADER     1
-
-#include <grub/types.h>
-#include <grub/symbol.h>
-#include <grub/err.h>
-
-typedef struct grub_fshelp_node *grub_fshelp_node_t;
-
-#define GRUB_FSHELP_CASE_INSENSITIVE   0x100
-#define GRUB_FSHELP_TYPE_MASK  0xff
-#define GRUB_FSHELP_FLAGS_MASK 0x100
-
-enum grub_fshelp_filetype
-  {
-    GRUB_FSHELP_UNKNOWN,
-    GRUB_FSHELP_REG,
-    GRUB_FSHELP_DIR,
-    GRUB_FSHELP_SYMLINK
-  };
-
-/* Lookup the node PATH.  The node ROOTNODE describes the root of the
-   directory tree.  The node found is returned in FOUNDNODE, which is
-   either a ROOTNODE or a new malloc'ed node.  ITERATE_DIR is used to
-   iterate over all directory entries in the current node.
-   READ_SYMLINK is used to read the symlink if a node is a symlink.
-   EXPECTTYPE is the type node that is expected by the called, an
-   error is generated if the node is not of the expected type.  Make
-   sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required
-   because GCC has a nasty bug when using regparm=3.  */
-grub_err_t
-EXPORT_FUNC(grub_fshelp_find_file) (const char *path,
-                                   grub_fshelp_node_t rootnode,
-                                   grub_fshelp_node_t *foundnode,
-                                   int (*iterate_dir) (grub_fshelp_node_t dir,
-                                                       int NESTED_FUNC_ATTR
-                                                       (*hook) (const char *filename,
-                                                                enum grub_fshelp_filetype filetype,
-                                                                grub_fshelp_node_t node)),
-                                   char *(*read_symlink) (grub_fshelp_node_t node),
-                                   enum grub_fshelp_filetype expect);
-
-
-/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF,
-   beginning with the block POS.  READ_HOOK should be set before
-   reading a block from the file.  GET_BLOCK is used to translate file
-   blocks to disk blocks.  The file is FILESIZE bytes big and the
-   blocks have a size of LOG2BLOCKSIZE (in log2).  */
-grub_ssize_t
-EXPORT_FUNC(grub_fshelp_read_file) (grub_disk_t disk, grub_fshelp_node_t node,
-                                   void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
-                                                                        unsigned offset,
-                                                                        unsigned length),
-                                   grub_off_t pos, grub_size_t len, char *buf,
-                                   grub_disk_addr_t (*get_block) (grub_fshelp_node_t node,
-                                                                   grub_disk_addr_t block),
-                                   grub_off_t filesize, int log2blocksize);
-
-unsigned int
-EXPORT_FUNC(grub_fshelp_log2blksize) (unsigned int blksize,
-                                     unsigned int *pow);
-
-#endif /* ! GRUB_FSHELP_HEADER */
diff --git a/include/grub/gfxmenu_model.h b/include/grub/gfxmenu_model.h
deleted file mode 100644 (file)
index 8b13789..0000000
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/include/grub/gfxmenu_view.h b/include/grub/gfxmenu_view.h
deleted file mode 100644 (file)
index 7cbfa89..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/* gfxmenu_view.h - gfxmenu view interface. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_GFXMENU_VIEW_HEADER
-#define GRUB_GFXMENU_VIEW_HEADER 1
-
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/menu.h>
-#include <grub/font.h>
-#include <grub/gfxwidgets.h>
-
-struct grub_gfxmenu_view;   /* Forward declaration of opaque type.  */
-typedef struct grub_gfxmenu_view *grub_gfxmenu_view_t;
-
-
-grub_gfxmenu_view_t grub_gfxmenu_view_new (const char *theme_path,
-                                          int width, int height);
-
-void grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view);
-
-/* Set properties on the view based on settings from the specified
-   theme file.  */
-grub_err_t grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view,
-                                         const char *theme_path);
-
-grub_err_t grub_gui_recreate_box (grub_gfxmenu_box_t *boxptr,
-                                  const char *pattern, const char *theme_dir);
-
-void grub_gfxmenu_view_draw (grub_gfxmenu_view_t view);
-
-void
-grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view);
-
-void
-grub_gfxmenu_redraw_timeout (grub_gfxmenu_view_t view);
-
-void
-grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view,
-                         const grub_video_rect_t *region);
-
-void 
-grub_gfxmenu_clear_timeout (void *data);
-void 
-grub_gfxmenu_print_timeout (int timeout, void *data);
-void
-grub_gfxmenu_set_chosen_entry (int entry, void *data);
-
-/* Implementation details -- this should not be used outside of the
-   view itself.  */
-
-#include <grub/video.h>
-#include <grub/bitmap.h>
-#include <grub/gui.h>
-#include <grub/gfxwidgets.h>
-#include <grub/icon_manager.h>
-
-/* Definition of the private representation of the view.  */
-struct grub_gfxmenu_view
-{
-  grub_video_rect_t screen;
-
-  grub_font_t title_font;
-  grub_font_t message_font;
-  char *terminal_font_name;
-  grub_gui_color_t title_color;
-  grub_gui_color_t message_color;
-  grub_gui_color_t message_bg_color;
-  struct grub_video_bitmap *desktop_image;
-  grub_gui_color_t desktop_color;
-  grub_gfxmenu_box_t terminal_box;
-  char *title_text;
-  char *progress_message_text;
-  char *theme_path;
-
-  grub_gui_container_t canvas;
-
-  int double_repaint;
-
-  int selected;
-
-  grub_video_rect_t progress_message_frame;
-
-  grub_menu_t menu;
-
-  int nested;
-
-  int first_timeout;
-};
-
-#endif /* ! GRUB_GFXMENU_VIEW_HEADER */
diff --git a/include/grub/gfxterm.h b/include/grub/gfxterm.h
deleted file mode 100644 (file)
index 295354b..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_GFXTERM_HEADER
-#define GRUB_GFXTERM_HEADER    1
-
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/term.h>
-#include <grub/video.h>
-
-grub_err_t
-EXPORT_FUNC (grub_gfxterm_set_window) (struct grub_video_render_target *target,
-                                      int x, int y, int width, int height,
-                                      int double_repaint,
-                                      const char *font_name, int border_width);
-
-typedef void (*grub_gfxterm_repaint_callback_t)(int x, int y,
-                                                int width, int height);
-
-void grub_gfxterm_set_repaint_callback (grub_gfxterm_repaint_callback_t func);
-
-void EXPORT_FUNC (grub_gfxterm_schedule_repaint) (void);
-
-grub_err_t EXPORT_FUNC (grub_gfxterm_fullscreen) (void);
-
-extern void (*EXPORT_VAR (grub_gfxterm_decorator_hook)) (void);
-
-#endif /* ! GRUB_GFXTERM_HEADER */
diff --git a/include/grub/gfxwidgets.h b/include/grub/gfxwidgets.h
deleted file mode 100644 (file)
index f9678bf..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/* gfxwidgets.h - Widgets for the graphical menu (gfxmenu).  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_GFXWIDGETS_HEADER
-#define GRUB_GFXWIDGETS_HEADER 1
-
-#include <grub/video.h>
-
-typedef struct grub_gfxmenu_box *grub_gfxmenu_box_t;
-
-struct grub_gfxmenu_box
-{
-  /* The size of the content.  */
-  int content_width;
-  int content_height;
-
-  struct grub_video_bitmap **raw_pixmaps;
-  struct grub_video_bitmap **scaled_pixmaps;
-
-  void (*draw) (grub_gfxmenu_box_t self, int x, int y);
-  void (*set_content_size) (grub_gfxmenu_box_t self,
-                            int width, int height);
-  int (*get_left_pad) (grub_gfxmenu_box_t self);
-  int (*get_top_pad) (grub_gfxmenu_box_t self);
-  int (*get_right_pad) (grub_gfxmenu_box_t self);
-  int (*get_bottom_pad) (grub_gfxmenu_box_t self);
-  void (*destroy) (grub_gfxmenu_box_t self);
-};
-
-grub_gfxmenu_box_t grub_gfxmenu_create_box (const char *pixmaps_prefix,
-                                            const char *pixmaps_suffix);
-
-#endif /* ! GRUB_GFXWIDGETS_HEADER */
diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h
deleted file mode 100644 (file)
index 428ceb1..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_GPT_PARTITION_HEADER
-#define GRUB_GPT_PARTITION_HEADER      1
-
-#include <grub/types.h>
-
-struct grub_gpt_part_type
-{
-  grub_uint32_t data1;
-  grub_uint16_t data2;
-  grub_uint16_t data3;
-  grub_uint8_t data4[8];
-} __attribute__ ((aligned(8)));
-typedef struct grub_gpt_part_type grub_gpt_part_type_t;
-
-#define GRUB_GPT_PARTITION_TYPE_EMPTY \
-  { 0x0, 0x0, 0x0, \
-    { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } \
-  }
-
-#define GRUB_GPT_PARTITION_TYPE_BIOS_BOOT \
-  { grub_cpu_to_le32 (0x21686148), grub_cpu_to_le16 (0x6449), grub_cpu_to_le16 (0x6e6f), \
-    { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } \
-  }
-
-struct grub_gpt_header
-{
-  grub_uint8_t magic[8];
-  grub_uint32_t version;
-  grub_uint32_t headersize;
-  grub_uint32_t crc32;
-  grub_uint32_t unused1;
-  grub_uint64_t primary;
-  grub_uint64_t backup;
-  grub_uint64_t start;
-  grub_uint64_t end;
-  grub_uint8_t guid[16];
-  grub_uint64_t partitions;
-  grub_uint32_t maxpart;
-  grub_uint32_t partentry_size;
-  grub_uint32_t partentry_crc32;
-} __attribute__ ((packed));
-
-struct grub_gpt_partentry
-{
-  grub_gpt_part_type_t type;
-  grub_uint8_t guid[16];
-  grub_uint64_t start;
-  grub_uint64_t end;
-  grub_uint64_t attrib;
-  char name[72];
-} __attribute__ ((packed));
-
-#endif /* ! GRUB_GPT_PARTITION_HEADER */
diff --git a/include/grub/gui.h b/include/grub/gui.h
deleted file mode 100644 (file)
index 7bd71ac..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/* gui.h - GUI components header file. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/video.h>
-#include <grub/bitmap.h>
-#include <grub/gfxmenu_view.h>
-
-#ifndef GRUB_GUI_H
-#define GRUB_GUI_H 1
-
-/* A representation of a color.  Unlike grub_video_color_t, this
-   representation is independent of any video mode specifics.  */
-typedef struct grub_gui_color
-{
-  grub_uint8_t red;
-  grub_uint8_t green;
-  grub_uint8_t blue;
-  grub_uint8_t alpha;
-} grub_gui_color_t;
-
-typedef struct grub_gui_component *grub_gui_component_t;
-typedef struct grub_gui_container *grub_gui_container_t;
-typedef struct grub_gui_list *grub_gui_list_t;
-
-typedef void (*grub_gui_component_callback) (grub_gui_component_t component,
-                                             void *userdata);
-
-/* Component interface.  */
-
-struct grub_gui_component_ops
-{
-  void (*destroy) (void *self);
-  const char * (*get_id) (void *self);
-  int (*is_instance) (void *self, const char *type);
-  void (*paint) (void *self, const grub_video_rect_t *bounds);
-  void (*set_parent) (void *self, grub_gui_container_t parent);
-  grub_gui_container_t (*get_parent) (void *self);
-  void (*set_bounds) (void *self, const grub_video_rect_t *bounds);
-  void (*get_bounds) (void *self, grub_video_rect_t *bounds);
-  void (*get_minimal_size) (void *self, unsigned *width, unsigned *height);
-  grub_err_t (*set_property) (void *self, const char *name, const char *value);
-  void (*repaint) (void *self, int second_pass);
-};
-
-struct grub_gui_container_ops
-{
-  void (*add) (void *self, grub_gui_component_t comp);
-  void (*remove) (void *self, grub_gui_component_t comp);
-  void (*iterate_children) (void *self,
-                            grub_gui_component_callback cb, void *userdata);
-};
-
-struct grub_gui_list_ops
-{
-  void (*set_view_info) (void *self,
-                         grub_gfxmenu_view_t view);
-};
-
-struct grub_gui_progress_ops
-{
-  void (*set_state) (void *self, int visible, int start, int current, int end);
-};
-
-typedef signed grub_fixed_signed_t;
-#define GRUB_FIXED_1 0x10000
-
-static inline signed
-grub_fixed_sfs_divide (signed a, grub_fixed_signed_t b)
-{
-  return (a * GRUB_FIXED_1) / b;
-}
-
-static inline grub_fixed_signed_t
-grub_fixed_fsf_divide (grub_fixed_signed_t a, signed b)
-{
-  return a / b;
-}
-
-static inline signed
-grub_fixed_sfs_multiply (signed a, grub_fixed_signed_t b)
-{
-  return (a * b) / GRUB_FIXED_1;
-}
-
-static inline signed
-grub_fixed_to_signed (grub_fixed_signed_t in)
-{
-  return in / GRUB_FIXED_1;
-}
-
-static inline grub_fixed_signed_t
-grub_signed_to_fixed (signed in)
-{
-  return in * GRUB_FIXED_1;
-}
-
-struct grub_gui_component
-{
-  struct grub_gui_component_ops *ops;
-  signed x;
-  grub_fixed_signed_t xfrac;
-  signed y;
-  grub_fixed_signed_t yfrac;
-  signed w;
-  grub_fixed_signed_t wfrac;
-  signed h;
-  grub_fixed_signed_t hfrac;
-};
-
-struct grub_gui_progress
-{
-  struct grub_gui_component component;
-  struct grub_gui_progress_ops *ops;
-};
-
-struct grub_gui_container
-{
-  struct grub_gui_component component;
-  struct grub_gui_container_ops *ops;
-};
-
-struct grub_gui_list
-{
-  struct grub_gui_component component;
-  struct grub_gui_list_ops *ops;
-};
-
-
-/* Interfaces to concrete component classes.  */
-
-grub_gui_container_t grub_gui_canvas_new (void);
-grub_gui_container_t grub_gui_vbox_new (void);
-grub_gui_container_t grub_gui_hbox_new (void);
-grub_gui_component_t grub_gui_label_new (void);
-grub_gui_component_t grub_gui_image_new (void);
-grub_gui_component_t grub_gui_progress_bar_new (void);
-grub_gui_component_t grub_gui_list_new (void);
-grub_gui_component_t grub_gui_circular_progress_new (void);
-
-/* Manipulation functions.  */
-
-/* Visit all components with the specified ID.  */
-void grub_gui_find_by_id (grub_gui_component_t root,
-                          const char *id,
-                          grub_gui_component_callback cb,
-                          void *userdata);
-
-/* Visit all components.  */
-void grub_gui_iterate_recursively (grub_gui_component_t root,
-                                   grub_gui_component_callback cb,
-                                   void *userdata);
-
-/* Helper functions.  */
-
-static __inline void
-grub_gui_save_viewport (grub_video_rect_t *r)
-{
-  grub_video_get_viewport ((unsigned *) &r->x,
-                           (unsigned *) &r->y,
-                           (unsigned *) &r->width,
-                           (unsigned *) &r->height);
-}
-
-static __inline void
-grub_gui_restore_viewport (const grub_video_rect_t *r)
-{
-  grub_video_set_viewport (r->x, r->y, r->width, r->height);
-}
-
-/* Set a new viewport relative the the current one, saving the current
-   viewport in OLD so it can be later restored.  */
-static __inline void
-grub_gui_set_viewport (const grub_video_rect_t *r, grub_video_rect_t *old)
-{
-  grub_gui_save_viewport (old);
-  grub_video_set_viewport (old->x + r->x,
-                           old->y + r->y,
-                           r->width,
-                           r->height);
-}
-
-static __inline grub_gui_color_t
-grub_gui_color_rgb (int r, int g, int b)
-{
-  grub_gui_color_t c;
-  c.red = r;
-  c.green = g;
-  c.blue = b;
-  c.alpha = 255;
-  return c;
-}
-
-static __inline grub_video_color_t
-grub_gui_map_color (grub_gui_color_t c)
-{
-  return grub_video_map_rgba (c.red, c.green, c.blue, c.alpha);
-}
-
-static inline int
-grub_video_have_common_points (const grub_video_rect_t *a,
-                              const grub_video_rect_t *b)
-{
-  if (!((a->x <= b->x && b->x <= a->x + a->width)
-       || (b->x <= a->x && a->x <= b->x + b->width)))
-    return 0;
-  if (!((a->y <= b->y && b->y <= a->y + a->height)
-       || (b->y <= a->y && a->y <= b->y + b->height)))
-    return 0;
-  return 1;
-}
-
-#endif /* ! GRUB_GUI_H */
diff --git a/include/grub/gui_string_util.h b/include/grub/gui_string_util.h
deleted file mode 100644 (file)
index 1baa2ee..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* gui_string_util.h - String utilities for the graphical menu interface. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_GUI_STRING_UTIL_HEADER
-#define GRUB_GUI_STRING_UTIL_HEADER 1
-
-#include <grub/types.h>
-#include <grub/gui.h>
-
-char *grub_new_substring (const char *buf,
-                          grub_size_t start, grub_size_t end);
-
-char *grub_resolve_relative_path (const char *base, const char *path);
-
-char *grub_get_dirname (const char *file_path);
-
-int grub_gui_get_named_color (const char *name, grub_gui_color_t *color);
-
-grub_err_t grub_gui_parse_color (const char *s, grub_gui_color_t *color);
-
-#endif /* GRUB_GUI_STRING_UTIL_HEADER */
diff --git a/include/grub/gzio.h b/include/grub/gzio.h
deleted file mode 100644 (file)
index cd7f397..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* gzio.h - prototypes for gzio */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_GZIO_H
-#define GRUB_GZIO_H    1
-
-#include <grub/file.h>
-
-grub_file_t grub_gzio_open (grub_file_t io, int transparent);
-grub_file_t grub_gzfile_open (const char *name, int transparent);
-
-#endif /* ! GRUB_GZIO_H */
diff --git a/include/grub/handler.h b/include/grub/handler.h
deleted file mode 100644 (file)
index 77dd7d9..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* handler.h - header for grub handler */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_HANDLER_HEADER
-#define GRUB_HANDLER_HEADER 1
-
-#include <grub/list.h>
-#include <grub/err.h>
-
-struct grub_handler
-{
-  struct grub_handler *next;
-  const char *name;
-  grub_err_t (*init) (void);
-  grub_err_t (*fini) (void);
-};
-typedef struct grub_handler *grub_handler_t;
-
-struct grub_handler_class
-{
-  struct grub_handler_class *next;
-  const char *name;
-  grub_handler_t handler_list;
-  grub_handler_t cur_handler;
-};
-typedef struct grub_handler_class *grub_handler_class_t;
-
-extern grub_handler_class_t EXPORT_VAR(grub_handler_class_list);
-
-void EXPORT_FUNC(grub_handler_register) (grub_handler_class_t class,
-                                        grub_handler_t handler);
-void EXPORT_FUNC(grub_handler_unregister) (grub_handler_class_t class,
-                                          grub_handler_t handler);
-grub_err_t EXPORT_FUNC(grub_handler_set_current) (grub_handler_class_t class,
-                                                 grub_handler_t handler);
-
-#define GRUB_AS_HANDLER(ptr) \
-  ((GRUB_FIELD_MATCH (ptr, grub_handler_t, next) && \
-    GRUB_FIELD_MATCH (ptr, grub_handler_t, name) && \
-    GRUB_FIELD_MATCH (ptr, grub_handler_t, init) && \
-    GRUB_FIELD_MATCH (ptr, grub_handler_t, fini)) ? \
-   (grub_handler_t) ptr : grub_bad_type_cast ())
-
-#endif /* ! GRUB_HANDLER_HEADER */
diff --git a/include/grub/hfs.h b/include/grub/hfs.h
deleted file mode 100644 (file)
index d93b9a2..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_HFS_HEADER
-#define GRUB_HFS_HEADER        1
-
-#include <grub/types.h>
-
-#define GRUB_HFS_MAGIC         0x4244
-
-/* A single extent.  A file consists of one or more extents.  */
-struct grub_hfs_extent
-{
-  /* The first physical block.  */
-  grub_uint16_t first_block;
-  grub_uint16_t count;
-};
-
-/* HFS stores extents in groups of 3.  */
-typedef struct grub_hfs_extent grub_hfs_datarecord_t[3];
-
-/* The HFS superblock (The official name is `Master Directory
-   Block').  */
-struct grub_hfs_sblock
-{
-  grub_uint16_t magic;
-  grub_uint8_t unused[18];
-  grub_uint32_t blksz;
-  grub_uint8_t unused2[4];
-  grub_uint16_t first_block;
-  grub_uint8_t unused4[6];
-
-  /* A pascal style string that holds the volumename.  */
-  grub_uint8_t volname[28];
-
-  grub_uint8_t unused5[52];
-  grub_uint64_t num_serial;
-  grub_uint16_t embed_sig;
-  struct grub_hfs_extent embed_extent;
-  grub_uint8_t unused6[4];
-  grub_hfs_datarecord_t extent_recs;
-  grub_uint32_t catalog_size;
-  grub_hfs_datarecord_t catalog_recs;
-} __attribute__ ((packed));
-
-#endif /* ! GRUB_HFS_HEADER */
diff --git a/include/grub/i18n.h b/include/grub/i18n.h
deleted file mode 100644 (file)
index 9e7f52d..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef        GRUB_I18N_H
-#define        GRUB_I18N_H     1
-
-#include <config.h>
-#include <grub/symbol.h>
-
-extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s);
-
-/* NLS can be disabled through the configure --disable-nls option.  */
-#if (defined(ENABLE_NLS) && ENABLE_NLS)
-
-# ifdef GRUB_UTIL
-
-#  include <locale.h>
-#  include <libintl.h>
-
-# endif /* GRUB_UTIL */
-
-#else /* ! (defined(ENABLE_NLS) && ENABLE_NLS) */
-
-/* Disabled NLS.
-   The casts to 'const char *' serve the purpose of producing warnings
-   for invalid uses of the value returned from these functions.
-   On pre-ANSI systems without 'const', the config.h file is supposed to
-   contain "#define const".  */
-# ifdef GRUB_UTIL
-#  define gettext(Msgid) ((const char *) (Msgid))
-# else
-#  define grub_gettext(str) ((const char *) (str))
-# endif /* GRUB_UTIL */
-
-#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */
-
-#ifdef GRUB_UTIL
-# define _(str) gettext(str)
-#else
-# define _(str) grub_gettext(str)
-#endif /* GRUB_UTIL */
-
-#define N_(str) str
-
-#endif /* GRUB_I18N_H */
diff --git a/include/grub/i386/at_keyboard.h b/include/grub/i386/at_keyboard.h
deleted file mode 100644 (file)
index da4e806..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_CPU_AT_KEYBOARD_HEADER
-#define GRUB_CPU_AT_KEYBOARD_HEADER    1
-
-#define KEYBOARD_REG_DATA      0x60
-#define KEYBOARD_REG_STATUS    0x64
-
-#endif
diff --git a/include/grub/i386/bsd.h b/include/grub/i386/bsd.h
deleted file mode 100644 (file)
index 4d55f04..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_BSD_CPU_HEADER
-#define GRUB_BSD_CPU_HEADER    1
-
-#include <grub/types.h>
-#include <grub/i386/freebsd_reboot.h>
-#include <grub/i386/netbsd_reboot.h>
-#include <grub/i386/openbsd_reboot.h>
-#include <grub/i386/freebsd_linker.h>
-#include <grub/i386/netbsd_bootinfo.h>
-#include <grub/i386/openbsd_bootarg.h>
-
-
-enum bsd_kernel_types
-  {
-    KERNEL_TYPE_NONE,
-    KERNEL_TYPE_FREEBSD,
-    KERNEL_TYPE_OPENBSD,
-    KERNEL_TYPE_NETBSD,
-  };
-
-#define GRUB_BSD_TEMP_BUFFER   0x80000
-
-#define FREEBSD_B_DEVMAGIC     OPENBSD_B_DEVMAGIC
-#define FREEBSD_B_SLICESHIFT   OPENBSD_B_CTRLSHIFT
-#define FREEBSD_B_UNITSHIFT    OPENBSD_B_UNITSHIFT
-#define FREEBSD_B_PARTSHIFT    OPENBSD_B_PARTSHIFT
-#define FREEBSD_B_TYPESHIFT    OPENBSD_B_TYPESHIFT
-
-#define FREEBSD_MODTYPE_KERNEL         "elf kernel"
-#define FREEBSD_MODTYPE_KERNEL64       "elf64 kernel"
-#define FREEBSD_MODTYPE_ELF_MODULE     "elf module"
-#define FREEBSD_MODTYPE_ELF_MODULE_OBJ "elf obj module"
-#define FREEBSD_MODTYPE_RAW            "raw"
-
-#define FREEBSD_BOOTINFO_VERSION 1
-
-struct grub_freebsd_bootinfo
-{
-  grub_uint32_t version;
-  grub_uint8_t unused1[44];
-  grub_uint32_t length;
-  grub_uint8_t unused2;
-  grub_uint8_t boot_device;
-  grub_uint8_t unused3[18];
-  grub_uint32_t kern_end;
-  grub_uint32_t environment;
-  grub_uint32_t tags;
-} __attribute__ ((packed));
-
-struct grub_openbsd_bios_mmap
-{
-  grub_uint64_t addr;
-  grub_uint64_t len;
-#define        OPENBSD_MMAP_AVAILABLE  1
-#define        OPENBSD_MMAP_RESERVED 2
-#define        OPENBSD_MMAP_ACPI       3
-#define        OPENBSD_MMAP_NVS        4
-  grub_uint32_t type;
-};
-
-void grub_unix_real_boot (grub_addr_t entry, ...)
-     __attribute__ ((cdecl,noreturn));
-grub_err_t grub_freebsd_load_elfmodule32 (grub_file_t file, int argc,
-                                         char *argv[], grub_addr_t *kern_end);
-grub_err_t grub_freebsd_load_elfmodule_obj64 (grub_file_t file, int argc,
-                                             char *argv[],
-                                             grub_addr_t *kern_end);
-grub_err_t grub_freebsd_load_elf_meta32 (grub_file_t file,
-                                        grub_addr_t *kern_end);
-grub_err_t grub_freebsd_load_elf_meta64 (grub_file_t file,
-                                        grub_addr_t *kern_end);
-
-grub_err_t grub_freebsd_add_meta (grub_uint32_t type, void *data,
-                                 grub_uint32_t len);
-grub_err_t grub_freebsd_add_meta_module (char *filename, char *type,
-                                        int argc, char **argv,
-                                        grub_addr_t addr, grub_uint32_t size);
-
-extern grub_uint8_t grub_bsd64_trampoline_start, grub_bsd64_trampoline_end;
-extern grub_uint32_t grub_bsd64_trampoline_selfjump;
-extern grub_uint32_t grub_bsd64_trampoline_gdt;
-
-#endif /* ! GRUB_BSD_CPU_HEADER */
diff --git a/include/grub/i386/cmos.h b/include/grub/i386/cmos.h
deleted file mode 100644 (file)
index 8b1fa35..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef        GRUB_CPU_CMOS_H
-#define        GRUB_CPU_CMOS_H 1
-
-#include <grub/types.h>
-#include <grub/cpu/io.h>
-
-#define GRUB_CMOS_ADDR_REG     0x70
-#define GRUB_CMOS_DATA_REG     0x71
-
-#endif /* GRUB_CPU_CMOS_H */
diff --git a/include/grub/i386/coreboot/boot.h b/include/grub/i386/coreboot/boot.h
deleted file mode 100644 (file)
index 6cd23aa..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/pc/boot.h>
diff --git a/include/grub/i386/coreboot/console.h b/include/grub/i386/coreboot/console.h
deleted file mode 100644 (file)
index 2ffef73..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MACHINE_CONSOLE_HEADER
-#define GRUB_MACHINE_CONSOLE_HEADER    1
-
-void grub_vga_text_init (void);
-void grub_vga_text_fini (void);
-
-#endif /* ! GRUB_MACHINE_CONSOLE_HEADER */
diff --git a/include/grub/i386/coreboot/init.h b/include/grub/i386/coreboot/init.h
deleted file mode 100644 (file)
index e670074..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_INIT_I386_LINUXBIOS_HEADER
-#define GRUB_INIT_I386_LINUXBIOS_HEADER                1
-
-#include <grub/symbol.h>
-#include <grub/i386/pc/memory.h>
-
-void EXPORT_FUNC(grub_stop) (void) __attribute__ ((noreturn));
-void EXPORT_FUNC(grub_stop_floppy) (void);
-
-#endif
diff --git a/include/grub/i386/coreboot/kernel.h b/include/grub/i386/coreboot/kernel.h
deleted file mode 100644 (file)
index fb60668..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_KERNEL_MACHINE_HEADER
-#define GRUB_KERNEL_MACHINE_HEADER     1
-
-#include <grub/symbol.h>
-
-#ifndef ASM_FILE
-extern char grub_prefix[];
-#endif
-
-#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/include/grub/i386/coreboot/loader.h b/include/grub/i386/coreboot/loader.h
deleted file mode 100644 (file)
index d3f36bb..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/cpu/loader.h>
diff --git a/include/grub/i386/coreboot/memory.h b/include/grub/i386/coreboot/memory.h
deleted file mode 100644 (file)
index 664086a..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/* memory.h - describe the memory map */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _GRUB_MEMORY_MACHINE_LB_HEADER
-#define _GRUB_MEMORY_MACHINE_LB_HEADER      1
-
-#include <grub/symbol.h>
-#include <grub/i386/pc/memory.h>
-
-#ifndef ASM_FILE
-#include <grub/err.h>
-#include <grub/types.h>
-#endif
-
-#define GRUB_MEMORY_MACHINE_LOWER_USABLE               0x9fc00         /* 640 kiB - 1 kiB */
-
-#define GRUB_MEMORY_MACHINE_UPPER_START                        0x100000        /* 1 MiB */
-#define GRUB_MEMORY_MACHINE_LOWER_SIZE                 GRUB_MEMORY_MACHINE_UPPER_START
-
-#ifndef ASM_FILE
-
-struct grub_linuxbios_table_header
-{
-  char signature[4];
-  grub_uint32_t size;
-};
-typedef struct grub_linuxbios_table_header *grub_linuxbios_table_header_t;
-
-struct grub_linuxbios_table_item
-{
-#define GRUB_LINUXBIOS_MEMBER_UNUSED           0x00
-#define GRUB_LINUXBIOS_MEMBER_MEMORY           0x01
-#define GRUB_LINUXBIOS_MEMBER_LINK              0x11
-  grub_uint32_t tag;
-  grub_uint32_t size;
-};
-typedef struct grub_linuxbios_table_item *grub_linuxbios_table_item_t;
-
-struct grub_linuxbios_mem_region
-{
-  grub_uint64_t addr;
-  grub_uint64_t size;
-#define GRUB_MACHINE_MEMORY_AVAILABLE          1
-  grub_uint32_t type;
-};
-typedef struct grub_linuxbios_mem_region *mem_region_t;
-
-void grub_machine_mmap_init (void);
-
-grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
-     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
-
-#endif
-
-#endif /* ! _GRUB_MEMORY_MACHINE_HEADER */
diff --git a/include/grub/i386/coreboot/serial.h b/include/grub/i386/coreboot/serial.h
deleted file mode 100644 (file)
index b6819d5..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MACHINE_SERIAL_HEADER
-#define GRUB_MACHINE_SERIAL_HEADER     1
-
-#define GRUB_MACHINE_SERIAL_PORTS { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }
-
-#endif
diff --git a/include/grub/i386/coreboot/time.h b/include/grub/i386/coreboot/time.h
deleted file mode 100644 (file)
index 2298ee8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/pc/time.h>
diff --git a/include/grub/i386/cpuid.h b/include/grub/i386/cpuid.h
deleted file mode 100644 (file)
index 09b313b..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_CPU_CPUID_HEADER
-#define GRUB_CPU_CPUID_HEADER 1
-
-extern unsigned char grub_cpuid_has_longmode;
-
-#endif
diff --git a/include/grub/i386/efi/kernel.h b/include/grub/i386/efi/kernel.h
deleted file mode 100644 (file)
index c0549f4..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MACHINE_KERNEL_HEADER
-#define GRUB_MACHINE_KERNEL_HEADER   1
-
-/* The prefix which points to the directory where GRUB modules and its
-   configuration file are located.  */
-extern char grub_prefix[];
-
-/* The offset of GRUB_PREFIX.  */
-#define GRUB_KERNEL_MACHINE_PREFIX             0x8
-
-/* End of the data section. */
-#define GRUB_KERNEL_MACHINE_DATA_END           0x50
-
-#endif /* ! GRUB_MACHINE_KERNEL_HEADER */
-
diff --git a/include/grub/i386/efi/loader.h b/include/grub/i386/efi/loader.h
deleted file mode 100644 (file)
index 222dae8..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_LOADER_MACHINE_HEADER
-#define GRUB_LOADER_MACHINE_HEADER     1
-
-#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/include/grub/i386/efi/memory.h b/include/grub/i386/efi/memory.h
deleted file mode 100644 (file)
index c9a61bb..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/efi/memory.h>
diff --git a/include/grub/i386/efi/serial.h b/include/grub/i386/efi/serial.h
deleted file mode 100644 (file)
index 2d85634..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/coreboot/serial.h>
diff --git a/include/grub/i386/efi/time.h b/include/grub/i386/efi/time.h
deleted file mode 100644 (file)
index 7a9241f..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MACHINE_TIME_HEADER
-#define GRUB_MACHINE_TIME_HEADER       1
-
-#include <grub/efi/time.h>
-
-#endif /* ! GRUB_MACHINE_TIME_HEADER */
diff --git a/include/grub/i386/efiemu.h b/include/grub/i386/efiemu.h
deleted file mode 100644 (file)
index edb13ff..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_ARCH_EFI_EMU_HEADER
-#define GRUB_ARCH_EFI_EMU_HEADER       1
-
-grub_err_t
-grub_arch_efiemu_relocate_symbols32 (grub_efiemu_segment_t segs,
-                                    struct grub_efiemu_elf_sym *elfsyms,
-                                    void *ehdr);
-grub_err_t
-grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs,
-                                    struct grub_efiemu_elf_sym *elfsyms,
-                                    void *ehdr);
-
-int grub_arch_efiemu_check_header32 (void *ehdr);
-int grub_arch_efiemu_check_header64 (void *ehdr);
-#endif
diff --git a/include/grub/i386/freebsd_linker.h b/include/grub/i386/freebsd_linker.h
deleted file mode 100644 (file)
index 3c1eb64..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*-
- * Copyright (c) 1997-2000 Doug Rabson
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: stable/8/sys/sys/linker.h 199583 2009-11-20 15:27:52Z jhb $
- */
-
-#ifndef GRUB_FREEBSD_LINKER_CPU_HEADER
-#define GRUB_FREEBSD_LINKER_CPU_HEADER 1
-
-#define FREEBSD_MODINFO_END            0x0000  /* End of list */
-#define FREEBSD_MODINFO_NAME           0x0001  /* Name of module (string) */
-#define FREEBSD_MODINFO_TYPE           0x0002  /* Type of module (string) */
-#define FREEBSD_MODINFO_ADDR           0x0003  /* Loaded address */
-#define FREEBSD_MODINFO_SIZE           0x0004  /* Size of module */
-#define FREEBSD_MODINFO_EMPTY          0x0005  /* Has been deleted */
-#define FREEBSD_MODINFO_ARGS           0x0006  /* Parameters string */
-#define FREEBSD_MODINFO_METADATA       0x8000  /* Module-specfic */
-
-#define FREEBSD_MODINFOMD_AOUTEXEC     0x0001  /* a.out exec header */
-#define FREEBSD_MODINFOMD_ELFHDR       0x0002  /* ELF header */
-#define FREEBSD_MODINFOMD_SSYM         0x0003  /* start of symbols */
-#define FREEBSD_MODINFOMD_ESYM         0x0004  /* end of symbols */
-#define FREEBSD_MODINFOMD_DYNAMIC      0x0005  /* _DYNAMIC pointer */
-#define FREEBSD_MODINFOMD_ENVP         0x0006  /* envp[] */
-#define FREEBSD_MODINFOMD_HOWTO                0x0007  /* boothowto */
-#define FREEBSD_MODINFOMD_KERNEND      0x0008  /* kernend */
-#define FREEBSD_MODINFOMD_SHDR         0x0009  /* section header table */
-#define FREEBSD_MODINFOMD_NOCOPY       0x8000  /* don't copy this metadata to the kernel */
-
-#define FREEBSD_MODINFOMD_SMAP         0x1001
-
-#define FREEBSD_MODINFOMD_DEPLIST      (0x4001 | FREEBSD_MODINFOMD_NOCOPY)  /* depends on */
-
-#endif
diff --git a/include/grub/i386/freebsd_reboot.h b/include/grub/i386/freebsd_reboot.h
deleted file mode 100644 (file)
index 9c17f6e..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*-
- * Copyright (c) 1982, 1986, 1988, 1993, 1994
- *      The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *      @(#)reboot.h    8.3 (Berkeley) 12/13/94
- * $FreeBSD: stable/8/sys/sys/reboot.h 199583 2009-11-20 15:27:52Z jhb $
- */
-
-#ifndef GRUB_FREEBSD_REBOOT_CPU_HEADER
-#define GRUB_FREEBSD_REBOOT_CPU_HEADER 1
-
-#define FREEBSD_RB_ASKNAME     (1 << 0)  /* ask for file name to reboot from */
-#define FREEBSD_RB_SINGLE       (1 << 1)  /* reboot to single user only */
-#define FREEBSD_RB_NOSYNC       (1 << 2)  /* dont sync before reboot */
-#define FREEBSD_RB_HALT         (1 << 3)  /* don't reboot, just halt */
-#define FREEBSD_RB_INITNAME     (1 << 4)  /* name given for /etc/init (unused) */
-#define FREEBSD_RB_DFLTROOT     (1 << 5)  /* use compiled-in rootdev */
-#define FREEBSD_RB_KDB          (1 << 6)  /* give control to kernel debugger */
-#define FREEBSD_RB_RDONLY       (1 << 7)  /* mount root fs read-only */
-#define FREEBSD_RB_DUMP         (1 << 8)  /* dump kernel memory before reboot */
-#define FREEBSD_RB_MINIROOT     (1 << 9)  /* mini-root present in memory at boot time */
-#define FREEBSD_RB_CONFIG       (1 << 10) /* invoke user configuration routing */
-#define FREEBSD_RB_VERBOSE      (1 << 11) /* print all potentially useful info */
-#define FREEBSD_RB_SERIAL       (1 << 12) /* user serial port as console */
-#define FREEBSD_RB_CDROM        (1 << 13) /* use cdrom as root */
-#define FREEBSD_RB_GDB         (1 << 15) /* use GDB remote debugger instead of DDB */
-#define FREEBSD_RB_MUTE                (1 << 16) /* Come up with the console muted */
-#define FREEBSD_RB_PAUSE       (1 << 20)
-#define FREEBSD_RB_QUIET       (1 << 21)
-#define FREEBSD_RB_NOINTR      (1 << 28)
-#define FREENSD_RB_MULTIPLE    (1 << 29)  /* Use multiple consoles */
-#define FREEBSD_RB_DUAL                FREENSD_RB_MULTIPLE
-#define FREEBSD_RB_BOOTINFO     (1 << 31) /* have `struct bootinfo *' arg */
-
-#endif
diff --git a/include/grub/i386/ieee1275/console.h b/include/grub/i386/ieee1275/console.h
deleted file mode 100644 (file)
index 854724a..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_CONSOLE_MACHINE_HEADER
-#define GRUB_CONSOLE_MACHINE_HEADER 1
-
-#include <grub/symbol.h>
-
-/* Initialize the console system.  */
-void grub_console_init (void);
-
-/* Finish the console system.  */
-void grub_console_fini (void);
-
-#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */
diff --git a/include/grub/i386/ieee1275/ieee1275.h b/include/grub/i386/ieee1275/ieee1275.h
deleted file mode 100644 (file)
index 2625f02..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/powerpc/ieee1275/ieee1275.h>
diff --git a/include/grub/i386/ieee1275/kernel.h b/include/grub/i386/ieee1275/kernel.h
deleted file mode 100644 (file)
index dccf8cb..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/powerpc/ieee1275/kernel.h>
diff --git a/include/grub/i386/ieee1275/loader.h b/include/grub/i386/ieee1275/loader.h
deleted file mode 100644 (file)
index 20df2e1..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_LOADER_MACHINE_HEADER
-#define GRUB_LOADER_MACHINE_HEADER     1
-
-#include <grub/types.h>
-#include <grub/symbol.h>
-#include <grub/multiboot.h>
-
-void grub_rescue_cmd_linux (int argc, char *argv[]);
-void grub_rescue_cmd_initrd (int argc, char *argv[]);
-
-#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/include/grub/i386/ieee1275/memory.h b/include/grub/i386/ieee1275/memory.h
deleted file mode 100644 (file)
index 386ee4a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/pc/memory.h>
diff --git a/include/grub/i386/ieee1275/serial.h b/include/grub/i386/ieee1275/serial.h
deleted file mode 100644 (file)
index 2d85634..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/coreboot/serial.h>
diff --git a/include/grub/i386/ieee1275/time.h b/include/grub/i386/ieee1275/time.h
deleted file mode 100644 (file)
index 6f474ba..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/powerpc/ieee1275/time.h>
diff --git a/include/grub/i386/io.h b/include/grub/i386/io.h
deleted file mode 100644 (file)
index ae12a3e..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1996,2000,2002,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Based on sys/io.h from GNU libc. */
-
-#ifndef        GRUB_IO_H
-#define        GRUB_IO_H       1
-
-typedef unsigned short int grub_port_t;
-
-static __inline unsigned char
-grub_inb (unsigned short int port)
-{
-  unsigned char _v;
-
-  __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
-  return _v;
-}
-
-static __inline unsigned short int
-grub_inw (unsigned short int port)
-{
-  unsigned short _v;
-
-  __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (port));
-  return _v;
-}
-
-static __inline unsigned int
-grub_inl (unsigned short int port)
-{
-  unsigned int _v;
-
-  __asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (port));
-  return _v;
-}
-
-static __inline void
-grub_outb (unsigned char value, unsigned short int port)
-{
-  __asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (port));
-}
-
-static __inline void
-grub_outw (unsigned short int value, unsigned short int port)
-{
-  __asm__ __volatile__ ("outw %w0,%w1": :"a" (value), "Nd" (port));
-
-}
-
-static __inline void
-grub_outl (unsigned int value, unsigned short int port)
-{
-  __asm__ __volatile__ ("outl %0,%w1": :"a" (value), "Nd" (port));
-}
-
-#endif /* _SYS_IO_H */
diff --git a/include/grub/i386/kernel.h b/include/grub/i386/kernel.h
deleted file mode 100644 (file)
index 5514c8c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_KERNEL_CPU_HEADER
-#define GRUB_KERNEL_CPU_HEADER 1
-
-
-#ifdef GRUB_MACHINE_IEEE1275
-#define GRUB_MOD_ALIGN 0x1000
-#else
-#define GRUB_MOD_ALIGN 0x1
-#endif
-
-/* Non-zero value is only needed for PowerMacs.  */
-#define GRUB_MOD_GAP 0x0
-
-#define GRUB_KERNEL_CPU_PREFIX 0x2
-#define GRUB_KERNEL_CPU_DATA_END       0x42
-
-#endif
diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
deleted file mode 100644 (file)
index f02a722..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_LINUX_MACHINE_HEADER
-#define GRUB_LINUX_MACHINE_HEADER      1
-
-#define GRUB_LINUX_MAGIC_SIGNATURE     0x53726448      /* "HdrS" */
-#define GRUB_LINUX_DEFAULT_SETUP_SECTS 4
-#define GRUB_LINUX_INITRD_MAX_ADDRESS  0x37FFFFFF
-#define GRUB_LINUX_MAX_SETUP_SECTS     64
-#define GRUB_LINUX_BOOT_LOADER_TYPE    0x72
-#define GRUB_LINUX_HEAP_END_OFFSET     (0x9000 - 0x200)
-
-#define GRUB_LINUX_BZIMAGE_ADDR                0x100000
-#define GRUB_LINUX_ZIMAGE_ADDR         0x10000
-#define GRUB_LINUX_OLD_REAL_MODE_ADDR  0x90000
-#define GRUB_LINUX_SETUP_STACK         0x9000
-
-#define GRUB_LINUX_FLAG_BIG_KERNEL     0x1
-#define GRUB_LINUX_FLAG_QUIET          0x20
-#define GRUB_LINUX_FLAG_CAN_USE_HEAP   0x80
-
-/* Linux's video mode selection support. Actually I hate it!  */
-#define GRUB_LINUX_VID_MODE_NORMAL     0xFFFF
-#define GRUB_LINUX_VID_MODE_EXTENDED   0xFFFE
-#define GRUB_LINUX_VID_MODE_ASK                0xFFFD
-#define GRUB_LINUX_VID_MODE_VESA_START 0x0300
-
-#define GRUB_LINUX_SETUP_MOVE_SIZE     0x9100
-#define GRUB_LINUX_CL_MAGIC            0xA33F
-
-#ifdef __x86_64__
-
-#define GRUB_LINUX_EFI_SIGNATURE       \
-  ('4' << 24 | '6' << 16 | 'L' << 8 | 'E')
-
-#else
-
-#define GRUB_LINUX_EFI_SIGNATURE       \
-  ('2' << 24 | '3' << 16 | 'L' << 8 | 'E')
-
-#endif
-
-#define GRUB_LINUX_EFI_SIGNATURE_0204  \
-  ('L' << 24 | 'I' << 16 | 'F' << 8 | 'E')
-
-#define GRUB_LINUX_OFW_SIGNATURE       \
-  (' ' << 24 | 'W' << 16 | 'F' << 8 | 'O')
-
-#ifndef ASM_FILE
-
-#define GRUB_E820_RAM        1
-#define GRUB_E820_RESERVED   2
-#define GRUB_E820_ACPI       3
-#define GRUB_E820_NVS        4
-#define GRUB_E820_EXEC_CODE  5
-
-#define GRUB_E820_MAX_ENTRY  128
-
-struct grub_e820_mmap
-{
-  grub_uint64_t addr;
-  grub_uint64_t size;
-  grub_uint32_t type;
-} __attribute__((packed));
-
-#define GRUB_VIDEO_LINUX_TYPE_TEXT     0x01
-#define GRUB_VIDEO_LINUX_TYPE_VESA     0x23    /* VESA VGA in graphic mode.  */
-#define GRUB_VIDEO_LINUX_TYPE_SIMPLE   0x70    /* Linear framebuffer without any additional functions.  */
-
-/* For the Linux/i386 boot protocol version 2.03.  */
-struct linux_kernel_header
-{
-  grub_uint8_t code1[0x0020];
-  grub_uint16_t cl_magic;              /* Magic number 0xA33F */
-  grub_uint16_t cl_offset;             /* The offset of command line */
-  grub_uint8_t code2[0x01F1 - 0x0020 - 2 - 2];
-  grub_uint8_t setup_sects;            /* The size of the setup in sectors */
-  grub_uint16_t root_flags;            /* If the root is mounted readonly */
-  grub_uint16_t syssize;               /* obsolete */
-  grub_uint16_t swap_dev;              /* obsolete */
-  grub_uint16_t ram_size;              /* obsolete */
-  grub_uint16_t vid_mode;              /* Video mode control */
-  grub_uint16_t root_dev;              /* Default root device number */
-  grub_uint16_t boot_flag;             /* 0xAA55 magic number */
-  grub_uint16_t jump;                  /* Jump instruction */
-  grub_uint32_t header;                        /* Magic signature "HdrS" */
-  grub_uint16_t version;               /* Boot protocol version supported */
-  grub_uint32_t realmode_swtch;                /* Boot loader hook */
-  grub_uint16_t start_sys;             /* The load-low segment (obsolete) */
-  grub_uint16_t kernel_version;                /* Points to kernel version string */
-  grub_uint8_t type_of_loader;         /* Boot loader identifier */
-#define LINUX_LOADER_ID_LILO           0x0
-#define LINUX_LOADER_ID_LOADLIN                0x1
-#define LINUX_LOADER_ID_BOOTSECT       0x2
-#define LINUX_LOADER_ID_SYSLINUX       0x3
-#define LINUX_LOADER_ID_ETHERBOOT      0x4
-#define LINUX_LOADER_ID_ELILO          0x5
-#define LINUX_LOADER_ID_GRUB           0x7
-#define LINUX_LOADER_ID_UBOOT          0x8
-#define LINUX_LOADER_ID_XEN            0x9
-#define LINUX_LOADER_ID_GUJIN          0xa
-#define LINUX_LOADER_ID_QEMU           0xb
-  grub_uint8_t loadflags;              /* Boot protocol option flags */
-  grub_uint16_t setup_move_size;       /* Move to high memory size */
-  grub_uint32_t code32_start;          /* Boot loader hook */
-  grub_uint32_t ramdisk_image;         /* initrd load address */
-  grub_uint32_t ramdisk_size;          /* initrd size */
-  grub_uint32_t bootsect_kludge;       /* obsolete */
-  grub_uint16_t heap_end_ptr;          /* Free memory after setup end */
-  grub_uint16_t pad1;                  /* Unused */
-  char *cmd_line_ptr;                  /* Points to the kernel command line */
-  grub_uint32_t initrd_addr_max;        /* Highest address for initrd */
-} __attribute__ ((packed));
-
-/* Boot parameters for Linux based on 2.6.12. This is used by the setup
-   sectors of Linux, and must be simulated by GRUB on EFI, because
-   the setup sectors depend on BIOS.  */
-struct linux_kernel_params
-{
-  grub_uint8_t video_cursor_x;         /* 0 */
-  grub_uint8_t video_cursor_y;
-
-  grub_uint16_t ext_mem;               /* 2 */
-
-  grub_uint16_t video_page;            /* 4 */
-  grub_uint8_t video_mode;             /* 6 */
-  grub_uint8_t video_width;            /* 7 */
-
-  grub_uint8_t padding1[0xa - 0x8];
-
-  grub_uint16_t video_ega_bx;          /* a */
-
-  grub_uint8_t padding2[0xe - 0xc];
-
-  grub_uint8_t video_height;           /* e */
-  grub_uint8_t have_vga;               /* f */
-  grub_uint16_t font_size;             /* 10 */
-
-  grub_uint16_t lfb_width;             /* 12 */
-  grub_uint16_t lfb_height;            /* 14 */
-  grub_uint16_t lfb_depth;             /* 16 */
-  grub_uint32_t lfb_base;              /* 18 */
-  grub_uint32_t lfb_size;              /* 1c */
-
-  grub_uint16_t cl_magic;              /* 20 */
-  grub_uint16_t cl_offset;
-
-  grub_uint16_t lfb_line_len;          /* 24 */
-  grub_uint8_t red_mask_size;          /* 26 */
-  grub_uint8_t red_field_pos;
-  grub_uint8_t green_mask_size;
-  grub_uint8_t green_field_pos;
-  grub_uint8_t blue_mask_size;
-  grub_uint8_t blue_field_pos;
-  grub_uint8_t reserved_mask_size;
-  grub_uint8_t reserved_field_pos;
-  grub_uint16_t vesapm_segment;                /* 2e */
-  grub_uint16_t vesapm_offset;         /* 30 */
-  grub_uint16_t lfb_pages;             /* 32 */
-  grub_uint16_t vesa_attrib;           /* 34 */
-  grub_uint32_t capabilities;          /* 36 */
-
-  grub_uint8_t padding3[0x40 - 0x3a];
-
-  grub_uint16_t apm_version;           /* 40 */
-  grub_uint16_t apm_code_segment;      /* 42 */
-  grub_uint32_t apm_entry;             /* 44 */
-  grub_uint16_t apm_16bit_code_segment;        /* 48 */
-  grub_uint16_t apm_data_segment;      /* 4a */
-  grub_uint16_t apm_flags;             /* 4c */
-  grub_uint32_t apm_code_len;          /* 4e */
-  grub_uint16_t apm_data_len;          /* 52 */
-
-  grub_uint8_t padding4[0x60 - 0x54];
-
-  grub_uint32_t ist_signature;         /* 60 */
-  grub_uint32_t ist_command;           /* 64 */
-  grub_uint32_t ist_event;             /* 68 */
-  grub_uint32_t ist_perf_level;                /* 6c */
-
-  grub_uint8_t padding5[0x80 - 0x70];
-
-  grub_uint8_t hd0_drive_info[0x10];   /* 80 */
-  grub_uint8_t hd1_drive_info[0x10];   /* 90 */
-  grub_uint16_t rom_config_len;                /* a0 */
-
-  grub_uint8_t padding6[0xb0 - 0xa2];
-
-  grub_uint32_t ofw_signature;         /* b0 */
-  grub_uint32_t ofw_num_items;         /* b4 */
-  grub_uint32_t ofw_cif_handler;       /* b8 */
-  grub_uint32_t ofw_idt;               /* bc */
-
-  grub_uint8_t padding7[0x1b8 - 0xc0];
-
-  union
-    {
-      struct
-        {
-          grub_uint32_t efi_system_table;      /* 1b8 */
-          grub_uint32_t padding7_1;            /* 1bc */
-          grub_uint32_t efi_signature;         /* 1c0 */
-          grub_uint32_t efi_mem_desc_size;     /* 1c4 */
-          grub_uint32_t efi_mem_desc_version;  /* 1c8 */
-          grub_uint32_t efi_mmap_size;         /* 1cc */
-          grub_uint32_t efi_mmap;              /* 1d0 */
-        } v0204;
-      struct
-        {
-          grub_uint32_t padding7_1;            /* 1b8 */
-          grub_uint32_t padding7_2;            /* 1bc */
-          grub_uint32_t efi_signature;         /* 1c0 */
-          grub_uint32_t efi_system_table;      /* 1c4 */
-          grub_uint32_t efi_mem_desc_size;     /* 1c8 */
-          grub_uint32_t efi_mem_desc_version;  /* 1cc */
-          grub_uint32_t efi_mmap;              /* 1d0 */
-          grub_uint32_t efi_mmap_size;         /* 1d4 */
-          grub_uint32_t efi_system_table_hi;   /* 1d8 */
-          grub_uint32_t efi_mmap_hi;           /* 1dc */
-        } v0206;
-    };
-
-  grub_uint32_t alt_mem;               /* 1e0 */
-
-  grub_uint8_t padding8[0x1e8 - 0x1e4];
-
-  grub_uint8_t mmap_size;              /* 1e8 */
-
-  grub_uint8_t padding9[0x1f1 - 0x1e9];
-
-  grub_uint8_t setup_sects;            /* The size of the setup in sectors */
-  grub_uint16_t root_flags;            /* If the root is mounted readonly */
-  grub_uint16_t syssize;               /* obsolete */
-  grub_uint16_t swap_dev;              /* obsolete */
-  grub_uint16_t ram_size;              /* obsolete */
-  grub_uint16_t vid_mode;              /* Video mode control */
-  grub_uint16_t root_dev;              /* Default root device number */
-
-  grub_uint8_t padding10;              /* 1fe */
-  grub_uint8_t ps_mouse;               /* 1ff */
-
-  grub_uint16_t jump;                  /* Jump instruction */
-  grub_uint32_t header;                        /* Magic signature "HdrS" */
-  grub_uint16_t version;               /* Boot protocol version supported */
-  grub_uint32_t realmode_swtch;                /* Boot loader hook */
-  grub_uint16_t start_sys;             /* The load-low segment (obsolete) */
-  grub_uint16_t kernel_version;                /* Points to kernel version string */
-  grub_uint8_t type_of_loader;         /* Boot loader identifier */
-  grub_uint8_t loadflags;              /* Boot protocol option flags */
-  grub_uint16_t setup_move_size;       /* Move to high memory size */
-  grub_uint32_t code32_start;          /* Boot loader hook */
-  grub_uint32_t ramdisk_image;         /* initrd load address */
-  grub_uint32_t ramdisk_size;          /* initrd size */
-  grub_uint32_t bootsect_kludge;       /* obsolete */
-  grub_uint16_t heap_end_ptr;          /* Free memory after setup end */
-  grub_uint16_t pad1;                  /* Unused */
-  grub_uint32_t cmd_line_ptr;          /* Points to the kernel command line */
-
-  grub_uint8_t pad2[164];              /* 22c */
-  struct grub_e820_mmap e820_map[GRUB_E820_MAX_ENTRY]; /* 2d0 */
-
-} __attribute__ ((packed));
-#endif /* ! ASM_FILE */
-
-#endif /* ! GRUB_LINUX_MACHINE_HEADER */
diff --git a/include/grub/i386/loader.h b/include/grub/i386/loader.h
deleted file mode 100644 (file)
index 05954b6..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_LOADER_CPU_HEADER
-#define GRUB_LOADER_CPU_HEADER 1
-
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/symbol.h>
-
-extern grub_addr_t EXPORT_VAR(grub_os_area_addr);
-extern grub_size_t EXPORT_VAR(grub_os_area_size);
-
-#ifdef GRUB_MACHINE_PCBIOS
-extern grub_uint32_t EXPORT_VAR(grub_linux_prot_size);
-extern char *EXPORT_VAR(grub_linux_tmp_addr);
-extern char *EXPORT_VAR(grub_linux_real_addr);
-extern grub_int32_t EXPORT_VAR(grub_linux_is_bzimage);
-grub_err_t EXPORT_FUNC(grub_linux16_real_boot) (void);
-#endif
-
-#endif /* ! GRUB_LOADER_CPU_HEADER */
diff --git a/include/grub/i386/macho.h b/include/grub/i386/macho.h
deleted file mode 100644 (file)
index f22c211..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_CPU_MACHO_H
-#define GRUB_CPU_MACHO_H 1
-
-#include <grub/macho.h>
-
-#define GRUB_MACHO_CPUTYPE_IS_HOST32(x) ((x)==0x00000007)
-#define GRUB_MACHO_CPUTYPE_IS_HOST64(x) ((x)==0x01000007)
-
-struct grub_macho_thread32
-{
-  grub_uint32_t cmd;
-  grub_uint32_t cmdsize;
-  grub_uint8_t unknown1[48];
-  grub_uint32_t entry_point;
-  grub_uint8_t unknown2[20];
-} __attribute__ ((packed));
-
-
-struct grub_macho_thread64
-{
-  grub_uint32_t cmd;
-  grub_uint32_t cmdsize;
-  grub_uint8_t unknown1[0x88];
-  grub_uint64_t entry_point;
-  grub_uint8_t unknown2[0x20];
-} __attribute__ ((packed));
-
-#endif
diff --git a/include/grub/i386/memory.h b/include/grub/i386/memory.h
deleted file mode 100644 (file)
index 466947c..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* memory.h - describe the memory map */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MEMORY_CPU_HEADER
-#define GRUB_MEMORY_CPU_HEADER 1
-
-/* The flag for protected mode.  */
-#define GRUB_MEMORY_CPU_CR0_PE_ON              0x1
-#define GRUB_MEMORY_CPU_CR4_PAE_ON             0x00000040
-#define GRUB_MEMORY_CPU_CR0_PAGING_ON          0x80000000
-#define GRUB_MEMORY_CPU_AMD64_MSR              0xc0000080
-#define GRUB_MEMORY_CPU_AMD64_MSR_ON           0x00000100
-
-#endif /* ! GRUB_MEMORY_CPU_HEADER */
diff --git a/include/grub/i386/multiboot.h b/include/grub/i386/multiboot.h
deleted file mode 100644 (file)
index 1c711fa..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MULTIBOOT_CPU_HEADER
-#define GRUB_MULTIBOOT_CPU_HEADER      1
-
-extern grub_uint32_t grub_multiboot_payload_eip;
-extern char *grub_multiboot_payload_orig;
-extern grub_addr_t grub_multiboot_payload_dest;
-extern grub_size_t grub_multiboot_payload_size;
-
-#define MULTIBOOT_INITIAL_STATE  { .eax = MULTIBOOT_BOOTLOADER_MAGIC,  \
-    .ecx = 0,                                                          \
-    .edx = 0,                                                          \
-    /* Set esp to some random location in low memory to avoid breaking */ \
-    /* non-compliant kernels.  */                                      \
-    .esp = 0x7ff00                                                     \
-      }
-#define MULTIBOOT_ENTRY_REGISTER eip
-#define MULTIBOOT_MBI_REGISTER ebx
-#define MULTIBOOT_ARCHITECTURE_CURRENT MULTIBOOT_ARCHITECTURE_I386
-
-#define MULTIBOOT_ELF32_MACHINE EM_386
-#define MULTIBOOT_ELF64_MACHINE EM_X86_64
-
-#endif /* ! GRUB_MULTIBOOT_CPU_HEADER */
diff --git a/include/grub/i386/multiboot/boot.h b/include/grub/i386/multiboot/boot.h
deleted file mode 100644 (file)
index c33f9ba..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/coreboot/boot.h>
diff --git a/include/grub/i386/multiboot/console.h b/include/grub/i386/multiboot/console.h
deleted file mode 100644 (file)
index 774399a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/coreboot/console.h>
diff --git a/include/grub/i386/multiboot/init.h b/include/grub/i386/multiboot/init.h
deleted file mode 100644 (file)
index fd935c3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/coreboot/init.h>
diff --git a/include/grub/i386/multiboot/kernel.h b/include/grub/i386/multiboot/kernel.h
deleted file mode 100644 (file)
index b41e86e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/coreboot/kernel.h>
diff --git a/include/grub/i386/multiboot/loader.h b/include/grub/i386/multiboot/loader.h
deleted file mode 100644 (file)
index 1c725be..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/coreboot/loader.h>
diff --git a/include/grub/i386/multiboot/memory.h b/include/grub/i386/multiboot/memory.h
deleted file mode 100644 (file)
index 8dd6f7c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/coreboot/memory.h>
diff --git a/include/grub/i386/multiboot/serial.h b/include/grub/i386/multiboot/serial.h
deleted file mode 100644 (file)
index 2d85634..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/coreboot/serial.h>
diff --git a/include/grub/i386/multiboot/time.h b/include/grub/i386/multiboot/time.h
deleted file mode 100644 (file)
index 7177c74..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/coreboot/time.h>
diff --git a/include/grub/i386/netbsd_bootinfo.h b/include/grub/i386/netbsd_bootinfo.h
deleted file mode 100644 (file)
index 776ecf3..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*     $NetBSD: bootinfo.h,v 1.16 2009/08/24 02:15:46 jmcneill Exp $   */
-
-/*
- * Copyright (c) 1997
- *     Matthias Drochner.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRUB_NETBSD_BOOTINFO_CPU_HEADER
-#define GRUB_NETBSD_BOOTINFO_CPU_HEADER        1
-
-#include <grub/types.h>
-
-
-#define NETBSD_BTINFO_BOOTPATH         0
-#define NETBSD_BTINFO_ROOTDEVICE       1
-#define NETBSD_BTINFO_BOOTDISK         3
-#define NETBSD_BTINFO_MEMMAP           9
-
-struct grub_netbsd_btinfo_common
-{
-  int len;
-  int type;
-};
-
-struct grub_netbsd_btinfo_mmap_header
-{
-  struct grub_netbsd_btinfo_common common;
-  grub_uint32_t count;
-};
-
-struct grub_netbsd_btinfo_mmap_entry
-{
-  grub_uint64_t addr;
-  grub_uint64_t len;
-#define        NETBSD_MMAP_AVAILABLE   1
-#define        NETBSD_MMAP_RESERVED    2
-#define        NETBSD_MMAP_ACPI        3
-#define        NETBSD_MMAP_NVS         4
-  grub_uint32_t type;
-};
-
-struct grub_netbsd_btinfo_bootpath
-{
-  struct grub_netbsd_btinfo_common common;
-  char bootpath[80];
-};
-
-struct grub_netbsd_btinfo_rootdevice
-{
-  struct grub_netbsd_btinfo_common common;
-  char devname[16];
-};
-
-struct grub_netbsd_btinfo_bootdisk
-{
-  struct grub_netbsd_btinfo_common common;
-  int labelsector;  /* label valid if != -1 */
-  struct
-    {
-      grub_uint16_t type, checksum;
-      char packname[16];
-    } label;
-  int biosdev;
-  int partition;
-};
-
-struct grub_netbsd_bootinfo
-{
-  grub_uint32_t bi_count;
-  void *bi_data[1];
-};
-
-#endif
diff --git a/include/grub/i386/netbsd_reboot.h b/include/grub/i386/netbsd_reboot.h
deleted file mode 100644 (file)
index ee82455..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*     $NetBSD: reboot.h,v 1.25 2007/12/25 18:33:48 perry Exp $        */
-
-/*
- * Copyright (c) 1982, 1986, 1988, 1993, 1994
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *     @(#)reboot.h    8.3 (Berkeley) 12/13/94
- */
-
-#ifndef GRUB_NETBSD_REBOOT_CPU_HEADER
-#define GRUB_NETBSD_REBOOT_CPU_HEADER  1
-
-#define NETBSD_RB_AUTOBOOT     0  /* flags for system auto-booting itself */
-
-#define NETBSD_RB_ASKNAME      (1 << 0)  /* ask for file name to reboot from */
-#define NETBSD_RB_SINGLE       (1 << 1)  /* reboot to single user only */
-#define NETBSD_RB_NOSYNC       (1 << 2)  /* dont sync before reboot */
-#define NETBSD_RB_HALT         (1 << 3)  /* don't reboot, just halt */
-#define NETBSD_RB_INITNAME     (1 << 4)  /* name given for /etc/init (unused) */
-#define NETBSD_RB_UNUSED1      (1 << 5)  /* was RB_DFLTROOT, obsolete */
-#define NETBSD_RB_KDB          (1 << 6)  /* give control to kernel debugger */
-#define NETBSD_RB_RDONLY       (1 << 7)  /* mount root fs read-only */
-#define NETBSD_RB_DUMP         (1 << 8)  /* dump kernel memory before reboot */
-#define NETBSD_RB_MINIROOT     (1 << 9)  /* mini-root present in memory at boot time */
-#define NETBSD_RB_STRING       (1 << 10) /* use provided bootstr */
-#define NETBSD_RB_POWERDOWN     ((1 << 11) | RB_HALT) /* turn power off (or at least halt) */
-#define NETBSD_RB_USERCONFIG   (1 << 12) /* change configured devices */
-
-#define NETBSD_AB_NORMAL       0  /* boot normally (default) */
-
-#define NETBSD_AB_QUIET                (1 << 16) /* boot quietly */
-#define NETBSD_AB_VERBOSE      (1 << 17) /* boot verbosely */
-#define NETBSD_AB_SILENT       (1 << 18) /* boot silently */
-#define NETBSD_AB_DEBUG                (1 << 19) /* boot with debug messages */
-#define NETBSD_AB_NOSMP                (1 << 28) /* Boot without SMP support.  */
-#define NETBSD_AB_NOACPI        (1 << 29) /* Boot without ACPI support.  */
-
-
-#endif
diff --git a/include/grub/i386/openbsd_bootarg.h b/include/grub/i386/openbsd_bootarg.h
deleted file mode 100644 (file)
index ccbe1ca..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*      $OpenBSD: bootarg.h,v 1.11 2003/06/02 20:20:54 mickey Exp $     */
-     
-/*
- * Copyright (c) 1996-1999 Michael Shalayeff
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef GRUB_OPENBSD_BOOTARG_CPU_HEADER
-#define GRUB_OPENBSD_BOOTARG_CPU_HEADER        1
-
-#define OPENBSD_BOOTARG_APIVER (OPENBSD_BAPIV_VECTOR | \
-                                 OPENBSD_BAPIV_ENV | \
-                                 OPENBSD_BAPIV_BMEMMAP)
-
-#define OPENBSD_BAPIV_ANCIENT  0x0  /* MD old i386 bootblocks */
-#define OPENBSD_BAPIV_VARS     0x1  /* MD structure w/ add info passed */
-#define OPENBSD_BAPIV_VECTOR   0x2  /* MI vector of MD structures passed */
-#define OPENBSD_BAPIV_ENV      0x4  /* MI environment vars vector */
-#define OPENBSD_BAPIV_BMEMMAP  0x8  /* MI memory map passed is in bytes */
-
-#define OPENBSD_BOOTARG_ENV    0x1000
-#define OPENBSD_BOOTARG_END    -1
-
-#define        OPENBSD_BOOTARG_MMAP    0
-
-struct grub_openbsd_bootargs
-{
-  int ba_type;
-  int ba_size;
-  struct grub_openbsd_bootargs *ba_next;
-} __attribute__ ((packed));
-
-#endif
diff --git a/include/grub/i386/openbsd_reboot.h b/include/grub/i386/openbsd_reboot.h
deleted file mode 100644 (file)
index 3f6571a..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*      $OpenBSD: reboot.h,v 1.13 2004/03/10 23:02:53 tom Exp $ */
-/*      $NetBSD: reboot.h,v 1.9 1996/04/22 01:23:25 christos Exp $      */
-
-/*
- * Copyright (c) 1982, 1986, 1988, 1993, 1994
- *      The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *      @(#)reboot.h    8.2 (Berkeley) 7/10/94
- */
-
-#ifndef GRUB_OPENBSD_REBOOT_CPU_HEADER
-#define GRUB_OPENBSD_REBOOT_CPU_HEADER 1
-
-#define OPENBSD_RB_ASKNAME     (1 << 0)  /* ask for file name to reboot from */
-#define OPENBSD_RB_SINGLE      (1 << 1)  /* reboot to single user only */
-#define OPENBSD_RB_NOSYNC      (1 << 2)  /* dont sync before reboot */
-#define OPENBSD_RB_HALT                (1 << 3)  /* don't reboot, just halt */
-#define OPENBSD_RB_INITNAME    (1 << 4)  /* name given for /etc/init (unused) */
-#define OPENBSD_RB_DFLTROOT    (1 << 5)  /* use compiled-in rootdev */
-#define OPENBSD_RB_KDB         (1 << 6)  /* give control to kernel debugger */
-#define OPENBSD_RB_RDONLY      (1 << 7)  /* mount root fs read-only */
-#define OPENBSD_RB_DUMP                (1 << 8)  /* dump kernel memory before reboot */
-#define OPENBSD_RB_MINIROOT    (1 << 9)  /* mini-root present in memory at boot time */
-#define OPENBSD_RB_CONFIG      (1 << 10) /* change configured devices */
-#define OPENBSD_RB_TIMEBAD     (1 << 11) /* don't call resettodr() in boot() */
-#define OPENBSD_RB_POWERDOWN   (1 << 12) /* attempt to power down machine */
-#define OPENBSD_RB_SERCONS     (1 << 13) /* use serial console if available */
-#define OPENBSD_RB_USERREQ     (1 << 14) /* boot() called at user request (e.g. ddb) */
-
-#define OPENBSD_B_DEVMAGIC     0xa0000000
-#define OPENBSD_B_ADAPTORSHIFT 24
-#define OPENBSD_B_CTRLSHIFT    20
-#define OPENBSD_B_UNITSHIFT    16
-#define OPENBSD_B_PARTSHIFT    8
-#define OPENBSD_B_TYPESHIFT    0
-
-#endif
diff --git a/include/grub/i386/pc/biosdisk.h b/include/grub/i386/pc/biosdisk.h
deleted file mode 100644 (file)
index b87e0e4..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_BIOSDISK_MACHINE_HEADER
-#define GRUB_BIOSDISK_MACHINE_HEADER   1
-
-#include <grub/symbol.h>
-#include <grub/types.h>
-
-#define GRUB_BIOSDISK_FLAG_LBA 1
-#define GRUB_BIOSDISK_FLAG_CDROM 2
-
-#define GRUB_BIOSDISK_CDTYPE_NO_EMUL   0
-#define GRUB_BIOSDISK_CDTYPE_1_2_M     1
-#define GRUB_BIOSDISK_CDTYPE_1_44_M    2
-#define GRUB_BIOSDISK_CDTYPE_2_88_M    3
-#define GRUB_BIOSDISK_CDTYPE_HARDDISK  4
-
-#define GRUB_BIOSDISK_CDTYPE_MASK      0xF
-
-struct grub_biosdisk_data
-{
-  int drive;
-  unsigned long cylinders;
-  unsigned long heads;
-  unsigned long sectors;
-  unsigned long flags;
-};
-
-/* Drive Parameters.  */
-struct grub_biosdisk_drp
-{
-  grub_uint16_t size;
-  grub_uint16_t flags;
-  grub_uint32_t cylinders;
-  grub_uint32_t heads;
-  grub_uint32_t sectors;
-  grub_uint64_t total_sectors;
-  grub_uint16_t bytes_per_sector;
-  /* ver 2.0 or higher */
-
-  union
-  {
-    grub_uint32_t EDD_configuration_parameters;
-
-    /* Pointer to the Device Parameter Table Extension (ver 3.0+).  */
-    grub_uint32_t dpte_pointer;
-  };
-
-  /* ver 3.0 or higher */
-  grub_uint16_t signature_dpi;
-  grub_uint8_t length_dpi;
-  grub_uint8_t reserved[3];
-  grub_uint8_t name_of_host_bus[4];
-  grub_uint8_t name_of_interface_type[8];
-  grub_uint8_t interface_path[8];
-  grub_uint8_t device_path[8];
-  grub_uint8_t reserved2;
-  grub_uint8_t checksum;
-
-  /* XXX: This is necessary, because the BIOS of Thinkpad X20
-     writes a garbage to the tail of drive parameters,
-     regardless of a size specified in a caller.  */
-  grub_uint8_t dummy[16];
-} __attribute__ ((packed));
-
-struct grub_biosdisk_cdrp
-{
-  grub_uint8_t size;
-  grub_uint8_t media_type;
-  grub_uint8_t drive_no;
-  grub_uint8_t controller_no;
-  grub_uint32_t image_lba;
-  grub_uint16_t device_spec;
-  grub_uint16_t cache_seg;
-  grub_uint16_t load_seg;
-  grub_uint16_t length_sec512;
-  grub_uint8_t cylinders;
-  grub_uint8_t sectors;
-  grub_uint8_t heads;
-  grub_uint8_t dummy[16];
-} __attribute__ ((packed));
-
-/* Disk Address Packet.  */
-struct grub_biosdisk_dap
-{
-  grub_uint8_t length;
-  grub_uint8_t reserved;
-  grub_uint16_t blocks;
-  grub_uint32_t buffer;
-  grub_uint64_t block;
-} __attribute__ ((packed));
-
-int EXPORT_FUNC(grub_biosdisk_rw_int13_extensions) (int ah, int drive, void *dap);
-int EXPORT_FUNC(grub_biosdisk_rw_standard) (int ah, int drive, int coff, int hoff,
-                              int soff, int nsec, int segment);
-int EXPORT_FUNC(grub_biosdisk_check_int13_extensions) (int drive);
-int EXPORT_FUNC(grub_biosdisk_get_diskinfo_int13_extensions) (int drive,
-           void *drp);
-int EXPORT_FUNC(grub_biosdisk_get_cdinfo_int13_extensions) (int drive,
-           void *cdrp);
-int EXPORT_FUNC(grub_biosdisk_get_diskinfo_standard) (int drive,
-                                        unsigned long *cylinders,
-                                        unsigned long *heads,
-                                        unsigned long *sectors);
-int EXPORT_FUNC(grub_biosdisk_get_num_floppies) (void);
-
-void grub_biosdisk_init (void);
-void grub_biosdisk_fini (void);
-
-#endif /* ! GRUB_BIOSDISK_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/biosnum.h b/include/grub/i386/pc/biosnum.h
deleted file mode 100644 (file)
index 29c8ecc..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef GRUB_BIOSNUM_MACHINE_HEADER
-#define GRUB_BIOSNUM_MACHINE_HEADER    1
-
-extern int (*grub_get_root_biosnumber) (void);
-
-#endif
diff --git a/include/grub/i386/pc/boot.h b/include/grub/i386/pc/boot.h
deleted file mode 100644 (file)
index e88c62b..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2002,2005,2006,2007,2008,2010   Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_BOOT_MACHINE_HEADER
-#define GRUB_BOOT_MACHINE_HEADER       1
-
-/* The signature for bootloader.  */
-#define GRUB_BOOT_MACHINE_SIGNATURE    0xaa55
-
-/* The offset of the start of BPB (BIOS Parameter Block).  */
-#define GRUB_BOOT_MACHINE_BPB_START    0x3
-
-/* The offset of the end of BPB (BIOS Parameter Block).  */
-#define GRUB_BOOT_MACHINE_BPB_END      0x5a
-
-/* The offset of KERNEL_SECTOR.  */
-#define GRUB_BOOT_MACHINE_KERNEL_SECTOR        0x5c
-
-/* The offset of BOOT_DRIVE.  */
-#define GRUB_BOOT_MACHINE_BOOT_DRIVE   0x64
-
-/* The offset of BOOT_DRIVE_CHECK.  */
-#define GRUB_BOOT_MACHINE_DRIVE_CHECK  0x66
-
-/* The offset of a magic number used by Windows NT.  */
-#define GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC     0x1b8
-
-/* The offset of the start of the partition table.  */
-#define GRUB_BOOT_MACHINE_PART_START   0x1be
-
-/* The offset of the end of the partition table.  */
-#define GRUB_BOOT_MACHINE_PART_END     0x1fe
-
-/* The stack segment.  */
-#define GRUB_BOOT_MACHINE_STACK_SEG    0x2000
-
-/* The segment of disk buffer. The disk buffer MUST be 32K long and
-   cannot straddle a 64K boundary.  */
-#define GRUB_BOOT_MACHINE_BUFFER_SEG   0x7000
-
-/* The flag for BIOS drive number to designate a hard disk vs. a
-   floppy.  */
-#define GRUB_BOOT_MACHINE_BIOS_HD_FLAG 0x80
-
-/* The segment where the kernel is loaded.  */
-#define GRUB_BOOT_MACHINE_KERNEL_SEG   0x800
-
-/* The address where the kernel is loaded.  */
-#define GRUB_BOOT_MACHINE_KERNEL_ADDR  (GRUB_BOOT_MACHINE_KERNEL_SEG << 4)
-
-/* The size of a block list used in the kernel startup code.  */
-#define GRUB_BOOT_MACHINE_LIST_SIZE    12
-
-#define GRUB_BOOT_MACHINE_PXE_DL       0x7f
-
-#ifndef ASM_FILE
-
-/* This is the blocklist used in the diskboot image.  */
-struct grub_boot_blocklist
-{
-  grub_uint64_t start;
-  grub_uint16_t len;
-  grub_uint16_t segment;
-} __attribute__ ((packed));
-
-#endif /* ! ASM_FILE */
-
-#endif /* ! BOOT_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/chainloader.h b/include/grub/i386/pc/chainloader.h
deleted file mode 100644 (file)
index ca1da23..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_CHAINLOADER_MACHINE_HEADER
-#define GRUB_CHAINLOADER_MACHINE_HEADER        1
-
-#include <grub/dl.h>
-
-/* Common function for normal and rescue mode commands. */
-typedef enum
-  {
-    GRUB_CHAINLOADER_FORCE = 0x1
-  } grub_chainloader_flags_t;
-
-#endif /* GRUB_CHAINLOADER_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/console.h b/include/grub/i386/pc/console.h
deleted file mode 100644 (file)
index 2a74d15..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_CONSOLE_MACHINE_HEADER
-#define GRUB_CONSOLE_MACHINE_HEADER    1
-
-/* Define scan codes.  */
-#define GRUB_CONSOLE_KEY_LEFT          0x4B00
-#define GRUB_CONSOLE_KEY_RIGHT         0x4D00
-#define GRUB_CONSOLE_KEY_UP            0x4800
-#define GRUB_CONSOLE_KEY_DOWN          0x5000
-#define GRUB_CONSOLE_KEY_IC            0x5200
-#define GRUB_CONSOLE_KEY_DC            0x5300
-#define GRUB_CONSOLE_KEY_BACKSPACE     0x0008
-#define GRUB_CONSOLE_KEY_HOME          0x4700
-#define GRUB_CONSOLE_KEY_END           0x4F00
-#define GRUB_CONSOLE_KEY_NPAGE         0x5100
-#define GRUB_CONSOLE_KEY_PPAGE         0x4900
-
-#ifndef ASM_FILE
-
-#include <grub/types.h>
-#include <grub/symbol.h>
-#include <grub/term.h>
-#include <grub/i386/vga_common.h>
-
-/* These are global to share code between C and asm.  */
-int grub_console_checkkey (void);
-int grub_console_getkey (void);
-grub_uint16_t grub_console_getxy (void);
-void grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y);
-void grub_console_cls (void);
-void grub_console_setcursor (int on);
-
-/* Initialize the console system.  */
-void grub_console_init (void);
-
-/* Finish the console system.  */
-void grub_console_fini (void);
-
-#endif
-
-#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/efiemu.h b/include/grub/i386/pc/efiemu.h
deleted file mode 100644 (file)
index f269dd0..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MACHINE_EFI_EMU_HEADER
-#define GRUB_MACHINE_EFI_EMU_HEADER    1
-
-grub_err_t grub_machine_efiemu_init_tables (void);
-
-#endif
diff --git a/include/grub/i386/pc/init.h b/include/grub/i386/pc/init.h
deleted file mode 100644 (file)
index 30130d1..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2005,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_INIT_MACHINE_HEADER
-#define GRUB_INIT_MACHINE_HEADER       1
-
-#include <grub/types.h>
-#include <grub/symbol.h>
-#include <grub/machine/memory.h>
-
-/* Get the memory size in KB. If EXTENDED is zero, return conventional
-   memory, otherwise return extended memory.  */
-grub_uint16_t grub_get_memsize (int extended);
-
-/* Get a packed EISA memory map. Lower 16 bits are between 1MB and 16MB
-   in 1KB parts, and upper 16 bits are above 16MB in 64KB parts.  */
-grub_uint32_t grub_get_eisa_mmap (void);
-
-/* Get a memory map entry. Return next continuation value. Zero means
-   the end.  */
-grub_uint32_t grub_get_mmap_entry (struct grub_machine_mmap_entry *entry,
-                                  grub_uint32_t cont);
-
-/* Turn on/off Gate A20.  */
-void grub_gate_a20 (int on);
-
-void EXPORT_FUNC(grub_stop_floppy) (void);
-
-#endif /* ! GRUB_INIT_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h
deleted file mode 100644 (file)
index e830afa..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KERNEL_MACHINE_HEADER
-#define KERNEL_MACHINE_HEADER  1
-
-/* The offset of GRUB_TOTAL_MODULE_SIZE.  */
-#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE  0x8
-
-/* The offset of GRUB_KERNEL_IMAGE_SIZE.  */
-#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE  0xc
-
-/* The offset of GRUB_COMPRESSED_SIZE.  */
-#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE    0x10
-
-/* The offset of GRUB_INSTALL_DOS_PART.  */
-#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART   0x14
-
-/* The offset of GRUB_INSTALL_BSD_PART.  */
-#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART   0x18
-
-/* The offset of GRUB_PREFIX.  */
-#define GRUB_KERNEL_MACHINE_PREFIX             0x1c
-
-/* End of the data section. */
-#define GRUB_KERNEL_MACHINE_DATA_END           0x5c
-
-/* The size of the first region which won't be compressed.  */
-#define GRUB_KERNEL_MACHINE_RAW_SIZE           (GRUB_KERNEL_MACHINE_DATA_END + 0x5F0)
-
-/* Enable LZMA compression */
-#define ENABLE_LZMA    1
-
-#ifndef ASM_FILE
-
-#include <grub/symbol.h>
-#include <grub/types.h>
-
-/* The size of kernel image.  */
-extern grub_int32_t grub_kernel_image_size;
-
-/* The total size of module images following the kernel.  */
-extern grub_int32_t grub_total_module_size;
-
-/* The DOS partition number of the installed partition.  */
-extern grub_int32_t grub_install_dos_part;
-
-/* The BSD partition number of the installed partition.  */
-extern grub_int32_t grub_install_bsd_part;
-
-/* The prefix which points to the directory where GRUB modules and its
-   configuration file are located.  */
-extern char grub_prefix[];
-
-/* The boot BIOS drive number.  */
-extern grub_uint8_t EXPORT_VAR(grub_boot_drive);
-
-#endif /* ! ASM_FILE */
-
-#endif /* ! KERNEL_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/loader.h b/include/grub/i386/pc/loader.h
deleted file mode 100644 (file)
index 3e03141..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_LOADER_MACHINE_HEADER
-#define GRUB_LOADER_MACHINE_HEADER     1
-
-#include <grub/symbol.h>
-#include <grub/cpu/loader.h>
-
-/* This is an asm part of the chainloader.  */
-void EXPORT_FUNC(grub_chainloader_real_boot) (int drive, void *part_addr) __attribute__ ((noreturn));
-
-#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h
deleted file mode 100644 (file)
index 841b061..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/* memory.h - describe the memory map */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MEMORY_MACHINE_HEADER
-#define GRUB_MEMORY_MACHINE_HEADER     1
-
-#include <grub/symbol.h>
-#ifndef ASM_FILE
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/memory.h>
-#endif
-
-#include <grub/i386/memory.h>
-
-/* The scratch buffer used in real mode code.  */
-#define GRUB_MEMORY_MACHINE_SCRATCH_ADDR       0x68000
-#define GRUB_MEMORY_MACHINE_SCRATCH_SEG        (GRUB_MEMORY_MACHINE_SCRATCH_ADDR >> 4)
-#define GRUB_MEMORY_MACHINE_SCRATCH_SIZE       0x10000
-
-/* The real mode stack.  */
-#define GRUB_MEMORY_MACHINE_REAL_STACK (0x2000 - 0x10)
-
-/* The size of the protect mode stack.  */
-#define GRUB_MEMORY_MACHINE_PROT_STACK_SIZE    0x8000
-
-/* The upper memory area (starting at 640 kiB).  */
-#define GRUB_MEMORY_MACHINE_UPPER              0xa0000
-
-/* The protected mode stack.  */
-#define GRUB_MEMORY_MACHINE_PROT_STACK \
-       (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + GRUB_MEMORY_MACHINE_SCRATCH_SIZE \
-        + GRUB_MEMORY_MACHINE_PROT_STACK_SIZE - 0x10)
-
-/* The memory area where GRUB uses its own purpose. This part is not added
-   into free memory for dynamic allocations.  */
-#define GRUB_MEMORY_MACHINE_RESERVED_START     \
-       GRUB_MEMORY_MACHINE_SCRATCH_ADDR
-#define GRUB_MEMORY_MACHINE_RESERVED_END       \
-       (GRUB_MEMORY_MACHINE_PROT_STACK + 0x10)
-
-/* The area where GRUB is decompressed at early startup.  */
-#define GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR 0x100000
-
-/* The address of a partition table passed to another boot loader.  */
-#define GRUB_MEMORY_MACHINE_PART_TABLE_ADDR    0x7be
-
-/* The address where another boot loader is loaded.  */
-#define GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR   0x7c00
-
-/* The code segment of the protected mode.  */
-#define GRUB_MEMORY_MACHINE_PROT_MODE_CSEG     0x8
-
-/* The data segment of the protected mode.  */
-#define GRUB_MEMORY_MACHINE_PROT_MODE_DSEG     0x10
-
-/* The code segment of the pseudo real mode.  */
-#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG   0x18
-
-/* The data segment of the pseudo real mode.  */
-#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG   0x20
-
-#define GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR        0x400
-
-#ifndef ASM_FILE
-
-/* See http://heim.ifi.uio.no/~stanisls/helppc/bios_data_area.html for a
-   description of the BIOS Data Area layout.  */
-struct grub_machine_bios_data_area
-{
-  grub_uint8_t unused1[0x17];
-  grub_uint8_t keyboard_flag_lower; /* 0x17 */
-  grub_uint8_t unused2[0xf0 - 0x18];
-};
-
-struct grub_machine_mmap_entry
-{
-  grub_uint32_t size;
-  grub_uint64_t addr;
-  grub_uint64_t len;
-#define GRUB_MACHINE_MEMORY_AVAILABLE  1
-#define GRUB_MACHINE_MEMORY_RESERVED   2
-#define GRUB_MACHINE_MEMORY_ACPI       3
-#define GRUB_MACHINE_MEMORY_NVS        4
-#define GRUB_MACHINE_MEMORY_MAX_TYPE   4
-  /* This one is special: it's used internally but is never reported
-     by firmware. */
-#define GRUB_MACHINE_MEMORY_HOLE       5
-
-  grub_uint32_t type;
-} __attribute__((packed));
-
-grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
-     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
-
-grub_uint64_t grub_mmap_get_post64 (void);
-grub_uint64_t grub_mmap_get_upper (void);
-grub_uint64_t grub_mmap_get_lower (void);
-
-#define GRUB_MMAP_MALLOC_LOW 1
-
-#ifdef GRUB_MACHINE_PCBIOS
-grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t size,
-                                      int type, int handle);
-grub_err_t grub_machine_mmap_unregister (int handle);
-#else
-static inline grub_err_t
-grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
-                           grub_uint64_t size __attribute__ ((unused)),
-                           int type __attribute__ ((unused)),
-                           int handle __attribute__ ((unused)))
-{
-  return GRUB_ERR_NONE;
-}
-static inline grub_err_t
-grub_machine_mmap_unregister (int handle  __attribute__ ((unused)))
-{
-  return GRUB_ERR_NONE;
-}
-#endif
-
-#endif
-
-#endif /* ! GRUB_MEMORY_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/pxe.h b/include/grub/i386/pc/pxe.h
deleted file mode 100644 (file)
index 39f356c..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_CPU_PXE_H
-#define GRUB_CPU_PXE_H
-
-#include <grub/types.h>
-
-#define GRUB_PXENV_TFTP_OPEN                   0x0020
-#define GRUB_PXENV_TFTP_CLOSE                  0x0021
-#define GRUB_PXENV_TFTP_READ                   0x0022
-#define GRUB_PXENV_TFTP_READ_FILE              0x0023
-#define GRUB_PXENV_TFTP_READ_FILE_PMODE                0x0024
-#define GRUB_PXENV_TFTP_GET_FSIZE              0x0025
-
-#define GRUB_PXENV_UDP_OPEN                    0x0030
-#define GRUB_PXENV_UDP_CLOSE                   0x0031
-#define GRUB_PXENV_UDP_READ                    0x0032
-#define GRUB_PXENV_UDP_WRITE                   0x0033
-
-#define GRUB_PXENV_START_UNDI                  0x0000
-#define GRUB_PXENV_UNDI_STARTUP                        0x0001
-#define GRUB_PXENV_UNDI_CLEANUP                        0x0002
-#define GRUB_PXENV_UNDI_INITIALIZE             0x0003
-#define GRUB_PXENV_UNDI_RESET_NIC              0x0004
-#define GRUB_PXENV_UNDI_SHUTDOWN               0x0005
-#define GRUB_PXENV_UNDI_OPEN                   0x0006
-#define GRUB_PXENV_UNDI_CLOSE                  0x0007
-#define GRUB_PXENV_UNDI_TRANSMIT               0x0008
-#define GRUB_PXENV_UNDI_SET_MCAST_ADDR         0x0009
-#define GRUB_PXENV_UNDI_SET_STATION_ADDR       0x000A
-#define GRUB_PXENV_UNDI_SET_PACKET_FILTER      0x000B
-#define GRUB_PXENV_UNDI_GET_INFORMATION                0x000C
-#define GRUB_PXENV_UNDI_GET_STATISTICS         0x000D
-#define GRUB_PXENV_UNDI_CLEAR_STATISTICS       0x000E
-#define GRUB_PXENV_UNDI_INITIATE_DIAGS         0x000F
-#define GRUB_PXENV_UNDI_FORCE_INTERRUPT                0x0010
-#define GRUB_PXENV_UNDI_GET_MCAST_ADDR         0x0011
-#define GRUB_PXENV_UNDI_GET_NIC_TYPE           0x0012
-#define GRUB_PXENV_UNDI_GET_IFACE_INFO         0x0013
-#define GRUB_PXENV_UNDI_ISR                    0x0014
-#define        GRUB_PXENV_STOP_UNDI                    0x0015
-#define GRUB_PXENV_UNDI_GET_STATE              0x0015
-
-#define GRUB_PXENV_UNLOAD_STACK                        0x0070
-#define GRUB_PXENV_GET_CACHED_INFO             0x0071
-#define GRUB_PXENV_RESTART_DHCP                        0x0072
-#define GRUB_PXENV_RESTART_TFTP                        0x0073
-#define GRUB_PXENV_MODE_SWITCH                 0x0074
-#define GRUB_PXENV_START_BASE                  0x0075
-#define GRUB_PXENV_STOP_BASE                   0x0076
-
-#define GRUB_PXENV_EXIT_SUCCESS                        0x0000
-#define GRUB_PXENV_EXIT_FAILURE                        0x0001
-
-#define GRUB_PXENV_STATUS_SUCCESS                              0x00
-#define GRUB_PXENV_STATUS_FAILURE                              0x01
-#define GRUB_PXENV_STATUS_BAD_FUNC                             0x02
-#define GRUB_PXENV_STATUS_UNSUPPORTED                          0x03
-#define GRUB_PXENV_STATUS_KEEP_UNDI                            0x04
-#define GRUB_PXENV_STATUS_KEEP_ALL                             0x05
-#define GRUB_PXENV_STATUS_OUT_OF_RESOURCES                     0x06
-#define GRUB_PXENV_STATUS_ARP_TIMEOUT                          0x11
-#define GRUB_PXENV_STATUS_UDP_CLOSED                           0x18
-#define GRUB_PXENV_STATUS_UDP_OPEN                             0x19
-#define GRUB_PXENV_STATUS_TFTP_CLOSED                          0x1A
-#define GRUB_PXENV_STATUS_TFTP_OPEN                            0x1B
-#define GRUB_PXENV_STATUS_MCOPY_PROBLEM                                0x20
-#define GRUB_PXENV_STATUS_BIS_INTEGRITY_FAILURE                        0x21
-#define GRUB_PXENV_STATUS_BIS_VALIDATE_FAILURE                 0x22
-#define GRUB_PXENV_STATUS_BIS_INIT_FAILURE                     0x23
-#define GRUB_PXENV_STATUS_BIS_SHUTDOWN_FAILURE                 0x24
-#define GRUB_PXENV_STATUS_BIS_GBOA_FAILURE                     0x25
-#define GRUB_PXENV_STATUS_BIS_FREE_FAILURE                     0x26
-#define GRUB_PXENV_STATUS_BIS_GSI_FAILURE                      0x27
-#define GRUB_PXENV_STATUS_BIS_BAD_CKSUM                                0x28
-#define GRUB_PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS              0x30
-#define GRUB_PXENV_STATUS_TFTP_OPEN_TIMEOUT                    0x32
-
-#define GRUB_PXENV_STATUS_TFTP_UNKNOWN_OPCODE                  0x33
-#define GRUB_PXENV_STATUS_TFTP_READ_TIMEOUT                    0x35
-#define GRUB_PXENV_STATUS_TFTP_ERROR_OPCODE                    0x36
-#define GRUB_PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION          0x38
-#define GRUB_PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION     0x39
-#define GRUB_PXENV_STATUS_TFTP_TOO_MANY_PACKAGES               0x3A
-#define GRUB_PXENV_STATUS_TFTP_FILE_NOT_FOUND                  0x3B
-#define GRUB_PXENV_STATUS_TFTP_ACCESS_VIOLATION                        0x3C
-#define GRUB_PXENV_STATUS_TFTP_NO_MCAST_ADDRESS                        0x3D
-#define GRUB_PXENV_STATUS_TFTP_NO_FILESIZE                     0x3E
-#define GRUB_PXENV_STATUS_TFTP_INVALID_PACKET_SIZE             0x3F
-#define GRUB_PXENV_STATUS_DHCP_TIMEOUT                         0x51
-#define GRUB_PXENV_STATUS_DHCP_NO_IP_ADDRESS                   0x52
-#define GRUB_PXENV_STATUS_DHCP_NO_BOOTFILE_NAME                        0x53
-#define GRUB_PXENV_STATUS_DHCP_BAD_IP_ADDRESS                  0x54
-#define GRUB_PXENV_STATUS_UNDI_INVALID_FUNCTION                        0x60
-#define GRUB_PXENV_STATUS_UNDI_MEDIATEST_FAILED                        0x61
-#define GRUB_PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST       0x62
-#define GRUB_PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC           0x63
-#define GRUB_PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY           0x64
-#define GRUB_PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA         0x65
-#define GRUB_PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA           0x66
-#define GRUB_PXENV_STATUS_UNDI_BAD_MAC_ADDRESS                 0x67
-#define GRUB_PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM             0x68
-#define GRUB_PXENV_STATUS_UNDI_ERROR_SETTING_ISR               0x69
-#define GRUB_PXENV_STATUS_UNDI_INVALID_STATE                   0x6A
-#define GRUB_PXENV_STATUS_UNDI_TRANSMIT_ERROR                  0x6B
-#define GRUB_PXENV_STATUS_UNDI_INVALID_PARAMETER               0x6C
-#define GRUB_PXENV_STATUS_BSTRAP_PROMPT_MENU                   0x74
-#define GRUB_PXENV_STATUS_BSTRAP_MCAST_ADDR                    0x76
-#define GRUB_PXENV_STATUS_BSTRAP_MISSING_LIST                  0x77
-#define GRUB_PXENV_STATUS_BSTRAP_NO_RESPONSE                   0x78
-#define GRUB_PXENV_STATUS_BSTRAP_FILE_TOO_BIG                  0x79
-#define GRUB_PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE           0xA0
-#define GRUB_PXENV_STATUS_BINL_NO_PXE_SERVER                   0xA1
-#define GRUB_PXENV_STATUS_NOT_AVAILABLE_IN_PMODE               0xA2
-#define GRUB_PXENV_STATUS_NOT_AVAILABLE_IN_RMODE               0xA3
-#define GRUB_PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED            0xB0
-#define GRUB_PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY           0xC0
-#define GRUB_PXENV_STATUS_LOADER_NO_BC_ROMID                   0xC1
-#define GRUB_PXENV_STATUS_LOADER_BAD_BC_ROMID                  0xC2
-#define GRUB_PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE          0xC3
-#define GRUB_PXENV_STATUS_LOADER_NO_UNDI_ROMID                 0xC4
-#define GRUB_PXENV_STATUS_LOADER_BAD_UNDI_ROMID                        0xC5
-#define GRUB_PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE         0xC6
-#define GRUB_PXENV_STATUS_LOADER_NO_PXE_STRUCT                 0xC8
-#define GRUB_PXENV_STATUS_LOADER_NO_PXENV_STRUCT               0xC9
-#define GRUB_PXENV_STATUS_LOADER_UNDI_START                    0xCA
-#define GRUB_PXENV_STATUS_LOADER_BC_START                      0xCB
-
-#define GRUB_PXENV_PACKET_TYPE_DHCP_DISCOVER   1
-#define GRUB_PXENV_PACKET_TYPE_DHCP_ACK                2
-#define GRUB_PXENV_PACKET_TYPE_CACHED_REPLY    3
-
-#define GRUB_PXE_BOOTP_REQ     1
-#define GRUB_PXE_BOOTP_REP     2
-
-#define GRUB_PXE_BOOTP_BCAST   0x8000
-
-#if 1
-#define GRUB_PXE_BOOTP_DHCPVEND        1024    /* DHCP extended vendor field size.  */
-#else
-#define GRUB_PXE_BOOTP_DHCPVEND        312     /* DHCP standard vendor field size.  */
-#endif
-
-#define GRUB_PXE_MIN_BLKSIZE   512
-#define GRUB_PXE_MAX_BLKSIZE   1432
-
-#define GRUB_PXE_TFTP_PORT     69
-
-#define        GRUB_PXE_VM_RFC1048     0x63825363L
-
-#define GRUB_PXE_ERR_LEN       0xFFFFFFFF
-
-#ifndef ASM_FILE
-
-struct grub_pxenv
-{
-  grub_uint8_t signature[6];   /* 'PXENV+'.  */
-  grub_uint16_t version;       /* MSB = major, LSB = minor.  */
-  grub_uint8_t length;         /* structure length.  */
-  grub_uint8_t checksum;       /* checksum pad.  */
-  grub_uint32_t rm_entry;      /* SEG:OFF to PXE entry point.  */
-  grub_uint32_t        pm_offset;      /* Protected mode entry.  */
-  grub_uint16_t pm_selector;   /* Protected mode selector.  */
-  grub_uint16_t stack_seg;     /* Stack segment address.  */
-  grub_uint16_t        stack_size;     /* Stack segment size (bytes).  */
-  grub_uint16_t bc_code_seg;   /* BC Code segment address.  */
-  grub_uint16_t        bc_code_size;   /* BC Code segment size (bytes).  */
-  grub_uint16_t        bc_data_seg;    /* BC Data segment address.  */
-  grub_uint16_t        bc_data_size;   /* BC Data segment size (bytes).  */
-  grub_uint16_t        undi_data_seg;  /* UNDI Data segment address.  */
-  grub_uint16_t        undi_data_size; /* UNDI Data segment size (bytes).  */
-  grub_uint16_t        undi_code_seg;  /* UNDI Code segment address.  */
-  grub_uint16_t        undi_code_size; /* UNDI Code segment size (bytes).  */
-  grub_uint32_t pxe_ptr;       /* SEG:OFF to !PXE struct.  */
-} __attribute__ ((packed));
-
-struct grub_pxenv_get_cached_info
-{
-  grub_uint16_t status;
-  grub_uint16_t packet_type;
-  grub_uint16_t buffer_size;
-  grub_uint32_t buffer;
-  grub_uint16_t buffer_limit;
-} __attribute__ ((packed));
-
-#define GRUB_PXE_MAC_ADDR_LEN  16
-
-typedef grub_uint8_t grub_pxe_mac_addr_t[GRUB_PXE_MAC_ADDR_LEN];
-
-struct grub_pxenv_boot_player
-{
-  grub_uint8_t opcode;
-  grub_uint8_t hw_type;                /* hardware type.  */
-  grub_uint8_t hw_len;         /* hardware addr len.  */
-  grub_uint8_t gate_hops;      /* zero it.  */
-  grub_uint32_t ident;         /* random number chosen by client.  */
-  grub_uint16_t seconds;       /* seconds since did initial bootstrap.  */
-  grub_uint16_t flags;
-  grub_uint32_t        client_ip;
-  grub_uint32_t your_ip;
-  grub_uint32_t        server_ip;
-  grub_uint32_t        gateway_ip;
-  grub_pxe_mac_addr_t mac_addr;
-  grub_uint8_t server_name[64];
-  grub_uint8_t boot_file[128];
-  union
-  {
-    grub_uint8_t d[GRUB_PXE_BOOTP_DHCPVEND];   /* raw array of vendor/dhcp options.  */
-    struct
-    {
-      grub_uint32_t magic;     /* DHCP magic cookie.  */
-      grub_uint32_t flags;     /* bootp flags/opcodes.  */
-      grub_uint8_t padding[56];
-    } v;
-  } vendor;
-} __attribute__ ((packed));
-
-struct grub_pxenv_tftp_open
-{
-  grub_uint16_t status;
-  grub_uint32_t server_ip;
-  grub_uint32_t gateway_ip;
-  grub_uint8_t filename[128];
-  grub_uint16_t tftp_port;
-  grub_uint16_t packet_size;
-} __attribute__ ((packed));
-
-struct grub_pxenv_tftp_close
-{
-  grub_uint16_t status;
-} __attribute__ ((packed));
-
-struct grub_pxenv_tftp_read
-{
-  grub_uint16_t status;
-  grub_uint16_t packet_number;
-  grub_uint16_t buffer_size;
-  grub_uint32_t buffer;
-} __attribute__ ((packed));
-
-struct grub_pxenv_tftp_get_fsize
-{
-  grub_uint16_t status;
-  grub_uint32_t server_ip;
-  grub_uint32_t gateway_ip;
-  grub_uint8_t filename[128];
-  grub_uint32_t file_size;
-} __attribute__ ((packed));
-
-struct grub_pxenv_udp_open
-{
-  grub_uint16_t status;
-  grub_uint32_t src_ip;
-} __attribute__ ((packed));
-
-struct grub_pxenv_udp_close
-{
-  grub_uint16_t status;
-} __attribute__ ((packed));
-
-struct grub_pxenv_udp_write
-{
-  grub_uint16_t status;
-  grub_uint32_t ip;
-  grub_uint32_t gateway;
-  grub_uint16_t src_port;
-  grub_uint16_t dst_port;
-  grub_uint16_t buffer_size;
-  grub_uint32_t buffer;
-} __attribute__ ((packed));
-
-struct grub_pxenv_udp_read
-{
-  grub_uint16_t status;
-  grub_uint32_t src_ip;
-  grub_uint32_t dst_ip;
-  grub_uint16_t src_port;
-  grub_uint16_t dst_port;
-  grub_uint16_t buffer_size;
-  grub_uint32_t buffer;
-} __attribute__ ((packed));
-
-struct grub_pxenv_unload_stack
-{
-  grub_uint16_t status;
-  grub_uint8_t reserved[10];
-} __attribute__ ((packed));
-
-struct grub_pxenv * EXPORT_FUNC(grub_pxe_scan) (void);
-int EXPORT_FUNC(grub_pxe_call) (int func, void * data);
-
-extern struct grub_pxenv *grub_pxe_pxenv;
-
-void grub_pxe_unload (void);
-
-#endif
-
-#endif /* GRUB_CPU_PXE_H */
diff --git a/include/grub/i386/pc/time.h b/include/grub/i386/pc/time.h
deleted file mode 100644 (file)
index 98399b6..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KERNEL_MACHINE_TIME_HEADER
-#define KERNEL_MACHINE_TIME_HEADER     1
-
-#include <grub/symbol.h>
-
-#define GRUB_TICKS_PER_SECOND  18
-
-/* Return the real time in ticks.  */
-grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
-
-#endif /* ! KERNEL_MACHINE_TIME_HEADER */
diff --git a/include/grub/i386/pc/vbe.h b/include/grub/i386/pc/vbe.h
deleted file mode 100644 (file)
index abf246f..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_VBE_MACHINE_HEADER
-#define GRUB_VBE_MACHINE_HEADER        1
-
-/* Default video mode to be used.  */
-#define GRUB_VBE_DEFAULT_VIDEO_MODE     0x101
-
-/* VBE status codes.  */
-#define GRUB_VBE_STATUS_OK             0x004f
-
-#define GRUB_VBE_CAPABILITY_DACWIDTH   (1 << 0)
-
-/* Bits from the GRUB_VBE "mode_attributes" field in the mode info struct.  */
-#define GRUB_VBE_MODEATTR_SUPPORTED                 (1 << 0)
-#define GRUB_VBE_MODEATTR_RESERVED_1                (1 << 1)
-#define GRUB_VBE_MODEATTR_BIOS_TTY_OUTPUT_SUPPORT   (1 << 2)
-#define GRUB_VBE_MODEATTR_COLOR                     (1 << 3)
-#define GRUB_VBE_MODEATTR_GRAPHICS                  (1 << 4)
-#define GRUB_VBE_MODEATTR_VGA_COMPATIBLE            (1 << 5)
-#define GRUB_VBE_MODEATTR_VGA_WINDOWED_AVAIL        (1 << 6)
-#define GRUB_VBE_MODEATTR_LFB_AVAIL                 (1 << 7)
-#define GRUB_VBE_MODEATTR_DOUBLE_SCAN_AVAIL         (1 << 8)
-#define GRUB_VBE_MODEATTR_INTERLACED_AVAIL          (1 << 9)
-#define GRUB_VBE_MODEATTR_TRIPLE_BUF_AVAIL          (1 << 10)
-#define GRUB_VBE_MODEATTR_STEREO_AVAIL              (1 << 11)
-#define GRUB_VBE_MODEATTR_DUAL_DISPLAY_START        (1 << 12)
-
-/* Values for the GRUB_VBE memory_model field in the mode info struct.  */
-#define GRUB_VBE_MEMORY_MODEL_TEXT           0x00
-#define GRUB_VBE_MEMORY_MODEL_CGA            0x01
-#define GRUB_VBE_MEMORY_MODEL_HERCULES       0x02
-#define GRUB_VBE_MEMORY_MODEL_PLANAR         0x03
-#define GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL   0x04
-#define GRUB_VBE_MEMORY_MODEL_NONCHAIN4_256  0x05
-#define GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR   0x06
-#define GRUB_VBE_MEMORY_MODEL_YUV            0x07
-
-/* Note:
-
-   Please refer to VESA BIOS Extension 3.0 Specification for more descriptive
-   meanings of following structures and how they should be used.
-
-   I have tried to maintain field name compatibility against specification
-   while following naming conventions used in GRUB.  */
-
-typedef grub_uint32_t grub_vbe_farptr_t;
-typedef grub_uint32_t grub_vbe_physptr_t;
-typedef grub_uint32_t grub_vbe_status_t;
-
-struct grub_vbe_info_block
-{
-  grub_uint8_t signature[4];
-  grub_uint16_t version;
-
-  grub_vbe_farptr_t oem_string_ptr;
-  grub_uint32_t capabilities;
-  grub_vbe_farptr_t video_mode_ptr;
-  grub_uint16_t total_memory;
-
-  grub_uint16_t oem_software_rev;
-  grub_vbe_farptr_t oem_vendor_name_ptr;
-  grub_vbe_farptr_t oem_product_name_ptr;
-  grub_vbe_farptr_t oem_product_rev_ptr;
-
-  grub_uint8_t reserved[222];
-
-  grub_uint8_t oem_data[256];
-} __attribute__ ((packed));
-
-struct grub_vbe_mode_info_block
-{
-  /* Mandatory information for all VBE revisions.  */
-  grub_uint16_t mode_attributes;
-  grub_uint8_t win_a_attributes;
-  grub_uint8_t win_b_attributes;
-  grub_uint16_t win_granularity;
-  grub_uint16_t win_size;
-  grub_uint16_t win_a_segment;
-  grub_uint16_t win_b_segment;
-  grub_vbe_farptr_t win_func_ptr;
-  grub_uint16_t bytes_per_scan_line;
-
-  /* Mandatory information for VBE 1.2 and above.  */
-  grub_uint16_t x_resolution;
-  grub_uint16_t y_resolution;
-  grub_uint8_t x_char_size;
-  grub_uint8_t y_char_size;
-  grub_uint8_t number_of_planes;
-  grub_uint8_t bits_per_pixel;
-  grub_uint8_t number_of_banks;
-  grub_uint8_t memory_model;
-  grub_uint8_t bank_size;
-  grub_uint8_t number_of_image_pages;
-  grub_uint8_t reserved;
-
-  /* Direct Color fields (required for direct/6 and YUV/7 memory models).  */
-  grub_uint8_t red_mask_size;
-  grub_uint8_t red_field_position;
-  grub_uint8_t green_mask_size;
-  grub_uint8_t green_field_position;
-  grub_uint8_t blue_mask_size;
-  grub_uint8_t blue_field_position;
-  grub_uint8_t rsvd_mask_size;
-  grub_uint8_t rsvd_field_position;
-  grub_uint8_t direct_color_mode_info;
-
-  /* Mandatory information for VBE 2.0 and above.  */
-  grub_vbe_physptr_t phys_base_addr;
-  grub_uint32_t reserved2;
-  grub_uint16_t reserved3;
-
-  /* Mandatory information for VBE 3.0 and above.  */
-  grub_uint16_t lin_bytes_per_scan_line;
-  grub_uint8_t bnk_number_of_image_pages;
-  grub_uint8_t lin_number_of_image_pages;
-  grub_uint8_t lin_red_mask_size;
-  grub_uint8_t lin_red_field_position;
-  grub_uint8_t lin_green_mask_size;
-  grub_uint8_t lin_green_field_position;
-  grub_uint8_t lin_blue_mask_size;
-  grub_uint8_t lin_blue_field_position;
-  grub_uint8_t lin_rsvd_mask_size;
-  grub_uint8_t lin_rsvd_field_position;
-  grub_uint32_t max_pixel_clock;
-
-  /* Reserved field to make structure to be 256 bytes long, VESA BIOS
-     Extension 3.0 Specification says to reserve 189 bytes here but
-     that doesn't make structure to be 256 bytes.  So additional one is
-     added here.  */
-  grub_uint8_t reserved4[189 + 1];
-} __attribute__ ((packed));
-
-struct grub_vbe_crtc_info_block
-{
-  grub_uint16_t horizontal_total;
-  grub_uint16_t horizontal_sync_start;
-  grub_uint16_t horizontal_sync_end;
-  grub_uint16_t vertical_total;
-  grub_uint16_t vertical_sync_start;
-  grub_uint16_t vertical_sync_end;
-  grub_uint8_t flags;
-  grub_uint32_t pixel_clock;
-  grub_uint16_t refresh_rate;
-  grub_uint8_t reserved[40];
-} __attribute__ ((packed));
-
-struct grub_vbe_palette_data
-{
-  grub_uint8_t blue;
-  grub_uint8_t green;
-  grub_uint8_t red;
-  grub_uint8_t alignment;
-} __attribute__ ((packed));
-
-/* Prototypes for kernel real mode thunks.  */
-
-/* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_controller_info) (struct grub_vbe_info_block *controller_info);
-
-/* Call VESA BIOS 0x4f01 to get VBE Mode Information, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_mode_info) (grub_uint32_t mode,
-                                                            struct grub_vbe_mode_info_block *mode_info);
-
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_getset_dac_palette_width) (int set, int *width);
-
-#define grub_vbe_bios_get_dac_palette_width(width)     grub_vbe_bios_getset_dac_palette_width(0, (width))
-#define grub_vbe_bios_set_dac_palette_width(width)     grub_vbe_bios_getset_dac_palette_width(1, (width))
-
-/* Call VESA BIOS 0x4f02 to set video mode, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_mode) (grub_uint32_t mode,
-                                                       struct grub_vbe_crtc_info_block *crtc_info);
-
-/* Call VESA BIOS 0x4f03 to return current VBE Mode, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_mode) (grub_uint32_t *mode);
-
-/* Call VESA BIOS 0x4f05 to set memory window, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_memory_window) (grub_uint32_t window,
-                                                                grub_uint32_t position);
-
-/* Call VESA BIOS 0x4f05 to return memory window, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_memory_window) (grub_uint32_t window,
-                                                                grub_uint32_t *position);
-
-/* Call VESA BIOS 0x4f06 to set scanline length (in bytes), return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_scanline_length) (grub_uint32_t length);
-
-/* Call VESA BIOS 0x4f06 to return scanline length (in bytes), return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_scanline_length) (grub_uint32_t *length);
-
-/* Call VESA BIOS 0x4f07 to set display start, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_display_start) (grub_uint32_t x,
-                                                                grub_uint32_t y);
-
-/* Call VESA BIOS 0x4f07 to get display start, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_display_start) (grub_uint32_t *x,
-                                                                grub_uint32_t *y);
-
-/* Call VESA BIOS 0x4f09 to set palette data, return status.  */
-grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_palette_data) (grub_uint32_t color_count,
-                                                               grub_uint32_t start_index,
-                                                               struct grub_vbe_palette_data *palette_data);
-
-/* Prototypes for helper functions.  */
-
-grub_err_t grub_vbe_probe (struct grub_vbe_info_block *info_block);
-grub_err_t grub_vbe_set_video_mode (grub_uint32_t mode,
-                                    struct grub_vbe_mode_info_block *mode_info);
-grub_err_t grub_vbe_get_video_mode (grub_uint32_t *mode);
-grub_err_t grub_vbe_get_video_mode_info (grub_uint32_t mode,
-                                         struct grub_vbe_mode_info_block *mode_info);
-
-
-#endif /* ! GRUB_VBE_MACHINE_HEADER */
diff --git a/include/grub/i386/pc/vga.h b/include/grub/i386/pc/vga.h
deleted file mode 100644 (file)
index 2724f64..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_VGA_MACHINE_HEADER
-#define GRUB_VGA_MACHINE_HEADER        1
-
-#include <grub/symbol.h>
-#include <grub/machine/memory.h>
-
-/* The VGA (at the beginning of upper memory).  */
-#define GRUB_MEMORY_MACHINE_VGA_ADDR           GRUB_MEMORY_MACHINE_UPPER
-
-/* Set the video mode to MODE and return the previous mode.  */
-unsigned char EXPORT_FUNC(grub_vga_set_mode) (unsigned char mode);
-
-#endif /* ! GRUB_VGA_MACHINE_HEADER */
diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h
deleted file mode 100644 (file)
index bab42ad..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef        GRUB_CPU_PCI_H
-#define        GRUB_CPU_PCI_H  1
-
-#include <grub/types.h>
-#include <grub/i386/io.h>
-
-#define GRUB_MACHINE_PCI_IO_BASE          0
-#define GRUB_PCI_ADDR_REG      0xcf8
-#define GRUB_PCI_DATA_REG      0xcfc
-#define GRUB_PCI_NUM_BUS        256
-#define GRUB_PCI_NUM_DEVICES    32
-
-static inline grub_uint32_t
-grub_pci_read (grub_pci_address_t addr)
-{
-  grub_outl (addr, GRUB_PCI_ADDR_REG);
-  return grub_inl (GRUB_PCI_DATA_REG);
-}
-
-static inline grub_uint16_t
-grub_pci_read_word (grub_pci_address_t addr)
-{
-  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
-  return grub_inw (GRUB_PCI_DATA_REG + (addr & 3));
-}
-
-static inline grub_uint8_t
-grub_pci_read_byte (grub_pci_address_t addr)
-{
-  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
-  return grub_inb (GRUB_PCI_DATA_REG + (addr & 3));
-}
-
-static inline void
-grub_pci_write (grub_pci_address_t addr, grub_uint32_t data)
-{
-  grub_outl (addr, GRUB_PCI_ADDR_REG);
-  grub_outl (data, GRUB_PCI_DATA_REG);
-}
-
-static inline void
-grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data)
-{
-  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
-  grub_outw (data, GRUB_PCI_DATA_REG + (addr & 3));
-}
-
-static inline void
-grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data)
-{
-  grub_outl (addr & ~3, GRUB_PCI_ADDR_REG);
-  grub_outb (data, GRUB_PCI_DATA_REG + (addr & 3));
-}
-
-static inline volatile void *
-grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)),
-                          grub_addr_t base,
-                          grub_size_t size __attribute__ ((unused)))
-{
-  return (volatile void *) base;
-}
-
-static inline void
-grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)),
-                            void *mem __attribute__ ((unused)),
-                            grub_size_t size __attribute__ ((unused)))
-{
-}
-
-
-#endif /* GRUB_CPU_PCI_H */
diff --git a/include/grub/i386/pit.h b/include/grub/i386/pit.h
deleted file mode 100644 (file)
index ff9b9a6..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KERNEL_CPU_PIT_HEADER
-#define KERNEL_CPU_PIT_HEADER   1
-
-#include <grub/types.h>
-#include <grub/err.h>
-
-void EXPORT_FUNC(grub_pit_wait) (grub_uint16_t tics);
-
-#endif /* ! KERNEL_CPU_PIT_HEADER */
diff --git a/include/grub/i386/qemu/boot.h b/include/grub/i386/qemu/boot.h
deleted file mode 100644 (file)
index 6fbb577..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_BOOT_MACHINE_HEADER
-#define GRUB_BOOT_MACHINE_HEADER       1
-
-/* The size of boot.img.  */
-#define GRUB_BOOT_MACHINE_SIZE                 (0x100000 - GRUB_BOOT_MACHINE_LINK_ADDR)
-
-/* The offset of GRUB_CORE_ENTRY_ADDR.  */
-#define GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR      0x4
-
-#endif
diff --git a/include/grub/i386/qemu/console.h b/include/grub/i386/qemu/console.h
deleted file mode 100644 (file)
index 774399a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/coreboot/console.h>
diff --git a/include/grub/i386/qemu/init.h b/include/grub/i386/qemu/init.h
deleted file mode 100644 (file)
index fd935c3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/coreboot/init.h>
diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h
deleted file mode 100644 (file)
index bc0b93d..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_KERNEL_MACHINE_HEADER
-#define GRUB_KERNEL_MACHINE_HEADER     1
-
-/* The offset of GRUB_CORE_ENTRY_ADDR.  */
-#define GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR    0x8
-
-/* The offset of GRUB_KERNEL_IMAGE_SIZE.  */
-#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE  0xc
-
-/* The offset of GRUB_PREFIX.  */
-#define GRUB_KERNEL_MACHINE_PREFIX             0x10
-
-/* End of the data section. */
-#define GRUB_KERNEL_MACHINE_DATA_END           0x50
-
-#ifndef ASM_FILE
-
-#include <grub/symbol.h>
-#include <grub/types.h>
-
-extern grub_addr_t grub_core_entry_addr;
-
-/* The size of kernel image.  */
-extern grub_int32_t grub_kernel_image_size;
-
-/* The total size of module images following the kernel.  */
-extern grub_int32_t grub_total_module_size;
-
-/* The prefix which points to the directory where GRUB modules and its
-   configuration file are located.  */
-extern char grub_prefix[];
-
-#endif /* ! ASM_FILE */
-
-#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/include/grub/i386/qemu/loader.h b/include/grub/i386/qemu/loader.h
deleted file mode 100644 (file)
index d3f36bb..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/cpu/loader.h>
diff --git a/include/grub/i386/qemu/memory.h b/include/grub/i386/qemu/memory.h
deleted file mode 100644 (file)
index de55944..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* memory.h - describe the memory map */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _GRUB_MEMORY_MACHINE_HEADER
-#define _GRUB_MEMORY_MACHINE_HEADER      1
-
-#include <grub/symbol.h>
-#include <grub/i386/pc/memory.h>
-
-#ifndef ASM_FILE
-#include <grub/err.h>
-#include <grub/types.h>
-#endif
-
-#define GRUB_MEMORY_MACHINE_LOWER_USABLE               0x9fc00         /* 640 kiB - 1 kiB */
-
-#define GRUB_MEMORY_MACHINE_UPPER_START                        0x100000        /* 1 MiB */
-#define GRUB_MEMORY_MACHINE_LOWER_SIZE                 GRUB_MEMORY_MACHINE_UPPER_START
-
-#ifndef ASM_FILE
-
-void grub_machine_mmap_init (void);
-
-grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
-     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
-
-#endif
-
-#endif /* ! _GRUB_MEMORY_MACHINE_HEADER */
diff --git a/include/grub/i386/qemu/serial.h b/include/grub/i386/qemu/serial.h
deleted file mode 100644 (file)
index 2d85634..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/coreboot/serial.h>
diff --git a/include/grub/i386/qemu/time.h b/include/grub/i386/qemu/time.h
deleted file mode 100644 (file)
index 7177c74..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/coreboot/time.h>
diff --git a/include/grub/i386/relocator.h b/include/grub/i386/relocator.h
deleted file mode 100644 (file)
index ef7fe23..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_RELOCATOR_CPU_HEADER
-#define GRUB_RELOCATOR_CPU_HEADER      1
-
-#include <grub/types.h>
-#include <grub/err.h>
-
-struct grub_relocator32_state
-{
-  grub_uint32_t esp;
-  grub_uint32_t eax;
-  grub_uint32_t ebx;
-  grub_uint32_t ecx;
-  grub_uint32_t edx;
-  grub_uint32_t eip;
-};
-
-void *grub_relocator32_alloc (grub_size_t size);
-grub_err_t grub_relocator32_boot (void *relocator, grub_uint32_t dest,
-                                 struct grub_relocator32_state state);
-void *grub_relocator32_realloc (void *relocator, grub_size_t size);
-void grub_relocator32_free (void *relocator);
-
-#endif /* ! GRUB_RELOCATOR_CPU_HEADER */
diff --git a/include/grub/i386/setjmp.h b/include/grub/i386/setjmp.h
deleted file mode 100644 (file)
index 6b6b6fd..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_SETJMP_CPU_HEADER
-#define GRUB_SETJMP_CPU_HEADER 1
-
-typedef unsigned long grub_jmp_buf[6];
-
-#ifdef __MINGW32__
-int grub_setjmp (grub_jmp_buf env) __attribute__ ((cdecl, regparm (3)));
-#else
-int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice, cdecl,
-                                                  regparm (3)));
-#endif
-void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn, cdecl,
-                                                             regparm (3)));
-
-#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/include/grub/i386/time.h b/include/grub/i386/time.h
deleted file mode 100644 (file)
index 842882c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KERNEL_CPU_TIME_HEADER
-#define KERNEL_CPU_TIME_HEADER 1
-
-static __inline void
-grub_cpu_idle (void)
-{
-  /* FIXME: this can't work until we handle interrupts.  */
-/*  __asm__ __volatile__ ("hlt"); */
-}
-
-#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/include/grub/i386/tsc.h b/include/grub/i386/tsc.h
deleted file mode 100644 (file)
index dad9d06..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KERNEL_CPU_TSC_HEADER
-#define KERNEL_CPU_TSC_HEADER   1
-
-#include <grub/types.h>
-
-/* Read the TSC value, which increments with each CPU clock cycle. */
-static __inline grub_uint64_t
-grub_get_tsc (void)
-{
-  grub_uint32_t lo, hi;
-
-  /* The CPUID instruction is a 'serializing' instruction, and
-     avoids out-of-order execution of the RDTSC instruction. */
-#ifdef APPLE_CC
-  __asm__ __volatile__ ("xorl %%eax, %%eax\n\t"
-#ifdef __x86_64__
-                       "push %%rbx\n"
-#else
-                       "push %%ebx\n"
-#endif
-                       "cpuid\n"
-#ifdef __x86_64__
-                       "pop %%rbx\n"
-#else
-                       "pop %%ebx\n"
-#endif
-                       :::"%rax", "%rcx", "%rdx");
-#else
-  __asm__ __volatile__ ("xorl %%eax, %%eax\n\t"
-                       "cpuid":::"%rax", "%rbx", "%rcx", "%rdx");
-#endif
-  /* Read TSC value.  We cannot use "=A", since this would use
-     %rax on x86_64. */
-  __asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi));
-
-  return (((grub_uint64_t) hi) << 32) | lo;
-}
-
-#ifdef __x86_64__
-
-static __inline int
-grub_cpu_is_cpuid_supported (void)
-{
-  grub_uint64_t id_supported;
-
-  __asm__ ("pushfq\n\t"
-           "popq %%rax             /* Get EFLAGS into EAX */\n\t"
-           "movq %%rax, %%rcx      /* Save original flags in ECX */\n\t"
-           "xorq $0x200000, %%rax  /* Flip ID bit in EFLAGS */\n\t"
-           "pushq %%rax            /* Store modified EFLAGS on stack */\n\t"
-           "popfq                  /* Replace current EFLAGS */\n\t"
-           "pushfq                 /* Read back the EFLAGS */\n\t"
-           "popq %%rax             /* Get EFLAGS into EAX */\n\t"
-           "xorq %%rcx, %%rax      /* Check if flag could be modified */\n\t"
-           : "=a" (id_supported)
-           : /* No inputs.  */
-           : /* Clobbered:  */ "%rcx");
-
-  return id_supported != 0;
-}
-
-#else
-
-static __inline int
-grub_cpu_is_cpuid_supported (void)
-{
-  grub_uint32_t id_supported;
-
-  __asm__ ("pushfl\n\t"
-           "popl %%eax             /* Get EFLAGS into EAX */\n\t"
-           "movl %%eax, %%ecx      /* Save original flags in ECX */\n\t"
-           "xorl $0x200000, %%eax  /* Flip ID bit in EFLAGS */\n\t"
-           "pushl %%eax            /* Store modified EFLAGS on stack */\n\t"
-           "popfl                  /* Replace current EFLAGS */\n\t"
-           "pushfl                 /* Read back the EFLAGS */\n\t"
-           "popl %%eax             /* Get EFLAGS into EAX */\n\t"
-           "xorl %%ecx, %%eax      /* Check if flag could be modified */\n\t"
-           : "=a" (id_supported)
-           : /* No inputs.  */
-           : /* Clobbered:  */ "%rcx");
-
-  return id_supported != 0;
-}
-
-#endif
-
-static __inline int
-grub_cpu_is_tsc_supported (void)
-{
-  if (! grub_cpu_is_cpuid_supported ())
-    return 0;
-
-  grub_uint32_t features;
-#ifdef APPLE_CC
-  __asm__ ("movl $1, %%eax\n\t"
-#ifdef __x86_64__
-          "push %%rbx\n"
-#else
-          "push %%ebx\n"
-#endif
-          "cpuid\n"
-#ifdef __x86_64__
-          "pop %%rbx\n"
-#else
-          "pop %%ebx\n"
-#endif
-           : "=d" (features)
-           : /* No inputs.  */
-          : /* Clobbered:  */ "%rax", "%rcx");
-#else
-  __asm__ ("movl $1, %%eax\n\t"
-           "cpuid\n"
-           : "=d" (features)
-           : /* No inputs.  */
-           : /* Clobbered:  */ "%rax", "%rbx", "%rcx");
-#endif
-  return (features & (1 << 4)) != 0;
-}
-
-void grub_tsc_init (void);
-grub_uint64_t grub_tsc_get_time_ms (void);
-
-#endif /* ! KERNEL_CPU_TSC_HEADER */
diff --git a/include/grub/i386/types.h b/include/grub/i386/types.h
deleted file mode 100644 (file)
index 0ac6473..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_TYPES_CPU_HEADER
-#define GRUB_TYPES_CPU_HEADER  1
-
-/* The size of void *.  */
-#define GRUB_TARGET_SIZEOF_VOID_P      4
-
-/* The size of long.  */
-#define GRUB_TARGET_SIZEOF_LONG                4
-
-/* i386 is little-endian.  */
-#undef GRUB_TARGET_WORDS_BIGENDIAN
-
-#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/include/grub/i386/vga_common.h b/include/grub/i386/vga_common.h
deleted file mode 100644 (file)
index f17fc01..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_VGA_COMMON_CPU_HEADER
-#define GRUB_VGA_COMMON_CPU_HEADER     1
-
-#include <grub/types.h>
-#include <grub/symbol.h>
-#include <grub/term.h>
-
-extern grub_uint8_t grub_console_cur_color;
-
-void grub_console_putchar (grub_uint32_t c);
-grub_ssize_t grub_console_getcharwidth (grub_uint32_t c);
-grub_uint16_t grub_console_getwh (void);
-void grub_console_setcolorstate (grub_term_color_state state);
-void grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color);
-void grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color);
-
-/* Implemented in both kern/i386/pc/startup.S and vga_text.c;  this symbol
-   is not exported, so there's no collision, but vga_common.c expects this
-   prototype to be the same.  */
-void grub_console_real_putchar (int c);
-
-#endif /* ! GRUB_VGA_COMMON_CPU_HEADER */
diff --git a/include/grub/i386/xnu.h b/include/grub/i386/xnu.h
deleted file mode 100644 (file)
index 3be2c3b..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_CPU_XNU_H
-#define GRUB_CPU_XNU_H 1
-
-#include <grub/err.h>
-#include <grub/efi/api.h>
-#include <grub/cpu/relocator.h>
-
-#define XNU_RELOCATOR(x) (grub_relocator32_ ## x)
-
-#define GRUB_XNU_PAGESIZE 4096
-typedef grub_uint32_t grub_xnu_ptr_t;
-
-struct grub_xnu_boot_params
-{
-  grub_uint16_t verminor;
-  grub_uint16_t vermajor;
-  /* Command line passed to xnu. */
-  grub_uint8_t cmdline[1024];
-
-  /* Later are the same as EFI's get_memory_map (). */
-  grub_xnu_ptr_t efi_mmap;
-  grub_uint32_t efi_mmap_size;
-  grub_uint32_t efi_mem_desc_size;
-  grub_uint32_t efi_mem_desc_version;
-
-  /* Later are video parameters. */
-  grub_xnu_ptr_t lfb_base;
-#define GRUB_XNU_VIDEO_SPLASH 1
-#define GRUB_XNU_VIDEO_TEXT_IN_VIDEO 2
-  grub_uint32_t lfb_mode;
-  grub_uint32_t lfb_line_len;
-  grub_uint32_t lfb_width;
-  grub_uint32_t lfb_height;
-  grub_uint32_t lfb_depth;
-
-  /* Pointer to device tree and its len. */
-  grub_xnu_ptr_t devtree;
-  grub_uint32_t devtreelen;
-
-  /* First used address by kernel or boot structures. */
-  grub_xnu_ptr_t heap_start;
-  /* Last used address by kernel or boot structures minus previous value. */
-  grub_uint32_t heap_size;
-
-  /* First memory page containing runtime code or data. */
-  grub_uint32_t efi_runtime_first_page;
-  /* First memory page containing runtime code or data minus previous value. */
-  grub_uint32_t efi_runtime_npages;
-  grub_uint32_t efi_system_table;
-  /* Size of grub_efi_uintn_t in bits. */
-  grub_uint8_t efi_uintnbits;
-} __attribute__ ((packed));
-#define GRUB_XNU_BOOTARGS_VERMINOR 5
-#define GRUB_XNU_BOOTARGS_VERMAJOR 1
-
-struct grub_xnu_devprop_header
-{
-  grub_uint32_t length;
-  /* Always set to 1. Version?  */
-  grub_uint32_t alwaysone;
-  grub_uint32_t num_devices;
-};
-
-struct grub_xnu_devprop_device_header
-{
-  grub_uint32_t length;
-  grub_uint32_t num_values;
-};
-
-void grub_cpu_xnu_unload (void);
-
-struct grub_xnu_devprop_device_descriptor;
-
-struct grub_xnu_devprop_device_descriptor *
-grub_xnu_devprop_add_device (struct grub_efi_device_path *path, int length);
-grub_err_t
-grub_xnu_devprop_remove_device (struct grub_xnu_devprop_device_descriptor *dev);
-grub_err_t
-grub_xnu_devprop_remove_property (struct grub_xnu_devprop_device_descriptor *dev,
-                                 char *name);
-grub_err_t
-grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *dev,
-                                   char *name, void *data, int datalen);
-grub_err_t
-grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor *dev,
-                                    grub_uint16_t *name, int namelen,
-                                    void *data, int datalen);
-grub_err_t
-grub_xnu_devprop_remove_property_utf8 (struct grub_xnu_devprop_device_descriptor *dev,
-                                      char *name);
-void grub_cpu_xnu_init (void);
-void grub_cpu_xnu_fini (void);
-
-extern grub_uint32_t grub_xnu_entry_point;
-extern grub_uint32_t grub_xnu_stack;
-extern grub_uint32_t grub_xnu_arg1;
-extern char grub_xnu_cmdline[1024];
-grub_err_t grub_xnu_boot (void);
-grub_err_t grub_xnu_set_video (struct grub_xnu_boot_params *bootparams_relloc);
-grub_err_t
-grub_cpu_xnu_fill_devicetree (void);
-extern grub_uint32_t grub_xnu_heap_will_be_at;
-#endif
diff --git a/include/grub/icon_manager.h b/include/grub/icon_manager.h
deleted file mode 100644 (file)
index 81c4884..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* icon_manager.h - gfxmenu icon manager. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_ICON_MANAGER_HEADER
-#define GRUB_ICON_MANAGER_HEADER 1
-
-#include <grub/menu.h>
-#include <grub/bitmap.h>
-
-/* Forward declaration of opaque structure handle type.  */
-typedef struct grub_gfxmenu_icon_manager *grub_gfxmenu_icon_manager_t;
-
-grub_gfxmenu_icon_manager_t grub_gfxmenu_icon_manager_new (void);
-void grub_gfxmenu_icon_manager_destroy (grub_gfxmenu_icon_manager_t mgr);
-void grub_gfxmenu_icon_manager_clear_cache (grub_gfxmenu_icon_manager_t mgr);
-void grub_gfxmenu_icon_manager_set_theme_path (grub_gfxmenu_icon_manager_t mgr,
-                                               const char *path);
-void grub_gfxmenu_icon_manager_set_icon_size (grub_gfxmenu_icon_manager_t mgr,
-                                              int width, int height);
-struct grub_video_bitmap *
-grub_gfxmenu_icon_manager_get_icon (grub_gfxmenu_icon_manager_t mgr,
-                                    grub_menu_entry_t entry);
-
-#endif /* GRUB_ICON_MANAGER_HEADER */
-
diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
deleted file mode 100644 (file)
index 2b2c36f..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/* ieee1275.h - Access the Open Firmware client interface.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_IEEE1275_HEADER
-#define GRUB_IEEE1275_HEADER   1
-
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/machine/ieee1275.h>
-
-/* Maps a device alias to a pathname.  */
-struct grub_ieee1275_devalias
-{
-  char *name;
-  char *path;
-  char *type;
-};
-
-struct grub_ieee1275_mem_region
-{
-  unsigned int start;
-  unsigned int size;
-};
-
-#define IEEE1275_MAX_PROP_LEN  8192
-#define IEEE1275_MAX_PATH_LEN  256
-
-#ifndef IEEE1275_CALL_ENTRY_FN
-#define IEEE1275_CALL_ENTRY_FN(args) (*grub_ieee1275_entry_fn) (args)
-#endif
-
-/* All backcalls to the firmware is done by calling an entry function
-   which was passed to us from the bootloader.  When doing the backcall,
-   a structure is passed which specifies what the firmware should do.
-   NAME is the requested service.  NR_INS and NR_OUTS is the number of
-   passed arguments and the expected number of return values, resp. */
-struct grub_ieee1275_common_hdr
-{
-  grub_ieee1275_cell_t name;
-  grub_ieee1275_cell_t nr_ins;
-  grub_ieee1275_cell_t nr_outs;
-};
-
-#define INIT_IEEE1275_COMMON(p, xname, xins, xouts) \
-  (p)->name = (grub_ieee1275_cell_t) xname; \
-  (p)->nr_ins = (grub_ieee1275_cell_t) xins; \
-  (p)->nr_outs = (grub_ieee1275_cell_t) xouts
-
-typedef grub_uint32_t grub_ieee1275_ihandle_t;
-typedef grub_uint32_t grub_ieee1275_phandle_t;
-
-extern grub_ieee1275_phandle_t EXPORT_VAR(grub_ieee1275_chosen);
-extern grub_ieee1275_ihandle_t EXPORT_VAR(grub_ieee1275_mmu);
-extern int (* EXPORT_VAR(grub_ieee1275_entry_fn)) (void *);
-
-enum grub_ieee1275_flag
-{
-  /* Old World Macintosh firmware fails seek when "dev:0" is opened.  */
-  GRUB_IEEE1275_FLAG_NO_PARTITION_0,
-
-  /* Apple firmware runs in translated mode and requires use of the "map"
-     method.  Other firmware runs in untranslated mode and doesn't like "map"
-     calls.  */
-  GRUB_IEEE1275_FLAG_REAL_MODE,
-
-  /* CHRP specifies partitions are numbered from 1 (partition 0 refers to the
-     whole disk). However, CodeGen firmware numbers partitions from 0.  */
-  GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS,
-
-  /* CodeGen firmware does not correctly implement "output-device output" */
-  GRUB_IEEE1275_FLAG_BROKEN_OUTPUT,
-
-  /* OLPC / XO firmware hangs when accessing USB devices.  */
-  GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY,
-
-  /* Open Hack'Ware stops when trying to set colors */
-  GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS,
-
-  /* Open Hack'Ware stops when grub_ieee1275_interpret is used.  */
-  GRUB_IEEE1275_FLAG_CANNOT_INTERPRET,
-
-  /* Open Hack'Ware has no memory map, just claim what we need.  */
-  GRUB_IEEE1275_FLAG_FORCE_CLAIM,
-
-  /* Open Hack'Ware don't support the ANSI sequence.  */
-  GRUB_IEEE1275_FLAG_NO_ANSI,
-};
-
-extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag);
-extern void EXPORT_FUNC(grub_ieee1275_set_flag) (enum grub_ieee1275_flag flag);
-
-\f
-
-
-void EXPORT_FUNC(grub_ieee1275_init) (void);
-int EXPORT_FUNC(grub_ieee1275_finddevice) (char *name,
-                                          grub_ieee1275_phandle_t *phandlep);
-int EXPORT_FUNC(grub_ieee1275_get_property) (grub_ieee1275_phandle_t phandle,
-                                            const char *property, void *buf,
-                                            grub_size_t size,
-                                            grub_ssize_t *actual);
-int EXPORT_FUNC(grub_ieee1275_get_integer_property) (grub_ieee1275_phandle_t phandle,
-                                                    const char *property, grub_uint32_t *buf,
-                                                    grub_size_t size,
-                                                    grub_ssize_t *actual);
-int EXPORT_FUNC(grub_ieee1275_next_property) (grub_ieee1275_phandle_t phandle,
-                                             char *prev_prop, char *prop);
-int EXPORT_FUNC(grub_ieee1275_get_property_length)
-     (grub_ieee1275_phandle_t phandle, const char *prop, grub_ssize_t *length);
-int EXPORT_FUNC(grub_ieee1275_instance_to_package)
-     (grub_ieee1275_ihandle_t ihandle, grub_ieee1275_phandle_t *phandlep);
-int EXPORT_FUNC(grub_ieee1275_package_to_path) (grub_ieee1275_phandle_t phandle,
-                                               char *path, grub_size_t len,
-                                               grub_ssize_t *actual);
-int EXPORT_FUNC(grub_ieee1275_instance_to_path)
-     (grub_ieee1275_ihandle_t ihandle, char *path, grub_size_t len,
-      grub_ssize_t *actual);
-int EXPORT_FUNC(grub_ieee1275_write) (grub_ieee1275_ihandle_t ihandle,
-                                     void *buffer, grub_size_t len,
-                                     grub_ssize_t *actualp);
-int EXPORT_FUNC(grub_ieee1275_read) (grub_ieee1275_ihandle_t ihandle,
-                                    void *buffer, grub_size_t len,
-                                    grub_ssize_t *actualp);
-int EXPORT_FUNC(grub_ieee1275_seek) (grub_ieee1275_ihandle_t ihandle,
-                                    grub_disk_addr_t pos,
-                                    grub_ssize_t *result);
-int EXPORT_FUNC(grub_ieee1275_peer) (grub_ieee1275_phandle_t node,
-                                    grub_ieee1275_phandle_t *result);
-int EXPORT_FUNC(grub_ieee1275_child) (grub_ieee1275_phandle_t node,
-                                     grub_ieee1275_phandle_t *result);
-int EXPORT_FUNC(grub_ieee1275_parent) (grub_ieee1275_phandle_t node,
-                                      grub_ieee1275_phandle_t *result);
-int EXPORT_FUNC(grub_ieee1275_interpret) (const char *command,
-                                         grub_ieee1275_cell_t *catch);
-int EXPORT_FUNC(grub_ieee1275_enter) (void);
-void EXPORT_FUNC(grub_ieee1275_exit) (void) __attribute__ ((noreturn));
-int EXPORT_FUNC(grub_ieee1275_open) (const char *node,
-                                    grub_ieee1275_ihandle_t *result);
-int EXPORT_FUNC(grub_ieee1275_close) (grub_ieee1275_ihandle_t ihandle);
-int EXPORT_FUNC(grub_ieee1275_claim) (grub_addr_t addr, grub_size_t size,
-                                     unsigned int align, grub_addr_t *result);
-int EXPORT_FUNC(grub_ieee1275_release) (grub_addr_t addr, grub_size_t size);
-int EXPORT_FUNC(grub_ieee1275_set_property) (grub_ieee1275_phandle_t phandle,
-                                            const char *propname, void *buf,
-                                            grub_size_t size,
-                                            grub_ssize_t *actual);
-int EXPORT_FUNC(grub_ieee1275_set_color) (grub_ieee1275_ihandle_t ihandle,
-                                         int index, int r, int g, int b);
-int EXPORT_FUNC(grub_ieee1275_milliseconds) (grub_uint32_t *msecs);
-
-
-int EXPORT_FUNC(grub_devalias_iterate)
-     (int (*hook) (struct grub_ieee1275_devalias *alias));
-int EXPORT_FUNC(grub_children_iterate) (char *devpath,
-     int (*hook) (struct grub_ieee1275_devalias *alias));
-grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
-     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
-int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
-
-int
-EXPORT_FUNC(grub_ieee1275_map) (grub_addr_t phys, grub_addr_t virt,
-                               grub_size_t size, grub_uint32_t mode);
-
-char *EXPORT_FUNC(grub_ieee1275_encode_devname) (const char *path);
-char *EXPORT_FUNC(grub_ieee1275_get_filename) (const char *path);
-
-int EXPORT_FUNC(grub_ieee1275_devices_iterate) (int (*hook)
-                                               (struct grub_ieee1275_devalias *
-                                                alias));
-
-#endif /* ! GRUB_IEEE1275_HEADER */
diff --git a/include/grub/ieee1275/ofdisk.h b/include/grub/ieee1275/ofdisk.h
deleted file mode 100644 (file)
index 2f69e3f..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_OFDISK_HEADER
-#define GRUB_OFDISK_HEADER     1
-
-extern void grub_ofdisk_init (void);
-extern void grub_ofdisk_fini (void);
-
-#endif /* ! GRUB_INIT_HEADER */
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
deleted file mode 100644 (file)
index bf52ffc..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_KERNEL_HEADER
-#define GRUB_KERNEL_HEADER     1
-
-#include <grub/types.h>
-#include <grub/symbol.h>
-
-enum
-{
-  OBJ_TYPE_ELF,
-  OBJ_TYPE_MEMDISK,
-  OBJ_TYPE_CONFIG,
-  OBJ_TYPE_FONT
-};
-
-/* The module header.  */
-struct grub_module_header
-{
-  /* The type of object.  */
-  grub_uint8_t type;
-  /* The size of object (including this header).  */
-  grub_uint32_t size;
-};
-
-/* "gmim" (GRUB Module Info Magic).  */
-#define GRUB_MODULE_MAGIC 0x676d696d
-
-struct grub_module_info
-{
-  /* Magic number so we know we have modules present.  */
-  grub_uint32_t magic;
-#if GRUB_TARGET_SIZEOF_VOID_P == 8
-  grub_uint32_t padding;
-#endif
-  /* The offset of the modules.  */
-  grub_target_off_t offset;
-  /* The size of all modules plus this header.  */
-  grub_target_size_t size;
-};
-
-extern grub_addr_t grub_arch_modules_addr (void);
-
-extern void EXPORT_FUNC(grub_module_iterate) (int (*hook) (struct grub_module_header *));
-
-grub_addr_t grub_modules_get_end (void);
-
-/* The start point of the C code.  */
-void grub_main (void);
-
-/* The machine-specific initialization. This must initialize memory.  */
-void grub_machine_init (void);
-
-/* The machine-specific finalization.  */
-void EXPORT_FUNC(grub_machine_fini) (void);
-
-/* The machine-specific prefix initialization.  */
-void grub_machine_set_prefix (void);
-
-/* Register all the exported symbols. This is automatically generated.  */
-void grub_register_exported_symbols (void);
-
-#endif /* ! GRUB_KERNEL_HEADER */
diff --git a/include/grub/lib/LzFind.h b/include/grub/lib/LzFind.h
deleted file mode 100644 (file)
index 69447b6..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (c) 1999-2008 Igor Pavlov
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
- * to adapt it to GRUB's requirement.
- *
- * See <http://www.7-zip.org>, for more information about LZMA.
- */
-
-#ifndef __LZFIND_H
-#define __LZFIND_H
-
-#include <grub/lib/LzmaTypes.h>
-
-typedef UInt32 CLzRef;
-
-typedef struct _CMatchFinder
-{
-  Byte *buffer;
-  UInt32 pos;
-  UInt32 posLimit;
-  UInt32 streamPos;
-  UInt32 lenLimit;
-
-  UInt32 cyclicBufferPos;
-  UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
-
-  UInt32 matchMaxLen;
-  CLzRef *hash;
-  CLzRef *son;
-  UInt32 hashMask;
-  UInt32 cutValue;
-
-  Byte *bufferBase;
-  ISeqInStream *stream;
-  int streamEndWasReached;
-
-  UInt32 blockSize;
-  UInt32 keepSizeBefore;
-  UInt32 keepSizeAfter;
-
-  UInt32 numHashBytes;
-  int directInput;
-  int btMode;
-  /* int skipModeBits; */
-  int bigHash;
-  UInt32 historySize;
-  UInt32 fixedHashSize;
-  UInt32 hashSizeSum;
-  UInt32 numSons;
-  SRes result;
-  UInt32 crc[256];
-} CMatchFinder;
-
-#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
-#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
-
-#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
-
-int MatchFinder_NeedMove(CMatchFinder *p);
-Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
-void MatchFinder_MoveBlock(CMatchFinder *p);
-void MatchFinder_ReadIfRequired(CMatchFinder *p);
-
-void MatchFinder_Construct(CMatchFinder *p);
-
-/* Conditions:
-     historySize <= 3 GB
-     keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
-*/
-int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
-    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
-    ISzAlloc *alloc);
-void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
-void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
-
-UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
-    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
-    UInt32 *distances, UInt32 maxLen);
-
-/*
-Conditions:
-  Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
-  Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
-*/
-
-typedef void (*Mf_Init_Func)(void *object);
-typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
-typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
-typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
-typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
-typedef void (*Mf_Skip_Func)(void *object, UInt32);
-
-typedef struct _IMatchFinder
-{
-  Mf_Init_Func Init;
-  Mf_GetIndexByte_Func GetIndexByte;
-  Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
-  Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
-  Mf_GetMatches_Func GetMatches;
-  Mf_Skip_Func Skip;
-} IMatchFinder;
-
-void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
-
-void MatchFinder_Init(CMatchFinder *p);
-UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
-UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
-void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
-void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
-
-#endif
diff --git a/include/grub/lib/LzHash.h b/include/grub/lib/LzHash.h
deleted file mode 100644 (file)
index c3d5586..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (c) 1999-2008 Igor Pavlov
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
- * to adapt it to GRUB's requirement.
- *
- * See <http://www.7-zip.org>, for more information about LZMA.
- */
-
-#ifndef __LZHASH_H
-#define __LZHASH_H
-
-#define kHash2Size (1 << 10)
-#define kHash3Size (1 << 16)
-#define kHash4Size (1 << 20)
-
-#define kFix3HashSize (kHash2Size)
-#define kFix4HashSize (kHash2Size + kHash3Size)
-#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
-
-#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
-
-#define HASH3_CALC { \
-  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-  hash2Value = temp & (kHash2Size - 1); \
-  hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
-
-#define HASH4_CALC { \
-  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-  hash2Value = temp & (kHash2Size - 1); \
-  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
-  hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
-
-#define HASH5_CALC { \
-  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-  hash2Value = temp & (kHash2Size - 1); \
-  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
-  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
-  hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
-  hash4Value &= (kHash4Size - 1); }
-
-/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
-#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
-
-
-#define MT_HASH2_CALC \
-  hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
-
-#define MT_HASH3_CALC { \
-  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-  hash2Value = temp & (kHash2Size - 1); \
-  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
-
-#define MT_HASH4_CALC { \
-  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-  hash2Value = temp & (kHash2Size - 1); \
-  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
-  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
-
-#endif
diff --git a/include/grub/lib/LzmaDec.h b/include/grub/lib/LzmaDec.h
deleted file mode 100644 (file)
index 1e66b74..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (c) 1999-2008 Igor Pavlov
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
- * to adapt it to GRUB's requirement.
- *
- * See <http://www.7-zip.org>, for more information about LZMA.
- */
-
-#ifndef __LZMADEC_H
-#define __LZMADEC_H
-
-#include "Types.h"
-
-/* #define _LZMA_PROB32 */
-/* _LZMA_PROB32 can increase the speed on some CPUs,
-   but memory usage for CLzmaDec::probs will be doubled in that case */
-
-#ifdef _LZMA_PROB32
-#define CLzmaProb UInt32
-#else
-#define CLzmaProb UInt16
-#endif
-
-
-/* ---------- LZMA Properties ---------- */
-
-#define LZMA_PROPS_SIZE 5
-
-typedef struct _CLzmaProps
-{
-  unsigned lc, lp, pb;
-  UInt32 dicSize;
-} CLzmaProps;
-
-/* LzmaProps_Decode - decodes properties
-Returns:
-  SZ_OK
-  SZ_ERROR_UNSUPPORTED - Unsupported properties
-*/
-
-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
-
-
-/* ---------- LZMA Decoder state ---------- */
-
-/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
-   Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
-
-#define LZMA_REQUIRED_INPUT_MAX 20
-
-typedef struct
-{
-  CLzmaProps prop;
-  CLzmaProb *probs;
-  Byte *dic;
-  const Byte *buf;
-  UInt32 range, code;
-  SizeT dicPos;
-  SizeT dicBufSize;
-  UInt32 processedPos;
-  UInt32 checkDicSize;
-  unsigned state;
-  UInt32 reps[4];
-  unsigned remainLen;
-  int needFlush;
-  int needInitState;
-  UInt32 numProbs;
-  unsigned tempBufSize;
-  Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
-} CLzmaDec;
-
-#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
-
-void LzmaDec_Init(CLzmaDec *p);
-
-/* There are two types of LZMA streams:
-     0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
-     1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
-
-typedef enum
-{
-  LZMA_FINISH_ANY,   /* finish at any point */
-  LZMA_FINISH_END    /* block must be finished at the end */
-} ELzmaFinishMode;
-
-/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
-
-   You must use LZMA_FINISH_END, when you know that current output buffer
-   covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
-
-   If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
-   and output value of destLen will be less than output buffer size limit.
-   You can check status result also.
-
-   You can use multiple checks to test data integrity after full decompression:
-     1) Check Result and "status" variable.
-     2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
-     3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
-        You must use correct finish mode in that case. */
-
-typedef enum
-{
-  LZMA_STATUS_NOT_SPECIFIED,               /* use main error code instead */
-  LZMA_STATUS_FINISHED_WITH_MARK,          /* stream was finished with end mark. */
-  LZMA_STATUS_NOT_FINISHED,                /* stream was not finished */
-  LZMA_STATUS_NEEDS_MORE_INPUT,            /* you must provide more input bytes */
-  LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK  /* there is probability that stream was finished without end mark */
-} ELzmaStatus;
-
-/* ELzmaStatus is used only as output value for function call */
-
-
-/* ---------- Interfaces ---------- */
-
-/* There are 3 levels of interfaces:
-     1) Dictionary Interface
-     2) Buffer Interface
-     3) One Call Interface
-   You can select any of these interfaces, but don't mix functions from different
-   groups for same object. */
-
-
-/* There are two variants to allocate state for Dictionary Interface:
-     1) LzmaDec_Allocate / LzmaDec_Free
-     2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
-   You can use variant 2, if you set dictionary buffer manually.
-   For Buffer Interface you must always use variant 1.
-
-LzmaDec_Allocate* can return:
-  SZ_OK
-  SZ_ERROR_MEM         - Memory allocation error
-  SZ_ERROR_UNSUPPORTED - Unsupported properties
-*/
-
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
-
-SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
-void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
-
-/* ---------- Dictionary Interface ---------- */
-
-/* You can use it, if you want to eliminate the overhead for data copying from
-   dictionary to some other external buffer.
-   You must work with CLzmaDec variables directly in this interface.
-
-   STEPS:
-     LzmaDec_Constr()
-     LzmaDec_Allocate()
-     for (each new stream)
-     {
-       LzmaDec_Init()
-       while (it needs more decompression)
-       {
-         LzmaDec_DecodeToDic()
-         use data from CLzmaDec::dic and update CLzmaDec::dicPos
-       }
-     }
-     LzmaDec_Free()
-*/
-
-/* LzmaDec_DecodeToDic
-
-   The decoding to internal dictionary buffer (CLzmaDec::dic).
-   You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
-
-finishMode:
-  It has meaning only if the decoding reaches output limit (dicLimit).
-  LZMA_FINISH_ANY - Decode just dicLimit bytes.
-  LZMA_FINISH_END - Stream must be finished after dicLimit.
-
-Returns:
-  SZ_OK
-    status:
-      LZMA_STATUS_FINISHED_WITH_MARK
-      LZMA_STATUS_NOT_FINISHED
-      LZMA_STATUS_NEEDS_MORE_INPUT
-      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
-  SZ_ERROR_DATA - Data error
-*/
-
-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
-    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
-
-
-/* ---------- Buffer Interface ---------- */
-
-/* It's zlib-like interface.
-   See LzmaDec_DecodeToDic description for information about STEPS and return results,
-   but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
-   to work with CLzmaDec variables manually.
-
-finishMode:
-  It has meaning only if the decoding reaches output limit (*destLen).
-  LZMA_FINISH_ANY - Decode just destLen bytes.
-  LZMA_FINISH_END - Stream must be finished after (*destLen).
-*/
-
-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
-    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
-
-
-/* ---------- One Call Interface ---------- */
-
-/* LzmaDecode
-
-finishMode:
-  It has meaning only if the decoding reaches output limit (*destLen).
-  LZMA_FINISH_ANY - Decode just destLen bytes.
-  LZMA_FINISH_END - Stream must be finished after (*destLen).
-
-Returns:
-  SZ_OK
-    status:
-      LZMA_STATUS_FINISHED_WITH_MARK
-      LZMA_STATUS_NOT_FINISHED
-      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
-  SZ_ERROR_DATA - Data error
-  SZ_ERROR_MEM  - Memory allocation error
-  SZ_ERROR_UNSUPPORTED - Unsupported properties
-  SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
-*/
-
-SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
-    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
-    ELzmaStatus *status, ISzAlloc *alloc);
-
-#endif
diff --git a/include/grub/lib/LzmaEnc.h b/include/grub/lib/LzmaEnc.h
deleted file mode 100644 (file)
index fc156a4..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (c) 1999-2008 Igor Pavlov
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
- * to adapt it to GRUB's requirement.
- *
- * See <http://www.7-zip.org>, for more information about LZMA.
- */
-
-#ifndef __LZMAENC_H
-#define __LZMAENC_H
-
-#include "LzmaTypes.h"
-
-#define LZMA_PROPS_SIZE 5
-
-typedef struct _CLzmaEncProps
-{
-  int level;       /*  0 <= level <= 9 */
-  UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
-                      (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
-                       default = (1 << 24) */
-  int lc;          /* 0 <= lc <= 8, default = 3 */
-  int lp;          /* 0 <= lp <= 4, default = 0 */
-  int pb;          /* 0 <= pb <= 4, default = 2 */
-  int algo;        /* 0 - fast, 1 - normal, default = 1 */
-  int fb;          /* 5 <= fb <= 273, default = 32 */
-  int btMode;      /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
-  int numHashBytes; /* 2, 3 or 4, default = 4 */
-  UInt32 mc;        /* 1 <= mc <= (1 << 30), default = 32 */
-  unsigned writeEndMark;  /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
-  int numThreads;  /* 1 or 2, default = 2 */
-} CLzmaEncProps;
-
-void LzmaEncProps_Init(CLzmaEncProps *p);
-void LzmaEncProps_Normalize(CLzmaEncProps *p);
-UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
-
-
-/* ---------- CLzmaEncHandle Interface ---------- */
-
-/* LzmaEnc_* functions can return the following exit codes:
-Returns:
-  SZ_OK           - OK
-  SZ_ERROR_MEM    - Memory allocation error
-  SZ_ERROR_PARAM  - Incorrect parameter in props
-  SZ_ERROR_WRITE  - Write callback error.
-  SZ_ERROR_PROGRESS - some break from progress callback
-  SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
-*/
-
-typedef void * CLzmaEncHandle;
-
-CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
-void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
-SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
-SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
-SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
-    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-
-/* ---------- One Call Interface ---------- */
-
-/* LzmaEncode
-Return code:
-  SZ_OK               - OK
-  SZ_ERROR_MEM        - Memory allocation error
-  SZ_ERROR_PARAM      - Incorrect parameter
-  SZ_ERROR_OUTPUT_EOF - output buffer overflow
-  SZ_ERROR_THREAD     - errors in multithreading functions (only for Mt version)
-*/
-
-SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
-    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-
-#endif
diff --git a/include/grub/lib/LzmaTypes.h b/include/grub/lib/LzmaTypes.h
deleted file mode 100644 (file)
index 1e783a2..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (c) 1999-2008 Igor Pavlov
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
- * to adapt it to GRUB's requirement.
- *
- * See <http://www.7-zip.org>, for more information about LZMA.
- */
-
-#ifndef __7Z_TYPES_H
-#define __7Z_TYPES_H
-
-#define SZ_OK 0
-
-#define SZ_ERROR_DATA 1
-#define SZ_ERROR_MEM 2
-#define SZ_ERROR_CRC 3
-#define SZ_ERROR_UNSUPPORTED 4
-#define SZ_ERROR_PARAM 5
-#define SZ_ERROR_INPUT_EOF 6
-#define SZ_ERROR_OUTPUT_EOF 7
-#define SZ_ERROR_READ 8
-#define SZ_ERROR_WRITE 9
-#define SZ_ERROR_PROGRESS 10
-#define SZ_ERROR_FAIL 11
-#define SZ_ERROR_THREAD 12
-
-#define SZ_ERROR_ARCHIVE 16
-#define SZ_ERROR_NO_ARCHIVE 17
-
-typedef int SRes;
-
-#ifndef RINOK
-#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
-#endif
-
-typedef unsigned char Byte;
-typedef short Int16;
-typedef unsigned short UInt16;
-
-#ifdef _LZMA_UINT32_IS_ULONG
-typedef long Int32;
-typedef unsigned long UInt32;
-#else
-typedef int Int32;
-typedef unsigned int UInt32;
-#endif
-
-/* #define _SZ_NO_INT_64 */
-/* define it if your compiler doesn't support 64-bit integers */
-
-#ifdef _SZ_NO_INT_64
-
-typedef long Int64;
-typedef unsigned long UInt64;
-
-#else
-
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-typedef __int64 Int64;
-typedef unsigned __int64 UInt64;
-#else
-typedef long long int Int64;
-typedef unsigned long long int UInt64;
-#endif
-
-#endif
-
-#ifdef _LZMA_NO_SYSTEM_SIZE_T
-typedef UInt32 SizeT;
-#else
-#include <stddef.h>
-typedef size_t SizeT;
-#endif
-
-typedef int Bool;
-#define True 1
-#define False 0
-
-
-#ifdef _MSC_VER
-
-#if _MSC_VER >= 1300
-#define MY_NO_INLINE __declspec(noinline)
-#else
-#define MY_NO_INLINE
-#endif
-
-#define MY_CDECL __cdecl
-#define MY_STD_CALL __stdcall
-#define MY_FAST_CALL MY_NO_INLINE __fastcall
-
-#else
-
-#define MY_CDECL
-#define MY_STD_CALL
-#define MY_FAST_CALL
-
-#endif
-
-
-/* The following interfaces use first parameter as pointer to structure */
-
-typedef struct
-{
-  SRes (*Read)(void *p, void *buf, size_t *size);
-    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
-       (output(*size) < input(*size)) is allowed */
-} ISeqInStream;
-
-typedef struct
-{
-  size_t (*Write)(void *p, const void *buf, size_t size);
-    /* Returns: result - the number of actually written bytes.
-      (result < size) means error */
-} ISeqOutStream;
-
-typedef struct
-{
-  SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
-    /* Returns: result. (result != SZ_OK) means break.
-       Value (UInt64)(Int64)-1 for size means unknown value. */
-} ICompressProgress;
-
-typedef struct
-{
-  void *(*Alloc)(void *p, size_t size);
-  void (*Free)(void *p, void *address); /* address can be 0 */
-} ISzAlloc;
-
-#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
-#define IAlloc_Free(p, a) (p)->Free((p), a)
-
-#endif
diff --git a/include/grub/lib/arg.h b/include/grub/lib/arg.h
deleted file mode 100644 (file)
index e6af60c..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_ARG_HEADER
-#define GRUB_ARG_HEADER        1
-
-#include <grub/symbol.h>
-#include <grub/err.h>
-#include <grub/types.h>
-
-enum grub_arg_type
-  {
-    ARG_TYPE_NONE,
-    ARG_TYPE_STRING,
-    ARG_TYPE_INT,
-    ARG_TYPE_DEVICE,
-    ARG_TYPE_FILE,
-    ARG_TYPE_DIR,
-    ARG_TYPE_PATHNAME
-  };
-
-typedef enum grub_arg_type grub_arg_type_t;
-
-/* Flags for the option field op grub_arg_option.  */
-#define GRUB_ARG_OPTION_OPTIONAL       (1 << 1)
-
-enum grub_key_type
-  {
-    GRUB_KEY_ARG = -1,
-    GRUB_KEY_END = -2
-  };
-typedef enum grub_key_type grub_arg_key_type_t;
-
-struct grub_arg_option
-{
-  const char *longarg;
-  int shortarg;
-  int flags;
-  char *doc;
-  char *arg;
-  grub_arg_type_t type;
-};
-
-struct grub_arg_list
-{
-  int set;
-  char *arg;
-};
-
-struct grub_extcmd;
-
-int grub_arg_parse (struct grub_extcmd *cmd, int argc, char **argv,
-                   struct grub_arg_list *usr, char ***args, int *argnum);
-
-void grub_arg_show_help (struct grub_extcmd *cmd);
-
-#endif /* ! GRUB_ARG_HEADER */
diff --git a/include/grub/lib/crc.h b/include/grub/lib/crc.h
deleted file mode 100644 (file)
index ff7284d..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* crc.h - prototypes for crc */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_CRC_H
-#define GRUB_CRC_H     1
-
-grub_uint32_t grub_getcrc32 (grub_uint32_t crc, void *buf, int size);
-
-#endif /* ! GRUB_CRC_H */
diff --git a/include/grub/lib/envblk.h b/include/grub/lib/envblk.h
deleted file mode 100644 (file)
index 368ba53..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_ENVBLK_HEADER
-#define GRUB_ENVBLK_HEADER     1
-
-#define GRUB_ENVBLK_SIGNATURE  "# GRUB Environment Block\n"
-#define GRUB_ENVBLK_DEFCFG     "grubenv"
-
-#ifndef ASM_FILE
-
-struct grub_envblk
-{
-  char *buf;
-  grub_size_t size;
-};
-typedef struct grub_envblk *grub_envblk_t;
-
-grub_envblk_t grub_envblk_open (char *buf, grub_size_t size);
-int grub_envblk_set (grub_envblk_t envblk, const char *name, const char *value);
-void grub_envblk_delete (grub_envblk_t envblk, const char *name);
-void grub_envblk_iterate (grub_envblk_t envblk,
-                          int hook (const char *name, const char *value));
-void grub_envblk_close (grub_envblk_t envblk);
-
-static inline char *
-grub_envblk_buffer (const grub_envblk_t envblk)
-{
-  return envblk->buf;
-}
-
-static inline grub_size_t
-grub_envblk_size (const grub_envblk_t envblk)
-{
-  return envblk->size;
-}
-
-#endif /* ! ASM_FILE */
-
-#endif /* ! GRUB_ENVBLK_HEADER */
diff --git a/include/grub/lib/hexdump.h b/include/grub/lib/hexdump.h
deleted file mode 100644 (file)
index 23c6fa6..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* hexdump.h - prototypes for dump */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_HEXDUMP_H
-#define GRUB_HEXDUMP_H 1
-
-void hexdump (unsigned long bse,char* buf,int len);
-
-#endif /* ! GRUB_HEXDUMP_H */
diff --git a/include/grub/libgcc.h b/include/grub/libgcc.h
deleted file mode 100644 (file)
index d0adae8..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-/* On x86 these functions aren't really needed. Save some space.  */
-#if !defined (__i386__) && !defined (__x86_64__)
-# ifdef HAVE___ASHLDI3
-void EXPORT_FUNC (__ashldi3) (void);
-# endif
-# ifdef HAVE___ASHRDI3
-void EXPORT_FUNC (__ashrdi3) (void);
-# endif
-# ifdef HAVE___LSHRDI3
-void EXPORT_FUNC (__lshrdi3) (void);
-# endif
-# ifdef HAVE___UCMPDI2
-void EXPORT_FUNC (__ucmpdi2) (void);
-# endif
-# ifdef HAVE___BSWAPSI2
-void EXPORT_FUNC (__bswapsi2) (void);
-# endif
-# ifdef HAVE___BSWAPDI2
-void EXPORT_FUNC (__bswapdi2) (void);
-# endif
-#endif
-
-#ifdef HAVE___TRAMPOLINE_SETUP
-void EXPORT_FUNC (__trampoline_setup) (void);
-#endif
-
-#ifdef HAVE__RESTGPR_14_X
-void EXPORT_FUNC (_restgpr_14_x) (void);
-void EXPORT_FUNC (_restgpr_15_x) (void);
-void EXPORT_FUNC (_restgpr_16_x) (void);
-void EXPORT_FUNC (_restgpr_17_x) (void);
-void EXPORT_FUNC (_restgpr_18_x) (void);
-void EXPORT_FUNC (_restgpr_19_x) (void);
-void EXPORT_FUNC (_restgpr_20_x) (void);
-void EXPORT_FUNC (_restgpr_21_x) (void);
-void EXPORT_FUNC (_restgpr_22_x) (void);
-void EXPORT_FUNC (_restgpr_23_x) (void);
-void EXPORT_FUNC (_restgpr_24_x) (void);
-void EXPORT_FUNC (_restgpr_25_x) (void);
-void EXPORT_FUNC (_restgpr_26_x) (void);
-void EXPORT_FUNC (_restgpr_27_x) (void);
-void EXPORT_FUNC (_restgpr_28_x) (void);
-void EXPORT_FUNC (_restgpr_29_x) (void);
-void EXPORT_FUNC (_restgpr_30_x) (void);
-void EXPORT_FUNC (_restgpr_31_x) (void);
-void EXPORT_FUNC (_savegpr_14) (void);
-void EXPORT_FUNC (_savegpr_15) (void);
-void EXPORT_FUNC (_savegpr_16) (void);
-void EXPORT_FUNC (_savegpr_17) (void);
-void EXPORT_FUNC (_savegpr_18) (void);
-void EXPORT_FUNC (_savegpr_19) (void);
-void EXPORT_FUNC (_savegpr_20) (void);
-void EXPORT_FUNC (_savegpr_21) (void);
-void EXPORT_FUNC (_savegpr_22) (void);
-void EXPORT_FUNC (_savegpr_23) (void);
-void EXPORT_FUNC (_savegpr_24) (void);
-void EXPORT_FUNC (_savegpr_25) (void);
-void EXPORT_FUNC (_savegpr_26) (void);
-void EXPORT_FUNC (_savegpr_27) (void);
-void EXPORT_FUNC (_savegpr_28) (void);
-void EXPORT_FUNC (_savegpr_29) (void);
-void EXPORT_FUNC (_savegpr_30) (void);
-void EXPORT_FUNC (_savegpr_31) (void);
-#endif
diff --git a/include/grub/libpciaccess.h b/include/grub/libpciaccess.h
deleted file mode 100644 (file)
index 4d2b3bd..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-void EXPORT_FUNC (pci_slot_match_iterator_create) (void);
-void EXPORT_FUNC (pci_system_cleanup) (void);
-void EXPORT_FUNC (pci_device_unmap_range) (void);
-void EXPORT_FUNC (pci_iterator_destroy) (void);
-void EXPORT_FUNC (pci_device_map_range) (void);
-void EXPORT_FUNC (pci_device_cfg_read_u32) (void);
-void EXPORT_FUNC (pci_device_next) (void);
-void EXPORT_FUNC (pci_system_init) (void);
diff --git a/include/grub/libusb.h b/include/grub/libusb.h
deleted file mode 100644 (file)
index 26548bc..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-void EXPORT_FUNC (usb_bulk_write) (void);
-void EXPORT_FUNC (usb_find_busses) (void);
-void EXPORT_FUNC (usb_init) (void);
-void EXPORT_FUNC (usb_find_devices) (void);
-void EXPORT_FUNC (usb_open) (void);
-void EXPORT_FUNC (usb_get_busses) (void);
-void EXPORT_FUNC (usb_control_msg) (void);
-void EXPORT_FUNC (usb_release_interface) (void);
-void EXPORT_FUNC (usb_close) (void);
-void EXPORT_FUNC (usb_bulk_read) (void);
-void EXPORT_FUNC (usb_claim_interface) (void);
diff --git a/include/grub/list.h b/include/grub/list.h
deleted file mode 100644 (file)
index 5559158..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/* list.h - header for grub list */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_LIST_HEADER
-#define GRUB_LIST_HEADER 1
-
-#include <grub/symbol.h>
-#include <grub/types.h>
-#include <grub/misc.h>
-
-struct grub_list
-{
-  struct grub_list *next;
-};
-typedef struct grub_list *grub_list_t;
-
-typedef int (*grub_list_hook_t) (grub_list_t item);
-typedef int (*grub_list_test_t) (grub_list_t new_item, grub_list_t item);
-
-void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item);
-void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head);
-void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item);
-int EXPORT_FUNC(grub_list_iterate) (grub_list_t head, grub_list_hook_t hook);
-void EXPORT_FUNC(grub_list_insert) (grub_list_t *head, grub_list_t item,
-                                   grub_list_test_t test);
-
-static inline void *
-grub_bad_type_cast_real (int line, const char *file)
-     ATTRIBUTE_ERROR ("bad type cast between incompatible grub types");
-
-static inline void *
-grub_bad_type_cast_real (int line, const char *file)
-{
-  grub_fatal ("error:%s:%u: bad type cast between incompatible grub types",
-             file, line);
-  return 0;
-}
-
-#define grub_bad_type_cast() grub_bad_type_cast_real(__LINE__, GRUB_FILE)
-
-#define GRUB_FIELD_MATCH(ptr, type, field) \
-  ((char *) &(ptr)->field == (char *) &((type) (ptr))->field)
-
-#define GRUB_AS_LIST(ptr) \
-  (GRUB_FIELD_MATCH (ptr, grub_list_t, next) ? \
-   (grub_list_t) ptr : grub_bad_type_cast ())
-
-#define GRUB_AS_LIST_P(pptr) \
-  (GRUB_FIELD_MATCH (*pptr, grub_list_t, next) ? \
-   (grub_list_t *) (void *) pptr : grub_bad_type_cast ())
-
-struct grub_named_list
-{
-  struct grub_named_list *next;
-  char *name;
-};
-typedef struct grub_named_list *grub_named_list_t;
-
-void * EXPORT_FUNC(grub_named_list_find) (grub_named_list_t head,
-                                         const char *name);
-
-#define GRUB_AS_NAMED_LIST(ptr) \
-  ((GRUB_FIELD_MATCH (ptr, grub_named_list_t, next) && \
-    GRUB_FIELD_MATCH (ptr, grub_named_list_t, name))? \
-   (grub_named_list_t) ptr : grub_bad_type_cast ())
-
-#define GRUB_AS_NAMED_LIST_P(pptr) \
-  ((GRUB_FIELD_MATCH (*pptr, grub_named_list_t, next) && \
-    GRUB_FIELD_MATCH (*pptr, grub_named_list_t, name))? \
-   (grub_named_list_t *) (void *) pptr : grub_bad_type_cast ())
-
-#define GRUB_PRIO_LIST_PRIO_MASK       0xff
-#define GRUB_PRIO_LIST_FLAG_ACTIVE     0x100
-
-struct grub_prio_list
-{
-  struct grub_prio_list *next;
-  char *name;
-  int prio;
-};
-typedef struct grub_prio_list *grub_prio_list_t;
-
-void EXPORT_FUNC(grub_prio_list_insert) (grub_prio_list_t *head,
-                                        grub_prio_list_t item);
-
-static inline void
-grub_prio_list_remove (grub_prio_list_t *head, grub_prio_list_t item)
-{
-  if ((item->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) && (item->next))
-    item->next->prio |= GRUB_PRIO_LIST_FLAG_ACTIVE;
-  grub_list_remove (GRUB_AS_LIST_P (head), GRUB_AS_LIST (item));
-}
-
-#define GRUB_AS_PRIO_LIST(ptr) \
-  ((GRUB_FIELD_MATCH (ptr, grub_prio_list_t, next) && \
-    GRUB_FIELD_MATCH (ptr, grub_prio_list_t, name) && \
-    GRUB_FIELD_MATCH (ptr, grub_prio_list_t, prio))? \
-   (grub_prio_list_t) ptr : grub_bad_type_cast ())
-
-#define GRUB_AS_PRIO_LIST_P(pptr) \
-  ((GRUB_FIELD_MATCH (*pptr, grub_prio_list_t, next) && \
-    GRUB_FIELD_MATCH (*pptr, grub_prio_list_t, name) && \
-    GRUB_FIELD_MATCH (*pptr, grub_prio_list_t, prio))? \
-   (grub_prio_list_t *) (void *) pptr : grub_bad_type_cast ())
-
-#endif /* ! GRUB_LIST_HEADER */
diff --git a/include/grub/loader.h b/include/grub/loader.h
deleted file mode 100644 (file)
index 319f3c5..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/* loader.h - OS loaders */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_LOADER_HEADER
-#define GRUB_LOADER_HEADER     1
-
-#include <grub/file.h>
-#include <grub/symbol.h>
-#include <grub/err.h>
-#include <grub/types.h>
-
-/* Check if a loader is loaded.  */
-int grub_loader_is_loaded (void);
-
-/* Set loader functions. NORETURN must be set to true, if BOOT won't return
-   to the original state.  */
-void grub_loader_set (grub_err_t (*boot) (void),
-                     grub_err_t (*unload) (void),
-                     int noreturn);
-
-/* Unset current loader, if any.  */
-void grub_loader_unset (void);
-
-/* Call the boot hook in current loader. This may or may not return,
-   depending on the setting by grub_loader_set.  */
-grub_err_t grub_loader_boot (void);
-
-/* The space between numbers is intentional for the simplicity of adding new
-   values even if external modules use them. */
-typedef enum {
-  /* A preboot hook which can use everything and turns nothing off. */
-  GRUB_LOADER_PREBOOT_HOOK_PRIO_NORMAL = 400,
-  /* A preboot hook which can't use disks and may stop disks. */
-  GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK = 300,
-  /* A preboot hook which can't use disks or console and may stop console. */
-  GRUB_LOADER_PREBOOT_HOOK_PRIO_CONSOLE = 200,
-  /* A preboot hook which can't use disks or console, can't modify memory map
-     and may stop memory services or finalize memory map. */
-  GRUB_LOADER_PREBOOT_HOOK_PRIO_MEMORY = 100,
-} grub_loader_preboot_hook_prio_t;
-
-/* Register a preboot hook. */
-void *grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noret),
-                                        grub_err_t (*preboot_rest_func) (void),
-                                        grub_loader_preboot_hook_prio_t prio);
-
-/* Unregister given preboot hook. */
-void grub_loader_unregister_preboot_hook (void *hnd);
-
-#endif /* ! GRUB_LOADER_HEADER */
diff --git a/include/grub/lvm.h b/include/grub/lvm.h
deleted file mode 100644 (file)
index a4bf3b2..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/* lvm.h - On disk structures for LVM. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_LVM_H
-#define GRUB_LVM_H     1
-
-#include <grub/types.h>
-
-/* Length of ID string, excluding terminating zero. */
-#define GRUB_LVM_ID_STRLEN 38
-
-struct grub_lvm_vg {
-  char id[GRUB_LVM_ID_STRLEN+1];
-  char *name;
-  int extent_size;
-  struct grub_lvm_pv *pvs;
-  struct grub_lvm_lv *lvs;
-  struct grub_lvm_vg *next;
-};
-
-struct grub_lvm_pv {
-  char id[GRUB_LVM_ID_STRLEN+1];
-  char *name;
-  grub_disk_t disk;
-  int start; /* Sector number where the data area starts. */
-  struct grub_lvm_pv *next;
-};
-
-struct grub_lvm_lv {
-  char *name;
-  unsigned int number;
-  unsigned int segment_count;
-  grub_uint64_t size;
-  struct grub_lvm_segment *segments; /* Pointer to segment_count segments. */
-  struct grub_lvm_vg *vg;
-  struct grub_lvm_lv *next;
-};
-
-struct grub_lvm_segment {
-  unsigned int start_extent;
-  unsigned int extent_count;
-  unsigned int stripe_count;
-  unsigned int stripe_size;
-  struct grub_lvm_stripe *stripes; /* Pointer to stripe_count stripes. */
-};
-
-struct grub_lvm_stripe {
-  int start;
-  struct grub_lvm_pv *pv;
-};
-
-#define GRUB_LVM_LABEL_SIZE GRUB_DISK_SECTOR_SIZE
-#define GRUB_LVM_LABEL_SCAN_SECTORS 4L
-
-#define GRUB_LVM_LABEL_ID "LABELONE"
-#define GRUB_LVM_LVM2_LABEL "LVM2 001"
-
-#define GRUB_LVM_ID_LEN 32
-
-/* On disk - 32 bytes */
-struct grub_lvm_label_header {
-  grub_int8_t id[8];           /* LABELONE */
-  grub_uint64_t sector_xl;     /* Sector number of this label */
-  grub_uint32_t crc_xl;                /* From next field to end of sector */
-  grub_uint32_t offset_xl;     /* Offset from start of struct to contents */
-  grub_int8_t type[8];         /* LVM2 001 */
-} __attribute__ ((packed));
-
-/* On disk */
-struct grub_lvm_disk_locn {
-  grub_uint64_t offset;                /* Offset in bytes to start sector */
-  grub_uint64_t size;          /* Bytes */
-} __attribute__ ((packed));
-
-/* Fields with the suffix _xl should be xlate'd wherever they appear */
-/* On disk */
-struct grub_lvm_pv_header {
-  grub_int8_t pv_uuid[GRUB_LVM_ID_LEN];
-
-  /* This size can be overridden if PV belongs to a VG */
-  grub_uint64_t device_size_xl;        /* Bytes */
-
-  /* NULL-terminated list of data areas followed by */
-  /* NULL-terminated list of metadata area headers */
-  struct grub_lvm_disk_locn disk_areas_xl[0];  /* Two lists */
-} __attribute__ ((packed));
-
-#define GRUB_LVM_FMTT_MAGIC "\040\114\126\115\062\040\170\133\065\101\045\162\060\116\052\076"
-#define GRUB_LVM_FMTT_VERSION 1
-#define GRUB_LVM_MDA_HEADER_SIZE 512
-
-/* On disk */
-struct grub_lvm_raw_locn {
-  grub_uint64_t offset;                /* Offset in bytes to start sector */
-  grub_uint64_t size;          /* Bytes */
-  grub_uint32_t checksum;
-  grub_uint32_t filler;
-} __attribute__ ((packed));
-
-/* On disk */
-/* Structure size limited to one sector */
-struct grub_lvm_mda_header {
-  grub_uint32_t checksum_xl;   /* Checksum of rest of mda_header */
-  grub_int8_t magic[16];       /* To aid scans for metadata */
-  grub_uint32_t version;
-  grub_uint64_t start;         /* Absolute start byte of mda_header */
-  grub_uint64_t size;          /* Size of metadata area */
-
-  struct grub_lvm_raw_locn raw_locns[0];       /* NULL-terminated list */
-} __attribute__ ((packed));
-
-
-#endif /* ! GRUB_LVM_H */
diff --git a/include/grub/macho.h b/include/grub/macho.h
deleted file mode 100644 (file)
index 8214583..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MACHO_H
-#define GRUB_MACHO_H 1
-#include <grub/types.h>
-
-/* Multi-architecture header. Always in big-endian. */
-struct grub_macho_fat_header
-{
-  grub_uint32_t magic;
-  grub_uint32_t nfat_arch;
-} __attribute__ ((packed));
-#define GRUB_MACHO_FAT_MAGIC 0xcafebabe
-
-typedef grub_uint32_t grub_macho_cpu_type_t;
-typedef grub_uint32_t grub_macho_cpu_subtype_t;
-
-/* Architecture descriptor. Always in big-endian. */
-struct grub_macho_fat_arch
-{
-  grub_macho_cpu_type_t cputype;
-  grub_macho_cpu_subtype_t cpusubtype;
-  grub_uint32_t offset;
-  grub_uint32_t size;
-  grub_uint32_t align;
-} __attribute__ ((packed));
-
-/* File header for 32-bit. Always in native-endian. */
-struct grub_macho_header32
-{
-#define GRUB_MACHO_MAGIC32 0xfeedface
-  grub_uint32_t magic;
-  grub_macho_cpu_type_t cputype;
-  grub_macho_cpu_subtype_t cpusubtype;
-  grub_uint32_t filetype;
-  grub_uint32_t ncmds;
-  grub_uint32_t sizeofcmds;
-  grub_uint32_t flags;
-} __attribute__ ((packed));
-
-/* File header for 64-bit. Always in native-endian. */
-struct grub_macho_header64
-{
-#define GRUB_MACHO_MAGIC64 0xfeedfacf
-  grub_uint32_t magic;
-  grub_macho_cpu_type_t cputype;
-  grub_macho_cpu_subtype_t cpusubtype;
-  grub_uint32_t filetype;
-  grub_uint32_t ncmds;
-  grub_uint32_t sizeofcmds;
-  grub_uint32_t flags;
-  grub_uint32_t reserved;
-} __attribute__ ((packed));
-
-/* Convenience union. What do we need to load to identify the file type. */
-union grub_macho_filestart
-{
-  struct grub_macho_fat_header fat;
-  struct grub_macho_header32 thin32;
-  struct grub_macho_header64 thin64;
-} __attribute__ ((packed));
-
-/* Common header of Mach-O commands. */
-struct grub_macho_cmd
-{
-  grub_uint32_t cmd;
-  grub_uint32_t cmdsize;
-} __attribute__ ((packed));
-
-typedef grub_uint32_t grub_macho_vmprot_t;
-
-/* 32-bit segment command. */
-struct grub_macho_segment32
-{
-#define GRUB_MACHO_CMD_SEGMENT32  1
-  grub_uint32_t cmd;
-  grub_uint32_t cmdsize;
-  grub_uint8_t segname[16];
-  grub_uint32_t vmaddr;
-  grub_uint32_t vmsize;
-  grub_uint32_t fileoff;
-  grub_uint32_t filesize;
-  grub_macho_vmprot_t maxprot;
-  grub_macho_vmprot_t initprot;
-  grub_uint32_t nsects;
-  grub_uint32_t flags;
-} __attribute__ ((packed));
-
-/* 64-bit segment command. */
-struct grub_macho_segment64
-{
-#define GRUB_MACHO_CMD_SEGMENT64  0x19
-  grub_uint32_t cmd;
-  grub_uint32_t cmdsize;
-  grub_uint8_t segname[16];
-  grub_uint64_t vmaddr;
-  grub_uint64_t vmsize;
-  grub_uint64_t fileoff;
-  grub_uint64_t filesize;
-  grub_macho_vmprot_t maxprot;
-  grub_macho_vmprot_t initprot;
-  grub_uint32_t nsects;
-  grub_uint32_t flags;
-} __attribute__ ((packed));
-
-#define GRUB_MACHO_CMD_THREAD     5
-
-#endif
diff --git a/include/grub/machoload.h b/include/grub/machoload.h
deleted file mode 100644 (file)
index 8410162..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MACHOLOAD_HEADER
-#define GRUB_MACHOLOAD_HEADER  1
-
-#include <grub/err.h>
-#include <grub/elf.h>
-#include <grub/file.h>
-#include <grub/symbol.h>
-#include <grub/types.h>
-
-struct grub_macho_file
-{
-  grub_file_t file;
-  grub_ssize_t offset32;
-  grub_ssize_t end32;
-  int ncmds32;
-  grub_size_t cmdsize32;
-  grub_uint8_t *cmds32;
-  grub_ssize_t offset64;
-  grub_ssize_t end64;
-  int ncmds64;
-  grub_size_t cmdsize64;
-  grub_uint8_t *cmds64;
-};
-typedef struct grub_macho_file *grub_macho_t;
-
-grub_macho_t grub_macho_open (const char *);
-grub_macho_t grub_macho_file (grub_file_t);
-grub_err_t grub_macho_close (grub_macho_t);
-
-int grub_macho_contains_macho32 (grub_macho_t);
-grub_err_t grub_macho_size32 (grub_macho_t macho, grub_uint32_t *segments_start,
-                             grub_uint32_t *segments_end, int flags);
-grub_uint32_t grub_macho_get_entry_point32 (grub_macho_t macho);
-
-int grub_macho_contains_macho64 (grub_macho_t);
-grub_err_t grub_macho_size64 (grub_macho_t macho, grub_uint64_t *segments_start,
-                             grub_uint64_t *segments_end, int flags);
-grub_uint64_t grub_macho_get_entry_point64 (grub_macho_t macho);
-
-/* Ignore BSS segments when loading. */
-#define GRUB_MACHO_NOBSS 0x1
-grub_err_t grub_macho_load32 (grub_macho_t macho, char *offset, int flags);
-grub_err_t grub_macho_load64 (grub_macho_t macho, char *offset, int flags);
-
-/* Like filesize and file_read but take only 32-bit part
-   for current architecture. */
-grub_size_t grub_macho_filesize32 (grub_macho_t macho);
-grub_err_t grub_macho_readfile32 (grub_macho_t macho, void *dest);
-grub_size_t grub_macho_filesize64 (grub_macho_t macho);
-grub_err_t grub_macho_readfile64 (grub_macho_t macho, void *dest);
-
-void grub_macho_parse32 (grub_macho_t macho);
-void grub_macho_parse64 (grub_macho_t macho);
-
-#endif /* ! GRUB_MACHOLOAD_HEADER */
diff --git a/include/grub/memory.h b/include/grub/memory.h
deleted file mode 100644 (file)
index 43f90e1..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* memory.h - describe the memory map */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MEMORY_HEADER
-#define GRUB_MEMORY_HEADER     1
-
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/machine/memory.h>
-
-grub_err_t grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
-                                                           grub_uint64_t,
-                                                           grub_uint32_t));
-int grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type);
-grub_err_t grub_mmap_unregister (int handle);
-
-void *grub_mmap_malign_and_register (grub_uint64_t align, grub_uint64_t size,
-                                    int *handle, int type, int flags);
-
-void grub_mmap_free_and_unregister (int handle);
-
-#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
-
-struct grub_mmap_region
-{
-  struct grub_mmap_region *next;
-  grub_uint64_t start;
-  grub_uint64_t end;
-  int type;
-  int handle;
-};
-
-extern struct grub_mmap_region *grub_mmap_overlays;
-#endif
-
-#endif /* ! GRUB_MEMORY_HEADER */
diff --git a/include/grub/menu.h b/include/grub/menu.h
deleted file mode 100644 (file)
index e5e5fb1..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/* menu.h - Menu model function prototypes and data structures. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MENU_HEADER
-#define GRUB_MENU_HEADER 1
-
-struct grub_menu_entry_class
-{
-  char *name;
-  struct grub_menu_entry_class *next;
-};
-
-/* The menu entry.  */
-struct grub_menu_entry
-{
-  /* The title name.  */
-  const char *title;
-
-  /* If set means not everybody is allowed to boot this entry.  */
-  int restricted;
-
-  /* Allowed users.  */
-  const char *users;
-
-  /* The classes associated with the menu entry:
-     used to choose an icon or other style attributes.
-     This is a dummy head node for the linked list, so for an entry E,
-     E.classes->next is the first class if it is not NULL.  */
-  struct grub_menu_entry_class *classes;
-
-  /* The sourcecode of the menu entry, used by the editor.  */
-  const char *sourcecode;
-
-  int hotkey;
-
-  /* The next element.  */
-  struct grub_menu_entry *next;
-};
-typedef struct grub_menu_entry *grub_menu_entry_t;
-
-/* The menu.  */
-struct grub_menu
-{
-  /* The size of a menu.  */
-  int size;
-
-  /* The list of menu entries.  */
-  grub_menu_entry_t entry_list;
-};
-typedef struct grub_menu *grub_menu_t;
-
-/* Callback structure menu viewers can use to provide user feedback when
-   default entries are executed, possibly including fallback entries.  */
-typedef struct grub_menu_execute_callback
-{
-  /* Called immediately before ENTRY is booted.  */
-  void (*notify_booting) (grub_menu_entry_t entry, void *userdata);
-
-  /* Called when executing one entry has failed, and another entry, ENTRY, will
-     be executed as a fallback.  The implementation of this function should
-     delay for a period of at least 2 seconds before returning in order to
-     allow the user time to read the information before it can be lost by
-     executing ENTRY.  */
-  void (*notify_fallback) (grub_menu_entry_t entry, void *userdata);
-
-  /* Called when an entry has failed to execute and there is no remaining
-     fallback entry to attempt.  */
-  void (*notify_failure) (void *userdata);
-}
-*grub_menu_execute_callback_t;
-
-grub_menu_entry_t grub_menu_get_entry (grub_menu_t menu, int no);
-int grub_menu_get_timeout (void);
-void grub_menu_set_timeout (int timeout);
-void grub_menu_execute_entry (grub_menu_entry_t entry);
-void grub_menu_execute_with_fallback (grub_menu_t menu,
-                                     grub_menu_entry_t entry,
-                                     grub_menu_execute_callback_t callback,
-                                     void *callback_data);
-void grub_menu_entry_run (grub_menu_entry_t entry);
-int grub_menu_get_default_entry_index (grub_menu_t menu);
-
-#endif /* GRUB_MENU_HEADER */
diff --git a/include/grub/menu_viewer.h b/include/grub/menu_viewer.h
deleted file mode 100644 (file)
index c6513c4..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* menu_viewer.h - Interface to menu viewer implementations. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MENU_VIEWER_HEADER
-#define GRUB_MENU_VIEWER_HEADER 1
-
-#include <grub/err.h>
-#include <grub/symbol.h>
-#include <grub/types.h>
-#include <grub/menu.h>
-#include <grub/term.h>
-
-struct grub_menu_viewer
-{
-  struct grub_menu_viewer *next;
-  void *data;
-  void (*set_chosen_entry) (int entry, void *data);
-  void (*print_timeout) (int timeout, void *data);
-  void (*clear_timeout) (void *data);
-  void (*fini) (void *fini);
-};
-
-void grub_menu_register_viewer (struct grub_menu_viewer *viewer);
-
-grub_err_t
-grub_menu_try_text (struct grub_term_output *term, 
-                   int entry, grub_menu_t menu, int nested);
-
-extern grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu,
-                                           int nested);
-
-#endif /* GRUB_MENU_VIEWER_HEADER */
diff --git a/include/grub/mips/at_keyboard.h b/include/grub/mips/at_keyboard.h
deleted file mode 100644 (file)
index 0c30753..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/machine/at_keyboard.h>
diff --git a/include/grub/mips/cache.h b/include/grub/mips/cache.h
deleted file mode 100644 (file)
index c347057..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* cache.h - Flush the processor's cache.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_CPU_CACHE_H
-#define GRUB_CPU_CACHE_H       1
-
-#include <grub/symbol.h>
-#include <grub/types.h>
-
-void EXPORT_FUNC(grub_cpu_flush_cache) (void *start, grub_size_t size, int type);
-#endif 
diff --git a/include/grub/mips/cmos.h b/include/grub/mips/cmos.h
deleted file mode 100644 (file)
index 79a7a4c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/machine/cmos.h>
diff --git a/include/grub/mips/io.h b/include/grub/mips/io.h
deleted file mode 100644 (file)
index dee76bd..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef        GRUB_IO_H
-#define        GRUB_IO_H       1
-
-#include <grub/types.h>
-
-typedef grub_addr_t grub_port_t;
-
-static __inline unsigned char
-grub_inb (grub_port_t port)
-{
-  return *(volatile grub_uint8_t *) port;
-}
-
-static __inline unsigned short int
-grub_inw (grub_port_t port)
-{
-  return *(volatile grub_uint16_t *) port;
-}
-
-static __inline unsigned int
-grub_inl (grub_port_t port)
-{
-  return *(volatile grub_uint32_t *) port;
-}
-
-static __inline void
-grub_outb (unsigned char value, grub_port_t port)
-{
-  *(volatile grub_uint8_t *) port = value;
-}
-
-static __inline void
-grub_outw (unsigned short int value, grub_port_t port)
-{
-  *(volatile grub_uint16_t *) port = value;
-}
-
-static __inline void
-grub_outl (unsigned int value, grub_port_t port)
-{
-  *(volatile grub_uint32_t *) port = value;
-}
-
-#endif /* _SYS_IO_H */
diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h
deleted file mode 100644 (file)
index 8b68f7b..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_KERNEL_CPU_HEADER
-#define GRUB_KERNEL_CPU_HEADER 1
-
-#define GRUB_MOD_ALIGN 0x1
-/* Non-zero value is only needed for PowerMacs.  */
-#define GRUB_MOD_GAP   0x0
-
-#define GRUB_KERNEL_MACHINE_LINK_ALIGN  32
-
-#define GRUB_KERNEL_CPU_RAW_SIZE        0x200
-#define GRUB_KERNEL_CPU_COMPRESSED_SIZE        0x8
-#define GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE      0xc
-#define GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE      0x10
-
-#define GRUB_KERNEL_CPU_PREFIX         GRUB_KERNEL_CPU_RAW_SIZE
-#define GRUB_KERNEL_CPU_DATA_END       GRUB_KERNEL_CPU_RAW_SIZE + 0x48
-
-#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_KERNEL_CPU_RAW_SIZE
-
-#define GRUB_KERNEL_MACHINE_PREFIX     GRUB_KERNEL_CPU_PREFIX
-#define GRUB_KERNEL_MACHINE_DATA_END   GRUB_KERNEL_CPU_DATA_END
-#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE
-#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE
-#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_KERNEL_CPU_COMPRESSED_SIZE
-
-#define GRUB_PLATFORM_IMAGE_FORMATS     "raw, elf"
-#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT     "raw"
-
-#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW
-
-#ifndef ASM_FILE
-
-typedef enum {
-  GRUB_PLATFORM_IMAGE_RAW,
-  GRUB_PLATFORM_IMAGE_ELF
-}
-  grub_platform_image_format_t;
-#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW
-#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF
-
-/* The prefix which points to the directory where GRUB modules and its
-   configuration file are located.  */
-extern char grub_prefix[];
-
-#endif
-
-#endif
diff --git a/include/grub/mips/multiboot.h b/include/grub/mips/multiboot.h
deleted file mode 100644 (file)
index a27229e..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MULTIBOOT_CPU_HEADER
-#define GRUB_MULTIBOOT_CPU_HEADER      1
-
-extern grub_uint32_t grub_multiboot_payload_eip;
-extern char *grub_multiboot_payload_orig;
-extern grub_addr_t grub_multiboot_payload_dest;
-extern grub_size_t grub_multiboot_payload_size;
-
-#define MULTIBOOT_INITIAL_STATE  { .gpr[4] = MULTIBOOT_BOOTLOADER_MAGIC, \
-    .jumpreg = 1 }
-#define MULTIBOOT_ENTRY_REGISTER gpr[1]
-#define MULTIBOOT_MBI_REGISTER gpr[5]
-#define MULTIBOOT_ARCHITECTURE_CURRENT MULTIBOOT_ARCHITECTURE_MIPS32
-
-#define MULTIBOOT_ELF32_MACHINE EM_MIPS
-#define MULTIBOOT_ELF64_MACHINE EM_MIPS
-
-#endif /* ! GRUB_MULTIBOOT_CPU_HEADER */
diff --git a/include/grub/mips/pci.h b/include/grub/mips/pci.h
deleted file mode 100644 (file)
index 8b49d84..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/machine/pci.h>
diff --git a/include/grub/mips/qemu-mips/boot.h b/include/grub/mips/qemu-mips/boot.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/include/grub/mips/qemu-mips/kernel.h b/include/grub/mips/qemu-mips/kernel.h
deleted file mode 100644 (file)
index dbf74c1..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_KERNEL_MACHINE_HEADER
-#define GRUB_KERNEL_MACHINE_HEADER     1
-
-#include <grub/symbol.h>
-#include <grub/cpu/kernel.h>
-
-#ifndef ASM_FILE
-
-void EXPORT_FUNC (grub_reboot) (void);
-void EXPORT_FUNC (grub_halt) (void);
-
-/* The prefix which points to the directory where GRUB modules and its
-   configuration file are located.  */
-extern char grub_prefix[];
-
-#endif
-
-#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/include/grub/mips/qemu-mips/loader.h b/include/grub/mips/qemu-mips/loader.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/include/grub/mips/qemu-mips/memory.h b/include/grub/mips/qemu-mips/memory.h
deleted file mode 100644 (file)
index 87e6867..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MEMORY_MACHINE_HEADER
-#define GRUB_MEMORY_MACHINE_HEADER     1
-
-#ifndef ASM_FILE
-#include <grub/symbol.h>
-#include <grub/err.h>
-#include <grub/types.h>
-#endif
-
-#define GRUB_MACHINE_MEMORY_STACK_HIGH       0x80f00000
-#define GRUB_MACHINE_MEMORY_USABLE       0x81000000
-
-#define GRUB_MACHINE_MEMORY_AVAILABLE        1
-
-#ifndef ASM_FILE
-grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate)
-(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
-grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
-     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
-
-static inline grub_err_t
-grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
-                           grub_uint64_t size __attribute__ ((unused)),
-                           int type __attribute__ ((unused)),
-                           int handle __attribute__ ((unused)))
-{
-  return GRUB_ERR_NONE;
-}
-static inline grub_err_t
-grub_machine_mmap_unregister (int handle  __attribute__ ((unused)))
-{
-  return GRUB_ERR_NONE;
-}
-#endif
-
-#endif
diff --git a/include/grub/mips/qemu-mips/serial.h b/include/grub/mips/qemu-mips/serial.h
deleted file mode 100644 (file)
index 1f8ce08..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MACHINE_SERIAL_HEADER
-#define GRUB_MACHINE_SERIAL_HEADER     1
-
-#define GRUB_MACHINE_SERIAL_PORTS { 0x140003f8 }
-
-#endif 
diff --git a/include/grub/mips/qemu-mips/time.h b/include/grub/mips/qemu-mips/time.h
deleted file mode 100644 (file)
index a73f64d..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KERNEL_MACHINE_TIME_HEADER
-#define KERNEL_MACHINE_TIME_HEADER     1
-
-#include <grub/symbol.h>
-
-#define GRUB_TICKS_PER_SECOND  1000
-
-/* Return the real time in ticks.  */
-grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
-
-static inline void
-grub_cpu_idle(void)
-{
-}
-
-#endif /* ! KERNEL_MACHINE_TIME_HEADER */
diff --git a/include/grub/mips/relocator.h b/include/grub/mips/relocator.h
deleted file mode 100644 (file)
index 838ef83..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_RELOCATOR_CPU_HEADER
-#define GRUB_RELOCATOR_CPU_HEADER      1
-
-#include <grub/types.h>
-#include <grub/err.h>
-
-struct grub_relocator32_state
-{
-  /* gpr[0] is ignored since it's hardwired to 0.  */
-  grub_uint32_t gpr[32];
-  /* Register holding target $pc.  */
-  int jumpreg;
-};
-
-void *grub_relocator32_alloc (grub_size_t size);
-grub_err_t grub_relocator32_boot (void *relocator, grub_uint32_t dest,
-                                 struct grub_relocator32_state state);
-void *grub_relocator32_realloc (void *relocator, grub_size_t size);
-void grub_relocator32_free (void *relocator);
-
-#endif /* ! GRUB_RELOCATOR_CPU_HEADER */
diff --git a/include/grub/mips/setjmp.h b/include/grub/mips/setjmp.h
deleted file mode 100644 (file)
index 5e59855..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_SETJMP_CPU_HEADER
-#define GRUB_SETJMP_CPU_HEADER 1
-
-typedef unsigned long grub_jmp_buf[11];
-
-int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice));
-void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
-
-#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/include/grub/mips/time.h b/include/grub/mips/time.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/include/grub/mips/types.h b/include/grub/mips/types.h
deleted file mode 100644 (file)
index fe09afa..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_TYPES_CPU_HEADER
-#define GRUB_TYPES_CPU_HEADER  1
-
-/* The size of void *.  */
-#define GRUB_TARGET_SIZEOF_VOID_P      4
-
-/* The size of long.  */
-#define GRUB_TARGET_SIZEOF_LONG                4
-
-#ifdef GRUB_CPU_MIPSEL
-/* mipsEL is little-endian.  */
-#undef GRUB_TARGET_WORDS_BIGENDIAN
-#elif defined (GRUB_CPU_MIPS)
-/* mips is big-endian.  */
-#define GRUB_TARGET_WORDS_BIGENDIAN
-#elif !defined (GRUB_SYMBOL_GENERATOR)
-#error Neither GRUB_CPU_MIPS nor GRUB_CPU_MIPSEL is defined
-#endif
-
-#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/include/grub/mips/yeeloong/at_keyboard.h b/include/grub/mips/yeeloong/at_keyboard.h
deleted file mode 100644 (file)
index f279ac8..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MACHINE_AT_KEYBOARD_HEADER
-#define GRUB_MACHINE_AT_KEYBOARD_HEADER        1
-
-#define KEYBOARD_REG_DATA      0xbfd00060
-#define KEYBOARD_REG_STATUS    0xbfd00064
-
-#endif
diff --git a/include/grub/mips/yeeloong/boot.h b/include/grub/mips/yeeloong/boot.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/include/grub/mips/yeeloong/cmos.h b/include/grub/mips/yeeloong/cmos.h
deleted file mode 100644 (file)
index f2a32d7..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef        GRUB_CPU_CMOS_H
-#define        GRUB_CPU_CMOS_H 1
-
-#include <grub/types.h>
-#include <grub/cpu/io.h>
-
-#define GRUB_CMOS_ADDR_REG     0xbfd00070
-#define GRUB_CMOS_DATA_REG     0xbfd00071
-
-#endif /* GRUB_CPU_CMOS_H */
diff --git a/include/grub/mips/yeeloong/kernel.h b/include/grub/mips/yeeloong/kernel.h
deleted file mode 100644 (file)
index 230455d..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_KERNEL_MACHINE_HEADER
-#define GRUB_KERNEL_MACHINE_HEADER     1
-
-#include <grub/symbol.h>
-#include <grub/cpu/kernel.h>
-
-#ifndef ASM_FILE
-
-void EXPORT_FUNC (grub_reboot) (void);
-void EXPORT_FUNC (grub_halt) (void);
-
-#endif
-
-#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/include/grub/mips/yeeloong/loader.h b/include/grub/mips/yeeloong/loader.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/include/grub/mips/yeeloong/memory.h b/include/grub/mips/yeeloong/memory.h
deleted file mode 100644 (file)
index 922db24..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MEMORY_MACHINE_HEADER
-#define GRUB_MEMORY_MACHINE_HEADER     1
-
-#ifndef ASM_FILE
-#include <grub/symbol.h>
-#include <grub/err.h>
-#include <grub/types.h>
-#endif
-
-#define GRUB_MACHINE_MEMORY_STACK_HIGH       0x801ffff0
-#define GRUB_ARCH_LOWMEMVSTART 0x80000000
-#define GRUB_ARCH_LOWMEMPSTART 0x00000000
-#define GRUB_ARCH_LOWMEMMAXSIZE 0x10000000
-#define GRUB_ARCH_HIGHMEMPSTART 0x10000000
-
-
-#define GRUB_MACHINE_MEMORY_AVAILABLE        1
-#define GRUB_MACHINE_MEMORY_MAX_TYPE         1
-  /* This one is special: it's used internally but is never reported
-     by firmware. */
-#define GRUB_MACHINE_MEMORY_HOLE       2
-#define GRUB_MACHINE_MEMORY_RESERVED GRUB_MACHINE_MEMORY_HOLE
-
-#ifndef ASM_FILE
-grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate)
-(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
-
-static inline grub_err_t
-grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
-                           grub_uint64_t size __attribute__ ((unused)),
-                           int type __attribute__ ((unused)),
-                           int handle __attribute__ ((unused)))
-{
-  return GRUB_ERR_NONE;
-}
-static inline grub_err_t
-grub_machine_mmap_unregister (int handle  __attribute__ ((unused)))
-{
-  return GRUB_ERR_NONE;
-}
-
-grub_uint64_t grub_mmap_get_lower (void);
-grub_uint64_t grub_mmap_get_upper (void);
-
-extern grub_uint32_t EXPORT_VAR (grub_arch_memsize);
-extern grub_uint32_t EXPORT_VAR (grub_arch_highmemsize);
-
-#endif
-
-#endif
diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h
deleted file mode 100644 (file)
index c7bd31d..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef        GRUB_MACHINE_PCI_H
-#define        GRUB_MACHINE_PCI_H      1
-
-#include <grub/types.h>
-#include <grub/cpu/io.h>
-
-#define GRUB_PCI_NUM_BUS        1
-#define GRUB_PCI_NUM_DEVICES    16
-
-#define GRUB_MACHINE_PCI_IO_BASE          0xbfd00000
-#define GRUB_MACHINE_PCI_CONFSPACE        0xbfe80000
-#define GRUB_MACHINE_PCI_CONF_CTRL_REG    (*(volatile grub_uint32_t *) 0xbfe00118)
-#define GRUB_MACHINE_PCI_IO_CTRL_REG      (*(volatile grub_uint32_t *) 0xbfe00110)
-#define GRUB_MACHINE_PCI_WIN_MASK_SIZE    6
-#define GRUB_MACHINE_PCI_WIN_MASK         ((1 << GRUB_MACHINE_PCI_WIN_MASK_SIZE) - 1)
-
-/* We have 3 PCI windows.  */
-#define GRUB_MACHINE_PCI_NUM_WIN          3
-/* Each window is 64MiB.  */
-#define GRUB_MACHINE_PCI_WIN_SHIFT        26
-#define GRUB_MACHINE_PCI_WIN_OFFSET_MASK  ((1 << GRUB_MACHINE_PCI_WIN_SHIFT) - 1)
-
-#define GRUB_MACHINE_PCI_WIN_SIZE         0x04000000
-/* Graphical acceleration takes 1 MiB away.  */
-#define GRUB_MACHINE_PCI_WIN1_SIZE        0x03f00000
-
-#define GRUB_MACHINE_PCI_WIN1_ADDR        0xb0000000
-#define GRUB_MACHINE_PCI_WIN2_ADDR        0xb4000000
-#define GRUB_MACHINE_PCI_WIN3_ADDR        0xb8000000
-
-static inline grub_uint32_t
-grub_pci_read (grub_pci_address_t addr)
-{
-  GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
-  return *(volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONFSPACE
-                                     | (addr & 0x03ff));
-}
-
-static inline grub_uint16_t
-grub_pci_read_word (grub_pci_address_t addr)
-{
-  GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
-  return *(volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONFSPACE
-                                     | (addr & 0x03ff));
-}
-
-static inline grub_uint8_t
-grub_pci_read_byte (grub_pci_address_t addr)
-{
-  GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
-  return *(volatile grub_uint8_t *) (GRUB_MACHINE_PCI_CONFSPACE
-                                    | (addr & 0x03ff));
-}
-
-static inline void
-grub_pci_write (grub_pci_address_t addr, grub_uint32_t data)
-{
-  GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
-  *(volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONFSPACE
-                              | (addr & 0x03ff)) = data;
-}
-
-static inline void
-grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data)
-{
-  GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
-  *(volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONFSPACE
-                              | (addr & 0x03ff)) = data;
-}
-
-static inline void
-grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data)
-{
-  GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf);
-  *(volatile grub_uint8_t *) (GRUB_MACHINE_PCI_CONFSPACE
-                             | (addr & 0x03ff)) = data;
-}
-
-volatile void *
-grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)),
-                          grub_addr_t base, grub_size_t size);
-void
-grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)),
-                            volatile void *mem,
-                            grub_size_t size __attribute__ ((unused)));
-
-#endif /* GRUB_MACHINE_PCI_H */
diff --git a/include/grub/mips/yeeloong/serial.h b/include/grub/mips/yeeloong/serial.h
deleted file mode 100644 (file)
index 9390ea1..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MACHINE_SERIAL_HEADER
-#define GRUB_MACHINE_SERIAL_HEADER     1
-
-#define GRUB_MACHINE_SERIAL_PORTS { 0xbff003f8 }
-
-#endif 
diff --git a/include/grub/mips/yeeloong/time.h b/include/grub/mips/yeeloong/time.h
deleted file mode 100644 (file)
index 7f468bf..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KERNEL_MACHINE_TIME_HEADER
-#define KERNEL_MACHINE_TIME_HEADER     1
-
-#include <grub/symbol.h>
-
-#define GRUB_TICKS_PER_SECOND  (grub_arch_cpuclock / 2)
-
-/* Return the real time in ticks.  */
-grub_uint64_t EXPORT_FUNC (grub_get_rtc) (void);
-
-extern grub_uint32_t EXPORT_VAR (grub_arch_busclock);
-extern grub_uint32_t EXPORT_VAR (grub_arch_cpuclock);
-
-static inline void
-grub_cpu_idle(void)
-{
-}
-
-#endif /* ! KERNEL_MACHINE_TIME_HEADER */
diff --git a/include/grub/misc.h b/include/grub/misc.h
deleted file mode 100644 (file)
index 9bfc697..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-/* misc.h - prototypes for misc functions */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MISC_HEADER
-#define GRUB_MISC_HEADER       1
-
-#include <stdarg.h>
-#include <grub/types.h>
-#include <grub/symbol.h>
-#include <grub/err.h>
-
-/* GCC version checking borrowed from glibc. */
-#if defined(__GNUC__) && defined(__GNUC_MINOR__)
-#  define GNUC_PREREQ(maj,min) \
-       ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
-#else
-#  define GNUC_PREREQ(maj,min) 0
-#endif
-
-/* Does this compiler support compile-time error attributes? */
-#if GNUC_PREREQ(4,3)
-#  define ATTRIBUTE_ERROR(msg) \
-       __attribute__ ((__error__ (msg)))
-#else
-#  define ATTRIBUTE_ERROR(msg)
-#endif
-
-#define ALIGN_UP(addr, align) \
-       ((addr + (typeof (addr)) align - 1) & ~((typeof (addr)) align - 1))
-#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))
-#define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; }
-
-#define grub_dprintf(condition, fmt, args...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, fmt, ## args)
-/* XXX: If grub_memmove is too slow, we must implement grub_memcpy.  */
-#define grub_memcpy(d,s,n)     grub_memmove ((d), (s), (n))
-
-void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n);
-char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src);
-char *EXPORT_FUNC(grub_strncpy) (char *dest, const char *src, int c);
-char *EXPORT_FUNC(grub_stpcpy) (char *dest, const char *src);
-
-static inline char *
-grub_strcat (char *dest, const char *src)
-{
-  char *p = dest;
-
-  while (*p)
-    p++;
-
-  while ((*p = *src) != '\0')
-    {
-      p++;
-      src++;
-    }
-
-  return dest;
-}
-
-static inline char *
-grub_strncat (char *dest, const char *src, int c)
-{
-  char *p = dest;
-
-  while (*p)
-    p++;
-
-  while ((*p = *src) != '\0' && c--)
-    {
-      p++;
-      src++;
-    }
-
-  *p = '\0';
-
-  return dest;
-}
-
-/* Prototypes for aliases.  */
-#ifndef GRUB_UTIL
-int EXPORT_FUNC(memcmp) (const void *s1, const void *s2, grub_size_t n);
-void *EXPORT_FUNC(memmove) (void *dest, const void *src, grub_size_t n);
-void *EXPORT_FUNC(memcpy) (void *dest, const void *src, grub_size_t n);
-void *EXPORT_FUNC(memset) (void *s, int c, grub_size_t n);
-#endif
-
-int EXPORT_FUNC(grub_memcmp) (const void *s1, const void *s2, grub_size_t n);
-int EXPORT_FUNC(grub_strcmp) (const char *s1, const char *s2);
-int EXPORT_FUNC(grub_strncmp) (const char *s1, const char *s2, grub_size_t n);
-
-char *EXPORT_FUNC(grub_strchr) (const char *s, int c);
-char *EXPORT_FUNC(grub_strrchr) (const char *s, int c);
-int EXPORT_FUNC(grub_strword) (const char *s, const char *w);
-char *EXPORT_FUNC(grub_strstr) (const char *haystack, const char *needle);
-int EXPORT_FUNC(grub_isspace) (int c);
-int EXPORT_FUNC(grub_isprint) (int c);
-
-static inline int
-grub_iscntrl (int c)
-{
-  return (c >= 0x00 && c <= 0x1F) || c == 0x7F;
-}
-
-static inline int
-grub_isalpha (int c)
-{
-  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
-}
-
-static inline int
-grub_isgraph (int c)
-{
-  return (c >= '!' && c <= '~');
-}
-
-static inline int
-grub_isdigit (int c)
-{
-  return (c >= '0' && c <= '9');
-}
-
-static inline int
-grub_isalnum (int c)
-{
-  return grub_isalpha (c) || grub_isdigit (c);
-}
-
-static inline int
-grub_tolower (int c)
-{
-  if (c >= 'A' && c <= 'Z')
-    return c - 'A' + 'a';
-
-  return c;
-}
-
-static inline int
-grub_toupper (int c)
-{
-  if (c >= 'a' && c <= 'z')
-    return c - 'a' + 'A';
-
-  return c;
-}
-
-static inline int
-grub_strcasecmp (const char *s1, const char *s2)
-{
-  while (*s1 && *s2)
-    {
-      if (grub_tolower (*s1) != grub_tolower (*s2))
-       break;
-
-      s1++;
-      s2++;
-    }
-
-  return (int) grub_tolower (*s1) - (int) grub_tolower (*s2);
-}
-
-static inline int
-grub_strncasecmp (const char *s1, const char *s2, grub_size_t n)
-{
-  if (n == 0)
-    return 0;
-
-  while (*s1 && *s2 && --n)
-    {
-      if (grub_tolower (*s1) != grub_tolower (*s2))
-       break;
-
-      s1++;
-      s2++;
-    }
-
-  return (int) grub_tolower (*s1) - (int) grub_tolower (*s2);
-}
-
-
-unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base);
-unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base);
-
-static inline long
-grub_strtol (const char *str, char **end, int base)
-{
-  int negative = 0;
-  unsigned long magnitude;
-
-  while (*str && grub_isspace (*str))
-    str++;
-
-  if (*str == '-')
-    {
-      negative = 1;
-      str++;
-    }
-
-  magnitude = grub_strtoull (str, end, base);
-  if (negative)
-    {
-      if (magnitude > (unsigned long) GRUB_LONG_MAX + 1)
-        {
-          grub_error (GRUB_ERR_OUT_OF_RANGE, "negative overflow");
-          return GRUB_LONG_MIN;
-        }
-      return -((long) magnitude);
-    }
-  else
-    {
-      if (magnitude > GRUB_LONG_MAX)
-        {
-          grub_error (GRUB_ERR_OUT_OF_RANGE, "positive overflow");
-          return GRUB_LONG_MAX;
-        }
-      return (long) magnitude;
-    }
-}
-
-char *EXPORT_FUNC(grub_strdup) (const char *s);
-char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n);
-void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n);
-grub_size_t EXPORT_FUNC(grub_strlen) (const char *s);
-int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
-int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
-int EXPORT_FUNC(grub_puts) (const char *s);
-int EXPORT_FUNC(grub_puts_) (const char *s);
-void EXPORT_FUNC(grub_real_dprintf) (const char *file,
-                                     const int line,
-                                     const char *condition,
-                                     const char *fmt, ...) __attribute__ ((format (printf, 4, 5)));
-int EXPORT_FUNC(grub_vprintf) (const char *fmt, va_list args);
-int EXPORT_FUNC(grub_snprintf) (char *str, grub_size_t n, const char *fmt, ...)
-     __attribute__ ((format (printf, 3, 4)));
-int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt,
-                                va_list args);
-char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...)
-     __attribute__ ((format (printf, 1, 2)));
-char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args);
-void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn));
-void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn));
-grub_size_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest,
-                                           grub_size_t destsize,
-                                           const grub_uint8_t *src,
-                                           grub_size_t srcsize,
-                                           const grub_uint8_t **srcend);
-grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
-                                         grub_uint32_t d, grub_uint32_t *r);
-
-#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL)
-void EXPORT_FUNC(__enable_execute_stack) (void *addr);
-#endif
-
-#if defined (NEED_REGISTER_FRAME_INFO) && !defined(GRUB_UTIL)
-void EXPORT_FUNC (__register_frame_info) (void);
-void EXPORT_FUNC (__deregister_frame_info) (void);
-#endif
-
-/* Inline functions.  */
-
-static inline unsigned int
-grub_abs (int x)
-{
-  if (x < 0)
-    return (unsigned int) (-x);
-  else
-    return (unsigned int) x;
-}
-
-static inline long
-grub_max (long x, long y)
-{
-  if (x > y)
-    return x;
-  else
-    return y;
-}
-
-/* Rounded-up division */
-static inline unsigned int
-grub_div_roundup (unsigned int x, unsigned int y)
-{
-  return (x + y - 1) / y;
-}
-
-/* Reboot the machine.  */
-void EXPORT_FUNC (grub_reboot) (void);
-
-#ifdef GRUB_MACHINE_PCBIOS
-/* Halt the system, using APM if possible. If NO_APM is true, don't
- * use APM even if it is available.  */
-void EXPORT_FUNC (grub_halt) (int no_apm);
-#else
-void EXPORT_FUNC (grub_halt) (void);
-#endif
-
-#endif /* ! GRUB_MISC_HEADER */
diff --git a/include/grub/mm.h b/include/grub/mm.h
deleted file mode 100644 (file)
index 38dd396..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* mm.h - prototypes and declarations for memory manager */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MM_H
-#define GRUB_MM_H      1
-
-#include <grub/types.h>
-#include <grub/symbol.h>
-#include <config.h>
-
-#ifndef NULL
-# define NULL  ((void *) 0)
-#endif
-
-void grub_mm_init_region (void *addr, grub_size_t size);
-void *EXPORT_FUNC(grub_malloc) (grub_size_t size);
-void *EXPORT_FUNC(grub_zalloc) (grub_size_t size);
-void EXPORT_FUNC(grub_free) (void *ptr);
-void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size);
-void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size);
-
-/* For debugging.  */
-#if defined(MM_DEBUG) && !defined(GRUB_UTIL) && !defined (GRUB_MACHINE_EMU)
-/* Set this variable to 1 when you want to trace all memory function calls.  */
-extern int EXPORT_VAR(grub_mm_debug);
-
-void grub_mm_dump_free (void);
-void grub_mm_dump (unsigned lineno);
-
-#define grub_malloc(size)      \
-  grub_debug_malloc (GRUB_FILE, __LINE__, size)
-
-#define grub_zalloc(size)      \
-  grub_debug_zalloc (GRUB_FILE, __LINE__, size)
-
-#define grub_realloc(ptr,size) \
-  grub_debug_realloc (GRUB_FILE, __LINE__, ptr, size)
-
-#define grub_memalign(align,size)      \
-  grub_debug_memalign (GRUB_FILE, __LINE__, align, size)
-
-#define grub_free(ptr) \
-  grub_debug_free (GRUB_FILE, __LINE__, ptr)
-
-void *EXPORT_FUNC(grub_debug_malloc) (const char *file, int line,
-                                     grub_size_t size);
-void *EXPORT_FUNC(grub_debug_zalloc) (const char *file, int line,
-                                      grub_size_t size);
-void EXPORT_FUNC(grub_debug_free) (const char *file, int line, void *ptr);
-void *EXPORT_FUNC(grub_debug_realloc) (const char *file, int line, void *ptr,
-                                      grub_size_t size);
-void *EXPORT_FUNC(grub_debug_memalign) (const char *file, int line,
-                                       grub_size_t align, grub_size_t size);
-#endif /* MM_DEBUG && ! GRUB_UTIL */
-
-#endif /* ! GRUB_MM_H */
diff --git a/include/grub/msdos_partition.h b/include/grub/msdos_partition.h
deleted file mode 100644 (file)
index 650d784..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2004,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_PC_PARTITION_HEADER
-#define GRUB_PC_PARTITION_HEADER       1
-
-#include <grub/symbol.h>
-#include <grub/types.h>
-#include <grub/err.h>
-
-/* The signature.  */
-#define GRUB_PC_PARTITION_SIGNATURE            0xaa55
-
-/* This is not a flag actually, but used as if it were a flag.  */
-#define GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG     0x10
-
-/* DOS partition types.  */
-#define GRUB_PC_PARTITION_TYPE_NONE            0
-#define GRUB_PC_PARTITION_TYPE_FAT12           1
-#define GRUB_PC_PARTITION_TYPE_FAT16_LT32M     4
-#define GRUB_PC_PARTITION_TYPE_EXTENDED                5
-#define GRUB_PC_PARTITION_TYPE_FAT16_GT32M     6
-#define GRUB_PC_PARTITION_TYPE_NTFS            7
-#define GRUB_PC_PARTITION_TYPE_FAT32           0xb
-#define GRUB_PC_PARTITION_TYPE_FAT32_LBA       0xc
-#define GRUB_PC_PARTITION_TYPE_FAT16_LBA       0xe
-#define GRUB_PC_PARTITION_TYPE_WIN95_EXTENDED  0xf
-#define GRUB_PC_PARTITION_TYPE_EZD             0x55
-#define GRUB_PC_PARTITION_TYPE_MINIX           0x80
-#define GRUB_PC_PARTITION_TYPE_LINUX_MINIX     0x81
-#define GRUB_PC_PARTITION_TYPE_EXT2FS          0x83
-#define GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED  0x85
-#define GRUB_PC_PARTITION_TYPE_VSTAFS          0x9e
-#define GRUB_PC_PARTITION_TYPE_FREEBSD         0xa5
-#define GRUB_PC_PARTITION_TYPE_OPENBSD         0xa6
-#define GRUB_PC_PARTITION_TYPE_NETBSD          0xa9
-#define GRUB_PC_PARTITION_TYPE_HFS             0xaf
-#define GRUB_PC_PARTITION_TYPE_GPT_DISK                0xee
-#define GRUB_PC_PARTITION_TYPE_LINUX_RAID      0xfd
-
-/* The partition entry.  */
-struct grub_msdos_partition_entry
-{
-  /* If active, 0x80, otherwise, 0x00.  */
-  grub_uint8_t flag;
-
-  /* The head of the start.  */
-  grub_uint8_t start_head;
-
-  /* (S | ((C >> 2) & 0xC0)) where S is the sector of the start and C
-     is the cylinder of the start. Note that S is counted from one.  */
-  grub_uint8_t start_sector;
-
-  /* (C & 0xFF) where C is the cylinder of the start.  */
-  grub_uint8_t start_cylinder;
-
-  /* The partition type.  */
-  grub_uint8_t type;
-
-  /* The end versions of start_head, start_sector and start_cylinder,
-     respectively.  */
-  grub_uint8_t end_head;
-  grub_uint8_t end_sector;
-  grub_uint8_t end_cylinder;
-
-  /* The start sector. Note that this is counted from zero.  */
-  grub_uint32_t start;
-
-  /* The length in sector units.  */
-  grub_uint32_t length;
-} __attribute__ ((packed));
-
-/* The structure of MBR.  */
-struct grub_msdos_partition_mbr
-{
-  /* The code area (actually, including BPB).  */
-  grub_uint8_t code[446];
-
-  /* Four partition entries.  */
-  struct grub_msdos_partition_entry entries[4];
-
-  /* The signature 0xaa55.  */
-  grub_uint16_t signature;
-} __attribute__ ((packed));
-
-\f
-
-static inline int
-grub_msdos_partition_is_empty (int type)
-{
-  return (type == GRUB_PC_PARTITION_TYPE_NONE);
-}
-
-static inline int
-grub_msdos_partition_is_extended (int type)
-{
-  return (type == GRUB_PC_PARTITION_TYPE_EXTENDED
-         || type == GRUB_PC_PARTITION_TYPE_WIN95_EXTENDED
-         || type == GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED);
-}
-
-#endif /* ! GRUB_PC_PARTITION_HEADER */
diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h
deleted file mode 100644 (file)
index 63947d1..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/* multiboot.h - multiboot header file with grub definitions. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2007,2008,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MULTIBOOT_HEADER
-#define GRUB_MULTIBOOT_HEADER 1
-
-#include <grub/file.h>
-
-#ifdef GRUB_USE_MULTIBOOT2
-#include <multiboot2.h>
-/* Same thing as far as our loader is concerned.  */
-#define MULTIBOOT_BOOTLOADER_MAGIC     MULTIBOOT2_BOOTLOADER_MAGIC
-#define MULTIBOOT_HEADER_MAGIC         MULTIBOOT2_HEADER_MAGIC
-#else
-#include <multiboot.h>
-#endif
-
-#include <grub/types.h>
-#include <grub/err.h>
-
-void grub_multiboot (int argc, char *argv[]);
-void grub_module (int argc, char *argv[]);
-
-grub_size_t grub_multiboot_get_mbi_size (void);
-grub_err_t grub_multiboot_make_mbi (void *orig, grub_uint32_t dest,
-                                   grub_off_t buf_off, grub_size_t bufsize);
-void grub_multiboot_free_mbi (void);
-grub_err_t grub_multiboot_init_mbi (int argc, char *argv[]);
-grub_err_t grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
-                                     int argc, char *argv[]);
-void grub_multiboot_set_bootdev (void);
-
-grub_uint32_t grub_get_multiboot_mmap_count (void);
-grub_err_t grub_multiboot_set_video_mode (void);
-
-#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU)
-#include <grub/i386/pc/vbe.h>
-#define GRUB_MACHINE_HAS_VGA_TEXT 1
-#else
-#define GRUB_MACHINE_HAS_VGA_TEXT 0
-#endif
-
-#define GRUB_MULTIBOOT_CONSOLE_EGA_TEXT 1
-#define GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER 2 
-
-grub_err_t
-grub_multiboot_set_console (int console_type, int accepted_consoles,
-                           int width, int height, int depth,
-                           int console_required);
-grub_err_t
-grub_multiboot_load (grub_file_t file);
-/* Load ELF32 or ELF64.  */
-grub_err_t
-grub_multiboot_load_elf (grub_file_t file, void *buffer);
-extern grub_size_t grub_multiboot_pure_size;
-extern grub_size_t grub_multiboot_alloc_mbi;
-
-#endif /* ! GRUB_MULTIBOOT_HEADER */
diff --git a/include/grub/multiboot_loader.h b/include/grub/multiboot_loader.h
deleted file mode 100644 (file)
index bf1c130..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* multiboot_loader.h - multiboot loader header file. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef GRUB_MULTIBOOT_LOADER_HEADER
-#define GRUB_MULTIBOOT_LOADER_HEADER 1
-
-/* Provided by the core ("rescue mode").  */
-void grub_rescue_cmd_multiboot_loader (int argc, char *argv[]);
-void grub_rescue_cmd_module_loader (int argc, char *argv[]);
-
-#endif /* ! GRUB_MULTIBOOT_LOADER_HEADER */
diff --git a/include/grub/net.h b/include/grub/net.h
deleted file mode 100644 (file)
index c6d71d5..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_NET_HEADER
-#define GRUB_NET_HEADER        1
-
-#include <grub/symbol.h>
-#include <grub/err.h>
-#include <grub/types.h>
-
-struct grub_net;
-
-struct grub_net_dev
-{
-  /* The device name.  */
-  const char *name;
-
-  /* FIXME: Just a template.  */
-  int (*probe) (struct grub_net *net, const void *addr);
-  void (*reset) (struct grub_net *net);
-  int (*poll) (struct grub_net *net);
-  void (*transmit) (struct grub_net *net, const void *destip,
-                   unsigned srcsock, unsigned destsock, const void *packet);
-  void (*disable) (struct grub_net *net);
-
-  /* The next net device.  */
-  struct grub_net_dev *next;
-};
-typedef struct grub_net_dev *grub_net_dev_t;
-
-struct grub_fs;
-
-struct grub_net
-{
-  /* The net name.  */
-  const char *name;
-
-  /* The underlying disk device.  */
-  grub_net_dev_t dev;
-
-  /* The binding filesystem.  */
-  struct grub_fs *fs;
-
-  /* FIXME: More data would be required, such as an IP address, a mask,
-     a gateway, etc.  */
-
-  /* Device-specific data.  */
-  void *data;
-};
-typedef struct grub_net *grub_net_t;
-
-/* FIXME: How to abstract networks? More consideration is necessary.  */
-
-/* Note: Networks are very different from disks, because networks must
-   be initialized before used, and the status is persistent.  */
-
-#endif /* ! GRUB_NET_HEADER */
diff --git a/include/grub/normal.h b/include/grub/normal.h
deleted file mode 100644 (file)
index 35eedf5..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/* normal.h - prototypes for the normal mode */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_NORMAL_HEADER
-#define GRUB_NORMAL_HEADER     1
-
-#include <grub/term.h>
-#include <grub/symbol.h>
-#include <grub/err.h>
-#include <grub/env.h>
-#include <grub/menu.h>
-#include <grub/command.h>
-#include <grub/file.h>
-
-/* The maximum size of a command-line.  */
-#define GRUB_MAX_CMDLINE       1600
-
-/* The standard left and right margin for some messages.  */
-#define STANDARD_MARGIN 6
-
-/* The type of a completion item.  */
-enum grub_completion_type
-  {
-    GRUB_COMPLETION_TYPE_COMMAND,
-    GRUB_COMPLETION_TYPE_DEVICE,
-    GRUB_COMPLETION_TYPE_PARTITION,
-    GRUB_COMPLETION_TYPE_FILE,
-    GRUB_COMPLETION_TYPE_ARGUMENT
-  };
-typedef enum grub_completion_type grub_completion_type_t;
-
-extern struct grub_menu_viewer grub_normal_text_menu_viewer;
-extern int grub_normal_exit_level;
-
-/* Defined in `main.c'.  */
-void grub_enter_normal_mode (const char *config);
-void grub_normal_execute (const char *config, int nested, int batch);
-void grub_menu_init_page (int nested, int edit,
-                         struct grub_term_output *term);
-void grub_normal_init_page (struct grub_term_output *term);
-grub_err_t grub_normal_add_menu_entry (int argc, const char **args,
-                                      const char *sourcecode);
-char *grub_file_getline (grub_file_t file);
-void grub_cmdline_run (int nested);
-
-/* Defined in `cmdline.c'.  */
-char *grub_cmdline_get (const char *prompt);
-grub_err_t grub_set_history (int newsize);
-
-/* Defined in `completion.c'.  */
-char *grub_normal_do_completion (char *buf, int *restore,
-                                void (*hook) (const char *item, grub_completion_type_t type, int count));
-
-/* Defined in `misc.c'.  */
-grub_err_t grub_normal_print_device_info (const char *name);
-
-/* Defined in `color.c'.  */
-char *grub_env_write_color_normal (struct grub_env_var *var, const char *val);
-char *grub_env_write_color_highlight (struct grub_env_var *var, const char *val);
-void grub_parse_color_name_pair (grub_uint8_t *ret, const char *name);
-
-/* Defined in `menu_text.c'.  */
-void grub_wait_after_message (void);
-void grub_print_ucs4 (const grub_uint32_t * str,
-                     const grub_uint32_t * last_position,
-                     struct grub_term_output *term);
-grub_ssize_t grub_getstringwidth (grub_uint32_t * str,
-                                 const grub_uint32_t * last_position,
-                                 struct grub_term_output *term);
-void grub_print_message_indented (const char *msg, int margin_left,
-                                 int margin_right,
-                                 struct grub_term_output *term);
-void
-grub_menu_text_register_instances (int entry, grub_menu_t menu, int nested);
-grub_err_t
-grub_show_menu (grub_menu_t menu, int nested);
-
-/* Defined in `handler.c'.  */
-void read_handler_list (void);
-void free_handler_list (void);
-
-/* Defined in `dyncmd.c'.  */
-void read_command_list (const char *prefix);
-
-/* Defined in `autofs.c'.  */
-void read_fs_list (const char *prefix);
-
-void grub_context_init (void);
-void grub_context_fini (void);
-
-void read_crypto_list (const char *prefix);
-
-void read_terminal_list (const char *prefix);
-
-void grub_set_more (int onoff);
-
-int grub_normal_get_line_counter (void);
-void grub_install_newline_hook (void);
-
-#endif /* ! GRUB_NORMAL_HEADER */
diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h
deleted file mode 100644 (file)
index 31b9939..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/* ntfs.h - header for the NTFS filesystem */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_NTFS_H
-#define GRUB_NTFS_H    1
-
-#define FILE_MFT      0
-#define FILE_MFTMIRR  1
-#define FILE_LOGFILE  2
-#define FILE_VOLUME   3
-#define FILE_ATTRDEF  4
-#define FILE_ROOT     5
-#define FILE_BITMAP   6
-#define FILE_BOOT     7
-#define FILE_BADCLUS  8
-#define FILE_QUOTA    9
-#define FILE_UPCASE  10
-
-#define AT_STANDARD_INFORMATION        0x10
-#define AT_ATTRIBUTE_LIST      0x20
-#define AT_FILENAME            0x30
-#define AT_OBJECT_ID           0x40
-#define AT_SECURITY_DESCRIPTOR 0x50
-#define AT_VOLUME_NAME         0x60
-#define AT_VOLUME_INFORMATION  0x70
-#define AT_DATA                        0x80
-#define AT_INDEX_ROOT          0x90
-#define AT_INDEX_ALLOCATION    0xA0
-#define AT_BITMAP              0xB0
-#define AT_SYMLINK             0xC0
-#define AT_EA_INFORMATION      0xD0
-#define AT_EA                  0xE0
-
-#define ATTR_READ_ONLY         0x1
-#define ATTR_HIDDEN            0x2
-#define ATTR_SYSTEM            0x4
-#define ATTR_ARCHIVE           0x20
-#define ATTR_DEVICE            0x40
-#define ATTR_NORMAL            0x80
-#define ATTR_TEMPORARY         0x100
-#define ATTR_SPARSE            0x200
-#define ATTR_REPARSE           0x400
-#define ATTR_COMPRESSED                0x800
-#define ATTR_OFFLINE           0x1000
-#define ATTR_NOT_INDEXED       0x2000
-#define ATTR_ENCRYPTED         0x4000
-#define ATTR_DIRECTORY         0x10000000
-#define ATTR_INDEX_VIEW                0x20000000
-
-#define FLAG_COMPRESSED                1
-#define FLAG_ENCRYPTED         0x4000
-#define FLAG_SPARSE            0x8000
-
-#define BLK_SHR                GRUB_DISK_SECTOR_BITS
-
-#define MAX_MFT                (1024 >> BLK_SHR)
-#define MAX_IDX                (16384 >> BLK_SHR)
-
-#define COM_LEN                4096
-#define COM_LOG_LEN    12
-#define COM_SEC                (COM_LEN >> BLK_SHR)
-
-#define AF_ALST                1
-#define AF_MMFT                2
-#define AF_GPOS                4
-
-#define RF_COMP                1
-#define RF_CBLK                2
-#define RF_BLNK                4
-
-#define valueat(buf,ofs,type)  *((type*)(((char*)buf)+ofs))
-
-#define u16at(buf,ofs) grub_le_to_cpu16(valueat(buf,ofs,grub_uint16_t))
-#define u32at(buf,ofs) grub_le_to_cpu32(valueat(buf,ofs,grub_uint32_t))
-#define u64at(buf,ofs) grub_le_to_cpu64(valueat(buf,ofs,grub_uint64_t))
-
-#define v16at(buf,ofs) valueat(buf,ofs,grub_uint16_t)
-#define v32at(buf,ofs) valueat(buf,ofs,grub_uint32_t)
-#define v64at(buf,ofs) valueat(buf,ofs,grub_uint64_t)
-
-struct grub_ntfs_bpb
-{
-  grub_uint8_t jmp_boot[3];
-  grub_uint8_t oem_name[8];
-  grub_uint16_t bytes_per_sector;
-  grub_uint8_t sectors_per_cluster;
-  grub_uint8_t reserved_1[7];
-  grub_uint8_t media;
-  grub_uint16_t reserved_2;
-  grub_uint16_t sectors_per_track;
-  grub_uint16_t num_heads;
-  grub_uint32_t num_hidden_sectors;
-  grub_uint32_t reserved_3[2];
-  grub_uint64_t num_total_sectors;
-  grub_uint64_t mft_lcn;
-  grub_uint64_t mft_mirr_lcn;
-  grub_int8_t clusters_per_mft;
-  grub_int8_t reserved_4[3];
-  grub_int8_t clusters_per_index;
-  grub_int8_t reserved_5[3];
-  grub_uint64_t num_serial;
-  grub_uint32_t checksum;
-} __attribute__ ((packed));
-
-#define grub_ntfs_file grub_fshelp_node
-
-struct grub_ntfs_attr
-{
-  int flags;
-  char *emft_buf, *edat_buf;
-  char *attr_cur, *attr_nxt, *attr_end;
-  grub_uint32_t save_pos;
-  char *sbuf;
-  struct grub_ntfs_file *mft;
-};
-
-struct grub_fshelp_node
-{
-  struct grub_ntfs_data *data;
-  char *buf;
-  grub_uint64_t size;
-  grub_uint32_t ino;
-  int inode_read;
-  struct grub_ntfs_attr attr;
-};
-
-struct grub_ntfs_data
-{
-  struct grub_ntfs_file cmft;
-  struct grub_ntfs_file mmft;
-  grub_disk_t disk;
-  grub_uint32_t mft_size;
-  grub_uint32_t idx_size;
-  grub_uint32_t spc;
-  grub_uint32_t blocksize;
-  grub_uint32_t mft_start;
-  grub_uint64_t uuid;
-};
-
-struct grub_ntfs_comp
-{
-  grub_disk_t disk;
-  int comp_head, comp_tail;
-  grub_uint32_t comp_table[16][2];
-  grub_uint32_t cbuf_ofs, cbuf_vcn, spc;
-  char *cbuf;
-};
-
-struct grub_ntfs_rlst
-{
-  int flags;
-  grub_disk_addr_t target_vcn, curr_vcn, next_vcn, curr_lcn;
-  char *cur_run;
-  struct grub_ntfs_attr *attr;
-  struct grub_ntfs_comp comp;
-};
-
-typedef grub_err_t (*ntfscomp_func_t) (struct grub_ntfs_attr * at, char *dest,
-                                      grub_uint32_t ofs, grub_uint32_t len,
-                                      struct grub_ntfs_rlst * ctx,
-                                      grub_uint32_t vcn);
-
-extern ntfscomp_func_t EXPORT_VAR (grub_ntfscomp_func);
-
-grub_err_t EXPORT_FUNC(grub_ntfs_read_run_list) (struct grub_ntfs_rlst *ctx);
-
-#endif /* ! GRUB_NTFS_H */
diff --git a/include/grub/parser.h b/include/grub/parser.h
deleted file mode 100644 (file)
index 17f0c43..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/* parser.h - prototypes for the command line parser.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_PARSER_HEADER
-#define GRUB_PARSER_HEADER     1
-
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/handler.h>
-#include <grub/reader.h>
-
-/* All the states for the command line.  */
-typedef enum
-  {
-    GRUB_PARSER_STATE_TEXT = 1,
-    GRUB_PARSER_STATE_ESC,
-    GRUB_PARSER_STATE_QUOTE,
-    GRUB_PARSER_STATE_DQUOTE,
-    GRUB_PARSER_STATE_VAR,
-    GRUB_PARSER_STATE_VARNAME,
-    GRUB_PARSER_STATE_VARNAME2,
-    GRUB_PARSER_STATE_QVAR,
-    GRUB_PARSER_STATE_QVARNAME,
-    GRUB_PARSER_STATE_QVARNAME2
-  } grub_parser_state_t;
-
-/* A single state transition.  */
-struct grub_parser_state_transition
-{
-  /* The state that is looked up.  */
-  grub_parser_state_t from_state;
-
-  /* The next state, determined by FROM_STATE and INPUT.  */
-  grub_parser_state_t to_state;
-
-  /* The input that will determine the next state from FROM_STATE.  */
-  char input;
-
-  /* If set to 1, the input is valid and should be used.  */
-  int keep_value;
-};
-
-/* Determines the state following STATE, determined by C.  */
-grub_parser_state_t
-EXPORT_FUNC (grub_parser_cmdline_state) (grub_parser_state_t state,
-                                        char c, char *result);
-
-grub_err_t
-EXPORT_FUNC (grub_parser_split_cmdline) (const char *cmdline,
-                                        grub_reader_getline_t getline,
-                                        int *argc, char ***argv);
-
-struct grub_parser
-{
-  /* The next parser.  */
-  struct grub_parser *next;
-
-  /* The parser name.  */
-  const char *name;
-
-  /* Initialize the parser.  */
-  grub_err_t (*init) (void);
-
-  /* Clean up the parser.  */
-  grub_err_t (*fini) (void);
-
-  grub_err_t (*parse_line) (char *line, grub_reader_getline_t getline);
-};
-typedef struct grub_parser *grub_parser_t;
-
-extern struct grub_handler_class EXPORT_VAR(grub_parser_class);
-grub_err_t EXPORT_FUNC(grub_parser_execute) (char *source);
-
-static inline void
-grub_parser_register (const char *name __attribute__ ((unused)),
-                     /* `name' is ignored here, but used by genhandlerlist.sh.  */
-                     grub_parser_t parser)
-{
-  grub_handler_register (&grub_parser_class, GRUB_AS_HANDLER (parser));
-}
-
-static inline void
-grub_parser_unregister (grub_parser_t parser)
-{
-  grub_handler_unregister (&grub_parser_class, GRUB_AS_HANDLER (parser));
-}
-
-static inline grub_parser_t
-grub_parser_get_current (void)
-{
-  return (grub_parser_t) grub_parser_class.cur_handler;
-}
-
-static inline grub_err_t
-grub_parser_set_current (grub_parser_t parser)
-{
-  return grub_handler_set_current (&grub_parser_class,
-                                  GRUB_AS_HANDLER (parser));
-}
-
-void grub_register_rescue_parser (void);
-
-#endif /* ! GRUB_PARSER_HEADER */
diff --git a/include/grub/partition.h b/include/grub/partition.h
deleted file mode 100644 (file)
index 80a9c15..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2004,2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_PART_HEADER
-#define GRUB_PART_HEADER       1
-
-#include <grub/dl.h>
-#include <grub/list.h>
-
-struct grub_disk;
-
-typedef struct grub_partition *grub_partition_t;
-
-/* Partition map type.  */
-struct grub_partition_map
-{
-  /* The next partition map type.  */
-  struct grub_partition_map *next;
-
-  /* The name of the partition map type.  */
-  const char *name;
-
-  /* Call HOOK with each partition, until HOOK returns non-zero.  */
-  grub_err_t (*iterate) (struct grub_disk *disk,
-                        int (*hook) (struct grub_disk *disk,
-                                     const grub_partition_t partition));
-};
-typedef struct grub_partition_map *grub_partition_map_t;
-
-/* Partition description.  */
-struct grub_partition
-{
-  /* The partition number.  */
-  int number;
-
-  /* The start sector.  */
-  grub_disk_addr_t start;
-
-  /* The length in sector units.  */
-  grub_uint64_t len;
-
-  /* The offset of the partition table.  */
-  grub_disk_addr_t offset;
-
-  /* The index of this partition in the partition table.  */
-  int index;
-
-  /* Parent partition map.  */
-  struct grub_partition *parent;
-
-  /* The type partition map.  */
-  grub_partition_map_t partmap;
-};
-
-grub_partition_t EXPORT_FUNC(grub_partition_probe) (struct grub_disk *disk,
-                                                   const char *str);
-int EXPORT_FUNC(grub_partition_iterate) (struct grub_disk *disk,
-                                        int (*hook) (struct grub_disk *disk,
-                                                     const grub_partition_t partition));
-char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition);
-
-
-extern grub_partition_map_t EXPORT_VAR(grub_partition_map_list);
-
-static inline void
-grub_partition_map_register (grub_partition_map_t partmap)
-{
-  grub_list_push (GRUB_AS_LIST_P (&grub_partition_map_list),
-                 GRUB_AS_LIST (partmap));
-}
-
-static inline void
-grub_partition_map_unregister (grub_partition_map_t partmap)
-{
-  grub_list_remove (GRUB_AS_LIST_P (&grub_partition_map_list),
-                   GRUB_AS_LIST (partmap));
-}
-
-#define FOR_PARTITION_MAPS(var) for (var = grub_partition_map_list; var; var = var->next)
-
-\f
-static inline grub_disk_addr_t
-grub_partition_get_start (const grub_partition_t p)
-{
-  grub_partition_t part;
-  grub_uint64_t part_start = 0;
-
-  for (part = p; part; part = part->parent)
-    part_start += part->start;
-
-  return part_start;
-}
-
-static inline grub_uint64_t
-grub_partition_get_len (const grub_partition_t p)
-{
-  return p->len;
-}
-
-#endif /* ! GRUB_PART_HEADER */
diff --git a/include/grub/parttool.h b/include/grub/parttool.h
deleted file mode 100644 (file)
index 8291e11..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_PARTTOOL_HEADER
-#define GRUB_PARTTOOL_HEADER   1
-
-struct grub_parttool_argdesc
-{
-  char *name;
-  char *desc;
-  enum {GRUB_PARTTOOL_ARG_END, GRUB_PARTTOOL_ARG_BOOL, GRUB_PARTTOOL_ARG_VAL}
-    type;
-};
-
-struct grub_parttool_args
-{
-  int set;
-  union
-  {
-    int bool;
-    char *str;
-  };
-};
-
-typedef grub_err_t (*grub_parttool_function_t) (const grub_device_t dev,
-                                               const struct grub_parttool_args *args);
-
-struct grub_parttool
-{
-  struct grub_parttool *next;
-  char *name;
-  int handle;
-  int nargs;
-  struct grub_parttool_argdesc *args;
-  grub_parttool_function_t func;
-};
-
-int grub_parttool_register(const char *part_name,
-                          const grub_parttool_function_t func,
-                          const struct grub_parttool_argdesc *args);
-void grub_parttool_unregister (int handle);
-
-#endif /* ! GRUB_PARTTOOL_HEADER*/
diff --git a/include/grub/pci.h b/include/grub/pci.h
deleted file mode 100644 (file)
index 89bd103..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef        GRUB_PCI_H
-#define        GRUB_PCI_H      1
-
-#include <grub/types.h>
-#include <grub/symbol.h>
-
-#define  GRUB_PCI_ADDR_SPACE_MASK      0x01
-#define  GRUB_PCI_ADDR_SPACE_MEMORY    0x00
-#define  GRUB_PCI_ADDR_SPACE_IO                0x01
-
-#define  GRUB_PCI_ADDR_MEM_TYPE_MASK   0x06
-#define  GRUB_PCI_ADDR_MEM_TYPE_32     0x00    /* 32 bit address */
-#define  GRUB_PCI_ADDR_MEM_TYPE_1M     0x02    /* Below 1M [obsolete] */
-#define  GRUB_PCI_ADDR_MEM_TYPE_64     0x04    /* 64 bit address */
-#define  GRUB_PCI_ADDR_MEM_PREFETCH    0x08    /* prefetchable */
-
-#define  GRUB_PCI_ADDR_MEM_MASK                ~0xf
-#define  GRUB_PCI_ADDR_IO_MASK         ~0x03
-
-#define  GRUB_PCI_REG_PCI_ID       0x00
-#define  GRUB_PCI_REG_VENDOR       0x00
-#define  GRUB_PCI_REG_DEVICE       0x02
-#define  GRUB_PCI_REG_COMMAND      0x04
-#define  GRUB_PCI_REG_STATUS       0x06
-#define  GRUB_PCI_REG_REVISION     0x08
-#define  GRUB_PCI_REG_CLASS        0x08
-#define  GRUB_PCI_REG_CACHELINE    0x0c
-#define  GRUB_PCI_REG_LAT_TIMER    0x0d
-#define  GRUB_PCI_REG_HEADER_TYPE  0x0e
-#define  GRUB_PCI_REG_BIST         0x0f
-#define  GRUB_PCI_REG_ADDRESSES    0x10
-
-/* Beware that 64-bit address takes 2 registers.  */
-#define  GRUB_PCI_REG_ADDRESS_REG0 0x10
-#define  GRUB_PCI_REG_ADDRESS_REG1 0x14
-#define  GRUB_PCI_REG_ADDRESS_REG2 0x18
-#define  GRUB_PCI_REG_ADDRESS_REG3 0x1c
-#define  GRUB_PCI_REG_ADDRESS_REG4 0x20
-#define  GRUB_PCI_REG_ADDRESS_REG5 0x24
-
-#define  GRUB_PCI_REG_CIS_POINTER  0x28
-#define  GRUB_PCI_REG_SUBVENDOR    0x2c
-#define  GRUB_PCI_REG_SUBSYSTEM    0x2e
-#define  GRUB_PCI_REG_ROM_ADDRESS  0x30
-#define  GRUB_PCI_REG_CAP_POINTER  0x34
-#define  GRUB_PCI_REG_IRQ_LINE     0x3c
-#define  GRUB_PCI_REG_IRQ_PIN      0x3d
-#define  GRUB_PCI_REG_MIN_GNT      0x3e
-#define  GRUB_PCI_REG_MAX_LAT      0x3f
-
-typedef grub_uint32_t grub_pci_id_t;
-
-#ifdef GRUB_MACHINE_EMU
-#include <grub/pciutils.h>
-#else
-typedef grub_uint32_t grub_pci_address_t;
-struct grub_pci_device
-{
-  int bus;
-  int device;
-  int function;
-};
-typedef struct grub_pci_device grub_pci_device_t;
-static inline int
-grub_pci_get_bus (grub_pci_device_t dev)
-{
-  return dev.bus;
-}
-
-static inline int
-grub_pci_get_device (grub_pci_device_t dev)
-{
-  return dev.device;
-}
-
-static inline int
-grub_pci_get_function (grub_pci_device_t dev)
-{
-  return dev.function;
-}
-#include <grub/cpu/pci.h>
-#endif
-
-typedef int NESTED_FUNC_ATTR (*grub_pci_iteratefunc_t)
-     (grub_pci_device_t dev, grub_pci_id_t pciid);
-
-grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (grub_pci_device_t dev,
-                                                      int reg);
-
-void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook);
-
-#endif /* GRUB_PCI_H */
diff --git a/include/grub/pciutils.h b/include/grub/pciutils.h
deleted file mode 100644 (file)
index 36d47e5..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef        GRUB_PCIUTILS_H
-#define        GRUB_PCIUTILS_H 1
-
-#include <pciaccess.h>
-
-typedef struct pci_device *grub_pci_device_t;
-
-static inline int
-grub_pci_get_bus (grub_pci_device_t dev)
-{
-  return dev->bus;
-}
-
-static inline int
-grub_pci_get_device (grub_pci_device_t dev)
-{
-  return dev->dev;
-}
-
-static inline int
-grub_pci_get_function (grub_pci_device_t dev)
-{
-  return dev->func;
-}
-
-struct grub_pci_address
-{
-  grub_pci_device_t dev;
-  int pos;
-};
-
-typedef struct grub_pci_address grub_pci_address_t;
-
-static inline grub_uint32_t
-grub_pci_read (grub_pci_address_t addr)
-{
-  grub_uint32_t ret;
-  pci_device_cfg_read_u32 (addr.dev, &ret, addr.pos);
-  return ret;
-}
-
-static inline grub_uint16_t
-grub_pci_read_word (grub_pci_address_t addr)
-{
-  grub_uint16_t ret;
-  pci_device_cfg_read_u16 (addr.dev, &ret, addr.pos);
-  return ret;
-}
-
-static inline grub_uint8_t
-grub_pci_read_byte (grub_pci_address_t addr)
-{
-  grub_uint8_t ret;
-  pci_device_cfg_read_u8 (addr.dev, &ret, addr.pos);
-  return ret;
-}
-
-static inline void
-grub_pci_write (grub_pci_address_t addr, grub_uint32_t data)
-{
-  pci_device_cfg_write_u32 (addr.dev, data, addr.pos);
-}
-
-static inline void
-grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data)
-{
-  pci_device_cfg_write_u16 (addr.dev, data, addr.pos);
-}
-
-static inline void
-grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data)
-{
-  pci_device_cfg_write_u8 (addr.dev, data, addr.pos);
-}
-
-void *
-grub_pci_device_map_range (grub_pci_device_t dev, grub_addr_t base,
-                          grub_size_t size);
-
-void
-grub_pci_device_unmap_range (grub_pci_device_t dev, void *mem,
-                            grub_size_t size);
-
-
-#endif /* GRUB_PCIUTILS_H */
diff --git a/include/grub/powerpc/ieee1275/biosdisk.h b/include/grub/powerpc/ieee1275/biosdisk.h
deleted file mode 100644 (file)
index 30584d6..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_BIOSDISK_MACHINE_HEADER
-#define GRUB_BIOSDISK_MACHINE_HEADER   1
-
-#define GRUB_BIOSDISK_FLAG_LBA 1
-
-struct grub_biosdisk_data
-{
-  int drive;
-  unsigned long cylinders;
-  unsigned long heads;
-  unsigned long sectors;
-  unsigned long flags;
-};
-
-int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap);
-int grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff,
-                              int soff, int nsec, int segment);
-int grub_biosdisk_check_int13_extensions (int drive);
-int grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp);
-int grub_biosdisk_get_diskinfo_standard (int drive,
-                                        unsigned long *cylinders,
-                                        unsigned long *heads,
-                                        unsigned long *sectors);
-int grub_biosdisk_get_num_floppies (void);
-
-void grub_biosdisk_init (void);
-
-#endif /* ! GRUB_BIOSDISK_MACHINE_HEADER */
diff --git a/include/grub/powerpc/ieee1275/console.h b/include/grub/powerpc/ieee1275/console.h
deleted file mode 100644 (file)
index ed2b720..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_CONSOLE_MACHINE_HEADER
-#define GRUB_CONSOLE_MACHINE_HEADER    1
-
-/* Initialize the console system.  */
-void grub_console_init (void);
-
-/* Finish the console system.  */
-void grub_console_fini (void);
-
-#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */
diff --git a/include/grub/powerpc/ieee1275/ieee1275.h b/include/grub/powerpc/ieee1275/ieee1275.h
deleted file mode 100644 (file)
index 3c7683f..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* ieee1275.h - Access the Open Firmware client interface.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_IEEE1275_MACHINE_HEADER
-#define GRUB_IEEE1275_MACHINE_HEADER   1
-
-#include <grub/types.h>
-
-#define GRUB_IEEE1275_CELL_SIZEOF 4
-typedef grub_uint32_t grub_ieee1275_cell_t;
-
-#endif /* ! GRUB_IEEE1275_MACHINE_HEADER */
diff --git a/include/grub/powerpc/ieee1275/kernel.h b/include/grub/powerpc/ieee1275/kernel.h
deleted file mode 100644 (file)
index a76c2a4..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_KERNEL_MACHINE_HEADER
-#define GRUB_KERNEL_MACHINE_HEADER     1
-
-#include <grub/symbol.h>
-
-#ifndef ASM_FILE
-
-/* The prefix which points to the directory where GRUB modules and its
-   configuration file are located.  */
-extern char grub_prefix[];
-
-#endif
-
-#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/include/grub/powerpc/ieee1275/loader.h b/include/grub/powerpc/ieee1275/loader.h
deleted file mode 100644 (file)
index 606bfcd..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_LOADER_MACHINE_HEADER
-#define GRUB_LOADER_MACHINE_HEADER     1
-
-/* The symbol shared between the normal mode and rescue mode
-   loader.  */
-void grub_rescue_cmd_linux (int argc, char *argv[]);
-void grub_rescue_cmd_initrd (int argc, char *argv[]);
-
-void grub_linux_init (void);
-void grub_linux_fini (void);
-void grub_linux_normal_init (void);
-void grub_linux_normal_fini (void);
-
-#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/include/grub/powerpc/ieee1275/memory.h b/include/grub/powerpc/ieee1275/memory.h
deleted file mode 100644 (file)
index f8f2ff0..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MEMORY_MACHINE_HEADER
-#define GRUB_MEMORY_MACHINE_HEADER     1
-
-#include <grub/ieee1275/ieee1275.h>
-
-#define GRUB_MACHINE_MEMORY_AVAILABLE          1
-
-#endif
diff --git a/include/grub/powerpc/ieee1275/time.h b/include/grub/powerpc/ieee1275/time.h
deleted file mode 100644 (file)
index 3f8ad26..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KERNEL_MACHINE_TIME_HEADER
-#define KERNEL_MACHINE_TIME_HEADER     1
-
-#include <grub/symbol.h>
-
-#define GRUB_TICKS_PER_SECOND  1000
-
-/* Return the real time in ticks.  */
-grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
-
-#endif /* ! KERNEL_MACHINE_TIME_HEADER */
diff --git a/include/grub/powerpc/ieee1275/util/biosdisk.h b/include/grub/powerpc/ieee1275/util/biosdisk.h
deleted file mode 100644 (file)
index f4262a0..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* biosdisk.h - emulate biosdisk */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_BIOSDISK_MACHINE_UTIL_HEADER
-#define GRUB_BIOSDISK_MACHINE_UTIL_HEADER      1
-
-void grub_util_biosdisk_init (const char *dev_map);
-void grub_util_biosdisk_fini (void);
-char *grub_util_biosdisk_get_grub_dev (const char *os_dev);
-
-#endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */
diff --git a/include/grub/powerpc/kernel.h b/include/grub/powerpc/kernel.h
deleted file mode 100644 (file)
index b468733..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_KERNEL_CPU_HEADER
-#define GRUB_KERNEL_CPU_HEADER 1
-
-#define GRUB_MOD_ALIGN 0x1000
-
-/* Minimal gap between _end and the start of the modules.  It's a hack
-   for PowerMac to prevent "CLAIM failed" error.  The real fix is to
-   rewrite grub-mkimage to generate valid ELF files.  */
-#define GRUB_MOD_GAP 0x8000
-
-#define GRUB_KERNEL_CPU_PREFIX         0x4
-#define GRUB_KERNEL_CPU_DATA_END       0x44
-
-#endif
diff --git a/include/grub/powerpc/setjmp.h b/include/grub/powerpc/setjmp.h
deleted file mode 100644 (file)
index fa16f73..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_SETJMP_CPU_HEADER
-#define GRUB_SETJMP_CPU_HEADER 1
-
-typedef unsigned long grub_jmp_buf[20];
-
-int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice));
-void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
-
-#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/include/grub/powerpc/time.h b/include/grub/powerpc/time.h
deleted file mode 100644 (file)
index 5db7ff4..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KERNEL_CPU_TIME_HEADER
-#define KERNEL_CPU_TIME_HEADER 1
-
-static __inline void
-grub_cpu_idle (void)
-{
-  /* FIXME: not implemented */
-}
-
-#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/include/grub/powerpc/types.h b/include/grub/powerpc/types.h
deleted file mode 100644 (file)
index a098ae6..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_TYPES_CPU_HEADER
-#define GRUB_TYPES_CPU_HEADER  1
-
-/* The size of void *.  */
-#define GRUB_TARGET_SIZEOF_VOID_P      4
-
-/* The size of long.  */
-#define GRUB_TARGET_SIZEOF_LONG                4
-
-/* powerpc is big-endian.  */
-#define GRUB_TARGET_WORDS_BIGENDIAN    1
-
-
-#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/include/grub/raid.h b/include/grub/raid.h
deleted file mode 100644 (file)
index 8fa4c38..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* raid.h - On disk structures for RAID. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_RAID_H
-#define GRUB_RAID_H    1
-
-#include <grub/types.h>
-
-#define GRUB_RAID_MAX_DEVICES  32
-
-#define GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC       0
-#define GRUB_RAID_LAYOUT_RIGHT_ASYMMETRIC      1
-#define GRUB_RAID_LAYOUT_LEFT_SYMMETRIC                2
-#define GRUB_RAID_LAYOUT_RIGHT_SYMMETRIC       3
-
-#define GRUB_RAID_LAYOUT_RIGHT_MASK            1
-#define GRUB_RAID_LAYOUT_SYMMETRIC_MASK                2
-
-struct grub_raid_array
-{
-  int number;              /* The device number, taken from md_minor so we
-                             are consistent with the device name in
-                             Linux. */
-  int level;               /* RAID levels, only 0, 1 or 5 at the moment. */
-  int layout;              /* Layout for RAID 5/6.  */
-  unsigned int total_devs; /* Total number of devices in the array. */
-  grub_size_t chunk_size;  /* The size of a chunk, in 512 byte sectors. */
-  grub_uint64_t disk_size; /* Size of an individual disk, in 512 byte
-                             sectors. */
-  int index;               /* Index of current device.  */
-  int uuid_len;            /* The length of uuid.  */
-  char *uuid;              /* The UUID of the device. */
-
-  /* The following field is setup by the caller.  */
-  char *name;              /* That will be "md<number>". */
-  unsigned int nr_devs;    /* The number of devices we've found so far. */
-  grub_disk_t device[GRUB_RAID_MAX_DEVICES];  /* Array of total_devs devices. */
-  struct grub_raid_array *next;
-};
-
-struct grub_raid
-{
-  const char *name;
-
-  grub_err_t (*detect) (grub_disk_t disk, struct grub_raid_array *array);
-
-  struct grub_raid *next;
-};
-typedef struct grub_raid *grub_raid_t;
-
-void grub_raid_register (grub_raid_t raid);
-void grub_raid_unregister (grub_raid_t raid);
-
-void grub_raid_block_xor (char *buf1, const char *buf2, int size);
-
-typedef grub_err_t (*grub_raid5_recover_func_t) (struct grub_raid_array *array,
-                                                 int disknr, char *buf,
-                                                 grub_disk_addr_t sector,
-                                                 int size);
-
-typedef grub_err_t (*grub_raid6_recover_func_t) (struct grub_raid_array *array,
-                                                 int disknr, int p, char *buf,
-                                                 grub_disk_addr_t sector,
-                                                 int size);
-
-extern grub_raid5_recover_func_t grub_raid5_recover_func;
-extern grub_raid6_recover_func_t grub_raid6_recover_func;
-
-#endif /* ! GRUB_RAID_H */
diff --git a/include/grub/reader.h b/include/grub/reader.h
deleted file mode 100644 (file)
index fd72a32..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* reader.h - prototypes for command line reader.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_READER_HEADER
-#define GRUB_READER_HEADER     1
-
-#include <grub/err.h>
-
-typedef grub_err_t (*grub_reader_getline_t) (char **, int);
-
-void grub_rescue_run (void);
-
-#endif /* ! GRUB_READER_HEADER */
diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h
deleted file mode 100644 (file)
index b55b6a8..0000000
+++ /dev/null
@@ -1,349 +0,0 @@
-/* normal_parser.h  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_NORMAL_PARSER_HEADER
-#define GRUB_NORMAL_PARSER_HEADER      1
-
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/parser.h>
-
-struct grub_script_mem;
-
-/* The generic header for each scripting command or structure.  */
-struct grub_script_cmd
-{
-  /* This function is called to execute the command.  */
-  grub_err_t (*exec) (struct grub_script_cmd *cmd);
-
-  /* The next command.  This can be used by the parent to form a chain
-     of commands.  */
-  struct grub_script_cmd *next;
-};
-
-struct grub_script
-{
-  struct grub_script_mem *mem;
-  struct grub_script_cmd *cmd;
-};
-\f
-typedef enum
-{
-  GRUB_SCRIPT_ARG_TYPE_VAR,
-  GRUB_SCRIPT_ARG_TYPE_TEXT,
-  GRUB_SCRIPT_ARG_TYPE_DQVAR,
-  GRUB_SCRIPT_ARG_TYPE_DQSTR,
-  GRUB_SCRIPT_ARG_TYPE_SQSTR
-} grub_script_arg_type_t;
-
-/* A part of an argument.  */
-struct grub_script_arg
-{
-  grub_script_arg_type_t type;
-
-  char *str;
-
-  /* Next argument part.  */
-  struct grub_script_arg *next;
-};
-
-/* A complete argument.  It consists of a list of one or more `struct
-   grub_script_arg's.  */
-struct grub_script_arglist
-{
-  struct grub_script_arglist *next;
-  struct grub_script_arg *arg;
-  /* Only stored in the first link.  */
-  int argcount;
-};
-
-/* A single command line.  */
-struct grub_script_cmdline
-{
-  struct grub_script_cmd cmd;
-
-  /* The arguments for this command.  */
-  struct grub_script_arglist *arglist;
-};
-
-/* A block of commands, this can be used to group commands.  */
-struct grub_script_cmdblock
-{
-  struct grub_script_cmd cmd;
-
-  /* A chain of commands.  */
-  struct grub_script_cmd *cmdlist;
-};
-
-/* An if statement.  */
-struct grub_script_cmdif
-{
-  struct grub_script_cmd cmd;
-
-  /* The command used to check if the 'if' is true or false.  */
-  struct grub_script_cmd *exec_to_evaluate;
-
-  /* The code executed in case the result of 'if' was true.  */
-  struct grub_script_cmd *exec_on_true;
-
-  /* The code executed in case the result of 'if' was false.  */
-  struct grub_script_cmd *exec_on_false;
-};
-
-/* A for statement.  */
-struct grub_script_cmdfor
-{
-  struct grub_script_cmd cmd;
-
-  /* The name used as looping variable.  */
-  struct grub_script_arg *name;
-
-  /* The words loop iterates over.  */
-  struct grub_script_arglist *words;
-
-  /* The command list executed in each loop.  */
-  struct grub_script_cmd *list;
-};
-
-/* A while/until command.  */
-struct grub_script_cmdwhile
-{
-  struct grub_script_cmd cmd;
-
-  /* The command list used as condition.  */
-  struct grub_script_cmd *cond;
-
-  /* The command list executed in each loop.  */
-  struct grub_script_cmd *list;
-
-  /* The flag to indicate this as "until" loop.  */
-  int until;
-};
-
-/* A menu entry generate statement.  */
-struct grub_script_cmd_menuentry
-{
-  struct grub_script_cmd cmd;
-
-  /* The arguments for this menu entry.  */
-  struct grub_script_arglist *arglist;
-
-  /* The sourcecode the entry will be generated from.  */
-  const char *sourcecode;
-
-  /* Options.  XXX: Not used yet.  */
-  int options;
-};
-
-/* State of the lexer as passed to the lexer.  */
-struct grub_lexer_param
-{
-  /* Function used by the lexer to get a new line when more input is
-     expected, but not available.  */
-  grub_reader_getline_t getline;
-
-  /* A reference counter.  If this is >0 it means that the parser
-     expects more tokens and `getline' should be called to fetch more.
-     Otherwise the lexer can stop processing if the current buffer is
-     depleted.  */
-  int refs;
-
-  /* While walking through the databuffer, `record' the characters to
-     this other buffer.  It can be used to edit the menu entry at a
-     later moment.  */
-
-  /* If true, recording is enabled.  */
-  int record;
-
-  /* Points to the recording.  */
-  char *recording;
-
-  /* index in the RECORDING.  */
-  int recordpos;
-
-  /* Size of RECORDING.  */
-  int recordlen;
-
-  /* End of file reached.  */
-  int eof;
-
-  /* Merge multiple word tokens.  */
-  int merge_start;
-  int merge_end;
-
-  /* Part of a multi-part token.  */
-  char *text;
-  unsigned used;
-  unsigned size;
-
-  /* Type of text.  */
-  grub_script_arg_type_t type;
-
-  /* Flex scanner.  */
-  void *yyscanner;
-
-  /* Flex scanner buffer.  */
-  void *buffer;
-};
-
-#define GRUB_LEXER_INITIAL_TEXT_SIZE   32
-#define GRUB_LEXER_INITIAL_RECORD_SIZE 256
-
-/* State of the parser as passes to the parser.  */
-struct grub_parser_param
-{
-  /* Keep track of the memory allocated for this specific
-     function.  */
-  struct grub_script_mem *func_mem;
-
-  /* When set to 0, no errors have occurred during parsing.  */
-  int err;
-
-  /* The memory that was used while parsing and scanning.  */
-  struct grub_script_mem *memused;
-
-  /* The result of the parser.  */
-  struct grub_script_cmd *parsed;
-
-  struct grub_lexer_param *lexerstate;
-};
-
-struct grub_script_arglist *
-grub_script_create_arglist (struct grub_parser_param *state);
-
-struct grub_script_arglist *
-grub_script_add_arglist (struct grub_parser_param *state,
-                        struct grub_script_arglist *list,
-                        struct grub_script_arg *arg);
-struct grub_script_cmd *
-grub_script_create_cmdline (struct grub_parser_param *state,
-                           struct grub_script_arglist *arglist);
-struct grub_script_cmd *
-grub_script_create_cmdblock (struct grub_parser_param *state);
-
-struct grub_script_cmd *
-grub_script_create_cmdif (struct grub_parser_param *state,
-                         struct grub_script_cmd *exec_to_evaluate,
-                         struct grub_script_cmd *exec_on_true,
-                         struct grub_script_cmd *exec_on_false);
-
-struct grub_script_cmd *
-grub_script_create_cmdfor (struct grub_parser_param *state,
-                          struct grub_script_arg *name,
-                          struct grub_script_arglist *words,
-                          struct grub_script_cmd *list);
-
-struct grub_script_cmd *
-grub_script_create_cmdwhile (struct grub_parser_param *state,
-                            struct grub_script_cmd *cond,
-                            struct grub_script_cmd *list,
-                            int is_an_until_loop);
-
-struct grub_script_cmd *
-grub_script_create_cmdmenu (struct grub_parser_param *state,
-                           struct grub_script_arglist *arglist,
-                           char *sourcecode,
-                           int options);
-
-struct grub_script_cmd *
-grub_script_add_cmd (struct grub_parser_param *state,
-                    struct grub_script_cmdblock *cmdblock,
-                    struct grub_script_cmd *cmd);
-struct grub_script_arg *
-grub_script_arg_add (struct grub_parser_param *state,
-                    struct grub_script_arg *arg,
-                    grub_script_arg_type_t type, char *str);
-
-struct grub_script *grub_script_parse (char *script,
-                                      grub_reader_getline_t getline);
-void grub_script_free (struct grub_script *script);
-struct grub_script *grub_script_create (struct grub_script_cmd *cmd,
-                                       struct grub_script_mem *mem);
-
-struct grub_lexer_param *grub_script_lexer_init (struct grub_parser_param *parser,
-                                                char *script,
-                                                grub_reader_getline_t getline);
-void grub_script_lexer_fini (struct grub_lexer_param *);
-void grub_script_lexer_ref (struct grub_lexer_param *);
-void grub_script_lexer_deref (struct grub_lexer_param *);
-void grub_script_lexer_record_start (struct grub_parser_param *);
-char *grub_script_lexer_record_stop (struct grub_parser_param *);
-int  grub_script_lexer_yywrap (struct grub_parser_param *);
-void grub_script_lexer_record (struct grub_parser_param *, char *);
-
-/* Functions to track allocated memory.  */
-struct grub_script_mem *grub_script_mem_record (struct grub_parser_param *state);
-struct grub_script_mem *grub_script_mem_record_stop (struct grub_parser_param *state,
-                                                    struct grub_script_mem *restore);
-void *grub_script_malloc (struct grub_parser_param *state, grub_size_t size);
-
-/* Functions used by bison.  */
-union YYSTYPE;
-int grub_script_yylex (union YYSTYPE *, struct grub_parser_param *);
-int grub_script_yyparse (struct grub_parser_param *);
-void grub_script_yyerror (struct grub_parser_param *, char const *);
-
-/* Commands to execute, don't use these directly.  */
-grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd);
-grub_err_t grub_script_execute_cmdblock (struct grub_script_cmd *cmd);
-grub_err_t grub_script_execute_cmdif (struct grub_script_cmd *cmd);
-grub_err_t grub_script_execute_cmdfor (struct grub_script_cmd *cmd);
-grub_err_t grub_script_execute_cmdwhile (struct grub_script_cmd *cmd);
-grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd);
-
-/* Execute any GRUB pre-parsed command or script.  */
-grub_err_t grub_script_execute (struct grub_script *script);
-
-/* This variable points to the parsed command.  This is used to
-   communicate with the bison code.  */
-extern struct grub_script_cmd *grub_script_parsed;
-
-\f
-
-/* The function description.  */
-struct grub_script_function
-{
-  /* The name.  */
-  char *name;
-
-  /* The script function.  */
-  struct grub_script *func;
-
-  /* The flags.  */
-  unsigned flags;
-
-  /* The next element.  */
-  struct grub_script_function *next;
-
-  int references;
-};
-typedef struct grub_script_function *grub_script_function_t;
-
-grub_script_function_t grub_script_function_create (struct grub_script_arg *functionname,
-                                                   struct grub_script *cmd);
-void grub_script_function_remove (const char *name);
-grub_script_function_t grub_script_function_find (char *functionname);
-int grub_script_function_iterate (int (*iterate) (grub_script_function_t));
-int grub_script_function_call (grub_script_function_t func,
-                              int argc, char **args);
-
-char **
-grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count);
-
-#endif /* ! GRUB_NORMAL_PARSER_HEADER */
diff --git a/include/grub/scsi.h b/include/grub/scsi.h
deleted file mode 100644 (file)
index fbe4582..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef        GRUB_SCSI_H
-#define        GRUB_SCSI_H     1
-
-typedef struct grub_scsi_dev *grub_scsi_dev_t;
-
-void grub_scsi_dev_register (grub_scsi_dev_t dev);
-void grub_scsi_dev_unregister (grub_scsi_dev_t dev);
-
-struct grub_scsi;
-
-struct grub_scsi_dev
-{
-  /* The device name.  */
-  const char *name;
-
-  /* Call HOOK with each device name, until HOOK returns non-zero.  */
-  int (*iterate) (int (*hook) (const char *name, int luns));
-
-  /* Open the device named NAME, and set up SCSI.  */
-  grub_err_t (*open) (const char *name, struct grub_scsi *scsi);
-
-  /* Close the scsi device SCSI.  */
-  void (*close) (struct grub_scsi *scsi);
-
-  /* Read SIZE bytes from the device SCSI into BUF after sending the
-     command CMD of size CMDSIZE.  */
-  grub_err_t (*read) (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
-                     grub_size_t size, char *buf);
-
-  /* Write SIZE  bytes from BUF to  the device SCSI  after sending the
-     command CMD of size CMDSIZE.  */
-  grub_err_t (*write) (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
-                      grub_size_t size, char *buf);
-
-  /* The next scsi device.  */
-  struct grub_scsi_dev *next;
-};
-
-struct grub_scsi
-{
-  /* The scsi device name.  */
-  char *name;
-
-  /* The underlying scsi device.  */
-  grub_scsi_dev_t dev;
-
-  /* Type of SCSI device.  XXX: Make enum.  */
-  grub_uint8_t devtype;
-
-  /* Number of LUNs.  */
-  int luns;
-
-  /* LUN for this `struct grub_scsi'.  */
-  int lun;
-
-  /* Set to 0 when not removable, 1 when removable.  */
-  int removable;
-
-  /* Size of the device in blocks.  */
-  int size;
-
-  /* Size of one block.  */
-  int blocksize;
-
-  /* Device-specific data.  */
-  void *data;
-};
-typedef struct grub_scsi *grub_scsi_t;
-
-#endif /* GRUB_SCSI_H */
diff --git a/include/grub/scsicmd.h b/include/grub/scsicmd.h
deleted file mode 100644 (file)
index 40f237a..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef        GRUB_SCSICMD_H
-#define        GRUB_SCSICMD_H  1
-
-#include <grub/types.h>
-
-#define GRUB_SCSI_DEVTYPE_MASK 31
-#define GRUB_SCSI_REMOVABLE_BIT        7
-#define GRUB_SCSI_LUN_SHIFT    5
-
-struct grub_scsi_inquiry
-{
-  grub_uint8_t opcode;
-  grub_uint8_t lun;
-  grub_uint16_t reserved;
-  grub_uint16_t alloc_length;
-  grub_uint8_t reserved2;
-  grub_uint8_t pad[5];
-} __attribute__((packed));
-
-struct grub_scsi_inquiry_data
-{
-  grub_uint8_t devtype;
-  grub_uint8_t rmb;
-  grub_uint16_t reserved;
-  grub_uint8_t length;
-  grub_uint8_t reserved2[3];
-  char vendor[8];
-  char prodid[16];
-  char prodrev[4];
-} __attribute__((packed));
-
-struct grub_scsi_read_capacity
-{
-  grub_uint8_t opcode;
-  grub_uint8_t lun;
-  grub_uint8_t reserved[8];
-  grub_uint8_t pad[2];
-} __attribute__((packed));
-
-struct grub_scsi_read_capacity_data
-{
-  grub_uint32_t size;
-  grub_uint32_t blocksize;
-} __attribute__((packed));
-
-struct grub_scsi_read10
-{
-  grub_uint8_t opcode;
-  grub_uint8_t lun;
-  grub_uint32_t lba;
-  grub_uint8_t reserved;
-  grub_uint16_t size;
-  grub_uint8_t reserved2;
-  grub_uint16_t pad;
-} __attribute__((packed));
-
-struct grub_scsi_read12
-{
-  grub_uint8_t opcode;
-  grub_uint8_t lun;
-  grub_uint32_t lba;
-  grub_uint32_t size;
-  grub_uint8_t reserved;
-  grub_uint8_t control;
-} __attribute__((packed));
-
-struct grub_scsi_write10
-{
-  grub_uint8_t opcode;
-  grub_uint8_t lun;
-  grub_uint32_t lba;
-  grub_uint8_t reserved;
-  grub_uint16_t size;
-  grub_uint8_t reserved2;
-  grub_uint16_t pad;
-} __attribute__((packed));
-
-struct grub_scsi_write12
-{
-  grub_uint8_t opcode;
-  grub_uint8_t lun;
-  grub_uint32_t lba;
-  grub_uint32_t size;
-  grub_uint8_t reserved;
-  grub_uint8_t control;
-} __attribute__((packed));
-
-typedef enum
-  {
-    grub_scsi_cmd_inquiry = 0x12,
-    grub_scsi_cmd_read_capacity = 0x25,
-    grub_scsi_cmd_read10 = 0x28,
-    grub_scsi_cmd_write10 = 0x2a,
-    grub_scsi_cmd_read12 = 0xa8,
-    grub_scsi_cmd_write12 = 0xaa
-  } grub_scsi_cmd_t;
-
-typedef enum
-  {
-    grub_scsi_devtype_direct = 0x00,
-    grub_scsi_devtype_cdrom = 0x05
-  } grub_scsi_devtype_t;
-
-#endif /* GRUB_SCSICMD_H */
diff --git a/include/grub/sdl.h b/include/grub/sdl.h
deleted file mode 100644 (file)
index e4efdc9..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-void EXPORT_FUNC (SDL_Quit) (void);
-void EXPORT_FUNC (SDL_SetColors) (void);
-void EXPORT_FUNC (SDL_Init) (void);
-void EXPORT_FUNC (SDL_GetError) (void);
-void EXPORT_FUNC (SDL_Flip) (void);
-void EXPORT_FUNC (SDL_SetVideoMode) (void);
diff --git a/include/grub/search.h b/include/grub/search.h
deleted file mode 100644 (file)
index e8f9db2..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_SEARCH_HEADER
-#define GRUB_SEARCH_HEADER 1
-
-void grub_search_fs_file (const char *key, const char *var, int no_floppy);
-void grub_search_fs_uuid (const char *key, const char *var, int no_floppy);
-void grub_search_label (const char *key, const char *var, int no_floppy);
-
-#endif
diff --git a/include/grub/serial.h b/include/grub/serial.h
deleted file mode 100644 (file)
index 1c35b40..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* serial.h - serial device interface */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2000,2001,2002,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_SERIAL_HEADER
-#define GRUB_SERIAL_HEADER     1
-
-/* Macros.  */
-
-/* The offsets of UART registers.  */
-#define UART_TX                0
-#define UART_RX                0
-#define UART_DLL       0
-#define UART_IER       1
-#define UART_DLH       1
-#define UART_IIR       2
-#define UART_FCR       2
-#define UART_LCR       3
-#define UART_MCR       4
-#define UART_LSR       5
-#define UART_MSR       6
-#define UART_SR                7
-
-/* For LSR bits.  */
-#define UART_DATA_READY                0x01
-#define UART_EMPTY_TRANSMITTER 0x20
-
-/* The type of parity.  */
-#define UART_NO_PARITY         0x00
-#define UART_ODD_PARITY                0x08
-#define UART_EVEN_PARITY       0x18
-
-/* The type of word length.  */
-#define UART_5BITS_WORD        0x00
-#define UART_6BITS_WORD        0x01
-#define UART_7BITS_WORD        0x02
-#define UART_8BITS_WORD        0x03
-
-/* The type of the length of stop bit.  */
-#define UART_1_STOP_BIT                0x00
-#define UART_2_STOP_BITS       0x04
-
-/* the switch of DLAB.  */
-#define UART_DLAB      0x80
-
-/* Enable the FIFO.  */
-#define UART_ENABLE_FIFO       0xC7
-
-/* Turn on DTR, RTS, and OUT2.  */
-#define UART_ENABLE_MODEM      0x0B
-
-#endif /* ! GRUB_SERIAL_MACHINE_HEADER */
diff --git a/include/grub/setjmp.h b/include/grub/setjmp.h
deleted file mode 100644 (file)
index 70147a7..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_SETJMP_HEADER
-#define GRUB_SETJMP_HEADER     1
-
-#if defined(GRUB_UTIL) && !defined(GRUBOF)
-#include <setjmp.h>
-typedef jmp_buf grub_jmp_buf;
-#define grub_setjmp setjmp
-#define grub_longjmp longjmp
-#else
-/* This must define grub_jmp_buf, and declare grub_setjmp and
-   grub_longjmp.  */
-# include <grub/cpu/setjmp.h>
-#endif
-
-#endif /* ! GRUB_SETJMP_HEADER */
diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h
deleted file mode 100644 (file)
index 9671c69..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009   Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_BOOT_MACHINE_HEADER
-#define GRUB_BOOT_MACHINE_HEADER       1
-
-#define CIF_REG                                %l0
-#define CHOSEN_NODE_REG                        %l4
-#define STDOUT_NODE_REG                        %l5
-#define BOOTDEV_REG                    %l6
-#define PIC_REG                                %l7
-
-#define        SCRATCH_PAD_BOOT                0x5000
-#define        SCRATCH_PAD_DISKBOOT            0x4000
-
-#define GET_ABS(symbol, reg)   \
-       add     PIC_REG, (symbol - pic_base), reg
-#define LDUW_ABS(symbol, offset, reg)  \
-       lduw    [PIC_REG + (symbol - pic_base) + (offset)], reg
-#define LDX_ABS(symbol, offset, reg)   \
-       ldx     [PIC_REG + (symbol - pic_base) + (offset)], reg
-
-#define GRUB_BOOT_AOUT_HEADER_SIZE     32
-
-#define GRUB_BOOT_MACHINE_SIGNATURE    0xbb44aa55
-
-#define GRUB_BOOT_MACHINE_VER_MAJ      0x08
-
-#define GRUB_BOOT_MACHINE_BOOT_DEVPATH 0x0a
-
-#define GRUB_BOOT_MACHINE_BOOT_DEVPATH_END 0x80
-
-#define GRUB_BOOT_MACHINE_KERNEL_BYTE 0x80
-
-#define GRUB_BOOT_MACHINE_CODE_END \
-       (0x1fc - GRUB_BOOT_AOUT_HEADER_SIZE)
-
-#define GRUB_BOOT_MACHINE_LIST_SIZE    12
-
-#define GRUB_BOOT_MACHINE_IMAGE_ADDRESS        0x4400
-
-#define GRUB_BOOT_MACHINE_KERNEL_ADDR 0x4200
-
-#endif /* ! BOOT_MACHINE_HEADER */
diff --git a/include/grub/sparc64/ieee1275/console.h b/include/grub/sparc64/ieee1275/console.h
deleted file mode 100644 (file)
index ed2b720..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_CONSOLE_MACHINE_HEADER
-#define GRUB_CONSOLE_MACHINE_HEADER    1
-
-/* Initialize the console system.  */
-void grub_console_init (void);
-
-/* Finish the console system.  */
-void grub_console_fini (void);
-
-#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */
diff --git a/include/grub/sparc64/ieee1275/ieee1275.h b/include/grub/sparc64/ieee1275/ieee1275.h
deleted file mode 100644 (file)
index 32c77f8..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* ieee1275.h - Access the Open Firmware client interface.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_IEEE1275_MACHINE_HEADER
-#define GRUB_IEEE1275_MACHINE_HEADER   1
-
-#include <grub/types.h>
-
-#define GRUB_IEEE1275_CELL_SIZEOF 8
-typedef grub_uint64_t grub_ieee1275_cell_t;
-
-/* Encoding of 'mode' argument to grub_ieee1275_map_physical() */
-#define IEEE1275_MAP_WRITE     0x0001 /* Writable */
-#define IEEE1275_MAP_READ      0x0002 /* Readable */
-#define IEEE1275_MAP_EXEC      0x0004 /* Executable */
-#define IEEE1275_MAP_LOCKED    0x0010 /* Locked in TLB */
-#define IEEE1275_MAP_CACHED    0x0020 /* Cacheable */
-#define IEEE1275_MAP_SE                0x0040 /* Side-effects */
-#define IEEE1275_MAP_GLOBAL    0x0080 /* Global */
-#define IEEE1275_MAP_IE                0x0100 /* Invert Endianness */
-#define IEEE1275_MAP_DEFAULT   (IEEE1275_MAP_WRITE | IEEE1275_MAP_READ | \
-                                IEEE1275_MAP_EXEC | IEEE1275_MAP_CACHED)
-
-extern int EXPORT_FUNC(grub_ieee1275_claim_vaddr) (grub_addr_t vaddr,
-                                                  grub_size_t size);
-extern int EXPORT_FUNC(grub_ieee1275_alloc_physmem) (grub_addr_t *paddr,
-                                                    grub_size_t size,
-                                                    grub_uint32_t align);
-
-extern grub_addr_t EXPORT_VAR (grub_ieee1275_original_stack);
-
-#endif /* ! GRUB_IEEE1275_MACHINE_HEADER */
diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h
deleted file mode 100644 (file)
index a16fb88..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_KERNEL_MACHINE_HEADER
-#define GRUB_KERNEL_MACHINE_HEADER     1
-
-#define GRUB_MOD_ALIGN 0x2000
-
-/* Non-zero value is only needed for PowerMacs.  */
-#define GRUB_MOD_GAP 0x0
-
-/* The offset of GRUB_TOTAL_MODULE_SIZE.  */
-#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE  0x8
-
-/* The offset of GRUB_KERNEL_IMAGE_SIZE.  */
-#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE  0xc
-
-/* The offset of GRUB_COMPRESSED_SIZE.  */
-#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE    0x10
-
-/* The offset of GRUB_PREFIX.  */
-#define GRUB_KERNEL_MACHINE_PREFIX             0x14
-
-/* End of the data section. */
-#define GRUB_KERNEL_MACHINE_DATA_END           0x114
-
-#define GRUB_KERNEL_MACHINE_RAW_SIZE                   0
-#define GRUB_KERNEL_MACHINE_STACK_SIZE          0x40000
-
-#define GRUB_PLATFORM_IMAGE_FORMATS     "raw, aout"
-#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT     "raw"
-
-#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW
-
-#ifndef ASM_FILE
-
-typedef enum {
-  GRUB_PLATFORM_IMAGE_RAW,
-  GRUB_PLATFORM_IMAGE_AOUT
-}
-  grub_platform_image_format_t;
-#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW
-#define GRUB_PLATFORM_IMAGE_AOUT GRUB_PLATFORM_IMAGE_AOUT
-
-#include <grub/symbol.h>
-#include <grub/types.h>
-
-/* The size of kernel image.  */
-extern grub_int32_t grub_kernel_image_size;
-
-/* The total size of module images following the kernel.  */
-extern grub_int32_t grub_total_module_size;
-
-/* The prefix which points to the directory where GRUB modules and its
-   configuration file are located.  */
-extern char grub_prefix[];
-
-#endif /* ! ASM_FILE */
-
-#endif /* ! GRUB_KERNEL_MACHINE_HEADER */
diff --git a/include/grub/sparc64/ieee1275/loader.h b/include/grub/sparc64/ieee1275/loader.h
deleted file mode 100644 (file)
index 12bb2a6..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_LOADER_MACHINE_HEADER
-#define GRUB_LOADER_MACHINE_HEADER     1
-
-/* The symbol shared between the normal mode and rescue mode
-   loader.  */
-void grub_rescue_cmd_linux (int argc, char *argv[]);
-void grub_rescue_cmd_initrd (int argc, char *argv[]);
-
-#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/include/grub/sparc64/ieee1275/memory.h b/include/grub/sparc64/ieee1275/memory.h
deleted file mode 100644 (file)
index 25e3100..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MEMORY_MACHINE_HEADER
-#define GRUB_MEMORY_MACHINE_HEADER     1
-
-#include <grub/ieee1275/ieee1275.h>
-
-#define GRUB_MACHINE_MEMORY_AVAILABLE          1
-
-#endif
diff --git a/include/grub/sparc64/ieee1275/time.h b/include/grub/sparc64/ieee1275/time.h
deleted file mode 100644 (file)
index 3f8ad26..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KERNEL_MACHINE_TIME_HEADER
-#define KERNEL_MACHINE_TIME_HEADER     1
-
-#include <grub/symbol.h>
-
-#define GRUB_TICKS_PER_SECOND  1000
-
-/* Return the real time in ticks.  */
-grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
-
-#endif /* ! KERNEL_MACHINE_TIME_HEADER */
diff --git a/include/grub/sparc64/kernel.h b/include/grub/sparc64/kernel.h
deleted file mode 100644 (file)
index 9f404b0..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_KERNEL_CPU_HEADER
-#define GRUB_KERNEL_CPU_HEADER 1
-
-#define GRUB_MOD_ALIGN 0x2000
-
-/* Non-zero value is only needed for PowerMacs.  */
-#define GRUB_MOD_GAP 0x0
-
-#define GRUB_KERNEL_CPU_PREFIX 0x2
-#define GRUB_KERNEL_CPU_DATA_END       0x42
-
-#endif
diff --git a/include/grub/sparc64/setjmp.h b/include/grub/sparc64/setjmp.h
deleted file mode 100644 (file)
index 6096bae..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_SETJMP_CPU_HEADER
-#define GRUB_SETJMP_CPU_HEADER 1
-
-#include <grub/types.h>
-
-typedef grub_uint64_t grub_jmp_buf[3];
-
-int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice));
-void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
-
-#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/include/grub/sparc64/time.h b/include/grub/sparc64/time.h
deleted file mode 100644 (file)
index 5db7ff4..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KERNEL_CPU_TIME_HEADER
-#define KERNEL_CPU_TIME_HEADER 1
-
-static __inline void
-grub_cpu_idle (void)
-{
-  /* FIXME: not implemented */
-}
-
-#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/include/grub/sparc64/types.h b/include/grub/sparc64/types.h
deleted file mode 100644 (file)
index b9b0cf9..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_TYPES_CPU_HEADER
-#define GRUB_TYPES_CPU_HEADER  1
-
-/* The size of void *.  */
-#define GRUB_TARGET_SIZEOF_VOID_P      8
-
-/* The size of long.  */
-#define GRUB_TARGET_SIZEOF_LONG                8
-
-/* sparc64 is big-endian.  */
-#define GRUB_TARGET_WORDS_BIGENDIAN    1
-
-
-#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/include/grub/symbol.h b/include/grub/symbol.h
deleted file mode 100644 (file)
index 63ed194..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_SYMBOL_HEADER
-#define GRUB_SYMBOL_HEADER     1
-
-#include <config.h>
-
-/* Apple assembler requires local labels to start with a capital L */
-#define LOCAL(sym)     L_ ## sym
-
-/* Add an underscore to a C symbol in assembler code if needed. */
-#ifdef HAVE_ASM_USCORE
-# define EXT_C(sym)    _ ## sym
-#else
-# define EXT_C(sym)    sym
-#endif
-
-#if defined (APPLE_CC)
-#define FUNCTION(x)    .globl EXT_C(x) ; EXT_C(x):
-#define VARIABLE(x)    .globl EXT_C(x) ; EXT_C(x):
-#elif ! defined (__CYGWIN__) && ! defined (__MINGW32__)
-#define FUNCTION(x)    .globl EXT_C(x) ; .type EXT_C(x), "function" ; EXT_C(x):
-#define VARIABLE(x)    .globl EXT_C(x) ; .type EXT_C(x), "object" ; EXT_C(x):
-#else
-/* .type not supported for non-ELF targets.  XXX: Check this in configure? */
-#define FUNCTION(x)    .globl EXT_C(x) ; .def EXT_C(x); .scl 2; .type 32; .endef; EXT_C(x):
-#define VARIABLE(x)    .globl EXT_C(x) ; .def EXT_C(x); .scl 2; .type 0; .endef; EXT_C(x):
-#endif
-
-/* Mark an exported symbol.  */
-#ifndef GRUB_SYMBOL_GENERATOR
-# define EXPORT_FUNC(x)        x
-# define EXPORT_VAR(x) x
-#endif /* ! GRUB_SYMBOL_GENERATOR */
-
-#endif /* ! GRUB_SYMBOL_HEADER */
diff --git a/include/grub/term.h b/include/grub/term.h
deleted file mode 100644 (file)
index 143aabe..0000000
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2005,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_TERM_HEADER
-#define GRUB_TERM_HEADER       1
-
-/* Internal codes used by GRUB to represent terminal input.  */
-#define GRUB_TERM_LEFT         2
-#define GRUB_TERM_RIGHT                6
-#define GRUB_TERM_UP           16
-#define GRUB_TERM_DOWN         14
-#define GRUB_TERM_HOME         1
-#define GRUB_TERM_END          5
-#define GRUB_TERM_DC           4
-#define GRUB_TERM_PPAGE                7
-#define GRUB_TERM_NPAGE                3
-#define GRUB_TERM_ESC          '\e'
-#define GRUB_TERM_TAB          '\t'
-#define GRUB_TERM_BACKSPACE    8
-
-#ifndef ASM_FILE
-
-#include <grub/err.h>
-#include <grub/symbol.h>
-#include <grub/types.h>
-#include <grub/handler.h>
-
-/* These are used to represent the various color states we use.  */
-typedef enum
-  {
-    /* The color used to display all text that does not use the
-       user defined colors below.  */
-    GRUB_TERM_COLOR_STANDARD,
-    /* The user defined colors for normal text.  */
-    GRUB_TERM_COLOR_NORMAL,
-    /* The user defined colors for highlighted text.  */
-    GRUB_TERM_COLOR_HIGHLIGHT
-  }
-grub_term_color_state;
-
-/* Flags for representing the capabilities of a terminal.  */
-/* Some notes about the flags:
-   - These flags are used by higher-level functions but not terminals
-   themselves.
-   - If a terminal is dumb, you may assume that only putchar, getkey and
-   checkkey are called.
-   - Some fancy features (setcolorstate, setcolor and setcursor) can be set
-   to NULL.  */
-
-/* Set when input characters shouldn't be echoed back.  */
-#define GRUB_TERM_NO_ECHO      (1 << 0)
-/* Set when the editing feature should be disabled.  */
-#define GRUB_TERM_NO_EDIT      (1 << 1)
-/* Set when the terminal cannot do fancy things.  */
-#define GRUB_TERM_DUMB         (1 << 2)
-
-
-/* Bitmasks for modifier keys returned by grub_getkeystatus.  */
-#define GRUB_TERM_STATUS_SHIFT (1 << 0)
-#define GRUB_TERM_STATUS_CTRL  (1 << 1)
-#define GRUB_TERM_STATUS_ALT   (1 << 2)
-
-
-/* Unicode characters for fancy graphics.  */
-#define GRUB_TERM_DISP_LEFT    0x2190
-#define GRUB_TERM_DISP_UP      0x2191
-#define GRUB_TERM_DISP_RIGHT   0x2192
-#define GRUB_TERM_DISP_DOWN    0x2193
-#define GRUB_TERM_DISP_HLINE   0x2501
-#define GRUB_TERM_DISP_VLINE   0x2503
-#define GRUB_TERM_DISP_UL      0x250F
-#define GRUB_TERM_DISP_UR      0x2513
-#define GRUB_TERM_DISP_LL      0x2517
-#define GRUB_TERM_DISP_LR      0x251B
-
-
-/* Menu-related geometrical constants.  */
-
-/* The number of lines of "GRUB version..." at the top.  */
-#define GRUB_TERM_INFO_HEIGHT  1
-
-/* The number of columns/lines between messages/borders/etc.  */
-#define GRUB_TERM_MARGIN       1
-
-/* The number of columns of scroll information.  */
-#define GRUB_TERM_SCROLL_WIDTH 1
-
-/* The Y position of the top border.  */
-#define GRUB_TERM_TOP_BORDER_Y (GRUB_TERM_MARGIN + GRUB_TERM_INFO_HEIGHT \
-                                 + GRUB_TERM_MARGIN)
-
-/* The X position of the left border.  */
-#define GRUB_TERM_LEFT_BORDER_X        GRUB_TERM_MARGIN
-
-/* The number of lines of messages at the bottom.  */
-#define GRUB_TERM_MESSAGE_HEIGHT       8
-
-/* The Y position of the first entry.  */
-#define GRUB_TERM_FIRST_ENTRY_Y        (GRUB_TERM_TOP_BORDER_Y + 1)
-
-struct grub_term_input
-{
-  /* The next terminal.  */
-  struct grub_term_input *next;
-
-  /* The terminal name.  */
-  const char *name;
-
-  /* Initialize the terminal.  */
-  grub_err_t (*init) (void);
-
-  /* Clean up the terminal.  */
-  grub_err_t (*fini) (void);
-
-  /* Check if any input character is available.  */
-  int (*checkkey) (void);
-
-  /* Get a character.  */
-  int (*getkey) (void);
-
-  /* Get keyboard modifier status.  */
-  int (*getkeystatus) (void);
-};
-typedef struct grub_term_input *grub_term_input_t;
-
-struct grub_term_output
-{
-  /* The next terminal.  */
-  struct grub_term_output *next;
-
-  /* The terminal name.  */
-  const char *name;
-
-  /* Initialize the terminal.  */
-  grub_err_t (*init) (void);
-
-  /* Clean up the terminal.  */
-  grub_err_t (*fini) (void);
-
-  /* Put a character. C is encoded in Unicode.  */
-  void (*putchar) (grub_uint32_t c);
-
-  /* Get the number of columns occupied by a given character C. C is
-     encoded in Unicode.  */
-  grub_ssize_t (*getcharwidth) (grub_uint32_t c);
-
-  /* Get the screen size. The return value is ((Width << 8) | Height).  */
-  grub_uint16_t (*getwh) (void);
-
-  /* Get the cursor position. The return value is ((X << 8) | Y).  */
-  grub_uint16_t (*getxy) (void);
-
-  /* Go to the position (X, Y).  */
-  void (*gotoxy) (grub_uint8_t x, grub_uint8_t y);
-
-  /* Clear the screen.  */
-  void (*cls) (void);
-
-  /* Set the current color to be used */
-  void (*setcolorstate) (grub_term_color_state state);
-
-  /* Set the normal color and the highlight color. The format of each
-     color is VGA's.  */
-  void (*setcolor) (grub_uint8_t normal_color, grub_uint8_t highlight_color);
-
-  /* Get the normal color and the highlight color. The format of each
-     color is VGA's.  */
-  void (*getcolor) (grub_uint8_t *normal_color, grub_uint8_t *highlight_color);
-
-  /* Turn on/off the cursor.  */
-  void (*setcursor) (int on);
-
-  /* Update the screen.  */
-  void (*refresh) (void);
-
-  /* The feature flags defined above.  */
-  grub_uint32_t flags;
-};
-typedef struct grub_term_output *grub_term_output_t;
-
-extern struct grub_term_output *EXPORT_VAR(grub_term_outputs_disabled);
-extern struct grub_term_input *EXPORT_VAR(grub_term_inputs_disabled);
-extern struct grub_term_output *EXPORT_VAR(grub_term_outputs);
-extern struct grub_term_input *EXPORT_VAR(grub_term_inputs);
-
-static inline void
-grub_term_register_input (const char *name __attribute__ ((unused)),
-                         grub_term_input_t term)
-{
-  if (grub_term_inputs)
-    grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
-                   GRUB_AS_LIST (term));
-  else
-    {
-      /* If this is the first terminal, enable automatically.  */
-      if (! term->init || term->init () == GRUB_ERR_NONE)
-       grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term));
-    }
-}
-
-static inline void
-grub_term_register_output (const char *name __attribute__ ((unused)),
-                          grub_term_output_t term)
-{
-  if (grub_term_outputs)
-    grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
-                   GRUB_AS_LIST (term));
-  else
-    {
-      /* If this is the first terminal, enable automatically.  */
-      if (! term->init || term->init () == GRUB_ERR_NONE)
-       grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
-                       GRUB_AS_LIST (term));
-    }
-}
-
-static inline void
-grub_term_unregister_input (grub_term_input_t term)
-{
-  grub_list_remove (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term));
-  grub_list_remove (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
-                   GRUB_AS_LIST (term));
-}
-
-static inline void
-grub_term_unregister_output (grub_term_output_t term)
-{
-  grub_list_remove (GRUB_AS_LIST_P (&grub_term_outputs), GRUB_AS_LIST (term));
-  grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
-                   GRUB_AS_LIST (term));
-}
-
-#define FOR_ACTIVE_TERM_INPUTS(var) for (var = grub_term_inputs; var; var = var->next)
-#define FOR_DISABLED_TERM_INPUTS(var) for (var = grub_term_inputs_disabled; var; var = var->next)
-#define FOR_ACTIVE_TERM_OUTPUTS(var) for (var = grub_term_outputs; var; var = var->next)
-#define FOR_DISABLED_TERM_OUTPUTS(var) for (var = grub_term_outputs_disabled; var; var = var->next)
-
-void EXPORT_FUNC(grub_putchar) (int c);
-void EXPORT_FUNC(grub_putcode) (grub_uint32_t code,
-                               struct grub_term_output *term);
-int EXPORT_FUNC(grub_getkey) (void);
-int EXPORT_FUNC(grub_checkkey) (void);
-int EXPORT_FUNC(grub_getkeystatus) (void);
-void EXPORT_FUNC(grub_cls) (void);
-void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state);
-void EXPORT_FUNC(grub_refresh) (void);
-void grub_puts_terminal (const char *str, struct grub_term_output *term);
-grub_uint16_t *grub_term_save_pos (void);
-void grub_term_restore_pos (grub_uint16_t *pos);
-
-static inline unsigned grub_term_width (struct grub_term_output *term)
-{
-  return ((term->getwh()&0xFF00)>>8);
-}
-
-static inline unsigned grub_term_height (struct grub_term_output *term)
-{
-  return (term->getwh()&0xFF);
-}
-
-/* The width of the border.  */
-static inline unsigned
-grub_term_border_width (struct grub_term_output *term)
-{
-  return grub_term_width (term) - GRUB_TERM_MARGIN * 3 - GRUB_TERM_SCROLL_WIDTH;
-}
-
-/* The max column number of an entry. The last "-1" is for a
-   continuation marker.  */
-static inline int
-grub_term_entry_width (struct grub_term_output *term)
-{
-  return grub_term_border_width (term) - 2 - GRUB_TERM_MARGIN * 2 - 1;
-}
-
-/* The height of the border.  */
-
-static inline unsigned
-grub_term_border_height (struct grub_term_output *term)
-{
-  return grub_term_height (term) - GRUB_TERM_TOP_BORDER_Y
-    - GRUB_TERM_MESSAGE_HEIGHT;
-}
-
-/* The number of entries shown at a time.  */
-static inline int
-grub_term_num_entries (struct grub_term_output *term)
-{
-  return grub_term_border_height (term) - 2;
-}
-
-static inline int
-grub_term_cursor_x (struct grub_term_output *term)
-{
-  return (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term) 
-         - GRUB_TERM_MARGIN - 1);
-}
-
-static inline grub_uint16_t
-grub_term_getxy (struct grub_term_output *term)
-{
-  return term->getxy ();
-}
-
-static inline void
-grub_term_refresh (struct grub_term_output *term)
-{
-  if (term->refresh)
-    term->refresh ();
-}
-
-static inline void
-grub_term_gotoxy (struct grub_term_output *term, grub_uint8_t x, grub_uint8_t y)
-{
-  term->gotoxy (x, y);
-}
-
-static inline void 
-grub_term_setcolorstate (struct grub_term_output *term, 
-                        grub_term_color_state state)
-{
-  if (term->setcolorstate)
-    term->setcolorstate (state);
-}
-
-  /* Set the normal color and the highlight color. The format of each
-     color is VGA's.  */
-static inline void 
-grub_term_setcolor (struct grub_term_output *term,
-                   grub_uint8_t normal_color, grub_uint8_t highlight_color)
-{
-  if (term->setcolor)
-    term->setcolor (normal_color, highlight_color);
-}
-
-/* Turn on/off the cursor.  */
-static inline void 
-grub_term_setcursor (struct grub_term_output *term, int on)
-{
-  if (term->setcursor)
-    term->setcursor (on);
-}
-
-static inline void 
-grub_term_cls (struct grub_term_output *term)
-{
-  if (term->cls)
-    (term->cls) ();
-  else
-    {
-      grub_putcode ('\n', term);
-      grub_term_refresh (term);
-    }
-}
-
-static inline grub_ssize_t 
-grub_term_getcharwidth (struct grub_term_output *term, grub_uint32_t c)
-{
-  if (term->getcharwidth)
-    return term->getcharwidth (c);
-  else
-    return 1;
-}
-
-static inline void 
-grub_term_getcolor (struct grub_term_output *term, 
-                   grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
-{
-  if (term->getcolor)
-    term->getcolor (normal_color, highlight_color);
-  else
-    {
-      *normal_color = 0x07;
-      *highlight_color = 0x07;
-    }
-}
-
-extern void (*EXPORT_VAR (grub_newline_hook)) (void);
-
-struct grub_term_autoload
-{
-  struct grub_term_autoload *next;
-  char *name;
-  char *modname;
-};
-
-extern struct grub_term_autoload *grub_term_input_autoload;
-extern struct grub_term_autoload *grub_term_output_autoload;
-
-static inline void
-grub_print_spaces (struct grub_term_output *term, int number_spaces)
-{
-  while (--number_spaces >= 0)
-    grub_putcode (' ', term);
-}
-
-
-/* For convenience.  */
-#define GRUB_TERM_ASCII_CHAR(c)        ((c) & 0xff)
-
-#endif /* ! ASM_FILE */
-
-#endif /* ! GRUB_TERM_HEADER */
diff --git a/include/grub/terminfo.h b/include/grub/terminfo.h
deleted file mode 100644 (file)
index e3a2c17..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_TERMINFO_HEADER
-#define GRUB_TERMINFO_HEADER   1
-
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/term.h>
-
-char *grub_terminfo_get_current (void);
-grub_err_t grub_terminfo_set_current (const char *);
-
-void grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y,
-                          grub_term_output_t oterm);
-void grub_terminfo_cls (grub_term_output_t oterm);
-void grub_terminfo_reverse_video_on (grub_term_output_t oterm);
-void grub_terminfo_reverse_video_off (grub_term_output_t oterm);
-void grub_terminfo_cursor_on (grub_term_output_t oterm);
-void grub_terminfo_cursor_off (grub_term_output_t oterm);
-
-#endif /* ! GRUB_TERMINFO_HEADER */
diff --git a/include/grub/test.h b/include/grub/test.h
deleted file mode 100644 (file)
index 27591cc..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2010 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_TEST_HEADER
-#define GRUB_TEST_HEADER
-
-#include <grub/dl.h>
-#include <grub/list.h>
-#include <grub/misc.h>
-#include <grub/types.h>
-#include <grub/symbol.h>
-
-struct grub_test
-{
-  /* The next test.  */
-  struct grub_test *next;
-
-  /* The test name.  */
-  char *name;
-
-  /* The test main function.  */
-  void (*main) (void);
-};
-typedef struct grub_test *grub_test_t;
-
-extern grub_test_t grub_test_list;
-
-void grub_test_register   (const char *name, void (*test) (void));
-void grub_test_unregister (const char *name);
-
-/* Execute a test and print results.  */
-int grub_test_run (grub_test_t test);
-
-/* Test `cond' for nonzero; log failure otherwise.  */
-void grub_test_nonzero (int cond, const char *file,
-                       const char *func, grub_uint32_t line,
-                       const char *fmt, ...)
-  __attribute__ ((format (printf, 5, 6)));
-
-/* Macro to fill in location details and an optional error message.  */
-#define grub_test_assert(cond, ...)                            \
-  grub_test_nonzero(cond, GRUB_FILE, __FUNCTION__, __LINE__,   \
-                   ## __VA_ARGS__,                             \
-                   "assert failed: %s", #cond)
-
-/* Macro to define a unit test.  */
-#define GRUB_UNIT_TEST(name, funp)             \
-  void grub_unit_test_init (void)              \
-  {                                            \
-    grub_test_register (name, funp);           \
-  }                                            \
-                                               \
-  void grub_unit_test_fini (void)              \
-  {                                            \
-    grub_test_unregister (name);               \
-  }
-
-/* Macro to define a functional test.  */
-#define GRUB_FUNCTIONAL_TEST(name, funp)       \
-  GRUB_MOD_INIT(functional_test_##funp)                \
-  {                                            \
-    grub_test_register (name, funp);           \
-  }                                            \
-                                               \
-  GRUB_MOD_FINI(functional_test_##funp)                \
-  {                                            \
-    grub_test_unregister (name);               \
-  }
-
-#endif /* ! GRUB_TEST_HEADER */
diff --git a/include/grub/time.h b/include/grub/time.h
deleted file mode 100644 (file)
index ae2617e..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007, 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KERNEL_TIME_HEADER
-#define KERNEL_TIME_HEADER     1
-
-#include <grub/types.h>
-#include <grub/symbol.h>
-#include <grub/cpu/time.h>
-
-#if defined (GRUB_MACHINE_EMU) || defined (GRUB_UTIL)
-#define GRUB_TICKS_PER_SECOND 100000
-/* Return the real time in ticks.  */
-grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
-#else
-#include <grub/machine/time.h>
-#endif
-
-void EXPORT_FUNC(grub_millisleep) (grub_uint32_t ms);
-grub_uint64_t EXPORT_FUNC(grub_get_time_ms) (void);
-
-grub_uint64_t grub_rtc_get_time_ms (void);
-
-static __inline void
-grub_sleep (grub_uint32_t s)
-{
-  grub_millisleep (1000 * s);
-}
-
-void grub_install_get_time_ms (grub_uint64_t (*get_time_ms_func) (void));
-
-#endif /* ! KERNEL_TIME_HEADER */
diff --git a/include/grub/tparm.h b/include/grub/tparm.h
deleted file mode 100644 (file)
index 642a22f..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/* tparm.h - parameter formatting of terminfo */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_TPARM_HEADER
-#define GRUB_TPARM_HEADER      1
-
-/* Function prototypes.  */
-char *grub_terminfo_tparm (const char *string, ...);
-
-#endif /* ! GRUB_TPARM_HEADER */
diff --git a/include/grub/trig.h b/include/grub/trig.h
deleted file mode 100644 (file)
index 2512a5f..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/* trig.h - Trigonometric function support.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_TRIG_HEADER
-#define GRUB_TRIG_HEADER 1
-
-#define GRUB_TRIG_ANGLE_MAX 256
-#define GRUB_TRIG_ANGLE_MASK 255
-#define GRUB_TRIG_FRACTION_SCALE 16384
-
-extern short grub_trig_sintab[];
-extern short grub_trig_costab[];
-
-static __inline int
-grub_sin (int x)
-{
-  x &= GRUB_TRIG_ANGLE_MASK;
-  return grub_trig_sintab[x];
-}
-
-static __inline int
-grub_cos (int x)
-{
-  x &= GRUB_TRIG_ANGLE_MASK;
-  return grub_trig_costab[x];
-}
-
-#endif /* ! GRUB_TRIG_HEADER */
diff --git a/include/grub/types.h b/include/grub/types.h
deleted file mode 100644 (file)
index 9eaafd0..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_TYPES_HEADER
-#define GRUB_TYPES_HEADER      1
-
-#include <config.h>
-#include <grub/cpu/types.h>
-
-#ifdef GRUB_UTIL
-# define GRUB_CPU_SIZEOF_VOID_P        SIZEOF_VOID_P
-# define GRUB_CPU_SIZEOF_LONG  SIZEOF_LONG
-# ifdef WORDS_BIGENDIAN
-#  define GRUB_CPU_WORDS_BIGENDIAN     1
-# else
-#  undef GRUB_CPU_WORDS_BIGENDIAN
-# endif
-#else /* ! GRUB_UTIL */
-# define GRUB_CPU_SIZEOF_VOID_P        GRUB_TARGET_SIZEOF_VOID_P
-# define GRUB_CPU_SIZEOF_LONG  GRUB_TARGET_SIZEOF_LONG
-# ifdef GRUB_TARGET_WORDS_BIGENDIAN
-#  define GRUB_CPU_WORDS_BIGENDIAN     1
-# else
-#  undef GRUB_CPU_WORDS_BIGENDIAN
-# endif
-#endif /* ! GRUB_UTIL */
-
-#if GRUB_CPU_SIZEOF_VOID_P != GRUB_CPU_SIZEOF_LONG
-# error "This architecture is not supported because sizeof(void *) != sizeof(long)"
-#endif
-
-#if GRUB_CPU_SIZEOF_VOID_P != 4 && GRUB_CPU_SIZEOF_VOID_P != 8
-# error "This architecture is not supported because sizeof(void *) != 4 and sizeof(void *) != 8"
-#endif
-
-#ifndef GRUB_TARGET_WORDSIZE
-# if GRUB_TARGET_SIZEOF_VOID_P == 4
-#  define GRUB_TARGET_WORDSIZE 32
-# elif GRUB_TARGET_SIZEOF_VOID_P == 8
-#  define GRUB_TARGET_WORDSIZE 64
-# endif
-#endif
-
-/* Define various wide integers.  */
-typedef signed char            grub_int8_t;
-typedef short                  grub_int16_t;
-typedef int                    grub_int32_t;
-#if GRUB_CPU_SIZEOF_VOID_P == 8
-typedef long                   grub_int64_t;
-#else
-typedef long long              grub_int64_t;
-#endif
-
-typedef unsigned char          grub_uint8_t;
-typedef unsigned short         grub_uint16_t;
-typedef unsigned               grub_uint32_t;
-#if GRUB_CPU_SIZEOF_VOID_P == 8
-typedef unsigned long          grub_uint64_t;
-#else
-typedef unsigned long long     grub_uint64_t;
-#endif
-
-/* Misc types.  */
-#if GRUB_TARGET_SIZEOF_VOID_P == 8
-typedef grub_uint64_t  grub_target_addr_t;
-typedef grub_uint64_t  grub_target_off_t;
-typedef grub_uint64_t  grub_target_size_t;
-typedef grub_int64_t   grub_target_ssize_t;
-#else
-typedef grub_uint32_t  grub_target_addr_t;
-typedef grub_uint32_t  grub_target_off_t;
-typedef grub_uint32_t  grub_target_size_t;
-typedef grub_int32_t   grub_target_ssize_t;
-#endif
-
-#if GRUB_CPU_SIZEOF_VOID_P == 8
-typedef grub_uint64_t  grub_addr_t;
-typedef grub_uint64_t  grub_size_t;
-typedef grub_int64_t   grub_ssize_t;
-#else
-typedef grub_uint32_t  grub_addr_t;
-typedef grub_uint32_t  grub_size_t;
-typedef grub_int32_t   grub_ssize_t;
-#endif
-
-#if GRUB_CPU_SIZEOF_VOID_P == 8
-# define GRUB_ULONG_MAX 18446744073709551615UL
-# define GRUB_LONG_MAX 9223372036854775807L
-# define GRUB_LONG_MIN (-9223372036854775807L - 1)
-#else
-# define GRUB_ULONG_MAX 4294967295UL
-# define GRUB_LONG_MAX 2147483647L
-# define GRUB_LONG_MIN (-2147483647L - 1)
-#endif
-
-#if GRUB_CPU_SIZEOF_VOID_P == 4
-#define UINT_TO_PTR(x) ((void*)(grub_uint32_t)(x))
-#define PTR_TO_UINT64(x) ((grub_uint64_t)(grub_uint32_t)(x))
-#define PTR_TO_UINT32(x) ((grub_uint32_t)(x))
-#else
-#define UINT_TO_PTR(x) ((void*)(grub_uint64_t)(x))
-#define PTR_TO_UINT64(x) ((grub_uint64_t)(x))
-#define PTR_TO_UINT32(x) ((grub_uint32_t)(grub_uint64_t)(x))
-#endif
-
-/* The type for representing a file offset.  */
-typedef grub_uint64_t  grub_off_t;
-
-/* The type for representing a disk block address.  */
-typedef grub_uint64_t  grub_disk_addr_t;
-
-/* Byte-orders.  */
-#define grub_swap_bytes16(x)   \
-({ \
-   grub_uint16_t _x = (x); \
-   (grub_uint16_t) ((_x << 8) | (_x >> 8)); \
-})
-
-#if defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)
-static inline grub_uint32_t grub_swap_bytes32(grub_uint32_t x)
-{
-       return __builtin_bswap32(x);
-}
-
-static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x)
-{
-       return __builtin_bswap64(x);
-}
-#else                                  /* not gcc 4.3 or newer */
-#define grub_swap_bytes32(x)   \
-({ \
-   grub_uint32_t _x = (x); \
-   (grub_uint32_t) ((_x << 24) \
-                    | ((_x & (grub_uint32_t) 0xFF00UL) << 8) \
-                    | ((_x & (grub_uint32_t) 0xFF0000UL) >> 8) \
-                    | (_x >> 24)); \
-})
-
-#define grub_swap_bytes64(x)   \
-({ \
-   grub_uint64_t _x = (x); \
-   (grub_uint64_t) ((_x << 56) \
-                    | ((_x & (grub_uint64_t) 0xFF00ULL) << 40) \
-                    | ((_x & (grub_uint64_t) 0xFF0000ULL) << 24) \
-                    | ((_x & (grub_uint64_t) 0xFF000000ULL) << 8) \
-                    | ((_x & (grub_uint64_t) 0xFF00000000ULL) >> 8) \
-                    | ((_x & (grub_uint64_t) 0xFF0000000000ULL) >> 24) \
-                    | ((_x & (grub_uint64_t) 0xFF000000000000ULL) >> 40) \
-                    | (_x >> 56)); \
-})
-#endif                                 /* not gcc 4.3 or newer */
-
-#ifdef GRUB_CPU_WORDS_BIGENDIAN
-# define grub_cpu_to_le16(x)   grub_swap_bytes16(x)
-# define grub_cpu_to_le32(x)   grub_swap_bytes32(x)
-# define grub_cpu_to_le64(x)   grub_swap_bytes64(x)
-# define grub_le_to_cpu16(x)   grub_swap_bytes16(x)
-# define grub_le_to_cpu32(x)   grub_swap_bytes32(x)
-# define grub_le_to_cpu64(x)   grub_swap_bytes64(x)
-# define grub_cpu_to_be16(x)   ((grub_uint16_t) (x))
-# define grub_cpu_to_be32(x)   ((grub_uint32_t) (x))
-# define grub_cpu_to_be64(x)   ((grub_uint64_t) (x))
-# define grub_be_to_cpu16(x)   ((grub_uint16_t) (x))
-# define grub_be_to_cpu32(x)   ((grub_uint32_t) (x))
-# define grub_be_to_cpu64(x)   ((grub_uint64_t) (x))
-# ifdef GRUB_TARGET_WORDS_BIGENDIAN
-#  define grub_target_to_host16(x)     ((grub_uint16_t) (x))
-#  define grub_target_to_host32(x)     ((grub_uint32_t) (x))
-#  define grub_target_to_host64(x)     ((grub_uint64_t) (x))
-#  define grub_host_to_target16(x)     ((grub_uint16_t) (x))
-#  define grub_host_to_target32(x)     ((grub_uint32_t) (x))
-#  define grub_host_to_target64(x)     ((grub_uint64_t) (x))
-# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */
-#  define grub_target_to_host16(x)     grub_swap_bytes16(x)
-#  define grub_target_to_host32(x)     grub_swap_bytes32(x)
-#  define grub_target_to_host64(x)     grub_swap_bytes64(x)
-#  define grub_host_to_target16(x)     grub_swap_bytes16(x)
-#  define grub_host_to_target32(x)     grub_swap_bytes32(x)
-#  define grub_host_to_target64(x)     grub_swap_bytes64(x)
-# endif
-#else /* ! WORDS_BIGENDIAN */
-# define grub_cpu_to_le16(x)   ((grub_uint16_t) (x))
-# define grub_cpu_to_le32(x)   ((grub_uint32_t) (x))
-# define grub_cpu_to_le64(x)   ((grub_uint64_t) (x))
-# define grub_le_to_cpu16(x)   ((grub_uint16_t) (x))
-# define grub_le_to_cpu32(x)   ((grub_uint32_t) (x))
-# define grub_le_to_cpu64(x)   ((grub_uint64_t) (x))
-# define grub_cpu_to_be16(x)   grub_swap_bytes16(x)
-# define grub_cpu_to_be32(x)   grub_swap_bytes32(x)
-# define grub_cpu_to_be64(x)   grub_swap_bytes64(x)
-# define grub_be_to_cpu16(x)   grub_swap_bytes16(x)
-# define grub_be_to_cpu32(x)   grub_swap_bytes32(x)
-# define grub_be_to_cpu64(x)   grub_swap_bytes64(x)
-# ifdef GRUB_TARGET_WORDS_BIGENDIAN
-#  define grub_target_to_host16(x)     grub_swap_bytes16(x)
-#  define grub_target_to_host32(x)     grub_swap_bytes32(x)
-#  define grub_target_to_host64(x)     grub_swap_bytes64(x)
-#  define grub_host_to_target16(x)     grub_swap_bytes16(x)
-#  define grub_host_to_target32(x)     grub_swap_bytes32(x)
-#  define grub_host_to_target64(x)     grub_swap_bytes64(x)
-# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */
-#  define grub_target_to_host16(x)     ((grub_uint16_t) (x))
-#  define grub_target_to_host32(x)     ((grub_uint32_t) (x))
-#  define grub_target_to_host64(x)     ((grub_uint64_t) (x))
-#  define grub_host_to_target16(x)     ((grub_uint16_t) (x))
-#  define grub_host_to_target32(x)     ((grub_uint32_t) (x))
-#  define grub_host_to_target64(x)     ((grub_uint64_t) (x))
-# endif
-#endif /* ! WORDS_BIGENDIAN */
-
-#if GRUB_TARGET_SIZEOF_VOID_P == 8
-#  define grub_host_to_target_addr(x) grub_host_to_target64(x)
-#else
-#  define grub_host_to_target_addr(x) grub_host_to_target32(x)
-#endif
-
-#endif /* ! GRUB_TYPES_HEADER */
diff --git a/include/grub/usb.h b/include/grub/usb.h
deleted file mode 100644 (file)
index dc90e78..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef        GRUB_USB_H
-#define        GRUB_USB_H      1
-
-#include <grub/usbdesc.h>
-#include <grub/usbtrans.h>
-
-typedef struct grub_usb_device *grub_usb_device_t;
-typedef struct grub_usb_controller *grub_usb_controller_t;
-typedef struct grub_usb_controller_dev *grub_usb_controller_dev_t;
-
-typedef enum
-  {
-    GRUB_USB_ERR_NONE,
-    GRUB_USB_ERR_INTERNAL,
-    GRUB_USB_ERR_STALL,
-    GRUB_USB_ERR_DATA,
-    GRUB_USB_ERR_NAK,
-    GRUB_USB_ERR_BABBLE,
-    GRUB_USB_ERR_TIMEOUT,
-    GRUB_USB_ERR_BITSTUFF
-  } grub_usb_err_t;
-
-typedef enum
-  {
-    GRUB_USB_SPEED_NONE,
-    GRUB_USB_SPEED_LOW,
-    GRUB_USB_SPEED_FULL,
-    GRUB_USB_SPEED_HIGH
-  } grub_usb_speed_t;
-
-/* Call HOOK with each device, until HOOK returns non-zero.  */
-int grub_usb_iterate (int (*hook) (grub_usb_device_t dev));
-
-grub_usb_err_t grub_usb_device_initialize (grub_usb_device_t dev);
-
-grub_usb_err_t grub_usb_get_descriptor (grub_usb_device_t dev,
-                                       grub_uint8_t type, grub_uint8_t index,
-                                       grub_size_t size, char *data);
-
-struct grub_usb_desc_endp *
-grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr);
-
-grub_usb_err_t grub_usb_clear_halt (grub_usb_device_t dev, int endpoint);
-
-
-grub_usb_err_t grub_usb_set_configuration (grub_usb_device_t dev,
-                                          int configuration);
-
-void grub_usb_controller_dev_register (grub_usb_controller_dev_t usb);
-
-void grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb);
-
-int grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev));
-
-
-grub_usb_err_t grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype,
-                                    grub_uint8_t request, grub_uint16_t value,
-                                    grub_uint16_t index, grub_size_t size,
-                                    char *data);
-
-grub_usb_err_t
-grub_usb_bulk_read (grub_usb_device_t dev,
-                   int endpoint, grub_size_t size, char *data);
-grub_usb_err_t
-grub_usb_bulk_write (grub_usb_device_t dev,
-                    int endpoint, grub_size_t size, char *data);
-
-grub_usb_err_t
-grub_usb_root_hub (grub_usb_controller_t controller);
-
-\f
-/* XXX: All handled by libusb for now.  */
-struct grub_usb_controller_dev
-{
-  /* The device name.  */
-  const char *name;
-
-  int (*iterate) (int (*hook) (grub_usb_controller_t dev));
-
-  grub_usb_err_t (*transfer) (grub_usb_controller_t dev,
-                             grub_usb_transfer_t transfer);
-
-  int (*hubports) (grub_usb_controller_t dev);
-
-  grub_err_t (*portstatus) (grub_usb_controller_t dev, unsigned int port,
-                           unsigned int enable);
-
-  grub_usb_speed_t (*detect_dev) (grub_usb_controller_t dev, int port);
-
-  /* The next host controller.  */
-  struct grub_usb_controller_dev *next;
-};
-
-struct grub_usb_controller
-{
-  /* The underlying USB Host Controller device.  */
-  grub_usb_controller_dev_t dev;
-
-  /* Data used by the USB Host Controller Driver.  */
-  void *data;
-};
-\f
-
-struct grub_usb_interface
-{
-  struct grub_usb_desc_if *descif;
-
-  struct grub_usb_desc_endp *descendp;
-};
-
-struct grub_usb_configuration
-{
-  /* Configuration descriptors .  */
-  struct grub_usb_desc_config *descconf;
-
-  /* Interfaces associated to this configuration.  */
-  struct grub_usb_interface interf[32];
-};
-
-struct grub_usb_device
-{
-  /* The device descriptor of this device.  */
-  struct grub_usb_desc_device descdev;
-
-  /* The controller the device is connected to.  */
-  struct grub_usb_controller controller;
-
-  /* Device configurations (after opening the device).  */
-  struct grub_usb_configuration config[8];
-
-  /* Device address.  */
-  int addr;
-
-  /* Device speed.  */
-  grub_usb_speed_t speed;
-
-  /* All descriptors are read if this is set to 1.  */
-  int initialized;
-
-  /* Data toggle values (used for bulk transfers only).  */
-  int toggle[16];
-
-  /* Device-specific data.  */
-  void *data;
-};
-
-\f
-
-typedef enum
-  {
-    GRUB_USB_CLASS_NOTHERE,
-    GRUB_USB_CLASS_AUDIO,
-    GRUB_USB_CLASS_COMMUNICATION,
-    GRUB_USB_CLASS_HID,
-    GRUB_USB_CLASS_XXX,
-    GRUB_USB_CLASS_PHYSICAL,
-    GRUB_USB_CLASS_IMAGE,
-    GRUB_USB_CLASS_PRINTER,
-    GRUB_USB_CLASS_MASS_STORAGE,
-    GRUB_USB_CLASS_HUB,
-    GRUB_USB_CLASS_DATA_INTERFACE,
-    GRUB_USB_CLASS_SMART_CARD,
-    GRUB_USB_CLASS_CONTENT_SECURITY,
-    GRUB_USB_CLASS_VIDEO
-  } grub_usb_classes_t;
-
-typedef enum
-  {
-    GRUB_USBMS_SUBCLASS_BULK = 0x06
-  } grub_usbms_subclass_t;
-
-typedef enum
-  {
-    GRUB_USBMS_PROTOCOL_BULK = 0x50
-  } grub_usbms_protocol_t;
-
-static inline struct grub_usb_desc_if *
-grub_usb_get_config_interface (struct grub_usb_desc_config *config)
-{
-  struct grub_usb_desc_if *interf;
-
-  interf = (struct grub_usb_desc_if *) (sizeof (*config) + (char *) config);
-  return interf;
-}
-
-#endif /* GRUB_USB_H */
diff --git a/include/grub/usbdesc.h b/include/grub/usbdesc.h
deleted file mode 100644 (file)
index 2f711d7..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef        GRUB_USBDESC_H
-#define        GRUB_USBDESC_H  1
-
-#include <grub/types.h>
-#include <grub/symbol.h>
-
-typedef enum {
-  GRUB_USB_DESCRIPTOR_DEVICE = 1,
-  GRUB_USB_DESCRIPTOR_CONFIG,
-  GRUB_USB_DESCRIPTOR_STRING,
-  GRUB_USB_DESCRIPTOR_INTERFACE,
-  GRUB_USB_DESCRIPTOR_ENDPOINT,
-  GRUB_USB_DESCRIPTOR_HUB = 0x29
-} grub_usb_descriptor_t;
-
-struct grub_usb_desc_device
-{
-  grub_uint8_t length;
-  grub_uint8_t type;
-  grub_uint16_t usbrel;
-  grub_uint8_t class;
-  grub_uint8_t subclass;
-  grub_uint8_t protocol;
-  grub_uint8_t maxsize0;
-  grub_uint16_t vendorid;
-  grub_uint16_t prodid;
-  grub_uint16_t devrel;
-  grub_uint8_t strvendor;
-  grub_uint8_t strprod;
-  grub_uint8_t strserial;
-  grub_uint8_t configcnt;
-} __attribute__ ((packed));
-
-struct grub_usb_desc_config
-{
-  grub_uint8_t length;
-  grub_uint8_t type;
-  grub_uint16_t totallen;
-  grub_uint8_t numif;
-  grub_uint8_t config;
-  grub_uint8_t strconfig;
-  grub_uint8_t attrib;
-  grub_uint8_t maxpower;
-} __attribute__ ((packed));
-
-#if 0
-struct grub_usb_desc_if_association
-{
-  grub_uint8_t length;
-  grub_uint8_t type;
-  grub_uint8_t firstif;
-  grub_uint8_t ifcnt;
-  grub_uint8_t class;
-  grub_uint8_t subclass;
-  grub_uint8_t protocol;
-  grub_uint8_t function;
-} __attribute__ ((packed));
-#endif
-
-struct grub_usb_desc_if
-{
-  grub_uint8_t length;
-  grub_uint8_t type;
-  grub_uint8_t ifnum;
-  grub_uint8_t altsetting;
-  grub_uint8_t endpointcnt;
-  grub_uint8_t class;
-  grub_uint8_t subclass;
-  grub_uint8_t protocol;
-  grub_uint8_t strif;
-} __attribute__ ((packed));
-
-struct grub_usb_desc_endp
-{
-  grub_uint8_t length;
-  grub_uint8_t type;
-  grub_uint8_t endp_addr;
-  grub_uint8_t attrib;
-  grub_uint16_t maxpacket;
-  grub_uint8_t interval;
-} __attribute__ ((packed));
-
-struct grub_usb_desc_str
-{
-  grub_uint8_t length;
-  grub_uint8_t type;
-  grub_uint16_t str[0];
-} __attribute__ ((packed));
-
-struct grub_usb_usb_hubdesc
-{
-  grub_uint8_t length;
-  grub_uint8_t type;
-  grub_uint8_t portcnt;
-  grub_uint16_t characteristics;
-  grub_uint8_t pwdgood;
-  grub_uint8_t current;
-  /* Removable and power control bits follow.  */
-} __attribute__ ((packed));
-
-#endif /* GRUB_USBDESC_H */
diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h
deleted file mode 100644 (file)
index 7e4a9d7..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef        GRUB_USBTRANS_H
-#define        GRUB_USBTRANS_H 1
-
-typedef enum
-  {
-    GRUB_USB_TRANSFER_TYPE_IN,
-    GRUB_USB_TRANSFER_TYPE_OUT,
-    GRUB_USB_TRANSFER_TYPE_SETUP
-  } grub_transfer_type_t;
-
-typedef enum
-  {
-    GRUB_USB_TRANSACTION_TYPE_CONTROL,
-    GRUB_USB_TRANSACTION_TYPE_BULK
-  } grub_transaction_type_t;
-
-struct grub_usb_transaction
-{
-  int size;
-  int toggle;
-  grub_transfer_type_t pid;
-  char *data;
-};
-typedef struct grub_usb_transaction *grub_usb_transaction_t;
-
-struct grub_usb_transfer
-{
-  int devaddr;
-
-  int endpoint;
-
-  int size;
-
-  int transcnt;
-
-  int max;
-
-  grub_transaction_type_t type;
-
-  struct grub_usb_device *dev;
-
-  struct grub_usb_transaction *transactions;
-};
-typedef struct grub_usb_transfer *grub_usb_transfer_t;
-
-\f
-#define GRUB_USB_REQTYPE_IN            (1 << 7)
-#define GRUB_USB_REQTYPE_OUT           (0 << 7)
-#define GRUB_USB_REQTYPE_STANDARD      (0 << 5)
-#define GRUB_USB_REQTYPE_CLASS         (1 << 5)
-#define GRUB_USB_REQTYPE_VENDOR                (2 << 5)
-#define GRUB_USB_REQTYPE_TARGET_DEV    (0 << 0)
-#define GRUB_USB_REQTYPE_TARGET_INTERF (1 << 0)
-#define GRUB_USB_REQTYPE_TARGET_ENDP   (2 << 0)
-#define GRUB_USB_REQTYPE_TARGET_OTHER  (3 << 0)
-
-#define GRUB_USB_REQ_GET_STATUS                0x00
-#define GRUB_USB_REQ_CLEAR_FEATURE     0x01
-#define GRUB_USB_REQ_SET_FEATURE       0x03
-#define GRUB_USB_REQ_SET_ADDRESS       0x05
-#define GRUB_USB_REQ_GET_DESCRIPTOR    0x06
-#define GRUB_USB_REQ_SET_DESCRIPTOR    0x07
-#define GRUB_USB_REQ_GET_CONFIGURATION 0x08
-#define GRUB_USB_REQ_SET_CONFIGURATION 0x09
-#define GRUB_USB_REQ_GET_INTERFACE     0x0A
-#define GRUB_USB_REQ_SET_INTERFACE     0x0B
-#define GRUB_USB_REQ_SYNC_FRAME                0x0C
-
-#define GRUB_USB_REQ_HUB_GET_PORT_STATUS 0x00
-
-#define GRUB_USB_FEATURE_ENDP_HALT     0x01
-#define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x02
-#define GRUB_USB_FEATURE_TEST_MODE     0x04
-
-#define GRUB_USB_HUB_STATUS_CONNECTED  (1 << 0)
-#define GRUB_USB_HUB_STATUS_LOWSPEED   (1 << 9)
-#define GRUB_USB_HUB_STATUS_HIGHSPEED  (1 << 10)
-
-struct grub_usb_packet_setup
-{
-  grub_uint8_t reqtype;
-  grub_uint8_t request;
-  grub_uint16_t value;
-  grub_uint16_t index;
-  grub_uint16_t length;
-} __attribute__((packed));
-
-
-#endif /* GRUB_USBTRANS_H */
diff --git a/include/grub/util/console.h b/include/grub/util/console.h
deleted file mode 100644 (file)
index 1e55682..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_CONSOLE_UTIL_HEADER
-#define GRUB_CONSOLE_UTIL_HEADER       1
-
-/* Initialize the console system.  */
-void grub_console_init (void);
-
-/* Finish the console system.  */
-void grub_console_fini (void);
-
-#endif /* ! GRUB_CONSOLE_UTIL_HEADER */
diff --git a/include/grub/util/deviceiter.h b/include/grub/util/deviceiter.h
deleted file mode 100644 (file)
index a8af03c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef GRUB_DEVICEITER_MACHINE_UTIL_HEADER
-#define GRUB_DEVICEITER_MACHINE_UTIL_HEADER    1
-
-#include <config.h>
-
-void grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
-                               int floppy_disks);
-void grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy,
-                                    int *num_fd, int *num_hd);
-
-#endif /* ! GRUB_DEVICEITER_MACHINE_UTIL_HEADER */
diff --git a/include/grub/util/getroot.h b/include/grub/util/getroot.h
deleted file mode 100644 (file)
index dff7b4d..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003, 2007, 2008, 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_UTIL_GETROOT_HEADER
-#define GRUB_UTIL_GETROOT_HEADER       1
-
-enum grub_dev_abstraction_types {
-  GRUB_DEV_ABSTRACTION_NONE,
-  GRUB_DEV_ABSTRACTION_LVM,
-  GRUB_DEV_ABSTRACTION_RAID,
-};
-
-char *grub_guess_root_device (const char *dir);
-int grub_util_get_dev_abstraction (const char *os_dev);
-char *grub_util_get_grub_dev (const char *os_dev);
-const char *grub_util_check_block_device (const char *blk_dev);
-const char *grub_util_check_char_device (const char *blk_dev);
-
-#endif /* ! GRUB_UTIL_GETROOT_HEADER */
diff --git a/include/grub/util/hostdisk.h b/include/grub/util/hostdisk.h
deleted file mode 100644 (file)
index 246046e..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* biosdisk.h - emulate biosdisk */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_BIOSDISK_MACHINE_UTIL_HEADER
-#define GRUB_BIOSDISK_MACHINE_UTIL_HEADER      1
-
-#include <grub/disk.h>
-
-void grub_util_biosdisk_init (const char *dev_map);
-void grub_util_biosdisk_fini (void);
-char *grub_util_biosdisk_get_grub_dev (const char *os_dev);
-const char *grub_util_biosdisk_get_osdev (grub_disk_t disk);
-
-#endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */
diff --git a/include/grub/util/lvm.h b/include/grub/util/lvm.h
deleted file mode 100644 (file)
index 7a4c76c..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* lvm.h - LVM support for GRUB utils.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_LVM_UTIL_HEADER
-#define GRUB_LVM_UTIL_HEADER   1
-
-#ifdef __linux__
-int grub_util_lvm_isvolume (char *name);
-#endif
-
-#endif /* ! GRUB_RAID_UTIL_HEADER */
diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h
deleted file mode 100644 (file)
index 8b78b92..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_UTIL_MISC_HEADER
-#define GRUB_UTIL_MISC_HEADER  1
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <setjmp.h>
-#include <unistd.h>
-
-#include <config.h>
-#include <grub/types.h>
-#include <grub/symbol.h>
-
-#ifdef __NetBSD__
-/* NetBSD uses /boot for its boot block.  */
-# define DEFAULT_DIRECTORY     "/grub"
-#else
-# define DEFAULT_DIRECTORY     "/boot/grub"
-#endif
-
-#define DEFAULT_DEVICE_MAP     DEFAULT_DIRECTORY "/device.map"
-
-extern char *progname;
-extern int verbosity;
-
-void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...);
-void EXPORT_FUNC(grub_util_info) (const char *fmt, ...);
-void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((noreturn));
-
-void *xmalloc (size_t size);
-void *xrealloc (void *ptr, size_t size);
-char *xstrdup (const char *str);
-
-char *grub_util_get_path (const char *dir, const char *file);
-size_t grub_util_get_fp_size (FILE *fp);
-size_t grub_util_get_image_size (const char *path);
-void grub_util_read_at (void *img, size_t len, off_t offset, FILE *fp);
-char *grub_util_read_image (const char *path);
-void grub_util_load_image (const char *path, char *buf);
-void grub_util_write_image (const char *img, size_t size, FILE *out);
-void grub_util_write_image_at (const void *img, size_t size, off_t offset,
-                              FILE *out);
-
-#ifndef HAVE_VASPRINTF
-
-int vasprintf (char **buf, const char *fmt, va_list ap);
-
-#endif
-
-#ifndef  HAVE_ASPRINTF
-
-int asprintf (char **buf, const char *fmt, ...);
-
-#endif
-
-char *xasprintf (const char *fmt, ...);
-
-#ifdef __MINGW32__
-
-#define fseeko fseeko64
-#define ftello ftello64
-
-void sync (void);
-int fsync (int fno);
-void sleep(int s);
-
-grub_int64_t grub_util_get_disk_size (char *name);
-
-#endif
-
-
-char *make_system_path_relative_to_its_root (const char *path);
-
-char *canonicalize_file_name (const char *path);
-
-void grub_util_init_nls (void);
-
-#endif /* ! GRUB_UTIL_MISC_HEADER */
diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h
deleted file mode 100644 (file)
index b43c523..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef GRUB_OFPATH_MACHINE_UTIL_HEADER
-#define GRUB_OFPATH_MACHINE_UTIL_HEADER        1
-
-char *grub_util_devname_to_ofpath (const char *devname);
-
-#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
diff --git a/include/grub/util/raid.h b/include/grub/util/raid.h
deleted file mode 100644 (file)
index 67020bb..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* raid.h - RAID support for GRUB utils.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_RAID_UTIL_HEADER
-#define GRUB_RAID_UTIL_HEADER  1
-
-#ifdef __linux__
-char** grub_util_raid_getmembers (char *name);
-#endif
-
-#endif /* ! GRUB_RAID_UTIL_HEADER */
diff --git a/include/grub/util/resolve.h b/include/grub/util/resolve.h
deleted file mode 100644 (file)
index f42df32..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_UTIL_RESOLVE_HEADER
-#define GRUB_UTIL_RESOLVE_HEADER       1
-
-struct grub_util_path_list
-{
-  const char *name;
-  struct grub_util_path_list *next;
-};
-
-/* Resolve the dependencies of the modules MODULES using the information
-   in the file DEP_LIST_FILE. The directory PREFIX is used to find files.  */
-struct grub_util_path_list *
-grub_util_resolve_dependencies (const char *prefix,
-                               const char *dep_list_file,
-                               char *modules[]);
-
-#endif /* ! GRUB_UTIL_RESOLVE_HEADER */
diff --git a/include/grub/video.h b/include/grub/video.h
deleted file mode 100644 (file)
index 782a528..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_VIDEO_HEADER
-#define GRUB_VIDEO_HEADER      1
-
-#include <grub/err.h>
-#include <grub/types.h>
-
-/* Video color in hardware dependent format.  Users should not assume any
-   specific coding format.  */
-typedef grub_uint32_t grub_video_color_t;
-
-/* This structure is driver specific and should not be accessed directly by
-   outside code.  */
-struct grub_video_render_target;
-
-/* Forward declarations for used data structures.  */
-struct grub_video_bitmap;
-
-/* Defines used to describe video mode or rendering target.  */
-/* If following is set render target contains currenly displayed image
-   after swapping buffers (otherwise it contains previously displayed image).
- */
-#define GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP     0x00000080
-#define GRUB_VIDEO_MODE_TYPE_PURE_TEXT         0x00000040
-#define GRUB_VIDEO_MODE_TYPE_ALPHA             0x00000020
-#define GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED   0x00000010
-#define GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP       0x00000004
-#define GRUB_VIDEO_MODE_TYPE_INDEX_COLOR       0x00000002
-#define GRUB_VIDEO_MODE_TYPE_RGB               0x00000001
-
-/* Defines used to mask flags.  */
-#define GRUB_VIDEO_MODE_TYPE_COLOR_MASK                0x0000000F
-
-/* Defines used to specify requested bit depth.  */
-#define GRUB_VIDEO_MODE_TYPE_DEPTH_MASK                0x0000ff00
-#define GRUB_VIDEO_MODE_TYPE_DEPTH_POS         8
-
-/* The basic render target representing the whole display.  This always
-   renders to the back buffer when double-buffering is in use.  */
-#define GRUB_VIDEO_RENDER_TARGET_DISPLAY \
-  ((struct grub_video_render_target *) 0)
-
-/* Defined blitting formats.  */
-enum grub_video_blit_format
-  {
-    /* Generic RGBA, use fields & masks.  */
-    GRUB_VIDEO_BLIT_FORMAT_RGBA,
-
-    /* Optimized RGBA's.  */
-    GRUB_VIDEO_BLIT_FORMAT_RGBA_8888,
-    GRUB_VIDEO_BLIT_FORMAT_BGRA_8888,
-
-    /* Generic RGB, use fields & masks.  */
-    GRUB_VIDEO_BLIT_FORMAT_RGB,
-
-    /* Optimized RGB's.  */
-    GRUB_VIDEO_BLIT_FORMAT_RGB_888,
-    GRUB_VIDEO_BLIT_FORMAT_BGR_888,
-    GRUB_VIDEO_BLIT_FORMAT_RGB_565,
-    GRUB_VIDEO_BLIT_FORMAT_BGR_565,
-
-    /* When needed, decode color or just use value as is.  */
-    GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR,
-
-    /* Two color bitmap; bits packed: rows are not padded to byte boundary.  */
-    GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED
-  };
-
-/* Define blitting operators.  */
-enum grub_video_blit_operators
-  {
-    /* Replace target bitmap data with source.  */
-    GRUB_VIDEO_BLIT_REPLACE,
-    /* Blend target and source based on source's alpha value.  */
-    GRUB_VIDEO_BLIT_BLEND
-  };
-
-struct grub_video_mode_info
-{
-  /* Width of the screen.  */
-  unsigned int width;
-
-  /* Height of the screen.  */
-  unsigned int height;
-
-  /* Mode type bitmask.  Contains information like is it Index color or
-     RGB mode.  */
-  unsigned int mode_type;
-
-  /* Bits per pixel.  */
-  unsigned int bpp;
-
-  /* Bytes per pixel.  */
-  unsigned int bytes_per_pixel;
-
-  /* Pitch of one scanline.  How many bytes there are for scanline.  */
-  unsigned int pitch;
-
-  /* In index color mode, number of colors.  In RGB mode this is 256.  */
-  unsigned int number_of_colors;
-
-  /* Optimization hint how binary data is coded.  */
-  enum grub_video_blit_format blit_format;
-
-  /* How many bits are reserved for red color.  */
-  unsigned int red_mask_size;
-
-  /* What is location of red color bits.  In Index Color mode, this is 0.  */
-  unsigned int red_field_pos;
-
-  /* How many bits are reserved for green color.  */
-  unsigned int green_mask_size;
-
-  /* What is location of green color bits.  In Index Color mode, this is 0.  */
-  unsigned int green_field_pos;
-
-  /* How many bits are reserved for blue color.  */
-  unsigned int blue_mask_size;
-
-  /* What is location of blue color bits.  In Index Color mode, this is 0.  */
-  unsigned int blue_field_pos;
-
-  /* How many bits are reserved in color.  */
-  unsigned int reserved_mask_size;
-
-  /* What is location of reserved color bits.  In Index Color mode,
-     this is 0.  */
-  unsigned int reserved_field_pos;
-
-  /* For 1-bit bitmaps, the background color.  Used for bits = 0.  */
-  grub_uint8_t bg_red;
-  grub_uint8_t bg_green;
-  grub_uint8_t bg_blue;
-  grub_uint8_t bg_alpha;
-
-  /* For 1-bit bitmaps, the foreground color.  Used for bits = 1.  */
-  grub_uint8_t fg_red;
-  grub_uint8_t fg_green;
-  grub_uint8_t fg_blue;
-  grub_uint8_t fg_alpha;
-};
-
-/* A 2D rectangle type.  */
-struct grub_video_rect
-{
-  unsigned x;
-  unsigned y;
-  unsigned width;
-  unsigned height;
-};
-typedef struct grub_video_rect grub_video_rect_t;
-
-struct grub_video_palette_data
-{
-  grub_uint8_t r; /* Red color value (0-255).  */
-  grub_uint8_t g; /* Green color value (0-255).  */
-  grub_uint8_t b; /* Blue color value (0-255).  */
-  grub_uint8_t a; /* Reserved bits value (0-255).  */
-};
-
-typedef enum grub_video_driver_id
-  {
-    GRUB_VIDEO_DRIVER_NONE,
-    GRUB_VIDEO_DRIVER_VBE,
-    GRUB_VIDEO_DRIVER_EFI_UGA,
-    GRUB_VIDEO_DRIVER_EFI_GOP,
-    GRUB_VIDEO_DRIVER_SM712
-  } grub_video_driver_id_t;
-
-struct grub_video_adapter
-{
-  /* The video adapter name.  */
-  const char *name;
-  grub_video_driver_id_t id;
-
-  /* Initialize the video adapter.  */
-  grub_err_t (*init) (void);
-
-  /* Clean up the video adapter.  */
-  grub_err_t (*fini) (void);
-
-  grub_err_t (*setup) (unsigned int width,  unsigned int height,
-                       unsigned int mode_type, unsigned int mode_mask);
-
-  grub_err_t (*get_info) (struct grub_video_mode_info *mode_info);
-
-  grub_err_t (*get_info_and_fini) (struct grub_video_mode_info *mode_info,
-                                  void **framebuffer);
-
-  grub_err_t (*set_palette) (unsigned int start, unsigned int count,
-                             struct grub_video_palette_data *palette_data);
-
-  grub_err_t (*get_palette) (unsigned int start, unsigned int count,
-                             struct grub_video_palette_data *palette_data);
-
-  grub_err_t (*set_viewport) (unsigned int x, unsigned int y,
-                              unsigned int width, unsigned int height);
-
-  grub_err_t (*get_viewport) (unsigned int *x, unsigned int *y,
-                              unsigned int *width, unsigned int *height);
-
-  grub_video_color_t (*map_color) (grub_uint32_t color_name);
-
-  grub_video_color_t (*map_rgb) (grub_uint8_t red, grub_uint8_t green,
-                                 grub_uint8_t blue);
-
-  grub_video_color_t (*map_rgba) (grub_uint8_t red, grub_uint8_t green,
-                                  grub_uint8_t blue, grub_uint8_t alpha);
-
-  grub_err_t (*unmap_color) (grub_video_color_t color,
-                             grub_uint8_t *red, grub_uint8_t *green,
-                             grub_uint8_t *blue, grub_uint8_t *alpha);
-
-  grub_err_t (*fill_rect) (grub_video_color_t color, int x, int y,
-                           unsigned int width, unsigned int height);
-
-  grub_err_t (*blit_bitmap) (struct grub_video_bitmap *bitmap,
-                             enum grub_video_blit_operators oper,
-                             int x, int y, int offset_x, int offset_y,
-                             unsigned int width, unsigned int height);
-
-  grub_err_t (*blit_render_target) (struct grub_video_render_target *source,
-                                    enum grub_video_blit_operators oper,
-                                    int x, int y, int offset_x, int offset_y,
-                                    unsigned int width, unsigned int height);
-
-  grub_err_t (*scroll) (grub_video_color_t color, int dx, int dy);
-
-  grub_err_t (*swap_buffers) (void);
-
-  grub_err_t (*create_render_target) (struct grub_video_render_target **result,
-                                      unsigned int width, unsigned int height,
-                                      unsigned int mode_type);
-
-  grub_err_t (*delete_render_target) (struct grub_video_render_target *target);
-
-  grub_err_t (*set_active_render_target) (struct grub_video_render_target *target);
-
-  grub_err_t (*get_active_render_target) (struct grub_video_render_target **target);
-
-  /* The next video adapter.  */
-  struct grub_video_adapter *next;
-};
-typedef struct grub_video_adapter *grub_video_adapter_t;
-
-void EXPORT_FUNC (grub_video_register) (grub_video_adapter_t adapter);
-void grub_video_unregister (grub_video_adapter_t adapter);
-void grub_video_iterate (int (*hook) (grub_video_adapter_t adapter));
-
-grub_err_t EXPORT_FUNC (grub_video_restore) (void);
-
-grub_err_t EXPORT_FUNC (grub_video_get_info) (struct grub_video_mode_info *mode_info);
-
-/* Framebuffer address may change as a part of normal operation
-   (e.g. double buffering). That's why you need to stop video subsystem to be
-   sure that framebuffer address doesn't change. To ensure this abstraction
-   grub_video_get_info_and_fini is the only function supplying framebuffer
-   address. */
-grub_err_t EXPORT_FUNC (grub_video_get_info_and_fini) (struct grub_video_mode_info *mode_info,
-                                        void **framebuffer);
-
-enum grub_video_blit_format grub_video_get_blit_format (struct grub_video_mode_info *mode_info);
-
-grub_err_t grub_video_set_palette (unsigned int start, unsigned int count,
-                                   struct grub_video_palette_data *palette_data);
-
-grub_err_t EXPORT_FUNC (grub_video_get_palette) (unsigned int start,
-                                                unsigned int count,
-                                                struct grub_video_palette_data *palette_data);
-
-grub_err_t EXPORT_FUNC (grub_video_set_viewport) (unsigned int x,
-                                                 unsigned int y,
-                                                 unsigned int width,
-                                                 unsigned int height);
-
-grub_err_t EXPORT_FUNC (grub_video_get_viewport) (unsigned int *x,
-                                                 unsigned int *y,
-                                                 unsigned int *width,
-                                                 unsigned int *height);
-
-grub_video_color_t EXPORT_FUNC (grub_video_map_color) (grub_uint32_t color_name);
-
-grub_video_color_t EXPORT_FUNC (grub_video_map_rgb) (grub_uint8_t red,
-                                                    grub_uint8_t green,
-                                                    grub_uint8_t blue);
-
-grub_video_color_t EXPORT_FUNC (grub_video_map_rgba) (grub_uint8_t red,
-                                                     grub_uint8_t green,
-                                                     grub_uint8_t blue,
-                                                     grub_uint8_t alpha);
-
-grub_err_t EXPORT_FUNC (grub_video_unmap_color) (grub_video_color_t color,
-                                                grub_uint8_t *red,
-                                                grub_uint8_t *green,
-                                                grub_uint8_t *blue,
-                                                grub_uint8_t *alpha);
-
-grub_err_t EXPORT_FUNC (grub_video_fill_rect) (grub_video_color_t color, 
-                                              int x, int y,
-                                              unsigned int width,
-                                              unsigned int height);
-
-grub_err_t EXPORT_FUNC (grub_video_blit_bitmap) (struct grub_video_bitmap *bitmap,
-                                                enum grub_video_blit_operators oper,
-                                                int x, int y,
-                                                int offset_x, int offset_y,
-                                                unsigned int width,
-                                                unsigned int height);
-
-grub_err_t EXPORT_FUNC (grub_video_blit_render_target) (struct grub_video_render_target *source,
-                                                       enum grub_video_blit_operators oper,
-                                                       int x, int y,
-                                                       int offset_x,
-                                                       int offset_y,
-                                                       unsigned int width,
-                                                       unsigned int height);
-
-grub_err_t grub_video_scroll (grub_video_color_t color, int dx, int dy);
-
-grub_err_t EXPORT_FUNC (grub_video_swap_buffers) (void);
-
-grub_err_t EXPORT_FUNC (grub_video_create_render_target) (struct grub_video_render_target **result,
-                                                         unsigned int width,
-                                                         unsigned int height,
-                                                         unsigned int mode_type);
-
-grub_err_t EXPORT_FUNC (grub_video_delete_render_target) (struct grub_video_render_target *target);
-
-grub_err_t EXPORT_FUNC (grub_video_set_active_render_target) (struct grub_video_render_target *target);
-
-grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target);
-
-grub_err_t EXPORT_FUNC (grub_video_set_mode) (const char *modestring,
-                                             unsigned int modemask,
-                                             unsigned int modevalue);
-
-static inline int
-grub_video_check_mode_flag (unsigned int flags, unsigned int mask,
-                           unsigned int flag, int def)
-{
-  return (flag & mask) ? !! (flags & flag) : def;
-}
-
-grub_video_driver_id_t EXPORT_FUNC (grub_video_get_driver_id) (void);
-
-#endif /* ! GRUB_VIDEO_HEADER */
diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h
deleted file mode 100644 (file)
index 3046a59..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_VIDEO_FB_HEADER
-#define GRUB_VIDEO_FB_HEADER   1
-
-#include <grub/symbol.h>
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/video.h>
-
-/* FB module internal prototype (should not be used from elsewhere).  */
-
-struct grub_video_fbblit_info;
-
-struct grub_video_fbrender_target;
-
-#define GRUB_VIDEO_FBSTD_NUMCOLORS 16
-extern struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLORS];
-
-grub_err_t
-grub_video_fb_init (void);
-
-grub_err_t
-grub_video_fb_fini (void);
-
-grub_err_t
-grub_video_fb_get_info (struct grub_video_mode_info *mode_info);
-
-grub_err_t
-grub_video_fb_get_palette (unsigned int start, unsigned int count,
-                          struct grub_video_palette_data *palette_data);
-grub_err_t
-grub_video_fb_set_palette (unsigned int start, unsigned int count,
-                          struct grub_video_palette_data *palette_data);
-grub_err_t
-grub_video_fb_set_viewport (unsigned int x, unsigned int y,
-                           unsigned int width, unsigned int height);
-grub_err_t
-grub_video_fb_get_viewport (unsigned int *x, unsigned int *y,
-                           unsigned int *width, unsigned int *height);
-
-grub_video_color_t
-grub_video_fb_map_color (grub_uint32_t color_name);
-
-grub_video_color_t
-grub_video_fb_map_rgb (grub_uint8_t red, grub_uint8_t green,
-                      grub_uint8_t blue);
-
-grub_video_color_t
-grub_video_fb_map_rgba (grub_uint8_t red, grub_uint8_t green,
-                       grub_uint8_t blue, grub_uint8_t alpha);
-
-grub_err_t
-grub_video_fb_unmap_color (grub_video_color_t color,
-                          grub_uint8_t *red, grub_uint8_t *green,
-                          grub_uint8_t *blue, grub_uint8_t *alpha);
-
-void
-grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source,
-                              grub_video_color_t color,
-                              grub_uint8_t *red, grub_uint8_t *green,
-                              grub_uint8_t *blue, grub_uint8_t *alpha);
-
-grub_err_t
-grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
-                        unsigned int width, unsigned int height);
-
-grub_err_t
-grub_video_fb_blit_bitmap (struct grub_video_bitmap *bitmap,
-                          enum grub_video_blit_operators oper, int x, int y,
-                          int offset_x, int offset_y,
-                          unsigned int width, unsigned int height);
-
-grub_err_t
-grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source,
-                                   enum grub_video_blit_operators oper,
-                                   int x, int y, int offset_x, int offset_y,
-                                 unsigned int width, unsigned int height);
-
-grub_err_t
-grub_video_fb_scroll (grub_video_color_t color, int dx, int dy);
-
-grub_err_t
-grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
-                                   unsigned int width, unsigned int height,
-                                   unsigned int mode_type __attribute__ ((unused)));
-
-grub_err_t
-grub_video_fb_create_render_target_from_pointer (struct grub_video_fbrender_target **result,
-                                                const struct grub_video_mode_info *mode_info,
-                                                void *ptr);
-
-grub_err_t
-grub_video_fb_delete_render_target (struct grub_video_fbrender_target *target);
-
-grub_err_t
-grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **target);
-
-grub_err_t
-grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *target);
-
-typedef grub_err_t
-(*grub_video_fb_doublebuf_update_screen_t) (struct grub_video_fbrender_target *front,
-                                         struct grub_video_fbrender_target *back);
-
-grub_err_t
-grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **front,
-                                  struct grub_video_fbrender_target **back,
-                                  grub_video_fb_doublebuf_update_screen_t *update_screen,
-                                  struct grub_video_mode_info mode_info,
-                                  void *framebuf);
-
-#endif /* ! GRUB_VIDEO_FB_HEADER */
diff --git a/include/grub/x86_64/at_keyboard.h b/include/grub/x86_64/at_keyboard.h
deleted file mode 100644 (file)
index c632aa8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/at_keyboard.h>
diff --git a/include/grub/x86_64/efi/kernel.h b/include/grub/x86_64/efi/kernel.h
deleted file mode 100644 (file)
index c0549f4..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MACHINE_KERNEL_HEADER
-#define GRUB_MACHINE_KERNEL_HEADER   1
-
-/* The prefix which points to the directory where GRUB modules and its
-   configuration file are located.  */
-extern char grub_prefix[];
-
-/* The offset of GRUB_PREFIX.  */
-#define GRUB_KERNEL_MACHINE_PREFIX             0x8
-
-/* End of the data section. */
-#define GRUB_KERNEL_MACHINE_DATA_END           0x50
-
-#endif /* ! GRUB_MACHINE_KERNEL_HEADER */
-
diff --git a/include/grub/x86_64/efi/loader.h b/include/grub/x86_64/efi/loader.h
deleted file mode 100644 (file)
index 7c302e8..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_LOADER_MACHINE_HEADER
-#define GRUB_LOADER_MACHINE_HEADER     1
-
-#include <grub/types.h>
-#include <grub/symbol.h>
-
-
-#endif /* ! GRUB_LOADER_MACHINE_HEADER */
diff --git a/include/grub/x86_64/efi/memory.h b/include/grub/x86_64/efi/memory.h
deleted file mode 100644 (file)
index c9a61bb..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/efi/memory.h>
diff --git a/include/grub/x86_64/efi/serial.h b/include/grub/x86_64/efi/serial.h
deleted file mode 100644 (file)
index 2d85634..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/coreboot/serial.h>
diff --git a/include/grub/x86_64/efi/time.h b/include/grub/x86_64/efi/time.h
deleted file mode 100644 (file)
index 7a9241f..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_MACHINE_TIME_HEADER
-#define GRUB_MACHINE_TIME_HEADER       1
-
-#include <grub/efi/time.h>
-
-#endif /* ! GRUB_MACHINE_TIME_HEADER */
diff --git a/include/grub/x86_64/io.h b/include/grub/x86_64/io.h
deleted file mode 100644 (file)
index 9f465bc..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/i386/io.h>
diff --git a/include/grub/x86_64/kernel.h b/include/grub/x86_64/kernel.h
deleted file mode 100644 (file)
index 25ac57e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/kernel.h>
diff --git a/include/grub/x86_64/linux.h b/include/grub/x86_64/linux.h
deleted file mode 100644 (file)
index 19ea936..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/i386/linux.h>
diff --git a/include/grub/x86_64/macho.h b/include/grub/x86_64/macho.h
deleted file mode 100644 (file)
index 165b8da..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/macho.h>
diff --git a/include/grub/x86_64/multiboot.h b/include/grub/x86_64/multiboot.h
deleted file mode 100644 (file)
index 957c7a5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/multiboot.h>
diff --git a/include/grub/x86_64/pci.h b/include/grub/x86_64/pci.h
deleted file mode 100644 (file)
index 91a9924..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/i386/pci.h>
diff --git a/include/grub/x86_64/relocator.h b/include/grub/x86_64/relocator.h
deleted file mode 100644 (file)
index 247e7a1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/relocator.h>
diff --git a/include/grub/x86_64/setjmp.h b/include/grub/x86_64/setjmp.h
deleted file mode 100644 (file)
index 4ad968e..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_SETJMP_CPU_HEADER
-#define GRUB_SETJMP_CPU_HEADER 1
-
-typedef unsigned long grub_jmp_buf[8];
-
-int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice));
-void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn));
-
-#endif /* ! GRUB_SETJMP_CPU_HEADER */
diff --git a/include/grub/x86_64/time.h b/include/grub/x86_64/time.h
deleted file mode 100644 (file)
index 842882c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef KERNEL_CPU_TIME_HEADER
-#define KERNEL_CPU_TIME_HEADER 1
-
-static __inline void
-grub_cpu_idle (void)
-{
-  /* FIXME: this can't work until we handle interrupts.  */
-/*  __asm__ __volatile__ ("hlt"); */
-}
-
-#endif /* ! KERNEL_CPU_TIME_HEADER */
diff --git a/include/grub/x86_64/types.h b/include/grub/x86_64/types.h
deleted file mode 100644 (file)
index bdee5a1..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_TYPES_CPU_HEADER
-#define GRUB_TYPES_CPU_HEADER  1
-
-/* The size of void *.  */
-#define GRUB_TARGET_SIZEOF_VOID_P      8
-
-/* The size of long.  */
-#define GRUB_TARGET_SIZEOF_LONG                8
-
-/* x86_64 is little-endian.  */
-#undef GRUB_TARGET_WORDS_BIGENDIAN
-
-#endif /* ! GRUB_TYPES_CPU_HEADER */
diff --git a/include/grub/x86_64/xnu.h b/include/grub/x86_64/xnu.h
deleted file mode 100644 (file)
index ae61733..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <grub/i386/xnu.h>
diff --git a/include/grub/xnu.h b/include/grub/xnu.h
deleted file mode 100644 (file)
index 6089aad..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_XNU_H
-#define GRUB_XNU_H 1
-
-#include <grub/bitmap.h>
-
-/* Header of a hibernation image. */
-struct grub_xnu_hibernate_header
-{
-  /* Size of the image. Notice that file containing image is usually bigger. */
-  grub_uint64_t image_size;
-  grub_uint8_t unknown1[8];
-  /* Where to copy launchcode? */
-  grub_uint32_t launchcode_target_page;
-  /* How many pages of launchcode? */
-  grub_uint32_t launchcode_numpages;
-  /* Where to jump? */
-  grub_uint32_t entry_point;
-  /* %esp at start. */
-  grub_uint32_t stack;
-  grub_uint8_t unknown2[44];
-#define GRUB_XNU_HIBERNATE_MAGIC 0x73696d65
-  grub_uint32_t magic;
-  grub_uint8_t unknown3[28];
-  /* This value is non-zero if page is encrypted. Unsupported. */
-  grub_uint64_t encoffset;
-  grub_uint8_t unknown4[360];
-  /* The size of additional header used to locate image without parsing FS.
-     Used only to skip it.
-   */
-  grub_uint32_t extmapsize;
-} __attribute__ ((packed));
-
-/* In-memory structure for temporary keeping device tree. */
-struct grub_xnu_devtree_key
-{
-  char *name;
-  int datasize; /* -1 for not leaves. */
-  union
-  {
-    struct grub_xnu_devtree_key *first_child;
-    void *data;
-  };
-  struct grub_xnu_devtree_key *next;
-};
-
-/* A structure used in memory-map values. */
-struct
-grub_xnu_extdesc
-{
-  grub_uint32_t addr;
-  grub_uint32_t size;
-} __attribute__ ((packed));
-
-/* Header describing extension in the memory. */
-struct grub_xnu_extheader
-{
-  grub_uint32_t infoplistaddr;
-  grub_uint32_t infoplistsize;
-  grub_uint32_t binaryaddr;
-  grub_uint32_t binarysize;
-  grub_uint32_t nameaddr;
-  grub_uint32_t namesize;
-} __attribute__ ((packed));
-
-struct grub_xnu_devtree_key *grub_xnu_create_key (struct grub_xnu_devtree_key **parent,
-                                                 char *name);
-
-extern struct grub_xnu_devtree_key *grub_xnu_devtree_root;
-
-void grub_xnu_free_devtree (struct grub_xnu_devtree_key *cur);
-
-grub_err_t grub_xnu_writetree_toheap (void **start, grub_size_t *size);
-struct grub_xnu_devtree_key *grub_xnu_create_value (struct grub_xnu_devtree_key **parent,
-                                                   char *name);
-
-void grub_xnu_lock (void);
-void grub_xnu_unlock (void);
-grub_err_t grub_xnu_resume (char *imagename);
-grub_err_t grub_xnu_boot_resume (void);
-struct grub_xnu_devtree_key *grub_xnu_find_key (struct grub_xnu_devtree_key *parent,
-                                               char *name);
-grub_err_t grub_xnu_align_heap (int align);
-grub_err_t grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired,
-                                       int maxrecursion);
-grub_err_t grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired,
-                                       int maxrecursion);
-void *grub_xnu_heap_malloc (int size);
-grub_err_t grub_xnu_fill_devicetree (void);
-extern grub_uint32_t grub_xnu_heap_real_start;
-extern grub_size_t grub_xnu_heap_size;
-extern void *grub_xnu_heap_start;
-extern struct grub_video_bitmap *grub_xnu_bitmap;
-typedef enum {GRUB_XNU_BITMAP_CENTER, GRUB_XNU_BITMAP_STRETCH}
-  grub_xnu_bitmap_mode_t;
-extern grub_xnu_bitmap_mode_t grub_xnu_bitmap_mode;
-extern int grub_xnu_is_64bit;
-#endif
diff --git a/include/multiboot.h b/include/multiboot.h
deleted file mode 100644 (file)
index fda863e..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-/*  multiboot.h - Multiboot header file.  */
-/*  Copyright (C) 1999,2003,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  Permission is hereby granted, free of charge, to any person obtaining a copy
- *  of this software and associated documentation files (the "Software"), to
- *  deal in the Software without restriction, including without limitation the
- *  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- *  sell copies of the Software, and to permit persons to whom the Software is
- *  furnished to do so, subject to the following conditions:
- *
- *  The above copyright notice and this permission notice shall be included in
- *  all copies or substantial portions of the Software.
- *
- *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL ANY
- *  DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
- *  IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef MULTIBOOT_HEADER
-#define MULTIBOOT_HEADER 1
-
-/* How many bytes from the start of the file we search for the header.  */
-#define MULTIBOOT_SEARCH                       8192
-#define MULTIBOOT_HEADER_ALIGN                 4
-
-/* The magic field should contain this.  */
-#define MULTIBOOT_HEADER_MAGIC                 0x1BADB002
-
-/* This should be in %eax.  */
-#define MULTIBOOT_BOOTLOADER_MAGIC             0x2BADB002
-
-/* Alignment of multiboot modules.  */
-#define MULTIBOOT_MOD_ALIGN                    0x00001000
-
-/* Alignment of the multiboot info structure.  */
-#define MULTIBOOT_INFO_ALIGN                   0x00000004
-
-/* Flags set in the 'flags' member of the multiboot header.  */
-
-/* Align all boot modules on i386 page (4KB) boundaries.  */
-#define MULTIBOOT_PAGE_ALIGN                   0x00000001
-
-/* Must pass memory information to OS.  */
-#define MULTIBOOT_MEMORY_INFO                  0x00000002
-
-/* Must pass video information to OS.  */
-#define MULTIBOOT_VIDEO_MODE                   0x00000004
-
-/* This flag indicates the use of the address fields in the header.  */
-#define MULTIBOOT_AOUT_KLUDGE                  0x00010000
-
-/* Flags to be set in the 'flags' member of the multiboot info structure.  */
-
-/* is there basic lower/upper memory information? */
-#define MULTIBOOT_INFO_MEMORY                  0x00000001
-/* is there a boot device set? */
-#define MULTIBOOT_INFO_BOOTDEV                 0x00000002
-/* is the command-line defined? */
-#define MULTIBOOT_INFO_CMDLINE                 0x00000004
-/* are there modules to do something with? */
-#define MULTIBOOT_INFO_MODS                    0x00000008
-
-/* These next two are mutually exclusive */
-
-/* is there a symbol table loaded? */
-#define MULTIBOOT_INFO_AOUT_SYMS               0x00000010
-/* is there an ELF section header table? */
-#define MULTIBOOT_INFO_ELF_SHDR                        0X00000020
-
-/* is there a full memory map? */
-#define MULTIBOOT_INFO_MEM_MAP                 0x00000040
-
-/* Is there drive info?  */
-#define MULTIBOOT_INFO_DRIVE_INFO              0x00000080
-
-/* Is there a config table?  */
-#define MULTIBOOT_INFO_CONFIG_TABLE            0x00000100
-
-/* Is there a boot loader name?  */
-#define MULTIBOOT_INFO_BOOT_LOADER_NAME                0x00000200
-
-/* Is there a APM table?  */
-#define MULTIBOOT_INFO_APM_TABLE               0x00000400
-
-/* Is there video information?  */
-#define MULTIBOOT_INFO_VBE_INFO                        0x00000800
-#define MULTIBOOT_INFO_FRAMEBUFFER_INFO                0x00001000
-
-#ifndef ASM_FILE
-
-typedef unsigned char          multiboot_uint8_t;
-typedef unsigned short         multiboot_uint16_t;
-typedef unsigned int           multiboot_uint32_t;
-typedef unsigned long long     multiboot_uint64_t;
-
-struct multiboot_header
-{
-  /* Must be MULTIBOOT_MAGIC - see above.  */
-  multiboot_uint32_t magic;
-
-  /* Feature flags.  */
-  multiboot_uint32_t flags;
-
-  /* The above fields plus this one must equal 0 mod 2^32. */
-  multiboot_uint32_t checksum;
-
-  /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set.  */
-  multiboot_uint32_t header_addr;
-  multiboot_uint32_t load_addr;
-  multiboot_uint32_t load_end_addr;
-  multiboot_uint32_t bss_end_addr;
-  multiboot_uint32_t entry_addr;
-
-  /* These are only valid if MULTIBOOT_VIDEO_MODE is set.  */
-  multiboot_uint32_t mode_type;
-  multiboot_uint32_t width;
-  multiboot_uint32_t height;
-  multiboot_uint32_t depth;
-};
-
-/* The symbol table for a.out.  */
-struct multiboot_aout_symbol_table
-{
-  multiboot_uint32_t tabsize;
-  multiboot_uint32_t strsize;
-  multiboot_uint32_t addr;
-  multiboot_uint32_t reserved;
-};
-typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
-
-/* The section header table for ELF.  */
-struct multiboot_elf_section_header_table
-{
-  multiboot_uint32_t num;
-  multiboot_uint32_t size;
-  multiboot_uint32_t addr;
-  multiboot_uint32_t shndx;
-};
-typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
-
-struct multiboot_info
-{
-  /* Multiboot info version number */
-  multiboot_uint32_t flags;
-
-  /* Available memory from BIOS */
-  multiboot_uint32_t mem_lower;
-  multiboot_uint32_t mem_upper;
-
-  /* "root" partition */
-  multiboot_uint32_t boot_device;
-
-  /* Kernel command line */
-  multiboot_uint32_t cmdline;
-
-  /* Boot-Module list */
-  multiboot_uint32_t mods_count;
-  multiboot_uint32_t mods_addr;
-
-  union
-  {
-    multiboot_aout_symbol_table_t aout_sym;
-    multiboot_elf_section_header_table_t elf_sec;
-  } u;
-
-  /* Memory Mapping buffer */
-  multiboot_uint32_t mmap_length;
-  multiboot_uint32_t mmap_addr;
-
-  /* Drive Info buffer */
-  multiboot_uint32_t drives_length;
-  multiboot_uint32_t drives_addr;
-
-  /* ROM configuration table */
-  multiboot_uint32_t config_table;
-
-  /* Boot Loader Name */
-  multiboot_uint32_t boot_loader_name;
-
-  /* APM table */
-  multiboot_uint32_t apm_table;
-
-  /* Video */
-  multiboot_uint32_t vbe_control_info;
-  multiboot_uint32_t vbe_mode_info;
-  multiboot_uint16_t vbe_mode;
-  multiboot_uint16_t vbe_interface_seg;
-  multiboot_uint16_t vbe_interface_off;
-  multiboot_uint16_t vbe_interface_len;
-
-  multiboot_uint64_t framebuffer_addr;
-  multiboot_uint32_t framebuffer_pitch;
-  multiboot_uint32_t framebuffer_width;
-  multiboot_uint32_t framebuffer_height;
-  multiboot_uint8_t framebuffer_bpp;
-#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
-#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB     1
-#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT    2
-  multiboot_uint8_t framebuffer_type;
-  union
-  {
-    struct
-    {
-      multiboot_uint32_t framebuffer_palette_addr;
-      multiboot_uint16_t framebuffer_palette_num_colors;
-    };
-    struct
-    {
-      multiboot_uint8_t framebuffer_red_field_position;
-      multiboot_uint8_t framebuffer_red_mask_size;
-      multiboot_uint8_t framebuffer_green_field_position;
-      multiboot_uint8_t framebuffer_green_mask_size;
-      multiboot_uint8_t framebuffer_blue_field_position;
-      multiboot_uint8_t framebuffer_blue_mask_size;
-    };
-  };
-};
-typedef struct multiboot_info multiboot_info_t;
-
-struct multiboot_color
-{
-  multiboot_uint8_t red;
-  multiboot_uint8_t green;
-  multiboot_uint8_t blue;
-};
-
-struct multiboot_mmap_entry
-{
-  multiboot_uint32_t size;
-  multiboot_uint64_t addr;
-  multiboot_uint64_t len;
-#define MULTIBOOT_MEMORY_AVAILABLE             1
-#define MULTIBOOT_MEMORY_RESERVED              2
-#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE       3
-#define MULTIBOOT_MEMORY_NVS                    4
-  multiboot_uint32_t type;
-} __attribute__((packed));
-typedef struct multiboot_mmap_entry multiboot_memory_map_t;
-
-struct multiboot_mod_list
-{
-  /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
-  multiboot_uint32_t mod_start;
-  multiboot_uint32_t mod_end;
-
-  /* Module command line */
-  multiboot_uint32_t cmdline;
-
-  /* padding to take it to 16 bytes (must be zero) */
-  multiboot_uint32_t pad;
-};
-typedef struct multiboot_mod_list multiboot_module_t;
-
-#endif /* ! ASM_FILE */
-
-#endif /* ! MULTIBOOT_HEADER */
diff --git a/include/multiboot2.h b/include/multiboot2.h
deleted file mode 100644 (file)
index 275debe..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-/*  multiboot2.h - Multiboot 2 header file.  */
-/*  Copyright (C) 1999,2003,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  Permission is hereby granted, free of charge, to any person obtaining a copy
- *  of this software and associated documentation files (the "Software"), to
- *  deal in the Software without restriction, including without limitation the
- *  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- *  sell copies of the Software, and to permit persons to whom the Software is
- *  furnished to do so, subject to the following conditions:
- *
- *  The above copyright notice and this permission notice shall be included in
- *  all copies or substantial portions of the Software.
- *
- *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL ANY
- *  DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
- *  IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef MULTIBOOT_HEADER
-#define MULTIBOOT_HEADER 1
-
-/* How many bytes from the start of the file we search for the header.  */
-#define MULTIBOOT_SEARCH                       32768
-#define MULTIBOOT_HEADER_ALIGN                 8
-
-/* The magic field should contain this.  */
-#define MULTIBOOT2_HEADER_MAGIC                        0xe85250d6
-
-/* This should be in %eax.  */
-#define MULTIBOOT2_BOOTLOADER_MAGIC            0x36d76289
-
-/* Alignment of multiboot modules.  */
-#define MULTIBOOT_MOD_ALIGN                    0x00001000
-
-/* Alignment of the multiboot info structure.  */
-#define MULTIBOOT_INFO_ALIGN                   0x00000008
-
-/* Flags set in the 'flags' member of the multiboot header.  */
-
-#define MULTIBOOT_TAG_ALIGN                  8
-#define MULTIBOOT_TAG_TYPE_END               0
-#define MULTIBOOT_TAG_TYPE_CMDLINE           1
-#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME  2
-#define MULTIBOOT_TAG_TYPE_MODULE            3
-#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO     4
-#define MULTIBOOT_TAG_TYPE_BOOTDEV           5
-#define MULTIBOOT_TAG_TYPE_MMAP              6
-#define MULTIBOOT_TAG_TYPE_VBE               7
-#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER       8
-#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS      9
-#define MULTIBOOT_TAG_TYPE_APM               10
-
-#define MULTIBOOT_HEADER_TAG_END  0
-#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST  1
-#define MULTIBOOT_HEADER_TAG_ADDRESS  2
-#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS  3
-#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS  4
-#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER  5
-#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN  6
-
-#define MULTIBOOT_ARCHITECTURE_I386  0
-#define MULTIBOOT_ARCHITECTURE_MIPS32  4
-#define MULTIBOOT_HEADER_TAG_OPTIONAL 1
-
-#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
-#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
-
-#ifndef ASM_FILE
-
-typedef unsigned char          multiboot_uint8_t;
-typedef unsigned short         multiboot_uint16_t;
-typedef unsigned int           multiboot_uint32_t;
-typedef unsigned long long     multiboot_uint64_t;
-
-struct multiboot_header
-{
-  /* Must be MULTIBOOT_MAGIC - see above.  */
-  multiboot_uint32_t magic;
-
-  /* ISA */
-  multiboot_uint32_t architecture;
-
-  /* Total header length.  */
-  multiboot_uint32_t header_length;
-
-  /* The above fields plus this one must equal 0 mod 2^32. */
-  multiboot_uint32_t checksum;
-};
-
-struct multiboot_header_tag
-{
-  multiboot_uint16_t type;
-  multiboot_uint16_t flags;
-  multiboot_uint32_t size;
-};
-
-struct multiboot_header_tag_information_request
-{
-  multiboot_uint16_t type;
-  multiboot_uint16_t flags;
-  multiboot_uint32_t size;
-  multiboot_uint32_t requests[0];
-};
-
-struct multiboot_header_tag_address
-{
-  multiboot_uint16_t type;
-  multiboot_uint16_t flags;
-  multiboot_uint32_t size;
-  multiboot_uint32_t header_addr;
-  multiboot_uint32_t load_addr;
-  multiboot_uint32_t load_end_addr;
-  multiboot_uint32_t bss_end_addr;
-};
-
-struct multiboot_header_tag_entry_address
-{
-  multiboot_uint16_t type;
-  multiboot_uint16_t flags;
-  multiboot_uint32_t size;
-  multiboot_uint32_t entry_addr;
-};
-
-struct multiboot_header_tag_console_flags
-{
-  multiboot_uint16_t type;
-  multiboot_uint16_t flags;
-  multiboot_uint32_t size;
-  multiboot_uint32_t console_flags;
-};
-
-struct multiboot_header_tag_framebuffer
-{
-  multiboot_uint16_t type;
-  multiboot_uint16_t flags;
-  multiboot_uint32_t size;
-  multiboot_uint32_t width;
-  multiboot_uint32_t height;
-  multiboot_uint32_t depth;
-};
-
-struct multiboot_header_tag_module_align
-{
-  multiboot_uint16_t type;
-  multiboot_uint16_t flags;
-  multiboot_uint32_t size;
-  multiboot_uint32_t width;
-  multiboot_uint32_t height;
-  multiboot_uint32_t depth;
-};
-
-struct multiboot_color
-{
-  multiboot_uint8_t red;
-  multiboot_uint8_t green;
-  multiboot_uint8_t blue;
-};
-
-struct multiboot_mmap_entry
-{
-  multiboot_uint64_t addr;
-  multiboot_uint64_t len;
-#define MULTIBOOT_MEMORY_AVAILABLE             1
-#define MULTIBOOT_MEMORY_RESERVED              2
-#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE       3
-#define MULTIBOOT_MEMORY_NVS                    4
-  multiboot_uint32_t type;
-  multiboot_uint32_t zero;
-} __attribute__((packed));
-typedef struct multiboot_mmap_entry multiboot_memory_map_t;
-
-struct multiboot_tag
-{
-  multiboot_uint32_t type;
-  multiboot_uint32_t size;
-};
-
-struct multiboot_tag_string
-{
-  multiboot_uint32_t type;
-  multiboot_uint32_t size;
-  char string[0];
-};
-
-struct multiboot_tag_module
-{
-  multiboot_uint32_t type;
-  multiboot_uint32_t size;
-  multiboot_uint32_t mod_start;
-  multiboot_uint32_t mod_end;
-  char cmdline[0];
-};
-
-struct multiboot_tag_basic_meminfo
-{
-  multiboot_uint32_t type;
-  multiboot_uint32_t size;
-  multiboot_uint32_t mem_lower;
-  multiboot_uint32_t mem_upper;
-};
-
-struct multiboot_tag_bootdev
-{
-  multiboot_uint32_t type;
-  multiboot_uint32_t size;
-  multiboot_uint32_t biosdev;
-  multiboot_uint32_t slice;
-  multiboot_uint32_t part;
-};
-
-struct multiboot_tag_mmap
-{
-  multiboot_uint32_t type;
-  multiboot_uint32_t size;
-  multiboot_uint32_t entry_size;
-  multiboot_uint32_t entry_version;
-  struct multiboot_mmap_entry entries[0];  
-};
-
-struct multiboot_vbe_info_block
-{
-  multiboot_uint8_t external_specification[512];
-};
-
-struct multiboot_vbe_mode_info_block
-{
-  multiboot_uint8_t external_specification[256];
-};
-
-struct multiboot_tag_vbe
-{
-  multiboot_uint32_t type;
-  multiboot_uint32_t size;
-
-  multiboot_uint16_t vbe_mode;
-  multiboot_uint16_t vbe_interface_seg;
-  multiboot_uint16_t vbe_interface_off;
-  multiboot_uint16_t vbe_interface_len;
-
-  struct multiboot_vbe_info_block vbe_control_info;
-  struct multiboot_vbe_mode_info_block vbe_mode_info;
-};
-
-struct multiboot_tag_framebuffer_common
-{
-  multiboot_uint32_t type;
-  multiboot_uint32_t size;
-
-  multiboot_uint64_t framebuffer_addr;
-  multiboot_uint32_t framebuffer_pitch;
-  multiboot_uint32_t framebuffer_width;
-  multiboot_uint32_t framebuffer_height;
-  multiboot_uint8_t framebuffer_bpp;
-#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
-#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB     1
-#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT    2
-  multiboot_uint8_t framebuffer_type;
-  multiboot_uint16_t reserved;
-};
-
-struct multiboot_tag_framebuffer
-{
-  struct multiboot_tag_framebuffer_common common;
-
-  union
-  {
-    struct
-    {
-      multiboot_uint16_t framebuffer_palette_num_colors;
-      struct multiboot_color framebuffer_palette[0];
-    };
-    struct
-    {
-      multiboot_uint8_t framebuffer_red_field_position;
-      multiboot_uint8_t framebuffer_red_mask_size;
-      multiboot_uint8_t framebuffer_green_field_position;
-      multiboot_uint8_t framebuffer_green_mask_size;
-      multiboot_uint8_t framebuffer_blue_field_position;
-      multiboot_uint8_t framebuffer_blue_mask_size;
-    };
-  };
-};
-
-struct multiboot_tag_elf_sections
-{
-  multiboot_uint32_t type;
-  multiboot_uint32_t size;
-  multiboot_uint32_t num;
-  multiboot_uint32_t entsize;
-  multiboot_uint32_t shndx;
-  char sections[0];
-};
-
-struct multiboot_tag_apm
-{
-  multiboot_uint32_t type;
-  multiboot_uint32_t size;
-  multiboot_uint16_t version;
-  multiboot_uint16_t cseg;
-  multiboot_uint32_t offset;
-  multiboot_uint16_t cseg_16;
-  multiboot_uint16_t dseg;
-  multiboot_uint16_t flags;
-  multiboot_uint16_t cseg_len;
-  multiboot_uint16_t cseg_16_len;
-  multiboot_uint16_t dseg_len;
-};
-
-#endif /* ! ASM_FILE */
-
-#endif /* ! MULTIBOOT_HEADER */
diff --git a/io/bufio.c b/io/bufio.c
deleted file mode 100644 (file)
index 92f2927..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/* bufio.c - buffered io access */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/fs.h>
-#include <grub/bufio.h>
-
-#define GRUB_BUFIO_DEF_SIZE    8192
-#define GRUB_BUFIO_MAX_SIZE    1048576
-
-struct grub_bufio
-{
-  grub_file_t file;
-  grub_size_t block_size;
-  grub_size_t buffer_len;
-  char buffer[0];
-};
-typedef struct grub_bufio *grub_bufio_t;
-
-static struct grub_fs grub_bufio_fs;
-
-grub_file_t
-grub_bufio_open (grub_file_t io, int size)
-{
-  grub_file_t file;
-  grub_bufio_t bufio = 0;
-
-  file = (grub_file_t) grub_malloc (sizeof (*file));
-  if (! file)
-    return 0;
-
-  if (size == 0)
-    size = GRUB_BUFIO_DEF_SIZE;
-  else if (size > GRUB_BUFIO_MAX_SIZE)
-    size = GRUB_BUFIO_MAX_SIZE;
-
-  if ((size < 0) || ((unsigned) size > io->size))
-    size = ((io->size > GRUB_BUFIO_MAX_SIZE) ? GRUB_BUFIO_MAX_SIZE :
-            io->size);
-
-  bufio = grub_malloc (sizeof (struct grub_bufio) + size);
-  if (! bufio)
-    {
-      grub_free (file);
-      return 0;
-    }
-
-  bufio->file = io;
-  bufio->block_size = size;
-  bufio->buffer_len = 0;
-
-  file->device = io->device;
-  file->offset = 0;
-  file->size = io->size;
-  file->data = bufio;
-  file->read_hook = 0;
-  file->fs = &grub_bufio_fs;
-
-  return file;
-}
-
-grub_file_t
-grub_buffile_open (const char *name, int size)
-{
-  grub_file_t io, file;
-
-  io = grub_file_open (name);
-  if (! io)
-    return 0;
-
-  file = grub_bufio_open (io, size);
-  if (! file)
-    {
-      grub_file_close (io);
-      return 0;
-    }
-
-  return file;
-}
-
-static grub_ssize_t
-grub_bufio_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  grub_size_t res = len;
-  grub_bufio_t bufio = file->data;
-  grub_uint32_t pos;
-
-  if ((file->offset >= bufio->file->offset) &&
-      (file->offset < bufio->file->offset + bufio->buffer_len))
-    {
-      grub_size_t n;
-
-      pos = file->offset - bufio->file->offset;
-      n = bufio->buffer_len - pos;
-      if (n > len)
-        n = len;
-
-      grub_memcpy (buf, &bufio->buffer[pos], n);
-      len -= n;
-      if (! len)
-        return res;
-
-      buf += n;
-      bufio->file->offset += bufio->buffer_len;
-      pos = 0;
-    }
-  else
-    {
-      bufio->file->offset = grub_divmod64 (file->offset, bufio->block_size,
-                                           &pos);
-      bufio->file->offset *= bufio->block_size;
-    }
-
-  if (pos + len >= bufio->block_size)
-    {
-      if (pos)
-        {
-          grub_size_t n;
-
-          bufio->file->fs->read (bufio->file, bufio->buffer,
-                                 bufio->block_size);
-          if (grub_errno)
-            return -1;
-
-          n = bufio->block_size - pos;
-          grub_memcpy (buf, &bufio->buffer[pos], n);
-          len -= n;
-          buf += n;
-          bufio->file->offset += bufio->block_size;
-          pos = 0;
-        }
-
-      while (len >= bufio->block_size)
-        {
-          bufio->file->fs->read (bufio->file, buf, bufio->block_size);
-          if (grub_errno)
-            return -1;
-
-          len -= bufio->block_size;
-          buf += bufio->block_size;
-          bufio->file->offset += bufio->block_size;
-        }
-
-      if (! len)
-        {
-          bufio->buffer_len = 0;
-          return res;
-        }
-    }
-
-  bufio->buffer_len = bufio->file->size - bufio->file->offset;
-  if (bufio->buffer_len > bufio->block_size)
-    bufio->buffer_len = bufio->block_size;
-
-  bufio->file->fs->read (bufio->file, bufio->buffer, bufio->buffer_len);
-  if (grub_errno)
-    return -1;
-
-  grub_memcpy (buf, &bufio->buffer[pos], len);
-
-  return res;
-}
-
-static grub_err_t
-grub_bufio_close (grub_file_t file)
-{
-  grub_bufio_t bufio = file->data;
-
-  grub_file_close (bufio->file);
-  grub_free (bufio);
-
-  file->device = 0;
-
-  return grub_errno;
-}
-
-static struct grub_fs grub_bufio_fs =
-  {
-    .name = "bufio",
-    .dir = 0,
-    .open = 0,
-    .read = grub_bufio_read,
-    .close = grub_bufio_close,
-    .label = 0,
-    .next = 0
-  };
diff --git a/io/gzio.c b/io/gzio.c
deleted file mode 100644 (file)
index 9bf6091..0000000
--- a/io/gzio.c
+++ /dev/null
@@ -1,1251 +0,0 @@
-/* gzio.c - decompression support for gzip */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2005,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * Most of this file was originally the source file "inflate.c", written
- * by Mark Adler.  It has been very heavily modified.  In particular, the
- * original would run through the whole file at once, and this version can
- * be stopped and restarted on any boundary during the decompression process.
- *
- * The license and header comments that file are included here.
- */
-
-/* inflate.c -- Not copyrighted 1992 by Mark Adler
-   version c10p1, 10 January 1993 */
-
-/* You can do whatever you like with this source file, though I would
-   prefer that if you modify it and redistribute it that you include
-   comments to that effect with your name and the date.  Thank you.
- */
-
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/fs.h>
-#include <grub/file.h>
-#include <grub/gzio.h>
-
-/*
- *  Window Size
- *
- *  This must be a power of two, and at least 32K for zip's deflate method
- */
-
-#define WSIZE  0x8000
-
-
-#define INBUFSIZ  0x2000
-
-/* The state stored in filesystem-specific data.  */
-struct grub_gzio
-{
-  /* The underlying file object.  */
-  grub_file_t file;
-  /* The offset at which the data starts in the underlying file.  */
-  grub_off_t data_offset;
-  /* The type of current block.  */
-  int block_type;
-  /* The length of current block.  */
-  int block_len;
-  /* The flag of the last block.  */
-  int last_block;
-  /* The flag of codes.  */
-  int code_state;
-  /* The length of a copy.  */
-  unsigned inflate_n;
-  /* The index of a copy.  */
-  unsigned inflate_d;
-  /* The input buffer.  */
-  grub_uint8_t inbuf[INBUFSIZ];
-  int inbuf_d;
-  /* The bit buffer.  */
-  unsigned long bb;
-  /* The bits in the bit buffer.  */
-  unsigned bk;
-  /* The sliding window in uncompressed data.  */
-  grub_uint8_t slide[WSIZE];
-  /* Current position in the slide.  */
-  unsigned wp;
-  /* The literal/length code table.  */
-  struct huft *tl;
-  /* The distance code table.  */
-  struct huft *td;
-  /* The lookup bits for the literal/length code table. */
-  int bl;
-  /* The lookup bits for the distance code table.  */
-  int bd;
-  /* The original offset value.  */
-  grub_off_t saved_offset;
-};
-typedef struct grub_gzio *grub_gzio_t;
-
-/* Declare the filesystem structure for grub_gzio_open.  */
-static struct grub_fs grub_gzio_fs;
-
-/* Function prototypes */
-static void initialize_tables (grub_file_t file);
-
-/* Eat variable-length header fields.  */
-static int
-eat_field (grub_file_t file, int len)
-{
-  char ch = 1;
-  int not_retval = 1;
-
-  do
-    {
-      if (len >= 0)
-       {
-         if (! (len--))
-           break;
-       }
-      else
-       {
-         if (! ch)
-           break;
-       }
-    }
-  while ((not_retval = grub_file_read (file, &ch, 1)) == 1);
-
-  return ! not_retval;
-}
-
-
-/* Little-Endian defines for the 2-byte magic numbers for gzip files.  */
-#define GZIP_MAGIC     grub_le_to_cpu16 (0x8B1F)
-#define OLD_GZIP_MAGIC grub_le_to_cpu16 (0x9E1F)
-
-/* Compression methods (see algorithm.doc) */
-#define STORED      0
-#define COMPRESSED  1
-#define PACKED      2
-#define LZHED       3
-/* methods 4 to 7 reserved */
-#define DEFLATED    8
-#define MAX_METHODS 9
-
-/* gzip flag byte */
-#define ASCII_FLAG   0x01      /* bit 0 set: file probably ascii text */
-#define CONTINUATION 0x02      /* bit 1 set: continuation of multi-part gzip file */
-#define EXTRA_FIELD  0x04      /* bit 2 set: extra field present */
-#define ORIG_NAME    0x08      /* bit 3 set: original file name present */
-#define COMMENT      0x10      /* bit 4 set: file comment present */
-#define ENCRYPTED    0x20      /* bit 5 set: file is encrypted */
-#define RESERVED     0xC0      /* bit 6,7:   reserved */
-
-#define UNSUPPORTED_FLAGS      (CONTINUATION | ENCRYPTED | RESERVED)
-
-/* inflate block codes */
-#define INFLATE_STORED 0
-#define INFLATE_FIXED  1
-#define INFLATE_DYNAMIC        2
-
-typedef unsigned char uch;
-typedef unsigned short ush;
-typedef unsigned long ulg;
-
-static int
-test_header (grub_file_t file)
-{
-  struct {
-    grub_uint16_t magic;
-    grub_uint8_t method;
-    grub_uint8_t flags;
-    grub_uint32_t timestamp;
-    grub_uint8_t extra_flags;
-    grub_uint8_t os_type;
-  } hdr;
-  grub_uint16_t extra_len;
-  grub_uint32_t orig_len;
-  grub_gzio_t gzio = file->data;
-
-  if (grub_file_tell (gzio->file) != 0)
-    grub_file_seek (gzio->file, 0);
-
-  /*
-   *  This checks if the file is gzipped.  If a problem occurs here
-   *  (other than a real error with the disk) then we don't think it
-   *  is a compressed file, and simply mark it as such.
-   */
-  if (grub_file_read (gzio->file, &hdr, 10) != 10
-      || ((hdr.magic != GZIP_MAGIC)
-         && (hdr.magic != OLD_GZIP_MAGIC)))
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "no gzip magic found");
-      return 0;
-    }
-
-  /*
-   *  This does consistency checking on the header data.  If a
-   *  problem occurs from here on, then we have corrupt or otherwise
-   *  bad data, and the error should be reported to the user.
-   */
-  if (hdr.method != DEFLATED
-      || (hdr.flags & UNSUPPORTED_FLAGS)
-      || ((hdr.flags & EXTRA_FIELD)
-         && (grub_file_read (gzio->file, &extra_len, 2) != 2
-             || eat_field (gzio->file,
-                           grub_le_to_cpu16 (extra_len))))
-      || ((hdr.flags & ORIG_NAME) && eat_field (gzio->file, -1))
-      || ((hdr.flags & COMMENT) && eat_field (gzio->file, -1)))
-    {
-      grub_error (GRUB_ERR_BAD_GZIP_DATA, "unsupported gzip format");
-      return 0;
-    }
-
-  gzio->data_offset = grub_file_tell (gzio->file);
-
-  grub_file_seek (gzio->file, grub_file_size (gzio->file) - 4);
-
-  if (grub_file_read (gzio->file, &orig_len, 4) != 4)
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported gzip format");
-      return 0;
-    }
-
-  /* FIXME: this does not handle files whose original size is over 4GB.
-     But how can we know the real original size?  */
-  file->size = grub_le_to_cpu32 (orig_len);
-
-  initialize_tables (file);
-
-  return 1;
-}
-
-
-/* Huffman code lookup table entry--this entry is four bytes for machines
-   that have 16-bit pointers (e.g. PC's in the small or medium model).
-   Valid extra bits are 0..13.  e == 15 is EOB (end of block), e == 16
-   means that v is a literal, 16 < e < 32 means that v is a pointer to
-   the next table, which codes e - 16 bits, and lastly e == 99 indicates
-   an unused code.  If a code with e == 99 is looked up, this implies an
-   error in the data. */
-struct huft
-{
-  uch e;                       /* number of extra bits or operation */
-  uch b;                       /* number of bits in this code or subcode */
-  union
-    {
-      ush n;                   /* literal, length base, or distance base */
-      struct huft *t;          /* pointer to next level of table */
-    }
-  v;
-};
-
-
-/* The inflate algorithm uses a sliding 32K byte window on the uncompressed
-   stream to find repeated byte strings.  This is implemented here as a
-   circular buffer.  The index is updated simply by incrementing and then
-   and'ing with 0x7fff (32K-1). */
-/* It is left to other modules to supply the 32K area.  It is assumed
-   to be usable as if it were declared "uch slide[32768];" or as just
-   "uch *slide;" and then malloc'ed in the latter case.  The definition
-   must be in unzip.h, included above. */
-
-
-/* Tables for deflate from PKZIP's appnote.txt. */
-static unsigned bitorder[] =
-{                              /* Order of the bit length code lengths */
-  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-static ush cplens[] =
-{                              /* Copy lengths for literal codes 257..285 */
-  3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
-  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
-       /* note: see note #13 above about the 258 in this list. */
-static ush cplext[] =
-{                              /* Extra bits for literal codes 257..285 */
-  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
-  3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99};      /* 99==invalid */
-static ush cpdist[] =
-{                              /* Copy offsets for distance codes 0..29 */
-  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
-  257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
-  8193, 12289, 16385, 24577};
-static ush cpdext[] =
-{                              /* Extra bits for distance codes */
-  0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
-  7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
-  12, 12, 13, 13};
-
-
-/*
-   Huffman code decoding is performed using a multi-level table lookup.
-   The fastest way to decode is to simply build a lookup table whose
-   size is determined by the longest code.  However, the time it takes
-   to build this table can also be a factor if the data being decoded
-   is not very long.  The most common codes are necessarily the
-   shortest codes, so those codes dominate the decoding time, and hence
-   the speed.  The idea is you can have a shorter table that decodes the
-   shorter, more probable codes, and then point to subsidiary tables for
-   the longer codes.  The time it costs to decode the longer codes is
-   then traded against the time it takes to make longer tables.
-
-   This results of this trade are in the variables lbits and dbits
-   below.  lbits is the number of bits the first level table for literal/
-   length codes can decode in one step, and dbits is the same thing for
-   the distance codes.  Subsequent tables are also less than or equal to
-   those sizes.  These values may be adjusted either when all of the
-   codes are shorter than that, in which case the longest code length in
-   bits is used, or when the shortest code is *longer* than the requested
-   table size, in which case the length of the shortest code in bits is
-   used.
-
-   There are two different values for the two tables, since they code a
-   different number of possibilities each.  The literal/length table
-   codes 286 possible values, or in a flat code, a little over eight
-   bits.  The distance table codes 30 possible values, or a little less
-   than five bits, flat.  The optimum values for speed end up being
-   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
-   The optimum values may differ though from machine to machine, and
-   possibly even between compilers.  Your mileage may vary.
- */
-
-
-static int lbits = 9;          /* bits in base literal/length lookup table */
-static int dbits = 6;          /* bits in base distance lookup table */
-
-
-/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
-#define BMAX 16                        /* maximum bit length of any code (16 for explode) */
-#define N_MAX 288              /* maximum number of codes in any set */
-
-
-/* Macros for inflate() bit peeking and grabbing.
-   The usage is:
-
-        NEEDBITS(j)
-        x = b & mask_bits[j];
-        DUMPBITS(j)
-
-   where NEEDBITS makes sure that b has at least j bits in it, and
-   DUMPBITS removes the bits from b.  The macros use the variable k
-   for the number of bits in b.  Normally, b and k are register
-   variables for speed, and are initialized at the beginning of a
-   routine that uses these macros from a global bit buffer and count.
-
-   If we assume that EOB will be the longest code, then we will never
-   ask for bits with NEEDBITS that are beyond the end of the stream.
-   So, NEEDBITS should not read any more bytes than are needed to
-   meet the request.  Then no bytes need to be "returned" to the buffer
-   at the end of the last block.
-
-   However, this assumption is not true for fixed blocks--the EOB code
-   is 7 bits, but the other literal/length codes can be 8 or 9 bits.
-   (The EOB code is shorter than other codes because fixed blocks are
-   generally short.  So, while a block always has an EOB, many other
-   literal/length codes have a significantly lower probability of
-   showing up at all.)  However, by making the first table have a
-   lookup of seven bits, the EOB code will be found in that first
-   lookup, and so will not require that too many bits be pulled from
-   the stream.
- */
-
-static ush mask_bits[] =
-{
-  0x0000,
-  0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
-  0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-};
-
-#define NEEDBITS(n) do {while(k<(n)){b|=((ulg)get_byte(file))<<k;k+=8;}} while (0)
-#define DUMPBITS(n) do {b>>=(n);k-=(n);} while (0)
-
-static int
-get_byte (grub_file_t file)
-{
-  grub_gzio_t gzio = file->data;
-
-  if (grub_file_tell (gzio->file) == (grub_off_t) gzio->data_offset
-      || gzio->inbuf_d == INBUFSIZ)
-    {
-      gzio->inbuf_d = 0;
-      grub_file_read (gzio->file, gzio->inbuf, INBUFSIZ);
-    }
-
-  return gzio->inbuf[gzio->inbuf_d++];
-}
-
-/* more function prototypes */
-static int huft_build (unsigned *, unsigned, unsigned, ush *, ush *,
-                      struct huft **, int *);
-static int huft_free (struct huft *);
-static int inflate_codes_in_window (grub_file_t);
-
-
-/* Given a list of code lengths and a maximum table size, make a set of
-   tables to decode that set of codes.  Return zero on success, one if
-   the given code set is incomplete (the tables are still built in this
-   case), two if the input is invalid (all zero length codes or an
-   oversubscribed set of lengths), and three if not enough memory. */
-
-static int
-huft_build (unsigned *b,       /* code lengths in bits (all assumed <= BMAX) */
-           unsigned n,         /* number of codes (assumed <= N_MAX) */
-           unsigned s,         /* number of simple-valued codes (0..s-1) */
-           ush * d,            /* list of base values for non-simple codes */
-           ush * e,            /* list of extra bits for non-simple codes */
-           struct huft **t,    /* result: starting table */
-           int *m)             /* maximum lookup bits, returns actual */
-{
-  unsigned a;                  /* counter for codes of length k */
-  unsigned c[BMAX + 1];                /* bit length count table */
-  unsigned f;                  /* i repeats in table every f entries */
-  int g;                       /* maximum code length */
-  int h;                       /* table level */
-  register unsigned i;         /* counter, current code */
-  register unsigned j;         /* counter */
-  register int k;              /* number of bits in current code */
-  int l;                       /* bits per table (returned in m) */
-  register unsigned *p;                /* pointer into c[], b[], or v[] */
-  register struct huft *q;     /* points to current table */
-  struct huft r;               /* table entry for structure assignment */
-  struct huft *u[BMAX];                /* table stack */
-  unsigned v[N_MAX];           /* values in order of bit length */
-  register int w;              /* bits before this table == (l * h) */
-  unsigned x[BMAX + 1];                /* bit offsets, then code stack */
-  unsigned *xp;                        /* pointer into x */
-  int y;                       /* number of dummy codes added */
-  unsigned z;                  /* number of entries in current table */
-
-  /* Generate counts for each bit length */
-  grub_memset ((char *) c, 0, sizeof (c));
-  p = b;
-  i = n;
-  do
-    {
-      c[*p]++;                 /* assume all entries <= BMAX */
-      p++;                     /* Can't combine with above line (Solaris bug) */
-    }
-  while (--i);
-  if (c[0] == n)               /* null input--all zero length codes */
-    {
-      *t = (struct huft *) NULL;
-      *m = 0;
-      return 0;
-    }
-
-  /* Find minimum and maximum length, bound *m by those */
-  l = *m;
-  for (j = 1; j <= BMAX; j++)
-    if (c[j])
-      break;
-  k = j;                       /* minimum code length */
-  if ((unsigned) l < j)
-    l = j;
-  for (i = BMAX; i; i--)
-    if (c[i])
-      break;
-  g = i;                       /* maximum code length */
-  if ((unsigned) l > i)
-    l = i;
-  *m = l;
-
-  /* Adjust last length count to fill out codes, if needed */
-  for (y = 1 << j; j < i; j++, y <<= 1)
-    if ((y -= c[j]) < 0)
-      return 2;                        /* bad input: more codes than bits */
-  if ((y -= c[i]) < 0)
-    return 2;
-  c[i] += y;
-
-  /* Generate starting offsets into the value table for each length */
-  x[1] = j = 0;
-  p = c + 1;
-  xp = x + 2;
-  while (--i)
-    {                          /* note that i == g from above */
-      *xp++ = (j += *p++);
-    }
-
-  /* Make a table of values in order of bit lengths */
-  p = b;
-  i = 0;
-  do
-    {
-      if ((j = *p++) != 0)
-       v[x[j]++] = i;
-    }
-  while (++i < n);
-
-  /* Generate the Huffman codes and for each, make the table entries */
-  x[0] = i = 0;                        /* first Huffman code is zero */
-  p = v;                       /* grab values in bit order */
-  h = -1;                      /* no tables yet--level -1 */
-  w = -l;                      /* bits decoded == (l * h) */
-  u[0] = (struct huft *) NULL; /* just to keep compilers happy */
-  q = (struct huft *) NULL;    /* ditto */
-  z = 0;                       /* ditto */
-
-  /* go through the bit lengths (k already is bits in shortest code) */
-  for (; k <= g; k++)
-    {
-      a = c[k];
-      while (a--)
-       {
-         /* here i is the Huffman code of length k bits for value *p */
-         /* make tables up to required level */
-         while (k > w + l)
-           {
-             h++;
-             w += l;           /* previous table always l bits */
-
-             /* compute minimum size table less than or equal to l bits */
-             z = (z = (unsigned) (g - w)) > (unsigned) l ? (unsigned) l : z;   /* upper limit on table size */
-             if ((f = 1 << (j = k - w)) > a + 1)       /* try a k-w bit table */
-               {               /* too few codes for k-w bit table */
-                 f -= a + 1;   /* deduct codes from patterns left */
-                 xp = c + k;
-                 while (++j < z)       /* try smaller tables up to z bits */
-                   {
-                     if ((f <<= 1) <= *++xp)
-                       break;  /* enough codes to use up j bits */
-                     f -= *xp; /* else deduct codes from patterns */
-                   }
-               }
-             z = 1 << j;       /* table entries for j-bit table */
-
-             /* allocate and link in new table */
-             q = (struct huft *) grub_malloc ((z + 1) * sizeof (struct huft));
-             if (! q)
-               {
-                 if (h)
-                   huft_free (u[0]);
-                 return 3;
-               }
-
-             *t = q + 1;       /* link to list for huft_free() */
-             *(t = &(q->v.t)) = (struct huft *) NULL;
-             u[h] = ++q;       /* table starts after link */
-
-             /* connect to last table, if there is one */
-             if (h)
-               {
-                 x[h] = i;     /* save pattern for backing up */
-                 r.b = (uch) l;        /* bits to dump before this table */
-                 r.e = (uch) (16 + j);         /* bits in this table */
-                 r.v.t = q;    /* pointer to this table */
-                 j = i >> (w - l);     /* (get around Turbo C bug) */
-                 u[h - 1][j] = r;      /* connect to last table */
-               }
-           }
-
-         /* set up table entry in r */
-         r.b = (uch) (k - w);
-         if (p >= v + n)
-           r.e = 99;           /* out of values--invalid code */
-         else if (*p < s)
-           {
-             r.e = (uch) (*p < 256 ? 16 : 15);         /* 256 is end-of-block code */
-             r.v.n = (ush) (*p);       /* simple code is just the value */
-             p++;              /* one compiler does not like *p++ */
-           }
-         else
-           {
-             r.e = (uch) e[*p - s];    /* non-simple--look up in lists */
-             r.v.n = d[*p++ - s];
-           }
-
-         /* fill code-like entries with r */
-         f = 1 << (k - w);
-         for (j = i >> w; j < z; j += f)
-           q[j] = r;
-
-         /* backwards increment the k-bit code i */
-         for (j = 1 << (k - 1); i & j; j >>= 1)
-           i ^= j;
-         i ^= j;
-
-         /* backup over finished tables */
-         while ((i & ((1 << w) - 1)) != x[h])
-           {
-             h--;              /* don't need to update q */
-             w -= l;
-           }
-       }
-    }
-
-  /* Return true (1) if we were given an incomplete table */
-  return y != 0 && g != 1;
-}
-
-
-/* Free the malloc'ed tables built by huft_build(), which makes a linked
-   list of the tables it made, with the links in a dummy first entry of
-   each table.  */
-static int
-huft_free (struct huft *t)
-{
-  register struct huft *p, *q;
-
-
-  /* Go through linked list, freeing from the malloced (t[-1]) address. */
-  p = t;
-  while (p != (struct huft *) NULL)
-    {
-      q = (--p)->v.t;
-      grub_free ((char *) p);
-      p = q;
-    }
-  return 0;
-}
-
-
-/*
- *  inflate (decompress) the codes in a deflated (compressed) block.
- *  Return an error code or zero if it all goes ok.
- */
-
-static int
-inflate_codes_in_window (grub_file_t file)
-{
-  register unsigned e;         /* table entry flag/number of extra bits */
-  unsigned n, d;               /* length and index for copy */
-  unsigned w;                  /* current window position */
-  struct huft *t;              /* pointer to table entry */
-  unsigned ml, md;             /* masks for bl and bd bits */
-  register ulg b;              /* bit buffer */
-  register unsigned k;         /* number of bits in bit buffer */
-  grub_gzio_t gzio = file->data;
-
-  /* make local copies of globals */
-  d = gzio->inflate_d;
-  n = gzio->inflate_n;
-  b = gzio->bb;                        /* initialize bit buffer */
-  k = gzio->bk;
-  w = gzio->wp;                        /* initialize window position */
-
-  /* inflate the coded data */
-  ml = mask_bits[gzio->bl];            /* precompute masks for speed */
-  md = mask_bits[gzio->bd];
-  for (;;)                     /* do until end of block */
-    {
-      if (! gzio->code_state)
-       {
-         NEEDBITS ((unsigned) gzio->bl);
-         if ((e = (t = gzio->tl + ((unsigned) b & ml))->e) > 16)
-           do
-             {
-               if (e == 99)
-                 {
-                   grub_error (GRUB_ERR_BAD_GZIP_DATA,
-                               "an unused code found");
-                   return 1;
-                 }
-               DUMPBITS (t->b);
-               e -= 16;
-               NEEDBITS (e);
-             }
-           while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16);
-         DUMPBITS (t->b);
-
-         if (e == 16)          /* then it's a literal */
-           {
-             gzio->slide[w++] = (uch) t->v.n;
-             if (w == WSIZE)
-               break;
-           }
-         else
-           /* it's an EOB or a length */
-           {
-             /* exit if end of block */
-             if (e == 15)
-               {
-                 gzio->block_len = 0;
-                 break;
-               }
-
-             /* get length of block to copy */
-             NEEDBITS (e);
-             n = t->v.n + ((unsigned) b & mask_bits[e]);
-             DUMPBITS (e);
-
-             /* decode distance of block to copy */
-             NEEDBITS ((unsigned) gzio->bd);
-             if ((e = (t = gzio->td + ((unsigned) b & md))->e) > 16)
-               do
-                 {
-                   if (e == 99)
-                     {
-                       grub_error (GRUB_ERR_BAD_GZIP_DATA,
-                                   "an unused code found");
-                       return 1;
-                     }
-                   DUMPBITS (t->b);
-                   e -= 16;
-                   NEEDBITS (e);
-                 }
-               while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e)
-                      > 16);
-             DUMPBITS (t->b);
-             NEEDBITS (e);
-             d = w - t->v.n - ((unsigned) b & mask_bits[e]);
-             DUMPBITS (e);
-             gzio->code_state++;
-           }
-       }
-
-      if (gzio->code_state)
-       {
-         /* do the copy */
-         do
-           {
-             n -= (e = (e = WSIZE - ((d &= WSIZE - 1) > w ? d : w)) > n ? n
-                   : e);
-
-             if (w - d >= e)
-               {
-                 grub_memmove (gzio->slide + w, gzio->slide + d, e);
-                 w += e;
-                 d += e;
-               }
-             else
-               /* purposefully use the overlap for extra copies here!! */
-               {
-                 while (e--)
-                   gzio->slide[w++] = gzio->slide[d++];
-               }
-
-             if (w == WSIZE)
-               break;
-           }
-         while (n);
-
-         if (! n)
-           gzio->code_state--;
-
-         /* did we break from the loop too soon? */
-         if (w == WSIZE)
-           break;
-       }
-    }
-
-  /* restore the globals from the locals */
-  gzio->inflate_d = d;
-  gzio->inflate_n = n;
-  gzio->wp = w;                        /* restore global window pointer */
-  gzio->bb = b;                        /* restore global bit buffer */
-  gzio->bk = k;
-
-  return ! gzio->block_len;
-}
-
-
-/* get header for an inflated type 0 (stored) block. */
-
-static void
-init_stored_block (grub_file_t file)
-{
-  register ulg b;              /* bit buffer */
-  register unsigned k;         /* number of bits in bit buffer */
-  grub_gzio_t gzio = file->data;
-
-  /* make local copies of globals */
-  b = gzio->bb;                        /* initialize bit buffer */
-  k = gzio->bk;
-
-  /* go to byte boundary */
-  DUMPBITS (k & 7);
-
-  /* get the length and its complement */
-  NEEDBITS (16);
-  gzio->block_len = ((unsigned) b & 0xffff);
-  DUMPBITS (16);
-  NEEDBITS (16);
-  if (gzio->block_len != (int) ((~b) & 0xffff))
-    grub_error (GRUB_ERR_BAD_GZIP_DATA,
-               "the length of a stored block does not match");
-  DUMPBITS (16);
-
-  /* restore global variables */
-  gzio->bb = b;
-  gzio->bk = k;
-}
-
-
-/* get header for an inflated type 1 (fixed Huffman codes) block.  We should
-   either replace this with a custom decoder, or at least precompute the
-   Huffman tables. */
-
-static void
-init_fixed_block (grub_file_t file)
-{
-  int i;                       /* temporary variable */
-  unsigned l[288];             /* length list for huft_build */
-  grub_gzio_t gzio = file->data;
-
-  /* set up literal table */
-  for (i = 0; i < 144; i++)
-    l[i] = 8;
-  for (; i < 256; i++)
-    l[i] = 9;
-  for (; i < 280; i++)
-    l[i] = 7;
-  for (; i < 288; i++)         /* make a complete, but wrong code set */
-    l[i] = 8;
-  gzio->bl = 7;
-  if (huft_build (l, 288, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0)
-    {
-      if (grub_errno == GRUB_ERR_NONE)
-       grub_error (GRUB_ERR_BAD_GZIP_DATA,
-                   "failed in building a Huffman code table");
-      return;
-    }
-
-  /* set up distance table */
-  for (i = 0; i < 30; i++)     /* make an incomplete code set */
-    l[i] = 5;
-  gzio->bd = 5;
-  if (huft_build (l, 30, 0, cpdist, cpdext, &gzio->td, &gzio->bd) > 1)
-    {
-      if (grub_errno == GRUB_ERR_NONE)
-       grub_error (GRUB_ERR_BAD_GZIP_DATA,
-                   "failed in building a Huffman code table");
-      huft_free (gzio->tl);
-      gzio->tl = 0;
-      return;
-    }
-
-  /* indicate we're now working on a block */
-  gzio->code_state = 0;
-  gzio->block_len++;
-}
-
-
-/* get header for an inflated type 2 (dynamic Huffman codes) block. */
-
-static void
-init_dynamic_block (grub_file_t file)
-{
-  int i;                       /* temporary variables */
-  unsigned j;
-  unsigned l;                  /* last length */
-  unsigned m;                  /* mask for bit lengths table */
-  unsigned n;                  /* number of lengths to get */
-  unsigned nb;                 /* number of bit length codes */
-  unsigned nl;                 /* number of literal/length codes */
-  unsigned nd;                 /* number of distance codes */
-  unsigned ll[286 + 30];       /* literal/length and distance code lengths */
-  register ulg b;              /* bit buffer */
-  register unsigned k;         /* number of bits in bit buffer */
-  grub_gzio_t gzio = file->data;
-
-  /* make local bit buffer */
-  b = gzio->bb;
-  k = gzio->bk;
-
-  /* read in table lengths */
-  NEEDBITS (5);
-  nl = 257 + ((unsigned) b & 0x1f);    /* number of literal/length codes */
-  DUMPBITS (5);
-  NEEDBITS (5);
-  nd = 1 + ((unsigned) b & 0x1f);      /* number of distance codes */
-  DUMPBITS (5);
-  NEEDBITS (4);
-  nb = 4 + ((unsigned) b & 0xf);       /* number of bit length codes */
-  DUMPBITS (4);
-  if (nl > 286 || nd > 30)
-    {
-      grub_error (GRUB_ERR_BAD_GZIP_DATA, "too much data");
-      return;
-    }
-
-  /* read in bit-length-code lengths */
-  for (j = 0; j < nb; j++)
-    {
-      NEEDBITS (3);
-      ll[bitorder[j]] = (unsigned) b & 7;
-      DUMPBITS (3);
-    }
-  for (; j < 19; j++)
-    ll[bitorder[j]] = 0;
-
-  /* build decoding table for trees--single level, 7 bit lookup */
-  gzio->bl = 7;
-  if (huft_build (ll, 19, 19, NULL, NULL, &gzio->tl, &gzio->bl) != 0)
-    {
-      grub_error (GRUB_ERR_BAD_GZIP_DATA,
-                 "failed in building a Huffman code table");
-      return;
-    }
-
-  /* read in literal and distance code lengths */
-  n = nl + nd;
-  m = mask_bits[gzio->bl];
-  i = l = 0;
-  while ((unsigned) i < n)
-    {
-      NEEDBITS ((unsigned) gzio->bl);
-      j = (gzio->td = gzio->tl + ((unsigned) b & m))->b;
-      DUMPBITS (j);
-      j = gzio->td->v.n;
-      if (j < 16)              /* length of code in bits (0..15) */
-       ll[i++] = l = j;        /* save last length in l */
-      else if (j == 16)                /* repeat last length 3 to 6 times */
-       {
-         NEEDBITS (2);
-         j = 3 + ((unsigned) b & 3);
-         DUMPBITS (2);
-         if ((unsigned) i + j > n)
-           {
-             grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found");
-             return;
-           }
-         while (j--)
-           ll[i++] = l;
-       }
-      else if (j == 17)                /* 3 to 10 zero length codes */
-       {
-         NEEDBITS (3);
-         j = 3 + ((unsigned) b & 7);
-         DUMPBITS (3);
-         if ((unsigned) i + j > n)
-           {
-             grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found");
-             return;
-           }
-         while (j--)
-           ll[i++] = 0;
-         l = 0;
-       }
-      else
-       /* j == 18: 11 to 138 zero length codes */
-       {
-         NEEDBITS (7);
-         j = 11 + ((unsigned) b & 0x7f);
-         DUMPBITS (7);
-         if ((unsigned) i + j > n)
-           {
-             grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found");
-             return;
-           }
-         while (j--)
-           ll[i++] = 0;
-         l = 0;
-       }
-    }
-
-  /* free decoding table for trees */
-  huft_free (gzio->tl);
-  gzio->td = 0;
-  gzio->tl = 0;
-
-  /* restore the global bit buffer */
-  gzio->bb = b;
-  gzio->bk = k;
-
-  /* build the decoding tables for literal/length and distance codes */
-  gzio->bl = lbits;
-  if (huft_build (ll, nl, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0)
-    {
-      grub_error (GRUB_ERR_BAD_GZIP_DATA,
-                 "failed in building a Huffman code table");
-      return;
-    }
-  gzio->bd = dbits;
-  if (huft_build (ll + nl, nd, 0, cpdist, cpdext, &gzio->td, &gzio->bd) != 0)
-    {
-      huft_free (gzio->tl);
-      gzio->tl = 0;
-      grub_error (GRUB_ERR_BAD_GZIP_DATA,
-                 "failed in building a Huffman code table");
-      return;
-    }
-
-  /* indicate we're now working on a block */
-  gzio->code_state = 0;
-  gzio->block_len++;
-}
-
-
-static void
-get_new_block (grub_file_t file)
-{
-  register ulg b;              /* bit buffer */
-  register unsigned k;         /* number of bits in bit buffer */
-  grub_gzio_t gzio = file->data;
-
-  /* make local bit buffer */
-  b = gzio->bb;
-  k = gzio->bk;
-
-  /* read in last block bit */
-  NEEDBITS (1);
-  gzio->last_block = (int) b & 1;
-  DUMPBITS (1);
-
-  /* read in block type */
-  NEEDBITS (2);
-  gzio->block_type = (unsigned) b & 3;
-  DUMPBITS (2);
-
-  /* restore the global bit buffer */
-  gzio->bb = b;
-  gzio->bk = k;
-
-  switch (gzio->block_type)
-    {
-    case INFLATE_STORED:
-      init_stored_block (file);
-      break;
-    case INFLATE_FIXED:
-      init_fixed_block (file);
-      break;
-    case INFLATE_DYNAMIC:
-      init_dynamic_block (file);
-      break;
-    default:
-      break;
-    }
-}
-
-
-static void
-inflate_window (grub_file_t file)
-{
-  grub_gzio_t gzio = file->data;
-
-  /* initialize window */
-  gzio->wp = 0;
-
-  /*
-   *  Main decompression loop.
-   */
-
-  while (gzio->wp < WSIZE && grub_errno == GRUB_ERR_NONE)
-    {
-      if (! gzio->block_len)
-       {
-         if (gzio->last_block)
-           break;
-
-         get_new_block (file);
-       }
-
-      if (gzio->block_type > INFLATE_DYNAMIC)
-       grub_error (GRUB_ERR_BAD_GZIP_DATA,
-                   "unknown block type %d", gzio->block_type);
-
-      if (grub_errno != GRUB_ERR_NONE)
-       return;
-
-      /*
-       *  Expand stored block here.
-       */
-      if (gzio->block_type == INFLATE_STORED)
-       {
-         int w = gzio->wp;
-
-         /*
-          *  This is basically a glorified pass-through
-          */
-
-         while (gzio->block_len && w < WSIZE && grub_errno == GRUB_ERR_NONE)
-           {
-             gzio->slide[w++] = get_byte (file);
-             gzio->block_len--;
-           }
-
-         gzio->wp = w;
-
-         continue;
-       }
-
-      /*
-       *  Expand other kind of block.
-       */
-
-      if (inflate_codes_in_window (file))
-       {
-         huft_free (gzio->tl);
-         huft_free (gzio->td);
-         gzio->tl = 0;
-         gzio->td = 0;
-       }
-    }
-
-  gzio->saved_offset += WSIZE;
-
-  /* XXX do CRC calculation here! */
-}
-
-
-static void
-initialize_tables (grub_file_t file)
-{
-  grub_gzio_t gzio = file->data;
-
-  gzio->saved_offset = 0;
-  grub_file_seek (gzio->file, gzio->data_offset);
-
-  /* Initialize the bit buffer.  */
-  gzio->bk = 0;
-  gzio->bb = 0;
-
-  /* Reset partial decompression code.  */
-  gzio->last_block = 0;
-  gzio->block_len = 0;
-
-  /* Reset memory allocation stuff.  */
-  huft_free (gzio->tl);
-  huft_free (gzio->td);
-}
-
-
-/* Open a new decompressing object on the top of IO. If TRANSPARENT is true,
-   even if IO does not contain data compressed by gzip, return a valid file
-   object. Note that this function won't close IO, even if an error occurs.  */
-grub_file_t
-grub_gzio_open (grub_file_t io, int transparent)
-{
-  grub_file_t file;
-  grub_gzio_t gzio = 0;
-
-  file = (grub_file_t) grub_malloc (sizeof (*file));
-  if (! file)
-    return 0;
-
-  gzio = grub_zalloc (sizeof (*gzio));
-  if (! gzio)
-    {
-      grub_free (file);
-      return 0;
-    }
-
-  gzio->file = io;
-
-  file->device = io->device;
-  file->offset = 0;
-  file->data = gzio;
-  file->read_hook = 0;
-  file->fs = &grub_gzio_fs;
-
-  if (! test_header (file))
-    {
-      grub_free (gzio);
-      grub_free (file);
-      grub_file_seek (io, 0);
-
-      if (grub_errno == GRUB_ERR_BAD_FILE_TYPE && transparent)
-       {
-         grub_errno = GRUB_ERR_NONE;
-         return io;
-       }
-      else
-       return 0;
-    }
-
-  return file;
-}
-
-/* This is similar to grub_gzio_open, but takes a file name as an argument.  */
-grub_file_t
-grub_gzfile_open (const char *name, int transparent)
-{
-  grub_file_t io, file;
-
-  io = grub_file_open (name);
-  if (! io)
-    return 0;
-
-  file = grub_gzio_open (io, transparent);
-  if (! file)
-    {
-      grub_file_close (io);
-      return 0;
-    }
-
-  return file;
-}
-
-static grub_ssize_t
-grub_gzio_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  grub_ssize_t ret = 0;
-  grub_gzio_t gzio = file->data;
-  grub_off_t offset;
-
-  /* Do we reset decompression to the beginning of the file?  */
-  if (gzio->saved_offset > file->offset + WSIZE)
-    initialize_tables (file);
-
-  /*
-   *  This loop operates upon uncompressed data only.  The only
-   *  special thing it does is to make sure the decompression
-   *  window is within the range of data it needs.
-   */
-
-  offset = file->offset;
-
-  while (len > 0 && grub_errno == GRUB_ERR_NONE)
-    {
-      register grub_size_t size;
-      register char *srcaddr;
-
-      while (offset >= gzio->saved_offset)
-       inflate_window (file);
-
-      srcaddr = (char *) ((offset & (WSIZE - 1)) + gzio->slide);
-      size = gzio->saved_offset - offset;
-      if (size > len)
-       size = len;
-
-      grub_memmove (buf, srcaddr, size);
-
-      buf += size;
-      len -= size;
-      ret += size;
-      offset += size;
-    }
-
-  if (grub_errno != GRUB_ERR_NONE)
-    ret = -1;
-
-  return ret;
-}
-
-/* Release everything, including the underlying file object.  */
-static grub_err_t
-grub_gzio_close (grub_file_t file)
-{
-  grub_gzio_t gzio = file->data;
-
-  grub_file_close (gzio->file);
-  huft_free (gzio->tl);
-  huft_free (gzio->td);
-  grub_free (gzio);
-
-  /* No need to close the same device twice.  */
-  file->device = 0;
-
-  return grub_errno;
-}
-
-\f
-
-static struct grub_fs grub_gzio_fs =
-  {
-    .name = "gzio",
-    .dir = 0,
-    .open = 0,
-    .read = grub_gzio_read,
-    .close = grub_gzio_close,
-    .label = 0,
-    .next = 0
-  };
diff --git a/kern/command.c b/kern/command.c
deleted file mode 100644 (file)
index 477240d..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* command.c - support basic command */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/command.h>
-
-grub_command_t grub_command_list;
-
-grub_command_t
-grub_register_command_prio (const char *name,
-                           grub_command_func_t func,
-                           const char *summary,
-                           const char *description,
-                           int prio)
-{
-  grub_command_t cmd;
-
-  cmd = (grub_command_t) grub_zalloc (sizeof (*cmd));
-  if (! cmd)
-    return 0;
-
-  cmd->name = name;
-  cmd->func = func;
-  cmd->summary = (summary) ? summary : "";
-  cmd->description = description;
-
-  cmd->flags = GRUB_COMMAND_FLAG_BOTH;
-  cmd->prio = prio;
-
-  grub_prio_list_insert (GRUB_AS_PRIO_LIST_P (&grub_command_list),
-                        GRUB_AS_PRIO_LIST (cmd));
-
-  return cmd;
-}
-
-void
-grub_unregister_command (grub_command_t cmd)
-{
-  grub_prio_list_remove (GRUB_AS_PRIO_LIST_P (&grub_command_list),
-                        GRUB_AS_PRIO_LIST (cmd));
-  grub_free (cmd);
-}
diff --git a/kern/corecmd.c b/kern/corecmd.c
deleted file mode 100644 (file)
index 9af706e..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-/* corecmd.c - critical commands which are registered in kernel */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/dl.h>
-#include <grub/err.h>
-#include <grub/env.h>
-#include <grub/misc.h>
-#include <grub/term.h>
-#include <grub/file.h>
-#include <grub/device.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-/* set ENVVAR=VALUE */
-static grub_err_t
-grub_core_cmd_set (struct grub_command *cmd __attribute__ ((unused)),
-                  int argc, char *argv[])
-{
-  char *var;
-  char *val;
-
-  auto int print_env (struct grub_env_var *env);
-
-  int print_env (struct grub_env_var *env)
-    {
-      grub_printf ("%s=%s\n", env->name, env->value);
-      return 0;
-    }
-
-  if (argc < 1)
-    {
-      grub_env_iterate (print_env);
-      return 0;
-    }
-
-  var = argv[0];
-  val = grub_strchr (var, '=');
-  if (! val)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "not an assignment");
-
-  val[0] = 0;
-  grub_env_set (var, val + 1);
-  val[0] = '=';
-
-  return 0;
-}
-
-static grub_err_t
-grub_core_cmd_unset (struct grub_command *cmd __attribute__ ((unused)),
-                    int argc, char *argv[])
-{
-  if (argc < 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "no environment variable specified");
-
-  grub_env_unset (argv[0]);
-  return 0;
-}
-
-/* insmod MODULE */
-static grub_err_t
-grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)),
-                     int argc, char *argv[])
-{
-  char *p;
-  grub_dl_t mod;
-
-  if (argc == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
-
-  p = grub_strchr (argv[0], '/');
-  if (! p)
-    mod = grub_dl_load (argv[0]);
-  else
-    mod = grub_dl_load_file (argv[0]);
-
-  if (mod)
-    grub_dl_ref (mod);
-
-  return 0;
-}
-
-static int
-grub_mini_print_devices (const char *name)
-{
-  grub_printf ("(%s) ", name);
-
-  return 0;
-}
-
-static int
-grub_mini_print_files (const char *filename,
-                      const struct grub_dirhook_info *info)
-{
-  grub_printf ("%s%s ", filename, info->dir ? "/" : "");
-
-  return 0;
-}
-
-/* ls [ARG] */
-static grub_err_t
-grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
-                 int argc, char *argv[])
-{
-  if (argc < 1)
-    {
-      grub_device_iterate (grub_mini_print_devices);
-      grub_putchar ('\n');
-      grub_refresh ();
-    }
-  else
-    {
-      char *device_name;
-      grub_device_t dev;
-      grub_fs_t fs;
-      char *path;
-
-      device_name = grub_file_get_device_name (argv[0]);
-      dev = grub_device_open (device_name);
-      if (! dev)
-       goto fail;
-
-      fs = grub_fs_probe (dev);
-      path = grub_strchr (argv[0], ')');
-      if (! path)
-       path = argv[0];
-      else
-       path++;
-
-      if (! path && ! device_name)
-       {
-         grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
-         goto fail;
-       }
-
-      if (! path)
-       {
-         if (grub_errno == GRUB_ERR_UNKNOWN_FS)
-           grub_errno = GRUB_ERR_NONE;
-
-         grub_printf ("(%s): Filesystem is %s.\n",
-                      device_name, fs ? fs->name : "unknown");
-       }
-      else if (fs)
-       {
-         (fs->dir) (dev, path, grub_mini_print_files);
-         grub_putchar ('\n');
-         grub_refresh ();
-       }
-
-    fail:
-      if (dev)
-       grub_device_close (dev);
-
-      grub_free (device_name);
-    }
-
-  return grub_errno;
-}
-
-void
-grub_register_core_commands (void)
-{
-  grub_register_command ("set", grub_core_cmd_set,
-                        N_("[ENVVAR=VALUE]"),
-                        N_("Set an environment variable."));
-  grub_register_command ("unset", grub_core_cmd_unset,
-                        N_("ENVVAR"),
-                        N_("Remove an environment variable."));
-  grub_register_command ("ls", grub_core_cmd_ls,
-                        N_("[ARG]"), N_("List devices or files."));
-  grub_register_command ("insmod", grub_core_cmd_insmod,
-                        N_("MODULE"), N_("Insert a module."));
-}
diff --git a/kern/device.c b/kern/device.c
deleted file mode 100644 (file)
index 4273fed..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/* device.c - device manager */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/device.h>
-#include <grub/disk.h>
-#include <grub/net.h>
-#include <grub/fs.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/env.h>
-#include <grub/partition.h>
-
-grub_device_t
-grub_device_open (const char *name)
-{
-  grub_disk_t disk = 0;
-  grub_device_t dev = 0;
-
-  if (! name)
-    {
-      name = grub_env_get ("root");
-      if (*name == '\0')
-       {
-         grub_error (GRUB_ERR_BAD_DEVICE, "no device is set");
-         goto fail;
-       }
-    }
-
-  dev = grub_malloc (sizeof (*dev));
-  if (! dev)
-    goto fail;
-
-  /* Try to open a disk.  */
-  disk = grub_disk_open (name);
-  if (! disk)
-    goto fail;
-
-  dev->disk = disk;
-  dev->net = 0;        /* FIXME */
-
-  return dev;
-
- fail:
-  if (disk)
-    grub_disk_close (disk);
-
-  grub_free (dev);
-
-  return 0;
-}
-
-grub_err_t
-grub_device_close (grub_device_t device)
-{
-  if (device->disk)
-    grub_disk_close (device->disk);
-
-  grub_free (device);
-
-  return grub_errno;
-}
-
-int
-grub_device_iterate (int (*hook) (const char *name))
-{
-  auto int iterate_disk (const char *disk_name);
-  auto int iterate_partition (grub_disk_t disk,
-                             const grub_partition_t partition);
-
-  struct part_ent
-  {
-    struct part_ent *next;
-    char *name;
-  } *ents;
-
-  int iterate_disk (const char *disk_name)
-    {
-      grub_device_t dev;
-
-      if (hook (disk_name))
-       return 1;
-
-      dev = grub_device_open (disk_name);
-      if (! dev)
-       {
-         grub_errno = GRUB_ERR_NONE;
-         return 0;
-       }
-
-      if (dev->disk && dev->disk->has_partitions)
-       {
-         struct part_ent *p;
-         int ret = 0;
-
-         ents = NULL;
-         (void) grub_partition_iterate (dev->disk, iterate_partition);
-         grub_device_close (dev);
-
-         grub_errno = GRUB_ERR_NONE;
-
-         p = ents;
-         while (p != NULL)
-           {
-             struct part_ent *next = p->next;
-
-             if (!ret)
-               ret = hook (p->name);
-             grub_free (p->name);
-             grub_free (p);
-             p = next;
-           }
-
-         return ret;
-       }
-
-      grub_device_close (dev);
-      return 0;
-    }
-
-  int iterate_partition (grub_disk_t disk, const grub_partition_t partition)
-    {
-      char *partition_name;
-      struct part_ent *p;
-
-      partition_name = grub_partition_get_name (partition);
-      if (! partition_name)
-       return 1;
-
-      p = grub_malloc (sizeof (*p));
-      if (!p)
-       {
-         grub_free (partition_name);
-         return 1;
-       }
-
-      p->name = grub_xasprintf ("%s,%s", disk->name, partition_name);
-      if (!p->name)
-       {
-         grub_free (partition_name);
-         grub_free (p);
-         return 1;
-       }
-      grub_free (partition_name);
-
-      p->next = ents;
-      ents = p;
-
-      return 0;
-    }
-
-  /* Only disk devices are supported at the moment.  */
-  return grub_disk_dev_iterate (iterate_disk);
-}
diff --git a/kern/disk.c b/kern/disk.c
deleted file mode 100644 (file)
index ccd5f20..0000000
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/disk.h>
-#include <grub/err.h>
-#include <grub/mm.h>
-#include <grub/types.h>
-#include <grub/partition.h>
-#include <grub/misc.h>
-#include <grub/time.h>
-#include <grub/file.h>
-
-#define        GRUB_CACHE_TIMEOUT      2
-
-/* The last time the disk was used.  */
-static grub_uint64_t grub_last_time = 0;
-
-
-/* Disk cache.  */
-struct grub_disk_cache
-{
-  enum grub_disk_dev_id dev_id;
-  unsigned long disk_id;
-  grub_disk_addr_t sector;
-  char *data;
-  int lock;
-};
-
-static struct grub_disk_cache grub_disk_cache_table[GRUB_DISK_CACHE_NUM];
-
-void (*grub_disk_firmware_fini) (void);
-int grub_disk_firmware_is_tainted;
-
-grub_err_t (* grub_disk_ata_pass_through) (grub_disk_t,
-           struct grub_disk_ata_pass_through_parms *);
-
-
-#if 0
-static unsigned long grub_disk_cache_hits;
-static unsigned long grub_disk_cache_misses;
-
-void
-grub_disk_cache_get_performance (unsigned long *hits, unsigned long *misses)
-{
-  *hits = grub_disk_cache_hits;
-  *misses = grub_disk_cache_misses;
-}
-#endif
-
-static unsigned
-grub_disk_cache_get_index (unsigned long dev_id, unsigned long disk_id,
-                          grub_disk_addr_t sector)
-{
-  return ((dev_id * 524287UL + disk_id * 2606459UL
-          + ((unsigned) (sector >> GRUB_DISK_CACHE_BITS)))
-         % GRUB_DISK_CACHE_NUM);
-}
-
-static void
-grub_disk_cache_invalidate (unsigned long dev_id, unsigned long disk_id,
-                           grub_disk_addr_t sector)
-{
-  unsigned index;
-  struct grub_disk_cache *cache;
-
-  sector &= ~(GRUB_DISK_CACHE_SIZE - 1);
-  index = grub_disk_cache_get_index (dev_id, disk_id, sector);
-  cache = grub_disk_cache_table + index;
-
-  if (cache->dev_id == dev_id && cache->disk_id == disk_id
-      && cache->sector == sector && cache->data)
-    {
-      cache->lock = 1;
-      grub_free (cache->data);
-      cache->data = 0;
-      cache->lock = 0;
-    }
-}
-
-void
-grub_disk_cache_invalidate_all (void)
-{
-  unsigned i;
-
-  for (i = 0; i < GRUB_DISK_CACHE_NUM; i++)
-    {
-      struct grub_disk_cache *cache = grub_disk_cache_table + i;
-
-      if (cache->data && ! cache->lock)
-       {
-         grub_free (cache->data);
-         cache->data = 0;
-       }
-    }
-}
-
-static char *
-grub_disk_cache_fetch (unsigned long dev_id, unsigned long disk_id,
-                      grub_disk_addr_t sector)
-{
-  struct grub_disk_cache *cache;
-  unsigned index;
-
-  index = grub_disk_cache_get_index (dev_id, disk_id, sector);
-  cache = grub_disk_cache_table + index;
-
-  if (cache->dev_id == dev_id && cache->disk_id == disk_id
-      && cache->sector == sector)
-    {
-      cache->lock = 1;
-#if 0
-      grub_disk_cache_hits++;
-#endif
-      return cache->data;
-    }
-
-#if 0
-  grub_disk_cache_misses++;
-#endif
-
-  return 0;
-}
-
-static void
-grub_disk_cache_unlock (unsigned long dev_id, unsigned long disk_id,
-                       grub_disk_addr_t sector)
-{
-  struct grub_disk_cache *cache;
-  unsigned index;
-
-  index = grub_disk_cache_get_index (dev_id, disk_id, sector);
-  cache = grub_disk_cache_table + index;
-
-  if (cache->dev_id == dev_id && cache->disk_id == disk_id
-      && cache->sector == sector)
-    cache->lock = 0;
-}
-
-static grub_err_t
-grub_disk_cache_store (unsigned long dev_id, unsigned long disk_id,
-                      grub_disk_addr_t sector, const char *data)
-{
-  unsigned index;
-  struct grub_disk_cache *cache;
-
-  index = grub_disk_cache_get_index (dev_id, disk_id, sector);
-  cache = grub_disk_cache_table + index;
-
-  cache->lock = 1;
-  grub_free (cache->data);
-  cache->data = 0;
-  cache->lock = 0;
-
-  cache->data = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS);
-  if (! cache->data)
-    return grub_errno;
-
-  grub_memcpy (cache->data, data,
-              GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS);
-  cache->dev_id = dev_id;
-  cache->disk_id = disk_id;
-  cache->sector = sector;
-
-  return GRUB_ERR_NONE;
-}
-
-\f
-
-static grub_disk_dev_t grub_disk_dev_list;
-
-void
-grub_disk_dev_register (grub_disk_dev_t dev)
-{
-  dev->next = grub_disk_dev_list;
-  grub_disk_dev_list = dev;
-}
-
-void
-grub_disk_dev_unregister (grub_disk_dev_t dev)
-{
-  grub_disk_dev_t *p, q;
-
-  for (p = &grub_disk_dev_list, q = *p; q; p = &(q->next), q = q->next)
-    if (q == dev)
-      {
-        *p = q->next;
-       break;
-      }
-}
-
-int
-grub_disk_dev_iterate (int (*hook) (const char *name))
-{
-  grub_disk_dev_t p;
-
-  for (p = grub_disk_dev_list; p; p = p->next)
-    if (p->iterate && (p->iterate) (hook))
-      return 1;
-
-  return 0;
-}
-
-/* Return the location of the first ',', if any, which is not
-   escaped by a '\'.  */
-static const char *
-find_part_sep (const char *name)
-{
-  const char *p = name;
-  char c;
-
-  while ((c = *p++) != '\0')
-    {
-      if (c == '\\' && *p == ',')
-       p++;
-      else if (c == ',')
-       return p - 1;
-    }
-  return NULL;
-}
-
-grub_disk_t
-grub_disk_open (const char *name)
-{
-  const char *p;
-  grub_disk_t disk;
-  grub_disk_dev_t dev;
-  char *raw = (char *) name;
-  grub_uint64_t current_time;
-
-  grub_dprintf ("disk", "Opening `%s'...\n", name);
-
-  disk = (grub_disk_t) grub_zalloc (sizeof (*disk));
-  if (! disk)
-    return 0;
-
-  disk->name = grub_strdup (name);
-  if (! disk->name)
-    goto fail;
-
-  p = find_part_sep (name);
-  if (p)
-    {
-      grub_size_t len = p - name;
-
-      raw = grub_malloc (len + 1);
-      if (! raw)
-       goto fail;
-
-      grub_memcpy (raw, name, len);
-      raw[len] = '\0';
-    }
-
-  for (dev = grub_disk_dev_list; dev; dev = dev->next)
-    {
-      if ((dev->open) (raw, disk) == GRUB_ERR_NONE)
-       break;
-      else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE)
-       grub_errno = GRUB_ERR_NONE;
-      else
-       goto fail;
-    }
-
-  if (! dev)
-    {
-      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such disk");
-      goto fail;
-    }
-
-  if (p && ! disk->has_partitions)
-    {
-      grub_error (GRUB_ERR_BAD_DEVICE, "no partition on this disk");
-      goto fail;
-    }
-
-  disk->dev = dev;
-
-  if (p)
-    {
-      disk->partition = grub_partition_probe (disk, p + 1);
-      if (! disk->partition)
-       {
-         grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such partition");
-         goto fail;
-       }
-    }
-
-  /* The cache will be invalidated about 2 seconds after a device was
-     closed.  */
-  current_time = grub_get_time_ms ();
-
-  if (current_time > (grub_last_time
-                     + GRUB_CACHE_TIMEOUT * 1000))
-    grub_disk_cache_invalidate_all ();
-
-  grub_last_time = current_time;
-
- fail:
-
-  if (raw && raw != name)
-    grub_free (raw);
-
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_error_push ();
-      grub_dprintf ("disk", "Opening `%s' failed.\n", name);
-      grub_error_pop ();
-
-      grub_disk_close (disk);
-      return 0;
-    }
-
-  return disk;
-}
-
-void
-grub_disk_close (grub_disk_t disk)
-{
-  grub_partition_t part;
-  grub_dprintf ("disk", "Closing `%s'.\n", disk->name);
-
-  if (disk->dev && disk->dev->close)
-    (disk->dev->close) (disk);
-
-  /* Reset the timer.  */
-  grub_last_time = grub_get_time_ms ();
-
-  while (disk->partition)
-    {
-      part = disk->partition->parent;
-      grub_free (disk->partition);
-      disk->partition = part;
-    }
-  grub_free ((void *) disk->name);
-  grub_free (disk);
-}
-
-/* This function performs three tasks:
-   - Make sectors disk relative from partition relative.
-   - Normalize offset to be less than the sector size.
-   - Verify that the range is inside the partition.  */
-static grub_err_t
-grub_disk_adjust_range (grub_disk_t disk, grub_disk_addr_t *sector,
-                       grub_off_t *offset, grub_size_t size)
-{
-  grub_partition_t part;
-  *sector += *offset >> GRUB_DISK_SECTOR_BITS;
-  *offset &= GRUB_DISK_SECTOR_SIZE - 1;
-
-  for (part = disk->partition; part; part = part->parent)
-    {
-      grub_disk_addr_t start;
-      grub_uint64_t len;
-
-      start = part->start;
-      len = part->len;
-
-      if (*sector >= len
-         || len - *sector < ((*offset + size + GRUB_DISK_SECTOR_SIZE - 1)
-                             >> GRUB_DISK_SECTOR_BITS))
-       return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of partition");
-
-      *sector += start;
-    }
-
-  if (disk->total_sectors <= *sector
-      || ((*offset + size + GRUB_DISK_SECTOR_SIZE - 1)
-         >> GRUB_DISK_SECTOR_BITS) > disk->total_sectors - *sector)
-    return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of disk");
-
-  return GRUB_ERR_NONE;
-}
-
-/* Read data from the disk.  */
-grub_err_t
-grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
-               grub_off_t offset, grub_size_t size, void *buf)
-{
-  char *tmp_buf;
-  unsigned real_offset;
-
-  /* First of all, check if the region is within the disk.  */
-  if (grub_disk_adjust_range (disk, &sector, &offset, size) != GRUB_ERR_NONE)
-    {
-      grub_error_push ();
-      grub_dprintf ("disk", "Read out of range: sector 0x%llx (%s).\n",
-                   (unsigned long long) sector, grub_errmsg);
-      grub_error_pop ();
-      return grub_errno;
-    }
-
-  real_offset = offset;
-
-  /* Allocate a temporary buffer.  */
-  tmp_buf = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS);
-  if (! tmp_buf)
-    return grub_errno;
-
-  /* Until SIZE is zero...  */
-  while (size)
-    {
-      char *data;
-      grub_disk_addr_t start_sector;
-      grub_size_t len;
-      grub_size_t pos;
-
-      /* For reading bulk data.  */
-      start_sector = sector & ~(GRUB_DISK_CACHE_SIZE - 1);
-      pos = (sector - start_sector) << GRUB_DISK_SECTOR_BITS;
-      len = ((GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS)
-            - pos - real_offset);
-      if (len > size)
-       len = size;
-
-      /* Fetch the cache.  */
-      data = grub_disk_cache_fetch (disk->dev->id, disk->id, start_sector);
-      if (data)
-       {
-         /* Just copy it!  */
-         grub_memcpy (buf, data + pos + real_offset, len);
-         grub_disk_cache_unlock (disk->dev->id, disk->id, start_sector);
-       }
-      else
-       {
-         /* Otherwise read data from the disk actually.  */
-         if (start_sector + GRUB_DISK_CACHE_SIZE > disk->total_sectors
-             || (disk->dev->read) (disk, start_sector,
-                                   GRUB_DISK_CACHE_SIZE, tmp_buf)
-             != GRUB_ERR_NONE)
-           {
-             /* Uggh... Failed. Instead, just read necessary data.  */
-             unsigned num;
-             char *p;
-
-             grub_errno = GRUB_ERR_NONE;
-
-             num = ((size + real_offset + GRUB_DISK_SECTOR_SIZE - 1)
-                    >> GRUB_DISK_SECTOR_BITS);
-
-             p = grub_realloc (tmp_buf, num << GRUB_DISK_SECTOR_BITS);
-             if (!p)
-               goto finish;
-
-             tmp_buf = p;
-
-             if ((disk->dev->read) (disk, sector, num, tmp_buf))
-               {
-                 grub_error_push ();
-                 grub_dprintf ("disk", "%s read failed\n", disk->name);
-                 grub_error_pop ();
-                 goto finish;
-               }
-
-             grub_memcpy (buf, tmp_buf + real_offset, size);
-
-             /* Call the read hook, if any.  */
-             if (disk->read_hook)
-               while (size)
-                 {
-                   grub_size_t to_read = (size > GRUB_DISK_SECTOR_SIZE) ? GRUB_DISK_SECTOR_SIZE : size;
-                   (disk->read_hook) (sector, real_offset,
-                                      to_read);
-                   if (grub_errno != GRUB_ERR_NONE)
-                     goto finish;
-
-                   sector++;
-                   size -= to_read - real_offset;
-                   real_offset = 0;
-                 }
-
-             /* This must be the end.  */
-             goto finish;
-           }
-
-         /* Copy it and store it in the disk cache.  */
-         grub_memcpy (buf, tmp_buf + pos + real_offset, len);
-         grub_disk_cache_store (disk->dev->id, disk->id,
-                                start_sector, tmp_buf);
-       }
-
-      /* Call the read hook, if any.  */
-      if (disk->read_hook)
-       {
-         grub_disk_addr_t s = sector;
-         grub_size_t l = len;
-
-         while (l)
-           {
-             (disk->read_hook) (s, real_offset,
-                                ((l > GRUB_DISK_SECTOR_SIZE)
-                                 ? GRUB_DISK_SECTOR_SIZE
-                                 : l));
-
-             if (l < GRUB_DISK_SECTOR_SIZE - real_offset)
-               break;
-
-             s++;
-             l -= GRUB_DISK_SECTOR_SIZE - real_offset;
-             real_offset = 0;
-           }
-       }
-
-      sector = start_sector + GRUB_DISK_CACHE_SIZE;
-      buf = (char *) buf + len;
-      size -= len;
-      real_offset = 0;
-    }
-
- finish:
-
-  grub_free (tmp_buf);
-
-  return grub_errno;
-}
-
-grub_err_t
-grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector,
-                grub_off_t offset, grub_size_t size, const void *buf)
-{
-  unsigned real_offset;
-
-  grub_dprintf ("disk", "Writing `%s'...\n", disk->name);
-
-  if (grub_disk_adjust_range (disk, &sector, &offset, size) != GRUB_ERR_NONE)
-    return -1;
-
-  real_offset = offset;
-
-  while (size)
-    {
-      if (real_offset != 0 || (size < GRUB_DISK_SECTOR_SIZE && size != 0))
-       {
-         char tmp_buf[GRUB_DISK_SECTOR_SIZE];
-         grub_size_t len;
-         grub_partition_t part;
-
-         part = disk->partition;
-         disk->partition = 0;
-         if (grub_disk_read (disk, sector, 0, GRUB_DISK_SECTOR_SIZE, tmp_buf)
-             != GRUB_ERR_NONE)
-           {
-             disk->partition = part;
-             goto finish;
-           }
-         disk->partition = part;
-
-         len = GRUB_DISK_SECTOR_SIZE - real_offset;
-         if (len > size)
-           len = size;
-
-         grub_memcpy (tmp_buf + real_offset, buf, len);
-
-         grub_disk_cache_invalidate (disk->dev->id, disk->id, sector);
-
-         if ((disk->dev->write) (disk, sector, 1, tmp_buf) != GRUB_ERR_NONE)
-           goto finish;
-
-         sector++;
-         buf = (char *) buf + len;
-         size -= len;
-         real_offset = 0;
-       }
-      else
-       {
-         grub_size_t len;
-         grub_size_t n;
-
-         len = size & ~(GRUB_DISK_SECTOR_SIZE - 1);
-         n = size >> GRUB_DISK_SECTOR_BITS;
-
-         if ((disk->dev->write) (disk, sector, n, buf) != GRUB_ERR_NONE)
-           goto finish;
-
-         while (n--)
-           grub_disk_cache_invalidate (disk->dev->id, disk->id, sector++);
-
-         buf = (char *) buf + len;
-         size -= len;
-       }
-    }
-
- finish:
-
-  return grub_errno;
-}
-
-grub_uint64_t
-grub_disk_get_size (grub_disk_t disk)
-{
-  if (disk->partition)
-    return grub_partition_get_len (disk->partition);
-  else
-    return disk->total_sectors;
-}
diff --git a/kern/dl.c b/kern/dl.c
deleted file mode 100644 (file)
index 19ee132..0000000
--- a/kern/dl.c
+++ /dev/null
@@ -1,722 +0,0 @@
-/* dl.c - loadable module support */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Force native word size */
-#define GRUB_TARGET_WORDSIZE (8 * GRUB_CPU_SIZEOF_VOID_P)
-
-#include <config.h>
-#include <grub/elf.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/symbol.h>
-#include <grub/file.h>
-#include <grub/env.h>
-#include <grub/cache.h>
-
-/* Platforms where modules are in a readonly area of memory.  */
-#if defined(GRUB_MACHINE_QEMU)
-#define GRUB_MODULES_MACHINE_READONLY
-#endif
-
-\f
-
-struct grub_dl_list
-{
-  struct grub_dl_list *next;
-  grub_dl_t mod;
-};
-typedef struct grub_dl_list *grub_dl_list_t;
-
-static grub_dl_list_t grub_dl_head;
-
-static grub_err_t
-grub_dl_add (grub_dl_t mod)
-{
-  grub_dl_list_t l;
-
-  if (grub_dl_get (mod->name))
-    return grub_error (GRUB_ERR_BAD_MODULE,
-                      "`%s' is already loaded", mod->name);
-
-  l = (grub_dl_list_t) grub_malloc (sizeof (*l));
-  if (! l)
-    return grub_errno;
-
-  l->mod = mod;
-  l->next = grub_dl_head;
-  grub_dl_head = l;
-
-  return GRUB_ERR_NONE;
-}
-
-static void
-grub_dl_remove (grub_dl_t mod)
-{
-  grub_dl_list_t *p, q;
-
-  for (p = &grub_dl_head, q = *p; q; p = &q->next, q = *p)
-    if (q->mod == mod)
-      {
-       *p = q->next;
-       grub_free (q);
-       return;
-      }
-}
-
-grub_dl_t
-grub_dl_get (const char *name)
-{
-  grub_dl_list_t l;
-
-  for (l = grub_dl_head; l; l = l->next)
-    if (grub_strcmp (name, l->mod->name) == 0)
-      return l->mod;
-
-  return 0;
-}
-
-void
-grub_dl_iterate (int (*hook) (grub_dl_t mod))
-{
-  grub_dl_list_t l;
-
-  for (l = grub_dl_head; l; l = l->next)
-    if (hook (l->mod))
-      break;
-}
-
-\f
-
-struct grub_symbol
-{
-  struct grub_symbol *next;
-  const char *name;
-  void *addr;
-  grub_dl_t mod;       /* The module to which this symbol belongs.  */
-};
-typedef struct grub_symbol *grub_symbol_t;
-
-/* The size of the symbol table.  */
-#define GRUB_SYMTAB_SIZE       509
-
-/* The symbol table (using an open-hash).  */
-static struct grub_symbol *grub_symtab[GRUB_SYMTAB_SIZE];
-
-/* Simple hash function.  */
-static unsigned
-grub_symbol_hash (const char *s)
-{
-  unsigned key = 0;
-
-  while (*s)
-    key = key * 65599 + *s++;
-
-  return (key + (key >> 5)) % GRUB_SYMTAB_SIZE;
-}
-
-/* Resolve the symbol name NAME and return the address.
-   Return NULL, if not found.  */
-static void *
-grub_dl_resolve_symbol (const char *name)
-{
-  grub_symbol_t sym;
-
-  for (sym = grub_symtab[grub_symbol_hash (name)]; sym; sym = sym->next)
-    if (grub_strcmp (sym->name, name) == 0)
-      return sym->addr;
-
-  return 0;
-}
-
-/* Register a symbol with the name NAME and the address ADDR.  */
-grub_err_t
-grub_dl_register_symbol (const char *name, void *addr, grub_dl_t mod)
-{
-  grub_symbol_t sym;
-  unsigned k;
-
-  sym = (grub_symbol_t) grub_malloc (sizeof (*sym));
-  if (! sym)
-    return grub_errno;
-
-  if (mod)
-    {
-      sym->name = grub_strdup (name);
-      if (! sym->name)
-       {
-         grub_free (sym);
-         return grub_errno;
-       }
-    }
-  else
-    sym->name = name;
-
-  sym->addr = addr;
-  sym->mod = mod;
-
-  k = grub_symbol_hash (name);
-  sym->next = grub_symtab[k];
-  grub_symtab[k] = sym;
-
-  return GRUB_ERR_NONE;
-}
-
-/* Unregister all the symbols defined in the module MOD.  */
-static void
-grub_dl_unregister_symbols (grub_dl_t mod)
-{
-  unsigned i;
-
-  if (! mod)
-    grub_fatal ("core symbols cannot be unregistered");
-
-  for (i = 0; i < GRUB_SYMTAB_SIZE; i++)
-    {
-      grub_symbol_t sym, *p, q;
-
-      for (p = &grub_symtab[i], sym = *p; sym; sym = q)
-       {
-         q = sym->next;
-         if (sym->mod == mod)
-           {
-             *p = q;
-             grub_free ((void *) sym->name);
-             grub_free (sym);
-           }
-         else
-           p = &sym->next;
-       }
-    }
-}
-
-/* Return the address of a section whose index is N.  */
-static void *
-grub_dl_get_section_addr (grub_dl_t mod, unsigned n)
-{
-  grub_dl_segment_t seg;
-
-  for (seg = mod->segment; seg; seg = seg->next)
-    if (seg->section == n)
-      return seg->addr;
-
-  return 0;
-}
-
-/* Check if EHDR is a valid ELF header.  */
-static grub_err_t
-grub_dl_check_header (void *ehdr, grub_size_t size)
-{
-  Elf_Ehdr *e = ehdr;
-
-  /* Check the header size.  */
-  if (size < sizeof (Elf_Ehdr))
-    return grub_error (GRUB_ERR_BAD_OS, "ELF header smaller than expected");
-
-  /* Check the magic numbers.  */
-  if (grub_arch_dl_check_header (ehdr)
-      || 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;
-}
-
-/* Load all segments from memory specified by E.  */
-static grub_err_t
-grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
-{
-  unsigned i;
-  Elf_Shdr *s;
-
-  for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
-    {
-      if (s->sh_flags & SHF_ALLOC)
-       {
-         grub_dl_segment_t seg;
-
-         seg = (grub_dl_segment_t) grub_malloc (sizeof (*seg));
-         if (! seg)
-           return grub_errno;
-
-         if (s->sh_size)
-           {
-             void *addr;
-
-             addr = grub_memalign (s->sh_addralign, s->sh_size);
-             if (! addr)
-               {
-                 grub_free (seg);
-                 return grub_errno;
-               }
-
-             switch (s->sh_type)
-               {
-               case SHT_PROGBITS:
-                 grub_memcpy (addr, (char *) e + s->sh_offset, s->sh_size);
-                 break;
-               case SHT_NOBITS:
-                 grub_memset (addr, 0, s->sh_size);
-                 break;
-               }
-
-             seg->addr = addr;
-           }
-         else
-           seg->addr = 0;
-
-         seg->size = s->sh_size;
-         seg->section = i;
-         seg->next = mod->segment;
-         mod->segment = seg;
-       }
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
-{
-  unsigned i;
-  Elf_Shdr *s;
-  Elf_Sym *sym;
-  const char *str;
-  Elf_Word size, entsize;
-
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_SYMTAB)
-      break;
-
-  if (i == e->e_shnum)
-    return grub_error (GRUB_ERR_BAD_MODULE, "no symbol table");
-
-#ifdef GRUB_MODULES_MACHINE_READONLY
-  mod->symtab = grub_malloc (s->sh_size);
-  memcpy (mod->symtab, (char *) e + s->sh_offset, s->sh_size);
-#else
-  mod->symtab = (Elf_Sym *) ((char *) e + s->sh_offset);
-#endif
-  sym = mod->symtab;
-  size = s->sh_size;
-  entsize = s->sh_entsize;
-
-  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
-  str = (char *) e + s->sh_offset;
-
-  for (i = 0;
-       i < size / entsize;
-       i++, sym = (Elf_Sym *) ((char *) sym + entsize))
-    {
-      unsigned char type = ELF_ST_TYPE (sym->st_info);
-      unsigned char bind = ELF_ST_BIND (sym->st_info);
-      const char *name = str + sym->st_name;
-
-      switch (type)
-       {
-       case STT_NOTYPE:
-       case STT_OBJECT:
-         /* Resolve a global symbol.  */
-         if (sym->st_name != 0 && sym->st_shndx == 0)
-           {
-             sym->st_value = (Elf_Addr) grub_dl_resolve_symbol (name);
-             if (! sym->st_value)
-               return grub_error (GRUB_ERR_BAD_MODULE,
-                                  "symbol not found: `%s'", name);
-           }
-         else
-           {
-             sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
-                                                                   sym->st_shndx);
-             if (bind != STB_LOCAL)
-               if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
-                 return grub_errno;
-           }
-         break;
-
-       case STT_FUNC:
-         sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod,
-                                                               sym->st_shndx);
-         if (bind != STB_LOCAL)
-           if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
-             return grub_errno;
-
-         if (grub_strcmp (name, "grub_mod_init") == 0)
-           mod->init = (void (*) (grub_dl_t)) sym->st_value;
-         else if (grub_strcmp (name, "grub_mod_fini") == 0)
-           mod->fini = (void (*) (void)) sym->st_value;
-         break;
-
-       case STT_SECTION:
-         sym->st_value = (Elf_Addr) grub_dl_get_section_addr (mod,
-                                                              sym->st_shndx);
-         break;
-
-       case STT_FILE:
-         sym->st_value = 0;
-         break;
-
-       default:
-         return grub_error (GRUB_ERR_BAD_MODULE,
-                            "unknown symbol type `%d'", (int) type);
-       }
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-static void
-grub_dl_call_init (grub_dl_t mod)
-{
-  if (mod->init)
-    (mod->init) (mod);
-}
-
-static grub_err_t
-grub_dl_resolve_name (grub_dl_t mod, Elf_Ehdr *e)
-{
-  Elf_Shdr *s;
-  const char *str;
-  unsigned i;
-
-  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize);
-  str = (char *) e + s->sh_offset;
-
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (grub_strcmp (str + s->sh_name, ".modname") == 0)
-      {
-       mod->name = grub_strdup ((char *) e + s->sh_offset);
-       if (! mod->name)
-         return grub_errno;
-       break;
-      }
-
-  if (i == e->e_shnum)
-    return grub_error (GRUB_ERR_BAD_MODULE, "no module name found");
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_dl_resolve_dependencies (grub_dl_t mod, Elf_Ehdr *e)
-{
-  Elf_Shdr *s;
-  const char *str;
-  unsigned i;
-
-  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize);
-  str = (char *) e + s->sh_offset;
-
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (grub_strcmp (str + s->sh_name, ".moddeps") == 0)
-      {
-       const char *name = (char *) e + s->sh_offset;
-       const char *max = name + s->sh_size;
-
-       while ((name < max) && (*name))
-         {
-           grub_dl_t m;
-           grub_dl_dep_t dep;
-
-           m = grub_dl_load (name);
-           if (! m)
-             return grub_errno;
-
-           grub_dl_ref (m);
-
-           dep = (grub_dl_dep_t) grub_malloc (sizeof (*dep));
-           if (! dep)
-             return grub_errno;
-
-           dep->mod = m;
-           dep->next = mod->dep;
-           mod->dep = dep;
-
-           name += grub_strlen (name) + 1;
-         }
-      }
-
-  return GRUB_ERR_NONE;
-}
-
-#if !GRUB_NO_MODULES
-int
-grub_dl_ref (grub_dl_t mod)
-{
-  grub_dl_dep_t dep;
-
-  for (dep = mod->dep; dep; dep = dep->next)
-    grub_dl_ref (dep->mod);
-
-  return ++mod->ref_count;
-}
-
-int
-grub_dl_unref (grub_dl_t mod)
-{
-  grub_dl_dep_t dep;
-
-  for (dep = mod->dep; dep; dep = dep->next)
-    grub_dl_unref (dep->mod);
-
-  return --mod->ref_count;
-}
-#endif
-
-static void
-grub_dl_flush_cache (grub_dl_t mod)
-{
-  grub_dl_segment_t seg;
-
-  for (seg = mod->segment; seg; seg = seg->next) {
-    if (seg->size) {
-      grub_dprintf ("modules", "flushing 0x%lx bytes at %p\n",
-                   (unsigned long) seg->size, seg->addr);
-      grub_arch_sync_caches (seg->addr, seg->size);
-    }
-  }
-}
-
-/* Load a module from core memory.  */
-grub_dl_t
-grub_dl_load_core (void *addr, grub_size_t size)
-{
-  Elf_Ehdr *e;
-  grub_dl_t mod;
-
-  grub_dprintf ("modules", "module at %p, size 0x%lx\n", addr,
-               (unsigned long) size);
-  e = addr;
-  if (grub_dl_check_header (e, size))
-    return 0;
-
-  if (e->e_type != ET_REL)
-    {
-      grub_error (GRUB_ERR_BAD_MODULE, "invalid ELF file type");
-      return 0;
-    }
-
-  /* Make sure that every section is within the core.  */
-  if (size < e->e_shoff + e->e_shentsize * e->e_shnum)
-    {
-      grub_error (GRUB_ERR_BAD_OS, "ELF sections outside core");
-      return 0;
-    }
-
-  mod = (grub_dl_t) grub_zalloc (sizeof (*mod));
-  if (! mod)
-    return 0;
-
-  mod->ref_count = 1;
-
-  grub_dprintf ("modules", "relocating to %p\n", mod);
-  if (grub_dl_resolve_name (mod, e)
-      || grub_dl_resolve_dependencies (mod, e)
-      || grub_dl_load_segments (mod, e)
-      || grub_dl_resolve_symbols (mod, e)
-      || grub_arch_dl_relocate_symbols (mod, e))
-    {
-      mod->fini = 0;
-      grub_dl_unload (mod);
-      return 0;
-    }
-
-  grub_dl_flush_cache (mod);
-
-  grub_dprintf ("modules", "module name: %s\n", mod->name);
-  grub_dprintf ("modules", "init function: %p\n", mod->init);
-  grub_dl_call_init (mod);
-
-  if (grub_dl_add (mod))
-    {
-      grub_dl_unload (mod);
-      return 0;
-    }
-
-  return mod;
-}
-
-/* Load a module from the file FILENAME.  */
-grub_dl_t
-grub_dl_load_file (const char *filename)
-{
-  grub_file_t file = NULL;
-  grub_ssize_t size;
-  void *core = 0;
-  grub_dl_t mod = 0;
-
-  file = grub_file_open (filename);
-  if (! file)
-    return 0;
-
-  size = grub_file_size (file);
-  core = grub_malloc (size);
-  if (! core)
-    {
-      grub_file_close (file);
-      return 0;
-    }
-
-  if (grub_file_read (file, core, size) != (int) size)
-    {
-      grub_file_close (file);
-      grub_free (core);
-      return 0;
-    }
-
-  /* We must close this before we try to process dependencies.
-     Some disk backends do not handle gracefully multiple concurrent
-     opens of the same device.  */
-  grub_file_close (file);
-
-  mod = grub_dl_load_core (core, size);
-  if (! mod)
-    {
-      grub_free (core);
-      return 0;
-    }
-
-  mod->ref_count = 0;
-  return mod;
-}
-
-/* Load a module using a symbolic name.  */
-grub_dl_t
-grub_dl_load (const char *name)
-{
-  char *filename;
-  grub_dl_t mod;
-  char *grub_dl_dir = grub_env_get ("prefix");
-
-  mod = grub_dl_get (name);
-  if (mod)
-    return mod;
-
-  if (! grub_dl_dir) {
-    grub_error (GRUB_ERR_FILE_NOT_FOUND, "\"prefix\" is not set");
-    return 0;
-  }
-
-  filename = grub_xasprintf ("%s/%s.mod", grub_dl_dir, name);
-  if (! filename)
-    return 0;
-
-  mod = grub_dl_load_file (filename);
-  grub_free (filename);
-
-  if (! mod)
-    return 0;
-
-  if (grub_strcmp (mod->name, name) != 0)
-    grub_error (GRUB_ERR_BAD_MODULE, "mismatched names");
-
-  return mod;
-}
-
-/* Unload the module MOD.  */
-int
-grub_dl_unload (grub_dl_t mod)
-{
-  grub_dl_dep_t dep, depn;
-  grub_dl_segment_t seg, segn;
-
-  if (mod->ref_count > 0)
-    return 0;
-
-  if (mod->fini)
-    (mod->fini) ();
-
-  grub_dl_remove (mod);
-  grub_dl_unregister_symbols (mod);
-
-  for (dep = mod->dep; dep; dep = depn)
-    {
-      depn = dep->next;
-
-      if (! grub_dl_unref (dep->mod))
-       grub_dl_unload (dep->mod);
-
-      grub_free (dep);
-    }
-
-  for (seg = mod->segment; seg; seg = segn)
-    {
-      segn = seg->next;
-      grub_free (seg->addr);
-      grub_free (seg);
-    }
-
-  grub_free (mod->name);
-#ifdef GRUB_MODULES_MACHINE_READONLY
-  grub_free (mod->symtab);
-#endif
-  grub_free (mod);
-  return 1;
-}
-
-/* Unload unneeded modules.  */
-void
-grub_dl_unload_unneeded (void)
-{
-  /* Because grub_dl_remove modifies the list of modules, this
-     implementation is tricky.  */
-  grub_dl_list_t p = grub_dl_head;
-
-  while (p)
-    {
-      if (grub_dl_unload (p->mod))
-       {
-         p = grub_dl_head;
-         continue;
-       }
-
-      p = p->next;
-    }
-}
-
-/* Unload all modules.  */
-void
-grub_dl_unload_all (void)
-{
-  while (grub_dl_head)
-    {
-      grub_dl_list_t p;
-
-      grub_dl_unload_unneeded ();
-
-      /* Force to decrement the ref count. This will purge pre-loaded
-        modules and manually inserted modules.  */
-      for (p = grub_dl_head; p; p = p->next)
-       p->mod->ref_count--;
-    }
-}
diff --git a/kern/efi/efi.c b/kern/efi/efi.c
deleted file mode 100644 (file)
index d8b2255..0000000
+++ /dev/null
@@ -1,783 +0,0 @@
-/* efi.c - generic EFI support */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/charset.h>
-#include <grub/efi/api.h>
-#include <grub/efi/efi.h>
-#include <grub/efi/console_control.h>
-#include <grub/efi/pe32.h>
-#include <grub/machine/time.h>
-#include <grub/term.h>
-#include <grub/kernel.h>
-#include <grub/mm.h>
-
-/* The handle of GRUB itself. Filled in by the startup code.  */
-grub_efi_handle_t grub_efi_image_handle;
-
-/* The pointer to a system table. Filled in by the startup code.  */
-grub_efi_system_table_t *grub_efi_system_table;
-
-static grub_efi_guid_t console_control_guid = GRUB_EFI_CONSOLE_CONTROL_GUID;
-static grub_efi_guid_t loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID;
-static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID;
-
-void *
-grub_efi_locate_protocol (grub_efi_guid_t *protocol, void *registration)
-{
-  void *interface;
-  grub_efi_status_t status;
-
-  status = efi_call_3 (grub_efi_system_table->boot_services->locate_protocol,
-                       protocol, registration, &interface);
-  if (status != GRUB_EFI_SUCCESS)
-    return 0;
-
-  return interface;
-}
-
-/* Return the array of handles which meet the requirement. If successful,
-   the number of handles is stored in NUM_HANDLES. The array is allocated
-   from the heap.  */
-grub_efi_handle_t *
-grub_efi_locate_handle (grub_efi_locate_search_type_t search_type,
-                       grub_efi_guid_t *protocol,
-                       void *search_key,
-                       grub_efi_uintn_t *num_handles)
-{
-  grub_efi_boot_services_t *b;
-  grub_efi_status_t status;
-  grub_efi_handle_t *buffer;
-  grub_efi_uintn_t buffer_size = 8 * sizeof (grub_efi_handle_t);
-
-  buffer = grub_malloc (buffer_size);
-  if (! buffer)
-    return 0;
-
-  b = grub_efi_system_table->boot_services;
-  status = efi_call_5 (b->locate_handle, search_type, protocol, search_key,
-                            &buffer_size, buffer);
-  if (status == GRUB_EFI_BUFFER_TOO_SMALL)
-    {
-      grub_free (buffer);
-      buffer = grub_malloc (buffer_size);
-      if (! buffer)
-       return 0;
-
-      status = efi_call_5 (b->locate_handle, search_type, protocol, search_key,
-                                &buffer_size, buffer);
-    }
-
-  if (status != GRUB_EFI_SUCCESS)
-    {
-      grub_free (buffer);
-      return 0;
-    }
-
-  *num_handles = buffer_size / sizeof (grub_efi_handle_t);
-  return buffer;
-}
-
-void *
-grub_efi_open_protocol (grub_efi_handle_t handle,
-                       grub_efi_guid_t *protocol,
-                       grub_efi_uint32_t attributes)
-{
-  grub_efi_boot_services_t *b;
-  grub_efi_status_t status;
-  void *interface;
-
-  b = grub_efi_system_table->boot_services;
-  status = efi_call_6 (b->open_protocol, handle,
-                      protocol,
-                      &interface,
-                      grub_efi_image_handle,
-                      0,
-                      attributes);
-  if (status != GRUB_EFI_SUCCESS)
-    return 0;
-
-  return interface;
-}
-
-int
-grub_efi_set_text_mode (int on)
-{
-  grub_efi_console_control_protocol_t *c;
-  grub_efi_screen_mode_t mode, new_mode;
-
-  c = grub_efi_locate_protocol (&console_control_guid, 0);
-  if (! c)
-    /* No console control protocol instance available, assume it is
-       already in text mode. */
-    return 1;
-
-  if (efi_call_4 (c->get_mode, c, &mode, 0, 0) != GRUB_EFI_SUCCESS)
-    return 0;
-
-  new_mode = on ? GRUB_EFI_SCREEN_TEXT : GRUB_EFI_SCREEN_GRAPHICS;
-  if (mode != new_mode)
-    if (efi_call_2 (c->set_mode, c, new_mode) != GRUB_EFI_SUCCESS)
-      return 0;
-
-  return 1;
-}
-
-void
-grub_efi_stall (grub_efi_uintn_t microseconds)
-{
-  efi_call_1 (grub_efi_system_table->boot_services->stall, microseconds);
-}
-
-grub_efi_loaded_image_t *
-grub_efi_get_loaded_image (grub_efi_handle_t image_handle)
-{
-  return grub_efi_open_protocol (image_handle,
-                                &loaded_image_guid,
-                                GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
-}
-
-void
-grub_exit (void)
-{
-  grub_efi_fini ();
-  efi_call_4 (grub_efi_system_table->boot_services->exit,
-              grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0);
-  for (;;) ;
-}
-
-/* On i386, a firmware-independant grub_reboot() is provided by realmode.S.  */
-#ifndef __i386__
-void
-grub_reboot (void)
-{
-  grub_efi_fini ();
-  efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
-              GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
-}
-#endif
-
-void
-grub_halt (void)
-{
-  grub_efi_fini ();
-  efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
-              GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL);
-}
-
-int
-grub_efi_exit_boot_services (grub_efi_uintn_t map_key)
-{
-  grub_efi_boot_services_t *b;
-  grub_efi_status_t status;
-
-  b = grub_efi_system_table->boot_services;
-  status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle, map_key);
-  return status == GRUB_EFI_SUCCESS;
-}
-
-grub_err_t
-grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
-                                 grub_efi_uintn_t descriptor_size,
-                                 grub_efi_uint32_t descriptor_version,
-                                 grub_efi_memory_descriptor_t *virtual_map)
-{
-  grub_efi_runtime_services_t *r;
-  grub_efi_status_t status;
-
-  r = grub_efi_system_table->runtime_services;
-  status = efi_call_4 (r->set_virtual_address_map, memory_map_size,
-                      descriptor_size, descriptor_version, virtual_map);
-
-  if (status == GRUB_EFI_SUCCESS)
-    return GRUB_ERR_NONE;
-
-  return grub_error (GRUB_ERR_IO, "set_virtual_address_map failed");
-}
-
-grub_uint32_t
-grub_get_rtc (void)
-{
-  grub_efi_time_t time;
-  grub_efi_runtime_services_t *r;
-
-  r = grub_efi_system_table->runtime_services;
-  if (efi_call_2 (r->get_time, &time, 0) != GRUB_EFI_SUCCESS)
-    /* What is possible in this case?  */
-    return 0;
-
-  return (((time.minute * 60 + time.second) * 1000
-          + time.nanosecond / 1000000)
-         * GRUB_TICKS_PER_SECOND / 1000);
-}
-
-/* Search the mods section from the PE32/PE32+ image. This code uses
-   a PE32 header, but should work with PE32+ as well.  */
-grub_addr_t
-grub_arch_modules_addr (void)
-{
-  grub_efi_loaded_image_t *image;
-  struct grub_pe32_header *header;
-  struct grub_pe32_coff_header *coff_header;
-  struct grub_pe32_section_table *sections;
-  struct grub_pe32_section_table *section;
-  struct grub_module_info *info;
-  grub_uint16_t i;
-
-  image = grub_efi_get_loaded_image (grub_efi_image_handle);
-  if (! image)
-    return 0;
-
-  header = image->image_base;
-  coff_header = &(header->coff_header);
-  sections
-    = (struct grub_pe32_section_table *) ((char *) coff_header
-                                         + sizeof (*coff_header)
-                                         + coff_header->optional_header_size);
-
-  for (i = 0, section = sections;
-       i < coff_header->num_sections;
-       i++, section++)
-    {
-      if (grub_strcmp (section->name, "mods") == 0)
-       break;
-    }
-
-  if (i == coff_header->num_sections)
-    return 0;
-
-  info = (struct grub_module_info *) ((char *) image->image_base
-                                     + section->virtual_address);
-  if (info->magic != GRUB_MODULE_MAGIC)
-    return 0;
-
-  return (grub_addr_t) info;
-}
-
-char *
-grub_efi_get_filename (grub_efi_device_path_t *dp)
-{
-  char *name = 0;
-
-  while (1)
-    {
-      grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
-      grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
-
-      if (type == GRUB_EFI_END_DEVICE_PATH_TYPE)
-       break;
-      else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
-              && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
-       {
-         grub_efi_file_path_device_path_t *fp;
-         grub_efi_uint16_t len;
-         char *p;
-         grub_size_t size;
-
-         if (name)
-           {
-             size = grub_strlen (name);
-             name[size] = '/';
-             size++;
-           }
-         else
-           size = 0;
-
-         len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
-                / sizeof (grub_efi_char16_t));
-         p = grub_realloc (name, size + len * 4 + 1);
-         if (! p)
-           {
-             grub_free (name);
-             return 0;
-           }
-
-         name = p;
-         fp = (grub_efi_file_path_device_path_t *) dp;
-         *grub_utf16_to_utf8 ((grub_uint8_t *) name + size,
-                              fp->path_name, len) = '\0';
-       }
-
-      dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
-    }
-
-  if (name)
-    {
-      /* EFI breaks paths with backslashes.  */
-      char *p;
-
-      for (p = name; *p; p++)
-       if (*p == '\\')
-         *p = '/';
-    }
-
-  return name;
-}
-
-grub_efi_device_path_t *
-grub_efi_get_device_path (grub_efi_handle_t handle)
-{
-  return grub_efi_open_protocol (handle, &device_path_guid,
-                                GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
-}
-
-/* Print the chain of Device Path nodes. This is mainly for debugging. */
-void
-grub_efi_print_device_path (grub_efi_device_path_t *dp)
-{
-  while (1)
-    {
-      grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
-      grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
-      grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
-
-      switch (type)
-       {
-       case GRUB_EFI_END_DEVICE_PATH_TYPE:
-         switch (subtype)
-           {
-           case GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE:
-             grub_printf ("/EndEntire\n");
-             //grub_putchar ('\n');
-             break;
-           case GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE:
-             grub_printf ("/EndThis\n");
-             //grub_putchar ('\n');
-             break;
-           default:
-             grub_printf ("/EndUnknown(%x)\n", (unsigned) subtype);
-             break;
-           }
-         break;
-
-       case GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE:
-         switch (subtype)
-           {
-           case GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_pci_device_path_t pci;
-               grub_memcpy (&pci, dp, len);
-               grub_printf ("/PCI(%x,%x)",
-                            (unsigned) pci.function, (unsigned) pci.device);
-             }
-             break;
-           case GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_pccard_device_path_t pccard;
-               grub_memcpy (&pccard, dp, len);
-               grub_printf ("/PCCARD(%x)",
-                            (unsigned) pccard.function);
-             }
-             break;
-           case GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_memory_mapped_device_path_t mmapped;
-               grub_memcpy (&mmapped, dp, len);
-               grub_printf ("/MMap(%x,%llx,%llx)",
-                            (unsigned) mmapped.memory_type,
-                            (unsigned long long) mmapped.start_address,
-                            (unsigned long long) mmapped.end_address);
-             }
-             break;
-           case GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_vendor_device_path_t vendor;
-               grub_memcpy (&vendor, dp, sizeof (vendor));
-               grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
-                            (unsigned) vendor.vendor_guid.data1,
-                            (unsigned) vendor.vendor_guid.data2,
-                            (unsigned) vendor.vendor_guid.data3,
-                            (unsigned) vendor.vendor_guid.data4[0],
-                            (unsigned) vendor.vendor_guid.data4[1],
-                            (unsigned) vendor.vendor_guid.data4[2],
-                            (unsigned) vendor.vendor_guid.data4[3],
-                            (unsigned) vendor.vendor_guid.data4[4],
-                            (unsigned) vendor.vendor_guid.data4[5],
-                            (unsigned) vendor.vendor_guid.data4[6],
-                            (unsigned) vendor.vendor_guid.data4[7]);
-             }
-             break;
-           case GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_controller_device_path_t controller;
-               grub_memcpy (&controller, dp, len);
-               grub_printf ("/Ctrl(%x)",
-                            (unsigned) controller.controller_number);
-             }
-             break;
-           default:
-             grub_printf ("/UnknownHW(%x)", (unsigned) subtype);
-             break;
-           }
-         break;
-
-       case GRUB_EFI_ACPI_DEVICE_PATH_TYPE:
-         switch (subtype)
-           {
-           case GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_acpi_device_path_t acpi;
-               grub_memcpy (&acpi, dp, len);
-               grub_printf ("/ACPI(%x,%x)",
-                            (unsigned) acpi.hid,
-                            (unsigned) acpi.uid);
-             }
-             break;
-           case GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_expanded_acpi_device_path_t eacpi;
-               grub_memcpy (&eacpi, dp, sizeof (eacpi));
-               grub_printf ("/ACPI(");
-
-               if (GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp)[0] == '\0')
-                 grub_printf ("%x,", (unsigned) eacpi.hid);
-               else
-                 grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp));
-
-               if (GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp)[0] == '\0')
-                 grub_printf ("%x,", (unsigned) eacpi.uid);
-               else
-                 grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp));
-
-               if (GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp)[0] == '\0')
-                 grub_printf ("%x)", (unsigned) eacpi.cid);
-               else
-                 grub_printf ("%s)", GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp));
-             }
-             break;
-           default:
-             grub_printf ("/UnknownACPI(%x)", (unsigned) subtype);
-             break;
-           }
-         break;
-
-       case GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE:
-         switch (subtype)
-           {
-           case GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_atapi_device_path_t atapi;
-               grub_memcpy (&atapi, dp, len);
-               grub_printf ("/ATAPI(%x,%x,%x)",
-                            (unsigned) atapi.primary_secondary,
-                            (unsigned) atapi.slave_master,
-                            (unsigned) atapi.lun);
-             }
-             break;
-           case GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_scsi_device_path_t scsi;
-               grub_memcpy (&scsi, dp, len);
-               grub_printf ("/SCSI(%x,%x)",
-                            (unsigned) scsi.pun,
-                            (unsigned) scsi.lun);
-             }
-             break;
-           case GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_fibre_channel_device_path_t fc;
-               grub_memcpy (&fc, dp, len);
-               grub_printf ("/FibreChannel(%llx,%llx)",
-                            (unsigned long long) fc.wwn,
-                            (unsigned long long) fc.lun);
-             }
-             break;
-           case GRUB_EFI_1394_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_1394_device_path_t firewire;
-               grub_memcpy (&firewire, dp, len);
-               grub_printf ("/1394(%llx)", (unsigned long long) firewire.guid);
-             }
-             break;
-           case GRUB_EFI_USB_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_usb_device_path_t usb;
-               grub_memcpy (&usb, dp, len);
-               grub_printf ("/USB(%x,%x)",
-                            (unsigned) usb.parent_port_number,
-                            (unsigned) usb.interface);
-             }
-             break;
-           case GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_usb_class_device_path_t usb_class;
-               grub_memcpy (&usb_class, dp, len);
-               grub_printf ("/USBClass(%x,%x,%x,%x,%x)",
-                            (unsigned) usb_class.vendor_id,
-                            (unsigned) usb_class.product_id,
-                            (unsigned) usb_class.device_class,
-                            (unsigned) usb_class.device_subclass,
-                            (unsigned) usb_class.device_protocol);
-             }
-             break;
-           case GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_i2o_device_path_t i2o;
-               grub_memcpy (&i2o, dp, len);
-               grub_printf ("/I2O(%x)", (unsigned) i2o.tid);
-             }
-             break;
-           case GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_mac_address_device_path_t mac;
-               grub_memcpy (&mac, dp, len);
-               grub_printf ("/MacAddr(%02x:%02x:%02x:%02x:%02x:%02x,%x)",
-                            (unsigned) mac.mac_address[0],
-                            (unsigned) mac.mac_address[1],
-                            (unsigned) mac.mac_address[2],
-                            (unsigned) mac.mac_address[3],
-                            (unsigned) mac.mac_address[4],
-                            (unsigned) mac.mac_address[5],
-                            (unsigned) mac.if_type);
-             }
-             break;
-           case GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_ipv4_device_path_t ipv4;
-               grub_memcpy (&ipv4, dp, len);
-               grub_printf ("/IPv4(%u.%u.%u.%u,%u.%u.%u.%u,%u,%u,%x,%x)",
-                            (unsigned) ipv4.local_ip_address[0],
-                            (unsigned) ipv4.local_ip_address[1],
-                            (unsigned) ipv4.local_ip_address[2],
-                            (unsigned) ipv4.local_ip_address[3],
-                            (unsigned) ipv4.remote_ip_address[0],
-                            (unsigned) ipv4.remote_ip_address[1],
-                            (unsigned) ipv4.remote_ip_address[2],
-                            (unsigned) ipv4.remote_ip_address[3],
-                            (unsigned) ipv4.local_port,
-                            (unsigned) ipv4.remote_port,
-                            (unsigned) ipv4.protocol,
-                            (unsigned) ipv4.static_ip_address);
-             }
-             break;
-           case GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_ipv6_device_path_t ipv6;
-               grub_memcpy (&ipv6, dp, len);
-               grub_printf ("/IPv6(%x:%x:%x:%x:%x:%x:%x:%x,%x:%x:%x:%x:%x:%x:%x:%x,%u,%u,%x,%x)",
-                            (unsigned) ipv6.local_ip_address[0],
-                            (unsigned) ipv6.local_ip_address[1],
-                            (unsigned) ipv6.local_ip_address[2],
-                            (unsigned) ipv6.local_ip_address[3],
-                            (unsigned) ipv6.local_ip_address[4],
-                            (unsigned) ipv6.local_ip_address[5],
-                            (unsigned) ipv6.local_ip_address[6],
-                            (unsigned) ipv6.local_ip_address[7],
-                            (unsigned) ipv6.remote_ip_address[0],
-                            (unsigned) ipv6.remote_ip_address[1],
-                            (unsigned) ipv6.remote_ip_address[2],
-                            (unsigned) ipv6.remote_ip_address[3],
-                            (unsigned) ipv6.remote_ip_address[4],
-                            (unsigned) ipv6.remote_ip_address[5],
-                            (unsigned) ipv6.remote_ip_address[6],
-                            (unsigned) ipv6.remote_ip_address[7],
-                            (unsigned) ipv6.local_port,
-                            (unsigned) ipv6.remote_port,
-                            (unsigned) ipv6.protocol,
-                            (unsigned) ipv6.static_ip_address);
-             }
-             break;
-           case GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_infiniband_device_path_t ib;
-               grub_memcpy (&ib, dp, len);
-               grub_printf ("/InfiniBand(%x,%llx,%llx,%llx)",
-                            (unsigned) ib.port_gid[0], /* XXX */
-                            (unsigned long long) ib.remote_id,
-                            (unsigned long long) ib.target_port_id,
-                            (unsigned long long) ib.device_id);
-             }
-             break;
-           case GRUB_EFI_UART_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_uart_device_path_t uart;
-               grub_memcpy (&uart, dp, len);
-               grub_printf ("/UART(%llu,%u,%x,%x)",
-                            (unsigned long long) uart.baud_rate,
-                            uart.data_bits,
-                            uart.parity,
-                            uart.stop_bits);
-             }
-             break;
-           case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_vendor_messaging_device_path_t vendor;
-               grub_memcpy (&vendor, dp, sizeof (vendor));
-               grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
-                            (unsigned) vendor.vendor_guid.data1,
-                            (unsigned) vendor.vendor_guid.data2,
-                            (unsigned) vendor.vendor_guid.data3,
-                            (unsigned) vendor.vendor_guid.data4[0],
-                            (unsigned) vendor.vendor_guid.data4[1],
-                            (unsigned) vendor.vendor_guid.data4[2],
-                            (unsigned) vendor.vendor_guid.data4[3],
-                            (unsigned) vendor.vendor_guid.data4[4],
-                            (unsigned) vendor.vendor_guid.data4[5],
-                            (unsigned) vendor.vendor_guid.data4[6],
-                            (unsigned) vendor.vendor_guid.data4[7]);
-             }
-             break;
-           default:
-             grub_printf ("/UnknownMessaging(%x)", (unsigned) subtype);
-             break;
-           }
-         break;
-
-       case GRUB_EFI_MEDIA_DEVICE_PATH_TYPE:
-         switch (subtype)
-           {
-           case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_hard_drive_device_path_t hd;
-               grub_memcpy (&hd, dp, len);
-               grub_printf ("/HD(%u,%llx,%llx,%02x%02x%02x%02x%02x%02x%02x%02x,%x,%x)",
-                            hd.partition_number,
-                            (unsigned long long) hd.partition_start,
-                            (unsigned long long) hd.partition_size,
-                            (unsigned) hd.partition_signature[0],
-                            (unsigned) hd.partition_signature[1],
-                            (unsigned) hd.partition_signature[2],
-                            (unsigned) hd.partition_signature[3],
-                            (unsigned) hd.partition_signature[4],
-                            (unsigned) hd.partition_signature[5],
-                            (unsigned) hd.partition_signature[6],
-                            (unsigned) hd.partition_signature[7],
-                            (unsigned) hd.mbr_type,
-                            (unsigned) hd.signature_type);
-             }
-             break;
-           case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_cdrom_device_path_t cd;
-               grub_memcpy (&cd, dp, len);
-               grub_printf ("/CD(%u,%llx,%llx)",
-                            cd.boot_entry,
-                            (unsigned long long) cd.partition_start,
-                            (unsigned long long) cd.partition_size);
-             }
-             break;
-           case GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_vendor_media_device_path_t vendor;
-               grub_memcpy (&vendor, dp, sizeof (vendor));
-               grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
-                            (unsigned) vendor.vendor_guid.data1,
-                            (unsigned) vendor.vendor_guid.data2,
-                            (unsigned) vendor.vendor_guid.data3,
-                            (unsigned) vendor.vendor_guid.data4[0],
-                            (unsigned) vendor.vendor_guid.data4[1],
-                            (unsigned) vendor.vendor_guid.data4[2],
-                            (unsigned) vendor.vendor_guid.data4[3],
-                            (unsigned) vendor.vendor_guid.data4[4],
-                            (unsigned) vendor.vendor_guid.data4[5],
-                            (unsigned) vendor.vendor_guid.data4[6],
-                            (unsigned) vendor.vendor_guid.data4[7]);
-             }
-             break;
-           case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_file_path_device_path_t *fp;
-               grub_uint8_t buf[(len - 4) * 2 + 1];
-               fp = (grub_efi_file_path_device_path_t *) dp;
-               *grub_utf16_to_utf8 (buf, fp->path_name,
-                                    (len - 4) / sizeof (grub_efi_char16_t))
-                 = '\0';
-               grub_printf ("/File(%s)", buf);
-             }
-             break;
-           case GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_protocol_device_path_t proto;
-               grub_memcpy (&proto, dp, sizeof (proto));
-               grub_printf ("/Protocol(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)",
-                            (unsigned) proto.guid.data1,
-                            (unsigned) proto.guid.data2,
-                            (unsigned) proto.guid.data3,
-                            (unsigned) proto.guid.data4[0],
-                            (unsigned) proto.guid.data4[1],
-                            (unsigned) proto.guid.data4[2],
-                            (unsigned) proto.guid.data4[3],
-                            (unsigned) proto.guid.data4[4],
-                            (unsigned) proto.guid.data4[5],
-                            (unsigned) proto.guid.data4[6],
-                            (unsigned) proto.guid.data4[7]);
-             }
-             break;
-           default:
-             grub_printf ("/UnknownMedia(%x)", (unsigned) subtype);
-             break;
-           }
-         break;
-
-       case GRUB_EFI_BIOS_DEVICE_PATH_TYPE:
-         switch (subtype)
-           {
-           case GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE:
-             {
-               grub_efi_bios_device_path_t bios;
-               grub_memcpy (&bios, dp, sizeof (bios));
-               grub_printf ("/BIOS(%x,%x,%s)",
-                            (unsigned) bios.device_type,
-                            (unsigned) bios.status_flags,
-                            (char *) (dp + 1));
-             }
-             break;
-           default:
-             grub_printf ("/UnknownBIOS(%x)", (unsigned) subtype);
-             break;
-           }
-         break;
-
-       default:
-         grub_printf ("/UnknownType(%x,%x)\n",
-                      (unsigned) type,
-                      (unsigned) subtype);
-         return;
-         break;
-       }
-
-      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
-       break;
-
-      dp = (grub_efi_device_path_t *) ((char *) dp + len);
-    }
-}
-
-int
-grub_efi_finish_boot_services (void)
-{
-  grub_efi_uintn_t mmap_size = 0;
-  grub_efi_uintn_t map_key;
-  grub_efi_uintn_t desc_size;
-  grub_efi_uint32_t desc_version;
-  void *mmap_buf = 0;
-
-  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
-                              &desc_size, &desc_version) < 0)
-    return 0;
-
-  mmap_buf = grub_malloc (mmap_size);
-
-  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
-                              &desc_size, &desc_version) <= 0)
-    return 0;
-
-  return grub_efi_exit_boot_services (map_key);
-}
-
diff --git a/kern/efi/init.c b/kern/efi/init.c
deleted file mode 100644 (file)
index a0b4ff7..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* init.c - generic EFI initialization and finalization */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/efi/efi.h>
-#include <grub/efi/console.h>
-#include <grub/efi/disk.h>
-#include <grub/term.h>
-#include <grub/misc.h>
-#include <grub/env.h>
-#include <grub/mm.h>
-#include <grub/machine/kernel.h>
-
-void
-grub_efi_init (void)
-{
-  /* First of all, initialize the console so that GRUB can display
-     messages.  */
-  grub_console_init ();
-
-  /* Initialize the memory management system.  */
-  grub_efi_mm_init ();
-
-  grub_efidisk_init ();
-}
-
-void
-grub_efi_set_prefix (void)
-{
-  grub_efi_loaded_image_t *image;
-
-  image = grub_efi_get_loaded_image (grub_efi_image_handle);
-  if (image)
-    {
-      char *device;
-      char *file;
-
-      device = grub_efidisk_get_device_name (image->device_handle);
-      file = grub_efi_get_filename (image->file_path);
-
-      if (device && file)
-       {
-         char *p;
-         char *prefix;
-
-         /* Get the directory.  */
-         p = grub_strrchr (file, '/');
-         if (p)
-           *p = '\0';
-
-         prefix = grub_xasprintf ("(%s)%s", device, file);
-         if (prefix)
-           {
-             
-             grub_env_set ("prefix", prefix);
-             grub_free (prefix);
-           }
-       }
-
-      grub_free (device);
-      grub_free (file);
-    }
-}
-
-void
-grub_efi_fini (void)
-{
-  grub_efidisk_fini ();
-  grub_console_fini ();
-}
diff --git a/kern/efi/mm.c b/kern/efi/mm.c
deleted file mode 100644 (file)
index ceb8fc9..0000000
+++ /dev/null
@@ -1,431 +0,0 @@
-/* mm.c - generic EFI memory management */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/efi/api.h>
-#include <grub/efi/efi.h>
-
-#define NEXT_MEMORY_DESCRIPTOR(desc, size)     \
-  ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
-
-#define BYTES_TO_PAGES(bytes)  ((bytes) >> 12)
-#define PAGES_TO_BYTES(pages)  ((pages) << 12)
-
-/* The size of a memory map obtained from the firmware. This must be
-   a multiplier of 4KB.  */
-#define MEMORY_MAP_SIZE        0x3000
-
-/* Maintain the list of allocated pages.  */
-struct allocated_page
-{
-  grub_efi_physical_address_t addr;
-  grub_efi_uint64_t num_pages;
-};
-
-#define ALLOCATED_PAGES_SIZE   0x1000
-#define MAX_ALLOCATED_PAGES    \
-  (ALLOCATED_PAGES_SIZE / sizeof (struct allocated_page))
-
-static struct allocated_page *allocated_pages = 0;
-
-/* The minimum and maximum heap size for GRUB itself.  */
-#define MIN_HEAP_SIZE  0x100000
-#define MAX_HEAP_SIZE  (1600 * 0x100000)
-
-
-/* Allocate pages. Return the pointer to the first of allocated pages.  */
-void *
-grub_efi_allocate_pages (grub_efi_physical_address_t address,
-                        grub_efi_uintn_t pages)
-{
-  grub_efi_allocate_type_t type;
-  grub_efi_status_t status;
-  grub_efi_boot_services_t *b;
-
-#if GRUB_TARGET_SIZEOF_VOID_P < 8
-  /* Limit the memory access to less than 4GB for 32-bit platforms.  */
-  if (address > 0xffffffff)
-    return 0;
-#endif
-
-#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
-  if (address == 0)
-    {
-      type = GRUB_EFI_ALLOCATE_MAX_ADDRESS;
-      address = 0xffffffff;
-    }
-  else
-    type = GRUB_EFI_ALLOCATE_ADDRESS;
-#else
-  if (address == 0)
-    type = GRUB_EFI_ALLOCATE_ANY_PAGES;
-  else
-    type = GRUB_EFI_ALLOCATE_ADDRESS;
-#endif
-
-  b = grub_efi_system_table->boot_services;
-  status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_LOADER_DATA, pages, &address);
-  if (status != GRUB_EFI_SUCCESS)
-    return 0;
-
-  if (address == 0)
-    {
-      /* Uggh, the address 0 was allocated... This is too annoying,
-        so reallocate another one.  */
-      address = 0xffffffff;
-      status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_LOADER_DATA, pages, &address);
-      grub_efi_free_pages (0, pages);
-      if (status != GRUB_EFI_SUCCESS)
-       return 0;
-    }
-
-  if (allocated_pages)
-    {
-      unsigned i;
-
-      for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
-       if (allocated_pages[i].addr == 0)
-         {
-           allocated_pages[i].addr = address;
-           allocated_pages[i].num_pages = pages;
-           break;
-         }
-
-      if (i == MAX_ALLOCATED_PAGES)
-       grub_fatal ("too many page allocations");
-    }
-
-  return (void *) ((grub_addr_t) address);
-}
-
-/* Free pages starting from ADDRESS.  */
-void
-grub_efi_free_pages (grub_efi_physical_address_t address,
-                    grub_efi_uintn_t pages)
-{
-  grub_efi_boot_services_t *b;
-
-  if (allocated_pages
-      && ((grub_efi_physical_address_t) ((grub_addr_t) allocated_pages)
-         != address))
-    {
-      unsigned i;
-
-      for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
-       if (allocated_pages[i].addr == address)
-         {
-           allocated_pages[i].addr = 0;
-           break;
-         }
-    }
-
-  b = grub_efi_system_table->boot_services;
-  efi_call_2 (b->free_pages, address, pages);
-}
-
-/* Get the memory map as defined in the EFI spec. Return 1 if successful,
-   return 0 if partial, or return -1 if an error occurs.  */
-int
-grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size,
-                        grub_efi_memory_descriptor_t *memory_map,
-                        grub_efi_uintn_t *map_key,
-                        grub_efi_uintn_t *descriptor_size,
-                        grub_efi_uint32_t *descriptor_version)
-{
-  grub_efi_status_t status;
-  grub_efi_boot_services_t *b;
-  grub_efi_uintn_t key;
-  grub_efi_uint32_t version;
-
-  /* Allow some parameters to be missing.  */
-  if (! map_key)
-    map_key = &key;
-  if (! descriptor_version)
-    descriptor_version = &version;
-
-  b = grub_efi_system_table->boot_services;
-  status = efi_call_5 (b->get_memory_map, memory_map_size, memory_map, map_key,
-                             descriptor_size, descriptor_version);
-  if (status == GRUB_EFI_SUCCESS)
-    return 1;
-  else if (status == GRUB_EFI_BUFFER_TOO_SMALL)
-    return 0;
-  else
-    return -1;
-}
-
-/* Sort the memory map in place.  */
-static void
-sort_memory_map (grub_efi_memory_descriptor_t *memory_map,
-                grub_efi_uintn_t desc_size,
-                grub_efi_memory_descriptor_t *memory_map_end)
-{
-  grub_efi_memory_descriptor_t *d1;
-  grub_efi_memory_descriptor_t *d2;
-
-  for (d1 = memory_map;
-       d1 < memory_map_end;
-       d1 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size))
-    {
-      grub_efi_memory_descriptor_t *max_desc = d1;
-
-      for (d2 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size);
-          d2 < memory_map_end;
-          d2 = NEXT_MEMORY_DESCRIPTOR (d2, desc_size))
-       {
-         if (max_desc->num_pages < d2->num_pages)
-           max_desc = d2;
-       }
-
-      if (max_desc != d1)
-       {
-         grub_efi_memory_descriptor_t tmp;
-
-         tmp = *d1;
-         *d1 = *max_desc;
-         *max_desc = tmp;
-       }
-    }
-}
-
-/* Filter the descriptors. GRUB needs only available memory.  */
-static grub_efi_memory_descriptor_t *
-filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
-                  grub_efi_memory_descriptor_t *filtered_memory_map,
-                  grub_efi_uintn_t desc_size,
-                  grub_efi_memory_descriptor_t *memory_map_end)
-{
-  grub_efi_memory_descriptor_t *desc;
-  grub_efi_memory_descriptor_t *filtered_desc;
-
-  for (desc = memory_map, filtered_desc = filtered_memory_map;
-       desc < memory_map_end;
-       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
-    {
-      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
-#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
-         && desc->physical_start <= 0xffffffff
-#endif
-         && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000
-         && desc->num_pages != 0)
-       {
-         grub_memcpy (filtered_desc, desc, desc_size);
-
-         /* Avoid less than 1MB, because some loaders seem to be confused.  */
-         if (desc->physical_start < 0x100000)
-           {
-             desc->num_pages -= BYTES_TO_PAGES (0x100000
-                                                - desc->physical_start);
-             desc->physical_start = 0x100000;
-           }
-
-#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
-         if (BYTES_TO_PAGES (filtered_desc->physical_start)
-             + filtered_desc->num_pages
-             > BYTES_TO_PAGES (0x100000000LL))
-           filtered_desc->num_pages
-             = (BYTES_TO_PAGES (0x100000000LL)
-                - BYTES_TO_PAGES (filtered_desc->physical_start));
-#endif
-
-         if (filtered_desc->num_pages == 0)
-           continue;
-
-         filtered_desc = NEXT_MEMORY_DESCRIPTOR (filtered_desc, desc_size);
-       }
-    }
-
-  return filtered_desc;
-}
-
-/* Return the total number of pages.  */
-static grub_efi_uint64_t
-get_total_pages (grub_efi_memory_descriptor_t *memory_map,
-                grub_efi_uintn_t desc_size,
-                grub_efi_memory_descriptor_t *memory_map_end)
-{
-  grub_efi_memory_descriptor_t *desc;
-  grub_efi_uint64_t total = 0;
-
-  for (desc = memory_map;
-       desc < memory_map_end;
-       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
-    total += desc->num_pages;
-
-  return total;
-}
-
-/* Add memory regions.  */
-static void
-add_memory_regions (grub_efi_memory_descriptor_t *memory_map,
-                   grub_efi_uintn_t desc_size,
-                   grub_efi_memory_descriptor_t *memory_map_end,
-                   grub_efi_uint64_t required_pages)
-{
-  grub_efi_memory_descriptor_t *desc;
-
-  for (desc = memory_map;
-       desc < memory_map_end;
-       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
-    {
-      grub_efi_uint64_t pages;
-      grub_efi_physical_address_t start;
-      void *addr;
-
-      start = desc->physical_start;
-      pages = desc->num_pages;
-      if (pages > required_pages)
-       {
-         start += PAGES_TO_BYTES (pages - required_pages);
-         pages = required_pages;
-       }
-
-      addr = grub_efi_allocate_pages (start, pages);
-      if (! addr)
-       grub_fatal ("cannot allocate conventional memory %p with %u pages",
-                   (void *) ((grub_addr_t) start),
-                   (unsigned) pages);
-
-      grub_mm_init_region (addr, PAGES_TO_BYTES (pages));
-
-      required_pages -= pages;
-      if (required_pages == 0)
-       break;
-    }
-
-  if (required_pages > 0)
-    grub_fatal ("too little memory");
-}
-
-#if 0
-/* Print the memory map.  */
-static void
-print_memory_map (grub_efi_memory_descriptor_t *memory_map,
-                 grub_efi_uintn_t desc_size,
-                 grub_efi_memory_descriptor_t *memory_map_end)
-{
-  grub_efi_memory_descriptor_t *desc;
-  int i;
-
-  for (desc = memory_map, i = 0;
-       desc < memory_map_end;
-       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size), i++)
-    {
-      grub_printf ("MD: t=%x, p=%llx, v=%llx, n=%llx, a=%llx\n",
-                  desc->type, desc->physical_start, desc->virtual_start,
-                  desc->num_pages, desc->attribute);
-    }
-}
-#endif
-
-void
-grub_efi_mm_init (void)
-{
-  grub_efi_memory_descriptor_t *memory_map;
-  grub_efi_memory_descriptor_t *memory_map_end;
-  grub_efi_memory_descriptor_t *filtered_memory_map;
-  grub_efi_memory_descriptor_t *filtered_memory_map_end;
-  grub_efi_uintn_t map_size;
-  grub_efi_uintn_t desc_size;
-  grub_efi_uint64_t total_pages;
-  grub_efi_uint64_t required_pages;
-
-  /* First of all, allocate pages to maintain allocations.  */
-  allocated_pages
-    = grub_efi_allocate_pages (0, BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE));
-  if (! allocated_pages)
-    grub_fatal ("cannot allocate memory");
-
-  grub_memset (allocated_pages, 0, ALLOCATED_PAGES_SIZE);
-
-  /* Prepare a memory region to store two memory maps.  */
-  memory_map = grub_efi_allocate_pages (0,
-                                       2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
-  if (! memory_map)
-    grub_fatal ("cannot allocate memory");
-
-  filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map, MEMORY_MAP_SIZE);
-
-  /* Obtain descriptors for available memory.  */
-  map_size = MEMORY_MAP_SIZE;
-
-  if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0)
-    grub_fatal ("cannot get memory map");
-
-  memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size);
-
-  filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map,
-                                              desc_size, memory_map_end);
-
-  /* By default, request a quarter of the available memory.  */
-  total_pages = get_total_pages (filtered_memory_map, desc_size,
-                                filtered_memory_map_end);
-  required_pages = (total_pages >> 2);
-  if (required_pages < BYTES_TO_PAGES (MIN_HEAP_SIZE))
-    required_pages = BYTES_TO_PAGES (MIN_HEAP_SIZE);
-  else if (required_pages > BYTES_TO_PAGES (MAX_HEAP_SIZE))
-    required_pages = BYTES_TO_PAGES (MAX_HEAP_SIZE);
-
-  /* Sort the filtered descriptors, so that GRUB can allocate pages
-     from smaller regions.  */
-  sort_memory_map (filtered_memory_map, desc_size, filtered_memory_map_end);
-
-  /* Allocate memory regions for GRUB's memory management.  */
-  add_memory_regions (filtered_memory_map, desc_size,
-                     filtered_memory_map_end, required_pages);
-
-#if 0
-  /* For debug.  */
-  map_size = MEMORY_MAP_SIZE;
-
-  if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0)
-    grub_fatal ("cannot get memory map");
-
-  grub_printf ("printing memory map\n");
-  print_memory_map (memory_map, desc_size,
-                   NEXT_MEMORY_DESCRIPTOR (memory_map, map_size));
-  grub_abort ();
-#endif
-
-  /* Release the memory maps.  */
-  grub_efi_free_pages ((grub_addr_t) memory_map,
-                      2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
-}
-
-void
-grub_efi_mm_fini (void)
-{
-  if (allocated_pages)
-    {
-      unsigned i;
-
-      for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
-       {
-         struct allocated_page *p;
-
-         p = allocated_pages + i;
-         if (p->addr != 0)
-           grub_efi_free_pages ((grub_addr_t) p->addr, p->num_pages);
-       }
-
-      grub_efi_free_pages ((grub_addr_t) allocated_pages,
-                          BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE));
-    }
-}
diff --git a/kern/elf.c b/kern/elf.c
deleted file mode 100644 (file)
index d9948a8..0000000
+++ /dev/null
@@ -1,480 +0,0 @@
-/* elf.c - load ELF files */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <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_zalloc (sizeof (*elf));
-  if (! elf)
-    return 0;
-
-  elf->file = file;
-
-  if (grub_file_seek (elf->file, 0) == (grub_off_t) -1)
-    goto fail;
-
-  if (grub_file_read (elf->file, &elf->ehdr, sizeof (elf->ehdr))
-      != sizeof (elf->ehdr))
-    {
-      grub_error_push ();
-      grub_error (GRUB_ERR_READ_ERROR, "cannot read ELF header");
-      goto fail;
-    }
-
-  if (grub_elf_check_header (elf))
-    goto fail;
-
-  return elf;
-
-fail:
-  grub_free (elf->phdrs);
-  grub_free (elf);
-  return 0;
-}
-
-grub_elf_t
-grub_elf_open (const char *name)
-{
-  grub_file_t file;
-  grub_elf_t elf;
-
-  file = grub_gzfile_open (name, 1);
-  if (! file)
-    return 0;
-
-  elf = grub_elf_file (file);
-  if (! elf)
-    grub_file_close (file);
-
-  return elf;
-}
-
-\f
-/* 32-bit */
-
-int
-grub_elf_is_elf32 (grub_elf_t elf)
-{
-  return elf->ehdr.ehdr32.e_ident[EI_CLASS] == ELFCLASS32;
-}
-
-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%lx.\n",
-               (unsigned long long) elf->ehdr.ehdr32.e_phoff,
-               (unsigned long) 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))
-    {
-      grub_error_push ();
-      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 NESTED_FUNC_ATTR (*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 "
-                   "filesz %lx\n",
-                   i, phdr->p_type,
-                   (unsigned long) phdr->p_paddr,
-                   (unsigned long) phdr->p_memsz,
-                   (unsigned long) phdr->p_filesz);
-      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 *base)
-{
-  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 NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf32_Phdr *phdr, void *_arg);
-  int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf  __attribute__ ((unused)),
-                                Elf32_Phdr *phdr,
-                                void *_arg __attribute__ ((unused)))
-    {
-      /* 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 (base)
-    *base = 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;
-    }
-
-  if (base)
-    *base = segments_start;
-
-  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,
-                grub_addr_t *base, grub_size_t *size)
-{
-  grub_addr_t load_base = (grub_addr_t) -1ULL;
-  grub_size_t load_size = 0;
-  grub_err_t err;
-
-  auto int NESTED_FUNC_ATTR grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *hook);
-  int NESTED_FUNC_ATTR 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;
-    int do_load = 1;
-
-    load_addr = phdr->p_paddr;
-    if (load_hook && load_hook (phdr, &load_addr, &do_load))
-      return 1;
-
-    if (! do_load)
-      return 0;
-
-    if (load_addr < load_base)
-      load_base = load_addr;
-
-    grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n",
-                 (unsigned long long) load_addr,
-                 (unsigned long long) phdr->p_memsz);
-
-    if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1)
-      {
-       grub_error_push ();
-       return grub_error (GRUB_ERR_BAD_OS,
-                          "invalid offset in program header");
-      }
-
-    if (phdr->p_filesz)
-      {
-       grub_ssize_t read;
-       read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz);
-       if (read != (grub_ssize_t) phdr->p_filesz)
-         {
-           /* XXX How can we free memory from `load_hook'? */
-           grub_error_push ();
-           return grub_error (GRUB_ERR_BAD_OS,
-                              "couldn't read segment from file: "
-                              "wanted 0x%lx bytes; read 0x%lx bytes",
-                              phdr->p_filesz, read);
-         }
-      }
-
-    if (phdr->p_filesz < phdr->p_memsz)
-      grub_memset ((void *) (long) (load_addr + phdr->p_filesz),
-                  0, phdr->p_memsz - phdr->p_filesz);
-
-    load_size += phdr->p_memsz;
-
-    return 0;
-  }
-
-  err = grub_elf32_phdr_iterate (_elf, grub_elf32_load_segment, _load_hook);
-
-  if (base)
-    *base = load_base;
-  if (size)
-    *size = load_size;
-
-  return err;
-}
-
-
-\f
-/* 64-bit */
-
-int
-grub_elf_is_elf64 (grub_elf_t elf)
-{
-  return elf->ehdr.ehdr64.e_ident[EI_CLASS] == ELFCLASS64;
-}
-
-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%lx.\n",
-               (unsigned long long) elf->ehdr.ehdr64.e_phoff,
-               (unsigned long) 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))
-    {
-      grub_error_push ();
-      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 NESTED_FUNC_ATTR (*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 "
-                   "filesz %lx\n",
-                   i, phdr->p_type,
-                   (unsigned long) phdr->p_paddr,
-                   (unsigned long) phdr->p_memsz,
-                   (unsigned long) phdr->p_filesz);
-      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 *base)
-{
-  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 NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg);
-  int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)),
-                                Elf64_Phdr *phdr,
-                                void *_arg __attribute__ ((unused)))
-    {
-      /* 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 (base)
-    *base = 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;
-    }
-
-  if (base)
-    *base = segments_start;
-
-  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,
-                grub_addr_t *base, grub_size_t *size)
-{
-  grub_addr_t load_base = (grub_addr_t) -1ULL;
-  grub_size_t load_size = 0;
-  grub_err_t err;
-
-  auto int NESTED_FUNC_ATTR grub_elf64_load_segment (grub_elf_t elf, Elf64_Phdr *phdr,
-                                                    void *hook);
-  int NESTED_FUNC_ATTR 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;
-    int do_load = 1;
-
-    load_addr = phdr->p_paddr;
-    if (load_hook && load_hook (phdr, &load_addr, &do_load))
-      return 1;
-
-    if (! do_load)
-      return 0;
-
-    if (load_addr < load_base)
-      load_base = load_addr;
-
-    grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n",
-                 (unsigned long long) load_addr,
-                 (unsigned long long) phdr->p_memsz);
-
-    if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1)
-      {
-       grub_error_push ();
-       return grub_error (GRUB_ERR_BAD_OS,
-                          "invalid offset in program header");
-      }
-
-    if (phdr->p_filesz)
-      {
-       grub_ssize_t read;
-       read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz);
-       if (read != (grub_ssize_t) phdr->p_filesz)
-          {
-           /* XXX How can we free memory from `load_hook'?  */
-           grub_error_push ();
-           return grub_error (GRUB_ERR_BAD_OS,
-                             "couldn't read segment from file: "
-                             "wanted 0x%lx bytes; read 0x%lx bytes",
-                             phdr->p_filesz, read);
-          }
-      }
-
-    if (phdr->p_filesz < phdr->p_memsz)
-      grub_memset ((void *) (long) (load_addr + phdr->p_filesz),
-                  0, phdr->p_memsz - phdr->p_filesz);
-
-    load_size += phdr->p_memsz;
-
-    return 0;
-  }
-
-  err = grub_elf64_phdr_iterate (_elf, grub_elf64_load_segment, _load_hook);
-
-  if (base)
-    *base = load_base;
-  if (size)
-    *size = load_size;
-
-  return err;
-}
diff --git a/kern/env.c b/kern/env.c
deleted file mode 100644 (file)
index 84b3a00..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-/* env.c - Environment variables */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/env.h>
-#include <grub/env_private.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-
-/* The initial context.  */
-static struct grub_env_context initial_context;
-
-/* The current context.  */
-struct grub_env_context *grub_current_context = &initial_context;
-
-/* Return the hash representation of the string S.  */
-static unsigned int
-grub_env_hashval (const char *s)
-{
-  unsigned int i = 0;
-
-  /* XXX: This can be done much more efficiently.  */
-  while (*s)
-    i += 5 * *(s++);
-
-  return i % HASHSZ;
-}
-
-struct grub_env_var *
-grub_env_find (const char *name)
-{
-  struct grub_env_var *var;
-  int idx = grub_env_hashval (name);
-
-  /* Look for the variable in the current context.  */
-  for (var = grub_current_context->vars[idx]; var; var = var->next)
-    if (grub_strcmp (var->name, name) == 0)
-      return var;
-
-  return 0;
-}
-
-static void
-grub_env_insert (struct grub_env_context *context,
-                struct grub_env_var *var)
-{
-  int idx = grub_env_hashval (var->name);
-
-  /* Insert the variable into the hashtable.  */
-  var->prevp = &context->vars[idx];
-  var->next = context->vars[idx];
-  if (var->next)
-    var->next->prevp = &(var->next);
-  context->vars[idx] = var;
-}
-
-static void
-grub_env_remove (struct grub_env_var *var)
-{
-  /* Remove the entry from the variable table.  */
-  *var->prevp = var->next;
-  if (var->next)
-    var->next->prevp = var->prevp;
-}
-
-grub_err_t
-grub_env_set (const char *name, const char *val)
-{
-  struct grub_env_var *var;
-
-  /* If the variable does already exist, just update the variable.  */
-  var = grub_env_find (name);
-  if (var)
-    {
-      char *old = var->value;
-
-      if (var->write_hook)
-       var->value = var->write_hook (var, val);
-      else
-       var->value = grub_strdup (val);
-
-      if (! var->value)
-       {
-         var->value = old;
-         return grub_errno;
-       }
-
-      grub_free (old);
-      return GRUB_ERR_NONE;
-    }
-
-  /* The variable does not exist, so create a new one.  */
-  var = grub_zalloc (sizeof (*var));
-  if (! var)
-    return grub_errno;
-
-  /* This is not necessary. But leave this for readability.  */
-  var->global = 0;
-
-  var->name = grub_strdup (name);
-  if (! var->name)
-    goto fail;
-
-  var->value = grub_strdup (val);
-  if (! var->value)
-    goto fail;
-
-  grub_env_insert (grub_current_context, var);
-
-  return GRUB_ERR_NONE;
-
- fail:
-  grub_free (var->name);
-  grub_free (var->value);
-  grub_free (var);
-
-  return grub_errno;
-}
-
-char *
-grub_env_get (const char *name)
-{
-  struct grub_env_var *var;
-
-  var = grub_env_find (name);
-  if (! var)
-    return 0;
-
-  if (var->read_hook)
-    return var->read_hook (var, var->value);
-
-  return var->value;
-}
-
-void
-grub_env_unset (const char *name)
-{
-  struct grub_env_var *var;
-
-  var = grub_env_find (name);
-  if (! var)
-    return;
-
-  if (var->read_hook || var->write_hook)
-    {
-      grub_env_set (name, "");
-      return;
-    }
-
-  grub_env_remove (var);
-
-  grub_free (var->name);
-  grub_free (var->value);
-  grub_free (var);
-}
-
-void
-grub_env_iterate (int (*func) (struct grub_env_var *var))
-{
-  struct grub_env_sorted_var *sorted_list = 0;
-  struct grub_env_sorted_var *sorted_var;
-  int i;
-
-  /* Add variables associated with this context into a sorted list.  */
-  for (i = 0; i < HASHSZ; i++)
-    {
-      struct grub_env_var *var;
-
-      for (var = grub_current_context->vars[i]; var; var = var->next)
-       {
-         struct grub_env_sorted_var *p, **q;
-
-         sorted_var = grub_malloc (sizeof (*sorted_var));
-         if (! sorted_var)
-           goto fail;
-
-         sorted_var->var = var;
-
-         for (q = &sorted_list, p = *q; p; q = &((*q)->next), p = *q)
-           {
-             if (grub_strcmp (p->var->name, var->name) > 0)
-               break;
-           }
-
-         sorted_var->next = *q;
-         *q = sorted_var;
-       }
-    }
-
-  /* Iterate FUNC on the sorted list.  */
-  for (sorted_var = sorted_list; sorted_var; sorted_var = sorted_var->next)
-    if (func (sorted_var->var))
-      break;
-
- fail:
-
-  /* Free the sorted list.  */
-  for (sorted_var = sorted_list; sorted_var; )
-    {
-      struct grub_env_sorted_var *tmp = sorted_var->next;
-
-      grub_free (sorted_var);
-      sorted_var = tmp;
-    }
-}
-
-grub_err_t
-grub_register_variable_hook (const char *name,
-                            grub_env_read_hook_t read_hook,
-                            grub_env_write_hook_t write_hook)
-{
-  struct grub_env_var *var = grub_env_find (name);
-
-  if (! var)
-    {
-      if (grub_env_set (name, "") != GRUB_ERR_NONE)
-       return grub_errno;
-
-      var = grub_env_find (name);
-      /* XXX Insert an assertion?  */
-    }
-
-  var->read_hook = read_hook;
-  var->write_hook = write_hook;
-
-  return GRUB_ERR_NONE;
-}
diff --git a/kern/err.c b/kern/err.c
deleted file mode 100644 (file)
index 8272467..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/* err.c - error handling routines */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <stdarg.h>
-#include <grub/i18n.h>
-
-#define GRUB_MAX_ERRMSG                256
-#define GRUB_ERROR_STACK_SIZE  10
-
-grub_err_t grub_errno;
-char grub_errmsg[GRUB_MAX_ERRMSG];
-
-static struct
-{
-  grub_err_t errno;
-  char errmsg[GRUB_MAX_ERRMSG];
-} grub_error_stack_items[GRUB_ERROR_STACK_SIZE];
-
-static int grub_error_stack_pos;
-static int grub_error_stack_assert;
-
-grub_err_t
-grub_error (grub_err_t n, const char *fmt, ...)
-{
-  va_list ap;
-
-  grub_errno = n;
-
-  va_start (ap, fmt);
-  grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), _(fmt), ap);
-  va_end (ap);
-
-  return n;
-}
-
-void
-grub_fatal (const char *fmt, ...)
-{
-  va_list ap;
-
-  va_start (ap, fmt);
-  grub_vprintf (_(fmt), ap);
-  va_end (ap);
-
-  grub_abort ();
-}
-
-void
-grub_error_push (void)
-{
-  /* Only add items to stack, if there is enough room.  */
-  if (grub_error_stack_pos < GRUB_ERROR_STACK_SIZE)
-    {
-      /* Copy active error message to stack.  */
-      grub_error_stack_items[grub_error_stack_pos].errno = grub_errno;
-      grub_memcpy (grub_error_stack_items[grub_error_stack_pos].errmsg,
-                   grub_errmsg,
-                   sizeof (grub_errmsg));
-
-      /* Advance to next error stack position.  */
-      grub_error_stack_pos++;
-    }
-  else
-    {
-      /* There is no room for new error message. Discard new error message
-         and mark error stack assertion flag.  */
-      grub_error_stack_assert = 1;
-    }
-
-  /* Allow further operation of other components by resetting
-     active errno to GRUB_ERR_NONE.  */
-  grub_errno = GRUB_ERR_NONE;
-}
-
-int
-grub_error_pop (void)
-{
-  if (grub_error_stack_pos > 0)
-    {
-      /* Pop error message from error stack to current active error.  */
-      grub_error_stack_pos--;
-
-      grub_errno = grub_error_stack_items[grub_error_stack_pos].errno;
-      grub_memcpy (grub_errmsg,
-                   grub_error_stack_items[grub_error_stack_pos].errmsg,
-                   sizeof (grub_errmsg));
-
-      return 1;
-    }
-  else
-    {
-      /* There is no more items on error stack, reset to no error state.  */
-      grub_errno = GRUB_ERR_NONE;
-
-      return 0;
-    }
-}
-
-void
-grub_print_error (void)
-{
-  /* Print error messages in reverse order. First print active error message
-     and then empty error stack.  */
-  do
-    {
-      if (grub_errno != GRUB_ERR_NONE)
-        grub_err_printf (_("error: %s.\n"), grub_errmsg);
-    }
-  while (grub_error_pop ());
-
-  /* If there was an assert while using error stack, report about it.  */
-  if (grub_error_stack_assert)
-    {
-      grub_err_printf ("assert: error stack overflow detected!\n");
-      grub_error_stack_assert = 0;
-    }
-}
diff --git a/kern/file.c b/kern/file.c
deleted file mode 100644 (file)
index e17c35f..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/* file.c - file I/O functions */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/err.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/fs.h>
-#include <grub/device.h>
-
-/* Get the device part of the filename NAME. It is enclosed by parentheses.  */
-char *
-grub_file_get_device_name (const char *name)
-{
-  if (name[0] == '(')
-    {
-      char *p = grub_strchr (name, ')');
-      char *ret;
-
-      if (! p)
-       {
-         grub_error (GRUB_ERR_BAD_FILENAME, "missing `)'");
-         return 0;
-       }
-
-      ret = (char *) grub_malloc (p - name);
-      if (! ret)
-       return 0;
-
-      grub_memcpy (ret, name + 1, p - name - 1);
-      ret[p - name - 1] = '\0';
-      return ret;
-    }
-
-  return 0;
-}
-
-grub_file_t
-grub_file_open (const char *name)
-{
-  grub_device_t device;
-  grub_file_t file = 0;
-  char *device_name;
-  char *file_name;
-
-  device_name = grub_file_get_device_name (name);
-  if (grub_errno)
-    return 0;
-
-  /* Get the file part of NAME.  */
-  file_name = grub_strchr (name, ')');
-  if (file_name)
-    file_name++;
-  else
-    file_name = (char *) name;
-
-  device = grub_device_open (device_name);
-  grub_free (device_name);
-  if (! device)
-    goto fail;
-
-  file = (grub_file_t) grub_zalloc (sizeof (*file));
-  if (! file)
-    goto fail;
-
-  file->device = device;
-
-  if (device->disk && file_name[0] != '/')
-    /* This is a block list.  */
-    file->fs = &grub_fs_blocklist;
-  else
-    {
-      file->fs = grub_fs_probe (device);
-      if (! file->fs)
-       goto fail;
-    }
-
-  if ((file->fs->open) (file, file_name) != GRUB_ERR_NONE)
-    goto fail;
-
-  return file;
-
- fail:
-  if (device)
-    grub_device_close (device);
-
-  /* if (net) grub_net_close (net);  */
-
-  grub_free (file);
-
-  return 0;
-}
-
-grub_ssize_t
-grub_file_read (grub_file_t file, void *buf, grub_size_t len)
-{
-  grub_ssize_t res;
-
-  if (file->offset > file->size)
-    {
-      grub_error (GRUB_ERR_OUT_OF_RANGE,
-                 "attempt to read past the end of file");
-      return -1;
-    }
-
-  if (len == 0 || len > file->size - file->offset)
-    len = file->size - file->offset;
-
-  /* Prevent an overflow.  */
-  if ((grub_ssize_t) len < 0)
-    len >>= 1;
-
-  if (len == 0)
-    return 0;
-
-  res = (file->fs->read) (file, buf, len);
-  if (res > 0)
-    file->offset += res;
-
-  return res;
-}
-
-grub_err_t
-grub_file_close (grub_file_t file)
-{
-  if (file->fs->close)
-    (file->fs->close) (file);
-
-  if (file->device)
-    grub_device_close (file->device);
-  grub_free (file);
-  return grub_errno;
-}
-
-grub_off_t
-grub_file_seek (grub_file_t file, grub_off_t offset)
-{
-  grub_off_t old;
-
-  if (offset > file->size)
-    {
-      grub_error (GRUB_ERR_OUT_OF_RANGE,
-                 "attempt to seek outside of the file");
-      return -1;
-    }
-
-  old = file->offset;
-  file->offset = offset;
-  return old;
-}
diff --git a/kern/fs.c b/kern/fs.c
deleted file mode 100644 (file)
index 0c45637..0000000
--- a/kern/fs.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/* fs.c - filesystem manager */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/disk.h>
-#include <grub/net.h>
-#include <grub/fs.h>
-#include <grub/file.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/types.h>
-#include <grub/mm.h>
-#include <grub/term.h>
-
-static grub_fs_t grub_fs_list;
-
-grub_fs_autoload_hook_t grub_fs_autoload_hook = 0;
-
-void
-grub_fs_register (grub_fs_t fs)
-{
-  fs->next = grub_fs_list;
-  grub_fs_list = fs;
-}
-
-void
-grub_fs_unregister (grub_fs_t fs)
-{
-  grub_fs_t *p, q;
-
-  for (p = &grub_fs_list, q = *p; q; p = &(q->next), q = q->next)
-    if (q == fs)
-      {
-       *p = q->next;
-       break;
-      }
-}
-
-void
-grub_fs_iterate (int (*hook) (const grub_fs_t fs))
-{
-  grub_fs_t p;
-
-  for (p = grub_fs_list; p; p = p->next)
-    if (hook (p))
-      break;
-}
-
-grub_fs_t
-grub_fs_probe (grub_device_t device)
-{
-  grub_fs_t p;
-  auto int dummy_func (const char *filename,
-                      const struct grub_dirhook_info *info);
-
-  int dummy_func (const char *filename __attribute__ ((unused)),
-                 const struct grub_dirhook_info *info  __attribute__ ((unused)))
-    {
-      return 1;
-    }
-
-  if (device->disk)
-    {
-      /* Make it sure not to have an infinite recursive calls.  */
-      static int count = 0;
-
-      for (p = grub_fs_list; p; p = p->next)
-       {
-         grub_dprintf ("fs", "Detecting %s...\n", p->name);
-         (p->dir) (device, "/", dummy_func);
-         if (grub_errno == GRUB_ERR_NONE)
-           return p;
-
-         grub_error_push ();
-         grub_dprintf ("fs", "%s detection failed.\n", p->name);
-         grub_error_pop ();
-
-         if (grub_errno != GRUB_ERR_BAD_FS)
-           return 0;
-
-         grub_errno = GRUB_ERR_NONE;
-       }
-
-      /* Let's load modules automatically.  */
-      if (grub_fs_autoload_hook && count == 0)
-       {
-         count++;
-
-         while (grub_fs_autoload_hook ())
-           {
-             p = grub_fs_list;
-
-             (p->dir) (device, "/", dummy_func);
-             if (grub_errno == GRUB_ERR_NONE)
-               {
-                 count--;
-                 return p;
-               }
-
-             if (grub_errno != GRUB_ERR_BAD_FS)
-               {
-                 count--;
-                 return 0;
-               }
-
-             grub_errno = GRUB_ERR_NONE;
-           }
-
-         count--;
-       }
-    }
-  else if (device->net->fs)
-    return device->net->fs;
-
-  grub_error (GRUB_ERR_UNKNOWN_FS, "unknown filesystem");
-  return 0;
-}
-
-\f
-
-/* Block list support routines.  */
-
-struct grub_fs_block
-{
-  grub_disk_addr_t offset;
-  unsigned long length;
-};
-
-static grub_err_t
-grub_fs_blocklist_open (grub_file_t file, const char *name)
-{
-  char *p = (char *) name;
-  unsigned num = 0;
-  unsigned i;
-  grub_disk_t disk = file->device->disk;
-  struct grub_fs_block *blocks;
-
-  /* First, count the number of blocks.  */
-  do
-    {
-      num++;
-      p = grub_strchr (p, ',');
-      if (p)
-       p++;
-    }
-  while (p);
-
-  /* Allocate a block list.  */
-  blocks = grub_zalloc (sizeof (struct grub_fs_block) * (num + 1));
-  if (! blocks)
-    return 0;
-
-  file->size = 0;
-  p = (char *) name;
-  for (i = 0; i < num; i++)
-    {
-      if (*p != '+')
-       {
-         blocks[i].offset = grub_strtoull (p, &p, 0);
-         if (grub_errno != GRUB_ERR_NONE || *p != '+')
-           {
-             grub_error (GRUB_ERR_BAD_FILENAME,
-                         "invalid file name `%s'", name);
-             goto fail;
-           }
-       }
-
-      p++;
-      blocks[i].length = grub_strtoul (p, &p, 0);
-      if (grub_errno != GRUB_ERR_NONE
-         || blocks[i].length == 0
-         || (*p && *p != ',' && ! grub_isspace (*p)))
-       {
-         grub_error (GRUB_ERR_BAD_FILENAME,
-                     "invalid file name `%s'", name);
-         goto fail;
-       }
-
-      if (disk->total_sectors < blocks[i].offset + blocks[i].length)
-       {
-         grub_error (GRUB_ERR_BAD_FILENAME, "beyond the total sectors");
-         goto fail;
-       }
-
-      file->size += (blocks[i].length << GRUB_DISK_SECTOR_BITS);
-      p++;
-    }
-
-  file->data = blocks;
-
-  return GRUB_ERR_NONE;
-
- fail:
-  grub_free (blocks);
-  return grub_errno;
-}
-
-static grub_ssize_t
-grub_fs_blocklist_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  struct grub_fs_block *p;
-  grub_disk_addr_t sector;
-  grub_off_t offset;
-  grub_ssize_t ret = 0;
-
-  if (len > file->size - file->offset)
-    len = file->size - file->offset;
-
-  sector = (file->offset >> GRUB_DISK_SECTOR_BITS);
-  offset = (file->offset & (GRUB_DISK_SECTOR_SIZE - 1));
-  for (p = file->data; p->length && len > 0; p++)
-    {
-      if (sector < p->length)
-       {
-         grub_size_t size;
-
-         size = len;
-         if (((size + offset + GRUB_DISK_SECTOR_SIZE - 1)
-              >> GRUB_DISK_SECTOR_BITS) > p->length - sector)
-           size = ((p->length - sector) << GRUB_DISK_SECTOR_BITS) - offset;
-
-         if (grub_disk_read (file->device->disk, p->offset + sector, offset,
-                             size, buf) != GRUB_ERR_NONE)
-           return -1;
-
-         ret += size;
-         len -= size;
-         sector -= ((size + offset) >> GRUB_DISK_SECTOR_BITS);
-         offset = ((size + offset) & (GRUB_DISK_SECTOR_SIZE - 1));
-       }
-      else
-       sector -= p->length;
-    }
-
-  return ret;
-}
-
-struct grub_fs grub_fs_blocklist =
-  {
-    .name = "blocklist",
-    .dir = 0,
-    .open = grub_fs_blocklist_open,
-    .read = grub_fs_blocklist_read,
-    .close = 0,
-    .next = 0
-  };
diff --git a/kern/generic/millisleep.c b/kern/generic/millisleep.c
deleted file mode 100644 (file)
index 9d5971f..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* millisleep.c - generic millisleep function.
- * The generic implementation of these functions can be used for architectures
- * or platforms that do not have a more specialized implementation. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/time.h>
-
-void
-grub_millisleep (grub_uint32_t ms)
-{
-  grub_uint64_t start;
-
-  start = grub_get_time_ms ();
-
-  /* Instead of setting an end time and looping while the current time is
-     less than that, comparing the elapsed sleep time with the desired sleep
-     time handles the (unlikely!) case that the timer would wrap around
-     during the sleep. */
-
-  while (grub_get_time_ms () - start < ms)
-    grub_cpu_idle ();
-}
diff --git a/kern/generic/rtc_get_time_ms.c b/kern/generic/rtc_get_time_ms.c
deleted file mode 100644 (file)
index 3592336..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* rtc_get_time_ms.c - get_time_ms implementation using platform RTC.
- * The generic implementation of these functions can be used for architectures
- * or platforms that do not have a more specialized implementation. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/time.h>
-#include <grub/misc.h>
-
-/* Calculate the time in milliseconds since the epoch based on the RTC. */
-grub_uint64_t
-grub_rtc_get_time_ms (void)
-{
-  /* By dimensional analysis:
-
-      1000 ms   N rtc ticks       1 s
-      ------- * ----------- * ----------- = 1000*N/T ms
-        1 s          1        T rtc ticks
-   */
-  grub_uint64_t ticks_ms_per_sec = ((grub_uint64_t) 1000) * grub_get_rtc ();
-  return grub_divmod64 (ticks_ms_per_sec, GRUB_TICKS_PER_SECOND, 0);
-}
diff --git a/kern/handler.c b/kern/handler.c
deleted file mode 100644 (file)
index 2bf8531..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* handler.c - grub handler function */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/handler.h>
-
-grub_handler_class_t grub_handler_class_list;
-
-void
-grub_handler_register (grub_handler_class_t class, grub_handler_t handler)
-{
-  int first_handler = (class->handler_list == 0);
-
-  grub_list_push (GRUB_AS_LIST_P (&class->handler_list),
-                 GRUB_AS_LIST (handler));
-
-  if (first_handler)
-    {
-      grub_list_push (GRUB_AS_LIST_P (&grub_handler_class_list),
-                     GRUB_AS_LIST (class));
-      grub_handler_set_current (class, handler);
-    }
-}
-
-void
-grub_handler_unregister (grub_handler_class_t class, grub_handler_t handler)
-{
-  grub_list_remove (GRUB_AS_LIST_P (&class->handler_list),
-                   GRUB_AS_LIST (handler));
-
-  if (class->handler_list == 0)
-    grub_list_remove (GRUB_AS_LIST_P (&grub_handler_class_list),
-                     GRUB_AS_LIST (class));
-}
-
-grub_err_t
-grub_handler_set_current (grub_handler_class_t class, grub_handler_t handler)
-{
-  if (class->cur_handler && class->cur_handler->fini)
-    if ((class->cur_handler->fini) () != GRUB_ERR_NONE)
-      return grub_errno;
-
-  if (handler->init)
-    if ((handler->init) () != GRUB_ERR_NONE)
-      return grub_errno;
-
-  class->cur_handler = handler;
-  return GRUB_ERR_NONE;
-}
diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c
deleted file mode 100644 (file)
index f7b8370..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/kernel.h>
-#include <grub/mm.h>
-#include <grub/machine/time.h>
-#include <grub/machine/init.h>
-#include <grub/machine/memory.h>
-#include <grub/machine/console.h>
-#include <grub/machine/kernel.h>
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/loader.h>
-#include <grub/env.h>
-#include <grub/cache.h>
-#include <grub/time.h>
-#include <grub/symbol.h>
-#include <grub/cpu/io.h>
-#include <grub/cpu/kernel.h>
-#include <grub/cpu/tsc.h>
-
-#define GRUB_FLOPPY_REG_DIGITAL_OUTPUT         0x3f2
-
-extern char _start[];
-extern char _end[];
-
-grub_addr_t grub_os_area_addr;
-grub_size_t grub_os_area_size;
-
-grub_uint32_t
-grub_get_rtc (void)
-{
-  grub_fatal ("grub_get_rtc() is not implemented.\n");
-}
-
-/* Stop the floppy drive from spinning, so that other software is
-   jumped to with a known state.  */
-void
-grub_stop_floppy (void)
-{
-  grub_outb (0, GRUB_FLOPPY_REG_DIGITAL_OUTPUT);
-}
-
-void
-grub_exit (void)
-{
-  /* We can't use grub_fatal() in this function.  This would create an infinite
-     loop, since grub_fatal() calls grub_abort() which in turn calls grub_exit().  */
-  while (1)
-    grub_cpu_idle ();
-}
-
-void
-grub_machine_init (void)
-{
-  /* Initialize the console as early as possible.  */
-  grub_vga_text_init ();
-
-  auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
-  {
-#if GRUB_CPU_SIZEOF_VOID_P == 4
-    /* Restrict ourselves to 32-bit memory space.  */
-    if (addr > GRUB_ULONG_MAX)
-      return 0;
-    if (addr + size > GRUB_ULONG_MAX)
-      size = GRUB_ULONG_MAX - addr;
-#endif
-
-    if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
-      return 0;
-
-    /* Avoid the lower memory.  */
-    if (addr < GRUB_MEMORY_MACHINE_LOWER_SIZE)
-      {
-       if (addr + size <= GRUB_MEMORY_MACHINE_LOWER_SIZE)
-         return 0;
-       else
-         {
-           size -= GRUB_MEMORY_MACHINE_LOWER_SIZE - addr;
-           addr = GRUB_MEMORY_MACHINE_LOWER_SIZE;
-         }
-      }
-
-    if (addr == GRUB_MEMORY_MACHINE_UPPER_START
-       || (addr >= GRUB_MEMORY_MACHINE_LOWER_SIZE
-           && addr <= GRUB_MEMORY_MACHINE_UPPER_START
-           && (addr + size > GRUB_MEMORY_MACHINE_UPPER_START)))
-      {
-       grub_size_t quarter = size >> 2;
-
-       grub_os_area_addr = addr;
-       grub_os_area_size = size - quarter;
-       grub_mm_init_region ((void *) (grub_os_area_addr + grub_os_area_size),
-                            quarter);
-      }
-    else
-      grub_mm_init_region ((void *) (grub_addr_t) addr, (grub_size_t) size);
-
-    return 0;
-  }
-
-#if defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU)
-  grub_machine_mmap_init ();
-#endif
-  grub_machine_mmap_iterate (heap_init);
-
-  grub_tsc_init ();
-}
-
-void
-grub_machine_set_prefix (void)
-{
-  /* Initialize the prefix.  */
-  grub_env_set ("prefix", grub_prefix);
-}
-
-void
-grub_machine_fini (void)
-{
-  grub_vga_text_fini ();
-  grub_stop_floppy ();
-}
-
-/* Return the end of the core image.  */
-grub_addr_t
-grub_arch_modules_addr (void)
-{
-#ifdef GRUB_MACHINE_QEMU
-  return grub_core_entry_addr + grub_kernel_image_size;
-#else
-  return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN);
-#endif
-}
diff --git a/kern/i386/coreboot/mmap.c b/kern/i386/coreboot/mmap.c
deleted file mode 100644 (file)
index d06627a..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/machine/memory.h>
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-
-static grub_err_t
-grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t))
-{
-  grub_linuxbios_table_header_t table_header;
-  grub_linuxbios_table_item_t table_item;
-
-  auto int check_signature (grub_linuxbios_table_header_t);
-  int check_signature (grub_linuxbios_table_header_t tbl_header)
-  {
-    if (! grub_memcmp (tbl_header->signature, "LBIO", 4))
-      return 1;
-
-    return 0;
-  }
-
-  /* Assuming table_header is aligned to its size (8 bytes).  */
-
-  for (table_header = (grub_linuxbios_table_header_t) 0x500;
-       table_header < (grub_linuxbios_table_header_t) 0x1000; table_header++)
-    if (check_signature (table_header))
-      goto signature_found;
-
-  for (table_header = (grub_linuxbios_table_header_t) 0xf0000;
-       table_header < (grub_linuxbios_table_header_t) 0x100000; table_header++)
-    if (check_signature (table_header))
-      goto signature_found;
-
-  grub_fatal ("Could not find coreboot table\n");
-
-signature_found:
-
-  table_item =
-    (grub_linuxbios_table_item_t) ((long) table_header +
-                              (long) table_header->size);
-  for (; table_item->size;
-       table_item = (grub_linuxbios_table_item_t) ((long) table_item + (long) table_item->size))
-    {
-      if (table_item->tag == GRUB_LINUXBIOS_MEMBER_LINK
-         && check_signature ((grub_linuxbios_table_header_t) (grub_addr_t)
-                             *(grub_uint64_t *) (table_item + 1)))
-       {
-         table_header = (grub_linuxbios_table_header_t) (grub_addr_t)
-           *(grub_uint64_t *) (table_item + 1);
-         goto signature_found;   
-       }
-      if (hook (table_item))
-       return 1;
-    }
-
-  return 0;
-}
-
-grub_err_t
-grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
-{
-  mem_region_t mem_region;
-
-  auto int iterate_linuxbios_table (grub_linuxbios_table_item_t);
-  int iterate_linuxbios_table (grub_linuxbios_table_item_t table_item)
-  {
-    if (table_item->tag != GRUB_LINUXBIOS_MEMBER_MEMORY)
-      return 0;
-
-    mem_region =
-      (mem_region_t) ((long) table_item +
-                                sizeof (struct grub_linuxbios_table_item));
-    while ((long) mem_region < (long) table_item + (long) table_item->size)
-      {
-       if (hook (mem_region->addr, mem_region->size,
-                 /* Multiboot mmaps match with the coreboot mmap definition.
-                    Therefore, we can just pass type through.  */
-                 mem_region->type))
-         return 1;
-
-       mem_region++;
-      }
-
-    return 0;
-  }
-
-  grub_linuxbios_table_iterate (iterate_linuxbios_table);
-
-  return 0;
-}
diff --git a/kern/i386/coreboot/startup.S b/kern/i386/coreboot/startup.S
deleted file mode 100644 (file)
index 2c4a941..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-#include <grub/machine/memory.h>
-#include <grub/cpu/linux.h>
-#include <grub/cpu/kernel.h>
-#include <multiboot.h>
-#include <multiboot2.h>
-
-/*
- * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
- *       So the first three arguments are passed in %eax, %edx, and %ecx,
- *       respectively, and if a function has a fixed number of arguments
- *       and the number if greater than three, the function must return
- *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
- */
-
-       .file   "startup.S"
-       .text
-       .globl  start, _start
-start:
-_start:
-       jmp codestart
-
-       /*
-        *  This is a special data area at a fixed offset from the beginning.
-        */
-
-       . = _start + GRUB_KERNEL_CPU_PREFIX
-
-VARIABLE(grub_prefix)
-       /* to be filled by grub-mkimage */
-
-       /*
-        *  Leave some breathing room for the prefix.
-        */
-
-       . = _start + GRUB_KERNEL_CPU_DATA_END
-
-/*
- *  Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself).
- */
-       .p2align        2       /* force 4-byte alignment */
-multiboot_header:
-       /* magic */
-       .long   0x1BADB002
-       /* flags */
-       .long   MULTIBOOT_MEMORY_INFO
-       /* checksum */
-       .long   -0x1BADB002 - MULTIBOOT_MEMORY_INFO
-
-codestart:
-#ifdef GRUB_MACHINE_MULTIBOOT
-       cmpl    $MULTIBOOT_BOOTLOADER_MAGIC, %eax
-       jne 0f
-       movl    %ebx, EXT_C(startup_multiboot_info)
-0:
-#endif
-
-       /* initialize the stack */
-       movl $GRUB_MEMORY_MACHINE_PROT_STACK, %esp
-
-       /* jump to the main body of C code */
-       jmp EXT_C(grub_main)
-
-/*
- *  prot_to_real and associated structures (but NOT real_to_prot, that is
- *  only needed for BIOS gates).
- */
-#include "../realmode.S"
-
-/*
- *  Routines needed by Linux and Multiboot loaders.
- */
-#include "../loader.S"
diff --git a/kern/i386/dl.c b/kern/i386/dl.c
deleted file mode 100644 (file)
index 5785496..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/* dl-386.c - arch-dependent part of loadable module support */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/elf.h>
-#include <grub/misc.h>
-#include <grub/err.h>
-
-/* Check if EHDR is a valid ELF header.  */
-grub_err_t
-grub_arch_dl_check_header (void *ehdr)
-{
-  Elf_Ehdr *e = ehdr;
-
-  /* Check the magic numbers.  */
-  if (e->e_ident[EI_CLASS] != ELFCLASS32
-      || e->e_ident[EI_DATA] != ELFDATA2LSB
-      || e->e_machine != EM_386)
-    return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
-
-  return GRUB_ERR_NONE;
-}
-
-/* Relocate symbols.  */
-grub_err_t
-grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
-{
-  Elf_Ehdr *e = ehdr;
-  Elf_Shdr *s;
-  Elf_Word entsize;
-  unsigned i;
-
-  /* Find a symbol table.  */
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_SYMTAB)
-      break;
-
-  if (i == e->e_shnum)
-    return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
-
-  entsize = s->sh_entsize;
-
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_REL)
-      {
-       grub_dl_segment_t seg;
-
-       /* Find the target segment.  */
-       for (seg = mod->segment; seg; seg = seg->next)
-         if (seg->section == s->sh_info)
-           break;
-
-       if (seg)
-         {
-           Elf_Rel *rel, *max;
-
-           for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
-                  max = rel + s->sh_size / s->sh_entsize;
-                rel < max;
-                rel++)
-             {
-               Elf_Word *addr;
-               Elf_Sym *sym;
-
-               if (seg->size < rel->r_offset)
-                 return grub_error (GRUB_ERR_BAD_MODULE,
-                                    "reloc offset is out of the segment");
-
-               addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
-               sym = (Elf_Sym *) ((char *) mod->symtab
-                                    + entsize * ELF_R_SYM (rel->r_info));
-
-               switch (ELF_R_TYPE (rel->r_info))
-                 {
-                 case R_386_32:
-                   *addr += sym->st_value;
-                   break;
-
-                 case R_386_PC32:
-                   *addr += (sym->st_value - (Elf_Word) seg->addr
-                             - rel->r_offset);
-                   break;
-                 }
-             }
-         }
-      }
-
-  return GRUB_ERR_NONE;
-}
diff --git a/kern/i386/efi/init.c b/kern/i386/efi/init.c
deleted file mode 100644 (file)
index f73f828..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* init.c - initialize an x86-based EFI system */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/cache.h>
-#include <grub/kernel.h>
-#include <grub/efi/efi.h>
-#include <grub/i386/tsc.h>
-
-void
-grub_machine_init (void)
-{
-  grub_efi_init ();
-  grub_tsc_init ();
-}
-
-void
-grub_machine_fini (void)
-{
-  grub_efi_fini ();
-}
-
-void
-grub_machine_set_prefix (void)
-{
-  grub_efi_set_prefix ();
-}
diff --git a/kern/i386/efi/startup.S b/kern/i386/efi/startup.S
deleted file mode 100644 (file)
index 5b464ab..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/* startup.S - bootstrap GRUB itself */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <grub/symbol.h>
-#include <grub/boot.h>
-
-        .file   "startup.S"
-        .text
-        .globl  start, _start
-start:
-_start:
-       jmp codestart
-
-        /*
-         *  Compatibility version number
-         *
-         *  These MUST be at byte offset 6 and 7 of the executable
-         *  DO NOT MOVE !!!
-         */
-        . = _start + 0x6
-        .byte   GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
-
-        /*
-         *  This is a special data area 8 bytes from the beginning.
-         */
-
-        . = _start + 0x8
-
-VARIABLE(grub_prefix)
-       /* to be filled by grub-mkimage */
-
-        /*
-         *  Leave some breathing room for the prefix.
-         */
-
-        . = _start + 0x50
-
-codestart:
-       /*
-        *  EFI_SYSTEM_TABLE * and EFI_HANDLE are passed on the stack.
-        */
-       movl    4(%esp), %eax
-       movl    %eax, EXT_C(grub_efi_image_handle)
-       movl    8(%esp), %eax
-       movl    %eax, EXT_C(grub_efi_system_table)
-       call    EXT_C(grub_main)
-       ret
-
-#include "../realmode.S"
diff --git a/kern/i386/halt.c b/kern/i386/halt.c
deleted file mode 100644 (file)
index 10805e4..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/cpu/io.h>
-#include <grub/machine/init.h>
-#include <grub/misc.h>
-
-const char bochs_shutdown[] = "Shutdown";
-
-void
-grub_halt (void)
-{
-  unsigned int i;
-
-  /* Disable interrupts.  */
-  __asm__ __volatile__ ("cli");
-
-  /* Bochs, QEMU, etc.  */
-  for (i = 0; i < sizeof (bochs_shutdown) - 1; i++)
-    grub_outb (bochs_shutdown[i], 0x8900);
-
-  grub_printf ("GRUB doesn't know how to halt this machine yet!\n");
-
-  /* In order to return we'd have to check what the previous status of IF
-     flag was.  But user most likely doesn't want to return anyway ...  */
-  grub_stop ();
-}
diff --git a/kern/i386/ieee1275/init.c b/kern/i386/ieee1275/init.c
deleted file mode 100644 (file)
index 9fb9873..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*  init.c -- Initialize GRUB on Open Firmware.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/cache.h>
-
-void grub_stop_floppy (void);
-
-void
-grub_stop_floppy (void)
-{
-}
diff --git a/kern/i386/ieee1275/startup.S b/kern/i386/ieee1275/startup.S
deleted file mode 100644 (file)
index 35258ad..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-#include <grub/machine/memory.h>
-#include <grub/cpu/linux.h>
-#include <grub/cpu/kernel.h>
-#include <multiboot.h>
-#include <multiboot2.h>
-
-/*
- * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
- *       So the first three arguments are passed in %eax, %edx, and %ecx,
- *       respectively, and if a function has a fixed number of arguments
- *       and the number if greater than three, the function must return
- *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
- */
-
-       .file   "startup.S"
-       .text
-       .globl  start, _start
-
-start:
-_start:
-       jmp codestart
-
-       /*
-        *  This is a special data area at a fixed offset from the beginning.
-        */
-
-       . = _start + GRUB_KERNEL_CPU_PREFIX
-
-VARIABLE(grub_prefix)
-       /* to be filled by grub-mkimage */
-
-       /*
-        *  Leave some breathing room for the prefix.
-        */
-
-       . = _start + GRUB_KERNEL_CPU_DATA_END
-
-codestart:
-       movl %eax, EXT_C(grub_ieee1275_entry_fn)
-       jmp EXT_C(grub_main)
-
-/*
- *  prot_to_real and associated structures (but NOT real_to_prot, that is
- *  only needed for BIOS gates).
- */
-#include "../realmode.S"
-
-/*
- *  Routines needed by Linux and Multiboot loaders.
- */
-#include "../loader.S"
diff --git a/kern/i386/loader.S b/kern/i386/loader.S
deleted file mode 100644 (file)
index ed57c43..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-/*
- * Note: These functions defined in this file may be called from C.
- *       Be careful of that you must not modify some registers. Quote
- *       from gcc-2.95.2/gcc/config/i386/i386.h:
-
-   1 for registers not available across function calls.
-   These must include the FIXED_REGISTERS and also any
-   registers that can be used without being saved.
-   The latter must include the registers where values are returned
-   and the register where structure-value addresses are passed.
-   Aside from that, you can include as many other registers as you like.
-
-  ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
-{  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
- */
-
-/*
- * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
- *       So the first three arguments are passed in %eax, %edx, and %ecx,
- *       respectively, and if a function has a fixed number of arguments
- *       and the number if greater than three, the function must return
- *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
- */
-
-/*
- *  This is the area for all of the special variables.
- */
-
-       .p2align        2       /* force 4-byte alignment */
-
-/*
- * void grub_linux_boot_zimage (void)
- */
-VARIABLE(grub_linux_prot_size)
-       .long   0
-VARIABLE(grub_linux_tmp_addr)
-       .long   0
-VARIABLE(grub_linux_real_addr)
-       .long   0
-VARIABLE(grub_linux_is_bzimage)
-       .long   0
-
-FUNCTION(grub_linux16_real_boot)
-       /* Must be done before zImage copy.  */
-       call    EXT_C(grub_dl_unload_all)
-
-       movl    EXT_C(grub_linux_is_bzimage), %ebx
-       test    %ebx, %ebx
-       jne bzimage
-
-       /* copy the kernel */
-       movl    EXT_C(grub_linux_prot_size), %ecx
-       addl    $3, %ecx
-       shrl    $2, %ecx
-       movl    $GRUB_LINUX_BZIMAGE_ADDR, %esi
-       movl    $GRUB_LINUX_ZIMAGE_ADDR, %edi
-       cld
-       rep
-       movsl
-
-bzimage:
-       movl    EXT_C(grub_linux_real_addr), %ebx
-
-       /* copy the real mode code */
-       movl    EXT_C(grub_linux_tmp_addr), %esi
-       movl    %ebx, %edi
-       movl    $GRUB_LINUX_SETUP_MOVE_SIZE, %ecx
-       cld
-       rep
-       movsb
-
-       /* change %ebx to the segment address */
-       shrl    $4, %ebx
-       movl    %ebx, %eax
-       addl    $0x20, %eax
-       movw    %ax, linux_setup_seg
-
-       /* XXX new stack pointer in safe area for calling functions */
-       movl    $0x4000, %esp
-       call    EXT_C(grub_stop_floppy)
-
-       /* final setup for linux boot */
-       call    prot_to_real
-       .code16
-
-       cli
-       movw    %bx, %ss
-       movw    $GRUB_LINUX_SETUP_STACK, %sp
-
-       movw    %bx, %ds
-       movw    %bx, %es
-       movw    %bx, %fs
-       movw    %bx, %gs
-
-       /* ljmp */
-       .byte   0xea
-       .word   0
-linux_setup_seg:
-       .word   0
-       .code32
-
diff --git a/kern/i386/misc.S b/kern/i386/misc.S
deleted file mode 100644 (file)
index 7d57df9..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-
-       .text
-/*
- *  This call is special...  it never returns...  in fact it should simply
- *  hang at this point!
- */
-FUNCTION(grub_stop)
-       cli
-1:     hlt
-       jmp     1b
diff --git a/kern/i386/multiboot_mmap.c b/kern/i386/multiboot_mmap.c
deleted file mode 100644 (file)
index 0f463c2..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/machine/init.h>
-#include <grub/machine/memory.h>
-#include <grub/types.h>
-#include <grub/multiboot.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-
-grub_size_t grub_lower_mem, grub_upper_mem;
-
-/* A pointer to the MBI in its initial location.  */
-struct multiboot_info *startup_multiboot_info;
-
-/* The MBI has to be copied to our BSS so that it won't be
-   overwritten.  This is its final location.  */
-static struct multiboot_info kern_multiboot_info;
-
-/* Unfortunately we can't use heap at this point.  But 32 looks like a sane
-   limit (used by memtest86).  */
-static grub_uint8_t mmap_entries[sizeof (struct multiboot_mmap_entry) * 32];
-
-void
-grub_machine_mmap_init ()
-{
-  if (! startup_multiboot_info)
-    grub_fatal ("Unable to find Multiboot Information (is CONFIG_MULTIBOOT disabled in coreboot?)");
-
-  /* Move MBI to a safe place.  */
-  grub_memmove (&kern_multiboot_info, startup_multiboot_info, sizeof (struct multiboot_info));
-
-  if ((kern_multiboot_info.flags & MULTIBOOT_INFO_MEM_MAP) == 0)
-    grub_fatal ("Missing Multiboot memory information");
-
-  /* Move the memory map to a safe place.  */
-  if (kern_multiboot_info.mmap_length > sizeof (mmap_entries))
-    {
-      grub_printf ("WARNING: Memory map size exceeds limit (0x%x > 0x%x); it will be truncated\n",
-                  kern_multiboot_info.mmap_length, sizeof (mmap_entries));
-      kern_multiboot_info.mmap_length = sizeof (mmap_entries);
-    }
-  grub_memmove (mmap_entries, (void *) kern_multiboot_info.mmap_addr, kern_multiboot_info.mmap_length);
-  kern_multiboot_info.mmap_addr = (grub_uint32_t) mmap_entries;
-
-  if ((kern_multiboot_info.flags & MULTIBOOT_INFO_MEMORY) == 0)
-    {
-      grub_lower_mem = GRUB_MEMORY_MACHINE_LOWER_USABLE;
-      grub_upper_mem = 0;
-    }
-  else
-    {
-      grub_lower_mem = kern_multiboot_info.mem_lower * 1024;
-      grub_upper_mem = kern_multiboot_info.mem_upper * 1024;
-    }
-}
-
-grub_err_t
-grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
-{
-  struct multiboot_mmap_entry *entry = (void *) kern_multiboot_info.mmap_addr;
-
-  while ((unsigned long) entry < kern_multiboot_info.mmap_addr + kern_multiboot_info.mmap_length)
-    {
-      if (hook (entry->addr, entry->len, entry->type))
-       break;
-
-      entry = (void *) ((grub_addr_t) entry + entry->size + sizeof (entry->size));
-    }
-
-  return 0;
-}
diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c
deleted file mode 100644 (file)
index fa646df..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/kernel.h>
-#include <grub/mm.h>
-#include <grub/machine/boot.h>
-#include <grub/machine/init.h>
-#include <grub/machine/memory.h>
-#include <grub/machine/console.h>
-#include <grub/machine/kernel.h>
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/loader.h>
-#include <grub/env.h>
-#include <grub/cache.h>
-#include <grub/time.h>
-#include <grub/cpu/tsc.h>
-
-struct mem_region
-{
-  grub_addr_t addr;
-  grub_size_t size;
-};
-
-#define MAX_REGIONS    32
-
-static struct mem_region mem_regions[MAX_REGIONS];
-static int num_regions;
-
-grub_addr_t grub_os_area_addr;
-grub_size_t grub_os_area_size;
-
-static char *
-make_install_device (void)
-{
-  /* XXX: This should be enough.  */
-  char dev[100], *ptr = dev;
-
-  if (grub_prefix[0] != '(')
-    {
-      /* No hardcoded root partition - make it from the boot drive and the
-        partition number encoded at the install time.  */
-      if (grub_boot_drive == GRUB_BOOT_MACHINE_PXE_DL)
-       {
-         grub_strcpy (dev, "(pxe");
-         ptr += sizeof ("(pxe") - 1;
-       }
-      else
-       {
-         grub_snprintf (dev, sizeof (dev),
-                        "(%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f',
-                        grub_boot_drive & 0x7f);
-         ptr += grub_strlen (ptr);
-
-         if (grub_install_dos_part >= 0)
-           grub_snprintf (ptr, sizeof (dev) - (ptr - dev),
-                          ",%u", grub_install_dos_part + 1);
-         ptr += grub_strlen (ptr);
-
-         if (grub_install_bsd_part >= 0)
-           grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%c",
-                          grub_install_bsd_part + 'a');
-         ptr += grub_strlen (ptr);
-       }
-
-      grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ")%s", grub_prefix);
-      grub_strcpy (grub_prefix, dev);
-    }
-
-  return grub_prefix;
-}
-
-/* Add a memory region.  */
-static void
-add_mem_region (grub_addr_t addr, grub_size_t size)
-{
-  if (num_regions == MAX_REGIONS)
-    /* Ignore.  */
-    return;
-
-  mem_regions[num_regions].addr = addr;
-  mem_regions[num_regions].size = size;
-  num_regions++;
-}
-
-/* Compact memory regions.  */
-static void
-compact_mem_regions (void)
-{
-  int i, j;
-
-  /* Sort them.  */
-  for (i = 0; i < num_regions - 1; i++)
-    for (j = i + 1; j < num_regions; j++)
-      if (mem_regions[i].addr > mem_regions[j].addr)
-       {
-         struct mem_region tmp = mem_regions[i];
-         mem_regions[i] = mem_regions[j];
-         mem_regions[j] = tmp;
-       }
-
-  /* Merge overlaps.  */
-  for (i = 0; i < num_regions - 1; i++)
-    if (mem_regions[i].addr + mem_regions[i].size >= mem_regions[i + 1].addr)
-      {
-       j = i + 1;
-
-       if (mem_regions[i].addr + mem_regions[i].size
-           < mem_regions[j].addr + mem_regions[j].size)
-         mem_regions[i].size = (mem_regions[j].addr + mem_regions[j].size
-                                - mem_regions[i].addr);
-
-       grub_memmove (mem_regions + j, mem_regions + j + 1,
-                     (num_regions - j - 1) * sizeof (struct mem_region));
-       i--;
-        num_regions--;
-      }
-}
-
-void
-grub_machine_init (void)
-{
-  int i;
-  int grub_lower_mem;
-
-  /* Initialize the console as early as possible.  */
-  grub_console_init ();
-
-  grub_lower_mem = grub_get_memsize (0) << 10;
-
-  /* Sanity check.  */
-  if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END)
-    grub_fatal ("too small memory");
-
-#if 0
-  /* Turn on Gate A20 to access >1MB.  */
-  grub_gate_a20 (1);
-#endif
-
-/* FIXME: This prevents loader/i386/linux.c from using low memory.  When our
-   heap implements support for requesting a chunk in low memory, this should
-   no longer be a problem.  */
-#if 0
-  /* Add the lower memory into free memory.  */
-  if (grub_lower_mem >= GRUB_MEMORY_MACHINE_RESERVED_END)
-    add_mem_region (GRUB_MEMORY_MACHINE_RESERVED_END,
-                   grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END);
-#endif
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
-    {
-      /* Avoid the lower memory.  */
-      if (addr < 0x100000)
-       {
-         if (size <= 0x100000 - addr)
-           return 0;
-
-         size -= 0x100000 - addr;
-         addr = 0x100000;
-       }
-
-      /* Ignore >4GB.  */
-      if (addr <= 0xFFFFFFFF && type == GRUB_MACHINE_MEMORY_AVAILABLE)
-       {
-         grub_size_t len;
-
-         len = (grub_size_t) ((addr + size > 0xFFFFFFFF)
-                ? 0xFFFFFFFF - addr
-                : size);
-         add_mem_region (addr, len);
-       }
-
-      return 0;
-    }
-
-  grub_machine_mmap_iterate (hook);
-
-  compact_mem_regions ();
-
-  /* Add the memory regions to free memory, except for the region starting
-     from 1MB. This region is partially used for loading OS images.
-     For now, 1/4 of this is added to free memory.  */
-  for (i = 0; i < num_regions; i++)
-    if (mem_regions[i].addr == 0x100000)
-      {
-       grub_size_t quarter = mem_regions[i].size >> 2;
-
-       grub_os_area_addr = mem_regions[i].addr;
-       grub_os_area_size = mem_regions[i].size - quarter;
-       grub_mm_init_region ((void *) (grub_os_area_addr + grub_os_area_size),
-                            quarter);
-      }
-    else
-      grub_mm_init_region ((void *) mem_regions[i].addr, mem_regions[i].size);
-
-  if (! grub_os_area_addr)
-    grub_fatal ("no upper memory");
-
-  grub_tsc_init ();
-}
-
-void
-grub_machine_set_prefix (void)
-{
-  /* Initialize the prefix.  */
-  grub_env_set ("prefix", make_install_device ());
-}
-
-void
-grub_machine_fini (void)
-{
-  grub_console_fini ();
-  grub_stop_floppy ();
-}
-
-/* Return the end of the core image.  */
-grub_addr_t
-grub_arch_modules_addr (void)
-{
-  return GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR
-    + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE);
-}
diff --git a/kern/i386/pc/lzma_decode.S b/kern/i386/pc/lzma_decode.S
deleted file mode 100644 (file)
index a5a8684..0000000
+++ /dev/null
@@ -1,677 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define FIXED_PROPS
-
-#define LZMA_BASE_SIZE 1846
-#define LZMA_LIT_SIZE 768
-
-#define LZMA_PROPERTIES_SIZE 5
-
-#define kNumTopBits 24
-#define kTopValue (1 << kNumTopBits)
-
-#define kNumBitModelTotalBits 11
-#define kBitModelTotal (1 << kNumBitModelTotalBits)
-#define kNumMoveBits 5
-
-
-#define kNumPosBitsMax 4
-#define kNumPosStatesMax (1 << kNumPosBitsMax)
-
-#define kLenNumLowBits 3
-#define kLenNumLowSymbols (1 << kLenNumLowBits)
-#define kLenNumMidBits 3
-#define kLenNumMidSymbols (1 << kLenNumMidBits)
-#define kLenNumHighBits 8
-#define kLenNumHighSymbols (1 << kLenNumHighBits)
-
-#define LenChoice 0
-#define LenChoice2 (LenChoice + 1)
-#define LenLow (LenChoice2 + 1)
-#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
-#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
-#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
-
-
-#define kNumStates 12
-#define kNumLitStates 7
-
-#define kStartPosModelIndex 4
-#define kEndPosModelIndex 14
-#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
-
-#define kNumPosSlotBits 6
-#define kNumLenToPosStates 4
-
-#define kNumAlignBits 4
-#define kAlignTableSize (1 << kNumAlignBits)
-
-#define kMatchMinLen 2
-
-#define IsMatch 0
-#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
-#define IsRepG0 (IsRep + kNumStates)
-#define IsRepG1 (IsRepG0 + kNumStates)
-#define IsRepG2 (IsRepG1 + kNumStates)
-#define IsRep0Long (IsRepG2 + kNumStates)
-#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
-#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
-#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
-#define LenCoder (Align + kAlignTableSize)
-#define RepLenCoder (LenCoder + kNumLenProbs)
-#define Literal (RepLenCoder + kNumLenProbs)
-
-
-#if 0
-
-DbgOut:
-       pushf
-       pushl   %ebp
-       pushl   %edi
-       pushl   %esi
-       pushl   %edx
-       pushl   %ecx
-       pushl   %ebx
-       pushl   %eax
-
-       call    _DebugPrint
-
-       popl    %eax
-       popl    %ebx
-       popl    %ecx
-       popl    %edx
-       popl    %esi
-       popl    %edi
-       popl    %ebp
-       popf
-
-       ret
-
-
-/*
- * int LzmaDecodeProperties(CLzmaProperties *propsRes,
- *                          const unsigned char *propsData,
- *                          int size);
- */
-
-_LzmaDecodePropertiesA:
-       movb    (%edx), %dl
-
-       xorl    %ecx, %ecx
-1:
-       cmpb    $45, %dl
-       jb      2f
-       incl    %ecx
-       subb    $45, %dl
-       jmp     1b
-2:
-       movl    %ecx, 8(%eax)           /* pb */
-       xorl    %ecx, %ecx
-1:
-       cmpb    $9, %dl
-       jb      2f
-       incl    %ecx
-       subb    $9, %dl
-2:
-       movl    %ecx, 4(%eax)           /* lp */
-       movb    %dl, %cl
-       movl    %ecx, (%eax)            /* lc */
-
-#endif
-
-#ifndef ASM_FILE
-       xorl    %eax, %eax
-#endif
-       ret
-
-#define out_size       8(%ebp)
-
-#define now_pos                -4(%ebp)
-#define prev_byte      -8(%ebp)
-#define range          -12(%ebp)
-#define code           -16(%ebp)
-#define state          -20(%ebp)
-#define rep0           -24(%ebp)
-#define rep1           -28(%ebp)
-#define rep2           -32(%ebp)
-#define rep3           -36(%ebp)
-
-#ifdef FIXED_PROPS
-
-#define FIXED_LC       3
-#define FIXED_LP       0
-#define FIXED_PB       2
-
-#define POS_STATE_MASK ((1 << (FIXED_PB)) - 1)
-#define LIT_POS_MASK   ((1 << (FIXED_LP)) - 1)
-
-#define LOCAL_SIZE     36
-
-#else
-
-#define lc             (%ebx)
-#define lp             4(%ebx)
-#define pb             8(%ebx)
-#define probs          12(%ebx)
-
-#define pos_state_mask -40(%ebp)
-#define lit_pos_mask   -44(%ebp)
-
-#define LOCAL_SIZE     44
-
-#endif
-
-RangeDecoderBitDecode:
-#ifdef FIXED_PROPS
-       leal    (%ebx, %eax, 4), %eax
-#else
-       shll    $2, %eax
-       addl    probs, %eax
-#endif
-
-       movl    %eax, %ecx
-       movl    (%ecx), %eax
-
-       movl    range, %edx
-       shrl    $kNumBitModelTotalBits, %edx
-       mull    %edx
-
-       cmpl    code, %eax
-       jbe     1f
-
-       movl    %eax, range
-       movl    $kBitModelTotal, %edx
-       subl    (%ecx), %edx
-       shrl    $kNumMoveBits, %edx
-       addl    %edx, (%ecx)
-       clc
-3:
-       pushf
-       cmpl    $kTopValue, range
-       jnc     2f
-       shll    $8, code
-       lodsb
-       movb    %al, code
-       shll    $8, range
-2:
-       popf
-       ret
-1:
-       subl    %eax, range
-       subl    %eax, code
-       movl    (%ecx), %edx
-       shrl    $kNumMoveBits, %edx
-       subl    %edx, (%ecx)
-       stc
-       jmp     3b
-
-RangeDecoderBitTreeDecode:
-RangeDecoderReverseBitTreeDecode:
-       movzbl  %cl, %ecx
-       xorl    %edx, %edx
-       pushl   %edx
-       incl    %edx
-       pushl   %edx
-
-1:
-       pushl   %eax
-       pushl   %ecx
-       pushl   %edx
-
-       addl    %edx, %eax
-       call    RangeDecoderBitDecode
-
-       popl    %edx
-       popl    %ecx
-
-       jnc     2f
-       movl    4(%esp), %eax
-       orl     %eax, 8(%esp)
-       stc
-
-2:
-       adcl    %edx, %edx
-       popl    %eax
-
-       shll    $1, (%esp)
-       loop    1b
-
-       popl    %ecx
-       subl    %ecx, %edx              /* RangeDecoderBitTreeDecode */
-       popl    %ecx                    /* RangeDecoderReverseBitTreeDecode */
-       ret
-
-LzmaLenDecode:
-       pushl   %eax
-       addl    $LenChoice, %eax
-       call    RangeDecoderBitDecode
-       popl    %eax
-       jc      1f
-       pushl   $0
-       movb    $kLenNumLowBits, %cl
-       addl    $LenLow, %eax
-2:
-       movl    12(%esp), %edx
-       shll    %cl, %edx
-       addl    %edx, %eax
-3:
-
-       call    RangeDecoderBitTreeDecode
-       popl    %eax
-       addl    %eax, %edx
-       ret
-
-1:
-       pushl   %eax
-       addl    $LenChoice2, %eax
-       call    RangeDecoderBitDecode
-       popl    %eax
-       jc      1f
-       pushl   $kLenNumLowSymbols
-       movb    $kLenNumMidBits, %cl
-       addl    $LenMid, %eax
-       jmp     2b
-
-1:
-       pushl   $(kLenNumLowSymbols + kLenNumMidSymbols)
-       addl    $LenHigh, %eax
-       movb    $kLenNumHighBits, %cl
-       jmp     3b
-
-WriteByte:
-       movb    %al, prev_byte
-       stosb
-       incl    now_pos
-       ret
-
-/*
- * int LzmaDecode(CLzmaDecoderState *vs,
- *                const unsigned char *inStream,
- *                unsigned char *outStream,
- *                SizeT outSize);
- */
-
-_LzmaDecodeA:
-
-       pushl   %ebp
-       movl    %esp, %ebp
-       subl    $LOCAL_SIZE, %esp
-
-#ifndef ASM_FILE
-       pushl   %esi
-       pushl   %edi
-       pushl   %ebx
-
-       movl    %eax, %ebx
-       movl    %edx, %esi
-       pushl   %ecx
-#else
-       pushl   %edi
-#endif
-
-       cld
-
-#ifdef FIXED_PROPS
-       movl    %ebx, %edi
-       movl    $(Literal + (LZMA_LIT_SIZE << (FIXED_LC + FIXED_LP))), %ecx
-#else
-       movl    $LZMA_LIT_SIZE, %eax
-       movb    lc, %cl
-       addb    lp, %cl
-       shll    %cl, %eax
-       addl    $Literal, %eax
-       movl    %eax, %ecx
-       movl    probs, %edi
-#endif
-
-       movl    $(kBitModelTotal >> 1), %eax
-
-       rep
-       stosl
-
-       popl    %edi
-
-       xorl    %eax, %eax
-       movl    %eax, now_pos
-       movl    %eax, prev_byte
-       movl    %eax, state
-
-       incl    %eax
-       movl    %eax, rep0
-       movl    %eax, rep1
-       movl    %eax, rep2
-       movl    %eax, rep3
-
-#ifndef FIXED_PROPS
-       movl    %eax, %edx
-       movb    pb, %cl
-       shll    %cl, %edx
-       decl    %edx
-       movl    %edx, pos_state_mask
-
-       movl    %eax, %edx
-       movb    lp, %cl
-       shll    %cl, %edx
-       decl    %edx
-       movl    %edx, lit_pos_mask;
-#endif
-
-       /* RangeDecoderInit */
-       negl    %eax
-       movl    %eax, range
-
-       incl    %eax
-       movb    $5, %cl
-
-1:
-       shll    $8, %eax
-       lodsb
-       loop    1b
-
-       movl    %eax, code
-
-lzma_decode_loop:
-       movl    now_pos, %eax
-       cmpl    out_size, %eax
-
-       jb      1f
-
-#ifndef ASM_FILE
-       xorl    %eax, %eax
-
-       popl    %ebx
-       popl    %edi
-       popl    %esi
-#endif
-
-       movl    %ebp, %esp
-       popl    %ebp
-       ret
-
-1:
-#ifdef FIXED_PROPS
-       andl    $POS_STATE_MASK, %eax
-#else
-       andl    pos_state_mask, %eax
-#endif
-       pushl   %eax                            /* posState */
-       movl    state, %edx
-       shll    $kNumPosBitsMax, %edx
-       addl    %edx, %eax
-       pushl   %eax                            /* (state << kNumPosBitsMax) + posState */
-
-       call    RangeDecoderBitDecode
-       jc      1f
-
-       movl    now_pos, %eax
-
-#ifdef FIXED_PROPS
-       andl    $LIT_POS_MASK, %eax
-       shll    $FIXED_LC, %eax
-       movl    prev_byte, %edx
-       shrl    $(8 - FIXED_LC), %edx
-#else
-       andl    lit_pos_mask, %eax
-       movb    lc, %cl
-       shll    %cl, %eax
-       negb    %cl
-       addb    $8, %cl
-       movl    prev_byte, %edx
-       shrl    %cl, %edx
-#endif
-
-       addl    %edx, %eax
-       movl    $LZMA_LIT_SIZE, %edx
-       mull    %edx
-       addl    $Literal, %eax
-       pushl   %eax
-
-       incl    %edx                    /* edx = 1 */
-
-       movl    rep0, %eax
-       negl    %eax
-       pushl   (%edi, %eax)            /* matchByte */
-
-       cmpb    $kNumLitStates, state
-       jb      5f
-
-       /* LzmaLiteralDecodeMatch */
-
-3:
-       cmpl    $0x100, %edx
-       jae     4f
-
-       xorl    %eax, %eax
-       shlb    $1, (%esp)
-       adcl    %eax, %eax
-
-       pushl   %eax
-       pushl   %edx
-
-       shll    $8, %eax
-       leal    0x100(%edx, %eax), %eax
-       addl    12(%esp), %eax
-       call    RangeDecoderBitDecode
-
-       setc    %al
-       popl    %edx
-       adcl    %edx, %edx
-
-       popl    %ecx
-       cmpb    %cl, %al
-       jz      3b
-
-5:
-
-       /* LzmaLiteralDecode */
-
-       cmpl    $0x100, %edx
-       jae     4f
-
-       pushl   %edx
-       movl    %edx, %eax
-       addl    8(%esp), %eax
-       call    RangeDecoderBitDecode
-       popl    %edx
-       adcl    %edx, %edx
-       jmp     5b
-
-4:
-       addl    $16, %esp
-
-       movb    %dl, %al
-       call    WriteByte
-
-       movb    state, %al
-       cmpb    $4, %al
-       jae     2f
-       xorb    %al, %al
-       jmp     3f
-2:
-       subb    $3, %al
-       cmpb    $7, %al
-       jb      3f
-       subb    $3, %al
-3:
-       movb    %al, state
-       jmp     lzma_decode_loop
-
-1:
-       movl    state, %eax
-       addl    $IsRep, %eax
-       call    RangeDecoderBitDecode
-       jnc     1f
-
-       movl    state, %eax
-       addl    $IsRepG0, %eax
-       call    RangeDecoderBitDecode
-       jc      10f
-
-       movl    (%esp), %eax
-       addl    $IsRep0Long, %eax
-       call    RangeDecoderBitDecode
-       jc      20f
-
-       cmpb    $7, state
-       movb    $9, state
-       jb      100f
-       addb    $2, state
-100:
-
-       movl    $1, %ecx
-
-3:
-       movl    rep0, %edx
-       negl    %edx
-
-4:
-       movb    (%edi, %edx), %al
-       call    WriteByte
-       loop    4b
-
-       popl    %eax
-       popl    %eax
-       jmp     lzma_decode_loop
-
-10:
-       movl    state, %eax
-       addl    $IsRepG1, %eax
-       call    RangeDecoderBitDecode
-       movl    rep1, %edx
-       jnc     100f
-
-       movl    state, %eax
-       addl    $IsRepG2, %eax
-       call    RangeDecoderBitDecode
-       movl    rep2, %edx
-       jnc     1000f
-       movl    rep2, %edx
-       xchgl   rep3, %edx
-1000:
-       pushl   rep1
-       popl    rep2
-100:
-       xchg    rep0, %edx
-       movl    %edx, rep1
-20:
-
-       movl    $RepLenCoder, %eax
-       call    LzmaLenDecode
-
-       cmpb    $7, state
-       movb    $8, state
-       jb      100f
-       addb    $3, state
-100:
-       jmp     2f
-
-1:
-       movl    rep0, %eax
-       xchgl   rep1, %eax
-       xchgl   rep2, %eax
-       movl    %eax, rep3
-
-       cmpb    $7, state
-       movb    $7, state
-       jb      10f
-       addb    $3, state
-10:
-
-       movl    $LenCoder, %eax
-       call    LzmaLenDecode
-       pushl   %edx
-
-       movl    $(kNumLenToPosStates - 1), %eax
-       cmpl    %eax, %edx
-       jbe     100f
-       movl    %eax, %edx
-100:
-       movb    $kNumPosSlotBits, %cl
-       shll    %cl, %edx
-       leal    PosSlot(%edx), %eax
-       call    RangeDecoderBitTreeDecode
-
-       movl    %edx, rep0
-       cmpl    $kStartPosModelIndex, %edx
-       jb      100f
-
-       movl    %edx, %ecx
-       shrl    $1, %ecx
-       decl    %ecx
-
-       movzbl  %dl, %eax
-       andb    $1, %al
-       orb     $2, %al
-       shll    %cl, %eax
-       movl    %eax, rep0
-
-       cmpl    $kEndPosModelIndex, %edx
-       jae     200f
-       movl    rep0, %eax
-       addl    $(SpecPos - 1), %eax
-       subl    %edx, %eax
-       jmp     300f
-200:
-
-       subb    $kNumAlignBits, %cl
-
-       /* RangeDecoderDecodeDirectBits */
-       xorl    %edx, %edx
-
-1000:
-       shrl    $1, range
-       shll    $1, %edx
-
-       movl    range, %eax
-       cmpl    %eax, code
-       jb      2000f
-       subl    %eax, code
-       orb     $1, %dl
-2000:
-
-       cmpl    $kTopValue, %eax
-       jae     3000f
-       shll    $8, range
-       shll    $8, code
-       lodsb
-       movb    %al, code
-
-3000:
-       loop    1000b
-
-       movb    $kNumAlignBits, %cl
-       shll    %cl, %edx
-       addl    %edx, rep0
-
-       movl    $Align, %eax
-
-300:
-       call    RangeDecoderReverseBitTreeDecode
-       addl    %ecx, rep0
-
-100:
-       incl    rep0
-       popl    %edx
-
-2:
-
-       addl    $kMatchMinLen, %edx
-       movl    %edx, %ecx
-
-       jmp     3b
diff --git a/kern/i386/pc/mmap.c b/kern/i386/pc/mmap.c
deleted file mode 100644 (file)
index 52d8fd5..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/machine/init.h>
-#include <grub/machine/memory.h>
-#include <grub/err.h>
-#include <grub/types.h>
-
-grub_err_t
-grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
-{
-  grub_uint32_t cont;
-  struct grub_machine_mmap_entry *entry
-    = (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
-
-  /* Check if grub_get_mmap_entry works.  */
-  cont = grub_get_mmap_entry (entry, 0);
-
-  if (entry->size)
-    do
-      {
-       if (hook (entry->addr, entry->len,
-                 /* Multiboot mmaps have been defined to match with the E820 definition.
-                    Therefore, we can just pass type through.  */
-                 entry->type))
-         break;
-
-       if (! cont)
-         break;
-
-       cont = grub_get_mmap_entry (entry, cont);
-      }
-    while (entry->size);
-  else
-    {
-      grub_uint32_t eisa_mmap = grub_get_eisa_mmap ();
-
-      if (eisa_mmap)
-       {
-         if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10, GRUB_MACHINE_MEMORY_AVAILABLE) == 0)
-           hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MACHINE_MEMORY_AVAILABLE);
-       }
-      else
-       hook (0x100000, grub_get_memsize (1) << 10, GRUB_MACHINE_MEMORY_AVAILABLE);
-    }
-
-  return 0;
-}
diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S
deleted file mode 100644 (file)
index 3742777..0000000
+++ /dev/null
@@ -1,2074 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-/*
- * Note: These functions defined in this file may be called from C.
- *       Be careful of that you must not modify some registers. Quote
- *       from gcc-2.95.2/gcc/config/i386/i386.h:
-
-   1 for registers not available across function calls.
-   These must include the FIXED_REGISTERS and also any
-   registers that can be used without being saved.
-   The latter must include the registers where values are returned
-   and the register where structure-value addresses are passed.
-   Aside from that, you can include as many other registers as you like.
-
-  ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
-{  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
- */
-
-/*
- * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
- *       So the first three arguments are passed in %eax, %edx, and %ecx,
- *       respectively, and if a function has a fixed number of arguments
- *       and the number is greater than three, the function must return
- *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
- */
-
-#include <config.h>
-#include <grub/symbol.h>
-#include <grub/boot.h>
-#include <grub/machine/boot.h>
-#include <grub/machine/memory.h>
-#include <grub/machine/console.h>
-#include <grub/cpu/linux.h>
-#include <grub/machine/kernel.h>
-#include <grub/term.h>
-#include <multiboot.h>
-#include <multiboot2.h>
-
-#define ABS(x) ((x) - LOCAL (base) + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200)
-
-       .file   "startup.S"
-
-       .text
-
-       /* Tell GAS to generate 16-bit instructions so that this code works
-          in real mode. */
-       .code16
-
-       .globl  start, _start
-start:
-_start:
-LOCAL (base):
-       /*
-        *  Guarantee that "main" is loaded at 0x0:0x8200.
-        */
-#ifdef __APPLE__
-       ljmp $0, $(ABS(LOCAL (codestart)) - 0x10000)
-#else
-       ljmp $0, $ABS(LOCAL (codestart))
-#endif
-       /*
-        *  Compatibility version number
-        *
-        *  These MUST be at byte offset 6 and 7 of the executable
-        *  DO NOT MOVE !!!
-        */
-       . = _start + 0x6
-       .byte   GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
-
-       /*
-        *  This is a special data area 8 bytes from the beginning.
-        */
-
-       . = _start + 0x8
-
-VARIABLE(grub_total_module_size)
-       .long   0
-VARIABLE(grub_kernel_image_size)
-       .long   0
-VARIABLE(grub_compressed_size)
-       .long   0
-VARIABLE(grub_install_dos_part)
-       .long   0xFFFFFFFF
-VARIABLE(grub_install_bsd_part)
-       .long   0xFFFFFFFF
-VARIABLE(grub_prefix)
-       /* to be filled by grub-mkimage */
-
-       /*
-        *  Leave some breathing room for the prefix.
-        */
-
-       . = _start + GRUB_KERNEL_MACHINE_DATA_END
-
-#ifdef APPLE_CC
-bss_start:
-       .long 0
-bss_end:
-       .long 0
-#endif
-
-/*
- * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself).
- * This uses the a.out kludge to load raw binary to the area starting at 1MB,
- * and relocates itself after loaded.
- */
-       .p2align        2       /* force 4-byte alignment */
-multiboot_header:
-       /* magic */
-       .long   0x1BADB002
-       /* flags */
-       .long   (1 << 16)
-       /* checksum */
-       .long   -0x1BADB002 - (1 << 16)
-       /* header addr */
-       .long   multiboot_header - _start + 0x100000 + 0x200
-       /* load addr */
-       .long   0x100000
-       /* load end addr */
-       .long   0
-       /* bss end addr */
-       .long   0
-       /* entry addr */
-       .long   multiboot_entry - _start + 0x100000 + 0x200
-
-multiboot_entry:
-       .code32
-       /* obtain the boot device */
-       movl    12(%ebx), %edx
-
-       movl    $GRUB_MEMORY_MACHINE_PROT_STACK, %ebp
-       movl    %ebp, %esp
-
-       /* relocate the code */
-       movl    $(GRUB_KERNEL_MACHINE_RAW_SIZE + 0x200), %ecx
-       addl    EXT_C(grub_compressed_size) - _start + 0x100000 + 0x200, %ecx
-       movl    $0x100000, %esi
-       movl    $GRUB_BOOT_MACHINE_KERNEL_ADDR, %edi
-       cld
-       rep
-       movsb
-       /* jump to the real address */
-       movl    $multiboot_trampoline, %eax
-       jmp     *%eax
-
-multiboot_trampoline:
-       /* fill the boot information */
-       movl    %edx, %eax
-       shrl    $8, %eax
-       xorl    %ebx, %ebx
-       cmpb    $0xFF, %ah
-       je      1f
-       movb    %ah, %bl
-       movl    %ebx, EXT_C(grub_install_dos_part)
-1:
-       cmpb    $0xFF, %al
-       je      2f
-       movb    %al, %bl
-       movl    %ebx, EXT_C(grub_install_bsd_part)
-2:
-       shrl    $24, %edx
-        movb    $0xFF, %dh
-       /* enter the usual booting */
-       call    prot_to_real
-       .code16
-
-/* the real mode code continues... */
-LOCAL (codestart):
-       cli             /* we're not safe here! */
-
-       /* set up %ds, %ss, and %es */
-       xorw    %ax, %ax
-       movw    %ax, %ds
-       movw    %ax, %ss
-       movw    %ax, %es
-
-       /* set up the real mode/BIOS stack */
-       movl    $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp
-       movl    %ebp, %esp
-
-       sti             /* we're safe again */
-
-       /* save the boot drive */
-       ADDR32  movb    %dl, EXT_C(grub_boot_drive)
-
-       /* reset disk system (%ah = 0) */
-       int     $0x13
-
-       /* transition to protected mode */
-       DATA32  call real_to_prot
-
-       /* The ".code32" directive takes GAS out of 16-bit mode. */
-       .code32
-
-       incl    %eax
-       call    EXT_C(grub_gate_a20)
-
-#ifdef ENABLE_LZMA
-       movl    $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi
-       movl    $(_start + GRUB_KERNEL_MACHINE_RAW_SIZE), %esi
-       pushl   %edi
-       pushl   %esi
-       movl    EXT_C(grub_kernel_image_size), %ecx
-       addl    EXT_C(grub_total_module_size), %ecx
-       subl    $GRUB_KERNEL_MACHINE_RAW_SIZE, %ecx
-       pushl   %ecx
-       leal    (%edi, %ecx), %ebx
-       call    _LzmaDecodeA
-       /* _LzmaDecodeA clears DF, so no need to run cld */
-       popl    %ecx
-       popl    %edi
-       popl    %esi
-#endif
-
-       /* copy back the decompressed part (except the modules) */
-       subl    EXT_C(grub_total_module_size), %ecx
-       rep
-       movsb
-
-#if 0
-       /* copy modules before cleaning out the bss */
-       movl    EXT_C(grub_total_module_size), %ecx
-       movl    EXT_C(grub_kernel_image_size), %esi
-       addl    %ecx, %esi
-       addl    $_start, %esi
-       decl    %esi
-       movl    $END_SYMBOL, %edi
-       addl    %ecx, %edi
-       decl    %edi
-       std
-       rep
-       movsb
-#endif
-
-#ifdef APPLE_CC
-       /* clean out the bss */
-       bss_start_abs = ABS (bss_start)
-       bss_end_abs = ABS (bss_end)
-
-       movl    bss_start_abs, %edi
-
-       /* compute the bss length */
-       movl    bss_end_abs, %ecx
-       subl    %edi, %ecx
-#else
-       /* clean out the bss */
-       movl    $BSS_START_SYMBOL, %edi
-
-       /* compute the bss length */
-       movl    $END_SYMBOL, %ecx
-       subl    %edi, %ecx
-#endif
-
-       /* clean out */
-       xorl    %eax, %eax
-       cld
-       rep
-       stosb
-
-       /*
-        *  Call the start of main body of C code.
-        */
-       call EXT_C(grub_main)
-
-/*
- *  This is the area for all of the special variables.
- */
-
-VARIABLE(grub_boot_drive)
-       .byte   0
-
-       .p2align        2       /* force 4-byte alignment */
-
-#include "../realmode.S"
-
-/*
- * grub_gate_a20(int on)
- *
- * Gate address-line 20 for high memory.
- *
- * This routine is probably overconservative in what it does, but so what?
- *
- * It also eats any keystrokes in the keyboard buffer.  :-(
- */
-
-FUNCTION(grub_gate_a20)
-       movl    %eax, %edx
-
-gate_a20_test_current_state:
-       /* first of all, test if already in a good state */
-       call    gate_a20_check_state
-       cmpb    %al, %dl
-       jnz     gate_a20_try_bios
-       ret
-
-gate_a20_try_bios:
-       /* second, try a BIOS call */
-       pushl   %ebp
-       call    prot_to_real
-
-       .code16
-       movw    $0x2400, %ax
-       testb   %dl, %dl
-       jz      1f
-       incw    %ax
-1:     int     $0x15
-
-       DATA32  call    real_to_prot
-       .code32
-
-       popl    %ebp
-       call    gate_a20_check_state
-       cmpb    %al, %dl
-       jnz     gate_a20_try_system_control_port_a
-       ret
-
-gate_a20_try_system_control_port_a:
-       /*
-        * In macbook, the keyboard test would hang the machine, so we move
-        * this forward.
-        */
-       /* fourth, try the system control port A */
-       inb     $0x92
-       andb    $(~0x03), %al
-       testb   %dl, %dl
-       jz      6f
-       orb     $0x02, %al
-6:     outb    $0x92
-
-       /* When turning off Gate A20, do not check the state strictly,
-          because a failure is not fatal usually, and Gate A20 is always
-          on some modern machines.  */
-       testb   %dl, %dl
-       jz      7f
-       call    gate_a20_check_state
-       cmpb    %al, %dl
-       jnz     gate_a20_try_keyboard_controller
-7:     ret
-
-gate_a20_flush_keyboard_buffer:
-       inb     $0x64
-       andb    $0x02, %al
-       jnz     gate_a20_flush_keyboard_buffer
-2:
-       inb     $0x64
-       andb    $0x01, %al
-       jz      3f
-       inb     $0x60
-       jmp     2b
-3:
-       ret
-
-gate_a20_try_keyboard_controller:
-       /* third, try the keyboard controller */
-       call    gate_a20_flush_keyboard_buffer
-
-       movb    $0xd1, %al
-       outb    $0x64
-4:
-       inb     $0x64
-       andb    $0x02, %al
-       jnz     4b
-
-       movb    $0xdd, %al
-       testb   %dl, %dl
-       jz      5f
-       orb     $0x02, %al
-5:     outb    $0x60
-       call    gate_a20_flush_keyboard_buffer
-
-       /* output a dummy command (USB keyboard hack) */
-       movb    $0xff, %al
-       outb    $0x64
-       call    gate_a20_flush_keyboard_buffer
-
-       call    gate_a20_check_state
-       cmpb    %al, %dl
-       /* everything failed, so restart from the beginning */
-       jnz     gate_a20_try_bios
-       ret
-
-gate_a20_check_state:
-       /* iterate the checking for a while */
-       movl    $100, %ecx
-1:
-       call    3f
-       cmpb    %al, %dl
-       jz      2f
-       loop    1b
-2:
-       ret
-3:
-       pushl   %ebx
-       pushl   %ecx
-       xorl    %eax, %eax
-       /* compare the byte at 0x8000 with that at 0x108000 */
-       movl    $GRUB_BOOT_MACHINE_KERNEL_ADDR, %ebx
-       pushl   %ebx
-       /* save the original byte in CL */
-       movb    (%ebx), %cl
-       /* store the value at 0x108000 in AL */
-       addl    $0x100000, %ebx
-       movb    (%ebx), %al
-       /* try to set one less value at 0x8000 */
-       popl    %ebx
-       movb    %al, %ch
-       decb    %ch
-       movb    %ch, (%ebx)
-       /* serialize */
-       outb    %al, $0x80
-       outb    %al, $0x80
-       /* obtain the value at 0x108000 in CH */
-       pushl   %ebx
-       addl    $0x100000, %ebx
-       movb    (%ebx), %ch
-       /* this result is 1 if A20 is on or 0 if it is off */
-       subb    %ch, %al
-       xorb    $1, %al
-       /* restore the original */
-       popl    %ebx
-       movb    %cl, (%ebx)
-       popl    %ecx
-       popl    %ebx
-       ret
-
-#ifdef ENABLE_LZMA
-#include "lzma_decode.S"
-#endif
-
-/*
- * The code beyond this point is compressed.  Assert that the uncompressed
- * code fits GRUB_KERNEL_MACHINE_RAW_SIZE.
- */
-       . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE
-
-       /*
-        * This next part is sort of evil.  It takes advantage of the
-        * byte ordering on the x86 to work in either 16-bit or 32-bit
-        * mode, so think about it before changing it.
-        */
-
-FUNCTION(grub_hard_stop)
-       hlt
-       jmp EXT_C(grub_hard_stop)
-
-
-/*
- * grub_stop_floppy()
- *
- * Stop the floppy drive from spinning, so that other software is
- * jumped to with a known state.
- */
-FUNCTION(grub_stop_floppy)
-       movw    $0x3F2, %dx
-       xorb    %al, %al
-       outb    %al, %dx
-       ret
-
-/*
- * grub_exit()
- *
- * Exit the system.
- */
-FUNCTION(grub_exit)
-       call    prot_to_real
-       .code16
-       /* Tell the BIOS a boot failure. If this does not work, reboot.  */
-       int     $0x18
-       jmp     cold_reboot
-       .code32
-
-/*
- * grub_halt(int no_apm)
- *
- * Halt the system, using APM if possible. If NO_APM is true, don't use
- * APM even if it is available.
- */
-FUNCTION(grub_halt)
-       /* see if zero */
-       testl   %eax, %eax
-       jnz     EXT_C(grub_stop)
-
-       call    prot_to_real
-       .code16
-
-       /* detect APM */
-       movw    $0x5300, %ax
-       xorw    %bx, %bx
-       int     $0x15
-       jc      EXT_C(grub_hard_stop)
-       /* don't check %bx for buggy BIOSes... */
-
-       /* disconnect APM first */
-       movw    $0x5304, %ax
-       xorw    %bx, %bx
-       int     $0x15
-
-       /* connect APM */
-       movw    $0x5301, %ax
-       xorw    %bx, %bx
-       int     $0x15
-       jc      EXT_C(grub_hard_stop)
-
-       /* set APM protocol level - 1.1 or bust. (this covers APM 1.2 also) */
-       movw    $0x530E, %ax
-       xorw    %bx, %bx
-       movw    $0x0101, %cx
-       int     $0x15
-       jc      EXT_C(grub_hard_stop)
-
-       /* set the power state to off */
-       movw    $0x5307, %ax
-       movw    $1, %bx
-       movw    $3, %cx
-       int     $0x15
-
-       /* shouldn't reach here */
-       jmp     EXT_C(grub_hard_stop)
-       .code32
-
-
-/*
- *  void grub_chainloader_real_boot (int drive, void *part_addr)
- *
- *  This starts another boot loader.
- */
-
-FUNCTION(grub_chainloader_real_boot)
-       pushl   %edx
-       pushl   %eax
-
-       call    EXT_C(grub_dl_unload_all)
-
-       /* Turn off Gate A20 */
-       xorl    %eax, %eax
-       call    EXT_C(grub_gate_a20)
-
-       /* set up to pass boot drive */
-       popl    %edx
-
-       /* ESI must point to a partition table entry */
-       popl    %esi
-
-       call    prot_to_real
-       .code16
-       ljmp    $0, $GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR
-       .code32
-
-#include "../loader.S"
-
-/*
- *   int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap)
- *
- *   Call IBM/MS INT13 Extensions (int 13 %ah=AH) for DRIVE. DAP
- *   is passed for disk address packet. If an error occurs, return
- *   non-zero, otherwise zero.
- */
-
-FUNCTION(grub_biosdisk_rw_int13_extensions)
-       pushl   %ebp
-       pushl   %esi
-
-       /* compute the address of disk_address_packet */
-       movw    %cx, %si
-       xorw    %cx, %cx
-       shrl    $4, %ecx        /* save the segment to cx */
-
-       /* ah */
-       movb    %al, %dh
-       /* enter real mode */
-       call    prot_to_real
-
-       .code16
-       movb    %dh, %ah
-       movw    %cx, %ds
-       int     $0x13           /* do the operation */
-       movb    %ah, %dl        /* save return value */
-       /* back to protected mode */
-       DATA32  call    real_to_prot
-       .code32
-
-       movb    %dl, %al        /* return value in %eax */
-
-       popl    %esi
-       popl    %ebp
-
-       ret
-
-/*
- *   int grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff,
- *                                  int soff, int nsec, int segment)
- *
- *   Call standard and old INT13 (int 13 %ah=AH) for DRIVE. Read/write
- *   NSEC sectors from COFF/HOFF/SOFF into SEGMENT. If an error occurs,
- *   return non-zero, otherwise zero.
- */
-
-FUNCTION(grub_biosdisk_rw_standard)
-       pushl   %ebp
-       movl    %esp, %ebp
-
-       pushl   %ebx
-       pushl   %edi
-       pushl   %esi
-
-       /* set up CHS information */
-
-       /* set %ch to low eight bits of cylinder */
-       xchgb   %cl, %ch
-       /* set bits 6-7 of %cl to high two bits of cylinder */
-       shlb    $6, %cl
-       /* set bits 0-5 of %cl to sector */
-       addb    0xc(%ebp), %cl
-       /* set %dh to head */
-       movb    0x8(%ebp), %dh
-       /* set %ah to AH */
-       movb    %al, %ah
-       /* set %al to NSEC */
-       movb    0x10(%ebp), %al
-       /* save %ax in %di */
-       movw    %ax, %di
-       /* save SEGMENT in %bx */
-       movw    0x14(%ebp), %bx
-
-       /* enter real mode */
-       call    prot_to_real
-
-       .code16
-       movw    %bx, %es
-       xorw    %bx, %bx
-       movw    $3, %si         /* attempt at least three times */
-
-1:
-       movw    %di, %ax
-       int     $0x13           /* do the operation */
-       jnc     2f              /* check if successful */
-
-       movb    %ah, %bl        /* save return value */
-       /* if fail, reset the disk system */
-       xorw    %ax, %ax
-       int     $0x13
-
-       decw    %si
-       cmpw    $0, %si
-       je      2f
-       xorb    %bl, %bl
-       jmp     1b              /* retry */
-2:
-       /* back to protected mode */
-       DATA32  call    real_to_prot
-       .code32
-
-       movb    %bl, %al        /* return value in %eax */
-
-       popl    %esi
-       popl    %edi
-       popl    %ebx
-       popl    %ebp
-
-       ret     $(4 * 4)
-
-
-/*
- *   int grub_biosdisk_check_int13_extensions (int drive)
- *
- *   Check if LBA is supported for DRIVE. If it is supported, then return
- *   the major version of extensions, otherwise zero.
- */
-
-FUNCTION(grub_biosdisk_check_int13_extensions)
-       pushl   %ebp
-       pushl   %ebx
-
-       /* drive */
-       movb    %al, %dl
-       /* enter real mode */
-       call    prot_to_real
-
-       .code16
-       movb    $0x41, %ah
-       movw    $0x55aa, %bx
-       int     $0x13           /* do the operation */
-
-       /* check the result */
-       jc      1f
-       cmpw    $0xaa55, %bx
-       jne     1f
-
-       movb    %ah, %bl        /* save the major version into %bl */
-
-       /* check if AH=0x42 is supported */
-       andw    $1, %cx
-       jnz     2f
-
-1:
-       xorb    %bl, %bl
-2:
-       /* back to protected mode */
-       DATA32  call    real_to_prot
-       .code32
-
-       movb    %bl, %al        /* return value in %eax */
-
-       popl    %ebx
-       popl    %ebp
-
-       ret
-
-
-/*
- *   int grub_biosdisk_get_cdinfo_int13_extensions (int drive, void *cdrp)
- *
- *   Return the cdrom information of DRIVE in CDRP. If an error occurs,
- *   then return non-zero, otherwise zero.
- */
-
-FUNCTION(grub_biosdisk_get_cdinfo_int13_extensions)
-       movw    $0x4B01, %cx
-       jmp     1f
-
-/*
- *   int grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp)
- *
- *   Return the geometry of DRIVE in a drive parameters, DRP. If an error
- *   occurs, then return non-zero, otherwise zero.
- */
-
-FUNCTION(grub_biosdisk_get_diskinfo_int13_extensions)
-       movb    $0x48, %ch
-1:
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-
-       /* compute the address of drive parameters */
-       movw    %dx, %si
-       andl    $0xf, %esi
-       shrl    $4, %edx
-       movw    %dx, %bx        /* save the segment into %bx */
-       /* drive */
-       movb    %al, %dl
-       /* enter real mode */
-       call    prot_to_real
-
-       .code16
-       movw    %cx, %ax
-       movw    %bx, %ds
-       int     $0x13           /* do the operation */
-       jc      noclean
-       /* Clean return value if carry isn't set to workaround
-       some buggy BIOSes.  */
-       xor     %ax, %ax
-noclean:
-       movb    %ah, %bl        /* save return value in %bl */
-       /* back to protected mode */
-       DATA32  call    real_to_prot
-       .code32
-
-       movb    %bl, %al        /* return value in %eax */
-
-       popl    %esi
-       popl    %ebx
-       popl    %ebp
-
-       ret
-
-
-/*
- *   int grub_biosdisk_get_diskinfo_standard (int drive,
- *                                            unsigned long *cylinders,
- *                                            unsigned long *heads,
- *                                            unsigned long *sectors)
- *
- *   Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an
- *   error occurs, then return non-zero, otherwise zero.
- */
-
-FUNCTION(grub_biosdisk_get_diskinfo_standard)
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %edi
-
-       /* push CYLINDERS */
-       pushl   %edx
-       /* push HEADS */
-       pushl   %ecx
-       /* SECTORS is on the stack */
-
-       /* drive */
-       movb    %al, %dl
-       /* enter real mode */
-       call    prot_to_real
-
-       .code16
-       movb    $0x8, %ah
-       int     $0x13           /* do the operation */
-       jc      noclean2
-       /* Clean return value if carry isn't set to workaround
-       some buggy BIOSes.  */
-       xor     %ax, %ax
-noclean2:
-       /* check if successful */
-       testb   %ah, %ah
-       jnz     1f
-       /* bogus BIOSes may not return an error number */
-       testb   $0x3f, %cl      /* 0 sectors means no disk */
-       jnz     1f              /* if non-zero, then succeed */
-       /* XXX 0x60 is one of the unused error numbers */
-       movb    $0x60, %ah
-1:
-       movb    %ah, %bl        /* save return value in %bl */
-       /* back to protected mode */
-       DATA32  call    real_to_prot
-       .code32
-
-       /* pop HEADS */
-       popl    %edi
-       movb    %dh, %al
-       incl    %eax    /* the number of heads is counted from zero */
-       movl    %eax, (%edi)
-
-       /* pop CYLINDERS */
-       popl    %edi
-       movb    %ch, %al
-       movb    %cl, %ah
-       shrb    $6, %ah /* the number of cylinders is counted from zero */
-       incl    %eax
-       movl    %eax, (%edi)
-
-       /* SECTORS */
-       movl    0x10(%esp), %edi
-       andb    $0x3f, %cl
-       movzbl  %cl, %eax
-       movl    %eax, (%edi)
-
-       xorl    %eax, %eax
-       movb    %bl, %al        /* return value in %eax */
-
-       popl    %edi
-       popl    %ebx
-       popl    %ebp
-
-       ret     $4
-
-
-/*
- * int grub_biosdisk_get_num_floppies (void)
- */
-FUNCTION(grub_biosdisk_get_num_floppies)
-       pushl   %ebp
-
-       xorl    %edx, %edx
-       call    prot_to_real
-
-       .code16
-       /* reset the disk system first */
-       int     $0x13
-1:
-       stc
-
-       /* call GET DISK TYPE */
-       movb    $0x15, %ah
-       int     $0x13
-
-       jc      2f
-
-       /* check if this drive exists */
-       testb   $0x3, %ah
-       jz      2f
-
-       incb    %dl
-       cmpb    $2, %dl
-       jne     1b
-2:
-       DATA32  call    real_to_prot
-       .code32
-
-       movl    %edx, %eax
-       popl    %ebp
-       ret
-
-
-/*
- *
- * grub_get_memsize(i) :  return the memory size in KB. i == 0 for conventional
- *             memory, i == 1 for extended memory
- *     BIOS call "INT 12H" to get conventional memory size
- *     BIOS call "INT 15H, AH=88H" to get extended memory size
- *             Both have the return value in AX.
- *
- */
-
-FUNCTION(grub_get_memsize)
-       pushl   %ebp
-
-       movl    %eax, %edx
-
-       call    prot_to_real    /* enter real mode */
-       .code16
-
-       testl   %edx, %edx
-       jnz     xext
-
-       int     $0x12
-       jmp     xdone
-
-xext:
-       movb    $0x88, %ah
-       int     $0x15
-
-xdone:
-       movw    %ax, %dx
-
-       DATA32  call    real_to_prot
-       .code32
-
-       movw    %dx, %ax
-
-       popl    %ebp
-       ret
-
-
-/*
- *
- * grub_get_eisa_mmap() :  return packed EISA memory map, lower 16 bits is
- *             memory between 1M and 16M in 1K parts, upper 16 bits is
- *             memory above 16M in 64K parts.  If error, return zero.
- *     BIOS call "INT 15H, AH=E801H" to get EISA memory map,
- *             AX = memory between 1M and 16M in 1K parts.
- *             BX = memory above 16M in 64K parts.
- *
- */
-
-FUNCTION(grub_get_eisa_mmap)
-       pushl   %ebp
-       pushl   %ebx
-
-       call    prot_to_real    /* enter real mode */
-       .code16
-
-       movw    $0xe801, %ax
-       int     $0x15
-
-       shll    $16, %ebx
-       movw    %ax, %bx
-
-       DATA32  call    real_to_prot
-       .code32
-
-       cmpb    $0x86, %bh
-       je      xnoteisa
-
-       movl    %ebx, %eax
-
-xnoteisa:
-       popl    %ebx
-       popl    %ebp
-       ret
-
-/*
- *
- * grub_get_mmap_entry(addr, cont) : address and old continuation value (zero to
- *             start), for the Query System Address Map BIOS call.
- *
- *  Sets the first 4-byte int value of "addr" to the size returned by
- *  the call.  If the call fails, sets it to zero.
- *
- *     Returns:  new (non-zero) continuation value, 0 if done.
- */
-
-FUNCTION(grub_get_mmap_entry)
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %edi
-       pushl   %esi
-
-       /* push ADDR */
-       pushl   %eax
-
-       /* place address (+4) in ES:DI */
-       addl    $4, %eax
-       movl    %eax, %edi
-       andl    $0xf, %edi
-       shrl    $4, %eax
-       movl    %eax, %esi
-
-       /* set continuation value */
-       movl    %edx, %ebx
-
-       /* set default maximum buffer size */
-       movl    $0x14, %ecx
-
-       /* set EDX to 'SMAP' */
-       movl    $0x534d4150, %edx
-
-       call    prot_to_real    /* enter real mode */
-       .code16
-
-       movw    %si, %es
-       movl    $0xe820, %eax
-       int     $0x15
-
-       DATA32  jc      xnosmap
-
-       cmpl    $0x534d4150, %eax
-       jne     xnosmap
-
-       cmpl    $0x14, %ecx
-       jl      xnosmap
-
-       cmpl    $0x400, %ecx
-       jg      xnosmap
-
-       jmp     xsmap
-
-xnosmap:
-       xorl    %ecx, %ecx
-
-/*     Apple's cc jumps few bytes before the correct
-       label in this context. Hence nops. */
-#ifdef APPLE_CC
-       nop
-       nop
-       nop
-       nop
-       nop
-       nop
-#endif
-
-xsmap:
-       DATA32  call    real_to_prot
-       .code32
-
-       /* write length of buffer (zero if error) into ADDR */
-       popl    %eax
-       movl    %ecx, (%eax)
-
-       /* set return value to continuation */
-       movl    %ebx, %eax
-
-       popl    %esi
-       popl    %edi
-       popl    %ebx
-       popl    %ebp
-       ret
-
-
-/*
- * void grub_console_real_putchar (int c)
- *
- * Put the character C on the console. Because GRUB wants to write a
- * character with an attribute, this implementation is a bit tricky.
- * If C is a control character (CR, LF, BEL, BS), use INT 10, AH = 0Eh
- * (TELETYPE OUTPUT). Otherwise, save the original position, put a space,
- * save the current position, restore the original position, write the
- * character and the attribute, and restore the current position.
- *
- * The reason why this is so complicated is that there is no easy way to
- * get the height of the screen, and the TELETYPE OUTPUT BIOS call doesn't
- * support setting a background attribute.
- */
-FUNCTION(grub_console_real_putchar)
-       movl    %eax, %edx
-       pusha
-       movb    EXT_C(grub_console_cur_color), %bl
-
-       call    prot_to_real
-       .code16
-       movb    %dl, %al
-       xorb    %bh, %bh
-
-       /* use teletype output if control character */
-       cmpb    $0x7, %al
-       je      1f
-       cmpb    $0x8, %al
-       je      1f
-       cmpb    $0xa, %al
-       je      1f
-       cmpb    $0xd, %al
-       je      1f
-
-       /* save the character and the attribute on the stack */
-       pushw   %ax
-       pushw   %bx
-
-       /* get the current position */
-       movb    $0x3, %ah
-       int     $0x10
-
-       /* check the column with the width */
-       cmpb    $79, %dl
-       jl      2f
-
-       /* print CR and LF, if next write will exceed the width */
-       movw    $0x0e0d, %ax
-       int     $0x10
-       movb    $0x0a, %al
-       int     $0x10
-
-       /* get the current position */
-       movb    $0x3, %ah
-       int     $0x10
-
-2:
-       /* restore the character and the attribute */
-       popw    %bx
-       popw    %ax
-
-       /* write the character with the attribute */
-       movb    $0x9, %ah
-       movw    $1, %cx
-       int     $0x10
-
-       /* move the cursor forward */
-       incb    %dl
-       movb    $0x2, %ah
-       int     $0x10
-
-       jmp     3f
-
-1:     movw    $1, %bx
-       movb    $0xe, %ah
-       int     $0x10
-
-3:     DATA32  call    real_to_prot
-       .code32
-
-       popa
-       ret
-
-
-/*
- * int grub_console_getkey (void)
- * BIOS call "INT 16H Function 00H" to read character from keyboard
- *     Call with       %ah = 0x0
- *     Return:         %ah = keyboard scan code
- *                     %al = ASCII character
- */
-
-/* this table is used in translate_keycode below */
-LOCAL (translation_table):
-       .word   GRUB_CONSOLE_KEY_LEFT, GRUB_TERM_LEFT
-       .word   GRUB_CONSOLE_KEY_RIGHT, GRUB_TERM_RIGHT
-       .word   GRUB_CONSOLE_KEY_UP, GRUB_TERM_UP
-       .word   GRUB_CONSOLE_KEY_DOWN, GRUB_TERM_DOWN
-       .word   GRUB_CONSOLE_KEY_HOME, GRUB_TERM_HOME
-       .word   GRUB_CONSOLE_KEY_END, GRUB_TERM_END
-       .word   GRUB_CONSOLE_KEY_DC, GRUB_TERM_DC
-       .word   GRUB_CONSOLE_KEY_BACKSPACE, GRUB_TERM_BACKSPACE
-       .word   GRUB_CONSOLE_KEY_PPAGE, GRUB_TERM_PPAGE
-       .word   GRUB_CONSOLE_KEY_NPAGE, GRUB_TERM_NPAGE
-       .word   0
-
-/*
- * translate_keycode translates the key code %dx to an ascii code.
- */
-       .code16
-
-translate_keycode:
-       pushw   %bx
-       pushw   %si
-
-#ifdef __APPLE__
-       movw    $(ABS(LOCAL (translation_table)) - 0x10000), %si
-#else
-       movw    $ABS(LOCAL (translation_table)), %si
-#endif
-
-1:     lodsw
-       /* check if this is the end */
-       testw   %ax, %ax
-       jz      2f
-       /* load the ascii code into %ax */
-       movw    %ax, %bx
-       lodsw
-       /* check if this matches the key code */
-       cmpw    %bx, %dx
-       jne     1b
-       /* translate %dx, if successful */
-       movw    %ax, %dx
-
-2:     popw    %si
-       popw    %bx
-       ret
-
-       .code32
-
-FUNCTION(grub_console_getkey)
-       pushl   %ebp
-
-       call    prot_to_real
-       .code16
-
-       /*
-        * Due to a bug in apple's bootcamp implementation, INT 16/AH = 0 would
-        * cause the machine to hang at the second keystroke. However, we can
-        * work around this problem by ensuring the presence of keystroke with
-        * INT 16/AH = 1 before calling INT 16/AH = 0.
-        */
-
-1:
-       movb    $1, %ah
-       int     $0x16
-       jnz     2f
-       hlt
-       jmp     1b
-
-2:
-
-       movb    $0, %ah
-       int     $0x16
-
-       movw    %ax, %dx                /* real_to_prot uses %eax */
-       call    translate_keycode
-
-       DATA32  call    real_to_prot
-       .code32
-
-       movw    %dx, %ax
-
-       popl    %ebp
-       ret
-
-
-/*
- * int grub_console_checkkey (void)
- *     if there is a character pending, return it; otherwise return -1
- * BIOS call "INT 16H Function 01H" to check whether a character is pending
- *     Call with       %ah = 0x1
- *     Return:
- *             If key waiting to be input:
- *                     %ah = keyboard scan code
- *                     %al = ASCII character
- *                     Zero flag = clear
- *             else
- *                     Zero flag = set
- */
-FUNCTION(grub_console_checkkey)
-       pushl   %ebp
-       xorl    %edx, %edx
-
-       call    prot_to_real    /* enter real mode */
-       .code16
-
-       movb    $0x1, %ah
-       int     $0x16
-
-       jz      notpending
-
-       movw    %ax, %dx
-       DATA32  jmp     pending
-
-notpending:
-       decl    %edx
-
-pending:
-       DATA32  call    real_to_prot
-       .code32
-
-       movl    %edx, %eax
-
-       popl    %ebp
-       ret
-
-
-/*
- * grub_uint16_t grub_console_getxy (void)
- * BIOS call "INT 10H Function 03h" to get cursor position
- *     Call with       %ah = 0x03
- *                     %bh = page
- *      Returns         %ch = starting scan line
- *                      %cl = ending scan line
- *                      %dh = row (0 is top)
- *                      %dl = column (0 is left)
- */
-
-
-FUNCTION(grub_console_getxy)
-       pushl   %ebp
-       pushl   %ebx                    /* save EBX */
-
-       call    prot_to_real
-       .code16
-
-        xorb   %bh, %bh                /* set page to 0 */
-       movb    $0x3, %ah
-       int     $0x10                   /* get cursor position */
-
-       DATA32  call    real_to_prot
-       .code32
-
-       movb    %dl, %ah
-       movb    %dh, %al
-
-       popl    %ebx
-       popl    %ebp
-       ret
-
-
-/*
- * void grub_console_gotoxy(grub_uint8_t x, grub_uint8_t y)
- * BIOS call "INT 10H Function 02h" to set cursor position
- *     Call with       %ah = 0x02
- *                     %bh = page
- *                      %dh = row (0 is top)
- *                      %dl = column (0 is left)
- */
-
-
-FUNCTION(grub_console_gotoxy)
-       pushl   %ebp
-       pushl   %ebx                    /* save EBX */
-
-       movb    %dl, %dh        /* %dh = y */
-       movb    %al, %dl        /* %dl = x */
-
-       call    prot_to_real
-       .code16
-
-        xorb   %bh, %bh                /* set page to 0 */
-       movb    $0x2, %ah
-       int     $0x10                   /* set cursor position */
-
-       DATA32  call    real_to_prot
-       .code32
-
-       popl    %ebx
-       popl    %ebp
-       ret
-
-
-/*
- * void grub_console_cls (void)
- * BIOS call "INT 10H Function 09h" to write character and attribute
- *     Call with       %ah = 0x09
- *                      %al = (character)
- *                      %bh = (page number)
- *                      %bl = (attribute)
- *                      %cx = (number of times)
- */
-
-FUNCTION(grub_console_cls)
-       pushl   %ebp
-       pushl   %ebx                    /* save EBX */
-
-       call    prot_to_real
-       .code16
-
-       /* move the cursor to the beginning */
-       movb    $0x02, %ah
-       xorb    %bh, %bh
-       xorw    %dx, %dx
-       int     $0x10
-
-       /* write spaces to the entire screen */
-       movw    $0x0920, %ax
-       movw    $0x07, %bx
-       movw    $(80 * 25), %cx
-        int    $0x10
-
-       /* move back the cursor */
-       movb    $0x02, %ah
-       int     $0x10
-
-       DATA32  call    real_to_prot
-       .code32
-
-       popl    %ebx
-       popl    %ebp
-       ret
-
-
-/*
- * void grub_console_setcursor (int on)
- * BIOS call "INT 10H Function 01h" to set cursor type
- *      Call with       %ah = 0x01
- *                      %ch = cursor starting scanline
- *                      %cl = cursor ending scanline
- */
-
-console_cursor_state:
-       .byte   1
-console_cursor_shape:
-       .word   0
-
-FUNCTION(grub_console_setcursor)
-       pushl   %ebp
-       pushl   %ebx
-
-       /* push ON */
-       pushl   %eax
-
-       /* check if the standard cursor shape has already been saved */
-       movw    console_cursor_shape, %ax
-       testw   %ax, %ax
-       jne     1f
-
-       call    prot_to_real
-       .code16
-
-       movb    $0x03, %ah
-       xorb    %bh, %bh
-       int     $0x10
-
-       DATA32  call    real_to_prot
-       .code32
-
-       movw    %cx, console_cursor_shape
-1:
-       /* set %cx to the designated cursor shape */
-       movw    $0x2000, %cx
-       popl    %eax
-       testl   %eax, %eax
-       jz      2f
-       movw    console_cursor_shape, %cx
-2:
-       call    prot_to_real
-       .code16
-
-       movb    $0x1, %ah
-       int     $0x10
-
-       DATA32  call    real_to_prot
-       .code32
-
-       popl    %ebx
-       popl    %ebp
-       ret
-
-/*
- * grub_get_rtc()
- *     return the real time in ticks, of which there are about
- *     18-20 per second
- */
-FUNCTION(grub_get_rtc)
-       pushl   %ebp
-
-       call    prot_to_real    /* enter real mode */
-       .code16
-
-       /* %ax is already zero */
-        int    $0x1a
-
-       DATA32  call    real_to_prot
-       .code32
-
-       movl    %ecx, %eax
-       shll    $16, %eax
-       movw    %dx, %ax
-
-       popl    %ebp
-       ret
-
-
-/*
- * unsigned char grub_vga_set_mode (unsigned char mode)
- */
-FUNCTION(grub_vga_set_mode)
-       pushl   %ebp
-       pushl   %ebx
-       movl    %eax, %ecx
-
-       call    prot_to_real
-       .code16
-       /* get current mode */
-       xorw    %bx, %bx
-       movb    $0x0f, %ah
-       int     $0x10
-       movb    %al, %dl
-
-       /* set the new mode */
-       movb    %cl, %al
-       xorb    %ah, %ah
-       int     $0x10
-
-       DATA32  call    real_to_prot
-       .code32
-
-       movb    %dl, %al
-       popl    %ebx
-       popl    %ebp
-       ret
-
-/*
- * grub_vbe_bios_status_t grub_vbe_get_controller_info (struct grub_vbe_info_block *controller_info)
- *
- * Register allocations for parameters:
- * %eax                *controller_info
- */
-FUNCTION(grub_vbe_bios_get_controller_info)
-       pushl   %ebp
-       pushl   %edi
-       pushl   %edx
-
-       movw    %ax, %di        /* Store *controller_info to %edx:%di.  */
-       xorw    %ax, %ax
-       shrl    $4, %eax
-       mov     %eax, %edx      /* prot_to_real destroys %eax.  */
-
-       call    prot_to_real
-       .code16
-
-       pushw   %es
-
-       movw    %dx, %es        /* *controller_info is now on %es:%di.  */
-       movw    $0x4f00, %ax
-       int     $0x10
-
-       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
-
-       popw    %es
-
-       DATA32 call     real_to_prot
-       .code32
-
-       movl    %edx, %eax
-       andl    $0x0FFFF, %eax  /* Return value in %eax.  */
-
-       pop     %edx
-       popl    %edi
-       popl    %ebp
-       ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_get_mode_info (grub_uint32_t mode,
- *                                               struct grub_vbe_mode_info_block *mode_info)
- *
- * Register allocations for parameters:
- * %eax                mode
- * %edx                *mode_info
- */
-FUNCTION(grub_vbe_bios_get_mode_info)
-       pushl   %ebp
-       pushl   %edi
-
-       movl    %eax, %ecx      /* Store mode number to %ecx.  */
-
-       movw    %dx, %di        /* Store *mode_info to %edx:%di.  */
-       xorw    %dx, %dx
-       shrl    $4, %edx
-
-       call    prot_to_real
-       .code16
-
-       pushw   %es
-
-       movw    %dx, %es        /* *mode_info is now on %es:%di.  */
-       movw    $0x4f01, %ax
-       int     $0x10
-
-       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
-
-       popw    %es
-
-       DATA32 call     real_to_prot
-       .code32
-
-       movl    %edx, %eax
-       andl    $0x0FFFF, %eax  /* Return value in %eax.  */
-
-       popl    %edi
-       popl    %ebp
-       ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_set_mode (grub_uint32_t mode,
- *                                          struct grub_vbe_crtc_info_block *crtc_info)
- *
- * Register allocations for parameters:
- * %eax                mode
- * %edx                *crtc_info
- */
-FUNCTION(grub_vbe_bios_set_mode)
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %edi
-
-       movl    %eax, %ebx      /* Store mode in %ebx.  */
-
-       movw    %dx, %di        /* Store *crtc_info to %edx:%di.  */
-       xorw    %dx, %dx
-       shrl    $4, %edx
-
-       call    prot_to_real
-       .code16
-
-       pushw   %es
-
-       movw    %dx, %es        /* *crtc_info is now on %es:%di.  */
-
-       movw    $0x4f02, %ax
-       int     $0x10
-
-       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
-
-       popw    %es
-
-       DATA32 call     real_to_prot
-       .code32
-
-       movw    %dx, %ax
-       andl    $0xFFFF, %eax   /* Return value in %eax.  */
-
-       popl    %edi
-       popl    %ebx
-       popl    %ebp
-       ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_get_mode (grub_uint32_t *mode)
- *
- * Register allocations for parameters:
- * %eax                *mode
- */
-FUNCTION(grub_vbe_bios_get_mode)
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %edi
-       pushl   %edx
-       pushl   %eax            /* Push *mode to stack.  */
-
-       call    prot_to_real
-       .code16
-
-       movw    $0x4f03, %ax
-       int     $0x10
-
-       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
-
-       DATA32 call     real_to_prot
-       .code32
-
-       popl    %edi            /* Pops *mode from stack to %edi.  */
-       andl    $0xFFFF, %ebx
-       movl    %ebx, (%edi)
-
-       movw    %dx, %ax
-       andl    $0xFFFF, %eax   /* Return value in %eax.  */
-
-       popl    %edx
-       popl    %edi
-       popl    %ebx
-       popl    %ebp
-       ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_getset_dac_palette_width (int set, int *dac_mask_size)
- *
- * Register allocations for parameters:
- * %eax                set
- * %edx                *dac_mask_size
- */
-FUNCTION(grub_vbe_bios_getset_dac_palette_width)
-       pushl   %ebp
-       pushl   %ebx
-
-       xorl    %ebx, %ebx
-
-       /* If we only want to fetch the value, set %bl to 1.  */
-       testl   %eax, %eax
-       jne     1f
-       incb    %bl
-1:
-
-       /* Put desired width in %bh.  */
-       movl    (%edx), %eax
-       movb    %al, %bh
-
-       call    prot_to_real
-       .code16
-
-       movw    $0x4f08, %ax
-       int     $0x10
-
-       movw    %ax, %cx        /* real_to_prot destroys %eax.  */
-
-       DATA32 call     real_to_prot
-       .code32
-
-       /* Move result back to *dac_mask_size.  */
-       xorl    %eax, %eax
-       movb    %bh, %al
-       movl    %eax, (%edx)
-
-       /* Return value in %eax.  */
-       movw    %cx, %ax
-
-       popl    %ebx
-       popl    %ebp
-       ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_set_memory_window (grub_uint32_t window,
- *                                                   grub_uint32_t position);
- *
- * Register allocations for parameters:
- * %eax                window
- * %edx                position
- */
-FUNCTION(grub_vbe_bios_set_memory_window)
-       pushl   %ebp
-       pushl   %ebx
-
-       movl    %eax, %ebx
-
-       call    prot_to_real
-       .code16
-
-       movw    $0x4f05, %ax
-       andw    $0x00ff, %bx    /* BL = window, BH = 0, Set memory window.  */
-       int     $0x10
-
-       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
-
-       DATA32 call     real_to_prot
-       .code32
-
-       movw    %dx, %ax
-       andl    $0xFFFF, %eax   /* Return value in %eax.  */
-
-       popl    %ebx
-       popl    %ebp
-       ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_get_memory_window (grub_uint32_t window,
- *                                                   grub_uint32_t *position);
- *
- * Register allocations for parameters:
- * %eax                window
- * %edx                *position
- */
-FUNCTION(grub_vbe_bios_get_memory_window)
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %edi
-       pushl   %edx            /* Push *position to stack.  */
-
-       movl    %eax, %ebx      /* Store window in %ebx.  */
-
-       call    prot_to_real
-       .code16
-
-       movw    $0x4f05, %ax
-       andw    $0x00ff, %bx    /* BL = window.  */
-       orw     $0x0100, %bx    /* BH = 1, Get memory window.  */
-       int     $0x10
-
-       movw    %ax, %bx        /* real_to_prot destroys %eax.  */
-
-       DATA32 call     real_to_prot
-       .code32
-
-       popl    %edi            /* pops *position from stack to %edi.  */
-       andl    $0xFFFF, %edx
-       movl    %edx, (%edi)    /* Return position to caller.  */
-
-       movw    %bx, %ax
-       andl    $0xFFFF, %eax   /* Return value in %eax.  */
-
-       popl    %edi
-       popl    %ebx
-       popl    %ebp
-       ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_set_scanline_length (grub_uint32_t length)
- *
- * Register allocations for parameters:
- * %eax                length
- */
-FUNCTION(grub_vbe_bios_set_scanline_length)
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %edx
-
-       movl    %eax, %ecx      /* Store length in %ecx.  */
-
-       call    prot_to_real
-       .code16
-
-       movw    $0x4f06, %ax
-       movw    $0x0002, %bx    /* BL = 2, Set Scan Line in Bytes.  */
-       int     $0x10
-
-       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
-
-       DATA32 call     real_to_prot
-       .code32
-
-       movw    %dx, %ax
-       andl    $0xFFFF, %eax   /* Return value in %eax.  */
-
-       popl    %edx
-       popl    %ebx
-       popl    %ebp
-       ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_get_scanline_length (grub_uint32_t *length)
- *
- * Register allocations for parameters:
- * %eax                *length
- */
-FUNCTION(grub_vbe_bios_get_scanline_length)
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %edi
-       pushl   %edx            /* Push *length to stack.  */
-
-       call    prot_to_real
-       .code16
-
-       movw    $0x4f06, %ax
-       movw    $0x0001, %bx    /* BL = 1, Get Scan Line Length (in bytes).  */
-       int     $0x10
-
-       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
-
-       DATA32 call     real_to_prot
-       .code32
-
-       popl    %edi            /* Pops *length from stack to %edi.  */
-       andl    $0xFFFF, %ebx
-       movl    %ebx, (%edi)    /* Return length to caller.  */
-
-       movw    %dx, %ax
-       andl    $0xFFFF, %eax   /* Return value in %eax.  */
-
-       popl    %edi
-       popl    %ebx
-       popl    %ebp
-       ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_set_display_start (grub_uint32_t x,
- *                                                   grub_uint32_t y)
- *
- * Register allocations for parameters:
- * %eax                x
- * %edx                y
- */
-FUNCTION(grub_vbe_bios_set_display_start)
-       pushl   %ebp
-       pushl   %ebx
-
-       movl    %eax, %ecx      /* Store x in %ecx.  */
-
-       call    prot_to_real
-       .code16
-
-       movw    $0x4f07, %ax
-       movw    $0x0080, %bx    /* BL = 80h, Set Display Start
-                                  during Vertical Retrace.  */
-       int     $0x10
-
-       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
-
-       DATA32 call     real_to_prot
-       .code32
-
-       movw    %dx, %ax
-       andl    $0xFFFF, %eax   /* Return value in %eax.  */
-
-       popl    %ebx
-       popl    %ebp
-       ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_get_display_start (grub_uint32_t *x,
- *                                                   grub_uint32_t *y)
- *
- * Register allocations for parameters:
- * %eax                *x
- * %edx                *y
- */
-FUNCTION(grub_vbe_bios_get_display_start)
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %edi
-       pushl   %eax            /* Push *x to stack.  */
-       pushl   %edx            /* Push *y to stack.  */
-
-       call    prot_to_real
-       .code16
-
-       movw    $0x4f07, %ax
-       movw    $0x0001, %bx    /* BL = 1, Get Display Start.  */
-       int     $0x10
-
-       movw    %ax, %bx        /* real_to_prot destroys %eax.  */
-
-       DATA32 call     real_to_prot
-       .code32
-
-       popl    %edi            /* Pops *y from stack to %edi.  */
-       andl    $0xFFFF, %edx
-       movl    %edx, (%edi)    /* Return y-position to caller.  */
-
-       popl    %edi            /* Pops *x from stack to %edi.  */
-       andl    $0xFFFF, %ecx
-       movl    %ecx, (%edi)    /* Return x-position to caller.  */
-
-       movw    %bx, %ax
-       andl    $0xFFFF, %eax   /* Return value in %eax.  */
-
-       popl    %edi
-       popl    %ebx
-       popl    %ebp
-       ret
-
-/*
- * grub_vbe_status_t grub_vbe_bios_set_palette_data (grub_uint32_t color_count,
- *                                                  grub_uint32_t start_index,
- *                                                  struct grub_vbe_palette_data *palette_data)
- *
- * Register allocations for parameters:
- * %eax                color_count
- * %edx                start_index
- * %ecx                *palette_data
- */
-FUNCTION(grub_vbe_bios_set_palette_data)
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %edi
-
-       movl    %eax, %ebx      /* Store color_count in %ebx.  */
-
-       movw    %cx, %di        /* Store *palette_data to %ecx:%di.  */
-       xorw    %cx, %cx
-       shrl    $4, %ecx
-
-       call    prot_to_real
-       .code16
-
-       pushw   %es
-
-       movw    %cx, %es        /* *palette_data is now on %es:%di.  */
-       movw    %bx, %cx        /* color_count is now on %cx.  */
-
-       movw    $0x4f09, %ax
-       xorw    %bx, %bx        /* BL = 0, Set Palette Data.  */
-       int     $0x10
-
-       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
-
-       popw    %es
-
-       DATA32 call     real_to_prot
-       .code32
-
-       movw    %dx, %ax
-       andl    $0xFFFF, %eax   /* Return value in %eax.  */
-
-       popl    %edi
-       popl    %ebx
-       popl    %ebp
-       ret
-
-
-pxe_rm_entry:
-       .long   0
-
-/*
- * struct grub_pxenv *grub_pxe_scan (void);
- */
-FUNCTION(grub_pxe_scan)
-       pushl   %ebp
-       pushl   %ebx
-
-       xorl    %ebx, %ebx
-       xorl    %ecx, %ecx
-
-       call    prot_to_real
-       .code16
-
-       pushw   %es
-
-       movw    $0x5650, %ax
-       int     $0x1A
-       cmpw    $0x564E, %ax
-       jnz     1f
-       cmpl    $0x4E455850, %es:(%bx)          /* PXEN(V+)  */
-       jnz     1f
-       cmpw    $0x201, %es:6(%bx)              /* API version  */
-       jb      1f
-       lesw    %es:0x28(%bx), %bx              /* !PXE structure  */
-       cmpl    $0x45585021, %es:(%bx)          /* !PXE  */
-       jnz     1f
-       movw    %es, %cx
-       jmp     2f
-1:
-       xorw    %bx, %bx
-       xorw    %cx, %cx
-2:
-
-       popw    %es
-
-       DATA32 call     real_to_prot
-       .code32
-
-       xorl    %eax, %eax
-       leal    (%eax, %ecx, 4), %ecx
-       leal    (%ebx, %ecx, 4), %eax           /* eax = ecx * 16 + ebx  */
-
-       orl     %eax, %eax
-       jz      1f
-
-       movl    0x10(%eax), %ecx
-       movl    %ecx, pxe_rm_entry
-
-1:
-
-       popl    %ebx
-       popl    %ebp
-       ret
-
-/*
- * int grub_pxe_call (int func, void* data);
- */
-FUNCTION(grub_pxe_call)
-       pushl   %ebp
-       movl    %esp, %ebp
-       pushl   %esi
-       pushl   %edi
-       pushl   %ebx
-
-       movl    %eax, %ecx
-       movl    %edx, %eax
-       andl    $0xF, %eax
-       shrl    $4, %edx
-       shll    $16, %edx
-       addl    %eax, %edx
-       movl    pxe_rm_entry, %ebx
-
-       call    prot_to_real
-       .code16
-
-       pushl   %ebx
-       pushl   %edx
-       pushw   %cx
-       movw    %sp, %bx
-       lcall   *%ss:6(%bx)
-       cld
-       addw    $10, %sp
-       movw    %ax, %cx
-
-       DATA32  call    real_to_prot
-       .code32
-
-       movzwl  %cx, %eax
-
-       popl    %ebx
-       popl    %edi
-       popl    %esi
-       popl    %ebp
-       ret
diff --git a/kern/i386/pit.c b/kern/i386/pit.c
deleted file mode 100644 (file)
index 82a17d3..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/i386/io.h>
-#include <grub/i386/pit.h>
-
-#define TIMER2_REG_CONTROL     0x42
-#define TIMER_REG_COMMAND      0x43
-#define TIMER2_REG_LATCH       0x61
-
-#define TIMER2_SELECT          0x80
-#define TIMER_ENABLE_LSB       0x20
-#define TIMER_ENABLE_MSB       0x10
-#define TIMER2_LATCH           0x20
-#define TIMER2_SPEAKER         0x02
-#define TIMER2_GATE            0x01
-
-void
-grub_pit_wait (grub_uint16_t tics)
-{
-  /* Disable timer2 gate and speaker.  */
-  grub_outb (grub_inb (TIMER2_REG_LATCH) & ~ (TIMER2_SPEAKER | TIMER2_GATE),
-             TIMER2_REG_LATCH);
-
-  /* Set tics.  */
-  grub_outb (TIMER2_SELECT | TIMER_ENABLE_LSB | TIMER_ENABLE_MSB, TIMER_REG_COMMAND);
-  grub_outb (tics & 0xff, TIMER2_REG_CONTROL);
-  grub_outb (tics >> 8, TIMER2_REG_CONTROL);
-
-  /* Enable timer2 gate, keep speaker disabled.  */
-  grub_outb ((grub_inb (TIMER2_REG_LATCH) & ~ TIMER2_SPEAKER) | TIMER2_GATE,
-             TIMER2_REG_LATCH);
-
-  /* Wait.  */
-  while ((grub_inb (TIMER2_REG_LATCH) & TIMER2_LATCH) == 0x00);
-
-  /* Disable timer2 gate and speaker.  */
-  grub_outb (grub_inb (TIMER2_REG_LATCH) & ~ (TIMER2_SPEAKER | TIMER2_GATE),
-             TIMER2_REG_LATCH);
-}
diff --git a/kern/i386/qemu/mmap.c b/kern/i386/qemu/mmap.c
deleted file mode 100644 (file)
index c7fc4f4..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/machine/init.h>
-#include <grub/machine/memory.h>
-#include <grub/machine/boot.h>
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/cmos.h>
-
-#define QEMU_CMOS_MEMSIZE_HIGH         0x35
-#define QEMU_CMOS_MEMSIZE_LOW          0x34
-
-#define min(a,b)       ((a) > (b) ? (b) : (a))
-
-extern char _start[];
-extern char _end[];
-
-grub_size_t grub_lower_mem, grub_upper_mem;
-grub_uint64_t mem_size;
-
-void
-grub_machine_mmap_init ()
-{
-  mem_size = grub_cmos_read (QEMU_CMOS_MEMSIZE_HIGH) << 24 | grub_cmos_read (QEMU_CMOS_MEMSIZE_LOW) << 16;
-
-  /* Don't ask... */
-  mem_size += (16 * 1024 * 1024);
-}
-
-grub_err_t
-grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
-{
-  if (hook (0x0,
-           (grub_addr_t) _start,
-           GRUB_MACHINE_MEMORY_AVAILABLE))
-    return 1;
-
-  if (hook (GRUB_MEMORY_MACHINE_UPPER,
-           0x100000 - GRUB_MEMORY_MACHINE_UPPER,
-           GRUB_MACHINE_MEMORY_RESERVED))
-    return 1;
-
-  /* Protect boot.img, which contains the gdt.  It is mapped at the top of memory
-     (it is also mapped below 0x100000, but we already reserved that area).  */
-  if (hook ((grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE,
-           GRUB_BOOT_MACHINE_SIZE,
-           GRUB_MACHINE_MEMORY_RESERVED))
-    return 1;
-
-  /* Everything else is free.  */
-  if (hook (0x100000,
-           min (mem_size, (grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE) - 0x100000,
-           GRUB_MACHINE_MEMORY_AVAILABLE))
-    return 1;
-
-  return 0;
-}
diff --git a/kern/i386/qemu/startup.S b/kern/i386/qemu/startup.S
deleted file mode 100644 (file)
index 7484650..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <grub/symbol.h>
-#include <grub/machine/memory.h>
-#include <grub/machine/kernel.h>
-
-       .text
-       .code32
-       .globl _start
-_start:
-       jmp     codestart
-
-       . = _start + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR
-VARIABLE(grub_core_entry_addr)
-       .long   0
-VARIABLE(grub_kernel_image_size)
-       .long   0
-VARIABLE(grub_prefix)
-       /* to be filled by grub-mkimage */
-
-       /*
-        *  Leave some breathing room for the prefix.
-        */
-
-       . = _start + GRUB_KERNEL_MACHINE_DATA_END
-
-codestart:
-       /* Relocate to low memory.  First we figure out our location.
-          We will derive the rom start address from it.  */
-       call    1f
-1:     popl    %esi
-
-       /* Rom size is a multiple of 64 kiB.  With this we get the
-          value of `grub_core_entry_addr' in %esi.  */
-       xorw    %si, %si
-
-       /* ... which allows us to access `grub_kernel_image_size'
-          before relocation.  */
-       movl    (grub_kernel_image_size - _start)(%esi), %ecx
-
-
-       movl    $_start, %edi
-       cld
-       rep
-       movsb
-       ljmp    $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $1f
-1:
-
-#ifdef APPLE_CC
-       /* clean out the bss */
-       bss_start_abs = ABS (bss_start)
-       bss_end_abs = ABS (bss_end)
-
-       movl    bss_start_abs, %edi
-
-       /* compute the bss length */
-       movl    bss_end_abs, %ecx
-       subl    %edi, %ecx
-#else
-       /* clean out the bss */
-       movl    $BSS_START_SYMBOL, %edi
-
-       /* compute the bss length */
-       movl    $END_SYMBOL, %ecx
-       subl    %edi, %ecx
-#endif
-               
-       /* clean out */
-       xorl    %eax, %eax
-       cld
-       rep
-       stosb
-
-       /*
-        *  Call the start of main body of C code.
-        */
-       call    EXT_C(grub_main)
-
-       /* This should never happen.  */
-       jmp     EXT_C(grub_stop)
-
-#include "../realmode.S"
diff --git a/kern/i386/realmode.S b/kern/i386/realmode.S
deleted file mode 100644 (file)
index 578c8d2..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2009,2010 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/i386/pc/memory.h>
-
-/*
- * Note: These functions defined in this file may be called from C.
- *       Be careful of that you must not modify some registers. Quote
- *       from gcc-2.95.2/gcc/config/i386/i386.h:
-
-   1 for registers not available across function calls.
-   These must include the FIXED_REGISTERS and also any
-   registers that can be used without being saved.
-   The latter must include the registers where values are returned
-   and the register where structure-value addresses are passed.
-   Aside from that, you can include as many other registers as you like.
-
-  ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
-{  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
- */
-
-/*
- * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
- *       So the first three arguments are passed in %eax, %edx, and %ecx,
- *       respectively, and if a function has a fixed number of arguments
- *       and the number if greater than three, the function must return
- *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
- */
-
-/*
- *  This is the area for all of the special variables.
- */
-
-       .p2align        2       /* force 4-byte alignment */
-
-protstack:
-       .long   GRUB_MEMORY_MACHINE_PROT_STACK
-
-/*
- * This is the Global Descriptor Table
- *
- *  An entry, a "Segment Descriptor", looks like this:
- *
- * 31          24         19   16                 7           0
- * ------------------------------------------------------------
- * |             | |B| |A|       | |   |1|0|E|W|A|            |
- * | BASE 31..24 |G|/|L|V| LIMIT |P|DPL|  TYPE   | BASE 23:16 |  4
- * |             | |D| |L| 19..16| |   |1|1|C|R|A|            |
- * ------------------------------------------------------------
- * |                             |                            |
- * |        BASE 15..0           |       LIMIT 15..0          |  0
- * |                             |                            |
- * ------------------------------------------------------------
- *
- *  Note the ordering of the data items is reversed from the above
- *  description.
- */
-
-       .p2align        2       /* force 4-byte alignment */
-gdt:
-       .word   0, 0
-       .byte   0, 0, 0, 0
-
-       /* -- code segment --
-        * base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present
-        * type = 32bit code execute/read, DPL = 0
-        */
-       .word   0xFFFF, 0
-       .byte   0, 0x9A, 0xCF, 0
-
-       /* -- data segment --
-        * base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present
-        * type = 32 bit data read/write, DPL = 0
-        */
-       .word   0xFFFF, 0
-       .byte   0, 0x92, 0xCF, 0
-
-       /* -- 16 bit real mode CS --
-        * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present
-        * type = 16 bit code execute/read only/conforming, DPL = 0
-        */
-       .word   0xFFFF, 0
-       .byte   0, 0x9E, 0, 0
-
-       /* -- 16 bit real mode DS --
-        * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present
-        * type = 16 bit data read/write, DPL = 0
-        */
-       .word   0xFFFF, 0
-       .byte   0, 0x92, 0, 0
-
-
-/* this is the GDT descriptor */
-gdtdesc:
-       .word   0x27                    /* limit */
-       .long   gdt                     /* addr */
-
-/*
- *  These next two routines, "real_to_prot" and "prot_to_real" are structured
- *  in a very specific way.  Be very careful when changing them.
- *
- *  NOTE:  Use of either one messes up %eax and %ebp.
- */
-
-real_to_prot:
-       .code16
-       cli
-
-       /* load the GDT register */
-       xorw    %ax, %ax
-       movw    %ax, %ds
-       DATA32  ADDR32  lgdt    gdtdesc
-
-       /* turn on protected mode */
-       movl    %cr0, %eax
-       orl     $GRUB_MEMORY_CPU_CR0_PE_ON, %eax
-       movl    %eax, %cr0
-
-       /* jump to relocation, flush prefetch queue, and reload %cs */
-       DATA32  ljmp    $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg
-
-       .code32
-protcseg:
-       /* reload other segment registers */
-       movw    $GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %ax
-       movw    %ax, %ds
-       movw    %ax, %es
-       movw    %ax, %fs
-       movw    %ax, %gs
-       movw    %ax, %ss
-
-       /* put the return address in a known safe location */
-       movl    (%esp), %eax
-       movl    %eax, GRUB_MEMORY_MACHINE_REAL_STACK
-
-       /* get protected mode stack */
-       movl    protstack, %eax
-       movl    %eax, %esp
-       movl    %eax, %ebp
-
-       /* get return address onto the right stack */
-       movl    GRUB_MEMORY_MACHINE_REAL_STACK, %eax
-       movl    %eax, (%esp)
-
-       /* zero %eax */
-       xorl    %eax, %eax
-
-       /* return on the old (or initialized) stack! */
-       ret
-
-prot_to_real:
-       /* just in case, set GDT */
-       lgdt    gdtdesc
-
-       /* save the protected mode stack */
-       movl    %esp, %eax
-       movl    %eax, protstack
-
-       /* get the return address */
-       movl    (%esp), %eax
-       movl    %eax, GRUB_MEMORY_MACHINE_REAL_STACK
-
-       /* set up new stack */
-       movl    $GRUB_MEMORY_MACHINE_REAL_STACK, %eax
-       movl    %eax, %esp
-       movl    %eax, %ebp
-
-       /* set up segment limits */
-       movw    $GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG, %ax
-       movw    %ax, %ds
-       movw    %ax, %es
-       movw    %ax, %fs
-       movw    %ax, %gs
-       movw    %ax, %ss
-
-       /* this might be an extra step */
-       /* jump to a 16 bit segment */
-       ljmp    $GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG, $tmpcseg
-
-tmpcseg:
-       .code16
-
-       /* clear the PE bit of CR0 */
-       movl    %cr0, %eax
-       andl    $(~GRUB_MEMORY_CPU_CR0_PE_ON), %eax
-       movl    %eax, %cr0
-
-       /* flush prefetch queue, reload %cs */
-       DATA32  ljmp    $0, $realcseg
-
-realcseg:
-       /* we are in real mode now
-        * set up the real mode segment registers : DS, SS, ES
-        */
-       /* zero %eax */
-       xorl    %eax, %eax
-
-       movw    %ax, %ds
-       movw    %ax, %es
-       movw    %ax, %fs
-       movw    %ax, %gs
-       movw    %ax, %ss
-
-#ifdef GRUB_MACHINE_PCBIOS
-       /* restore interrupts */
-       sti
-#endif
-
-       /* return on new stack! */
-       DATA32  ret
-
-       .code32
-
-/*
- * grub_reboot()
- *
- * Reboot the system. At the moment, rely on BIOS.
- */
-FUNCTION(grub_reboot)
-       call    prot_to_real
-       .code16
-cold_reboot:
-       /* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */
-       movw    $0x0472, %di
-       movw    %ax, (%di)
-       ljmp    $0xf000, $0xfff0
-       .code32
diff --git a/kern/i386/tsc.c b/kern/i386/tsc.c
deleted file mode 100644 (file)
index 36b35e2..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/* kern/i386/tsc.c - x86 TSC time source implementation
- * Requires Pentium or better x86 CPU that supports the RDTSC instruction.
- * This module uses the RTC (via grub_get_rtc()) to calibrate the TSC to
- * real time.
- *
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/time.h>
-#include <grub/misc.h>
-#include <grub/i386/tsc.h>
-#include <grub/i386/pit.h>
-
-/* This defines the value TSC had at the epoch (that is, when we calibrated it). */
-static grub_uint64_t tsc_boot_time;
-
-/* Calibrated TSC rate.  (In TSC ticks per millisecond.) */
-static grub_uint64_t tsc_ticks_per_ms;
-
-
-grub_uint64_t
-grub_tsc_get_time_ms (void)
-{
-  return tsc_boot_time + grub_divmod64 (grub_get_tsc (), tsc_ticks_per_ms, 0);
-}
-
-
-/* How many RTC ticks to use for calibration loop. (>= 1) */
-#define CALIBRATION_TICKS 2
-
-/* Calibrate the TSC based on the RTC.  */
-static void
-calibrate_tsc (void)
-{
-  /* First calibrate the TSC rate (relative, not absolute time). */
-  grub_uint64_t start_tsc;
-  grub_uint64_t end_tsc;
-
-  start_tsc = grub_get_tsc ();
-  grub_pit_wait (0xffff);
-  end_tsc = grub_get_tsc ();
-
-  tsc_ticks_per_ms = grub_divmod64 (end_tsc - start_tsc, 55, 0);
-}
-
-void
-grub_tsc_init (void)
-{
-  if (grub_cpu_is_tsc_supported ())
-    {
-      tsc_boot_time = grub_get_tsc ();
-      calibrate_tsc ();
-      grub_install_get_time_ms (grub_tsc_get_time_ms);
-    }
-  else
-    {
-      grub_install_get_time_ms (grub_rtc_get_time_ms);
-    }
-}
diff --git a/kern/ieee1275/cmain.c b/kern/ieee1275/cmain.c
deleted file mode 100644 (file)
index c1185f8..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/* cmain.c - Startup code for the PowerPC.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/kernel.h>
-#include <grub/misc.h>
-#include <grub/types.h>
-#include <grub/machine/kernel.h>
-#include <grub/ieee1275/ieee1275.h>
-
-int (*grub_ieee1275_entry_fn) (void *);
-
-grub_ieee1275_phandle_t grub_ieee1275_chosen;
-grub_ieee1275_ihandle_t grub_ieee1275_mmu;
-
-static grub_uint32_t grub_ieee1275_flags;
-\f
-
-
-int
-grub_ieee1275_test_flag (enum grub_ieee1275_flag flag)
-{
-  return (grub_ieee1275_flags & (1 << flag));
-}
-
-void
-grub_ieee1275_set_flag (enum grub_ieee1275_flag flag)
-{
-  grub_ieee1275_flags |= (1 << flag);
-}
-
-#define SF "SmartFirmware(tm)"
-#define OHW "PPC Open Hack'Ware"
-
-static void
-grub_ieee1275_find_options (void)
-{
-  grub_ieee1275_phandle_t root;
-  grub_ieee1275_phandle_t options;
-  grub_ieee1275_phandle_t openprom;
-  grub_ieee1275_phandle_t bootrom;
-  int rc;
-  grub_uint32_t realmode = 0;
-  char tmp[32];
-  int is_smartfirmware = 0;
-  int is_olpc = 0;
-
-  grub_ieee1275_finddevice ("/", &root);
-  grub_ieee1275_finddevice ("/options", &options);
-  grub_ieee1275_finddevice ("/openprom", &openprom);
-
-  rc = grub_ieee1275_get_integer_property (options, "real-mode?", &realmode,
-                                          sizeof realmode, 0);
-  if (((rc >= 0) && realmode) || (grub_ieee1275_mmu == 0))
-    grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_REAL_MODE);
-
-  rc = grub_ieee1275_get_property (openprom, "CodeGen-copyright",
-                                  tmp, sizeof (tmp), 0);
-  if (rc >= 0 && !grub_strncmp (tmp, SF, sizeof (SF) - 1))
-    is_smartfirmware = 1;
-
-  rc = grub_ieee1275_get_property (root, "architecture",
-                                  tmp, sizeof (tmp), 0);
-  if (rc >= 0 && !grub_strcmp (tmp, "OLPC"))
-    is_olpc = 1;
-
-  if (is_smartfirmware)
-    {
-      /* Broken in all versions */
-      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT);
-
-      /* There are two incompatible ways of checking the version number.  Try
-         both. */
-      rc = grub_ieee1275_get_property (openprom, "SmartFirmware-version",
-                                      tmp, sizeof (tmp), 0);
-      if (rc < 0)
-       rc = grub_ieee1275_get_property (openprom, "firmware-version",
-                                        tmp, sizeof (tmp), 0);
-      if (rc >= 0)
-       {
-         /* It is tempting to implement a version parser to set the flags for
-            e.g. 1.3 and below.  However, there's a special situation here.
-            3rd party updates which fix the partition bugs are common, and for
-            some reason their fixes aren't being merged into trunk.  So for
-            example we know that 1.2 and 1.3 are broken, but there's 1.2.99
-            and 1.3.99 which are known good (and applying this workaround
-            would cause breakage). */
-         if (!grub_strcmp (tmp, "1.0")
-             || !grub_strcmp (tmp, "1.1")
-             || !grub_strcmp (tmp, "1.2")
-             || !grub_strcmp (tmp, "1.3"))
-           {
-             grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
-             grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS);
-           }
-       }
-    }
-
-  if (is_olpc)
-    {
-      /* OLPC / XO laptops have three kinds of storage devices:
-
-        - NAND flash.  These are accessible via OFW callbacks, but:
-          - Follow strange semantics, imposed by hardware constraints.
-          - Its ABI is undocumented, and not stable.
-          They lack "device_type" property, which conveniently makes GRUB
-          skip them.
-
-        - USB drives.  Not accessible, because OFW shuts down the controller
-          in order to prevent collisions with applications accessing it
-          directly.  Even worse, attempts to access it will NOT return
-          control to the caller, so we have to avoid probing them.
-
-        - SD cards.  These work fine.
-
-        To avoid breakage, we only need to skip USB probing.  However,
-        since detecting SD cards is more reliable, we do that instead.
-      */
-
-      grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY);
-    }
-
-  if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom))
-    {
-      rc = grub_ieee1275_get_property (bootrom, "model", tmp, sizeof (tmp), 0);
-      if (rc >= 0 && !grub_strncmp (tmp, OHW, sizeof (OHW) - 1))
-       {
-         grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT);
-         grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS);
-         grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET);
-         grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM);
-         grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_ANSI);
-       }
-    }
-}
-
-#undef SF
-#undef OHW
-
-void
-grub_ieee1275_init (void)
-{
-  grub_ieee1275_finddevice ("/chosen", &grub_ieee1275_chosen);
-
-  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "mmu", &grub_ieee1275_mmu,
-                                         sizeof grub_ieee1275_mmu, 0) < 0)
-    grub_ieee1275_mmu = 0;
-
-  grub_ieee1275_find_options ();
-}
diff --git a/kern/ieee1275/ieee1275.c b/kern/ieee1275/ieee1275.c
deleted file mode 100644 (file)
index 9e29191..0000000
+++ /dev/null
@@ -1,609 +0,0 @@
-/* of.c - Access the Open Firmware client interface.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/ieee1275/ieee1275.h>
-#include <grub/types.h>
-
-#define IEEE1275_PHANDLE_INVALID  ((grub_ieee1275_cell_t) -1)
-#define IEEE1275_IHANDLE_INVALID  ((grub_ieee1275_cell_t) 0)
-#define IEEE1275_CELL_INVALID     ((grub_ieee1275_cell_t) -1)
-
-\f
-
-int
-grub_ieee1275_finddevice (char *name, grub_ieee1275_phandle_t *phandlep)
-{
-  struct find_device_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t device;
-    grub_ieee1275_cell_t phandle;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "finddevice", 1, 1);
-  args.device = (grub_ieee1275_cell_t) name;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  *phandlep = args.phandle;
-  if (args.phandle == IEEE1275_PHANDLE_INVALID)
-    return -1;
-  return 0;
-}
-
-int
-grub_ieee1275_get_property (grub_ieee1275_phandle_t phandle,
-                           const char *property, void *buf,
-                           grub_size_t size, grub_ssize_t *actual)
-{
-  struct get_property_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t phandle;
-    grub_ieee1275_cell_t prop;
-    grub_ieee1275_cell_t buf;
-    grub_ieee1275_cell_t buflen;
-    grub_ieee1275_cell_t size;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "getprop", 4, 1);
-  args.phandle = phandle;
-  args.prop = (grub_ieee1275_cell_t) property;
-  args.buf = (grub_ieee1275_cell_t) buf;
-  args.buflen = (grub_ieee1275_cell_t) size;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  if (actual)
-    *actual = (grub_ssize_t) args.size;
-  if (args.size == IEEE1275_CELL_INVALID)
-    return -1;
-  return 0;
-}
-
-int
-grub_ieee1275_get_integer_property (grub_ieee1275_phandle_t phandle,
-                                   const char *property, grub_uint32_t *buf,
-                                   grub_size_t size, grub_ssize_t *actual)
-{
-  int ret;
-  ret = grub_ieee1275_get_property (phandle, property, (void *) buf, size, actual);
-#ifndef GRUB_CPU_WORDS_BIGENDIAN
-  /* Integer properties are always in big endian.  */
-  if (ret == 0)
-    {
-      unsigned int i;
-      size /= sizeof (grub_uint32_t);
-      for (i = 0; i < size; i++)
-       buf[i] = grub_be_to_cpu32 (buf[i]);
-    }
-#endif
-  return ret;
-}
-
-int
-grub_ieee1275_next_property (grub_ieee1275_phandle_t phandle, char *prev_prop,
-                            char *prop)
-{
-  struct get_property_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t phandle;
-    grub_ieee1275_cell_t prev_prop;
-    grub_ieee1275_cell_t next_prop;
-    grub_ieee1275_cell_t flags;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "nextprop", 3, 1);
-  args.phandle = phandle;
-  args.prev_prop = (grub_ieee1275_cell_t) prev_prop;
-  args.next_prop = (grub_ieee1275_cell_t) prop;
-  args.flags = (grub_ieee1275_cell_t) -1;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  return (int) args.flags;
-}
-
-int
-grub_ieee1275_get_property_length (grub_ieee1275_phandle_t phandle,
-                                  const char *prop, grub_ssize_t *length)
-{
-  struct get_property_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t phandle;
-    grub_ieee1275_cell_t prop;
-    grub_ieee1275_cell_t length;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "getproplen", 2, 1);
-  args.phandle = phandle;
-  args.prop = (grub_ieee1275_cell_t) prop;
-  args.length = (grub_ieee1275_cell_t) -1;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  *length = args.length;
-  if (args.length == IEEE1275_CELL_INVALID)
-    return -1;
-  return 0;
-}
-
-int
-grub_ieee1275_instance_to_package (grub_ieee1275_ihandle_t ihandle,
-                                  grub_ieee1275_phandle_t *phandlep)
-{
-  struct instance_to_package_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t ihandle;
-    grub_ieee1275_cell_t phandle;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "instance-to-package", 1, 1);
-  args.ihandle = ihandle;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  *phandlep = args.phandle;
-  if (args.phandle == IEEE1275_PHANDLE_INVALID)
-    return -1;
-  return 0;
-}
-
-int
-grub_ieee1275_package_to_path (grub_ieee1275_phandle_t phandle,
-                              char *path, grub_size_t len,
-                              grub_ssize_t *actual)
-{
-  struct instance_to_package_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t phandle;
-    grub_ieee1275_cell_t buf;
-    grub_ieee1275_cell_t buflen;
-    grub_ieee1275_cell_t actual;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "package-to-path", 3, 1);
-  args.phandle = phandle;
-  args.buf = (grub_ieee1275_cell_t) path;
-  args.buflen = (grub_ieee1275_cell_t) len;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  if (actual)
-    *actual = args.actual;
-  if (args.actual == IEEE1275_CELL_INVALID)
-    return -1;
-  return 0;
-}
-
-int
-grub_ieee1275_instance_to_path (grub_ieee1275_ihandle_t ihandle,
-                               char *path, grub_size_t len,
-                               grub_ssize_t *actual)
-{
-  struct instance_to_path_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t ihandle;
-    grub_ieee1275_cell_t buf;
-    grub_ieee1275_cell_t buflen;
-    grub_ieee1275_cell_t actual;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "instance-to-path", 3, 1);
-  args.ihandle = ihandle;
-  args.buf = (grub_ieee1275_cell_t) path;
-  args.buflen = (grub_ieee1275_cell_t) len;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  if (actual)
-    *actual = args.actual;
-  if (args.actual == IEEE1275_CELL_INVALID)
-    return -1;
-  return 0;
-}
-
-int
-grub_ieee1275_write (grub_ieee1275_ihandle_t ihandle, void *buffer,
-                    grub_size_t len, grub_ssize_t *actualp)
-{
-  struct write_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t ihandle;
-    grub_ieee1275_cell_t buf;
-    grub_ieee1275_cell_t len;
-    grub_ieee1275_cell_t actual;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "write", 3, 1);
-  args.ihandle = ihandle;
-  args.buf = (grub_ieee1275_cell_t) buffer;
-  args.len = (grub_ieee1275_cell_t) len;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  if (actualp)
-    *actualp = args.actual;
-  return 0;
-}
-
-int
-grub_ieee1275_read (grub_ieee1275_ihandle_t ihandle, void *buffer,
-                   grub_size_t len, grub_ssize_t *actualp)
-{
-  struct write_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t ihandle;
-    grub_ieee1275_cell_t buf;
-    grub_ieee1275_cell_t len;
-    grub_ieee1275_cell_t actual;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "read", 3, 1);
-  args.ihandle = ihandle;
-  args.buf = (grub_ieee1275_cell_t) buffer;
-  args.len = (grub_ieee1275_cell_t) len;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  if (actualp)
-    *actualp = args.actual;
-  return 0;
-}
-
-int
-grub_ieee1275_seek (grub_ieee1275_ihandle_t ihandle, grub_disk_addr_t pos,
-                   grub_ssize_t *result)
-{
-  struct write_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t ihandle;
-    grub_ieee1275_cell_t pos_hi;
-    grub_ieee1275_cell_t pos_lo;
-    grub_ieee1275_cell_t result;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "seek", 3, 1);
-  args.ihandle = ihandle;
-  /* To prevent stupid gcc warning.  */
-#if GRUB_IEEE1275_CELL_SIZEOF >= 8
-  args.pos_hi = 0;
-  args.pos_lo = pos;
-#else
-  args.pos_hi = (grub_ieee1275_cell_t) (pos >> (8 * GRUB_IEEE1275_CELL_SIZEOF));
-  args.pos_lo = (grub_ieee1275_cell_t) 
-    (pos & ((1ULL << (8 * GRUB_IEEE1275_CELL_SIZEOF)) - 1));
-#endif
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-
-  if (result)
-    *result = args.result;
-  return 0;
-}
-
-int
-grub_ieee1275_peer (grub_ieee1275_phandle_t node,
-                   grub_ieee1275_phandle_t *result)
-{
-  struct peer_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t node;
-    grub_ieee1275_cell_t result;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "peer", 1, 1);
-  args.node = node;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  *result = args.result;
-  if (args.result == 0)
-    return -1;
-  return 0;
-}
-
-int
-grub_ieee1275_child (grub_ieee1275_phandle_t node,
-                    grub_ieee1275_phandle_t *result)
-{
-  struct child_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t node;
-    grub_ieee1275_cell_t result;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "child", 1, 1);
-  args.node = node;
-  args.result = IEEE1275_PHANDLE_INVALID;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  *result = args.result;
-  if (args.result == 0)
-    return -1;
-  return 0;
-}
-
-int
-grub_ieee1275_parent (grub_ieee1275_phandle_t node,
-                     grub_ieee1275_phandle_t *result)
-{
-  struct parent_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t node;
-    grub_ieee1275_cell_t result;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "parent", 1, 1);
-  args.node = node;
-  args.result = IEEE1275_PHANDLE_INVALID;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  *result = args.result;
-  return 0;
-}
-
-int
-grub_ieee1275_interpret (const char *command, grub_ieee1275_cell_t *catch)
-{
-  struct enter_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t command;
-    grub_ieee1275_cell_t catch;
-  }
-  args;
-
-  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
-    return -1;
-
-  INIT_IEEE1275_COMMON (&args.common, "interpret", 1, 1);
-  args.command = (grub_ieee1275_cell_t) command;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  if (catch)
-    *catch = args.catch;
-  return 0;
-}
-
-int
-grub_ieee1275_enter (void)
-{
-  struct enter_args
-  {
-    struct grub_ieee1275_common_hdr common;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "enter", 0, 0);
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  return 0;
-}
-
-void
-grub_ieee1275_exit (void)
-{
-  struct exit_args
-  {
-    struct grub_ieee1275_common_hdr common;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "exit", 0, 0);
-
-  IEEE1275_CALL_ENTRY_FN (&args);
-  for (;;) ;
-}
-
-int
-grub_ieee1275_open (const char *path, grub_ieee1275_ihandle_t *result)
-{
-  struct open_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t path;
-    grub_ieee1275_cell_t result;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "open", 1, 1);
-  args.path = (grub_ieee1275_cell_t) path;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  *result = args.result;
-  if (args.result == IEEE1275_IHANDLE_INVALID)
-    return -1;
-  return 0;
-}
-
-int
-grub_ieee1275_close (grub_ieee1275_ihandle_t ihandle)
-{
-  struct close_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t ihandle;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "close", 1, 0);
-  args.ihandle = ihandle;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-
-  return 0;
-}
-
-int
-grub_ieee1275_claim (grub_addr_t addr, grub_size_t size, unsigned int align,
-                    grub_addr_t *result)
-{
-  struct claim_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t addr;
-    grub_ieee1275_cell_t size;
-    grub_ieee1275_cell_t align;
-    grub_ieee1275_cell_t base;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "claim", 3, 1);
-  args.addr = (grub_ieee1275_cell_t) addr;
-  args.size = (grub_ieee1275_cell_t) size;
-  args.align = (grub_ieee1275_cell_t) align;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  if (result)
-    *result = args.base;
-  if (args.base == IEEE1275_CELL_INVALID)
-    return -1;
-  return 0;
-}
-
-int
-grub_ieee1275_release (grub_addr_t addr, grub_size_t size)
-{
- struct release_args
- {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t addr;
-    grub_ieee1275_cell_t size;
- }
- args;
-
-  INIT_IEEE1275_COMMON (&args.common, "release", 2, 0);
-  args.addr = addr;
-  args.size = size;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  return 0;
-}
-
-int
-grub_ieee1275_set_property (grub_ieee1275_phandle_t phandle,
-                           const char *propname, void *buf,
-                           grub_size_t size, grub_ssize_t *actual)
-{
-  struct set_property_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t phandle;
-    grub_ieee1275_cell_t propname;
-    grub_ieee1275_cell_t buf;
-    grub_ieee1275_cell_t size;
-    grub_ieee1275_cell_t actual;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "setprop", 4, 1);
-  args.size = (grub_ieee1275_cell_t) size;
-  args.buf = (grub_ieee1275_cell_t) buf;
-  args.propname = (grub_ieee1275_cell_t) propname;
-  args.phandle = (grub_ieee1275_cell_t) phandle;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  *actual = args.actual;
-  if ((args.actual == IEEE1275_CELL_INVALID) || (args.actual != args.size))
-    return -1;
-  return 0;
-}
-
-int
-grub_ieee1275_set_color (grub_ieee1275_ihandle_t ihandle,
-                        int index, int r, int g, int b)
-{
-  struct set_color_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t method;
-    grub_ieee1275_cell_t ihandle;
-    grub_ieee1275_cell_t index;
-    grub_ieee1275_cell_t b;
-    grub_ieee1275_cell_t g;
-    grub_ieee1275_cell_t r;
-    grub_ieee1275_cell_t catch_result;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1);
-  args.method = (grub_ieee1275_cell_t) "color!";
-  args.ihandle = ihandle;
-  args.index = index;
-  args.r = r;
-  args.g = g;
-  args.b = b;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  return args.catch_result;
-}
-
-int
-grub_ieee1275_milliseconds (grub_uint32_t *msecs)
-{
-  struct milliseconds_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t msecs;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "milliseconds", 0, 1);
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  *msecs = args.msecs;
-  return 0;
-}
diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c
deleted file mode 100644 (file)
index 75f261a..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-/*  init.c -- Initialize GRUB on the newworld mac (PPC).  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/kernel.h>
-#include <grub/dl.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/partition.h>
-#include <grub/normal.h>
-#include <grub/fs.h>
-#include <grub/setjmp.h>
-#include <grub/env.h>
-#include <grub/misc.h>
-#include <grub/time.h>
-#include <grub/machine/console.h>
-#include <grub/machine/kernel.h>
-#include <grub/cpu/kernel.h>
-#include <grub/ieee1275/ofdisk.h>
-#include <grub/ieee1275/ieee1275.h>
-
-/* The minimal heap size we can live with. */
-#define HEAP_MIN_SIZE          (unsigned long) (2 * 1024 * 1024)
-
-/* The maximum heap size we're going to claim */
-#define HEAP_MAX_SIZE          (unsigned long) (32 * 1024 * 1024)
-
-/* If possible, we will avoid claiming heap above this address, because it
-   seems to cause relocation problems with OSes that link at 4 MiB */
-#define HEAP_MAX_ADDR          (unsigned long) (32 * 1024 * 1024)
-
-extern char _start[];
-extern char _end[];
-
-void
-grub_exit (void)
-{
-  grub_ieee1275_exit ();
-}
-
-/* Translate an OF filesystem path (separated by backslashes), into a GRUB
-   path (separated by forward slashes).  */
-static void
-grub_translate_ieee1275_path (char *filepath)
-{
-  char *backslash;
-
-  backslash = grub_strchr (filepath, '\\');
-  while (backslash != 0)
-    {
-      *backslash = '/';
-      backslash = grub_strchr (filepath, '\\');
-    }
-}
-
-void
-grub_machine_set_prefix (void)
-{
-  char bootpath[64]; /* XXX check length */
-  char *filename;
-  char *prefix;
-
-  if (grub_prefix[0])
-    {
-      grub_env_set ("prefix", grub_prefix);
-      /* Prefix is hardcoded in the core image.  */
-      return;
-    }
-
-  if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath,
-                                 sizeof (bootpath), 0))
-    {
-      /* Should never happen.  */
-      grub_printf ("/chosen/bootpath property missing!\n");
-      grub_env_set ("prefix", "");
-      return;
-    }
-
-  /* Transform an OF device path to a GRUB path.  */
-
-  prefix = grub_ieee1275_encode_devname (bootpath);
-
-  filename = grub_ieee1275_get_filename (bootpath);
-  if (filename)
-    {
-      char *newprefix;
-      char *lastslash = grub_strrchr (filename, '\\');
-
-      /* Truncate at last directory.  */
-      if (lastslash)
-        {
-         *lastslash = '\0';
-         grub_translate_ieee1275_path (filename);
-
-         newprefix = grub_xasprintf ("%s%s", prefix, filename);
-         if (newprefix)
-           {
-             grub_free (prefix);
-             prefix = newprefix;
-           }
-       }
-    }
-
-  grub_env_set ("prefix", prefix);
-
-  grub_free (filename);
-  grub_free (prefix);
-}
-
-/* Claim some available memory in the first /memory node. */
-static void grub_claim_heap (void)
-{
-  unsigned long total = 0;
-
-  auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type);
-  int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type)
-  {
-    if (type != 1)
-      return 0;
-
-    len -= 1; /* Required for some firmware.  */
-
-    /* Never exceed HEAP_MAX_SIZE  */
-    if (total + len > HEAP_MAX_SIZE)
-      len = HEAP_MAX_SIZE - total;
-
-    /* Avoid claiming anything above HEAP_MAX_ADDR, if possible. */
-    if ((addr < HEAP_MAX_ADDR) &&                              /* if it's too late, don't bother */
-        (addr + len > HEAP_MAX_ADDR) &&                                /* if it wasn't available anyway, don't bother */
-        (total + (HEAP_MAX_ADDR - addr) > HEAP_MIN_SIZE))      /* only limit ourselves when we can afford to */
-       len = HEAP_MAX_ADDR - addr;
-
-    /* In theory, firmware should already prevent this from happening by not
-       listing our own image in /memory/available.  The check below is intended
-       as a safeguard in case that doesn't happen.  However, it doesn't protect
-       us from corrupting our module area, which extends up to a
-       yet-undetermined region above _end.  */
-    if ((addr < (grub_addr_t) _end) && ((addr + len) > (grub_addr_t) _start))
-      {
-        grub_printf ("Warning: attempt to claim over our own code!\n");
-        len = 0;
-      }
-
-    if (len)
-      {
-       /* Claim and use it.  */
-       if (grub_claimmap (addr, len) < 0)
-         return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                            "failed to claim heap at 0x%llx, len 0x%llx",
-                            addr, len);
-       grub_mm_init_region ((void *) (grub_addr_t) addr, len);
-      }
-
-    total += len;
-    if (total >= HEAP_MAX_SIZE)
-      return 1;
-
-    return 0;
-  }
-
-  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET))
-    heap_init (HEAP_MAX_ADDR - HEAP_MIN_SIZE, HEAP_MIN_SIZE, 1);
-  else
-    grub_machine_mmap_iterate (heap_init);
-}
-
-#ifdef __i386__
-
-grub_uint32_t grub_upper_mem;
-
-/* We need to call this before grub_claim_memory.  */
-static void
-grub_get_extended_memory (void)
-{
-  auto int NESTED_FUNC_ATTR find_ext_mem (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type);
-  int NESTED_FUNC_ATTR find_ext_mem (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type)
-    {
-      if (type == 1 && addr == 0x100000)
-        {
-          grub_upper_mem = len;
-          return 1;
-        }
-
-      return 0;
-    }
-
-  grub_machine_mmap_iterate (find_ext_mem);
-}
-
-#endif
-
-static grub_uint64_t ieee1275_get_time_ms (void);
-
-void
-grub_machine_init (void)
-{
-  char args[256];
-  grub_ssize_t actual;
-
-  grub_ieee1275_init ();
-
-  grub_console_init ();
-#ifdef __i386__
-  grub_get_extended_memory ();
-#endif
-  grub_claim_heap ();
-  grub_ofdisk_init ();
-
-  /* Process commandline.  */
-  if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args,
-                                 sizeof args, &actual) == 0
-      && actual > 1)
-    {
-      int i = 0;
-
-      while (i < actual)
-       {
-         char *command = &args[i];
-         char *end;
-         char *val;
-
-         end = grub_strchr (command, ';');
-         if (end == 0)
-           i = actual; /* No more commands after this one.  */
-         else
-           {
-             *end = '\0';
-             i += end - command + 1;
-             while (grub_isspace(args[i]))
-               i++;
-           }
-
-         /* Process command.  */
-         val = grub_strchr (command, '=');
-         if (val)
-           {
-             *val = '\0';
-             grub_env_set (command, val + 1);
-           }
-       }
-    }
-
-  grub_install_get_time_ms (ieee1275_get_time_ms);
-}
-
-void
-grub_machine_fini (void)
-{
-  grub_ofdisk_fini ();
-  grub_console_fini ();
-}
-
-static grub_uint64_t
-ieee1275_get_time_ms (void)
-{
-  grub_uint32_t msecs = 0;
-
-  grub_ieee1275_milliseconds (&msecs);
-
-  return msecs;
-}
-
-grub_uint32_t
-grub_get_rtc (void)
-{
-  return ieee1275_get_time_ms ();
-}
-
-grub_addr_t
-grub_arch_modules_addr (void)
-{
-  return ALIGN_UP((grub_addr_t) _end + GRUB_MOD_GAP, GRUB_MOD_ALIGN);
-}
diff --git a/kern/ieee1275/mmap.c b/kern/ieee1275/mmap.c
deleted file mode 100644 (file)
index 6f06527..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/machine/memory.h>
-#include <grub/ieee1275/ieee1275.h>
-#include <grub/types.h>
-
-grub_err_t
-grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
-{
-  grub_ieee1275_phandle_t root;
-  grub_ieee1275_phandle_t memory;
-  grub_uint32_t available[32];
-  grub_ssize_t available_size;
-  grub_uint32_t address_cells = 1;
-  grub_uint32_t size_cells = 1;
-  int i;
-
-  /* Determine the format of each entry in `available'.  */
-  grub_ieee1275_finddevice ("/", &root);
-  grub_ieee1275_get_integer_property (root, "#address-cells", &address_cells,
-                                     sizeof address_cells, 0);
-  grub_ieee1275_get_integer_property (root, "#size-cells", &size_cells,
-                                     sizeof size_cells, 0);
-
-  if (size_cells > address_cells)
-    address_cells = size_cells;
-
-  /* Load `/memory/available'.  */
-  if (grub_ieee1275_finddevice ("/memory", &memory))
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
-                      "couldn't find /memory node");
-  if (grub_ieee1275_get_integer_property (memory, "available", available,
-                                         sizeof available, &available_size))
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
-                      "couldn't examine /memory/available property");
-
-  /* Decode each entry and call `hook'.  */
-  i = 0;
-  available_size /= sizeof (grub_uint32_t);
-  while (i < available_size)
-    {
-      grub_uint64_t address;
-      grub_uint64_t size;
-
-      address = available[i++];
-      if (address_cells == 2)
-       address = (address << 32) | available[i++];
-
-      size = available[i++];
-      if (size_cells == 2)
-       size = (size << 32) | available[i++];
-
-      if (hook (address, size, GRUB_MACHINE_MEMORY_AVAILABLE))
-       break;
-    }
-
-  return grub_errno;
-}
diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c
deleted file mode 100644 (file)
index cf9e1a8..0000000
+++ /dev/null
@@ -1,435 +0,0 @@
-/*  openfw.c -- Open firmware support functions.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/machine/kernel.h>
-#include <grub/ieee1275/ieee1275.h>
-
-enum grub_ieee1275_parse_type
-{
-  GRUB_PARSE_FILENAME,
-  GRUB_PARSE_PARTITION,
-};
-
-/* Walk children of 'devpath', calling hook for each.  */
-int
-grub_children_iterate (char *devpath,
-                      int (*hook) (struct grub_ieee1275_devalias *alias))
-{
-  grub_ieee1275_phandle_t dev;
-  grub_ieee1275_phandle_t child;
-  char *childtype, *childpath;
-  char *childname;
-  int ret = 0;
-
-  if (grub_ieee1275_finddevice (devpath, &dev))
-    return 0;
-
-  if (grub_ieee1275_child (dev, &child))
-    return 0;
-
-  childtype = grub_malloc (IEEE1275_MAX_PROP_LEN);
-  if (!childtype)
-    return 0;
-  childpath = grub_malloc (IEEE1275_MAX_PATH_LEN);
-  if (!childpath)
-    {
-      grub_free (childtype);
-      return 0;
-    }
-  childname = grub_malloc (IEEE1275_MAX_PROP_LEN);
-  if (!childname)
-    {
-      grub_free (childpath);
-      grub_free (childtype);
-      return 0;
-    }
-
-  do
-    {
-      struct grub_ieee1275_devalias alias;
-      grub_ssize_t actual;
-
-      if (grub_ieee1275_get_property (child, "device_type", childtype,
-                                     IEEE1275_MAX_PROP_LEN, &actual))
-       childtype[0] = 0;
-
-      if (dev == child)
-       continue;
-
-      if (grub_ieee1275_package_to_path (child, childpath,
-                                        IEEE1275_MAX_PATH_LEN, &actual))
-       continue;
-
-      if (grub_strcmp (devpath, childpath) == 0)
-       continue;
-
-      if (grub_ieee1275_get_property (child, "name", childname,
-                                     IEEE1275_MAX_PROP_LEN, &actual))
-       continue;
-
-      alias.type = childtype;
-      alias.path = childpath;
-      alias.name = childname;
-      ret = hook (&alias);
-      if (ret)
-       break;
-    }
-  while (grub_ieee1275_peer (child, &child) != -1);
-
-  grub_free (childname);
-  grub_free (childpath);
-  grub_free (childtype);
-
-  return ret;
-}
-
-int
-grub_ieee1275_devices_iterate (int (*hook) (struct grub_ieee1275_devalias *alias))
-{
-  auto int it_through (struct grub_ieee1275_devalias *alias);
-  int it_through (struct grub_ieee1275_devalias *alias)
-  {
-    if (hook (alias))
-      return 1;
-    return grub_children_iterate (alias->path, it_through);
-  }
-
-  return grub_children_iterate ("/", it_through);
-}
-
-/* Iterate through all device aliases.  This function can be used to
-   find a device of a specific type.  */
-int
-grub_devalias_iterate (int (*hook) (struct grub_ieee1275_devalias *alias))
-{
-  grub_ieee1275_phandle_t aliases;
-  char *aliasname, *devtype;
-  grub_ssize_t actual;
-  struct grub_ieee1275_devalias alias;
-  int ret = 0;
-
-  if (grub_ieee1275_finddevice ("/aliases", &aliases))
-    return 0;
-
-  aliasname = grub_malloc (IEEE1275_MAX_PROP_LEN);
-  if (!aliasname)
-    return 0;
-  devtype = grub_malloc (IEEE1275_MAX_PROP_LEN);
-  if (!devtype)
-    {
-      grub_free (aliasname);
-      return 0;
-    }
-
-  /* Find the first property.  */
-  aliasname[0] = '\0';
-
-  while (grub_ieee1275_next_property (aliases, aliasname, aliasname) > 0)
-    {
-      grub_ieee1275_phandle_t dev;
-      grub_ssize_t pathlen;
-      char *devpath;
-
-      grub_dprintf ("devalias", "devalias name = %s\n", aliasname);
-
-      grub_ieee1275_get_property_length (aliases, aliasname, &pathlen);
-
-      /* The property `name' is a special case we should skip.  */
-      if (!grub_strcmp (aliasname, "name"))
-       continue;
-
-      /* Sun's OpenBoot often doesn't zero terminate the device alias
-        strings, so we will add a NULL byte at the end explicitly.  */
-      pathlen += 1;
-
-      devpath = grub_malloc (pathlen);
-      if (! devpath)
-       {
-         grub_free (devtype);
-         grub_free (aliasname);
-         return 0;
-       }
-
-      if (grub_ieee1275_get_property (aliases, aliasname, devpath, pathlen,
-                                     &actual))
-       {
-         grub_dprintf ("devalias", "get_property (%s) failed\n", aliasname);
-         goto nextprop;
-       }
-      devpath [actual] = '\0';
-
-      if (grub_ieee1275_finddevice (devpath, &dev))
-       {
-         grub_dprintf ("devalias", "finddevice (%s) failed\n", devpath);
-         goto nextprop;
-       }
-
-      if (grub_ieee1275_get_property (dev, "device_type", devtype,
-                                     IEEE1275_MAX_PROP_LEN, &actual))
-       {
-         /* NAND device don't have device_type property.  */
-          devtype[0] = 0;
-       }
-
-      alias.name = aliasname;
-      alias.path = devpath;
-      alias.type = devtype;
-      ret = hook (&alias);
-
-nextprop:
-      grub_free (devpath);
-      if (ret)
-       break;
-    }
-
-  grub_free (devtype);
-  grub_free (aliasname);
-  return ret;
-}
-
-/* Call the "map" method of /chosen/mmu.  */
-int
-grub_ieee1275_map (grub_addr_t phys, grub_addr_t virt, grub_size_t size,
-                  grub_uint32_t mode)
-{
-  struct map_args {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t method;
-    grub_ieee1275_cell_t ihandle;
-    grub_ieee1275_cell_t mode;
-    grub_ieee1275_cell_t size;
-    grub_ieee1275_cell_t virt;
-#ifdef GRUB_MACHINE_SPARC64
-    grub_ieee1275_cell_t phys_high;
-#endif
-    grub_ieee1275_cell_t phys_low;
-    grub_ieee1275_cell_t catch_result;
-  } args;
-
-  INIT_IEEE1275_COMMON (&args.common, "call-method",
-#ifdef GRUB_MACHINE_SPARC64
-                       7,
-#else
-                       6,
-#endif
-                       1);
-  args.method = (grub_ieee1275_cell_t) "map";
-  args.ihandle = grub_ieee1275_mmu;
-#ifdef GRUB_MACHINE_SPARC64
-  args.phys_high = 0;
-#endif
-  args.phys_low = phys;
-  args.virt = virt;
-  args.size = size;
-  args.mode = mode; /* Format is WIMG0PP.  */
-  args.catch_result = (grub_ieee1275_cell_t) -1;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-
-  return args.catch_result;
-}
-
-int
-grub_claimmap (grub_addr_t addr, grub_size_t size)
-{
-  if (grub_ieee1275_claim (addr, size, 0, 0))
-    return -1;
-
-  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_REAL_MODE)
-      && grub_ieee1275_map (addr, addr, size, 0x00))
-    {
-      grub_printf ("map failed: address 0x%llx, size 0x%llx\n",
-                  (long long) addr, (long long) size);
-      grub_ieee1275_release (addr, size);
-      return -1;
-    }
-
-  return 0;
-}
-
-/* Get the device arguments of the Open Firmware node name `path'.  */
-static char *
-grub_ieee1275_get_devargs (const char *path)
-{
-  char *colon = grub_strchr (path, ':');
-
-  if (! colon)
-    return 0;
-
-  return grub_strdup (colon + 1);
-}
-
-/* Get the device path of the Open Firmware node name `path'.  */
-static char *
-grub_ieee1275_get_devname (const char *path)
-{
-  char *colon = grub_strchr (path, ':');
-  char *newpath = 0;
-  int pathlen = grub_strlen (path);
-  auto int match_alias (struct grub_ieee1275_devalias *alias);
-
-  int match_alias (struct grub_ieee1275_devalias *curalias)
-    {
-      /* briQ firmware can change capitalization in /chosen/bootpath.  */
-      if (! grub_strncasecmp (curalias->path, path, pathlen))
-        {
-         newpath = grub_strdup (curalias->name);
-         return 1;
-       }
-
-      return 0;
-    }
-
-  if (colon)
-    pathlen = (int)(colon - path);
-
-  /* Try to find an alias for this device.  */
-  grub_devalias_iterate (match_alias);
-
-  if (! newpath)
-    newpath = grub_strndup (path, pathlen);
-
-  return newpath;
-}
-
-static char *
-grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype)
-{
-  char type[64]; /* XXX check size.  */
-  char *device = grub_ieee1275_get_devname (path);
-  char *args = grub_ieee1275_get_devargs (path);
-  char *ret = 0;
-  grub_ieee1275_phandle_t dev;
-
-  if (!args)
-    /* Shouldn't happen.  */
-    return 0;
-
-  /* We need to know what type of device it is in order to parse the full
-     file path properly.  */
-  if (grub_ieee1275_finddevice (device, &dev))
-    {
-      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "device %s not found", device);
-      goto fail;
-    }
-  if (grub_ieee1275_get_property (dev, "device_type", &type, sizeof type, 0))
-    {
-      grub_error (GRUB_ERR_UNKNOWN_DEVICE,
-                 "device %s lacks a device_type property", device);
-      goto fail;
-    }
-
-  if (!grub_strcmp ("block", type))
-    {
-      /* The syntax of the device arguments is defined in the CHRP and PReP
-         IEEE1275 bindings: "[partition][,[filename]]".  */
-      char *comma = grub_strchr (args, ',');
-
-      if (ptype == GRUB_PARSE_FILENAME)
-       {
-         if (comma)
-           {
-             char *filepath = comma + 1;
-
-             /* Make sure filepath has leading backslash.  */
-             if (filepath[0] != '\\')
-               ret = grub_xasprintf ("\\%s", filepath);
-             else
-               ret = grub_strdup (filepath);
-           }
-       }
-      else if (ptype == GRUB_PARSE_PARTITION)
-        {
-         if (!comma)
-           ret = grub_strdup (args);
-         else
-           ret = grub_strndup (args, (grub_size_t)(comma - args));
-       }
-    }
-  else
-    {
-      /* XXX Handle net devices by configuring & registering a grub_net_dev
-        here, then return its name?
-        Example path: "net:<server ip>,<file name>,<client ip>,<gateway
-        ip>,<bootp retries>,<tftp retries>".  */
-      grub_printf ("Unsupported type %s for device %s\n", type, device);
-    }
-
-fail:
-  grub_free (device);
-  grub_free (args);
-  return ret;
-}
-
-char *
-grub_ieee1275_get_filename (const char *path)
-{
-  return grub_ieee1275_parse_args (path, GRUB_PARSE_FILENAME);
-}
-
-/* Convert a device name from IEEE1275 syntax to GRUB syntax.  */
-char *
-grub_ieee1275_encode_devname (const char *path)
-{
-  char *device = grub_ieee1275_get_devname (path);
-  char *partition = grub_ieee1275_parse_args (path, GRUB_PARSE_PARTITION);
-  char *encoding;
-
-  if (partition && partition[0])
-    {
-      unsigned int partno = grub_strtoul (partition, 0, 0);
-
-      if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS))
-       /* GRUB partition 1 is OF partition 0.  */
-       partno++;
-
-      encoding = grub_xasprintf ("(%s,%d)", device, partno);
-    }
-  else
-    encoding = grub_xasprintf ("(%s)", device);
-
-  grub_free (partition);
-  grub_free (device);
-
-  return encoding;
-}
-
-/* On i386, a firmware-independant grub_reboot() is provided by realmode.S.  */
-#ifndef __i386__
-void
-grub_reboot (void)
-{
-  grub_ieee1275_interpret ("reset-all", 0);
-}
-#endif
-
-void
-grub_halt (void)
-{
-  /* Not standardized.  We try three known commands.  */
-
-  grub_ieee1275_interpret ("shut-down", 0);
-  grub_ieee1275_interpret ("power-off", 0);
-  grub_ieee1275_interpret ("poweroff", 0);
-}
diff --git a/kern/list.c b/kern/list.c
deleted file mode 100644 (file)
index 379b0d8..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/* list.c - grub list function */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/list.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-
-void
-grub_list_push (grub_list_t *head, grub_list_t item)
-{
-  item->next = *head;
-  *head = item;
-}
-
-void *
-grub_list_pop (grub_list_t *head)
-{
-  grub_list_t item;
-
-  item = *head;
-  if (item)
-    *head = item->next;
-
-  return item;
-}
-
-void
-grub_list_remove (grub_list_t *head, grub_list_t item)
-{
-  grub_list_t *p, q;
-
-  for (p = head, q = *p; q; p = &(q->next), q = q->next)
-    if (q == item)
-      {
-       *p = q->next;
-       break;
-      }
-}
-
-int
-grub_list_iterate (grub_list_t head, grub_list_hook_t hook)
-{
-  grub_list_t p;
-
-  for (p = head; p; p = p->next)
-    if (hook (p))
-      return 1;
-
-  return 0;
-}
-
-void
-grub_list_insert (grub_list_t *head, grub_list_t item,
-                 grub_list_test_t test)
-{
-  grub_list_t *p, q;
-
-  for (p = head, q = *p; q; p = &(q->next), q = q->next)
-    if (test (item, q))
-      break;
-
-  *p = item;
-  item->next = q;
-}
-
-void *
-grub_named_list_find (grub_named_list_t head, const char *name)
-{
-  grub_named_list_t result = NULL;
-
-  auto int list_find (grub_named_list_t item);
-  int list_find (grub_named_list_t item)
-    {
-      if (! grub_strcmp (item->name, name))
-       {
-         result = item;
-         return 1;
-       }
-
-      return 0;
-    }
-
-  grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_find);
-  return result;
-}
-
-void
-grub_prio_list_insert (grub_prio_list_t *head, grub_prio_list_t nitem)
-{
-  int inactive = 0;
-
-  auto int test (grub_prio_list_t new_item, grub_prio_list_t item);
-  int test (grub_prio_list_t new_item, grub_prio_list_t item)
-    {
-      int r;
-
-      r = grub_strcmp (new_item->name, item->name);
-      if (r)
-       return (r < 0);
-
-      if (new_item->prio >= (item->prio & GRUB_PRIO_LIST_PRIO_MASK))
-       {
-         item->prio &= ~GRUB_PRIO_LIST_FLAG_ACTIVE;
-         return 1;
-       }
-
-      inactive = 1;
-      return 0;
-    }
-
-  grub_list_insert (GRUB_AS_LIST_P (head), GRUB_AS_LIST (nitem),
-                   (grub_list_test_t) test);
-  if (! inactive)
-    nitem->prio |= GRUB_PRIO_LIST_FLAG_ACTIVE;
-}
diff --git a/kern/main.c b/kern/main.c
deleted file mode 100644 (file)
index 1fdf4ab..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/* main.c - the kernel main routine */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2005,2006,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/kernel.h>
-#include <grub/misc.h>
-#include <grub/symbol.h>
-#include <grub/dl.h>
-#include <grub/term.h>
-#include <grub/file.h>
-#include <grub/device.h>
-#include <grub/env.h>
-#include <grub/mm.h>
-#include <grub/command.h>
-#include <grub/reader.h>
-#include <grub/parser.h>
-
-void
-grub_module_iterate (int (*hook) (struct grub_module_header *header))
-{
-  struct grub_module_info *modinfo;
-  struct grub_module_header *header;
-  grub_addr_t modbase;
-
-  modbase = grub_arch_modules_addr ();
-  modinfo = (struct grub_module_info *) modbase;
-
-  /* Check if there are any modules.  */
-  if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC)
-    return;
-
-  for (header = (struct grub_module_header *) (modbase + modinfo->offset);
-       header < (struct grub_module_header *) (modbase + modinfo->size);
-       header = (struct grub_module_header *) ((char *) header + header->size))
-    {
-      if (hook (header))
-       break;
-    }
-}
-
-/* This is actualy platform-independant but used only on yeeloong and sparc.  */
-#if defined (GRUB_MACHINE_MIPS_YEELOONG) || defined (GRUB_MACHINE_SPARC64)
-grub_addr_t
-grub_modules_get_end (void)
-{
-  struct grub_module_info *modinfo;
-  grub_addr_t modbase;
-
-  modbase = grub_arch_modules_addr ();
-  modinfo = (struct grub_module_info *) modbase;
-
-  /* Check if there are any modules.  */
-  if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC)
-    return modbase;
-
-  return modbase + modinfo->size;
-}
-#endif
-
-/* Load all modules in core.  */
-static void
-grub_load_modules (void)
-{
-  auto int hook (struct grub_module_header *);
-  int hook (struct grub_module_header *header)
-    {
-      /* Not an ELF module, skip.  */
-      if (header->type != OBJ_TYPE_ELF)
-        return 0;
-
-      if (! grub_dl_load_core ((char *) header + sizeof (struct grub_module_header),
-                              (header->size - sizeof (struct grub_module_header))))
-       grub_fatal ("%s", grub_errmsg);
-
-      if (grub_errno)
-       grub_print_error ();
-
-      return 0;
-    }
-
-  grub_module_iterate (hook);
-}
-
-static void
-grub_load_config (void)
-{
-  auto int hook (struct grub_module_header *);
-  int hook (struct grub_module_header *header)
-    {
-      /* Not an embedded config, skip.  */
-      if (header->type != OBJ_TYPE_CONFIG)
-       return 0;
-
-      grub_parser_execute ((char *) header +
-                          sizeof (struct grub_module_header));
-      return 1;
-    }
-
-  grub_module_iterate (hook);
-}
-
-/* Write hook for the environment variables of root. Remove surrounding
-   parentheses, if any.  */
-static char *
-grub_env_write_root (struct grub_env_var *var __attribute__ ((unused)),
-                    const char *val)
-{
-  /* XXX Is it better to check the existence of the device?  */
-  grub_size_t len = grub_strlen (val);
-
-  if (val[0] == '(' && val[len - 1] == ')')
-    return grub_strndup (val + 1, len - 2);
-
-  return grub_strdup (val);
-}
-
-/* Set the root device according to the dl prefix.  */
-static void
-grub_set_root_dev (void)
-{
-  const char *prefix;
-
-  grub_register_variable_hook ("root", 0, grub_env_write_root);
-
-  prefix = grub_env_get ("prefix");
-
-  if (prefix)
-    {
-      char *dev;
-
-      dev = grub_file_get_device_name (prefix);
-      if (dev)
-       {
-         grub_env_set ("root", dev);
-         grub_free (dev);
-       }
-    }
-}
-
-/* Load the normal mode module and execute the normal mode if possible.  */
-static void
-grub_load_normal_mode (void)
-{
-  /* Load the module.  */
-  grub_dl_load ("normal");
-
-  /* Something went wrong.  Print errors here to let user know why we're entering rescue mode.  */
-  grub_print_error ();
-  grub_errno = 0;
-
-  grub_command_execute ("normal", 0, 0);
-}
-
-/* The main routine.  */
-void
-grub_main (void)
-{
-  /* First of all, initialize the machine.  */
-  grub_machine_init ();
-
-  /* Hello.  */
-  grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
-  grub_printf ("Welcome to GRUB!\n\n");
-  grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
-
-  /* Load pre-loaded modules and free the space.  */
-  grub_register_exported_symbols ();
-#ifdef GRUB_LINKER_HAVE_INIT
-  grub_arch_dl_init_linker ();
-#endif  
-  grub_load_modules ();
-
-  /* It is better to set the root device as soon as possible,
-     for convenience.  */
-  grub_machine_set_prefix ();
-  grub_set_root_dev ();
-
-  grub_register_core_commands ();
-  grub_register_rescue_parser ();
-
-  grub_load_config ();
-  grub_load_normal_mode ();
-  grub_rescue_run ();
-}
diff --git a/kern/mips/cache.S b/kern/mips/cache.S
deleted file mode 100644 (file)
index 2c35b6d..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-
-#include <grub/symbol.h>
-
-FUNCTION (grub_cpu_flush_cache)
-FUNCTION (grub_arch_sync_caches)
-#include "cache_flush.S"
-       j $ra
diff --git a/kern/mips/cache_flush.S b/kern/mips/cache_flush.S
deleted file mode 100644 (file)
index 5667ee7..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-       move $t2, $a0
-       addu $t3, $a0, $a1
-       srl $t2, $t2, 5
-       sll $t2, $t2, 5
-       addu $t3, $t3, 0x1f
-       srl $t3, $t3, 5
-       sll $t3, $t3, 5
-       move $t0, $t2
-       subu $t1, $t3, $t2
-1:
-       cache 1, 0($t0)
-       addiu $t0, $t0, 0x1
-       addiu $t1, $t1, 0xffff
-       bne $t1, $zero, 1b
-       sync
-       move $t0, $t2
-       subu $t1, $t3, $t2
-2:
-       cache 0, 0($t0)
-       addiu $t0, $t0, 0x1
-       addiu $t1, $t1, 0xffff
-       bne $t1, $zero, 2b
-       sync
diff --git a/kern/mips/dl.c b/kern/mips/dl.c
deleted file mode 100644 (file)
index 485955e..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/* dl-386.c - arch-dependent part of loadable module support */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/elf.h>
-#include <grub/misc.h>
-#include <grub/err.h>
-#include <grub/cpu/types.h>
-#include <grub/mm.h>
-
-/* Dummy __gnu_local_gp. Resolved by linker.  */
-static char __gnu_local_gp_dummy;
-
-/* Check if EHDR is a valid ELF header.  */
-grub_err_t
-grub_arch_dl_check_header (void *ehdr)
-{
-  Elf_Ehdr *e = ehdr;
-
-  /* Check the magic numbers.  */
-#ifdef WORDS_BIGENDIAN
-  if (e->e_ident[EI_CLASS] != ELFCLASS32
-      || e->e_ident[EI_DATA] != ELFDATA2MSB
-      || e->e_machine != EM_MIPS)
-#else
-  if (e->e_ident[EI_CLASS] != ELFCLASS32
-      || e->e_ident[EI_DATA] != ELFDATA2LSB
-      || e->e_machine != EM_MIPS)
-#endif
-    return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
-
-  return GRUB_ERR_NONE;
-}
-
-/* Relocate symbols.  */
-grub_err_t
-grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
-{
-  Elf_Ehdr *e = ehdr;
-  Elf_Shdr *s;
-  Elf_Word entsize;
-  unsigned i;
-  grub_size_t gp_size = 0;
-  /* FIXME: suboptimal.  */
-  grub_uint32_t *gp, *gpptr;
-  grub_uint32_t gp0;
-
-  /* Find a symbol table.  */
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_SYMTAB)
-      break;
-
-  if (i == e->e_shnum)
-    return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
-
-  entsize = s->sh_entsize;
-
-  /* Find reginfo. */
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_MIPS_REGINFO)
-      break;
-
-  if (i == e->e_shnum)
-    return grub_error (GRUB_ERR_BAD_MODULE, "no reginfo found");
-
-  gp0 = ((grub_uint32_t *)((char *) e + s->sh_offset))[5];
-
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_REL)
-      {
-       grub_dl_segment_t seg;
-
-       /* Find the target segment.  */
-       for (seg = mod->segment; seg; seg = seg->next)
-         if (seg->section == s->sh_info)
-           break;
-
-       if (seg)
-         {
-           Elf_Rel *rel, *max;
-
-           for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
-                  max = rel + s->sh_size / s->sh_entsize;
-                rel < max;
-                rel++)
-               switch (ELF_R_TYPE (rel->r_info))
-                 {
-                 case R_MIPS_GOT16:
-                 case R_MIPS_CALL16:
-                 case R_MIPS_GPREL32:
-                   gp_size += 4;
-                   break;
-                 }
-         }
-      }
-
-  if (gp_size > 0x08000)
-    return grub_error (GRUB_ERR_OUT_OF_RANGE, "__gnu_local_gp is too big\n");
-
-  gpptr = gp = grub_malloc (gp_size);
-  if (!gp)
-    return grub_errno;
-
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_REL)
-      {
-       grub_dl_segment_t seg;
-
-       /* Find the target segment.  */
-       for (seg = mod->segment; seg; seg = seg->next)
-         if (seg->section == s->sh_info)
-           break;
-
-       if (seg)
-         {
-           Elf_Rel *rel, *max;
-
-           for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
-                  max = rel + s->sh_size / s->sh_entsize;
-                rel < max;
-                rel++)
-             {
-               Elf_Word *addr;
-               Elf_Sym *sym;
-
-               if (seg->size < rel->r_offset)
-                 return grub_error (GRUB_ERR_BAD_MODULE,
-                                    "reloc offset is out of the segment");
-
-               addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
-               sym = (Elf_Sym *) ((char *) mod->symtab
-                                    + entsize * ELF_R_SYM (rel->r_info));
-               if (sym->st_value == (grub_addr_t) &__gnu_local_gp_dummy)
-                 sym->st_value = (grub_addr_t) gp;
-
-               switch (ELF_R_TYPE (rel->r_info))
-                 {
-                 case R_MIPS_HI16:
-                   {
-                     grub_uint32_t value;
-                     Elf_Rel *rel2;
-                     
-                     /* Handle partner lo16 relocation. Lower part is
-                        treated as signed. Hence add 0x8000 to compensate. 
-                      */
-                     value = (*(grub_uint16_t *) addr << 16)
-                       + sym->st_value + 0x8000;
-                     for (rel2 = rel + 1; rel2 < max; rel2++)
-                       if (ELF_R_SYM (rel2->r_info)
-                           == ELF_R_SYM (rel->r_info)
-                           && ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16)
-                         {
-                           value += *(grub_int16_t *)
-                             ((char *) seg->addr + rel2->r_offset);
-                           break;
-                         }
-                     *(grub_uint16_t *) addr = (value >> 16) & 0xffff;
-                   }
-                   break;
-                 case R_MIPS_LO16:
-                   *(grub_uint16_t *) addr += (sym->st_value) & 0xffff;
-                   break;
-                 case R_MIPS_32:
-                   *(grub_uint32_t *) addr += sym->st_value;
-                   break;
-                 case R_MIPS_GPREL32:
-                   *(grub_uint32_t *) addr = sym->st_value
-                     + *(grub_uint32_t *) addr + gp0 - (grub_uint32_t)gp;
-                   break;
-
-                 case R_MIPS_26:
-                   {
-                     grub_uint32_t value;
-                     grub_uint32_t raw;
-                     raw = (*(grub_uint32_t *) addr) & 0x3ffffff;
-                     value = raw << 2;
-                     value += sym->st_value;
-                     raw = (value >> 2) & 0x3ffffff;
-                       
-                     *(grub_uint32_t *) addr = 
-                       raw | ((*(grub_uint32_t *) addr) & 0xfc000000);
-                   }
-                   break;
-                 case R_MIPS_GOT16:
-                 case R_MIPS_CALL16:
-                   /* FIXME: reuse*/
-                   *gpptr = sym->st_value + *(grub_uint16_t *) addr;
-                   *(grub_uint16_t *) addr
-                     = sizeof (grub_uint32_t) * (gpptr - gp);
-                   gpptr++;
-                   break;
-                 default:
-                   {
-                     grub_free (gp);
-                     return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                                        "Unknown relocation type %d\n",
-                                        ELF_R_TYPE (rel->r_info));
-                   }
-                   break;
-                 }
-             }
-         }
-      }
-
-  return GRUB_ERR_NONE;
-}
-
-void 
-grub_arch_dl_init_linker (void)
-{
-  grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0);
-}
-
diff --git a/kern/mips/init.c b/kern/mips/init.c
deleted file mode 100644 (file)
index 5adcedc..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/kernel.h>
-#include <grub/env.h>
-#include <grub/mips/kernel.h>
-
-void
-grub_machine_set_prefix (void)
-{
-  grub_env_set ("prefix", grub_prefix);
-}
-
-extern char _end[];
-
-grub_addr_t
-grub_arch_modules_addr (void)
-{
-  return (grub_addr_t) _end;
-}
diff --git a/kern/mips/qemu-mips/init.c b/kern/mips/qemu-mips/init.c
deleted file mode 100644 (file)
index 866c7a8..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <grub/kernel.h>
-#include <grub/misc.h>
-#include <grub/env.h>
-#include <grub/time.h>
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/time.h>
-#include <grub/machine/kernel.h>
-#include <grub/machine/memory.h>
-#include <grub/cpu/kernel.h>
-
-#define RAMSIZE (*(grub_uint32_t *) ((16 << 20) - 264))
-
-grub_uint32_t
-grub_get_rtc (void)
-{
-  static int calln = 0;
-  return calln++;
-}
-
-void
-grub_machine_init (void)
-{
-  grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_USABLE,
-                      RAMSIZE - (GRUB_MACHINE_MEMORY_USABLE & 0x7fffffff));
-  grub_install_get_time_ms (grub_rtc_get_time_ms);
-}
-
-void
-grub_machine_fini (void)
-{
-}
-
-void
-grub_exit (void)
-{
-  while (1);
-}
-
-void
-grub_halt (void)
-{
-  while (1);
-}
-
-void
-grub_reboot (void)
-{
-  while (1);
-}
-
-grub_err_t 
-grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, 
-                                                        grub_uint64_t, 
-                                                        grub_uint32_t))
-{
-  hook (0, RAMSIZE,
-       GRUB_MACHINE_MEMORY_AVAILABLE);
-  return GRUB_ERR_NONE;
-}
diff --git a/kern/mips/startup.S b/kern/mips/startup.S
deleted file mode 100644 (file)
index 5e3fb7a..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-/* startup.S - Startup code for the MIPS.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-#include <grub/cpu/kernel.h>
-#include <grub/machine/memory.h>
-
-#define BASE_ADDR 8
-       
-.extern __bss_start
-.extern _end
-       
-       .globl __start, _start, start
-__start:
-_start:
-start: 
-       bal codestart
-base:  
-       . = _start + GRUB_KERNEL_CPU_COMPRESSED_SIZE
-compressed_size:
-       .long 0
-       . = _start + GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE
-total_module_size:
-       .long 0
-       . = _start + GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE
-kernel_image_size:     
-       .long   0
-codestart:
-       /* Save our base.  */
-       move $s0, $ra
-
-       /* Parse arguments. Has to be done before relocation.
-       So need to do it in asm.  */
-#ifdef GRUB_MACHINE_MIPS_YEELOONG
-       /* $a2 has the environment.  */
-       move $t0, $a2
-argcont:       
-       lw $t1, 0($t0)
-       beq $t1, $zero, argdone
-#define DO_PARSE(str, reg) \
-       addiu $t2, $s0, (str-base);\
-       bal parsestr;\
-       beq $v0, $zero, 1f;\
-       move reg, $v0;\
-       b 2f;\
-1:     
-       DO_PARSE (busclockstr, $s2)
-       DO_PARSE (cpuclockstr, $s3)
-       DO_PARSE (memsizestr, $s4)
-       DO_PARSE (highmemsizestr, $s5)
-2:     
-       addiu $t0, $t0, 4
-       b argcont
-parsestr:
-       move $v0, $zero
-       move $t3, $t1
-3:     
-       lb $t4, 0($t2)
-       lb $t5, 0($t3)
-       addiu $t2, $t2, 1
-       addiu $t3, $t3, 1
-       beq $t5, $zero, 1f
-       beq $t5, $t4, 3b
-       bne $t4, $zero, 1f
-
-       addiu $t3, $t3, 0xffff
-digcont:       
-       lb $t5, 0($t3)
-       /* Substract '0' from digit.  */
-       addiu $t5, $t5, 0xffd0
-       bltz $t5, 1f
-       addiu $t4, $t5, 0xfff7
-       bgtz $t4, 1f
-       /* Multiply $v0 by 10 with bitshifts. */
-       sll $v0, $v0, 1
-       sll $t4, $v0, 2
-       addu $v0, $v0, $t4
-       addu $v0, $v0, $t5
-       addiu $t3, $t3, 1
-       b digcont
-1:
-       jr $ra
-busclockstr:   .asciiz "busclock="
-cpuclockstr:   .asciiz "cpuclock="
-memsizestr:    .asciiz "memsize="
-highmemsizestr:        .asciiz "highmemsize="
-       .p2align 2
-argdone:
-#endif
-
-       /* Decompress the payload. */
-       addiu $a0, $s0, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR
-       lui $a1, %hi(compressed)
-       addiu $a1, %lo(compressed)
-       lw $a2, (GRUB_KERNEL_CPU_COMPRESSED_SIZE - BASE_ADDR)($s0)
-       move $s1, $a1
-
-       /* $a0 contains source compressed address, $a1 is destination,
-          $a2 is compressed size. FIXME: put LZMA here. Don't clober $s0,
-          $s1, $s2, $s3, $s4 and $s5.
-          On return $v0 contains uncompressed size.
-       */
-       move $v0, $a2
-reloccont:
-       lb $t4, 0($a0)
-       sb $t4, 0($a1)
-       addiu $a1,$a1,1
-       addiu $a0,$a0,1
-       addiu $a2, 0xffff
-       bne $a2, $0, reloccont
-
-       move $a0, $s1
-       move $a1, $v0
-
-#include "cache_flush.S"
-
-       lui $t1, %hi(cont)
-       addiu $t1, %lo(cont)
-
-       jr $t1
-       . = _start + GRUB_KERNEL_CPU_RAW_SIZE
-compressed:    
-       . = _start + GRUB_KERNEL_CPU_PREFIX
-
-VARIABLE(grub_prefix)
-
-       /* to be filled by grub-mkelfimage */
-
-       /*
-        *  Leave some breathing room for the prefix.
-        */
-
-       . = _start + GRUB_KERNEL_CPU_DATA_END
-#ifdef GRUB_MACHINE_MIPS_YEELOONG
-VARIABLE (grub_arch_busclock)
-       .long 0
-VARIABLE (grub_arch_cpuclock)
-       .long 0
-VARIABLE (grub_arch_memsize)
-       .long 0
-VARIABLE (grub_arch_highmemsize)
-       .long 0
-#endif
-cont:
-
-#ifdef GRUB_MACHINE_MIPS_YEELOONG
-       lui $t1, %hi(grub_arch_busclock)
-       addiu $t1, %lo(grub_arch_busclock)
-       sw $s2, 0($t1)
-       sw $s3, 4($t1)
-       sw $s4, 8($t1)
-       sw $s5, 12($t1)
-#endif
-
-       /* Move the modules out of BSS.  */
-       lui $t1, %hi(_start)
-       addiu $t1, %lo(_start)
-       lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0)
-       addu $t2, $t1, $t2
-       
-       lui $t1, %hi(_end)
-       addiu $t1, %lo(_end)
-       addiu $t1, (GRUB_MOD_ALIGN-1)
-       li $t3, (GRUB_MOD_ALIGN-1)
-       nor $t3, $t3, $0
-       and $t1, $t1, $t3
-       
-       lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($s0)
-
-       /* Backward copy.  */
-       add $t1, $t1, $t3
-       add $t2, $t2, $t3
-       addiu $t1, $t1, 0xffff
-       addiu $t2, $t2, 0xffff
-
-       /* $t2 is source. $t1 is destination. $t3 is size.  */
-modulesmovcont:
-       lb $t4, 0($t2)
-       sb $t4, 0($t1)
-       addiu $t1,$t1,0xffff
-       addiu $t2,$t2,0xffff
-       addiu $t3, 0xffff
-       bne $t3, $0, modulesmovcont
-
-       /* Clean BSS.  */
-       
-       lui $t1, %hi(__bss_start)
-       addiu $t1, %lo(__bss_start)
-       lui $t2, %hi(_end)
-       addiu $t2, %lo(_end)
-bsscont:
-       sb $0,0($t1)
-       addiu $t1,$t1,1
-       sltu $t3,$t1,$t2
-       bne $t3, $0, bsscont
-
-       li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH
-       lui $t1, %hi(grub_main)
-       addiu $t1, %lo(grub_main)
-
-       jr $t1
-
diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c
deleted file mode 100644 (file)
index 6bba27b..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/kernel.h>
-#include <grub/misc.h>
-#include <grub/env.h>
-#include <grub/time.h>
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/time.h>
-#include <grub/machine/kernel.h>
-#include <grub/machine/memory.h>
-#include <grub/cpu/kernel.h>
-
-extern void grub_video_sm712_init (void);
-extern void grub_video_init (void);
-extern void grub_bitmap_init (void);
-extern void grub_font_init (void);
-extern void grub_gfxterm_init (void);
-extern void grub_at_keyboard_init (void);
-
-/* FIXME: use interrupt to count high.  */
-grub_uint64_t
-grub_get_rtc (void)
-{
-  static grub_uint32_t high = 0;
-  static grub_uint32_t last = 0;
-  grub_uint32_t low;
-
-  asm volatile ("mfc0 %0, $9": "=r" (low));
-  if (low < last)
-    high++;
-  last = low;
-
-  return (((grub_uint64_t) high) << 32) | low;
-}
-
-grub_err_t
-grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
-                                                        grub_uint64_t,
-                                                        grub_uint32_t))
-{
-  hook (GRUB_ARCH_LOWMEMPSTART, grub_arch_memsize << 20,
-       GRUB_MACHINE_MEMORY_AVAILABLE);
-  hook (GRUB_ARCH_HIGHMEMPSTART, grub_arch_highmemsize << 20,
-       GRUB_MACHINE_MEMORY_AVAILABLE);
-  return GRUB_ERR_NONE;
-}
-
-void
-grub_machine_init (void)
-{
-  grub_addr_t modend;
-  modend = grub_modules_get_end ();
-  grub_mm_init_region ((void *) modend, (grub_arch_memsize << 20)
-                      - (modend - GRUB_ARCH_LOWMEMVSTART));
-  /* FIXME: use upper memory as well.  */
-  grub_install_get_time_ms (grub_rtc_get_time_ms);
-
-  /* Initialize output terminal (can't be done earlier, as gfxterm
-     relies on a working heap.  */
-  grub_video_sm712_init ();
-  grub_video_init ();
-  grub_bitmap_init ();
-  grub_font_init ();
-  grub_gfxterm_init ();
-
-  grub_at_keyboard_init ();
-}
-
-void
-grub_machine_fini (void)
-{
-}
-
-void
-grub_exit (void)
-{
-  while (1);
-}
-
-void
-grub_halt (void)
-{
-  while (1);
-}
-
-void
-grub_reboot (void)
-{
-  while (1);
-}
-
diff --git a/kern/misc.c b/kern/misc.c
deleted file mode 100644 (file)
index ccc01d4..0000000
+++ /dev/null
@@ -1,1077 +0,0 @@
-/* misc.c - definitions of misc functions */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/err.h>
-#include <grub/mm.h>
-#include <stdarg.h>
-#include <grub/term.h>
-#include <grub/env.h>
-#include <grub/i18n.h>
-
-static int
-grub_vsnprintf_real (char *str, grub_size_t n, const char *fmt, va_list args);
-
-static int
-grub_iswordseparator (int c)
-{
-  return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&');
-}
-
-/* grub_gettext_dummy is not translating anything.  */
-static const char *
-grub_gettext_dummy (const char *s)
-{
-  return s;
-}
-
-const char* (*grub_gettext) (const char *s) = grub_gettext_dummy;
-
-void *
-grub_memmove (void *dest, const void *src, grub_size_t n)
-{
-  char *d = (char *) dest;
-  const char *s = (const char *) src;
-
-  if (d < s)
-    while (n--)
-      *d++ = *s++;
-  else
-    {
-      d += n;
-      s += n;
-
-      while (n--)
-       *--d = *--s;
-    }
-
-  return dest;
-}
-
-#ifndef APPLE_CC
-void *memmove (void *dest, const void *src, grub_size_t n)
-  __attribute__ ((alias ("grub_memmove")));
-/* GCC emits references to memcpy() for struct copies etc.  */
-void *memcpy (void *dest, const void *src, grub_size_t n)
-  __attribute__ ((alias ("grub_memmove")));
-#else
-void *memcpy (void *dest, const void *src, grub_size_t n)
-{
-       return grub_memmove (dest, src, n);
-}
-void *memmove (void *dest, const void *src, grub_size_t n)
-{
-       return grub_memmove (dest, src, n);
-}
-#endif
-
-char *
-grub_strcpy (char *dest, const char *src)
-{
-  char *p = dest;
-
-  while ((*p++ = *src++) != '\0')
-    ;
-
-  return dest;
-}
-
-char *
-grub_strncpy (char *dest, const char *src, int c)
-{
-  char *p = dest;
-
-  while ((*p++ = *src++) != '\0' && --c)
-    ;
-
-  return dest;
-}
-
-char *
-grub_stpcpy (char *dest, const char *src)
-{
-  char *d = dest;
-  const char *s = src;
-
-  do
-    *d++ = *s;
-  while (*s++ != '\0');
-
-  return d - 1;
-}
-
-int
-grub_printf (const char *fmt, ...)
-{
-  va_list ap;
-  int ret;
-
-  va_start (ap, fmt);
-  ret = grub_vprintf (fmt, ap);
-  va_end (ap);
-
-  return ret;
-}
-
-int
-grub_printf_ (const char *fmt, ...)
-{
-  va_list ap;
-  int ret;
-
-  va_start (ap, fmt);
-  ret = grub_vprintf (_(fmt), ap);
-  va_end (ap);
-
-  return ret;
-}
-
-int
-grub_puts (const char *s)
-{
-  while (*s)
-    {
-      grub_putchar (*s);
-      s++;
-    }
-  grub_putchar ('\n');
-
-  return 1;    /* Cannot fail.  */
-}
-
-int
-grub_puts_ (const char *s)
-{
-  return grub_puts (_(s));
-}
-
-#if defined (APPLE_CC) && ! defined (GRUB_UTIL)
-int
-grub_err_printf (const char *fmt, ...)
-{
-       va_list ap;
-       int ret;
-
-       va_start (ap, fmt);
-       ret = grub_vprintf (fmt, ap);
-       va_end (ap);
-
-       return ret;
-}
-#endif
-
-#if ! defined (APPLE_CC) && ! defined (GRUB_UTIL)
-int grub_err_printf (const char *fmt, ...)
-__attribute__ ((alias("grub_printf")));
-#endif
-
-void
-grub_real_dprintf (const char *file, const int line, const char *condition,
-                  const char *fmt, ...)
-{
-  va_list args;
-  const char *debug = grub_env_get ("debug");
-
-  if (! debug)
-    return;
-
-  if (grub_strword (debug, "all") || grub_strword (debug, condition))
-    {
-      grub_printf ("%s:%d: ", file, line);
-      va_start (args, fmt);
-      grub_vprintf (fmt, args);
-      va_end (args);
-    }
-}
-
-int
-grub_vprintf (const char *fmt, va_list args)
-{
-  int ret;
-
-  ret = grub_vsnprintf_real (0, 0, fmt, args);
-  return ret;
-}
-
-int
-grub_memcmp (const void *s1, const void *s2, grub_size_t n)
-{
-  const char *t1 = s1;
-  const char *t2 = s2;
-
-  while (n--)
-    {
-      if (*t1 != *t2)
-       return (int) *t1 - (int) *t2;
-
-      t1++;
-      t2++;
-    }
-
-  return 0;
-}
-#ifndef APPLE_CC
-int memcmp (const void *s1, const void *s2, grub_size_t n)
-  __attribute__ ((alias ("grub_memcmp")));
-#else
-int memcmp (const void *s1, const void *s2, grub_size_t n)
-{
-  return grub_memcmp (s1, s2, n);
-}
-#endif
-
-int
-grub_strcmp (const char *s1, const char *s2)
-{
-  while (*s1 && *s2)
-    {
-      if (*s1 != *s2)
-       break;
-
-      s1++;
-      s2++;
-    }
-
-  return (int) *s1 - (int) *s2;
-}
-
-int
-grub_strncmp (const char *s1, const char *s2, grub_size_t n)
-{
-  if (n == 0)
-    return 0;
-
-  while (*s1 && *s2 && --n)
-    {
-      if (*s1 != *s2)
-       break;
-
-      s1++;
-      s2++;
-    }
-
-  return (int) *s1 - (int) *s2;
-}
-
-char *
-grub_strchr (const char *s, int c)
-{
-  do
-    {
-      if (*s == c)
-       return (char *) s;
-    }
-  while (*s++);
-
-  return 0;
-}
-
-char *
-grub_strrchr (const char *s, int c)
-{
-  char *p = NULL;
-
-  do
-    {
-      if (*s == c)
-       p = (char *) s;
-    }
-  while (*s++);
-
-  return p;
-}
-
-/* Copied from gnulib.
-   Written by Bruno Haible <bruno@clisp.org>, 2005. */
-char *
-grub_strstr (const char *haystack, const char *needle)
-{
-  /* Be careful not to look at the entire extent of haystack or needle
-     until needed.  This is useful because of these two cases:
-       - haystack may be very long, and a match of needle found early,
-       - needle may be very long, and not even a short initial segment of
-       needle may be found in haystack.  */
-  if (*needle != '\0')
-    {
-      /* Speed up the following searches of needle by caching its first
-        character.  */
-      char b = *needle++;
-
-      for (;; haystack++)
-       {
-         if (*haystack == '\0')
-           /* No match.  */
-           return NULL;
-         if (*haystack == b)
-           /* The first character matches.  */
-           {
-             const char *rhaystack = haystack + 1;
-             const char *rneedle = needle;
-
-             for (;; rhaystack++, rneedle++)
-               {
-                 if (*rneedle == '\0')
-                   /* Found a match.  */
-                   return (char *) haystack;
-                 if (*rhaystack == '\0')
-                   /* No match.  */
-                   return NULL;
-                 if (*rhaystack != *rneedle)
-                   /* Nothing in this round.  */
-                   break;
-               }
-           }
-       }
-    }
-  else
-    return (char *) haystack;
-}
-
-int
-grub_strword (const char *haystack, const char *needle)
-{
-  const char *n_pos = needle;
-
-  while (grub_iswordseparator (*haystack))
-    haystack++;
-
-  while (*haystack)
-    {
-      /* Crawl both the needle and the haystack word we're on.  */
-      while(*haystack && !grub_iswordseparator (*haystack)
-            && *haystack == *n_pos)
-        {
-          haystack++;
-          n_pos++;
-        }
-
-      /* If we reached the end of both words at the same time, the word
-      is found. If not, eat everything in the haystack that isn't the
-      next word (or the end of string) and "reset" the needle.  */
-      if ( (!*haystack || grub_iswordseparator (*haystack))
-         && (!*n_pos || grub_iswordseparator (*n_pos)))
-        return 1;
-      else
-        {
-          n_pos = needle;
-          while (*haystack && !grub_iswordseparator (*haystack))
-            haystack++;
-          while (grub_iswordseparator (*haystack))
-            haystack++;
-        }
-    }
-
-  return 0;
-}
-
-int
-grub_isspace (int c)
-{
-  return (c == '\n' || c == '\r' || c == ' ' || c == '\t');
-}
-
-int
-grub_isprint (int c)
-{
-  return (c >= ' ' && c <= '~');
-}
-
-
-unsigned long
-grub_strtoul (const char *str, char **end, int base)
-{
-  unsigned long long num;
-
-  num = grub_strtoull (str, end, base);
-  if (num > ~0UL)
-    {
-      grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
-      return ~0UL;
-    }
-
-  return (unsigned long) num;
-}
-
-unsigned long long
-grub_strtoull (const char *str, char **end, int base)
-{
-  unsigned long long num = 0;
-  int found = 0;
-
-  /* Skip white spaces.  */
-  while (*str && grub_isspace (*str))
-    str++;
-
-  /* Guess the base, if not specified. The prefix `0x' means 16, and
-     the prefix `0' means 8.  */
-  if (str[0] == '0')
-    {
-      if (str[1] == 'x')
-       {
-         if (base == 0 || base == 16)
-           {
-             base = 16;
-             str += 2;
-           }
-       }
-      else if (base == 0 && str[1] >= '0' && str[1] <= '7')
-       base = 8;
-    }
-
-  if (base == 0)
-    base = 10;
-
-  while (*str)
-    {
-      unsigned long digit;
-
-      digit = grub_tolower (*str) - '0';
-      if (digit > 9)
-       {
-         digit += '0' - 'a' + 10;
-         if (digit >= (unsigned long) base)
-           break;
-       }
-
-      found = 1;
-
-      /* NUM * BASE + DIGIT > ~0ULL */
-      if (num > grub_divmod64 (~0ULL - digit, base, 0))
-       {
-         grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
-         return ~0ULL;
-       }
-
-      num = num * base + digit;
-      str++;
-    }
-
-  if (! found)
-    {
-      grub_error (GRUB_ERR_BAD_NUMBER, "unrecognized number");
-      return 0;
-    }
-
-  if (end)
-    *end = (char *) str;
-
-  return num;
-}
-
-char *
-grub_strdup (const char *s)
-{
-  grub_size_t len;
-  char *p;
-
-  len = grub_strlen (s) + 1;
-  p = (char *) grub_malloc (len);
-  if (! p)
-    return 0;
-
-  return grub_memcpy (p, s, len);
-}
-
-char *
-grub_strndup (const char *s, grub_size_t n)
-{
-  grub_size_t len;
-  char *p;
-
-  len = grub_strlen (s);
-  if (len > n)
-    len = n;
-  p = (char *) grub_malloc (len + 1);
-  if (! p)
-    return 0;
-
-  grub_memcpy (p, s, len);
-  p[len] = '\0';
-  return p;
-}
-
-void *
-grub_memset (void *s, int c, grub_size_t n)
-{
-  unsigned char *p = (unsigned char *) s;
-
-  while (n--)
-    *p++ = (unsigned char) c;
-
-  return s;
-}
-#ifndef APPLE_CC
-void *memset (void *s, int c, grub_size_t n)
-  __attribute__ ((alias ("grub_memset")));
-#else
-void *memset (void *s, int c, grub_size_t n)
-{
-  return grub_memset (s, c, n);
-}
-#endif
-
-grub_size_t
-grub_strlen (const char *s)
-{
-  const char *p = s;
-
-  while (*p)
-    p++;
-
-  return p - s;
-}
-
-static inline void
-grub_reverse (char *str)
-{
-  char *p = str + grub_strlen (str) - 1;
-
-  while (str < p)
-    {
-      char tmp;
-
-      tmp = *str;
-      *str = *p;
-      *p = tmp;
-      str++;
-      p--;
-    }
-}
-
-/* Divide N by D, return the quotient, and store the remainder in *R.  */
-grub_uint64_t
-grub_divmod64 (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r)
-{
-  /* This algorithm is typically implemented by hardware. The idea
-     is to get the highest bit in N, 64 times, by keeping
-     upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
-     represents the high 64 bits in 128-bits space.  */
-  unsigned bits = 64;
-  unsigned long long q = 0;
-  unsigned m = 0;
-
-  /* Skip the slow computation if 32-bit arithmetic is possible.  */
-  if (n < 0xffffffff)
-    {
-      if (r)
-       *r = ((grub_uint32_t) n) % d;
-
-      return ((grub_uint32_t) n) / d;
-    }
-
-  while (bits--)
-    {
-      m <<= 1;
-
-      if (n & (1ULL << 63))
-       m |= 1;
-
-      q <<= 1;
-      n <<= 1;
-
-      if (m >= d)
-       {
-         q |= 1;
-         m -= d;
-       }
-    }
-
-  if (r)
-    *r = m;
-
-  return q;
-}
-
-/* Convert a long long value to a string. This function avoids 64-bit
-   modular arithmetic or divisions.  */
-static char *
-grub_lltoa (char *str, int c, unsigned long long n)
-{
-  unsigned base = (c == 'x') ? 16 : 10;
-  char *p;
-
-  if ((long long) n < 0 && c == 'd')
-    {
-      n = (unsigned long long) (-((long long) n));
-      *str++ = '-';
-    }
-
-  p = str;
-
-  if (base == 16)
-    do
-      {
-       unsigned d = (unsigned) (n & 0xf);
-       *p++ = (d > 9) ? d + 'a' - 10 : d + '0';
-      }
-    while (n >>= 4);
-  else
-    /* BASE == 10 */
-    do
-      {
-       unsigned m;
-
-       n = grub_divmod64 (n, 10, &m);
-       *p++ = m + '0';
-      }
-    while (n);
-
-  *p = 0;
-
-  grub_reverse (str);
-  return p;
-}
-
-static int
-grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list args)
-{
-  char c;
-  grub_size_t count = 0;
-  auto void write_char (unsigned char ch);
-  auto void write_str (const char *s);
-  auto void write_fill (const char ch, int n);
-
-  void write_char (unsigned char ch)
-    {
-      if (str)
-       {
-         if (count < max_len)
-           *str++ = ch;
-       }
-      else
-       grub_putchar (ch);
-
-      count++;
-    }
-
-  void write_str (const char *s)
-    {
-      while (*s)
-       write_char (*s++);
-    }
-
-  void write_fill (const char ch, int n)
-    {
-      int i;
-      for (i = 0; i < n; i++)
-       write_char (ch);
-    }
-
-  while ((c = *fmt++) != 0)
-    {
-      if (c != '%')
-       write_char (c);
-      else
-       {
-         char tmp[32];
-         char *p;
-         unsigned int format1 = 0;
-         unsigned int format2 = ~ 0U;
-         char zerofill = ' ';
-         int rightfill = 0;
-         int n;
-         int longfmt = 0;
-         int longlongfmt = 0;
-         int unsig = 0;
-
-         if (*fmt && *fmt =='-')
-           {
-             rightfill = 1;
-             fmt++;
-           }
-
-         p = (char *) fmt;
-         /* Read formatting parameters.  */
-         while (*p && grub_isdigit (*p))
-           p++;
-
-         if (p > fmt)
-           {
-             char s[p - fmt + 1];
-             grub_strncpy (s, fmt, p - fmt);
-             s[p - fmt] = 0;
-             if (s[0] == '0')
-               zerofill = '0';
-             format1 = grub_strtoul (s, 0, 10);
-             fmt = p;
-           }
-
-         if (*p && *p == '.')
-           {
-             p++;
-             fmt++;
-             while (*p && grub_isdigit (*p))
-               p++;
-
-             if (p > fmt)
-               {
-                 char fstr[p - fmt + 1];
-                 grub_strncpy (fstr, fmt, p - fmt);
-                 fstr[p - fmt] = 0;
-                 format2 = grub_strtoul (fstr, 0, 10);
-                 fmt = p;
-               }
-           }
-
-         c = *fmt++;
-         if (c == 'l')
-           {
-             longfmt = 1;
-             c = *fmt++;
-             if (c == 'l')
-               {
-                 longlongfmt = 1;
-                 c = *fmt++;
-               }
-           }
-
-         switch (c)
-           {
-           case 'p':
-             write_str ("0x");
-             c = 'x';
-             longlongfmt |= (sizeof (void *) == sizeof (long long));
-             /* Fall through. */
-           case 'x':
-           case 'u':
-             unsig = 1;
-             /* Fall through. */
-           case 'd':
-             if (longlongfmt)
-               {
-                 long long ll;
-
-                 ll = va_arg (args, long long);
-                 grub_lltoa (tmp, c, ll);
-               }
-             else if (longfmt && unsig)
-               {
-                 unsigned long l = va_arg (args, unsigned long);
-                 grub_lltoa (tmp, c, l);
-               }
-             else if (longfmt)
-               {
-                 long l = va_arg (args, long);
-                 grub_lltoa (tmp, c, l);
-               }
-             else if (unsig)
-               {
-                 unsigned u = va_arg (args, unsigned);
-                 grub_lltoa (tmp, c, u);
-               }
-             else
-               {
-                 n = va_arg (args, int);
-                 grub_lltoa (tmp, c, n);
-               }
-             if (! rightfill && grub_strlen (tmp) < format1)
-               write_fill (zerofill, format1 - grub_strlen (tmp));
-             write_str (tmp);
-             if (rightfill && grub_strlen (tmp) < format1)
-               write_fill (zerofill, format1 - grub_strlen (tmp));
-             break;
-
-           case 'c':
-             n = va_arg (args, int);
-             write_char (n & 0xff);
-             break;
-
-           case 'C':
-             {
-               grub_uint32_t code = va_arg (args, grub_uint32_t);
-               int shift;
-               unsigned mask;
-
-               if (code <= 0x7f)
-                 {
-                   shift = 0;
-                   mask = 0;
-                 }
-               else if (code <= 0x7ff)
-                 {
-                   shift = 6;
-                   mask = 0xc0;
-                 }
-               else if (code <= 0xffff)
-                 {
-                   shift = 12;
-                   mask = 0xe0;
-                 }
-               else if (code <= 0x1fffff)
-                 {
-                   shift = 18;
-                   mask = 0xf0;
-                 }
-               else if (code <= 0x3ffffff)
-                 {
-                   shift = 24;
-                   mask = 0xf8;
-                 }
-               else if (code <= 0x7fffffff)
-                 {
-                   shift = 30;
-                   mask = 0xfc;
-                 }
-               else
-                 {
-                   code = '?';
-                   shift = 0;
-                   mask = 0;
-                 }
-
-               write_char (mask | (code >> shift));
-
-               for (shift -= 6; shift >= 0; shift -= 6)
-                 write_char (0x80 | (0x3f & (code >> shift)));
-             }
-             break;
-
-           case 's':
-             p = va_arg (args, char *);
-             if (p)
-               {
-                 grub_size_t len = 0;
-                 while (len < format2 && p[len])
-                   len++;
-
-                 if (!rightfill && len < format1)
-                   write_fill (zerofill, format1 - len);
-
-                 grub_size_t i;
-                 for (i = 0; i < len; i++)
-                   write_char (*p++);
-
-                 if (rightfill && len < format1)
-                   write_fill (zerofill, format1 - len);
-               }
-             else
-               write_str ("(null)");
-
-             break;
-
-           default:
-             write_char (c);
-             break;
-           }
-       }
-    }
-
-  if (str)
-    *str = '\0';
-
-  return count;
-}
-
-int
-grub_vsnprintf (char *str, grub_size_t n, const char *fmt, va_list ap)
-{
-  grub_size_t ret;
-
-  if (!n)
-    return 0;
-
-  n--;
-
-  ret = grub_vsnprintf_real (str, n, fmt, ap);
-
-  return ret < n ? ret : n;
-}
-
-int
-grub_snprintf (char *str, grub_size_t n, const char *fmt, ...)
-{
-  va_list ap;
-  int ret;
-
-  va_start (ap, fmt);
-  ret = grub_vsnprintf (str, n, fmt, ap);
-  va_end (ap);
-
-  return ret;
-}
-
-#define PREALLOC_SIZE 255
-
-char *
-grub_xvasprintf (const char *fmt, va_list ap)
-{
-  grub_size_t s, as = PREALLOC_SIZE;
-  char *ret;
-
-  while (1)
-    {
-      ret = grub_malloc (as + 1);
-      if (!ret)
-       return NULL;
-
-      s = grub_vsnprintf_real (ret, as, fmt, ap);
-      if (s <= as)
-       return ret;
-
-      grub_free (ret);
-      as = s;
-    }
-}
-
-char *
-grub_xasprintf (const char *fmt, ...)
-{
-  va_list ap;
-  char *ret;
-
-  va_start (ap, fmt);
-  ret = grub_xvasprintf (fmt, ap);
-  va_end (ap);
-
-  return ret;
-}
-
-/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
-   bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string.
-   Return the number of characters converted. DEST must be able to hold
-   at least DESTSIZE characters.
-   If SRCEND is not NULL, then *SRCEND is set to the next byte after the
-   last byte used in SRC.  */
-grub_size_t
-grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
-                  const grub_uint8_t *src, grub_size_t srcsize,
-                  const grub_uint8_t **srcend)
-{
-  grub_uint32_t *p = dest;
-  int count = 0;
-  grub_uint32_t code = 0;
-
-  if (srcend)
-    *srcend = src;
-
-  while (srcsize && destsize)
-    {
-      grub_uint32_t c = *src++;
-      if (srcsize != (grub_size_t)-1)
-       srcsize--;
-      if (count)
-       {
-         if ((c & 0xc0) != 0x80)
-           {
-             /* invalid */
-             code = '?';
-             /* Character c may be valid, don't eat it.  */
-             src--;
-             if (srcsize != (grub_size_t)-1)
-               srcsize++;
-             count = 0;
-           }
-         else
-           {
-             code <<= 6;
-             code |= (c & 0x3f);
-             count--;
-           }
-       }
-      else
-       {
-         if (c == 0)
-           break;
-
-         if ((c & 0x80) == 0x00)
-           code = c;
-         else if ((c & 0xe0) == 0xc0)
-           {
-             count = 1;
-             code = c & 0x1f;
-           }
-         else if ((c & 0xf0) == 0xe0)
-           {
-             count = 2;
-             code = c & 0x0f;
-           }
-         else if ((c & 0xf8) == 0xf0)
-           {
-             count = 3;
-             code = c & 0x07;
-           }
-         else if ((c & 0xfc) == 0xf8)
-           {
-             count = 4;
-             code = c & 0x03;
-           }
-         else if ((c & 0xfe) == 0xfc)
-           {
-             count = 5;
-             code = c & 0x01;
-           }
-         else
-           {
-             /* invalid */
-             code = '?';
-             count = 0;
-           }
-       }
-
-      if (count == 0)
-       {
-         *p++ = code;
-         destsize--;
-       }
-    }
-
-  if (srcend)
-    *srcend = src;
-  return p - dest;
-}
-
-/* Abort GRUB. This function does not return.  */
-void
-grub_abort (void)
-{
-  grub_printf ("\nAborted.");
-  
-#ifndef GRUB_UTIL
-  if (grub_term_inputs)
-#endif
-    {
-      grub_printf (" Press any key to exit.");
-      grub_getkey ();
-    }
-
-  grub_exit ();
-}
-
-#ifndef APPLE_CC
-/* GCC emits references to abort().  */
-void abort (void) __attribute__ ((alias ("grub_abort")));
-#endif
-
-#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL)
-/* Some gcc versions generate a call to this function
-   in trampolines for nested functions.  */
-void __enable_execute_stack (void *addr __attribute__ ((unused)))
-{
-}
-#endif
-
-#if defined (NEED_REGISTER_FRAME_INFO) && !defined(GRUB_UTIL)
-void __register_frame_info (void)
-{
-}
-
-void __deregister_frame_info (void)
-{
-}
-#endif
diff --git a/kern/mm.c b/kern/mm.c
deleted file mode 100644 (file)
index 47324a6..0000000
--- a/kern/mm.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/* mm.c - functions for memory manager */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
-  The design of this memory manager.
-
-  This is a simple implementation of malloc with a few extensions. These are
-  the extensions:
-
-  - memalign is implemented efficiently.
-
-  - multiple regions may be used as free space. They may not be
-  contiguous.
-
-  Regions are managed by a singly linked list, and the meta information is
-  stored in the beginning of each region. Space after the meta information
-  is used to allocate memory.
-
-  The memory space is used as cells instead of bytes for simplicity. This
-  is important for some CPUs which may not access multiple bytes at a time
-  when the first byte is not aligned at a certain boundary (typically,
-  4-byte or 8-byte). The size of each cell is equal to the size of struct
-  grub_mm_header, so the header of each allocated/free block fits into one
-  cell precisely. One cell is 16 bytes on 32-bit platforms and 32 bytes
-  on 64-bit platforms.
-
-  There are two types of blocks: allocated blocks and free blocks.
-
-  In allocated blocks, the header of each block has only its size. Note that
-  this size is based on cells but not on bytes. The header is located right
-  before the returned pointer, that is, the header resides at the previous
-  cell.
-
-  Free blocks constitutes a ring, using a singly linked list. The first free
-  block is pointed to by the meta information of a region. The allocator
-  attempts to pick up the second block instead of the first one. This is
-  a typical optimization against defragmentation, and makes the
-  implementation a bit easier.
-
-  For safety, both allocated blocks and free ones are marked by magic
-  numbers. Whenever anything unexpected is detected, GRUB aborts the
-  operation.
- */
-
-#include <config.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/disk.h>
-#include <grub/dl.h>
-
-#ifdef MM_DEBUG
-# undef grub_malloc
-# undef grub_zalloc
-# undef grub_realloc
-# undef grub_free
-# undef grub_memalign
-#endif
-
-/* Magic words.  */
-#define GRUB_MM_FREE_MAGIC     0x2d3c2808
-#define GRUB_MM_ALLOC_MAGIC    0x6db08fa4
-
-typedef struct grub_mm_header
-{
-  struct grub_mm_header *next;
-  grub_size_t size;
-  grub_size_t magic;
-#if GRUB_CPU_SIZEOF_VOID_P == 4
-  char padding[4];
-#elif GRUB_CPU_SIZEOF_VOID_P == 8
-  char padding[8];
-#else
-# error "unknown word size"
-#endif
-}
-*grub_mm_header_t;
-
-#if GRUB_CPU_SIZEOF_VOID_P == 4
-# define GRUB_MM_ALIGN_LOG2    4
-#elif GRUB_CPU_SIZEOF_VOID_P == 8
-# define GRUB_MM_ALIGN_LOG2    5
-#endif
-
-#define GRUB_MM_ALIGN  (1 << GRUB_MM_ALIGN_LOG2)
-
-typedef struct grub_mm_region
-{
-  struct grub_mm_header *first;
-  struct grub_mm_region *next;
-  grub_addr_t addr;
-  grub_size_t size;
-}
-*grub_mm_region_t;
-
-\f
-
-static grub_mm_region_t base;
-
-/* Get a header from the pointer PTR, and set *P and *R to a pointer
-   to the header and a pointer to its region, respectively. PTR must
-   be allocated.  */
-static void
-get_header_from_pointer (void *ptr, grub_mm_header_t *p, grub_mm_region_t *r)
-{
-  if ((grub_addr_t) ptr & (GRUB_MM_ALIGN - 1))
-    grub_fatal ("unaligned pointer %p", ptr);
-
-  for (*r = base; *r; *r = (*r)->next)
-    if ((grub_addr_t) ptr > (*r)->addr
-       && (grub_addr_t) ptr <= (*r)->addr + (*r)->size)
-      break;
-
-  if (! *r)
-    grub_fatal ("out of range pointer %p", ptr);
-
-  *p = (grub_mm_header_t) ptr - 1;
-  if ((*p)->magic != GRUB_MM_ALLOC_MAGIC)
-    grub_fatal ("alloc magic is broken at %p", *p);
-}
-
-/* Initialize a region starting from ADDR and whose size is SIZE,
-   to use it as free space.  */
-void
-grub_mm_init_region (void *addr, grub_size_t size)
-{
-  grub_mm_header_t h;
-  grub_mm_region_t r, *p, q;
-
-#if 0
-  grub_printf ("Using memory for heap: start=%p, end=%p\n", addr, addr + (unsigned int) size);
-#endif
-
-  /* Allocate a region from the head.  */
-  r = (grub_mm_region_t) ALIGN_UP ((grub_addr_t) addr, GRUB_MM_ALIGN);
-  size -= (char *) r - (char *) addr + sizeof (*r);
-
-  /* If this region is too small, ignore it.  */
-  if (size < GRUB_MM_ALIGN)
-    return;
-
-  h = (grub_mm_header_t) ((char *) r + GRUB_MM_ALIGN);
-  h->next = h;
-  h->magic = GRUB_MM_FREE_MAGIC;
-  h->size = (size >> GRUB_MM_ALIGN_LOG2);
-
-  r->first = h;
-  r->addr = (grub_addr_t) h;
-  r->size = (h->size << GRUB_MM_ALIGN_LOG2);
-
-  /* Find where to insert this region. Put a smaller one before bigger ones,
-     to prevent fragmentation.  */
-  for (p = &base, q = *p; q; p = &(q->next), q = *p)
-    if (q->size > r->size)
-      break;
-
-  *p = r;
-  r->next = q;
-}
-
-/* Allocate the number of units N with the alignment ALIGN from the ring
-   buffer starting from *FIRST.  ALIGN must be a power of two. Both N and
-   ALIGN are in units of GRUB_MM_ALIGN.  Return a non-NULL if successful,
-   otherwise return NULL.  */
-static void *
-grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align)
-{
-  grub_mm_header_t p, q;
-
-  /* When everything is allocated side effect is that *first will have alloc
-     magic marked, meaning that there is no room in this region.  */
-  if ((*first)->magic == GRUB_MM_ALLOC_MAGIC)
-    return 0;
-
-  /* Try to search free slot for allocation in this memory region.  */
-  for (q = *first, p = q->next; ; q = p, p = p->next)
-    {
-      grub_off_t extra;
-
-      extra = ((grub_addr_t) (p + 1) >> GRUB_MM_ALIGN_LOG2) % align;
-      if (extra)
-       extra = align - extra;
-
-      if (! p)
-       grub_fatal ("null in the ring");
-
-      if (p->magic != GRUB_MM_FREE_MAGIC)
-       grub_fatal ("free magic is broken at %p: 0x%x", p, p->magic);
-
-      if (p->size >= n + extra)
-       {
-         if (extra == 0 && p->size == n)
-           {
-             /* There is no special alignment requirement and memory block
-                is complete match.
-
-                1. Just mark memory block as allocated and remove it from
-                   free list.
-
-                Result:
-                +---------------+ previous block's next
-                | alloc, size=n |          |
-                +---------------+          v
-              */
-             q->next = p->next;
-           }
-         else if (align == 1 || p->size == n + extra)
-           {
-             /* There might be alignment requirement, when taking it into
-                account memory block fits in.
-
-                1. Allocate new area at end of memory block.
-                2. Reduce size of available blocks from original node.
-                3. Mark new area as allocated and "remove" it from free
-                   list.
-
-                Result:
-                +---------------+
-                | free, size-=n | next --+
-                +---------------+        |
-                | alloc, size=n |        |
-                +---------------+        v
-              */
-
-             p->size -= n;
-             p += p->size;
-           }
-         else if (extra == 0)
-           {
-             grub_mm_header_t r;
-             
-             r = p + extra + n;
-             r->magic = GRUB_MM_FREE_MAGIC;
-             r->size = p->size - extra - n;
-             r->next = p->next;
-             q->next = r;
-
-             if (q == p)
-               {
-                 q = r;
-                 r->next = r;
-               }
-           }
-         else
-           {
-             /* There is alignment requirement and there is room in memory
-                block.  Split memory block to three pieces.
-
-                1. Create new memory block right after section being
-                   allocated.  Mark it as free.
-                2. Add new memory block to free chain.
-                3. Mark current memory block having only extra blocks.
-                4. Advance to aligned block and mark that as allocated and
-                   "remove" it from free list.
-
-                Result:
-                +------------------------------+
-                | free, size=extra             | next --+
-                +------------------------------+        |
-                | alloc, size=n                |        |
-                +------------------------------+        |
-                | free, size=orig.size-extra-n | <------+, next --+
-                +------------------------------+                  v
-              */
-             grub_mm_header_t r;
-
-             r = p + extra + n;
-             r->magic = GRUB_MM_FREE_MAGIC;
-             r->size = p->size - extra - n;
-             r->next = p->next;
-
-             p->size = extra;
-             p->next = r;
-             p += extra;
-           }
-
-         p->magic = GRUB_MM_ALLOC_MAGIC;
-         p->size = n;
-
-         /* Mark find as a start marker for next allocation to fasten it.
-            This will have side effect of fragmenting memory as small
-            pieces before this will be un-used.  */
-         *first = q;
-
-         return p + 1;
-       }
-
-      /* Search was completed without result.  */
-      if (p == *first)
-       break;
-    }
-
-  return 0;
-}
-
-/* Allocate SIZE bytes with the alignment ALIGN and return the pointer.  */
-void *
-grub_memalign (grub_size_t align, grub_size_t size)
-{
-  grub_mm_region_t r;
-  grub_size_t n = ((size + GRUB_MM_ALIGN - 1) >> GRUB_MM_ALIGN_LOG2) + 1;
-  int count = 0;
-
-  align = (align >> GRUB_MM_ALIGN_LOG2);
-  if (align == 0)
-    align = 1;
-
- again:
-
-  for (r = base; r; r = r->next)
-    {
-      void *p;
-
-      p = grub_real_malloc (&(r->first), n, align);
-      if (p)
-       return p;
-    }
-
-  /* If failed, increase free memory somehow.  */
-  switch (count)
-    {
-    case 0:
-      /* Invalidate disk caches.  */
-      grub_disk_cache_invalidate_all ();
-      count++;
-      goto again;
-
-    case 1:
-      /* Unload unneeded modules.  */
-      grub_dl_unload_unneeded ();
-      count++;
-      goto again;
-
-    default:
-      break;
-    }
-
-  grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
-  return 0;
-}
-
-/* Allocate SIZE bytes and return the pointer.  */
-void *
-grub_malloc (grub_size_t size)
-{
-  return grub_memalign (0, size);
-}
-
-/* Allocate SIZE bytes, clear them and return the pointer.  */
-void *
-grub_zalloc (grub_size_t size)
-{
-  void *ret;
-
-  ret = grub_memalign (0, size);
-  if (ret)
-    grub_memset (ret, 0, size);
-
-  return ret;
-}
-
-/* Deallocate the pointer PTR.  */
-void
-grub_free (void *ptr)
-{
-  grub_mm_header_t p;
-  grub_mm_region_t r;
-
-  if (! ptr)
-    return;
-
-  get_header_from_pointer (ptr, &p, &r);
-
-  if (r->first->magic == GRUB_MM_ALLOC_MAGIC)
-    {
-      p->magic = GRUB_MM_FREE_MAGIC;
-      r->first = p->next = p;
-    }
-  else
-    {
-      grub_mm_header_t q;
-
-#if 0
-      q = r->first;
-      do
-       {
-         grub_printf ("%s:%d: q=%p, q->size=0x%x, q->magic=0x%x\n",
-                      GRUB_FILE, __LINE__, q, q->size, q->magic);
-         q = q->next;
-       }
-      while (q != r->first);
-#endif
-
-      for (q = r->first; q >= p || q->next <= p; q = q->next)
-       {
-         if (q->magic != GRUB_MM_FREE_MAGIC)
-           grub_fatal ("free magic is broken at %p: 0x%x", q, q->magic);
-
-         if (q >= q->next && (q < p || q->next > p))
-           break;
-       }
-
-      p->magic = GRUB_MM_FREE_MAGIC;
-      p->next = q->next;
-      q->next = p;
-
-      if (p + p->size == p->next)
-       {
-         if (p->next == q)
-           q = p;
-
-         p->next->magic = 0;
-         p->size += p->next->size;
-         p->next = p->next->next;
-       }
-
-      if (q + q->size == p)
-       {
-         p->magic = 0;
-         q->size += p->size;
-         q->next = p->next;
-       }
-
-      r->first = q;
-    }
-}
-
-/* Reallocate SIZE bytes and return the pointer. The contents will be
-   the same as that of PTR.  */
-void *
-grub_realloc (void *ptr, grub_size_t size)
-{
-  grub_mm_header_t p;
-  grub_mm_region_t r;
-  void *q;
-  grub_size_t n;
-
-  if (! ptr)
-    return grub_malloc (size);
-
-  if (! size)
-    {
-      grub_free (ptr);
-      return 0;
-    }
-
-  /* FIXME: Not optimal.  */
-  n = ((size + GRUB_MM_ALIGN - 1) >> GRUB_MM_ALIGN_LOG2) + 1;
-  get_header_from_pointer (ptr, &p, &r);
-
-  if (p->size >= n)
-    return ptr;
-
-  q = grub_malloc (size);
-  if (! q)
-    return q;
-
-  grub_memcpy (q, ptr, size);
-  grub_free (ptr);
-  return q;
-}
-
-#ifdef MM_DEBUG
-int grub_mm_debug = 0;
-
-void
-grub_mm_dump_free (void)
-{
-  grub_mm_region_t r;
-
-  for (r = base; r; r = r->next)
-    {
-      grub_mm_header_t p;
-
-      /* Follow the free list.  */
-      p = r->first;
-      do
-       {
-         if (p->magic != GRUB_MM_FREE_MAGIC)
-           grub_fatal ("free magic is broken at %p: 0x%x", p, p->magic);
-
-         grub_printf ("F:%p:%u:%p\n",
-                      p, (unsigned int) p->size << GRUB_MM_ALIGN_LOG2, p->next);
-         p = p->next;
-       }
-      while (p != r->first);
-    }
-
-  grub_printf ("\n");
-}
-
-void
-grub_mm_dump (unsigned lineno)
-{
-  grub_mm_region_t r;
-
-  grub_printf ("called at line %u\n", lineno);
-  for (r = base; r; r = r->next)
-    {
-      grub_mm_header_t p;
-
-      for (p = (grub_mm_header_t) ((r->addr + GRUB_MM_ALIGN - 1)
-                                  & (~(GRUB_MM_ALIGN - 1)));
-          (grub_addr_t) p < r->addr + r->size;
-          p++)
-       {
-         switch (p->magic)
-           {
-           case GRUB_MM_FREE_MAGIC:
-             grub_printf ("F:%p:%u:%p\n",
-                          p, (unsigned int) p->size << GRUB_MM_ALIGN_LOG2, p->next);
-             break;
-           case GRUB_MM_ALLOC_MAGIC:
-             grub_printf ("A:%p:%u\n", p, (unsigned int) p->size << GRUB_MM_ALIGN_LOG2);
-             break;
-           }
-       }
-    }
-
-  grub_printf ("\n");
-}
-
-void *
-grub_debug_malloc (const char *file, int line, grub_size_t size)
-{
-  void *ptr;
-
-  if (grub_mm_debug)
-    grub_printf ("%s:%d: malloc (0x%zx) = ", file, line, size);
-  ptr = grub_malloc (size);
-  if (grub_mm_debug)
-    grub_printf ("%p\n", ptr);
-  return ptr;
-}
-
-void *
-grub_debug_zalloc (const char *file, int line, grub_size_t size)
-{
-  void *ptr;
-
-  if (grub_mm_debug)
-    grub_printf ("%s:%d: zalloc (0x%zx) = ", file, line, size);
-  ptr = grub_zalloc (size);
-  if (grub_mm_debug)
-    grub_printf ("%p\n", ptr);
-  return ptr;
-}
-
-void
-grub_debug_free (const char *file, int line, void *ptr)
-{
-  if (grub_mm_debug)
-    grub_printf ("%s:%d: free (%p)\n", file, line, ptr);
-  grub_free (ptr);
-}
-
-void *
-grub_debug_realloc (const char *file, int line, void *ptr, grub_size_t size)
-{
-  if (grub_mm_debug)
-    grub_printf ("%s:%d: realloc (%p, 0x%zx) = ", file, line, ptr, size);
-  ptr = grub_realloc (ptr, size);
-  if (grub_mm_debug)
-    grub_printf ("%p\n", ptr);
-  return ptr;
-}
-
-void *
-grub_debug_memalign (const char *file, int line, grub_size_t align,
-                   grub_size_t size)
-{
-  void *ptr;
-
-  if (grub_mm_debug)
-    grub_printf ("%s:%d: memalign (0x%zx, 0x%zx) = ",
-                file, line, align, size);
-  ptr = grub_memalign (align, size);
-  if (grub_mm_debug)
-    grub_printf ("%p\n", ptr);
-  return ptr;
-}
-
-#endif /* MM_DEBUG */
diff --git a/kern/parser.c b/kern/parser.c
deleted file mode 100644 (file)
index 07597a1..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-/* parser.c - the part of the parser that can return partial tokens */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/parser.h>
-#include <grub/env.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-
-
-/* All the possible state transitions on the command line.  If a
-   transition can not be found, it is assumed that there is no
-   transition and keep_value is assumed to be 1.  */
-static struct grub_parser_state_transition state_transitions[] = {
-  {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_QUOTE, '\'', 0},
-  {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_DQUOTE, '\"', 0},
-  {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_VAR, '$', 0},
-  {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_ESC, '\\', 0},
-
-  {GRUB_PARSER_STATE_ESC, GRUB_PARSER_STATE_TEXT, 0, 1},
-
-  {GRUB_PARSER_STATE_QUOTE, GRUB_PARSER_STATE_TEXT, '\'', 0},
-
-  {GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_TEXT, '\"', 0},
-  {GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_QVAR, '$', 0},
-
-  {GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME2, '{', 0},
-  {GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME, 0, 1},
-  {GRUB_PARSER_STATE_VARNAME, GRUB_PARSER_STATE_TEXT, ' ', 1},
-  {GRUB_PARSER_STATE_VARNAME2, GRUB_PARSER_STATE_TEXT, '}', 0},
-
-  {GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME2, '{', 0},
-  {GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME, 0, 1},
-  {GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_TEXT, '\"', 0},
-  {GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_DQUOTE, ' ', 1},
-  {GRUB_PARSER_STATE_QVARNAME2, GRUB_PARSER_STATE_DQUOTE, '}', 0},
-
-  {0, 0, 0, 0}
-};
-
-
-/* Determines the state following STATE, determined by C.  */
-grub_parser_state_t
-grub_parser_cmdline_state (grub_parser_state_t state, char c, char *result)
-{
-  struct grub_parser_state_transition *transition;
-  struct grub_parser_state_transition default_transition;
-
-  default_transition.to_state = state;
-  default_transition.keep_value = 1;
-
-  /* Look for a good translation.  */
-  for (transition = state_transitions; transition->from_state; transition++)
-    {
-      if (transition->from_state != state)
-       continue;
-      /* An exact match was found, use it.  */
-      if (transition->input == c)
-       break;
-
-      if (transition->input == ' ' && !grub_isalpha (c)
-         && !grub_isdigit (c) && c != '_')
-       break;
-
-      /* A less perfect match was found, use this one if no exact
-         match can be found.  */
-      if (transition->input == 0)
-       break;
-    }
-
-  if (!transition->from_state)
-    transition = &default_transition;
-
-  if (transition->keep_value)
-    *result = c;
-  else
-    *result = 0;
-  return transition->to_state;
-}
-
-
-grub_err_t
-grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline,
-                          int *argc, char ***argv)
-{
-  grub_parser_state_t state = GRUB_PARSER_STATE_TEXT;
-  /* XXX: Fixed size buffer, perhaps this buffer should be dynamically
-     allocated.  */
-  char buffer[1024];
-  char *bp = buffer;
-  char *rd = (char *) cmdline;
-  char varname[200];
-  char *vp = varname;
-  char *args;
-  int i;
-
-  auto int check_varstate (grub_parser_state_t s);
-
-  int check_varstate (grub_parser_state_t s)
-  {
-    return (s == GRUB_PARSER_STATE_VARNAME
-           || s == GRUB_PARSER_STATE_VARNAME2
-           || s == GRUB_PARSER_STATE_QVARNAME
-           || s == GRUB_PARSER_STATE_QVARNAME2);
-  }
-
-  auto void add_var (grub_parser_state_t newstate);
-
-  void add_var (grub_parser_state_t newstate)
-  {
-    char *val;
-
-    /* Check if a variable was being read in and the end of the name
-       was reached.  */
-    if (!(check_varstate (state) && !check_varstate (newstate)))
-      return;
-
-    *(vp++) = '\0';
-    val = grub_env_get (varname);
-    vp = varname;
-    if (!val)
-      return;
-
-    /* Insert the contents of the variable in the buffer.  */
-    for (; *val; val++)
-      *(bp++) = *val;
-  }
-
-  *argc = 0;
-  do
-    {
-      if (!rd || !*rd)
-       {
-         if (getline)
-           getline (&rd, 1);
-         else
-           break;
-       }
-
-      if (!rd)
-       break;
-
-      for (; *rd; rd++)
-       {
-         grub_parser_state_t newstate;
-         char use;
-
-         newstate = grub_parser_cmdline_state (state, *rd, &use);
-
-         /* If a variable was being processed and this character does
-            not describe the variable anymore, write the variable to
-            the buffer.  */
-         add_var (newstate);
-
-         if (check_varstate (newstate))
-           {
-             if (use)
-               *(vp++) = use;
-           }
-         else
-           {
-             if (newstate == GRUB_PARSER_STATE_TEXT
-                 && state != GRUB_PARSER_STATE_ESC && use == ' ')
-               {
-                 /* Don't add more than one argument if multiple
-                    spaces are used.  */
-                 if (bp != buffer && *(bp - 1))
-                   {
-                     *(bp++) = '\0';
-                     (*argc)++;
-                   }
-               }
-             else if (use)
-               *(bp++) = use;
-           }
-         state = newstate;
-       }
-    }
-  while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state));
-
-  /* A special case for when the last character was part of a
-     variable.  */
-  add_var (GRUB_PARSER_STATE_TEXT);
-
-  if (bp != buffer && *(bp - 1))
-    {
-      *(bp++) = '\0';
-      (*argc)++;
-    }
-
-  /* Reserve memory for the return values.  */
-  args = grub_malloc (bp - buffer);
-  if (!args)
-    return grub_errno;
-  grub_memcpy (args, buffer, bp - buffer);
-
-  *argv = grub_malloc (sizeof (char *) * (*argc + 1));
-  if (!*argv)
-    {
-      grub_free (args);
-      return grub_errno;
-    }
-
-  /* The arguments are separated with 0's, setup argv so it points to
-     the right values.  */
-  bp = args;
-  for (i = 0; i < *argc; i++)
-    {
-      (*argv)[i] = bp;
-      while (*bp)
-       bp++;
-      bp++;
-    }
-
-  return 0;
-}
-
-struct grub_handler_class grub_parser_class = {
-  .name = "parser"
-};
-
-grub_err_t
-grub_parser_execute (char *source)
-{
-  auto grub_err_t getline (char **line, int cont);
-  grub_err_t getline (char **line, int cont __attribute__ ((unused)))
-  {
-    char *p;
-
-    if (!source)
-      {
-       *line = 0;
-       return 0;
-      }
-
-    p = grub_strchr (source, '\n');
-
-    if (p)
-      *line = grub_strndup (source, p - source);
-    else
-      *line = grub_strdup (source);
-    source = p ? p + 1 : 0;
-    return 0;
-  }
-
-  while (source)
-    {
-      char *line;
-      grub_parser_t parser;
-
-      getline (&line, 0);
-      parser = grub_parser_get_current ();
-      parser->parse_line (line, getline);
-      grub_free (line);
-    }
-
-  return grub_errno;
-}
diff --git a/kern/partition.c b/kern/partition.c
deleted file mode 100644 (file)
index 2a33ac3..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/partition.h>
-#include <grub/disk.h>
-
-grub_partition_map_t grub_partition_map_list;
-
-static grub_partition_t
-grub_partition_map_probe (const grub_partition_map_t partmap,
-                         grub_disk_t disk, int partnum)
-{
-  grub_partition_t p = 0;
-
-  auto int find_func (grub_disk_t d, const grub_partition_t partition);
-
-  int find_func (grub_disk_t d __attribute__ ((unused)),
-                const grub_partition_t partition)
-    {
-      if (partnum == partition->number)
-       {
-         p = (grub_partition_t) grub_malloc (sizeof (*p));
-         if (! p)
-           return 1;
-
-         grub_memcpy (p, partition, sizeof (*p));
-         return 1;
-       }
-
-      return 0;
-    }
-
-  partmap->iterate (disk, find_func);
-  if (grub_errno)
-    goto fail;
-
-  return p;
-
- fail:
-  grub_free (p);
-  return 0;
-}
-
-grub_partition_t
-grub_partition_probe (struct grub_disk *disk, const char *str)
-{
-  grub_partition_t part = 0;
-  grub_partition_t curpart = 0;
-  grub_partition_t tail;
-  const char *ptr;
-
-  part = tail = disk->partition;
-
-  for (ptr = str; *ptr;)
-    {
-      grub_partition_map_t partmap;
-      int num;
-      const char *partname, *partname_end;
-
-      partname = ptr;
-      while (*ptr && grub_isalpha (*ptr))
-       ptr++;
-      partname_end = ptr; 
-      num = grub_strtoul (ptr, (char **) &ptr, 0) - 1;
-
-      curpart = 0;
-      /* Use the first partition map type found.  */
-      FOR_PARTITION_MAPS(partmap)
-      {
-       if (partname_end != partname &&
-           (grub_strncmp (partmap->name, partname, partname_end - partname)
-            != 0 || partmap->name[partname_end - partname] != 0))
-         continue;
-
-       disk->partition = part;
-       curpart = grub_partition_map_probe (partmap, disk, num);
-       disk->partition = tail;
-       if (curpart)
-         break;
-
-       if (grub_errno == GRUB_ERR_BAD_PART_TABLE)
-         {
-           /* Continue to next partition map type.  */
-           grub_errno = GRUB_ERR_NONE;
-           continue;
-         }
-
-       break;
-      }
-
-      if (! curpart)
-       {
-         while (part)
-           {
-             curpart = part->parent;
-             grub_free (part);
-             part = curpart;
-           }
-         return 0;
-       }
-      curpart->parent = part;
-      part = curpart;
-      if (! ptr || *ptr != ',')
-       break;
-      ptr++;
-    }
-
-  return part;
-}
-
-int
-grub_partition_iterate (struct grub_disk *disk,
-                       int (*hook) (grub_disk_t disk,
-                                    const grub_partition_t partition))
-{
-  int ret = 0;
-
-  auto int part_iterate (grub_disk_t dsk, const grub_partition_t p);
-
-  int part_iterate (grub_disk_t dsk,
-                   const grub_partition_t partition)
-    {
-      struct grub_partition p = *partition;
-      p.parent = dsk->partition;
-      dsk->partition = 0;
-      if (hook (dsk, &p))
-       {
-         ret = 1;
-         return 1;
-       }
-      if (p.start != 0)
-       {
-         const struct grub_partition_map *partmap;
-         dsk->partition = &p;
-         FOR_PARTITION_MAPS(partmap)
-         {
-           grub_err_t err;
-           err = partmap->iterate (dsk, part_iterate);
-           if (err)
-             grub_errno = GRUB_ERR_NONE;
-           if (ret)
-             break;
-         }
-       }
-      dsk->partition = p.parent;
-      return ret;
-    }
-
-  {
-    const struct grub_partition_map *partmap;
-    FOR_PARTITION_MAPS(partmap)
-    {
-      grub_err_t err;
-      err = partmap->iterate (disk, part_iterate);
-      if (err)
-       grub_errno = GRUB_ERR_NONE;
-      if (ret)
-       break;
-    }
-  }
-
-  return ret;
-}
-
-char *
-grub_partition_get_name (const grub_partition_t partition)
-{
-  char *out = 0;
-  int curlen = 0;
-  grub_partition_t part;
-  for (part = partition; part; part = part->parent)
-    {
-      /* Even on 64-bit machines this buffer is enough to hold
-        longest number.  */
-      char buf[grub_strlen (part->partmap->name) + 25];
-      int strl;
-      grub_snprintf (buf, sizeof (buf), "%s%d", part->partmap->name,
-                    part->number + 1);
-      strl = grub_strlen (buf);
-      if (curlen)
-       {
-         out = grub_realloc (out, curlen + strl + 2);
-         grub_memcpy (out + strl + 1, out, curlen);
-         out[curlen + 1 + strl] = 0;
-         grub_memcpy (out, buf, strl);
-         out[strl] = ',';
-         curlen = curlen + 1 + strl;
-       }
-      else
-       {
-         curlen = strl;
-         out = grub_strdup (buf);
-       }
-    }
-  return out;
-}
diff --git a/kern/powerpc/cache.S b/kern/powerpc/cache.S
deleted file mode 100644 (file)
index da982af..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* cache.S - Flush the processor cache for a specific region.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define CACHE_LINE_BYTES 32
-
-       .text
-
-       .align 2
-       .globl grub_arch_sync_caches
-grub_arch_sync_caches:
-       /* `address' may not be CACHE_LINE_BYTES-aligned.  */
-       andi. 6, 3, CACHE_LINE_BYTES - 1 /* Find the misalignment.  */
-       add 4, 4, 6 /* Adjust `size' to compensate.  */
-
-       /* Force the dcache lines to memory.  */
-       li 5, 0
-1:     dcbst 5, 3
-       addi 5, 5, CACHE_LINE_BYTES
-       cmpw 5, 4
-       blt 1b
-       sync            /* Force all dcbsts to complete.  */
-
-       /* Invalidate the icache lines.  */
-       li 5, 0
-1:     icbi 5, 3
-       addi 5, 5, CACHE_LINE_BYTES
-       cmpw 5, 4
-       blt 1b
-       sync            /* Force all icbis to complete.  */
-       isync           /* Discard partially executed instructions that were
-                          loaded from the invalid icache.  */
-       blr
diff --git a/kern/powerpc/dl.c b/kern/powerpc/dl.c
deleted file mode 100644 (file)
index ad19e56..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/* dl.c - arch-dependent part of loadable module support */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/elf.h>
-#include <grub/misc.h>
-#include <grub/err.h>
-
-/* Check if EHDR is a valid ELF header.  */
-grub_err_t
-grub_arch_dl_check_header (void *ehdr)
-{
-  Elf_Ehdr *e = ehdr;
-
-  /* Check the magic numbers.  */
-  if (e->e_ident[EI_CLASS] != ELFCLASS32
-      || e->e_ident[EI_DATA] != ELFDATA2MSB
-      || e->e_machine != EM_PPC)
-    return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
-
-  return GRUB_ERR_NONE;
-}
-
-
-/* Relocate symbols.  */
-grub_err_t
-grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
-{
-  Elf_Ehdr *e = ehdr;
-  Elf_Shdr *s;
-  Elf_Word entsize;
-  unsigned i;
-
-  /* Find a symbol table.  */
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_SYMTAB)
-      break;
-
-  if (i == e->e_shnum)
-    return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
-
-  entsize = s->sh_entsize;
-
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_RELA)
-      {
-       grub_dl_segment_t seg;
-
-       /* Find the target segment.  */
-       for (seg = mod->segment; seg; seg = seg->next)
-         if (seg->section == s->sh_info)
-           break;
-
-       if (seg)
-         {
-           Elf_Rela *rel, *max;
-
-           for (rel = (Elf_Rela *) ((char *) e + s->sh_offset),
-                  max = rel + s->sh_size / s->sh_entsize;
-                rel < max;
-                rel++)
-             {
-               Elf_Word *addr;
-               Elf_Sym *sym;
-               grub_uint32_t value;
-
-               if (seg->size < rel->r_offset)
-                 return grub_error (GRUB_ERR_BAD_MODULE,
-                                    "reloc offset is out of the segment");
-
-               addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
-               sym = (Elf_Sym *) ((char *) mod->symtab
-                                    + entsize * ELF_R_SYM (rel->r_info));
-
-               /* On the PPC the value does not have an explicit
-                  addend, add it.  */
-               value = sym->st_value + rel->r_addend;
-               switch (ELF_R_TYPE (rel->r_info))
-                 {
-                 case R_PPC_ADDR16_LO:
-                   *(Elf_Half *) addr = value;
-                   break;
-
-                 case R_PPC_REL24:
-                   {
-                     Elf_Sword delta = value - (Elf_Word) addr;
-
-                     if (delta << 6 >> 6 != delta)
-                       return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow");
-                     *addr = (*addr & 0xfc000003) | (delta & 0x3fffffc);
-                     break;
-                   }
-
-                 case R_PPC_ADDR16_HA:
-                   *(Elf_Half *) addr = (value + 0x8000) >> 16;
-                   break;
-
-                 case R_PPC_ADDR32:
-                   *addr = value;
-                   break;
-
-                 case R_PPC_REL32:
-                   *addr = value - (Elf_Word) addr;
-                   break;
-
-                 default:
-                   return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                                      "this relocation (%d) is not implemented yet",
-                                      ELF_R_TYPE (rel->r_info));
-                 }
-             }
-         }
-      }
-
-  return GRUB_ERR_NONE;
-}
diff --git a/kern/powerpc/ieee1275/startup.S b/kern/powerpc/ieee1275/startup.S
deleted file mode 100644 (file)
index 75e1ed8..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* startup.S - Startup code for the PowerPC.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-#include <grub/cpu/kernel.h>
-
-.extern __bss_start
-.extern _end
-
-       .text
-       .align  2
-       .globl  start, _start
-start:
-_start:
-       b       codestart
-
-       . = _start + GRUB_KERNEL_CPU_PREFIX
-
-VARIABLE(grub_prefix)
-       /* to be filled by grub-mkelfimage */
-
-       /*
-        *  Leave some breathing room for the prefix.
-        */
-
-       . = _start + GRUB_KERNEL_CPU_DATA_END
-
-codestart:
-       li      2, 0
-       li      13, 0
-
-       /* Stage1 won't zero BSS for us. In other cases, why not do it again?  */
-       lis     6, (__bss_start - 4)@h
-       ori     6, 6, (__bss_start - 4)@l
-       lis     7, (_end - 4)@h
-       ori     7, 7, (_end - 4)@l
-       subf    7, 6, 7
-       srwi    7, 7, 2 /* We store 4 bytes at a time.  */
-       mtctr   7
-2:     stwu    2, 4(6) /* We know r2 is already 0 from above.  */
-       bdnz    2b
-
-       /* Store r5 in grub_ieee1275_entry_fn.  */
-       lis     9, grub_ieee1275_entry_fn@ha
-       stw     5, grub_ieee1275_entry_fn@l(9)
-
-       bl      grub_main
-1:     b       1b
diff --git a/kern/rescue_parser.c b/kern/rescue_parser.c
deleted file mode 100644 (file)
index d3725e7..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/* rescue_parser.c - rescue mode parser  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/mm.h>
-#include <grub/env.h>
-#include <grub/parser.h>
-#include <grub/misc.h>
-#include <grub/command.h>
-
-static grub_err_t
-grub_rescue_parse_line (char *line, grub_reader_getline_t getline)
-{
-  char *name;
-  int n;
-  grub_command_t cmd;
-  char **args;
-
-  if (grub_parser_split_cmdline (line, getline, &n, &args) || n < 0)
-    return grub_errno;
-
-  if (n == 0)
-    return GRUB_ERR_NONE;
-
-  /* In case of an assignment set the environment accordingly
-     instead of calling a function.  */
-  if (n == 1 && grub_strchr (line, '='))
-    {
-      char *val = grub_strchr (args[0], '=');
-      val[0] = 0;
-      grub_env_set (args[0], val + 1);
-      val[0] = '=';
-      goto quit;
-    }
-
-  /* Get the command name.  */
-  name = args[0];
-
-  /* If nothing is specified, restart.  */
-  if (*name == '\0')
-    goto quit;
-
-  cmd = grub_command_find (name);
-  if (cmd)
-    {
-      (cmd->func) (cmd, n - 1, &args[1]);
-    }
-  else
-    {
-      grub_printf ("Unknown command `%s'\n", name);
-      if (grub_command_find ("help"))
-       grub_printf ("Try `help' for usage\n");
-    }
-
- quit:
-  grub_free (args[0]);
-  grub_free (args);
-
-  return grub_errno;
-}
-
-static struct grub_parser grub_rescue_parser =
-  {
-    .name = "rescue",
-    .parse_line = grub_rescue_parse_line
-  };
-
-void
-grub_register_rescue_parser (void)
-{
-  grub_parser_register ("rescue", &grub_rescue_parser);
-}
diff --git a/kern/rescue_reader.c b/kern/rescue_reader.c
deleted file mode 100644 (file)
index f573cf4..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* rescue_reader.c - rescue mode reader  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/reader.h>
-#include <grub/parser.h>
-#include <grub/misc.h>
-#include <grub/term.h>
-#include <grub/mm.h>
-
-#define GRUB_RESCUE_BUF_SIZE   256
-
-static char linebuf[GRUB_RESCUE_BUF_SIZE];
-
-/* Prompt to input a command and read the line.  */
-static grub_err_t
-grub_rescue_read_line (char **line, int cont)
-{
-  int c;
-  int pos = 0;
-
-  grub_printf ((cont) ? "> " : "grub rescue> ");
-  grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE);
-
-  while ((c = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && c != '\r')
-    {
-      if (grub_isprint (c))
-       {
-         if (pos < GRUB_RESCUE_BUF_SIZE - 1)
-           {
-             linebuf[pos++] = c;
-             grub_putchar (c);
-           }
-       }
-      else if (c == '\b')
-       {
-         if (pos > 0)
-           {
-             linebuf[--pos] = 0;
-             grub_putchar (c);
-             grub_putchar (' ');
-             grub_putchar (c);
-           }
-       }
-      grub_refresh ();
-    }
-
-  grub_putchar ('\n');
-  grub_refresh ();
-
-  *line = grub_strdup (linebuf);
-
-  return 0;
-}
-
-void
-grub_rescue_run (void)
-{
-  grub_printf ("Entering rescue mode...\n");
-
-  while (1)
-    {
-      char *line;
-
-      /* Print an error, if any.  */
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-
-      grub_rescue_read_line (&line, 0);
-      if (! line || line[0] == '\0')
-       continue;
-
-      grub_parser_get_current ()->parse_line (line, grub_rescue_read_line);
-      grub_free (line);
-    }
-}
diff --git a/kern/sparc64/cache.S b/kern/sparc64/cache.S
deleted file mode 100644 (file)
index 1a16add..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* cache.S - Flush the processor cache for a specific region.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-
-        .file   "cache.S"
-
-        .text
-
-/*
- * void grub_arch_sync_caches (void *address, grub_size_t len)
- */
-FUNCTION(grub_arch_sync_caches)
-       brz,pn          %o1, 2f
-        add            %o0, %o1, %o1
-       add             %o1, 7, %o1
-       andn            %o1, 7, %o1
-       andn            %o0, 7, %o0
-       sub             %o1, %o0, %o1
-1:     subcc           %o1, 8, %o1
-       bne,pt          %icc, 1b
-        flush          %o0 + %o1
-2:     retl
-        nop
-
diff --git a/kern/sparc64/dl.c b/kern/sparc64/dl.c
deleted file mode 100644 (file)
index 7b6266c..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/* dl.c - arch-dependent part of loadable module support */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/elf.h>
-#include <grub/misc.h>
-#include <grub/err.h>
-
-/* Check if EHDR is a valid ELF header.  */
-grub_err_t
-grub_arch_dl_check_header (void *ehdr)
-{
-  Elf_Ehdr *e = ehdr;
-
-  /* Check the magic numbers.  */
-  if (e->e_ident[EI_CLASS] != ELFCLASS64
-      || e->e_ident[EI_DATA] != ELFDATA2MSB
-      || e->e_machine != EM_SPARCV9)
-    return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
-
-  return GRUB_ERR_NONE;
-}
-
-
-/* Relocate symbols.  */
-grub_err_t
-grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
-{
-  Elf_Ehdr *e = ehdr;
-  Elf_Shdr *s;
-  Elf_Word entsize;
-  unsigned i;
-
-  /* Find a symbol table.  */
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_SYMTAB)
-      break;
-
-  if (i == e->e_shnum)
-    return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
-
-  entsize = s->sh_entsize;
-
-  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_RELA)
-      {
-       grub_dl_segment_t seg;
-
-       /* Find the target segment.  */
-       for (seg = mod->segment; seg; seg = seg->next)
-         if (seg->section == s->sh_info)
-           break;
-
-       if (seg)
-         {
-           Elf_Rela *rel, *max;
-
-           for (rel = (Elf_Rela *) ((char *) e + s->sh_offset),
-                  max = rel + s->sh_size / s->sh_entsize;
-                rel < max;
-                rel++)
-             {
-               Elf_Word *addr;
-               Elf_Sym *sym;
-               Elf_Addr value;
-
-               if (seg->size < rel->r_offset)
-                 return grub_error (GRUB_ERR_BAD_MODULE,
-                                    "reloc offset is out of the segment");
-
-               addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
-               sym = (Elf_Sym *) ((char *) mod->symtab
-                                    + entsize * ELF_R_SYM (rel->r_info));
-
-               value = sym->st_value + rel->r_addend;
-               switch (ELF_R_TYPE (rel->r_info) & 0xff)
-                 {
-                  case R_SPARC_32: /* 3 V-word32 */
-                    if (value & 0xFFFFFFFF00000000)
-                      return grub_error (GRUB_ERR_BAD_MODULE,
-                                         "address out of 32 bits range");
-                    *addr = value;
-                    break;
-                  case R_SPARC_WDISP30: /* 7 V-disp30 */
-                    if (((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000) &&
-                        (((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000)
-                        != 0xFFFFFFFF00000000))
-                      return grub_error (GRUB_ERR_BAD_MODULE,
-                                         "displacement out of 30 bits range");
-                    *addr = (*addr & 0xC0000000) |
-                      (((grub_int32_t) ((value - (Elf_Addr) addr) >> 2)) &
-                       0x3FFFFFFF);
-                    break;
-                  case R_SPARC_HI22: /* 9 V-imm22 */
-                    if (((grub_int32_t) value) & 0xFF00000000)
-                      return grub_error (GRUB_ERR_BAD_MODULE,
-                                         "high address out of 22 bits range");
-                    *addr = (*addr & 0xFFC00000) | ((value >> 10) & 0x3FFFFF);
-                    break;
-                  case R_SPARC_LO10: /* 12 T-simm13 */
-                    *addr = (*addr & 0xFFFFFC00) | (value & 0x3FF);
-                    break;
-                  case R_SPARC_64: /* 32 V-xwords64 */
-                    *(Elf_Xword *) addr = value;
-                    break;
-                 case R_SPARC_OLO10:
-                   *addr = (*addr & ~0x1fff)
-                     | (((value & 0x3ff) +
-                         (ELF_R_TYPE (rel->r_info) >> 8))
-                        & 0x1fff);
-                   break;
-                 default:
-                   return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                                      "this relocation (%d) is not implemented yet",
-                                      ELF_R_TYPE (rel->r_info));
-                 }
-             }
-         }
-      }
-
-  return GRUB_ERR_NONE;
-}
diff --git a/kern/sparc64/ieee1275/crt0.S b/kern/sparc64/ieee1275/crt0.S
deleted file mode 100644 (file)
index d5a1722..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/* crt0.S - Startup code for the Sparc64.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-#include <grub/symbol.h>
-#include <grub/machine/kernel.h>
-
-       .text
-       .align  4
-       .globl  _start
-_start:
-       ba      codestart
-        mov  %o4, %o0
-
-       . = EXT_C(_start) + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
-
-VARIABLE(grub_total_module_size)
-       .word   0
-VARIABLE(grub_kernel_image_size)
-       .word   0
-VARIABLE(grub_compressed_size)
-       .word   0
-VARIABLE(grub_prefix)
-       /* to be filled by grub-mkimage */
-
-       /*
-        *  Leave some breathing room for the prefix.
-        */
-
-       . = EXT_C(_start) + GRUB_KERNEL_MACHINE_DATA_END
-
-codestart:
-       /* Copy the modules past the end of the kernel image.
-        * They are currently sitting in the BSS.
-        */
-       sethi   %hi(__bss_start), %o2
-       or      %o2, %lo(__bss_start), %o2
-       sethi   %hi(_end), %o3
-       or      %o3, %lo(_end), %o3
-       sethi   %hi(grub_total_module_size), %o4
-       lduw    [%o4 + %lo(grub_total_module_size)], %o4
-
-       add     %o2, %o4, %o2
-       add     %o3, %o4, %o3
-
-       /* Save ieee1275 stack for future use by booter.  */
-       mov     %o6, %o1
-       /* Our future stack.  */
-       sethi   %hi(GRUB_KERNEL_MACHINE_STACK_SIZE - 2047), %o5
-       or      %o5, %lo(GRUB_KERNEL_MACHINE_STACK_SIZE - 2047), %o5
-       add     %o3, %o5, %o6
-       
-       sub     %o2, 4, %o2
-       sub     %o3, 4, %o3
-1:     lduw    [%o2], %o5
-       stw     %o5, [%o3]
-       subcc   %o4, 4, %o4
-       sub     %o2, 4, %o2
-       bne,pt  %icc, 1b
-        sub    %o3, 4, %o3
-
-       /* Now it's safe to clear out the BSS.  */
-       sethi   %hi(__bss_start), %o2
-       or      %o2, %lo(__bss_start), %o2
-       sethi   %hi(_end), %o3
-       or      %o3, %lo(_end), %o3
-1:     stx     %g0, [%o2]
-       add     %o2, 8, %o2
-       cmp     %o2, %o3
-       blt,pt  %xcc, 1b
-        nop
-       sethi   %hi(grub_ieee1275_original_stack), %o2
-       stx     %o1, [%o2 + %lo(grub_ieee1275_original_stack)]
-       sethi   %hi(grub_ieee1275_entry_fn), %o2
-       call    grub_main
-        stx    %o0, [%o2 + %lo(grub_ieee1275_entry_fn)]
-1:     ba,a    1b
diff --git a/kern/sparc64/ieee1275/ieee1275.c b/kern/sparc64/ieee1275/ieee1275.c
deleted file mode 100644 (file)
index 53be692..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/ieee1275/ieee1275.h>
-#include <grub/types.h>
-
-/* Sun specific ieee1275 interfaces used by GRUB.  */
-
-int
-grub_ieee1275_claim_vaddr (grub_addr_t vaddr, grub_size_t size)
-{
-  struct claim_vaddr_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t method;
-    grub_ieee1275_cell_t ihandle;
-    grub_ieee1275_cell_t align;
-    grub_ieee1275_cell_t size;
-    grub_ieee1275_cell_t virt;
-    grub_ieee1275_cell_t catch_result;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "call-method", 5, 2);
-  args.method = (grub_ieee1275_cell_t) "claim";
-  args.ihandle = grub_ieee1275_mmu;
-  args.align = 0;
-  args.size = size;
-  args.virt = vaddr;
-  args.catch_result = (grub_ieee1275_cell_t) -1;
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-  return args.catch_result;
-}
-
-int
-grub_ieee1275_alloc_physmem (grub_addr_t *paddr, grub_size_t size,
-                            grub_uint32_t align)
-{
-  grub_uint32_t memory_ihandle;
-  struct alloc_physmem_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t method;
-    grub_ieee1275_cell_t ihandle;
-    grub_ieee1275_cell_t align;
-    grub_ieee1275_cell_t size;
-    grub_ieee1275_cell_t catch_result;
-    grub_ieee1275_cell_t phys_high;
-    grub_ieee1275_cell_t phys_low;
-  }
-  args;
-  grub_ssize_t actual = 0;
-
-  grub_ieee1275_get_property (grub_ieee1275_chosen, "memory",
-                             &memory_ihandle, sizeof (memory_ihandle),
-                             &actual);
-  if (actual != sizeof (memory_ihandle))
-    return -1;
-
-  if (!align)
-    align = 1;
-
-  INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 3);
-  args.method = (grub_ieee1275_cell_t) "claim";
-  args.ihandle = memory_ihandle;
-  args.align = (align ? align : 1);
-  args.size = size;
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-
-  *paddr = args.phys_low;
-
-  return args.catch_result;
-}
diff --git a/kern/sparc64/ieee1275/init.c b/kern/sparc64/ieee1275/init.c
deleted file mode 100644 (file)
index a995217..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/*  init.c -- Initialize GRUB on SPARC64.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/kernel.h>
-#include <grub/mm.h>
-#include <grub/env.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/time.h>
-#include <grub/machine/boot.h>
-#include <grub/machine/console.h>
-#include <grub/machine/kernel.h>
-#include <grub/machine/time.h>
-#include <grub/ieee1275/ofdisk.h>
-#include <grub/ieee1275/ieee1275.h>
-
-grub_addr_t grub_ieee1275_original_stack;
-
-void
-grub_exit (void)
-{
-  grub_ieee1275_exit ();
-}
-
-static grub_uint64_t
-ieee1275_get_time_ms (void)
-{
-  grub_uint32_t msecs = 0;
-
-  grub_ieee1275_milliseconds (&msecs);
-
-  return msecs;
-}
-
-grub_uint32_t
-grub_get_rtc (void)
-{
-  return ieee1275_get_time_ms ();
-}
-
-grub_addr_t
-grub_arch_modules_addr (void)
-{
-  extern char _end[];
-  return (grub_addr_t) _end;
-}
-
-void
-grub_machine_set_prefix (void)
-{
-  if (grub_prefix[0] != '(')
-    {
-      char bootpath[IEEE1275_MAX_PATH_LEN];
-      char *prefix, *path, *colon;
-      grub_ssize_t actual;
-
-      if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath",
-                                     &bootpath, sizeof (bootpath), &actual))
-       {
-         /* Should never happen.  */
-         grub_printf ("/chosen/bootpath property missing!\n");
-         grub_env_set ("prefix", "");
-         return;
-       }
-
-      /* Transform an OF device path to a GRUB path.  */
-      colon = grub_strchr (bootpath, ':');
-      if (colon)
-       {
-         char *part = colon + 1;
-
-         /* Consistently provide numbered partitions to GRUB.
-            OpenBOOT traditionally uses alphabetical partition
-            specifiers.  */
-         if (part[0] >= 'a' && part[0] <= 'z')
-           part[0] = '1' + (part[0] - 'a');
-       }
-      prefix = grub_ieee1275_encode_devname (bootpath);
-
-      path = grub_xasprintf("%s%s", prefix, grub_prefix);
-
-      grub_strcpy (grub_prefix, path);
-
-      grub_free (path);
-      grub_free (prefix);
-    }
-
-  grub_env_set ("prefix", grub_prefix);
-}
-
-static void
-grub_heap_init (void)
-{
-  grub_mm_init_region ((void *) (grub_modules_get_end ()
-                                + GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000);
-}
-
-static void
-grub_parse_cmdline (void)
-{
-  grub_ssize_t actual;
-  char args[256];
-
-  if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args,
-                                 sizeof args, &actual) == 0
-      && actual > 1)
-    {
-      int i = 0;
-
-      while (i < actual)
-       {
-         char *command = &args[i];
-         char *end;
-         char *val;
-
-         end = grub_strchr (command, ';');
-         if (end == 0)
-           i = actual; /* No more commands after this one.  */
-         else
-           {
-             *end = '\0';
-             i += end - command + 1;
-             while (grub_isspace(args[i]))
-               i++;
-           }
-
-         /* Process command.  */
-         val = grub_strchr (command, '=');
-         if (val)
-           {
-             *val = '\0';
-             grub_env_set (command, val + 1);
-           }
-       }
-    }
-}
-
-void
-grub_machine_init (void)
-{
-  grub_ieee1275_init ();
-  grub_console_init ();
-  grub_heap_init ();
-
-  grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
-  grub_ofdisk_init ();
-
-  grub_parse_cmdline ();
-  grub_install_get_time_ms (ieee1275_get_time_ms);
-}
-
-void
-grub_machine_fini (void)
-{
-  grub_ofdisk_fini ();
-  grub_console_fini ();
-}
diff --git a/kern/term.c b/kern/term.c
deleted file mode 100644 (file)
index 6e3a2b4..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/term.h>
-#include <grub/err.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/env.h>
-#include <grub/time.h>
-
-struct grub_term_output *grub_term_outputs_disabled;
-struct grub_term_input *grub_term_inputs_disabled;
-struct grub_term_output *grub_term_outputs;
-struct grub_term_input *grub_term_inputs;
-
-void (*grub_newline_hook) (void) = NULL;
-
-/* Put a Unicode character.  */
-void
-grub_putcode (grub_uint32_t code, struct grub_term_output *term)
-{
-  if (code == '\t' && term->getxy)
-    {
-      int n;
-
-      n = 8 - ((term->getxy () >> 8) & 7);
-      while (n--)
-       grub_putcode (' ', term);
-
-      return;
-    }
-
-  (term->putchar) (code);
-  if (code == '\n')
-    (term->putchar) ('\r');
-}
-
-/* Put a character. C is one byte of a UTF-8 stream.
-   This function gathers bytes until a valid Unicode character is found.  */
-void
-grub_putchar (int c)
-{
-  static grub_size_t size = 0;
-  static grub_uint8_t buf[6];
-  grub_uint8_t *rest;
-  grub_uint32_t code;
-
-  buf[size++] = c;
-
-  while (grub_utf8_to_ucs4 (&code, 1, buf, size, (const grub_uint8_t **) &rest) 
-        != 0)
-    {
-      struct grub_term_output *term;
-      size -= rest - buf;
-      grub_memmove (buf, rest, size);
-      FOR_ACTIVE_TERM_OUTPUTS(term)
-       grub_putcode (code, term);
-      if (code == '\n' && grub_newline_hook)
-       grub_newline_hook ();
-    }
-}
-
-int
-grub_getkey (void)
-{
-  grub_term_input_t term;
-
-  grub_refresh ();
-
-  while (1)
-    {
-      FOR_ACTIVE_TERM_INPUTS(term)
-      {
-       int key = term->checkkey ();
-       if (key != -1)
-         return term->getkey ();
-      }
-
-      grub_cpu_idle ();
-    }
-}
-
-int
-grub_checkkey (void)
-{
-  grub_term_input_t term;
-
-  FOR_ACTIVE_TERM_INPUTS(term)
-  {
-    int key = term->checkkey ();
-    if (key != -1)
-      return key;
-  }
-
-  return -1;
-}
-
-int
-grub_getkeystatus (void)
-{
-  int status = 0;
-  grub_term_input_t term;
-
-  FOR_ACTIVE_TERM_INPUTS(term)
-  {
-    if (term->getkeystatus)
-      status |= term->getkeystatus ();
-  }
-
-  return status;
-}
-
-void
-grub_cls (void)
-{
-  struct grub_term_output *term;
-
-  FOR_ACTIVE_TERM_OUTPUTS(term)  
-  {
-    if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
-      {
-       grub_putcode ('\n', term);
-       grub_term_refresh (term);
-      }
-    else
-      (term->cls) ();
-  }
-}
-
-void
-grub_setcolorstate (grub_term_color_state state)
-{
-  struct grub_term_output *term;
-  
-  FOR_ACTIVE_TERM_OUTPUTS(term)
-    grub_term_setcolorstate (term, state);
-}
-
-void
-grub_refresh (void)
-{
-  struct grub_term_output *term;
-
-  FOR_ACTIVE_TERM_OUTPUTS(term)
-    grub_term_refresh (term);
-}
diff --git a/kern/time.c b/kern/time.c
deleted file mode 100644 (file)
index 6521ec6..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* time.c - kernel time functions */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/time.h>
-
-typedef grub_uint64_t (*get_time_ms_func_t) (void);
-
-/* Function pointer to the implementation in use.  */
-static get_time_ms_func_t get_time_ms_func;
-
-grub_uint64_t
-grub_get_time_ms (void)
-{
-  return get_time_ms_func ();
-}
-
-void
-grub_install_get_time_ms (get_time_ms_func_t func)
-{
-  get_time_ms_func = func;
-}
diff --git a/kern/x86_64/dl.c b/kern/x86_64/dl.c
deleted file mode 100644 (file)
index 090ad78..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/* dl-x86_64.c - arch-dependent part of loadable module support */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/elf.h>
-#include <grub/misc.h>
-#include <grub/err.h>
-
-/* Check if EHDR is a valid ELF header.  */
-grub_err_t
-grub_arch_dl_check_header (void *ehdr)
-{
-  Elf64_Ehdr *e = ehdr;
-
-  /* Check the magic numbers.  */
-  if (e->e_ident[EI_CLASS] != ELFCLASS64
-      || e->e_ident[EI_DATA] != ELFDATA2LSB
-      || e->e_machine != EM_X86_64)
-    return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
-
-  return GRUB_ERR_NONE;
-}
-
-/* Relocate symbols.  */
-grub_err_t
-grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
-{
-  Elf64_Ehdr *e = ehdr;
-  Elf64_Shdr *s;
-  Elf64_Word entsize;
-  unsigned i;
-
-  /* Find a symbol table.  */
-  for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_SYMTAB)
-      break;
-
-  if (i == e->e_shnum)
-    return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
-
-  entsize = s->sh_entsize;
-
-  for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
-       i < e->e_shnum;
-       i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize))
-    if (s->sh_type == SHT_RELA)
-      {
-       grub_dl_segment_t seg;
-
-       /* Find the target segment.  */
-       for (seg = mod->segment; seg; seg = seg->next)
-         if (seg->section == s->sh_info)
-           break;
-
-       if (seg)
-         {
-           Elf64_Rela *rel, *max;
-
-           for (rel = (Elf64_Rela *) ((char *) e + s->sh_offset),
-                  max = rel + s->sh_size / s->sh_entsize;
-                rel < max;
-                rel++)
-             {
-               Elf64_Word *addr32;
-               Elf64_Xword *addr64;
-               Elf64_Sym *sym;
-
-               if (seg->size < rel->r_offset)
-                 return grub_error (GRUB_ERR_BAD_MODULE,
-                                    "reloc offset is out of the segment");
-
-               addr32 = (Elf64_Word *) ((char *) seg->addr + rel->r_offset);
-               addr64 = (Elf64_Xword *) addr32;
-               sym = (Elf64_Sym *) ((char *) mod->symtab
-                                    + entsize * ELF_R_SYM (rel->r_info));
-
-               switch (ELF_R_TYPE (rel->r_info))
-                 {
-                 case R_X86_64_64:
-                   *addr64 += rel->r_addend + sym->st_value;
-                   break;
-
-                 case R_X86_64_PC32:
-                   *addr32 += rel->r_addend + sym->st_value -
-                             (Elf64_Xword) seg->addr - rel->r_offset;
-                   break;
-
-                  case R_X86_64_32:
-                  case R_X86_64_32S:
-                    *addr32 += rel->r_addend + sym->st_value;
-                    break;
-
-                  default:
-                    grub_fatal ("Unrecognized relocation: %d\n", ELF_R_TYPE (rel->r_info));
-                 }
-             }
-         }
-      }
-
-  return GRUB_ERR_NONE;
-}
diff --git a/kern/x86_64/efi/callwrap.S b/kern/x86_64/efi/callwrap.S
deleted file mode 100644 (file)
index 1946732..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/* callwrap.S - wrapper for x86_64 efi calls */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <grub/symbol.h>
-#include <grub/boot.h>
-
-/*
- * x86_64 uses registry to pass parameters. Unfortunately, gcc and efi use
- * different call conversion, so we need to do some conversion.
- *
- * gcc:
- *   %rdi,  %esi,  %rdx,  %rcx, %r8, %r9, 8(%rsp), 16(%rsp), ...
- *
- * efi:
- *   %rcx,  %rdx,  %r8,  %r9,  32(%rsp), 40(%rsp), 48(%rsp), ...
- *
- */
-
-        .file   "callwrap.S"
-        .text
-
-FUNCTION(efi_wrap_0)
-       subq $40, %rsp
-       call *%rdi
-       addq $40, %rsp
-       ret
-
-FUNCTION(efi_wrap_1)
-       subq $40, %rsp
-       mov  %rsi, %rcx
-       call *%rdi
-       addq $40, %rsp
-       ret
-
-FUNCTION(efi_wrap_2)
-       subq $40, %rsp
-       mov  %rsi, %rcx
-       call *%rdi
-       addq $40, %rsp
-       ret
-
-FUNCTION(efi_wrap_3)
-       subq $40, %rsp
-       mov  %rcx, %r8
-       mov  %rsi, %rcx
-       call *%rdi
-       addq $40, %rsp
-       ret
-
-FUNCTION(efi_wrap_4)
-       subq $40, %rsp
-       mov %r8, %r9
-       mov %rcx, %r8
-       mov %rsi, %rcx
-       call *%rdi
-       addq $40, %rsp
-       ret
-
-FUNCTION(efi_wrap_5)
-       subq $40, %rsp
-       mov %r9, 32(%rsp)
-       mov %r8, %r9
-       mov %rcx, %r8
-       mov %rsi, %rcx
-       call *%rdi
-       addq $40, %rsp
-       ret
-
-FUNCTION(efi_wrap_6)
-       subq $56, %rsp
-       mov 56+8(%rsp), %rax
-       mov %rax, 40(%rsp)
-       mov %r9, 32(%rsp)
-       mov %r8, %r9
-       mov %rcx, %r8
-       mov %rsi, %rcx
-       call *%rdi
-       addq $56, %rsp
-       ret
-
-FUNCTION(efi_wrap_10)
-       subq $88, %rsp
-       mov 88+40(%rsp), %rax
-       mov %rax, 72(%rsp)
-       mov 88+32(%rsp), %rax
-       mov %rax, 64(%rsp)
-       mov 88+24(%rsp), %rax
-       mov %rax, 56(%rsp)
-       mov 88+16(%rsp), %rax
-       mov %rax, 48(%rsp)
-       mov 88+8(%rsp), %rax
-       mov %rax, 40(%rsp)
-       mov %r9, 32(%rsp)
-       mov %r8, %r9
-       mov %rcx, %r8
-       mov %rsi, %rcx
-       call *%rdi
-       addq $88, %rsp
-       ret
diff --git a/kern/x86_64/efi/startup.S b/kern/x86_64/efi/startup.S
deleted file mode 100644 (file)
index fb4fc7b..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/* startup.S - bootstrap GRUB itself */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <grub/symbol.h>
-#include <grub/boot.h>
-
-        .file   "startup.S"
-        .text
-        .globl  start, _start
-        .code64
-
-start:
-_start:
-       jmp codestart
-
-        /*
-         *  Compatibility version number
-         *
-         *  These MUST be at byte offset 6 and 7 of the executable
-         *  DO NOT MOVE !!!
-         */
-        . = _start + 0x6
-        .byte   GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
-
-        /*
-         *  This is a special data area 8 bytes from the beginning.
-         */
-
-        . = _start + 0x8
-
-VARIABLE(grub_prefix)
-       /* to be filled by grub-mkimage */
-
-        /*
-         *  Leave some breathing room for the prefix.
-         */
-
-        . = _start + 0x50
-
-codestart:
-       movq    %rcx, EXT_C(grub_efi_image_handle)(%rip)
-       movq    %rdx, EXT_C(grub_efi_system_table)(%rip)
-
-       call    EXT_C(grub_main)
-       ret
-
diff --git a/lib/LzFind.c b/lib/LzFind.c
deleted file mode 100644 (file)
index cd7a1cb..0000000
+++ /dev/null
@@ -1,774 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (c) 1999-2008 Igor Pavlov
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
- * to adapt it to GRUB's requirement.
- *
- * See <http://www.7-zip.org>, for more information about LZMA.
- */
-
-#include <string.h>
-
-#include <grub/lib/LzFind.h>
-#include <grub/lib/LzHash.h>
-
-#define kEmptyHashValue 0
-#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
-#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
-#define kNormalizeMask (~(kNormalizeStepMin - 1))
-#define kMaxHistorySize ((UInt32)3 << 30)
-
-#define kStartMaxLen 3
-
-static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
-{
-  if (!p->directInput)
-  {
-    alloc->Free(alloc, p->bufferBase);
-    p->bufferBase = 0;
-  }
-}
-
-/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
-
-static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
-{
-  UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
-  if (p->directInput)
-  {
-    p->blockSize = blockSize;
-    return 1;
-  }
-  if (p->bufferBase == 0 || p->blockSize != blockSize)
-  {
-    LzInWindow_Free(p, alloc);
-    p->blockSize = blockSize;
-    p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
-  }
-  return (p->bufferBase != 0);
-}
-
-Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
-Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
-
-UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
-
-void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
-{
-  p->posLimit -= subValue;
-  p->pos -= subValue;
-  p->streamPos -= subValue;
-}
-
-static void MatchFinder_ReadBlock(CMatchFinder *p)
-{
-  if (p->streamEndWasReached || p->result != SZ_OK)
-    return;
-  for (;;)
-  {
-    Byte *dest = p->buffer + (p->streamPos - p->pos);
-    size_t size = (p->bufferBase + p->blockSize - dest);
-    if (size == 0)
-      return;
-    p->result = p->stream->Read(p->stream, dest, &size);
-    if (p->result != SZ_OK)
-      return;
-    if (size == 0)
-    {
-      p->streamEndWasReached = 1;
-      return;
-    }
-    p->streamPos += (UInt32)size;
-    if (p->streamPos - p->pos > p->keepSizeAfter)
-      return;
-  }
-}
-
-void MatchFinder_MoveBlock(CMatchFinder *p)
-{
-  memmove(p->bufferBase,
-    p->buffer - p->keepSizeBefore,
-    (size_t)(p->streamPos - p->pos + p->keepSizeBefore));
-  p->buffer = p->bufferBase + p->keepSizeBefore;
-}
-
-int MatchFinder_NeedMove(CMatchFinder *p)
-{
-  /* if (p->streamEndWasReached) return 0; */
-  return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
-}
-
-void MatchFinder_ReadIfRequired(CMatchFinder *p)
-{
-  if (p->streamEndWasReached)
-    return;
-  if (p->keepSizeAfter >= p->streamPos - p->pos)
-    MatchFinder_ReadBlock(p);
-}
-
-static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
-{
-  if (MatchFinder_NeedMove(p))
-    MatchFinder_MoveBlock(p);
-  MatchFinder_ReadBlock(p);
-}
-
-static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
-{
-  p->cutValue = 32;
-  p->btMode = 1;
-  p->numHashBytes = 4;
-  /* p->skipModeBits = 0; */
-  p->directInput = 0;
-  p->bigHash = 0;
-}
-
-#define kCrcPoly 0xEDB88320
-
-void MatchFinder_Construct(CMatchFinder *p)
-{
-  UInt32 i;
-  p->bufferBase = 0;
-  p->directInput = 0;
-  p->hash = 0;
-  MatchFinder_SetDefaultSettings(p);
-
-  for (i = 0; i < 256; i++)
-  {
-    UInt32 r = i;
-    int j;
-    for (j = 0; j < 8; j++)
-      r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
-    p->crc[i] = r;
-  }
-}
-
-static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
-{
-  alloc->Free(alloc, p->hash);
-  p->hash = 0;
-}
-
-void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
-{
-  MatchFinder_FreeThisClassMemory(p, alloc);
-  LzInWindow_Free(p, alloc);
-}
-
-static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
-{
-  size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
-  if (sizeInBytes / sizeof(CLzRef) != num)
-    return 0;
-  return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
-}
-
-int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
-    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
-    ISzAlloc *alloc)
-{
-  UInt32 sizeReserv;
-  if (historySize > kMaxHistorySize)
-  {
-    MatchFinder_Free(p, alloc);
-    return 0;
-  }
-  sizeReserv = historySize >> 1;
-  if (historySize > ((UInt32)2 << 30))
-    sizeReserv = historySize >> 2;
-  sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
-
-  p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
-  p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
-  /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
-  if (LzInWindow_Create(p, sizeReserv, alloc))
-  {
-    UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1;
-    UInt32 hs;
-    p->matchMaxLen = matchMaxLen;
-    {
-      p->fixedHashSize = 0;
-      if (p->numHashBytes == 2)
-        hs = (1 << 16) - 1;
-      else
-      {
-        hs = historySize - 1;
-        hs |= (hs >> 1);
-        hs |= (hs >> 2);
-        hs |= (hs >> 4);
-        hs |= (hs >> 8);
-        hs >>= 1;
-        /* hs >>= p->skipModeBits; */
-        hs |= 0xFFFF; /* don't change it! It's required for Deflate */
-        if (hs > (1 << 24))
-        {
-          if (p->numHashBytes == 3)
-            hs = (1 << 24) - 1;
-          else
-            hs >>= 1;
-        }
-      }
-      p->hashMask = hs;
-      hs++;
-      if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
-      if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
-      if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
-      hs += p->fixedHashSize;
-    }
-
-    {
-      UInt32 prevSize = p->hashSizeSum + p->numSons;
-      UInt32 newSize;
-      p->historySize = historySize;
-      p->hashSizeSum = hs;
-      p->cyclicBufferSize = newCyclicBufferSize;
-      p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
-      newSize = p->hashSizeSum + p->numSons;
-      if (p->hash != 0 && prevSize == newSize)
-        return 1;
-      MatchFinder_FreeThisClassMemory(p, alloc);
-      p->hash = AllocRefs(newSize, alloc);
-      if (p->hash != 0)
-      {
-        p->son = p->hash + p->hashSizeSum;
-        return 1;
-      }
-    }
-  }
-  MatchFinder_Free(p, alloc);
-  return 0;
-}
-
-static void MatchFinder_SetLimits(CMatchFinder *p)
-{
-  UInt32 limit = kMaxValForNormalize - p->pos;
-  UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
-  if (limit2 < limit)
-    limit = limit2;
-  limit2 = p->streamPos - p->pos;
-  if (limit2 <= p->keepSizeAfter)
-  {
-    if (limit2 > 0)
-      limit2 = 1;
-  }
-  else
-    limit2 -= p->keepSizeAfter;
-  if (limit2 < limit)
-    limit = limit2;
-  {
-    UInt32 lenLimit = p->streamPos - p->pos;
-    if (lenLimit > p->matchMaxLen)
-      lenLimit = p->matchMaxLen;
-    p->lenLimit = lenLimit;
-  }
-  p->posLimit = p->pos + limit;
-}
-
-void MatchFinder_Init(CMatchFinder *p)
-{
-  UInt32 i;
-  for(i = 0; i < p->hashSizeSum; i++)
-    p->hash[i] = kEmptyHashValue;
-  p->cyclicBufferPos = 0;
-  p->buffer = p->bufferBase;
-  p->pos = p->streamPos = p->cyclicBufferSize;
-  p->result = SZ_OK;
-  p->streamEndWasReached = 0;
-  MatchFinder_ReadBlock(p);
-  MatchFinder_SetLimits(p);
-}
-
-static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
-{
-  return (p->pos - p->historySize - 1) & kNormalizeMask;
-}
-
-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
-{
-  UInt32 i;
-  for (i = 0; i < numItems; i++)
-  {
-    UInt32 value = items[i];
-    if (value <= subValue)
-      value = kEmptyHashValue;
-    else
-      value -= subValue;
-    items[i] = value;
-  }
-}
-
-static void MatchFinder_Normalize(CMatchFinder *p)
-{
-  UInt32 subValue = MatchFinder_GetSubValue(p);
-  MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
-  MatchFinder_ReduceOffsets(p, subValue);
-}
-
-static void MatchFinder_CheckLimits(CMatchFinder *p)
-{
-  if (p->pos == kMaxValForNormalize)
-    MatchFinder_Normalize(p);
-  if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
-    MatchFinder_CheckAndMoveAndRead(p);
-  if (p->cyclicBufferPos == p->cyclicBufferSize)
-    p->cyclicBufferPos = 0;
-  MatchFinder_SetLimits(p);
-}
-
-static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
-    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
-    UInt32 *distances, UInt32 maxLen)
-{
-  son[_cyclicBufferPos] = curMatch;
-  for (;;)
-  {
-    UInt32 delta = pos - curMatch;
-    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
-      return distances;
-    {
-      const Byte *pb = cur - delta;
-      curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
-      if (pb[maxLen] == cur[maxLen] && *pb == *cur)
-      {
-        UInt32 len = 0;
-        while(++len != lenLimit)
-          if (pb[len] != cur[len])
-            break;
-        if (maxLen < len)
-        {
-          *distances++ = maxLen = len;
-          *distances++ = delta - 1;
-          if (len == lenLimit)
-            return distances;
-        }
-      }
-    }
-  }
-}
-
-UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
-    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
-    UInt32 *distances, UInt32 maxLen)
-{
-  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
-  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
-  UInt32 len0 = 0, len1 = 0;
-  for (;;)
-  {
-    UInt32 delta = pos - curMatch;
-    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
-    {
-      *ptr0 = *ptr1 = kEmptyHashValue;
-      return distances;
-    }
-    {
-      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
-      const Byte *pb = cur - delta;
-      UInt32 len = (len0 < len1 ? len0 : len1);
-      if (pb[len] == cur[len])
-      {
-        if (++len != lenLimit && pb[len] == cur[len])
-          while(++len != lenLimit)
-            if (pb[len] != cur[len])
-              break;
-        if (maxLen < len)
-        {
-          *distances++ = maxLen = len;
-          *distances++ = delta - 1;
-          if (len == lenLimit)
-          {
-            *ptr1 = pair[0];
-            *ptr0 = pair[1];
-            return distances;
-          }
-        }
-      }
-      if (pb[len] < cur[len])
-      {
-        *ptr1 = curMatch;
-        ptr1 = pair + 1;
-        curMatch = *ptr1;
-        len1 = len;
-      }
-      else
-      {
-        *ptr0 = curMatch;
-        ptr0 = pair;
-        curMatch = *ptr0;
-        len0 = len;
-      }
-    }
-  }
-}
-
-static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
-    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
-{
-  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
-  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
-  UInt32 len0 = 0, len1 = 0;
-  for (;;)
-  {
-    UInt32 delta = pos - curMatch;
-    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
-    {
-      *ptr0 = *ptr1 = kEmptyHashValue;
-      return;
-    }
-    {
-      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
-      const Byte *pb = cur - delta;
-      UInt32 len = (len0 < len1 ? len0 : len1);
-      if (pb[len] == cur[len])
-      {
-        while(++len != lenLimit)
-          if (pb[len] != cur[len])
-            break;
-        {
-          if (len == lenLimit)
-          {
-            *ptr1 = pair[0];
-            *ptr0 = pair[1];
-            return;
-          }
-        }
-      }
-      if (pb[len] < cur[len])
-      {
-        *ptr1 = curMatch;
-        ptr1 = pair + 1;
-        curMatch = *ptr1;
-        len1 = len;
-      }
-      else
-      {
-        *ptr0 = curMatch;
-        ptr0 = pair;
-        curMatch = *ptr0;
-        len0 = len;
-      }
-    }
-  }
-}
-
-#define MOVE_POS \
-  ++p->cyclicBufferPos; \
-  p->buffer++; \
-  if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
-
-#define MOVE_POS_RET MOVE_POS return offset;
-
-static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
-
-#define GET_MATCHES_HEADER2(minLen, ret_op) \
-  UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
-  lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
-  cur = p->buffer;
-
-#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
-#define SKIP_HEADER(minLen)        GET_MATCHES_HEADER2(minLen, continue)
-
-#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
-
-#define GET_MATCHES_FOOTER(offset, maxLen) \
-  offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
-  distances + offset, maxLen) - distances); MOVE_POS_RET;
-
-#define SKIP_FOOTER \
-  SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
-
-static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-{
-  UInt32 offset;
-  GET_MATCHES_HEADER(2)
-  HASH2_CALC;
-  curMatch = p->hash[hashValue];
-  p->hash[hashValue] = p->pos;
-  offset = 0;
-  GET_MATCHES_FOOTER(offset, 1)
-}
-
-UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-{
-  UInt32 offset;
-  GET_MATCHES_HEADER(3)
-  HASH_ZIP_CALC;
-  curMatch = p->hash[hashValue];
-  p->hash[hashValue] = p->pos;
-  offset = 0;
-  GET_MATCHES_FOOTER(offset, 2)
-}
-
-static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-{
-  UInt32 hash2Value, delta2, maxLen, offset;
-  GET_MATCHES_HEADER(3)
-
-  HASH3_CALC;
-
-  delta2 = p->pos - p->hash[hash2Value];
-  curMatch = p->hash[kFix3HashSize + hashValue];
-
-  p->hash[hash2Value] =
-  p->hash[kFix3HashSize + hashValue] = p->pos;
-
-
-  maxLen = 2;
-  offset = 0;
-  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
-  {
-    for (; maxLen != lenLimit; maxLen++)
-      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
-        break;
-    distances[0] = maxLen;
-    distances[1] = delta2 - 1;
-    offset = 2;
-    if (maxLen == lenLimit)
-    {
-      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
-      MOVE_POS_RET;
-    }
-  }
-  GET_MATCHES_FOOTER(offset, maxLen)
-}
-
-static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-{
-  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
-  GET_MATCHES_HEADER(4)
-
-  HASH4_CALC;
-
-  delta2 = p->pos - p->hash[                hash2Value];
-  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
-  curMatch = p->hash[kFix4HashSize + hashValue];
-
-  p->hash[                hash2Value] =
-  p->hash[kFix3HashSize + hash3Value] =
-  p->hash[kFix4HashSize + hashValue] = p->pos;
-
-  maxLen = 1;
-  offset = 0;
-  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
-  {
-    distances[0] = maxLen = 2;
-    distances[1] = delta2 - 1;
-    offset = 2;
-  }
-  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
-  {
-    maxLen = 3;
-    distances[offset + 1] = delta3 - 1;
-    offset += 2;
-    delta2 = delta3;
-  }
-  if (offset != 0)
-  {
-    for (; maxLen != lenLimit; maxLen++)
-      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
-        break;
-    distances[offset - 2] = maxLen;
-    if (maxLen == lenLimit)
-    {
-      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
-      MOVE_POS_RET;
-    }
-  }
-  if (maxLen < 3)
-    maxLen = 3;
-  GET_MATCHES_FOOTER(offset, maxLen)
-}
-
-static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-{
-  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
-  GET_MATCHES_HEADER(4)
-
-  HASH4_CALC;
-
-  delta2 = p->pos - p->hash[                hash2Value];
-  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
-  curMatch = p->hash[kFix4HashSize + hashValue];
-
-  p->hash[                hash2Value] =
-  p->hash[kFix3HashSize + hash3Value] =
-  p->hash[kFix4HashSize + hashValue] = p->pos;
-
-  maxLen = 1;
-  offset = 0;
-  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
-  {
-    distances[0] = maxLen = 2;
-    distances[1] = delta2 - 1;
-    offset = 2;
-  }
-  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
-  {
-    maxLen = 3;
-    distances[offset + 1] = delta3 - 1;
-    offset += 2;
-    delta2 = delta3;
-  }
-  if (offset != 0)
-  {
-    for (; maxLen != lenLimit; maxLen++)
-      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
-        break;
-    distances[offset - 2] = maxLen;
-    if (maxLen == lenLimit)
-    {
-      p->son[p->cyclicBufferPos] = curMatch;
-      MOVE_POS_RET;
-    }
-  }
-  if (maxLen < 3)
-    maxLen = 3;
-  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
-    distances + offset, maxLen) - (distances));
-  MOVE_POS_RET
-}
-
-UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-{
-  UInt32 offset;
-  GET_MATCHES_HEADER(3)
-  HASH_ZIP_CALC;
-  curMatch = p->hash[hashValue];
-  p->hash[hashValue] = p->pos;
-  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
-    distances, 2) - (distances));
-  MOVE_POS_RET
-}
-
-static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-{
-  do
-  {
-    SKIP_HEADER(2)
-    HASH2_CALC;
-    curMatch = p->hash[hashValue];
-    p->hash[hashValue] = p->pos;
-    SKIP_FOOTER
-  }
-  while (--num != 0);
-}
-
-void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-{
-  do
-  {
-    SKIP_HEADER(3)
-    HASH_ZIP_CALC;
-    curMatch = p->hash[hashValue];
-    p->hash[hashValue] = p->pos;
-    SKIP_FOOTER
-  }
-  while (--num != 0);
-}
-
-static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-{
-  do
-  {
-    UInt32 hash2Value;
-    SKIP_HEADER(3)
-    HASH3_CALC;
-    curMatch = p->hash[kFix3HashSize + hashValue];
-    p->hash[hash2Value] =
-    p->hash[kFix3HashSize + hashValue] = p->pos;
-    SKIP_FOOTER
-  }
-  while (--num != 0);
-}
-
-static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-{
-  do
-  {
-    UInt32 hash2Value, hash3Value;
-    SKIP_HEADER(4)
-    HASH4_CALC;
-    curMatch = p->hash[kFix4HashSize + hashValue];
-    p->hash[                hash2Value] =
-    p->hash[kFix3HashSize + hash3Value] = p->pos;
-    p->hash[kFix4HashSize + hashValue] = p->pos;
-    SKIP_FOOTER
-  }
-  while (--num != 0);
-}
-
-static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-{
-  do
-  {
-    UInt32 hash2Value, hash3Value;
-    SKIP_HEADER(4)
-    HASH4_CALC;
-    curMatch = p->hash[kFix4HashSize + hashValue];
-    p->hash[                hash2Value] =
-    p->hash[kFix3HashSize + hash3Value] =
-    p->hash[kFix4HashSize + hashValue] = p->pos;
-    p->son[p->cyclicBufferPos] = curMatch;
-    MOVE_POS
-  }
-  while (--num != 0);
-}
-
-void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-{
-  do
-  {
-    SKIP_HEADER(3)
-    HASH_ZIP_CALC;
-    curMatch = p->hash[hashValue];
-    p->hash[hashValue] = p->pos;
-    p->son[p->cyclicBufferPos] = curMatch;
-    MOVE_POS
-  }
-  while (--num != 0);
-}
-
-void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
-{
-  vTable->Init = (Mf_Init_Func)MatchFinder_Init;
-  vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
-  vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
-  vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
-  if (!p->btMode)
-  {
-    vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
-    vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
-  }
-  else if (p->numHashBytes == 2)
-  {
-    vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
-    vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
-  }
-  else if (p->numHashBytes == 3)
-  {
-    vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
-    vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
-  }
-  else
-  {
-    vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
-    vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
-  }
-}
diff --git a/lib/LzmaDec.c b/lib/LzmaDec.c
deleted file mode 100644 (file)
index 62ebee6..0000000
+++ /dev/null
@@ -1,1035 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (c) 1999-2008 Igor Pavlov
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
- * to adapt it to GRUB's requirement.
- *
- * See <http://www.7-zip.org>, for more information about LZMA.
- */
-
-#include <grub/lib/LzmaDec.h>
-
-#include <string.h>
-
-#define kNumTopBits 24
-#define kTopValue ((UInt32)1 << kNumTopBits)
-
-#define kNumBitModelTotalBits 11
-#define kBitModelTotal (1 << kNumBitModelTotalBits)
-#define kNumMoveBits 5
-
-#define RC_INIT_SIZE 5
-
-#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
-
-#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
-#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
-#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
-#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
-  { UPDATE_0(p); i = (i + i); A0; } else \
-  { UPDATE_1(p); i = (i + i) + 1; A1; }
-#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
-
-#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
-#define TREE_DECODE(probs, limit, i) \
-  { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
-
-/* #define _LZMA_SIZE_OPT */
-
-#ifdef _LZMA_SIZE_OPT
-#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
-#else
-#define TREE_6_DECODE(probs, i) \
-  { i = 1; \
-  TREE_GET_BIT(probs, i); \
-  TREE_GET_BIT(probs, i); \
-  TREE_GET_BIT(probs, i); \
-  TREE_GET_BIT(probs, i); \
-  TREE_GET_BIT(probs, i); \
-  TREE_GET_BIT(probs, i); \
-  i -= 0x40; }
-#endif
-
-#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
-
-#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
-#define UPDATE_0_CHECK range = bound;
-#define UPDATE_1_CHECK range -= bound; code -= bound;
-#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
-  { UPDATE_0_CHECK; i = (i + i); A0; } else \
-  { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
-#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
-#define TREE_DECODE_CHECK(probs, limit, i) \
-  { i = 1; do { GET_BIT_CHECK(probs + i, i) } while(i < limit); i -= limit; }
-
-
-#define kNumPosBitsMax 4
-#define kNumPosStatesMax (1 << kNumPosBitsMax)
-
-#define kLenNumLowBits 3
-#define kLenNumLowSymbols (1 << kLenNumLowBits)
-#define kLenNumMidBits 3
-#define kLenNumMidSymbols (1 << kLenNumMidBits)
-#define kLenNumHighBits 8
-#define kLenNumHighSymbols (1 << kLenNumHighBits)
-
-#define LenChoice 0
-#define LenChoice2 (LenChoice + 1)
-#define LenLow (LenChoice2 + 1)
-#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
-#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
-#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
-
-
-#define kNumStates 12
-#define kNumLitStates 7
-
-#define kStartPosModelIndex 4
-#define kEndPosModelIndex 14
-#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
-
-#define kNumPosSlotBits 6
-#define kNumLenToPosStates 4
-
-#define kNumAlignBits 4
-#define kAlignTableSize (1 << kNumAlignBits)
-
-#define kMatchMinLen 2
-#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
-
-#define IsMatch 0
-#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
-#define IsRepG0 (IsRep + kNumStates)
-#define IsRepG1 (IsRepG0 + kNumStates)
-#define IsRepG2 (IsRepG1 + kNumStates)
-#define IsRep0Long (IsRepG2 + kNumStates)
-#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
-#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
-#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
-#define LenCoder (Align + kAlignTableSize)
-#define RepLenCoder (LenCoder + kNumLenProbs)
-#define Literal (RepLenCoder + kNumLenProbs)
-
-#define LZMA_BASE_SIZE 1846
-#define LZMA_LIT_SIZE 768
-
-#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
-
-#if Literal != LZMA_BASE_SIZE
-StopCompilingDueBUG
-#endif
-
-/*
-#define LZMA_STREAM_WAS_FINISHED_ID (-1)
-#define LZMA_SPEC_LEN_OFFSET (-3)
-*/
-
-Byte kLiteralNextStates[kNumStates * 2] =
-{
-  0, 0, 0, 0, 1, 2, 3,  4,  5,  6,  4,  5,
-  7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
-};
-
-#define LZMA_DIC_MIN (1 << 12)
-
-/* First LZMA-symbol is always decoded.
-And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
-Out:
-  Result:
-    0 - OK
-    1 - Error
-  p->remainLen:
-    < kMatchSpecLenStart : normal remain
-    = kMatchSpecLenStart : finished
-    = kMatchSpecLenStart + 1 : Flush marker
-    = kMatchSpecLenStart + 2 : State Init Marker
-*/
-
-static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
-{
-  CLzmaProb *probs = p->probs;
-
-  unsigned state = p->state;
-  UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
-  unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
-  unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
-  unsigned lc = p->prop.lc;
-
-  Byte *dic = p->dic;
-  SizeT dicBufSize = p->dicBufSize;
-  SizeT dicPos = p->dicPos;
-
-  UInt32 processedPos = p->processedPos;
-  UInt32 checkDicSize = p->checkDicSize;
-  unsigned len = 0;
-
-  const Byte *buf = p->buf;
-  UInt32 range = p->range;
-  UInt32 code = p->code;
-
-  do
-  {
-    CLzmaProb *prob;
-    UInt32 bound;
-    unsigned ttt;
-    unsigned posState = processedPos & pbMask;
-
-    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
-    IF_BIT_0(prob)
-    {
-      unsigned symbol;
-      UPDATE_0(prob);
-      prob = probs + Literal;
-      if (checkDicSize != 0 || processedPos != 0)
-        prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
-        (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
-
-      if (state < kNumLitStates)
-      {
-        symbol = 1;
-        do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
-      }
-      else
-      {
-        unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
-        unsigned offs = 0x100;
-        symbol = 1;
-        do
-        {
-          unsigned bit;
-          CLzmaProb *probLit;
-          matchByte <<= 1;
-          bit = (matchByte & offs);
-          probLit = prob + offs + bit + symbol;
-          GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
-        }
-        while (symbol < 0x100);
-      }
-      dic[dicPos++] = (Byte)symbol;
-      processedPos++;
-
-      state = kLiteralNextStates[state];
-      /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
-      continue;
-    }
-    else
-    {
-      UPDATE_1(prob);
-      prob = probs + IsRep + state;
-      IF_BIT_0(prob)
-      {
-        UPDATE_0(prob);
-        state += kNumStates;
-        prob = probs + LenCoder;
-      }
-      else
-      {
-        UPDATE_1(prob);
-        if (checkDicSize == 0 && processedPos == 0)
-          return SZ_ERROR_DATA;
-        prob = probs + IsRepG0 + state;
-        IF_BIT_0(prob)
-        {
-          UPDATE_0(prob);
-          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
-          IF_BIT_0(prob)
-          {
-            UPDATE_0(prob);
-            dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
-            dicPos++;
-            processedPos++;
-            state = state < kNumLitStates ? 9 : 11;
-            continue;
-          }
-          UPDATE_1(prob);
-        }
-        else
-        {
-          UInt32 distance;
-          UPDATE_1(prob);
-          prob = probs + IsRepG1 + state;
-          IF_BIT_0(prob)
-          {
-            UPDATE_0(prob);
-            distance = rep1;
-          }
-          else
-          {
-            UPDATE_1(prob);
-            prob = probs + IsRepG2 + state;
-            IF_BIT_0(prob)
-            {
-              UPDATE_0(prob);
-              distance = rep2;
-            }
-            else
-            {
-              UPDATE_1(prob);
-              distance = rep3;
-              rep3 = rep2;
-            }
-            rep2 = rep1;
-          }
-          rep1 = rep0;
-          rep0 = distance;
-        }
-        state = state < kNumLitStates ? 8 : 11;
-        prob = probs + RepLenCoder;
-      }
-      {
-        unsigned limit, offset;
-        CLzmaProb *probLen = prob + LenChoice;
-        IF_BIT_0(probLen)
-        {
-          UPDATE_0(probLen);
-          probLen = prob + LenLow + (posState << kLenNumLowBits);
-          offset = 0;
-          limit = (1 << kLenNumLowBits);
-        }
-        else
-        {
-          UPDATE_1(probLen);
-          probLen = prob + LenChoice2;
-          IF_BIT_0(probLen)
-          {
-            UPDATE_0(probLen);
-            probLen = prob + LenMid + (posState << kLenNumMidBits);
-            offset = kLenNumLowSymbols;
-            limit = (1 << kLenNumMidBits);
-          }
-          else
-          {
-            UPDATE_1(probLen);
-            probLen = prob + LenHigh;
-            offset = kLenNumLowSymbols + kLenNumMidSymbols;
-            limit = (1 << kLenNumHighBits);
-          }
-        }
-        TREE_DECODE(probLen, limit, len);
-        len += offset;
-      }
-
-      if (state >= kNumStates)
-      {
-        UInt32 distance;
-        prob = probs + PosSlot +
-            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
-        TREE_6_DECODE(prob, distance);
-        if (distance >= kStartPosModelIndex)
-        {
-          unsigned posSlot = (unsigned)distance;
-          int numDirectBits = (int)(((distance >> 1) - 1));
-          distance = (2 | (distance & 1));
-          if (posSlot < kEndPosModelIndex)
-          {
-            distance <<= numDirectBits;
-            prob = probs + SpecPos + distance - posSlot - 1;
-            {
-              UInt32 mask = 1;
-              unsigned i = 1;
-              do
-              {
-                GET_BIT2(prob + i, i, ; , distance |= mask);
-                mask <<= 1;
-              }
-              while(--numDirectBits != 0);
-            }
-          }
-          else
-          {
-            numDirectBits -= kNumAlignBits;
-            do
-            {
-              NORMALIZE
-              range >>= 1;
-
-              {
-                UInt32 t;
-                code -= range;
-                t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
-                distance = (distance << 1) + (t + 1);
-                code += range & t;
-              }
-              /*
-              distance <<= 1;
-              if (code >= range)
-              {
-                code -= range;
-                distance |= 1;
-              }
-              */
-            }
-            while (--numDirectBits != 0);
-            prob = probs + Align;
-            distance <<= kNumAlignBits;
-            {
-              unsigned i = 1;
-              GET_BIT2(prob + i, i, ; , distance |= 1);
-              GET_BIT2(prob + i, i, ; , distance |= 2);
-              GET_BIT2(prob + i, i, ; , distance |= 4);
-              GET_BIT2(prob + i, i, ; , distance |= 8);
-            }
-            if (distance == (UInt32)0xFFFFFFFF)
-            {
-              len += kMatchSpecLenStart;
-              state -= kNumStates;
-              break;
-            }
-          }
-        }
-        rep3 = rep2;
-        rep2 = rep1;
-        rep1 = rep0;
-        rep0 = distance + 1;
-        if (checkDicSize == 0)
-        {
-          if (distance >= processedPos)
-            return SZ_ERROR_DATA;
-        }
-        else if (distance >= checkDicSize)
-          return SZ_ERROR_DATA;
-        state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
-        /* state = kLiteralNextStates[state]; */
-      }
-
-      len += kMatchMinLen;
-
-      {
-        SizeT rem = limit - dicPos;
-        unsigned curLen = ((rem < len) ? (unsigned)rem : len);
-        SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
-
-        processedPos += curLen;
-
-        len -= curLen;
-        if (pos + curLen <= dicBufSize)
-        {
-          Byte *dest = dic + dicPos;
-          ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
-          const Byte *lim = dest + curLen;
-          dicPos += curLen;
-          do
-            *(dest) = (Byte)*(dest + src);
-          while (++dest != lim);
-        }
-        else
-        {
-          do
-          {
-            dic[dicPos++] = dic[pos];
-            if (++pos == dicBufSize)
-              pos = 0;
-          }
-          while (--curLen != 0);
-        }
-      }
-    }
-  }
-  while (dicPos < limit && buf < bufLimit);
-  NORMALIZE;
-  p->buf = buf;
-  p->range = range;
-  p->code = code;
-  p->remainLen = len;
-  p->dicPos = dicPos;
-  p->processedPos = processedPos;
-  p->reps[0] = rep0;
-  p->reps[1] = rep1;
-  p->reps[2] = rep2;
-  p->reps[3] = rep3;
-  p->state = state;
-
-  return SZ_OK;
-}
-
-static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
-{
-  if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
-  {
-    Byte *dic = p->dic;
-    SizeT dicPos = p->dicPos;
-    SizeT dicBufSize = p->dicBufSize;
-    unsigned len = p->remainLen;
-    UInt32 rep0 = p->reps[0];
-    if (limit - dicPos < len)
-      len = (unsigned)(limit - dicPos);
-
-    if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
-      p->checkDicSize = p->prop.dicSize;
-
-    p->processedPos += len;
-    p->remainLen -= len;
-    while (len-- != 0)
-    {
-      dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
-      dicPos++;
-    }
-    p->dicPos = dicPos;
-  }
-}
-
-/* LzmaDec_DecodeReal2 decodes LZMA-symbols and sets p->needFlush and p->needInit, if required. */
-
-static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
-{
-  do
-  {
-    SizeT limit2 = limit;
-    if (p->checkDicSize == 0)
-    {
-      UInt32 rem = p->prop.dicSize - p->processedPos;
-      if (limit - p->dicPos > rem)
-        limit2 = p->dicPos + rem;
-    }
-    RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
-    if (p->processedPos >= p->prop.dicSize)
-      p->checkDicSize = p->prop.dicSize;
-    LzmaDec_WriteRem(p, limit);
-  }
-  while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
-
-  if (p->remainLen > kMatchSpecLenStart)
-  {
-    p->remainLen = kMatchSpecLenStart;
-  }
-  return 0;
-}
-
-typedef enum
-{
-  DUMMY_ERROR, /* unexpected end of input stream */
-  DUMMY_LIT,
-  DUMMY_MATCH,
-  DUMMY_REP
-} ELzmaDummy;
-
-static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
-{
-  UInt32 range = p->range;
-  UInt32 code = p->code;
-  const Byte *bufLimit = buf + inSize;
-  CLzmaProb *probs = p->probs;
-  unsigned state = p->state;
-  ELzmaDummy res;
-
-  {
-    CLzmaProb *prob;
-    UInt32 bound;
-    unsigned ttt;
-    unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
-
-    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
-    IF_BIT_0_CHECK(prob)
-    {
-      UPDATE_0_CHECK
-
-      /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
-
-      prob = probs + Literal;
-      if (p->checkDicSize != 0 || p->processedPos != 0)
-        prob += (LZMA_LIT_SIZE *
-          ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
-          (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
-
-      if (state < kNumLitStates)
-      {
-        unsigned symbol = 1;
-        do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
-      }
-      else
-      {
-        unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
-            ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
-        unsigned offs = 0x100;
-        unsigned symbol = 1;
-        do
-        {
-          unsigned bit;
-          CLzmaProb *probLit;
-          matchByte <<= 1;
-          bit = (matchByte & offs);
-          probLit = prob + offs + bit + symbol;
-          GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
-        }
-        while (symbol < 0x100);
-      }
-      res = DUMMY_LIT;
-    }
-    else
-    {
-      unsigned len;
-      UPDATE_1_CHECK;
-
-      prob = probs + IsRep + state;
-      IF_BIT_0_CHECK(prob)
-      {
-        UPDATE_0_CHECK;
-        state = 0;
-        prob = probs + LenCoder;
-        res = DUMMY_MATCH;
-      }
-      else
-      {
-        UPDATE_1_CHECK;
-        res = DUMMY_REP;
-        prob = probs + IsRepG0 + state;
-        IF_BIT_0_CHECK(prob)
-        {
-          UPDATE_0_CHECK;
-          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
-          IF_BIT_0_CHECK(prob)
-          {
-            UPDATE_0_CHECK;
-            NORMALIZE_CHECK;
-            return DUMMY_REP;
-          }
-          else
-          {
-            UPDATE_1_CHECK;
-          }
-        }
-        else
-        {
-          UPDATE_1_CHECK;
-          prob = probs + IsRepG1 + state;
-          IF_BIT_0_CHECK(prob)
-          {
-            UPDATE_0_CHECK;
-          }
-          else
-          {
-            UPDATE_1_CHECK;
-            prob = probs + IsRepG2 + state;
-            IF_BIT_0_CHECK(prob)
-            {
-              UPDATE_0_CHECK;
-            }
-            else
-            {
-              UPDATE_1_CHECK;
-            }
-          }
-        }
-        state = kNumStates;
-        prob = probs + RepLenCoder;
-      }
-      {
-        unsigned limit, offset;
-        CLzmaProb *probLen = prob + LenChoice;
-        IF_BIT_0_CHECK(probLen)
-        {
-          UPDATE_0_CHECK;
-          probLen = prob + LenLow + (posState << kLenNumLowBits);
-          offset = 0;
-          limit = 1 << kLenNumLowBits;
-        }
-        else
-        {
-          UPDATE_1_CHECK;
-          probLen = prob + LenChoice2;
-          IF_BIT_0_CHECK(probLen)
-          {
-            UPDATE_0_CHECK;
-            probLen = prob + LenMid + (posState << kLenNumMidBits);
-            offset = kLenNumLowSymbols;
-            limit = 1 << kLenNumMidBits;
-          }
-          else
-          {
-            UPDATE_1_CHECK;
-            probLen = prob + LenHigh;
-            offset = kLenNumLowSymbols + kLenNumMidSymbols;
-            limit = 1 << kLenNumHighBits;
-          }
-        }
-        TREE_DECODE_CHECK(probLen, limit, len);
-        len += offset;
-      }
-
-      if (state < 4)
-      {
-        unsigned posSlot;
-        prob = probs + PosSlot +
-            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
-            kNumPosSlotBits);
-        TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
-        if (posSlot >= kStartPosModelIndex)
-        {
-          int numDirectBits = ((posSlot >> 1) - 1);
-
-          /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
-
-          if (posSlot < kEndPosModelIndex)
-          {
-            prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
-          }
-          else
-          {
-            numDirectBits -= kNumAlignBits;
-            do
-            {
-              NORMALIZE_CHECK
-              range >>= 1;
-              code -= range & (((code - range) >> 31) - 1);
-              /* if (code >= range) code -= range; */
-            }
-            while (--numDirectBits != 0);
-            prob = probs + Align;
-            numDirectBits = kNumAlignBits;
-          }
-          {
-            unsigned i = 1;
-            do
-            {
-              GET_BIT_CHECK(prob + i, i);
-            }
-            while(--numDirectBits != 0);
-          }
-        }
-      }
-    }
-  }
-  NORMALIZE_CHECK;
-  return res;
-}
-
-
-static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
-{
-  p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
-  p->range = 0xFFFFFFFF;
-  p->needFlush = 0;
-}
-
-void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
-{
-  p->needFlush = 1;
-  p->remainLen = 0;
-  p->tempBufSize = 0;
-
-  if (initDic)
-  {
-    p->processedPos = 0;
-    p->checkDicSize = 0;
-    p->needInitState = 1;
-  }
-  if (initState)
-    p->needInitState = 1;
-}
-
-void LzmaDec_Init(CLzmaDec *p)
-{
-  p->dicPos = 0;
-  LzmaDec_InitDicAndState(p, True, True);
-}
-
-static void LzmaDec_InitStateReal(CLzmaDec *p)
-{
-  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
-  UInt32 i;
-  CLzmaProb *probs = p->probs;
-  for (i = 0; i < numProbs; i++)
-    probs[i] = kBitModelTotal >> 1;
-  p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
-  p->state = 0;
-  p->needInitState = 0;
-}
-
-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
-    ELzmaFinishMode finishMode, ELzmaStatus *status)
-{
-  SizeT inSize = *srcLen;
-  (*srcLen) = 0;
-  LzmaDec_WriteRem(p, dicLimit);
-
-  *status = LZMA_STATUS_NOT_SPECIFIED;
-
-  while (p->remainLen != kMatchSpecLenStart)
-  {
-      int checkEndMarkNow;
-
-      if (p->needFlush != 0)
-      {
-        for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
-          p->tempBuf[p->tempBufSize++] = *src++;
-        if (p->tempBufSize < RC_INIT_SIZE)
-        {
-          *status = LZMA_STATUS_NEEDS_MORE_INPUT;
-          return SZ_OK;
-        }
-        if (p->tempBuf[0] != 0)
-          return SZ_ERROR_DATA;
-
-        LzmaDec_InitRc(p, p->tempBuf);
-        p->tempBufSize = 0;
-      }
-
-      checkEndMarkNow = 0;
-      if (p->dicPos >= dicLimit)
-      {
-        if (p->remainLen == 0 && p->code == 0)
-        {
-          *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
-          return SZ_OK;
-        }
-        if (finishMode == LZMA_FINISH_ANY)
-        {
-          *status = LZMA_STATUS_NOT_FINISHED;
-          return SZ_OK;
-        }
-        if (p->remainLen != 0)
-        {
-          *status = LZMA_STATUS_NOT_FINISHED;
-          return SZ_ERROR_DATA;
-        }
-        checkEndMarkNow = 1;
-      }
-
-      if (p->needInitState)
-        LzmaDec_InitStateReal(p);
-
-      if (p->tempBufSize == 0)
-      {
-        SizeT processed;
-        const Byte *bufLimit;
-        if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
-        {
-          int dummyRes = LzmaDec_TryDummy(p, src, inSize);
-          if (dummyRes == DUMMY_ERROR)
-          {
-            memcpy(p->tempBuf, src, inSize);
-            p->tempBufSize = (unsigned)inSize;
-            (*srcLen) += inSize;
-            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
-            return SZ_OK;
-          }
-          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
-          {
-            *status = LZMA_STATUS_NOT_FINISHED;
-            return SZ_ERROR_DATA;
-          }
-          bufLimit = src;
-        }
-        else
-          bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
-        p->buf = src;
-        if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
-          return SZ_ERROR_DATA;
-        processed = p->buf - src;
-        (*srcLen) += processed;
-        src += processed;
-        inSize -= processed;
-      }
-      else
-      {
-        unsigned rem = p->tempBufSize, lookAhead = 0;
-        while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
-          p->tempBuf[rem++] = src[lookAhead++];
-        p->tempBufSize = rem;
-        if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
-        {
-          int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
-          if (dummyRes == DUMMY_ERROR)
-          {
-            (*srcLen) += lookAhead;
-            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
-            return SZ_OK;
-          }
-          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
-          {
-            *status = LZMA_STATUS_NOT_FINISHED;
-            return SZ_ERROR_DATA;
-          }
-        }
-        p->buf = p->tempBuf;
-        if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
-          return SZ_ERROR_DATA;
-        lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
-        (*srcLen) += lookAhead;
-        src += lookAhead;
-        inSize -= lookAhead;
-        p->tempBufSize = 0;
-      }
-  }
-  if (p->code == 0)
-    *status = LZMA_STATUS_FINISHED_WITH_MARK;
-  return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
-}
-
-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
-{
-  SizeT outSize = *destLen;
-  SizeT inSize = *srcLen;
-  *srcLen = *destLen = 0;
-  for (;;)
-  {
-    SizeT inSizeCur = inSize, outSizeCur, dicPos;
-    ELzmaFinishMode curFinishMode;
-    SRes res;
-    if (p->dicPos == p->dicBufSize)
-      p->dicPos = 0;
-    dicPos = p->dicPos;
-    if (outSize > p->dicBufSize - dicPos)
-    {
-      outSizeCur = p->dicBufSize;
-      curFinishMode = LZMA_FINISH_ANY;
-    }
-    else
-    {
-      outSizeCur = dicPos + outSize;
-      curFinishMode = finishMode;
-    }
-
-    res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
-    src += inSizeCur;
-    inSize -= inSizeCur;
-    *srcLen += inSizeCur;
-    outSizeCur = p->dicPos - dicPos;
-    memcpy(dest, p->dic + dicPos, outSizeCur);
-    dest += outSizeCur;
-    outSize -= outSizeCur;
-    *destLen += outSizeCur;
-    if (res != 0)
-      return res;
-    if (outSizeCur == 0 || outSize == 0)
-      return SZ_OK;
-  }
-}
-
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
-{
-  alloc->Free(alloc, p->probs);
-  p->probs = 0;
-}
-
-static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
-{
-  alloc->Free(alloc, p->dic);
-  p->dic = 0;
-}
-
-void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
-{
-  LzmaDec_FreeProbs(p, alloc);
-  LzmaDec_FreeDict(p, alloc);
-}
-
-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
-{
-  UInt32 dicSize;
-  Byte d;
-
-  if (size < LZMA_PROPS_SIZE)
-    return SZ_ERROR_UNSUPPORTED;
-  else
-    dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
-
-  if (dicSize < LZMA_DIC_MIN)
-    dicSize = LZMA_DIC_MIN;
-  p->dicSize = dicSize;
-
-  d = data[0];
-  if (d >= (9 * 5 * 5))
-    return SZ_ERROR_UNSUPPORTED;
-
-  p->lc = d % 9;
-  d /= 9;
-  p->pb = d / 5;
-  p->lp = d % 5;
-
-  return SZ_OK;
-}
-
-static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
-{
-  UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
-  if (p->probs == 0 || numProbs != p->numProbs)
-  {
-    LzmaDec_FreeProbs(p, alloc);
-    p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
-    p->numProbs = numProbs;
-    if (p->probs == 0)
-      return SZ_ERROR_MEM;
-  }
-  return SZ_OK;
-}
-
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
-{
-  CLzmaProps propNew;
-  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
-  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
-  p->prop = propNew;
-  return SZ_OK;
-}
-
-SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
-{
-  CLzmaProps propNew;
-  SizeT dicBufSize;
-  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
-  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
-  dicBufSize = propNew.dicSize;
-  if (p->dic == 0 || dicBufSize != p->dicBufSize)
-  {
-    LzmaDec_FreeDict(p, alloc);
-    p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
-    if (p->dic == 0)
-    {
-      LzmaDec_FreeProbs(p, alloc);
-      return SZ_ERROR_MEM;
-    }
-  }
-  p->dicBufSize = dicBufSize;
-  p->prop = propNew;
-  return SZ_OK;
-}
-
-SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
-    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
-    ELzmaStatus *status, ISzAlloc *alloc)
-{
-  CLzmaDec p;
-  SRes res;
-  SizeT inSize = *srcLen;
-  SizeT outSize = *destLen;
-  *srcLen = *destLen = 0;
-  if (inSize < RC_INIT_SIZE)
-    return SZ_ERROR_INPUT_EOF;
-
-  LzmaDec_Construct(&p);
-  res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
-  if (res != 0)
-    return res;
-  p.dic = dest;
-  p.dicBufSize = outSize;
-
-  LzmaDec_Init(&p);
-
-  *srcLen = inSize;
-  res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
-
-  if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
-    res = SZ_ERROR_INPUT_EOF;
-
-  (*destLen) = p.dicPos;
-  LzmaDec_FreeProbs(&p, alloc);
-  return res;
-}
diff --git a/lib/LzmaEnc.c b/lib/LzmaEnc.c
deleted file mode 100644 (file)
index 842d43a..0000000
+++ /dev/null
@@ -1,2355 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (c) 1999-2008 Igor Pavlov
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * This code was taken from LZMA SDK 4.58 beta, and was slightly modified
- * to adapt it to GRUB's requirement.
- *
- * See <http://www.7-zip.org>, for more information about LZMA.
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include <grub/lib/LzmaEnc.h>
-
-#include <grub/lib/LzFind.h>
-#ifdef COMPRESS_MF_MT
-#include <grub/lib/LzFindMt.h>
-#endif
-
-/* #define SHOW_STAT */
-/* #define SHOW_STAT2 */
-
-#ifdef SHOW_STAT
-static int ttt = 0;
-#endif
-
-#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
-
-#define kBlockSize (9 << 10)
-#define kUnpackBlockSize (1 << 18)
-#define kMatchArraySize (1 << 21)
-#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
-
-#define kNumMaxDirectBits (31)
-
-#define kNumTopBits 24
-#define kTopValue ((UInt32)1 << kNumTopBits)
-
-#define kNumBitModelTotalBits 11
-#define kBitModelTotal (1 << kNumBitModelTotalBits)
-#define kNumMoveBits 5
-#define kProbInitValue (kBitModelTotal >> 1)
-
-#define kNumMoveReducingBits 4
-#define kNumBitPriceShiftBits 4
-#define kBitPrice (1 << kNumBitPriceShiftBits)
-
-void LzmaEncProps_Init(CLzmaEncProps *p)
-{
-  p->level = 5;
-  p->dictSize = p->mc = 0;
-  p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
-  p->writeEndMark = 0;
-}
-
-void LzmaEncProps_Normalize(CLzmaEncProps *p)
-{
-  int level = p->level;
-  if (level < 0) level = 5;
-  p->level = level;
-  if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
-  if (p->lc < 0) p->lc = 3;
-  if (p->lp < 0) p->lp = 0;
-  if (p->pb < 0) p->pb = 2;
-  if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
-  if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
-  if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
-  if (p->numHashBytes < 0) p->numHashBytes = 4;
-  if (p->mc == 0)  p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
-  if (p->numThreads < 0) p->numThreads = ((p->btMode && p->algo) ? 2 : 1);
-}
-
-UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
-{
-  CLzmaEncProps props = *props2;
-  LzmaEncProps_Normalize(&props);
-  return props.dictSize;
-}
-
-/* #define LZMA_LOG_BSR */
-/* Define it for Intel's CPU */
-
-
-#ifdef LZMA_LOG_BSR
-
-#define kDicLogSizeMaxCompress 30
-
-#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
-
-UInt32 GetPosSlot1(UInt32 pos)
-{
-  UInt32 res;
-  BSR2_RET(pos, res);
-  return res;
-}
-#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
-#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
-
-#else
-
-#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
-#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
-
-void LzmaEnc_FastPosInit(Byte *g_FastPos)
-{
-  int c = 2, slotFast;
-  g_FastPos[0] = 0;
-  g_FastPos[1] = 1;
-
-  for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
-  {
-    UInt32 k = (1 << ((slotFast >> 1) - 1));
-    UInt32 j;
-    for (j = 0; j < k; j++, c++)
-      g_FastPos[c] = (Byte)slotFast;
-  }
-}
-
-#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
-  (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
-  res = p->g_FastPos[pos >> i] + (i * 2); }
-/*
-#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
-  p->g_FastPos[pos >> 6] + 12 : \
-  p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
-*/
-
-#define GetPosSlot1(pos) p->g_FastPos[pos]
-#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
-#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
-
-#endif
-
-
-#define LZMA_NUM_REPS 4
-
-typedef unsigned CState;
-
-typedef struct _COptimal
-{
-  UInt32 price;
-
-  CState state;
-  int prev1IsChar;
-  int prev2;
-
-  UInt32 posPrev2;
-  UInt32 backPrev2;
-
-  UInt32 posPrev;
-  UInt32 backPrev;
-  UInt32 backs[LZMA_NUM_REPS];
-} COptimal;
-
-#define kNumOpts (1 << 12)
-
-#define kNumLenToPosStates 4
-#define kNumPosSlotBits 6
-#define kDicLogSizeMin 0
-#define kDicLogSizeMax 32
-#define kDistTableSizeMax (kDicLogSizeMax * 2)
-
-
-#define kNumAlignBits 4
-#define kAlignTableSize (1 << kNumAlignBits)
-#define kAlignMask (kAlignTableSize - 1)
-
-#define kStartPosModelIndex 4
-#define kEndPosModelIndex 14
-#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
-
-#define kNumFullDistances (1 << (kEndPosModelIndex / 2))
-
-#ifdef _LZMA_PROB32
-#define CLzmaProb UInt32
-#else
-#define CLzmaProb UInt16
-#endif
-
-#define LZMA_PB_MAX 4
-#define LZMA_LC_MAX 8
-#define LZMA_LP_MAX 4
-
-#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
-
-
-#define kLenNumLowBits 3
-#define kLenNumLowSymbols (1 << kLenNumLowBits)
-#define kLenNumMidBits 3
-#define kLenNumMidSymbols (1 << kLenNumMidBits)
-#define kLenNumHighBits 8
-#define kLenNumHighSymbols (1 << kLenNumHighBits)
-
-#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
-
-#define LZMA_MATCH_LEN_MIN 2
-#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
-
-#define kNumStates 12
-
-typedef struct
-{
-  CLzmaProb choice;
-  CLzmaProb choice2;
-  CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
-  CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
-  CLzmaProb high[kLenNumHighSymbols];
-} CLenEnc;
-
-typedef struct
-{
-  CLenEnc p;
-  UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
-  UInt32 tableSize;
-  UInt32 counters[LZMA_NUM_PB_STATES_MAX];
-} CLenPriceEnc;
-
-typedef struct _CRangeEnc
-{
-  UInt32 range;
-  Byte cache;
-  UInt64 low;
-  UInt64 cacheSize;
-  Byte *buf;
-  Byte *bufLim;
-  Byte *bufBase;
-  ISeqOutStream *outStream;
-  UInt64 processed;
-  SRes res;
-} CRangeEnc;
-
-typedef struct _CSeqInStreamBuf
-{
-  ISeqInStream funcTable;
-  const Byte *data;
-  SizeT rem;
-} CSeqInStreamBuf;
-
-static SRes MyRead(void *pp, void *data, size_t *size)
-{
-  size_t curSize = *size;
-  CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp;
-  if (p->rem < curSize)
-    curSize = p->rem;
-  memcpy(data, p->data, curSize);
-  p->rem -= curSize;
-  p->data += curSize;
-  *size = curSize;
-  return SZ_OK;
-}
-
-typedef struct
-{
-  CLzmaProb *litProbs;
-
-  CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
-  CLzmaProb isRep[kNumStates];
-  CLzmaProb isRepG0[kNumStates];
-  CLzmaProb isRepG1[kNumStates];
-  CLzmaProb isRepG2[kNumStates];
-  CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
-
-  CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
-  CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
-  CLzmaProb posAlignEncoder[1 << kNumAlignBits];
-
-  CLenPriceEnc lenEnc;
-  CLenPriceEnc repLenEnc;
-
-  UInt32 reps[LZMA_NUM_REPS];
-  UInt32 state;
-} CSaveState;
-
-typedef struct _CLzmaEnc
-{
-  IMatchFinder matchFinder;
-  void *matchFinderObj;
-
-  #ifdef COMPRESS_MF_MT
-  Bool mtMode;
-  CMatchFinderMt matchFinderMt;
-  #endif
-
-  CMatchFinder matchFinderBase;
-
-  #ifdef COMPRESS_MF_MT
-  Byte pad[128];
-  #endif
-
-  UInt32 optimumEndIndex;
-  UInt32 optimumCurrentIndex;
-
-  Bool longestMatchWasFound;
-  UInt32 longestMatchLength;
-  UInt32 numDistancePairs;
-
-  COptimal opt[kNumOpts];
-
-  #ifndef LZMA_LOG_BSR
-  Byte g_FastPos[1 << kNumLogBits];
-  #endif
-
-  UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
-  UInt32 matchDistances[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
-  UInt32 numFastBytes;
-  UInt32 additionalOffset;
-  UInt32 reps[LZMA_NUM_REPS];
-  UInt32 state;
-
-  UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
-  UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
-  UInt32 alignPrices[kAlignTableSize];
-  UInt32 alignPriceCount;
-
-  UInt32 distTableSize;
-
-  unsigned lc, lp, pb;
-  unsigned lpMask, pbMask;
-
-  CLzmaProb *litProbs;
-
-  CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
-  CLzmaProb isRep[kNumStates];
-  CLzmaProb isRepG0[kNumStates];
-  CLzmaProb isRepG1[kNumStates];
-  CLzmaProb isRepG2[kNumStates];
-  CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
-
-  CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
-  CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
-  CLzmaProb posAlignEncoder[1 << kNumAlignBits];
-
-  CLenPriceEnc lenEnc;
-  CLenPriceEnc repLenEnc;
-
-  unsigned lclp;
-
-  Bool fastMode;
-
-  CRangeEnc rc;
-
-  Bool writeEndMark;
-  UInt64 nowPos64;
-  UInt32 matchPriceCount;
-  Bool finished;
-  Bool multiThread;
-
-  SRes result;
-  UInt32 dictSize;
-  UInt32 matchFinderCycles;
-
-  ISeqInStream *inStream;
-  CSeqInStreamBuf seqBufInStream;
-
-  CSaveState saveState;
-} CLzmaEnc;
-
-void LzmaEnc_SaveState(CLzmaEncHandle pp)
-{
-  CLzmaEnc *p = (CLzmaEnc *)pp;
-  CSaveState *dest = &p->saveState;
-  int i;
-  dest->lenEnc = p->lenEnc;
-  dest->repLenEnc = p->repLenEnc;
-  dest->state = p->state;
-
-  for (i = 0; i < kNumStates; i++)
-  {
-    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
-    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
-  }
-  for (i = 0; i < kNumLenToPosStates; i++)
-    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
-  memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
-  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
-  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
-  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
-  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
-  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
-  memcpy(dest->reps, p->reps, sizeof(p->reps));
-  memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
-}
-
-void LzmaEnc_RestoreState(CLzmaEncHandle pp)
-{
-  CLzmaEnc *dest = (CLzmaEnc *)pp;
-  const CSaveState *p = &dest->saveState;
-  int i;
-  dest->lenEnc = p->lenEnc;
-  dest->repLenEnc = p->repLenEnc;
-  dest->state = p->state;
-
-  for (i = 0; i < kNumStates; i++)
-  {
-    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
-    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
-  }
-  for (i = 0; i < kNumLenToPosStates; i++)
-    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
-  memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
-  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
-  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
-  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
-  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
-  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
-  memcpy(dest->reps, p->reps, sizeof(p->reps));
-  memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
-}
-
-SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
-{
-  CLzmaEnc *p = (CLzmaEnc *)pp;
-  CLzmaEncProps props = *props2;
-  LzmaEncProps_Normalize(&props);
-
-  if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
-      props.dictSize > (1U << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
-    return SZ_ERROR_PARAM;
-  p->dictSize = props.dictSize;
-  p->matchFinderCycles = props.mc;
-  {
-    unsigned fb = props.fb;
-    if (fb < 5)
-      fb = 5;
-    if (fb > LZMA_MATCH_LEN_MAX)
-      fb = LZMA_MATCH_LEN_MAX;
-    p->numFastBytes = fb;
-  }
-  p->lc = props.lc;
-  p->lp = props.lp;
-  p->pb = props.pb;
-  p->fastMode = (props.algo == 0);
-  p->matchFinderBase.btMode = props.btMode;
-  {
-    UInt32 numHashBytes = 4;
-    if (props.btMode)
-    {
-      if (props.numHashBytes < 2)
-        numHashBytes = 2;
-      else if (props.numHashBytes < 4)
-        numHashBytes = props.numHashBytes;
-    }
-    p->matchFinderBase.numHashBytes = numHashBytes;
-  }
-
-  p->matchFinderBase.cutValue = props.mc;
-
-  p->writeEndMark = props.writeEndMark;
-
-  #ifdef COMPRESS_MF_MT
-  /*
-  if (newMultiThread != _multiThread)
-  {
-    ReleaseMatchFinder();
-    _multiThread = newMultiThread;
-  }
-  */
-  p->multiThread = (props.numThreads > 1);
-  #endif
-
-  return SZ_OK;
-}
-
-static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4,  5,  6,   4, 5};
-static const int kMatchNextStates[kNumStates]   = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
-static const int kRepNextStates[kNumStates]     = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
-static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
-
-/*
-  void UpdateChar() { Index = kLiteralNextStates[Index]; }
-  void UpdateMatch() { Index = kMatchNextStates[Index]; }
-  void UpdateRep() { Index = kRepNextStates[Index]; }
-  void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
-*/
-
-#define IsCharState(s) ((s) < 7)
-
-
-#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
-
-#define kInfinityPrice (1 << 30)
-
-static void RangeEnc_Construct(CRangeEnc *p)
-{
-  p->outStream = 0;
-  p->bufBase = 0;
-}
-
-#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
-
-#define RC_BUF_SIZE (1 << 16)
-static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
-{
-  if (p->bufBase == 0)
-  {
-    p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
-    if (p->bufBase == 0)
-      return 0;
-    p->bufLim = p->bufBase + RC_BUF_SIZE;
-  }
-  return 1;
-}
-
-static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
-{
-  alloc->Free(alloc, p->bufBase);
-  p->bufBase = 0;
-}
-
-static void RangeEnc_Init(CRangeEnc *p)
-{
-  /* Stream.Init(); */
-  p->low = 0;
-  p->range = 0xFFFFFFFF;
-  p->cacheSize = 1;
-  p->cache = 0;
-
-  p->buf = p->bufBase;
-
-  p->processed = 0;
-  p->res = SZ_OK;
-}
-
-static void RangeEnc_FlushStream(CRangeEnc *p)
-{
-  size_t num;
-  if (p->res != SZ_OK)
-    return;
-  num = p->buf - p->bufBase;
-  if (num != p->outStream->Write(p->outStream, p->bufBase, num))
-    p->res = SZ_ERROR_WRITE;
-  p->processed += num;
-  p->buf = p->bufBase;
-}
-
-static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
-{
-  if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
-  {
-    Byte temp = p->cache;
-    do
-    {
-      Byte *buf = p->buf;
-      *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
-      p->buf = buf;
-      if (buf == p->bufLim)
-        RangeEnc_FlushStream(p);
-      temp = 0xFF;
-    }
-    while (--p->cacheSize != 0);
-    p->cache = (Byte)((UInt32)p->low >> 24);
-  }
-  p->cacheSize++;
-  p->low = (UInt32)p->low << 8;
-}
-
-static void RangeEnc_FlushData(CRangeEnc *p)
-{
-  int i;
-  for (i = 0; i < 5; i++)
-    RangeEnc_ShiftLow(p);
-}
-
-static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
-{
-  do
-  {
-    p->range >>= 1;
-    p->low += p->range & (0 - ((value >> --numBits) & 1));
-    if (p->range < kTopValue)
-    {
-      p->range <<= 8;
-      RangeEnc_ShiftLow(p);
-    }
-  }
-  while (numBits != 0);
-}
-
-static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
-{
-  UInt32 ttt = *prob;
-  UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
-  if (symbol == 0)
-  {
-    p->range = newBound;
-    ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
-  }
-  else
-  {
-    p->low += newBound;
-    p->range -= newBound;
-    ttt -= ttt >> kNumMoveBits;
-  }
-  *prob = (CLzmaProb)ttt;
-  if (p->range < kTopValue)
-  {
-    p->range <<= 8;
-    RangeEnc_ShiftLow(p);
-  }
-}
-
-static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
-{
-  symbol |= 0x100;
-  do
-  {
-    RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
-    symbol <<= 1;
-  }
-  while (symbol < 0x10000);
-}
-
-static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
-{
-  UInt32 offs = 0x100;
-  symbol |= 0x100;
-  do
-  {
-    matchByte <<= 1;
-    RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
-    symbol <<= 1;
-    offs &= ~(matchByte ^ symbol);
-  }
-  while (symbol < 0x10000);
-}
-
-void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
-{
-  UInt32 i;
-  for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
-  {
-    const int kCyclesBits = kNumBitPriceShiftBits;
-    UInt32 w = i;
-    UInt32 bitCount = 0;
-    int j;
-    for (j = 0; j < kCyclesBits; j++)
-    {
-      w = w * w;
-      bitCount <<= 1;
-      while (w >= ((UInt32)1 << 16))
-      {
-        w >>= 1;
-        bitCount++;
-      }
-    }
-    ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
-  }
-}
-
-
-#define GET_PRICE(prob, symbol) \
-  p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
-
-#define GET_PRICEa(prob, symbol) \
-  ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
-
-#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
-#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
-
-#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
-#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
-
-static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
-{
-  UInt32 price = 0;
-  symbol |= 0x100;
-  do
-  {
-    price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
-    symbol <<= 1;
-  }
-  while (symbol < 0x10000);
-  return price;
-};
-
-static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
-{
-  UInt32 price = 0;
-  UInt32 offs = 0x100;
-  symbol |= 0x100;
-  do
-  {
-    matchByte <<= 1;
-    price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);
-    symbol <<= 1;
-    offs &= ~(matchByte ^ symbol);
-  }
-  while (symbol < 0x10000);
-  return price;
-};
-
-
-static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
-{
-  UInt32 m = 1;
-  int i;
-  for (i = numBitLevels; i != 0 ;)
-  {
-    UInt32 bit;
-    i--;
-    bit = (symbol >> i) & 1;
-    RangeEnc_EncodeBit(rc, probs + m, bit);
-    m = (m << 1) | bit;
-  }
-};
-
-static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
-{
-  UInt32 m = 1;
-  int i;
-  for (i = 0; i < numBitLevels; i++)
-  {
-    UInt32 bit = symbol & 1;
-    RangeEnc_EncodeBit(rc, probs + m, bit);
-    m = (m << 1) | bit;
-    symbol >>= 1;
-  }
-}
-
-static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
-{
-  UInt32 price = 0;
-  symbol |= (1 << numBitLevels);
-  while (symbol != 1)
-  {
-    price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
-    symbol >>= 1;
-  }
-  return price;
-}
-
-static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
-{
-  UInt32 price = 0;
-  UInt32 m = 1;
-  int i;
-  for (i = numBitLevels; i != 0; i--)
-  {
-    UInt32 bit = symbol & 1;
-    symbol >>= 1;
-    price += GET_PRICEa(probs[m], bit);
-    m = (m << 1) | bit;
-  }
-  return price;
-}
-
-
-static void LenEnc_Init(CLenEnc *p)
-{
-  unsigned i;
-  p->choice = p->choice2 = kProbInitValue;
-  for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
-    p->low[i] = kProbInitValue;
-  for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
-    p->mid[i] = kProbInitValue;
-  for (i = 0; i < kLenNumHighSymbols; i++)
-    p->high[i] = kProbInitValue;
-}
-
-static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
-{
-  if (symbol < kLenNumLowSymbols)
-  {
-    RangeEnc_EncodeBit(rc, &p->choice, 0);
-    RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
-  }
-  else
-  {
-    RangeEnc_EncodeBit(rc, &p->choice, 1);
-    if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
-    {
-      RangeEnc_EncodeBit(rc, &p->choice2, 0);
-      RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
-    }
-    else
-    {
-      RangeEnc_EncodeBit(rc, &p->choice2, 1);
-      RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
-    }
-  }
-}
-
-static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
-{
-  UInt32 a0 = GET_PRICE_0a(p->choice);
-  UInt32 a1 = GET_PRICE_1a(p->choice);
-  UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
-  UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
-  UInt32 i = 0;
-  for (i = 0; i < kLenNumLowSymbols; i++)
-  {
-    if (i >= numSymbols)
-      return;
-    prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
-  }
-  for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
-  {
-    if (i >= numSymbols)
-      return;
-    prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
-  }
-  for (; i < numSymbols; i++)
-    prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
-}
-
-static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
-{
-  LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
-  p->counters[posState] = p->tableSize;
-}
-
-static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
-{
-  UInt32 posState;
-  for (posState = 0; posState < numPosStates; posState++)
-    LenPriceEnc_UpdateTable(p, posState, ProbPrices);
-}
-
-static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
-{
-  LenEnc_Encode(&p->p, rc, symbol, posState);
-  if (updatePrice)
-    if (--p->counters[posState] == 0)
-      LenPriceEnc_UpdateTable(p, posState, ProbPrices);
-}
-
-
-
-
-static void MovePos(CLzmaEnc *p, UInt32 num)
-{
-  #ifdef SHOW_STAT
-  ttt += num;
-  printf("\n MovePos %d", num);
-  #endif
-  if (num != 0)
-  {
-    p->additionalOffset += num;
-    p->matchFinder.Skip(p->matchFinderObj, num);
-  }
-}
-
-static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
-{
-  UInt32 lenRes = 0, numDistancePairs;
-  numDistancePairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matchDistances);
-  #ifdef SHOW_STAT
-  printf("\n i = %d numPairs = %d    ", ttt, numDistancePairs / 2);
-  if (ttt >= 61994)
-    ttt = ttt;
-
-  ttt++;
-  {
-    UInt32 i;
-  for (i = 0; i < numDistancePairs; i += 2)
-    printf("%2d %6d   | ", p->matchDistances[i], p->matchDistances[i + 1]);
-  }
-  #endif
-  if (numDistancePairs > 0)
-  {
-    lenRes = p->matchDistances[numDistancePairs - 2];
-    if (lenRes == p->numFastBytes)
-    {
-      UInt32 numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) + 1;
-      const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-      UInt32 distance = p->matchDistances[numDistancePairs - 1] + 1;
-      if (numAvail > LZMA_MATCH_LEN_MAX)
-        numAvail = LZMA_MATCH_LEN_MAX;
-
-      {
-        const Byte *pby2 = pby - distance;
-        for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
-      }
-    }
-  }
-  p->additionalOffset++;
-  *numDistancePairsRes = numDistancePairs;
-  return lenRes;
-}
-
-
-#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
-#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
-#define IsShortRep(p) ((p)->backPrev == 0)
-
-static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
-{
-  return
-    GET_PRICE_0(p->isRepG0[state]) +
-    GET_PRICE_0(p->isRep0Long[state][posState]);
-}
-
-static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
-{
-  UInt32 price;
-  if (repIndex == 0)
-  {
-    price = GET_PRICE_0(p->isRepG0[state]);
-    price += GET_PRICE_1(p->isRep0Long[state][posState]);
-  }
-  else
-  {
-    price = GET_PRICE_1(p->isRepG0[state]);
-    if (repIndex == 1)
-      price += GET_PRICE_0(p->isRepG1[state]);
-    else
-    {
-      price += GET_PRICE_1(p->isRepG1[state]);
-      price += GET_PRICE(p->isRepG2[state], repIndex - 2);
-    }
-  }
-  return price;
-}
-
-static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
-{
-  return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
-    GetPureRepPrice(p, repIndex, state, posState);
-}
-
-static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
-{
-  UInt32 posMem = p->opt[cur].posPrev;
-  UInt32 backMem = p->opt[cur].backPrev;
-  p->optimumEndIndex = cur;
-  do
-  {
-    if (p->opt[cur].prev1IsChar)
-    {
-      MakeAsChar(&p->opt[posMem])
-      p->opt[posMem].posPrev = posMem - 1;
-      if (p->opt[cur].prev2)
-      {
-        p->opt[posMem - 1].prev1IsChar = False;
-        p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
-        p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
-      }
-    }
-    {
-      UInt32 posPrev = posMem;
-      UInt32 backCur = backMem;
-
-      backMem = p->opt[posPrev].backPrev;
-      posMem = p->opt[posPrev].posPrev;
-
-      p->opt[posPrev].backPrev = backCur;
-      p->opt[posPrev].posPrev = cur;
-      cur = posPrev;
-    }
-  }
-  while (cur != 0);
-  *backRes = p->opt[0].backPrev;
-  p->optimumCurrentIndex  = p->opt[0].posPrev;
-  return p->optimumCurrentIndex;
-}
-
-#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
-
-static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
-{
-  UInt32 numAvailableBytes, lenMain, numDistancePairs;
-  const Byte *data;
-  UInt32 reps[LZMA_NUM_REPS];
-  UInt32 repLens[LZMA_NUM_REPS];
-  UInt32 repMaxIndex, i;
-  UInt32 *matchDistances;
-  Byte currentByte, matchByte;
-  UInt32 posState;
-  UInt32 matchPrice, repMatchPrice;
-  UInt32 lenEnd;
-  UInt32 len;
-  UInt32 normalMatchPrice;
-  UInt32 cur;
-  if (p->optimumEndIndex != p->optimumCurrentIndex)
-  {
-    const COptimal *opt = &p->opt[p->optimumCurrentIndex];
-    UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
-    *backRes = opt->backPrev;
-    p->optimumCurrentIndex = opt->posPrev;
-    return lenRes;
-  }
-  p->optimumCurrentIndex = p->optimumEndIndex = 0;
-
-  numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
-
-  if (!p->longestMatchWasFound)
-  {
-    lenMain = ReadMatchDistances(p, &numDistancePairs);
-  }
-  else
-  {
-    lenMain = p->longestMatchLength;
-    numDistancePairs = p->numDistancePairs;
-    p->longestMatchWasFound = False;
-  }
-
-  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-  if (numAvailableBytes < 2)
-  {
-    *backRes = (UInt32)(-1);
-    return 1;
-  }
-  if (numAvailableBytes > LZMA_MATCH_LEN_MAX)
-    numAvailableBytes = LZMA_MATCH_LEN_MAX;
-
-  repMaxIndex = 0;
-  for (i = 0; i < LZMA_NUM_REPS; i++)
-  {
-    UInt32 lenTest;
-    const Byte *data2;
-    reps[i] = p->reps[i];
-    data2 = data - (reps[i] + 1);
-    if (data[0] != data2[0] || data[1] != data2[1])
-    {
-      repLens[i] = 0;
-      continue;
-    }
-    for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++);
-    repLens[i] = lenTest;
-    if (lenTest > repLens[repMaxIndex])
-      repMaxIndex = i;
-  }
-  if (repLens[repMaxIndex] >= p->numFastBytes)
-  {
-    UInt32 lenRes;
-    *backRes = repMaxIndex;
-    lenRes = repLens[repMaxIndex];
-    MovePos(p, lenRes - 1);
-    return lenRes;
-  }
-
-  matchDistances = p->matchDistances;
-  if (lenMain >= p->numFastBytes)
-  {
-    *backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS;
-    MovePos(p, lenMain - 1);
-    return lenMain;
-  }
-  currentByte = *data;
-  matchByte = *(data - (reps[0] + 1));
-
-  if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
-  {
-    *backRes = (UInt32)-1;
-    return 1;
-  }
-
-  p->opt[0].state = (CState)p->state;
-
-  posState = (position & p->pbMask);
-
-  {
-    const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
-    p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
-        (!IsCharState(p->state) ?
-          LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) :
-          LitEnc_GetPrice(probs, currentByte, p->ProbPrices));
-  }
-
-  MakeAsChar(&p->opt[1]);
-
-  matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
-  repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
-
-  if (matchByte == currentByte)
-  {
-    UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
-    if (shortRepPrice < p->opt[1].price)
-    {
-      p->opt[1].price = shortRepPrice;
-      MakeAsShortRep(&p->opt[1]);
-    }
-  }
-  lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
-
-  if (lenEnd < 2)
-  {
-    *backRes = p->opt[1].backPrev;
-    return 1;
-  }
-
-  p->opt[1].posPrev = 0;
-  for (i = 0; i < LZMA_NUM_REPS; i++)
-    p->opt[0].backs[i] = reps[i];
-
-  len = lenEnd;
-  do
-    p->opt[len--].price = kInfinityPrice;
-  while (len >= 2);
-
-  for (i = 0; i < LZMA_NUM_REPS; i++)
-  {
-    UInt32 repLen = repLens[i];
-    UInt32 price;
-    if (repLen < 2)
-      continue;
-    price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
-    do
-    {
-      UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
-      COptimal *opt = &p->opt[repLen];
-      if (curAndLenPrice < opt->price)
-      {
-        opt->price = curAndLenPrice;
-        opt->posPrev = 0;
-        opt->backPrev = i;
-        opt->prev1IsChar = False;
-      }
-    }
-    while (--repLen >= 2);
-  }
-
-  normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
-
-  len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
-  if (len <= lenMain)
-  {
-    UInt32 offs = 0;
-    while (len > matchDistances[offs])
-      offs += 2;
-    for (; ; len++)
-    {
-      COptimal *opt;
-      UInt32 distance = matchDistances[offs + 1];
-
-      UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
-      UInt32 lenToPosState = GetLenToPosState(len);
-      if (distance < kNumFullDistances)
-        curAndLenPrice += p->distancesPrices[lenToPosState][distance];
-      else
-      {
-        UInt32 slot;
-        GetPosSlot2(distance, slot);
-        curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
-      }
-      opt = &p->opt[len];
-      if (curAndLenPrice < opt->price)
-      {
-        opt->price = curAndLenPrice;
-        opt->posPrev = 0;
-        opt->backPrev = distance + LZMA_NUM_REPS;
-        opt->prev1IsChar = False;
-      }
-      if (len == matchDistances[offs])
-      {
-        offs += 2;
-        if (offs == numDistancePairs)
-          break;
-      }
-    }
-  }
-
-  cur = 0;
-
-    #ifdef SHOW_STAT2
-    if (position >= 0)
-    {
-      unsigned i;
-      printf("\n pos = %4X", position);
-      for (i = cur; i <= lenEnd; i++)
-      printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);
-    }
-    #endif
-
-  for (;;)
-  {
-    UInt32 numAvailableBytesFull, newLen, numDistancePairs;
-    COptimal *curOpt;
-    UInt32 posPrev;
-    UInt32 state;
-    UInt32 curPrice;
-    Bool nextIsChar;
-    const Byte *data;
-    Byte currentByte, matchByte;
-    UInt32 posState;
-    UInt32 curAnd1Price;
-    COptimal *nextOpt;
-    UInt32 matchPrice, repMatchPrice;
-    UInt32 numAvailableBytes;
-    UInt32 startLen;
-
-    cur++;
-    if (cur == lenEnd)
-      return Backward(p, backRes, cur);
-
-    numAvailableBytesFull = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
-    newLen = ReadMatchDistances(p, &numDistancePairs);
-    if (newLen >= p->numFastBytes)
-    {
-      p->numDistancePairs = numDistancePairs;
-      p->longestMatchLength = newLen;
-      p->longestMatchWasFound = True;
-      return Backward(p, backRes, cur);
-    }
-    position++;
-    curOpt = &p->opt[cur];
-    posPrev = curOpt->posPrev;
-    if (curOpt->prev1IsChar)
-    {
-      posPrev--;
-      if (curOpt->prev2)
-      {
-        state = p->opt[curOpt->posPrev2].state;
-        if (curOpt->backPrev2 < LZMA_NUM_REPS)
-          state = kRepNextStates[state];
-        else
-          state = kMatchNextStates[state];
-      }
-      else
-        state = p->opt[posPrev].state;
-      state = kLiteralNextStates[state];
-    }
-    else
-      state = p->opt[posPrev].state;
-    if (posPrev == cur - 1)
-    {
-      if (IsShortRep(curOpt))
-        state = kShortRepNextStates[state];
-      else
-        state = kLiteralNextStates[state];
-    }
-    else
-    {
-      UInt32 pos;
-      const COptimal *prevOpt;
-      if (curOpt->prev1IsChar && curOpt->prev2)
-      {
-        posPrev = curOpt->posPrev2;
-        pos = curOpt->backPrev2;
-        state = kRepNextStates[state];
-      }
-      else
-      {
-        pos = curOpt->backPrev;
-        if (pos < LZMA_NUM_REPS)
-          state = kRepNextStates[state];
-        else
-          state = kMatchNextStates[state];
-      }
-      prevOpt = &p->opt[posPrev];
-      if (pos < LZMA_NUM_REPS)
-      {
-        UInt32 i;
-        reps[0] = prevOpt->backs[pos];
-        for (i = 1; i <= pos; i++)
-          reps[i] = prevOpt->backs[i - 1];
-        for (; i < LZMA_NUM_REPS; i++)
-          reps[i] = prevOpt->backs[i];
-      }
-      else
-      {
-        UInt32 i;
-        reps[0] = (pos - LZMA_NUM_REPS);
-        for (i = 1; i < LZMA_NUM_REPS; i++)
-          reps[i] = prevOpt->backs[i - 1];
-      }
-    }
-    curOpt->state = (CState)state;
-
-    curOpt->backs[0] = reps[0];
-    curOpt->backs[1] = reps[1];
-    curOpt->backs[2] = reps[2];
-    curOpt->backs[3] = reps[3];
-
-    curPrice = curOpt->price;
-    nextIsChar = False;
-    data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-    currentByte = *data;
-    matchByte = *(data - (reps[0] + 1));
-
-    posState = (position & p->pbMask);
-
-    curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
-    {
-      const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
-      curAnd1Price +=
-        (!IsCharState(state) ?
-          LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) :
-          LitEnc_GetPrice(probs, currentByte, p->ProbPrices));
-    }
-
-    nextOpt = &p->opt[cur + 1];
-
-    if (curAnd1Price < nextOpt->price)
-    {
-      nextOpt->price = curAnd1Price;
-      nextOpt->posPrev = cur;
-      MakeAsChar(nextOpt);
-      nextIsChar = True;
-    }
-
-    matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
-    repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
-
-    if (matchByte == currentByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
-    {
-      UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
-      if (shortRepPrice <= nextOpt->price)
-      {
-        nextOpt->price = shortRepPrice;
-        nextOpt->posPrev = cur;
-        MakeAsShortRep(nextOpt);
-        nextIsChar = True;
-      }
-    }
-
-    {
-      UInt32 temp = kNumOpts - 1 - cur;
-      if (temp <  numAvailableBytesFull)
-        numAvailableBytesFull = temp;
-    }
-    numAvailableBytes = numAvailableBytesFull;
-
-    if (numAvailableBytes < 2)
-      continue;
-    if (numAvailableBytes > p->numFastBytes)
-      numAvailableBytes = p->numFastBytes;
-    if (!nextIsChar && matchByte != currentByte) /* speed optimization */
-    {
-      /* try Literal + rep0 */
-      UInt32 temp;
-      UInt32 lenTest2;
-      const Byte *data2 = data - (reps[0] + 1);
-      UInt32 limit = p->numFastBytes + 1;
-      if (limit > numAvailableBytesFull)
-        limit = numAvailableBytesFull;
-
-      for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
-      lenTest2 = temp - 1;
-      if (lenTest2 >= 2)
-      {
-        UInt32 state2 = kLiteralNextStates[state];
-        UInt32 posStateNext = (position + 1) & p->pbMask;
-        UInt32 nextRepMatchPrice = curAnd1Price +
-            GET_PRICE_1(p->isMatch[state2][posStateNext]) +
-            GET_PRICE_1(p->isRep[state2]);
-        /* for (; lenTest2 >= 2; lenTest2--) */
-        {
-          UInt32 curAndLenPrice;
-          COptimal *opt;
-          UInt32 offset = cur + 1 + lenTest2;
-          while (lenEnd < offset)
-            p->opt[++lenEnd].price = kInfinityPrice;
-          curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
-          opt = &p->opt[offset];
-          if (curAndLenPrice < opt->price)
-          {
-            opt->price = curAndLenPrice;
-            opt->posPrev = cur + 1;
-            opt->backPrev = 0;
-            opt->prev1IsChar = True;
-            opt->prev2 = False;
-          }
-        }
-      }
-    }
-
-    startLen = 2; /* speed optimization */
-    {
-    UInt32 repIndex;
-    for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
-    {
-      UInt32 lenTest;
-      UInt32 lenTestTemp;
-      UInt32 price;
-      const Byte *data2 = data - (reps[repIndex] + 1);
-      if (data[0] != data2[0] || data[1] != data2[1])
-        continue;
-      for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++);
-      while (lenEnd < cur + lenTest)
-        p->opt[++lenEnd].price = kInfinityPrice;
-      lenTestTemp = lenTest;
-      price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
-      do
-      {
-        UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
-        COptimal *opt = &p->opt[cur + lenTest];
-        if (curAndLenPrice < opt->price)
-        {
-          opt->price = curAndLenPrice;
-          opt->posPrev = cur;
-          opt->backPrev = repIndex;
-          opt->prev1IsChar = False;
-        }
-      }
-      while (--lenTest >= 2);
-      lenTest = lenTestTemp;
-
-      if (repIndex == 0)
-        startLen = lenTest + 1;
-
-      /* if (_maxMode) */
-        {
-          UInt32 lenTest2 = lenTest + 1;
-          UInt32 limit = lenTest2 + p->numFastBytes;
-          UInt32 nextRepMatchPrice;
-          if (limit > numAvailableBytesFull)
-            limit = numAvailableBytesFull;
-          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
-          lenTest2 -= lenTest + 1;
-          if (lenTest2 >= 2)
-          {
-            UInt32 state2 = kRepNextStates[state];
-            UInt32 posStateNext = (position + lenTest) & p->pbMask;
-            UInt32 curAndLenCharPrice =
-                price + p->repLenEnc.prices[posState][lenTest - 2] +
-                GET_PRICE_0(p->isMatch[state2][posStateNext]) +
-                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
-                    data[lenTest], data2[lenTest], p->ProbPrices);
-            state2 = kLiteralNextStates[state2];
-            posStateNext = (position + lenTest + 1) & p->pbMask;
-            nextRepMatchPrice = curAndLenCharPrice +
-                GET_PRICE_1(p->isMatch[state2][posStateNext]) +
-                GET_PRICE_1(p->isRep[state2]);
-
-            /* for (; lenTest2 >= 2; lenTest2--) */
-            {
-              UInt32 curAndLenPrice;
-              COptimal *opt;
-              UInt32 offset = cur + lenTest + 1 + lenTest2;
-              while (lenEnd < offset)
-                p->opt[++lenEnd].price = kInfinityPrice;
-              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
-              opt = &p->opt[offset];
-              if (curAndLenPrice < opt->price)
-              {
-                opt->price = curAndLenPrice;
-                opt->posPrev = cur + lenTest + 1;
-                opt->backPrev = 0;
-                opt->prev1IsChar = True;
-                opt->prev2 = True;
-                opt->posPrev2 = cur;
-                opt->backPrev2 = repIndex;
-              }
-            }
-          }
-        }
-    }
-    }
-    /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
-    if (newLen > numAvailableBytes)
-    {
-      newLen = numAvailableBytes;
-      for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2);
-      matchDistances[numDistancePairs] = newLen;
-      numDistancePairs += 2;
-    }
-    if (newLen >= startLen)
-    {
-      UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
-      UInt32 offs, curBack, posSlot;
-      UInt32 lenTest;
-      while (lenEnd < cur + newLen)
-        p->opt[++lenEnd].price = kInfinityPrice;
-
-      offs = 0;
-      while (startLen > matchDistances[offs])
-        offs += 2;
-      curBack = matchDistances[offs + 1];
-      GetPosSlot2(curBack, posSlot);
-      for (lenTest = /*2*/ startLen; ; lenTest++)
-      {
-        UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
-        UInt32 lenToPosState = GetLenToPosState(lenTest);
-        COptimal *opt;
-        if (curBack < kNumFullDistances)
-          curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
-        else
-          curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
-
-        opt = &p->opt[cur + lenTest];
-        if (curAndLenPrice < opt->price)
-        {
-          opt->price = curAndLenPrice;
-          opt->posPrev = cur;
-          opt->backPrev = curBack + LZMA_NUM_REPS;
-          opt->prev1IsChar = False;
-        }
-
-        if (/*_maxMode && */lenTest == matchDistances[offs])
-        {
-          /* Try Match + Literal + Rep0 */
-          const Byte *data2 = data - (curBack + 1);
-          UInt32 lenTest2 = lenTest + 1;
-          UInt32 limit = lenTest2 + p->numFastBytes;
-          UInt32 nextRepMatchPrice;
-          if (limit > numAvailableBytesFull)
-            limit = numAvailableBytesFull;
-          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
-          lenTest2 -= lenTest + 1;
-          if (lenTest2 >= 2)
-          {
-            UInt32 state2 = kMatchNextStates[state];
-            UInt32 posStateNext = (position + lenTest) & p->pbMask;
-            UInt32 curAndLenCharPrice = curAndLenPrice +
-                GET_PRICE_0(p->isMatch[state2][posStateNext]) +
-                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
-                    data[lenTest], data2[lenTest], p->ProbPrices);
-            state2 = kLiteralNextStates[state2];
-            posStateNext = (posStateNext + 1) & p->pbMask;
-            nextRepMatchPrice = curAndLenCharPrice +
-                GET_PRICE_1(p->isMatch[state2][posStateNext]) +
-                GET_PRICE_1(p->isRep[state2]);
-
-            /* for (; lenTest2 >= 2; lenTest2--) */
-            {
-              UInt32 offset = cur + lenTest + 1 + lenTest2;
-              UInt32 curAndLenPrice;
-              COptimal *opt;
-              while (lenEnd < offset)
-                p->opt[++lenEnd].price = kInfinityPrice;
-              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
-              opt = &p->opt[offset];
-              if (curAndLenPrice < opt->price)
-              {
-                opt->price = curAndLenPrice;
-                opt->posPrev = cur + lenTest + 1;
-                opt->backPrev = 0;
-                opt->prev1IsChar = True;
-                opt->prev2 = True;
-                opt->posPrev2 = cur;
-                opt->backPrev2 = curBack + LZMA_NUM_REPS;
-              }
-            }
-          }
-          offs += 2;
-          if (offs == numDistancePairs)
-            break;
-          curBack = matchDistances[offs + 1];
-          if (curBack >= kNumFullDistances)
-            GetPosSlot2(curBack, posSlot);
-        }
-      }
-    }
-  }
-}
-
-#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
-
-static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
-{
-  UInt32 numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
-  UInt32 lenMain, numDistancePairs;
-  const Byte *data;
-  UInt32 repLens[LZMA_NUM_REPS];
-  UInt32 repMaxIndex, i;
-  UInt32 *matchDistances;
-  UInt32 backMain;
-
-  if (!p->longestMatchWasFound)
-  {
-    lenMain = ReadMatchDistances(p, &numDistancePairs);
-  }
-  else
-  {
-    lenMain = p->longestMatchLength;
-    numDistancePairs = p->numDistancePairs;
-    p->longestMatchWasFound = False;
-  }
-
-  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-  if (numAvailableBytes > LZMA_MATCH_LEN_MAX)
-    numAvailableBytes = LZMA_MATCH_LEN_MAX;
-  if (numAvailableBytes < 2)
-  {
-    *backRes = (UInt32)(-1);
-    return 1;
-  }
-
-  repMaxIndex = 0;
-
-  for (i = 0; i < LZMA_NUM_REPS; i++)
-  {
-    const Byte *data2 = data - (p->reps[i] + 1);
-    UInt32 len;
-    if (data[0] != data2[0] || data[1] != data2[1])
-    {
-      repLens[i] = 0;
-      continue;
-    }
-    for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++);
-    if (len >= p->numFastBytes)
-    {
-      *backRes = i;
-      MovePos(p, len - 1);
-      return len;
-    }
-    repLens[i] = len;
-    if (len > repLens[repMaxIndex])
-      repMaxIndex = i;
-  }
-  matchDistances = p->matchDistances;
-  if (lenMain >= p->numFastBytes)
-  {
-    *backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS;
-    MovePos(p, lenMain - 1);
-    return lenMain;
-  }
-
-  backMain = 0; /* for GCC */
-  if (lenMain >= 2)
-  {
-    backMain = matchDistances[numDistancePairs - 1];
-    while (numDistancePairs > 2 && lenMain == matchDistances[numDistancePairs - 4] + 1)
-    {
-      if (!ChangePair(matchDistances[numDistancePairs - 3], backMain))
-        break;
-      numDistancePairs -= 2;
-      lenMain = matchDistances[numDistancePairs - 2];
-      backMain = matchDistances[numDistancePairs - 1];
-    }
-    if (lenMain == 2 && backMain >= 0x80)
-      lenMain = 1;
-  }
-
-  if (repLens[repMaxIndex] >= 2)
-  {
-    if (repLens[repMaxIndex] + 1 >= lenMain ||
-        (repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1 << 9))) ||
-        (repLens[repMaxIndex] + 3 >= lenMain && (backMain > (1 << 15))))
-    {
-      UInt32 lenRes;
-      *backRes = repMaxIndex;
-      lenRes = repLens[repMaxIndex];
-      MovePos(p, lenRes - 1);
-      return lenRes;
-    }
-  }
-
-  if (lenMain >= 2 && numAvailableBytes > 2)
-  {
-    UInt32 i;
-    numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
-    p->longestMatchLength = ReadMatchDistances(p, &p->numDistancePairs);
-    if (p->longestMatchLength >= 2)
-    {
-      UInt32 newDistance = matchDistances[p->numDistancePairs - 1];
-      if ((p->longestMatchLength >= lenMain && newDistance < backMain) ||
-          (p->longestMatchLength == lenMain + 1 && !ChangePair(backMain, newDistance)) ||
-          (p->longestMatchLength > lenMain + 1) ||
-          (p->longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(newDistance, backMain)))
-      {
-        p->longestMatchWasFound = True;
-        *backRes = (UInt32)(-1);
-        return 1;
-      }
-    }
-    data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-    for (i = 0; i < LZMA_NUM_REPS; i++)
-    {
-      UInt32 len;
-      const Byte *data2 = data - (p->reps[i] + 1);
-      if (data[1] != data2[1] || data[2] != data2[2])
-      {
-        repLens[i] = 0;
-        continue;
-      }
-      for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++);
-      if (len + 1 >= lenMain)
-      {
-        p->longestMatchWasFound = True;
-        *backRes = (UInt32)(-1);
-        return 1;
-      }
-    }
-    *backRes = backMain + LZMA_NUM_REPS;
-    MovePos(p, lenMain - 2);
-    return lenMain;
-  }
-  *backRes = (UInt32)(-1);
-  return 1;
-}
-
-static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
-{
-  UInt32 len;
-  RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
-  RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
-  p->state = kMatchNextStates[p->state];
-  len = LZMA_MATCH_LEN_MIN;
-  LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
-  RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
-  RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
-  RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
-}
-
-static SRes CheckErrors(CLzmaEnc *p)
-{
-  if (p->result != SZ_OK)
-    return p->result;
-  if (p->rc.res != SZ_OK)
-    p->result = SZ_ERROR_WRITE;
-  if (p->matchFinderBase.result != SZ_OK)
-    p->result = SZ_ERROR_READ;
-  if (p->result != SZ_OK)
-    p->finished = True;
-  return p->result;
-}
-
-static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
-{
-  /* ReleaseMFStream(); */
-  p->finished = True;
-  if (p->writeEndMark)
-    WriteEndMarker(p, nowPos & p->pbMask);
-  RangeEnc_FlushData(&p->rc);
-  RangeEnc_FlushStream(&p->rc);
-  return CheckErrors(p);
-}
-
-static void FillAlignPrices(CLzmaEnc *p)
-{
-  UInt32 i;
-  for (i = 0; i < kAlignTableSize; i++)
-    p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
-  p->alignPriceCount = 0;
-}
-
-static void FillDistancesPrices(CLzmaEnc *p)
-{
-  UInt32 tempPrices[kNumFullDistances];
-  UInt32 i, lenToPosState;
-  for (i = kStartPosModelIndex; i < kNumFullDistances; i++)
-  {
-    UInt32 posSlot = GetPosSlot1(i);
-    UInt32 footerBits = ((posSlot >> 1) - 1);
-    UInt32 base = ((2 | (posSlot & 1)) << footerBits);
-    tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);
-  }
-
-  for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
-  {
-    UInt32 posSlot;
-    const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
-    UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
-    for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
-      posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
-    for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
-      posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
-
-    {
-      UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
-      UInt32 i;
-      for (i = 0; i < kStartPosModelIndex; i++)
-        distancesPrices[i] = posSlotPrices[i];
-      for (; i < kNumFullDistances; i++)
-        distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];
-    }
-  }
-  p->matchPriceCount = 0;
-}
-
-void LzmaEnc_Construct(CLzmaEnc *p)
-{
-  RangeEnc_Construct(&p->rc);
-  MatchFinder_Construct(&p->matchFinderBase);
-  #ifdef COMPRESS_MF_MT
-  MatchFinderMt_Construct(&p->matchFinderMt);
-  p->matchFinderMt.MatchFinder = &p->matchFinderBase;
-  #endif
-
-  {
-    CLzmaEncProps props;
-    LzmaEncProps_Init(&props);
-    LzmaEnc_SetProps(p, &props);
-  }
-
-  #ifndef LZMA_LOG_BSR
-  LzmaEnc_FastPosInit(p->g_FastPos);
-  #endif
-
-  LzmaEnc_InitPriceTables(p->ProbPrices);
-  p->litProbs = 0;
-  p->saveState.litProbs = 0;
-}
-
-CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
-{
-  void *p;
-  p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
-  if (p != 0)
-    LzmaEnc_Construct((CLzmaEnc *)p);
-  return p;
-}
-
-void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
-{
-  alloc->Free(alloc, p->litProbs);
-  alloc->Free(alloc, p->saveState.litProbs);
-  p->litProbs = 0;
-  p->saveState.litProbs = 0;
-}
-
-void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
-{
-  #ifdef COMPRESS_MF_MT
-  MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
-  #endif
-  MatchFinder_Free(&p->matchFinderBase, allocBig);
-  LzmaEnc_FreeLits(p, alloc);
-  RangeEnc_Free(&p->rc, alloc);
-}
-
-void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
-{
-  LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
-  alloc->Free(alloc, p);
-}
-
-static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
-{
-  UInt32 nowPos32, startPos32;
-  if (p->inStream != 0)
-  {
-    p->matchFinderBase.stream = p->inStream;
-    p->matchFinder.Init(p->matchFinderObj);
-    p->inStream = 0;
-  }
-
-  if (p->finished)
-    return p->result;
-  RINOK(CheckErrors(p));
-
-  nowPos32 = (UInt32)p->nowPos64;
-  startPos32 = nowPos32;
-
-  if (p->nowPos64 == 0)
-  {
-    UInt32 numDistancePairs;
-    Byte curByte;
-    if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
-      return Flush(p, nowPos32);
-    ReadMatchDistances(p, &numDistancePairs);
-    RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
-    p->state = kLiteralNextStates[p->state];
-    curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
-    LitEnc_Encode(&p->rc, p->litProbs, curByte);
-    p->additionalOffset--;
-    nowPos32++;
-  }
-
-  if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
-  for (;;)
-  {
-    UInt32 pos, len, posState;
-
-    if (p->fastMode)
-      len = GetOptimumFast(p, &pos);
-    else
-      len = GetOptimum(p, nowPos32, &pos);
-
-    #ifdef SHOW_STAT2
-    printf("\n pos = %4X,   len = %d   pos = %d", nowPos32, len, pos);
-    #endif
-
-    posState = nowPos32 & p->pbMask;
-    if (len == 1 && pos == 0xFFFFFFFF)
-    {
-      Byte curByte;
-      CLzmaProb *probs;
-      const Byte *data;
-
-      RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
-      data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
-      curByte = *data;
-      probs = LIT_PROBS(nowPos32, *(data - 1));
-      if (IsCharState(p->state))
-        LitEnc_Encode(&p->rc, probs, curByte);
-      else
-        LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
-      p->state = kLiteralNextStates[p->state];
-    }
-    else
-    {
-      RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
-      if (pos < LZMA_NUM_REPS)
-      {
-        RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
-        if (pos == 0)
-        {
-          RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
-          RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
-        }
-        else
-        {
-          UInt32 distance = p->reps[pos];
-          RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
-          if (pos == 1)
-            RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
-          else
-          {
-            RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
-            RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
-            if (pos == 3)
-              p->reps[3] = p->reps[2];
-            p->reps[2] = p->reps[1];
-          }
-          p->reps[1] = p->reps[0];
-          p->reps[0] = distance;
-        }
-        if (len == 1)
-          p->state = kShortRepNextStates[p->state];
-        else
-        {
-          LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
-          p->state = kRepNextStates[p->state];
-        }
-      }
-      else
-      {
-        UInt32 posSlot;
-        RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
-        p->state = kMatchNextStates[p->state];
-        LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
-        pos -= LZMA_NUM_REPS;
-        GetPosSlot(pos, posSlot);
-        RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
-
-        if (posSlot >= kStartPosModelIndex)
-        {
-          UInt32 footerBits = ((posSlot >> 1) - 1);
-          UInt32 base = ((2 | (posSlot & 1)) << footerBits);
-          UInt32 posReduced = pos - base;
-
-          if (posSlot < kEndPosModelIndex)
-            RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
-          else
-          {
-            RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
-            RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
-            p->alignPriceCount++;
-          }
-        }
-        p->reps[3] = p->reps[2];
-        p->reps[2] = p->reps[1];
-        p->reps[1] = p->reps[0];
-        p->reps[0] = pos;
-        p->matchPriceCount++;
-      }
-    }
-    p->additionalOffset -= len;
-    nowPos32 += len;
-    if (p->additionalOffset == 0)
-    {
-      UInt32 processed;
-      if (!p->fastMode)
-      {
-        if (p->matchPriceCount >= (1 << 7))
-          FillDistancesPrices(p);
-        if (p->alignPriceCount >= kAlignTableSize)
-          FillAlignPrices(p);
-      }
-      if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
-        break;
-      processed = nowPos32 - startPos32;
-      if (useLimits)
-      {
-        if (processed + kNumOpts + 300 >= maxUnpackSize ||
-            RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
-          break;
-      }
-      else if (processed >= (1 << 15))
-      {
-        p->nowPos64 += nowPos32 - startPos32;
-        return CheckErrors(p);
-      }
-    }
-  }
-  p->nowPos64 += nowPos32 - startPos32;
-  return Flush(p, nowPos32);
-}
-
-#define kBigHashDicLimit ((UInt32)1 << 24)
-
-static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
-{
-  UInt32 beforeSize = kNumOpts;
-  Bool btMode;
-  if (!RangeEnc_Alloc(&p->rc, alloc))
-    return SZ_ERROR_MEM;
-  btMode = (p->matchFinderBase.btMode != 0);
-  #ifdef COMPRESS_MF_MT
-  p->mtMode = (p->multiThread && !p->fastMode && btMode);
-  #endif
-
-  {
-    unsigned lclp = p->lc + p->lp;
-    if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
-    {
-      LzmaEnc_FreeLits(p, alloc);
-      p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
-      p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
-      if (p->litProbs == 0 || p->saveState.litProbs == 0)
-      {
-        LzmaEnc_FreeLits(p, alloc);
-        return SZ_ERROR_MEM;
-      }
-      p->lclp = lclp;
-    }
-  }
-
-  p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
-
-  if (beforeSize + p->dictSize < keepWindowSize)
-    beforeSize = keepWindowSize - p->dictSize;
-
-  #ifdef COMPRESS_MF_MT
-  if (p->mtMode)
-  {
-    RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
-    p->matchFinderObj = &p->matchFinderMt;
-    MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
-  }
-  else
-  #endif
-  {
-    if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
-      return SZ_ERROR_MEM;
-    p->matchFinderObj = &p->matchFinderBase;
-    MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
-  }
-  return SZ_OK;
-}
-
-void LzmaEnc_Init(CLzmaEnc *p)
-{
-  UInt32 i;
-  p->state = 0;
-  for(i = 0 ; i < LZMA_NUM_REPS; i++)
-    p->reps[i] = 0;
-
-  RangeEnc_Init(&p->rc);
-
-
-  for (i = 0; i < kNumStates; i++)
-  {
-    UInt32 j;
-    for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
-    {
-      p->isMatch[i][j] = kProbInitValue;
-      p->isRep0Long[i][j] = kProbInitValue;
-    }
-    p->isRep[i] = kProbInitValue;
-    p->isRepG0[i] = kProbInitValue;
-    p->isRepG1[i] = kProbInitValue;
-    p->isRepG2[i] = kProbInitValue;
-  }
-
-  {
-    UInt32 num = 0x300 << (p->lp + p->lc);
-    for (i = 0; i < num; i++)
-      p->litProbs[i] = kProbInitValue;
-  }
-
-  {
-    for (i = 0; i < kNumLenToPosStates; i++)
-    {
-      CLzmaProb *probs = p->posSlotEncoder[i];
-      UInt32 j;
-      for (j = 0; j < (1 << kNumPosSlotBits); j++)
-        probs[j] = kProbInitValue;
-    }
-  }
-  {
-    for(i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
-      p->posEncoders[i] = kProbInitValue;
-  }
-
-  LenEnc_Init(&p->lenEnc.p);
-  LenEnc_Init(&p->repLenEnc.p);
-
-  for (i = 0; i < (1 << kNumAlignBits); i++)
-    p->posAlignEncoder[i] = kProbInitValue;
-
-  p->longestMatchWasFound = False;
-  p->optimumEndIndex = 0;
-  p->optimumCurrentIndex = 0;
-  p->additionalOffset = 0;
-
-  p->pbMask = (1 << p->pb) - 1;
-  p->lpMask = (1 << p->lp) - 1;
-}
-
-void LzmaEnc_InitPrices(CLzmaEnc *p)
-{
-  if (!p->fastMode)
-  {
-    FillDistancesPrices(p);
-    FillAlignPrices(p);
-  }
-
-  p->lenEnc.tableSize =
-  p->repLenEnc.tableSize =
-      p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
-  LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
-  LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
-}
-
-static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
-{
-  UInt32 i;
-  for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
-    if (p->dictSize <= ((UInt32)1 << i))
-      break;
-  p->distTableSize = i * 2;
-
-  p->finished = False;
-  p->result = SZ_OK;
-  RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
-  LzmaEnc_Init(p);
-  LzmaEnc_InitPrices(p);
-  p->nowPos64 = 0;
-  return SZ_OK;
-}
-
-static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream,
-    ISzAlloc *alloc, ISzAlloc *allocBig)
-{
-  CLzmaEnc *p = (CLzmaEnc *)pp;
-  p->inStream = inStream;
-  p->rc.outStream = outStream;
-  return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
-}
-
-SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
-    ISeqInStream *inStream, UInt32 keepWindowSize,
-    ISzAlloc *alloc, ISzAlloc *allocBig)
-{
-  CLzmaEnc *p = (CLzmaEnc *)pp;
-  p->inStream = inStream;
-  return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
-}
-
-static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
-{
-  p->seqBufInStream.funcTable.Read = MyRead;
-  p->seqBufInStream.data = src;
-  p->seqBufInStream.rem = srcLen;
-}
-
-SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
-    UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
-{
-  CLzmaEnc *p = (CLzmaEnc *)pp;
-  LzmaEnc_SetInputBuf(p, src, srcLen);
-  p->inStream = &p->seqBufInStream.funcTable;
-  return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
-}
-
-void LzmaEnc_Finish(CLzmaEncHandle pp)
-{
-  #ifdef COMPRESS_MF_MT
-  CLzmaEnc *p = (CLzmaEnc *)pp;
-  if (p->mtMode)
-    MatchFinderMt_ReleaseStream(&p->matchFinderMt);
-  #else
-  (void)pp;
-  #endif
-}
-
-typedef struct _CSeqOutStreamBuf
-{
-  ISeqOutStream funcTable;
-  Byte *data;
-  SizeT rem;
-  Bool overflow;
-} CSeqOutStreamBuf;
-
-static size_t MyWrite(void *pp, const void *data, size_t size)
-{
-  CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
-  if (p->rem < size)
-  {
-    size = p->rem;
-    p->overflow = True;
-  }
-  memcpy(p->data, data, size);
-  p->rem -= size;
-  p->data += size;
-  return size;
-}
-
-
-UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
-{
-  const CLzmaEnc *p = (CLzmaEnc *)pp;
-  return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
-}
-
-const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
-{
-  const CLzmaEnc *p = (CLzmaEnc *)pp;
-  return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
-}
-
-SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
-    Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
-{
-  CLzmaEnc *p = (CLzmaEnc *)pp;
-  UInt64 nowPos64;
-  SRes res;
-  CSeqOutStreamBuf outStream;
-
-  outStream.funcTable.Write = MyWrite;
-  outStream.data = dest;
-  outStream.rem = *destLen;
-  outStream.overflow = False;
-
-  p->writeEndMark = False;
-  p->finished = False;
-  p->result = SZ_OK;
-
-  if (reInit)
-    LzmaEnc_Init(p);
-  LzmaEnc_InitPrices(p);
-  nowPos64 = p->nowPos64;
-  RangeEnc_Init(&p->rc);
-  p->rc.outStream = &outStream.funcTable;
-
-  res = LzmaEnc_CodeOneBlock(pp, True, desiredPackSize, *unpackSize);
-
-  *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
-  *destLen -= outStream.rem;
-  if (outStream.overflow)
-    return SZ_ERROR_OUTPUT_EOF;
-
-  return res;
-}
-
-SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
-    ISzAlloc *alloc, ISzAlloc *allocBig)
-{
-  CLzmaEnc *p = (CLzmaEnc *)pp;
-  SRes res = SZ_OK;
-
-  #ifdef COMPRESS_MF_MT
-  Byte allocaDummy[0x300];
-  int i = 0;
-  for (i = 0; i < 16; i++)
-    allocaDummy[i] = (Byte)i;
-  #endif
-
-  RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig));
-
-  for (;;)
-  {
-    res = LzmaEnc_CodeOneBlock(pp, False, 0, 0);
-    if (res != SZ_OK || p->finished != 0)
-      break;
-    if (progress != 0)
-    {
-      res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
-      if (res != SZ_OK)
-      {
-        res = SZ_ERROR_PROGRESS;
-        break;
-      }
-    }
-  }
-  LzmaEnc_Finish(pp);
-  return res;
-}
-
-SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
-{
-  CLzmaEnc *p = (CLzmaEnc *)pp;
-  int i;
-  UInt32 dictSize = p->dictSize;
-  if (*size < LZMA_PROPS_SIZE)
-    return SZ_ERROR_PARAM;
-  *size = LZMA_PROPS_SIZE;
-  props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
-
-  for (i = 11; i <= 30; i++)
-  {
-    if (dictSize <= ((UInt32)2 << i))
-    {
-      dictSize = (2 << i);
-      break;
-    }
-    if (dictSize <= ((UInt32)3 << i))
-    {
-      dictSize = (3 << i);
-      break;
-    }
-  }
-
-  for (i = 0; i < 4; i++)
-    props[1 + i] = (Byte)(dictSize >> (8 * i));
-  return SZ_OK;
-}
-
-SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
-{
-  SRes res;
-  CLzmaEnc *p = (CLzmaEnc *)pp;
-
-  CSeqOutStreamBuf outStream;
-
-  LzmaEnc_SetInputBuf(p, src, srcLen);
-
-  outStream.funcTable.Write = MyWrite;
-  outStream.data = dest;
-  outStream.rem = *destLen;
-  outStream.overflow = False;
-
-  p->writeEndMark = writeEndMark;
-  res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable,
-      progress, alloc, allocBig);
-
-  *destLen -= outStream.rem;
-  if (outStream.overflow)
-    return SZ_ERROR_OUTPUT_EOF;
-  return res;
-}
-
-SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
-    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
-{
-  CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
-  SRes res;
-  if (p == 0)
-    return SZ_ERROR_MEM;
-
-  res = LzmaEnc_SetProps(p, props);
-  if (res == SZ_OK)
-  {
-    res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
-    if (res == SZ_OK)
-      res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
-          writeEndMark, progress, alloc, allocBig);
-  }
-
-  LzmaEnc_Destroy(p, alloc, allocBig);
-  return res;
-}
diff --git a/lib/arg.c b/lib/arg.c
deleted file mode 100644 (file)
index 6a7bb8b..0000000
--- a/lib/arg.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/* arg.c - argument parser */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/term.h>
-#include <grub/extcmd.h>
-#include <grub/i18n.h>
-
-/* Built-in parser for default options.  */
-#define SHORT_ARG_HELP -100
-#define SHORT_ARG_USAGE        -101
-
-static const struct grub_arg_option help_options[] =
-  {
-    {"help", SHORT_ARG_HELP, 0,
-     N_("Display this help and exit."), 0, ARG_TYPE_NONE},
-    {"usage", SHORT_ARG_USAGE, 0,
-     N_("Display the usage of this command and exit."), 0, ARG_TYPE_NONE},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-static struct grub_arg_option *
-find_short (const struct grub_arg_option *options, char c)
-{
-  struct grub_arg_option *found = 0;
-  auto struct grub_arg_option *fnd_short (const struct grub_arg_option *opt);
-
-  struct grub_arg_option *fnd_short (const struct grub_arg_option *opt)
-    {
-      while (opt->doc)
-       {
-         if (opt->shortarg == c)
-           return (struct grub_arg_option *) opt;
-         opt++;
-       }
-      return 0;
-    }
-
-  if (options)
-    found = fnd_short (options);
-
-  if (! found)
-    {
-      switch (c)
-       {
-       case 'h':
-         found = (struct grub_arg_option *) help_options;
-         break;
-
-       case 'u':
-         found = (struct grub_arg_option *) (help_options + 1);
-         break;
-
-       default:
-         break;
-       }
-    }
-
-  return found;
-}
-
-static struct grub_arg_option *
-find_long (const struct grub_arg_option *options, const char *s, int len)
-{
-  struct grub_arg_option *found = 0;
-  auto struct grub_arg_option *fnd_long (const struct grub_arg_option *opt);
-
-  struct grub_arg_option *fnd_long (const struct grub_arg_option *opt)
-    {
-      while (opt->doc)
-       {
-         if (opt->longarg && ! grub_strncmp (opt->longarg, s, len) &&
-             opt->longarg[len] == '\0')
-           return (struct grub_arg_option *) opt;
-         opt++;
-       }
-      return 0;
-    }
-
-  if (options)
-    found = fnd_long (options);
-
-  if (! found)
-    found = fnd_long (help_options);
-
-  return found;
-}
-
-static void
-show_usage (grub_extcmd_t cmd)
-{
-  grub_printf ("%s %s %s\n", _("Usage:"), cmd->cmd->name, _(cmd->cmd->summary));
-}
-
-void
-grub_arg_show_help (grub_extcmd_t cmd)
-{
-  auto void showargs (const struct grub_arg_option *opt);
-  int h_is_used = 0;
-  int u_is_used = 0;
-
-  auto void showargs (const struct grub_arg_option *opt)
-    {
-      for (; opt->doc; opt++)
-       {
-         int spacing = 20;
-
-         if (opt->shortarg && grub_isgraph (opt->shortarg))
-           grub_printf ("-%c%c ", opt->shortarg, opt->longarg ? ',':' ');
-         else if (opt->shortarg == SHORT_ARG_HELP && ! h_is_used)
-           grub_printf ("-h, ");
-         else if (opt->shortarg == SHORT_ARG_USAGE && ! u_is_used)
-           grub_printf ("-u, ");
-         else
-           grub_printf ("    ");
-
-         if (opt->longarg)
-           {
-             grub_printf ("--%s", opt->longarg);
-             spacing -= grub_strlen (opt->longarg) + 2;
-
-             if (opt->arg)
-               {
-                 grub_printf ("=%s", opt->arg);
-                 spacing -= grub_strlen (opt->arg) + 1;
-               }
-           }
-
-         const char *doc = _(opt->doc);
-         for (;;)
-           {
-             while (spacing-- > 0)
-               grub_putchar (' ');
-
-             while (*doc && *doc != '\n')
-               grub_putchar (*doc++);
-             grub_putchar ('\n');
-
-             if (! *doc)
-               break;
-             doc++;
-             spacing = 4 + 20;
-           }
-
-         switch (opt->shortarg)
-           {
-           case 'h':
-             h_is_used = 1;
-             break;
-
-           case 'u':
-             u_is_used = 1;
-             break;
-
-           default:
-             break;
-           }
-       }
-    }
-
-  show_usage (cmd);
-  grub_printf ("%s\n\n", _(cmd->cmd->description));
-  if (cmd->options)
-    showargs (cmd->options);
-  showargs (help_options);
-#if 0
-  grub_printf ("\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
-#endif
-}
-
-
-static int
-parse_option (grub_extcmd_t cmd, int key, char *arg, struct grub_arg_list *usr)
-{
-  switch (key)
-    {
-    case SHORT_ARG_HELP:
-      grub_arg_show_help (cmd);
-      return -1;
-
-    case SHORT_ARG_USAGE:
-      show_usage (cmd);
-      return -1;
-
-    default:
-      {
-       int found = -1;
-       int i = 0;
-       const struct grub_arg_option *opt = cmd->options;
-
-       while (opt->doc)
-         {
-           if (opt->shortarg && key == opt->shortarg)
-             {
-               found = i;
-               break;
-             }
-           opt++;
-           i++;
-         }
-
-       if (found == -1)
-         return -1;
-
-       usr[found].set = 1;
-       usr[found].arg = arg;
-      }
-    }
-
-  return 0;
-}
-
-int
-grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv,
-               struct grub_arg_list *usr, char ***args, int *argnum)
-{
-  int curarg;
-  int arglen;
-  int complete = 0;
-  char **argl = 0;
-  int num = 0;
-  auto grub_err_t add_arg (char *s);
-
-  grub_err_t add_arg (char *s)
-    {
-      argl = grub_realloc (argl, (++num) * sizeof (char *));
-      if (! argl)
-       return grub_errno;
-      argl[num - 1] = s;
-      return 0;
-    }
-
-
-  for (curarg = 0; curarg < argc; curarg++)
-    {
-      char *arg = argv[curarg];
-      struct grub_arg_option *opt;
-      char *option = 0;
-
-      /* No option is used.  */
-      if (arg[0] != '-' || grub_strlen (arg) == 1)
-       {
-         if (add_arg (arg) != 0)
-           goto fail;
-
-         continue;
-       }
-
-      /* One or more short options.  */
-      if (arg[1] != '-')
-       {
-         char *curshort = arg + 1;
-
-         while (1)
-           {
-             opt = find_short (cmd->options, *curshort);
-             if (! opt)
-               {
-                 grub_error (GRUB_ERR_BAD_ARGUMENT,
-                             "unknown argument `-%c'", *curshort);
-                 goto fail;
-               }
-
-             curshort++;
-
-             /* Parse all arguments here except the last one because
-                it can have an argument value.  */
-             if (*curshort)
-               {
-                 if (parse_option (cmd, opt->shortarg, 0, usr) || grub_errno)
-                   goto fail;
-               }
-             else
-               {
-                 if (opt->type != ARG_TYPE_NONE)
-                   {
-                     if (curarg + 1 < argc)
-                       {
-                         char *nextarg = argv[curarg + 1];
-                         if (!(opt->flags & GRUB_ARG_OPTION_OPTIONAL)
-                             || (grub_strlen (nextarg) < 2 || nextarg[0] != '-'))
-                           option = argv[++curarg];
-                       }
-                   }
-                 break;
-               }
-           }
-
-       }
-      else /* The argument starts with "--".  */
-       {
-         /* If the argument "--" is used just pass the other
-            arguments.  */
-         if (grub_strlen (arg) == 2)
-           {
-             for (curarg++; curarg < argc; curarg++)
-               if (add_arg (argv[curarg]) != 0)
-                 goto fail;
-             break;
-           }
-
-         option = grub_strchr (arg, '=');
-         if (option) {
-           arglen = option - arg - 2;
-           option++;
-         } else
-           arglen = grub_strlen (arg) - 2;
-
-         opt = find_long (cmd->options, arg + 2, arglen);
-         if (! opt)
-           {
-             grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown argument `%s'", arg);
-             goto fail;
-           }
-       }
-
-      if (! (opt->type == ARG_TYPE_NONE
-            || (! option && (opt->flags & GRUB_ARG_OPTION_OPTIONAL))))
-       {
-         if (! option)
-           {
-             grub_error (GRUB_ERR_BAD_ARGUMENT,
-                         "missing mandatory option for `%s'", opt->longarg);
-             goto fail;
-           }
-
-         switch (opt->type)
-           {
-           case ARG_TYPE_NONE:
-             /* This will never happen.  */
-             break;
-
-           case ARG_TYPE_STRING:
-                 /* No need to do anything.  */
-             break;
-
-           case ARG_TYPE_INT:
-             {
-               char *tail;
-
-               grub_strtoull (option, &tail, 0);
-               if (tail == 0 || tail == option || *tail != '\0' || grub_errno)
-                 {
-                   grub_error (GRUB_ERR_BAD_ARGUMENT,
-                               "the argument `%s' requires an integer",
-                               arg);
-
-                   goto fail;
-                 }
-               break;
-             }
-
-           case ARG_TYPE_DEVICE:
-           case ARG_TYPE_DIR:
-           case ARG_TYPE_FILE:
-           case ARG_TYPE_PATHNAME:
-             /* XXX: Not implemented.  */
-             break;
-           }
-         if (parse_option (cmd, opt->shortarg, option, usr) || grub_errno)
-           goto fail;
-       }
-      else
-       {
-         if (option)
-           {
-             grub_error (GRUB_ERR_BAD_ARGUMENT,
-                         "a value was assigned to the argument `%s' while it "
-                         "doesn't require an argument", arg);
-             goto fail;
-           }
-
-         if (parse_option (cmd, opt->shortarg, 0, usr) || grub_errno)
-           goto fail;
-       }
-    }
-
-  complete = 1;
-
-  *args = argl;
-  *argnum = num;
-
- fail:
-  return complete;
-}
diff --git a/lib/charset.c b/lib/charset.c
deleted file mode 100644 (file)
index f2e1b03..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
-   bytes (if SRCSIZE is -1, it is ignored) in length to a UTF-16 string.
-   Return the number of characters converted. DEST must be able to hold
-   at least DESTSIZE characters. If an invalid sequence is found, return -1.
-   If SRCEND is not NULL, then *SRCEND is set to the next byte after the
-   last byte used in SRC.  */
-
-#include <grub/charset.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-
-grub_ssize_t
-grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
-                   const grub_uint8_t *src, grub_size_t srcsize,
-                   const grub_uint8_t **srcend)
-{
-  grub_uint16_t *p = dest;
-  int count = 0;
-  grub_uint32_t code = 0;
-
-  if (srcend)
-    *srcend = src;
-
-  while (srcsize && destsize)
-    {
-      grub_uint32_t c = *src++;
-      if (srcsize != (grub_size_t)-1)
-       srcsize--;
-      if (count)
-       {
-         if ((c & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT)
-           {
-             /* invalid */
-             return -1;
-           }
-         else
-           {
-             code <<= 6;
-             code |= (c & GRUB_UINT8_6_TRAILINGBITS);
-             count--;
-           }
-       }
-      else
-       {
-         if (c == 0)
-           break;
-
-         if ((c & GRUB_UINT8_1_LEADINGBIT) == 0)
-           code = c;
-         else if ((c & GRUB_UINT8_3_LEADINGBITS) == GRUB_UINT8_2_LEADINGBITS)
-           {
-             count = 1;
-             code = c & GRUB_UINT8_5_TRAILINGBITS;
-           }
-         else if ((c & GRUB_UINT8_4_LEADINGBITS) == GRUB_UINT8_3_LEADINGBITS)
-           {
-             count = 2;
-             code = c & GRUB_UINT8_4_TRAILINGBITS;
-           }
-         else if ((c & GRUB_UINT8_5_LEADINGBITS) == GRUB_UINT8_4_LEADINGBITS)
-           {
-             count = 3;
-             code = c & GRUB_UINT8_3_TRAILINGBITS;
-           }
-         else if ((c & GRUB_UINT8_6_LEADINGBITS) == GRUB_UINT8_5_LEADINGBITS)
-           {
-             count = 4;
-             code = c & GRUB_UINT8_2_TRAILINGBITS;
-           }
-         else if ((c & GRUB_UINT8_7_LEADINGBITS) == GRUB_UINT8_6_LEADINGBITS)
-           {
-             count = 5;
-             code = c & GRUB_UINT8_1_TRAILINGBIT;
-           }
-         else
-           return -1;
-       }
-
-      if (count == 0)
-       {
-         if (destsize < 2 && code >= GRUB_UCS2_LIMIT)
-           break;
-         if (code >= GRUB_UCS2_LIMIT)
-           {
-             *p++ = GRUB_UTF16_UPPER_SURROGATE (code);
-             *p++ = GRUB_UTF16_LOWER_SURROGATE (code);
-             destsize -= 2;
-           }
-         else
-           {
-             *p++ = code;
-             destsize--;
-           }
-       }
-    }
-
-  if (srcend)
-    *srcend = src;
-  return p - dest;
-}
-
-/* Convert UCS-4 to UTF-8.  */
-char *
-grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size)
-{
-  grub_size_t remaining;
-  grub_uint32_t *ptr;
-  grub_size_t cnt = 0;
-  grub_uint8_t *ret, *dest;
-
-  remaining = size;
-  ptr = src;
-  while (remaining--)
-    {
-      grub_uint32_t code = *ptr++;
-      
-      if (code <= 0x007F)
-       cnt++;
-      else if (code <= 0x07FF)
-       cnt += 2;
-      else if ((code >= 0xDC00 && code <= 0xDFFF)
-              || (code >= 0xD800 && code <= 0xDBFF))
-       /* No surrogates in UCS-4... */
-       cnt++;
-      else
-       cnt += 3;
-    }
-  cnt++;
-
-  ret = grub_malloc (cnt);
-  if (!ret)
-    return 0;
-
-  dest = ret;
-  remaining = size;
-  ptr = src;
-  while (remaining--)
-    {
-      grub_uint32_t code = *ptr++;
-
-      if (code <= 0x007F)
-       *dest++ = code;
-      else if (code <= 0x07FF)
-       {
-         *dest++ = (code >> 6) | 0xC0;
-         *dest++ = (code & 0x3F) | 0x80;
-       }
-      else if ((code >= 0xDC00 && code <= 0xDFFF)
-              || (code >= 0xD800 && code <= 0xDBFF))
-       {
-         /* No surrogates in UCS-4... */
-         *dest++ = '?';
-       }
-      else
-       {
-         *dest++ = (code >> 12) | 0xE0;
-         *dest++ = ((code >> 6) & 0x3F) | 0x80;
-         *dest++ = (code & 0x3F) | 0x80;
-       }
-    }
-  *dest = 0;
-
-  return (char *) ret;
-}
-
-int
-grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize)
-{
-  grub_uint32_t code = 0;
-  int count = 0;
-
-  while (srcsize)
-    {
-      grub_uint32_t c = *src++;
-      if (srcsize != (grub_size_t)-1)
-       srcsize--;
-      if (count)
-       {
-         if ((c & 0xc0) != 0x80)
-           {
-             /* invalid */
-             return 0;
-           }
-         else
-           {
-             code <<= 6;
-             code |= (c & 0x3f);
-             count--;
-           }
-       }
-      else
-       {
-         if (c == 0)
-           break;
-
-         if ((c & 0x80) == 0x00)
-           code = c;
-         else if ((c & 0xe0) == 0xc0)
-           {
-             count = 1;
-             code = c & 0x1f;
-           }
-         else if ((c & 0xf0) == 0xe0)
-           {
-             count = 2;
-             code = c & 0x0f;
-           }
-         else if ((c & 0xf8) == 0xf0)
-           {
-             count = 3;
-             code = c & 0x07;
-           }
-         else if ((c & 0xfc) == 0xf8)
-           {
-             count = 4;
-             code = c & 0x03;
-           }
-         else if ((c & 0xfe) == 0xfc)
-           {
-             count = 5;
-             code = c & 0x01;
-           }
-         else
-           return 0;
-       }
-    }
-
-  return 1;
-}
-
-int
-grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
-                       grub_uint32_t **last_position)
-{
-  grub_size_t msg_len = grub_strlen (msg);
-
-  *unicode_msg = grub_malloc (grub_strlen (msg) * sizeof (grub_uint32_t));
-  if (!*unicode_msg)
-    {
-      grub_printf ("utf8_to_ucs4 ERROR1: %s", msg);
-      return -1;
-    }
-
-  msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len,
-                             (grub_uint8_t *) msg, -1, 0);
-
-  *last_position = *unicode_msg + msg_len;
-
-  return msg_len;
-}
diff --git a/lib/cmos_datetime.c b/lib/cmos_datetime.c
deleted file mode 100644 (file)
index 8db60b4..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/* kern/cmos_datetime.c - CMOS datetime function.
- *
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/datetime.h>
-#include <grub/cmos.h>
-
-grub_err_t
-grub_get_datetime (struct grub_datetime *datetime)
-{
-  int is_bcd, is_12hour;
-  grub_uint8_t value, flag;
-
-  flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B);
-
-  is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY);
-
-  value = grub_cmos_read (GRUB_CMOS_INDEX_YEAR);
-  if (is_bcd)
-    value = grub_bcd_to_num (value);
-
-  datetime->year = value;
-  datetime->year += (value < 80) ? 2000 : 1900;
-
-  value = grub_cmos_read (GRUB_CMOS_INDEX_MONTH);
-  if (is_bcd)
-    value = grub_bcd_to_num (value);
-
-  datetime->month = value;
-
-  value = grub_cmos_read (GRUB_CMOS_INDEX_DAY_OF_MONTH);
-  if (is_bcd)
-    value = grub_bcd_to_num (value);
-
-  datetime->day = value;
-
-  is_12hour = ! (flag & GRUB_CMOS_STATUS_B_24HOUR);
-
-  value = grub_cmos_read (GRUB_CMOS_INDEX_HOUR);
-  if (is_12hour)
-    {
-      is_12hour = (value & 0x80);
-
-      value &= 0x7F;
-      value--;
-    }
-
-  if (is_bcd)
-    value = grub_bcd_to_num (value);
-
-  if (is_12hour)
-    value += 12;
-
-  datetime->hour = value;
-
-  value = grub_cmos_read (GRUB_CMOS_INDEX_MINUTE);
-  if (is_bcd)
-    value = grub_bcd_to_num (value);
-
-  datetime->minute = value;
-
-  value = grub_cmos_read (GRUB_CMOS_INDEX_SECOND);
-  if (is_bcd)
-    value = grub_bcd_to_num (value);
-
-  datetime->second = value;
-
-  return 0;
-}
-
-grub_err_t
-grub_set_datetime (struct grub_datetime *datetime)
-{
-  int is_bcd, is_12hour;
-  grub_uint8_t value, flag;
-
-  flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B);
-
-  is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY);
-
-  value = ((datetime->year >= 2000) ? datetime->year - 2000 :
-           datetime->year - 1900);
-
-  if (is_bcd)
-    value = grub_num_to_bcd (value);
-
-  grub_cmos_write (GRUB_CMOS_INDEX_YEAR, value);
-
-  value = datetime->month;
-
-  if (is_bcd)
-    value = grub_num_to_bcd (value);
-
-  grub_cmos_write (GRUB_CMOS_INDEX_MONTH, value);
-
-  value = datetime->day;
-
-  if (is_bcd)
-    value = grub_num_to_bcd (value);
-
-  grub_cmos_write (GRUB_CMOS_INDEX_DAY_OF_MONTH, value);
-
-  value = datetime->hour;
-
-  is_12hour = (! (flag & GRUB_CMOS_STATUS_B_24HOUR));
-
-  if (is_12hour)
-    {
-      value++;
-
-      if (value > 12)
-        value -= 12;
-      else
-        is_12hour = 0;
-    }
-
-  if (is_bcd)
-    value = grub_num_to_bcd (value);
-
-  if (is_12hour)
-    value |= 0x80;
-
-  grub_cmos_write (GRUB_CMOS_INDEX_HOUR, value);
-
-  value = datetime->minute;
-
-  if (is_bcd)
-    value = grub_num_to_bcd (value);
-
-  grub_cmos_write (GRUB_CMOS_INDEX_MINUTE, value);
-
-  value = datetime->second;
-
-  if (is_bcd)
-    value = grub_num_to_bcd (value);
-
-  grub_cmos_write (GRUB_CMOS_INDEX_SECOND, value);
-
-  return 0;
-}
diff --git a/lib/crc.c b/lib/crc.c
deleted file mode 100644 (file)
index bc0d8aa..0000000
--- a/lib/crc.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/* crc.c - crc function  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/lib/crc.h>
-
-static grub_uint32_t crc32_table [256];
-
-static void
-init_crc32_table (void)
-{
-  auto grub_uint32_t reflect (grub_uint32_t ref, int len);
-  grub_uint32_t reflect (grub_uint32_t ref, int len)
-    {
-      grub_uint32_t result = 0;
-      int i;
-
-      for (i = 1; i <= len; i++)
-        {
-          if (ref & 1)
-            result |= 1 << (len - i);
-          ref >>= 1;
-        }
-
-      return result;
-    }
-
-  grub_uint32_t polynomial = 0x04c11db7;
-  int i, j;
-
-  for(i = 0; i < 256; i++)
-    {
-      crc32_table[i] = reflect(i, 8) << 24;
-      for (j = 0; j < 8; j++)
-        crc32_table[i] = (crc32_table[i] << 1) ^
-            (crc32_table[i] & (1 << 31) ? polynomial : 0);
-      crc32_table[i] = reflect(crc32_table[i], 32);
-    }
-}
-
-grub_uint32_t
-grub_getcrc32 (grub_uint32_t crc, void *buf, int size)
-{
-  int i;
-  grub_uint8_t *data = buf;
-
-  if (! crc32_table[1])
-    init_crc32_table ();
-
-  crc^= 0xffffffff;
-
-  for (i = 0; i < size; i++)
-    {
-      crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ *data];
-      data++;
-    }
-
-  return crc ^ 0xffffffff;
-}
diff --git a/lib/crypto.c b/lib/crypto.c
deleted file mode 100644 (file)
index d11f099..0000000
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
- *                2007, 2008, 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/crypto.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/term.h>
-
-struct grub_crypto_hmac_handle
-{
-  const struct gcry_md_spec *md;
-  void *ctx;
-  void *opad;
-};
-
-static gcry_cipher_spec_t *grub_ciphers = NULL;
-static gcry_md_spec_t *grub_digests = NULL;
-
-void (*grub_crypto_autoload_hook) (const char *name) = NULL;
-
-/* Based on libgcrypt-1.4.4/src/misc.c.  */
-void
-grub_burn_stack (grub_size_t size)
-{
-  char buf[64];
-
-  grub_memset (buf, 0, sizeof (buf));
-  if (size > sizeof (buf))
-    grub_burn_stack (size - sizeof (buf));
-}
-
-
-void 
-grub_cipher_register (gcry_cipher_spec_t *cipher)
-{
-  cipher->next = grub_ciphers;
-  grub_ciphers = cipher;
-}
-
-void
-grub_cipher_unregister (gcry_cipher_spec_t *cipher)
-{
-  gcry_cipher_spec_t **ciph;
-  for (ciph = &grub_ciphers; *ciph; ciph = &((*ciph)->next))
-    if (*ciph == cipher)
-      {
-       *ciph = (*ciph)->next;
-       break;
-      }
-}
-
-void 
-grub_md_register (gcry_md_spec_t *digest)
-{
-  digest->next = grub_digests;
-  grub_digests = digest;
-}
-
-void 
-grub_md_unregister (gcry_md_spec_t *cipher)
-{
-  gcry_md_spec_t **ciph;
-  for (ciph = &grub_digests; *ciph; ciph = &((*ciph)->next))
-    if (*ciph == cipher)
-      {
-       *ciph = (*ciph)->next;
-       break;
-      }
-}
-
-void
-grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in,
-                 grub_size_t inlen)
-{
-  grub_uint8_t ctx[hash->contextsize];
-  hash->init (&ctx);
-  hash->write (&ctx, in, inlen);
-  hash->final (&ctx);
-  grub_memcpy (out, hash->read (&ctx), hash->mdlen);
-}
-
-const gcry_md_spec_t *
-grub_crypto_lookup_md_by_name (const char *name)
-{
-  const gcry_md_spec_t *md;
-  int first = 1;
-  while (1)
-    {
-      for (md = grub_digests; md; md = md->next)
-       if (grub_strcasecmp (name, md->name) == 0)
-         return md;
-      if (grub_crypto_autoload_hook && first)
-       grub_crypto_autoload_hook (name);
-      else
-       return NULL;
-      first = 0;
-    }
-}
-
-const gcry_cipher_spec_t *
-grub_crypto_lookup_cipher_by_name (const char *name)
-{
-  const gcry_cipher_spec_t *ciph;
-  int first = 1;
-  while (1)
-    {
-      for (ciph = grub_ciphers; ciph; ciph = ciph->next)
-       {
-         const char **alias;
-         if (grub_strcasecmp (name, ciph->name) == 0)
-           return ciph;
-         if (!ciph->aliases)
-           continue;
-         for (alias = ciph->aliases; *alias; alias++)
-           if (grub_strcasecmp (name, *alias) == 0)
-             return ciph;
-       }
-      if (grub_crypto_autoload_hook && first)
-       grub_crypto_autoload_hook (name);
-      else
-       return NULL;
-      first = 0;
-    }
-}
-
-
-grub_crypto_cipher_handle_t
-grub_crypto_cipher_open (const struct gcry_cipher_spec *cipher)
-{
-  grub_crypto_cipher_handle_t ret;
-  ret = grub_malloc (sizeof (*ret) + cipher->contextsize);
-  if (!ret)
-    return NULL;
-  ret->cipher = cipher;
-  return ret;
-}
-
-gcry_err_code_t
-grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher,
-                           const unsigned char *key,
-                           unsigned keylen)
-{
-  return cipher->cipher->setkey (cipher->ctx, key, keylen);
-}
-
-
-void
-grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher)
-{
-  grub_free (cipher);
-}
-
-
-void
-grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size)
-{
-  const grub_uint8_t *in1ptr = in1, *in2ptr = in2;
-  grub_uint8_t *outptr = out;
-  while (size--)
-    {
-      *outptr = *in1ptr ^ *in2ptr;
-      in1ptr++;
-      in2ptr++;
-      outptr++;
-    }
-}
-
-gcry_err_code_t
-grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
-                        void *out, void *in, grub_size_t size)
-{
-  grub_uint8_t *inptr, *outptr, *end;
-  if (!cipher->cipher->decrypt)
-    return GPG_ERR_NOT_SUPPORTED;
-  if (size % cipher->cipher->blocksize != 0)
-    return GPG_ERR_INV_ARG;
-  end = (grub_uint8_t *) in + size;
-  for (inptr = in, outptr = out; inptr < end;
-       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
-    cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
-  return GPG_ERR_NO_ERROR;
-}
-
-gcry_err_code_t
-grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher,
-                        void *out, void *in, grub_size_t size)
-{
-  grub_uint8_t *inptr, *outptr, *end;
-  if (!cipher->cipher->encrypt)
-    return GPG_ERR_NOT_SUPPORTED;
-  if (size % cipher->cipher->blocksize != 0)
-    return GPG_ERR_INV_ARG;
-  end = (grub_uint8_t *) in + size;
-  for (inptr = in, outptr = out; inptr < end;
-       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
-    cipher->cipher->encrypt (cipher->ctx, outptr, inptr);
-  return GPG_ERR_NO_ERROR;
-}
-
-gcry_err_code_t
-grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher,
-                        void *out, void *in, grub_size_t size,
-                        void *iv_in)
-{
-  grub_uint8_t *inptr, *outptr, *end;
-  void *iv;
-  if (!cipher->cipher->decrypt)
-    return GPG_ERR_NOT_SUPPORTED;
-  if (size % cipher->cipher->blocksize != 0)
-    return GPG_ERR_INV_ARG;
-  end = (grub_uint8_t *) in + size;
-  iv = iv_in;
-  for (inptr = in, outptr = out; inptr < end;
-       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
-    {
-      grub_crypto_xor (outptr, inptr, iv, cipher->cipher->blocksize);
-      cipher->cipher->encrypt (cipher->ctx, outptr, outptr);
-      iv = outptr;
-    }
-  grub_memcpy (iv_in, iv, cipher->cipher->blocksize);
-  return GPG_ERR_NO_ERROR;
-}
-
-gcry_err_code_t
-grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher,
-                        void *out, void *in, grub_size_t size,
-                        void *iv)
-{
-  grub_uint8_t *inptr, *outptr, *end;
-  grub_uint8_t ivt[cipher->cipher->blocksize];
-  if (!cipher->cipher->decrypt)
-    return GPG_ERR_NOT_SUPPORTED;
-  if (size % cipher->cipher->blocksize != 0)
-    return GPG_ERR_INV_ARG;
-  end = (grub_uint8_t *) in + size;
-  for (inptr = in, outptr = out; inptr < end;
-       inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
-    {
-      grub_memcpy (ivt, inptr, cipher->cipher->blocksize);
-      cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
-      grub_crypto_xor (outptr, outptr, iv, cipher->cipher->blocksize);
-      grub_memcpy (iv, ivt, cipher->cipher->blocksize);
-    }
-  return GPG_ERR_NO_ERROR;
-}
-
-/* Based on gcry/cipher/md.c.  */
-struct grub_crypto_hmac_handle *
-grub_crypto_hmac_init (const struct gcry_md_spec *md,
-                      const void *key, grub_size_t keylen)
-{
-  grub_uint8_t *helpkey = NULL;
-  grub_uint8_t *ipad = NULL, *opad = NULL;
-  void *ctx = NULL;
-  struct grub_crypto_hmac_handle *ret = NULL;
-  unsigned i;
-
-  if (md->mdlen > md->blocksize)
-    return NULL;
-
-  ctx = grub_malloc (md->contextsize);
-  if (!ctx)
-    goto err;
-
-  if ( keylen > md->blocksize ) 
-    {
-      helpkey = grub_malloc (md->mdlen);
-      if (!helpkey)
-       goto err;
-      grub_crypto_hash (md, helpkey, key, keylen);
-
-      key = helpkey;
-      keylen = md->mdlen;
-    }
-
-  ipad = grub_zalloc (md->blocksize);
-  if (!ipad)
-    goto err;
-
-  opad = grub_zalloc (md->blocksize);
-  if (!opad)
-    goto err;
-
-  grub_memcpy ( ipad, key, keylen );
-  grub_memcpy ( opad, key, keylen );
-  for (i=0; i < md->blocksize; i++ ) 
-    {
-      ipad[i] ^= 0x36;
-      opad[i] ^= 0x5c;
-    }
-  grub_free (helpkey);
-  helpkey = NULL;
-
-  md->init (ctx);
-
-  md->write (ctx, ipad, md->blocksize); /* inner pad */
-  grub_memset (ipad, 0, md->blocksize);
-  grub_free (ipad);
-  ipad = NULL;
-
-  ret = grub_malloc (sizeof (*ret));
-  if (!ret)
-    goto err;
-
-  ret->md = md;
-  ret->ctx = ctx;
-  ret->opad = opad;
-
-  return ret;
-
- err:
-  grub_free (helpkey);
-  grub_free (ctx);
-  grub_free (ipad);
-  grub_free (opad);
-  return NULL;
-}
-
-void
-grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd, void *data,
-                       grub_size_t datalen)
-{
-  hnd->md->write (hnd->ctx, data, datalen);
-}
-
-gcry_err_code_t
-grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out)
-{
-  grub_uint8_t *p;
-  grub_uint8_t *ctx2;
-
-  ctx2 = grub_malloc (hnd->md->contextsize);
-  if (!ctx2)
-    return GPG_ERR_OUT_OF_MEMORY;
-
-  hnd->md->final (hnd->ctx);
-  hnd->md->read (hnd->ctx);
-  p = hnd->md->read (hnd->ctx);
-
-  hnd->md->init (ctx2);
-  hnd->md->write (ctx2, hnd->opad, hnd->md->blocksize);
-  hnd->md->write (ctx2, p, hnd->md->mdlen);
-  hnd->md->final (ctx2);
-  grub_memset (hnd->opad, 0, hnd->md->blocksize);
-  grub_free (hnd->opad);
-  grub_memset (hnd->ctx, 0, hnd->md->contextsize);
-  grub_free (hnd->ctx);
-
-  grub_memcpy (out, hnd->md->read (ctx2), hnd->md->mdlen);
-  grub_memset (ctx2, 0, hnd->md->contextsize);
-  grub_free (ctx2);
-
-  grub_memset (hnd, 0, sizeof (*hnd));
-  grub_free (hnd);
-
-  return GPG_ERR_NO_ERROR;
-}
-
-gcry_err_code_t
-grub_crypto_hmac_buffer (const struct gcry_md_spec *md,
-                        const void *key, grub_size_t keylen,
-                        void *data, grub_size_t datalen, void *out)
-{
-  struct grub_crypto_hmac_handle *hnd;
-
-  hnd = grub_crypto_hmac_init (md, key, keylen);
-  if (!hnd)
-    return GPG_ERR_OUT_OF_MEMORY;
-
-  grub_crypto_hmac_write (hnd, data, datalen);
-  return grub_crypto_hmac_fini (hnd, out);
-}
-
-
-grub_err_t
-grub_crypto_gcry_error (gcry_err_code_t in)
-{
-  if (in == GPG_ERR_NO_ERROR)
-    return GRUB_ERR_NONE;
-  return GRUB_ACCESS_DENIED;
-}
-
-int
-grub_crypto_memcmp (const void *a, const void *b, grub_size_t n)
-{
-  register grub_size_t counter = 0;
-  const grub_uint8_t *pa, *pb;
-
-  for (pa = a, pb = b; n; pa++, pb++, n--)
-    {
-      if (*pa != *pb)
-       counter++;
-    }
-
-  return !!counter;
-}
-
-#ifndef GRUB_MKPASSWD
-int
-grub_password_get (char buf[], unsigned buf_size)
-{
-  unsigned cur_len = 0;
-  int key;
-
-  while (1)
-    {
-      key = GRUB_TERM_ASCII_CHAR (grub_getkey ()); 
-      if (key == '\n' || key == '\r')
-       break;
-
-      if (key == '\e')
-       {
-         cur_len = 0;
-         break;
-       }
-
-      if (key == '\b')
-       {
-         cur_len--;
-         continue;
-       }
-
-      if (!grub_isprint (key))
-       continue;
-
-      if (cur_len + 2 < buf_size)
-       buf[cur_len++] = key;
-    }
-
-  grub_memset (buf + cur_len, 0, buf_size - cur_len);
-
-  grub_putchar ('\n');
-  grub_refresh ();
-
-  return (key != '\e');
-}
-#endif
diff --git a/lib/efi/datetime.c b/lib/efi/datetime.c
deleted file mode 100644 (file)
index 0a91c34..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/* kern/efi/datetime.c - efi datetime function.
- *
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/symbol.h>
-#include <grub/efi/api.h>
-#include <grub/efi/efi.h>
-#include <grub/datetime.h>
-
-grub_err_t
-grub_get_datetime (struct grub_datetime *datetime)
-{
-  grub_efi_status_t status;
-  struct grub_efi_time efi_time;
-
-  status = efi_call_2 (grub_efi_system_table->runtime_services->get_time,
-                       &efi_time, 0);
-
-  if (status)
-    return grub_error (GRUB_ERR_INVALID_COMMAND,
-                       "can\'t get datetime using efi");
-  else
-    {
-      datetime->year = efi_time.year;
-      datetime->month = efi_time.month;
-      datetime->day = efi_time.day;
-      datetime->hour = efi_time.hour;
-      datetime->minute = efi_time.minute;
-      datetime->second = efi_time.second;
-    }
-
-  return 0;
-}
-
-grub_err_t
-grub_set_datetime (struct grub_datetime *datetime)
-{
-  grub_efi_status_t status;
-  struct grub_efi_time efi_time;
-
-  status = efi_call_2 (grub_efi_system_table->runtime_services->get_time,
-                       &efi_time, 0);
-
-  if (status)
-    return grub_error (GRUB_ERR_INVALID_COMMAND,
-                       "can\'t get datetime using efi");
-
-  efi_time.year = datetime->year;
-  efi_time.month = datetime->month;
-  efi_time.day = datetime->day;
-  efi_time.hour = datetime->hour;
-  efi_time.minute = datetime->minute;
-  efi_time.second = datetime->second;
-
-  status = efi_call_1 (grub_efi_system_table->runtime_services->set_time,
-                       &efi_time);
-
-  if (status)
-    return grub_error (GRUB_ERR_INVALID_COMMAND,
-                       "can\'t set datetime using efi");
-
-  return 0;
-}
diff --git a/lib/envblk.c b/lib/envblk.c
deleted file mode 100644 (file)
index 311927b..0000000
+++ /dev/null
@@ -1,296 +0,0 @@
-/* envblk.c - Common functions for environment block.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/lib/envblk.h>
-
-grub_envblk_t
-grub_envblk_open (char *buf, grub_size_t size)
-{
-  grub_envblk_t envblk;
-
-  if (size < sizeof (GRUB_ENVBLK_SIGNATURE)
-      || grub_memcmp (buf, GRUB_ENVBLK_SIGNATURE,
-                      sizeof (GRUB_ENVBLK_SIGNATURE) - 1))
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block");
-      return 0;
-    }
-
-  envblk = grub_malloc (sizeof (*envblk));
-  if (envblk)
-    {
-      envblk->buf = buf;
-      envblk->size = size;
-    }
-
-  return envblk;
-}
-
-void
-grub_envblk_close (grub_envblk_t envblk)
-{
-  grub_free (envblk->buf);
-  grub_free (envblk);
-}
-
-static int
-escaped_value_len (const char *value)
-{
-  int n = 0;
-  char *p;
-
-  for (p = (char *) value; *p; p++)
-    {
-      if (*p == '\\' || *p == '\n')
-        n += 2;
-      else
-        n++;
-    }
-
-  return n;
-}
-
-static char *
-find_next_line (char *p, const char *pend)
-{
-  while (p < pend)
-    {
-      if (*p == '\\')
-        p += 2;
-      else if (*p == '\n')
-        break;
-      else
-        p++;
-    }
-
-  return p + 1;
-}
-
-int
-grub_envblk_set (grub_envblk_t envblk, const char *name, const char *value)
-{
-  char *p, *pend;
-  char *space;
-  int found = 0;
-  int nl;
-  int vl;
-  int i;
-
-  nl = grub_strlen (name);
-  vl = escaped_value_len (value);
-  p = envblk->buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
-  pend = envblk->buf + envblk->size;
-
-  /* First, look at free space.  */
-  for (space = pend - 1; *space == '#'; space--)
-    ;
-
-  if (*space != '\n')
-    /* Broken.  */
-    return 0;
-
-  space++;
-
-  while (p + nl + 1 < space)
-    {
-      if (grub_memcmp (p, name, nl) == 0 && p[nl] == '=')
-        {
-          int len;
-
-          /* Found the same name.  */
-          p += nl + 1;
-
-          /* Check the length of the current value.  */
-          len = 0;
-          while (p + len < pend && p[len] != '\n')
-            {
-              if (p[len] == '\\')
-                len += 2;
-              else
-                len++;
-            }
-
-          if (p + len >= pend)
-            /* Broken.  */
-            return 0;
-
-          if (pend - space < vl - len)
-            /* No space.  */
-            return 0;
-
-          if (vl < len)
-            {
-              /* Move the following characters backward, and fill the new
-                 space with harmless characters.  */
-              grub_memmove (p + vl, p + len, pend - (p + len));
-              grub_memset (space + len - vl, '#', len - vl);
-            }
-          else
-            /* Move the following characters forward.  */
-            grub_memmove (p + vl, p + len, pend - (p + vl));
-
-          found = 1;
-          break;
-        }
-
-      p = find_next_line (p, pend);
-    }
-
-  if (! found)
-    {
-      /* Append a new variable.  */
-
-      if (pend - space < nl + 1 + vl + 1)
-        /* No space.  */
-        return 0;
-
-      grub_memcpy (space, name, nl);
-      p = space + nl;
-      *p++ = '=';
-    }
-
-  /* Write the value.  */
-  for (i = 0; value[i]; i++)
-    {
-      if (value[i] == '\\' || value[i] == '\n')
-        *p++ = '\\';
-
-      *p++ = value[i];
-    }
-
-  *p = '\n';
-  return 1;
-}
-
-void
-grub_envblk_delete (grub_envblk_t envblk, const char *name)
-{
-  char *p, *pend;
-  int nl;
-
-  nl = grub_strlen (name);
-  p = envblk->buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
-  pend = envblk->buf + envblk->size;
-
-  while (p + nl + 1 < pend)
-    {
-      if (grub_memcmp (p, name, nl) == 0 && p[nl] == '=')
-        {
-          /* Found.  */
-          int len = nl + 1;
-
-          while (p + len < pend)
-            {
-              if (p[len] == '\n')
-                break;
-              else if (p[len] == '\\')
-                len += 2;
-              else
-                len++;
-            }
-
-          if (p + len >= pend)
-            /* Broken.  */
-            return;
-
-          len++;
-          grub_memmove (p, p + len, pend - (p + len));
-          grub_memset (pend - len, '#', len);
-          break;
-        }
-
-      p = find_next_line (p, pend);
-    }
-}
-
-void
-grub_envblk_iterate (grub_envblk_t envblk,
-                     int hook (const char *name, const char *value))
-{
-  char *p, *pend;
-
-  p = envblk->buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
-  pend = envblk->buf + envblk->size;
-
-  while (p < pend)
-    {
-      if (*p != '#')
-        {
-          char *name;
-          char *value;
-          char *name_start, *name_end, *value_start;
-          char *q;
-          int ret;
-
-          name_start = p;
-          while (p < pend && *p != '=')
-            p++;
-          if (p == pend)
-            /* Broken.  */
-            return;
-          name_end = p;
-
-          p++;
-          value_start = p;
-          while (p < pend)
-            {
-              if (*p == '\n')
-                break;
-              else if (*p == '\\')
-                p += 2;
-              else
-                p++;
-            }
-
-          if (p >= pend)
-            /* Broken.  */
-            return;
-
-          name = grub_malloc (p - name_start + 1);
-          if (! name)
-            /* out of memory.  */
-            return;
-
-          value = name + (value_start - name_start);
-
-          grub_memcpy (name, name_start, name_end - name_start);
-          name[name_end - name_start] = '\0';
-
-          for (p = value_start, q = value; *p != '\n'; ++p)
-            {
-              if (*p == '\\')
-                *q++ = *++p;
-              else
-                *q++ = *p;
-            }
-          *q = '\0';
-
-          ret = hook (name, value);
-          grub_free (name);
-          if (ret)
-            return;
-        }
-
-      p = find_next_line (p, pend);
-    }
-}
diff --git a/lib/hexdump.c b/lib/hexdump.c
deleted file mode 100644 (file)
index 317635a..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* hexdump.c - hexdump function */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/lib/hexdump.h>
-
-void
-hexdump (unsigned long bse, char *buf, int len)
-{
-  int pos;
-  char line[80];
-
-  while (len > 0)
-    {
-      int cnt, i;
-
-      pos = grub_snprintf (line, sizeof (line), "%08lx  ", bse);
-      cnt = 16;
-      if (cnt > len)
-       cnt = len;
-
-      for (i = 0; i < cnt; i++)
-       {
-         pos += grub_snprintf (&line[pos], sizeof (line) - pos,
-                               "%02x ", (unsigned char) buf[i]);
-         if ((i & 7) == 7)
-           line[pos++] = ' ';
-       }
-
-      for (; i < 16; i++)
-       {
-         pos += grub_snprintf (&line[pos], sizeof (line) - pos, "   ");
-         if ((i & 7) == 7)
-           line[pos++] = ' ';
-       }
-
-      line[pos++] = '|';
-
-      for (i = 0; i < cnt; i++)
-       line[pos++] = ((buf[i] >= 32) && (buf[i] < 127)) ? buf[i] : '.';
-
-      line[pos++] = '|';
-
-      line[pos] = 0;
-
-      grub_printf ("%s\n", line);
-
-      /* Print only first and last line if more than 3 lines are identical.  */
-      if (len >= 4 * 16
-         && ! grub_memcmp (buf, buf + 1 * 16, 16)
-         && ! grub_memcmp (buf, buf + 2 * 16, 16)
-         && ! grub_memcmp (buf, buf + 3 * 16, 16))
-       {
-         grub_printf ("*\n");
-         do
-           {
-             bse += 16;
-             buf += 16;
-             len -= 16;
-           }
-         while (len >= 3 * 16 && ! grub_memcmp (buf, buf + 2 * 16, 16));
-       }
-
-      bse += 16;
-      buf += 16;
-      len -= cnt;
-    }
-}
diff --git a/lib/i386/pc/biosnum.c b/lib/i386/pc/biosnum.c
deleted file mode 100644 (file)
index 058c9d3..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/env.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-
-static int
-grub_get_root_biosnumber_default (void)
-{
-  char *biosnum;
-  int ret = -1;
-  grub_device_t dev;
-
-  biosnum = grub_env_get ("biosnum");
-
-  if (biosnum)
-    return grub_strtoul (biosnum, 0, 0);
-
-  dev = grub_device_open (0);
-  if (dev && dev->disk && dev->disk->dev
-      && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID)
-    ret = (int) dev->disk->id;
-
-  if (dev)
-    grub_device_close (dev);
-
-  return ret;
-}
-
-int (*grub_get_root_biosnumber) (void) = grub_get_root_biosnumber_default;
diff --git a/lib/i386/relocator.c b/lib/i386/relocator.c
deleted file mode 100644 (file)
index 453f73f..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/misc.h>
-
-#include <grub/types.h>
-#include <grub/types.h>
-#include <grub/err.h>
-
-#include <grub/i386/relocator.h>
-
-extern grub_uint8_t grub_relocator32_forward_start;
-extern grub_uint8_t grub_relocator32_forward_end;
-extern grub_uint8_t grub_relocator32_backward_start;
-extern grub_uint8_t grub_relocator32_backward_end;
-
-extern grub_uint32_t grub_relocator32_backward_dest;
-extern grub_uint32_t grub_relocator32_backward_size;
-extern grub_addr_t grub_relocator32_backward_src;
-
-extern grub_uint32_t grub_relocator32_forward_dest;
-extern grub_uint32_t grub_relocator32_forward_size;
-extern grub_addr_t grub_relocator32_forward_src;
-
-extern grub_uint32_t grub_relocator32_forward_eax;
-extern grub_uint32_t grub_relocator32_forward_ebx;
-extern grub_uint32_t grub_relocator32_forward_ecx;
-extern grub_uint32_t grub_relocator32_forward_edx;
-extern grub_uint32_t grub_relocator32_forward_eip;
-extern grub_uint32_t grub_relocator32_forward_esp;
-
-extern grub_uint32_t grub_relocator32_backward_eax;
-extern grub_uint32_t grub_relocator32_backward_ebx;
-extern grub_uint32_t grub_relocator32_backward_ecx;
-extern grub_uint32_t grub_relocator32_backward_edx;
-extern grub_uint32_t grub_relocator32_backward_eip;
-extern grub_uint32_t grub_relocator32_backward_esp;
-
-#define RELOCATOR_SIZEOF(x)    (&grub_relocator32_##x##_end - &grub_relocator32_##x##_start)
-#define RELOCATOR_ALIGN 16
-#define PREFIX(x) grub_relocator32_ ## x
-
-static void
-write_call_relocator_bw (void *ptr, void *src, grub_uint32_t dest,
-                        grub_size_t size, struct grub_relocator32_state state)
-{
-  grub_relocator32_backward_dest = dest;
-  grub_relocator32_backward_src = PTR_TO_UINT64 (src);
-  grub_relocator32_backward_size = size;
-
-  grub_relocator32_backward_eax = state.eax;
-  grub_relocator32_backward_ebx = state.ebx;
-  grub_relocator32_backward_ecx = state.ecx;
-  grub_relocator32_backward_edx = state.edx;
-  grub_relocator32_backward_eip = state.eip;
-  grub_relocator32_backward_esp = state.esp;
-
-  grub_memmove (ptr,
-               &grub_relocator32_backward_start,
-               RELOCATOR_SIZEOF (backward));
-  ((void (*) (void)) ptr) ();
-}
-
-static void
-write_call_relocator_fw (void *ptr, void *src, grub_uint32_t dest,
-                        grub_size_t size, struct grub_relocator32_state state)
-{
-
-  grub_relocator32_forward_dest = dest;
-  grub_relocator32_forward_src = PTR_TO_UINT64 (src);
-  grub_relocator32_forward_size = size;
-
-  grub_relocator32_forward_eax = state.eax;
-  grub_relocator32_forward_ebx = state.ebx;
-  grub_relocator32_forward_ecx = state.ecx;
-  grub_relocator32_forward_edx = state.edx;
-  grub_relocator32_forward_eip = state.eip;
-  grub_relocator32_forward_esp = state.esp;
-
-  grub_memmove (ptr,
-               &grub_relocator32_forward_start,
-               RELOCATOR_SIZEOF (forward));
-  ((void (*) (void)) ptr) ();
-}
-
-#include "../relocator.c"
diff --git a/lib/i386/relocator_asm.S b/lib/i386/relocator_asm.S
deleted file mode 100644 (file)
index 6b803db..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-#include <grub/i386/memory.h>
-
-#ifdef BACKWARD
-#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_backward_ ## x)
-#else
-#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_forward_ ## x)
-#endif
-#ifdef __x86_64__
-#define RAX %rax
-#define RCX %rcx
-#define RDI %rdi
-#define RSI %rdi
-#else
-#define RAX %eax
-#define RCX %ecx
-#define RDI %edi
-#define RSI %esi
-#endif
-
-/* The code segment of the protected mode.  */
-#define CODE_SEGMENT   0x10
-
-/* The data segment of the protected mode.  */
-#define DATA_SEGMENT   0x18
-
-       .p2align        4       /* force 16-byte alignment */
-
-RELOCATOR_VARIABLE(start)
-#ifdef BACKWARD
-LOCAL(base):
-#endif
-       cli
-
-#ifndef __x86_64__
-       /* mov imm32, %eax */
-       .byte   0xb8
-RELOCATOR_VARIABLE(dest)
-       .long   0
-       movl    %eax, %edi
-
-       /* mov imm32, %eax */
-       .byte   0xb8
-RELOCATOR_VARIABLE(src)
-       .long   0
-       movl    %eax, %esi
-
-       /* mov imm32, %ecx */
-       .byte   0xb9
-RELOCATOR_VARIABLE(size)
-       .long   0
-#else
-       xorq    %rax, %rax
-
-       /* mov imm32, %eax */
-       .byte   0xb8
-RELOCATOR_VARIABLE(dest)
-       .long   0
-       movq    %rax, %rdi
-
-       /* mov imm64, %rax */
-       .byte   0x48
-       .byte   0xb8
-RELOCATOR_VARIABLE(src)
-       .long   0, 0
-       movq    %rax, %rsi
-
-       xorq    %rcx, %rcx
-       /* mov imm32, %ecx */
-       .byte   0xb9
-RELOCATOR_VARIABLE(size)
-       .long   0
-
-#endif
-
-       mov     RDI, RAX
-
-#ifdef BACKWARD
-       add     RCX, RSI
-       add     RCX, RDI
-#endif
-
-#ifndef BACKWARD
-       add     RCX, RAX
-#endif
-       add     $0x3, RCX
-       shr     $2, RCX
-
-
-#ifdef BACKWARD
-       /* Backward movsl is implicitly off-by-four.  compensate that.  */
-       sub     $4,     RSI
-       sub     $4,     RDI
-
-       /* Backward copy.  */
-       std
-
-       rep
-       movsl
-
-#else
-       /* Forward copy.  */
-       cld
-       rep
-       movsl
-#endif
-
-       /* %rax contains now our new 'base'.  */
-       mov     RAX, RSI
-       add     $(LOCAL(cont0) - LOCAL(base)), RAX
-       jmp     *RAX
-LOCAL(cont0):
-       lea     (LOCAL(cont1) - LOCAL(base)) (RSI, 1), RAX
-       movl    %eax, (LOCAL(jump_vector) - LOCAL(base)) (RSI, 1)
-
-       lea     (LOCAL(gdt) - LOCAL(base)) (RSI, 1), RAX
-       mov     RAX, (LOCAL(gdt_addr) - LOCAL(base)) (RSI, 1)
-
-       /* Switch to compatibility mode. */
-
-       lgdt    (LOCAL(gdtdesc) - LOCAL(base)) (RSI, 1)
-
-       /* Update %cs.  */
-       ljmp    *(LOCAL(jump_vector) - LOCAL(base)) (RSI, 1)
-
-LOCAL(cont1):
-       .code32
-
-       /* Update other registers. */
-       movl    $DATA_SEGMENT, %eax
-       movl    %eax, %ds
-       movl    %eax, %es
-       movl    %eax, %fs
-       movl    %eax, %gs
-       movl    %eax, %ss
-
-       /* Disable paging. */
-       movl    %cr0, %eax
-       andl    $(~GRUB_MEMORY_CPU_CR0_PAGING_ON), %eax
-       movl    %eax, %cr0
-
-       /* Disable amd64. */
-       movl    $GRUB_MEMORY_CPU_AMD64_MSR, %ecx
-       rdmsr
-       andl    $(~GRUB_MEMORY_CPU_AMD64_MSR_ON), %eax
-       wrmsr
-
-       /* Turn off PAE. */
-       movl    %cr4, %eax
-       andl    $GRUB_MEMORY_CPU_CR4_PAE_ON, %eax
-       movl    %eax, %cr4
-
-       jmp     LOCAL(cont2)
-LOCAL(cont2):
-       .code32
-
-       /* mov imm32, %eax */
-       .byte   0xb8
-RELOCATOR_VARIABLE (esp)
-       .long   0
-
-       movl    %eax, %esp
-
-       /* mov imm32, %eax */
-       .byte   0xb8
-RELOCATOR_VARIABLE (eax)
-       .long   0
-
-       /* mov imm32, %ebx */
-       .byte   0xbb
-RELOCATOR_VARIABLE (ebx)
-       .long   0
-
-       /* mov imm32, %ecx */
-       .byte   0xb9
-RELOCATOR_VARIABLE (ecx)
-       .long   0
-
-       /* mov imm32, %edx */
-       .byte   0xba
-RELOCATOR_VARIABLE (edx)
-       .long   0
-
-       /* Cleared direction flag is of no problem with any current
-          payload and makes this implementation easier.  */
-       cld
-
-       .byte   0xea
-RELOCATOR_VARIABLE (eip)
-       .long   0
-       .word   CODE_SEGMENT
-
-       /* GDT. Copied from loader/i386/linux.c. */
-       .p2align        4
-LOCAL(gdt):
-       /* NULL.  */
-       .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-
-       /* Reserved.  */
-       .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-
-       /* Code segment.  */
-       .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
-
-       /* Data segment.  */
-       .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
-
-       .p2align        4
-LOCAL(gdtdesc):
-       .word   0x27
-LOCAL(gdt_addr):
-#ifdef __x86_64__
-       /* Filled by the code. */
-       .quad   0
-#else
-       /* Filled by the code. */
-       .long   0
-#endif
-
-       .p2align        4
-LOCAL(jump_vector):
-       /* Jump location. Is filled by the code */
-       .long   0
-       .long   CODE_SEGMENT
-
-#ifndef BACKWARD
-LOCAL(base):
-#endif
-
-RELOCATOR_VARIABLE(end)
diff --git a/lib/i386/relocator_backward.S b/lib/i386/relocator_backward.S
deleted file mode 100644 (file)
index 0691347..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#define BACKWARD
-#include "relocator_asm.S"
diff --git a/lib/i386/setjmp.S b/lib/i386/setjmp.S
deleted file mode 100644 (file)
index a2002ae..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-
-       .file   "setjmp.S"
-
-       .text
-
-/*
- * int grub_setjmp (grub_jmp_buf env)
- */
-FUNCTION(grub_setjmp)
-       movl    %ebx, 0(%eax)   /* EBX */
-       movl    %esi, 4(%eax)   /* ESI */
-       movl    %edi, 8(%eax)   /* EDI */
-       movl    %ebp, 12(%eax)  /* EBP */
-       popl    %ecx
-       movl    %esp, 16(%eax)  /* ESP */
-       movl    %ecx, 20(%eax)  /* EIP */
-       xorl    %eax, %eax
-       jmp     *%ecx
-
-
-/*
- * int grub_longjmp (grub_jmp_buf env, int val)
- */
-FUNCTION(grub_longjmp)
-       movl    0(%eax), %ebx
-       movl    4(%eax), %esi
-       movl    8(%eax), %edi
-       movl    12(%eax), %ebp
-       movl    16(%eax), %esp
-       movl    20(%eax), %ecx
-
-       movl    %edx, %eax
-       testl   %eax, %eax
-       jnz     1f
-       incl    %eax
-1:     jmp     *%ecx
-
diff --git a/lib/ieee1275/datetime.c b/lib/ieee1275/datetime.c
deleted file mode 100644 (file)
index 7e6f8d1..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/* kern/cmos_datetime.c - CMOS datetime function.
- *
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/datetime.h>
-#include <grub/ieee1275/ieee1275.h>
-#include <grub/misc.h>
-
-static char *rtc = 0;
-
-static void
-find_rtc (void)
-{
-  auto int hook (struct grub_ieee1275_devalias *alias);
-  int hook (struct grub_ieee1275_devalias *alias)
-  {
-    if (grub_strcmp (alias->type, "rtc") == 0)
-      {
-       grub_dprintf ("datetime", "Found RTC %s\n", alias->path);
-       rtc = grub_strdup (alias->path);
-       return 1;
-      }
-    return 0;
-  }
-  
-  grub_ieee1275_devices_iterate (hook);
-}
-
-grub_err_t
-grub_get_datetime (struct grub_datetime *datetime)
-{
-  struct get_time_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t method;
-    grub_ieee1275_cell_t device;
-    grub_ieee1275_cell_t catch_result;
-    grub_ieee1275_cell_t year;
-    grub_ieee1275_cell_t month;
-    grub_ieee1275_cell_t day;
-    grub_ieee1275_cell_t hour;
-    grub_ieee1275_cell_t minute;
-    grub_ieee1275_cell_t second;
-  }
-  args;
-  int status;
-  grub_ieee1275_ihandle_t ihandle;
-
-  if (!rtc)
-    find_rtc ();
-  if (!rtc)
-    return grub_error (GRUB_ERR_IO, "no RTC found");
-
-  status = grub_ieee1275_open (rtc, &ihandle);
-  if (status == -1)
-    return grub_error (GRUB_ERR_IO, "couldn't open RTC");
-
-  INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 7);
-  args.device = (grub_ieee1275_cell_t) ihandle;
-  args.method = (grub_ieee1275_cell_t) "get-time";
-
-  status = IEEE1275_CALL_ENTRY_FN (&args);
-
-  grub_ieee1275_close (ihandle);
-
-  if (status == -1)
-    return grub_error (GRUB_ERR_IO, "get-time failed");
-
-  datetime->year = args.year;
-  datetime->month = args.month;
-  datetime->day = args.day;
-  datetime->hour = args.hour;
-  datetime->minute = args.minute;
-  datetime->second = args.second;
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_set_datetime (struct grub_datetime *datetime)
-{
-  struct set_time_args
-  {
-    struct grub_ieee1275_common_hdr common;
-    grub_ieee1275_cell_t method;
-    grub_ieee1275_cell_t device;
-    grub_ieee1275_cell_t year;
-    grub_ieee1275_cell_t month;
-    grub_ieee1275_cell_t day;
-    grub_ieee1275_cell_t hour;
-    grub_ieee1275_cell_t minute;
-    grub_ieee1275_cell_t second;
-    grub_ieee1275_cell_t catch_result;
-  }
-  args;
-  int status;
-  grub_ieee1275_ihandle_t ihandle;
-
-  if (!rtc)
-    find_rtc ();
-  if (!rtc)
-    return grub_error (GRUB_ERR_IO, "no RTC found");
-
-  status = grub_ieee1275_open (rtc, &ihandle);
-  if (status == -1)
-    return grub_error (GRUB_ERR_IO, "couldn't open RTC");
-
-  INIT_IEEE1275_COMMON (&args.common, "call-method", 8, 1);
-  args.device = (grub_ieee1275_cell_t) ihandle;
-  args.method = (grub_ieee1275_cell_t) "set-time";
-
-  args.year = datetime->year;
-  args.month = datetime->month;
-  args.day = datetime->day;
-  args.hour = datetime->hour;
-  args.minute = datetime->minute;
-  args.second = datetime->second;
-
-  status = IEEE1275_CALL_ENTRY_FN (&args);
-
-  grub_ieee1275_close (ihandle);
-
-  if (status == -1)
-    return grub_error (GRUB_ERR_IO, "set-time failed");
-
-  return GRUB_ERR_NONE;
-}
diff --git a/lib/libgcrypt/cipher/ChangeLog b/lib/libgcrypt/cipher/ChangeLog
deleted file mode 100644 (file)
index 8924f17..0000000
+++ /dev/null
@@ -1,3900 +0,0 @@
-2009-01-22  Werner Koch  <wk@g10code.com>
-
-       * ecc.c (compute_keygrip): Remove superfluous const.
-
-2009-01-06  Werner Koch  <wk@g10code.com>
-
-       * rmd160.c (oid_spec_rmd160): Add TeleTrust identifier.
-
-2008-12-10  Werner Koch  <wk@g10code.com>
-
-       * dsa.c (generate): Add arg DOMAIN and use it if specified.
-       (generate_fips186): Ditto.
-       (dsa_generate_ext): Parse and check the optional "domain"
-       parameter and pass them to the generate functions.
-
-       * rijndael.c (rijndael_names): Add "AES128" and "AES-128".
-       (rijndael192_names): Add "AES-192".
-       (rijndael256_names): Add "AES-256".
-
-2008-12-05  Werner Koch  <wk@g10code.com>
-
-       * dsa.c (generate): Add arg TRANSIENT_KEY and use it to detrmine
-       the RNG quality needed.
-       (dsa_generate_ext): Parse the transient-key flag und pass it to
-       generate.
-
-2008-11-28  Werner Koch  <wk@g10code.com>
-
-       * dsa.c (generate_fips186): Add arg DERIVEPARMS and use the seed
-       value if available.
-
-       * primegen.c (_gcry_generate_fips186_2_prime): Fix inner p loop.
-
-2008-11-26  Werner Koch  <wk@g10code.com>
-
-       * primegen.c (_gcry_generate_fips186_3_prime): New.
-       * dsa.c (generate_fips186): Add arg USE_FIPS186_2.
-       (dsa_generate_ext): Parse new flag use-fips183-2.
-
-2008-11-25  Werner Koch  <wk@g10code.com>
-
-       * dsa.c (generate_fips186): New.
-       (dsa_generate_ext): Use new function if derive-parms are given or
-       if in FIPS mode.
-       * primegen.c (_gcry_generate_fips186_2_prime): New.
-
-2008-11-24  Werner Koch  <wk@g10code.com>
-
-       * pubkey.c (gcry_pk_genkey): Insert code to output extrainfo.
-       (pubkey_generate): Add arg R_EXTRAINFO and pass it to the extended
-       key generation function.
-       * rsa.c (gen_x931_parm_xp, gen_x931_parm_xi): New.
-       (generate_x931): Generate params if not given.
-       (rsa_generate_ext): Parse use-x931 flag.  Return p-q-swapped
-       indicator.
-       * dsa.c (dsa_generate_ext): Put RETFACTORS into R_EXTRAINFO if
-       possible.
-
-       * pubkey.c (gcry_pk_genkey): Remove parsing of almost all
-       parameters and pass the parameter S-expression to pubkey_generate.
-       (pubkey_generate): Simplify by requitring modules to parse the
-       parameters. Remove the special cases for Elgamal and ECC.
-       (sexp_elements_extract_ecc): Add arg EXTRASPEC and use it.  Fix
-       small memory leak.
-       (sexp_to_key): Pass EXTRASPEC to sexp_elements_extract_ecc.
-       (pubkey_table) [USE_ELGAMAL]: Add real extraspec.
-       * rsa.c (rsa_generate_ext): Adjust for new calling convention.
-       * dsa.c (dsa_generate_ext): Ditto.
-       * elgamal.c (_gcry_elg_generate): Ditto. Rename to elg_generate_ext.
-       (elg_generate): New.
-       (_gcry_elg_generate_using_x): Remove after merging code with
-       elg_generate_ext.
-       (_gcry_pubkey_extraspec_elg): New.
-       (_gcry_elg_check_secret_key, _gcry_elg_encrypt, _gcry_elg_sign) 
-       (_gcry_elg_verify, _gcry_elg_get_nbits): Make static and remove
-       _gcry_ prefix.
-       * ecc.c (_gcry_ecc_generate): Rename to ecc_generate_ext and
-       adjust for new calling convention.
-       (_gcry_ecc_get_param): Rename to ecc_get_param and make static.
-       (_gcry_pubkey_extraspec_ecdsa): Add ecc_generate_ext and
-       ecc_get_param.
-       
-2008-11-20  Werner Koch  <wk@g10code.com>
-
-       * pubkey.c (pubkey_generate): Add arg DERIVEPARMS.
-       (gcry_pk_genkey): Parse derive-parms and pass it to above.
-       * rsa.c (generate_x931): New.
-       (rsa_generate_ext): Add arg DERIVEPARMS and call new function in
-       fips mode or if DERIVEPARMS is given.
-       * primegen.c (_gcry_derive_x931_prime, find_x931_prime): New.
-
-2008-11-19  Werner Koch  <wk@g10code.com>
-
-       * rsa.c (rsa_decrypt): Use gcry_create_nonce for blinding.
-       (generate): Rename to generate_std.
-
-2008-11-05  Werner Koch  <wk@g10code.com>
-
-       * md.c (md_open): Use a switch to set the Bsize.
-       (prepare_macpads): Fix long key case for SHA384 and SHA512.
-
-       * cipher.c (gcry_cipher_handle): Add field EXTRASPEC.
-       (gcry_cipher_open): Set it.
-       (gcry_cipher_ctl): Add private control code to disable weak key
-       detection and to return the current input block.
-       * des.c (_tripledes_ctx): Add field FLAGS.
-       (do_tripledes_set_extra_info): New.
-       (_gcry_cipher_extraspec_tripledes): Add new function.
-       (do_tripledes_setkey): Disable weak key detection.
-
-2008-10-24  Werner Koch  <wk@g10code.com>
-
-       * md.c (digest_table): Allow MD5 in fips mode.
-       (md_register_default): Take special action for MD5.
-       (md_enable, gcry_md_hash_buffer): Ditto.
-
-2008-09-30  Werner Koch  <wk@g10code.com>
-
-       * rijndael.c (do_setkey): Properly align "t" and "tk".
-       (prepare_decryption): Properly align "w".  Fixes bug #936.
-
-2008-09-18  Werner Koch  <wk@g10code.com>
-
-       * pubkey.c (gcry_pk_genkey): Parse domain parameter.
-       (pubkey_generate): Add new arg DOMAIN and remove special case for
-       DSA with qbits.
-       * rsa.c (rsa_generate): Add dummy args QBITS, NAME and DOMAIN and
-       rename to rsa_generate_ext.  Change caller.
-       (_gcry_rsa_generate, _gcry_rsa_check_secret_key) 
-       (_gcry_rsa_encrypt, _gcry_rsa_decrypt, _gcry_rsa_sign) 
-       (_gcry_rsa_verify, _gcry_rsa_get_nbits): Make static and remove
-       _gcry_ prefix.
-       (_gcry_pubkey_spec_rsa, _gcry_pubkey_extraspec_rsa): Adjust names.
-       * dsa.c (dsa_generate_ext): New.
-       (_gcry_dsa_generate): Replace code by a call to dsa_generate.
-       (_gcry_dsa_check_secret_key, _gcry_dsa_sign, _gcry_dsa_verify)
-       (_gcry_dsa_get_nbits): Make static and remove _gcry prefix.
-       (_gcry_dsa_generate2): Remove.
-       (_gcry_pubkey_spec_dsa): Adjust to name changes.
-       (_gcry_pubkey_extraspec_rsa): Add dsa_generate_ext.
-
-2008-09-16  Werner Koch  <wk@g10code.com>
-
-       * ecc.c (run_selftests): Add arg EXTENDED.
-
-2008-09-12  Werner Koch  <wk@g10code.com>
-
-       * rsa.c (test_keys): Do a bad case signature check.
-       * dsa.c (test_keys): Do a bad case check.
-
-       * cipher.c (_gcry_cipher_selftest): Add arg EXTENDED and pass it
-       to the called tests.
-       * md.c (_gcry_md_selftest): Ditto.
-       * pubkey.c (_gcry_pk_selftest): Ditto.
-       * rijndael.c (run_selftests): Add arg EXTENDED and pass it to the
-       called tests.
-       (selftest_fips_128): Add arg EXTENDED and run only one test
-       non-extended mode.
-       (selftest_fips_192): Add dummy arg EXTENDED.
-       (selftest_fips_256): Ditto.
-       * hmac-tests.c (_gcry_hmac_selftest): Ditto.
-       (run_selftests): Ditto.
-       (selftests_sha1): Add arg EXTENDED and run only one test
-       non-extended mode.
-       (selftests_sha224, selftests_sha256): Ditto.
-       (selftests_sha384, selftests_sha512): Ditto.
-       * sha1.c (run_selftests): Add arg EXTENDED and pass it to the
-       called test.
-       (selftests_sha1): Add arg EXTENDED and run only one test
-       non-extended mode.
-       * sha256.c (run_selftests): Add arg EXTENDED and pass it to the
-       called tests.
-       (selftests_sha224): Add arg EXTENDED and run only one test
-       non-extended mode.
-       (selftests_sha256): Ditto.
-       * sha512.c (run_selftests): Add arg EXTENDED and pass it to the
-       called tests.
-       (selftests_sha384): Add arg EXTENDED and run only one test
-       non-extended mode.
-       (selftests_sha512): Ditto.
-       * des.c (run_selftests): Add arg EXTENDED and pass it to the
-       called test.
-       (selftest_fips): Add dummy arg EXTENDED.
-       * rsa.c (run_selftests): Add dummy arg EXTENDED.
-
-       * dsa.c (run_selftests): Add dummy arg EXTENDED.
-
-       * rsa.c (extract_a_from_sexp): New.
-       (selftest_encr_1024): Check that the ciphertext does not match the
-       plaintext.
-       (test_keys): Improve tests and return an error status.
-       (generate): Return an error if test_keys fails.
-       * dsa.c (test_keys): Add comments and return an error status.
-       (generate): Return an error if test_keys failed.
-
-2008-09-11  Werner Koch  <wk@g10code.com>
-
-       * rsa.c (_gcry_rsa_decrypt): Return an error instead of calling
-       BUG in case of a practically impossible condition.
-       (sample_secret_key, sample_public_key): New.
-       (selftest_sign_1024, selftest_encr_1024): New.
-       (selftests_rsa): Implement tests.
-       * dsa.c (sample_secret_key, sample_public_key): New.
-       (selftest_sign_1024): New.
-       (selftests_dsa): Implement tests.
-
-2008-09-09  Werner Koch  <wk@g10code.com>
-
-       * hmac-tests.c (selftests_sha1): Add tests.
-       (selftests_sha224, selftests_sha384, selftests_sha512): Make up tests.
-
-       * hash-common.c, hash-common.h: New.
-       * sha1.c (selftests_sha1): Add 3 tests.
-       * sha256.c (selftests_sha256, selftests_sha224): Ditto.
-       * sha512.c (selftests_sha512, selftests_sha384): Ditto.
-
-2008-08-29  Werner Koch  <wk@g10code.com>
-
-       * pubkey.c (gcry_pk_get_keygrip): Remove the special case for RSA
-       and check whether a custom computation function has been setup.
-       * rsa.c (compute_keygrip): New.
-       (_gcry_pubkey_extraspec_rsa): Setup this function.
-       * ecc.c (compute_keygrip): New.
-       (_gcry_pubkey_extraspec_ecdsa): Setup this function.
-
-2008-08-28  Werner Koch  <wk@g10code.com>
-
-       * cipher.c (cipher_decrypt, cipher_encrypt): Return an error if
-       mode NONE is used.
-       (gcry_cipher_open): Allow mode NONE only with a debug flag set and
-       if not in FIPS mode.
-
-2008-08-26  Werner Koch  <wk@g10code.com>
-
-       * pubkey.c (pubkey_generate): Add arg KEYGEN_FLAGS.
-       (gcry_pk_genkey): Implement new parameter "transient-key" and
-       pass it as flags to pubkey_generate.
-       (pubkey_generate): Make use of an ext_generate function.
-       * rsa.c (generate): Add new arg transient_key and pass appropriate
-       args to the prime generator.
-       (_gcry_rsa_generate): Factor all code out to ...
-       (rsa_generate): .. new func with extra arg KEYGEN_FLAGS.
-       (_gcry_pubkey_extraspec_ecdsa): Setup rsa_generate.
-       * primegen.c (_gcry_generate_secret_prime) 
-       (_gcry_generate_public_prime): Add new arg RANDOM_LEVEL.
-
-2008-08-21  Werner Koch  <wk@g10code.com>
-
-       * primegen.c (_gcry_generate_secret_prime)
-       (_gcry_generate_public_prime): Use a constant macro for the random
-       level.
-       
-2008-08-19  Werner Koch  <wk@g10code.com>
-
-       * pubkey.c (sexp_elements_extract_ecc) [!USE_ECC]: Do not allow
-       allow "curve" parameter.
-
-2008-08-15  Werner Koch  <wk@g10code.com>
-
-       * pubkey.c (_gcry_pk_selftest): New.
-       * dsa.c (selftests_dsa, run_selftests): New.
-       * rsa.c (selftests_rsa, run_selftests): New.
-       * ecc.c (selftests_ecdsa, run_selftests): New.
-
-       * md.c (_gcry_md_selftest): New.
-       * sha1.c (run_selftests, selftests_sha1): New.
-       * sha256.c (selftests_sha224, selftests_sha256, run_selftests): New.
-       * sha512.c (selftests_sha384, selftests_sha512, run_selftests): New.
-
-       * des.c (selftest): Remove static variable form selftest.
-       (des_setkey): No on-the-fly self test in fips mode.
-       (tripledes_set3keys): Ditto.
-
-       * cipher.c (_gcry_cipher_setkey, _gcry_cipher_setiv): 
-
-       * dsa.c (generate): Bail out in fips mode if NBITS is less than 1024.
-       * rsa.c (generate): Return an error code if the the requested size
-       is less than 1024 and we are in fpis mode.
-       (_gcry_rsa_generate): Take care of that error code.
-
-       * ecc.c (generate_curve): In fips mode enable only NIST curves.
-
-       * cipher.c (_gcry_cipher_selftest): New.
-
-       * sha512.c (_gcry_digest_extraspec_sha384)
-       (_gcry_digest_extraspec_sha512): New.
-       * sha256.c (_gcry_digest_extraspec_sha224)
-       (_gcry_digest_extraspec_sha256): New.
-       * sha1.c (_gcry_digest_extraspec_sha1): New.
-       * ecc.c (_gcry_pubkey_extraspec_ecdsa): New.
-       * dsa.c (_gcry_pubkey_extraspec_dsa): New.
-       * rsa.c (_gcry_pubkey_extraspec_rsa): New.
-       * rijndael.c (_gcry_cipher_extraspec_aes)
-       (_gcry_cipher_extraspec_aes192, _gcry_cipher_extraspec_aes256): New.
-       * des.c (_gcry_cipher_extraspec_tripledes): New.
-
-       * cipher.c (gcry_cipher_register): Rename to _gcry_cipher_register.
-       Add arg EXTRASPEC.
-       (dummy_extra_spec): New.
-       (cipher_table_entry): Add extraspec field.
-       * md.c (_gcry_md_register): Rename to _gcry_md_register.  Add
-       arg EXTRASPEC.
-       (dummy_extra_spec): New.
-       (digest_table_entry): Add extraspec field.
-       * pubkey.c (gcry_pk_register): Rename to _gcry_pk_register.  Add
-       arg EXTRASPEC.
-       (dummy_extra_spec): New.
-       (pubkey_table_entry): Add extraspec field.
-
-       * ac.c: Let most public functions return GPG_ERR_UNSUPPORTED in
-       fips mode.
-
-       * pubkey.c (pubkey_table_entry): Add field FIPS_ALLOWED and mark
-       appropriate algorithms.
-       (dummy_generate, dummy_check_secret_key, dummy_encrypt) 
-       (dummy_decrypt, dummy_sign, dummy_verify, dummy_get_nbits): Signal
-       a fips error when used.
-       (gcry_pk_register): In fips mode do not allow to register new
-       algorithms.
-
-       * md.c (digest_table): Add field FIPS_ALLOWED and mark appropriate
-       algorithms.
-       (md_register_default): In fips mode register only fips algorithms.
-       (gcry_md_register): In fips mode do not allow to register new
-       algorithms.
-       (gcry_md_get): Signal a fips error if called.
-       (gcry_md_hash_buffer): Do not allow rmd160 when not in fips mode.
-       (md_start_debug): Disable in fips_mode.
-
-       * md.c (gcry_md_register_default): Rename to ..
-       (md_register_default): .. this.
-       (md_digest): Remove this commented fucntion.
-       * pubkey.c (gcry_pk_register_default): Rename to ..
-       (pk_register_default): .. this.
-
-       * cipher.c (cipher_table_entry): Add field FIPS_ALLOWED.
-       (gcry_cipher_register_default): Register only fips approved
-       algorithms.
-       (gcry_cipher_register): Do not allow to register new ciphers.
-       (cipher_setiv): Signal fips error.
-       
-       * cipher (gcry_cipher_register_default): Rename to ..
-       (cipher_register_default): .. this.
-       (REGISTER_DEFAULT_CIPHERS): Adjust for that change.
-
-2008-07-05  Werner Koch  <wk@g10code.com>
-
-       * random-daemon.c, random.h, rndhw.c, rndunix.c, rand-internal.h
-       * random.c, rndegd.c, rndlinux.c, rndw32.c: Move to ../cipher.
-       * Makefile.am: Remove random stuff.
-
-2008-06-24  Szakats Istvan <szaki.ms@gmail.com>  (wk)
-
-       * ac.c (_gcry_ac_key_destroy, _gcry_ac_key_pair_generate): Relase
-       some more memory.
-
-2008-04-22  Werner Koch  <wk@g10code.com>
-
-       * rijndael.c (_gcry_aes_cfb_enc, _gcry_aes_cbc_enc) 
-       (_gcry_aes_cfb_dec, _gcry_aes_cbc_dec): Use Padlock if possible.
-
-2008-04-18  Werner Koch  <wk@g10code.com>
-
-       * sha1.c (transform_aligned): Remove.  That is will obviosuly not
-       work because we need a scratch working area and our internal API
-       does not allow to modify the buffers.
-
-       * rijndael.c: Factor tables out to ..
-       * rijndael-tables.h: .. new.
-
-       * ac.c (ac_data_extract): Make static.
-
-       * camellia.h [HAVE_CONFIG_H]: Include config.h.
-
-       * rndw32.c (registry_poll): Only print the performance data
-       problem warning once.  Suggested by Simon Josefsson.
-
-2008-03-19  Werner Koch  <wk@g10code.com>
-
-       * cipher.c (gcry_cipher_open) [USE_AES]: Init bulk encryption only
-       if requested.  Suggested by Dirk Stoecker.
-
-2008-03-18  Werner Koch  <wk@g10code.com>
-
-       * sha1.c: Include stdint.h.
-       (transform): Add arg NBLOCKS so that we can work on more than one
-       block and avoid updates of the chaining variables.  Changed all
-       callers to use 1.
-       (sha1_write): Replace loop around transform.
-       (transform_aligned) [WORDS_BIGENDIAN]: New.
-       (TRANSFORM): New macro to replace all direct calls of transform.
-
-2008-03-17  Werner Koch  <wk@g10code.com>
-
-       * rijndael.c (_gcry_aes_cfb_dec): New.
-       (do_encrypt): Factor code out to ..
-       (do_encrypt_aligned): .. New.
-       (_gcry_aes_cfb_enc, _gcry_aes_cfb_dec): Use new function.
-       (do_decrypt): Factor code out to ..
-       (do_decrypt_aligned): .. new.
-       (_gcry_aes_cbc_enc, _gcry_aes_cbc_dec): New.
-       * cipher.c (struct gcry_cipher_handle): Put field IV into new
-       union U_IV to enforce proper alignment.  Change all users.
-       (do_cfb_decrypt): Optimize.
-       (do_cbc_encrypt, do_cbc_decrypt): Optimize.
-
-2008-03-15  Werner Koch  <wk@g10code.com>
-
-       * rijndael.c (_gcry_aes_cfb_enc): New.
-       * cipher.c (struct gcry_cipher_handle): Add field ALGO and BULK.
-       (gcry_cipher_open): Set ALGO and BULK.
-       (do_cfb_encrypt): Optimize.
-
-2008-02-18  Werner Koch  <wk@g10code.com>
-
-       * rsa.c (_gcry_rsa_verify) [IS_DEVELOPMENT_VERSION]: Print
-       intermediate results.
-
-2008-01-08  Werner Koch  <wk@g10code.com>
-
-       * random.c (add_randomness): Do not just increment
-       POOL_FILLED_COUNTER but update it by the actual amount of data.
-
-2007-12-13  Werner Koch  <wk@g10code.com>
-
-       * pubkey.c (sexp_data_to_mpi): Support SHA-224.
-
-2007-12-05  Werner Koch  <wk@g10code.com>
-
-       * rijndael.c (USE_PADLOCK): Depend on ENABLE_PADLOCK_SUPPORT.
-       * rndhw.c (USE_PADLOCK): Ditto
-
-       * rsa.c (secret): Fixed condition test for using CRT.  Reported by
-       Dean Scarff.  Fixes bug#864.
-       (_gcry_rsa_check_secret_key): Return an erro if the optional
-       parameters are missing.
-       * pubkey.c (sexp_elements_extract): Add arg ALGO_NAME. Changed all
-       callers to pass NULL. Add hack to allow for optional RSA
-       parameters.
-       (sexp_to_key): Pass algo name to sexp_elements_extract.
-
-2007-12-03  Werner Koch  <wk@g10code.com>
-
-       * random.c (gcry_random_add_bytes): Implement it.
-       * rand-internal.h (RANDOM_ORIGIN_EXTERNAL): New.
-
-2007-11-30  Werner Koch  <wk@g10code.com>
-
-       * rndhw.c: New.
-       * rndlinux.c (_gcry_rndlinux_gather_random): Try to read 50%
-       directly from the hwrng.
-       * random.c (do_fast_random_poll): Also run the hw rng fast poll.
-       (_gcry_random_dump_stats): Tell whether the hw rng failed.
-
-2007-11-29  Werner Koch  <wk@g10code.com>
-
-       * rijndael.c (USE_PADLOCK): Define new macro used for ia32.
-       (RIJNDAEL_context) [USE_PADLOCK]: Add fields USE_PADLOCK and
-       PADLOCK_KEY.
-       (do_setkey) [USE_PADLOCK]: Enable padlock if available for 128 bit
-       AES.
-       (do_padlock) [USE_PADLOCK]: New.
-       (rijndael_encrypt, rijndael_decrypt) [USE_PADLOCK]: Divert to
-       do_padlock.
-       * cipher.c (cipher_context_alignment_t): New.  Use it in this
-       module in place of PROPERLY_ALIGNED_TYPE.
-       (NEED_16BYTE_ALIGNED_CONTEXT): Define macro for ia32.
-       (struct gcry_cipher_handle): Add field HANDLE_OFFSET.
-       (gcry_cipher_open): Take care of increased alignment requirements.
-       (gcry_cipher_close): Ditto.
-
-2007-11-28  Werner Koch  <wk@g10code.com>
-
-       * sha256.c (asn224): Fixed wrong template.  It happened due to a
-       bug in RFC4880.  SHA-224 is not in the stable version of libgcrypt
-       so the consequences are limited to users of this devel version.
-
-2007-10-31  Werner Koch  <wk@g10code.com>
-
-       * ac.c (gcry_ac_data_new): Remove due to the visibility wrapper.
-       (gcry_ac_data_destroy, gcry_ac_data_copy, gcry_ac_data_length) 
-       (gcry_ac_data_set, gcry_ac_data_get_name, gcry_ac_data_get_index) 
-       (gcry_ac_data_to_sexp, gcry_ac_data_from_sexp) 
-       (gcry_ac_data_clear, gcry_ac_io_init, gcry_ac_open) 
-       (gcry_ac_close, gcry_ac_key_init, gcry_ac_key_pair_generate) 
-       (gcry_ac_key_pair_extract, gcry_ac_key_destroy) 
-       (gcry_ac_key_pair_destroy, gcry_ac_key_data_get) 
-       (gcry_ac_key_test, gcry_ac_key_get_nbits, gcry_ac_key_get_grip) 
-       (gcry_ac_data_encrypt, gcry_ac_data_decrypt, gcry_ac_data_sign) 
-       (gcry_ac_data_verify, gcry_ac_data_encode, gcry_ac_data_decode) 
-       (gcry_ac_mpi_to_os, gcry_ac_mpi_to_os_alloc, gcry_ac_os_to_mpi) 
-       (gcry_ac_data_encrypt_scheme, gcry_ac_data_decrypt_scheme) 
-       (gcry_ac_data_sign_scheme, gcry_ac_data_verify_scheme) 
-       (gcry_ac_io_init_va): Ditto.
-       (gcry_ac_id_to_name, gcry_ac_name_to_id): Remove as these
-       deprecated functions are now implemented by visibility.c.
-
-2007-10-26  Werner Koch  <wk@g10code.com>
-
-       * rndw32.c: Disable debug flag.
-
-2007-10-25  Werner Koch  <wk@g10code.com>
-
-       * rndw32.c: Updated from current cryptlib snapshot and modified
-       for our use.  Removed support from pre NT systems.
-       (slow_gatherer_windows95): Remove.
-       (_gcry_rndw32_gather_random): Require an NT platform.
-       (init_system_rng, read_system_rng, read_mbm_data): New.
-       (slow_gatherer_windowsNT): Rename to ...
-       (slow_gatherer): .. this.  Read system RNG and MBM.
-       (registry_poll): New with code factored out from slow_gatherer.
-
-2007-08-23  Werner Koch  <wk@g10code.com>
-
-       * random.c (pool_filled_counter): New.
-       (add_randomness): Use it.
-
-2007-08-22  Werner Koch  <wk@g10code.com>
-
-       * rndw32.c, rndunix.c: Switched to LGPL.
-
-2007-05-30  Werner Koch  <wk@g10code.com>
-
-       * camellia.h, camellia.c: Replace by new LGPL version and adjusted
-       camellia.h.
-
-2007-05-09  Marcus Brinkmann  <marcus@g10code.de>
-
-       * ac.c (_gcry_ac_io_init_va, _gcry_ac_io_write, _gcry_ac_io_read):
-       Adjust users of gcry_ac_io_t because union is not anonymous
-       anymore.
-
-2007-05-02  Werner Koch  <wk@g10code.com>
-
-       * camellia-glue.c (camellia_setkey, camellia_encrypt)
-       (camellia_decrypt): Recalculated used stack size in called
-       functions.
-       * camellia.h: Redefine external symbols.
-
-2007-05-02  David Shaw  <dshaw@jabberwocky.com>
-
-       * Makefile.am, cipher.c: Add Camellia.
-
-       * camellia-glue.c: New.  The necessary glue to interface libgcrypt
-       to the stock NTT Camellia distribution.
-
-       * camellia.h, camellia.c: The stock NTT Camellia distribution
-       (GPL).
-
-2007-04-30  David Shaw  <dshaw@jabberwocky.com>
-
-       * cipher.c: Use #if instead of #ifdef as configure defines the
-       USE_cipher defines as 0 for disabled.
-
-2007-04-30  Werner Koch  <wk@g10code.com>
-
-       * rndegd.c (_gcry_rndegd_set_socket_name): New.
-
-2007-04-30  Marcus Brinkmann  <marcus@g10code.de>
-
-       * ecc.c (ec2os): Fix relocation of short numbers.
-
-       * ecc.c (generate_key): Do not allocate D, which will be allocated
-       by GEN_K.  Remove G.  Fix test if g_x, g_y resp. q_x, q_y are
-       requested.
-       (_gcry_ecc_generate): Release unneeded members of SK.
-       * pubkey.c (sexp_to_key): Release NAME.
-
-2007-04-28  Marcus Brinkmann  <marcus@g10code.de>
-
-       * ac.c (gcry_ac_mpi): Remove member NAME_PROVIDED.
-       (ac_data_mpi_copy, _gcry_ac_data_set, _gcry_ac_data_get_name)
-       (_gcry_ac_data_get_index, ac_data_construct): Adjust handling of
-       NAME accordingly.
-
-2007-04-20  Werner Koch  <wk@g10code.com>
-
-       * ecc.c (domain_parms): Add standard brainpool curves.
-
-2007-04-18  Werner Koch  <wk@g10code.com>
-
-       * ecc.c (generate_curve): Implement alias mechanism.
-
-       * pubkey.c (sexp_elements_extract_ecc): New.
-       (sexp_to_key): Add special case for ecc.
-       (sexp_to_key, sexp_to_sig, sexp_to_enc, gcry_pk_genkey): Replace
-       name_terminated stuff by a call to _gcry_sexp_nth_string.
-       (gcry_pk_get_keygrip): Ditto.
-
-2007-04-16  Werner Koch  <wk@g10code.com>
-
-       * ecc.c (_gcry_ecc_generate): Renamed DUMMY to CURVE and use it.
-
-2007-04-13  Marcus Brinkmann  <marcus@g10code.de>
-
-       * ac.c (ac_data_construct): Cast const away to suppress compiler
-       warning.
-
-       * ecc.c (ecc_generate): Avoid compiler warning for unused argument
-       DUMMY.
-       (ecc_verify): Avoid compiler warning for unused arguments CMP and
-       OPAQUEV.
-
-2007-04-06  Werner Koch  <wk@g10code.com>
-
-       * sha1.c (oid_spec_sha1): Add another oid from X9.62.
-
-2007-03-28  Werner Koch  <wk@g10code.com>
-
-       * pubkey.c (gcry_pk_genkey): Do not issue misc-key-info if it is
-       empty.
-       (gcry_pk_genkey): New parameter "curve".
-
-       * ecc.c: Entirely rewritten with only a few traces of the old
-       code left.
-       (_gcry_ecc_generate): New.
-       (generate_key) New arg NAME.
-       (generate_curve): Ditto.  Return actual number of NBITS.
-
-2007-03-26  Werner Koch  <wk@g10code.com>
-
-       * pubkey.c (gcry_pk_genkey): Increase size of SKEY array and add a
-       runtime bounds check.
-
-2007-03-23  Werner Koch  <wk@g10code.com>
-
-       * ecc.c (ecc_ctx_init, ecc_ctx_free, ecc_mod, ecc_mulm): New.
-       (duplicate_point, sum_points, escalar_mult): Don't use a
-       copy of base->p.  Replaced all mpi_mulm by ecc_mulm so that we can
-       experiment with different algorithms.
-       (generate_key, check_secret_key, sign, verify): Initialize a
-       computation context for use by ecc_mulm.
-
-2007-03-22  Werner Koch  <wk@g10code.com>
-
-       * pubkey.c (pubkey_table): Initialize ECC.
-       * Makefile.am (EXTRA_libcipher_la_SOURCES): Add ecc.c.
-       * ecc.c: New. Heavily reformatted and changed for use in libgcrypt.
-       (point_init): New.
-       (escalar_mult): Make arg R the first arg to be similar to the mpi
-       functions.
-       (duplicate_point): Ditto
-       (sum_points): Ditto
-       (sign, verify): Remove unneeded copy operations.
-       (sum_points): Removed memory leaks and optimized some compares.
-       (verify): Simplified input check.
-
-2007-03-14  Werner Koch  <wk@g10code.com>
-
-       * random.c (MASK_LEVEL): Removed macro as it was used only at one
-       place.  Open coded it there.
-       (gcry_randomize, _gcry_update_random_seed_file)
-       (_gcry_fast_random_poll): Factor lock code out to ..
-       (lock_pool, unlock_pool): .. new.
-       (initialize): Look the pool while allocating. 
-       (read_random_source, do_fast_random_poll): Moved intialization to ...
-       (initialize): .. here.
-       (_gcry_enable_quick_random_gen): No more need for initialization.
-       (is_initialized):  Moved this global flag to ..
-       (initialize): .. here and changed all users to unconditionally call
-       initialize.
-       (add_randomness): Remove initalization here.  It simply can't
-       happen. 
-
-       * random.c (enum random_origins): Moved to ..
-       * rand-internal.h: .. here.
-       * rndunix.c (_gcry_rndunix_gather_random): Use enum in prototype
-       for ORIGIN and renamed REQUESTOR to ORIGIN.
-       * rndegd.c (_gcry_rndegd_gather_random): Ditto.
-       * rndlinux.c (_gcry_rndlinux_gather_random): Ditto.
-       * rndw32.c (_gcry_rndw32_gather_random): Ditto.
-       (_gcry_rndw32_gather_random_fast): Ditto.
-
-2007-03-13  Werner Koch  <wk@g10code.com>
-
-       * random.c (enum random_origins): New.
-       (add_randomness): Renamed arg SOURCE to ORIGIN.
-       (read_random_source): Renamed arg REQUESTOR to ORIGIN.
-       (getfnc_gather_random): Removed static variable because this
-       function is only called one and thus we don't need this
-       optimization.
-       (_gcry_quick_random_gen): Removed and replaced by..
-       (_gcry_enable_quick_random_gen): .. this.  It is onlyu used to
-       enable it and it does not make sense to disable it later. Changed
-       the only one caller too.
-       (get_random_bytes): Removed.
-       (gcry_random_bytes, gcry_random_bytes_secure): Implement in terms
-       of gcry_randomize.
-       * random-daemon.c (_gcry_daemon_get_random_bytes): Removed.
-
-2007-02-23  Werner Koch  <wk@g10code.com>
-
-       * elgamal.c (generate): Removed unused variable TEMP.
-       (test_keys): New arg NODIE.
-       (generate_using_x, _gcry_elg_generate_using_x): New.
-       * pubkey.c (pubkey_generate): New arg XVALUE and direct call to
-       the new elgamal generate fucntion.
-       (gcry_pk_genkey): Parse the new "xvalue" tag.
-
-2007-02-22  Werner Koch  <wk@g10code.com>
-
-       * pubkey.c (sexp_data_to_mpi): Handle dynamically allocated
-       algorithms.  Suggested by Neil Dunbar.  Fixes bug#596.
-
-       * rndw32.c (_gcry_rndw32_gather_random_fast): Make it return void.
-
-       * cipher.c (gcry_cipher_algo_name): Simplified.
-
-       * random.c: Use the daemon only if compiled with USE_RANDOM_DAEMON. 
-
-       * Makefile.am (libcipher_la_SOURCES): Build random-daemon support
-       only if requested.
-
-2007-02-21  Werner Koch  <wk@g10code.com>
-
-       * random.c (rndpool, keypool): Make unsigned.
-       (mix_pool): Change char* variables to unsigned char*.
-       (gcry_randomize): Make arg BUFFER a void*.
-       (gcry_create_nonce): Ditto.
-
-       * rmd160.c (gcry_rmd160_mixblock): Make BUFFER a void*.
-       (_gcry_rmd160_hash_buffer): Make OUTBUF and BUFFER void*.
-       * sha1.c (_gcry_sha1_hash_buffer): Ditto.
-
-       * cipher.c (gcry_cipher_encrypt, cry_cipher_decrypt): Change
-       buffer args to void*.
-       (gcry_cipher_register): Make ALGORITHM_ID a int *.
-
-       * md.c (md_start_debug): Make SUFFIX a const char*.  Use snprintf.
-       (gcry_md_debug): New.
-       (gcry_md_ctl): Changed arg BUFFER from unsigned char*.
-
-       * md.c (md_write): Make INBUF a const void*.
-       (gcry_md_write): Remove needless cast.
-       * crc.c (crc32_write): Make INBUF a const void*
-       (update_crc32, crc24rfc2440_write): Ditto.
-       * sha512.c (sha512_write, transform): Ditto.
-       * sha256.c (sha256_write, transform): Ditto.
-       * rmd160.c (rmd160_write, transform): Ditto.
-       * md5.c (md5_write, transform): Ditto.
-       * md4.c (md4_write, transform): Ditto.
-       * sha1.c (sha1_write, transform): Ditto.
-
-       * tiger.c (tiger_write, transform): Ditto.
-       * whirlpool.c (whirlpool_write, whirlpool_add, transform): Ditto.
-
-       * elgamal.c (elg_names): Change to a const*.
-       * dsa.c (dsa_names): Ditto.
-       * rsa.c (rsa_names): Ditto.
-       * pubkey.c (gcry_pk_lookup_func_name): Make ALIASES a const.
-
-2007-02-20  Werner Koch  <wk@g10code.com>
-
-       * rndlinux.c (open_device): Remove unsused arg MINOR.
-
-2007-01-30  Werner Koch  <wk@g10code.com>
-
-       * sha256.c (oid_spec_sha256): Add alias from pkcs#1.
-       * sha512.c (oid_spec_sha512): Ditto.
-       (oid_spec_sha384): Ditto.
-
-2006-12-18  Werner Koch  <wk@g10code.com>
-
-       * rndlinux.c (set_cloexec_flag): New.
-       (open_device): Set close-on-exit flags.  Suggested by Max
-       Kellermann.  Fixes Debian#403613.
-
-       * Makefile.am (AM_CPPFLAGS, AM_CFLAGS): Splitted and merged
-       Moritz' changes.
-       (INCLUDES): Removed.
-
-2006-11-30  Werner Koch  <wk@g10code.com>
-
-       * serpent.c (byte_swap_32): Remove trailing semicolon.
-
-2006-11-15  Werner Koch  <wk@g10code.com>
-
-       * Makefile.am (INCLUDES): Include ../src/
-
-2006-11-03  Werner Koch  <wk@g10code.com>
-
-       * random.c [HAVE_GETTIMEOFDAY]: Included sys/time.h and not
-       sys/times.h.  Reported by Rafaël Carré.
-
-2006-11-05  Moritz Schulte  <moritz@g10code.com>
-
-       * Makefile.am (AM_CFLAGS): Added -I$(top_builddir)/src so that the
-       new gcrypt.h is used, not the one installed in the system.
-
-2006-10-25  Werner Koch  <wk@g10code.com>
-
-       * primegen.c (prime_generate_internal): Tweaked use of secure
-       memory and entropy use. Safe unused primes from the pool. Allocate
-       at least a pool of 30.
-       (save_pool_prime, get_pool_prime): New.
-
-2006-10-23  Werner Koch  <wk@g10code.com>
-
-       * ac.c (_gcry_ac_data_from_sexp): Reset sexp_tmp for failsafe
-       means.  Release sexp_cur if needed.  Reported by Dirk Stoecker.
-
-       * pubkey.c (pubkeys_registered_lock): Intialized it.  It is not
-        realy needed because this is a mere initialization to 0 anyway.
-        Noted by Victor Stinner.
-
-2006-10-17  Werner Koch  <wk@g10code.com>
-
-       * dsa.c (_gcry_dsa_generate2): New.
-       (generate): New arg QBITS.  Add sanity checks for reasonable qbits
-       and nbits.
-       * pubkey.c (gcry_pk_genkey): Parse an qbits element.
-       (pubkey_generate): New arg QBITS.  Pass it to the DSA generation.
-
-2006-10-05  Werner Koch  <wk@g10code.com>
-
-       * md.c (gcry_md_algo_info) <get_asnoid>: Check that the algo is
-       available.
-
-2006-10-04  David Shaw  <dshaw@jabberwocky.com>  (wk)
-       * tiger.c (round): Rename to tiger_round as gcc 4 has a built-in
-       round function that this conflicts with.
-2006-09-11  Werner Koch  <wk@g10code.com>
-
-       * rndw32.c (slow_gatherer_windowsNT): While adding data use the
-       size of the diskPerformance and not its address. Has been fixed in
-       GnuPG more than a year ago.  Noted by Lee Fisher.
-
-2006-08-30  Werner Koch  <wk@g10code.com>
-
-       * pubkey.c (sexp_data_to_mpi): Need to allow "ripemd160" here as
-       this is the canonical name.
-
-2006-08-29  Hye-Shik Chang <perky@FreeBSD.org>  (wk)
-
-       * seed.c: New.
-
-2006-08-03  Werner Koch  <wk@g10code.com>
-
-       * random-daemon.c (_gcry_daemon_initialize_basics): Don't
-       initialize the socket.  Remove arg SOCKETNAME.
-       (connect_to_socket): Make sure that daemon is set to -1 on error.
-       (call_daemon): Initialize the socket on the first call.
-       (_gcry_daemon_randomize, _gcry_daemon_get_random_bytes) 
-       (_gcry_daemon_create_nonce): New arg SOCKETNAME.
-       * random.c (initialize): Call new daemon initializator.
-       (get_random_bytes, gcry_randomize, gcry_create_nonce): Pass socket
-       name to daemon call and reset allow_daemon on failure.
-
-2006-07-26  Werner Koch  <wk@g10code.com>
-
-       * rmd160.c (_gcry_rmd160_mixblock): Add cast to transform call.
-
-       * blowfish.c (selftest): Cast string to usnigned char*.
-
-       * primegen.c (prime_generate_internal): Cast unsigned/char*
-       mismatch in calling m_out_of_n.
-       (is_prime): Changed COUNT to unsigned int *.
-
-       * ac.c (_gcry_ac_data_copy): Initialize DATA_MPIS.
-
-       * random.c (gcry_create_nonce): Update the pid after a fork.
-       Reported by Uoti Urpala.
-
-2006-07-04  Marcus Brinkmann  <marcus@g10code.de>
-
-       * sha512.c: Fix typo in copyright notice.
-
-2006-06-21  Werner Koch  <wk@g10code.com>
-
-       * rsa.c (_gcry_rsa_generate): Replace xcalloc by calloc.
-       * pubkey.c (gcry_pk_encrypt, gcry_pk_sign): Ditto.
-       (sexp_to_key, sexp_to_sig, sexp_to_enc, gcry_pk_encrypt) 
-       (gcry_pk_sign, gcry_pk_genkey, gcry_pk_get_keygrip): Ditto. 
-       * md.c (md_copy): Ditto.
-       
-2006-04-22  Moritz Schulte  <moritz@g10code.com>
-
-       * random-daemon.c (_gcry_daemon_initialize_basics): New argument:
-       SOCKETNAME.  Passing on to connect_to_socket() if non-NULL.
-       (connect_to_socket, writen, readn, call_daemon): New functions.
-       (_gcry_daemon_randomize, _gcry_daemon_get_random_bytes) 
-       (_gcry_daemon_create_nonce): Call call_daemon().
-       (RANDOM_DAEMON_SOCKET): New symbol.
-       (daemon_socket): New static variable.
-
-       * random.h (_gcry_daemon_initialize_basics): New parameter:
-       SOCKETNAME.
-       (_gcry_set_random_daemon_socket): New declaration.
-
-       * random.c (initialize_basics): Pass DAEMON_SOCKET_NAME to
-       _gcry_daemon_initialize_basics.
-       (_gcry_set_random_daemon_socket): New function, setting
-       DAEMON_SOCKET_NAME.
-
-2006-04-01  Moritz Schulte  <moritz@g10code.com>
-
-       * ac.c (eme_pkcs_v1_5_encode): Use KEY_SIZE directly, no need to
-       call gcry_ac_key_get_nbits.
-       (eme_pkcs_v1_5_decode): Likewise.
-       (ac_es_dencode_prepare_pkcs_v1_5): Fill options_em structure with
-       key_size.
-       (_gcry_ac_data_dump, gcry_ac_data_dump): New functions.
-       (_gcry_ac_data_to_sexp, _gcry_ac_data_from_sexp): More or less
-       rewritten; changed S-Expression format so that it matches the one
-       used in pubkey.c.
-
-2006-03-15  Werner Koch  <wk@g10code.com>
-
-       * random-daemon.c: New.
-       * random.c (_gcry_use_random_daemon): New.
-       (get_random_bytes, gcry_randomize, gcry_create_nonce): Try
-       diverting to the daemon functions.
-
-2006-03-14  Werner Koch  <wk@g10code.com>
-
-       * random.c (lock_seed_file): New.
-       (read_seed_file, _gcry_update_random_seed_file): Use it.
-
-       * random.c (gcry_create_nonce):  Detect a fork and re-seed.
-       (read_pool): Fixed the fork detection; it used to work only for
-       multi-threaded processes.
-
-2006-03-12  Brad Hards  <bradh@frogmouth.net>  (wk)
-
-       * md.c (md_open): Use new variable macpads_Bsize instead of
-       hardwiring the block size.  Changed at all places.
-
-2006-03-10  Brad Hards  <bradh@frogmouth.net>  (wk, patch 2005-04-22)
-
-       * md.c, sha256.c:  Add support for SHA-224.
-       (sha224_init): New.
-       
-2006-01-18  Brad Hards  <bradh@frogmouth.net>  (wk 2006-03-07)
-
-       * cipher.c (cipher_encrypt, cipher_decrypt, do_ofb_encrypt)
-       (do_ofb_decrypt, gcry_cipher_open): Implement Output Feedback Mode.
-
-2005-11-02  Moritz Schulte  <moritz@g10code.com>
-
-       * pubkey.c (gcry_pk_algo_name): Return "?" instead of NULL for
-       unknown algorithm IDs.
-       * cipher.c (cipher_algo_to_string): Likewise.
-
-2005-11-01  Moritz Schulte  <moritz@g10code.com>
-
-       * pubkey.c (gcry_pk_algo_info): Don't forget to break after switch
-       case.
-
-2005-09-19  Werner Koch  <wk@g10code.com>
-
-       * dsa.c (generate): Add preliminary support for 2 and 4 keys.
-       Return an error code if the key size is not supported.
-       (_gcry_dsa_generate): Return an error.
-
-2005-08-22  Werner Koch  <wk@g10code.com>
-
-       * primegen.c (check_prime): New arg RM_ROUNDS.
-       (prime_generate_internal): Call it here with 5 rounds as used
-       before.
-       (gcry_prime_check): But here with 64 rounds.
-       (is_prime): Make sure never to use less than 5 rounds.
-
-2005-04-16  Moritz Schulte  <moritz@g10code.com>
-
-       * ac.c (_gcry_ac_init): New function.
-
-2005-04-12  Moritz Schulte  <moritz@g10code.com>
-
-       * ac.c (_gcry_ac_io_write, _gcry_ac_io_read): Initialize err to
-       make the compiler happy.
-       Always use errno, now that gcry_malloc() is guaranteed to set
-       errno on failure.
-       (_gcry_ac_data_to_sexp): Don't forget to goto out after error in
-       loop.
-       (_gcry_ac_data_to_sexp): Remove unused variable: mpi_list;
-       (_gcry_ac_data_to_sexp): Always deallocate sexp_buffer.
-       (_gcry_ac_data_from_sexp): Don't forget to initialize data_set_new.
-       (_gcry_ac_data_from_sexp): Handle special case, which is
-       necessary, since gcry_sexp_nth() does not distinguish between
-       "element does not exist" and "element is the empty list".
-       (_gcry_ac_io_init_va): Use assert to make sure that mode and type
-       are correct.
-       Use gcry_error_t types where gcry_err_code_t types have been used
-       before.
-
-2005-04-11  Moritz Schulte  <moritz@g10code.com>
-
-       * ac.c (_gcry_ac_data_sign_scheme): Don't forget to initialize
-       buffer.
-
-       * whirlpool.c: New file.
-       * md.c (digest_table): Add whirlpool.
-       * Makefile.am (EXTRA_libcipher_la_SOURCES): Added: whirlpool.c.
-
-2005-03-30  Moritz Schulte  <moritz@g10code.com>
-
-       * ac.c (_gcry_ac_data_from_sexp): Use length of SEXP_CUR, not
-       length of SEXP; do not forget to set SEXP_TMP to NULL after it has
-       been released.
-
-       (struct gcry_ac_mpi): New member: name_provided.
-       (_gcry_ac_data_set): Rename variable `name_final' to `name_cp';
-       remove const qualifier; change code to not cast away const
-       qualifiers; use name_provided member as well.
-       (_gcry_ac_data_set, _gcry_ac_data_get_name): Use name_provided
-       member of named mpi structure.
-
-       (gcry_ac_name_to_id): Do not forget to initialize err.
-       (_gcry_ac_data_get_index): Do not forget to initialize mpi_return;
-       use gcry_free() instead of free(); remove unnecessary cast; rename
-       mpi_return and name_return to mpi_cp and name_cp; adjust code.
-       (ac_data_mpi_copy): Do not cast away const qualifier.
-       (ac_data_values_destroy): Likewise.
-       (ac_data_construct): Likewise.
-
-       (ac_data_mpi_copy): Initialize flags to GCRY_AC_FLAG_DEALLOC.
-       (ac_data_extract): Use GCRY_AC_FLAG_DEALLOC instead of
-       GCRY_AC_FLAG_COPY.
-
-       (_gcry_ac_io_init_va, _gcry_ac_io_init, gcry_ac_io_init)
-       (gcry_ac_io_init_va, _gcry_ac_io_write, _gcry_ac_io_read)
-       (_gcry_ac_io_read_all, _gcry_ac_io_process): New functions.
-       (gry_ac_em_dencode_t): Use gcry_ac_io_t in prototype instead of
-       memroy strings directly; adjust encode/decode functions to use io
-       objects.
-       (emsa_pkcs_v1_5_encode_data_cb): New function ...
-       (emsa_pkcs_v1_5_encode): ... use it here.
-       (ac_data_dencode): Use io objects.
-       (_gcry_ac_data_encode, _gcry_ac_data_decode, gcry_ac_data_encode)
-       (gcry_ac_data_decode): Likewise.
-       (_gcry_ac_data_encrypt_scheme, gcry_ac_data_encrypt_scheme)
-       (_gcry_ac_data_decrypt_scheme, gcry_ac_data_decrypt_scheme)
-       (_gcry_ac_data_sign_scheme, gcry_ac_data_sign_scheme)
-       (_gcry_ac_data_verify_scheme, gcry_ac_data_verify_scheme):
-       Likewise.
-
-2005-03-23  Werner Koch  <wk@g10code.com>
-
-       * rndw32.c (_gcry_rndw32_gather_random_fast): While adding data
-       use the size of the object and not the one of its address.  Bug
-       reported by Sascha Kiefer.
-
-2005-03-19  Moritz Schulte  <moritz@g10code.com>
-
-       * cipher.c (do_cbc_encrypt): Be careful to not overwrite data,
-       which is to be used later on.  This happend, in case CTS is
-       enabled and OUTBUF is equal to INBUF.
-
-2005-02-25  Werner Koch  <wk@g10code.com>
-
-       * pubkey.c (gcry_pk_get_keygrip): Allow for shadowed-private-key.
-
-2005-02-13  Moritz Schulte  <moritz@g10code.com>
-
-       * serpent.c: Updated from 1.2 branch:
-
-       s/u32_t/u32/ and s/byte_t/byte/.  Too match what we have always
-       used and are using in all other files too
-       (serpent_test): Moved prototype out of a fucntion.
-
-2005-02-07  Moritz Schulte  <moritz@g10code.com>
-
-       * ac.c: Major parts rewritten.
-       * pubkey.c (_gcry_pk_get_elements): New function.
-
-2004-12-09  Werner Koch  <wk@g10code.com>
-
-       * serpent.c (serpent_setkey): Moved prototype of serpent_test to
-       outer scope.
-
-2004-09-11  Moritz Schulte  <moritz@g10code.com>
-
-       * pubkey.c (pubkey_table): Added an alias entry for GCRY_PK_ELG_E.
-
-2004-08-23  Moritz Schulte  <moritz@g10code.com>
-
-       * ac.c: Do not include <assert.h>.
-       * rndegd.c: Likewise.
-       * sha1.c: Likewise.
-       * rndunix.c: Likewise.
-       * rndlinux.c: Likewise.
-       * rmd160.c: Likewise.
-       * md5.c: Likewise.
-       * md4.c: Likewise.
-       * cipher.c: Likewise.
-       * crc.c: Likewise.
-       * blowfish.c: Likewise.
-
-       * pubkey.c (dummy_generate, dummy_check_secret_key)
-       (dummy_encrypt, dummy_decrypt, dummy_sign, dummy_verify): Return
-       err code GPG_ERR_NOT_IMPLEMENTED instead of aborting through
-       log_bug().
-       (dummy_get_nbits): Return 0 instead of aborting though log_bug().
-
-2004-08-19  Werner Koch  <wk@g10code.de>
-
-       * pubkey.c (sexp_data_to_mpi): Changed the zero random byte
-       substituting code to actually do clever things.  Thanks to
-       Matthias Urlichs for noting the implementation problem.
-
-2004-08-09  Moritz Schulte  <moritz@g10code.com>
-
-       * pubkey.c (gcry_pk_sign): Fixed memory leak; fix provided by
-       Modestas Vainius.
-
-2004-07-16  Werner Koch  <wk@gnupg.org>
-
-       * rijndael.c (do_encrypt): Fix alignment problem.  Bugs found by
-       Matthias Urlichs.
-       (do_decrypt): Ditto.
-       (keySched, keySched2): Use 2 macros along with unions in the key
-       schedule context.
-
-2004-07-14  Moritz Schulte  <moritz@g10code.com>
-
-       * rsa.c (_gcry_rsa_decrypt): Don't forget to free "a".  Thanks to
-       Nikos Mavroyanopoulos.
-
-2004-05-09  Werner Koch  <wk@gnupg.org>
-
-       * random.c (read_pool): Mix the PID in to better protect after a
-       fork.
-
-2004-07-04  Moritz Schulte  <moritz@g10code.com>
-
-       * serpent.c: Use "u32_t" instead of "unsigned long", do not
-       declare S-Box variables as "register".  Fixes failure on
-       OpenBSD/sparc64, reported by Nikolay Sturm.
-
-2004-05-07  Werner Koch  <wk@gnupg.org>
-
-       * random.c (initialize): Factored out some code to ..
-       (initialize_basics): .. new function.
-       (_gcry_random_initialize): Just call initialize_basics unless the
-       new arg FULL is set to TRUE.
-       (_gcry_fast_random_poll): Don't do anything unless the random
-       system has been really initialized.
-
-2004-05-07  Moritz Schulte  <moritz@g10code.de>
-
-       * ac.c (gcry_ac_open): Do not dereference NULL pointer.  Reported
-       by Umberto Salsi.
-
-2004-02-20  Werner Koch  <wk@gnupg.org>
-
-       * primegen.c (check_prime): New args CB_FUNC and CB_ARG; call them
-       at different stages.  Pass these arguments through all callers.
-
-2004-02-06  Werner Koch  <wk@gnupg.org>
-
-       * des.c: Add a new OID as used by pkcs#12.
-
-       * rfc2268.c: New. Taken from libgcrypt. 
-       * cipher.c: Setup the rfc2268 algorithm.
-
-2004-01-25  Moritz Schulte  <mo@g10code.com>
-
-       * primegen.c (prime_generate_internal): Do not forget to free
-       `q_factor'; fixed by Brieuc Jeunhomme.
-       (prime_generate_internal): Do not forget to free `prime'.
-
-2004-01-14  Moritz Schulte  <mo@g10code.com>
-
-       * ac.c (gcry_ac_data_set): New argument: flags; slightly
-       rewritten.
-       (gcry_ac_data_get_name, gcry_ac_data_get_index): Likewise.
-       (gcry_ac_key_pair_generate): New argument: misc_data; modified
-       order of arguments.
-       (gcry_ac_key_test): New argument: handle.
-       (gcry_ac_key_get_nbits, gcry_ac_key_get_grip): Likewise.
-       Use GCRY_AC_FLAG_NO_BLINDING instead of
-       GCRY_AC_DATA_FLAG_NO_BLINDING.
-       (gcry_ac_mpi): New member: flags.
-       (gcry_ac_data_search, gcry_ac_data_add): Removed functions.
-
-2003-12-22  Werner Koch  <wk@gnupg.org>
-
-       * primegen.c (is_prime): Release A2.
-
-2003-12-19  Werner Koch  <wk@gnupg.org>
-
-       * md.c: Moved a couple of functions down below the data structure
-       definitions.
-       (struct gcry_md_context): New field ACTUAL_HANDLE_SIZE.
-       (md_open): Set it here.
-       (strcut gcry_md_list): New field ACTUAL_STRUCT_SIZE.
-       (md_enable): Set it here.
-       (md_close): Wipe the context memory.
-       secure memory.
-       * cipher.c (struct gcry_cipher_handle): New field ACTUAL_HANDLE_SIZE.
-       (gcry_cipher_open): Set it here.
-       (gcry_cipher_close): Use it to always wipe out the handle data.
-
-       * ac.c (gcry_ac_open): Make sure HANDLE gets initialized even when
-       the function is not successful.
-       (gcry_ac_close): Allow a NULL handle.
-       (gcry_ac_key_destroy, gcry_ac_key_pair_destroy): Ditto.
-       (gcry_ac_key_get_grip): Return INV_OBJ on error.
-
-       * primegen.c (prime_generate_internal): Fixed error code for
-       failed malloc.  Replaced the !err if chain by gotos.
-       (gcry_prime_group_generator): Remove the extra sanity check.
-
-       * md.c: Minor code and comment cleanups.
-
-2003-12-16  Werner Koch  <wk@gnupg.org>
-
-       * primegen.c (gen_prime): Doc fix.  Thanks to Newton Hammet.
-
-2003-12-11  Werner Koch  <wk@gnupg.org>
-
-       * rndunix.c (slow_poll): Don't use #warning but #error.
-
-       * rndegd.c: Changed indentation.
-       (my_make_filename): Removd the var_arg cruft becuase we
-       don't need it here.  Changed caller.  
-
-       * rndlinux.c: Changed indentation.
-       (open_device): Remove the superfluous stat call and clarify
-       comment.
-
-       * rsa.c: Changed indentation.
-       (secret): Use the standard algorithm if p, q and u are not
-       available.
-       (rsa_blind, rsa_unblind): Renamed from _gcry_rsa_blind,
-       _gcry_rsa_unblind and moved more to the top.
-
-       * md4.c: Changed indentation.  Removed unnecessary casts.
-       * md5.c, rmd160.c, sha1.c, tiger.c: Ditto.
-       * rijndael.c, twofish.c: Ditto.
-       * serpent.c: Removed unnecessary casts.
-       * sha256.c, sha512.c: Ditto.
-
-2003-12-09  Werner Koch  <wk@gnupg.org>
-
-       * dsa.c: Unified indentation style.
-       * elgamal.c: Ditto. 
-       * des.c (des_key_schedule): Code beautifications.
-       * blowfish.c: Changed indentation style.
-       * cast5.c (do_cast_setkey): Ditto.
-
-       * pubkey.c (gcry_pk_encrypt): Replaced the chain of if(!err) tests
-       by straightforward gotos. Other cleanups.
-       (gcry_pk_decrypt): Ditto.
-       (gcry_pk_sign): Ditto.
-       (gcry_pk_verify): Ditto.
-       (gcry_pk_genkey): Ditto.  Use strtoul instead of strtol.
-       (gcry_pk_ctl): Use GPG_ERR_INV_ARG to indicate bad arguments.
-
-2003-12-07  Werner Koch  <wk@gnupg.org>
-
-       * pubkey.c (gcry_pk_register_default): Undef the helper macro.
-       (gcry_pk_map_name): Allow NULL for string.
-       (sexp_to_key): Use memcpy and not strncpy.  Use gcry_free and not
-       free.
-       (sexp_to_sig): Ditto.
-       (sexp_to_enc): Ditto.  Replaced the chain of if(!err) tests by
-       straightforward gotos.
-
-2003-12-05  Werner Koch  <wk@gnupg.org>
-
-       * cipher.c: Documentation cleanups.
-       (gcry_cipher_mode_from_oid): Allow NULL for STRING.
-
-2003-12-03  Werner Koch  <wk@gnupg.org>
-
-       * elgamal.c (sign, do_encrypt, gen_k): Make sure that a small K is
-       only used for encryption.
-
-2003-11-18  Werner Koch  <wk@gnupg.org>
-
-       * random.h (rndw32_set_dll_name): Removed unused prototype.
-
-       * Makefile.am (EXTRA_DIST): Added Manifest.
-
-2003-11-11  Werner Koch  <wk@gnupg.org>
-
-       * Manifest: New.
-
-2003-11-04  Werner Koch  <wk@gnupg.org>
-
-       * md.c (gcry_md_hash_buffer): Use shortcut for SHA1
-       * sha1.c (_gcry_sha1_hash_buffer): New.
-
-       * random.c: Reformatted most functions.
-       (mix_pool): Moved the failsafe_digest from global
-       scope to here.
-       (do_fast_random_poll): Use the generic fucntions even if a fast
-       gathering function has been used.
-       (read_pool): Detect a fork and retry.
-       (gcry_randomize, get_random_bytes): Don't distinguish anymore
-       between weak and strong random.
-       (gcry_create_nonce): New.
-
-2003-10-31  Werner Koch  <wk@gnupg.org>
-
-       * rndw32.c (slow_gatherer_windowsNT): Use a plain buffer for the
-       disk performance values and not the W32 API structure.
-
-       * dsa.c (verify): s/exp/ex/ due to shadowing of a builtin.
-       * elgamal.c (verify): Ditto.
-
-       * ac.c (gcry_ac_data_get_index): s/index/idx/
-       (gcry_ac_data_copy_internal): Remove the cast in _gcry_malloc.
-       (gcry_ac_data_add): Must use gcry_realloc instead of realloc.
-       * pubkey.c (sexp_elements_extract): s/index/idx/ as tribute to the
-       forehackers.
-       (gcry_pk_encrypt): Removed shadowed definition of I. Reordered
-       arguments to malloc for clarity.
-       (gcry_pk_sign, gcry_pk_genkey): Ditto.
-       * primegen.c (prime_generate_internal): s/random/randomlevel/.
-
-2003-10-27  Moritz Schulte  <mo@g10code.com>
-
-       * pubkey.c (gcry_pk_encrypt): Don't forget to deallocate pkey.
-
-2003-10-27  Werner Koch  <wk@gnupg.org>
-
-       * random.c (gcry_random_add_bytes): Return if buflen is zero to
-       avoid gcc warning about unsed parameter.
-       (MASK_LEVEL): Simplified; does now work for signed and unsigned
-       w/o warnings.
-
-       * md.c (md_start_debug): Removed the const from SUFFIX, because
-       this function is called from the control fucntion which does not
-       require const.
-
-       Prefixed all (pubkey,digest,cipher}_spec_* globale variables with
-       _gcry_.
-
-       * ac.c (ac_key_identifiers): Made static.
-
-       * random.c (getfnc_gather_random,getfnc_fast_random_poll): Move
-       prototypes to ..
-       * rand-internal.h: .. here 
-       * random.c (getfnc_gather_random): Include rndw32 gatherer.
-       * rndunix.c, rndw32.c, rndegd.c: Include them here.
-       * rndlinux.c (_gcry_rndlinux_gather_random): Prepend the _gcry_
-       prefix.  Changed all callers.
-       * rndegd.c (_gcry_rndegd_gather_random): Likewise.
-       (_gcry_rndegd_connect_socket): Likewise.
-       * rndunix.c (_gcry_rndunix_gather_random): Likewise.
-       (waitpid): Made static.
-       * rndw32.c: Removed the old and unused winseed.dll cruft.
-       (_gcry_rndw32_gather_random_fast): Renamed from
-       gather_random_fast.
-       (_gcry_rndw32_gather_random): Renamed from gather_random.  Note,
-       that the changes 2003-04-08 somehow got lost.
-
-       * sha512.c (sha512_init, sha384_init): Made static.
-
-       * cipher.c (do_ctr_decrypt): Removed "return" from this void
-       function.
-
-2003-10-24  Moritz Schulte  <mo@g10code.com>
-
-       * serpent.c: Fix an issue on big-endian systems.
-
-       * rndw32.c: Removed IS_MODULE -cruft.
-       * rndlinux.c (rndlinux_gather_random): Likewise.
-
-2003-10-10  Werner Koch  <wk@gnupg.org>
-
-       * primegen.c (gen_prime): Bail out if NBITS is less than 16.
-       (prime_generate_internal): Initialize prime variable to suppress
-       compiler warning.  Check pbits, initialize qbits when passed as
-       zero.
-
-       * primegen.c (prime_generate_internal): New arg
-       ALL_FACTORS. Changed all callers.
-       (gcry_prime_generate): Make the factors arg optional. Request
-       all_factors.  Make sure PRIME is set to NULL even on error.
-       (gcry_prime_group_generator): New.
-       (gcry_prime_release_factors): New.
-
-2003-10-06  Werner Koch  <wk@gnupg.org>
-
-       * primegen.c (gen_prime): Assert that NBITS is never zero, it
-       would cause a segv.
-
-2003-09-28  Moritz Schulte  <mo@g10code.com>
-
-       * ac.c: Include "cipher.h".
-
-2003-09-27  Moritz Schulte  <mo@g10code.com>
-
-       * rndegd.c (do_read): Return nread instead of nbytes; thanks to
-       Michael Caerwyn.
-
-2003-09-04  Werner Koch  <wk@gnupg.org>
-
-       * pubkey.c (_gcry_pk_aliased_algo_name): New.
-       * ac.c (gcry_ac_open): Use it here.
-
-       * Makefile.am (EXTRA_libcipher_la_SOURCES): Add serpent.c
-
-2003-09-02  Moritz Schulte  <mo@g10code.com>
-
-       * primegen.c (gcry_prime_check, gcry_prime_generate): New
-       functions.
-       (prime_generate_internal): New function, based on
-       _gcry_generate_elg_prime.
-       (_gcry_generate_elg_prime): Rewritten as a wrapper for
-       prime_generate_internal.
-
-2003-08-28  Werner Koch  <wk@gnupg.org>
-
-       * pubkey.c (gcry_pk_encrypt): Don't include the flags list in the
-       return value.  This does not make sense and breaks any programs
-       parsing the output strictly (e.g. current gpgsm).
-       (gcry_pk_encrypt): If aliases for the algorithm name exists, take
-       the first one instead of the regular name to adhere to SPKI
-       conventions.
-       (gcry_pk_genkey): Ditto.
-       (gcry_pk_sign): Ditto. Removed unused KEY_ALGO_NAME.
-
-2003-08-19  Moritz Schulte  <mo@g10code.com>
-
-       * cipher.c: Add support for Serpent
-       * serpent.c: New file.
-
-2003-08-10  Moritz Schulte  <moritz@g10code.com>
-
-       * rsa.c (_gcry_rsa_blind, _gcry_rsa_unblind): Declare static.
-
-2003-08-09  Timo Schulz  <twoaday@freakmail.de>
-
-       * random.c (getfnc_gather_random): Don't check NAME_OF_DEV_RANDOM
-       two times, but also the NAME_OF_DEV_URANDOM device.
-       
-2003-08-08  Moritz Schulte  <moritz@g10code.com>
-
-       * pubkey.c (sexp_to_enc): Fixed extraction of S-Expression: do not
-       fail if no `flags' sub S-Expression is found.
-
-2003-07-27  Werner Koch  <wk@gnupg.org>
-
-       * md.c (gcry_md_lookup_func_oid): Allow for empty OID lists.
-
-2003-07-23  Moritz Schulte  <moritz@g10code.com>
-
-       * ac.c (gcry_ac_data_construct): New argument: include_flags, only
-       include `flags' S-expression, if include_flags is true.  Adjust
-       callers.  Thanks for triggering a bug caused by `flags'
-       sub-S-expression where they are not expected to Ralf Schneider.
-
-2003-07-21  Moritz Schulte  <moritz@g10code.com>
-
-       * pubkey.c (gcry_pk_lookup_func_name): Use new member name
-       `aliases' instead of `sexp_names'.
-
-       * ac.c (gcry_ac_key_data_get): New function.
-
-       * cipher.c (gcry_cipher_lookup_func_name): Fix return value.
-
-2003-07-20  Moritz Schulte  <moritz@g10code.com>
-
-       * blowfish.c: Adjusted for new gcry_cipher_spec_t structure.
-       * cast5.c: Likewise.
-       * twofish.c: Likewise.
-       * arcfour.c: Likewise.
-       * rijndael.c (rijndael_oids, rijndael192_oids, rijndael256_oids):
-       New variables, adjust for new gcry_cipher_spec_t structure.
-       * des.c (oids_tripledes): New variable, adjust for new
-       gcry_cipher_spec_t structure.
-
-       * md.c (oid_table): Removed.
-
-       * tiger.c (oid_spec_tiger): New variable.
-       (digest_spec_tiger): Adjusted for new gry_md_spec_t structure.
-
-       * sha512.c (oid_spec_sha512): New variable.
-       (digest_spec_sha512): Adjusted for new gry_md_spec_t structure.
-
-       * sha512.c (oid_spec_sha384): New variable.
-       (digest_spec_sha384): Adjusted for new gry_md_spec_t structure.
-
-       * sha256.c (oid_spec_sha256): New variable.
-       (digest_spec_sha256): Adjusted for new gry_md_spec_t structure.
-
-       * sha1.c (oid_spec_sha1): New variable.
-       (digest_spec_sha1): Adjusted for new gry_md_spec_t structure.
-
-       * rmd160.c (oid_spec_rmd160): New variable.
-       (digest_spec_rnd160): Adjusted for new gry_md_spec_t structure.
-
-       * md5.c (oid_spec_md5): New variable.
-       (digest_spec_md5): Adjusted for new gry_md_spec_t structure.
-
-       * md4.c (oid_spec_md4): New variable.
-       (digest_spec_md4): Adjusted for new gry_md_spec_t structure.
-
-       * crc.c (digest_spec_crc32, digest_spec_crc32_rfc1510,
-       digest_spec_crc32_rfc2440): Adjusted for new gry_md_spec_t
-       structure.
-
-2003-07-19  Moritz Schulte  <moritz@g10code.com>
-
-       * md.c (gcry_md_lookup_func_oid): New function.
-       (search_oid): New function, copied from cipher.c.
-       (gcry_md_map_name): Adjust for new search_oid_interface.
-
-       * cipher.c (oid_table): Removed table.
-       (gcry_cipher_lookup_func_oid): New function.
-       (search_oid): Rewritten to use the module functions.
-       (gcry_cipher_map_name): Adjust for new search_oid interface.
-       (gcry_cipher_mode_from_oid): Likewise.
-
-2003-07-18  Werner Koch  <wk@gnupg.org>
-
-       * md.c (gcry_md_hash_buffer): Convert ERR to gpg_error_t in
-       gpg_strerror.
-
-2003-07-14  Moritz Schulte  <moritz@g10code.com>
-
-       * cipher.c (gcry_cipher_lookup_func_name): Also check the cipher
-       name aliases, not just the primary name.
-       (gcry_cipher_map_name): Remove kludge for aliasing Rijndael to
-       AES.
-
-       * arcfour.c, blowfish.c, cast5.c, des.c, twofish.c: Adjust cipher
-       specification structures.
-
-       * rijndael.c (rijndael_names, rijndael192_names,
-       rijndael256_names): New variables, use them in the cipher
-       specifications.
-
-       * rmd160test.c: Removed file.
-
-       * ac.c, arcfour.c, blowfish.c, cast5.c, cipher.c, des.c, dsa.c,
-       elgamal.c, md.c, pubkey.c, random.c, rijndael.c, rsa.c, twofish.c:
-       Used gcry_err* wrappers for libgpg symbols.
-
-       * primegen.c (gen_prime): Correct the order arguments to
-       extra_check.
-
-2003-07-12  Moritz Schulte  <moritz@g10code.com>
-
-       * ac.c: Replaced all public occurences of gpg_error_t with
-       gcry_error_t.
-       * cipher.c: Likewise.
-       * md.c: Likewise.
-       * pubkey.c: Likewise.
-       * random.c: Likewise.
-
-       * cipher.c: Added support for TWOFISH128.
-
-2003-07-08  Moritz Schulte  <moritz@g10code.com>
-
-       * ac.c (gcry_ac_data_copy_internal): New function, based on
-       gcry_ac_data_copy.
-       (gcry_ac_data_copy): Made public, use gcry_ac_data_copy_internal.
-       (gcry_ac_key_init): Use gcry_ac_data_copy_internal.
-
-2003-07-07  Moritz Schulte  <moritz@g10code.com>
-
-       * ac.c (gcry_ac_data_set): Only release old MPI value if it is
-       different from the new value.  Bug reported by Simon Josefsson
-       <jas@extundo.com>.
-
-       * pubkey.c (gcry_pk_list): New function.
-       * md.c (gcry_md_list): New function.
-
-       * ac.c (gcry_ac_key_pair_generate): Fix calculation of format
-       string size.
-
-2003-07-05  Moritz Schulte  <moritz@g10code.com>
-
-       * md.c: Named struct of digest_table `digest_table_entry'.
-       (digest_table_entry): New member: algorithm; filled in.
-       (digest_table_entry): Removed unused member: flags.
-       (gcry_md_register): New argument: algorithm_id, filled in.
-       (gcry_md_register_default): Used algorithm ID from module
-       structure.
-       (gcry_md_map_name): Likewise.
-       (md_enable): Likewise.
-       (md_read): Likewise.
-       (gcry_md_info): Likewise.
-
-       * pubkey.c: Named truct for pubkey_table `pubkey_table_entry'.
-       (pubkey_table_entry): New member: algorithm; filled in.
-       (gcry_pk_register_default): Used algorithm ID from pubkey_table.
-       (gcry_pk_register): New argument: algorithm_id, filled in.
-       (gcry_pk_map_name): Used algorithm ID from module structure.
-       (gcry_pk_decrypt): Likewise.
-       (gcry_pk_encrypt): Likewise.
-       (gcry_pk_verify): Likewise.
-       (gcry_pk_sign): Likewise.
-       (gcry_pk_testkey): Likewise.
-       (gcry_pk_genkey): Likewise.
-       (gcry_pk_get_nbits): Likewise.
-       (sexp_to_key): Removed unused variable: algo.
-       (sexp_to_sig): Likewise.
-
-       * cipher.c: Named struct for cipher_table `cipher_table_entry'.
-       (cipher_table_entry): New member: algorithm; filled in.
-       (gcry_cipher_register_default): Used algorithm ID from
-       cipher_table.
-       (gcry_cipher_register): New argument: algorithm_id, filled in.
-       (gcry_cipher_map_name): Used algorithm ID from module structure.
-
-       * arcfour.c (cipher_spec_arcfour): Removed algorithm ID.
-       * blowfish.c (cipher_spec_blowfish): Likewise.
-       * cast5.c (cipher_spec_cast5): Likewise.
-       * crc.c (digest_spec_crc32): Likewise.
-       * crc.c (digest_spec_crc32_rfc1510): Likewise.
-       * crc.c (digest_spec_crc32_rfc2440): Likewise.
-       * des.c (cipher_spec_des): Likewise.
-       * des.c (cipher_spec_tripledes): Likewise.
-       * dsa.c (pubkey_spec_dsa): Likewise.
-       * elgamal.c (pubkey_spec_elg): Likewise.
-       * md4.c (digest_spec_md4): Likewise.
-       * md5.c (digest_spec_md5): Likewise.
-       * aes.c (cipher_spec_aes): Likewise.
-       * aes.c (cipher_spec_aes192): Likewise.
-       * aes.c (cipher_spec_aes256): Likewise.
-       * rsa.c (pubkey_spec_rsa): Likewise.
-       * sha1.c (digest_spec_sha1): Likewise.
-       * sha256.c (digest_spec_sha256): Likewise.
-       * sha512.c (digest_spec_sha512): Likewise.
-       * tiger.c (digest_spec_tiger): Likewise.
-       * twofish.c (cipher_spec_twofish): Likewise.
-       * twofish.c (cipher_spec_twofish128): Likewise.
-
-       * Makefile.am (EXTRA_libcipher_la_SOURCES): Fix list of source
-       files; reported by Simon Josefsson <jas@extundo.com>.
-
-       * pubkey.c: Replaced all occurences of `id' with `algorithm',
-       since `id' is a keyword in obj-c.
-       * md.c: Likewise.
-       * cipher.c: Likewise.
-
-       * crc.c, md4.c, md5.c, rmd160.c, sha1.c, sha256.c, tiger.c:
-       Replaced all occurences of gcry_digest_spec_t with gcry_md_spec_t.
-
-       * dsa.c, rsa.c, elgamal.c: Replaced all occurencens of
-       gcry_pubkey_spec_t with gcry_pk_spec_t.
-
-       * md.c: Replaced all occurences of gcry_digest_spec_t with
-       gcry_md_spec_t.
-       (gcry_digest_register_default): Renamed to ...
-       (gcry_md_register_default): ... this; adjusted callers.
-       (gcry_digest_lookup_func_name): Renamed to ...
-       (gcry_md_lookup_func_name): ... this; adjusted callers.
-       (gcry_digest_lookup_name): Renamed to ...
-       (gcry_md_lookup_name): ... this; adjusted callers.
-       (gcry_digest_register): Renamed to ...
-       (gcry_md_register): ... this.
-       (gcry_digest_unregister): Renamed to ...
-       (gcry_md_unregister): ... this.
-
-       * pubkey.c (gcry_pubkey_register): Renamed to ...
-       (gcry_pk_register): ... this.
-       (gcry_pubkey_unregister): Renamed to ...
-       (gcry_pk_unregister): ... this.
-       Replaced all occurences of gcry_pubkey_spec_t with gcry_pk_spec_t.
-       (gcry_pubkey_register_default): Renamed to ...
-       (gcry_pk_register_default): ... this; adjusted callers.
-       (gcry_pubkey_lookup_func_name): Renamed to ...
-       (gcry_pk_lookup_func_name): ... this; adjusted callers.
-       (gcry_pubkey_lookup_name): Renamed to ...
-       (gcry_pk_lookup_name): ... this; adjusted callers.
-
-       * md.c (gcry_md_hash_buffer): Fix error checking.  Thanks to Simon
-       Josefsson <jas@extunde.com>.
-
-2003-07-04  Moritz Schulte  <moritz@g10code.com>
-
-       * cipher.c (gcry_cipher_list): New function.
-
-2003-07-01  Moritz Schulte  <moritz@g10code.com>
-
-       * pubkey.c (sexp_to_sig): Accept a `flags' S-expression to be more
-       consistent with sexp_to_enc.
-
-2003-06-30  Moritz Schulte  <moritz@g10code.com>
-
-       * Makefile.am (libcipher_la_SOURCES): Added: ac.c.
-
-       * pubkey.c (_gcry_pk_module_lookup): New function.
-       (_gcry_pk_module_release): New function.
-
-2003-06-29  Moritz Schulte  <moritz@g10code.com>
-
-       * ac.c: New file.
-
-2003-06-26  Werner Koch  <wk@gnupg.org>
-
-       * md.c (gcry_md_hash_buffer): Trigger BUG correcly with new API.
-
-2003-06-19  Werner Koch  <wk@gnupg.org>
-
-       * md.c (gcry_md_is_enabled): Fixed. 
-
-2003-06-18  Werner Koch  <wk@gnupg.org>
-
-       * cipher.c (gcry_cipher_get_algo_keylen): New.
-       (gcry_cipher_get_algo_blklen): New.
-
-2003-06-18  Moritz Schulte  <moritz@g10code.com>
-
-       * arcfour.c, cipher.c, blowfish.c, md.c, cast5.c, pubkey.c, crc.c,
-       des.c, dsa.c, elgamal.c, md4.c, md5.c, random.c, rijndael.c,
-       rmd160.c, rsa.c, sha1.c, sha256.c, sha512.c, tiger.c, twofish.c:
-       Replaced older types GcryDigestSpec, GcryCipherSpec and
-       GcryPubkeySpec with newer types: gcry_digest_spec_t,
-       gcry_cipher_spec_t and gcry_pubkey_spec_t.
-
-       * md.c (gcry_digest_id_new): Removed function.
-       (gcry_digest_register): Removed code for generating a new module
-       ID.
-
-       * pubkey.c (gcry_pubkey_id_new): Removed function.
-       (gcry_pubkey_register): Removed code for generating a new module
-       ID.
-
-       * cipher.c, md.c, pubkey.c: Replace old type GcryModule with newer
-       one: gcry_module_t.
-       (gcry_cipher_id_new): Removed function.
-       (gcry_cipher_register): Removed code for generating a new module
-       ID.
-
-       * cipher.c (gcry_cipher_register): Adjust call to
-       _gcry_module_add.
-       (gcry_cipher_register_default): Likewise.
-       * pubkey.c (gcry_pubkey_register_default): Likewise.
-       (gcry_pubkey_register): Likewise.
-       * md.c (gcry_digest_register_default): Likewise.
-       (gcry_digest_register): Likewise.
-
-       * md.c (gcry_digest_lookup_func_id): Removed function.
-       (gcry_digest_lookup_id): Likewise.
-       (gcry_digest_id_new): Use _gcry_module_lookup_id instead of
-       gcry_digest_lookup_id.
-       (digest_algo_to_string): Likewise.
-       (check_digest_algo): Likewise.
-       (md_enable): Likewise.
-       (md_digest_length): Likewise.
-       (md_asn_oid): Likewise.
-
-       * pubkey.c (gcry_pubkey_lookup_id): Removed function.
-       (gcry_pubkey_lookup_func_id): Likewise.
-       (gcry_pubkey_id_new): Use _gcry_module_lookup_id instead of
-       gcry_pubkey_id_new.
-       (gcry_pk_algo_name): Likewise.
-       (disable_pubkey_algo): Likewise.
-       (check_pubkey_algo): Likewise.
-       (pubkey_get_npkey): Likewise.
-       (pubkey_get_nskey): Likewise.
-       (pubkey_get_nsig): Likewise.
-       (pubkey_get_nenc): Likewise.
-       (pubkey_generate): Likewise.
-       (pubkey_check_secret_key): Likewise.
-       (pubkey_encrypt): Likewise.
-       (pubkey_decrypt): Likewise.
-       (pubkey_sign): Likewise.
-       (pubkey_verify): Likewise.
-       (gcry_pk_algo_info): Likewise.
-
-       * cipher.c (gcry_cipher_lookup_func_id): Removed function.
-       (gcry_cipher_lookup_id): Likewise.
-       (cipher_algo_to_string): use _gcry_module_lookup_id instead of
-       gcry_cipher_lookup_id.
-       (disable_cipher_algo): Likewise.
-       (check_cipher_algo): Likewise.
-       (cipher_get_blocksize): Likewise.
-       (gcry_cipher_open): Likewise.
-       (gcry_cipher_id_new): Likewise.
-
-2003-06-17  Moritz Schulte  <moritz@g10code.com>
-
-       * Makefile.am (GCRYPT_MODULES): Set to @GCRYPT_CIPHERS@,
-       @GCRYPT_PUBKEY_CIPHERS@, @GCRYPT_DIGESTS@ and @GCRYPT_RANDOM@.
-       (libcipher_la_DEPENDENCIES): Set to $(GCRYPT_MODULES).
-       (libcipher_la_LIBADD): Likewise.
-       (AM_CFLAGS): Added: @GPG_ERROR_CFLAGS@.
-       (EXTRA_libcipher_la_SOURCES): Added all conditional sources.
-
-       * md.c (md_open): Use _gcry_fast_random_poll instead of
-       fast_random_poll.
-       * cipher.c (gcry_cipher_open): Likewise.
-
-       * random.h (fast_random_poll): Removed macro.
-
-       * blowfish.c, md4.c, md5.c, rmd160.c, sha1.c, sha256.c, sha512.c,
-       tiger.c: Use Autoconf's WORDS_BIGENDIAN instead of our own
-       BIG_ENDIAN_HOST.
-
-2003-06-16  Moritz Schulte  <moritz@g10code.com>
-
-       * random.c (getfnc_gather_random): Do not special-case
-       USE_ALL_RANDOM_MODULES, make it the default.
-
-       * dsa.c: Replace last occurences of old type names with newer
-       names (i.e. replace MPI with gcry_mpi_t).
-       * elgamal.c: Likewise.
-       * primegen.c: Likewise.
-       * pubkey.c: Likewise.
-       * rsa.c: Likewise.
-
-2003-06-14  Moritz Schulte  <moritz@g10code.com>
-
-       * des.c (des_setkey): Add selftest check.
-       (tripledes_set3keys): Likewise.
-       (do_tripledes_setkey): Remove selftest check.
-       (do_des_setkey): Likewise.
-
-2003-06-11  Moritz Schulte  <moritz@g10code.com>
-
-       * md.c (_gcry_md_init): New function.
-       * cipher.c (_gcry_cipher_init): New function.
-       * pubkey.c (_gcry_pk_init): New function.
-
-2003-06-13  Werner Koch  <wk@gnupg.org>
-
-       * md.c (gcry_md_get_algo): Reverted to old API.  This is a
-       convenience function anyway and error checking is not approriate.
-       (gcry_md_is_secure): New.
-       (gcry_md_is_enabled): New.
-
-2003-06-12  Werner Koch  <wk@gnupg.org>
-
-       * cipher.c (gcry_cipher_open): Make sure HANDLE is set to NULL on
-       error.
-
-2003-06-11  Werner Koch  <wk@gnupg.org>
-
-       * md.c (gcry_md_open): Make sure H receives either NULL or an
-       valid handle.
-       (gcry_md_copy): Swapped arguments so that it is more in lione with
-       md_open and most other API fucntions like memcpy (destination
-       comes first).  Make sure HANDLE is set to NULL on error.
-       
-       * rijndael.c (do_encrypt): Hack to force correct alignment.  It
-       seems not to be not sufficient, though.  We should rework this
-       fucntions and remove all these ugly casts.  Let the compiler
-       optimize or have an assembler implementation.
-
-2003-06-09  Moritz Schulte  <moritz@g10code.com>
-
-       * Makefile.am: Removed rules serpent, since that is not commited
-       yet.
-
-2003-06-08  Moritz Schulte  <moritz@g10code.com>
-
-       * pubkey.c (gcry_pk_encrypt): Improve calculation for size of the
-       format string.
-
-2003-06-07  Moritz Schulte  <moritz@g10code.com>
-
-       * arcfour.c, bithelp.h, blowfish.c, cast5.c, cipher.c, crc.c,
-       des.c, dsa.c, elgamal.c, md4.c, md5.c, md.c, primegen.c, pubkey.c,
-       rand-internal.h, random.c, random.h, rijndael.c, rmd160.c,
-       rmd160test.c, rmd.h, rndeged.c, rndlinux.c, rndunix.c, rndw32.c,
-       rsa.c, sha1.c, sha256.c, sha512.c, tiger.c, twofish.c: Edited all
-       preprocessor instructions to remove whitespace before the '#'.
-       This is not required by C89, but there are some compilers out
-       there that don't like it.  Replaced any occurence of the now
-       deprecated type names with the new ones.
-       
-2003-06-04  Moritz Schulte  <moritz@g10code.com>
-
-       * pubkey.c (gcry_pk_encrypt): Construct an arg_list and use
-       gcry_sexp_build_array instead of gcry_sexp_build.
-       (gcry_pk_sign): Likewise.
-       (gcry_pk_genkey): Likewise.
-
-2003-06-01  Moritz Schulte  <moritz@g10code.com>
-
-       * dsa.c (_gcry_dsa_generate): Do not check wether the algorithm ID
-       does indeed belong to DSA.
-       (_gcry_dsa_sign): Likewise.
-       (_gcry_dsa_verify): Likewise.
-       (_gcry_dsa_get_nbits): Likewise.
-
-       * elgamal.c (_gcry_elg_check_secret_key): Do not check wether the
-       algorithm ID does indeed belong to ElGamal.
-       (_gcry_elg_encrypt): Likewise.
-       (_gcry_elg_decrypt): Likewise.
-       (_gcry_elg_sign): Likewise.
-       (_gcry_elg_verify): Likewise.
-       (_gcry_elg_get_nbits): Likewise.
-       (_gcry_elg_generate): Likewise.
-
-       * rsa.c (_gcry_rsa_generate): Do not check wether the algorithm ID
-       does indeed belong to RSA.
-       (_gcry_rsa_encrypt): Likewise.
-       (_gcry_rsa_decrypt): Likewise.
-       (_gcry_rsa_sign): Likewise.
-       (_gcry_rsa_verify): Likewise.
-       (_gcry_rsa_get_nbits): Likewise.
-
-2003-05-30  Moritz Schulte  <moritz@g10code.com>
-
-       * md.c (md_get_algo): Return zero in case to algorithm is enabled.
-
-       * md.c (gcry_md_info): Adjusted for new no-errno-API.
-       (md_final): Likewise.
-       (gcry_md_get_algo): Likewise.
-       * pubkey.c (gcry_pk_get_keygrip): Likewise.
-       (gcry_pk_ctl): Likewise.
-       (gcry_pk_algo_info): Likewise.
-       * des.c (selftest): Likewise.
-
-2003-05-29  Moritz Schulte  <moritz@g10code.com>
-
-       * md.c (md_enable): Do not forget to release module on error.
-       (gcry_md_open): Adjusted for new no-errno-API.
-       (md_open): Likewise.
-       (md_copy): Likewise.
-       (gcry_md_copy): Likewise.
-       (gcry_md_setkey): Likewise.
-       (gcry_md_algo_info): Likewise.
-
-       * cipher.c (gcry_cipher_open): Adjusted for new no-errno-API and
-       also fixed a locking bug.
-       (gcry_cipher_encrypt): Adjusted for new no-errno-API.
-       (gcry_cipher_decrypt): Likewise.
-       (gcry_cipher_ctl): Likewise.
-       (gcry_cipher_info): Likewise.
-       (gcry_cipher_algo_info): Likewise.
-
-2003-05-28  Moritz Schulte  <moritz@g10code.com>
-
-       * md.c (md_enable): Adjusted for libgpg-error.
-       (gcry_md_enable): Likewise.
-       (gcry_digest_register_default): Likewise.
-       (gcry_digest_register): Likewise.
-       (check_digest_algo): Likewise.
-       (prepare_macpads): Likewise.
-       (gcry_md_setkey): Likewise.
-       (gcry_md_ctl): Likewise.
-       (gcry_md_get): Likewise.
-       (gcry_md_algo_info): Likewise.
-       (gcry_md_info): Likewise.
-       * dsa.c (_gcry_dsa_generate): Likewise.
-       (_gcry_dsa_check_secret_key): Likewise.
-       (_gcry_dsa_sign): Likewie.
-       (_gcry_dsa_verify): Likewise.
-       * twofish.c (do_twofish_setkey): Likewise.
-       (twofish_setkey): Likewise.
-       * cipher.c (gcry_cipher_register): Likewise.
-
-2003-05-25  Moritz Schulte  <moritz@g10code.com>
-
-       * rijndael.c (do_setkey): Adjusted for libgpg-error.
-       (rijndael_setkey): Likewise.
-       * random.c (gcry_random_add_bytes): Likewise.
-       * elgamal.c (_gcry_elg_generate): Likewise.
-       (_gcry_elg_check_secret_key): Likewise.
-       (_gcry_elg_encrypt): Likewise.
-       (_gcry_elg_decrypt): Likewise.
-       (_gcry_elg_sign): Likewise.
-       (_gcry_elg_verify): Likewise.
-       * rsa.c (_gcry_rsa_generate): Likewise.
-       (_gcry_rsa_check_secret_key): Likewise.
-       (_gcry_rsa_encrypt): Likewise.
-       (_gcry_rsa_decrypt): Likewise.
-       (_gcry_rsa_sign): Likewise.
-       (_gcry_rsa_verify): Likewise.
-       * pubkey.c (dummy_generate, dummy_check_secret_key, dummy_encrypt,
-       dummy_decrypt, dummy_sign, dummy_verify): Likewise.
-       (gcry_pubkey_register): Likewise.
-       (check_pubkey_algo): Likewise.
-       (pubkey_generate): Likewise.
-       (pubkey_check_secret_key): Likewise.
-       (pubkey_encrypt): Likewise.
-       (pubkey_decrypt): Likewise.
-       (pubkey_sign): Likewise.
-       (pubkey_verify): Likewise.
-       (sexp_elements_extract): Likewise.
-       (sexp_to_key): Likewise.
-       (sexp_to_sig): Likewise.
-       (sexp_to_enc): Likewise.
-       (sexp_data_to_mpi): Likewise.
-       (gcry_pk_encrypt): Likewise.
-       (gcry_pk_decrypt): Likewise.
-       (gcry_pk_sign): Likewise.
-       (gcry_pk_verify): Likewise.
-       (gcry_pk_testkey): Likewise.
-       (gcry_pk_genkey): Likewise.
-       (gcry_pk_ctl): Likewise.
-       * cipher.c (dummy_setkey): Likewise.
-       (check_cipher_algo): Likewise.
-       (gcry_cipher_open): Likewise.
-       (cipher_setkey): Likewise.
-       (gcry_cipher_ctl): Likewise.
-       (cipher_encrypt): Likewise.
-       (gcry_cipher_encrypt): Likewise.
-       (cipher_decrypt): Likewise.
-       (gcry_cipher_decrypt): Likewise.
-       (gcry_cipher_info): Likewise.
-       (gcry_cipher_algo_info): Likewise.
-       * cast5.c (cast_setkey): Likewise.
-       (do_cast_setkey): Likewise.
-       * arcfour.c (arcfour_setkey): Likewise.
-       (do_arcfour_setkey): Likewise.
-       * blowfish.c (do_bf_setkey): Likewise.
-       (bf_setkey): Likewise.
-       * des.c (do_des_setkey): Likewise.
-       (do_tripledes_setkey): Likewise.
-
-2003-05-22  Moritz Schulte  <moritz@g10code.com>
-
-       * tiger.c: Merged code ussing the U64_C macro from GnuPG.
-
-       * sha512.c: Likewise.
-
-2003-05-17  Moritz Schulte  <moritz@g10code.com>
-
-       * pubkey.c (gcry_pk_genkey): Fix type: acquire a lock, instead of
-       releasing it.
-
-2003-05-11  Moritz Schulte  <moritz@g10code.com>
-
-       * pubkey.c (gcry_pk_testkey): Call REGISTER_DEFAULT_CIPHERS.
-       (gcry_pk_ctl): Likewise.
-
-2003-04-27  Moritz Schulte  <moritz@g10code.com>
-
-       * pubkey.c (gcry_pk_genkey): Release sexp after extracted data has
-       been used.
-
-       * md.c (gcry_md_get_algo_dlen): Simplified, simply call
-       md_digest_length to do the job.
-
-       * des.c (do_des_setkey): Check for selftest failure not only
-       during initialization.
-       (do_tripledes_setkey): Include check for selftest failure.
-
-       * pubkey.c (gcry_pubkey_register_default): New macro
-       `pubkey_use_dummy', use it.
-
-       * elgamal.c (elg_names): New variable.
-       (pubkey_spec_elg): Include elg_names.
-
-       * dsa.c (dsa_names): New variable.
-       (pubkey_spec_dsa): Include dsa_names.
-
-       * rsa.c (rsa_names): New variable.
-       (pubkey_spec_rsa): Include rsa_names.
-
-       * pubkey.c (gcry_pubkey_lookup_func_name): Compare name also with
-       the names listed in `sexp_names'.
-
-2003-04-24  Moritz Schulte  <moritz@g10code.com>
-
-       * pubkey.c (sexp_to_key): New variables: module, pubkey.  Adjusted
-       to new module interface.
-       (sexp_to_key): Changend type of argument `retalgo' from `int *' to
-       `GcryModule **'.  Adjusted all callers.  Removed argument:
-       r_algotblidx.
-       (sexp_to_sig): Changend type of argument `retalgo' from `int *' to
-       `GcryModule **'.  Adjusted all callers.
-       (sexp_to_enc): Likewise.
-
-       (pubkey_get_npkey, pubkey_get_nskey, pubkey_get_nsig,
-       pubkey_get_nenc): Use strlen to find out the number.
-
-       * rsa.c: Adjust pubkey_spec_rsa to new internal interface.
-       * dsa.c: Likewise.
-       * elgamal.c: Likewise.
-
-2003-04-17  Moritz Schulte  <moritz@g10code.com>
-
-       * pubkey.c (sexp_elements_extract): New function.
-       * pubkey.c (sexp_to_key): Removed variable `idx', added `err', use
-       sexp_elements_extract.
-       (sexp_to_sig): Likewise.
-       (sexp_to_enc): Likewise.
-
-       * pubkey.c: Terminate list correctly.
-       * md.c: Include sha512/sha384 in digest_table.
-
-2003-04-16  Moritz Schulte  <moritz@g10code.com>
-
-       * Makefile.am: Include support for sha512.c.
-
-       * sha512.c: New file, merged from GnuPG, with few modifications
-       for libgcrypt.
-
-       * rand-internal.h: Removed declarations for constructor functions.
-
-       * md.c (md_copy): Call _gcry_module_use for incrementing the usage
-       counter of the digest modules.
-
-       * rsa.c: Do not include "rsa.h".
-       * dsa.c: Do not include "dsa.h".
-       * elgamal.c: Do not include "elgamal.h".
-       * des.c: Do not include "des.h".
-       * cast5.c: Do not include "cast5.h".
-       * blowfish.c: Do not include "blowfish.h".
-       * arcfour.c: Do not include "arcfour.h".
-
-       * Makefile.am (libcipher_la_DEPENDENCIES): Removed.
-       (libcipher_la_LIBADD): Removed.
-       Use Automake conditionals for conditional compilation.
-
-2003-04-13  Moritz Schulte  <moritz@g10code.com>
-
-       * cipher.c (gcry_cipher_open): Call REGISTER_DEFAULT_CIPHERS.
-
-       * md.c (gcry_md_list): New member: module.
-       (md_enable): New variable: module, changed use of module and
-       digest.
-       (md_enable): Initialize member: module.
-       (md_close): Call _gcry_module_release.
-
-       * cipher.c (gcry_cipher_open): New variable: module, changed use of
-       module and cipher.
-       (struct gcry_cipher_handle): New member: module.
-       (gcry_cipher_open): Initialize member: module.
-       (gcry_cipher_close): Call _gcry_module_release.
-
-2003-04-09  Moritz Schulte  <moritz@g10code.com>
-       
-       * cipher.c: Include "ath.h".
-       * md.c: Likewise.
-       * pubkey.c: Likewise.
-
-       * cipher.c (ciphers_registered_lock): New variable.
-       * md.c (digests_registered_lock): New variable.
-       * pubkey.c (pubkeys_registered_lock): New variable.
-
-       * rndlinux.c (gnupgext_version, func_table): Removed definitions.
-       (gnupgext_enum_func): Removed function.
-       (_gcry_rndlinux_constructor): Removed function.
-
-       * rndegd.c (gnupgext_version, func_table): Removed definitions.
-       (gnupgext_enum_func): Removed function.
-       (_gcry_rndegd_constructor): Removed function.
-
-       * rndunix.c (gnupgext_version, func_table): Removed definitions.
-       (gnupgext_enum_func): Removed function.
-       (_gcry_rndunix_constructor): Removed function.
-
-       * rndw32.c (gnupgext_version, func_table): Removed definitions.
-       (gnupgext_enum_func): Removed function.
-       (_gcry_rndw32_constructor): Removed function.
-
-       * rndegd.c (rndegd_connect_socket): Simplify code for creating the
-       egd socket address.
-       (rndegd_connect_socket): Call log_fatal use instead of
-       g10_log_fatal.
-       (egd_gather_random): Renamed to ...
-       (rndegd_gather_random): ... here.
-
-2003-04-08  Moritz Schulte  <moritz@g10code.com>
-
-       * rndlinux.c: Do not include "dynload.h".
-       * rndunix.c: Likewise.
-       * rndw32.c: Likewise.
-
-       * rndegd.c (rndegd_connect_socket): Factored out from ...
-       (egd_gather_random): here; call it.
-       (egd_socket): New variable.
-       (egd_gather_random): Initialize fd with egd_socket, do not declare
-       fd static.
-       (do_read): Merged few changes from GnuPG. FIXME - not finished?
-       Do not include "dynload.h".
-
-       * rndw32.c (gather_random): Renamed to rndw32_gather_random, do
-       not declare static.
-       (gather_random_fast): Renamed to rndw32_gather_random_fast, do not
-       declare static.
-
-       * rndunix.c (gather_random): Renamed to rndunix_gather_random, do
-       not declare static.
-       * rndegd.c (gather_random): Renamed to rndegd_gather_random, do
-       not declare static.
-       * rndlinux.c (gather_random): Renamed to rndlinux_gather_random,
-       do not declare static.
-
-2003-04-07  Moritz Schulte  <moritz@g10code.com>
-
-       * Makefile.am (libcipher_la_SOURCES): Removed construct.c.
-       (libcipher_la_SOURCES): Added sha1.c, sha256.c, rmd160.c, md4.c,
-       md5.c, tiger.c and crc.c
-       (EXTRA_PROGRAMS): Removed sha1, sha256, rmd160, md4, md5, tiger
-       and crc.  Removed definitions: EXTRA_md4_SOURCES,
-       EXTRA_md5_SOURCES, EXTRA_rmd160_SOURCES, EXTRA_sha1_SOURCES,
-       EXTRA_sha256_SOURCES, EXTRA_tiger_SOURCES and EXTRA_crc_SOURCES,
-       BUILT_SOURCES, DISTCLEANFILES.
-
-       * pubkey.c: Do not include "elgamal.h", "dsa.h" and "rsa.h".
-
-       * Makefile.am (libcipher_la_SOURCES): Removed rsa.h, elgamal.h,
-       dsa.h, des.h, cast5.h, arcfour.h and blowfish.h.
-
-       * rsa.h: Removed file.
-       * elgamal.h: Removed file.
-       * dsa.h: Removed file.
-       * des.h: Removed file.
-       * cast5.h: Removed file.
-       * arcfour.h: Removed file.
-       * blowfish.h: Removed file.
-
-       * Makefile.am (libcipher_la_SOURCES): Removed dynload.c and
-       dynload.h.
-
-       * rsa.c (pubkey_spec_rsa): New variable.
-       * dsa.c (pubkey_spec_rsa): New variable.
-       * elgamal.c (pubkey_spec_elg): New variable.
-       
-       * rsa.c (_gcry_rsa_get_info): Removed function.
-       * elgamal.c (_gcry_elg_get_info): Removed function.
-       * dsa.c (_gcry_dsa_get_info): Removed function.
-
-       * tiger.c (tiger_get_info): Removed function.
-       (gnupgext_version, func_table): Removed definitions.
-       (gnupgext_enum_func): Removed function.
-       (_gcry_tiger_constructor): Removed function.
-       
-       * sha1.c (sha1_get_info): Removed function.
-       (gnupgext_version, func_table): Removed definitions.
-       (gnupgext_enum_func): Removed function.
-       (_gcry_sha1_constructor): Removed function.
-
-       * sha256.c (sha256_get_info): Removed function.
-       (gnupgext_version, func_table): Removed definitions.
-       (gnupgext_enum_func): Removed function.
-       (_gcry_sha256_constructor): Removed function.
-
-       * rmd160.c (rmd160_get_info): Removed function.
-       (gnupgext_version, func_table): Removed definitions.
-       (gnupgext_enum_func): Removed function.
-       (_gcry_rmd160_constructor): Removed function.
-
-       * md5.c (md5_get_info): Removed function.
-       (gnupgext_version, func_table): Removed definitions.
-       (gnupgext_enum_func): Removed function.
-       (_gcry_md5_constructor): Removed function.
-
-       * md4.c (md4_get_info): Removed function.
-       (gnupgext_version, func_table): Removed definitions.
-       (gnupgext_enum_func): Removed function.
-       (_gcry_md4_constructor): Removed function.
-
-       * crc.c (crc_get_info): Removed function.
-
-       * arcfour.c (do_arcfour_setkey): Changed type of context argument
-       to `void *', added local variable for cast, adjusted callers.
-       (arcfour_setkey): Likewise.
-       (encrypt_stream): Likewise.
-       * cast5.c (cast_setkey): Likewise.
-       (encrypt_block): Likewise.
-       * rijndael.c (rijndael_setkey): Likewise.
-       (rijndael_encrypt): Likewise.
-       (rijndael_decrypt): Likewise.
-       * twofish.c (twofish_setkey): Likewise.
-       (twofish_encrypt): Likewise.
-       (twofish_decrypt): Likewise.
-       * des.c (do_des_setkey): Likewise.
-       (do_des_encrypt): Likewise.
-       (do_des_encrypt): Likewise.
-       (do_tripledes_encrypt): Likewise.
-       (do_tripledes_encrypt): Likewise.
-       * blowfish.c (bf_setkey: Likewise.
-       (encrypt_block): Likewise.
-       (decrypt_block): Likewise.
-       
-       * arcfour.c (encrypt_stream): Likewise.
-
-       * rijndael.c (gnupgext_version, func_table): Removed definitions.
-       (gnupgext_enum_func) Removed function.  
-       
-       * twofish.c (gnupgext_version, func_table): Removed definitions.
-       (gnupgext_enum_func) Removed function.  
-
-       * cast5.c (CIPHER_ALGO_CAST5): Removed.
-
-       * blowfish.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Removed macros.
-       (CIPHER_ALGO_BLOWFISH): Removed symbol.
-       * cast5.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Likewise.
-       * des.c (selftest_failed): Removed.
-       (initialized): New variable.
-       (do_des_setkey): Run selftest, if not yet done.
-       (FNCCAST_SETKEY, FNCCAST_CRYPT): Removed macros.
-
-       * arcfour.c (_gcry_arcfour_get_info): Removed function.
-       * blowfish.c (_gcry_blowfish_get_info): Removed function.
-       * cast5.c (_gcry_cast5_get_info): Removed function.
-       * des.c (_gcry_des_get_info): Removed function.
-       * rijndael.c (_gcry_rijndael_get_info): Removed function.
-       * twofish.c (_gcry_twofish_get_info): Removed function.
-
-       * arcfour.c (cipher_spec_arcfour): New variable.
-       * twofish.c (cipher_spec_twofish, cipher_spec_twofish128): New
-       variables.
-       * rijndael.c (cipher_spec_aes, cipher_spec_aes192,
-       cipher_spec256): New variables.
-       * des.c (cipher_spec_des, cipher_spec_tripledes): New variables.
-       * cast5.c (cipher_spec_cast5): New variable.
-       * blowfish.c (cipher_spec_blowfish): Likewise.
-       
-       * twofish.c: Do not include "dynload.h".
-       * rijndael.c: Likewise.
-       * des.c: Likewise.
-       * cast5.c: Likewise.
-       * blowfish.c: Likewise.
-       * cipher.c: Likewise.
-       * crc.c: Likewise.
-       * md4.c: Likewise.
-       * md5.c: Likewise.
-       * md.c: Likewise.
-       * pubkey.c: Likewise.
-       * rijndael.c: Likewise.
-       * sha1.c: Likewise.
-       * sha256.c: Likewise.
-
-       * arcfour.c: Include "cipher.h".
-       * twofish.c: Likewise.
-       * rijndael.c: Likewise.
-       * des.c: Likewise.
-       * cast5.c: Likewise.
-       * blowfish.c: Likewise.
-
-       * twofish.c (twofish_setkey): Declared argument `key' const.
-       (twofish_encrypt): Declared argument `inbuf' const.
-       (twofish_decrypt): Likewise.
-
-       * rijndael.c (rijndael_setkey): Declared argument `key' const.
-       (rijndael_encrypt): Declared argument `inbuf' const.
-       (rijndael_decrypt): Likewise.
-
-       * des.c (do_des_setkey): Declared argument `key' const.
-       (do_tripledes_setkey): Likewise.
-       (do_des_encrypt): Declared argument `inbuf' const.
-       (do_des_decrypt): Likewise.
-       (do_tripledes_encrypt): Likewise.
-       (do_tripledes_decrypt): Likewise.
-
-       * cast5.c (encrypt_block): Declared argument `inbuf' const.
-       (decrypt_block): Likewise.
-       (cast_setkey): Declared argument `key' const.
-
-       * blowfish.c (do_bf_setkey): Declared argument `key' const.
-       (encrypt_block): Declared argument `inbuf' const.
-       (encrypt_block): Likewise.
-
-       
-
-       * cipher.c: Remove CIPHER_ALGO_DUMMY related code.
-       Removed struct cipher_table_s.
-       Changed definition of cipher_table.
-       Removed definition of disabled_algos.
-       (ciphers_registered, default_ciphers_registered): New variables.
-       (REGISTER_DEFAULT_CIPHERS): New macro.
-       (dummy_setkey): Declared argument `key' const.
-       (dummy_encrypt_block): Declared argument `inbuf' const.
-       (dummy_encrypt_block): Likewise.
-       (dummy_encrypt_stream): Likewise.
-       (dummy_encrypt_stream): Likewise.
-       (dummy_setkey): Use `unsigned char' instead of `byte'.
-       (dummy_encrypt_block): Likewise.
-       (dummy_decrypt_block): Likewise.
-       (dummy_encrypt_stream): Likewise.
-       (dummy_decrypt_stream): Likewise.
-       (gcry_cipher_register_default): New function.
-       (gcry_cipher_lookup_func_id): New function.
-       (gcry_cipher_lookup_func_name): New function.
-       (gcry_cipher_lookup_id): New function.
-       (gcry_cipher_lookup_name): New function.
-       (gcry_cipher_id_new): New function.
-       (gcry_cipher_register): New function.
-       (gcry_cipher_unregister): New function.
-       (setup_cipher_table): Removed function.
-       (load_cipher_modules): Removed function.
-       (gcry_cipher_map_name): Adjusted to use new module management.
-       (cipher_algo_to_string): Likewise.
-       (disable_cipher_algo): Likewise.
-       (check_cipher_algo): Likewise.
-       (cipher_get_keylen): Likewise.
-       (cipher_get_blocksize): Likewise.
-       (gcry_cipher_open): Likewise.
-       (struct gcry_cipher_handle): Replaced members algo, algo_index,
-       blocksize, setkey, encrypt, decrypt, stencrypt, stdecrypt with one
-       member: cipher.
-       (gcry_cipher_open): Adjusted code for new handle structure.
-       (cipher_setkey): Likewise.
-       (cipher_setiv): Likewise.
-       (cipher_reset): Likewise.
-       (do_ecb_encrypt): Likewise.
-       (do_ecb_decrypt): Likewise.
-       (do_cbc_encrypt): Likewise.
-       (do_cbc_decrypt): Likewise.
-       (do_cfb_encrypt): Likewise.
-       (do_cfb_decrypt): Likewise.
-       (do_ctr_encrypt): Likewise.
-       (cipher_encrypt): Likewise.
-       (gcry_cipher_encrypt): Likewise.
-       (cipher_decrypt): Likewise.
-       (gcry_cipher_decrypt): Likewise.
-       (cipher_sync): Likewise.
-       (gcry_cipher_ctl): Likewise.
-
-       * pubkey.c: Removed struct pubkey_table_s.
-       Changed definition of pubkey_table.
-       Removed definition of disabled_algos.
-       (pubkeys_registered, default_pubkeys_registered): New variables.
-       (REGISTER_DEFAULT_PUBKEYS): New macro.
-       (setup_pubkey_table): Removed function.
-       (load_pubkey_modules): Removed function.
-       (gcry_pubkey_register_default): New function.
-       (gcry_pubkey_lookup_func_id): New function.
-       (gcry_pubkey_lookup_func_name): New function.
-       (gcry_pubkey_lookup_id): New function.
-       (gcry_pubkey_lookup_name): New function.
-       (gcry_pubkey_id_new): New function.
-       (gcry_pubkey_register): New function.
-       (gcry_pubkey_unregister): New function.
-       (gcry_pk_map_name): Adjusted to use new module management.
-       (gcry_pk_algo_name): Likewise.
-       (disable_pubkey_algo): Likewise.
-       (check_pubkey_algo): Likewise.
-       (pubkey_get_npkey): Likewise.
-       (pubkey_get_nskey): Likewise.
-       (pubkey_get_nsig): Likewise.
-       (pubkey_get_nenc): Likewise.
-       (pubkey_generate): Likewise.
-       (pubkey_check_secret_key): Likewise.
-       (pubkey_encrypt): Likewise.
-       (pubkey_decrypt): Likewise.
-       (pubkey_sign): Likewise.
-       (pubkey_verify): Likewise.
-       (gcry_pk_get_nbits): Likewise.
-       (gcry_pk_algo_info): Likewise.
-
-       * md.c: Removed struct md_digest_list_s.
-       (digest_list): Changed definition.
-       (digests_registered, default_digests_registered): New variables.
-       (REGISTER_DEFAULT_DIGESTS): New macro.
-       (new_list_item): Removed function.
-       (setup_md_table): Removed function.
-       (load_digest_module): Removed function.
-       (gcry_digest_register_default): New function.
-       (gcry_digest_lookup_func_id): New function.
-       (gcry_digest_lookup_func_name): New function.
-       (gcry_digest_lookup_id): New function.
-       (gcry_digest_lookup_name): New function.
-       (gcry_digest_id_new): New function.
-       (gcry_digest_register): New function.
-       (gcry_digest_unregister): New function.
-       (GcryDigestEntry): New type.
-       (struct gcry_md_context): Adjusted type of `list'.
-       (gcry_md_map_name): Adjusted to use new module management.
-       (digest_algo_to_string): Likewise.
-       (check_digest_algo): Likewise.
-       (md_enable): Likewise.
-       (md_digest_length): Likewise.
-       (md_asn_oid): Likewise.
-
-2003-04-07  Moritz Schulte  <moritz@g10code.com>
-
-       * pubkey.c: Replaced PUBKEY_ALGO_DSA with GCRY_PK_DSA,
-       PUBKEY_ALGO_RSA with GCRY_PK_RSA and PUBKEY_ALGO_ELGAMAL with
-       GCRY_PK_ELG.
-
-       * dsa.c: Replaced PUBKEY_ALGO_DSA with GCRY_PK_DSA.
-
-2003-04-01  Moritz Schulte  <moritz@g10code.com>
-
-       * des.c: Removed checks for GCRY_CIPHER_3DES and GCRY_CIPHER_DES.
-
-2003-03-31  Moritz Schulte  <moritz@g10code.com>
-
-       * tiger.c (tiger_get_info): Do not declare static.
-       * sha256.c (sha256_get_info): Likewise.
-       * sha1.c (sha1_get_info): Likewise.
-       * rmd160.c (rmd160_get_info): Likewise.
-       * md5.c (md5_get_info): Likewise.
-       * md4.c (md4_get_info): Likewise.
-       * crc.c (crc_get_info): Likewise.
-
-       * md.c (load_digest_module): Call setup_md_table during
-       initialization.
-       (new_list_item): Link new element into digest_list.
-
-       * cipher.c (do_ctr_decrypt): Made do_ctr_encrypt act as a wrapper
-       for do_ctr_encrypt, since these functions are identical.
-
-2003-03-30  Simon Josefsson  <jas@extundo.com>
-
-       * cipher.c (struct gcry_cipher_handle): Add counter field.
-       (gcry_cipher_open): Add CTR.
-       (cipher_reset): Clear counter field.
-       (do_ctr_encrypt, do_ctr_decrypt): New functions.
-       (cipher_encrypt, cipher_decrypt): Call CTR functions.
-       (gcry_cipher_ctl): Add SET_CTR to set counter.
-
-2003-03-30  Moritz Schulte  <moritz@g10code.com>
-
-       * rsa.c (_gcry_rsa_blind): New function.
-       (_gcry_rsa_unblind): New function.
-       (_gcry_rsa_decrypt): Use _gcry_rsa_blind and _gcry_rsa_decrypt.
-
-2003-03-26  Moritz Schulte  <moritz@g10code.com>
-
-       * dynload.c (_gcry_enum_gnupgext_pubkeys): Adjust `encrypt' and
-       `decrypt' function arguments.
-       (_gcry_enum_gnupgext_pubkeys): Likewise.
-       * dynload.h: Likewise.
-       
-       * pubkey.c (dummy_decrypt): Add argument: int flags.
-       (dummy_encrypt): Likewise.
-
-       * elgamal.c (_gcry_elg_encrypt): Add argument: int flags.
-       (_gcry_elg_decrypt): Likewise.
-
-       * rsa.c (_gcry_rsa_encrypt): Add argument: int flags.
-       (_gcry_rsa_decrypt): Likewise.
-
-       * pubkey.c: Add `flags' argument to members `encrypt' and
-       `decrypt' of struct `pubkey_table_s'.
-
-       * rsa.h: Add `flags' argument to function declarations.
-       * elgamal.h: Likewise.
-
-       * pubkey.c (sexp_data_to_mpi): New variable: int parsed_flags.
-       (sexp_data_to_mpi): Set `parsed_flags'.
-       (sexp_data_to_mpi): New argument: int *flags.
-       (gcry_pk_encrypt): New variable: int flags.
-       (gcry_pk_encrypt): Pass `flags' to pubkey_encrypt.
-       (pubkey_encrypt): New variable: int flags.
-       (pubkey_encrypt): Pass `flags' to pubkey encrypt function.
-       (pubkey_decrypt): Likewise.
-       (pubkey_decrypt): Pass `flags' to pubkey encrypt function.
-       (gcry_pk_encrypt): Include `flags' s-exp in return list.
-       (sexp_to_enc): New argument: int *flags.
-       (gcry_pk_decrypt): New variable: int flags.
-       (gcry_pk_decrypt): Pass `flags' to pubkey_decrypt.
-       (sexp_to_enc): New variable: int parsed_flags.
-       (sexp_to_enc): Set `parsed_flags'.
-
-2003-03-22  Simon Josefsson  <jas@extundo.com>
-
-       * cipher.c (gcry_cipher_open, do_cbc_encrypt)
-       (gcry_cipher_encrypt): Support GCRY_CIPHER_CBC_MAC.
-       (gcry_cipher_ctl): Support GCRYCTL_SET_CBC_MAC.
-
-2003-03-19  Werner Koch  <wk@gnupg.org>
-
-       * primegen.c (gen_prime): New args EXTRA_CHECK and EXTRA_CHECK_ARG
-       to allow for a user callback.  Changed all callers.
-       (_gcry_generate_secret_prime)
-       (_gcry_generate_public_prime): Ditto, pass them to gen_prime.
-       * rsa.c (check_exponent): New.
-       (generate): Use a callback to ensure that a given exponent is
-       actually generated.
-
-2003-03-12  Moritz Schulte  <moritz@g10code.com>
-
-       * primegen.c: Initialize `no_of_small_prime_numbers' statically.
-       (gen_prime): Remove calculation of `no_of_small_prime_numbers'.
-
-2003-03-03  Moritz Schulte  <moritz@g10code.com>
-
-       * md.c (gcry_md_ctl): Rewritten to use same style like the other
-       functions dispatchers.
-
-2003-03-02  Moritz Schulte  <moritz@g10code.com>
-
-       * cipher.c (struct gcry_cipher_handle): New member: algo_index.
-       (gcry_cipher_open): Allocate memory for two cipher contexts.
-       Initialize algo_index.
-       (cipher_setkey): Duplicate context into reserved memory.
-       (cipher_reset): New function, which resets the context and clear
-       the IV.
-       (gcry_cipher_ctl): Call cipher_reset.
-
-2003-02-23  Moritz Schulte  <moritz@g10code.com>
-
-       * cipher.c: Remove (bogus) `digitp' macro definition.
-       * md.c: Likewise.
-
-       * blowfish.c (burn_stack): Removed.
-       * arcfour.c (burn_stack): Likewise.
-       * cast5.c (burn_stack): Likewise.
-       * des.c (burn_stack): Likewise.
-       * md4.c (burn_stack): Likewise.
-       * md5.c (burn_stack): Likewise.
-       * random.c (burn_stack): Likewise.
-       * rijndael.c (burn_stack): Likewise.
-       * rmd160.c (burn_stack): Likewise.
-       * sha1.c (burn_stack): Likewise.
-       * sha256.c (burn_stack): Likewise.
-       * tiger.c (burn_stack): Likewise.
-       * twofish.c (burn_stack): Likewise.
-
-       * blowfish.c: Changed all occurences of burn_stack to
-       _gcry_burn_stack.
-       * arcfour.c: Likewise.
-       * cast5.c: Likewise.
-       * des.c: Likewise.
-       * md4.c: Likewise.
-       * md5.c: Likewise.
-       * random.c: Likewise.
-       * rijndael.c: Likewise.
-       * rmd160.c: Likewise.
-       * sha1.c: Likewise.
-       * sha256.c: Likewise.
-       * tiger.c: Likewise.
-       * twofish.c: Likewise.
-
-       * arcfour.c (_gcry_arcfour_get_info): Use GCRY_CIPHER_ARCFOUR
-       instead of hard-coded value `301'.
-
-2003-01-24  Werner Koch  <wk@gnupg.org>
-
-       * random.c (_gcry_register_random_progress): New.
-       (_gcry_random_progress): New.
-
-       * rndlinux.c (gather_random): Call the random progress function. 
-
-2003-01-23  Werner Koch  <wk@gnupg.org>
-
-       * rsa.c (generate): New arg USE_E to request a specific public
-       exponent.
-       (_gcry_rsa_generate): Ditto.
-       * elgamal.c (_gcry_elg_generate): Must add an dummy argument
-       instead of USE_E.
-       * dsa.c (_gcry_dsa_generate): Ditto.
-       * pubkey.c (dummy_generate): Ditto.
-       (pubkey_generate): Add USE_E arg and pass it down.
-       (gcry_pk_genkey): Detect "rsa-use-e" parameter and pass it to generate.
-
-       * pubkey.c (sexp_to_enc): New arg RET_MODERN.
-       (gcry_pk_decrypt): Make use of it to return a real S-expression.
-       Return better error codes.
-       (gcry_pk_verify): Return better error codes.
-
-2003-01-21  Werner Koch  <wk@gnupg.org>
-
-       * random.c (gcry_random_add_bytes): Add QUALITY argument, let
-       function return an error code and disable its core for now.
-
-2003-01-21  Timo Schulz  <twoaday@freakmail.de>
-
-       * random.c (gcry_random_add_bytes): New. Function to add external
-       random to the pool.
-       
-2003-01-20  Simon Josefsson  <jas@extundo.com>
-
-       * crc.c: New.
-       * Makefile.am (EXTRA_PROGRAMS, EXTRA_crc_SOURCES): Add crc.c.
-       * md.c (gcry_md_get_algo_dlen): Add values for CRC.
-
-2003-01-20  Werner Koch  <wk@gnupg.org>
-
-       * sha256.c: New.
-       * bithelp.h (ror): New.
-       * Makfile.am: Add sha256.c.
-       * md.c (oid_table): Add values for SHA256 et al.
-       (gcry_md_get_algo_dlen): Likewise
-
-2003-01-20  Werner Koch  <wk@gnupg.org>
-
-       * pubkey.c (gcry_pk_get_keygrip): Implemented keygrips for DSA
-       and ElGamal.
-
-2003-01-17  Werner Koch  <wk@gnupg.org>
-
-       * cipher.c (gcry_cipher_encrypt): Reworked so that the output will
-       never contain the plaintext even if the caller did not checked the
-       return value.
-
-       * md.c (gcry_md_get_algo): Changed error code to GCRYERR_GENERAL
-       because we don't have an invalid md algo but no algorithm enabled.
-
-       * pubkey.c (gcry_pk_genkey): Changed error code for bounds check
-       of table parameters to GCRYERR_INTERNAL.
-
-       * md.c (gcry_md_open): Partly reverted Timo's change from
-       2002-10-10 by removing the check for the algorithm.  An algorithm
-       of 0 is allowed and anyway we should not double check it or check
-       it using a different function.  Also fixed the flags check.
-
-       * pubkey.c (gcry_pk_encrypt): Make sure that R_CIPH points to NULL
-       on error.
-       (gcry_pk_decrypt): Ditto for R_PLAIN.
-       (gcry_pk_sign): Ditto for R_SIG.
-       (gcry_pk_genkey): Ditto for R_KEY.
-
-2003-01-16  Werner Koch  <wk@gnupg.org>
-
-       * md.c (gcry_md_write): Changed 2nd argument type to void*.
-       (gcry_md_hash_buffer): Changed type of boths buffers to void*.
-       (gcry_md_setkey): Changed 2nd argument type to void*.
-
-2003-01-15  Werner Koch  <wk@gnupg.org>
-
-       * pubkey.c (sexp_data_to_mpi): New.  This handles pkcs1 padding.
-       (gcry_pk_sign, gcry_pk_verify): Use it here.
-       (gcry_pk_encrypt): And here.
-       (pubkey_verify): Add debug code.
-       (sexp_to_enc): Handle flags in the input and return the pkcs1 flag
-       in a new parameter.
-       (gcry_pk_decrypt): Prepare for future pkcs1 handling.
-
-2002-12-19  Werner Koch  <wk@gnupg.org>
-
-       * random.c (_gcry_random_initialize): New.
-
-2002-12-16  Werner Koch  <wk@gnupg.org>
-
-       * cipher.c: Added a Teletrust specific OID for 3DES.
-
-2002-12-12  Werner Koch  <wk@gnupg.org>
-
-       * md.c: Added another oddball OIW OID (sha-1WithRSAEncryption).
-
-2002-11-23  Werner Koch  <wk@gnupg.org>
-
-       * md.c (load_digest_module): Enlarged checked_algos bitmap.
-       * md4.c (func_table):  Fixed entry for md4. 
-       Both by Simon Josephson.
-       (transform): Copy data to get the alignment straight. Tested only
-       on i386.
-
-2002-11-10  Simon Josefsson  <jas@extundo.com>
-
-       * cipher.c (gcry_cipher_open): Don't reject CTS flag.
-       (do_cbc_encrypt, do_cbc_decrypt, cipher_encrypt) 
-       (gcry_cipher_encrypt, cipher_decrypt)
-       (gcry_cipher_decrypt): Support CTS flag.
-       (gcry_cipher_ctl): Toggle CTS flag.
-
-2002-11-10  Werner Koch  <wk@gnupg.org>
-
-       * md4.c: New. By Simon Josefsson.
-       * Makefile.am (EXTRA_PROGRAMS): Add md4.c. 
-       * md.c (oid_table,gcry_md_get_algo_dlen): MD4 support. 
-
-2002-10-14  Werner Koch  <wk@gnupg.org>
-
-       * arcfour.c (do_encrypt_stream): Don't use increment op when
-       assigning to the same variable.
-
-2002-10-10  Timo Schulz  <ts@winpt.org>
-
-       * pubkey.c (gcry_pk_genkey): Check boundaries.
-       
-       * md.c (gcry_md_open): Check that algo is available and only
-       valid flag values are used.
-       (gcry_md_get_algo): Add error handling.
-       
-2002-09-26  Werner Koch  <wk@gnupg.org>
-
-       * md.c: Include an OID for TIGER.
-       * tiger.c (tiger_get_info): Use a regular OID.
-
-2002-09-17  Werner Koch  <wk@gnupg.org>
-
-       * random.c: Replaced mutex.h by the new ath.h.  Changed all calls.
-
-2002-09-16  Werner Koch  <wk@gnupg.org>
-
-       * arcfour.c (do_encrypt_stream): Use register modifier and modulo.
-       According to Nikos Mavroyanopoulos this increases perfromace on
-       i386 system noticable.  And I always tought gcc is clever enough.
-       * md5.c (transform): Use register modifier.
-       * rmd160.c (transform): Ditto.
-       * sha1.c (transform): Ditto.  We hope that there are 6 free registers.
-       * random.c (gcry_randomize): Rewrote to avoid malloc calls.
-
-       * rndlinux.c (gather_random): Replaced remaining fprintfs by log_*.
-       * arcfour.c (do_arcfour_setkey): Ditto.
-       * twofish.c (do_twofish_setkey): Ditto.
-       * rndegd.c (gather_random): Ditto.
-       * rijndael.c (do_setkey): Ditto.
-       * random.c (_gcry_random_dump_stats): Ditto. 
-       * primegen.c (_gcry_generate_elg_prime): Ditto.
-       * des.c (_gcry_des_get_info): Ditto.
-       * cast5.c (do_cast_setkey): Ditto.
-       * blowfish.c (do_bf_setkey): Ditto.
-
-2002-08-26  Werner Koch  <wk@gnupg.org>
-
-       * des.c (weak_keys): Fixed one entry in the table and compared
-       all entries against the literature.
-       (selftest): Checksum the weak key table.
-
-2002-08-21  Werner Koch  <wk@gnupg.org>
-
-       * pubkey.c: Enable keygrip calculation for "openpgp-rsa".
-
-2002-08-17  Werner Koch  <wk@gnupg.org>
-
-       * cipher.c (setup_cipher_table): Don't overwrite the DES entry
-       with the entry for DUMMY.
-
-2002-08-14  Werner Koch  <wk@gnupg.org>
-
-       * des.c (do_des_setkey,do_des_encrypt, do_des_decrypt): New.
-       (_gcry_des_get_info): Support plain old DES.
-       * cipher.c (setup_cipher_table): Put DES into the table.
-
-2002-07-25  Werner Koch  <wk@gnupg.org>
-
-       * rndunix.c (_gcry_rndunix_constructor): Prefixed with _gcry_.
-       Noted by Stephan Austermuehle.
-
-2002-07-08  Timo Schulz  <ts@winpt.org>
-
-       * rndw32.c: Replaced the m_ memory functions with the real 
-       gcry_ functions. Renamed all g10_ prefixed functions to log_.
-       
-2002-06-12  Werner Koch  <wk@gnupg.org>
-
-       * rsa.c (generate): Use e = 65537 for now.
-
-2002-06-11  Werner Koch  <wk@gnupg.org>
-
-       * pubkey.c (gcry_pk_get_keygrip): Allow a "protected-private-key".
-
-2002-06-05  Timo Schulz  <ts@winpt.org>
-
-       * cipher.c (gcry_cipher_encrypt, gcry_cipher_decrypt):
-       Check that the input size is a multiple of the blocksize.
-       
-2002-05-23  Werner Koch  <wk@gnupg.org>
-
-       * md.c (oid_table): Add an rsadsi OID for MD5.
-
-2002-05-21  Werner Koch  <wk@gnupg.org>
-
-       * primegen.c, elgamal.c, dsa.c (progress): Do not print anything
-       by default.  Pass an extra identifying string to the callback and
-       reserved 2 argumenst for current and total counters.  Changed the
-       register function prototype.
-
-2002-05-17  Werner Koch  <wk@gnupg.org>
-
-       * rndegd.c (rndegd_constructor): Fixed name of register function
-       and prefixed the function name with _gcry_.
-       * rndw32.c (rndw32_constructor): Ditto.
-       * tiger.c (tiger_constructor): Ditto.
-
-       * Makefile.am: Removed all dynamic loading stuff.
-       * dynload.c: Ditto. Now only used for the constructor system.
-
-2002-05-15  Werner Koch  <wk@gnupg.org>
-
-       * random.c (gcry_random_bytes,gcry_random_bytes_secure)
-       (gcry_randomize): Make sure we are initialized.
-
-2002-05-14  Werner Koch  <wk@gnupg.org>
-
-       Changed license of most files to the LGPL.
-
-2002-05-02  Werner Koch  <wk@gnupg.org>
-
-       * random.c (_gcry_fast_random_poll): Initialize the module so the
-       mutex can be used.
-
-       * primegen.c (small_prime_numbers): Moved table from smallprime.c
-       * smallprime.c: File removed.
-
-       * des.c (leftkey_swap, rightkey_swap, working_memcmp): Made static.
-
-       * cipher.c (gcry_cipher_map_name): Map "RIJNDAEL" to "AES".
-       * rijndael.c (rijndael_get_info): We do only support a 128 bit
-       blocksize so it makes sense to change the algorithm strings to
-       AES.
-
-       * tiger.c (tiger_final): Removed superfluous token pasting operators.
-       * md5.c (md5_final): Ditto.
-
-2002-04-30  Werner Koch  <wk@gnupg.org>
-
-       * cipher.c: Fixed list of copyright years.
-
-2002-03-18  Werner Koch  <wk@gnupg.org>
-
-       * random.c (initialize): Initialize the new pool lock mutex.
-       (_gcry_fast_random_poll): Add locking and moved main
-       code out to...
-       (do_fast_random_poll): new function.
-       (read_pool): Use the new function here.
-       (get_random_bytes): Add locking.
-       (_gcry_update_random_seed_file): Ditto.
-
-2002-03-11  Werner Koch  <wk@gnupg.org>
-
-       * md.c: Add rsaSignatureWithripemd160 to OID table.
-
-2002-02-20  Werner Koch  <wk@gnupg.org>
-
-       * sha1.c: Removed a left over comment note.  The code has been
-       rewritten from scratch in 1998.  Thanks to Niels Möller for
-       reporting this misleading comment.
-
-2002-02-18  Werner Koch  <wk@gnupg.org>
-
-       * rndunix.c (rndunix_constructor): Use the the new prefixed
-       function name.  Reported by Jordi Mallach.
-
-2002-02-10  Werner Koch  <wk@gnupg.org>
-
-       * random.c (mix_pool): Carry an extra failsafe_digest buffer
-       around to make the function more robust.
-
-2002-02-08  Werner Koch  <wk@gnupg.org>
-
-       * random.c (add_randomness): Xor new data into the pool and not
-       just copy it.  This avoids any choosen input attacks which are not
-       serious in our setting because an outsider won't be able to mix
-       data in and even then we keep going with a PRNG.  Thanks to Stefan
-       Keller for pointing this out.
-
-2002-01-04  Werner Koch  <wk@gnupg.org>
-
-       * pubkey.c (gcry_pk_genkey): Do not release skey - it is static.
-
-       * primegen.c (gen_prime): Of course we should use set_bit
-       and not set_highbit to set the second high bit.
-
-2001-12-18  Werner Koch  <wk@gnupg.org>
-
-       * rsa.c (generate): Loop until we find the exact modulus size.
-       Changed the exponent to 41.
-       (rsa_get_info): s/usage/r_usage/ to avoid shadow warnings.
-       * primegen.c (gen_prime): Set 2 high order bits for secret primes.
-
-       * Makefile.am (DISTCLEANFILES): Include construct.c.
-
-2001-12-17  Werner Koch  <wk@gnupg.org>
-
-       * pubkey.c (gcry_pk_get_keygrip): New - experimental.
-
-2001-12-11  Werner Koch  <wk@gnupg.org>
-
-       * cipher.c: Added OIDs for AES.
-       (gcry_cipher_mode_from_oid): New.
-       (gcry_cipher_map_name): Moved OID search code to ..
-       (search_oid): .. new function.
-
-2001-12-10  Werner Koch  <wk@gnupg.org>
-
-       * pubkey.c (gcry_pk_encrypt): Find the signature algorithm by name
-       and not by number.
-       
-       * pubkey.c (gcry_pk_encrypt,gcry_pk_decrypt,gcry_pk_sign)
-       (gcry_pk_verify,gcry_pk_testkey, gcry_pk_genkey)
-       (gcry_pk_get_nbits): Release the arrays.  Noted by Nikos
-       Mavroyanopoulos.
-
-2001-12-06  Werner Koch  <wk@gnupg.org>
-
-       * cipher.c (gcry_cipher_map_name): Look also for OIDs prefixed
-       with "oid."  or "OID.".
-
-2001-12-05  Werner Koch  <wk@gnupg.org>
-
-       * pubkey.c (algo_info_table): Fixed entry for openpgp-rsa. 
-
-2001-11-24  Werner Koch  <wk@gnupg.org>
-
-       * pubkey.c: Added the rsaEncryption OID to the tables.
-       (sexp_to_key): Add an arg to return the index of the algorithm,
-       changed all callers.
-       (gcry_pk_sign): Find the signature algorithm by name and not by
-       number.
-       (gcry_pk_get_nbits): Fixed so that we can now really pass a secret
-       key to get the result.
-       
-       * md.c (gcry_md_map_name): Look also for OIDs prefixed with "oid."
-       or "OID." so that an OID string can be used as an S-Exp token.
-
-2001-11-20  Werner Koch  <wk@gnupg.org>
-
-       * md.c (gcry_md_map_name): Lookup by OID if the the name begins
-       with a digit.
-       (oid_table): New.
-       
-2001-11-16  Werner Koch  <wk@gnupg.org>
-
-       * md.c (gcry_md_info): New operator GCRYCTL_IS_ALGO_ENABLED.
-
-2001-11-07  Werner Koch  <wk@gnupg.org>
-
-       * md.c (gcry_md_hash_buffer): Close the handle which was left open
-       for algorithms other than rmd160.
-
-2001-08-08  Werner Koch  <wk@gnupg.org>
-
-       * rndw32.c (gather_random): Use toolhelp in addition to the NT
-       gatherer for Windows2000.  Suggested by Sami Tolvanen.
-
-       * random.c (read_pool): Fixed length check, this used to be one
-       byte to strict.  Made an assert out of it because the caller has
-       already made sure that only poolsize bytes are requested.
-       Reported by Marcus Brinkmann.
-
-2001-08-03  Werner Koch  <wk@gnupg.org>
-
-       * cipher.c (cipher_encrypt, cipher_decrypt): Prepare to return
-       errors. We have to change the interface to all ciphers to make
-       this really work but we should do so to prepare for hardware
-       encryption modules.
-       (gcry_cipher_encrypt, gcry_cipher_decrypt): Return the error and
-       set lasterr. 
-       (gcry_cipher_ctl): Make sure that errors from setkey are returned.
-
-2001-08-02  Werner Koch  <wk@gnupg.org>
-
-       * rndlinux.c (gather_random): casted a size_t arg to int so that
-       the format string is correct.  Casting is okay here and avoids
-       translation changes. 
-
-       * random.c (fast_random_poll): Do not check the return code of
-       getrusage.
-
-       * rndunix.c: Add a signal.h header to avoid warnings on Solaris 7
-       and 8.
-
-       * tiger.c (print_abc,print_data): Removed.
-
-       * rijndael.c, des.c, blowfish.c, twofish.c, cast5.c, arcfour.c
-       (burn_stack): New.  Add wrappers for most functions to be able to
-       call burn_stack after the function invocation. This methods seems
-       to be the most portable way to zeroise the stack used. It does
-       only work on stack frame based machines but it is highly portable
-       and has no side effects.  Just setting the automatic variables at
-       the end of a function to zero does not work well because the
-       compiler will optimize them away - marking them as volatile would
-       be bad for performance.
-       * md5.c, sha1.c, rmd160.c, tiger.c (burn_stack): Likewise.
-       * random.c (burn_stack): New.
-       (mix_pool): Use it here to burn the stack of the mixblock function.
-
-       * primegen.c (_gcry_generate_elg_prime): Freed q at 3 places.
-       Thanks to Tommi Komulainen.
-
-       * arcfour.c (arcfour_setkey): Check the minimim keylength against
-       bytes and not bits.
-       (selftest): Must reset the key before decryption. 
-
-2001-05-31  Werner Koch  <wk@gnupg.org>
-
-       * sha1.c (sha1_init): Made static.
-
-        Changed all g10_ prefixed function names as well as some mpi_
-       function names to cope with the introduced naming changes.
-       
-       * md.c (prepare_macpads): Made key const.
-
-2001-05-28  Werner Koch  <wk@gnupg.org>
-
-       * rndegd.c (gather_random): Removed the use of tty_printf.
-
-2001-03-29  Werner Koch  <wk@gnupg.org>
-
-       * md5.c (md5_final): Fixed calculation of hashed length.  Thanks
-       to disastry@saiknes.lv for pointing out that it was horrible wrong
-       for more than 512MB of input.
-       * sha1.c (sha1_final): Ditto.
-       * rmd160.c (rmd160_final): Ditto.
-       * tiger.c (tiger_final): Ditto.
-
-       * blowfish.c (encrypt,do_encrypt): Changed name to do_encrypt to
-       avoid name clashes with an encrypt function in stdlib.h of
-       Dynix/PIX.  Thanks to Gene Carter.
-       * elgamal.c (encrypt,do_encrypt): Ditto.
-
-       * twofish.c (gnupgext_enum_func): Use only when when compiled as a
-       module.
-       * rijndael.c (gnupgext_enum_func): Ditto.
-
-       * tiger.c (tiger_get_info): Return "TIGER192" and not just
-       "TIGER".  By Edwin Woudt.
-       
-       * random.c: Always include time.h - standard requirement.  Thanks
-       to James Troup.
-
-       * rndw32.c: Fixes to the macros.
-
-2001-01-11  Werner Koch  <wk@gnupg.org>
-
-       * cipher.c (cipher_encrypt,gcry_cipher_encrypt): Use blocksize and
-       not 8.
-
-2000-12-19  Werner Koch  <wk@gnupg.org>
-
-       Major change:
-       Removed all GnuPG stuff and renamed this piece of software
-       to gcrypt. 
-
-2000-11-14  Werner Koch  <wk@gnupg.org>
-
-       * dsa.c (test_keys): Replaced mpi_alloc by gcry_mpi_new and
-       mpi_free by gcry_mpi_release.
-       * elgamal.c (test_keys,generate): Ditto, also for mpi_alloc_secure.
-       * rsa.c (test_keys,generate,rsa_verify): Ditto.
-       * primegen.c (generate_elg_prime): Ditto.
-       (gen_prime): Ditto and removed nlimbs.
-
-       * rsa.c (generate): Allocate 2 more vars in secure memory.
-
-       * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency
-       problems.
-
-2000-10-09  Werner Koch  <wk@gnupg.org>
-
-       * arcfour.c, arcfour.h: New.
-       * cipher.c (cipher_encrypt, cipher_decrypt): Add stream mode.
-       (setup_cipher_table): Add Arcfour.
-       (gcry_cipher_open): Kludge to allow stream mode.
-
-Wed Oct  4 13:16:18 CEST 2000  Werner Koch  <wk@openit.de>
-
-        * sha1.c (transform): Use rol() macro.  Actually this is not needed
-        for a newer gcc but there are still aoter compilers.
-
-        * rsa.c (test_keys): Use new random function. 
-
-        * md.c (gcry_md_setkey): New function to overcome problems with
-        const conflics.  
-        (gcry_md_ctl): Pass set key to the new functions.
-
-        * rijndael.c: New.
-        * cipher.c: Add Rijndael support.
-
-Mon Sep 18 16:35:45 CEST 2000  Werner Koch  <wk@openit.de>
-
-        * rndlinux.c (open_device): Loose random device checking.
-        By Nils Ellmenreich.
-
-        * random.c (fast_random_poll): Check ENOSYS for getrusage.
-        * rndunix.c:  Add 2 sources for QNX. By Sam Roberts.
-
-        * pubkey.c (gcry_pk_algo_info): Add GCRYCTL_GET_ALGO_USAGE.
-
-        * rsa.c: Changed the comment about the patent.
-        (secret): Speed up by using the CRT.  For a 2k keys this
-        is about 3 times faster.
-        (stronger_key_check): New but unused code to check the secret key.
-        * Makefile.am: Included rsa.[ch].
-        * pubkey.c: Enabled RSA support.
-        (pubkey_get_npkey): Removed RSA workaround.
-
-Mon Jul 31 10:04:47 CEST 2000  Werner Koch  <wk@openit.de>
-
-  * pubkey.c: Replaced all gcry_sexp_{car,cdr}_{data,mpi} by the new
-  gcry_sexp_nth_{data,mpi} functions.
-
-Tue Jul 25 17:44:15 CEST 2000  Werner Koch  <wk@openit.de>
-
-  * pubkey.c (exp_to_key,sexp_to_sig,sexp_to_enc,gcry_pk_encrypt,
-    gcry_pk_decrypt,gcry_pk_sign,gcry_pk_genkey): Changed to work with
-    the new S-Exp interface.
-
-Mon Jul 17 16:35:47 CEST 2000  Werner Koch  <wk@>
-
-  * random.c (gather_faked): Replaced make_timestamp by time(2) again.
-
-Fri Jul 14 19:38:23 CEST 2000  Werner Koch  <wk@>
-
-  * md.c (gcry_md_ctl): Support GCRYCTL_{START,STOP}_DUMP.
-
-  * Makefile.am: Never compile mingw32 as module.
-
-  * Makefile.am: Tweaked module build and removed libtool
-
-  * Makefile.am:  Replaced -O1 by -O. Suggested by Alec Habig.
-
-  * elgamal.c (sign): Removed inactive code.
-
-  * rsa.c, rsa.h: New based on the old module version (only in CVS for now).
-  * pubkey.c (setup_pubkey_table): Added commented support for RSA.
-
-  * rndunix.c (waitpid): New. For UTS 2.1.  All by Dave Dykstra.
-  (my_popen): Do the FD_CLOEXEC only if it is available
-  (start_gatherer): Cope with missing _SC_OPEN_MAX
-
-  * rndunix.c: Add some more headers for QNX. By Sam Roberts.
-
-  * rndegd.c (gather_random): Shortcut level 0.
-  * rndunix.c (gather_random): Ditto.
-  * rndw32.c (gather_random): Ditto.
-
-  * rndw32.c: Replaced with code from Cryptlib and commented the old stuff.
-  * rndw32.c: Add some debuging code enabled by an environment variable.
-
-  * random.c (read_seed_file): Binary open for DOSish system
-  (update_random_seed_file): Ditto.
-  * random.c [MINGW32]: Include process.h for getpid.
-  * random.c (fast_random_poll): Add clock_gettime() as fallback for
-  system which support this POSIX.4 fucntion. By Sam Roberts.
-
-  * random.c (read_seed_file): Removed the S_ISLNK test becuase it
-  is already covered by !S_ISREG and is not defined in Unixware.
-  Reported by Dave Dykstra.
-  (update_random_seed_file): Silently ignore update request when pool
-  is not filled.
-
-  * random.c (read_seed_file): New.
-  (set_random_seed_file): New.
-  (read_pool): Try to read the seeding file.
-  (update_random_seed_file): New.
-
-  (read_pool): Do an initial extra seeding when level 2 quality random
-  is requested the first time. This requestes at least POOLSIZE/2 bytes
-  of entropy.  Compined with the seeding file this should make normal
-  random bytes cheaper and increase the quality of the random bytes
-  used for key generation.
-
-  * random.c (read_pool): Print a more friendly error message in
-  cases when too much random is requested in one call.
-
-  * random.c (fast_random_poll): Check whether RUSAGE_SELF is defined;
-  this is not the case for some ESIX and Unixware, although they have
-  getrusage().
-
-  * primegen.c (generate_elg_prime): All primes are now generated with
-  the lowest random quality level.  Because they are public anyway we
-  don't need stronger random and by this we do not drain the systems
-  entropy so much.
-
-  * primegen.c (register_primegen_progress): New.
-  * dsa.c (register_pk_dsa_progress): New.
-  * elgamal.c (register_pk_elg_progress): New.
-
-  * elgamal.c (wiener_map): New.
-  (gen_k): Use a much smaller k.
-  (generate): Calculate the qbits using the wiener map and
-  choose an x at a size comparable to the one choosen in gen_k
-
-  * rmd160.c (rmd160_get_info): Moved casting to the left side due to a
-  problem with UTS4.3. Suggested by Dave Dykstra.
-  * sha1.c (sha1_get_info): Ditto.
-  * tiger.c (tiger_get_info): Ditto.
-  * md5.c (md5_get_info): Ditto
-  * des.c (des_get_info): Ditto.
-  * blowfish.c (blowfish_get_info): Ditto.
-  * cast5.c (cast5_get_info): Ditto.
-  * twofish.c (twofish_get_info): Ditto.
-
-Fri Mar 24 11:25:45 CET 2000  Werner Koch  <wk@openit.de>
-
-       * md.c (md_open): Add hmac arg and allocate space for the pads.
-       (md_finalize): Add HMAC support.
-       (md_copy): Ditto.
-       (md_close): Ditto.
-       (gcry_md_reset): Ditto.
-       (gcry_md_ctl): Ditto.
-       (prepare_macpdas): New.
-
-Mon Mar 13 19:22:46 CET 2000  Werner Koch  <wk@openit.de>
-
-       * md.c (gcry_md_hash_buffer): Add support for the other algorithms.
-
-Mon Jan 31 16:37:34 CET 2000  Werner Koch  <wk@gnupg.de>
-
-       * genprime.c (generate_elg_prime): Fixed returned factors which never
-       worked for non-DSA keys.
-
-Thu Jan 27 18:00:44 CET 2000  Werner Koch  <wk@gnupg.de>
-
-       * pubkey.c (sexp_to_key): Fixed mem leaks in case of errors.
-
-Mon Jan 24 22:24:38 CET 2000  Werner Koch  <wk@gnupg.de>
-
-       * pubkey.c (gcry_pk_decrypt): Implemented.
-       (gcry_pk_encrypt): Implemented.
-       (gcry_pk_testkey): New.
-       (gcry_pk_genkey): New.
-       (pubkey_decrypt): Made static.
-       (pubkey_encrypt): Ditto.
-       (pubkey_check_secret_key): Ditto.
-       (pubkey_generate): Ditto.
-
-Mon Jan 24 13:04:28 CET 2000  Werner Koch  <wk@gnupg.de>
-
-       * pubkey.c (pubkey_nbits): Removed and replaced by ...
-       (gcry_pk_get_nbits): this new one.
-
-Wed Dec  8 21:58:32 CET 1999  Werner Koch  <wk@gnupg.de>
-
-       * dsa.c: s/mpi_powm/gcry_mpi_powm/g
-       * elgamal.c: Ditto.
-       * primegen.c: Ditto.
-
-       * : Replaced g10_opt_verbose by g10_log_verbosity().
-
-       * Makefile.am (INCLUDES): removed intl, add ../gcrypt
-
-Fri Nov 19 17:15:20 CET 1999  Werner Koch  <wk@gnupg.de>
-
-       * dynload.c (cmp_filenames): New to replaced compare_filename() in
-       module.
-       (register_cipher_extension): Removed the tilde expansion stuff.
-       * rndeg.c (my_make_filename): New.
-
-       * : Replaced header util.h by g10lib.h
-
-       * random.c (gather_faked): Replaced make_timestamp by time(2).
-       Disabled wrning printed with tty_printf.
-       * rndlinux.c (gather_random): Always use fprintf instead of tty_xxx;
-       this should be replaced by a callback function.
-
-       * primegen.c (gen_prime): Use gcry_mpi_randomize.
-       (is_prime): Ditto.
-       * elgamal.c (test_keys): Ditto.
-       * dsa.c (test_keys): Ditto.
-
-       * cipher.c (gcry_cipher_close): Die on invalid handle.
-
-Mon Nov 15 21:36:02 CET 1999  Werner Koch  <wk@gnupg.de>
-
-       * elgamal.c (gen_k): Use the new random API.
-       (generate): Ditto.
-       * dsa.c (gen_k): Ditto.
-       (generate): Ditto.
-
-Sat Nov 13 17:44:23 CET 1999  Werner Koch  <wk@gnupg.de>
-
-       * pubkey.c (disable_pubkey_algo): Made static.
-       (gcry_pk_ctl): New.
-
-       * random.c (get_random_bits): Renamed to ...
-       (get_random_bytes): ... this and made static.
-       (gcry_random_bytes): New.
-       (gcry_random_bytes_secure): New.
-       (randomize_buffer): Renamed to ...
-       (gcry_randomize): ...this.
-
-       * md.c (gcry_md_hash_buffer): New.
-
-       * pubkey.c (gcry_pk_algo_info): 4 new commands.
-       (pubkey_get_npkey): Made static.
-       (pubkey_get_nskey): Made static.
-       (pubkey_get_nsig): Made static.
-       (pubkey_get_nenc): Made static.
-
-       * pubkey.c: Removed all G10ERR_xxx.
-       * cipher.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_CIPHER_ALGO.
-       * md.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_MD_ALGO.
-       * cast5.c (cast_setkey): Changed errocodes to GCRYERR_xxx.
-       * blowfish.c: Ditto.
-       * des.c: Ditto.
-       * twofish.c: Ditto.
-       * dsa.c: Ditto.
-       * elgamal.c: Ditto.
-
-       * g10c.c: Removed
-
-       * cipher.c (gcry_cipher_open): Replaced alloc functions and return NULL
-       if we are out of core.
-       * dynload.c: Replaced all memory allocation functions.
-       * md.c: Ditto.
-       * primegen.c: Ditto.
-       * pubkey.c: Ditto.
-       * random.c: Ditto.
-       * rndw32.c: Ditto.
-       * elgamal.c: Ditto.
-       * dsa.c: Ditto.
-
-Tue Oct 26 14:10:21 CEST 1999  Werner Koch  <wk@gnupg.de>
-
-       * elgamal.c (sign): Hugh found strange code here. Replaced by BUG().
-
-       * cipher.c: Merged with gcrypt/symapi.c.
-
-       * pubkey.c (string_to_pubkey_algo): Renamed function to ...
-       (gcry_pk_map_name): ... this.
-       (pubkey_algo_to_string): Renamed function to ...
-       (gcry_pk_algo_name): ... this.
-       (gcry_pk_algo_info): New.
-       * pubkey.c: Merged with gcrypt/pkapi.c.
-
-       * md.c (md_reset): Clear finalized; thanks to Ulf Moeller for
-       fixing this bug.
-
-       * md.c: Merged with gcrypt/mdapi.c
-
-Wed Sep 15 14:39:59 CEST 1999  Michael Roth <mroth@nessie.de>
-
-       * des.c: Various speed improvements: One bit pre rotation
-         trick after initial permutation (Richard Outerbridge).
-         Finished test of SSLeay Tripple-DES patterns.
-
-Wed Sep 15 16:22:17 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * rndw32.c: New.
-
-Mon Sep 13 10:51:29 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * bithelp.h: New.
-       * rmd160.h, sha1.h, md5.h: Use the rol macro from bithelp.h
-
-Tue Sep  7 16:23:36 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * Makefile.am: Fixed seds for latest egcc. By Ollivier Robert.
-
-Mon Sep  6 19:59:08 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * des.c (selftest): Add some testpattern
-
-Mon Aug 30 20:38:33 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * cipher.c (do_cbc_encrypt): Fixed serious bug occuring when not using
-       in place encryption. Pointed out by Frank Stajano.
-
-Mon Jul 26 09:34:46 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * md5.c (md5_final): Fix for a SCO cpp bug.
-
-Thu Jul 15 10:15:35 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * elgamal.c (elg_check_secret_key,elg_encrypt
-       elg_decrypt,elg_sign,elg_verify): Sanity check on the args.
-       * dsa.c (dsa_check_secret_key,dsa_sign,dsa_verify): Ditto.
-
-       * pubkey.c (disable_pubkey_algo): New.
-       (check_pubkey_algo2): Look at disabled algo table.
-       * cipher.c (disable_cipher_algo): New.
-       (check_cipher_algo): Look at disabled algo table.
-
-Wed Jul  7 13:08:40 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * Makefile.am: Support for libtool.
-
-Fri Jul  2 11:45:54 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * dsa.c (gen_k): Changed algorithm to consume less random bytes
-       * elgamal.c (gen_k): Ditto.
-
-       * random.c (random_dump_stats): New.
-
-Thu Jul  1 12:47:31 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * primegen.c, elgamal.c, dsa.c (progess): New and replaced all
-       fputc with a call to this function.
-
-Sat Jun 26 12:15:59 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * rndegd.c (do_write): s/ssize_t/int/ due to SunOS 4.1 probs.
-
-       * cipher.c (do_cbc_encrypt, do_cbc_decrypt): New.
-
-       * dynload.c (HAVE_DL_SHL_LOAD): Map hpux API to dlopen (Dave Dykstra).
-       * Makefile.am (install-exec-hook): Removed.
-
-Sun May 23 14:20:22 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * cipher.c (setup_cipher_table): Enable Twofish
-
-       * random.c (fast_random_poll): Disable use of times() for mingw32.
-
-Mon May 17 21:54:43 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * dynload.c (register_internal_cipher_extension): Minor init fix.
-
-Tue May  4 15:47:53 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * primegen.c (gen_prime): Readded the Fermat test. Fixed the bug
-       that we didn't correct for step when passing the prime to the
-       Rabin-Miller test which led to bad performance (Stefan Keller).
-       (check_prime): Add a first Fermat test.
-
-Sun Apr 18 10:11:28 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * cipher.c (cipher_setiv): Add ivlen arg, changed all callers.
-
-       * random.c (randomize_buffer): alway use secure memory because
-       we can't use m_is_secure() on a statically allocated buffer.
-
-       * twofish.c: Replaced some macros by a loop to reduce text size.
-       * Makefile.am (twofish): No more need for sed editing.
-
-Fri Apr  9 12:26:25 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * cipher.c (cipher_open): Reversed the changes for AUTO_CFB.
-
-       * blowfish.c: Dropped the Blowfish 160 mode.
-       * cipher.c (cipher_open): Ditto.
-       (setup_cipher_table): Ditto.  And removed support of twofish128
-
-Wed Apr  7 20:51:39 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * random.c (get_random_bits): Can now handle requests > POOLSIZE
-
-       * cipher.c (cipher_open): Now uses standard CFB for automode if
-       the blocksize is gt 8 (according to rfc2440).
-
-       * twofish.c: Applied Matthew Skala's patches for 256 bit key.
-
-Tue Apr  6 19:58:12 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * random.c (get_random_bits): Can now handle requests > POOLSIZE
-
-       * cipher.c (cipher_open): Now uses standard CFB for automode if
-       the blocksize is gt 8 (according to rfc2440).
-
-Sat Mar 20 11:44:21 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * rndlinux.c (tty_printf) [IS_MODULE]: Removed.
-
-       * rndegd.c (gather_random): Some fixes.
-
-Wed Mar 17 13:09:03 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * rndegd.c (do_read): New.
-       (gather_random): Changed the implementation.
-
-Mon Mar  8 20:47:17 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * dynload.c (DLSYM_NEEDS_UNDERSCORE): Renamed.
-
-Fri Feb 26 17:55:41 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * md.c: Nearly a total rewrote.
-
-Wed Feb 24 11:07:27 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * cipher.c (context): Fixed alignment
-       * md.c: Ditto.
-
-       * rndegd.c: New
-
-Mon Feb 22 20:04:00 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * rndegd.c: New.
-
-Wed Feb 10 17:15:39 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * Makefile.am: Modules are now figured out by configure
-       * construct.c: New. Generated by configure. Changed all modules
-       to work with that.
-       * sha1.h: Removed.
-       * md5.h: Removed.
-
-       * twofish.c: Changed interface to allow Twofish/256
-
-       * rndunix.c (start_gatherer): Die on SIGPIPE.
-
-Wed Jan 20 18:59:49 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * rndunix.c (gather_random): Fix to avoid infinite loop.
-
-Sun Jan 17 11:04:33 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * des.c (is_weak_key): Replace system memcmp due to bugs
-       in SunOS's memcmp.
-       (des_get_info): Return error on failed selftest.
-       * twofish.c (twofish_setkey): Return error on failed selftest or
-       invalid keylength.
-       * cast5.c (cast_setkey): Ditto.
-       * blowfish.c (bf_setkey): Return error on failed selftest.
-
-Tue Jan 12 11:17:18 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * random.c (random_is_faked): New.
-
-       * tiger.c: Only compile if we have the u64 type
-
-Sat Jan  9 16:02:23 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * rndunix.c (gather_random): check for setuid.
-
-       * Makefile.am: Add a way to staically link random modules
-
-Thu Jan  7 18:00:58 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * md.c (md_stop_debug): Do a flush first.
-       (md_open): size of buffer now depends on the secure parameter
-
-Sun Jan  3 15:28:44 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * rndunix.c (start_gatherer): Fixed stupid ==/= bug
-
-1998-12-31  Geoff Keating  <geoffk@ozemail.com.au>
-
-       * des.c (is_weak_key): Rewrite loop end condition.
-
-Tue Dec 29 14:41:47 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * random.c: add unistd.h for getpid().
-       (RAND_MAX): Fallback value for Sun.
-
-Wed Dec 23 17:12:24 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * md.c (md_copy): Reset debug.
-
-Mon Dec 14 21:18:49 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * random.c (read_random_source): Changed the interface to the
-       random gathering function.
-       (gather_faked): Use new interface.
-       * dynload.c (dynload_getfnc_fast_random_poll): Ditto.
-       (dynload_getfnc_gather_random): Ditto.
-       * rndlinux.c (gather_random): Ditto.
-       * rndunix.c (gather_random): Ditto.
-
-Sat Dec 12 18:40:32 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * dynload.c (SYMBOL_VERSION): New to cope with system which needs
-       underscores.
-
-       * rndunix.c: Rewrote large parts
-
-Thu Dec 10 20:15:36 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * dynload.c (load_extension): increased needed verbosity level.
-
-       * random.c (fast_random_poll): Fallback to a default fast random
-       poll function.
-       (read_random_source): Always use the faked entroy gatherer if no
-       gather module is available.
-       * rndlinux.c (fast_poll): Removed.
-       * rndunix.c (fast_poll): Removed.
-
-
-Wed Nov 25 12:33:41 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * rand-*.c: Removed.
-       * rndlinux.c : New.
-       * rndunix.c : New.
-       * random.c : Restructured the interface to the gather modules.
-       (intialize): Call constructor functions
-       (read_radnom_source): Moved to here.
-       * dynload.c (dynload_getfnc_gather_random): New.
-       (dynload_getfnc_fast_random_poll): New.
-       (register_internal_cipher_extension): New.
-       (register_cipher_extension): Support of internal modules.
-
-Sun Nov  8 17:44:36 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * rand-unix.c (read_random_source): Removed the assert.
-
-Mon Oct 19 18:34:30 1998  me,,,  (wk@tobold)
-
-       * pubkey.c: Hack to allow us to give some info about RSA keys back.
-
-Thu Oct 15 11:47:57 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * dynload.c: Support for DLD
-
-Wed Oct 14 12:13:07 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * rand-unix.c: Now uses names from configure for /dev/random.
-
-1998-10-10  SL Baur  <steve@altair.xemacs.org>
-
-       * Makefile.am: fix sed -O substitutions to catch -O6, etc.
-
-Tue Oct  6 10:06:32 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * rand-unix.c (HAVE_GETTIMEOFDAY): Fixed (was ..GETTIMEOFTIME :-)
-       * rand-dummy.c (HAVE_GETTIMEOFDAY): Ditto.
-
-Mon Sep 28 13:23:09 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * md.c (md_digest): New.
-       (md_reset): New.
-
-Wed Sep 23 12:27:02 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * tiger.c (TIGER_CONTEXT): moved "buf", so that it is 64 bit aligned.
-
-Mon Sep 21 06:22:53 1998  Werner Koch  (wk@(none))
-
-       * des.c: Some patches from Michael.
-
-Thu Sep 17 19:00:06 1998  Werner Koch  (wk@(none))
-
-       * des.c : New file from Michael Roth <mroth@nessie.de>
-
-Mon Sep 14 11:10:55 1998  Werner Koch  (wk@(none))
-
-       * blowfish.c (bf_setkey): Niklas Hernaeus patch to detect weak keys.
-
-Mon Sep 14 09:19:25 1998  Werner Koch  (wk@(none))
-
-       * dynload.c (RTLD_NOW): Now defined to 1 if it is undefined.
-
-Mon Sep  7 17:04:33 1998  Werner Koch  (wk@(none))
-
-       * Makefile.am: Fixes to allow a different build directory
-
-Thu Aug  6 17:25:38 1998  Werner Koch,mobil,,, (wk@tobold)
-
-       * random.c (get_random_byte): Removed and changed all callers
-       to use get_random_bits()
-
-Mon Jul 27 10:30:22 1998  Werner Koch  (wk@(none))
-
-       * cipher.c : Support for other blocksizes
-       (cipher_get_blocksize): New.
-       * twofish.c: New.
-       * Makefile.am: Add twofish module.
-
-Mon Jul 13 21:30:52 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * random.c (read_pool): Simple alloc if secure_alloc is not set.
-       (get_random_bits): Ditto.
-
-Thu Jul  9 13:01:14 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * dynload.c (load_extension): Function now nbails out if
-       the program is run setuid.
-
-Wed Jul  8 18:58:23 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * rmd160.c (rmd160_hash_buffer): New.
-
-Thu Jul  2 10:50:30 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * cipher.c (cipher_open): algos >=100 use standard CFB
-
-Thu Jun 25 11:18:25 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * Makefile.am: Support for extensions
-
-Thu Jun 18 12:09:38 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * random.c (mix_pool): simpler handling for level 0
-
-Mon Jun 15 14:40:48 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * tiger.c: Removed from dist, will reappear as dynload module
-
-Sat Jun 13 14:16:57 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * pubkey.c: Major changes to allow extensions. Changed the inteface
-       of all public key ciphers and added the ability to load extensions
-       on demand.
-
-       * misc.c: Removed.
-
-Wed Jun 10 07:52:08 1998  Werner Koch,mobil,,, (wk@tobold)
-
-       * dynload.c: New.
-       * cipher.c: Major changes to allow extensions.
-
-Mon Jun  8 22:43:00 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * cipher.c: Major internal chnages to support extensions.
-       * blowfish.c (blowfish_get_info): New and made all internal
-       functions static, changed heder.
-       * cast5.c (cast5_get_info): Likewise.
-
-Mon Jun  8 12:27:52 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * tiger.c (transform): Fix for big endian
-
-       * cipher.c (do_cfb_decrypt): Big endian fix.
-
-Fri May 22 07:30:39 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * md.c (md_get_oid): Add a new one for TIGER.
-
-Thu May 21 13:24:52 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * cipher.c: Add support for a dummy cipher
-
-Thu May 14 15:40:36 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * rmd160.c (transform): fixed sigbus - I should better
-       add Christian von Roques's new implemenation of rmd160_write.
-
-Fri May  8 18:07:44 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * rand-internal.h, rand-unix.c, rand-w32.c, rand_dummy.c: New
-       * random.c: Moved system specific functions to rand-****.c
-
-Fri May  8 14:01:17 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * random.c (fast_random_poll): add call to gethrtime.
-
-Tue May  5 21:28:55 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * elgamal.c (elg_generate): choosing x was not correct, could
-       yield 6 bytes which are not from the random pool, tsss, tsss..
-
-Tue May  5 14:09:06 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * primegen.c (generate_elg_prime): Add arg mode, changed all
-       callers and implemented mode 1.
-
-Mon Apr 27 14:41:58 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * cipher.c (cipher_get_keylen): New.
-
-Sun Apr 26 14:44:52 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * tiger.c, tiger.h: New.
-
-Wed Apr  8 14:57:11 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * misc.c (check_pubkey_algo2): New.
-
-Tue Apr  7 18:46:49 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * cipher.c: New
-       * misc.c (check_cipher_algo): Moved to cipher.c
-       * cast5.c: Moved many functions to cipher.c
-       * blowfish.c: Likewise.
-
-Sat Apr  4 19:52:08 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * cast5.c: Implemented and tested.
-
-Wed Apr  1 16:38:27 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * elgamal.c (elg_generate): Faster generation of x in some cases.
-
-Thu Mar 19 13:54:48 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * blowfish.c (blowfish_decode_cfb): changed XOR operation
-       (blowfish_encode_cfb): Ditto.
-
-Thu Mar 12 14:04:05 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * sha1.c (transform): Rewrote
-
-       * blowfish.c (encrypt): Unrolled for rounds == 16
-       (decrypt): Ditto.
-
-Tue Mar 10 16:32:08 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * rmd160.c (transform): Unrolled the loop.
-
-Tue Mar 10 13:05:14 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * random.c (read_pool): Add pool_balance stuff.
-       (get_random_bits): New.
-
-       * elgamal.c (elg_generate): Now uses get_random_bits to generate x.
-
-
-Tue Mar 10 11:33:51 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * md.c (md_digest_length): New.
-
-Tue Mar 10 11:27:41 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * dsa.c (dsa_verify): Works.
-
-Mon Mar  9 12:59:08 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * dsa.c, dsa.h: Removed some unused code.
-
-Wed Mar  4 10:39:22 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * md.c (md_open): Add call to fast_random_poll.
-       blowfish.c (blowfish_setkey): Ditto.
-
-Tue Mar  3 13:32:54 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * rmd160.c (rmd160_mixblock): New.
-       * random.c: Restructured to start with a new RNG implementation.
-       * random.h: New.
-
-Mon Mar  2 19:21:46 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * gost.c, gost.h: Removed because they did only contain trash.
-
-Sun Mar  1 16:42:29 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * random.c (fill_buffer): removed error message if n == -1.
-
-Fri Feb 27 16:39:34 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * md.c (md_enable): No init if called twice.
-
-Thu Feb 26 07:57:02 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * primegen.c (generate_elg_prime): Changed the progress printing.
-       (gen_prime): Ditto.
-
-Tue Feb 24 12:28:42 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * md5.c, md.5 : Replaced by a modified version of md5.c from
-       GNU textutils 1.22.
-
-Wed Feb 18 14:08:30 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * md.c, md.h : New debugging support
-
-Mon Feb 16 10:08:47 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * misc.c (cipher_algo_to_string): New
-       (pubkey_algo_to_string): New.
-       (digest_algo_to_string): New.
-
-
- Copyright 1998,1999,2000,2001,2002,2003,2004,2005,2006
-          2007, 2008, 2009 Free Software Foundation, Inc.
-
- This file is free software; as a special exception the author gives
- unlimited permission to copy and/or distribute it, with or without
- modifications, as long as this notice is preserved.
-
- This file is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/lib/libgcrypt/cipher/ac.c b/lib/libgcrypt/cipher/ac.c
deleted file mode 100644 (file)
index ee9498b..0000000
+++ /dev/null
@@ -1,3301 +0,0 @@
-/* ac.c - Alternative interface for asymmetric cryptography.
-   Copyright (C) 2003, 2004, 2005, 2006
-                 2007, 2008  Free Software Foundation, Inc.
-   This file is part of Libgcrypt.
-  
-   Libgcrypt is free software; you can redistribute it and/or modify
-   it under the terms of the GNU Lesser general Public License as
-   published by the Free Software Foundation; either version 2.1 of
-   the License, or (at your option) any later version.
-  
-   Libgcrypt 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 Lesser General Public License for more details.
-  
-   You should have received a copy of the GNU Lesser General Public
-   License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <stddef.h>
-
-#include "g10lib.h"
-#include "cipher.h"
-#include "mpi.h"
-
-\f
-
-/* At the moment the ac interface is a wrapper around the pk
-   interface, but this might change somewhen in the future, depending
-   on how many people prefer the ac interface.  */
-
-/* Mapping of flag numbers to the according strings as it is expected
-   for S-expressions.  */
-static struct number_string
-{
-  int number;
-  const char *string;
-} ac_flags[] =
-  {
-    { GCRY_AC_FLAG_NO_BLINDING, "no-blinding" },
-  };
-
-/* The positions in this list correspond to the values contained in
-   the gcry_ac_key_type_t enumeration list.  */
-static const char *ac_key_identifiers[] =
-  {
-    "private-key",
-    "public-key"
-  };
-
-/* These specifications are needed for key-pair generation; the caller
-   is allowed to pass additional, algorithm-specific `specs' to
-   gcry_ac_key_pair_generate.  This list is used for decoding the
-   provided values according to the selected algorithm.  */
-struct gcry_ac_key_generate_spec
-{
-  int algorithm;               /* Algorithm for which this flag is
-                                  relevant.  */
-  const char *name;            /* Name of this flag.  */
-  size_t offset;               /* Offset in the cipher-specific spec
-                                  structure at which the MPI value
-                                  associated with this flag is to be
-                                  found.  */
-} ac_key_generate_specs[] =
-  {
-    { GCRY_AC_RSA, "rsa-use-e", offsetof (gcry_ac_key_spec_rsa_t, e) },
-    { 0 }
-  };
-
-/* Handle structure.  */
-struct gcry_ac_handle
-{
-  int algorithm;               /* Algorithm ID associated with this
-                                  handle.  */
-  const char *algorithm_name;  /* Name of the algorithm.  */
-  unsigned int flags;          /* Flags, not used yet.  */
-  gcry_module_t module;                /* Reference to the algorithm
-                                  module.  */
-};
-
-/* A named MPI value.  */
-typedef struct gcry_ac_mpi
-{
-  char *name;                  /* Self-maintained copy of name.  */
-  gcry_mpi_t mpi;              /* MPI value.         */
-  unsigned int flags;          /* Flags.             */
-} gcry_ac_mpi_t;
-
-/* A data set, that is simply a list of named MPI values.  */
-struct gcry_ac_data
-{
-  gcry_ac_mpi_t *data;         /* List of named values.      */
-  unsigned int data_n;         /* Number of values in DATA.  */
-};
-
-/* A single key.  */
-struct gcry_ac_key
-{
-  gcry_ac_data_t data;         /* Data in native ac structure.  */
-  gcry_ac_key_type_t type;     /* Type of the key.              */
-};
-
-/* A key pair.  */
-struct gcry_ac_key_pair
-{
-  gcry_ac_key_t public;
-  gcry_ac_key_t secret;
-};
-
-\f
-
-/* 
- * Functions for working with data sets.
- */
-
-/* Creates a new, empty data set and store it in DATA.  */
-gcry_error_t
-_gcry_ac_data_new (gcry_ac_data_t *data)
-{
-  gcry_ac_data_t data_new;
-  gcry_error_t err;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  data_new = gcry_malloc (sizeof (*data_new));
-  if (! data_new)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  data_new->data = NULL;
-  data_new->data_n = 0;
-  *data = data_new;
-  err = 0;
-
- out:
-
-  return err;
-}
-
-/* Destroys all the entries in DATA, but not DATA itself.  */
-static void
-ac_data_values_destroy (gcry_ac_data_t data)
-{
-  unsigned int i;
-  
-  for (i = 0; i < data->data_n; i++)
-    if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
-      {
-       gcry_mpi_release (data->data[i].mpi);
-       gcry_free (data->data[i].name);
-      }
-}
-
-/* Destroys the data set DATA.  */
-void
-_gcry_ac_data_destroy (gcry_ac_data_t data)
-{
-  if (data)
-    {
-      ac_data_values_destroy (data);
-      gcry_free (data->data);
-      gcry_free (data);
-    }
-}
-
-/* This function creates a copy of the array of named MPIs DATA_MPIS,
-   which is of length DATA_MPIS_N; the copy is stored in
-   DATA_MPIS_CP.  */
-static gcry_error_t
-ac_data_mpi_copy (gcry_ac_mpi_t *data_mpis, unsigned int data_mpis_n,
-                 gcry_ac_mpi_t **data_mpis_cp)
-{
-  gcry_ac_mpi_t *data_mpis_new;
-  gcry_error_t err;
-  unsigned int i;
-  gcry_mpi_t mpi;
-  char *label;
-
-  data_mpis_new = gcry_malloc (sizeof (*data_mpis_new) * data_mpis_n);
-  if (! data_mpis_new)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-  memset (data_mpis_new, 0, sizeof (*data_mpis_new) * data_mpis_n);
-
-  err = 0;
-  for (i = 0; i < data_mpis_n; i++)
-    {
-      /* Copy values.  */
-
-      label = gcry_strdup (data_mpis[i].name);
-      mpi = gcry_mpi_copy (data_mpis[i].mpi);
-      if (! (label && mpi))
-       {
-         err = gcry_error_from_errno (errno);
-         gcry_mpi_release (mpi);
-         gcry_free (label);
-         break;
-       }
-
-      data_mpis_new[i].flags = GCRY_AC_FLAG_DEALLOC;
-      data_mpis_new[i].name = label;
-      data_mpis_new[i].mpi = mpi;
-    }
-  if (err)
-    goto out;
-
-  *data_mpis_cp = data_mpis_new;
-  err = 0;
-
- out:
-
-  if (err)
-    if (data_mpis_new)
-      {
-       for (i = 0; i < data_mpis_n; i++)
-         {
-           gcry_mpi_release (data_mpis_new[i].mpi);
-           gcry_free (data_mpis_new[i].name);
-         }
-       gcry_free (data_mpis_new);
-      }
-
-  return err;
-}
-
-/* Create a copy of the data set DATA and store it in DATA_CP.  */
-gcry_error_t
-_gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data)
-{
-  gcry_ac_mpi_t *data_mpis = NULL;
-  gcry_ac_data_t data_new;
-  gcry_error_t err;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  /* Allocate data set.  */
-  data_new = gcry_malloc (sizeof (*data_new));
-  if (! data_new)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  err = ac_data_mpi_copy (data->data, data->data_n, &data_mpis);
-  if (err)
-    goto out;
-  
-  data_new->data_n = data->data_n;
-  data_new->data = data_mpis;
-  *data_cp = data_new;
-
- out:
-
-  if (err)
-    gcry_free (data_new);
-
-  return err;
-}
-
-/* Returns the number of named MPI values inside of the data set
-   DATA.  */
-unsigned int
-_gcry_ac_data_length (gcry_ac_data_t data)
-{
-  return data->data_n;
-}
-
-
-/* Add the value MPI to DATA with the label NAME.  If FLAGS contains
-   GCRY_AC_FLAG_COPY, the data set will contain copies of NAME
-   and MPI.  If FLAGS contains GCRY_AC_FLAG_DEALLOC or
-   GCRY_AC_FLAG_COPY, the values contained in the data set will
-   be deallocated when they are to be removed from the data set.  */
-gcry_error_t
-_gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
-                  const char *name, gcry_mpi_t mpi)
-{
-  gcry_error_t err;
-  gcry_mpi_t mpi_cp;
-  char *name_cp;
-  unsigned int i;
-
-  name_cp = NULL;
-  mpi_cp = NULL;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  if (flags & ~(GCRY_AC_FLAG_DEALLOC | GCRY_AC_FLAG_COPY))
-    {
-      err = gcry_error (GPG_ERR_INV_ARG);
-      goto out;
-    }
-
-  if (flags & GCRY_AC_FLAG_COPY)
-    {
-      /* Create copies.  */
-
-      flags |= GCRY_AC_FLAG_DEALLOC;
-      name_cp = gcry_strdup (name);
-      mpi_cp = gcry_mpi_copy (mpi);
-      if (! (name_cp && mpi_cp))
-       {
-         err = gcry_error_from_errno (errno);
-         goto out;
-       }
-    }
-
-  /* Search for existing entry.  */
-  for (i = 0; i < data->data_n; i++)
-    if (! strcmp (name, data->data[i].name))
-      break;
-  if (i < data->data_n)
-    {
-      /* An entry for NAME does already exist.  */
-      if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
-       {
-         gcry_mpi_release (data->data[i].mpi);
-         gcry_free (data->data[i].name);
-       }
-    }
-  else
-    {
-      /* Create a new entry.  */
-
-      gcry_ac_mpi_t *ac_mpis;
-
-      ac_mpis = gcry_realloc (data->data,
-                             sizeof (*data->data) * (data->data_n + 1));
-      if (! ac_mpis)
-       {
-         err = gcry_error_from_errno (errno);
-         goto out;
-       }
-
-      if (data->data != ac_mpis)
-       data->data = ac_mpis;
-      data->data_n++;
-    }
-
-  data->data[i].name = name_cp ? name_cp : ((char *) name);
-  data->data[i].mpi = mpi_cp ? mpi_cp : mpi;
-  data->data[i].flags = flags;
-  err = 0;
-
- out:
-
-  if (err)
-    {
-      gcry_mpi_release (mpi_cp);
-      gcry_free (name_cp);
-    }
-
-  return err;
-}
-
-/* Stores the value labelled with NAME found in the data set DATA in
-   MPI.  The returned MPI value will be released in case
-   gcry_ac_data_set is used to associate the label NAME with a
-   different MPI value.  */
-gcry_error_t
-_gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
-                       const char *name, gcry_mpi_t *mpi)
-{
-  gcry_mpi_t mpi_return;
-  gcry_error_t err;
-  unsigned int i;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  if (flags & ~(GCRY_AC_FLAG_COPY))
-    {
-      err = gcry_error (GPG_ERR_INV_ARG);
-      goto out;
-    }
-
-  for (i = 0; i < data->data_n; i++)
-    if (! strcmp (name, data->data[i].name))
-      break;
-  if (i == data->data_n)
-    {
-      err = gcry_error (GPG_ERR_NOT_FOUND);
-      goto out;
-    }
-
-  if (flags & GCRY_AC_FLAG_COPY)
-    {
-      mpi_return = gcry_mpi_copy (data->data[i].mpi);
-      if (! mpi_return)
-       {
-         err = gcry_error_from_errno (errno); /* FIXME? */
-         goto out;
-       }
-    }
-  else
-    mpi_return = data->data[i].mpi;
-
-  *mpi = mpi_return;
-  err = 0;
-
- out:
-
-  return err;
-}
-
-/* Stores in NAME and MPI the named MPI value contained in the data
-   set DATA with the index IDX.  NAME or MPI may be NULL.  The
-   returned MPI value will be released in case gcry_ac_data_set is
-   used to associate the label NAME with a different MPI value.  */
-gcry_error_t
-_gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
-                        unsigned int idx,
-                        const char **name, gcry_mpi_t *mpi)
-{
-  gcry_error_t err;
-  gcry_mpi_t mpi_cp;
-  char *name_cp;
-
-  name_cp = NULL;
-  mpi_cp = NULL;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  if (flags & ~(GCRY_AC_FLAG_COPY))
-    {
-      err = gcry_error (GPG_ERR_INV_ARG);
-      goto out;
-    }
-
-  if (idx >= data->data_n)
-    {
-      err = gcry_error (GPG_ERR_INV_ARG);
-      goto out;
-    }
-
-  if (flags & GCRY_AC_FLAG_COPY)
-    {
-      /* Return copies to the user.  */
-      if (name)
-       {
-         name_cp = gcry_strdup (data->data[idx].name);
-         if (! name_cp)
-           {
-             err = gcry_error_from_errno (errno);
-             goto out;
-           }
-       }
-      if (mpi)
-       {
-         mpi_cp = gcry_mpi_copy (data->data[idx].mpi);
-         if (! mpi_cp)
-           {
-             err = gcry_error_from_errno (errno);
-             goto out;
-           }
-       }
-    }
-
-  if (name)
-    *name = name_cp ? name_cp : data->data[idx].name;
-  if (mpi)
-    *mpi = mpi_cp ? mpi_cp : data->data[idx].mpi;
-  err = 0;
-
- out:
-
-  if (err)
-    {
-      gcry_mpi_release (mpi_cp);
-      gcry_free (name_cp);
-    }
-
-  return err;
-}
-
-/* Convert the data set DATA into a new S-Expression, which is to be
-   stored in SEXP, according to the identifiers contained in
-   IDENTIFIERS.  */
-gcry_error_t
-_gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
-                      const char **identifiers)
-{
-  gcry_sexp_t sexp_new;
-  gcry_error_t err;
-  char *sexp_buffer;
-  size_t sexp_buffer_n;
-  size_t identifiers_n;
-  const char *label;
-  gcry_mpi_t mpi;
-  void **arg_list;
-  size_t data_n;
-  unsigned int i;
-
-  sexp_buffer_n = 1;
-  sexp_buffer = NULL;
-  arg_list = NULL;
-  err = 0;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  /* Calculate size of S-expression representation.  */
-
-  i = 0;
-  if (identifiers)
-    while (identifiers[i])
-      {
-       /* For each identifier, we add "(<IDENTIFIER>)".  */
-       sexp_buffer_n += 1 + strlen (identifiers[i]) + 1;
-       i++;
-      }
-  identifiers_n = i;
-  
-  if (! identifiers_n)
-    /* If there are NO identifiers, we still add surrounding braces so
-       that we have a list of named MPI value lists.  Otherwise it
-       wouldn't be too much fun to process these lists.  */
-    sexp_buffer_n += 2;
-  
-  data_n = _gcry_ac_data_length (data);
-  for (i = 0; i < data_n; i++)
-    {
-      err = gcry_ac_data_get_index (data, 0, i, &label, NULL);
-      if (err)
-       break;
-      /* For each MPI we add "(<LABEL> %m)".  */
-      sexp_buffer_n += 1 + strlen (label) + 4;
-    }
-  if (err)
-    goto out;
-
-  /* Allocate buffer.  */
-
-  sexp_buffer = gcry_malloc (sexp_buffer_n);
-  if (! sexp_buffer)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Fill buffer.  */
-
-  *sexp_buffer = 0;
-  sexp_buffer_n = 0;
-
-  /* Add identifiers: (<IDENTIFIER0>(<IDENTIFIER1>...)).  */
-  if (identifiers_n)
-    {
-      /* Add nested identifier lists as usual.  */
-      for (i = 0; i < identifiers_n; i++)
-       sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(%s",
-                                 identifiers[i]);
-    }
-  else
-    {
-      /* Add special list.  */
-      sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(");
-    }
-
-  /* Add MPI list.  */
-  arg_list = gcry_malloc (sizeof (*arg_list) * (data_n + 1));
-  if (! arg_list)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-  for (i = 0; i < data_n; i++)
-    {
-      err = gcry_ac_data_get_index (data, 0, i, &label, &mpi);
-      if (err)
-       break;
-      sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n,
-                               "(%s %%m)", label);
-      arg_list[i] = &data->data[i].mpi;
-    }
-  if (err)
-    goto out;
-
-  if (identifiers_n)
-    {
-      /* Add closing braces for identifier lists as usual.  */
-      for (i = 0; i < identifiers_n; i++)
-       sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")");
-    }
-  else
-    {
-      /* Add closing braces for special list.  */
-      sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")");
-    }
-
-  /* Construct.  */
-  err = gcry_sexp_build_array (&sexp_new, NULL, sexp_buffer, arg_list);
-  if (err)
-    goto out;
-
-  *sexp = sexp_new;
-
- out:
-
-  gcry_free (sexp_buffer);
-  gcry_free (arg_list);
-
-  return err;
-}
-
-/* Create a new data set, which is to be stored in DATA_SET, from the
-   S-Expression SEXP, according to the identifiers contained in
-   IDENTIFIERS.  */
-gcry_error_t
-_gcry_ac_data_from_sexp (gcry_ac_data_t *data_set, gcry_sexp_t sexp,
-                        const char **identifiers)
-{
-  gcry_ac_data_t data_set_new;
-  gcry_error_t err;
-  gcry_sexp_t sexp_cur;
-  gcry_sexp_t sexp_tmp;
-  gcry_mpi_t mpi;
-  char *string;
-  const char *data;
-  size_t data_n;
-  size_t sexp_n;
-  unsigned int i;
-  int skip_name;
-
-  data_set_new = NULL;
-  sexp_cur = sexp;
-  sexp_tmp = NULL;
-  string = NULL;
-  mpi = NULL;
-  err = 0;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  /* Process S-expression/identifiers.  */
-
-  if (identifiers)
-    {
-      for (i = 0; identifiers[i]; i++)
-       {
-         /* Next identifier.  Extract first data item from
-            SEXP_CUR.  */
-         data = gcry_sexp_nth_data (sexp_cur, 0, &data_n);
-
-         if (! ((data_n == strlen (identifiers[i]))
-                && (! strncmp (data, identifiers[i], data_n))))
-           {
-             /* Identifier mismatch -> error.  */
-             err = gcry_error (GPG_ERR_INV_SEXP);
-             break;
-           }
-
-         /* Identifier matches.  Now we have to distinguish two
-            cases:
-            
-            (i)  we are at the last identifier:
-            leave loop
-
-            (ii) we are not at the last identifier:
-            extract next element, which is supposed to be a
-            sublist.  */
-
-         if (! identifiers[i + 1])
-           /* Last identifier.  */
-           break;
-         else
-           {
-             /* Not the last identifier, extract next sublist.  */
-
-             sexp_tmp = gcry_sexp_nth (sexp_cur, 1);
-             if (! sexp_tmp)
-               {
-                 /* Missing sublist.  */
-                 err = gcry_error (GPG_ERR_INV_SEXP);
-                 break;
-               }
-
-             /* Release old SEXP_CUR, in case it is not equal to the
-                original SEXP.  */
-             if (sexp_cur != sexp)
-               gcry_sexp_release (sexp_cur);
-
-             /* Make SEXP_CUR point to the new current sublist.  */
-             sexp_cur = sexp_tmp;
-              sexp_tmp = NULL;
-           }
-       }
-      if (err)
-       goto out;
-
-      if (i)
-        {
-          /* We have at least one identifier in the list, this means
-             the the list of named MPI values is prefixed, this means
-             that we need to skip the first item (the list name), when
-             processing the MPI values.  */
-          skip_name = 1;
-        }
-      else
-        {
-          /* Since there is no identifiers list, the list of named MPI
-             values is not prefixed with a list name, therefore the
-             offset to use is zero.  */
-          skip_name = 0;
-        }
-    }
-  else
-    /* Since there is no identifiers list, the list of named MPI
-       values is not prefixed with a list name, therefore the offset
-       to use is zero.  */
-    skip_name = 0;
-
-  /* Create data set from S-expression data.  */
-  
-  err = gcry_ac_data_new (&data_set_new);
-  if (err)
-    goto out;
-
-  /* Figure out amount of named MPIs in SEXP_CUR.  */
-  if (sexp_cur)
-    sexp_n = gcry_sexp_length (sexp_cur) - skip_name;
-  else
-    sexp_n = 0;
-
-  /* Extracte the named MPIs sequentially.  */
-  for (i = 0; i < sexp_n; i++)
-    {
-      /* Store next S-Expression pair, which is supposed to consist of
-        a name and an MPI value, in SEXP_TMP.  */
-
-      sexp_tmp = gcry_sexp_nth (sexp_cur, i + skip_name);
-      if (! sexp_tmp)
-       {
-         err = gcry_error (GPG_ERR_INV_SEXP);
-         break;
-       }
-
-      /* Extract name from current S-Expression pair.  */
-      data = gcry_sexp_nth_data (sexp_tmp, 0, &data_n);
-      string = gcry_malloc (data_n + 1);
-      if (! string)
-       {
-         err = gcry_error_from_errno (errno);
-         break;
-       }
-      memcpy (string, data, data_n);
-      string[data_n] = 0;
-
-      /* Extract MPI value.  */
-      mpi = gcry_sexp_nth_mpi (sexp_tmp, 1, 0);
-      if (! mpi)
-       {
-         err = gcry_error (GPG_ERR_INV_SEXP); /* FIXME? */
-         break;
-       }
-
-      /* Store named MPI in data_set_new.  */
-      err = gcry_ac_data_set (data_set_new, GCRY_AC_FLAG_DEALLOC, string, mpi);
-      if (err)
-       break;
-
-/*       gcry_free (string); */
-      string = NULL;
-/*       gcry_mpi_release (mpi); */
-      mpi = NULL;
-
-      gcry_sexp_release (sexp_tmp);
-      sexp_tmp = NULL;
-    }
-  if (err)
-    goto out;
-
-  *data_set = data_set_new;
-
- out:
-
-  if (sexp_cur != sexp)
-    gcry_sexp_release (sexp_cur);
-  gcry_sexp_release (sexp_tmp);
-  gcry_mpi_release (mpi);
-  gcry_free (string);
-  
-  if (err)
-    gcry_ac_data_destroy (data_set_new);
-
-  return err;
-}
-
-
-static void
-_gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data)
-{
-  unsigned char *mpi_buffer;
-  size_t mpi_buffer_n;
-  unsigned int data_n;
-  gcry_error_t err;
-  const char *name;
-  gcry_mpi_t mpi;
-  unsigned int i;
-
-  if (! data)
-    return;
-
-  if (fips_mode ())
-    return;
-
-  mpi_buffer = NULL;
-
-  data_n = _gcry_ac_data_length (data);
-  for (i = 0; i < data_n; i++)
-    {
-      err = gcry_ac_data_get_index (data, 0, i, &name, &mpi);
-      if (err)
-       {
-         log_error ("failed to dump data set");
-         break;
-       }
-
-      err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &mpi_buffer, &mpi_buffer_n, mpi);
-      if (err)
-       {
-         log_error ("failed to dump data set");
-         break;
-       }
-
-      log_printf ("%s%s%s: %s\n",
-                 prefix ? prefix : "",
-                 prefix ? ": " : ""
-                 , name, mpi_buffer);
-
-      gcry_free (mpi_buffer);
-      mpi_buffer = NULL;
-    }
-
-  gcry_free (mpi_buffer);
-}
-
-/* Dump the named MPI values contained in the data set DATA to
-   Libgcrypt's logging stream.  */
-void
-gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data)
-{
-  _gcry_ac_data_dump (prefix, data);
-}
-
-/* Destroys any values contained in the data set DATA.  */
-void
-_gcry_ac_data_clear (gcry_ac_data_t data)
-{
-  ac_data_values_destroy (data);
-  gcry_free (data->data);
-  data->data = NULL;
-  data->data_n = 0;
-}
-
-\f
-
-/*
- * Implementation of `ac io' objects.
- */
-
-/* Initialize AC_IO according to MODE, TYPE and the variable list of
-   arguments AP.  The list of variable arguments to specify depends on
-   the given TYPE.  */
-void
-_gcry_ac_io_init_va (gcry_ac_io_t *ac_io,
-                    gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, va_list ap)
-{
-  memset (ac_io, 0, sizeof (*ac_io));
-
-  if (fips_mode ())
-    return;
-
-  gcry_assert ((mode == GCRY_AC_IO_READABLE) || (mode == GCRY_AC_IO_WRITABLE));
-  gcry_assert ((type == GCRY_AC_IO_STRING) || (type == GCRY_AC_IO_STRING));
-
-  ac_io->mode = mode;
-  ac_io->type = type;
-
-  switch (mode)
-    {
-    case GCRY_AC_IO_READABLE:
-      switch (type)
-       {
-       case GCRY_AC_IO_STRING:
-         ac_io->io.readable.string.data = va_arg (ap, unsigned char *);
-         ac_io->io.readable.string.data_n = va_arg (ap, size_t);
-         break;
-
-       case GCRY_AC_IO_CALLBACK:
-         ac_io->io.readable.callback.cb = va_arg (ap, gcry_ac_data_read_cb_t);
-         ac_io->io.readable.callback.opaque = va_arg (ap, void *);
-         break;
-       }
-      break;
-    case GCRY_AC_IO_WRITABLE:
-      switch (type)
-       {
-       case GCRY_AC_IO_STRING:
-         ac_io->io.writable.string.data = va_arg (ap, unsigned char **);
-         ac_io->io.writable.string.data_n = va_arg (ap, size_t *);
-         break;
-
-       case GCRY_AC_IO_CALLBACK:
-         ac_io->io.writable.callback.cb = va_arg (ap, gcry_ac_data_write_cb_t);
-         ac_io->io.writable.callback.opaque = va_arg (ap, void *);
-         break;
-       }
-      break;
-    }
-}
-
-/* Initialize AC_IO according to MODE, TYPE and the variable list of
-   arguments.  The list of variable arguments to specify depends on
-   the given TYPE. */
-void
-_gcry_ac_io_init (gcry_ac_io_t *ac_io,
-                 gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, ...)
-{
-  va_list ap;
-
-  va_start (ap, type);
-  _gcry_ac_io_init_va (ac_io, mode, type, ap);
-  va_end (ap);
-}
-
-
-/* Write to the IO object AC_IO BUFFER_N bytes from BUFFER.  Return
-   zero on success or error code.  */
-static gcry_error_t
-_gcry_ac_io_write (gcry_ac_io_t *ac_io, unsigned char *buffer, size_t buffer_n)
-{
-  gcry_error_t err;
-
-  gcry_assert (ac_io->mode == GCRY_AC_IO_WRITABLE);
-  err = 0;
-
-  switch (ac_io->type)
-    {
-    case GCRY_AC_IO_STRING:
-      {
-       unsigned char *p;
-
-       if (*ac_io->io.writable.string.data)
-         {
-           p = gcry_realloc (*ac_io->io.writable.string.data,
-                             *ac_io->io.writable.string.data_n + buffer_n);
-           if (! p)
-             err = gcry_error_from_errno (errno);
-           else
-             {
-               if (*ac_io->io.writable.string.data != p)
-                 *ac_io->io.writable.string.data = p;
-               memcpy (p + *ac_io->io.writable.string.data_n, buffer, buffer_n);
-               *ac_io->io.writable.string.data_n += buffer_n;
-             }
-         }
-       else
-         {
-           if (gcry_is_secure (buffer))
-             p = gcry_malloc_secure (buffer_n);
-           else
-             p = gcry_malloc (buffer_n);
-           if (! p)
-             err = gcry_error_from_errno (errno);
-           else
-             {
-               memcpy (p, buffer, buffer_n);
-               *ac_io->io.writable.string.data = p;
-               *ac_io->io.writable.string.data_n = buffer_n;
-             }
-         }
-      }
-      break;
-
-    case GCRY_AC_IO_CALLBACK:
-      err = (*ac_io->io.writable.callback.cb) (ac_io->io.writable.callback.opaque,
-                                              buffer, buffer_n);
-      break;
-    }
-
-  return err;
-}
-
-/* Read *BUFFER_N bytes from the IO object AC_IO into BUFFER; NREAD
-   bytes have already been read from the object; on success, store the
-   amount of bytes read in *BUFFER_N; zero bytes read means EOF.
-   Return zero on success or error code.  */
-static gcry_error_t
-_gcry_ac_io_read (gcry_ac_io_t *ac_io,
-                 unsigned int nread, unsigned char *buffer, size_t *buffer_n)
-{
-  gcry_error_t err;
-  
-  gcry_assert (ac_io->mode == GCRY_AC_IO_READABLE);
-  err = 0;
-
-  switch (ac_io->type)
-    {
-    case GCRY_AC_IO_STRING:
-      {
-       size_t bytes_available;
-       size_t bytes_to_read;
-       size_t bytes_wanted;
-
-       bytes_available = ac_io->io.readable.string.data_n - nread;
-       bytes_wanted = *buffer_n;
-
-       if (bytes_wanted > bytes_available)
-         bytes_to_read = bytes_available;
-       else
-         bytes_to_read = bytes_wanted;
-
-       memcpy (buffer, ac_io->io.readable.string.data + nread, bytes_to_read);
-       *buffer_n = bytes_to_read;
-       err = 0;
-       break;
-      }
-
-    case GCRY_AC_IO_CALLBACK:
-      err = (*ac_io->io.readable.callback.cb)
-       (ac_io->io.readable.callback.opaque, buffer, buffer_n);
-      break;
-    }
-
-  return err;
-}
-
-/* Read all data available from the IO object AC_IO into newly
-   allocated memory, storing an appropriate pointer in *BUFFER and the
-   amount of bytes read in *BUFFER_N.  Return zero on success or error
-   code.  */
-static gcry_error_t
-_gcry_ac_io_read_all (gcry_ac_io_t *ac_io, unsigned char **buffer, size_t *buffer_n)
-{
-  unsigned char *buffer_new;
-  size_t buffer_new_n;
-  unsigned char buf[BUFSIZ];
-  size_t buf_n;
-  unsigned char *p;
-  gcry_error_t err;
-
-  buffer_new = NULL;
-  buffer_new_n = 0;
-
-  while (1)
-    {
-      buf_n = sizeof (buf);
-      err = _gcry_ac_io_read (ac_io, buffer_new_n, buf, &buf_n);
-      if (err)
-       break;
-
-      if (buf_n)
-       {
-         p = gcry_realloc (buffer_new, buffer_new_n + buf_n);
-         if (! p)
-           {
-             err = gcry_error_from_errno (errno);
-             break;
-           }
-         
-         if (buffer_new != p)
-           buffer_new = p;
-
-         memcpy (buffer_new + buffer_new_n, buf, buf_n);
-         buffer_new_n += buf_n;
-       }
-      else
-       break;
-    }
-  if (err)
-    goto out;
-
-  *buffer_n = buffer_new_n;
-  *buffer = buffer_new;
-
- out:
-
-  if (err)
-    gcry_free (buffer_new);
-
-  return err;
-}
-
-/* Read data chunks from the IO object AC_IO until EOF, feeding them
-   to the callback function CB.  Return zero on success or error
-   code.  */
-static gcry_error_t
-_gcry_ac_io_process (gcry_ac_io_t *ac_io,
-                    gcry_ac_data_write_cb_t cb, void *opaque)
-{
-  unsigned char buffer[BUFSIZ];
-  unsigned int nread;
-  size_t buffer_n;
-  gcry_error_t err;
-
-  nread = 0;
-
-  while (1)
-    {
-      buffer_n = sizeof (buffer);
-      err = _gcry_ac_io_read (ac_io, nread, buffer, &buffer_n);
-      if (err)
-       break;
-      if (buffer_n)
-       {
-         err = (*cb) (opaque, buffer, buffer_n);
-         if (err)
-           break;
-         nread += buffer_n;
-       }
-      else
-       break;
-    }
-
-  return err;
-}
-
-\f
-
-/* 
- * Functions for converting data between the native ac and the
- * S-expression structure used by the pk interface.
- */
-
-/* Extract the S-Expression DATA_SEXP into DATA under the control of
-   TYPE and NAME.  This function assumes that S-Expressions are of the
-   following structure:
-
-   (IDENTIFIER [...]
-   (ALGORITHM <list of named MPI values>)) */
-static gcry_error_t
-ac_data_extract (const char *identifier, const char *algorithm,
-                gcry_sexp_t sexp, gcry_ac_data_t *data)
-{
-  gcry_error_t err;
-  gcry_sexp_t value_sexp;
-  gcry_sexp_t data_sexp;
-  size_t data_sexp_n;
-  gcry_mpi_t value_mpi;
-  char *value_name;
-  const char *data_raw;
-  size_t data_raw_n;
-  gcry_ac_data_t data_new;
-  unsigned int i;
-
-  value_sexp = NULL;
-  data_sexp = NULL;
-  value_name = NULL;
-  value_mpi = NULL;
-  data_new = NULL;
-
-  /* Verify that the S-expression contains the correct identifier.  */
-  data_raw = gcry_sexp_nth_data (sexp, 0, &data_raw_n);
-  if ((! data_raw) || strncmp (identifier, data_raw, data_raw_n))
-    {
-      err = gcry_error (GPG_ERR_INV_SEXP);
-      goto out;
-    }
-
-  /* Extract inner S-expression.  */
-  data_sexp = gcry_sexp_find_token (sexp, algorithm, 0);
-  if (! data_sexp)
-    {
-      err = gcry_error (GPG_ERR_INV_SEXP);
-      goto out;
-    }
-
-  /* Count data elements.  */
-  data_sexp_n = gcry_sexp_length (data_sexp);
-  data_sexp_n--;
-
-  /* Allocate new data set.  */
-  err = _gcry_ac_data_new (&data_new);
-  if (err)
-    goto out;
-
-  /* Iterate through list of data elements and add them to the data
-     set.  */
-  for (i = 0; i < data_sexp_n; i++)
-    {
-      /* Get the S-expression of the named MPI, that contains the name
-        and the MPI value.  */
-      value_sexp = gcry_sexp_nth (data_sexp, i + 1);
-      if (! value_sexp)
-       {
-         err = gcry_error (GPG_ERR_INV_SEXP);
-         break;
-       }
-
-      /* Extract the name.  */
-      data_raw = gcry_sexp_nth_data (value_sexp, 0, &data_raw_n);
-      if (! data_raw)
-       {
-         err = gcry_error (GPG_ERR_INV_SEXP);
-         break;
-       }
-
-      /* Extract the MPI value.  */
-      value_mpi = gcry_sexp_nth_mpi (value_sexp, 1, GCRYMPI_FMT_USG);
-      if (! value_mpi)
-       {
-         err = gcry_error (GPG_ERR_INTERNAL); /* FIXME? */
-         break;
-       }
-
-      /* Duplicate the name.  */
-      value_name = gcry_malloc (data_raw_n + 1);
-      if (! value_name)
-       {
-         err = gcry_error_from_errno (errno);
-         break;
-       }
-      strncpy (value_name, data_raw, data_raw_n);
-      value_name[data_raw_n] = 0;
-
-      err = _gcry_ac_data_set (data_new, GCRY_AC_FLAG_DEALLOC, value_name, value_mpi);
-      if (err)
-       break;
-
-      gcry_sexp_release (value_sexp);
-      value_sexp = NULL;
-      value_name = NULL;
-      value_mpi = NULL;
-    }
-  if (err)
-    goto out;
-
-  /* Copy out.  */
-  *data = data_new;
-
- out:
-
-  /* Deallocate resources.  */
-  if (err)
-    {
-      _gcry_ac_data_destroy (data_new);
-      gcry_mpi_release (value_mpi);
-      gcry_free (value_name);
-      gcry_sexp_release (value_sexp);
-    }
-  gcry_sexp_release (data_sexp);
-
-  return err;
-}
-
-/* Construct an S-expression from the DATA and store it in
-   DATA_SEXP. The S-expression will be of the following structure:
-
-   (IDENTIFIER [(flags [...])]
-   (ALGORITHM <list of named MPI values>))  */
-static gcry_error_t
-ac_data_construct (const char *identifier, int include_flags,
-                  unsigned int flags, const char *algorithm,
-                  gcry_ac_data_t data, gcry_sexp_t *sexp)
-{
-  unsigned int data_length;
-  gcry_sexp_t sexp_new;
-  gcry_error_t err;
-  size_t sexp_format_n;
-  char *sexp_format;
-  void **arg_list;
-  unsigned int i;
-
-  arg_list = NULL;
-  sexp_new = NULL;
-  sexp_format = NULL;
-
-  /* We build a list of arguments to pass to
-     gcry_sexp_build_array().  */
-  data_length = _gcry_ac_data_length (data);
-  arg_list = gcry_malloc (sizeof (*arg_list) * (data_length * 2));
-  if (! arg_list)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Fill list with MPIs.  */
-  for (i = 0; i < data_length; i++)
-    {
-      char **nameaddr  = &data->data[i].name;
-
-      arg_list[(i * 2) + 0] = nameaddr;
-      arg_list[(i * 2) + 1] = &data->data[i].mpi;
-    }
-
-  /* Calculate size of format string.  */
-  sexp_format_n = (3
-                  + (include_flags ? 7 : 0)
-                  + (algorithm ? (2 + strlen (algorithm)) : 0)
-                  + strlen (identifier));
-
-  for (i = 0; i < data_length; i++)
-    /* Per-element sizes.  */
-    sexp_format_n += 6;
-
-  if (include_flags)
-    /* Add flags.  */
-    for (i = 0; i < DIM (ac_flags); i++)
-      if (flags & ac_flags[i].number)
-       sexp_format_n += strlen (ac_flags[i].string) + 1;
-
-  /* Done.  */
-  sexp_format = gcry_malloc (sexp_format_n);
-  if (! sexp_format)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Construct the format string.  */
-
-  *sexp_format = 0;
-  strcat (sexp_format, "(");
-  strcat (sexp_format, identifier);
-  if (include_flags)
-    {
-      strcat (sexp_format, "(flags");
-      for (i = 0; i < DIM (ac_flags); i++)
-       if (flags & ac_flags[i].number)
-         {
-           strcat (sexp_format, " ");
-           strcat (sexp_format, ac_flags[i].string);
-         }
-      strcat (sexp_format, ")");
-    }
-  if (algorithm)
-    {
-      strcat (sexp_format, "(");
-      strcat (sexp_format, algorithm);
-    }
-  for (i = 0; i < data_length; i++)
-    strcat (sexp_format, "(%s%m)");
-  if (algorithm)
-    strcat (sexp_format, ")");
-  strcat (sexp_format, ")");
-
-  /* Create final S-expression.  */
-  err = gcry_sexp_build_array (&sexp_new, NULL, sexp_format, arg_list);
-  if (err)
-    goto out;
-
-  *sexp = sexp_new;
-
- out:
-
-  /* Deallocate resources.  */
-  gcry_free (sexp_format);
-  gcry_free (arg_list);
-  if (err)
-    gcry_sexp_release (sexp_new);
-
-  return err;
-}
-
-\f
-
-/*
- * Handle management.
- */
-
-/* Creates a new handle for the algorithm ALGORITHM and stores it in
-   HANDLE.  FLAGS is not used yet.  */
-gcry_error_t
-_gcry_ac_open (gcry_ac_handle_t *handle,
-              gcry_ac_id_t algorithm, unsigned int flags)
-{
-  gcry_ac_handle_t handle_new;
-  const char *algorithm_name;
-  gcry_module_t module;
-  gcry_error_t err;
-
-  *handle = NULL;
-  module = NULL;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  /* Get name.  */
-  algorithm_name = _gcry_pk_aliased_algo_name (algorithm);
-  if (! algorithm_name)
-    {
-      err = gcry_error (GPG_ERR_PUBKEY_ALGO);
-      goto out;
-    }
-
-  /* Acquire reference to the pubkey module.  */
-  err = _gcry_pk_module_lookup (algorithm, &module);
-  if (err)
-    goto out;
-  
-  /* Allocate.  */
-  handle_new = gcry_malloc (sizeof (*handle_new));
-  if (! handle_new)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Done.  */
-  handle_new->algorithm = algorithm;
-  handle_new->algorithm_name = algorithm_name;
-  handle_new->flags = flags;
-  handle_new->module = module;
-  *handle = handle_new;
-
- out:
-  
-  /* Deallocate resources.  */
-  if (err)
-    _gcry_pk_module_release (module);
-
-  return err;
-}
-
-
-/* Destroys the handle HANDLE.  */
-void
-_gcry_ac_close (gcry_ac_handle_t handle)
-{
-  /* Release reference to pubkey module.  */
-  if (handle)
-    {
-      _gcry_pk_module_release (handle->module);
-      gcry_free (handle);
-    }
-}
-
-
-\f
-/* 
- * Key management.
- */
-
-/* Initialize a key from a given data set.  */
-/* FIXME/Damn: the argument HANDLE is not only unnecessary, it is
-   completely WRONG here.  */
-gcry_error_t
-_gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
-                  gcry_ac_key_type_t type, gcry_ac_data_t data)
-{
-  gcry_ac_data_t data_new;
-  gcry_ac_key_t key_new;
-  gcry_error_t err;
-
-  (void)handle;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  /* Allocate.  */
-  key_new = gcry_malloc (sizeof (*key_new));
-  if (! key_new)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Copy data set.  */
-  err = _gcry_ac_data_copy (&data_new, data);
-  if (err)
-    goto out;
-
-  /* Done.  */
-  key_new->data = data_new;
-  key_new->type = type;
-  *key = key_new;
-
- out:
-
-  if (err)
-    /* Deallocate resources.  */
-    gcry_free (key_new);
-
-  return err;
-}
-
-
-/* Generates a new key pair via the handle HANDLE of NBITS bits and
-   stores it in KEY_PAIR.  In case non-standard settings are wanted, a
-   pointer to a structure of type gcry_ac_key_spec_<algorithm>_t,
-   matching the selected algorithm, can be given as KEY_SPEC.
-   MISC_DATA is not used yet.  */
-gcry_error_t
-_gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits,
-                           void *key_spec,
-                           gcry_ac_key_pair_t *key_pair,
-                           gcry_mpi_t **misc_data)
-{
-  gcry_sexp_t genkey_sexp_request;
-  gcry_sexp_t genkey_sexp_reply;
-  gcry_ac_data_t key_data_secret;
-  gcry_ac_data_t key_data_public;
-  gcry_ac_key_pair_t key_pair_new;
-  gcry_ac_key_t key_secret;
-  gcry_ac_key_t key_public;
-  gcry_sexp_t key_sexp;
-  gcry_error_t err;
-  char *genkey_format;
-  size_t genkey_format_n;
-  void **arg_list;
-  size_t arg_list_n;
-  unsigned int i;
-  unsigned int j;
-
-  (void)misc_data;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  key_data_secret = NULL;
-  key_data_public = NULL;
-  key_secret = NULL;
-  key_public = NULL;
-  genkey_format = NULL;
-  arg_list = NULL;
-  genkey_sexp_request = NULL;
-  genkey_sexp_reply = NULL;
-  key_sexp = NULL;
-
-  /* Allocate key pair.  */
-  key_pair_new = gcry_malloc (sizeof (struct gcry_ac_key_pair));
-  if (! key_pair_new)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Allocate keys.  */
-  key_secret = gcry_malloc (sizeof (*key_secret));
-  if (! key_secret)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-  key_public = gcry_malloc (sizeof (*key_public));
-  if (! key_public)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Calculate size of the format string, that is used for creating
-     the request S-expression.  */
-  genkey_format_n = 22;
-
-  /* Respect any relevant algorithm specific commands.  */
-  if (key_spec)
-    for (i = 0; i < DIM (ac_key_generate_specs); i++)
-      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
-       genkey_format_n += 6;
-
-  /* Create format string.  */
-  genkey_format = gcry_malloc (genkey_format_n);
-  if (! genkey_format)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Fill format string.  */
-  *genkey_format = 0;
-  strcat (genkey_format, "(genkey(%s(nbits%d)");
-  if (key_spec)
-    for (i = 0; i < DIM (ac_key_generate_specs); i++)
-      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
-       strcat (genkey_format, "(%s%m)");
-  strcat (genkey_format, "))");
-
-  /* Build list of argument pointers, the algorithm name and the nbits
-     are always needed.  */
-  arg_list_n = 2;
-
-  /* Now the algorithm specific arguments.  */
-  if (key_spec)
-    for (i = 0; i < DIM (ac_key_generate_specs); i++)
-      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
-       arg_list_n += 2;
-
-  /* Allocate list.  */
-  arg_list = gcry_malloc (sizeof (*arg_list) * arg_list_n);
-  if (! arg_list)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  arg_list[0] = (void *) &handle->algorithm_name;
-  arg_list[1] = (void *) &nbits;
-  if (key_spec)
-    for (j = 2, i = 0; i < DIM (ac_key_generate_specs); i++)
-      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
-       {
-         /* Add name of this specification flag and the
-            according member of the spec strucuture.  */
-         arg_list[j++] = (void *)(&ac_key_generate_specs[i].name);
-         arg_list[j++] = (void *)
-           (((char *) key_spec)
-            + ac_key_generate_specs[i].offset);
-         /* FIXME: above seems to suck.  */
-       }
-
-  /* Construct final request S-expression.  */
-  err = gcry_sexp_build_array (&genkey_sexp_request,
-                              NULL, genkey_format, arg_list);
-  if (err)
-    goto out;
-
-  /* Perform genkey operation.  */
-  err = gcry_pk_genkey (&genkey_sexp_reply, genkey_sexp_request);
-  if (err)
-    goto out;
-
-  key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "private-key", 0);
-  if (! key_sexp)
-    {
-      err = gcry_error (GPG_ERR_INTERNAL);
-      goto out;
-    }
-  err = ac_data_extract ("private-key", handle->algorithm_name,
-                        key_sexp, &key_data_secret);
-  if (err)
-    goto out;
-
-  gcry_sexp_release (key_sexp);
-  key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "public-key", 0);
-  if (! key_sexp)
-    {
-      err = gcry_error (GPG_ERR_INTERNAL);
-      goto out;
-    }
-  err = ac_data_extract ("public-key", handle->algorithm_name,
-                        key_sexp, &key_data_public);
-  if (err)
-    goto out;
-
-  /* Done.  */
-
-  key_secret->type = GCRY_AC_KEY_SECRET;
-  key_secret->data = key_data_secret;
-  key_public->type = GCRY_AC_KEY_PUBLIC;
-  key_public->data = key_data_public;
-  key_pair_new->secret = key_secret;
-  key_pair_new->public = key_public;
-  *key_pair = key_pair_new;
-
- out:
-
-  /* Deallocate resources.  */
-  
-  gcry_free (genkey_format);
-  gcry_free (arg_list);
-  gcry_sexp_release (genkey_sexp_request);
-  gcry_sexp_release (genkey_sexp_reply);
-  gcry_sexp_release (key_sexp);
-  if (err)
-    {
-      _gcry_ac_data_destroy (key_data_secret);
-      _gcry_ac_data_destroy (key_data_public);
-      gcry_free (key_secret);
-      gcry_free (key_public);
-      gcry_free (key_pair_new);
-    }
-
-  return err;
-}
-
-/* Returns the key of type WHICH out of the key pair KEY_PAIR.  */
-gcry_ac_key_t
-_gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair, 
-                           gcry_ac_key_type_t which)
-{
-  gcry_ac_key_t key;
-
-  if (fips_mode ())
-    return NULL;
-
-  switch (which)
-    {
-    case GCRY_AC_KEY_SECRET:
-      key = key_pair->secret;
-      break;
-
-    case GCRY_AC_KEY_PUBLIC:
-      key = key_pair->public;
-      break;
-
-    default:
-      key = NULL;
-      break;
-    }
-
-  return key;
-}
-
-/* Destroys the key KEY.  */
-void
-_gcry_ac_key_destroy (gcry_ac_key_t key)
-{
-  unsigned int i;
-
-  if (key)
-    {
-      if (key->data)
-        {
-          for (i = 0; i < key->data->data_n; i++)
-            {
-              if (key->data->data[i].mpi)
-                gcry_mpi_release (key->data->data[i].mpi);
-              if (key->data->data[i].name)
-                gcry_free (key->data->data[i].name);
-            }
-          gcry_free (key->data->data);
-          gcry_free (key->data);
-        }
-      gcry_free (key);
-    }
-}
-
-/* Destroys the key pair KEY_PAIR.  */
-void
-_gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
-{
-  if (key_pair)
-    {
-      gcry_ac_key_destroy (key_pair->secret);
-      gcry_ac_key_destroy (key_pair->public);
-      gcry_free (key_pair);
-    }
-}
-
-/* Returns the data set contained in the key KEY.  */
-gcry_ac_data_t
-_gcry_ac_key_data_get (gcry_ac_key_t key)
-{
-  if (fips_mode ())
-    return NULL;
-  return key->data;
-}
-
-/* Verifies that the key KEY is sane via HANDLE.  */
-gcry_error_t
-_gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
-{
-  gcry_sexp_t key_sexp;
-  gcry_error_t err;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  key_sexp = NULL;
-  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
-                          handle->algorithm_name, key->data, &key_sexp);
-  if (err)
-    goto out;
-
-  err = gcry_pk_testkey (key_sexp);
-
- out:
-
-  gcry_sexp_release (key_sexp);
-
-  return gcry_error (err);
-}
-
-/* Stores the number of bits of the key KEY in NBITS via HANDLE.  */
-gcry_error_t
-_gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
-                       gcry_ac_key_t key, unsigned int *nbits)
-{
-  gcry_sexp_t key_sexp;
-  gcry_error_t err;
-  unsigned int n;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  key_sexp = NULL;
-
-  err = ac_data_construct (ac_key_identifiers[key->type],
-                          0, 0, handle->algorithm_name, key->data, &key_sexp);
-  if (err)
-    goto out;
-
-  n = gcry_pk_get_nbits (key_sexp);
-  if (! n)
-    {
-      err = gcry_error (GPG_ERR_PUBKEY_ALGO);
-      goto out;
-    }
-
-  *nbits = n;
-
- out:
-
-  gcry_sexp_release (key_sexp);
-
-  return err;
-}
-
-/* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
-   HANDLE.  */
-gcry_error_t
-_gcry_ac_key_get_grip (gcry_ac_handle_t handle,
-                      gcry_ac_key_t key, unsigned char *key_grip)
-{
-  gcry_sexp_t key_sexp;
-  gcry_error_t err;
-  unsigned char *ret;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  key_sexp = NULL;
-  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
-                          handle->algorithm_name, key->data, &key_sexp);
-  if (err)
-    goto out;
-
-  ret = gcry_pk_get_keygrip (key_sexp, key_grip);
-  if (! ret)
-    {
-      err = gcry_error (GPG_ERR_INV_OBJ);
-      goto out;
-    }
-
-  err = 0;
-
- out:
-
-  gcry_sexp_release (key_sexp);
-
-  return err;
-}
-
-
-\f
-
-/* 
- * Functions performing cryptographic operations.
- */
-
-/* Encrypts the plain text MPI value DATA_PLAIN with the key public
-   KEY under the control of the flags FLAGS and stores the resulting
-   data set into DATA_ENCRYPTED.  */
-gcry_error_t
-_gcry_ac_data_encrypt (gcry_ac_handle_t handle,
-                      unsigned int flags,
-                      gcry_ac_key_t key,
-                      gcry_mpi_t data_plain,
-                      gcry_ac_data_t *data_encrypted)
-{
-  gcry_ac_data_t data_encrypted_new;
-  gcry_ac_data_t data_value;
-  gcry_sexp_t sexp_request;
-  gcry_sexp_t sexp_reply;
-  gcry_sexp_t sexp_key;
-  gcry_error_t err;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  data_encrypted_new = NULL;
-  sexp_request = NULL;
-  sexp_reply = NULL;
-  data_value = NULL;
-  sexp_key = NULL;
-
-  if (key->type != GCRY_AC_KEY_PUBLIC)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
-                          handle->algorithm_name, key->data, &sexp_key);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_new (&data_value);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_set (data_value, 0, "value", data_plain);
-  if (err)
-    goto out;
-
-  err = ac_data_construct ("data", 1, flags, handle->algorithm_name,
-                          data_value, &sexp_request);
-  if (err)
-    goto out;
-
-  /* FIXME: error vs. errcode? */
-
-  err = gcry_pk_encrypt (&sexp_reply, sexp_request, sexp_key);
-  if (err)
-    goto out;
-
-  /* Extract data.  */
-  err = ac_data_extract ("enc-val", handle->algorithm_name,
-                        sexp_reply, &data_encrypted_new);
-  if (err)
-    goto out;
-
-  *data_encrypted = data_encrypted_new;
-
- out:
-
-  /* Deallocate resources.  */
-
-  gcry_sexp_release (sexp_request);
-  gcry_sexp_release (sexp_reply);
-  gcry_sexp_release (sexp_key);
-  _gcry_ac_data_destroy (data_value);
-
-  return err;
-}
-
-/* Decrypts the encrypted data contained in the data set
-   DATA_ENCRYPTED with the secret key KEY under the control of the
-   flags FLAGS and stores the resulting plain text MPI value in
-   DATA_PLAIN.  */
-gcry_error_t
-_gcry_ac_data_decrypt (gcry_ac_handle_t handle,
-                      unsigned int flags,
-                      gcry_ac_key_t key,
-                      gcry_mpi_t *data_plain,
-                      gcry_ac_data_t data_encrypted)
-{
-  gcry_mpi_t data_decrypted;
-  gcry_sexp_t sexp_request;
-  gcry_sexp_t sexp_reply;
-  gcry_sexp_t sexp_value;
-  gcry_sexp_t sexp_key;
-  gcry_error_t err;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  sexp_request = NULL;
-  sexp_reply = NULL;
-  sexp_value = NULL;
-  sexp_key = NULL;
-
-  if (key->type != GCRY_AC_KEY_SECRET)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
-                          handle->algorithm_name, key->data, &sexp_key);
-  if (err)
-    goto out;
-
-  /* Create S-expression from data.  */
-  err = ac_data_construct ("enc-val", 1, flags, handle->algorithm_name,
-                          data_encrypted, &sexp_request);
-  if (err)
-    goto out;
-
-  /* Decrypt.  */
-  err = gcry_pk_decrypt (&sexp_reply, sexp_request, sexp_key);
-  if (err)
-    goto out;
-
-  /* Extract plain text. */
-  sexp_value = gcry_sexp_find_token (sexp_reply, "value", 0);
-  if (! sexp_value)
-    {
-      /* FIXME?  */
-      err = gcry_error (GPG_ERR_GENERAL);
-      goto out;
-    }
-
-  data_decrypted = gcry_sexp_nth_mpi (sexp_value, 1, GCRYMPI_FMT_USG);
-  if (! data_decrypted)
-    {
-      err = gcry_error (GPG_ERR_GENERAL);
-      goto out;
-    }
-
-  *data_plain = data_decrypted;
-
- out:
-
-  /* Deallocate resources.  */
-  gcry_sexp_release (sexp_request);
-  gcry_sexp_release (sexp_reply);
-  gcry_sexp_release (sexp_value);
-  gcry_sexp_release (sexp_key);
-
-  return gcry_error (err);
-
-}
-
-/* Signs the data contained in DATA with the secret key KEY and stores
-   the resulting signature data set in DATA_SIGNATURE.  */
-gcry_error_t
-_gcry_ac_data_sign (gcry_ac_handle_t handle,
-                   gcry_ac_key_t key,
-                   gcry_mpi_t data,
-                   gcry_ac_data_t *data_signature)
-{
-  gcry_ac_data_t data_signed;
-  gcry_ac_data_t data_value;
-  gcry_sexp_t sexp_request;
-  gcry_sexp_t sexp_reply;
-  gcry_sexp_t sexp_key;
-  gcry_error_t err;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  data_signed = NULL;
-  data_value = NULL;
-  sexp_request = NULL;
-  sexp_reply = NULL;
-  sexp_key = NULL;
-
-  if (key->type != GCRY_AC_KEY_SECRET)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
-                          handle->algorithm_name, key->data, &sexp_key);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_new (&data_value);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_set (data_value, 0, "value", data);
-  if (err)
-    goto out;
-
-  /* Create S-expression holding the data.  */
-  err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_request);
-  if (err)
-    goto out;
-
-  /* Sign.  */
-  err = gcry_pk_sign (&sexp_reply, sexp_request, sexp_key);
-  if (err)
-    goto out;
-
-  /* Extract data.  */
-  err = ac_data_extract ("sig-val", handle->algorithm_name,
-                        sexp_reply, &data_signed);
-  if (err)
-    goto out;
-
-  /* Done.  */
-  *data_signature = data_signed;
-
- out:
-
-  gcry_sexp_release (sexp_request);
-  gcry_sexp_release (sexp_reply);
-  gcry_sexp_release (sexp_key);
-  _gcry_ac_data_destroy (data_value);
-
-  return gcry_error (err);
-}
-
-
-/* Verifies that the signature contained in the data set
-   DATA_SIGNATURE is indeed the result of signing the data contained
-   in DATA with the secret key belonging to the public key KEY.  */
-gcry_error_t
-_gcry_ac_data_verify (gcry_ac_handle_t handle,
-                     gcry_ac_key_t key,
-                     gcry_mpi_t data,
-                     gcry_ac_data_t data_signature)
-{
-  gcry_sexp_t sexp_signature;
-  gcry_ac_data_t data_value;
-  gcry_sexp_t sexp_data;
-  gcry_sexp_t sexp_key;
-  gcry_error_t err;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  sexp_signature = NULL;
-  data_value = NULL;
-  sexp_data = NULL;
-  sexp_key = NULL;
-
-  err = ac_data_construct ("public-key", 0, 0,
-                          handle->algorithm_name, key->data, &sexp_key);
-  if (err)
-    goto out;
-
-  if (key->type != GCRY_AC_KEY_PUBLIC)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  /* Construct S-expression holding the signature data.  */
-  err = ac_data_construct ("sig-val", 1, 0, handle->algorithm_name,
-                          data_signature, &sexp_signature);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_new (&data_value);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_set (data_value, 0, "value", data);
-  if (err)
-    goto out;
-
-  /* Construct S-expression holding the data.  */
-  err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_data);
-  if (err)
-    goto out;
-
-  /* Verify signature.  */
-  err = gcry_pk_verify (sexp_signature, sexp_data, sexp_key);
-
- out:
-
-  gcry_sexp_release (sexp_signature);
-  gcry_sexp_release (sexp_data);
-  gcry_sexp_release (sexp_key);
-  _gcry_ac_data_destroy (data_value);
-
-  return gcry_error (err);
-}
-
-
-
-\f
-/*
- * Implementation of encoding methods (em).
- */
-
-/* Type for functions that encode or decode (hence the name) a
-   message.  */
-typedef gcry_error_t (*gcry_ac_em_dencode_t) (unsigned int flags,
-                                                void *options,
-                                                gcry_ac_io_t *ac_io_read,
-                                                gcry_ac_io_t *ac_io_write);
-
-/* Fill the buffer BUFFER which is BUFFER_N bytes long with non-zero
-   random bytes of random level LEVEL.  */
-static void
-em_randomize_nonzero (unsigned char *buffer, size_t buffer_n,
-                     gcry_random_level_t level)
-{
-  unsigned char *buffer_rand;
-  unsigned int buffer_rand_n;
-  unsigned int zeros;
-  unsigned int i;
-  unsigned int j;
-
-  for (i = 0; i < buffer_n; i++)
-    buffer[i] = 0;
-  
-  do
-    {
-      /* Count zeros.  */
-      for (i = zeros = 0; i < buffer_n; i++)
-       if (! buffer[i])
-         zeros++;
-
-      if (zeros)
-       {
-         /* Get random bytes.  */
-         buffer_rand_n = zeros + (zeros / 128);
-         buffer_rand = gcry_random_bytes_secure (buffer_rand_n, level);
-
-         /* Substitute zeros with non-zero random bytes.  */
-         for (i = j = 0; zeros && (i < buffer_n) && (j < buffer_rand_n); i++)
-           if (! buffer[i])
-             {
-               while ((j < buffer_rand_n) && (! buffer_rand[j]))
-                 j++;
-               if (j < buffer_rand_n)
-                 {
-                   buffer[i] = buffer_rand[j++];
-                   zeros--;
-                 }
-               else
-                 break;
-             }
-         gcry_free (buffer_rand);
-       }
-    }
-  while (zeros);
-}
-
-/* Encode a message according to the Encoding Method for Encryption
-   `PKCS-V1_5' (EME-PKCS-V1_5).  */
-static gcry_error_t
-eme_pkcs_v1_5_encode (unsigned int flags, void *opts,
-                     gcry_ac_io_t *ac_io_read,
-                     gcry_ac_io_t *ac_io_write)
-{
-  gcry_ac_eme_pkcs_v1_5_t *options;
-  gcry_error_t err;
-  unsigned char *buffer;
-  unsigned char *ps;
-  unsigned char *m;
-  size_t m_n;
-  unsigned int ps_n;
-  unsigned int k;
-
-  (void)flags;
-
-  options = opts;
-  buffer = NULL;
-  m = NULL;
-
-  err = _gcry_ac_io_read_all (ac_io_read, &m, &m_n);
-  if (err)
-    goto out;
-
-  /* Figure out key length in bytes.  */
-  k = options->key_size / 8;
-
-  if (m_n > k - 11)
-    {
-      /* Key is too short for message.  */
-      err = gcry_error (GPG_ERR_TOO_SHORT);
-      goto out;
-    }
-
-  /* According to this encoding method, the first byte of the encoded
-     message is zero.  This byte will be lost anyway, when the encoded
-     message is to be converted into an MPI, that's why we skip
-     it.  */
-
-  /* Allocate buffer.  */
-  buffer = gcry_malloc (k - 1);
-  if (! buffer)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Generate an octet string PS of length k - mLen - 3 consisting
-     of pseudorandomly generated nonzero octets.  The length of PS
-     will be at least eight octets.  */
-  ps_n = k - m_n - 3;
-  ps = buffer + 1;
-  em_randomize_nonzero (ps, ps_n, GCRY_STRONG_RANDOM);
-
-  /* Concatenate PS, the message M, and other padding to form an
-     encoded message EM of length k octets as:
-
-     EM = 0x00 || 0x02 || PS || 0x00 || M.  */
-
-  buffer[0] = 0x02;
-  buffer[ps_n + 1] = 0x00;
-  memcpy (buffer + ps_n + 2, m, m_n);
-
-  err = _gcry_ac_io_write (ac_io_write, buffer, k - 1);
-
- out:
-
-  gcry_free (buffer);
-  gcry_free (m);
-
-  return err;
-}
-
-/* Decode a message according to the Encoding Method for Encryption
-   `PKCS-V1_5' (EME-PKCS-V1_5).  */
-static gcry_error_t
-eme_pkcs_v1_5_decode (unsigned int flags, void *opts,
-                     gcry_ac_io_t *ac_io_read,
-                     gcry_ac_io_t *ac_io_write)
-{
-  gcry_ac_eme_pkcs_v1_5_t *options;
-  unsigned char *buffer;
-  unsigned char *em;
-  size_t em_n;
-  gcry_error_t err;
-  unsigned int i;
-  unsigned int k;
-
-  (void)flags;
-
-  options = opts;
-  buffer = NULL;
-  em = NULL;
-
-  err = _gcry_ac_io_read_all (ac_io_read, &em, &em_n);
-  if (err)
-    goto out;
-
-  /* Figure out key size.  */
-  k = options->key_size / 8;
-
-  /* Search for zero byte.  */
-  for (i = 0; (i < em_n) && em[i]; i++);
-
-  /* According to this encoding method, the first byte of the encoded
-     message should be zero.  This byte is lost.  */
-
-  if (! ((em_n >= 10)
-        && (em_n == (k - 1))
-        && (em[0] == 0x02)
-        && (i < em_n)
-        && ((i - 1) >= 8)))
-    {
-      err = gcry_error (GPG_ERR_DECRYPT_FAILED);
-      goto out;
-    }
-
-  i++;
-  buffer = gcry_malloc (em_n - i);
-  if (! buffer)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  memcpy (buffer, em + i, em_n - i);
-  err = _gcry_ac_io_write (ac_io_write, buffer, em_n - i);
-
- out:
-
-  gcry_free (buffer);
-  gcry_free (em);
-
-  return err;
-}
-
-static gcry_error_t
-emsa_pkcs_v1_5_encode_data_cb (void *opaque,
-                              unsigned char *buffer, size_t buffer_n)
-{
-  gcry_md_hd_t md_handle;
-
-  md_handle = opaque;
-  gcry_md_write (md_handle, buffer, buffer_n);
-
-  return 0;
-}
-
-
-/* Encode a message according to the Encoding Method for Signatures
-   with Appendix `PKCS-V1_5' (EMSA-PKCS-V1_5).  */
-static gcry_error_t
-emsa_pkcs_v1_5_encode (unsigned int flags, void *opts,
-                      gcry_ac_io_t *ac_io_read,
-                      gcry_ac_io_t *ac_io_write)
-{
-  gcry_ac_emsa_pkcs_v1_5_t *options;
-  gcry_error_t err;
-  gcry_md_hd_t md;
-  unsigned char *t;
-  size_t t_n;
-  unsigned char *h;
-  size_t h_n;
-  unsigned char *ps;
-  size_t ps_n;
-  unsigned char *buffer;
-  size_t buffer_n;
-  unsigned char asn[100];      /* FIXME, always enough?  */
-  size_t asn_n;
-  unsigned int i;
-
-  (void)flags;
-  
-  options = opts;
-  buffer = NULL;
-  md = NULL;
-  ps = NULL;
-  t = NULL;
-
-  /* Create hashing handle and get the necessary information.  */
-  err = gcry_md_open (&md, options->md, 0);
-  if (err)
-    goto out;
-
-  asn_n = DIM (asn);
-  err = gcry_md_algo_info (options->md, GCRYCTL_GET_ASNOID, asn, &asn_n);
-  if (err)
-    goto out;
-
-  h_n = gcry_md_get_algo_dlen (options->md);
-
-  err = _gcry_ac_io_process (ac_io_read, emsa_pkcs_v1_5_encode_data_cb, md);
-  if (err)
-    goto out;
-
-  h = gcry_md_read (md, 0);
-
-  /* Encode the algorithm ID for the hash function and the hash value
-     into an ASN.1 value of type DigestInfo with the Distinguished
-     Encoding Rules (DER), where the type DigestInfo has the syntax:
-
-     DigestInfo ::== SEQUENCE {
-     digestAlgorithm AlgorithmIdentifier,
-     digest OCTET STRING
-     }
-
-     The first field identifies the hash function and the second
-     contains the hash value.  Let T be the DER encoding of the
-     DigestInfo value and let tLen be the length in octets of T.  */
-
-  t_n = asn_n + h_n;
-  t = gcry_malloc (t_n);
-  if (! t)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  for (i = 0; i < asn_n; i++)
-    t[i] = asn[i];
-  for (i = 0; i < h_n; i++)
-    t[asn_n + i] = h[i];
-
-  /* If emLen < tLen + 11, output "intended encoded message length
-     too short" and stop.  */
-  if (options->em_n < t_n + 11)
-    {
-      err = gcry_error (GPG_ERR_TOO_SHORT);
-      goto out;
-    }
-
-  /* Generate an octet string PS consisting of emLen - tLen - 3 octets
-     with hexadecimal value 0xFF.  The length of PS will be at least 8
-     octets.  */
-  ps_n = options->em_n - t_n - 3;
-  ps = gcry_malloc (ps_n);
-  if (! ps)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-  for (i = 0; i < ps_n; i++)
-    ps[i] = 0xFF;
-
-  /* Concatenate PS, the DER encoding T, and other padding to form the
-     encoded message EM as:
-
-     EM = 0x00 || 0x01 || PS || 0x00 || T.  */
-
-  buffer_n = ps_n + t_n + 3;
-  buffer = gcry_malloc (buffer_n);
-  if (! buffer)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  buffer[0] = 0x00;
-  buffer[1] = 0x01;
-  for (i = 0; i < ps_n; i++)
-    buffer[2 + i] = ps[i];
-  buffer[2 + ps_n] = 0x00;
-  for (i = 0; i < t_n; i++)
-    buffer[3 + ps_n + i] = t[i];
-
-  err = _gcry_ac_io_write (ac_io_write, buffer, buffer_n);
-
- out:
-
-  gcry_md_close (md);
-
-  gcry_free (buffer);
-  gcry_free (ps);
-  gcry_free (t);
-
-  return err;
-}
-
-/* `Actions' for data_dencode().  */
-typedef enum dencode_action
-  {
-    DATA_ENCODE,
-    DATA_DECODE,
-  }
-dencode_action_t;
-
-/* Encode or decode a message according to the the encoding method
-   METHOD; ACTION specifies wether the message that is contained in
-   BUFFER_IN and of length BUFFER_IN_N should be encoded or decoded.
-   The resulting message will be stored in a newly allocated buffer in
-   BUFFER_OUT and BUFFER_OUT_N.  */
-static gcry_error_t
-ac_data_dencode (gcry_ac_em_t method, dencode_action_t action,
-                unsigned int flags, void *options,
-                gcry_ac_io_t *ac_io_read,
-                gcry_ac_io_t *ac_io_write)
-{
-  struct
-  {
-    gcry_ac_em_t method;
-    gcry_ac_em_dencode_t encode;
-    gcry_ac_em_dencode_t decode;
-  } methods[] =
-    {
-      { GCRY_AC_EME_PKCS_V1_5,
-       eme_pkcs_v1_5_encode, eme_pkcs_v1_5_decode },
-      { GCRY_AC_EMSA_PKCS_V1_5,
-       emsa_pkcs_v1_5_encode, NULL },
-    };
-  size_t methods_n;
-  gcry_error_t err;
-  unsigned int i;
-
-  methods_n = sizeof (methods) / sizeof (*methods);
-
-  for (i = 0; i < methods_n; i++)
-    if (methods[i].method == method)
-      break;
-  if (i == methods_n)
-    {
-      err = gcry_error (GPG_ERR_NOT_FOUND);    /* FIXME? */
-      goto out;
-    }
-
-  err = 0;
-  switch (action)
-    {
-    case DATA_ENCODE:
-      if (methods[i].encode)
-       /* FIXME? */
-       err = (*methods[i].encode) (flags, options, ac_io_read, ac_io_write);
-      break;
-
-    case DATA_DECODE:
-      if (methods[i].decode)
-       /* FIXME? */
-       err = (*methods[i].decode) (flags, options, ac_io_read, ac_io_write);
-      break;
-
-    default:
-      err = gcry_error (GPG_ERR_INV_ARG);
-      break;
-    }
-
- out:
-
-  return err;
-}
-
-/* Encode a message according to the encoding method METHOD.  OPTIONS
-   must be a pointer to a method-specific structure
-   (gcry_ac_em*_t).  */
-gcry_error_t
-_gcry_ac_data_encode (gcry_ac_em_t method,
-                     unsigned int flags, void *options,
-                     gcry_ac_io_t *ac_io_read,
-                     gcry_ac_io_t *ac_io_write)
-{
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  return ac_data_dencode (method, DATA_ENCODE, flags, options,
-                         ac_io_read, ac_io_write);
-}
-
-/* Dencode a message according to the encoding method METHOD.  OPTIONS
-   must be a pointer to a method-specific structure
-   (gcry_ac_em*_t).  */
-gcry_error_t
-_gcry_ac_data_decode (gcry_ac_em_t method,
-                     unsigned int flags, void *options,
-                     gcry_ac_io_t *ac_io_read,
-                     gcry_ac_io_t *ac_io_write)
-{
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  return ac_data_dencode (method, DATA_DECODE, flags, options,
-                         ac_io_read, ac_io_write);
-}
-
-/* Convert an MPI into an octet string.  */
-void
-_gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
-{
-  unsigned long digit;
-  gcry_mpi_t base;
-  unsigned int i;
-  unsigned int n;
-  gcry_mpi_t m;
-  gcry_mpi_t d;
-
-  if (fips_mode ())
-    return;
-
-  base = gcry_mpi_new (0);
-  gcry_mpi_set_ui (base, 256);
-
-  n = 0;
-  m = gcry_mpi_copy (mpi);
-  while (gcry_mpi_cmp_ui (m, 0))
-    {
-      n++;
-      gcry_mpi_div (m, NULL, m, base, 0);
-    }
-
-  gcry_mpi_set (m, mpi);
-  d = gcry_mpi_new (0);
-  for (i = 0; (i < n) && (i < os_n); i++)
-    {
-      gcry_mpi_mod (d, m, base);
-      _gcry_mpi_get_ui (d, &digit);
-      gcry_mpi_div (m, NULL, m, base, 0);
-      os[os_n - i - 1] = (digit & 0xFF);
-    }
-
-  for (; i < os_n; i++)
-    os[os_n - i - 1] = 0;
-
-  gcry_mpi_release (base);
-  gcry_mpi_release (d);
-  gcry_mpi_release (m);
-}
-
-/* Convert an MPI into an newly allocated octet string.  */
-gcry_error_t
-_gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os, size_t *os_n)
-{
-  unsigned char *buffer;
-  size_t buffer_n;
-  gcry_error_t err;
-  unsigned int nbits;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  nbits = gcry_mpi_get_nbits (mpi);
-  buffer_n = (nbits + 7) / 8;
-  buffer = gcry_malloc (buffer_n);
-  if (! buffer)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-      
-  _gcry_ac_mpi_to_os (mpi, buffer, buffer_n);
-  *os = buffer;
-  *os_n = buffer_n;
-  err = 0;
-
- out:
-
-  return err;
-}
-
-
-/* Convert an octet string into an MPI.  */
-void
-_gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
-{
-  unsigned int i;
-  gcry_mpi_t xi;
-  gcry_mpi_t x;
-  gcry_mpi_t a;
-  
-  if (fips_mode ())
-    return;
-
-  a = gcry_mpi_new (0);
-  gcry_mpi_set_ui (a, 1);
-  x = gcry_mpi_new (0);
-  gcry_mpi_set_ui (x, 0);
-  xi = gcry_mpi_new (0);
-
-  for (i = 0; i < os_n; i++)
-    {
-      gcry_mpi_mul_ui (xi, a, os[os_n - i - 1]);
-      gcry_mpi_add (x, x, xi);
-      gcry_mpi_mul_ui (a, a, 256);
-    }
-      
-  gcry_mpi_release (xi);
-  gcry_mpi_release (a);
-
-  gcry_mpi_set (mpi, x);
-  gcry_mpi_release (x);                /* FIXME: correct? */
-}
-
-
-\f
-/* 
- * Implementation of Encryption Schemes (ES) and Signature Schemes
- * with Appendix (SSA).
- */
-
-/* Schemes consist of two things: encoding methods and cryptographic
-   primitives.
-
-   Since encoding methods are accessible through a common API with
-   method-specific options passed as an anonymous struct, schemes have
-   to provide functions that construct this method-specific structure;
-   this is what the functions of type `gcry_ac_dencode_prepare_t' are
-   there for.  */
-
-typedef gcry_error_t (*gcry_ac_dencode_prepare_t) (gcry_ac_handle_t handle,
-                                                  gcry_ac_key_t key,
-                                                  void *opts,
-                                                  void *opts_em);
-
-/* The `dencode_prepare' function for ES-PKCS-V1_5.  */
-static gcry_error_t
-ac_es_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
-                                void *opts, void *opts_em)
-{
-  gcry_ac_eme_pkcs_v1_5_t *options_em;
-  unsigned int nbits;
-  gcry_error_t err;
-
-  (void)opts;
-
-  err = _gcry_ac_key_get_nbits (handle, key, &nbits);
-  if (err)
-    goto out;
-
-  options_em = opts_em;
-  options_em->key_size = nbits;
-
- out:
-
-  return err;
-}
-
-/* The `dencode_prepare' function for SSA-PKCS-V1_5.  */
-static gcry_error_t
-ac_ssa_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
-                                 void *opts, void *opts_em)
-{
-  gcry_ac_emsa_pkcs_v1_5_t *options_em;
-  gcry_ac_ssa_pkcs_v1_5_t *options;
-  gcry_error_t err;
-  unsigned int k;
-
-  options_em = opts_em;
-  options = opts;
-
-  err = _gcry_ac_key_get_nbits (handle, key, &k);
-  if (err)
-    goto out;
-
-  k = (k + 7) / 8;
-  options_em->md = options->md;
-  options_em->em_n = k;
-
- out:
-
-  return err;
-}
-
-/* Type holding the information about each supported
-   Encryption/Signature Scheme.  */
-typedef struct ac_scheme
-{
-  gcry_ac_scheme_t scheme;
-  gcry_ac_em_t scheme_encoding;
-  gcry_ac_dencode_prepare_t dencode_prepare;
-  size_t options_em_n;
-} ac_scheme_t;
-
-/* List of supported Schemes.  */
-static ac_scheme_t ac_schemes[] =
-  {
-    { GCRY_AC_ES_PKCS_V1_5, GCRY_AC_EME_PKCS_V1_5,
-      ac_es_dencode_prepare_pkcs_v1_5,
-      sizeof (gcry_ac_eme_pkcs_v1_5_t) },
-    { GCRY_AC_SSA_PKCS_V1_5, GCRY_AC_EMSA_PKCS_V1_5,
-      ac_ssa_dencode_prepare_pkcs_v1_5,
-      sizeof (gcry_ac_emsa_pkcs_v1_5_t) }
-  };
-
-/* Lookup a scheme by it's ID.  */
-static ac_scheme_t *
-ac_scheme_get (gcry_ac_scheme_t scheme)
-{
-  ac_scheme_t *ac_scheme;
-  unsigned int i;
-
-  for (i = 0; i < DIM (ac_schemes); i++)
-    if (scheme == ac_schemes[i].scheme)
-      break;
-  if (i == DIM (ac_schemes))
-    ac_scheme = NULL;
-  else
-    ac_scheme = ac_schemes + i;
-
-  return ac_scheme;
-}
-
-/* Prepares the encoding/decoding by creating an according option
-   structure.  */
-static gcry_error_t
-ac_dencode_prepare (gcry_ac_handle_t handle, gcry_ac_key_t key, void *opts,
-                   ac_scheme_t scheme, void **opts_em)
-{
-  gcry_error_t err;
-  void *options_em;
-
-  options_em = gcry_malloc (scheme.options_em_n);
-  if (! options_em)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-  
-  err = (*scheme.dencode_prepare) (handle, key, opts, options_em);
-  if (err)
-    goto out;
-
-  *opts_em = options_em;
-
- out:
-
-  if (err)
-    free (options_em);
-
-  return err;
-}
-
-/* Convert a data set into a single MPI; currently, this is only
-   supported for data sets containing a single MPI.  */
-static gcry_error_t
-ac_data_set_to_mpi (gcry_ac_data_t data, gcry_mpi_t *mpi)
-{
-  gcry_error_t err;
-  gcry_mpi_t mpi_new;
-  unsigned int elems;
-
-  elems = _gcry_ac_data_length (data);
-
-  if (elems != 1)
-    {
-      /* FIXME: I guess, we should be more flexible in this respect by
-        allowing the actual encryption/signature schemes to implement
-        this conversion mechanism.  */
-      err = gcry_error (GPG_ERR_CONFLICT);
-      goto out;
-    }
-
-  err = _gcry_ac_data_get_index (data, GCRY_AC_FLAG_COPY, 0, NULL, &mpi_new);
-  if (err)
-    goto out;
-
-  *mpi = mpi_new;
-
- out:
-
-  return err;
-}
-
-/* Encrypts the plain text message contained in M, which is of size
-   M_N, with the public key KEY_PUBLIC according to the Encryption
-   Scheme SCHEME_ID.  HANDLE is used for accessing the low-level
-   cryptographic primitives.  If OPTS is not NULL, it has to be an
-   anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
-   The encrypted message will be stored in C and C_N.  */
-gcry_error_t
-_gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
-                             gcry_ac_scheme_t scheme_id,
-                             unsigned int flags, void *opts,
-                             gcry_ac_key_t key,
-                             gcry_ac_io_t *io_message,
-                             gcry_ac_io_t *io_cipher)
-{
-  gcry_error_t err;
-  gcry_ac_io_t io_em;
-  unsigned char *em;
-  size_t em_n;
-  gcry_mpi_t mpi_plain;
-  gcry_ac_data_t data_encrypted;
-  gcry_mpi_t mpi_encrypted;
-  unsigned char *buffer;
-  size_t buffer_n;
-  void *opts_em;
-  ac_scheme_t *scheme;
-
-  (void)flags;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  data_encrypted = NULL;
-  mpi_encrypted = NULL;
-  mpi_plain = NULL;
-  opts_em = NULL;
-  buffer = NULL;
-  em = NULL;
-
-  scheme = ac_scheme_get (scheme_id);
-  if (! scheme)
-    {
-      err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
-      goto out;
-    }
-
-  if (key->type != GCRY_AC_KEY_PUBLIC)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
-  if (err)
-    goto out;
-
-  _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
-                   GCRY_AC_IO_STRING, &em, &em_n);
-
-  err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
-                             io_message, &io_em);
-  if (err)
-    goto out;
-
-  mpi_plain = gcry_mpi_snew (0);
-  gcry_ac_os_to_mpi (mpi_plain, em, em_n);
-
-  err = _gcry_ac_data_encrypt (handle, 0, key, mpi_plain, &data_encrypted);
-  if (err)
-    goto out;
-
-  err = ac_data_set_to_mpi (data_encrypted, &mpi_encrypted);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_mpi_to_os_alloc (mpi_encrypted, &buffer, &buffer_n);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_io_write (io_cipher, buffer, buffer_n);
-
- out:
-
-  gcry_ac_data_destroy (data_encrypted);
-  gcry_mpi_release (mpi_encrypted);
-  gcry_mpi_release (mpi_plain);
-  gcry_free (opts_em);
-  gcry_free (buffer);
-  gcry_free (em);
-
-  return err;
-}
-
-/* Decryptes the cipher message contained in C, which is of size C_N,
-   with the secret key KEY_SECRET according to the Encryption Scheme
-   SCHEME_ID.  Handle is used for accessing the low-level
-   cryptographic primitives.  If OPTS is not NULL, it has to be an
-   anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
-   The decrypted message will be stored in M and M_N.  */
-gcry_error_t
-_gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
-                             gcry_ac_scheme_t scheme_id,
-                             unsigned int flags, void *opts,
-                             gcry_ac_key_t key,
-                             gcry_ac_io_t *io_cipher,
-                             gcry_ac_io_t *io_message)
-{
-  gcry_ac_io_t io_em;
-  gcry_error_t err;
-  gcry_ac_data_t data_encrypted;
-  unsigned char *em;
-  size_t em_n;
-  gcry_mpi_t mpi_encrypted;
-  gcry_mpi_t mpi_decrypted;
-  void *opts_em;
-  ac_scheme_t *scheme;
-  char *elements_enc;
-  size_t elements_enc_n;
-  unsigned char *c;
-  size_t c_n;
-
-  (void)flags;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  data_encrypted = NULL;
-  mpi_encrypted = NULL;
-  mpi_decrypted = NULL;
-  elements_enc = NULL;
-  opts_em = NULL;
-  em = NULL;
-  c = NULL;
-
-  scheme = ac_scheme_get (scheme_id);
-  if (! scheme)
-    {
-      err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
-      goto out;
-    }
-
-  if (key->type != GCRY_AC_KEY_SECRET)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  err = _gcry_ac_io_read_all (io_cipher, &c, &c_n);
-  if (err)
-    goto out;
-
-  mpi_encrypted = gcry_mpi_snew (0);
-  gcry_ac_os_to_mpi (mpi_encrypted, c, c_n);
-
-  err = _gcry_pk_get_elements (handle->algorithm, &elements_enc, NULL);
-  if (err)
-    goto out;
-
-  elements_enc_n = strlen (elements_enc);
-  if (elements_enc_n != 1)
-    {
-      /* FIXME? */
-      err = gcry_error (GPG_ERR_CONFLICT);
-      goto out;
-    }
-
-  err = _gcry_ac_data_new (&data_encrypted);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_set (data_encrypted, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
-                          elements_enc, mpi_encrypted);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_decrypt (handle, 0, key, &mpi_decrypted, data_encrypted);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_mpi_to_os_alloc (mpi_decrypted, &em, &em_n);
-  if (err)
-    goto out;
-
-  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
-  if (err)
-    goto out;
-
-  _gcry_ac_io_init (&io_em, GCRY_AC_IO_READABLE,
-                   GCRY_AC_IO_STRING, em, em_n);
-
-  err = _gcry_ac_data_decode (scheme->scheme_encoding, 0, opts_em,
-                             &io_em, io_message);
-  if (err)
-    goto out;
-
- out:
-  
-  _gcry_ac_data_destroy (data_encrypted);
-  gcry_mpi_release (mpi_encrypted);
-  gcry_mpi_release (mpi_decrypted);
-  free (elements_enc);
-  gcry_free (opts_em);
-  gcry_free (em);
-  gcry_free (c);
-
-  return err;
-}
-
-
-/* Signs the message contained in M, which is of size M_N, with the
-   secret key KEY according to the Signature Scheme SCHEME_ID.  Handle
-   is used for accessing the low-level cryptographic primitives.  If
-   OPTS is not NULL, it has to be an anonymous structure specific to
-   the chosen scheme (gcry_ac_ssa_*_t).  The signed message will be
-   stored in S and S_N.  */
-gcry_error_t
-_gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
-                          gcry_ac_scheme_t scheme_id,
-                          unsigned int flags, void *opts,
-                          gcry_ac_key_t key,
-                          gcry_ac_io_t *io_message,
-                          gcry_ac_io_t *io_signature)
-{
-  gcry_ac_io_t io_em;
-  gcry_error_t err;
-  gcry_ac_data_t data_signed;
-  unsigned char *em;
-  size_t em_n;
-  gcry_mpi_t mpi;
-  void *opts_em;
-  unsigned char *buffer;
-  size_t buffer_n;
-  gcry_mpi_t mpi_signed;
-  ac_scheme_t *scheme;
-
-  (void)flags;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  data_signed = NULL;
-  mpi_signed = NULL;
-  opts_em = NULL;
-  buffer = NULL;
-  mpi = NULL;
-  em = NULL;
-
-  if (key->type != GCRY_AC_KEY_SECRET)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  scheme = ac_scheme_get (scheme_id);
-  if (! scheme)
-    {
-      /* FIXME: adjust api of scheme_get in respect to err codes.  */
-      err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
-      goto out;
-    }
-
-  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
-  if (err)
-    goto out;
-
-  _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
-                   GCRY_AC_IO_STRING, &em, &em_n);
-
-  err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
-                             io_message, &io_em);
-  if (err)
-    goto out;
-
-  mpi = gcry_mpi_new (0);
-  _gcry_ac_os_to_mpi (mpi, em, em_n);
-
-  err = _gcry_ac_data_sign (handle, key, mpi, &data_signed);
-  if (err)
-    goto out;
-
-  err = ac_data_set_to_mpi (data_signed, &mpi_signed);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_mpi_to_os_alloc (mpi_signed, &buffer, &buffer_n);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_io_write (io_signature, buffer, buffer_n);
-
- out:
-
-  _gcry_ac_data_destroy (data_signed);
-  gcry_mpi_release (mpi_signed);
-  gcry_mpi_release (mpi);
-  gcry_free (opts_em);
-  gcry_free (buffer);
-  gcry_free (em);
-
-  return err;
-}
-
-/* Verifies that the signature contained in S, which is of length S_N,
-   is indeed the result of signing the message contained in M, which
-   is of size M_N, with the secret key belonging to the public key
-   KEY_PUBLIC.  If OPTS is not NULL, it has to be an anonymous
-   structure (gcry_ac_ssa_*_t) specific to the Signature Scheme, whose
-   ID is contained in SCHEME_ID.  */
-gcry_error_t
-_gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
-                            gcry_ac_scheme_t scheme_id,
-                            unsigned int flags, void *opts,
-                            gcry_ac_key_t key,
-                            gcry_ac_io_t *io_message,
-                            gcry_ac_io_t *io_signature)
-{
-  gcry_ac_io_t io_em;
-  gcry_error_t err;
-  gcry_ac_data_t data_signed;
-  unsigned char *em;
-  size_t em_n;
-  void *opts_em;
-  gcry_mpi_t mpi_signature;
-  gcry_mpi_t mpi_data;
-  ac_scheme_t *scheme;
-  char *elements_sig;
-  size_t elements_sig_n;
-  unsigned char *s;
-  size_t s_n;
-
-  (void)flags;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  mpi_signature = NULL;
-  elements_sig = NULL;
-  data_signed = NULL;
-  mpi_data = NULL;
-  opts_em = NULL;
-  em = NULL;
-  s = NULL;
-
-  if (key->type != GCRY_AC_KEY_PUBLIC)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  scheme = ac_scheme_get (scheme_id);
-  if (! scheme)
-    {
-      err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
-      goto out;
-    }
-
-  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
-  if (err)
-    goto out;
-
-  _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
-                   GCRY_AC_IO_STRING, &em, &em_n);
-
-  err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
-                             io_message, &io_em);
-  if (err)
-    goto out;
-
-  mpi_data = gcry_mpi_new (0);
-  _gcry_ac_os_to_mpi (mpi_data, em, em_n);
-
-  err = _gcry_ac_io_read_all (io_signature, &s, &s_n);
-  if (err)
-    goto out;
-
-  mpi_signature = gcry_mpi_new (0);
-  _gcry_ac_os_to_mpi (mpi_signature, s, s_n);
-
-  err = _gcry_pk_get_elements (handle->algorithm, NULL, &elements_sig);
-  if (err)
-    goto out;
-
-  elements_sig_n = strlen (elements_sig);
-  if (elements_sig_n != 1)
-    {
-      /* FIXME? */
-      err = gcry_error (GPG_ERR_CONFLICT);
-      goto out;
-    }
-
-  err = _gcry_ac_data_new (&data_signed);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_set (data_signed, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
-                          elements_sig, mpi_signature);
-  if (err)
-    goto out;
-
-  gcry_mpi_release (mpi_signature);
-  mpi_signature = NULL;
-  
-  err = _gcry_ac_data_verify (handle, key, mpi_data, data_signed);
-
- out:
-
-  _gcry_ac_data_destroy (data_signed);
-  gcry_mpi_release (mpi_signature);
-  gcry_mpi_release (mpi_data);
-  free (elements_sig);
-  gcry_free (opts_em);
-  gcry_free (em);
-  gcry_free (s);
-
-  return err;
-}
-
-
-/* 
- * General functions.
- */
-
-gcry_err_code_t
-_gcry_ac_init (void)
-{
-  if (fips_mode ())
-    return GPG_ERR_NOT_SUPPORTED;
-
-  return 0;
-}
diff --git a/lib/libgcrypt/cipher/arcfour.c b/lib/libgcrypt/cipher/arcfour.c
deleted file mode 100644 (file)
index 6bb0555..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/* arcfour.c  -  The arcfour stream cipher
- *     Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * For a description of the algorithm, see:
- *   Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
- *   ISBN 0-471-11709-9. Pages 397 ff.
- */
-
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "types.h"
-#include "g10lib.h"
-#include "cipher.h"
-
-static const char *selftest(void);
-
-typedef struct {
-    int idx_i, idx_j;
-    byte sbox[256];
-} ARCFOUR_context;
-
-static void
-do_encrypt_stream( ARCFOUR_context *ctx,
-                  byte *outbuf, const byte *inbuf, unsigned int length )
-{
-  register int i = ctx->idx_i;
-  register int j = ctx->idx_j;
-  register byte *sbox = ctx->sbox;
-  register int t;  
-
-  while ( length-- )
-    {
-      i++;
-      i = i & 255; /* The and-op seems to be faster than the mod-op. */
-      j += sbox[i];
-      j &= 255;
-      t = sbox[i]; sbox[i] = sbox[j]; sbox[j] = t;
-      *outbuf++ = *inbuf++ ^ sbox[(sbox[i] + sbox[j]) & 255];
-    }
-  
-  ctx->idx_i = i;
-  ctx->idx_j = j;
-}
-
-static void
-encrypt_stream (void *context,
-                byte *outbuf, const byte *inbuf, unsigned int length)
-{
-  ARCFOUR_context *ctx = (ARCFOUR_context *) context;
-  do_encrypt_stream (ctx, outbuf, inbuf, length );
-  _gcry_burn_stack (64);
-}
-
-
-static gcry_err_code_t
-do_arcfour_setkey (void *context, const byte *key, unsigned int keylen)
-{
-  static int initialized;
-  static const char* selftest_failed;
-  int i, j;
-  byte karr[256];
-  ARCFOUR_context *ctx = (ARCFOUR_context *) context;
-
-  if (!initialized ) 
-    {
-      initialized = 1;
-      selftest_failed = selftest();
-      if( selftest_failed )
-        log_error ("ARCFOUR selftest failed (%s)\n", selftest_failed );
-    }
-  if( selftest_failed )
-    return GPG_ERR_SELFTEST_FAILED;
-
-  if( keylen < 40/8 ) /* we want at least 40 bits */
-    return GPG_ERR_INV_KEYLEN;
-
-  ctx->idx_i = ctx->idx_j = 0;
-  for (i=0; i < 256; i++ )
-    ctx->sbox[i] = i;
-  for (i=0; i < 256; i++ )
-    karr[i] = key[i%keylen];
-  for (i=j=0; i < 256; i++ ) 
-    {
-      int t;
-      j = (j + ctx->sbox[i] + karr[i]) % 256;
-      t = ctx->sbox[i];
-      ctx->sbox[i] = ctx->sbox[j];
-      ctx->sbox[j] = t;
-    } 
-  memset( karr, 0, 256 );
-
-  return GPG_ERR_NO_ERROR;
-}
-
-static gcry_err_code_t
-arcfour_setkey ( void *context, const byte *key, unsigned int keylen )
-{
-  ARCFOUR_context *ctx = (ARCFOUR_context *) context;
-  gcry_err_code_t rc = do_arcfour_setkey (ctx, key, keylen );
-  _gcry_burn_stack (300);
-  return rc;
-}
-
-
-static const char*
-selftest(void)
-{
-  ARCFOUR_context ctx;
-  byte scratch[16];       
-    
-  /* Test vector from Cryptlib labeled there: "from the
-     State/Commerce Department". */
-  static byte key_1[] =
-    { 0x61, 0x8A, 0x63, 0xD2, 0xFB };
-  static byte plaintext_1[] =
-    { 0xDC, 0xEE, 0x4C, 0xF9, 0x2C };
-  static const byte ciphertext_1[] =
-    { 0xF1, 0x38, 0x29, 0xC9, 0xDE };
-
-  arcfour_setkey( &ctx, key_1, sizeof(key_1));
-  encrypt_stream( &ctx, scratch, plaintext_1, sizeof(plaintext_1));
-  if ( memcmp (scratch, ciphertext_1, sizeof (ciphertext_1)))
-    return "Arcfour encryption test 1 failed.";
-  arcfour_setkey( &ctx, key_1, sizeof(key_1));
-  encrypt_stream(&ctx, scratch, scratch, sizeof(plaintext_1)); /* decrypt */
-  if ( memcmp (scratch, plaintext_1, sizeof (plaintext_1)))
-    return "Arcfour decryption test 1 failed.";
-  return NULL;
-}
-
-
-gcry_cipher_spec_t _gcry_cipher_spec_arcfour =
-  {
-    "ARCFOUR", NULL, NULL, 1, 128, sizeof (ARCFOUR_context),
-    arcfour_setkey, NULL, NULL, encrypt_stream, encrypt_stream,
-  };
-
diff --git a/lib/libgcrypt/cipher/bithelp.h b/lib/libgcrypt/cipher/bithelp.h
deleted file mode 100644 (file)
index 1505324..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* bithelp.h  -  Some bit manipulation helpers
- *     Copyright (C) 1999, 2002 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef G10_BITHELP_H
-#define G10_BITHELP_H
-
-
-/****************
- * Rotate the 32 bit unsigned integer X by N bits left/right
- */
-#if defined(__GNUC__) && defined(__i386__)
-static inline u32
-rol( u32 x, int n)
-{
-       __asm__("roll %%cl,%0"
-               :"=r" (x)
-               :"0" (x),"c" (n));
-       return x;
-}
-#else
-#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
-#endif
-
-#if defined(__GNUC__) && defined(__i386__)
-static inline u32
-ror(u32 x, int n)
-{
-       __asm__("rorl %%cl,%0"
-               :"=r" (x)
-               :"0" (x),"c" (n));
-       return x;
-}
-#else
-#define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) )
-#endif
-
-
-#endif /*G10_BITHELP_H*/
diff --git a/lib/libgcrypt/cipher/blowfish.c b/lib/libgcrypt/cipher/blowfish.c
deleted file mode 100644 (file)
index 6ef68e3..0000000
+++ /dev/null
@@ -1,605 +0,0 @@
-/* blowfish.c  -  Blowfish encryption
- *     Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * For a description of the algorithm, see:
- *   Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
- *   ISBN 0-471-11709-9. Pages 336 ff.
- */
-
-/* Test values:
- * key   "abcdefghijklmnopqrstuvwxyz";
- * plain  "BLOWFISH"
- * cipher 32 4E D0 FE F4 13 A2 03
- *
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "types.h"
-#include "g10lib.h"
-#include "cipher.h"
-
-#define BLOWFISH_BLOCKSIZE 8
-#define BLOWFISH_ROUNDS 16
-
-typedef struct {
-    u32 s0[256];
-    u32 s1[256];
-    u32 s2[256];
-    u32 s3[256];
-    u32 p[BLOWFISH_ROUNDS+2];
-} BLOWFISH_context;
-
-static gcry_err_code_t bf_setkey (void *c, const byte *key, unsigned keylen);
-static void encrypt_block (void *bc, byte *outbuf, const byte *inbuf);
-static void decrypt_block (void *bc, byte *outbuf, const byte *inbuf);
-
-
-/* precomputed S boxes */
-static const u32 ks0[256] = {
-    0xD1310BA6,0x98DFB5AC,0x2FFD72DB,0xD01ADFB7,0xB8E1AFED,0x6A267E96,
-    0xBA7C9045,0xF12C7F99,0x24A19947,0xB3916CF7,0x0801F2E2,0x858EFC16,
-    0x636920D8,0x71574E69,0xA458FEA3,0xF4933D7E,0x0D95748F,0x728EB658,
-    0x718BCD58,0x82154AEE,0x7B54A41D,0xC25A59B5,0x9C30D539,0x2AF26013,
-    0xC5D1B023,0x286085F0,0xCA417918,0xB8DB38EF,0x8E79DCB0,0x603A180E,
-    0x6C9E0E8B,0xB01E8A3E,0xD71577C1,0xBD314B27,0x78AF2FDA,0x55605C60,
-    0xE65525F3,0xAA55AB94,0x57489862,0x63E81440,0x55CA396A,0x2AAB10B6,
-    0xB4CC5C34,0x1141E8CE,0xA15486AF,0x7C72E993,0xB3EE1411,0x636FBC2A,
-    0x2BA9C55D,0x741831F6,0xCE5C3E16,0x9B87931E,0xAFD6BA33,0x6C24CF5C,
-    0x7A325381,0x28958677,0x3B8F4898,0x6B4BB9AF,0xC4BFE81B,0x66282193,
-    0x61D809CC,0xFB21A991,0x487CAC60,0x5DEC8032,0xEF845D5D,0xE98575B1,
-    0xDC262302,0xEB651B88,0x23893E81,0xD396ACC5,0x0F6D6FF3,0x83F44239,
-    0x2E0B4482,0xA4842004,0x69C8F04A,0x9E1F9B5E,0x21C66842,0xF6E96C9A,
-    0x670C9C61,0xABD388F0,0x6A51A0D2,0xD8542F68,0x960FA728,0xAB5133A3,
-    0x6EEF0B6C,0x137A3BE4,0xBA3BF050,0x7EFB2A98,0xA1F1651D,0x39AF0176,
-    0x66CA593E,0x82430E88,0x8CEE8619,0x456F9FB4,0x7D84A5C3,0x3B8B5EBE,
-    0xE06F75D8,0x85C12073,0x401A449F,0x56C16AA6,0x4ED3AA62,0x363F7706,
-    0x1BFEDF72,0x429B023D,0x37D0D724,0xD00A1248,0xDB0FEAD3,0x49F1C09B,
-    0x075372C9,0x80991B7B,0x25D479D8,0xF6E8DEF7,0xE3FE501A,0xB6794C3B,
-    0x976CE0BD,0x04C006BA,0xC1A94FB6,0x409F60C4,0x5E5C9EC2,0x196A2463,
-    0x68FB6FAF,0x3E6C53B5,0x1339B2EB,0x3B52EC6F,0x6DFC511F,0x9B30952C,
-    0xCC814544,0xAF5EBD09,0xBEE3D004,0xDE334AFD,0x660F2807,0x192E4BB3,
-    0xC0CBA857,0x45C8740F,0xD20B5F39,0xB9D3FBDB,0x5579C0BD,0x1A60320A,
-    0xD6A100C6,0x402C7279,0x679F25FE,0xFB1FA3CC,0x8EA5E9F8,0xDB3222F8,
-    0x3C7516DF,0xFD616B15,0x2F501EC8,0xAD0552AB,0x323DB5FA,0xFD238760,
-    0x53317B48,0x3E00DF82,0x9E5C57BB,0xCA6F8CA0,0x1A87562E,0xDF1769DB,
-    0xD542A8F6,0x287EFFC3,0xAC6732C6,0x8C4F5573,0x695B27B0,0xBBCA58C8,
-    0xE1FFA35D,0xB8F011A0,0x10FA3D98,0xFD2183B8,0x4AFCB56C,0x2DD1D35B,
-    0x9A53E479,0xB6F84565,0xD28E49BC,0x4BFB9790,0xE1DDF2DA,0xA4CB7E33,
-    0x62FB1341,0xCEE4C6E8,0xEF20CADA,0x36774C01,0xD07E9EFE,0x2BF11FB4,
-    0x95DBDA4D,0xAE909198,0xEAAD8E71,0x6B93D5A0,0xD08ED1D0,0xAFC725E0,
-    0x8E3C5B2F,0x8E7594B7,0x8FF6E2FB,0xF2122B64,0x8888B812,0x900DF01C,
-    0x4FAD5EA0,0x688FC31C,0xD1CFF191,0xB3A8C1AD,0x2F2F2218,0xBE0E1777,
-    0xEA752DFE,0x8B021FA1,0xE5A0CC0F,0xB56F74E8,0x18ACF3D6,0xCE89E299,
-    0xB4A84FE0,0xFD13E0B7,0x7CC43B81,0xD2ADA8D9,0x165FA266,0x80957705,
-    0x93CC7314,0x211A1477,0xE6AD2065,0x77B5FA86,0xC75442F5,0xFB9D35CF,
-    0xEBCDAF0C,0x7B3E89A0,0xD6411BD3,0xAE1E7E49,0x00250E2D,0x2071B35E,
-    0x226800BB,0x57B8E0AF,0x2464369B,0xF009B91E,0x5563911D,0x59DFA6AA,
-    0x78C14389,0xD95A537F,0x207D5BA2,0x02E5B9C5,0x83260376,0x6295CFA9,
-    0x11C81968,0x4E734A41,0xB3472DCA,0x7B14A94A,0x1B510052,0x9A532915,
-    0xD60F573F,0xBC9BC6E4,0x2B60A476,0x81E67400,0x08BA6FB5,0x571BE91F,
-    0xF296EC6B,0x2A0DD915,0xB6636521,0xE7B9F9B6,0xFF34052E,0xC5855664,
-    0x53B02D5D,0xA99F8FA1,0x08BA4799,0x6E85076A };
-
-static const u32 ks1[256] = {
-    0x4B7A70E9,0xB5B32944,0xDB75092E,0xC4192623,0xAD6EA6B0,0x49A7DF7D,
-    0x9CEE60B8,0x8FEDB266,0xECAA8C71,0x699A17FF,0x5664526C,0xC2B19EE1,
-    0x193602A5,0x75094C29,0xA0591340,0xE4183A3E,0x3F54989A,0x5B429D65,
-    0x6B8FE4D6,0x99F73FD6,0xA1D29C07,0xEFE830F5,0x4D2D38E6,0xF0255DC1,
-    0x4CDD2086,0x8470EB26,0x6382E9C6,0x021ECC5E,0x09686B3F,0x3EBAEFC9,
-    0x3C971814,0x6B6A70A1,0x687F3584,0x52A0E286,0xB79C5305,0xAA500737,
-    0x3E07841C,0x7FDEAE5C,0x8E7D44EC,0x5716F2B8,0xB03ADA37,0xF0500C0D,
-    0xF01C1F04,0x0200B3FF,0xAE0CF51A,0x3CB574B2,0x25837A58,0xDC0921BD,
-    0xD19113F9,0x7CA92FF6,0x94324773,0x22F54701,0x3AE5E581,0x37C2DADC,
-    0xC8B57634,0x9AF3DDA7,0xA9446146,0x0FD0030E,0xECC8C73E,0xA4751E41,
-    0xE238CD99,0x3BEA0E2F,0x3280BBA1,0x183EB331,0x4E548B38,0x4F6DB908,
-    0x6F420D03,0xF60A04BF,0x2CB81290,0x24977C79,0x5679B072,0xBCAF89AF,
-    0xDE9A771F,0xD9930810,0xB38BAE12,0xDCCF3F2E,0x5512721F,0x2E6B7124,
-    0x501ADDE6,0x9F84CD87,0x7A584718,0x7408DA17,0xBC9F9ABC,0xE94B7D8C,
-    0xEC7AEC3A,0xDB851DFA,0x63094366,0xC464C3D2,0xEF1C1847,0x3215D908,
-    0xDD433B37,0x24C2BA16,0x12A14D43,0x2A65C451,0x50940002,0x133AE4DD,
-    0x71DFF89E,0x10314E55,0x81AC77D6,0x5F11199B,0x043556F1,0xD7A3C76B,
-    0x3C11183B,0x5924A509,0xF28FE6ED,0x97F1FBFA,0x9EBABF2C,0x1E153C6E,
-    0x86E34570,0xEAE96FB1,0x860E5E0A,0x5A3E2AB3,0x771FE71C,0x4E3D06FA,
-    0x2965DCB9,0x99E71D0F,0x803E89D6,0x5266C825,0x2E4CC978,0x9C10B36A,
-    0xC6150EBA,0x94E2EA78,0xA5FC3C53,0x1E0A2DF4,0xF2F74EA7,0x361D2B3D,
-    0x1939260F,0x19C27960,0x5223A708,0xF71312B6,0xEBADFE6E,0xEAC31F66,
-    0xE3BC4595,0xA67BC883,0xB17F37D1,0x018CFF28,0xC332DDEF,0xBE6C5AA5,
-    0x65582185,0x68AB9802,0xEECEA50F,0xDB2F953B,0x2AEF7DAD,0x5B6E2F84,
-    0x1521B628,0x29076170,0xECDD4775,0x619F1510,0x13CCA830,0xEB61BD96,
-    0x0334FE1E,0xAA0363CF,0xB5735C90,0x4C70A239,0xD59E9E0B,0xCBAADE14,
-    0xEECC86BC,0x60622CA7,0x9CAB5CAB,0xB2F3846E,0x648B1EAF,0x19BDF0CA,
-    0xA02369B9,0x655ABB50,0x40685A32,0x3C2AB4B3,0x319EE9D5,0xC021B8F7,
-    0x9B540B19,0x875FA099,0x95F7997E,0x623D7DA8,0xF837889A,0x97E32D77,
-    0x11ED935F,0x16681281,0x0E358829,0xC7E61FD6,0x96DEDFA1,0x7858BA99,
-    0x57F584A5,0x1B227263,0x9B83C3FF,0x1AC24696,0xCDB30AEB,0x532E3054,
-    0x8FD948E4,0x6DBC3128,0x58EBF2EF,0x34C6FFEA,0xFE28ED61,0xEE7C3C73,
-    0x5D4A14D9,0xE864B7E3,0x42105D14,0x203E13E0,0x45EEE2B6,0xA3AAABEA,
-    0xDB6C4F15,0xFACB4FD0,0xC742F442,0xEF6ABBB5,0x654F3B1D,0x41CD2105,
-    0xD81E799E,0x86854DC7,0xE44B476A,0x3D816250,0xCF62A1F2,0x5B8D2646,
-    0xFC8883A0,0xC1C7B6A3,0x7F1524C3,0x69CB7492,0x47848A0B,0x5692B285,
-    0x095BBF00,0xAD19489D,0x1462B174,0x23820E00,0x58428D2A,0x0C55F5EA,
-    0x1DADF43E,0x233F7061,0x3372F092,0x8D937E41,0xD65FECF1,0x6C223BDB,
-    0x7CDE3759,0xCBEE7460,0x4085F2A7,0xCE77326E,0xA6078084,0x19F8509E,
-    0xE8EFD855,0x61D99735,0xA969A7AA,0xC50C06C2,0x5A04ABFC,0x800BCADC,
-    0x9E447A2E,0xC3453484,0xFDD56705,0x0E1E9EC9,0xDB73DBD3,0x105588CD,
-    0x675FDA79,0xE3674340,0xC5C43465,0x713E38D8,0x3D28F89E,0xF16DFF20,
-    0x153E21E7,0x8FB03D4A,0xE6E39F2B,0xDB83ADF7 };
-
-static const u32 ks2[256] = {
-    0xE93D5A68,0x948140F7,0xF64C261C,0x94692934,0x411520F7,0x7602D4F7,
-    0xBCF46B2E,0xD4A20068,0xD4082471,0x3320F46A,0x43B7D4B7,0x500061AF,
-    0x1E39F62E,0x97244546,0x14214F74,0xBF8B8840,0x4D95FC1D,0x96B591AF,
-    0x70F4DDD3,0x66A02F45,0xBFBC09EC,0x03BD9785,0x7FAC6DD0,0x31CB8504,
-    0x96EB27B3,0x55FD3941,0xDA2547E6,0xABCA0A9A,0x28507825,0x530429F4,
-    0x0A2C86DA,0xE9B66DFB,0x68DC1462,0xD7486900,0x680EC0A4,0x27A18DEE,
-    0x4F3FFEA2,0xE887AD8C,0xB58CE006,0x7AF4D6B6,0xAACE1E7C,0xD3375FEC,
-    0xCE78A399,0x406B2A42,0x20FE9E35,0xD9F385B9,0xEE39D7AB,0x3B124E8B,
-    0x1DC9FAF7,0x4B6D1856,0x26A36631,0xEAE397B2,0x3A6EFA74,0xDD5B4332,
-    0x6841E7F7,0xCA7820FB,0xFB0AF54E,0xD8FEB397,0x454056AC,0xBA489527,
-    0x55533A3A,0x20838D87,0xFE6BA9B7,0xD096954B,0x55A867BC,0xA1159A58,
-    0xCCA92963,0x99E1DB33,0xA62A4A56,0x3F3125F9,0x5EF47E1C,0x9029317C,
-    0xFDF8E802,0x04272F70,0x80BB155C,0x05282CE3,0x95C11548,0xE4C66D22,
-    0x48C1133F,0xC70F86DC,0x07F9C9EE,0x41041F0F,0x404779A4,0x5D886E17,
-    0x325F51EB,0xD59BC0D1,0xF2BCC18F,0x41113564,0x257B7834,0x602A9C60,
-    0xDFF8E8A3,0x1F636C1B,0x0E12B4C2,0x02E1329E,0xAF664FD1,0xCAD18115,
-    0x6B2395E0,0x333E92E1,0x3B240B62,0xEEBEB922,0x85B2A20E,0xE6BA0D99,
-    0xDE720C8C,0x2DA2F728,0xD0127845,0x95B794FD,0x647D0862,0xE7CCF5F0,
-    0x5449A36F,0x877D48FA,0xC39DFD27,0xF33E8D1E,0x0A476341,0x992EFF74,
-    0x3A6F6EAB,0xF4F8FD37,0xA812DC60,0xA1EBDDF8,0x991BE14C,0xDB6E6B0D,
-    0xC67B5510,0x6D672C37,0x2765D43B,0xDCD0E804,0xF1290DC7,0xCC00FFA3,
-    0xB5390F92,0x690FED0B,0x667B9FFB,0xCEDB7D9C,0xA091CF0B,0xD9155EA3,
-    0xBB132F88,0x515BAD24,0x7B9479BF,0x763BD6EB,0x37392EB3,0xCC115979,
-    0x8026E297,0xF42E312D,0x6842ADA7,0xC66A2B3B,0x12754CCC,0x782EF11C,
-    0x6A124237,0xB79251E7,0x06A1BBE6,0x4BFB6350,0x1A6B1018,0x11CAEDFA,
-    0x3D25BDD8,0xE2E1C3C9,0x44421659,0x0A121386,0xD90CEC6E,0xD5ABEA2A,
-    0x64AF674E,0xDA86A85F,0xBEBFE988,0x64E4C3FE,0x9DBC8057,0xF0F7C086,
-    0x60787BF8,0x6003604D,0xD1FD8346,0xF6381FB0,0x7745AE04,0xD736FCCC,
-    0x83426B33,0xF01EAB71,0xB0804187,0x3C005E5F,0x77A057BE,0xBDE8AE24,
-    0x55464299,0xBF582E61,0x4E58F48F,0xF2DDFDA2,0xF474EF38,0x8789BDC2,
-    0x5366F9C3,0xC8B38E74,0xB475F255,0x46FCD9B9,0x7AEB2661,0x8B1DDF84,
-    0x846A0E79,0x915F95E2,0x466E598E,0x20B45770,0x8CD55591,0xC902DE4C,
-    0xB90BACE1,0xBB8205D0,0x11A86248,0x7574A99E,0xB77F19B6,0xE0A9DC09,
-    0x662D09A1,0xC4324633,0xE85A1F02,0x09F0BE8C,0x4A99A025,0x1D6EFE10,
-    0x1AB93D1D,0x0BA5A4DF,0xA186F20F,0x2868F169,0xDCB7DA83,0x573906FE,
-    0xA1E2CE9B,0x4FCD7F52,0x50115E01,0xA70683FA,0xA002B5C4,0x0DE6D027,
-    0x9AF88C27,0x773F8641,0xC3604C06,0x61A806B5,0xF0177A28,0xC0F586E0,
-    0x006058AA,0x30DC7D62,0x11E69ED7,0x2338EA63,0x53C2DD94,0xC2C21634,
-    0xBBCBEE56,0x90BCB6DE,0xEBFC7DA1,0xCE591D76,0x6F05E409,0x4B7C0188,
-    0x39720A3D,0x7C927C24,0x86E3725F,0x724D9DB9,0x1AC15BB4,0xD39EB8FC,
-    0xED545578,0x08FCA5B5,0xD83D7CD3,0x4DAD0FC4,0x1E50EF5E,0xB161E6F8,
-    0xA28514D9,0x6C51133C,0x6FD5C7E7,0x56E14EC4,0x362ABFCE,0xDDC6C837,
-    0xD79A3234,0x92638212,0x670EFA8E,0x406000E0 };
-
-static const u32 ks3[256] = {
-    0x3A39CE37,0xD3FAF5CF,0xABC27737,0x5AC52D1B,0x5CB0679E,0x4FA33742,
-    0xD3822740,0x99BC9BBE,0xD5118E9D,0xBF0F7315,0xD62D1C7E,0xC700C47B,
-    0xB78C1B6B,0x21A19045,0xB26EB1BE,0x6A366EB4,0x5748AB2F,0xBC946E79,
-    0xC6A376D2,0x6549C2C8,0x530FF8EE,0x468DDE7D,0xD5730A1D,0x4CD04DC6,
-    0x2939BBDB,0xA9BA4650,0xAC9526E8,0xBE5EE304,0xA1FAD5F0,0x6A2D519A,
-    0x63EF8CE2,0x9A86EE22,0xC089C2B8,0x43242EF6,0xA51E03AA,0x9CF2D0A4,
-    0x83C061BA,0x9BE96A4D,0x8FE51550,0xBA645BD6,0x2826A2F9,0xA73A3AE1,
-    0x4BA99586,0xEF5562E9,0xC72FEFD3,0xF752F7DA,0x3F046F69,0x77FA0A59,
-    0x80E4A915,0x87B08601,0x9B09E6AD,0x3B3EE593,0xE990FD5A,0x9E34D797,
-    0x2CF0B7D9,0x022B8B51,0x96D5AC3A,0x017DA67D,0xD1CF3ED6,0x7C7D2D28,
-    0x1F9F25CF,0xADF2B89B,0x5AD6B472,0x5A88F54C,0xE029AC71,0xE019A5E6,
-    0x47B0ACFD,0xED93FA9B,0xE8D3C48D,0x283B57CC,0xF8D56629,0x79132E28,
-    0x785F0191,0xED756055,0xF7960E44,0xE3D35E8C,0x15056DD4,0x88F46DBA,
-    0x03A16125,0x0564F0BD,0xC3EB9E15,0x3C9057A2,0x97271AEC,0xA93A072A,
-    0x1B3F6D9B,0x1E6321F5,0xF59C66FB,0x26DCF319,0x7533D928,0xB155FDF5,
-    0x03563482,0x8ABA3CBB,0x28517711,0xC20AD9F8,0xABCC5167,0xCCAD925F,
-    0x4DE81751,0x3830DC8E,0x379D5862,0x9320F991,0xEA7A90C2,0xFB3E7BCE,
-    0x5121CE64,0x774FBE32,0xA8B6E37E,0xC3293D46,0x48DE5369,0x6413E680,
-    0xA2AE0810,0xDD6DB224,0x69852DFD,0x09072166,0xB39A460A,0x6445C0DD,
-    0x586CDECF,0x1C20C8AE,0x5BBEF7DD,0x1B588D40,0xCCD2017F,0x6BB4E3BB,
-    0xDDA26A7E,0x3A59FF45,0x3E350A44,0xBCB4CDD5,0x72EACEA8,0xFA6484BB,
-    0x8D6612AE,0xBF3C6F47,0xD29BE463,0x542F5D9E,0xAEC2771B,0xF64E6370,
-    0x740E0D8D,0xE75B1357,0xF8721671,0xAF537D5D,0x4040CB08,0x4EB4E2CC,
-    0x34D2466A,0x0115AF84,0xE1B00428,0x95983A1D,0x06B89FB4,0xCE6EA048,
-    0x6F3F3B82,0x3520AB82,0x011A1D4B,0x277227F8,0x611560B1,0xE7933FDC,
-    0xBB3A792B,0x344525BD,0xA08839E1,0x51CE794B,0x2F32C9B7,0xA01FBAC9,
-    0xE01CC87E,0xBCC7D1F6,0xCF0111C3,0xA1E8AAC7,0x1A908749,0xD44FBD9A,
-    0xD0DADECB,0xD50ADA38,0x0339C32A,0xC6913667,0x8DF9317C,0xE0B12B4F,
-    0xF79E59B7,0x43F5BB3A,0xF2D519FF,0x27D9459C,0xBF97222C,0x15E6FC2A,
-    0x0F91FC71,0x9B941525,0xFAE59361,0xCEB69CEB,0xC2A86459,0x12BAA8D1,
-    0xB6C1075E,0xE3056A0C,0x10D25065,0xCB03A442,0xE0EC6E0E,0x1698DB3B,
-    0x4C98A0BE,0x3278E964,0x9F1F9532,0xE0D392DF,0xD3A0342B,0x8971F21E,
-    0x1B0A7441,0x4BA3348C,0xC5BE7120,0xC37632D8,0xDF359F8D,0x9B992F2E,
-    0xE60B6F47,0x0FE3F11D,0xE54CDA54,0x1EDAD891,0xCE6279CF,0xCD3E7E6F,
-    0x1618B166,0xFD2C1D05,0x848FD2C5,0xF6FB2299,0xF523F357,0xA6327623,
-    0x93A83531,0x56CCCD02,0xACF08162,0x5A75EBB5,0x6E163697,0x88D273CC,
-    0xDE966292,0x81B949D0,0x4C50901B,0x71C65614,0xE6C6C7BD,0x327A140A,
-    0x45E1D006,0xC3F27B9A,0xC9AA53FD,0x62A80F00,0xBB25BFE2,0x35BDD2F6,
-    0x71126905,0xB2040222,0xB6CBCF7C,0xCD769C2B,0x53113EC0,0x1640E3D3,
-    0x38ABBD60,0x2547ADF0,0xBA38209C,0xF746CE76,0x77AFA1C5,0x20756060,
-    0x85CBFE4E,0x8AE88DD8,0x7AAAF9B0,0x4CF9AA7E,0x1948C25C,0x02FB8A8C,
-    0x01C36AE4,0xD6EBE1F9,0x90D4F869,0xA65CDEA0,0x3F09252D,0xC208E69F,
-    0xB74E6132,0xCE77E25B,0x578FDFE3,0x3AC372E6 };
-
-static const u32 ps[BLOWFISH_ROUNDS+2] = {
-    0x243F6A88,0x85A308D3,0x13198A2E,0x03707344,0xA4093822,0x299F31D0,
-    0x082EFA98,0xEC4E6C89,0x452821E6,0x38D01377,0xBE5466CF,0x34E90C6C,
-    0xC0AC29B7,0xC97C50DD,0x3F84D5B5,0xB5470917,0x9216D5D9,0x8979FB1B };
-
-
-
-#if BLOWFISH_ROUNDS != 16
-static inline u32
-function_F( BLOWFISH_context *bc, u32 x )
-{
-    u16 a, b, c, d;
-
-#ifdef WORDS_BIGENDIAN
-    a = ((byte*)&x)[0];
-    b = ((byte*)&x)[1];
-    c = ((byte*)&x)[2];
-    d = ((byte*)&x)[3];
-#else
-    a = ((byte*)&x)[3];
-    b = ((byte*)&x)[2];
-    c = ((byte*)&x)[1];
-    d = ((byte*)&x)[0];
-#endif
-
-    return ((bc->s0[a] + bc->s1[b]) ^ bc->s2[c] ) + bc->s3[d];
-}
-#endif
-
-#ifdef WORDS_BIGENDIAN
-#define F(x) ((( s0[((byte*)&x)[0]] + s1[((byte*)&x)[1]])       \
-                  ^ s2[((byte*)&x)[2]]) + s3[((byte*)&x)[3]] )
-#else
-#define F(x) ((( s0[((byte*)&x)[3]] + s1[((byte*)&x)[2]])       \
-                  ^ s2[((byte*)&x)[1]]) + s3[((byte*)&x)[0]] )
-#endif
-#define R(l,r,i)  do { l ^= p[i]; r ^= F(l); } while(0)
-
-
-static void
-do_encrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
-{
-#if BLOWFISH_ROUNDS == 16
-  u32 xl, xr, *s0, *s1, *s2, *s3, *p;
-
-  xl = *ret_xl;
-  xr = *ret_xr;
-  p = bc->p;
-  s0 = bc->s0;
-  s1 = bc->s1;
-  s2 = bc->s2;
-  s3 = bc->s3;
-
-  R( xl, xr,   0);
-  R( xr, xl,   1);
-  R( xl, xr,   2);
-  R( xr, xl,   3);
-  R( xl, xr,   4);
-  R( xr, xl,   5);
-  R( xl, xr,   6);
-  R( xr, xl,   7);
-  R( xl, xr,   8);
-  R( xr, xl,   9);
-  R( xl, xr, 10);
-  R( xr, xl, 11);
-  R( xl, xr, 12);
-  R( xr, xl, 13);
-  R( xl, xr, 14);
-  R( xr, xl, 15);
-
-  xl ^= p[BLOWFISH_ROUNDS];
-  xr ^= p[BLOWFISH_ROUNDS+1];
-
-  *ret_xl = xr;
-  *ret_xr = xl;
-
-#else
-  u32 xl, xr, temp, *p;
-  int i;
-
-  xl = *ret_xl;
-  xr = *ret_xr;
-  p = bc->p;
-
-  for(i=0; i < BLOWFISH_ROUNDS; i++ )
-    {
-      xl ^= p[i];
-      xr ^= function_F(bc, xl);
-      temp = xl;
-      xl = xr;
-      xr = temp;
-    }
-  temp = xl;
-  xl = xr;
-  xr = temp;
-
-  xr ^= p[BLOWFISH_ROUNDS];
-  xl ^= p[BLOWFISH_ROUNDS+1];
-
-  *ret_xl = xl;
-  *ret_xr = xr;
-#endif
-}
-
-
-static void
-decrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
-{
-#if BLOWFISH_ROUNDS == 16
-  u32 xl, xr, *s0, *s1, *s2, *s3, *p;
-
-  xl = *ret_xl;
-  xr = *ret_xr;
-  p = bc->p;
-  s0 = bc->s0;
-  s1 = bc->s1;
-  s2 = bc->s2;
-  s3 = bc->s3;
-
-  R( xl, xr, 17);
-  R( xr, xl, 16);
-  R( xl, xr, 15);
-  R( xr, xl, 14);
-  R( xl, xr, 13);
-  R( xr, xl, 12);
-  R( xl, xr, 11);
-  R( xr, xl, 10);
-  R( xl, xr,   9);
-  R( xr, xl,   8);
-  R( xl, xr,   7);
-  R( xr, xl,   6);
-  R( xl, xr,   5);
-  R( xr, xl,   4);
-  R( xl, xr,   3);
-  R( xr, xl,   2);
-
-  xl ^= p[1];
-  xr ^= p[0];
-
-  *ret_xl = xr;
-  *ret_xr = xl;
-
-#else
-  u32 xl, xr, temp, *p;
-  int i;
-
-  xl = *ret_xl;
-  xr = *ret_xr;
-  p = bc->p;
-
-  for (i=BLOWFISH_ROUNDS+1; i > 1; i-- )
-    {
-      xl ^= p[i];
-      xr ^= function_F(bc, xl);
-      temp = xl;
-      xl = xr;
-      xr = temp;
-    }
-
-  temp = xl;
-  xl = xr;
-  xr = temp;
-
-  xr ^= p[1];
-  xl ^= p[0];
-
-  *ret_xl = xl;
-  *ret_xr = xr;
-#endif
-}
-
-#undef F
-#undef R
-
-static void
-do_encrypt_block ( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf )
-{
-  u32 d1, d2;
-
-  d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
-  d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
-  do_encrypt( bc, &d1, &d2 );
-  outbuf[0] = (d1 >> 24) & 0xff;
-  outbuf[1] = (d1 >> 16) & 0xff;
-  outbuf[2] = (d1 >>   8) & 0xff;
-  outbuf[3] =  d1         & 0xff;
-  outbuf[4] = (d2 >> 24) & 0xff;
-  outbuf[5] = (d2 >> 16) & 0xff;
-  outbuf[6] = (d2 >>   8) & 0xff;
-  outbuf[7] =  d2         & 0xff;
-}
-
-static void
-encrypt_block (void *context, byte *outbuf, const byte *inbuf)
-{
-  BLOWFISH_context *bc = (BLOWFISH_context *) context;
-  do_encrypt_block (bc, outbuf, inbuf);
-  _gcry_burn_stack (64);
-}
-
-
-static void
-do_decrypt_block (BLOWFISH_context *bc, byte *outbuf, const byte *inbuf)
-{
-  u32 d1, d2;
-
-  d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
-  d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
-  decrypt( bc, &d1, &d2 );
-  outbuf[0] = (d1 >> 24) & 0xff;
-  outbuf[1] = (d1 >> 16) & 0xff;
-  outbuf[2] = (d1 >>   8) & 0xff;
-  outbuf[3] =  d1         & 0xff;
-  outbuf[4] = (d2 >> 24) & 0xff;
-  outbuf[5] = (d2 >> 16) & 0xff;
-  outbuf[6] = (d2 >>   8) & 0xff;
-  outbuf[7] =  d2         & 0xff;
-}
-
-static void
-decrypt_block (void *context, byte *outbuf, const byte *inbuf)
-{
-  BLOWFISH_context *bc = (BLOWFISH_context *) context;
-  do_decrypt_block (bc, outbuf, inbuf);
-  _gcry_burn_stack (64);
-}
-
-
-static const char*
-selftest(void)
-{
-  BLOWFISH_context c;
-  byte plain[] = "BLOWFISH";
-  byte buffer[8];
-  byte plain3[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 };
-  byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 };
-  byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 };
-
-  bf_setkey( (void *) &c,
-             (const unsigned char*)"abcdefghijklmnopqrstuvwxyz", 26 );
-  encrypt_block( (void *) &c, buffer, plain );
-  if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) )
-    return "Blowfish selftest failed (1).";
-  decrypt_block( (void *) &c, buffer, buffer );
-  if( memcmp( buffer, plain, 8 ) )
-    return "Blowfish selftest failed (2).";
-
-  bf_setkey( (void *) &c, key3, 8 );
-  encrypt_block( (void *) &c, buffer, plain3 );
-  if( memcmp( buffer, cipher3, 8 ) )
-    return "Blowfish selftest failed (3).";
-  decrypt_block( (void *) &c, buffer, buffer );
-  if( memcmp( buffer, plain3, 8 ) )
-    return "Blowfish selftest failed (4).";
-  return NULL;
-}
-
-
-
-static gcry_err_code_t
-do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen)
-{
-  int i, j;
-  u32 data, datal, datar;
-  static int initialized;
-  static const char *selftest_failed;
-
-  if( !initialized ) 
-    {
-      initialized = 1;
-      selftest_failed = selftest();
-      if( selftest_failed )
-        log_error ("%s\n", selftest_failed );
-    }
-  if( selftest_failed )
-    return GPG_ERR_SELFTEST_FAILED;
-
-  for(i=0; i < BLOWFISH_ROUNDS+2; i++ )
-    c->p[i] = ps[i];
-  for(i=0; i < 256; i++ ) 
-    {
-      c->s0[i] = ks0[i];
-      c->s1[i] = ks1[i];
-      c->s2[i] = ks2[i];
-      c->s3[i] = ks3[i];
-    }
-
-  for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ ) 
-    {
-#ifdef WORDS_BIGENDIAN
-      ((byte*)&data)[0] = key[j];
-      ((byte*)&data)[1] = key[(j+1)%keylen];
-      ((byte*)&data)[2] = key[(j+2)%keylen];
-      ((byte*)&data)[3] = key[(j+3)%keylen];
-#else
-      ((byte*)&data)[3] = key[j];
-      ((byte*)&data)[2] = key[(j+1)%keylen];
-      ((byte*)&data)[1] = key[(j+2)%keylen];
-      ((byte*)&data)[0] = key[(j+3)%keylen];
-#endif
-      c->p[i] ^= data;
-      j = (j+4) % keylen;
-    }
-
-  datal = datar = 0;
-  for(i=0; i < BLOWFISH_ROUNDS+2; i += 2 )
-    {
-      do_encrypt( c, &datal, &datar );
-      c->p[i]   = datal;
-      c->p[i+1] = datar;
-    }
-  for(i=0; i < 256; i += 2 )   
-    {
-      do_encrypt( c, &datal, &datar );
-      c->s0[i]   = datal;
-      c->s0[i+1] = datar;
-    }
-  for(i=0; i < 256; i += 2 )
-    {
-      do_encrypt( c, &datal, &datar );
-      c->s1[i]   = datal;
-      c->s1[i+1] = datar;
-    }
-  for(i=0; i < 256; i += 2 )
-    {
-      do_encrypt( c, &datal, &datar );
-      c->s2[i]   = datal;
-      c->s2[i+1] = datar;
-    }
-  for(i=0; i < 256; i += 2 )
-    {
-      do_encrypt( c, &datal, &datar );
-      c->s3[i]   = datal;
-      c->s3[i+1] = datar;
-    }
-
-
-  /* Check for weak key.  A weak key is a key in which a value in
-     the P-array (here c) occurs more than once per table.  */
-  for(i=0; i < 255; i++ )
-    {
-      for( j=i+1; j < 256; j++)
-        {
-          if( (c->s0[i] == c->s0[j]) || (c->s1[i] == c->s1[j]) ||
-              (c->s2[i] == c->s2[j]) || (c->s3[i] == c->s3[j]) )
-            return GPG_ERR_WEAK_KEY;
-        }
-    }
-
-  return GPG_ERR_NO_ERROR;
-}
-
-
-static gcry_err_code_t
-bf_setkey (void *context, const byte *key, unsigned keylen)
-{
-  BLOWFISH_context *c = (BLOWFISH_context *) context;
-  gcry_err_code_t rc = do_bf_setkey (c, key, keylen);
-  _gcry_burn_stack (64);
-  return rc;
-}
-
-
-gcry_cipher_spec_t _gcry_cipher_spec_blowfish =
-  {
-    "BLOWFISH", NULL, NULL, BLOWFISH_BLOCKSIZE, 128,
-    sizeof (BLOWFISH_context),
-    bf_setkey, encrypt_block, decrypt_block
-  };
diff --git a/lib/libgcrypt/cipher/camellia-glue.c b/lib/libgcrypt/cipher/camellia-glue.c
deleted file mode 100644 (file)
index 067af85..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/* camellia-glue.c - Glue for the Camellia cipher
- * Copyright (C) 2007 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/* I put all the libgcrypt-specific stuff in this file to keep the
-   camellia.c/camellia.h files exactly as provided by NTT.  If they
-   update their code, this should make it easier to bring the changes
-   in. - dshaw
-
-   There is one small change which needs to be done: Include the
-   following code at the top of camellia.h: */
-#if 0
-
-/* To use Camellia with libraries it is often useful to keep the name
- * space of the library clean.  The following macro is thus useful:
- *
- *     #define CAMELLIA_EXT_SYM_PREFIX foo_
- *  
- * This prefixes all external symbols with "foo_".
- */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#ifdef CAMELLIA_EXT_SYM_PREFIX
-#define CAMELLIA_PREFIX1(x,y) x ## y
-#define CAMELLIA_PREFIX2(x,y) CAMELLIA_PREFIX1(x,y)
-#define CAMELLIA_PREFIX(x)    CAMELLIA_PREFIX2(CAMELLIA_EXT_SYM_PREFIX,x)
-#define Camellia_Ekeygen      CAMELLIA_PREFIX(Camellia_Ekeygen)
-#define Camellia_EncryptBlock CAMELLIA_PREFIX(Camellia_EncryptBlock)
-#define Camellia_DecryptBlock CAMELLIA_PREFIX(Camellia_DecryptBlock)
-#define camellia_decrypt128   CAMELLIA_PREFIX(camellia_decrypt128)
-#define camellia_decrypt256   CAMELLIA_PREFIX(camellia_decrypt256)
-#define camellia_encrypt128   CAMELLIA_PREFIX(camellia_encrypt128)
-#define camellia_encrypt256   CAMELLIA_PREFIX(camellia_encrypt256)
-#define camellia_setup128     CAMELLIA_PREFIX(camellia_setup128)
-#define camellia_setup192     CAMELLIA_PREFIX(camellia_setup192) 
-#define camellia_setup256     CAMELLIA_PREFIX(camellia_setup256)
-#endif /*CAMELLIA_EXT_SYM_PREFIX*/
-
-#endif /* Code sample. */
-
-
-#include <config.h>
-#include "types.h"
-#include "g10lib.h"
-#include "cipher.h"
-#include "camellia.h"
-
-typedef struct
-{
-  int keybitlength;
-  KEY_TABLE_TYPE keytable;
-} CAMELLIA_context;
-
-static const char *selftest(void);
-
-static gcry_err_code_t
-camellia_setkey(void *c, const byte *key, unsigned keylen)
-{
-  CAMELLIA_context *ctx=c;
-  static int initialized=0;
-  static const char *selftest_failed=NULL;
-
-  if(keylen!=16 && keylen!=24 && keylen!=32)
-    return GPG_ERR_INV_KEYLEN;
-
-  if(!initialized)
-    {
-      initialized=1;
-      selftest_failed=selftest();
-      if(selftest_failed)
-       log_error("%s\n",selftest_failed);
-    }
-
-  if(selftest_failed)
-    return GPG_ERR_SELFTEST_FAILED;
-
-  ctx->keybitlength=keylen*8;
-  Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable);
-  _gcry_burn_stack
-    ((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */
-     +(4+32)*sizeof(u32)+2*sizeof(void*)    /* camellia_setup192 */
-     +0+sizeof(int)+2*sizeof(void*)         /* Camellia_Ekeygen */
-     +3*2*sizeof(void*)                     /* Function calls.  */
-     );  
-
-  return 0;
-}
-
-static void
-camellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
-{
-  CAMELLIA_context *ctx=c;
-
-  Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
-  _gcry_burn_stack
-    (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
-     +4*sizeof(u32)
-     +2*sizeof(u32*)+4*sizeof(u32)
-     +2*2*sizeof(void*) /* Function calls.  */
-    );
-}
-
-static void
-camellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
-{
-  CAMELLIA_context *ctx=c;
-
-  Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
-  _gcry_burn_stack
-    (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
-     +4*sizeof(u32)
-     +2*sizeof(u32*)+4*sizeof(u32)
-     +2*2*sizeof(void*) /* Function calls.  */
-    );
-}
-
-static const char *
-selftest(void)
-{
-  CAMELLIA_context ctx;
-  byte scratch[16];
-  
-  /* These test vectors are from RFC-3713 */
-  const byte plaintext[]=
-    {
-      0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
-      0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
-    };
-  const byte key_128[]=
-    {
-      0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
-      0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
-    };
-  const byte ciphertext_128[]=
-    {
-      0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,
-      0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43
-    };
-  const byte key_192[]=
-    {
-      0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,
-      0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77
-    };
-  const byte ciphertext_192[]=
-    {
-      0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,
-      0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9
-    };
-  const byte key_256[]=
-    {
-      0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,
-      0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,
-      0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
-    };
-  const byte ciphertext_256[]=
-    {
-      0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,
-      0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09
-    };
-
-  camellia_setkey(&ctx,key_128,sizeof(key_128));
-  camellia_encrypt(&ctx,scratch,plaintext);
-  if(memcmp(scratch,ciphertext_128,sizeof(ciphertext_128))!=0)
-    return "CAMELLIA-128 test encryption failed.";
-  camellia_decrypt(&ctx,scratch,scratch);
-  if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
-    return "CAMELLIA-128 test decryption failed.";
-
-  camellia_setkey(&ctx,key_192,sizeof(key_192));
-  camellia_encrypt(&ctx,scratch,plaintext);
-  if(memcmp(scratch,ciphertext_192,sizeof(ciphertext_192))!=0)
-    return "CAMELLIA-192 test encryption failed.";
-  camellia_decrypt(&ctx,scratch,scratch);
-  if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
-    return "CAMELLIA-192 test decryption failed.";
-
-  camellia_setkey(&ctx,key_256,sizeof(key_256));
-  camellia_encrypt(&ctx,scratch,plaintext);
-  if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0)
-    return "CAMELLIA-256 test encryption failed.";
-  camellia_decrypt(&ctx,scratch,scratch);
-  if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
-    return "CAMELLIA-256 test decryption failed.";
-
-  return NULL;
-}
-
-/* These oids are from
-   <http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications_oid.html>,
-   retrieved May 1, 2007. */
-
-static gcry_cipher_oid_spec_t camellia128_oids[] =
-  {
-    {"1.2.392.200011.61.1.1.1.2", GCRY_CIPHER_MODE_CBC},
-    {"0.3.4401.5.3.1.9.1", GCRY_CIPHER_MODE_ECB},
-    {"0.3.4401.5.3.1.9.3", GCRY_CIPHER_MODE_OFB},
-    {"0.3.4401.5.3.1.9.4", GCRY_CIPHER_MODE_CFB},
-    { NULL }
-  };
-
-static gcry_cipher_oid_spec_t camellia192_oids[] =
-  {
-    {"1.2.392.200011.61.1.1.1.3", GCRY_CIPHER_MODE_CBC},
-    {"0.3.4401.5.3.1.9.21", GCRY_CIPHER_MODE_ECB},
-    {"0.3.4401.5.3.1.9.23", GCRY_CIPHER_MODE_OFB},
-    {"0.3.4401.5.3.1.9.24", GCRY_CIPHER_MODE_CFB},
-    { NULL }
-  };
-
-static gcry_cipher_oid_spec_t camellia256_oids[] =
-  {
-    {"1.2.392.200011.61.1.1.1.4", GCRY_CIPHER_MODE_CBC},
-    {"0.3.4401.5.3.1.9.41", GCRY_CIPHER_MODE_ECB},
-    {"0.3.4401.5.3.1.9.43", GCRY_CIPHER_MODE_OFB},
-    {"0.3.4401.5.3.1.9.44", GCRY_CIPHER_MODE_CFB},
-    { NULL }
-  };
-
-gcry_cipher_spec_t _gcry_cipher_spec_camellia128 =
-  {
-    "CAMELLIA128",NULL,camellia128_oids,CAMELLIA_BLOCK_SIZE,128,
-    sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
-  };
-
-gcry_cipher_spec_t _gcry_cipher_spec_camellia192 =
-  {
-    "CAMELLIA192",NULL,camellia192_oids,CAMELLIA_BLOCK_SIZE,192,
-    sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
-  };
-
-gcry_cipher_spec_t _gcry_cipher_spec_camellia256 =
-  {
-    "CAMELLIA256",NULL,camellia256_oids,CAMELLIA_BLOCK_SIZE,256,
-    sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
-  };
diff --git a/lib/libgcrypt/cipher/camellia.c b/lib/libgcrypt/cipher/camellia.c
deleted file mode 100644 (file)
index 79cd49b..0000000
+++ /dev/null
@@ -1,1461 +0,0 @@
-/* camellia.h  ver 1.2.0
- *
- * Copyright (C) 2006,2007
- * NTT (Nippon Telegraph and Telephone Corporation).
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-/*
- * Algorithm Specification 
- *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
- */
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "camellia.h"
-
-/* u32 must be 32bit word */
-typedef unsigned int u32;
-typedef unsigned char u8;
-
-/* key constants */
-
-#define CAMELLIA_SIGMA1L (0xA09E667FL)
-#define CAMELLIA_SIGMA1R (0x3BCC908BL)
-#define CAMELLIA_SIGMA2L (0xB67AE858L)
-#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
-#define CAMELLIA_SIGMA3L (0xC6EF372FL)
-#define CAMELLIA_SIGMA3R (0xE94F82BEL)
-#define CAMELLIA_SIGMA4L (0x54FF53A5L)
-#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
-#define CAMELLIA_SIGMA5L (0x10E527FAL)
-#define CAMELLIA_SIGMA5R (0xDE682D1DL)
-#define CAMELLIA_SIGMA6L (0xB05688C2L)
-#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
-
-/*
- *  macros
- */
-
-
-#if defined(_MSC_VER)
-
-# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
-# define GETU32(p) SWAP(*((u32 *)(p)))
-# define PUTU32(ct, st) {*((u32 *)(ct)) = SWAP((st));}
-
-#else /* not MS-VC */
-
-# define GETU32(pt)                            \
-    (((u32)(pt)[0] << 24)                      \
-     ^ ((u32)(pt)[1] << 16)                    \
-     ^ ((u32)(pt)[2] <<  8)                    \
-     ^ ((u32)(pt)[3]))
-
-# define PUTU32(ct, st)  {                     \
-       (ct)[0] = (u8)((st) >> 24);             \
-       (ct)[1] = (u8)((st) >> 16);             \
-       (ct)[2] = (u8)((st) >>  8);             \
-       (ct)[3] = (u8)(st); }
-
-#endif
-
-#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])
-#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])
-
-/* rotation right shift 1byte */
-#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
-/* rotation left shift 1bit */
-#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
-/* rotation left shift 1byte */
-#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
-
-#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits)   \
-    do {                                               \
-       w0 = ll;                                        \
-       ll = (ll << bits) + (lr >> (32 - bits));        \
-       lr = (lr << bits) + (rl >> (32 - bits));        \
-       rl = (rl << bits) + (rr >> (32 - bits));        \
-       rr = (rr << bits) + (w0 >> (32 - bits));        \
-    } while(0)
-
-#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits)        \
-    do {                                               \
-       w0 = ll;                                        \
-       w1 = lr;                                        \
-       ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
-       lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
-       rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
-       rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
-    } while(0)
-
-#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
-#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
-#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
-#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
-
-#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)     \
-    do {                                                       \
-       il = xl ^ kl;                                           \
-       ir = xr ^ kr;                                           \
-       t0 = il >> 16;                                          \
-       t1 = ir >> 16;                                          \
-       yl = CAMELLIA_SP1110(ir & 0xff)                         \
-           ^ CAMELLIA_SP0222((t1 >> 8) & 0xff)                 \
-           ^ CAMELLIA_SP3033(t1 & 0xff)                        \
-           ^ CAMELLIA_SP4404((ir >> 8) & 0xff);                \
-       yr = CAMELLIA_SP1110((t0 >> 8) & 0xff)                  \
-           ^ CAMELLIA_SP0222(t0 & 0xff)                        \
-           ^ CAMELLIA_SP3033((il >> 8) & 0xff)                 \
-           ^ CAMELLIA_SP4404(il & 0xff);                       \
-       yl ^= yr;                                               \
-       yr = CAMELLIA_RR8(yr);                                  \
-       yr ^= yl;                                               \
-    } while(0)
-
-
-/*
- * for speed up
- *
- */
-#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
-    do {                                                               \
-       t0 = kll;                                                       \
-       t0 &= ll;                                                       \
-       lr ^= CAMELLIA_RL1(t0);                                         \
-       t1 = klr;                                                       \
-       t1 |= lr;                                                       \
-       ll ^= t1;                                                       \
-                                                                       \
-       t2 = krr;                                                       \
-       t2 |= rr;                                                       \
-       rl ^= t2;                                                       \
-       t3 = krl;                                                       \
-       t3 &= rl;                                                       \
-       rr ^= CAMELLIA_RL1(t3);                                         \
-    } while(0)
-
-#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)       \
-    do {                                                               \
-       ir = CAMELLIA_SP1110(xr & 0xff)                                 \
-           ^ CAMELLIA_SP0222((xr >> 24) & 0xff)                        \
-           ^ CAMELLIA_SP3033((xr >> 16) & 0xff)                        \
-           ^ CAMELLIA_SP4404((xr >> 8) & 0xff);                        \
-       il = CAMELLIA_SP1110((xl >> 24) & 0xff)                         \
-           ^ CAMELLIA_SP0222((xl >> 16) & 0xff)                        \
-           ^ CAMELLIA_SP3033((xl >> 8) & 0xff)                         \
-           ^ CAMELLIA_SP4404(xl & 0xff);                               \
-       il ^= kl;                                                       \
-       ir ^= kr;                                                       \
-       ir ^= il;                                                       \
-       il = CAMELLIA_RR8(il);                                          \
-       il ^= ir;                                                       \
-       yl ^= ir;                                                       \
-       yr ^= il;                                                       \
-    } while(0)
-
-
-static const u32 camellia_sp1110[256] = {
-    0x70707000,0x82828200,0x2c2c2c00,0xececec00,
-    0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
-    0xe4e4e400,0x85858500,0x57575700,0x35353500,
-    0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
-    0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
-    0x45454500,0x19191900,0xa5a5a500,0x21212100,
-    0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
-    0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
-    0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
-    0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
-    0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
-    0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
-    0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
-    0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
-    0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
-    0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
-    0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
-    0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
-    0x74747400,0x12121200,0x2b2b2b00,0x20202000,
-    0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
-    0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
-    0x34343400,0x7e7e7e00,0x76767600,0x05050500,
-    0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
-    0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
-    0x14141400,0x58585800,0x3a3a3a00,0x61616100,
-    0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
-    0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
-    0x53535300,0x18181800,0xf2f2f200,0x22222200,
-    0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
-    0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
-    0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
-    0x60606000,0xfcfcfc00,0x69696900,0x50505000,
-    0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
-    0xa1a1a100,0x89898900,0x62626200,0x97979700,
-    0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
-    0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
-    0x10101000,0xc4c4c400,0x00000000,0x48484800,
-    0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
-    0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
-    0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
-    0x87878700,0x5c5c5c00,0x83838300,0x02020200,
-    0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
-    0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
-    0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
-    0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
-    0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
-    0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
-    0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
-    0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
-    0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
-    0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
-    0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
-    0x78787800,0x98989800,0x06060600,0x6a6a6a00,
-    0xe7e7e700,0x46464600,0x71717100,0xbababa00,
-    0xd4d4d400,0x25252500,0xababab00,0x42424200,
-    0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
-    0x72727200,0x07070700,0xb9b9b900,0x55555500,
-    0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
-    0x36363600,0x49494900,0x2a2a2a00,0x68686800,
-    0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
-    0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
-    0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
-    0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
-    0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
-};
-
-static const u32 camellia_sp0222[256] = {
-    0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
-    0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
-    0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
-    0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
-    0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
-    0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
-    0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
-    0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
-    0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
-    0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
-    0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
-    0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
-    0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
-    0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
-    0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
-    0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
-    0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
-    0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
-    0x00e8e8e8,0x00242424,0x00565656,0x00404040,
-    0x00e1e1e1,0x00636363,0x00090909,0x00333333,
-    0x00bfbfbf,0x00989898,0x00979797,0x00858585,
-    0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
-    0x00dadada,0x006f6f6f,0x00535353,0x00626262,
-    0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
-    0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
-    0x00bdbdbd,0x00363636,0x00222222,0x00383838,
-    0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
-    0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
-    0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
-    0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
-    0x00484848,0x00101010,0x00d1d1d1,0x00515151,
-    0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
-    0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
-    0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
-    0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
-    0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
-    0x00202020,0x00898989,0x00000000,0x00909090,
-    0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
-    0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
-    0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
-    0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
-    0x009b9b9b,0x00949494,0x00212121,0x00666666,
-    0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
-    0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
-    0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
-    0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
-    0x00030303,0x002d2d2d,0x00dedede,0x00969696,
-    0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
-    0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
-    0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
-    0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
-    0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
-    0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
-    0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
-    0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
-    0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
-    0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
-    0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
-    0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
-    0x00787878,0x00707070,0x00e3e3e3,0x00494949,
-    0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
-    0x00777777,0x00939393,0x00868686,0x00838383,
-    0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
-    0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
-};
-
-static const u32 camellia_sp3033[256] = {
-    0x38003838,0x41004141,0x16001616,0x76007676,
-    0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
-    0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
-    0x75007575,0x06000606,0x57005757,0xa000a0a0,
-    0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
-    0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
-    0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
-    0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
-    0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
-    0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
-    0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
-    0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
-    0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
-    0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
-    0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
-    0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
-    0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
-    0xfd00fdfd,0x66006666,0x58005858,0x96009696,
-    0x3a003a3a,0x09000909,0x95009595,0x10001010,
-    0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
-    0xef00efef,0x26002626,0xe500e5e5,0x61006161,
-    0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
-    0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
-    0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
-    0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
-    0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
-    0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
-    0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
-    0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
-    0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
-    0x12001212,0x04000404,0x74007474,0x54005454,
-    0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
-    0x55005555,0x68006868,0x50005050,0xbe00bebe,
-    0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
-    0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
-    0x70007070,0xff00ffff,0x32003232,0x69006969,
-    0x08000808,0x62006262,0x00000000,0x24002424,
-    0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
-    0x45004545,0x81008181,0x73007373,0x6d006d6d,
-    0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
-    0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
-    0xe600e6e6,0x25002525,0x48004848,0x99009999,
-    0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
-    0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
-    0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
-    0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
-    0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
-    0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
-    0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
-    0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
-    0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
-    0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
-    0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
-    0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
-    0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
-    0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
-    0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
-    0x7c007c7c,0x77007777,0x56005656,0x05000505,
-    0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
-    0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
-    0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
-    0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
-    0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
-    0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
-};
-
-static const u32 camellia_sp4404[256] = {
-    0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
-    0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
-    0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
-    0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
-    0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
-    0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
-    0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
-    0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
-    0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
-    0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
-    0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
-    0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
-    0x14140014,0x3a3a003a,0xdede00de,0x11110011,
-    0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
-    0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
-    0x24240024,0xe8e800e8,0x60600060,0x69690069,
-    0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
-    0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
-    0x10100010,0x00000000,0xa3a300a3,0x75750075,
-    0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
-    0x87870087,0x83830083,0xcdcd00cd,0x90900090,
-    0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
-    0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
-    0x81810081,0x6f6f006f,0x13130013,0x63630063,
-    0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
-    0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
-    0x78780078,0x06060006,0xe7e700e7,0x71710071,
-    0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
-    0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
-    0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
-    0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
-    0x15150015,0xadad00ad,0x77770077,0x80800080,
-    0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
-    0x85850085,0x35350035,0x0c0c000c,0x41410041,
-    0xefef00ef,0x93930093,0x19190019,0x21210021,
-    0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
-    0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
-    0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
-    0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
-    0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
-    0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
-    0x12120012,0x20200020,0xb1b100b1,0x99990099,
-    0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
-    0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
-    0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
-    0x0f0f000f,0x16160016,0x18180018,0x22220022,
-    0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
-    0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
-    0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
-    0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
-    0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
-    0x03030003,0xdada00da,0x3f3f003f,0x94940094,
-    0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
-    0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
-    0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
-    0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
-    0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
-    0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
-    0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
-    0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
-    0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
-    0x49490049,0x68680068,0x38380038,0xa4a400a4,
-    0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
-    0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
-};
-
-
-/**
- * Stuff related to the Camellia key schedule
- */
-#define subl(x) subL[(x)]
-#define subr(x) subR[(x)]
-
-void camellia_setup128(const unsigned char *key, u32 *subkey)
-{
-    u32 kll, klr, krl, krr;
-    u32 il, ir, t0, t1, w0, w1;
-    u32 kw4l, kw4r, dw, tl, tr;
-    u32 subL[26];
-    u32 subR[26];
-
-    /**
-     *  k == kll || klr || krl || krr (|| is concatination)
-     */
-    kll = GETU32(key     );
-    klr = GETU32(key +  4);
-    krl = GETU32(key +  8);
-    krr = GETU32(key + 12);
-    /**
-     * generate KL dependent subkeys
-     */
-    subl(0) = kll; subr(0) = klr;
-    subl(1) = krl; subr(1) = krr;
-    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-    subl(4) = kll; subr(4) = klr;
-    subl(5) = krl; subr(5) = krr;
-    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
-    subl(10) = kll; subr(10) = klr;
-    subl(11) = krl; subr(11) = krr;
-    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-    subl(13) = krl; subr(13) = krr;
-    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
-    subl(16) = kll; subr(16) = klr;
-    subl(17) = krl; subr(17) = krr;
-    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
-    subl(18) = kll; subr(18) = klr;
-    subl(19) = krl; subr(19) = krr;
-    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
-    subl(22) = kll; subr(22) = klr;
-    subl(23) = krl; subr(23) = krr;
-
-    /* generate KA */
-    kll = subl(0); klr = subr(0);
-    krl = subl(1); krr = subr(1);
-    CAMELLIA_F(kll, klr,
-              CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
-              w0, w1, il, ir, t0, t1);
-    krl ^= w0; krr ^= w1;
-    CAMELLIA_F(krl, krr,
-              CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
-              kll, klr, il, ir, t0, t1);
-    CAMELLIA_F(kll, klr,
-              CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
-              krl, krr, il, ir, t0, t1);
-    krl ^= w0; krr ^= w1;
-    CAMELLIA_F(krl, krr,
-              CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
-              w0, w1, il, ir, t0, t1);
-    kll ^= w0; klr ^= w1;
-
-    /* generate KA dependent subkeys */
-    subl(2) = kll; subr(2) = klr;
-    subl(3) = krl; subr(3) = krr;
-    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-    subl(6) = kll; subr(6) = klr;
-    subl(7) = krl; subr(7) = krr;
-    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-    subl(8) = kll; subr(8) = klr;
-    subl(9) = krl; subr(9) = krr;
-    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-    subl(12) = kll; subr(12) = klr;
-    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-    subl(14) = kll; subr(14) = klr;
-    subl(15) = krl; subr(15) = krr;
-    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
-    subl(20) = kll; subr(20) = klr;
-    subl(21) = krl; subr(21) = krr;
-    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
-    subl(24) = kll; subr(24) = klr;
-    subl(25) = krl; subr(25) = krr;
-
-
-    /* absorb kw2 to other subkeys */
-    subl(3) ^= subl(1); subr(3) ^= subr(1);
-    subl(5) ^= subl(1); subr(5) ^= subr(1);
-    subl(7) ^= subl(1); subr(7) ^= subr(1);
-    subl(1) ^= subr(1) & ~subr(9);
-    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
-    subl(11) ^= subl(1); subr(11) ^= subr(1);
-    subl(13) ^= subl(1); subr(13) ^= subr(1);
-    subl(15) ^= subl(1); subr(15) ^= subr(1);
-    subl(1) ^= subr(1) & ~subr(17);
-    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
-    subl(19) ^= subl(1); subr(19) ^= subr(1);
-    subl(21) ^= subl(1); subr(21) ^= subr(1);
-    subl(23) ^= subl(1); subr(23) ^= subr(1);
-    subl(24) ^= subl(1); subr(24) ^= subr(1);
-
-    /* absorb kw4 to other subkeys */
-    kw4l = subl(25); kw4r = subr(25);
-    subl(22) ^= kw4l; subr(22) ^= kw4r;
-    subl(20) ^= kw4l; subr(20) ^= kw4r;
-    subl(18) ^= kw4l; subr(18) ^= kw4r;
-    kw4l ^= kw4r & ~subr(16);
-    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
-    subl(14) ^= kw4l; subr(14) ^= kw4r;
-    subl(12) ^= kw4l; subr(12) ^= kw4r;
-    subl(10) ^= kw4l; subr(10) ^= kw4r;
-    kw4l ^= kw4r & ~subr(8);
-    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
-    subl(6) ^= kw4l; subr(6) ^= kw4r;
-    subl(4) ^= kw4l; subr(4) ^= kw4r;
-    subl(2) ^= kw4l; subr(2) ^= kw4r;
-    subl(0) ^= kw4l; subr(0) ^= kw4r;
-
-    /* key XOR is end of F-function */
-    CamelliaSubkeyL(0) = subl(0) ^ subl(2);
-    CamelliaSubkeyR(0) = subr(0) ^ subr(2);
-    CamelliaSubkeyL(2) = subl(3);
-    CamelliaSubkeyR(2) = subr(3);
-    CamelliaSubkeyL(3) = subl(2) ^ subl(4);
-    CamelliaSubkeyR(3) = subr(2) ^ subr(4);
-    CamelliaSubkeyL(4) = subl(3) ^ subl(5);
-    CamelliaSubkeyR(4) = subr(3) ^ subr(5);
-    CamelliaSubkeyL(5) = subl(4) ^ subl(6);
-    CamelliaSubkeyR(5) = subr(4) ^ subr(6);
-    CamelliaSubkeyL(6) = subl(5) ^ subl(7);
-    CamelliaSubkeyR(6) = subr(5) ^ subr(7);
-    tl = subl(10) ^ (subr(10) & ~subr(8));
-    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
-    CamelliaSubkeyL(7) = subl(6) ^ tl;
-    CamelliaSubkeyR(7) = subr(6) ^ tr;
-    CamelliaSubkeyL(8) = subl(8);
-    CamelliaSubkeyR(8) = subr(8);
-    CamelliaSubkeyL(9) = subl(9);
-    CamelliaSubkeyR(9) = subr(9);
-    tl = subl(7) ^ (subr(7) & ~subr(9));
-    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
-    CamelliaSubkeyL(10) = tl ^ subl(11);
-    CamelliaSubkeyR(10) = tr ^ subr(11);
-    CamelliaSubkeyL(11) = subl(10) ^ subl(12);
-    CamelliaSubkeyR(11) = subr(10) ^ subr(12);
-    CamelliaSubkeyL(12) = subl(11) ^ subl(13);
-    CamelliaSubkeyR(12) = subr(11) ^ subr(13);
-    CamelliaSubkeyL(13) = subl(12) ^ subl(14);
-    CamelliaSubkeyR(13) = subr(12) ^ subr(14);
-    CamelliaSubkeyL(14) = subl(13) ^ subl(15);
-    CamelliaSubkeyR(14) = subr(13) ^ subr(15);
-    tl = subl(18) ^ (subr(18) & ~subr(16));
-    dw = tl & subl(16),        tr = subr(18) ^ CAMELLIA_RL1(dw);
-    CamelliaSubkeyL(15) = subl(14) ^ tl;
-    CamelliaSubkeyR(15) = subr(14) ^ tr;
-    CamelliaSubkeyL(16) = subl(16);
-    CamelliaSubkeyR(16) = subr(16);
-    CamelliaSubkeyL(17) = subl(17);
-    CamelliaSubkeyR(17) = subr(17);
-    tl = subl(15) ^ (subr(15) & ~subr(17));
-    dw = tl & subl(17),        tr = subr(15) ^ CAMELLIA_RL1(dw);
-    CamelliaSubkeyL(18) = tl ^ subl(19);
-    CamelliaSubkeyR(18) = tr ^ subr(19);
-    CamelliaSubkeyL(19) = subl(18) ^ subl(20);
-    CamelliaSubkeyR(19) = subr(18) ^ subr(20);
-    CamelliaSubkeyL(20) = subl(19) ^ subl(21);
-    CamelliaSubkeyR(20) = subr(19) ^ subr(21);
-    CamelliaSubkeyL(21) = subl(20) ^ subl(22);
-    CamelliaSubkeyR(21) = subr(20) ^ subr(22);
-    CamelliaSubkeyL(22) = subl(21) ^ subl(23);
-    CamelliaSubkeyR(22) = subr(21) ^ subr(23);
-    CamelliaSubkeyL(23) = subl(22);
-    CamelliaSubkeyR(23) = subr(22);
-    CamelliaSubkeyL(24) = subl(24) ^ subl(23);
-    CamelliaSubkeyR(24) = subr(24) ^ subr(23);
-
-    /* apply the inverse of the last half of P-function */
-    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
-    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
-    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
-    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
-    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
-    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
-    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
-    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
-    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
-    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
-    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
-    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
-    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
-    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
-    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
-    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
-    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
-    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
-
-    return;
-}
-
-void camellia_setup256(const unsigned char *key, u32 *subkey)
-{
-    u32 kll,klr,krl,krr;           /* left half of key */
-    u32 krll,krlr,krrl,krrr;       /* right half of key */
-    u32 il, ir, t0, t1, w0, w1;    /* temporary variables */
-    u32 kw4l, kw4r, dw, tl, tr;
-    u32 subL[34];
-    u32 subR[34];
-
-    /**
-     *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
-     *  (|| is concatination)
-     */
-
-    kll  = GETU32(key     );
-    klr  = GETU32(key +  4);
-    krl  = GETU32(key +  8);
-    krr  = GETU32(key + 12);
-    krll = GETU32(key + 16);
-    krlr = GETU32(key + 20);
-    krrl = GETU32(key + 24);
-    krrr = GETU32(key + 28);
-
-    /* generate KL dependent subkeys */
-    subl(0) = kll; subr(0) = klr;
-    subl(1) = krl; subr(1) = krr;
-    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
-    subl(12) = kll; subr(12) = klr;
-    subl(13) = krl; subr(13) = krr;
-    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-    subl(16) = kll; subr(16) = klr;
-    subl(17) = krl; subr(17) = krr;
-    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
-    subl(22) = kll; subr(22) = klr;
-    subl(23) = krl; subr(23) = krr;
-    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
-    subl(30) = kll; subr(30) = klr;
-    subl(31) = krl; subr(31) = krr;
-
-    /* generate KR dependent subkeys */
-    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
-    subl(4) = krll; subr(4) = krlr;
-    subl(5) = krrl; subr(5) = krrr;
-    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
-    subl(8) = krll; subr(8) = krlr;
-    subl(9) = krrl; subr(9) = krrr;
-    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
-    subl(18) = krll; subr(18) = krlr;
-    subl(19) = krrl; subr(19) = krrr;
-    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
-    subl(26) = krll; subr(26) = krlr;
-    subl(27) = krrl; subr(27) = krrr;
-    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
-
-    /* generate KA */
-    kll = subl(0) ^ krll; klr = subr(0) ^ krlr;
-    krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;
-    CAMELLIA_F(kll, klr,
-              CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
-              w0, w1, il, ir, t0, t1);
-    krl ^= w0; krr ^= w1;
-    CAMELLIA_F(krl, krr,
-              CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
-              kll, klr, il, ir, t0, t1);
-    kll ^= krll; klr ^= krlr;
-    CAMELLIA_F(kll, klr,
-              CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
-              krl, krr, il, ir, t0, t1);
-    krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
-    CAMELLIA_F(krl, krr,
-              CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
-              w0, w1, il, ir, t0, t1);
-    kll ^= w0; klr ^= w1;
-
-    /* generate KB */
-    krll ^= kll; krlr ^= klr;
-    krrl ^= krl; krrr ^= krr;
-    CAMELLIA_F(krll, krlr,
-              CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
-              w0, w1, il, ir, t0, t1);
-    krrl ^= w0; krrr ^= w1;
-    CAMELLIA_F(krrl, krrr,
-              CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
-              w0, w1, il, ir, t0, t1);
-    krll ^= w0; krlr ^= w1;
-
-    /* generate KA dependent subkeys */
-    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
-    subl(6) = kll; subr(6) = klr;
-    subl(7) = krl; subr(7) = krr;
-    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
-    subl(14) = kll; subr(14) = klr;
-    subl(15) = krl; subr(15) = krr;
-    subl(24) = klr; subr(24) = krl;
-    subl(25) = krr; subr(25) = kll;
-    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
-    subl(28) = kll; subr(28) = klr;
-    subl(29) = krl; subr(29) = krr;
-
-    /* generate KB dependent subkeys */
-    subl(2) = krll; subr(2) = krlr;
-    subl(3) = krrl; subr(3) = krrr;
-    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
-    subl(10) = krll; subr(10) = krlr;
-    subl(11) = krrl; subr(11) = krrr;
-    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
-    subl(20) = krll; subr(20) = krlr;
-    subl(21) = krrl; subr(21) = krrr;
-    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
-    subl(32) = krll; subr(32) = krlr;
-    subl(33) = krrl; subr(33) = krrr;
-
-    /* absorb kw2 to other subkeys */
-    subl(3) ^= subl(1); subr(3) ^= subr(1);
-    subl(5) ^= subl(1); subr(5) ^= subr(1);
-    subl(7) ^= subl(1); subr(7) ^= subr(1);
-    subl(1) ^= subr(1) & ~subr(9);
-    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
-    subl(11) ^= subl(1); subr(11) ^= subr(1);
-    subl(13) ^= subl(1); subr(13) ^= subr(1);
-    subl(15) ^= subl(1); subr(15) ^= subr(1);
-    subl(1) ^= subr(1) & ~subr(17);
-    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
-    subl(19) ^= subl(1); subr(19) ^= subr(1);
-    subl(21) ^= subl(1); subr(21) ^= subr(1);
-    subl(23) ^= subl(1); subr(23) ^= subr(1);
-    subl(1) ^= subr(1) & ~subr(25);
-    dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw);
-    subl(27) ^= subl(1); subr(27) ^= subr(1);
-    subl(29) ^= subl(1); subr(29) ^= subr(1);
-    subl(31) ^= subl(1); subr(31) ^= subr(1);
-    subl(32) ^= subl(1); subr(32) ^= subr(1);
-
-    /* absorb kw4 to other subkeys */
-    kw4l = subl(33); kw4r = subr(33);
-    subl(30) ^= kw4l; subr(30) ^= kw4r;
-    subl(28) ^= kw4l; subr(28) ^= kw4r;
-    subl(26) ^= kw4l; subr(26) ^= kw4r;
-    kw4l ^= kw4r & ~subr(24);
-    dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw);
-    subl(22) ^= kw4l; subr(22) ^= kw4r;
-    subl(20) ^= kw4l; subr(20) ^= kw4r;
-    subl(18) ^= kw4l; subr(18) ^= kw4r;
-    kw4l ^= kw4r & ~subr(16);
-    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
-    subl(14) ^= kw4l; subr(14) ^= kw4r;
-    subl(12) ^= kw4l; subr(12) ^= kw4r;
-    subl(10) ^= kw4l; subr(10) ^= kw4r;
-    kw4l ^= kw4r & ~subr(8);
-    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
-    subl(6) ^= kw4l; subr(6) ^= kw4r;
-    subl(4) ^= kw4l; subr(4) ^= kw4r;
-    subl(2) ^= kw4l; subr(2) ^= kw4r;
-    subl(0) ^= kw4l; subr(0) ^= kw4r;
-
-    /* key XOR is end of F-function */
-    CamelliaSubkeyL(0) = subl(0) ^ subl(2);
-    CamelliaSubkeyR(0) = subr(0) ^ subr(2);
-    CamelliaSubkeyL(2) = subl(3);
-    CamelliaSubkeyR(2) = subr(3);
-    CamelliaSubkeyL(3) = subl(2) ^ subl(4);
-    CamelliaSubkeyR(3) = subr(2) ^ subr(4);
-    CamelliaSubkeyL(4) = subl(3) ^ subl(5);
-    CamelliaSubkeyR(4) = subr(3) ^ subr(5);
-    CamelliaSubkeyL(5) = subl(4) ^ subl(6);
-    CamelliaSubkeyR(5) = subr(4) ^ subr(6);
-    CamelliaSubkeyL(6) = subl(5) ^ subl(7);
-    CamelliaSubkeyR(6) = subr(5) ^ subr(7);
-    tl = subl(10) ^ (subr(10) & ~subr(8));
-    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
-    CamelliaSubkeyL(7) = subl(6) ^ tl;
-    CamelliaSubkeyR(7) = subr(6) ^ tr;
-    CamelliaSubkeyL(8) = subl(8);
-    CamelliaSubkeyR(8) = subr(8);
-    CamelliaSubkeyL(9) = subl(9);
-    CamelliaSubkeyR(9) = subr(9);
-    tl = subl(7) ^ (subr(7) & ~subr(9));
-    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
-    CamelliaSubkeyL(10) = tl ^ subl(11);
-    CamelliaSubkeyR(10) = tr ^ subr(11);
-    CamelliaSubkeyL(11) = subl(10) ^ subl(12);
-    CamelliaSubkeyR(11) = subr(10) ^ subr(12);
-    CamelliaSubkeyL(12) = subl(11) ^ subl(13);
-    CamelliaSubkeyR(12) = subr(11) ^ subr(13);
-    CamelliaSubkeyL(13) = subl(12) ^ subl(14);
-    CamelliaSubkeyR(13) = subr(12) ^ subr(14);
-    CamelliaSubkeyL(14) = subl(13) ^ subl(15);
-    CamelliaSubkeyR(14) = subr(13) ^ subr(15);
-    tl = subl(18) ^ (subr(18) & ~subr(16));
-    dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
-    CamelliaSubkeyL(15) = subl(14) ^ tl;
-    CamelliaSubkeyR(15) = subr(14) ^ tr;
-    CamelliaSubkeyL(16) = subl(16);
-    CamelliaSubkeyR(16) = subr(16);
-    CamelliaSubkeyL(17) = subl(17);
-    CamelliaSubkeyR(17) = subr(17);
-    tl = subl(15) ^ (subr(15) & ~subr(17));
-    dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
-    CamelliaSubkeyL(18) = tl ^ subl(19);
-    CamelliaSubkeyR(18) = tr ^ subr(19);
-    CamelliaSubkeyL(19) = subl(18) ^ subl(20);
-    CamelliaSubkeyR(19) = subr(18) ^ subr(20);
-    CamelliaSubkeyL(20) = subl(19) ^ subl(21);
-    CamelliaSubkeyR(20) = subr(19) ^ subr(21);
-    CamelliaSubkeyL(21) = subl(20) ^ subl(22);
-    CamelliaSubkeyR(21) = subr(20) ^ subr(22);
-    CamelliaSubkeyL(22) = subl(21) ^ subl(23);
-    CamelliaSubkeyR(22) = subr(21) ^ subr(23);
-    tl = subl(26) ^ (subr(26) & ~subr(24));
-    dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw);
-    CamelliaSubkeyL(23) = subl(22) ^ tl;
-    CamelliaSubkeyR(23) = subr(22) ^ tr;
-    CamelliaSubkeyL(24) = subl(24);
-    CamelliaSubkeyR(24) = subr(24);
-    CamelliaSubkeyL(25) = subl(25);
-    CamelliaSubkeyR(25) = subr(25);
-    tl = subl(23) ^ (subr(23) &  ~subr(25));
-    dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw);
-    CamelliaSubkeyL(26) = tl ^ subl(27);
-    CamelliaSubkeyR(26) = tr ^ subr(27);
-    CamelliaSubkeyL(27) = subl(26) ^ subl(28);
-    CamelliaSubkeyR(27) = subr(26) ^ subr(28);
-    CamelliaSubkeyL(28) = subl(27) ^ subl(29);
-    CamelliaSubkeyR(28) = subr(27) ^ subr(29);
-    CamelliaSubkeyL(29) = subl(28) ^ subl(30);
-    CamelliaSubkeyR(29) = subr(28) ^ subr(30);
-    CamelliaSubkeyL(30) = subl(29) ^ subl(31);
-    CamelliaSubkeyR(30) = subr(29) ^ subr(31);
-    CamelliaSubkeyL(31) = subl(30);
-    CamelliaSubkeyR(31) = subr(30);
-    CamelliaSubkeyL(32) = subl(32) ^ subl(31);
-    CamelliaSubkeyR(32) = subr(32) ^ subr(31);
-
-    /* apply the inverse of the last half of P-function */
-    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
-    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
-    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
-    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
-    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
-    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
-    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
-    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
-    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
-    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
-    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
-    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
-    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
-    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
-    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
-    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
-    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
-    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
-    dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw;
-    dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw;
-    dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw;
-    dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw;
-    dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw;
-    dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw;
-    
-    return;
-}
-
-void camellia_setup192(const unsigned char *key, u32 *subkey)
-{
-    unsigned char kk[32];
-    u32 krll, krlr, krrl,krrr;
-
-    memcpy(kk, key, 24);
-    memcpy((unsigned char *)&krll, key+16,4);
-    memcpy((unsigned char *)&krlr, key+20,4);
-    krrl = ~krll;
-    krrr = ~krlr;
-    memcpy(kk+24, (unsigned char *)&krrl, 4);
-    memcpy(kk+28, (unsigned char *)&krrr, 4);
-    camellia_setup256(kk, subkey);
-    return;
-}
-
-
-/**
- * Stuff related to camellia encryption/decryption
- *
- * "io" must be 4byte aligned and big-endian data.
- */
-void camellia_encrypt128(const u32 *subkey, u32 *io)
-{
-    u32 il, ir, t0, t1;
-
-    /* pre whitening but absorb kw2*/
-    io[0] ^= CamelliaSubkeyL(0);
-    io[1] ^= CamelliaSubkeyR(0);
-    /* main iteration */
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
-                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
-                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
-                    io[0],io[1],il,ir,t0,t1);
-
-    /* post whitening but kw4 */
-    io[2] ^= CamelliaSubkeyL(24);
-    io[3] ^= CamelliaSubkeyR(24);
-
-    t0 = io[0];
-    t1 = io[1];
-    io[0] = io[2];
-    io[1] = io[3];
-    io[2] = t0;
-    io[3] = t1;
-       
-    return;
-}
-
-void camellia_decrypt128(const u32 *subkey, u32 *io)
-{
-    u32 il,ir,t0,t1;               /* temporary valiables */
-    
-    /* pre whitening but absorb kw2*/
-    io[0] ^= CamelliaSubkeyL(24);
-    io[1] ^= CamelliaSubkeyR(24);
-
-    /* main iteration */
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
-                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
-                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
-                    io[0],io[1],il,ir,t0,t1);
-
-    /* post whitening but kw4 */
-    io[2] ^= CamelliaSubkeyL(0);
-    io[3] ^= CamelliaSubkeyR(0);
-
-    t0 = io[0];
-    t1 = io[1];
-    io[0] = io[2];
-    io[1] = io[3];
-    io[2] = t0;
-    io[3] = t1;
-
-    return;
-}
-
-/**
- * stuff for 192 and 256bit encryption/decryption
- */
-void camellia_encrypt256(const u32 *subkey, u32 *io)
-{
-    u32 il,ir,t0,t1;           /* temporary valiables */
-
-    /* pre whitening but absorb kw2*/
-    io[0] ^= CamelliaSubkeyL(0);
-    io[1] ^= CamelliaSubkeyR(0);
-
-    /* main iteration */
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
-                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
-                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(24),CamelliaSubkeyR(24),
-                CamelliaSubkeyL(25),CamelliaSubkeyR(25),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(26),CamelliaSubkeyR(26),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(27),CamelliaSubkeyR(27),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(28),CamelliaSubkeyR(28),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(29),CamelliaSubkeyR(29),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(30),CamelliaSubkeyR(30),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(31),CamelliaSubkeyR(31),
-                    io[0],io[1],il,ir,t0,t1);
-
-    /* post whitening but kw4 */
-    io[2] ^= CamelliaSubkeyL(32);
-    io[3] ^= CamelliaSubkeyR(32);
-
-    t0 = io[0];
-    t1 = io[1];
-    io[0] = io[2];
-    io[1] = io[3];
-    io[2] = t0;
-    io[3] = t1;
-
-    return;
-}
-
-void camellia_decrypt256(const u32 *subkey, u32 *io)
-{
-    u32 il,ir,t0,t1;           /* temporary valiables */
-
-    /* pre whitening but absorb kw2*/
-    io[0] ^= CamelliaSubkeyL(32);
-    io[1] ^= CamelliaSubkeyR(32);
-       
-    /* main iteration */
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(31),CamelliaSubkeyR(31),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(30),CamelliaSubkeyR(30),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(29),CamelliaSubkeyR(29),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(28),CamelliaSubkeyR(28),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(27),CamelliaSubkeyR(27),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(26),CamelliaSubkeyR(26),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(25),CamelliaSubkeyR(25),
-                CamelliaSubkeyL(24),CamelliaSubkeyR(24),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
-                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
-                    io[0],io[1],il,ir,t0,t1);
-
-    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
-                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
-                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
-                t0,t1,il,ir);
-
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
-                    io[0],io[1],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[0],io[1],
-                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
-                    io[2],io[3],il,ir,t0,t1);
-    CAMELLIA_ROUNDSM(io[2],io[3],
-                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
-                    io[0],io[1],il,ir,t0,t1);
-
-    /* post whitening but kw4 */
-    io[2] ^= CamelliaSubkeyL(0);
-    io[3] ^= CamelliaSubkeyR(0);
-
-    t0 = io[0];
-    t1 = io[1];
-    io[0] = io[2];
-    io[1] = io[3];
-    io[2] = t0;
-    io[3] = t1;
-
-    return;
-}
-
-/***
- *
- * API for compatibility
- */
-
-void Camellia_Ekeygen(const int keyBitLength, 
-                     const unsigned char *rawKey, 
-                     KEY_TABLE_TYPE keyTable)
-{
-    switch(keyBitLength) {
-    case 128:
-       camellia_setup128(rawKey, keyTable);
-       break;
-    case 192:
-       camellia_setup192(rawKey, keyTable);
-       break;
-    case 256:
-       camellia_setup256(rawKey, keyTable);
-       break;
-    default:
-       break;
-    }
-}
-
-
-void Camellia_EncryptBlock(const int keyBitLength, 
-                          const unsigned char *plaintext, 
-                          const KEY_TABLE_TYPE keyTable, 
-                          unsigned char *ciphertext)
-{
-    u32 tmp[4];
-
-    tmp[0] = GETU32(plaintext);
-    tmp[1] = GETU32(plaintext + 4);
-    tmp[2] = GETU32(plaintext + 8);
-    tmp[3] = GETU32(plaintext + 12);
-
-    switch (keyBitLength) {
-    case 128:
-       camellia_encrypt128(keyTable, tmp);
-       break;
-    case 192:
-       /* fall through */
-    case 256:
-       camellia_encrypt256(keyTable, tmp);
-       break;
-    default:
-       break;
-    }
-
-    PUTU32(ciphertext, tmp[0]);
-    PUTU32(ciphertext + 4, tmp[1]);
-    PUTU32(ciphertext + 8, tmp[2]);
-    PUTU32(ciphertext + 12, tmp[3]);
-}
-
-void Camellia_DecryptBlock(const int keyBitLength, 
-                          const unsigned char *ciphertext, 
-                          const KEY_TABLE_TYPE keyTable, 
-                          unsigned char *plaintext)
-{
-    u32 tmp[4];
-
-    tmp[0] = GETU32(ciphertext);
-    tmp[1] = GETU32(ciphertext + 4);
-    tmp[2] = GETU32(ciphertext + 8);
-    tmp[3] = GETU32(ciphertext + 12);
-
-    switch (keyBitLength) {
-    case 128:
-       camellia_decrypt128(keyTable, tmp);
-       break;
-    case 192:
-       /* fall through */
-    case 256:
-       camellia_decrypt256(keyTable, tmp);
-       break;
-    default:
-       break;
-    }
-    PUTU32(plaintext, tmp[0]);
-    PUTU32(plaintext + 4, tmp[1]);
-    PUTU32(plaintext + 8, tmp[2]);
-    PUTU32(plaintext + 12, tmp[3]);
-}
diff --git a/lib/libgcrypt/cipher/camellia.h b/lib/libgcrypt/cipher/camellia.h
deleted file mode 100644 (file)
index 4425a3a..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/* camellia.h  ver 1.2.0
- *
- * Copyright (C) 2006,2007
- * NTT (Nippon Telegraph and Telephone Corporation).
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef HEADER_CAMELLIA_H
-#define HEADER_CAMELLIA_H
-
-/* To use Camellia with libraries it is often useful to keep the name
- * space of the library clean.  The following macro is thus useful:
- *
- *     #define CAMELLIA_EXT_SYM_PREFIX foo_
- *  
- * This prefixes all external symbols with "foo_".
- */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#ifdef CAMELLIA_EXT_SYM_PREFIX
-#define CAMELLIA_PREFIX1(x,y) x ## y
-#define CAMELLIA_PREFIX2(x,y) CAMELLIA_PREFIX1(x,y)
-#define CAMELLIA_PREFIX(x)    CAMELLIA_PREFIX2(CAMELLIA_EXT_SYM_PREFIX,x)
-#define Camellia_Ekeygen      CAMELLIA_PREFIX(Camellia_Ekeygen)
-#define Camellia_EncryptBlock CAMELLIA_PREFIX(Camellia_EncryptBlock)
-#define Camellia_DecryptBlock CAMELLIA_PREFIX(Camellia_DecryptBlock)
-#define camellia_decrypt128   CAMELLIA_PREFIX(camellia_decrypt128)
-#define camellia_decrypt256   CAMELLIA_PREFIX(camellia_decrypt256)
-#define camellia_encrypt128   CAMELLIA_PREFIX(camellia_encrypt128)
-#define camellia_encrypt256   CAMELLIA_PREFIX(camellia_encrypt256)
-#define camellia_setup128     CAMELLIA_PREFIX(camellia_setup128)
-#define camellia_setup192     CAMELLIA_PREFIX(camellia_setup192) 
-#define camellia_setup256     CAMELLIA_PREFIX(camellia_setup256)
-#endif /*CAMELLIA_EXT_SYM_PREFIX*/
-
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-#define CAMELLIA_BLOCK_SIZE 16
-#define CAMELLIA_TABLE_BYTE_LEN 272
-#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
-
-typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
-
-
-void Camellia_Ekeygen(const int keyBitLength,
-                     const unsigned char *rawKey, 
-                     KEY_TABLE_TYPE keyTable);
-
-void Camellia_EncryptBlock(const int keyBitLength,
-                          const unsigned char *plaintext, 
-                          const KEY_TABLE_TYPE keyTable, 
-                          unsigned char *cipherText);
-
-void Camellia_DecryptBlock(const int keyBitLength, 
-                          const unsigned char *cipherText, 
-                          const KEY_TABLE_TYPE keyTable, 
-                          unsigned char *plaintext);
-
-
-#ifdef  __cplusplus
-}
-#endif
-
-#endif /* HEADER_CAMELLIA_H */
diff --git a/lib/libgcrypt/cipher/cast5.c b/lib/libgcrypt/cipher/cast5.c
deleted file mode 100644 (file)
index 333d55e..0000000
+++ /dev/null
@@ -1,620 +0,0 @@
-/* cast5.c  -  CAST5 cipher (RFC2144)
- *     Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-/* Test vectors:
- *
- * 128-bit key        = 01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A
- *        plaintext   = 01 23 45 67 89 AB CD EF
- *        ciphertext  = 23 8B 4F E5 84 7E 44 B2
- *
- * 80-bit  key        = 01 23 45 67 12 34 56 78 23 45
- *                    = 01 23 45 67 12 34 56 78 23 45 00 00 00 00 00 00
- *        plaintext   = 01 23 45 67 89 AB CD EF
- *        ciphertext  = EB 6A 71 1A 2C 02 27 1B
- *
- * 40-bit  key        = 01 23 45 67 12
- *                    = 01 23 45 67 12 00 00 00 00 00 00 00 00 00 00 00
- *        plaintext   = 01 23 45 67 89 AB CD EF
- *        ciphertext  = 7A C8 16 D1 6E 9B 30 2E
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "g10lib.h"
-#include "types.h"
-#include "cipher.h"
-
-#define CAST5_BLOCKSIZE 8
-
-typedef struct {
-    u32  Km[16];
-    byte Kr[16];
-} CAST5_context;
-
-static gcry_err_code_t cast_setkey (void *c, const byte *key, unsigned keylen);
-static void encrypt_block (void *c, byte *outbuf, const byte *inbuf);
-static void decrypt_block (void *c, byte *outbuf, const byte *inbuf);
-
-
-
-
-static const u32 s1[256] = {
-0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
-0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
-0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
-0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
-0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
-0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
-0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
-0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
-0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
-0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
-0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
-0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
-0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
-0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
-0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
-0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
-0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
-0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
-0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
-0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
-0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
-0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
-0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
-0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
-0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
-0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
-0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
-0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
-0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
-0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
-0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
-0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
-};
-static const u32 s2[256] = {
-0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
-0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
-0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
-0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
-0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
-0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
-0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
-0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
-0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
-0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
-0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
-0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
-0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
-0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
-0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
-0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
-0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
-0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
-0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
-0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
-0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
-0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
-0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
-0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
-0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
-0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
-0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
-0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
-0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
-0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
-0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
-0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1
-};
-static const u32 s3[256] = {
-0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
-0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
-0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
-0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
-0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
-0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
-0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
-0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
-0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
-0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
-0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
-0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
-0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
-0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
-0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
-0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
-0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
-0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
-0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
-0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
-0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
-0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
-0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
-0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
-0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
-0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
-0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
-0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
-0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
-0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
-0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
-0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783
-};
-static const u32 s4[256] = {
-0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
-0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
-0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
-0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
-0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
-0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
-0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
-0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
-0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
-0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
-0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
-0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
-0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
-0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
-0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
-0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
-0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
-0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
-0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
-0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
-0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
-0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
-0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
-0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
-0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
-0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
-0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
-0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
-0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
-0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
-0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
-0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
-};
-static const u32 s5[256] = {
-0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
-0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
-0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
-0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
-0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
-0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
-0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
-0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
-0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
-0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
-0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
-0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
-0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
-0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
-0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
-0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
-0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
-0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
-0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
-0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
-0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
-0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
-0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
-0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
-0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
-0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
-0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
-0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
-0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
-0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
-0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
-0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4
-};
-static const u32 s6[256] = {
-0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
-0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
-0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
-0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
-0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
-0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
-0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
-0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
-0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
-0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
-0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
-0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
-0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
-0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
-0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
-0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
-0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
-0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
-0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
-0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
-0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
-0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
-0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
-0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
-0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
-0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
-0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
-0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
-0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
-0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
-0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
-0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f
-};
-static const u32 s7[256] = {
-0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
-0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
-0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
-0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
-0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
-0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
-0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
-0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
-0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
-0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
-0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
-0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
-0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
-0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
-0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
-0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
-0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
-0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
-0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
-0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
-0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
-0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
-0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
-0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
-0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
-0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
-0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
-0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
-0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
-0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
-0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
-0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3
-};
-static const u32 s8[256] = {
-0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
-0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
-0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
-0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
-0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
-0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
-0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
-0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
-0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
-0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
-0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
-0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
-0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
-0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
-0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
-0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
-0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
-0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
-0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
-0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
-0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
-0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
-0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
-0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
-0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
-0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
-0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
-0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
-0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
-0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
-0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
-0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e
-};
-
-
-#if defined(__GNUC__) && defined(__i386__)
-static inline u32
-rol(int n, u32 x)
-{
-       __asm__("roll %%cl,%0"
-               :"=r" (x)
-               :"0" (x),"c" (n));
-       return x;
-}
-#else
-#define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
-#endif
-
-#define F1(D,m,r)  (  (I = ((m) + (D))), (I=rol((r),I)),   \
-    (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) )
-#define F2(D,m,r)  (  (I = ((m) ^ (D))), (I=rol((r),I)),   \
-    (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) )
-#define F3(D,m,r)  (  (I = ((m) - (D))), (I=rol((r),I)),   \
-    (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
-
-static void
-do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf )
-{
-    u32 l, r, t;
-    u32 I;   /* used by the Fx macros */
-    u32 *Km;
-    byte *Kr;
-
-    Km = c->Km;
-    Kr = c->Kr;
-
-    /* (L0,R0) <-- (m1...m64). (Split the plaintext into left and
-     * right 32-bit halves L0 = m1...m32 and R0 = m33...m64.)
-     */
-    l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
-    r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
-
-    /* (16 rounds) for i from 1 to 16, compute Li and Ri as follows:
-     * Li = Ri-1;
-     * Ri = Li-1 ^ f(Ri-1,Kmi,Kri), where f is defined in Section 2.2
-     * Rounds 1, 4, 7, 10, 13, and 16 use f function Type 1.
-     * Rounds 2, 5, 8, 11, and 14 use f function Type 2.
-     * Rounds 3, 6, 9, 12, and 15 use f function Type 3.
-     */
-
-    t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
-    t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
-    t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
-    t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
-    t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
-    t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
-    t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
-    t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
-    t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
-    t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
-    t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
-    t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
-    t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
-    t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
-    t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
-    t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
-
-    /* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and
-     * concatenate to form the ciphertext.) */
-    outbuf[0] = (r >> 24) & 0xff;
-    outbuf[1] = (r >> 16) & 0xff;
-    outbuf[2] = (r >>  8) & 0xff;
-    outbuf[3] =  r       & 0xff;
-    outbuf[4] = (l >> 24) & 0xff;
-    outbuf[5] = (l >> 16) & 0xff;
-    outbuf[6] = (l >>  8) & 0xff;
-    outbuf[7] =  l       & 0xff;
-}
-
-static void
-encrypt_block (void *context , byte *outbuf, const byte *inbuf)
-{
-  CAST5_context *c = (CAST5_context *) context;
-  do_encrypt_block (c, outbuf, inbuf);
-  _gcry_burn_stack (20+4*sizeof(void*));
-}
-
-
-static void
-do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf )
-{
-    u32 l, r, t;
-    u32 I;
-    u32 *Km;
-    byte *Kr;
-
-    Km = c->Km;
-    Kr = c->Kr;
-
-    l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
-    r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
-
-    t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
-    t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
-    t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
-    t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
-    t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
-    t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
-    t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
-    t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
-    t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
-    t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
-    t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
-    t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
-    t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
-    t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
-    t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
-    t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
-
-    outbuf[0] = (r >> 24) & 0xff;
-    outbuf[1] = (r >> 16) & 0xff;
-    outbuf[2] = (r >>  8) & 0xff;
-    outbuf[3] =  r       & 0xff;
-    outbuf[4] = (l >> 24) & 0xff;
-    outbuf[5] = (l >> 16) & 0xff;
-    outbuf[6] = (l >>  8) & 0xff;
-    outbuf[7] =  l       & 0xff;
-}
-
-static void
-decrypt_block (void *context, byte *outbuf, const byte *inbuf)
-{
-  CAST5_context *c = (CAST5_context *) context;
-  do_decrypt_block (c, outbuf, inbuf);
-  _gcry_burn_stack (20+4*sizeof(void*));
-}
-
-
-static const char*
-selftest(void)
-{
-    CAST5_context c;
-    byte key[16]  = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
-                     0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A  };
-    byte plain[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
-    byte cipher[8]= { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };
-    byte buffer[8];
-
-    cast_setkey( &c, key, 16 );
-    encrypt_block( &c, buffer, plain );
-    if( memcmp( buffer, cipher, 8 ) )
-       return "1";
-    decrypt_block( &c, buffer, buffer );
-    if( memcmp( buffer, plain, 8 ) )
-       return "2";
-
-#if 0 /* full maintenance test */
-    {
-       int i;
-       byte a0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
-                       0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A };
-       byte b0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
-                       0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A };
-       byte a1[16] = { 0xEE,0xA9,0xD0,0xA2,0x49,0xFD,0x3B,0xA6,
-                       0xB3,0x43,0x6F,0xB8,0x9D,0x6D,0xCA,0x92 };
-       byte b1[16] = { 0xB2,0xC9,0x5E,0xB0,0x0C,0x31,0xAD,0x71,
-                       0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E };
-
-       for(i=0; i < 1000000; i++ ) {
-           cast_setkey( &c, b0, 16 );
-           encrypt_block( &c, a0, a0 );
-           encrypt_block( &c, a0+8, a0+8 );
-           cast_setkey( &c, a0, 16 );
-           encrypt_block( &c, b0, b0 );
-           encrypt_block( &c, b0+8, b0+8 );
-       }
-       if( memcmp( a0, a1, 16 ) || memcmp( b0, b1, 16 ) )
-           return "3";
-
-    }
-#endif
-    return NULL;
-}
-
-
-static void
-key_schedule( u32 *x, u32 *z, u32 *k )
-{
-
-#define xi(i)   ((x[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
-#define zi(i)   ((z[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
-
-    z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)];
-    z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)];
-    z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)];
-    z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)];
-    k[0] = s5[zi( 8)]^s6[zi( 9)]^s7[zi( 7)]^s8[zi( 6)]^s5[zi( 2)];
-    k[1] = s5[zi(10)]^s6[zi(11)]^s7[zi( 5)]^s8[zi( 4)]^s6[zi( 6)];
-    k[2] = s5[zi(12)]^s6[zi(13)]^s7[zi( 3)]^s8[zi( 2)]^s7[zi( 9)];
-    k[3] = s5[zi(14)]^s6[zi(15)]^s7[zi( 1)]^s8[zi( 0)]^s8[zi(12)];
-
-    x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)];
-    x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)];
-    x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)];
-    x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)];
-    k[4] = s5[xi( 3)]^s6[xi( 2)]^s7[xi(12)]^s8[xi(13)]^s5[xi( 8)];
-    k[5] = s5[xi( 1)]^s6[xi( 0)]^s7[xi(14)]^s8[xi(15)]^s6[xi(13)];
-    k[6] = s5[xi( 7)]^s6[xi( 6)]^s7[xi( 8)]^s8[xi( 9)]^s7[xi( 3)];
-    k[7] = s5[xi( 5)]^s6[xi( 4)]^s7[xi(10)]^s8[xi(11)]^s8[xi( 7)];
-
-    z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)];
-    z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)];
-    z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)];
-    z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)];
-    k[8] = s5[zi( 3)]^s6[zi( 2)]^s7[zi(12)]^s8[zi(13)]^s5[zi( 9)];
-    k[9] = s5[zi( 1)]^s6[zi( 0)]^s7[zi(14)]^s8[zi(15)]^s6[zi(12)];
-    k[10]= s5[zi( 7)]^s6[zi( 6)]^s7[zi( 8)]^s8[zi( 9)]^s7[zi( 2)];
-    k[11]= s5[zi( 5)]^s6[zi( 4)]^s7[zi(10)]^s8[zi(11)]^s8[zi( 6)];
-
-    x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)];
-    x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)];
-    x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)];
-    x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)];
-    k[12]= s5[xi( 8)]^s6[xi( 9)]^s7[xi( 7)]^s8[xi( 6)]^s5[xi( 3)];
-    k[13]= s5[xi(10)]^s6[xi(11)]^s7[xi( 5)]^s8[xi( 4)]^s6[xi( 7)];
-    k[14]= s5[xi(12)]^s6[xi(13)]^s7[xi( 3)]^s8[xi( 2)]^s7[xi( 8)];
-    k[15]= s5[xi(14)]^s6[xi(15)]^s7[xi( 1)]^s8[xi( 0)]^s8[xi(13)];
-
-#undef xi
-#undef zi
-}
-
-
-static gcry_err_code_t
-do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen )
-{
-  static int initialized;
-  static const char* selftest_failed;
-  int i;
-  u32 x[4];
-  u32 z[4];
-  u32 k[16];
-
-  if( !initialized ) 
-    {
-      initialized = 1;
-      selftest_failed = selftest();
-      if( selftest_failed )
-        log_error ("CAST5 selftest failed (%s).\n", selftest_failed );
-    }
-  if( selftest_failed )
-    return GPG_ERR_SELFTEST_FAILED;
-
-  if( keylen != 16 )
-    return GPG_ERR_INV_KEYLEN;
-
-  x[0] = key[0]  << 24 | key[1]  << 16 | key[2]  << 8 | key[3];
-  x[1] = key[4]  << 24 | key[5]  << 16 | key[6]  << 8 | key[7];
-  x[2] = key[8]  << 24 | key[9]  << 16 | key[10] << 8 | key[11];
-  x[3] = key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15];
-
-  key_schedule( x, z, k );
-  for(i=0; i < 16; i++ )
-    c->Km[i] = k[i];
-  key_schedule( x, z, k );
-  for(i=0; i < 16; i++ )
-    c->Kr[i] = k[i] & 0x1f;
-
-  memset(&x,0, sizeof x);
-  memset(&z,0, sizeof z);
-  memset(&k,0, sizeof k);
-
-#undef xi
-#undef zi
-  return GPG_ERR_NO_ERROR;
-}
-
-static gcry_err_code_t
-cast_setkey (void *context, const byte *key, unsigned keylen )
-{
-  CAST5_context *c = (CAST5_context *) context;
-  gcry_err_code_t rc = do_cast_setkey (c, key, keylen);
-  _gcry_burn_stack (96+7*sizeof(void*));
-  return rc;
-}
-
-
-gcry_cipher_spec_t _gcry_cipher_spec_cast5 =
-  {
-    "CAST5", NULL, NULL, CAST5_BLOCKSIZE, 128, sizeof (CAST5_context),
-    cast_setkey, encrypt_block, decrypt_block
-  };
diff --git a/lib/libgcrypt/cipher/cipher.c b/lib/libgcrypt/cipher/cipher.c
deleted file mode 100644 (file)
index 2c33ee9..0000000
+++ /dev/null
@@ -1,1932 +0,0 @@
-/* cipher.c  - cipher dispatcher
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
- *               2005, 2007, 2008 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#include "g10lib.h"
-#include "cipher.h"
-#include "ath.h"
-
-#define MAX_BLOCKSIZE 16
-#define TABLE_SIZE 14
-#define CTX_MAGIC_NORMAL 0x24091964
-#define CTX_MAGIC_SECURE 0x46919042
-
-#undef NEED_16BYTE_ALIGNED_CONTEXT
-#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
-#define NEED_16BYTE_ALIGNED_CONTEXT 1
-#endif
-
-/* A dummy extraspec so that we do not need to tests the extraspec
-   field from the module specification against NULL and instead
-   directly test the respective fields of extraspecs.  */
-static cipher_extra_spec_t dummy_extra_spec;
-
-/* This is the list of the default ciphers, which are included in
-   libgcrypt.  */
-static struct cipher_table_entry
-{
-  gcry_cipher_spec_t *cipher;
-  cipher_extra_spec_t *extraspec;
-  unsigned int algorithm;
-  int fips_allowed;
-} cipher_table[] =
-  {
-#if USE_BLOWFISH
-    { &_gcry_cipher_spec_blowfish,
-      &dummy_extra_spec,                  GCRY_CIPHER_BLOWFISH },
-#endif
-#if USE_DES
-    { &_gcry_cipher_spec_des,       
-      &dummy_extra_spec,                  GCRY_CIPHER_DES },
-    { &_gcry_cipher_spec_tripledes,
-      &_gcry_cipher_extraspec_tripledes,  GCRY_CIPHER_3DES, 1 },
-#endif
-#if USE_ARCFOUR
-    { &_gcry_cipher_spec_arcfour,    
-      &dummy_extra_spec,                  GCRY_CIPHER_ARCFOUR },
-#endif
-#if USE_CAST5
-    { &_gcry_cipher_spec_cast5,      
-      &dummy_extra_spec,                  GCRY_CIPHER_CAST5 },
-#endif
-#if USE_AES
-    { &_gcry_cipher_spec_aes,        
-      &_gcry_cipher_extraspec_aes,        GCRY_CIPHER_AES,    1 },
-    { &_gcry_cipher_spec_aes192,     
-      &_gcry_cipher_extraspec_aes192,     GCRY_CIPHER_AES192, 1 },
-    { &_gcry_cipher_spec_aes256,     
-      &_gcry_cipher_extraspec_aes256,     GCRY_CIPHER_AES256, 1 },
-#endif
-#if USE_TWOFISH
-    { &_gcry_cipher_spec_twofish,
-      &dummy_extra_spec,                  GCRY_CIPHER_TWOFISH },
-    { &_gcry_cipher_spec_twofish128,     
-      &dummy_extra_spec,                  GCRY_CIPHER_TWOFISH128 },
-#endif
-#if USE_SERPENT
-    { &_gcry_cipher_spec_serpent128, 
-      &dummy_extra_spec,                  GCRY_CIPHER_SERPENT128 },
-    { &_gcry_cipher_spec_serpent192,
-      &dummy_extra_spec,                  GCRY_CIPHER_SERPENT192 },
-    { &_gcry_cipher_spec_serpent256, 
-      &dummy_extra_spec,                  GCRY_CIPHER_SERPENT256 },
-#endif
-#if USE_RFC2268
-    { &_gcry_cipher_spec_rfc2268_40,
-      &dummy_extra_spec,                  GCRY_CIPHER_RFC2268_40 },
-#endif
-#if USE_SEED
-    { &_gcry_cipher_spec_seed, 
-      &dummy_extra_spec,                  GCRY_CIPHER_SEED },
-#endif
-#if USE_CAMELLIA
-    { &_gcry_cipher_spec_camellia128,
-      &dummy_extra_spec,                  GCRY_CIPHER_CAMELLIA128 },
-    { &_gcry_cipher_spec_camellia192, 
-      &dummy_extra_spec,                  GCRY_CIPHER_CAMELLIA192 },
-    { &_gcry_cipher_spec_camellia256,
-      &dummy_extra_spec,                  GCRY_CIPHER_CAMELLIA256 },
-#endif
-    { NULL                    }
-  };
-
-/* List of registered ciphers.  */
-static gcry_module_t ciphers_registered;
-
-/* This is the lock protecting CIPHERS_REGISTERED.  */
-static ath_mutex_t ciphers_registered_lock = ATH_MUTEX_INITIALIZER;
-
-/* Flag to check wether the default ciphers have already been
-   registered.  */
-static int default_ciphers_registered;
-
-/* Convenient macro for registering the default ciphers.  */
-#define REGISTER_DEFAULT_CIPHERS                   \
-  do                                               \
-    {                                              \
-      ath_mutex_lock (&ciphers_registered_lock);   \
-      if (! default_ciphers_registered)            \
-        {                                          \
-          cipher_register_default ();              \
-          default_ciphers_registered = 1;          \
-        }                                          \
-      ath_mutex_unlock (&ciphers_registered_lock); \
-    }                                              \
-  while (0)
-
-
-/* A VIA processor with the Padlock engine requires an alignment of
-   most data on a 16 byte boundary.  Because we trick out the compiler
-   while allocating the context, the align attribute as used in
-   rijndael.c does not work on its own.  Thus we need to make sure
-   that the entire context structure is a aligned on that boundary.
-   We achieve this by defining a new type and use that instead of our
-   usual alignment type.  */
-typedef union 
-{
-  PROPERLY_ALIGNED_TYPE foo;
-#ifdef NEED_16BYTE_ALIGNED_CONTEXT
-  char bar[16] __attribute__ ((aligned (16)));
-#endif  
-  char c[1];
-} cipher_context_alignment_t;
-
-
-/* The handle structure.  */
-struct gcry_cipher_handle
-{
-  int magic;
-  size_t actual_handle_size;     /* Allocated size of this handle. */
-  size_t handle_offset;          /* Offset to the malloced block.  */
-  gcry_cipher_spec_t *cipher;
-  cipher_extra_spec_t *extraspec;
-  gcry_module_t module;
-
-  /* The algorithm id.  This is a hack required because the module
-     interface does not easily allow to retrieve this value. */
-  int algo;  
-
-  /* A structure with function pointers for bulk operations.  Due to
-     limitations of the module system (we don't want to change the
-     API) we need to keep these function pointers here.  The cipher
-     open function intializes them and the actual encryption routines
-     use them if they are not NULL.  */
-  struct {
-    void (*cfb_enc)(void *context, unsigned char *iv, 
-                    void *outbuf_arg, const void *inbuf_arg,
-                    unsigned int nblocks);
-    void (*cfb_dec)(void *context, unsigned char *iv, 
-                    void *outbuf_arg, const void *inbuf_arg,
-                    unsigned int nblocks);
-    void (*cbc_enc)(void *context, unsigned char *iv, 
-                    void *outbuf_arg, const void *inbuf_arg,
-                    unsigned int nblocks, int cbc_mac);
-    void (*cbc_dec)(void *context, unsigned char *iv, 
-                    void *outbuf_arg, const void *inbuf_arg,
-                    unsigned int nblocks);
-  } bulk;
-
-
-  int mode;
-  unsigned int flags;
-
-  /* The initialization vector.  To help code optimization we make
-     sure that it is aligned on an unsigned long and u32 boundary.  */
-  union {
-    unsigned long dummy_iv;         
-    u32 dummy_u32_iv;
-    unsigned char iv[MAX_BLOCKSIZE];   
-  } u_iv;
-
-  unsigned char lastiv[MAX_BLOCKSIZE];
-  int unused;  /* Number of unused bytes in the IV. */
-
-  unsigned char ctr[MAX_BLOCKSIZE];     /* For Counter (CTR) mode. */
-
-
-  /* What follows are two contexts of the cipher in use.  The first
-     one needs to be aligned well enough for the cipher operation
-     whereas the second one is a copy created by cipher_setkey and
-     used by cipher_reset.  That second copy has no need for proper
-     aligment because it is only accessed by memcpy.  */
-  cipher_context_alignment_t context;
-};
-
-
-\f
-/* These dummy functions are used in case a cipher implementation
-   refuses to provide it's own functions.  */
-
-static gcry_err_code_t
-dummy_setkey (void *c, const unsigned char *key, unsigned int keylen)
-{
-  (void)c; 
-  (void)key;
-  (void)keylen;
-  return GPG_ERR_NO_ERROR;
-}
-
-static void
-dummy_encrypt_block (void *c,
-                    unsigned char *outbuf, const unsigned char *inbuf)
-{
-  (void)c;
-  (void)outbuf;
-  (void)inbuf;
-  BUG();
-}
-
-static void
-dummy_decrypt_block (void *c,
-                    unsigned char *outbuf, const unsigned char *inbuf)
-{
-  (void)c;
-  (void)outbuf;
-  (void)inbuf;
-  BUG();
-}
-
-static void
-dummy_encrypt_stream (void *c,
-                     unsigned char *outbuf, const unsigned char *inbuf,
-                     unsigned int n)
-{
-  (void)c;
-  (void)outbuf;
-  (void)inbuf;
-  (void)n;
-  BUG();
-}
-
-static void
-dummy_decrypt_stream (void *c,
-                     unsigned char *outbuf, const unsigned char *inbuf,
-                     unsigned int n)
-{
-  (void)c;
-  (void)outbuf;
-  (void)inbuf;
-  (void)n;
-  BUG();
-}
-
-\f
-/* Internal function.  Register all the ciphers included in
-   CIPHER_TABLE.  Note, that this function gets only used by the macro
-   REGISTER_DEFAULT_CIPHERS which protects it using a mutex. */
-static void
-cipher_register_default (void)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  int i;
-  
-  for (i = 0; !err && cipher_table[i].cipher; i++)
-    {
-      if (! cipher_table[i].cipher->setkey)
-       cipher_table[i].cipher->setkey = dummy_setkey;
-      if (! cipher_table[i].cipher->encrypt)
-       cipher_table[i].cipher->encrypt = dummy_encrypt_block;
-      if (! cipher_table[i].cipher->decrypt)
-       cipher_table[i].cipher->decrypt = dummy_decrypt_block;
-      if (! cipher_table[i].cipher->stencrypt)
-       cipher_table[i].cipher->stencrypt = dummy_encrypt_stream;
-      if (! cipher_table[i].cipher->stdecrypt)
-       cipher_table[i].cipher->stdecrypt = dummy_decrypt_stream;
-
-      if ( fips_mode () && !cipher_table[i].fips_allowed )
-        continue;
-
-      err = _gcry_module_add (&ciphers_registered,
-                             cipher_table[i].algorithm,
-                             (void *) cipher_table[i].cipher,
-                             (void *) cipher_table[i].extraspec,
-                             NULL);
-    }
-
-  if (err)
-    BUG ();
-}
-
-/* Internal callback function.  Used via _gcry_module_lookup.  */
-static int
-gcry_cipher_lookup_func_name (void *spec, void *data)
-{
-  gcry_cipher_spec_t *cipher = (gcry_cipher_spec_t *) spec;
-  char *name = (char *) data;
-  const char **aliases = cipher->aliases;
-  int i, ret = ! stricmp (name, cipher->name);
-
-  if (aliases)
-    for (i = 0; aliases[i] && (! ret); i++)
-      ret = ! stricmp (name, aliases[i]);
-
-  return ret;
-}
-
-/* Internal callback function.  Used via _gcry_module_lookup.  */
-static int
-gcry_cipher_lookup_func_oid (void *spec, void *data)
-{
-  gcry_cipher_spec_t *cipher = (gcry_cipher_spec_t *) spec;
-  char *oid = (char *) data;
-  gcry_cipher_oid_spec_t *oid_specs = cipher->oids;
-  int ret = 0, i;
-
-  if (oid_specs)
-    for (i = 0; oid_specs[i].oid && (! ret); i++)
-      if (! stricmp (oid, oid_specs[i].oid))
-       ret = 1;
-
-  return ret;
-}
-
-/* Internal function.  Lookup a cipher entry by it's name.  */
-static gcry_module_t
-gcry_cipher_lookup_name (const char *name)
-{
-  gcry_module_t cipher;
-
-  cipher = _gcry_module_lookup (ciphers_registered, (void *) name,
-                               gcry_cipher_lookup_func_name);
-
-  return cipher;
-}
-
-/* Internal function.  Lookup a cipher entry by it's oid.  */
-static gcry_module_t
-gcry_cipher_lookup_oid (const char *oid)
-{
-  gcry_module_t cipher;
-
-  cipher = _gcry_module_lookup (ciphers_registered, (void *) oid,
-                               gcry_cipher_lookup_func_oid);
-
-  return cipher;
-}
-
-/* Register a new cipher module whose specification can be found in
-   CIPHER.  On success, a new algorithm ID is stored in ALGORITHM_ID
-   and a pointer representhing this module is stored in MODULE.  */
-gcry_error_t
-_gcry_cipher_register (gcry_cipher_spec_t *cipher,
-                       cipher_extra_spec_t *extraspec,
-                       int *algorithm_id,
-                       gcry_module_t *module)
-{
-  gcry_err_code_t err = 0;
-  gcry_module_t mod;
-
-  /* We do not support module loading in fips mode.  */
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  ath_mutex_lock (&ciphers_registered_lock);
-  err = _gcry_module_add (&ciphers_registered, 0,
-                         (void *)cipher, 
-                         (void *)(extraspec? extraspec : &dummy_extra_spec), 
-                          &mod);
-  ath_mutex_unlock (&ciphers_registered_lock);
-
-  if (! err)
-    {
-      *module = mod;
-      *algorithm_id = mod->mod_id;
-    }
-
-  return gcry_error (err);
-}
-
-/* Unregister the cipher identified by MODULE, which must have been
-   registered with gcry_cipher_register.  */
-void
-gcry_cipher_unregister (gcry_module_t module)
-{
-  ath_mutex_lock (&ciphers_registered_lock);
-  _gcry_module_release (module);
-  ath_mutex_unlock (&ciphers_registered_lock);
-}
-
-/* Locate the OID in the oid table and return the index or -1 when not
-   found.  An opitonal "oid." or "OID." prefix in OID is ignored, the
-   OID is expected to be in standard IETF dotted notation.  The
-   internal algorithm number is returned in ALGORITHM unless it
-   ispassed as NULL.  A pointer to the specification of the module
-   implementing this algorithm is return in OID_SPEC unless passed as
-   NULL.*/
-static int 
-search_oid (const char *oid, int *algorithm, gcry_cipher_oid_spec_t *oid_spec)
-{
-  gcry_module_t module;
-  int ret = 0;
-
-  if (oid && ((! strncmp (oid, "oid.", 4))
-             || (! strncmp (oid, "OID.", 4))))
-    oid += 4;
-
-  module = gcry_cipher_lookup_oid (oid);
-  if (module)
-    {
-      gcry_cipher_spec_t *cipher = module->spec;
-      int i;
-
-      for (i = 0; cipher->oids[i].oid && !ret; i++)
-       if (! stricmp (oid, cipher->oids[i].oid))
-         {
-           if (algorithm)
-             *algorithm = module->mod_id;
-           if (oid_spec)
-             *oid_spec = cipher->oids[i];
-           ret = 1;
-         }
-      _gcry_module_release (module);
-    }
-
-  return ret;
-}
-
-/* Map STRING to the cipher algorithm identifier.  Returns the
-   algorithm ID of the cipher for the given name or 0 if the name is
-   not known.  It is valid to pass NULL for STRING which results in a
-   return value of 0. */
-int
-gcry_cipher_map_name (const char *string)
-{
-  gcry_module_t cipher;
-  int ret, algorithm = 0;
-
-  if (! string)
-    return 0;
-
-  REGISTER_DEFAULT_CIPHERS;
-
-  /* If the string starts with a digit (optionally prefixed with
-     either "OID." or "oid."), we first look into our table of ASN.1
-     object identifiers to figure out the algorithm */
-
-  ath_mutex_lock (&ciphers_registered_lock);
-
-  ret = search_oid (string, &algorithm, NULL);
-  if (! ret)
-    {
-      cipher = gcry_cipher_lookup_name (string);
-      if (cipher)
-       {
-         algorithm = cipher->mod_id;
-         _gcry_module_release (cipher);
-       }
-    }
-
-  ath_mutex_unlock (&ciphers_registered_lock);
-  
-  return algorithm;
-}
-
-
-/* Given a STRING with an OID in dotted decimal notation, this
-   function returns the cipher mode (GCRY_CIPHER_MODE_*) associated
-   with that OID or 0 if no mode is known.  Passing NULL for string
-   yields a return value of 0. */
-int
-gcry_cipher_mode_from_oid (const char *string)
-{
-  gcry_cipher_oid_spec_t oid_spec;
-  int ret = 0, mode = 0;
-
-  if (!string)
-    return 0;
-
-  ath_mutex_lock (&ciphers_registered_lock);
-  ret = search_oid (string, NULL, &oid_spec);
-  if (ret)
-    mode = oid_spec.mode;
-  ath_mutex_unlock (&ciphers_registered_lock);
-
-  return mode;
-}
-
-
-/* Map the cipher algorithm whose ID is contained in ALGORITHM to a
-   string representation of the algorithm name.  For unknown algorithm
-   IDs this function returns "?".  */
-static const char *
-cipher_algo_to_string (int algorithm)
-{
-  gcry_module_t cipher;
-  const char *name;
-
-  REGISTER_DEFAULT_CIPHERS;
-
-  ath_mutex_lock (&ciphers_registered_lock);
-  cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
-  if (cipher)
-    {
-      name = ((gcry_cipher_spec_t *) cipher->spec)->name;
-      _gcry_module_release (cipher);
-    }
-  else
-    name = "?";
-  ath_mutex_unlock (&ciphers_registered_lock);
-
-  return name;
-}
-
-/* Map the cipher algorithm identifier ALGORITHM to a string
-   representing this algorithm.  This string is the default name as
-   used by Libgcrypt.  An pointer to an empty string is returned for
-   an unknown algorithm.  NULL is never returned. */
-const char *
-gcry_cipher_algo_name (int algorithm)
-{
-  return cipher_algo_to_string (algorithm);
-}
-
-
-/* Flag the cipher algorithm with the identifier ALGORITHM as
-   disabled.  There is no error return, the function does nothing for
-   unknown algorithms.  Disabled algorithms are vitually not available
-   in Libgcrypt. */
-static void
-disable_cipher_algo (int algorithm)
-{
-  gcry_module_t cipher;
-
-  REGISTER_DEFAULT_CIPHERS;
-
-  ath_mutex_lock (&ciphers_registered_lock);
-  cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
-  if (cipher)
-    {
-      if (! (cipher->flags & FLAG_MODULE_DISABLED))
-       cipher->flags |= FLAG_MODULE_DISABLED;
-      _gcry_module_release (cipher);
-    }
-  ath_mutex_unlock (&ciphers_registered_lock);
-}
-
-
-/* Return 0 if the cipher algorithm with identifier ALGORITHM is
-   available. Returns a basic error code value if it is not
-   available.  */
-static gcry_err_code_t
-check_cipher_algo (int algorithm)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_module_t cipher;
-
-  REGISTER_DEFAULT_CIPHERS;
-
-  ath_mutex_lock (&ciphers_registered_lock);
-  cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
-  if (cipher)
-    {
-      if (cipher->flags & FLAG_MODULE_DISABLED)
-       err = GPG_ERR_CIPHER_ALGO;
-      _gcry_module_release (cipher);
-    }
-  else
-    err = GPG_ERR_CIPHER_ALGO;
-  ath_mutex_unlock (&ciphers_registered_lock);
-  
-  return err;
-}
-
-
-/* Return the standard length of the key for the cipher algorithm with
-   the identifier ALGORITHM.  This function expects a valid algorithm
-   and will abort if the algorithm is not available or the length of
-   the key is not known. */
-static unsigned int
-cipher_get_keylen (int algorithm)
-{
-  gcry_module_t cipher;
-  unsigned len = 0;
-
-  REGISTER_DEFAULT_CIPHERS;
-
-  ath_mutex_lock (&ciphers_registered_lock);
-  cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
-  if (cipher)
-    {
-      len = ((gcry_cipher_spec_t *) cipher->spec)->keylen;
-      if (!len)
-       log_bug ("cipher %d w/o key length\n", algorithm);
-      _gcry_module_release (cipher);
-    }
-  else
-    log_bug ("cipher %d not found\n", algorithm);
-  ath_mutex_unlock (&ciphers_registered_lock);
-
-  return len;
-}
-
-/* Return the block length of the cipher algorithm with the identifier
-   ALGORITHM.  This function expects a valid algorithm and will abort
-   if the algorithm is not available or the length of the key is not
-   known. */
-static unsigned int
-cipher_get_blocksize (int algorithm)
-{
-  gcry_module_t cipher;
-  unsigned len = 0;
-
-  REGISTER_DEFAULT_CIPHERS;
-
-  ath_mutex_lock (&ciphers_registered_lock);
-  cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
-  if (cipher)
-    {
-      len = ((gcry_cipher_spec_t *) cipher->spec)->blocksize;
-      if (! len)
-         log_bug ("cipher %d w/o blocksize\n", algorithm);
-      _gcry_module_release (cipher);
-    }
-  else
-    log_bug ("cipher %d not found\n", algorithm);
-  ath_mutex_unlock (&ciphers_registered_lock);
-
-  return len;
-}
-
-
-/*
-   Open a cipher handle for use with cipher algorithm ALGORITHM, using
-   the cipher mode MODE (one of the GCRY_CIPHER_MODE_*) and return a
-   handle in HANDLE.  Put NULL into HANDLE and return an error code if
-   something goes wrong.  FLAGS may be used to modify the
-   operation.  The defined flags are:
-
-   GCRY_CIPHER_SECURE:  allocate all internal buffers in secure memory.
-   GCRY_CIPHER_ENABLE_SYNC:  Enable the sync operation as used in OpenPGP.
-   GCRY_CIPHER_CBC_CTS:  Enable CTS mode.
-   GCRY_CIPHER_CBC_MAC:  Enable MAC mode.
-
-   Values for these flags may be combined using OR.
- */
-gcry_error_t
-gcry_cipher_open (gcry_cipher_hd_t *handle,
-                 int algo, int mode, unsigned int flags)
-{
-  int secure = (flags & GCRY_CIPHER_SECURE);
-  gcry_cipher_spec_t *cipher = NULL;
-  cipher_extra_spec_t *extraspec = NULL;
-  gcry_module_t module = NULL;
-  gcry_cipher_hd_t h = NULL;
-  gcry_err_code_t err = 0;
-
-  /* If the application missed to call the random poll function, we do
-     it here to ensure that it is used once in a while. */
-  _gcry_fast_random_poll ();
-  
-  REGISTER_DEFAULT_CIPHERS;
-
-  /* Fetch the according module and check wether the cipher is marked
-     available for use.  */
-  ath_mutex_lock (&ciphers_registered_lock);
-  module = _gcry_module_lookup_id (ciphers_registered, algo);
-  if (module)
-    {
-      /* Found module.  */
-
-      if (module->flags & FLAG_MODULE_DISABLED)
-       {
-         /* Not available for use.  */
-         err = GPG_ERR_CIPHER_ALGO;
-         _gcry_module_release (module);
-       }
-      else
-        {
-          cipher = (gcry_cipher_spec_t *) module->spec;
-          extraspec = module->extraspec;
-        }
-    }
-  else
-    err = GPG_ERR_CIPHER_ALGO;
-  ath_mutex_unlock (&ciphers_registered_lock);
-
-  /* check flags */
-  if ((! err)
-      && ((flags & ~(0 
-                    | GCRY_CIPHER_SECURE
-                    | GCRY_CIPHER_ENABLE_SYNC
-                    | GCRY_CIPHER_CBC_CTS
-                    | GCRY_CIPHER_CBC_MAC))
-         || (flags & GCRY_CIPHER_CBC_CTS & GCRY_CIPHER_CBC_MAC)))
-    err = GPG_ERR_CIPHER_ALGO;
-
-  /* check that a valid mode has been requested */
-  if (! err)
-    switch (mode)
-      {
-      case GCRY_CIPHER_MODE_ECB:
-      case GCRY_CIPHER_MODE_CBC:
-      case GCRY_CIPHER_MODE_CFB:
-      case GCRY_CIPHER_MODE_OFB:
-      case GCRY_CIPHER_MODE_CTR:
-       if ((cipher->encrypt == dummy_encrypt_block)
-           || (cipher->decrypt == dummy_decrypt_block))
-         err = GPG_ERR_INV_CIPHER_MODE;
-       break;
-
-      case GCRY_CIPHER_MODE_STREAM:
-       if ((cipher->stencrypt == dummy_encrypt_stream)
-           || (cipher->stdecrypt == dummy_decrypt_stream))
-         err = GPG_ERR_INV_CIPHER_MODE;
-       break;
-
-      case GCRY_CIPHER_MODE_NONE:
-        /* This mode may be used for debugging.  It copies the main
-           text verbatim to the ciphertext.  We do not allow this in
-           fips mode or if no debug flag has been set.  */
-       if (fips_mode () || !_gcry_get_debug_flag (0))
-          err = GPG_ERR_INV_CIPHER_MODE;
-       break;
-
-      default:
-       err = GPG_ERR_INV_CIPHER_MODE;
-      }
-
-  /* Perform selftest here and mark this with a flag in cipher_table?
-     No, we should not do this as it takes too long.  Further it does
-     not make sense to exclude algorithms with failing selftests at
-     runtime: If a selftest fails there is something seriously wrong
-     with the system and thus we better die immediately. */
-
-  if (! err)
-    {
-      size_t size = (sizeof (*h)
-                     + 2 * cipher->contextsize
-                     - sizeof (cipher_context_alignment_t)
-#ifdef NEED_16BYTE_ALIGNED_CONTEXT
-                     + 15  /* Space for leading alignment gap.  */
-#endif /*NEED_16BYTE_ALIGNED_CONTEXT*/
-                     );
-
-      if (secure)
-       h = gcry_calloc_secure (1, size);
-      else
-       h = gcry_calloc (1, size);
-
-      if (! h)
-       err = gpg_err_code_from_errno (errno);
-      else
-       {
-          size_t off = 0;
-
-#ifdef NEED_16BYTE_ALIGNED_CONTEXT
-          if ( ((unsigned long)h & 0x0f) )
-            {
-              /* The malloced block is not aligned on a 16 byte
-                 boundary.  Correct for this.  */
-              off = 16 - ((unsigned long)h & 0x0f);
-              h = (void*)((char*)h + off);
-            }
-#endif /*NEED_16BYTE_ALIGNED_CONTEXT*/
-
-         h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
-          h->actual_handle_size = size - off;
-          h->handle_offset = off;
-         h->cipher = cipher;
-         h->extraspec = extraspec;
-         h->module = module;
-          h->algo = algo;
-         h->mode = mode;
-         h->flags = flags;
-
-          /* Setup bulk encryption routines.  */
-          switch (algo)
-            {
-#ifdef USE_AES
-            case GCRY_CIPHER_AES128:
-            case GCRY_CIPHER_AES192:
-            case GCRY_CIPHER_AES256:
-              h->bulk.cfb_enc = _gcry_aes_cfb_enc;
-              h->bulk.cfb_dec = _gcry_aes_cfb_dec;
-              h->bulk.cbc_enc = _gcry_aes_cbc_enc;
-              h->bulk.cbc_dec = _gcry_aes_cbc_dec;
-              break;
-#endif /*USE_AES*/
-              
-            default:
-              break;
-            }
-       }
-    }
-
-  /* Done.  */
-
-  if (err)
-    {
-      if (module)
-       {
-         /* Release module.  */
-         ath_mutex_lock (&ciphers_registered_lock);
-         _gcry_module_release (module);
-         ath_mutex_unlock (&ciphers_registered_lock);
-       }
-    }
-
-  *handle = err ? NULL : h;
-
-  return gcry_error (err);
-}
-
-
-/* Release all resources associated with the cipher handle H. H may be
-   NULL in which case this is a no-operation. */
-void
-gcry_cipher_close (gcry_cipher_hd_t h)
-{
-  size_t off;
-
-  if (!h)
-    return;
-
-  if ((h->magic != CTX_MAGIC_SECURE)
-      && (h->magic != CTX_MAGIC_NORMAL))
-    _gcry_fatal_error(GPG_ERR_INTERNAL,
-                     "gcry_cipher_close: already closed/invalid handle");
-  else
-    h->magic = 0;
-
-  /* Release module.  */
-  ath_mutex_lock (&ciphers_registered_lock);
-  _gcry_module_release (h->module);
-  ath_mutex_unlock (&ciphers_registered_lock);
-
-  /* We always want to wipe out the memory even when the context has
-     been allocated in secure memory.  The user might have disabled
-     secure memory or is using his own implementation which does not
-     do the wiping.  To accomplish this we need to keep track of the
-     actual size of this structure because we have no way to known
-     how large the allocated area was when using a standard malloc. */
-  off = h->handle_offset;
-  wipememory (h, h->actual_handle_size);
-
-  gcry_free ((char*)h - off);
-}
-
-
-/* Set the key to be used for the encryption context C to KEY with
-   length KEYLEN.  The length should match the required length. */
-static gcry_error_t
-cipher_setkey (gcry_cipher_hd_t c, byte *key, unsigned int keylen)
-{
-  gcry_err_code_t ret;
-
-  ret = (*c->cipher->setkey) (&c->context.c, key, keylen);
-  if (!ret)
-    {
-      /* Duplicate initial context.  */
-      memcpy ((void *) ((char *) &c->context.c + c->cipher->contextsize),
-              (void *) &c->context.c,
-              c->cipher->contextsize);
-    }
-
-  return gcry_error (ret);
-}
-
-
-/* Set the IV to be used for the encryption context C to IV with
-   length IVLEN.  The length should match the required length. */
-static void
-cipher_setiv( gcry_cipher_hd_t c, const byte *iv, unsigned ivlen )
-{
-  memset (c->u_iv.iv, 0, c->cipher->blocksize);
-  if (iv) 
-    {
-      if (ivlen != c->cipher->blocksize)
-        {
-          log_info ("WARNING: cipher_setiv: ivlen=%u blklen=%u\n",
-                    ivlen, (unsigned int)c->cipher->blocksize);
-          fips_signal_error ("IV length does not match blocklength");
-        }
-      if (ivlen > c->cipher->blocksize)
-        ivlen = c->cipher->blocksize;
-      memcpy (c->u_iv.iv, iv, ivlen);
-    }
-  c->unused = 0;
-}
-
-
-/* Reset the cipher context to the initial context.  This is basically
-   the same as an release followed by a new. */
-static void
-cipher_reset (gcry_cipher_hd_t c)
-{
-  memcpy (&c->context.c,
-         (char *) &c->context.c + c->cipher->contextsize,
-         c->cipher->contextsize);
-  memset (c->u_iv.iv, 0, c->cipher->blocksize);
-  memset (c->lastiv, 0, c->cipher->blocksize);
-  memset (c->ctr, 0, c->cipher->blocksize);
-}
-
-
-static void
-do_ecb_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
-                unsigned int nblocks )
-{
-  unsigned int n;
-  
-  for (n=0; n < nblocks; n++ )
-    {
-      c->cipher->encrypt ( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
-      inbuf  += c->cipher->blocksize;
-      outbuf += c->cipher->blocksize;
-    }
-}
-
-static void
-do_ecb_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
-                unsigned int nblocks )
-{
-  unsigned int n;
-
-  for (n=0; n < nblocks; n++ ) 
-    {
-      c->cipher->decrypt ( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
-      inbuf  += c->cipher->blocksize;
-      outbuf += c->cipher->blocksize;
-    }
-}
-
-
-static void
-do_cbc_encrypt (gcry_cipher_hd_t c, unsigned char *outbuf, 
-                const unsigned char *inbuf, unsigned int nbytes )
-{
-  unsigned int n;
-  unsigned char *ivp;
-  int i;
-  size_t blocksize = c->cipher->blocksize;
-  unsigned nblocks = nbytes / blocksize;
-
-  if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) 
-    {
-      if ((nbytes % blocksize) == 0)
-       nblocks--;
-    }
-
-  if (c->bulk.cbc_enc)
-    {
-      c->bulk.cbc_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks,
-                       (c->flags & GCRY_CIPHER_CBC_MAC)); 
-      inbuf  += nblocks * blocksize;
-      if (!(c->flags & GCRY_CIPHER_CBC_MAC))
-        outbuf += nblocks * blocksize;
-    }
-  else
-    {
-      for (n=0; n < nblocks; n++ )
-        {
-          for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-            outbuf[i] = inbuf[i] ^ *ivp++;
-          c->cipher->encrypt ( &c->context.c, outbuf, outbuf );
-          memcpy (c->u_iv.iv, outbuf, blocksize );
-          inbuf  += blocksize;
-          if (!(c->flags & GCRY_CIPHER_CBC_MAC))
-            outbuf += blocksize;
-        }
-    }
-
-  if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize)
-    {
-      /* We have to be careful here, since outbuf might be equal to
-         inbuf.  */
-      int restbytes;
-      unsigned char b;
-
-      if ((nbytes % blocksize) == 0)
-        restbytes = blocksize;
-      else
-        restbytes = nbytes % blocksize;
-
-      outbuf -= blocksize;
-      for (ivp = c->u_iv.iv, i = 0; i < restbytes; i++)
-        {
-          b = inbuf[i];
-          outbuf[blocksize + i] = outbuf[i];
-          outbuf[i] = b ^ *ivp++;
-        }
-      for (; i < blocksize; i++)
-        outbuf[i] = 0 ^ *ivp++;
-      
-      c->cipher->encrypt (&c->context.c, outbuf, outbuf);
-      memcpy (c->u_iv.iv, outbuf, blocksize);
-    }
-}
-
-
-static void
-do_cbc_decrypt (gcry_cipher_hd_t c, unsigned char *outbuf, 
-                const unsigned char *inbuf, unsigned int nbytes)
-{
-  unsigned int n;
-  unsigned char *ivp;
-  int i;
-  size_t blocksize = c->cipher->blocksize;
-  unsigned int nblocks = nbytes / blocksize;
-
-  if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize)
-    {
-      nblocks--;
-      if ((nbytes % blocksize) == 0)
-       nblocks--;
-      memcpy (c->lastiv, c->u_iv.iv, blocksize);
-    }
-
-  if (c->bulk.cbc_dec)
-    {
-      c->bulk.cbc_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks); 
-      inbuf  += nblocks * blocksize;
-      outbuf += nblocks * blocksize;
-    }
-  else
-    {
-      for (n=0; n < nblocks; n++ ) 
-        {
-          /* Because outbuf and inbuf might be the same, we have to
-           * save the original ciphertext block.  We use LASTIV for
-           * this here because it is not used otherwise. */
-          memcpy (c->lastiv, inbuf, blocksize);
-          c->cipher->decrypt ( &c->context.c, outbuf, inbuf );
-          for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-           outbuf[i] ^= *ivp++;
-          memcpy(c->u_iv.iv, c->lastiv, blocksize );
-          inbuf  += c->cipher->blocksize;
-          outbuf += c->cipher->blocksize;
-        }
-    }
-
-  if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) 
-    {
-      int restbytes;
-      
-      if ((nbytes % blocksize) == 0)
-        restbytes = blocksize;
-      else
-        restbytes = nbytes % blocksize;
-      
-      memcpy (c->lastiv, c->u_iv.iv, blocksize );         /* Save Cn-2. */
-      memcpy (c->u_iv.iv, inbuf + blocksize, restbytes ); /* Save Cn. */
-
-      c->cipher->decrypt ( &c->context.c, outbuf, inbuf );
-      for (ivp=c->u_iv.iv,i=0; i < restbytes; i++ )
-        outbuf[i] ^= *ivp++;
-      
-      memcpy(outbuf + blocksize, outbuf, restbytes);
-      for(i=restbytes; i < blocksize; i++)
-        c->u_iv.iv[i] = outbuf[i];
-      c->cipher->decrypt (&c->context.c, outbuf, c->u_iv.iv);
-      for(ivp=c->lastiv,i=0; i < blocksize; i++ )
-        outbuf[i] ^= *ivp++;
-      /* c->lastiv is now really lastlastiv, does this matter? */
-    }
-}
-
-
-static void
-do_cfb_encrypt( gcry_cipher_hd_t c, unsigned char *outbuf, 
-                const unsigned char *inbuf, unsigned int nbytes )
-{
-  unsigned char *ivp;
-  size_t blocksize = c->cipher->blocksize;
-  size_t blocksize_x_2 = blocksize + blocksize;
-  
-  if ( nbytes <= c->unused )
-    {
-      /* Short enough to be encoded by the remaining XOR mask. */
-      /* XOR the input with the IV and store input into IV. */
-      for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused;
-           nbytes;
-           nbytes--, c->unused-- )
-        *outbuf++ = (*ivp++ ^= *inbuf++);
-      return;
-    }
-
-  if ( c->unused )
-    {
-      /* XOR the input with the IV and store input into IV */
-      nbytes -= c->unused;
-      for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
-        *outbuf++ = (*ivp++ ^= *inbuf++);
-    }
-
-  /* Now we can process complete blocks.  We use a loop as long as we
-     have at least 2 blocks and use conditions for the rest.  This
-     also allows to use a bulk encryption function if available.  */
-  if (nbytes >= blocksize_x_2 && c->bulk.cfb_enc)
-    {
-      unsigned int nblocks = nbytes / blocksize;
-      c->bulk.cfb_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks); 
-      outbuf += nblocks * blocksize;
-      inbuf  += nblocks * blocksize;
-      nbytes -= nblocks * blocksize;
-    }
-  else
-    {
-      while ( nbytes >= blocksize_x_2 )
-        {
-          int i;
-          /* Encrypt the IV. */
-          c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-          /* XOR the input with the IV and store input into IV.  */
-          for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-            *outbuf++ = (*ivp++ ^= *inbuf++);
-          nbytes -= blocksize;
-        }
-    }
-
-  if ( nbytes >= blocksize )
-    {
-      int i;
-      /* Save the current IV and then encrypt the IV. */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      /* XOR the input with the IV and store input into IV */
-      for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-        *outbuf++ = (*ivp++ ^= *inbuf++);
-      nbytes -= blocksize;
-    }
-  if ( nbytes ) 
-    {
-      /* Save the current IV and then encrypt the IV. */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      c->unused = blocksize;
-      /* Apply the XOR. */
-      c->unused -= nbytes;
-      for(ivp=c->u_iv.iv; nbytes; nbytes-- )
-        *outbuf++ = (*ivp++ ^= *inbuf++);
-    }
-}
-
-
-static void
-do_cfb_decrypt( gcry_cipher_hd_t c, unsigned char *outbuf, 
-                const unsigned char *inbuf, unsigned int nbytes )
-{
-  unsigned char *ivp;
-  unsigned long temp;
-  int i;
-  size_t blocksize = c->cipher->blocksize;
-  size_t blocksize_x_2 = blocksize + blocksize;
-  
-  if (nbytes <= c->unused)
-    {
-      /* Short enough to be encoded by the remaining XOR mask. */
-      /* XOR the input with the IV and store input into IV. */
-      for (ivp=c->u_iv.iv+blocksize - c->unused;
-           nbytes; 
-           nbytes--, c->unused--)
-        {
-          temp = *inbuf++;
-          *outbuf++ = *ivp ^ temp;
-          *ivp++ = temp;
-        }
-      return;
-    }
-  
-  if (c->unused)
-    {
-      /* XOR the input with the IV and store input into IV. */
-      nbytes -= c->unused;
-      for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
-        {
-          temp = *inbuf++;
-          *outbuf++ = *ivp ^ temp;
-          *ivp++ = temp;
-        }
-    }
-  
-  /* Now we can process complete blocks.  We use a loop as long as we
-     have at least 2 blocks and use conditions for the rest.  This
-     also allows to use a bulk encryption function if available.  */
-  if (nbytes >= blocksize_x_2 && c->bulk.cfb_dec)
-    {
-      unsigned int nblocks = nbytes / blocksize;
-      c->bulk.cfb_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks); 
-      outbuf += nblocks * blocksize;
-      inbuf  += nblocks * blocksize;
-      nbytes -= nblocks * blocksize;
-    }
-  else
-    {
-      while (nbytes >= blocksize_x_2 )
-        {
-          /* Encrypt the IV. */
-          c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-          /* XOR the input with the IV and store input into IV. */
-          for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-            {
-              temp = *inbuf++;
-              *outbuf++ = *ivp ^ temp;
-              *ivp++ = temp;
-            }
-          nbytes -= blocksize;
-        }
-    }
-
-  if (nbytes >= blocksize )
-    {
-      /* Save the current IV and then encrypt the IV. */
-      memcpy ( c->lastiv, c->u_iv.iv, blocksize);
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      /* XOR the input with the IV and store input into IV */
-      for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-        {
-          temp = *inbuf++;
-          *outbuf++ = *ivp ^ temp;
-          *ivp++ = temp;
-        }
-      nbytes -= blocksize;
-    }
-
-  if (nbytes)
-    { 
-      /* Save the current IV and then encrypt the IV. */
-      memcpy ( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      c->unused = blocksize;
-      /* Apply the XOR. */
-      c->unused -= nbytes;
-      for (ivp=c->u_iv.iv; nbytes; nbytes-- )
-        {
-          temp = *inbuf++;
-          *outbuf++ = *ivp ^ temp;
-          *ivp++ = temp;
-        }
-    }
-}
-
-
-static void
-do_ofb_encrypt( gcry_cipher_hd_t c,
-                byte *outbuf, const byte *inbuf, unsigned nbytes )
-{
-  byte *ivp;
-  size_t blocksize = c->cipher->blocksize;
-
-  if ( nbytes <= c->unused )
-    {
-      /* Short enough to be encoded by the remaining XOR mask. */
-      /* XOR the input with the IV */
-      for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused;
-           nbytes;
-           nbytes--, c->unused-- )
-        *outbuf++ = (*ivp++ ^ *inbuf++);
-      return;
-    }
-
-  if( c->unused )
-    {
-      nbytes -= c->unused;
-      for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
-        *outbuf++ = (*ivp++ ^ *inbuf++);
-    }
-
-  /* Now we can process complete blocks. */
-  while ( nbytes >= blocksize )
-    {
-      int i;
-      /* Encrypt the IV (and save the current one). */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      
-      for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-        *outbuf++ = (*ivp++ ^ *inbuf++);
-      nbytes -= blocksize;
-    }
-  if ( nbytes )
-    { /* process the remaining bytes */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      c->unused = blocksize;
-      c->unused -= nbytes;
-      for(ivp=c->u_iv.iv; nbytes; nbytes-- )
-        *outbuf++ = (*ivp++ ^ *inbuf++);
-    }
-}
-
-static void
-do_ofb_decrypt( gcry_cipher_hd_t c,
-                byte *outbuf, const byte *inbuf, unsigned int nbytes )
-{
-  byte *ivp;
-  size_t blocksize = c->cipher->blocksize;
-  
-  if( nbytes <= c->unused )
-    {
-      /* Short enough to be encoded by the remaining XOR mask. */
-      for (ivp=c->u_iv.iv+blocksize - c->unused; nbytes; nbytes--,c->unused--)
-        *outbuf++ = *ivp++ ^ *inbuf++;
-      return;
-    }
-
-  if ( c->unused )
-    {
-      nbytes -= c->unused;
-      for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
-        *outbuf++ = *ivp++ ^ *inbuf++;
-    }
-
-  /* Now we can process complete blocks. */
-  while ( nbytes >= blocksize )
-    {
-      int i;
-      /* Encrypt the IV (and save the current one). */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-        *outbuf++ = *ivp++ ^ *inbuf++;
-      nbytes -= blocksize;
-    }
-  if ( nbytes ) 
-    { /* Process the remaining bytes. */
-      /* Encrypt the IV (and save the current one). */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      c->unused = blocksize;
-      c->unused -= nbytes;
-      for (ivp=c->u_iv.iv; nbytes; nbytes-- )
-        *outbuf++ = *ivp++ ^ *inbuf++;
-    }
-}
-
-
-static void
-do_ctr_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
-                unsigned int nbytes )
-{
-  unsigned int n;
-  byte tmp[MAX_BLOCKSIZE];
-  int i;
-
-  for(n=0; n < nbytes; n++)
-    {
-      if ((n % c->cipher->blocksize) == 0)
-       {
-         c->cipher->encrypt (&c->context.c, tmp, c->ctr);
-
-         for (i = c->cipher->blocksize; i > 0; i--)
-           {
-             c->ctr[i-1]++;
-             if (c->ctr[i-1] != 0)
-               break;
-           }
-       }
-
-      /* XOR input with encrypted counter and store in output. */
-      outbuf[n] = inbuf[n] ^ tmp[n % c->cipher->blocksize];
-    }
-}
-
-static void
-do_ctr_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
-                unsigned int nbytes )
-{
-  do_ctr_encrypt (c, outbuf, inbuf, nbytes);
-}
-
-
-/****************
- * Encrypt INBUF to OUTBUF with the mode selected at open.
- * inbuf and outbuf may overlap or be the same.
- * Depending on the mode some contraints apply to NBYTES.
- */
-static gcry_err_code_t
-cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf,
-               const byte *inbuf, unsigned int nbytes)
-{
-    gcry_err_code_t rc = GPG_ERR_NO_ERROR;
-
-    switch( c->mode ) {
-      case GCRY_CIPHER_MODE_ECB:
-       if (!(nbytes%c->cipher->blocksize))
-            do_ecb_encrypt(c, outbuf, inbuf, nbytes/c->cipher->blocksize );
-        else 
-            rc = GPG_ERR_INV_ARG;
-       break;
-      case GCRY_CIPHER_MODE_CBC:
-       if (!(nbytes%c->cipher->blocksize)
-            || (nbytes > c->cipher->blocksize
-                && (c->flags & GCRY_CIPHER_CBC_CTS)))
-            do_cbc_encrypt(c, outbuf, inbuf, nbytes );
-        else 
-            rc = GPG_ERR_INV_ARG;
-       break;
-      case GCRY_CIPHER_MODE_CFB:
-       do_cfb_encrypt(c, outbuf, inbuf, nbytes );
-       break;
-      case GCRY_CIPHER_MODE_OFB:
-       do_ofb_encrypt(c, outbuf, inbuf, nbytes );
-       break;
-      case GCRY_CIPHER_MODE_CTR:
-       do_ctr_encrypt(c, outbuf, inbuf, nbytes );
-       break;
-      case GCRY_CIPHER_MODE_STREAM:
-        c->cipher->stencrypt ( &c->context.c,
-                               outbuf, (byte*)/*arggg*/inbuf, nbytes );
-        break;
-      case GCRY_CIPHER_MODE_NONE:
-               if (fips_mode () || !_gcry_get_debug_flag (0))
-          {
-            fips_signal_error ("cipher mode NONE used");
-            rc = GPG_ERR_INV_CIPHER_MODE;
-          }
-        else
-          {
-            if ( inbuf != outbuf )
-              memmove (outbuf, inbuf, nbytes);
-          }
-       break;
-      default:
-        log_fatal("cipher_encrypt: invalid mode %d\n", c->mode );
-        rc = GPG_ERR_INV_CIPHER_MODE;
-        break;
-    }
-    return rc;
-}
-
-
-/****************
- * Encrypt IN and write it to OUT.  If IN is NULL, in-place encryption has
- * been requested.
- */
-gcry_error_t
-gcry_cipher_encrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
-                     const void *in, size_t inlen)
-{
-  gcry_err_code_t err;
-
-  if (!in)
-    {
-      /* Caller requested in-place encryption. */
-      /* Actually cipher_encrypt() does not need to know about it, but
-       * we may change it in the future to get better performance.  */
-      err = cipher_encrypt (h, out, out, outsize);
-    }
-  else if (outsize < ((h->flags & GCRY_CIPHER_CBC_MAC) ?
-                      h->cipher->blocksize : inlen))
-    err = GPG_ERR_TOO_SHORT;
-  else if ((h->mode == GCRY_CIPHER_MODE_ECB
-           || (h->mode == GCRY_CIPHER_MODE_CBC
-               && (! ((h->flags & GCRY_CIPHER_CBC_CTS)
-                      && (inlen > h->cipher->blocksize)))))
-          && (inlen % h->cipher->blocksize))
-    err = GPG_ERR_INV_ARG;
-  else
-    err = cipher_encrypt (h, out, in, inlen);
-
-  if (err && out)
-    memset (out, 0x42, outsize); /* Failsafe: Make sure that the
-                                    plaintext will never make it into
-                                    OUT. */
-
-  return gcry_error (err);
-}
-
-
-
-/****************
- * Decrypt INBUF to OUTBUF with the mode selected at open.
- * inbuf and outbuf may overlap or be the same.
- * Depending on the mode some some contraints apply to NBYTES.
- */
-static gcry_err_code_t
-cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
-               unsigned int nbytes)
-{
-    gcry_err_code_t rc = GPG_ERR_NO_ERROR;
-
-    switch( c->mode ) {
-      case GCRY_CIPHER_MODE_ECB:
-       if (!(nbytes%c->cipher->blocksize))
-            do_ecb_decrypt(c, outbuf, inbuf, nbytes/c->cipher->blocksize );
-        else 
-            rc = GPG_ERR_INV_ARG;
-       break;
-      case GCRY_CIPHER_MODE_CBC:
-       if (!(nbytes%c->cipher->blocksize)
-            || (nbytes > c->cipher->blocksize
-                && (c->flags & GCRY_CIPHER_CBC_CTS)))
-            do_cbc_decrypt(c, outbuf, inbuf, nbytes );
-        else 
-            rc = GPG_ERR_INV_ARG;
-       break;
-      case GCRY_CIPHER_MODE_CFB:
-       do_cfb_decrypt(c, outbuf, inbuf, nbytes );
-       break;
-      case GCRY_CIPHER_MODE_OFB:
-       do_ofb_decrypt(c, outbuf, inbuf, nbytes );
-       break;
-      case GCRY_CIPHER_MODE_CTR:
-       do_ctr_decrypt(c, outbuf, inbuf, nbytes );
-       break;
-      case GCRY_CIPHER_MODE_STREAM:
-        c->cipher->stdecrypt ( &c->context.c,
-                               outbuf, (byte*)/*arggg*/inbuf, nbytes );
-        break;
-      case GCRY_CIPHER_MODE_NONE:
-               if (fips_mode () || !_gcry_get_debug_flag (0))
-          {
-            fips_signal_error ("cipher mode NONE used");
-            rc = GPG_ERR_INV_CIPHER_MODE;
-          }
-        else
-          {
-            if (inbuf != outbuf)
-              memmove (outbuf, inbuf, nbytes);
-          }
-       break;
-      default:
-        log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode );
-        rc = GPG_ERR_INV_CIPHER_MODE;
-        break;
-    }
-    return rc;
-}
-
-
-gcry_error_t
-gcry_cipher_decrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
-                    const void *in, size_t inlen)
-{
-  gcry_err_code_t err = 0;
-
-  if (!in)
-    {
-      /* Caller requested in-place encryption. */
-      /* Actually cipher_encrypt() does not need to know about it, but
-       * we may change it in the future to get better performance.  */
-      err = cipher_decrypt (h, out, out, outsize);
-    }
-  else if (outsize < inlen)
-    err = GPG_ERR_TOO_SHORT;
-  else if (((h->mode == GCRY_CIPHER_MODE_ECB)
-           || ((h->mode == GCRY_CIPHER_MODE_CBC)
-               && (! ((h->flags & GCRY_CIPHER_CBC_CTS)
-                      && (inlen > h->cipher->blocksize)))))
-          && (inlen % h->cipher->blocksize) != 0)
-    err = GPG_ERR_INV_ARG;
-  else
-    err = cipher_decrypt (h, out, in, inlen);
-
-  return gcry_error (err);
-}
-
-
-
-/****************
- * Used for PGP's somewhat strange CFB mode. Only works if
- * the corresponding flag is set.
- */
-static void
-cipher_sync (gcry_cipher_hd_t c)
-{
-  if ((c->flags & GCRY_CIPHER_ENABLE_SYNC) && c->unused)
-    {
-      memmove (c->u_iv.iv + c->unused,
-               c->u_iv.iv, c->cipher->blocksize - c->unused);
-      memcpy (c->u_iv.iv,
-              c->lastiv + c->cipher->blocksize - c->unused, c->unused);
-      c->unused = 0;
-    }
-}
-
-
-gcry_error_t
-_gcry_cipher_setkey (gcry_cipher_hd_t hd, const void *key, size_t keylen)
-{
-  return cipher_setkey (hd, (void*)key, keylen);
-}
-
-
-gcry_error_t
-_gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen)
-{
-  cipher_setiv (hd, iv, ivlen);
-  return 0;
-}
-
-/* Set counter for CTR mode.  (CTR,CTRLEN) must denote a buffer of
-   block size length, or (NULL,0) to set the CTR to the all-zero
-   block. */
-gpg_error_t
-_gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen)
-{
-  if (ctr && ctrlen == hd->cipher->blocksize)
-    memcpy (hd->ctr, ctr, hd->cipher->blocksize);
-  else if (!ctr || !ctrlen)
-    memset (hd->ctr, 0, hd->cipher->blocksize);
-  else
-    return gpg_error (GPG_ERR_INV_ARG);
-  return 0;
-}
-
-
-gcry_error_t
-gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
-{
-  gcry_err_code_t rc = GPG_ERR_NO_ERROR;
-
-  switch (cmd)
-    {
-    case GCRYCTL_SET_KEY:  /* Deprecated; use gcry_cipher_setkey.  */
-      rc = cipher_setkey( h, buffer, buflen );
-      break;
-
-    case GCRYCTL_SET_IV:   /* Deprecated; use gcry_cipher_setiv.  */
-      cipher_setiv( h, buffer, buflen );
-      break;
-
-    case GCRYCTL_RESET:
-      cipher_reset (h);
-      break;
-
-    case GCRYCTL_CFB_SYNC:
-      cipher_sync( h );
-      break;
-
-    case GCRYCTL_SET_CBC_CTS:
-      if (buflen)
-       if (h->flags & GCRY_CIPHER_CBC_MAC)
-         rc = GPG_ERR_INV_FLAG;
-       else
-         h->flags |= GCRY_CIPHER_CBC_CTS;
-      else
-       h->flags &= ~GCRY_CIPHER_CBC_CTS;
-      break;
-
-    case GCRYCTL_SET_CBC_MAC:
-      if (buflen)
-       if (h->flags & GCRY_CIPHER_CBC_CTS)
-         rc = GPG_ERR_INV_FLAG;
-       else
-         h->flags |= GCRY_CIPHER_CBC_MAC;
-      else
-       h->flags &= ~GCRY_CIPHER_CBC_MAC;
-      break;
-
-    case GCRYCTL_DISABLE_ALGO:
-      /* This command expects NULL for H and BUFFER to point to an
-         integer with the algo number.  */
-      if( h || !buffer || buflen != sizeof(int) )
-       return gcry_error (GPG_ERR_CIPHER_ALGO);
-      disable_cipher_algo( *(int*)buffer );
-      break;
-
-    case GCRYCTL_SET_CTR: /* Deprecated; use gcry_cipher_setctr.  */
-      if (buffer && buflen == h->cipher->blocksize)
-       memcpy (h->ctr, buffer, h->cipher->blocksize);
-      else if (buffer == NULL || buflen == 0)
-       memset (h->ctr, 0, h->cipher->blocksize);
-      else
-       rc = GPG_ERR_INV_ARG;
-      break;
-
-    case 61:  /* Disable weak key detection (private).  */
-      if (h->extraspec->set_extra_info)
-        rc = h->extraspec->set_extra_info 
-          (&h->context.c, CIPHER_INFO_NO_WEAK_KEY, NULL, 0);
-      else
-        rc = GPG_ERR_NOT_SUPPORTED;
-      break;
-
-    case 62: /* Return current input vector (private).  */
-      /* This is the input block as used in CFB and OFB mode which has
-         initially been set as IV.  The returned format is: 
-           1 byte  Actual length of the block in bytes.
-           n byte  The block.
-         If the provided buffer is too short, an error is returned. */
-      if (buflen < (1 + h->cipher->blocksize))
-        rc = GPG_ERR_TOO_SHORT;
-      else
-        {
-          unsigned char *ivp;
-          unsigned char *dst = buffer;
-          int n = h->unused;
-          
-          if (!n)
-            n = h->cipher->blocksize;
-          gcry_assert (n <= h->cipher->blocksize);
-          *dst++ = n;
-          ivp = h->u_iv.iv + h->cipher->blocksize - n;
-          while (n--)
-            *dst++ = *ivp++;
-        }
-      break;
-
-    default:
-      rc = GPG_ERR_INV_OP;
-    }
-
-  return gcry_error (rc);
-}
-
-
-/* Return information about the cipher handle H.  CMD is the kind of
-   information requested.  BUFFER and NBYTES are reserved for now.
-
-   There are no values for CMD yet defined.  
-
-   The fucntion always returns GPG_ERR_INV_OP.
-   
- */
-gcry_error_t
-gcry_cipher_info (gcry_cipher_hd_t h, int cmd, void *buffer, size_t *nbytes)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  (void)h;
-  (void)buffer;
-  (void)nbytes;
-
-  switch (cmd)
-    {
-    default:
-      err = GPG_ERR_INV_OP;
-    }
-
-  return gcry_error (err);
-}
-
-/* Return information about the given cipher algorithm ALGO.
-
-   WHAT select the kind of information returned:
-
-    GCRYCTL_GET_KEYLEN:
-       Return the length of the key.  If the algorithm ALGO
-       supports multiple key lengths, the maximum supported key length
-       is returned.  The key length is returned as number of octets.
-       BUFFER and NBYTES must be zero.
-
-    GCRYCTL_GET_BLKLEN:
-       Return the blocklength of the algorithm ALGO counted in octets.
-       BUFFER and NBYTES must be zero.
-
-    GCRYCTL_TEST_ALGO:
-       Returns 0 if the specified algorithm ALGO is available for use.
-       BUFFER and NBYTES must be zero.
-  
-   Note: Because this function is in most cases used to return an
-   integer value, we can make it easier for the caller to just look at
-   the return value.  The caller will in all cases consult the value
-   and thereby detecting whether a error occured or not (i.e. while
-   checking the block size)
- */
-gcry_error_t
-gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  unsigned int ui;
-
-  switch (what)
-    {
-    case GCRYCTL_GET_KEYLEN:
-      if (buffer || (! nbytes))
-       err = GPG_ERR_CIPHER_ALGO;
-      else
-       {
-         ui = cipher_get_keylen (algo);
-         if ((ui > 0) && (ui <= 512))
-           *nbytes = (size_t) ui / 8;
-         else
-           /* The only reason is an invalid algo or a strange
-              blocksize.  */
-           err = GPG_ERR_CIPHER_ALGO;
-       }
-      break;
-
-    case GCRYCTL_GET_BLKLEN:
-      if (buffer || (! nbytes))
-       err = GPG_ERR_CIPHER_ALGO;
-      else
-       {
-         ui = cipher_get_blocksize (algo);
-         if ((ui > 0) && (ui < 10000))
-           *nbytes = ui;
-         else
-           /* The only reason is an invalid algo or a strange
-              blocksize.  */
-           err = GPG_ERR_CIPHER_ALGO;
-       }
-      break;
-
-    case GCRYCTL_TEST_ALGO:
-      if (buffer || nbytes)
-       err = GPG_ERR_INV_ARG;
-      else
-       err = check_cipher_algo (algo);
-      break;
-
-      default:
-       err = GPG_ERR_INV_OP;
-    }
-
-  return gcry_error (err);
-}
-
-
-/* This function returns length of the key for algorithm ALGO.  If the
-   algorithm supports multiple key lengths, the maximum supported key
-   length is returned.  On error 0 is returned.  The key length is
-   returned as number of octets.
-
-   This is a convenience functions which should be preferred over
-   gcry_cipher_algo_info because it allows for proper type
-   checking.  */
-size_t
-gcry_cipher_get_algo_keylen (int algo) 
-{
-  size_t n;
-
-  if (gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, &n))
-    n = 0;
-  return n;
-}
-
-/* This functions returns the blocklength of the algorithm ALGO
-   counted in octets.  On error 0 is returned.
-
-   This is a convenience functions which should be preferred over
-   gcry_cipher_algo_info because it allows for proper type
-   checking.  */
-size_t
-gcry_cipher_get_algo_blklen (int algo) 
-{
-  size_t n;
-
-  if (gcry_cipher_algo_info( algo, GCRYCTL_GET_BLKLEN, NULL, &n))
-    n = 0;
-  return n;
-}
-
-/* Explicitly initialize this module.  */
-gcry_err_code_t
-_gcry_cipher_init (void)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  REGISTER_DEFAULT_CIPHERS;
-
-  return err;
-}
-
-/* Get a list consisting of the IDs of the loaded cipher modules.  If
-   LIST is zero, write the number of loaded cipher modules to
-   LIST_LENGTH and return.  If LIST is non-zero, the first
-   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
-   according size.  In case there are less cipher modules than
-   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
-gcry_error_t
-gcry_cipher_list (int *list, int *list_length)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  ath_mutex_lock (&ciphers_registered_lock);
-  err = _gcry_module_list (ciphers_registered, list, list_length);
-  ath_mutex_unlock (&ciphers_registered_lock);
-
-  return err;
-}
-
-
-/* Run the selftests for cipher algorithm ALGO with optional reporting
-   function REPORT.  */
-gpg_error_t
-_gcry_cipher_selftest (int algo, int extended, selftest_report_func_t report)
-{
-  gcry_module_t module = NULL;
-  cipher_extra_spec_t *extraspec = NULL;
-  gcry_err_code_t ec = 0;
-
-  REGISTER_DEFAULT_CIPHERS;
-
-  ath_mutex_lock (&ciphers_registered_lock);
-  module = _gcry_module_lookup_id (ciphers_registered, algo);
-  if (module && !(module->flags & FLAG_MODULE_DISABLED))
-    extraspec = module->extraspec;
-  ath_mutex_unlock (&ciphers_registered_lock);
-  if (extraspec && extraspec->selftest)
-    ec = extraspec->selftest (algo, extended, report);
-  else
-    {
-      ec = GPG_ERR_CIPHER_ALGO;
-      if (report)
-        report ("cipher", algo, "module", 
-                module && !(module->flags & FLAG_MODULE_DISABLED)?
-                "no selftest available" :
-                module? "algorithm disabled" : "algorithm not found");
-    }
-
-  if (module)
-    {
-      ath_mutex_lock (&ciphers_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&ciphers_registered_lock);
-    }
-  return gpg_error (ec);
-}
diff --git a/lib/libgcrypt/cipher/crc.c b/lib/libgcrypt/cipher/crc.c
deleted file mode 100644 (file)
index d04fff8..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-/* crc.c - Cyclic redundancy checks.
- * Copyright (C) 2003 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "g10lib.h"
-#include "memory.h"
-#include "cipher.h"
-
-#include "bithelp.h"
-
-/* Table of CRCs of all 8-bit messages.  Generated by running code
-   from RFC 1952 modified to print out the table. */
-static u32 crc32_table[256] = {
-  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
-  0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
-  0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
-  0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
-  0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
-  0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
-  0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
-  0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
-  0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
-  0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
-  0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
-  0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
-  0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
-  0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
-  0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
-  0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
-  0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
-  0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
-  0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
-  0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
-  0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
-  0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
-  0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
-  0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
-  0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
-  0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
-  0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
-  0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
-  0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
-  0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
-  0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
-  0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
-  0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
-  0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
-  0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
-  0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
-  0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
-  0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
-  0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
-};
-
-/*
- * The following function was extracted from RFC 1952 by Simon
- * Josefsson, for the Shishi project, and modified to be compatible
- * with the modified CRC-32 used by RFC 1510, and subsequently
- * modified for GNU Libgcrypt to allow it to be used for calculating
- * both unmodified CRC-32 and modified CRC-32 values.  Original
- * copyright and notice from the document follows:
- *
- *    Copyright (c) 1996 L. Peter Deutsch
- *
- *    Permission is granted to copy and distribute this document for
- *    any purpose and without charge, including translations into
- *    other languages and incorporation into compilations, provided
- *    that the copyright notice and this notice are preserved, and
- *    that any substantive changes or deletions from the original are
- *    clearly marked.
- *
- * The copyright on RFCs, and consequently the function below, are
- * supposedly also retroactively claimed by the Internet Society
- * (according to rfc-editor@rfc-editor.org), with the following
- * copyright notice:
- *
- *    Copyright (C) The Internet Society.  All Rights Reserved.
- *
- *    This document and translations of it may be copied and furnished
- *    to others, and derivative works that comment on or otherwise
- *    explain it or assist in its implementation may be prepared,
- *    copied, published and distributed, in whole or in part, without
- *    restriction of any kind, provided that the above copyright
- *    notice and this paragraph are included on all such copies and
- *    derivative works.  However, this document itself may not be
- *    modified in any way, such as by removing the copyright notice or
- *    references to the Internet Society or other Internet
- *    organizations, except as needed for the purpose of developing
- *    Internet standards in which case the procedures for copyrights
- *    defined in the Internet Standards process must be followed, or
- *    as required to translate it into languages other than English.
- *
- *    The limited permissions granted above are perpetual and will not be
- *    revoked by the Internet Society or its successors or assigns.
- *
- *    This document and the information contained herein is provided
- *    on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
- *    ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR
- *    IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE
- *    OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
- *    IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
- *    PARTICULAR PURPOSE.
- *
- */
-static u32
-update_crc32 (u32 crc, const void *buf_arg, size_t len)
-{
-  const char *buf = buf_arg;
-  size_t n;
-
-  for (n = 0; n < len; n++)
-    crc = crc32_table[(crc ^ buf[n]) & 0xff] ^ (crc >> 8);
-
-  return crc;
-}
-
-typedef struct
-{
-  u32 CRC;
-  byte buf[4];
-}
-CRC_CONTEXT;
-
-/* CRC32 */
-
-static void
-crc32_init (void *context)
-{
-  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
-  ctx->CRC = 0 ^ 0xffffffffL;
-}
-
-static void
-crc32_write (void *context, const void *inbuf, size_t inlen)
-{
-  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
-  if (!inbuf)
-    return;
-  ctx->CRC = update_crc32 (ctx->CRC, inbuf, inlen);
-}
-
-static byte *
-crc32_read (void *context)
-{
-  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
-  return ctx->buf;
-}
-
-static void
-crc32_final (void *context)
-{
-  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
-  ctx->CRC ^= 0xffffffffL;
-  ctx->buf[0] = (ctx->CRC >> 24) & 0xFF;
-  ctx->buf[1] = (ctx->CRC >> 16) & 0xFF;
-  ctx->buf[2] = (ctx->CRC >>  8) & 0xFF;
-  ctx->buf[3] = (ctx->CRC      ) & 0xFF;
-}
-
-/* CRC32 a'la RFC 1510 */
-static void
-crc32rfc1510_init (void *context)
-{
-  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
-  ctx->CRC = 0;
-}
-
-static void
-crc32rfc1510_final (void *context)
-{
-  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
-  ctx->buf[0] = (ctx->CRC >> 24) & 0xFF;
-  ctx->buf[1] = (ctx->CRC >> 16) & 0xFF;
-  ctx->buf[2] = (ctx->CRC >>  8) & 0xFF;
-  ctx->buf[3] = (ctx->CRC      ) & 0xFF;
-}
-
-/* CRC24 a'la RFC 2440 */
-/*
- * The following CRC 24 routines are adapted from RFC 2440, which has
- * the following copyright notice:
- *
- *   Copyright (C) The Internet Society (1998).  All Rights Reserved.
- *
- *   This document and translations of it may be copied and furnished
- *   to others, and derivative works that comment on or otherwise
- *   explain it or assist in its implementation may be prepared,
- *   copied, published and distributed, in whole or in part, without
- *   restriction of any kind, provided that the above copyright notice
- *   and this paragraph are included on all such copies and derivative
- *   works.  However, this document itself may not be modified in any
- *   way, such as by removing the copyright notice or references to
- *   the Internet Society or other Internet organizations, except as
- *   needed for the purpose of developing Internet standards in which
- *   case the procedures for copyrights defined in the Internet
- *   Standards process must be followed, or as required to translate
- *   it into languages other than English.
- *
- *   The limited permissions granted above are perpetual and will not be
- *   revoked by the Internet Society or its successors or assigns.
- *
- *   This document and the information contained herein is provided on
- *   an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
- *   ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR
- *   IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE
- *   OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
- *   IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
- *   PURPOSE.
- */
-
-#define CRC24_INIT 0xb704ceL
-#define CRC24_POLY 0x1864cfbL
-
-static void
-crc24rfc2440_init (void *context)
-{
-  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
-  ctx->CRC = CRC24_INIT;
-}
-
-static void
-crc24rfc2440_write (void *context, const void *inbuf_arg, size_t inlen)
-{
-  const unsigned char *inbuf = inbuf_arg;
-  int i;
-  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
-
-  if (!inbuf)
-    return;
-
-  while (inlen--) {
-    ctx->CRC ^= (*inbuf++) << 16;
-    for (i = 0; i < 8; i++) {
-      ctx->CRC <<= 1;
-      if (ctx->CRC & 0x1000000)
-       ctx->CRC ^= CRC24_POLY;
-    }
-  }
-}
-
-static void
-crc24rfc2440_final (void *context)
-{
-  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
-  ctx->buf[0] = (ctx->CRC >> 16) & 0xFF;
-  ctx->buf[1] = (ctx->CRC >>  8) & 0xFF;
-  ctx->buf[2] = (ctx->CRC      ) & 0xFF;
-}
-
-gcry_md_spec_t _gcry_digest_spec_crc32 =
-  {
-    "CRC32", NULL, 0, NULL, 4,
-    crc32_init, crc32_write, crc32_final, crc32_read,
-    sizeof (CRC_CONTEXT)
-  };
-
-gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510 =
-  {
-    "CRC32RFC1510", NULL, 0, NULL, 4,
-    crc32rfc1510_init, crc32_write,
-    crc32rfc1510_final, crc32_read,
-    sizeof (CRC_CONTEXT)
-  };
-
-gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440 =
-  {
-    "CRC24RFC2440", NULL, 0, NULL, 3,
-    crc24rfc2440_init, crc24rfc2440_write,
-    crc24rfc2440_final, crc32_read,
-    sizeof (CRC_CONTEXT)
-  };
diff --git a/lib/libgcrypt/cipher/des.c b/lib/libgcrypt/cipher/des.c
deleted file mode 100644 (file)
index f91df77..0000000
+++ /dev/null
@@ -1,1196 +0,0 @@
-/* des.c - DES and Triple-DES encryption/decryption Algorithm
- * Copyright (C) 1998, 1999, 2001, 2002, 2003,
- *               2008  Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * For a description of triple encryption, see:
- *   Bruce Schneier: Applied Cryptography. Second Edition.
- *   John Wiley & Sons, 1996. ISBN 0-471-12845-7. Pages 358 ff.
- * This implementation is according to the definition of DES in FIPS
- * PUB 46-2 from December 1993. 
- */
-
-
-/*
- * Written by Michael Roth <mroth@nessie.de>, September 1998
- */
-
-
-/*
- *  U S A G E
- * ===========
- *
- * For DES or Triple-DES encryption/decryption you must initialize a proper
- * encryption context with a key.
- *
- * A DES key is 64bit wide but only 56bits of the key are used. The remaining
- * bits are parity bits and they will _not_ checked in this implementation, but
- * simply ignored.
- *
- * For Triple-DES you could use either two 64bit keys or three 64bit keys.
- * The parity bits will _not_ checked, too.
- *
- * After initializing a context with a key you could use this context to
- * encrypt or decrypt data in 64bit blocks in Electronic Codebook Mode.
- *
- * (In the examples below the slashes at the beginning and ending of comments
- * are omited.)
- *
- * DES Example
- * -----------
- *     unsigned char key[8];
- *     unsigned char plaintext[8];
- *     unsigned char ciphertext[8];
- *     unsigned char recoverd[8];
- *     des_ctx context;
- *
- *     * Fill 'key' and 'plaintext' with some data *
- *     ....
- *
- *     * Set up the DES encryption context *
- *     des_setkey(context, key);
- *
- *     * Encrypt the plaintext *
- *     des_ecb_encrypt(context, plaintext, ciphertext);
- *
- *     * To recover the orginal plaintext from ciphertext use: *
- *     des_ecb_decrypt(context, ciphertext, recoverd);
- *
- *
- * Triple-DES Example
- * ------------------
- *     unsigned char key1[8];
- *     unsigned char key2[8];
- *     unsigned char key3[8];
- *     unsigned char plaintext[8];
- *     unsigned char ciphertext[8];
- *     unsigned char recoverd[8];
- *     tripledes_ctx context;
- *
- *     * If you would like to use two 64bit keys, fill 'key1' and'key2'
- *      then setup the encryption context: *
- *     tripledes_set2keys(context, key1, key2);
- *
- *     * To use three 64bit keys with Triple-DES use: *
- *     tripledes_set3keys(context, key1, key2, key3);
- *
- *     * Encrypting plaintext with Triple-DES *
- *     tripledes_ecb_encrypt(context, plaintext, ciphertext);
- *
- *     * Decrypting ciphertext to recover the plaintext with Triple-DES *
- *     tripledes_ecb_decrypt(context, ciphertext, recoverd);
- *
- *
- * Selftest
- * --------
- *     char *error_msg;
- *
- *     * To perform a selftest of this DES/Triple-DES implementation use the
- *      function selftest(). It will return an error string if there are
- *      some problems with this library. *
- *
- *     if ( (error_msg = selftest()) )
- *     {
- *        fprintf(stderr, "An error in the DES/Tripple-DES implementation occured: %s\n", error_msg);
- *        abort();
- *     }
- */
-
-
-#include <config.h>
-#include <stdio.h>
-#include <string.h>           /* memcpy, memcmp */
-#include "types.h"             /* for byte and u32 typedefs */
-#include "g10lib.h"
-#include "cipher.h"
-
-#if defined(__GNUC__) && defined(__GNU_LIBRARY__)
-#define working_memcmp memcmp
-#else
-/*
- * According to the SunOS man page, memcmp returns indeterminate sign
- * depending on whether characters are signed or not.
- */
-static int
-working_memcmp( const char *a, const char *b, size_t n )
-{
-    for( ; n; n--, a++, b++ )
-       if( *a != *b )
-           return (int)(*(byte*)a) - (int)(*(byte*)b);
-    return 0;
-}
-#endif
-
-/*
- * Encryption/Decryption context of DES
- */
-typedef struct _des_ctx
-  {
-    u32 encrypt_subkeys[32];
-    u32 decrypt_subkeys[32];
-  }
-des_ctx[1];
-
-/*
- * Encryption/Decryption context of Triple-DES
- */
-typedef struct _tripledes_ctx
-  {
-    u32 encrypt_subkeys[96];
-    u32 decrypt_subkeys[96];
-    struct {
-      int no_weak_key;
-    } flags;
-  }
-tripledes_ctx[1];
-
-static void des_key_schedule (const byte *, u32 *);
-static int des_setkey (struct _des_ctx *, const byte *);
-static int des_ecb_crypt (struct _des_ctx *, const byte *, byte *, int);
-static int tripledes_set2keys (struct _tripledes_ctx *,
-                               const byte *, const byte *);
-static int tripledes_set3keys (struct _tripledes_ctx *,
-                               const byte *, const byte *, const byte *);
-static int tripledes_ecb_crypt (struct _tripledes_ctx *,
-                                const byte *, byte *, int);
-static int is_weak_key ( const byte *key );
-static const char *selftest (void);
-
-static int initialized;
-
-
-
-
-/*
- * The s-box values are permuted according to the 'primitive function P'
- * and are rotated one bit to the left.
- */
-static u32 sbox1[64] =
-{
-  0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000,
-  0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
-  0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
-  0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000,
-  0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400,
-  0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
-  0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400,
-  0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004
-};
-
-static u32 sbox2[64] =
-{
-  0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020,
-  0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
-  0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
-  0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020,
-  0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000,
-  0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
-  0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020,
-  0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000
-};
-
-static u32 sbox3[64] =
-{
-  0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200,
-  0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
-  0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
-  0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000,
-  0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000,
-  0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
-  0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008,
-  0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200
-};
-
-static u32 sbox4[64] =
-{
-  0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001,
-  0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
-  0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
-  0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081,
-  0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000,
-  0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
-  0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081,
-  0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080
-};
-
-static u32 sbox5[64] =
-{
-  0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000,
-  0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
-  0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
-  0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100,
-  0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100,
-  0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
-  0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000,
-  0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100
-};
-
-static u32 sbox6[64] =
-{
-  0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000,
-  0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
-  0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
-  0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000,
-  0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010,
-  0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
-  0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010,
-  0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010
-};
-
-static u32 sbox7[64] =
-{
-  0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800,
-  0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
-  0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
-  0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800,
-  0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002,
-  0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
-  0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802,
-  0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002
-};
-
-static u32 sbox8[64] =
-{
-  0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000,
-  0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
-  0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
-  0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000,
-  0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040,
-  0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
-  0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000,
-  0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000
-};
-
-
-/*
- * These two tables are part of the 'permuted choice 1' function.
- * In this implementation several speed improvements are done.
- */
-static u32 leftkey_swap[16] =
-{
-  0x00000000, 0x00000001, 0x00000100, 0x00000101,
-  0x00010000, 0x00010001, 0x00010100, 0x00010101,
-  0x01000000, 0x01000001, 0x01000100, 0x01000101,
-  0x01010000, 0x01010001, 0x01010100, 0x01010101
-};
-
-static u32 rightkey_swap[16] =
-{
-  0x00000000, 0x01000000, 0x00010000, 0x01010000,
-  0x00000100, 0x01000100, 0x00010100, 0x01010100,
-  0x00000001, 0x01000001, 0x00010001, 0x01010001,
-  0x00000101, 0x01000101, 0x00010101, 0x01010101,
-};
-
-
-
-/*
- * Numbers of left shifts per round for encryption subkeys.
- * To calculate the decryption subkeys we just reverse the
- * ordering of the calculated encryption subkeys. So their
- * is no need for a decryption rotate tab.
- */
-static byte encrypt_rotate_tab[16] =
-{
-  1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
-};
-
-
-
-/*
- * Table with weak DES keys sorted in ascending order.
- * In DES their are 64 known keys which are weak. They are weak
- * because they produce only one, two or four different
- * subkeys in the subkey scheduling process.
- * The keys in this table have all their parity bits cleared.
- */
-static byte weak_keys[64][8] =
-{
-  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*w*/
-  { 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e },
-  { 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0 },
-  { 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe },
-  { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e }, /*sw*/
-  { 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00 },
-  { 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe },
-  { 0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0 },
-  { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0 }, /*sw*/
-  { 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe },
-  { 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00 },
-  { 0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e },
-  { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe }, /*sw*/
-  { 0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0 },
-  { 0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e },
-  { 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00 },
-  { 0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e },
-  { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 }, /*sw*/
-  { 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe },
-  { 0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0 },
-  { 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00 },
-  { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e }, /*w*/
-  { 0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0 },
-  { 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe },
-  { 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe },
-  { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 }, /*sw*/
-  { 0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e },
-  { 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00 },
-  { 0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0 },
-  { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe }, /*sw*/
-  { 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00 },
-  { 0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e },
-  { 0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0 },
-  { 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe },
-  { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 }, /*sw*/
-  { 0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e },
-  { 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe },
-  { 0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0 },
-  { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e }, /*sw*/
-  { 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00 },
-  { 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00 },
-  { 0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e },
-  { 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 }, /*w*/
-  { 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe },
-  { 0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e },
-  { 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00 },
-  { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe }, /*sw*/
-  { 0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0 },
-  { 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe },
-  { 0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0 },
-  { 0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e },
-  { 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00 }, /*sw*/
-  { 0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0 },
-  { 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe },
-  { 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00 },
-  { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e }, /*sw*/
-  { 0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e },
-  { 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00 },
-  { 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe },
-  { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 }, /*sw*/
-  { 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00 },
-  { 0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e },
-  { 0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0 },
-  { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe }  /*w*/
-};
-static unsigned char weak_keys_chksum[20] = {
-  0xD0, 0xCF, 0x07, 0x38, 0x93, 0x70, 0x8A, 0x83, 0x7D, 0xD7,
-  0x8A, 0x36, 0x65, 0x29, 0x6C, 0x1F, 0x7C, 0x3F, 0xD3, 0x41 
-};
-
-
-
-/*
- * Macro to swap bits across two words.
- */
-#define DO_PERMUTATION(a, temp, b, offset, mask)       \
-    temp = ((a>>offset) ^ b) & mask;                   \
-    b ^= temp;                                         \
-    a ^= temp<<offset;
-
-
-/*
- * This performs the 'initial permutation' of the data to be encrypted
- * or decrypted. Additionally the resulting two words are rotated one bit
- * to the left.
- */
-#define INITIAL_PERMUTATION(left, temp, right)         \
-    DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f)   \
-    DO_PERMUTATION(left, temp, right, 16, 0x0000ffff)  \
-    DO_PERMUTATION(right, temp, left, 2, 0x33333333)   \
-    DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff)   \
-    right =  (right << 1) | (right >> 31);             \
-    temp  =  (left ^ right) & 0xaaaaaaaa;              \
-    right ^= temp;                                     \
-    left  ^= temp;                                     \
-    left  =  (left << 1) | (left >> 31);
-
-/*
- * The 'inverse initial permutation'.
- */
-#define FINAL_PERMUTATION(left, temp, right)           \
-    left  =  (left << 31) | (left >> 1);               \
-    temp  =  (left ^ right) & 0xaaaaaaaa;              \
-    left  ^= temp;                                     \
-    right ^= temp;                                     \
-    right  =  (right << 31) | (right >> 1);            \
-    DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff)   \
-    DO_PERMUTATION(right, temp, left, 2, 0x33333333)   \
-    DO_PERMUTATION(left, temp, right, 16, 0x0000ffff)  \
-    DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f)
-
-
-/*
- * A full DES round including 'expansion function', 'sbox substitution'
- * and 'primitive function P' but without swapping the left and right word.
- * Please note: The data in 'from' and 'to' is already rotated one bit to
- * the left, done in the initial permutation.
- */
-#define DES_ROUND(from, to, work, subkey)              \
-    work = from ^ *subkey++;                           \
-    to ^= sbox8[  work     & 0x3f ];                   \
-    to ^= sbox6[ (work>>8)  & 0x3f ];                  \
-    to ^= sbox4[ (work>>16) & 0x3f ];                  \
-    to ^= sbox2[ (work>>24) & 0x3f ];                  \
-    work = ((from << 28) | (from >> 4)) ^ *subkey++;   \
-    to ^= sbox7[  work     & 0x3f ];                   \
-    to ^= sbox5[ (work>>8)  & 0x3f ];                  \
-    to ^= sbox3[ (work>>16) & 0x3f ];                  \
-    to ^= sbox1[ (work>>24) & 0x3f ];
-
-/*
- * Macros to convert 8 bytes from/to 32bit words.
- */
-#define READ_64BIT_DATA(data, left, right)                                \
-    left  = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];  \
-    right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
-
-#define WRITE_64BIT_DATA(data, left, right)                               \
-    data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff;           \
-    data[2] = (left >> 8) &0xff; data[3] = left &0xff;                    \
-    data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff;         \
-    data[6] = (right >> 8) &0xff; data[7] = right &0xff;
-
-/*
- * Handy macros for encryption and decryption of data
- */
-#define des_ecb_encrypt(ctx, from, to)       des_ecb_crypt(ctx, from, to, 0)
-#define des_ecb_decrypt(ctx, from, to)       des_ecb_crypt(ctx, from, to, 1)
-#define tripledes_ecb_encrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,0)
-#define tripledes_ecb_decrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,1)
-
-
-
-
-
-
-/*
- * des_key_schedule():   Calculate 16 subkeys pairs (even/odd) for
- *                       16 encryption rounds.
- *                       To calculate subkeys for decryption the caller
- *                       have to reorder the generated subkeys.
- *
- *    rawkey:      8 Bytes of key data
- *    subkey:      Array of at least 32 u32s. Will be filled
- *                 with calculated subkeys.
- *
- */
-static void
-des_key_schedule (const byte * rawkey, u32 * subkey)
-{
-  u32 left, right, work;
-  int round;
-
-  READ_64BIT_DATA (rawkey, left, right)
-
-  DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f)
-  DO_PERMUTATION (right, work, left, 0, 0x10101010)
-
-  left = ((leftkey_swap[(left >> 0) & 0xf] << 3)
-          | (leftkey_swap[(left >> 8) & 0xf] << 2)
-          | (leftkey_swap[(left >> 16) & 0xf] << 1)
-          | (leftkey_swap[(left >> 24) & 0xf])
-          | (leftkey_swap[(left >> 5) & 0xf] << 7)
-          | (leftkey_swap[(left >> 13) & 0xf] << 6)
-          | (leftkey_swap[(left >> 21) & 0xf] << 5)
-          | (leftkey_swap[(left >> 29) & 0xf] << 4));
-
-  left &= 0x0fffffff;
-
-  right = ((rightkey_swap[(right >> 1) & 0xf] << 3)
-           | (rightkey_swap[(right >> 9) & 0xf] << 2)
-           | (rightkey_swap[(right >> 17) & 0xf] << 1)
-           | (rightkey_swap[(right >> 25) & 0xf])
-           | (rightkey_swap[(right >> 4) & 0xf] << 7)
-           | (rightkey_swap[(right >> 12) & 0xf] << 6)
-           | (rightkey_swap[(right >> 20) & 0xf] << 5)
-           | (rightkey_swap[(right >> 28) & 0xf] << 4));
-
-  right &= 0x0fffffff;
-
-  for (round = 0; round < 16; ++round)
-    {
-      left = ((left << encrypt_rotate_tab[round])
-              | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
-      right = ((right << encrypt_rotate_tab[round])
-               | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
-
-      *subkey++ = (((left << 4) & 0x24000000)
-                   | ((left << 28) & 0x10000000)
-                   | ((left << 14) & 0x08000000)
-                   | ((left << 18) & 0x02080000)
-                   | ((left << 6) & 0x01000000)
-                   | ((left << 9) & 0x00200000)
-                   | ((left >> 1) & 0x00100000)
-                   | ((left << 10) & 0x00040000)
-                   | ((left << 2) & 0x00020000)
-                   | ((left >> 10) & 0x00010000)
-                   | ((right >> 13) & 0x00002000)
-                   | ((right >> 4) & 0x00001000)
-                   | ((right << 6) & 0x00000800)
-                   | ((right >> 1) & 0x00000400)
-                   | ((right >> 14) & 0x00000200)
-                   | (right & 0x00000100)
-                   | ((right >> 5) & 0x00000020)
-                   | ((right >> 10) & 0x00000010)
-                   | ((right >> 3) & 0x00000008)
-                   | ((right >> 18) & 0x00000004)
-                   | ((right >> 26) & 0x00000002)
-                   | ((right >> 24) & 0x00000001));
-
-      *subkey++ = (((left << 15) & 0x20000000)
-                   | ((left << 17) & 0x10000000)
-                   | ((left << 10) & 0x08000000)
-                   | ((left << 22) & 0x04000000)
-                   | ((left >> 2) & 0x02000000)
-                   | ((left << 1) & 0x01000000)
-                   | ((left << 16) & 0x00200000)
-                   | ((left << 11) & 0x00100000)
-                   | ((left << 3) & 0x00080000)
-                   | ((left >> 6) & 0x00040000)
-                   | ((left << 15) & 0x00020000)
-                   | ((left >> 4) & 0x00010000)
-                   | ((right >> 2) & 0x00002000)
-                   | ((right << 8) & 0x00001000)
-                   | ((right >> 14) & 0x00000808)
-                   | ((right >> 9) & 0x00000400)
-                   | ((right) & 0x00000200)
-                   | ((right << 7) & 0x00000100)
-                   | ((right >> 7) & 0x00000020)
-                   | ((right >> 3) & 0x00000011)
-                   | ((right << 2) & 0x00000004)
-                   | ((right >> 21) & 0x00000002));
-    }
-}
-
-
-/*
- * Fill a DES context with subkeys calculated from a 64bit key.
- * Does not check parity bits, but simply ignore them.
- * Does not check for weak keys.
- */
-static int
-des_setkey (struct _des_ctx *ctx, const byte * key)
-{
-  static const char *selftest_failed;
-  int i;
-
-  if (!fips_mode () && !initialized)
-    {
-      initialized = 1;
-      selftest_failed = selftest ();
-
-      if (selftest_failed)
-       log_error ("%s\n", selftest_failed);
-    }
-  if (selftest_failed)
-    return GPG_ERR_SELFTEST_FAILED;
-
-  des_key_schedule (key, ctx->encrypt_subkeys);
-  _gcry_burn_stack (32);
-
-  for(i=0; i<32; i+=2)
-    {
-      ctx->decrypt_subkeys[i]  = ctx->encrypt_subkeys[30-i];
-      ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[31-i];
-    }
-
-  return 0;
-}
-
-
-
-/*
- * Electronic Codebook Mode DES encryption/decryption of data according
- * to 'mode'.
- */
-static int
-des_ecb_crypt (struct _des_ctx *ctx, const byte * from, byte * to, int mode)
-{
-  u32 left, right, work;
-  u32 *keys;
-
-  keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
-
-  READ_64BIT_DATA (from, left, right)
-  INITIAL_PERMUTATION (left, work, right)
-
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-
-  FINAL_PERMUTATION (right, work, left)
-  WRITE_64BIT_DATA (to, right, left)
-
-  return 0;
-}
-
-
-
-/*
- * Fill a Triple-DES context with subkeys calculated from two 64bit keys.
- * Does not check the parity bits of the keys, but simply ignore them.
- * Does not check for weak keys.
- */
-static int
-tripledes_set2keys (struct _tripledes_ctx *ctx,
-                   const byte * key1,
-                   const byte * key2)
-{
-  int i;
-
-  des_key_schedule (key1, ctx->encrypt_subkeys);
-  des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
-  _gcry_burn_stack (32);
-
-  for(i=0; i<32; i+=2)
-    {
-      ctx->decrypt_subkeys[i]   = ctx->encrypt_subkeys[30-i];
-      ctx->decrypt_subkeys[i+1]  = ctx->encrypt_subkeys[31-i];
-
-      ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i];
-      ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i];
-
-      ctx->encrypt_subkeys[i+64] = ctx->encrypt_subkeys[i];
-      ctx->encrypt_subkeys[i+65] = ctx->encrypt_subkeys[i+1];
-
-      ctx->decrypt_subkeys[i+64] = ctx->decrypt_subkeys[i];
-      ctx->decrypt_subkeys[i+65] = ctx->decrypt_subkeys[i+1];
-    }
-
-  return 0;
-}
-
-
-
-/*
- * Fill a Triple-DES context with subkeys calculated from three 64bit keys.
- * Does not check the parity bits of the keys, but simply ignore them.
- * Does not check for weak keys.
- */
-static int
-tripledes_set3keys (struct _tripledes_ctx *ctx,
-                   const byte * key1,
-                   const byte * key2,
-                   const byte * key3)
-{
-  static const char *selftest_failed;
-  int i;
-
-  if (!fips_mode () && !initialized)
-    {
-      initialized = 1;
-      selftest_failed = selftest ();
-
-      if (selftest_failed)
-       log_error ("%s\n", selftest_failed);
-    }
-  if (selftest_failed)
-    return GPG_ERR_SELFTEST_FAILED;
-
-  des_key_schedule (key1, ctx->encrypt_subkeys);
-  des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
-  des_key_schedule (key3, &(ctx->encrypt_subkeys[64]));
-  _gcry_burn_stack (32);
-
-  for(i=0; i<32; i+=2)
-    {
-      ctx->decrypt_subkeys[i]   = ctx->encrypt_subkeys[94-i];
-      ctx->decrypt_subkeys[i+1]  = ctx->encrypt_subkeys[95-i];
-
-      ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i];
-      ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i];
-
-      ctx->decrypt_subkeys[i+64] = ctx->encrypt_subkeys[30-i];
-      ctx->decrypt_subkeys[i+65] = ctx->encrypt_subkeys[31-i];
-     }
-
-  return 0;
-}
-
-
-
-/*
- * Electronic Codebook Mode Triple-DES encryption/decryption of data
- * according to 'mode'.  Sometimes this mode is named 'EDE' mode
- * (Encryption-Decryption-Encryption).
- */
-static int
-tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from,
-                     byte * to, int mode)
-{
-  u32 left, right, work;
-  u32 *keys;
-
-  keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
-
-  READ_64BIT_DATA (from, left, right)
-  INITIAL_PERMUTATION (left, work, right)
-
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-
-  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
-  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
-  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
-  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
-  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
-  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
-  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
-  DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
-
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-  DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
-
-  FINAL_PERMUTATION (right, work, left)
-  WRITE_64BIT_DATA (to, right, left)
-
-  return 0;
-}
-
-
-
-
-
-/*
- * Check whether the 8 byte key is weak.
- * Does not check the parity bits of the key but simple ignore them.
- */
-static int
-is_weak_key ( const byte *key )
-{
-  byte work[8];
-  int i, left, right, middle, cmp_result;
-
-  /* clear parity bits */
-  for(i=0; i<8; ++i)
-     work[i] = key[i] & 0xfe;
-
-  /* binary search in the weak key table */
-  left = 0;
-  right = 63;
-  while(left <= right)
-    {
-      middle = (left + right) / 2;
-
-      if ( !(cmp_result=working_memcmp(work, weak_keys[middle], 8)) )
-         return -1;
-
-      if ( cmp_result > 0 )
-         left = middle + 1;
-      else
-         right = middle - 1;
-    }
-
-  return 0;
-}
-
-
-
-/*
- * Performs a selftest of this DES/Triple-DES implementation.
- * Returns an string with the error text on failure.
- * Returns NULL if all is ok.
- */
-static const char *
-selftest (void)
-{
-  /*
-   * Check if 'u32' is really 32 bits wide. This DES / 3DES implementation
-   * need this.
-   */
-  if (sizeof (u32) != 4)
-    return "Wrong word size for DES configured.";
-
-  /*
-   * DES Maintenance Test
-   */
-  {
-    int i;
-    byte key[8] =
-      {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
-    byte input[8] =
-      {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-    byte result[8] =
-      {0x24, 0x6e, 0x9d, 0xb9, 0xc5, 0x50, 0x38, 0x1a};
-    byte temp1[8], temp2[8], temp3[8];
-    des_ctx des;
-
-    for (i = 0; i < 64; ++i)
-      {
-       des_setkey (des, key);
-       des_ecb_encrypt (des, input, temp1);
-       des_ecb_encrypt (des, temp1, temp2);
-       des_setkey (des, temp2);
-       des_ecb_decrypt (des, temp1, temp3);
-       memcpy (key, temp3, 8);
-       memcpy (input, temp1, 8);
-      }
-    if (memcmp (temp3, result, 8))
-      return "DES maintenance test failed.";
-  }
-
-
-  /*
-   * Self made Triple-DES test (Does somebody know an official test?)
-   */
-  {
-    int i;
-    byte input[8] =
-      {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
-    byte key1[8] =
-      {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
-    byte key2[8] =
-      {0x11, 0x22, 0x33, 0x44, 0xff, 0xaa, 0xcc, 0xdd};
-    byte result[8] =
-      {0x7b, 0x38, 0x3b, 0x23, 0xa2, 0x7d, 0x26, 0xd3};
-
-    tripledes_ctx des3;
-
-    for (i = 0; i < 16; ++i)
-      {
-       tripledes_set2keys (des3, key1, key2);
-       tripledes_ecb_encrypt (des3, input, key1);
-       tripledes_ecb_decrypt (des3, input, key2);
-       tripledes_set3keys (des3, key1, input, key2);
-       tripledes_ecb_encrypt (des3, input, input);
-      }
-    if (memcmp (input, result, 8))
-      return "Triple-DES test failed.";
-  }
-  
-  /*
-   * More Triple-DES test.  These are testvectors as used by SSLeay,
-   * thanks to Jeroen C. van Gelderen.
-   */
-  { 
-    struct { byte key[24]; byte plain[8]; byte cipher[8]; } testdata[] = {
-      { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-          0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-          0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01  },
-        { 0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00  },
-        { 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00  }
-      },
-      
-      { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-          0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-          0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01  },
-        { 0x9D,0x64,0x55,0x5A,0x9A,0x10,0xB8,0x52, },
-        { 0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00  }
-      },
-      { { 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E,
-          0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E,
-          0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E  },
-        { 0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A  },
-        { 0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A  }
-      },
-      { { 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6,
-          0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6,
-          0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6  },
-        { 0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2  },
-        { 0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95  }
-      },
-      { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
-          0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
-          0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF  },
-        { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61  },
-        { 0x3D,0x12,0x4F,0xE2,0x19,0x8B,0xA3,0x18  }
-      },
-      { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
-          0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
-          0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF  },
-        { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61  },
-        { 0xFB,0xAB,0xA1,0xFF,0x9D,0x05,0xE9,0xB1  }
-      },
-      { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
-          0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
-          0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10  },
-        { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61  },
-        { 0x18,0xd7,0x48,0xe5,0x63,0x62,0x05,0x72  }
-      },
-      { { 0x03,0x52,0x02,0x07,0x67,0x20,0x82,0x17,
-          0x86,0x02,0x87,0x66,0x59,0x08,0x21,0x98,
-          0x64,0x05,0x6A,0xBD,0xFE,0xA9,0x34,0x57  },
-        { 0x73,0x71,0x75,0x69,0x67,0x67,0x6C,0x65  },
-        { 0xc0,0x7d,0x2a,0x0f,0xa5,0x66,0xfa,0x30  }
-      },
-      { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-          0x80,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-          0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02  },
-        { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00  },
-        { 0xe6,0xe6,0xdd,0x5b,0x7e,0x72,0x29,0x74  }
-      },
-      { { 0x10,0x46,0x10,0x34,0x89,0x98,0x80,0x20,
-          0x91,0x07,0xD0,0x15,0x89,0x19,0x01,0x01,
-          0x19,0x07,0x92,0x10,0x98,0x1A,0x01,0x01  },
-        { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00  },
-        { 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b  }
-      }
-    };
-
-    byte               result[8];
-    int                i;
-    tripledes_ctx      des3;
-
-    for (i=0; i<sizeof(testdata)/sizeof(*testdata); ++i)
-      {
-        tripledes_set3keys (des3, testdata[i].key,
-                            testdata[i].key + 8, testdata[i].key + 16);
-        
-        tripledes_ecb_encrypt (des3, testdata[i].plain, result);
-        if (memcmp (testdata[i].cipher, result, 8))
-          return "Triple-DES SSLeay test failed on encryption.";
-
-        tripledes_ecb_decrypt (des3, testdata[i].cipher, result);
-        if (memcmp (testdata[i].plain, result, 8))
-          return  "Triple-DES SSLeay test failed on decryption.";;
-      }
-  }
-
-  /*
-   * Check the weak key detection. We simply assume that the table
-   * with weak keys is ok and check every key in the table if it is
-   * detected... (This test is a little bit stupid).
-   */
-  {
-    int i;
-    unsigned char *p;
-    gcry_md_hd_t h;
-
-    if (_gcry_md_open (&h, GCRY_MD_SHA1, 0))
-      return "SHA1 not available";
-
-    for (i = 0; i < 64; ++i)
-      _gcry_md_write (h, weak_keys[i], 8);
-    p = _gcry_md_read (h, GCRY_MD_SHA1);
-    i = memcmp (p, weak_keys_chksum, 20);
-    _gcry_md_close (h);
-    if (i)
-      return "weak key table defect";
-
-    for (i = 0; i < 64; ++i)
-      if (!is_weak_key(weak_keys[i]))
-        return "DES weak key detection failed";
-  }
-
-  return 0;
-}
-
-
-static gcry_err_code_t
-do_tripledes_setkey ( void *context, const byte *key, unsigned keylen )
-{
-  struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
-
-  if( keylen != 24 )
-    return GPG_ERR_INV_KEYLEN;
-
-  tripledes_set3keys ( ctx, key, key+8, key+16);
-
-  if (ctx->flags.no_weak_key)
-    ; /* Detection has been disabled.  */
-  else if (is_weak_key (key) || is_weak_key (key+8) || is_weak_key (key+16))
-    {
-      _gcry_burn_stack (64);
-      return GPG_ERR_WEAK_KEY;
-    }
-  _gcry_burn_stack (64);
-
-  return GPG_ERR_NO_ERROR;
-}
-
-
-static gcry_err_code_t
-do_tripledes_set_extra_info (void *context, int what,
-                             const void *buffer, size_t buflen)
-{
-  struct _tripledes_ctx *ctx = (struct _tripledes_ctx *)context;
-  gpg_err_code_t ec = 0;
-
-  (void)buffer;
-  (void)buflen;
-
-  switch (what)
-    {
-    case CIPHER_INFO_NO_WEAK_KEY:
-      ctx->flags.no_weak_key = 1;
-      break;
-
-    default:
-      ec = GPG_ERR_INV_OP; 
-      break;
-    }
-  return ec;
-}
-
-
-static void
-do_tripledes_encrypt( void *context, byte *outbuf, const byte *inbuf )
-{
-  struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
-
-  tripledes_ecb_encrypt ( ctx, inbuf, outbuf );
-  _gcry_burn_stack (32);
-}
-
-static void
-do_tripledes_decrypt( void *context, byte *outbuf, const byte *inbuf )
-{
-  struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
-  tripledes_ecb_decrypt ( ctx, inbuf, outbuf );
-  _gcry_burn_stack (32);
-}
-
-static gcry_err_code_t
-do_des_setkey (void *context, const byte *key, unsigned keylen)
-{
-  struct _des_ctx *ctx = (struct _des_ctx *) context;
-
-  if (keylen != 8)
-    return GPG_ERR_INV_KEYLEN;
-
-  des_setkey (ctx, key);
-
-  if (is_weak_key (key)) {
-    _gcry_burn_stack (64);
-    return GPG_ERR_WEAK_KEY;
-  }
-  _gcry_burn_stack (64);
-
-  return GPG_ERR_NO_ERROR;
-}
-
-
-static void
-do_des_encrypt( void *context, byte *outbuf, const byte *inbuf )
-{
-  struct _des_ctx *ctx = (struct _des_ctx *) context;
-
-  des_ecb_encrypt ( ctx, inbuf, outbuf );
-  _gcry_burn_stack (32);
-}
-
-static void
-do_des_decrypt( void *context, byte *outbuf, const byte *inbuf )
-{
-  struct _des_ctx *ctx = (struct _des_ctx *) context;
-
-  des_ecb_decrypt ( ctx, inbuf, outbuf );
-  _gcry_burn_stack (32);
-}
-
-
-
-\f
-/* 
-     Self-test section.
- */
-
-
-/* Selftest for TripleDES.  */
-static gpg_err_code_t
-selftest_fips (int extended, selftest_report_func_t report)
-{
-  const char *what;
-  const char *errtxt;
-  
-  (void)extended; /* No extended tests available.  */
-
-  what = "low-level";
-  errtxt = selftest ();
-  if (errtxt)
-    goto failed;
-
-  /* The low-level self-tests are quite extensive and thus we can do
-     without high level tests.  This is also justified because we have
-     no custom block code implementation for 3des but always use the
-     standard high level block code.  */
-
-  return 0; /* Succeeded. */
-
- failed:
-  if (report)
-    report ("cipher", GCRY_CIPHER_3DES, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-
-
-/* Run a full self-test for ALGO and return 0 on success.  */
-static gpg_err_code_t
-run_selftests (int algo, int extended, selftest_report_func_t report)
-{
-  gpg_err_code_t ec;
-
-  switch (algo)
-    {
-    case GCRY_CIPHER_3DES:
-      ec = selftest_fips (extended, report);
-      break;
-    default:
-      ec = GPG_ERR_CIPHER_ALGO;
-      break;
-        
-    }
-  return ec;
-}
-
-
-\f
-gcry_cipher_spec_t _gcry_cipher_spec_des =
-  {
-    "DES", NULL, NULL, 8, 64, sizeof (struct _des_ctx),
-    do_des_setkey, do_des_encrypt, do_des_decrypt
-  };
-
-static gcry_cipher_oid_spec_t oids_tripledes[] =
-  {
-    { "1.2.840.113549.3.7", GCRY_CIPHER_MODE_CBC },
-    /* Teletrust specific OID for 3DES. */
-    { "1.3.36.3.1.3.2.1",   GCRY_CIPHER_MODE_CBC },
-    /* pbeWithSHAAnd3_KeyTripleDES_CBC */
-    { "1.2.840.113549.1.12.1.3", GCRY_CIPHER_MODE_CBC },
-    { NULL }
-  };
-
-gcry_cipher_spec_t _gcry_cipher_spec_tripledes =
-  {
-    "3DES", NULL, oids_tripledes, 8, 192, sizeof (struct _tripledes_ctx),
-    do_tripledes_setkey, do_tripledes_encrypt, do_tripledes_decrypt
-  };
-
-cipher_extra_spec_t _gcry_cipher_extraspec_tripledes = 
-  {
-    run_selftests,
-    do_tripledes_set_extra_info
-  };
diff --git a/lib/libgcrypt/cipher/dsa.c b/lib/libgcrypt/cipher/dsa.c
deleted file mode 100644 (file)
index 100710f..0000000
+++ /dev/null
@@ -1,1181 +0,0 @@
-/* dsa.c - DSA signature algorithm
- * Copyright (C) 1998, 2000, 2001, 2002, 2003,
- *               2006, 2008  Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "g10lib.h"
-#include "mpi.h"
-#include "cipher.h"
-
-typedef struct
-{
-  gcry_mpi_t p;            /* prime */
-  gcry_mpi_t q;            /* group order */
-  gcry_mpi_t g;            /* group generator */
-  gcry_mpi_t y;            /* g^x mod p */
-} DSA_public_key;
-
-
-typedef struct
-{
-  gcry_mpi_t p;            /* prime */
-  gcry_mpi_t q;            /* group order */
-  gcry_mpi_t g;            /* group generator */
-  gcry_mpi_t y;            /* g^x mod p */
-  gcry_mpi_t x;            /* secret exponent */
-} DSA_secret_key;
-
-
-/* A structure used to hold domain parameters.  */
-typedef struct
-{
-  gcry_mpi_t p;            /* prime */
-  gcry_mpi_t q;            /* group order */
-  gcry_mpi_t g;            /* group generator */
-} dsa_domain_t;
-
-
-/* A sample 1024 bit DSA key used for the selftests.  */
-static const char sample_secret_key[] =
-"(private-key"
-" (dsa"
-"  (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
-"      96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
-"      CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
-"      44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)"
-"  (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)"
-"  (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
-"      AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
-"      B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
-"      3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)"
-"  (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
-"      A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
-"      6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
-"      42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)"
-"  (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))";
-/* A sample 1024 bit DSA key used for the selftests (public only).  */
-static const char sample_public_key[] = 
-"(public-key"
-" (dsa"
-"  (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
-"      96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
-"      CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
-"      44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)"
-"  (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)"
-"  (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
-"      AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
-"      B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
-"      3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)"
-"  (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
-"      A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
-"      6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
-"      42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))";
-
-
-
-\f
-static gcry_mpi_t gen_k (gcry_mpi_t q);
-static int test_keys (DSA_secret_key *sk, unsigned int qbits);
-static int check_secret_key (DSA_secret_key *sk);
-static gpg_err_code_t generate (DSA_secret_key *sk,
-                                unsigned int nbits,
-                                unsigned int qbits,
-                                int transient_key,
-                                dsa_domain_t *domain,
-                                gcry_mpi_t **ret_factors);
-static void sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
-                  DSA_secret_key *skey);
-static int verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
-                   DSA_public_key *pkey);
-
-static void (*progress_cb) (void *,const char *, int, int, int );
-static void *progress_cb_data;
-
-
-void
-_gcry_register_pk_dsa_progress (void (*cb) (void *, const char *,
-                                            int, int, int),
-                               void *cb_data)
-{
-  progress_cb = cb;
-  progress_cb_data = cb_data;
-}
-
-
-static void
-progress (int c)
-{
-  if (progress_cb)
-    progress_cb (progress_cb_data, "pk_dsa", c, 0, 0);
-}
-
-
-/*
- * Generate a random secret exponent k less than q.
- */
-static gcry_mpi_t
-gen_k( gcry_mpi_t q )
-{
-  gcry_mpi_t k = mpi_alloc_secure( mpi_get_nlimbs(q) );
-  unsigned int nbits = mpi_get_nbits(q);
-  unsigned int nbytes = (nbits+7)/8;
-  char *rndbuf = NULL;
-
-  if ( DBG_CIPHER )
-    log_debug("choosing a random k ");
-  for (;;) 
-    {
-      if( DBG_CIPHER )
-        progress('.');
-
-      if ( !rndbuf || nbits < 32 ) 
-        {
-          gcry_free(rndbuf);
-          rndbuf = gcry_random_bytes_secure( (nbits+7)/8, GCRY_STRONG_RANDOM );
-       }
-      else
-        { /* Change only some of the higher bits.  We could improve
-            this by directly requesting more memory at the first call
-            to get_random_bytes() and use this the here maybe it is
-            easier to do this directly in random.c. */
-          char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
-          memcpy( rndbuf,pp, 4 );
-          gcry_free(pp);
-       }
-      _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
-      if ( mpi_test_bit( k, nbits-1 ) )
-        mpi_set_highbit( k, nbits-1 );
-      else
-        {
-          mpi_set_highbit( k, nbits-1 );
-          mpi_clear_bit( k, nbits-1 );
-       }
-
-      if( !(mpi_cmp( k, q ) < 0) ) /* check: k < q */
-        {      
-          if( DBG_CIPHER )
-            progress('+');
-          continue; /* no  */
-        }
-      if( !(mpi_cmp_ui( k, 0 ) > 0) )  /* check: k > 0 */
-        {
-          if( DBG_CIPHER )
-            progress('-');
-          continue; /* no */
-        }
-      break;   /* okay */
-    }
-  gcry_free(rndbuf);
-  if( DBG_CIPHER )
-    progress('\n');
-  
-  return k;
-}
-
-
-/* Check that a freshly generated key actually works.  Returns 0 on success. */
-static int
-test_keys (DSA_secret_key *sk, unsigned int qbits)
-{
-  int result = -1;  /* Default to failure.  */
-  DSA_public_key pk;
-  gcry_mpi_t data  = gcry_mpi_new (qbits);
-  gcry_mpi_t sig_a = gcry_mpi_new (qbits);
-  gcry_mpi_t sig_b = gcry_mpi_new (qbits);
-
-  /* Put the relevant parameters into a public key structure.  */
-  pk.p = sk->p;
-  pk.q = sk->q;
-  pk.g = sk->g;
-  pk.y = sk->y;
-
-  /* Create a random plaintext.  */
-  gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
-
-  /* Sign DATA using the secret key.  */
-  sign (sig_a, sig_b, data, sk);
-
-  /* Verify the signature using the public key.  */
-  if ( !verify (sig_a, sig_b, data, &pk) )
-    goto leave; /* Signature does not match.  */
-
-  /* Modify the data and check that the signing fails.  */
-  gcry_mpi_add_ui (data, data, 1);
-  if ( verify (sig_a, sig_b, data, &pk) )
-    goto leave; /* Signature matches but should not.  */
-
-  result = 0; /* The test succeeded.  */
-
- leave:
-  gcry_mpi_release (sig_b);
-  gcry_mpi_release (sig_a);
-  gcry_mpi_release (data);
-  return result;
-}
-
-
-
-/*
-   Generate a DSA key pair with a key of size NBITS.  If transient_key
-   is true the key is generated using the standard RNG and not the
-   very secure one.
-
-   Returns: 2 structures filled with all needed values
-           and an array with the n-1 factors of (p-1)
- */
-static gpg_err_code_t
-generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
-          int transient_key, dsa_domain_t *domain, gcry_mpi_t **ret_factors )
-{
-  gcry_mpi_t p;    /* the prime */
-  gcry_mpi_t q;    /* the 160 bit prime factor */
-  gcry_mpi_t g;    /* the generator */
-  gcry_mpi_t y;    /* g^x mod p */
-  gcry_mpi_t x;    /* the secret exponent */
-  gcry_mpi_t h, e;  /* helper */
-  unsigned char *rndbuf;
-  gcry_random_level_t random_level;
-
-  if (qbits)
-    ; /* Caller supplied qbits.  Use this value.  */
-  else if ( nbits >= 512 && nbits <= 1024 )
-    qbits = 160;
-  else if ( nbits == 2048 )
-    qbits = 224;
-  else if ( nbits == 3072 )
-    qbits = 256;
-  else if ( nbits == 7680 )
-    qbits = 384;
-  else if ( nbits == 15360 )
-    qbits = 512;
-  else
-    return GPG_ERR_INV_VALUE;
-
-  if (qbits < 160 || qbits > 512 || (qbits%8) )
-    return GPG_ERR_INV_VALUE;
-  if (nbits < 2*qbits || nbits > 15360)
-    return GPG_ERR_INV_VALUE;
-
-  if (fips_mode ())
-    {
-      if (nbits < 1024)
-        return GPG_ERR_INV_VALUE;
-      if (transient_key)
-        return GPG_ERR_INV_VALUE;
-    }
-
-  if (domain->p && domain->q && domain->g)
-    {
-      /* Domain parameters are given; use them.  */
-      p = mpi_copy (domain->p);
-      q = mpi_copy (domain->q);
-      g = mpi_copy (domain->g);
-      gcry_assert (mpi_get_nbits (p) == nbits);
-      gcry_assert (mpi_get_nbits (q) == qbits);
-      h = mpi_alloc (0);
-      e = NULL;
-    }
-  else
-    {
-      /* Generate new domain parameters.  */
-      p = _gcry_generate_elg_prime (1, nbits, qbits, NULL, ret_factors);
-      /* Get q out of factors.  */
-      q = mpi_copy ((*ret_factors)[0]);
-      gcry_assert (mpi_get_nbits (q) == qbits);
-
-      /* Find a generator g (h and e are helpers).
-         e = (p-1)/q */
-      e = mpi_alloc (mpi_get_nlimbs (p));
-      mpi_sub_ui (e, p, 1);
-      mpi_fdiv_q (e, e, q);
-      g = mpi_alloc (mpi_get_nlimbs (p));
-      h = mpi_alloc_set_ui (1); /* (We start with 2.) */
-      do
-        {
-          mpi_add_ui (h, h, 1);
-          /* g = h^e mod p */
-          gcry_mpi_powm (g, h, e, p);
-        } 
-      while (!mpi_cmp_ui (g, 1));  /* Continue until g != 1. */
-    }
-
-  /* Select a random number X with the property:
-   *    0 < x < q-1
-   * This must be a very good random number because this is the secret
-   * part.  The random quality depends on the transient_key flag.  */
-  random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
-  if (DBG_CIPHER)
-    log_debug("choosing a random x%s", transient_key? " (transient-key)":"");
-  gcry_assert( qbits >= 160 );
-  x = mpi_alloc_secure( mpi_get_nlimbs(q) );
-  mpi_sub_ui( h, q, 1 );  /* put q-1 into h */
-  rndbuf = NULL;
-  do 
-    {
-      if( DBG_CIPHER )
-        progress('.');
-      if( !rndbuf )
-        rndbuf = gcry_random_bytes_secure ((qbits+7)/8, random_level);
-      else 
-        { /* Change only some of the higher bits (= 2 bytes)*/
-          char *r = gcry_random_bytes_secure (2, random_level);
-          memcpy(rndbuf, r, 2 );
-          gcry_free(r);
-        }
-
-      _gcry_mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
-      mpi_clear_highbit( x, qbits+1 );
-    } 
-  while ( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
-  gcry_free(rndbuf);
-  mpi_free( e );
-  mpi_free( h );
-
-  /* y = g^x mod p */
-  y = mpi_alloc( mpi_get_nlimbs(p) );
-  gcry_mpi_powm( y, g, x, p );
-
-  if( DBG_CIPHER ) 
-    {
-      progress('\n');
-      log_mpidump("dsa  p", p );
-      log_mpidump("dsa  q", q );
-      log_mpidump("dsa  g", g );
-      log_mpidump("dsa  y", y );
-      log_mpidump("dsa  x", x );
-    }
-
-  /* Copy the stuff to the key structures. */
-  sk->p = p;
-  sk->q = q;
-  sk->g = g;
-  sk->y = y;
-  sk->x = x;
-
-  /* Now we can test our keys (this should never fail!). */
-  if ( test_keys (sk, qbits) )
-    {
-      gcry_mpi_release (sk->p); sk->p = NULL;
-      gcry_mpi_release (sk->q); sk->q = NULL;
-      gcry_mpi_release (sk->g); sk->g = NULL;
-      gcry_mpi_release (sk->y); sk->y = NULL;
-      gcry_mpi_release (sk->x); sk->x = NULL;
-      fips_signal_error ("self-test after key generation failed");
-      return GPG_ERR_SELFTEST_FAILED;
-    }
-  return 0;
-}
-
-
-/* Generate a DSA key pair with a key of size NBITS using the
-   algorithm given in FIPS-186-3.  If USE_FIPS186_2 is true,
-   FIPS-186-2 is used and thus the length is restricted to 1024/160.
-   If DERIVEPARMS is not NULL it may contain a seed value.  If domain
-   parameters are specified in DOMAIN, DERIVEPARMS may not be given
-   and NBITS and QBITS must match the specified domain parameters.  */
-static gpg_err_code_t
-generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
-                  gcry_sexp_t deriveparms, int use_fips186_2,
-                  dsa_domain_t *domain,
-                  int *r_counter, void **r_seed, size_t *r_seedlen,
-                  gcry_mpi_t *r_h)
-{
-  gpg_err_code_t ec;
-  struct {
-    gcry_sexp_t sexp;
-    const void *seed;
-    size_t seedlen;
-  } initial_seed = { NULL, NULL, 0 };
-  gcry_mpi_t prime_q = NULL; 
-  gcry_mpi_t prime_p = NULL; 
-  gcry_mpi_t value_g = NULL; /* The generator. */
-  gcry_mpi_t value_y = NULL; /* g^x mod p */
-  gcry_mpi_t value_x = NULL; /* The secret exponent. */
-  gcry_mpi_t value_h = NULL; /* Helper.  */
-  gcry_mpi_t value_e = NULL; /* Helper.  */
-
-  /* Preset return values.  */
-  *r_counter = 0;
-  *r_seed = NULL;
-  *r_seedlen = 0;
-  *r_h = NULL;
-
-  /* Derive QBITS from NBITS if requested  */
-  if (!qbits)
-    {
-      if (nbits == 1024)
-        qbits = 160;
-      else if (nbits == 2048)
-        qbits = 224;
-      else if (nbits == 3072)
-        qbits = 256;
-    }
-
-  /* Check that QBITS and NBITS match the standard.  Note that FIPS
-     186-3 uses N for QBITS and L for NBITS.  */
-  if (nbits == 1024 && qbits == 160)
-    ;
-  else if (nbits == 2048 && qbits == 224)
-    ;
-  else if (nbits == 2048 && qbits == 256)
-    ;
-  else if (nbits == 3072 && qbits == 256)
-    ;
-  else
-    return GPG_ERR_INV_VALUE;
-
-  if (domain->p && domain->q && domain->g)
-    {
-      /* Domain parameters are given; use them.  */
-      prime_p = mpi_copy (domain->p);
-      prime_q = mpi_copy (domain->q);
-      value_g = mpi_copy (domain->g);
-      gcry_assert (mpi_get_nbits (prime_p) == nbits);
-      gcry_assert (mpi_get_nbits (prime_q) == qbits);
-      gcry_assert (!deriveparms);
-      ec = 0;
-    }
-  else
-    {
-      /* Generate new domain parameters.  */
-
-      /* Get an initial seed value.  */
-      if (deriveparms)
-        {
-          initial_seed.sexp = gcry_sexp_find_token (deriveparms, "seed", 0);
-          if (initial_seed.sexp)
-            initial_seed.seed = gcry_sexp_nth_data (initial_seed.sexp, 1,
-                                                    &initial_seed.seedlen);
-        }
-      
-      /* Fixme: Enable 186-3 after it has been approved and after fixing
-         the generation function.  */
-      /*   if (use_fips186_2) */
-      (void)use_fips186_2;
-      ec = _gcry_generate_fips186_2_prime (nbits, qbits, 
-                                           initial_seed.seed, 
-                                           initial_seed.seedlen,
-                                           &prime_q, &prime_p, 
-                                           r_counter,
-                                           r_seed, r_seedlen);
-      /*   else */
-      /*     ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, */
-      /*                                          &prime_q, &prime_p, */
-      /*                                          r_counter, */
-      /*                                          r_seed, r_seedlen, NULL); */
-      gcry_sexp_release (initial_seed.sexp);
-      if (ec)
-        goto leave;
-
-      /* Find a generator g (h and e are helpers).
-         e = (p-1)/q */
-      value_e = mpi_alloc_like (prime_p);
-      mpi_sub_ui (value_e, prime_p, 1);
-      mpi_fdiv_q (value_e, value_e, prime_q );
-      value_g = mpi_alloc_like (prime_p);
-      value_h = mpi_alloc_set_ui (1); 
-      do
-        {
-          mpi_add_ui (value_h, value_h, 1);
-          /* g = h^e mod p */
-          mpi_powm (value_g, value_h, value_e, prime_p);
-        } 
-      while (!mpi_cmp_ui (value_g, 1));  /* Continue until g != 1.  */
-    }
-
-
-  /* Select a random number x with:  0 < x < q  */
-  value_x = gcry_mpi_snew (qbits);
-  do 
-    {
-      if( DBG_CIPHER )
-        progress('.');
-      gcry_mpi_randomize (value_x, qbits, GCRY_VERY_STRONG_RANDOM);
-      mpi_clear_highbit (value_x, qbits+1);
-    } 
-  while (!(mpi_cmp_ui (value_x, 0) > 0 && mpi_cmp (value_x, prime_q) < 0));
-
-  /* y = g^x mod p */
-  value_y = mpi_alloc_like (prime_p);
-  gcry_mpi_powm (value_y, value_g, value_x, prime_p);
-
-  if (DBG_CIPHER) 
-    {
-      progress('\n');
-      log_mpidump("dsa  p", prime_p );
-      log_mpidump("dsa  q", prime_q );
-      log_mpidump("dsa  g", value_g );
-      log_mpidump("dsa  y", value_y );
-      log_mpidump("dsa  x", value_x );
-      log_mpidump("dsa  h", value_h );
-    }
-
-  /* Copy the stuff to the key structures. */
-  sk->p = prime_p; prime_p = NULL;
-  sk->q = prime_q; prime_q = NULL;
-  sk->g = value_g; value_g = NULL;
-  sk->y = value_y; value_y = NULL;
-  sk->x = value_x; value_x = NULL;
-  *r_h = value_h; value_h = NULL;
-
- leave:
-  gcry_mpi_release (prime_p);
-  gcry_mpi_release (prime_q);
-  gcry_mpi_release (value_g);
-  gcry_mpi_release (value_y);
-  gcry_mpi_release (value_x);
-  gcry_mpi_release (value_h);
-  gcry_mpi_release (value_e);
-
-  /* As a last step test this keys (this should never fail of course). */
-  if (!ec && test_keys (sk, qbits) )
-    {
-      gcry_mpi_release (sk->p); sk->p = NULL;
-      gcry_mpi_release (sk->q); sk->q = NULL;
-      gcry_mpi_release (sk->g); sk->g = NULL;
-      gcry_mpi_release (sk->y); sk->y = NULL;
-      gcry_mpi_release (sk->x); sk->x = NULL;
-      fips_signal_error ("self-test after key generation failed");
-      ec = GPG_ERR_SELFTEST_FAILED;
-    }
-
-  if (ec)
-    {
-      *r_counter = 0;
-      gcry_free (*r_seed); *r_seed = NULL;
-      *r_seedlen = 0;
-      gcry_mpi_release (*r_h); *r_h = NULL;
-    }
-
-  return ec;
-}
-
-
-
-/*
-   Test whether the secret key is valid.
-   Returns: if this is a valid key.
- */
-static int
-check_secret_key( DSA_secret_key *sk )
-{
-  int rc;
-  gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
-
-  gcry_mpi_powm( y, sk->g, sk->x, sk->p );
-  rc = !mpi_cmp( y, sk->y );
-  mpi_free( y );
-  return rc;
-}
-
-
-
-/*
-   Make a DSA signature from HASH and put it into r and s.
- */
-static void
-sign(gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_secret_key *skey )
-{
-  gcry_mpi_t k;
-  gcry_mpi_t kinv;
-  gcry_mpi_t tmp;
-
-  /* Select a random k with 0 < k < q */
-  k = gen_k( skey->q );
-
-  /* r = (a^k mod p) mod q */
-  gcry_mpi_powm( r, skey->g, k, skey->p );
-  mpi_fdiv_r( r, r, skey->q );
-
-  /* kinv = k^(-1) mod q */
-  kinv = mpi_alloc( mpi_get_nlimbs(k) );
-  mpi_invm(kinv, k, skey->q );
-
-  /* s = (kinv * ( hash + x * r)) mod q */
-  tmp = mpi_alloc( mpi_get_nlimbs(skey->p) );
-  mpi_mul( tmp, skey->x, r );
-  mpi_add( tmp, tmp, hash );
-  mpi_mulm( s , kinv, tmp, skey->q );
-
-  mpi_free(k);
-  mpi_free(kinv);
-  mpi_free(tmp);
-}
-
-
-/*
-   Returns true if the signature composed from R and S is valid.
- */
-static int
-verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_public_key *pkey )
-{
-  int rc;
-  gcry_mpi_t w, u1, u2, v;
-  gcry_mpi_t base[3];
-  gcry_mpi_t ex[3];
-
-  if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
-    return 0; /* assertion     0 < r < q  failed */
-  if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
-    return 0; /* assertion     0 < s < q  failed */
-
-  w  = mpi_alloc( mpi_get_nlimbs(pkey->q) );
-  u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
-  u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
-  v  = mpi_alloc( mpi_get_nlimbs(pkey->p) );
-
-  /* w = s^(-1) mod q */
-  mpi_invm( w, s, pkey->q );
-
-  /* u1 = (hash * w) mod q */
-  mpi_mulm( u1, hash, w, pkey->q );
-
-  /* u2 = r * w mod q  */
-  mpi_mulm( u2, r, w, pkey->q );
-
-  /* v =  g^u1 * y^u2 mod p mod q */
-  base[0] = pkey->g; ex[0] = u1;
-  base[1] = pkey->y; ex[1] = u2;
-  base[2] = NULL;    ex[2] = NULL;
-  mpi_mulpowm( v, base, ex, pkey->p );
-  mpi_fdiv_r( v, v, pkey->q );
-
-  rc = !mpi_cmp( v, r );
-
-  mpi_free(w);
-  mpi_free(u1);
-  mpi_free(u2);
-  mpi_free(v);
-
-  return rc;
-}
-
-
-/*********************************************
- **************  interface  ******************
- *********************************************/
-
-static gcry_err_code_t
-dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
-                  const gcry_sexp_t genparms,
-                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
-                  gcry_sexp_t *r_extrainfo)
-{
-  gpg_err_code_t ec;
-  DSA_secret_key sk;
-  gcry_sexp_t l1;
-  unsigned int qbits = 0;
-  gcry_sexp_t deriveparms = NULL;
-  gcry_sexp_t seedinfo = NULL;
-  int transient_key = 0;
-  int use_fips186_2 = 0;
-  int use_fips186 = 0;
-  dsa_domain_t domain;
-  (void)algo;    /* No need to check it.  */
-  (void)evalue;  /* Not required for DSA. */
-
-  memset (&domain, 0, sizeof domain);
-
-  if (genparms)
-    {
-      gcry_sexp_t domainsexp;
-  
-      /* Parse the optional qbits element.  */
-      l1 = gcry_sexp_find_token (genparms, "qbits", 0);
-      if (l1)
-        {
-          char buf[50];
-          const char *s;
-          size_t n;
-          
-          s = gcry_sexp_nth_data (l1, 1, &n);
-          if (!s || n >= DIM (buf) - 1 )
-            {
-              gcry_sexp_release (l1);
-              return GPG_ERR_INV_OBJ; /* No value or value too large.  */
-            }
-          memcpy (buf, s, n);
-          buf[n] = 0;
-          qbits = (unsigned int)strtoul (buf, NULL, 0);
-          gcry_sexp_release (l1);
-        }
-
-      /* Parse the optional transient-key flag.  */
-      l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
-      if (l1)
-        {
-          transient_key = 1;
-          gcry_sexp_release (l1);
-        }
-
-      /* Get the optional derive parameters.  */
-      deriveparms = gcry_sexp_find_token (genparms, "derive-parms", 0);
-
-      /* Parse the optional "use-fips186" flags.  */
-      l1 = gcry_sexp_find_token (genparms, "use-fips186", 0);
-      if (l1)
-        {
-          use_fips186 = 1;
-          gcry_sexp_release (l1);
-        }
-      l1 = gcry_sexp_find_token (genparms, "use-fips186-2", 0);
-      if (l1)
-        {
-          use_fips186_2 = 1;
-          gcry_sexp_release (l1);
-        }
-
-      /* Check whether domain parameters are given.  */
-      domainsexp = gcry_sexp_find_token (genparms, "domain", 0);
-      if (domainsexp)
-        {
-          /* DERIVEPARMS can't be used together with domain
-             parameters.  NBITS abnd QBITS may not be specified
-             because there values are derived from the domain
-             parameters.  */
-          if (deriveparms || qbits || nbits)
-            {
-              gcry_sexp_release (domainsexp);
-              gcry_sexp_release (deriveparms);
-              return GPG_ERR_INV_VALUE;
-            }
-          
-          /* Put all domain parameters into the domain object.  */
-          l1 = gcry_sexp_find_token (domainsexp, "p", 0);
-          domain.p = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
-          gcry_sexp_release (l1);
-          l1 = gcry_sexp_find_token (domainsexp, "q", 0);
-          domain.q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
-          gcry_sexp_release (l1);
-          l1 = gcry_sexp_find_token (domainsexp, "g", 0);
-          domain.g = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
-          gcry_sexp_release (l1);
-          gcry_sexp_release (domainsexp);
-
-          /* Check that all domain parameters are available.  */
-          if (!domain.p || !domain.q || !domain.g)
-            {
-              gcry_mpi_release (domain.p);
-              gcry_mpi_release (domain.q);
-              gcry_mpi_release (domain.g);
-              gcry_sexp_release (deriveparms);
-              return GPG_ERR_MISSING_VALUE;
-            }
-
-          /* Get NBITS and QBITS from the domain parameters.  */
-          nbits = mpi_get_nbits (domain.p);
-          qbits = mpi_get_nbits (domain.q);
-        }
-    }
-
-  if (deriveparms || use_fips186 || use_fips186_2 || fips_mode ())
-    {
-      int counter;
-      void *seed;
-      size_t seedlen;
-      gcry_mpi_t h_value;
-
-      ec = generate_fips186 (&sk, nbits, qbits, deriveparms, use_fips186_2,
-                             &domain,
-                             &counter, &seed, &seedlen, &h_value);
-      gcry_sexp_release (deriveparms);
-      if (!ec && h_value)
-        {
-          /* Format the seed-values unless domain parameters are used
-             for which a H_VALUE of NULL is an indication.  */
-          ec = gpg_err_code (gcry_sexp_build 
-                             (&seedinfo, NULL,
-                              "(seed-values(counter %d)(seed %b)(h %m))",
-                              counter, (int)seedlen, seed, h_value));
-          if (ec)
-            {
-              gcry_mpi_release (sk.p); sk.p = NULL;
-              gcry_mpi_release (sk.q); sk.q = NULL;
-              gcry_mpi_release (sk.g); sk.g = NULL;
-              gcry_mpi_release (sk.y); sk.y = NULL;
-              gcry_mpi_release (sk.x); sk.x = NULL;
-            }
-          gcry_free (seed);
-          gcry_mpi_release (h_value);
-        }
-    }
-  else
-    {
-      ec = generate (&sk, nbits, qbits, transient_key, &domain, retfactors);
-    }
-
-  gcry_mpi_release (domain.p);
-  gcry_mpi_release (domain.q);
-  gcry_mpi_release (domain.g);
-
-  if (!ec)
-    {
-      skey[0] = sk.p;
-      skey[1] = sk.q;
-      skey[2] = sk.g;
-      skey[3] = sk.y;
-      skey[4] = sk.x;
-
-      if (!r_extrainfo)
-        {
-          /* Old style interface - return the factors - if any - at
-             retfactors.  */
-        }
-      else if (!*retfactors && !seedinfo)
-        {
-          /* No factors and no seedinfo, thus there is nothing to return.  */
-          *r_extrainfo = NULL;
-        }
-      else
-        {
-          /* Put the factors into extrainfo and set retfactors to NULL
-             to make use of the new interface.  Note that the factors
-             are not confidential thus we can store them in standard
-             memory.  */
-          int nfactors, i, j;
-          char *p;
-          char *format = NULL;
-          void **arg_list = NULL;
-
-          for (nfactors=0; *retfactors && (*retfactors)[nfactors]; nfactors++)
-            ;
-          /* Allocate space for the format string:
-               "(misc-key-info%S(pm1-factors%m))"
-             with one "%m" for each factor and construct it.  */
-          format = gcry_malloc (50 + 2*nfactors);
-          if (!format)
-            ec = gpg_err_code_from_syserror ();
-          else
-            {
-              p = stpcpy (format, "(misc-key-info");
-              if (seedinfo)
-                p = stpcpy (p, "%S");
-              if (nfactors)
-                {
-                  p = stpcpy (p, "(pm1-factors");
-                  for (i=0; i < nfactors; i++)
-                    p = stpcpy (p, "%m");
-                  p = stpcpy (p, ")");
-                }
-              p = stpcpy (p, ")");
-              
-              /* Allocate space for the list of factors plus one for
-                 an S-expression plus an extra NULL entry for safety
-                 and fill it with the factors.  */
-              arg_list = gcry_calloc (nfactors+1+1, sizeof *arg_list);
-              if (!arg_list)
-                ec = gpg_err_code_from_syserror ();
-              else
-                {
-                  i = 0;
-                  if (seedinfo)
-                    arg_list[i++] = &seedinfo;
-                  for (j=0; j < nfactors; j++)
-                    arg_list[i++] = (*retfactors) + j;
-                  arg_list[i] = NULL;
-                  
-                  ec = gpg_err_code (gcry_sexp_build_array 
-                                     (r_extrainfo, NULL, format, arg_list));
-                }
-            }
-
-          gcry_free (arg_list);
-          gcry_free (format);
-          for (i=0; i < nfactors; i++)
-            {
-              gcry_mpi_release ((*retfactors)[i]);
-              (*retfactors)[i] = NULL;
-            }
-          *retfactors = NULL;
-          if (ec)
-            {
-              for (i=0; i < 5; i++)
-                {
-                  gcry_mpi_release (skey[i]);
-                  skey[i] = NULL;
-                }
-            }
-        }
-    }
-
-  gcry_sexp_release (seedinfo);
-  return ec;
-}
-
-
-static gcry_err_code_t
-dsa_generate (int algo, unsigned int nbits, unsigned long evalue,
-              gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-{
-  (void)evalue;
-  return dsa_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
-}
-
-
-
-static gcry_err_code_t
-dsa_check_secret_key (int algo, gcry_mpi_t *skey)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  DSA_secret_key sk;
-
-  (void)algo;
-
-  if ((! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]) || (! skey[4]))
-    err = GPG_ERR_BAD_MPI;
-  else
-    {
-      sk.p = skey[0];
-      sk.q = skey[1];
-      sk.g = skey[2];
-      sk.y = skey[3];
-      sk.x = skey[4];
-      if (! check_secret_key (&sk))
-       err = GPG_ERR_BAD_SECKEY;
-    }
-
-  return err;
-}
-
-
-static gcry_err_code_t
-dsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  DSA_secret_key sk;
-
-  (void)algo;
-
-  if ((! data)
-      || (! skey[0]) || (! skey[1]) || (! skey[2])
-      || (! skey[3]) || (! skey[4]))
-    err = GPG_ERR_BAD_MPI;
-  else
-    {
-      sk.p = skey[0];
-      sk.q = skey[1];
-      sk.g = skey[2];
-      sk.y = skey[3];
-      sk.x = skey[4];
-      resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p));
-      resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
-      sign (resarr[0], resarr[1], data, &sk);
-    }
-  return err;
-}
-
-static gcry_err_code_t
-dsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
-            int (*cmp) (void *, gcry_mpi_t), void *opaquev)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  DSA_public_key pk;
-
-  (void)algo;
-  (void)cmp;
-  (void)opaquev;
-
-  if ((! data[0]) || (! data[1]) || (! hash)
-      || (! pkey[0]) || (! pkey[1]) || (! pkey[2]) || (! pkey[3]))
-    err = GPG_ERR_BAD_MPI;
-  else
-    {
-      pk.p = pkey[0];
-      pk.q = pkey[1];
-      pk.g = pkey[2];
-      pk.y = pkey[3];
-      if (! verify (data[0], data[1], hash, &pk))
-       err = GPG_ERR_BAD_SIGNATURE;
-    }
-  return err;
-}
-
-
-static unsigned int
-dsa_get_nbits (int algo, gcry_mpi_t *pkey)
-{
-  (void)algo;
-
-  return mpi_get_nbits (pkey[0]);
-}
-
-
-\f
-/* 
-     Self-test section.
- */
-
-static const char *
-selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
-{
-  static const char sample_data[] = 
-    "(data (flags pkcs1)"
-    " (hash sha1 #a0b1c2d3e4f500102030405060708090a1b2c3d4#))";
-  static const char sample_data_bad[] = 
-    "(data (flags pkcs1)"
-    " (hash sha1 #a0b1c2d3e4f510102030405060708090a1b2c3d4#))";
-
-  const char *errtxt = NULL;
-  gcry_error_t err;
-  gcry_sexp_t data = NULL;
-  gcry_sexp_t data_bad = NULL;
-  gcry_sexp_t sig = NULL;
-
-  err = gcry_sexp_sscan (&data, NULL,
-                         sample_data, strlen (sample_data));
-  if (!err)
-    err = gcry_sexp_sscan (&data_bad, NULL, 
-                           sample_data_bad, strlen (sample_data_bad));
-  if (err)
-    {
-      errtxt = "converting data failed";
-      goto leave;
-    }
-
-  err = gcry_pk_sign (&sig, data, skey);
-  if (err)
-    {
-      errtxt = "signing failed";
-      goto leave;
-    }
-  err = gcry_pk_verify (sig, data, pkey);
-  if (err)
-    {
-      errtxt = "verify failed";
-      goto leave;
-    }
-  err = gcry_pk_verify (sig, data_bad, pkey);
-  if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
-    {
-      errtxt = "bad signature not detected";
-      goto leave;
-    }
-
-
- leave:
-  gcry_sexp_release (sig);
-  gcry_sexp_release (data_bad);
-  gcry_sexp_release (data);
-  return errtxt;
-}
-
-
-static gpg_err_code_t
-selftests_dsa (selftest_report_func_t report)
-{
-  const char *what;
-  const char *errtxt;
-  gcry_error_t err;
-  gcry_sexp_t skey = NULL;
-  gcry_sexp_t pkey = NULL;
-
-  /* Convert the S-expressions into the internal representation.  */
-  what = "convert";
-  err = gcry_sexp_sscan (&skey, NULL, 
-                         sample_secret_key, strlen (sample_secret_key));
-  if (!err)
-    err = gcry_sexp_sscan (&pkey, NULL, 
-                           sample_public_key, strlen (sample_public_key));
-  if (err)
-    {
-      errtxt = gcry_strerror (err);
-      goto failed;
-    }
-
-  what = "key consistency";
-  err = gcry_pk_testkey (skey);
-  if (err)
-    {
-      errtxt = gcry_strerror (err);
-      goto failed;
-    }
-
-  what = "sign";
-  errtxt = selftest_sign_1024 (pkey, skey);
-  if (errtxt)
-    goto failed;
-
-  gcry_sexp_release (pkey);
-  gcry_sexp_release (skey);
-  return 0; /* Succeeded. */
-
- failed:
-  gcry_sexp_release (pkey);
-  gcry_sexp_release (skey);
-  if (report)
-    report ("pubkey", GCRY_PK_DSA, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-
-/* Run a full self-test for ALGO and return 0 on success.  */
-static gpg_err_code_t
-run_selftests (int algo, int extended, selftest_report_func_t report)
-{
-  gpg_err_code_t ec;
-
-  (void)extended;
-
-  switch (algo)
-    {
-    case GCRY_PK_DSA:
-      ec = selftests_dsa (report);
-      break;
-    default:
-      ec = GPG_ERR_PUBKEY_ALGO;
-      break;
-        
-    }
-  return ec;
-}
-
-
-
-\f
-static const char *dsa_names[] =
-  {
-    "dsa",
-    "openpgp-dsa",
-    NULL,
-  };
-
-gcry_pk_spec_t _gcry_pubkey_spec_dsa =
-  {
-    "DSA", dsa_names, 
-    "pqgy", "pqgyx", "", "rs", "pqgy",
-    GCRY_PK_USAGE_SIGN,
-    dsa_generate,
-    dsa_check_secret_key,
-    NULL,
-    NULL,
-    dsa_sign,
-    dsa_verify,
-    dsa_get_nbits
-  };
-pk_extra_spec_t _gcry_pubkey_extraspec_dsa = 
-  {
-    run_selftests,
-    dsa_generate_ext
-  };
-
diff --git a/lib/libgcrypt/cipher/ecc.c b/lib/libgcrypt/cipher/ecc.c
deleted file mode 100644 (file)
index fcbd8e3..0000000
+++ /dev/null
@@ -1,1390 +0,0 @@
-/* ecc.c  -  Elliptic Curve Cryptography
-   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
-
-   This file is part of Libgcrypt.
-  
-   Libgcrypt is free software; you can redistribute it and/or modify
-   it under the terms of the GNU Lesser General Public License as
-   published by the Free Software Foundation; either version 2.1 of
-   the License, or (at your option) any later version.
-  
-   Libgcrypt 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 Lesser General Public License for more details.
-  
-   You should have received a copy of the GNU Lesser General Public
-   License along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-   USA.  */
-
-/* This code is originally based on the Patch 0.1.6 for the gnupg
-   1.4.x branch as retrieved on 2007-03-21 from
-   http://www.calcurco.cat/eccGnuPG/src/gnupg-1.4.6-ecc0.2.0beta1.diff.bz2
-   The original authors are:
-     Written by
-      Sergi Blanch i Torne <d4372211 at alumnes.eup.udl.es>,
-      Ramiro Moreno Chiral <ramiro at eup.udl.es>
-     Maintainers
-      Sergi Blanch i Torne
-      Ramiro Moreno Chiral
-      Mikael Mylnikov (mmr)
-  For use in Libgcrypt the code has been heavily modified and cleaned
-  up. In fact there is not much left of the orginally code except for
-  some variable names and the text book implementaion of the sign and
-  verification algorithms.  The arithmetic functions have entirely
-  been rewritten and moved to mpi/ec.c.  */
-
-
-/* TODO:
-
-  - If we support point compression we need to decide how to compute
-    the keygrip - it should not change due to compression.
-
-  - In mpi/ec.c we use mpi_powm for x^2 mod p: Either implement a
-    special case in mpi_powm or check whether mpi_mulm is faster.
-
-  - Decide whether we should hide the mpi_point_t definition.
-
-  - Support more than just ECDSA.
-*/
-
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "g10lib.h"
-#include "mpi.h"
-#include "cipher.h"
-
-
-/* Definition of a curve.  */
-typedef struct
-{
-  gcry_mpi_t p;   /* Prime specifying the field GF(p).  */
-  gcry_mpi_t a;   /* First coefficient of the Weierstrass equation.  */
-  gcry_mpi_t b;   /* Second coefficient of the Weierstrass equation.  */
-  mpi_point_t G;  /* Base point (generator).  */
-  gcry_mpi_t n;   /* Order of G.  */
-} elliptic_curve_t; 
-
-
-typedef struct
-{
-  elliptic_curve_t E;
-  mpi_point_t Q;  /* Q = [d]G  */
-} ECC_public_key;
-
-typedef struct
-{
-  elliptic_curve_t E;
-  mpi_point_t Q;
-  gcry_mpi_t d;
-} ECC_secret_key;
-
-
-/* This tables defines aliases for curve names.  */
-static const struct
-{
-  const char *name;  /* Our name.  */
-  const char *other; /* Other name. */
-} curve_aliases[] = 
-  {
-    { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID  */
-    { "NIST P-192", "prime192v1" },          /* X9.62 name.  */
-    { "NIST P-192", "secp192r1"  },          /* SECP name.  */
-
-    { "NIST P-224", "secp224r1" },
-    { "NIST P-224", "1.3.132.0.33" },        /* SECP OID.  */
-
-    { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1.  */
-    { "NIST P-256", "prime256v1" },          
-    { "NIST P-256", "secp256r1"  },
-
-    { "NIST P-384", "secp384r1" },
-    { "NIST P-384", "1.3.132.0.34" },       
-
-    { "NIST P-521", "secp521r1" },
-    { "NIST P-521", "1.3.132.0.35" },
-
-    { "brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1" },
-    { "brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3" },
-    { "brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5" },
-    { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7" },
-    { "brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9" },
-    { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11"},
-    { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13"},
-
-    { NULL, NULL}
-  };
-
-
-
-/* This static table defines all available curves.  */
-static const struct
-{
-  const char *desc;           /* Description of the curve.  */
-  unsigned int nbits;         /* Number of bits.  */
-  unsigned int fips:1;        /* True if this is a FIPS140-2 approved curve. */
-  const char  *p;             /* Order of the prime field.  */
-  const char *a, *b;          /* The coefficients. */
-  const char *n;              /* The order of the base point.  */
-  const char *g_x, *g_y;      /* Base point.  */
-} domain_parms[] =
-  {
-    {
-      "NIST P-192", 192, 1,
-      "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
-      "0xfffffffffffffffffffffffffffffffefffffffffffffffc",
-      "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
-      "0xffffffffffffffffffffffff99def836146bc9b1b4d22831",
-
-      "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
-      "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811"
-    },
-    {
-      "NIST P-224", 224, 1,
-      "0xffffffffffffffffffffffffffffffff000000000000000000000001",
-      "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe",
-      "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
-      "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
-
-      "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
-      "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"
-    },
-    {
-      "NIST P-256", 256, 1,
-      "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
-      "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
-      "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
-      "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
-
-      "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
-      "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
-    },
-    {
-      "NIST P-384", 384, 1,
-      "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
-      "ffffffff0000000000000000ffffffff",
-      "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
-      "ffffffff0000000000000000fffffffc",
-      "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a"
-      "c656398d8a2ed19d2a85c8edd3ec2aef",
-      "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf"
-      "581a0db248b0a77aecec196accc52973",
-
-      "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38"
-      "5502f25dbf55296c3a545e3872760ab7",
-      "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0"
-      "0a60b1ce1d7e819d7a431d7c90ea0e5f"
-    },
-    {
-      "NIST P-521", 521, 1,
-      "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-      "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
-      "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-      "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
-      "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10"
-      "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
-      "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-      "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
-
-      "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d"
-      "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
-      "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6"
-      "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650"
-    },
-
-    { "brainpoolP160r1", 160, 0, 
-      "0xe95e4a5f737059dc60dfc7ad95b3d8139515620f",
-      "0x340e7be2a280eb74e2be61bada745d97e8f7c300",
-      "0x1e589a8595423412134faa2dbdec95c8d8675e58",
-      "0xe95e4a5f737059dc60df5991d45029409e60fc09",
-      "0xbed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3",
-      "0x1667cb477a1a8ec338f94741669c976316da6321"
-    },
-
-    { "brainpoolP192r1", 192, 0, 
-      "0xc302f41d932a36cda7a3463093d18db78fce476de1a86297",
-      "0x6a91174076b1e0e19c39c031fe8685c1cae040e5c69a28ef",
-      "0x469a28ef7c28cca3dc721d044f4496bcca7ef4146fbf25c9",
-      "0xc302f41d932a36cda7a3462f9e9e916b5be8f1029ac4acc1",
-      "0xc0a0647eaab6a48753b033c56cb0f0900a2f5c4853375fd6",
-      "0x14b690866abd5bb88b5f4828c1490002e6773fa2fa299b8f"
-    },
-
-    { "brainpoolP224r1", 224, 0,
-      "0xd7c134aa264366862a18302575d1d787b09f075797da89f57ec8c0ff",
-      "0x68a5e62ca9ce6c1c299803a6c1530b514e182ad8b0042a59cad29f43",
-      "0x2580f63ccfe44138870713b1a92369e33e2135d266dbb372386c400b",
-      "0xd7c134aa264366862a18302575d0fb98d116bc4b6ddebca3a5a7939f",
-      "0x0d9029ad2c7e5cf4340823b2a87dc68c9e4ce3174c1e6efdee12c07d",
-      "0x58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd"
-    },
-
-    { "brainpoolP256r1", 256, 0,
-      "0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377",
-      "0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9",
-      "0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6",
-      "0xa9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7",
-      "0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262",
-      "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997"
-    },
-
-    { "brainpoolP320r1", 320, 0,
-      "0xd35e472036bc4fb7e13c785ed201e065f98fcfa6f6f40def4f92b9ec7893ec28"
-      "fcd412b1f1b32e27",
-      "0x3ee30b568fbab0f883ccebd46d3f3bb8a2a73513f5eb79da66190eb085ffa9f4"
-      "92f375a97d860eb4",
-      "0x520883949dfdbc42d3ad198640688a6fe13f41349554b49acc31dccd88453981"
-      "6f5eb4ac8fb1f1a6",
-      "0xd35e472036bc4fb7e13c785ed201e065f98fcfa5b68f12a32d482ec7ee8658e9"
-      "8691555b44c59311",
-      "0x43bd7e9afb53d8b85289bcc48ee5bfe6f20137d10a087eb6e7871e2a10a599c7"
-      "10af8d0d39e20611",
-      "0x14fdd05545ec1cc8ab4093247f77275e0743ffed117182eaa9c77877aaac6ac7"
-      "d35245d1692e8ee1"
-    },
-
-    { "brainpoolP384r1", 384, 0,
-      "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123"
-      "acd3a729901d1a71874700133107ec53",
-      "0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f"
-      "8aa5814a503ad4eb04a8c7dd22ce2826",
-      "0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d5"
-      "7cb4390295dbc9943ab78696fa504c11",
-      "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b31f166e6cac0425a7"
-      "cf3ab6af6b7fc3103b883202e9046565",
-      "0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8"
-      "e826e03436d646aaef87b2e247d4af1e",
-      "0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff9912928"
-      "0e4646217791811142820341263c5315"
-    },
-
-    { "brainpoolP512r1", 512, 0,
-      "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330871"
-      "7d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3",
-      "0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc"
-      "2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca",
-      "0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a7"
-      "2bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723",
-      "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330870"
-      "553e5c414ca92619418661197fac10471db1d381085ddaddb58796829ca90069",
-      "0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098e"
-      "ff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822",
-      "0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111"
-      "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892"
-    },
-
-    { NULL, 0, 0, NULL, NULL, NULL, NULL }
-  };
-
-
-/* Registered progress function and its callback value. */
-static void (*progress_cb) (void *, const char*, int, int, int);
-static void *progress_cb_data;
-
-
-#define point_init(a)  _gcry_mpi_ec_point_init ((a))
-#define point_free(a)  _gcry_mpi_ec_point_free ((a))
-
-
-\f
-/* Local prototypes. */
-static gcry_mpi_t gen_k (gcry_mpi_t p, int security_level);
-static void test_keys (ECC_secret_key * sk, unsigned int nbits);
-static int check_secret_key (ECC_secret_key * sk);
-static gpg_err_code_t sign (gcry_mpi_t input, ECC_secret_key *skey,
-                            gcry_mpi_t r, gcry_mpi_t s);
-static gpg_err_code_t verify (gcry_mpi_t input, ECC_public_key *pkey,
-                              gcry_mpi_t r, gcry_mpi_t s);
-
-
-static gcry_mpi_t gen_y_2 (gcry_mpi_t x, elliptic_curve_t * base);
-
-
-
-\f
-void
-_gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
-                                            int, int, int),
-                                void *cb_data)
-{
-  progress_cb = cb;
-  progress_cb_data = cb_data;
-}
-
-/* static void */
-/* progress (int c) */
-/* { */
-/*   if (progress_cb) */
-/*     progress_cb (progress_cb_data, "pk_ecc", c, 0, 0); */
-/* } */
-
-
-\f
-
-/* Set the value from S into D.  */
-static void
-point_set (mpi_point_t *d, mpi_point_t *s)
-{
-  mpi_set (d->x, s->x);
-  mpi_set (d->y, s->y);
-  mpi_set (d->z, s->z);
-}
-
-
-/*
- * Release a curve object.
- */
-static void
-curve_free (elliptic_curve_t *E)
-{
-  mpi_free (E->p); E->p = NULL;
-  mpi_free (E->a); E->a = NULL;
-  mpi_free (E->b);  E->b = NULL;
-  point_free (&E->G);
-  mpi_free (E->n);  E->n = NULL;
-}
-
-
-/*
- * Return a copy of a curve object.
- */
-static elliptic_curve_t
-curve_copy (elliptic_curve_t E)
-{
-  elliptic_curve_t R;
-
-  R.p = mpi_copy (E.p);
-  R.a = mpi_copy (E.a);
-  R.b = mpi_copy (E.b);
-  point_init (&R.G);
-  point_set (&R.G, &E.G);
-  R.n = mpi_copy (E.n);
-
-  return R;
-}
-
-
-
-/* Helper to scan a hex string. */
-static gcry_mpi_t
-scanval (const char *string)
-{
-  gpg_error_t err;
-  gcry_mpi_t val;
-
-  err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
-  if (err)
-    log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (err));
-  return val;
-}
-
-
-
-\f
-
-/****************
- * Solve the right side of the equation that defines a curve.
- */
-static gcry_mpi_t
-gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base)
-{
-  gcry_mpi_t three, x_3, axb, y;
-
-  three = mpi_alloc_set_ui (3);
-  x_3 = mpi_new (0);
-  axb = mpi_new (0);
-  y   = mpi_new (0);
-
-  mpi_powm (x_3, x, three, base->p);  
-  mpi_mulm (axb, base->a, x, base->p); 
-  mpi_addm (axb, axb, base->b, base->p);     
-  mpi_addm (y, x_3, axb, base->p);    
-
-  mpi_free (x_3);
-  mpi_free (axb);
-  mpi_free (three);
-  return y; /* The quadratic value of the coordinate if it exist. */
-}
-
-
-
-
-
-/* Generate a random secret scalar k with an order of p
-
-   At the beginning this was identical to the code is in elgamal.c.
-   Later imporved by mmr.   Further simplified by wk.  */
-static gcry_mpi_t
-gen_k (gcry_mpi_t p, int security_level)
-{
-  gcry_mpi_t k;
-  unsigned int nbits;
-
-  nbits = mpi_get_nbits (p);
-  k = mpi_snew (nbits);
-  if (DBG_CIPHER)
-    log_debug ("choosing a random k of %u bits\n", nbits);
-
-  gcry_mpi_randomize (k, nbits, security_level);
-
-  mpi_mod (k, k, p);  /*  k = k mod p  */
-
-  return k;
-}
-
-/****************
- * Generate the crypto system setup.
- * As of now the fix NIST recommended values are used.
- * The subgroup generator point is in another function: gen_big_point.
- */
-static gpg_err_code_t
-generate_curve (unsigned int nbits, const char *name, 
-                elliptic_curve_t *curve, unsigned int *r_nbits)
-{
-  int idx, aliasno;
-
-  if (name)
-    {
-      /* First check nor native curves.  */
-      for (idx = 0; domain_parms[idx].desc; idx++)
-        if (!strcmp (name, domain_parms[idx].desc))
-          break;
-      /* If not found consult the alias table.  */
-      if (!domain_parms[idx].desc)
-        {
-          for (aliasno = 0; curve_aliases[aliasno].name; aliasno++)
-            if (!strcmp (name, curve_aliases[aliasno].other))
-              break;
-          if (curve_aliases[aliasno].name)
-            {
-              for (idx = 0; domain_parms[idx].desc; idx++)
-                if (!strcmp (curve_aliases[aliasno].name,
-                             domain_parms[idx].desc))
-                  break;
-            }
-        }
-    }
-  else
-    {
-      for (idx = 0; domain_parms[idx].desc; idx++)
-        if (nbits == domain_parms[idx].nbits)
-          break;
-    }
-  if (!domain_parms[idx].desc)
-    return GPG_ERR_INV_VALUE;
-
-  /* In fips mode we only support NIST curves.  Note that it is
-     possible to bypass this check by specifying the curve parameters
-     directly.  */
-  if (fips_mode () && !domain_parms[idx].fips )
-    return GPG_ERR_NOT_SUPPORTED; 
-  
-
-  *r_nbits = domain_parms[idx].nbits;
-  curve->p = scanval (domain_parms[idx].p);
-  curve->a = scanval (domain_parms[idx].a);
-  curve->b = scanval (domain_parms[idx].b);
-  curve->n = scanval (domain_parms[idx].n);
-  curve->G.x = scanval (domain_parms[idx].g_x);
-  curve->G.y = scanval (domain_parms[idx].g_y);
-  curve->G.z = mpi_alloc_set_ui (1);
-
-  return 0;
-}
-
-
-/*
- * First obtain the setup.  Over the finite field randomize an scalar
- * secret value, and calculate the public point.
- */
-static gpg_err_code_t
-generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
-              gcry_mpi_t g_x, gcry_mpi_t g_y,
-              gcry_mpi_t q_x, gcry_mpi_t q_y)
-{
-  gpg_err_code_t err;
-  elliptic_curve_t E;
-  gcry_mpi_t d;
-  mpi_point_t Q;
-  mpi_ec_t ctx;
-
-  err = generate_curve (nbits, name, &E, &nbits);
-  if (err)
-    return err;
-
-  if (DBG_CIPHER)
-    {
-      log_mpidump ("ecc generation   p", E.p);
-      log_mpidump ("ecc generation   a", E.a);
-      log_mpidump ("ecc generation   b", E.b);
-      log_mpidump ("ecc generation   n", E.n);
-      log_mpidump ("ecc generation  Gx", E.G.x);
-      log_mpidump ("ecc generation  Gy", E.G.y);
-      log_mpidump ("ecc generation  Gz", E.G.z);
-    }
-
-  if (DBG_CIPHER)
-    log_debug ("choosing a random x of size %u\n", nbits);
-  d = gen_k (E.n, GCRY_VERY_STRONG_RANDOM); 
-
-  /* Compute Q.  */
-  point_init (&Q);
-  ctx = _gcry_mpi_ec_init (E.p, E.a);
-  _gcry_mpi_ec_mul_point (&Q, d, &E.G, ctx);
-
-  /* Copy the stuff to the key structures. */
-  sk->E.p = mpi_copy (E.p);
-  sk->E.a = mpi_copy (E.a);
-  sk->E.b = mpi_copy (E.b);
-  point_init (&sk->E.G);
-  point_set (&sk->E.G, &E.G);
-  sk->E.n = mpi_copy (E.n);
-  point_init (&sk->Q);
-  point_set (&sk->Q, &Q);
-  sk->d    = mpi_copy (d);
-  /* We also return copies of G and Q in affine coordinates if
-     requested.  */
-  if (g_x && g_y)
-    {
-      if (_gcry_mpi_ec_get_affine (g_x, g_y, &sk->E.G, ctx))
-        log_fatal ("ecc generate: Failed to get affine coordinates\n");
-    }
-  if (q_x && q_y)
-    {
-      if (_gcry_mpi_ec_get_affine (q_x, q_y, &sk->Q, ctx))
-        log_fatal ("ecc generate: Failed to get affine coordinates\n");
-    }
-  _gcry_mpi_ec_free (ctx);
-
-  point_free (&Q);
-  mpi_free (d);
-  curve_free (&E);
-
-  /* Now we can test our keys (this should never fail!). */
-  test_keys (sk, nbits - 64);
-
-  return 0;
-}
-
-
-/****************
- * To verify correct skey it use a random information.
- * First, encrypt and decrypt this dummy value,
- * test if the information is recuperated.
- * Second, test with the sign and verify functions.
- */
-static void
-test_keys (ECC_secret_key *sk, unsigned int nbits)
-{
-  ECC_public_key pk;
-  gcry_mpi_t test = mpi_new (nbits);
-  mpi_point_t R_;
-  gcry_mpi_t c = mpi_new (nbits);
-  gcry_mpi_t out = mpi_new (nbits);
-  gcry_mpi_t r = mpi_new (nbits);
-  gcry_mpi_t s = mpi_new (nbits);
-
-  if (DBG_CIPHER)
-    log_debug ("Testing key.\n");
-
-  point_init (&R_);
-
-  pk.E = curve_copy (sk->E);
-  point_init (&pk.Q);
-  point_set (&pk.Q, &sk->Q);
-
-  gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
-
-  if (sign (test, sk, r, s) )
-    log_fatal ("ECDSA operation: sign failed\n");
-
-  if (verify (test, &pk, r, s))
-    {
-      log_fatal ("ECDSA operation: sign, verify failed\n");
-    }
-
-  if (DBG_CIPHER)
-    log_debug ("ECDSA operation: sign, verify ok.\n");
-
-  point_free (&pk.Q);
-  curve_free (&pk.E);
-
-  point_free (&R_);
-  mpi_free (s);
-  mpi_free (r);
-  mpi_free (out);
-  mpi_free (c);
-  mpi_free (test);
-}
-
-/****************
- * To check the validity of the value, recalculate the correspondence
- * between the public value and the secret one.
- */
-static int
-check_secret_key (ECC_secret_key * sk)
-{
-  mpi_point_t Q;
-  gcry_mpi_t y_2, y2 = mpi_alloc (0);
-  mpi_ec_t ctx;
-
-  /* ?primarity test of 'p' */
-  /*  (...) //!! */
-  /* G in E(F_p) */
-  y_2 = gen_y_2 (sk->E.G.x, &sk->E);   /*  y^2=x^3+a*x+b */
-  mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p);      /*  y^2=y*y */
-  if (mpi_cmp (y_2, y2))
-    {
-      if (DBG_CIPHER)
-        log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
-      return (1);
-    }
-  /* G != PaI */
-  if (!mpi_cmp_ui (sk->E.G.z, 0))
-    {
-      if (DBG_CIPHER)
-        log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
-      return (1);
-    }
-
-  point_init (&Q);
-  ctx = _gcry_mpi_ec_init (sk->E.p, sk->E.a);
-  _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx);
-  if (mpi_cmp_ui (Q.z, 0))
-    {
-      if (DBG_CIPHER)
-        log_debug ("check_secret_key: E is not a curve of order n\n");
-      point_free (&Q);
-      _gcry_mpi_ec_free (ctx);
-      return 1;
-    }
-  /* pubkey cannot be PaI */
-  if (!mpi_cmp_ui (sk->Q.z, 0))
-    {
-      if (DBG_CIPHER)
-        log_debug ("Bad check: Q can not be a Point at Infinity!\n");
-      _gcry_mpi_ec_free (ctx);
-      return (1);
-    }
-  /* pubkey = [d]G over E */
-  _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx);
-  if ((Q.x == sk->Q.x) && (Q.y == sk->Q.y) && (Q.z == sk->Q.z))
-    {
-      if (DBG_CIPHER)
-        log_debug
-          ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
-      _gcry_mpi_ec_free (ctx);
-      return (1);
-    }
-  _gcry_mpi_ec_free (ctx);
-  point_free (&Q);
-  return 0;
-}
-
-
-/*
- * Return the signature struct (r,s) from the message hash.  The caller
- * must have allocated R and S.
- */
-static gpg_err_code_t
-sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s)
-{
-  gpg_err_code_t err = 0;
-  gcry_mpi_t k, dr, sum, k_1, x;
-  mpi_point_t I;
-  mpi_ec_t ctx;
-
-  k = NULL;
-  dr = mpi_alloc (0);
-  sum = mpi_alloc (0);
-  k_1 = mpi_alloc (0);
-  x = mpi_alloc (0);
-  point_init (&I);
-
-  mpi_set_ui (s, 0);
-  mpi_set_ui (r, 0);
-
-  ctx = _gcry_mpi_ec_init (skey->E.p, skey->E.a);
-
-  while (!mpi_cmp_ui (s, 0)) /* s == 0 */
-    {
-      while (!mpi_cmp_ui (r, 0)) /* r == 0 */
-        {
-          /* Note, that we are guaranteed to enter this loop at least
-             once because r has been intialized to 0.  We can't use a
-             do_while because we want to keep the value of R even if S
-             has to be recomputed.  */
-          mpi_free (k);
-          k = gen_k (skey->E.n, GCRY_STRONG_RANDOM);
-          _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx); 
-          if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx))
-            {
-              if (DBG_CIPHER)
-                log_debug ("ecc sign: Failed to get affine coordinates\n");
-              err = GPG_ERR_BAD_SIGNATURE;
-              goto leave;
-            }
-          mpi_mod (r, x, skey->E.n);  /* r = x mod n */
-        }
-      mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n  */
-      mpi_addm (sum, input, dr, skey->E.n); /* sum = hash + (d*r) mod n  */
-      mpi_invm (k_1, k, skey->E.n);         /* k_1 = k^(-1) mod n  */
-      mpi_mulm (s, k_1, sum, skey->E.n);    /* s = k^(-1)*(hash+(d*r)) mod n */
-    }
-
- leave:
-  _gcry_mpi_ec_free (ctx);
-  point_free (&I);
-  mpi_free (x);
-  mpi_free (k_1);
-  mpi_free (sum);
-  mpi_free (dr);
-  mpi_free (k);
-
-  return err;
-}
-
-/*
- * Check if R and S verifies INPUT.
- */
-static gpg_err_code_t
-verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s)
-{
-  gpg_err_code_t err = 0;
-  gcry_mpi_t h, h1, h2, x, y;
-  mpi_point_t Q, Q1, Q2;
-  mpi_ec_t ctx;
-
-  if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) )
-    return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n  failed.  */
-  if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) )
-    return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n  failed.  */
-
-  h  = mpi_alloc (0);
-  h1 = mpi_alloc (0);
-  h2 = mpi_alloc (0);
-  x = mpi_alloc (0);
-  y = mpi_alloc (0);
-  point_init (&Q);
-  point_init (&Q1);
-  point_init (&Q2);
-
-  ctx = _gcry_mpi_ec_init (pkey->E.p, pkey->E.a);
-
-  /* h  = s^(-1) (mod n) */
-  mpi_invm (h, s, pkey->E.n);
-/*   log_mpidump ("   h", h); */
-  /* h1 = hash * s^(-1) (mod n) */
-  mpi_mulm (h1, input, h, pkey->E.n);
-/*   log_mpidump ("  h1", h1); */
-  /* Q1 = [ hash * s^(-1) ]G  */
-  _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx);
-/*   log_mpidump ("Q1.x", Q1.x); */
-/*   log_mpidump ("Q1.y", Q1.y); */
-/*   log_mpidump ("Q1.z", Q1.z); */
-  /* h2 = r * s^(-1) (mod n) */
-  mpi_mulm (h2, r, h, pkey->E.n);
-/*   log_mpidump ("  h2", h2); */
-  /* Q2 = [ r * s^(-1) ]Q */
-  _gcry_mpi_ec_mul_point (&Q2, h2, &pkey->Q, ctx);
-/*   log_mpidump ("Q2.x", Q2.x); */
-/*   log_mpidump ("Q2.y", Q2.y); */
-/*   log_mpidump ("Q2.z", Q2.z); */
-  /* Q  = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */
-  _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx);
-/*   log_mpidump (" Q.x", Q.x); */
-/*   log_mpidump (" Q.y", Q.y); */
-/*   log_mpidump (" Q.z", Q.z); */
-
-  if (!mpi_cmp_ui (Q.z, 0))
-    {
-      if (DBG_CIPHER)
-          log_debug ("ecc verify: Rejected\n");
-      err = GPG_ERR_BAD_SIGNATURE;
-      goto leave;
-    }
-  if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx))
-    {
-      if (DBG_CIPHER)
-        log_debug ("ecc verify: Failed to get affine coordinates\n");
-      err = GPG_ERR_BAD_SIGNATURE;
-      goto leave;
-    }
-  mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */
-  if (mpi_cmp (x, r))   /* x != r */
-    {
-      if (DBG_CIPHER)
-        {
-          log_mpidump ("   x", x);
-          log_mpidump ("   y", y);
-          log_mpidump ("   r", r);
-          log_mpidump ("   s", s);
-          log_debug ("ecc verify: Not verified\n");
-        }
-      err = GPG_ERR_BAD_SIGNATURE;
-      goto leave;
-    }
-  if (DBG_CIPHER)
-    log_debug ("ecc verify: Accepted\n");
-
- leave:
-  _gcry_mpi_ec_free (ctx);
-  point_free (&Q2);
-  point_free (&Q1);
-  point_free (&Q);
-  mpi_free (y);
-  mpi_free (x);
-  mpi_free (h2);
-  mpi_free (h1);
-  mpi_free (h);
-  return err;
-}
-
-
-
-/*********************************************
- **************  interface  ******************
- *********************************************/
-static gcry_mpi_t
-ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p)
-{
-  gpg_error_t err;
-  int pbytes = (mpi_get_nbits (p)+7)/8;
-  size_t n;
-  unsigned char *buf, *ptr;
-  gcry_mpi_t result;
-
-  buf = gcry_xmalloc ( 1 + 2*pbytes );
-  *buf = 04; /* Uncompressed point.  */
-  ptr = buf+1;
-  err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, x);
-  if (err)
-    log_fatal ("mpi_print failed: %s\n", gpg_strerror (err));
-  if (n < pbytes)
-    {
-      memmove (ptr+(pbytes-n), ptr, n);
-      memset (ptr, 0, (pbytes-n));
-    }
-  ptr += pbytes;
-  err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, y);
-  if (err)
-    log_fatal ("mpi_print failed: %s\n", gpg_strerror (err));
-  if (n < pbytes)
-    {
-      memmove (ptr+(pbytes-n), ptr, n);
-      memset (ptr, 0, (pbytes-n));
-    }
-  
-  err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, buf, 1+2*pbytes, NULL);
-  if (err)
-    log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err));
-  gcry_free (buf);
-
-  mpi_free (x);
-  mpi_free (y);
-
-  return result;
-}
-
-/* RESULT must have been initialized and is set on success to the
-   point given by VALUE.  */
-static gcry_error_t
-os2ec (mpi_point_t *result, gcry_mpi_t value)
-{
-  gcry_error_t err;
-  size_t n;
-  unsigned char *buf;
-  gcry_mpi_t x, y;
-
-  n = (mpi_get_nbits (value)+7)/8;
-  buf = gcry_xmalloc (n);
-  err = gcry_mpi_print (GCRYMPI_FMT_USG, buf, n, &n, value);
-  if (err)
-    {
-      gcry_free (buf);
-      return err;
-    }
-  if (n < 1) 
-    {
-      gcry_free (buf);
-      return GPG_ERR_INV_OBJ;
-    }
-  if (*buf != 4)
-    {
-      gcry_free (buf);
-      return GPG_ERR_NOT_IMPLEMENTED; /* No support for point compression.  */
-    }
-  if ( ((n-1)%2) ) 
-    {
-      gcry_free (buf);
-      return GPG_ERR_INV_OBJ;
-    }
-  n = (n-1)/2;
-  err = gcry_mpi_scan (&x, GCRYMPI_FMT_USG, buf+1, n, NULL);
-  if (err)
-    {
-      gcry_free (buf);
-      return err;
-    }
-  err = gcry_mpi_scan (&y, GCRYMPI_FMT_USG, buf+1+n, n, NULL);
-  gcry_free (buf);
-  if (err)
-    {
-      mpi_free (x);
-      return err;
-    }
-
-  mpi_set (result->x, x);
-  mpi_set (result->y, y);
-  mpi_set_ui (result->z, 1);
-
-  mpi_free (x);
-  mpi_free (y);
-  
-  return 0;
-}
-
-
-/* Extended version of ecc_generate.  */
-static gcry_err_code_t
-ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
-                  const gcry_sexp_t genparms,
-                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
-                  gcry_sexp_t *r_extrainfo)
-{
-  gpg_err_code_t ec;
-  ECC_secret_key sk;
-  gcry_mpi_t g_x, g_y, q_x, q_y;
-  char *curve_name = NULL;
-  gcry_sexp_t l1;
-
-  (void)algo;
-  (void)evalue;
-  (void)r_extrainfo;
-
-  if (genparms)
-    {
-      /* Parse the optional "curve" parameter. */
-      l1 = gcry_sexp_find_token (genparms, "curve", 0);
-      if (l1)
-        {
-          curve_name = _gcry_sexp_nth_string (l1, 1);
-          gcry_sexp_release (l1);
-          if (!curve_name)
-            return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
-        }
-    }
-
-  /* NBITS is required if no curve name has been given.  */
-  if (!nbits && !curve_name)
-    return GPG_ERR_NO_OBJ; /* No NBITS parameter. */
-
-  g_x = mpi_new (0);
-  g_y = mpi_new (0);
-  q_x = mpi_new (0);
-  q_y = mpi_new (0);
-  ec = generate_key (&sk, nbits, curve_name, g_x, g_y, q_x, q_y);
-  gcry_free (curve_name);
-  if (ec)
-    return ec;
-
-  skey[0] = sk.E.p;
-  skey[1] = sk.E.a;
-  skey[2] = sk.E.b;
-  /* The function ec2os releases g_x and g_y.  */
-  skey[3] = ec2os (g_x, g_y, sk.E.p);
-  skey[4] = sk.E.n;
-  /* The function ec2os releases g_x and g_y.  */
-  skey[5] = ec2os (q_x, q_y, sk.E.p);
-  skey[6] = sk.d;
-
-  point_free (&sk.E.G);
-  point_free (&sk.Q);
-
-  /* Make an empty list of factors.  */
-  *retfactors = gcry_calloc ( 1, sizeof **retfactors );
-  if (!*retfactors)
-    return gpg_err_code_from_syserror ();
-
-  return 0;
-}
-
-
-static gcry_err_code_t
-ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
-              gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-{
-  (void)evalue;
-  return ecc_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
-}
-
-
-/* Return the parameters of the curve NAME.  */
-static gcry_err_code_t
-ecc_get_param (const char *name, gcry_mpi_t *pkey)
-{
-  gpg_err_code_t err;
-  unsigned int nbits;
-  elliptic_curve_t E;
-  mpi_ec_t ctx;
-  gcry_mpi_t g_x, g_y;
-  
-  err = generate_curve (0, name, &E, &nbits);
-  if (err)
-    return err;
-
-  g_x = mpi_new (0);
-  g_y = mpi_new (0);
-  ctx = _gcry_mpi_ec_init (E.p, E.a);
-  if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx))
-    log_fatal ("ecc get param: Failed to get affine coordinates\n");
-  _gcry_mpi_ec_free (ctx);
-  point_free (&E.G);
-
-  pkey[0] = E.p;
-  pkey[1] = E.a;
-  pkey[2] = E.b;
-  pkey[3] = ec2os (g_x, g_y, E.p);
-  pkey[4] = E.n;
-  pkey[5] = NULL;
-
-  return 0;
-}
-
-
-static gcry_err_code_t
-ecc_check_secret_key (int algo, gcry_mpi_t *skey)
-{
-  gpg_err_code_t err;
-  ECC_secret_key sk;
-
-  (void)algo;
-
-  if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5]
-      || !skey[6] || !skey[7] || !skey[8] || !skey[9] || !skey[10])
-    return GPG_ERR_BAD_MPI;
-
-  sk.E.p = skey[0];
-  sk.E.a = skey[1];
-  sk.E.b = skey[2];
-  point_init (&sk.E.G);
-  err = os2ec (&sk.E.G, skey[3]);
-  if (err)
-    {
-      point_free (&sk.E.G);
-      return err;
-    }
-  sk.E.n = skey[4];
-  point_init (&sk.Q);
-  err = os2ec (&sk.Q, skey[5]);
-  if (err)
-    {
-      point_free (&sk.E.G);
-      point_free (&sk.Q);
-      return err;
-    }
-
-  sk.d = skey[6];
-
-  if (check_secret_key (&sk))
-    {
-      point_free (&sk.E.G);
-      point_free (&sk.Q);
-      return GPG_ERR_BAD_SECKEY;
-    }
-  point_free (&sk.E.G);
-  point_free (&sk.Q);
-  return 0;
-}
-
-
-static gcry_err_code_t
-ecc_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
-{
-  gpg_err_code_t err;
-  ECC_secret_key sk;
-
-  (void)algo;
-
-  if (!data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
-      || !skey[5] || !skey[6] )
-    return GPG_ERR_BAD_MPI;
-
-  sk.E.p = skey[0];
-  sk.E.a = skey[1];
-  sk.E.b = skey[2];
-  point_init (&sk.E.G);
-  err = os2ec (&sk.E.G, skey[3]);
-  if (err)
-    {
-      point_free (&sk.E.G);
-      return err;
-    }
-  sk.E.n = skey[4];
-  point_init (&sk.Q);
-  err = os2ec (&sk.Q, skey[5]);
-  if (err)
-    {
-      point_free (&sk.E.G);
-      point_free (&sk.Q);
-      return err;
-    }
-  sk.d = skey[6];
-
-  resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
-  resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
-  err = sign (data, &sk, resarr[0], resarr[1]);
-  if (err)
-    {
-      mpi_free (resarr[0]);
-      mpi_free (resarr[1]);
-      resarr[0] = NULL; /* Mark array as released.  */
-    }
-  point_free (&sk.E.G);
-  point_free (&sk.Q);
-  return err;
-}
-
-static gcry_err_code_t
-ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
-            int (*cmp)(void *, gcry_mpi_t), void *opaquev)
-{
-  gpg_err_code_t err;
-  ECC_public_key pk;
-
-  (void)algo;
-  (void)cmp;
-  (void)opaquev;
-
-  if (!data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2]
-      || !pkey[3] || !pkey[4] || !pkey[5] )
-    return GPG_ERR_BAD_MPI;
-
-  pk.E.p = pkey[0];
-  pk.E.a = pkey[1];
-  pk.E.b = pkey[2];
-  point_init (&pk.E.G);
-  err = os2ec (&pk.E.G, pkey[3]);
-  if (err)
-    {
-      point_free (&pk.E.G);
-      return err;
-    }
-  pk.E.n = pkey[4];
-  point_init (&pk.Q);
-  err = os2ec (&pk.Q, pkey[5]);
-  if (err)
-    {
-      point_free (&pk.E.G);
-      point_free (&pk.Q);
-      return err;
-    }
-
-  err = verify (hash, &pk, data[0], data[1]);
-
-  point_free (&pk.E.G);
-  point_free (&pk.Q);
-  return err;
-}
-
-
-
-static unsigned int
-ecc_get_nbits (int algo, gcry_mpi_t *pkey)
-{
-  (void)algo;
-
-  return mpi_get_nbits (pkey[0]);
-}
-
-
-
-/* See rsa.c for a description of this function.  */
-static gpg_err_code_t
-compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
-{
-  static const char names[] = "pabgnq";
-  gpg_err_code_t ec = 0;
-  gcry_sexp_t l1;
-  gcry_mpi_t values[6];
-  int idx;
-
-  /* Clear the values for easier error cleanup.  */
-  for (idx=0; idx < 6; idx++)
-    values[idx] = NULL;
-    
-  /* Fill values with all available parameters.  */
-  for (idx=0; idx < 6; idx++)
-    {
-      l1 = gcry_sexp_find_token (keyparam, names+idx, 1);
-      if (l1)
-        {
-          values[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
-         gcry_sexp_release (l1);
-         if (!values[idx])
-            {
-              ec = GPG_ERR_INV_OBJ;
-              goto leave;
-            }
-       }
-    }
-  
-  /* Check whether a curve parameter is available and use that to fill
-     in missing values.  */
-  l1 = gcry_sexp_find_token (keyparam, "curve", 5);
-  if (l1)
-    {
-      char *curve;
-      gcry_mpi_t tmpvalues[6];
-      
-      for (idx = 0; idx < 6; idx++)
-        tmpvalues[idx] = NULL;
-
-      curve = _gcry_sexp_nth_string (l1, 1);
-      if (!curve)
-        {
-          ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
-          goto leave;
-        }
-      ec = ecc_get_param (curve, tmpvalues);
-      gcry_free (curve);
-      if (ec)
-        goto leave;
-
-      for (idx = 0; idx < 6; idx++)
-        {
-          if (!values[idx])
-            values[idx] = tmpvalues[idx];
-          else
-            mpi_free (tmpvalues[idx]);
-        }
-    }
-
-  /* Check that all parameters are known and normalize all MPIs (that
-     should not be required but we use an internal fucntion later and
-     thus we better make 100% sure that they are normalized). */
-  for (idx = 0; idx < 6; idx++)
-    if (!values[idx])
-      {
-        ec = GPG_ERR_NO_OBJ;
-        goto leave;
-      }
-    else
-      _gcry_mpi_normalize (values[idx]);
-      
-  /* Hash them all.  */
-  for (idx = 0; idx < 6; idx++)
-    {
-      char buf[30];
-      unsigned char *rawmpi;
-      unsigned int rawmpilen;
-      
-      rawmpi = _gcry_mpi_get_buffer (values[idx], &rawmpilen, NULL);
-      if (!rawmpi)
-        {
-          ec = gpg_err_code_from_syserror ();
-          goto leave;
-        }
-      snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
-      gcry_md_write (md, buf, strlen (buf));
-      gcry_md_write (md, rawmpi, rawmpilen);
-      gcry_md_write (md, ")", 1);
-      gcry_free (rawmpi);
-    }
-
- leave:
-  for (idx = 0; idx < 6; idx++)
-    _gcry_mpi_release (values[idx]);
-  
-  return ec;
-}
-
-
-
-
-\f
-/* 
-     Self-test section.
- */
-
-
-static gpg_err_code_t
-selftests_ecdsa (selftest_report_func_t report)
-{
-  const char *what;
-  const char *errtxt;
-  
-  what = "low-level";
-  errtxt = NULL; /*selftest ();*/
-  if (errtxt)
-    goto failed;
-
-  /* FIXME:  need more tests.  */
-
-  return 0; /* Succeeded. */
-
- failed:
-  if (report)
-    report ("pubkey", GCRY_PK_ECDSA, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-
-/* Run a full self-test for ALGO and return 0 on success.  */
-static gpg_err_code_t
-run_selftests (int algo, int extended, selftest_report_func_t report)
-{
-  gpg_err_code_t ec;
-
-  (void)extended;
-
-  switch (algo)
-    {
-    case GCRY_PK_ECDSA:
-      ec = selftests_ecdsa (report);
-      break;
-    default:
-      ec = GPG_ERR_PUBKEY_ALGO;
-      break;
-        
-    }
-  return ec;
-}
-
-
-
-\f
-static const char *ecdsa_names[] =
-  {
-    "ecdsa",
-    "ecc",
-    NULL,
-  };
-
-gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
-  {
-    "ECDSA", ecdsa_names,
-    "pabgnq", "pabgnqd", "", "rs", "pabgnq",
-    GCRY_PK_USAGE_SIGN,
-    ecc_generate,
-    ecc_check_secret_key,
-    NULL,
-    NULL,
-    ecc_sign,
-    ecc_verify,
-    ecc_get_nbits
-  };
-
-pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa = 
-  {
-    run_selftests,
-    ecc_generate_ext,
-    compute_keygrip,
-    ecc_get_param
-  };
-
diff --git a/lib/libgcrypt/cipher/elgamal.c b/lib/libgcrypt/cipher/elgamal.c
deleted file mode 100644 (file)
index 0b0c07c..0000000
+++ /dev/null
@@ -1,846 +0,0 @@
-/* Elgamal.c  -  Elgamal Public Key encryption
- * Copyright (C) 1998, 2000, 2001, 2002, 2003,
- *               2008  Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * For a description of the algorithm, see:
- *   Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
- *   ISBN 0-471-11709-9. Pages 476 ff.
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "g10lib.h"
-#include "mpi.h"
-#include "cipher.h"
-
-typedef struct
-{
-  gcry_mpi_t p;            /* prime */
-  gcry_mpi_t g;            /* group generator */
-  gcry_mpi_t y;            /* g^x mod p */
-} ELG_public_key;
-
-
-typedef struct
-{
-  gcry_mpi_t p;            /* prime */
-  gcry_mpi_t g;            /* group generator */
-  gcry_mpi_t y;            /* g^x mod p */
-  gcry_mpi_t x;            /* secret exponent */
-} ELG_secret_key;
-
-
-static int test_keys (ELG_secret_key *sk, unsigned int nbits, int nodie);
-static gcry_mpi_t gen_k (gcry_mpi_t p, int small_k);
-static void generate (ELG_secret_key *sk, unsigned nbits, gcry_mpi_t **factors);
-static int  check_secret_key (ELG_secret_key *sk);
-static void do_encrypt (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
-                        ELG_public_key *pkey);
-static void decrypt (gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b,
-                     ELG_secret_key *skey);
-static void sign (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
-                  ELG_secret_key *skey);
-static int  verify (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
-                    ELG_public_key *pkey);
-
-
-static void (*progress_cb) (void *, const char *, int, int, int);
-static void *progress_cb_data;
-
-void
-_gcry_register_pk_elg_progress (void (*cb) (void *, const char *,
-                                            int, int, int),
-                               void *cb_data)
-{
-  progress_cb = cb;
-  progress_cb_data = cb_data;
-}
-
-
-static void
-progress (int c)
-{
-  if (progress_cb)
-    progress_cb (progress_cb_data, "pk_elg", c, 0, 0);
-}
-
-
-/****************
- * Michael Wiener's table on subgroup sizes to match field sizes.
- * (floating around somewhere, probably based on the paper from
- * Eurocrypt 96, page 332)
- */
-static unsigned int
-wiener_map( unsigned int n )
-{
-  static struct { unsigned int p_n, q_n; } t[] =
-    { /*   p     q      attack cost */
-      {  512, 119 },   /* 9 x 10^17 */
-      {  768, 145 },   /* 6 x 10^21 */
-      { 1024, 165 },   /* 7 x 10^24 */
-      { 1280, 183 },   /* 3 x 10^27 */
-      { 1536, 198 },   /* 7 x 10^29 */
-      { 1792, 212 },   /* 9 x 10^31 */
-      { 2048, 225 },   /* 8 x 10^33 */
-      { 2304, 237 },   /* 5 x 10^35 */
-      { 2560, 249 },   /* 3 x 10^37 */
-      { 2816, 259 },   /* 1 x 10^39 */
-      { 3072, 269 },   /* 3 x 10^40 */
-      { 3328, 279 },   /* 8 x 10^41 */
-      { 3584, 288 },   /* 2 x 10^43 */
-      { 3840, 296 },   /* 4 x 10^44 */
-      { 4096, 305 },   /* 7 x 10^45 */
-      { 4352, 313 },   /* 1 x 10^47 */
-      { 4608, 320 },   /* 2 x 10^48 */
-      { 4864, 328 },   /* 2 x 10^49 */
-      { 5120, 335 },   /* 3 x 10^50 */
-      { 0, 0 }
-    };
-  int i;
-
-  for(i=0; t[i].p_n; i++ )  
-    {
-      if( n <= t[i].p_n )
-        return t[i].q_n;
-    }
-  /* Not in table - use an arbitrary high number. */
-  return  n / 8 + 200;
-}
-
-static int
-test_keys ( ELG_secret_key *sk, unsigned int nbits, int nodie )
-{
-  ELG_public_key pk;
-  gcry_mpi_t test = gcry_mpi_new ( 0 );
-  gcry_mpi_t out1_a = gcry_mpi_new ( nbits );
-  gcry_mpi_t out1_b = gcry_mpi_new ( nbits );
-  gcry_mpi_t out2 = gcry_mpi_new ( nbits );
-  int failed = 0;
-
-  pk.p = sk->p;
-  pk.g = sk->g;
-  pk.y = sk->y;
-
-  gcry_mpi_randomize ( test, nbits, GCRY_WEAK_RANDOM );
-
-  do_encrypt ( out1_a, out1_b, test, &pk );
-  decrypt ( out2, out1_a, out1_b, sk );
-  if ( mpi_cmp( test, out2 ) )
-    failed |= 1;
-
-  sign ( out1_a, out1_b, test, sk );
-  if ( !verify( out1_a, out1_b, test, &pk ) )
-    failed |= 2;
-
-  gcry_mpi_release ( test );
-  gcry_mpi_release ( out1_a );
-  gcry_mpi_release ( out1_b );
-  gcry_mpi_release ( out2 );
-
-  if (failed && !nodie)
-    log_fatal ("Elgamal test key for %s %s failed\n",
-               (failed & 1)? "encrypt+decrypt":"",
-               (failed & 2)? "sign+verify":"");
-  if (failed && DBG_CIPHER) 
-    log_debug ("Elgamal test key for %s %s failed\n",
-               (failed & 1)? "encrypt+decrypt":"",
-               (failed & 2)? "sign+verify":"");
-
-  return failed;
-}
-
-
-/****************
- * Generate a random secret exponent k from prime p, so that k is
- * relatively prime to p-1.  With SMALL_K set, k will be selected for
- * better encryption performance - this must never be used signing!
- */
-static gcry_mpi_t
-gen_k( gcry_mpi_t p, int small_k )
-{
-  gcry_mpi_t k = mpi_alloc_secure( 0 );
-  gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(p) );
-  gcry_mpi_t p_1 = mpi_copy(p);
-  unsigned int orig_nbits = mpi_get_nbits(p);
-  unsigned int nbits, nbytes;
-  char *rndbuf = NULL;
-
-  if (small_k)
-    {
-      /* Using a k much lesser than p is sufficient for encryption and
-       * it greatly improves the encryption performance.  We use
-       * Wiener's table and add a large safety margin. */
-      nbits = wiener_map( orig_nbits ) * 3 / 2;
-      if( nbits >= orig_nbits )
-        BUG();
-    }
-  else
-    nbits = orig_nbits;
-
-
-  nbytes = (nbits+7)/8;
-  if( DBG_CIPHER )
-    log_debug("choosing a random k ");
-  mpi_sub_ui( p_1, p, 1);
-  for(;;) 
-    {
-      if( !rndbuf || nbits < 32 ) 
-        {
-          gcry_free(rndbuf);
-          rndbuf = gcry_random_bytes_secure( nbytes, GCRY_STRONG_RANDOM );
-        }
-      else
-        { 
-          /* Change only some of the higher bits.  We could improve
-             this by directly requesting more memory at the first call
-             to get_random_bytes() and use this the here maybe it is
-             easier to do this directly in random.c Anyway, it is
-             highly inlikely that we will ever reach this code. */
-          char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
-          memcpy( rndbuf, pp, 4 );
-          gcry_free(pp);
-       }
-      _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
-        
-      for(;;)
-        {
-          if( !(mpi_cmp( k, p_1 ) < 0) )  /* check: k < (p-1) */
-            {
-              if( DBG_CIPHER )
-                progress('+');
-              break; /* no  */
-            }
-          if( !(mpi_cmp_ui( k, 0 ) > 0) )  /* check: k > 0 */
-            {
-              if( DBG_CIPHER )
-                progress('-');
-              break; /* no */
-            }
-          if (gcry_mpi_gcd( temp, k, p_1 ))
-            goto found;  /* okay, k is relative prime to (p-1) */
-          mpi_add_ui( k, k, 1 );
-          if( DBG_CIPHER )
-            progress('.');
-       }
-    }
- found:
-  gcry_free(rndbuf);
-  if( DBG_CIPHER )
-    progress('\n');
-  mpi_free(p_1);
-  mpi_free(temp);
-
-  return k;
-}
-
-/****************
- * Generate a key pair with a key of size NBITS
- * Returns: 2 structures filled with all needed values
- *         and an array with n-1 factors of (p-1)
- */
-static void
-generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
-{
-  gcry_mpi_t p;    /* the prime */
-  gcry_mpi_t p_min1;
-  gcry_mpi_t g;
-  gcry_mpi_t x;    /* the secret exponent */
-  gcry_mpi_t y;
-  unsigned int qbits;
-  unsigned int xbits;
-  byte *rndbuf;
-
-  p_min1 = gcry_mpi_new ( nbits );
-  qbits = wiener_map( nbits );
-  if( qbits & 1 ) /* better have a even one */
-    qbits++;
-  g = mpi_alloc(1);
-  p = _gcry_generate_elg_prime( 0, nbits, qbits, g, ret_factors );
-  mpi_sub_ui(p_min1, p, 1);
-
-
-  /* Select a random number which has these properties:
-   *    0 < x < p-1
-   * This must be a very good random number because this is the
-   * secret part.  The prime is public and may be shared anyway,
-   * so a random generator level of 1 is used for the prime.
-   *
-   * I don't see a reason to have a x of about the same size
-   * as the p.  It should be sufficient to have one about the size
-   * of q or the later used k plus a large safety margin. Decryption
-   * will be much faster with such an x.
-   */
-  xbits = qbits * 3 / 2;
-  if( xbits >= nbits )
-    BUG();
-  x = gcry_mpi_snew ( xbits );
-  if( DBG_CIPHER )
-    log_debug("choosing a random x of size %u", xbits );
-  rndbuf = NULL;
-  do 
-    {
-      if( DBG_CIPHER )
-        progress('.');
-      if( rndbuf )
-        { /* Change only some of the higher bits */
-          if( xbits < 16 ) /* should never happen ... */
-            {
-              gcry_free(rndbuf);
-              rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
-                                                 GCRY_VERY_STRONG_RANDOM );
-            }
-          else
-            {
-              char *r = gcry_random_bytes_secure( 2,
-                                                  GCRY_VERY_STRONG_RANDOM );
-              memcpy(rndbuf, r, 2 );
-              gcry_free(r);
-            }
-       }
-      else 
-        {
-          rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
-                                             GCRY_VERY_STRONG_RANDOM );
-       }
-      _gcry_mpi_set_buffer( x, rndbuf, (xbits+7)/8, 0 );
-      mpi_clear_highbit( x, xbits+1 );
-    } 
-  while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
-  gcry_free(rndbuf);
-
-  y = gcry_mpi_new (nbits);
-  gcry_mpi_powm( y, g, x, p );
-
-  if( DBG_CIPHER ) 
-    {
-      progress('\n');
-      log_mpidump("elg  p= ", p );
-      log_mpidump("elg  g= ", g );
-      log_mpidump("elg  y= ", y );
-      log_mpidump("elg  x= ", x );
-    }
-
-  /* Copy the stuff to the key structures */
-  sk->p = p;
-  sk->g = g;
-  sk->y = y;
-  sk->x = x;
-
-  gcry_mpi_release ( p_min1 );
-
-  /* Now we can test our keys (this should never fail!) */
-  test_keys ( sk, nbits - 64, 0 );
-}
-
-
-/* Generate a key pair with a key of size NBITS not using a random
-   value for the secret key but the one given as X.  This is useful to
-   implement a passphrase based decryption for a public key based
-   encryption.  It has appliactions in backup systems.
-   Returns: A structure filled with all needed values and an array
-           with n-1 factors of (p-1).  */
-static gcry_err_code_t
-generate_using_x (ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t x,
-                  gcry_mpi_t **ret_factors )
-{
-  gcry_mpi_t p;      /* The prime.  */
-  gcry_mpi_t p_min1; /* The prime minus 1.  */
-  gcry_mpi_t g;      /* The generator.  */
-  gcry_mpi_t y;      /* g^x mod p.  */
-  unsigned int qbits;
-  unsigned int xbits;
-
-  sk->p = NULL;
-  sk->g = NULL;
-  sk->y = NULL;
-  sk->x = NULL;
-
-  /* Do a quick check to see whether X is suitable.  */
-  xbits = mpi_get_nbits (x);
-  if ( xbits < 64 || xbits >= nbits )
-    return GPG_ERR_INV_VALUE;
-
-  p_min1 = gcry_mpi_new ( nbits );
-  qbits  = wiener_map ( nbits );
-  if ( (qbits & 1) ) /* Better have an even one.  */
-    qbits++;
-  g = mpi_alloc (1);
-  p = _gcry_generate_elg_prime ( 0, nbits, qbits, g, ret_factors );
-  mpi_sub_ui (p_min1, p, 1);
-
-  if (DBG_CIPHER)
-    log_debug ("using a supplied x of size %u", xbits );
-  if ( !(mpi_cmp_ui ( x, 0 ) > 0 && mpi_cmp ( x, p_min1 ) <0 ) )
-    {
-      gcry_mpi_release ( p_min1 );
-      gcry_mpi_release ( p );
-      gcry_mpi_release ( g );
-      return GPG_ERR_INV_VALUE;
-    }
-
-  y = gcry_mpi_new (nbits);
-  gcry_mpi_powm ( y, g, x, p );
-
-  if ( DBG_CIPHER ) 
-    {
-      progress ('\n');
-      log_mpidump ("elg  p= ", p );
-      log_mpidump ("elg  g= ", g );
-      log_mpidump ("elg  y= ", y );
-      log_mpidump ("elg  x= ", x );
-    }
-
-  /* Copy the stuff to the key structures */
-  sk->p = p;
-  sk->g = g;
-  sk->y = y;
-  sk->x = gcry_mpi_copy (x);
-
-  gcry_mpi_release ( p_min1 );
-
-  /* Now we can test our keys. */
-  if ( test_keys ( sk, nbits - 64, 1 ) )
-    {
-      gcry_mpi_release ( sk->p ); sk->p = NULL;
-      gcry_mpi_release ( sk->g ); sk->g = NULL;
-      gcry_mpi_release ( sk->y ); sk->y = NULL;
-      gcry_mpi_release ( sk->x ); sk->x = NULL;
-      return GPG_ERR_BAD_SECKEY;
-    }
-
-  return 0;
-}
-
-
-/****************
- * Test whether the secret key is valid.
- * Returns: if this is a valid key.
- */
-static int
-check_secret_key( ELG_secret_key *sk )
-{
-  int rc;
-  gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
-
-  gcry_mpi_powm( y, sk->g, sk->x, sk->p );
-  rc = !mpi_cmp( y, sk->y );
-  mpi_free( y );
-  return rc;
-}
-
-
-static void
-do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
-{
-  gcry_mpi_t k;
-
-  /* Note: maybe we should change the interface, so that it
-   * is possible to check that input is < p and return an
-   * error code.
-   */
-
-  k = gen_k( pkey->p, 1 );
-  gcry_mpi_powm( a, pkey->g, k, pkey->p );
-  /* b = (y^k * input) mod p
-   *    = ((y^k mod p) * (input mod p)) mod p
-   * and because input is < p
-   *    = ((y^k mod p) * input) mod p
-   */
-  gcry_mpi_powm( b, pkey->y, k, pkey->p );
-  gcry_mpi_mulm( b, b, input, pkey->p );
-#if 0
-  if( DBG_CIPHER )
-    {
-      log_mpidump("elg encrypted y= ", pkey->y);
-      log_mpidump("elg encrypted p= ", pkey->p);
-      log_mpidump("elg encrypted k= ", k);
-      log_mpidump("elg encrypted M= ", input);
-      log_mpidump("elg encrypted a= ", a);
-      log_mpidump("elg encrypted b= ", b);
-    }
-#endif
-  mpi_free(k);
-}
-
-
-
-
-static void
-decrypt(gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, ELG_secret_key *skey )
-{
-  gcry_mpi_t t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
-
-  /* output = b/(a^x) mod p */
-  gcry_mpi_powm( t1, a, skey->x, skey->p );
-  mpi_invm( t1, t1, skey->p );
-  mpi_mulm( output, b, t1, skey->p );
-#if 0
-  if( DBG_CIPHER ) 
-    {
-      log_mpidump("elg decrypted x= ", skey->x);
-      log_mpidump("elg decrypted p= ", skey->p);
-      log_mpidump("elg decrypted a= ", a);
-      log_mpidump("elg decrypted b= ", b);
-      log_mpidump("elg decrypted M= ", output);
-    }
-#endif
-  mpi_free(t1);
-}
-
-
-/****************
- * Make an Elgamal signature out of INPUT
- */
-
-static void
-sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey )
-{
-    gcry_mpi_t k;
-    gcry_mpi_t t   = mpi_alloc( mpi_get_nlimbs(a) );
-    gcry_mpi_t inv = mpi_alloc( mpi_get_nlimbs(a) );
-    gcry_mpi_t p_1 = mpi_copy(skey->p);
-
-   /*
-    * b = (t * inv) mod (p-1)
-    * b = (t * inv(k,(p-1),(p-1)) mod (p-1)
-    * b = (((M-x*a) mod (p-1)) * inv(k,(p-1),(p-1))) mod (p-1)
-    *
-    */
-    mpi_sub_ui(p_1, p_1, 1);
-    k = gen_k( skey->p, 0 /* no small K ! */ );
-    gcry_mpi_powm( a, skey->g, k, skey->p );
-    mpi_mul(t, skey->x, a );
-    mpi_subm(t, input, t, p_1 );
-    mpi_invm(inv, k, p_1 );
-    mpi_mulm(b, t, inv, p_1 );
-
-#if 0
-    if( DBG_CIPHER ) 
-      {
-       log_mpidump("elg sign p= ", skey->p);
-       log_mpidump("elg sign g= ", skey->g);
-       log_mpidump("elg sign y= ", skey->y);
-       log_mpidump("elg sign x= ", skey->x);
-       log_mpidump("elg sign k= ", k);
-       log_mpidump("elg sign M= ", input);
-       log_mpidump("elg sign a= ", a);
-       log_mpidump("elg sign b= ", b);
-      }
-#endif
-    mpi_free(k);
-    mpi_free(t);
-    mpi_free(inv);
-    mpi_free(p_1);
-}
-
-
-/****************
- * Returns true if the signature composed of A and B is valid.
- */
-static int
-verify(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
-{
-  int rc;
-  gcry_mpi_t t1;
-  gcry_mpi_t t2;
-  gcry_mpi_t base[4];
-  gcry_mpi_t ex[4];
-
-  if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) )
-    return 0; /* assertion     0 < a < p  failed */
-
-  t1 = mpi_alloc( mpi_get_nlimbs(a) );
-  t2 = mpi_alloc( mpi_get_nlimbs(a) );
-
-#if 0
-  /* t1 = (y^a mod p) * (a^b mod p) mod p */
-  gcry_mpi_powm( t1, pkey->y, a, pkey->p );
-  gcry_mpi_powm( t2, a, b, pkey->p );
-  mpi_mulm( t1, t1, t2, pkey->p );
-
-  /* t2 = g ^ input mod p */
-  gcry_mpi_powm( t2, pkey->g, input, pkey->p );
-
-  rc = !mpi_cmp( t1, t2 );
-#elif 0
-  /* t1 = (y^a mod p) * (a^b mod p) mod p */
-  base[0] = pkey->y; ex[0] = a;
-  base[1] = a;       ex[1] = b;
-  base[2] = NULL;    ex[2] = NULL;
-  mpi_mulpowm( t1, base, ex, pkey->p );
-
-  /* t2 = g ^ input mod p */
-  gcry_mpi_powm( t2, pkey->g, input, pkey->p );
-
-  rc = !mpi_cmp( t1, t2 );
-#else
-  /* t1 = g ^ - input * y ^ a * a ^ b  mod p */
-  mpi_invm(t2, pkey->g, pkey->p );
-  base[0] = t2     ; ex[0] = input;
-  base[1] = pkey->y; ex[1] = a;
-  base[2] = a;       ex[2] = b;
-  base[3] = NULL;    ex[3] = NULL;
-  mpi_mulpowm( t1, base, ex, pkey->p );
-  rc = !mpi_cmp_ui( t1, 1 );
-
-#endif
-
-  mpi_free(t1);
-  mpi_free(t2);
-  return rc;
-}
-
-/*********************************************
- **************  interface  ******************
- *********************************************/
-
-static gpg_err_code_t
-elg_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
-                  const gcry_sexp_t genparms,
-                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
-                  gcry_sexp_t *r_extrainfo)
-{
-  gpg_err_code_t ec;
-  ELG_secret_key sk;
-  gcry_mpi_t xvalue = NULL;
-  gcry_sexp_t l1;
-
-  (void)algo;
-  (void)evalue;
-  (void)r_extrainfo;
-
-  if (genparms)
-    {
-      /* Parse the optional xvalue element. */
-      l1 = gcry_sexp_find_token (genparms, "xvalue", 0);
-      if (l1)
-        {
-          xvalue = gcry_sexp_nth_mpi (l1, 1, 0);
-          gcry_sexp_release (l1);
-          if (!xvalue)
-            return GPG_ERR_BAD_MPI;
-        }
-    }
-
-  if (xvalue)
-    ec = generate_using_x (&sk, nbits, xvalue, retfactors);
-  else
-    {
-      generate (&sk, nbits, retfactors);
-      ec = 0;
-    }
-
-  skey[0] = sk.p;
-  skey[1] = sk.g;
-  skey[2] = sk.y;
-  skey[3] = sk.x;
-  
-  return ec;
-}
-
-
-static gcry_err_code_t
-elg_generate (int algo, unsigned int nbits, unsigned long evalue,
-              gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-{
-  ELG_secret_key sk;
-
-  (void)algo;
-  (void)evalue;
-
-  generate (&sk, nbits, retfactors);
-  skey[0] = sk.p;
-  skey[1] = sk.g;
-  skey[2] = sk.y;
-  skey[3] = sk.x;
-  
-  return GPG_ERR_NO_ERROR;
-}
-
-
-static gcry_err_code_t
-elg_check_secret_key (int algo, gcry_mpi_t *skey)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  ELG_secret_key sk;
-
-  (void)algo;
-
-  if ((! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
-    err = GPG_ERR_BAD_MPI;
-  else
-    {
-      sk.p = skey[0];
-      sk.g = skey[1];
-      sk.y = skey[2];
-      sk.x = skey[3];
-      
-      if (! check_secret_key (&sk))
-       err = GPG_ERR_BAD_SECKEY;
-    }
-
-  return err;
-}
-
-
-static gcry_err_code_t
-elg_encrypt (int algo, gcry_mpi_t *resarr,
-             gcry_mpi_t data, gcry_mpi_t *pkey, int flags)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  ELG_public_key pk;
-
-  (void)algo;
-  (void)flags;
-
-  if ((! data) || (! pkey[0]) || (! pkey[1]) || (! pkey[2]))
-    err = GPG_ERR_BAD_MPI;
-  else
-    {
-      pk.p = pkey[0];
-      pk.g = pkey[1];
-      pk.y = pkey[2];
-      resarr[0] = mpi_alloc (mpi_get_nlimbs (pk.p));
-      resarr[1] = mpi_alloc (mpi_get_nlimbs (pk.p));
-      do_encrypt (resarr[0], resarr[1], data, &pk);
-    }
-  return err;
-}
-
-
-static gcry_err_code_t
-elg_decrypt (int algo, gcry_mpi_t *result,
-             gcry_mpi_t *data, gcry_mpi_t *skey, int flags)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  ELG_secret_key sk;
-
-  (void)algo;
-  (void)flags;
-
-  if ((! data[0]) || (! data[1])
-      || (! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
-    err = GPG_ERR_BAD_MPI;
-  else
-    {
-      sk.p = skey[0];
-      sk.g = skey[1];
-      sk.y = skey[2];
-      sk.x = skey[3];
-      *result = mpi_alloc_secure (mpi_get_nlimbs (sk.p));
-      decrypt (*result, data[0], data[1], &sk);
-    }
-  return err;
-}
-
-
-static gcry_err_code_t
-elg_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  ELG_secret_key sk;
-
-  (void)algo;
-
-  if ((! data)
-      || (! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
-    err = GPG_ERR_BAD_MPI;
-  else
-    {
-      sk.p = skey[0];
-      sk.g = skey[1];
-      sk.y = skey[2];
-      sk.x = skey[3];
-      resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p));
-      resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
-      sign (resarr[0], resarr[1], data, &sk);
-    }
-  
-  return err;
-}
-
-
-static gcry_err_code_t
-elg_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
-            int (*cmp) (void *, gcry_mpi_t), void *opaquev)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  ELG_public_key pk;
-
-  (void)algo;
-  (void)cmp;
-  (void)opaquev;
-
-  if ((! data[0]) || (! data[1]) || (! hash)
-      || (! pkey[0]) || (! pkey[1]) || (! pkey[2]))
-    err = GPG_ERR_BAD_MPI;
-  else
-    {
-      pk.p = pkey[0];
-      pk.g = pkey[1];
-      pk.y = pkey[2];
-      if (! verify (data[0], data[1], hash, &pk))
-       err = GPG_ERR_BAD_SIGNATURE;
-    }
-
-  return err;
-}
-
-
-static unsigned int
-elg_get_nbits (int algo, gcry_mpi_t *pkey)
-{
-  (void)algo;
-
-  return mpi_get_nbits (pkey[0]);
-}
-
-
-static const char *elg_names[] =
-  {
-    "elg",
-    "openpgp-elg",
-    "openpgp-elg-sig",
-    NULL,
-  };
-
-
-gcry_pk_spec_t _gcry_pubkey_spec_elg =
-  {
-    "ELG", elg_names,
-    "pgy", "pgyx", "ab", "rs", "pgy",
-    GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR,
-    elg_generate,
-    elg_check_secret_key,
-    elg_encrypt,
-    elg_decrypt,
-    elg_sign,
-    elg_verify,
-    elg_get_nbits
-  };
-
-pk_extra_spec_t _gcry_pubkey_extraspec_elg = 
-  {
-    NULL,
-    elg_generate_ext,
-    NULL
-  };
-
diff --git a/lib/libgcrypt/cipher/hash-common.c b/lib/libgcrypt/cipher/hash-common.c
deleted file mode 100644 (file)
index 656e180..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/* hash-common.c - Common code for hash algorithms
- * Copyright (C) 2008 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_STDINT_H 
-# include <stdint.h>
-#endif
-
-#include "g10lib.h"
-#include "hash-common.h"
-
-
-/* Run a selftest for hash algorithm ALGO.  If the resulting digest
-   matches EXPECT/EXPECTLEN and everything else is fine as well,
-   return NULL.  If an error occurs, return a static text string
-   describing the error.
-
-   DATAMODE controls what will be hashed according to this table:
-   
-     0 - Hash the supplied DATA of DATALEN.
-     1 - Hash one million times a 'a'.  DATA and DATALEN are ignored.
-   
-*/
-const char *
-_gcry_hash_selftest_check_one (int algo,
-                               int datamode, const void *data, size_t datalen,
-                               const void *expect, size_t expectlen)
-{
-  const char *result = NULL;
-  gcry_error_t err = 0;
-  gcry_md_hd_t hd;
-  unsigned char *digest;
-  
-  if (_gcry_md_get_algo_dlen (algo) != expectlen)
-    return "digest size does not match expected size";
-    
-  err = _gcry_md_open (&hd, algo, 0);
-  if (err)
-    return "gcry_md_open failed";
-  
-  switch (datamode)
-    {
-    case 0:
-      _gcry_md_write (hd, data, datalen);
-      break;
-
-    case 1: /* Hash one million times an "a". */
-      {                
-        char aaa[1000];
-        int i;
-
-        /* Write in odd size chunks so that we test the buffering.  */
-        memset (aaa, 'a', 1000);
-        for (i = 0; i < 1000; i++)
-          _gcry_md_write (hd, aaa, 1000);
-      }
-      break;
-
-    default:
-      result = "invalid DATAMODE";
-    }
-
-  if (!result)
-    {
-      digest = _gcry_md_read (hd, algo);
-      
-      if ( memcmp (digest, expect, expectlen) )
-        result = "digest mismatch";
-    }
-
-  _gcry_md_close (hd);
-
-  return result;
-}
-
diff --git a/lib/libgcrypt/cipher/hash-common.h b/lib/libgcrypt/cipher/hash-common.h
deleted file mode 100644 (file)
index 9c4e333..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* hash-common.h - Declarations of common code for hash algorithms.
- * Copyright (C) 2008 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GCRY_HASH_COMMON_H
-#define GCRY_HASH_COMMON_H
-
-
-const char * _gcry_hash_selftest_check_one 
-/**/         (int algo, 
-              int datamode, const void *data, size_t datalen,
-              const void *expect, size_t expectlen);
-     
-
-
-
-
-#endif /*GCRY_HASH_COMMON_H*/
diff --git a/lib/libgcrypt/cipher/hmac-tests.c b/lib/libgcrypt/cipher/hmac-tests.c
deleted file mode 100644 (file)
index 56c9b20..0000000
+++ /dev/null
@@ -1,732 +0,0 @@
-/* hmac-tests.c - HMAC selftests.
- * Copyright (C) 2008 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/* 
-   Although algorithm self-tests are usually implemented in the module
-   implementing the algorithm, the case for HMAC is different because
-   HMAC is implemnetd on a higher level using a special feature of the
-   gcry_md_ functions.  It would be possible to do this also in the
-   digest algorithm modules, but that would blow up the code too much
-   and spread the hmac tests over several modules.
-
-   Thus we implement all HMAC tests in this test module and provide a
-   function to run the tests.
-*/
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_STDINT_H 
-# include <stdint.h>
-#endif
-
-#include "g10lib.h"
-#include "cipher.h"
-#include "hmac256.h"
-
-/* Check one HMAC with digest ALGO using the regualr HAMC
-   API. (DATA,DATALEN) is the data to be MACed, (KEY,KEYLEN) the key
-   and (EXPECT,EXPECTLEN) the expected result.  Returns NULL on
-   succdess or a string describing the failure.  */
-static const char *
-check_one (int algo,
-           const void *data, size_t datalen, 
-           const void *key, size_t keylen,
-           const void *expect, size_t expectlen)
-{
-  gcry_md_hd_t hd;
-  const unsigned char *digest;
-
-/*   printf ("HMAC algo %d\n", algo); */
-  if (_gcry_md_get_algo_dlen (algo) != expectlen)
-    return "invalid tests data";
-  if (_gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC))
-    return "gcry_md_open failed";
-  if (_gcry_md_setkey (hd, key, keylen))
-    {
-      _gcry_md_close (hd);
-      return "gcry_md_setkey failed";
-    }
-  _gcry_md_write (hd, data, datalen);
-  digest = _gcry_md_read (hd, algo);
-  if (!digest)
-    {
-      _gcry_md_close (hd);
-      return "gcry_md_read failed";
-    }
-  if (memcmp (digest, expect, expectlen))
-    {
-/*       int i; */
-
-/*       fputs ("        {", stdout); */
-/*       for (i=0; i < expectlen-1; i++) */
-/*         { */
-/*           if (i && !(i % 8)) */
-/*             fputs ("\n         ", stdout); */
-/*           printf (" 0x%02x,", digest[i]); */
-/*         } */
-/*       printf (" 0x%02x } },\n", digest[i]); */
-
-      _gcry_md_close (hd);
-      return "does not match";
-    }
-  _gcry_md_close (hd);
-  return NULL;  
-}
-
-
-static gpg_err_code_t
-selftests_sha1 (int extended, selftest_report_func_t report)
-{
-  const char *what;
-  const char *errtxt;
-  unsigned char key[128];
-  int i, j;
-
-  what = "FIPS-198a, A.1";
-  for (i=0; i < 64; i++)
-    key[i] = i;
-  errtxt = check_one (GCRY_MD_SHA1,
-                      "Sample #1", 9,
-                      key, 64,
-                      "\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12"
-                      "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a", 20);
-  if (errtxt)
-    goto failed;
-
-  if (extended)
-    {
-      what = "FIPS-198a, A.2";
-      for (i=0, j=0x30; i < 20; i++)
-        key[i] = j++;
-      errtxt = check_one (GCRY_MD_SHA1,
-                          "Sample #2", 9,
-                          key, 20,
-                          "\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82"
-                          "\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24", 20);
-      if (errtxt)
-        goto failed;
-      
-      what = "FIPS-198a, A.3";
-      for (i=0, j=0x50; i < 100; i++)
-        key[i] = j++;
-      errtxt = check_one (GCRY_MD_SHA1,
-                          "Sample #3", 9,
-                          key, 100,
-                          "\xbc\xf4\x1e\xab\x8b\xb2\xd8\x02\xf3\xd0"
-                          "\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa", 20 );
-      if (errtxt)
-        goto failed;
-      
-      what = "FIPS-198a, A.4";
-      for (i=0, j=0x70; i < 49; i++)
-        key[i] = j++;
-      errtxt = check_one (GCRY_MD_SHA1,
-                          "Sample #4", 9,
-                          key, 49,
-                          "\x9e\xa8\x86\xef\xe2\x68\xdb\xec\xce\x42"
-                          "\x0c\x75\x24\xdf\x32\xe0\x75\x1a\x2a\x26", 20 );
-      if (errtxt)
-        goto failed;
-    }
-
-  return 0; /* Succeeded. */
-
- failed:
-  if (report)
-    report ("hmac", GCRY_MD_SHA1, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-
-
-static gpg_err_code_t
-selftests_sha224 (int extended, selftest_report_func_t report)
-{
-  static struct 
-  {
-    const char * const desc;
-    const char * const data;
-    const char * const key;
-    const char expect[28];
-  } tv[] =
-    {
-      { "data-28 key-4",
-        "what do ya want for nothing?", 
-        "Jefe",
-        { 0xa3, 0x0e, 0x01, 0x09, 0x8b, 0xc6, 0xdb, 0xbf,
-          0x45, 0x69, 0x0f, 0x3a, 0x7e, 0x9e, 0x6d, 0x0f,
-          0x8b, 0xbe, 0xa2, 0xa3, 0x9e, 0x61, 0x48, 0x00,
-          0x8f, 0xd0, 0x5e, 0x44 } },
-
-      { "data-9 key-20",
-        "Hi There",
-       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-        "\x0b\x0b\x0b\x0b",
-        { 0x89, 0x6f, 0xb1, 0x12, 0x8a, 0xbb, 0xdf, 0x19,
-          0x68, 0x32, 0x10, 0x7c, 0xd4, 0x9d, 0xf3, 0x3f,
-          0x47, 0xb4, 0xb1, 0x16, 0x99, 0x12, 0xba, 0x4f,
-          0x53, 0x68, 0x4b, 0x22 } },
-
-      { "data-50 key-20",
-        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-        "\xdd\xdd",
-       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa",
-        { 0x7f, 0xb3, 0xcb, 0x35, 0x88, 0xc6, 0xc1, 0xf6,
-          0xff, 0xa9, 0x69, 0x4d, 0x7d, 0x6a, 0xd2, 0x64,
-          0x93, 0x65, 0xb0, 0xc1, 0xf6, 0x5d, 0x69, 0xd1,
-          0xec, 0x83, 0x33, 0xea } },
-
-      { "data-50 key-26",
-        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-        "\xcd\xcd",
-       "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
-        "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
-        { 0x6c, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3c, 0xac,
-          0x6a, 0x2a, 0xbc, 0x1b, 0xb3, 0x82, 0x62, 0x7c,
-          0xec, 0x6a, 0x90, 0xd8, 0x6e, 0xfc, 0x01, 0x2d,
-          0xe7, 0xaf, 0xec, 0x5a } },
-
-      { "data-54 key-131",
-        "Test Using Larger Than Block-Size Key - Hash Key First",
-       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa",
-        { 0x95, 0xe9, 0xa0, 0xdb, 0x96, 0x20, 0x95, 0xad,
-          0xae, 0xbe, 0x9b, 0x2d, 0x6f, 0x0d, 0xbc, 0xe2,
-          0xd4, 0x99, 0xf1, 0x12, 0xf2, 0xd2, 0xb7, 0x27,
-          0x3f, 0xa6, 0x87, 0x0e } },
-
-      { "data-152 key-131",
-        "This is a test using a larger than block-size key and a larger "
-        "than block-size data. The key needs to be hashed before being "
-        "used by the HMAC algorithm.",
-       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa",
-        { 0x3a, 0x85, 0x41, 0x66, 0xac, 0x5d, 0x9f, 0x02,
-          0x3f, 0x54, 0xd5, 0x17, 0xd0, 0xb3, 0x9d, 0xbd,
-          0x94, 0x67, 0x70, 0xdb, 0x9c, 0x2b, 0x95, 0xc9,
-          0xf6, 0xf5, 0x65, 0xd1 } },
-
-      { NULL }
-    };
-  const char *what;
-  const char *errtxt;
-  int tvidx;
-  
-  for (tvidx=0; tv[tvidx].desc; tvidx++)
-    {
-      what = tv[tvidx].desc;
-      errtxt = check_one (GCRY_MD_SHA224,
-                          tv[tvidx].data, strlen (tv[tvidx].data),
-                          tv[tvidx].key, strlen (tv[tvidx].key),
-                          tv[tvidx].expect, DIM (tv[tvidx].expect) );
-      if (errtxt)
-        goto failed;
-      if (!extended)
-        break;
-    }
-
-  return 0; /* Succeeded. */
-
- failed:
-  if (report)
-    report ("hmac", GCRY_MD_SHA224, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-
-static gpg_err_code_t
-selftests_sha256 (int extended, selftest_report_func_t report)
-{
-  static struct 
-  {
-    const char * const desc;
-    const char * const data;
-    const char * const key;
-    const char expect[32];
-  } tv[] =
-    {
-      { "data-28 key-4",
-        "what do ya want for nothing?", 
-        "Jefe",
-       { 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
-          0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
-          0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
-          0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 } },
-
-      { "data-9 key-20",
-        "Hi There",
-       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-        "\x0b\x0b\x0b\x0b",
-        { 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
-          0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
-          0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
-          0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 } },
-
-      { "data-50 key-20",
-        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-        "\xdd\xdd",
-       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa",
-        { 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46,
-          0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7,
-          0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22,
-          0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe } },
-
-      { "data-50 key-26",
-        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-        "\xcd\xcd",
-       "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
-        "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
-       { 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e,
-          0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a,
-          0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07,
-          0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b } },
-
-      { "data-54 key-131",
-        "Test Using Larger Than Block-Size Key - Hash Key First",
-       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa",
-       { 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
-          0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
-          0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
-          0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 } },
-
-      { "data-152 key-131",
-        "This is a test using a larger than block-size key and a larger "
-        "than block-size data. The key needs to be hashed before being "
-        "used by the HMAC algorithm.",
-       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa",
-       { 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb,
-          0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44,
-          0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93,
-          0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2 } },
-
-      { NULL }
-    };
-  const char *what;
-  const char *errtxt;
-  int tvidx;
-  
-  for (tvidx=0; tv[tvidx].desc; tvidx++)
-    {
-      hmac256_context_t hmachd;
-      const unsigned char *digest;
-      size_t dlen;
-
-      what = tv[tvidx].desc;
-      errtxt = check_one (GCRY_MD_SHA256,
-                          tv[tvidx].data, strlen (tv[tvidx].data),
-                          tv[tvidx].key, strlen (tv[tvidx].key),
-                          tv[tvidx].expect, DIM (tv[tvidx].expect) );
-      if (errtxt)
-        goto failed;
-
-      hmachd = _gcry_hmac256_new (tv[tvidx].key, strlen (tv[tvidx].key));
-      if (!hmachd)
-        {
-          errtxt = "_gcry_hmac256_new failed";
-          goto failed;
-        }
-      _gcry_hmac256_update (hmachd, tv[tvidx].data, strlen (tv[tvidx].data));
-      digest = _gcry_hmac256_finalize (hmachd, &dlen);
-      if (!digest)
-        {
-          errtxt = "_gcry_hmac256_finalize failed";
-          _gcry_hmac256_release (hmachd);
-          goto failed;
-        }
-      if (dlen != DIM (tv[tvidx].expect)
-          || memcmp (digest, tv[tvidx].expect, DIM (tv[tvidx].expect)))
-        {
-          errtxt = "does not match in second implementation";
-          _gcry_hmac256_release (hmachd);
-          goto failed;
-        }
-      _gcry_hmac256_release (hmachd);
-
-      if (!extended)
-        break;
-    }
-
-  return 0; /* Succeeded. */
-
- failed:
-  if (report)
-    report ("hmac", GCRY_MD_SHA256, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-
-static gpg_err_code_t
-selftests_sha384 (int extended, selftest_report_func_t report)
-{
-  static struct 
-  {
-    const char * const desc;
-    const char * const data;
-    const char * const key;
-    const char expect[48];
-  } tv[] =
-    {
-      { "data-28 key-4",
-        "what do ya want for nothing?", 
-        "Jefe",
-        { 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31,
-          0x61, 0x7f, 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b,
-          0x9c, 0x7e, 0xf4, 0x64, 0xf5, 0xa0, 0x1b, 0x47,
-          0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22, 0x44, 0x5e,
-          0x8e, 0x22, 0x40, 0xca, 0x5e, 0x69, 0xe2, 0xc7,
-          0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49 } },
-
-      { "data-9 key-20",
-        "Hi There",
-       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-        "\x0b\x0b\x0b\x0b",
-        { 0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62,
-          0x6b, 0x08, 0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f,
-          0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6,
-          0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c,
-          0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f,
-          0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6 } },
-
-      { "data-50 key-20",
-        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-        "\xdd\xdd",
-       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa",
-        { 0x88, 0x06, 0x26, 0x08, 0xd3, 0xe6, 0xad, 0x8a,
-          0x0a, 0xa2, 0xac, 0xe0, 0x14, 0xc8, 0xa8, 0x6f,
-          0x0a, 0xa6, 0x35, 0xd9, 0x47, 0xac, 0x9f, 0xeb,
-          0xe8, 0x3e, 0xf4, 0xe5, 0x59, 0x66, 0x14, 0x4b,
-          0x2a, 0x5a, 0xb3, 0x9d, 0xc1, 0x38, 0x14, 0xb9,
-          0x4e, 0x3a, 0xb6, 0xe1, 0x01, 0xa3, 0x4f, 0x27 } },
-
-      { "data-50 key-26",
-        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-        "\xcd\xcd",
-       "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
-        "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
-        { 0x3e, 0x8a, 0x69, 0xb7, 0x78, 0x3c, 0x25, 0x85,
-          0x19, 0x33, 0xab, 0x62, 0x90, 0xaf, 0x6c, 0xa7,
-          0x7a, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9c,
-          0xc5, 0x57, 0x7c, 0x6e, 0x1f, 0x57, 0x3b, 0x4e,
-          0x68, 0x01, 0xdd, 0x23, 0xc4, 0xa7, 0xd6, 0x79,
-          0xcc, 0xf8, 0xa3, 0x86, 0xc6, 0x74, 0xcf, 0xfb } },
-
-      { "data-54 key-131",
-        "Test Using Larger Than Block-Size Key - Hash Key First",
-       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa",
-        { 0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90,
-          0x88, 0xd2, 0xc6, 0x3a, 0x04, 0x1b, 0xc5, 0xb4,
-          0x4f, 0x9e, 0xf1, 0x01, 0x2a, 0x2b, 0x58, 0x8f,
-          0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, 0xc4, 0xc6,
-          0x0c, 0x2e, 0xf6, 0xab, 0x40, 0x30, 0xfe, 0x82,
-          0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52 } },
-
-      { "data-152 key-131",
-        "This is a test using a larger than block-size key and a larger "
-        "than block-size data. The key needs to be hashed before being "
-        "used by the HMAC algorithm.",
-       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa",
-        { 0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d,
-          0x35, 0x1e, 0x2f, 0x25, 0x4e, 0x8f, 0xd3, 0x2c,
-          0x60, 0x24, 0x20, 0xfe, 0xb0, 0xb8, 0xfb, 0x9a,
-          0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e, 0x99, 0xc5,
-          0xa6, 0x78, 0xcc, 0x31, 0xe7, 0x99, 0x17, 0x6d,
-          0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e } },
-
-      { NULL }
-    };
-  const char *what;
-  const char *errtxt;
-  int tvidx;
-  
-  for (tvidx=0; tv[tvidx].desc; tvidx++)
-    {
-      what = tv[tvidx].desc;
-      errtxt = check_one (GCRY_MD_SHA384,
-                          tv[tvidx].data, strlen (tv[tvidx].data),
-                          tv[tvidx].key, strlen (tv[tvidx].key),
-                          tv[tvidx].expect, DIM (tv[tvidx].expect) );
-      if (errtxt)
-        goto failed;
-      if (!extended)
-        break;
-    }
-
-  return 0; /* Succeeded. */
-
- failed:
-  if (report)
-    report ("hmac", GCRY_MD_SHA384, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-
-static gpg_err_code_t
-selftests_sha512 (int extended, selftest_report_func_t report)
-{
-  static struct 
-  {
-    const char * const desc;
-    const char * const data;
-    const char * const key;
-    const char expect[64];
-  } tv[] =
-    {
-      { "data-28 key-4",
-        "what do ya want for nothing?", 
-        "Jefe",
-        { 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2,
-          0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3,
-          0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6,
-          0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54,
-          0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a,
-          0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd,
-          0xca, 0xea, 0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b,
-          0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37 } },
-
-      { "data-9 key-20",
-        "Hi There",
-       "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
-        "\x0b\x0b\x0b\x0b",
-        { 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d,
-          0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0,
-          0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78,
-          0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde,
-          0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02,
-          0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4,
-          0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70,
-          0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54 } },
-
-      { "data-50 key-20",
-        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
-        "\xdd\xdd",
-       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa",
-        { 0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84,
-          0xef, 0xb0, 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9,
-          0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36,
-          0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39,
-          0xbf, 0x3e, 0x84, 0x82, 0x79, 0xa7, 0x22, 0xc8,
-          0x06, 0xb4, 0x85, 0xa4, 0x7e, 0x67, 0xc8, 0x07,
-          0xb9, 0x46, 0xa3, 0x37, 0xbe, 0xe8, 0x94, 0x26,
-          0x74, 0x27, 0x88, 0x59, 0xe1, 0x32, 0x92, 0xfb } },
-
-      { "data-50 key-26",
-        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
-        "\xcd\xcd",
-       "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
-        "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
-        { 0xb0, 0xba, 0x46, 0x56, 0x37, 0x45, 0x8c, 0x69,
-          0x90, 0xe5, 0xa8, 0xc5, 0xf6, 0x1d, 0x4a, 0xf7,
-          0xe5, 0x76, 0xd9, 0x7f, 0xf9, 0x4b, 0x87, 0x2d,
-          0xe7, 0x6f, 0x80, 0x50, 0x36, 0x1e, 0xe3, 0xdb,
-          0xa9, 0x1c, 0xa5, 0xc1, 0x1a, 0xa2, 0x5e, 0xb4,
-          0xd6, 0x79, 0x27, 0x5c, 0xc5, 0x78, 0x80, 0x63,
-          0xa5, 0xf1, 0x97, 0x41, 0x12, 0x0c, 0x4f, 0x2d,
-          0xe2, 0xad, 0xeb, 0xeb, 0x10, 0xa2, 0x98, 0xdd } },
-
-      { "data-54 key-131",
-        "Test Using Larger Than Block-Size Key - Hash Key First",
-       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa",
-        { 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb,
-          0xb7, 0x14, 0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4,
-          0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1,
-          0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52,
-          0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98,
-          0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52,
-          0x95, 0xe6, 0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec,
-          0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98 } },
-
-      { "data-152 key-131",
-        "This is a test using a larger than block-size key and a larger "
-        "than block-size data. The key needs to be hashed before being "
-        "used by the HMAC algorithm.",
-       "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
-        "\xaa\xaa\xaa",
-        { 0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba,
-          0xa4, 0xdf, 0xa9, 0xf9, 0x6e, 0x5e, 0x3f, 0xfd,
-          0xde, 0xbd, 0x71, 0xf8, 0x86, 0x72, 0x89, 0x86,
-          0x5d, 0xf5, 0xa3, 0x2d, 0x20, 0xcd, 0xc9, 0x44,
-          0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, 0xb1,
-          0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15,
-          0x13, 0x46, 0x76, 0xfb, 0x6d, 0xe0, 0x44, 0x60,
-          0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58 } },
-
-      { NULL }
-    };
-  const char *what;
-  const char *errtxt;
-  int tvidx;
-  
-  for (tvidx=0; tv[tvidx].desc; tvidx++)
-    {
-      what = tv[tvidx].desc;
-      errtxt = check_one (GCRY_MD_SHA512,
-                          tv[tvidx].data, strlen (tv[tvidx].data),
-                          tv[tvidx].key, strlen (tv[tvidx].key),
-                          tv[tvidx].expect, DIM (tv[tvidx].expect) );
-      if (errtxt)
-        goto failed;
-      if (!extended)
-        break;
-    }
-
-  return 0; /* Succeeded. */
-
- failed:
-  if (report)
-    report ("hmac", GCRY_MD_SHA512, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-
-
-/* Run a full self-test for ALGO and return 0 on success.  */
-static gpg_err_code_t
-run_selftests (int algo, int extended, selftest_report_func_t report)
-{
-  gpg_err_code_t ec;
-
-  switch (algo)
-    {
-    case GCRY_MD_SHA1:
-      ec = selftests_sha1 (extended, report);
-      break;
-    case GCRY_MD_SHA224:
-      ec = selftests_sha224 (extended, report);
-      break;
-    case GCRY_MD_SHA256:
-      ec = selftests_sha256 (extended, report);
-      break;
-    case GCRY_MD_SHA384:
-      ec = selftests_sha384 (extended, report);
-      break;
-    case GCRY_MD_SHA512:
-      ec = selftests_sha512 (extended, report);
-      break;
-    default:
-      ec = GPG_ERR_DIGEST_ALGO;
-      break;
-    }
-  return ec;
-}
-
-
-
-
-/* Run the selftests for HMAC with digest algorithm ALGO with optional
-   reporting function REPORT.  */
-gpg_error_t
-_gcry_hmac_selftest (int algo, int extended, selftest_report_func_t report)
-{
-  gcry_err_code_t ec = 0;
-
-  if (!gcry_md_test_algo (algo))
-    {
-      ec = run_selftests (algo, extended, report);
-    }
-  else
-    {
-      ec = GPG_ERR_DIGEST_ALGO;
-      if (report)
-        report ("hmac", algo, "module", "algorithm not available");
-    }
-  return gpg_error (ec);
-}
diff --git a/lib/libgcrypt/cipher/md.c b/lib/libgcrypt/cipher/md.c
deleted file mode 100644 (file)
index 5dfbbd9..0000000
+++ /dev/null
@@ -1,1375 +0,0 @@
-/* md.c  -  message digest dispatcher
- * Copyright (C) 1998, 1999, 2002, 2003, 2006,
- *               2008 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#include "g10lib.h"
-#include "cipher.h"
-#include "ath.h"
-
-#include "rmd.h"
-
-/* A dummy extraspec so that we do not need to tests the extraspec
-   field from the module specification against NULL and instead
-   directly test the respective fields of extraspecs.  */
-static md_extra_spec_t dummy_extra_spec;
-
-
-/* This is the list of the digest implementations included in
-   libgcrypt.  */
-static struct digest_table_entry
-{
-  gcry_md_spec_t *digest;
-  md_extra_spec_t *extraspec;
-  unsigned int algorithm;
-  int fips_allowed; 
-} digest_table[] =
-  {
-#if USE_CRC    
-    /* We allow the CRC algorithms even in FIPS mode because they are
-       actually no cryptographic primitives.  */
-    { &_gcry_digest_spec_crc32,   
-      &dummy_extra_spec,                 GCRY_MD_CRC32, 1 },
-    { &_gcry_digest_spec_crc32_rfc1510,  
-      &dummy_extra_spec,                 GCRY_MD_CRC32_RFC1510, 1 },
-    { &_gcry_digest_spec_crc24_rfc2440,
-      &dummy_extra_spec,                 GCRY_MD_CRC24_RFC2440, 1 },
-#endif
-#if USE_MD4
-    { &_gcry_digest_spec_md4,
-      &dummy_extra_spec,                 GCRY_MD_MD4 },
-#endif
-#if USE_MD5
-    { &_gcry_digest_spec_md5,
-      &dummy_extra_spec,                 GCRY_MD_MD5, 1 },
-#endif
-#if USE_RMD160
-    { &_gcry_digest_spec_rmd160,
-      &dummy_extra_spec,                 GCRY_MD_RMD160 },
-#endif
-#if USE_SHA1
-    { &_gcry_digest_spec_sha1, 
-      &_gcry_digest_extraspec_sha1,      GCRY_MD_SHA1, 1 },
-#endif
-#if USE_SHA256
-    { &_gcry_digest_spec_sha256,
-      &_gcry_digest_extraspec_sha256,    GCRY_MD_SHA256, 1 },
-    { &_gcry_digest_spec_sha224,
-      &_gcry_digest_extraspec_sha224,    GCRY_MD_SHA224, 1 },
-#endif
-#if USE_SHA512
-    { &_gcry_digest_spec_sha512,
-      &_gcry_digest_extraspec_sha512,    GCRY_MD_SHA512, 1 },
-    { &_gcry_digest_spec_sha384,
-      &_gcry_digest_extraspec_sha384,    GCRY_MD_SHA384, 1 },
-#endif
-#if USE_TIGER
-    { &_gcry_digest_spec_tiger,
-      &dummy_extra_spec,                 GCRY_MD_TIGER },
-#endif
-#if USE_WHIRLPOOL
-    { &_gcry_digest_spec_whirlpool,
-      &dummy_extra_spec,                 GCRY_MD_WHIRLPOOL },
-#endif
-    { NULL },
-  };
-
-/* List of registered digests.  */
-static gcry_module_t digests_registered;
-
-/* This is the lock protecting DIGESTS_REGISTERED.  */
-static ath_mutex_t digests_registered_lock = ATH_MUTEX_INITIALIZER;
-
-/* Flag to check wether the default ciphers have already been
-   registered.  */
-static int default_digests_registered;
-
-typedef struct gcry_md_list
-{
-  gcry_md_spec_t *digest;
-  gcry_module_t module;
-  struct gcry_md_list *next;
-  size_t actual_struct_size;     /* Allocated size of this structure. */
-  PROPERLY_ALIGNED_TYPE context;
-} GcryDigestEntry;
-
-/* this structure is put right after the gcry_md_hd_t buffer, so that
- * only one memory block is needed. */
-struct gcry_md_context
-{
-  int  magic;
-  size_t actual_handle_size;     /* Allocated size of this handle. */
-  int  secure;
-  FILE  *debug;
-  int finalized;
-  GcryDigestEntry *list;
-  byte *macpads;
-  int macpads_Bsize;             /* Blocksize as used for the HMAC pads. */
-};
-
-
-#define CTX_MAGIC_NORMAL 0x11071961
-#define CTX_MAGIC_SECURE 0x16917011
-
-/* Convenient macro for registering the default digests.  */
-#define REGISTER_DEFAULT_DIGESTS                   \
-  do                                               \
-    {                                              \
-      ath_mutex_lock (&digests_registered_lock);   \
-      if (! default_digests_registered)            \
-        {                                          \
-          md_register_default ();                  \
-          default_digests_registered = 1;          \
-        }                                          \
-      ath_mutex_unlock (&digests_registered_lock); \
-    }                                              \
-  while (0)
-
-
-static const char * digest_algo_to_string( int algo );
-static gcry_err_code_t check_digest_algo (int algo);
-static gcry_err_code_t md_open (gcry_md_hd_t *h, int algo,
-                                int secure, int hmac);
-static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo);
-static gcry_err_code_t md_copy (gcry_md_hd_t a, gcry_md_hd_t *b);
-static void md_close (gcry_md_hd_t a);
-static void md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen);
-static void md_final(gcry_md_hd_t a);
-static byte *md_read( gcry_md_hd_t a, int algo );
-static int md_get_algo( gcry_md_hd_t a );
-static int md_digest_length( int algo );
-static const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen );
-static void md_start_debug ( gcry_md_hd_t a, const char *suffix );
-static void md_stop_debug ( gcry_md_hd_t a );
-
-
-
-
-/* Internal function.  Register all the ciphers included in
-   CIPHER_TABLE.  Returns zero on success or an error code.  */
-static void
-md_register_default (void)
-{
-  gcry_err_code_t err = 0;
-  int i;
-  
-  for (i = 0; !err && digest_table[i].digest; i++)
-    {
-      if ( fips_mode ())
-        {
-          if (!digest_table[i].fips_allowed)
-            continue;
-          if (digest_table[i].algorithm == GCRY_MD_MD5
-              && _gcry_enforced_fips_mode () )
-            continue;  /* Do not register in enforced fips mode.  */
-        }
-
-      err = _gcry_module_add (&digests_registered,
-                              digest_table[i].algorithm,
-                              (void *) digest_table[i].digest,
-                              (void *) digest_table[i].extraspec,
-                              NULL);
-    }
-
-  if (err)
-    BUG ();
-}
-
-/* Internal callback function.  */
-static int
-gcry_md_lookup_func_name (void *spec, void *data)
-{
-  gcry_md_spec_t *digest = (gcry_md_spec_t *) spec;
-  char *name = (char *) data;
-
-  return (! stricmp (digest->name, name));
-}
-
-/* Internal callback function.  Used via _gcry_module_lookup.  */
-static int
-gcry_md_lookup_func_oid (void *spec, void *data)
-{
-  gcry_md_spec_t *digest = (gcry_md_spec_t *) spec;
-  char *oid = (char *) data;
-  gcry_md_oid_spec_t *oid_specs = digest->oids;
-  int ret = 0, i;
-
-  if (oid_specs)
-    {
-      for (i = 0; oid_specs[i].oidstring && (! ret); i++)
-        if (! stricmp (oid, oid_specs[i].oidstring))
-          ret = 1;
-    }
-
-  return ret;
-}
-
-/* Internal function.  Lookup a digest entry by it's name.  */
-static gcry_module_t 
-gcry_md_lookup_name (const char *name)
-{
-  gcry_module_t digest;
-
-  digest = _gcry_module_lookup (digests_registered, (void *) name,
-                               gcry_md_lookup_func_name);
-
-  return digest;
-}
-
-/* Internal function.  Lookup a cipher entry by it's oid.  */
-static gcry_module_t
-gcry_md_lookup_oid (const char *oid)
-{
-  gcry_module_t digest;
-
-  digest = _gcry_module_lookup (digests_registered, (void *) oid,
-                               gcry_md_lookup_func_oid);
-
-  return digest;
-}
-
-/* Register a new digest module whose specification can be found in
-   DIGEST.  On success, a new algorithm ID is stored in ALGORITHM_ID
-   and a pointer representhing this module is stored in MODULE.  */
-gcry_error_t
-_gcry_md_register (gcry_md_spec_t *digest,
-                   md_extra_spec_t *extraspec,
-                   unsigned int *algorithm_id,
-                   gcry_module_t *module)
-{
-  gcry_err_code_t err = 0;
-  gcry_module_t mod;
-
-  /* We do not support module loading in fips mode.  */
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  ath_mutex_lock (&digests_registered_lock);
-  err = _gcry_module_add (&digests_registered, 0,
-                         (void *) digest, 
-                         (void *)(extraspec? extraspec : &dummy_extra_spec), 
-                          &mod);
-  ath_mutex_unlock (&digests_registered_lock);
-  
-  if (! err)
-    {
-      *module = mod;
-      *algorithm_id = mod->mod_id;
-    }
-
-  return gcry_error (err);
-}
-
-/* Unregister the digest identified by ID, which must have been
-   registered with gcry_digest_register.  */
-void
-gcry_md_unregister (gcry_module_t module)
-{
-  ath_mutex_lock (&digests_registered_lock);
-  _gcry_module_release (module);
-  ath_mutex_unlock (&digests_registered_lock);
-}
-
-
-static int 
-search_oid (const char *oid, int *algorithm, gcry_md_oid_spec_t *oid_spec)
-{
-  gcry_module_t module;
-  int ret = 0;
-
-  if (oid && ((! strncmp (oid, "oid.", 4))
-             || (! strncmp (oid, "OID.", 4))))
-    oid += 4;
-
-  module = gcry_md_lookup_oid (oid);
-  if (module)
-    {
-      gcry_md_spec_t *digest = module->spec;
-      int i;
-
-      for (i = 0; digest->oids[i].oidstring && !ret; i++)
-       if (! stricmp (oid, digest->oids[i].oidstring))
-         {
-           if (algorithm)
-             *algorithm = module->mod_id;
-           if (oid_spec)
-             *oid_spec = digest->oids[i];
-           ret = 1;
-         }
-      _gcry_module_release (module);
-    }
-
-  return ret;
-}
-
-/****************
- * Map a string to the digest algo
- */
-int
-gcry_md_map_name (const char *string)
-{
-  gcry_module_t digest;
-  int ret, algorithm = 0;
-
-  if (! string)
-    return 0;
-
-  REGISTER_DEFAULT_DIGESTS;
-
-  /* If the string starts with a digit (optionally prefixed with
-     either "OID." or "oid."), we first look into our table of ASN.1
-     object identifiers to figure out the algorithm */
-
-  ath_mutex_lock (&digests_registered_lock);
-
-  ret = search_oid (string, &algorithm, NULL);
-  if (! ret)
-    {
-      /* Not found, search a matching digest name.  */
-      digest = gcry_md_lookup_name (string);
-      if (digest)
-       {
-         algorithm = digest->mod_id;
-         _gcry_module_release (digest);
-       }
-    }
-  ath_mutex_unlock (&digests_registered_lock);
-
-  return algorithm;
-}
-
-
-/****************
- * Map a digest algo to a string
- */
-static const char *
-digest_algo_to_string (int algorithm)
-{
-  const char *name = NULL;
-  gcry_module_t digest;
-
-  REGISTER_DEFAULT_DIGESTS;
-
-  ath_mutex_lock (&digests_registered_lock);
-  digest = _gcry_module_lookup_id (digests_registered, algorithm);
-  if (digest)
-    {
-      name = ((gcry_md_spec_t *) digest->spec)->name;
-      _gcry_module_release (digest);
-    }
-  ath_mutex_unlock (&digests_registered_lock);
-
-  return name;
-}
-
-/****************
- * This function simply returns the name of the algorithm or some constant
- * string when there is no algo.  It will never return NULL.
- * Use the macro gcry_md_test_algo() to check whether the algorithm
- * is valid.
- */
-const char *
-gcry_md_algo_name (int algorithm)
-{
-  const char *s = digest_algo_to_string (algorithm);
-  return s ? s : "?";
-}
-
-
-static gcry_err_code_t
-check_digest_algo (int algorithm)
-{
-  gcry_err_code_t rc = 0;
-  gcry_module_t digest;
-
-  REGISTER_DEFAULT_DIGESTS;
-
-  ath_mutex_lock (&digests_registered_lock);
-  digest = _gcry_module_lookup_id (digests_registered, algorithm);
-  if (digest)
-    _gcry_module_release (digest);
-  else
-    rc = GPG_ERR_DIGEST_ALGO;
-  ath_mutex_unlock (&digests_registered_lock);
-
-  return rc;
-}
-
-
-
-/****************
- * Open a message digest handle for use with algorithm ALGO.
- * More algorithms may be added by md_enable(). The initial algorithm
- * may be 0.
- */
-static gcry_err_code_t
-md_open (gcry_md_hd_t *h, int algo, int secure, int hmac)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  int bufsize = secure ? 512 : 1024;
-  struct gcry_md_context *ctx;
-  gcry_md_hd_t hd;
-  size_t n;
-
-  /* Allocate a memory area to hold the caller visible buffer with it's
-   * control information and the data required by this module. Set the
-   * context pointer at the beginning to this area.
-   * We have to use this strange scheme because we want to hide the
-   * internal data but have a variable sized buffer.
-   *
-   *   +---+------+---........------+-------------+
-   *   !ctx! bctl !  buffer         ! private     !
-   *   +---+------+---........------+-------------+
-   *     !                           ^
-   *     !---------------------------!
-   *
-   * We have to make sure that private is well aligned.
-   */
-  n = sizeof (struct gcry_md_handle) + bufsize;
-  n = ((n + sizeof (PROPERLY_ALIGNED_TYPE) - 1)
-       / sizeof (PROPERLY_ALIGNED_TYPE)) * sizeof (PROPERLY_ALIGNED_TYPE);
-
-  /* Allocate and set the Context pointer to the private data */
-  if (secure)
-    hd = gcry_malloc_secure (n + sizeof (struct gcry_md_context));
-  else
-    hd = gcry_malloc (n + sizeof (struct gcry_md_context));
-
-  if (! hd)
-    err = gpg_err_code_from_errno (errno);
-
-  if (! err)
-    {
-      hd->ctx = ctx = (struct gcry_md_context *) ((char *) hd + n);
-      /* Setup the globally visible data (bctl in the diagram).*/
-      hd->bufsize = n - sizeof (struct gcry_md_handle) + 1;
-      hd->bufpos = 0;
-
-      /* Initialize the private data. */
-      memset (hd->ctx, 0, sizeof *hd->ctx);
-      ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
-      ctx->actual_handle_size = n + sizeof (struct gcry_md_context);
-      ctx->secure = secure;
-
-      if (hmac)
-       {
-         switch (algo)
-            {
-              case GCRY_MD_SHA384:
-              case GCRY_MD_SHA512:
-                ctx->macpads_Bsize = 128;
-                break;
-              default:
-                ctx->macpads_Bsize = 64;
-                break;
-            }
-          ctx->macpads = gcry_malloc_secure (2*(ctx->macpads_Bsize));
-         if (!ctx->macpads)
-           {
-             err = gpg_err_code_from_errno (errno);
-             md_close (hd);
-           }
-       }
-    }
-
-  if (! err)
-    {
-      /* Hmmm, should we really do that? - yes [-wk] */
-      _gcry_fast_random_poll ();
-
-      if (algo)
-       {
-         err = md_enable (hd, algo);
-         if (err)
-           md_close (hd);
-       }
-    }
-
-  if (! err)
-    *h = hd;
-
-  return err;
-}
-
-/* Create a message digest object for algorithm ALGO.  FLAGS may be
-   given as an bitwise OR of the gcry_md_flags values.  ALGO may be
-   given as 0 if the algorithms to be used are later set using
-   gcry_md_enable. H is guaranteed to be a valid handle or NULL on
-   error.  */
-gcry_error_t
-gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_md_hd_t hd;
-
-  if ((flags & ~(GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC)))
-    err = GPG_ERR_INV_ARG;
-  else
-    {
-      err = md_open (&hd, algo, (flags & GCRY_MD_FLAG_SECURE),
-                    (flags & GCRY_MD_FLAG_HMAC));
-    }
-
-  *h = err? NULL : hd;
-  return gcry_error (err);
-}
-
-
-
-static gcry_err_code_t
-md_enable (gcry_md_hd_t hd, int algorithm)
-{
-  struct gcry_md_context *h = hd->ctx;
-  gcry_md_spec_t *digest = NULL;
-  GcryDigestEntry *entry;
-  gcry_module_t module;
-  gcry_err_code_t err = 0;
-
-  for (entry = h->list; entry; entry = entry->next)
-    if (entry->module->mod_id == algorithm)
-      return err; /* already enabled */
-
-  REGISTER_DEFAULT_DIGESTS;
-
-  ath_mutex_lock (&digests_registered_lock);
-  module = _gcry_module_lookup_id (digests_registered, algorithm);
-  ath_mutex_unlock (&digests_registered_lock);
-  if (! module)
-    {
-      log_debug ("md_enable: algorithm %d not available\n", algorithm);
-      err = GPG_ERR_DIGEST_ALGO;
-    }
- else
-    digest = (gcry_md_spec_t *) module->spec;
-
-  
-  if (!err && algorithm == GCRY_MD_MD5 && fips_mode ())
-    {
-      _gcry_inactivate_fips_mode ("MD5 used");
-      if (_gcry_enforced_fips_mode () )
-        {
-          /* We should never get to here because we do not register
-             MD5 in enforced fips mode. But better throw an error.  */
-          err = GPG_ERR_DIGEST_ALGO;
-        }
-    }
-  
-  if (!err)
-    {
-      size_t size = (sizeof (*entry)
-                     + digest->contextsize
-                     - sizeof (entry->context));
-
-      /* And allocate a new list entry. */
-      if (h->secure)
-       entry = gcry_malloc_secure (size);
-      else
-       entry = gcry_malloc (size);
-
-      if (! entry)
-       err = gpg_err_code_from_errno (errno);
-      else
-       {
-         entry->digest = digest;
-         entry->module = module;
-         entry->next = h->list;
-          entry->actual_struct_size = size;
-         h->list = entry;
-
-         /* And init this instance. */
-         entry->digest->init (&entry->context.c);
-       }
-    }
-
-  if (err)
-    {
-      if (module)
-       {
-          ath_mutex_lock (&digests_registered_lock);
-          _gcry_module_release (module);
-          ath_mutex_unlock (&digests_registered_lock);
-       }
-    }
-
-  return err;
-}
-
-
-gcry_error_t
-gcry_md_enable (gcry_md_hd_t hd, int algorithm)
-{
-  return gcry_error (md_enable (hd, algorithm));
-}
-
-static gcry_err_code_t
-md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  struct gcry_md_context *a = ahd->ctx;
-  struct gcry_md_context *b;
-  GcryDigestEntry *ar, *br;
-  gcry_md_hd_t bhd;
-  size_t n;
-  
-  if (ahd->bufpos)
-    md_write (ahd, NULL, 0);
-
-  n = (char *) ahd->ctx - (char *) ahd;
-  if (a->secure)
-    bhd = gcry_malloc_secure (n + sizeof (struct gcry_md_context));
-  else
-    bhd = gcry_malloc (n + sizeof (struct gcry_md_context));
-
-  if (! bhd)
-    err = gpg_err_code_from_errno (errno);
-
-  if (! err)
-    {
-      bhd->ctx = b = (struct gcry_md_context *) ((char *) bhd + n);
-      /* No need to copy the buffer due to the write above. */
-      gcry_assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1));
-      bhd->bufsize = ahd->bufsize;
-      bhd->bufpos = 0;
-      gcry_assert (! ahd->bufpos);
-      memcpy (b, a, sizeof *a);
-      b->list = NULL;
-      b->debug = NULL;
-      if (a->macpads)
-       {
-         b->macpads = gcry_malloc_secure (2*(a->macpads_Bsize));
-         if (! b->macpads)
-           {
-             err = gpg_err_code_from_errno (errno);
-             md_close (bhd);
-           }
-         else
-           memcpy (b->macpads, a->macpads, (2*(a->macpads_Bsize)));
-       }
-    }
-
-  /* Copy the complete list of algorithms.  The copied list is
-     reversed, but that doesn't matter. */
-  if (!err)
-    {
-      for (ar = a->list; ar; ar = ar->next)
-        {
-          if (a->secure)
-            br = gcry_malloc_secure (sizeof *br
-                                     + ar->digest->contextsize
-                                     - sizeof(ar->context));
-          else
-            br = gcry_malloc (sizeof *br
-                              + ar->digest->contextsize
-                              - sizeof (ar->context));
-          if (!br)
-            {
-             err = gpg_err_code_from_errno (errno);
-              md_close (bhd);
-              break;
-            }
-
-          memcpy (br, ar, (sizeof (*br) + ar->digest->contextsize
-                           - sizeof (ar->context)));
-          br->next = b->list;
-          b->list = br;
-          
-          /* Add a reference to the module.  */
-          ath_mutex_lock (&digests_registered_lock);
-          _gcry_module_use (br->module);
-          ath_mutex_unlock (&digests_registered_lock);
-        }
-    }
-
-  if (a->debug && !err)
-    md_start_debug (bhd, "unknown");
-
-  if (!err)
-    *b_hd = bhd;
-
-  return err;
-}
-
-gcry_error_t
-gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
-{
-  gcry_err_code_t err;
-
-  err = md_copy (hd, handle);
-  if (err)
-    *handle = NULL;
-  return gcry_error (err);
-}
-
-/*
- * Reset all contexts and discard any buffered stuff.  This may be used
- * instead of a md_close(); md_open().
- */
-void
-gcry_md_reset (gcry_md_hd_t a)
-{
-  GcryDigestEntry *r;
-
-  /* Note: We allow this even in fips non operational mode.  */
-
-  a->bufpos = a->ctx->finalized = 0;
-
-  for (r = a->ctx->list; r; r = r->next)
-    {
-      memset (r->context.c, 0, r->digest->contextsize);
-      (*r->digest->init) (&r->context.c);
-    }
-  if (a->ctx->macpads)
-    md_write (a, a->ctx->macpads, a->ctx->macpads_Bsize); /* inner pad */
-}
-
-static void
-md_close (gcry_md_hd_t a)
-{
-  GcryDigestEntry *r, *r2;
-
-  if (! a)
-    return;
-  if (a->ctx->debug)
-    md_stop_debug (a);
-  for (r = a->ctx->list; r; r = r2)
-    {
-      r2 = r->next;
-      ath_mutex_lock (&digests_registered_lock);
-      _gcry_module_release (r->module);
-      ath_mutex_unlock (&digests_registered_lock);
-      wipememory (r, r->actual_struct_size);
-      gcry_free (r);
-    }
-
-  if (a->ctx->macpads)
-    {
-      wipememory (a->ctx->macpads, 2*(a->ctx->macpads_Bsize));
-      gcry_free(a->ctx->macpads);
-    }
-
-  wipememory (a, a->ctx->actual_handle_size);
-  gcry_free(a);
-}
-
-void
-gcry_md_close (gcry_md_hd_t hd)
-{
-  /* Note: We allow this even in fips non operational mode.  */
-  md_close (hd);
-}
-
-static void
-md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
-{
-  GcryDigestEntry *r;
-  
-  if (a->ctx->debug)
-    {
-      if (a->bufpos && fwrite (a->buf, a->bufpos, 1, a->ctx->debug) != 1)
-       BUG();
-      if (inlen && fwrite (inbuf, inlen, 1, a->ctx->debug) != 1)
-       BUG();
-    }
-
-  for (r = a->ctx->list; r; r = r->next)
-    {
-      if (a->bufpos)
-       (*r->digest->write) (&r->context.c, a->buf, a->bufpos);
-      (*r->digest->write) (&r->context.c, inbuf, inlen);
-    }
-  a->bufpos = 0;
-}
-
-void
-gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen)
-{
-  md_write (hd, inbuf, inlen);
-}
-
-static void
-md_final (gcry_md_hd_t a)
-{
-  GcryDigestEntry *r;
-
-  if (a->ctx->finalized)
-    return;
-
-  if (a->bufpos)
-    md_write (a, NULL, 0);
-
-  for (r = a->ctx->list; r; r = r->next)
-    (*r->digest->final) (&r->context.c);
-
-  a->ctx->finalized = 1;
-
-  if (a->ctx->macpads)
-    {
-      /* Finish the hmac. */
-      int algo = md_get_algo (a);
-      byte *p = md_read (a, algo);
-      size_t dlen = md_digest_length (algo);
-      gcry_md_hd_t om;
-      gcry_err_code_t err = md_open (&om, algo, a->ctx->secure, 0);
-
-      if (err)
-       _gcry_fatal_error (err, NULL);
-      md_write (om, 
-                (a->ctx->macpads)+(a->ctx->macpads_Bsize), 
-                a->ctx->macpads_Bsize);
-      md_write (om, p, dlen);
-      md_final (om);
-      /* Replace our digest with the mac (they have the same size). */
-      memcpy (p, md_read (om, algo), dlen);
-      md_close (om);
-    }
-}
-
-static gcry_err_code_t
-prepare_macpads (gcry_md_hd_t hd, const unsigned char *key, size_t keylen)
-{
-  int i;
-  int algo = md_get_algo (hd);
-  unsigned char *helpkey = NULL;
-  unsigned char *ipad, *opad;
-
-  if (!algo)
-    return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled.  */
-
-  if ( keylen > hd->ctx->macpads_Bsize ) 
-    {
-      helpkey = gcry_malloc_secure (md_digest_length (algo));
-      if (!helpkey)
-        return gpg_err_code_from_errno (errno);
-      gcry_md_hash_buffer (algo, helpkey, key, keylen);
-      key = helpkey;
-      keylen = md_digest_length (algo);
-      gcry_assert ( keylen <= hd->ctx->macpads_Bsize );
-    }
-
-  memset ( hd->ctx->macpads, 0, 2*(hd->ctx->macpads_Bsize) );
-  ipad = hd->ctx->macpads;
-  opad = (hd->ctx->macpads)+(hd->ctx->macpads_Bsize);
-  memcpy ( ipad, key, keylen );
-  memcpy ( opad, key, keylen );
-  for (i=0; i < hd->ctx->macpads_Bsize; i++ ) 
-    {
-      ipad[i] ^= 0x36;
-      opad[i] ^= 0x5c;
-    }
-  gcry_free (helpkey);
-
-  return GPG_ERR_NO_ERROR;
-}
-
-gcry_error_t
-gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
-{
-  gcry_err_code_t rc = 0;
-  
-  switch (cmd)
-    {
-    case GCRYCTL_FINALIZE:
-      md_final (hd);
-      break;
-    case GCRYCTL_SET_KEY:
-      rc = gcry_err_code (gcry_md_setkey (hd, buffer, buflen));
-      break;
-    case GCRYCTL_START_DUMP:
-      md_start_debug (hd, buffer);
-      break;
-    case GCRYCTL_STOP_DUMP:
-      md_stop_debug ( hd );
-      break;
-    default:
-      rc = GPG_ERR_INV_OP;
-    }
-  return gcry_error (rc);
-}
-
-gcry_error_t
-gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
-{
-  gcry_err_code_t rc = GPG_ERR_NO_ERROR;
-
-  if (!hd->ctx->macpads)
-    rc = GPG_ERR_CONFLICT;
-  else
-    {
-      rc = prepare_macpads (hd, key, keylen);
-      if (! rc)
-       gcry_md_reset (hd);
-    }
-
-  return gcry_error (rc);
-}
-
-/* The new debug interface.  If SUFFIX is a string it creates an debug
-   file for the context HD.  IF suffix is NULL, the file is closed and
-   debugging is stopped.  */
-void
-gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
-{
-  if (suffix)
-    md_start_debug (hd, suffix);
-  else
-    md_stop_debug (hd);
-}
-
-
-
-/****************
- * if ALGO is null get the digest for the used algo (which should be only one)
- */
-static byte *
-md_read( gcry_md_hd_t a, int algo )
-{
-  GcryDigestEntry *r = a->ctx->list;
-
-  if (! algo)
-    {
-      /* return the first algorithm */
-      if (r && r->next)
-       log_debug ("more than one algorithm in md_read(0)\n");
-      return r->digest->read( &r->context.c );
-    }
-  else
-    {
-      for (r = a->ctx->list; r; r = r->next)
-       if (r->module->mod_id == algo)
-         return r->digest->read (&r->context.c);
-    }
-  BUG();
-  return NULL;
-}
-
-/*
- * Read out the complete digest, this function implictly finalizes
- * the hash.
- */
-byte *
-gcry_md_read (gcry_md_hd_t hd, int algo)
-{
-  /* This function is expected to always return a digest, thus we
-     can't return an error which we actually should do in
-     non-operational state.  */
-  gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
-  return md_read (hd, algo);
-}
-
-
-/*
- * Read out an intermediate digest.  Not yet functional.
- */
-gcry_err_code_t
-gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen)
-{
-  (void)hd;
-  (void)algo;
-  (void)buffer;
-  (void)buflen;
-
-  /*md_digest ... */
-  fips_signal_error ("unimplemented function called");
-  return GPG_ERR_INTERNAL;
-}
-
-
-/*
- * Shortcut function to hash a buffer with a given algo. The only
- * guaranteed supported algorithms are RIPE-MD160 and SHA-1. The
- * supplied digest buffer must be large enough to store the resulting
- * hash.  No error is returned, the function will abort on an invalid
- * algo.  DISABLED_ALGOS are ignored here.  */
-void
-gcry_md_hash_buffer (int algo, void *digest,
-                     const void *buffer, size_t length)
-{
-  if (algo == GCRY_MD_SHA1)
-    _gcry_sha1_hash_buffer (digest, buffer, length);
-  else if (algo == GCRY_MD_RMD160 && !fips_mode () )
-    _gcry_rmd160_hash_buffer (digest, buffer, length);
-  else
-    {
-      /* For the others we do not have a fast function, so we use the
-        normal functions. */
-      gcry_md_hd_t h;
-      gpg_err_code_t err;
-
-      if (algo == GCRY_MD_MD5 && fips_mode ())
-        {
-          _gcry_inactivate_fips_mode ("MD5 used");
-          if (_gcry_enforced_fips_mode () )
-            {
-              /* We should never get to here because we do not register
-                 MD5 in enforced fips mode.  */
-              _gcry_fips_noreturn ();
-            }
-        }
-
-      err = md_open (&h, algo, 0, 0);
-      if (err)
-       log_bug ("gcry_md_open failed for algo %d: %s",
-                 algo, gpg_strerror (gcry_error(err)));
-      md_write (h, (byte *) buffer, length);
-      md_final (h);
-      memcpy (digest, md_read (h, algo), md_digest_length (algo));
-      md_close (h);
-    }
-}
-
-static int
-md_get_algo (gcry_md_hd_t a)
-{
-  GcryDigestEntry *r = a->ctx->list;
-
-  if (r && r->next)
-    {
-      fips_signal_error ("possible usage error");
-      log_error ("WARNING: more than one algorithm in md_get_algo()\n");
-    }
-  return r ? r->module->mod_id : 0;
-}
-
-int
-gcry_md_get_algo (gcry_md_hd_t hd)
-{
-  return md_get_algo (hd);
-}
-
-
-/****************
- * Return the length of the digest
- */
-static int
-md_digest_length (int algorithm)
-{
-  gcry_module_t digest;
-  int mdlen = 0;
-
-  REGISTER_DEFAULT_DIGESTS;
-
-  ath_mutex_lock (&digests_registered_lock);
-  digest = _gcry_module_lookup_id (digests_registered, algorithm);
-  if (digest)
-    {
-      mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen;
-      _gcry_module_release (digest);
-    }
-  ath_mutex_unlock (&digests_registered_lock);
-
-  return mdlen;
-}
-
-/****************
- * Return the length of the digest in bytes.
- * This function will return 0 in case of errors.
- */
-unsigned int
-gcry_md_get_algo_dlen (int algorithm)
-{
-  return md_digest_length (algorithm);
-}
-
-
-/* Hmmm: add a mode to enumerate the OIDs
- *     to make g10/sig-check.c more portable */
-static const byte *
-md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
-{
-  const byte *asnoid = NULL;
-  gcry_module_t digest;
-
-  REGISTER_DEFAULT_DIGESTS;
-
-  ath_mutex_lock (&digests_registered_lock);
-  digest = _gcry_module_lookup_id (digests_registered, algorithm);
-  if (digest)
-    {
-      if (asnlen)
-       *asnlen = ((gcry_md_spec_t *) digest->spec)->asnlen;
-      if (mdlen)
-       *mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen;
-      asnoid = ((gcry_md_spec_t *) digest->spec)->asnoid;
-      _gcry_module_release (digest);
-    }
-  else
-    log_bug ("no ASN.1 OID for md algo %d\n", algorithm);
-  ath_mutex_unlock (&digests_registered_lock);
-
-  return asnoid;
-}
-
-
-
-/****************
- * Return information about the given cipher algorithm
- * WHAT select the kind of information returned:
- *  GCRYCTL_TEST_ALGO:
- *     Returns 0 when the specified algorithm is available for use.
- *     buffer and nbytes must be zero.
- *  GCRYCTL_GET_ASNOID:
- *     Return the ASNOID of the algorithm in buffer. if buffer is NULL, only
- *     the required length is returned.
- *
- * Note:  Because this function is in most cases used to return an
- * integer value, we can make it easier for the caller to just look at
- * the return value.  The caller will in all cases consult the value
- * and thereby detecting whether a error occured or not (i.e. while checking
- * the block size)
- */
-gcry_error_t
-gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  switch (what)
-    {
-    case GCRYCTL_TEST_ALGO:
-      if (buffer || nbytes)
-       err = GPG_ERR_INV_ARG;
-      else
-       err = check_digest_algo (algo);
-      break;
-
-    case GCRYCTL_GET_ASNOID:
-      /* We need to check that the algo is available because
-         md_asn_oid would otherwise raise an assertion. */
-      err = check_digest_algo (algo);
-      if (!err)
-        {
-          const char unsigned *asn;
-          size_t asnlen;
-          
-          asn = md_asn_oid (algo, &asnlen, NULL);
-          if (buffer && (*nbytes >= asnlen))
-         {
-           memcpy (buffer, asn, asnlen);
-           *nbytes = asnlen;
-         }
-          else if (!buffer && nbytes)
-            *nbytes = asnlen;
-          else
-            {
-              if (buffer)
-                err = GPG_ERR_TOO_SHORT;
-              else
-                err = GPG_ERR_INV_ARG;
-            }
-        }
-      break;
-
-  default:
-    err = GPG_ERR_INV_OP;
-  }
-
-  return gcry_error (err);
-}
-
-
-static void
-md_start_debug ( gcry_md_hd_t md, const char *suffix )
-{
-  static int idx=0;
-  char buf[50];
-
-  if (fips_mode ())
-    return;
-  
-  if ( md->ctx->debug )
-    {
-      log_debug("Oops: md debug already started\n");
-      return;
-    }
-  idx++;
-  snprintf (buf, DIM(buf)-1, "dbgmd-%05d.%.10s", idx, suffix );
-  md->ctx->debug = fopen(buf, "w");
-  if ( !md->ctx->debug )
-    log_debug("md debug: can't open %s\n", buf );
-}
-
-static void
-md_stop_debug( gcry_md_hd_t md )
-{
-  if ( md->ctx->debug )
-    {
-      if ( md->bufpos )
-        md_write ( md, NULL, 0 );
-      fclose (md->ctx->debug);
-      md->ctx->debug = NULL;
-    }
-
-#ifdef HAVE_U64_TYPEDEF
-  {  /* a kludge to pull in the __muldi3 for Solaris */
-    volatile u32 a = (u32)(ulong)md;
-    volatile u64 b = 42;
-    volatile u64 c;
-    c = a * b;
-  }
-#endif
-}
-
-
-
-/*
- * Return information about the digest handle.
- *  GCRYCTL_IS_SECURE:
- *     Returns 1 when the handle works on secured memory
- *     otherwise 0 is returned.  There is no error return.
- *  GCRYCTL_IS_ALGO_ENABLED:
- *     Returns 1 if the algo is enabled for that handle.
- *     The algo must be passed as the address of an int.
- */
-gcry_error_t
-gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  switch (cmd)
-    {
-    case GCRYCTL_IS_SECURE:
-      *nbytes = h->ctx->secure;
-      break;
-
-    case GCRYCTL_IS_ALGO_ENABLED:
-      {
-       GcryDigestEntry *r;
-       int algo;
-
-       if ( !buffer || (nbytes && (*nbytes != sizeof (int))))
-         err = GPG_ERR_INV_ARG;
-       else
-         {
-           algo = *(int*)buffer;
-           
-           *nbytes = 0;
-           for(r=h->ctx->list; r; r = r->next ) {
-             if (r->module->mod_id == algo)
-               {
-                 *nbytes = 1;
-                 break;
-               }
-           }
-         }
-       break;
-      }
-
-  default:
-    err = GPG_ERR_INV_OP;
-  }
-
-  return gcry_error (err);
-}
-
-
-/* Explicitly initialize this module.  */
-gcry_err_code_t
-_gcry_md_init (void)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  REGISTER_DEFAULT_DIGESTS;
-
-  return err;
-}
-
-
-int
-gcry_md_is_secure (gcry_md_hd_t a) 
-{
-  size_t value;
-
-  if (gcry_md_info (a, GCRYCTL_IS_SECURE, NULL, &value))
-    value = 1; /* It seems to be better to assume secure memory on
-                  error. */
-  return value;
-}
-
-
-int
-gcry_md_is_enabled (gcry_md_hd_t a, int algo) 
-{
-  size_t value;
-
-  value = sizeof algo;
-  if (gcry_md_info (a, GCRYCTL_IS_ALGO_ENABLED, &algo, &value))
-    value = 0;
-  return value;
-}
-
-/* Get a list consisting of the IDs of the loaded message digest
-   modules.  If LIST is zero, write the number of loaded message
-   digest modules to LIST_LENGTH and return.  If LIST is non-zero, the
-   first *LIST_LENGTH algorithm IDs are stored in LIST, which must be
-   of according size.  In case there are less message digest modules
-   than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
-   number.  */
-gcry_error_t
-gcry_md_list (int *list, int *list_length)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  ath_mutex_lock (&digests_registered_lock);
-  err = _gcry_module_list (digests_registered, list, list_length);
-  ath_mutex_unlock (&digests_registered_lock);
-
-  return err;
-}
-
-
-/* Run the selftests for digest algorithm ALGO with optional reporting
-   function REPORT.  */
-gpg_error_t
-_gcry_md_selftest (int algo, int extended, selftest_report_func_t report)
-{
-  gcry_module_t module = NULL;
-  cipher_extra_spec_t *extraspec = NULL;
-  gcry_err_code_t ec = 0;
-
-  REGISTER_DEFAULT_DIGESTS;
-
-  ath_mutex_lock (&digests_registered_lock);
-  module = _gcry_module_lookup_id (digests_registered, algo);
-  if (module && !(module->flags & FLAG_MODULE_DISABLED))
-    extraspec = module->extraspec;
-  ath_mutex_unlock (&digests_registered_lock);
-  if (extraspec && extraspec->selftest)
-    ec = extraspec->selftest (algo, extended, report);
-  else
-    {
-      ec = GPG_ERR_DIGEST_ALGO;
-      if (report)
-        report ("digest", algo, "module", 
-                module && !(module->flags & FLAG_MODULE_DISABLED)?
-                "no selftest available" :
-                module? "algorithm disabled" : "algorithm not found");
-    }
-
-  if (module)
-    {
-      ath_mutex_lock (&digests_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&digests_registered_lock);
-    }
-  return gpg_error (ec);
-}
diff --git a/lib/libgcrypt/cipher/md4.c b/lib/libgcrypt/cipher/md4.c
deleted file mode 100644 (file)
index 680cf87..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/* md4.c - MD4 Message-Digest Algorithm
- * Copyright (C) 2002, 2003 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * Based on md5.c in libgcrypt, but rewritten to compute md4 checksums
- * using a public domain md4 implementation with the following comments:
- *
- * Modified by Wei Dai from Andrew M. Kuchling's md4.c
- * The original code and all modifications are in the public domain.
- *
- * This is the original introductory comment:
- *
- *  md4.c : MD4 hash algorithm.
- *
- * Part of the Python Cryptography Toolkit, version 1.1
- *
- * Distribute and use freely; there are no restrictions on further
- * dissemination and usage except those imposed by the laws of your
- * country of residence.
- *
- */
-
-/* MD4 test suite:
- * MD4 ("") = 31d6cfe0d16ae931b73c59d7e0c089c0
- * MD4 ("a") = bde52cb31de33e46245e05fbdbd6fb24
- * MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d
- * MD4 ("message digest") = d9130a8164549fe818874806e1c7014b
- * MD4 ("abcdefghijklmnopqrstuvwxyz") = d79e1c308aa5bbcdeea8ed63df412da9
- * MD4 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
- * 043f8582f241db351ce627e153e7f0e4
- * MD4 ("123456789012345678901234567890123456789012345678901234567890123456
- * 78901234567890") = e33b4ddc9c38f2199c3e7b164fcc0536
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "g10lib.h"
-#include "memory.h"
-#include "cipher.h"
-
-#include "bithelp.h"
-
-
-typedef struct {
-    u32 A,B,C,D;         /* chaining variables */
-    u32  nblocks;
-    byte buf[64];
-    int  count;
-} MD4_CONTEXT;
-
-
-static void
-md4_init( void *context )
-{
-  MD4_CONTEXT *ctx = context;
-
-  ctx->A = 0x67452301;
-  ctx->B = 0xefcdab89;
-  ctx->C = 0x98badcfe;
-  ctx->D = 0x10325476;
-
-  ctx->nblocks = 0;
-  ctx->count = 0;
-}
-
-#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
-#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-
-
-/****************
- * transform 64 bytes
- */
-static void
-transform ( MD4_CONTEXT *ctx, const unsigned char *data )
-{
-  u32 in[16];
-  register u32 A = ctx->A;
-  register u32 B = ctx->B;
-  register u32 C = ctx->C;
-  register u32 D = ctx->D;
-
-#ifdef WORDS_BIGENDIAN
-  {
-    int i;
-    byte *p2, *p1;
-    for(i=0, p1=data, p2=(byte*)in; i < 16; i++, p2 += 4 )
-      {
-       p2[3] = *p1++;
-       p2[2] = *p1++;
-       p2[1] = *p1++;
-       p2[0] = *p1++;
-      }
-  }
-#else
-  memcpy (in, data, 64);
-#endif
-
-  /* Round 1.  */
-#define function(a,b,c,d,k,s) a=rol(a+F(b,c,d)+in[k],s);
-  function(A,B,C,D, 0, 3);
-  function(D,A,B,C, 1, 7);
-  function(C,D,A,B, 2,11);
-  function(B,C,D,A, 3,19);
-  function(A,B,C,D, 4, 3);
-  function(D,A,B,C, 5, 7);
-  function(C,D,A,B, 6,11);
-  function(B,C,D,A, 7,19);
-  function(A,B,C,D, 8, 3);
-  function(D,A,B,C, 9, 7);
-  function(C,D,A,B,10,11);
-  function(B,C,D,A,11,19);
-  function(A,B,C,D,12, 3);
-  function(D,A,B,C,13, 7);
-  function(C,D,A,B,14,11);
-  function(B,C,D,A,15,19);
-
-#undef function
-
-  /* Round 2.  */
-#define function(a,b,c,d,k,s) a=rol(a+G(b,c,d)+in[k]+0x5a827999,s);
-
-  function(A,B,C,D, 0, 3);
-  function(D,A,B,C, 4, 5);
-  function(C,D,A,B, 8, 9);
-  function(B,C,D,A,12,13);
-  function(A,B,C,D, 1, 3);
-  function(D,A,B,C, 5, 5);
-  function(C,D,A,B, 9, 9);
-  function(B,C,D,A,13,13);
-  function(A,B,C,D, 2, 3);
-  function(D,A,B,C, 6, 5);
-  function(C,D,A,B,10, 9);
-  function(B,C,D,A,14,13);
-  function(A,B,C,D, 3, 3);
-  function(D,A,B,C, 7, 5);
-  function(C,D,A,B,11, 9);
-  function(B,C,D,A,15,13);
-
-#undef function
-
-  /* Round 3.  */
-#define function(a,b,c,d,k,s) a=rol(a+H(b,c,d)+in[k]+0x6ed9eba1,s);
-
-  function(A,B,C,D, 0, 3);
-  function(D,A,B,C, 8, 9);
-  function(C,D,A,B, 4,11);
-  function(B,C,D,A,12,15);
-  function(A,B,C,D, 2, 3);
-  function(D,A,B,C,10, 9);
-  function(C,D,A,B, 6,11);
-  function(B,C,D,A,14,15);
-  function(A,B,C,D, 1, 3);
-  function(D,A,B,C, 9, 9);
-  function(C,D,A,B, 5,11);
-  function(B,C,D,A,13,15);
-  function(A,B,C,D, 3, 3);
-  function(D,A,B,C,11, 9);
-  function(C,D,A,B, 7,11);
-  function(B,C,D,A,15,15);
-
-
-  /* Put checksum in context given as argument.  */
-  ctx->A += A;
-  ctx->B += B;
-  ctx->C += C;
-  ctx->D += D;
-}
-
-
-
-/* The routine updates the message-digest context to
- * account for the presence of each of the characters inBuf[0..inLen-1]
- * in the message whose digest is being computed.
- */
-static void
-md4_write ( void *context, const void *inbuf_arg, size_t inlen)
-{
-  const unsigned char *inbuf = inbuf_arg;
-  MD4_CONTEXT *hd = context;
-
-  if( hd->count == 64 ) /* flush the buffer */
-    { 
-      transform( hd, hd->buf );
-      _gcry_burn_stack (80+6*sizeof(void*));
-      hd->count = 0;
-      hd->nblocks++;
-    }
-  if( !inbuf )
-    return;
-
-  if( hd->count )
-    {
-      for( ; inlen && hd->count < 64; inlen-- )
-        hd->buf[hd->count++] = *inbuf++;
-      md4_write( hd, NULL, 0 );
-      if( !inlen )
-        return;
-    }
-  _gcry_burn_stack (80+6*sizeof(void*));
-
-  while( inlen >= 64 )
-    {
-      transform( hd, inbuf );
-      hd->count = 0;
-      hd->nblocks++;
-      inlen -= 64;
-      inbuf += 64;
-    }
-  for( ; inlen && hd->count < 64; inlen-- )
-    hd->buf[hd->count++] = *inbuf++;
-}
-
-
-
-/* The routine final terminates the message-digest computation and
- * ends with the desired message digest in mdContext->digest[0...15].
- * The handle is prepared for a new MD4 cycle.
- * Returns 16 bytes representing the digest.
- */
-
-static void
-md4_final( void *context )
-{
-  MD4_CONTEXT *hd = context;
-  u32 t, msb, lsb;
-  byte *p;
-
-  md4_write(hd, NULL, 0); /* flush */;
-
-  t = hd->nblocks;
-  /* multiply by 64 to make a byte count */
-  lsb = t << 6;
-  msb = t >> 26;
-  /* add the count */
-  t = lsb;
-  if( (lsb += hd->count) < t )
-    msb++;
-  /* multiply by 8 to make a bit count */
-  t = lsb;
-  lsb <<= 3;
-  msb <<= 3;
-  msb |= t >> 29;
-  
-  if( hd->count < 56 )  /* enough room */
-    {
-      hd->buf[hd->count++] = 0x80; /* pad */
-      while( hd->count < 56 )
-        hd->buf[hd->count++] = 0;  /* pad */
-    }
-  else /* need one extra block */ 
-    { 
-      hd->buf[hd->count++] = 0x80; /* pad character */
-      while( hd->count < 64 )
-        hd->buf[hd->count++] = 0;
-      md4_write(hd, NULL, 0);  /* flush */;
-      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
-    }
-  /* append the 64 bit count */
-  hd->buf[56] = lsb       ;
-  hd->buf[57] = lsb >>  8;
-  hd->buf[58] = lsb >> 16;
-  hd->buf[59] = lsb >> 24;
-  hd->buf[60] = msb       ;
-  hd->buf[61] = msb >>  8;
-  hd->buf[62] = msb >> 16;
-  hd->buf[63] = msb >> 24;
-  transform( hd, hd->buf );
-  _gcry_burn_stack (80+6*sizeof(void*));
-
-  p = hd->buf;
-#ifdef WORDS_BIGENDIAN
-#define X(a) do { *p++ = hd->a      ; *p++ = hd->a >> 8;      \
-                 *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
-#else /* little endian */
-#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0)
-#endif
-  X(A);
-  X(B);
-  X(C);
-  X(D);
-#undef X
-
-}
-
-static byte *
-md4_read (void *context)
-{
-  MD4_CONTEXT *hd = context;
-  return hd->buf;
-}
-
-static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */
-  { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
-    0x86, 0xf7, 0x0d, 0x02, 0x04, 0x05, 0x00, 0x04, 0x10 };
-
-static gcry_md_oid_spec_t oid_spec_md4[] =
-  {
-    /* iso.member-body.us.rsadsi.digestAlgorithm.md4 */
-    { "1.2.840.113549.2.4" },
-    { NULL },
-  };
-
-gcry_md_spec_t _gcry_digest_spec_md4 =
-  {
-    "MD4", asn, DIM (asn), oid_spec_md4,16,
-    md4_init, md4_write, md4_final, md4_read,
-    sizeof (MD4_CONTEXT)
-  };
-
diff --git a/lib/libgcrypt/cipher/md5.c b/lib/libgcrypt/cipher/md5.c
deleted file mode 100644 (file)
index 899dce8..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-/* md5.c - MD5 Message-Digest Algorithm
- * Copyright (C) 1995,1996,1998,1999,2001,2002,
- *               2003  Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * According to the definition of MD5 in RFC 1321 from April 1992.
- * NOTE: This is *not* the same file as the one from glibc.
- * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. 
- * heavily modified for GnuPG by Werner Koch <wk@gnupg.org> 
- */
-
-/* Test values:
- * ""                  D4 1D 8C D9 8F 00 B2 04  E9 80 09 98 EC F8 42 7E
- * "a"                 0C C1 75 B9 C0 F1 B6 A8  31 C3 99 E2 69 77 26 61
- * "abc                90 01 50 98 3C D2 4F B0  D6 96 3F 7D 28 E1 7F 72
- * "message digest"    F9 6B 69 7D 7C B7 93 8D  52 5A 2F 31 AA F1 61 D0
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "g10lib.h"
-#include "memory.h"
-#include "cipher.h"
-
-#include "bithelp.h"
-
-
-typedef struct {
-    u32 A,B,C,D;         /* chaining variables */
-    u32  nblocks;
-    byte buf[64];
-    int  count;
-} MD5_CONTEXT;
-
-
-static void
-md5_init( void *context )
-{
-  MD5_CONTEXT *ctx = context;
-
-  ctx->A = 0x67452301;
-  ctx->B = 0xefcdab89;
-  ctx->C = 0x98badcfe;
-  ctx->D = 0x10325476;
-
-  ctx->nblocks = 0;
-  ctx->count = 0;
-}
-
-
-/* These are the four functions used in the four steps of the MD5 algorithm
-   and defined in the RFC 1321.  The first function is a little bit optimized
-   (as found in Colin Plumbs public domain implementation).  */
-/* #define FF(b, c, d) ((b & c) | (~b & d)) */
-#define FF(b, c, d) (d ^ (b & (c ^ d)))
-#define FG(b, c, d) FF (d, b, c)
-#define FH(b, c, d) (b ^ c ^ d)
-#define FI(b, c, d) (c ^ (b | ~d))
-
-
-/****************
- * transform n*64 bytes
- */
-static void
-transform ( MD5_CONTEXT *ctx, const unsigned char *data )
-{
-  u32 correct_words[16];
-  register u32 A = ctx->A;
-  register u32 B = ctx->B;
-  register u32 C = ctx->C;
-  register u32 D = ctx->D;
-  u32 *cwp = correct_words;
-    
-#ifdef WORDS_BIGENDIAN
-  { 
-    int i;
-    byte *p2, *p1;
-    for(i=0, p1=data, p2=(byte*)correct_words; i < 16; i++, p2 += 4 )
-      {
-        p2[3] = *p1++;
-       p2[2] = *p1++;
-       p2[1] = *p1++;
-       p2[0] = *p1++;
-      }
-  }
-#else
-  memcpy( correct_words, data, 64 );
-#endif
-
-
-#define OP(a, b, c, d, s, T) \
-  do                                      \
-    {                                     \
-      a += FF (b, c, d) + (*cwp++) + T;    \
-      a = rol(a, s);                      \
-      a += b;                             \
-    }                                     \
-  while (0)
-
-  /* Before we start, one word about the strange constants.
-     They are defined in RFC 1321 as
-
-     T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
-  */
-
-  /* Round 1.  */
-  OP (A, B, C, D,  7, 0xd76aa478);
-  OP (D, A, B, C, 12, 0xe8c7b756);
-  OP (C, D, A, B, 17, 0x242070db);
-  OP (B, C, D, A, 22, 0xc1bdceee);
-  OP (A, B, C, D,  7, 0xf57c0faf);
-  OP (D, A, B, C, 12, 0x4787c62a);
-  OP (C, D, A, B, 17, 0xa8304613);
-  OP (B, C, D, A, 22, 0xfd469501);
-  OP (A, B, C, D,  7, 0x698098d8);
-  OP (D, A, B, C, 12, 0x8b44f7af);
-  OP (C, D, A, B, 17, 0xffff5bb1);
-  OP (B, C, D, A, 22, 0x895cd7be);
-  OP (A, B, C, D,  7, 0x6b901122);
-  OP (D, A, B, C, 12, 0xfd987193);
-  OP (C, D, A, B, 17, 0xa679438e);
-  OP (B, C, D, A, 22, 0x49b40821);
-
-#undef OP
-#define OP(f, a, b, c, d, k, s, T)  \
-    do                                                               \
-      {                                                              \
-       a += f (b, c, d) + correct_words[k] + T;                      \
-       a = rol(a, s);                                                \
-       a += b;                                                       \
-      }                                                              \
-    while (0)
-
-  /* Round 2.  */
-  OP (FG, A, B, C, D,  1,  5, 0xf61e2562);
-  OP (FG, D, A, B, C,  6,  9, 0xc040b340);
-  OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
-  OP (FG, B, C, D, A,  0, 20, 0xe9b6c7aa);
-  OP (FG, A, B, C, D,  5,  5, 0xd62f105d);
-  OP (FG, D, A, B, C, 10,  9, 0x02441453);
-  OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
-  OP (FG, B, C, D, A,  4, 20, 0xe7d3fbc8);
-  OP (FG, A, B, C, D,  9,  5, 0x21e1cde6);
-  OP (FG, D, A, B, C, 14,  9, 0xc33707d6);
-  OP (FG, C, D, A, B,  3, 14, 0xf4d50d87);
-  OP (FG, B, C, D, A,  8, 20, 0x455a14ed);
-  OP (FG, A, B, C, D, 13,  5, 0xa9e3e905);
-  OP (FG, D, A, B, C,  2,  9, 0xfcefa3f8);
-  OP (FG, C, D, A, B,  7, 14, 0x676f02d9);
-  OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
-
-  /* Round 3.  */
-  OP (FH, A, B, C, D,  5,  4, 0xfffa3942);
-  OP (FH, D, A, B, C,  8, 11, 0x8771f681);
-  OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
-  OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
-  OP (FH, A, B, C, D,  1,  4, 0xa4beea44);
-  OP (FH, D, A, B, C,  4, 11, 0x4bdecfa9);
-  OP (FH, C, D, A, B,  7, 16, 0xf6bb4b60);
-  OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
-  OP (FH, A, B, C, D, 13,  4, 0x289b7ec6);
-  OP (FH, D, A, B, C,  0, 11, 0xeaa127fa);
-  OP (FH, C, D, A, B,  3, 16, 0xd4ef3085);
-  OP (FH, B, C, D, A,  6, 23, 0x04881d05);
-  OP (FH, A, B, C, D,  9,  4, 0xd9d4d039);
-  OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
-  OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
-  OP (FH, B, C, D, A,  2, 23, 0xc4ac5665);
-
-  /* Round 4.  */
-  OP (FI, A, B, C, D,  0,  6, 0xf4292244);
-  OP (FI, D, A, B, C,  7, 10, 0x432aff97);
-  OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
-  OP (FI, B, C, D, A,  5, 21, 0xfc93a039);
-  OP (FI, A, B, C, D, 12,  6, 0x655b59c3);
-  OP (FI, D, A, B, C,  3, 10, 0x8f0ccc92);
-  OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
-  OP (FI, B, C, D, A,  1, 21, 0x85845dd1);
-  OP (FI, A, B, C, D,  8,  6, 0x6fa87e4f);
-  OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
-  OP (FI, C, D, A, B,  6, 15, 0xa3014314);
-  OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
-  OP (FI, A, B, C, D,  4,  6, 0xf7537e82);
-  OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
-  OP (FI, C, D, A, B,  2, 15, 0x2ad7d2bb);
-  OP (FI, B, C, D, A,  9, 21, 0xeb86d391);
-
-  /* Put checksum in context given as argument.  */
-  ctx->A += A;
-  ctx->B += B;
-  ctx->C += C;
-  ctx->D += D;
-}
-
-
-
-/* The routine updates the message-digest context to
- * account for the presence of each of the characters inBuf[0..inLen-1]
- * in the message whose digest is being computed.
- */
-static void
-md5_write( void *context, const void *inbuf_arg , size_t inlen)
-{
-  const unsigned char *inbuf = inbuf_arg;
-  MD5_CONTEXT *hd = context;
-  
-  if( hd->count == 64 )  /* flush the buffer */
-    {
-      transform( hd, hd->buf );
-      _gcry_burn_stack (80+6*sizeof(void*));
-      hd->count = 0;
-      hd->nblocks++;
-    }
-  if( !inbuf )
-    return;
-
-  if( hd->count )
-    {
-      for( ; inlen && hd->count < 64; inlen-- )
-        hd->buf[hd->count++] = *inbuf++;
-      md5_write( hd, NULL, 0 );
-      if( !inlen )
-        return;
-    }
-  _gcry_burn_stack (80+6*sizeof(void*));
-
-  while( inlen >= 64 ) 
-    {
-      transform( hd, inbuf );
-      hd->count = 0;
-      hd->nblocks++;
-      inlen -= 64;
-      inbuf += 64;
-    }
-  for( ; inlen && hd->count < 64; inlen-- )
-    hd->buf[hd->count++] = *inbuf++;
-
-}
-
-
-
-/* The routine final terminates the message-digest computation and
- * ends with the desired message digest in mdContext->digest[0...15].
- * The handle is prepared for a new MD5 cycle.
- * Returns 16 bytes representing the digest.
- */
-
-static void
-md5_final( void *context)
-{
-  MD5_CONTEXT *hd = context;
-  u32 t, msb, lsb;
-  byte *p;
-  
-  md5_write(hd, NULL, 0); /* flush */;
-
-  t = hd->nblocks;
-  /* multiply by 64 to make a byte count */
-  lsb = t << 6;
-  msb = t >> 26;
-  /* add the count */
-  t = lsb;
-  if( (lsb += hd->count) < t )
-    msb++;
-  /* multiply by 8 to make a bit count */
-  t = lsb;
-  lsb <<= 3;
-  msb <<= 3;
-  msb |= t >> 29;
-
-  if( hd->count < 56 )  /* enough room */
-    {
-      hd->buf[hd->count++] = 0x80; /* pad */
-      while( hd->count < 56 )
-        hd->buf[hd->count++] = 0;  /* pad */
-    }
-  else  /* need one extra block */
-    {
-      hd->buf[hd->count++] = 0x80; /* pad character */
-      while( hd->count < 64 )
-        hd->buf[hd->count++] = 0;
-      md5_write(hd, NULL, 0);  /* flush */;
-      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
-    }
-  /* append the 64 bit count */
-  hd->buf[56] = lsb       ;
-  hd->buf[57] = lsb >>  8;
-  hd->buf[58] = lsb >> 16;
-  hd->buf[59] = lsb >> 24;
-  hd->buf[60] = msb       ;
-  hd->buf[61] = msb >>  8;
-  hd->buf[62] = msb >> 16;
-  hd->buf[63] = msb >> 24;
-  transform( hd, hd->buf );
-  _gcry_burn_stack (80+6*sizeof(void*));
-
-  p = hd->buf;
-#ifdef WORDS_BIGENDIAN
-#define X(a) do { *p++ = hd->a      ; *p++ = hd->a >> 8;      \
-                 *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
-#else /* little endian */
-#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0)
-#endif
-  X(A);
-  X(B);
-  X(C);
-  X(D);
-#undef X
-
-}
-
-static byte *
-md5_read( void *context )
-{
-  MD5_CONTEXT *hd = (MD5_CONTEXT *) context;
-  return hd->buf;
-}
-
-static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */
-  { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
-    0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
-
-static gcry_md_oid_spec_t oid_spec_md5[] =
-  {
-    /* iso.member-body.us.rsadsi.pkcs.pkcs-1.4 (md5WithRSAEncryption) */
-    { "1.2.840.113549.1.1.4" },
-    /* RSADSI digestAlgorithm MD5 */
-    { "1.2.840.113549.2.5" },
-    { NULL },
-  };
-
-gcry_md_spec_t _gcry_digest_spec_md5 =
-  {
-    "MD5", asn, DIM (asn), oid_spec_md5, 16,
-    md5_init, md5_write, md5_final, md5_read,
-    sizeof (MD5_CONTEXT)
-  };
diff --git a/lib/libgcrypt/cipher/primegen.c b/lib/libgcrypt/cipher/primegen.c
deleted file mode 100644 (file)
index b869bee..0000000
+++ /dev/null
@@ -1,1862 +0,0 @@
-/* primegen.c - prime number generator
- * Copyright (C) 1998, 2000, 2001, 2002, 2003
- *               2004, 2008 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#include "g10lib.h"
-#include "mpi.h"
-#include "cipher.h"
-#include "ath.h"
-
-static gcry_mpi_t gen_prime (unsigned int nbits, int secret, int randomlevel, 
-                             int (*extra_check)(void *, gcry_mpi_t),
-                             void *extra_check_arg);
-static int check_prime( gcry_mpi_t prime, gcry_mpi_t val_2, int rm_rounds,
-                        gcry_prime_check_func_t cb_func, void *cb_arg );
-static int is_prime (gcry_mpi_t n, int steps, unsigned int *count);
-static void m_out_of_n( char *array, int m, int n );
-
-static void (*progress_cb) (void *,const char*,int,int, int );
-static void *progress_cb_data;
-
-/* Note: 2 is not included because it can be tested more easily by
-   looking at bit 0. The last entry in this list is marked by a zero */
-static ushort small_prime_numbers[] = {
-    3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
-    47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
-    103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
-    157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
-    211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
-    269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
-    331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
-    389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
-    449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
-    509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
-    587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
-    643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
-    709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
-    773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
-    853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
-    919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
-    991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
-    1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
-    1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
-    1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
-    1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
-    1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
-    1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
-    1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
-    1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
-    1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
-    1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
-    1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
-    1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
-    1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
-    1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
-    1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
-    1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
-    1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
-    2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
-    2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
-    2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
-    2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
-    2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
-    2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
-    2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
-    2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
-    2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
-    2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
-    2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
-    2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
-    2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
-    2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
-    2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
-    3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
-    3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
-    3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
-    3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
-    3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
-    3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
-    3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
-    3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
-    3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
-    3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
-    3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
-    3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
-    3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
-    3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
-    3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
-    4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
-    4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
-    4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
-    4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
-    4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
-    4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
-    4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
-    4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
-    4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
-    4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
-    4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
-    4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
-    4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
-    4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
-    4957, 4967, 4969, 4973, 4987, 4993, 4999,
-    0
-};
-static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1;
-
-
-\f
-/* An object and a list to build up a global pool of primes.  See
-   save_pool_prime and get_pool_prime. */
-struct primepool_s 
-{
-  struct primepool_s *next;
-  gcry_mpi_t prime;      /* If this is NULL the entry is not used. */
-  unsigned int nbits;
-  gcry_random_level_t randomlevel;
-};
-struct primepool_s *primepool;
-/* Mutex used to protect access to the primepool.  */
-static ath_mutex_t primepool_lock = ATH_MUTEX_INITIALIZER;
-
-
-
-/* Save PRIME which has been generated at RANDOMLEVEL for later
-   use. Needs to be called while primepool_lock is being hold.  Note
-   that PRIME should be considered released after calling this
-   function. */
-static void
-save_pool_prime (gcry_mpi_t prime, gcry_random_level_t randomlevel)
-{
-  struct primepool_s *item, *item2;
-  size_t n;
-
-  for (n=0, item = primepool; item; item = item->next, n++)
-    if (!item->prime)
-      break;
-  if (!item && n > 100)
-    {
-      /* Remove some of the entries.  Our strategy is removing
-         the last third from the list. */
-      int i;
-      
-      for (i=0, item2 = primepool; item2; item2 = item2->next)
-        {
-          if (i >= n/3*2)
-            {
-              gcry_mpi_release (item2->prime);
-              item2->prime = NULL;
-              if (!item)
-                item = item2;
-            }
-        }
-    }
-  if (!item)
-    {
-      item = gcry_calloc (1, sizeof *item);
-      if (!item)
-        {
-          /* Out of memory.  Silently giving up. */
-          gcry_mpi_release (prime);
-          return; 
-        }
-      item->next = primepool;
-      primepool = item;
-    }
-  item->prime = prime;
-  item->nbits = mpi_get_nbits (prime);
-  item->randomlevel = randomlevel;
-}
-
-
-/* Return a prime for the prime pool or NULL if none has been found.
-   The prime needs to match NBITS and randomlevel. This function needs
-   to be called why the primepool_look is being hold. */
-static gcry_mpi_t
-get_pool_prime (unsigned int nbits, gcry_random_level_t randomlevel)
-{
-  struct primepool_s *item;
-
-  for (item = primepool; item; item = item->next)
-    if (item->prime
-        && item->nbits == nbits && item->randomlevel == randomlevel)
-      {
-        gcry_mpi_t prime = item->prime;
-        item->prime = NULL;
-        gcry_assert (nbits == mpi_get_nbits (prime));
-        return prime;
-      }
-  return NULL;
-}
-
-
-
-
-
-\f
-void
-_gcry_register_primegen_progress ( void (*cb)(void *,const char*,int,int,int),
-                                   void *cb_data )
-{
-  progress_cb = cb;
-  progress_cb_data = cb_data;
-}
-
-
-static void
-progress( int c )
-{
-  if ( progress_cb )
-    progress_cb ( progress_cb_data, "primegen", c, 0, 0 );
-}
-
-
-/****************
- * Generate a prime number (stored in secure memory)
- */
-gcry_mpi_t
-_gcry_generate_secret_prime (unsigned int nbits,
-                             gcry_random_level_t random_level,
-                             int (*extra_check)(void*, gcry_mpi_t),
-                             void *extra_check_arg)
-{
-  gcry_mpi_t prime;
-
-  prime = gen_prime (nbits, 1, random_level, extra_check, extra_check_arg);
-  progress('\n');
-  return prime;
-}
-
-
-/* Generate a prime number which may be public, i.e. not allocated in
-   secure memory.  */
-gcry_mpi_t
-_gcry_generate_public_prime (unsigned int nbits,
-                             gcry_random_level_t random_level,
-                             int (*extra_check)(void*, gcry_mpi_t),
-                             void *extra_check_arg)
-{
-  gcry_mpi_t prime;
-
-  prime = gen_prime (nbits, 0, random_level, extra_check, extra_check_arg);
-  progress('\n');
-  return prime;
-}
-
-
-/* Core prime generation function.  The algorithm used to generate
-   practically save primes is due to Lim and Lee as described in the
-   CRYPTO '97 proceedings (ISBN3540633847) page 260.
-
-   NEED_Q_FACTOR: If true make sure that at least one factor is of
-                  size qbits.  This is for example required for DSA.
-   PRIME_GENERATED: Adresss of a variable where the resulting prime
-                    number will be stored.
-   PBITS: Requested size of the prime number.  At least 48.
-   QBITS: One factor of the prime needs to be of this size.  Maybe 0
-          if this is not required.  See also MODE.
-   G: If not NULL an MPI which will receive a generator for the prime
-      for use with Elgamal.
-   RET_FACTORS: if not NULL, an array with all factors are stored at
-                that address.
-   ALL_FACTORS: If set to true all factors of prime-1 are returned.
-   RANDOMLEVEL:  How strong should the random numers be.
-   FLAGS: Prime generation bit flags. Currently supported:
-          GCRY_PRIME_FLAG_SECRET - The prime needs to be kept secret.
-   CB_FUNC, CB_ARG:  Callback to be used for extra checks.
-
- */
-static gcry_err_code_t
-prime_generate_internal (int need_q_factor,
-                        gcry_mpi_t *prime_generated, unsigned int pbits,
-                        unsigned int qbits, gcry_mpi_t g,
-                        gcry_mpi_t **ret_factors,
-                        gcry_random_level_t randomlevel, unsigned int flags,
-                         int all_factors,
-                         gcry_prime_check_func_t cb_func, void *cb_arg)
-{
-  gcry_err_code_t err = 0;
-  gcry_mpi_t *factors_new = NULL; /* Factors to return to the
-                                    caller.  */
-  gcry_mpi_t *factors = NULL;  /* Current factors.  */
-  gcry_random_level_t poolrandomlevel; /* Random level used for pool primes. */
-  gcry_mpi_t *pool = NULL;     /* Pool of primes.  */
-  int *pool_in_use = NULL;      /* Array with currently used POOL elements. */
-  unsigned char *perms = NULL; /* Permutations of POOL.  */
-  gcry_mpi_t q_factor = NULL;  /* Used if QBITS is non-zero.  */
-  unsigned int fbits = 0;      /* Length of prime factors.  */
-  unsigned int n = 0;          /* Number of factors.  */
-  unsigned int m = 0;          /* Number of primes in pool.  */
-  gcry_mpi_t q = NULL;         /* First prime factor.  */
-  gcry_mpi_t prime = NULL;     /* Prime candidate.  */
-  unsigned int nprime = 0;     /* Bits of PRIME.  */
-  unsigned int req_qbits;       /* The original QBITS value.  */
-  gcry_mpi_t val_2;             /* For check_prime().  */
-  int is_locked = 0;            /* Flag to help unlocking the primepool. */
-  unsigned int is_secret = (flags & GCRY_PRIME_FLAG_SECRET);
-  unsigned int count1 = 0, count2 = 0;
-  unsigned int i = 0, j = 0;
-
-  if (pbits < 48)
-    return GPG_ERR_INV_ARG;
-
-  /* We won't use a too strong random elvel for the pooled subprimes. */
-  poolrandomlevel = (randomlevel > GCRY_STRONG_RANDOM?
-                     GCRY_STRONG_RANDOM : randomlevel);
-
-
-  /* If QBITS is not given, assume a reasonable value. */
-  if (!qbits)
-    qbits = pbits / 3;
-
-  req_qbits = qbits;
-
-  /* Find number of needed prime factors N.  */
-  for (n = 1; (pbits - qbits - 1) / n  >= qbits; n++)
-    ;
-  n--;
-
-  val_2 = mpi_alloc_set_ui (2);
-
-  if ((! n) || ((need_q_factor) && (n < 2)))
-    {
-      err = GPG_ERR_INV_ARG;
-      goto leave;
-    }
-
-  if (need_q_factor)
-    {
-      n--;  /* Need one factor less because we want a specific Q-FACTOR. */
-      fbits = (pbits - 2 * req_qbits -1) / n;
-      qbits =  pbits - req_qbits - n * fbits;
-    }
-  else
-    {
-      fbits = (pbits - req_qbits -1) / n;
-      qbits = pbits - n * fbits;
-    }
-  
-  if (DBG_CIPHER)
-    log_debug ("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
-               pbits, req_qbits, qbits, fbits, n);
-
-  /* Allocate an integer to old the new prime. */
-  prime = gcry_mpi_new (pbits);
-
-  /* Generate first prime factor.  */
-  q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
-
-  /* Generate a specific Q-Factor if requested. */
-  if (need_q_factor)
-    q_factor = gen_prime (req_qbits, is_secret, randomlevel, NULL, NULL);
-  
-  /* Allocate an array to hold all factors + 2 for later usage.  */
-  factors = gcry_calloc (n + 2, sizeof (*factors));
-  if (!factors)
-    {
-      err = gpg_err_code_from_errno (errno);
-      goto leave;
-    }
-
-  /* Allocate an array to track pool usage. */
-  pool_in_use = gcry_malloc (n * sizeof *pool_in_use);
-  if (!pool_in_use)
-    {
-      err = gpg_err_code_from_errno (errno);
-      goto leave;
-    }
-  for (i=0; i < n; i++)
-    pool_in_use[i] = -1;
-      
-  /* Make a pool of 3n+5 primes (this is an arbitrary value).  We
-     require at least 30 primes for are useful selection process. 
-     
-     Fixme: We need to research the best formula for sizing the pool.
-  */
-  m = n * 3 + 5;
-  if (need_q_factor) /* Need some more in this case. */
-    m += 5;
-  if (m < 30)
-    m = 30;
-  pool = gcry_calloc (m , sizeof (*pool));
-  if (! pool)
-    {
-      err = gpg_err_code_from_errno (errno);
-      goto leave;
-    }
-
-  /* Permutate over the pool of primes until we find a prime of the
-     requested length.  */
-  do
-    {
-    next_try:
-      for (i=0; i < n; i++)
-        pool_in_use[i] = -1;
-
-      if (!perms)
-        {
-          /* Allocate new primes.  This is done right at the beginning
-             of the loop and if we have later run out of primes. */
-          for (i = 0; i < m; i++)
-            {
-              mpi_free (pool[i]);
-              pool[i] = NULL;
-            }
-
-          /* Init m_out_of_n().  */
-          perms = gcry_calloc (1, m);
-          if (!perms)
-            {
-              err = gpg_err_code_from_errno (errno);
-              goto leave;
-            }
-
-          if (ath_mutex_lock (&primepool_lock))
-            {
-              err = GPG_ERR_INTERNAL;
-              goto leave;
-            }
-          is_locked = 1;
-          for (i = 0; i < n; i++)
-            {
-              perms[i] = 1; 
-              /* At a maximum we use strong random for the factors.
-                 This saves us a lot of entropy. Given that Q and
-                 possible Q-factor are also used in the final prime
-                 this should be acceptable.  We also don't allocate in
-                 secure memory to save on that scare resource too.  If
-                 Q has been allocated in secure memory, the final
-                 prime will be saved there anyway.  This is because
-                 our MPI routines take care of that.  GnuPG has worked
-                 this way ever since.  */
-              pool[i] = NULL;
-              if (is_locked)
-                {
-                  pool[i] = get_pool_prime (fbits, poolrandomlevel);
-                  if (!pool[i])
-                    {
-                      if (ath_mutex_unlock (&primepool_lock))
-                        {
-                          err = GPG_ERR_INTERNAL;
-                          goto leave;
-                        }
-                      is_locked = 0;
-                    }
-                }
-              if (!pool[i])
-                pool[i] = gen_prime (fbits, 0, poolrandomlevel, NULL, NULL);
-              pool_in_use[i] = i;
-              factors[i] = pool[i];
-            }
-          if (is_locked && ath_mutex_unlock (&primepool_lock))
-            {
-              err = GPG_ERR_INTERNAL;
-              goto leave;
-            }
-          is_locked = 0;
-        }
-      else
-        {
-          /* Get next permutation. */
-          m_out_of_n ( (char*)perms, n, m);
-          if (ath_mutex_lock (&primepool_lock))
-            {
-              err = GPG_ERR_INTERNAL;
-              goto leave;
-            }
-          is_locked = 1;
-          for (i = j = 0; (i < m) && (j < n); i++)
-            if (perms[i])
-              {
-                /* If the subprime has not yet beed generated do it now. */
-                if (!pool[i] && is_locked)
-                  {
-                    pool[i] = get_pool_prime (fbits, poolrandomlevel);
-                    if (!pool[i])
-                      {
-                        if (ath_mutex_unlock (&primepool_lock))
-                          {
-                            err = GPG_ERR_INTERNAL;
-                            goto leave;
-                          }
-                        is_locked = 0;
-                      }
-                  }
-                if (!pool[i])
-                  pool[i] = gen_prime (fbits, 0, poolrandomlevel, NULL, NULL);
-                pool_in_use[j] = i;
-                factors[j++] = pool[i];
-              }
-          if (is_locked && ath_mutex_unlock (&primepool_lock))
-            {
-              err = GPG_ERR_INTERNAL;
-              goto leave;
-            }
-          is_locked = 0;
-          if (i == n)
-            {
-              /* Ran out of permutations: Allocate new primes.  */
-              gcry_free (perms);
-              perms = NULL;
-              progress ('!');
-              goto next_try;   
-            }
-        }
-
-       /* Generate next prime candidate:
-          p = 2 * q [ * q_factor] * factor_0 * factor_1 * ... * factor_n + 1. 
-         */
-       mpi_set (prime, q);
-       mpi_mul_ui (prime, prime, 2);
-       if (need_q_factor)
-         mpi_mul (prime, prime, q_factor);
-       for(i = 0; i < n; i++)
-         mpi_mul (prime, prime, factors[i]);
-       mpi_add_ui (prime, prime, 1);
-       nprime = mpi_get_nbits (prime);
-
-       if (nprime < pbits)
-         {
-           if (++count1 > 20)
-             {
-               count1 = 0;
-               qbits++;
-               progress('>');
-               mpi_free (q);
-               q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
-               goto next_try;
-             }
-         }
-       else
-         count1 = 0;
-        
-       if (nprime > pbits)
-         {
-           if (++count2 > 20)
-             {
-               count2 = 0;
-               qbits--;
-               progress('<');
-               mpi_free (q);
-               q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
-               goto next_try;
-             }
-         }
-       else
-         count2 = 0;
-    }
-  while (! ((nprime == pbits) && check_prime (prime, val_2, 5,
-                                              cb_func, cb_arg)));
-
-  if (DBG_CIPHER)
-    {
-      progress ('\n');
-      log_mpidump ("prime    : ", prime);
-      log_mpidump ("factor  q: ", q);
-      if (need_q_factor)
-        log_mpidump ("factor q0: ", q_factor);
-      for (i = 0; i < n; i++)
-        log_mpidump ("factor pi: ", factors[i]);
-      log_debug ("bit sizes: prime=%u, q=%u",
-                 mpi_get_nbits (prime), mpi_get_nbits (q));
-      if (need_q_factor)
-        log_debug (", q0=%u", mpi_get_nbits (q_factor));
-      for (i = 0; i < n; i++)
-        log_debug (", p%d=%u", i, mpi_get_nbits (factors[i]));
-      progress('\n');
-    }
-
-  if (ret_factors)
-    {
-      /* Caller wants the factors.  */
-      factors_new = gcry_calloc (n + 4, sizeof (*factors_new));
-      if (! factors_new)
-        {
-          err = gpg_err_code_from_errno (errno);
-          goto leave;
-        }
-
-      if (all_factors)
-        {
-          i = 0;
-          factors_new[i++] = gcry_mpi_set_ui (NULL, 2);
-          factors_new[i++] = mpi_copy (q);
-          if (need_q_factor)
-            factors_new[i++] = mpi_copy (q_factor);
-          for(j=0; j < n; j++)
-            factors_new[i++] = mpi_copy (factors[j]);
-        }
-      else
-        {
-          i = 0;
-          if (need_q_factor)
-            {
-              factors_new[i++] = mpi_copy (q_factor);
-              for (; i <= n; i++)
-                factors_new[i] = mpi_copy (factors[i]);
-            }
-          else
-            for (; i < n; i++ )
-              factors_new[i] = mpi_copy (factors[i]);
-        }
-    }
-  
-  if (g)
-    {
-      /* Create a generator (start with 3).  */
-      gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs (prime));
-      gcry_mpi_t b = mpi_alloc (mpi_get_nlimbs (prime));
-      gcry_mpi_t pmin1 = mpi_alloc (mpi_get_nlimbs (prime));
-      
-      if (need_q_factor)
-        err = GPG_ERR_NOT_IMPLEMENTED;
-      else
-        {
-          factors[n] = q;
-          factors[n + 1] = mpi_alloc_set_ui (2);
-          mpi_sub_ui (pmin1, prime, 1);
-          mpi_set_ui (g, 2);
-          do
-            {
-              mpi_add_ui (g, g, 1);
-              if (DBG_CIPHER)
-                {
-                  log_debug ("checking g:");
-                  gcry_mpi_dump (g);
-                  log_printf ("\n");
-                }
-              else
-                progress('^');
-              for (i = 0; i < n + 2; i++)
-                {
-                  mpi_fdiv_q (tmp, pmin1, factors[i]);
-                  /* No mpi_pow(), but it is okay to use this with mod
-                     prime.  */
-                  gcry_mpi_powm (b, g, tmp, prime);
-                  if (! mpi_cmp_ui (b, 1))
-                    break;
-                }
-              if (DBG_CIPHER)
-                progress('\n');
-            } 
-          while (i < n + 2);
-
-          mpi_free (factors[n+1]);
-          mpi_free (tmp);
-          mpi_free (b);
-          mpi_free (pmin1);
-        }
-    }
-  
-  if (! DBG_CIPHER)
-    progress ('\n');
-
-
- leave:
-  if (pool)
-    {
-      is_locked = !ath_mutex_lock (&primepool_lock);
-      for(i = 0; i < m; i++)
-        {
-          if (pool[i])
-            {
-              for (j=0; j < n; j++)
-                if (pool_in_use[j] == i)
-                  break;
-              if (j == n && is_locked)
-                {
-                  /* This pooled subprime has not been used. */
-                  save_pool_prime (pool[i], poolrandomlevel);
-                }
-              else
-                mpi_free (pool[i]);
-            }
-        }
-      if (is_locked && ath_mutex_unlock (&primepool_lock))
-        err = GPG_ERR_INTERNAL;
-      is_locked = 0;
-      gcry_free (pool);
-    }
-  gcry_free (pool_in_use);
-  if (factors)
-    gcry_free (factors);  /* Factors are shallow copies.  */
-  if (perms)
-    gcry_free (perms);
-
-  mpi_free (val_2);
-  mpi_free (q);
-  mpi_free (q_factor);
-
-  if (! err)
-    {
-      *prime_generated = prime;
-      if (ret_factors)
-       *ret_factors = factors_new;
-    }
-  else
-    {
-      if (factors_new)
-       {
-         for (i = 0; factors_new[i]; i++)
-           mpi_free (factors_new[i]);
-         gcry_free (factors_new);
-       }
-      mpi_free (prime);
-    }
-
-  return err;
-}
-
-
-/* Generate a prime used for discrete logarithm algorithms; i.e. this
-   prime will be public and no strong random is required.  */
-gcry_mpi_t
-_gcry_generate_elg_prime (int mode, unsigned pbits, unsigned qbits,
-                         gcry_mpi_t g, gcry_mpi_t **ret_factors)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_mpi_t prime = NULL;
-  
-  err = prime_generate_internal ((mode == 1), &prime, pbits, qbits, g,
-                                ret_factors, GCRY_WEAK_RANDOM, 0, 0,
-                                 NULL, NULL);
-
-  return prime;
-}
-
-
-static gcry_mpi_t
-gen_prime (unsigned int nbits, int secret, int randomlevel, 
-           int (*extra_check)(void *, gcry_mpi_t), void *extra_check_arg)
-{
-  gcry_mpi_t prime, ptest, pminus1, val_2, val_3, result;
-  int i;
-  unsigned int x, step;
-  unsigned int count1, count2;
-  int *mods;
-  
-/*   if (  DBG_CIPHER ) */
-/*     log_debug ("generate a prime of %u bits ", nbits ); */
-
-  if (nbits < 16)
-    log_fatal ("can't generate a prime with less than %d bits\n", 16);
-
-  mods = gcry_xmalloc( no_of_small_prime_numbers * sizeof *mods );
-  /* Make nbits fit into gcry_mpi_t implementation. */
-  val_2  = mpi_alloc_set_ui( 2 );
-  val_3 = mpi_alloc_set_ui( 3);
-  prime  = secret? gcry_mpi_snew ( nbits ): gcry_mpi_new ( nbits );
-  result = mpi_alloc_like( prime );
-  pminus1= mpi_alloc_like( prime );
-  ptest  = mpi_alloc_like( prime );
-  count1 = count2 = 0;
-  for (;;)
-    {  /* try forvever */
-      int dotcount=0;
-      
-      /* generate a random number */
-      gcry_mpi_randomize( prime, nbits, randomlevel );
-      
-      /* Set high order bit to 1, set low order bit to 1.  If we are
-         generating a secret prime we are most probably doing that
-         for RSA, to make sure that the modulus does have the
-         requested key size we set the 2 high order bits. */
-      mpi_set_highbit (prime, nbits-1);
-      if (secret)
-        mpi_set_bit (prime, nbits-2);
-      mpi_set_bit(prime, 0);
-      
-      /* Calculate all remainders. */
-      for (i=0; (x = small_prime_numbers[i]); i++ )
-        mods[i] = mpi_fdiv_r_ui(NULL, prime, x);
-      
-      /* Now try some primes starting with prime. */
-      for(step=0; step < 20000; step += 2 ) 
-        {
-          /* Check against all the small primes we have in mods. */
-          count1++;
-          for (i=0; (x = small_prime_numbers[i]); i++ ) 
-            {
-              while ( mods[i] + step >= x )
-                mods[i] -= x;
-              if ( !(mods[i] + step) )
-                break;
-           }
-          if ( x )
-            continue;   /* Found a multiple of an already known prime. */
-          
-          mpi_add_ui( ptest, prime, step );
-
-          /* Do a fast Fermat test now. */
-          count2++;
-          mpi_sub_ui( pminus1, ptest, 1);
-          gcry_mpi_powm( result, val_2, pminus1, ptest );
-          if ( !mpi_cmp_ui( result, 1 ) )
-            { 
-              /* Not composite, perform stronger tests */
-              if (is_prime(ptest, 5, &count2 ))
-                {
-                  if (!mpi_test_bit( ptest, nbits-1-secret ))
-                    {
-                      progress('\n');
-                      log_debug ("overflow in prime generation\n");
-                      break; /* Stop loop, continue with a new prime. */
-                    }
-
-                  if (extra_check && extra_check (extra_check_arg, ptest))
-                    { 
-                      /* The extra check told us that this prime is
-                         not of the caller's taste. */
-                      progress ('/');
-                    }
-                  else
-                    { 
-                      /* Got it. */
-                      mpi_free(val_2);
-                      mpi_free(val_3);
-                      mpi_free(result);
-                      mpi_free(pminus1);
-                      mpi_free(prime);
-                      gcry_free(mods);
-                      return ptest; 
-                    }
-                }
-           }
-          if (++dotcount == 10 )
-            {
-              progress('.');
-              dotcount = 0;
-           }
-       }
-      progress(':'); /* restart with a new random value */
-    }
-}
-
-/****************
- * Returns: true if this may be a prime
- * RM_ROUNDS gives the number of Rabin-Miller tests to run.
- */
-static int
-check_prime( gcry_mpi_t prime, gcry_mpi_t val_2, int rm_rounds,
-             gcry_prime_check_func_t cb_func, void *cb_arg)
-{
-  int i;
-  unsigned int x;
-  unsigned int count=0;
-
-  /* Check against small primes. */
-  for (i=0; (x = small_prime_numbers[i]); i++ )
-    {
-      if ( mpi_divisible_ui( prime, x ) )
-        return 0;
-    }
-
-  /* A quick Fermat test. */
-  {
-    gcry_mpi_t result = mpi_alloc_like( prime );
-    gcry_mpi_t pminus1 = mpi_alloc_like( prime );
-    mpi_sub_ui( pminus1, prime, 1);
-    gcry_mpi_powm( result, val_2, pminus1, prime );
-    mpi_free( pminus1 );
-    if ( mpi_cmp_ui( result, 1 ) )
-      { 
-        /* Is composite. */
-        mpi_free( result );
-        progress('.');
-        return 0;
-      }
-    mpi_free( result );
-  }
-
-  if (!cb_func || cb_func (cb_arg, GCRY_PRIME_CHECK_AT_MAYBE_PRIME, prime))
-    {
-      /* Perform stronger tests. */
-      if ( is_prime( prime, rm_rounds, &count ) )
-        {
-          if (!cb_func
-              || cb_func (cb_arg, GCRY_PRIME_CHECK_AT_GOT_PRIME, prime))
-            return 1; /* Probably a prime. */
-        }
-    }
-  progress('.');
-  return 0;
-}
-
-
-/*
- * Return true if n is probably a prime
- */
-static int
-is_prime (gcry_mpi_t n, int steps, unsigned int *count)
-{
-  gcry_mpi_t x = mpi_alloc( mpi_get_nlimbs( n ) );
-  gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs( n ) );
-  gcry_mpi_t z = mpi_alloc( mpi_get_nlimbs( n ) );
-  gcry_mpi_t nminus1 = mpi_alloc( mpi_get_nlimbs( n ) );
-  gcry_mpi_t a2 = mpi_alloc_set_ui( 2 );
-  gcry_mpi_t q;
-  unsigned i, j, k;
-  int rc = 0;
-  unsigned nbits = mpi_get_nbits( n );
-
-  if (steps < 5) /* Make sure that we do at least 5 rounds. */
-    steps = 5; 
-
-  mpi_sub_ui( nminus1, n, 1 );
-
-  /* Find q and k, so that n = 1 + 2^k * q . */
-  q = mpi_copy ( nminus1 );
-  k = mpi_trailing_zeros ( q );
-  mpi_tdiv_q_2exp (q, q, k);
-
-  for (i=0 ; i < steps; i++ )
-    {
-      ++*count;
-      if( !i )
-        {
-          mpi_set_ui( x, 2 );
-        }
-      else
-        {
-          gcry_mpi_randomize( x, nbits, GCRY_WEAK_RANDOM );
-
-          /* Make sure that the number is smaller than the prime and
-             keep the randomness of the high bit. */
-          if ( mpi_test_bit ( x, nbits-2) )
-            {
-              mpi_set_highbit ( x, nbits-2); /* Clear all higher bits. */
-            }
-          else
-            {
-              mpi_set_highbit( x, nbits-2 );
-              mpi_clear_bit( x, nbits-2 );
-            }
-          gcry_assert (mpi_cmp (x, nminus1) < 0 && mpi_cmp_ui (x, 1) > 0);
-       }
-      gcry_mpi_powm ( y, x, q, n);
-      if ( mpi_cmp_ui(y, 1) && mpi_cmp( y, nminus1 ) )
-        {
-          for ( j=1; j < k && mpi_cmp( y, nminus1 ); j++ )
-            {
-              gcry_mpi_powm(y, y, a2, n);
-              if( !mpi_cmp_ui( y, 1 ) )
-                goto leave; /* Not a prime. */
-            }
-          if (mpi_cmp( y, nminus1 ) )
-            goto leave; /* Not a prime. */
-       }
-      progress('+');
-    }
-  rc = 1; /* May be a prime. */
-
- leave:
-  mpi_free( x );
-  mpi_free( y );
-  mpi_free( z );
-  mpi_free( nminus1 );
-  mpi_free( q );
-  mpi_free( a2 );
-
-  return rc;
-}
-
-
-/* Given ARRAY of size N with M elements set to true produce a
-   modified array with the next permutation of M elements.  Note, that
-   ARRAY is used in a one-bit-per-byte approach.  To detected the last
-   permutation it is useful to intialize the array with the first M
-   element set to true and use this test:
-       m_out_of_n (array, m, n);
-       for (i = j = 0; i < n && j < m; i++)
-         if (array[i])
-           j++;
-       if (j == m)
-         goto ready;
-     
-   This code is based on the algorithm 452 from the "Collected
-   Algorithms From ACM, Volume II" by C. N. Liu and D. T. Tang.
-*/
-static void
-m_out_of_n ( char *array, int m, int n )
-{
-  int i=0, i1=0, j=0, jp=0,  j1=0, k1=0, k2=0;
-
-  if( !m || m >= n )
-    return;
-
-  /* Need to handle this simple case separately. */
-  if( m == 1 )
-    { 
-      for (i=0; i < n; i++ )
-        {
-          if ( array[i] )
-            {
-              array[i++] = 0;
-              if( i >= n )
-                i = 0;
-              array[i] = 1;
-              return;
-            }
-        }
-      BUG();
-    }
-
-
-  for (j=1; j < n; j++ )
-    {
-      if ( array[n-1] == array[n-j-1])
-        continue;
-      j1 = j;
-      break;
-    }
-
-  if ( (m & 1) )
-    {
-      /* M is odd. */
-      if( array[n-1] )
-        {
-          if( j1 & 1 )
-            {
-              k1 = n - j1;
-              k2 = k1+2;
-              if( k2 > n )
-                k2 = n;
-              goto leave;
-            }
-          goto scan;
-        }
-      k2 = n - j1 - 1;
-      if( k2 == 0 )
-        {
-          k1 = i;
-          k2 = n - j1;
-        }
-      else if( array[k2] && array[k2-1] )
-        k1 = n;
-      else
-        k1 = k2 + 1;
-    }
-  else 
-    {
-      /* M is even. */
-      if( !array[n-1] )
-        {
-          k1 = n - j1;
-          k2 = k1 + 1;
-          goto leave;
-        }
-        
-      if( !(j1 & 1) )
-        {
-          k1 = n - j1;
-          k2 = k1+2;
-          if( k2 > n )
-            k2 = n;
-          goto leave;
-        }
-    scan:
-      jp = n - j1 - 1;
-      for (i=1; i <= jp; i++ ) 
-        {
-          i1 = jp + 2 - i;
-          if( array[i1-1]  )
-            {
-              if( array[i1-2] )
-                {
-                  k1 = i1 - 1;
-                  k2 = n - j1;
-               }
-              else
-                {
-                  k1 = i1 - 1;
-                  k2 = n + 1 - j1;
-                }
-              goto leave;
-            }
-        }
-      k1 = 1;
-      k2 = n + 1 - m;
-    }
- leave:
-  /* Now complement the two selected bits. */
-  array[k1-1] = !array[k1-1];
-  array[k2-1] = !array[k2-1];
-}
-
-
-/* Generate a new prime number of PRIME_BITS bits and store it in
-   PRIME.  If FACTOR_BITS is non-zero, one of the prime factors of
-   (prime - 1) / 2 must be FACTOR_BITS bits long.  If FACTORS is
-   non-zero, allocate a new, NULL-terminated array holding the prime
-   factors and store it in FACTORS.  FLAGS might be used to influence
-   the prime number generation process.  */
-gcry_error_t
-gcry_prime_generate (gcry_mpi_t *prime, unsigned int prime_bits,
-                    unsigned int factor_bits, gcry_mpi_t **factors,
-                    gcry_prime_check_func_t cb_func, void *cb_arg,
-                    gcry_random_level_t random_level,
-                    unsigned int flags)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_mpi_t *factors_generated = NULL;
-  gcry_mpi_t prime_generated = NULL;
-  unsigned int mode = 0;
-
-  if (!prime)
-    return gpg_error (GPG_ERR_INV_ARG);
-  *prime = NULL; 
-
-  if (flags & GCRY_PRIME_FLAG_SPECIAL_FACTOR)
-    mode = 1;
-
-  /* Generate.  */
-  err = prime_generate_internal ((mode==1), &prime_generated, prime_bits,
-                                factor_bits, NULL,
-                                 factors? &factors_generated : NULL,
-                                random_level, flags, 1,
-                                 cb_func, cb_arg);
-
-  if (! err)
-    if (cb_func)
-      {
-       /* Additional check. */
-       if ( !cb_func (cb_arg, GCRY_PRIME_CHECK_AT_FINISH, prime_generated))
-         {
-           /* Failed, deallocate resources.  */
-           unsigned int i;
-
-           mpi_free (prime_generated);
-            if (factors)
-              {
-                for (i = 0; factors_generated[i]; i++)
-                  mpi_free (factors_generated[i]);
-                gcry_free (factors_generated);
-              }
-           err = GPG_ERR_GENERAL; 
-         }
-      }
-
-  if (! err)
-    {
-      if (factors)
-        *factors = factors_generated;
-      *prime = prime_generated;
-    }
-
-  return gcry_error (err);
-}
-
-/* Check wether the number X is prime.  */
-gcry_error_t
-gcry_prime_check (gcry_mpi_t x, unsigned int flags)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_mpi_t val_2 = mpi_alloc_set_ui (2); /* Used by the Fermat test. */
-
-  (void)flags;
-
-  /* We use 64 rounds because the prime we are going to test is not
-     guaranteed to be a random one. */
-  if (! check_prime (x, val_2, 64, NULL, NULL))
-    err = GPG_ERR_NO_PRIME;
-
-  mpi_free (val_2);
-
-  return gcry_error (err);
-}
-
-/* Find a generator for PRIME where the factorization of (prime-1) is
-   in the NULL terminated array FACTORS. Return the generator as a
-   newly allocated MPI in R_G.  If START_G is not NULL, use this as s
-   atart for the search. Returns 0 on success.*/
-gcry_error_t
-gcry_prime_group_generator (gcry_mpi_t *r_g,
-                            gcry_mpi_t prime, gcry_mpi_t *factors,
-                            gcry_mpi_t start_g)
-{
-  gcry_mpi_t tmp = gcry_mpi_new (0);
-  gcry_mpi_t b = gcry_mpi_new (0);
-  gcry_mpi_t pmin1 = gcry_mpi_new (0);
-  gcry_mpi_t g = start_g? gcry_mpi_copy (start_g) : gcry_mpi_set_ui (NULL, 3);
-  int first = 1;
-  int i, n;
-
-  if (!factors || !r_g || !prime)
-    return gpg_error (GPG_ERR_INV_ARG);
-  *r_g = NULL; 
-
-  for (n=0; factors[n]; n++)
-    ;
-  if (n < 2)
-    return gpg_error (GPG_ERR_INV_ARG);
-
-  /* Extra sanity check - usually disabled. */  
-/*   mpi_set (tmp, factors[0]); */
-/*   for(i = 1; i < n; i++) */
-/*     mpi_mul (tmp, tmp, factors[i]); */
-/*   mpi_add_ui (tmp, tmp, 1); */
-/*   if (mpi_cmp (prime, tmp)) */
-/*     return gpg_error (GPG_ERR_INV_ARG); */
-  
-  gcry_mpi_sub_ui (pmin1, prime, 1);      
-  do         
-    {
-      if (first)
-        first = 0;
-      else
-        gcry_mpi_add_ui (g, g, 1);
-      
-      if (DBG_CIPHER)
-        {
-          log_debug ("checking g:");
-          gcry_mpi_dump (g);
-          log_debug ("\n");
-        }
-      else
-        progress('^');
-      
-      for (i = 0; i < n; i++)
-        {
-          mpi_fdiv_q (tmp, pmin1, factors[i]);
-          gcry_mpi_powm (b, g, tmp, prime);
-          if (! mpi_cmp_ui (b, 1))
-            break;
-        }
-      if (DBG_CIPHER)
-        progress('\n');
-    }
-  while (i < n);
-  
-  gcry_mpi_release (tmp);
-  gcry_mpi_release (b); 
-  gcry_mpi_release (pmin1); 
-  *r_g = g; 
-
-  return 0; 
-}
-
-/* Convenience function to release the factors array. */
-void
-gcry_prime_release_factors (gcry_mpi_t *factors)
-{
-  if (factors)
-    {
-      int i;
-      
-      for (i=0; factors[i]; i++)
-        mpi_free (factors[i]);
-      gcry_free (factors);
-    }
-}
-
-
-\f
-/* Helper for _gcry_derive_x931_prime.  */
-static gcry_mpi_t
-find_x931_prime (const gcry_mpi_t pfirst)
-{
-  gcry_mpi_t val_2 = mpi_alloc_set_ui (2); 
-  gcry_mpi_t prime;
-  
-  prime = gcry_mpi_copy (pfirst);
-  /* If P is even add 1.  */ 
-  mpi_set_bit (prime, 0);
-
-  /* We use 64 Rabin-Miller rounds which is better and thus
-     sufficient.  We do not have a Lucas test implementaion thus we
-     can't do it in the X9.31 preferred way of running a few
-     Rabin-Miller followed by one Lucas test.  */
-  while ( !check_prime (prime, val_2, 64, NULL, NULL) )
-    mpi_add_ui (prime, prime, 2);
-
-  mpi_free (val_2);
-
-  return prime;
-}
-
-
-/* Generate a prime using the algorithm from X9.31 appendix B.4. 
-
-   This function requires that the provided public exponent E is odd.
-   XP, XP1 and XP2 are the seed values.  All values are mandatory.
-
-   On success the prime is returned.  If R_P1 or R_P2 are given the
-   internal values P1 and P2 are saved at these addresses.  On error
-   NULL is returned.  */
-gcry_mpi_t
-_gcry_derive_x931_prime (const gcry_mpi_t xp, 
-                         const gcry_mpi_t xp1, const gcry_mpi_t xp2,
-                         const gcry_mpi_t e,
-                         gcry_mpi_t *r_p1, gcry_mpi_t *r_p2)
-{
-  gcry_mpi_t p1, p2, p1p2, yp0;
-
-  if (!xp || !xp1 || !xp2)
-    return NULL;
-  if (!e || !mpi_test_bit (e, 0))
-    return NULL;  /* We support only odd values for E.  */
-
-  p1 = find_x931_prime (xp1);
-  p2 = find_x931_prime (xp2);
-  p1p2 = mpi_alloc_like (xp);
-  mpi_mul (p1p2, p1, p2);
-
-  {
-    gcry_mpi_t r1, tmp;
-  
-    /* r1 = (p2^{-1} mod p1)p2 - (p1^{-1} mod p2) */
-    tmp = mpi_alloc_like (p1);
-    mpi_invm (tmp, p2, p1);
-    mpi_mul (tmp, tmp, p2);
-    r1 = tmp;
-    
-    tmp = mpi_alloc_like (p2);
-    mpi_invm (tmp, p1, p2);
-    mpi_mul (tmp, tmp, p1);
-    mpi_sub (r1, r1, tmp);
-
-    /* Fixup a negative value.  */
-    if (mpi_is_neg (r1)) 
-      mpi_add (r1, r1, p1p2);
-
-    /* yp0 = xp + (r1 - xp mod p1*p2)  */
-    yp0 = tmp; tmp = NULL;
-    mpi_subm (yp0, r1, xp, p1p2);
-    mpi_add (yp0, yp0, xp);
-    mpi_free (r1);
-
-    /* Fixup a negative value.  */
-    if (mpi_cmp (yp0, xp) < 0 ) 
-      mpi_add (yp0, yp0, p1p2);
-  }
-
-  /* yp0 is now the first integer greater than xp with p1 being a
-     large prime factor of yp0-1 and p2 a large prime factor of yp0+1.  */
-
-  /* Note that the first example from X9.31 (D.1.1) which uses
-       (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)
-       (Xq2 #134E4CAA16D2350A21D775C404#)
-       (Xq  #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
-             7C9953388F97DDDC3E1CA19C35CA659EDC2FC325
-             6D29C2627479C086A699A49C4C9CEE7EF7BD1B34
-             321DE34A#))))
-     returns an yp0 of
-            #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
-             7C9953388F97DDDC3E1CA19C35CA659EDC2FC4E3
-             BF20CB896EE37E098A906313271422162CB6C642
-             75C1201F#
-     and not
-            #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
-             7C9953388F97DDDC3E1CA19C35CA659EDC2FC2E6
-             C88FE299D52D78BE405A97E01FD71DD7819ECB91
-             FA85A076#
-     as stated in the standard.  This seems to be a bug in X9.31.
-   */
-
-  {
-    gcry_mpi_t val_2 = mpi_alloc_set_ui (2); 
-    gcry_mpi_t gcdtmp = mpi_alloc_like (yp0);
-    int gcdres;
-  
-    mpi_sub_ui (p1p2, p1p2, 1); /* Adjust for loop body.  */
-    mpi_sub_ui (yp0, yp0, 1);   /* Ditto.  */
-    for (;;)
-      {
-        gcdres = gcry_mpi_gcd (gcdtmp, e, yp0);
-        mpi_add_ui (yp0, yp0, 1);
-        if (!gcdres)
-          progress ('/');  /* gcd (e, yp0-1) != 1  */
-        else if (check_prime (yp0, val_2, 64, NULL, NULL))
-          break; /* Found.  */
-        /* We add p1p2-1 because yp0 is incremented after the gcd test.  */
-        mpi_add (yp0, yp0, p1p2);
-      }
-    mpi_free (gcdtmp);
-    mpi_free (val_2);
-  }
-
-  mpi_free (p1p2);
-
-  progress('\n');
-  if (r_p1)
-    *r_p1 = p1;
-  else
-    mpi_free (p1);
-  if (r_p2)
-    *r_p2 = p2;
-  else
-    mpi_free (p2);
-  return yp0;
-}
-
-
-\f
-/* Generate the two prime used for DSA using the algorithm specified
-   in FIPS 186-2.  PBITS is the desired length of the prime P and a
-   QBITS the length of the prime Q.  If SEED is not supplied and
-   SEEDLEN is 0 the function generates an appropriate SEED.  On
-   success the generated primes are stored at R_Q and R_P, the counter
-   value is stored at R_COUNTER and the seed actually used for
-   generation is stored at R_SEED and R_SEEDVALUE.  */
-gpg_err_code_t
-_gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
-                                const void *seed, size_t seedlen,
-                                gcry_mpi_t *r_q, gcry_mpi_t *r_p,
-                                int *r_counter,
-                                void **r_seed, size_t *r_seedlen)
-{
-  gpg_err_code_t ec;
-  unsigned char seed_help_buffer[160/8];  /* Used to hold a generated SEED. */
-  unsigned char *seed_plus;     /* Malloced buffer to hold SEED+x.  */
-  unsigned char digest[160/8];  /* Helper buffer for SHA-1 digest.  */
-  gcry_mpi_t val_2 = NULL;      /* Helper for the prime test.  */
-  gcry_mpi_t tmpval = NULL;     /* Helper variable.  */
-  int i;
-
-  unsigned char value_u[160/8];
-  int value_n, value_b, value_k;
-  int counter;
-  gcry_mpi_t value_w = NULL;
-  gcry_mpi_t value_x = NULL;
-  gcry_mpi_t prime_q = NULL;
-  gcry_mpi_t prime_p = NULL;
-
-  /* FIPS 186-2 allows only for 1024/160 bit.  */
-  if (pbits != 1024 || qbits != 160)
-    return GPG_ERR_INV_KEYLEN;
-
-  if (!seed && !seedlen)
-    ; /* No seed value given:  We are asked to generate it.  */
-  else if (!seed || seedlen < qbits/8)
-    return GPG_ERR_INV_ARG;
-  
-  /* Allocate a buffer to later compute SEED+some_increment. */
-  seed_plus = gcry_malloc (seedlen < 20? 20:seedlen);
-  if (!seed_plus)
-    {
-      ec = gpg_err_code_from_syserror ();
-      goto leave;
-    }
-
-  val_2   = mpi_alloc_set_ui (2);
-  value_n = (pbits - 1) / qbits;
-  value_b = (pbits - 1) - value_n * qbits;
-  value_w = gcry_mpi_new (pbits);
-  value_x = gcry_mpi_new (pbits);
-
- restart:  
-  /* Generate Q.  */
-  for (;;)
-    {
-      /* Step 1: Generate a (new) seed unless one has been supplied.  */
-      if (!seed)
-        {
-          seedlen = sizeof seed_help_buffer;
-          gcry_create_nonce (seed_help_buffer, seedlen);
-          seed = seed_help_buffer;
-        }
-      
-      /* Step 2: U = sha1(seed) ^ sha1((seed+1) mod 2^{qbits})  */
-      memcpy (seed_plus, seed, seedlen);
-      for (i=seedlen-1; i >= 0; i--)
-        {
-          seed_plus[i]++;
-          if (seed_plus[i])
-            break;
-        }
-      gcry_md_hash_buffer (GCRY_MD_SHA1, value_u, seed, seedlen);
-      gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
-      for (i=0; i < sizeof value_u; i++)
-        value_u[i] ^= digest[i];
-  
-      /* Step 3:  Form q from U  */
-      gcry_mpi_release (prime_q); prime_q = NULL;
-      ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG, 
-                                        value_u, sizeof value_u, NULL));
-      if (ec)
-        goto leave;
-      mpi_set_highbit (prime_q, qbits-1 );
-      mpi_set_bit (prime_q, 0);
-      
-      /* Step 4:  Test whether Q is prime using 64 round of Rabin-Miller.  */
-      if (check_prime (prime_q, val_2, 64, NULL, NULL))
-        break; /* Yes, Q is prime.  */
-
-      /* Step 5.  */
-      seed = NULL;  /* Force a new seed at Step 1.  */
-    }
-  
-  /* Step 6.  Note that we do no use an explicit offset but increment
-     SEED_PLUS accordingly.  SEED_PLUS is currently SEED+1.  */
-  counter = 0;
-
-  /* Generate P. */
-  prime_p = gcry_mpi_new (pbits);
-  for (;;)
-    {
-      /* Step 7: For k = 0,...n let 
-                   V_k = sha1(seed+offset+k) mod 2^{qbits}  
-         Step 8: W = V_0 + V_1*2^160 + 
-                         ... 
-                         + V_{n-1}*2^{(n-1)*160}
-                         + (V_{n} mod 2^b)*2^{n*160}                
-       */
-      mpi_set_ui (value_w, 0);
-      for (value_k=0; value_k <= value_n; value_k++)
-        {
-          /* There is no need to have an explicit offset variable:  In
-             the first round we shall have an offset of 2, this is
-             achieved by using SEED_PLUS which is already at SEED+1,
-             thus we just need to increment it once again.  The
-             requirement for the next round is to update offset by N,
-             which we implictly did at the end of this loop, and then
-             to add one; this one is the same as in the first round.  */
-          for (i=seedlen-1; i >= 0; i--)
-            {
-              seed_plus[i]++;
-              if (seed_plus[i])
-                break;
-            }
-          gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
-          
-          gcry_mpi_release (tmpval); tmpval = NULL;
-          ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
-                                            digest, sizeof digest, NULL));
-          if (ec)
-            goto leave;
-          if (value_k == value_n)
-            mpi_clear_highbit (tmpval, value_b); /* (V_n mod 2^b) */
-          mpi_lshift (tmpval, tmpval, value_k*qbits);
-          mpi_add (value_w, value_w, tmpval);
-        }
-
-      /* Step 8 continued: X = W + 2^{L-1}  */
-      mpi_set_ui (value_x, 0);
-      mpi_set_highbit (value_x, pbits-1);
-      mpi_add (value_x, value_x, value_w);
-
-      /* Step 9:  c = X mod 2q,  p = X - (c - 1)  */
-      mpi_mul_2exp (tmpval, prime_q, 1);
-      mpi_mod (tmpval, value_x, tmpval);
-      mpi_sub_ui (tmpval, tmpval, 1);
-      mpi_sub (prime_p, value_x, tmpval);
-
-      /* Step 10: If  p < 2^{L-1}  skip the primality test.  */
-      /* Step 11 and 12: Primality test.  */
-      if (mpi_get_nbits (prime_p) >= pbits-1
-          && check_prime (prime_p, val_2, 64, NULL, NULL) )
-        break; /* Yes, P is prime, continue with Step 15.  */
-
-      /* Step 13: counter = counter + 1, offset = offset + n + 1. */
-      counter++;
-
-      /* Step 14: If counter >= 2^12  goto Step 1.  */
-      if (counter >= 4096)
-        goto restart;
-    }
-
-  /* Step 15:  Save p, q, counter and seed.  */
-/*   log_debug ("fips186-2 pbits p=%u q=%u counter=%d\n", */
-/*              mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter); */
-/*   log_printhex("fips186-2 seed:", seed, seedlen); */
-/*   log_mpidump ("fips186-2 prime p", prime_p); */
-/*   log_mpidump ("fips186-2 prime q", prime_q); */
-  if (r_q)
-    {
-      *r_q = prime_q;
-      prime_q = NULL;
-    }
-  if (r_p)
-    {
-      *r_p = prime_p;
-      prime_p = NULL;
-    }
-  if (r_counter)
-    *r_counter = counter;
-  if (r_seed && r_seedlen)
-    {
-      memcpy (seed_plus, seed, seedlen);
-      *r_seed = seed_plus;
-      seed_plus = NULL;
-      *r_seedlen = seedlen;
-    }
-
-
- leave:
-  gcry_mpi_release (tmpval);
-  gcry_mpi_release (value_x);
-  gcry_mpi_release (value_w);
-  gcry_mpi_release (prime_p);
-  gcry_mpi_release (prime_q);
-  gcry_free (seed_plus);
-  gcry_mpi_release (val_2);
-  return ec;
-}
-
-
-\f
-/* WARNING: The code below has not yet been tested!  However, it is
-   not yet used.  We need to wait for FIPS 186-3 final and for test
-   vectors.
-
-   Generate the two prime used for DSA using the algorithm specified
-   in FIPS 186-3, A.1.1.2.  PBITS is the desired length of the prime P
-   and a QBITS the length of the prime Q.  If SEED is not supplied and
-   SEEDLEN is 0 the function generates an appropriate SEED.  On
-   success the generated primes are stored at R_Q and R_P, the counter
-   value is stored at R_COUNTER and the seed actually used for
-   generation is stored at R_SEED and R_SEEDVALUE.  The hash algorithm
-   used is stored at R_HASHALGO.
-   
-   Note that this function is very similar to the fips186_2 code.  Due
-   to the minor differences, other buffer sizes and for documentarion,
-   we use a separate function.
-*/
-gpg_err_code_t
-_gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
-                                const void *seed, size_t seedlen,
-                                gcry_mpi_t *r_q, gcry_mpi_t *r_p,
-                                int *r_counter,
-                                void **r_seed, size_t *r_seedlen,
-                                int *r_hashalgo)
-{
-  gpg_err_code_t ec;
-  unsigned char seed_help_buffer[256/8];  /* Used to hold a generated SEED. */
-  unsigned char *seed_plus;     /* Malloced buffer to hold SEED+x.  */
-  unsigned char digest[256/8];  /* Helper buffer for SHA-1 digest.  */
-  gcry_mpi_t val_2 = NULL;      /* Helper for the prime test.  */
-  gcry_mpi_t tmpval = NULL;     /* Helper variable.  */
-  int hashalgo;                 /* The id of the Approved Hash Function.  */
-  int i;
-  
-  unsigned char value_u[256/8];
-  int value_n, value_b, value_j;
-  int counter;
-  gcry_mpi_t value_w = NULL;
-  gcry_mpi_t value_x = NULL;
-  gcry_mpi_t prime_q = NULL;
-  gcry_mpi_t prime_p = NULL;
-
-  gcry_assert (sizeof seed_help_buffer == sizeof digest
-               && sizeof seed_help_buffer == sizeof value_u);
-
-  /* Step 1:  Check the requested prime lengths.  */
-  /* Note that due to the size of our buffers QBITS is limited to 256.  */
-  if (pbits == 1024 && qbits == 160)
-    hashalgo = GCRY_MD_SHA1;
-  else if (pbits == 2048 && qbits == 224)
-    hashalgo = GCRY_MD_SHA224;
-  else if (pbits == 2048 && qbits == 256)
-    hashalgo = GCRY_MD_SHA256;
-  else if (pbits == 3072 && qbits == 256)
-    hashalgo = GCRY_MD_SHA256;
-  else
-    return GPG_ERR_INV_KEYLEN;
-
-  /* Also check that the hash algorithm is available.  */
-  ec = gpg_err_code (gcry_md_test_algo (hashalgo));
-  if (ec)
-    return ec;
-  gcry_assert (qbits/8 <= sizeof digest);
-  gcry_assert (gcry_md_get_algo_dlen (hashalgo) == qbits/8);
-
-
-  /* Step 2:  Check seedlen.  */
-  if (!seed && !seedlen)
-    ; /* No seed value given:  We are asked to generate it.  */
-  else if (!seed || seedlen < qbits/8)
-    return GPG_ERR_INV_ARG;
-  
-  /* Allocate a buffer to later compute SEED+some_increment and a few
-     helper variables.  */
-  seed_plus = gcry_malloc (seedlen < sizeof seed_help_buffer? 
-                           sizeof seed_help_buffer : seedlen);
-  if (!seed_plus)
-    {
-      ec = gpg_err_code_from_syserror ();
-      goto leave;
-    }
-  val_2   = mpi_alloc_set_ui (2);
-  value_w = gcry_mpi_new (pbits);
-  value_x = gcry_mpi_new (pbits);
-
-  /* Step 3: n = \lceil L / outlen \rceil - 1  */
-  value_n = (pbits + qbits - 1) / qbits - 1;
-  /* Step 4: b = L - 1 - (n * outlen)  */
-  value_b = pbits - 1 - (value_n * qbits);
-
- restart:  
-  /* Generate Q.  */
-  for (;;)
-    {
-      /* Step 5:  Generate a (new) seed unless one has been supplied.  */
-      if (!seed)
-        {
-          seedlen = qbits/8;
-          gcry_assert (seedlen <= sizeof seed_help_buffer);
-          gcry_create_nonce (seed_help_buffer, seedlen);
-          seed = seed_help_buffer;
-        }
-      
-      /* Step 6:  U = hash(seed)  */
-      gcry_md_hash_buffer (hashalgo, value_u, seed, seedlen);
-
-      /* Step 7:  q = 2^{N-1} + U + 1 - (U mod 2)  */
-      if ( !(value_u[qbits/8-1] & 0x01) )
-        {
-          for (i=qbits/8-1; i >= 0; i--)
-            {
-              value_u[i]++;
-              if (value_u[i])
-                break;
-            }
-        }
-      gcry_mpi_release (prime_q); prime_q = NULL;
-      ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG, 
-                                        value_u, sizeof value_u, NULL));
-      if (ec)
-        goto leave;
-      mpi_set_highbit (prime_q, qbits-1 );
-      
-      /* Step 8:  Test whether Q is prime using 64 round of Rabin-Miller.
-                  According to table C.1 this is sufficient for all
-                  supported prime sizes (i.e. up 3072/256).  */
-      if (check_prime (prime_q, val_2, 64, NULL, NULL))
-        break; /* Yes, Q is prime.  */
-
-      /* Step 8.  */
-      seed = NULL;  /* Force a new seed at Step 5.  */
-    }
-  
-  /* Step 11.  Note that we do no use an explicit offset but increment
-     SEED_PLUS accordingly.  */
-  memcpy (seed_plus, seed, seedlen);
-  counter = 0;
-
-  /* Generate P. */
-  prime_p = gcry_mpi_new (pbits);
-  for (;;)
-    {
-      /* Step 11.1: For j = 0,...n let 
-                      V_j = hash(seed+offset+j)  
-         Step 11.2: W = V_0 + V_1*2^outlen + 
-                            ... 
-                            + V_{n-1}*2^{(n-1)*outlen}
-                            + (V_{n} mod 2^b)*2^{n*outlen}                
-       */
-      mpi_set_ui (value_w, 0);
-      for (value_j=0; value_j <= value_n; value_j++)
-        {
-          /* There is no need to have an explicit offset variable: In
-             the first round we shall have an offset of 1 and a j of
-             0.  This is achieved by incrementing SEED_PLUS here.  For
-             the next round offset is implicitly updated by using
-             SEED_PLUS again.  */
-          for (i=seedlen-1; i >= 0; i--)
-            {
-              seed_plus[i]++;
-              if (seed_plus[i])
-                break;
-            }
-          gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
-          
-          gcry_mpi_release (tmpval); tmpval = NULL;
-          ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
-                                            digest, sizeof digest, NULL));
-          if (ec)
-            goto leave;
-          if (value_j == value_n)
-            mpi_clear_highbit (tmpval, value_b); /* (V_n mod 2^b) */
-          mpi_lshift (tmpval, tmpval, value_j*qbits);
-          mpi_add (value_w, value_w, tmpval);
-        }
-
-      /* Step 11.3: X = W + 2^{L-1}  */
-      mpi_set_ui (value_x, 0);
-      mpi_set_highbit (value_x, pbits-1);
-      mpi_add (value_x, value_x, value_w);
-
-      /* Step 11.4:  c = X mod 2q  */
-      mpi_mul_2exp (tmpval, prime_q, 1);
-      mpi_mod (tmpval, value_x, tmpval);
-
-      /* Step 11.5:  p = X - (c - 1)  */
-      mpi_sub_ui (tmpval, tmpval, 1);
-      mpi_sub (prime_p, value_x, tmpval);
-
-      /* Step 11.6: If  p < 2^{L-1}  skip the primality test.  */
-      /* Step 11.7 and 11.8: Primality test.  */
-      if (mpi_get_nbits (prime_p) >= pbits-1
-          && check_prime (prime_p, val_2, 64, NULL, NULL) )
-        break; /* Yes, P is prime, continue with Step 15.  */
-      
-      /* Step 11.9: counter = counter + 1, offset = offset + n + 1.
-                    If counter >= 4L  goto Step 5.  */
-      counter++;
-      if (counter >= 4*pbits)
-        goto restart;
-    }
-
-  /* Step 12:  Save p, q, counter and seed.  */
-  log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n",
-             mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter);
-  log_printhex("fips186-3 seed:", seed, seedlen);
-  log_mpidump ("fips186-3 prime p", prime_p);
-  log_mpidump ("fips186-3 prime q", prime_q);
-  if (r_q)
-    {
-      *r_q = prime_q;
-      prime_q = NULL;
-    }
-  if (r_p)
-    {
-      *r_p = prime_p;
-      prime_p = NULL;
-    }
-  if (r_counter)
-    *r_counter = counter;
-  if (r_seed && r_seedlen)
-    {
-      memcpy (seed_plus, seed, seedlen);
-      *r_seed = seed_plus;
-      seed_plus = NULL;
-      *r_seedlen = seedlen;
-    }
-  if (r_hashalgo)
-    *r_hashalgo = hashalgo;
-
- leave:
-  gcry_mpi_release (tmpval);
-  gcry_mpi_release (value_x);
-  gcry_mpi_release (value_w);
-  gcry_mpi_release (prime_p);
-  gcry_mpi_release (prime_q);
-  gcry_free (seed_plus);
-  gcry_mpi_release (val_2);
-  return ec;
-}
-
diff --git a/lib/libgcrypt/cipher/pubkey.c b/lib/libgcrypt/cipher/pubkey.c
deleted file mode 100644 (file)
index 08abcbf..0000000
+++ /dev/null
@@ -1,2749 +0,0 @@
-/* pubkey.c  - pubkey dispatcher
- * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005, 
- *               2007, 2008 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#include "g10lib.h"
-#include "mpi.h"
-#include "cipher.h"
-#include "ath.h"
-
-
-static gcry_err_code_t pubkey_decrypt (int algo, gcry_mpi_t *result,
-                                       gcry_mpi_t *data, gcry_mpi_t *skey,
-                                       int flags);
-static gcry_err_code_t pubkey_sign (int algo, gcry_mpi_t *resarr,
-                                    gcry_mpi_t hash, gcry_mpi_t *skey);
-static gcry_err_code_t pubkey_verify (int algo, gcry_mpi_t hash,
-                                      gcry_mpi_t *data, gcry_mpi_t *pkey,
-                                    int (*cmp) (void *, gcry_mpi_t),
-                                      void *opaque);
-
-
-/* A dummy extraspec so that we do not need to tests the extraspec
-   field from the module specification against NULL and instead
-   directly test the respective fields of extraspecs.  */
-static pk_extra_spec_t dummy_extra_spec;
-
-
-/* This is the list of the default public-key ciphers included in
-   libgcrypt.  FIPS_ALLOWED indicated whether the algorithm is used in
-   FIPS mode. */
-static struct pubkey_table_entry
-{
-  gcry_pk_spec_t *pubkey;
-  pk_extra_spec_t *extraspec;
-  unsigned int algorithm;
-  int fips_allowed; 
-} pubkey_table[] =
-  {
-#if USE_RSA
-    { &_gcry_pubkey_spec_rsa,
-      &_gcry_pubkey_extraspec_rsa,   GCRY_PK_RSA, 1},
-#endif
-#if USE_ELGAMAL
-    { &_gcry_pubkey_spec_elg,
-      &_gcry_pubkey_extraspec_elg,    GCRY_PK_ELG   },
-    { &_gcry_pubkey_spec_elg,
-      &_gcry_pubkey_extraspec_elg,    GCRY_PK_ELG_E },
-#endif
-#if USE_DSA
-    { &_gcry_pubkey_spec_dsa,
-      &_gcry_pubkey_extraspec_dsa,   GCRY_PK_DSA, 1   },
-#endif
-#if USE_ECC
-    { &_gcry_pubkey_spec_ecdsa,
-      &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDSA, 0 },
-#endif
-    { NULL, 0 },
-  };
-
-/* List of registered ciphers.  */
-static gcry_module_t pubkeys_registered;
-
-/* This is the lock protecting PUBKEYS_REGISTERED.  */
-static ath_mutex_t pubkeys_registered_lock = ATH_MUTEX_INITIALIZER;;
-
-/* Flag to check wether the default pubkeys have already been
-   registered.  */
-static int default_pubkeys_registered;
-
-/* Convenient macro for registering the default digests.  */
-#define REGISTER_DEFAULT_PUBKEYS                   \
-  do                                               \
-    {                                              \
-      ath_mutex_lock (&pubkeys_registered_lock);   \
-      if (! default_pubkeys_registered)            \
-        {                                          \
-          pk_register_default ();                  \
-          default_pubkeys_registered = 1;          \
-        }                                          \
-      ath_mutex_unlock (&pubkeys_registered_lock); \
-    }                                              \
-  while (0)
-
-/* These dummy functions are used in case a cipher implementation
-   refuses to provide it's own functions.  */
-
-static gcry_err_code_t
-dummy_generate (int algorithm, unsigned int nbits, unsigned long dummy,
-                gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-{
-  (void)algorithm;
-  (void)nbits;
-  (void)dummy;
-  (void)skey;
-  (void)retfactors;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
-}
-
-static gcry_err_code_t
-dummy_check_secret_key (int algorithm, gcry_mpi_t *skey)
-{
-  (void)algorithm;
-  (void)skey;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
-}
-
-static gcry_err_code_t
-dummy_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
-               gcry_mpi_t *pkey, int flags)
-{
-  (void)algorithm;
-  (void)resarr;
-  (void)data;
-  (void)pkey;
-  (void)flags;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
-}
-
-static gcry_err_code_t
-dummy_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
-               gcry_mpi_t *skey, int flags)
-{
-  (void)algorithm;
-  (void)result;
-  (void)data;
-  (void)skey;
-  (void)flags;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
-}
-
-static gcry_err_code_t
-dummy_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
-            gcry_mpi_t *skey)
-{
-  (void)algorithm;
-  (void)resarr;
-  (void)data;
-  (void)skey;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
-}
-
-static gcry_err_code_t
-dummy_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
-              gcry_mpi_t *pkey,
-             int (*cmp) (void *, gcry_mpi_t), void *opaquev)
-{
-  (void)algorithm;
-  (void)hash;
-  (void)data;
-  (void)pkey;
-  (void)cmp;
-  (void)opaquev;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
-}
-
-static unsigned
-dummy_get_nbits (int algorithm, gcry_mpi_t *pkey)
-{
-  (void)algorithm;
-  (void)pkey;
-  fips_signal_error ("using dummy public key function");
-  return 0;
-}
-
-/* Internal function.  Register all the pubkeys included in
-   PUBKEY_TABLE.  Returns zero on success or an error code.  */
-static void
-pk_register_default (void)
-{
-  gcry_err_code_t err = 0;
-  int i;
-  
-  for (i = 0; (! err) && pubkey_table[i].pubkey; i++)
-    {
-#define pubkey_use_dummy(func)                       \
-      if (! pubkey_table[i].pubkey->func)            \
-       pubkey_table[i].pubkey->func = dummy_##func;
-
-      pubkey_use_dummy (generate);
-      pubkey_use_dummy (check_secret_key);
-      pubkey_use_dummy (encrypt);
-      pubkey_use_dummy (decrypt);
-      pubkey_use_dummy (sign);
-      pubkey_use_dummy (verify);
-      pubkey_use_dummy (get_nbits);
-#undef pubkey_use_dummy
-
-      err = _gcry_module_add (&pubkeys_registered,
-                             pubkey_table[i].algorithm,
-                             (void *) pubkey_table[i].pubkey, 
-                             (void *) pubkey_table[i].extraspec, 
-                              NULL);
-    }
-
-  if (err)
-    BUG ();
-}
-
-/* Internal callback function.  Used via _gcry_module_lookup.  */
-static int
-gcry_pk_lookup_func_name (void *spec, void *data)
-{
-  gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) spec;
-  char *name = (char *) data;
-  const char **aliases = pubkey->aliases;
-  int ret = stricmp (name, pubkey->name);
-
-  while (ret && *aliases)
-    ret = stricmp (name, *aliases++);
-
-  return ! ret;
-}
-
-/* Internal function.  Lookup a pubkey entry by it's name.  */
-static gcry_module_t 
-gcry_pk_lookup_name (const char *name)
-{
-  gcry_module_t pubkey;
-
-  pubkey = _gcry_module_lookup (pubkeys_registered, (void *) name,
-                               gcry_pk_lookup_func_name);
-
-  return pubkey;
-}
-
-/* Register a new pubkey module whose specification can be found in
-   PUBKEY.  On success, a new algorithm ID is stored in ALGORITHM_ID
-   and a pointer representhing this module is stored in MODULE.  */
-gcry_error_t
-_gcry_pk_register (gcry_pk_spec_t *pubkey,
-                   pk_extra_spec_t *extraspec,
-                   unsigned int *algorithm_id,
-                   gcry_module_t *module)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_module_t mod;
-
-  /* We do not support module loading in fips mode.  */
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  err = _gcry_module_add (&pubkeys_registered, 0,
-                         (void *) pubkey, 
-                         (void *)(extraspec? extraspec : &dummy_extra_spec), 
-                          &mod);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  if (! err)
-    {
-      *module = mod;
-      *algorithm_id = mod->mod_id;
-    }
-
-  return err;
-}
-
-/* Unregister the pubkey identified by ID, which must have been
-   registered with gcry_pk_register.  */
-void
-gcry_pk_unregister (gcry_module_t module)
-{
-  ath_mutex_lock (&pubkeys_registered_lock);
-  _gcry_module_release (module);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-}
-
-static void
-release_mpi_array (gcry_mpi_t *array)
-{
-  for (; *array; array++)
-    {
-      mpi_free(*array);
-      *array = NULL;
-    }
-}
-
-/****************
- * Map a string to the pubkey algo
- */
-int
-gcry_pk_map_name (const char *string)
-{
-  gcry_module_t pubkey;
-  int algorithm = 0;
-
-  if (!string)
-    return 0;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = gcry_pk_lookup_name (string);
-  if (pubkey)
-    {
-      algorithm = pubkey->mod_id;
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return algorithm;
-}
-
-
-/* Map the public key algorithm whose ID is contained in ALGORITHM to
-   a string representation of the algorithm name.  For unknown
-   algorithm IDs this functions returns "?". */
-const char *
-gcry_pk_algo_name (int algorithm)
-{
-  gcry_module_t pubkey;
-  const char *name;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      name = ((gcry_pk_spec_t *) pubkey->spec)->name;
-      _gcry_module_release (pubkey);
-    }
-  else
-    name = "?";
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return name;
-}
-
-
-/* A special version of gcry_pk_algo name to return the first aliased
-   name of the algorithm.  This is required to adhere to the spki
-   specs where the algorithm names are lowercase. */
-const char *
-_gcry_pk_aliased_algo_name (int algorithm)
-{
-  const char *name = NULL;
-  gcry_module_t module;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
-    {
-      gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) module->spec;
-
-      name = pubkey->aliases? *pubkey->aliases : NULL;
-      if (!name || !*name)
-        name = pubkey->name;
-      _gcry_module_release (module);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return name;
-}
-
-
-static void
-disable_pubkey_algo (int algorithm)
-{
-  gcry_module_t pubkey;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      if (! (pubkey-> flags & FLAG_MODULE_DISABLED))
-       pubkey->flags |= FLAG_MODULE_DISABLED;
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-}
-
-
-/****************
- * A USE of 0 means: don't care.
- */
-static gcry_err_code_t
-check_pubkey_algo (int algorithm, unsigned use)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_pk_spec_t *pubkey;
-  gcry_module_t module;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-
-      if (((use & GCRY_PK_USAGE_SIGN)
-          && (! (pubkey->use & GCRY_PK_USAGE_SIGN)))
-         || ((use & GCRY_PK_USAGE_ENCR)
-             && (! (pubkey->use & GCRY_PK_USAGE_ENCR))))
-       err = GPG_ERR_WRONG_PUBKEY_ALGO;
-      else if (module->flags & FLAG_MODULE_DISABLED)
-       err = GPG_ERR_PUBKEY_ALGO;
-      _gcry_module_release (module);
-    }
-  else
-    err = GPG_ERR_PUBKEY_ALGO;
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return err;
-}
-
-
-/****************
- * Return the number of public key material numbers
- */
-static int
-pubkey_get_npkey (int algorithm)
-{
-  gcry_module_t pubkey;
-  int npkey = 0;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      npkey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_pkey);
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return npkey;
-}
-
-/****************
- * Return the number of secret key material numbers
- */
-static int
-pubkey_get_nskey (int algorithm)
-{
-  gcry_module_t pubkey;
-  int nskey = 0;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      nskey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_skey);
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return nskey;
-}
-
-/****************
- * Return the number of signature material numbers
- */
-static int
-pubkey_get_nsig (int algorithm)
-{
-  gcry_module_t pubkey;
-  int nsig = 0;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      nsig = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_sig);
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return nsig;
-}
-
-/****************
- * Return the number of encryption material numbers
- */
-static int
-pubkey_get_nenc (int algorithm)
-{
-  gcry_module_t pubkey;
-  int nenc = 0;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      nenc = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_enc);
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return nenc;
-}
-
-
-/* Generate a new public key with algorithm ALGORITHM of size NBITS
-   and return it at SKEY.  USE_E depends on the ALGORITHM.  GENPARMS
-   is passed to the algorithm module if it features an extended
-   generation function.  RETFACTOR is used by some algorithms to
-   return certain additional information which are in general not
-   required.
-
-   The function returns the error code number or 0 on success. */
-static gcry_err_code_t
-pubkey_generate (int algorithm,
-                 unsigned int nbits,
-                 unsigned long use_e,
-                 gcry_sexp_t genparms,
-                 gcry_mpi_t *skey, gcry_mpi_t **retfactors,
-                 gcry_sexp_t *r_extrainfo)
-{
-  gcry_err_code_t ec = GPG_ERR_PUBKEY_ALGO;
-  gcry_module_t pubkey;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      pk_extra_spec_t *extraspec = pubkey->extraspec;
-
-      if (extraspec && extraspec->ext_generate)
-        {
-          /* Use the extended generate function.  */
-          ec = extraspec->ext_generate 
-            (algorithm, nbits, use_e, genparms, skey, retfactors, r_extrainfo);
-        }
-      else
-        {
-          /* Use the standard generate function.  */
-          ec = ((gcry_pk_spec_t *) pubkey->spec)->generate 
-            (algorithm, nbits, use_e, skey, retfactors);
-        }
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return ec;
-}
-
-
-static gcry_err_code_t
-pubkey_check_secret_key (int algorithm, gcry_mpi_t *skey)
-{
-  gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO;
-  gcry_module_t pubkey;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      err = ((gcry_pk_spec_t *) pubkey->spec)->check_secret_key
-        (algorithm, skey);
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return err;
-}
-
-
-/****************
- * This is the interface to the public key encryption.  Encrypt DATA
- * with PKEY and put it into RESARR which should be an array of MPIs
- * of size PUBKEY_MAX_NENC (or less if the algorithm allows this -
- * check with pubkey_get_nenc() )
- */
-static gcry_err_code_t
-pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
-                gcry_mpi_t *pkey, int flags)
-{
-  gcry_pk_spec_t *pubkey;
-  gcry_module_t module;
-  gcry_err_code_t rc;
-  int i;
-
-  /* Note: In fips mode DBG_CIPHER will enver evaluate to true but as
-     an extra failsafe protection we explicitly test for fips mode
-     here. */ 
-  if (DBG_CIPHER && !fips_mode ())
-    {
-      log_debug ("pubkey_encrypt: algo=%d\n", algorithm);
-      for(i = 0; i < pubkey_get_npkey (algorithm); i++)
-       log_mpidump ("  pkey:", pkey[i]);
-      log_mpidump ("  data:", data);
-    }
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = pubkey->encrypt (algorithm, resarr, data, pkey, flags);
-      _gcry_module_release (module);
-      goto ready;
-    }
-  rc = GPG_ERR_PUBKEY_ALGO;
-
- ready:
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  if (!rc && DBG_CIPHER && !fips_mode ())
-    {
-      for(i = 0; i < pubkey_get_nenc (algorithm); i++)
-       log_mpidump("  encr:", resarr[i] );
-    }
-  return rc;
-}
-
-
-/****************
- * This is the interface to the public key decryption.
- * ALGO gives the algorithm to use and this implicitly determines
- * the size of the arrays.
- * result is a pointer to a mpi variable which will receive a
- * newly allocated mpi or NULL in case of an error.
- */
-static gcry_err_code_t
-pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
-                gcry_mpi_t *skey, int flags)
-{
-  gcry_pk_spec_t *pubkey;
-  gcry_module_t module;
-  gcry_err_code_t rc;
-  int i;
-
-  *result = NULL; /* so the caller can always do a mpi_free */
-  if (DBG_CIPHER && !fips_mode ())
-    {
-      log_debug ("pubkey_decrypt: algo=%d\n", algorithm);
-      for(i = 0; i < pubkey_get_nskey (algorithm); i++)
-       log_mpidump ("  skey:", skey[i]);
-      for(i = 0; i < pubkey_get_nenc (algorithm); i++)
-       log_mpidump ("  data:", data[i]);
-    }
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = pubkey->decrypt (algorithm, result, data, skey, flags);
-      _gcry_module_release (module);
-      goto ready;
-    }
-
-  rc = GPG_ERR_PUBKEY_ALGO;
-  
- ready:
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  if (!rc && DBG_CIPHER && !fips_mode ())
-    log_mpidump (" plain:", *result);
-
-  return rc;
-}
-
-
-/****************
- * This is the interface to the public key signing.
- * Sign data with skey and put the result into resarr which
- * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
- * algorithm allows this - check with pubkey_get_nsig() )
- */
-static gcry_err_code_t
-pubkey_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
-             gcry_mpi_t *skey)
-{
-  gcry_pk_spec_t *pubkey;
-  gcry_module_t module;
-  gcry_err_code_t rc;
-  int i;
-
-  if (DBG_CIPHER && !fips_mode ())
-    {
-      log_debug ("pubkey_sign: algo=%d\n", algorithm);
-      for(i = 0; i < pubkey_get_nskey (algorithm); i++)
-       log_mpidump ("  skey:", skey[i]);
-      log_mpidump("  data:", data );
-    }
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = pubkey->sign (algorithm, resarr, data, skey);
-      _gcry_module_release (module);
-      goto ready;
-    }
-
-  rc = GPG_ERR_PUBKEY_ALGO;
-
- ready:
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  if (!rc && DBG_CIPHER && !fips_mode ())
-    for (i = 0; i < pubkey_get_nsig (algorithm); i++)
-      log_mpidump ("   sig:", resarr[i]);
-
-  return rc;
-}
-
-/****************
- * Verify a public key signature.
- * Return 0 if the signature is good
- */
-static gcry_err_code_t
-pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
-               gcry_mpi_t *pkey,
-              int (*cmp)(void *, gcry_mpi_t), void *opaquev)
-{
-  gcry_pk_spec_t *pubkey;
-  gcry_module_t module;
-  gcry_err_code_t rc;
-  int i;
-
-  if (DBG_CIPHER && !fips_mode ())
-    {
-      log_debug ("pubkey_verify: algo=%d\n", algorithm);
-      for (i = 0; i < pubkey_get_npkey (algorithm); i++)
-       log_mpidump ("  pkey:", pkey[i]);
-      for (i = 0; i < pubkey_get_nsig (algorithm); i++)
-       log_mpidump ("   sig:", data[i]);
-      log_mpidump ("  hash:", hash);
-    }
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = pubkey->verify (algorithm, hash, data, pkey, cmp, opaquev);
-      _gcry_module_release (module);
-      goto ready;
-    }
-
-  rc = GPG_ERR_PUBKEY_ALGO;
-
- ready:
-  ath_mutex_unlock (&pubkeys_registered_lock);
-  return rc;
-}
-
-
-/* Internal function.   */
-static gcry_err_code_t
-sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
-                      gcry_mpi_t *elements, const char *algo_name)
-{
-  gcry_err_code_t err = 0;
-  int i, idx;
-  const char *name;
-  gcry_sexp_t list;
-
-  for (name = element_names, idx = 0; *name && !err; name++, idx++)
-    {
-      list = gcry_sexp_find_token (key_sexp, name, 1);
-      if (!list)
-       elements[idx] = NULL;
-      else
-       {
-         elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
-         gcry_sexp_release (list);
-         if (!elements[idx])
-           err = GPG_ERR_INV_OBJ;
-       }
-    }
-
-  if (!err)
-    {
-      /* Check that all elements are available.  */
-      for (name = element_names, idx = 0; *name; name++, idx++)
-        if (!elements[idx])
-          break;
-      if (*name)
-        {
-          err = GPG_ERR_NO_OBJ;
-          /* Some are missing.  Before bailing out we test for
-             optional parameters.  */
-          if (algo_name && !strcmp (algo_name, "RSA")
-              && !strcmp (element_names, "nedpqu") )
-            {
-              /* This is RSA.  Test whether we got N, E and D and that
-                 the optional P, Q and U are all missing.  */
-              if (elements[0] && elements[1] && elements[2]
-                  && !elements[3] && !elements[4] && !elements[5])
-                err = 0;
-            }
-        }
-    }
-
-
-  if (err)
-    {
-      for (i = 0; i < idx; i++)
-        if (elements[i])
-          gcry_free (elements[i]);
-    }
-  return err;
-}
-
-
-/* Internal function used for ecc.  Note, that this function makes use
-   of its intimate knowledge about the ECC parameters from ecc.c. */
-static gcry_err_code_t
-sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
-                           gcry_mpi_t *elements, pk_extra_spec_t *extraspec)
-
-{
-  gcry_err_code_t err = 0;
-  int idx;
-  const char *name;
-  gcry_sexp_t list;
-
-  /* Clear the array for easier error cleanup. */
-  for (name = element_names, idx = 0; *name; name++, idx++)
-    elements[idx] = NULL;
-  gcry_assert (idx >= 6); /* We know that ECC has at least 6 elements.  */
-
-  /* Init the array with the available curve parameters. */
-  for (name = element_names, idx = 0; *name && !err; name++, idx++)
-    {
-      list = gcry_sexp_find_token (key_sexp, name, 1);
-      if (!list)
-       elements[idx] = NULL;
-      else
-       {
-         elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
-         gcry_sexp_release (list);
-         if (!elements[idx])
-            {
-              err = GPG_ERR_INV_OBJ;
-              goto leave;
-            }
-       }
-    }
-
-  /* Check whether a curve parameter has been given and then fill any
-     missing elements.  */
-  list = gcry_sexp_find_token (key_sexp, "curve", 5);
-  if (list)
-    {
-      if (extraspec->get_param)
-        {
-          char *curve;
-          gcry_mpi_t params[6];
-          
-          for (idx = 0; idx < DIM(params); idx++)
-            params[idx] = NULL;
-          
-          curve = _gcry_sexp_nth_string (list, 1);
-          gcry_sexp_release (list);
-          if (!curve)
-            {
-              /* No curve name given (or out of core). */
-              err = GPG_ERR_INV_OBJ; 
-              goto leave;
-            }
-          err = extraspec->get_param (curve, params);
-          gcry_free (curve);
-          if (err)
-            goto leave;
-          
-          for (idx = 0; idx < DIM(params); idx++)
-            {
-              if (!elements[idx])
-                elements[idx] = params[idx];
-              else
-                mpi_free (params[idx]);
-            }
-        }
-      else
-        {
-          gcry_sexp_release (list);
-          err = GPG_ERR_INV_OBJ; /* "curve" given but ECC not supported. */
-          goto leave;
-        }
-    }
-
-  /* Check that all parameters are known.  */
-  for (name = element_names, idx = 0; *name; name++, idx++)
-    if (!elements[idx])
-      {
-        err = GPG_ERR_NO_OBJ;
-        goto leave;
-      }
-  
- leave:
-  if (err)
-    {
-      for (name = element_names, idx = 0; *name; name++, idx++)
-        if (elements[idx])
-          gcry_free (elements[idx]);
-    }
-  return err;
-}
-
-
-
-/****************
- * Convert a S-Exp with either a private or a public key to our
- * internal format. Currently we do only support the following
- * algorithms:
- *    dsa
- *    rsa
- *    openpgp-dsa
- *    openpgp-rsa
- *    openpgp-elg
- *    openpgp-elg-sig
- *    ecdsa
- * Provide a SE with the first element be either "private-key" or
- * or "public-key". It is followed by a list with its first element
- * be one of the above algorithm identifiers and the remaning
- * elements are pairs with parameter-id and value.
- * NOTE: we look through the list to find a list beginning with
- * "private-key" or "public-key" - the first one found is used.
- *
- * Returns: A pointer to an allocated array of MPIs if the return value is
- *         zero; the caller has to release this array.
- *
- * Example of a DSA public key:
- *  (private-key
- *    (dsa
- *     (p <mpi>)
- *     (g <mpi>)
- *     (y <mpi>)
- *     (x <mpi>)
- *    )
- *  )
- * The <mpi> are expected to be in GCRYMPI_FMT_USG
- */
-static gcry_err_code_t
-sexp_to_key (gcry_sexp_t sexp, int want_private, gcry_mpi_t **retarray,
-             gcry_module_t *retalgo)
-{
-  gcry_err_code_t err = 0;
-  gcry_sexp_t list, l2;
-  char *name;
-  const char *elems;
-  gcry_mpi_t *array;
-  gcry_module_t module;
-  gcry_pk_spec_t *pubkey;
-  pk_extra_spec_t *extraspec;
-  int is_ecc;
-
-  /* Check that the first element is valid.  */
-  list = gcry_sexp_find_token (sexp, 
-                               want_private? "private-key":"public-key", 0);
-  if (!list)
-    return GPG_ERR_INV_OBJ; /* Does not contain a key object.  */
-
-  l2 = gcry_sexp_cadr( list );
-  gcry_sexp_release ( list );
-  list = l2;
-  name = _gcry_sexp_nth_string (list, 0);
-  if (!name)
-    {
-      gcry_sexp_release ( list );
-      return GPG_ERR_INV_OBJ;      /* Invalid structure of object. */
-    }
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name (name);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-  
-  /* Fixme: We should make sure that an ECC key is always named "ecc"
-     and not "ecdsa".  "ecdsa" should be used for the signature
-     itself.  We need a function to test whether an algorithm given
-     with a key is compatible with an application of the key (signing,
-     encryption).  For RSA this is easy, but ECC is the first
-     algorithm which has many flavours. */
-  is_ecc = ( !strcmp (name, "ecdsa") || !strcmp (name, "ecc") );
-  gcry_free (name);
-  
-  if (!module)
-    {
-      gcry_sexp_release (list);
-      return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
-    }
-  else
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      extraspec = module->extraspec;
-    }
-
-  elems = want_private ? pubkey->elements_skey : pubkey->elements_pkey;
-  array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
-  if (!array)
-    err = gpg_err_code_from_errno (errno);
-  if (!err)
-    {
-      if (is_ecc)
-        err = sexp_elements_extract_ecc (list, elems, array, extraspec);
-      else
-        err = sexp_elements_extract (list, elems, array, pubkey->name);
-    }
-  
-  gcry_sexp_release (list);
-  
-  if (err)
-    {
-      gcry_free (array);
-
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
-  else
-    {
-      *retarray = array;
-      *retalgo = module;
-    }
-  
-  return err;
-}
-
-
-static gcry_err_code_t
-sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
-            gcry_module_t *retalgo)
-{
-  gcry_err_code_t err = 0;
-  gcry_sexp_t list, l2;
-  char *name;
-  const char *elems;
-  gcry_mpi_t *array;
-  gcry_module_t module;
-  gcry_pk_spec_t *pubkey;
-  
-  /* Check that the first element is valid.  */
-  list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
-  if (!list)
-    return GPG_ERR_INV_OBJ; /* Does not contain a signature value object.  */
-
-  l2 = gcry_sexp_nth (list, 1);
-  if (!l2)
-    {
-      gcry_sexp_release (list);
-      return GPG_ERR_NO_OBJ;   /* No cadr for the sig object.  */
-    }
-  name = _gcry_sexp_nth_string (l2, 0);
-  if (!name)
-    {
-      gcry_sexp_release (list);
-      gcry_sexp_release (l2);
-      return GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
-    }
-  else if (!strcmp (name, "flags")) 
-    {
-      /* Skip flags, since they are not used but here just for the
-        sake of consistent S-expressions.  */
-      gcry_free (name);
-      gcry_sexp_release (l2);
-      l2 = gcry_sexp_nth (list, 2);
-      if (!l2)
-       {
-         gcry_sexp_release (list);
-         return GPG_ERR_INV_OBJ;
-       }
-      name = _gcry_sexp_nth_string (l2, 0);
-    }
-      
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name (name);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-  gcry_free (name);
-  name = NULL;
-
-  if (!module)
-    {
-      gcry_sexp_release (l2);
-      gcry_sexp_release (list);
-      return GPG_ERR_PUBKEY_ALGO;  /* Unknown algorithm. */
-    }
-  else
-    pubkey = (gcry_pk_spec_t *) module->spec;
-
-  elems = pubkey->elements_sig;
-  array = gcry_calloc (strlen (elems) + 1 , sizeof *array );
-  if (!array)
-    err = gpg_err_code_from_errno (errno);
-
-  if (!err)
-    err = sexp_elements_extract (list, elems, array, NULL);
-
-  gcry_sexp_release (l2);
-  gcry_sexp_release (list);
-
-  if (err)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-      
-      gcry_free (array);
-    }
-  else
-    {
-      *retarray = array;
-      *retalgo = module;
-    }
-  
-  return err;
-}
-
-
-/****************
- * Take sexp and return an array of MPI as used for our internal decrypt
- * function.
- * s_data = (enc-val
- *           [(flags [pkcs1])]
- *           (<algo>
- *             (<param_name1> <mpi>)
- *             ...
- *             (<param_namen> <mpi>)
- *           ))
- * RET_MODERN is set to true when at least an empty flags list has been found.
- */
-static gcry_err_code_t
-sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
-             int *ret_modern, int *ret_want_pkcs1, int *flags)
-{
-  gcry_err_code_t err = 0;
-  gcry_sexp_t list = NULL, l2 = NULL;
-  gcry_pk_spec_t *pubkey = NULL;
-  gcry_module_t module = NULL;
-  char *name = NULL;
-  size_t n;
-  int parsed_flags = 0;
-  const char *elems;
-  gcry_mpi_t *array = NULL;
-
-  *ret_want_pkcs1 = 0;
-  *ret_modern = 0;
-
-  /* Check that the first element is valid.  */
-  list = gcry_sexp_find_token (sexp, "enc-val" , 0);
-  if (!list)
-    {
-      err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
-      goto leave;
-    }
-
-  l2 = gcry_sexp_nth (list, 1);
-  if (!l2)
-    {
-      err = GPG_ERR_NO_OBJ; /* No cdr for the data object.  */
-      goto leave;
-    }
-
-  /* Extract identifier of sublist.  */
-  name = _gcry_sexp_nth_string (l2, 0);
-  if (!name)
-    {
-      err = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
-      goto leave;
-    }
-  
-  if (!strcmp (name, "flags"))
-    {
-      /* There is a flags element - process it.  */
-      const char *s;
-      int i;
-      
-      *ret_modern = 1;
-      for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
-        {
-          s = gcry_sexp_nth_data (l2, i, &n);
-          if (! s)
-            ; /* Not a data element - ignore.  */
-          else if (n == 3 && !memcmp (s, "raw", 3))
-            ; /* This is just a dummy as it is the default.  */
-          else if (n == 5 && !memcmp (s, "pkcs1", 5))
-            *ret_want_pkcs1 = 1;
-          else if (n == 11 && ! memcmp (s, "no-blinding", 11))
-            parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
-          else
-            {
-              err = GPG_ERR_INV_FLAG;
-              goto leave;
-            }
-        }
-      
-      /* Get the next which has the actual data. */
-      gcry_sexp_release (l2);
-      l2 = gcry_sexp_nth (list, 2);
-      if (!l2)
-        {
-          err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
-          goto leave;
-        }
-
-      /* Extract sublist identifier.  */
-      gcry_free (name);
-      name = _gcry_sexp_nth_string (l2, 0);
-      if (!name)
-        {
-          err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
-          goto leave;
-        }
-
-      gcry_sexp_release (list);
-      list = l2;
-      l2 = NULL;
-    }
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name (name);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-  
-  if (!module)
-    {
-      err = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
-      goto leave;
-    }
-  pubkey = (gcry_pk_spec_t *) module->spec;
-
-  elems = pubkey->elements_enc;
-  array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
-  if (!array)
-    {
-      err = gpg_err_code_from_errno (errno);
-      goto leave;
-    }
-
-  err = sexp_elements_extract (list, elems, array, NULL);
-
- leave:
-  gcry_sexp_release (list);
-  gcry_sexp_release (l2);
-  gcry_free (name);
-
-  if (err)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-      gcry_free (array);
-    }
-  else
-    {
-      *retarray = array;
-      *retalgo = module;
-      *flags = parsed_flags;
-    }
-
-  return err;
-}
-
-/* Take the hash value and convert into an MPI, suitable for
-   passing to the low level functions.  We currently support the
-   old style way of passing just a MPI and the modern interface which
-   allows to pass flags so that we can choose between raw and pkcs1
-   padding - may be more padding options later. 
-
-   (<mpi>)
-   or
-   (data
-    [(flags [pkcs1])]
-    [(hash <algo> <value>)]
-    [(value <text>)]
-   )
-   
-   Either the VALUE or the HASH element must be present for use
-   with signatures.  VALUE is used for encryption.
-
-   NBITS is the length of the key in bits. 
-
-*/
-static gcry_err_code_t
-sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
-                  int for_encryption, int *flags)
-{
-  gcry_err_code_t rc = 0;
-  gcry_sexp_t ldata, lhash, lvalue;
-  int i;
-  size_t n;
-  const char *s;
-  int is_raw = 0, is_pkcs1 = 0, unknown_flag=0; 
-  int parsed_flags = 0, dummy_flags;
-
-  if (! flags)
-    flags = &dummy_flags;
-  
-  *ret_mpi = NULL;
-  ldata = gcry_sexp_find_token (input, "data", 0);
-  if (!ldata)
-    { /* assume old style */
-      *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
-      return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
-    }
-
-  /* see whether there is a flags object */
-  {
-    gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
-    if (lflags)
-      { /* parse the flags list. */
-        for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
-          {
-            s = gcry_sexp_nth_data (lflags, i, &n);
-            if (!s)
-              ; /* not a data element*/
-            else if ( n == 3 && !memcmp (s, "raw", 3))
-              is_raw = 1;
-            else if ( n == 5 && !memcmp (s, "pkcs1", 5))
-              is_pkcs1 = 1;
-           else if (n == 11 && ! memcmp (s, "no-blinding", 11))
-             parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
-            else
-              unknown_flag = 1;
-          }
-        gcry_sexp_release (lflags);
-      }
-  }
-
-  if (!is_pkcs1 && !is_raw)
-    is_raw = 1; /* default to raw */
-
-  /* Get HASH or MPI */
-  lhash = gcry_sexp_find_token (ldata, "hash", 0);
-  lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
-
-  if (!(!lhash ^ !lvalue))
-    rc = GPG_ERR_INV_OBJ; /* none or both given */
-  else if (unknown_flag)
-    rc = GPG_ERR_INV_FLAG;
-  else if (is_raw && is_pkcs1 && !for_encryption)
-    rc = GPG_ERR_CONFLICT;
-  else if (is_raw && lvalue)
-    {
-      *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, 0);
-      if (!*ret_mpi)
-        rc = GPG_ERR_INV_OBJ;
-    }
-  else if (is_pkcs1 && lvalue && for_encryption)
-    { 
-      /* Create pkcs#1 block type 2 padding. */
-      unsigned char *frame = NULL;
-      size_t nframe = (nbits+7) / 8;
-      const void * value;
-      size_t valuelen;
-      unsigned char *p;
-
-      if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
-        rc = GPG_ERR_INV_OBJ;
-      else if (valuelen + 7 > nframe || !nframe)
-        {
-          /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
-          rc = GPG_ERR_TOO_SHORT; /* the key is too short */
-        }
-      else if ( !(frame = gcry_malloc_secure (nframe)))
-        rc = gpg_err_code_from_errno (errno);
-      else
-        {
-          n = 0;
-          frame[n++] = 0;
-          frame[n++] = 2; /* block type */
-          i = nframe - 3 - valuelen;
-          gcry_assert (i > 0);
-          p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
-          /* Replace zero bytes by new values. */
-          for (;;)
-            {
-              int j, k;
-              unsigned char *pp;
-              
-              /* Count the zero bytes. */
-              for (j=k=0; j < i; j++)
-                {
-                  if (!p[j])
-                    k++;
-                }
-              if (!k)
-                break; /* Okay: no (more) zero bytes. */
-              
-              k += k/128 + 3; /* Better get some more. */
-              pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
-              for (j=0; j < i && k; )
-                {
-                  if (!p[j])
-                    p[j] = pp[--k];
-                  if (p[j])
-                    j++;
-                }
-              gcry_free (pp);
-            }
-          memcpy (frame+n, p, i);
-          n += i;
-          gcry_free (p);
-          
-          frame[n++] = 0;
-          memcpy (frame+n, value, valuelen);
-          n += valuelen;
-          gcry_assert (n == nframe);
-
-         /* FIXME, error checking?  */
-          gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
-        }
-
-      gcry_free(frame);
-    }
-  else if (is_pkcs1 && lhash && !for_encryption)
-    { 
-      /* Create pkcs#1 block type 1 padding. */
-      if (gcry_sexp_length (lhash) != 3)
-        rc = GPG_ERR_INV_OBJ;
-      else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
-        rc = GPG_ERR_INV_OBJ;
-      else
-        {
-          static struct { const char *name; int algo; } hashnames[] = 
-          { { "sha1",   GCRY_MD_SHA1 },
-            { "md5",    GCRY_MD_MD5 },
-            { "sha256", GCRY_MD_SHA256 },
-            { "ripemd160", GCRY_MD_RMD160 },
-            { "rmd160", GCRY_MD_RMD160 },
-            { "sha384", GCRY_MD_SHA384 },
-            { "sha512", GCRY_MD_SHA512 },
-            { "sha224", GCRY_MD_SHA224 },
-            { "md2",    GCRY_MD_MD2 },
-            { "md4",    GCRY_MD_MD4 },
-            { "tiger",  GCRY_MD_TIGER },
-            { "haval",  GCRY_MD_HAVAL },
-            { NULL, 0 }
-          };
-          int algo;
-          byte asn[100];
-          byte *frame = NULL;
-          size_t nframe = (nbits+7) / 8;
-          const void * value;
-          size_t valuelen;
-          size_t asnlen, dlen;
-            
-          for (i=0; hashnames[i].name; i++)
-            {
-              if ( strlen (hashnames[i].name) == n
-                   && !memcmp (hashnames[i].name, s, n))
-                break;
-            }
-          if (hashnames[i].name)
-            algo = hashnames[i].algo;
-          else
-            {
-              /* In case of not listed or dynamically allocated hash
-                 algorithm we fall back to this somewhat slower
-                 method.  Further, it also allows to use OIDs as
-                 algorithm names. */
-              char *tmpname;
-
-              tmpname = gcry_malloc (n+1);
-              if (!tmpname)
-                algo = 0;  /* Out of core - silently give up.  */
-              else
-                {
-                  memcpy (tmpname, s, n);
-                  tmpname[n] = 0;
-                  algo = gcry_md_map_name (tmpname);
-                  gcry_free (tmpname);
-                }
-            }
-
-          asnlen = DIM(asn);
-          dlen = gcry_md_get_algo_dlen (algo);
-
-          if (!algo)
-            rc = GPG_ERR_DIGEST_ALGO;
-          else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
-                    || !valuelen )
-            rc = GPG_ERR_INV_OBJ;
-          else if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
-            {
-              /* We don't have yet all of the above algorithms.  */
-              rc = GPG_ERR_NOT_IMPLEMENTED;
-            }
-          else if ( valuelen != dlen )
-            {
-              /* Hash value does not match the length of digest for
-                 the given algorithm. */
-              rc = GPG_ERR_CONFLICT;
-            }
-          else if( !dlen || dlen + asnlen + 4 > nframe)
-            {
-              /* Can't encode an DLEN byte digest MD into a NFRAME
-                 byte frame. */
-              rc = GPG_ERR_TOO_SHORT;
-            }
-          else if ( !(frame = gcry_malloc (nframe)) )
-            rc = gpg_err_code_from_errno (errno);
-          else
-            { /* Assemble the pkcs#1 block type 1. */
-              n = 0;
-              frame[n++] = 0;
-              frame[n++] = 1; /* block type */
-              i = nframe - valuelen - asnlen - 3 ;
-              gcry_assert (i > 1);
-              memset (frame+n, 0xff, i );
-              n += i;
-              frame[n++] = 0;
-              memcpy (frame+n, asn, asnlen);
-              n += asnlen;
-              memcpy (frame+n, value, valuelen );
-              n += valuelen;
-              gcry_assert (n == nframe);
-      
-              /* Convert it into an MPI.  FIXME: error checking?  */
-              gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
-            }
-          
-          gcry_free (frame);
-        }
-    }
-  else
-    rc = GPG_ERR_CONFLICT;
-   
-  gcry_sexp_release (ldata);
-  gcry_sexp_release (lhash);
-  gcry_sexp_release (lvalue);
-
-  if (!rc)
-    *flags = parsed_flags;
-
-  return rc;
-}
-
-
-/*
-   Do a PK encrypt operation
-  
-   Caller has to provide a public key as the SEXP pkey and data as a
-   SEXP with just one MPI in it. Alternativly S_DATA might be a
-   complex S-Expression, similar to the one used for signature
-   verification.  This provides a flag which allows to handle PKCS#1
-   block type 2 padding.  The function returns a a sexp which may be
-   passed to to pk_decrypt.
-  
-   Returns: 0 or an errorcode.
-  
-   s_data = See comment for sexp_data_to_mpi
-   s_pkey = <key-as-defined-in-sexp_to_key>
-   r_ciph = (enc-val
-               (<algo>
-                 (<param_name1> <mpi>)
-                 ...
-                 (<param_namen> <mpi>)
-               ))
-
-*/
-gcry_error_t
-gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
-{
-  gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL;
-  const char *algo_name, *algo_elems;
-  int flags;
-  gcry_err_code_t rc;
-  gcry_pk_spec_t *pubkey = NULL;
-  gcry_module_t module = NULL;
-
-  *r_ciph = NULL;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  /* Get the key. */
-  rc = sexp_to_key (s_pkey, 0, &pkey, &module);
-  if (rc)
-    goto leave;
-
-  gcry_assert (module);
-  pubkey = (gcry_pk_spec_t *) module->spec;
-
-  /* If aliases for the algorithm name exists, take the first one
-     instead of the regular name to adhere to SPKI conventions.  We
-     assume that the first alias name is the lowercase version of the
-     regular one.  This change is required for compatibility with
-     1.1.12 generated S-expressions. */
-  algo_name = pubkey->aliases? *pubkey->aliases : NULL;
-  if (!algo_name || !*algo_name)
-    algo_name = pubkey->name;
-  
-  algo_elems = pubkey->elements_enc;
-  
-  /* Get the stuff we want to encrypt. */
-  rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1,
-                         &flags);
-  if (rc)
-    goto leave;
-
-  /* Now we can encrypt DATA to CIPH. */
-  ciph = gcry_calloc (strlen (algo_elems) + 1, sizeof (*ciph));
-  if (!ciph)
-    {
-      rc = gpg_err_code_from_errno (errno);
-      goto leave;
-    }
-  rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, flags);
-  mpi_free (data);
-  data = NULL;
-  if (rc)
-    goto leave;
-
-  /* We did it.  Now build the return list */
-  {
-    char *string, *p;
-    int i;
-    size_t nelem = strlen (algo_elems);
-    size_t needed = 19 + strlen (algo_name) + (nelem * 5);
-    void **arg_list;
-    
-    /* Build the string.  */
-    string = p = gcry_malloc (needed);
-    if (!string)
-      {
-        rc = gpg_err_code_from_errno (errno);
-        goto leave;
-      }
-    p = stpcpy ( p, "(enc-val(" );
-    p = stpcpy ( p, algo_name );
-    for (i=0; algo_elems[i]; i++ )
-      {
-        *p++ = '(';
-        *p++ = algo_elems[i];
-        p = stpcpy ( p, "%m)" );
-      }
-    strcpy ( p, "))" );
-    
-    /* And now the ugly part: We don't have a function to pass an
-     * array to a format string, so we have to do it this way :-(.  */
-    /* FIXME: There is now such a format specifier, so we can
-       change the code to be more clear. */
-    arg_list = malloc (nelem * sizeof *arg_list);
-    if (!arg_list)
-      {
-        rc = gpg_err_code_from_errno (errno);
-        goto leave;
-      }
-
-    for (i = 0; i < nelem; i++)
-      arg_list[i] = ciph + i;
-    
-    rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
-    free (arg_list);
-    if (rc)
-      BUG ();
-    gcry_free (string);
-  }
-
- leave:
-  if (pkey)
-    {
-      release_mpi_array (pkey);
-      gcry_free (pkey);
-    }
-
-  if (ciph)
-    {
-      release_mpi_array (ciph);
-      gcry_free (ciph);
-    }
-
-  if (module)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
-
-  return gcry_error (rc);
-}
-
-/* 
-   Do a PK decrypt operation
-  
-   Caller has to provide a secret key as the SEXP skey and data in a
-   format as created by gcry_pk_encrypt.  For historic reasons the
-   function returns simply an MPI as an S-expression part; this is
-   deprecated and the new method should be used which returns a real
-   S-expressionl this is selected by adding at least an empty flags
-   list to S_DATA.
-   
-   Returns: 0 or an errorcode.
-  
-   s_data = (enc-val
-              [(flags)]
-              (<algo>
-                (<param_name1> <mpi>)
-                ...
-                (<param_namen> <mpi>)
-              ))
-   s_skey = <key-as-defined-in-sexp_to_key>
-   r_plain= Either an incomplete S-expression without the parentheses
-            or if the flags list is used (even if empty) a real S-expression:
-            (value PLAIN). 
- */
-gcry_error_t
-gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
-{
-  gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL;
-  int modern, want_pkcs1, flags;
-  gcry_err_code_t rc;
-  gcry_module_t module_enc = NULL, module_key = NULL;
-  gcry_pk_spec_t *pubkey = NULL;
-
-  *r_plain = NULL;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  rc = sexp_to_key (s_skey, 1, &skey, &module_key);
-  if (rc)
-    goto leave;
-
-  rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &want_pkcs1, &flags);
-  if (rc)
-    goto leave;
-  
-  if (module_key->mod_id != module_enc->mod_id)
-    {
-      rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
-      goto leave;
-    }
-
-  pubkey = (gcry_pk_spec_t *) module_key->spec;
-
-  rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
-  if (rc)
-    goto leave;
-
-  if (gcry_sexp_build (r_plain, NULL, modern? "(value %m)" : "%m", plain))
-    BUG ();
-  
- leave:
-  if (skey)
-    {
-      release_mpi_array (skey);
-      gcry_free (skey);
-    }
-
-  if (plain)
-    mpi_free (plain);
-
-  if (data)
-    {
-      release_mpi_array (data);
-      gcry_free (data);
-    }
-
-  if (module_key || module_enc)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      if (module_key)
-       _gcry_module_release (module_key);
-      if (module_enc)
-       _gcry_module_release (module_enc);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
-
-  return gcry_error (rc);
-}
-
-
-
-/*
-   Create a signature.
-  
-   Caller has to provide a secret key as the SEXP skey and data
-   expressed as a SEXP list hash with only one element which should
-   instantly be available as a MPI. Alternatively the structure given
-   below may be used for S_HASH, it provides the abiliy to pass flags
-   to the operation; the only flag defined by now is "pkcs1" which
-   does PKCS#1 block type 1 style padding.
-  
-   Returns: 0 or an errorcode.
-            In case of 0 the function returns a new SEXP with the
-            signature value; the structure of this signature depends on the
-            other arguments but is always suitable to be passed to
-            gcry_pk_verify
-  
-   s_hash = See comment for sexp_data_to_mpi
-               
-   s_skey = <key-as-defined-in-sexp_to_key>
-   r_sig  = (sig-val
-              (<algo>
-                (<param_name1> <mpi>)
-                ...
-                (<param_namen> <mpi>))
-             [(hash algo)]) 
-
-  Note that (hash algo) in R_SIG is not used.
-*/
-gcry_error_t
-gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
-{
-  gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL;
-  gcry_pk_spec_t *pubkey = NULL;
-  gcry_module_t module = NULL;
-  const char *algo_name, *algo_elems;
-  int i;
-  gcry_err_code_t rc;
-
-  *r_sig = NULL;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  rc = sexp_to_key (s_skey, 1, &skey, &module);
-  if (rc)
-    goto leave;
-
-  gcry_assert (module);
-  pubkey = (gcry_pk_spec_t *) module->spec;
-  algo_name = pubkey->aliases? *pubkey->aliases : NULL;
-  if (!algo_name || !*algo_name)
-    algo_name = pubkey->name;
-  
-  algo_elems = pubkey->elements_sig;
-
-  /* Get the stuff we want to sign.  Note that pk_get_nbits does also
-      work on a private key. */
-  rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey),
-                             &hash, 0, NULL);
-  if (rc)
-    goto leave;
-
-  result = gcry_calloc (strlen (algo_elems) + 1, sizeof (*result));
-  if (!result)
-    {
-      rc = gpg_err_code_from_errno (errno);
-      goto leave;
-    }
-  rc = pubkey_sign (module->mod_id, result, hash, skey);
-  if (rc)
-    goto leave;
-
-  {
-    char *string, *p;
-    size_t nelem, needed = strlen (algo_name) + 20;
-    void **arg_list;
-
-    nelem = strlen (algo_elems);
-    
-    /* Count elements, so that we can allocate enough space. */
-    needed += 10 * nelem;
-
-    /* Build the string. */
-    string = p = gcry_malloc (needed);
-    if (!string)
-      {
-        rc = gpg_err_code_from_errno (errno);
-        goto leave;
-      }
-    p = stpcpy (p, "(sig-val(");
-    p = stpcpy (p, algo_name);
-    for (i = 0; algo_elems[i]; i++)
-      {
-        *p++ = '(';
-        *p++ = algo_elems[i];
-        p = stpcpy (p, "%m)");
-      }
-    strcpy (p, "))");
-
-    arg_list = malloc (nelem * sizeof *arg_list);
-    if (!arg_list)
-      {
-        rc = gpg_err_code_from_errno (errno);
-        goto leave;
-      }
-
-    for (i = 0; i < nelem; i++)
-      arg_list[i] = result + i;
-
-    rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
-    free (arg_list);
-    if (rc)
-      BUG ();
-    gcry_free (string);
-  }
-
- leave:
-  if (skey)
-    {
-      release_mpi_array (skey);
-      gcry_free (skey);
-    }
-
-  if (hash)
-    mpi_free (hash);
-
-  if (result)
-    {
-      release_mpi_array (result);
-      gcry_free (result);
-    }
-
-  return gcry_error (rc);
-}
-
-
-/*
-   Verify a signature.
-
-   Caller has to supply the public key pkey, the signature sig and his
-   hashvalue data.  Public key has to be a standard public key given
-   as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
-   must be an S-Exp like the one in sign too.  */
-gcry_error_t
-gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
-{
-  gcry_module_t module_key = NULL, module_sig = NULL;
-  gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
-  gcry_err_code_t rc;
-
-  REGISTER_DEFAULT_PUBKEYS;
-  rc = sexp_to_key (s_pkey, 0, &pkey, &module_key);
-  if (rc)
-    goto leave;
-
-  rc = sexp_to_sig (s_sig, &sig, &module_sig);
-  if (rc)
-    goto leave;
-
-  /* Fixme: Check that the algorithm of S_SIG is compatible to the one
-     of S_PKEY.  */
-
-  if (module_key->mod_id != module_sig->mod_id)
-    {
-      rc = GPG_ERR_CONFLICT;
-      goto leave;
-    }
-
-  rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0);
-  if (rc)
-    goto leave;
-
-  rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, NULL, NULL);
-
- leave:
-  if (pkey)
-    {
-      release_mpi_array (pkey);
-      gcry_free (pkey);
-    }
-  if (sig)
-    {
-      release_mpi_array (sig);
-      gcry_free (sig);
-    }
-  if (hash)
-    mpi_free (hash);
-
-  if (module_key || module_sig)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      if (module_key)
-       _gcry_module_release (module_key);
-      if (module_sig)
-       _gcry_module_release (module_sig);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
-
-  return gcry_error (rc);
-}
-
-
-/*
-   Test a key.
-
-   This may be used either for a public or a secret key to see whether
-   the internal structure is okay.
-  
-   Returns: 0 or an errorcode.
-  
-   s_key = <key-as-defined-in-sexp_to_key> */
-gcry_error_t
-gcry_pk_testkey (gcry_sexp_t s_key)
-{
-  gcry_module_t module = NULL;
-  gcry_mpi_t *key = NULL;
-  gcry_err_code_t rc;
-  
-  REGISTER_DEFAULT_PUBKEYS;
-
-  /* Note we currently support only secret key checking. */
-  rc = sexp_to_key (s_key, 1, &key, &module);
-  if (! rc)
-    {
-      rc = pubkey_check_secret_key (module->mod_id, key);
-      release_mpi_array (key);
-      gcry_free (key);
-    }
-  return gcry_error (rc);
-}
-
-
-/*
-  Create a public key pair and return it in r_key.
-  How the key is created depends on s_parms:
-  (genkey
-   (algo
-     (parameter_name_1 ....)
-      ....
-     (parameter_name_n ....)
-  ))
-  The key is returned in a format depending on the
-  algorithm. Both, private and secret keys are returned
-  and optionally some additional informatin.
-  For elgamal we return this structure:
-  (key-data
-   (public-key
-     (elg
-       (p <mpi>)
-       (g <mpi>)
-       (y <mpi>)
-     )
-   )
-   (private-key
-     (elg
-       (p <mpi>)
-       (g <mpi>)
-       (y <mpi>)
-       (x <mpi>)
-     )
-   )
-   (misc-key-info
-      (pm1-factors n1 n2 ... nn)
-   ))
- */
-gcry_error_t
-gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
-{
-  gcry_pk_spec_t *pubkey = NULL;
-  gcry_module_t module = NULL;
-  gcry_sexp_t list = NULL;
-  gcry_sexp_t l2 = NULL;
-  gcry_sexp_t l3 = NULL;
-  char *name = NULL;
-  size_t n;
-  gcry_err_code_t rc = GPG_ERR_NO_ERROR;
-  int i;
-  const char *algo_name = NULL;
-  int algo;
-  const char *sec_elems = NULL, *pub_elems = NULL;
-  gcry_mpi_t skey[12];
-  gcry_mpi_t *factors = NULL;
-  gcry_sexp_t extrainfo = NULL;
-  unsigned int nbits = 0;
-  unsigned long use_e = 0;
-
-  skey[0] = NULL;
-  *r_key = NULL;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  list = gcry_sexp_find_token (s_parms, "genkey", 0);
-  if (!list)
-    {
-      rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
-      goto leave;
-    }
-
-  l2 = gcry_sexp_cadr (list);
-  gcry_sexp_release (list);
-  list = l2;
-  l2 = NULL;
-  if (! list)
-    {
-      rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
-      goto leave;
-    }
-
-  name = _gcry_sexp_nth_string (list, 0);
-  if (!name)
-    {
-      rc = GPG_ERR_INV_OBJ; /* Algo string missing.  */
-      goto leave;
-    }
-  
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name (name);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-  gcry_free (name);
-  name = NULL;
-  if (!module)
-    {
-      rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
-      goto leave;
-    }
-  
-  pubkey = (gcry_pk_spec_t *) module->spec;
-  algo = module->mod_id;
-  algo_name = pubkey->aliases? *pubkey->aliases : NULL;
-  if (!algo_name || !*algo_name)
-    algo_name = pubkey->name;
-  pub_elems = pubkey->elements_pkey;
-  sec_elems = pubkey->elements_skey;
-  if (strlen (sec_elems) >= DIM(skey))
-    BUG ();
-
-  /* Handle the optional rsa-use-e element.  Actually this belong into
-     the algorithm module but we have this parameter in the public
-     module API, so we need to parse it right here.  */
-  l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
-  if (l2)
-    {
-      char buf[50];
-      const char *s;
-
-      s = gcry_sexp_nth_data (l2, 1, &n);
-      if ( !s || n >= DIM (buf) - 1 )
-        {
-          rc = GPG_ERR_INV_OBJ; /* No value or value too large.  */
-          goto leave;
-        }
-      memcpy (buf, s, n);
-      buf[n] = 0;
-      use_e = strtoul (buf, NULL, 0);
-      gcry_sexp_release (l2);
-      l2 = NULL;
-    }
-  else
-    use_e = 65537; /* Not given, use the value generated by old versions. */
-
-
-  /* Get the "nbits" parameter.  */
-  l2 = gcry_sexp_find_token (list, "nbits", 0);
-  if (l2)
-    {
-      char buf[50];
-      const char *s;
-
-      s = gcry_sexp_nth_data (l2, 1, &n);
-      if (!s || n >= DIM (buf) - 1 )
-        {
-          rc = GPG_ERR_INV_OBJ; /* NBITS given without a cdr.  */
-          goto leave;
-        }
-      memcpy (buf, s, n);
-      buf[n] = 0;
-      nbits = (unsigned int)strtoul (buf, NULL, 0);
-      gcry_sexp_release (l2); l2 = NULL;
-    }
-  else 
-    nbits = 0;
-
-  /* Pass control to the algorithm module. */
-  rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey, 
-                        &factors, &extrainfo);
-  gcry_sexp_release (list); list = NULL;
-  if (rc)
-    goto leave;
-
-  /* Key generation succeeded: Build an S-expression.  */
-  {
-    char *string, *p;
-    size_t nelem=0, nelem_cp = 0, needed=0;
-    gcry_mpi_t mpis[30];
-    
-    /* Estimate size of format string.  */
-    nelem = strlen (pub_elems) + strlen (sec_elems);
-    if (factors)
-      {
-        for (i = 0; factors[i]; i++)
-          nelem++;
-      }
-    nelem_cp = nelem;
-
-    needed += nelem * 10;
-    /* (+5 is for EXTRAINFO ("%S")).  */
-    needed += 2 * strlen (algo_name) + 300 + 5;
-    if (nelem > DIM (mpis))
-      BUG ();
-
-    /* Build the string. */
-    nelem = 0;
-    string = p = gcry_malloc (needed);
-    if (!string)
-      {
-        rc = gpg_err_code_from_errno (errno);
-        goto leave;
-      }
-    p = stpcpy (p, "(key-data");
-    p = stpcpy (p, "(public-key(");
-    p = stpcpy (p, algo_name);
-    for(i = 0; pub_elems[i]; i++)
-      {
-        *p++ = '(';
-        *p++ = pub_elems[i];
-        p = stpcpy (p, "%m)");
-        mpis[nelem++] = skey[i];
-      }
-    p = stpcpy (p, "))");
-    p = stpcpy (p, "(private-key(");
-    p = stpcpy (p, algo_name);
-    for (i = 0; sec_elems[i]; i++)
-      {
-        *p++ = '(';
-        *p++ = sec_elems[i];
-        p = stpcpy (p, "%m)");
-        mpis[nelem++] = skey[i];
-      }
-    p = stpcpy (p, "))");
-
-    /* Hack to make release_mpi_array() work.  */
-    skey[i] = NULL;
-
-    if (extrainfo)
-      {
-        /* If we have extrainfo we should not have any factors.  */
-        p = stpcpy (p, "%S");
-      }
-    else if (factors && factors[0])
-      {
-        p = stpcpy (p, "(misc-key-info(pm1-factors");
-        for(i = 0; factors[i]; i++)
-          {
-            p = stpcpy (p, "%m");
-            mpis[nelem++] = factors[i];
-          }
-        p = stpcpy (p, "))");
-      }
-    strcpy (p, ")");
-    gcry_assert (p - string < needed);
-
-    while (nelem < DIM (mpis))
-      mpis[nelem++] = NULL;
-
-    {
-      int elem_n = strlen (pub_elems) + strlen (sec_elems);
-      void **arg_list;
-
-      /* Allocate one extra for EXTRAINFO ("%S").  */
-      arg_list = gcry_calloc (nelem_cp+1, sizeof *arg_list);
-      if (!arg_list)
-        {
-          rc = gpg_err_code_from_errno (errno);
-          goto leave;
-        }
-      for (i = 0; i < elem_n; i++)
-        arg_list[i] = mpis + i;
-      if (extrainfo)
-        arg_list[i] = &extrainfo;
-      else if (factors && factors[0])
-        {
-          for (; i < nelem_cp; i++)
-            arg_list[i] = factors + i - elem_n;
-        }
-      
-      rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
-      gcry_free (arg_list);
-      if (rc)
-       BUG ();
-      gcry_assert (DIM (mpis) == 30); /* Reminder to make sure that
-                                         the array gets increased if
-                                         new parameters are added. */
-    }
-    gcry_free (string);
-  }
-
- leave:
-  gcry_free (name);
-  gcry_sexp_release (extrainfo);
-  release_mpi_array (skey);
-  /* Don't free SKEY itself, it is an stack allocated array. */
-
-  if (factors)
-    {
-      release_mpi_array ( factors );
-      gcry_free (factors);
-    }
-  
-  gcry_sexp_release (l3);
-  gcry_sexp_release (l2);
-  gcry_sexp_release (list);
-
-  if (module)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
-
-  return gcry_error (rc);
-}
-
-
-/* 
-   Get the number of nbits from the public key.
-
-   Hmmm: Should we have really this function or is it better to have a
-   more general function to retrieve different properties of the key?  */
-unsigned int
-gcry_pk_get_nbits (gcry_sexp_t key)
-{
-  gcry_module_t module = NULL;
-  gcry_pk_spec_t *pubkey;
-  gcry_mpi_t *keyarr = NULL;
-  unsigned int nbits = 0;
-  gcry_err_code_t rc;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  rc = sexp_to_key (key, 0, &keyarr, &module);
-  if (rc == GPG_ERR_INV_OBJ)
-    rc = sexp_to_key (key, 1, &keyarr, &module);
-  if (rc)
-    return 0; /* Error - 0 is a suitable indication for that. */
-
-  pubkey = (gcry_pk_spec_t *) module->spec;
-  nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
-  
-  ath_mutex_lock (&pubkeys_registered_lock);
-  _gcry_module_release (module);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  release_mpi_array (keyarr);
-  gcry_free (keyarr);
-
-  return nbits;
-}
-
-
-/* Return the so called KEYGRIP which is the SHA-1 hash of the public
-   key parameters expressed in a way depended on the algorithm.
-
-   ARRAY must either be 20 bytes long or NULL; in the latter case a
-   newly allocated array of that size is returned, otherwise ARRAY or
-   NULL is returned to indicate an error which is most likely an
-   unknown algorithm.  The function accepts public or secret keys. */
-unsigned char *
-gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
-{
-  gcry_sexp_t list = NULL, l2 = NULL;
-  gcry_pk_spec_t *pubkey = NULL;
-  gcry_module_t module = NULL;
-  pk_extra_spec_t *extraspec;
-  const char *s;
-  char *name = NULL;
-  int idx;
-  const char *elems;
-  gcry_md_hd_t md = NULL;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  /* Check that the first element is valid. */
-  list = gcry_sexp_find_token (key, "public-key", 0);
-  if (! list)
-    list = gcry_sexp_find_token (key, "private-key", 0);
-  if (! list)
-    list = gcry_sexp_find_token (key, "protected-private-key", 0);
-  if (! list)
-    list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
-  if (! list)
-    return NULL; /* No public- or private-key object. */
-
-  l2 = gcry_sexp_cadr (list);
-  gcry_sexp_release (list);
-  list = l2;
-  l2 = NULL;
-
-  name = _gcry_sexp_nth_string (list, 0);
-  if (!name)
-    goto fail; /* Invalid structure of object. */
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name (name);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  if (!module)
-    goto fail; /* Unknown algorithm.  */
-
-  pubkey = (gcry_pk_spec_t *) module->spec;
-  extraspec = module->extraspec;
-
-  elems = pubkey->elements_grip;
-  if (!elems)
-    goto fail; /* No grip parameter.  */
-    
-  if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
-    goto fail;
-
-  if (extraspec && extraspec->comp_keygrip)
-    {
-      /* Module specific method to compute a keygrip.  */
-      if (extraspec->comp_keygrip (md, list))
-        goto fail;
-    }
-  else
-    {
-      /* Generic method to compute a keygrip.  */
-      for (idx = 0, s = elems; *s; s++, idx++)
-        {
-          const char *data;
-          size_t datalen;
-          char buf[30];
-          
-          l2 = gcry_sexp_find_token (list, s, 1);
-          if (! l2)
-            goto fail;
-          data = gcry_sexp_nth_data (l2, 1, &datalen);
-          if (! data)
-            goto fail;
-          
-          snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
-          gcry_md_write (md, buf, strlen (buf));
-          gcry_md_write (md, data, datalen);
-          gcry_sexp_release (l2);
-          gcry_md_write (md, ")", 1);
-        }
-    }
-  
-  if (!array)
-    {
-      array = gcry_malloc (20);
-      if (! array)
-        goto fail;
-    }
-
-  memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
-  gcry_md_close (md);
-  gcry_sexp_release (list);
-  return array;
-
- fail:
-  gcry_free (name);
-  gcry_sexp_release (l2);
-  gcry_md_close (md);
-  gcry_sexp_release (list);
-  return NULL;
-}
-
-
-gcry_error_t
-gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  switch (cmd)
-    {
-    case GCRYCTL_DISABLE_ALGO:
-      /* This one expects a buffer pointing to an integer with the
-         algo number.  */
-      if ((! buffer) || (buflen != sizeof (int)))
-       err = GPG_ERR_INV_ARG;
-      else
-       disable_pubkey_algo (*((int *) buffer));
-      break;
-
-    default:
-      err = GPG_ERR_INV_OP;
-    }
-
-  return gcry_error (err);
-}
-
-
-/* Return information about the given algorithm
-
-   WHAT selects the kind of information returned:
-
-    GCRYCTL_TEST_ALGO:
-        Returns 0 when the specified algorithm is available for use.
-        Buffer must be NULL, nbytes  may have the address of a variable
-        with the required usage of the algorithm. It may be 0 for don't
-        care or a combination of the GCRY_PK_USAGE_xxx flags;
-
-    GCRYCTL_GET_ALGO_USAGE:
-        Return the usage glafs for the give algo.  An invalid alog
-        does return 0.  Disabled algos are ignored here becuase we
-        only want to know whether the algo is at all capable of
-        the usage.
-  
-   Note: Because this function is in most cases used to return an
-   integer value, we can make it easier for the caller to just look at
-   the return value.  The caller will in all cases consult the value
-   and thereby detecting whether a error occured or not (i.e. while
-   checking the block size) */
-gcry_error_t
-gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  switch (what)
-    {
-    case GCRYCTL_TEST_ALGO:
-      {
-       int use = nbytes ? *nbytes : 0;
-       if (buffer)
-         err = GPG_ERR_INV_ARG;
-       else if (check_pubkey_algo (algorithm, use))
-         err = GPG_ERR_PUBKEY_ALGO;
-       break;
-      }
-
-    case GCRYCTL_GET_ALGO_USAGE:
-      {
-       gcry_module_t pubkey;
-       int use = 0;
-
-       REGISTER_DEFAULT_PUBKEYS;
-
-       ath_mutex_lock (&pubkeys_registered_lock);
-       pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-       if (pubkey)
-         {
-           use = ((gcry_pk_spec_t *) pubkey->spec)->use;
-           _gcry_module_release (pubkey);
-         }
-       ath_mutex_unlock (&pubkeys_registered_lock);
-
-       /* FIXME? */
-       *nbytes = use;
-
-       break;
-      }
-
-    case GCRYCTL_GET_ALGO_NPKEY:
-      {
-       /* FIXME?  */
-       int npkey = pubkey_get_npkey (algorithm);
-       *nbytes = npkey;
-       break;
-      }
-    case GCRYCTL_GET_ALGO_NSKEY:
-      {
-       /* FIXME?  */
-       int nskey = pubkey_get_nskey (algorithm);
-       *nbytes = nskey;
-       break;
-      }
-    case GCRYCTL_GET_ALGO_NSIGN:
-      {
-       /* FIXME?  */
-       int nsign = pubkey_get_nsig (algorithm);
-       *nbytes = nsign;
-       break;
-      }
-    case GCRYCTL_GET_ALGO_NENCR:
-      {
-       /* FIXME?  */
-       int nencr = pubkey_get_nenc (algorithm);
-       *nbytes = nencr;
-       break;
-      }
-
-    default:
-      err = GPG_ERR_INV_OP;
-    }
-
-  return gcry_error (err);
-}
-
-
-/* Explicitly initialize this module.  */
-gcry_err_code_t
-_gcry_pk_init (void)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  return err;
-}
-
-
-gcry_err_code_t
-_gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_module_t pubkey;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    *module = pubkey;
-  else
-    err = GPG_ERR_PUBKEY_ALGO;
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return err;
-}
-
-
-void
-_gcry_pk_module_release (gcry_module_t module)
-{
-  ath_mutex_lock (&pubkeys_registered_lock);
-  _gcry_module_release (module);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-}
-
-/* Get a list consisting of the IDs of the loaded pubkey modules.  If
-   LIST is zero, write the number of loaded pubkey modules to
-   LIST_LENGTH and return.  If LIST is non-zero, the first
-   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
-   according size.  In case there are less pubkey modules than
-   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
-gcry_error_t
-gcry_pk_list (int *list, int *list_length)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  err = _gcry_module_list (pubkeys_registered, list, list_length);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return err;
-}
-
-
-/* Run the selftests for pubkey algorithm ALGO with optional reporting
-   function REPORT.  */
-gpg_error_t
-_gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
-{
-  gcry_module_t module = NULL;
-  pk_extra_spec_t *extraspec = NULL;
-  gcry_err_code_t ec = 0;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algo);
-  if (module && !(module->flags & FLAG_MODULE_DISABLED))
-    extraspec = module->extraspec;
-  ath_mutex_unlock (&pubkeys_registered_lock);
-  if (extraspec && extraspec->selftest)
-    ec = extraspec->selftest (algo, extended, report);
-  else
-    {
-      ec = GPG_ERR_PUBKEY_ALGO;
-      if (report)
-        report ("pubkey", algo, "module", 
-                module && !(module->flags & FLAG_MODULE_DISABLED)?
-                "no selftest available" :
-                module? "algorithm disabled" : "algorithm not found");
-    }
-
-  if (module)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
-  return gpg_error (ec);
-}
-
-
-/* This function is only used by ac.c!  */
-gcry_err_code_t
-_gcry_pk_get_elements (int algo, char **enc, char **sig)
-{
-  gcry_module_t pubkey;
-  gcry_pk_spec_t *spec;
-  gcry_err_code_t err;
-  char *enc_cp;
-  char *sig_cp;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  enc_cp = NULL;
-  sig_cp = NULL;
-  spec = NULL;
-
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algo);
-  if (! pubkey)
-    {
-      err = GPG_ERR_INTERNAL;
-      goto out;
-    }
-  spec = pubkey->spec;
-
-  if (enc)
-    {
-      enc_cp = strdup (spec->elements_enc);
-      if (! enc_cp)
-       {
-         err = gpg_err_code_from_errno (errno);
-         goto out;
-       }
-    }
-  
-  if (sig)
-    {
-      sig_cp = strdup (spec->elements_sig);
-      if (! sig_cp)
-       {
-         err = gpg_err_code_from_errno (errno);
-         goto out;
-       }
-    }
-
-  if (enc)
-    *enc = enc_cp;
-  if (sig)
-    *sig = sig_cp;
-  err = 0;
-
- out:
-
-  _gcry_module_release (pubkey);
-  if (err)
-    {
-      free (enc_cp);
-      free (sig_cp);
-    }
-
-  return err;
-}
diff --git a/lib/libgcrypt/cipher/rfc2268.c b/lib/libgcrypt/cipher/rfc2268.c
deleted file mode 100644 (file)
index 7d63fce..0000000
+++ /dev/null
@@ -1,345 +0,0 @@
-/* rfc2268.c  - The cipher described in rfc2268; aka Ron's Cipher 2.
- * Copyright (C) 2003 Nikos Mavroyanopoulos
- * Copyright (C) 2004 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-/* This implementation was written by Nikos Mavroyanopoulos for GNUTLS
- * as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for
- * direct use by Libgcrypt by Werner Koch.  This implementation is
- * only useful for pkcs#12 descryption.
- *
- * The implementation here is based on Peter Gutmann's RRC.2 paper.
- */
-
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "g10lib.h"
-#include "types.h"
-#include "cipher.h"
-
-#define RFC2268_BLOCKSIZE 8
-
-typedef struct 
-{
-  u16 S[64];
-} RFC2268_context;
-
-static const unsigned char rfc2268_sbox[] = { 
-  217, 120, 249, 196,  25, 221, 181, 237, 
-   40, 233, 253, 121,  74, 160, 216, 157,
-  198, 126,  55, 131,  43, 118,  83, 142, 
-   98,  76, 100, 136,  68, 139, 251, 162,
-   23, 154,  89, 245, 135, 179,  79,  19,
-   97,  69, 109, 141,   9, 129, 125,  50,
-  189, 143,  64, 235, 134, 183, 123,  11,
-  240, 149,  33,  34,  92, 107,  78, 130,
-   84, 214, 101, 147, 206,  96, 178,  28,
-  115,  86, 192,  20, 167, 140, 241, 220,
-   18, 117, 202,  31,  59, 190, 228, 209,
-   66,  61, 212,  48, 163,  60, 182,  38,
-  111, 191,  14, 218,  70, 105,   7,  87,
-   39, 242,  29, 155, 188, 148,  67,   3,
-  248,  17, 199, 246, 144, 239,  62, 231,
-    6, 195, 213,  47, 200, 102,  30, 215,
-    8, 232, 234, 222, 128,  82, 238, 247,
-  132, 170, 114, 172,  53,  77, 106,  42,
-  150,  26, 210, 113,  90,  21,  73, 116,
-   75, 159, 208,  94,   4,  24, 164, 236,
-  194, 224,  65, 110,  15,  81, 203, 204,
-   36, 145, 175,  80, 161, 244, 112,  57,
-  153, 124,  58, 133,  35, 184, 180, 122,
-  252,   2,  54,  91,  37,  85, 151,  49,
-   45,  93, 250, 152, 227, 138, 146, 174,
-    5, 223,  41,  16, 103, 108, 186, 201,
-  211,   0, 230, 207, 225, 158, 168,  44,
-   99,  22,   1,  63,  88, 226, 137, 169,
-   13,  56,  52,  27, 171,  51, 255, 176,
-  187,  72,  12,  95, 185, 177, 205,  46,
-  197, 243, 219,  71, 229, 165, 156, 119,
-   10, 166,  32, 104, 254, 127, 193, 173
-};
-
-#define rotl16(x,n)   (((x) << ((u16)(n))) | ((x) >> (16 - (u16)(n))))
-#define rotr16(x,n)   (((x) >> ((u16)(n))) | ((x) << (16 - (u16)(n))))
-
-static const char *selftest (void);
-
-
-static void
-do_encrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
-{
-  RFC2268_context *ctx = context;
-  register int i, j;
-  u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
-
-  word0 = (word0 << 8) | inbuf[1];
-  word0 = (word0 << 8) | inbuf[0];
-  word1 = (word1 << 8) | inbuf[3];
-  word1 = (word1 << 8) | inbuf[2];
-  word2 = (word2 << 8) | inbuf[5];
-  word2 = (word2 << 8) | inbuf[4];
-  word3 = (word3 << 8) | inbuf[7];
-  word3 = (word3 << 8) | inbuf[6];
-
-  for (i = 0; i < 16; i++)
-    {
-      j = i * 4;
-      /* For some reason I cannot combine those steps. */
-      word0 += (word1 & ~word3) + (word2 & word3) + ctx->S[j];
-      word0 = rotl16(word0, 1);
-               
-      word1 += (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
-      word1 = rotl16(word1, 2);
-               
-      word2 += (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
-      word2 = rotl16(word2, 3);
-
-      word3 += (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
-      word3 = rotl16(word3, 5);
-
-      if (i == 4 || i == 10)
-        {
-          word0 += ctx->S[word3 & 63];
-          word1 += ctx->S[word0 & 63];
-          word2 += ctx->S[word1 & 63];
-          word3 += ctx->S[word2 & 63];
-        }
-
-    }
-
-  outbuf[0] = word0 & 255;
-  outbuf[1] = word0 >> 8;
-  outbuf[2] = word1 & 255;
-  outbuf[3] = word1 >> 8;
-  outbuf[4] = word2 & 255;
-  outbuf[5] = word2 >> 8;
-  outbuf[6] = word3 & 255;
-  outbuf[7] = word3 >> 8;
-}
-
-static void
-do_decrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
-{
-  RFC2268_context *ctx = context;
-  register int i, j;
-  u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
-
-  word0 = (word0 << 8) | inbuf[1];
-  word0 = (word0 << 8) | inbuf[0];
-  word1 = (word1 << 8) | inbuf[3];
-  word1 = (word1 << 8) | inbuf[2];
-  word2 = (word2 << 8) | inbuf[5];
-  word2 = (word2 << 8) | inbuf[4];
-  word3 = (word3 << 8) | inbuf[7];
-  word3 = (word3 << 8) | inbuf[6];
-
-  for (i = 15; i >= 0; i--) 
-    {
-      j = i * 4;
-
-      word3 = rotr16(word3, 5);
-      word3 -= (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
-
-      word2 = rotr16(word2, 3);
-      word2 -= (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
-
-      word1 = rotr16(word1, 2);
-      word1 -= (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
-
-      word0 = rotr16(word0, 1);
-      word0 -= (word1 & ~word3) + (word2 & word3) + ctx->S[j];
-
-      if (i == 5 || i == 11) 
-        {
-          word3 = word3 - ctx->S[word2 & 63];
-          word2 = word2 - ctx->S[word1 & 63];
-          word1 = word1 - ctx->S[word0 & 63];
-          word0 = word0 - ctx->S[word3 & 63];
-        }
-
-    }
-
-  outbuf[0] = word0 & 255;
-  outbuf[1] = word0 >> 8;
-  outbuf[2] = word1 & 255;
-  outbuf[3] = word1 >> 8;
-  outbuf[4] = word2 & 255;
-  outbuf[5] = word2 >> 8;
-  outbuf[6] = word3 & 255;
-  outbuf[7] = word3 >> 8;
-}
-
-
-static gpg_err_code_t
-setkey_core (void *context, const unsigned char *key, unsigned int keylen, int with_phase2)
-{
-  static int initialized;
-  static const char *selftest_failed;
-  RFC2268_context *ctx = context;
-  unsigned int i;
-  unsigned char *S, x;
-  int len;
-  int bits = keylen * 8;
-
-  if (!initialized)
-    {
-      initialized = 1;
-      selftest_failed = selftest ();
-      if (selftest_failed)
-        log_error ("RFC2268 selftest failed (%s).\n", selftest_failed);
-    }
-  if (selftest_failed)
-    return GPG_ERR_SELFTEST_FAILED;
-
-  if (keylen < 40 / 8) /* We want at least 40 bits. */
-    return GPG_ERR_INV_KEYLEN;
-
-  S = (unsigned char *) ctx->S;
-  
-  for (i = 0; i < keylen; i++)
-    S[i] = key[i];
-
-  for (i = keylen; i < 128; i++)
-    S[i] = rfc2268_sbox[(S[i - keylen] + S[i - 1]) & 255];
-
-  S[0] = rfc2268_sbox[S[0]];
-
-  /* Phase 2 - reduce effective key size to "bits". This was not
-   * discussed in Gutmann's paper. I've copied that from the public
-   * domain code posted in sci.crypt. */
-  if (with_phase2)
-    {
-      len = (bits + 7) >> 3;
-      i = 128 - len;
-      x = rfc2268_sbox[S[i] & (255 >> (7 & -bits))];
-      S[i] = x;
-      
-      while (i--) 
-        {
-          x = rfc2268_sbox[x ^ S[i + len]];
-          S[i] = x;
-        }
-    }
-
-  /* Make the expanded key, endian independent. */
-  for (i = 0; i < 64; i++) 
-    ctx->S[i] = ( (u16) S[i * 2] | (((u16) S[i * 2 + 1]) << 8));
-
-  return 0;
-}
-
-static gpg_err_code_t
-do_setkey (void *context, const unsigned char *key, unsigned int keylen)
-{
-  return setkey_core (context, key, keylen, 1);
-}
-
-static const char *
-selftest (void)
-{
-  RFC2268_context ctx;
-  unsigned char scratch[16];
-
-  /* Test vectors from Peter Gutmann's paper. */
-  static unsigned char key_1[] =
-    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-    };
-  static unsigned char plaintext_1[] =
-    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-  static const unsigned char ciphertext_1[] =
-    { 0x1C, 0x19, 0x8A, 0x83, 0x8D, 0xF0, 0x28, 0xB7 };
-
-  static unsigned char key_2[] =
-    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-      0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
-    };
-  static unsigned char plaintext_2[] =
-    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-  static unsigned char ciphertext_2[] =
-    { 0x50, 0xDC, 0x01, 0x62, 0xBD, 0x75, 0x7F, 0x31 };
-
-  /* This one was checked against libmcrypt's RFC2268. */
-  static unsigned char key_3[] =
-    { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-    };
-  static unsigned char plaintext_3[] =
-    { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-  static unsigned char ciphertext_3[] =
-    { 0x8f, 0xd1, 0x03, 0x89, 0x33, 0x6b, 0xf9, 0x5e };
-
-
-  /* First test. */
-  setkey_core (&ctx, key_1, sizeof(key_1), 0);
-  do_encrypt (&ctx, scratch, plaintext_1);
-
-  if (memcmp (scratch, ciphertext_1, sizeof(ciphertext_1)))
-    return "RFC2268 encryption test 1 failed.";
-
-  setkey_core (&ctx, key_1, sizeof(key_1), 0);
-  do_decrypt (&ctx, scratch, scratch); 
-  if (memcmp (scratch, plaintext_1, sizeof(plaintext_1)))
-    return "RFC2268 decryption test 1 failed.";
-
-  /* Second test. */
-  setkey_core (&ctx, key_2, sizeof(key_2), 0);
-  do_encrypt (&ctx, scratch, plaintext_2);
-  if (memcmp (scratch, ciphertext_2, sizeof(ciphertext_2)))
-    return "RFC2268 encryption test 2 failed.";
-
-  setkey_core (&ctx, key_2, sizeof(key_2), 0);
-  do_decrypt (&ctx, scratch, scratch); 
-  if (memcmp (scratch, plaintext_2, sizeof(plaintext_2)))
-    return "RFC2268 decryption test 2 failed.";
-
-  /* Third test. */
-  setkey_core(&ctx, key_3, sizeof(key_3), 0);
-  do_encrypt(&ctx, scratch, plaintext_3);
-
-  if (memcmp(scratch, ciphertext_3, sizeof(ciphertext_3)))
-    return "RFC2268 encryption test 3 failed.";
-
-  setkey_core (&ctx, key_3, sizeof(key_3), 0);
-  do_decrypt (&ctx, scratch, scratch); 
-  if (memcmp(scratch, plaintext_3, sizeof(plaintext_3)))
-    return "RFC2268 decryption test 3 failed.";
-
-  return NULL;
-}
-
-
-
-static gcry_cipher_oid_spec_t oids_rfc2268_40[] =
-  {
-    /*{ "1.2.840.113549.3.2", GCRY_CIPHER_MODE_CBC },*/
-    /* pbeWithSHAAnd40BitRC2_CBC */
-    { "1.2.840.113549.1.12.1.6", GCRY_CIPHER_MODE_CBC },
-    { NULL }
-  };
-
-gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40 = {
-  "RFC2268_40", NULL, oids_rfc2268_40,
-  RFC2268_BLOCKSIZE, 40, sizeof(RFC2268_context),
-  do_setkey, do_encrypt, do_decrypt
-};
-
diff --git a/lib/libgcrypt/cipher/rijndael-tables.h b/lib/libgcrypt/cipher/rijndael-tables.h
deleted file mode 100644 (file)
index c9b6d77..0000000
+++ /dev/null
@@ -1,1687 +0,0 @@
-/* rijndael-tables.h - Rijndael (AES) for GnuPG, 
- * Copyright (C) 2000, 2001, 2002, 2003, 2007,
- *               2008 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/* To keep the actual implementation at a readable size we use this
-   include file to define the tables.  */
-
-static const unsigned char S[256] = 
-  {
-     99, 124, 119, 123, 242, 107, 111, 197,
-     48,   1, 103,  43, 254, 215, 171, 118, 
-    202, 130, 201, 125, 250,  89,  71, 240,
-    173, 212, 162, 175, 156, 164, 114, 192, 
-    183, 253, 147,  38,  54,  63, 247, 204,
-     52, 165, 229, 241, 113, 216,  49,  21, 
-      4, 199,  35, 195,  24, 150,   5, 154,
-      7,  18, 128, 226, 235,  39, 178, 117, 
-      9, 131,  44,  26,  27, 110,  90, 160, 
-     82,  59, 214, 179,  41, 227,  47, 132, 
-     83, 209,   0, 237,  32, 252, 177,  91,
-    106, 203, 190,  57,  74,  76,  88, 207, 
-    208, 239, 170, 251,  67,  77,  51, 133,
-     69, 249,   2, 127,  80,  60, 159, 168, 
-     81, 163,  64, 143, 146, 157,  56, 245,
-    188, 182, 218,  33,  16, 255, 243, 210, 
-    205,  12,  19, 236,  95, 151,  68,  23,
-    196, 167, 126,  61, 100,  93,  25, 115, 
-     96, 129,  79, 220,  34,  42, 144, 136,
-     70, 238, 184,  20, 222,  94,  11, 219, 
-    224,  50,  58,  10,  73,   6,  36,  92,
-    194, 211, 172,  98, 145, 149, 228, 121, 
-    231, 200,  55, 109, 141, 213,  78, 169, 
-    108,  86, 244, 234, 101, 122, 174,   8, 
-    186, 120,  37,  46,  28, 166, 180, 198, 
-    232, 221, 116,  31,  75, 189, 139, 138, 
-    112,  62, 181, 102,  72,   3, 246,  14,
-     97,  53,  87, 185, 134, 193,  29, 158, 
-    225, 248, 152,  17, 105, 217, 142, 148,
-    155,  30, 135, 233, 206,  85,  40, 223, 
-    140, 161, 137,  13, 191, 230,  66, 104, 
-     65, 153,  45,  15, 176,  84, 187,  22
-  };
-
-
-static const unsigned char T1[256][4] = 
-  {
-    { 0xc6,0x63,0x63,0xa5 }, { 0xf8,0x7c,0x7c,0x84 },
-    { 0xee,0x77,0x77,0x99 }, { 0xf6,0x7b,0x7b,0x8d }, 
-    { 0xff,0xf2,0xf2,0x0d }, { 0xd6,0x6b,0x6b,0xbd },
-    { 0xde,0x6f,0x6f,0xb1 }, { 0x91,0xc5,0xc5,0x54 }, 
-    { 0x60,0x30,0x30,0x50 }, { 0x02,0x01,0x01,0x03 },
-    { 0xce,0x67,0x67,0xa9 }, { 0x56,0x2b,0x2b,0x7d }, 
-    { 0xe7,0xfe,0xfe,0x19 }, { 0xb5,0xd7,0xd7,0x62 },
-    { 0x4d,0xab,0xab,0xe6 }, { 0xec,0x76,0x76,0x9a }, 
-    { 0x8f,0xca,0xca,0x45 }, { 0x1f,0x82,0x82,0x9d },
-    { 0x89,0xc9,0xc9,0x40 }, { 0xfa,0x7d,0x7d,0x87 }, 
-    { 0xef,0xfa,0xfa,0x15 }, { 0xb2,0x59,0x59,0xeb }, 
-    { 0x8e,0x47,0x47,0xc9 }, { 0xfb,0xf0,0xf0,0x0b }, 
-    { 0x41,0xad,0xad,0xec }, { 0xb3,0xd4,0xd4,0x67 },
-    { 0x5f,0xa2,0xa2,0xfd }, { 0x45,0xaf,0xaf,0xea }, 
-    { 0x23,0x9c,0x9c,0xbf }, { 0x53,0xa4,0xa4,0xf7 },
-    { 0xe4,0x72,0x72,0x96 }, { 0x9b,0xc0,0xc0,0x5b }, 
-    { 0x75,0xb7,0xb7,0xc2 }, { 0xe1,0xfd,0xfd,0x1c },
-    { 0x3d,0x93,0x93,0xae }, { 0x4c,0x26,0x26,0x6a }, 
-    { 0x6c,0x36,0x36,0x5a }, { 0x7e,0x3f,0x3f,0x41 },
-    { 0xf5,0xf7,0xf7,0x02 }, { 0x83,0xcc,0xcc,0x4f }, 
-    { 0x68,0x34,0x34,0x5c }, { 0x51,0xa5,0xa5,0xf4 }, 
-    { 0xd1,0xe5,0xe5,0x34 }, { 0xf9,0xf1,0xf1,0x08 }, 
-    { 0xe2,0x71,0x71,0x93 }, { 0xab,0xd8,0xd8,0x73 },
-    { 0x62,0x31,0x31,0x53 }, { 0x2a,0x15,0x15,0x3f }, 
-    { 0x08,0x04,0x04,0x0c }, { 0x95,0xc7,0xc7,0x52 },
-    { 0x46,0x23,0x23,0x65 }, { 0x9d,0xc3,0xc3,0x5e }, 
-    { 0x30,0x18,0x18,0x28 }, { 0x37,0x96,0x96,0xa1 },
-    { 0x0a,0x05,0x05,0x0f }, { 0x2f,0x9a,0x9a,0xb5 }, 
-    { 0x0e,0x07,0x07,0x09 }, { 0x24,0x12,0x12,0x36 },
-    { 0x1b,0x80,0x80,0x9b }, { 0xdf,0xe2,0xe2,0x3d }, 
-    { 0xcd,0xeb,0xeb,0x26 }, { 0x4e,0x27,0x27,0x69 },
-    { 0x7f,0xb2,0xb2,0xcd }, { 0xea,0x75,0x75,0x9f }, 
-    { 0x12,0x09,0x09,0x1b }, { 0x1d,0x83,0x83,0x9e },
-    { 0x58,0x2c,0x2c,0x74 }, { 0x34,0x1a,0x1a,0x2e }, 
-    { 0x36,0x1b,0x1b,0x2d }, { 0xdc,0x6e,0x6e,0xb2 }, 
-    { 0xb4,0x5a,0x5a,0xee }, { 0x5b,0xa0,0xa0,0xfb }, 
-    { 0xa4,0x52,0x52,0xf6 }, { 0x76,0x3b,0x3b,0x4d },
-    { 0xb7,0xd6,0xd6,0x61 }, { 0x7d,0xb3,0xb3,0xce }, 
-    { 0x52,0x29,0x29,0x7b }, { 0xdd,0xe3,0xe3,0x3e }, 
-    { 0x5e,0x2f,0x2f,0x71 }, { 0x13,0x84,0x84,0x97 }, 
-    { 0xa6,0x53,0x53,0xf5 }, { 0xb9,0xd1,0xd1,0x68 }, 
-    { 0x00,0x00,0x00,0x00 }, { 0xc1,0xed,0xed,0x2c }, 
-    { 0x40,0x20,0x20,0x60 }, { 0xe3,0xfc,0xfc,0x1f },
-    { 0x79,0xb1,0xb1,0xc8 }, { 0xb6,0x5b,0x5b,0xed }, 
-    { 0xd4,0x6a,0x6a,0xbe }, { 0x8d,0xcb,0xcb,0x46 },
-    { 0x67,0xbe,0xbe,0xd9 }, { 0x72,0x39,0x39,0x4b }, 
-    { 0x94,0x4a,0x4a,0xde }, { 0x98,0x4c,0x4c,0xd4 },
-    { 0xb0,0x58,0x58,0xe8 }, { 0x85,0xcf,0xcf,0x4a }, 
-    { 0xbb,0xd0,0xd0,0x6b }, { 0xc5,0xef,0xef,0x2a },
-    { 0x4f,0xaa,0xaa,0xe5 }, { 0xed,0xfb,0xfb,0x16 }, 
-    { 0x86,0x43,0x43,0xc5 }, { 0x9a,0x4d,0x4d,0xd7 },
-    { 0x66,0x33,0x33,0x55 }, { 0x11,0x85,0x85,0x94 }, 
-    { 0x8a,0x45,0x45,0xcf }, { 0xe9,0xf9,0xf9,0x10 },
-    { 0x04,0x02,0x02,0x06 }, { 0xfe,0x7f,0x7f,0x81 }, 
-    { 0xa0,0x50,0x50,0xf0 }, { 0x78,0x3c,0x3c,0x44 },
-    { 0x25,0x9f,0x9f,0xba }, { 0x4b,0xa8,0xa8,0xe3 }, 
-    { 0xa2,0x51,0x51,0xf3 }, { 0x5d,0xa3,0xa3,0xfe },
-    { 0x80,0x40,0x40,0xc0 }, { 0x05,0x8f,0x8f,0x8a }, 
-    { 0x3f,0x92,0x92,0xad }, { 0x21,0x9d,0x9d,0xbc },
-    { 0x70,0x38,0x38,0x48 }, { 0xf1,0xf5,0xf5,0x04 }, 
-    { 0x63,0xbc,0xbc,0xdf }, { 0x77,0xb6,0xb6,0xc1 },
-    { 0xaf,0xda,0xda,0x75 }, { 0x42,0x21,0x21,0x63 }, 
-    { 0x20,0x10,0x10,0x30 }, { 0xe5,0xff,0xff,0x1a },
-    { 0xfd,0xf3,0xf3,0x0e }, { 0xbf,0xd2,0xd2,0x6d }, 
-    { 0x81,0xcd,0xcd,0x4c }, { 0x18,0x0c,0x0c,0x14 },
-    { 0x26,0x13,0x13,0x35 }, { 0xc3,0xec,0xec,0x2f }, 
-    { 0xbe,0x5f,0x5f,0xe1 }, { 0x35,0x97,0x97,0xa2 },
-    { 0x88,0x44,0x44,0xcc }, { 0x2e,0x17,0x17,0x39 }, 
-    { 0x93,0xc4,0xc4,0x57 }, { 0x55,0xa7,0xa7,0xf2 },
-    { 0xfc,0x7e,0x7e,0x82 }, { 0x7a,0x3d,0x3d,0x47 }, 
-    { 0xc8,0x64,0x64,0xac }, { 0xba,0x5d,0x5d,0xe7 },
-    { 0x32,0x19,0x19,0x2b }, { 0xe6,0x73,0x73,0x95 }, 
-    { 0xc0,0x60,0x60,0xa0 }, { 0x19,0x81,0x81,0x98 },
-    { 0x9e,0x4f,0x4f,0xd1 }, { 0xa3,0xdc,0xdc,0x7f }, 
-    { 0x44,0x22,0x22,0x66 }, { 0x54,0x2a,0x2a,0x7e },
-    { 0x3b,0x90,0x90,0xab }, { 0x0b,0x88,0x88,0x83 }, 
-    { 0x8c,0x46,0x46,0xca }, { 0xc7,0xee,0xee,0x29 },
-    { 0x6b,0xb8,0xb8,0xd3 }, { 0x28,0x14,0x14,0x3c }, 
-    { 0xa7,0xde,0xde,0x79 }, { 0xbc,0x5e,0x5e,0xe2 },
-    { 0x16,0x0b,0x0b,0x1d }, { 0xad,0xdb,0xdb,0x76 }, 
-    { 0xdb,0xe0,0xe0,0x3b }, { 0x64,0x32,0x32,0x56 },
-    { 0x74,0x3a,0x3a,0x4e }, { 0x14,0x0a,0x0a,0x1e }, 
-    { 0x92,0x49,0x49,0xdb }, { 0x0c,0x06,0x06,0x0a },
-    { 0x48,0x24,0x24,0x6c }, { 0xb8,0x5c,0x5c,0xe4 }, 
-    { 0x9f,0xc2,0xc2,0x5d }, { 0xbd,0xd3,0xd3,0x6e },
-    { 0x43,0xac,0xac,0xef }, { 0xc4,0x62,0x62,0xa6 }, 
-    { 0x39,0x91,0x91,0xa8 }, { 0x31,0x95,0x95,0xa4 },
-    { 0xd3,0xe4,0xe4,0x37 }, { 0xf2,0x79,0x79,0x8b }, 
-    { 0xd5,0xe7,0xe7,0x32 }, { 0x8b,0xc8,0xc8,0x43 },
-    { 0x6e,0x37,0x37,0x59 }, { 0xda,0x6d,0x6d,0xb7 }, 
-    { 0x01,0x8d,0x8d,0x8c }, { 0xb1,0xd5,0xd5,0x64 },
-    { 0x9c,0x4e,0x4e,0xd2 }, { 0x49,0xa9,0xa9,0xe0 }, 
-    { 0xd8,0x6c,0x6c,0xb4 }, { 0xac,0x56,0x56,0xfa },
-    { 0xf3,0xf4,0xf4,0x07 }, { 0xcf,0xea,0xea,0x25 }, 
-    { 0xca,0x65,0x65,0xaf }, { 0xf4,0x7a,0x7a,0x8e },
-    { 0x47,0xae,0xae,0xe9 }, { 0x10,0x08,0x08,0x18 }, 
-    { 0x6f,0xba,0xba,0xd5 }, { 0xf0,0x78,0x78,0x88 },
-    { 0x4a,0x25,0x25,0x6f }, { 0x5c,0x2e,0x2e,0x72 }, 
-    { 0x38,0x1c,0x1c,0x24 }, { 0x57,0xa6,0xa6,0xf1 },
-    { 0x73,0xb4,0xb4,0xc7 }, { 0x97,0xc6,0xc6,0x51 }, 
-    { 0xcb,0xe8,0xe8,0x23 }, { 0xa1,0xdd,0xdd,0x7c },
-    { 0xe8,0x74,0x74,0x9c }, { 0x3e,0x1f,0x1f,0x21 }, 
-    { 0x96,0x4b,0x4b,0xdd }, { 0x61,0xbd,0xbd,0xdc }, 
-    { 0x0d,0x8b,0x8b,0x86 }, { 0x0f,0x8a,0x8a,0x85 }, 
-    { 0xe0,0x70,0x70,0x90 }, { 0x7c,0x3e,0x3e,0x42 },
-    { 0x71,0xb5,0xb5,0xc4 }, { 0xcc,0x66,0x66,0xaa }, 
-    { 0x90,0x48,0x48,0xd8 }, { 0x06,0x03,0x03,0x05 },
-    { 0xf7,0xf6,0xf6,0x01 }, { 0x1c,0x0e,0x0e,0x12 }, 
-    { 0xc2,0x61,0x61,0xa3 }, { 0x6a,0x35,0x35,0x5f },
-    { 0xae,0x57,0x57,0xf9 }, { 0x69,0xb9,0xb9,0xd0 }, 
-    { 0x17,0x86,0x86,0x91 }, { 0x99,0xc1,0xc1,0x58 },
-    { 0x3a,0x1d,0x1d,0x27 }, { 0x27,0x9e,0x9e,0xb9 }, 
-    { 0xd9,0xe1,0xe1,0x38 }, { 0xeb,0xf8,0xf8,0x13 },
-    { 0x2b,0x98,0x98,0xb3 }, { 0x22,0x11,0x11,0x33 }, 
-    { 0xd2,0x69,0x69,0xbb }, { 0xa9,0xd9,0xd9,0x70 },
-    { 0x07,0x8e,0x8e,0x89 }, { 0x33,0x94,0x94,0xa7 }, 
-    { 0x2d,0x9b,0x9b,0xb6 }, { 0x3c,0x1e,0x1e,0x22 },
-    { 0x15,0x87,0x87,0x92 }, { 0xc9,0xe9,0xe9,0x20 }, 
-    { 0x87,0xce,0xce,0x49 }, { 0xaa,0x55,0x55,0xff },
-    { 0x50,0x28,0x28,0x78 }, { 0xa5,0xdf,0xdf,0x7a }, 
-    { 0x03,0x8c,0x8c,0x8f }, { 0x59,0xa1,0xa1,0xf8 },
-    { 0x09,0x89,0x89,0x80 }, { 0x1a,0x0d,0x0d,0x17 }, 
-    { 0x65,0xbf,0xbf,0xda }, { 0xd7,0xe6,0xe6,0x31 },
-    { 0x84,0x42,0x42,0xc6 }, { 0xd0,0x68,0x68,0xb8 }, 
-    { 0x82,0x41,0x41,0xc3 }, { 0x29,0x99,0x99,0xb0 },
-    { 0x5a,0x2d,0x2d,0x77 }, { 0x1e,0x0f,0x0f,0x11 }, 
-    { 0x7b,0xb0,0xb0,0xcb }, { 0xa8,0x54,0x54,0xfc },
-    { 0x6d,0xbb,0xbb,0xd6 }, { 0x2c,0x16,0x16,0x3a }
-  };
-
-static const unsigned char T2[256][4] = 
-  {
-    { 0xa5,0xc6,0x63,0x63 }, { 0x84,0xf8,0x7c,0x7c },
-    { 0x99,0xee,0x77,0x77 }, { 0x8d,0xf6,0x7b,0x7b }, 
-    { 0x0d,0xff,0xf2,0xf2 }, { 0xbd,0xd6,0x6b,0x6b },
-    { 0xb1,0xde,0x6f,0x6f }, { 0x54,0x91,0xc5,0xc5 }, 
-    { 0x50,0x60,0x30,0x30 }, { 0x03,0x02,0x01,0x01 },
-    { 0xa9,0xce,0x67,0x67 }, { 0x7d,0x56,0x2b,0x2b }, 
-    { 0x19,0xe7,0xfe,0xfe }, { 0x62,0xb5,0xd7,0xd7 }, 
-    { 0xe6,0x4d,0xab,0xab }, { 0x9a,0xec,0x76,0x76 }, 
-    { 0x45,0x8f,0xca,0xca }, { 0x9d,0x1f,0x82,0x82 }, 
-    { 0x40,0x89,0xc9,0xc9 }, { 0x87,0xfa,0x7d,0x7d }, 
-    { 0x15,0xef,0xfa,0xfa }, { 0xeb,0xb2,0x59,0x59 }, 
-    { 0xc9,0x8e,0x47,0x47 }, { 0x0b,0xfb,0xf0,0xf0 }, 
-    { 0xec,0x41,0xad,0xad }, { 0x67,0xb3,0xd4,0xd4 }, 
-    { 0xfd,0x5f,0xa2,0xa2 }, { 0xea,0x45,0xaf,0xaf }, 
-    { 0xbf,0x23,0x9c,0x9c }, { 0xf7,0x53,0xa4,0xa4 }, 
-    { 0x96,0xe4,0x72,0x72 }, { 0x5b,0x9b,0xc0,0xc0 }, 
-    { 0xc2,0x75,0xb7,0xb7 }, { 0x1c,0xe1,0xfd,0xfd }, 
-    { 0xae,0x3d,0x93,0x93 }, { 0x6a,0x4c,0x26,0x26 }, 
-    { 0x5a,0x6c,0x36,0x36 }, { 0x41,0x7e,0x3f,0x3f },
-    { 0x02,0xf5,0xf7,0xf7 }, { 0x4f,0x83,0xcc,0xcc }, 
-    { 0x5c,0x68,0x34,0x34 }, { 0xf4,0x51,0xa5,0xa5 },
-    { 0x34,0xd1,0xe5,0xe5 }, { 0x08,0xf9,0xf1,0xf1 }, 
-    { 0x93,0xe2,0x71,0x71 }, { 0x73,0xab,0xd8,0xd8 },
-    { 0x53,0x62,0x31,0x31 }, { 0x3f,0x2a,0x15,0x15 }, 
-    { 0x0c,0x08,0x04,0x04 }, { 0x52,0x95,0xc7,0xc7 }, 
-    { 0x65,0x46,0x23,0x23 }, { 0x5e,0x9d,0xc3,0xc3 }, 
-    { 0x28,0x30,0x18,0x18 }, { 0xa1,0x37,0x96,0x96 }, 
-    { 0x0f,0x0a,0x05,0x05 }, { 0xb5,0x2f,0x9a,0x9a }, 
-    { 0x09,0x0e,0x07,0x07 }, { 0x36,0x24,0x12,0x12 },
-    { 0x9b,0x1b,0x80,0x80 }, { 0x3d,0xdf,0xe2,0xe2 }, 
-    { 0x26,0xcd,0xeb,0xeb }, { 0x69,0x4e,0x27,0x27 }, 
-    { 0xcd,0x7f,0xb2,0xb2 }, { 0x9f,0xea,0x75,0x75 }, 
-    { 0x1b,0x12,0x09,0x09 }, { 0x9e,0x1d,0x83,0x83 },
-    { 0x74,0x58,0x2c,0x2c }, { 0x2e,0x34,0x1a,0x1a }, 
-    { 0x2d,0x36,0x1b,0x1b }, { 0xb2,0xdc,0x6e,0x6e },
-    { 0xee,0xb4,0x5a,0x5a }, { 0xfb,0x5b,0xa0,0xa0 }, 
-    { 0xf6,0xa4,0x52,0x52 }, { 0x4d,0x76,0x3b,0x3b },
-    { 0x61,0xb7,0xd6,0xd6 }, { 0xce,0x7d,0xb3,0xb3 }, 
-    { 0x7b,0x52,0x29,0x29 }, { 0x3e,0xdd,0xe3,0xe3 }, 
-    { 0x71,0x5e,0x2f,0x2f }, { 0x97,0x13,0x84,0x84 }, 
-    { 0xf5,0xa6,0x53,0x53 }, { 0x68,0xb9,0xd1,0xd1 }, 
-    { 0x00,0x00,0x00,0x00 }, { 0x2c,0xc1,0xed,0xed }, 
-    { 0x60,0x40,0x20,0x20 }, { 0x1f,0xe3,0xfc,0xfc }, 
-    { 0xc8,0x79,0xb1,0xb1 }, { 0xed,0xb6,0x5b,0x5b }, 
-    { 0xbe,0xd4,0x6a,0x6a }, { 0x46,0x8d,0xcb,0xcb }, 
-    { 0xd9,0x67,0xbe,0xbe }, { 0x4b,0x72,0x39,0x39 }, 
-    { 0xde,0x94,0x4a,0x4a }, { 0xd4,0x98,0x4c,0x4c }, 
-    { 0xe8,0xb0,0x58,0x58 }, { 0x4a,0x85,0xcf,0xcf }, 
-    { 0x6b,0xbb,0xd0,0xd0 }, { 0x2a,0xc5,0xef,0xef },
-    { 0xe5,0x4f,0xaa,0xaa }, { 0x16,0xed,0xfb,0xfb }, 
-    { 0xc5,0x86,0x43,0x43 }, { 0xd7,0x9a,0x4d,0x4d }, 
-    { 0x55,0x66,0x33,0x33 }, { 0x94,0x11,0x85,0x85 }, 
-    { 0xcf,0x8a,0x45,0x45 }, { 0x10,0xe9,0xf9,0xf9 }, 
-    { 0x06,0x04,0x02,0x02 }, { 0x81,0xfe,0x7f,0x7f }, 
-    { 0xf0,0xa0,0x50,0x50 }, { 0x44,0x78,0x3c,0x3c },
-    { 0xba,0x25,0x9f,0x9f }, { 0xe3,0x4b,0xa8,0xa8 }, 
-    { 0xf3,0xa2,0x51,0x51 }, { 0xfe,0x5d,0xa3,0xa3 },
-    { 0xc0,0x80,0x40,0x40 }, { 0x8a,0x05,0x8f,0x8f }, 
-    { 0xad,0x3f,0x92,0x92 }, { 0xbc,0x21,0x9d,0x9d },
-    { 0x48,0x70,0x38,0x38 }, { 0x04,0xf1,0xf5,0xf5 }, 
-    { 0xdf,0x63,0xbc,0xbc }, { 0xc1,0x77,0xb6,0xb6 },
-    { 0x75,0xaf,0xda,0xda }, { 0x63,0x42,0x21,0x21 }, 
-    { 0x30,0x20,0x10,0x10 }, { 0x1a,0xe5,0xff,0xff },
-    { 0x0e,0xfd,0xf3,0xf3 }, { 0x6d,0xbf,0xd2,0xd2 }, 
-    { 0x4c,0x81,0xcd,0xcd }, { 0x14,0x18,0x0c,0x0c },
-    { 0x35,0x26,0x13,0x13 }, { 0x2f,0xc3,0xec,0xec }, 
-    { 0xe1,0xbe,0x5f,0x5f }, { 0xa2,0x35,0x97,0x97 },
-    { 0xcc,0x88,0x44,0x44 }, { 0x39,0x2e,0x17,0x17 }, 
-    { 0x57,0x93,0xc4,0xc4 }, { 0xf2,0x55,0xa7,0xa7 },
-    { 0x82,0xfc,0x7e,0x7e }, { 0x47,0x7a,0x3d,0x3d }, 
-    { 0xac,0xc8,0x64,0x64 }, { 0xe7,0xba,0x5d,0x5d },
-    { 0x2b,0x32,0x19,0x19 }, { 0x95,0xe6,0x73,0x73 }, 
-    { 0xa0,0xc0,0x60,0x60 }, { 0x98,0x19,0x81,0x81 }, 
-    { 0xd1,0x9e,0x4f,0x4f }, { 0x7f,0xa3,0xdc,0xdc }, 
-    { 0x66,0x44,0x22,0x22 }, { 0x7e,0x54,0x2a,0x2a }, 
-    { 0xab,0x3b,0x90,0x90 }, { 0x83,0x0b,0x88,0x88 }, 
-    { 0xca,0x8c,0x46,0x46 }, { 0x29,0xc7,0xee,0xee },
-    { 0xd3,0x6b,0xb8,0xb8 }, { 0x3c,0x28,0x14,0x14 }, 
-    { 0x79,0xa7,0xde,0xde }, { 0xe2,0xbc,0x5e,0x5e },
-    { 0x1d,0x16,0x0b,0x0b }, { 0x76,0xad,0xdb,0xdb }, 
-    { 0x3b,0xdb,0xe0,0xe0 }, { 0x56,0x64,0x32,0x32 },
-    { 0x4e,0x74,0x3a,0x3a }, { 0x1e,0x14,0x0a,0x0a }, 
-    { 0xdb,0x92,0x49,0x49 }, { 0x0a,0x0c,0x06,0x06 },
-    { 0x6c,0x48,0x24,0x24 }, { 0xe4,0xb8,0x5c,0x5c }, 
-    { 0x5d,0x9f,0xc2,0xc2 }, { 0x6e,0xbd,0xd3,0xd3 }, 
-    { 0xef,0x43,0xac,0xac }, { 0xa6,0xc4,0x62,0x62 }, 
-    { 0xa8,0x39,0x91,0x91 }, { 0xa4,0x31,0x95,0x95 },
-    { 0x37,0xd3,0xe4,0xe4 }, { 0x8b,0xf2,0x79,0x79 }, 
-    { 0x32,0xd5,0xe7,0xe7 }, { 0x43,0x8b,0xc8,0xc8 },
-    { 0x59,0x6e,0x37,0x37 }, { 0xb7,0xda,0x6d,0x6d }, 
-    { 0x8c,0x01,0x8d,0x8d }, { 0x64,0xb1,0xd5,0xd5 },
-    { 0xd2,0x9c,0x4e,0x4e }, { 0xe0,0x49,0xa9,0xa9 }, 
-    { 0xb4,0xd8,0x6c,0x6c }, { 0xfa,0xac,0x56,0x56 },
-    { 0x07,0xf3,0xf4,0xf4 }, { 0x25,0xcf,0xea,0xea }, 
-    { 0xaf,0xca,0x65,0x65 }, { 0x8e,0xf4,0x7a,0x7a },
-    { 0xe9,0x47,0xae,0xae }, { 0x18,0x10,0x08,0x08 }, 
-    { 0xd5,0x6f,0xba,0xba }, { 0x88,0xf0,0x78,0x78 }, 
-    { 0x6f,0x4a,0x25,0x25 }, { 0x72,0x5c,0x2e,0x2e }, 
-    { 0x24,0x38,0x1c,0x1c }, { 0xf1,0x57,0xa6,0xa6 }, 
-    { 0xc7,0x73,0xb4,0xb4 }, { 0x51,0x97,0xc6,0xc6 }, 
-    { 0x23,0xcb,0xe8,0xe8 }, { 0x7c,0xa1,0xdd,0xdd },
-    { 0x9c,0xe8,0x74,0x74 }, { 0x21,0x3e,0x1f,0x1f }, 
-    { 0xdd,0x96,0x4b,0x4b }, { 0xdc,0x61,0xbd,0xbd },
-    { 0x86,0x0d,0x8b,0x8b }, { 0x85,0x0f,0x8a,0x8a }, 
-    { 0x90,0xe0,0x70,0x70 }, { 0x42,0x7c,0x3e,0x3e }, 
-    { 0xc4,0x71,0xb5,0xb5 }, { 0xaa,0xcc,0x66,0x66 }, 
-    { 0xd8,0x90,0x48,0x48 }, { 0x05,0x06,0x03,0x03 },
-    { 0x01,0xf7,0xf6,0xf6 }, { 0x12,0x1c,0x0e,0x0e }, 
-    { 0xa3,0xc2,0x61,0x61 }, { 0x5f,0x6a,0x35,0x35 },
-    { 0xf9,0xae,0x57,0x57 }, { 0xd0,0x69,0xb9,0xb9 }, 
-    { 0x91,0x17,0x86,0x86 }, { 0x58,0x99,0xc1,0xc1 }, 
-    { 0x27,0x3a,0x1d,0x1d }, { 0xb9,0x27,0x9e,0x9e }, 
-    { 0x38,0xd9,0xe1,0xe1 }, { 0x13,0xeb,0xf8,0xf8 },
-    { 0xb3,0x2b,0x98,0x98 }, { 0x33,0x22,0x11,0x11 }, 
-    { 0xbb,0xd2,0x69,0x69 }, { 0x70,0xa9,0xd9,0xd9 },
-    { 0x89,0x07,0x8e,0x8e }, { 0xa7,0x33,0x94,0x94 }, 
-    { 0xb6,0x2d,0x9b,0x9b }, { 0x22,0x3c,0x1e,0x1e },
-    { 0x92,0x15,0x87,0x87 }, { 0x20,0xc9,0xe9,0xe9 }, 
-    { 0x49,0x87,0xce,0xce }, { 0xff,0xaa,0x55,0x55 },
-    { 0x78,0x50,0x28,0x28 }, { 0x7a,0xa5,0xdf,0xdf }, 
-    { 0x8f,0x03,0x8c,0x8c }, { 0xf8,0x59,0xa1,0xa1 }, 
-    { 0x80,0x09,0x89,0x89 }, { 0x17,0x1a,0x0d,0x0d }, 
-    { 0xda,0x65,0xbf,0xbf }, { 0x31,0xd7,0xe6,0xe6 },
-    { 0xc6,0x84,0x42,0x42 }, { 0xb8,0xd0,0x68,0x68 }, 
-    { 0xc3,0x82,0x41,0x41 }, { 0xb0,0x29,0x99,0x99 }, 
-    { 0x77,0x5a,0x2d,0x2d }, { 0x11,0x1e,0x0f,0x0f }, 
-    { 0xcb,0x7b,0xb0,0xb0 }, { 0xfc,0xa8,0x54,0x54 }, 
-    { 0xd6,0x6d,0xbb,0xbb }, { 0x3a,0x2c,0x16,0x16 }
-  };
-
-static const unsigned char T3[256][4] = 
-  {
-    { 0x63,0xa5,0xc6,0x63 }, { 0x7c,0x84,0xf8,0x7c },
-    { 0x77,0x99,0xee,0x77 }, { 0x7b,0x8d,0xf6,0x7b }, 
-    { 0xf2,0x0d,0xff,0xf2 }, { 0x6b,0xbd,0xd6,0x6b },
-    { 0x6f,0xb1,0xde,0x6f }, { 0xc5,0x54,0x91,0xc5 }, 
-    { 0x30,0x50,0x60,0x30 }, { 0x01,0x03,0x02,0x01 },
-    { 0x67,0xa9,0xce,0x67 }, { 0x2b,0x7d,0x56,0x2b }, 
-    { 0xfe,0x19,0xe7,0xfe }, { 0xd7,0x62,0xb5,0xd7 }, 
-    { 0xab,0xe6,0x4d,0xab }, { 0x76,0x9a,0xec,0x76 }, 
-    { 0xca,0x45,0x8f,0xca }, { 0x82,0x9d,0x1f,0x82 },
-    { 0xc9,0x40,0x89,0xc9 }, { 0x7d,0x87,0xfa,0x7d }, 
-    { 0xfa,0x15,0xef,0xfa }, { 0x59,0xeb,0xb2,0x59 }, 
-    { 0x47,0xc9,0x8e,0x47 }, { 0xf0,0x0b,0xfb,0xf0 }, 
-    { 0xad,0xec,0x41,0xad }, { 0xd4,0x67,0xb3,0xd4 }, 
-    { 0xa2,0xfd,0x5f,0xa2 }, { 0xaf,0xea,0x45,0xaf }, 
-    { 0x9c,0xbf,0x23,0x9c }, { 0xa4,0xf7,0x53,0xa4 },
-    { 0x72,0x96,0xe4,0x72 }, { 0xc0,0x5b,0x9b,0xc0 }, 
-    { 0xb7,0xc2,0x75,0xb7 }, { 0xfd,0x1c,0xe1,0xfd }, 
-    { 0x93,0xae,0x3d,0x93 }, { 0x26,0x6a,0x4c,0x26 }, 
-    { 0x36,0x5a,0x6c,0x36 }, { 0x3f,0x41,0x7e,0x3f },
-    { 0xf7,0x02,0xf5,0xf7 }, { 0xcc,0x4f,0x83,0xcc }, 
-    { 0x34,0x5c,0x68,0x34 }, { 0xa5,0xf4,0x51,0xa5 },
-    { 0xe5,0x34,0xd1,0xe5 }, { 0xf1,0x08,0xf9,0xf1 }, 
-    { 0x71,0x93,0xe2,0x71 }, { 0xd8,0x73,0xab,0xd8 },
-    { 0x31,0x53,0x62,0x31 }, { 0x15,0x3f,0x2a,0x15 }, 
-    { 0x04,0x0c,0x08,0x04 }, { 0xc7,0x52,0x95,0xc7 }, 
-    { 0x23,0x65,0x46,0x23 }, { 0xc3,0x5e,0x9d,0xc3 }, 
-    { 0x18,0x28,0x30,0x18 }, { 0x96,0xa1,0x37,0x96 },
-    { 0x05,0x0f,0x0a,0x05 }, { 0x9a,0xb5,0x2f,0x9a }, 
-    { 0x07,0x09,0x0e,0x07 }, { 0x12,0x36,0x24,0x12 }, 
-    { 0x80,0x9b,0x1b,0x80 }, { 0xe2,0x3d,0xdf,0xe2 }, 
-    { 0xeb,0x26,0xcd,0xeb }, { 0x27,0x69,0x4e,0x27 },
-    { 0xb2,0xcd,0x7f,0xb2 }, { 0x75,0x9f,0xea,0x75 }, 
-    { 0x09,0x1b,0x12,0x09 }, { 0x83,0x9e,0x1d,0x83 },
-    { 0x2c,0x74,0x58,0x2c }, { 0x1a,0x2e,0x34,0x1a }, 
-    { 0x1b,0x2d,0x36,0x1b }, { 0x6e,0xb2,0xdc,0x6e },
-    { 0x5a,0xee,0xb4,0x5a }, { 0xa0,0xfb,0x5b,0xa0 }, 
-    { 0x52,0xf6,0xa4,0x52 }, { 0x3b,0x4d,0x76,0x3b },
-    { 0xd6,0x61,0xb7,0xd6 }, { 0xb3,0xce,0x7d,0xb3 }, 
-    { 0x29,0x7b,0x52,0x29 }, { 0xe3,0x3e,0xdd,0xe3 }, 
-    { 0x2f,0x71,0x5e,0x2f }, { 0x84,0x97,0x13,0x84 }, 
-    { 0x53,0xf5,0xa6,0x53 }, { 0xd1,0x68,0xb9,0xd1 },
-    { 0x00,0x00,0x00,0x00 }, { 0xed,0x2c,0xc1,0xed }, 
-    { 0x20,0x60,0x40,0x20 }, { 0xfc,0x1f,0xe3,0xfc },
-    { 0xb1,0xc8,0x79,0xb1 }, { 0x5b,0xed,0xb6,0x5b }, 
-    { 0x6a,0xbe,0xd4,0x6a }, { 0xcb,0x46,0x8d,0xcb },
-    { 0xbe,0xd9,0x67,0xbe }, { 0x39,0x4b,0x72,0x39 }, 
-    { 0x4a,0xde,0x94,0x4a }, { 0x4c,0xd4,0x98,0x4c },
-    { 0x58,0xe8,0xb0,0x58 }, { 0xcf,0x4a,0x85,0xcf }, 
-    { 0xd0,0x6b,0xbb,0xd0 }, { 0xef,0x2a,0xc5,0xef },
-    { 0xaa,0xe5,0x4f,0xaa }, { 0xfb,0x16,0xed,0xfb }, 
-    { 0x43,0xc5,0x86,0x43 }, { 0x4d,0xd7,0x9a,0x4d },
-    { 0x33,0x55,0x66,0x33 }, { 0x85,0x94,0x11,0x85 }, 
-    { 0x45,0xcf,0x8a,0x45 }, { 0xf9,0x10,0xe9,0xf9 },
-    { 0x02,0x06,0x04,0x02 }, { 0x7f,0x81,0xfe,0x7f }, 
-    { 0x50,0xf0,0xa0,0x50 }, { 0x3c,0x44,0x78,0x3c },
-    { 0x9f,0xba,0x25,0x9f }, { 0xa8,0xe3,0x4b,0xa8 }, 
-    { 0x51,0xf3,0xa2,0x51 }, { 0xa3,0xfe,0x5d,0xa3 },
-    { 0x40,0xc0,0x80,0x40 }, { 0x8f,0x8a,0x05,0x8f }, 
-    { 0x92,0xad,0x3f,0x92 }, { 0x9d,0xbc,0x21,0x9d },
-    { 0x38,0x48,0x70,0x38 }, { 0xf5,0x04,0xf1,0xf5 }, 
-    { 0xbc,0xdf,0x63,0xbc }, { 0xb6,0xc1,0x77,0xb6 },
-    { 0xda,0x75,0xaf,0xda }, { 0x21,0x63,0x42,0x21 }, 
-    { 0x10,0x30,0x20,0x10 }, { 0xff,0x1a,0xe5,0xff },
-    { 0xf3,0x0e,0xfd,0xf3 }, { 0xd2,0x6d,0xbf,0xd2 }, 
-    { 0xcd,0x4c,0x81,0xcd }, { 0x0c,0x14,0x18,0x0c }, 
-    { 0x13,0x35,0x26,0x13 }, { 0xec,0x2f,0xc3,0xec }, 
-    { 0x5f,0xe1,0xbe,0x5f }, { 0x97,0xa2,0x35,0x97 },
-    { 0x44,0xcc,0x88,0x44 }, { 0x17,0x39,0x2e,0x17 }, 
-    { 0xc4,0x57,0x93,0xc4 }, { 0xa7,0xf2,0x55,0xa7 },
-    { 0x7e,0x82,0xfc,0x7e }, { 0x3d,0x47,0x7a,0x3d }, 
-    { 0x64,0xac,0xc8,0x64 }, { 0x5d,0xe7,0xba,0x5d },
-    { 0x19,0x2b,0x32,0x19 }, { 0x73,0x95,0xe6,0x73 }, 
-    { 0x60,0xa0,0xc0,0x60 }, { 0x81,0x98,0x19,0x81 },
-    { 0x4f,0xd1,0x9e,0x4f }, { 0xdc,0x7f,0xa3,0xdc }, 
-    { 0x22,0x66,0x44,0x22 }, { 0x2a,0x7e,0x54,0x2a },
-    { 0x90,0xab,0x3b,0x90 }, { 0x88,0x83,0x0b,0x88 }, 
-    { 0x46,0xca,0x8c,0x46 }, { 0xee,0x29,0xc7,0xee },
-    { 0xb8,0xd3,0x6b,0xb8 }, { 0x14,0x3c,0x28,0x14 }, 
-    { 0xde,0x79,0xa7,0xde }, { 0x5e,0xe2,0xbc,0x5e }, 
-    { 0x0b,0x1d,0x16,0x0b }, { 0xdb,0x76,0xad,0xdb }, 
-    { 0xe0,0x3b,0xdb,0xe0 }, { 0x32,0x56,0x64,0x32 },
-    { 0x3a,0x4e,0x74,0x3a }, { 0x0a,0x1e,0x14,0x0a }, 
-    { 0x49,0xdb,0x92,0x49 }, { 0x06,0x0a,0x0c,0x06 },
-    { 0x24,0x6c,0x48,0x24 }, { 0x5c,0xe4,0xb8,0x5c }, 
-    { 0xc2,0x5d,0x9f,0xc2 }, { 0xd3,0x6e,0xbd,0xd3 },
-    { 0xac,0xef,0x43,0xac }, { 0x62,0xa6,0xc4,0x62 }, 
-    { 0x91,0xa8,0x39,0x91 }, { 0x95,0xa4,0x31,0x95 },
-    { 0xe4,0x37,0xd3,0xe4 }, { 0x79,0x8b,0xf2,0x79 }, 
-    { 0xe7,0x32,0xd5,0xe7 }, { 0xc8,0x43,0x8b,0xc8 }, 
-    { 0x37,0x59,0x6e,0x37 }, { 0x6d,0xb7,0xda,0x6d }, 
-    { 0x8d,0x8c,0x01,0x8d }, { 0xd5,0x64,0xb1,0xd5 }, 
-    { 0x4e,0xd2,0x9c,0x4e }, { 0xa9,0xe0,0x49,0xa9 }, 
-    { 0x6c,0xb4,0xd8,0x6c }, { 0x56,0xfa,0xac,0x56 },
-    { 0xf4,0x07,0xf3,0xf4 }, { 0xea,0x25,0xcf,0xea }, 
-    { 0x65,0xaf,0xca,0x65 }, { 0x7a,0x8e,0xf4,0x7a }, 
-    { 0xae,0xe9,0x47,0xae }, { 0x08,0x18,0x10,0x08 }, 
-    { 0xba,0xd5,0x6f,0xba }, { 0x78,0x88,0xf0,0x78 }, 
-    { 0x25,0x6f,0x4a,0x25 }, { 0x2e,0x72,0x5c,0x2e }, 
-    { 0x1c,0x24,0x38,0x1c }, { 0xa6,0xf1,0x57,0xa6 }, 
-    { 0xb4,0xc7,0x73,0xb4 }, { 0xc6,0x51,0x97,0xc6 }, 
-    { 0xe8,0x23,0xcb,0xe8 }, { 0xdd,0x7c,0xa1,0xdd },
-    { 0x74,0x9c,0xe8,0x74 }, { 0x1f,0x21,0x3e,0x1f }, 
-    { 0x4b,0xdd,0x96,0x4b }, { 0xbd,0xdc,0x61,0xbd },
-    { 0x8b,0x86,0x0d,0x8b }, { 0x8a,0x85,0x0f,0x8a }, 
-    { 0x70,0x90,0xe0,0x70 }, { 0x3e,0x42,0x7c,0x3e },
-    { 0xb5,0xc4,0x71,0xb5 }, { 0x66,0xaa,0xcc,0x66 }, 
-    { 0x48,0xd8,0x90,0x48 }, { 0x03,0x05,0x06,0x03 },
-    { 0xf6,0x01,0xf7,0xf6 }, { 0x0e,0x12,0x1c,0x0e }, 
-    { 0x61,0xa3,0xc2,0x61 }, { 0x35,0x5f,0x6a,0x35 },
-    { 0x57,0xf9,0xae,0x57 }, { 0xb9,0xd0,0x69,0xb9 }, 
-    { 0x86,0x91,0x17,0x86 }, { 0xc1,0x58,0x99,0xc1 }, 
-    { 0x1d,0x27,0x3a,0x1d }, { 0x9e,0xb9,0x27,0x9e }, 
-    { 0xe1,0x38,0xd9,0xe1 }, { 0xf8,0x13,0xeb,0xf8 },
-    { 0x98,0xb3,0x2b,0x98 }, { 0x11,0x33,0x22,0x11 }, 
-    { 0x69,0xbb,0xd2,0x69 }, { 0xd9,0x70,0xa9,0xd9 },
-    { 0x8e,0x89,0x07,0x8e }, { 0x94,0xa7,0x33,0x94 }, 
-    { 0x9b,0xb6,0x2d,0x9b }, { 0x1e,0x22,0x3c,0x1e },
-    { 0x87,0x92,0x15,0x87 }, { 0xe9,0x20,0xc9,0xe9 }, 
-    { 0xce,0x49,0x87,0xce }, { 0x55,0xff,0xaa,0x55 },
-    { 0x28,0x78,0x50,0x28 }, { 0xdf,0x7a,0xa5,0xdf }, 
-    { 0x8c,0x8f,0x03,0x8c }, { 0xa1,0xf8,0x59,0xa1 },
-    { 0x89,0x80,0x09,0x89 }, { 0x0d,0x17,0x1a,0x0d }, 
-    { 0xbf,0xda,0x65,0xbf }, { 0xe6,0x31,0xd7,0xe6 },
-    { 0x42,0xc6,0x84,0x42 }, { 0x68,0xb8,0xd0,0x68 }, 
-    { 0x41,0xc3,0x82,0x41 }, { 0x99,0xb0,0x29,0x99 },
-    { 0x2d,0x77,0x5a,0x2d }, { 0x0f,0x11,0x1e,0x0f }, 
-    { 0xb0,0xcb,0x7b,0xb0 }, { 0x54,0xfc,0xa8,0x54 },
-    { 0xbb,0xd6,0x6d,0xbb }, { 0x16,0x3a,0x2c,0x16 }
-  };
-
-static const unsigned char T4[256][4] = 
-  {
-    { 0x63,0x63,0xa5,0xc6 }, { 0x7c,0x7c,0x84,0xf8 },
-    { 0x77,0x77,0x99,0xee }, { 0x7b,0x7b,0x8d,0xf6 }, 
-    { 0xf2,0xf2,0x0d,0xff }, { 0x6b,0x6b,0xbd,0xd6 }, 
-    { 0x6f,0x6f,0xb1,0xde }, { 0xc5,0xc5,0x54,0x91 }, 
-    { 0x30,0x30,0x50,0x60 }, { 0x01,0x01,0x03,0x02 },
-    { 0x67,0x67,0xa9,0xce }, { 0x2b,0x2b,0x7d,0x56 }, 
-    { 0xfe,0xfe,0x19,0xe7 }, { 0xd7,0xd7,0x62,0xb5 },
-    { 0xab,0xab,0xe6,0x4d }, { 0x76,0x76,0x9a,0xec }, 
-    { 0xca,0xca,0x45,0x8f }, { 0x82,0x82,0x9d,0x1f },
-    { 0xc9,0xc9,0x40,0x89 }, { 0x7d,0x7d,0x87,0xfa }, 
-    { 0xfa,0xfa,0x15,0xef }, { 0x59,0x59,0xeb,0xb2 },
-    { 0x47,0x47,0xc9,0x8e }, { 0xf0,0xf0,0x0b,0xfb }, 
-    { 0xad,0xad,0xec,0x41 }, { 0xd4,0xd4,0x67,0xb3 },
-    { 0xa2,0xa2,0xfd,0x5f }, { 0xaf,0xaf,0xea,0x45 }, 
-    { 0x9c,0x9c,0xbf,0x23 }, { 0xa4,0xa4,0xf7,0x53 },
-    { 0x72,0x72,0x96,0xe4 }, { 0xc0,0xc0,0x5b,0x9b }, 
-    { 0xb7,0xb7,0xc2,0x75 }, { 0xfd,0xfd,0x1c,0xe1 },
-    { 0x93,0x93,0xae,0x3d }, { 0x26,0x26,0x6a,0x4c }, 
-    { 0x36,0x36,0x5a,0x6c }, { 0x3f,0x3f,0x41,0x7e },
-    { 0xf7,0xf7,0x02,0xf5 }, { 0xcc,0xcc,0x4f,0x83 }, 
-    { 0x34,0x34,0x5c,0x68 }, { 0xa5,0xa5,0xf4,0x51 },
-    { 0xe5,0xe5,0x34,0xd1 }, { 0xf1,0xf1,0x08,0xf9 }, 
-    { 0x71,0x71,0x93,0xe2 }, { 0xd8,0xd8,0x73,0xab },
-    { 0x31,0x31,0x53,0x62 }, { 0x15,0x15,0x3f,0x2a }, 
-    { 0x04,0x04,0x0c,0x08 }, { 0xc7,0xc7,0x52,0x95 },
-    { 0x23,0x23,0x65,0x46 }, { 0xc3,0xc3,0x5e,0x9d }, 
-    { 0x18,0x18,0x28,0x30 }, { 0x96,0x96,0xa1,0x37 },
-    { 0x05,0x05,0x0f,0x0a }, { 0x9a,0x9a,0xb5,0x2f }, 
-    { 0x07,0x07,0x09,0x0e }, { 0x12,0x12,0x36,0x24 },
-    { 0x80,0x80,0x9b,0x1b }, { 0xe2,0xe2,0x3d,0xdf }, 
-    { 0xeb,0xeb,0x26,0xcd }, { 0x27,0x27,0x69,0x4e },
-    { 0xb2,0xb2,0xcd,0x7f }, { 0x75,0x75,0x9f,0xea }, 
-    { 0x09,0x09,0x1b,0x12 }, { 0x83,0x83,0x9e,0x1d },
-    { 0x2c,0x2c,0x74,0x58 }, { 0x1a,0x1a,0x2e,0x34 }, 
-    { 0x1b,0x1b,0x2d,0x36 }, { 0x6e,0x6e,0xb2,0xdc },
-    { 0x5a,0x5a,0xee,0xb4 }, { 0xa0,0xa0,0xfb,0x5b }, 
-    { 0x52,0x52,0xf6,0xa4 }, { 0x3b,0x3b,0x4d,0x76 },
-    { 0xd6,0xd6,0x61,0xb7 }, { 0xb3,0xb3,0xce,0x7d }, 
-    { 0x29,0x29,0x7b,0x52 }, { 0xe3,0xe3,0x3e,0xdd },
-    { 0x2f,0x2f,0x71,0x5e }, { 0x84,0x84,0x97,0x13 }, 
-    { 0x53,0x53,0xf5,0xa6 }, { 0xd1,0xd1,0x68,0xb9 },
-    { 0x00,0x00,0x00,0x00 }, { 0xed,0xed,0x2c,0xc1 }, 
-    { 0x20,0x20,0x60,0x40 }, { 0xfc,0xfc,0x1f,0xe3 },
-    { 0xb1,0xb1,0xc8,0x79 }, { 0x5b,0x5b,0xed,0xb6 }, 
-    { 0x6a,0x6a,0xbe,0xd4 }, { 0xcb,0xcb,0x46,0x8d },
-    { 0xbe,0xbe,0xd9,0x67 }, { 0x39,0x39,0x4b,0x72 }, 
-    { 0x4a,0x4a,0xde,0x94 }, { 0x4c,0x4c,0xd4,0x98 },
-    { 0x58,0x58,0xe8,0xb0 }, { 0xcf,0xcf,0x4a,0x85 }, 
-    { 0xd0,0xd0,0x6b,0xbb }, { 0xef,0xef,0x2a,0xc5 },
-    { 0xaa,0xaa,0xe5,0x4f }, { 0xfb,0xfb,0x16,0xed }, 
-    { 0x43,0x43,0xc5,0x86 }, { 0x4d,0x4d,0xd7,0x9a },
-    { 0x33,0x33,0x55,0x66 }, { 0x85,0x85,0x94,0x11 }, 
-    { 0x45,0x45,0xcf,0x8a }, { 0xf9,0xf9,0x10,0xe9 },
-    { 0x02,0x02,0x06,0x04 }, { 0x7f,0x7f,0x81,0xfe }, 
-    { 0x50,0x50,0xf0,0xa0 }, { 0x3c,0x3c,0x44,0x78 },
-    { 0x9f,0x9f,0xba,0x25 }, { 0xa8,0xa8,0xe3,0x4b }, 
-    { 0x51,0x51,0xf3,0xa2 }, { 0xa3,0xa3,0xfe,0x5d },
-    { 0x40,0x40,0xc0,0x80 }, { 0x8f,0x8f,0x8a,0x05 }, 
-    { 0x92,0x92,0xad,0x3f }, { 0x9d,0x9d,0xbc,0x21 },
-    { 0x38,0x38,0x48,0x70 }, { 0xf5,0xf5,0x04,0xf1 }, 
-    { 0xbc,0xbc,0xdf,0x63 }, { 0xb6,0xb6,0xc1,0x77 },
-    { 0xda,0xda,0x75,0xaf }, { 0x21,0x21,0x63,0x42 }, 
-    { 0x10,0x10,0x30,0x20 }, { 0xff,0xff,0x1a,0xe5 },
-    { 0xf3,0xf3,0x0e,0xfd }, { 0xd2,0xd2,0x6d,0xbf }, 
-    { 0xcd,0xcd,0x4c,0x81 }, { 0x0c,0x0c,0x14,0x18 },
-    { 0x13,0x13,0x35,0x26 }, { 0xec,0xec,0x2f,0xc3 }, 
-    { 0x5f,0x5f,0xe1,0xbe }, { 0x97,0x97,0xa2,0x35 },
-    { 0x44,0x44,0xcc,0x88 }, { 0x17,0x17,0x39,0x2e }, 
-    { 0xc4,0xc4,0x57,0x93 }, { 0xa7,0xa7,0xf2,0x55 },
-    { 0x7e,0x7e,0x82,0xfc }, { 0x3d,0x3d,0x47,0x7a }, 
-    { 0x64,0x64,0xac,0xc8 }, { 0x5d,0x5d,0xe7,0xba },
-    { 0x19,0x19,0x2b,0x32 }, { 0x73,0x73,0x95,0xe6 }, 
-    { 0x60,0x60,0xa0,0xc0 }, { 0x81,0x81,0x98,0x19 },
-    { 0x4f,0x4f,0xd1,0x9e }, { 0xdc,0xdc,0x7f,0xa3 }, 
-    { 0x22,0x22,0x66,0x44 }, { 0x2a,0x2a,0x7e,0x54 },
-    { 0x90,0x90,0xab,0x3b }, { 0x88,0x88,0x83,0x0b }, 
-    { 0x46,0x46,0xca,0x8c }, { 0xee,0xee,0x29,0xc7 },
-    { 0xb8,0xb8,0xd3,0x6b }, { 0x14,0x14,0x3c,0x28 }, 
-    { 0xde,0xde,0x79,0xa7 }, { 0x5e,0x5e,0xe2,0xbc },
-    { 0x0b,0x0b,0x1d,0x16 }, { 0xdb,0xdb,0x76,0xad }, 
-    { 0xe0,0xe0,0x3b,0xdb }, { 0x32,0x32,0x56,0x64 },
-    { 0x3a,0x3a,0x4e,0x74 }, { 0x0a,0x0a,0x1e,0x14 }, 
-    { 0x49,0x49,0xdb,0x92 }, { 0x06,0x06,0x0a,0x0c },
-    { 0x24,0x24,0x6c,0x48 }, { 0x5c,0x5c,0xe4,0xb8 }, 
-    { 0xc2,0xc2,0x5d,0x9f }, { 0xd3,0xd3,0x6e,0xbd },
-    { 0xac,0xac,0xef,0x43 }, { 0x62,0x62,0xa6,0xc4 }, 
-    { 0x91,0x91,0xa8,0x39 }, { 0x95,0x95,0xa4,0x31 },
-    { 0xe4,0xe4,0x37,0xd3 }, { 0x79,0x79,0x8b,0xf2 }, 
-    { 0xe7,0xe7,0x32,0xd5 }, { 0xc8,0xc8,0x43,0x8b },
-    { 0x37,0x37,0x59,0x6e }, { 0x6d,0x6d,0xb7,0xda }, 
-    { 0x8d,0x8d,0x8c,0x01 }, { 0xd5,0xd5,0x64,0xb1 }, 
-    { 0x4e,0x4e,0xd2,0x9c }, { 0xa9,0xa9,0xe0,0x49 }, 
-    { 0x6c,0x6c,0xb4,0xd8 }, { 0x56,0x56,0xfa,0xac }, 
-    { 0xf4,0xf4,0x07,0xf3 }, { 0xea,0xea,0x25,0xcf }, 
-    { 0x65,0x65,0xaf,0xca }, { 0x7a,0x7a,0x8e,0xf4 }, 
-    { 0xae,0xae,0xe9,0x47 }, { 0x08,0x08,0x18,0x10 }, 
-    { 0xba,0xba,0xd5,0x6f }, { 0x78,0x78,0x88,0xf0 }, 
-    { 0x25,0x25,0x6f,0x4a }, { 0x2e,0x2e,0x72,0x5c }, 
-    { 0x1c,0x1c,0x24,0x38 }, { 0xa6,0xa6,0xf1,0x57 },
-    { 0xb4,0xb4,0xc7,0x73 }, { 0xc6,0xc6,0x51,0x97 }, 
-    { 0xe8,0xe8,0x23,0xcb }, { 0xdd,0xdd,0x7c,0xa1 },
-    { 0x74,0x74,0x9c,0xe8 }, { 0x1f,0x1f,0x21,0x3e }, 
-    { 0x4b,0x4b,0xdd,0x96 }, { 0xbd,0xbd,0xdc,0x61 },
-    { 0x8b,0x8b,0x86,0x0d }, { 0x8a,0x8a,0x85,0x0f }, 
-    { 0x70,0x70,0x90,0xe0 }, { 0x3e,0x3e,0x42,0x7c },
-    { 0xb5,0xb5,0xc4,0x71 }, { 0x66,0x66,0xaa,0xcc }, 
-    { 0x48,0x48,0xd8,0x90 }, { 0x03,0x03,0x05,0x06 },
-    { 0xf6,0xf6,0x01,0xf7 }, { 0x0e,0x0e,0x12,0x1c }, 
-    { 0x61,0x61,0xa3,0xc2 }, { 0x35,0x35,0x5f,0x6a },
-    { 0x57,0x57,0xf9,0xae }, { 0xb9,0xb9,0xd0,0x69 }, 
-    { 0x86,0x86,0x91,0x17 }, { 0xc1,0xc1,0x58,0x99 },
-    { 0x1d,0x1d,0x27,0x3a }, { 0x9e,0x9e,0xb9,0x27 }, 
-    { 0xe1,0xe1,0x38,0xd9 }, { 0xf8,0xf8,0x13,0xeb },
-    { 0x98,0x98,0xb3,0x2b }, { 0x11,0x11,0x33,0x22 }, 
-    { 0x69,0x69,0xbb,0xd2 }, { 0xd9,0xd9,0x70,0xa9 },
-    { 0x8e,0x8e,0x89,0x07 }, { 0x94,0x94,0xa7,0x33 }, 
-    { 0x9b,0x9b,0xb6,0x2d }, { 0x1e,0x1e,0x22,0x3c },
-    { 0x87,0x87,0x92,0x15 }, { 0xe9,0xe9,0x20,0xc9 }, 
-    { 0xce,0xce,0x49,0x87 }, { 0x55,0x55,0xff,0xaa },
-    { 0x28,0x28,0x78,0x50 }, { 0xdf,0xdf,0x7a,0xa5 }, 
-    { 0x8c,0x8c,0x8f,0x03 }, { 0xa1,0xa1,0xf8,0x59 },
-    { 0x89,0x89,0x80,0x09 }, { 0x0d,0x0d,0x17,0x1a }, 
-    { 0xbf,0xbf,0xda,0x65 }, { 0xe6,0xe6,0x31,0xd7 }, 
-    { 0x42,0x42,0xc6,0x84 }, { 0x68,0x68,0xb8,0xd0 }, 
-    { 0x41,0x41,0xc3,0x82 }, { 0x99,0x99,0xb0,0x29 },
-    { 0x2d,0x2d,0x77,0x5a }, { 0x0f,0x0f,0x11,0x1e }, 
-    { 0xb0,0xb0,0xcb,0x7b }, { 0x54,0x54,0xfc,0xa8 },
-    { 0xbb,0xbb,0xd6,0x6d }, { 0x16,0x16,0x3a,0x2c }
-  };
-
-static const unsigned char T5[256][4] = 
-  {
-    { 0x51,0xf4,0xa7,0x50 }, { 0x7e,0x41,0x65,0x53 }, 
-    { 0x1a,0x17,0xa4,0xc3 }, { 0x3a,0x27,0x5e,0x96 }, 
-    { 0x3b,0xab,0x6b,0xcb }, { 0x1f,0x9d,0x45,0xf1 },
-    { 0xac,0xfa,0x58,0xab }, { 0x4b,0xe3,0x03,0x93 }, 
-    { 0x20,0x30,0xfa,0x55 }, { 0xad,0x76,0x6d,0xf6 },
-    { 0x88,0xcc,0x76,0x91 }, { 0xf5,0x02,0x4c,0x25 }, 
-    { 0x4f,0xe5,0xd7,0xfc }, { 0xc5,0x2a,0xcb,0xd7 },
-    { 0x26,0x35,0x44,0x80 }, { 0xb5,0x62,0xa3,0x8f }, 
-    { 0xde,0xb1,0x5a,0x49 }, { 0x25,0xba,0x1b,0x67 },
-    { 0x45,0xea,0x0e,0x98 }, { 0x5d,0xfe,0xc0,0xe1 }, 
-    { 0xc3,0x2f,0x75,0x02 }, { 0x81,0x4c,0xf0,0x12 },
-    { 0x8d,0x46,0x97,0xa3 }, { 0x6b,0xd3,0xf9,0xc6 }, 
-    { 0x03,0x8f,0x5f,0xe7 }, { 0x15,0x92,0x9c,0x95 },
-    { 0xbf,0x6d,0x7a,0xeb }, { 0x95,0x52,0x59,0xda }, 
-    { 0xd4,0xbe,0x83,0x2d }, { 0x58,0x74,0x21,0xd3 },
-    { 0x49,0xe0,0x69,0x29 }, { 0x8e,0xc9,0xc8,0x44 }, 
-    { 0x75,0xc2,0x89,0x6a }, { 0xf4,0x8e,0x79,0x78 },
-    { 0x99,0x58,0x3e,0x6b }, { 0x27,0xb9,0x71,0xdd }, 
-    { 0xbe,0xe1,0x4f,0xb6 }, { 0xf0,0x88,0xad,0x17 },
-    { 0xc9,0x20,0xac,0x66 }, { 0x7d,0xce,0x3a,0xb4 }, 
-    { 0x63,0xdf,0x4a,0x18 }, { 0xe5,0x1a,0x31,0x82 },
-    { 0x97,0x51,0x33,0x60 }, { 0x62,0x53,0x7f,0x45 }, 
-    { 0xb1,0x64,0x77,0xe0 }, { 0xbb,0x6b,0xae,0x84 }, 
-    { 0xfe,0x81,0xa0,0x1c }, { 0xf9,0x08,0x2b,0x94 }, 
-    { 0x70,0x48,0x68,0x58 }, { 0x8f,0x45,0xfd,0x19 }, 
-    { 0x94,0xde,0x6c,0x87 }, { 0x52,0x7b,0xf8,0xb7 }, 
-    { 0xab,0x73,0xd3,0x23 }, { 0x72,0x4b,0x02,0xe2 },
-    { 0xe3,0x1f,0x8f,0x57 }, { 0x66,0x55,0xab,0x2a }, 
-    { 0xb2,0xeb,0x28,0x07 }, { 0x2f,0xb5,0xc2,0x03 },
-    { 0x86,0xc5,0x7b,0x9a }, { 0xd3,0x37,0x08,0xa5 }, 
-    { 0x30,0x28,0x87,0xf2 }, { 0x23,0xbf,0xa5,0xb2 },
-    { 0x02,0x03,0x6a,0xba }, { 0xed,0x16,0x82,0x5c }, 
-    { 0x8a,0xcf,0x1c,0x2b }, { 0xa7,0x79,0xb4,0x92 },
-    { 0xf3,0x07,0xf2,0xf0 }, { 0x4e,0x69,0xe2,0xa1 }, 
-    { 0x65,0xda,0xf4,0xcd }, { 0x06,0x05,0xbe,0xd5 },
-    { 0xd1,0x34,0x62,0x1f }, { 0xc4,0xa6,0xfe,0x8a }, 
-    { 0x34,0x2e,0x53,0x9d }, { 0xa2,0xf3,0x55,0xa0 },
-    { 0x05,0x8a,0xe1,0x32 }, { 0xa4,0xf6,0xeb,0x75 }, 
-    { 0x0b,0x83,0xec,0x39 }, { 0x40,0x60,0xef,0xaa },
-    { 0x5e,0x71,0x9f,0x06 }, { 0xbd,0x6e,0x10,0x51 }, 
-    { 0x3e,0x21,0x8a,0xf9 }, { 0x96,0xdd,0x06,0x3d }, 
-    { 0xdd,0x3e,0x05,0xae }, { 0x4d,0xe6,0xbd,0x46 }, 
-    { 0x91,0x54,0x8d,0xb5 }, { 0x71,0xc4,0x5d,0x05 }, 
-    { 0x04,0x06,0xd4,0x6f }, { 0x60,0x50,0x15,0xff }, 
-    { 0x19,0x98,0xfb,0x24 }, { 0xd6,0xbd,0xe9,0x97 },
-    { 0x89,0x40,0x43,0xcc }, { 0x67,0xd9,0x9e,0x77 }, 
-    { 0xb0,0xe8,0x42,0xbd }, { 0x07,0x89,0x8b,0x88 },
-    { 0xe7,0x19,0x5b,0x38 }, { 0x79,0xc8,0xee,0xdb }, 
-    { 0xa1,0x7c,0x0a,0x47 }, { 0x7c,0x42,0x0f,0xe9 },
-    { 0xf8,0x84,0x1e,0xc9 }, { 0x00,0x00,0x00,0x00 }, 
-    { 0x09,0x80,0x86,0x83 }, { 0x32,0x2b,0xed,0x48 },
-    { 0x1e,0x11,0x70,0xac }, { 0x6c,0x5a,0x72,0x4e }, 
-    { 0xfd,0x0e,0xff,0xfb }, { 0x0f,0x85,0x38,0x56 },
-    { 0x3d,0xae,0xd5,0x1e }, { 0x36,0x2d,0x39,0x27 }, 
-    { 0x0a,0x0f,0xd9,0x64 }, { 0x68,0x5c,0xa6,0x21 },
-    { 0x9b,0x5b,0x54,0xd1 }, { 0x24,0x36,0x2e,0x3a }, 
-    { 0x0c,0x0a,0x67,0xb1 }, { 0x93,0x57,0xe7,0x0f },
-    { 0xb4,0xee,0x96,0xd2 }, { 0x1b,0x9b,0x91,0x9e }, 
-    { 0x80,0xc0,0xc5,0x4f }, { 0x61,0xdc,0x20,0xa2 },
-    { 0x5a,0x77,0x4b,0x69 }, { 0x1c,0x12,0x1a,0x16 }, 
-    { 0xe2,0x93,0xba,0x0a }, { 0xc0,0xa0,0x2a,0xe5 }, 
-    { 0x3c,0x22,0xe0,0x43 }, { 0x12,0x1b,0x17,0x1d }, 
-    { 0x0e,0x09,0x0d,0x0b }, { 0xf2,0x8b,0xc7,0xad }, 
-    { 0x2d,0xb6,0xa8,0xb9 }, { 0x14,0x1e,0xa9,0xc8 }, 
-    { 0x57,0xf1,0x19,0x85 }, { 0xaf,0x75,0x07,0x4c }, 
-    { 0xee,0x99,0xdd,0xbb }, { 0xa3,0x7f,0x60,0xfd }, 
-    { 0xf7,0x01,0x26,0x9f }, { 0x5c,0x72,0xf5,0xbc },
-    { 0x44,0x66,0x3b,0xc5 }, { 0x5b,0xfb,0x7e,0x34 }, 
-    { 0x8b,0x43,0x29,0x76 }, { 0xcb,0x23,0xc6,0xdc },
-    { 0xb6,0xed,0xfc,0x68 }, { 0xb8,0xe4,0xf1,0x63 }, 
-    { 0xd7,0x31,0xdc,0xca }, { 0x42,0x63,0x85,0x10 },
-    { 0x13,0x97,0x22,0x40 }, { 0x84,0xc6,0x11,0x20 }, 
-    { 0x85,0x4a,0x24,0x7d }, { 0xd2,0xbb,0x3d,0xf8 }, 
-    { 0xae,0xf9,0x32,0x11 }, { 0xc7,0x29,0xa1,0x6d }, 
-    { 0x1d,0x9e,0x2f,0x4b }, { 0xdc,0xb2,0x30,0xf3 },
-    { 0x0d,0x86,0x52,0xec }, { 0x77,0xc1,0xe3,0xd0 }, 
-    { 0x2b,0xb3,0x16,0x6c }, { 0xa9,0x70,0xb9,0x99 },
-    { 0x11,0x94,0x48,0xfa }, { 0x47,0xe9,0x64,0x22 }, 
-    { 0xa8,0xfc,0x8c,0xc4 }, { 0xa0,0xf0,0x3f,0x1a },
-    { 0x56,0x7d,0x2c,0xd8 }, { 0x22,0x33,0x90,0xef }, 
-    { 0x87,0x49,0x4e,0xc7 }, { 0xd9,0x38,0xd1,0xc1 }, 
-    { 0x8c,0xca,0xa2,0xfe }, { 0x98,0xd4,0x0b,0x36 }, 
-    { 0xa6,0xf5,0x81,0xcf }, { 0xa5,0x7a,0xde,0x28 }, 
-    { 0xda,0xb7,0x8e,0x26 }, { 0x3f,0xad,0xbf,0xa4 }, 
-    { 0x2c,0x3a,0x9d,0xe4 }, { 0x50,0x78,0x92,0x0d }, 
-    { 0x6a,0x5f,0xcc,0x9b }, { 0x54,0x7e,0x46,0x62 }, 
-    { 0xf6,0x8d,0x13,0xc2 }, { 0x90,0xd8,0xb8,0xe8 }, 
-    { 0x2e,0x39,0xf7,0x5e }, { 0x82,0xc3,0xaf,0xf5 }, 
-    { 0x9f,0x5d,0x80,0xbe }, { 0x69,0xd0,0x93,0x7c },
-    { 0x6f,0xd5,0x2d,0xa9 }, { 0xcf,0x25,0x12,0xb3 }, 
-    { 0xc8,0xac,0x99,0x3b }, { 0x10,0x18,0x7d,0xa7 },
-    { 0xe8,0x9c,0x63,0x6e }, { 0xdb,0x3b,0xbb,0x7b }, 
-    { 0xcd,0x26,0x78,0x09 }, { 0x6e,0x59,0x18,0xf4 },
-    { 0xec,0x9a,0xb7,0x01 }, { 0x83,0x4f,0x9a,0xa8 }, 
-    { 0xe6,0x95,0x6e,0x65 }, { 0xaa,0xff,0xe6,0x7e }, 
-    { 0x21,0xbc,0xcf,0x08 }, { 0xef,0x15,0xe8,0xe6 }, 
-    { 0xba,0xe7,0x9b,0xd9 }, { 0x4a,0x6f,0x36,0xce }, 
-    { 0xea,0x9f,0x09,0xd4 }, { 0x29,0xb0,0x7c,0xd6 }, 
-    { 0x31,0xa4,0xb2,0xaf }, { 0x2a,0x3f,0x23,0x31 }, 
-    { 0xc6,0xa5,0x94,0x30 }, { 0x35,0xa2,0x66,0xc0 }, 
-    { 0x74,0x4e,0xbc,0x37 }, { 0xfc,0x82,0xca,0xa6 }, 
-    { 0xe0,0x90,0xd0,0xb0 }, { 0x33,0xa7,0xd8,0x15 }, 
-    { 0xf1,0x04,0x98,0x4a }, { 0x41,0xec,0xda,0xf7 },
-    { 0x7f,0xcd,0x50,0x0e }, { 0x17,0x91,0xf6,0x2f }, 
-    { 0x76,0x4d,0xd6,0x8d }, { 0x43,0xef,0xb0,0x4d },
-    { 0xcc,0xaa,0x4d,0x54 }, { 0xe4,0x96,0x04,0xdf }, 
-    { 0x9e,0xd1,0xb5,0xe3 }, { 0x4c,0x6a,0x88,0x1b },
-    { 0xc1,0x2c,0x1f,0xb8 }, { 0x46,0x65,0x51,0x7f }, 
-    { 0x9d,0x5e,0xea,0x04 }, { 0x01,0x8c,0x35,0x5d },
-    { 0xfa,0x87,0x74,0x73 }, { 0xfb,0x0b,0x41,0x2e }, 
-    { 0xb3,0x67,0x1d,0x5a }, { 0x92,0xdb,0xd2,0x52 },
-    { 0xe9,0x10,0x56,0x33 }, { 0x6d,0xd6,0x47,0x13 }, 
-    { 0x9a,0xd7,0x61,0x8c }, { 0x37,0xa1,0x0c,0x7a },
-    { 0x59,0xf8,0x14,0x8e }, { 0xeb,0x13,0x3c,0x89 }, 
-    { 0xce,0xa9,0x27,0xee }, { 0xb7,0x61,0xc9,0x35 },
-    { 0xe1,0x1c,0xe5,0xed }, { 0x7a,0x47,0xb1,0x3c }, 
-    { 0x9c,0xd2,0xdf,0x59 }, { 0x55,0xf2,0x73,0x3f }, 
-    { 0x18,0x14,0xce,0x79 }, { 0x73,0xc7,0x37,0xbf }, 
-    { 0x53,0xf7,0xcd,0xea }, { 0x5f,0xfd,0xaa,0x5b },
-    { 0xdf,0x3d,0x6f,0x14 }, { 0x78,0x44,0xdb,0x86 }, 
-    { 0xca,0xaf,0xf3,0x81 }, { 0xb9,0x68,0xc4,0x3e }, 
-    { 0x38,0x24,0x34,0x2c }, { 0xc2,0xa3,0x40,0x5f }, 
-    { 0x16,0x1d,0xc3,0x72 }, { 0xbc,0xe2,0x25,0x0c }, 
-    { 0x28,0x3c,0x49,0x8b }, { 0xff,0x0d,0x95,0x41 }, 
-    { 0x39,0xa8,0x01,0x71 }, { 0x08,0x0c,0xb3,0xde }, 
-    { 0xd8,0xb4,0xe4,0x9c }, { 0x64,0x56,0xc1,0x90 }, 
-    { 0x7b,0xcb,0x84,0x61 }, { 0xd5,0x32,0xb6,0x70 },
-    { 0x48,0x6c,0x5c,0x74 }, { 0xd0,0xb8,0x57,0x42 }
-  };
-
-static const unsigned char T6[256][4] = 
-  {
-    { 0x50,0x51,0xf4,0xa7 }, { 0x53,0x7e,0x41,0x65 }, 
-    { 0xc3,0x1a,0x17,0xa4 }, { 0x96,0x3a,0x27,0x5e }, 
-    { 0xcb,0x3b,0xab,0x6b }, { 0xf1,0x1f,0x9d,0x45 },
-    { 0xab,0xac,0xfa,0x58 }, { 0x93,0x4b,0xe3,0x03 }, 
-    { 0x55,0x20,0x30,0xfa }, { 0xf6,0xad,0x76,0x6d },
-    { 0x91,0x88,0xcc,0x76 }, { 0x25,0xf5,0x02,0x4c }, 
-    { 0xfc,0x4f,0xe5,0xd7 }, { 0xd7,0xc5,0x2a,0xcb },
-    { 0x80,0x26,0x35,0x44 }, { 0x8f,0xb5,0x62,0xa3 }, 
-    { 0x49,0xde,0xb1,0x5a }, { 0x67,0x25,0xba,0x1b }, 
-    { 0x98,0x45,0xea,0x0e }, { 0xe1,0x5d,0xfe,0xc0 }, 
-    { 0x02,0xc3,0x2f,0x75 }, { 0x12,0x81,0x4c,0xf0 },
-    { 0xa3,0x8d,0x46,0x97 }, { 0xc6,0x6b,0xd3,0xf9 }, 
-    { 0xe7,0x03,0x8f,0x5f }, { 0x95,0x15,0x92,0x9c },
-    { 0xeb,0xbf,0x6d,0x7a }, { 0xda,0x95,0x52,0x59 }, 
-    { 0x2d,0xd4,0xbe,0x83 }, { 0xd3,0x58,0x74,0x21 },
-    { 0x29,0x49,0xe0,0x69 }, { 0x44,0x8e,0xc9,0xc8 }, 
-    { 0x6a,0x75,0xc2,0x89 }, { 0x78,0xf4,0x8e,0x79 },
-    { 0x6b,0x99,0x58,0x3e }, { 0xdd,0x27,0xb9,0x71 }, 
-    { 0xb6,0xbe,0xe1,0x4f }, { 0x17,0xf0,0x88,0xad },
-    { 0x66,0xc9,0x20,0xac }, { 0xb4,0x7d,0xce,0x3a }, 
-    { 0x18,0x63,0xdf,0x4a }, { 0x82,0xe5,0x1a,0x31 },
-    { 0x60,0x97,0x51,0x33 }, { 0x45,0x62,0x53,0x7f }, 
-    { 0xe0,0xb1,0x64,0x77 }, { 0x84,0xbb,0x6b,0xae },
-    { 0x1c,0xfe,0x81,0xa0 }, { 0x94,0xf9,0x08,0x2b }, 
-    { 0x58,0x70,0x48,0x68 }, { 0x19,0x8f,0x45,0xfd },
-    { 0x87,0x94,0xde,0x6c }, { 0xb7,0x52,0x7b,0xf8 }, 
-    { 0x23,0xab,0x73,0xd3 }, { 0xe2,0x72,0x4b,0x02 },
-    { 0x57,0xe3,0x1f,0x8f }, { 0x2a,0x66,0x55,0xab }, 
-    { 0x07,0xb2,0xeb,0x28 }, { 0x03,0x2f,0xb5,0xc2 },
-    { 0x9a,0x86,0xc5,0x7b }, { 0xa5,0xd3,0x37,0x08 }, 
-    { 0xf2,0x30,0x28,0x87 }, { 0xb2,0x23,0xbf,0xa5 },
-    { 0xba,0x02,0x03,0x6a }, { 0x5c,0xed,0x16,0x82 }, 
-    { 0x2b,0x8a,0xcf,0x1c }, { 0x92,0xa7,0x79,0xb4 },
-    { 0xf0,0xf3,0x07,0xf2 }, { 0xa1,0x4e,0x69,0xe2 }, 
-    { 0xcd,0x65,0xda,0xf4 }, { 0xd5,0x06,0x05,0xbe },
-    { 0x1f,0xd1,0x34,0x62 }, { 0x8a,0xc4,0xa6,0xfe }, 
-    { 0x9d,0x34,0x2e,0x53 }, { 0xa0,0xa2,0xf3,0x55 },
-    { 0x32,0x05,0x8a,0xe1 }, { 0x75,0xa4,0xf6,0xeb }, 
-    { 0x39,0x0b,0x83,0xec }, { 0xaa,0x40,0x60,0xef },
-    { 0x06,0x5e,0x71,0x9f }, { 0x51,0xbd,0x6e,0x10 }, 
-    { 0xf9,0x3e,0x21,0x8a }, { 0x3d,0x96,0xdd,0x06 },
-    { 0xae,0xdd,0x3e,0x05 }, { 0x46,0x4d,0xe6,0xbd }, 
-    { 0xb5,0x91,0x54,0x8d }, { 0x05,0x71,0xc4,0x5d },
-    { 0x6f,0x04,0x06,0xd4 }, { 0xff,0x60,0x50,0x15 }, 
-    { 0x24,0x19,0x98,0xfb }, { 0x97,0xd6,0xbd,0xe9 },
-    { 0xcc,0x89,0x40,0x43 }, { 0x77,0x67,0xd9,0x9e }, 
-    { 0xbd,0xb0,0xe8,0x42 }, { 0x88,0x07,0x89,0x8b },
-    { 0x38,0xe7,0x19,0x5b }, { 0xdb,0x79,0xc8,0xee }, 
-    { 0x47,0xa1,0x7c,0x0a }, { 0xe9,0x7c,0x42,0x0f },
-    { 0xc9,0xf8,0x84,0x1e }, { 0x00,0x00,0x00,0x00 }, 
-    { 0x83,0x09,0x80,0x86 }, { 0x48,0x32,0x2b,0xed },
-    { 0xac,0x1e,0x11,0x70 }, { 0x4e,0x6c,0x5a,0x72 }, 
-    { 0xfb,0xfd,0x0e,0xff }, { 0x56,0x0f,0x85,0x38 },
-    { 0x1e,0x3d,0xae,0xd5 }, { 0x27,0x36,0x2d,0x39 }, 
-    { 0x64,0x0a,0x0f,0xd9 }, { 0x21,0x68,0x5c,0xa6 },
-    { 0xd1,0x9b,0x5b,0x54 }, { 0x3a,0x24,0x36,0x2e }, 
-    { 0xb1,0x0c,0x0a,0x67 }, { 0x0f,0x93,0x57,0xe7 },
-    { 0xd2,0xb4,0xee,0x96 }, { 0x9e,0x1b,0x9b,0x91 }, 
-    { 0x4f,0x80,0xc0,0xc5 }, { 0xa2,0x61,0xdc,0x20 }, 
-    { 0x69,0x5a,0x77,0x4b }, { 0x16,0x1c,0x12,0x1a }, 
-    { 0x0a,0xe2,0x93,0xba }, { 0xe5,0xc0,0xa0,0x2a },
-    { 0x43,0x3c,0x22,0xe0 }, { 0x1d,0x12,0x1b,0x17 }, 
-    { 0x0b,0x0e,0x09,0x0d }, { 0xad,0xf2,0x8b,0xc7 },
-    { 0xb9,0x2d,0xb6,0xa8 }, { 0xc8,0x14,0x1e,0xa9 }, 
-    { 0x85,0x57,0xf1,0x19 }, { 0x4c,0xaf,0x75,0x07 },
-    { 0xbb,0xee,0x99,0xdd }, { 0xfd,0xa3,0x7f,0x60 }, 
-    { 0x9f,0xf7,0x01,0x26 }, { 0xbc,0x5c,0x72,0xf5 },
-    { 0xc5,0x44,0x66,0x3b }, { 0x34,0x5b,0xfb,0x7e }, 
-    { 0x76,0x8b,0x43,0x29 }, { 0xdc,0xcb,0x23,0xc6 },
-    { 0x68,0xb6,0xed,0xfc }, { 0x63,0xb8,0xe4,0xf1 }, 
-    { 0xca,0xd7,0x31,0xdc }, { 0x10,0x42,0x63,0x85 },
-    { 0x40,0x13,0x97,0x22 }, { 0x20,0x84,0xc6,0x11 }, 
-    { 0x7d,0x85,0x4a,0x24 }, { 0xf8,0xd2,0xbb,0x3d },
-    { 0x11,0xae,0xf9,0x32 }, { 0x6d,0xc7,0x29,0xa1 }, 
-    { 0x4b,0x1d,0x9e,0x2f }, { 0xf3,0xdc,0xb2,0x30 },
-    { 0xec,0x0d,0x86,0x52 }, { 0xd0,0x77,0xc1,0xe3 }, 
-    { 0x6c,0x2b,0xb3,0x16 }, { 0x99,0xa9,0x70,0xb9 }, 
-    { 0xfa,0x11,0x94,0x48 }, { 0x22,0x47,0xe9,0x64 }, 
-    { 0xc4,0xa8,0xfc,0x8c }, { 0x1a,0xa0,0xf0,0x3f }, 
-    { 0xd8,0x56,0x7d,0x2c }, { 0xef,0x22,0x33,0x90 }, 
-    { 0xc7,0x87,0x49,0x4e }, { 0xc1,0xd9,0x38,0xd1 },
-    { 0xfe,0x8c,0xca,0xa2 }, { 0x36,0x98,0xd4,0x0b }, 
-    { 0xcf,0xa6,0xf5,0x81 }, { 0x28,0xa5,0x7a,0xde }, 
-    { 0x26,0xda,0xb7,0x8e }, { 0xa4,0x3f,0xad,0xbf }, 
-    { 0xe4,0x2c,0x3a,0x9d }, { 0x0d,0x50,0x78,0x92 }, 
-    { 0x9b,0x6a,0x5f,0xcc }, { 0x62,0x54,0x7e,0x46 }, 
-    { 0xc2,0xf6,0x8d,0x13 }, { 0xe8,0x90,0xd8,0xb8 }, 
-    { 0x5e,0x2e,0x39,0xf7 }, { 0xf5,0x82,0xc3,0xaf }, 
-    { 0xbe,0x9f,0x5d,0x80 }, { 0x7c,0x69,0xd0,0x93 },
-    { 0xa9,0x6f,0xd5,0x2d }, { 0xb3,0xcf,0x25,0x12 }, 
-    { 0x3b,0xc8,0xac,0x99 }, { 0xa7,0x10,0x18,0x7d }, 
-    { 0x6e,0xe8,0x9c,0x63 }, { 0x7b,0xdb,0x3b,0xbb }, 
-    { 0x09,0xcd,0x26,0x78 }, { 0xf4,0x6e,0x59,0x18 },
-    { 0x01,0xec,0x9a,0xb7 }, { 0xa8,0x83,0x4f,0x9a }, 
-    { 0x65,0xe6,0x95,0x6e }, { 0x7e,0xaa,0xff,0xe6 }, 
-    { 0x08,0x21,0xbc,0xcf }, { 0xe6,0xef,0x15,0xe8 }, 
-    { 0xd9,0xba,0xe7,0x9b }, { 0xce,0x4a,0x6f,0x36 },
-    { 0xd4,0xea,0x9f,0x09 }, { 0xd6,0x29,0xb0,0x7c }, 
-    { 0xaf,0x31,0xa4,0xb2 }, { 0x31,0x2a,0x3f,0x23 },
-    { 0x30,0xc6,0xa5,0x94 }, { 0xc0,0x35,0xa2,0x66 }, 
-    { 0x37,0x74,0x4e,0xbc }, { 0xa6,0xfc,0x82,0xca }, 
-    { 0xb0,0xe0,0x90,0xd0 }, { 0x15,0x33,0xa7,0xd8 }, 
-    { 0x4a,0xf1,0x04,0x98 }, { 0xf7,0x41,0xec,0xda },
-    { 0x0e,0x7f,0xcd,0x50 }, { 0x2f,0x17,0x91,0xf6 }, 
-    { 0x8d,0x76,0x4d,0xd6 }, { 0x4d,0x43,0xef,0xb0 },
-    { 0x54,0xcc,0xaa,0x4d }, { 0xdf,0xe4,0x96,0x04 }, 
-    { 0xe3,0x9e,0xd1,0xb5 }, { 0x1b,0x4c,0x6a,0x88 },
-    { 0xb8,0xc1,0x2c,0x1f }, { 0x7f,0x46,0x65,0x51 }, 
-    { 0x04,0x9d,0x5e,0xea }, { 0x5d,0x01,0x8c,0x35 },
-    { 0x73,0xfa,0x87,0x74 }, { 0x2e,0xfb,0x0b,0x41 }, 
-    { 0x5a,0xb3,0x67,0x1d }, { 0x52,0x92,0xdb,0xd2 },
-    { 0x33,0xe9,0x10,0x56 }, { 0x13,0x6d,0xd6,0x47 }, 
-    { 0x8c,0x9a,0xd7,0x61 }, { 0x7a,0x37,0xa1,0x0c }, 
-    { 0x8e,0x59,0xf8,0x14 }, { 0x89,0xeb,0x13,0x3c }, 
-    { 0xee,0xce,0xa9,0x27 }, { 0x35,0xb7,0x61,0xc9 },
-    { 0xed,0xe1,0x1c,0xe5 }, { 0x3c,0x7a,0x47,0xb1 }, 
-    { 0x59,0x9c,0xd2,0xdf }, { 0x3f,0x55,0xf2,0x73 },
-    { 0x79,0x18,0x14,0xce }, { 0xbf,0x73,0xc7,0x37 }, 
-    { 0xea,0x53,0xf7,0xcd }, { 0x5b,0x5f,0xfd,0xaa },
-    { 0x14,0xdf,0x3d,0x6f }, { 0x86,0x78,0x44,0xdb }, 
-    { 0x81,0xca,0xaf,0xf3 }, { 0x3e,0xb9,0x68,0xc4 },
-    { 0x2c,0x38,0x24,0x34 }, { 0x5f,0xc2,0xa3,0x40 }, 
-    { 0x72,0x16,0x1d,0xc3 }, { 0x0c,0xbc,0xe2,0x25 },
-    { 0x8b,0x28,0x3c,0x49 }, { 0x41,0xff,0x0d,0x95 }, 
-    { 0x71,0x39,0xa8,0x01 }, { 0xde,0x08,0x0c,0xb3 },
-    { 0x9c,0xd8,0xb4,0xe4 }, { 0x90,0x64,0x56,0xc1 }, 
-    { 0x61,0x7b,0xcb,0x84 }, { 0x70,0xd5,0x32,0xb6 },
-    { 0x74,0x48,0x6c,0x5c }, { 0x42,0xd0,0xb8,0x57 }
-  };
-
-static const unsigned char T7[256][4] = 
-  {
-    { 0xa7,0x50,0x51,0xf4 }, { 0x65,0x53,0x7e,0x41 },
-    { 0xa4,0xc3,0x1a,0x17 }, { 0x5e,0x96,0x3a,0x27 }, 
-    { 0x6b,0xcb,0x3b,0xab }, { 0x45,0xf1,0x1f,0x9d },
-    { 0x58,0xab,0xac,0xfa }, { 0x03,0x93,0x4b,0xe3 }, 
-    { 0xfa,0x55,0x20,0x30 }, { 0x6d,0xf6,0xad,0x76 },
-    { 0x76,0x91,0x88,0xcc }, { 0x4c,0x25,0xf5,0x02 }, 
-    { 0xd7,0xfc,0x4f,0xe5 }, { 0xcb,0xd7,0xc5,0x2a },
-    { 0x44,0x80,0x26,0x35 }, { 0xa3,0x8f,0xb5,0x62 }, 
-    { 0x5a,0x49,0xde,0xb1 }, { 0x1b,0x67,0x25,0xba }, 
-    { 0x0e,0x98,0x45,0xea }, { 0xc0,0xe1,0x5d,0xfe }, 
-    { 0x75,0x02,0xc3,0x2f }, { 0xf0,0x12,0x81,0x4c },
-    { 0x97,0xa3,0x8d,0x46 }, { 0xf9,0xc6,0x6b,0xd3 }, 
-    { 0x5f,0xe7,0x03,0x8f }, { 0x9c,0x95,0x15,0x92 },
-    { 0x7a,0xeb,0xbf,0x6d }, { 0x59,0xda,0x95,0x52 }, 
-    { 0x83,0x2d,0xd4,0xbe }, { 0x21,0xd3,0x58,0x74 },
-    { 0x69,0x29,0x49,0xe0 }, { 0xc8,0x44,0x8e,0xc9 }, 
-    { 0x89,0x6a,0x75,0xc2 }, { 0x79,0x78,0xf4,0x8e }, 
-    { 0x3e,0x6b,0x99,0x58 }, { 0x71,0xdd,0x27,0xb9 }, 
-    { 0x4f,0xb6,0xbe,0xe1 }, { 0xad,0x17,0xf0,0x88 },
-    { 0xac,0x66,0xc9,0x20 }, { 0x3a,0xb4,0x7d,0xce }, 
-    { 0x4a,0x18,0x63,0xdf }, { 0x31,0x82,0xe5,0x1a },
-    { 0x33,0x60,0x97,0x51 }, { 0x7f,0x45,0x62,0x53 }, 
-    { 0x77,0xe0,0xb1,0x64 }, { 0xae,0x84,0xbb,0x6b },
-    { 0xa0,0x1c,0xfe,0x81 }, { 0x2b,0x94,0xf9,0x08 }, 
-    { 0x68,0x58,0x70,0x48 }, { 0xfd,0x19,0x8f,0x45 },
-    { 0x6c,0x87,0x94,0xde }, { 0xf8,0xb7,0x52,0x7b }, 
-    { 0xd3,0x23,0xab,0x73 }, { 0x02,0xe2,0x72,0x4b },
-    { 0x8f,0x57,0xe3,0x1f }, { 0xab,0x2a,0x66,0x55 }, 
-    { 0x28,0x07,0xb2,0xeb }, { 0xc2,0x03,0x2f,0xb5 },
-    { 0x7b,0x9a,0x86,0xc5 }, { 0x08,0xa5,0xd3,0x37 }, 
-    { 0x87,0xf2,0x30,0x28 }, { 0xa5,0xb2,0x23,0xbf },
-    { 0x6a,0xba,0x02,0x03 }, { 0x82,0x5c,0xed,0x16 }, 
-    { 0x1c,0x2b,0x8a,0xcf }, { 0xb4,0x92,0xa7,0x79 }, 
-    { 0xf2,0xf0,0xf3,0x07 }, { 0xe2,0xa1,0x4e,0x69 }, 
-    { 0xf4,0xcd,0x65,0xda }, { 0xbe,0xd5,0x06,0x05 },
-    { 0x62,0x1f,0xd1,0x34 }, { 0xfe,0x8a,0xc4,0xa6 }, 
-    { 0x53,0x9d,0x34,0x2e }, { 0x55,0xa0,0xa2,0xf3 },
-    { 0xe1,0x32,0x05,0x8a }, { 0xeb,0x75,0xa4,0xf6 }, 
-    { 0xec,0x39,0x0b,0x83 }, { 0xef,0xaa,0x40,0x60 },
-    { 0x9f,0x06,0x5e,0x71 }, { 0x10,0x51,0xbd,0x6e }, 
-    { 0x8a,0xf9,0x3e,0x21 }, { 0x06,0x3d,0x96,0xdd },
-    { 0x05,0xae,0xdd,0x3e }, { 0xbd,0x46,0x4d,0xe6 }, 
-    { 0x8d,0xb5,0x91,0x54 }, { 0x5d,0x05,0x71,0xc4 },
-    { 0xd4,0x6f,0x04,0x06 }, { 0x15,0xff,0x60,0x50 }, 
-    { 0xfb,0x24,0x19,0x98 }, { 0xe9,0x97,0xd6,0xbd }, 
-    { 0x43,0xcc,0x89,0x40 }, { 0x9e,0x77,0x67,0xd9 }, 
-    { 0x42,0xbd,0xb0,0xe8 }, { 0x8b,0x88,0x07,0x89 },
-    { 0x5b,0x38,0xe7,0x19 }, { 0xee,0xdb,0x79,0xc8 }, 
-    { 0x0a,0x47,0xa1,0x7c }, { 0x0f,0xe9,0x7c,0x42 },
-    { 0x1e,0xc9,0xf8,0x84 }, { 0x00,0x00,0x00,0x00 }, 
-    { 0x86,0x83,0x09,0x80 }, { 0xed,0x48,0x32,0x2b },
-    { 0x70,0xac,0x1e,0x11 }, { 0x72,0x4e,0x6c,0x5a }, 
-    { 0xff,0xfb,0xfd,0x0e }, { 0x38,0x56,0x0f,0x85 },
-    { 0xd5,0x1e,0x3d,0xae }, { 0x39,0x27,0x36,0x2d }, 
-    { 0xd9,0x64,0x0a,0x0f }, { 0xa6,0x21,0x68,0x5c },
-    { 0x54,0xd1,0x9b,0x5b }, { 0x2e,0x3a,0x24,0x36 }, 
-    { 0x67,0xb1,0x0c,0x0a }, { 0xe7,0x0f,0x93,0x57 },
-    { 0x96,0xd2,0xb4,0xee }, { 0x91,0x9e,0x1b,0x9b }, 
-    { 0xc5,0x4f,0x80,0xc0 }, { 0x20,0xa2,0x61,0xdc },
-    { 0x4b,0x69,0x5a,0x77 }, { 0x1a,0x16,0x1c,0x12 }, 
-    { 0xba,0x0a,0xe2,0x93 }, { 0x2a,0xe5,0xc0,0xa0 },
-    { 0xe0,0x43,0x3c,0x22 }, { 0x17,0x1d,0x12,0x1b }, 
-    { 0x0d,0x0b,0x0e,0x09 }, { 0xc7,0xad,0xf2,0x8b },
-    { 0xa8,0xb9,0x2d,0xb6 }, { 0xa9,0xc8,0x14,0x1e }, 
-    { 0x19,0x85,0x57,0xf1 }, { 0x07,0x4c,0xaf,0x75 },
-    { 0xdd,0xbb,0xee,0x99 }, { 0x60,0xfd,0xa3,0x7f }, 
-    { 0x26,0x9f,0xf7,0x01 }, { 0xf5,0xbc,0x5c,0x72 },
-    { 0x3b,0xc5,0x44,0x66 }, { 0x7e,0x34,0x5b,0xfb }, 
-    { 0x29,0x76,0x8b,0x43 }, { 0xc6,0xdc,0xcb,0x23 },
-    { 0xfc,0x68,0xb6,0xed }, { 0xf1,0x63,0xb8,0xe4 }, 
-    { 0xdc,0xca,0xd7,0x31 }, { 0x85,0x10,0x42,0x63 },
-    { 0x22,0x40,0x13,0x97 }, { 0x11,0x20,0x84,0xc6 }, 
-    { 0x24,0x7d,0x85,0x4a }, { 0x3d,0xf8,0xd2,0xbb },
-    { 0x32,0x11,0xae,0xf9 }, { 0xa1,0x6d,0xc7,0x29 }, 
-    { 0x2f,0x4b,0x1d,0x9e }, { 0x30,0xf3,0xdc,0xb2 },
-    { 0x52,0xec,0x0d,0x86 }, { 0xe3,0xd0,0x77,0xc1 }, 
-    { 0x16,0x6c,0x2b,0xb3 }, { 0xb9,0x99,0xa9,0x70 },
-    { 0x48,0xfa,0x11,0x94 }, { 0x64,0x22,0x47,0xe9 }, 
-    { 0x8c,0xc4,0xa8,0xfc }, { 0x3f,0x1a,0xa0,0xf0 },
-    { 0x2c,0xd8,0x56,0x7d }, { 0x90,0xef,0x22,0x33 }, 
-    { 0x4e,0xc7,0x87,0x49 }, { 0xd1,0xc1,0xd9,0x38 },
-    { 0xa2,0xfe,0x8c,0xca }, { 0x0b,0x36,0x98,0xd4 }, 
-    { 0x81,0xcf,0xa6,0xf5 }, { 0xde,0x28,0xa5,0x7a },
-    { 0x8e,0x26,0xda,0xb7 }, { 0xbf,0xa4,0x3f,0xad }, 
-    { 0x9d,0xe4,0x2c,0x3a }, { 0x92,0x0d,0x50,0x78 },
-    { 0xcc,0x9b,0x6a,0x5f }, { 0x46,0x62,0x54,0x7e }, 
-    { 0x13,0xc2,0xf6,0x8d }, { 0xb8,0xe8,0x90,0xd8 },
-    { 0xf7,0x5e,0x2e,0x39 }, { 0xaf,0xf5,0x82,0xc3 }, 
-    { 0x80,0xbe,0x9f,0x5d }, { 0x93,0x7c,0x69,0xd0 },
-    { 0x2d,0xa9,0x6f,0xd5 }, { 0x12,0xb3,0xcf,0x25 }, 
-    { 0x99,0x3b,0xc8,0xac }, { 0x7d,0xa7,0x10,0x18 },
-    { 0x63,0x6e,0xe8,0x9c }, { 0xbb,0x7b,0xdb,0x3b }, 
-    { 0x78,0x09,0xcd,0x26 }, { 0x18,0xf4,0x6e,0x59 }, 
-    { 0xb7,0x01,0xec,0x9a }, { 0x9a,0xa8,0x83,0x4f }, 
-    { 0x6e,0x65,0xe6,0x95 }, { 0xe6,0x7e,0xaa,0xff },
-    { 0xcf,0x08,0x21,0xbc }, { 0xe8,0xe6,0xef,0x15 }, 
-    { 0x9b,0xd9,0xba,0xe7 }, { 0x36,0xce,0x4a,0x6f },
-    { 0x09,0xd4,0xea,0x9f }, { 0x7c,0xd6,0x29,0xb0 }, 
-    { 0xb2,0xaf,0x31,0xa4 }, { 0x23,0x31,0x2a,0x3f },
-    { 0x94,0x30,0xc6,0xa5 }, { 0x66,0xc0,0x35,0xa2 }, 
-    { 0xbc,0x37,0x74,0x4e }, { 0xca,0xa6,0xfc,0x82 },
-    { 0xd0,0xb0,0xe0,0x90 }, { 0xd8,0x15,0x33,0xa7 }, 
-    { 0x98,0x4a,0xf1,0x04 }, { 0xda,0xf7,0x41,0xec },
-    { 0x50,0x0e,0x7f,0xcd }, { 0xf6,0x2f,0x17,0x91 }, 
-    { 0xd6,0x8d,0x76,0x4d }, { 0xb0,0x4d,0x43,0xef }, 
-    { 0x4d,0x54,0xcc,0xaa }, { 0x04,0xdf,0xe4,0x96 }, 
-    { 0xb5,0xe3,0x9e,0xd1 }, { 0x88,0x1b,0x4c,0x6a },
-    { 0x1f,0xb8,0xc1,0x2c }, { 0x51,0x7f,0x46,0x65 }, 
-    { 0xea,0x04,0x9d,0x5e }, { 0x35,0x5d,0x01,0x8c },
-    { 0x74,0x73,0xfa,0x87 }, { 0x41,0x2e,0xfb,0x0b }, 
-    { 0x1d,0x5a,0xb3,0x67 }, { 0xd2,0x52,0x92,0xdb },
-    { 0x56,0x33,0xe9,0x10 }, { 0x47,0x13,0x6d,0xd6 }, 
-    { 0x61,0x8c,0x9a,0xd7 }, { 0x0c,0x7a,0x37,0xa1 },
-    { 0x14,0x8e,0x59,0xf8 }, { 0x3c,0x89,0xeb,0x13 }, 
-    { 0x27,0xee,0xce,0xa9 }, { 0xc9,0x35,0xb7,0x61 },
-    { 0xe5,0xed,0xe1,0x1c }, { 0xb1,0x3c,0x7a,0x47 }, 
-    { 0xdf,0x59,0x9c,0xd2 }, { 0x73,0x3f,0x55,0xf2 },
-    { 0xce,0x79,0x18,0x14 }, { 0x37,0xbf,0x73,0xc7 }, 
-    { 0xcd,0xea,0x53,0xf7 }, { 0xaa,0x5b,0x5f,0xfd },
-    { 0x6f,0x14,0xdf,0x3d }, { 0xdb,0x86,0x78,0x44 }, 
-    { 0xf3,0x81,0xca,0xaf }, { 0xc4,0x3e,0xb9,0x68 },
-    { 0x34,0x2c,0x38,0x24 }, { 0x40,0x5f,0xc2,0xa3 }, 
-    { 0xc3,0x72,0x16,0x1d }, { 0x25,0x0c,0xbc,0xe2 },
-    { 0x49,0x8b,0x28,0x3c }, { 0x95,0x41,0xff,0x0d }, 
-    { 0x01,0x71,0x39,0xa8 }, { 0xb3,0xde,0x08,0x0c },
-    { 0xe4,0x9c,0xd8,0xb4 }, { 0xc1,0x90,0x64,0x56 }, 
-    { 0x84,0x61,0x7b,0xcb }, { 0xb6,0x70,0xd5,0x32 },
-    { 0x5c,0x74,0x48,0x6c }, { 0x57,0x42,0xd0,0xb8 }
-  };
-
-static const unsigned char T8[256][4] = 
-  {
-    { 0xf4,0xa7,0x50,0x51 }, { 0x41,0x65,0x53,0x7e },
-    { 0x17,0xa4,0xc3,0x1a }, { 0x27,0x5e,0x96,0x3a }, 
-    { 0xab,0x6b,0xcb,0x3b }, { 0x9d,0x45,0xf1,0x1f },
-    { 0xfa,0x58,0xab,0xac }, { 0xe3,0x03,0x93,0x4b }, 
-    { 0x30,0xfa,0x55,0x20 }, { 0x76,0x6d,0xf6,0xad },
-    { 0xcc,0x76,0x91,0x88 }, { 0x02,0x4c,0x25,0xf5 }, 
-    { 0xe5,0xd7,0xfc,0x4f }, { 0x2a,0xcb,0xd7,0xc5 },
-    { 0x35,0x44,0x80,0x26 }, { 0x62,0xa3,0x8f,0xb5 }, 
-    { 0xb1,0x5a,0x49,0xde }, { 0xba,0x1b,0x67,0x25 },
-    { 0xea,0x0e,0x98,0x45 }, { 0xfe,0xc0,0xe1,0x5d }, 
-    { 0x2f,0x75,0x02,0xc3 }, { 0x4c,0xf0,0x12,0x81 },
-    { 0x46,0x97,0xa3,0x8d }, { 0xd3,0xf9,0xc6,0x6b }, 
-    { 0x8f,0x5f,0xe7,0x03 }, { 0x92,0x9c,0x95,0x15 },
-    { 0x6d,0x7a,0xeb,0xbf }, { 0x52,0x59,0xda,0x95 }, 
-    { 0xbe,0x83,0x2d,0xd4 }, { 0x74,0x21,0xd3,0x58 },
-    { 0xe0,0x69,0x29,0x49 }, { 0xc9,0xc8,0x44,0x8e }, 
-    { 0xc2,0x89,0x6a,0x75 }, { 0x8e,0x79,0x78,0xf4 },
-    { 0x58,0x3e,0x6b,0x99 }, { 0xb9,0x71,0xdd,0x27 }, 
-    { 0xe1,0x4f,0xb6,0xbe }, { 0x88,0xad,0x17,0xf0 },
-    { 0x20,0xac,0x66,0xc9 }, { 0xce,0x3a,0xb4,0x7d }, 
-    { 0xdf,0x4a,0x18,0x63 }, { 0x1a,0x31,0x82,0xe5 },
-    { 0x51,0x33,0x60,0x97 }, { 0x53,0x7f,0x45,0x62 }, 
-    { 0x64,0x77,0xe0,0xb1 }, { 0x6b,0xae,0x84,0xbb },
-    { 0x81,0xa0,0x1c,0xfe }, { 0x08,0x2b,0x94,0xf9 }, 
-    { 0x48,0x68,0x58,0x70 }, { 0x45,0xfd,0x19,0x8f },
-    { 0xde,0x6c,0x87,0x94 }, { 0x7b,0xf8,0xb7,0x52 }, 
-    { 0x73,0xd3,0x23,0xab }, { 0x4b,0x02,0xe2,0x72 },
-    { 0x1f,0x8f,0x57,0xe3 }, { 0x55,0xab,0x2a,0x66 }, 
-    { 0xeb,0x28,0x07,0xb2 }, { 0xb5,0xc2,0x03,0x2f },
-    { 0xc5,0x7b,0x9a,0x86 }, { 0x37,0x08,0xa5,0xd3 }, 
-    { 0x28,0x87,0xf2,0x30 }, { 0xbf,0xa5,0xb2,0x23 },
-    { 0x03,0x6a,0xba,0x02 }, { 0x16,0x82,0x5c,0xed }, 
-    { 0xcf,0x1c,0x2b,0x8a }, { 0x79,0xb4,0x92,0xa7 },
-    { 0x07,0xf2,0xf0,0xf3 }, { 0x69,0xe2,0xa1,0x4e }, 
-    { 0xda,0xf4,0xcd,0x65 }, { 0x05,0xbe,0xd5,0x06 },
-    { 0x34,0x62,0x1f,0xd1 }, { 0xa6,0xfe,0x8a,0xc4 }, 
-    { 0x2e,0x53,0x9d,0x34 }, { 0xf3,0x55,0xa0,0xa2 },
-    { 0x8a,0xe1,0x32,0x05 }, { 0xf6,0xeb,0x75,0xa4 }, 
-    { 0x83,0xec,0x39,0x0b }, { 0x60,0xef,0xaa,0x40 },
-    { 0x71,0x9f,0x06,0x5e }, { 0x6e,0x10,0x51,0xbd }, 
-    { 0x21,0x8a,0xf9,0x3e }, { 0xdd,0x06,0x3d,0x96 },
-    { 0x3e,0x05,0xae,0xdd }, { 0xe6,0xbd,0x46,0x4d }, 
-    { 0x54,0x8d,0xb5,0x91 }, { 0xc4,0x5d,0x05,0x71 },
-    { 0x06,0xd4,0x6f,0x04 }, { 0x50,0x15,0xff,0x60 }, 
-    { 0x98,0xfb,0x24,0x19 }, { 0xbd,0xe9,0x97,0xd6 },
-    { 0x40,0x43,0xcc,0x89 }, { 0xd9,0x9e,0x77,0x67 }, 
-    { 0xe8,0x42,0xbd,0xb0 }, { 0x89,0x8b,0x88,0x07 },
-    { 0x19,0x5b,0x38,0xe7 }, { 0xc8,0xee,0xdb,0x79 }, 
-    { 0x7c,0x0a,0x47,0xa1 }, { 0x42,0x0f,0xe9,0x7c },
-    { 0x84,0x1e,0xc9,0xf8 }, { 0x00,0x00,0x00,0x00 }, 
-    { 0x80,0x86,0x83,0x09 }, { 0x2b,0xed,0x48,0x32 },
-    { 0x11,0x70,0xac,0x1e }, { 0x5a,0x72,0x4e,0x6c }, 
-    { 0x0e,0xff,0xfb,0xfd }, { 0x85,0x38,0x56,0x0f }, 
-    { 0xae,0xd5,0x1e,0x3d }, { 0x2d,0x39,0x27,0x36 }, 
-    { 0x0f,0xd9,0x64,0x0a }, { 0x5c,0xa6,0x21,0x68 },
-    { 0x5b,0x54,0xd1,0x9b }, { 0x36,0x2e,0x3a,0x24 }, 
-    { 0x0a,0x67,0xb1,0x0c }, { 0x57,0xe7,0x0f,0x93 },
-    { 0xee,0x96,0xd2,0xb4 }, { 0x9b,0x91,0x9e,0x1b }, 
-    { 0xc0,0xc5,0x4f,0x80 }, { 0xdc,0x20,0xa2,0x61 },
-    { 0x77,0x4b,0x69,0x5a }, { 0x12,0x1a,0x16,0x1c }, 
-    { 0x93,0xba,0x0a,0xe2 }, { 0xa0,0x2a,0xe5,0xc0 },
-    { 0x22,0xe0,0x43,0x3c }, { 0x1b,0x17,0x1d,0x12 }, 
-    { 0x09,0x0d,0x0b,0x0e }, { 0x8b,0xc7,0xad,0xf2 },
-    { 0xb6,0xa8,0xb9,0x2d }, { 0x1e,0xa9,0xc8,0x14 }, 
-    { 0xf1,0x19,0x85,0x57 }, { 0x75,0x07,0x4c,0xaf },
-    { 0x99,0xdd,0xbb,0xee }, { 0x7f,0x60,0xfd,0xa3 }, 
-    { 0x01,0x26,0x9f,0xf7 }, { 0x72,0xf5,0xbc,0x5c },
-    { 0x66,0x3b,0xc5,0x44 }, { 0xfb,0x7e,0x34,0x5b }, 
-    { 0x43,0x29,0x76,0x8b }, { 0x23,0xc6,0xdc,0xcb },
-    { 0xed,0xfc,0x68,0xb6 }, { 0xe4,0xf1,0x63,0xb8 }, 
-    { 0x31,0xdc,0xca,0xd7 }, { 0x63,0x85,0x10,0x42 },
-    { 0x97,0x22,0x40,0x13 }, { 0xc6,0x11,0x20,0x84 }, 
-    { 0x4a,0x24,0x7d,0x85 }, { 0xbb,0x3d,0xf8,0xd2 }, 
-    { 0xf9,0x32,0x11,0xae }, { 0x29,0xa1,0x6d,0xc7 }, 
-    { 0x9e,0x2f,0x4b,0x1d }, { 0xb2,0x30,0xf3,0xdc },
-    { 0x86,0x52,0xec,0x0d }, { 0xc1,0xe3,0xd0,0x77 }, 
-    { 0xb3,0x16,0x6c,0x2b }, { 0x70,0xb9,0x99,0xa9 },
-    { 0x94,0x48,0xfa,0x11 }, { 0xe9,0x64,0x22,0x47 }, 
-    { 0xfc,0x8c,0xc4,0xa8 }, { 0xf0,0x3f,0x1a,0xa0 },
-    { 0x7d,0x2c,0xd8,0x56 }, { 0x33,0x90,0xef,0x22 }, 
-    { 0x49,0x4e,0xc7,0x87 }, { 0x38,0xd1,0xc1,0xd9 },
-    { 0xca,0xa2,0xfe,0x8c }, { 0xd4,0x0b,0x36,0x98 }, 
-    { 0xf5,0x81,0xcf,0xa6 }, { 0x7a,0xde,0x28,0xa5 },
-    { 0xb7,0x8e,0x26,0xda }, { 0xad,0xbf,0xa4,0x3f }, 
-    { 0x3a,0x9d,0xe4,0x2c }, { 0x78,0x92,0x0d,0x50 },
-    { 0x5f,0xcc,0x9b,0x6a }, { 0x7e,0x46,0x62,0x54 }, 
-    { 0x8d,0x13,0xc2,0xf6 }, { 0xd8,0xb8,0xe8,0x90 },
-    { 0x39,0xf7,0x5e,0x2e }, { 0xc3,0xaf,0xf5,0x82 }, 
-    { 0x5d,0x80,0xbe,0x9f }, { 0xd0,0x93,0x7c,0x69 },
-    { 0xd5,0x2d,0xa9,0x6f }, { 0x25,0x12,0xb3,0xcf }, 
-    { 0xac,0x99,0x3b,0xc8 }, { 0x18,0x7d,0xa7,0x10 },
-    { 0x9c,0x63,0x6e,0xe8 }, { 0x3b,0xbb,0x7b,0xdb }, 
-    { 0x26,0x78,0x09,0xcd }, { 0x59,0x18,0xf4,0x6e },
-    { 0x9a,0xb7,0x01,0xec }, { 0x4f,0x9a,0xa8,0x83 }, 
-    { 0x95,0x6e,0x65,0xe6 }, { 0xff,0xe6,0x7e,0xaa },
-    { 0xbc,0xcf,0x08,0x21 }, { 0x15,0xe8,0xe6,0xef }, 
-    { 0xe7,0x9b,0xd9,0xba }, { 0x6f,0x36,0xce,0x4a },
-    { 0x9f,0x09,0xd4,0xea }, { 0xb0,0x7c,0xd6,0x29 }, 
-    { 0xa4,0xb2,0xaf,0x31 }, { 0x3f,0x23,0x31,0x2a },
-    { 0xa5,0x94,0x30,0xc6 }, { 0xa2,0x66,0xc0,0x35 }, 
-    { 0x4e,0xbc,0x37,0x74 }, { 0x82,0xca,0xa6,0xfc },
-    { 0x90,0xd0,0xb0,0xe0 }, { 0xa7,0xd8,0x15,0x33 }, 
-    { 0x04,0x98,0x4a,0xf1 }, { 0xec,0xda,0xf7,0x41 },
-    { 0xcd,0x50,0x0e,0x7f }, { 0x91,0xf6,0x2f,0x17 }, 
-    { 0x4d,0xd6,0x8d,0x76 }, { 0xef,0xb0,0x4d,0x43 }, 
-    { 0xaa,0x4d,0x54,0xcc }, { 0x96,0x04,0xdf,0xe4 }, 
-    { 0xd1,0xb5,0xe3,0x9e }, { 0x6a,0x88,0x1b,0x4c },
-    { 0x2c,0x1f,0xb8,0xc1 }, { 0x65,0x51,0x7f,0x46 }, 
-    { 0x5e,0xea,0x04,0x9d }, { 0x8c,0x35,0x5d,0x01 },
-    { 0x87,0x74,0x73,0xfa }, { 0x0b,0x41,0x2e,0xfb }, 
-    { 0x67,0x1d,0x5a,0xb3 }, { 0xdb,0xd2,0x52,0x92 },
-    { 0x10,0x56,0x33,0xe9 }, { 0xd6,0x47,0x13,0x6d }, 
-    { 0xd7,0x61,0x8c,0x9a }, { 0xa1,0x0c,0x7a,0x37 },
-    { 0xf8,0x14,0x8e,0x59 }, { 0x13,0x3c,0x89,0xeb }, 
-    { 0xa9,0x27,0xee,0xce }, { 0x61,0xc9,0x35,0xb7 },
-    { 0x1c,0xe5,0xed,0xe1 }, { 0x47,0xb1,0x3c,0x7a }, 
-    { 0xd2,0xdf,0x59,0x9c }, { 0xf2,0x73,0x3f,0x55 },
-    { 0x14,0xce,0x79,0x18 }, { 0xc7,0x37,0xbf,0x73 }, 
-    { 0xf7,0xcd,0xea,0x53 }, { 0xfd,0xaa,0x5b,0x5f },
-    { 0x3d,0x6f,0x14,0xdf }, { 0x44,0xdb,0x86,0x78 }, 
-    { 0xaf,0xf3,0x81,0xca }, { 0x68,0xc4,0x3e,0xb9 },
-    { 0x24,0x34,0x2c,0x38 }, { 0xa3,0x40,0x5f,0xc2 }, 
-    { 0x1d,0xc3,0x72,0x16 }, { 0xe2,0x25,0x0c,0xbc },
-    { 0x3c,0x49,0x8b,0x28 }, { 0x0d,0x95,0x41,0xff }, 
-    { 0xa8,0x01,0x71,0x39 }, { 0x0c,0xb3,0xde,0x08 },
-    { 0xb4,0xe4,0x9c,0xd8 }, { 0x56,0xc1,0x90,0x64 }, 
-    { 0xcb,0x84,0x61,0x7b }, { 0x32,0xb6,0x70,0xd5 },
-    { 0x6c,0x5c,0x74,0x48 }, { 0xb8,0x57,0x42,0xd0 }
-  };
-
-static const unsigned char S5[256] = 
-  {
-    0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,
-    0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
-    0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,
-    0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
-    0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,
-    0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
-    0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,
-    0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
-    0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,
-    0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
-    0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,
-    0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
-    0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,
-    0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
-    0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,
-    0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
-    0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,
-    0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
-    0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,
-    0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
-    0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,
-    0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
-    0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,
-    0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
-    0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,
-    0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
-    0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,
-    0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
-    0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,
-    0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
-    0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,
-    0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
-  };
-
-static const unsigned char U1[256][4] = 
-  {
-    { 0x00,0x00,0x00,0x00 }, { 0x0e,0x09,0x0d,0x0b },
-    { 0x1c,0x12,0x1a,0x16 }, { 0x12,0x1b,0x17,0x1d }, 
-    { 0x38,0x24,0x34,0x2c }, { 0x36,0x2d,0x39,0x27 },
-    { 0x24,0x36,0x2e,0x3a }, { 0x2a,0x3f,0x23,0x31 }, 
-    { 0x70,0x48,0x68,0x58 }, { 0x7e,0x41,0x65,0x53 },
-    { 0x6c,0x5a,0x72,0x4e }, { 0x62,0x53,0x7f,0x45 }, 
-    { 0x48,0x6c,0x5c,0x74 }, { 0x46,0x65,0x51,0x7f },
-    { 0x54,0x7e,0x46,0x62 }, { 0x5a,0x77,0x4b,0x69 }, 
-    { 0xe0,0x90,0xd0,0xb0 }, { 0xee,0x99,0xdd,0xbb },
-    { 0xfc,0x82,0xca,0xa6 }, { 0xf2,0x8b,0xc7,0xad }, 
-    { 0xd8,0xb4,0xe4,0x9c }, { 0xd6,0xbd,0xe9,0x97 },
-    { 0xc4,0xa6,0xfe,0x8a }, { 0xca,0xaf,0xf3,0x81 }, 
-    { 0x90,0xd8,0xb8,0xe8 }, { 0x9e,0xd1,0xb5,0xe3 },
-    { 0x8c,0xca,0xa2,0xfe }, { 0x82,0xc3,0xaf,0xf5 }, 
-    { 0xa8,0xfc,0x8c,0xc4 }, { 0xa6,0xf5,0x81,0xcf },
-    { 0xb4,0xee,0x96,0xd2 }, { 0xba,0xe7,0x9b,0xd9 }, 
-    { 0xdb,0x3b,0xbb,0x7b }, { 0xd5,0x32,0xb6,0x70 },
-    { 0xc7,0x29,0xa1,0x6d }, { 0xc9,0x20,0xac,0x66 }, 
-    { 0xe3,0x1f,0x8f,0x57 }, { 0xed,0x16,0x82,0x5c },
-    { 0xff,0x0d,0x95,0x41 }, { 0xf1,0x04,0x98,0x4a }, 
-    { 0xab,0x73,0xd3,0x23 }, { 0xa5,0x7a,0xde,0x28 },
-    { 0xb7,0x61,0xc9,0x35 }, { 0xb9,0x68,0xc4,0x3e }, 
-    { 0x93,0x57,0xe7,0x0f }, { 0x9d,0x5e,0xea,0x04 },
-    { 0x8f,0x45,0xfd,0x19 }, { 0x81,0x4c,0xf0,0x12 }, 
-    { 0x3b,0xab,0x6b,0xcb }, { 0x35,0xa2,0x66,0xc0 },
-    { 0x27,0xb9,0x71,0xdd }, { 0x29,0xb0,0x7c,0xd6 }, 
-    { 0x03,0x8f,0x5f,0xe7 }, { 0x0d,0x86,0x52,0xec },
-    { 0x1f,0x9d,0x45,0xf1 }, { 0x11,0x94,0x48,0xfa }, 
-    { 0x4b,0xe3,0x03,0x93 }, { 0x45,0xea,0x0e,0x98 },
-    { 0x57,0xf1,0x19,0x85 }, { 0x59,0xf8,0x14,0x8e }, 
-    { 0x73,0xc7,0x37,0xbf }, { 0x7d,0xce,0x3a,0xb4 },
-    { 0x6f,0xd5,0x2d,0xa9 }, { 0x61,0xdc,0x20,0xa2 }, 
-    { 0xad,0x76,0x6d,0xf6 }, { 0xa3,0x7f,0x60,0xfd },
-    { 0xb1,0x64,0x77,0xe0 }, { 0xbf,0x6d,0x7a,0xeb }, 
-    { 0x95,0x52,0x59,0xda }, { 0x9b,0x5b,0x54,0xd1 },
-    { 0x89,0x40,0x43,0xcc }, { 0x87,0x49,0x4e,0xc7 }, 
-    { 0xdd,0x3e,0x05,0xae }, { 0xd3,0x37,0x08,0xa5 },
-    { 0xc1,0x2c,0x1f,0xb8 }, { 0xcf,0x25,0x12,0xb3 }, 
-    { 0xe5,0x1a,0x31,0x82 }, { 0xeb,0x13,0x3c,0x89 },
-    { 0xf9,0x08,0x2b,0x94 }, { 0xf7,0x01,0x26,0x9f }, 
-    { 0x4d,0xe6,0xbd,0x46 }, { 0x43,0xef,0xb0,0x4d },
-    { 0x51,0xf4,0xa7,0x50 }, { 0x5f,0xfd,0xaa,0x5b }, 
-    { 0x75,0xc2,0x89,0x6a }, { 0x7b,0xcb,0x84,0x61 },
-    { 0x69,0xd0,0x93,0x7c }, { 0x67,0xd9,0x9e,0x77 }, 
-    { 0x3d,0xae,0xd5,0x1e }, { 0x33,0xa7,0xd8,0x15 },
-    { 0x21,0xbc,0xcf,0x08 }, { 0x2f,0xb5,0xc2,0x03 }, 
-    { 0x05,0x8a,0xe1,0x32 }, { 0x0b,0x83,0xec,0x39 },
-    { 0x19,0x98,0xfb,0x24 }, { 0x17,0x91,0xf6,0x2f }, 
-    { 0x76,0x4d,0xd6,0x8d }, { 0x78,0x44,0xdb,0x86 },
-    { 0x6a,0x5f,0xcc,0x9b }, { 0x64,0x56,0xc1,0x90 }, 
-    { 0x4e,0x69,0xe2,0xa1 }, { 0x40,0x60,0xef,0xaa },
-    { 0x52,0x7b,0xf8,0xb7 }, { 0x5c,0x72,0xf5,0xbc }, 
-    { 0x06,0x05,0xbe,0xd5 }, { 0x08,0x0c,0xb3,0xde },
-    { 0x1a,0x17,0xa4,0xc3 }, { 0x14,0x1e,0xa9,0xc8 }, 
-    { 0x3e,0x21,0x8a,0xf9 }, { 0x30,0x28,0x87,0xf2 },
-    { 0x22,0x33,0x90,0xef }, { 0x2c,0x3a,0x9d,0xe4 }, 
-    { 0x96,0xdd,0x06,0x3d }, { 0x98,0xd4,0x0b,0x36 },
-    { 0x8a,0xcf,0x1c,0x2b }, { 0x84,0xc6,0x11,0x20 }, 
-    { 0xae,0xf9,0x32,0x11 }, { 0xa0,0xf0,0x3f,0x1a },
-    { 0xb2,0xeb,0x28,0x07 }, { 0xbc,0xe2,0x25,0x0c }, 
-    { 0xe6,0x95,0x6e,0x65 }, { 0xe8,0x9c,0x63,0x6e },
-    { 0xfa,0x87,0x74,0x73 }, { 0xf4,0x8e,0x79,0x78 }, 
-    { 0xde,0xb1,0x5a,0x49 }, { 0xd0,0xb8,0x57,0x42 },
-    { 0xc2,0xa3,0x40,0x5f }, { 0xcc,0xaa,0x4d,0x54 }, 
-    { 0x41,0xec,0xda,0xf7 }, { 0x4f,0xe5,0xd7,0xfc },
-    { 0x5d,0xfe,0xc0,0xe1 }, { 0x53,0xf7,0xcd,0xea }, 
-    { 0x79,0xc8,0xee,0xdb }, { 0x77,0xc1,0xe3,0xd0 },
-    { 0x65,0xda,0xf4,0xcd }, { 0x6b,0xd3,0xf9,0xc6 }, 
-    { 0x31,0xa4,0xb2,0xaf }, { 0x3f,0xad,0xbf,0xa4 },
-    { 0x2d,0xb6,0xa8,0xb9 }, { 0x23,0xbf,0xa5,0xb2 }, 
-    { 0x09,0x80,0x86,0x83 }, { 0x07,0x89,0x8b,0x88 },
-    { 0x15,0x92,0x9c,0x95 }, { 0x1b,0x9b,0x91,0x9e }, 
-    { 0xa1,0x7c,0x0a,0x47 }, { 0xaf,0x75,0x07,0x4c },
-    { 0xbd,0x6e,0x10,0x51 }, { 0xb3,0x67,0x1d,0x5a }, 
-    { 0x99,0x58,0x3e,0x6b }, { 0x97,0x51,0x33,0x60 },
-    { 0x85,0x4a,0x24,0x7d }, { 0x8b,0x43,0x29,0x76 }, 
-    { 0xd1,0x34,0x62,0x1f }, { 0xdf,0x3d,0x6f,0x14 },
-    { 0xcd,0x26,0x78,0x09 }, { 0xc3,0x2f,0x75,0x02 }, 
-    { 0xe9,0x10,0x56,0x33 }, { 0xe7,0x19,0x5b,0x38 },
-    { 0xf5,0x02,0x4c,0x25 }, { 0xfb,0x0b,0x41,0x2e }, 
-    { 0x9a,0xd7,0x61,0x8c }, { 0x94,0xde,0x6c,0x87 }, 
-    { 0x86,0xc5,0x7b,0x9a }, { 0x88,0xcc,0x76,0x91 }, 
-    { 0xa2,0xf3,0x55,0xa0 }, { 0xac,0xfa,0x58,0xab },
-    { 0xbe,0xe1,0x4f,0xb6 }, { 0xb0,0xe8,0x42,0xbd }, 
-    { 0xea,0x9f,0x09,0xd4 }, { 0xe4,0x96,0x04,0xdf },
-    { 0xf6,0x8d,0x13,0xc2 }, { 0xf8,0x84,0x1e,0xc9 }, 
-    { 0xd2,0xbb,0x3d,0xf8 }, { 0xdc,0xb2,0x30,0xf3 },
-    { 0xce,0xa9,0x27,0xee }, { 0xc0,0xa0,0x2a,0xe5 }, 
-    { 0x7a,0x47,0xb1,0x3c }, { 0x74,0x4e,0xbc,0x37 }, 
-    { 0x66,0x55,0xab,0x2a }, { 0x68,0x5c,0xa6,0x21 }, 
-    { 0x42,0x63,0x85,0x10 }, { 0x4c,0x6a,0x88,0x1b },
-    { 0x5e,0x71,0x9f,0x06 }, { 0x50,0x78,0x92,0x0d }, 
-    { 0x0a,0x0f,0xd9,0x64 }, { 0x04,0x06,0xd4,0x6f },
-    { 0x16,0x1d,0xc3,0x72 }, { 0x18,0x14,0xce,0x79 }, 
-    { 0x32,0x2b,0xed,0x48 }, { 0x3c,0x22,0xe0,0x43 },
-    { 0x2e,0x39,0xf7,0x5e }, { 0x20,0x30,0xfa,0x55 }, 
-    { 0xec,0x9a,0xb7,0x01 }, { 0xe2,0x93,0xba,0x0a },
-    { 0xf0,0x88,0xad,0x17 }, { 0xfe,0x81,0xa0,0x1c }, 
-    { 0xd4,0xbe,0x83,0x2d }, { 0xda,0xb7,0x8e,0x26 },
-    { 0xc8,0xac,0x99,0x3b }, { 0xc6,0xa5,0x94,0x30 }, 
-    { 0x9c,0xd2,0xdf,0x59 }, { 0x92,0xdb,0xd2,0x52 },
-    { 0x80,0xc0,0xc5,0x4f }, { 0x8e,0xc9,0xc8,0x44 }, 
-    { 0xa4,0xf6,0xeb,0x75 }, { 0xaa,0xff,0xe6,0x7e },
-    { 0xb8,0xe4,0xf1,0x63 }, { 0xb6,0xed,0xfc,0x68 }, 
-    { 0x0c,0x0a,0x67,0xb1 }, { 0x02,0x03,0x6a,0xba },
-    { 0x10,0x18,0x7d,0xa7 }, { 0x1e,0x11,0x70,0xac }, 
-    { 0x34,0x2e,0x53,0x9d }, { 0x3a,0x27,0x5e,0x96 },
-    { 0x28,0x3c,0x49,0x8b }, { 0x26,0x35,0x44,0x80 }, 
-    { 0x7c,0x42,0x0f,0xe9 }, { 0x72,0x4b,0x02,0xe2 },
-    { 0x60,0x50,0x15,0xff }, { 0x6e,0x59,0x18,0xf4 }, 
-    { 0x44,0x66,0x3b,0xc5 }, { 0x4a,0x6f,0x36,0xce },
-    { 0x58,0x74,0x21,0xd3 }, { 0x56,0x7d,0x2c,0xd8 }, 
-    { 0x37,0xa1,0x0c,0x7a }, { 0x39,0xa8,0x01,0x71 },
-    { 0x2b,0xb3,0x16,0x6c }, { 0x25,0xba,0x1b,0x67 }, 
-    { 0x0f,0x85,0x38,0x56 }, { 0x01,0x8c,0x35,0x5d },
-    { 0x13,0x97,0x22,0x40 }, { 0x1d,0x9e,0x2f,0x4b }, 
-    { 0x47,0xe9,0x64,0x22 }, { 0x49,0xe0,0x69,0x29 },
-    { 0x5b,0xfb,0x7e,0x34 }, { 0x55,0xf2,0x73,0x3f }, 
-    { 0x7f,0xcd,0x50,0x0e }, { 0x71,0xc4,0x5d,0x05 },
-    { 0x63,0xdf,0x4a,0x18 }, { 0x6d,0xd6,0x47,0x13 }, 
-    { 0xd7,0x31,0xdc,0xca }, { 0xd9,0x38,0xd1,0xc1 },
-    { 0xcb,0x23,0xc6,0xdc }, { 0xc5,0x2a,0xcb,0xd7 }, 
-    { 0xef,0x15,0xe8,0xe6 }, { 0xe1,0x1c,0xe5,0xed },
-    { 0xf3,0x07,0xf2,0xf0 }, { 0xfd,0x0e,0xff,0xfb }, 
-    { 0xa7,0x79,0xb4,0x92 }, { 0xa9,0x70,0xb9,0x99 },
-    { 0xbb,0x6b,0xae,0x84 }, { 0xb5,0x62,0xa3,0x8f }, 
-    { 0x9f,0x5d,0x80,0xbe }, { 0x91,0x54,0x8d,0xb5 },
-    { 0x83,0x4f,0x9a,0xa8 }, { 0x8d,0x46,0x97,0xa3 }
-  };
-
-static const unsigned char U2[256][4] = 
-  {
-    { 0x00,0x00,0x00,0x00 }, { 0x0b,0x0e,0x09,0x0d },
-    { 0x16,0x1c,0x12,0x1a }, { 0x1d,0x12,0x1b,0x17 }, 
-    { 0x2c,0x38,0x24,0x34 }, { 0x27,0x36,0x2d,0x39 },
-    { 0x3a,0x24,0x36,0x2e }, { 0x31,0x2a,0x3f,0x23 }, 
-    { 0x58,0x70,0x48,0x68 }, { 0x53,0x7e,0x41,0x65 }, 
-    { 0x4e,0x6c,0x5a,0x72 }, { 0x45,0x62,0x53,0x7f }, 
-    { 0x74,0x48,0x6c,0x5c }, { 0x7f,0x46,0x65,0x51 },
-    { 0x62,0x54,0x7e,0x46 }, { 0x69,0x5a,0x77,0x4b }, 
-    { 0xb0,0xe0,0x90,0xd0 }, { 0xbb,0xee,0x99,0xdd }, 
-    { 0xa6,0xfc,0x82,0xca }, { 0xad,0xf2,0x8b,0xc7 }, 
-    { 0x9c,0xd8,0xb4,0xe4 }, { 0x97,0xd6,0xbd,0xe9 }, 
-    { 0x8a,0xc4,0xa6,0xfe }, { 0x81,0xca,0xaf,0xf3 }, 
-    { 0xe8,0x90,0xd8,0xb8 }, { 0xe3,0x9e,0xd1,0xb5 },
-    { 0xfe,0x8c,0xca,0xa2 }, { 0xf5,0x82,0xc3,0xaf }, 
-    { 0xc4,0xa8,0xfc,0x8c }, { 0xcf,0xa6,0xf5,0x81 }, 
-    { 0xd2,0xb4,0xee,0x96 }, { 0xd9,0xba,0xe7,0x9b }, 
-    { 0x7b,0xdb,0x3b,0xbb }, { 0x70,0xd5,0x32,0xb6 }, 
-    { 0x6d,0xc7,0x29,0xa1 }, { 0x66,0xc9,0x20,0xac }, 
-    { 0x57,0xe3,0x1f,0x8f }, { 0x5c,0xed,0x16,0x82 }, 
-    { 0x41,0xff,0x0d,0x95 }, { 0x4a,0xf1,0x04,0x98 }, 
-    { 0x23,0xab,0x73,0xd3 }, { 0x28,0xa5,0x7a,0xde },
-    { 0x35,0xb7,0x61,0xc9 }, { 0x3e,0xb9,0x68,0xc4 }, 
-    { 0x0f,0x93,0x57,0xe7 }, { 0x04,0x9d,0x5e,0xea },
-    { 0x19,0x8f,0x45,0xfd }, { 0x12,0x81,0x4c,0xf0 }, 
-    { 0xcb,0x3b,0xab,0x6b }, { 0xc0,0x35,0xa2,0x66 },
-    { 0xdd,0x27,0xb9,0x71 }, { 0xd6,0x29,0xb0,0x7c }, 
-    { 0xe7,0x03,0x8f,0x5f }, { 0xec,0x0d,0x86,0x52 },
-    { 0xf1,0x1f,0x9d,0x45 }, { 0xfa,0x11,0x94,0x48 }, 
-    { 0x93,0x4b,0xe3,0x03 }, { 0x98,0x45,0xea,0x0e }, 
-    { 0x85,0x57,0xf1,0x19 }, { 0x8e,0x59,0xf8,0x14 }, 
-    { 0xbf,0x73,0xc7,0x37 }, { 0xb4,0x7d,0xce,0x3a },
-    { 0xa9,0x6f,0xd5,0x2d }, { 0xa2,0x61,0xdc,0x20 }, 
-    { 0xf6,0xad,0x76,0x6d }, { 0xfd,0xa3,0x7f,0x60 }, 
-    { 0xe0,0xb1,0x64,0x77 }, { 0xeb,0xbf,0x6d,0x7a }, 
-    { 0xda,0x95,0x52,0x59 }, { 0xd1,0x9b,0x5b,0x54 }, 
-    { 0xcc,0x89,0x40,0x43 }, { 0xc7,0x87,0x49,0x4e }, 
-    { 0xae,0xdd,0x3e,0x05 }, { 0xa5,0xd3,0x37,0x08 },
-    { 0xb8,0xc1,0x2c,0x1f }, { 0xb3,0xcf,0x25,0x12 }, 
-    { 0x82,0xe5,0x1a,0x31 }, { 0x89,0xeb,0x13,0x3c },
-    { 0x94,0xf9,0x08,0x2b }, { 0x9f,0xf7,0x01,0x26 }, 
-    { 0x46,0x4d,0xe6,0xbd }, { 0x4d,0x43,0xef,0xb0 },
-    { 0x50,0x51,0xf4,0xa7 }, { 0x5b,0x5f,0xfd,0xaa }, 
-    { 0x6a,0x75,0xc2,0x89 }, { 0x61,0x7b,0xcb,0x84 },
-    { 0x7c,0x69,0xd0,0x93 }, { 0x77,0x67,0xd9,0x9e }, 
-    { 0x1e,0x3d,0xae,0xd5 }, { 0x15,0x33,0xa7,0xd8 },
-    { 0x08,0x21,0xbc,0xcf }, { 0x03,0x2f,0xb5,0xc2 }, 
-    { 0x32,0x05,0x8a,0xe1 }, { 0x39,0x0b,0x83,0xec },
-    { 0x24,0x19,0x98,0xfb }, { 0x2f,0x17,0x91,0xf6 }, 
-    { 0x8d,0x76,0x4d,0xd6 }, { 0x86,0x78,0x44,0xdb },
-    { 0x9b,0x6a,0x5f,0xcc }, { 0x90,0x64,0x56,0xc1 }, 
-    { 0xa1,0x4e,0x69,0xe2 }, { 0xaa,0x40,0x60,0xef },
-    { 0xb7,0x52,0x7b,0xf8 }, { 0xbc,0x5c,0x72,0xf5 }, 
-    { 0xd5,0x06,0x05,0xbe }, { 0xde,0x08,0x0c,0xb3 },
-    { 0xc3,0x1a,0x17,0xa4 }, { 0xc8,0x14,0x1e,0xa9 }, 
-    { 0xf9,0x3e,0x21,0x8a }, { 0xf2,0x30,0x28,0x87 },
-    { 0xef,0x22,0x33,0x90 }, { 0xe4,0x2c,0x3a,0x9d }, 
-    { 0x3d,0x96,0xdd,0x06 }, { 0x36,0x98,0xd4,0x0b },
-    { 0x2b,0x8a,0xcf,0x1c }, { 0x20,0x84,0xc6,0x11 }, 
-    { 0x11,0xae,0xf9,0x32 }, { 0x1a,0xa0,0xf0,0x3f },
-    { 0x07,0xb2,0xeb,0x28 }, { 0x0c,0xbc,0xe2,0x25 }, 
-    { 0x65,0xe6,0x95,0x6e }, { 0x6e,0xe8,0x9c,0x63 },
-    { 0x73,0xfa,0x87,0x74 }, { 0x78,0xf4,0x8e,0x79 }, 
-    { 0x49,0xde,0xb1,0x5a }, { 0x42,0xd0,0xb8,0x57 },
-    { 0x5f,0xc2,0xa3,0x40 }, { 0x54,0xcc,0xaa,0x4d }, 
-    { 0xf7,0x41,0xec,0xda }, { 0xfc,0x4f,0xe5,0xd7 },
-    { 0xe1,0x5d,0xfe,0xc0 }, { 0xea,0x53,0xf7,0xcd }, 
-    { 0xdb,0x79,0xc8,0xee }, { 0xd0,0x77,0xc1,0xe3 },
-    { 0xcd,0x65,0xda,0xf4 }, { 0xc6,0x6b,0xd3,0xf9 }, 
-    { 0xaf,0x31,0xa4,0xb2 }, { 0xa4,0x3f,0xad,0xbf },
-    { 0xb9,0x2d,0xb6,0xa8 }, { 0xb2,0x23,0xbf,0xa5 }, 
-    { 0x83,0x09,0x80,0x86 }, { 0x88,0x07,0x89,0x8b },
-    { 0x95,0x15,0x92,0x9c }, { 0x9e,0x1b,0x9b,0x91 }, 
-    { 0x47,0xa1,0x7c,0x0a }, { 0x4c,0xaf,0x75,0x07 },
-    { 0x51,0xbd,0x6e,0x10 }, { 0x5a,0xb3,0x67,0x1d }, 
-    { 0x6b,0x99,0x58,0x3e }, { 0x60,0x97,0x51,0x33 },
-    { 0x7d,0x85,0x4a,0x24 }, { 0x76,0x8b,0x43,0x29 }, 
-    { 0x1f,0xd1,0x34,0x62 }, { 0x14,0xdf,0x3d,0x6f },
-    { 0x09,0xcd,0x26,0x78 }, { 0x02,0xc3,0x2f,0x75 }, 
-    { 0x33,0xe9,0x10,0x56 }, { 0x38,0xe7,0x19,0x5b },
-    { 0x25,0xf5,0x02,0x4c }, { 0x2e,0xfb,0x0b,0x41 }, 
-    { 0x8c,0x9a,0xd7,0x61 }, { 0x87,0x94,0xde,0x6c },
-    { 0x9a,0x86,0xc5,0x7b }, { 0x91,0x88,0xcc,0x76 }, 
-    { 0xa0,0xa2,0xf3,0x55 }, { 0xab,0xac,0xfa,0x58 },
-    { 0xb6,0xbe,0xe1,0x4f }, { 0xbd,0xb0,0xe8,0x42 }, 
-    { 0xd4,0xea,0x9f,0x09 }, { 0xdf,0xe4,0x96,0x04 },
-    { 0xc2,0xf6,0x8d,0x13 }, { 0xc9,0xf8,0x84,0x1e }, 
-    { 0xf8,0xd2,0xbb,0x3d }, { 0xf3,0xdc,0xb2,0x30 },
-    { 0xee,0xce,0xa9,0x27 }, { 0xe5,0xc0,0xa0,0x2a }, 
-    { 0x3c,0x7a,0x47,0xb1 }, { 0x37,0x74,0x4e,0xbc },
-    { 0x2a,0x66,0x55,0xab }, { 0x21,0x68,0x5c,0xa6 }, 
-    { 0x10,0x42,0x63,0x85 }, { 0x1b,0x4c,0x6a,0x88 },
-    { 0x06,0x5e,0x71,0x9f }, { 0x0d,0x50,0x78,0x92 }, 
-    { 0x64,0x0a,0x0f,0xd9 }, { 0x6f,0x04,0x06,0xd4 },
-    { 0x72,0x16,0x1d,0xc3 }, { 0x79,0x18,0x14,0xce }, 
-    { 0x48,0x32,0x2b,0xed }, { 0x43,0x3c,0x22,0xe0 },
-    { 0x5e,0x2e,0x39,0xf7 }, { 0x55,0x20,0x30,0xfa }, 
-    { 0x01,0xec,0x9a,0xb7 }, { 0x0a,0xe2,0x93,0xba },
-    { 0x17,0xf0,0x88,0xad }, { 0x1c,0xfe,0x81,0xa0 }, 
-    { 0x2d,0xd4,0xbe,0x83 }, { 0x26,0xda,0xb7,0x8e },
-    { 0x3b,0xc8,0xac,0x99 }, { 0x30,0xc6,0xa5,0x94 }, 
-    { 0x59,0x9c,0xd2,0xdf }, { 0x52,0x92,0xdb,0xd2 },
-    { 0x4f,0x80,0xc0,0xc5 }, { 0x44,0x8e,0xc9,0xc8 }, 
-    { 0x75,0xa4,0xf6,0xeb }, { 0x7e,0xaa,0xff,0xe6 },
-    { 0x63,0xb8,0xe4,0xf1 }, { 0x68,0xb6,0xed,0xfc }, 
-    { 0xb1,0x0c,0x0a,0x67 }, { 0xba,0x02,0x03,0x6a },
-    { 0xa7,0x10,0x18,0x7d }, { 0xac,0x1e,0x11,0x70 }, 
-    { 0x9d,0x34,0x2e,0x53 }, { 0x96,0x3a,0x27,0x5e },
-    { 0x8b,0x28,0x3c,0x49 }, { 0x80,0x26,0x35,0x44 }, 
-    { 0xe9,0x7c,0x42,0x0f }, { 0xe2,0x72,0x4b,0x02 },
-    { 0xff,0x60,0x50,0x15 }, { 0xf4,0x6e,0x59,0x18 }, 
-    { 0xc5,0x44,0x66,0x3b }, { 0xce,0x4a,0x6f,0x36 },
-    { 0xd3,0x58,0x74,0x21 }, { 0xd8,0x56,0x7d,0x2c }, 
-    { 0x7a,0x37,0xa1,0x0c }, { 0x71,0x39,0xa8,0x01 },
-    { 0x6c,0x2b,0xb3,0x16 }, { 0x67,0x25,0xba,0x1b }, 
-    { 0x56,0x0f,0x85,0x38 }, { 0x5d,0x01,0x8c,0x35 },
-    { 0x40,0x13,0x97,0x22 }, { 0x4b,0x1d,0x9e,0x2f }, 
-    { 0x22,0x47,0xe9,0x64 }, { 0x29,0x49,0xe0,0x69 },
-    { 0x34,0x5b,0xfb,0x7e }, { 0x3f,0x55,0xf2,0x73 }, 
-    { 0x0e,0x7f,0xcd,0x50 }, { 0x05,0x71,0xc4,0x5d },
-    { 0x18,0x63,0xdf,0x4a }, { 0x13,0x6d,0xd6,0x47 }, 
-    { 0xca,0xd7,0x31,0xdc }, { 0xc1,0xd9,0x38,0xd1 },
-    { 0xdc,0xcb,0x23,0xc6 }, { 0xd7,0xc5,0x2a,0xcb }, 
-    { 0xe6,0xef,0x15,0xe8 }, { 0xed,0xe1,0x1c,0xe5 },
-    { 0xf0,0xf3,0x07,0xf2 }, { 0xfb,0xfd,0x0e,0xff }, 
-    { 0x92,0xa7,0x79,0xb4 }, { 0x99,0xa9,0x70,0xb9 },
-    { 0x84,0xbb,0x6b,0xae }, { 0x8f,0xb5,0x62,0xa3 }, 
-    { 0xbe,0x9f,0x5d,0x80 }, { 0xb5,0x91,0x54,0x8d },
-    { 0xa8,0x83,0x4f,0x9a }, { 0xa3,0x8d,0x46,0x97 }
-  };
-
-static const unsigned char U3[256][4] = 
-  {
-    { 0x00,0x00,0x00,0x00 }, { 0x0d,0x0b,0x0e,0x09 },
-    { 0x1a,0x16,0x1c,0x12 }, { 0x17,0x1d,0x12,0x1b }, 
-    { 0x34,0x2c,0x38,0x24 }, { 0x39,0x27,0x36,0x2d },
-    { 0x2e,0x3a,0x24,0x36 }, { 0x23,0x31,0x2a,0x3f }, 
-    { 0x68,0x58,0x70,0x48 }, { 0x65,0x53,0x7e,0x41 },
-    { 0x72,0x4e,0x6c,0x5a }, { 0x7f,0x45,0x62,0x53 }, 
-    { 0x5c,0x74,0x48,0x6c }, { 0x51,0x7f,0x46,0x65 },
-    { 0x46,0x62,0x54,0x7e }, { 0x4b,0x69,0x5a,0x77 }, 
-    { 0xd0,0xb0,0xe0,0x90 }, { 0xdd,0xbb,0xee,0x99 },
-    { 0xca,0xa6,0xfc,0x82 }, { 0xc7,0xad,0xf2,0x8b }, 
-    { 0xe4,0x9c,0xd8,0xb4 }, { 0xe9,0x97,0xd6,0xbd },
-    { 0xfe,0x8a,0xc4,0xa6 }, { 0xf3,0x81,0xca,0xaf }, 
-    { 0xb8,0xe8,0x90,0xd8 }, { 0xb5,0xe3,0x9e,0xd1 },
-    { 0xa2,0xfe,0x8c,0xca }, { 0xaf,0xf5,0x82,0xc3 }, 
-    { 0x8c,0xc4,0xa8,0xfc }, { 0x81,0xcf,0xa6,0xf5 },
-    { 0x96,0xd2,0xb4,0xee }, { 0x9b,0xd9,0xba,0xe7 }, 
-    { 0xbb,0x7b,0xdb,0x3b }, { 0xb6,0x70,0xd5,0x32 },
-    { 0xa1,0x6d,0xc7,0x29 }, { 0xac,0x66,0xc9,0x20 }, 
-    { 0x8f,0x57,0xe3,0x1f }, { 0x82,0x5c,0xed,0x16 },
-    { 0x95,0x41,0xff,0x0d }, { 0x98,0x4a,0xf1,0x04 }, 
-    { 0xd3,0x23,0xab,0x73 }, { 0xde,0x28,0xa5,0x7a },
-    { 0xc9,0x35,0xb7,0x61 }, { 0xc4,0x3e,0xb9,0x68 }, 
-    { 0xe7,0x0f,0x93,0x57 }, { 0xea,0x04,0x9d,0x5e },
-    { 0xfd,0x19,0x8f,0x45 }, { 0xf0,0x12,0x81,0x4c }, 
-    { 0x6b,0xcb,0x3b,0xab }, { 0x66,0xc0,0x35,0xa2 },
-    { 0x71,0xdd,0x27,0xb9 }, { 0x7c,0xd6,0x29,0xb0 }, 
-    { 0x5f,0xe7,0x03,0x8f }, { 0x52,0xec,0x0d,0x86 },
-    { 0x45,0xf1,0x1f,0x9d }, { 0x48,0xfa,0x11,0x94 }, 
-    { 0x03,0x93,0x4b,0xe3 }, { 0x0e,0x98,0x45,0xea },
-    { 0x19,0x85,0x57,0xf1 }, { 0x14,0x8e,0x59,0xf8 }, 
-    { 0x37,0xbf,0x73,0xc7 }, { 0x3a,0xb4,0x7d,0xce }, 
-    { 0x2d,0xa9,0x6f,0xd5 }, { 0x20,0xa2,0x61,0xdc }, 
-    { 0x6d,0xf6,0xad,0x76 }, { 0x60,0xfd,0xa3,0x7f },
-    { 0x77,0xe0,0xb1,0x64 }, { 0x7a,0xeb,0xbf,0x6d }, 
-    { 0x59,0xda,0x95,0x52 }, { 0x54,0xd1,0x9b,0x5b },
-    { 0x43,0xcc,0x89,0x40 }, { 0x4e,0xc7,0x87,0x49 }, 
-    { 0x05,0xae,0xdd,0x3e }, { 0x08,0xa5,0xd3,0x37 },
-    { 0x1f,0xb8,0xc1,0x2c }, { 0x12,0xb3,0xcf,0x25 }, 
-    { 0x31,0x82,0xe5,0x1a }, { 0x3c,0x89,0xeb,0x13 }, 
-    { 0x2b,0x94,0xf9,0x08 }, { 0x26,0x9f,0xf7,0x01 }, 
-    { 0xbd,0x46,0x4d,0xe6 }, { 0xb0,0x4d,0x43,0xef }, 
-    { 0xa7,0x50,0x51,0xf4 }, { 0xaa,0x5b,0x5f,0xfd }, 
-    { 0x89,0x6a,0x75,0xc2 }, { 0x84,0x61,0x7b,0xcb }, 
-    { 0x93,0x7c,0x69,0xd0 }, { 0x9e,0x77,0x67,0xd9 }, 
-    { 0xd5,0x1e,0x3d,0xae }, { 0xd8,0x15,0x33,0xa7 },
-    { 0xcf,0x08,0x21,0xbc }, { 0xc2,0x03,0x2f,0xb5 }, 
-    { 0xe1,0x32,0x05,0x8a }, { 0xec,0x39,0x0b,0x83 },
-    { 0xfb,0x24,0x19,0x98 }, { 0xf6,0x2f,0x17,0x91 }, 
-    { 0xd6,0x8d,0x76,0x4d }, { 0xdb,0x86,0x78,0x44 }, 
-    { 0xcc,0x9b,0x6a,0x5f }, { 0xc1,0x90,0x64,0x56 }, 
-    { 0xe2,0xa1,0x4e,0x69 }, { 0xef,0xaa,0x40,0x60 }, 
-    { 0xf8,0xb7,0x52,0x7b }, { 0xf5,0xbc,0x5c,0x72 }, 
-    { 0xbe,0xd5,0x06,0x05 }, { 0xb3,0xde,0x08,0x0c }, 
-    { 0xa4,0xc3,0x1a,0x17 }, { 0xa9,0xc8,0x14,0x1e }, 
-    { 0x8a,0xf9,0x3e,0x21 }, { 0x87,0xf2,0x30,0x28 },
-    { 0x90,0xef,0x22,0x33 }, { 0x9d,0xe4,0x2c,0x3a }, 
-    { 0x06,0x3d,0x96,0xdd }, { 0x0b,0x36,0x98,0xd4 },
-    { 0x1c,0x2b,0x8a,0xcf }, { 0x11,0x20,0x84,0xc6 }, 
-    { 0x32,0x11,0xae,0xf9 }, { 0x3f,0x1a,0xa0,0xf0 },
-    { 0x28,0x07,0xb2,0xeb }, { 0x25,0x0c,0xbc,0xe2 }, 
-    { 0x6e,0x65,0xe6,0x95 }, { 0x63,0x6e,0xe8,0x9c },
-    { 0x74,0x73,0xfa,0x87 }, { 0x79,0x78,0xf4,0x8e }, 
-    { 0x5a,0x49,0xde,0xb1 }, { 0x57,0x42,0xd0,0xb8 },
-    { 0x40,0x5f,0xc2,0xa3 }, { 0x4d,0x54,0xcc,0xaa }, 
-    { 0xda,0xf7,0x41,0xec }, { 0xd7,0xfc,0x4f,0xe5 },
-    { 0xc0,0xe1,0x5d,0xfe }, { 0xcd,0xea,0x53,0xf7 }, 
-    { 0xee,0xdb,0x79,0xc8 }, { 0xe3,0xd0,0x77,0xc1 },
-    { 0xf4,0xcd,0x65,0xda }, { 0xf9,0xc6,0x6b,0xd3 }, 
-    { 0xb2,0xaf,0x31,0xa4 }, { 0xbf,0xa4,0x3f,0xad },
-    { 0xa8,0xb9,0x2d,0xb6 }, { 0xa5,0xb2,0x23,0xbf }, 
-    { 0x86,0x83,0x09,0x80 }, { 0x8b,0x88,0x07,0x89 },
-    { 0x9c,0x95,0x15,0x92 }, { 0x91,0x9e,0x1b,0x9b }, 
-    { 0x0a,0x47,0xa1,0x7c }, { 0x07,0x4c,0xaf,0x75 },
-    { 0x10,0x51,0xbd,0x6e }, { 0x1d,0x5a,0xb3,0x67 }, 
-    { 0x3e,0x6b,0x99,0x58 }, { 0x33,0x60,0x97,0x51 },
-    { 0x24,0x7d,0x85,0x4a }, { 0x29,0x76,0x8b,0x43 }, 
-    { 0x62,0x1f,0xd1,0x34 }, { 0x6f,0x14,0xdf,0x3d },
-    { 0x78,0x09,0xcd,0x26 }, { 0x75,0x02,0xc3,0x2f }, 
-    { 0x56,0x33,0xe9,0x10 }, { 0x5b,0x38,0xe7,0x19 },
-    { 0x4c,0x25,0xf5,0x02 }, { 0x41,0x2e,0xfb,0x0b }, 
-    { 0x61,0x8c,0x9a,0xd7 }, { 0x6c,0x87,0x94,0xde },
-    { 0x7b,0x9a,0x86,0xc5 }, { 0x76,0x91,0x88,0xcc }, 
-    { 0x55,0xa0,0xa2,0xf3 }, { 0x58,0xab,0xac,0xfa },
-    { 0x4f,0xb6,0xbe,0xe1 }, { 0x42,0xbd,0xb0,0xe8 }, 
-    { 0x09,0xd4,0xea,0x9f }, { 0x04,0xdf,0xe4,0x96 },
-    { 0x13,0xc2,0xf6,0x8d }, { 0x1e,0xc9,0xf8,0x84 }, 
-    { 0x3d,0xf8,0xd2,0xbb }, { 0x30,0xf3,0xdc,0xb2 },
-    { 0x27,0xee,0xce,0xa9 }, { 0x2a,0xe5,0xc0,0xa0 }, 
-    { 0xb1,0x3c,0x7a,0x47 }, { 0xbc,0x37,0x74,0x4e },
-    { 0xab,0x2a,0x66,0x55 }, { 0xa6,0x21,0x68,0x5c }, 
-    { 0x85,0x10,0x42,0x63 }, { 0x88,0x1b,0x4c,0x6a },
-    { 0x9f,0x06,0x5e,0x71 }, { 0x92,0x0d,0x50,0x78 }, 
-    { 0xd9,0x64,0x0a,0x0f }, { 0xd4,0x6f,0x04,0x06 },
-    { 0xc3,0x72,0x16,0x1d }, { 0xce,0x79,0x18,0x14 }, 
-    { 0xed,0x48,0x32,0x2b }, { 0xe0,0x43,0x3c,0x22 },
-    { 0xf7,0x5e,0x2e,0x39 }, { 0xfa,0x55,0x20,0x30 }, 
-    { 0xb7,0x01,0xec,0x9a }, { 0xba,0x0a,0xe2,0x93 },
-    { 0xad,0x17,0xf0,0x88 }, { 0xa0,0x1c,0xfe,0x81 }, 
-    { 0x83,0x2d,0xd4,0xbe }, { 0x8e,0x26,0xda,0xb7 },
-    { 0x99,0x3b,0xc8,0xac }, { 0x94,0x30,0xc6,0xa5 }, 
-    { 0xdf,0x59,0x9c,0xd2 }, { 0xd2,0x52,0x92,0xdb },
-    { 0xc5,0x4f,0x80,0xc0 }, { 0xc8,0x44,0x8e,0xc9 }, 
-    { 0xeb,0x75,0xa4,0xf6 }, { 0xe6,0x7e,0xaa,0xff },
-    { 0xf1,0x63,0xb8,0xe4 }, { 0xfc,0x68,0xb6,0xed }, 
-    { 0x67,0xb1,0x0c,0x0a }, { 0x6a,0xba,0x02,0x03 },
-    { 0x7d,0xa7,0x10,0x18 }, { 0x70,0xac,0x1e,0x11 }, 
-    { 0x53,0x9d,0x34,0x2e }, { 0x5e,0x96,0x3a,0x27 },
-    { 0x49,0x8b,0x28,0x3c }, { 0x44,0x80,0x26,0x35 }, 
-    { 0x0f,0xe9,0x7c,0x42 }, { 0x02,0xe2,0x72,0x4b },
-    { 0x15,0xff,0x60,0x50 }, { 0x18,0xf4,0x6e,0x59 }, 
-    { 0x3b,0xc5,0x44,0x66 }, { 0x36,0xce,0x4a,0x6f },
-    { 0x21,0xd3,0x58,0x74 }, { 0x2c,0xd8,0x56,0x7d }, 
-    { 0x0c,0x7a,0x37,0xa1 }, { 0x01,0x71,0x39,0xa8 },
-    { 0x16,0x6c,0x2b,0xb3 }, { 0x1b,0x67,0x25,0xba }, 
-    { 0x38,0x56,0x0f,0x85 }, { 0x35,0x5d,0x01,0x8c },
-    { 0x22,0x40,0x13,0x97 }, { 0x2f,0x4b,0x1d,0x9e }, 
-    { 0x64,0x22,0x47,0xe9 }, { 0x69,0x29,0x49,0xe0 },
-    { 0x7e,0x34,0x5b,0xfb }, { 0x73,0x3f,0x55,0xf2 }, 
-    { 0x50,0x0e,0x7f,0xcd }, { 0x5d,0x05,0x71,0xc4 },
-    { 0x4a,0x18,0x63,0xdf }, { 0x47,0x13,0x6d,0xd6 }, 
-    { 0xdc,0xca,0xd7,0x31 }, { 0xd1,0xc1,0xd9,0x38 },
-    { 0xc6,0xdc,0xcb,0x23 }, { 0xcb,0xd7,0xc5,0x2a }, 
-    { 0xe8,0xe6,0xef,0x15 }, { 0xe5,0xed,0xe1,0x1c },
-    { 0xf2,0xf0,0xf3,0x07 }, { 0xff,0xfb,0xfd,0x0e }, 
-    { 0xb4,0x92,0xa7,0x79 }, { 0xb9,0x99,0xa9,0x70 },
-    { 0xae,0x84,0xbb,0x6b }, { 0xa3,0x8f,0xb5,0x62 }, 
-    { 0x80,0xbe,0x9f,0x5d }, { 0x8d,0xb5,0x91,0x54 },
-    { 0x9a,0xa8,0x83,0x4f }, { 0x97,0xa3,0x8d,0x46 }
-  };
-
-static const unsigned char U4[256][4] =
-  {
-    { 0x00,0x00,0x00,0x00 }, { 0x09,0x0d,0x0b,0x0e },
-    { 0x12,0x1a,0x16,0x1c }, { 0x1b,0x17,0x1d,0x12 }, 
-    { 0x24,0x34,0x2c,0x38 }, { 0x2d,0x39,0x27,0x36 },
-    { 0x36,0x2e,0x3a,0x24 }, { 0x3f,0x23,0x31,0x2a }, 
-    { 0x48,0x68,0x58,0x70 }, { 0x41,0x65,0x53,0x7e },
-    { 0x5a,0x72,0x4e,0x6c }, { 0x53,0x7f,0x45,0x62 }, 
-    { 0x6c,0x5c,0x74,0x48 }, { 0x65,0x51,0x7f,0x46 },
-    { 0x7e,0x46,0x62,0x54 }, { 0x77,0x4b,0x69,0x5a }, 
-    { 0x90,0xd0,0xb0,0xe0 }, { 0x99,0xdd,0xbb,0xee },
-    { 0x82,0xca,0xa6,0xfc }, { 0x8b,0xc7,0xad,0xf2 }, 
-    { 0xb4,0xe4,0x9c,0xd8 }, { 0xbd,0xe9,0x97,0xd6 },
-    { 0xa6,0xfe,0x8a,0xc4 }, { 0xaf,0xf3,0x81,0xca }, 
-    { 0xd8,0xb8,0xe8,0x90 }, { 0xd1,0xb5,0xe3,0x9e },
-    { 0xca,0xa2,0xfe,0x8c }, { 0xc3,0xaf,0xf5,0x82 }, 
-    { 0xfc,0x8c,0xc4,0xa8 }, { 0xf5,0x81,0xcf,0xa6 },
-    { 0xee,0x96,0xd2,0xb4 }, { 0xe7,0x9b,0xd9,0xba }, 
-    { 0x3b,0xbb,0x7b,0xdb }, { 0x32,0xb6,0x70,0xd5 },
-    { 0x29,0xa1,0x6d,0xc7 }, { 0x20,0xac,0x66,0xc9 }, 
-    { 0x1f,0x8f,0x57,0xe3 }, { 0x16,0x82,0x5c,0xed },
-    { 0x0d,0x95,0x41,0xff }, { 0x04,0x98,0x4a,0xf1 }, 
-    { 0x73,0xd3,0x23,0xab }, { 0x7a,0xde,0x28,0xa5 },
-    { 0x61,0xc9,0x35,0xb7 }, { 0x68,0xc4,0x3e,0xb9 }, 
-    { 0x57,0xe7,0x0f,0x93 }, { 0x5e,0xea,0x04,0x9d },
-    { 0x45,0xfd,0x19,0x8f }, { 0x4c,0xf0,0x12,0x81 }, 
-    { 0xab,0x6b,0xcb,0x3b }, { 0xa2,0x66,0xc0,0x35 },
-    { 0xb9,0x71,0xdd,0x27 }, { 0xb0,0x7c,0xd6,0x29 }, 
-    { 0x8f,0x5f,0xe7,0x03 }, { 0x86,0x52,0xec,0x0d },
-    { 0x9d,0x45,0xf1,0x1f }, { 0x94,0x48,0xfa,0x11 }, 
-    { 0xe3,0x03,0x93,0x4b }, { 0xea,0x0e,0x98,0x45 },
-    { 0xf1,0x19,0x85,0x57 }, { 0xf8,0x14,0x8e,0x59 }, 
-    { 0xc7,0x37,0xbf,0x73 }, { 0xce,0x3a,0xb4,0x7d },
-    { 0xd5,0x2d,0xa9,0x6f }, { 0xdc,0x20,0xa2,0x61 }, 
-    { 0x76,0x6d,0xf6,0xad }, { 0x7f,0x60,0xfd,0xa3 },
-    { 0x64,0x77,0xe0,0xb1 }, { 0x6d,0x7a,0xeb,0xbf }, 
-    { 0x52,0x59,0xda,0x95 }, { 0x5b,0x54,0xd1,0x9b },
-    { 0x40,0x43,0xcc,0x89 }, { 0x49,0x4e,0xc7,0x87 }, 
-    { 0x3e,0x05,0xae,0xdd }, { 0x37,0x08,0xa5,0xd3 },
-    { 0x2c,0x1f,0xb8,0xc1 }, { 0x25,0x12,0xb3,0xcf }, 
-    { 0x1a,0x31,0x82,0xe5 }, { 0x13,0x3c,0x89,0xeb },
-    { 0x08,0x2b,0x94,0xf9 }, { 0x01,0x26,0x9f,0xf7 }, 
-    { 0xe6,0xbd,0x46,0x4d }, { 0xef,0xb0,0x4d,0x43 },
-    { 0xf4,0xa7,0x50,0x51 }, { 0xfd,0xaa,0x5b,0x5f }, 
-    { 0xc2,0x89,0x6a,0x75 }, { 0xcb,0x84,0x61,0x7b },
-    { 0xd0,0x93,0x7c,0x69 }, { 0xd9,0x9e,0x77,0x67 }, 
-    { 0xae,0xd5,0x1e,0x3d }, { 0xa7,0xd8,0x15,0x33 },
-    { 0xbc,0xcf,0x08,0x21 }, { 0xb5,0xc2,0x03,0x2f }, 
-    { 0x8a,0xe1,0x32,0x05 }, { 0x83,0xec,0x39,0x0b },
-    { 0x98,0xfb,0x24,0x19 }, { 0x91,0xf6,0x2f,0x17 }, 
-    { 0x4d,0xd6,0x8d,0x76 }, { 0x44,0xdb,0x86,0x78 },
-    { 0x5f,0xcc,0x9b,0x6a }, { 0x56,0xc1,0x90,0x64 }, 
-    { 0x69,0xe2,0xa1,0x4e }, { 0x60,0xef,0xaa,0x40 },
-    { 0x7b,0xf8,0xb7,0x52 }, { 0x72,0xf5,0xbc,0x5c }, 
-    { 0x05,0xbe,0xd5,0x06 }, { 0x0c,0xb3,0xde,0x08 },
-    { 0x17,0xa4,0xc3,0x1a }, { 0x1e,0xa9,0xc8,0x14 }, 
-    { 0x21,0x8a,0xf9,0x3e }, { 0x28,0x87,0xf2,0x30 },
-    { 0x33,0x90,0xef,0x22 }, { 0x3a,0x9d,0xe4,0x2c }, 
-    { 0xdd,0x06,0x3d,0x96 }, { 0xd4,0x0b,0x36,0x98 },
-    { 0xcf,0x1c,0x2b,0x8a }, { 0xc6,0x11,0x20,0x84 }, 
-    { 0xf9,0x32,0x11,0xae }, { 0xf0,0x3f,0x1a,0xa0 },
-    { 0xeb,0x28,0x07,0xb2 }, { 0xe2,0x25,0x0c,0xbc }, 
-    { 0x95,0x6e,0x65,0xe6 }, { 0x9c,0x63,0x6e,0xe8 },
-    { 0x87,0x74,0x73,0xfa }, { 0x8e,0x79,0x78,0xf4 }, 
-    { 0xb1,0x5a,0x49,0xde }, { 0xb8,0x57,0x42,0xd0 },
-    { 0xa3,0x40,0x5f,0xc2 }, { 0xaa,0x4d,0x54,0xcc }, 
-    { 0xec,0xda,0xf7,0x41 }, { 0xe5,0xd7,0xfc,0x4f },
-    { 0xfe,0xc0,0xe1,0x5d }, { 0xf7,0xcd,0xea,0x53 }, 
-    { 0xc8,0xee,0xdb,0x79 }, { 0xc1,0xe3,0xd0,0x77 },
-    { 0xda,0xf4,0xcd,0x65 }, { 0xd3,0xf9,0xc6,0x6b }, 
-    { 0xa4,0xb2,0xaf,0x31 }, { 0xad,0xbf,0xa4,0x3f },
-    { 0xb6,0xa8,0xb9,0x2d }, { 0xbf,0xa5,0xb2,0x23 }, 
-    { 0x80,0x86,0x83,0x09 }, { 0x89,0x8b,0x88,0x07 },
-    { 0x92,0x9c,0x95,0x15 }, { 0x9b,0x91,0x9e,0x1b }, 
-    { 0x7c,0x0a,0x47,0xa1 }, { 0x75,0x07,0x4c,0xaf },
-    { 0x6e,0x10,0x51,0xbd }, { 0x67,0x1d,0x5a,0xb3 }, 
-    { 0x58,0x3e,0x6b,0x99 }, { 0x51,0x33,0x60,0x97 },
-    { 0x4a,0x24,0x7d,0x85 }, { 0x43,0x29,0x76,0x8b }, 
-    { 0x34,0x62,0x1f,0xd1 }, { 0x3d,0x6f,0x14,0xdf },
-    { 0x26,0x78,0x09,0xcd }, { 0x2f,0x75,0x02,0xc3 }, 
-    { 0x10,0x56,0x33,0xe9 }, { 0x19,0x5b,0x38,0xe7 },
-    { 0x02,0x4c,0x25,0xf5 }, { 0x0b,0x41,0x2e,0xfb }, 
-    { 0xd7,0x61,0x8c,0x9a }, { 0xde,0x6c,0x87,0x94 },
-    { 0xc5,0x7b,0x9a,0x86 }, { 0xcc,0x76,0x91,0x88 }, 
-    { 0xf3,0x55,0xa0,0xa2 }, { 0xfa,0x58,0xab,0xac },
-    { 0xe1,0x4f,0xb6,0xbe }, { 0xe8,0x42,0xbd,0xb0 }, 
-    { 0x9f,0x09,0xd4,0xea }, { 0x96,0x04,0xdf,0xe4 },
-    { 0x8d,0x13,0xc2,0xf6 }, { 0x84,0x1e,0xc9,0xf8 }, 
-    { 0xbb,0x3d,0xf8,0xd2 }, { 0xb2,0x30,0xf3,0xdc },
-    { 0xa9,0x27,0xee,0xce }, { 0xa0,0x2a,0xe5,0xc0 }, 
-    { 0x47,0xb1,0x3c,0x7a }, { 0x4e,0xbc,0x37,0x74 },
-    { 0x55,0xab,0x2a,0x66 }, { 0x5c,0xa6,0x21,0x68 }, 
-    { 0x63,0x85,0x10,0x42 }, { 0x6a,0x88,0x1b,0x4c },
-    { 0x71,0x9f,0x06,0x5e }, { 0x78,0x92,0x0d,0x50 }, 
-    { 0x0f,0xd9,0x64,0x0a }, { 0x06,0xd4,0x6f,0x04 },
-    { 0x1d,0xc3,0x72,0x16 }, { 0x14,0xce,0x79,0x18 }, 
-    { 0x2b,0xed,0x48,0x32 }, { 0x22,0xe0,0x43,0x3c },
-    { 0x39,0xf7,0x5e,0x2e }, { 0x30,0xfa,0x55,0x20 }, 
-    { 0x9a,0xb7,0x01,0xec }, { 0x93,0xba,0x0a,0xe2 }, 
-    { 0x88,0xad,0x17,0xf0 }, { 0x81,0xa0,0x1c,0xfe }, 
-    { 0xbe,0x83,0x2d,0xd4 }, { 0xb7,0x8e,0x26,0xda },
-    { 0xac,0x99,0x3b,0xc8 }, { 0xa5,0x94,0x30,0xc6 }, 
-    { 0xd2,0xdf,0x59,0x9c }, { 0xdb,0xd2,0x52,0x92 }, 
-    { 0xc0,0xc5,0x4f,0x80 }, { 0xc9,0xc8,0x44,0x8e }, 
-    { 0xf6,0xeb,0x75,0xa4 }, { 0xff,0xe6,0x7e,0xaa },
-    { 0xe4,0xf1,0x63,0xb8 }, { 0xed,0xfc,0x68,0xb6 }, 
-    { 0x0a,0x67,0xb1,0x0c }, { 0x03,0x6a,0xba,0x02 },
-    { 0x18,0x7d,0xa7,0x10 }, { 0x11,0x70,0xac,0x1e }, 
-    { 0x2e,0x53,0x9d,0x34 }, { 0x27,0x5e,0x96,0x3a },
-    { 0x3c,0x49,0x8b,0x28 }, { 0x35,0x44,0x80,0x26 }, 
-    { 0x42,0x0f,0xe9,0x7c }, { 0x4b,0x02,0xe2,0x72 }, 
-    { 0x50,0x15,0xff,0x60 }, { 0x59,0x18,0xf4,0x6e }, 
-    { 0x66,0x3b,0xc5,0x44 }, { 0x6f,0x36,0xce,0x4a },
-    { 0x74,0x21,0xd3,0x58 }, { 0x7d,0x2c,0xd8,0x56 }, 
-    { 0xa1,0x0c,0x7a,0x37 }, { 0xa8,0x01,0x71,0x39 },
-    { 0xb3,0x16,0x6c,0x2b }, { 0xba,0x1b,0x67,0x25 }, 
-    { 0x85,0x38,0x56,0x0f }, { 0x8c,0x35,0x5d,0x01 },
-    { 0x97,0x22,0x40,0x13 }, { 0x9e,0x2f,0x4b,0x1d }, 
-    { 0xe9,0x64,0x22,0x47 }, { 0xe0,0x69,0x29,0x49 }, 
-    { 0xfb,0x7e,0x34,0x5b }, { 0xf2,0x73,0x3f,0x55 }, 
-    { 0xcd,0x50,0x0e,0x7f }, { 0xc4,0x5d,0x05,0x71 },
-    { 0xdf,0x4a,0x18,0x63 }, { 0xd6,0x47,0x13,0x6d }, 
-    { 0x31,0xdc,0xca,0xd7 }, { 0x38,0xd1,0xc1,0xd9 },
-    { 0x23,0xc6,0xdc,0xcb }, { 0x2a,0xcb,0xd7,0xc5 }, 
-    { 0x15,0xe8,0xe6,0xef }, { 0x1c,0xe5,0xed,0xe1 },
-    { 0x07,0xf2,0xf0,0xf3 }, { 0x0e,0xff,0xfb,0xfd }, 
-    { 0x79,0xb4,0x92,0xa7 }, { 0x70,0xb9,0x99,0xa9 },
-    { 0x6b,0xae,0x84,0xbb }, { 0x62,0xa3,0x8f,0xb5 }, 
-    { 0x5d,0x80,0xbe,0x9f }, { 0x54,0x8d,0xb5,0x91 },
-    { 0x4f,0x9a,0xa8,0x83 }, { 0x46,0x97,0xa3,0x8d }
-  };
-
-static const u32 rcon[30] = 
-  { 
-    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c,
-    0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
-    0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
-  };
-
diff --git a/lib/libgcrypt/cipher/rijndael.c b/lib/libgcrypt/cipher/rijndael.c
deleted file mode 100644 (file)
index d43b349..0000000
+++ /dev/null
@@ -1,1253 +0,0 @@
-/* Rijndael (AES) for GnuPG
- * Copyright (C) 2000, 2001, 2002, 2003, 2007,
- *               2008 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- *******************************************************************
- * The code here is based on the optimized implementation taken from
- * http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ on Oct 2, 2000,
- * which carries this notice:
- *------------------------------------------
- * rijndael-alg-fst.c   v2.3   April '2000
- *
- * Optimised ANSI C code
- *
- * authors: v1.0: Antoon Bosselaers
- *          v2.0: Vincent Rijmen
- *          v2.3: Paulo Barreto
- *
- * This code is placed in the public domain.
- *------------------------------------------
- *
- * The SP800-38a document is available at:
- *   http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
- *
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h> /* for memcmp() */
-
-#include "types.h"  /* for byte and u32 typedefs */
-#include "g10lib.h"
-#include "cipher.h"
-
-#define MAXKC                  (256/32)
-#define MAXROUNDS              14
-#define BLOCKSIZE               (128/8)
-
-
-/* USE_PADLOCK indicates whether to compile the padlock specific
-   code.  */
-#undef USE_PADLOCK
-#ifdef ENABLE_PADLOCK_SUPPORT
-# if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
-# define USE_PADLOCK
-# endif
-#endif /*ENABLE_PADLOCK_SUPPORT*/
-
-static const char *selftest(void);
-
-typedef struct 
-{
-  int   ROUNDS;             /* Key-length-dependent number of rounds.  */
-  int decryption_prepared;  /* The decryption key schedule is available.  */
-#ifdef USE_PADLOCK
-  int use_padlock;          /* Padlock shall be used.  */
-  /* The key as passed to the padlock engine.  */
-  unsigned char padlock_key[16] __attribute__ ((aligned (16)));
-#endif
-  union
-  {
-    PROPERLY_ALIGNED_TYPE dummy;
-    byte keyschedule[MAXROUNDS+1][4][4];
-  } u1;
-  union
-  {
-    PROPERLY_ALIGNED_TYPE dummy;
-    byte keyschedule[MAXROUNDS+1][4][4];       
-  } u2;
-} RIJNDAEL_context;
-
-#define keySched  u1.keyschedule
-#define keySched2 u2.keyschedule
-
-/* All the numbers.  */
-#include "rijndael-tables.h"
-
-
-/* Perform the key setup.  */  
-static gcry_err_code_t
-do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
-{
-  static int initialized = 0;
-  static const char *selftest_failed=0;
-  int ROUNDS;
-  int i,j, r, t, rconpointer = 0;
-  int KC;
-  union
-  {
-    PROPERLY_ALIGNED_TYPE dummy;
-    byte k[MAXKC][4];
-  } k;
-#define k k.k
-  union
-  {
-    PROPERLY_ALIGNED_TYPE dummy;
-    byte tk[MAXKC][4];
-  } tk;
-#define tk tk.tk  
-
-  /* The on-the-fly self tests are only run in non-fips mode. In fips
-     mode explicit self-tests are required.  Actually the on-the-fly
-     self-tests are not fully thread-safe and it might happen that a
-     failed self-test won't get noticed in another thread.  
-
-     FIXME: We might want to have a central registry of succeeded
-     self-tests. */
-  if (!fips_mode () && !initialized)
-    {
-      initialized = 1;
-      selftest_failed = selftest ();
-      if (selftest_failed)
-        log_error ("%s\n", selftest_failed );
-    }
-  if (selftest_failed)
-    return GPG_ERR_SELFTEST_FAILED;
-
-  ctx->decryption_prepared = 0;
-#ifdef USE_PADLOCK
-  ctx->use_padlock = 0;
-#endif
-
-  if( keylen == 128/8 )
-    {
-      ROUNDS = 10;
-      KC = 4;
-#ifdef USE_PADLOCK
-      if ((_gcry_get_hw_features () & HWF_PADLOCK_AES))
-        {
-          ctx->use_padlock = 1;
-          memcpy (ctx->padlock_key, key, keylen);
-        }
-#endif
-    }
-  else if ( keylen == 192/8 )
-    {
-      ROUNDS = 12;
-      KC = 6;
-    }
-  else if ( keylen == 256/8 )
-    {
-      ROUNDS = 14;
-      KC = 8;
-    }
-  else
-    return GPG_ERR_INV_KEYLEN;
-
-  ctx->ROUNDS = ROUNDS;
-
-#ifdef USE_PADLOCK
-  if (ctx->use_padlock)
-    {
-      /* Nothing to do as we support only hardware key generation for
-         now.  */
-    }
-  else
-#endif /*USE_PADLOCK*/
-    {
-#define W (ctx->keySched)
-      for (i = 0; i < keylen; i++) 
-        {
-          k[i >> 2][i & 3] = key[i]; 
-        }
-      
-      for (j = KC-1; j >= 0; j--) 
-        {
-          *((u32*)tk[j]) = *((u32*)k[j]);
-        }
-      r = 0;
-      t = 0;
-      /* Copy values into round key array.  */
-      for (j = 0; (j < KC) && (r < ROUNDS + 1); )
-        {
-          for (; (j < KC) && (t < 4); j++, t++)
-            {
-              *((u32*)W[r][t]) = *((u32*)tk[j]);
-            }
-          if (t == 4)
-            {
-              r++;
-              t = 0;
-            }
-        }
-      
-      while (r < ROUNDS + 1)
-        {
-          /* While not enough round key material calculated calculate
-             new values.  */
-          tk[0][0] ^= S[tk[KC-1][1]];
-          tk[0][1] ^= S[tk[KC-1][2]];
-          tk[0][2] ^= S[tk[KC-1][3]];
-          tk[0][3] ^= S[tk[KC-1][0]];
-          tk[0][0] ^= rcon[rconpointer++];
-          
-          if (KC != 8)
-            {
-              for (j = 1; j < KC; j++) 
-                {
-                  *((u32*)tk[j]) ^= *((u32*)tk[j-1]);
-                }
-            } 
-          else 
-            {
-              for (j = 1; j < KC/2; j++)
-                {
-                  *((u32*)tk[j]) ^= *((u32*)tk[j-1]);
-                }
-              tk[KC/2][0] ^= S[tk[KC/2 - 1][0]];
-              tk[KC/2][1] ^= S[tk[KC/2 - 1][1]];
-              tk[KC/2][2] ^= S[tk[KC/2 - 1][2]];
-              tk[KC/2][3] ^= S[tk[KC/2 - 1][3]];
-              for (j = KC/2 + 1; j < KC; j++)
-                {
-                  *((u32*)tk[j]) ^= *((u32*)tk[j-1]);
-                }
-            }
-          
-          /* Copy values into round key array.  */
-          for (j = 0; (j < KC) && (r < ROUNDS + 1); )
-            {
-              for (; (j < KC) && (t < 4); j++, t++)
-                {
-                  *((u32*)W[r][t]) = *((u32*)tk[j]);
-                }
-              if (t == 4)
-                {
-                  r++;
-                  t = 0;
-                }
-            }
-        }              
-#undef W    
-    }
-
-  return 0;
-#undef tk
-#undef k
-}
-
-
-static gcry_err_code_t
-rijndael_setkey (void *context, const byte *key, const unsigned keylen)
-{
-  RIJNDAEL_context *ctx = context;
-
-  int rc = do_setkey (ctx, key, keylen);
-  _gcry_burn_stack ( 100 + 16*sizeof(int));
-  return rc;
-}
-
-
-/* Make a decryption key from an encryption key. */
-static void
-prepare_decryption( RIJNDAEL_context *ctx )
-{
-  int r;
-  union
-  {
-    PROPERLY_ALIGNED_TYPE dummy;
-    byte *w;
-  } w;
-#define w w.w
-
-  for (r=0; r < MAXROUNDS+1; r++ )
-    {
-      *((u32*)ctx->keySched2[r][0]) = *((u32*)ctx->keySched[r][0]);
-      *((u32*)ctx->keySched2[r][1]) = *((u32*)ctx->keySched[r][1]);
-      *((u32*)ctx->keySched2[r][2]) = *((u32*)ctx->keySched[r][2]);
-      *((u32*)ctx->keySched2[r][3]) = *((u32*)ctx->keySched[r][3]);
-    }
-#define W (ctx->keySched2)
-  for (r = 1; r < ctx->ROUNDS; r++)
-    {
-      w = W[r][0];
-      *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
-        ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
-       
-      w = W[r][1];
-      *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
-        ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
-        
-      w = W[r][2];
-      *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
-        ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
-        
-      w = W[r][3];
-      *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
-        ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
-    }
-#undef W
-#undef w
-}      
-
-
-\f
-/* Encrypt one block.  A and B need to be aligned on a 4 byte
-   boundary.  A and B may be the same. */
-static void
-do_encrypt_aligned (const RIJNDAEL_context *ctx, 
-                    unsigned char *b, const unsigned char *a)
-{
-#define rk (ctx->keySched)
-  int ROUNDS = ctx->ROUNDS;
-  int r;
-  union
-  {
-    u32  tempu32[4];  /* Force correct alignment. */
-    byte temp[4][4];
-  } u;
-
-  *((u32*)u.temp[0]) = *((u32*)(a   )) ^ *((u32*)rk[0][0]);
-  *((u32*)u.temp[1]) = *((u32*)(a+ 4)) ^ *((u32*)rk[0][1]);
-  *((u32*)u.temp[2]) = *((u32*)(a+ 8)) ^ *((u32*)rk[0][2]);
-  *((u32*)u.temp[3]) = *((u32*)(a+12)) ^ *((u32*)rk[0][3]);
-  *((u32*)(b    ))   = (*((u32*)T1[u.temp[0][0]])
-                        ^ *((u32*)T2[u.temp[1][1]])
-                        ^ *((u32*)T3[u.temp[2][2]]) 
-                        ^ *((u32*)T4[u.temp[3][3]]));
-  *((u32*)(b + 4))   = (*((u32*)T1[u.temp[1][0]])
-                        ^ *((u32*)T2[u.temp[2][1]])
-                        ^ *((u32*)T3[u.temp[3][2]]) 
-                        ^ *((u32*)T4[u.temp[0][3]]));
-  *((u32*)(b + 8))   = (*((u32*)T1[u.temp[2][0]])
-                        ^ *((u32*)T2[u.temp[3][1]])
-                        ^ *((u32*)T3[u.temp[0][2]]) 
-                        ^ *((u32*)T4[u.temp[1][3]]));
-  *((u32*)(b +12))   = (*((u32*)T1[u.temp[3][0]])
-                        ^ *((u32*)T2[u.temp[0][1]])
-                        ^ *((u32*)T3[u.temp[1][2]]) 
-                        ^ *((u32*)T4[u.temp[2][3]]));
-
-  for (r = 1; r < ROUNDS-1; r++)
-    {
-      *((u32*)u.temp[0]) = *((u32*)(b   )) ^ *((u32*)rk[r][0]);
-      *((u32*)u.temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[r][1]);
-      *((u32*)u.temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[r][2]);
-      *((u32*)u.temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[r][3]);
-
-      *((u32*)(b    ))   = (*((u32*)T1[u.temp[0][0]])
-                            ^ *((u32*)T2[u.temp[1][1]])
-                            ^ *((u32*)T3[u.temp[2][2]]) 
-                            ^ *((u32*)T4[u.temp[3][3]]));
-      *((u32*)(b + 4))   = (*((u32*)T1[u.temp[1][0]])
-                            ^ *((u32*)T2[u.temp[2][1]])
-                            ^ *((u32*)T3[u.temp[3][2]]) 
-                            ^ *((u32*)T4[u.temp[0][3]]));
-      *((u32*)(b + 8))   = (*((u32*)T1[u.temp[2][0]])
-                            ^ *((u32*)T2[u.temp[3][1]])
-                            ^ *((u32*)T3[u.temp[0][2]]) 
-                            ^ *((u32*)T4[u.temp[1][3]]));
-      *((u32*)(b +12))   = (*((u32*)T1[u.temp[3][0]])
-                            ^ *((u32*)T2[u.temp[0][1]])
-                            ^ *((u32*)T3[u.temp[1][2]]) 
-                            ^ *((u32*)T4[u.temp[2][3]]));
-    }
-
-  /* Last round is special. */   
-  *((u32*)u.temp[0]) = *((u32*)(b   )) ^ *((u32*)rk[ROUNDS-1][0]);
-  *((u32*)u.temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[ROUNDS-1][1]);
-  *((u32*)u.temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[ROUNDS-1][2]);
-  *((u32*)u.temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[ROUNDS-1][3]);
-  b[ 0] = T1[u.temp[0][0]][1];
-  b[ 1] = T1[u.temp[1][1]][1];
-  b[ 2] = T1[u.temp[2][2]][1];
-  b[ 3] = T1[u.temp[3][3]][1];
-  b[ 4] = T1[u.temp[1][0]][1];
-  b[ 5] = T1[u.temp[2][1]][1];
-  b[ 6] = T1[u.temp[3][2]][1];
-  b[ 7] = T1[u.temp[0][3]][1];
-  b[ 8] = T1[u.temp[2][0]][1];
-  b[ 9] = T1[u.temp[3][1]][1];
-  b[10] = T1[u.temp[0][2]][1];
-  b[11] = T1[u.temp[1][3]][1];
-  b[12] = T1[u.temp[3][0]][1];
-  b[13] = T1[u.temp[0][1]][1];
-  b[14] = T1[u.temp[1][2]][1];
-  b[15] = T1[u.temp[2][3]][1];
-  *((u32*)(b   )) ^= *((u32*)rk[ROUNDS][0]);
-  *((u32*)(b+ 4)) ^= *((u32*)rk[ROUNDS][1]);
-  *((u32*)(b+ 8)) ^= *((u32*)rk[ROUNDS][2]);
-  *((u32*)(b+12)) ^= *((u32*)rk[ROUNDS][3]);
-#undef rk
-}
-
-
-static void
-do_encrypt (const RIJNDAEL_context *ctx,
-            unsigned char *bx, const unsigned char *ax)
-{
-  /* BX and AX are not necessary correctly aligned.  Thus we need to
-     copy them here. */
-  union
-  {
-    u32  dummy[4]; 
-    byte a[16];
-  } a;
-  union
-  {
-    u32  dummy[4]; 
-    byte b[16];
-  } b;
-
-  memcpy (a.a, ax, 16);
-  do_encrypt_aligned (ctx, b.b, a.a);
-  memcpy (bx, b.b, 16);
-}
-
-
-/* Encrypt or decrypt one block using the padlock engine.  A and B may
-   be the same. */
-#ifdef USE_PADLOCK
-static void
-do_padlock (const RIJNDAEL_context *ctx, int decrypt_flag,
-            unsigned char *bx, const unsigned char *ax)
-{
-  /* BX and AX are not necessary correctly aligned.  Thus we need to
-     copy them here. */
-  unsigned char a[16] __attribute__ ((aligned (16)));
-  unsigned char b[16] __attribute__ ((aligned (16)));
-  unsigned int cword[4] __attribute__ ((aligned (16)));
-
-  /* The control word fields are:
-      127:12   11:10 9     8     7     6     5     4     3:0
-      RESERVED KSIZE CRYPT INTER KEYGN CIPHR ALIGN DGEST ROUND  */
-  cword[0] = (ctx->ROUNDS & 15);  /* (The mask is just a safeguard.)  */
-  cword[1] = 0;
-  cword[2] = 0;
-  cword[3] = 0;
-  if (decrypt_flag)
-    cword[0] |= 0x00000200;
-
-  memcpy (a, ax, 16);
-   
-  asm volatile 
-    ("pushfl\n\t"          /* Force key reload.  */            
-     "popfl\n\t"
-     "xchg %3, %%ebx\n\t"  /* Load key.  */
-     "movl $1, %%ecx\n\t"  /* Init counter for just one block.  */
-     ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XSTORE ECB. */
-     "xchg %3, %%ebx\n"    /* Restore GOT register.  */
-     : /* No output */
-     : "S" (a), "D" (b), "d" (cword), "r" (ctx->padlock_key)
-     : "%ecx", "cc", "memory"
-     );
-
-  memcpy (bx, b, 16);
-
-}
-#endif /*USE_PADLOCK*/
-
-
-static void
-rijndael_encrypt (void *context, byte *b, const byte *a)
-{
-  RIJNDAEL_context *ctx = context;
-
-#ifdef USE_PADLOCK
-  if (ctx->use_padlock)
-    {
-      do_padlock (ctx, 0, b, a);
-      _gcry_burn_stack (48 + 15 /* possible padding for alignment */);
-    }
-  else
-#endif /*USE_PADLOCK*/
-    {
-      do_encrypt (ctx, b, a);
-      _gcry_burn_stack (48 + 2*sizeof(int));
-    }
-}
-
-
-/* Bulk encryption of complete blocks in CFB mode.  Caller needs to
-   make sure that IV is aligned on an unsigned long boundary.  This
-   function is only intended for the bulk encryption feature of
-   cipher.c. */
-void
-_gcry_aes_cfb_enc (void *context, unsigned char *iv, 
-                   void *outbuf_arg, const void *inbuf_arg,
-                   unsigned int nblocks)
-{
-  RIJNDAEL_context *ctx = context;
-  unsigned char *outbuf = outbuf_arg;
-  const unsigned char *inbuf = inbuf_arg;
-  unsigned char *ivp;
-  int i;
-
-#ifdef USE_PADLOCK
-  if (ctx->use_padlock)
-    {
-      /* Fixme: Let Padlock do the CFBing.  */
-      for ( ;nblocks; nblocks-- )
-        {
-          /* Encrypt the IV. */
-          do_padlock (ctx, 0, iv, iv);
-          /* XOR the input with the IV and store input into IV.  */
-          for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
-            *outbuf++ = (*ivp++ ^= *inbuf++);
-        }
-    }
-  else
-#endif /* USE_PADLOCK*/
-    {
-      for ( ;nblocks; nblocks-- )
-        {
-          /* Encrypt the IV. */
-          do_encrypt_aligned (ctx, iv, iv);
-          /* XOR the input with the IV and store input into IV.  */
-          for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
-            *outbuf++ = (*ivp++ ^= *inbuf++);
-        }
-    }
-
-  _gcry_burn_stack (48 + 2*sizeof(int));
-}
-
-
-/* Bulk encryption of complete blocks in CBC mode.  Caller needs to
-   make sure that IV is aligned on an unsigned long boundary.  This
-   function is only intended for the bulk encryption feature of
-   cipher.c. */
-void
-_gcry_aes_cbc_enc (void *context, unsigned char *iv, 
-                   void *outbuf_arg, const void *inbuf_arg,
-                   unsigned int nblocks, int cbc_mac)
-{
-  RIJNDAEL_context *ctx = context;
-  unsigned char *outbuf = outbuf_arg;
-  const unsigned char *inbuf = inbuf_arg;
-  unsigned char *ivp;
-  int i;
-
-  for ( ;nblocks; nblocks-- )
-    {
-      for (ivp=iv, i=0; i < BLOCKSIZE; i++ )
-        outbuf[i] = inbuf[i] ^ *ivp++;
-
-#ifdef USE_PADLOCK
-      if (ctx->use_padlock)
-        do_padlock (ctx, 0, outbuf, outbuf);
-      else
-#endif /*USE_PADLOCK*/
-        do_encrypt (ctx, outbuf, outbuf );
-
-      memcpy (iv, outbuf, BLOCKSIZE);
-      inbuf += BLOCKSIZE;
-      if (!cbc_mac)
-        outbuf += BLOCKSIZE;
-    }
-
-  _gcry_burn_stack (48 + 2*sizeof(int));
-}
-
-
-\f
-/* Decrypt one block.  A and B need to be aligned on a 4 byte boundary
-   and the decryption must have been prepared.  A and B may be the
-   same. */
-static void
-do_decrypt_aligned (RIJNDAEL_context *ctx, 
-                    unsigned char *b, const unsigned char *a)
-{
-#define rk  (ctx->keySched2)
-  int ROUNDS = ctx->ROUNDS; 
-  int r;
-  union 
-  {
-    u32  tempu32[4];  /* Force correct alignment. */
-    byte temp[4][4];
-  } u;
-
-
-  *((u32*)u.temp[0]) = *((u32*)(a   )) ^ *((u32*)rk[ROUNDS][0]);
-  *((u32*)u.temp[1]) = *((u32*)(a+ 4)) ^ *((u32*)rk[ROUNDS][1]);
-  *((u32*)u.temp[2]) = *((u32*)(a+ 8)) ^ *((u32*)rk[ROUNDS][2]);
-  *((u32*)u.temp[3]) = *((u32*)(a+12)) ^ *((u32*)rk[ROUNDS][3]);
-  
-  *((u32*)(b   ))    = (*((u32*)T5[u.temp[0][0]])
-                        ^ *((u32*)T6[u.temp[3][1]])
-                        ^ *((u32*)T7[u.temp[2][2]]) 
-                        ^ *((u32*)T8[u.temp[1][3]]));
-  *((u32*)(b+ 4))    = (*((u32*)T5[u.temp[1][0]])
-                        ^ *((u32*)T6[u.temp[0][1]])
-                        ^ *((u32*)T7[u.temp[3][2]]) 
-                        ^ *((u32*)T8[u.temp[2][3]]));
-  *((u32*)(b+ 8))    = (*((u32*)T5[u.temp[2][0]])
-                        ^ *((u32*)T6[u.temp[1][1]])
-                        ^ *((u32*)T7[u.temp[0][2]]) 
-                        ^ *((u32*)T8[u.temp[3][3]]));
-  *((u32*)(b+12))    = (*((u32*)T5[u.temp[3][0]])
-                        ^ *((u32*)T6[u.temp[2][1]])
-                        ^ *((u32*)T7[u.temp[1][2]]) 
-                        ^ *((u32*)T8[u.temp[0][3]]));
-
-  for (r = ROUNDS-1; r > 1; r--)
-    {
-      *((u32*)u.temp[0]) = *((u32*)(b   )) ^ *((u32*)rk[r][0]);
-      *((u32*)u.temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[r][1]);
-      *((u32*)u.temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[r][2]);
-      *((u32*)u.temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[r][3]);
-      *((u32*)(b   ))    = (*((u32*)T5[u.temp[0][0]])
-                            ^ *((u32*)T6[u.temp[3][1]])
-                            ^ *((u32*)T7[u.temp[2][2]]) 
-                            ^ *((u32*)T8[u.temp[1][3]]));
-      *((u32*)(b+ 4))    = (*((u32*)T5[u.temp[1][0]])
-                            ^ *((u32*)T6[u.temp[0][1]])
-                            ^ *((u32*)T7[u.temp[3][2]]) 
-                            ^ *((u32*)T8[u.temp[2][3]]));
-      *((u32*)(b+ 8))    = (*((u32*)T5[u.temp[2][0]])
-                            ^ *((u32*)T6[u.temp[1][1]])
-                            ^ *((u32*)T7[u.temp[0][2]]) 
-                            ^ *((u32*)T8[u.temp[3][3]]));
-      *((u32*)(b+12))    = (*((u32*)T5[u.temp[3][0]])
-                            ^ *((u32*)T6[u.temp[2][1]])
-                            ^ *((u32*)T7[u.temp[1][2]]) 
-                            ^ *((u32*)T8[u.temp[0][3]]));
-    }
-
-  /* Last round is special. */   
-  *((u32*)u.temp[0]) = *((u32*)(b   )) ^ *((u32*)rk[1][0]);
-  *((u32*)u.temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[1][1]);
-  *((u32*)u.temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[1][2]);
-  *((u32*)u.temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[1][3]);
-  b[ 0] = S5[u.temp[0][0]];
-  b[ 1] = S5[u.temp[3][1]];
-  b[ 2] = S5[u.temp[2][2]];
-  b[ 3] = S5[u.temp[1][3]];
-  b[ 4] = S5[u.temp[1][0]];
-  b[ 5] = S5[u.temp[0][1]];
-  b[ 6] = S5[u.temp[3][2]];
-  b[ 7] = S5[u.temp[2][3]];
-  b[ 8] = S5[u.temp[2][0]];
-  b[ 9] = S5[u.temp[1][1]];
-  b[10] = S5[u.temp[0][2]];
-  b[11] = S5[u.temp[3][3]];
-  b[12] = S5[u.temp[3][0]];
-  b[13] = S5[u.temp[2][1]];
-  b[14] = S5[u.temp[1][2]];
-  b[15] = S5[u.temp[0][3]];
-  *((u32*)(b   )) ^= *((u32*)rk[0][0]);
-  *((u32*)(b+ 4)) ^= *((u32*)rk[0][1]);
-  *((u32*)(b+ 8)) ^= *((u32*)rk[0][2]);
-  *((u32*)(b+12)) ^= *((u32*)rk[0][3]);
-#undef rk
-}
-
-
-/* Decrypt one block.  AX and BX may be the same. */
-static void
-do_decrypt (RIJNDAEL_context *ctx, byte *bx, const byte *ax)
-{
-  /* BX and AX are not necessary correctly aligned.  Thus we need to
-     copy them here. */
-  union
-  {
-    u32  dummy[4]; 
-    byte a[16];
-  } a;
-  union
-  {
-    u32  dummy[4]; 
-    byte b[16];
-  } b;
-
-  if ( !ctx->decryption_prepared )
-    {
-      prepare_decryption ( ctx );
-      _gcry_burn_stack (64);
-      ctx->decryption_prepared = 1;
-    }
-
-  memcpy (a.a, ax, 16);
-  do_decrypt_aligned (ctx, b.b, a.a);
-  memcpy (bx, b.b, 16);
-#undef rk
-}
-    
-
-
-
-static void
-rijndael_decrypt (void *context, byte *b, const byte *a)
-{
-  RIJNDAEL_context *ctx = context;
-
-#ifdef USE_PADLOCK
-  if (ctx->use_padlock)
-    {
-      do_padlock (ctx, 1, b, a);
-      _gcry_burn_stack (48 + 2*sizeof(int) /* FIXME */);
-    }
-  else
-#endif /*USE_PADLOCK*/
-    {
-      do_decrypt (ctx, b, a);
-      _gcry_burn_stack (48+2*sizeof(int));
-    }
-}
-
-
-/* Bulk decryption of complete blocks in CFB mode.  Caller needs to
-   make sure that IV is aligned on an unisgned lonhg boundary.  This
-   function is only intended for the bulk encryption feature of
-   cipher.c. */
-void
-_gcry_aes_cfb_dec (void *context, unsigned char *iv, 
-                   void *outbuf_arg, const void *inbuf_arg,
-                   unsigned int nblocks)
-{
-  RIJNDAEL_context *ctx = context;
-  unsigned char *outbuf = outbuf_arg;
-  const unsigned char *inbuf = inbuf_arg;
-  unsigned char *ivp;
-  unsigned char temp;
-  int i;
-
-#ifdef USE_PADLOCK
-  if (ctx->use_padlock)
-    {
-      /* Fixme:  Let Padlock do the CFBing.  */
-      for ( ;nblocks; nblocks-- )
-        {
-          do_padlock (ctx, 0, iv, iv);
-          for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
-            {
-              temp = *inbuf++;
-              *outbuf++ = *ivp ^ temp;
-              *ivp++ = temp;
-            }
-        }
-    }
-  else
-#endif /*USE_PADLOCK*/
-    {
-      for ( ;nblocks; nblocks-- )
-        {
-          do_encrypt_aligned (ctx, iv, iv);
-          for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
-            {
-              temp = *inbuf++;
-              *outbuf++ = *ivp ^ temp;
-              *ivp++ = temp;
-            }
-        }
-    }
-
-  _gcry_burn_stack (48 + 2*sizeof(int));
-}
-
-
-/* Bulk decryption of complete blocks in CBC mode.  Caller needs to
-   make sure that IV is aligned on an unsigned long boundary.  This
-   function is only intended for the bulk encryption feature of
-   cipher.c. */
-void
-_gcry_aes_cbc_dec (void *context, unsigned char *iv, 
-                   void *outbuf_arg, const void *inbuf_arg,
-                   unsigned int nblocks)
-{
-  RIJNDAEL_context *ctx = context;
-  unsigned char *outbuf = outbuf_arg;
-  const unsigned char *inbuf = inbuf_arg;
-  unsigned char *ivp;
-  int i;
-  unsigned char savebuf[BLOCKSIZE];
-
-  for ( ;nblocks; nblocks-- )
-    {
-      /* We need to save INBUF away because it may be identical to
-         OUTBUF.  */
-      memcpy (savebuf, inbuf, BLOCKSIZE);
-
-#ifdef USE_PADLOCK
-      if (ctx->use_padlock)
-        do_padlock (ctx, 1, outbuf, inbuf);
-      else
-#endif /*USE_PADLOCK*/
-        do_decrypt (ctx, outbuf, inbuf);
-
-      for (ivp=iv, i=0; i < BLOCKSIZE; i++ )
-        outbuf[i] ^= *ivp++;
-      memcpy (iv, savebuf, BLOCKSIZE);
-      inbuf += BLOCKSIZE;
-      outbuf += BLOCKSIZE;
-    }
-
-  _gcry_burn_stack (48 + 2*sizeof(int) + BLOCKSIZE + 4*sizeof (char*));
-}
-
-
-
-\f
-/* Run the self-tests for AES 128.  Returns NULL on success. */
-static const char*
-selftest_basic_128 (void)
-{
-  RIJNDAEL_context ctx;
-  unsigned char scratch[16];      
-
-  /* The test vectors are from the AES supplied ones; more or less
-     randomly taken from ecb_tbl.txt (I=42,81,14) */
-  static const unsigned char plaintext_128[16] = 
-    {
-      0x01,0x4B,0xAF,0x22,0x78,0xA6,0x9D,0x33,
-      0x1D,0x51,0x80,0x10,0x36,0x43,0xE9,0x9A
-    };
-  static const unsigned char key_128[16] =
-    {
-      0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF,0xF0,
-      0xF2,0xF3,0xF4,0xF5,0xF7,0xF8,0xF9,0xFA
-    };
-  static const unsigned char ciphertext_128[16] =
-    {
-      0x67,0x43,0xC3,0xD1,0x51,0x9A,0xB4,0xF2,
-      0xCD,0x9A,0x78,0xAB,0x09,0xA5,0x11,0xBD
-    };
-  
-  rijndael_setkey (&ctx, key_128, sizeof (key_128));
-  rijndael_encrypt (&ctx, scratch, plaintext_128);
-  if (memcmp (scratch, ciphertext_128, sizeof (ciphertext_128)))
-     return "AES-128 test encryption failed.";
-  rijndael_decrypt (&ctx, scratch, scratch);
-  if (memcmp (scratch, plaintext_128, sizeof (plaintext_128)))
-    return "AES-128 test decryption failed.";
-  
-  return NULL;
-}
-
-/* Run the self-tests for AES 192.  Returns NULL on success. */
-static const char*
-selftest_basic_192 (void)
-{
-  RIJNDAEL_context ctx;
-  unsigned char scratch[16];      
-  
-  static unsigned char plaintext_192[16] = 
-    {
-      0x76,0x77,0x74,0x75,0xF1,0xF2,0xF3,0xF4,
-      0xF8,0xF9,0xE6,0xE7,0x77,0x70,0x71,0x72
-    };
-  static unsigned char key_192[24] = 
-    {
-      0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C,
-      0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16,
-      0x18,0x19,0x1A,0x1B,0x1D,0x1E,0x1F,0x20
-    };
-  static const unsigned char ciphertext_192[16] =
-    {
-      0x5D,0x1E,0xF2,0x0D,0xCE,0xD6,0xBC,0xBC,
-      0x12,0x13,0x1A,0xC7,0xC5,0x47,0x88,0xAA
-    };
-    
-  rijndael_setkey (&ctx, key_192, sizeof(key_192));
-  rijndael_encrypt (&ctx, scratch, plaintext_192);
-  if (memcmp (scratch, ciphertext_192, sizeof (ciphertext_192)))
-    return "AES-192 test encryption failed.";
-  rijndael_decrypt (&ctx, scratch, scratch);
-  if (memcmp (scratch, plaintext_192, sizeof (plaintext_192)))
-    return "AES-192 test decryption failed.";
-  
-  return NULL;
-}
-
-
-/* Run the self-tests for AES 256.  Returns NULL on success. */
-static const char*
-selftest_basic_256 (void)
-{
-  RIJNDAEL_context ctx;
-  unsigned char scratch[16];      
-
-  static unsigned char plaintext_256[16] = 
-    {
-      0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
-      0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21
-    };
-  static unsigned char key_256[32] = 
-    {
-      0x08,0x09,0x0A,0x0B,0x0D,0x0E,0x0F,0x10,
-      0x12,0x13,0x14,0x15,0x17,0x18,0x19,0x1A,
-      0x1C,0x1D,0x1E,0x1F,0x21,0x22,0x23,0x24,
-      0x26,0x27,0x28,0x29,0x2B,0x2C,0x2D,0x2E
-    };
-  static const unsigned char ciphertext_256[16] = 
-    {
-      0x08,0x0E,0x95,0x17,0xEB,0x16,0x77,0x71,
-      0x9A,0xCF,0x72,0x80,0x86,0x04,0x0A,0xE3
-    };
-
-  rijndael_setkey (&ctx, key_256, sizeof(key_256));
-  rijndael_encrypt (&ctx, scratch, plaintext_256);
-  if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256)))
-    return "AES-256 test encryption failed.";
-  rijndael_decrypt (&ctx, scratch, scratch);
-  if (memcmp (scratch, plaintext_256, sizeof (plaintext_256)))
-    return "AES-256 test decryption failed.";
-    
-  return NULL;
-}
-
-/* Run all the self-tests and return NULL on success.  This function
-   is used for the on-the-fly self-tests. */
-static const char *
-selftest (void)
-{
-  const char *r;
-
-  if ( (r = selftest_basic_128 ())
-       || (r = selftest_basic_192 ())
-       || (r = selftest_basic_256 ()) )
-    return r;
-
-  return r;
-}
-
-
-/* SP800-38a.pdf for AES-128.  */
-static const char *
-selftest_fips_128_38a (int requested_mode)
-{
-  struct tv
-  {
-    int mode;
-    const unsigned char key[16];
-    const unsigned char iv[16];
-    struct 
-    {
-      const unsigned char input[16];
-      const unsigned char output[16];
-    } data[4];
-  } tv[2] =
-    {
-      {
-        GCRY_CIPHER_MODE_CFB,  /* F.3.13, CFB128-AES128 */
-        { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
-          0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
-        { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
-          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
-        {
-          { { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
-              0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a },
-            { 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
-              0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a } },
-          
-          { { 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
-              0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 },
-            { 0xc8, 0xa6, 0x45, 0x37, 0xa0, 0xb3, 0xa9, 0x3f,
-              0xcd, 0xe3, 0xcd, 0xad, 0x9f, 0x1c, 0xe5, 0x8b } },
-          
-          { { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 
-              0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef },
-            { 0x26, 0x75, 0x1f, 0x67, 0xa3, 0xcb, 0xb1, 0x40,
-              0xb1, 0x80, 0x8c, 0xf1, 0x87, 0xa4, 0xf4, 0xdf } },
-          
-          { { 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
-              0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
-            { 0xc0, 0x4b, 0x05, 0x35, 0x7c, 0x5d, 0x1c, 0x0e,
-              0xea, 0xc4, 0xc6, 0x6f, 0x9f, 0xf7, 0xf2, 0xe6 } }
-        }
-      },
-      {
-        GCRY_CIPHER_MODE_OFB,
-        { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
-          0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
-        { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
-          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
-        {
-          { { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
-              0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a },
-            { 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
-              0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a } },
-
-          { { 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
-              0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 },
-            { 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
-              0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25 } },
-          
-          { { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
-              0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef },
-            { 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
-              0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc } },
-
-          { { 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
-              0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
-            { 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
-              0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e } },
-        }
-      }
-    };
-  unsigned char scratch[16];
-  gpg_error_t err;
-  int tvi, idx;
-  gcry_cipher_hd_t hdenc = NULL;
-  gcry_cipher_hd_t hddec = NULL;
-
-#define Fail(a) do {           \
-    _gcry_cipher_close (hdenc);  \
-    _gcry_cipher_close (hddec);  \
-    return a;                    \
-  } while (0)
-
-  gcry_assert (sizeof tv[0].data[0].input == sizeof scratch);
-  gcry_assert (sizeof tv[0].data[0].output == sizeof scratch);
-
-  for (tvi=0; tvi < DIM (tv); tvi++)
-    if (tv[tvi].mode == requested_mode)
-      break;
-  if (tvi == DIM (tv))
-    Fail ("no test data for this mode");
-
-  err = _gcry_cipher_open (&hdenc, GCRY_CIPHER_AES, tv[tvi].mode, 0);
-  if (err)
-    Fail ("open");
-  err = _gcry_cipher_open (&hddec, GCRY_CIPHER_AES, tv[tvi].mode, 0);
-  if (err)
-    Fail ("open");
-  err = _gcry_cipher_setkey (hdenc, tv[tvi].key,  sizeof tv[tvi].key);
-  if (!err)
-    err = _gcry_cipher_setkey (hddec, tv[tvi].key, sizeof tv[tvi].key);
-  if (err)
-    Fail ("set key");
-  err = _gcry_cipher_setiv (hdenc, tv[tvi].iv, sizeof tv[tvi].iv);
-  if (!err)
-    err = _gcry_cipher_setiv (hddec, tv[tvi].iv, sizeof tv[tvi].iv);
-  if (err)
-    Fail ("set IV");
-  for (idx=0; idx < DIM (tv[tvi].data); idx++)
-    {
-      err = _gcry_cipher_encrypt (hdenc, scratch, sizeof scratch,
-                                  tv[tvi].data[idx].input,
-                                  sizeof tv[tvi].data[idx].input);
-      if (err)
-        Fail ("encrypt command");
-      if (memcmp (scratch, tv[tvi].data[idx].output, sizeof scratch))
-        Fail ("encrypt mismatch");
-      err = _gcry_cipher_decrypt (hddec, scratch, sizeof scratch,
-                                  tv[tvi].data[idx].output,
-                                  sizeof tv[tvi].data[idx].output);
-      if (err)
-        Fail ("decrypt command");
-      if (memcmp (scratch, tv[tvi].data[idx].input, sizeof scratch))
-        Fail ("decrypt mismatch");
-    }
-
-#undef Fail
-  _gcry_cipher_close (hdenc);
-  _gcry_cipher_close (hddec); 
-  return NULL;
-}
-
-
-/* Complete selftest for AES-128 with all modes and driver code.  */
-static gpg_err_code_t
-selftest_fips_128 (int extended, selftest_report_func_t report)
-{
-  const char *what;
-  const char *errtxt;
-  
-  what = "low-level";
-  errtxt = selftest_basic_128 ();
-  if (errtxt)
-    goto failed;
-
-  if (extended)
-    {
-      what = "cfb";
-      errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_CFB);
-      if (errtxt)
-        goto failed;
-      
-      what = "ofb";
-      errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_OFB);
-      if (errtxt)
-        goto failed;
-    }
-
-  return 0; /* Succeeded. */
-
- failed:
-  if (report)
-    report ("cipher", GCRY_CIPHER_AES128, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-/* Complete selftest for AES-192.  */
-static gpg_err_code_t
-selftest_fips_192 (int extended, selftest_report_func_t report)
-{
-  const char *what;
-  const char *errtxt;
-
-  (void)extended; /* No extended tests available.  */
-
-  what = "low-level";
-  errtxt = selftest_basic_192 ();
-  if (errtxt)
-    goto failed;
-
-
-  return 0; /* Succeeded. */
-
- failed:
-  if (report)
-    report ("cipher", GCRY_CIPHER_AES192, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-
-/* Complete selftest for AES-256.  */
-static gpg_err_code_t
-selftest_fips_256 (int extended, selftest_report_func_t report)
-{
-  const char *what;
-  const char *errtxt;
-  
-  (void)extended; /* No extended tests available.  */
-
-  what = "low-level";
-  errtxt = selftest_basic_256 ();
-  if (errtxt)
-    goto failed;
-
-  return 0; /* Succeeded. */
-
- failed:
-  if (report)
-    report ("cipher", GCRY_CIPHER_AES256, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-
-
-/* Run a full self-test for ALGO and return 0 on success.  */
-static gpg_err_code_t
-run_selftests (int algo, int extended, selftest_report_func_t report)
-{
-  gpg_err_code_t ec;
-
-  switch (algo)
-    {
-    case GCRY_CIPHER_AES128:
-      ec = selftest_fips_128 (extended, report);
-      break;
-    case GCRY_CIPHER_AES192:
-      ec = selftest_fips_192 (extended, report);
-      break;
-    case GCRY_CIPHER_AES256:
-      ec = selftest_fips_256 (extended, report);
-      break;
-    default:
-      ec = GPG_ERR_CIPHER_ALGO;
-      break;
-        
-    }
-  return ec;
-}
-
-
-\f
-
-static const char *rijndael_names[] =
-  {
-    "RIJNDAEL",
-    "AES128",
-    "AES-128",
-    NULL
-  };
-
-static gcry_cipher_oid_spec_t rijndael_oids[] =
-  {
-    { "2.16.840.1.101.3.4.1.1", GCRY_CIPHER_MODE_ECB },
-    { "2.16.840.1.101.3.4.1.2", GCRY_CIPHER_MODE_CBC },
-    { "2.16.840.1.101.3.4.1.3", GCRY_CIPHER_MODE_OFB },
-    { "2.16.840.1.101.3.4.1.4", GCRY_CIPHER_MODE_CFB },
-    { NULL }
-  };
-
-gcry_cipher_spec_t _gcry_cipher_spec_aes =
-  {
-    "AES", rijndael_names, rijndael_oids, 16, 128, sizeof (RIJNDAEL_context),
-    rijndael_setkey, rijndael_encrypt, rijndael_decrypt
-  };
-cipher_extra_spec_t _gcry_cipher_extraspec_aes = 
-  {
-    run_selftests
-  };
-
-static const char *rijndael192_names[] =
-  {
-    "RIJNDAEL192",
-    "AES-192",
-    NULL
-  };
-
-static gcry_cipher_oid_spec_t rijndael192_oids[] =
-  {
-    { "2.16.840.1.101.3.4.1.21", GCRY_CIPHER_MODE_ECB },
-    { "2.16.840.1.101.3.4.1.22", GCRY_CIPHER_MODE_CBC },
-    { "2.16.840.1.101.3.4.1.23", GCRY_CIPHER_MODE_OFB },
-    { "2.16.840.1.101.3.4.1.24", GCRY_CIPHER_MODE_CFB },
-    { NULL }
-  };
-
-gcry_cipher_spec_t _gcry_cipher_spec_aes192 =
-  {
-    "AES192", rijndael192_names, rijndael192_oids, 16, 192, sizeof (RIJNDAEL_context),
-    rijndael_setkey, rijndael_encrypt, rijndael_decrypt
-  };
-cipher_extra_spec_t _gcry_cipher_extraspec_aes192 = 
-  {
-    run_selftests
-  };
-
-static const char *rijndael256_names[] =
-  {
-    "RIJNDAEL256",
-    "AES-256",
-    NULL
-  };
-
-static gcry_cipher_oid_spec_t rijndael256_oids[] =
-  {
-    { "2.16.840.1.101.3.4.1.41", GCRY_CIPHER_MODE_ECB },
-    { "2.16.840.1.101.3.4.1.42", GCRY_CIPHER_MODE_CBC },
-    { "2.16.840.1.101.3.4.1.43", GCRY_CIPHER_MODE_OFB },
-    { "2.16.840.1.101.3.4.1.44", GCRY_CIPHER_MODE_CFB },
-    { NULL }
-  };
-
-gcry_cipher_spec_t _gcry_cipher_spec_aes256 =
-  {
-    "AES256", rijndael256_names, rijndael256_oids, 16, 256,
-    sizeof (RIJNDAEL_context),
-    rijndael_setkey, rijndael_encrypt, rijndael_decrypt
-  };
-
-cipher_extra_spec_t _gcry_cipher_extraspec_aes256 = 
-  {
-    run_selftests
-  };
diff --git a/lib/libgcrypt/cipher/rmd.h b/lib/libgcrypt/cipher/rmd.h
deleted file mode 100644 (file)
index f4ce9c6..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* rmd.h - RIPE-MD hash functions
- *     Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef G10_RMD_H
-#define G10_RMD_H
-
-
-/* We need this here because random.c must have direct access. */
-typedef struct 
-{
-  u32  h0,h1,h2,h3,h4;
-  u32  nblocks;
-  byte buf[64];
-  int  count;
-} RMD160_CONTEXT;
-
-void _gcry_rmd160_init ( void *context );
-void _gcry_rmd160_mixblock ( RMD160_CONTEXT *hd, void *blockof64byte );
-
-#endif /*G10_RMD_H*/
-
diff --git a/lib/libgcrypt/cipher/rmd160.c b/lib/libgcrypt/cipher/rmd160.c
deleted file mode 100644 (file)
index 7805bf5..0000000
+++ /dev/null
@@ -1,572 +0,0 @@
-/* rmd160.c  - RIPE-MD160
- * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "g10lib.h"
-#include "memory.h"
-#include "rmd.h"
-#include "cipher.h" /* Only used for the rmd160_hash_buffer() prototype. */
-
-#include "bithelp.h"
-
-/*********************************
- * RIPEMD-160 is not patented, see (as of 25.10.97)
- *   http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
- * Note that the code uses Little Endian byteorder, which is good for
- * 386 etc, but we must add some conversion when used on a big endian box.
- *
- *
- * Pseudo-code for RIPEMD-160
- *
- * RIPEMD-160 is an iterative hash function that operates on 32-bit words.
- * The round function takes as input a 5-word chaining variable and a 16-word
- * message block and maps this to a new chaining variable. All operations are
- * defined on 32-bit words. Padding is identical to that of MD4.
- *
- *
- * RIPEMD-160: definitions
- *
- *
- *   nonlinear functions at bit level: exor, mux, -, mux, -
- *
- *   f(j, x, y, z) = x XOR y XOR z               (0 <= j <= 15)
- *   f(j, x, y, z) = (x AND y) OR (NOT(x) AND z)  (16 <= j <= 31)
- *   f(j, x, y, z) = (x OR NOT(y)) XOR z         (32 <= j <= 47)
- *   f(j, x, y, z) = (x AND z) OR (y AND NOT(z))  (48 <= j <= 63)
- *   f(j, x, y, z) = x XOR (y OR NOT(z))         (64 <= j <= 79)
- *
- *
- *   added constants (hexadecimal)
- *
- *   K(j) = 0x00000000     (0 <= j <= 15)
- *   K(j) = 0x5A827999    (16 <= j <= 31)      int(2**30 x sqrt(2))
- *   K(j) = 0x6ED9EBA1    (32 <= j <= 47)      int(2**30 x sqrt(3))
- *   K(j) = 0x8F1BBCDC    (48 <= j <= 63)      int(2**30 x sqrt(5))
- *   K(j) = 0xA953FD4E    (64 <= j <= 79)      int(2**30 x sqrt(7))
- *   K'(j) = 0x50A28BE6     (0 <= j <= 15)      int(2**30 x cbrt(2))
- *   K'(j) = 0x5C4DD124    (16 <= j <= 31)      int(2**30 x cbrt(3))
- *   K'(j) = 0x6D703EF3    (32 <= j <= 47)      int(2**30 x cbrt(5))
- *   K'(j) = 0x7A6D76E9    (48 <= j <= 63)      int(2**30 x cbrt(7))
- *   K'(j) = 0x00000000    (64 <= j <= 79)
- *
- *
- *   selection of message word
- *
- *   r(j)      = j                   (0 <= j <= 15)
- *   r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
- *   r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
- *   r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
- *   r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
- *   r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
- *   r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
- *   r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
- *   r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
- *   r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
- *
- *
- *   amount for rotate left (rol)
- *
- *   s(0..15)  = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
- *   s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
- *   s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
- *   s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
- *   s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
- *   s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
- *   s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
- *   s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
- *   s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
- *   s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
- *
- *
- *   initial value (hexadecimal)
- *
- *   h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
- *                                                     h4 = 0xC3D2E1F0;
- *
- *
- * RIPEMD-160: pseudo-code
- *
- *   It is assumed that the message after padding consists of t 16-word blocks
- *   that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15.
- *   The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left
- *   shift (rotate) over s positions.
- *
- *
- *   for i := 0 to t-1 {
- *      A := h0; B := h1; C := h2; D = h3; E = h4;
- *      A' := h0; B' := h1; C' := h2; D' = h3; E' = h4;
- *      for j := 0 to 79 {
- *          T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E;
- *          A := E; E := D; D := rol_10(C); C := B; B := T;
- *          T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)]
-                                                      [+] K'(j)) [+] E';
- *          A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
- *      }
- *      T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
- *      h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
- *   }
- */
-
-/* Some examples:
- * ""                    9c1185a5c5e9fc54612808977ee8f548b2258d31
- * "a"                   0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
- * "abc"                 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
- * "message digest"      5d0689ef49d2fae572b881b123a85ffa21595f36
- * "a...z"               f71c27109c692c1b56bbdceb5b9d2865b3708dbc
- * "abcdbcde...nopq"     12a053384a9c0c88e405a06c27dcf49ada62eb2b
- * "A...Za...z0...9"     b0e20b6e3116640286ed3a87a5713079b21f5189
- * 8 times "1234567890"  9b752e45573d4b39f4dbd3323cab82bf63326bfb
- * 1 million times "a"   52783243c1697bdbe16d37f97f68f08325dc1528
- */
-
-
-void
-_gcry_rmd160_init (void *context)
-{
-  RMD160_CONTEXT *hd = context;
-
-  hd->h0 = 0x67452301;
-  hd->h1 = 0xEFCDAB89;
-  hd->h2 = 0x98BADCFE;
-  hd->h3 = 0x10325476;
-  hd->h4 = 0xC3D2E1F0;
-  hd->nblocks = 0;
-  hd->count = 0;
-}
-
-
-
-/****************
- * Transform the message X which consists of 16 32-bit-words
- */
-static void
-transform ( RMD160_CONTEXT *hd, const unsigned char *data )
-{
-  register u32 a,b,c,d,e;
-  u32 aa,bb,cc,dd,ee,t;
-#ifdef WORDS_BIGENDIAN
-  u32 x[16];
-  {
-    int i;
-    byte *p2, *p1;
-    for (i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 )
-      {
-        p2[3] = *p1++;
-        p2[2] = *p1++;
-        p2[1] = *p1++;
-        p2[0] = *p1++;
-      }
-  }
-#else
-  /* This version is better because it is always aligned;
-   * The performance penalty on a 586-100 is about 6% which
-   * is acceptable - because the data is more local it might
-   * also be possible that this is faster on some machines.
-   * This function (when compiled with -02 on gcc 2.7.2)
-   * executes on a 586-100 (39.73 bogomips) at about 1900kb/sec;
-   * [measured with a 4MB data and "gpgm --print-md rmd160"] */
-  u32 x[16];
-  memcpy( x, data, 64 );
-#endif
-
-
-#define K0  0x00000000
-#define K1  0x5A827999
-#define K2  0x6ED9EBA1
-#define K3  0x8F1BBCDC
-#define K4  0xA953FD4E
-#define KK0 0x50A28BE6
-#define KK1 0x5C4DD124
-#define KK2 0x6D703EF3
-#define KK3 0x7A6D76E9
-#define KK4 0x00000000
-#define F0(x,y,z)   ( (x) ^ (y) ^ (z) )
-#define F1(x,y,z)   ( ((x) & (y)) | (~(x) & (z)) )
-#define F2(x,y,z)   ( ((x) | ~(y)) ^ (z) )
-#define F3(x,y,z)   ( ((x) & (z)) | ((y) & ~(z)) )
-#define F4(x,y,z)   ( (x) ^ ((y) | ~(z)) )
-#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
-                                 a = rol(t,s) + e;            \
-                                 c = rol(c,10);               \
-                               } while(0)
-
-  /* left lane */
-  a = hd->h0;
-  b = hd->h1;
-  c = hd->h2;
-  d = hd->h3;
-  e = hd->h4;
-  R( a, b, c, d, e, F0, K0,  0, 11 );
-  R( e, a, b, c, d, F0, K0,  1, 14 );
-  R( d, e, a, b, c, F0, K0,  2, 15 );
-  R( c, d, e, a, b, F0, K0,  3, 12 );
-  R( b, c, d, e, a, F0, K0,  4,  5 );
-  R( a, b, c, d, e, F0, K0,  5,  8 );
-  R( e, a, b, c, d, F0, K0,  6,  7 );
-  R( d, e, a, b, c, F0, K0,  7,  9 );
-  R( c, d, e, a, b, F0, K0,  8, 11 );
-  R( b, c, d, e, a, F0, K0,  9, 13 );
-  R( a, b, c, d, e, F0, K0, 10, 14 );
-  R( e, a, b, c, d, F0, K0, 11, 15 );
-  R( d, e, a, b, c, F0, K0, 12,  6 );
-  R( c, d, e, a, b, F0, K0, 13,  7 );
-  R( b, c, d, e, a, F0, K0, 14,  9 );
-  R( a, b, c, d, e, F0, K0, 15,  8 );
-  R( e, a, b, c, d, F1, K1,  7,  7 );
-  R( d, e, a, b, c, F1, K1,  4,  6 );
-  R( c, d, e, a, b, F1, K1, 13,  8 );
-  R( b, c, d, e, a, F1, K1,  1, 13 );
-  R( a, b, c, d, e, F1, K1, 10, 11 );
-  R( e, a, b, c, d, F1, K1,  6,  9 );
-  R( d, e, a, b, c, F1, K1, 15,  7 );
-  R( c, d, e, a, b, F1, K1,  3, 15 );
-  R( b, c, d, e, a, F1, K1, 12,  7 );
-  R( a, b, c, d, e, F1, K1,  0, 12 );
-  R( e, a, b, c, d, F1, K1,  9, 15 );
-  R( d, e, a, b, c, F1, K1,  5,  9 );
-  R( c, d, e, a, b, F1, K1,  2, 11 );
-  R( b, c, d, e, a, F1, K1, 14,  7 );
-  R( a, b, c, d, e, F1, K1, 11, 13 );
-  R( e, a, b, c, d, F1, K1,  8, 12 );
-  R( d, e, a, b, c, F2, K2,  3, 11 );
-  R( c, d, e, a, b, F2, K2, 10, 13 );
-  R( b, c, d, e, a, F2, K2, 14,  6 );
-  R( a, b, c, d, e, F2, K2,  4,  7 );
-  R( e, a, b, c, d, F2, K2,  9, 14 );
-  R( d, e, a, b, c, F2, K2, 15,  9 );
-  R( c, d, e, a, b, F2, K2,  8, 13 );
-  R( b, c, d, e, a, F2, K2,  1, 15 );
-  R( a, b, c, d, e, F2, K2,  2, 14 );
-  R( e, a, b, c, d, F2, K2,  7,  8 );
-  R( d, e, a, b, c, F2, K2,  0, 13 );
-  R( c, d, e, a, b, F2, K2,  6,  6 );
-  R( b, c, d, e, a, F2, K2, 13,  5 );
-  R( a, b, c, d, e, F2, K2, 11, 12 );
-  R( e, a, b, c, d, F2, K2,  5,  7 );
-  R( d, e, a, b, c, F2, K2, 12,  5 );
-  R( c, d, e, a, b, F3, K3,  1, 11 );
-  R( b, c, d, e, a, F3, K3,  9, 12 );
-  R( a, b, c, d, e, F3, K3, 11, 14 );
-  R( e, a, b, c, d, F3, K3, 10, 15 );
-  R( d, e, a, b, c, F3, K3,  0, 14 );
-  R( c, d, e, a, b, F3, K3,  8, 15 );
-  R( b, c, d, e, a, F3, K3, 12,  9 );
-  R( a, b, c, d, e, F3, K3,  4,  8 );
-  R( e, a, b, c, d, F3, K3, 13,  9 );
-  R( d, e, a, b, c, F3, K3,  3, 14 );
-  R( c, d, e, a, b, F3, K3,  7,  5 );
-  R( b, c, d, e, a, F3, K3, 15,  6 );
-  R( a, b, c, d, e, F3, K3, 14,  8 );
-  R( e, a, b, c, d, F3, K3,  5,  6 );
-  R( d, e, a, b, c, F3, K3,  6,  5 );
-  R( c, d, e, a, b, F3, K3,  2, 12 );
-  R( b, c, d, e, a, F4, K4,  4,  9 );
-  R( a, b, c, d, e, F4, K4,  0, 15 );
-  R( e, a, b, c, d, F4, K4,  5,  5 );
-  R( d, e, a, b, c, F4, K4,  9, 11 );
-  R( c, d, e, a, b, F4, K4,  7,  6 );
-  R( b, c, d, e, a, F4, K4, 12,  8 );
-  R( a, b, c, d, e, F4, K4,  2, 13 );
-  R( e, a, b, c, d, F4, K4, 10, 12 );
-  R( d, e, a, b, c, F4, K4, 14,  5 );
-  R( c, d, e, a, b, F4, K4,  1, 12 );
-  R( b, c, d, e, a, F4, K4,  3, 13 );
-  R( a, b, c, d, e, F4, K4,  8, 14 );
-  R( e, a, b, c, d, F4, K4, 11, 11 );
-  R( d, e, a, b, c, F4, K4,  6,  8 );
-  R( c, d, e, a, b, F4, K4, 15,  5 );
-  R( b, c, d, e, a, F4, K4, 13,  6 );
-
-  aa = a; bb = b; cc = c; dd = d; ee = e;
-
-  /* right lane */
-  a = hd->h0;
-  b = hd->h1;
-  c = hd->h2;
-  d = hd->h3;
-  e = hd->h4;
-  R( a, b, c, d, e, F4, KK0,   5,  8);
-  R( e, a, b, c, d, F4, KK0, 14,  9);
-  R( d, e, a, b, c, F4, KK0,   7,  9);
-  R( c, d, e, a, b, F4, KK0,   0, 11);
-  R( b, c, d, e, a, F4, KK0,   9, 13);
-  R( a, b, c, d, e, F4, KK0,   2, 15);
-  R( e, a, b, c, d, F4, KK0, 11, 15);
-  R( d, e, a, b, c, F4, KK0,   4,  5);
-  R( c, d, e, a, b, F4, KK0, 13,  7);
-  R( b, c, d, e, a, F4, KK0,   6,  7);
-  R( a, b, c, d, e, F4, KK0, 15,  8);
-  R( e, a, b, c, d, F4, KK0,   8, 11);
-  R( d, e, a, b, c, F4, KK0,   1, 14);
-  R( c, d, e, a, b, F4, KK0, 10, 14);
-  R( b, c, d, e, a, F4, KK0,   3, 12);
-  R( a, b, c, d, e, F4, KK0, 12,  6);
-  R( e, a, b, c, d, F3, KK1,   6,  9);
-  R( d, e, a, b, c, F3, KK1, 11, 13);
-  R( c, d, e, a, b, F3, KK1,   3, 15);
-  R( b, c, d, e, a, F3, KK1,   7,  7);
-  R( a, b, c, d, e, F3, KK1,   0, 12);
-  R( e, a, b, c, d, F3, KK1, 13,  8);
-  R( d, e, a, b, c, F3, KK1,   5,  9);
-  R( c, d, e, a, b, F3, KK1, 10, 11);
-  R( b, c, d, e, a, F3, KK1, 14,  7);
-  R( a, b, c, d, e, F3, KK1, 15,  7);
-  R( e, a, b, c, d, F3, KK1,   8, 12);
-  R( d, e, a, b, c, F3, KK1, 12,  7);
-  R( c, d, e, a, b, F3, KK1,   4,  6);
-  R( b, c, d, e, a, F3, KK1,   9, 15);
-  R( a, b, c, d, e, F3, KK1,   1, 13);
-  R( e, a, b, c, d, F3, KK1,   2, 11);
-  R( d, e, a, b, c, F2, KK2, 15,  9);
-  R( c, d, e, a, b, F2, KK2,   5,  7);
-  R( b, c, d, e, a, F2, KK2,   1, 15);
-  R( a, b, c, d, e, F2, KK2,   3, 11);
-  R( e, a, b, c, d, F2, KK2,   7,  8);
-  R( d, e, a, b, c, F2, KK2, 14,  6);
-  R( c, d, e, a, b, F2, KK2,   6,  6);
-  R( b, c, d, e, a, F2, KK2,   9, 14);
-  R( a, b, c, d, e, F2, KK2, 11, 12);
-  R( e, a, b, c, d, F2, KK2,   8, 13);
-  R( d, e, a, b, c, F2, KK2, 12,  5);
-  R( c, d, e, a, b, F2, KK2,   2, 14);
-  R( b, c, d, e, a, F2, KK2, 10, 13);
-  R( a, b, c, d, e, F2, KK2,   0, 13);
-  R( e, a, b, c, d, F2, KK2,   4,  7);
-  R( d, e, a, b, c, F2, KK2, 13,  5);
-  R( c, d, e, a, b, F1, KK3,   8, 15);
-  R( b, c, d, e, a, F1, KK3,   6,  5);
-  R( a, b, c, d, e, F1, KK3,   4,  8);
-  R( e, a, b, c, d, F1, KK3,   1, 11);
-  R( d, e, a, b, c, F1, KK3,   3, 14);
-  R( c, d, e, a, b, F1, KK3, 11, 14);
-  R( b, c, d, e, a, F1, KK3, 15,  6);
-  R( a, b, c, d, e, F1, KK3,   0, 14);
-  R( e, a, b, c, d, F1, KK3,   5,  6);
-  R( d, e, a, b, c, F1, KK3, 12,  9);
-  R( c, d, e, a, b, F1, KK3,   2, 12);
-  R( b, c, d, e, a, F1, KK3, 13,  9);
-  R( a, b, c, d, e, F1, KK3,   9, 12);
-  R( e, a, b, c, d, F1, KK3,   7,  5);
-  R( d, e, a, b, c, F1, KK3, 10, 15);
-  R( c, d, e, a, b, F1, KK3, 14,  8);
-  R( b, c, d, e, a, F0, KK4, 12,  8);
-  R( a, b, c, d, e, F0, KK4, 15,  5);
-  R( e, a, b, c, d, F0, KK4, 10, 12);
-  R( d, e, a, b, c, F0, KK4,   4,  9);
-  R( c, d, e, a, b, F0, KK4,   1, 12);
-  R( b, c, d, e, a, F0, KK4,   5,  5);
-  R( a, b, c, d, e, F0, KK4,   8, 14);
-  R( e, a, b, c, d, F0, KK4,   7,  6);
-  R( d, e, a, b, c, F0, KK4,   6,  8);
-  R( c, d, e, a, b, F0, KK4,   2, 13);
-  R( b, c, d, e, a, F0, KK4, 13,  6);
-  R( a, b, c, d, e, F0, KK4, 14,  5);
-  R( e, a, b, c, d, F0, KK4,   0, 15);
-  R( d, e, a, b, c, F0, KK4,   3, 13);
-  R( c, d, e, a, b, F0, KK4,   9, 11);
-  R( b, c, d, e, a, F0, KK4, 11, 11);
-
-
-  t       = hd->h1 + d + cc;
-  hd->h1 = hd->h2 + e + dd;
-  hd->h2 = hd->h3 + a + ee;
-  hd->h3 = hd->h4 + b + aa;
-  hd->h4 = hd->h0 + c + bb;
-  hd->h0 = t;
-}
-
-
-/* Update the message digest with the contents
- * of INBUF with length INLEN.
- */
-static void
-rmd160_write ( void *context, const void *inbuf_arg, size_t inlen)
-{
-  const unsigned char *inbuf = inbuf_arg;
-  RMD160_CONTEXT *hd = context;
-
-  if( hd->count == 64 )  /* flush the buffer */
-    {
-      transform( hd, hd->buf );
-      _gcry_burn_stack (108+5*sizeof(void*));
-      hd->count = 0;
-      hd->nblocks++;
-    }
-  if( !inbuf )
-    return;
-  if( hd->count ) 
-    {
-      for( ; inlen && hd->count < 64; inlen-- )
-        hd->buf[hd->count++] = *inbuf++;
-      rmd160_write( hd, NULL, 0 );
-      if( !inlen )
-        return;
-    }
-
-  while( inlen >= 64 )
-    {
-      transform( hd, inbuf );
-      hd->count = 0;
-      hd->nblocks++;
-      inlen -= 64;
-      inbuf += 64;
-    }
-  _gcry_burn_stack (108+5*sizeof(void*));
-  for( ; inlen && hd->count < 64; inlen-- )
-    hd->buf[hd->count++] = *inbuf++;
-}
-
-/****************
- * Apply the rmd160 transform function on the buffer which must have
- * a length 64 bytes. Do not use this function together with the
- * other functions, use rmd160_init to initialize internal variables.
- * Returns: 16 bytes in buffer with the mixed contentes of buffer.
- */
-void
-_gcry_rmd160_mixblock ( RMD160_CONTEXT *hd, void *blockof64byte )
-{
-  char *p = blockof64byte;
-
-  transform ( hd, blockof64byte );
-#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
-  X(0);
-  X(1);
-  X(2);
-  X(3);
-  X(4);
-#undef X
-}
-
-
-/* The routine terminates the computation
- */
-
-static void
-rmd160_final( void *context )
-{
-  RMD160_CONTEXT *hd = context;
-  u32 t, msb, lsb;
-  byte *p;
-  
-  rmd160_write(hd, NULL, 0); /* flush */;
-
-  t = hd->nblocks;
-  /* multiply by 64 to make a byte count */
-  lsb = t << 6;
-  msb = t >> 26;
-  /* add the count */
-  t = lsb;
-  if( (lsb += hd->count) < t )
-    msb++;
-  /* multiply by 8 to make a bit count */
-  t = lsb;
-  lsb <<= 3;
-  msb <<= 3;
-  msb |= t >> 29;
-
-  if( hd->count < 56 )  /* enough room */
-    {
-      hd->buf[hd->count++] = 0x80; /* pad */
-      while( hd->count < 56 )
-        hd->buf[hd->count++] = 0;  /* pad */
-    }
-  else  /* need one extra block */
-    {
-      hd->buf[hd->count++] = 0x80; /* pad character */
-      while( hd->count < 64 )
-        hd->buf[hd->count++] = 0;
-      rmd160_write(hd, NULL, 0);  /* flush */;
-      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
-    }
-  /* append the 64 bit count */
-  hd->buf[56] = lsb       ;
-  hd->buf[57] = lsb >>  8;
-  hd->buf[58] = lsb >> 16;
-  hd->buf[59] = lsb >> 24;
-  hd->buf[60] = msb       ;
-  hd->buf[61] = msb >>  8;
-  hd->buf[62] = msb >> 16;
-  hd->buf[63] = msb >> 24;
-  transform( hd, hd->buf );
-  _gcry_burn_stack (108+5*sizeof(void*));
-
-  p = hd->buf;
-#ifdef WORDS_BIGENDIAN
-#define X(a) do { *p++ = hd->h##a         ; *p++ = hd->h##a >> 8;      \
-                 *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
-#else /* little endian */
-#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
-#endif
-  X(0);
-  X(1);
-  X(2);
-  X(3);
-  X(4);
-#undef X
-}
-
-static byte *
-rmd160_read( void *context )
-{
-  RMD160_CONTEXT *hd = context;
-
-  return hd->buf;
-}
-
-
-
-/****************
- * Shortcut functions which puts the hash value of the supplied buffer
- * into outbuf which must have a size of 20 bytes.
- */
-void
-_gcry_rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length )
-{
-  RMD160_CONTEXT hd;
-
-  _gcry_rmd160_init ( &hd );
-  rmd160_write ( &hd, buffer, length );
-  rmd160_final ( &hd );
-  memcpy ( outbuf, hd.buf, 20 );
-}
-
-static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */
-  { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
-    0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
-
-static gcry_md_oid_spec_t oid_spec_rmd160[] =
-  {
-    /* rsaSignatureWithripemd160 */
-    { "1.3.36.3.3.1.2" },
-    /* TeleTrust hash algorithm.  */
-    { "1.3.36.3.2.1" },
-    { NULL }
-  };
-
-gcry_md_spec_t _gcry_digest_spec_rmd160 =
-  {
-    "RIPEMD160", asn, DIM (asn), oid_spec_rmd160, 20,
-    _gcry_rmd160_init, rmd160_write, rmd160_final, rmd160_read,
-    sizeof (RMD160_CONTEXT)
-  };
diff --git a/lib/libgcrypt/cipher/rsa.c b/lib/libgcrypt/cipher/rsa.c
deleted file mode 100644 (file)
index cf278c2..0000000
+++ /dev/null
@@ -1,1379 +0,0 @@
-/* rsa.c - RSA implementation
- * Copyright (C) 1997, 1998, 1999 by Werner Koch (dd9jn)
- * Copyright (C) 2000, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/* This code uses an algorithm protected by U.S. Patent #4,405,829
-   which expired on September 20, 2000.  The patent holder placed that
-   patent into the public domain on Sep 6th, 2000.
-*/
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#include "g10lib.h"
-#include "mpi.h"
-#include "cipher.h"
-
-
-typedef struct
-{
-  gcry_mpi_t n;            /* modulus */
-  gcry_mpi_t e;            /* exponent */
-} RSA_public_key;
-
-
-typedef struct
-{
-  gcry_mpi_t n;            /* public modulus */
-  gcry_mpi_t e;            /* public exponent */
-  gcry_mpi_t d;            /* exponent */
-  gcry_mpi_t p;            /* prime  p. */
-  gcry_mpi_t q;            /* prime  q. */
-  gcry_mpi_t u;            /* inverse of p mod q. */
-} RSA_secret_key;
-
-
-/* A sample 1024 bit RSA key used for the selftests.  */
-static const char sample_secret_key[] =
-"(private-key"
-" (rsa"
-"  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
-"      2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
-"      ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
-"      891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)"
-"  (e #010001#)"
-"  (d #046129f2489d71579be0a75fe029bd6cdb574ebf57ea8a5b0fda942cab943b11"
-"      7d7bb95e5d28875e0f9fc5fcc06a72f6d502464dabded78ef6b716177b83d5bd"
-"      c543dc5d3fed932e59f5897e92e6f58a0f33424106a3b6fa2cbf877510e4ac21"
-"      c3ee47851e97d12996222ac3566d4ccb0b83d164074abf7de655fc2446da1781#)"
-"  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
-"      fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)"
-"  (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
-"      35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)"
-"  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
-"      ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))";
-/* A sample 1024 bit RSA key used for the selftests (public only).  */
-static const char sample_public_key[] = 
-"(public-key"
-" (rsa"
-"  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
-"      2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
-"      ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
-"      891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)"
-"  (e #010001#)))";
-
-
-
-\f
-static int test_keys (RSA_secret_key *sk, unsigned nbits);
-static int  check_secret_key (RSA_secret_key *sk);
-static void public (gcry_mpi_t output, gcry_mpi_t input, RSA_public_key *skey);
-static void secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey);
-
-
-/* Check that a freshly generated key actually works.  Returns 0 on success. */
-static int
-test_keys (RSA_secret_key *sk, unsigned int nbits)
-{
-  int result = -1; /* Default to failure.  */
-  RSA_public_key pk;
-  gcry_mpi_t plaintext = gcry_mpi_new (nbits);
-  gcry_mpi_t ciphertext = gcry_mpi_new (nbits);
-  gcry_mpi_t decr_plaintext = gcry_mpi_new (nbits);
-  gcry_mpi_t signature = gcry_mpi_new (nbits);
-
-  /* Put the relevant parameters into a public key structure.  */
-  pk.n = sk->n;
-  pk.e = sk->e;
-
-  /* Create a random plaintext.  */
-  gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
-
-  /* Encrypt using the public key.  */
-  public (ciphertext, plaintext, &pk);
-
-  /* Check that the cipher text does not match the plaintext.  */
-  if (!gcry_mpi_cmp (ciphertext, plaintext))
-    goto leave; /* Ciphertext is identical to the plaintext.  */
-
-  /* Decrypt using the secret key.  */
-  secret (decr_plaintext, ciphertext, sk);
-
-  /* Check that the decrypted plaintext matches the original plaintext.  */
-  if (gcry_mpi_cmp (decr_plaintext, plaintext))
-    goto leave; /* Plaintext does not match.  */
-
-  /* Create another random plaintext as data for signature checking.  */
-  gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
-
-  /* Use the RSA secret function to create a signature of the plaintext.  */
-  secret (signature, plaintext, sk);
-  
-  /* Use the RSA public function to verify this signature.  */
-  public (decr_plaintext, signature, &pk);
-  if (gcry_mpi_cmp (decr_plaintext, plaintext))
-    goto leave; /* Signature does not match.  */
-
-  /* Modify the signature and check that the signing fails.  */
-  gcry_mpi_add_ui (signature, signature, 1);
-  public (decr_plaintext, signature, &pk);
-  if (!gcry_mpi_cmp (decr_plaintext, plaintext))
-    goto leave; /* Signature matches but should not.  */
-
-  result = 0; /* All tests succeeded.  */
-
- leave:
-  gcry_mpi_release (signature);
-  gcry_mpi_release (decr_plaintext);
-  gcry_mpi_release (ciphertext);
-  gcry_mpi_release (plaintext);
-  return result;
-}
-
-
-/* Callback used by the prime generation to test whether the exponent
-   is suitable. Returns 0 if the test has been passed. */
-static int
-check_exponent (void *arg, gcry_mpi_t a)
-{
-  gcry_mpi_t e = arg;
-  gcry_mpi_t tmp;
-  int result;
-  
-  mpi_sub_ui (a, a, 1);
-  tmp = _gcry_mpi_alloc_like (a);
-  result = !gcry_mpi_gcd(tmp, e, a); /* GCD is not 1. */
-  gcry_mpi_release (tmp);
-  mpi_add_ui (a, a, 1);
-  return result;
-}
-
-/****************
- * Generate a key pair with a key of size NBITS.  
- * USE_E = 0 let Libcgrypt decide what exponent to use.
- *       = 1 request the use of a "secure" exponent; this is required by some 
- *           specification to be 65537.
- *       > 2 Use this public exponent.  If the given exponent
- *           is not odd one is internally added to it. 
- * TRANSIENT_KEY:  If true, generate the primes using the standard RNG.
- * Returns: 2 structures filled with all needed values
- */
-static gpg_err_code_t
-generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
-              int transient_key)
-{
-  gcry_mpi_t p, q; /* the two primes */
-  gcry_mpi_t d;    /* the private key */
-  gcry_mpi_t u;
-  gcry_mpi_t t1, t2;
-  gcry_mpi_t n;    /* the public key */
-  gcry_mpi_t e;    /* the exponent */
-  gcry_mpi_t phi;  /* helper: (p-1)(q-1) */
-  gcry_mpi_t g;
-  gcry_mpi_t f;
-  gcry_random_level_t random_level;
-
-  if (fips_mode ())
-    {
-      if (nbits < 1024)
-        return GPG_ERR_INV_VALUE;
-      if (transient_key)
-        return GPG_ERR_INV_VALUE;
-    }
-
-  /* The random quality depends on the transient_key flag.  */
-  random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
-
-  /* Make sure that nbits is even so that we generate p, q of equal size. */
-  if ( (nbits&1) )
-    nbits++; 
-
-  if (use_e == 1)   /* Alias for a secure value */
-    use_e = 65537;  /* as demanded by Sphinx. */
-
-  /* Public exponent:
-     In general we use 41 as this is quite fast and more secure than the
-     commonly used 17.  Benchmarking the RSA verify function
-     with a 1024 bit key yields (2001-11-08): 
-     e=17    0.54 ms
-     e=41    0.75 ms
-     e=257   0.95 ms
-     e=65537 1.80 ms
-  */
-  e = mpi_alloc( (32+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
-  if (!use_e)
-    mpi_set_ui (e, 41);     /* This is a reasonable secure and fast value */
-  else 
-    {
-      use_e |= 1; /* make sure this is odd */
-      mpi_set_ui (e, use_e); 
-    }
-    
-  n = gcry_mpi_new (nbits);
-
-  p = q = NULL;
-  do
-    {
-      /* select two (very secret) primes */
-      if (p)
-        gcry_mpi_release (p);
-      if (q)
-        gcry_mpi_release (q);
-      if (use_e)
-        { /* Do an extra test to ensure that the given exponent is
-             suitable. */
-          p = _gcry_generate_secret_prime (nbits/2, random_level,
-                                           check_exponent, e);
-          q = _gcry_generate_secret_prime (nbits/2, random_level,
-                                           check_exponent, e);
-        }
-      else
-        { /* We check the exponent later. */
-          p = _gcry_generate_secret_prime (nbits/2, random_level, NULL, NULL);
-          q = _gcry_generate_secret_prime (nbits/2, random_level, NULL, NULL);
-        }
-      if (mpi_cmp (p, q) > 0 ) /* p shall be smaller than q (for calc of u)*/
-        mpi_swap(p,q);
-      /* calculate the modulus */
-      mpi_mul( n, p, q );
-    }
-  while ( mpi_get_nbits(n) != nbits );
-
-  /* calculate Euler totient: phi = (p-1)(q-1) */
-  t1 = mpi_alloc_secure( mpi_get_nlimbs(p) );
-  t2 = mpi_alloc_secure( mpi_get_nlimbs(p) );
-  phi = gcry_mpi_snew ( nbits );
-  g    = gcry_mpi_snew ( nbits );
-  f    = gcry_mpi_snew ( nbits );
-  mpi_sub_ui( t1, p, 1 );
-  mpi_sub_ui( t2, q, 1 );
-  mpi_mul( phi, t1, t2 );
-  gcry_mpi_gcd(g, t1, t2);
-  mpi_fdiv_q(f, phi, g);
-
-  while (!gcry_mpi_gcd(t1, e, phi)) /* (while gcd is not 1) */
-    {
-      if (use_e)
-        BUG (); /* The prime generator already made sure that we
-                   never can get to here. */
-      mpi_add_ui (e, e, 2);
-    }
-
-  /* calculate the secret key d = e^1 mod phi */
-  d = gcry_mpi_snew ( nbits );
-  mpi_invm(d, e, f );
-  /* calculate the inverse of p and q (used for chinese remainder theorem)*/
-  u = gcry_mpi_snew ( nbits );
-  mpi_invm(u, p, q );
-
-  if( DBG_CIPHER )
-    {
-      log_mpidump("  p= ", p );
-      log_mpidump("  q= ", q );
-      log_mpidump("phi= ", phi );
-      log_mpidump("  g= ", g );
-      log_mpidump("  f= ", f );
-      log_mpidump("  n= ", n );
-      log_mpidump("  e= ", e );
-      log_mpidump("  d= ", d );
-      log_mpidump("  u= ", u );
-    }
-
-  gcry_mpi_release (t1);
-  gcry_mpi_release (t2);
-  gcry_mpi_release (phi);
-  gcry_mpi_release (f);
-  gcry_mpi_release (g);
-
-  sk->n = n;
-  sk->e = e;
-  sk->p = p;
-  sk->q = q;
-  sk->d = d;
-  sk->u = u;
-
-  /* Now we can test our keys. */
-  if (test_keys (sk, nbits - 64))
-    {
-      gcry_mpi_release (sk->n); sk->n = NULL;
-      gcry_mpi_release (sk->e); sk->e = NULL;
-      gcry_mpi_release (sk->p); sk->p = NULL;
-      gcry_mpi_release (sk->q); sk->q = NULL;
-      gcry_mpi_release (sk->d); sk->d = NULL;
-      gcry_mpi_release (sk->u); sk->u = NULL;
-      fips_signal_error ("self-test after key generation failed");
-      return GPG_ERR_SELFTEST_FAILED;
-    }
-
-  return 0;
-}
-
-
-/* Helper for generate_x931.  */
-static gcry_mpi_t 
-gen_x931_parm_xp (unsigned int nbits)
-{
-  gcry_mpi_t xp;
-
-  xp = gcry_mpi_snew (nbits);
-  gcry_mpi_randomize (xp, nbits, GCRY_VERY_STRONG_RANDOM);
-      
-  /* The requirement for Xp is:
-
-       sqrt{2}*2^{nbits-1} <= xp <= 2^{nbits} - 1
-
-     We set the two high order bits to 1 to satisfy the lower bound.
-     By using mpi_set_highbit we make sure that the upper bound is
-     satisfied as well.  */
-  mpi_set_highbit (xp, nbits-1);
-  mpi_set_bit (xp, nbits-2);
-  gcry_assert ( mpi_get_nbits (xp) == nbits );
-  
-  return xp;
-}     
-
-
-/* Helper for generate_x931.  */
-static gcry_mpi_t 
-gen_x931_parm_xi (void)
-{
-  gcry_mpi_t xi;
-
-  xi = gcry_mpi_snew (101);
-  gcry_mpi_randomize (xi, 101, GCRY_VERY_STRONG_RANDOM);
-  mpi_set_highbit (xi, 100);
-  gcry_assert ( mpi_get_nbits (xi) == 101 );
-  
-  return xi;
-}     
-
-
-
-/* Variant of the standard key generation code using the algorithm
-   from X9.31.  Using this algorithm has the advantage that the
-   generation can be made deterministic which is required for CAVS
-   testing.  */
-static gpg_err_code_t
-generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value,
-               gcry_sexp_t deriveparms, int *swapped)
-{
-  gcry_mpi_t p, q; /* The two primes.  */
-  gcry_mpi_t e;    /* The public exponent.  */
-  gcry_mpi_t n;    /* The public key.  */
-  gcry_mpi_t d;    /* The private key */
-  gcry_mpi_t u;    /* The inverse of p and q.  */
-  gcry_mpi_t pm1;  /* p - 1  */
-  gcry_mpi_t qm1;  /* q - 1  */
-  gcry_mpi_t phi;  /* Euler totient.  */
-  gcry_mpi_t f, g; /* Helper.  */
-
-  *swapped = 0;
-
-  if (e_value == 1)   /* Alias for a secure value. */
-    e_value = 65537; 
-
-  /* Point 1 of section 4.1:  k = 1024 + 256s with S >= 0  */
-  if (nbits < 1024 || (nbits % 256))
-    return GPG_ERR_INV_VALUE;
-  
-  /* Point 2:  2 <= bitlength(e) < 2^{k-2}
-     Note that we do not need to check the upper bound because we use
-     an unsigned long for E and thus there is no way for E to reach
-     that limit.  */
-  if (e_value < 3)
-    return GPG_ERR_INV_VALUE;
-     
-  /* Our implementaion requires E to be odd.  */
-  if (!(e_value & 1))
-    return GPG_ERR_INV_VALUE;
-
-  /* Point 3:  e > 0 or e 0 if it is to be randomly generated.
-     We support only a fixed E and thus there is no need for an extra test.  */
-
-
-  /* Compute or extract the derive parameters.  */
-  {
-    gcry_mpi_t xp1 = NULL;
-    gcry_mpi_t xp2 = NULL;
-    gcry_mpi_t xp  = NULL;
-    gcry_mpi_t xq1 = NULL;
-    gcry_mpi_t xq2 = NULL;
-    gcry_mpi_t xq  = NULL;
-    gcry_mpi_t tmpval;
-
-    if (!deriveparms)
-      {
-        /* Not given: Generate them.  */
-        xp = gen_x931_parm_xp (nbits/2);
-        /* Make sure that |xp - xq| > 2^{nbits - 100} holds.  */
-        tmpval = gcry_mpi_snew (nbits/2);
-        do
-          {
-            gcry_mpi_release (xq);
-            xq = gen_x931_parm_xp (nbits/2);
-            mpi_sub (tmpval, xp, xq);
-          }
-        while (mpi_get_nbits (tmpval) <= (nbits/2 - 100));
-        gcry_mpi_release (tmpval);
-
-        xp1 = gen_x931_parm_xi ();
-        xp2 = gen_x931_parm_xi ();
-        xq1 = gen_x931_parm_xi ();
-        xq2 = gen_x931_parm_xi ();
-
-      }
-    else
-      {
-        /* Parameters to derive the key are given.  */
-        struct { const char *name; gcry_mpi_t *value; } tbl[] = {
-          { "Xp1", &xp1 },
-          { "Xp2", &xp2 },
-          { "Xp",  &xp  },
-          { "Xq1", &xq1 },
-          { "Xq2", &xq2 },
-          { "Xq",  &xq  },
-          { NULL,  NULL }
-        };
-        int idx;
-        gcry_sexp_t oneparm;
-        
-        for (idx=0; tbl[idx].name; idx++)
-          {
-            oneparm = gcry_sexp_find_token (deriveparms, tbl[idx].name, 0);
-            if (oneparm)
-              {
-                *tbl[idx].value = gcry_sexp_nth_mpi (oneparm, 1,
-                                                     GCRYMPI_FMT_USG);
-                gcry_sexp_release (oneparm);
-              }
-          }
-        for (idx=0; tbl[idx].name; idx++)
-          if (!*tbl[idx].value)
-            break;
-        if (tbl[idx].name)
-          {
-            /* At least one parameter is missing.  */
-            for (idx=0; tbl[idx].name; idx++)
-              gcry_mpi_release (*tbl[idx].value);
-            return GPG_ERR_MISSING_VALUE;
-          }
-      }
-    
-    e = mpi_alloc_set_ui (e_value); 
-
-    /* Find two prime numbers.  */
-    p = _gcry_derive_x931_prime (xp, xp1, xp2, e, NULL, NULL);
-    q = _gcry_derive_x931_prime (xq, xq1, xq2, e, NULL, NULL);
-    gcry_mpi_release (xp);  xp  = NULL;
-    gcry_mpi_release (xp1); xp1 = NULL;
-    gcry_mpi_release (xp2); xp2 = NULL;
-    gcry_mpi_release (xq);  xq  = NULL; 
-    gcry_mpi_release (xq1); xq1 = NULL;
-    gcry_mpi_release (xq2); xq2 = NULL;
-    if (!p || !q)
-      {
-        gcry_mpi_release (p);
-        gcry_mpi_release (q);
-        gcry_mpi_release (e);
-        return GPG_ERR_NO_PRIME;
-      }
-  }
-
-
-  /* Compute the public modulus.  We make sure that p is smaller than
-     q to allow the use of the CRT.  */
-  if (mpi_cmp (p, q) > 0 )
-    {
-      mpi_swap (p, q);
-      *swapped = 1;
-    }
-  n = gcry_mpi_new (nbits);
-  mpi_mul (n, p, q);
-
-  /* Compute the Euler totient:  phi = (p-1)(q-1)  */
-  pm1 = gcry_mpi_snew (nbits/2);
-  qm1 = gcry_mpi_snew (nbits/2);
-  phi = gcry_mpi_snew (nbits);
-  mpi_sub_ui (pm1, p, 1);
-  mpi_sub_ui (qm1, q, 1);
-  mpi_mul (phi, pm1, qm1);
-
-  g = gcry_mpi_snew (nbits);
-  gcry_assert (gcry_mpi_gcd (g, e, phi));
-
-  /* Compute: f = lcm(p-1,q-1) = phi / gcd(p-1,q-1) */
-  gcry_mpi_gcd (g, pm1, qm1);
-  f = pm1; pm1 = NULL;
-  gcry_mpi_release (qm1); qm1 = NULL;
-  mpi_fdiv_q (f, phi, g);
-  gcry_mpi_release (phi); phi = NULL;
-  d = g; g = NULL;
-  /* Compute the secret key:  d = e^{-1} mod lcm(p-1,q-1) */
-  mpi_invm (d, e, f);
-
-  /* Compute the inverse of p and q.  */
-  u = f; f = NULL;
-  mpi_invm (u, p, q );
-
-  if( DBG_CIPHER )
-    {
-      if (*swapped)
-        log_debug ("p and q are swapped\n");
-      log_mpidump("  p", p );
-      log_mpidump("  q", q );
-      log_mpidump("  n", n );
-      log_mpidump("  e", e );
-      log_mpidump("  d", d );
-      log_mpidump("  u", u );
-    }
-
-
-  sk->n = n;
-  sk->e = e;
-  sk->p = p;
-  sk->q = q;
-  sk->d = d;
-  sk->u = u;
-
-  /* Now we can test our keys. */
-  if (test_keys (sk, nbits - 64))
-    {
-      gcry_mpi_release (sk->n); sk->n = NULL;
-      gcry_mpi_release (sk->e); sk->e = NULL;
-      gcry_mpi_release (sk->p); sk->p = NULL;
-      gcry_mpi_release (sk->q); sk->q = NULL;
-      gcry_mpi_release (sk->d); sk->d = NULL;
-      gcry_mpi_release (sk->u); sk->u = NULL;
-      fips_signal_error ("self-test after key generation failed");
-      return GPG_ERR_SELFTEST_FAILED;
-    }
-
-  return 0;
-}
-
-
-/****************
- * Test wether the secret key is valid.
- * Returns: true if this is a valid key.
- */
-static int
-check_secret_key( RSA_secret_key *sk )
-{
-  int rc;
-  gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(sk->p)*2 );
-  
-  mpi_mul(temp, sk->p, sk->q );
-  rc = mpi_cmp( temp, sk->n );
-  mpi_free(temp);
-  return !rc;
-}
-
-
-
-/****************
- * Public key operation. Encrypt INPUT with PKEY and put result into OUTPUT.
- *
- *     c = m^e mod n
- *
- * Where c is OUTPUT, m is INPUT and e,n are elements of PKEY.
- */
-static void
-public(gcry_mpi_t output, gcry_mpi_t input, RSA_public_key *pkey )
-{
-  if( output == input )  /* powm doesn't like output and input the same */
-    {
-      gcry_mpi_t x = mpi_alloc( mpi_get_nlimbs(input)*2 );
-      mpi_powm( x, input, pkey->e, pkey->n );
-      mpi_set(output, x);
-      mpi_free(x);
-    }
-  else
-    mpi_powm( output, input, pkey->e, pkey->n );
-}
-
-#if 0
-static void
-stronger_key_check ( RSA_secret_key *skey )
-{
-  gcry_mpi_t t = mpi_alloc_secure ( 0 );
-  gcry_mpi_t t1 = mpi_alloc_secure ( 0 );
-  gcry_mpi_t t2 = mpi_alloc_secure ( 0 );
-  gcry_mpi_t phi = mpi_alloc_secure ( 0 );
-
-  /* check that n == p * q */
-  mpi_mul( t, skey->p, skey->q);
-  if (mpi_cmp( t, skey->n) )
-    log_info ( "RSA Oops: n != p * q\n" );
-
-  /* check that p is less than q */
-  if( mpi_cmp( skey->p, skey->q ) > 0 )
-    {
-      log_info ("RSA Oops: p >= q - fixed\n");
-      _gcry_mpi_swap ( skey->p, skey->q);
-    }
-
-    /* check that e divides neither p-1 nor q-1 */
-    mpi_sub_ui(t, skey->p, 1 );
-    mpi_fdiv_r(t, t, skey->e );
-    if ( !mpi_cmp_ui( t, 0) )
-        log_info ( "RSA Oops: e divides p-1\n" );
-    mpi_sub_ui(t, skey->q, 1 );
-    mpi_fdiv_r(t, t, skey->e );
-    if ( !mpi_cmp_ui( t, 0) )
-        log_info ( "RSA Oops: e divides q-1\n" );
-
-    /* check that d is correct */
-    mpi_sub_ui( t1, skey->p, 1 );
-    mpi_sub_ui( t2, skey->q, 1 );
-    mpi_mul( phi, t1, t2 );
-    gcry_mpi_gcd(t, t1, t2);
-    mpi_fdiv_q(t, phi, t);
-    mpi_invm(t, skey->e, t );
-    if ( mpi_cmp(t, skey->d ) )
-      {
-        log_info ( "RSA Oops: d is wrong - fixed\n");
-        mpi_set (skey->d, t);
-        _gcry_log_mpidump ("  fixed d", skey->d);
-      }
-
-    /* check for correctness of u */
-    mpi_invm(t, skey->p, skey->q );
-    if ( mpi_cmp(t, skey->u ) )
-      {
-        log_info ( "RSA Oops: u is wrong - fixed\n");
-        mpi_set (skey->u, t);
-        _gcry_log_mpidump ("  fixed u", skey->u);
-      }
-
-    log_info ( "RSA secret key check finished\n");
-
-    mpi_free (t);
-    mpi_free (t1);
-    mpi_free (t2);
-    mpi_free (phi);
-}
-#endif
-
-
-
-/****************
- * Secret key operation. Encrypt INPUT with SKEY and put result into OUTPUT.
- *
- *     m = c^d mod n
- *
- * Or faster:
- *
- *      m1 = c ^ (d mod (p-1)) mod p 
- *      m2 = c ^ (d mod (q-1)) mod q 
- *      h = u * (m2 - m1) mod q 
- *      m = m1 + h * p
- *
- * Where m is OUTPUT, c is INPUT and d,n,p,q,u are elements of SKEY.
- */
-static void
-secret(gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
-{
-  if (!skey->p || !skey->q || !skey->u)
-    {
-      mpi_powm (output, input, skey->d, skey->n);
-    }
-  else
-    {
-      gcry_mpi_t m1 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
-      gcry_mpi_t m2 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
-      gcry_mpi_t h  = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
-      
-      /* m1 = c ^ (d mod (p-1)) mod p */
-      mpi_sub_ui( h, skey->p, 1  );
-      mpi_fdiv_r( h, skey->d, h );   
-      mpi_powm( m1, input, h, skey->p );
-      /* m2 = c ^ (d mod (q-1)) mod q */
-      mpi_sub_ui( h, skey->q, 1  );
-      mpi_fdiv_r( h, skey->d, h );
-      mpi_powm( m2, input, h, skey->q );
-      /* h = u * ( m2 - m1 ) mod q */
-      mpi_sub( h, m2, m1 );
-      if ( mpi_is_neg( h ) ) 
-        mpi_add ( h, h, skey->q );
-      mpi_mulm( h, skey->u, h, skey->q ); 
-      /* m = m2 + h * p */
-      mpi_mul ( h, h, skey->p );
-      mpi_add ( output, m1, h );
-    
-      mpi_free ( h );
-      mpi_free ( m1 );
-      mpi_free ( m2 );
-    }
-}
-
-
-
-/* Perform RSA blinding.  */
-static gcry_mpi_t
-rsa_blind (gcry_mpi_t x, gcry_mpi_t r, gcry_mpi_t e, gcry_mpi_t n)
-{
-  /* A helper.  */
-  gcry_mpi_t a;
-
-  /* Result.  */
-  gcry_mpi_t y;
-
-  a = gcry_mpi_snew (gcry_mpi_get_nbits (n));
-  y = gcry_mpi_snew (gcry_mpi_get_nbits (n));
-  
-  /* Now we calculate: y = (x * r^e) mod n, where r is the random
-     number, e is the public exponent, x is the non-blinded data and n
-     is the RSA modulus.  */
-  gcry_mpi_powm (a, r, e, n);
-  gcry_mpi_mulm (y, a, x, n);
-
-  gcry_mpi_release (a);
-
-  return y;
-}
-
-/* Undo RSA blinding.  */
-static gcry_mpi_t
-rsa_unblind (gcry_mpi_t x, gcry_mpi_t ri, gcry_mpi_t n)
-{
-  gcry_mpi_t y;
-
-  y = gcry_mpi_snew (gcry_mpi_get_nbits (n));
-
-  /* Here we calculate: y = (x * r^-1) mod n, where x is the blinded
-     decrypted data, ri is the modular multiplicative inverse of r and
-     n is the RSA modulus.  */
-
-  gcry_mpi_mulm (y, ri, x, n);
-
-  return y;
-}
-
-/*********************************************
- **************  interface  ******************
- *********************************************/
-
-static gcry_err_code_t
-rsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
-                  const gcry_sexp_t genparms,
-                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
-                  gcry_sexp_t *r_extrainfo)
-{
-  RSA_secret_key sk;
-  gpg_err_code_t ec;
-  gcry_sexp_t deriveparms;
-  int transient_key = 0;
-  int use_x931 = 0;
-  gcry_sexp_t l1;
-
-  (void)algo;
-  
-  *retfactors = NULL; /* We don't return them.  */
-
-  deriveparms = (genparms?
-                 gcry_sexp_find_token (genparms, "derive-parms", 0) : NULL);
-  if (!deriveparms)
-    {
-      /* Parse the optional "use-x931" flag. */
-      l1 = gcry_sexp_find_token (genparms, "use-x931", 0);
-      if (l1)
-        {
-          use_x931 = 1;
-          gcry_sexp_release (l1);
-        }
-    }
-
-  if (deriveparms || use_x931 || fips_mode ())
-    {
-      int swapped;
-      ec = generate_x931 (&sk, nbits, evalue, deriveparms, &swapped);
-      gcry_sexp_release (deriveparms);
-      if (!ec && r_extrainfo && swapped)
-        {
-          ec = gcry_sexp_new (r_extrainfo, 
-                              "(misc-key-info(p-q-swapped))", 0, 1);
-          if (ec)
-            {
-              gcry_mpi_release (sk.n); sk.n = NULL;
-              gcry_mpi_release (sk.e); sk.e = NULL;
-              gcry_mpi_release (sk.p); sk.p = NULL;
-              gcry_mpi_release (sk.q); sk.q = NULL;
-              gcry_mpi_release (sk.d); sk.d = NULL;
-              gcry_mpi_release (sk.u); sk.u = NULL;
-            }
-        }
-    }
-  else
-    {
-      /* Parse the optional "transient-key" flag. */
-      l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
-      if (l1)
-        {
-          transient_key = 1;
-          gcry_sexp_release (l1);
-        }
-      /* Generate.  */
-      ec = generate_std (&sk, nbits, evalue, transient_key);
-    }
-
-  if (!ec)
-    {
-      skey[0] = sk.n;
-      skey[1] = sk.e;
-      skey[2] = sk.d;
-      skey[3] = sk.p;
-      skey[4] = sk.q;
-      skey[5] = sk.u;
-    }
-  
-  return ec;
-}
-
-
-static gcry_err_code_t
-rsa_generate (int algo, unsigned int nbits, unsigned long evalue,
-              gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-{
-  return rsa_generate_ext (algo, nbits, evalue, NULL, skey, retfactors, NULL);
-}
-
-
-static gcry_err_code_t
-rsa_check_secret_key (int algo, gcry_mpi_t *skey)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  RSA_secret_key sk;
-
-  (void)algo;
-
-  sk.n = skey[0];
-  sk.e = skey[1];
-  sk.d = skey[2];
-  sk.p = skey[3];
-  sk.q = skey[4];
-  sk.u = skey[5];
-
-  if (!sk.p || !sk.q || !sk.u)
-    err = GPG_ERR_NO_OBJ;  /* To check the key we need the optional
-                              parameters. */
-  else if (!check_secret_key (&sk))
-    err = GPG_ERR_PUBKEY_ALGO;
-
-  return err;
-}
-
-
-static gcry_err_code_t
-rsa_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
-             gcry_mpi_t *pkey, int flags)
-{
-  RSA_public_key pk;
-
-  (void)algo;
-  (void)flags;
-  
-  pk.n = pkey[0];
-  pk.e = pkey[1];
-  resarr[0] = mpi_alloc (mpi_get_nlimbs (pk.n));
-  public (resarr[0], data, &pk);
-  
-  return GPG_ERR_NO_ERROR;
-}
-
-
-static gcry_err_code_t
-rsa_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
-             gcry_mpi_t *skey, int flags)
-{
-  RSA_secret_key sk;
-  gcry_mpi_t r = MPI_NULL;     /* Random number needed for blinding.  */
-  gcry_mpi_t ri = MPI_NULL;    /* Modular multiplicative inverse of
-                                  r.  */
-  gcry_mpi_t x = MPI_NULL;     /* Data to decrypt.  */
-  gcry_mpi_t y;                        /* Result.  */
-
-  (void)algo;
-
-  /* Extract private key.  */
-  sk.n = skey[0];
-  sk.e = skey[1];
-  sk.d = skey[2];
-  sk.p = skey[3]; /* Optional. */
-  sk.q = skey[4]; /* Optional. */
-  sk.u = skey[5]; /* Optional. */
-
-  y = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
-
-  /* We use blinding by default to mitigate timing attacks which can
-     be practically mounted over the network as shown by Brumley and
-     Boney in 2003.  */ 
-  if (! (flags & PUBKEY_FLAG_NO_BLINDING))
-    {
-      /* Initialize blinding.  */
-      
-      /* First, we need a random number r between 0 and n - 1, which
-        is relatively prime to n (i.e. it is neither p nor q).  The
-        random number needs to be only unpredictable, thus we employ
-        the gcry_create_nonce function by using GCRY_WEAK_RANDOM with
-        gcry_mpi_randomize.  */
-      r = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
-      ri = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
-      
-      gcry_mpi_randomize (r, gcry_mpi_get_nbits (sk.n), GCRY_WEAK_RANDOM);
-      gcry_mpi_mod (r, r, sk.n);
-
-      /* Calculate inverse of r.  It practically impossible that the
-         follwing test fails, thus we do not add code to release
-         allocated resources.  */
-      if (!gcry_mpi_invm (ri, r, sk.n))
-       return GPG_ERR_INTERNAL;
-    }
-
-  if (! (flags & PUBKEY_FLAG_NO_BLINDING))
-    x = rsa_blind (data[0], r, sk.e, sk.n);
-  else
-    x = data[0];
-
-  /* Do the encryption.  */
-  secret (y, x, &sk);
-
-  if (! (flags & PUBKEY_FLAG_NO_BLINDING))
-    {
-      /* Undo blinding.  */
-      gcry_mpi_t a = gcry_mpi_copy (y);
-      
-      gcry_mpi_release (y);
-      y = rsa_unblind (a, ri, sk.n);
-
-      gcry_mpi_release (a);
-    }
-
-  if (! (flags & PUBKEY_FLAG_NO_BLINDING))
-    {
-      /* Deallocate resources needed for blinding.  */
-      gcry_mpi_release (x);
-      gcry_mpi_release (r);
-      gcry_mpi_release (ri);
-    }
-
-  /* Copy out result.  */
-  *result = y;
-  
-  return GPG_ERR_NO_ERROR;
-}
-
-
-static gcry_err_code_t
-rsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
-{
-  RSA_secret_key sk;
-
-  (void)algo;
-  
-  sk.n = skey[0];
-  sk.e = skey[1];
-  sk.d = skey[2];
-  sk.p = skey[3];
-  sk.q = skey[4];
-  sk.u = skey[5];
-  resarr[0] = mpi_alloc( mpi_get_nlimbs (sk.n));
-  secret (resarr[0], data, &sk);
-
-  return GPG_ERR_NO_ERROR;
-}
-
-
-static gcry_err_code_t
-rsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
-                 int (*cmp) (void *opaque, gcry_mpi_t tmp),
-                 void *opaquev)
-{
-  RSA_public_key pk;
-  gcry_mpi_t result;
-  gcry_err_code_t rc;
-
-  (void)algo;
-  (void)cmp;
-  (void)opaquev;
-
-  pk.n = pkey[0];
-  pk.e = pkey[1];
-  result = gcry_mpi_new ( 160 );
-  public( result, data[0], &pk );
-#ifdef IS_DEVELOPMENT_VERSION
-  if (DBG_CIPHER)
-    {
-      log_mpidump ("rsa verify result:", result );
-      log_mpidump ("             hash:", hash );
-    }
-#endif /*IS_DEVELOPMENT_VERSION*/
-  /*rc = (*cmp)( opaquev, result );*/
-  rc = mpi_cmp (result, hash) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR;
-  gcry_mpi_release (result);
-  
-  return rc;
-}
-
-
-static unsigned int
-rsa_get_nbits (int algo, gcry_mpi_t *pkey)
-{
-  (void)algo;
-
-  return mpi_get_nbits (pkey[0]);
-}
-
-
-/* Compute a keygrip.  MD is the hash context which we are going to
-   update.  KEYPARAM is an S-expression with the key parameters, this
-   is usually a public key but may also be a secret key.  An example
-   of such an S-expression is:
-
-      (rsa
-        (n #00B...#)
-        (e #010001#))
-        
-   PKCS-15 says that for RSA only the modulus should be hashed -
-   however, it is not clear wether this is meant to use the raw bytes
-   (assuming this is an unsigned integer) or whether the DER required
-   0 should be prefixed.  We hash the raw bytes.  */
-static gpg_err_code_t
-compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
-{
-  gcry_sexp_t l1;
-  const char *data;
-  size_t datalen;
-
-  l1 = gcry_sexp_find_token (keyparam, "n", 1);
-  if (!l1)
-    return GPG_ERR_NO_OBJ;
-
-  data = gcry_sexp_nth_data (l1, 1, &datalen);
-  if (!data)
-    {
-      gcry_sexp_release (l1);
-      return GPG_ERR_NO_OBJ;
-    }
-
-  gcry_md_write (md, data, datalen);
-  gcry_sexp_release (l1);
-
-  return 0;
-}
-
-
-
-\f
-/* 
-     Self-test section.
- */
-
-static const char *
-selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
-{
-  static const char sample_data[] = 
-    "(data (flags pkcs1)"
-    " (hash sha1 #11223344556677889900aabbccddeeff10203040#))";
-  static const char sample_data_bad[] = 
-    "(data (flags pkcs1)"
-    " (hash sha1 #11223344556677889900aabbccddeeff80203040#))";
-
-  const char *errtxt = NULL;
-  gcry_error_t err;
-  gcry_sexp_t data = NULL;
-  gcry_sexp_t data_bad = NULL;
-  gcry_sexp_t sig = NULL;
-
-  err = gcry_sexp_sscan (&data, NULL,
-                         sample_data, strlen (sample_data));
-  if (!err)
-    err = gcry_sexp_sscan (&data_bad, NULL, 
-                           sample_data_bad, strlen (sample_data_bad));
-  if (err)
-    {
-      errtxt = "converting data failed";
-      goto leave;
-    }
-
-  err = gcry_pk_sign (&sig, data, skey);
-  if (err)
-    {
-      errtxt = "signing failed";
-      goto leave;
-    }
-  err = gcry_pk_verify (sig, data, pkey);
-  if (err)
-    {
-      errtxt = "verify failed";
-      goto leave;
-    }
-  err = gcry_pk_verify (sig, data_bad, pkey);
-  if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
-    {
-      errtxt = "bad signature not detected";
-      goto leave;
-    }
-
-
- leave:
-  gcry_sexp_release (sig);
-  gcry_sexp_release (data_bad);
-  gcry_sexp_release (data);
-  return errtxt;
-}
-
-
-
-/* Given an S-expression ENCR_DATA of the form:
-
-   (enc-val
-    (rsa
-     (a a-value)))
-
-   as returned by gcry_pk_decrypt, return the the A-VALUE.  On error,
-   return NULL.  */
-static gcry_mpi_t
-extract_a_from_sexp (gcry_sexp_t encr_data)
-{
-  gcry_sexp_t l1, l2, l3;
-  gcry_mpi_t a_value;
-
-  l1 = gcry_sexp_find_token (encr_data, "enc-val", 0);
-  if (!l1)
-    return NULL;
-  l2 = gcry_sexp_find_token (l1, "rsa", 0);
-  gcry_sexp_release (l1);
-  if (!l2)
-    return NULL;
-  l3 = gcry_sexp_find_token (l2, "a", 0);
-  gcry_sexp_release (l2);
-  if (!l3)
-    return NULL;
-  a_value = gcry_sexp_nth_mpi (l3, 1, 0);
-  gcry_sexp_release (l3);
-
-  return a_value;
-}
-
-
-static const char *
-selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
-{
-  const char *errtxt = NULL;
-  gcry_error_t err;
-  const unsigned int nbits = 1000; /* Encrypt 1000 random bits.  */
-  gcry_mpi_t plaintext = NULL;
-  gcry_sexp_t plain = NULL;
-  gcry_sexp_t encr  = NULL;
-  gcry_mpi_t  ciphertext = NULL;
-  gcry_sexp_t decr  = NULL;
-  gcry_mpi_t  decr_plaintext = NULL;
-  gcry_sexp_t tmplist = NULL;
-
-  /* Create plaintext.  The plaintext is actually a big integer number.  */
-  plaintext = gcry_mpi_new (nbits);
-  gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
-  
-  /* Put the plaintext into an S-expression.  */
-  err = gcry_sexp_build (&plain, NULL,
-                         "(data (flags raw) (value %m))", plaintext);
-  if (err)
-    {
-      errtxt = "converting data failed";
-      goto leave;
-    }
-
-  /* Encrypt.  */
-  err = gcry_pk_encrypt (&encr, plain, pkey);
-  if (err)
-    {
-      errtxt = "encrypt failed";
-      goto leave;
-    }
-
-  /* Extraxt the ciphertext from the returned S-expression.  */
-  /*gcry_sexp_dump (encr);*/
-  ciphertext = extract_a_from_sexp (encr);
-  if (!ciphertext)
-    {
-      errtxt = "gcry_pk_decrypt returned garbage";
-      goto leave;
-    }
-
-  /* Check that the ciphertext does no match the plaintext.  */
-  /* _gcry_log_mpidump ("plaintext", plaintext); */
-  /* _gcry_log_mpidump ("ciphertxt", ciphertext); */
-  if (!gcry_mpi_cmp (plaintext, ciphertext))
-    {
-      errtxt = "ciphertext matches plaintext";
-      goto leave;
-    }
-
-  /* Decrypt.  */
-  err = gcry_pk_decrypt (&decr, encr, skey);
-  if (err)
-    {
-      errtxt = "decrypt failed";
-      goto leave;
-    }
-
-  /* Extract the decrypted data from the S-expression.  Note that the
-     output of gcry_pk_decrypt depends on whether a flags lists occurs
-     in its input data.  Because we passed the output of
-     gcry_pk_encrypt directly to gcry_pk_decrypt, such a flag value
-     won't be there as of today.  To be prepared for future changes we
-     take care of it anyway.  */
-  tmplist = gcry_sexp_find_token (decr, "value", 0);
-  if (tmplist)
-    decr_plaintext = gcry_sexp_nth_mpi (tmplist, 1, GCRYMPI_FMT_USG);
-  else
-    decr_plaintext = gcry_sexp_nth_mpi (decr, 0, GCRYMPI_FMT_USG);
-  if (!decr_plaintext)
-    {
-      errtxt = "decrypt returned no plaintext";
-      goto leave;
-    }
-  
-  /* Check that the decrypted plaintext matches the original  plaintext.  */
-  if (gcry_mpi_cmp (plaintext, decr_plaintext))
-    {
-      errtxt = "mismatch";
-      goto leave;
-    }
-
- leave:
-  gcry_sexp_release (tmplist);
-  gcry_mpi_release (decr_plaintext);
-  gcry_sexp_release (decr);
-  gcry_mpi_release (ciphertext);
-  gcry_sexp_release (encr);
-  gcry_sexp_release (plain);
-  gcry_mpi_release (plaintext);
-  return errtxt;
-}
-
-
-static gpg_err_code_t
-selftests_rsa (selftest_report_func_t report)
-{
-  const char *what;
-  const char *errtxt;
-  gcry_error_t err;
-  gcry_sexp_t skey = NULL;
-  gcry_sexp_t pkey = NULL;
-  
-  /* Convert the S-expressions into the internal representation.  */
-  what = "convert";
-  err = gcry_sexp_sscan (&skey, NULL, 
-                         sample_secret_key, strlen (sample_secret_key));
-  if (!err)
-    err = gcry_sexp_sscan (&pkey, NULL, 
-                           sample_public_key, strlen (sample_public_key));
-  if (err)
-    {
-      errtxt = gcry_strerror (err);
-      goto failed;
-    }
-
-  what = "key consistency";
-  err = gcry_pk_testkey (skey);
-  if (err)
-    {
-      errtxt = gcry_strerror (err);
-      goto failed;
-    }
-
-  what = "sign";
-  errtxt = selftest_sign_1024 (pkey, skey);
-  if (errtxt)
-    goto failed;
-
-  what = "encrypt";
-  errtxt = selftest_encr_1024 (pkey, skey);
-  if (errtxt)
-    goto failed;
-
-  gcry_sexp_release (pkey);
-  gcry_sexp_release (skey);
-  return 0; /* Succeeded. */
-
- failed:
-  gcry_sexp_release (pkey);
-  gcry_sexp_release (skey);
-  if (report)
-    report ("pubkey", GCRY_PK_RSA, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-
-/* Run a full self-test for ALGO and return 0 on success.  */
-static gpg_err_code_t
-run_selftests (int algo, int extended, selftest_report_func_t report)
-{
-  gpg_err_code_t ec;
-
-  (void)extended;
-
-  switch (algo)
-    {
-    case GCRY_PK_RSA:
-      ec = selftests_rsa (report);
-      break;
-    default:
-      ec = GPG_ERR_PUBKEY_ALGO;
-      break;
-        
-    }
-  return ec;
-}
-
-
-
-\f
-static const char *rsa_names[] =
-  {
-    "rsa",
-    "openpgp-rsa",
-    "oid.1.2.840.113549.1.1.1",
-    NULL,
-  };
-
-gcry_pk_spec_t _gcry_pubkey_spec_rsa =
-  {
-    "RSA", rsa_names,
-    "ne", "nedpqu", "a", "s", "n",
-    GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR,
-    rsa_generate,
-    rsa_check_secret_key,
-    rsa_encrypt,
-    rsa_decrypt,
-    rsa_sign,
-    rsa_verify,
-    rsa_get_nbits,
-  };
-pk_extra_spec_t _gcry_pubkey_extraspec_rsa = 
-  {
-    run_selftests,
-    rsa_generate_ext,
-    compute_keygrip
-  };
-
diff --git a/lib/libgcrypt/cipher/seed.c b/lib/libgcrypt/cipher/seed.c
deleted file mode 100644 (file)
index b0980d6..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
-/* SEED for libgcrypt
- *     Copyright (C) 2006 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * --
- * This implementation was provided for libgcrypt in public domain
- * by Hye-Shik Chang <perky@FreeBSD.org>, July 2006.
- */
-\f
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "types.h"  /* for byte and u32 typedefs */
-#include "g10lib.h"
-#include "cipher.h"
-
-#define NUMKC  16
-
-#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \
-                   ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
-#define PUTU32(ct, st) { (ct)[0] = (byte)((st) >> 24); \
-                        (ct)[1] = (byte)((st) >> 16); \
-                        (ct)[2] = (byte)((st) >>  8); \
-                        (ct)[3] = (byte)(st); }
-
-union wordbuf
-{
-  u32 w;
-  byte b[4];
-};
-
-#ifdef WORDS_BIGENDIAN
-#define b0  b[3]
-#define b1  b[2]
-#define b2  b[1]
-#define b3  b[0]
-#else
-#define b0  b[0]
-#define b1  b[1]
-#define b2  b[2]
-#define b3  b[3]
-#endif
-
-static const char *selftest(void);
-
-typedef struct 
-{
-  u32 keyschedule[32];
-} SEED_context;
-
-static const u32 SS0[256] = {
-    0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c,
-    0x2c8ca0ac, 0x25052124, 0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c,
-    0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360, 0x28082028, 0x04444044,
-    0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
-    0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310,
-    0x12c2d2d0, 0x2ecee2ec, 0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8,
-    0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074, 0x2ccce0ec, 0x15859194,
-    0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
-    0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc,
-    0x32c2f2f0, 0x19c9d1d8, 0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380,
-    0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8, 0x20406060, 0x10405050,
-    0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
-    0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210,
-    0x2f8fa3ac, 0x15c5d1d4, 0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140,
-    0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008, 0x1f0f131c, 0x19899198,
-    0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
-    0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388,
-    0x0e0e020c, 0x2b8ba3a8, 0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c,
-    0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208, 0x3f8fb3bc, 0x2fcfe3ec,
-    0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
-    0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120,
-    0x2b4b6368, 0x26466264, 0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288,
-    0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0, 0x3a4a7278, 0x07474344,
-    0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
-    0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114,
-    0x22022220, 0x38083038, 0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c,
-    0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394, 0x35053134, 0x0bcbc3c8,
-    0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
-    0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158,
-    0x02828280, 0x04c4c0c4, 0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364,
-    0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8, 0x0f0f030c, 0x0e8e828c,
-    0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
-    0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c,
-    0x2d0d212c, 0x00404040, 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0,
-    0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154, 0x3b0b3338, 0x1cccd0dc,
-    0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
-    0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328,
-    0x25456164, 0x3acaf2f8, 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c,
-    0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0, 0x31013130, 0x2acae2e8,
-    0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
-    0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128,
-    0x07070304, 0x33033330, 0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178,
-    0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298,
-};
-
-static const u32 SS1[256] = {
-    0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2,
-    0xb03383b3, 0xb83888b0, 0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3,
-    0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53, 0xc003c3c3, 0x60224262,
-    0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
-    0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0,
-    0x34360632, 0x480b4b43, 0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0,
-    0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0, 0xc002c2c2, 0x44054541,
-    0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
-    0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1,
-    0x0c0d0d01, 0xdc1fcfd3, 0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72,
-    0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272, 0x40024242, 0xd414c4d0,
-    0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
-    0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20,
-    0xa82a8aa2, 0x34340430, 0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1,
-    0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0, 0x54174753, 0xac2e8ea2,
-    0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
-    0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82,
-    0x682a4a62, 0xb03181b1, 0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202,
-    0x20220222, 0x04040400, 0x68284860, 0x70314171, 0x04070703, 0xd81bcbd3,
-    0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
-    0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3,
-    0xa82b8ba3, 0xd010c0d0, 0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12,
-    0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3, 0x94168692, 0x783b4b73,
-    0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
-    0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22,
-    0xb83a8ab2, 0x6c2e4e62, 0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292,
-    0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0, 0x14150511, 0xf83bcbf3,
-    0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
-    0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0,
-    0xe82acae2, 0x08090901, 0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040,
-    0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501, 0xf83acaf2, 0x00010101,
-    0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
-    0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1,
-    0x48084840, 0x78394971, 0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282,
-    0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53, 0x74374773, 0x54144450,
-    0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
-    0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2,
-    0xc809c9c1, 0xfc3dcdf1, 0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30,
-    0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70, 0x0c0e0e02, 0x50104050,
-    0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393,
-    0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353,
-    0x080a0a02, 0x84078783, 0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83,
-    0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3,
-};
-
-static const u32 SS2[256] = {
-    0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d,
-    0xa0ac2c8c, 0x21242505, 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e,
-    0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343, 0x20282808, 0x40440444,
-    0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
-    0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303,
-    0xd2d012c2, 0xe2ec2ece, 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888,
-    0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444, 0xe0ec2ccc, 0x91941585,
-    0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
-    0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc,
-    0xf2f032c2, 0xd1d819c9, 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383,
-    0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9, 0x60602040, 0x50501040,
-    0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
-    0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202,
-    0xa3ac2f8f, 0xd1d415c5, 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141,
-    0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808, 0x131c1f0f, 0x91981989,
-    0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
-    0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b,
-    0x020c0e0e, 0xa3a82b8b, 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d,
-    0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a, 0xb3bc3f8f, 0xe3ec2fcf,
-    0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
-    0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101,
-    0x63682b4b, 0x62642646, 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a,
-    0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0, 0x72783a4a, 0x43440747,
-    0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
-    0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505,
-    0x22202202, 0x30383808, 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c,
-    0x81800181, 0xe1e829c9, 0x80840484, 0x93941787, 0x31343505, 0xc3c80bcb,
-    0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
-    0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949,
-    0x82800282, 0xc0c404c4, 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747,
-    0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888, 0x030c0f0f, 0x828c0e8e,
-    0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
-    0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d,
-    0x212c2d0d, 0x40400040, 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1,
-    0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545, 0x33383b0b, 0xd0dc1ccc,
-    0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
-    0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b,
-    0x61642545, 0xf2f83aca, 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f,
-    0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282, 0x31303101, 0xe2e82aca,
-    0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
-    0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909,
-    0x03040707, 0x33303303, 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949,
-    0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a,
-};
-
-static const u32 SS3[256] = {
-    0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e,
-    0x83b3b033, 0x88b0b838, 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407,
-    0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b, 0xc3c3c003, 0x42626022,
-    0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
-    0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c,
-    0x06323436, 0x4b43480b, 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828,
-    0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434, 0xc2c2c002, 0x45414405,
-    0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
-    0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839,
-    0x0d010c0d, 0xcfd3dc1f, 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a,
-    0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032, 0x42424002, 0xc4d0d414,
-    0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
-    0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c,
-    0x8aa2a82a, 0x04303434, 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829,
-    0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838, 0x47535417, 0x8ea2ac2e,
-    0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
-    0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a,
-    0x4a62682a, 0x81b1b031, 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002,
-    0x02222022, 0x04000404, 0x48606828, 0x41717031, 0x07030407, 0xcbd3d81b,
-    0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
-    0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023,
-    0x8ba3a82b, 0xc0d0d010, 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a,
-    0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f, 0x86929416, 0x4b73783b,
-    0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
-    0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e,
-    0x8ab2b83a, 0x4e626c2e, 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012,
-    0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c, 0x05111415, 0xcbf3f83b,
-    0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
-    0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434,
-    0xcae2e82a, 0x09010809, 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000,
-    0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405, 0xcaf2f83a, 0x01010001,
-    0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
-    0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425,
-    0x48404808, 0x49717839, 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002,
-    0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f, 0x47737437, 0x44505414,
-    0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
-    0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a,
-    0xc9c1c809, 0xcdf1fc3d, 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c,
-    0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c, 0x0e020c0e, 0x40505010,
-    0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013,
-    0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013,
-    0x0a02080a, 0x87838407, 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f,
-    0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437,
-};
-
-static const u32 KC[NUMKC] = {
-    0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc,
-    0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf,
-    0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1,
-    0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b,
-};
-\f
-
-
-/* Perform the key setup.
- */  
-static gcry_err_code_t
-do_setkey (SEED_context *ctx, const byte *key, const unsigned keylen)
-{
-  static int initialized = 0;
-  static const char *selftest_failed=0;
-  u32 x1, x2, x3, x4;
-  union wordbuf t0, t1;
-  u32 *keyout = ctx->keyschedule;
-  int i;
-
-  if (!initialized)
-    {
-      initialized = 1;
-      selftest_failed = selftest ();
-      if( selftest_failed )
-        log_error ("%s\n", selftest_failed );
-    }
-  if (selftest_failed)
-    return GPG_ERR_SELFTEST_FAILED;
-
-  if (keylen != 16)
-    return GPG_ERR_INV_KEYLEN;
-
-  x1 = GETU32 (key);
-  x2 = GETU32 (key+4);
-  x3 = GETU32 (key+8);
-  x4 = GETU32 (key+12);
-
-  for (i = 0; i < NUMKC; i++)
-    {
-      t0.w = x1 + x3 - KC[i];
-      t1.w = x2 + KC[i] - x4;
-      *(keyout++) = SS0[t0.b0] ^ SS1[t0.b1] ^ SS2[t0.b2] ^ SS3[t0.b3];
-      *(keyout++) = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3];
-
-      if (i % 2 == 0)
-       {
-         t0.w = x1;
-         x1 = (x1>>8) ^ (x2<<24);
-         x2 = (x2>>8) ^ (t0.w<<24);
-       }
-      else
-       {
-         t0.w = x3;
-         x3 = (x3<<8) ^ (x4>>24);
-         x4 = (x4<<8) ^ (t0.w>>24);
-       }
-    }
-
-  return 0;
-}
-
-static gcry_err_code_t
-seed_setkey (void *context, const byte *key, const unsigned keylen)
-{
-  SEED_context *ctx = context;
-
-  int rc = do_setkey (ctx, key, keylen);
-  _gcry_burn_stack (4*6 + sizeof(void*)*2 + sizeof(int)*2);
-  return rc;
-}
-
-
-\f
-#define OP(X1, X2, X3, X4, rbase)                              \
-    t0.w = X3 ^ ctx->keyschedule[rbase];                       \
-    t1.w = X4 ^ ctx->keyschedule[rbase+1];                     \
-    t1.w ^= t0.w;                                              \
-    t1.w = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3];  \
-    t0.w += t1.w;                                              \
-    t0.w = SS0[t0.b0] ^ SS1[t0.b1] ^ SS2[t0.b2] ^ SS3[t0.b3];  \
-    t1.w += t0.w;                                              \
-    t1.w = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3];  \
-    t0.w += t1.w;                                              \
-    X1 ^= t0.w;                                                        \
-    X2 ^= t1.w;
-
-/* Encrypt one block.  inbuf and outbuf may be the same. */
-static void
-do_encrypt (const SEED_context *ctx, byte *outbuf, const byte *inbuf)
-{
-  u32 x1, x2, x3, x4;
-  union wordbuf t0, t1;
-
-  x1 = GETU32 (inbuf);
-  x2 = GETU32 (inbuf+4);
-  x3 = GETU32 (inbuf+8);
-  x4 = GETU32 (inbuf+12);
-
-  OP (x1, x2, x3, x4, 0);
-  OP (x3, x4, x1, x2, 2);
-  OP (x1, x2, x3, x4, 4);
-  OP (x3, x4, x1, x2, 6);
-  OP (x1, x2, x3, x4, 8);
-  OP (x3, x4, x1, x2, 10);
-  OP (x1, x2, x3, x4, 12);
-  OP (x3, x4, x1, x2, 14);
-  OP (x1, x2, x3, x4, 16);
-  OP (x3, x4, x1, x2, 18);
-  OP (x1, x2, x3, x4, 20);
-  OP (x3, x4, x1, x2, 22);
-  OP (x1, x2, x3, x4, 24);
-  OP (x3, x4, x1, x2, 26);
-  OP (x1, x2, x3, x4, 28);
-  OP (x3, x4, x1, x2, 30);
-
-  PUTU32 (outbuf, x3);
-  PUTU32 (outbuf+4, x4);
-  PUTU32 (outbuf+8, x1);
-  PUTU32 (outbuf+12, x2);
-}
-
-static void
-seed_encrypt (void *context, byte *outbuf, const byte *inbuf)
-{
-  SEED_context *ctx = context;
-
-  do_encrypt (ctx, outbuf, inbuf);
-  _gcry_burn_stack (4*6);
-}
-
-
-\f
-/* Decrypt one block.  inbuf and outbuf may be the same. */
-static void
-do_decrypt (SEED_context *ctx, byte *outbuf, const byte *inbuf)
-{
-  u32 x1, x2, x3, x4;
-  union wordbuf t0, t1;
-
-  x1 = GETU32 (inbuf);
-  x2 = GETU32 (inbuf+4);
-  x3 = GETU32 (inbuf+8);
-  x4 = GETU32 (inbuf+12);
-
-  OP (x1, x2, x3, x4, 30);
-  OP (x3, x4, x1, x2, 28);
-  OP (x1, x2, x3, x4, 26);
-  OP (x3, x4, x1, x2, 24);
-  OP (x1, x2, x3, x4, 22);
-  OP (x3, x4, x1, x2, 20);
-  OP (x1, x2, x3, x4, 18);
-  OP (x3, x4, x1, x2, 16);
-  OP (x1, x2, x3, x4, 14);
-  OP (x3, x4, x1, x2, 12);
-  OP (x1, x2, x3, x4, 10);
-  OP (x3, x4, x1, x2, 8);
-  OP (x1, x2, x3, x4, 6);
-  OP (x3, x4, x1, x2, 4);
-  OP (x1, x2, x3, x4, 2);
-  OP (x3, x4, x1, x2, 0);
-
-  PUTU32 (outbuf, x3);
-  PUTU32 (outbuf+4, x4);
-  PUTU32 (outbuf+8, x1);
-  PUTU32 (outbuf+12, x2);
-}
-
-static void
-seed_decrypt (void *context, byte *outbuf, const byte *inbuf)
-{
-  SEED_context *ctx = context;
-
-  do_decrypt (ctx, outbuf, inbuf);
-  _gcry_burn_stack (4*6);
-}
-
-\f
-/* Test a single encryption and decryption with each key size. */
-static const char*
-selftest (void)
-{
-  SEED_context ctx;
-  byte scratch[16];       
-
-  /* The test vector is taken from the appendix section B.3 of RFC4269.
-   */
-  static const byte plaintext[16] = {
-    0x83, 0xA2, 0xF8, 0xA2, 0x88, 0x64, 0x1F, 0xB9,
-    0xA4, 0xE9, 0xA5, 0xCC, 0x2F, 0x13, 0x1C, 0x7D
-  };
-  static const byte key[16] = {
-    0x47, 0x06, 0x48, 0x08, 0x51, 0xE6, 0x1B, 0xE8,
-    0x5D, 0x74, 0xBF, 0xB3, 0xFD, 0x95, 0x61, 0x85
-  };
-  static const byte ciphertext[16] = {
-    0xEE, 0x54, 0xD1, 0x3E, 0xBC, 0xAE, 0x70, 0x6D,
-    0x22, 0x6B, 0xC3, 0x14, 0x2C, 0xD4, 0x0D, 0x4A,
-  };
-
-  seed_setkey (&ctx, key, sizeof(key));
-  seed_encrypt (&ctx, scratch, plaintext);
-  if (memcmp (scratch, ciphertext, sizeof (ciphertext)))
-    return "SEED test encryption failed.";
-  seed_decrypt (&ctx, scratch, scratch);
-  if (memcmp (scratch, plaintext, sizeof (plaintext)))
-    return "SEED test decryption failed.";
-
-  return NULL;
-}
-
-\f
-
-static gcry_cipher_oid_spec_t seed_oids[] =
-  {
-    { "1.2.410.200004.1.3", GCRY_CIPHER_MODE_ECB },
-    { "1.2.410.200004.1.4", GCRY_CIPHER_MODE_CBC },
-    { "1.2.410.200004.1.5", GCRY_CIPHER_MODE_CFB },
-    { "1.2.410.200004.1.6", GCRY_CIPHER_MODE_OFB },
-    { NULL }
-  };
-
-gcry_cipher_spec_t _gcry_cipher_spec_seed =
-  {
-    "SEED", NULL, seed_oids, 16, 128, sizeof (SEED_context),
-    seed_setkey, seed_encrypt, seed_decrypt,
-  };
diff --git a/lib/libgcrypt/cipher/serpent.c b/lib/libgcrypt/cipher/serpent.c
deleted file mode 100644 (file)
index 6b7e655..0000000
+++ /dev/null
@@ -1,978 +0,0 @@
-/* serpent.c - Implementation of the Serpent encryption algorithm.
- *     Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-#include <config.h>
-
-#include <string.h>
-#include <stdio.h>
-
-#include "types.h"
-#include "g10lib.h"
-#include "cipher.h"
-#include "bithelp.h"
-
-/* Number of rounds per Serpent encrypt/decrypt operation.  */
-#define ROUNDS 32
-
-/* Magic number, used during generating of the subkeys.  */
-#define PHI 0x9E3779B9
-
-/* Serpent works on 128 bit blocks.  */
-typedef u32 serpent_block_t[4];
-
-/* Serpent key, provided by the user.  If the original key is shorter
-   than 256 bits, it is padded.  */
-typedef u32 serpent_key_t[8];
-
-/* The key schedule consists of 33 128 bit subkeys.  */
-typedef u32 serpent_subkeys_t[ROUNDS + 1][4];
-
-/* A Serpent context.  */
-typedef struct serpent_context
-{
-  serpent_subkeys_t keys;      /* Generated subkeys.  */
-} serpent_context_t;
-
-
-/* A prototype.  */
-static const char *serpent_test (void);
-      
-
-#define byte_swap_32(x) \
-  (0 \
-   | (((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) \
-   | (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
-
-/* These are the S-Boxes of Serpent.  They are copied from Serpents
-   reference implementation (the optimized one, contained in
-   `floppy2') and are therefore:
-
-     Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen.
-
-  To quote the Serpent homepage
-  (http://www.cl.cam.ac.uk/~rja14/serpent.html):
-
-  "Serpent is now completely in the public domain, and we impose no
-   restrictions on its use.  This was announced on the 21st August at
-   the First AES Candidate Conference. The optimised implementations
-   in the submission package are now under the GNU PUBLIC LICENSE
-   (GPL), although some comments in the code still say otherwise. You
-   are welcome to use Serpent for any application."  */
-
-#define SBOX0(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t05, t06, t07, t08, t09; \
-    u32 t11, t12, t13, t14, t15, t17, t01; \
-    t01 = b   ^ c  ; \
-    t02 = a   | d  ; \
-    t03 = a   ^ b  ; \
-    z   = t02 ^ t01; \
-    t05 = c   | z  ; \
-    t06 = a   ^ d  ; \
-    t07 = b   | c  ; \
-    t08 = d   & t05; \
-    t09 = t03 & t07; \
-    y   = t09 ^ t08; \
-    t11 = t09 & y  ; \
-    t12 = c   ^ d  ; \
-    t13 = t07 ^ t11; \
-    t14 = b   & t06; \
-    t15 = t06 ^ t13; \
-    w   =     ~ t15; \
-    t17 = w   ^ t14; \
-    x   = t12 ^ t17; \
-  }
-
-#define SBOX0_INVERSE(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t04, t05, t06, t08, t09, t10; \
-    u32 t12, t13, t14, t15, t17, t18, t01; \
-    t01 = c   ^ d  ; \
-    t02 = a   | b  ; \
-    t03 = b   | c  ; \
-    t04 = c   & t01; \
-    t05 = t02 ^ t01; \
-    t06 = a   | t04; \
-    y   =     ~ t05; \
-    t08 = b   ^ d  ; \
-    t09 = t03 & t08; \
-    t10 = d   | y  ; \
-    x   = t09 ^ t06; \
-    t12 = a   | t05; \
-    t13 = x   ^ t12; \
-    t14 = t03 ^ t10; \
-    t15 = a   ^ c  ; \
-    z   = t14 ^ t13; \
-    t17 = t05 & t13; \
-    t18 = t14 | t17; \
-    w   = t15 ^ t18; \
-  }
-
-#define SBOX1(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t04, t05, t06, t07, t08; \
-    u32 t10, t11, t12, t13, t16, t17, t01; \
-    t01 = a   | d  ; \
-    t02 = c   ^ d  ; \
-    t03 =     ~ b  ; \
-    t04 = a   ^ c  ; \
-    t05 = a   | t03; \
-    t06 = d   & t04; \
-    t07 = t01 & t02; \
-    t08 = b   | t06; \
-    y   = t02 ^ t05; \
-    t10 = t07 ^ t08; \
-    t11 = t01 ^ t10; \
-    t12 = y   ^ t11; \
-    t13 = b   & d  ; \
-    z   =     ~ t10; \
-    x   = t13 ^ t12; \
-    t16 = t10 | x  ; \
-    t17 = t05 & t16; \
-    w   = c   ^ t17; \
-  }
-
-#define SBOX1_INVERSE(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t04, t05, t06, t07, t08; \
-    u32 t09, t10, t11, t14, t15, t17, t01; \
-    t01 = a   ^ b  ; \
-    t02 = b   | d  ; \
-    t03 = a   & c  ; \
-    t04 = c   ^ t02; \
-    t05 = a   | t04; \
-    t06 = t01 & t05; \
-    t07 = d   | t03; \
-    t08 = b   ^ t06; \
-    t09 = t07 ^ t06; \
-    t10 = t04 | t03; \
-    t11 = d   & t08; \
-    y   =     ~ t09; \
-    x   = t10 ^ t11; \
-    t14 = a   | y  ; \
-    t15 = t06 ^ x  ; \
-    z   = t01 ^ t04; \
-    t17 = c   ^ t15; \
-    w   = t14 ^ t17; \
-  }
-
-#define SBOX2(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t05, t06, t07, t08; \
-    u32 t09, t10, t12, t13, t14, t01; \
-    t01 = a   | c  ; \
-    t02 = a   ^ b  ; \
-    t03 = d   ^ t01; \
-    w   = t02 ^ t03; \
-    t05 = c   ^ w  ; \
-    t06 = b   ^ t05; \
-    t07 = b   | t05; \
-    t08 = t01 & t06; \
-    t09 = t03 ^ t07; \
-    t10 = t02 | t09; \
-    x   = t10 ^ t08; \
-    t12 = a   | d  ; \
-    t13 = t09 ^ x  ; \
-    t14 = b   ^ t13; \
-    z   =     ~ t09; \
-    y   = t12 ^ t14; \
-  }
-
-#define SBOX2_INVERSE(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t04, t06, t07, t08, t09; \
-    u32 t10, t11, t12, t15, t16, t17, t01; \
-    t01 = a   ^ d  ; \
-    t02 = c   ^ d  ; \
-    t03 = a   & c  ; \
-    t04 = b   | t02; \
-    w   = t01 ^ t04; \
-    t06 = a   | c  ; \
-    t07 = d   | w  ; \
-    t08 =     ~ d  ; \
-    t09 = b   & t06; \
-    t10 = t08 | t03; \
-    t11 = b   & t07; \
-    t12 = t06 & t02; \
-    z   = t09 ^ t10; \
-    x   = t12 ^ t11; \
-    t15 = c   & z  ; \
-    t16 = w   ^ x  ; \
-    t17 = t10 ^ t15; \
-    y   = t16 ^ t17; \
-  }
-
-#define SBOX3(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t04, t05, t06, t07, t08; \
-    u32 t09, t10, t11, t13, t14, t15, t01; \
-    t01 = a   ^ c  ; \
-    t02 = a   | d  ; \
-    t03 = a   & d  ; \
-    t04 = t01 & t02; \
-    t05 = b   | t03; \
-    t06 = a   & b  ; \
-    t07 = d   ^ t04; \
-    t08 = c   | t06; \
-    t09 = b   ^ t07; \
-    t10 = d   & t05; \
-    t11 = t02 ^ t10; \
-    z   = t08 ^ t09; \
-    t13 = d   | z  ; \
-    t14 = a   | t07; \
-    t15 = b   & t13; \
-    y   = t08 ^ t11; \
-    w   = t14 ^ t15; \
-    x   = t05 ^ t04; \
-  }
-
-#define SBOX3_INVERSE(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t04, t05, t06, t07, t09; \
-    u32 t11, t12, t13, t14, t16, t01; \
-    t01 = c   | d  ; \
-    t02 = a   | d  ; \
-    t03 = c   ^ t02; \
-    t04 = b   ^ t02; \
-    t05 = a   ^ d  ; \
-    t06 = t04 & t03; \
-    t07 = b   & t01; \
-    y   = t05 ^ t06; \
-    t09 = a   ^ t03; \
-    w   = t07 ^ t03; \
-    t11 = w   | t05; \
-    t12 = t09 & t11; \
-    t13 = a   & y  ; \
-    t14 = t01 ^ t05; \
-    x   = b   ^ t12; \
-    t16 = b   | t13; \
-    z   = t14 ^ t16; \
-  }
-
-#define SBOX4(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t04, t05, t06, t08, t09; \
-    u32 t10, t11, t12, t13, t14, t15, t16, t01; \
-    t01 = a   | b  ; \
-    t02 = b   | c  ; \
-    t03 = a   ^ t02; \
-    t04 = b   ^ d  ; \
-    t05 = d   | t03; \
-    t06 = d   & t01; \
-    z   = t03 ^ t06; \
-    t08 = z   & t04; \
-    t09 = t04 & t05; \
-    t10 = c   ^ t06; \
-    t11 = b   & c  ; \
-    t12 = t04 ^ t08; \
-    t13 = t11 | t03; \
-    t14 = t10 ^ t09; \
-    t15 = a   & t05; \
-    t16 = t11 | t12; \
-    y   = t13 ^ t08; \
-    x   = t15 ^ t16; \
-    w   =     ~ t14; \
-  }
-
-#define SBOX4_INVERSE(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t04, t05, t06, t07, t09; \
-    u32 t10, t11, t12, t13, t15, t01; \
-    t01 = b   | d  ; \
-    t02 = c   | d  ; \
-    t03 = a   & t01; \
-    t04 = b   ^ t02; \
-    t05 = c   ^ d  ; \
-    t06 =     ~ t03; \
-    t07 = a   & t04; \
-    x   = t05 ^ t07; \
-    t09 = x   | t06; \
-    t10 = a   ^ t07; \
-    t11 = t01 ^ t09; \
-    t12 = d   ^ t04; \
-    t13 = c   | t10; \
-    z   = t03 ^ t12; \
-    t15 = a   ^ t04; \
-    y   = t11 ^ t13; \
-    w   = t15 ^ t09; \
-  }
-
-#define SBOX5(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t04, t05, t07, t08, t09; \
-    u32 t10, t11, t12, t13, t14, t01; \
-    t01 = b   ^ d  ; \
-    t02 = b   | d  ; \
-    t03 = a   & t01; \
-    t04 = c   ^ t02; \
-    t05 = t03 ^ t04; \
-    w   =     ~ t05; \
-    t07 = a   ^ t01; \
-    t08 = d   | w  ; \
-    t09 = b   | t05; \
-    t10 = d   ^ t08; \
-    t11 = b   | t07; \
-    t12 = t03 | w  ; \
-    t13 = t07 | t10; \
-    t14 = t01 ^ t11; \
-    y   = t09 ^ t13; \
-    x   = t07 ^ t08; \
-    z   = t12 ^ t14; \
-  }
-
-#define SBOX5_INVERSE(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t04, t05, t07, t08, t09; \
-    u32 t10, t12, t13, t15, t16, t01; \
-    t01 = a   & d  ; \
-    t02 = c   ^ t01; \
-    t03 = a   ^ d  ; \
-    t04 = b   & t02; \
-    t05 = a   & c  ; \
-    w   = t03 ^ t04; \
-    t07 = a   & w  ; \
-    t08 = t01 ^ w  ; \
-    t09 = b   | t05; \
-    t10 =     ~ b  ; \
-    x   = t08 ^ t09; \
-    t12 = t10 | t07; \
-    t13 = w   | x  ; \
-    z   = t02 ^ t12; \
-    t15 = t02 ^ t13; \
-    t16 = b   ^ d  ; \
-    y   = t16 ^ t15; \
-  }
-
-#define SBOX6(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t04, t05, t07, t08, t09, t10; \
-    u32 t11, t12, t13, t15, t17, t18, t01; \
-    t01 = a   & d  ; \
-    t02 = b   ^ c  ; \
-    t03 = a   ^ d  ; \
-    t04 = t01 ^ t02; \
-    t05 = b   | c  ; \
-    x   =     ~ t04; \
-    t07 = t03 & t05; \
-    t08 = b   & x  ; \
-    t09 = a   | c  ; \
-    t10 = t07 ^ t08; \
-    t11 = b   | d  ; \
-    t12 = c   ^ t11; \
-    t13 = t09 ^ t10; \
-    y   =     ~ t13; \
-    t15 = x   & t03; \
-    z   = t12 ^ t07; \
-    t17 = a   ^ b  ; \
-    t18 = y   ^ t15; \
-    w   = t17 ^ t18; \
-  }
-
-#define SBOX6_INVERSE(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t04, t05, t06, t07, t08, t09; \
-    u32 t12, t13, t14, t15, t16, t17, t01; \
-    t01 = a   ^ c  ; \
-    t02 =     ~ c  ; \
-    t03 = b   & t01; \
-    t04 = b   | t02; \
-    t05 = d   | t03; \
-    t06 = b   ^ d  ; \
-    t07 = a   & t04; \
-    t08 = a   | t02; \
-    t09 = t07 ^ t05; \
-    x   = t06 ^ t08; \
-    w   =     ~ t09; \
-    t12 = b   & w  ; \
-    t13 = t01 & t05; \
-    t14 = t01 ^ t12; \
-    t15 = t07 ^ t13; \
-    t16 = d   | t02; \
-    t17 = a   ^ x  ; \
-    z   = t17 ^ t15; \
-    y   = t16 ^ t14; \
-  }
-
-#define SBOX7(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t04, t05, t06, t08, t09, t10; \
-    u32 t11, t13, t14, t15, t16, t17, t01; \
-    t01 = a   & c  ; \
-    t02 =     ~ d  ; \
-    t03 = a   & t02; \
-    t04 = b   | t01; \
-    t05 = a   & b  ; \
-    t06 = c   ^ t04; \
-    z   = t03 ^ t06; \
-    t08 = c   | z  ; \
-    t09 = d   | t05; \
-    t10 = a   ^ t08; \
-    t11 = t04 & z  ; \
-    x   = t09 ^ t10; \
-    t13 = b   ^ x  ; \
-    t14 = t01 ^ x  ; \
-    t15 = c   ^ t05; \
-    t16 = t11 | t13; \
-    t17 = t02 | t14; \
-    w   = t15 ^ t17; \
-    y   = a   ^ t16; \
-  }
-
-#define SBOX7_INVERSE(a, b, c, d, w, x, y, z) \
-  { \
-    u32 t02, t03, t04, t06, t07, t08, t09; \
-    u32 t10, t11, t13, t14, t15, t16, t01; \
-    t01 = a   & b  ; \
-    t02 = a   | b  ; \
-    t03 = c   | t01; \
-    t04 = d   & t02; \
-    z   = t03 ^ t04; \
-    t06 = b   ^ t04; \
-    t07 = d   ^ z  ; \
-    t08 =     ~ t07; \
-    t09 = t06 | t08; \
-    t10 = b   ^ d  ; \
-    t11 = a   | d  ; \
-    x   = a   ^ t09; \
-    t13 = c   ^ t06; \
-    t14 = c   & t11; \
-    t15 = d   | x  ; \
-    t16 = t01 | t10; \
-    w   = t13 ^ t15; \
-    y   = t14 ^ t16; \
-  }
-
-/* XOR BLOCK1 into BLOCK0.  */
-#define BLOCK_XOR(block0, block1) \
-  {                               \
-    block0[0] ^= block1[0];       \
-    block0[1] ^= block1[1];       \
-    block0[2] ^= block1[2];       \
-    block0[3] ^= block1[3];       \
-  }
-
-/* Copy BLOCK_SRC to BLOCK_DST.  */
-#define BLOCK_COPY(block_dst, block_src) \
-  {                                      \
-    block_dst[0] = block_src[0];         \
-    block_dst[1] = block_src[1];         \
-    block_dst[2] = block_src[2];         \
-    block_dst[3] = block_src[3];         \
-  }
-
-/* Apply SBOX number WHICH to to the block found in ARRAY0 at index
-   INDEX, writing the output to the block found in ARRAY1 at index
-   INDEX.  */
-#define SBOX(which, array0, array1, index)            \
-  SBOX##which (array0[index + 0], array0[index + 1],  \
-               array0[index + 2], array0[index + 3],  \
-               array1[index + 0], array1[index + 1],  \
-               array1[index + 2], array1[index + 3]);
-
-/* Apply inverse SBOX number WHICH to to the block found in ARRAY0 at
-   index INDEX, writing the output to the block found in ARRAY1 at
-   index INDEX.  */
-#define SBOX_INVERSE(which, array0, array1, index)              \
-  SBOX##which##_INVERSE (array0[index + 0], array0[index + 1],  \
-                         array0[index + 2], array0[index + 3],  \
-                         array1[index + 0], array1[index + 1],  \
-                         array1[index + 2], array1[index + 3]);
-
-/* Apply the linear transformation to BLOCK.  */
-#define LINEAR_TRANSFORMATION(block)                  \
-  {                                                   \
-    block[0] = rol (block[0], 13);                    \
-    block[2] = rol (block[2], 3);                     \
-    block[1] = block[1] ^ block[0] ^ block[2];        \
-    block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
-    block[1] = rol (block[1], 1);                     \
-    block[3] = rol (block[3], 7);                     \
-    block[0] = block[0] ^ block[1] ^ block[3];        \
-    block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
-    block[0] = rol (block[0], 5);                     \
-    block[2] = rol (block[2], 22);                    \
-  }
-
-/* Apply the inverse linear transformation to BLOCK.  */
-#define LINEAR_TRANSFORMATION_INVERSE(block)          \
-  {                                                   \
-    block[2] = ror (block[2], 22);                    \
-    block[0] = ror (block[0] , 5);                    \
-    block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
-    block[0] = block[0] ^ block[1] ^ block[3];        \
-    block[3] = ror (block[3], 7);                     \
-    block[1] = ror (block[1], 1);                     \
-    block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
-    block[1] = block[1] ^ block[0] ^ block[2];        \
-    block[2] = ror (block[2], 3);                     \
-    block[0] = ror (block[0], 13);                    \
-  }
-
-/* Apply a Serpent round to BLOCK, using the SBOX number WHICH and the
-   subkeys contained in SUBKEYS.  Use BLOCK_TMP as temporary storage.
-   This macro increments `round'.  */
-#define ROUND(which, subkeys, block, block_tmp) \
-  {                                             \
-    BLOCK_XOR (block, subkeys[round]);          \
-    round++;                                    \
-    SBOX (which, block, block_tmp, 0);          \
-    LINEAR_TRANSFORMATION (block_tmp);          \
-    BLOCK_COPY (block, block_tmp);              \
-  }
-
-/* Apply the last Serpent round to BLOCK, using the SBOX number WHICH
-   and the subkeys contained in SUBKEYS.  Use BLOCK_TMP as temporary
-   storage.  The result will be stored in BLOCK_TMP.  This macro
-   increments `round'.  */
-#define ROUND_LAST(which, subkeys, block, block_tmp) \
-  {                                                  \
-    BLOCK_XOR (block, subkeys[round]);               \
-    round++;                                         \
-    SBOX (which, block, block_tmp, 0);               \
-    BLOCK_XOR (block_tmp, subkeys[round]);           \
-    round++;                                         \
-  }
-
-/* Apply an inverse Serpent round to BLOCK, using the SBOX number
-   WHICH and the subkeys contained in SUBKEYS.  Use BLOCK_TMP as
-   temporary storage.  This macro increments `round'.  */
-#define ROUND_INVERSE(which, subkey, block, block_tmp) \
-  {                                                    \
-    LINEAR_TRANSFORMATION_INVERSE (block);             \
-    SBOX_INVERSE (which, block, block_tmp, 0);         \
-    BLOCK_XOR (block_tmp, subkey[round]);              \
-    round--;                                           \
-    BLOCK_COPY (block, block_tmp);                     \
-  }
-
-/* Apply the first Serpent round to BLOCK, using the SBOX number WHICH
-   and the subkeys contained in SUBKEYS.  Use BLOCK_TMP as temporary
-   storage.  The result will be stored in BLOCK_TMP.  This macro
-   increments `round'.  */
-#define ROUND_FIRST_INVERSE(which, subkeys, block, block_tmp) \
-  {                                                           \
-    BLOCK_XOR (block, subkeys[round]);                        \
-    round--;                                                  \
-    SBOX_INVERSE (which, block, block_tmp, 0);                \
-    BLOCK_XOR (block_tmp, subkeys[round]);                    \
-    round--;                                                  \
-  }
-
-/* Convert the user provided key KEY of KEY_LENGTH bytes into the
-   internally used format.  */
-static void
-serpent_key_prepare (const byte *key, unsigned int key_length,
-                    serpent_key_t key_prepared)
-{
-  int i;
-
-  /* Copy key.  */
-  for (i = 0; i < key_length / 4; i++)
-    {
-#ifdef WORDS_BIGENDIAN
-      key_prepared[i] = byte_swap_32 (((u32 *) key)[i]);
-#else
-      key_prepared[i] = ((u32 *) key)[i];
-#endif
-    }
-
-  if (i < 8)
-    {
-      /* Key must be padded according to the Serpent
-        specification.  */
-      key_prepared[i] = 0x00000001;
-
-      for (i++; i < 8; i++)
-       key_prepared[i] = 0;
-    }
-}
-
-/* Derive the 33 subkeys from KEY and store them in SUBKEYS.  */
-static void
-serpent_subkeys_generate (serpent_key_t key, serpent_subkeys_t subkeys)
-{
-  u32 w_real[140];             /* The `prekey'.  */
-  u32 k[132];
-  u32 *w = &w_real[8];
-  int i, j;
-
-  /* Initialize with key values.  */
-  for (i = 0; i < 8; i++)
-    w[i - 8] = key[i];
-
-  /* Expand to intermediate key using the affine recurrence.  */
-  for (i = 0; i < 132; i++)
-    w[i] = rol (w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11);
-
-  /* Calculate subkeys via S-Boxes, in bitslice mode.  */
-  SBOX (3, w, k,   0);
-  SBOX (2, w, k,   4);
-  SBOX (1, w, k,   8);
-  SBOX (0, w, k,  12);
-  SBOX (7, w, k,  16);
-  SBOX (6, w, k,  20);
-  SBOX (5, w, k,  24);
-  SBOX (4, w, k,  28);
-  SBOX (3, w, k,  32);
-  SBOX (2, w, k,  36);
-  SBOX (1, w, k,  40);
-  SBOX (0, w, k,  44);
-  SBOX (7, w, k,  48);
-  SBOX (6, w, k,  52);
-  SBOX (5, w, k,  56);
-  SBOX (4, w, k,  60);
-  SBOX (3, w, k,  64);
-  SBOX (2, w, k,  68);
-  SBOX (1, w, k,  72);
-  SBOX (0, w, k,  76);
-  SBOX (7, w, k,  80);
-  SBOX (6, w, k,  84);
-  SBOX (5, w, k,  88);
-  SBOX (4, w, k,  92);
-  SBOX (3, w, k,  96);
-  SBOX (2, w, k, 100);
-  SBOX (1, w, k, 104);
-  SBOX (0, w, k, 108);
-  SBOX (7, w, k, 112);
-  SBOX (6, w, k, 116);
-  SBOX (5, w, k, 120);
-  SBOX (4, w, k, 124);
-  SBOX (3, w, k, 128);
-
-  /* Renumber subkeys.  */
-  for (i = 0; i < ROUNDS + 1; i++)
-    for (j = 0; j < 4; j++)
-      subkeys[i][j] = k[4 * i + j];
-}
-
-/* Initialize CONTEXT with the key KEY of KEY_LENGTH bits.  */
-static void
-serpent_setkey_internal (serpent_context_t *context,
-                        const byte *key, unsigned int key_length)
-{
-  serpent_key_t key_prepared;
-
-  serpent_key_prepare (key, key_length, key_prepared);
-  serpent_subkeys_generate (key_prepared, context->keys);
-  _gcry_burn_stack (272 * sizeof (u32));
-}
-
-/* Initialize CTX with the key KEY of KEY_LENGTH bytes.  */
-static gcry_err_code_t
-serpent_setkey (void *ctx,
-               const byte *key, unsigned int key_length)
-{
-  serpent_context_t *context = ctx;
-  static const char *serpent_test_ret;
-  static int serpent_init_done;
-  gcry_err_code_t ret = GPG_ERR_NO_ERROR;
-  
-  if (! serpent_init_done)
-    {
-      /* Execute a self-test the first time, Serpent is used.  */
-      serpent_test_ret = serpent_test ();
-      if (serpent_test_ret)
-       log_error ("Serpent test failure: %s\n", serpent_test_ret);
-      serpent_init_done = 1;
-    }
-
-  if (serpent_test_ret)
-    ret = GPG_ERR_SELFTEST_FAILED;
-  else
-    {
-      serpent_setkey_internal (context, key, key_length);
-      _gcry_burn_stack (sizeof (serpent_key_t));
-    }
-
-  return ret;
-}
-
-static void
-serpent_encrypt_internal (serpent_context_t *context,
-                         const serpent_block_t input, serpent_block_t output)
-{
-  serpent_block_t b, b_next;
-  int round = 0;
-
-#ifdef WORDS_BIGENDIAN
-  b[0] = byte_swap_32 (input[0]);
-  b[1] = byte_swap_32 (input[1]);
-  b[2] = byte_swap_32 (input[2]);
-  b[3] = byte_swap_32 (input[3]);
-#else
-  b[0] = input[0];
-  b[1] = input[1];
-  b[2] = input[2];
-  b[3] = input[3];
-#endif
-
-  ROUND (0, context->keys, b, b_next);
-  ROUND (1, context->keys, b, b_next);
-  ROUND (2, context->keys, b, b_next);
-  ROUND (3, context->keys, b, b_next);
-  ROUND (4, context->keys, b, b_next);
-  ROUND (5, context->keys, b, b_next);
-  ROUND (6, context->keys, b, b_next);
-  ROUND (7, context->keys, b, b_next);
-  ROUND (0, context->keys, b, b_next);
-  ROUND (1, context->keys, b, b_next);
-  ROUND (2, context->keys, b, b_next);
-  ROUND (3, context->keys, b, b_next);
-  ROUND (4, context->keys, b, b_next);
-  ROUND (5, context->keys, b, b_next);
-  ROUND (6, context->keys, b, b_next);
-  ROUND (7, context->keys, b, b_next);
-  ROUND (0, context->keys, b, b_next);
-  ROUND (1, context->keys, b, b_next);
-  ROUND (2, context->keys, b, b_next);
-  ROUND (3, context->keys, b, b_next);
-  ROUND (4, context->keys, b, b_next);
-  ROUND (5, context->keys, b, b_next);
-  ROUND (6, context->keys, b, b_next);
-  ROUND (7, context->keys, b, b_next);
-  ROUND (0, context->keys, b, b_next);
-  ROUND (1, context->keys, b, b_next);
-  ROUND (2, context->keys, b, b_next);
-  ROUND (3, context->keys, b, b_next);
-  ROUND (4, context->keys, b, b_next);
-  ROUND (5, context->keys, b, b_next);
-  ROUND (6, context->keys, b, b_next);
-
-  ROUND_LAST (7, context->keys, b, b_next);
-
-#ifdef WORDS_BIGENDIAN
-  output[0] = byte_swap_32 (b_next[0]);
-  output[1] = byte_swap_32 (b_next[1]);
-  output[2] = byte_swap_32 (b_next[2]);
-  output[3] = byte_swap_32 (b_next[3]);
-#else
-  output[0] = b_next[0];
-  output[1] = b_next[1];
-  output[2] = b_next[2];
-  output[3] = b_next[3];
-#endif
-}
-
-static void
-serpent_decrypt_internal (serpent_context_t *context,
-                         const serpent_block_t input, serpent_block_t output)
-{
-  serpent_block_t b, b_next;
-  int round = ROUNDS;
-
-#ifdef WORDS_BIGENDIAN
-  b_next[0] = byte_swap_32 (input[0]);
-  b_next[1] = byte_swap_32 (input[1]);
-  b_next[2] = byte_swap_32 (input[2]);
-  b_next[3] = byte_swap_32 (input[3]);
-#else
-  b_next[0] = input[0];
-  b_next[1] = input[1];
-  b_next[2] = input[2];
-  b_next[3] = input[3];
-#endif
-
-  ROUND_FIRST_INVERSE (7, context->keys, b_next, b);
-
-  ROUND_INVERSE (6, context->keys, b, b_next);
-  ROUND_INVERSE (5, context->keys, b, b_next);
-  ROUND_INVERSE (4, context->keys, b, b_next);
-  ROUND_INVERSE (3, context->keys, b, b_next);
-  ROUND_INVERSE (2, context->keys, b, b_next);
-  ROUND_INVERSE (1, context->keys, b, b_next);
-  ROUND_INVERSE (0, context->keys, b, b_next);
-  ROUND_INVERSE (7, context->keys, b, b_next);
-  ROUND_INVERSE (6, context->keys, b, b_next);
-  ROUND_INVERSE (5, context->keys, b, b_next);
-  ROUND_INVERSE (4, context->keys, b, b_next);
-  ROUND_INVERSE (3, context->keys, b, b_next);
-  ROUND_INVERSE (2, context->keys, b, b_next);
-  ROUND_INVERSE (1, context->keys, b, b_next);
-  ROUND_INVERSE (0, context->keys, b, b_next);
-  ROUND_INVERSE (7, context->keys, b, b_next);
-  ROUND_INVERSE (6, context->keys, b, b_next);
-  ROUND_INVERSE (5, context->keys, b, b_next);
-  ROUND_INVERSE (4, context->keys, b, b_next);
-  ROUND_INVERSE (3, context->keys, b, b_next);
-  ROUND_INVERSE (2, context->keys, b, b_next);
-  ROUND_INVERSE (1, context->keys, b, b_next);
-  ROUND_INVERSE (0, context->keys, b, b_next);
-  ROUND_INVERSE (7, context->keys, b, b_next);
-  ROUND_INVERSE (6, context->keys, b, b_next);
-  ROUND_INVERSE (5, context->keys, b, b_next);
-  ROUND_INVERSE (4, context->keys, b, b_next);
-  ROUND_INVERSE (3, context->keys, b, b_next);
-  ROUND_INVERSE (2, context->keys, b, b_next);
-  ROUND_INVERSE (1, context->keys, b, b_next);
-  ROUND_INVERSE (0, context->keys, b, b_next);
-
-
-#ifdef WORDS_BIGENDIAN
-  output[0] = byte_swap_32 (b_next[0]);
-  output[1] = byte_swap_32 (b_next[1]);
-  output[2] = byte_swap_32 (b_next[2]);
-  output[3] = byte_swap_32 (b_next[3]);
-#else
-  output[0] = b_next[0];
-  output[1] = b_next[1];
-  output[2] = b_next[2];
-  output[3] = b_next[3];
-#endif
-}
-
-static void
-serpent_encrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
-{
-  serpent_context_t *context = ctx;
-
-  serpent_encrypt_internal (context,
-                           (const u32 *) buffer_in, (u32 *) buffer_out);
-  _gcry_burn_stack (2 * sizeof (serpent_block_t));
-}
-
-static void
-serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
-{
-  serpent_context_t *context = ctx;
-
-  serpent_decrypt_internal (context,
-                           (const u32 *) buffer_in,
-                           (u32 *) buffer_out);
-  _gcry_burn_stack (2 * sizeof (serpent_block_t));
-}
-
-\f
-
-/* Serpent test.  */
-
-static const char *
-serpent_test (void)
-{
-  serpent_context_t context;
-  unsigned char scratch[16];
-  unsigned int i;
-
-  static struct test
-  {
-    int key_length;
-    unsigned char key[32];
-    unsigned char text_plain[16];
-    unsigned char text_cipher[16];
-  } test_data[] =
-    {
-      {
-       16,
-       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
-       "\xD2\x9D\x57\x6F\xCE\xA3\xA3\xA7\xED\x90\x99\xF2\x92\x73\xD7\x8E",
-       "\xB2\x28\x8B\x96\x8A\xE8\xB0\x86\x48\xD1\xCE\x96\x06\xFD\x99\x2D"
-      },
-      {
-       24,
-       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
-       "\x00\x00\x00\x00\x00\x00\x00\x00",
-       "\xD2\x9D\x57\x6F\xCE\xAB\xA3\xA7\xED\x98\x99\xF2\x92\x7B\xD7\x8E",
-       "\x13\x0E\x35\x3E\x10\x37\xC2\x24\x05\xE8\xFA\xEF\xB2\xC3\xC3\xE9"
-      },
-      {
-       32,
-       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
-       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
-       "\xD0\x95\x57\x6F\xCE\xA3\xE3\xA7\xED\x98\xD9\xF2\x90\x73\xD7\x8E",
-       "\xB9\x0E\xE5\x86\x2D\xE6\x91\x68\xF2\xBD\xD5\x12\x5B\x45\x47\x2B"
-      },
-      {
-       32,
-       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
-       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
-       "\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00",
-       "\x20\x61\xA4\x27\x82\xBD\x52\xEC\x69\x1E\xC3\x83\xB0\x3B\xA7\x7C"
-      },
-      {
-       0
-      },
-    };
-
-  for (i = 0; test_data[i].key_length; i++)
-    {
-      serpent_setkey_internal (&context, test_data[i].key,
-                               test_data[i].key_length);
-      serpent_encrypt_internal (&context,
-                               (const u32 *) test_data[i].text_plain,
-                               (u32 *) scratch);
-
-      if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t)))
-       switch (test_data[i].key_length)
-         {
-         case 16:
-           return "Serpent-128 test encryption failed.";
-         case  24:
-           return "Serpent-192 test encryption failed.";
-         case 32:
-           return "Serpent-256 test encryption failed.";
-         }
-
-    serpent_decrypt_internal (&context,
-                             (const u32 *) test_data[i].text_cipher,
-                             (u32 *) scratch);
-    if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t)))
-      switch (test_data[i].key_length)
-       {
-       case 16:
-         return "Serpent-128 test decryption failed.";
-       case  24:
-         return "Serpent-192 test decryption failed.";
-       case 32:
-         return "Serpent-256 test decryption failed.";
-       }
-    }
-
-  return NULL;
-}
-
-\f
-
-/* "SERPENT" is an alias for "SERPENT128".  */
-static const char *cipher_spec_serpent128_aliases[] =
-  {
-    "SERPENT",
-    NULL
-  };
-
-gcry_cipher_spec_t _gcry_cipher_spec_serpent128 =
-  {
-    "SERPENT128", cipher_spec_serpent128_aliases, NULL, 16, 128,
-    sizeof (serpent_context_t),
-    serpent_setkey, serpent_encrypt, serpent_decrypt
-  };
-
-gcry_cipher_spec_t _gcry_cipher_spec_serpent192 =
-  {
-    "SERPENT192", NULL, NULL, 16, 192,
-    sizeof (serpent_context_t),
-    serpent_setkey, serpent_encrypt, serpent_decrypt
-  };
-
-gcry_cipher_spec_t _gcry_cipher_spec_serpent256 =
-  {
-    "SERPENT256", NULL, NULL, 16, 256,
-    sizeof (serpent_context_t),
-    serpent_setkey, serpent_encrypt, serpent_decrypt
-  };
diff --git a/lib/libgcrypt/cipher/sha1.c b/lib/libgcrypt/cipher/sha1.c
deleted file mode 100644 (file)
index 8862c64..0000000
+++ /dev/null
@@ -1,479 +0,0 @@
-/* sha1.c - SHA1 hash function
- * Copyright (C) 1998, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-
-/*  Test vectors:
- *
- *  "abc"
- *  A999 3E36 4706 816A BA3E  2571 7850 C26C 9CD0 D89D
- *
- *  "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
- *  8498 3E44 1C3B D26E BAAE  4AA1 F951 29E5 E546 70F1
- */
-
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_STDINT_H 
-# include <stdint.h>
-#endif
-
-#include "g10lib.h"
-#include "memory.h"
-#include "bithelp.h"
-#include "cipher.h"
-#include "hash-common.h"
-
-
-/* A macro to test whether P is properly aligned for an u32 type.
-   Note that config.h provides a suitable replacement for uintptr_t if
-   it does not exist in stdint.h.  */
-/* #if __GNUC__ >= 2 */
-/* # define U32_ALIGNED_P(p) (!(((uintptr_t)p) % __alignof__ (u32))) */
-/* #else */
-/* # define U32_ALIGNED_P(p) (!(((uintptr_t)p) % sizeof (u32))) */
-/* #endif */
-
-#define TRANSFORM(x,d,n) transform ((x), (d), (n))
-
-
-typedef struct 
-{
-  u32           h0,h1,h2,h3,h4;
-  u32           nblocks;
-  unsigned char buf[64];
-  int           count;
-} SHA1_CONTEXT;
-
-
-
-static void
-sha1_init (void *context)
-{
-  SHA1_CONTEXT *hd = context;
-
-  hd->h0 = 0x67452301;
-  hd->h1 = 0xefcdab89;
-  hd->h2 = 0x98badcfe;
-  hd->h3 = 0x10325476;
-  hd->h4 = 0xc3d2e1f0;
-  hd->nblocks = 0;
-  hd->count = 0;
-}
-
-
-/* Round function macros. */
-#define K1  0x5A827999L
-#define K2  0x6ED9EBA1L
-#define K3  0x8F1BBCDCL
-#define K4  0xCA62C1D6L
-#define F1(x,y,z)   ( z ^ ( x & ( y ^ z ) ) )
-#define F2(x,y,z)   ( x ^ y ^ z )
-#define F3(x,y,z)   ( ( x & y ) | ( z & ( x | y ) ) )
-#define F4(x,y,z)   ( x ^ y ^ z )
-#define M(i) ( tm =    x[ i    &0x0f]  \
-                     ^ x[(i-14)&0x0f]  \
-                    ^ x[(i-8) &0x0f]  \
-                     ^ x[(i-3) &0x0f], \
-                     (x[i&0x0f] = rol(tm, 1)))
-#define R(a,b,c,d,e,f,k,m)  do { e += rol( a, 5 )     \
-                                     + f( b, c, d )  \
-                                     + k             \
-                                     + m;            \
-                                b = rol( b, 30 );    \
-                              } while(0)
-
-
-/*
- * Transform NBLOCKS of each 64 bytes (16 32-bit words) at DATA.
- */
-static void
-transform (SHA1_CONTEXT *hd, const unsigned char *data, size_t nblocks)
-{
-  register u32 a, b, c, d, e; /* Local copies of the chaining variables.  */
-  register u32 tm;            /* Helper.  */
-  u32 x[16];                  /* The array we work on. */
-  
-  /* Loop over all blocks.  */
-  for ( ;nblocks; nblocks--)
-    {
-#ifdef WORDS_BIGENDIAN
-      memcpy (x, data, 64);
-      data += 64;
-#else
-      {
-        int i;
-        unsigned char *p;
-
-        for(i=0, p=(unsigned char*)x; i < 16; i++, p += 4 )
-          {
-            p[3] = *data++;
-            p[2] = *data++;
-            p[1] = *data++;
-            p[0] = *data++;
-          }
-      }
-#endif
-      /* Get the values of the chaining variables. */
-      a = hd->h0;
-      b = hd->h1;
-      c = hd->h2;
-      d = hd->h3;
-      e = hd->h4;
-
-      /* Transform. */
-      R( a, b, c, d, e, F1, K1, x[ 0] );
-      R( e, a, b, c, d, F1, K1, x[ 1] );
-      R( d, e, a, b, c, F1, K1, x[ 2] );
-      R( c, d, e, a, b, F1, K1, x[ 3] );
-      R( b, c, d, e, a, F1, K1, x[ 4] );
-      R( a, b, c, d, e, F1, K1, x[ 5] );
-      R( e, a, b, c, d, F1, K1, x[ 6] );
-      R( d, e, a, b, c, F1, K1, x[ 7] );
-      R( c, d, e, a, b, F1, K1, x[ 8] );
-      R( b, c, d, e, a, F1, K1, x[ 9] );
-      R( a, b, c, d, e, F1, K1, x[10] );
-      R( e, a, b, c, d, F1, K1, x[11] );
-      R( d, e, a, b, c, F1, K1, x[12] );
-      R( c, d, e, a, b, F1, K1, x[13] );
-      R( b, c, d, e, a, F1, K1, x[14] );
-      R( a, b, c, d, e, F1, K1, x[15] );
-      R( e, a, b, c, d, F1, K1, M(16) );
-      R( d, e, a, b, c, F1, K1, M(17) );
-      R( c, d, e, a, b, F1, K1, M(18) );
-      R( b, c, d, e, a, F1, K1, M(19) );
-      R( a, b, c, d, e, F2, K2, M(20) );
-      R( e, a, b, c, d, F2, K2, M(21) );
-      R( d, e, a, b, c, F2, K2, M(22) );
-      R( c, d, e, a, b, F2, K2, M(23) );
-      R( b, c, d, e, a, F2, K2, M(24) );
-      R( a, b, c, d, e, F2, K2, M(25) );
-      R( e, a, b, c, d, F2, K2, M(26) );
-      R( d, e, a, b, c, F2, K2, M(27) );
-      R( c, d, e, a, b, F2, K2, M(28) );
-      R( b, c, d, e, a, F2, K2, M(29) );
-      R( a, b, c, d, e, F2, K2, M(30) );
-      R( e, a, b, c, d, F2, K2, M(31) );
-      R( d, e, a, b, c, F2, K2, M(32) );
-      R( c, d, e, a, b, F2, K2, M(33) );
-      R( b, c, d, e, a, F2, K2, M(34) );
-      R( a, b, c, d, e, F2, K2, M(35) );
-      R( e, a, b, c, d, F2, K2, M(36) );
-      R( d, e, a, b, c, F2, K2, M(37) );
-      R( c, d, e, a, b, F2, K2, M(38) );
-      R( b, c, d, e, a, F2, K2, M(39) );
-      R( a, b, c, d, e, F3, K3, M(40) );
-      R( e, a, b, c, d, F3, K3, M(41) );
-      R( d, e, a, b, c, F3, K3, M(42) );
-      R( c, d, e, a, b, F3, K3, M(43) );
-      R( b, c, d, e, a, F3, K3, M(44) );
-      R( a, b, c, d, e, F3, K3, M(45) );
-      R( e, a, b, c, d, F3, K3, M(46) );
-      R( d, e, a, b, c, F3, K3, M(47) );
-      R( c, d, e, a, b, F3, K3, M(48) );
-      R( b, c, d, e, a, F3, K3, M(49) );
-      R( a, b, c, d, e, F3, K3, M(50) );
-      R( e, a, b, c, d, F3, K3, M(51) );
-      R( d, e, a, b, c, F3, K3, M(52) );
-      R( c, d, e, a, b, F3, K3, M(53) );
-      R( b, c, d, e, a, F3, K3, M(54) );
-      R( a, b, c, d, e, F3, K3, M(55) );
-      R( e, a, b, c, d, F3, K3, M(56) );
-      R( d, e, a, b, c, F3, K3, M(57) );
-      R( c, d, e, a, b, F3, K3, M(58) );
-      R( b, c, d, e, a, F3, K3, M(59) );
-      R( a, b, c, d, e, F4, K4, M(60) );
-      R( e, a, b, c, d, F4, K4, M(61) );
-      R( d, e, a, b, c, F4, K4, M(62) );
-      R( c, d, e, a, b, F4, K4, M(63) );
-      R( b, c, d, e, a, F4, K4, M(64) );
-      R( a, b, c, d, e, F4, K4, M(65) );
-      R( e, a, b, c, d, F4, K4, M(66) );
-      R( d, e, a, b, c, F4, K4, M(67) );
-      R( c, d, e, a, b, F4, K4, M(68) );
-      R( b, c, d, e, a, F4, K4, M(69) );
-      R( a, b, c, d, e, F4, K4, M(70) );
-      R( e, a, b, c, d, F4, K4, M(71) );
-      R( d, e, a, b, c, F4, K4, M(72) );
-      R( c, d, e, a, b, F4, K4, M(73) );
-      R( b, c, d, e, a, F4, K4, M(74) );
-      R( a, b, c, d, e, F4, K4, M(75) );
-      R( e, a, b, c, d, F4, K4, M(76) );
-      R( d, e, a, b, c, F4, K4, M(77) );
-      R( c, d, e, a, b, F4, K4, M(78) );
-      R( b, c, d, e, a, F4, K4, M(79) );
-
-      /* Update the chaining variables. */
-      hd->h0 += a;
-      hd->h1 += b;
-      hd->h2 += c;
-      hd->h3 += d;
-      hd->h4 += e;
-    }
-}
-
-
-/* Update the message digest with the contents
- * of INBUF with length INLEN.
- */
-static void
-sha1_write( void *context, const void *inbuf_arg, size_t inlen)
-{
-  const unsigned char *inbuf = inbuf_arg;
-  SHA1_CONTEXT *hd = context;
-  size_t nblocks;
-
-  if (hd->count == 64)  /* Flush the buffer. */
-    {
-      TRANSFORM( hd, hd->buf, 1 );
-      _gcry_burn_stack (88+4*sizeof(void*));
-      hd->count = 0;
-      hd->nblocks++;
-    }
-  if (!inbuf)
-    return;
-
-  if (hd->count)
-    {
-      for (; inlen && hd->count < 64; inlen--)
-        hd->buf[hd->count++] = *inbuf++;
-      sha1_write (hd, NULL, 0);
-      if (!inlen)
-        return;
-    }
-
-  nblocks = inlen / 64;
-  if (nblocks)
-    {
-      TRANSFORM (hd, inbuf, nblocks);
-      hd->count = 0;
-      hd->nblocks += nblocks;
-      inlen -= nblocks * 64;
-      inbuf += nblocks * 64;
-    }
-  _gcry_burn_stack (88+4*sizeof(void*));
-
-  /* Save remaining bytes.  */
-  for (; inlen && hd->count < 64; inlen--)
-    hd->buf[hd->count++] = *inbuf++;
-}
-
-
-/* The routine final terminates the computation and
- * returns the digest.
- * The handle is prepared for a new cycle, but adding bytes to the
- * handle will the destroy the returned buffer.
- * Returns: 20 bytes representing the digest.
- */
-
-static void
-sha1_final(void *context)
-{
-  SHA1_CONTEXT *hd = context;
-  
-  u32 t, msb, lsb;
-  unsigned char *p;
-
-  sha1_write(hd, NULL, 0); /* flush */;
-
-  t = hd->nblocks;
-  /* multiply by 64 to make a byte count */
-  lsb = t << 6;
-  msb = t >> 26;
-  /* add the count */
-  t = lsb;
-  if( (lsb += hd->count) < t )
-    msb++;
-  /* multiply by 8 to make a bit count */
-  t = lsb;
-  lsb <<= 3;
-  msb <<= 3;
-  msb |= t >> 29;
-
-  if( hd->count < 56 )  /* enough room */
-    {
-      hd->buf[hd->count++] = 0x80; /* pad */
-      while( hd->count < 56 )
-        hd->buf[hd->count++] = 0;  /* pad */
-    }
-  else  /* need one extra block */
-    {
-      hd->buf[hd->count++] = 0x80; /* pad character */
-      while( hd->count < 64 )
-        hd->buf[hd->count++] = 0;
-      sha1_write(hd, NULL, 0);  /* flush */;
-      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
-    }
-  /* append the 64 bit count */
-  hd->buf[56] = msb >> 24;
-  hd->buf[57] = msb >> 16;
-  hd->buf[58] = msb >>  8;
-  hd->buf[59] = msb       ;
-  hd->buf[60] = lsb >> 24;
-  hd->buf[61] = lsb >> 16;
-  hd->buf[62] = lsb >>  8;
-  hd->buf[63] = lsb       ;
-  TRANSFORM( hd, hd->buf, 1 );
-  _gcry_burn_stack (88+4*sizeof(void*));
-
-  p = hd->buf;
-#ifdef WORDS_BIGENDIAN
-#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
-#else /* little endian */
-#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;         \
-                  *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
-#endif
-  X(0);
-  X(1);
-  X(2);
-  X(3);
-  X(4);
-#undef X
-
-}
-
-static unsigned char *
-sha1_read( void *context )
-{
-  SHA1_CONTEXT *hd = context;
-
-  return hd->buf;
-}
-
-/****************
- * Shortcut functions which puts the hash value of the supplied buffer
- * into outbuf which must have a size of 20 bytes.
- */
-void
-_gcry_sha1_hash_buffer (void *outbuf, const void *buffer, size_t length)
-{
-  SHA1_CONTEXT hd;
-
-  sha1_init (&hd);
-  sha1_write (&hd, buffer, length);
-  sha1_final (&hd);
-  memcpy (outbuf, hd.buf, 20);
-}
-
-
-\f
-/* 
-     Self-test section.
- */
-
-
-static gpg_err_code_t
-selftests_sha1 (int extended, selftest_report_func_t report)
-{
-  const char *what;
-  const char *errtxt;
-  
-  what = "short string";
-  errtxt = _gcry_hash_selftest_check_one
-    (GCRY_MD_SHA1, 0, 
-     "abc", 3,
-     "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E"
-     "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D", 20);
-  if (errtxt)
-    goto failed;
-
-  if (extended)
-    {
-      what = "long string";
-      errtxt = _gcry_hash_selftest_check_one
-        (GCRY_MD_SHA1, 0, 
-         "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
-         "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE"
-         "\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1", 20);
-      if (errtxt)
-        goto failed;
-      
-      what = "one million \"a\"";
-      errtxt = _gcry_hash_selftest_check_one
-        (GCRY_MD_SHA1, 1,
-         NULL, 0,
-         "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E"
-         "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F", 20);
-      if (errtxt)
-        goto failed;
-    }
-
-  return 0; /* Succeeded. */
-
- failed:
-  if (report)
-    report ("digest", GCRY_MD_SHA1, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-
-/* Run a full self-test for ALGO and return 0 on success.  */
-static gpg_err_code_t
-run_selftests (int algo, int extended, selftest_report_func_t report)
-{
-  gpg_err_code_t ec;
-
-  switch (algo)
-    {
-    case GCRY_MD_SHA1:
-      ec = selftests_sha1 (extended, report);
-      break;
-    default:
-      ec = GPG_ERR_DIGEST_ALGO;
-      break;
-        
-    }
-  return ec;
-}
-
-
-
-\f
-static unsigned char asn[15] = /* Object ID is 1.3.14.3.2.26 */
-  { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
-    0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
-
-static gcry_md_oid_spec_t oid_spec_sha1[] =
-  {
-    /* iso.member-body.us.rsadsi.pkcs.pkcs-1.5 (sha1WithRSAEncryption) */
-    { "1.2.840.113549.1.1.5" },
-    /* iso.member-body.us.x9-57.x9cm.3 (dsaWithSha1)*/
-    { "1.2.840.10040.4.3" },
-    /* from NIST's OIW  (sha1) */
-    { "1.3.14.3.2.26" },
-    /* from NIST OIW (sha-1WithRSAEncryption) */
-    { "1.3.14.3.2.29" },
-    /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha1 */
-    { "1.2.840.10045.4.1" },
-    { NULL },
-  };
-
-gcry_md_spec_t _gcry_digest_spec_sha1 =
-  {
-    "SHA1", asn, DIM (asn), oid_spec_sha1, 20,
-    sha1_init, sha1_write, sha1_final, sha1_read,
-    sizeof (SHA1_CONTEXT)
-  };
-md_extra_spec_t _gcry_digest_extraspec_sha1 = 
-  {
-    run_selftests
-  };
-
diff --git a/lib/libgcrypt/cipher/sha256.c b/lib/libgcrypt/cipher/sha256.c
deleted file mode 100644 (file)
index 5d61d2f..0000000
+++ /dev/null
@@ -1,487 +0,0 @@
-/* sha256.c - SHA256 hash function
- *     Copyright (C) 2003, 2006, 2008 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-
-/*  Test vectors:
-    
-    "abc"
-    SHA224: 23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7
-    SHA256: ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
-
-    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
-    SHA224: 75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525
-    SHA256: 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
-    "a" one million times
-    SHA224: 20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67
-    SHA256: cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0
-
- */
-
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "g10lib.h"
-#include "memory.h"
-#include "bithelp.h"
-#include "cipher.h"
-#include "hash-common.h"
-
-typedef struct {
-  u32  h0,h1,h2,h3,h4,h5,h6,h7;
-  u32  nblocks;
-  byte buf[64];
-  int  count;
-} SHA256_CONTEXT;
-
-
-static void
-sha256_init (void *context)
-{
-  SHA256_CONTEXT *hd = context;
-
-  hd->h0 = 0x6a09e667;
-  hd->h1 = 0xbb67ae85;
-  hd->h2 = 0x3c6ef372;
-  hd->h3 = 0xa54ff53a;
-  hd->h4 = 0x510e527f;
-  hd->h5 = 0x9b05688c;
-  hd->h6 = 0x1f83d9ab;
-  hd->h7 = 0x5be0cd19;
-
-  hd->nblocks = 0;
-  hd->count = 0;
-}
-
-
-static void
-sha224_init (void *context)
-{
-  SHA256_CONTEXT *hd = context;
-
-  hd->h0 = 0xc1059ed8;
-  hd->h1 = 0x367cd507;
-  hd->h2 = 0x3070dd17;
-  hd->h3 = 0xf70e5939;
-  hd->h4 = 0xffc00b31;
-  hd->h5 = 0x68581511;
-  hd->h6 = 0x64f98fa7;
-  hd->h7 = 0xbefa4fa4;
-
-  hd->nblocks = 0;
-  hd->count = 0;
-}
-
-
-/*
-  Transform the message X which consists of 16 32-bit-words. See FIPS
-  180-2 for details.  */
-#define Cho(x,y,z) (z ^ (x & (y ^ z)))      /* (4.2) same as SHA-1's F1 */
-#define Maj(x,y,z) ((x & y) | (z & (x|y)))  /* (4.3) same as SHA-1's F3 */
-#define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22))  /* (4.4) */
-#define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25))  /* (4.5) */
-#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3))       /* (4.6) */
-#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10))     /* (4.7) */
-#define R(a,b,c,d,e,f,g,h,k,w) do                                 \
-          {                                                       \
-            t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w);  \
-            t2 = Sum0((a)) + Maj((a),(b),(c));                    \
-            h = g;                                                \
-            g = f;                                                \
-            f = e;                                                \
-            e = d + t1;                                           \
-            d = c;                                                \
-            c = b;                                                \
-            b = a;                                                \
-            a = t1 + t2;                                          \
-          } while (0)
-static void
-transform (SHA256_CONTEXT *hd, const unsigned char *data)
-{
-  static const u32 K[64] = {
-    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
-    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
-    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
-    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 
-    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
-    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
-    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
-    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
-    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
-    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
-    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
-    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
-    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
-    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
-    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
-    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-  };
-
-  u32 a,b,c,d,e,f,g,h,t1,t2;
-  u32 x[16];
-  u32 w[64];
-  int i;
-  
-  a = hd->h0;
-  b = hd->h1;
-  c = hd->h2;
-  d = hd->h3;
-  e = hd->h4;
-  f = hd->h5;
-  g = hd->h6;
-  h = hd->h7;
-  
-#ifdef WORDS_BIGENDIAN
-  memcpy (x, data, 64);
-#else
-  { 
-    byte *p2;
-  
-    for (i=0, p2=(byte*)x; i < 16; i++, p2 += 4 ) 
-      {
-        p2[3] = *data++;
-        p2[2] = *data++;
-        p2[1] = *data++;
-        p2[0] = *data++;
-      }
-  }
-#endif
-
-  for (i=0; i < 16; i++)
-    w[i] = x[i];
-  for (; i < 64; i++)
-    w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
-
-  for (i=0; i < 64; i++)
-    R(a,b,c,d,e,f,g,h,K[i],w[i]);
-
-  hd->h0 += a;
-  hd->h1 += b;
-  hd->h2 += c;
-  hd->h3 += d;
-  hd->h4 += e;
-  hd->h5 += f;
-  hd->h6 += g;
-  hd->h7 += h;
-}
-#undef Cho
-#undef Maj
-#undef Sum0
-#undef Sum1
-#undef S0
-#undef S1
-#undef R
-
-
-/* Update the message digest with the contents of INBUF with length
-  INLEN.  */
-static void
-sha256_write (void *context, const void *inbuf_arg, size_t inlen)
-{
-  const unsigned char *inbuf = inbuf_arg;
-  SHA256_CONTEXT *hd = context;
-
-  if (hd->count == 64)
-    { /* flush the buffer */
-      transform (hd, hd->buf);
-      _gcry_burn_stack (74*4+32);
-      hd->count = 0;
-      hd->nblocks++;
-    }
-  if (!inbuf)
-    return;
-  if (hd->count)
-    {
-      for (; inlen && hd->count < 64; inlen--)
-        hd->buf[hd->count++] = *inbuf++;
-      sha256_write (hd, NULL, 0);
-      if (!inlen)
-        return;
-    }
-
-  while (inlen >= 64)
-    {
-      transform (hd, inbuf);
-      hd->count = 0;
-      hd->nblocks++;
-      inlen -= 64;
-      inbuf += 64;
-    }
-  _gcry_burn_stack (74*4+32);
-  for (; inlen && hd->count < 64; inlen--)
-    hd->buf[hd->count++] = *inbuf++;
-}
-
-
-/*
-   The routine finally terminates the computation and returns the
-   digest.  The handle is prepared for a new cycle, but adding bytes
-   to the handle will the destroy the returned buffer.  Returns: 32
-   bytes with the message the digest.  */
-static void
-sha256_final(void *context)
-{
-  SHA256_CONTEXT *hd = context;
-  u32 t, msb, lsb;
-  byte *p;
-  
-  sha256_write (hd, NULL, 0); /* flush */;
-
-  t = hd->nblocks;
-  /* multiply by 64 to make a byte count */
-  lsb = t << 6;
-  msb = t >> 26;
-  /* add the count */
-  t = lsb;
-  if ((lsb += hd->count) < t)
-    msb++;
-  /* multiply by 8 to make a bit count */
-  t = lsb;
-  lsb <<= 3;
-  msb <<= 3;
-  msb |= t >> 29;
-
-  if (hd->count < 56)
-    { /* enough room */
-      hd->buf[hd->count++] = 0x80; /* pad */
-      while (hd->count < 56)
-        hd->buf[hd->count++] = 0;  /* pad */
-    }
-  else
-    { /* need one extra block */
-      hd->buf[hd->count++] = 0x80; /* pad character */
-      while (hd->count < 64)
-        hd->buf[hd->count++] = 0;
-      sha256_write (hd, NULL, 0);  /* flush */;
-      memset (hd->buf, 0, 56 ); /* fill next block with zeroes */
-    }
-  /* append the 64 bit count */
-  hd->buf[56] = msb >> 24;
-  hd->buf[57] = msb >> 16;
-  hd->buf[58] = msb >>  8;
-  hd->buf[59] = msb;
-  hd->buf[60] = lsb >> 24;
-  hd->buf[61] = lsb >> 16;
-  hd->buf[62] = lsb >>  8;
-  hd->buf[63] = lsb;
-  transform (hd, hd->buf);
-  _gcry_burn_stack (74*4+32);
-
-  p = hd->buf;
-#ifdef WORDS_BIGENDIAN
-#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
-#else /* little endian */
-#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;         \
-                 *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
-#endif
-  X(0);
-  X(1);
-  X(2);
-  X(3);
-  X(4);
-  X(5);
-  X(6);
-  X(7);
-#undef X
-}
-
-static byte *
-sha256_read (void *context)
-{
-  SHA256_CONTEXT *hd = context;
-
-  return hd->buf;
-}
-
-
-\f
-/* 
-     Self-test section.
- */
-
-
-static gpg_err_code_t
-selftests_sha224 (int extended, selftest_report_func_t report)
-{
-  const char *what;
-  const char *errtxt;
-  
-  what = "short string";
-  errtxt = _gcry_hash_selftest_check_one
-    (GCRY_MD_SHA224, 0, 
-     "abc", 3,
-     "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3"
-     "\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7", 28);
-  if (errtxt)
-    goto failed;
-
-  if (extended)
-    {
-      what = "long string";
-      errtxt = _gcry_hash_selftest_check_one
-        (GCRY_MD_SHA224, 0, 
-         "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
-         "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50"
-         "\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25", 28);
-      if (errtxt)
-        goto failed;
-      
-      what = "one million \"a\"";
-      errtxt = _gcry_hash_selftest_check_one
-        (GCRY_MD_SHA224, 1,
-         NULL, 0,
-         "\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b"
-         "\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67", 28);
-      if (errtxt)
-        goto failed;
-    }
-
-  return 0; /* Succeeded. */
-
- failed:
-  if (report)
-    report ("digest", GCRY_MD_SHA224, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-static gpg_err_code_t
-selftests_sha256 (int extended, selftest_report_func_t report)
-{
-  const char *what;
-  const char *errtxt;
-  
-  what = "short string";
-  errtxt = _gcry_hash_selftest_check_one
-    (GCRY_MD_SHA256, 0, 
-     "abc", 3,
-     "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23"
-     "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad", 32);
-  if (errtxt)
-    goto failed;
-
-  if (extended)
-    {
-      what = "long string";
-      errtxt = _gcry_hash_selftest_check_one
-        (GCRY_MD_SHA256, 0, 
-         "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
-         "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
-         "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1",
-         32);
-      if (errtxt)
-        goto failed;
-      
-      what = "one million \"a\"";
-      errtxt = _gcry_hash_selftest_check_one
-        (GCRY_MD_SHA256, 1,
-         NULL, 0,
-         "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
-         "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0",
-         32);
-      if (errtxt)
-        goto failed;
-    }
-
-  return 0; /* Succeeded. */
-
- failed:
-  if (report)
-    report ("digest", GCRY_MD_SHA256, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-
-/* Run a full self-test for ALGO and return 0 on success.  */
-static gpg_err_code_t
-run_selftests (int algo, int extended, selftest_report_func_t report)
-{
-  gpg_err_code_t ec;
-
-  switch (algo)
-    {
-    case GCRY_MD_SHA224:
-      ec = selftests_sha224 (extended, report);
-      break;
-    case GCRY_MD_SHA256:
-      ec = selftests_sha256 (extended, report);
-      break;
-    default:
-      ec = GPG_ERR_DIGEST_ALGO;
-      break;
-        
-    }
-  return ec;
-}
-
-
-
-\f
-static byte asn224[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */
-  { 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
-    0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
-    0x1C
-  };
-
-static gcry_md_oid_spec_t oid_spec_sha224[] =
-  {
-    /* From RFC3874, Section 4 */
-    { "2.16.840.1.101.3.4.2.4" }, 
-    { NULL },
-  };
-
-static byte asn256[19] = /* Object ID is  2.16.840.1.101.3.4.2.1 */
-  { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-    0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
-    0x00, 0x04, 0x20 };
-
-static gcry_md_oid_spec_t oid_spec_sha256[] =
-  {
-    /* According to the OpenPGP draft rfc2440-bis06 */
-    { "2.16.840.1.101.3.4.2.1" }, 
-    /* PKCS#1 sha256WithRSAEncryption */
-    { "1.2.840.113549.1.1.11" },
-
-    { NULL },
-  };
-
-gcry_md_spec_t _gcry_digest_spec_sha224 =
-  {
-    "SHA224", asn224, DIM (asn224), oid_spec_sha224, 28,
-    sha224_init, sha256_write, sha256_final, sha256_read,
-    sizeof (SHA256_CONTEXT)
-  };
-md_extra_spec_t _gcry_digest_extraspec_sha224 = 
-  {
-    run_selftests
-  };
-
-gcry_md_spec_t _gcry_digest_spec_sha256 =
-  {
-    "SHA256", asn256, DIM (asn256), oid_spec_sha256, 32,
-    sha256_init, sha256_write, sha256_final, sha256_read,
-    sizeof (SHA256_CONTEXT)
-  };
-md_extra_spec_t _gcry_digest_extraspec_sha256 = 
-  {
-    run_selftests
-  };
diff --git a/lib/libgcrypt/cipher/sha512.c b/lib/libgcrypt/cipher/sha512.c
deleted file mode 100644 (file)
index bbbd4c5..0000000
+++ /dev/null
@@ -1,553 +0,0 @@
-/* sha512.c - SHA384 and SHA512 hash functions
- *     Copyright (C) 2003, 2008 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser general Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-
-/*  Test vectors from FIPS-180-2:
- *
- *  "abc"
- * 384:
- *  CB00753F 45A35E8B B5A03D69 9AC65007 272C32AB 0EDED163
- *  1A8B605A 43FF5BED 8086072B A1E7CC23 58BAECA1 34C825A7
- * 512:
- *  DDAF35A1 93617ABA CC417349 AE204131 12E6FA4E 89A97EA2 0A9EEEE6 4B55D39A
- *  2192992A 274FC1A8 36BA3C23 A3FEEBBD 454D4423 643CE80E 2A9AC94F A54CA49F
- *
- *  "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
- * 384:
- *  09330C33 F71147E8 3D192FC7 82CD1B47 53111B17 3B3B05D2
- *  2FA08086 E3B0F712 FCC7C71A 557E2DB9 66C3E9FA 91746039
- * 512:
- *  8E959B75 DAE313DA 8CF4F728 14FC143F 8F7779C6 EB9F7FA1 7299AEAD B6889018
- *  501D289E 4900F7E4 331B99DE C4B5433A C7D329EE B6DD2654 5E96E55B 874BE909
- *
- *  "a" x 1000000
- * 384:
- *  9D0E1809 716474CB 086E834E 310A4A1C ED149E9C 00F24852
- *  7972CEC5 704C2A5B 07B8B3DC 38ECC4EB AE97DDD8 7F3D8985
- * 512:
- *  E718483D 0CE76964 4E2E42C7 BC15B463 8E1F98B1 3B204428 5632A803 AFA973EB
- *  DE0FF244 877EA60A 4CB0432C E577C31B EB009C5C 2C49AA2E 4EADB217 AD8CC09B
- */
-
-
-#include <config.h>
-#include <string.h>
-#include "g10lib.h"
-#include "bithelp.h"
-#include "cipher.h"
-#include "hash-common.h"
-
-typedef struct
-{
-  u64 h0, h1, h2, h3, h4, h5, h6, h7;
-  u64 nblocks;
-  byte buf[128];
-  int count;
-} SHA512_CONTEXT;
-
-static void
-sha512_init (void *context)
-{
-  SHA512_CONTEXT *hd = context;
-
-  hd->h0 = U64_C(0x6a09e667f3bcc908);
-  hd->h1 = U64_C(0xbb67ae8584caa73b);
-  hd->h2 = U64_C(0x3c6ef372fe94f82b);
-  hd->h3 = U64_C(0xa54ff53a5f1d36f1);
-  hd->h4 = U64_C(0x510e527fade682d1);
-  hd->h5 = U64_C(0x9b05688c2b3e6c1f);
-  hd->h6 = U64_C(0x1f83d9abfb41bd6b);
-  hd->h7 = U64_C(0x5be0cd19137e2179);
-
-  hd->nblocks = 0;
-  hd->count = 0;
-}
-
-static void
-sha384_init (void *context)
-{
-  SHA512_CONTEXT *hd = context;
-
-  hd->h0 = U64_C(0xcbbb9d5dc1059ed8);
-  hd->h1 = U64_C(0x629a292a367cd507);
-  hd->h2 = U64_C(0x9159015a3070dd17);
-  hd->h3 = U64_C(0x152fecd8f70e5939);
-  hd->h4 = U64_C(0x67332667ffc00b31);
-  hd->h5 = U64_C(0x8eb44a8768581511);
-  hd->h6 = U64_C(0xdb0c2e0d64f98fa7);
-  hd->h7 = U64_C(0x47b5481dbefa4fa4);
-
-  hd->nblocks = 0;
-  hd->count = 0;
-}
-
-
-/****************
- * Transform the message W which consists of 16 64-bit-words
- */
-static void
-transform (SHA512_CONTEXT *hd, const unsigned char *data)
-{
-  u64 a, b, c, d, e, f, g, h;
-  u64 w[80];
-  int t;
-  static const u64 k[] =
-    {
-      U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd),
-      U64_C(0xb5c0fbcfec4d3b2f), U64_C(0xe9b5dba58189dbbc),
-      U64_C(0x3956c25bf348b538), U64_C(0x59f111f1b605d019),
-      U64_C(0x923f82a4af194f9b), U64_C(0xab1c5ed5da6d8118),
-      U64_C(0xd807aa98a3030242), U64_C(0x12835b0145706fbe),
-      U64_C(0x243185be4ee4b28c), U64_C(0x550c7dc3d5ffb4e2),
-      U64_C(0x72be5d74f27b896f), U64_C(0x80deb1fe3b1696b1),
-      U64_C(0x9bdc06a725c71235), U64_C(0xc19bf174cf692694),
-      U64_C(0xe49b69c19ef14ad2), U64_C(0xefbe4786384f25e3),
-      U64_C(0x0fc19dc68b8cd5b5), U64_C(0x240ca1cc77ac9c65),
-      U64_C(0x2de92c6f592b0275), U64_C(0x4a7484aa6ea6e483),
-      U64_C(0x5cb0a9dcbd41fbd4), U64_C(0x76f988da831153b5),
-      U64_C(0x983e5152ee66dfab), U64_C(0xa831c66d2db43210),
-      U64_C(0xb00327c898fb213f), U64_C(0xbf597fc7beef0ee4),
-      U64_C(0xc6e00bf33da88fc2), U64_C(0xd5a79147930aa725),
-      U64_C(0x06ca6351e003826f), U64_C(0x142929670a0e6e70),
-      U64_C(0x27b70a8546d22ffc), U64_C(0x2e1b21385c26c926),
-      U64_C(0x4d2c6dfc5ac42aed), U64_C(0x53380d139d95b3df),
-      U64_C(0x650a73548baf63de), U64_C(0x766a0abb3c77b2a8),
-      U64_C(0x81c2c92e47edaee6), U64_C(0x92722c851482353b),
-      U64_C(0xa2bfe8a14cf10364), U64_C(0xa81a664bbc423001),
-      U64_C(0xc24b8b70d0f89791), U64_C(0xc76c51a30654be30),
-      U64_C(0xd192e819d6ef5218), U64_C(0xd69906245565a910),
-      U64_C(0xf40e35855771202a), U64_C(0x106aa07032bbd1b8),
-      U64_C(0x19a4c116b8d2d0c8), U64_C(0x1e376c085141ab53),
-      U64_C(0x2748774cdf8eeb99), U64_C(0x34b0bcb5e19b48a8),
-      U64_C(0x391c0cb3c5c95a63), U64_C(0x4ed8aa4ae3418acb),
-      U64_C(0x5b9cca4f7763e373), U64_C(0x682e6ff3d6b2b8a3),
-      U64_C(0x748f82ee5defb2fc), U64_C(0x78a5636f43172f60),
-      U64_C(0x84c87814a1f0ab72), U64_C(0x8cc702081a6439ec),
-      U64_C(0x90befffa23631e28), U64_C(0xa4506cebde82bde9),
-      U64_C(0xbef9a3f7b2c67915), U64_C(0xc67178f2e372532b),
-      U64_C(0xca273eceea26619c), U64_C(0xd186b8c721c0c207),
-      U64_C(0xeada7dd6cde0eb1e), U64_C(0xf57d4f7fee6ed178),
-      U64_C(0x06f067aa72176fba), U64_C(0x0a637dc5a2c898a6),
-      U64_C(0x113f9804bef90dae), U64_C(0x1b710b35131c471b),
-      U64_C(0x28db77f523047d84), U64_C(0x32caab7b40c72493),
-      U64_C(0x3c9ebe0a15c9bebc), U64_C(0x431d67c49c100d4c),
-      U64_C(0x4cc5d4becb3e42b6), U64_C(0x597f299cfc657e2a),
-      U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817)
-    };
-
-  /* get values from the chaining vars */
-  a = hd->h0;
-  b = hd->h1;
-  c = hd->h2;
-  d = hd->h3;
-  e = hd->h4;
-  f = hd->h5;
-  g = hd->h6;
-  h = hd->h7;
-
-#ifdef WORDS_BIGENDIAN
-  memcpy (w, data, 128);
-#else
-  {
-    int i;
-    byte *p2;
-
-    for (i = 0, p2 = (byte *) w; i < 16; i++, p2 += 8)
-      {
-       p2[7] = *data++;
-       p2[6] = *data++;
-       p2[5] = *data++;
-       p2[4] = *data++;
-       p2[3] = *data++;
-       p2[2] = *data++;
-       p2[1] = *data++;
-       p2[0] = *data++;
-      }
-  }
-#endif
-
-#define ROTR(x,n) (((x)>>(n)) | ((x)<<(64-(n))))
-#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
-#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-#define Sum0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
-#define Sum1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
-#define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
-#define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
-
-  for (t = 16; t < 80; t++)
-    w[t] = S1 (w[t - 2]) + w[t - 7] + S0 (w[t - 15]) + w[t - 16];
-
-  for (t = 0; t < 80; t++)
-    {
-      u64 t1, t2;
-
-      t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t];
-      t2 = Sum0 (a) + Maj (a, b, c);
-      h = g;
-      g = f;
-      f = e;
-      e = d + t1;
-      d = c;
-      c = b;
-      b = a;
-      a = t1 + t2;
-
-      /* printf("t=%d a=%016llX b=%016llX c=%016llX d=%016llX "
-          "e=%016llX f=%016llX g=%016llX h=%016llX\n",t,a,b,c,d,e,f,g,h); */
-    }
-
-  /* update chaining vars */
-  hd->h0 += a;
-  hd->h1 += b;
-  hd->h2 += c;
-  hd->h3 += d;
-  hd->h4 += e;
-  hd->h5 += f;
-  hd->h6 += g;
-  hd->h7 += h;
-}
-
-
-/* Update the message digest with the contents
- * of INBUF with length INLEN.
- */
-static void
-sha512_write (void *context, const void *inbuf_arg, size_t inlen)
-{
-  const unsigned char *inbuf = inbuf_arg;
-  SHA512_CONTEXT *hd = context;
-
-  if (hd->count == 128)
-    {                          /* flush the buffer */
-      transform (hd, hd->buf);
-      _gcry_burn_stack (768);
-      hd->count = 0;
-      hd->nblocks++;
-    }
-  if (!inbuf)
-    return;
-  if (hd->count)
-    {
-      for (; inlen && hd->count < 128; inlen--)
-       hd->buf[hd->count++] = *inbuf++;
-      sha512_write (context, NULL, 0);
-      if (!inlen)
-       return;
-    }
-
-  while (inlen >= 128)
-    {
-      transform (hd, inbuf);
-      hd->count = 0;
-      hd->nblocks++;
-      inlen -= 128;
-      inbuf += 128;
-    }
-  _gcry_burn_stack (768);
-  for (; inlen && hd->count < 128; inlen--)
-    hd->buf[hd->count++] = *inbuf++;
-}
-
-
-/* The routine final terminates the computation and
- * returns the digest.
- * The handle is prepared for a new cycle, but adding bytes to the
- * handle will the destroy the returned buffer.
- * Returns: 64 bytes representing the digest.  When used for sha384,
- * we take the leftmost 48 of those bytes.
- */
-
-static void
-sha512_final (void *context)
-{
-  SHA512_CONTEXT *hd = context;
-  u64 t, msb, lsb;
-  byte *p;
-
-  sha512_write (context, NULL, 0); /* flush */ ;
-
-  t = hd->nblocks;
-  /* multiply by 128 to make a byte count */
-  lsb = t << 7;
-  msb = t >> 57;
-  /* add the count */
-  t = lsb;
-  if ((lsb += hd->count) < t)
-    msb++;
-  /* multiply by 8 to make a bit count */
-  t = lsb;
-  lsb <<= 3;
-  msb <<= 3;
-  msb |= t >> 61;
-
-  if (hd->count < 112)
-    {                          /* enough room */
-      hd->buf[hd->count++] = 0x80;     /* pad */
-      while (hd->count < 112)
-       hd->buf[hd->count++] = 0;       /* pad */
-    }
-  else
-    {                          /* need one extra block */
-      hd->buf[hd->count++] = 0x80;     /* pad character */
-      while (hd->count < 128)
-       hd->buf[hd->count++] = 0;
-      sha512_write (context, NULL, 0); /* flush */ ;
-      memset (hd->buf, 0, 112);        /* fill next block with zeroes */
-    }
-  /* append the 128 bit count */
-  hd->buf[112] = msb >> 56;
-  hd->buf[113] = msb >> 48;
-  hd->buf[114] = msb >> 40;
-  hd->buf[115] = msb >> 32;
-  hd->buf[116] = msb >> 24;
-  hd->buf[117] = msb >> 16;
-  hd->buf[118] = msb >> 8;
-  hd->buf[119] = msb;
-
-  hd->buf[120] = lsb >> 56;
-  hd->buf[121] = lsb >> 48;
-  hd->buf[122] = lsb >> 40;
-  hd->buf[123] = lsb >> 32;
-  hd->buf[124] = lsb >> 24;
-  hd->buf[125] = lsb >> 16;
-  hd->buf[126] = lsb >> 8;
-  hd->buf[127] = lsb;
-  transform (hd, hd->buf);
-  _gcry_burn_stack (768);
-
-  p = hd->buf;
-#ifdef WORDS_BIGENDIAN
-#define X(a) do { *(u64*)p = hd->h##a ; p += 8; } while (0)
-#else /* little endian */
-#define X(a) do { *p++ = hd->h##a >> 56; *p++ = hd->h##a >> 48;              \
-                  *p++ = hd->h##a >> 40; *p++ = hd->h##a >> 32;              \
-                  *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;              \
-                  *p++ = hd->h##a >> 8;  *p++ = hd->h##a; } while (0)
-#endif
-  X (0);
-  X (1);
-  X (2);
-  X (3);
-  X (4);
-  X (5);
-  /* Note that these last two chunks are included even for SHA384.
-     We just ignore them. */
-  X (6);
-  X (7);
-#undef X
-}
-
-static byte *
-sha512_read (void *context)
-{
-  SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context;
-  return hd->buf;
-}
-
-
-\f
-/* 
-     Self-test section.
- */
-
-
-static gpg_err_code_t
-selftests_sha384 (int extended, selftest_report_func_t report)
-{
-  const char *what;
-  const char *errtxt;
-  
-  what = "short string";
-  errtxt = _gcry_hash_selftest_check_one
-    (GCRY_MD_SHA384, 0, 
-     "abc", 3,
-     "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07"
-     "\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed"
-     "\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7", 48);
-  if (errtxt)
-    goto failed;
-
-  if (extended)
-    {
-      what = "long string";
-      errtxt = _gcry_hash_selftest_check_one
-        (GCRY_MD_SHA384, 0, 
-         "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
-         "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, 
-         "\x09\x33\x0C\x33\xF7\x11\x47\xE8\x3D\x19\x2F\xC7\x82\xCD\x1B\x47"
-         "\x53\x11\x1B\x17\x3B\x3B\x05\xD2\x2F\xA0\x80\x86\xE3\xB0\xF7\x12"
-         "\xFC\xC7\xC7\x1A\x55\x7E\x2D\xB9\x66\xC3\xE9\xFA\x91\x74\x60\x39",
-         48);
-      if (errtxt)
-        goto failed;
-
-      what = "one million \"a\"";
-      errtxt = _gcry_hash_selftest_check_one
-        (GCRY_MD_SHA384, 1,
-         NULL, 0,
-         "\x9D\x0E\x18\x09\x71\x64\x74\xCB\x08\x6E\x83\x4E\x31\x0A\x4A\x1C"
-         "\xED\x14\x9E\x9C\x00\xF2\x48\x52\x79\x72\xCE\xC5\x70\x4C\x2A\x5B"
-         "\x07\xB8\xB3\xDC\x38\xEC\xC4\xEB\xAE\x97\xDD\xD8\x7F\x3D\x89\x85",
-         48);
-      if (errtxt)
-        goto failed;
-    }
-
-  return 0; /* Succeeded. */
-
- failed:
-  if (report)
-    report ("digest", GCRY_MD_SHA384, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-static gpg_err_code_t
-selftests_sha512 (int extended, selftest_report_func_t report)
-{
-  const char *what;
-  const char *errtxt;
-  
-  what = "short string";
-  errtxt = _gcry_hash_selftest_check_one
-    (GCRY_MD_SHA512, 0, 
-     "abc", 3,
-     "\xDD\xAF\x35\xA1\x93\x61\x7A\xBA\xCC\x41\x73\x49\xAE\x20\x41\x31"
-     "\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A"
-     "\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD"
-     "\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F", 64);
-  if (errtxt)
-    goto failed;
-
-  if (extended)
-    {
-      what = "long string";
-      errtxt = _gcry_hash_selftest_check_one
-        (GCRY_MD_SHA512, 0, 
-         "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
-         "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, 
-         "\x8E\x95\x9B\x75\xDA\xE3\x13\xDA\x8C\xF4\xF7\x28\x14\xFC\x14\x3F"
-         "\x8F\x77\x79\xC6\xEB\x9F\x7F\xA1\x72\x99\xAE\xAD\xB6\x88\x90\x18"
-         "\x50\x1D\x28\x9E\x49\x00\xF7\xE4\x33\x1B\x99\xDE\xC4\xB5\x43\x3A"
-         "\xC7\xD3\x29\xEE\xB6\xDD\x26\x54\x5E\x96\xE5\x5B\x87\x4B\xE9\x09",
-         64);
-      if (errtxt)
-        goto failed;
-      
-      what = "one million \"a\"";
-      errtxt = _gcry_hash_selftest_check_one
-        (GCRY_MD_SHA512, 1,
-         NULL, 0,
-         "\xE7\x18\x48\x3D\x0C\xE7\x69\x64\x4E\x2E\x42\xC7\xBC\x15\xB4\x63"
-         "\x8E\x1F\x98\xB1\x3B\x20\x44\x28\x56\x32\xA8\x03\xAF\xA9\x73\xEB"
-         "\xDE\x0F\xF2\x44\x87\x7E\xA6\x0A\x4C\xB0\x43\x2C\xE5\x77\xC3\x1B"
-         "\xEB\x00\x9C\x5C\x2C\x49\xAA\x2E\x4E\xAD\xB2\x17\xAD\x8C\xC0\x9B",
-         64);
-      if (errtxt)
-        goto failed;
-    }
-
-  return 0; /* Succeeded. */
-
- failed:
-  if (report)
-    report ("digest", GCRY_MD_SHA512, what, errtxt);
-  return GPG_ERR_SELFTEST_FAILED;
-}
-
-
-/* Run a full self-test for ALGO and return 0 on success.  */
-static gpg_err_code_t
-run_selftests (int algo, int extended, selftest_report_func_t report)
-{
-  gpg_err_code_t ec;
-
-  switch (algo)
-    {
-    case GCRY_MD_SHA384:
-      ec = selftests_sha384 (extended, report);
-      break;
-    case GCRY_MD_SHA512:
-      ec = selftests_sha512 (extended, report);
-      break;
-    default:
-      ec = GPG_ERR_DIGEST_ALGO;
-      break;
-        
-    }
-  return ec;
-}
-
-
-
-\f
-static byte sha512_asn[] =     /* Object ID is 2.16.840.1.101.3.4.2.3 */
-  {
-    0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-    0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
-    0x00, 0x04, 0x40
-  };
-
-static gcry_md_oid_spec_t oid_spec_sha512[] =
-  {
-    { "2.16.840.1.101.3.4.2.3" },
-
-    /* PKCS#1 sha512WithRSAEncryption */
-    { "1.2.840.113549.1.1.13" },
-
-    { NULL }
-  };
-
-gcry_md_spec_t _gcry_digest_spec_sha512 = 
-  {
-    "SHA512", sha512_asn, DIM (sha512_asn), oid_spec_sha512, 64,
-    sha512_init, sha512_write, sha512_final, sha512_read,
-    sizeof (SHA512_CONTEXT),
-  };
-md_extra_spec_t _gcry_digest_extraspec_sha512 = 
-  {
-    run_selftests
-  };
-
-static byte sha384_asn[] =     /* Object ID is 2.16.840.1.101.3.4.2.2 */
-  {
-    0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-    0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
-    0x00, 0x04, 0x30
-  };
-
-static gcry_md_oid_spec_t oid_spec_sha384[] =
-  {
-    { "2.16.840.1.101.3.4.2.2" }, 
-
-    /* PKCS#1 sha384WithRSAEncryption */
-    { "1.2.840.113549.1.1.12" },
-
-    { NULL },
-  };
-
-gcry_md_spec_t _gcry_digest_spec_sha384 = 
-  {
-    "SHA384", sha384_asn, DIM (sha384_asn), oid_spec_sha384, 48,
-    sha384_init, sha512_write, sha512_final, sha512_read,
-    sizeof (SHA512_CONTEXT),
-  };
-md_extra_spec_t _gcry_digest_extraspec_sha384 = 
-  {
-    run_selftests
-  };
diff --git a/lib/libgcrypt/cipher/tiger.c b/lib/libgcrypt/cipher/tiger.c
deleted file mode 100644 (file)
index a620045..0000000
+++ /dev/null
@@ -1,851 +0,0 @@
-/* tiger.c  -  The TIGER hash function
- *     Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "g10lib.h"
-#include "memory.h"
-#include "cipher.h"
-
-#ifdef HAVE_U64_TYPEDEF
-
-/* we really need it here, but as this is only experiment we
- * can live without Tiger */
-
-typedef struct {
-    u64  a, b, c;
-    byte buf[64];
-    int  count;
-    u32  nblocks;
-} TIGER_CONTEXT;
-
-
-/*********************************
- * Okay, okay, this is not the fastest code - improvements are welcome.
- *
- */
-
-/* Some test vectors:
- * ""                   24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A
- * "abc"                F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951
- * "Tiger"              9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF
- * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"
- *                     87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386
- * "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789"
- *                     467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197
- * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham"
- *                     0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303
- * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proc"
- * "eedings of Fast Software Encryption 3, Cambridge."
- *                     EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193
- * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proc"
- * "eedings of Fast Software Encryption 3, Cambridge, 1996."
- *                     3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC
- * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEF"
- * "GHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"
- *                     00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4
- */
-
-static u64 sbox1[256] = {
-  U64_C(0x02aab17cf7e90c5e) /*    0 */, U64_C(0xac424b03e243a8ec) /*    1 */,
-  U64_C(0x72cd5be30dd5fcd3) /*    2 */, U64_C(0x6d019b93f6f97f3a) /*    3 */,
-  U64_C(0xcd9978ffd21f9193) /*    4 */, U64_C(0x7573a1c9708029e2) /*    5 */,
-  U64_C(0xb164326b922a83c3) /*    6 */, U64_C(0x46883eee04915870) /*    7 */,
-  U64_C(0xeaace3057103ece6) /*    8 */, U64_C(0xc54169b808a3535c) /*    9 */,
-  U64_C(0x4ce754918ddec47c) /*   10 */, U64_C(0x0aa2f4dfdc0df40c) /*   11 */,
-  U64_C(0x10b76f18a74dbefa) /*   12 */, U64_C(0xc6ccb6235ad1ab6a) /*   13 */,
-  U64_C(0x13726121572fe2ff) /*   14 */, U64_C(0x1a488c6f199d921e) /*   15 */,
-  U64_C(0x4bc9f9f4da0007ca) /*   16 */, U64_C(0x26f5e6f6e85241c7) /*   17 */,
-  U64_C(0x859079dbea5947b6) /*   18 */, U64_C(0x4f1885c5c99e8c92) /*   19 */,
-  U64_C(0xd78e761ea96f864b) /*   20 */, U64_C(0x8e36428c52b5c17d) /*   21 */,
-  U64_C(0x69cf6827373063c1) /*   22 */, U64_C(0xb607c93d9bb4c56e) /*   23 */,
-  U64_C(0x7d820e760e76b5ea) /*   24 */, U64_C(0x645c9cc6f07fdc42) /*   25 */,
-  U64_C(0xbf38a078243342e0) /*   26 */, U64_C(0x5f6b343c9d2e7d04) /*   27 */,
-  U64_C(0xf2c28aeb600b0ec6) /*   28 */, U64_C(0x6c0ed85f7254bcac) /*   29 */,
-  U64_C(0x71592281a4db4fe5) /*   30 */, U64_C(0x1967fa69ce0fed9f) /*   31 */,
-  U64_C(0xfd5293f8b96545db) /*   32 */, U64_C(0xc879e9d7f2a7600b) /*   33 */,
-  U64_C(0x860248920193194e) /*   34 */, U64_C(0xa4f9533b2d9cc0b3) /*   35 */,
-  U64_C(0x9053836c15957613) /*   36 */, U64_C(0xdb6dcf8afc357bf1) /*   37 */,
-  U64_C(0x18beea7a7a370f57) /*   38 */, U64_C(0x037117ca50b99066) /*   39 */,
-  U64_C(0x6ab30a9774424a35) /*   40 */, U64_C(0xf4e92f02e325249b) /*   41 */,
-  U64_C(0x7739db07061ccae1) /*   42 */, U64_C(0xd8f3b49ceca42a05) /*   43 */,
-  U64_C(0xbd56be3f51382f73) /*   44 */, U64_C(0x45faed5843b0bb28) /*   45 */,
-  U64_C(0x1c813d5c11bf1f83) /*   46 */, U64_C(0x8af0e4b6d75fa169) /*   47 */,
-  U64_C(0x33ee18a487ad9999) /*   48 */, U64_C(0x3c26e8eab1c94410) /*   49 */,
-  U64_C(0xb510102bc0a822f9) /*   50 */, U64_C(0x141eef310ce6123b) /*   51 */,
-  U64_C(0xfc65b90059ddb154) /*   52 */, U64_C(0xe0158640c5e0e607) /*   53 */,
-  U64_C(0x884e079826c3a3cf) /*   54 */, U64_C(0x930d0d9523c535fd) /*   55 */,
-  U64_C(0x35638d754e9a2b00) /*   56 */, U64_C(0x4085fccf40469dd5) /*   57 */,
-  U64_C(0xc4b17ad28be23a4c) /*   58 */, U64_C(0xcab2f0fc6a3e6a2e) /*   59 */,
-  U64_C(0x2860971a6b943fcd) /*   60 */, U64_C(0x3dde6ee212e30446) /*   61 */,
-  U64_C(0x6222f32ae01765ae) /*   62 */, U64_C(0x5d550bb5478308fe) /*   63 */,
-  U64_C(0xa9efa98da0eda22a) /*   64 */, U64_C(0xc351a71686c40da7) /*   65 */,
-  U64_C(0x1105586d9c867c84) /*   66 */, U64_C(0xdcffee85fda22853) /*   67 */,
-  U64_C(0xccfbd0262c5eef76) /*   68 */, U64_C(0xbaf294cb8990d201) /*   69 */,
-  U64_C(0xe69464f52afad975) /*   70 */, U64_C(0x94b013afdf133e14) /*   71 */,
-  U64_C(0x06a7d1a32823c958) /*   72 */, U64_C(0x6f95fe5130f61119) /*   73 */,
-  U64_C(0xd92ab34e462c06c0) /*   74 */, U64_C(0xed7bde33887c71d2) /*   75 */,
-  U64_C(0x79746d6e6518393e) /*   76 */, U64_C(0x5ba419385d713329) /*   77 */,
-  U64_C(0x7c1ba6b948a97564) /*   78 */, U64_C(0x31987c197bfdac67) /*   79 */,
-  U64_C(0xde6c23c44b053d02) /*   80 */, U64_C(0x581c49fed002d64d) /*   81 */,
-  U64_C(0xdd474d6338261571) /*   82 */, U64_C(0xaa4546c3e473d062) /*   83 */,
-  U64_C(0x928fce349455f860) /*   84 */, U64_C(0x48161bbacaab94d9) /*   85 */,
-  U64_C(0x63912430770e6f68) /*   86 */, U64_C(0x6ec8a5e602c6641c) /*   87 */,
-  U64_C(0x87282515337ddd2b) /*   88 */, U64_C(0x2cda6b42034b701b) /*   89 */,
-  U64_C(0xb03d37c181cb096d) /*   90 */, U64_C(0xe108438266c71c6f) /*   91 */,
-  U64_C(0x2b3180c7eb51b255) /*   92 */, U64_C(0xdf92b82f96c08bbc) /*   93 */,
-  U64_C(0x5c68c8c0a632f3ba) /*   94 */, U64_C(0x5504cc861c3d0556) /*   95 */,
-  U64_C(0xabbfa4e55fb26b8f) /*   96 */, U64_C(0x41848b0ab3baceb4) /*   97 */,
-  U64_C(0xb334a273aa445d32) /*   98 */, U64_C(0xbca696f0a85ad881) /*   99 */,
-  U64_C(0x24f6ec65b528d56c) /*  100 */, U64_C(0x0ce1512e90f4524a) /*  101 */,
-  U64_C(0x4e9dd79d5506d35a) /*  102 */, U64_C(0x258905fac6ce9779) /*  103 */,
-  U64_C(0x2019295b3e109b33) /*  104 */, U64_C(0xf8a9478b73a054cc) /*  105 */,
-  U64_C(0x2924f2f934417eb0) /*  106 */, U64_C(0x3993357d536d1bc4) /*  107 */,
-  U64_C(0x38a81ac21db6ff8b) /*  108 */, U64_C(0x47c4fbf17d6016bf) /*  109 */,
-  U64_C(0x1e0faadd7667e3f5) /*  110 */, U64_C(0x7abcff62938beb96) /*  111 */,
-  U64_C(0xa78dad948fc179c9) /*  112 */, U64_C(0x8f1f98b72911e50d) /*  113 */,
-  U64_C(0x61e48eae27121a91) /*  114 */, U64_C(0x4d62f7ad31859808) /*  115 */,
-  U64_C(0xeceba345ef5ceaeb) /*  116 */, U64_C(0xf5ceb25ebc9684ce) /*  117 */,
-  U64_C(0xf633e20cb7f76221) /*  118 */, U64_C(0xa32cdf06ab8293e4) /*  119 */,
-  U64_C(0x985a202ca5ee2ca4) /*  120 */, U64_C(0xcf0b8447cc8a8fb1) /*  121 */,
-  U64_C(0x9f765244979859a3) /*  122 */, U64_C(0xa8d516b1a1240017) /*  123 */,
-  U64_C(0x0bd7ba3ebb5dc726) /*  124 */, U64_C(0xe54bca55b86adb39) /*  125 */,
-  U64_C(0x1d7a3afd6c478063) /*  126 */, U64_C(0x519ec608e7669edd) /*  127 */,
-  U64_C(0x0e5715a2d149aa23) /*  128 */, U64_C(0x177d4571848ff194) /*  129 */,
-  U64_C(0xeeb55f3241014c22) /*  130 */, U64_C(0x0f5e5ca13a6e2ec2) /*  131 */,
-  U64_C(0x8029927b75f5c361) /*  132 */, U64_C(0xad139fabc3d6e436) /*  133 */,
-  U64_C(0x0d5df1a94ccf402f) /*  134 */, U64_C(0x3e8bd948bea5dfc8) /*  135 */,
-  U64_C(0xa5a0d357bd3ff77e) /*  136 */, U64_C(0xa2d12e251f74f645) /*  137 */,
-  U64_C(0x66fd9e525e81a082) /*  138 */, U64_C(0x2e0c90ce7f687a49) /*  139 */,
-  U64_C(0xc2e8bcbeba973bc5) /*  140 */, U64_C(0x000001bce509745f) /*  141 */,
-  U64_C(0x423777bbe6dab3d6) /*  142 */, U64_C(0xd1661c7eaef06eb5) /*  143 */,
-  U64_C(0xa1781f354daacfd8) /*  144 */, U64_C(0x2d11284a2b16affc) /*  145 */,
-  U64_C(0xf1fc4f67fa891d1f) /*  146 */, U64_C(0x73ecc25dcb920ada) /*  147 */,
-  U64_C(0xae610c22c2a12651) /*  148 */, U64_C(0x96e0a810d356b78a) /*  149 */,
-  U64_C(0x5a9a381f2fe7870f) /*  150 */, U64_C(0xd5ad62ede94e5530) /*  151 */,
-  U64_C(0xd225e5e8368d1427) /*  152 */, U64_C(0x65977b70c7af4631) /*  153 */,
-  U64_C(0x99f889b2de39d74f) /*  154 */, U64_C(0x233f30bf54e1d143) /*  155 */,
-  U64_C(0x9a9675d3d9a63c97) /*  156 */, U64_C(0x5470554ff334f9a8) /*  157 */,
-  U64_C(0x166acb744a4f5688) /*  158 */, U64_C(0x70c74caab2e4aead) /*  159 */,
-  U64_C(0xf0d091646f294d12) /*  160 */, U64_C(0x57b82a89684031d1) /*  161 */,
-  U64_C(0xefd95a5a61be0b6b) /*  162 */, U64_C(0x2fbd12e969f2f29a) /*  163 */,
-  U64_C(0x9bd37013feff9fe8) /*  164 */, U64_C(0x3f9b0404d6085a06) /*  165 */,
-  U64_C(0x4940c1f3166cfe15) /*  166 */, U64_C(0x09542c4dcdf3defb) /*  167 */,
-  U64_C(0xb4c5218385cd5ce3) /*  168 */, U64_C(0xc935b7dc4462a641) /*  169 */,
-  U64_C(0x3417f8a68ed3b63f) /*  170 */, U64_C(0xb80959295b215b40) /*  171 */,
-  U64_C(0xf99cdaef3b8c8572) /*  172 */, U64_C(0x018c0614f8fcb95d) /*  173 */,
-  U64_C(0x1b14accd1a3acdf3) /*  174 */, U64_C(0x84d471f200bb732d) /*  175 */,
-  U64_C(0xc1a3110e95e8da16) /*  176 */, U64_C(0x430a7220bf1a82b8) /*  177 */,
-  U64_C(0xb77e090d39df210e) /*  178 */, U64_C(0x5ef4bd9f3cd05e9d) /*  179 */,
-  U64_C(0x9d4ff6da7e57a444) /*  180 */, U64_C(0xda1d60e183d4a5f8) /*  181 */,
-  U64_C(0xb287c38417998e47) /*  182 */, U64_C(0xfe3edc121bb31886) /*  183 */,
-  U64_C(0xc7fe3ccc980ccbef) /*  184 */, U64_C(0xe46fb590189bfd03) /*  185 */,
-  U64_C(0x3732fd469a4c57dc) /*  186 */, U64_C(0x7ef700a07cf1ad65) /*  187 */,
-  U64_C(0x59c64468a31d8859) /*  188 */, U64_C(0x762fb0b4d45b61f6) /*  189 */,
-  U64_C(0x155baed099047718) /*  190 */, U64_C(0x68755e4c3d50baa6) /*  191 */,
-  U64_C(0xe9214e7f22d8b4df) /*  192 */, U64_C(0x2addbf532eac95f4) /*  193 */,
-  U64_C(0x32ae3909b4bd0109) /*  194 */, U64_C(0x834df537b08e3450) /*  195 */,
-  U64_C(0xfa209da84220728d) /*  196 */, U64_C(0x9e691d9b9efe23f7) /*  197 */,
-  U64_C(0x0446d288c4ae8d7f) /*  198 */, U64_C(0x7b4cc524e169785b) /*  199 */,
-  U64_C(0x21d87f0135ca1385) /*  200 */, U64_C(0xcebb400f137b8aa5) /*  201 */,
-  U64_C(0x272e2b66580796be) /*  202 */, U64_C(0x3612264125c2b0de) /*  203 */,
-  U64_C(0x057702bdad1efbb2) /*  204 */, U64_C(0xd4babb8eacf84be9) /*  205 */,
-  U64_C(0x91583139641bc67b) /*  206 */, U64_C(0x8bdc2de08036e024) /*  207 */,
-  U64_C(0x603c8156f49f68ed) /*  208 */, U64_C(0xf7d236f7dbef5111) /*  209 */,
-  U64_C(0x9727c4598ad21e80) /*  210 */, U64_C(0xa08a0896670a5fd7) /*  211 */,
-  U64_C(0xcb4a8f4309eba9cb) /*  212 */, U64_C(0x81af564b0f7036a1) /*  213 */,
-  U64_C(0xc0b99aa778199abd) /*  214 */, U64_C(0x959f1ec83fc8e952) /*  215 */,
-  U64_C(0x8c505077794a81b9) /*  216 */, U64_C(0x3acaaf8f056338f0) /*  217 */,
-  U64_C(0x07b43f50627a6778) /*  218 */, U64_C(0x4a44ab49f5eccc77) /*  219 */,
-  U64_C(0x3bc3d6e4b679ee98) /*  220 */, U64_C(0x9cc0d4d1cf14108c) /*  221 */,
-  U64_C(0x4406c00b206bc8a0) /*  222 */, U64_C(0x82a18854c8d72d89) /*  223 */,
-  U64_C(0x67e366b35c3c432c) /*  224 */, U64_C(0xb923dd61102b37f2) /*  225 */,
-  U64_C(0x56ab2779d884271d) /*  226 */, U64_C(0xbe83e1b0ff1525af) /*  227 */,
-  U64_C(0xfb7c65d4217e49a9) /*  228 */, U64_C(0x6bdbe0e76d48e7d4) /*  229 */,
-  U64_C(0x08df828745d9179e) /*  230 */, U64_C(0x22ea6a9add53bd34) /*  231 */,
-  U64_C(0xe36e141c5622200a) /*  232 */, U64_C(0x7f805d1b8cb750ee) /*  233 */,
-  U64_C(0xafe5c7a59f58e837) /*  234 */, U64_C(0xe27f996a4fb1c23c) /*  235 */,
-  U64_C(0xd3867dfb0775f0d0) /*  236 */, U64_C(0xd0e673de6e88891a) /*  237 */,
-  U64_C(0x123aeb9eafb86c25) /*  238 */, U64_C(0x30f1d5d5c145b895) /*  239 */,
-  U64_C(0xbb434a2dee7269e7) /*  240 */, U64_C(0x78cb67ecf931fa38) /*  241 */,
-  U64_C(0xf33b0372323bbf9c) /*  242 */, U64_C(0x52d66336fb279c74) /*  243 */,
-  U64_C(0x505f33ac0afb4eaa) /*  244 */, U64_C(0xe8a5cd99a2cce187) /*  245 */,
-  U64_C(0x534974801e2d30bb) /*  246 */, U64_C(0x8d2d5711d5876d90) /*  247 */,
-  U64_C(0x1f1a412891bc038e) /*  248 */, U64_C(0xd6e2e71d82e56648) /*  249 */,
-  U64_C(0x74036c3a497732b7) /*  250 */, U64_C(0x89b67ed96361f5ab) /*  251 */,
-  U64_C(0xffed95d8f1ea02a2) /*  252 */, U64_C(0xe72b3bd61464d43d) /*  253 */,
-  U64_C(0xa6300f170bdc4820) /*  254 */, U64_C(0xebc18760ed78a77a) /*  255 */
-};
-static u64 sbox2[256] = {
-  U64_C(0xe6a6be5a05a12138) /*  256 */, U64_C(0xb5a122a5b4f87c98) /*  257 */,
-  U64_C(0x563c6089140b6990) /*  258 */, U64_C(0x4c46cb2e391f5dd5) /*  259 */,
-  U64_C(0xd932addbc9b79434) /*  260 */, U64_C(0x08ea70e42015aff5) /*  261 */,
-  U64_C(0xd765a6673e478cf1) /*  262 */, U64_C(0xc4fb757eab278d99) /*  263 */,
-  U64_C(0xdf11c6862d6e0692) /*  264 */, U64_C(0xddeb84f10d7f3b16) /*  265 */,
-  U64_C(0x6f2ef604a665ea04) /*  266 */, U64_C(0x4a8e0f0ff0e0dfb3) /*  267 */,
-  U64_C(0xa5edeef83dbcba51) /*  268 */, U64_C(0xfc4f0a2a0ea4371e) /*  269 */,
-  U64_C(0xe83e1da85cb38429) /*  270 */, U64_C(0xdc8ff882ba1b1ce2) /*  271 */,
-  U64_C(0xcd45505e8353e80d) /*  272 */, U64_C(0x18d19a00d4db0717) /*  273 */,
-  U64_C(0x34a0cfeda5f38101) /*  274 */, U64_C(0x0be77e518887caf2) /*  275 */,
-  U64_C(0x1e341438b3c45136) /*  276 */, U64_C(0xe05797f49089ccf9) /*  277 */,
-  U64_C(0xffd23f9df2591d14) /*  278 */, U64_C(0x543dda228595c5cd) /*  279 */,
-  U64_C(0x661f81fd99052a33) /*  280 */, U64_C(0x8736e641db0f7b76) /*  281 */,
-  U64_C(0x15227725418e5307) /*  282 */, U64_C(0xe25f7f46162eb2fa) /*  283 */,
-  U64_C(0x48a8b2126c13d9fe) /*  284 */, U64_C(0xafdc541792e76eea) /*  285 */,
-  U64_C(0x03d912bfc6d1898f) /*  286 */, U64_C(0x31b1aafa1b83f51b) /*  287 */,
-  U64_C(0xf1ac2796e42ab7d9) /*  288 */, U64_C(0x40a3a7d7fcd2ebac) /*  289 */,
-  U64_C(0x1056136d0afbbcc5) /*  290 */, U64_C(0x7889e1dd9a6d0c85) /*  291 */,
-  U64_C(0xd33525782a7974aa) /*  292 */, U64_C(0xa7e25d09078ac09b) /*  293 */,
-  U64_C(0xbd4138b3eac6edd0) /*  294 */, U64_C(0x920abfbe71eb9e70) /*  295 */,
-  U64_C(0xa2a5d0f54fc2625c) /*  296 */, U64_C(0xc054e36b0b1290a3) /*  297 */,
-  U64_C(0xf6dd59ff62fe932b) /*  298 */, U64_C(0x3537354511a8ac7d) /*  299 */,
-  U64_C(0xca845e9172fadcd4) /*  300 */, U64_C(0x84f82b60329d20dc) /*  301 */,
-  U64_C(0x79c62ce1cd672f18) /*  302 */, U64_C(0x8b09a2add124642c) /*  303 */,
-  U64_C(0xd0c1e96a19d9e726) /*  304 */, U64_C(0x5a786a9b4ba9500c) /*  305 */,
-  U64_C(0x0e020336634c43f3) /*  306 */, U64_C(0xc17b474aeb66d822) /*  307 */,
-  U64_C(0x6a731ae3ec9baac2) /*  308 */, U64_C(0x8226667ae0840258) /*  309 */,
-  U64_C(0x67d4567691caeca5) /*  310 */, U64_C(0x1d94155c4875adb5) /*  311 */,
-  U64_C(0x6d00fd985b813fdf) /*  312 */, U64_C(0x51286efcb774cd06) /*  313 */,
-  U64_C(0x5e8834471fa744af) /*  314 */, U64_C(0xf72ca0aee761ae2e) /*  315 */,
-  U64_C(0xbe40e4cdaee8e09a) /*  316 */, U64_C(0xe9970bbb5118f665) /*  317 */,
-  U64_C(0x726e4beb33df1964) /*  318 */, U64_C(0x703b000729199762) /*  319 */,
-  U64_C(0x4631d816f5ef30a7) /*  320 */, U64_C(0xb880b5b51504a6be) /*  321 */,
-  U64_C(0x641793c37ed84b6c) /*  322 */, U64_C(0x7b21ed77f6e97d96) /*  323 */,
-  U64_C(0x776306312ef96b73) /*  324 */, U64_C(0xae528948e86ff3f4) /*  325 */,
-  U64_C(0x53dbd7f286a3f8f8) /*  326 */, U64_C(0x16cadce74cfc1063) /*  327 */,
-  U64_C(0x005c19bdfa52c6dd) /*  328 */, U64_C(0x68868f5d64d46ad3) /*  329 */,
-  U64_C(0x3a9d512ccf1e186a) /*  330 */, U64_C(0x367e62c2385660ae) /*  331 */,
-  U64_C(0xe359e7ea77dcb1d7) /*  332 */, U64_C(0x526c0773749abe6e) /*  333 */,
-  U64_C(0x735ae5f9d09f734b) /*  334 */, U64_C(0x493fc7cc8a558ba8) /*  335 */,
-  U64_C(0xb0b9c1533041ab45) /*  336 */, U64_C(0x321958ba470a59bd) /*  337 */,
-  U64_C(0x852db00b5f46c393) /*  338 */, U64_C(0x91209b2bd336b0e5) /*  339 */,
-  U64_C(0x6e604f7d659ef19f) /*  340 */, U64_C(0xb99a8ae2782ccb24) /*  341 */,
-  U64_C(0xccf52ab6c814c4c7) /*  342 */, U64_C(0x4727d9afbe11727b) /*  343 */,
-  U64_C(0x7e950d0c0121b34d) /*  344 */, U64_C(0x756f435670ad471f) /*  345 */,
-  U64_C(0xf5add442615a6849) /*  346 */, U64_C(0x4e87e09980b9957a) /*  347 */,
-  U64_C(0x2acfa1df50aee355) /*  348 */, U64_C(0xd898263afd2fd556) /*  349 */,
-  U64_C(0xc8f4924dd80c8fd6) /*  350 */, U64_C(0xcf99ca3d754a173a) /*  351 */,
-  U64_C(0xfe477bacaf91bf3c) /*  352 */, U64_C(0xed5371f6d690c12d) /*  353 */,
-  U64_C(0x831a5c285e687094) /*  354 */, U64_C(0xc5d3c90a3708a0a4) /*  355 */,
-  U64_C(0x0f7f903717d06580) /*  356 */, U64_C(0x19f9bb13b8fdf27f) /*  357 */,
-  U64_C(0xb1bd6f1b4d502843) /*  358 */, U64_C(0x1c761ba38fff4012) /*  359 */,
-  U64_C(0x0d1530c4e2e21f3b) /*  360 */, U64_C(0x8943ce69a7372c8a) /*  361 */,
-  U64_C(0xe5184e11feb5ce66) /*  362 */, U64_C(0x618bdb80bd736621) /*  363 */,
-  U64_C(0x7d29bad68b574d0b) /*  364 */, U64_C(0x81bb613e25e6fe5b) /*  365 */,
-  U64_C(0x071c9c10bc07913f) /*  366 */, U64_C(0xc7beeb7909ac2d97) /*  367 */,
-  U64_C(0xc3e58d353bc5d757) /*  368 */, U64_C(0xeb017892f38f61e8) /*  369 */,
-  U64_C(0xd4effb9c9b1cc21a) /*  370 */, U64_C(0x99727d26f494f7ab) /*  371 */,
-  U64_C(0xa3e063a2956b3e03) /*  372 */, U64_C(0x9d4a8b9a4aa09c30) /*  373 */,
-  U64_C(0x3f6ab7d500090fb4) /*  374 */, U64_C(0x9cc0f2a057268ac0) /*  375 */,
-  U64_C(0x3dee9d2dedbf42d1) /*  376 */, U64_C(0x330f49c87960a972) /*  377 */,
-  U64_C(0xc6b2720287421b41) /*  378 */, U64_C(0x0ac59ec07c00369c) /*  379 */,
-  U64_C(0xef4eac49cb353425) /*  380 */, U64_C(0xf450244eef0129d8) /*  381 */,
-  U64_C(0x8acc46e5caf4deb6) /*  382 */, U64_C(0x2ffeab63989263f7) /*  383 */,
-  U64_C(0x8f7cb9fe5d7a4578) /*  384 */, U64_C(0x5bd8f7644e634635) /*  385 */,
-  U64_C(0x427a7315bf2dc900) /*  386 */, U64_C(0x17d0c4aa2125261c) /*  387 */,
-  U64_C(0x3992486c93518e50) /*  388 */, U64_C(0xb4cbfee0a2d7d4c3) /*  389 */,
-  U64_C(0x7c75d6202c5ddd8d) /*  390 */, U64_C(0xdbc295d8e35b6c61) /*  391 */,
-  U64_C(0x60b369d302032b19) /*  392 */, U64_C(0xce42685fdce44132) /*  393 */,
-  U64_C(0x06f3ddb9ddf65610) /*  394 */, U64_C(0x8ea4d21db5e148f0) /*  395 */,
-  U64_C(0x20b0fce62fcd496f) /*  396 */, U64_C(0x2c1b912358b0ee31) /*  397 */,
-  U64_C(0xb28317b818f5a308) /*  398 */, U64_C(0xa89c1e189ca6d2cf) /*  399 */,
-  U64_C(0x0c6b18576aaadbc8) /*  400 */, U64_C(0xb65deaa91299fae3) /*  401 */,
-  U64_C(0xfb2b794b7f1027e7) /*  402 */, U64_C(0x04e4317f443b5beb) /*  403 */,
-  U64_C(0x4b852d325939d0a6) /*  404 */, U64_C(0xd5ae6beefb207ffc) /*  405 */,
-  U64_C(0x309682b281c7d374) /*  406 */, U64_C(0xbae309a194c3b475) /*  407 */,
-  U64_C(0x8cc3f97b13b49f05) /*  408 */, U64_C(0x98a9422ff8293967) /*  409 */,
-  U64_C(0x244b16b01076ff7c) /*  410 */, U64_C(0xf8bf571c663d67ee) /*  411 */,
-  U64_C(0x1f0d6758eee30da1) /*  412 */, U64_C(0xc9b611d97adeb9b7) /*  413 */,
-  U64_C(0xb7afd5887b6c57a2) /*  414 */, U64_C(0x6290ae846b984fe1) /*  415 */,
-  U64_C(0x94df4cdeacc1a5fd) /*  416 */, U64_C(0x058a5bd1c5483aff) /*  417 */,
-  U64_C(0x63166cc142ba3c37) /*  418 */, U64_C(0x8db8526eb2f76f40) /*  419 */,
-  U64_C(0xe10880036f0d6d4e) /*  420 */, U64_C(0x9e0523c9971d311d) /*  421 */,
-  U64_C(0x45ec2824cc7cd691) /*  422 */, U64_C(0x575b8359e62382c9) /*  423 */,
-  U64_C(0xfa9e400dc4889995) /*  424 */, U64_C(0xd1823ecb45721568) /*  425 */,
-  U64_C(0xdafd983b8206082f) /*  426 */, U64_C(0xaa7d29082386a8cb) /*  427 */,
-  U64_C(0x269fcd4403b87588) /*  428 */, U64_C(0x1b91f5f728bdd1e0) /*  429 */,
-  U64_C(0xe4669f39040201f6) /*  430 */, U64_C(0x7a1d7c218cf04ade) /*  431 */,
-  U64_C(0x65623c29d79ce5ce) /*  432 */, U64_C(0x2368449096c00bb1) /*  433 */,
-  U64_C(0xab9bf1879da503ba) /*  434 */, U64_C(0xbc23ecb1a458058e) /*  435 */,
-  U64_C(0x9a58df01bb401ecc) /*  436 */, U64_C(0xa070e868a85f143d) /*  437 */,
-  U64_C(0x4ff188307df2239e) /*  438 */, U64_C(0x14d565b41a641183) /*  439 */,
-  U64_C(0xee13337452701602) /*  440 */, U64_C(0x950e3dcf3f285e09) /*  441 */,
-  U64_C(0x59930254b9c80953) /*  442 */, U64_C(0x3bf299408930da6d) /*  443 */,
-  U64_C(0xa955943f53691387) /*  444 */, U64_C(0xa15edecaa9cb8784) /*  445 */,
-  U64_C(0x29142127352be9a0) /*  446 */, U64_C(0x76f0371fff4e7afb) /*  447 */,
-  U64_C(0x0239f450274f2228) /*  448 */, U64_C(0xbb073af01d5e868b) /*  449 */,
-  U64_C(0xbfc80571c10e96c1) /*  450 */, U64_C(0xd267088568222e23) /*  451 */,
-  U64_C(0x9671a3d48e80b5b0) /*  452 */, U64_C(0x55b5d38ae193bb81) /*  453 */,
-  U64_C(0x693ae2d0a18b04b8) /*  454 */, U64_C(0x5c48b4ecadd5335f) /*  455 */,
-  U64_C(0xfd743b194916a1ca) /*  456 */, U64_C(0x2577018134be98c4) /*  457 */,
-  U64_C(0xe77987e83c54a4ad) /*  458 */, U64_C(0x28e11014da33e1b9) /*  459 */,
-  U64_C(0x270cc59e226aa213) /*  460 */, U64_C(0x71495f756d1a5f60) /*  461 */,
-  U64_C(0x9be853fb60afef77) /*  462 */, U64_C(0xadc786a7f7443dbf) /*  463 */,
-  U64_C(0x0904456173b29a82) /*  464 */, U64_C(0x58bc7a66c232bd5e) /*  465 */,
-  U64_C(0xf306558c673ac8b2) /*  466 */, U64_C(0x41f639c6b6c9772a) /*  467 */,
-  U64_C(0x216defe99fda35da) /*  468 */, U64_C(0x11640cc71c7be615) /*  469 */,
-  U64_C(0x93c43694565c5527) /*  470 */, U64_C(0xea038e6246777839) /*  471 */,
-  U64_C(0xf9abf3ce5a3e2469) /*  472 */, U64_C(0x741e768d0fd312d2) /*  473 */,
-  U64_C(0x0144b883ced652c6) /*  474 */, U64_C(0xc20b5a5ba33f8552) /*  475 */,
-  U64_C(0x1ae69633c3435a9d) /*  476 */, U64_C(0x97a28ca4088cfdec) /*  477 */,
-  U64_C(0x8824a43c1e96f420) /*  478 */, U64_C(0x37612fa66eeea746) /*  479 */,
-  U64_C(0x6b4cb165f9cf0e5a) /*  480 */, U64_C(0x43aa1c06a0abfb4a) /*  481 */,
-  U64_C(0x7f4dc26ff162796b) /*  482 */, U64_C(0x6cbacc8e54ed9b0f) /*  483 */,
-  U64_C(0xa6b7ffefd2bb253e) /*  484 */, U64_C(0x2e25bc95b0a29d4f) /*  485 */,
-  U64_C(0x86d6a58bdef1388c) /*  486 */, U64_C(0xded74ac576b6f054) /*  487 */,
-  U64_C(0x8030bdbc2b45805d) /*  488 */, U64_C(0x3c81af70e94d9289) /*  489 */,
-  U64_C(0x3eff6dda9e3100db) /*  490 */, U64_C(0xb38dc39fdfcc8847) /*  491 */,
-  U64_C(0x123885528d17b87e) /*  492 */, U64_C(0xf2da0ed240b1b642) /*  493 */,
-  U64_C(0x44cefadcd54bf9a9) /*  494 */, U64_C(0x1312200e433c7ee6) /*  495 */,
-  U64_C(0x9ffcc84f3a78c748) /*  496 */, U64_C(0xf0cd1f72248576bb) /*  497 */,
-  U64_C(0xec6974053638cfe4) /*  498 */, U64_C(0x2ba7b67c0cec4e4c) /*  499 */,
-  U64_C(0xac2f4df3e5ce32ed) /*  500 */, U64_C(0xcb33d14326ea4c11) /*  501 */,
-  U64_C(0xa4e9044cc77e58bc) /*  502 */, U64_C(0x5f513293d934fcef) /*  503 */,
-  U64_C(0x5dc9645506e55444) /*  504 */, U64_C(0x50de418f317de40a) /*  505 */,
-  U64_C(0x388cb31a69dde259) /*  506 */, U64_C(0x2db4a83455820a86) /*  507 */,
-  U64_C(0x9010a91e84711ae9) /*  508 */, U64_C(0x4df7f0b7b1498371) /*  509 */,
-  U64_C(0xd62a2eabc0977179) /*  510 */, U64_C(0x22fac097aa8d5c0e) /*  511 */
-};
-static u64 sbox3[256] = {
-  U64_C(0xf49fcc2ff1daf39b) /*  512 */, U64_C(0x487fd5c66ff29281) /*  513 */,
-  U64_C(0xe8a30667fcdca83f) /*  514 */, U64_C(0x2c9b4be3d2fcce63) /*  515 */,
-  U64_C(0xda3ff74b93fbbbc2) /*  516 */, U64_C(0x2fa165d2fe70ba66) /*  517 */,
-  U64_C(0xa103e279970e93d4) /*  518 */, U64_C(0xbecdec77b0e45e71) /*  519 */,
-  U64_C(0xcfb41e723985e497) /*  520 */, U64_C(0xb70aaa025ef75017) /*  521 */,
-  U64_C(0xd42309f03840b8e0) /*  522 */, U64_C(0x8efc1ad035898579) /*  523 */,
-  U64_C(0x96c6920be2b2abc5) /*  524 */, U64_C(0x66af4163375a9172) /*  525 */,
-  U64_C(0x2174abdcca7127fb) /*  526 */, U64_C(0xb33ccea64a72ff41) /*  527 */,
-  U64_C(0xf04a4933083066a5) /*  528 */, U64_C(0x8d970acdd7289af5) /*  529 */,
-  U64_C(0x8f96e8e031c8c25e) /*  530 */, U64_C(0xf3fec02276875d47) /*  531 */,
-  U64_C(0xec7bf310056190dd) /*  532 */, U64_C(0xf5adb0aebb0f1491) /*  533 */,
-  U64_C(0x9b50f8850fd58892) /*  534 */, U64_C(0x4975488358b74de8) /*  535 */,
-  U64_C(0xa3354ff691531c61) /*  536 */, U64_C(0x0702bbe481d2c6ee) /*  537 */,
-  U64_C(0x89fb24057deded98) /*  538 */, U64_C(0xac3075138596e902) /*  539 */,
-  U64_C(0x1d2d3580172772ed) /*  540 */, U64_C(0xeb738fc28e6bc30d) /*  541 */,
-  U64_C(0x5854ef8f63044326) /*  542 */, U64_C(0x9e5c52325add3bbe) /*  543 */,
-  U64_C(0x90aa53cf325c4623) /*  544 */, U64_C(0xc1d24d51349dd067) /*  545 */,
-  U64_C(0x2051cfeea69ea624) /*  546 */, U64_C(0x13220f0a862e7e4f) /*  547 */,
-  U64_C(0xce39399404e04864) /*  548 */, U64_C(0xd9c42ca47086fcb7) /*  549 */,
-  U64_C(0x685ad2238a03e7cc) /*  550 */, U64_C(0x066484b2ab2ff1db) /*  551 */,
-  U64_C(0xfe9d5d70efbf79ec) /*  552 */, U64_C(0x5b13b9dd9c481854) /*  553 */,
-  U64_C(0x15f0d475ed1509ad) /*  554 */, U64_C(0x0bebcd060ec79851) /*  555 */,
-  U64_C(0xd58c6791183ab7f8) /*  556 */, U64_C(0xd1187c5052f3eee4) /*  557 */,
-  U64_C(0xc95d1192e54e82ff) /*  558 */, U64_C(0x86eea14cb9ac6ca2) /*  559 */,
-  U64_C(0x3485beb153677d5d) /*  560 */, U64_C(0xdd191d781f8c492a) /*  561 */,
-  U64_C(0xf60866baa784ebf9) /*  562 */, U64_C(0x518f643ba2d08c74) /*  563 */,
-  U64_C(0x8852e956e1087c22) /*  564 */, U64_C(0xa768cb8dc410ae8d) /*  565 */,
-  U64_C(0x38047726bfec8e1a) /*  566 */, U64_C(0xa67738b4cd3b45aa) /*  567 */,
-  U64_C(0xad16691cec0dde19) /*  568 */, U64_C(0xc6d4319380462e07) /*  569 */,
-  U64_C(0xc5a5876d0ba61938) /*  570 */, U64_C(0x16b9fa1fa58fd840) /*  571 */,
-  U64_C(0x188ab1173ca74f18) /*  572 */, U64_C(0xabda2f98c99c021f) /*  573 */,
-  U64_C(0x3e0580ab134ae816) /*  574 */, U64_C(0x5f3b05b773645abb) /*  575 */,
-  U64_C(0x2501a2be5575f2f6) /*  576 */, U64_C(0x1b2f74004e7e8ba9) /*  577 */,
-  U64_C(0x1cd7580371e8d953) /*  578 */, U64_C(0x7f6ed89562764e30) /*  579 */,
-  U64_C(0xb15926ff596f003d) /*  580 */, U64_C(0x9f65293da8c5d6b9) /*  581 */,
-  U64_C(0x6ecef04dd690f84c) /*  582 */, U64_C(0x4782275fff33af88) /*  583 */,
-  U64_C(0xe41433083f820801) /*  584 */, U64_C(0xfd0dfe409a1af9b5) /*  585 */,
-  U64_C(0x4325a3342cdb396b) /*  586 */, U64_C(0x8ae77e62b301b252) /*  587 */,
-  U64_C(0xc36f9e9f6655615a) /*  588 */, U64_C(0x85455a2d92d32c09) /*  589 */,
-  U64_C(0xf2c7dea949477485) /*  590 */, U64_C(0x63cfb4c133a39eba) /*  591 */,
-  U64_C(0x83b040cc6ebc5462) /*  592 */, U64_C(0x3b9454c8fdb326b0) /*  593 */,
-  U64_C(0x56f56a9e87ffd78c) /*  594 */, U64_C(0x2dc2940d99f42bc6) /*  595 */,
-  U64_C(0x98f7df096b096e2d) /*  596 */, U64_C(0x19a6e01e3ad852bf) /*  597 */,
-  U64_C(0x42a99ccbdbd4b40b) /*  598 */, U64_C(0xa59998af45e9c559) /*  599 */,
-  U64_C(0x366295e807d93186) /*  600 */, U64_C(0x6b48181bfaa1f773) /*  601 */,
-  U64_C(0x1fec57e2157a0a1d) /*  602 */, U64_C(0x4667446af6201ad5) /*  603 */,
-  U64_C(0xe615ebcacfb0f075) /*  604 */, U64_C(0xb8f31f4f68290778) /*  605 */,
-  U64_C(0x22713ed6ce22d11e) /*  606 */, U64_C(0x3057c1a72ec3c93b) /*  607 */,
-  U64_C(0xcb46acc37c3f1f2f) /*  608 */, U64_C(0xdbb893fd02aaf50e) /*  609 */,
-  U64_C(0x331fd92e600b9fcf) /*  610 */, U64_C(0xa498f96148ea3ad6) /*  611 */,
-  U64_C(0xa8d8426e8b6a83ea) /*  612 */, U64_C(0xa089b274b7735cdc) /*  613 */,
-  U64_C(0x87f6b3731e524a11) /*  614 */, U64_C(0x118808e5cbc96749) /*  615 */,
-  U64_C(0x9906e4c7b19bd394) /*  616 */, U64_C(0xafed7f7e9b24a20c) /*  617 */,
-  U64_C(0x6509eadeeb3644a7) /*  618 */, U64_C(0x6c1ef1d3e8ef0ede) /*  619 */,
-  U64_C(0xb9c97d43e9798fb4) /*  620 */, U64_C(0xa2f2d784740c28a3) /*  621 */,
-  U64_C(0x7b8496476197566f) /*  622 */, U64_C(0x7a5be3e6b65f069d) /*  623 */,
-  U64_C(0xf96330ed78be6f10) /*  624 */, U64_C(0xeee60de77a076a15) /*  625 */,
-  U64_C(0x2b4bee4aa08b9bd0) /*  626 */, U64_C(0x6a56a63ec7b8894e) /*  627 */,
-  U64_C(0x02121359ba34fef4) /*  628 */, U64_C(0x4cbf99f8283703fc) /*  629 */,
-  U64_C(0x398071350caf30c8) /*  630 */, U64_C(0xd0a77a89f017687a) /*  631 */,
-  U64_C(0xf1c1a9eb9e423569) /*  632 */, U64_C(0x8c7976282dee8199) /*  633 */,
-  U64_C(0x5d1737a5dd1f7abd) /*  634 */, U64_C(0x4f53433c09a9fa80) /*  635 */,
-  U64_C(0xfa8b0c53df7ca1d9) /*  636 */, U64_C(0x3fd9dcbc886ccb77) /*  637 */,
-  U64_C(0xc040917ca91b4720) /*  638 */, U64_C(0x7dd00142f9d1dcdf) /*  639 */,
-  U64_C(0x8476fc1d4f387b58) /*  640 */, U64_C(0x23f8e7c5f3316503) /*  641 */,
-  U64_C(0x032a2244e7e37339) /*  642 */, U64_C(0x5c87a5d750f5a74b) /*  643 */,
-  U64_C(0x082b4cc43698992e) /*  644 */, U64_C(0xdf917becb858f63c) /*  645 */,
-  U64_C(0x3270b8fc5bf86dda) /*  646 */, U64_C(0x10ae72bb29b5dd76) /*  647 */,
-  U64_C(0x576ac94e7700362b) /*  648 */, U64_C(0x1ad112dac61efb8f) /*  649 */,
-  U64_C(0x691bc30ec5faa427) /*  650 */, U64_C(0xff246311cc327143) /*  651 */,
-  U64_C(0x3142368e30e53206) /*  652 */, U64_C(0x71380e31e02ca396) /*  653 */,
-  U64_C(0x958d5c960aad76f1) /*  654 */, U64_C(0xf8d6f430c16da536) /*  655 */,
-  U64_C(0xc8ffd13f1be7e1d2) /*  656 */, U64_C(0x7578ae66004ddbe1) /*  657 */,
-  U64_C(0x05833f01067be646) /*  658 */, U64_C(0xbb34b5ad3bfe586d) /*  659 */,
-  U64_C(0x095f34c9a12b97f0) /*  660 */, U64_C(0x247ab64525d60ca8) /*  661 */,
-  U64_C(0xdcdbc6f3017477d1) /*  662 */, U64_C(0x4a2e14d4decad24d) /*  663 */,
-  U64_C(0xbdb5e6d9be0a1eeb) /*  664 */, U64_C(0x2a7e70f7794301ab) /*  665 */,
-  U64_C(0xdef42d8a270540fd) /*  666 */, U64_C(0x01078ec0a34c22c1) /*  667 */,
-  U64_C(0xe5de511af4c16387) /*  668 */, U64_C(0x7ebb3a52bd9a330a) /*  669 */,
-  U64_C(0x77697857aa7d6435) /*  670 */, U64_C(0x004e831603ae4c32) /*  671 */,
-  U64_C(0xe7a21020ad78e312) /*  672 */, U64_C(0x9d41a70c6ab420f2) /*  673 */,
-  U64_C(0x28e06c18ea1141e6) /*  674 */, U64_C(0xd2b28cbd984f6b28) /*  675 */,
-  U64_C(0x26b75f6c446e9d83) /*  676 */, U64_C(0xba47568c4d418d7f) /*  677 */,
-  U64_C(0xd80badbfe6183d8e) /*  678 */, U64_C(0x0e206d7f5f166044) /*  679 */,
-  U64_C(0xe258a43911cbca3e) /*  680 */, U64_C(0x723a1746b21dc0bc) /*  681 */,
-  U64_C(0xc7caa854f5d7cdd3) /*  682 */, U64_C(0x7cac32883d261d9c) /*  683 */,
-  U64_C(0x7690c26423ba942c) /*  684 */, U64_C(0x17e55524478042b8) /*  685 */,
-  U64_C(0xe0be477656a2389f) /*  686 */, U64_C(0x4d289b5e67ab2da0) /*  687 */,
-  U64_C(0x44862b9c8fbbfd31) /*  688 */, U64_C(0xb47cc8049d141365) /*  689 */,
-  U64_C(0x822c1b362b91c793) /*  690 */, U64_C(0x4eb14655fb13dfd8) /*  691 */,
-  U64_C(0x1ecbba0714e2a97b) /*  692 */, U64_C(0x6143459d5cde5f14) /*  693 */,
-  U64_C(0x53a8fbf1d5f0ac89) /*  694 */, U64_C(0x97ea04d81c5e5b00) /*  695 */,
-  U64_C(0x622181a8d4fdb3f3) /*  696 */, U64_C(0xe9bcd341572a1208) /*  697 */,
-  U64_C(0x1411258643cce58a) /*  698 */, U64_C(0x9144c5fea4c6e0a4) /*  699 */,
-  U64_C(0x0d33d06565cf620f) /*  700 */, U64_C(0x54a48d489f219ca1) /*  701 */,
-  U64_C(0xc43e5eac6d63c821) /*  702 */, U64_C(0xa9728b3a72770daf) /*  703 */,
-  U64_C(0xd7934e7b20df87ef) /*  704 */, U64_C(0xe35503b61a3e86e5) /*  705 */,
-  U64_C(0xcae321fbc819d504) /*  706 */, U64_C(0x129a50b3ac60bfa6) /*  707 */,
-  U64_C(0xcd5e68ea7e9fb6c3) /*  708 */, U64_C(0xb01c90199483b1c7) /*  709 */,
-  U64_C(0x3de93cd5c295376c) /*  710 */, U64_C(0xaed52edf2ab9ad13) /*  711 */,
-  U64_C(0x2e60f512c0a07884) /*  712 */, U64_C(0xbc3d86a3e36210c9) /*  713 */,
-  U64_C(0x35269d9b163951ce) /*  714 */, U64_C(0x0c7d6e2ad0cdb5fa) /*  715 */,
-  U64_C(0x59e86297d87f5733) /*  716 */, U64_C(0x298ef221898db0e7) /*  717 */,
-  U64_C(0x55000029d1a5aa7e) /*  718 */, U64_C(0x8bc08ae1b5061b45) /*  719 */,
-  U64_C(0xc2c31c2b6c92703a) /*  720 */, U64_C(0x94cc596baf25ef42) /*  721 */,
-  U64_C(0x0a1d73db22540456) /*  722 */, U64_C(0x04b6a0f9d9c4179a) /*  723 */,
-  U64_C(0xeffdafa2ae3d3c60) /*  724 */, U64_C(0xf7c8075bb49496c4) /*  725 */,
-  U64_C(0x9cc5c7141d1cd4e3) /*  726 */, U64_C(0x78bd1638218e5534) /*  727 */,
-  U64_C(0xb2f11568f850246a) /*  728 */, U64_C(0xedfabcfa9502bc29) /*  729 */,
-  U64_C(0x796ce5f2da23051b) /*  730 */, U64_C(0xaae128b0dc93537c) /*  731 */,
-  U64_C(0x3a493da0ee4b29ae) /*  732 */, U64_C(0xb5df6b2c416895d7) /*  733 */,
-  U64_C(0xfcabbd25122d7f37) /*  734 */, U64_C(0x70810b58105dc4b1) /*  735 */,
-  U64_C(0xe10fdd37f7882a90) /*  736 */, U64_C(0x524dcab5518a3f5c) /*  737 */,
-  U64_C(0x3c9e85878451255b) /*  738 */, U64_C(0x4029828119bd34e2) /*  739 */,
-  U64_C(0x74a05b6f5d3ceccb) /*  740 */, U64_C(0xb610021542e13eca) /*  741 */,
-  U64_C(0x0ff979d12f59e2ac) /*  742 */, U64_C(0x6037da27e4f9cc50) /*  743 */,
-  U64_C(0x5e92975a0df1847d) /*  744 */, U64_C(0xd66de190d3e623fe) /*  745 */,
-  U64_C(0x5032d6b87b568048) /*  746 */, U64_C(0x9a36b7ce8235216e) /*  747 */,
-  U64_C(0x80272a7a24f64b4a) /*  748 */, U64_C(0x93efed8b8c6916f7) /*  749 */,
-  U64_C(0x37ddbff44cce1555) /*  750 */, U64_C(0x4b95db5d4b99bd25) /*  751 */,
-  U64_C(0x92d3fda169812fc0) /*  752 */, U64_C(0xfb1a4a9a90660bb6) /*  753 */,
-  U64_C(0x730c196946a4b9b2) /*  754 */, U64_C(0x81e289aa7f49da68) /*  755 */,
-  U64_C(0x64669a0f83b1a05f) /*  756 */, U64_C(0x27b3ff7d9644f48b) /*  757 */,
-  U64_C(0xcc6b615c8db675b3) /*  758 */, U64_C(0x674f20b9bcebbe95) /*  759 */,
-  U64_C(0x6f31238275655982) /*  760 */, U64_C(0x5ae488713e45cf05) /*  761 */,
-  U64_C(0xbf619f9954c21157) /*  762 */, U64_C(0xeabac46040a8eae9) /*  763 */,
-  U64_C(0x454c6fe9f2c0c1cd) /*  764 */, U64_C(0x419cf6496412691c) /*  765 */,
-  U64_C(0xd3dc3bef265b0f70) /*  766 */, U64_C(0x6d0e60f5c3578a9e) /*  767 */
-};
-static u64 sbox4[256] = {
-  U64_C(0x5b0e608526323c55) /*  768 */, U64_C(0x1a46c1a9fa1b59f5) /*  769 */,
-  U64_C(0xa9e245a17c4c8ffa) /*  770 */, U64_C(0x65ca5159db2955d7) /*  771 */,
-  U64_C(0x05db0a76ce35afc2) /*  772 */, U64_C(0x81eac77ea9113d45) /*  773 */,
-  U64_C(0x528ef88ab6ac0a0d) /*  774 */, U64_C(0xa09ea253597be3ff) /*  775 */,
-  U64_C(0x430ddfb3ac48cd56) /*  776 */, U64_C(0xc4b3a67af45ce46f) /*  777 */,
-  U64_C(0x4ececfd8fbe2d05e) /*  778 */, U64_C(0x3ef56f10b39935f0) /*  779 */,
-  U64_C(0x0b22d6829cd619c6) /*  780 */, U64_C(0x17fd460a74df2069) /*  781 */,
-  U64_C(0x6cf8cc8e8510ed40) /*  782 */, U64_C(0xd6c824bf3a6ecaa7) /*  783 */,
-  U64_C(0x61243d581a817049) /*  784 */, U64_C(0x048bacb6bbc163a2) /*  785 */,
-  U64_C(0xd9a38ac27d44cc32) /*  786 */, U64_C(0x7fddff5baaf410ab) /*  787 */,
-  U64_C(0xad6d495aa804824b) /*  788 */, U64_C(0xe1a6a74f2d8c9f94) /*  789 */,
-  U64_C(0xd4f7851235dee8e3) /*  790 */, U64_C(0xfd4b7f886540d893) /*  791 */,
-  U64_C(0x247c20042aa4bfda) /*  792 */, U64_C(0x096ea1c517d1327c) /*  793 */,
-  U64_C(0xd56966b4361a6685) /*  794 */, U64_C(0x277da5c31221057d) /*  795 */,
-  U64_C(0x94d59893a43acff7) /*  796 */, U64_C(0x64f0c51ccdc02281) /*  797 */,
-  U64_C(0x3d33bcc4ff6189db) /*  798 */, U64_C(0xe005cb184ce66af1) /*  799 */,
-  U64_C(0xff5ccd1d1db99bea) /*  800 */, U64_C(0xb0b854a7fe42980f) /*  801 */,
-  U64_C(0x7bd46a6a718d4b9f) /*  802 */, U64_C(0xd10fa8cc22a5fd8c) /*  803 */,
-  U64_C(0xd31484952be4bd31) /*  804 */, U64_C(0xc7fa975fcb243847) /*  805 */,
-  U64_C(0x4886ed1e5846c407) /*  806 */, U64_C(0x28cddb791eb70b04) /*  807 */,
-  U64_C(0xc2b00be2f573417f) /*  808 */, U64_C(0x5c9590452180f877) /*  809 */,
-  U64_C(0x7a6bddfff370eb00) /*  810 */, U64_C(0xce509e38d6d9d6a4) /*  811 */,
-  U64_C(0xebeb0f00647fa702) /*  812 */, U64_C(0x1dcc06cf76606f06) /*  813 */,
-  U64_C(0xe4d9f28ba286ff0a) /*  814 */, U64_C(0xd85a305dc918c262) /*  815 */,
-  U64_C(0x475b1d8732225f54) /*  816 */, U64_C(0x2d4fb51668ccb5fe) /*  817 */,
-  U64_C(0xa679b9d9d72bba20) /*  818 */, U64_C(0x53841c0d912d43a5) /*  819 */,
-  U64_C(0x3b7eaa48bf12a4e8) /*  820 */, U64_C(0x781e0e47f22f1ddf) /*  821 */,
-  U64_C(0xeff20ce60ab50973) /*  822 */, U64_C(0x20d261d19dffb742) /*  823 */,
-  U64_C(0x16a12b03062a2e39) /*  824 */, U64_C(0x1960eb2239650495) /*  825 */,
-  U64_C(0x251c16fed50eb8b8) /*  826 */, U64_C(0x9ac0c330f826016e) /*  827 */,
-  U64_C(0xed152665953e7671) /*  828 */, U64_C(0x02d63194a6369570) /*  829 */,
-  U64_C(0x5074f08394b1c987) /*  830 */, U64_C(0x70ba598c90b25ce1) /*  831 */,
-  U64_C(0x794a15810b9742f6) /*  832 */, U64_C(0x0d5925e9fcaf8c6c) /*  833 */,
-  U64_C(0x3067716cd868744e) /*  834 */, U64_C(0x910ab077e8d7731b) /*  835 */,
-  U64_C(0x6a61bbdb5ac42f61) /*  836 */, U64_C(0x93513efbf0851567) /*  837 */,
-  U64_C(0xf494724b9e83e9d5) /*  838 */, U64_C(0xe887e1985c09648d) /*  839 */,
-  U64_C(0x34b1d3c675370cfd) /*  840 */, U64_C(0xdc35e433bc0d255d) /*  841 */,
-  U64_C(0xd0aab84234131be0) /*  842 */, U64_C(0x08042a50b48b7eaf) /*  843 */,
-  U64_C(0x9997c4ee44a3ab35) /*  844 */, U64_C(0x829a7b49201799d0) /*  845 */,
-  U64_C(0x263b8307b7c54441) /*  846 */, U64_C(0x752f95f4fd6a6ca6) /*  847 */,
-  U64_C(0x927217402c08c6e5) /*  848 */, U64_C(0x2a8ab754a795d9ee) /*  849 */,
-  U64_C(0xa442f7552f72943d) /*  850 */, U64_C(0x2c31334e19781208) /*  851 */,
-  U64_C(0x4fa98d7ceaee6291) /*  852 */, U64_C(0x55c3862f665db309) /*  853 */,
-  U64_C(0xbd0610175d53b1f3) /*  854 */, U64_C(0x46fe6cb840413f27) /*  855 */,
-  U64_C(0x3fe03792df0cfa59) /*  856 */, U64_C(0xcfe700372eb85e8f) /*  857 */,
-  U64_C(0xa7be29e7adbce118) /*  858 */, U64_C(0xe544ee5cde8431dd) /*  859 */,
-  U64_C(0x8a781b1b41f1873e) /*  860 */, U64_C(0xa5c94c78a0d2f0e7) /*  861 */,
-  U64_C(0x39412e2877b60728) /*  862 */, U64_C(0xa1265ef3afc9a62c) /*  863 */,
-  U64_C(0xbcc2770c6a2506c5) /*  864 */, U64_C(0x3ab66dd5dce1ce12) /*  865 */,
-  U64_C(0xe65499d04a675b37) /*  866 */, U64_C(0x7d8f523481bfd216) /*  867 */,
-  U64_C(0x0f6f64fcec15f389) /*  868 */, U64_C(0x74efbe618b5b13c8) /*  869 */,
-  U64_C(0xacdc82b714273e1d) /*  870 */, U64_C(0xdd40bfe003199d17) /*  871 */,
-  U64_C(0x37e99257e7e061f8) /*  872 */, U64_C(0xfa52626904775aaa) /*  873 */,
-  U64_C(0x8bbbf63a463d56f9) /*  874 */, U64_C(0xf0013f1543a26e64) /*  875 */,
-  U64_C(0xa8307e9f879ec898) /*  876 */, U64_C(0xcc4c27a4150177cc) /*  877 */,
-  U64_C(0x1b432f2cca1d3348) /*  878 */, U64_C(0xde1d1f8f9f6fa013) /*  879 */,
-  U64_C(0x606602a047a7ddd6) /*  880 */, U64_C(0xd237ab64cc1cb2c7) /*  881 */,
-  U64_C(0x9b938e7225fcd1d3) /*  882 */, U64_C(0xec4e03708e0ff476) /*  883 */,
-  U64_C(0xfeb2fbda3d03c12d) /*  884 */, U64_C(0xae0bced2ee43889a) /*  885 */,
-  U64_C(0x22cb8923ebfb4f43) /*  886 */, U64_C(0x69360d013cf7396d) /*  887 */,
-  U64_C(0x855e3602d2d4e022) /*  888 */, U64_C(0x073805bad01f784c) /*  889 */,
-  U64_C(0x33e17a133852f546) /*  890 */, U64_C(0xdf4874058ac7b638) /*  891 */,
-  U64_C(0xba92b29c678aa14a) /*  892 */, U64_C(0x0ce89fc76cfaadcd) /*  893 */,
-  U64_C(0x5f9d4e0908339e34) /*  894 */, U64_C(0xf1afe9291f5923b9) /*  895 */,
-  U64_C(0x6e3480f60f4a265f) /*  896 */, U64_C(0xeebf3a2ab29b841c) /*  897 */,
-  U64_C(0xe21938a88f91b4ad) /*  898 */, U64_C(0x57dfeff845c6d3c3) /*  899 */,
-  U64_C(0x2f006b0bf62caaf2) /*  900 */, U64_C(0x62f479ef6f75ee78) /*  901 */,
-  U64_C(0x11a55ad41c8916a9) /*  902 */, U64_C(0xf229d29084fed453) /*  903 */,
-  U64_C(0x42f1c27b16b000e6) /*  904 */, U64_C(0x2b1f76749823c074) /*  905 */,
-  U64_C(0x4b76eca3c2745360) /*  906 */, U64_C(0x8c98f463b91691bd) /*  907 */,
-  U64_C(0x14bcc93cf1ade66a) /*  908 */, U64_C(0x8885213e6d458397) /*  909 */,
-  U64_C(0x8e177df0274d4711) /*  910 */, U64_C(0xb49b73b5503f2951) /*  911 */,
-  U64_C(0x10168168c3f96b6b) /*  912 */, U64_C(0x0e3d963b63cab0ae) /*  913 */,
-  U64_C(0x8dfc4b5655a1db14) /*  914 */, U64_C(0xf789f1356e14de5c) /*  915 */,
-  U64_C(0x683e68af4e51dac1) /*  916 */, U64_C(0xc9a84f9d8d4b0fd9) /*  917 */,
-  U64_C(0x3691e03f52a0f9d1) /*  918 */, U64_C(0x5ed86e46e1878e80) /*  919 */,
-  U64_C(0x3c711a0e99d07150) /*  920 */, U64_C(0x5a0865b20c4e9310) /*  921 */,
-  U64_C(0x56fbfc1fe4f0682e) /*  922 */, U64_C(0xea8d5de3105edf9b) /*  923 */,
-  U64_C(0x71abfdb12379187a) /*  924 */, U64_C(0x2eb99de1bee77b9c) /*  925 */,
-  U64_C(0x21ecc0ea33cf4523) /*  926 */, U64_C(0x59a4d7521805c7a1) /*  927 */,
-  U64_C(0x3896f5eb56ae7c72) /*  928 */, U64_C(0xaa638f3db18f75dc) /*  929 */,
-  U64_C(0x9f39358dabe9808e) /*  930 */, U64_C(0xb7defa91c00b72ac) /*  931 */,
-  U64_C(0x6b5541fd62492d92) /*  932 */, U64_C(0x6dc6dee8f92e4d5b) /*  933 */,
-  U64_C(0x353f57abc4beea7e) /*  934 */, U64_C(0x735769d6da5690ce) /*  935 */,
-  U64_C(0x0a234aa642391484) /*  936 */, U64_C(0xf6f9508028f80d9d) /*  937 */,
-  U64_C(0xb8e319a27ab3f215) /*  938 */, U64_C(0x31ad9c1151341a4d) /*  939 */,
-  U64_C(0x773c22a57bef5805) /*  940 */, U64_C(0x45c7561a07968633) /*  941 */,
-  U64_C(0xf913da9e249dbe36) /*  942 */, U64_C(0xda652d9b78a64c68) /*  943 */,
-  U64_C(0x4c27a97f3bc334ef) /*  944 */, U64_C(0x76621220e66b17f4) /*  945 */,
-  U64_C(0x967743899acd7d0b) /*  946 */, U64_C(0xf3ee5bcae0ed6782) /*  947 */,
-  U64_C(0x409f753600c879fc) /*  948 */, U64_C(0x06d09a39b5926db6) /*  949 */,
-  U64_C(0x6f83aeb0317ac588) /*  950 */, U64_C(0x01e6ca4a86381f21) /*  951 */,
-  U64_C(0x66ff3462d19f3025) /*  952 */, U64_C(0x72207c24ddfd3bfb) /*  953 */,
-  U64_C(0x4af6b6d3e2ece2eb) /*  954 */, U64_C(0x9c994dbec7ea08de) /*  955 */,
-  U64_C(0x49ace597b09a8bc4) /*  956 */, U64_C(0xb38c4766cf0797ba) /*  957 */,
-  U64_C(0x131b9373c57c2a75) /*  958 */, U64_C(0xb1822cce61931e58) /*  959 */,
-  U64_C(0x9d7555b909ba1c0c) /*  960 */, U64_C(0x127fafdd937d11d2) /*  961 */,
-  U64_C(0x29da3badc66d92e4) /*  962 */, U64_C(0xa2c1d57154c2ecbc) /*  963 */,
-  U64_C(0x58c5134d82f6fe24) /*  964 */, U64_C(0x1c3ae3515b62274f) /*  965 */,
-  U64_C(0xe907c82e01cb8126) /*  966 */, U64_C(0xf8ed091913e37fcb) /*  967 */,
-  U64_C(0x3249d8f9c80046c9) /*  968 */, U64_C(0x80cf9bede388fb63) /*  969 */,
-  U64_C(0x1881539a116cf19e) /*  970 */, U64_C(0x5103f3f76bd52457) /*  971 */,
-  U64_C(0x15b7e6f5ae47f7a8) /*  972 */, U64_C(0xdbd7c6ded47e9ccf) /*  973 */,
-  U64_C(0x44e55c410228bb1a) /*  974 */, U64_C(0xb647d4255edb4e99) /*  975 */,
-  U64_C(0x5d11882bb8aafc30) /*  976 */, U64_C(0xf5098bbb29d3212a) /*  977 */,
-  U64_C(0x8fb5ea14e90296b3) /*  978 */, U64_C(0x677b942157dd025a) /*  979 */,
-  U64_C(0xfb58e7c0a390acb5) /*  980 */, U64_C(0x89d3674c83bd4a01) /*  981 */,
-  U64_C(0x9e2da4df4bf3b93b) /*  982 */, U64_C(0xfcc41e328cab4829) /*  983 */,
-  U64_C(0x03f38c96ba582c52) /*  984 */, U64_C(0xcad1bdbd7fd85db2) /*  985 */,
-  U64_C(0xbbb442c16082ae83) /*  986 */, U64_C(0xb95fe86ba5da9ab0) /*  987 */,
-  U64_C(0xb22e04673771a93f) /*  988 */, U64_C(0x845358c9493152d8) /*  989 */,
-  U64_C(0xbe2a488697b4541e) /*  990 */, U64_C(0x95a2dc2dd38e6966) /*  991 */,
-  U64_C(0xc02c11ac923c852b) /*  992 */, U64_C(0x2388b1990df2a87b) /*  993 */,
-  U64_C(0x7c8008fa1b4f37be) /*  994 */, U64_C(0x1f70d0c84d54e503) /*  995 */,
-  U64_C(0x5490adec7ece57d4) /*  996 */, U64_C(0x002b3c27d9063a3a) /*  997 */,
-  U64_C(0x7eaea3848030a2bf) /*  998 */, U64_C(0xc602326ded2003c0) /*  999 */,
-  U64_C(0x83a7287d69a94086) /* 1000 */, U64_C(0xc57a5fcb30f57a8a) /* 1001 */,
-  U64_C(0xb56844e479ebe779) /* 1002 */, U64_C(0xa373b40f05dcbce9) /* 1003 */,
-  U64_C(0xd71a786e88570ee2) /* 1004 */, U64_C(0x879cbacdbde8f6a0) /* 1005 */,
-  U64_C(0x976ad1bcc164a32f) /* 1006 */, U64_C(0xab21e25e9666d78b) /* 1007 */,
-  U64_C(0x901063aae5e5c33c) /* 1008 */, U64_C(0x9818b34448698d90) /* 1009 */,
-  U64_C(0xe36487ae3e1e8abb) /* 1010 */, U64_C(0xafbdf931893bdcb4) /* 1011 */,
-  U64_C(0x6345a0dc5fbbd519) /* 1012 */, U64_C(0x8628fe269b9465ca) /* 1013 */,
-  U64_C(0x1e5d01603f9c51ec) /* 1014 */, U64_C(0x4de44006a15049b7) /* 1015 */,
-  U64_C(0xbf6c70e5f776cbb1) /* 1016 */, U64_C(0x411218f2ef552bed) /* 1017 */,
-  U64_C(0xcb0c0708705a36a3) /* 1018 */, U64_C(0xe74d14754f986044) /* 1019 */,
-  U64_C(0xcd56d9430ea8280e) /* 1020 */, U64_C(0xc12591d7535f5065) /* 1021 */,
-  U64_C(0xc83223f1720aef96) /* 1022 */, U64_C(0xc3a0396f7363a51f) /* 1023 */
-};
-
-static void
-tiger_init( void *context )
-{
-  TIGER_CONTEXT *hd = context;
-
-  hd->a = 0x0123456789abcdefLL;
-  hd->b = 0xfedcba9876543210LL;
-  hd->c = 0xf096a5b4c3b2e187LL;
-  hd->nblocks = 0;
-  hd->count = 0;
-}
-
-static void
-tiger_round( u64 *ra, u64 *rb, u64 *rc, u64 x, int mul )
-{
-  u64 a = *ra;
-  u64 b = *rb;
-  u64 c = *rc;
-  
-  c ^= x;
-  a -= (  sbox1[  c        & 0xff ] ^ sbox2[ (c >> 16) & 0xff ]
-        ^ sbox3[ (c >> 32) & 0xff ] ^ sbox4[ (c >> 48) & 0xff ]);
-  b += (  sbox4[ (c >>  8) & 0xff ] ^ sbox3[ (c >> 24) & 0xff ]
-        ^ sbox2[ (c >> 40) & 0xff ] ^ sbox1[ (c >> 56) & 0xff ]);
-  b *= mul;
-  
-  *ra = a;
-  *rb = b;
-  *rc = c;
-}
-
-
-static void
-pass( u64 *ra, u64 *rb, u64 *rc, u64 *x, int mul )
-{
-  u64 a = *ra;
-  u64 b = *rb;
-  u64 c = *rc;
-
-  tiger_round( &a, &b, &c, x[0], mul );
-  tiger_round( &b, &c, &a, x[1], mul );
-  tiger_round( &c, &a, &b, x[2], mul );
-  tiger_round( &a, &b, &c, x[3], mul );
-  tiger_round( &b, &c, &a, x[4], mul );
-  tiger_round( &c, &a, &b, x[5], mul );
-  tiger_round( &a, &b, &c, x[6], mul );
-  tiger_round( &b, &c, &a, x[7], mul );
-
-  *ra = a;
-  *rb = b;
-  *rc = c;
-}
-
-
-static void
-key_schedule( u64 *x )
-{
-  x[0] -= x[7] ^ 0xa5a5a5a5a5a5a5a5LL;
-  x[1] ^= x[0];
-  x[2] += x[1];
-  x[3] -= x[2] ^ ((~x[1]) << 19 );
-  x[4] ^= x[3];
-  x[5] += x[4];
-  x[6] -= x[5] ^ ((~x[4]) >> 23 );
-  x[7] ^= x[6];
-  x[0] += x[7];
-  x[1] -= x[0] ^ ((~x[7]) << 19 );
-  x[2] ^= x[1];
-  x[3] += x[2];
-  x[4] -= x[3] ^ ((~x[2]) >> 23 );
-  x[5] ^= x[4];
-  x[6] += x[5];
-  x[7] -= x[6] ^ 0x0123456789abcdefLL;
-}
-
-
-/****************
- * Transform the message DATA which consists of 512 bytes (8 words)
- */
-static void
-transform ( TIGER_CONTEXT *hd, const unsigned char *data )
-{
-  u64 a,b,c,aa,bb,cc;
-  u64 x[8];
-#ifdef WORDS_BIGENDIAN
-#define MKWORD(d,n) \
-               (  ((u64)(d)[8*(n)+7]) << 56 | ((u64)(d)[8*(n)+6]) << 48  \
-                | ((u64)(d)[8*(n)+5]) << 40 | ((u64)(d)[8*(n)+4]) << 32  \
-                | ((u64)(d)[8*(n)+3]) << 24 | ((u64)(d)[8*(n)+2]) << 16  \
-                | ((u64)(d)[8*(n)+1]) << 8  | ((u64)(d)[8*(n)  ])       )
-  x[0] = MKWORD(data, 0);
-  x[1] = MKWORD(data, 1);
-  x[2] = MKWORD(data, 2);
-  x[3] = MKWORD(data, 3);
-  x[4] = MKWORD(data, 4);
-  x[5] = MKWORD(data, 5);
-  x[6] = MKWORD(data, 6);
-  x[7] = MKWORD(data, 7);
-#undef MKWORD
-#else
-  memcpy( &x[0], data, 64 );
-#endif
-
-  /* save */
-  a = aa = hd->a;
-  b = bb = hd->b;
-  c = cc = hd->c;
-
-  pass( &a, &b, &c, x, 5);
-  key_schedule( x );
-  pass( &c, &a, &b, x, 7);
-  key_schedule( x );
-  pass( &b, &c, &a, x, 9);
-
-  /* feedforward */
-  a ^= aa;
-  b -= bb;
-  c += cc;
-  /* store */
-  hd->a = a;
-  hd->b = b;
-  hd->c = c;
-}
-
-
-
-/* Update the message digest with the contents
- * of INBUF with length INLEN.
- */
-static void
-tiger_write ( void *context, const void *inbuf_arg, size_t inlen)
-{
-  const unsigned char *inbuf = inbuf_arg;
-  TIGER_CONTEXT *hd = context;
-
-  if( hd->count == 64 ) /* flush the buffer */
-    {
-      transform( hd, hd->buf );
-      _gcry_burn_stack (21*8+11*sizeof(void*));
-      hd->count = 0;
-      hd->nblocks++;
-    }
-  if( !inbuf )
-    return;
-  if( hd->count ) 
-    {
-      for( ; inlen && hd->count < 64; inlen-- )
-        hd->buf[hd->count++] = *inbuf++;
-      tiger_write( hd, NULL, 0 );
-      if( !inlen )
-        return;
-    }
-
-  while( inlen >= 64 )
-    {
-      transform( hd, inbuf );
-      hd->count = 0;
-      hd->nblocks++;
-      inlen -= 64;
-      inbuf += 64;
-    }
-  _gcry_burn_stack (21*8+11*sizeof(void*));
-  for( ; inlen && hd->count < 64; inlen-- )
-    hd->buf[hd->count++] = *inbuf++;
-}
-
-
-
-/* The routine terminates the computation
- */
-static void
-tiger_final( void *context )
-{
-  TIGER_CONTEXT *hd = context;
-  u32 t, msb, lsb;
-  byte *p;
-
-  tiger_write(hd, NULL, 0); /* flush */;
-
-  t = hd->nblocks;
-  /* multiply by 64 to make a byte count */
-  lsb = t << 6;
-  msb = t >> 26;
-  /* add the count */
-  t = lsb;
-  if( (lsb += hd->count) < t )
-    msb++;
-  /* multiply by 8 to make a bit count */
-  t = lsb;
-  lsb <<= 3;
-  msb <<= 3;
-  msb |= t >> 29;
-
-  if( hd->count < 56 )  /* enough room */
-    {
-      hd->buf[hd->count++] = 0x01; /* pad */
-      while( hd->count < 56 )
-        hd->buf[hd->count++] = 0;  /* pad */
-    }
-  else  /* need one extra block */
-    {
-      hd->buf[hd->count++] = 0x01; /* pad character */
-      while( hd->count < 64 )
-        hd->buf[hd->count++] = 0;
-      tiger_write(hd, NULL, 0);  /* flush */;
-      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
-    }
-  /* append the 64 bit count */
-  hd->buf[56] = lsb       ;
-  hd->buf[57] = lsb >>  8;
-  hd->buf[58] = lsb >> 16;
-  hd->buf[59] = lsb >> 24;
-  hd->buf[60] = msb       ;
-  hd->buf[61] = msb >>  8;
-  hd->buf[62] = msb >> 16;
-  hd->buf[63] = msb >> 24;
-  transform( hd, hd->buf );
-  _gcry_burn_stack (21*8+11*sizeof(void*));
-
-  p = hd->buf;
-#ifdef WORDS_BIGENDIAN
-#define X(a) do { *(u64*)p = hd->a ; p += 8; } while(0)
-#else /* little endian */
-#define X(a) do { *p++ = hd->a >> 56; *p++ = hd->a >> 48; \
-                 *p++ = hd->a >> 40; *p++ = hd->a >> 32; \
-                 *p++ = hd->a >> 24; *p++ = hd->a >> 16; \
-                 *p++ = hd->a >>  8; *p++ = hd->a;       } while(0)
-#endif
-  X(a);
-  X(b);
-  X(c);
-#undef X
-}
-
-static byte *
-tiger_read( void *context )
-{
-  TIGER_CONTEXT *hd = context;
-
-  return hd->buf;
-}
-
-static byte asn[19] = /* Object ID is 1.3.6.1.4.1.11591.12.2 */
-  { 0x30, 0x29, 0x30, 0x0d, 0x06, 0x09, 0x2b, 0x06,
-    0x01, 0x04, 0x01, 0xda, 0x47, 0x0c, 0x02,
-    0x05, 0x00, 0x04, 0x18 };
-
-static gcry_md_oid_spec_t oid_spec_tiger[] =
-  {
-    /* GNU.digestAlgorithm TIGER */
-    { "1.3.6.1.4.1.11591.12.2" },
-    { NULL }
-  };
-
-gcry_md_spec_t _gcry_digest_spec_tiger =
-  {
-    "TIGER192", asn, DIM (asn), oid_spec_tiger, 24,
-    tiger_init, tiger_write, tiger_final, tiger_read,
-    sizeof (TIGER_CONTEXT)
-  };
-
-#endif /* HAVE_U64_TYPEDEF */
diff --git a/lib/libgcrypt/cipher/twofish.c b/lib/libgcrypt/cipher/twofish.c
deleted file mode 100644 (file)
index 5274c40..0000000
+++ /dev/null
@@ -1,1040 +0,0 @@
-/* Twofish for GPG
- * Copyright (C) 1998, 2002, 2003 Free Software Foundation, Inc.
- * Written by Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
- * 256-bit key length added March 20, 1999
- * Some modifications to reduce the text size by Werner Koch, April, 1998
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- ********************************************************************
- *
- * This code is a "clean room" implementation, written from the paper
- * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
- * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
- * through http://www.counterpane.com/twofish.html
- *
- * For background information on multiplication in finite fields, used for
- * the matrix operations in the key schedule, see the book _Contemporary
- * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
- * Third Edition.
- *
- * Only the 128- and 256-bit key sizes are supported.  This code is intended
- * for GNU C on a 32-bit system, but it should work almost anywhere.  Loops
- * are unrolled, precomputation tables are used, etc., for maximum speed at
- * some cost in memory consumption. */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h> /* for memcmp() */
-
-#include "types.h"  /* for byte and u32 typedefs */
-#include "g10lib.h"
-#include "cipher.h"
-
-/* Prototype for the self-test function. */
-static const char *selftest(void);
-
-/* Structure for an expanded Twofish key.  s contains the key-dependent
- * S-boxes composed with the MDS matrix; w contains the eight "whitening"
- * subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys.  Note
- * that k[i] corresponds to what the Twofish paper calls K[i+8]. */
-typedef struct {
-   u32 s[4][256], w[8], k[32];
-} TWOFISH_context;
-\f
-/* These two tables are the q0 and q1 permutations, exactly as described in
- * the Twofish paper. */
-
-static const byte q0[256] = {
-   0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
-   0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
-   0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
-   0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
-   0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
-   0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
-   0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
-   0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
-   0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
-   0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
-   0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
-   0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
-   0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
-   0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
-   0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
-   0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
-   0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
-   0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
-   0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
-   0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
-   0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
-   0x4A, 0x5E, 0xC1, 0xE0
-};
-
-static const byte q1[256] = {
-   0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
-   0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
-   0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
-   0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
-   0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
-   0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
-   0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
-   0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
-   0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
-   0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
-   0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
-   0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
-   0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
-   0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
-   0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
-   0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
-   0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
-   0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
-   0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
-   0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
-   0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
-   0x55, 0x09, 0xBE, 0x91
-};
-\f
-/* These MDS tables are actually tables of MDS composed with q0 and q1,
- * because it is only ever used that way and we can save some time by
- * precomputing.  Of course the main saving comes from precomputing the
- * GF(2^8) multiplication involved in the MDS matrix multiply; by looking
- * things up in these tables we reduce the matrix multiply to four lookups
- * and three XORs.  Semi-formally, the definition of these tables is:
- * mds[0][i] = MDS (q1[i] 0 0 0)^T  mds[1][i] = MDS (0 q0[i] 0 0)^T
- * mds[2][i] = MDS (0 0 q1[i] 0)^T  mds[3][i] = MDS (0 0 0 q0[i])^T
- * where ^T means "transpose", the matrix multiply is performed in GF(2^8)
- * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described
- * by Schneier et al, and I'm casually glossing over the byte/word
- * conversion issues. */
-
-static const u32 mds[4][256] = {
-   {0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,
-    0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,
-    0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,
-    0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
-    0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA,
-    0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B,
-    0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1,
-    0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
-    0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490,
-    0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154,
-    0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0,
-    0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
-    0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228,
-    0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7,
-    0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3,
-    0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
-    0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477,
-    0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF,
-    0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C,
-    0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
-    0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA,
-    0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D,
-    0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72,
-    0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
-    0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76,
-    0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321,
-    0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39,
-    0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
-    0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D,
-    0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E,
-    0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5,
-    0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
-    0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7,
-    0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544,
-    0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E,
-    0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
-    0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A,
-    0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B,
-    0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2,
-    0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
-    0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504,
-    0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,
-    0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91},
-
-   {0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,
-    0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,
-    0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,
-    0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
-    0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444,
-    0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424,
-    0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A,
-    0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
-    0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383,
-    0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A,
-    0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9,
-    0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
-    0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1,
-    0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898,
-    0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414,
-    0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
-    0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1,
-    0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989,
-    0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5,
-    0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
-    0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E,
-    0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E,
-    0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202,
-    0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
-    0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565,
-    0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A,
-    0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808,
-    0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
-    0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A,
-    0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969,
-    0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505,
-    0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
-    0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D,
-    0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343,
-    0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF,
-    0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
-    0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F,
-    0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646,
-    0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6,
-    0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
-    0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A,
-    0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,
-    0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8},
-
-   {0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,
-    0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,
-    0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,
-    0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
-    0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70,
-    0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3,
-    0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB,
-    0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
-    0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4,
-    0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41,
-    0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C,
-    0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
-    0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622,
-    0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18,
-    0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035,
-    0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
-    0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84,
-    0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E,
-    0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F,
-    0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
-    0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558,
-    0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40,
-    0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA,
-    0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
-    0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF,
-    0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773,
-    0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D,
-    0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
-    0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C,
-    0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19,
-    0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086,
-    0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
-    0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74,
-    0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755,
-    0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691,
-    0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
-    0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4,
-    0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53,
-    0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E,
-    0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
-    0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705,
-    0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,
-    0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF},
-
-   {0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,
-    0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,
-    0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
-    0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
-    0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9,
-    0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C,
-    0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3,
-    0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
-    0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F,
-    0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25,
-    0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF,
-    0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
-    0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4,
-    0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E,
-    0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA,
-    0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
-    0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12,
-    0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A,
-    0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D,
-    0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
-    0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A,
-    0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C,
-    0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B,
-    0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
-    0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B,
-    0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3,
-    0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE,
-    0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
-    0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85,
-    0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA,
-    0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E,
-    0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
-    0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33,
-    0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC,
-    0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718,
-    0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
-    0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8,
-    0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872,
-    0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882,
-    0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
-    0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10,
-    0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6,
-    0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8}
-};
-\f
-/* The exp_to_poly and poly_to_exp tables are used to perform efficient
- * operations in GF(2^8) represented as GF(2)[x]/w(x) where
- * w(x)=x^8+x^6+x^3+x^2+1.  We care about doing that because it's part of the
- * definition of the RS matrix in the key schedule.  Elements of that field
- * are polynomials of degree not greater than 7 and all coefficients 0 or 1,
- * which can be represented naturally by bytes (just substitute x=2).  In that
- * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8)
- * multiplication is inefficient without hardware support.  To multiply
- * faster, I make use of the fact x is a generator for the nonzero elements,
- * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for
- * some n in 0..254.  Note that that caret is exponentiation in GF(2^8),
- * *not* polynomial notation.  So if I want to compute pq where p and q are
- * in GF(2^8), I can just say:
- *    1. if p=0 or q=0 then pq=0
- *    2. otherwise, find m and n such that p=x^m and q=x^n
- *    3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq
- * The translations in steps 2 and 3 are looked up in the tables
- * poly_to_exp (for step 2) and exp_to_poly (for step 3).  To see this
- * in action, look at the CALC_S macro.  As additional wrinkles, note that
- * one of my operands is always a constant, so the poly_to_exp lookup on it
- * is done in advance; I included the original values in the comments so
- * readers can have some chance of recognizing that this *is* the RS matrix
- * from the Twofish paper.  I've only included the table entries I actually
- * need; I never do a lookup on a variable input of zero and the biggest
- * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll
- * never sum to more than 491. I'm repeating part of the exp_to_poly table
- * so that I don't have to do mod-255 reduction in the exponent arithmetic.
- * Since I know my constant operands are never zero, I only have to worry
- * about zero values in the variable operand, and I do it with a simple
- * conditional branch. I know conditionals are expensive, but I couldn't
- * see a non-horrible way of avoiding them, and I did manage to group the
- * statements so that each if covers four group multiplications. */
-
-static const byte poly_to_exp[255] = {
-   0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
-   0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
-   0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
-   0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B,
-   0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47,
-   0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D,
-   0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8,
-   0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C,
-   0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83,
-   0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48,
-   0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26,
-   0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E,
-   0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3,
-   0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9,
-   0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A,
-   0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D,
-   0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75,
-   0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84,
-   0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64,
-   0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49,
-   0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,
-   0x85, 0xC8, 0xA1
-};
-
-static const byte exp_to_poly[492] = {
-   0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
-   0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
-   0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
-   0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A,
-   0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63,
-   0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C,
-   0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07,
-   0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88,
-   0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12,
-   0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7,
-   0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C,
-   0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8,
-   0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25,
-   0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A,
-   0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE,
-   0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC,
-   0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E,
-   0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92,
-   0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89,
-   0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB,
-   0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,
-   0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D,
-   0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC,
-   0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3,
-   0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52,
-   0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0,
-   0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1,
-   0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A,
-   0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11,
-   0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51,
-   0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66,
-   0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB,
-   0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19,
-   0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D,
-   0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56,
-   0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE,
-   0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9,
-   0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE,
-   0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41,
-   0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E,
-   0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
-};
-\f
-
-/* The table constants are indices of
- * S-box entries, preprocessed through q0 and q1. */
-static byte calc_sb_tbl[512] = {
-    0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4,
-    0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8,
-    0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B,
-    0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B,
-    0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD,
-    0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1,
-    0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B,
-    0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F,
-    0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B,
-    0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D,
-    0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E,
-    0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5,
-    0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14,
-    0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3,
-    0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54,
-    0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51,
-    0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A,
-    0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96,
-    0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10,
-    0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C,
-    0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7,
-    0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70,
-    0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB,
-    0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8,
-    0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF,
-    0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC,
-    0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF,
-    0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2,
-    0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82,
-    0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9,
-    0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97,
-    0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17,
-    0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D,
-    0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3,
-    0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C,
-    0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E,
-    0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F,
-    0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49,
-    0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21,
-    0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9,
-    0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD,
-    0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01,
-    0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F,
-    0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48,
-    0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E,
-    0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19,
-    0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57,
-    0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64,
-    0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE,
-    0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5,
-    0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44,
-    0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69,
-    0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15,
-    0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E,
-    0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34,
-    0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC,
-    0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B,
-    0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB,
-    0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52,
-    0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9,
-    0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4,
-    0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2,
-    0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
-    0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
-};
-/* Macro to perform one column of the RS matrix multiplication.  The
- * parameters a, b, c, and d are the four bytes of output; i is the index
- * of the key bytes, and w, x, y, and z, are the column of constants from
- * the RS matrix, preprocessed through the poly_to_exp table. */
-
-#define CALC_S(a, b, c, d, i, w, x, y, z) \
-   if (key[i]) { \
-      tmp = poly_to_exp[key[i] - 1]; \
-      (a) ^= exp_to_poly[tmp + (w)]; \
-      (b) ^= exp_to_poly[tmp + (x)]; \
-      (c) ^= exp_to_poly[tmp + (y)]; \
-      (d) ^= exp_to_poly[tmp + (z)]; \
-   }
-
-/* Macros to calculate the key-dependent S-boxes for a 128-bit key using
- * the S vector from CALC_S.  CALC_SB_2 computes a single entry in all
- * four S-boxes, where i is the index of the entry to compute, and a and b
- * are the index numbers preprocessed through the q0 and q1 tables
- * respectively.  CALC_SB is simply a convenience to make the code shorter;
- * it calls CALC_SB_2 four times with consecutive indices from i to i+3,
- * using the remaining parameters two by two. */
-
-#define CALC_SB_2(i, a, b) \
-   ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \
-   ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \
-   ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \
-   ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh]
-
-#define CALC_SB(i, a, b, c, d, e, f, g, h) \
-   CALC_SB_2 (i, a, b); CALC_SB_2 ((i)+1, c, d); \
-   CALC_SB_2 ((i)+2, e, f); CALC_SB_2 ((i)+3, g, h)
-
-/* Macros exactly like CALC_SB and CALC_SB_2, but for 256-bit keys. */
-
-#define CALC_SB256_2(i, a, b) \
-   ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \
-   ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \
-   ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \
-   ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp];
-
-#define CALC_SB256(i, a, b, c, d, e, f, g, h) \
-   CALC_SB256_2 (i, a, b); CALC_SB256_2 ((i)+1, c, d); \
-   CALC_SB256_2 ((i)+2, e, f); CALC_SB256_2 ((i)+3, g, h)
-
-/* Macros to calculate the whitening and round subkeys.  CALC_K_2 computes the
- * last two stages of the h() function for a given index (either 2i or 2i+1).
- * a, b, c, and d are the four bytes going into the last two stages.  For
- * 128-bit keys, this is the entire h() function and a and c are the index
- * preprocessed through q0 and q1 respectively; for longer keys they are the
- * output of previous stages.  j is the index of the first key byte to use.
- * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
- * twice, doing the Psuedo-Hadamard Transform, and doing the necessary
- * rotations.  Its parameters are: a, the array to write the results into,
- * j, the index of the first output entry, k and l, the preprocessed indices
- * for index 2i, and m and n, the preprocessed indices for index 2i+1.
- * CALC_K256_2 expands CALC_K_2 to handle 256-bit keys, by doing two
- * additional lookup-and-XOR stages.  The parameters a and b are the index
- * preprocessed through q0 and q1 respectively; j is the index of the first
- * key byte to use.  CALC_K256 is identical to CALC_K but for using the
- * CALC_K256_2 macro instead of CALC_K_2. */
-
-#define CALC_K_2(a, b, c, d, j) \
-     mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \
-   ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \
-   ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \
-   ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]
-
-#define CALC_K(a, j, k, l, m, n) \
-   x = CALC_K_2 (k, l, k, l, 0); \
-   y = CALC_K_2 (m, n, m, n, 4); \
-   y = (y << 8) + (y >> 24); \
-   x += y; y += x; ctx->a[j] = x; \
-   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
-
-#define CALC_K256_2(a, b, j) \
-   CALC_K_2 (q0[q1[b ^ key[(j) + 24]] ^ key[(j) + 16]], \
-            q1[q1[a ^ key[(j) + 25]] ^ key[(j) + 17]], \
-            q0[q0[a ^ key[(j) + 26]] ^ key[(j) + 18]], \
-            q1[q0[b ^ key[(j) + 27]] ^ key[(j) + 19]], j)
-
-#define CALC_K256(a, j, k, l, m, n) \
-   x = CALC_K256_2 (k, l, 0); \
-   y = CALC_K256_2 (m, n, 4); \
-   y = (y << 8) + (y >> 24); \
-   x += y; y += x; ctx->a[j] = x; \
-   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
-\f
-
-
-/* Perform the key setup.  Note that this works only with 128- and 256-bit
- * keys, despite the API that looks like it might support other sizes. */
-
-static gcry_err_code_t
-do_twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
-{
-  int i, j, k;
-
-  /* Temporaries for CALC_K. */
-  u32 x, y;
-
-  /* The S vector used to key the S-boxes, split up into individual bytes.
-   * 128-bit keys use only sa through sh; 256-bit use all of them. */
-  byte sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
-  byte si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
-  
-  /* Temporary for CALC_S. */
-  byte tmp;
-  
-  /* Flags for self-test. */
-  static int initialized = 0;
-  static const char *selftest_failed=0;
-
-  /* Check key length. */
-  if( ( ( keylen - 16 ) | 16 ) != 16 )
-    return GPG_ERR_INV_KEYLEN;
-
-  /* Do self-test if necessary. */
-  if (!initialized)
-    {
-      initialized = 1;
-      selftest_failed = selftest ();
-      if( selftest_failed )
-        log_error("%s\n", selftest_failed );
-    }
-  if( selftest_failed )
-    return GPG_ERR_SELFTEST_FAILED;
-
-  /* Compute the first two words of the S vector.  The magic numbers are
-   * the entries of the RS matrix, preprocessed through poly_to_exp.   The
-   * numbers in the comments are the original (polynomial form) matrix
-   * entries. */
-  CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
-  CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
-  CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
-  CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
-  CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
-  CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
-  CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
-  CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
-  CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
-  CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
-  CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
-  CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
-  CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
-  CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
-  CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
-  CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
-
-  if (keylen == 32)  /* 256-bit key */
-    {
-      /* Calculate the remaining two words of the S vector */
-      CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
-      CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
-      CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
-      CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
-      CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
-      CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
-      CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
-      CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
-      CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
-      CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
-      CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
-      CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
-      CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
-      CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
-      CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
-      CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
-
-      /* Compute the S-boxes. */
-      for(i=j=0,k=1; i < 256; i++, j += 2, k += 2 )
-        {
-          CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
-       }
-
-      /* Calculate whitening and round subkeys.  The constants are
-       * indices of subkeys, preprocessed through q0 and q1. */
-      CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
-      CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
-      CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
-      CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
-      CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
-      CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
-      CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
-      CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
-      CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
-      CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
-      CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
-      CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
-      CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
-      CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
-      CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
-      CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
-      CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
-      CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
-      CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
-      CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
-    }
-  else 
-    {
-      /* Compute the S-boxes. */
-      for(i=j=0,k=1; i < 256; i++, j += 2, k += 2 )
-        {
-          CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
-        }
-
-      /* Calculate whitening and round subkeys.  The constants are
-       * indices of subkeys, preprocessed through q0 and q1. */
-      CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
-      CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
-      CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
-      CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
-      CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
-      CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
-      CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
-      CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
-      CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
-      CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
-      CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
-      CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
-      CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
-      CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
-      CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
-      CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
-      CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
-      CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
-      CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
-      CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
-    }
-
-  return 0;
-}
-
-static gcry_err_code_t
-twofish_setkey (void *context, const byte *key, unsigned int keylen)
-{
-  TWOFISH_context *ctx = context;
-  int rc = do_twofish_setkey (ctx, key, keylen);
-  _gcry_burn_stack (23+6*sizeof(void*));
-  return rc;
-}
-
-
-\f
-/* Macros to compute the g() function in the encryption and decryption
- * rounds.  G1 is the straight g() function; G2 includes the 8-bit
- * rotation for the high 32-bit word. */
-
-#define G1(a) \
-     (ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \
-   ^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24])
-
-#define G2(b) \
-     (ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \
-   ^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24])
-
-/* Encryption and decryption Feistel rounds.  Each one calls the two g()
- * macros, does the PHT, and performs the XOR and the appropriate bit
- * rotations.  The parameters are the round number (used to select subkeys),
- * and the four 32-bit chunks of the text. */
-
-#define ENCROUND(n, a, b, c, d) \
-   x = G1 (a); y = G2 (b); \
-   x += y; y += x + ctx->k[2 * (n) + 1]; \
-   (c) ^= x + ctx->k[2 * (n)]; \
-   (c) = ((c) >> 1) + ((c) << 31); \
-   (d) = (((d) << 1)+((d) >> 31)) ^ y
-
-#define DECROUND(n, a, b, c, d) \
-   x = G1 (a); y = G2 (b); \
-   x += y; y += x; \
-   (d) ^= y + ctx->k[2 * (n) + 1]; \
-   (d) = ((d) >> 1) + ((d) << 31); \
-   (c) = (((c) << 1)+((c) >> 31)); \
-   (c) ^= (x + ctx->k[2 * (n)])
-
-/* Encryption and decryption cycles; each one is simply two Feistel rounds
- * with the 32-bit chunks re-ordered to simulate the "swap" */
-
-#define ENCCYCLE(n) \
-   ENCROUND (2 * (n), a, b, c, d); \
-   ENCROUND (2 * (n) + 1, c, d, a, b)
-
-#define DECCYCLE(n) \
-   DECROUND (2 * (n) + 1, c, d, a, b); \
-   DECROUND (2 * (n), a, b, c, d)
-
-/* Macros to convert the input and output bytes into 32-bit words,
- * and simultaneously perform the whitening step.  INPACK packs word
- * number n into the variable named by x, using whitening subkey number m.
- * OUTUNPACK unpacks word number n from the variable named by x, using
- * whitening subkey number m. */
-
-#define INPACK(n, x, m) \
-   x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \
-     ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m]
-
-#define OUTUNPACK(n, x, m) \
-   x ^= ctx->w[m]; \
-   out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \
-   out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24
-\f
-/* Encrypt one block.  in and out may be the same. */
-
-static void
-do_twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
-{
-  /* The four 32-bit chunks of the text. */
-  u32 a, b, c, d;
-
-  /* Temporaries used by the round function. */
-  u32 x, y;
-
-  /* Input whitening and packing. */
-  INPACK (0, a, 0);
-  INPACK (1, b, 1);
-  INPACK (2, c, 2);
-  INPACK (3, d, 3);
-
-  /* Encryption Feistel cycles. */
-  ENCCYCLE (0);
-  ENCCYCLE (1);
-  ENCCYCLE (2);
-  ENCCYCLE (3);
-  ENCCYCLE (4);
-  ENCCYCLE (5);
-  ENCCYCLE (6);
-  ENCCYCLE (7);
-
-  /* Output whitening and unpacking. */
-  OUTUNPACK (0, c, 4);
-  OUTUNPACK (1, d, 5);
-  OUTUNPACK (2, a, 6);
-  OUTUNPACK (3, b, 7);
-}
-
-static void
-twofish_encrypt (void *context, byte *out, const byte *in)
-{
-  TWOFISH_context *ctx = context;
-  do_twofish_encrypt (ctx, out, in);
-  _gcry_burn_stack (24+3*sizeof (void*));
-}
-
-\f
-/* Decrypt one block.  in and out may be the same. */
-
-static void
-do_twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
-{
-  /* The four 32-bit chunks of the text. */
-  u32 a, b, c, d;
-
-  /* Temporaries used by the round function. */
-  u32 x, y;
-
-  /* Input whitening and packing. */
-  INPACK (0, c, 4);
-  INPACK (1, d, 5);
-  INPACK (2, a, 6);
-  INPACK (3, b, 7);
-
-  /* Encryption Feistel cycles. */
-  DECCYCLE (7);
-  DECCYCLE (6);
-  DECCYCLE (5);
-  DECCYCLE (4);
-  DECCYCLE (3);
-  DECCYCLE (2);
-  DECCYCLE (1);
-  DECCYCLE (0);
-
-  /* Output whitening and unpacking. */
-  OUTUNPACK (0, a, 0);
-  OUTUNPACK (1, b, 1);
-  OUTUNPACK (2, c, 2);
-  OUTUNPACK (3, d, 3);
-}
-
-static void
-twofish_decrypt (void *context, byte *out, const byte *in)
-{
-  TWOFISH_context *ctx = context;
-
-  do_twofish_decrypt (ctx, out, in);
-  _gcry_burn_stack (24+3*sizeof (void*));
-}
-
-\f
-/* Test a single encryption and decryption with each key size. */
-
-static const char*
-selftest (void)
-{
-  TWOFISH_context ctx; /* Expanded key. */
-  byte scratch[16];    /* Encryption/decryption result buffer. */
-
-  /* Test vectors for single encryption/decryption.  Note that I am using
-   * the vectors from the Twofish paper's "known answer test", I=3 for
-   * 128-bit and I=4 for 256-bit, instead of the all-0 vectors from the
-   * "intermediate value test", because an all-0 key would trigger all the
-   * special cases in the RS matrix multiply, leaving the math untested. */
-  static  byte plaintext[16] = {
-    0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,
-    0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19
-  };
-  static byte key[16] = {
-    0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
-    0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A
-  };
-  static const byte ciphertext[16] = {
-    0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,
-    0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3
-  };
-  static byte plaintext_256[16] = {
-    0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F,
-    0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6
-  };
-  static byte key_256[32] = {
-    0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
-    0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
-    0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
-    0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F
-  };
-  static const byte ciphertext_256[16] = {
-    0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97,
-    0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA
-  };
-
-  twofish_setkey (&ctx, key, sizeof(key));
-  twofish_encrypt (&ctx, scratch, plaintext);
-  if (memcmp (scratch, ciphertext, sizeof (ciphertext)))
-    return "Twofish-128 test encryption failed.";
-  twofish_decrypt (&ctx, scratch, scratch);
-  if (memcmp (scratch, plaintext, sizeof (plaintext)))
-    return "Twofish-128 test decryption failed.";
-
-  twofish_setkey (&ctx, key_256, sizeof(key_256));
-  twofish_encrypt (&ctx, scratch, plaintext_256);
-  if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256)))
-    return "Twofish-256 test encryption failed.";
-  twofish_decrypt (&ctx, scratch, scratch);
-  if (memcmp (scratch, plaintext_256, sizeof (plaintext_256)))
-    return "Twofish-256 test decryption failed.";
-
-  return NULL;
-}
-\f
-/* More complete test program. This does 1000 encryptions and decryptions
- * with each of 250 128-bit keys and 2000 encryptions and decryptions with
- * each of 125 256-bit keys, using a feedback scheme similar to a Feistel
- * cipher, so as to be sure of testing all the table entries pretty
- * thoroughly. We keep changing the keys so as to get a more meaningful
- * performance number, since the key setup is non-trivial for Twofish. */
-
-#ifdef TEST
-
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-
-int
-main()
-{
-  TWOFISH_context ctx;     /* Expanded key. */
-  int i, j;                /* Loop counters. */
-
-  const char *encrypt_msg; /* Message to print regarding encryption test;
-                            * the printf is done outside the loop to avoid
-                            * stuffing up the timing. */
-  clock_t timer; /* For computing elapsed time. */
-
-  /* Test buffer. */
-  byte buffer[4][16] = {
-    {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
-     0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
-    {0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x5A, 0x69, 0x78,
-     0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0},
-    {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
-     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54 ,0x32, 0x10},
-    {0x01, 0x23, 0x45, 0x67, 0x76, 0x54 ,0x32, 0x10,
-     0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98}
-  };
-
-  /* Expected outputs for the million-operation test */
-  static const byte test_encrypt[4][16] = {
-    {0xC8, 0x23, 0xB8, 0xB7, 0x6B, 0xFE, 0x91, 0x13,
-     0x2F, 0xA7, 0x5E, 0xE6, 0x94, 0x77, 0x6F, 0x6B},
-    {0x90, 0x36, 0xD8, 0x29, 0xD5, 0x96, 0xC2, 0x8E,
-     0xE4, 0xFF, 0x76, 0xBC, 0xE5, 0x77, 0x88, 0x27},
-    {0xB8, 0x78, 0x69, 0xAF, 0x42, 0x8B, 0x48, 0x64,
-     0xF7, 0xE9, 0xF3, 0x9C, 0x42, 0x18, 0x7B, 0x73},
-    {0x7A, 0x88, 0xFB, 0xEB, 0x90, 0xA4, 0xB4, 0xA8,
-     0x43, 0xA3, 0x1D, 0xF1, 0x26, 0xC4, 0x53, 0x57}
-  };
-  static const byte test_decrypt[4][16] = {
-    {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
-     0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
-    {0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x5A, 0x69, 0x78,
-     0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0},
-    {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
-     0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54 ,0x32, 0x10},
-    {0x01, 0x23, 0x45, 0x67, 0x76, 0x54 ,0x32, 0x10,
-     0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98}
-  };
-
-  /* Start the timer ticking. */
-  timer = clock ();
-
-  /* Encryption test. */
-  for (i = 0; i < 125; i++) 
-    {
-      twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]));
-      for (j = 0; j < 1000; j++)
-        twofish_encrypt (&ctx, buffer[2], buffer[2]);
-      twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]));
-      for (j = 0; j < 1000; j++)
-        twofish_encrypt (&ctx, buffer[3], buffer[3]);
-      twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2);
-      for (j = 0; j < 1000; j++) {
-        twofish_encrypt (&ctx, buffer[0], buffer[0]);
-        twofish_encrypt (&ctx, buffer[1], buffer[1]);
-      }
-    }
-  encrypt_msg = memcmp (buffer, test_encrypt, sizeof (test_encrypt)) ?
-    "encryption failure!\n" : "encryption OK!\n";
-
-  /* Decryption test. */
-  for (i = 0; i < 125; i++) 
-    {
-      twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2);
-      for (j = 0; j < 1000; j++) {
-        twofish_decrypt (&ctx, buffer[0], buffer[0]);
-        twofish_decrypt (&ctx, buffer[1], buffer[1]);
-      }
-      twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]));
-      for (j = 0; j < 1000; j++)
-        twofish_decrypt (&ctx, buffer[3], buffer[3]);
-      twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]));
-      for (j = 0; j < 1000; j++)
-        twofish_decrypt (&ctx, buffer[2], buffer[2]);
-    }
-
-  /* Stop the timer, and print results. */
-  timer = clock () - timer;
-  printf (encrypt_msg);
-  printf (memcmp (buffer, test_decrypt, sizeof (test_decrypt)) ?
-          "decryption failure!\n" : "decryption OK!\n");
-  printf ("elapsed time: %.1f s.\n", (float) timer / CLOCKS_PER_SEC);
-
-  return 0;
-}
-
-#endif /* TEST */
-
-\f
-
-gcry_cipher_spec_t _gcry_cipher_spec_twofish =
-  {
-    "TWOFISH", NULL, NULL, 16, 256, sizeof (TWOFISH_context),
-    twofish_setkey, twofish_encrypt, twofish_decrypt
-  };
-
-gcry_cipher_spec_t _gcry_cipher_spec_twofish128 =
-  {
-    "TWOFISH128", NULL, NULL, 16, 128, sizeof (TWOFISH_context),
-    twofish_setkey, twofish_encrypt, twofish_decrypt
-  };
diff --git a/lib/libgcrypt/cipher/whirlpool.c b/lib/libgcrypt/cipher/whirlpool.c
deleted file mode 100644 (file)
index 9b029ee..0000000
+++ /dev/null
@@ -1,1406 +0,0 @@
-/* whirlpool.c - Whirlpool hashing algorithm
- * Copyright (C) 2005 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- */
-
-/* This is an implementation of the Whirlpool hashing algorithm, which
-   has been developed by Vincent Rijmen and Paulo S. L. M. Barreto;
-   it's homepage is located at:
-   http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html.
-
-   The S-Boxes and the structure of the main transformation function,
-   which implements an optimized version of the algorithm, is taken
-   from the reference implementation available from
-   http://planeta.terra.com.br/informatica/paulobarreto/whirlpool.zip.  */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "types.h"
-#include "g10lib.h"
-#include "memory.h"
-#include "cipher.h"
-
-#include "bithelp.h"
-
-/* Size of a whirlpool block (in bytes).  */
-#define BLOCK_SIZE 64
-
-/* Number of rounds.  */
-#define R 10
-
-\f
-
-/* Types.  */
-typedef u64 whirlpool_block_t[BLOCK_SIZE / 8];
-
-typedef struct {
-  whirlpool_block_t hash_state;
-  unsigned char buffer[BLOCK_SIZE];
-  size_t count;
-  unsigned char length[32];
-} whirlpool_context_t;
-
-\f
-
-/* Macros. */
-
-/* Convert the the buffer BUFFER into a block BLOCK, using I as
-   counter.  */
-#define buffer_to_block(buffer, block, i) \
-  for (i = 0; i < 8; i++) \
-    (block)[i] = ((u64) (0 \
-                         | (((u64) (buffer)[i * 8 + 0]) << 56) \
-                         | (((u64) (buffer)[i * 8 + 1]) << 48) \
-                         | (((u64) (buffer)[i * 8 + 2]) << 40) \
-                         | (((u64) (buffer)[i * 8 + 3]) << 32) \
-                         | (((u64) (buffer)[i * 8 + 4]) << 24) \
-                         | (((u64) (buffer)[i * 8 + 5]) << 16) \
-                         | (((u64) (buffer)[i * 8 + 6]) <<  8) \
-                         | (((u64) (buffer)[i * 8 + 7]) <<  0)));
-
-/* Convert the block BLOCK into a buffer BUFFER, using I as
-   counter.  */
-#define block_to_buffer(buffer, block, i) \
-  for (i = 0; i < 8; i++) \
-    { \
-      (buffer)[i * 8 + 0] = (block[i] >> 56) & 0xFF; \
-      (buffer)[i * 8 + 1] = (block[i] >> 48) & 0xFF; \
-      (buffer)[i * 8 + 2] = (block[i] >> 40) & 0xFF; \
-      (buffer)[i * 8 + 3] = (block[i] >> 32) & 0xFF; \
-      (buffer)[i * 8 + 4] = (block[i] >> 24) & 0xFF; \
-      (buffer)[i * 8 + 5] = (block[i] >> 16) & 0xFF; \
-      (buffer)[i * 8 + 6] = (block[i] >>  8) & 0xFF; \
-      (buffer)[i * 8 + 7] = (block[i] >>  0) & 0xFF; \
-    }
-
-/* Copy the block BLOCK_SRC to BLOCK_DST, using I as counter.  */
-#define block_copy(block_dst, block_src, i) \
-  for (i = 0; i < 8; i++) \
-    block_dst[i] = block_src[i];
-
-/* XOR the block BLOCK_SRC into BLOCK_DST, using I as counter.  */
-#define block_xor(block_dst, block_src, i) \
-  for (i = 0; i < 8; i++) \
-    block_dst[i] ^= block_src[i];
-
-\f
-
-/* Round constants.  */
-static const u64 rc[R] =
-  {
-    U64_C (0x1823c6e887b8014f),
-    U64_C (0x36a6d2f5796f9152),
-    U64_C (0x60bc9b8ea30c7b35),
-    U64_C (0x1de0d7c22e4bfe57),
-    U64_C (0x157737e59ff04ada),
-    U64_C (0x58c9290ab1a06b85),
-    U64_C (0xbd5d10f4cb3e0567),
-    U64_C (0xe427418ba77d95d8),
-    U64_C (0xfbee7c66dd17479e),
-    U64_C (0xca2dbf07ad5a8333),
-  };
-  
-\f
-
-/* Main lookup boxes.  */
-static const u64 C0[256] =
-  {
-    U64_C (0x18186018c07830d8), U64_C (0x23238c2305af4626),
-    U64_C (0xc6c63fc67ef991b8), U64_C (0xe8e887e8136fcdfb),
-    U64_C (0x878726874ca113cb), U64_C (0xb8b8dab8a9626d11),
-    U64_C (0x0101040108050209), U64_C (0x4f4f214f426e9e0d),
-    U64_C (0x3636d836adee6c9b), U64_C (0xa6a6a2a6590451ff),
-    U64_C (0xd2d26fd2debdb90c), U64_C (0xf5f5f3f5fb06f70e),
-    U64_C (0x7979f979ef80f296), U64_C (0x6f6fa16f5fcede30),
-    U64_C (0x91917e91fcef3f6d), U64_C (0x52525552aa07a4f8),
-    U64_C (0x60609d6027fdc047), U64_C (0xbcbccabc89766535),
-    U64_C (0x9b9b569baccd2b37), U64_C (0x8e8e028e048c018a),
-    U64_C (0xa3a3b6a371155bd2), U64_C (0x0c0c300c603c186c),
-    U64_C (0x7b7bf17bff8af684), U64_C (0x3535d435b5e16a80),
-    U64_C (0x1d1d741de8693af5), U64_C (0xe0e0a7e05347ddb3),
-    U64_C (0xd7d77bd7f6acb321), U64_C (0xc2c22fc25eed999c),
-    U64_C (0x2e2eb82e6d965c43), U64_C (0x4b4b314b627a9629),
-    U64_C (0xfefedffea321e15d), U64_C (0x575741578216aed5),
-    U64_C (0x15155415a8412abd), U64_C (0x7777c1779fb6eee8),
-    U64_C (0x3737dc37a5eb6e92), U64_C (0xe5e5b3e57b56d79e),
-    U64_C (0x9f9f469f8cd92313), U64_C (0xf0f0e7f0d317fd23),
-    U64_C (0x4a4a354a6a7f9420), U64_C (0xdada4fda9e95a944),
-    U64_C (0x58587d58fa25b0a2), U64_C (0xc9c903c906ca8fcf),
-    U64_C (0x2929a429558d527c), U64_C (0x0a0a280a5022145a),
-    U64_C (0xb1b1feb1e14f7f50), U64_C (0xa0a0baa0691a5dc9),
-    U64_C (0x6b6bb16b7fdad614), U64_C (0x85852e855cab17d9),
-    U64_C (0xbdbdcebd8173673c), U64_C (0x5d5d695dd234ba8f),
-    U64_C (0x1010401080502090), U64_C (0xf4f4f7f4f303f507),
-    U64_C (0xcbcb0bcb16c08bdd), U64_C (0x3e3ef83eedc67cd3),
-    U64_C (0x0505140528110a2d), U64_C (0x676781671fe6ce78),
-    U64_C (0xe4e4b7e47353d597), U64_C (0x27279c2725bb4e02),
-    U64_C (0x4141194132588273), U64_C (0x8b8b168b2c9d0ba7),
-    U64_C (0xa7a7a6a7510153f6), U64_C (0x7d7de97dcf94fab2),
-    U64_C (0x95956e95dcfb3749), U64_C (0xd8d847d88e9fad56),
-    U64_C (0xfbfbcbfb8b30eb70), U64_C (0xeeee9fee2371c1cd),
-    U64_C (0x7c7ced7cc791f8bb), U64_C (0x6666856617e3cc71),
-    U64_C (0xdddd53dda68ea77b), U64_C (0x17175c17b84b2eaf),
-    U64_C (0x4747014702468e45), U64_C (0x9e9e429e84dc211a),
-    U64_C (0xcaca0fca1ec589d4), U64_C (0x2d2db42d75995a58),
-    U64_C (0xbfbfc6bf9179632e), U64_C (0x07071c07381b0e3f),
-    U64_C (0xadad8ead012347ac), U64_C (0x5a5a755aea2fb4b0),
-    U64_C (0x838336836cb51bef), U64_C (0x3333cc3385ff66b6),
-    U64_C (0x636391633ff2c65c), U64_C (0x02020802100a0412),
-    U64_C (0xaaaa92aa39384993), U64_C (0x7171d971afa8e2de),
-    U64_C (0xc8c807c80ecf8dc6), U64_C (0x19196419c87d32d1),
-    U64_C (0x494939497270923b), U64_C (0xd9d943d9869aaf5f),
-    U64_C (0xf2f2eff2c31df931), U64_C (0xe3e3abe34b48dba8),
-    U64_C (0x5b5b715be22ab6b9), U64_C (0x88881a8834920dbc),
-    U64_C (0x9a9a529aa4c8293e), U64_C (0x262698262dbe4c0b),
-    U64_C (0x3232c8328dfa64bf), U64_C (0xb0b0fab0e94a7d59),
-    U64_C (0xe9e983e91b6acff2), U64_C (0x0f0f3c0f78331e77),
-    U64_C (0xd5d573d5e6a6b733), U64_C (0x80803a8074ba1df4),
-    U64_C (0xbebec2be997c6127), U64_C (0xcdcd13cd26de87eb),
-    U64_C (0x3434d034bde46889), U64_C (0x48483d487a759032),
-    U64_C (0xffffdbffab24e354), U64_C (0x7a7af57af78ff48d),
-    U64_C (0x90907a90f4ea3d64), U64_C (0x5f5f615fc23ebe9d),
-    U64_C (0x202080201da0403d), U64_C (0x6868bd6867d5d00f),
-    U64_C (0x1a1a681ad07234ca), U64_C (0xaeae82ae192c41b7),
-    U64_C (0xb4b4eab4c95e757d), U64_C (0x54544d549a19a8ce),
-    U64_C (0x93937693ece53b7f), U64_C (0x222288220daa442f),
-    U64_C (0x64648d6407e9c863), U64_C (0xf1f1e3f1db12ff2a),
-    U64_C (0x7373d173bfa2e6cc), U64_C (0x12124812905a2482),
-    U64_C (0x40401d403a5d807a), U64_C (0x0808200840281048),
-    U64_C (0xc3c32bc356e89b95), U64_C (0xecec97ec337bc5df),
-    U64_C (0xdbdb4bdb9690ab4d), U64_C (0xa1a1bea1611f5fc0),
-    U64_C (0x8d8d0e8d1c830791), U64_C (0x3d3df43df5c97ac8),
-    U64_C (0x97976697ccf1335b), U64_C (0x0000000000000000),
-    U64_C (0xcfcf1bcf36d483f9), U64_C (0x2b2bac2b4587566e),
-    U64_C (0x7676c57697b3ece1), U64_C (0x8282328264b019e6),
-    U64_C (0xd6d67fd6fea9b128), U64_C (0x1b1b6c1bd87736c3),
-    U64_C (0xb5b5eeb5c15b7774), U64_C (0xafaf86af112943be),
-    U64_C (0x6a6ab56a77dfd41d), U64_C (0x50505d50ba0da0ea),
-    U64_C (0x45450945124c8a57), U64_C (0xf3f3ebf3cb18fb38),
-    U64_C (0x3030c0309df060ad), U64_C (0xefef9bef2b74c3c4),
-    U64_C (0x3f3ffc3fe5c37eda), U64_C (0x55554955921caac7),
-    U64_C (0xa2a2b2a2791059db), U64_C (0xeaea8fea0365c9e9),
-    U64_C (0x656589650fecca6a), U64_C (0xbabad2bab9686903),
-    U64_C (0x2f2fbc2f65935e4a), U64_C (0xc0c027c04ee79d8e),
-    U64_C (0xdede5fdebe81a160), U64_C (0x1c1c701ce06c38fc),
-    U64_C (0xfdfdd3fdbb2ee746), U64_C (0x4d4d294d52649a1f),
-    U64_C (0x92927292e4e03976), U64_C (0x7575c9758fbceafa),
-    U64_C (0x06061806301e0c36), U64_C (0x8a8a128a249809ae),
-    U64_C (0xb2b2f2b2f940794b), U64_C (0xe6e6bfe66359d185),
-    U64_C (0x0e0e380e70361c7e), U64_C (0x1f1f7c1ff8633ee7),
-    U64_C (0x6262956237f7c455), U64_C (0xd4d477d4eea3b53a),
-    U64_C (0xa8a89aa829324d81), U64_C (0x96966296c4f43152),
-    U64_C (0xf9f9c3f99b3aef62), U64_C (0xc5c533c566f697a3),
-    U64_C (0x2525942535b14a10), U64_C (0x59597959f220b2ab),
-    U64_C (0x84842a8454ae15d0), U64_C (0x7272d572b7a7e4c5),
-    U64_C (0x3939e439d5dd72ec), U64_C (0x4c4c2d4c5a619816),
-    U64_C (0x5e5e655eca3bbc94), U64_C (0x7878fd78e785f09f),
-    U64_C (0x3838e038ddd870e5), U64_C (0x8c8c0a8c14860598),
-    U64_C (0xd1d163d1c6b2bf17), U64_C (0xa5a5aea5410b57e4),
-    U64_C (0xe2e2afe2434dd9a1), U64_C (0x616199612ff8c24e),
-    U64_C (0xb3b3f6b3f1457b42), U64_C (0x2121842115a54234),
-    U64_C (0x9c9c4a9c94d62508), U64_C (0x1e1e781ef0663cee),
-    U64_C (0x4343114322528661), U64_C (0xc7c73bc776fc93b1),
-    U64_C (0xfcfcd7fcb32be54f), U64_C (0x0404100420140824),
-    U64_C (0x51515951b208a2e3), U64_C (0x99995e99bcc72f25),
-    U64_C (0x6d6da96d4fc4da22), U64_C (0x0d0d340d68391a65),
-    U64_C (0xfafacffa8335e979), U64_C (0xdfdf5bdfb684a369),
-    U64_C (0x7e7ee57ed79bfca9), U64_C (0x242490243db44819),
-    U64_C (0x3b3bec3bc5d776fe), U64_C (0xabab96ab313d4b9a),
-    U64_C (0xcece1fce3ed181f0), U64_C (0x1111441188552299),
-    U64_C (0x8f8f068f0c890383), U64_C (0x4e4e254e4a6b9c04),
-    U64_C (0xb7b7e6b7d1517366), U64_C (0xebeb8beb0b60cbe0),
-    U64_C (0x3c3cf03cfdcc78c1), U64_C (0x81813e817cbf1ffd),
-    U64_C (0x94946a94d4fe3540), U64_C (0xf7f7fbf7eb0cf31c),
-    U64_C (0xb9b9deb9a1676f18), U64_C (0x13134c13985f268b),
-    U64_C (0x2c2cb02c7d9c5851), U64_C (0xd3d36bd3d6b8bb05),
-    U64_C (0xe7e7bbe76b5cd38c), U64_C (0x6e6ea56e57cbdc39),
-    U64_C (0xc4c437c46ef395aa), U64_C (0x03030c03180f061b),
-    U64_C (0x565645568a13acdc), U64_C (0x44440d441a49885e),
-    U64_C (0x7f7fe17fdf9efea0), U64_C (0xa9a99ea921374f88),
-    U64_C (0x2a2aa82a4d825467), U64_C (0xbbbbd6bbb16d6b0a),
-    U64_C (0xc1c123c146e29f87), U64_C (0x53535153a202a6f1),
-    U64_C (0xdcdc57dcae8ba572), U64_C (0x0b0b2c0b58271653),
-    U64_C (0x9d9d4e9d9cd32701), U64_C (0x6c6cad6c47c1d82b),
-    U64_C (0x3131c43195f562a4), U64_C (0x7474cd7487b9e8f3),
-    U64_C (0xf6f6fff6e309f115), U64_C (0x464605460a438c4c),
-    U64_C (0xacac8aac092645a5), U64_C (0x89891e893c970fb5),
-    U64_C (0x14145014a04428b4), U64_C (0xe1e1a3e15b42dfba),
-    U64_C (0x16165816b04e2ca6), U64_C (0x3a3ae83acdd274f7),
-    U64_C (0x6969b9696fd0d206), U64_C (0x09092409482d1241),
-    U64_C (0x7070dd70a7ade0d7), U64_C (0xb6b6e2b6d954716f),
-    U64_C (0xd0d067d0ceb7bd1e), U64_C (0xeded93ed3b7ec7d6),
-    U64_C (0xcccc17cc2edb85e2), U64_C (0x424215422a578468),
-    U64_C (0x98985a98b4c22d2c), U64_C (0xa4a4aaa4490e55ed),
-    U64_C (0x2828a0285d885075), U64_C (0x5c5c6d5cda31b886),
-    U64_C (0xf8f8c7f8933fed6b), U64_C (0x8686228644a411c2),
-  };
-
-static const u64 C1[256] =
-  {
-    U64_C (0xd818186018c07830), U64_C (0x2623238c2305af46),
-    U64_C (0xb8c6c63fc67ef991), U64_C (0xfbe8e887e8136fcd),
-    U64_C (0xcb878726874ca113), U64_C (0x11b8b8dab8a9626d),
-    U64_C (0x0901010401080502), U64_C (0x0d4f4f214f426e9e),
-    U64_C (0x9b3636d836adee6c), U64_C (0xffa6a6a2a6590451),
-    U64_C (0x0cd2d26fd2debdb9), U64_C (0x0ef5f5f3f5fb06f7),
-    U64_C (0x967979f979ef80f2), U64_C (0x306f6fa16f5fcede),
-    U64_C (0x6d91917e91fcef3f), U64_C (0xf852525552aa07a4),
-    U64_C (0x4760609d6027fdc0), U64_C (0x35bcbccabc897665),
-    U64_C (0x379b9b569baccd2b), U64_C (0x8a8e8e028e048c01),
-    U64_C (0xd2a3a3b6a371155b), U64_C (0x6c0c0c300c603c18),
-    U64_C (0x847b7bf17bff8af6), U64_C (0x803535d435b5e16a),
-    U64_C (0xf51d1d741de8693a), U64_C (0xb3e0e0a7e05347dd),
-    U64_C (0x21d7d77bd7f6acb3), U64_C (0x9cc2c22fc25eed99),
-    U64_C (0x432e2eb82e6d965c), U64_C (0x294b4b314b627a96),
-    U64_C (0x5dfefedffea321e1), U64_C (0xd5575741578216ae),
-    U64_C (0xbd15155415a8412a), U64_C (0xe87777c1779fb6ee),
-    U64_C (0x923737dc37a5eb6e), U64_C (0x9ee5e5b3e57b56d7),
-    U64_C (0x139f9f469f8cd923), U64_C (0x23f0f0e7f0d317fd),
-    U64_C (0x204a4a354a6a7f94), U64_C (0x44dada4fda9e95a9),
-    U64_C (0xa258587d58fa25b0), U64_C (0xcfc9c903c906ca8f),
-    U64_C (0x7c2929a429558d52), U64_C (0x5a0a0a280a502214),
-    U64_C (0x50b1b1feb1e14f7f), U64_C (0xc9a0a0baa0691a5d),
-    U64_C (0x146b6bb16b7fdad6), U64_C (0xd985852e855cab17),
-    U64_C (0x3cbdbdcebd817367), U64_C (0x8f5d5d695dd234ba),
-    U64_C (0x9010104010805020), U64_C (0x07f4f4f7f4f303f5),
-    U64_C (0xddcbcb0bcb16c08b), U64_C (0xd33e3ef83eedc67c),
-    U64_C (0x2d0505140528110a), U64_C (0x78676781671fe6ce),
-    U64_C (0x97e4e4b7e47353d5), U64_C (0x0227279c2725bb4e),
-    U64_C (0x7341411941325882), U64_C (0xa78b8b168b2c9d0b),
-    U64_C (0xf6a7a7a6a7510153), U64_C (0xb27d7de97dcf94fa),
-    U64_C (0x4995956e95dcfb37), U64_C (0x56d8d847d88e9fad),
-    U64_C (0x70fbfbcbfb8b30eb), U64_C (0xcdeeee9fee2371c1),
-    U64_C (0xbb7c7ced7cc791f8), U64_C (0x716666856617e3cc),
-    U64_C (0x7bdddd53dda68ea7), U64_C (0xaf17175c17b84b2e),
-    U64_C (0x454747014702468e), U64_C (0x1a9e9e429e84dc21),
-    U64_C (0xd4caca0fca1ec589), U64_C (0x582d2db42d75995a),
-    U64_C (0x2ebfbfc6bf917963), U64_C (0x3f07071c07381b0e),
-    U64_C (0xacadad8ead012347), U64_C (0xb05a5a755aea2fb4),
-    U64_C (0xef838336836cb51b), U64_C (0xb63333cc3385ff66),
-    U64_C (0x5c636391633ff2c6), U64_C (0x1202020802100a04),
-    U64_C (0x93aaaa92aa393849), U64_C (0xde7171d971afa8e2),
-    U64_C (0xc6c8c807c80ecf8d), U64_C (0xd119196419c87d32),
-    U64_C (0x3b49493949727092), U64_C (0x5fd9d943d9869aaf),
-    U64_C (0x31f2f2eff2c31df9), U64_C (0xa8e3e3abe34b48db),
-    U64_C (0xb95b5b715be22ab6), U64_C (0xbc88881a8834920d),
-    U64_C (0x3e9a9a529aa4c829), U64_C (0x0b262698262dbe4c),
-    U64_C (0xbf3232c8328dfa64), U64_C (0x59b0b0fab0e94a7d),
-    U64_C (0xf2e9e983e91b6acf), U64_C (0x770f0f3c0f78331e),
-    U64_C (0x33d5d573d5e6a6b7), U64_C (0xf480803a8074ba1d),
-    U64_C (0x27bebec2be997c61), U64_C (0xebcdcd13cd26de87),
-    U64_C (0x893434d034bde468), U64_C (0x3248483d487a7590),
-    U64_C (0x54ffffdbffab24e3), U64_C (0x8d7a7af57af78ff4),
-    U64_C (0x6490907a90f4ea3d), U64_C (0x9d5f5f615fc23ebe),
-    U64_C (0x3d202080201da040), U64_C (0x0f6868bd6867d5d0),
-    U64_C (0xca1a1a681ad07234), U64_C (0xb7aeae82ae192c41),
-    U64_C (0x7db4b4eab4c95e75), U64_C (0xce54544d549a19a8),
-    U64_C (0x7f93937693ece53b), U64_C (0x2f222288220daa44),
-    U64_C (0x6364648d6407e9c8), U64_C (0x2af1f1e3f1db12ff),
-    U64_C (0xcc7373d173bfa2e6), U64_C (0x8212124812905a24),
-    U64_C (0x7a40401d403a5d80), U64_C (0x4808082008402810),
-    U64_C (0x95c3c32bc356e89b), U64_C (0xdfecec97ec337bc5),
-    U64_C (0x4ddbdb4bdb9690ab), U64_C (0xc0a1a1bea1611f5f),
-    U64_C (0x918d8d0e8d1c8307), U64_C (0xc83d3df43df5c97a),
-    U64_C (0x5b97976697ccf133), U64_C (0x0000000000000000),
-    U64_C (0xf9cfcf1bcf36d483), U64_C (0x6e2b2bac2b458756),
-    U64_C (0xe17676c57697b3ec), U64_C (0xe68282328264b019),
-    U64_C (0x28d6d67fd6fea9b1), U64_C (0xc31b1b6c1bd87736),
-    U64_C (0x74b5b5eeb5c15b77), U64_C (0xbeafaf86af112943),
-    U64_C (0x1d6a6ab56a77dfd4), U64_C (0xea50505d50ba0da0),
-    U64_C (0x5745450945124c8a), U64_C (0x38f3f3ebf3cb18fb),
-    U64_C (0xad3030c0309df060), U64_C (0xc4efef9bef2b74c3),
-    U64_C (0xda3f3ffc3fe5c37e), U64_C (0xc755554955921caa),
-    U64_C (0xdba2a2b2a2791059), U64_C (0xe9eaea8fea0365c9),
-    U64_C (0x6a656589650fecca), U64_C (0x03babad2bab96869),
-    U64_C (0x4a2f2fbc2f65935e), U64_C (0x8ec0c027c04ee79d),
-    U64_C (0x60dede5fdebe81a1), U64_C (0xfc1c1c701ce06c38),
-    U64_C (0x46fdfdd3fdbb2ee7), U64_C (0x1f4d4d294d52649a),
-    U64_C (0x7692927292e4e039), U64_C (0xfa7575c9758fbcea),
-    U64_C (0x3606061806301e0c), U64_C (0xae8a8a128a249809),
-    U64_C (0x4bb2b2f2b2f94079), U64_C (0x85e6e6bfe66359d1),
-    U64_C (0x7e0e0e380e70361c), U64_C (0xe71f1f7c1ff8633e),
-    U64_C (0x556262956237f7c4), U64_C (0x3ad4d477d4eea3b5),
-    U64_C (0x81a8a89aa829324d), U64_C (0x5296966296c4f431),
-    U64_C (0x62f9f9c3f99b3aef), U64_C (0xa3c5c533c566f697),
-    U64_C (0x102525942535b14a), U64_C (0xab59597959f220b2),
-    U64_C (0xd084842a8454ae15), U64_C (0xc57272d572b7a7e4),
-    U64_C (0xec3939e439d5dd72), U64_C (0x164c4c2d4c5a6198),
-    U64_C (0x945e5e655eca3bbc), U64_C (0x9f7878fd78e785f0),
-    U64_C (0xe53838e038ddd870), U64_C (0x988c8c0a8c148605),
-    U64_C (0x17d1d163d1c6b2bf), U64_C (0xe4a5a5aea5410b57),
-    U64_C (0xa1e2e2afe2434dd9), U64_C (0x4e616199612ff8c2),
-    U64_C (0x42b3b3f6b3f1457b), U64_C (0x342121842115a542),
-    U64_C (0x089c9c4a9c94d625), U64_C (0xee1e1e781ef0663c),
-    U64_C (0x6143431143225286), U64_C (0xb1c7c73bc776fc93),
-    U64_C (0x4ffcfcd7fcb32be5), U64_C (0x2404041004201408),
-    U64_C (0xe351515951b208a2), U64_C (0x2599995e99bcc72f),
-    U64_C (0x226d6da96d4fc4da), U64_C (0x650d0d340d68391a),
-    U64_C (0x79fafacffa8335e9), U64_C (0x69dfdf5bdfb684a3),
-    U64_C (0xa97e7ee57ed79bfc), U64_C (0x19242490243db448),
-    U64_C (0xfe3b3bec3bc5d776), U64_C (0x9aabab96ab313d4b),
-    U64_C (0xf0cece1fce3ed181), U64_C (0x9911114411885522),
-    U64_C (0x838f8f068f0c8903), U64_C (0x044e4e254e4a6b9c),
-    U64_C (0x66b7b7e6b7d15173), U64_C (0xe0ebeb8beb0b60cb),
-    U64_C (0xc13c3cf03cfdcc78), U64_C (0xfd81813e817cbf1f),
-    U64_C (0x4094946a94d4fe35), U64_C (0x1cf7f7fbf7eb0cf3),
-    U64_C (0x18b9b9deb9a1676f), U64_C (0x8b13134c13985f26),
-    U64_C (0x512c2cb02c7d9c58), U64_C (0x05d3d36bd3d6b8bb),
-    U64_C (0x8ce7e7bbe76b5cd3), U64_C (0x396e6ea56e57cbdc),
-    U64_C (0xaac4c437c46ef395), U64_C (0x1b03030c03180f06),
-    U64_C (0xdc565645568a13ac), U64_C (0x5e44440d441a4988),
-    U64_C (0xa07f7fe17fdf9efe), U64_C (0x88a9a99ea921374f),
-    U64_C (0x672a2aa82a4d8254), U64_C (0x0abbbbd6bbb16d6b),
-    U64_C (0x87c1c123c146e29f), U64_C (0xf153535153a202a6),
-    U64_C (0x72dcdc57dcae8ba5), U64_C (0x530b0b2c0b582716),
-    U64_C (0x019d9d4e9d9cd327), U64_C (0x2b6c6cad6c47c1d8),
-    U64_C (0xa43131c43195f562), U64_C (0xf37474cd7487b9e8),
-    U64_C (0x15f6f6fff6e309f1), U64_C (0x4c464605460a438c),
-    U64_C (0xa5acac8aac092645), U64_C (0xb589891e893c970f),
-    U64_C (0xb414145014a04428), U64_C (0xbae1e1a3e15b42df),
-    U64_C (0xa616165816b04e2c), U64_C (0xf73a3ae83acdd274),
-    U64_C (0x066969b9696fd0d2), U64_C (0x4109092409482d12),
-    U64_C (0xd77070dd70a7ade0), U64_C (0x6fb6b6e2b6d95471),
-    U64_C (0x1ed0d067d0ceb7bd), U64_C (0xd6eded93ed3b7ec7),
-    U64_C (0xe2cccc17cc2edb85), U64_C (0x68424215422a5784),
-    U64_C (0x2c98985a98b4c22d), U64_C (0xeda4a4aaa4490e55),
-    U64_C (0x752828a0285d8850), U64_C (0x865c5c6d5cda31b8),
-    U64_C (0x6bf8f8c7f8933fed), U64_C (0xc28686228644a411),
-  };
-
-static const u64 C2[256] =
-  {
-    U64_C (0x30d818186018c078), U64_C (0x462623238c2305af),
-    U64_C (0x91b8c6c63fc67ef9), U64_C (0xcdfbe8e887e8136f),
-    U64_C (0x13cb878726874ca1), U64_C (0x6d11b8b8dab8a962),
-    U64_C (0x0209010104010805), U64_C (0x9e0d4f4f214f426e),
-    U64_C (0x6c9b3636d836adee), U64_C (0x51ffa6a6a2a65904),
-    U64_C (0xb90cd2d26fd2debd), U64_C (0xf70ef5f5f3f5fb06),
-    U64_C (0xf2967979f979ef80), U64_C (0xde306f6fa16f5fce),
-    U64_C (0x3f6d91917e91fcef), U64_C (0xa4f852525552aa07),
-    U64_C (0xc04760609d6027fd), U64_C (0x6535bcbccabc8976),
-    U64_C (0x2b379b9b569baccd), U64_C (0x018a8e8e028e048c),
-    U64_C (0x5bd2a3a3b6a37115), U64_C (0x186c0c0c300c603c),
-    U64_C (0xf6847b7bf17bff8a), U64_C (0x6a803535d435b5e1),
-    U64_C (0x3af51d1d741de869), U64_C (0xddb3e0e0a7e05347),
-    U64_C (0xb321d7d77bd7f6ac), U64_C (0x999cc2c22fc25eed),
-    U64_C (0x5c432e2eb82e6d96), U64_C (0x96294b4b314b627a),
-    U64_C (0xe15dfefedffea321), U64_C (0xaed5575741578216),
-    U64_C (0x2abd15155415a841), U64_C (0xeee87777c1779fb6),
-    U64_C (0x6e923737dc37a5eb), U64_C (0xd79ee5e5b3e57b56),
-    U64_C (0x23139f9f469f8cd9), U64_C (0xfd23f0f0e7f0d317),
-    U64_C (0x94204a4a354a6a7f), U64_C (0xa944dada4fda9e95),
-    U64_C (0xb0a258587d58fa25), U64_C (0x8fcfc9c903c906ca),
-    U64_C (0x527c2929a429558d), U64_C (0x145a0a0a280a5022),
-    U64_C (0x7f50b1b1feb1e14f), U64_C (0x5dc9a0a0baa0691a),
-    U64_C (0xd6146b6bb16b7fda), U64_C (0x17d985852e855cab),
-    U64_C (0x673cbdbdcebd8173), U64_C (0xba8f5d5d695dd234),
-    U64_C (0x2090101040108050), U64_C (0xf507f4f4f7f4f303),
-    U64_C (0x8bddcbcb0bcb16c0), U64_C (0x7cd33e3ef83eedc6),
-    U64_C (0x0a2d050514052811), U64_C (0xce78676781671fe6),
-    U64_C (0xd597e4e4b7e47353), U64_C (0x4e0227279c2725bb),
-    U64_C (0x8273414119413258), U64_C (0x0ba78b8b168b2c9d),
-    U64_C (0x53f6a7a7a6a75101), U64_C (0xfab27d7de97dcf94),
-    U64_C (0x374995956e95dcfb), U64_C (0xad56d8d847d88e9f),
-    U64_C (0xeb70fbfbcbfb8b30), U64_C (0xc1cdeeee9fee2371),
-    U64_C (0xf8bb7c7ced7cc791), U64_C (0xcc716666856617e3),
-    U64_C (0xa77bdddd53dda68e), U64_C (0x2eaf17175c17b84b),
-    U64_C (0x8e45474701470246), U64_C (0x211a9e9e429e84dc),
-    U64_C (0x89d4caca0fca1ec5), U64_C (0x5a582d2db42d7599),
-    U64_C (0x632ebfbfc6bf9179), U64_C (0x0e3f07071c07381b),
-    U64_C (0x47acadad8ead0123), U64_C (0xb4b05a5a755aea2f),
-    U64_C (0x1bef838336836cb5), U64_C (0x66b63333cc3385ff),
-    U64_C (0xc65c636391633ff2), U64_C (0x041202020802100a),
-    U64_C (0x4993aaaa92aa3938), U64_C (0xe2de7171d971afa8),
-    U64_C (0x8dc6c8c807c80ecf), U64_C (0x32d119196419c87d),
-    U64_C (0x923b494939497270), U64_C (0xaf5fd9d943d9869a),
-    U64_C (0xf931f2f2eff2c31d), U64_C (0xdba8e3e3abe34b48),
-    U64_C (0xb6b95b5b715be22a), U64_C (0x0dbc88881a883492),
-    U64_C (0x293e9a9a529aa4c8), U64_C (0x4c0b262698262dbe),
-    U64_C (0x64bf3232c8328dfa), U64_C (0x7d59b0b0fab0e94a),
-    U64_C (0xcff2e9e983e91b6a), U64_C (0x1e770f0f3c0f7833),
-    U64_C (0xb733d5d573d5e6a6), U64_C (0x1df480803a8074ba),
-    U64_C (0x6127bebec2be997c), U64_C (0x87ebcdcd13cd26de),
-    U64_C (0x68893434d034bde4), U64_C (0x903248483d487a75),
-    U64_C (0xe354ffffdbffab24), U64_C (0xf48d7a7af57af78f),
-    U64_C (0x3d6490907a90f4ea), U64_C (0xbe9d5f5f615fc23e),
-    U64_C (0x403d202080201da0), U64_C (0xd00f6868bd6867d5),
-    U64_C (0x34ca1a1a681ad072), U64_C (0x41b7aeae82ae192c),
-    U64_C (0x757db4b4eab4c95e), U64_C (0xa8ce54544d549a19),
-    U64_C (0x3b7f93937693ece5), U64_C (0x442f222288220daa),
-    U64_C (0xc86364648d6407e9), U64_C (0xff2af1f1e3f1db12),
-    U64_C (0xe6cc7373d173bfa2), U64_C (0x248212124812905a),
-    U64_C (0x807a40401d403a5d), U64_C (0x1048080820084028),
-    U64_C (0x9b95c3c32bc356e8), U64_C (0xc5dfecec97ec337b),
-    U64_C (0xab4ddbdb4bdb9690), U64_C (0x5fc0a1a1bea1611f),
-    U64_C (0x07918d8d0e8d1c83), U64_C (0x7ac83d3df43df5c9),
-    U64_C (0x335b97976697ccf1), U64_C (0x0000000000000000),
-    U64_C (0x83f9cfcf1bcf36d4), U64_C (0x566e2b2bac2b4587),
-    U64_C (0xece17676c57697b3), U64_C (0x19e68282328264b0),
-    U64_C (0xb128d6d67fd6fea9), U64_C (0x36c31b1b6c1bd877),
-    U64_C (0x7774b5b5eeb5c15b), U64_C (0x43beafaf86af1129),
-    U64_C (0xd41d6a6ab56a77df), U64_C (0xa0ea50505d50ba0d),
-    U64_C (0x8a5745450945124c), U64_C (0xfb38f3f3ebf3cb18),
-    U64_C (0x60ad3030c0309df0), U64_C (0xc3c4efef9bef2b74),
-    U64_C (0x7eda3f3ffc3fe5c3), U64_C (0xaac755554955921c),
-    U64_C (0x59dba2a2b2a27910), U64_C (0xc9e9eaea8fea0365),
-    U64_C (0xca6a656589650fec), U64_C (0x6903babad2bab968),
-    U64_C (0x5e4a2f2fbc2f6593), U64_C (0x9d8ec0c027c04ee7),
-    U64_C (0xa160dede5fdebe81), U64_C (0x38fc1c1c701ce06c),
-    U64_C (0xe746fdfdd3fdbb2e), U64_C (0x9a1f4d4d294d5264),
-    U64_C (0x397692927292e4e0), U64_C (0xeafa7575c9758fbc),
-    U64_C (0x0c3606061806301e), U64_C (0x09ae8a8a128a2498),
-    U64_C (0x794bb2b2f2b2f940), U64_C (0xd185e6e6bfe66359),
-    U64_C (0x1c7e0e0e380e7036), U64_C (0x3ee71f1f7c1ff863),
-    U64_C (0xc4556262956237f7), U64_C (0xb53ad4d477d4eea3),
-    U64_C (0x4d81a8a89aa82932), U64_C (0x315296966296c4f4),
-    U64_C (0xef62f9f9c3f99b3a), U64_C (0x97a3c5c533c566f6),
-    U64_C (0x4a102525942535b1), U64_C (0xb2ab59597959f220),
-    U64_C (0x15d084842a8454ae), U64_C (0xe4c57272d572b7a7),
-    U64_C (0x72ec3939e439d5dd), U64_C (0x98164c4c2d4c5a61),
-    U64_C (0xbc945e5e655eca3b), U64_C (0xf09f7878fd78e785),
-    U64_C (0x70e53838e038ddd8), U64_C (0x05988c8c0a8c1486),
-    U64_C (0xbf17d1d163d1c6b2), U64_C (0x57e4a5a5aea5410b),
-    U64_C (0xd9a1e2e2afe2434d), U64_C (0xc24e616199612ff8),
-    U64_C (0x7b42b3b3f6b3f145), U64_C (0x42342121842115a5),
-    U64_C (0x25089c9c4a9c94d6), U64_C (0x3cee1e1e781ef066),
-    U64_C (0x8661434311432252), U64_C (0x93b1c7c73bc776fc),
-    U64_C (0xe54ffcfcd7fcb32b), U64_C (0x0824040410042014),
-    U64_C (0xa2e351515951b208), U64_C (0x2f2599995e99bcc7),
-    U64_C (0xda226d6da96d4fc4), U64_C (0x1a650d0d340d6839),
-    U64_C (0xe979fafacffa8335), U64_C (0xa369dfdf5bdfb684),
-    U64_C (0xfca97e7ee57ed79b), U64_C (0x4819242490243db4),
-    U64_C (0x76fe3b3bec3bc5d7), U64_C (0x4b9aabab96ab313d),
-    U64_C (0x81f0cece1fce3ed1), U64_C (0x2299111144118855),
-    U64_C (0x03838f8f068f0c89), U64_C (0x9c044e4e254e4a6b),
-    U64_C (0x7366b7b7e6b7d151), U64_C (0xcbe0ebeb8beb0b60),
-    U64_C (0x78c13c3cf03cfdcc), U64_C (0x1ffd81813e817cbf),
-    U64_C (0x354094946a94d4fe), U64_C (0xf31cf7f7fbf7eb0c),
-    U64_C (0x6f18b9b9deb9a167), U64_C (0x268b13134c13985f),
-    U64_C (0x58512c2cb02c7d9c), U64_C (0xbb05d3d36bd3d6b8),
-    U64_C (0xd38ce7e7bbe76b5c), U64_C (0xdc396e6ea56e57cb),
-    U64_C (0x95aac4c437c46ef3), U64_C (0x061b03030c03180f),
-    U64_C (0xacdc565645568a13), U64_C (0x885e44440d441a49),
-    U64_C (0xfea07f7fe17fdf9e), U64_C (0x4f88a9a99ea92137),
-    U64_C (0x54672a2aa82a4d82), U64_C (0x6b0abbbbd6bbb16d),
-    U64_C (0x9f87c1c123c146e2), U64_C (0xa6f153535153a202),
-    U64_C (0xa572dcdc57dcae8b), U64_C (0x16530b0b2c0b5827),
-    U64_C (0x27019d9d4e9d9cd3), U64_C (0xd82b6c6cad6c47c1),
-    U64_C (0x62a43131c43195f5), U64_C (0xe8f37474cd7487b9),
-    U64_C (0xf115f6f6fff6e309), U64_C (0x8c4c464605460a43),
-    U64_C (0x45a5acac8aac0926), U64_C (0x0fb589891e893c97),
-    U64_C (0x28b414145014a044), U64_C (0xdfbae1e1a3e15b42),
-    U64_C (0x2ca616165816b04e), U64_C (0x74f73a3ae83acdd2),
-    U64_C (0xd2066969b9696fd0), U64_C (0x124109092409482d),
-    U64_C (0xe0d77070dd70a7ad), U64_C (0x716fb6b6e2b6d954),
-    U64_C (0xbd1ed0d067d0ceb7), U64_C (0xc7d6eded93ed3b7e),
-    U64_C (0x85e2cccc17cc2edb), U64_C (0x8468424215422a57),
-    U64_C (0x2d2c98985a98b4c2), U64_C (0x55eda4a4aaa4490e),
-    U64_C (0x50752828a0285d88), U64_C (0xb8865c5c6d5cda31),
-    U64_C (0xed6bf8f8c7f8933f), U64_C (0x11c28686228644a4),
-  };
-
-static const u64 C3[256] =
-  {
-    U64_C (0x7830d818186018c0), U64_C (0xaf462623238c2305),
-    U64_C (0xf991b8c6c63fc67e), U64_C (0x6fcdfbe8e887e813),
-    U64_C (0xa113cb878726874c), U64_C (0x626d11b8b8dab8a9),
-    U64_C (0x0502090101040108), U64_C (0x6e9e0d4f4f214f42),
-    U64_C (0xee6c9b3636d836ad), U64_C (0x0451ffa6a6a2a659),
-    U64_C (0xbdb90cd2d26fd2de), U64_C (0x06f70ef5f5f3f5fb),
-    U64_C (0x80f2967979f979ef), U64_C (0xcede306f6fa16f5f),
-    U64_C (0xef3f6d91917e91fc), U64_C (0x07a4f852525552aa),
-    U64_C (0xfdc04760609d6027), U64_C (0x766535bcbccabc89),
-    U64_C (0xcd2b379b9b569bac), U64_C (0x8c018a8e8e028e04),
-    U64_C (0x155bd2a3a3b6a371), U64_C (0x3c186c0c0c300c60),
-    U64_C (0x8af6847b7bf17bff), U64_C (0xe16a803535d435b5),
-    U64_C (0x693af51d1d741de8), U64_C (0x47ddb3e0e0a7e053),
-    U64_C (0xacb321d7d77bd7f6), U64_C (0xed999cc2c22fc25e),
-    U64_C (0x965c432e2eb82e6d), U64_C (0x7a96294b4b314b62),
-    U64_C (0x21e15dfefedffea3), U64_C (0x16aed55757415782),
-    U64_C (0x412abd15155415a8), U64_C (0xb6eee87777c1779f),
-    U64_C (0xeb6e923737dc37a5), U64_C (0x56d79ee5e5b3e57b),
-    U64_C (0xd923139f9f469f8c), U64_C (0x17fd23f0f0e7f0d3),
-    U64_C (0x7f94204a4a354a6a), U64_C (0x95a944dada4fda9e),
-    U64_C (0x25b0a258587d58fa), U64_C (0xca8fcfc9c903c906),
-    U64_C (0x8d527c2929a42955), U64_C (0x22145a0a0a280a50),
-    U64_C (0x4f7f50b1b1feb1e1), U64_C (0x1a5dc9a0a0baa069),
-    U64_C (0xdad6146b6bb16b7f), U64_C (0xab17d985852e855c),
-    U64_C (0x73673cbdbdcebd81), U64_C (0x34ba8f5d5d695dd2),
-    U64_C (0x5020901010401080), U64_C (0x03f507f4f4f7f4f3),
-    U64_C (0xc08bddcbcb0bcb16), U64_C (0xc67cd33e3ef83eed),
-    U64_C (0x110a2d0505140528), U64_C (0xe6ce78676781671f),
-    U64_C (0x53d597e4e4b7e473), U64_C (0xbb4e0227279c2725),
-    U64_C (0x5882734141194132), U64_C (0x9d0ba78b8b168b2c),
-    U64_C (0x0153f6a7a7a6a751), U64_C (0x94fab27d7de97dcf),
-    U64_C (0xfb374995956e95dc), U64_C (0x9fad56d8d847d88e),
-    U64_C (0x30eb70fbfbcbfb8b), U64_C (0x71c1cdeeee9fee23),
-    U64_C (0x91f8bb7c7ced7cc7), U64_C (0xe3cc716666856617),
-    U64_C (0x8ea77bdddd53dda6), U64_C (0x4b2eaf17175c17b8),
-    U64_C (0x468e454747014702), U64_C (0xdc211a9e9e429e84),
-    U64_C (0xc589d4caca0fca1e), U64_C (0x995a582d2db42d75),
-    U64_C (0x79632ebfbfc6bf91), U64_C (0x1b0e3f07071c0738),
-    U64_C (0x2347acadad8ead01), U64_C (0x2fb4b05a5a755aea),
-    U64_C (0xb51bef838336836c), U64_C (0xff66b63333cc3385),
-    U64_C (0xf2c65c636391633f), U64_C (0x0a04120202080210),
-    U64_C (0x384993aaaa92aa39), U64_C (0xa8e2de7171d971af),
-    U64_C (0xcf8dc6c8c807c80e), U64_C (0x7d32d119196419c8),
-    U64_C (0x70923b4949394972), U64_C (0x9aaf5fd9d943d986),
-    U64_C (0x1df931f2f2eff2c3), U64_C (0x48dba8e3e3abe34b),
-    U64_C (0x2ab6b95b5b715be2), U64_C (0x920dbc88881a8834),
-    U64_C (0xc8293e9a9a529aa4), U64_C (0xbe4c0b262698262d),
-    U64_C (0xfa64bf3232c8328d), U64_C (0x4a7d59b0b0fab0e9),
-    U64_C (0x6acff2e9e983e91b), U64_C (0x331e770f0f3c0f78),
-    U64_C (0xa6b733d5d573d5e6), U64_C (0xba1df480803a8074),
-    U64_C (0x7c6127bebec2be99), U64_C (0xde87ebcdcd13cd26),
-    U64_C (0xe468893434d034bd), U64_C (0x75903248483d487a),
-    U64_C (0x24e354ffffdbffab), U64_C (0x8ff48d7a7af57af7),
-    U64_C (0xea3d6490907a90f4), U64_C (0x3ebe9d5f5f615fc2),
-    U64_C (0xa0403d202080201d), U64_C (0xd5d00f6868bd6867),
-    U64_C (0x7234ca1a1a681ad0), U64_C (0x2c41b7aeae82ae19),
-    U64_C (0x5e757db4b4eab4c9), U64_C (0x19a8ce54544d549a),
-    U64_C (0xe53b7f93937693ec), U64_C (0xaa442f222288220d),
-    U64_C (0xe9c86364648d6407), U64_C (0x12ff2af1f1e3f1db),
-    U64_C (0xa2e6cc7373d173bf), U64_C (0x5a24821212481290),
-    U64_C (0x5d807a40401d403a), U64_C (0x2810480808200840),
-    U64_C (0xe89b95c3c32bc356), U64_C (0x7bc5dfecec97ec33),
-    U64_C (0x90ab4ddbdb4bdb96), U64_C (0x1f5fc0a1a1bea161),
-    U64_C (0x8307918d8d0e8d1c), U64_C (0xc97ac83d3df43df5),
-    U64_C (0xf1335b97976697cc), U64_C (0x0000000000000000),
-    U64_C (0xd483f9cfcf1bcf36), U64_C (0x87566e2b2bac2b45),
-    U64_C (0xb3ece17676c57697), U64_C (0xb019e68282328264),
-    U64_C (0xa9b128d6d67fd6fe), U64_C (0x7736c31b1b6c1bd8),
-    U64_C (0x5b7774b5b5eeb5c1), U64_C (0x2943beafaf86af11),
-    U64_C (0xdfd41d6a6ab56a77), U64_C (0x0da0ea50505d50ba),
-    U64_C (0x4c8a574545094512), U64_C (0x18fb38f3f3ebf3cb),
-    U64_C (0xf060ad3030c0309d), U64_C (0x74c3c4efef9bef2b),
-    U64_C (0xc37eda3f3ffc3fe5), U64_C (0x1caac75555495592),
-    U64_C (0x1059dba2a2b2a279), U64_C (0x65c9e9eaea8fea03),
-    U64_C (0xecca6a656589650f), U64_C (0x686903babad2bab9),
-    U64_C (0x935e4a2f2fbc2f65), U64_C (0xe79d8ec0c027c04e),
-    U64_C (0x81a160dede5fdebe), U64_C (0x6c38fc1c1c701ce0),
-    U64_C (0x2ee746fdfdd3fdbb), U64_C (0x649a1f4d4d294d52),
-    U64_C (0xe0397692927292e4), U64_C (0xbceafa7575c9758f),
-    U64_C (0x1e0c360606180630), U64_C (0x9809ae8a8a128a24),
-    U64_C (0x40794bb2b2f2b2f9), U64_C (0x59d185e6e6bfe663),
-    U64_C (0x361c7e0e0e380e70), U64_C (0x633ee71f1f7c1ff8),
-    U64_C (0xf7c4556262956237), U64_C (0xa3b53ad4d477d4ee),
-    U64_C (0x324d81a8a89aa829), U64_C (0xf4315296966296c4),
-    U64_C (0x3aef62f9f9c3f99b), U64_C (0xf697a3c5c533c566),
-    U64_C (0xb14a102525942535), U64_C (0x20b2ab59597959f2),
-    U64_C (0xae15d084842a8454), U64_C (0xa7e4c57272d572b7),
-    U64_C (0xdd72ec3939e439d5), U64_C (0x6198164c4c2d4c5a),
-    U64_C (0x3bbc945e5e655eca), U64_C (0x85f09f7878fd78e7),
-    U64_C (0xd870e53838e038dd), U64_C (0x8605988c8c0a8c14),
-    U64_C (0xb2bf17d1d163d1c6), U64_C (0x0b57e4a5a5aea541),
-    U64_C (0x4dd9a1e2e2afe243), U64_C (0xf8c24e616199612f),
-    U64_C (0x457b42b3b3f6b3f1), U64_C (0xa542342121842115),
-    U64_C (0xd625089c9c4a9c94), U64_C (0x663cee1e1e781ef0),
-    U64_C (0x5286614343114322), U64_C (0xfc93b1c7c73bc776),
-    U64_C (0x2be54ffcfcd7fcb3), U64_C (0x1408240404100420),
-    U64_C (0x08a2e351515951b2), U64_C (0xc72f2599995e99bc),
-    U64_C (0xc4da226d6da96d4f), U64_C (0x391a650d0d340d68),
-    U64_C (0x35e979fafacffa83), U64_C (0x84a369dfdf5bdfb6),
-    U64_C (0x9bfca97e7ee57ed7), U64_C (0xb44819242490243d),
-    U64_C (0xd776fe3b3bec3bc5), U64_C (0x3d4b9aabab96ab31),
-    U64_C (0xd181f0cece1fce3e), U64_C (0x5522991111441188),
-    U64_C (0x8903838f8f068f0c), U64_C (0x6b9c044e4e254e4a),
-    U64_C (0x517366b7b7e6b7d1), U64_C (0x60cbe0ebeb8beb0b),
-    U64_C (0xcc78c13c3cf03cfd), U64_C (0xbf1ffd81813e817c),
-    U64_C (0xfe354094946a94d4), U64_C (0x0cf31cf7f7fbf7eb),
-    U64_C (0x676f18b9b9deb9a1), U64_C (0x5f268b13134c1398),
-    U64_C (0x9c58512c2cb02c7d), U64_C (0xb8bb05d3d36bd3d6),
-    U64_C (0x5cd38ce7e7bbe76b), U64_C (0xcbdc396e6ea56e57),
-    U64_C (0xf395aac4c437c46e), U64_C (0x0f061b03030c0318),
-    U64_C (0x13acdc565645568a), U64_C (0x49885e44440d441a),
-    U64_C (0x9efea07f7fe17fdf), U64_C (0x374f88a9a99ea921),
-    U64_C (0x8254672a2aa82a4d), U64_C (0x6d6b0abbbbd6bbb1),
-    U64_C (0xe29f87c1c123c146), U64_C (0x02a6f153535153a2),
-    U64_C (0x8ba572dcdc57dcae), U64_C (0x2716530b0b2c0b58),
-    U64_C (0xd327019d9d4e9d9c), U64_C (0xc1d82b6c6cad6c47),
-    U64_C (0xf562a43131c43195), U64_C (0xb9e8f37474cd7487),
-    U64_C (0x09f115f6f6fff6e3), U64_C (0x438c4c464605460a),
-    U64_C (0x2645a5acac8aac09), U64_C (0x970fb589891e893c),
-    U64_C (0x4428b414145014a0), U64_C (0x42dfbae1e1a3e15b),
-    U64_C (0x4e2ca616165816b0), U64_C (0xd274f73a3ae83acd),
-    U64_C (0xd0d2066969b9696f), U64_C (0x2d12410909240948),
-    U64_C (0xade0d77070dd70a7), U64_C (0x54716fb6b6e2b6d9),
-    U64_C (0xb7bd1ed0d067d0ce), U64_C (0x7ec7d6eded93ed3b),
-    U64_C (0xdb85e2cccc17cc2e), U64_C (0x578468424215422a),
-    U64_C (0xc22d2c98985a98b4), U64_C (0x0e55eda4a4aaa449),
-    U64_C (0x8850752828a0285d), U64_C (0x31b8865c5c6d5cda),
-    U64_C (0x3fed6bf8f8c7f893), U64_C (0xa411c28686228644),
-  };
-
-static const u64 C4[256] =
-  {
-    U64_C (0xc07830d818186018), U64_C (0x05af462623238c23),
-    U64_C (0x7ef991b8c6c63fc6), U64_C (0x136fcdfbe8e887e8),
-    U64_C (0x4ca113cb87872687), U64_C (0xa9626d11b8b8dab8),
-    U64_C (0x0805020901010401), U64_C (0x426e9e0d4f4f214f),
-    U64_C (0xadee6c9b3636d836), U64_C (0x590451ffa6a6a2a6),
-    U64_C (0xdebdb90cd2d26fd2), U64_C (0xfb06f70ef5f5f3f5),
-    U64_C (0xef80f2967979f979), U64_C (0x5fcede306f6fa16f),
-    U64_C (0xfcef3f6d91917e91), U64_C (0xaa07a4f852525552),
-    U64_C (0x27fdc04760609d60), U64_C (0x89766535bcbccabc),
-    U64_C (0xaccd2b379b9b569b), U64_C (0x048c018a8e8e028e),
-    U64_C (0x71155bd2a3a3b6a3), U64_C (0x603c186c0c0c300c),
-    U64_C (0xff8af6847b7bf17b), U64_C (0xb5e16a803535d435),
-    U64_C (0xe8693af51d1d741d), U64_C (0x5347ddb3e0e0a7e0),
-    U64_C (0xf6acb321d7d77bd7), U64_C (0x5eed999cc2c22fc2),
-    U64_C (0x6d965c432e2eb82e), U64_C (0x627a96294b4b314b),
-    U64_C (0xa321e15dfefedffe), U64_C (0x8216aed557574157),
-    U64_C (0xa8412abd15155415), U64_C (0x9fb6eee87777c177),
-    U64_C (0xa5eb6e923737dc37), U64_C (0x7b56d79ee5e5b3e5),
-    U64_C (0x8cd923139f9f469f), U64_C (0xd317fd23f0f0e7f0),
-    U64_C (0x6a7f94204a4a354a), U64_C (0x9e95a944dada4fda),
-    U64_C (0xfa25b0a258587d58), U64_C (0x06ca8fcfc9c903c9),
-    U64_C (0x558d527c2929a429), U64_C (0x5022145a0a0a280a),
-    U64_C (0xe14f7f50b1b1feb1), U64_C (0x691a5dc9a0a0baa0),
-    U64_C (0x7fdad6146b6bb16b), U64_C (0x5cab17d985852e85),
-    U64_C (0x8173673cbdbdcebd), U64_C (0xd234ba8f5d5d695d),
-    U64_C (0x8050209010104010), U64_C (0xf303f507f4f4f7f4),
-    U64_C (0x16c08bddcbcb0bcb), U64_C (0xedc67cd33e3ef83e),
-    U64_C (0x28110a2d05051405), U64_C (0x1fe6ce7867678167),
-    U64_C (0x7353d597e4e4b7e4), U64_C (0x25bb4e0227279c27),
-    U64_C (0x3258827341411941), U64_C (0x2c9d0ba78b8b168b),
-    U64_C (0x510153f6a7a7a6a7), U64_C (0xcf94fab27d7de97d),
-    U64_C (0xdcfb374995956e95), U64_C (0x8e9fad56d8d847d8),
-    U64_C (0x8b30eb70fbfbcbfb), U64_C (0x2371c1cdeeee9fee),
-    U64_C (0xc791f8bb7c7ced7c), U64_C (0x17e3cc7166668566),
-    U64_C (0xa68ea77bdddd53dd), U64_C (0xb84b2eaf17175c17),
-    U64_C (0x02468e4547470147), U64_C (0x84dc211a9e9e429e),
-    U64_C (0x1ec589d4caca0fca), U64_C (0x75995a582d2db42d),
-    U64_C (0x9179632ebfbfc6bf), U64_C (0x381b0e3f07071c07),
-    U64_C (0x012347acadad8ead), U64_C (0xea2fb4b05a5a755a),
-    U64_C (0x6cb51bef83833683), U64_C (0x85ff66b63333cc33),
-    U64_C (0x3ff2c65c63639163), U64_C (0x100a041202020802),
-    U64_C (0x39384993aaaa92aa), U64_C (0xafa8e2de7171d971),
-    U64_C (0x0ecf8dc6c8c807c8), U64_C (0xc87d32d119196419),
-    U64_C (0x7270923b49493949), U64_C (0x869aaf5fd9d943d9),
-    U64_C (0xc31df931f2f2eff2), U64_C (0x4b48dba8e3e3abe3),
-    U64_C (0xe22ab6b95b5b715b), U64_C (0x34920dbc88881a88),
-    U64_C (0xa4c8293e9a9a529a), U64_C (0x2dbe4c0b26269826),
-    U64_C (0x8dfa64bf3232c832), U64_C (0xe94a7d59b0b0fab0),
-    U64_C (0x1b6acff2e9e983e9), U64_C (0x78331e770f0f3c0f),
-    U64_C (0xe6a6b733d5d573d5), U64_C (0x74ba1df480803a80),
-    U64_C (0x997c6127bebec2be), U64_C (0x26de87ebcdcd13cd),
-    U64_C (0xbde468893434d034), U64_C (0x7a75903248483d48),
-    U64_C (0xab24e354ffffdbff), U64_C (0xf78ff48d7a7af57a),
-    U64_C (0xf4ea3d6490907a90), U64_C (0xc23ebe9d5f5f615f),
-    U64_C (0x1da0403d20208020), U64_C (0x67d5d00f6868bd68),
-    U64_C (0xd07234ca1a1a681a), U64_C (0x192c41b7aeae82ae),
-    U64_C (0xc95e757db4b4eab4), U64_C (0x9a19a8ce54544d54),
-    U64_C (0xece53b7f93937693), U64_C (0x0daa442f22228822),
-    U64_C (0x07e9c86364648d64), U64_C (0xdb12ff2af1f1e3f1),
-    U64_C (0xbfa2e6cc7373d173), U64_C (0x905a248212124812),
-    U64_C (0x3a5d807a40401d40), U64_C (0x4028104808082008),
-    U64_C (0x56e89b95c3c32bc3), U64_C (0x337bc5dfecec97ec),
-    U64_C (0x9690ab4ddbdb4bdb), U64_C (0x611f5fc0a1a1bea1),
-    U64_C (0x1c8307918d8d0e8d), U64_C (0xf5c97ac83d3df43d),
-    U64_C (0xccf1335b97976697), U64_C (0x0000000000000000),
-    U64_C (0x36d483f9cfcf1bcf), U64_C (0x4587566e2b2bac2b),
-    U64_C (0x97b3ece17676c576), U64_C (0x64b019e682823282),
-    U64_C (0xfea9b128d6d67fd6), U64_C (0xd87736c31b1b6c1b),
-    U64_C (0xc15b7774b5b5eeb5), U64_C (0x112943beafaf86af),
-    U64_C (0x77dfd41d6a6ab56a), U64_C (0xba0da0ea50505d50),
-    U64_C (0x124c8a5745450945), U64_C (0xcb18fb38f3f3ebf3),
-    U64_C (0x9df060ad3030c030), U64_C (0x2b74c3c4efef9bef),
-    U64_C (0xe5c37eda3f3ffc3f), U64_C (0x921caac755554955),
-    U64_C (0x791059dba2a2b2a2), U64_C (0x0365c9e9eaea8fea),
-    U64_C (0x0fecca6a65658965), U64_C (0xb9686903babad2ba),
-    U64_C (0x65935e4a2f2fbc2f), U64_C (0x4ee79d8ec0c027c0),
-    U64_C (0xbe81a160dede5fde), U64_C (0xe06c38fc1c1c701c),
-    U64_C (0xbb2ee746fdfdd3fd), U64_C (0x52649a1f4d4d294d),
-    U64_C (0xe4e0397692927292), U64_C (0x8fbceafa7575c975),
-    U64_C (0x301e0c3606061806), U64_C (0x249809ae8a8a128a),
-    U64_C (0xf940794bb2b2f2b2), U64_C (0x6359d185e6e6bfe6),
-    U64_C (0x70361c7e0e0e380e), U64_C (0xf8633ee71f1f7c1f),
-    U64_C (0x37f7c45562629562), U64_C (0xeea3b53ad4d477d4),
-    U64_C (0x29324d81a8a89aa8), U64_C (0xc4f4315296966296),
-    U64_C (0x9b3aef62f9f9c3f9), U64_C (0x66f697a3c5c533c5),
-    U64_C (0x35b14a1025259425), U64_C (0xf220b2ab59597959),
-    U64_C (0x54ae15d084842a84), U64_C (0xb7a7e4c57272d572),
-    U64_C (0xd5dd72ec3939e439), U64_C (0x5a6198164c4c2d4c),
-    U64_C (0xca3bbc945e5e655e), U64_C (0xe785f09f7878fd78),
-    U64_C (0xddd870e53838e038), U64_C (0x148605988c8c0a8c),
-    U64_C (0xc6b2bf17d1d163d1), U64_C (0x410b57e4a5a5aea5),
-    U64_C (0x434dd9a1e2e2afe2), U64_C (0x2ff8c24e61619961),
-    U64_C (0xf1457b42b3b3f6b3), U64_C (0x15a5423421218421),
-    U64_C (0x94d625089c9c4a9c), U64_C (0xf0663cee1e1e781e),
-    U64_C (0x2252866143431143), U64_C (0x76fc93b1c7c73bc7),
-    U64_C (0xb32be54ffcfcd7fc), U64_C (0x2014082404041004),
-    U64_C (0xb208a2e351515951), U64_C (0xbcc72f2599995e99),
-    U64_C (0x4fc4da226d6da96d), U64_C (0x68391a650d0d340d),
-    U64_C (0x8335e979fafacffa), U64_C (0xb684a369dfdf5bdf),
-    U64_C (0xd79bfca97e7ee57e), U64_C (0x3db4481924249024),
-    U64_C (0xc5d776fe3b3bec3b), U64_C (0x313d4b9aabab96ab),
-    U64_C (0x3ed181f0cece1fce), U64_C (0x8855229911114411),
-    U64_C (0x0c8903838f8f068f), U64_C (0x4a6b9c044e4e254e),
-    U64_C (0xd1517366b7b7e6b7), U64_C (0x0b60cbe0ebeb8beb),
-    U64_C (0xfdcc78c13c3cf03c), U64_C (0x7cbf1ffd81813e81),
-    U64_C (0xd4fe354094946a94), U64_C (0xeb0cf31cf7f7fbf7),
-    U64_C (0xa1676f18b9b9deb9), U64_C (0x985f268b13134c13),
-    U64_C (0x7d9c58512c2cb02c), U64_C (0xd6b8bb05d3d36bd3),
-    U64_C (0x6b5cd38ce7e7bbe7), U64_C (0x57cbdc396e6ea56e),
-    U64_C (0x6ef395aac4c437c4), U64_C (0x180f061b03030c03),
-    U64_C (0x8a13acdc56564556), U64_C (0x1a49885e44440d44),
-    U64_C (0xdf9efea07f7fe17f), U64_C (0x21374f88a9a99ea9),
-    U64_C (0x4d8254672a2aa82a), U64_C (0xb16d6b0abbbbd6bb),
-    U64_C (0x46e29f87c1c123c1), U64_C (0xa202a6f153535153),
-    U64_C (0xae8ba572dcdc57dc), U64_C (0x582716530b0b2c0b),
-    U64_C (0x9cd327019d9d4e9d), U64_C (0x47c1d82b6c6cad6c),
-    U64_C (0x95f562a43131c431), U64_C (0x87b9e8f37474cd74),
-    U64_C (0xe309f115f6f6fff6), U64_C (0x0a438c4c46460546),
-    U64_C (0x092645a5acac8aac), U64_C (0x3c970fb589891e89),
-    U64_C (0xa04428b414145014), U64_C (0x5b42dfbae1e1a3e1),
-    U64_C (0xb04e2ca616165816), U64_C (0xcdd274f73a3ae83a),
-    U64_C (0x6fd0d2066969b969), U64_C (0x482d124109092409),
-    U64_C (0xa7ade0d77070dd70), U64_C (0xd954716fb6b6e2b6),
-    U64_C (0xceb7bd1ed0d067d0), U64_C (0x3b7ec7d6eded93ed),
-    U64_C (0x2edb85e2cccc17cc), U64_C (0x2a57846842421542),
-    U64_C (0xb4c22d2c98985a98), U64_C (0x490e55eda4a4aaa4),
-    U64_C (0x5d8850752828a028), U64_C (0xda31b8865c5c6d5c),
-    U64_C (0x933fed6bf8f8c7f8), U64_C (0x44a411c286862286),
-  };
-
-static const u64 C5[256] =
-  {
-    U64_C (0x18c07830d8181860), U64_C (0x2305af462623238c),
-    U64_C (0xc67ef991b8c6c63f), U64_C (0xe8136fcdfbe8e887),
-    U64_C (0x874ca113cb878726), U64_C (0xb8a9626d11b8b8da),
-    U64_C (0x0108050209010104), U64_C (0x4f426e9e0d4f4f21),
-    U64_C (0x36adee6c9b3636d8), U64_C (0xa6590451ffa6a6a2),
-    U64_C (0xd2debdb90cd2d26f), U64_C (0xf5fb06f70ef5f5f3),
-    U64_C (0x79ef80f2967979f9), U64_C (0x6f5fcede306f6fa1),
-    U64_C (0x91fcef3f6d91917e), U64_C (0x52aa07a4f8525255),
-    U64_C (0x6027fdc04760609d), U64_C (0xbc89766535bcbcca),
-    U64_C (0x9baccd2b379b9b56), U64_C (0x8e048c018a8e8e02),
-    U64_C (0xa371155bd2a3a3b6), U64_C (0x0c603c186c0c0c30),
-    U64_C (0x7bff8af6847b7bf1), U64_C (0x35b5e16a803535d4),
-    U64_C (0x1de8693af51d1d74), U64_C (0xe05347ddb3e0e0a7),
-    U64_C (0xd7f6acb321d7d77b), U64_C (0xc25eed999cc2c22f),
-    U64_C (0x2e6d965c432e2eb8), U64_C (0x4b627a96294b4b31),
-    U64_C (0xfea321e15dfefedf), U64_C (0x578216aed5575741),
-    U64_C (0x15a8412abd151554), U64_C (0x779fb6eee87777c1),
-    U64_C (0x37a5eb6e923737dc), U64_C (0xe57b56d79ee5e5b3),
-    U64_C (0x9f8cd923139f9f46), U64_C (0xf0d317fd23f0f0e7),
-    U64_C (0x4a6a7f94204a4a35), U64_C (0xda9e95a944dada4f),
-    U64_C (0x58fa25b0a258587d), U64_C (0xc906ca8fcfc9c903),
-    U64_C (0x29558d527c2929a4), U64_C (0x0a5022145a0a0a28),
-    U64_C (0xb1e14f7f50b1b1fe), U64_C (0xa0691a5dc9a0a0ba),
-    U64_C (0x6b7fdad6146b6bb1), U64_C (0x855cab17d985852e),
-    U64_C (0xbd8173673cbdbdce), U64_C (0x5dd234ba8f5d5d69),
-    U64_C (0x1080502090101040), U64_C (0xf4f303f507f4f4f7),
-    U64_C (0xcb16c08bddcbcb0b), U64_C (0x3eedc67cd33e3ef8),
-    U64_C (0x0528110a2d050514), U64_C (0x671fe6ce78676781),
-    U64_C (0xe47353d597e4e4b7), U64_C (0x2725bb4e0227279c),
-    U64_C (0x4132588273414119), U64_C (0x8b2c9d0ba78b8b16),
-    U64_C (0xa7510153f6a7a7a6), U64_C (0x7dcf94fab27d7de9),
-    U64_C (0x95dcfb374995956e), U64_C (0xd88e9fad56d8d847),
-    U64_C (0xfb8b30eb70fbfbcb), U64_C (0xee2371c1cdeeee9f),
-    U64_C (0x7cc791f8bb7c7ced), U64_C (0x6617e3cc71666685),
-    U64_C (0xdda68ea77bdddd53), U64_C (0x17b84b2eaf17175c),
-    U64_C (0x4702468e45474701), U64_C (0x9e84dc211a9e9e42),
-    U64_C (0xca1ec589d4caca0f), U64_C (0x2d75995a582d2db4),
-    U64_C (0xbf9179632ebfbfc6), U64_C (0x07381b0e3f07071c),
-    U64_C (0xad012347acadad8e), U64_C (0x5aea2fb4b05a5a75),
-    U64_C (0x836cb51bef838336), U64_C (0x3385ff66b63333cc),
-    U64_C (0x633ff2c65c636391), U64_C (0x02100a0412020208),
-    U64_C (0xaa39384993aaaa92), U64_C (0x71afa8e2de7171d9),
-    U64_C (0xc80ecf8dc6c8c807), U64_C (0x19c87d32d1191964),
-    U64_C (0x497270923b494939), U64_C (0xd9869aaf5fd9d943),
-    U64_C (0xf2c31df931f2f2ef), U64_C (0xe34b48dba8e3e3ab),
-    U64_C (0x5be22ab6b95b5b71), U64_C (0x8834920dbc88881a),
-    U64_C (0x9aa4c8293e9a9a52), U64_C (0x262dbe4c0b262698),
-    U64_C (0x328dfa64bf3232c8), U64_C (0xb0e94a7d59b0b0fa),
-    U64_C (0xe91b6acff2e9e983), U64_C (0x0f78331e770f0f3c),
-    U64_C (0xd5e6a6b733d5d573), U64_C (0x8074ba1df480803a),
-    U64_C (0xbe997c6127bebec2), U64_C (0xcd26de87ebcdcd13),
-    U64_C (0x34bde468893434d0), U64_C (0x487a75903248483d),
-    U64_C (0xffab24e354ffffdb), U64_C (0x7af78ff48d7a7af5),
-    U64_C (0x90f4ea3d6490907a), U64_C (0x5fc23ebe9d5f5f61),
-    U64_C (0x201da0403d202080), U64_C (0x6867d5d00f6868bd),
-    U64_C (0x1ad07234ca1a1a68), U64_C (0xae192c41b7aeae82),
-    U64_C (0xb4c95e757db4b4ea), U64_C (0x549a19a8ce54544d),
-    U64_C (0x93ece53b7f939376), U64_C (0x220daa442f222288),
-    U64_C (0x6407e9c86364648d), U64_C (0xf1db12ff2af1f1e3),
-    U64_C (0x73bfa2e6cc7373d1), U64_C (0x12905a2482121248),
-    U64_C (0x403a5d807a40401d), U64_C (0x0840281048080820),
-    U64_C (0xc356e89b95c3c32b), U64_C (0xec337bc5dfecec97),
-    U64_C (0xdb9690ab4ddbdb4b), U64_C (0xa1611f5fc0a1a1be),
-    U64_C (0x8d1c8307918d8d0e), U64_C (0x3df5c97ac83d3df4),
-    U64_C (0x97ccf1335b979766), U64_C (0x0000000000000000),
-    U64_C (0xcf36d483f9cfcf1b), U64_C (0x2b4587566e2b2bac),
-    U64_C (0x7697b3ece17676c5), U64_C (0x8264b019e6828232),
-    U64_C (0xd6fea9b128d6d67f), U64_C (0x1bd87736c31b1b6c),
-    U64_C (0xb5c15b7774b5b5ee), U64_C (0xaf112943beafaf86),
-    U64_C (0x6a77dfd41d6a6ab5), U64_C (0x50ba0da0ea50505d),
-    U64_C (0x45124c8a57454509), U64_C (0xf3cb18fb38f3f3eb),
-    U64_C (0x309df060ad3030c0), U64_C (0xef2b74c3c4efef9b),
-    U64_C (0x3fe5c37eda3f3ffc), U64_C (0x55921caac7555549),
-    U64_C (0xa2791059dba2a2b2), U64_C (0xea0365c9e9eaea8f),
-    U64_C (0x650fecca6a656589), U64_C (0xbab9686903babad2),
-    U64_C (0x2f65935e4a2f2fbc), U64_C (0xc04ee79d8ec0c027),
-    U64_C (0xdebe81a160dede5f), U64_C (0x1ce06c38fc1c1c70),
-    U64_C (0xfdbb2ee746fdfdd3), U64_C (0x4d52649a1f4d4d29),
-    U64_C (0x92e4e03976929272), U64_C (0x758fbceafa7575c9),
-    U64_C (0x06301e0c36060618), U64_C (0x8a249809ae8a8a12),
-    U64_C (0xb2f940794bb2b2f2), U64_C (0xe66359d185e6e6bf),
-    U64_C (0x0e70361c7e0e0e38), U64_C (0x1ff8633ee71f1f7c),
-    U64_C (0x6237f7c455626295), U64_C (0xd4eea3b53ad4d477),
-    U64_C (0xa829324d81a8a89a), U64_C (0x96c4f43152969662),
-    U64_C (0xf99b3aef62f9f9c3), U64_C (0xc566f697a3c5c533),
-    U64_C (0x2535b14a10252594), U64_C (0x59f220b2ab595979),
-    U64_C (0x8454ae15d084842a), U64_C (0x72b7a7e4c57272d5),
-    U64_C (0x39d5dd72ec3939e4), U64_C (0x4c5a6198164c4c2d),
-    U64_C (0x5eca3bbc945e5e65), U64_C (0x78e785f09f7878fd),
-    U64_C (0x38ddd870e53838e0), U64_C (0x8c148605988c8c0a),
-    U64_C (0xd1c6b2bf17d1d163), U64_C (0xa5410b57e4a5a5ae),
-    U64_C (0xe2434dd9a1e2e2af), U64_C (0x612ff8c24e616199),
-    U64_C (0xb3f1457b42b3b3f6), U64_C (0x2115a54234212184),
-    U64_C (0x9c94d625089c9c4a), U64_C (0x1ef0663cee1e1e78),
-    U64_C (0x4322528661434311), U64_C (0xc776fc93b1c7c73b),
-    U64_C (0xfcb32be54ffcfcd7), U64_C (0x0420140824040410),
-    U64_C (0x51b208a2e3515159), U64_C (0x99bcc72f2599995e),
-    U64_C (0x6d4fc4da226d6da9), U64_C (0x0d68391a650d0d34),
-    U64_C (0xfa8335e979fafacf), U64_C (0xdfb684a369dfdf5b),
-    U64_C (0x7ed79bfca97e7ee5), U64_C (0x243db44819242490),
-    U64_C (0x3bc5d776fe3b3bec), U64_C (0xab313d4b9aabab96),
-    U64_C (0xce3ed181f0cece1f), U64_C (0x1188552299111144),
-    U64_C (0x8f0c8903838f8f06), U64_C (0x4e4a6b9c044e4e25),
-    U64_C (0xb7d1517366b7b7e6), U64_C (0xeb0b60cbe0ebeb8b),
-    U64_C (0x3cfdcc78c13c3cf0), U64_C (0x817cbf1ffd81813e),
-    U64_C (0x94d4fe354094946a), U64_C (0xf7eb0cf31cf7f7fb),
-    U64_C (0xb9a1676f18b9b9de), U64_C (0x13985f268b13134c),
-    U64_C (0x2c7d9c58512c2cb0), U64_C (0xd3d6b8bb05d3d36b),
-    U64_C (0xe76b5cd38ce7e7bb), U64_C (0x6e57cbdc396e6ea5),
-    U64_C (0xc46ef395aac4c437), U64_C (0x03180f061b03030c),
-    U64_C (0x568a13acdc565645), U64_C (0x441a49885e44440d),
-    U64_C (0x7fdf9efea07f7fe1), U64_C (0xa921374f88a9a99e),
-    U64_C (0x2a4d8254672a2aa8), U64_C (0xbbb16d6b0abbbbd6),
-    U64_C (0xc146e29f87c1c123), U64_C (0x53a202a6f1535351),
-    U64_C (0xdcae8ba572dcdc57), U64_C (0x0b582716530b0b2c),
-    U64_C (0x9d9cd327019d9d4e), U64_C (0x6c47c1d82b6c6cad),
-    U64_C (0x3195f562a43131c4), U64_C (0x7487b9e8f37474cd),
-    U64_C (0xf6e309f115f6f6ff), U64_C (0x460a438c4c464605),
-    U64_C (0xac092645a5acac8a), U64_C (0x893c970fb589891e),
-    U64_C (0x14a04428b4141450), U64_C (0xe15b42dfbae1e1a3),
-    U64_C (0x16b04e2ca6161658), U64_C (0x3acdd274f73a3ae8),
-    U64_C (0x696fd0d2066969b9), U64_C (0x09482d1241090924),
-    U64_C (0x70a7ade0d77070dd), U64_C (0xb6d954716fb6b6e2),
-    U64_C (0xd0ceb7bd1ed0d067), U64_C (0xed3b7ec7d6eded93),
-    U64_C (0xcc2edb85e2cccc17), U64_C (0x422a578468424215),
-    U64_C (0x98b4c22d2c98985a), U64_C (0xa4490e55eda4a4aa),
-    U64_C (0x285d8850752828a0), U64_C (0x5cda31b8865c5c6d),
-    U64_C (0xf8933fed6bf8f8c7), U64_C (0x8644a411c2868622),
-  };
-
-static const u64 C6[256] =
-  {
-    U64_C (0x6018c07830d81818), U64_C (0x8c2305af46262323),
-    U64_C (0x3fc67ef991b8c6c6), U64_C (0x87e8136fcdfbe8e8),
-    U64_C (0x26874ca113cb8787), U64_C (0xdab8a9626d11b8b8),
-    U64_C (0x0401080502090101), U64_C (0x214f426e9e0d4f4f),
-    U64_C (0xd836adee6c9b3636), U64_C (0xa2a6590451ffa6a6),
-    U64_C (0x6fd2debdb90cd2d2), U64_C (0xf3f5fb06f70ef5f5),
-    U64_C (0xf979ef80f2967979), U64_C (0xa16f5fcede306f6f),
-    U64_C (0x7e91fcef3f6d9191), U64_C (0x5552aa07a4f85252),
-    U64_C (0x9d6027fdc0476060), U64_C (0xcabc89766535bcbc),
-    U64_C (0x569baccd2b379b9b), U64_C (0x028e048c018a8e8e),
-    U64_C (0xb6a371155bd2a3a3), U64_C (0x300c603c186c0c0c),
-    U64_C (0xf17bff8af6847b7b), U64_C (0xd435b5e16a803535),
-    U64_C (0x741de8693af51d1d), U64_C (0xa7e05347ddb3e0e0),
-    U64_C (0x7bd7f6acb321d7d7), U64_C (0x2fc25eed999cc2c2),
-    U64_C (0xb82e6d965c432e2e), U64_C (0x314b627a96294b4b),
-    U64_C (0xdffea321e15dfefe), U64_C (0x41578216aed55757),
-    U64_C (0x5415a8412abd1515), U64_C (0xc1779fb6eee87777),
-    U64_C (0xdc37a5eb6e923737), U64_C (0xb3e57b56d79ee5e5),
-    U64_C (0x469f8cd923139f9f), U64_C (0xe7f0d317fd23f0f0),
-    U64_C (0x354a6a7f94204a4a), U64_C (0x4fda9e95a944dada),
-    U64_C (0x7d58fa25b0a25858), U64_C (0x03c906ca8fcfc9c9),
-    U64_C (0xa429558d527c2929), U64_C (0x280a5022145a0a0a),
-    U64_C (0xfeb1e14f7f50b1b1), U64_C (0xbaa0691a5dc9a0a0),
-    U64_C (0xb16b7fdad6146b6b), U64_C (0x2e855cab17d98585),
-    U64_C (0xcebd8173673cbdbd), U64_C (0x695dd234ba8f5d5d),
-    U64_C (0x4010805020901010), U64_C (0xf7f4f303f507f4f4),
-    U64_C (0x0bcb16c08bddcbcb), U64_C (0xf83eedc67cd33e3e),
-    U64_C (0x140528110a2d0505), U64_C (0x81671fe6ce786767),
-    U64_C (0xb7e47353d597e4e4), U64_C (0x9c2725bb4e022727),
-    U64_C (0x1941325882734141), U64_C (0x168b2c9d0ba78b8b),
-    U64_C (0xa6a7510153f6a7a7), U64_C (0xe97dcf94fab27d7d),
-    U64_C (0x6e95dcfb37499595), U64_C (0x47d88e9fad56d8d8),
-    U64_C (0xcbfb8b30eb70fbfb), U64_C (0x9fee2371c1cdeeee),
-    U64_C (0xed7cc791f8bb7c7c), U64_C (0x856617e3cc716666),
-    U64_C (0x53dda68ea77bdddd), U64_C (0x5c17b84b2eaf1717),
-    U64_C (0x014702468e454747), U64_C (0x429e84dc211a9e9e),
-    U64_C (0x0fca1ec589d4caca), U64_C (0xb42d75995a582d2d),
-    U64_C (0xc6bf9179632ebfbf), U64_C (0x1c07381b0e3f0707),
-    U64_C (0x8ead012347acadad), U64_C (0x755aea2fb4b05a5a),
-    U64_C (0x36836cb51bef8383), U64_C (0xcc3385ff66b63333),
-    U64_C (0x91633ff2c65c6363), U64_C (0x0802100a04120202),
-    U64_C (0x92aa39384993aaaa), U64_C (0xd971afa8e2de7171),
-    U64_C (0x07c80ecf8dc6c8c8), U64_C (0x6419c87d32d11919),
-    U64_C (0x39497270923b4949), U64_C (0x43d9869aaf5fd9d9),
-    U64_C (0xeff2c31df931f2f2), U64_C (0xabe34b48dba8e3e3),
-    U64_C (0x715be22ab6b95b5b), U64_C (0x1a8834920dbc8888),
-    U64_C (0x529aa4c8293e9a9a), U64_C (0x98262dbe4c0b2626),
-    U64_C (0xc8328dfa64bf3232), U64_C (0xfab0e94a7d59b0b0),
-    U64_C (0x83e91b6acff2e9e9), U64_C (0x3c0f78331e770f0f),
-    U64_C (0x73d5e6a6b733d5d5), U64_C (0x3a8074ba1df48080),
-    U64_C (0xc2be997c6127bebe), U64_C (0x13cd26de87ebcdcd),
-    U64_C (0xd034bde468893434), U64_C (0x3d487a7590324848),
-    U64_C (0xdbffab24e354ffff), U64_C (0xf57af78ff48d7a7a),
-    U64_C (0x7a90f4ea3d649090), U64_C (0x615fc23ebe9d5f5f),
-    U64_C (0x80201da0403d2020), U64_C (0xbd6867d5d00f6868),
-    U64_C (0x681ad07234ca1a1a), U64_C (0x82ae192c41b7aeae),
-    U64_C (0xeab4c95e757db4b4), U64_C (0x4d549a19a8ce5454),
-    U64_C (0x7693ece53b7f9393), U64_C (0x88220daa442f2222),
-    U64_C (0x8d6407e9c8636464), U64_C (0xe3f1db12ff2af1f1),
-    U64_C (0xd173bfa2e6cc7373), U64_C (0x4812905a24821212),
-    U64_C (0x1d403a5d807a4040), U64_C (0x2008402810480808),
-    U64_C (0x2bc356e89b95c3c3), U64_C (0x97ec337bc5dfecec),
-    U64_C (0x4bdb9690ab4ddbdb), U64_C (0xbea1611f5fc0a1a1),
-    U64_C (0x0e8d1c8307918d8d), U64_C (0xf43df5c97ac83d3d),
-    U64_C (0x6697ccf1335b9797), U64_C (0x0000000000000000),
-    U64_C (0x1bcf36d483f9cfcf), U64_C (0xac2b4587566e2b2b),
-    U64_C (0xc57697b3ece17676), U64_C (0x328264b019e68282),
-    U64_C (0x7fd6fea9b128d6d6), U64_C (0x6c1bd87736c31b1b),
-    U64_C (0xeeb5c15b7774b5b5), U64_C (0x86af112943beafaf),
-    U64_C (0xb56a77dfd41d6a6a), U64_C (0x5d50ba0da0ea5050),
-    U64_C (0x0945124c8a574545), U64_C (0xebf3cb18fb38f3f3),
-    U64_C (0xc0309df060ad3030), U64_C (0x9bef2b74c3c4efef),
-    U64_C (0xfc3fe5c37eda3f3f), U64_C (0x4955921caac75555),
-    U64_C (0xb2a2791059dba2a2), U64_C (0x8fea0365c9e9eaea),
-    U64_C (0x89650fecca6a6565), U64_C (0xd2bab9686903baba),
-    U64_C (0xbc2f65935e4a2f2f), U64_C (0x27c04ee79d8ec0c0),
-    U64_C (0x5fdebe81a160dede), U64_C (0x701ce06c38fc1c1c),
-    U64_C (0xd3fdbb2ee746fdfd), U64_C (0x294d52649a1f4d4d),
-    U64_C (0x7292e4e039769292), U64_C (0xc9758fbceafa7575),
-    U64_C (0x1806301e0c360606), U64_C (0x128a249809ae8a8a),
-    U64_C (0xf2b2f940794bb2b2), U64_C (0xbfe66359d185e6e6),
-    U64_C (0x380e70361c7e0e0e), U64_C (0x7c1ff8633ee71f1f),
-    U64_C (0x956237f7c4556262), U64_C (0x77d4eea3b53ad4d4),
-    U64_C (0x9aa829324d81a8a8), U64_C (0x6296c4f431529696),
-    U64_C (0xc3f99b3aef62f9f9), U64_C (0x33c566f697a3c5c5),
-    U64_C (0x942535b14a102525), U64_C (0x7959f220b2ab5959),
-    U64_C (0x2a8454ae15d08484), U64_C (0xd572b7a7e4c57272),
-    U64_C (0xe439d5dd72ec3939), U64_C (0x2d4c5a6198164c4c),
-    U64_C (0x655eca3bbc945e5e), U64_C (0xfd78e785f09f7878),
-    U64_C (0xe038ddd870e53838), U64_C (0x0a8c148605988c8c),
-    U64_C (0x63d1c6b2bf17d1d1), U64_C (0xaea5410b57e4a5a5),
-    U64_C (0xafe2434dd9a1e2e2), U64_C (0x99612ff8c24e6161),
-    U64_C (0xf6b3f1457b42b3b3), U64_C (0x842115a542342121),
-    U64_C (0x4a9c94d625089c9c), U64_C (0x781ef0663cee1e1e),
-    U64_C (0x1143225286614343), U64_C (0x3bc776fc93b1c7c7),
-    U64_C (0xd7fcb32be54ffcfc), U64_C (0x1004201408240404),
-    U64_C (0x5951b208a2e35151), U64_C (0x5e99bcc72f259999),
-    U64_C (0xa96d4fc4da226d6d), U64_C (0x340d68391a650d0d),
-    U64_C (0xcffa8335e979fafa), U64_C (0x5bdfb684a369dfdf),
-    U64_C (0xe57ed79bfca97e7e), U64_C (0x90243db448192424),
-    U64_C (0xec3bc5d776fe3b3b), U64_C (0x96ab313d4b9aabab),
-    U64_C (0x1fce3ed181f0cece), U64_C (0x4411885522991111),
-    U64_C (0x068f0c8903838f8f), U64_C (0x254e4a6b9c044e4e),
-    U64_C (0xe6b7d1517366b7b7), U64_C (0x8beb0b60cbe0ebeb),
-    U64_C (0xf03cfdcc78c13c3c), U64_C (0x3e817cbf1ffd8181),
-    U64_C (0x6a94d4fe35409494), U64_C (0xfbf7eb0cf31cf7f7),
-    U64_C (0xdeb9a1676f18b9b9), U64_C (0x4c13985f268b1313),
-    U64_C (0xb02c7d9c58512c2c), U64_C (0x6bd3d6b8bb05d3d3),
-    U64_C (0xbbe76b5cd38ce7e7), U64_C (0xa56e57cbdc396e6e),
-    U64_C (0x37c46ef395aac4c4), U64_C (0x0c03180f061b0303),
-    U64_C (0x45568a13acdc5656), U64_C (0x0d441a49885e4444),
-    U64_C (0xe17fdf9efea07f7f), U64_C (0x9ea921374f88a9a9),
-    U64_C (0xa82a4d8254672a2a), U64_C (0xd6bbb16d6b0abbbb),
-    U64_C (0x23c146e29f87c1c1), U64_C (0x5153a202a6f15353),
-    U64_C (0x57dcae8ba572dcdc), U64_C (0x2c0b582716530b0b),
-    U64_C (0x4e9d9cd327019d9d), U64_C (0xad6c47c1d82b6c6c),
-    U64_C (0xc43195f562a43131), U64_C (0xcd7487b9e8f37474),
-    U64_C (0xfff6e309f115f6f6), U64_C (0x05460a438c4c4646),
-    U64_C (0x8aac092645a5acac), U64_C (0x1e893c970fb58989),
-    U64_C (0x5014a04428b41414), U64_C (0xa3e15b42dfbae1e1),
-    U64_C (0x5816b04e2ca61616), U64_C (0xe83acdd274f73a3a),
-    U64_C (0xb9696fd0d2066969), U64_C (0x2409482d12410909),
-    U64_C (0xdd70a7ade0d77070), U64_C (0xe2b6d954716fb6b6),
-    U64_C (0x67d0ceb7bd1ed0d0), U64_C (0x93ed3b7ec7d6eded),
-    U64_C (0x17cc2edb85e2cccc), U64_C (0x15422a5784684242),
-    U64_C (0x5a98b4c22d2c9898), U64_C (0xaaa4490e55eda4a4),
-    U64_C (0xa0285d8850752828), U64_C (0x6d5cda31b8865c5c),
-    U64_C (0xc7f8933fed6bf8f8), U64_C (0x228644a411c28686),
-  };
-
-static const u64 C7[256] =
-  {
-    U64_C (0x186018c07830d818), U64_C (0x238c2305af462623),
-    U64_C (0xc63fc67ef991b8c6), U64_C (0xe887e8136fcdfbe8),
-    U64_C (0x8726874ca113cb87), U64_C (0xb8dab8a9626d11b8),
-    U64_C (0x0104010805020901), U64_C (0x4f214f426e9e0d4f),
-    U64_C (0x36d836adee6c9b36), U64_C (0xa6a2a6590451ffa6),
-    U64_C (0xd26fd2debdb90cd2), U64_C (0xf5f3f5fb06f70ef5),
-    U64_C (0x79f979ef80f29679), U64_C (0x6fa16f5fcede306f),
-    U64_C (0x917e91fcef3f6d91), U64_C (0x525552aa07a4f852),
-    U64_C (0x609d6027fdc04760), U64_C (0xbccabc89766535bc),
-    U64_C (0x9b569baccd2b379b), U64_C (0x8e028e048c018a8e),
-    U64_C (0xa3b6a371155bd2a3), U64_C (0x0c300c603c186c0c),
-    U64_C (0x7bf17bff8af6847b), U64_C (0x35d435b5e16a8035),
-    U64_C (0x1d741de8693af51d), U64_C (0xe0a7e05347ddb3e0),
-    U64_C (0xd77bd7f6acb321d7), U64_C (0xc22fc25eed999cc2),
-    U64_C (0x2eb82e6d965c432e), U64_C (0x4b314b627a96294b),
-    U64_C (0xfedffea321e15dfe), U64_C (0x5741578216aed557),
-    U64_C (0x155415a8412abd15), U64_C (0x77c1779fb6eee877),
-    U64_C (0x37dc37a5eb6e9237), U64_C (0xe5b3e57b56d79ee5),
-    U64_C (0x9f469f8cd923139f), U64_C (0xf0e7f0d317fd23f0),
-    U64_C (0x4a354a6a7f94204a), U64_C (0xda4fda9e95a944da),
-    U64_C (0x587d58fa25b0a258), U64_C (0xc903c906ca8fcfc9),
-    U64_C (0x29a429558d527c29), U64_C (0x0a280a5022145a0a),
-    U64_C (0xb1feb1e14f7f50b1), U64_C (0xa0baa0691a5dc9a0),
-    U64_C (0x6bb16b7fdad6146b), U64_C (0x852e855cab17d985),
-    U64_C (0xbdcebd8173673cbd), U64_C (0x5d695dd234ba8f5d),
-    U64_C (0x1040108050209010), U64_C (0xf4f7f4f303f507f4),
-    U64_C (0xcb0bcb16c08bddcb), U64_C (0x3ef83eedc67cd33e),
-    U64_C (0x05140528110a2d05), U64_C (0x6781671fe6ce7867),
-    U64_C (0xe4b7e47353d597e4), U64_C (0x279c2725bb4e0227),
-    U64_C (0x4119413258827341), U64_C (0x8b168b2c9d0ba78b),
-    U64_C (0xa7a6a7510153f6a7), U64_C (0x7de97dcf94fab27d),
-    U64_C (0x956e95dcfb374995), U64_C (0xd847d88e9fad56d8),
-    U64_C (0xfbcbfb8b30eb70fb), U64_C (0xee9fee2371c1cdee),
-    U64_C (0x7ced7cc791f8bb7c), U64_C (0x66856617e3cc7166),
-    U64_C (0xdd53dda68ea77bdd), U64_C (0x175c17b84b2eaf17),
-    U64_C (0x47014702468e4547), U64_C (0x9e429e84dc211a9e),
-    U64_C (0xca0fca1ec589d4ca), U64_C (0x2db42d75995a582d),
-    U64_C (0xbfc6bf9179632ebf), U64_C (0x071c07381b0e3f07),
-    U64_C (0xad8ead012347acad), U64_C (0x5a755aea2fb4b05a),
-    U64_C (0x8336836cb51bef83), U64_C (0x33cc3385ff66b633),
-    U64_C (0x6391633ff2c65c63), U64_C (0x020802100a041202),
-    U64_C (0xaa92aa39384993aa), U64_C (0x71d971afa8e2de71),
-    U64_C (0xc807c80ecf8dc6c8), U64_C (0x196419c87d32d119),
-    U64_C (0x4939497270923b49), U64_C (0xd943d9869aaf5fd9),
-    U64_C (0xf2eff2c31df931f2), U64_C (0xe3abe34b48dba8e3),
-    U64_C (0x5b715be22ab6b95b), U64_C (0x881a8834920dbc88),
-    U64_C (0x9a529aa4c8293e9a), U64_C (0x2698262dbe4c0b26),
-    U64_C (0x32c8328dfa64bf32), U64_C (0xb0fab0e94a7d59b0),
-    U64_C (0xe983e91b6acff2e9), U64_C (0x0f3c0f78331e770f),
-    U64_C (0xd573d5e6a6b733d5), U64_C (0x803a8074ba1df480),
-    U64_C (0xbec2be997c6127be), U64_C (0xcd13cd26de87ebcd),
-    U64_C (0x34d034bde4688934), U64_C (0x483d487a75903248),
-    U64_C (0xffdbffab24e354ff), U64_C (0x7af57af78ff48d7a),
-    U64_C (0x907a90f4ea3d6490), U64_C (0x5f615fc23ebe9d5f),
-    U64_C (0x2080201da0403d20), U64_C (0x68bd6867d5d00f68),
-    U64_C (0x1a681ad07234ca1a), U64_C (0xae82ae192c41b7ae),
-    U64_C (0xb4eab4c95e757db4), U64_C (0x544d549a19a8ce54),
-    U64_C (0x937693ece53b7f93), U64_C (0x2288220daa442f22),
-    U64_C (0x648d6407e9c86364), U64_C (0xf1e3f1db12ff2af1),
-    U64_C (0x73d173bfa2e6cc73), U64_C (0x124812905a248212),
-    U64_C (0x401d403a5d807a40), U64_C (0x0820084028104808),
-    U64_C (0xc32bc356e89b95c3), U64_C (0xec97ec337bc5dfec),
-    U64_C (0xdb4bdb9690ab4ddb), U64_C (0xa1bea1611f5fc0a1),
-    U64_C (0x8d0e8d1c8307918d), U64_C (0x3df43df5c97ac83d),
-    U64_C (0x976697ccf1335b97), U64_C (0x0000000000000000),
-    U64_C (0xcf1bcf36d483f9cf), U64_C (0x2bac2b4587566e2b),
-    U64_C (0x76c57697b3ece176), U64_C (0x82328264b019e682),
-    U64_C (0xd67fd6fea9b128d6), U64_C (0x1b6c1bd87736c31b),
-    U64_C (0xb5eeb5c15b7774b5), U64_C (0xaf86af112943beaf),
-    U64_C (0x6ab56a77dfd41d6a), U64_C (0x505d50ba0da0ea50),
-    U64_C (0x450945124c8a5745), U64_C (0xf3ebf3cb18fb38f3),
-    U64_C (0x30c0309df060ad30), U64_C (0xef9bef2b74c3c4ef),
-    U64_C (0x3ffc3fe5c37eda3f), U64_C (0x554955921caac755),
-    U64_C (0xa2b2a2791059dba2), U64_C (0xea8fea0365c9e9ea),
-    U64_C (0x6589650fecca6a65), U64_C (0xbad2bab9686903ba),
-    U64_C (0x2fbc2f65935e4a2f), U64_C (0xc027c04ee79d8ec0),
-    U64_C (0xde5fdebe81a160de), U64_C (0x1c701ce06c38fc1c),
-    U64_C (0xfdd3fdbb2ee746fd), U64_C (0x4d294d52649a1f4d),
-    U64_C (0x927292e4e0397692), U64_C (0x75c9758fbceafa75),
-    U64_C (0x061806301e0c3606), U64_C (0x8a128a249809ae8a),
-    U64_C (0xb2f2b2f940794bb2), U64_C (0xe6bfe66359d185e6),
-    U64_C (0x0e380e70361c7e0e), U64_C (0x1f7c1ff8633ee71f),
-    U64_C (0x62956237f7c45562), U64_C (0xd477d4eea3b53ad4),
-    U64_C (0xa89aa829324d81a8), U64_C (0x966296c4f4315296),
-    U64_C (0xf9c3f99b3aef62f9), U64_C (0xc533c566f697a3c5),
-    U64_C (0x25942535b14a1025), U64_C (0x597959f220b2ab59),
-    U64_C (0x842a8454ae15d084), U64_C (0x72d572b7a7e4c572),
-    U64_C (0x39e439d5dd72ec39), U64_C (0x4c2d4c5a6198164c),
-    U64_C (0x5e655eca3bbc945e), U64_C (0x78fd78e785f09f78),
-    U64_C (0x38e038ddd870e538), U64_C (0x8c0a8c148605988c),
-    U64_C (0xd163d1c6b2bf17d1), U64_C (0xa5aea5410b57e4a5),
-    U64_C (0xe2afe2434dd9a1e2), U64_C (0x6199612ff8c24e61),
-    U64_C (0xb3f6b3f1457b42b3), U64_C (0x21842115a5423421),
-    U64_C (0x9c4a9c94d625089c), U64_C (0x1e781ef0663cee1e),
-    U64_C (0x4311432252866143), U64_C (0xc73bc776fc93b1c7),
-    U64_C (0xfcd7fcb32be54ffc), U64_C (0x0410042014082404),
-    U64_C (0x515951b208a2e351), U64_C (0x995e99bcc72f2599),
-    U64_C (0x6da96d4fc4da226d), U64_C (0x0d340d68391a650d),
-    U64_C (0xfacffa8335e979fa), U64_C (0xdf5bdfb684a369df),
-    U64_C (0x7ee57ed79bfca97e), U64_C (0x2490243db4481924),
-    U64_C (0x3bec3bc5d776fe3b), U64_C (0xab96ab313d4b9aab),
-    U64_C (0xce1fce3ed181f0ce), U64_C (0x1144118855229911),
-    U64_C (0x8f068f0c8903838f), U64_C (0x4e254e4a6b9c044e),
-    U64_C (0xb7e6b7d1517366b7), U64_C (0xeb8beb0b60cbe0eb),
-    U64_C (0x3cf03cfdcc78c13c), U64_C (0x813e817cbf1ffd81),
-    U64_C (0x946a94d4fe354094), U64_C (0xf7fbf7eb0cf31cf7),
-    U64_C (0xb9deb9a1676f18b9), U64_C (0x134c13985f268b13),
-    U64_C (0x2cb02c7d9c58512c), U64_C (0xd36bd3d6b8bb05d3),
-    U64_C (0xe7bbe76b5cd38ce7), U64_C (0x6ea56e57cbdc396e),
-    U64_C (0xc437c46ef395aac4), U64_C (0x030c03180f061b03),
-    U64_C (0x5645568a13acdc56), U64_C (0x440d441a49885e44),
-    U64_C (0x7fe17fdf9efea07f), U64_C (0xa99ea921374f88a9),
-    U64_C (0x2aa82a4d8254672a), U64_C (0xbbd6bbb16d6b0abb),
-    U64_C (0xc123c146e29f87c1), U64_C (0x535153a202a6f153),
-    U64_C (0xdc57dcae8ba572dc), U64_C (0x0b2c0b582716530b),
-    U64_C (0x9d4e9d9cd327019d), U64_C (0x6cad6c47c1d82b6c),
-    U64_C (0x31c43195f562a431), U64_C (0x74cd7487b9e8f374),
-    U64_C (0xf6fff6e309f115f6), U64_C (0x4605460a438c4c46),
-    U64_C (0xac8aac092645a5ac), U64_C (0x891e893c970fb589),
-    U64_C (0x145014a04428b414), U64_C (0xe1a3e15b42dfbae1),
-    U64_C (0x165816b04e2ca616), U64_C (0x3ae83acdd274f73a),
-    U64_C (0x69b9696fd0d20669), U64_C (0x092409482d124109),
-    U64_C (0x70dd70a7ade0d770), U64_C (0xb6e2b6d954716fb6),
-    U64_C (0xd067d0ceb7bd1ed0), U64_C (0xed93ed3b7ec7d6ed),
-    U64_C (0xcc17cc2edb85e2cc), U64_C (0x4215422a57846842),
-    U64_C (0x985a98b4c22d2c98), U64_C (0xa4aaa4490e55eda4),
-    U64_C (0x28a0285d88507528), U64_C (0x5c6d5cda31b8865c),
-    U64_C (0xf8c7f8933fed6bf8), U64_C (0x86228644a411c286),
-  };
-
-\f
-
-static void
-whirlpool_init (void *ctx)
-{
-  whirlpool_context_t *context = ctx;
-
-  memset (context, 0, sizeof (*context));
-}
-
-
-/*
- * Transform block.
- */
-static void
-whirlpool_transform (whirlpool_context_t *context, const unsigned char *data)
-{
-  whirlpool_block_t data_block;
-  whirlpool_block_t key;
-  whirlpool_block_t state;
-  whirlpool_block_t block;
-  unsigned int r;
-  unsigned int i;
-
-  buffer_to_block (data, data_block, i);
-  block_copy (key, context->hash_state, i);
-  block_copy (state, context->hash_state, i);
-  block_xor (state, data_block, i);
-
-  for (r = 0; r < R; r++)
-    {
-      /* Compute round key K^r.  */
-
-      block[0] = (C0[(key[0] >> 56) & 0xFF] ^ C1[(key[7] >> 48) & 0xFF] ^
-                 C2[(key[6] >> 40) & 0xFF] ^ C3[(key[5] >> 32) & 0xFF] ^
-                 C4[(key[4] >> 24) & 0xFF] ^ C5[(key[3] >> 16) & 0xFF] ^
-                 C6[(key[2] >>  8) & 0xFF] ^ C7[(key[1] >>  0) & 0xFF] ^ rc[r]);
-      block[1] = (C0[(key[1] >> 56) & 0xFF] ^ C1[(key[0] >> 48) & 0xFF] ^
-                 C2[(key[7] >> 40) & 0xFF] ^ C3[(key[6] >> 32) & 0xFF] ^
-                 C4[(key[5] >> 24) & 0xFF] ^ C5[(key[4] >> 16) & 0xFF] ^
-                 C6[(key[3] >>  8) & 0xFF] ^ C7[(key[2] >>  0) & 0xFF]);
-      block[2] = (C0[(key[2] >> 56) & 0xFF] ^ C1[(key[1] >> 48) & 0xFF] ^
-                 C2[(key[0] >> 40) & 0xFF] ^ C3[(key[7] >> 32) & 0xFF] ^
-                 C4[(key[6] >> 24) & 0xFF] ^ C5[(key[5] >> 16) & 0xFF] ^
-                 C6[(key[4] >>  8) & 0xFF] ^ C7[(key[3] >>  0) & 0xFF]);
-      block[3] = (C0[(key[3] >> 56) & 0xFF] ^ C1[(key[2] >> 48) & 0xFF] ^
-                 C2[(key[1] >> 40) & 0xFF] ^ C3[(key[0] >> 32) & 0xFF] ^
-                 C4[(key[7] >> 24) & 0xFF] ^ C5[(key[6] >> 16) & 0xFF] ^
-                 C6[(key[5] >>  8) & 0xFF] ^ C7[(key[4] >>  0) & 0xFF]);
-      block[4] = (C0[(key[4] >> 56) & 0xFF] ^ C1[(key[3] >> 48) & 0xFF] ^
-                 C2[(key[2] >> 40) & 0xFF] ^ C3[(key[1] >> 32) & 0xFF] ^
-                 C4[(key[0] >> 24) & 0xFF] ^ C5[(key[7] >> 16) & 0xFF] ^
-                 C6[(key[6] >>  8) & 0xFF] ^ C7[(key[5] >>  0) & 0xFF]);
-      block[5] = (C0[(key[5] >> 56) & 0xFF] ^ C1[(key[4] >> 48) & 0xFF] ^
-                 C2[(key[3] >> 40) & 0xFF] ^ C3[(key[2] >> 32) & 0xFF] ^
-                 C4[(key[1] >> 24) & 0xFF] ^ C5[(key[0] >> 16) & 0xFF] ^
-                 C6[(key[7] >>  8) & 0xFF] ^ C7[(key[6] >>  0) & 0xFF]);
-      block[6] = (C0[(key[6] >> 56) & 0xFF] ^ C1[(key[5] >> 48) & 0xFF] ^
-                 C2[(key[4] >> 40) & 0xFF] ^ C3[(key[3] >> 32) & 0xFF] ^
-                 C4[(key[2] >> 24) & 0xFF] ^ C5[(key[1] >> 16) & 0xFF] ^
-                 C6[(key[0] >>  8) & 0xFF] ^ C7[(key[7] >>  0) & 0xFF]);
-      block[7] = (C0[(key[7] >> 56) & 0xFF] ^ C1[(key[6] >> 48) & 0xFF] ^
-                 C2[(key[5] >> 40) & 0xFF] ^ C3[(key[4] >> 32) & 0xFF] ^
-                 C4[(key[3] >> 24) & 0xFF] ^ C5[(key[2] >> 16) & 0xFF] ^
-                 C6[(key[1] >>  8) & 0xFF] ^ C7[(key[0] >>  0) & 0xFF]);
-      block_copy (key, block, i);
-
-      /* Apply r-th round transformation.  */
-
-      block[0] = (C0[(state[0] >> 56) & 0xFF] ^ C1[(state[7] >> 48) & 0xFF] ^
-                 C2[(state[6] >> 40) & 0xFF] ^ C3[(state[5] >> 32) & 0xFF] ^
-                 C4[(state[4] >> 24) & 0xFF] ^ C5[(state[3] >> 16) & 0xFF] ^
-                 C6[(state[2] >>  8) & 0xFF] ^ C7[(state[1] >>  0) & 0xFF] ^ key[0]);
-      block[1] = (C0[(state[1] >> 56) & 0xFF] ^ C1[(state[0] >> 48) & 0xFF] ^
-                 C2[(state[7] >> 40) & 0xFF] ^ C3[(state[6] >> 32) & 0xFF] ^
-                 C4[(state[5] >> 24) & 0xFF] ^ C5[(state[4] >> 16) & 0xFF] ^
-                 C6[(state[3] >>  8) & 0xFF] ^ C7[(state[2] >>  0) & 0xFF] ^ key[1]);
-      block[2] = (C0[(state[2] >> 56) & 0xFF] ^ C1[(state[1] >> 48) & 0xFF] ^
-                 C2[(state[0] >> 40) & 0xFF] ^ C3[(state[7] >> 32) & 0xFF] ^
-                 C4[(state[6] >> 24) & 0xFF] ^ C5[(state[5] >> 16) & 0xFF] ^
-                 C6[(state[4] >>  8) & 0xFF] ^ C7[(state[3] >>  0) & 0xFF] ^ key[2]);
-      block[3] = (C0[(state[3] >> 56) & 0xFF] ^ C1[(state[2] >> 48) & 0xFF] ^
-                 C2[(state[1] >> 40) & 0xFF] ^ C3[(state[0] >> 32) & 0xFF] ^
-                 C4[(state[7] >> 24) & 0xFF] ^ C5[(state[6] >> 16) & 0xFF] ^
-                 C6[(state[5] >>  8) & 0xFF] ^ C7[(state[4] >>  0) & 0xFF] ^ key[3]);
-      block[4] = (C0[(state[4] >> 56) & 0xFF] ^ C1[(state[3] >> 48) & 0xFF] ^
-                 C2[(state[2] >> 40) & 0xFF] ^ C3[(state[1] >> 32) & 0xFF] ^
-                 C4[(state[0] >> 24) & 0xFF] ^ C5[(state[7] >> 16) & 0xFF] ^
-                 C6[(state[6] >>  8) & 0xFF] ^ C7[(state[5] >>  0) & 0xFF] ^ key[4]);
-      block[5] = (C0[(state[5] >> 56) & 0xFF] ^ C1[(state[4] >> 48) & 0xFF] ^
-                 C2[(state[3] >> 40) & 0xFF] ^ C3[(state[2] >> 32) & 0xFF] ^
-                 C4[(state[1] >> 24) & 0xFF] ^ C5[(state[0] >> 16) & 0xFF] ^
-                 C6[(state[7] >>  8) & 0xFF] ^ C7[(state[6] >>  0) & 0xFF] ^ key[5]);
-      block[6] = (C0[(state[6] >> 56) & 0xFF] ^ C1[(state[5] >> 48) & 0xFF] ^
-                 C2[(state[4] >> 40) & 0xFF] ^ C3[(state[3] >> 32) & 0xFF] ^
-                 C4[(state[2] >> 24) & 0xFF] ^ C5[(state[1] >> 16) & 0xFF] ^
-                 C6[(state[0] >>  8) & 0xFF] ^ C7[(state[7] >>  0) & 0xFF] ^ key[6]);
-      block[7] = (C0[(state[7] >> 56) & 0xFF] ^ C1[(state[6] >> 48) & 0xFF] ^
-                 C2[(state[5] >> 40) & 0xFF] ^ C3[(state[4] >> 32) & 0xFF] ^
-                 C4[(state[3] >> 24) & 0xFF] ^ C5[(state[2] >> 16) & 0xFF] ^
-                 C6[(state[1] >>  8) & 0xFF] ^ C7[(state[0] >>  0) & 0xFF] ^ key[7]);
-      block_copy (state, block, i);
-    }
-
-  /* Compression.  */
-
-  block_xor (context->hash_state, data_block, i);
-  block_xor (context->hash_state, state, i);
-}
-
-static void
-whirlpool_add (whirlpool_context_t *context,
-              const void *buffer_arg, size_t buffer_n)
-{
-  const unsigned char *buffer = buffer_arg;
-  u64 buffer_size;
-  unsigned int carry;
-  unsigned int i;
-
-  buffer_size = buffer_n;
-
-  if (context->count == BLOCK_SIZE)
-    {
-      /* Flush the buffer.  */
-      whirlpool_transform (context, context->buffer);
-      /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */
-      context->count = 0;
-    }
-  if (! buffer)
-    return; /* Nothing to add.  */
-
-  if (context->count)
-    {
-      while (buffer_n && (context->count < BLOCK_SIZE))
-       {
-         context->buffer[context->count++] = *buffer++;
-         buffer_n--;
-       }
-      whirlpool_add (context, NULL, 0);
-      if (!buffer_n)
-       /* Done.  */
-        return;
-    }
-  /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */
-
-  while (buffer_n >= BLOCK_SIZE) 
-    {
-      whirlpool_transform (context, buffer);
-      context->count = 0;
-      buffer_n -= BLOCK_SIZE;
-      buffer += BLOCK_SIZE;
-    }
-  while (buffer_n && (context->count < BLOCK_SIZE))
-    {
-      context->buffer[context->count++] = *buffer++;
-      buffer_n--;
-    }
-
-  /* Update bit counter.  */
-  carry = 0;
-  buffer_size <<= 3;
-  for (i = 1; i <= 32; i++)
-    {
-      if (! (buffer_size || carry))
-       break;
-
-      carry += context->length[32 - i] + (buffer_size & 0xFF);
-      context->length[32 - i] = carry;
-      buffer_size >>= 8;
-      carry >>= 8;
-    }
-  gcry_assert (! (buffer_size || carry));
-}
-
-static void
-whirlpool_write (void *ctx, const void *buffer, size_t buffer_n)
-{
-  whirlpool_context_t *context = ctx;
-
-  whirlpool_add (context, buffer, buffer_n);
-}
-
-static void
-whirlpool_final (void *ctx)
-{
-  whirlpool_context_t *context = ctx;
-  unsigned int i;
-
-  /* Flush.  */
-  whirlpool_add (context, NULL, 0);
-
-  /* Pad.  */
-  context->buffer[context->count++] = 0x80;
-
-  if (context->count > 32)
-    {
-      /* An extra block is necessary.  */
-      while (context->count < 64)
-       context->buffer[context->count++] = 0;
-      whirlpool_add (context, NULL, 0);
-    }
-  while (context->count < 32)
-    context->buffer[context->count++] = 0;
-
-  /* Add length of message.  */
-  memcpy (context->buffer + context->count, context->length, 32);
-  context->count += 32;
-  whirlpool_add (context, NULL, 0);
-
-  block_to_buffer (context->buffer, context->hash_state, i);
-}
-
-static byte *
-whirlpool_read (void *ctx)
-{
-  whirlpool_context_t *context = ctx;
-
-  return context->buffer;
-}
-
-gcry_md_spec_t _gcry_digest_spec_whirlpool =
-  {
-    "WHIRLPOOL", NULL, 0, NULL, 64,
-    whirlpool_init, whirlpool_write, whirlpool_final, whirlpool_read,
-    sizeof (whirlpool_context_t)
-  };
diff --git a/lib/libgcrypt_wrap/cipher_wrap.h b/lib/libgcrypt_wrap/cipher_wrap.h
deleted file mode 100644 (file)
index b4530c1..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_GCRY_WRAP_HEADER
-#define GRUB_GCRY_WRAP_HEADER 1
-
-#include <grub/types.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/dl.h>
-#include <grub/crypto.h>
-
-#define __GNU_LIBRARY__
-
-#define DIM ARRAY_SIZE
-
-typedef grub_uint64_t u64;
-typedef grub_uint32_t u32;
-typedef grub_uint16_t u16;
-typedef grub_uint8_t byte;
-typedef grub_size_t size_t;
-
-#define U64_C(c) (c ## ULL)
-
-#define _gcry_burn_stack grub_burn_stack
-#define log_error(fmt, args...) grub_dprintf ("crypto", fmt, ## args)
-
-
-#define PUBKEY_FLAG_NO_BLINDING    (1 << 0)
-
-#define CIPHER_INFO_NO_WEAK_KEY    1
-
-#define HAVE_U64_TYPEDEF 1
-
-typedef union {
-    int a;
-    short b;
-    char c[1];
-    long d;
-#ifdef HAVE_U64_TYPEDEF
-    u64 e;
-#endif
-    float f;
-    double g;
-} PROPERLY_ALIGNED_TYPE;
-
-#define gcry_assert(x) grub_assert_real(GRUB_FILE, __LINE__, x)
-
-static inline void
-grub_assert_real (const char *file, int line, int cond)
-{
-  if (!cond)
-    grub_fatal ("Assertion failed at %s:%d\n", file, line);
-}
-
-/* Selftests are in separate modules.  */
-static inline char *
-selftest (void)
-{
-  return NULL;
-}
-
-static inline int
-fips_mode (void)
-{
-  return 0;
-}
-
-#define memset grub_memset
-
-#endif
diff --git a/lib/mips/relocator.c b/lib/mips/relocator.c
deleted file mode 100644 (file)
index 118ddbd..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/misc.h>
-
-#include <grub/types.h>
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/cache.h>
-
-#include <grub/mips/relocator.h>
-
-/* Remark: doesn't work with source outside of 4G.
-   Use relocator64 in this case. 
- */
-
-extern grub_uint8_t grub_relocator32_forward_start;
-extern grub_uint8_t grub_relocator32_forward_end;
-extern grub_uint8_t grub_relocator32_backward_start;
-extern grub_uint8_t grub_relocator32_backward_end;
-
-#define REGW_SIZEOF (2 * sizeof (grub_uint32_t))
-#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t))
-
-#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator32_##x##_end \
-                                - &grub_relocator32_##x##_start)
-#define RELOCATOR_SIZEOF(x)    (RELOCATOR_SRC_SIZEOF(x) \
-                                + REGW_SIZEOF * (31 + 3) + JUMP_SIZEOF)
-#define RELOCATOR_ALIGN 16
-
-#define PREFIX(x) grub_relocator32_ ## x
-
-static void
-write_reg (int regn, grub_uint32_t val, void **target)
-{
-  /* lui $r, (val+0x8000).  */
-  *(grub_uint32_t *) *target = ((0x3c00 | regn) << 16) | ((val + 0x8000) >> 16);
-  *target = ((grub_uint32_t *) *target) + 1;
-  /* addiu $r, $r, val. */
-  *(grub_uint32_t *) *target = (((0x2400 | regn << 5 | regn) << 16)
-                               | (val & 0xffff));
-  *target = ((grub_uint32_t *) *target) + 1;
-}
-
-static void
-write_jump (int regn, void **target)
-{
-  /* j $r.  */
-  *(grub_uint32_t *) *target = (regn<<21) | 0x8;
-  *target = ((grub_uint32_t *) *target) + 1;
-  /* nop.  */
-  *(grub_uint32_t *) *target = 0;
-  *target = ((grub_uint32_t *) *target) + 1;
-}
-
-static void
-write_call_relocator_bw (void *ptr0, void *src, grub_uint32_t dest,
-                        grub_size_t size, struct grub_relocator32_state state)
-{
-  void *ptr = ptr0;
-  int i;
-  write_reg (8, (grub_uint32_t) src, &ptr);
-  write_reg (9, dest, &ptr);
-  write_reg (10, size, &ptr);
-  grub_memcpy (ptr, &grub_relocator32_backward_start,
-              RELOCATOR_SRC_SIZEOF (backward));
-  ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (backward);
-  for (i = 1; i < 32; i++)
-    write_reg (i, state.gpr[i], &ptr);
-  write_jump (state.jumpreg, &ptr);
-  grub_arch_sync_caches (ptr0, (grub_uint8_t *) ptr -  (grub_uint8_t *) ptr0);
-  grub_dprintf ("relocator", "Backward relocator: about to jump to %p\n", ptr0);
-  ((void (*) (void)) ptr0) ();
-}
-
-static void
-write_call_relocator_fw (void *ptr0, void *src, grub_uint32_t dest,
-                        grub_size_t size, struct grub_relocator32_state state)
-{
-  void *ptr = ptr0;
-  int i;
-  write_reg (8, (grub_uint32_t) src, &ptr);
-  write_reg (9, dest, &ptr);
-  write_reg (10, size, &ptr);
-  grub_memcpy (ptr, &grub_relocator32_forward_start,
-              RELOCATOR_SRC_SIZEOF (forward));
-  ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (forward);
-  for (i = 1; i < 32; i++)
-    write_reg (i, state.gpr[i], &ptr);
-  write_jump (state.jumpreg, &ptr);
-  grub_arch_sync_caches (ptr0, (grub_uint8_t *) ptr -  (grub_uint8_t *) ptr0);
-  grub_dprintf ("relocator", "Forward relocator: about to jump to %p\n", ptr0);
-  ((void (*) (void)) ptr0) ();
-}
-
-#include "../relocator.c"
diff --git a/lib/mips/relocator_asm.S b/lib/mips/relocator_asm.S
deleted file mode 100644 (file)
index ff4fa31..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-       
-       .p2align        4       /* force 16-byte alignment */
-
-VARIABLE (grub_relocator32_forward_start)
-       move $a0, $9
-       move $a1, $10
-
-copycont1:     
-       lb $11,0($8)
-       sb $11,0($9)
-       addiu $8, $8, 0x1
-       addiu $9, $9, 0x1
-       addiu $10, $10, 0xffff
-       bne $10, $0, copycont1
-
-#include "../../kern/mips/cache_flush.S"
-
-VARIABLE (grub_relocator32_forward_end)
-
-VARIABLE (grub_relocator32_backward_start)
-       move $a0, $9
-       move $a1, $10
-
-       addu $9, $9, $10
-       addu $8, $8, $10
-       /* Backward movsl is implicitly off-by-one.  compensate that.  */
-       addiu $9, $9, 0xffff
-       addiu $8, $8, 0xffff
-copycont2:     
-       lb $11,0($8)
-       sb $11,0($9)
-       addiu $8, $8, 0xffff
-       addiu $9, $9, 0xffff
-       addiu $10, 0xffff
-       bne $10, $0, copycont2
-
-#include "../../kern/mips/cache_flush.S"
-
-VARIABLE (grub_relocator32_backward_end)
diff --git a/lib/mips/setjmp.S b/lib/mips/setjmp.S
deleted file mode 100644 (file)
index 8ab6222..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-
-       .file   "setjmp.S"
-
-       .text
-
-/*
- * int grub_setjmp (grub_jmp_buf env)
- */
-FUNCTION(grub_setjmp)
-       sw $s0, 0($a0)
-       sw $s1, 4($a0)
-       sw $s2, 8($a0)
-       sw $s3, 12($a0)
-       sw $s4, 16($a0)
-       sw $s5, 20($a0)
-       sw $s6, 24($a0)
-       sw $s7, 28($a0)
-       sw $s8, 32($a0)
-       sw $gp, 36($a0)
-       sw $sp, 40($a0)
-       sw $ra, 44($a0)
-       move $v0, $zero
-       move $v1, $zero
-       jr $ra
-/*
- * int grub_longjmp (grub_jmp_buf env, int val)
- */
-FUNCTION(grub_longjmp)
-       lw $s0, 0($a0)
-       lw $s1, 4($a0)
-       lw $s2, 8($a0)
-       lw $s3, 12($a0)
-       lw $s4, 16($a0)
-       lw $s5, 20($a0)
-       lw $s6, 24($a0)
-       lw $s7, 28($a0)
-       lw $s8, 32($a0)
-       lw $gp, 36($a0)
-       lw $sp, 40($a0)
-       lw $ra, 44($a0)
-       move $v0, $a1
-       bne  $v0, $zero, 1f
-       addiu $v0, $v0, 1
-1:     
-       move $v1, $zero
-       jr $ra
diff --git a/lib/pbkdf2.c b/lib/pbkdf2.c
deleted file mode 100644 (file)
index 083446a..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/* gc-pbkdf2-sha1.c --- Password-Based Key Derivation Function a'la PKCS#5
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2009 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
-
-/* Written by Simon Josefsson.  */
-/* Imported from gnulib.  */
-
-#include <grub/crypto.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-
-/* Implement PKCS#5 PBKDF2 as per RFC 2898.  The PRF to use is HMAC variant
-   of digest supplied by MD.  Inputs are the password P of length PLEN,
-   the salt S of length SLEN, the iteration counter C (> 0), and the
-   desired derived output length DKLEN.  Output buffer is DK which
-   must have room for at least DKLEN octets.  The output buffer will
-   be filled with the derived data.  */
-gcry_err_code_t
-grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
-                   const grub_uint8_t *P, grub_size_t Plen,
-                   const grub_uint8_t *S, grub_size_t Slen,
-                   unsigned int c,
-                   grub_uint8_t *DK, grub_size_t dkLen)
-{
-  unsigned int hLen = md->mdlen;
-  grub_uint8_t U[md->mdlen];
-  grub_uint8_t T[md->mdlen];
-  unsigned int u;
-  unsigned int l;
-  unsigned int r;
-  unsigned int i;
-  unsigned int k;
-  gcry_err_code_t rc;
-  grub_uint8_t *tmp;
-  grub_size_t tmplen = Slen + 4;
-
-  if (c == 0)
-    return GPG_ERR_INV_ARG;
-
-  if (dkLen == 0)
-    return GPG_ERR_INV_ARG;
-
-  if (dkLen > 4294967295U)
-    return GPG_ERR_INV_ARG;
-
-  l = ((dkLen - 1) / hLen) + 1;
-  r = dkLen - (l - 1) * hLen;
-
-  tmp = grub_malloc (tmplen);
-  if (tmp == NULL)
-    return GPG_ERR_OUT_OF_MEMORY;
-
-  grub_memcpy (tmp, S, Slen);
-
-  for (i = 1; i <= l; i++)
-    {
-      grub_memset (T, 0, hLen);
-
-      for (u = 1; u <= c; u++)
-       {
-         if (u == 1)
-           {
-             tmp[Slen + 0] = (i & 0xff000000) >> 24;
-             tmp[Slen + 1] = (i & 0x00ff0000) >> 16;
-             tmp[Slen + 2] = (i & 0x0000ff00) >> 8;
-             tmp[Slen + 3] = (i & 0x000000ff) >> 0;
-
-             rc = grub_crypto_hmac_buffer (md, P, Plen, tmp, tmplen, U);
-           }
-         else
-           rc = grub_crypto_hmac_buffer (md, P, Plen, U, hLen, U);
-
-         if (rc != GPG_ERR_NO_ERROR)
-           {
-             grub_free (tmp);
-             return rc;
-           }
-
-         for (k = 0; k < hLen; k++)
-           T[k] ^= U[k];
-       }
-
-      grub_memcpy (DK + (i - 1) * hLen, T, i == l ? r : hLen);
-    }
-
-  grub_free (tmp);
-
-  return GPG_ERR_NO_ERROR;
-}
diff --git a/lib/posix_wrap/assert.h b/lib/posix_wrap/assert.h
deleted file mode 100644 (file)
index 94cfdd5..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_POSIX_ASSERT_H
-#define GRUB_POSIX_ASSERT_H    1
-
-#include <grub/misc.h>
-
-#define assert(x) assert_real(__FILE__, __LINE__, x)
-
-static inline void
-assert_real (const char *file, int line, int cond)
-{
-  if (!cond)
-    grub_fatal ("Assertion failed at %s:%d\n", file, line);
-}
-
-#endif
diff --git a/lib/posix_wrap/ctype.h b/lib/posix_wrap/ctype.h
deleted file mode 100644 (file)
index 2dc3e53..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_POSIX_CTYPE_H
-#define GRUB_POSIX_CTYPE_H     1
-
-#include <grub/misc.h>
-
-static inline int
-toupper (int c)
-{
-  return grub_toupper (c);
-}
-
-static inline int 
-isspace (int c)
-{
-  return grub_isspace (c);
-}
-
-static inline int 
-isdigit (int c)
-{
-  return grub_isdigit (c);
-}
-
-static inline int
-islower (int c)
-{
-  return (c >= 'a' && c <= 'z');
-}
-
-static inline int
-isupper (int c)
-{
-  return (c >= 'A' && c <= 'Z');
-}
-
-static inline int
-isxdigit (int c)
-{
-  return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')
-    || (c >= '0' && c <= '9');
-}
-
-static inline int 
-isprint (int c)
-{
-  return grub_isprint (c);
-}
-
-static inline int 
-iscntrl (int c)
-{
-  return !grub_isprint (c);
-}
-
-static inline int 
-isgraph (int c)
-{
-  return grub_isprint (c) && !grub_isspace (c);
-}
-
-static inline int
-isalnum (int c)
-{
-  return grub_isalpha (c) || grub_isdigit (c);
-}
-
-static inline int 
-ispunct (int c)
-{
-  return grub_isprint (c) && !grub_isspace (c) && !isalnum (c);
-}
-
-static inline int 
-isalpha (int c)
-{
-  return grub_isalpha (c);
-}
-
-static inline int
-tolower (int c)
-{
-  return grub_tolower (c);
-}
-
-#endif
diff --git a/lib/posix_wrap/errno.h b/lib/posix_wrap/errno.h
deleted file mode 100644 (file)
index 9031722..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_POSIX_ERRNO_H
-#define GRUB_POSIX_ERRNO_H     1
-
-#include <grub/err.h>
-
-#define errno  grub_errno
-#define EINVAL GRUB_ERR_BAD_NUMBER
-#define ENOMEM GRUB_ERR_OUT_OF_MEMORY
-
-#endif
diff --git a/lib/posix_wrap/langinfo.h b/lib/posix_wrap/langinfo.h
deleted file mode 100644 (file)
index 14833c0..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_POSIX_LANGINFO_H
-#define GRUB_POSIX_LANGINFO_H  1
-
-#include <localcharset.h>
-
-typedef enum { CODESET } nl_item;
-
-static inline char *
-nl_langinfo (nl_item item)
-{
-  switch (item)
-    {
-    case CODESET:
-      return locale_charset ();
-    default:
-      return "";
-    }
-}
-
-#endif
diff --git a/lib/posix_wrap/limits.h b/lib/posix_wrap/limits.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/lib/posix_wrap/localcharset.h b/lib/posix_wrap/localcharset.h
deleted file mode 100644 (file)
index 92eb815..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_POSIX_LOCALCHARSET_H
-#define GRUB_POSIX_LOCALCHARSET_H      1
-
-static inline char *
-locale_charset (void)
-{
-  return "UTF-8";
-}
-
-#endif
diff --git a/lib/posix_wrap/locale.h b/lib/posix_wrap/locale.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/lib/posix_wrap/stdint.h b/lib/posix_wrap/stdint.h
deleted file mode 100644 (file)
index a12c43b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <sys/types.h>
diff --git a/lib/posix_wrap/stdio.h b/lib/posix_wrap/stdio.h
deleted file mode 100644 (file)
index 701fcea..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_POSIX_STDIO_H
-#define GRUB_POSIX_STDIO_H     1
-
-#include <grub/misc.h>
-#include <grub/file.h>
-
-typedef struct grub_file FILE;
-
-#define EOF    -1
-
-#endif
diff --git a/lib/posix_wrap/stdlib.h b/lib/posix_wrap/stdlib.h
deleted file mode 100644 (file)
index 5ef6159..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_POSIX_STDLIB_H
-#define GRUB_POSIX_STDLIB_H    1
-
-#include <grub/mm.h>
-
-static inline void 
-free (void *ptr)
-{
-  grub_free (ptr);
-}
-
-static inline void *
-malloc (grub_size_t size)
-{
-  return grub_malloc (size);
-}
-
-static inline void *
-calloc (grub_size_t size, grub_size_t nelem)
-{
-  return grub_zalloc (size * nelem);
-}
-
-static inline void *
-realloc (void *ptr, grub_size_t size)
-{
-  return grub_realloc (ptr, size);
-}
-
-static inline void
-abort (void)
-{
-  grub_abort ();
-}
-
-#define MB_CUR_MAX 6
-
-#endif
diff --git a/lib/posix_wrap/string.h b/lib/posix_wrap/string.h
deleted file mode 100644 (file)
index 7bb6f1e..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_POSIX_STRING_H
-#define GRUB_POSIX_STRING_H    1
-
-static inline grub_size_t
-strlen (const char *s)
-{
-  return grub_strlen (s);
-}
-
-static inline int 
-strcmp (const char *s1, const char *s2)
-{
-  return grub_strcmp (s1, s2);
-}
-
-static inline int 
-strcasecmp (const char *s1, const char *s2)
-{
-  return grub_strcasecmp (s1, s2);
-}
-
-#endif
diff --git a/lib/posix_wrap/sys/types.h b/lib/posix_wrap/sys/types.h
deleted file mode 100644 (file)
index ce37940..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_POSIX_SYS_TYPES_H
-#define GRUB_POSIX_SYS_TYPES_H 1
-
-#include <grub/misc.h>
-
-typedef grub_size_t size_t;
-typedef int bool;
-static const bool true = 1;
-static const bool false = 0;
-
-#define ULONG_MAX GRUB_ULONG_MAX
-#define UCHAR_MAX 0xff
-
-#endif
diff --git a/lib/posix_wrap/unistd.h b/lib/posix_wrap/unistd.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/lib/posix_wrap/wchar.h b/lib/posix_wrap/wchar.h
deleted file mode 100644 (file)
index fd56fd3..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009, 2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_POSIX_WCHAR_H
-#define GRUB_POSIX_WCHAR_H     1
-
-/* UCS-4.  */
-typedef grub_uint32_t wchar_t;
-
-#endif
diff --git a/lib/posix_wrap/wctype.h b/lib/posix_wrap/wctype.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/lib/powerpc/setjmp.S b/lib/powerpc/setjmp.S
deleted file mode 100644 (file)
index 25cbaa3..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2004,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-
-       .file   "setjmp.S"
-
-       .text
-
-/*
- * int grub_setjmp (grub_jmp_buf env)
- */
-FUNCTION(grub_setjmp)
-       stw     1, 0(3)
-       stw     14, 4(3)
-       stw     15, 8(3)
-       stw     16, 12(3)
-       stw     17, 16(3)
-       stw     18, 20(3)
-       stw     19, 24(3)
-       stw     20, 28(3)
-       stw     21, 32(3)
-       stw     22, 36(3)
-       stw     23, 40(3)
-       stw     24, 44(3)
-       stw     25, 48(3)
-       stw     26, 52(3)
-       stw     27, 56(3)
-       stw     28, 60(3)
-       stw     29, 64(3)
-       stw     30, 68(3)
-       mflr    4
-       stw     4, 72(3)
-       mfcr    4
-       stw     4, 76(3)
-       li      3, 0
-       blr
-
-/*
- * int grub_longjmp (grub_jmp_buf env, int val)
- */
-FUNCTION(grub_longjmp)
-       lwz     1, 0(3)
-       lwz     14, 4(3)
-       lwz     15, 8(3)
-       lwz     16, 12(3)
-       lwz     17, 16(3)
-       lwz     18, 20(3)
-       lwz     19, 24(3)
-       lwz     20, 28(3)
-       lwz     21, 32(3)
-       lwz     22, 36(3)
-       lwz     23, 40(3)
-       lwz     24, 44(3)
-       lwz     25, 48(3)
-       lwz     26, 52(3)
-       lwz     27, 56(3)
-       lwz     28, 60(3)
-       lwz     29, 64(3)
-       lwz     30, 68(3)
-       lwz     5, 72(3)
-       mtlr    5
-       lwz     5, 76(3)
-       mtcr    5
-       mr.     3, 4
-       bne     1f
-       li      3, 1
-1:     blr
-
diff --git a/lib/relocator.c b/lib/relocator.c
deleted file mode 100644 (file)
index 6a5acc5..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define MAX_OVERHEAD ((RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) \
-                     + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN) \
-                     + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)  \
-                     + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN))
-#define PRE_REGION_SIZE (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN)
-
-void *
-PREFIX (alloc) (grub_size_t size)
-{
-  char *playground;
-
-  playground = grub_malloc (size + MAX_OVERHEAD);
-  if (!playground)
-    return 0;
-
-  *(grub_size_t *) playground = size;
-
-  return playground + PRE_REGION_SIZE;
-}
-
-void *
-PREFIX (realloc) (void *relocator, grub_size_t size)
-{
-  char *playground;
-
-  if (!relocator)
-    return PREFIX (alloc) (size);
-
-  playground = (char *) relocator - PRE_REGION_SIZE;
-
-  playground = grub_realloc (playground, size + MAX_OVERHEAD);
-  if (!playground)
-    return 0;
-
-  *(grub_size_t *) playground = size;
-
-  return playground + PRE_REGION_SIZE;
-}
-
-void
-PREFIX(free) (void *relocator)
-{
-  if (relocator)
-    grub_free ((char *) relocator - PRE_REGION_SIZE);
-}
-
-grub_err_t
-PREFIX (boot) (void *relocator, grub_uint32_t dest,
-              struct grub_relocator32_state state)
-{
-  grub_size_t size;
-  char *playground;
-
-  playground = (char *) relocator - PRE_REGION_SIZE;
-  size = *(grub_size_t *) playground;
-
-  grub_dprintf ("relocator",
-               "Relocator: source: %p, destination: 0x%x, size: 0x%lx\n",
-               relocator, (unsigned) dest, (unsigned long) size);
-
-  /* Very unlikely condition: Relocator may risk overwrite itself.
-     Just move it a bit up.  */
-  if ((grub_addr_t) dest < (grub_addr_t) relocator
-      + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN)
-      && (grub_addr_t) dest + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)
-      > (grub_addr_t) relocator)
-    {
-      void *relocator_new = ((grub_uint8_t *) relocator)
-       + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)
-       + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN);
-      grub_dprintf ("relocator", "Overwrite condition detected moving "
-                   "relocator from %p to %p\n", relocator, relocator_new);
-      grub_memmove (relocator_new, relocator,
-                   (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN)
-                   + size
-                   + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN));
-      relocator = relocator_new;
-    }
-
-  if ((grub_addr_t) dest >= (grub_addr_t) relocator)
-    {
-      int overhead;
-      overhead = dest -
-       ALIGN_UP (dest - RELOCATOR_SIZEOF (backward) - RELOCATOR_ALIGN,
-                 RELOCATOR_ALIGN);
-      grub_dprintf ("relocator",
-                   "Backward relocator: code %p, source: %p, "
-                   "destination: 0x%x, size: 0x%lx\n",
-                   (char *) relocator - overhead,
-                   (char *) relocator - overhead,
-                   (unsigned) dest - overhead,
-                   (unsigned long) size + overhead);
-
-      write_call_relocator_bw ((char *) relocator - overhead,
-                              (char *) relocator - overhead,
-                              dest - overhead, size + overhead, state);
-    }
-  else
-    {
-      int overhead;
-
-      overhead = ALIGN_UP (dest + size, RELOCATOR_ALIGN)
-       + RELOCATOR_SIZEOF (forward) - (dest + size);
-      grub_dprintf ("relocator",
-                   "Forward relocator: code %p, source: %p, "
-                   "destination: 0x%x, size: 0x%lx\n",
-                   (char *) relocator + size + overhead
-                   - RELOCATOR_SIZEOF (forward),
-                   relocator, (unsigned) dest,
-                   (unsigned long) size + overhead);
-
-      write_call_relocator_fw ((char *) relocator + size + overhead
-                              - RELOCATOR_SIZEOF (forward),
-                              relocator, dest, size + overhead, state);
-    }
-
-  /* Not reached.  */
-  return GRUB_ERR_NONE;
-}
diff --git a/lib/sparc64/setjmp.S b/lib/sparc64/setjmp.S
deleted file mode 100644 (file)
index 0e23ecf..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-
-        .file   "setjmp.S"
-
-        .text
-
-/*
- * int grub_setjmp (grub_jmp_buf env)
- */
-FUNCTION(grub_setjmp)
-       stx     %o7, [%o0 + 0x00]
-       stx     %sp, [%o0 + 0x08]
-       stx     %fp, [%o0 + 0x10]
-       retl
-        clr    %o0
-
-/*
- * int grub_longjmp (grub_jmp_buf env, int val)
- */
-FUNCTION(grub_longjmp)
-       ldx     [%o0 + 0x10], %g1
-       movrz   %o1, 1, %o1
-       flushw
-       ldx     [%o0 + 0x00], %o7
-       ldx     [%o0 + 0x08], %fp
-       sub     %fp, 192, %sp
-       stx     %g1, [%sp + 2047 + (14 * 8)]
-       retl
-        restore %o1, 0, %o0
diff --git a/lib/x86_64/setjmp.S b/lib/x86_64/setjmp.S
deleted file mode 100644 (file)
index 621b09b..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-
-       .file   "setjmp.S"
-
-       .text
-
-/*
- *  jmp_buf:
- *   rbx rsp rbp r12 r13 r14 r15 rip
- *   0   8   16  24  32  40  48  56
- */
-
-/*
- * int grub_setjmp (grub_jmp_buf env)
- */
-FUNCTION(grub_setjmp)
-       pop     %rsi            /* Return address, and adjust the stack */
-       xorq    %rax, %rax
-       movq    %rbx, 0(%rdi)   /* RBX */
-       movq    %rsp, 8(%rdi)   /* RSP */
-       push    %rsi
-       movq    %rbp, 16(%rdi)  /* RBP */
-       movq    %r12, 24(%rdi)  /* R12 */
-       movq    %r13, 32(%rdi)  /* R13 */
-       movq    %r14, 40(%rdi)  /* R14 */
-       movq    %r15, 48(%rdi)  /* R15 */
-       movq    %rsi, 56(%rdi)  /* RSI */
-       ret
-
-/*
- * int grub_longjmp (grub_jmp_buf env, int val)
- */
-FUNCTION(grub_longjmp)
-       movl    %esi, %eax
-       orl     %eax, %eax
-       jnz     1f
-       incl    %eax
-1:
-
-       movq    (%rdi), %rbx
-       movq    8(%rdi), %rsp
-       movq    16(%rdi), %rbp
-       movq    24(%rdi), %r12
-       movq    32(%rdi), %r13
-       movq    40(%rdi), %r14
-       movq    48(%rdi), %r15
-       jmp     *56(%rdi)
diff --git a/loader/aout.c b/loader/aout.c
deleted file mode 100644 (file)
index 0254b6a..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *  Copyright (C) 2008 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 3 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/file.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/aout.h>
-
-int
-grub_aout_get_type (union grub_aout_header *header)
-{
-  int magic;
-
-  magic = AOUT_GETMAGIC (header->aout32);
-  if ((magic == AOUT32_OMAGIC) || (magic == AOUT32_NMAGIC) ||
-      (magic == AOUT32_ZMAGIC) || (magic == AOUT32_QMAGIC))
-    return AOUT_TYPE_AOUT32;
-  else if ((magic == AOUT64_OMAGIC) || (magic == AOUT64_NMAGIC) ||
-          (magic == AOUT64_ZMAGIC))
-    return AOUT_TYPE_AOUT64;
-  else
-    return AOUT_TYPE_NONE;
-}
-
-grub_err_t
-grub_aout_load (grub_file_t file, int offset,
-                grub_addr_t load_addr,
-               int load_size,
-                grub_addr_t bss_end_addr)
-{
-  if ((grub_file_seek (file, offset)) == (grub_off_t) - 1)
-    return grub_errno;
-
-  if (!load_size)
-    load_size = file->size - offset;
-
-  grub_file_read (file, (void *) load_addr, load_size);
-
-  if (grub_errno)
-    return grub_errno;
-
-  if (bss_end_addr)
-    grub_memset ((char *) load_addr + load_size, 0,
-                 bss_end_addr - load_addr - load_size);
-
-  return GRUB_ERR_NONE;
-}
diff --git a/loader/efi/appleloader.c b/loader/efi/appleloader.c
deleted file mode 100644 (file)
index dc42683..0000000
+++ /dev/null
@@ -1,332 +0,0 @@
-/* appleloader.c - apple legacy boot loader.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/loader.h>
-#include <grub/err.h>
-#include <grub/mm.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/efi/api.h>
-#include <grub/efi/efi.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static grub_dl_t my_mod;
-
-static grub_efi_handle_t image_handle;
-static grub_efi_char16_t *cmdline;
-
-static grub_err_t
-grub_appleloader_unload (void)
-{
-  grub_efi_boot_services_t *b;
-
-  b = grub_efi_system_table->boot_services;
-  efi_call_1 (b->unload_image, image_handle);
-
-  grub_free (cmdline);
-  cmdline = 0;
-
-  grub_dl_unref (my_mod);
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_appleloader_boot (void)
-{
-  grub_efi_boot_services_t *b;
-
-  b = grub_efi_system_table->boot_services;
-  efi_call_3 (b->start_image, image_handle, 0, 0);
-
-  grub_appleloader_unload ();
-
-  return grub_errno;
-}
-
-struct piwg_full_device_path
-{
-  struct grub_efi_memory_mapped_device_path comp1;
-  struct grub_efi_piwg_device_path comp2;
-  struct grub_efi_device_path end;
-};
-
-/* early 2006 Core Duo / Core Solo models  */
-static struct piwg_full_device_path devpath_1 =
-{
-  .comp1 =
-  {
-    .header = {
-      .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE,
-      .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE,
-      .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0}
-    },
-    .memory_type = GRUB_EFI_MEMORY_MAPPED_IO,
-    .start_address = 0xffe00000,
-    .end_address = 0xfff9ffff
-  },
-  .comp2 =
-  {
-    .header = {
-      .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
-      .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE,
-      .length = {sizeof (struct grub_efi_piwg_device_path), 0}
-    },
-    .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B,
-                                         0x01, 0xAE, 0xF2, 0xB7}}
-  },
-  .end =
-  {
-    .type = GRUB_EFI_END_DEVICE_PATH_TYPE,
-    .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
-    .length = {sizeof (struct grub_efi_device_path), 0}
-  }
-};
-
-/* mid-2006 Mac Pro (and probably other Core 2 models)  */
-static struct piwg_full_device_path devpath_2 =
-{
-  .comp1 =
-  {
-    .header = {
-      .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE,
-      .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE,
-      .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0}
-    },
-    .memory_type = GRUB_EFI_MEMORY_MAPPED_IO,
-    .start_address = 0xffe00000,
-    .end_address = 0xfff7ffff
-  },
-  .comp2 =
-  {
-    .header = {
-      .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
-      .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE,
-      .length = {sizeof (struct grub_efi_piwg_device_path), 0}
-    },
-    .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B,
-                                         0x01, 0xAE, 0xF2, 0xB7}}
-  },
-  .end =
-  {
-    .type = GRUB_EFI_END_DEVICE_PATH_TYPE,
-    .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
-    .length = {sizeof (struct grub_efi_device_path), 0}
-  }
-};
-
-/* mid-2007 MBP ("Santa Rosa" based models)  */
-static struct piwg_full_device_path devpath_3 =
-{
-  .comp1 =
-  {
-    .header = {
-      .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE,
-      .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE,
-      .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0}
-    },
-    .memory_type = GRUB_EFI_MEMORY_MAPPED_IO,
-    .start_address = 0xffe00000,
-    .end_address = 0xfff8ffff
-  },
-  .comp2 =
-  {
-    .header = {
-      .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
-      .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE,
-      .length = {sizeof (struct grub_efi_piwg_device_path), 0}
-    },
-    .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B,
-                                         0x01, 0xAE, 0xF2, 0xB7}}
-  },
-  .end =
-  {
-    .type = GRUB_EFI_END_DEVICE_PATH_TYPE,
-    .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
-    .length = {sizeof (struct grub_efi_device_path), 0}
-  }
-};
-
-/* early-2008 MBA  */
-static struct piwg_full_device_path devpath_4 =
-{
-  .comp1 =
-  {
-    .header = {
-      .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE,
-      .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE,
-      .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0}
-    },
-    .memory_type = GRUB_EFI_MEMORY_MAPPED_IO,
-    .start_address = 0xffc00000,
-    .end_address = 0xfff8ffff
-  },
-  .comp2 =
-  {
-    .header = {
-      .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
-      .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE,
-      .length = {sizeof (struct grub_efi_piwg_device_path), 0}
-    },
-    .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B,
-                                         0x01, 0xAE, 0xF2, 0xB7}}
-  },
-  .end =
-  {
-    .type = GRUB_EFI_END_DEVICE_PATH_TYPE,
-    .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
-    .length = {sizeof (struct grub_efi_device_path), 0}
-  }
-};
-
-/* late-2008 MB/MBP (NVidia chipset)  */
-static struct piwg_full_device_path devpath_5 =
-{
-  .comp1 =
-  {
-    .header = {
-      .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE,
-      .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE,
-      .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0}
-    },
-    .memory_type = GRUB_EFI_MEMORY_MAPPED_IO,
-    .start_address = 0xffcb4000,
-    .end_address = 0xffffbfff
-  },
-  .comp2 =
-  {
-    .header = {
-      .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
-      .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE,
-      .length = {sizeof (struct grub_efi_piwg_device_path), 0}
-    },
-    .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B,
-                                         0x01, 0xAE, 0xF2, 0xB7}}
-  },
-  .end =
-  {
-    .type = GRUB_EFI_END_DEVICE_PATH_TYPE,
-    .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
-    .length = {sizeof (struct grub_efi_device_path), 0}
-  }
-};
-
-struct devdata
-{
-  char *model;
-  grub_efi_device_path_t *devpath;
-};
-
-struct devdata devs[] =
-{
-  {"Core Duo/Solo", (grub_efi_device_path_t *) &devpath_1},
-  {"Mac Pro", (grub_efi_device_path_t *) &devpath_2},
-  {"MBP", (grub_efi_device_path_t *) &devpath_3},
-  {"MBA", (grub_efi_device_path_t *) &devpath_4},
-  {"MB NV", (grub_efi_device_path_t *) &devpath_5},
-  {NULL, NULL},
-};
-
-static grub_err_t
-grub_cmd_appleloader (grub_command_t cmd __attribute__ ((unused)),
-                      int argc, char *argv[])
-{
-  grub_efi_boot_services_t *b;
-  grub_efi_loaded_image_t *loaded_image;
-  struct devdata *pdev;
-
-  grub_dl_ref (my_mod);
-
-  /* Initialize some global variables.  */
-  image_handle = 0;
-
-  b = grub_efi_system_table->boot_services;
-
-  for (pdev = devs ; pdev->devpath ; pdev++)
-    if (efi_call_6 (b->load_image, 0, grub_efi_image_handle, pdev->devpath,
-                    NULL, 0, &image_handle) == GRUB_EFI_SUCCESS)
-      break;
-
-  if (! pdev->devpath)
-    {
-      grub_error (GRUB_ERR_BAD_OS, "can't find model");
-      goto fail;
-    }
-
-  grub_printf ("Model : %s\n", pdev->model);
-
-  loaded_image = grub_efi_get_loaded_image (image_handle);
-  if (! loaded_image)
-    {
-      grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
-      goto fail;
-    }
-
-  if (argc > 0)
-    {
-      int i, len;
-      grub_efi_char16_t *p16;
-
-      for (i = 0, len = 0; i < argc; i++)
-        len += grub_strlen (argv[i]) + 1;
-
-      len *= sizeof (grub_efi_char16_t);
-      cmdline = p16 = grub_malloc (len);
-      if (! cmdline)
-        goto fail;
-
-      for (i = 0; i < argc; i++)
-        {
-          char *p8;
-
-          p8 = argv[i];
-          while (*p8)
-            *(p16++) = *(p8++);
-
-          *(p16++) = ' ';
-        }
-      *(--p16) = 0;
-
-      loaded_image->load_options = cmdline;
-      loaded_image->load_options_size = len;
-    }
-
-  grub_loader_set (grub_appleloader_boot, grub_appleloader_unload, 0);
-
-  return 0;
-
- fail:
-
-  grub_dl_unref (my_mod);
-  return grub_errno;
-}
-
-static grub_command_t cmd;
-
-GRUB_MOD_INIT(appleloader)
-{
-  cmd = grub_register_command ("appleloader", grub_cmd_appleloader,
-                              "[OPTS]", N_("Boot legacy system."));
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(appleloader)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/loader/efi/chainloader.c b/loader/efi/chainloader.c
deleted file mode 100644 (file)
index a095ad9..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/* chainloader.c - boot another boot loader */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* TODO: support load options.  */
-
-#include <grub/loader.h>
-#include <grub/file.h>
-#include <grub/err.h>
-#include <grub/device.h>
-#include <grub/disk.h>
-#include <grub/misc.h>
-#include <grub/charset.h>
-#include <grub/mm.h>
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/efi/api.h>
-#include <grub/efi/efi.h>
-#include <grub/efi/disk.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static grub_dl_t my_mod;
-
-static grub_efi_physical_address_t address;
-static grub_efi_uintn_t pages;
-static grub_efi_device_path_t *file_path;
-static grub_efi_handle_t image_handle;
-static grub_efi_char16_t *cmdline;
-
-static grub_err_t
-grub_chainloader_unload (void)
-{
-  grub_efi_boot_services_t *b;
-
-  b = grub_efi_system_table->boot_services;
-  efi_call_1 (b->unload_image, image_handle);
-  efi_call_2 (b->free_pages, address, pages);
-
-  grub_free (file_path);
-  grub_free (cmdline);
-  cmdline = 0;
-
-  grub_dl_unref (my_mod);
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_chainloader_boot (void)
-{
-  grub_efi_boot_services_t *b;
-  grub_efi_status_t status;
-  grub_efi_uintn_t exit_data_size;
-  grub_efi_char16_t *exit_data;
-
-  b = grub_efi_system_table->boot_services;
-  status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data);
-  if (status != GRUB_EFI_SUCCESS)
-    {
-      if (exit_data)
-       {
-         char *buf;
-
-         buf = grub_malloc (exit_data_size * 4 + 1);
-         if (buf)
-           {
-             *grub_utf16_to_utf8 ((grub_uint8_t *) buf,
-                                  exit_data, exit_data_size) = 0;
-
-             grub_error (GRUB_ERR_BAD_OS, buf);
-             grub_free (buf);
-           }
-         else
-           grub_error (GRUB_ERR_BAD_OS, "unknown error");
-       }
-    }
-
-  if (exit_data)
-    efi_call_1 (b->free_pool, exit_data);
-
-  grub_chainloader_unload ();
-
-  return grub_errno;
-}
-
-static void
-copy_file_path (grub_efi_file_path_device_path_t *fp,
-               const char *str, grub_efi_uint16_t len)
-{
-  grub_efi_char16_t *p;
-  grub_efi_uint16_t size;
-
-  fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
-  fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
-  size = len * sizeof (grub_efi_char16_t) + sizeof (*fp);
-  fp->header.length[0] = (grub_efi_uint8_t) (size & 0xff);
-  fp->header.length[1] = (grub_efi_uint8_t) (size >> 8);
-  for (p = fp->path_name; len > 0; len--, p++, str++)
-    {
-      /* FIXME: this assumes that the path is in ASCII.  */
-      *p = (grub_efi_char16_t) (*str == '/' ? '\\' : *str);
-    }
-}
-
-static grub_efi_device_path_t *
-make_file_path (grub_efi_device_path_t *dp, const char *filename)
-{
-  char *dir_start;
-  char *dir_end;
-  grub_size_t size;
-  grub_efi_device_path_t *d;
-
-  dir_start = grub_strchr (filename, ')');
-  if (! dir_start)
-    dir_start = (char *) filename;
-  else
-    dir_start++;
-
-  dir_end = grub_strrchr (dir_start, '/');
-  if (! dir_end)
-    {
-      grub_error (GRUB_ERR_BAD_FILENAME, "invalid EFI file path");
-      return 0;
-    }
-
-  size = 0;
-  d = dp;
-  while (1)
-    {
-      size += GRUB_EFI_DEVICE_PATH_LENGTH (d);
-      if ((GRUB_EFI_END_ENTIRE_DEVICE_PATH (d)))
-       break;
-      d = GRUB_EFI_NEXT_DEVICE_PATH (d);
-    }
-
-  file_path = grub_malloc (size
-                          + ((grub_strlen (dir_start) + 1)
-                             * sizeof (grub_efi_char16_t))
-                          + sizeof (grub_efi_file_path_device_path_t) * 2);
-  if (! file_path)
-    return 0;
-
-  grub_memcpy (file_path, dp, size);
-
-  /* Fill the file path for the directory.  */
-  d = (grub_efi_device_path_t *) ((char *) file_path
-                                 + ((char *) d - (char *) dp));
-  grub_efi_print_device_path (d);
-  copy_file_path ((grub_efi_file_path_device_path_t *) d,
-                 dir_start, dir_end - dir_start);
-
-  /* Fill the file path for the file.  */
-  d = GRUB_EFI_NEXT_DEVICE_PATH (d);
-  copy_file_path ((grub_efi_file_path_device_path_t *) d,
-                 dir_end + 1, grub_strlen (dir_end + 1));
-
-  /* Fill the end of device path nodes.  */
-  d = GRUB_EFI_NEXT_DEVICE_PATH (d);
-  d->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
-  d->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
-  d->length[0] = sizeof (*d);
-  d->length[1] = 0;
-
-  return file_path;
-}
-
-static grub_err_t
-grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
-                     int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  grub_ssize_t size;
-  grub_efi_status_t status;
-  grub_efi_boot_services_t *b;
-  grub_efi_handle_t dev_handle = 0;
-  grub_device_t dev = 0;
-  grub_efi_device_path_t *dp = 0;
-  grub_efi_loaded_image_t *loaded_image;
-  char *filename;
-
-  if (argc == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
-  filename = argv[0];
-
-  grub_dl_ref (my_mod);
-
-  /* Initialize some global variables.  */
-  address = 0;
-  image_handle = 0;
-  file_path = 0;
-
-  b = grub_efi_system_table->boot_services;
-
-  file = grub_file_open (filename);
-  if (! file)
-    goto fail;
-
-  /* Get the root device's device path.  */
-  dev = grub_device_open (0);
-  if (! dev)
-    goto fail;
-
-  if (dev->disk)
-    {
-      dev_handle = grub_efidisk_get_device_handle (dev->disk);
-      if (dev_handle)
-       dp = grub_efi_get_device_path (dev_handle);
-    }
-
-  if (! dev->disk || ! dev_handle || ! dp)
-    {
-      grub_error (GRUB_ERR_BAD_DEVICE, "not a valid root device");
-      goto fail;
-    }
-
-  file_path = make_file_path (dp, filename);
-  if (! file_path)
-    goto fail;
-
-  grub_printf ("file path: ");
-  grub_efi_print_device_path (file_path);
-
-  size = grub_file_size (file);
-  pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12);
-
-  status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES,
-                             GRUB_EFI_LOADER_CODE,
-                             pages, &address);
-  if (status != GRUB_EFI_SUCCESS)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate %u pages", pages);
-      goto fail;
-    }
-
-  if (grub_file_read (file, (void *) ((grub_addr_t) address), size) != size)
-    {
-      if (grub_errno == GRUB_ERR_NONE)
-       grub_error (GRUB_ERR_BAD_OS, "too small");
-
-      goto fail;
-    }
-
-  status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path,
-                         (void *) ((grub_addr_t) address), size,
-                         &image_handle);
-  if (status != GRUB_EFI_SUCCESS)
-    {
-      if (status == GRUB_EFI_OUT_OF_RESOURCES)
-       grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources");
-      else
-       grub_error (GRUB_ERR_BAD_OS, "cannot load image");
-
-      goto fail;
-    }
-
-  /* LoadImage does not set a device handler when the image is
-     loaded from memory, so it is necessary to set it explicitly here.
-     This is a mess.  */
-  loaded_image = grub_efi_get_loaded_image (image_handle);
-  if (! loaded_image)
-    {
-      grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
-      goto fail;
-    }
-  loaded_image->device_handle = dev_handle;
-
-  grub_file_close (file);
-
-  if (argc > 1)
-    {
-      int i, len;
-      grub_efi_char16_t *p16;
-
-      for (i = 1, len = 0; i < argc; i++)
-        len += grub_strlen (argv[i]) + 1;
-
-      len *= sizeof (grub_efi_char16_t);
-      cmdline = p16 = grub_malloc (len);
-      if (! cmdline)
-        goto fail;
-
-      for (i = 1; i < argc; i++)
-        {
-          char *p8;
-
-          p8 = argv[i];
-          while (*p8)
-            *(p16++) = *(p8++);
-
-          *(p16++) = ' ';
-        }
-      *(--p16) = 0;
-
-      loaded_image->load_options = cmdline;
-      loaded_image->load_options_size = len;
-    }
-
-  grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
-  return 0;
-
- fail:
-
-  if (dev)
-    grub_device_close (dev);
-
-  if (file)
-    grub_file_close (file);
-
-  if (file_path)
-    grub_free (file_path);
-
-  if (address)
-    efi_call_2 (b->free_pages, address, pages);
-
-  grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_command_t cmd;
-
-GRUB_MOD_INIT(chainloader)
-{
-  cmd = grub_register_command ("chainloader", grub_cmd_chainloader,
-                              0, N_("Load another boot loader."));
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(chainloader)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c
deleted file mode 100644 (file)
index 3c7fe2f..0000000
+++ /dev/null
@@ -1,1326 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/loader.h>
-#include <grub/cpu/loader.h>
-#include <grub/cpu/bsd.h>
-#include <grub/i386/cpuid.h>
-#include <grub/machine/init.h>
-#include <grub/machine/memory.h>
-#include <grub/memory.h>
-#include <grub/file.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/elfload.h>
-#include <grub/env.h>
-#include <grub/misc.h>
-#include <grub/gzio.h>
-#include <grub/aout.h>
-#include <grub/command.h>
-#include <grub/extcmd.h>
-#include <grub/i18n.h>
-#include <grub/video.h>
-#ifdef GRUB_MACHINE_PCBIOS
-#include <grub/machine/biosnum.h>
-#endif
-#include <grub/disk.h>
-#include <grub/device.h>
-#include <grub/partition.h>
-
-#define ALIGN_DWORD(a) ALIGN_UP (a, 4)
-#define ALIGN_QWORD(a) ALIGN_UP (a, 8)
-#define ALIGN_VAR(a)   ((is_64bit) ? (ALIGN_QWORD(a)) : (ALIGN_DWORD(a)))
-#define ALIGN_PAGE(a)  ALIGN_UP (a, 4096)
-
-#define MOD_BUF_ALLOC_UNIT     4096
-
-static int kernel_type = KERNEL_TYPE_NONE;
-static grub_dl_t my_mod;
-static grub_addr_t entry, entry_hi, kern_start, kern_end;
-static grub_uint32_t bootflags;
-static char *mod_buf;
-static grub_uint32_t mod_buf_len, mod_buf_max, kern_end_mdofs;
-static int is_elf_kernel, is_64bit;
-static char *netbsd_root = NULL;
-static grub_uint32_t openbsd_root;
-
-static const struct grub_arg_option freebsd_opts[] =
-  {
-    {"dual", 'D', 0, N_("Display output on all consoles."), 0, 0},
-    {"serial", 'h', 0, N_("Use serial console."), 0, 0},
-    {"askname", 'a', 0, N_("Ask for file name to reboot from."), 0, 0},
-    {"cdrom", 'C', 0, N_("Use CDROM as root."), 0, 0},
-    {"config", 'c', 0, N_("Invoke user configuration routing."), 0, 0},
-    {"kdb", 'd', 0, N_("Enter in KDB on boot."), 0, 0},
-    {"gdb", 'g', 0, N_("Use GDB remote debugger instead of DDB."), 0, 0},
-    {"mute", 'm', 0, N_("Disable all boot output."), 0, 0},
-    {"nointr", 'n', 0, "", 0, 0},
-    {"pause", 'p', 0, N_("Wait for keypress after every line of output."), 0, 0},
-    {"quiet", 'q', 0, "", 0, 0},
-    {"dfltroot", 'r', 0, N_("Use compiled-in rootdev."), 0, 0},
-    {"single", 's', 0, N_("Boot into single mode."), 0, 0},
-    {"verbose", 'v', 0, N_("Boot with verbose messages."), 0, 0},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-static const grub_uint32_t freebsd_flags[] =
-{
-  FREEBSD_RB_DUAL, FREEBSD_RB_SERIAL, FREEBSD_RB_ASKNAME,
-  FREEBSD_RB_CDROM, FREEBSD_RB_CONFIG, FREEBSD_RB_KDB,
-  FREEBSD_RB_GDB, FREEBSD_RB_MUTE, FREEBSD_RB_NOINTR,
-  FREEBSD_RB_PAUSE, FREEBSD_RB_QUIET, FREEBSD_RB_DFLTROOT,
-  FREEBSD_RB_SINGLE, FREEBSD_RB_VERBOSE, 0
-};
-
-static const struct grub_arg_option openbsd_opts[] =
-  {
-    {"askname", 'a', 0, N_("Ask for file name to reboot from."), 0, 0},
-    {"halt", 'b', 0, N_("Don't reboot, just halt."), 0, 0},
-    {"config", 'c', 0, N_("Change configured devices."), 0, 0},
-    {"single", 's', 0, N_("Boot into single mode."), 0, 0},
-    {"kdb", 'd', 0, N_("Enter in KDB on boot."), 0, 0},
-    {"root", 'r', 0, N_("Set root device."), "wdXY", ARG_TYPE_STRING},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-static const grub_uint32_t openbsd_flags[] =
-{
-  OPENBSD_RB_ASKNAME, OPENBSD_RB_HALT, OPENBSD_RB_CONFIG,
-  OPENBSD_RB_SINGLE, OPENBSD_RB_KDB, 0
-};
-
-#define OPENBSD_ROOT_ARG (ARRAY_SIZE (openbsd_flags) - 1)
-
-static const struct grub_arg_option netbsd_opts[] =
-  {
-    {"no-smp", '1', 0, N_("Disable SMP."), 0, 0},
-    {"no-acpi", '2', 0, N_("Disable ACPI."), 0, 0},
-    {"askname", 'a', 0, N_("Ask for file name to reboot from."), 0, 0},
-    {"halt", 'b', 0, N_("Don't reboot, just halt."), 0, 0},
-    {"config", 'c', 0, N_("Change configured devices."), 0, 0},
-    {"kdb", 'd', 0, N_("Enter in KDB on boot."), 0, 0},
-    {"miniroot", 'm', 0, "", 0, 0},
-    {"quiet", 'q', 0, N_("Don't display boot diagnostic messages."), 0, 0},
-    {"single", 's', 0, N_("Boot into single mode."), 0, 0},
-    {"verbose", 'v', 0, N_("Boot with verbose messages."), 0, 0},
-    {"debug", 'x', 0, N_("Boot with debug messages."), 0, 0},
-    {"silent", 'z', 0, N_("Supress normal output (warnings remain)."), 0, 0},
-    {"root", 'r', 0, N_("Set root device."), N_("DEVICE"), ARG_TYPE_STRING},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-static const grub_uint32_t netbsd_flags[] =
-{
-  NETBSD_AB_NOSMP, NETBSD_AB_NOACPI, NETBSD_RB_ASKNAME,
-  NETBSD_RB_HALT, NETBSD_RB_USERCONFIG, NETBSD_RB_KDB,
-  NETBSD_RB_MINIROOT, NETBSD_AB_QUIET, NETBSD_RB_SINGLE,
-  NETBSD_AB_VERBOSE, NETBSD_AB_DEBUG, NETBSD_AB_SILENT, 0
-};
-
-#define NETBSD_ROOT_ARG (ARRAY_SIZE (netbsd_flags) - 1)
-
-static void
-grub_bsd_get_device (grub_uint32_t * biosdev,
-                    grub_uint32_t * unit,
-                    grub_uint32_t * slice, grub_uint32_t * part)
-{
-  grub_device_t dev;
-
-#ifdef GRUB_MACHINE_PCBIOS
-  *biosdev = grub_get_root_biosnumber () & 0xff;
-#else
-  *biosdev = 0xff;
-#endif
-  *unit = (*biosdev & 0x7f);
-  *slice = 0xff;
-  *part = 0xff;
-  dev = grub_device_open (0);
-  if (dev && dev->disk && dev->disk->partition)
-    {
-      if (dev->disk->partition->parent)
-       {
-         *part = dev->disk->partition->number;
-         *slice = dev->disk->partition->parent->number + 1;
-       }
-      else
-       *slice = dev->disk->partition->number + 1;
-    }
-  if (dev)
-    grub_device_close (dev);
-}
-
-grub_err_t
-grub_freebsd_add_meta (grub_uint32_t type, void *data, grub_uint32_t len)
-{
-  if (mod_buf_max < mod_buf_len + len + 8)
-    {
-      char *new_buf;
-
-      do
-       {
-         mod_buf_max += MOD_BUF_ALLOC_UNIT;
-       }
-      while (mod_buf_max < mod_buf_len + len + 8);
-
-      new_buf = grub_malloc (mod_buf_max);
-      if (!new_buf)
-       return grub_errno;
-
-      grub_memcpy (new_buf, mod_buf, mod_buf_len);
-      grub_free (mod_buf);
-
-      mod_buf = new_buf;
-    }
-
-  *((grub_uint32_t *) (mod_buf + mod_buf_len)) = type;
-  *((grub_uint32_t *) (mod_buf + mod_buf_len + 4)) = len;
-  mod_buf_len += 8;
-
-  if (len)
-    grub_memcpy (mod_buf + mod_buf_len, data, len);
-
-  mod_buf_len = ALIGN_VAR (mod_buf_len + len);
-
-  return GRUB_ERR_NONE;
-}
-
-struct grub_e820_mmap
-{
-  grub_uint64_t addr;
-  grub_uint64_t size;
-  grub_uint32_t type;
-} __attribute__((packed));
-#define GRUB_E820_RAM        1
-#define GRUB_E820_RESERVED   2
-#define GRUB_E820_ACPI       3
-#define GRUB_E820_NVS        4
-#define GRUB_E820_EXEC_CODE  5
-
-static grub_err_t
-grub_freebsd_add_mmap (void)
-{
-  grub_size_t len = 0;
-  struct grub_e820_mmap *mmap_buf = 0;
-  struct grub_e820_mmap *mmap = 0;
-  int isfirstrun = 1;
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
-                            grub_uint32_t type)
-    {
-      /* FreeBSD assumes that first 64KiB are available.
-        Not always true but try to prevent panic somehow. */
-      if (isfirstrun && addr != 0)
-       {
-         if (mmap)
-           {
-             mmap->addr = 0;
-             mmap->size = (addr < 0x10000) ? addr : 0x10000;
-             mmap->type = GRUB_E820_RAM;
-             mmap++;
-           }
-         else
-           len += sizeof (struct grub_e820_mmap);
-       }
-      isfirstrun = 0;
-      if (mmap)
-       {
-         mmap->addr = addr;
-         mmap->size = size;
-         switch (type)
-           {
-           case GRUB_MACHINE_MEMORY_AVAILABLE:
-             mmap->type = GRUB_E820_RAM;
-             break;
-
-#ifdef GRUB_MACHINE_MEMORY_ACPI
-           case GRUB_MACHINE_MEMORY_ACPI:
-             mmap->type = GRUB_E820_ACPI;
-             break;
-#endif
-
-#ifdef GRUB_MACHINE_MEMORY_NVS
-           case GRUB_MACHINE_MEMORY_NVS:
-             mmap->type = GRUB_E820_NVS;
-             break;
-#endif
-
-           default:
-#ifdef GRUB_MACHINE_MEMORY_CODE
-           case GRUB_MACHINE_MEMORY_CODE:
-#endif
-#ifdef GRUB_MACHINE_MEMORY_RESERVED
-           case GRUB_MACHINE_MEMORY_RESERVED:
-#endif
-             mmap->type = GRUB_E820_RESERVED;
-             break;
-           }
-
-         /* Merge regions if possible. */
-         if (mmap != mmap_buf && mmap->type == mmap[-1].type &&
-             mmap->addr == mmap[-1].addr + mmap[-1].size)
-           mmap[-1].size += mmap->size;
-         else
-           mmap++;
-       }
-      else
-       len += sizeof (struct grub_e820_mmap);
-
-      return 0;
-    }
-
-  grub_mmap_iterate (hook);
-  mmap_buf = mmap = grub_malloc (len);
-  if (! mmap)
-    return grub_errno;
-
-  isfirstrun = 1;
-  grub_mmap_iterate (hook);
-
-  len = (mmap - mmap_buf) * sizeof (struct grub_e820_mmap);
-  int i;
-  for (i = 0; i < mmap - mmap_buf; i++)
-    grub_dprintf ("bsd", "smap %d, %d:%llx - %llx\n", i,
-                 mmap_buf[i].type,
-                 (unsigned long long) mmap_buf[i].addr,
-                 (unsigned long long) mmap_buf[i].size);
-
-  grub_dprintf ("bsd", "%d entries in smap\n", mmap - mmap_buf);
-  grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
-                        FREEBSD_MODINFOMD_SMAP, mmap_buf, len);
-
-  grub_free (mmap_buf);
-
-  return grub_errno;
-}
-
-grub_err_t
-grub_freebsd_add_meta_module (char *filename, char *type, int argc, char **argv,
-                             grub_addr_t addr, grub_uint32_t size)
-{
-  char *name;
-  name = grub_strrchr (filename, '/');
-  if (name)
-    name++;
-  else
-    name = filename;
-  if (grub_strcmp (type, "/boot/zfs/zpool.cache") == 0)
-    name = "/boot/zfs/zpool.cache";
-
-  if (grub_freebsd_add_meta (FREEBSD_MODINFO_NAME, name,
-                            grub_strlen (name) + 1))
-    return grub_errno;
-
-  if (is_64bit)
-    {
-      grub_uint64_t addr64 = addr, size64 = size;
-      if ((grub_freebsd_add_meta (FREEBSD_MODINFO_TYPE, type,
-                             grub_strlen (type) + 1)) ||
-         (grub_freebsd_add_meta (FREEBSD_MODINFO_ADDR, &addr64,
-                                 sizeof (addr64))) ||
-         (grub_freebsd_add_meta (FREEBSD_MODINFO_SIZE, &size64,
-                                 sizeof (size64))))
-       return grub_errno;
-    }
-  else
-    {
-      if ((grub_freebsd_add_meta (FREEBSD_MODINFO_TYPE, type,
-                                 grub_strlen (type) + 1)) ||
-         (grub_freebsd_add_meta (FREEBSD_MODINFO_ADDR, &addr,
-                                 sizeof (addr))) ||
-         (grub_freebsd_add_meta (FREEBSD_MODINFO_SIZE, &size,
-                                 sizeof (size))))
-       return grub_errno;
-    }
-
-  if (argc)
-    {
-      int i, n;
-
-      n = 0;
-      for (i = 0; i < argc; i++)
-       {
-         n += grub_strlen (argv[i]) + 1;
-       }
-
-      if (n)
-       {
-         char cmdline[n], *p;
-
-         p = cmdline;
-         for (i = 0; i < argc; i++)
-           {
-             grub_strcpy (p, argv[i]);
-             p += grub_strlen (argv[i]);
-             *(p++) = ' ';
-           }
-         *p = 0;
-
-         if (grub_freebsd_add_meta (FREEBSD_MODINFO_ARGS, cmdline, n))
-           return grub_errno;
-       }
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-static void
-grub_freebsd_list_modules (void)
-{
-  grub_uint32_t pos = 0;
-
-  grub_printf ("  %-18s  %-18s%14s%14s\n", "name", "type", "addr", "size");
-  while (pos < mod_buf_len)
-    {
-      grub_uint32_t type, size;
-
-      type = *((grub_uint32_t *) (mod_buf + pos));
-      size = *((grub_uint32_t *) (mod_buf + pos + 4));
-      pos += 8;
-      switch (type)
-       {
-       case FREEBSD_MODINFO_NAME:
-       case FREEBSD_MODINFO_TYPE:
-         grub_printf ("  %-18s", mod_buf + pos);
-         break;
-       case FREEBSD_MODINFO_ADDR:
-         {
-           grub_addr_t addr;
-
-           addr = *((grub_addr_t *) (mod_buf + pos));
-           grub_printf ("    0x%08x", addr);
-           break;
-         }
-       case FREEBSD_MODINFO_SIZE:
-         {
-           grub_uint32_t len;
-
-           len = *((grub_uint32_t *) (mod_buf + pos));
-           grub_printf ("    0x%08x\n", len);
-         }
-       }
-
-      pos = ALIGN_VAR (pos + size);
-    }
-}
-
-/* This function would be here but it's under different license. */
-#include "bsd_pagetable.c"
-
-struct gdt_descriptor
-{
-  grub_uint16_t limit;
-  void *base;
-} __attribute__ ((packed));
-
-static grub_err_t
-grub_freebsd_boot (void)
-{
-  struct grub_freebsd_bootinfo bi;
-  char *p;
-  grub_uint32_t bootdev, biosdev, unit, slice, part;
-
-  auto int iterate_env (struct grub_env_var *var);
-  int iterate_env (struct grub_env_var *var)
-  {
-    if ((!grub_memcmp (var->name, "kFreeBSD.", sizeof("kFreeBSD.") - 1)) && (var->name[sizeof("kFreeBSD.") - 1]))
-      {
-       grub_strcpy (p, &var->name[sizeof("kFreeBSD.") - 1]);
-       p += grub_strlen (p);
-       *(p++) = '=';
-       grub_strcpy (p, var->value);
-       p += grub_strlen (p) + 1;
-      }
-
-    return 0;
-  }
-
-  grub_memset (&bi, 0, sizeof (bi));
-  bi.version = FREEBSD_BOOTINFO_VERSION;
-  bi.length = sizeof (bi);
-
-  grub_bsd_get_device (&biosdev, &unit, &slice, &part);
-  bootdev = (FREEBSD_B_DEVMAGIC + ((slice + 1) << FREEBSD_B_SLICESHIFT) +
-            (unit << FREEBSD_B_UNITSHIFT) + (part << FREEBSD_B_PARTSHIFT));
-
-  bi.boot_device = biosdev;
-
-  p = (char *) kern_end;
-
-  grub_env_iterate (iterate_env);
-
-  if (p != (char *) kern_end)
-    {
-      *(p++) = 0;
-
-      bi.environment = kern_end;
-      kern_end = ALIGN_PAGE ((grub_uint32_t) p);
-    }
-
-  if (is_elf_kernel)
-    {
-      grub_addr_t md_ofs;
-      int ofs;
-
-      if (grub_freebsd_add_meta (FREEBSD_MODINFO_END, 0, 0))
-       return grub_errno;
-
-      grub_memcpy ((char *) kern_end, mod_buf, mod_buf_len);
-      bi.tags = kern_end;
-
-      kern_end = ALIGN_PAGE (kern_end + mod_buf_len);
-
-      if (is_64bit)
-       kern_end += 4096 * 4;
-
-      md_ofs = bi.tags + kern_end_mdofs;
-      ofs = (is_64bit) ? 16 : 12;
-      *((grub_uint32_t *) md_ofs) = kern_end;
-      md_ofs -= ofs;
-      *((grub_uint32_t *) md_ofs) = bi.environment;
-      md_ofs -= ofs;
-      *((grub_uint32_t *) md_ofs) = bootflags;
-    }
-
-  bi.kern_end = kern_end;
-
-  grub_video_set_mode ("text", 0, 0);
-
-  if (is_64bit)
-    {
-      grub_uint32_t *gdt;
-      grub_uint8_t *trampoline;
-      void (*launch_trampoline) (grub_addr_t entry_lo, ...)
-       __attribute__ ((cdecl, regparm (0)));
-      grub_uint8_t *pagetable;
-
-      struct gdt_descriptor *gdtdesc;
-
-      pagetable = (grub_uint8_t *) (kern_end - 16384);
-      fill_bsd64_pagetable (pagetable);
-
-      /* Create GDT. */
-      gdt = (grub_uint32_t *) (kern_end - 4096);
-      gdt[0] = 0;
-      gdt[1] = 0;
-      gdt[2] = 0;
-      gdt[3] = 0x00209800;
-      gdt[4] = 0;
-      gdt[5] = 0x00008000;
-
-      /* Create GDT descriptor. */
-      gdtdesc = (struct gdt_descriptor *) (kern_end - 4096 + 24);
-      gdtdesc->limit = 24;
-      gdtdesc->base = gdt;
-
-      /* Prepare trampoline. */
-      trampoline = (grub_uint8_t *) (kern_end - 4096 + 24
-                                    + sizeof (struct gdt_descriptor));
-      launch_trampoline = (void  __attribute__ ((cdecl, regparm (0)))
-                          (*) (grub_addr_t entry_lo, ...)) trampoline;
-      grub_bsd64_trampoline_gdt = (grub_uint32_t) gdtdesc;
-      grub_bsd64_trampoline_selfjump
-       = (grub_uint32_t) (trampoline + 6
-                          + ((grub_uint8_t *) &grub_bsd64_trampoline_selfjump
-                             - &grub_bsd64_trampoline_start));
-
-      /* Copy trampoline. */
-      grub_memcpy (trampoline, &grub_bsd64_trampoline_start,
-                  &grub_bsd64_trampoline_end - &grub_bsd64_trampoline_start);
-
-      /* Launch trampoline. */
-      launch_trampoline (entry, entry_hi, pagetable, bi.tags,
-                        kern_end);
-    }
-  else
-    grub_unix_real_boot (entry, bootflags | FREEBSD_RB_BOOTINFO, bootdev,
-                        0, 0, 0, &bi, bi.tags, kern_end);
-
-  /* Not reached.  */
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_openbsd_boot (void)
-{
-  char *buf = (char *) GRUB_BSD_TEMP_BUFFER;
-  struct grub_openbsd_bios_mmap *pm;
-  struct grub_openbsd_bootargs *pa;
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
-    {
-      pm->addr = addr;
-      pm->len = size;
-
-      switch (type)
-        {
-        case GRUB_MACHINE_MEMORY_AVAILABLE:
-         pm->type = OPENBSD_MMAP_AVAILABLE;
-         break;
-
-        case GRUB_MACHINE_MEMORY_ACPI:
-         pm->type = OPENBSD_MMAP_ACPI;
-         break;
-
-        case GRUB_MACHINE_MEMORY_NVS:
-         pm->type = OPENBSD_MMAP_NVS;
-         break;
-
-       default:
-         pm->type = OPENBSD_MMAP_RESERVED;
-         break;
-       }
-      pm++;
-
-      return 0;
-    }
-
-  pa = (struct grub_openbsd_bootargs *) buf;
-
-  pa->ba_type = OPENBSD_BOOTARG_MMAP;
-  pm = (struct grub_openbsd_bios_mmap *) (pa + 1);
-  grub_mmap_iterate (hook);
-
-  /* Memory map terminator.  */
-  pm->addr = 0;
-  pm->len = 0;
-  pm->type = 0;
-  pm++;
-
-  pa->ba_size = (char *) pm - (char *) pa;
-  pa->ba_next = (struct grub_openbsd_bootargs *) pm;
-  pa = pa->ba_next;
-  pa->ba_type = OPENBSD_BOOTARG_END;
-  pa++;
-
-  grub_video_set_mode ("text", 0, 0);
-
-  grub_unix_real_boot (entry, bootflags, openbsd_root, OPENBSD_BOOTARG_APIVER,
-                      0, (grub_uint32_t) (grub_mmap_get_upper () >> 10),
-                      (grub_uint32_t) (grub_mmap_get_lower () >> 10),
-                      (char *) pa - buf, buf);
-
-  /* Not reached.  */
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_netbsd_boot (void)
-{
-  struct grub_netbsd_bootinfo *bootinfo;
-  int count = 0;
-  struct grub_netbsd_btinfo_mmap_header *mmap;
-  struct grub_netbsd_btinfo_mmap_entry *pm;
-  void *curarg;
-
-  auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
-                                  grub_uint64_t size __attribute__ ((unused)),
-                                  grub_uint32_t type __attribute__ ((unused)))
-  {
-    count++;
-    return 0;
-  }
-
-  auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
-  {
-    pm->addr = addr;
-    pm->len = size;
-
-    switch (type)
-      {
-      case GRUB_MACHINE_MEMORY_AVAILABLE:
-       pm->type = NETBSD_MMAP_AVAILABLE;
-       break;
-
-      case GRUB_MACHINE_MEMORY_ACPI:
-       pm->type = NETBSD_MMAP_ACPI;
-       break;
-
-      case GRUB_MACHINE_MEMORY_NVS:
-       pm->type = NETBSD_MMAP_NVS;
-       break;
-
-      default:
-       pm->type = NETBSD_MMAP_RESERVED;
-       break;
-      }
-    pm++;
-
-    return 0;
-  }
-
-  grub_mmap_iterate (count_hook);
-
-  if (kern_end + sizeof (struct grub_netbsd_btinfo_rootdevice)
-      + sizeof (struct grub_netbsd_bootinfo)
-      + sizeof (struct grub_netbsd_btinfo_mmap_header)
-      + count * sizeof (struct grub_netbsd_btinfo_mmap_entry)
-      > grub_os_area_addr + grub_os_area_size)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
-
-  curarg = mmap = (struct grub_netbsd_btinfo_mmap_header *) kern_end;
-  pm = (struct grub_netbsd_btinfo_mmap_entry *) (mmap + 1);
-
-  grub_mmap_iterate (fill_hook);
-  mmap->common.type = NETBSD_BTINFO_MEMMAP;
-  mmap->common.len = (char *) pm - (char *) mmap;
-  mmap->count = count;
-  curarg = pm;
-
-  if (netbsd_root)
-    {
-      struct grub_netbsd_btinfo_rootdevice *rootdev;
-
-      rootdev = (struct grub_netbsd_btinfo_rootdevice *) curarg;
-
-      rootdev->common.len = sizeof (struct grub_netbsd_btinfo_rootdevice);
-      rootdev->common.type = NETBSD_BTINFO_ROOTDEVICE;
-      grub_strncpy (rootdev->devname, netbsd_root, sizeof (rootdev->devname));
-
-      bootinfo = (struct grub_netbsd_bootinfo *) (rootdev + 1);
-      bootinfo->bi_count = 2;
-      bootinfo->bi_data[0] = mmap;
-      bootinfo->bi_data[1] = rootdev;
-    }
-  else
-    {
-      bootinfo = (struct grub_netbsd_bootinfo *) curarg;
-      bootinfo->bi_count = 1;
-      bootinfo->bi_data[0] = mmap;
-    }
-
-  grub_video_set_mode ("text", 0, 0);
-
-  grub_unix_real_boot (entry, bootflags, 0, bootinfo,
-                      0, (grub_uint32_t) (grub_mmap_get_upper () >> 10),
-                      (grub_uint32_t) (grub_mmap_get_lower () >> 10));
-
-  /* Not reached.  */
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_bsd_unload (void)
-{
-  if (mod_buf)
-    {
-      grub_free (mod_buf);
-      mod_buf = 0;
-      mod_buf_max = 0;
-    }
-
-  kernel_type = KERNEL_TYPE_NONE;
-  grub_dl_unref (my_mod);
-
-  grub_free (netbsd_root);
-  netbsd_root = NULL;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_bsd_load_aout (grub_file_t file)
-{
-  grub_addr_t load_addr, bss_end_addr;
-  int ofs, align_page;
-  union grub_aout_header ah;
-
-  if ((grub_file_seek (file, 0)) == (grub_off_t) - 1)
-    return grub_errno;
-
-  if (grub_file_read (file, &ah, sizeof (ah)) != sizeof (ah))
-    return grub_error (GRUB_ERR_READ_ERROR, "cannot read the a.out header");
-
-  if (grub_aout_get_type (&ah) != AOUT_TYPE_AOUT32)
-    return grub_error (GRUB_ERR_BAD_OS, "invalid a.out header");
-
-  entry = ah.aout32.a_entry & 0xFFFFFF;
-
-  if (AOUT_GETMAGIC (ah.aout32) == AOUT32_ZMAGIC)
-    {
-      load_addr = entry;
-      ofs = 0x1000;
-      align_page = 0;
-    }
-  else
-    {
-      load_addr = entry & 0xF00000;
-      ofs = sizeof (struct grub_aout32_header);
-      align_page = 1;
-    }
-
-  if (load_addr < 0x100000)
-    return grub_error (GRUB_ERR_BAD_OS, "load address below 1M");
-
-  kern_start = load_addr;
-  kern_end = load_addr + ah.aout32.a_text + ah.aout32.a_data;
-  if (align_page)
-    kern_end = ALIGN_PAGE (kern_end);
-
-  if (ah.aout32.a_bss)
-    {
-      kern_end += ah.aout32.a_bss;
-      if (align_page)
-       kern_end = ALIGN_PAGE (kern_end);
-
-      bss_end_addr = kern_end;
-    }
-  else
-    bss_end_addr = 0;
-
-  return grub_aout_load (file, ofs, load_addr,
-                        ah.aout32.a_text + ah.aout32.a_data, bss_end_addr);
-}
-
-static grub_err_t
-grub_bsd_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr, int *do_load)
-{
-  Elf32_Addr paddr;
-
-  if (phdr->p_type != PT_LOAD
-      && phdr->p_type != PT_DYNAMIC)
-    {
-      *do_load = 0;
-      return 0;
-    }
-
-  *do_load = 1;
-  phdr->p_paddr &= 0xFFFFFF;
-  paddr = phdr->p_paddr;
-
-  if ((paddr < grub_os_area_addr)
-      || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
-    return grub_error (GRUB_ERR_OUT_OF_RANGE, "address 0x%x is out of range",
-                      paddr);
-
-  if ((!kern_start) || (paddr < kern_start))
-    kern_start = paddr;
-
-  if (paddr + phdr->p_memsz > kern_end)
-    kern_end = paddr + phdr->p_memsz;
-
-  *addr = paddr;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_bsd_elf64_hook (Elf64_Phdr * phdr, grub_addr_t * addr, int *do_load)
-{
-  Elf64_Addr paddr;
-
-  if (phdr->p_type != PT_LOAD
-      && phdr->p_type != PT_DYNAMIC)
-    {
-      *do_load = 0;
-      return 0;
-    }
-
-  *do_load = 1;
-  paddr = phdr->p_paddr & 0xffffff;
-
-  if ((paddr < grub_os_area_addr)
-      || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
-    return grub_error (GRUB_ERR_OUT_OF_RANGE, "address 0x%x is out of range",
-                      paddr);
-
-  if ((!kern_start) || (paddr < kern_start))
-    kern_start = paddr;
-
-  if (paddr + phdr->p_memsz > kern_end)
-    kern_end = paddr + phdr->p_memsz;
-
-  *addr = paddr;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_bsd_load_elf (grub_elf_t elf)
-{
-  kern_start = kern_end = 0;
-
-  if (grub_elf_is_elf32 (elf))
-    {
-      entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFF;
-      return grub_elf32_load (elf, grub_bsd_elf32_hook, 0, 0);
-    }
-  else if (grub_elf_is_elf64 (elf))
-    {
-      is_64bit = 1;
-
-      if (! grub_cpuid_has_longmode)
-       return grub_error (GRUB_ERR_BAD_OS, "your CPU does not implement AMD64 architecture");
-
-      /* FreeBSD has 64-bit entry point.  */
-      if (kernel_type == KERNEL_TYPE_FREEBSD)
-       {
-         entry = elf->ehdr.ehdr64.e_entry & 0xffffffff;
-         entry_hi = (elf->ehdr.ehdr64.e_entry >> 32) & 0xffffffff;
-       }
-      else
-       {
-         entry = elf->ehdr.ehdr64.e_entry & 0x0fffffff;
-         entry_hi = 0;
-       }
-      return grub_elf64_load (elf, grub_bsd_elf64_hook, 0, 0);
-    }
-  else
-    return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
-}
-
-static grub_err_t
-grub_bsd_load (int argc, char *argv[])
-{
-  grub_file_t file;
-  grub_elf_t elf;
-
-  grub_dl_ref (my_mod);
-
-  grub_loader_unset ();
-
-  if (argc == 0)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
-      goto fail;
-    }
-
-  file = grub_gzfile_open (argv[0], 1);
-  if (!file)
-    goto fail;
-
-  elf = grub_elf_file (file);
-  if (elf)
-    {
-      is_elf_kernel = 1;
-      grub_bsd_load_elf (elf);
-      grub_elf_close (elf);
-    }
-  else
-    {
-      is_elf_kernel = 0;
-      grub_errno = 0;
-      grub_bsd_load_aout (file);
-      grub_file_close (file);
-    }
-
-fail:
-
-  if (grub_errno != GRUB_ERR_NONE)
-    grub_dl_unref (my_mod);
-
-  return grub_errno;
-}
-
-static grub_uint32_t
-grub_bsd_parse_flags (const struct grub_arg_list *state,
-                     const grub_uint32_t * flags)
-{
-  grub_uint32_t result = 0;
-  unsigned i;
-
-  for (i = 0; flags[i]; i++)
-    if (state[i].set)
-      result |= flags[i];
-
-  return result;
-}
-
-static grub_err_t
-grub_cmd_freebsd (grub_extcmd_t cmd, int argc, char *argv[])
-{
-  kernel_type = KERNEL_TYPE_FREEBSD;
-  bootflags = grub_bsd_parse_flags (cmd->state, freebsd_flags);
-
-  if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
-    {
-      kern_end = ALIGN_PAGE (kern_end);
-      if (is_elf_kernel)
-       {
-         grub_err_t err;
-         grub_uint64_t data = 0;
-         grub_file_t file;
-         int len = is_64bit ? 8 : 4;
-
-         err = grub_freebsd_add_meta_module (argv[0], is_64bit
-                                             ? FREEBSD_MODTYPE_KERNEL64
-                                             : FREEBSD_MODTYPE_KERNEL,
-                                             argc - 1, argv + 1,
-                                             kern_start,
-                                             kern_end - kern_start);
-         if (err)
-           return err;
-
-         file = grub_gzfile_open (argv[0], 1);
-         if (! file)
-           return grub_errno;
-
-         if (is_64bit)
-           err = grub_freebsd_load_elf_meta64 (file, &kern_end);
-         else
-           err = grub_freebsd_load_elf_meta32 (file, &kern_end);
-         if (err)
-           return err;
-
-         err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
-                                      FREEBSD_MODINFOMD_HOWTO, &data, 4);
-         if (err)
-           return err;
-
-         err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
-                                      FREEBSD_MODINFOMD_ENVP, &data, len);
-         if (err)
-           return err;
-
-         err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
-                                      FREEBSD_MODINFOMD_KERNEND, &data, len);
-         if (err)
-           return err;
-
-         kern_end_mdofs = mod_buf_len - len;
-
-         err = grub_freebsd_add_mmap ();
-         if (err)
-           return err;
-       }
-      grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 1);
-    }
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_cmd_openbsd (grub_extcmd_t cmd, int argc, char *argv[])
-{
-  grub_uint32_t bootdev;
-
-  kernel_type = KERNEL_TYPE_OPENBSD;
-  bootflags = grub_bsd_parse_flags (cmd->state, openbsd_flags);
-
-  if (cmd->state[OPENBSD_ROOT_ARG].set)
-    {
-      const char *arg = cmd->state[OPENBSD_ROOT_ARG].arg;
-      int unit, part;
-      if (*(arg++) != 'w' || *(arg++) != 'd')
-       return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                          "only device specifications of form "
-                          "wd<number><lowercase letter> are supported");
-
-      unit = grub_strtoul (arg, (char **) &arg, 10);
-      if (! (arg && *arg >= 'a' && *arg <= 'z'))
-       return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                          "only device specifications of form "
-                          "wd<number><lowercase letter> are supported");
-
-      part = *arg - 'a';
-
-      bootdev = (OPENBSD_B_DEVMAGIC + (unit << OPENBSD_B_UNITSHIFT) +
-                (part << OPENBSD_B_PARTSHIFT));
-    }
-  else
-    bootdev = 0;
-
-  if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
-    {
-      grub_loader_set (grub_openbsd_boot, grub_bsd_unload, 1);
-      openbsd_root = bootdev;
-    }
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_cmd_netbsd (grub_extcmd_t cmd, int argc, char *argv[])
-{
-  kernel_type = KERNEL_TYPE_NETBSD;
-  bootflags = grub_bsd_parse_flags (cmd->state, netbsd_flags);
-
-  if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
-    {
-      grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 1);
-      if (cmd->state[NETBSD_ROOT_ARG].set)
-       netbsd_root = grub_strdup (cmd->state[NETBSD_ROOT_ARG].arg);
-    }
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_cmd_freebsd_loadenv (grub_command_t cmd __attribute__ ((unused)),
-                         int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  char *buf = 0, *curr, *next;
-  int len;
-
-  if (kernel_type == KERNEL_TYPE_NONE)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "you need to load the kernel first");
-
-  if (kernel_type != KERNEL_TYPE_FREEBSD)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "only FreeBSD supports environment");
-
-  if (argc == 0)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "no filename");
-      goto fail;
-    }
-
-  file = grub_gzfile_open (argv[0], 1);
-  if ((!file) || (!file->size))
-    goto fail;
-
-  len = file->size;
-  buf = grub_malloc (len + 1);
-  if (!buf)
-    goto fail;
-
-  if (grub_file_read (file, buf, len) != len)
-    goto fail;
-
-  buf[len] = 0;
-
-  next = buf;
-  while (next)
-    {
-      char *p;
-
-      curr = next;
-      next = grub_strchr (curr, '\n');
-      if (next)
-       {
-
-         p = next - 1;
-         while (p > curr)
-           {
-             if ((*p != '\r') && (*p != ' ') && (*p != '\t'))
-               break;
-             p--;
-           }
-
-         if ((p > curr) && (*p == '"'))
-           p--;
-
-         *(p + 1) = 0;
-         next++;
-       }
-
-      if (*curr == '#')
-       continue;
-
-      p = grub_strchr (curr, '=');
-      if (!p)
-       continue;
-
-      *(p++) = 0;
-
-      if (*curr)
-       {
-         char *name;
-
-         if (*p == '"')
-           p++;
-
-         name = grub_xasprintf ("kFreeBSD.%s", curr);
-         if (!name)
-           goto fail;
-         if (grub_env_set (name, p))
-           {
-             grub_free (name);
-             goto fail;
-           }
-         grub_free (name);
-       }
-    }
-
-fail:
-  grub_free (buf);
-
-  if (file)
-    grub_file_close (file);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)),
-                        int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  grub_err_t err;
-  int modargc;
-  char **modargv;
-  char *type;
-
-  if (kernel_type == KERNEL_TYPE_NONE)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "you need to load the kernel first");
-
-  if (kernel_type != KERNEL_TYPE_FREEBSD)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "only FreeBSD supports module");
-
-  if (!is_elf_kernel)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "only ELF kernel supports module");
-
-  /* List the current modules if no parameter.  */
-  if (!argc)
-    {
-      grub_freebsd_list_modules ();
-      return 0;
-    }
-
-  file = grub_gzfile_open (argv[0], 1);
-  if ((!file) || (!file->size))
-    goto fail;
-
-  if (kern_end + file->size > grub_os_area_addr + grub_os_area_size)
-    {
-      grub_error (GRUB_ERR_OUT_OF_RANGE, "not enough memory for the module");
-      goto fail;
-    }
-
-  grub_file_read (file, (void *) kern_end, file->size);
-  if (grub_errno)
-    goto fail;
-
-  modargc = argc - 1;
-  modargv = argv + 1;
-
-  if (modargc && (! grub_memcmp (modargv[0], "type=", 5)))
-    {
-      type = &modargv[0][5];
-      modargc--;
-      modargv++;
-    }
-  else
-    type = FREEBSD_MODTYPE_RAW;
-
-  err = grub_freebsd_add_meta_module (argv[0], type, modargc, modargv,
-                                     kern_end, file->size);
-  if (err)
-    goto fail;
-
-  kern_end = ALIGN_PAGE (kern_end + file->size);
-
-fail:
-  if (file)
-    grub_file_close (file);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_cmd_freebsd_module_elf (grub_command_t cmd __attribute__ ((unused)),
-                            int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  grub_err_t err;
-
-  if (kernel_type == KERNEL_TYPE_NONE)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "you need to load the kernel first");
-
-  if (kernel_type != KERNEL_TYPE_FREEBSD)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "only FreeBSD supports module");
-
-  if (! is_elf_kernel)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "only ELF kernel supports module");
-
-  /* List the current modules if no parameter.  */
-  if (! argc)
-    {
-      grub_freebsd_list_modules ();
-      return 0;
-    }
-
-  file = grub_gzfile_open (argv[0], 1);
-  if (!file)
-    return grub_errno;
-  if (!file->size)
-    {
-      grub_file_close (file);
-      return grub_errno;
-    }
-
-  if (is_64bit)
-    err = grub_freebsd_load_elfmodule_obj64 (file, argc, argv, &kern_end);
-  else
-    err = grub_freebsd_load_elfmodule32 (file, argc, argv, &kern_end);
-  grub_file_close (file);
-
-  return err;
-}
-
-
-static grub_extcmd_t cmd_freebsd, cmd_openbsd, cmd_netbsd;
-static grub_command_t cmd_freebsd_loadenv, cmd_freebsd_module;
-static grub_command_t cmd_freebsd_module_elf;
-
-GRUB_MOD_INIT (bsd)
-{
-  cmd_freebsd = grub_register_extcmd ("kfreebsd", grub_cmd_freebsd,
-                                     GRUB_COMMAND_FLAG_BOTH,
-                                     N_("FILE"), N_("Load kernel of FreeBSD."),
-                                     freebsd_opts);
-  cmd_openbsd = grub_register_extcmd ("kopenbsd", grub_cmd_openbsd,
-                                     GRUB_COMMAND_FLAG_BOTH,
-                                     N_("FILE"), N_("Load kernel of OpenBSD."),
-                                     openbsd_opts);
-  cmd_netbsd = grub_register_extcmd ("knetbsd", grub_cmd_netbsd,
-                                    GRUB_COMMAND_FLAG_BOTH,
-                                    N_("FILE"), N_("Load kernel of NetBSD."),
-                                    netbsd_opts);
-  cmd_freebsd_loadenv =
-    grub_register_command ("kfreebsd_loadenv", grub_cmd_freebsd_loadenv,
-                          0, N_("Load FreeBSD env."));
-  cmd_freebsd_module =
-    grub_register_command ("kfreebsd_module", grub_cmd_freebsd_module,
-                          0, N_("Load FreeBSD kernel module."));
-  cmd_freebsd_module_elf =
-    grub_register_command ("kfreebsd_module_elf", grub_cmd_freebsd_module_elf,
-                          0, N_("Load FreeBSD kernel module (ELF)."));
-
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI (bsd)
-{
-  grub_unregister_extcmd (cmd_freebsd);
-  grub_unregister_extcmd (cmd_openbsd);
-  grub_unregister_extcmd (cmd_netbsd);
-
-  grub_unregister_command (cmd_freebsd_loadenv);
-  grub_unregister_command (cmd_freebsd_module);
-  grub_unregister_command (cmd_freebsd_module_elf);
-
-  if (mod_buf)
-    {
-      grub_free (mod_buf);
-      mod_buf = 0;
-      mod_buf_max = 0;
-    }
-}
diff --git a/loader/i386/bsd32.c b/loader/i386/bsd32.c
deleted file mode 100644 (file)
index 26704c4..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#define SUFFIX(x) x ## 32
-#define GRUB_TARGET_WORDSIZE 32
-#define OBJSYM 0
-#include <grub/types.h>
-typedef grub_uint32_t grub_freebsd_addr_t;
-#include "bsdXX.c"
diff --git a/loader/i386/bsd64.c b/loader/i386/bsd64.c
deleted file mode 100644 (file)
index f8aad1c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#define SUFFIX(x) x ## 64
-#define GRUB_TARGET_WORDSIZE 64
-#define OBJSYM 1
-#include <grub/types.h>
-typedef grub_uint64_t grub_freebsd_addr_t;
-#include "bsdXX.c"
diff --git a/loader/i386/bsdXX.c b/loader/i386/bsdXX.c
deleted file mode 100644 (file)
index cd5ba85..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-#include <grub/loader.h>
-#include <grub/cpu/bsd.h>
-#include <grub/mm.h>
-#include <grub/elf.h>
-#include <grub/misc.h>
-#include <grub/i386/loader.h>
-
-#define ALIGN_PAGE(a)  ALIGN_UP (a, 4096)
-
-static inline grub_err_t
-load (grub_file_t file, void *where, grub_off_t off, grub_size_t size)
-{
-  if (PTR_TO_UINT32 (where) + size > grub_os_area_addr + grub_os_area_size)
-    return grub_error (GRUB_ERR_OUT_OF_RANGE,
-                      "not enough memory for the module");
-  if (grub_file_seek (file, off) == (grub_off_t) -1)
-    return grub_errno;
-  if (grub_file_read (file, where, size)
-      != (grub_ssize_t) size)
-    {
-      if (grub_errno)
-       return grub_errno;
-      else
-       return grub_error (GRUB_ERR_BAD_OS, "file is truncated");
-    }
-  return GRUB_ERR_NONE;
-}
-
-static inline grub_err_t
-read_headers (grub_file_t file, Elf_Ehdr *e, char **shdr)
-{
- if (grub_file_seek (file, 0) == (grub_off_t) -1)
-    return grub_errno;
-
-  if (grub_file_read (file, (char *) e, sizeof (*e)) != sizeof (*e))
-    {
-      if (grub_errno)
-       return grub_errno;
-      else
-       return grub_error (GRUB_ERR_BAD_OS, "file is too short");
-    }
-
-  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");
-
-  if (e->e_ident[EI_CLASS] != SUFFIX (ELFCLASS))
-    return grub_error (GRUB_ERR_BAD_OS, "invalid arch dependent ELF magic");
-
-  *shdr = grub_malloc (e->e_shnum * e->e_shentsize);
-  if (! *shdr)
-    return grub_errno;
-
-  if (grub_file_seek (file, e->e_shoff) == (grub_off_t) -1)
-    return grub_errno;
-
-  if (grub_file_read (file, *shdr, e->e_shnum * e->e_shentsize)
-      != e->e_shnum * e->e_shentsize)
-    {
-      if (grub_errno)
-       return grub_errno;
-      else
-       return grub_error (GRUB_ERR_BAD_OS, "file is truncated");
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-/* On i386 FreeBSD uses "elf module" approarch for 32-bit variant
-   and "elf obj module" for 64-bit variant. However it may differ on other
-   platforms. So I keep both versions.  */
-#if OBJSYM
-grub_err_t
-SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc,
-                                         char *argv[], grub_addr_t *kern_end)
-{
-  Elf_Ehdr e;
-  Elf_Shdr *s;
-  char *shdr = 0;
-  grub_addr_t curload, module;
-  grub_err_t err;
-
-  err = read_headers (file, &e, &shdr);
-  if (err)
-    return err;
-
-  curload = module = ALIGN_PAGE (*kern_end);
-
-  for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
-                                               + e.e_shnum * e.e_shentsize);
-       s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
-    {
-      if (s->sh_size == 0)
-       continue;
-
-      if (s->sh_addralign)
-       curload = ALIGN_UP (curload, s->sh_addralign);
-      s->sh_addr = curload;
-
-      grub_dprintf ("bsd", "loading section to %x, size %d, align %d\n",
-                   (unsigned) curload, (int) s->sh_size,
-                   (int) s->sh_addralign);
-
-      switch (s->sh_type)
-       {
-       default:
-       case SHT_PROGBITS:
-         err = load (file, UINT_TO_PTR (curload), s->sh_offset, s->sh_size);
-         if (err)
-           return err;
-         break;
-       case SHT_NOBITS:
-         if (curload + s->sh_size > grub_os_area_addr + grub_os_area_size)
-           return grub_error (GRUB_ERR_OUT_OF_RANGE,
-                              "not enough memory for the module");
-         grub_memset (UINT_TO_PTR (curload), 0, s->sh_size);
-         break;
-       }
-      curload += s->sh_size;
-    }
-
-  *kern_end = ALIGN_PAGE (curload);
-
-  err = grub_freebsd_add_meta_module (argv[0], FREEBSD_MODTYPE_ELF_MODULE_OBJ,
-                                     argc - 1, argv + 1, module,
-                                     curload - module);
-  if (! err)
-    err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA
-                                | FREEBSD_MODINFOMD_ELFHDR,
-                                &e, sizeof (e));
-  if (! err)
-    err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA
-                                | FREEBSD_MODINFOMD_SHDR,
-                                shdr, e.e_shnum * e.e_shentsize);
-
-  return err;
-}
-
-#else
-
-grub_err_t
-SUFFIX (grub_freebsd_load_elfmodule) (grub_file_t file, int argc, char *argv[],
-                                     grub_addr_t *kern_end)
-{
-  Elf_Ehdr e;
-  Elf_Shdr *s;
-  char *shdr = 0;
-  grub_addr_t curload, module;
-  grub_err_t err;
-
-  err = read_headers (file, &e, &shdr);
-  if (err)
-    return err;
-
-  curload = module = ALIGN_PAGE (*kern_end);
-
-  for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr
-                                               + e.e_shnum * e.e_shentsize);
-       s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
-    {
-      if (s->sh_size == 0)
-       continue;
-
-      if (! (s->sh_flags & SHF_ALLOC))
-       continue;
-
-      grub_dprintf ("bsd", "loading section to %x, size %d, align %d\n",
-                   (unsigned) curload, (int) s->sh_size,
-                   (int) s->sh_addralign);
-
-      switch (s->sh_type)
-       {
-       default:
-       case SHT_PROGBITS:
-         err = load (file, UINT_TO_PTR (module + s->sh_addr),
-                     s->sh_offset, s->sh_size);
-         if (err)
-           return err;
-         break;
-       case SHT_NOBITS:
-         if (module + s->sh_addr + s->sh_size
-             > grub_os_area_addr + grub_os_area_size)
-           return grub_error (GRUB_ERR_OUT_OF_RANGE,
-                              "not enough memory for the module");
-         grub_memset (UINT_TO_PTR (module + s->sh_addr), 0, s->sh_size);
-         break;
-       }
-      if (curload < module + s->sh_addr + s->sh_size)
-       curload = module + s->sh_addr + s->sh_size;
-    }
-
-  load (file, UINT_TO_PTR (module), 0, sizeof (e));
-  if (curload < module + sizeof (e))
-    curload = module + sizeof (e);
-
-  load (file, UINT_TO_PTR (curload), e.e_shoff,
-       e.e_shnum * e.e_shentsize);
-  e.e_shoff = curload - module;
-  curload +=  e.e_shnum * e.e_shentsize;
-
-  load (file, UINT_TO_PTR (curload), e.e_phoff,
-       e.e_phnum * e.e_phentsize);
-  e.e_phoff = curload - module;
-  curload +=  e.e_phnum * e.e_phentsize;
-
-  *kern_end = curload;
-
-  grub_freebsd_add_meta_module (argv[0], FREEBSD_MODTYPE_ELF_MODULE,
-                               argc - 1, argv + 1, module,
-                               curload - module);
-  return SUFFIX (grub_freebsd_load_elf_meta) (file, kern_end);
-}
-
-#endif
-
-grub_err_t
-SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end)
-{
-  grub_err_t err;
-  Elf_Ehdr e;
-  Elf_Shdr *s;
-  char *shdr = 0;
-  unsigned symoff, stroff, symsize, strsize;
-  grub_addr_t curload;
-  grub_freebsd_addr_t symstart, symend, symentsize, dynamic;
-  Elf_Sym *sym;
-  const char *str;
-  unsigned i;
-
-  err = read_headers (file, &e, &shdr);
-  if (err)
-    return err;
-
-  err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
-                              FREEBSD_MODINFOMD_ELFHDR, &e,
-                              sizeof (e));
-  if (err)
-    return err;
-
-  for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr
-                                               + e.e_shnum * e.e_shentsize);
-       s = (Elf_Shdr *) ((char *) s + e.e_shentsize))
-      if (s->sh_type == SHT_SYMTAB)
-       break;
-  if (s >= (Elf_Shdr *) ((char *) shdr
-                       + e.e_shnum * e.e_shentsize))
-    return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
-  symoff = s->sh_offset;
-  symsize = s->sh_size;
-  symentsize = s->sh_entsize;
-  s = (Elf_Shdr *) (shdr + e.e_shentsize * s->sh_link);
-  stroff = s->sh_offset;
-  strsize = s->sh_size;
-
-  if (*kern_end + 4 * sizeof (grub_freebsd_addr_t) + symsize + strsize
-      > grub_os_area_addr + grub_os_area_size)
-    return grub_error (GRUB_ERR_OUT_OF_RANGE,
-                      "not enough memory for kernel symbols");
-
-  symstart = curload = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t));
-  *((grub_freebsd_addr_t *) UINT_TO_PTR (curload)) = symsize;
-  curload += sizeof (grub_freebsd_addr_t);
-  if (grub_file_seek (file, symoff) == (grub_off_t) -1)
-    return grub_errno;
-  sym = (Elf_Sym *) UINT_TO_PTR (curload);
-  if (grub_file_read (file, UINT_TO_PTR (curload), symsize) !=
-      (grub_ssize_t) symsize)
-    {
-      if (! grub_errno)
-       return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
-      return grub_errno;
-    }
-  curload += symsize;
-
-  *((grub_freebsd_addr_t *) UINT_TO_PTR (curload)) = strsize;
-  curload += sizeof (grub_freebsd_addr_t);
-  if (grub_file_seek (file, stroff) == (grub_off_t) -1)
-    return grub_errno;
-  str = (char *) UINT_TO_PTR (curload);
-  if (grub_file_read (file, UINT_TO_PTR (curload), strsize)
-      != (grub_ssize_t) strsize)
-    {
-      if (! grub_errno)
-       return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
-      return grub_errno;
-    }
-  curload += strsize;
-  curload = ALIGN_UP (curload, sizeof (grub_freebsd_addr_t));
-  symend = curload;
-
-  for (i = 0;
-       i * symentsize < symsize;
-       i++, sym = (Elf_Sym *) ((char *) sym + symentsize))
-    {
-      const char *name = str + sym->st_name;
-      if (grub_strcmp (name, "_DYNAMIC") == 0)
-       break;
-    }
-
-  if (i * symentsize < symsize)
-    {
-      dynamic = sym->st_value;
-      grub_dprintf ("bsd", "dynamic = %llx\n", (unsigned long long) dynamic);
-      err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
-                                  FREEBSD_MODINFOMD_DYNAMIC, &dynamic,
-                                  sizeof (dynamic));
-      if (err)
-       return err;
-    }
-
-  err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
-                              FREEBSD_MODINFOMD_SSYM, &symstart,
-                              sizeof (symstart));
-  if (err)
-    return err;
-
-  err = grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
-                              FREEBSD_MODINFOMD_ESYM, &symend,
-                              sizeof (symend));
-  if (err)
-    return err;
-  *kern_end = ALIGN_PAGE (curload);
-
-  return GRUB_ERR_NONE;
-}
diff --git a/loader/i386/bsd_helper.S b/loader/i386/bsd_helper.S
deleted file mode 100644 (file)
index 25aee3a..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008, 2009 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-
-       .p2align        2
-
-
-       .code32
-
-/*
- * Use cdecl calling convention for *BSD kernels.
- */
-
-FUNCTION(grub_unix_real_boot)
-
-       /* Interrupts should be disabled.  */
-        cli
-
-       /* Discard `grub_unix_real_boot' return address.  */
-        popl    %eax
-
-        /* Fetch `entry' address ...  */
-        popl   %eax
-
-        /*
-         * ... and put our return address in its place. The kernel will
-         * ignore it, but it expects %esp to point to it.
-         */
-        call   *%eax
diff --git a/loader/i386/bsd_pagetable.c b/loader/i386/bsd_pagetable.c
deleted file mode 100644 (file)
index 0fd3937..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (c) 1998  Michael Smith <msmith@freebsd.org>
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Based on the code from FreeBSD originally distributed under the
-   following terms: */
-
-/*-
- * Copyright (c) 1998  Michael Smith <msmith@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-
-static void
-fill_bsd64_pagetable (grub_uint8_t *target)
-{
-  grub_uint64_t *pt2, *pt3, *pt4;
-  int i;
-
-#define PG_V           0x001
-#define PG_RW          0x002
-#define PG_U           0x004
-#define PG_PS          0x080
-
-  pt4 = (grub_uint64_t *) target;
-  pt3 = (grub_uint64_t *) (target + 4096);
-  pt2 = (grub_uint64_t *) (target + 8192);
-
-  grub_memset ((char *) target, 0, 4096 * 3);
-
-  /*
-   * This is kinda brutal, but every single 1GB VM memory segment points to
-   * the same first 1GB of physical memory.  But it is how BSD expects
-   * it to be.
-   */
-  for (i = 0; i < 512; i++)
-    {
-      /* Each slot of the level 4 pages points to the same level 3 page */
-      pt4[i] = (grub_addr_t) &pt3[0];
-      pt4[i] |= PG_V | PG_RW | PG_U;
-
-      /* Each slot of the level 3 pages points to the same level 2 page */
-      pt3[i] = (grub_addr_t) &pt2[0];
-      pt3[i] |= PG_V | PG_RW | PG_U;
-
-      /* The level 2 page slots are mapped with 2MB pages for 1GB. */
-      pt2[i] = i * (2 * 1024 * 1024);
-      pt2[i] |= PG_V | PG_RW | PG_PS | PG_U;
-    }
-}
diff --git a/loader/i386/bsd_trampoline.S b/loader/i386/bsd_trampoline.S
deleted file mode 100644 (file)
index a568fff..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (c) 2003  Peter Wemm <peter@FreeBSD.org>
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Based on the code from FreeBSD originally distributed under the
-   following terms: */
-
-/*-
- * Copyright (c) 2003  Peter Wemm <peter@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-
-#define MSR_EFER       0xc0000080
-#define EFER_LME       0x00000100
-#define CR4_PAE                0x00000020
-#define CR4_PSE                0x00000010
-#define CR0_PG         0x80000000
-
-#include <grub/symbol.h>
-
-       .p2align        2
-
-       .code32
-
-
-VARIABLE(grub_bsd64_trampoline_start)
-
-       /* Discard `grub_unix_real_boot' return address.  */
-        popl    %eax
-
-        /* entry  */
-        popl   %edi
-
-        /* entry_hi  */
-        popl   %esi
-
-       cli
-
-       /* Turn on EFER.LME.  */
-       movl    $MSR_EFER, %ecx
-       rdmsr
-       orl     $EFER_LME, %eax
-        wrmsr
-
-       /* Turn on PAE.  */
-       movl    %cr4, %eax
-       orl     $(CR4_PAE | CR4_PSE), %eax
-       movl    %eax, %cr4
-
-       /* Set %cr3 for PT4.  */
-       popl    %eax
-       movl    %eax, %cr3
-
-       /* Push a dummy return address.  */
-       pushl   %eax
-
-       /* Turn on paging (implicitly sets EFER.LMA).  */
-       movl    %cr0, %eax
-       orl     $CR0_PG, %eax
-       movl    %eax, %cr0
-
-       /* Now we're in compatibility mode. set %cs for long mode.  */
-       /* lgdt */
-       .byte 0x0f
-       .byte 0x01
-       .byte 0x15
-VARIABLE (grub_bsd64_trampoline_gdt)
-       .long 0x0
-
-       /* ljmp */
-       .byte 0xea
-VARIABLE (grub_bsd64_trampoline_selfjump)
-       .long 0x0
-       .word 0x08
-
-       .code64
-
-bsd64_longmode:
-         /* We're still running V=P, jump to entry point.  */
-       movl    %esi, %eax
-       salq    $32, %rax
-       orq     %rdi, %rax
-       pushq   %rax
-       ret
-VARIABLE(grub_bsd64_trampoline_end)
diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c
deleted file mode 100644 (file)
index a6db22e..0000000
+++ /dev/null
@@ -1,1021 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/loader.h>
-#include <grub/machine/loader.h>
-#include <grub/file.h>
-#include <grub/disk.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/term.h>
-#include <grub/cpu/linux.h>
-#include <grub/efi/api.h>
-#include <grub/efi/efi.h>
-#include <grub/efi/uga_draw.h>
-#include <grub/pci.h>
-#include <grub/command.h>
-#include <grub/memory.h>
-#include <grub/i18n.h>
-
-#define GRUB_LINUX_CL_OFFSET           0x1000
-#define GRUB_LINUX_CL_END_OFFSET       0x2000
-
-#define NEXT_MEMORY_DESCRIPTOR(desc, size)      \
-  ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
-
-static grub_dl_t my_mod;
-
-static grub_size_t linux_mem_size;
-static int loaded;
-static void *real_mode_mem;
-static void *prot_mode_mem;
-static void *initrd_mem;
-static grub_efi_uintn_t real_mode_pages;
-static grub_efi_uintn_t prot_mode_pages;
-static grub_efi_uintn_t initrd_pages;
-static void *mmap_buf;
-
-static grub_uint8_t gdt[] __attribute__ ((aligned(16))) =
-  {
-    /* NULL.  */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    /* Reserved.  */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    /* Code segment.  */
-    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00,
-    /* Data segment.  */
-    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
-  };
-
-struct gdt_descriptor
-{
-  grub_uint16_t limit;
-  void *base;
-} __attribute__ ((packed));
-
-static struct gdt_descriptor gdt_desc =
-  {
-    sizeof (gdt) - 1,
-    gdt
-  };
-
-struct idt_descriptor
-{
-  grub_uint16_t limit;
-  void *base;
-} __attribute__ ((packed));
-
-static struct idt_descriptor idt_desc =
-  {
-    0,
-    0
-  };
-
-static inline grub_size_t
-page_align (grub_size_t size)
-{
-  return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
-}
-
-/* Find the optimal number of pages for the memory map. Is it better to
-   move this code to efi/mm.c?  */
-static grub_efi_uintn_t
-find_mmap_size (void)
-{
-  static grub_efi_uintn_t mmap_size = 0;
-
-  if (mmap_size != 0)
-    return mmap_size;
-
-  mmap_size = (1 << 12);
-  while (1)
-    {
-      int ret;
-      grub_efi_memory_descriptor_t *mmap;
-      grub_efi_uintn_t desc_size;
-
-      mmap = grub_malloc (mmap_size);
-      if (! mmap)
-       return 0;
-
-      ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
-      grub_free (mmap);
-
-      if (ret < 0)
-       grub_fatal ("cannot get memory map");
-      else if (ret > 0)
-       break;
-
-      mmap_size += (1 << 12);
-    }
-
-  /* Increase the size a bit for safety, because GRUB allocates more on
-     later, and EFI itself may allocate more.  */
-  mmap_size += (1 << 12);
-
-  return page_align (mmap_size);
-}
-
-static void
-free_pages (void)
-{
-  if (real_mode_mem)
-    {
-      grub_efi_free_pages ((grub_addr_t) real_mode_mem, real_mode_pages);
-      real_mode_mem = 0;
-    }
-
-  if (prot_mode_mem)
-    {
-      grub_efi_free_pages ((grub_addr_t) prot_mode_mem, prot_mode_pages);
-      prot_mode_mem = 0;
-    }
-
-  if (initrd_mem)
-    {
-      grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
-      initrd_mem = 0;
-    }
-}
-
-/* Allocate pages for the real mode code and the protected mode code
-   for linux as well as a memory map buffer.  */
-static int
-allocate_pages (grub_size_t prot_size)
-{
-  grub_efi_uintn_t desc_size;
-  grub_efi_memory_descriptor_t *mmap, *mmap_end;
-  grub_efi_uintn_t mmap_size, tmp_mmap_size;
-  grub_efi_memory_descriptor_t *desc;
-  grub_size_t real_size;
-
-  /* Make sure that each size is aligned to a page boundary.  */
-  real_size = GRUB_LINUX_CL_END_OFFSET;
-  prot_size = page_align (prot_size);
-  mmap_size = find_mmap_size ();
-
-  grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
-               (unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
-
-  /* Calculate the number of pages; Combine the real mode code with
-     the memory map buffer for simplicity.  */
-  real_mode_pages = ((real_size + mmap_size) >> 12);
-  prot_mode_pages = (prot_size >> 12);
-
-  /* Initialize the memory pointers with NULL for convenience.  */
-  real_mode_mem = 0;
-  prot_mode_mem = 0;
-
-  /* Read the memory map temporarily, to find free space.  */
-  mmap = grub_malloc (mmap_size);
-  if (! mmap)
-    return 0;
-
-  tmp_mmap_size = mmap_size;
-  if (grub_efi_get_memory_map (&tmp_mmap_size, mmap, 0, &desc_size, 0) <= 0)
-    grub_fatal ("cannot get memory map");
-
-  mmap_end = NEXT_MEMORY_DESCRIPTOR (mmap, tmp_mmap_size);
-
-  /* First, find free pages for the real mode code
-     and the memory map buffer.  */
-  for (desc = mmap;
-       desc < mmap_end;
-       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
-    {
-      /* Probably it is better to put the real mode code in the traditional
-        space for safety.  */
-      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
-         && desc->physical_start <= 0x90000
-         && desc->num_pages >= real_mode_pages)
-       {
-         grub_efi_physical_address_t physical_end;
-         grub_efi_physical_address_t addr;
-
-         physical_end = desc->physical_start + (desc->num_pages << 12);
-         if (physical_end > 0x90000)
-           physical_end = 0x90000;
-
-         grub_dprintf ("linux", "physical_start = %x, physical_end = %x\n",
-                       (unsigned) desc->physical_start,
-                       (unsigned) physical_end);
-         addr = physical_end - real_size - mmap_size;
-         if (addr < 0x10000)
-           continue;
-
-         grub_dprintf ("linux", "trying to allocate %u pages at %lx\n",
-                       (unsigned) real_mode_pages, (unsigned long) addr);
-         real_mode_mem = grub_efi_allocate_pages (addr, real_mode_pages);
-         if (! real_mode_mem)
-           grub_fatal ("cannot allocate pages");
-
-         desc->num_pages -= real_mode_pages;
-         break;
-       }
-    }
-
-  if (! real_mode_mem)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
-      goto fail;
-    }
-
-  mmap_buf = (void *) ((char *) real_mode_mem + real_size);
-
-  /* Next, find free pages for the protected mode code.  */
-  /* XXX what happens if anything is using this address?  */
-  prot_mode_mem = grub_efi_allocate_pages (0x100000, prot_mode_pages + 1);
-  if (! prot_mode_mem)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                 "cannot allocate protected mode pages");
-      goto fail;
-    }
-
-  grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
-               "prot_mode_mem = %lx, prot_mode_pages = %x\n",
-               (unsigned long) real_mode_mem, (unsigned) real_mode_pages,
-               (unsigned long) prot_mode_mem, (unsigned) prot_mode_pages);
-
-  grub_free (mmap);
-  return 1;
-
- fail:
-  grub_free (mmap);
-  free_pages ();
-  return 0;
-}
-
-static void
-grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num,
-                     grub_uint64_t start, grub_uint64_t size,
-                     grub_uint32_t type)
-{
-  int n = *e820_num;
-
-  if (n >= GRUB_E820_MAX_ENTRY)
-    grub_fatal ("Too many e820 memory map entries");
-
-  if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) &&
-      (e820_map[n - 1].type == type))
-      e820_map[n - 1].size += size;
-  else
-    {
-      e820_map[n].addr = start;
-      e820_map[n].size = size;
-      e820_map[n].type = type;
-      (*e820_num)++;
-    }
-}
-
-#ifdef __x86_64__
-extern grub_uint8_t grub_linux_trampoline_start[];
-extern grub_uint8_t grub_linux_trampoline_end[];
-#endif
-
-static grub_err_t
-grub_linux_boot (void)
-{
-  struct linux_kernel_params *params;
-  grub_efi_uintn_t mmap_size;
-  grub_efi_uintn_t map_key;
-  grub_efi_uintn_t desc_size;
-  grub_efi_uint32_t desc_version;
-  int e820_num;
-
-  params = real_mode_mem;
-
-  grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n",
-               (unsigned) params->code32_start,
-               (unsigned long) &(idt_desc.limit),
-               (unsigned long) &(gdt_desc.limit));
-  grub_dprintf ("linux", "idt = %x:%lx, gdt = %x:%lx\n",
-               (unsigned) idt_desc.limit, (unsigned long) idt_desc.base,
-               (unsigned) gdt_desc.limit, (unsigned long) gdt_desc.base);
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
-    {
-      switch (type)
-        {
-        case GRUB_MACHINE_MEMORY_AVAILABLE:
-         grub_e820_add_region (params->e820_map, &e820_num,
-                               addr, size, GRUB_E820_RAM);
-         break;
-
-#ifdef GRUB_MACHINE_MEMORY_ACPI
-        case GRUB_MACHINE_MEMORY_ACPI:
-         grub_e820_add_region (params->e820_map, &e820_num,
-                               addr, size, GRUB_E820_ACPI);
-         break;
-#endif
-
-#ifdef GRUB_MACHINE_MEMORY_NVS
-        case GRUB_MACHINE_MEMORY_NVS:
-         grub_e820_add_region (params->e820_map, &e820_num,
-                               addr, size, GRUB_E820_NVS);
-         break;
-#endif
-
-#ifdef GRUB_MACHINE_MEMORY_CODE
-        case GRUB_MACHINE_MEMORY_CODE:
-         grub_e820_add_region (params->e820_map, &e820_num,
-                               addr, size, GRUB_E820_EXEC_CODE);
-         break;
-#endif
-
-        default:
-          grub_e820_add_region (params->e820_map, &e820_num,
-                                addr, size, GRUB_E820_RESERVED);
-        }
-      return 0;
-    }
-
-  e820_num = 0;
-  grub_mmap_iterate (hook);
-  params->mmap_size = e820_num;
-
-  mmap_size = find_mmap_size ();
-  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
-                              &desc_size, &desc_version) <= 0)
-    grub_fatal ("cannot get memory map");
-
-  if (! grub_efi_exit_boot_services (map_key))
-     grub_fatal ("cannot exit boot services");
-
-  /* Note that no boot services are available from here.  */
-
-  /* Pass EFI parameters.  */
-  if (grub_le_to_cpu16 (params->version) >= 0x0206)
-    {
-      params->v0206.efi_mem_desc_size = desc_size;
-      params->v0206.efi_mem_desc_version = desc_version;
-      params->v0206.efi_mmap = (grub_uint32_t) (unsigned long) mmap_buf;
-      params->v0206.efi_mmap_size = mmap_size;
-#ifdef __x86_64__
-      params->v0206.efi_mmap_hi = (grub_uint32_t) ((grub_uint64_t) mmap_buf >> 32);
-#endif
-    }
-  else if (grub_le_to_cpu16 (params->version) >= 0x0204)
-    {
-      params->v0204.efi_mem_desc_size = desc_size;
-      params->v0204.efi_mem_desc_version = desc_version;
-      params->v0204.efi_mmap = (grub_uint32_t) (unsigned long) mmap_buf;
-      params->v0204.efi_mmap_size = mmap_size;
-    }
-
-#ifdef __x86_64__
-
-  grub_memcpy ((char *) prot_mode_mem + (prot_mode_pages << 12),
-              grub_linux_trampoline_start,
-              grub_linux_trampoline_end - grub_linux_trampoline_start);
-
-  ((void (*) (unsigned long, void *)) ((char *) prot_mode_mem
-                                     + (prot_mode_pages << 12)))
-    (params->code32_start, real_mode_mem);
-
-#else
-
-  /* Hardware interrupts are not safe any longer.  */
-  asm volatile ("cli" : : );
-
-  /* Load the IDT and the GDT for the bootstrap.  */
-  asm volatile ("lidt %0" : : "m" (idt_desc));
-  asm volatile ("lgdt %0" : : "m" (gdt_desc));
-
-  /* Pass parameters.  */
-  asm volatile ("movl %0, %%ecx" : : "m" (params->code32_start));
-  asm volatile ("movl %0, %%esi" : : "m" (real_mode_mem));
-
-  asm volatile ("xorl %%ebx, %%ebx" : : );
-
-  /* Enter Linux.  */
-  asm volatile ("jmp *%%ecx" : : );
-
-#endif
-
-  /* Never reach here.  */
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_linux_unload (void)
-{
-  free_pages ();
-  grub_dl_unref (my_mod);
-  loaded = 0;
-  return GRUB_ERR_NONE;
-}
-
-static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
-
-
-#define RGB_MASK       0xffffff
-#define RGB_MAGIC      0x121314
-#define LINE_MIN       800
-#define LINE_MAX       4096
-#define FBTEST_STEP    (0x10000 >> 2)
-#define FBTEST_COUNT   8
-
-static int
-find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
-{
-  grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base;
-  int i;
-
-  for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP)
-    {
-      if ((*base & RGB_MASK) == RGB_MAGIC)
-       {
-         int j;
-
-         for (j = LINE_MIN; j <= LINE_MAX; j++)
-           {
-             if ((base[j] & RGB_MASK) == RGB_MAGIC)
-               {
-                 *fb_base = (grub_uint32_t) (grub_target_addr_t) base;
-                 *line_len = j << 2;
-
-                 return 1;
-               }
-           }
-
-         break;
-       }
-    }
-
-  return 0;
-}
-
-static int
-find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
-{
-  int found = 0;
-
-  auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
-                                      grub_pci_id_t pciid);
-
-  int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
-                                 grub_pci_id_t pciid)
-    {
-      grub_pci_address_t addr;
-
-      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
-      if (grub_pci_read (addr) >> 24 == 0x3)
-       {
-         int i;
-
-         grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n",
-                      grub_pci_get_bus (dev), grub_pci_get_device (dev),
-                      grub_pci_get_function (dev), pciid);
-         addr += 8;
-         for (i = 0; i < 6; i++, addr += 4)
-           {
-             grub_uint32_t old_bar1, old_bar2, type;
-             grub_uint64_t base64;
-
-             old_bar1 = grub_pci_read (addr);
-             if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
-               continue;
-
-             type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
-             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
-               {
-                 if (i == 5)
-                   break;
-
-                 old_bar2 = grub_pci_read (addr + 4);
-               }
-             else
-               old_bar2 = 0;
-
-             base64 = old_bar2;
-             base64 <<= 32;
-             base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
-
-             grub_printf ("%s(%d): 0x%llx\n",
-                          ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
-                           "VMEM" : "MMIO"), i,
-                          (unsigned long long) base64);
-
-             if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found))
-               {
-                 *fb_base = base64;
-                 if (find_line_len (fb_base, line_len))
-                   found++;
-               }
-
-             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
-               {
-                 i++;
-                 addr += 4;
-               }
-           }
-       }
-
-      return found;
-    }
-
-  grub_pci_iterate (find_card);
-  return found;
-}
-
-static int
-grub_linux_setup_video (struct linux_kernel_params *params)
-{
-  grub_efi_uga_draw_protocol_t *c;
-  grub_uint32_t width, height, depth, rate, pixel, fb_base, line_len;
-  int ret;
-
-  c = grub_efi_locate_protocol (&uga_draw_guid, 0);
-  if (! c)
-    return 1;
-
-  if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate))
-    return 1;
-
-  grub_printf ("Video mode: %ux%u-%u@%u\n", width, height, depth, rate);
-
-  grub_efi_set_text_mode (0);
-  pixel = RGB_MAGIC;
-  efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel,
-              GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0);
-  ret = find_framebuf (&fb_base, &line_len);
-  grub_efi_set_text_mode (1);
-
-  if (! ret)
-    {
-      grub_printf ("Can\'t find frame buffer address\n");
-      return 1;
-    }
-
-  grub_printf ("Frame buffer base: 0x%x\n", fb_base);
-  grub_printf ("Video line length: %d\n", line_len);
-
-  params->lfb_width = width;
-  params->lfb_height = height;
-  params->lfb_depth = depth;
-  params->lfb_line_len = line_len;
-
-  params->lfb_base = fb_base;
-  params->lfb_size = ALIGN_UP (line_len * params->lfb_height, 65536);
-
-  params->red_mask_size = 8;
-  params->red_field_pos = 16;
-  params->green_mask_size = 8;
-  params->green_field_pos = 8;
-  params->blue_mask_size = 8;
-  params->blue_field_pos = 0;
-  params->reserved_mask_size = 8;
-  params->reserved_field_pos = 24;
-
-  params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA;
-  params->vid_mode = 0x338;  /* 1024x768x32  */
-
-  return 0;
-}
-
-static grub_err_t
-grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-               int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  struct linux_kernel_header lh;
-  struct linux_kernel_params *params;
-  grub_uint8_t setup_sects;
-  grub_size_t real_size, prot_size;
-  grub_ssize_t len;
-  int i;
-  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, &lh, sizeof (lh)) != sizeof (lh))
-    {
-      grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
-      goto fail;
-    }
-
-  if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
-    {
-      grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
-      goto fail;
-    }
-
-  if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
-    {
-      grub_error (GRUB_ERR_BAD_OS, "too many setup sectors");
-      goto fail;
-    }
-
-  /* EFI support is quite new, so reject old versions.  */
-  if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
-      || grub_le_to_cpu16 (lh.version) < 0x0203)
-    {
-      grub_error (GRUB_ERR_BAD_OS, "too old version");
-      goto fail;
-    }
-
-  /* I'm not sure how to support zImage on EFI.  */
-  if (! (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL))
-    {
-      grub_error (GRUB_ERR_BAD_OS, "zImage is not supported");
-      goto fail;
-    }
-
-  setup_sects = lh.setup_sects;
-
-  /* If SETUP_SECTS is not set, set it to the default (4).  */
-  if (! setup_sects)
-    setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
-
-  real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
-  prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
-
-  if (! allocate_pages (prot_size))
-    goto fail;
-
-  params = (struct linux_kernel_params *) real_mode_mem;
-  grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET);
-  grub_memcpy (&params->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
-
-  params->ps_mouse = params->padding10 =  0;
-
-  len = 0x400 - sizeof (lh);
-  if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != len)
-    {
-      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
-      goto fail;
-    }
-
-  params->type_of_loader = (LINUX_LOADER_ID_GRUB << 4);
-
-  params->cl_magic = GRUB_LINUX_CL_MAGIC;
-  params->cl_offset = 0x1000;
-  params->cmd_line_ptr = (unsigned long) real_mode_mem + 0x1000;
-  params->ramdisk_image = 0;
-  params->ramdisk_size = 0;
-
-  params->heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET;
-  params->loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP;
-
-  /* These are not needed to be precise, because Linux uses these values
-     only to raise an error when the decompression code cannot find good
-     space.  */
-  params->ext_mem = ((32 * 0x100000) >> 10);
-  params->alt_mem = ((32 * 0x100000) >> 10);
-
-  {
-    grub_term_output_t term;
-    int found = 0;
-    FOR_ACTIVE_TERM_OUTPUTS(term)
-      if (grub_strcmp (term->name, "vga_text") == 0
-         || grub_strcmp (term->name, "console") == 0)
-       {
-         grub_uint16_t pos = grub_term_getxy (term);
-         params->video_cursor_x = pos >> 8;
-         params->video_cursor_y = pos & 0xff;
-         params->video_width = grub_term_width (term);
-         params->video_height = grub_term_height (term);
-         found = 1;
-         break;
-       }
-    if (!found)
-      {
-       params->video_cursor_x = 0;
-       params->video_cursor_y = 0;
-       params->video_width = 80;
-       params->video_height = 25;
-      }
-  }
-  params->video_page = 0; /* ??? */
-  params->video_mode = grub_efi_system_table->con_out->mode->mode;
-  params->video_ega_bx = 0;
-  params->have_vga = 0;
-  params->font_size = 16; /* XXX */
-
-  if (grub_le_to_cpu16 (params->version) >= 0x0206)
-    {
-      params->v0206.efi_signature = GRUB_LINUX_EFI_SIGNATURE;
-      params->v0206.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table;
-#ifdef __x86_64__
-      params->v0206.efi_system_table_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32);
-#endif
-    }
-  else if (grub_le_to_cpu16 (params->version) >= 0x0204)
-    {
-      params->v0204.efi_signature = GRUB_LINUX_EFI_SIGNATURE_0204;
-      params->v0204.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table;
-    }
-
-#if 0
-  /* The structure is zeroed already.  */
-
-  /* No VBE on EFI.  */
-  params->lfb_width = 0;
-  params->lfb_height = 0;
-  params->lfb_depth = 0;
-  params->lfb_base = 0;
-  params->lfb_size = 0;
-  params->lfb_line_len = 0;
-  params->red_mask_size = 0;
-  params->red_field_pos = 0;
-  params->green_mask_size = 0;
-  params->green_field_pos = 0;
-  params->blue_mask_size = 0;
-  params->blue_field_pos = 0;
-  params->reserved_mask_size = 0;
-  params->reserved_field_pos = 0;
-  params->vesapm_segment = 0;
-  params->vesapm_offset = 0;
-  params->lfb_pages = 0;
-  params->vesa_attrib = 0;
-
-  /* No APM on EFI.  */
-  params->apm_version = 0;
-  params->apm_code_segment = 0;
-  params->apm_entry = 0;
-  params->apm_16bit_code_segment = 0;
-  params->apm_data_segment = 0;
-  params->apm_flags = 0;
-  params->apm_code_len = 0;
-  params->apm_data_len = 0;
-
-  /* XXX is there any way to use SpeedStep on EFI?  */
-  params->ist_signature = 0;
-  params->ist_command = 0;
-  params->ist_event = 0;
-  params->ist_perf_level = 0;
-
-  /* Let the kernel probe the information.  */
-  grub_memset (params->hd0_drive_info, 0, sizeof (params->hd0_drive_info));
-  grub_memset (params->hd1_drive_info, 0, sizeof (params->hd1_drive_info));
-
-  /* No MCA on EFI.  */
-  params->rom_config_len = 0;
-
-  /* No need to fake the BIOS's memory map.  */
-  params->mmap_size = 0;
-
-  /* Let the kernel probe the information.  */
-  params->ps_mouse = 0;
-
-  /* Clear padding for future compatibility.  */
-  grub_memset (params->padding1, 0, sizeof (params->padding1));
-  grub_memset (params->padding2, 0, sizeof (params->padding2));
-  grub_memset (params->padding3, 0, sizeof (params->padding3));
-  grub_memset (params->padding4, 0, sizeof (params->padding4));
-  grub_memset (params->padding5, 0, sizeof (params->padding5));
-  grub_memset (params->padding6, 0, sizeof (params->padding6));
-  grub_memset (params->padding7, 0, sizeof (params->padding7));
-  grub_memset (params->padding8, 0, sizeof (params->padding8));
-  grub_memset (params->padding9, 0, sizeof (params->padding9));
-
-#endif
-
-  /* The other EFI parameters are filled when booting.  */
-
-  grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
-
-  /* XXX there is no way to know if the kernel really supports EFI.  */
-  grub_printf ("   [Linux-bzImage, setup=0x%x, size=0x%x]\n",
-              (unsigned) real_size, (unsigned) prot_size);
-
-  grub_linux_setup_video (params);
-
-  /* Detect explicitly specified memory size, if any.  */
-  linux_mem_size = 0;
-  for (i = 1; i < argc; i++)
-    if (grub_memcmp (argv[i], "mem=", 4) == 0)
-      {
-       char *val = argv[i] + 4;
-
-       linux_mem_size = grub_strtoul (val, &val, 0);
-
-       if (grub_errno)
-         {
-           grub_errno = GRUB_ERR_NONE;
-           linux_mem_size = 0;
-         }
-       else
-         {
-           int shift = 0;
-
-           switch (grub_tolower (val[0]))
-             {
-             case 'g':
-               shift += 10;
-             case 'm':
-               shift += 10;
-             case 'k':
-               shift += 10;
-             default:
-               break;
-             }
-
-           /* Check an overflow.  */
-           if (linux_mem_size > (~0UL >> shift))
-             linux_mem_size = 0;
-           else
-             linux_mem_size <<= shift;
-         }
-      }
-    else if (grub_memcmp (argv[i], "video=efifb", 11) == 0)
-      {
-       if (params->have_vga)
-         params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
-      }
-
-  /* Specify the boot file.  */
-  dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET,
-                     "BOOT_IMAGE=");
-  dest = grub_stpcpy (dest, argv[0]);
-
-  /* Copy kernel parameters.  */
-  for (i = 1;
-       i < argc
-        && dest + grub_strlen (argv[i]) + 1 < ((char *) real_mode_mem
-                                               + GRUB_LINUX_CL_END_OFFSET);
-       i++)
-    {
-      *dest++ = ' ';
-      dest = grub_stpcpy (dest, argv[i]);
-    }
-
-  len = prot_size;
-  if (grub_file_read (file, (void *) GRUB_LINUX_BZIMAGE_ADDR, len) != len)
-    grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
-
-  if (grub_errno == GRUB_ERR_NONE)
-    {
-      grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
-      loaded = 1;
-    }
-
- fail:
-
-  if (file)
-    grub_file_close (file);
-
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_dl_unref (my_mod);
-      loaded = 0;
-    }
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
-                int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  grub_ssize_t size;
-  grub_addr_t addr_min, addr_max;
-  grub_addr_t addr;
-  grub_efi_uintn_t mmap_size;
-  grub_efi_memory_descriptor_t *desc;
-  grub_efi_uintn_t desc_size;
-  struct linux_kernel_header *lh;
-
-  if (argc == 0)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
-      goto fail;
-    }
-
-  if (! loaded)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
-      goto fail;
-    }
-
-  file = grub_file_open (argv[0]);
-  if (! file)
-    goto fail;
-
-  size = grub_file_size (file);
-  initrd_pages = (page_align (size) >> 12);
-
-  lh = (struct linux_kernel_header *) real_mode_mem;
-
-  addr_max = (grub_cpu_to_le32 (lh->initrd_addr_max) << 10);
-  if (linux_mem_size != 0 && linux_mem_size < addr_max)
-    addr_max = linux_mem_size;
-
-  /* Linux 2.3.xx has a bug in the memory range check, so avoid
-     the last page.
-     Linux 2.2.xx has a bug in the memory range check, which is
-     worse than that of Linux 2.3.xx, so avoid the last 64kb.  */
-  addr_max -= 0x10000;
-
-  /* Usually, the compression ratio is about 50%.  */
-  addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
-            + page_align (size);
-
-  /* Find the highest address to put the initrd.  */
-  mmap_size = find_mmap_size ();
-  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0) <= 0)
-    grub_fatal ("cannot get memory map");
-
-  addr = 0;
-  for (desc = mmap_buf;
-       desc < NEXT_MEMORY_DESCRIPTOR (mmap_buf, mmap_size);
-       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
-    {
-      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
-         && desc->num_pages >= initrd_pages)
-       {
-         grub_efi_physical_address_t physical_end;
-
-         physical_end = desc->physical_start + (desc->num_pages << 12);
-         if (physical_end > addr_max)
-           physical_end = addr_max;
-
-         if (physical_end < page_align (size))
-           continue;
-
-         physical_end -= page_align (size);
-
-         if ((physical_end >= addr_min) &&
-             (physical_end >= desc->physical_start) &&
-             (physical_end > addr))
-           addr = physical_end;
-       }
-    }
-
-  if (addr == 0)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "no free pages available");
-      goto fail;
-    }
-
-  initrd_mem = grub_efi_allocate_pages (addr, initrd_pages);
-  if (! initrd_mem)
-    grub_fatal ("cannot allocate pages");
-
-  if (grub_file_read (file, initrd_mem, size) != size)
-    {
-      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
-      goto fail;
-    }
-
-  grub_printf ("   [Initrd, addr=0x%x, size=0x%x]\n",
-              (unsigned) addr, (unsigned) size);
-
-  lh->ramdisk_image = addr;
-  lh->ramdisk_size = size;
-  lh->root_dev = 0x0100; /* XXX */
-
- fail:
-  if (file)
-    grub_file_close (file);
-
-  return grub_errno;
-}
-
-static grub_command_t cmd_linux, cmd_initrd;
-
-GRUB_MOD_INIT(linux)
-{
-  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
-                                    0, N_("Load Linux."));
-  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
-                                     0, N_("Load initrd."));
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(linux)
-{
-  grub_unregister_command (cmd_linux);
-  grub_unregister_command (cmd_initrd);
-}
diff --git a/loader/i386/efi/xnu.c b/loader/i386/efi/xnu.c
deleted file mode 100644 (file)
index e80f7f3..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/env.h>
-#include <grub/xnu.h>
-#include <grub/cpu/xnu.h>
-#include <grub/efi/api.h>
-#include <grub/efi/efi.h>
-#include <grub/efi/uga_draw.h>
-#include <grub/pci.h>
-#include <grub/misc.h>
-
-/* Setup video for xnu. Big parts are copied from linux.c. */
-
-static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
-
-#define RGB_MASK       0xffffff
-#define RGB_MAGIC      0x121314
-#define LINE_MIN       800
-#define LINE_MAX       4096
-#define FBTEST_STEP    (0x10000 >> 2)
-#define FBTEST_COUNT   8
-
-static int
-find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
-{
-  grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base;
-  int i;
-
-  for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP)
-    {
-      if ((*base & RGB_MASK) == RGB_MAGIC)
-       {
-         int j;
-
-         for (j = LINE_MIN; j <= LINE_MAX; j++)
-           {
-             if ((base[j] & RGB_MASK) == RGB_MAGIC)
-               {
-                 *fb_base = (grub_uint32_t) (grub_target_addr_t) base;
-                 *line_len = j << 2;
-
-                 return 1;
-               }
-           }
-
-         break;
-       }
-    }
-
-  return 0;
-}
-
-static int
-find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
-{
-  int found = 0;
-
-  auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
-                                      grub_pci_id_t pciid);
-
-  int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
-                                 grub_pci_id_t pciid)
-    {
-      grub_pci_address_t addr;
-
-      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
-      if (grub_pci_read (addr) >> 24 == 0x3)
-       {
-         int i;
-
-         grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n",
-                      grub_pci_get_bus (dev), grub_pci_get_device (dev),
-                      grub_pci_get_function (dev), pciid);
-         addr += 8;
-         for (i = 0; i < 6; i++, addr += 4)
-           {
-             grub_uint32_t old_bar1, old_bar2, type;
-             grub_uint64_t base64;
-
-             old_bar1 = grub_pci_read (addr);
-             if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
-               continue;
-
-             type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
-             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
-               {
-                 if (i == 5)
-                   break;
-
-                 old_bar2 = grub_pci_read (addr + 4);
-               }
-             else
-               old_bar2 = 0;
-
-             base64 = old_bar2;
-             base64 <<= 32;
-             base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
-
-             grub_printf ("%s(%d): 0x%llx\n",
-                          ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
-                           "VMEM" : "MMIO"), i,
-                          (unsigned long long) base64);
-
-             if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found))
-               {
-                 *fb_base = base64;
-                 if (find_line_len (fb_base, line_len))
-                   found++;
-               }
-
-             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
-               {
-                 i++;
-                 addr += 4;
-               }
-           }
-       }
-
-      return found;
-    }
-
-  grub_pci_iterate (find_card);
-  return found;
-}
-
-grub_err_t
-grub_xnu_set_video (struct grub_xnu_boot_params *params)
-{
-  grub_efi_uga_draw_protocol_t *c;
-  grub_uint32_t width, height, depth, rate, pixel, fb_base, line_len;
-  int ret;
-
-  c = grub_efi_locate_protocol (&uga_draw_guid, 0);
-  if (! c)
-    return grub_error (GRUB_ERR_IO, "couldn't find UGADraw");
-
-  if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate))
-    return grub_error (GRUB_ERR_IO, "couldn't retrieve video mode");
-
-  grub_printf ("Video mode: %ux%u-%u@%u\n", width, height, depth, rate);
-
-  grub_efi_set_text_mode (0);
-  pixel = RGB_MAGIC;
-  efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel,
-              GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0);
-  ret = find_framebuf (&fb_base, &line_len);
-  grub_efi_set_text_mode (1);
-
-  if (! ret)
-    return grub_error (GRUB_ERR_IO, "can\'t find frame buffer address");
-
-  grub_printf ("Frame buffer base: 0x%x\n", fb_base);
-  grub_printf ("Video line length: %d\n", line_len);
-
-  params->lfb_width = width;
-  params->lfb_height = height;
-  params->lfb_depth = depth;
-  params->lfb_line_len = line_len;
-  params->lfb_mode = GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
-  params->lfb_base = fb_base;
-  return GRUB_ERR_NONE;
-}
diff --git a/loader/i386/ieee1275/linux.c b/loader/i386/ieee1275/linux.c
deleted file mode 100644 (file)
index 8780804..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-/* linux.c - boot Linux zImage or bzImage */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/loader.h>
-#include <grub/machine/loader.h>
-#include <grub/machine/memory.h>
-#include <grub/file.h>
-#include <grub/err.h>
-#include <grub/disk.h>
-#include <grub/misc.h>
-#include <grub/types.h>
-#include <grub/mm.h>
-#include <grub/dl.h>
-#include <grub/env.h>
-#include <grub/term.h>
-#include <grub/cpu/linux.h>
-#include <grub/ieee1275/ieee1275.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-#define GRUB_OFW_LINUX_PARAMS_ADDR     0x90000
-#define GRUB_OFW_LINUX_KERNEL_ADDR     0x100000
-#define GRUB_OFW_LINUX_INITRD_ADDR     0x800000
-
-#define GRUB_OFW_LINUX_CL_OFFSET       0x1e00
-#define GRUB_OFW_LINUX_CL_LENGTH       0x100
-
-static grub_dl_t my_mod;
-
-static grub_size_t kernel_size;
-static char *kernel_addr, *kernel_cmdline;
-static grub_size_t initrd_size;
-
-static grub_err_t
-grub_linux_unload (void)
-{
-  grub_free (kernel_cmdline);
-  grub_free (kernel_addr);
-  kernel_cmdline = 0;
-  kernel_addr = 0;
-  initrd_size = 0;
-
-  grub_dl_unref (my_mod);
-
-  return GRUB_ERR_NONE;
-}
-
-/*
-static int
-grub_ieee1275_debug (void)
-{
-  struct enter_args
-  {
-    struct grub_ieee1275_common_hdr common;
-  }
-  args;
-
-  INIT_IEEE1275_COMMON (&args.common, "enter", 0, 0);
-
-  if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
-    return -1;
-
-  return 0;
-}
-*/
-
-static grub_err_t
-grub_linux_boot (void)
-{
-  struct linux_kernel_params *params;
-  struct linux_kernel_header *lh;
-  char *prot_code;
-  char *bootpath;
-  grub_ssize_t len;
-
-  bootpath = grub_env_get ("root");
-  if (bootpath)
-    grub_ieee1275_set_property (grub_ieee1275_chosen,
-                                "bootpath", bootpath,
-                                grub_strlen (bootpath) + 1,
-                                &len);
-
-  params = (struct linux_kernel_params *) GRUB_OFW_LINUX_PARAMS_ADDR;
-  lh = (struct linux_kernel_header *) params;
-
-  grub_memset ((char *) params, 0, GRUB_OFW_LINUX_CL_OFFSET);
-
-  params->alt_mem = grub_mmap_get_upper () >> 10;
-  params->ext_mem = params->alt_mem;
-
-  lh->cmd_line_ptr = (char *)
-        (GRUB_OFW_LINUX_PARAMS_ADDR + GRUB_OFW_LINUX_CL_OFFSET);
-
-  params->cl_magic = GRUB_LINUX_CL_MAGIC;
-  params->cl_offset = GRUB_OFW_LINUX_CL_OFFSET;
-
-  {
-    grub_term_output_t term;
-    int found = 0;
-    FOR_ACTIVE_TERM_OUTPUTS(term)
-      if (grub_strcmp (term->name, "ofconsole") == 0)
-        {
-          grub_uint16_t pos = grub_term_getxy (term);
-          params->video_cursor_x = pos >> 8;
-          params->video_cursor_y = pos & 0xff;
-          params->video_width = grub_term_width (term);
-          params->video_height = grub_term_height (term);
-          found = 1;
-          break;
-        }
-    if (!found)
-      {
-        params->video_cursor_x = 0;
-        params->video_cursor_y = 0;
-        params->video_width = 80;
-        params->video_height = 25;
-      }
-  }
-
-  params->font_size = 16;
-
-  params->ofw_signature = GRUB_LINUX_OFW_SIGNATURE;
-  params->ofw_num_items = 1;
-  params->ofw_cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn;
-  params->ofw_idt = 0;
-
-  if (initrd_size)
-    {
-      lh->type_of_loader = 1;
-      lh->ramdisk_image = GRUB_OFW_LINUX_INITRD_ADDR;
-      lh->ramdisk_size = initrd_size;
-    }
-
-  if (kernel_cmdline)
-    grub_strcpy (lh->cmd_line_ptr, kernel_cmdline);
-
-  prot_code = (char *) GRUB_OFW_LINUX_KERNEL_ADDR;
-  grub_memcpy (prot_code, kernel_addr, kernel_size);
-
-  asm volatile ("movl %0, %%esi" : : "m" (params));
-  asm volatile ("movl %%esi, %%esp" : : );
-  asm volatile ("movl %0, %%ecx" : : "m" (prot_code));
-  asm volatile ("xorl %%ebx, %%ebx" : : );
-  asm volatile ("jmp *%%ecx" : : );
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-               int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  struct linux_kernel_header lh;
-  grub_uint8_t setup_sects;
-  grub_size_t real_size, prot_size;
-  int i;
-  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, &lh, sizeof (lh)) != sizeof (lh))
-    {
-      grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
-      goto fail;
-    }
-
-  if ((lh.boot_flag != grub_cpu_to_le16 (0xaa55)) ||
-      (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)))
-    {
-      grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
-      goto fail;
-    }
-
-  setup_sects = lh.setup_sects;
-  if (! setup_sects)
-    setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
-
-  real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
-  prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
-
-  grub_printf ("   [Linux-%s, setup=0x%x, size=0x%x]\n",
-               "bzImage", real_size, prot_size);
-
-  grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
-  if (grub_errno)
-    goto fail;
-
-  kernel_cmdline = grub_malloc (GRUB_OFW_LINUX_CL_LENGTH);
-  if (! kernel_cmdline)
-    goto fail;
-
-  dest = kernel_cmdline;
-  for (i = 1;
-       i < argc
-       && dest + grub_strlen (argv[i]) + 1 < (kernel_cmdline
-                                              + GRUB_OFW_LINUX_CL_LENGTH);
-       i++)
-    {
-      *dest++ = ' ';
-      dest = grub_stpcpy (dest, argv[i]);
-    }
-
-  kernel_addr = grub_malloc (prot_size);
-  if (! kernel_addr)
-    goto fail;
-
-  kernel_size = prot_size;
-  if (grub_file_read (file, kernel_addr, prot_size) != (int) prot_size)
-    grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
-
-  if (grub_errno == GRUB_ERR_NONE)
-    grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
-
-fail:
-
-  if (file)
-    grub_file_close (file);
-
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_free (kernel_cmdline);
-      grub_free (kernel_addr);
-      kernel_cmdline = 0;
-      kernel_addr = 0;
-
-      grub_dl_unref (my_mod);
-    }
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
-                int argc, char *argv[])
-{
-  grub_file_t file = 0;
-
-  if (argc == 0)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
-      goto fail;
-    }
-
-  if (! kernel_addr)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
-      goto fail;
-    }
-
-  file = grub_file_open (argv[0]);
-  if (! file)
-    goto fail;
-
-  initrd_size = grub_file_size (file);
-  if (grub_file_read (file, (void *) GRUB_OFW_LINUX_INITRD_ADDR,
-                      initrd_size) != (int) initrd_size)
-    {
-      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
-      goto fail;
-    }
-
-fail:
-  if (file)
-    grub_file_close (file);
-
-  return grub_errno;
-}
-
-static grub_command_t cmd_linux, cmd_initrd;
-
-GRUB_MOD_INIT(linux)
-{
-  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
-                                    0, N_("Load Linux."));
-  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
-                                     0, N_("Load initrd."));
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(linux)
-{
-  grub_unregister_command (cmd_linux);
-  grub_unregister_command (cmd_initrd);
-}
diff --git a/loader/i386/linux.c b/loader/i386/linux.c
deleted file mode 100644 (file)
index d3d9351..0000000
+++ /dev/null
@@ -1,1022 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/loader.h>
-#include <grub/machine/memory.h>
-#include <grub/machine/loader.h>
-#include <grub/normal.h>
-#include <grub/file.h>
-#include <grub/disk.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/term.h>
-#include <grub/cpu/linux.h>
-#include <grub/video.h>
-#include <grub/video_fb.h>
-#include <grub/command.h>
-#include <grub/i386/pc/vbe.h>
-#include <grub/i386/pc/console.h>
-#include <grub/i18n.h>
-
-#define GRUB_LINUX_CL_OFFSET           0x1000
-#define GRUB_LINUX_CL_END_OFFSET       0x2000
-
-static grub_dl_t my_mod;
-
-static grub_size_t linux_mem_size;
-static int loaded;
-static void *real_mode_mem;
-static void *prot_mode_mem;
-static void *initrd_mem;
-static grub_uint32_t real_mode_pages;
-static grub_uint32_t prot_mode_pages;
-static grub_uint32_t initrd_pages;
-
-static grub_uint8_t gdt[] __attribute__ ((aligned(16))) =
-  {
-    /* NULL.  */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    /* Reserved.  */
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    /* Code segment.  */
-    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00,
-    /* Data segment.  */
-    0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
-  };
-
-struct gdt_descriptor
-{
-  grub_uint16_t limit;
-  void *base;
-} __attribute__ ((packed));
-
-static struct gdt_descriptor gdt_desc =
-  {
-    sizeof (gdt) - 1,
-    gdt
-  };
-
-struct idt_descriptor
-{
-  grub_uint16_t limit;
-  void *base;
-} __attribute__ ((packed));
-
-static struct idt_descriptor idt_desc =
-  {
-    0,
-    0
-  };
-
-#ifdef GRUB_MACHINE_PCBIOS
-struct linux_vesafb_res
-{
-  grub_uint16_t width;
-  grub_uint16_t height;
-};
-
-struct linux_vesafb_mode
-{
-  grub_uint8_t res_index;
-  grub_uint8_t depth;
-};
-
-enum vga_modes
-  {
-    VGA_320_200,
-    VGA_640_400,
-    VGA_640_480,
-    VGA_800_500,
-    VGA_800_600,
-    VGA_896_672,
-    VGA_1024_640,
-    VGA_1024_768,
-    VGA_1152_720,
-    VGA_1280_1024,
-    VGA_1440_900,
-    VGA_1600_1200,
-  };
-
-static struct linux_vesafb_res linux_vesafb_res[] =
-  {
-    { 320, 200 },
-    { 640, 400 },
-    { 640, 480 },
-    { 800, 500 },
-    { 800, 600 },
-    { 896, 672 },
-    { 1024, 640 },
-    { 1024, 768 },
-    { 1152, 720 },
-    { 1280, 1024 },
-    { 1440, 900 },
-    { 1600, 1200 },
-  };
-
-/* This is the reverse of the table in [linux]/Documentation/fb/vesafb.txt
-   plus a few more modes based on the table in
-   http://en.wikipedia.org/wiki/VESA_BIOS_Extensions  */
-struct linux_vesafb_mode linux_vesafb_modes[] =
-  {
-    { VGA_640_400, 8 },                /* 0x300 */
-    { VGA_640_480, 8 },                /* 0x301 */
-    { VGA_800_600, 4 },                /* 0x302 */
-    { VGA_800_600, 8 },                /* 0x303 */
-    { VGA_1024_768, 4 },       /* 0x304 */
-    { VGA_1024_768, 8 },       /* 0x305 */
-    { VGA_1280_1024, 4 },      /* 0x306 */
-    { VGA_1280_1024, 8 },      /* 0x307 */
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { VGA_320_200, 15 },       /* 0x30d */
-    { VGA_320_200, 16 },       /* 0x30e */
-    { VGA_320_200, 24 },       /* 0x30f */
-    { VGA_640_480, 15 },       /* 0x310 */
-    { VGA_640_480, 16 },       /* 0x311 */
-    { VGA_640_480, 24 },       /* 0x312 */
-    { VGA_800_600, 15 },       /* 0x313 */
-    { VGA_800_600, 16 },       /* 0x314 */
-    { VGA_800_600, 24 },       /* 0x315 */
-    { VGA_1024_768, 15 },      /* 0x316 */
-    { VGA_1024_768, 16 },      /* 0x317 */
-    { VGA_1024_768, 24 },      /* 0x318 */
-    { VGA_1280_1024, 15 },     /* 0x319 */
-    { VGA_1280_1024, 16 },     /* 0x31a */
-    { VGA_1280_1024, 24 },     /* 0x31b */
-    { VGA_1600_1200, 8 },      /* 0x31c */
-    { VGA_1600_1200, 15 },     /* 0x31d */
-    { VGA_1600_1200, 16 },     /* 0x31e */
-    { VGA_1600_1200, 24 },     /* 0x31f */
-    { 0, 0 },
-    { VGA_640_400, 15 },       /* 0x321 */
-    { VGA_640_400, 16 },       /* 0x322 */
-    { VGA_640_400, 24 },       /* 0x323 */
-    { VGA_640_400, 32 },       /* 0x324 */
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { VGA_640_480, 32 },       /* 0x329 */
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { VGA_896_672, 8 },                /* 0x32f */
-    { VGA_896_672, 15 },       /* 0x330 */
-    { VGA_896_672, 16 },       /* 0x331 */
-    { VGA_896_672, 24 },       /* 0x332 */
-    { VGA_896_672, 32 },       /* 0x333 */
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { VGA_1600_1200, 32 },     /* 0x342 */
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { 0, 0 },
-    { VGA_1440_900, 8 },       /* 0x360 */
-    { VGA_1440_900, 15 },      /* 0x361 */
-    { VGA_1440_900, 16 },      /* 0x362 */
-    { VGA_1440_900, 24 },      /* 0x363 */
-    { VGA_1440_900, 32 },      /* 0x364 */
-    { VGA_1152_720, 8 },       /* 0x365 */
-    { VGA_1152_720, 15 },      /* 0x366 */
-    { VGA_1152_720, 16 },      /* 0x367 */
-    { VGA_1152_720, 24 },      /* 0x368 */
-    { VGA_1152_720, 32 },      /* 0x369 */
-    { VGA_1024_640, 8 },       /* 0x36a */
-    { VGA_1024_640, 15 },      /* 0x36b */
-    { VGA_1024_640, 16 },      /* 0x36c */
-    { VGA_1024_640, 24 },      /* 0x36d */
-    { VGA_1024_640, 32 },      /* 0x36e */
-    { VGA_800_500, 8 },                /* 0x36f */
-    { VGA_800_500, 15 },       /* 0x370 */
-    { VGA_800_500, 16 },       /* 0x371 */
-    { VGA_800_500, 24 },       /* 0x372 */
-    { VGA_800_500, 32 },       /* 0x373 */
-  };
-#endif
-
-static inline grub_size_t
-page_align (grub_size_t size)
-{
-  return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
-}
-
-/* Find the optimal number of pages for the memory map. */
-static grub_size_t
-find_mmap_size (void)
-{
-  grub_size_t count = 0, mmap_size;
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
-                            grub_uint64_t size __attribute__ ((unused)),
-                            grub_uint32_t type __attribute__ ((unused)))
-    {
-      count++;
-      return 0;
-    }
-
-  grub_mmap_iterate (hook);
-
-  mmap_size = count * sizeof (struct grub_e820_mmap);
-
-  /* Increase the size a bit for safety, because GRUB allocates more on
-     later.  */
-  mmap_size += (1 << 12);
-
-  return page_align (mmap_size);
-}
-
-static void
-free_pages (void)
-{
-  real_mode_mem = prot_mode_mem = initrd_mem = 0;
-}
-
-/* Allocate pages for the real mode code and the protected mode code
-   for linux as well as a memory map buffer.  */
-static int
-allocate_pages (grub_size_t prot_size)
-{
-  grub_size_t real_size, mmap_size;
-
-  /* Make sure that each size is aligned to a page boundary.  */
-  real_size = GRUB_LINUX_CL_END_OFFSET;
-  prot_size = page_align (prot_size);
-  mmap_size = find_mmap_size ();
-
-  grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
-               (unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
-
-  /* Calculate the number of pages; Combine the real mode code with
-     the memory map buffer for simplicity.  */
-  real_mode_pages = ((real_size + mmap_size) >> 12);
-  prot_mode_pages = (prot_size >> 12);
-
-  /* Initialize the memory pointers with NULL for convenience.  */
-  free_pages ();
-
-  /* FIXME: Should request low memory from the heap when this feature is
-     implemented.  */
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
-    {
-      /* We must put real mode code in the traditional space.  */
-
-      if (type == GRUB_MACHINE_MEMORY_AVAILABLE
-         && addr <= 0x90000)
-       {
-         if (addr < 0x10000)
-           {
-             size += addr - 0x10000;
-             addr = 0x10000;
-           }
-
-         if (addr + size > 0x90000)
-           size = 0x90000 - addr;
-
-         if (real_size + mmap_size > size)
-           return 0;
-
-         real_mode_mem =
-           (void *) (grub_size_t) ((addr + size) - (real_size + mmap_size));
-         return 1;
-       }
-
-      return 0;
-    }
-  grub_mmap_iterate (hook);
-  if (! real_mode_mem)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
-      goto fail;
-    }
-
-  prot_mode_mem = (void *) 0x100000;
-
-  grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
-                "prot_mode_mem = %lx, prot_mode_pages = %x\n",
-                (unsigned long) real_mode_mem, (unsigned) real_mode_pages,
-                (unsigned long) prot_mode_mem, (unsigned) prot_mode_pages);
-
-  return 1;
-
- fail:
-  free_pages ();
-  return 0;
-}
-
-static void
-grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num,
-                      grub_uint64_t start, grub_uint64_t size,
-                      grub_uint32_t type)
-{
-  int n = *e820_num;
-
-  if (n >= GRUB_E820_MAX_ENTRY)
-    grub_fatal ("Too many e820 memory map entries");
-
-  if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) &&
-      (e820_map[n - 1].type == type))
-      e820_map[n - 1].size += size;
-  else
-    {
-      e820_map[n].addr = start;
-      e820_map[n].size = size;
-      e820_map[n].type = type;
-      (*e820_num)++;
-    }
-}
-
-static int
-grub_linux_setup_video (struct linux_kernel_params *params)
-{
-  struct grub_video_mode_info mode_info;
-  void *framebuffer;
-  grub_err_t err;
-
-  err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
-
-  if (err)
-    {
-      grub_errno = GRUB_ERR_NONE;
-      return 1;
-    }
-
-  params->lfb_width = mode_info.width;
-  params->lfb_height = mode_info.height;
-  params->lfb_depth = mode_info.bpp;
-  params->lfb_line_len = mode_info.pitch;
-
-  params->lfb_base = (grub_size_t) framebuffer;
-  params->lfb_size = ALIGN_UP (params->lfb_line_len * params->lfb_height, 65536);
-
-  params->red_mask_size = mode_info.red_mask_size;
-  params->red_field_pos = mode_info.red_field_pos;
-  params->green_mask_size = mode_info.green_mask_size;
-  params->green_field_pos = mode_info.green_field_pos;
-  params->blue_mask_size = mode_info.blue_mask_size;
-  params->blue_field_pos = mode_info.blue_field_pos;
-  params->reserved_mask_size = mode_info.reserved_mask_size;
-  params->reserved_field_pos = mode_info.reserved_field_pos;
-
-
-#ifdef GRUB_MACHINE_PCBIOS
-  /* VESA packed modes may come with zeroed mask sizes, which need
-     to be set here according to DAC Palette width.  If we don't,
-     this results in Linux displaying a black screen.  */
-  if (mode_info.bpp <= 8)
-    {
-      struct grub_vbe_info_block controller_info;
-      int status;
-      int width = 8;
-
-      status = grub_vbe_bios_get_controller_info (&controller_info);
-
-      if (status == GRUB_VBE_STATUS_OK &&
-         (controller_info.capabilities & GRUB_VBE_CAPABILITY_DACWIDTH))
-       status = grub_vbe_bios_set_dac_palette_width (&width);
-
-      if (status != GRUB_VBE_STATUS_OK)
-       /* 6 is default after mode reset.  */
-       width = 6;
-
-      params->red_mask_size = params->green_mask_size
-       = params->blue_mask_size = width;
-      params->reserved_mask_size = 0;
-    }
-#endif
-
-  return 0;
-}
-
-#ifdef __x86_64__
-extern grub_uint8_t grub_linux_trampoline_start[];
-extern grub_uint8_t grub_linux_trampoline_end[];
-#endif
-
-static grub_err_t
-grub_linux_boot (void)
-{
-  struct linux_kernel_params *params;
-  int e820_num;
-  grub_err_t err = 0;
-  char *modevar, *tmp;
-
-  params = real_mode_mem;
-
-  grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n",
-               (unsigned) params->code32_start,
-                (unsigned long) &(idt_desc.limit),
-               (unsigned long) &(gdt_desc.limit));
-  grub_dprintf ("linux", "idt = %x:%lx, gdt = %x:%lx\n",
-               (unsigned) idt_desc.limit, (unsigned long) idt_desc.base,
-               (unsigned) gdt_desc.limit, (unsigned long) gdt_desc.base);
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
-    {
-      switch (type)
-        {
-        case GRUB_MACHINE_MEMORY_AVAILABLE:
-         grub_e820_add_region (params->e820_map, &e820_num,
-                               addr, size, GRUB_E820_RAM);
-         break;
-
-#ifdef GRUB_MACHINE_MEMORY_ACPI
-        case GRUB_MACHINE_MEMORY_ACPI:
-         grub_e820_add_region (params->e820_map, &e820_num,
-                               addr, size, GRUB_E820_ACPI);
-         break;
-#endif
-
-#ifdef GRUB_MACHINE_MEMORY_NVS
-        case GRUB_MACHINE_MEMORY_NVS:
-         grub_e820_add_region (params->e820_map, &e820_num,
-                               addr, size, GRUB_E820_NVS);
-         break;
-#endif
-
-#ifdef GRUB_MACHINE_MEMORY_CODE
-        case GRUB_MACHINE_MEMORY_CODE:
-         grub_e820_add_region (params->e820_map, &e820_num,
-                               addr, size, GRUB_E820_EXEC_CODE);
-         break;
-#endif
-
-        default:
-          grub_e820_add_region (params->e820_map, &e820_num,
-                                addr, size, GRUB_E820_RESERVED);
-        }
-      return 0;
-    }
-
-  e820_num = 0;
-  grub_mmap_iterate (hook);
-  params->mmap_size = e820_num;
-
-  modevar = grub_env_get ("gfxpayload");
-
-  /* Now all graphical modes are acceptable.
-     May change in future if we have modes without framebuffer.  */
-  if (modevar && *modevar != 0)
-    {
-      tmp = grub_xasprintf ("%s;text", modevar);
-      if (! tmp)
-       return grub_errno;
-      err = grub_video_set_mode (tmp, 0, 0);
-      grub_free (tmp);
-    }
-  else
-    err = grub_video_set_mode ("text", 0, 0);
-
-  if (err)
-    {
-      grub_print_error ();
-      grub_printf ("Booting however\n");
-      grub_errno = GRUB_ERR_NONE;
-    }
-
-  if (! grub_linux_setup_video (params))
-    {
-      /* Use generic framebuffer unless VESA is known to be supported.  */
-      if (params->have_vga != GRUB_VIDEO_LINUX_TYPE_VESA)
-       params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
-      else
-       params->lfb_size >>= 16;
-    }
-  else
-    {
-      params->have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT;
-      params->video_width = 80;
-      params->video_height = 25;
-    }
-
-  /* Initialize these last, because terminal position could be affected by printfs above.  */
-  if (params->have_vga == GRUB_VIDEO_LINUX_TYPE_TEXT)
-    {
-      grub_term_output_t term;
-      int found = 0;
-      FOR_ACTIVE_TERM_OUTPUTS(term)
-       if (grub_strcmp (term->name, "vga_text") == 0
-           || grub_strcmp (term->name, "console") == 0)
-         {
-           grub_uint16_t pos = grub_term_getxy (term);
-           params->video_cursor_x = pos >> 8;
-           params->video_cursor_y = pos & 0xff;
-           found = 1;
-           break;
-         }
-      if (!found)
-       {
-         params->video_cursor_x = 0;
-         params->video_cursor_y = 0;
-       }
-    }
-
-#ifdef __x86_64__
-
-  grub_memcpy ((char *) prot_mode_mem + (prot_mode_pages << 12),
-              grub_linux_trampoline_start,
-              grub_linux_trampoline_end - grub_linux_trampoline_start);
-
-  ((void (*) (unsigned long, void *)) ((char *) prot_mode_mem
-                                      + (prot_mode_pages << 12)))
-    (params->code32_start, real_mode_mem);
-#else
-
-  /* Hardware interrupts are not safe any longer.  */
-  asm volatile ("cli" : : );
-
-  /* Load the IDT and the GDT for the bootstrap.  */
-  asm volatile ("lidt %0" : : "m" (idt_desc));
-  asm volatile ("lgdt %0" : : "m" (gdt_desc));
-
-  /* Enter Linux.  */
-  asm volatile ("jmp *%2" : : "b" (0), "S" (real_mode_mem), "g" (params->code32_start));
-
-#endif
-
-  /* Never reach here.  */
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_linux_unload (void)
-{
-  grub_dl_unref (my_mod);
-  loaded = 0;
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-               int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  struct linux_kernel_header lh;
-  struct linux_kernel_params *params;
-  grub_uint8_t setup_sects;
-  grub_size_t real_size, prot_size;
-  grub_ssize_t len;
-  int i;
-  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, &lh, sizeof (lh)) != sizeof (lh))
-    {
-      grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
-      goto fail;
-    }
-
-  if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
-    {
-      grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
-      goto fail;
-    }
-
-  if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
-    {
-      grub_error (GRUB_ERR_BAD_OS, "too many setup sectors");
-      goto fail;
-    }
-
-  if (! (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL))
-    {
-      grub_error (GRUB_ERR_BAD_OS, "zImage doesn't support 32-bit boot"
-#ifdef GRUB_MACHINE_PCBIOS
-                 " (try with `linux16')"
-#endif
-                 );
-      goto fail;
-    }
-
-  /* FIXME: 2.03 is not always good enough (Linux 2.4 can be 2.03 and
-     still not support 32-bit boot.  */
-  if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
-      || grub_le_to_cpu16 (lh.version) < 0x0203)
-    {
-      grub_error (GRUB_ERR_BAD_OS, "version too old for 32-bit boot"
-#ifdef GRUB_MACHINE_PCBIOS
-                 " (try with `linux16')"
-#endif
-                 );
-      goto fail;
-    }
-
-  setup_sects = lh.setup_sects;
-
-  /* If SETUP_SECTS is not set, set it to the default (4).  */
-  if (! setup_sects)
-    setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
-
-  real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
-  prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
-
-  if (! allocate_pages (prot_size))
-    goto fail;
-
-  params = (struct linux_kernel_params *) real_mode_mem;
-  grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET);
-  grub_memcpy (&params->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
-
-  params->ps_mouse = params->padding10 =  0;
-
-  len = 0x400 - sizeof (lh);
-  if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != len)
-    {
-      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
-      goto fail;
-    }
-
-  params->type_of_loader = (LINUX_LOADER_ID_GRUB << 4);
-
-  /* These two are used (instead of cmd_line_ptr) by older versions of Linux,
-     and otherwise ignored.  */
-  params->cl_magic = GRUB_LINUX_CL_MAGIC;
-  params->cl_offset = 0x1000;
-
-  params->cmd_line_ptr = (unsigned long) real_mode_mem + 0x1000;
-  params->ramdisk_image = 0;
-  params->ramdisk_size = 0;
-
-  params->heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET;
-  params->loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP;
-
-  /* These are not needed to be precise, because Linux uses these values
-     only to raise an error when the decompression code cannot find good
-     space.  */
-  params->ext_mem = ((32 * 0x100000) >> 10);
-  params->alt_mem = ((32 * 0x100000) >> 10);
-
-  /* Ignored by Linux.  */
-  params->video_page = 0;
-
-  /* Must be non-zero even in text mode, or Linux will think there's no VGA.  */
-  params->video_mode = 0x3;
-
-  /* Only used when `video_mode == 0x7', otherwise ignored.  */
-  params->video_ega_bx = 0;
-
-  params->font_size = 16; /* XXX */
-
-  /* The other parameters are filled when booting.  */
-
-  grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
-
-  grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n",
-               (unsigned) real_size, (unsigned) prot_size);
-
-  /* Look for memory size and video mode specified on the command line.  */
-  linux_mem_size = 0;
-  for (i = 1; i < argc; i++)
-#ifdef GRUB_MACHINE_PCBIOS
-    if (grub_memcmp (argv[i], "vga=", 4) == 0)
-      {
-       /* Video mode selection support.  */
-       char *val = argv[i] + 4;
-       unsigned vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
-       struct linux_vesafb_mode *linux_mode;
-       grub_err_t err;
-       char *buf;
-
-       if (grub_strcmp (val, "normal") == 0)
-         vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
-       else if (grub_strcmp (val, "ext") == 0)
-         vid_mode = GRUB_LINUX_VID_MODE_EXTENDED;
-       else if (grub_strcmp (val, "ask") == 0)
-         {
-           grub_printf ("Legacy `ask' parameter no longer supported.\n");
-
-           /* We usually would never do this in a loader, but "vga=ask" means user
-              requested interaction, so it can't hurt to request keyboard input.  */
-           grub_wait_after_message ();
-
-           goto fail;
-         }
-       else
-         vid_mode = (grub_uint16_t) grub_strtoul (val, 0, 0);
-
-       switch (vid_mode)
-         {
-         case 0:
-         case GRUB_LINUX_VID_MODE_NORMAL:
-           grub_env_set ("gfxpayload", "text");
-           grub_printf ("%s is deprecated. "
-                        "Use set gfxpayload=text before "
-                        "linux command instead.\n",
-                        argv[i]);
-           break;
-
-         case 1:
-         case GRUB_LINUX_VID_MODE_EXTENDED:
-           /* FIXME: support 80x50 text. */
-           grub_env_set ("gfxpayload", "text");
-           grub_printf ("%s is deprecated. "
-                        "Use set gfxpayload=text before "
-                        "linux command instead.\n",
-                        argv[i]);
-           break;
-         default:
-           /* Ignore invalid values.  */
-           if (vid_mode < GRUB_LINUX_VID_MODE_VESA_START ||
-               vid_mode >= GRUB_LINUX_VID_MODE_VESA_START +
-               ARRAY_SIZE (linux_vesafb_modes))
-             {
-               grub_env_set ("gfxpayload", "text");
-               grub_printf ("%s is deprecated. Mode %d isn't recognized. "
-                            "Use set gfxpayload=WIDTHxHEIGHT[xDEPTH] before "
-                            "linux command instead.\n",
-                            argv[i], vid_mode);
-               break;
-             }
-
-           /* We can't detect VESA, but user is implicitly telling us that it
-              is built-in because `vga=' parameter was used.  */
-           params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA;
-
-           linux_mode
-             = &linux_vesafb_modes[vid_mode - GRUB_LINUX_VID_MODE_VESA_START];
-
-           buf = grub_xasprintf ("%ux%ux%u,%ux%u",
-                                linux_vesafb_res[linux_mode->res_index].width,
-                                linux_vesafb_res[linux_mode->res_index].height,
-                                linux_mode->depth,
-                                linux_vesafb_res[linux_mode->res_index].width,
-                                linux_vesafb_res[linux_mode->res_index].height);
-           if (! buf)
-             goto fail;
-
-           grub_printf ("%s is deprecated. "
-                        "Use set gfxpayload=%s before "
-                        "linux command instead.\n",
-                        argv[i], buf);
-           err = grub_env_set ("gfxpayload", buf);
-           grub_free (buf);
-           if (err)
-             goto fail;
-         }
-      }
-    else
-#endif /* GRUB_MACHINE_PCBIOS */
-    if (grub_memcmp (argv[i], "mem=", 4) == 0)
-      {
-       char *val = argv[i] + 4;
-
-       linux_mem_size = grub_strtoul (val, &val, 0);
-
-       if (grub_errno)
-         {
-           grub_errno = GRUB_ERR_NONE;
-           linux_mem_size = 0;
-         }
-       else
-         {
-           int shift = 0;
-
-           switch (grub_tolower (val[0]))
-             {
-             case 'g':
-               shift += 10;
-             case 'm':
-               shift += 10;
-             case 'k':
-               shift += 10;
-             default:
-               break;
-             }
-
-           /* Check an overflow.  */
-           if (linux_mem_size > (~0UL >> shift))
-             linux_mem_size = 0;
-           else
-             linux_mem_size <<= shift;
-         }
-      }
-    else if (grub_memcmp (argv[i], "quiet", sizeof ("quiet") - 1) == 0)
-      {
-       params->loadflags |= GRUB_LINUX_FLAG_QUIET;
-      }
-
-
-  /* Specify the boot file.  */
-  dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET,
-                     "BOOT_IMAGE=");
-  dest = grub_stpcpy (dest, argv[0]);
-
-  /* Copy kernel parameters.  */
-  for (i = 1;
-       i < argc
-        && dest + grub_strlen (argv[i]) + 1 < ((char *) real_mode_mem
-                                               + GRUB_LINUX_CL_END_OFFSET);
-       i++)
-    {
-      *dest++ = ' ';
-      dest = grub_stpcpy (dest, argv[i]);
-    }
-
-  len = prot_size;
-  if (grub_file_read (file, (void *) GRUB_LINUX_BZIMAGE_ADDR, len) != len)
-    grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
-
-  if (grub_errno == GRUB_ERR_NONE)
-    {
-      grub_loader_set (grub_linux_boot, grub_linux_unload,
-                      0 /* set noreturn=0 in order to avoid grub_console_fini() */);
-      loaded = 1;
-    }
-
- fail:
-
-  if (file)
-    grub_file_close (file);
-
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_dl_unref (my_mod);
-      loaded = 0;
-    }
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
-                int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  grub_ssize_t size;
-  grub_addr_t addr_min, addr_max;
-  grub_addr_t addr;
-  struct linux_kernel_header *lh;
-
-  if (argc == 0)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
-      goto fail;
-    }
-
-  if (! loaded)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
-      goto fail;
-    }
-
-  file = grub_file_open (argv[0]);
-  if (! file)
-    goto fail;
-
-  size = grub_file_size (file);
-  initrd_pages = (page_align (size) >> 12);
-
-  lh = (struct linux_kernel_header *) real_mode_mem;
-
-  /* Get the highest address available for the initrd.  */
-  if (grub_le_to_cpu16 (lh->version) >= 0x0203)
-    {
-      addr_max = grub_cpu_to_le32 (lh->initrd_addr_max);
-
-      /* XXX in reality, Linux specifies a bogus value, so
-        it is necessary to make sure that ADDR_MAX does not exceed
-        0x3fffffff.  */
-      if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS)
-       addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
-    }
-  else
-    addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
-
-  if (linux_mem_size != 0 && linux_mem_size < addr_max)
-    addr_max = linux_mem_size;
-
-  /* Linux 2.3.xx has a bug in the memory range check, so avoid
-     the last page.
-     Linux 2.2.xx has a bug in the memory range check, which is
-     worse than that of Linux 2.3.xx, so avoid the last 64kb.  */
-  addr_max -= 0x10000;
-
-  /* Usually, the compression ratio is about 50%.  */
-  addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
-             + page_align (size);
-
-  if (addr_max > grub_os_area_addr + grub_os_area_size)
-    addr_max = grub_os_area_addr + grub_os_area_size;
-
-  /* Put the initrd as high as possible, 4KiB aligned.  */
-  addr = (addr_max - size) & ~0xFFF;
-
-  if (addr < addr_min)
-    {
-      grub_error (GRUB_ERR_OUT_OF_RANGE, "the initrd is too big");
-      goto fail;
-    }
-
-  initrd_mem = (void *) addr;
-
-  if (grub_file_read (file, initrd_mem, size) != size)
-    {
-      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
-      goto fail;
-    }
-
-  grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n",
-               (unsigned) addr, (unsigned) size);
-
-  lh->ramdisk_image = addr;
-  lh->ramdisk_size = size;
-  lh->root_dev = 0x0100; /* XXX */
-
- fail:
-  if (file)
-    grub_file_close (file);
-
-  return grub_errno;
-}
-
-static grub_command_t cmd_linux, cmd_initrd;
-
-GRUB_MOD_INIT(linux)
-{
-  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
-                                    0, N_("Load Linux."));
-  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
-                                     0, N_("Load initrd."));
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(linux)
-{
-  grub_unregister_command (cmd_linux);
-  grub_unregister_command (cmd_initrd);
-}
diff --git a/loader/i386/linux_trampoline.S b/loader/i386/linux_trampoline.S
deleted file mode 100644 (file)
index 4acea7b..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-
-
-       .p2align        4       /* force 16-byte alignment */
-VARIABLE(grub_linux_trampoline_start)
-       cli
-       /* %rdi contains protected memory start and %rsi
-       contains real memory start. */
-
-       mov %rsi, %rbx
-
-       call base
-base:
-       pop %rsi
-
-#ifdef APPLE_CC
-       lea (cont1 - base) (%esi, 1), %rax
-       mov %eax, (jump_vector - base) (%esi, 1)
-
-       lea (gdt - base) (%esi, 1), %rax
-       mov %rax, (gdtaddr - base) (%esi, 1)
-
-       /* Switch to compatibility mode. */
-
-       lidt (idtdesc - base) (%esi, 1)
-       lgdt (gdtdesc - base) (%esi, 1)
-
-       /* Update %cs. Thanks to David Miller for pointing this mistake out. */
-       ljmp *(jump_vector - base) (%esi, 1)
-#else
-       lea (cont1 - base) (%rsi, 1), %rax
-       mov %eax, (jump_vector - base) (%rsi, 1)
-
-       lea (gdt - base) (%rsi, 1), %rax
-       mov %rax, (gdtaddr - base) (%rsi, 1)
-
-       /* Switch to compatibility mode. */
-
-       lidt (idtdesc - base) (%rsi, 1)
-       lgdt (gdtdesc - base) (%rsi, 1)
-
-       /* Update %cs. Thanks to David Miller for pointing this mistake out. */
-       ljmp *(jump_vector - base) (%rsi, 1)
-#endif
-
-cont1:
-       .code32
-
-       /* Update other registers. */
-       mov $0x18, %eax
-       mov %eax, %ds
-       mov %eax, %es
-       mov %eax, %fs
-       mov %eax, %gs
-       mov %eax, %ss
-
-       /* Disable paging. */
-       mov %cr0, %eax
-       and $0x7fffffff, %eax
-       mov %eax, %cr0
-
-       /* Disable amd64. */
-       mov $0xc0000080, %ecx
-       rdmsr
-       and $0xfffffeff, %eax
-       wrmsr
-
-       /* Turn off PAE. */
-       movl %cr4, %eax
-       and $0xffffffcf, %eax
-       mov %eax, %cr4
-
-       jmp cont2
-cont2:
-       .code32
-
-       mov %ebx, %esi
-
-       jmp *%edi
-
-       /* GDT. */
-       .p2align 4
-gdt:
-       /* NULL.  */
-       .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-
-       /* Reserved.  */
-       .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-
-       /* Code segment.  */
-       .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
-
-       /* Data segment.  */
-       .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
-
-gdtdesc:
-       .word 31
-gdtaddr:
-       .quad gdt
-
-idtdesc:
-       .word 0
-idtaddr:
-       .quad 0
-
-       .p2align 4
-jump_vector:
-       /* Jump location. Is filled by the code */
-       .long 0
-       .long 0x10
-VARIABLE(grub_linux_trampoline_end)
diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c
deleted file mode 100644 (file)
index 3d974f0..0000000
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/machine/memory.h>
-#include <grub/memory.h>
-#ifdef GRUB_MACHINE_PCBIOS
-#include <grub/machine/biosnum.h>
-#endif
-#include <grub/multiboot.h>
-#include <grub/cpu/multiboot.h>
-#include <grub/cpu/relocator.h>
-#include <grub/disk.h>
-#include <grub/device.h>
-#include <grub/partition.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/env.h>
-#include <grub/video.h>
-#include <grub/file.h>
-
-/* The bits in the required part of flags field we don't support.  */
-#define UNSUPPORTED_FLAGS                      0x0000fff8
-
-struct module
-{
-  struct module *next;
-  grub_addr_t start;
-  grub_size_t size;
-  char *cmdline;
-  int cmdline_size;
-};
-
-struct module *modules, *modules_last;
-static grub_size_t cmdline_size;
-static grub_size_t total_modcmd;
-static unsigned modcnt;
-static char *cmdline = NULL;
-static grub_uint32_t bootdev;
-static int bootdev_set;
-
-grub_err_t
-grub_multiboot_load (grub_file_t file)
-{
-  char *buffer;
-  grub_ssize_t len;
-  struct multiboot_header *header;
-  grub_err_t err;
-
-  buffer = grub_malloc (MULTIBOOT_SEARCH);
-  if (!buffer)
-    return grub_errno;
-
-  len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
-  if (len < 32)
-    {
-      grub_free (buffer);
-      return grub_error (GRUB_ERR_BAD_OS, "file too small");
-    }
-
-  /* Look for the multiboot header in the buffer.  The header should
-     be at least 12 bytes and aligned on a 4-byte boundary.  */
-  for (header = (struct multiboot_header *) buffer;
-       ((char *) header <= buffer + len - 12) || (header = 0);
-       header = (struct multiboot_header *) ((char *) header + MULTIBOOT_HEADER_ALIGN))
-    {
-      if (header->magic == MULTIBOOT_HEADER_MAGIC
-         && !(header->magic + header->flags + header->checksum))
-       break;
-    }
-
-  if (header == 0)
-    {
-      grub_free (buffer);
-      return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found");
-    }
-
-  if (header->flags & UNSUPPORTED_FLAGS)
-    {
-      grub_free (buffer);
-      return grub_error (GRUB_ERR_UNKNOWN_OS,
-                        "unsupported flag: 0x%x", header->flags);
-    }
-
-  if (header->flags & MULTIBOOT_AOUT_KLUDGE)
-    {
-      int offset = ((char *) header - buffer -
-                   (header->header_addr - header->load_addr));
-      int load_size = ((header->load_end_addr == 0) ? file->size - offset :
-                      header->load_end_addr - header->load_addr);
-      grub_size_t code_size;
-
-      if (header->bss_end_addr)
-       code_size = (header->bss_end_addr - header->load_addr);
-      else
-       code_size = load_size;
-      grub_multiboot_payload_dest = header->load_addr;
-
-      grub_multiboot_pure_size += code_size;
-
-      /* Allocate a bit more to avoid relocations in most cases.  */
-      grub_multiboot_alloc_mbi = grub_multiboot_get_mbi_size () + 65536;
-      grub_multiboot_payload_orig
-       = grub_relocator32_alloc (grub_multiboot_pure_size + grub_multiboot_alloc_mbi);
-
-      if (! grub_multiboot_payload_orig)
-       {
-         grub_free (buffer);
-         return grub_errno;
-       }
-
-      if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
-       {
-         grub_free (buffer);
-         return grub_errno;
-       }
-
-      grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size);
-      if (grub_errno)
-       {
-         grub_free (buffer);
-         return grub_errno;
-       }
-
-      if (header->bss_end_addr)
-       grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0,
-                    header->bss_end_addr - header->load_addr - load_size);
-
-      grub_multiboot_payload_eip = header->entry_addr;
-
-    }
-  else
-    {
-      err = grub_multiboot_load_elf (file, buffer);
-      if (err)
-       {
-         grub_free (buffer);
-         return err;
-       }
-    }
-
-  if (header->flags & MULTIBOOT_VIDEO_MODE)
-    {
-      switch (header->mode_type)
-       {
-       case 1:
-         err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, 
-                                           GRUB_MULTIBOOT_CONSOLE_EGA_TEXT
-                                           | GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
-                                           0, 0, 0, 0);
-         break;
-       case 0:
-         err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
-                                           GRUB_MULTIBOOT_CONSOLE_EGA_TEXT
-                                           | GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
-                                           header->width, header->height,
-                                           header->depth, 0);
-         break;
-       default:
-         err = grub_error (GRUB_ERR_BAD_OS, 
-                           "unsupported graphical mode type %d",
-                           header->mode_type);
-         break;
-       }
-    }
-  else
-    err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, 
-                                     GRUB_MULTIBOOT_CONSOLE_EGA_TEXT,
-                                     0, 0, 0, 0);
-  return err;
-}
-
-grub_size_t
-grub_multiboot_get_mbi_size (void)
-{
-  return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4)
-    + modcnt * sizeof (struct multiboot_mod_list) + total_modcmd
-    + ALIGN_UP (sizeof(PACKAGE_STRING), 4) 
-    + grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry)
-    + 256 * sizeof (struct multiboot_color);
-}
-
-/* Fill previously allocated Multiboot mmap.  */
-static void
-grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry)
-{
-  struct multiboot_mmap_entry *mmap_entry = (struct multiboot_mmap_entry *) first_entry;
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
-    {
-      mmap_entry->addr = addr;
-      mmap_entry->len = size;
-      switch (type)
-       {
-       case GRUB_MACHINE_MEMORY_AVAILABLE:
-         mmap_entry->type = MULTIBOOT_MEMORY_AVAILABLE;
-         break;
-
-#ifdef GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE
-       case GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE:
-         mmap_entry->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE;
-         break;
-#endif
-
-#ifdef GRUB_MACHINE_MEMORY_NVS
-       case GRUB_MACHINE_MEMORY_NVS:
-         mmap_entry->type = MULTIBOOT_MEMORY_NVS;
-         break;
-#endif   
-         
-       default:
-         mmap_entry->type = MULTIBOOT_MEMORY_RESERVED;
-         break;
-       }
-      mmap_entry->size = sizeof (struct multiboot_mmap_entry) - sizeof (mmap_entry->size);
-      mmap_entry++;
-
-      return 0;
-    }
-
-  grub_mmap_iterate (hook);
-}
-
-static grub_err_t
-retrieve_video_parameters (struct multiboot_info *mbi,
-                          grub_uint8_t *ptrorig, grub_uint32_t ptrdest)
-{
-  grub_err_t err;
-  struct grub_video_mode_info mode_info;
-  void *framebuffer;
-  grub_video_driver_id_t driv_id;
-  struct grub_video_palette_data palette[256];
-
-  err = grub_multiboot_set_video_mode ();
-  if (err)
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-    }
-
-  grub_video_get_palette (0, ARRAY_SIZE (palette), palette);
-
-  driv_id = grub_video_get_driver_id ();
-  if (driv_id == GRUB_VIDEO_DRIVER_NONE)
-    return GRUB_ERR_NONE;
-
-  err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
-  if (err)
-    return err;
-
-  mbi->framebuffer_addr = (grub_addr_t) framebuffer;
-  mbi->framebuffer_pitch = mode_info.pitch;
-
-  mbi->framebuffer_width = mode_info.width;
-  mbi->framebuffer_height = mode_info.height;
-
-  mbi->framebuffer_bpp = mode_info.bpp;
-      
-  if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
-    {
-      struct multiboot_color *mb_palette;
-      unsigned i;
-      mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED;
-      mbi->framebuffer_palette_addr = ptrdest;
-      mbi->framebuffer_palette_num_colors = mode_info.number_of_colors;
-      if (mbi->framebuffer_palette_num_colors > ARRAY_SIZE (palette))
-       mbi->framebuffer_palette_num_colors = ARRAY_SIZE (palette);
-      mb_palette = (struct multiboot_color *) ptrorig;
-      for (i = 0; i < mbi->framebuffer_palette_num_colors; i++)
-       {
-         mb_palette[i].red = palette[i].r;
-         mb_palette[i].green = palette[i].g;
-         mb_palette[i].blue = palette[i].b;
-       }
-      ptrorig += mbi->framebuffer_palette_num_colors
-       * sizeof (struct multiboot_color);
-      ptrdest += mbi->framebuffer_palette_num_colors
-       * sizeof (struct multiboot_color);
-    }
-  else
-    {
-      mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
-      mbi->framebuffer_red_field_position = mode_info.green_field_pos;
-      mbi->framebuffer_red_mask_size = mode_info.green_mask_size;
-      mbi->framebuffer_green_field_position = mode_info.green_field_pos;
-      mbi->framebuffer_green_mask_size = mode_info.green_mask_size;
-      mbi->framebuffer_blue_field_position = mode_info.blue_field_pos;
-      mbi->framebuffer_blue_mask_size = mode_info.blue_mask_size;
-    }
-
-  mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO;
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
-                        grub_size_t bufsize)
-{
-  grub_uint8_t *ptrorig = (grub_uint8_t *) orig + buf_off;
-  grub_uint32_t ptrdest = dest + buf_off;
-  struct multiboot_info *mbi;
-  struct multiboot_mod_list *modlist;
-  unsigned i;
-  struct module *cur;
-  grub_size_t mmap_size;
-  grub_err_t err;
-
-  if (bufsize < grub_multiboot_get_mbi_size ())
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small");
-
-  mbi = (struct multiboot_info *) ptrorig;
-  ptrorig += sizeof (*mbi);
-  ptrdest += sizeof (*mbi);
-  grub_memset (mbi, 0, sizeof (*mbi));
-
-  grub_memcpy (ptrorig, cmdline, cmdline_size);
-  mbi->flags |= MULTIBOOT_INFO_CMDLINE;
-  mbi->cmdline = ptrdest;
-  ptrorig += ALIGN_UP (cmdline_size, 4);
-  ptrdest += ALIGN_UP (cmdline_size, 4);
-
-  grub_memcpy (ptrorig, PACKAGE_STRING, sizeof(PACKAGE_STRING));
-  mbi->flags |= MULTIBOOT_INFO_BOOT_LOADER_NAME;
-  mbi->boot_loader_name = ptrdest;
-  ptrorig += ALIGN_UP (sizeof(PACKAGE_STRING), 4);
-  ptrdest += ALIGN_UP (sizeof(PACKAGE_STRING), 4);
-
-  if (modcnt)
-    {
-      mbi->flags |= MULTIBOOT_INFO_MODS;
-      mbi->mods_addr = ptrdest;
-      mbi->mods_count = modcnt;
-      modlist = (struct multiboot_mod_list *) ptrorig;
-      ptrorig += modcnt * sizeof (struct multiboot_mod_list);
-      ptrdest += modcnt * sizeof (struct multiboot_mod_list);
-
-      for (i = 0, cur = modules; i < modcnt; i++, cur = cur->next)
-       {
-         modlist[i].mod_start = cur->start;
-         modlist[i].mod_end = modlist[i].mod_start + cur->size;
-         modlist[i].cmdline = ptrdest;
-         grub_memcpy (ptrorig, cur->cmdline, cur->cmdline_size);
-         ptrorig += ALIGN_UP (cur->cmdline_size, 4);
-         ptrdest += ALIGN_UP (cur->cmdline_size, 4);
-       }
-    }
-  else
-    {
-      mbi->mods_addr = 0;
-      mbi->mods_count = 0;
-    }
-
-  mmap_size = grub_get_multiboot_mmap_count () 
-    * sizeof (struct multiboot_mmap_entry);
-  grub_fill_multiboot_mmap ((struct multiboot_mmap_entry *) ptrorig);
-  mbi->mmap_length = mmap_size;
-  mbi->mmap_addr = ptrdest;
-  mbi->flags |= MULTIBOOT_INFO_MEM_MAP;
-  ptrorig += mmap_size;
-  ptrdest += mmap_size;
-
-  /* Convert from bytes to kilobytes.  */
-  mbi->mem_lower = grub_mmap_get_lower () / 1024;
-  mbi->mem_upper = grub_mmap_get_upper () / 1024;
-  mbi->flags |= MULTIBOOT_INFO_MEMORY;
-
-  if (bootdev_set)
-    {
-      mbi->boot_device = bootdev;
-      mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
-    }
-
-  err = retrieve_video_parameters (mbi, ptrorig, ptrdest);
-  if (err)
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-void
-grub_multiboot_free_mbi (void)
-{
-  struct module *cur, *next;
-
-  cmdline_size = 0;
-  total_modcmd = 0;
-  modcnt = 0;
-  grub_free (cmdline);
-  cmdline = NULL;
-  bootdev_set = 0;
-
-  for (cur = modules; cur; cur = next)
-    {
-      next = cur->next;
-      grub_free (cur->cmdline);
-      grub_free (cur);
-    }
-  modules = NULL;
-  modules_last = NULL;
-}
-
-grub_err_t
-grub_multiboot_init_mbi (int argc, char *argv[])
-{
-  grub_ssize_t len = 0;
-  char *p;
-  int i;
-
-  grub_multiboot_free_mbi ();
-
-  for (i = 0; i < argc; i++)
-    len += grub_strlen (argv[i]) + 1;
-  if (len == 0)
-    len = 1;
-
-  cmdline = p = grub_malloc (len);
-  if (! cmdline)
-    return grub_errno;
-  cmdline_size = len;
-
-  for (i = 0; i < argc; i++)
-    {
-      p = grub_stpcpy (p, argv[i]);
-      *(p++) = ' ';
-    }
-
-  /* Remove the space after the last word.  */
-  if (p != cmdline)
-    p--;
-  *p = '\0';
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
-                          int argc, char *argv[])
-{
-  struct module *newmod;
-  char *p;
-  grub_ssize_t len = 0;
-  int i;
-
-  newmod = grub_malloc (sizeof (*newmod));
-  if (!newmod)
-    return grub_errno;
-  newmod->start = start;
-  newmod->size = size;
-
-  for (i = 0; i < argc; i++)
-    len += grub_strlen (argv[i]) + 1;
-
-  if (len == 0)
-    len = 1;
-
-  newmod->cmdline = p = grub_malloc (len);
-  if (! newmod->cmdline)
-    {
-      grub_free (newmod);
-      return grub_errno;
-    }
-  newmod->cmdline_size = len;
-  total_modcmd += ALIGN_UP (len, 4);
-
-  for (i = 0; i < argc; i++)
-    {
-      p = grub_stpcpy (p, argv[i]);
-      *(p++) = ' ';
-    }
-
-  /* Remove the space after the last word.  */
-  if (p != newmod->cmdline)
-    p--;
-  *p = '\0';
-
-  if (modules_last)
-    modules_last->next = newmod;
-  else
-    {
-      modules = newmod;
-      modules_last->next = NULL;
-    }
-  modules_last = newmod;
-
-  modcnt++;
-
-  return GRUB_ERR_NONE;
-}
-
-void
-grub_multiboot_set_bootdev (void)
-{
-  grub_uint32_t biosdev, slice = ~0, part = ~0;
-  grub_device_t dev;
-
-#ifdef GRUB_MACHINE_PCBIOS
-  biosdev = grub_get_root_biosnumber ();
-#else
-  biosdev = 0xffffffff;
-#endif
-
-  if (biosdev == 0xffffffff)
-    return;
-
-  dev = grub_device_open (0);
-  if (dev && dev->disk && dev->disk->partition)
-    {
-      if (dev->disk->partition->parent)
-       {
-         part = dev->disk->partition->number;
-         slice = dev->disk->partition->parent->number;
-       }
-      else
-       slice = dev->disk->partition->number;
-    }
-  if (dev)
-    grub_device_close (dev);
-
-  bootdev = ((biosdev & 0xff) << 24) | ((slice & 0xff) << 16) 
-    | ((part & 0xff) << 8) | 0xff;
-  bootdev_set = 1;
-}
diff --git a/loader/i386/pc/chainloader.c b/loader/i386/pc/chainloader.c
deleted file mode 100644 (file)
index 502031d..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/* chainloader.c - boot another boot loader */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2007,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/loader.h>
-#include <grub/machine/loader.h>
-#include <grub/machine/chainloader.h>
-#include <grub/file.h>
-#include <grub/err.h>
-#include <grub/device.h>
-#include <grub/disk.h>
-#include <grub/misc.h>
-#include <grub/types.h>
-#include <grub/machine/init.h>
-#include <grub/partition.h>
-#include <grub/machine/memory.h>
-#include <grub/dl.h>
-#include <grub/command.h>
-#include <grub/msdos_partition.h>
-#include <grub/machine/biosnum.h>
-#include <grub/i18n.h>
-#include <grub/video.h>
-#include <grub/mm.h>
-
-static grub_dl_t my_mod;
-static int boot_drive;
-static void *boot_part_addr;
-
-static grub_err_t
-grub_chainloader_boot (void)
-{
-  grub_video_set_mode ("text", 0, 0);
-  grub_chainloader_real_boot (boot_drive, boot_part_addr);
-
-  /* Never reach here.  */
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_chainloader_unload (void)
-{
-  grub_dl_unref (my_mod);
-  return GRUB_ERR_NONE;
-}
-
-static void
-grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
-{
-  grub_file_t file = 0;
-  grub_uint16_t signature;
-  grub_device_t dev;
-  int drive = -1;
-  void *part_addr = 0;
-
-  grub_dl_ref (my_mod);
-
-  file = grub_file_open (filename);
-  if (! file)
-    goto fail;
-
-  /* Read the first block.  */
-  if (grub_file_read (file, (void *) 0x7C00, GRUB_DISK_SECTOR_SIZE)
-      != GRUB_DISK_SECTOR_SIZE)
-    {
-      if (grub_errno == GRUB_ERR_NONE)
-       grub_error (GRUB_ERR_BAD_OS, "too small");
-
-      goto fail;
-    }
-
-  /* Check the signature.  */
-  signature = *((grub_uint16_t *) (0x7C00 + GRUB_DISK_SECTOR_SIZE - 2));
-  if (signature != grub_le_to_cpu16 (0xaa55)
-      && ! (flags & GRUB_CHAINLOADER_FORCE))
-    {
-      grub_error (GRUB_ERR_BAD_OS, "invalid signature");
-      goto fail;
-    }
-
-  grub_file_close (file);
-
-  /* Obtain the partition table from the root device.  */
-  drive = grub_get_root_biosnumber ();
-  dev = grub_device_open (0);
-  if (dev && dev->disk && dev->disk->partition)
-    {
-      grub_disk_t disk = dev->disk;
-
-      if (disk)
-       {
-         grub_partition_t p = disk->partition;
-
-         if (p && grub_strcmp (p->partmap->name, "msdos") == 0)
-           {
-             disk->partition = p->parent;
-             grub_disk_read (disk, p->offset, 446, 64,
-                             (void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR);
-             part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR
-                                   + (p->index << 4));
-             disk->partition = p;
-           }
-       }
-    }
-
-  if (dev)
-    grub_device_close (dev);
-  /* Ignore errors. Perhaps it's not fatal.  */
-  grub_errno = GRUB_ERR_NONE;
-
-  boot_drive = drive;
-  boot_part_addr = part_addr;
-
-  grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 1);
-  return;
-
- fail:
-
-  if (file)
-    grub_file_close (file);
-
-  grub_dl_unref (my_mod);
-}
-
-static grub_err_t
-grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
-                     int argc, char *argv[])
-{
-  grub_chainloader_flags_t flags = 0;
-
-  if (argc > 0 && grub_strcmp (argv[0], "--force") == 0)
-    {
-      flags |= GRUB_CHAINLOADER_FORCE;
-      argc--;
-      argv++;
-    }
-
-  if (argc == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
-  else
-    grub_chainloader_cmd (argv[0], flags);
-
-  return grub_errno;
-}
-
-static grub_command_t cmd;
-
-GRUB_MOD_INIT(chainloader)
-{
-  cmd = grub_register_command ("chainloader", grub_cmd_chainloader,
-                              0, N_("Load another boot loader."));
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(chainloader)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/loader/i386/pc/linux.c b/loader/i386/pc/linux.c
deleted file mode 100644 (file)
index 0fa9abc..0000000
+++ /dev/null
@@ -1,410 +0,0 @@
-/* linux.c - boot Linux zImage or bzImage */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/loader.h>
-#include <grub/machine/loader.h>
-#include <grub/file.h>
-#include <grub/err.h>
-#include <grub/device.h>
-#include <grub/disk.h>
-#include <grub/misc.h>
-#include <grub/types.h>
-#include <grub/machine/init.h>
-#include <grub/machine/memory.h>
-#include <grub/dl.h>
-#include <grub/cpu/linux.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-#include <grub/mm.h>
-#include <grub/video.h>
-
-#define GRUB_LINUX_CL_OFFSET           0x9000
-#define GRUB_LINUX_CL_END_OFFSET       0x90FF
-
-static grub_dl_t my_mod;
-
-static grub_size_t linux_mem_size;
-static int loaded;
-
-static grub_err_t
-grub_linux_unload (void)
-{
-  grub_dl_unref (my_mod);
-  loaded = 0;
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_linux16_boot (void)
-{
-  grub_video_set_mode ("text", 0, 0);
-  grub_linux16_real_boot ();
-
-  /* Not reached.  */
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-               int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  struct linux_kernel_header lh;
-  grub_uint8_t setup_sects;
-  grub_size_t real_size, prot_size;
-  grub_ssize_t len;
-  int i;
-  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_size_t) grub_file_size (file) > grub_os_area_size)
-    {
-      grub_error (GRUB_ERR_OUT_OF_RANGE, "too big kernel (0x%x > 0x%x)",
-                 (grub_size_t) grub_file_size (file),
-                 grub_os_area_size);
-      goto fail;
-    }
-
-  if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
-    {
-      grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
-      goto fail;
-    }
-
-  if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
-    {
-      grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
-      goto fail;
-    }
-
-  if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
-    {
-      grub_error (GRUB_ERR_BAD_OS, "too many setup sectors");
-      goto fail;
-    }
-
-  grub_linux_is_bzimage = 0;
-  setup_sects = lh.setup_sects;
-  linux_mem_size = 0;
-
-  if (lh.header == grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
-      && grub_le_to_cpu16 (lh.version) >= 0x0200)
-    {
-      grub_linux_is_bzimage = (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL);
-      lh.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;
-
-      /* Put the real mode part at as a high location as possible.  */
-      grub_linux_real_addr
-       = (char *) UINT_TO_PTR (grub_mmap_get_lower ()
-                               - GRUB_LINUX_SETUP_MOVE_SIZE);
-      /* But it must not exceed the traditional area.  */
-      if (grub_linux_real_addr > (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR)
-       grub_linux_real_addr = (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR;
-
-      if (grub_le_to_cpu16 (lh.version) >= 0x0201)
-       {
-         lh.heap_end_ptr = grub_cpu_to_le16 (GRUB_LINUX_HEAP_END_OFFSET);
-         lh.loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP;
-       }
-
-      if (grub_le_to_cpu16 (lh.version) >= 0x0202)
-       lh.cmd_line_ptr = grub_linux_real_addr + GRUB_LINUX_CL_OFFSET;
-      else
-       {
-         lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC);
-         lh.cl_offset = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET);
-         lh.setup_move_size = grub_cpu_to_le16 (GRUB_LINUX_SETUP_MOVE_SIZE);
-       }
-    }
-  else
-    {
-      /* Your kernel is quite old...  */
-      lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC);
-      lh.cl_offset = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET);
-
-      setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
-
-      grub_linux_real_addr = (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR;
-    }
-
-  /* If SETUP_SECTS is not set, set it to the default (4).  */
-  if (! setup_sects)
-    setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
-
-  real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
-  prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
-
-  grub_linux_tmp_addr = (char *) GRUB_LINUX_BZIMAGE_ADDR + prot_size;
-
-  if (! grub_linux_is_bzimage
-      && ((char *) GRUB_LINUX_ZIMAGE_ADDR + prot_size > grub_linux_real_addr))
-    {
-      grub_error (GRUB_ERR_BAD_OS, "too big zImage (0x%x > 0x%x), use bzImage instead",
-                 (char *) GRUB_LINUX_ZIMAGE_ADDR + prot_size,
-                 (grub_size_t) grub_linux_real_addr);
-      goto fail;
-    }
-
-  if (grub_linux_real_addr + GRUB_LINUX_SETUP_MOVE_SIZE
-      > (char *) UINT_TO_PTR (grub_mmap_get_lower ()))
-    {
-      grub_error (GRUB_ERR_OUT_OF_RANGE,
-                "too small lower memory (0x%x > 0x%x)",
-                 grub_linux_real_addr + GRUB_LINUX_SETUP_MOVE_SIZE,
-                 (int) grub_mmap_get_lower ());
-      goto fail;
-    }
-
-  grub_printf ("   [Linux-%s, setup=0x%x, size=0x%x]\n",
-              grub_linux_is_bzimage ? "bzImage" : "zImage", real_size, prot_size);
-
-  for (i = 1; i < argc; i++)
-    if (grub_memcmp (argv[i], "vga=", 4) == 0)
-      {
-       /* Video mode selection support.  */
-       grub_uint16_t vid_mode;
-       char *val = argv[i] + 4;
-
-       if (grub_strcmp (val, "normal") == 0)
-         vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
-       else if (grub_strcmp (val, "ext") == 0)
-         vid_mode = GRUB_LINUX_VID_MODE_EXTENDED;
-       else if (grub_strcmp (val, "ask") == 0)
-         vid_mode = GRUB_LINUX_VID_MODE_ASK;
-       else
-         vid_mode = (grub_uint16_t) grub_strtoul (val, 0, 0);
-
-       if (grub_errno)
-         goto fail;
-
-       lh.vid_mode = grub_cpu_to_le16 (vid_mode);
-      }
-    else if (grub_memcmp (argv[i], "mem=", 4) == 0)
-      {
-       char *val = argv[i] + 4;
-
-       linux_mem_size = grub_strtoul (val, &val, 0);
-
-       if (grub_errno)
-         {
-           grub_errno = GRUB_ERR_NONE;
-           linux_mem_size = 0;
-         }
-       else
-         {
-           int shift = 0;
-
-           switch (grub_tolower (val[0]))
-             {
-             case 'g':
-               shift += 10;
-             case 'm':
-               shift += 10;
-             case 'k':
-               shift += 10;
-             default:
-               break;
-             }
-
-           /* Check an overflow.  */
-           if (linux_mem_size > (~0UL >> shift))
-             linux_mem_size = 0;
-           else
-             linux_mem_size <<= shift;
-         }
-      }
-
-  /* Put the real mode code at the temporary address.  */
-  grub_memmove (grub_linux_tmp_addr, &lh, sizeof (lh));
-
-  len = real_size + GRUB_DISK_SECTOR_SIZE - sizeof (lh);
-  if (grub_file_read (file, grub_linux_tmp_addr + sizeof (lh), len) != len)
-    {
-      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
-      goto fail;
-    }
-
-  if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
-      || grub_le_to_cpu16 (lh.version) < 0x0200)
-    /* Clear the heap space.  */
-    grub_memset (grub_linux_tmp_addr
-                + ((setup_sects + 1) << GRUB_DISK_SECTOR_BITS),
-                0,
-                ((GRUB_LINUX_MAX_SETUP_SECTS - setup_sects - 1)
-                 << GRUB_DISK_SECTOR_BITS));
-
-  /* Specify the boot file.  */
-  dest = grub_stpcpy (grub_linux_tmp_addr + GRUB_LINUX_CL_OFFSET,
-                     "BOOT_IMAGE=");
-  dest = grub_stpcpy (dest, argv[0]);
-
-  /* Copy kernel parameters.  */
-  for (i = 1;
-       i < argc
-        && dest + grub_strlen (argv[i]) + 1 < (grub_linux_tmp_addr
-                                               + GRUB_LINUX_CL_END_OFFSET);
-       i++)
-    {
-      *dest++ = ' ';
-      dest = grub_stpcpy (dest, argv[i]);
-    }
-
-  len = prot_size;
-  if (grub_file_read (file, (void *) GRUB_LINUX_BZIMAGE_ADDR, len) != len)
-    grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
-
-  if (grub_errno == GRUB_ERR_NONE)
-    {
-      grub_linux_prot_size = prot_size;
-      grub_loader_set (grub_linux16_boot, grub_linux_unload, 1);
-      loaded = 1;
-    }
-
- fail:
-
-  if (file)
-    grub_file_close (file);
-
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_dl_unref (my_mod);
-      loaded = 0;
-    }
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
-                int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  grub_ssize_t size;
-  grub_addr_t addr_max, addr_min, addr;
-  struct linux_kernel_header *lh;
-
-  if (argc == 0)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
-      goto fail;
-    }
-
-  if (!loaded)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
-      goto fail;
-    }
-
-  lh = (struct linux_kernel_header *) grub_linux_tmp_addr;
-
-  if (!(lh->header == grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
-       && grub_le_to_cpu16 (lh->version) >= 0x0200))
-    {
-      grub_error (GRUB_ERR_BAD_OS, "the kernel is too old for initrd");
-      goto fail;
-    }
-
-  /* Get the highest address available for the initrd.  */
-  if (grub_le_to_cpu16 (lh->version) >= 0x0203)
-    {
-      addr_max = grub_cpu_to_le32 (lh->initrd_addr_max);
-
-      /* XXX in reality, Linux specifies a bogus value, so
-        it is necessary to make sure that ADDR_MAX does not exceed
-        0x3fffffff.  */
-      if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS)
-       addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
-    }
-  else
-    addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
-
-  if (linux_mem_size != 0 && linux_mem_size < addr_max)
-    addr_max = linux_mem_size;
-
-  /* Linux 2.3.xx has a bug in the memory range check, so avoid
-     the last page.
-     Linux 2.2.xx has a bug in the memory range check, which is
-     worse than that of Linux 2.3.xx, so avoid the last 64kb.  */
-  addr_max -= 0x10000;
-
-  if (addr_max > grub_os_area_addr + grub_os_area_size)
-    addr_max = grub_os_area_addr + grub_os_area_size;
-
-  addr_min = (grub_addr_t) grub_linux_tmp_addr + GRUB_LINUX_CL_END_OFFSET;
-
-  file = grub_file_open (argv[0]);
-  if (!file)
-    goto fail;
-
-  size = grub_file_size (file);
-
-  /* Put the initrd as high as possible, 4KiB aligned.  */
-  addr = (addr_max - size) & ~0xFFF;
-
-  if (addr < addr_min)
-    {
-      grub_error (GRUB_ERR_OUT_OF_RANGE, "the initrd is too big");
-      goto fail;
-    }
-
-  if (grub_file_read (file, (void *) addr, size) != size)
-    {
-      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
-      goto fail;
-    }
-
-  lh->ramdisk_image = addr;
-  lh->ramdisk_size = size;
-
- fail:
-  if (file)
-    grub_file_close (file);
-
-  return grub_errno;
-}
-
-static grub_command_t cmd_linux, cmd_initrd;
-
-GRUB_MOD_INIT(linux16)
-{
-  cmd_linux =
-    grub_register_command ("linux16", grub_cmd_linux,
-                          0, N_("Load Linux."));
-  cmd_initrd =
-    grub_register_command ("initrd16", grub_cmd_initrd,
-                          0, N_("Load initrd."));
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(linux16)
-{
-  grub_unregister_command (cmd_linux);
-  grub_unregister_command (cmd_initrd);
-}
diff --git a/loader/i386/pc/xnu.c b/loader/i386/pc/xnu.c
deleted file mode 100644 (file)
index 39a595d..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/env.h>
-#include <grub/misc.h>
-#include <grub/xnu.h>
-#include <grub/mm.h>
-#include <grub/cpu/xnu.h>
-#include <grub/video_fb.h>
-#include <grub/bitmap_scale.h>
-
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-
-#define DEFAULT_VIDEO_MODE "auto"
-
-/* Setup video for xnu. */
-grub_err_t
-grub_xnu_set_video (struct grub_xnu_boot_params *params)
-{
-  struct grub_video_mode_info mode_info;
-  int ret;
-  char *tmp;
-  const char *modevar;
-  void *framebuffer;
-  grub_err_t err;
-  struct grub_video_bitmap *bitmap = NULL;
-
-  modevar = grub_env_get ("gfxpayload");
-  /* Consider only graphical 32-bit deep modes.  */
-  if (! modevar || *modevar == 0)
-    err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
-                              GRUB_VIDEO_MODE_TYPE_PURE_TEXT
-                              | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
-                              32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
-  else
-    {
-      tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
-      if (! tmp)
-       return grub_errno;
-      err = grub_video_set_mode (tmp,
-                                GRUB_VIDEO_MODE_TYPE_PURE_TEXT
-                                | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
-                                32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
-      grub_free (tmp);
-    }
-
-  if (err)
-    return err;
-
-  ret = grub_video_get_info (&mode_info);
-  if (ret)
-    return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
-
-  if (grub_xnu_bitmap)
-    {
-      if (grub_xnu_bitmap_mode == GRUB_XNU_BITMAP_STRETCH)
-       err = grub_video_bitmap_create_scaled (&bitmap,
-                                              mode_info.width,
-                                              mode_info.height,
-                                              grub_xnu_bitmap,
-                                              GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
-      else
-       bitmap = grub_xnu_bitmap;
-    }
-
-  if (bitmap)
-    {
-      int x, y;
-
-      x = mode_info.width - bitmap->mode_info.width;
-      x /= 2;
-      y = mode_info.height - bitmap->mode_info.height;
-      y /= 2;
-      err = grub_video_blit_bitmap (bitmap,
-                                   GRUB_VIDEO_BLIT_REPLACE,
-                                   x > 0 ? x : 0,
-                                   y > 0 ? y : 0,
-                                   x < 0 ? -x : 0,
-                                   y < 0 ? -y : 0,
-                                   min (bitmap->mode_info.width,
-                                        mode_info.width),
-                                   min (bitmap->mode_info.height,
-                                        mode_info.height));
-    }
-  if (err)
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-      bitmap = 0;
-    }
-
-  ret = grub_video_get_info_and_fini (&mode_info, &framebuffer);
-  if (ret)
-    return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
-
-  params->lfb_width = mode_info.width;
-  params->lfb_height = mode_info.height;
-  params->lfb_depth = mode_info.bpp;
-  params->lfb_line_len = mode_info.pitch;
-
-  params->lfb_base = PTR_TO_UINT32 (framebuffer);
-  params->lfb_mode = bitmap ? GRUB_XNU_VIDEO_SPLASH 
-    : GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
-
-  return GRUB_ERR_NONE;
-}
-
diff --git a/loader/i386/xnu.c b/loader/i386/xnu.c
deleted file mode 100644 (file)
index 8000579..0000000
+++ /dev/null
@@ -1,1039 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/env.h>
-#include <grub/file.h>
-#include <grub/disk.h>
-#include <grub/xnu.h>
-#include <grub/cpu/xnu.h>
-#include <grub/mm.h>
-#include <grub/loader.h>
-#include <grub/autoefi.h>
-#include <grub/i386/tsc.h>
-#include <grub/efi/api.h>
-#include <grub/i386/pit.h>
-#include <grub/misc.h>
-#include <grub/charset.h>
-#include <grub/term.h>
-#include <grub/command.h>
-#include <grub/gzio.h>
-#include <grub/i18n.h>
-
-char grub_xnu_cmdline[1024];
-grub_uint32_t grub_xnu_heap_will_be_at;
-grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack;
-
-/* Aliases set for some tables. */
-struct tbl_alias
-{
-  grub_efi_guid_t guid;
-  char *name;
-};
-
-struct tbl_alias table_aliases[] =
-  {
-    {GRUB_EFI_ACPI_20_TABLE_GUID, "ACPI_20"},
-    {GRUB_EFI_ACPI_TABLE_GUID, "ACPI"},
-  };
-
-struct grub_xnu_devprop_device_descriptor
-{
-  struct grub_xnu_devprop_device_descriptor *next;
-  struct property_descriptor *properties;
-  struct grub_efi_device_path *path;
-  int pathlen;
-};
-
-static int
-utf16_strlen (grub_uint16_t *in)
-{
-  int i;
-  for (i = 0; in[i]; i++);
-  return i;
-}
-
-/* Read frequency from a string in MHz and return it in Hz. */
-static grub_uint64_t
-readfrequency (const char *str)
-{
-  grub_uint64_t num = 0;
-  int mul = 1000000;
-  int found = 0;
-
-  while (*str)
-    {
-      unsigned long digit;
-
-      digit = grub_tolower (*str) - '0';
-      if (digit > 9)
-       break;
-
-      found = 1;
-
-      num = num * 10 + digit;
-      str++;
-    }
-  num *= 1000000;
-  if (*str == '.')
-    {
-      str++;
-      while (*str)
-       {
-         unsigned long digit;
-
-         digit = grub_tolower (*str) - '0';
-         if (digit > 9)
-           break;
-
-         found = 1;
-
-         mul /= 10;
-         num = num + mul * digit;
-         str++;
-       }
-    }
-  if (! found)
-    return 0;
-
-  return num;
-}
-
-/* Thanks to Kabyl for precious information about Intel architecture. */
-static grub_uint64_t
-guessfsb (void)
-{
-  const grub_uint64_t sane_value = 100000000;
-  grub_uint32_t manufacturer[3], max_cpuid, capabilities, msrlow;
-  grub_uint64_t start_tsc;
-  grub_uint64_t end_tsc;
-  grub_uint64_t tsc_ticks_per_ms;
-
-  if (! grub_cpu_is_cpuid_supported ())
-    return sane_value;
-
-#ifdef APPLE_CC
-  asm volatile ("movl $0, %%eax\n"
-#ifdef __x86_64__
-               "push %%rbx\n"
-#else
-               "push %%ebx\n"
-#endif
-               "cpuid\n"
-#ifdef __x86_64__
-               "pop %%rbx\n"
-#else
-               "pop %%ebx\n"
-#endif
-               : "=a" (max_cpuid),
-                 "=d" (manufacturer[1]), "=c" (manufacturer[2]));
-
-  /* Only Intel for now is done. */
-  if (grub_memcmp (manufacturer + 1, "ineIntel", 12) != 0)
-    return sane_value;
-
-#else
-  asm volatile ("movl $0, %%eax\n"
-               "cpuid"
-               : "=a" (max_cpuid), "=b" (manufacturer[0]),
-                 "=d" (manufacturer[1]), "=c" (manufacturer[2]));
-
-  /* Only Intel for now is done. */
-  if (grub_memcmp (manufacturer, "GenuineIntel", 12) != 0)
-    return sane_value;
-#endif
-
-  /* Check Speedstep. */
-  if (max_cpuid < 1)
-    return sane_value;
-
-#ifdef APPLE_CC
-  asm volatile ("movl $1, %%eax\n"
-#ifdef __x86_64__
-               "push %%rbx\n"
-#else
-               "push %%ebx\n"
-#endif
-               "cpuid\n"
-#ifdef __x86_64__
-               "pop %%rbx\n"
-#else
-               "pop %%ebx\n"
-#endif
-               : "=c" (capabilities):
-               : "%rax", "%rdx");
-#else
-  asm volatile ("movl $1, %%eax\n"
-               "cpuid"
-               : "=c" (capabilities):
-               : "%rax", "%rbx", "%rdx");
-#endif
-
-  if (! (capabilities & (1 << 7)))
-    return sane_value;
-
-  /* Calibrate the TSC rate. */
-
-  start_tsc = grub_get_tsc ();
-  grub_pit_wait (0xffff);
-  end_tsc = grub_get_tsc ();
-
-  tsc_ticks_per_ms = grub_divmod64 (end_tsc - start_tsc, 55, 0);
-
-  /* Read the multiplier. */
-  asm volatile ("movl $0x198, %%ecx\n"
-               "rdmsr"
-               : "=d" (msrlow)
-               :
-               : "%ecx", "%eax");
-
-  return grub_divmod64 (2000 * tsc_ticks_per_ms,
-                       ((msrlow >> 7) & 0x3e) + ((msrlow >> 14) & 1), 0);
-}
-
-struct property_descriptor
-{
-  struct property_descriptor *next;
-  grub_uint8_t *name;
-  grub_uint16_t *name16;
-  int name16len;
-  int length;
-  void *data;
-};
-
-struct grub_xnu_devprop_device_descriptor *devices = 0;
-
-grub_err_t
-grub_xnu_devprop_remove_property (struct grub_xnu_devprop_device_descriptor *dev,
-                                 char *name)
-{
-  struct property_descriptor *prop;
-  prop = grub_named_list_find (GRUB_AS_NAMED_LIST_P (&dev->properties), name);
-  if (!prop)
-    return GRUB_ERR_NONE;
-
-  grub_free (prop->name);
-  grub_free (prop->name16);
-  grub_free (prop->data);
-
-  grub_list_remove (GRUB_AS_LIST_P (&dev->properties), GRUB_AS_LIST (prop));
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_xnu_devprop_remove_device (struct grub_xnu_devprop_device_descriptor *dev)
-{
-  void *t;
-  struct property_descriptor *prop;
-
-  grub_list_remove (GRUB_AS_LIST_P (&devices), GRUB_AS_LIST (dev));
-
-  for (prop = dev->properties; prop; )
-    {
-      grub_free (prop->name);
-      grub_free (prop->name16);
-      grub_free (prop->data);
-      t = prop;
-      prop = prop->next;
-      grub_free (t);
-    }
-
-  grub_free (dev->path);
-  grub_free (dev);
-
-  return GRUB_ERR_NONE;
-}
-
-struct grub_xnu_devprop_device_descriptor *
-grub_xnu_devprop_add_device (struct grub_efi_device_path *path, int length)
-{
-  struct grub_xnu_devprop_device_descriptor *ret;
-
-  ret = grub_zalloc (sizeof (*ret));
-  if (!ret)
-    return 0;
-
-  ret->path = grub_malloc (length);
-  if (!ret->path)
-    {
-      grub_free (ret);
-      return 0;
-    }
-  ret->pathlen = length;
-  grub_memcpy (ret->path, path, length);
-
-  grub_list_push (GRUB_AS_LIST_P (&devices), GRUB_AS_LIST (ret));
-
-  return ret;
-}
-
-static grub_err_t
-grub_xnu_devprop_add_property (struct grub_xnu_devprop_device_descriptor *dev,
-                              grub_uint8_t *utf8, grub_uint16_t *utf16,
-                              int utf16len, void *data, int datalen)
-{
-  struct property_descriptor *prop;
-
-  prop = grub_malloc (sizeof (*prop));
-  if (!prop)
-    return grub_errno;
-
-  prop->name = utf8;
-  prop->name16 = utf16;
-  prop->name16len = utf16len;
-
-  prop->length = datalen;
-  prop->data = grub_malloc (prop->length);
-  if (!prop->data)
-    {
-      grub_free (prop);
-      grub_free (prop->name);
-      grub_free (prop->name16);
-      return grub_errno;
-    }
-  grub_memcpy (prop->data, data, prop->length);
-  grub_list_push (GRUB_AS_LIST_P (&dev->properties),
-                 GRUB_AS_LIST (prop));
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *dev,
-                                   char *name, void *data, int datalen)
-{
-  grub_uint8_t *utf8;
-  grub_uint16_t *utf16;
-  int len, utf16len;
-  grub_err_t err;
-
-  utf8 = (grub_uint8_t *) grub_strdup (name);
-  if (!utf8)
-    return grub_errno;
-
-  len = grub_strlen (name);
-  utf16 = grub_malloc (sizeof (grub_uint16_t) * len);
-  if (!utf16)
-    {
-      grub_free (utf8);
-      return grub_errno;
-    }
-
-  utf16len = grub_utf8_to_utf16 (utf16, len, utf8, len, NULL);
-  if (utf16len < 0)
-    {
-      grub_free (utf8);
-      grub_free (utf16);
-      return grub_errno;
-    }
-
-  err = grub_xnu_devprop_add_property (dev, utf8, utf16,
-                                      utf16len, data, datalen);
-  if (err)
-    {
-      grub_free (utf8);
-      grub_free (utf16);
-      return err;
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor *dev,
-                                    grub_uint16_t *name, int namelen,
-                                    void *data, int datalen)
-{
-  grub_uint8_t *utf8;
-  grub_uint16_t *utf16;
-  grub_err_t err;
-
-  utf16 = grub_malloc (sizeof (grub_uint16_t) * namelen);
-  if (!utf16)
-    return grub_errno;
-  grub_memcpy (utf16, name, sizeof (grub_uint16_t) * namelen);
-
-  utf8 = grub_malloc (namelen * 4 + 1);
-  if (!utf8)
-    {
-      grub_free (utf8);
-      return grub_errno;
-    }
-
-  *grub_utf16_to_utf8 ((grub_uint8_t *) utf8, name, namelen) = '\0';
-
-  err = grub_xnu_devprop_add_property (dev, utf8, utf16,
-                                      namelen, data, datalen);
-  if (err)
-    {
-      grub_free (utf8);
-      grub_free (utf16);
-      return err;
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-static inline int
-hextoval (char c)
-{
-  if (c >= '0' && c <= '9')
-    return c - '0';
-  if (c >= 'a' && c <= 'z')
-    return c - 'a' + 10;
-  if (c >= 'A' && c <= 'Z')
-    return c - 'A' + 10;
-  return 0;
-}
-
-void
-grub_cpu_xnu_unload (void)
-{
-  struct grub_xnu_devprop_device_descriptor *dev1, *dev2;
-
-  for (dev1 = devices; dev1; )
-    {
-      dev2 = dev1->next;
-      grub_xnu_devprop_remove_device (dev1);
-      dev1 = dev2;
-    }
-}
-
-static grub_err_t
-grub_cpu_xnu_fill_devprop (void)
-{
-  struct grub_xnu_devtree_key *efikey;
-  int total_length = sizeof (struct grub_xnu_devprop_header);
-  struct grub_xnu_devtree_key *devprop;
-  struct grub_xnu_devprop_device_descriptor *device;
-  void *ptr;
-  struct grub_xnu_devprop_header *head;
-  void *t;
-  int numdevs = 0;
-
-  /* The key "efi". */
-  efikey = grub_xnu_create_key (&grub_xnu_devtree_root, "efi");
-  if (! efikey)
-    return grub_errno;
-
-  for (device = devices; device; device = device->next)
-    {
-      struct property_descriptor *propdesc;
-      total_length += sizeof (struct grub_xnu_devprop_device_header);
-      total_length += device->pathlen;
-
-      for (propdesc = device->properties; propdesc; propdesc = propdesc->next)
-       {
-         total_length += sizeof (grub_uint32_t);
-         total_length += sizeof (grub_uint16_t)
-           * (propdesc->name16len + 1);
-         total_length += sizeof (grub_uint32_t);
-         total_length += propdesc->length;
-       }
-      numdevs++;
-    }
-
-  devprop = grub_xnu_create_value (&(efikey->first_child), "device-properties");
-  if (devprop)
-    {
-      devprop->data = grub_malloc (total_length);
-      devprop->datasize = total_length;
-    }
-
-  ptr = devprop->data;
-  head = ptr;
-  ptr = head + 1;
-  head->length = total_length;
-  head->alwaysone = 1;
-  head->num_devices = numdevs;
-  for (device = devices; device; )
-    {
-      struct grub_xnu_devprop_device_header *devhead;
-      struct property_descriptor *propdesc;
-      devhead = ptr;
-      devhead->num_values = 0;
-      ptr = devhead + 1;
-
-      grub_memcpy (ptr, device->path, device->pathlen);
-      ptr = (char *) ptr + device->pathlen;
-
-      for (propdesc = device->properties; propdesc; )
-       {
-         grub_uint32_t *len;
-         grub_uint16_t *name;
-         void *data;
-
-         len = ptr;
-         *len = 2 * propdesc->name16len + sizeof (grub_uint16_t)
-           + sizeof (grub_uint32_t);
-         ptr = len + 1;
-
-         name = ptr;
-         grub_memcpy (name, propdesc->name16, 2 * propdesc->name16len);
-         name += propdesc->name16len;
-
-         /* NUL terminator.  */
-         *name = 0;
-         ptr = name + 1;
-
-         len = ptr;
-         *len = propdesc->length + sizeof (grub_uint32_t);
-         data = len + 1;
-         ptr = data;
-         grub_memcpy (ptr, propdesc->data, propdesc->length);
-         ptr = (char *) ptr + propdesc->length;
-
-         grub_free (propdesc->name);
-         grub_free (propdesc->name16);
-         grub_free (propdesc->data);
-         t = propdesc;
-         propdesc = propdesc->next;
-         grub_free (t);
-         devhead->num_values++;
-       }
-
-      devhead->length = (char *) ptr - (char *) devhead;
-      t = device;
-      device = device->next;
-      grub_free (t);
-    }
-
-  devices = 0;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_cmd_devprop_load (grub_command_t cmd __attribute__ ((unused)),
-                      int argc, char *args[])
-{
-  grub_file_t file;
-  void *buf, *bufstart, *bufend;
-  struct grub_xnu_devprop_header *head;
-  grub_size_t size;
-  unsigned i, j;
-
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
-  file = grub_gzfile_open (args[0], 1);
-  if (! file)
-    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
-                      "couldn't load device-propertie dump");
-  size = grub_file_size (file);
-  buf = grub_malloc (size);
-  if (!buf)
-    {
-      grub_file_close (file);
-      return grub_errno;
-    }
-  if (grub_file_read (file, buf, size) != (grub_ssize_t) size)
-    {
-      grub_file_close (file);
-      return grub_errno;
-    }
-  grub_file_close (file);
-
-  bufstart = buf;
-  bufend = (char *) buf + size;
-  head = buf;
-  buf = head + 1;
-  for (i = 0; i < grub_le_to_cpu32 (head->num_devices) && buf < bufend; i++)
-    {
-      struct grub_efi_device_path *dp, *dpstart;
-      struct grub_xnu_devprop_device_descriptor *dev;
-      struct grub_xnu_devprop_device_header *devhead;
-
-      devhead = buf;
-      buf = devhead + 1;
-      dpstart = buf;
-
-      do
-       {
-         dp = buf;
-         buf = (char *) buf + GRUB_EFI_DEVICE_PATH_LENGTH (dp);
-       }
-      while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp) && buf < bufend);
-
-      dev = grub_xnu_devprop_add_device (dpstart, (char *) buf
-                                        - (char *) dpstart);
-
-      for (j = 0; j < grub_le_to_cpu32 (devhead->num_values) && buf < bufend;
-          j++)
-       {
-         grub_uint32_t *namelen;
-         grub_uint32_t *datalen;
-         grub_uint16_t *utf16;
-         void *data;
-         grub_err_t err;
-
-         namelen = buf;
-         buf = namelen + 1;
-         if (buf >= bufend)
-           break;
-
-         utf16 = buf;
-         buf = (char *) buf + *namelen - sizeof (grub_uint32_t);
-         if (buf >= bufend)
-           break;
-
-         datalen = buf;
-         buf = datalen + 1;
-         if (buf >= bufend)
-           break;
-
-         data = buf;
-         buf = (char *) buf + *datalen - sizeof (grub_uint32_t);
-         if (buf >= bufend)
-           break;
-         err = grub_xnu_devprop_add_property_utf16
-           (dev, utf16, (*namelen - sizeof (grub_uint32_t)
-                         - sizeof (grub_uint16_t)) / sizeof (grub_uint16_t),
-            data, *datalen - sizeof (grub_uint32_t));
-         if (err)
-           {
-             grub_free (bufstart);
-             return err;
-           }
-       }
-    }
-
-  grub_free (bufstart);
-  return GRUB_ERR_NONE;
-}
-
-/* Fill device tree. */
-/* FIXME: some entries may be platform-agnostic. Move them to loader/xnu.c. */
-grub_err_t
-grub_cpu_xnu_fill_devicetree (void)
-{
-  struct grub_xnu_devtree_key *efikey;
-  struct grub_xnu_devtree_key *cfgtablekey;
-  struct grub_xnu_devtree_key *curval;
-  struct grub_xnu_devtree_key *runtimesrvkey;
-  struct grub_xnu_devtree_key *platformkey;
-  unsigned i, j;
-
-  /* The value "model". */
-  /* FIXME: may this value be sometimes different? */
-  curval = grub_xnu_create_value (&grub_xnu_devtree_root, "model");
-  if (! curval)
-    return grub_errno;
-  curval->datasize = sizeof ("ACPI");
-  curval->data = grub_strdup ("ACPI");
-  curval = grub_xnu_create_value (&grub_xnu_devtree_root, "compatible");
-  if (! curval)
-    return grub_errno;
-  curval->datasize = sizeof ("ACPI");
-  curval->data = grub_strdup ("ACPI");
-
-  /* The key "efi". */
-  efikey = grub_xnu_create_key (&grub_xnu_devtree_root, "efi");
-  if (! efikey)
-    return grub_errno;
-
-  /* Information about firmware. */
-  curval = grub_xnu_create_value (&(efikey->first_child), "firmware-revision");
-  if (! curval)
-    return grub_errno;
-  curval->datasize = (SYSTEM_TABLE_SIZEOF (firmware_revision));
-  curval->data = grub_malloc (curval->datasize);
-  if (! curval->data)
-    return grub_errno;
-  grub_memcpy (curval->data, (SYSTEM_TABLE_VAR(firmware_revision)),
-              curval->datasize);
-
-  curval = grub_xnu_create_value (&(efikey->first_child), "firmware-vendor");
-  if (! curval)
-    return grub_errno;
-  curval->datasize =
-    2 * (utf16_strlen (SYSTEM_TABLE_PTR (firmware_vendor)) + 1);
-  curval->data = grub_malloc (curval->datasize);
-  if (! curval->data)
-    return grub_errno;
-  grub_memcpy (curval->data, SYSTEM_TABLE_PTR (firmware_vendor),
-              curval->datasize);
-
-  curval = grub_xnu_create_value (&(efikey->first_child), "firmware-abi");
-  if (! curval)
-    return grub_errno;
-  curval->datasize = sizeof ("EFI32");
-  curval->data = grub_malloc (curval->datasize);
-  if (! curval->data)
-    return grub_errno;
-  if (SIZEOF_OF_UINTN == 4)
-    grub_memcpy (curval->data, "EFI32", curval->datasize);
-  else
-    grub_memcpy (curval->data, "EFI64", curval->datasize);
-
-  /* The key "platform". */
-  platformkey = grub_xnu_create_key (&(efikey->first_child),
-                                    "platform");
-  if (! platformkey)
-    return grub_errno;
-
-  /* Pass FSB frequency to the kernel. */
-  curval = grub_xnu_create_value (&(platformkey->first_child), "FSBFrequency");
-  if (! curval)
-    return grub_errno;
-  curval->datasize = sizeof (grub_uint64_t);
-  curval->data = grub_malloc (curval->datasize);
-  if (!curval->data)
-    return grub_errno;
-
-  /* First see if user supplies the value. */
-  char *fsbvar = grub_env_get ("fsb");
-  if (! fsbvar)
-    *((grub_uint64_t *) curval->data) = 0;
-  else
-    *((grub_uint64_t *) curval->data) = readfrequency (fsbvar);
-  /* Try autodetect. */
-  if (! *((grub_uint64_t *) curval->data))
-    *((grub_uint64_t *) curval->data) = guessfsb ();
-  grub_dprintf ("xnu", "fsb autodetected as %llu\n",
-               (unsigned long long) *((grub_uint64_t *) curval->data));
-
-  cfgtablekey = grub_xnu_create_key (&(efikey->first_child),
-                                    "configuration-table");
-  if (!cfgtablekey)
-    return grub_errno;
-
-  /* Fill "configuration-table" key. */
-  for (i = 0; i < SYSTEM_TABLE (num_table_entries); i++)
-    {
-      void *ptr;
-      struct grub_xnu_devtree_key *curkey;
-      grub_efi_guid_t guid;
-      char guidbuf[64];
-
-      /* Retrieve current key. */
-#ifdef GRUB_MACHINE_EFI
-      {
-       ptr = (void *)
-         grub_efi_system_table->configuration_table[i].vendor_table;
-       guid = grub_efi_system_table->configuration_table[i].vendor_guid;
-      }
-#else
-      if (SIZEOF_OF_UINTN == 4)
-       {
-         ptr = UINT_TO_PTR (((grub_efiemu_configuration_table32_t *)
-                             SYSTEM_TABLE_PTR (configuration_table))[i]
-                            .vendor_table);
-         guid =
-           ((grub_efiemu_configuration_table32_t *)
-            SYSTEM_TABLE_PTR (configuration_table))[i].vendor_guid;
-       }
-      else
-       {
-         ptr = UINT_TO_PTR (((grub_efiemu_configuration_table64_t *)
-                             SYSTEM_TABLE_PTR (configuration_table))[i]
-                            .vendor_table);
-         guid =
-           ((grub_efiemu_configuration_table64_t *)
-            SYSTEM_TABLE_PTR (configuration_table))[i].vendor_guid;
-       }
-#endif
-
-      /* The name of key for new table. */
-      grub_snprintf (guidbuf, sizeof (guidbuf), "%08x-%04x-%04x-%02x%02x-",
-                    guid.data1, guid.data2, guid.data3, guid.data4[0],
-                    guid.data4[1]);
-      for (j = 2; j < 8; j++)
-       grub_snprintf (guidbuf + grub_strlen (guidbuf),
-                      sizeof (guidbuf) - grub_strlen (guidbuf),
-                      "%02x", guid.data4[j]);
-      /* For some reason GUID has to be in uppercase. */
-      for (j = 0; guidbuf[j] ; j++)
-       if (guidbuf[j] >= 'a' && guidbuf[j] <= 'f')
-         guidbuf[j] += 'A' - 'a';
-      curkey = grub_xnu_create_key (&(cfgtablekey->first_child), guidbuf);
-      if (! curkey)
-       return grub_errno;
-
-      curval = grub_xnu_create_value (&(curkey->first_child), "guid");
-      if (! curval)
-       return grub_errno;
-      curval->datasize = sizeof (guid);
-      curval->data = grub_malloc (curval->datasize);
-      if (! curval->data)
-       return grub_errno;
-      grub_memcpy (curval->data, &guid, curval->datasize);
-
-      /* The value "table". */
-      curval = grub_xnu_create_value (&(curkey->first_child), "table");
-      if (! curval)
-       return grub_errno;
-      curval->datasize = SIZEOF_OF_UINTN;
-      curval->data = grub_malloc (curval->datasize);
-      if (! curval->data)
-       return grub_errno;
-      if (SIZEOF_OF_UINTN == 4)
-       *((grub_uint32_t *)curval->data) = PTR_TO_UINT32 (ptr);
-      else
-       *((grub_uint64_t *)curval->data) = PTR_TO_UINT64 (ptr);
-
-      /* Create alias. */
-      for (j = 0; j < sizeof (table_aliases) / sizeof (table_aliases[0]); j++)
-       if (grub_memcmp (&table_aliases[j].guid, &guid, sizeof (guid)) == 0)
-         break;
-      if (j != sizeof (table_aliases) / sizeof (table_aliases[0]))
-       {
-         curval = grub_xnu_create_value (&(curkey->first_child), "alias");
-         if (!curval)
-           return grub_errno;
-         curval->datasize = grub_strlen (table_aliases[j].name) + 1;
-         curval->data = grub_malloc (curval->datasize);
-         if (!curval->data)
-           return grub_errno;
-         grub_memcpy (curval->data, table_aliases[j].name, curval->datasize);
-       }
-    }
-
-  /* Create and fill "runtime-services" key. */
-  runtimesrvkey = grub_xnu_create_key (&(efikey->first_child),
-                                      "runtime-services");
-  if (! runtimesrvkey)
-    return grub_errno;
-  curval = grub_xnu_create_value (&(runtimesrvkey->first_child), "table");
-  if (! curval)
-    return grub_errno;
-  curval->datasize = SIZEOF_OF_UINTN;
-  curval->data = grub_malloc (curval->datasize);
-  if (! curval->data)
-    return grub_errno;
-  if (SIZEOF_OF_UINTN == 4)
-    *((grub_uint32_t *) curval->data)
-      = PTR_TO_UINT32 (SYSTEM_TABLE_PTR (runtime_services));
-  else
-    *((grub_uint64_t *) curval->data)
-      = PTR_TO_UINT64 (SYSTEM_TABLE_PTR (runtime_services));
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_xnu_boot_resume (void)
-{
-  struct grub_relocator32_state state;
-
-  state.esp = grub_xnu_stack;
-  state.eip = grub_xnu_entry_point;
-  state.eax = grub_xnu_arg1;
-
-  return grub_relocator32_boot (grub_xnu_heap_start, grub_xnu_heap_will_be_at,
-                               state); 
-}
-
-/* Boot xnu. */
-grub_err_t
-grub_xnu_boot (void)
-{
-  struct grub_xnu_boot_params *bootparams_relloc;
-  grub_off_t bootparams_relloc_off;
-  grub_off_t mmap_relloc_off;
-  grub_err_t err;
-  grub_efi_uintn_t memory_map_size = 0;
-  grub_efi_memory_descriptor_t *memory_map;
-  grub_efi_uintn_t map_key = 0;
-  grub_efi_uintn_t descriptor_size = 0;
-  grub_efi_uint32_t descriptor_version = 0;
-  grub_uint64_t firstruntimepage, lastruntimepage;
-  grub_uint64_t curruntimepage;
-  void *devtree;
-  grub_size_t devtreelen;
-  int i;
-  struct grub_relocator32_state state;
-
-  err = grub_autoefi_prepare ();
-  if (err)
-    return err;
-
-  err = grub_cpu_xnu_fill_devprop ();
-  if (err)
-    return err;
-
-  err = grub_cpu_xnu_fill_devicetree ();
-  if (err)
-    return err;
-
-  err = grub_xnu_fill_devicetree ();
-  if (err)
-    return err;
-
-  /* Page-align to avoid following parts to be inadvertently freed. */
-  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
-  if (err)
-    return err;
-
-  /* Pass memory map to kernel. */
-  memory_map_size = 0;
-  memory_map = 0;
-  map_key = 0;
-  descriptor_size = 0;
-  descriptor_version = 0;
-
-  grub_dprintf ("xnu", "eip=%x\n", grub_xnu_entry_point);
-
-  const char *debug = grub_env_get ("debug");
-
-  if (debug && (grub_strword (debug, "all") || grub_strword (debug, "xnu")))
-    {
-      grub_printf ("Press any key to launch xnu\n");
-      grub_getkey ();
-    }
-
-  /* Relocate the boot parameters to heap. */
-  bootparams_relloc = grub_xnu_heap_malloc (sizeof (*bootparams_relloc));
-  if (! bootparams_relloc)
-    return grub_errno;
-  bootparams_relloc_off = (grub_uint8_t *) bootparams_relloc
-    - (grub_uint8_t *) grub_xnu_heap_start;
-
-  /* Set video. */
-  err = grub_xnu_set_video (bootparams_relloc);
-  if (err != GRUB_ERR_NONE)
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-      grub_printf ("Booting in blind mode\n");
-
-      bootparams_relloc->lfb_mode = 0;
-      bootparams_relloc->lfb_width = 0;
-      bootparams_relloc->lfb_height = 0;
-      bootparams_relloc->lfb_depth = 0;
-      bootparams_relloc->lfb_line_len = 0;
-      bootparams_relloc->lfb_base = 0;
-    }
-
-  if (grub_autoefi_get_memory_map (&memory_map_size, memory_map,
-                                  &map_key, &descriptor_size,
-                                  &descriptor_version) < 0)
-    return grub_errno;
-
-  /* We will do few allocations later. Reserve some space for possible
-     memory map growth.  */
-  memory_map_size += 20 * descriptor_size;
-  memory_map = grub_xnu_heap_malloc (memory_map_size);
-  if (! memory_map)
-    return grub_errno;
-  mmap_relloc_off = (grub_uint8_t *) memory_map
-    - (grub_uint8_t *) grub_xnu_heap_start;
-
-  err = grub_xnu_writetree_toheap (&devtree, &devtreelen);
-  if (err)
-    return err;
-  bootparams_relloc = (struct grub_xnu_boot_params *)
-    (bootparams_relloc_off + (grub_uint8_t *) grub_xnu_heap_start);
-
-  grub_memcpy (bootparams_relloc->cmdline, grub_xnu_cmdline,
-              sizeof (bootparams_relloc->cmdline));
-
-  bootparams_relloc->devtree
-    = ((grub_uint8_t *) devtree - (grub_uint8_t *) grub_xnu_heap_start)
-    + grub_xnu_heap_will_be_at;
-  bootparams_relloc->devtreelen = devtreelen;
-
-  memory_map = (grub_efi_memory_descriptor_t *)
-    ((grub_uint8_t *) grub_xnu_heap_start + mmap_relloc_off);
-
-  if (grub_autoefi_get_memory_map (&memory_map_size, memory_map,
-                                  &map_key, &descriptor_size,
-                                  &descriptor_version) <= 0)
-    return grub_errno;
-
-  bootparams_relloc->efi_system_table
-    = PTR_TO_UINT32 (grub_autoefi_system_table);
-
-  firstruntimepage = (((grub_addr_t) grub_xnu_heap_will_be_at
-                      + grub_xnu_heap_size + GRUB_XNU_PAGESIZE - 1)
-                     / GRUB_XNU_PAGESIZE) + 20;
-  curruntimepage = firstruntimepage;
-
-  for (i = 0; (unsigned) i < memory_map_size / descriptor_size; i++)
-    {
-      grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *)
-       ((char *) memory_map + descriptor_size * i);
-
-      curdesc->virtual_start = curdesc->physical_start;
-
-      if (curdesc->type == GRUB_EFI_RUNTIME_SERVICES_DATA
-         || curdesc->type == GRUB_EFI_RUNTIME_SERVICES_CODE)
-       {
-         curdesc->virtual_start = curruntimepage << 12;
-         curruntimepage += curdesc->num_pages;
-         if (curdesc->physical_start
-             <= PTR_TO_UINT64 (grub_autoefi_system_table)
-             && curdesc->physical_start + (curdesc->num_pages << 12)
-             > PTR_TO_UINT64 (grub_autoefi_system_table))
-           bootparams_relloc->efi_system_table
-             = PTR_TO_UINT64 (grub_autoefi_system_table)
-             - curdesc->physical_start + curdesc->virtual_start;
-         if (SIZEOF_OF_UINTN == 8 && grub_xnu_is_64bit)
-           curdesc->virtual_start |= 0xffffff8000000000ULL;
-       }
-    }
-
-  lastruntimepage = curruntimepage;
-
-  bootparams_relloc->efi_mmap = grub_xnu_heap_will_be_at + mmap_relloc_off;
-  bootparams_relloc->efi_mmap_size = memory_map_size;
-  bootparams_relloc->efi_mem_desc_size = descriptor_size;
-  bootparams_relloc->efi_mem_desc_version = descriptor_version;
-
-  bootparams_relloc->heap_start = grub_xnu_heap_will_be_at;
-  bootparams_relloc->heap_size = grub_xnu_heap_size;
-  bootparams_relloc->efi_runtime_first_page = firstruntimepage;
-
-  bootparams_relloc->efi_runtime_npages = lastruntimepage - firstruntimepage;
-  bootparams_relloc->efi_uintnbits = SIZEOF_OF_UINTN * 8;
-
-  bootparams_relloc->verminor = GRUB_XNU_BOOTARGS_VERMINOR;
-  bootparams_relloc->vermajor = GRUB_XNU_BOOTARGS_VERMAJOR;
-
-  /* Parameters for asm helper. */
-  grub_xnu_stack = bootparams_relloc->heap_start
-    + bootparams_relloc->heap_size + GRUB_XNU_PAGESIZE;
-  grub_xnu_arg1 = bootparams_relloc_off + grub_xnu_heap_will_be_at;
-
-  if (! grub_autoefi_exit_boot_services (map_key))
-    return grub_error (GRUB_ERR_IO, "can't exit boot services");
-
-  grub_autoefi_set_virtual_address_map (memory_map_size, descriptor_size,
-                                       descriptor_version,memory_map);
-
-  state.eip = grub_xnu_entry_point;
-  state.eax = grub_xnu_arg1;
-  state.esp = grub_xnu_stack;
-  return grub_relocator32_boot (grub_xnu_heap_start, grub_xnu_heap_will_be_at,
-                               state);
-}
-
-static grub_command_t cmd_devprop_load;
-
-void
-grub_cpu_xnu_init (void)
-{
-  cmd_devprop_load = grub_register_command ("xnu_devprop_load",
-                                           grub_cmd_devprop_load,
-                                           0, N_("Load device-properties dump."));
-}
-
-void
-grub_cpu_xnu_fini (void)
-{
-  grub_unregister_command (cmd_devprop_load);
-}
diff --git a/loader/macho.c b/loader/macho.c
deleted file mode 100644 (file)
index 199d6f1..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/* macho.c - load Mach-O files. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* This Mach-O loader is incomplete and can load only non-relocatable segments.
-   This is however enough to boot xnu (otool -l and Mach-O specs for more info).
-*/
-
-#include <grub/err.h>
-#include <grub/macho.h>
-#include <grub/cpu/macho.h>
-#include <grub/machoload.h>
-#include <grub/file.h>
-#include <grub/gzio.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-
-grub_err_t
-grub_macho_close (grub_macho_t macho)
-{
-  grub_file_t file = macho->file;
-
-  grub_free (macho->cmds32);
-  grub_free (macho->cmds64);
-
-  grub_free (macho);
-
-  if (file)
-    grub_file_close (file);
-
-  return grub_errno;
-}
-
-grub_macho_t
-grub_macho_file (grub_file_t file)
-{
-  grub_macho_t macho;
-  union grub_macho_filestart filestart;
-
-  macho = grub_malloc (sizeof (*macho));
-  if (! macho)
-    return 0;
-
-  macho->file = file;
-  macho->offset32 = -1;
-  macho->offset64 = -1;
-  macho->end32 = -1;
-  macho->end64 = -1;
-  macho->cmds32 = 0;
-  macho->cmds64 = 0;
-
-  if (grub_file_seek (macho->file, 0) == (grub_off_t) -1)
-    goto fail;
-
-  if (grub_file_read (macho->file, &filestart, sizeof (filestart))
-      != sizeof (filestart))
-    {
-      grub_error_push ();
-      grub_error (GRUB_ERR_READ_ERROR, "cannot read Mach-O header");
-      goto fail;
-    }
-
-  /* Is it a fat file? */
-  if (filestart.fat.magic == grub_be_to_cpu32 (GRUB_MACHO_FAT_MAGIC))
-    {
-      struct grub_macho_fat_arch *archs;
-      int i, narchs;
-
-      /* Load architecture description. */
-      narchs = grub_be_to_cpu32 (filestart.fat.nfat_arch);
-      if (grub_file_seek (macho->file, sizeof (struct grub_macho_fat_header))
-         == (grub_off_t) -1)
-       goto fail;
-      archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs);
-      if (!archs)
-       goto fail;
-      if (grub_file_read (macho->file, archs,
-                         sizeof (struct grub_macho_fat_arch) * narchs)
-         != (grub_ssize_t)sizeof(struct grub_macho_fat_arch) * narchs)
-       {
-         grub_free (archs);
-         grub_error_push ();
-         grub_error (GRUB_ERR_READ_ERROR, "cannot read Mach-O header");
-         goto fail;
-       }
-
-      for (i = 0; i < narchs; i++)
-       {
-         if (GRUB_MACHO_CPUTYPE_IS_HOST32
-             (grub_be_to_cpu32 (archs[i].cputype)))
-           {
-             macho->offset32 = grub_be_to_cpu32 (archs[i].offset);
-             macho->end32 = grub_be_to_cpu32 (archs[i].offset)
-               + grub_be_to_cpu32 (archs[i].size);
-           }
-         if (GRUB_MACHO_CPUTYPE_IS_HOST64
-             (grub_be_to_cpu32 (archs[i].cputype)))
-           {
-             macho->offset64 = grub_be_to_cpu32 (archs[i].offset);
-             macho->end64 = grub_be_to_cpu32 (archs[i].offset)
-               + grub_be_to_cpu32 (archs[i].size);
-           }
-       }
-      grub_free (archs);
-    }
-
-  /* Is it a thin 32-bit file? */
-  if (filestart.thin32.magic == GRUB_MACHO_MAGIC32)
-    {
-      macho->offset32 = 0;
-      macho->end32 = grub_file_size (file);
-    }
-
-  /* Is it a thin 64-bit file? */
-  if (filestart.thin64.magic == GRUB_MACHO_MAGIC64)
-    {
-      macho->offset64 = 0;
-      macho->end64 = grub_file_size (file);
-    }
-
-  grub_macho_parse32 (macho);
-  grub_macho_parse64 (macho);
-
-  return macho;
-
-fail:
-  grub_macho_close (macho);
-  return 0;
-}
-
-grub_macho_t
-grub_macho_open (const char *name)
-{
-  grub_file_t file;
-  grub_macho_t macho;
-
-  file = grub_gzfile_open (name, 1);
-  if (! file)
-    return 0;
-
-  macho = grub_macho_file (file);
-  if (! macho)
-    grub_file_close (file);
-
-  return macho;
-}
diff --git a/loader/macho32.c b/loader/macho32.c
deleted file mode 100644 (file)
index 0d740ed..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <grub/cpu/macho.h>
-#include <grub/machoload.h>
-
-#define SUFFIX(x) x ## 32
-typedef struct grub_macho_header32 grub_macho_header_t;
-typedef struct grub_macho_segment32 grub_macho_segment_t;
-typedef grub_uint32_t grub_macho_addr_t;
-typedef struct grub_macho_thread32 grub_macho_thread_t;
-#define offsetXX offset32
-#define ncmdsXX ncmds32
-#define cmdsizeXX cmdsize32
-#define cmdsXX cmds32
-#define endXX end32
-#define XX "32"
-#define GRUB_MACHO_MAGIC GRUB_MACHO_MAGIC32
-#define GRUB_MACHO_CMD_SEGMENT GRUB_MACHO_CMD_SEGMENT32
-#include "machoXX.c"
-
diff --git a/loader/macho64.c b/loader/macho64.c
deleted file mode 100644 (file)
index 17a8021..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <grub/cpu/macho.h>
-#include <grub/machoload.h>
-
-#define SUFFIX(x) x ## 64
-typedef struct grub_macho_header64 grub_macho_header_t;
-typedef struct grub_macho_segment64 grub_macho_segment_t;
-typedef grub_uint64_t grub_macho_addr_t;
-typedef struct grub_macho_thread64 grub_macho_thread_t;
-#define offsetXX offset64
-#define ncmdsXX ncmds64
-#define cmdsizeXX cmdsize64
-#define cmdsXX cmds64
-#define endXX end64
-#define XX "64"
-#define GRUB_MACHO_MAGIC GRUB_MACHO_MAGIC64
-#define GRUB_MACHO_CMD_SEGMENT GRUB_MACHO_CMD_SEGMENT64
-#include "machoXX.c"
-
diff --git a/loader/machoXX.c b/loader/machoXX.c
deleted file mode 100644 (file)
index 918ddbb..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-
-int
-SUFFIX (grub_macho_contains_macho) (grub_macho_t macho)
-{
-  return macho->offsetXX != -1;
-}
-
-void
-SUFFIX (grub_macho_parse) (grub_macho_t macho)
-{
-  grub_macho_header_t head;
-
-  /* Is there any candidate at all? */
-  if (macho->offsetXX == -1)
-    return;
-
-  /* Read header and check magic*/
-  if (grub_file_seek (macho->file, macho->offsetXX) == (grub_off_t) -1
-      || grub_file_read (macho->file, &head, sizeof (head))
-      != sizeof(head))
-    {
-      grub_error (GRUB_ERR_READ_ERROR, "cannot read Mach-O header");
-      macho->offsetXX = -1;
-      return;
-    }
-  if (head.magic != GRUB_MACHO_MAGIC)
-    {
-      grub_error (GRUB_ERR_BAD_OS, "invalid Mach-O " XX "-bit header");
-      macho->offsetXX = -1;
-      return;
-    }
-
-  /* Read commands. */
-  macho->ncmdsXX = head.ncmds;
-  macho->cmdsizeXX = head.sizeofcmds;
-  macho->cmdsXX = grub_malloc(macho->cmdsizeXX);
-  if (! macho->cmdsXX)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "not enough memory to read commands");
-      return;
-    }
-  if (grub_file_read (macho->file, macho->cmdsXX,
-                     (grub_size_t) macho->cmdsizeXX)
-      != (grub_ssize_t) macho->cmdsizeXX)
-    {
-      grub_error (GRUB_ERR_READ_ERROR, "cannot read Mach-O header");
-      macho->offsetXX = -1;
-    }
-}
-
-typedef int NESTED_FUNC_ATTR (*grub_macho_iter_hook_t)
-(grub_macho_t , struct grub_macho_cmd *,
-              void *);
-
-static grub_err_t
-grub_macho_cmds_iterate (grub_macho_t macho,
-                        grub_macho_iter_hook_t hook,
-                        void *hook_arg)
-{
-  grub_uint8_t *hdrs = macho->cmdsXX;
-  int i;
-  if (! macho->cmdsXX)
-    return grub_error (GRUB_ERR_BAD_OS, "couldn't find " XX "-bit Mach-O");
-  for (i = 0; i < macho->ncmdsXX; i++)
-    {
-      struct grub_macho_cmd *hdr = (struct grub_macho_cmd *) hdrs;
-      if (hook (macho, hdr, hook_arg))
-       break;
-      hdrs += hdr->cmdsize;
-    }
-
-  return grub_errno;
-}
-
-grub_size_t
-SUFFIX (grub_macho_filesize) (grub_macho_t macho)
-{
-  if (SUFFIX (grub_macho_contains_macho) (macho))
-    return macho->endXX - macho->offsetXX;
-  return 0;
-}
-
-grub_err_t
-SUFFIX (grub_macho_readfile) (grub_macho_t macho, void *dest)
-{
-  grub_ssize_t read;
-  if (! SUFFIX (grub_macho_contains_macho) (macho))
-    return grub_error (GRUB_ERR_BAD_OS,
-                      "couldn't read architecture-specific part");
-
-  if (grub_file_seek (macho->file, macho->offsetXX) == (grub_off_t) -1)
-    {
-      grub_error_push ();
-      return grub_error (GRUB_ERR_BAD_OS,
-                        "invalid offset in program header");
-    }
-
-  read = grub_file_read (macho->file, dest,
-                        macho->endXX - macho->offsetXX);
-  if (read != (grub_ssize_t) (macho->endXX - macho->offsetXX))
-    {
-      grub_error_push ();
-      return grub_error (GRUB_ERR_BAD_OS,
-                        "couldn't read architecture-specific part");
-    }
-  return GRUB_ERR_NONE;
-}
-
-/* Calculate the amount of memory spanned by the segments. */
-grub_err_t
-SUFFIX (grub_macho_size) (grub_macho_t macho, grub_macho_addr_t *segments_start,
-                         grub_macho_addr_t *segments_end, int flags)
-{
-  int nr_phdrs = 0;
-
-  /* Run through the program headers to calculate the total memory size we
-     should claim.  */
-  auto int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho,
-                                     struct grub_macho_cmd *phdr, void *_arg);
-  int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho __attribute__ ((unused)),
-                                struct grub_macho_cmd *hdr0,
-                                void *_arg __attribute__ ((unused)))
-    {
-      grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0;
-      if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT)
-       return 0;
-
-      if (! hdr->vmsize)
-       return 0;
-
-      if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS))
-       return 0;
-
-      nr_phdrs++;
-      if (hdr->vmaddr < *segments_start)
-       *segments_start = hdr->vmaddr;
-      if (hdr->vmaddr + hdr->vmsize > *segments_end)
-       *segments_end = hdr->vmaddr + hdr->vmsize;
-      return 0;
-    }
-
-  *segments_start = (grub_macho_addr_t) -1;
-  *segments_end = 0;
-
-  grub_macho_cmds_iterate (macho, calcsize, 0);
-
-  if (nr_phdrs == 0)
-    return grub_error (GRUB_ERR_BAD_OS, "no program headers present");
-
-  if (*segments_end < *segments_start)
-    /* Very bad addresses.  */
-    return grub_error (GRUB_ERR_BAD_OS, "bad program header load addresses");
-
-  return GRUB_ERR_NONE;
-}
-
-/* Load every loadable segment into memory specified by `_load_hook'.  */
-grub_err_t
-SUFFIX (grub_macho_load) (grub_macho_t macho, char *offset, int flags)
-{
-  grub_err_t err = 0;
-  auto int NESTED_FUNC_ATTR do_load(grub_macho_t _macho,
-                              struct grub_macho_cmd *hdr0,
-                              void *_arg __attribute__ ((unused)));
-  int NESTED_FUNC_ATTR do_load(grub_macho_t _macho,
-                              struct grub_macho_cmd *hdr0,
-                              void *_arg __attribute__ ((unused)))
-  {
-    grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0;
-
-    if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT)
-      return 0;
-
-    if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS))
-      return 0;
-    if (! hdr->vmsize)
-      return 0;
-
-    if (grub_file_seek (_macho->file, hdr->fileoff
-                       + _macho->offsetXX) == (grub_off_t) -1)
-      {
-       grub_error_push ();
-       grub_error (GRUB_ERR_BAD_OS,
-                   "invalid offset in program header");
-       return 1;
-      }
-
-    if (hdr->filesize)
-      {
-       grub_ssize_t read;
-       read = grub_file_read (_macho->file, offset + hdr->vmaddr,
-                                  min (hdr->filesize, hdr->vmsize));
-       if (read != (grub_ssize_t) min (hdr->filesize, hdr->vmsize))
-         {
-           /* XXX How can we free memory from `load_hook'? */
-           grub_error_push ();
-           err=grub_error (GRUB_ERR_BAD_OS,
-                           "couldn't read segment from file: "
-                           "wanted 0x%lx bytes; read 0x%lx bytes",
-                           hdr->filesize, read);
-           return 1;
-         }
-      }
-
-    if (hdr->filesize < hdr->vmsize)
-      grub_memset (offset + hdr->vmaddr + hdr->filesize,
-                  0, hdr->vmsize - hdr->filesize);
-    return 0;
-  }
-
-  grub_macho_cmds_iterate (macho, do_load, 0);
-
-  return err;
-}
-
-grub_macho_addr_t
-SUFFIX (grub_macho_get_entry_point) (grub_macho_t macho)
-{
-  grub_macho_addr_t entry_point = 0;
-  auto int NESTED_FUNC_ATTR hook(grub_macho_t _macho,
-                                struct grub_macho_cmd *hdr,
-                                void *_arg __attribute__ ((unused)));
-  int NESTED_FUNC_ATTR hook(grub_macho_t _macho __attribute__ ((unused)),
-                           struct grub_macho_cmd *hdr,
-                           void *_arg __attribute__ ((unused)))
-  {
-    if (hdr->cmd == GRUB_MACHO_CMD_THREAD)
-      entry_point = ((grub_macho_thread_t *) hdr)->entry_point;
-    return 0;
-  }
-  grub_macho_cmds_iterate (macho, hook, 0);
-  return entry_point;
-}
diff --git a/loader/mips/linux.c b/loader/mips/linux.c
deleted file mode 100644 (file)
index 64497f4..0000000
+++ /dev/null
@@ -1,398 +0,0 @@
-/* linux.c - boot Linux */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/elf.h>
-#include <grub/elfload.h>
-#include <grub/loader.h>
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/machine/loader.h>
-#include <grub/command.h>
-#include <grub/mips/relocator.h>
-#include <grub/machine/memory.h>
-#include <grub/i18n.h>
-
-/* For frequencies.  */
-#include <grub/pci.h>
-#include <grub/machine/time.h>
-
-#define ELF32_LOADMASK (0x00000000UL)
-#define ELF64_LOADMASK (0x0000000000000000ULL)
-
-static grub_dl_t my_mod;
-
-static int loaded;
-
-static grub_size_t linux_size;
-
-static grub_uint8_t *playground;
-static grub_addr_t target_addr, entry_addr;
-static int linux_argc;
-static grub_off_t argv_off, envp_off;
-static grub_off_t rd_addr_arg_off, rd_size_arg_off;
-static int initrd_loaded = 0;
-
-static grub_err_t
-grub_linux_boot (void)
-{
-  struct grub_relocator32_state state;
-
-  /* Boot the kernel.  */
-  state.gpr[1] = entry_addr;
-  state.gpr[4] = linux_argc;
-  state.gpr[5] = target_addr + argv_off;
-  state.gpr[6] = target_addr + envp_off;
-  state.jumpreg = 1;
-  grub_relocator32_boot (playground, target_addr, state);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_linux_release_mem (void)
-{
-  grub_relocator32_free (playground);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_linux_unload (void)
-{
-  grub_err_t err;
-
-  err = grub_linux_release_mem ();
-  grub_dl_unref (my_mod);
-
-  loaded = 0;
-
-  return err;
-}
-
-static grub_err_t
-grub_linux_load32 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size)
-{
-  Elf32_Addr base;
-  int extraoff;
-
-  /* Linux's entry point incorrectly contains a virtual address.  */
-  entry_addr = elf->ehdr.ehdr32.e_entry & ~ELF32_LOADMASK;
-
-  linux_size = grub_elf32_size (elf, &base);
-  if (linux_size == 0)
-    return grub_errno;
-  target_addr = base;
-  /* Pad it; the kernel scribbles over memory beyond its load address.  */
-  linux_size += 0x100000;
-  linux_size = ALIGN_UP (base + linux_size, 4) - base;
-  extraoff = linux_size;
-  linux_size += extra_size;
-
-  playground = grub_relocator32_alloc (linux_size);
-  if (!playground)
-    return grub_errno;
-
-  *extra_mem = playground + extraoff;
-
-  /* Now load the segments into the area we claimed.  */
-  auto grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load);
-  grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load)
-    {
-      if (phdr->p_type != PT_LOAD)
-       {
-         *do_load = 0;
-         return 0;
-       }
-      *do_load = 1;
-
-      /* Linux's program headers incorrectly contain virtual addresses.
-       * Translate those to physical, and offset to the area we claimed.  */
-      *addr = (grub_addr_t) (phdr->p_paddr - base + playground);
-      return 0;
-    }
-  return grub_elf32_load (elf, offset_phdr, 0, 0);
-}
-
-static grub_err_t
-grub_linux_load64 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size)
-{
-  Elf64_Addr base;
-  int extraoff;
-
-  /* Linux's entry point incorrectly contains a virtual address.  */
-  entry_addr = elf->ehdr.ehdr64.e_entry & ~ELF64_LOADMASK;
-
-  linux_size = grub_elf64_size (elf, &base);
-  if (linux_size == 0)
-    return grub_errno;
-  target_addr = base;
-  /* Pad it; the kernel scribbles over memory beyond its load address.  */
-  linux_size += 0x100000;
-  linux_size = ALIGN_UP (base + linux_size, 4) - base;
-  extraoff = linux_size;
-  linux_size += extra_size;
-
-  playground = grub_relocator32_alloc (linux_size);
-  if (!playground)
-    return grub_errno;
-
-  *extra_mem = playground + extraoff;
-
-  /* Now load the segments into the area we claimed.  */
-  auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load);
-  grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load)
-    {
-      if (phdr->p_type != PT_LOAD)
-       {
-         *do_load = 0;
-         return 0;
-       }
-      *do_load = 1;
-      /* Linux's program headers incorrectly contain virtual addresses.
-       * Translate those to physical, and offset to the area we claimed.  */
-      *addr = (grub_addr_t) (phdr->p_paddr - base + playground);
-      return 0;
-    }
-  return grub_elf64_load (elf, offset_phdr, 0, 0);
-}
-
-static grub_err_t
-grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-               int argc, char *argv[])
-{
-  grub_elf_t elf = 0;
-  int i;
-  int size;
-  void *extra = NULL;
-  grub_uint32_t *linux_argv, *linux_envp;
-  char *linux_args, *linux_envs;
-  grub_err_t err;
-
-  if (argc == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
-
-  elf = grub_elf_open (argv[0]);
-  if (! elf)
-    return grub_errno;
-
-  if (elf->ehdr.ehdr32.e_type != ET_EXEC)
-    {
-      grub_elf_close (elf);
-      return grub_error (GRUB_ERR_UNKNOWN_OS,
-                        "this ELF file is not of the right type\n");
-    }
-
-  /* Release the previously used memory.  */
-  grub_loader_unset ();
-  loaded = 0;
-
-  /* For arguments.  */
-  linux_argc = argc;
-  /* Main arguments.  */
-  size = (linux_argc) * sizeof (grub_uint32_t); 
-  /* Initrd address and size.  */
-  size += 2 * sizeof (grub_uint32_t); 
-  /* NULL terminator.  */
-  size += sizeof (grub_uint32_t); 
-
-  /* First argument is always "a0".  */
-  size += ALIGN_UP (sizeof ("a0"), 4);
-  /* Normal arguments.  */
-  for (i = 1; i < argc; i++)
-    size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4);
-  
-  /* rd arguments.  */
-  size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4);
-  size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4);
-
-  /* For the environment.  */
-  size += sizeof (grub_uint32_t);
-  size += 4 * sizeof (grub_uint32_t);
-  size += ALIGN_UP (sizeof ("memsize=XXXXXXXXXXXXXXXXXXXX"), 4)
-    + ALIGN_UP (sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"), 4)
-    + ALIGN_UP (sizeof ("busclock=XXXXXXXXXX"), 4)
-    + ALIGN_UP (sizeof ("cpuclock=XXXXXXXXXX"), 4);
-
-  if (grub_elf_is_elf32 (elf))
-    err = grub_linux_load32 (elf, &extra, size);
-  else
-  if (grub_elf_is_elf64 (elf))
-    err = grub_linux_load64 (elf, &extra, size);
-  else
-    err = grub_error (GRUB_ERR_BAD_FILE_TYPE, "unknown ELF class");
-
-  grub_elf_close (elf);
-
-  if (err)
-    return err;
-
-  linux_argv = extra;
-  argv_off = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground;
-  extra = linux_argv + (linux_argc + 1 + 2);
-  linux_args = extra;
-
-  grub_memcpy (linux_args, "a0", sizeof ("a0"));
-  *linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground
-    + target_addr;
-  linux_argv++;
-  linux_args += ALIGN_UP (sizeof ("a0"), 4);
-
-  for (i = 1; i < argc; i++)
-    {
-      grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1);
-      *linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground
-       + target_addr;
-      linux_argv++;
-      linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4);
-    }
-
-  /* Reserve space for rd arguments.  */
-  rd_addr_arg_off = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground;
-  linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4);
-  *linux_argv = 0;
-  linux_argv++;
-
-  rd_size_arg_off = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground;
-  linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4);
-  *linux_argv = 0;
-  linux_argv++;
-
-  *linux_argv = 0;
-
-  extra = linux_args;
-
-  linux_envp = extra;
-  envp_off = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground;
-  linux_envs = (char *) (linux_envp + 5);
-  grub_snprintf (linux_envs, sizeof ("memsize=XXXXXXXXXXXXXXXXXXXX"),
-                "memsize=%lld",
-                (unsigned long long) grub_mmap_get_lower () >> 20);
-  linux_envp[0] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
-    + target_addr;
-  linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
-  grub_snprintf (linux_envs, sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"),
-                "highmemsize=%lld",
-                (unsigned long long) grub_mmap_get_upper () >> 20);
-  linux_envp[1] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
-    + target_addr;
-  linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
-
-  grub_snprintf (linux_envs, sizeof ("busclock=XXXXXXXXXX"),
-                "busclock=%d", grub_arch_busclock);
-  linux_envp[2] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
-    + target_addr;
-  linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
-  grub_snprintf (linux_envs, sizeof ("cpuclock=XXXXXXXXXX"),
-                "cpuclock=%d", grub_arch_cpuclock);
-  linux_envp[3] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
-    + target_addr;
-  linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
-
-
-  linux_envp[4] = 0;
-
-  grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
-  initrd_loaded = 0;
-  loaded = 1;
-  grub_dl_ref (my_mod);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
-                int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  grub_ssize_t size;
-  grub_size_t overhead;
-
-  if (argc == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified");
-
-  if (!loaded)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load Linux first.");
-
-  if (initrd_loaded)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "only one initrd can be loaded.");
-
-  file = grub_file_open (argv[0]);
-  if (! file)
-    return grub_errno;
-
-  size = grub_file_size (file);
-
-  overhead = ALIGN_UP (target_addr + linux_size + 0x10000, 0x10000)
-    - (target_addr + linux_size);
-
-  playground = grub_relocator32_realloc (playground,
-                                        linux_size + overhead + size);
-
-  if (!playground)
-    {
-      grub_file_close (file);
-      return grub_errno;
-    }
-
-  if (grub_file_read (file, playground + linux_size + overhead, size) != size)
-    {
-      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
-      grub_file_close (file);
-
-      return grub_errno;
-    }
-
-  grub_snprintf ((char *) playground + rd_addr_arg_off,
-                sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), "rd_start=0x%llx",
-               (unsigned long long) target_addr + linux_size  + overhead);
-  ((grub_uint32_t *) (playground + argv_off))[linux_argc]
-    = target_addr + rd_addr_arg_off;
-  linux_argc++;
-
-  grub_snprintf ((char *) playground + rd_size_arg_off,
-               sizeof ("rd_size=0xXXXXXXXXXXXXXXXXX"), "rd_size=0x%llx",
-               (unsigned long long) size);
-  ((grub_uint32_t *) (playground + argv_off))[linux_argc]
-    = target_addr + rd_size_arg_off;
-  linux_argc++;
-
-  initrd_loaded = 1;
-
-  grub_file_close (file);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_command_t cmd_linux, cmd_initrd;
-\f
-GRUB_MOD_INIT(linux)
-{
-  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
-                                    0, N_("Load Linux."));
-  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
-                                     0, N_("Load initrd."));
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(linux)
-{
-  grub_unregister_command (cmd_linux);
-  grub_unregister_command (cmd_initrd);
-}
diff --git a/loader/multiboot.c b/loader/multiboot.c
deleted file mode 100644 (file)
index 592289c..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/* multiboot.c - boot a multiboot OS image. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- *  FIXME: The following features from the Multiboot specification still
- *         need to be implemented:
- *  - VBE support
- *  - symbol table
- *  - drives table
- *  - ROM configuration table
- *  - APM table
- */
-
-#include <grub/loader.h>
-#include <grub/command.h>
-#include <grub/machine/loader.h>
-#include <grub/multiboot.h>
-#include <grub/cpu/multiboot.h>
-#include <grub/elf.h>
-#include <grub/aout.h>
-#include <grub/file.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/gzio.h>
-#include <grub/env.h>
-#include <grub/cpu/relocator.h>
-#include <grub/video.h>
-#include <grub/memory.h>
-#include <grub/i18n.h>
-
-#ifdef GRUB_MACHINE_EFI
-#include <grub/efi/efi.h>
-#endif
-
-#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
-#define DEFAULT_VIDEO_MODE "text"
-#else
-#define DEFAULT_VIDEO_MODE "auto"
-#endif
-
-grub_size_t grub_multiboot_alloc_mbi;
-
-char *grub_multiboot_payload_orig;
-grub_addr_t grub_multiboot_payload_dest;
-grub_size_t grub_multiboot_pure_size;
-grub_uint32_t grub_multiboot_payload_eip;
-static int accepts_video;
-static int accepts_ega_text;
-static int console_required;
-static grub_dl_t my_mod;
-
-
-/* Return the length of the Multiboot mmap that will be needed to allocate
-   our platform's map.  */
-grub_uint32_t
-grub_get_multiboot_mmap_count (void)
-{
-  grub_size_t count = 0;
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
-                            grub_uint64_t size __attribute__ ((unused)),
-                            grub_uint32_t type __attribute__ ((unused)))
-    {
-      count++;
-      return 0;
-    }
-
-  grub_mmap_iterate (hook);
-
-  return count;
-}
-
-grub_err_t
-grub_multiboot_set_video_mode (void)
-{
-  grub_err_t err;
-  const char *modevar;
-
-  if (accepts_video || !GRUB_MACHINE_HAS_VGA_TEXT)
-    {
-      modevar = grub_env_get ("gfxpayload");
-      if (! modevar || *modevar == 0)
-       err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0);
-      else
-       {
-         char *tmp;
-         tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
-         if (! tmp)
-           return grub_errno;
-         err = grub_video_set_mode (tmp, 0, 0);
-         grub_free (tmp);
-       }
-    }
-  else
-    err = grub_video_set_mode ("text", 0, 0);
-
-  return err;
-}
-
-static grub_err_t
-grub_multiboot_boot (void)
-{
-  grub_size_t mbi_size;
-  grub_err_t err;
-  struct grub_relocator32_state state = MULTIBOOT_INITIAL_STATE;
-
-  state.MULTIBOOT_ENTRY_REGISTER = grub_multiboot_payload_eip;
-
-  mbi_size = grub_multiboot_get_mbi_size ();
-  if (grub_multiboot_alloc_mbi < mbi_size)
-    {
-      grub_multiboot_payload_orig
-       = grub_relocator32_realloc (grub_multiboot_payload_orig,
-                                   grub_multiboot_pure_size + mbi_size);
-      if (!grub_multiboot_payload_orig)
-       return grub_errno;
-      grub_multiboot_alloc_mbi = mbi_size;
-    }
-
-  state.MULTIBOOT_MBI_REGISTER = grub_multiboot_payload_dest
-    + grub_multiboot_pure_size;
-  err = grub_multiboot_make_mbi (grub_multiboot_payload_orig,
-                                grub_multiboot_payload_dest,
-                                grub_multiboot_pure_size, mbi_size);
-  if (err)
-    return err;
-
-#ifdef GRUB_MACHINE_EFI
-  if (! grub_efi_finish_boot_services ())
-     grub_fatal ("cannot exit boot services");
-#endif
-
-  grub_relocator32_boot (grub_multiboot_payload_orig,
-                        grub_multiboot_payload_dest,
-                        state);
-
-  /* Not reached.  */
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_multiboot_unload (void)
-{
-  grub_multiboot_free_mbi ();
-
-  grub_relocator32_free (grub_multiboot_payload_orig);
-
-  grub_multiboot_alloc_mbi = 0;
-
-  grub_multiboot_payload_orig = NULL;
-  grub_dl_unref (my_mod);
-
-  return GRUB_ERR_NONE;
-}
-
-#define MULTIBOOT_LOAD_ELF64
-#include "multiboot_elfxx.c"
-#undef MULTIBOOT_LOAD_ELF64
-
-#define MULTIBOOT_LOAD_ELF32
-#include "multiboot_elfxx.c"
-#undef MULTIBOOT_LOAD_ELF32
-
-/* Load ELF32 or ELF64.  */
-grub_err_t
-grub_multiboot_load_elf (grub_file_t file, void *buffer)
-{
-  if (grub_multiboot_is_elf32 (buffer))
-    return grub_multiboot_load_elf32 (file, buffer);
-  else if (grub_multiboot_is_elf64 (buffer))
-    return grub_multiboot_load_elf64 (file, buffer);
-
-  return grub_error (GRUB_ERR_UNKNOWN_OS, "unknown ELF class");
-}
-
-grub_err_t
-grub_multiboot_set_console (int console_type, int accepted_consoles,
-                           int width, int height, int depth,
-                           int console_req)
-{
-  console_required = console_req;
-  if (!(accepted_consoles 
-       & (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER
-          | (GRUB_MACHINE_HAS_VGA_TEXT ? GRUB_MULTIBOOT_CONSOLE_EGA_TEXT : 0))))
-    {
-      if (console_required)
-       return grub_error (GRUB_ERR_BAD_OS,
-                          "OS requires a console but none is available");
-      grub_printf ("WARNING: no console will be available to OS");
-      accepts_video = 0;
-      accepts_ega_text = 0;
-      return GRUB_ERR_NONE;
-    }
-
-  if (console_type == GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER)
-    {
-      char *buf;
-      if (depth && width && height)
-       buf = grub_xasprintf ("%dx%dx%d,%dx%d,auto", width,
-                             height, depth, width, height);
-      else if (width && height)
-       buf = grub_xasprintf ("%dx%d,auto", width, height);
-      else
-       buf = grub_strdup ("auto");
-
-      if (!buf)
-       return grub_errno;
-      grub_env_set ("gfxpayload", buf);
-      grub_free (buf);
-    }
- else
-   grub_env_set ("gfxpayload", "text");
-
-  accepts_video = !!(accepted_consoles & GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER);
-  accepts_ega_text = !!(accepted_consoles & GRUB_MULTIBOOT_CONSOLE_EGA_TEXT);
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_cmd_multiboot (grub_command_t cmd __attribute__ ((unused)),
-                   int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  grub_err_t err;
-
-  grub_loader_unset ();
-
-  if (argc == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
-
-  file = grub_gzfile_open (argv[0], 1);
-  if (! file)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file");
-
-  grub_dl_ref (my_mod);
-
-  /* Skip filename.  */
-  grub_multiboot_init_mbi (argc - 1, argv + 1);
-
-  grub_relocator32_free (grub_multiboot_payload_orig);
-  grub_multiboot_payload_orig = NULL;
-
-  err = grub_multiboot_load (file);
-  if (err)
-    goto fail;
-
-  grub_multiboot_set_bootdev ();
-
-  grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0);
-
- fail:
-  if (file)
-    grub_file_close (file);
-
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_relocator32_free (grub_multiboot_payload_orig);
-      grub_multiboot_free_mbi ();
-      grub_dl_unref (my_mod);
-    }
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
-                int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  grub_ssize_t size;
-  char *module = 0;
-  grub_err_t err;
-
-  if (argc == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
-
-  if (!grub_multiboot_payload_orig)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "you need to load the multiboot kernel first");
-
-  file = grub_gzfile_open (argv[0], 1);
-  if (! file)
-    return grub_errno;
-
-  size = grub_file_size (file);
-  module = grub_memalign (MULTIBOOT_MOD_ALIGN, size);
-  if (! module)
-    {
-      grub_file_close (file);
-      return grub_errno;
-    }
-
-  err = grub_multiboot_add_module ((grub_addr_t) module, size,
-                                  argc - 1, argv + 1);
-  if (err)
-    {
-      grub_file_close (file);
-      return err;
-    }
-
-  if (grub_file_read (file, module, size) != size)
-    {
-      grub_file_close (file);
-      return grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
-    }
-
-  grub_file_close (file);
-  return GRUB_ERR_NONE;;
-}
-
-static grub_command_t cmd_multiboot, cmd_module;
-
-GRUB_MOD_INIT(multiboot)
-{
-  cmd_multiboot =
-#ifdef GRUB_USE_MULTIBOOT2
-    grub_register_command ("multiboot2", grub_cmd_multiboot,
-                          0, N_("Load a multiboot 2 kernel."));
-  cmd_module =
-    grub_register_command ("module2", grub_cmd_module,
-                          0, N_("Load a multiboot 2 module."));
-#else
-    grub_register_command ("multiboot", grub_cmd_multiboot,
-                          0, N_("Load a multiboot kernel."));
-  cmd_module =
-    grub_register_command ("module", grub_cmd_module,
-                          0, N_("Load a multiboot module."));
-#endif
-
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(multiboot)
-{
-  grub_unregister_command (cmd_multiboot);
-  grub_unregister_command (cmd_module);
-}
diff --git a/loader/multiboot_elfxx.c b/loader/multiboot_elfxx.c
deleted file mode 100644 (file)
index 92a52d3..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#if defined(MULTIBOOT_LOAD_ELF32)
-# define XX            32
-# define E_MACHINE     MULTIBOOT_ELF32_MACHINE
-# define ELFCLASSXX    ELFCLASS32
-# define Elf_Ehdr      Elf32_Ehdr
-# define Elf_Phdr      Elf32_Phdr
-#elif defined(MULTIBOOT_LOAD_ELF64)
-# define XX            64
-# define E_MACHINE     MULTIBOOT_ELF64_MACHINE
-# define ELFCLASSXX    ELFCLASS64
-# define Elf_Ehdr      Elf64_Ehdr
-# define Elf_Phdr      Elf64_Phdr
-#else
-#error "I'm confused"
-#endif
-
-#include <grub/i386/relocator.h>
-
-#define CONCAT(a,b)    CONCAT_(a, b)
-#define CONCAT_(a,b)   a ## b
-
-/* Check if BUFFER contains ELF32 (or ELF64).  */
-static int
-CONCAT(grub_multiboot_is_elf, XX) (void *buffer)
-{
-  Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer;
-
-  return ehdr->e_ident[EI_CLASS] == ELFCLASSXX;
-}
-
-static grub_err_t
-CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
-{
-  Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer;
-  char *phdr_base;
-  int lowest_segment = -1, highest_segment = -1;
-  int i;
-  grub_size_t code_size;
-
-  if (ehdr->e_ident[EI_CLASS] != ELFCLASSXX)
-    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class");
-
-  if (ehdr->e_ident[EI_MAG0] != ELFMAG0
-      || ehdr->e_ident[EI_MAG1] != ELFMAG1
-      || ehdr->e_ident[EI_MAG2] != ELFMAG2
-      || ehdr->e_ident[EI_MAG3] != ELFMAG3
-      || ehdr->e_version != EV_CURRENT
-      || ehdr->e_ident[EI_DATA] != ELFDATA2LSB
-      || ehdr->e_machine != E_MACHINE)
-    return grub_error(GRUB_ERR_UNKNOWN_OS, "no valid ELF header found");
-
-  if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
-    return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type");
-
-  /* FIXME: Should we support program headers at strange locations?  */
-  if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
-    return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
-
-#ifdef MULTIBOOT_LOAD_ELF64
-  /* We still in 32-bit mode.  */
-  if (ehdr->e_entry > 0xffffffff)
-    return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64");
-#endif
-
-  phdr_base = (char *) buffer + ehdr->e_phoff;
-#define phdr(i)                        ((Elf_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
-
-  for (i = 0; i < ehdr->e_phnum; i++)
-    if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0)
-      {
-       /* Beware that segment 0 isn't necessarily loadable */
-       if (lowest_segment == -1
-           || phdr(i)->p_paddr < phdr(lowest_segment)->p_paddr)
-         lowest_segment = i;
-       if (highest_segment == -1
-           || phdr(i)->p_paddr > phdr(highest_segment)->p_paddr)
-         highest_segment = i;
-      }
-
-  if (lowest_segment == -1)
-    return grub_error (GRUB_ERR_BAD_OS, "ELF contains no loadable segments");
-
-  code_size = (phdr(highest_segment)->p_paddr + phdr(highest_segment)->p_memsz) - phdr(lowest_segment)->p_paddr;
-  grub_multiboot_payload_dest = phdr(lowest_segment)->p_paddr;
-
-  grub_multiboot_pure_size += code_size;
-
-  grub_multiboot_alloc_mbi = grub_multiboot_get_mbi_size () + 65536;
-  grub_multiboot_payload_orig
-    = grub_relocator32_alloc (grub_multiboot_pure_size + grub_multiboot_alloc_mbi);
-
-  if (!grub_multiboot_payload_orig)
-    return grub_errno;
-
-  /* Load every loadable segment in memory.  */
-  for (i = 0; i < ehdr->e_phnum; i++)
-    {
-      if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0)
-        {
-         char *load_this_module_at = (char *) (grub_multiboot_payload_orig + (long) (phdr(i)->p_paddr - phdr(lowest_segment)->p_paddr));
-
-         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);
-
-         if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
-             == (grub_off_t) -1)
-           return grub_error (GRUB_ERR_BAD_OS,
-                              "invalid offset in program header");
-
-          if (grub_file_read (file, load_this_module_at, phdr(i)->p_filesz)
-              != (grub_ssize_t) phdr(i)->p_filesz)
-           return grub_error (GRUB_ERR_BAD_OS,
-                              "couldn't read segment from file");
-
-          if (phdr(i)->p_filesz < phdr(i)->p_memsz)
-            grub_memset (load_this_module_at + phdr(i)->p_filesz, 0,
-                        phdr(i)->p_memsz - phdr(i)->p_filesz);
-        }
-    }
-
-  for (i = 0; i < ehdr->e_phnum; i++)
-    if (phdr(i)->p_vaddr <= ehdr->e_entry
-       && phdr(i)->p_vaddr + phdr(i)->p_memsz > ehdr->e_entry)
-      {
-       grub_multiboot_payload_eip = grub_multiboot_payload_dest
-         + (ehdr->e_entry - phdr(i)->p_vaddr) + (phdr(i)->p_paddr  - phdr(lowest_segment)->p_paddr);
-       break;
-      }
-
-  if (i == ehdr->e_phnum)
-    return grub_error (GRUB_ERR_BAD_OS, "entry point isn't in a segment");
-
-#undef phdr
-
-  return grub_errno;
-}
-
-#undef XX
-#undef E_MACHINE
-#undef ELFCLASSXX
-#undef Elf_Ehdr
-#undef Elf_Phdr
diff --git a/loader/multiboot_mbi2.c b/loader/multiboot_mbi2.c
deleted file mode 100644 (file)
index 7e9cebe..0000000
+++ /dev/null
@@ -1,701 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/machine/memory.h>
-#include <grub/memory.h>
-#ifdef GRUB_MACHINE_PCBIOS
-#include <grub/machine/biosnum.h>
-#endif
-#include <grub/multiboot.h>
-#include <grub/cpu/multiboot.h>
-#include <grub/cpu/relocator.h>
-#include <grub/disk.h>
-#include <grub/device.h>
-#include <grub/partition.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/env.h>
-#include <grub/video.h>
-
-#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU)
-#include <grub/i386/pc/vbe.h>
-#define HAS_VGA_TEXT 1
-#else
-#define HAS_VGA_TEXT 0
-#endif
-
-struct module
-{
-  struct module *next;
-  grub_addr_t start;
-  grub_size_t size;
-  char *cmdline;
-  int cmdline_size;
-};
-
-struct module *modules, *modules_last;
-static grub_size_t cmdline_size;
-static grub_size_t total_modcmd;
-static unsigned modcnt;
-static char *cmdline = NULL;
-static int bootdev_set;
-static grub_uint32_t biosdev, slice, part;
-
-grub_err_t
-grub_multiboot_load (grub_file_t file)
-{
-  char *buffer;
-  grub_ssize_t len;
-  struct multiboot_header *header;
-  grub_err_t err;
-  struct multiboot_header_tag *tag;
-  struct multiboot_header_tag_address *addr_tag = NULL;
-  int entry_specified = 0;
-  grub_addr_t entry = 0;
-  grub_uint32_t console_required = 0;
-  struct multiboot_header_tag_framebuffer *fbtag = NULL;
-  int accepted_consoles = GRUB_MULTIBOOT_CONSOLE_EGA_TEXT;
-
-  buffer = grub_malloc (MULTIBOOT_SEARCH);
-  if (!buffer)
-    return grub_errno;
-
-  len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
-  if (len < 32)
-    {
-      grub_free (buffer);
-      return grub_error (GRUB_ERR_BAD_OS, "file too small");
-    }
-
-  /* Look for the multiboot header in the buffer.  The header should
-     be at least 12 bytes and aligned on a 4-byte boundary.  */
-  for (header = (struct multiboot_header *) buffer;
-       ((char *) header <= buffer + len - 12) || (header = 0);
-       header = (struct multiboot_header *) ((char *) header + MULTIBOOT_HEADER_ALIGN))
-    {
-      if (header->magic == MULTIBOOT_HEADER_MAGIC
-         && !(header->magic + header->architecture
-              + header->header_length + header->checksum)
-         && header->architecture == MULTIBOOT_ARCHITECTURE_CURRENT)
-       break;
-    }
-
-  if (header == 0)
-    {
-      grub_free (buffer);
-      return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found");
-    }
-
-  for (tag = (struct multiboot_header_tag *) (header + 1);
-       tag->type != MULTIBOOT_TAG_TYPE_END;
-       tag = (struct multiboot_header_tag *) ((char *) tag + tag->size))
-    switch (tag->type)
-      {
-      case MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST:
-       {
-         unsigned i;
-         struct multiboot_header_tag_information_request *request_tag
-           = (struct multiboot_header_tag_information_request *) tag;
-         if (request_tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL)
-           break;
-         for (i = 0; i < (request_tag->size - sizeof (request_tag))
-                / sizeof (request_tag->requests[0]); i++)
-           switch (request_tag->requests[i])
-             {
-             case MULTIBOOT_TAG_TYPE_END:
-             case MULTIBOOT_TAG_TYPE_CMDLINE:
-             case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
-             case MULTIBOOT_TAG_TYPE_MODULE:
-             case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
-             case MULTIBOOT_TAG_TYPE_BOOTDEV:
-             case MULTIBOOT_TAG_TYPE_MMAP:
-             case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
-               break;
-
-             case MULTIBOOT_TAG_TYPE_VBE:
-             case MULTIBOOT_TAG_TYPE_ELF_SECTIONS:
-             case MULTIBOOT_TAG_TYPE_APM:
-             default:
-               grub_free (buffer);
-               return grub_error (GRUB_ERR_UNKNOWN_OS,
-                                  "unsupported information tag: 0x%x",
-                                  request_tag->requests[i]);
-             }
-         break;
-       }
-              
-      case MULTIBOOT_HEADER_TAG_ADDRESS:
-       addr_tag = (struct multiboot_header_tag_address *) tag;
-       break;
-
-      case MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS:
-       entry_specified = 1;
-       entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr;
-       break;
-
-      case MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS:
-       if (!(((struct multiboot_header_tag_console_flags *) tag)->console_flags
-           & MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED))
-         accepted_consoles &= ~GRUB_MULTIBOOT_CONSOLE_EGA_TEXT;
-       if (((struct multiboot_header_tag_console_flags *) tag)->console_flags
-           & MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED)
-         console_required = 1;
-       break;
-
-      case MULTIBOOT_HEADER_TAG_FRAMEBUFFER:
-       fbtag = (struct multiboot_header_tag_framebuffer *) tag;
-       accepted_consoles |= GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER;
-       break;
-
-       /* GRUB always page-aligns modules.  */
-      case MULTIBOOT_HEADER_TAG_MODULE_ALIGN:
-       break;
-
-      default:
-       if (! (tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL))
-         {
-           grub_free (buffer);
-           return grub_error (GRUB_ERR_UNKNOWN_OS,
-                              "unsupported tag: 0x%x", tag->type);
-         }
-       break;
-      }
-
-  if (addr_tag && !entry_specified)
-    {
-      grub_free (buffer);
-      return grub_error (GRUB_ERR_UNKNOWN_OS,
-                        "load address tag without entry address tag");
-    }
-  if (addr_tag)
-    {
-      int offset = ((char *) header - buffer -
-                   (addr_tag->header_addr - addr_tag->load_addr));
-      int load_size = ((addr_tag->load_end_addr == 0) ? file->size - offset :
-                      addr_tag->load_end_addr - addr_tag->load_addr);
-      grub_size_t code_size;
-
-      if (addr_tag->bss_end_addr)
-       code_size = (addr_tag->bss_end_addr - addr_tag->load_addr);
-      else
-       code_size = load_size;
-      grub_multiboot_payload_dest = addr_tag->load_addr;
-
-      grub_multiboot_pure_size += code_size;
-
-      /* Allocate a bit more to avoid relocations in most cases.  */
-      grub_multiboot_alloc_mbi = grub_multiboot_get_mbi_size () + 65536;
-      grub_multiboot_payload_orig
-       = grub_relocator32_alloc (grub_multiboot_pure_size + grub_multiboot_alloc_mbi);
-
-      if (! grub_multiboot_payload_orig)
-       {
-         grub_free (buffer);
-         return grub_errno;
-       }
-
-      if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
-       {
-         grub_free (buffer);
-         return grub_errno;
-       }
-
-      grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size);
-      if (grub_errno)
-       {
-         grub_free (buffer);
-         return grub_errno;
-       }
-
-      if (addr_tag->bss_end_addr)
-       grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0,
-                    addr_tag->bss_end_addr - addr_tag->load_addr - load_size);
-    }
-  else
-    {
-      err = grub_multiboot_load_elf (file, buffer);
-      if (err)
-       {
-         grub_free (buffer);
-         return err;
-       }
-    }
-
-  if (entry_specified)
-    grub_multiboot_payload_eip = entry;
-
-  if (fbtag)
-    err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
-                                     accepted_consoles,
-                                     fbtag->width, fbtag->height,
-                                     fbtag->depth, console_required);
-  else
-    err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT,
-                                     accepted_consoles,
-                                     0, 0, 0, console_required);
-  return err;
-}
-
-grub_size_t
-grub_multiboot_get_mbi_size (void)
-{
-  return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
-    + (sizeof (struct multiboot_tag_string)
-       + ALIGN_UP (cmdline_size, MULTIBOOT_TAG_ALIGN))
-    + (sizeof (struct multiboot_tag_string)
-       + ALIGN_UP (sizeof (PACKAGE_STRING), MULTIBOOT_TAG_ALIGN))
-    + (modcnt * sizeof (struct multiboot_tag_module) + total_modcmd)
-    + sizeof (struct multiboot_tag_basic_meminfo)
-    + ALIGN_UP (sizeof (struct multiboot_tag_bootdev), MULTIBOOT_TAG_ALIGN)
-    + (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_count ()
-       * sizeof (struct multiboot_mmap_entry))
-    + sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1;
-}
-
-/* Fill previously allocated Multiboot mmap.  */
-static void
-grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag)
-{
-  struct multiboot_mmap_entry *mmap_entry = tag->entries;
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
-    {
-      mmap_entry->addr = addr;
-      mmap_entry->len = size;
-      switch (type)
-       {
-       case GRUB_MACHINE_MEMORY_AVAILABLE:
-         mmap_entry->type = MULTIBOOT_MEMORY_AVAILABLE;
-         break;
-
-#ifdef GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE
-       case GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE:
-         mmap_entry->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE;
-         break;
-#endif
-
-#ifdef GRUB_MACHINE_MEMORY_NVS
-       case GRUB_MACHINE_MEMORY_NVS:
-         mmap_entry->type = MULTIBOOT_MEMORY_NVS;
-         break;
-#endif   
-         
-       default:
-         mmap_entry->type = MULTIBOOT_MEMORY_RESERVED;
-         break;
-       }
-      mmap_entry++;
-
-      return 0;
-    }
-
-  tag->type = MULTIBOOT_TAG_TYPE_MMAP;
-  tag->size = sizeof (struct multiboot_tag_mmap)
-    + sizeof (struct multiboot_mmap_entry) * grub_get_multiboot_mmap_count (); 
-  tag->entry_size = sizeof (struct multiboot_mmap_entry);
-  tag->entry_version = 0;
-
-  grub_mmap_iterate (hook);
-}
-
-static grub_err_t
-retrieve_video_parameters (grub_uint8_t **ptrorig)
-{
-  grub_err_t err;
-  struct grub_video_mode_info mode_info;
-  void *framebuffer;
-  grub_video_driver_id_t driv_id;
-  struct grub_video_palette_data palette[256];
-  struct multiboot_tag_framebuffer *tag
-    = (struct multiboot_tag_framebuffer *) *ptrorig;
-
-  err = grub_multiboot_set_video_mode ();
-  if (err)
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-    }
-
-  grub_video_get_palette (0, ARRAY_SIZE (palette), palette);
-
-  driv_id = grub_video_get_driver_id ();
-#if HAS_VGA_TEXT
-  if (driv_id == GRUB_VIDEO_DRIVER_NONE)
-    {
-      struct grub_vbe_mode_info_block vbe_mode_info;
-      grub_uint32_t vbe_mode;
-
-#if defined (GRUB_MACHINE_PCBIOS)
-      {
-       grub_vbe_status_t status;
-       void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
-       status = grub_vbe_bios_get_mode (scratch);
-       vbe_mode = *(grub_uint32_t *) scratch;
-       if (status != GRUB_VBE_STATUS_OK)
-         return GRUB_ERR_NONE;
-      }
-#else
-      vbe_mode = 3;
-#endif
-
-      /* get_mode_info isn't available for mode 3.  */
-      if (vbe_mode == 3)
-       {
-         grub_memset (&vbe_mode_info, 0,
-                      sizeof (struct grub_vbe_mode_info_block));
-         vbe_mode_info.memory_model = GRUB_VBE_MEMORY_MODEL_TEXT;
-         vbe_mode_info.x_resolution = 80;
-         vbe_mode_info.y_resolution = 25;
-       }
-#if defined (GRUB_MACHINE_PCBIOS)
-      else
-       {
-         grub_vbe_status_t status;
-         void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
-         status = grub_vbe_bios_get_mode_info (vbe_mode, scratch);
-         if (status != GRUB_VBE_STATUS_OK)
-           return GRUB_ERR_NONE;
-         grub_memcpy (&vbe_mode_info, scratch,
-                      sizeof (struct grub_vbe_mode_info_block));
-       }
-#endif
-
-      if (vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_TEXT)
-       {
-         tag = (struct multiboot_tag_framebuffer *) *ptrorig;
-         tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER;
-         tag->common.size = 0;
-
-         tag->common.framebuffer_addr = 0xb8000;
-         
-         tag->common.framebuffer_pitch = 2 * vbe_mode_info.x_resolution;       
-         tag->common.framebuffer_width = vbe_mode_info.x_resolution;
-         tag->common.framebuffer_height = vbe_mode_info.y_resolution;
-
-         tag->common.framebuffer_bpp = 16;
-         
-         tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT;
-         tag->common.size = sizeof (tag->common);
-         tag->common.reserved = 0;
-         *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN);
-       }
-      return GRUB_ERR_NONE;
-    }
-#else
-  if (driv_id == GRUB_VIDEO_DRIVER_NONE)
-    return GRUB_ERR_NONE;
-#endif
-
-  err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
-  if (err)
-    return err;
-
-  tag = (struct multiboot_tag_framebuffer *) *ptrorig;
-  tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER;
-  tag->common.size = 0;
-
-  tag->common.framebuffer_addr = (grub_addr_t) framebuffer;
-  tag->common.framebuffer_pitch = mode_info.pitch;
-
-  tag->common.framebuffer_width = mode_info.width;
-  tag->common.framebuffer_height = mode_info.height;
-
-  tag->common.framebuffer_bpp = mode_info.bpp;
-
-  tag->common.reserved = 0;
-      
-  if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
-    {
-      unsigned i;
-      tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED;
-      tag->framebuffer_palette_num_colors = mode_info.number_of_colors;
-      if (tag->framebuffer_palette_num_colors > ARRAY_SIZE (palette))
-       tag->framebuffer_palette_num_colors = ARRAY_SIZE (palette);
-      tag->common.size = sizeof (struct multiboot_tag_framebuffer_common)
-       + sizeof (multiboot_uint16_t) + tag->framebuffer_palette_num_colors
-       * sizeof (struct multiboot_color);
-      for (i = 0; i < tag->framebuffer_palette_num_colors; i++)
-       {
-         tag->framebuffer_palette[i].red = palette[i].r;
-         tag->framebuffer_palette[i].green = palette[i].g;
-         tag->framebuffer_palette[i].blue = palette[i].b;
-       }
-    }
-  else
-    {
-      tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
-      tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
-      tag->framebuffer_red_field_position = mode_info.green_field_pos;
-      tag->framebuffer_red_mask_size = mode_info.green_mask_size;
-      tag->framebuffer_green_field_position = mode_info.green_field_pos;
-      tag->framebuffer_green_mask_size = mode_info.green_mask_size;
-      tag->framebuffer_blue_field_position = mode_info.blue_field_pos;
-      tag->framebuffer_blue_mask_size = mode_info.blue_mask_size;
-
-      tag->common.size = sizeof (struct multiboot_tag_framebuffer_common) + 6;
-    }
-  *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN);
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
-                        grub_size_t bufsize)
-{
-  grub_uint8_t *ptrorig;
-  grub_uint8_t *mbistart = (grub_uint8_t *) orig + buf_off 
-    + (ALIGN_UP (dest + buf_off, MULTIBOOT_TAG_ALIGN) - (dest + buf_off));
-  grub_err_t err;
-
-  if (bufsize < grub_multiboot_get_mbi_size ())
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small");
-
-  ptrorig = mbistart + 2 * sizeof (grub_uint32_t);
-
-  {
-    struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
-    tag->type = MULTIBOOT_TAG_TYPE_CMDLINE;
-    tag->size = sizeof (struct multiboot_tag_string) + cmdline_size; 
-    grub_memcpy (tag->string, cmdline, cmdline_size);
-    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
-  }
-
-  {
-    struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
-    tag->type = MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME;
-    tag->size = sizeof (struct multiboot_tag_string) + sizeof (PACKAGE_STRING); 
-    grub_memcpy (tag->string, PACKAGE_STRING, sizeof (PACKAGE_STRING));
-    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
-  }
-
-  {
-    unsigned i;
-    struct module *cur;
-
-    for (i = 0, cur = modules; i < modcnt; i++, cur = cur->next)
-      {
-       struct multiboot_tag_module *tag
-         = (struct multiboot_tag_module *) ptrorig;
-       tag->type = MULTIBOOT_TAG_TYPE_MODULE;
-       tag->size = sizeof (struct multiboot_tag_module) + cur->cmdline_size;
-       tag->mod_start = dest + cur->start;
-       tag->mod_end = tag->mod_start + cur->size;
-       grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size);
-       ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
-      }
-  }
-
-  {
-    struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
-    grub_fill_multiboot_mmap (tag);
-    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
-  }
-
-  {
-    struct multiboot_tag_basic_meminfo *tag
-      = (struct multiboot_tag_basic_meminfo *) ptrorig;
-    tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
-    tag->size = sizeof (struct multiboot_tag_basic_meminfo); 
-
-    /* Convert from bytes to kilobytes.  */
-    tag->mem_lower = grub_mmap_get_lower () / 1024;
-    tag->mem_upper = grub_mmap_get_upper () / 1024;
-    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
-  }
-
-  if (bootdev_set)
-    {
-      struct multiboot_tag_bootdev *tag
-       = (struct multiboot_tag_bootdev *) ptrorig;
-      tag->type = MULTIBOOT_TAG_TYPE_BOOTDEV;
-      tag->size = sizeof (struct multiboot_tag_bootdev); 
-
-      tag->biosdev = biosdev;
-      tag->slice = slice;
-      tag->part = part;
-      ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
-    }
-
-  {
-    err = retrieve_video_parameters (&ptrorig);
-    if (err)
-      {
-       grub_print_error ();
-       grub_errno = GRUB_ERR_NONE;
-      }
-  }
-  
-  {
-    struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
-    tag->type = MULTIBOOT_TAG_TYPE_END;
-    tag->size = sizeof (struct multiboot_tag);
-    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
-  }
-
-  ((grub_uint32_t *) mbistart)[0] = ptrorig - mbistart;
-  ((grub_uint32_t *) mbistart)[1] = 0;
-
-  return GRUB_ERR_NONE;
-}
-
-void
-grub_multiboot_free_mbi (void)
-{
-  struct module *cur, *next;
-
-  cmdline_size = 0;
-  total_modcmd = 0;
-  modcnt = 0;
-  grub_free (cmdline);
-  cmdline = NULL;
-  bootdev_set = 0;
-
-  for (cur = modules; cur; cur = next)
-    {
-      next = cur->next;
-      grub_free (cur->cmdline);
-      grub_free (cur);
-    }
-  modules = NULL;
-  modules_last = NULL;
-}
-
-grub_err_t
-grub_multiboot_init_mbi (int argc, char *argv[])
-{
-  grub_ssize_t len = 0;
-  char *p;
-  int i;
-
-  grub_multiboot_free_mbi ();
-
-  for (i = 0; i < argc; i++)
-    len += grub_strlen (argv[i]) + 1;
-  if (len == 0)
-    len = 1;
-
-  cmdline = p = grub_malloc (len);
-  if (! cmdline)
-    return grub_errno;
-  cmdline_size = len;
-
-  for (i = 0; i < argc; i++)
-    {
-      p = grub_stpcpy (p, argv[i]);
-      *(p++) = ' ';
-    }
-
-  /* Remove the space after the last word.  */
-  if (p != cmdline)
-    p--;
-  *p = '\0';
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
-                          int argc, char *argv[])
-{
-  struct module *newmod;
-  char *p;
-  grub_ssize_t len = 0;
-  int i;
-
-  newmod = grub_malloc (sizeof (*newmod));
-  if (!newmod)
-    return grub_errno;
-  newmod->start = start;
-  newmod->size = size;
-
-  for (i = 0; i < argc; i++)
-    len += grub_strlen (argv[i]) + 1;
-
-  if (len == 0)
-    len = 1;
-
-  newmod->cmdline = p = grub_malloc (len);
-  if (! newmod->cmdline)
-    {
-      grub_free (newmod);
-      return grub_errno;
-    }
-  newmod->cmdline_size = len;
-  total_modcmd += ALIGN_UP (len, MULTIBOOT_TAG_ALIGN);
-
-  for (i = 0; i < argc; i++)
-    {
-      p = grub_stpcpy (p, argv[i]);
-      *(p++) = ' ';
-    }
-
-  /* Remove the space after the last word.  */
-  if (p != newmod->cmdline)
-    p--;
-  *p = '\0';
-
-  if (modules_last)
-    modules_last->next = newmod;
-  else
-    {
-      modules = newmod;
-      modules_last->next = NULL;
-    }
-  modules_last = newmod;
-
-  modcnt++;
-
-  return GRUB_ERR_NONE;
-}
-
-void
-grub_multiboot_set_bootdev (void)
-{
-  grub_device_t dev;
-
-  slice = ~0;
-  part = ~0;
-
-#ifdef GRUB_MACHINE_PCBIOS
-  biosdev = grub_get_root_biosnumber ();
-#else
-  biosdev = 0xffffffff;
-#endif
-
-  if (biosdev == 0xffffffff)
-    return;
-
-  dev = grub_device_open (0);
-  if (dev && dev->disk && dev->disk->partition)
-    {
-      if (dev->disk->partition->parent)
-       {
-         part = dev->disk->partition->number;
-         slice = dev->disk->partition->parent->number;
-       }
-      else
-       slice = dev->disk->partition->number;
-    }
-  if (dev)
-    grub_device_close (dev);
-
-  bootdev_set = 1;
-}
diff --git a/loader/powerpc/ieee1275/linux.c b/loader/powerpc/ieee1275/linux.c
deleted file mode 100644 (file)
index 930c0cb..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-/* linux.c - boot Linux */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/elf.h>
-#include <grub/elfload.h>
-#include <grub/loader.h>
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/ieee1275/ieee1275.h>
-#include <grub/machine/loader.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-#define ELF32_LOADMASK (0xc0000000UL)
-#define ELF64_LOADMASK (0xc000000000000000ULL)
-
-static grub_dl_t my_mod;
-
-static int loaded;
-
-static grub_addr_t initrd_addr;
-static grub_size_t initrd_size;
-
-static grub_addr_t linux_addr;
-static grub_size_t linux_size;
-
-static char *linux_args;
-
-typedef void (*kernel_entry_t) (void *, unsigned long, int (void *),
-                               unsigned long, unsigned long);
-
-static grub_err_t
-grub_linux_boot (void)
-{
-  kernel_entry_t linuxmain;
-  grub_ssize_t actual;
-
-  /* Set the command line arguments.  */
-  grub_ieee1275_set_property (grub_ieee1275_chosen, "bootargs", linux_args,
-                             grub_strlen (linux_args) + 1, &actual);
-
-  grub_dprintf ("loader", "Entry point: 0x%x\n", linux_addr);
-  grub_dprintf ("loader", "Initrd at: 0x%x, size 0x%x\n", initrd_addr,
-               initrd_size);
-  grub_dprintf ("loader", "Boot arguments: %s\n", linux_args);
-  grub_dprintf ("loader", "Jumping to Linux...\n");
-
-  /* Boot the kernel.  */
-  linuxmain = (kernel_entry_t) linux_addr;
-  linuxmain ((void *) initrd_addr, initrd_size, grub_ieee1275_entry_fn, 0, 0);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_linux_release_mem (void)
-{
-  grub_free (linux_args);
-  linux_args = 0;
-
-  if (linux_addr && grub_ieee1275_release (linux_addr, linux_size))
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot release memory");
-
-  if (initrd_addr && grub_ieee1275_release (initrd_addr, initrd_size))
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot release memory");
-
-  linux_addr = 0;
-  initrd_addr = 0;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_linux_unload (void)
-{
-  grub_err_t err;
-
-  err = grub_linux_release_mem ();
-  grub_dl_unref (my_mod);
-
-  loaded = 0;
-
-  return err;
-}
-
-static grub_err_t
-grub_linux_load32 (grub_elf_t elf)
-{
-  Elf32_Addr entry;
-  int found_addr = 0;
-
-  /* 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, 0);
-  if (linux_size == 0)
-    return grub_errno;
-  /* Pad it; the kernel scribbles over memory beyond its load address.  */
-  linux_size += 0x100000;
-
-  /* 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",
-                   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, "couldn't claim memory");
-
-  /* Now load the segments into the area we claimed.  */
-  auto grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load);
-  grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load)
-    {
-      if (phdr->p_type != PT_LOAD)
-       {
-         *do_load = 0;
-         return 0;
-       }
-      *do_load = 1;
-
-      /* 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;
-    }
-  return grub_elf32_load (elf, offset_phdr, 0, 0);
-}
-
-static grub_err_t
-grub_linux_load64 (grub_elf_t elf)
-{
-  Elf64_Addr entry;
-  int found_addr = 0;
-
-  /* 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, 0);
-  if (linux_size == 0)
-    return grub_errno;
-  /* Pad it; the kernel scribbles over memory beyond its load address.  */
-  linux_size += 0x100000;
-
-  /* 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",
-                   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, "couldn't claim memory");
-
-  /* Now load the segments into the area we claimed.  */
-  auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load);
-  grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load)
-    {
-      if (phdr->p_type != PT_LOAD)
-       {
-         *do_load = 0;
-         return 0;
-       }
-      *do_load = 1;
-      /* 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;
-    }
-  return grub_elf64_load (elf, offset_phdr, 0, 0);
-}
-
-static grub_err_t
-grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-               int argc, char *argv[])
-{
-  grub_elf_t elf = 0;
-  int i;
-  int size;
-  char *dest;
-
-  grub_dl_ref (my_mod);
-
-  if (argc == 0)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
-      goto out;
-    }
-
-  elf = grub_elf_open (argv[0]);
-  if (! elf)
-    goto out;
-
-  if (elf->ehdr.ehdr32.e_type != ET_EXEC)
-    {
-      grub_error (GRUB_ERR_UNKNOWN_OS,
-                 "this ELF file is not of the right type");
-      goto out;
-    }
-
-  /* Release the previously used memory.  */
-  grub_loader_unset ();
-
-  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]);
-  for (i = 0; i < argc; i++)
-    size += grub_strlen (argv[i]) + 1;
-
-  linux_args = grub_malloc (size);
-  if (! linux_args)
-    goto out;
-
-  /* Specify the boot file.  */
-  dest = grub_stpcpy (linux_args, "BOOT_IMAGE=");
-  dest = grub_stpcpy (dest, argv[0]);
-
-  for (i = 1; i < argc; i++)
-    {
-      *dest++ = ' ';
-      dest = grub_stpcpy (dest, argv[i]);
-    }
-
-out:
-
-  if (elf)
-    grub_elf_close (elf);
-
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_linux_release_mem ();
-      grub_dl_unref (my_mod);
-      loaded = 0;
-    }
-  else
-    {
-      grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
-      initrd_addr = 0;
-      loaded = 1;
-    }
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
-                int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  grub_ssize_t size;
-  grub_addr_t first_addr;
-  grub_addr_t addr;
-  int found_addr = 0;
-
-  if (argc == 0)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified");
-      goto fail;
-    }
-
-  if (!loaded)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
-      goto fail;
-    }
-
-  file = grub_file_open (argv[0]);
-  if (! file)
-    goto fail;
-
-  first_addr = linux_addr + linux_size;
-  size = grub_file_size (file);
-
-  /* Attempt to claim at a series of addresses until successful in
-     the same way that grub_rescue_cmd_linux does.  */
-  for (addr = first_addr; addr < first_addr + 200 * 0x100000; addr += 0x100000)
-    {
-      grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n",
-                   addr, size);
-      found_addr = grub_claimmap (addr, size);
-      if (found_addr != -1)
-       break;
-    }
-
-  if (found_addr == -1)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot claim memory");
-      goto fail;
-    }
-
-  grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size);
-
-  if (grub_file_read (file, (void *) addr, size) != size)
-    {
-      grub_ieee1275_release (addr, size);
-      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
-      goto fail;
-    }
-
-  initrd_addr = addr;
-  initrd_size = size;
-
- fail:
-  if (file)
-    grub_file_close (file);
-
-  return grub_errno;
-}
-
-static grub_command_t cmd_linux, cmd_initrd;
-\f
-GRUB_MOD_INIT(linux)
-{
-  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
-                                    0, N_("Load Linux."));
-  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
-                                     0, N_("Load initrd."));
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(linux)
-{
-  grub_unregister_command (cmd_linux);
-  grub_unregister_command (cmd_initrd);
-}
diff --git a/loader/sparc64/ieee1275/linux.c b/loader/sparc64/ieee1275/linux.c
deleted file mode 100644 (file)
index f55b4fa..0000000
+++ /dev/null
@@ -1,529 +0,0 @@
-/* linux.c - boot Linux */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003, 2004, 2005, 2007, 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/elf.h>
-#include <grub/elfload.h>
-#include <grub/loader.h>
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/ieee1275/ieee1275.h>
-#include <grub/machine/loader.h>
-#include <grub/gzio.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-static grub_dl_t my_mod;
-
-static int loaded;
-
-/* /virtual-memory/translations property layout  */
-struct grub_ieee1275_translation {
-  grub_uint64_t vaddr;
-  grub_uint64_t size;
-  grub_uint64_t data;
-};
-
-static struct grub_ieee1275_translation *of_trans;
-static int of_num_trans;
-
-static grub_addr_t phys_base;
-static grub_addr_t grub_phys_start;
-static grub_addr_t grub_phys_end;
-
-static grub_addr_t initrd_addr;
-static grub_addr_t initrd_paddr;
-static grub_size_t initrd_size;
-
-static Elf64_Addr linux_entry;
-static grub_addr_t linux_addr;
-static grub_addr_t linux_paddr;
-static grub_size_t linux_size;
-
-static char *linux_args;
-
-struct linux_bootstr_info {
-       int len, valid;
-       char buf[];
-};
-
-struct linux_hdrs {
-       /* All HdrS versions support these fields.  */
-       unsigned int start_insns[2];
-       char magic[4]; /* "HdrS" */
-       unsigned int linux_kernel_version; /* LINUX_VERSION_CODE */
-       unsigned short hdrs_version;
-       unsigned short root_flags;
-       unsigned short root_dev;
-       unsigned short ram_flags;
-       unsigned int __deprecated_ramdisk_image;
-       unsigned int ramdisk_size;
-
-       /* HdrS versions 0x0201 and higher only */
-       char *reboot_command;
-
-       /* HdrS versions 0x0202 and higher only */
-       struct linux_bootstr_info *bootstr_info;
-
-       /* HdrS versions 0x0301 and higher only */
-       unsigned long ramdisk_image;
-};
-
-static grub_err_t
-grub_linux_boot (void)
-{
-  struct linux_bootstr_info *bp;
-  struct linux_hdrs *hp;
-  grub_addr_t addr;
-
-  hp = (struct linux_hdrs *) linux_addr;
-
-  /* Any pointer we dereference in the kernel image must be relocated
-     to where we actually loaded the kernel.  */
-  addr = (grub_addr_t) hp->bootstr_info;
-  addr += (linux_addr - linux_entry);
-  bp = (struct linux_bootstr_info *) addr;
-
-  /* Set the command line arguments, unless the kernel has been
-     built with a fixed CONFIG_CMDLINE.  */
-  if (!bp->valid)
-    {
-      int len = grub_strlen (linux_args) + 1;
-      if (bp->len < len)
-       len = bp->len;
-      memcpy(bp->buf, linux_args, len);
-      bp->buf[len-1] = '\0';
-      bp->valid = 1;
-    }
-
-  if (initrd_addr)
-    {
-      /* The kernel expects the physical address, adjusted relative
-        to the lowest address advertised in "/memory"'s available
-        property.
-
-        The history of this is that back when the kernel only supported
-        specifying a 32-bit ramdisk address, this was the way to still
-        be able to specify the ramdisk physical address even if memory
-        started at some place above 4GB.
-
-        The magic 0x400000 is KERNBASE, I have no idea why SILO adds
-        that term into the address, but it does and thus we have to do
-        it too as this is what the kernel expects.  */
-      hp->ramdisk_image = initrd_paddr - phys_base + 0x400000;
-      hp->ramdisk_size = initrd_size;
-    }
-
-  grub_dprintf ("loader", "Entry point: 0x%lx\n", linux_addr);
-  grub_dprintf ("loader", "Initrd at: 0x%lx, size 0x%lx\n", initrd_addr,
-               initrd_size);
-  grub_dprintf ("loader", "Boot arguments: %s\n", linux_args);
-  grub_dprintf ("loader", "Jumping to Linux...\n");
-
-  /* Boot the kernel.  */
-  asm volatile ("sethi %hi(grub_ieee1275_entry_fn), %o1\n"
-               "ldx    [%o1 + %lo(grub_ieee1275_entry_fn)], %o4\n"
-               "sethi  %hi(grub_ieee1275_original_stack), %o1\n"
-               "ldx    [%o1 + %lo(grub_ieee1275_original_stack)], %o6\n"
-               "sethi  %hi(linux_addr), %o1\n"
-               "ldx    [%o1 + %lo(linux_addr)], %o5\n"
-               "mov    %g0, %o0\n"
-               "mov    %g0, %o2\n"
-               "mov    %g0, %o3\n"
-               "jmp    %o5\n"
-               "mov    %g0, %o1\n");
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_linux_release_mem (void)
-{
-  grub_free (linux_args);
-  linux_args = 0;
-  linux_addr = 0;
-  initrd_addr = 0;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_linux_unload (void)
-{
-  grub_err_t err;
-
-  err = grub_linux_release_mem ();
-  grub_dl_unref (my_mod);
-
-  loaded = 0;
-
-  return err;
-}
-
-#define FOUR_MB        (4 * 1024 * 1024)
-
-static grub_addr_t
-alloc_phys (grub_addr_t size)
-{
-  grub_addr_t ret = (grub_addr_t) -1;
-
-  auto int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type);
-  int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type)
-  {
-    grub_addr_t end = addr + len;
-
-    if (type != 1)
-      return 0;
-
-    addr = ALIGN_UP (addr, FOUR_MB);
-    if (addr + size >= end)
-      return 0;
-
-    if (addr >= grub_phys_start && addr < grub_phys_end)
-      {
-       addr = ALIGN_UP (grub_phys_end, FOUR_MB);
-       if (addr + size >= end)
-         return 0;
-      }
-    if ((addr + size) >= grub_phys_start
-       && (addr + size) < grub_phys_end)
-      {
-       addr = ALIGN_UP (grub_phys_end, FOUR_MB);
-       if (addr + size >= end)
-         return 0;
-      }
-
-    if (loaded)
-      {
-       grub_addr_t linux_end = ALIGN_UP (linux_paddr + linux_size, FOUR_MB);
-
-       if (addr >= linux_paddr && addr < linux_end)
-         {
-           addr = linux_end;
-           if (addr + size >= end)
-             return 0;
-         }
-       if ((addr + size) >= linux_paddr
-           && (addr + size) < linux_end)
-         {
-           addr = linux_end;
-           if (addr + size >= end)
-             return 0;
-         }
-      }
-
-    ret = addr;
-    return 1;
-  }
-
-  grub_machine_mmap_iterate (choose);
-
-  return ret;
-}
-
-static grub_err_t
-grub_linux_load64 (grub_elf_t elf)
-{
-  grub_addr_t off, paddr, base;
-  int ret;
-
-  linux_entry = elf->ehdr.ehdr64.e_entry;
-  linux_addr = 0x40004000;
-  off = 0x4000;
-  linux_size = grub_elf64_size (elf, 0);
-  if (linux_size == 0)
-    return grub_errno;
-
-  grub_dprintf ("loader", "Attempting to claim at 0x%lx, size 0x%lx.\n",
-               linux_addr, linux_size);
-
-  paddr = alloc_phys (linux_size + off);
-  if (paddr == (grub_addr_t) -1)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                      "couldn't allocate physical memory");
-  ret = grub_ieee1275_map (paddr, linux_addr - off,
-                          linux_size + off, IEEE1275_MAP_DEFAULT);
-  if (ret)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                      "couldn't map physical memory");
-
-  grub_dprintf ("loader", "Loading Linux at vaddr 0x%lx, paddr 0x%lx, size 0x%lx\n",
-               linux_addr, paddr, linux_size);
-
-  linux_paddr = paddr;
-
-  base = linux_entry - off;
-
-  /* Now load the segments into the area we claimed.  */
-  auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load);
-  grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load)
-    {
-      if (phdr->p_type != PT_LOAD)
-       {
-         *do_load = 0;
-         return 0;
-       }
-      *do_load = 1;
-
-      /* Adjust the program load address to linux_addr.  */
-      *addr = (phdr->p_paddr - base) + (linux_addr - off);
-      return 0;
-    }
-  return grub_elf64_load (elf, offset_phdr, 0, 0);
-}
-
-static grub_err_t
-grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-               int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  grub_elf_t elf = 0;
-  int i;
-  int size;
-  char *dest;
-
-  grub_dl_ref (my_mod);
-
-  if (argc == 0)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
-      goto out;
-    }
-
-  file = grub_gzfile_open (argv[0], 1);
-  if (!file)
-    goto out;
-
-  elf = grub_elf_file (file);
-  if (! elf)
-    goto out;
-
-  if (elf->ehdr.ehdr32.e_type != ET_EXEC)
-    {
-      grub_error (GRUB_ERR_UNKNOWN_OS,
-                 "this ELF file is not of the right type");
-      goto out;
-    }
-
-  /* Release the previously used memory.  */
-  grub_loader_unset ();
-
-  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]);
-  for (i = 0; i < argc; i++)
-    size += grub_strlen (argv[i]) + 1;
-
-  linux_args = grub_malloc (size);
-  if (! linux_args)
-    goto out;
-
-  /* Specify the boot file.  */
-  dest = grub_stpcpy (linux_args, "BOOT_IMAGE=");
-  dest = grub_stpcpy (dest, argv[0]);
-
-  for (i = 1; i < argc; i++)
-    {
-      *dest++ = ' ';
-      dest = grub_stpcpy (dest, argv[i]);
-    }
-
-out:
-  if (elf)
-    grub_elf_close (elf);
-  else if (file)
-    grub_file_close (file);
-
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_linux_release_mem ();
-      grub_dl_unref (my_mod);
-      loaded = 0;
-    }
-  else
-    {
-      grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
-      initrd_addr = 0;
-      loaded = 1;
-    }
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
-                int argc, char *argv[])
-{
-  grub_file_t file = 0;
-  grub_ssize_t size;
-  grub_addr_t paddr;
-  grub_addr_t addr;
-  int ret;
-
-  if (argc == 0)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified");
-      goto fail;
-    }
-
-  if (!loaded)
-    {
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first");
-      goto fail;
-    }
-
-  file = grub_file_open (argv[0]);
-  if (! file)
-    goto fail;
-
-  addr = 0x60000000;
-  size = grub_file_size (file);
-
-  paddr = alloc_phys (size);
-  if (paddr == (grub_addr_t) -1)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                 "couldn't allocate physical memory");
-      goto fail;
-    }
-  ret = grub_ieee1275_map (paddr, addr, size, IEEE1275_MAP_DEFAULT);
-  if (ret)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                 "couldn't map physical memory");
-      goto fail;
-    }
-
-  grub_dprintf ("loader", "Loading initrd at vaddr 0x%lx, paddr 0x%lx, size 0x%lx\n",
-               addr, paddr, size);
-
-  if (grub_file_read (file, (void *) addr, size) != size)
-    {
-      grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
-      goto fail;
-    }
-
-  initrd_addr = addr;
-  initrd_paddr = paddr;
-  initrd_size = size;
-
- fail:
-  if (file)
-    grub_file_close (file);
-
-  return grub_errno;
-}
-
-static void
-determine_phys_base (void)
-{
-  auto int NESTED_FUNC_ATTR get_physbase (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type);
-  int NESTED_FUNC_ATTR get_physbase (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type)
-  {
-    if (type != 1)
-      return 0;
-    if (addr < phys_base)
-      phys_base = addr;
-    return 0;
-  }
-
-  phys_base = ~(grub_uint64_t) 0;
-  grub_machine_mmap_iterate (get_physbase);
-}
-
-static void
-fetch_translations (void)
-{
-  grub_ieee1275_phandle_t node;
-  grub_ssize_t actual;
-  int i;
-
-  if (grub_ieee1275_finddevice ("/virtual-memory", &node))
-    {
-      grub_printf ("Cannot find /virtual-memory node.\n");
-      return;
-    }
-
-  if (grub_ieee1275_get_property_length (node, "translations", &actual))
-    {
-      grub_printf ("Cannot find /virtual-memory/translations size.\n");
-      return;
-    }
-
-  of_trans = grub_malloc (actual);
-  if (!of_trans)
-    {
-      grub_printf ("Cannot allocate translations buffer.\n");
-      return;
-    }
-
-  if (grub_ieee1275_get_property (node, "translations", of_trans, actual, &actual))
-    {
-      grub_printf ("Cannot fetch /virtual-memory/translations property.\n");
-      return;
-    }
-
-  of_num_trans = actual / sizeof(struct grub_ieee1275_translation);
-
-  for (i = 0; i < of_num_trans; i++)
-    {
-      struct grub_ieee1275_translation *p = &of_trans[i];
-
-      if (p->vaddr == 0x2000)
-       {
-         grub_addr_t phys, tte = p->data;
-
-         phys = tte & ~(0xff00000000001fffULL);
-
-         grub_phys_start = phys;
-         grub_phys_end = grub_phys_start + p->size;
-         grub_dprintf ("loader", "Grub lives at phys_start[%lx] phys_end[%lx]\n",
-                       (unsigned long) grub_phys_start,
-                       (unsigned long) grub_phys_end);
-         break;
-       }
-    }
-}
-
-\f
-static grub_command_t cmd_linux, cmd_initrd;
-
-GRUB_MOD_INIT(linux)
-{
-  determine_phys_base ();
-  fetch_translations ();
-
-  cmd_linux = grub_register_command ("linux", grub_cmd_linux,
-                                    0, N_("Load Linux."));
-  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
-                                     0, N_("Load initrd."));
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(linux)
-{
-  grub_unregister_command (cmd_linux);
-  grub_unregister_command (cmd_initrd);
-}
diff --git a/loader/xnu.c b/loader/xnu.c
deleted file mode 100644 (file)
index 8f1d0c6..0000000
+++ /dev/null
@@ -1,1471 +0,0 @@
-/* xnu.c - load xnu kernel. Thanks to Florian Idelberger for all the
-   time he spent testing this
- */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/file.h>
-#include <grub/xnu.h>
-#include <grub/cpu/xnu.h>
-#include <grub/mm.h>
-#include <grub/dl.h>
-#include <grub/loader.h>
-#include <grub/machoload.h>
-#include <grub/macho.h>
-#include <grub/cpu/macho.h>
-#include <grub/gzio.h>
-#include <grub/command.h>
-#include <grub/misc.h>
-#include <grub/extcmd.h>
-#include <grub/env.h>
-#include <grub/i18n.h>
-
-struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0;
-static int driverspackagenum = 0;
-static int driversnum = 0;
-int grub_xnu_is_64bit = 0;
-
-void *grub_xnu_heap_start = 0;
-grub_size_t grub_xnu_heap_size = 0;
-
-/* Allocate heap by 32MB-blocks. */
-#define GRUB_XNU_HEAP_ALLOC_BLOCK 0x2000000
-
-static grub_err_t
-grub_xnu_register_memory (char *prefix, int *suffix,
-                         void *addr, grub_size_t size);
-void *
-grub_xnu_heap_malloc (int size)
-{
-  void *val;
-  int oldblknum, newblknum;
-
-  /* The page after the heap is used for stack. Ensure it's usable. */
-  if (grub_xnu_heap_size)
-    oldblknum = (grub_xnu_heap_size + GRUB_XNU_PAGESIZE
-                + GRUB_XNU_HEAP_ALLOC_BLOCK - 1) / GRUB_XNU_HEAP_ALLOC_BLOCK;
-  else
-    oldblknum = 0;
-  newblknum = (grub_xnu_heap_size + size + GRUB_XNU_PAGESIZE
-              + GRUB_XNU_HEAP_ALLOC_BLOCK - 1) / GRUB_XNU_HEAP_ALLOC_BLOCK;
-  if (oldblknum != newblknum)
-    {
-      /* FIXME: instruct realloc to allocate at 1MB if possible once
-        advanced mm is ready. */
-      grub_xnu_heap_start
-       = XNU_RELOCATOR (realloc) (grub_xnu_heap_start,
-                                  newblknum
-                                  * GRUB_XNU_HEAP_ALLOC_BLOCK);
-      if (!grub_xnu_heap_start)
-       return NULL;
-    }
-
-  val = (grub_uint8_t *) grub_xnu_heap_start + grub_xnu_heap_size;
-  grub_xnu_heap_size += size;
-  grub_dprintf ("xnu", "val=%p\n", val);
-  return val;
-}
-
-/* Make sure next block of the heap will be aligned.
-   Please notice: aligned are pointers AFTER relocation
-   and not the current ones. */
-grub_err_t
-grub_xnu_align_heap (int align)
-{
-  int align_overhead = align - grub_xnu_heap_size % align;
-  if (align_overhead == align)
-    return GRUB_ERR_NONE;
-  if (! grub_xnu_heap_malloc (align_overhead))
-    return grub_errno;
-  return GRUB_ERR_NONE;
-}
-
-/* Free subtree pointed by CUR. */
-void
-grub_xnu_free_devtree (struct grub_xnu_devtree_key *cur)
-{
-  struct grub_xnu_devtree_key *d;
-  while (cur)
-    {
-      grub_free (cur->name);
-      if (cur->datasize == -1)
-       grub_xnu_free_devtree (cur->first_child);
-      else if (cur->data)
-       grub_free (cur->data);
-      d = cur->next;
-      grub_free (cur);
-      cur = d;
-    }
-}
-
-/* Compute the size of device tree in xnu format. */
-static grub_size_t
-grub_xnu_writetree_get_size (struct grub_xnu_devtree_key *start, char *name)
-{
-  grub_size_t ret;
-  struct grub_xnu_devtree_key *cur;
-
-  /* Key header. */
-  ret = 2 * sizeof (grub_uint32_t);
-
-  /* "name" value. */
-  ret += 32 + sizeof (grub_uint32_t)
-    + grub_strlen (name) + 4
-    - (grub_strlen (name) % 4);
-
-  for (cur = start; cur; cur = cur->next)
-    if (cur->datasize != -1)
-      {
-       int align_overhead;
-
-       align_overhead = 4 - (cur->datasize % 4);
-       if (align_overhead == 4)
-         align_overhead = 0;
-       ret += 32 + sizeof (grub_uint32_t) + cur->datasize + align_overhead;
-      }
-    else
-      ret += grub_xnu_writetree_get_size (cur->first_child, cur->name);
-  return ret;
-}
-
-/* Write devtree in XNU format at curptr assuming the head is named NAME.*/
-static void *
-grub_xnu_writetree_toheap_real (void *curptr,
-                               struct grub_xnu_devtree_key *start, char *name)
-{
-  struct grub_xnu_devtree_key *cur;
-  int nkeys = 0, nvals = 0;
-  for (cur = start; cur; cur = cur->next)
-    {
-      if (cur->datasize == -1)
-       nkeys++;
-      else
-       nvals++;
-    }
-  /* For the name. */
-  nvals++;
-
-  *((grub_uint32_t *) curptr) = nvals;
-  curptr = ((grub_uint32_t *) curptr) + 1;
-  *((grub_uint32_t *) curptr) = nkeys;
-  curptr = ((grub_uint32_t *) curptr) + 1;
-
-  /* First comes "name" value. */
-  grub_memset (curptr, 0, 32);
-  grub_memcpy (curptr, "name", 4);
-  curptr = ((grub_uint8_t *) curptr) + 32;
-  *((grub_uint32_t *)curptr) = grub_strlen (name) + 1;
-  curptr = ((grub_uint32_t *) curptr) + 1;
-  grub_memcpy (curptr, name, grub_strlen (name));
-  curptr = ((grub_uint8_t *) curptr) + grub_strlen (name);
-  grub_memset (curptr, 0, 4 - (grub_strlen (name) % 4));
-  curptr = ((grub_uint8_t *) curptr) + (4 - (grub_strlen (name) % 4));
-
-  /* Then the other values. */
-  for (cur = start; cur; cur = cur->next)
-    if (cur->datasize != -1)
-      {
-       int align_overhead;
-
-       align_overhead = 4 - (cur->datasize % 4);
-       if (align_overhead == 4)
-         align_overhead = 0;
-       grub_memset (curptr, 0, 32);
-       grub_strncpy (curptr, cur->name, 31);
-       curptr = ((grub_uint8_t *) curptr) + 32;
-       *((grub_uint32_t *) curptr) = cur->datasize;
-       curptr = ((grub_uint32_t *) curptr) + 1;
-       grub_memcpy (curptr, cur->data, cur->datasize);
-       curptr = ((grub_uint8_t *) curptr) + cur->datasize;
-       grub_memset (curptr, 0, align_overhead);
-       curptr = ((grub_uint8_t *) curptr) + align_overhead;
-      }
-
-  /* And then the keys. Recursively use this function. */
-  for (cur = start; cur; cur = cur->next)
-    if (cur->datasize == -1)
-      if (!(curptr = grub_xnu_writetree_toheap_real (curptr,
-                                                    cur->first_child,
-                                                    cur->name)))
-       return 0;
-  return curptr;
-}
-
-grub_err_t
-grub_xnu_writetree_toheap (void **start, grub_size_t *size)
-{
-  struct grub_xnu_devtree_key *chosen;
-  struct grub_xnu_devtree_key *memorymap;
-  struct grub_xnu_devtree_key *driverkey;
-  struct grub_xnu_extdesc *extdesc;
-  grub_err_t err;
-
-  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
-  if (err)
-    return err;
-
-  /* Device tree itself is in the memory map of device tree. */
-  /* Create a dummy value in memory-map. */
-  chosen = grub_xnu_create_key (&grub_xnu_devtree_root, "chosen");
-  if (! chosen)
-    return grub_errno;
-  memorymap = grub_xnu_create_key (&(chosen->first_child), "memory-map");
-  if (! memorymap)
-    return grub_errno;
-
-  driverkey = (struct grub_xnu_devtree_key *) grub_malloc (sizeof (*driverkey));
-  if (! driverkey)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't write device tree");
-  driverkey->name = grub_strdup ("DeviceTree");
-  if (! driverkey->name)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't write device tree");
-  driverkey->datasize = sizeof (*extdesc);
-  driverkey->next = memorymap->first_child;
-  memorymap->first_child = driverkey;
-  driverkey->data = extdesc
-    = (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc));
-  if (! driverkey->data)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't write device tree");
-
-  /* Allocate the space based on the size with dummy value. */
-  *size = grub_xnu_writetree_get_size (grub_xnu_devtree_root, "/");
-  *start = grub_xnu_heap_malloc (*size + GRUB_XNU_PAGESIZE
-                                - *size % GRUB_XNU_PAGESIZE);
-
-  /* Put real data in the dummy. */
-  extdesc->addr = (grub_uint8_t *) *start - (grub_uint8_t *) grub_xnu_heap_start
-    + grub_xnu_heap_will_be_at;
-  extdesc->size = (grub_uint32_t) *size;
-
-  /* Write the tree to heap. */
-  grub_xnu_writetree_toheap_real (*start, grub_xnu_devtree_root, "/");
-  return GRUB_ERR_NONE;
-}
-
-/* Find a key or value in parent key. */
-struct grub_xnu_devtree_key *
-grub_xnu_find_key (struct grub_xnu_devtree_key *parent, char *name)
-{
-  struct grub_xnu_devtree_key *cur;
-  for (cur = parent; cur; cur = cur->next)
-    if (grub_strcmp (cur->name, name) == 0)
-      return cur;
-  return 0;
-}
-
-struct grub_xnu_devtree_key *
-grub_xnu_create_key (struct grub_xnu_devtree_key **parent, char *name)
-{
-  struct grub_xnu_devtree_key *ret;
-  ret = grub_xnu_find_key (*parent, name);
-  if (ret)
-    return ret;
-  ret = (struct grub_xnu_devtree_key *) grub_zalloc (sizeof (*ret));
-  if (! ret)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create key %s", name);
-      return 0;
-    }
-  ret->name = grub_strdup (name);
-  if (! ret->name)
-    {
-      grub_free (ret);
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create key %s", name);
-      return 0;
-    }
-  ret->datasize = -1;
-  ret->next = *parent;
-  *parent = ret;
-  return ret;
-}
-
-struct grub_xnu_devtree_key *
-grub_xnu_create_value (struct grub_xnu_devtree_key **parent, char *name)
-{
-  struct grub_xnu_devtree_key *ret;
-  ret = grub_xnu_find_key (*parent, name);
-  if (ret)
-    {
-      if (ret->datasize == -1)
-       grub_xnu_free_devtree (ret->first_child);
-      else if (ret->datasize)
-       grub_free (ret->data);
-      ret->datasize = 0;
-      ret->data = 0;
-      return ret;
-    }
-  ret = (struct grub_xnu_devtree_key *) grub_zalloc (sizeof (*ret));
-  if (! ret)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create value %s", name);
-      return 0;
-    }
-  ret->name = grub_strdup (name);
-  if (! ret->name)
-    {
-      grub_free (ret);
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't create value %s", name);
-      return 0;
-    }
-  ret->next = *parent;
-  *parent = ret;
-  return ret;
-}
-
-static grub_err_t
-grub_xnu_unload (void)
-{
-  grub_cpu_xnu_unload ();
-
-  grub_xnu_free_devtree (grub_xnu_devtree_root);
-  grub_xnu_devtree_root = 0;
-
-  /* Free loaded image. */
-  driversnum = 0;
-  driverspackagenum = 0;
-  grub_free (grub_xnu_heap_start);
-  grub_xnu_heap_start = 0;
-  grub_xnu_heap_size = 0;
-  grub_xnu_unlock ();
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
-                    int argc, char *args[])
-{
-  grub_err_t err;
-  grub_macho_t macho;
-  grub_uint32_t startcode, endcode;
-  int i;
-  char *ptr, *loadaddr;
-
-  if (argc < 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
-  grub_xnu_unload ();
-
-  macho = grub_macho_open (args[0]);
-  if (! macho)
-    return grub_errno;
-  if (! grub_macho_contains_macho32 (macho))
-    {
-      grub_macho_close (macho);
-      return grub_error (GRUB_ERR_BAD_OS,
-                        "kernel doesn't contain suitable 32-bit architecture");
-    }
-
-  err = grub_macho_size32 (macho, &startcode, &endcode, GRUB_MACHO_NOBSS);
-  if (err)
-    {
-      grub_macho_close (macho);
-      grub_xnu_unload ();
-      return err;
-    }
-
-  grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n",
-               (unsigned long) endcode, (unsigned long) startcode);
-
-  loadaddr = grub_xnu_heap_malloc (endcode - startcode);
-  grub_xnu_heap_will_be_at = startcode;
-
-  if (! loadaddr)
-    {
-      grub_macho_close (macho);
-      grub_xnu_unload ();
-      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                        "not enough memory to load kernel");
-    }
-
-  /* Load kernel. */
-  err = grub_macho_load32 (macho, loadaddr - startcode, GRUB_MACHO_NOBSS);
-  if (err)
-    {
-      grub_macho_close (macho);
-      grub_xnu_unload ();
-      return err;
-    }
-
-  grub_xnu_entry_point = grub_macho_get_entry_point32 (macho);
-  if (! grub_xnu_entry_point)
-    {
-      grub_macho_close (macho);
-      grub_xnu_unload ();
-      return grub_error (GRUB_ERR_BAD_OS, "couldn't find entry point");
-    }
-
-  grub_macho_close (macho);
-
-  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
-  if (err)
-    {
-      grub_xnu_unload ();
-      return err;
-    }
-
-  /* Copy parameters to kernel command line. */
-  ptr = grub_xnu_cmdline;
-  for (i = 1; i < argc; i++)
-    {
-      if (ptr + grub_strlen (args[i]) + 1
-         >= grub_xnu_cmdline + sizeof (grub_xnu_cmdline))
-       break;
-      grub_memcpy (ptr, args[i], grub_strlen (args[i]));
-      ptr += grub_strlen (args[i]);
-      *ptr = ' ';
-      ptr++;
-    }
-
-  /* Replace last space by '\0'. */
-  if (ptr != grub_xnu_cmdline)
-    *(ptr - 1) = 0;
-
-  grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0);
-
-  grub_xnu_lock ();
-  grub_xnu_is_64bit = 0;
-
-  return 0;
-}
-
-static grub_err_t
-grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
-                      int argc, char *args[])
-{
-  grub_err_t err;
-  grub_macho_t macho;
-  grub_uint64_t startcode, endcode;
-  int i;
-  char *ptr, *loadaddr;
-
-  if (argc < 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
-  grub_xnu_unload ();
-
-  macho = grub_macho_open (args[0]);
-  if (! macho)
-    return grub_errno;
-  if (! grub_macho_contains_macho64 (macho))
-    {
-      grub_macho_close (macho);
-      return grub_error (GRUB_ERR_BAD_OS,
-                        "kernel doesn't contain suitable 64-bit architecture");
-    }
-
-  err = grub_macho_size64 (macho, &startcode, &endcode, GRUB_MACHO_NOBSS);
-  if (err)
-    {
-      grub_macho_close (macho);
-      grub_xnu_unload ();
-      return err;
-    }
-
-  startcode &= 0x0fffffff;
-  endcode &= 0x0fffffff;
-
-  grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n",
-               (unsigned long) endcode, (unsigned long) startcode);
-
-  loadaddr = grub_xnu_heap_malloc (endcode - startcode);
-  grub_xnu_heap_will_be_at = startcode;
-
-  if (! loadaddr)
-    {
-      grub_macho_close (macho);
-      grub_xnu_unload ();
-      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                        "not enough memory to load kernel");
-    }
-
-  /* Load kernel. */
-  err = grub_macho_load64 (macho, loadaddr - startcode, GRUB_MACHO_NOBSS);
-  if (err)
-    {
-      grub_macho_close (macho);
-      grub_xnu_unload ();
-      return err;
-    }
-
-  grub_xnu_entry_point = grub_macho_get_entry_point64 (macho) & 0x0fffffff;
-  if (! grub_xnu_entry_point)
-    {
-      grub_macho_close (macho);
-      grub_xnu_unload ();
-      return grub_error (GRUB_ERR_BAD_OS, "couldn't find entry point");
-    }
-
-  grub_macho_close (macho);
-
-  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
-  if (err)
-    {
-      grub_xnu_unload ();
-      return err;
-    }
-
-  /* Copy parameters to kernel command line. */
-  ptr = grub_xnu_cmdline;
-  for (i = 1; i < argc; i++)
-    {
-      if (ptr + grub_strlen (args[i]) + 1
-         >= grub_xnu_cmdline + sizeof (grub_xnu_cmdline))
-       break;
-      grub_memcpy (ptr, args[i], grub_strlen (args[i]));
-      ptr += grub_strlen (args[i]);
-      *ptr = ' ';
-      ptr++;
-    }
-
-  /* Replace last space by '\0'. */
-  if (ptr != grub_xnu_cmdline)
-    *(ptr - 1) = 0;
-
-  grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0);
-
-  grub_xnu_lock ();
-  grub_xnu_is_64bit = 1;
-
-  return 0;
-}
-
-/* Register a memory in a memory map under name PREFIXSUFFIX
-   and increment SUFFIX. */
-static grub_err_t
-grub_xnu_register_memory (char *prefix, int *suffix,
-                         void *addr, grub_size_t size)
-{
-  struct grub_xnu_devtree_key *chosen;
-  struct grub_xnu_devtree_key *memorymap;
-  struct grub_xnu_devtree_key *driverkey;
-  struct grub_xnu_extdesc *extdesc;
-
-  if (! grub_xnu_heap_size)
-    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
-
-  chosen = grub_xnu_create_key (&grub_xnu_devtree_root, "chosen");
-  if (! chosen)
-    return grub_errno;
-  memorymap = grub_xnu_create_key (&(chosen->first_child), "memory-map");
-  if (! memorymap)
-    return grub_errno;
-
-  driverkey = (struct grub_xnu_devtree_key *) grub_malloc (sizeof (*driverkey));
-  if (! driverkey)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register memory");
-  if (suffix)
-    {
-      driverkey->name = grub_xasprintf ("%s%d", prefix, (*suffix)++);
-      if (!driverkey->name)
-       return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register memory");
-    }
-  else
-    driverkey->name = grub_strdup (prefix);
-  if (! driverkey->name)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register extension");
-  driverkey->datasize = sizeof (*extdesc);
-  driverkey->next = memorymap->first_child;
-  memorymap->first_child = driverkey;
-  driverkey->data = extdesc
-    = (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc));
-  if (! driverkey->data)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register extension");
-  extdesc->addr = grub_xnu_heap_will_be_at +
-    ((grub_uint8_t *) addr - (grub_uint8_t *) grub_xnu_heap_start);
-  extdesc->size = (grub_uint32_t) size;
-  return GRUB_ERR_NONE;
-}
-
-static inline char *
-get_name_ptr (char *name)
-{
-  char *p = name, *p2;
-  /* Skip Info.plist.  */
-  p2 = grub_strrchr (p, '/');
-  if (!p2)
-    return name;
-  if (p2 == name)
-    return name + 1;
-  p = p2 - 1;
-
-  p2 = grub_strrchr (p, '/');
-  if (!p2)
-    return name;
-  if (p2 == name)
-    return name + 1;
-  if (grub_memcmp (p2, "/Contents/", sizeof ("/Contents/") - 1) != 0)
-    return p2 + 1;
-
-  p = p2 - 1;
-
-  p2 = grub_strrchr (p, '/');
-  if (!p2)
-    return name;
-  return p2 + 1;
-}
-
-/* Load .kext. */
-static grub_err_t
-grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
-{
-  grub_macho_t macho;
-  grub_err_t err;
-  grub_file_t infoplist;
-  struct grub_xnu_extheader *exthead;
-  int neededspace = sizeof (*exthead);
-  grub_uint8_t *buf;
-  grub_size_t infoplistsize = 0, machosize = 0;
-  char *name, *nameend;
-  int namelen;
-
-  name = get_name_ptr (infoplistname);
-  nameend = grub_strchr (name, '/');
-
-  if (nameend)
-    namelen = nameend - name;
-  else
-    namelen = grub_strlen (name);
-
-  neededspace += namelen + 1;
-
-  if (! grub_xnu_heap_size)
-    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
-
-  /* Compute the needed space. */
-  if (binaryfile)
-    {
-      macho = grub_macho_file (binaryfile);
-      if (! macho || ! grub_macho_contains_macho32 (macho))
-       {
-         if (macho)
-           grub_macho_close (macho);
-         return grub_error (GRUB_ERR_BAD_OS,
-                            "extension doesn't contain suitable architecture");
-       }
-      if (grub_xnu_is_64bit)
-       machosize = grub_macho_filesize64 (macho);
-      else
-       machosize = grub_macho_filesize32 (macho);
-      neededspace += machosize;
-    }
-  else
-    macho = 0;
-
-  if (infoplistname)
-    infoplist = grub_gzfile_open (infoplistname, 1);
-  else
-    infoplist = 0;
-  grub_errno = GRUB_ERR_NONE;
-  if (infoplist)
-    {
-      infoplistsize = grub_file_size (infoplist);
-      neededspace += infoplistsize + 1;
-    }
-  else
-    infoplistsize = 0;
-
-  /* Allocate the space. */
-  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
-  if (err)
-    return err;
-  buf = grub_xnu_heap_malloc (neededspace);
-
-  exthead = (struct grub_xnu_extheader *) buf;
-  grub_memset (exthead, 0, sizeof (*exthead));
-  buf += sizeof (*exthead);
-
-  /* Load the binary. */
-  if (macho)
-    {
-      exthead->binaryaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start)
-       + grub_xnu_heap_will_be_at;
-      exthead->binarysize = machosize;
-      if (grub_xnu_is_64bit)
-       err = grub_macho_readfile64 (macho, buf);
-      else
-       err = grub_macho_readfile32 (macho, buf);
-      if (err)
-       {
-         grub_macho_close (macho);
-         return err;
-       }
-      grub_macho_close (macho);
-      buf += machosize;
-    }
-  grub_errno = GRUB_ERR_NONE;
-
-  /* Load the plist. */
-  if (infoplist)
-    {
-      exthead->infoplistaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start)
-       + grub_xnu_heap_will_be_at;
-      exthead->infoplistsize = infoplistsize + 1;
-      if (grub_file_read (infoplist, buf, infoplistsize)
-         != (grub_ssize_t) (infoplistsize))
-       {
-         grub_file_close (infoplist);
-         grub_error_push ();
-         return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s: ",
-                            infoplistname);
-       }
-      grub_file_close (infoplist);
-      buf[infoplistsize] = 0;
-      buf += infoplistsize + 1;
-    }
-  grub_errno = GRUB_ERR_NONE;
-
-  exthead->nameaddr = (buf - (grub_uint8_t *) grub_xnu_heap_start)
-    + grub_xnu_heap_will_be_at;
-  exthead->namesize = namelen + 1;
-  grub_memcpy (buf, name, namelen);
-  buf[namelen] = 0;
-  buf += namelen + 1;
-
-  /* Announce to kernel */
-  return grub_xnu_register_memory ("Driver-", &driversnum, exthead,
-                                  neededspace);
-}
-
-/* Load mkext. */
-static grub_err_t
-grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)),
-                   int argc, char *args[])
-{
-  grub_file_t file;
-  void *loadto;
-  grub_err_t err;
-  grub_off_t readoff = 0;
-  grub_ssize_t readlen = -1;
-  struct grub_macho_fat_header head;
-  struct grub_macho_fat_arch *archs;
-  int narchs, i;
-
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
-  if (! grub_xnu_heap_size)
-    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
-
-  file = grub_gzfile_open (args[0], 1);
-  if (! file)
-    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
-                      "couldn't load driver package");
-
-  /* Sometimes caches are fat binary. Errgh. */
-  if (grub_file_read (file, &head, sizeof (head))
-      != (grub_ssize_t) (sizeof (head)))
-    {
-      /* I don't know the internal structure of package but
-        can hardly imagine a valid package shorter than 20 bytes. */
-      grub_file_close (file);
-      grub_error_push ();
-      return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[0]);
-    }
-
-  /* Find the corresponding architecture. */
-  if (grub_be_to_cpu32 (head.magic) == GRUB_MACHO_FAT_MAGIC)
-    {
-      narchs = grub_be_to_cpu32 (head.nfat_arch);
-      archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs);
-      if (! archs)
-       {
-         grub_file_close (file);
-         grub_error_push ();
-         return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                            "couldn't read file %s", args[0]);
-
-       }
-      if (grub_file_read (file, archs,
-                         sizeof (struct grub_macho_fat_arch) * narchs)
-         != (grub_ssize_t) sizeof(struct grub_macho_fat_arch) * narchs)
-       {
-         grub_free (archs);
-         grub_error_push ();
-         return grub_error (GRUB_ERR_READ_ERROR, "cannot read fat header");
-       }
-      for (i = 0; i < narchs; i++)
-       {
-         if (!grub_xnu_is_64bit && GRUB_MACHO_CPUTYPE_IS_HOST32
-             (grub_be_to_cpu32 (archs[i].cputype)))
-           {
-             readoff = grub_be_to_cpu32 (archs[i].offset);
-             readlen = grub_be_to_cpu32 (archs[i].size);
-           }
-         if (grub_xnu_is_64bit && GRUB_MACHO_CPUTYPE_IS_HOST64
-             (grub_be_to_cpu32 (archs[i].cputype)))
-           {
-             readoff = grub_be_to_cpu32 (archs[i].offset);
-             readlen = grub_be_to_cpu32 (archs[i].size);
-           }
-       }
-      grub_free (archs);
-    }
-  else
-    {
-      /* It's a flat file. Some sane people still exist. */
-      readoff = 0;
-      readlen = grub_file_size (file);
-    }
-
-  if (readlen == -1)
-    {
-      grub_file_close (file);
-      return grub_error (GRUB_ERR_BAD_OS, "no suitable architecture is found");
-    }
-
-  /* Allocate space. */
-  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
-  if (err)
-    {
-      grub_file_close (file);
-      return err;
-    }
-
-  loadto = grub_xnu_heap_malloc (readlen);
-  if (! loadto)
-    {
-      grub_file_close (file);
-      return grub_errno;
-    }
-
-  /* Read the file. */
-  grub_file_seek (file, readoff);
-  if (grub_file_read (file, loadto, readlen) != (grub_ssize_t) (readlen))
-    {
-      grub_file_close (file);
-      grub_error_push ();
-      return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[0]);
-    }
-  grub_file_close (file);
-
-  /* Pass it to kernel. */
-  return grub_xnu_register_memory ("DriversPackage-", &driverspackagenum,
-                                  loadto, readlen);
-}
-
-static grub_err_t
-grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)),
-                     int argc, char *args[])
-{
-  grub_file_t file;
-  void *loadto;
-  grub_err_t err;
-  grub_size_t size;
-
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
-  if (! grub_xnu_heap_size)
-    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
-
-  file = grub_gzfile_open (args[0], 1);
-  if (! file)
-    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
-                      "couldn't load ramdisk");
-
-  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
-  if (err)
-    return err;
-
-  size = grub_file_size (file);
-
-  loadto = grub_xnu_heap_malloc (size);
-  if (! loadto)
-    return grub_errno;
-  if (grub_file_read (file, loadto, size)
-      != (grub_ssize_t) (size))
-    {
-      grub_file_close (file);
-      grub_error_push ();
-      return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[0]);
-    }
-  return grub_xnu_register_memory ("RAMDisk", 0, loadto, size);
-}
-
-/* Returns true if the kext should be loaded according to plist
-   and osbundlereq. Also fill BINNAME. */
-static int
-grub_xnu_check_os_bundle_required (char *plistname, char *osbundlereq,
-                                  char **binname)
-{
-  grub_file_t file;
-  char *buf = 0, *tagstart = 0, *ptr1 = 0, *keyptr = 0;
-  char *stringptr = 0, *ptr2 = 0;
-  grub_size_t size;
-  int depth = 0;
-  int ret;
-  int osbundlekeyfound = 0, binnamekeyfound = 0;
-  if (binname)
-    *binname = 0;
-
-  file = grub_gzfile_open (plistname, 1);
-  if (! file)
-    {
-      grub_file_close (file);
-      grub_error_push ();
-      grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", plistname);
-      return 0;
-    }
-
-  size = grub_file_size (file);
-  buf = grub_malloc (size);
-  if (! buf)
-    {
-      grub_file_close (file);
-      grub_error_push ();
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't read file %s", plistname);
-      return 0;
-    }
-  if (grub_file_read (file, buf, size) != (grub_ssize_t) (size))
-    {
-      grub_file_close (file);
-      grub_error_push ();
-      grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", plistname);
-      return 0;
-    }
-  grub_file_close (file);
-
-  /* Set the return value for the case when no OSBundleRequired tag is found. */
-  if (osbundlereq)
-    ret = grub_strword (osbundlereq, "all") || grub_strword (osbundlereq, "-");
-  else
-    ret = 1;
-
-  /* Parse plist. It's quite dirty and inextensible but does its job. */
-  for (ptr1 = buf; ptr1 < buf + size; ptr1++)
-    switch (*ptr1)
-      {
-      case '<':
-       tagstart = ptr1;
-       *ptr1 = 0;
-       if (keyptr && depth == 4
-           && grub_strcmp (keyptr, "OSBundleRequired") == 0)
-         osbundlekeyfound = 1;
-       if (keyptr && depth == 4 &&
-           grub_strcmp (keyptr, "CFBundleExecutable") == 0)
-         binnamekeyfound = 1;
-       if (stringptr && osbundlekeyfound && osbundlereq && depth == 4)
-         {
-           for (ptr2 = stringptr; *ptr2; ptr2++)
-             *ptr2 = grub_tolower (*ptr2);
-           ret = grub_strword (osbundlereq, stringptr)
-             || grub_strword (osbundlereq, "all");
-         }
-       if (stringptr && binnamekeyfound && binname && depth == 4)
-         {
-           if (*binname)
-             grub_free (*binname);
-           *binname = grub_strdup (stringptr);
-         }
-
-       *ptr1 = '<';
-       keyptr = 0;
-       stringptr = 0;
-       break;
-      case '>':
-       if (! tagstart)
-         {
-           grub_free (buf);
-           grub_error (GRUB_ERR_BAD_OS, "can't parse %s", plistname);
-           return 0;
-         }
-       *ptr1 = 0;
-       if (tagstart[1] == '?' || ptr1[-1] == '/')
-         {
-           osbundlekeyfound = 0;
-           *ptr1 = '>';
-           break;
-         }
-       if (depth == 3 && grub_strcmp (tagstart + 1, "key") == 0)
-         keyptr = ptr1 + 1;
-       if (depth == 3 && grub_strcmp (tagstart + 1, "string") == 0)
-         stringptr = ptr1 + 1;
-       else if (grub_strcmp (tagstart + 1, "/key") != 0)
-         {
-           osbundlekeyfound = 0;
-           binnamekeyfound = 0;
-         }
-       *ptr1 = '>';
-
-       if (tagstart[1] == '/')
-         depth--;
-       else
-         depth++;
-       break;
-      }
-  grub_free (buf);
-
-  return ret;
-}
-
-/* Load all loadable kexts placed under DIRNAME and matching OSBUNDLEREQUIRED */
-grub_err_t
-grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired,
-                            int maxrecursion)
-{
-  grub_device_t dev;
-  char *device_name;
-  grub_fs_t fs;
-  const char *path;
-
-  auto int load_hook (const char *filename,
-                     const struct grub_dirhook_info *info);
-  int load_hook (const char *filename, const struct grub_dirhook_info *info)
-  {
-    char *newdirname;
-    if (! info->dir)
-      return 0;
-    if (filename[0] == '.')
-      return 0;
-
-    if (grub_strlen (filename) < 5 ||
-       grub_memcmp (filename + grub_strlen (filename) - 5, ".kext", 5) != 0)
-      return 0;
-
-    newdirname
-      = grub_malloc (grub_strlen (dirname) + grub_strlen (filename) + 2);
-
-    /* It's a .kext. Try to load it. */
-    if (newdirname)
-      {
-       grub_strcpy (newdirname, dirname);
-       newdirname[grub_strlen (newdirname) + 1] = 0;
-       newdirname[grub_strlen (newdirname)] = '/';
-       grub_strcpy (newdirname + grub_strlen (newdirname), filename);
-       grub_xnu_load_kext_from_dir (newdirname, osbundlerequired,
-                                    maxrecursion);
-       if (grub_errno == GRUB_ERR_BAD_OS)
-         grub_errno = GRUB_ERR_NONE;
-       grub_free (newdirname);
-      }
-    return 0;
-  }
-
-  if (! grub_xnu_heap_size)
-    return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
-
-  device_name = grub_file_get_device_name (dirname);
-  dev = grub_device_open (device_name);
-  if (dev)
-    {
-      fs = grub_fs_probe (dev);
-      path = grub_strchr (dirname, ')');
-      if (! path)
-       path = dirname;
-      else
-       path++;
-
-      if (fs)
-       (fs->dir) (dev, path, load_hook);
-      grub_device_close (dev);
-    }
-  grub_free (device_name);
-
-  return GRUB_ERR_NONE;
-}
-
-/* Load extension DIRNAME. (extensions are directories in xnu) */
-grub_err_t
-grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired,
-                            int maxrecursion)
-{
-  grub_device_t dev;
-  char *plistname = 0;
-  char *newdirname;
-  char *newpath;
-  char *device_name;
-  grub_fs_t fs;
-  const char *path;
-  char *binsuffix;
-  int usemacos = 0;
-  grub_file_t binfile;
-
-  auto int load_hook (const char *filename,
-                     const struct grub_dirhook_info *info);
-
-  int load_hook (const char *filename, const struct grub_dirhook_info *info)
-  {
-    if (grub_strlen (filename) > 15)
-      return 0;
-    grub_strcpy (newdirname + grub_strlen (dirname) + 1, filename);
-
-    /* If the kext contains directory "Contents" all real stuff is in
-       this directory. */
-    if (info->dir && grub_strcasecmp (filename, "Contents") == 0)
-      grub_xnu_load_kext_from_dir (newdirname, osbundlerequired,
-                                  maxrecursion - 1);
-
-    /* Directory "Plugins" contains nested kexts. */
-    if (info->dir && grub_strcasecmp (filename, "Plugins") == 0)
-      grub_xnu_scan_dir_for_kexts (newdirname, osbundlerequired,
-                                  maxrecursion - 1);
-
-    /* Directory "MacOS" contains executable, otherwise executable is
-       on the top. */
-    if (info->dir && grub_strcasecmp (filename, "MacOS") == 0)
-      usemacos = 1;
-
-    /* Info.plist is the file which governs our future actions. */
-    if (! info->dir && grub_strcasecmp (filename, "Info.plist") == 0
-       && ! plistname)
-      plistname = grub_strdup (newdirname);
-    return 0;
-  }
-
-  newdirname = grub_malloc (grub_strlen (dirname) + 20);
-  if (! newdirname)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't allocate buffer");
-  grub_strcpy (newdirname, dirname);
-  newdirname[grub_strlen (dirname)] = '/';
-  newdirname[grub_strlen (dirname) + 1] = 0;
-  device_name = grub_file_get_device_name (dirname);
-  dev = grub_device_open (device_name);
-  if (dev)
-    {
-      fs = grub_fs_probe (dev);
-      path = grub_strchr (dirname, ')');
-      if (! path)
-       path = dirname;
-      else
-       path++;
-
-      newpath = grub_strchr (newdirname, ')');
-      if (! newpath)
-       newpath = newdirname;
-      else
-       newpath++;
-
-      /* Look at the directory. */
-      if (fs)
-       (fs->dir) (dev, path, load_hook);
-
-      if (plistname && grub_xnu_check_os_bundle_required
-         (plistname, osbundlerequired, &binsuffix))
-       {
-         if (binsuffix)
-           {
-             /* Open the binary. */
-             char *binname = grub_malloc (grub_strlen (dirname)
-                                          + grub_strlen (binsuffix)
-                                          + sizeof ("/MacOS/"));
-             grub_strcpy (binname, dirname);
-             if (usemacos)
-               grub_strcpy (binname + grub_strlen (binname), "/MacOS/");
-             else
-               grub_strcpy (binname + grub_strlen (binname), "/");
-             grub_strcpy (binname + grub_strlen (binname), binsuffix);
-             grub_dprintf ("xnu", "%s:%s\n", plistname, binname);
-             binfile = grub_gzfile_open (binname, 1);
-             if (! binfile)
-               grub_errno = GRUB_ERR_NONE;
-
-             /* Load the extension. */
-             grub_xnu_load_driver (plistname, binfile);
-             grub_free (binname);
-             grub_free (binsuffix);
-           }
-         else
-           {
-             grub_dprintf ("xnu", "%s:0\n", plistname);
-             grub_xnu_load_driver (plistname, 0);
-           }
-       }
-      grub_free (plistname);
-      grub_device_close (dev);
-    }
-  grub_free (device_name);
-
-  return GRUB_ERR_NONE;
-}
-
-
-static int locked=0;
-static grub_dl_t my_mod;
-
-/* Load the kext. */
-static grub_err_t
-grub_cmd_xnu_kext (grub_command_t cmd __attribute__ ((unused)),
-                  int argc, char *args[])
-{
-  grub_file_t binfile = 0;
-  if (argc == 2)
-    {
-      /* User explicitly specified plist and binary. */
-      if (grub_strcmp (args[1], "-") != 0)
-       {
-         binfile = grub_gzfile_open (args[1], 1);
-         if (! binfile)
-           {
-             grub_error (GRUB_ERR_BAD_OS, "can't open file");
-             return GRUB_ERR_NONE;
-           }
-       }
-      return grub_xnu_load_driver (grub_strcmp (args[0], "-") ? args[0] : 0,
-                                  binfile);
-    }
-
-  /* load kext normally. */
-  if (argc == 1)
-    return grub_xnu_load_kext_from_dir (args[0], 0, 10);
-
-  return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-}
-
-/* Load a directory containing kexts. */
-static grub_err_t
-grub_cmd_xnu_kextdir (grub_command_t cmd __attribute__ ((unused)),
-                     int argc, char *args[])
-{
-  if (argc != 1 && argc != 2)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "directory name required");
-
-  if (argc == 1)
-    return grub_xnu_scan_dir_for_kexts (args[0],
-                                       "console,root,local-root,network-root",
-                                       10);
-  else
-    {
-      char *osbundlerequired = grub_strdup (args[1]), *ptr;
-      grub_err_t err;
-      if (! osbundlerequired)
-       return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                          "couldn't allocate string temporary space");
-      for (ptr = osbundlerequired; *ptr; ptr++)
-       *ptr = grub_tolower (*ptr);
-      err = grub_xnu_scan_dir_for_kexts (args[0], osbundlerequired, 10);
-      grub_free (osbundlerequired);
-      return err;
-    }
-}
-
-static inline int
-hextoval (char c)
-{
-  if (c >= '0' && c <= '9')
-    return c - '0';
-  if (c >= 'a' && c <= 'z')
-    return c - 'a' + 10;
-  if (c >= 'A' && c <= 'Z')
-    return c - 'A' + 10;
-  return 0;
-}
-
-static inline void
-unescape (char *name, char *curdot, char *nextdot, int *len)
-{
-  char *ptr, *dptr;
-  dptr = name;
-  for (ptr = curdot; ptr < nextdot;)
-    if (ptr + 2 < nextdot && *ptr == '%')
-      {
-       *dptr = (hextoval (ptr[1]) << 4) | (hextoval (ptr[2]));
-       ptr += 3;
-       dptr++;
-      }
-    else
-      {
-       *dptr = *ptr;
-       ptr++;
-       dptr++;
-      }
-  *len = dptr - name;
-}
-
-grub_err_t
-grub_xnu_fill_devicetree (void)
-{
-  auto int iterate_env (struct grub_env_var *var);
-  int iterate_env (struct grub_env_var *var)
-  {
-    char *nextdot = 0, *curdot;
-    struct grub_xnu_devtree_key **curkey = &grub_xnu_devtree_root;
-    struct grub_xnu_devtree_key *curvalue;
-    char *name = 0, *data;
-    int len;
-
-    if (grub_memcmp (var->name, "XNU.DeviceTree.",
-                    sizeof ("XNU.DeviceTree.") - 1) != 0)
-      return 0;
-
-    curdot = var->name + sizeof ("XNU.DeviceTree.") - 1;
-    nextdot = grub_strchr (curdot, '.');
-    if (nextdot)
-      nextdot++;
-    while (nextdot)
-      {
-       name = grub_realloc (name, nextdot - curdot + 1);
-
-       if (!name)
-         return 1;
-
-       unescape (name, curdot, nextdot, &len);
-       name[len - 1] = 0;
-
-       curkey = &(grub_xnu_create_key (curkey, name)->first_child);
-
-       curdot = nextdot;
-       nextdot = grub_strchr (nextdot, '.');
-       if (nextdot)
-         nextdot++;
-      }
-
-    nextdot = curdot + grub_strlen (curdot) + 1;
-
-    name = grub_realloc (name, nextdot - curdot + 1);
-   
-    if (!name)
-      return 1;
-   
-    unescape (name, curdot, nextdot, &len);
-    name[len] = 0;
-
-    curvalue = grub_xnu_create_value (curkey, name);
-    grub_free (name);
-   
-    data = grub_malloc (grub_strlen (var->value) + 1);
-    if (!data)
-      return 1;
-   
-    unescape (data, var->value, var->value + grub_strlen (var->value),
-             &len);
-    curvalue->datasize = len;
-    curvalue->data = data;
-
-    return 0;
-  }
-
-  grub_env_iterate (iterate_env);
-
-  return grub_errno;
-}
-
-struct grub_video_bitmap *grub_xnu_bitmap = 0;
-grub_xnu_bitmap_mode_t grub_xnu_bitmap_mode;
-
-/* Option array indices.  */
-#define XNU_SPLASH_CMD_ARGINDEX_MODE 0
-
-static const struct grub_arg_option xnu_splash_cmd_options[] =
-  {
-    {"mode", 'm', 0, "Background image mode.", "stretch|normal",
-     ARG_TYPE_STRING},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-static grub_err_t
-grub_cmd_xnu_splash (grub_extcmd_t cmd,
-                    int argc, char *args[])
-{
-  grub_err_t err;
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
-  if (cmd->state[XNU_SPLASH_CMD_ARGINDEX_MODE].set &&
-      grub_strcmp (cmd->state[XNU_SPLASH_CMD_ARGINDEX_MODE].arg,
-                  "stretch") == 0)
-    grub_xnu_bitmap_mode = GRUB_XNU_BITMAP_STRETCH;
-  else
-    grub_xnu_bitmap_mode = GRUB_XNU_BITMAP_CENTER;
-
-  err = grub_video_bitmap_load (&grub_xnu_bitmap, args[0]);
-  if (err)
-    grub_xnu_bitmap = 0;
-
-  return err;
-}
-
-
-#ifndef GRUB_MACHINE_EMU
-static grub_err_t
-grub_cmd_xnu_resume (grub_command_t cmd __attribute__ ((unused)),
-                    int argc, char *args[])
-{
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
-  return grub_xnu_resume (args[0]);
-}
-#endif
-
-void
-grub_xnu_lock ()
-{
-  if (!locked)
-    grub_dl_ref (my_mod);
-  locked = 1;
-}
-
-void
-grub_xnu_unlock ()
-{
-  if (locked)
-    grub_dl_unref (my_mod);
-  locked = 0;
-}
-
-static grub_command_t cmd_kernel64, cmd_kernel, cmd_mkext, cmd_kext;
-static grub_command_t cmd_kextdir, cmd_ramdisk, cmd_resume;
-static grub_extcmd_t cmd_splash;
-
-GRUB_MOD_INIT(xnu)
-{
-  cmd_kernel = grub_register_command ("xnu_kernel", grub_cmd_xnu_kernel, 0,
-                                     N_("Load XNU image."));
-  cmd_kernel64 = grub_register_command ("xnu_kernel64", grub_cmd_xnu_kernel64,
-                                       0, N_("Load 64-bit XNU image."));
-  cmd_mkext = grub_register_command ("xnu_mkext", grub_cmd_xnu_mkext, 0,
-                                    N_("Load XNU extension package."));
-  cmd_kext = grub_register_command ("xnu_kext", grub_cmd_xnu_kext, 0,
-                                   N_("Load XNU extension."));
-  cmd_kextdir = grub_register_command ("xnu_kextdir", grub_cmd_xnu_kextdir,
-                                      N_("DIRECTORY [OSBundleRequired]"),
-                                      N_("Load XNU extension directory."));
-  cmd_ramdisk = grub_register_command ("xnu_ramdisk", grub_cmd_xnu_ramdisk, 0,
-                                      "Load XNU ramdisk. "
-                                      "It will be seen as md0.");
-  cmd_splash = grub_register_extcmd ("xnu_splash",
-                                    grub_cmd_xnu_splash,
-                                    GRUB_COMMAND_FLAG_BOTH, 0,
-                                    N_("Load a splash image for XNU."),
-                                    xnu_splash_cmd_options);
-
-#ifndef GRUB_MACHINE_EMU
-  cmd_resume = grub_register_command ("xnu_resume", grub_cmd_xnu_resume,
-                                     0, N_("Load XNU hibernate image."));
-#endif
-
-  grub_cpu_xnu_init ();
-
-  my_mod = mod;
-}
-
-GRUB_MOD_FINI(xnu)
-{
-#ifndef GRUB_MACHINE_EMU
-  grub_unregister_command (cmd_resume);
-#endif
-  grub_unregister_command (cmd_mkext);
-  grub_unregister_command (cmd_kext);
-  grub_unregister_command (cmd_kextdir);
-  grub_unregister_command (cmd_ramdisk);
-  grub_unregister_command (cmd_kernel);
-  grub_unregister_extcmd (cmd_splash);
-  grub_unregister_command (cmd_kernel64);
-
-  grub_cpu_xnu_fini ();
-}
diff --git a/loader/xnu_resume.c b/loader/xnu_resume.c
deleted file mode 100644 (file)
index e6620e7..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/normal.h>
-#include <grub/dl.h>
-#include <grub/file.h>
-#include <grub/disk.h>
-#include <grub/misc.h>
-#include <grub/xnu.h>
-#include <grub/cpu/xnu.h>
-#include <grub/mm.h>
-#include <grub/loader.h>
-
-static void *grub_xnu_hibernate_image;
-
-static grub_err_t
-grub_xnu_resume_unload (void)
-{
-  /* Free loaded image */
-  if (grub_xnu_hibernate_image)
-    grub_free (grub_xnu_hibernate_image);
-  grub_xnu_hibernate_image = 0;
-  grub_xnu_unlock ();
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_xnu_resume (char *imagename)
-{
-  grub_file_t file;
-  grub_size_t total_header_size;
-  struct grub_xnu_hibernate_header hibhead;
-  grub_uint8_t *buf;
-
-  grub_uint32_t codedest;
-  grub_uint32_t codesize;
-
-  file = grub_file_open (imagename);
-  if (! file)
-    return 0;
-
-  /* Read the header. */
-  if (grub_file_read (file, &hibhead, sizeof (hibhead))
-      !=sizeof (hibhead))
-    {
-      grub_file_close (file);
-      return grub_error (GRUB_ERR_READ_ERROR,
-                        "cannot read the hibernate header");
-    }
-
-  /* Check the header. */
-  if (hibhead.magic != GRUB_XNU_HIBERNATE_MAGIC)
-    {
-      grub_file_close (file);
-      return grub_error (GRUB_ERR_BAD_OS,
-                        "hibernate header has incorrect magic number");
-    }
-  if (hibhead.encoffset)
-    {
-      grub_file_close (file);
-      return grub_error (GRUB_ERR_BAD_OS,
-                        "encrypted images aren't supported yet");
-    }
-
-  codedest = hibhead.launchcode_target_page;
-  codedest *= GRUB_XNU_PAGESIZE;
-  codesize = hibhead.launchcode_numpages;
-  codesize *= GRUB_XNU_PAGESIZE;
-
-  /* FIXME: check that codedest..codedest+codesize is available. */
-
-  /* Calculate total size before pages to copy. */
-  total_header_size = hibhead.extmapsize + sizeof (hibhead);
-
-  /* Unload image if any. */
-  if (grub_xnu_hibernate_image)
-    grub_free (grub_xnu_hibernate_image);
-
-  /* Try to allocate necessary space.
-     FIXME: mm isn't good enough yet to handle huge allocations.
-   */
-  grub_xnu_hibernate_image = buf = XNU_RELOCATOR (alloc) (hibhead.image_size
-                                                         + codesize
-                                                         + GRUB_XNU_PAGESIZE);
-  if (! buf)
-    {
-      grub_file_close (file);
-      return grub_errno;
-    }
-
-  /* Read code part. */
-  if (grub_file_seek (file, total_header_size) == (grub_off_t) -1
-      || grub_file_read (file, buf, codesize)
-      != (grub_ssize_t) codesize)
-    {
-      grub_file_close (file);
-      return grub_error (GRUB_ERR_READ_ERROR, "cannot read resume image");
-    }
-
-  /* Read image. */
-  if (grub_file_seek (file, 0) == (grub_off_t) -1
-      || grub_file_read (file, buf + codesize + GRUB_XNU_PAGESIZE,
-                        hibhead.image_size)
-      != (grub_ssize_t) hibhead.image_size)
-    {
-      grub_file_close (file);
-      return grub_error (GRUB_ERR_READ_ERROR, "cannot read resume image");
-    }
-  grub_file_close (file);
-
-  /* Setup variables needed by asm helper. */
-  grub_xnu_heap_will_be_at = codedest;
-  grub_xnu_heap_start = buf;
-  grub_xnu_heap_size = codesize + GRUB_XNU_PAGESIZE + hibhead.image_size;
-  grub_xnu_stack = (codedest + hibhead.stack);
-  grub_xnu_entry_point = (codedest + hibhead.entry_point);
-  grub_xnu_arg1 = codedest + codesize + GRUB_XNU_PAGESIZE;
-
-  grub_dprintf ("xnu", "entry point 0x%x\n", codedest + hibhead.entry_point);
-  grub_dprintf ("xnu", "image at 0x%x\n",
-               codedest + codesize + GRUB_XNU_PAGESIZE);
-
-  /* We're ready now. */
-  grub_loader_set (grub_xnu_boot_resume,
-                  grub_xnu_resume_unload, 0);
-
-  /* Prevent module from unloading. */
-  grub_xnu_lock ();
-  return GRUB_ERR_NONE;
-}
diff --git a/mmap/efi/mmap.c b/mmap/efi/mmap.c
deleted file mode 100644 (file)
index 316c997..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-/* Mmap management. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/machine/memory.h>
-#include <grub/memory.h>
-#include <grub/err.h>
-#include <grub/efi/api.h>
-#include <grub/efi/efi.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-
-#define NEXT_MEMORY_DESCRIPTOR(desc, size)      \
-  ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
-
-grub_err_t
-grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
-                                                        grub_uint64_t,
-                                                        grub_uint32_t))
-{
-  grub_efi_uintn_t mmap_size = 0;
-  grub_efi_memory_descriptor_t *map_buf = 0;
-  grub_efi_uintn_t map_key = 0;
-  grub_efi_uintn_t desc_size = 0;
-  grub_efi_uint32_t desc_version = 0;
-  grub_efi_memory_descriptor_t *desc;
-
-  if (grub_efi_get_memory_map (&mmap_size, map_buf,
-                              &map_key, &desc_size,
-                              &desc_version) < 0)
-    return grub_errno;
-
-  map_buf = grub_malloc (mmap_size);
-  if (! map_buf)
-    return grub_errno;
-
-  if (grub_efi_get_memory_map (&mmap_size, map_buf,
-                              &map_key, &desc_size,
-                              &desc_version) <= 0)
-    {
-      grub_free (map_buf);
-      return grub_errno;
-    }
-
-  for (desc = map_buf;
-       desc < NEXT_MEMORY_DESCRIPTOR (map_buf, mmap_size);
-       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
-    {
-      grub_dprintf ("mmap", "EFI memory region 0x%llx-0x%llx: %d\n",
-                   (unsigned long long) desc->physical_start,
-                   (unsigned long long) desc->physical_start
-                   + desc->num_pages * 4096, desc->type);
-      switch (desc->type)
-       {
-       case GRUB_EFI_RUNTIME_SERVICES_CODE:
-         hook (desc->physical_start, desc->num_pages * 4096,
-               GRUB_MACHINE_MEMORY_CODE);
-         break;
-
-       default:
-         grub_printf ("Unknown memory type %d, considering reserved\n",
-                      desc->type);
-
-       case GRUB_EFI_RESERVED_MEMORY_TYPE:
-       case GRUB_EFI_RUNTIME_SERVICES_DATA:
-       case GRUB_EFI_UNUSABLE_MEMORY:
-       case GRUB_EFI_MEMORY_MAPPED_IO:
-       case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
-       case GRUB_EFI_PAL_CODE:
-         hook (desc->physical_start, desc->num_pages * 4096,
-               GRUB_MACHINE_MEMORY_RESERVED);
-         break;
-
-       case GRUB_EFI_LOADER_CODE:
-       case GRUB_EFI_LOADER_DATA:
-       case GRUB_EFI_BOOT_SERVICES_CODE:
-       case GRUB_EFI_BOOT_SERVICES_DATA:
-       case GRUB_EFI_CONVENTIONAL_MEMORY:
-         hook (desc->physical_start, desc->num_pages * 4096,
-               GRUB_MACHINE_MEMORY_AVAILABLE);
-         break;
-
-       case GRUB_EFI_ACPI_RECLAIM_MEMORY:
-         hook (desc->physical_start, desc->num_pages * 4096,
-               GRUB_MACHINE_MEMORY_ACPI);
-         break;
-
-       case GRUB_EFI_ACPI_MEMORY_NVS:
-         hook (desc->physical_start, desc->num_pages * 4096,
-               GRUB_MACHINE_MEMORY_NVS);
-         break;
-       }
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-static inline grub_efi_memory_type_t
-make_efi_memtype (int type)
-{
-  switch (type)
-    {
-    case GRUB_MACHINE_MEMORY_CODE:
-      return GRUB_EFI_RUNTIME_SERVICES_CODE;
-
-      /* No way to remove a chunk of memory from EFI mmap.
-        So mark it as unusable. */
-    case GRUB_MACHINE_MEMORY_HOLE:
-
-    default:
-
-    case GRUB_MACHINE_MEMORY_RESERVED:
-      return GRUB_EFI_UNUSABLE_MEMORY;
-
-    case GRUB_MACHINE_MEMORY_AVAILABLE:
-      return GRUB_EFI_CONVENTIONAL_MEMORY;
-
-    case GRUB_MACHINE_MEMORY_ACPI:
-      return GRUB_EFI_ACPI_RECLAIM_MEMORY;
-
-    case GRUB_MACHINE_MEMORY_NVS:
-      return GRUB_EFI_ACPI_RECLAIM_MEMORY;
-
-    }
-
-}
-
-struct overlay
-{
-  struct overlay *next;
-  grub_efi_physical_address_t address;
-  grub_efi_uintn_t pages;
-  int handle;
-};
-
-static struct overlay *overlays = 0;
-static int curhandle = 1;
-
-int
-grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type)
-{
-  grub_uint64_t end = start + size;
-  grub_efi_physical_address_t address;
-  grub_efi_boot_services_t *b;
-  grub_efi_uintn_t pages;
-  grub_efi_status_t status;
-  struct overlay *curover;
-
-  curover = (struct overlay *) grub_malloc (sizeof (struct overlay));
-  if (! curover)
-    return 0;
-
-  b = grub_efi_system_table->boot_services;
-  address = start & (~0x3ffULL);
-  pages = (end - address  + 0x3ff) >> 12;
-  status = efi_call_2 (b->free_pages, address, pages);
-  if (status != GRUB_EFI_SUCCESS && status != GRUB_EFI_NOT_FOUND)
-    {
-      grub_free (curover);
-      return 0;
-    }
-  status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ADDRESS,
-                      make_efi_memtype (type), pages, &address);
-  if (status != GRUB_EFI_SUCCESS)
-    {
-      grub_free (curover);
-      return 0;
-    }
-  curover->next = overlays;
-  curover->handle = curhandle++;
-  curover->address = address;
-  curover->pages = pages;
-  overlays = curover;
-
-  return curover->handle;
-}
-
-grub_err_t
-grub_mmap_unregister (int handle)
-{
-  struct overlay *curover, *prevover;
-  grub_efi_boot_services_t *b;
-  grub_efi_status_t status;
-
-  b = grub_efi_system_table->boot_services;
-
-
-  for (curover = overlays, prevover = 0; curover;
-       prevover = curover, curover = curover->next)
-    {
-      if (curover->handle == handle)
-       {
-         status = efi_call_2 (b->free_pages, curover->address, curover->pages);
-         if (prevover != 0)
-           prevover->next = curover->next;
-         else
-           overlays = curover->next;
-         grub_free (curover);
-         return GRUB_ERR_NONE;
-       }
-    }
-  return grub_error (GRUB_ERR_BAD_ARGUMENT, "handle %d not found", handle);
-}
-
-/* Result is always page-aligned. */
-void *
-grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)),
-                              grub_uint64_t size,
-                              int *handle, int type,
-                              int flags __attribute__ ((unused)))
-{
-  grub_efi_physical_address_t address;
-  grub_efi_boot_services_t *b;
-  grub_efi_uintn_t pages;
-  grub_efi_status_t status;
-  struct overlay *curover;
-  grub_efi_allocate_type_t atype;
-
-  curover = (struct overlay *) grub_malloc (sizeof (struct overlay));
-  if (! curover)
-    return 0;
-
-  b = grub_efi_system_table->boot_services;
-
-  address = 0xffffffff;
-
-#if GRUB_TARGET_SIZEOF_VOID_P < 8
-  /* Limit the memory access to less than 4GB for 32-bit platforms.  */
-  atype = GRUB_EFI_ALLOCATE_MAX_ADDRESS;
-#else
-  atype = GRUB_EFI_ALLOCATE_ANY_PAGES;
-#endif
-
-  pages = (size + 0x3ff) >> 12;
-  status = efi_call_4 (b->allocate_pages, atype,
-                      make_efi_memtype (type), pages, &address);
-  if (status != GRUB_EFI_SUCCESS)
-    {
-      grub_free (curover);
-      return 0;
-    }
-
-  if (address == 0)
-    {
-      /* Uggh, the address 0 was allocated... This is too annoying,
-        so reallocate another one.  */
-      address = 0xffffffff;
-      status = efi_call_4 (b->allocate_pages, atype,
-                          make_efi_memtype (type), pages, &address);
-      grub_efi_free_pages (0, pages);
-      if (status != GRUB_EFI_SUCCESS)
-       return 0;
-    }
-
-  curover->next = overlays;
-  curover->handle = curhandle++;
-  curover->address = address;
-  curover->pages = pages;
-  overlays = curover;
-  *handle = curover->handle;
-
-  return UINT_TO_PTR (curover->address);
-}
-
-void
-grub_mmap_free_and_unregister (int handle)
-{
-  grub_mmap_unregister (handle);
-}
diff --git a/mmap/i386/mmap.c b/mmap/i386/mmap.c
deleted file mode 100644 (file)
index f6e1612..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/* Mmap management. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/machine/memory.h>
-#include <grub/memory.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-
-
-#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
-
-void *
-grub_mmap_malign_and_register (grub_uint64_t align, grub_uint64_t size,
-                              int *handle, int type, int flags)
-{
-  grub_uint64_t highestlow = 0;
-
-  auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t,
-                                      grub_uint32_t);
-  int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t rangesize,
-                                 grub_uint32_t memtype)
-  {
-    grub_uint64_t end = start + rangesize;
-    if (memtype != GRUB_MACHINE_MEMORY_AVAILABLE)
-      return 0;
-    if (end > 0x100000)
-      end = 0x100000;
-    if (end > start + size
-       && highestlow < ((end - size) - ((end - size) & (align - 1))))
-      highestlow = (end - size)  - ((end - size) & (align - 1));
-    return 0;
-  }
-
-  void *ret;
-  if (flags & GRUB_MMAP_MALLOC_LOW)
-    {
-      /* FIXME: use low-memory mm allocation once it's available. */
-      grub_mmap_iterate (find_hook);
-      ret = UINT_TO_PTR (highestlow);
-    }
-  else
-    ret = grub_memalign (align, size);
-
-  if (! ret)
-    {
-      *handle = 0;
-      return 0;
-    }
-
-  *handle = grub_mmap_register (PTR_TO_UINT64 (ret), size, type);
-  if (! *handle)
-    {
-      grub_free (ret);
-      return 0;
-    }
-
-  return ret;
-}
-
-void
-grub_mmap_free_and_unregister (int handle)
-{
-  struct grub_mmap_region *cur;
-  grub_uint64_t addr;
-
-  for (cur = grub_mmap_overlays; cur; cur = cur->next)
-    if (cur->handle == handle)
-      break;
-
-  if (! cur)
-    return;
-
-  addr = cur->start;
-
-  grub_mmap_unregister (handle);
-
-  if (addr >= 0x100000)
-    grub_free (UINT_TO_PTR (addr));
-}
-
-#endif
diff --git a/mmap/i386/pc/mmap.c b/mmap/i386/pc/mmap.c
deleted file mode 100644 (file)
index 7d5a43f..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/* Mmap management. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/machine/memory.h>
-#include <grub/memory.h>
-#include <grub/misc.h>
-#include <grub/term.h>
-#include <grub/loader.h>
-
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-
-static void *hooktarget = 0;
-
-extern grub_uint8_t grub_machine_mmaphook_start;
-extern grub_uint8_t grub_machine_mmaphook_end;
-extern grub_uint8_t grub_machine_mmaphook_int12;
-extern grub_uint8_t grub_machine_mmaphook_int15;
-
-static grub_uint16_t grub_machine_mmaphook_int12offset = 0;
-static grub_uint16_t grub_machine_mmaphook_int12segment = 0;
-extern grub_uint16_t grub_machine_mmaphook_int15offset;
-extern grub_uint16_t grub_machine_mmaphook_int15segment;
-
-extern grub_uint16_t grub_machine_mmaphook_mmap_num;
-extern grub_uint16_t grub_machine_mmaphook_kblow;
-extern grub_uint16_t grub_machine_mmaphook_kbin16mb;
-extern grub_uint16_t grub_machine_mmaphook_64kbin4gb;
-
-struct grub_e820_mmap_entry
-{
-  grub_uint64_t addr;
-  grub_uint64_t len;
-  grub_uint32_t type;
-} __attribute__((packed));
-
-
-static grub_err_t
-preboot (int noreturn __attribute__ ((unused)))
-{
-  struct grub_e820_mmap_entry *hookmmap, *hookmmapcur;
-  auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t,
-                                      grub_uint32_t);
-  int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size,
-                                 grub_uint32_t type)
-  {
-    grub_dprintf ("mmap", "mmap chunk %llx-%llx:%x\n", addr, addr + size, type);
-    hookmmapcur->addr = addr;
-    hookmmapcur->len = size;
-    hookmmapcur->type = type;
-    hookmmapcur++;
-    return 0;
-  }
-
-  if (! hooktarget)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                      "no space is allocated for memory hook");
-
-  grub_dprintf ("mmap", "installing preboot handlers\n");
-
-  hookmmapcur = hookmmap = (struct grub_e820_mmap_entry *)
-    ((grub_uint8_t *) hooktarget + (&grub_machine_mmaphook_end
-                                   - &grub_machine_mmaphook_start));
-
-  grub_mmap_iterate (fill_hook);
-  grub_machine_mmaphook_mmap_num = hookmmapcur - hookmmap;
-
-  grub_machine_mmaphook_kblow = grub_mmap_get_lower () >> 10;
-  grub_machine_mmaphook_kbin16mb
-    = min (grub_mmap_get_upper (),0x3f00000ULL) >> 10;
-  grub_machine_mmaphook_64kbin4gb
-    = min (grub_mmap_get_post64 (), 0xfc000000ULL) >> 16;
-
-  /* Correct BDA. */
-  *((grub_uint16_t *) 0x413) = grub_mmap_get_lower () >> 10;
-
-  /* Save old interrupt handlers. */
-  grub_machine_mmaphook_int12offset = *((grub_uint16_t *) 0x48);
-  grub_machine_mmaphook_int12segment = *((grub_uint16_t *) 0x4a);
-  grub_machine_mmaphook_int15offset = *((grub_uint16_t *) 0x54);
-  grub_machine_mmaphook_int15segment = *((grub_uint16_t *) 0x56);
-
-  grub_dprintf ("mmap", "hooktarget = %p\n", hooktarget);
-
-  /* Install the interrupt handlers. */
-  grub_memcpy (hooktarget, &grub_machine_mmaphook_start,
-              &grub_machine_mmaphook_end - &grub_machine_mmaphook_start);
-
-  *((grub_uint16_t *) 0x4a) = PTR_TO_UINT32 (hooktarget) >> 4;
-  *((grub_uint16_t *) 0x56) = PTR_TO_UINT32 (hooktarget) >> 4;
-  *((grub_uint16_t *) 0x48) = &grub_machine_mmaphook_int12
-    - &grub_machine_mmaphook_start;
-  *((grub_uint16_t *) 0x54) = &grub_machine_mmaphook_int15
-    - &grub_machine_mmaphook_start;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-preboot_rest (void)
-{
-  /* Restore old interrupt handlers. */
-  *((grub_uint16_t *) 0x48) = grub_machine_mmaphook_int12offset;
-  *((grub_uint16_t *) 0x4a) = grub_machine_mmaphook_int12segment;
-  *((grub_uint16_t *) 0x54) = grub_machine_mmaphook_int15offset;
-  *((grub_uint16_t *) 0x56) = grub_machine_mmaphook_int15segment;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-malloc_hook (void)
-{
-  static int reentry = 0;
-  static int mmapregion = 0;
-  static int slots_available = 0;
-  int hooksize;
-  int regcount = 0;
-  auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t,
-                                       grub_uint32_t);
-  int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
-                                  grub_uint64_t size __attribute__ ((unused)),
-                                  grub_uint32_t type __attribute__ ((unused)))
-  {
-    regcount++;
-    return 0;
-  }
-
-  if (reentry)
-    return GRUB_ERR_NONE;
-
-  grub_dprintf ("mmap", "registering\n");
-
-  grub_mmap_iterate (count_hook);
-
-  /* Mapping hook itself may introduce up to 2 additional regions. */
-  regcount += 2;
-
-  if (regcount <= slots_available)
-    return GRUB_ERR_NONE;
-
-  if (mmapregion)
-    {
-      grub_mmap_free_and_unregister (mmapregion);
-      mmapregion = 0;
-      hooktarget = 0;
-    }
-
-  hooksize = &grub_machine_mmaphook_end - &grub_machine_mmaphook_start
-    + regcount * sizeof (struct grub_e820_mmap_entry);
-  /* Allocate an integer number of KiB. */
-  hooksize = ((hooksize - 1) | 0x3ff) + 1;
-  slots_available = (hooksize - (&grub_machine_mmaphook_end
-                                - &grub_machine_mmaphook_start))
-    / sizeof (struct grub_e820_mmap_entry);
-
-  reentry = 1;
-  hooktarget
-    = grub_mmap_malign_and_register (16, hooksize, &mmapregion,
-                                    GRUB_MACHINE_MEMORY_RESERVED,
-                                    GRUB_MMAP_MALLOC_LOW);
-  reentry = 0;
-
-  if (! hooktarget)
-    {
-      slots_available = 0;
-      return grub_error (GRUB_ERR_OUT_OF_MEMORY, "no space for mmap hook");
-    }
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
-                           grub_uint64_t size __attribute__ ((unused)),
-                           int type __attribute__ ((unused)),
-                           int handle  __attribute__ ((unused)))
-{
-  grub_err_t err;
-  static void *preb_handle = 0;
-
-  err = malloc_hook ();
-  if (err)
-    return err;
-
-  if (! preb_handle)
-    {
-      grub_dprintf ("mmap", "adding preboot\n");
-      preb_handle
-       = grub_loader_register_preboot_hook (preboot, preboot_rest,
-                                            GRUB_LOADER_PREBOOT_HOOK_PRIO_MEMORY);
-      if (! preb_handle)
-       return grub_errno;
-    }
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_machine_mmap_unregister (int handle __attribute__ ((unused)))
-{
-  return GRUB_ERR_NONE;
-}
diff --git a/mmap/i386/pc/mmap_helper.S b/mmap/i386/pc/mmap_helper.S
deleted file mode 100644 (file)
index 7439545..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/* Mmap management. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/symbol.h>
-
-#define DS(x) ((x) - LOCAL (segstart))
-
-LOCAL (segstart):
-VARIABLE(grub_machine_mmaphook_start)
-       .code16
-VARIABLE(grub_machine_mmaphook_int12)
-       push %ds
-       push %cs
-       pop %ds
-       movw DS (LOCAL (kblow)), %ax
-       pop %ds
-       iret
-
-VARIABLE(grub_machine_mmaphook_int15)
-       pushf
-       cmpw $0xe801, %ax
-       jz LOCAL (e801)
-       cmpw $0xe820, %ax
-       jz LOCAL (e820)
-       cmpb $0x88, %ah
-       jz LOCAL (h88)
-       popf
-       /* ljmp */
-       .byte   0xea
-VARIABLE (grub_machine_mmaphook_int15offset)
-       .word   0
-VARIABLE (grub_machine_mmaphook_int15segment)
-       .word   0
-
-LOCAL (e801):
-       popf
-       push %ds
-       push %cs
-       pop %ds
-       movw DS (LOCAL (kbin16mb)), %ax
-       movw DS (LOCAL (m64kbin4gb)), %bx
-       movw %ax, %cx
-       movw %bx, %dx
-       pop %ds
-       clc
-       iret
-
-LOCAL (h88):
-       popf
-       push %ds
-       push %cs
-       pop %ds
-       movw DS (LOCAL (kbin16mb)), %ax
-       pop %ds
-       clc
-       iret
-
-LOCAL (e820):
-       popf
-       push %ds
-       push %cs
-       pop %ds
-       cmpw $20, %cx
-       jb LOCAL (errexit)
-       cmpw DS (LOCAL (mmap_num)), %bx
-       jae LOCAL (errexit)
-       cmp $0x534d4150, %edx
-       jne LOCAL (errexit)
-       push %si
-       push %di
-       movw $20, %cx
-       movw $(DS(LOCAL (mmaphook_mmap))), %si
-       mov %bx, %ax
-       imul $20, %ax
-       add %ax, %si
-       rep movsb
-       pop %di
-       pop %si
-       movl $20, %ecx
-       inc %bx
-       cmpw DS(LOCAL (mmap_num)), %bx
-       jb LOCAL (noclean)
-       xor %bx, %bx
-LOCAL (noclean):
-       mov $0x534d4150, %eax
-       pop %ds
-       clc
-       iret
-LOCAL (errexit):
-       mov $0x534d4150, %eax
-       pop %ds
-       stc
-       xor %bx, %bx
-       iret
-
-VARIABLE(grub_machine_mmaphook_mmap_num)
-LOCAL (mmap_num):
-       .word 0
-VARIABLE(grub_machine_mmaphook_kblow)
-LOCAL (kblow):
-       .word 0
-VARIABLE (grub_machine_mmaphook_kbin16mb)
-LOCAL (kbin16mb):
-       .word 0
-VARIABLE (grub_machine_mmaphook_64kbin4gb)
-LOCAL (m64kbin4gb):
-       .word 0
-LOCAL (mmaphook_mmap):
-       /* Memory map is placed just after the interrupt handlers. */
-VARIABLE(grub_machine_mmaphook_end)
-       .byte 0
diff --git a/mmap/i386/uppermem.c b/mmap/i386/uppermem.c
deleted file mode 100644 (file)
index cd1a452..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Compute amount of lower and upper memory till the first hole. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/memory.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-
-grub_uint64_t
-grub_mmap_get_lower (void)
-{
-  grub_uint64_t lower = 0;
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
-                            grub_uint32_t type)
-    {
-      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
-       return 0;
-      if (addr == 0)
-       lower = size;
-      return 0;
-    }
-
-  grub_mmap_iterate (hook);
-  if (lower > 0x100000)
-    lower =  0x100000;
-  return lower;
-}
-
-grub_uint64_t
-grub_mmap_get_upper (void)
-{
-  grub_uint64_t upper = 0;
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
-                            grub_uint32_t type)
-    {
-      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
-       return 0;
-      if (addr <= 0x100000 && addr + size > 0x100000)
-       upper = addr + size - 0x100000;
-      return 0;
-    }
-
-  grub_mmap_iterate (hook);
-  return upper;
-}
-
-/* Count the continuous bytes after 64 MiB. */
-grub_uint64_t
-grub_mmap_get_post64 (void)
-{
-  grub_uint64_t post64 = 0;
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
-                            grub_uint32_t type)
-    {
-      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
-       return 0;
-      if (addr <= 0x4000000 && addr + size > 0x4000000)
-       post64 = addr + size - 0x4000000;
-      return 0;
-    }
-
-  grub_mmap_iterate (hook);
-  return post64;
-}
diff --git a/mmap/mips/yeeloong/uppermem.c b/mmap/mips/yeeloong/uppermem.c
deleted file mode 100644 (file)
index 3c5f814..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Compute amount of lower and upper memory till the first hole. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/memory.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/machine/memory.h>
-
-grub_uint64_t
-grub_mmap_get_lower (void)
-{
-  grub_uint64_t lower = 0;
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
-                            grub_uint32_t type)
-    {
-      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
-       return 0;
-      if (addr == 0)
-       lower = size;
-      return 0;
-    }
-
-  grub_mmap_iterate (hook);
-  if (lower > GRUB_ARCH_LOWMEMMAXSIZE)
-    lower = GRUB_ARCH_LOWMEMMAXSIZE;
-  return lower;
-}
-
-grub_uint64_t
-grub_mmap_get_upper (void)
-{
-  grub_uint64_t upper = 0;
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
-                            grub_uint32_t type)
-    {
-      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
-       return 0;
-      if (addr <= GRUB_ARCH_HIGHMEMPSTART && addr + size
-         > GRUB_ARCH_HIGHMEMPSTART)
-       upper = addr + size - GRUB_ARCH_HIGHMEMPSTART;
-      return 0;
-    }
-
-  grub_mmap_iterate (hook);
-  return upper;
-}
diff --git a/mmap/mmap.c b/mmap/mmap.c
deleted file mode 100644 (file)
index a1afc8b..0000000
+++ /dev/null
@@ -1,426 +0,0 @@
-/* Mmap management. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/machine/memory.h>
-#include <grub/memory.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/command.h>
-#include <grub/dl.h>
-#include <grub/i18n.h>
-
-#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
-
-struct grub_mmap_region *grub_mmap_overlays = 0;
-static int curhandle = 1;
-
-#endif
-
-grub_err_t
-grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
-                                                grub_uint64_t, grub_uint32_t))
-{
-
-  /* This function resolves overlapping regions and sorts the memory map.
-     It uses scanline (sweeping) algorithm.
-  */
-  /* If same page is used by multiple types it's resolved
-     according to priority:
-     1 - free memory
-     2 - memory usable by firmware-aware code
-     3 - unusable memory
-     4 - a range deliberately empty
-  */
-  int priority[GRUB_MACHINE_MEMORY_MAX_TYPE + 2] =
-    {
-#ifdef GRUB_MACHINE_MEMORY_AVAILABLE
-      [GRUB_MACHINE_MEMORY_AVAILABLE] = 1,
-#endif
-#if defined (GRUB_MACHINE_MEMORY_RESERVED) && GRUB_MACHINE_MEMORY_RESERVED != GRUB_MACHINE_MEMORY_HOLE
-      [GRUB_MACHINE_MEMORY_RESERVED] = 3,
-#endif
-#ifdef GRUB_MACHINE_MEMORY_ACPI
-      [GRUB_MACHINE_MEMORY_ACPI] = 2,
-#endif
-#ifdef GRUB_MACHINE_MEMORY_CODE
-      [GRUB_MACHINE_MEMORY_CODE] = 3,
-#endif
-#ifdef GRUB_MACHINE_MEMORY_NVS
-      [GRUB_MACHINE_MEMORY_NVS] = 3,
-#endif
-      [GRUB_MACHINE_MEMORY_HOLE] = 4,
-    };
-
-  int i, k, done;
-
-  /* Scanline events. */
-  struct grub_mmap_scan
-  {
-    /* At which memory address. */
-    grub_uint64_t pos;
-    /* 0 = region starts, 1 = region ends. */
-    int type;
-    /* Which type of memory region? */
-    int memtype;
-  };
-  struct grub_mmap_scan *scanline_events;
-  struct grub_mmap_scan t;
-
-  /* Previous scanline event. */
-  grub_uint64_t lastaddr;
-  int lasttype;
-  /* Current scanline event. */
-  int curtype;
-  /* How many regions of given type overlap at current location? */
-  int present[GRUB_MACHINE_MEMORY_MAX_TYPE + 2];
-  /* Number of mmap chunks. */
-  int mmap_num;
-
-#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
-  struct grub_mmap_region *cur;
-#endif
-
-  auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t,
-                                       grub_uint32_t);
-  int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
-                                  grub_uint64_t size __attribute__ ((unused)),
-                                  grub_uint32_t type __attribute__ ((unused)))
-  {
-    mmap_num++;
-    return 0;
-  }
-
-  auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t,
-                                       grub_uint32_t);
-  int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr,
-                                 grub_uint64_t size,
-                                 grub_uint32_t type)
-  {
-    scanline_events[i].pos = addr;
-    scanline_events[i].type = 0;
-    if (type <= GRUB_MACHINE_MEMORY_MAX_TYPE && priority[type])
-      scanline_events[i].memtype = type;
-    else
-      {
-       grub_dprintf ("mmap", "Unknown memory type %d. Assuming unusable\n",
-                     type);
-       scanline_events[i].memtype = GRUB_MACHINE_MEMORY_RESERVED;
-      }
-    i++;
-
-    scanline_events[i].pos = addr + size;
-    scanline_events[i].type = 1;
-    scanline_events[i].memtype = scanline_events[i - 1].memtype;
-    i++;
-
-    return 0;
-  }
-
-  mmap_num = 0;
-
-#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
-  for (cur = grub_mmap_overlays; cur; cur = cur->next)
-    mmap_num++;
-#endif
-
-  grub_machine_mmap_iterate (count_hook);
-
-  /* Initialize variables. */
-  grub_memset (present, 0, sizeof (present));
-  scanline_events = (struct grub_mmap_scan *)
-    grub_malloc (sizeof (struct grub_mmap_scan) * 2 * mmap_num);
-
-  if (! scanline_events)
-    {
-      return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                        "couldn't allocate space for new memory map");
-    }
-
-  i = 0;
-#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
-  /* Register scanline events. */
-  for (cur = grub_mmap_overlays; cur; cur = cur->next)
-    {
-      scanline_events[i].pos = cur->start;
-      scanline_events[i].type = 0;
-      if (cur->type == GRUB_MACHINE_MEMORY_HOLE
-         || (cur->type >= 0 && cur->type <= GRUB_MACHINE_MEMORY_MAX_TYPE
-             && priority[cur->type]))
-       scanline_events[i].memtype = cur->type;
-      else
-       scanline_events[i].memtype = GRUB_MACHINE_MEMORY_RESERVED;
-      i++;
-
-      scanline_events[i].pos = cur->end;
-      scanline_events[i].type = 1;
-      scanline_events[i].memtype = scanline_events[i - 1].memtype;
-      i++;
-    }
-#endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */
-
-  grub_machine_mmap_iterate (fill_hook);
-
-  /* Primitive bubble sort. It has complexity O(n^2) but since we're
-     unlikely to have more than 100 chunks it's probably one of the
-     fastest for one purpose. */
-  done = 1;
-  while (done)
-    {
-      done = 0;
-      for (i = 0; i < 2 * mmap_num - 1; i++)
-       if (scanline_events[i + 1].pos < scanline_events[i].pos
-           || (scanline_events[i + 1].pos == scanline_events[i].pos
-               && scanline_events[i + 1].type == 0
-               && scanline_events[i].type == 1))
-         {
-           t = scanline_events[i + 1];
-           scanline_events[i + 1] = scanline_events[i];
-           scanline_events[i] = t;
-           done = 1;
-         }
-    }
-
-  lastaddr = scanline_events[0].pos;
-  lasttype = scanline_events[0].memtype;
-  for (i = 0; i < 2 * mmap_num; i++)
-    {
-      /* Process event. */
-      if (scanline_events[i].type)
-       present[scanline_events[i].memtype]--;
-      else
-       present[scanline_events[i].memtype]++;
-
-      /* Determine current region type. */
-      curtype = -1;
-      for (k = 0; k <= GRUB_MACHINE_MEMORY_MAX_TYPE + 1; k++)
-       if (present[k] && (curtype == -1 || priority[k] > priority[curtype]))
-         curtype = k;
-
-      /* Announce region to the hook if necessary. */
-      if ((curtype == -1 || curtype != lasttype)
-         && lastaddr != scanline_events[i].pos
-         && lasttype != -1
-         && lasttype != GRUB_MACHINE_MEMORY_HOLE
-         && hook (lastaddr, scanline_events[i].pos - lastaddr, lasttype))
-       {
-         grub_free (scanline_events);
-         return GRUB_ERR_NONE;
-       }
-
-      /* Update last values if necessary. */
-      if (curtype == -1 || curtype != lasttype)
-       {
-         lasttype = curtype;
-         lastaddr = scanline_events[i].pos;
-       }
-    }
-
-  grub_free (scanline_events);
-  return GRUB_ERR_NONE;
-}
-
-#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
-int
-grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type)
-{
-  struct grub_mmap_region *cur;
-
-  grub_dprintf ("mmap", "registering\n");
-
-  cur = (struct grub_mmap_region *)
-    grub_malloc (sizeof (struct grub_mmap_region));
-  if (! cur)
-    {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                 "couldn't allocate memory map overlay");
-      return 0;
-    }
-
-  cur->next = grub_mmap_overlays;
-  cur->start = start;
-  cur->end = start + size;
-  cur->type = type;
-  cur->handle = curhandle++;
-  grub_mmap_overlays = cur;
-
-  if (grub_machine_mmap_register (start, size, type, curhandle))
-    {
-      grub_mmap_overlays = cur->next;
-      grub_free (cur);
-      return 0;
-    }
-
-  return cur->handle;
-}
-
-grub_err_t
-grub_mmap_unregister (int handle)
-{
-  struct grub_mmap_region *cur, *prev;
-
-  for (cur = grub_mmap_overlays, prev = 0; cur; prev= cur, cur = cur->next)
-    if (handle == cur->handle)
-      {
-       grub_err_t err;
-       if ((err = grub_machine_mmap_unregister (handle)))
-         return err;
-
-       if (prev)
-         prev->next = cur->next;
-       else
-         grub_mmap_overlays = cur->next;
-       grub_free (cur);
-       return GRUB_ERR_NONE;
-      }
-  return grub_error (GRUB_ERR_BAD_ARGUMENT, "mmap overlay not found");
-}
-
-#endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */
-
-#define CHUNK_SIZE     0x400
-
-static inline grub_uint64_t
-fill_mask (grub_uint64_t addr, grub_uint64_t mask, grub_uint64_t iterator)
-{
-  int i, j;
-  grub_uint64_t ret = (addr & mask);
-
-  /* Find first fixed bit. */
-  for (i = 0; i < 64; i++)
-    if ((mask & (1ULL << i)) != 0)
-      break;
-  j = 0;
-  for (; i < 64; i++)
-    if ((mask & (1ULL << i)) == 0)
-      {
-       if ((iterator & (1ULL << j)) != 0)
-         ret |= 1ULL << i;
-       j++;
-      }
-  return ret;
-}
-
-static grub_err_t
-grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)),
-                int argc, char **args)
-{
-  char * str;
-  grub_uint64_t badaddr, badmask;
-
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr,
-                            grub_uint64_t size,
-                            grub_uint32_t type __attribute__ ((unused)))
-  {
-    grub_uint64_t iterator, low, high, cur;
-    int tail, var;
-    int i;
-    grub_dprintf ("badram", "hook %llx+%llx\n", (unsigned long long) addr,
-                 (unsigned long long) size);
-
-    /* How many trailing zeros? */
-    for (tail = 0; ! (badmask & (1ULL << tail)); tail++);
-
-    /* How many zeros in mask? */
-    var = 0;
-    for (i = 0; i < 64; i++)
-      if (! (badmask & (1ULL << i)))
-       var++;
-
-    if (fill_mask (badaddr, badmask, 0) >= addr)
-      iterator = 0;
-    else
-      {
-       low = 0;
-       high = ~0ULL;
-       /* Find starting value. Keep low and high such that
-          fill_mask (low) < addr and fill_mask (high) >= addr;
-       */
-       while (high - low > 1)
-         {
-           cur = (low + high) / 2;
-           if (fill_mask (badaddr, badmask, cur) >= addr)
-             high = cur;
-           else
-             low = cur;
-         }
-       iterator = high;
-      }
-
-    for (; iterator < (1ULL << (var - tail))
-          && (cur = fill_mask (badaddr, badmask, iterator)) < addr + size;
-        iterator++)
-      {
-       grub_dprintf ("badram", "%llx (size %llx) is a badram range\n",
-                     (unsigned long long) cur, (1ULL << tail));
-       grub_mmap_register (cur, (1ULL << tail), GRUB_MACHINE_MEMORY_HOLE);
-      }
-    return 0;
-  }
-
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "badram string required");
-
-  grub_dprintf ("badram", "executing badram\n");
-
-  str = args[0];
-
-  while (1)
-    {
-      /* Parse address and mask.  */
-      badaddr = grub_strtoull (str, &str, 16);
-      if (*str == ',')
-       str++;
-      badmask = grub_strtoull (str, &str, 16);
-      if (*str == ',')
-       str++;
-
-      if (grub_errno == GRUB_ERR_BAD_NUMBER)
-       {
-         grub_errno = 0;
-         return GRUB_ERR_NONE;
-       }
-
-      /* When part of a page is tainted, we discard the whole of it.  There's
-        no point in providing sub-page chunks.  */
-      badmask &= ~(CHUNK_SIZE - 1);
-
-      grub_dprintf ("badram", "badram %llx:%llx\n",
-                   (unsigned long long) badaddr, (unsigned long long) badmask);
-
-      grub_mmap_iterate (hook);
-    }
-}
-
-static grub_command_t cmd;
-
-\f
-GRUB_MOD_INIT(mmap)
-{
-  cmd = grub_register_command ("badram", grub_cmd_badram,
-                              N_("ADDR1,MASK1[,ADDR2,MASK2[,...]]"),
-                              N_("Declare memory regions as badram."));
-}
-
-GRUB_MOD_FINI(mmap)
-{
-  grub_unregister_command (cmd);
-}
-
diff --git a/modules.def b/modules.def
new file mode 100644 (file)
index 0000000..4877533
--- /dev/null
@@ -0,0 +1,497 @@
+AutoGen definitions Makefile.tpl;
+
+library = {
+  name = libutil.a;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+
+  nodist = grub_script.tab.c;
+  nodist = grub_script.yy.c;
+  nodist = libutil_a_init.c;
+
+  source = grub-core/gnulib/error.c;
+  source = grub-core/gnulib/fnmatch.c;
+  source = grub-core/gnulib/getdelim.c;
+  source = grub-core/gnulib/getline.c;
+  source = grub-core/gnulib/getopt1.c;
+  source = grub-core/gnulib/getopt.c;
+  source = grub-core/gnulib/progname.c;
+
+  source = util/misc.c;
+  source = grub-core/kern/misc.c;
+  source = grub-core/kern/emu/misc.c;
+  source = grub-core/kern/emu/hostfs.c;
+  source = grub-core/kern/emu/getroot.c;
+  source = grub-core/kern/emu/hostdisk.c;
+
+  source = grub-core/commands/blocklist.c;
+  source = grub-core/commands/extcmd.c;
+  source = grub-core/commands/ls.c;
+  source = grub-core/disk/dmraid_nvidia.c;
+  source = grub-core/disk/host.c;
+  source = grub-core/disk/loopback.c;
+  source = grub-core/disk/lvm.c;
+  source = grub-core/disk/mdraid_linux.c;
+  source = grub-core/disk/raid5_recover.c;
+  source = grub-core/disk/raid6_recover.c;
+  source = grub-core/disk/raid.c;
+  source = grub-core/fs/affs.c;
+  source = grub-core/fs/afs_be.c;
+  source = grub-core/fs/afs.c;
+  source = grub-core/fs/befs_be.c;
+  source = grub-core/fs/befs.c;
+  source = grub-core/fs/cpio.c;
+  source = grub-core/fs/ext2.c;
+  source = grub-core/fs/fat.c;
+  source = grub-core/fs/fshelp.c;
+  source = grub-core/fs/hfs.c;
+  source = grub-core/fs/hfsplus.c;
+  source = grub-core/fs/iso9660.c;
+  source = grub-core/fs/jfs.c;
+  source = grub-core/fs/minix.c;
+  source = grub-core/fs/nilfs2.c;
+  source = grub-core/fs/ntfs.c;
+  source = grub-core/fs/ntfscomp.c;
+  source = grub-core/fs/reiserfs.c;
+  source = grub-core/fs/sfs.c;
+  source = grub-core/fs/tar.c;
+  source = grub-core/fs/udf.c;
+  source = grub-core/fs/ufs2.c;
+  source = grub-core/fs/ufs.c;
+  source = grub-core/fs/xfs.c;
+  source = grub-core/kern/command.c;
+  source = grub-core/kern/device.c;
+  source = grub-core/kern/disk.c;
+  source = grub-core/kern/env.c;
+  source = grub-core/kern/err.c;
+  source = grub-core/kern/file.c;
+  source = grub-core/kern/fs.c;
+  source = grub-core/kern/handler.c;
+  source = grub-core/kern/list.c;
+  source = grub-core/kern/parser.c;
+  source = grub-core/kern/partition.c;
+  source = grub-core/lib/arg.c;
+  source = grub-core/lib/crc.c;
+  source = grub-core/lib/crypto.c;
+  source = grub-core/lib/envblk.c;
+  source = grub-core/lib/hexdump.c;
+  source = grub-core/lib/libgcrypt-grub/cipher/sha512.c;
+  source = grub-core/lib/LzFind.c;
+  source = grub-core/lib/LzmaEnc.c;
+  source = grub-core/lib/pbkdf2.c;
+  source = grub-core/normal/datetime.c;
+  source = grub-core/normal/misc.c;
+  source = grub-core/partmap/acorn.c;
+  source = grub-core/partmap/amiga.c;
+  source = grub-core/partmap/apple.c;
+  source = grub-core/partmap/gpt.c;
+  source = grub-core/partmap/msdos.c;
+  source = grub-core/partmap/sun.c;
+  source = grub-core/script/function.c;
+  source = grub-core/script/lexer.c;
+  source = grub-core/script/main.c;
+  source = grub-core/script/script.c;
+  common;
+};
+
+program = {
+  name = grub-bin2h;
+  source = util/bin2h.c;
+  ldadd = libutil.a;
+  mansection = 1;
+  common;
+};
+
+program = {
+  name = grub-mkimage;
+  mansection = 1;
+
+  source = util/grub-mkrawimage.c;
+  source = util/resolve.c;
+
+  x86_efi = util/i386/efi/grub-mkimage.c;
+  x86_efi = util/resolve.c;
+
+  ldadd = libutil.a;
+
+  sparc64_ieee1275_cppflags = '-DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
+  mips_cppflags = '-DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
+  i386_pc_cppflags = '-DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
+  i386_qemu_cppflags = '-DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
+
+  i386_pc; i386_qemu; mips; sparc64_ieee1275;
+};
+
+program = {
+  name = grub-mkelfimage;
+  mansection = 1;
+  source = util/elf/grub-mkimage.c;
+  source = util/resolve.c;
+
+  ldadd = libutil.a;
+  common;
+};
+
+program = {
+  name = grub-mkisofs;
+  mansection = 1;
+  source = util/mkisofs/eltorito.c;
+  source = util/mkisofs/hash.c;
+  source = util/mkisofs/joliet.c;
+  source = util/mkisofs/match.c;
+  source = util/mkisofs/mkisofs.c;
+  source = util/mkisofs/multi.c;
+  source = util/mkisofs/name.c;
+  source = util/mkisofs/rock.c;
+  source = util/mkisofs/tree.c;
+  source = util/mkisofs/write.c;
+  source = grub-core/gnulib/progname.c;
+  source = grub-core/gnulib/error.c;
+  cflags = '$(CFLAGS_MKISOFS)';
+  cppflags = '$(CPPFLAGS_MKISOFS)';
+  common;
+};
+
+program = {
+  name = grub-mkrelpath;
+  mansection = 1;
+
+  source = util/grub-mkrelpath.c;
+
+  ldadd = libutil.a;
+  common;
+};
+
+program = {
+  name = grub-script-check;
+  mansection = 1;
+
+  source = util/grub-script-check.c;
+
+  ldadd = libutil.a;
+  common;
+};
+
+program = {
+  name = grub-editenv;
+  mansection = 1;
+
+  source = util/grub-editenv.c;
+
+  ldadd = libutil.a;
+  common;
+};
+
+program = {
+  name = grub-mkpasswd-pbkdf2;
+  mansection = 1;
+
+  source = util/grub-mkpasswd-pbkdf2.c;
+
+  ldadd = libutil.a;
+  cflags = '$(CFLAGS_GCRY)';
+  cppflags = '$(CPPFLAGS_GCRY)';
+  common;
+};
+
+program = {
+  name = grub-macho2img;
+  mansection = 1;
+  source = util/grub-macho2img.c;
+};
+
+program = {
+  name = grub-pe2elf;
+  mansection = 1;
+  source = util/grub-pe2elf.c;
+
+  ldadd = libutil.a;
+};
+
+program = {
+  name = grub-fstest;
+  mansection = 1;
+  source = util/grub-fstest.c;
+
+  ldadd = libutil.a;
+  enable = COND_GRUB_FSTEST;
+  common;
+};
+
+program = {
+  name = grub-mkfont;
+  mansection = 1;
+  source = util/grub-mkfont.c;
+
+  ldadd = libutil.a;
+  cflags = '$(freetype_cflags)';
+  ldflags = '$(freetype_libs)';
+  common;
+  enable = COND_GRUB_MKFONT;
+};
+
+program = {
+  name = grub-mkdevicemap;
+  installdir = sbin;
+  mansection = 8;
+  source = util/grub-mkdevicemap.c;
+  source = util/deviceiter.c;
+  source = util/devicemap.c;
+
+  sparc64_ieee1275 = util/grub-mkdevicemap.c;
+  sparc64_ieee1275 = util/deviceiter.c;
+  sparc64_ieee1275 = util/ieee1275/ofpath.c;
+  sparc64_ieee1275 = util/ieee1275/devicemap.c;
+
+  ldadd = libutil.a;
+  common;
+};
+
+program = {
+  name = grub-probe;
+  installdir = sbin;
+  mansection = 8;
+  source = util/grub-probe.c;
+
+  ldadd = libutil.a;
+  common;
+};
+
+program = {
+  name = grub-setup;
+  installdir = sbin;
+  mansection = 8;
+  i386_pc = util/i386/pc/grub-setup.c;
+  i386_pc = util/raid.c;
+  i386_pc = util/lvm.c;
+
+  sparc64_ieee1275 = util/ieee1275/ofpath.c;
+  sparc64_ieee1275 = util/sparc64/ieee1275/grub-setup.c;
+  sparc64_ieee1275 = util/raid.c;
+  sparc64_ieee1275 = util/lvm.c;
+
+  ldadd = libutil.a;
+};
+
+program = {
+  name = grub-ofpathname;
+  installdir = sbin;
+  source = util/ieee1275/grub-ofpathname.c;
+  source = util/ieee1275/ofpath.c;
+
+  ldadd = libutil.a;
+  sparc64_ieee1275;
+};
+
+data = {
+  source = util/grub.d/README;
+  installdir = grubconf;
+  common;
+};
+
+script = {
+  name = '00_header';
+  source = util/grub.d/00_header.in;
+  installdir = grubconf;
+  common;
+};
+
+script = {
+  name = '10_windows';
+  source = util/grub.d/10_windows.in;
+  installdir = grubconf;
+};
+
+script = {
+  name = '10_hurd';
+  source = util/grub.d/10_hurd.in;
+  installdir = grubconf;
+};
+
+script = {
+  name = '10_linux';
+  source = util/grub.d/10_linux.in;
+  installdir = grubconf;
+  common;
+};
+
+script = {
+  name = '30_os-prober';
+  source = util/grub.d/30_os-prober.in;
+  installdir = grubconf;
+  common;
+};
+
+script = {
+  name = '40_custom';
+  source = util/grub.d/40_custom.in;
+  installdir = grubconf;
+  common;
+};
+
+script = {
+  mansection = 1;
+  name = grub-mkrescue;
+  source = util/grub-mkrescue.in;
+  powerpc_ieee1275 = util/powerpc/ieee1275/grub-mkrescue.in;
+  i386_pc;
+  i386_qemu;
+  i386_coreboot;
+};
+
+script = {
+  mansection = 8;
+  installdir = sbin;
+  name = grub-install;
+  source = util/grub-install.in;
+  x86_efi = util/i386/efi/grub-install.in;
+  i386_ieee1275 = util/ieee1275/grub-install.in;
+  powerpc_ieee1275 = util/ieee1275/grub-install.in;
+  mips;
+  i386_pc;
+  i386_qemu;
+  i386_coreboot;
+};
+
+script = {
+  name = grub-mkconfig;
+  source = util/grub-mkconfig.in;
+  mansection = 8;
+  installdir = sbin;
+  common;
+};
+
+script = {
+  name = grub-set-default;
+  source = util/grub-set-default.in;
+  mansection = 8;
+  installdir = sbin;
+  common;
+};
+
+script = {
+  name = grub-reboot;
+  source = util/grub-reboot.in;
+  mansection = 8;
+  installdir = sbin;
+  common;
+};
+
+script = {
+  name = grub-mkconfig_lib;
+  source = util/grub-mkconfig_lib.in;
+  installdir = pkglib;
+  common;
+};
+
+script = {
+  name = update-grub_lib;
+  source = util/update-grub_lib.in;
+  installdir = pkglib;
+  common;
+};
+
+test_script = {
+  name = grub-shell;
+  source = tests/util/grub-shell.in;
+  common;
+};
+
+test_script = {
+  name = grub-shell-tester;
+  source = tests/util/grub-shell-tester.in;
+  common;
+};
+
+test_script = {
+  name = example_scripted_test;
+  source = tests/example_scripted_test.in;
+  common;
+};
+
+test_script = {
+  name = example_grub_script_test;
+  source = tests/example_grub_script_test.in;
+  common;
+};
+
+test_script = {
+  name = grub_script_echo1;
+  source = tests/grub_script_echo1.in;
+  common;
+  enable;
+};
+
+test_script = {
+  name = grub_script_echo_keywords;
+  source = tests/grub_script_echo_keywords.in;
+  common;
+  enable;
+};
+
+test_script = {
+  name = grub_script_vars1;
+  source = tests/grub_script_vars1.in;
+  common;
+  enable;
+};
+
+test_script = {
+  name = grub_script_for1;
+  source = tests/grub_script_for1.in;
+  common;
+  enable;
+};
+
+test_script = {
+  name = grub_script_while1;
+  source = tests/grub_script_while1.in;
+  common;
+  enable;
+};
+
+test_script = {
+  name = grub_script_if;
+  source = tests/grub_script_if.in;
+  common;
+  enable;
+};
+
+test_script = {
+  name = grub_script_blanklines;
+  source = tests/grub_script_blanklines.in;
+  common;
+  enable;
+};
+
+test_script = {
+  name = grub_script_final_semicolon;
+  source = tests/grub_script_final_semicolon.in;
+  common;
+  enable;
+};
+
+test_script = {
+  name = grub_script_dollar;
+  source = tests/grub_script_dollar.in;
+  common;
+  enable;
+};
+
+test_script = {
+  name = grub_script_comments;
+  source = tests/grub_script_comments.in;
+  common;
+  enable;
+};
+
+test_program = {
+  name = example_unit_test;
+  source = tests/example_unit_test.c;
+  source = tests/lib/unit_test.c;
+  source = grub-core/kern/list.c;
+  source = grub-core/kern/misc.c;
+  source = grub-core/tests/lib/test.c;
+  cflags = -Wno-format;
+  common;
+};
diff --git a/normal/auth.c b/normal/auth.c
deleted file mode 100644 (file)
index 156b84c..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/auth.h>
-#include <grub/list.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/env.h>
-#include <grub/normal.h>
-#include <grub/time.h>
-#include <grub/i18n.h>
-
-struct grub_auth_user
-{
-  struct grub_auth_user *next;
-  char *name;
-  grub_auth_callback_t callback;
-  void *arg;
-  int authenticated;
-};
-
-struct grub_auth_user *users = NULL;
-
-grub_err_t
-grub_auth_register_authentication (const char *user,
-                                  grub_auth_callback_t callback,
-                                  void *arg)
-{
-  struct grub_auth_user *cur;
-
-  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
-  if (!cur)
-    cur = grub_zalloc (sizeof (*cur));
-  if (!cur)
-    return grub_errno;
-  cur->callback = callback;
-  cur->arg = arg;
-  if (! cur->name)
-    {
-      cur->name = grub_strdup (user);
-      if (!cur->name)
-       {
-         grub_free (cur);
-         return grub_errno;
-       }
-      grub_list_push (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
-    }
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_auth_unregister_authentication (const char *user)
-{
-  struct grub_auth_user *cur;
-  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
-  if (!cur)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "user '%s' not found", user);
-  if (!cur->authenticated)
-    {
-      grub_free (cur->name);
-      grub_list_remove (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
-      grub_free (cur);
-    }
-  else
-    {
-      cur->callback = NULL;
-      cur->arg = NULL;
-    }
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_auth_authenticate (const char *user)
-{
-  struct grub_auth_user *cur;
-
-  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
-  if (!cur)
-    cur = grub_zalloc (sizeof (*cur));
-  if (!cur)
-    return grub_errno;
-
-  cur->authenticated = 1;
-
-  if (! cur->name)
-    {
-      cur->name = grub_strdup (user);
-      if (!cur->name)
-       {
-         grub_free (cur);
-         return grub_errno;
-       }
-      grub_list_push (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_auth_deauthenticate (const char *user)
-{
-  struct grub_auth_user *cur;
-  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
-  if (!cur)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "user '%s' not found", user);
-  if (!cur->callback)
-    {
-      grub_free (cur->name);
-      grub_list_remove (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
-      grub_free (cur);
-    }
-  else
-    cur->authenticated = 0;
-  return GRUB_ERR_NONE;
-}
-
-static int
-is_authenticated (const char *userlist)
-{
-  const char *superusers;
-
-  auto int hook (grub_list_t item);
-  int hook (grub_list_t item)
-  {
-    const char *name;
-    if (!((struct grub_auth_user *) item)->authenticated)
-      return 0;
-    name = ((struct grub_auth_user *) item)->name;
-
-    return (userlist && grub_strword (userlist, name))
-      || grub_strword (superusers, name);
-  }
-
-  superusers = grub_env_get ("superusers");
-
-  if (!superusers)
-    return 1;
-
-  return grub_list_iterate (GRUB_AS_LIST (users), hook);
-}
-
-static int
-grub_username_get (char buf[], unsigned buf_size)
-{
-  unsigned cur_len = 0;
-  int key;
-
-  while (1)
-    {
-      key = GRUB_TERM_ASCII_CHAR (grub_getkey ()); 
-      if (key == '\n' || key == '\r')
-       break;
-
-      if (key == '\e')
-       {
-         cur_len = 0;
-         break;
-       }
-
-      if (key == '\b')
-       {
-         cur_len--;
-         grub_printf ("\b");
-         continue;
-       }
-
-      if (!grub_isprint (key))
-       continue;
-
-      if (cur_len + 2 < buf_size)
-       {
-         buf[cur_len++] = key;
-         grub_putchar (key);
-       }
-    }
-
-  grub_memset (buf + cur_len, 0, buf_size - cur_len);
-
-  grub_putchar ('\n');
-  grub_refresh ();
-
-  return (key != '\e');
-}
-
-grub_err_t
-grub_auth_check_authentication (const char *userlist)
-{
-  char login[1024];
-  struct grub_auth_user *cur = NULL;
-  grub_err_t err;
-  static unsigned long punishment_delay = 1;
-  char entered[GRUB_AUTH_MAX_PASSLEN];
-
-  auto int hook (grub_list_t item);
-  int hook (grub_list_t item)
-  {
-    if (grub_strcmp (login, ((struct grub_auth_user *) item)->name) == 0)
-      cur = (struct grub_auth_user *) item;
-    return 0;
-  }
-
-  auto int hook_any (grub_list_t item);
-  int hook_any (grub_list_t item)
-  {
-    if (((struct grub_auth_user *) item)->callback)
-      cur = (struct grub_auth_user *) item;
-    return 0;
-  }
-
-  grub_memset (login, 0, sizeof (login));
-
-  if (is_authenticated (userlist))
-    {
-      punishment_delay = 1;
-      return GRUB_ERR_NONE;
-    }
-
-  grub_puts_ (N_("Enter username: "));
-
-  if (!grub_username_get (login, sizeof (login) - 1))
-    goto access_denied;
-
-  grub_puts_ (N_("Enter password: "));
-
-  if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
-    goto access_denied;
-
-  grub_list_iterate (GRUB_AS_LIST (users), hook);
-
-  if (!cur || ! cur->callback)
-    goto access_denied;
-
-  err = cur->callback (login, entered, cur->arg);
-  if (is_authenticated (userlist))
-    {
-      punishment_delay = 1;
-      return GRUB_ERR_NONE;
-    }
-
- access_denied:
-  grub_sleep (punishment_delay);
-
-  if (punishment_delay < GRUB_ULONG_MAX / 2)
-    punishment_delay *= 2;
-
-  return GRUB_ACCESS_DENIED;
-}
diff --git a/normal/autofs.c b/normal/autofs.c
deleted file mode 100644 (file)
index e1d4c01..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/* autofs.c - support auto-loading from fs.lst */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/dl.h>
-#include <grub/env.h>
-#include <grub/misc.h>
-#include <grub/fs.h>
-#include <grub/normal.h>
-
-/* This is used to store the names of filesystem modules for auto-loading.  */
-static grub_named_list_t fs_module_list;
-
-/* The auto-loading hook for filesystems.  */
-static int
-autoload_fs_module (void)
-{
-  grub_named_list_t p;
-
-  while ((p = fs_module_list) != NULL)
-    {
-      if (! grub_dl_get (p->name) && grub_dl_load (p->name))
-       return 1;
-
-      if (grub_errno)
-       grub_print_error ();
-
-      fs_module_list = p->next;
-      grub_free (p->name);
-      grub_free (p);
-    }
-
-  return 0;
-}
-
-/* Read the file fs.lst for auto-loading.  */
-void
-read_fs_list (const char *prefix)
-{
-  if (prefix)
-    {
-      char *filename;
-
-      filename = grub_xasprintf ("%s/fs.lst", prefix);
-      if (filename)
-       {
-         grub_file_t file;
-         grub_fs_autoload_hook_t tmp_autoload_hook;
-
-         /* This rules out the possibility that read_fs_list() is invoked
-            recursively when we call grub_file_open() below.  */
-         tmp_autoload_hook = grub_fs_autoload_hook;
-         grub_fs_autoload_hook = NULL;
-
-         file = grub_file_open (filename);
-         if (file)
-           {
-             /* Override previous fs.lst.  */
-             while (fs_module_list)
-               {
-                 grub_named_list_t tmp;
-                 tmp = fs_module_list->next;
-                 grub_free (fs_module_list);
-                 fs_module_list = tmp;
-               }
-
-             while (1)
-               {
-                 char *buf;
-                 char *p;
-                 char *q;
-                 grub_named_list_t fs_mod;
-
-                 buf = grub_file_getline (file);
-                 if (! buf)
-                   break;
-
-                 p = buf;
-                 q = buf + grub_strlen (buf) - 1;
-
-                 /* Ignore space.  */
-                 while (grub_isspace (*p))
-                   p++;
-
-                 while (p < q && grub_isspace (*q))
-                   *q-- = '\0';
-
-                 /* If the line is empty, skip it.  */
-                 if (p >= q)
-                   continue;
-
-                 fs_mod = grub_malloc (sizeof (*fs_mod));
-                 if (! fs_mod)
-                   continue;
-
-                 fs_mod->name = grub_strdup (p);
-                 if (! fs_mod->name)
-                   {
-                     grub_free (fs_mod);
-                     continue;
-                   }
-
-                 fs_mod->next = fs_module_list;
-                 fs_module_list = fs_mod;
-               }
-
-             grub_file_close (file);
-             grub_fs_autoload_hook = tmp_autoload_hook;
-           }
-
-         grub_free (filename);
-       }
-    }
-
-  /* Ignore errors.  */
-  grub_errno = GRUB_ERR_NONE;
-
-  /* Set the hook.  */
-  grub_fs_autoload_hook = autoload_fs_module;
-}
diff --git a/normal/cmdline.c b/normal/cmdline.c
deleted file mode 100644 (file)
index 05d6654..0000000
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/normal.h>
-#include <grub/misc.h>
-#include <grub/term.h>
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/mm.h>
-#include <grub/partition.h>
-#include <grub/disk.h>
-#include <grub/file.h>
-#include <grub/env.h>
-#include <grub/i18n.h>
-#include <grub/charset.h>
-
-static grub_uint32_t *kill_buf;
-
-static int hist_size;
-static grub_uint32_t **hist_lines = 0;
-static int hist_pos = 0;
-static int hist_end = 0;
-static int hist_used = 0;
-
-grub_err_t
-grub_set_history (int newsize)
-{
-  grub_uint32_t **old_hist_lines = hist_lines;
-  hist_lines = grub_malloc (sizeof (grub_uint32_t *) * newsize);
-
-  /* Copy the old lines into the new buffer.  */
-  if (old_hist_lines)
-    {
-      /* Remove the lines that don't fit in the new buffer.  */
-      if (newsize < hist_used)
-       {
-         int i;
-         int delsize = hist_used - newsize;
-         hist_used = newsize;
-
-         for (i = 1; i <= delsize; i++)
-           {
-             int pos = hist_end - i;
-             if (pos < 0)
-               pos += hist_size;
-             grub_free (old_hist_lines[pos]);
-           }
-
-         hist_end -= delsize;
-         if (hist_end < 0)
-           hist_end += hist_size;
-       }
-
-      if (hist_pos < hist_end)
-       grub_memmove (hist_lines, old_hist_lines + hist_pos,
-                     (hist_end - hist_pos) * sizeof (grub_uint32_t *));
-      else if (hist_used)
-       {
-         /* Copy the older part.  */
-         grub_memmove (hist_lines, old_hist_lines + hist_pos,
-                       (hist_size - hist_pos) * sizeof (grub_uint32_t *));
-
-         /* Copy the newer part. */
-         grub_memmove (hist_lines + hist_size - hist_pos, old_hist_lines,
-                       hist_end * sizeof (grub_uint32_t *));
-       }
-    }
-
-  grub_free (old_hist_lines);
-
-  hist_size = newsize;
-  hist_pos = 0;
-  hist_end = hist_used;
-  return 0;
-}
-
-/* Get the entry POS from the history where `0' is the newest
-   entry.  */
-static grub_uint32_t *
-grub_history_get (int pos)
-{
-  pos = (hist_pos + pos) % hist_size;
-  return hist_lines[pos];
-}
-
-static grub_size_t
-strlen_ucs4 (const grub_uint32_t *s)
-{
-  const grub_uint32_t *p = s;
-
-  while (*p)
-    p++;
-
-  return p - s;
-}
-
-/* Replace the history entry on position POS with the string S.  */
-static void
-grub_history_set (int pos, grub_uint32_t *s, grub_size_t len)
-{
-  grub_free (hist_lines[pos]);
-  hist_lines[pos] = grub_malloc ((len + 1) * sizeof (grub_uint32_t));
-  if (!hist_lines[pos])
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-      return ;
-    }
-  grub_memcpy (hist_lines[pos], s, len * sizeof (grub_uint32_t));
-  hist_lines[pos][len] = 0;
-}
-
-/* Insert a new history line S on the top of the history.  */
-static void
-grub_history_add (grub_uint32_t *s, grub_size_t len)
-{
-  /* Remove the oldest entry in the history to make room for a new
-     entry.  */
-  if (hist_used + 1 > hist_size)
-    {
-      hist_end--;
-      if (hist_end < 0)
-       hist_end = hist_size + hist_end;
-
-      grub_free (hist_lines[hist_end]);
-    }
-  else
-    hist_used++;
-
-  /* Move to the next position.  */
-  hist_pos--;
-  if (hist_pos < 0)
-    hist_pos = hist_size + hist_pos;
-
-  /* Insert into history.  */
-  hist_lines[hist_pos] = NULL;
-  grub_history_set (hist_pos, s, len);
-}
-
-/* Replace the history entry on position POS with the string S.  */
-static void
-grub_history_replace (int pos, grub_uint32_t *s, grub_size_t len)
-{
-  grub_history_set ((hist_pos + pos) % hist_size, s, len);
-}
-
-/* A completion hook to print items.  */
-static void
-print_completion (const char *item, grub_completion_type_t type, int count)
-{
-  if (count == 0)
-    {
-      /* If this is the first time, print a label.  */
-      
-      grub_puts ("");
-      switch (type)
-       {
-       case GRUB_COMPLETION_TYPE_COMMAND:
-         grub_puts_ (N_("Possible commands are:"));
-         break;
-       case GRUB_COMPLETION_TYPE_DEVICE:
-         grub_puts_ (N_("Possible devices are:"));
-         break;
-       case GRUB_COMPLETION_TYPE_FILE:
-         grub_puts_ (N_("Possible files are:"));
-         break;
-       case GRUB_COMPLETION_TYPE_PARTITION:
-         grub_puts_ (N_("Possible partitions are:"));
-         break;
-       case GRUB_COMPLETION_TYPE_ARGUMENT:
-         grub_puts_ (N_("Possible arguments are:"));
-         break;
-       default:
-         grub_puts_ (N_("Possible things are:"));
-         break;
-       }
-      grub_puts ("");
-    }
-
-  if (type == GRUB_COMPLETION_TYPE_PARTITION)
-    {
-      grub_normal_print_device_info (item);
-      grub_errno = GRUB_ERR_NONE;
-    }
-  else
-    grub_printf (" %s", item);
-}
-
-struct cmdline_term
-{
-  unsigned xpos, ypos, ystart, width, height;
-  struct grub_term_output *term;
-};
-
-/* Get a command-line. If ESC is pushed, return zero,
-   otherwise return command line.  */
-/* FIXME: The dumb interface is not supported yet.  */
-char *
-grub_cmdline_get (const char *prompt)
-{
-  grub_size_t lpos, llen;
-  grub_size_t plen;
-  grub_uint32_t *buf;
-  grub_size_t max_len = 256;
-  int key;
-  int histpos = 0;
-  auto void cl_insert (const grub_uint32_t *str);
-  auto void cl_delete (unsigned len);
-  auto inline void __attribute__ ((always_inline)) cl_print (struct cmdline_term *cl_term, int pos,
-                       grub_uint32_t c);
-  auto void cl_set_pos (struct cmdline_term *cl_term);
-  auto void cl_print_all (int pos, grub_uint32_t c);
-  auto void cl_set_pos_all (void);
-  auto void init_clterm (struct cmdline_term *cl_term_cur);
-  auto void init_clterm_all (void);
-  const char *prompt_translated = _(prompt);
-  struct cmdline_term *cl_terms;
-  char *ret;
-  unsigned nterms;
-
-  void cl_set_pos (struct cmdline_term *cl_term)
-  {
-    cl_term->xpos = (plen + lpos) % (cl_term->width - 1);
-    cl_term->ypos = cl_term->ystart + (plen + lpos) / (cl_term->width - 1);
-    grub_term_gotoxy (cl_term->term, cl_term->xpos, cl_term->ypos);
-  }
-
-  void cl_set_pos_all ()
-  {
-    unsigned i;
-    for (i = 0; i < nterms; i++)
-      cl_set_pos (&cl_terms[i]);
-  }
-
-  inline void __attribute__ ((always_inline)) cl_print (struct cmdline_term *cl_term, int pos, grub_uint32_t c)
-    {
-      grub_uint32_t *p;
-
-      for (p = buf + pos; p < buf + llen; p++)
-       {
-         if (c)
-           grub_putcode (c, cl_term->term);
-         else
-           grub_putcode (*p, cl_term->term);
-         cl_term->xpos++;
-         if (cl_term->xpos >= cl_term->width - 1)
-           {
-             cl_term->xpos = 0;
-             if (cl_term->ypos >= (unsigned) (cl_term->height - 1))
-               cl_term->ystart--;
-             else
-               cl_term->ypos++;
-             grub_putcode ('\n', cl_term->term);
-           }
-       }
-    }
-
-  void cl_print_all (int pos, grub_uint32_t c)
-  {
-    unsigned i;
-    for (i = 0; i < nterms; i++)
-      cl_print (&cl_terms[i], pos, c);
-  }
-
-  void cl_insert (const grub_uint32_t *str)
-    {
-      grub_size_t len = strlen_ucs4 (str);
-
-      if (len + llen >= max_len)
-       {
-         grub_uint32_t *nbuf;
-         max_len *= 2;
-         nbuf = grub_realloc (buf, sizeof (grub_uint32_t) * max_len);
-         if (nbuf)
-           buf = nbuf;
-         else
-           {
-             grub_print_error ();
-             grub_errno = GRUB_ERR_NONE;
-             max_len /= 2;
-           }
-       }
-
-      if (len + llen < max_len)
-       {
-         grub_memmove (buf + lpos + len, buf + lpos,
-                       (llen - lpos + 1) * sizeof (grub_uint32_t));
-         grub_memmove (buf + lpos, str, len * sizeof (grub_uint32_t));
-
-         llen += len;
-         cl_set_pos_all ();
-         cl_print_all (lpos, 0);
-         lpos += len;
-         cl_set_pos_all ();
-       }
-    }
-
-  void cl_delete (unsigned len)
-    {
-      if (lpos + len <= llen)
-       {
-         grub_size_t saved_lpos = lpos;
-
-         lpos = llen - len;
-         cl_set_pos_all ();
-         cl_print_all (lpos, ' ');
-         lpos = saved_lpos;
-         cl_set_pos_all ();
-
-         grub_memmove (buf + lpos, buf + lpos + len,
-                       sizeof (grub_uint32_t) * (llen - lpos + 1));
-         llen -= len;
-         cl_print_all (lpos, 0);
-         cl_set_pos_all ();
-       }
-    }
-
-  void init_clterm (struct cmdline_term *cl_term_cur)
-  {
-    cl_term_cur->xpos = plen;
-    cl_term_cur->ypos = (grub_term_getxy (cl_term_cur->term) & 0xFF);
-    cl_term_cur->ystart = cl_term_cur->ypos;
-    cl_term_cur->width = grub_term_width (cl_term_cur->term);
-    cl_term_cur->height = grub_term_height (cl_term_cur->term);
-  }
-
-  void init_clterm_all (void)
-  {
-    unsigned i;
-    for (i = 0; i < nterms; i++)
-      init_clterm (&cl_terms[i]);
-  }
-
-  buf = grub_malloc (max_len * sizeof (grub_uint32_t));
-  if (!buf)
-    return 0;
-
-  plen = grub_strlen (prompt_translated) + sizeof (" ") - 1;
-  lpos = llen = 0;
-  buf[0] = '\0';
-
-  {
-    grub_term_output_t term;
-
-    FOR_ACTIVE_TERM_OUTPUTS(term)
-      if ((grub_term_getxy (term) >> 8) != 0)
-       grub_putcode ('\n', term);
-  }
-  grub_printf ("%s ", prompt_translated);
-
-  {
-    struct cmdline_term *cl_term_cur;
-    struct grub_term_output *cur;
-    nterms = 0;
-    FOR_ACTIVE_TERM_OUTPUTS(cur)
-      nterms++;
-
-    cl_terms = grub_malloc (sizeof (cl_terms[0]) * nterms);
-    if (!cl_terms)
-      return 0;
-    cl_term_cur = cl_terms;
-    FOR_ACTIVE_TERM_OUTPUTS(cur)
-    {
-      cl_term_cur->term = cur;
-      init_clterm (cl_term_cur);
-      cl_term_cur++;
-    }
-  }
-
-  if (hist_used == 0)
-    grub_history_add (buf, llen);
-
-  grub_refresh ();
-
-  while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r')
-    {
-      switch (key)
-       {
-       case 1: /* Ctrl-a */
-         lpos = 0;
-         cl_set_pos_all ();
-         break;
-
-       case 2: /* Ctrl-b */
-         if (lpos > 0)
-           {
-             lpos--;
-             cl_set_pos_all ();
-           }
-         break;
-
-       case 5: /* Ctrl-e */
-         lpos = llen;
-         cl_set_pos_all ();
-         break;
-
-       case 6: /* Ctrl-f */
-         if (lpos < llen)
-           {
-             lpos++;
-             cl_set_pos_all ();
-           }
-         break;
-
-       case 9: /* Ctrl-i or TAB */
-         {
-           int restore;
-           char *insertu8;
-           char *bufu8;
-           grub_uint32_t c;
-
-           c = buf[lpos];
-           buf[lpos] = '\0';
-
-           bufu8 = grub_ucs4_to_utf8_alloc (buf, lpos);
-           buf[lpos] = c;
-           if (!bufu8)
-             {
-               grub_print_error ();
-               grub_errno = GRUB_ERR_NONE;
-               break;
-             }
-
-           insertu8 = grub_normal_do_completion (bufu8, &restore,
-                                                 print_completion);
-           grub_free (bufu8);
-
-           if (restore)
-             {
-               /* Restore the prompt.  */
-               grub_printf ("\n%s ", prompt_translated);
-               init_clterm_all ();
-               cl_print_all (0, 0);
-             }
-
-           if (insertu8)
-             {
-               grub_size_t insertlen;
-               grub_ssize_t t;
-               grub_uint32_t *insert;
-
-               insertlen = grub_strlen (insertu8);
-               insert = grub_malloc ((insertlen + 1) * sizeof (grub_uint32_t));
-               if (!insert)
-                 {
-                   grub_free (insertu8);
-                   grub_print_error ();
-                   grub_errno = GRUB_ERR_NONE;
-                   break;
-                 }
-               t = grub_utf8_to_ucs4 (insert, insertlen,
-                                      (grub_uint8_t *) insertu8,
-                                      insertlen, 0);
-               if (t > 0)
-                 {
-                   if (insert[t-1] == ' ' && buf[lpos] == ' ')
-                     {
-                       insert[t-1] = 0;
-                       if (t != 1)
-                         cl_insert (insert);
-                       lpos++;
-                     }
-                   else
-                     {
-                       insert[t] = 0;
-                       cl_insert (insert);
-                     }
-                 }
-
-               grub_free (insertu8);
-               grub_free (insert);
-             }
-           cl_set_pos_all ();
-         }
-         break;
-
-       case 11:        /* Ctrl-k */
-         if (lpos < llen)
-           {
-             if (kill_buf)
-               grub_free (kill_buf);
-
-             kill_buf = grub_malloc ((llen - lpos + 1)
-                                     * sizeof (grub_uint32_t));
-             if (grub_errno)
-               {
-                 grub_print_error ();
-                 grub_errno = GRUB_ERR_NONE;
-               }
-             else
-               {
-                 grub_memcpy (kill_buf, buf + lpos,
-                              (llen - lpos + 1) * sizeof (grub_uint32_t));
-                 kill_buf[llen - lpos] = 0;
-               }
-
-             cl_delete (llen - lpos);
-           }
-         break;
-
-       case 14:        /* Ctrl-n */
-         {
-           grub_uint32_t *hist;
-
-           lpos = 0;
-
-           if (histpos > 0)
-             {
-               grub_history_replace (histpos, buf, llen);
-               histpos--;
-             }
-
-           cl_delete (llen);
-           hist = grub_history_get (histpos);
-           cl_insert (hist);
-
-           break;
-         }
-       case 16:        /* Ctrl-p */
-         {
-           grub_uint32_t *hist;
-
-           lpos = 0;
-
-           if (histpos < hist_used - 1)
-             {
-               grub_history_replace (histpos, buf, llen);
-               histpos++;
-             }
-
-           cl_delete (llen);
-           hist = grub_history_get (histpos);
-
-           cl_insert (hist);
-         }
-         break;
-
-       case 21:        /* Ctrl-u */
-         if (lpos > 0)
-           {
-             grub_size_t n = lpos;
-
-             if (kill_buf)
-               grub_free (kill_buf);
-
-             kill_buf = grub_malloc (n + 1);
-             if (grub_errno)
-               {
-                 grub_print_error ();
-                 grub_errno = GRUB_ERR_NONE;
-               }
-             if (kill_buf)
-               {
-                 grub_memcpy (kill_buf, buf, n);
-                 kill_buf[n] = '\0';
-               }
-
-             lpos = 0;
-             cl_set_pos_all ();
-             cl_delete (n);
-           }
-         break;
-
-       case 25:        /* Ctrl-y */
-         if (kill_buf)
-           cl_insert (kill_buf);
-         break;
-
-       case '\e':
-         return 0;
-
-       case '\b':
-         if (lpos > 0)
-           {
-             lpos--;
-             cl_set_pos_all ();
-           }
-          else
-            break;
-         /* fall through */
-
-       case 4: /* Ctrl-d */
-         if (lpos < llen)
-           cl_delete (1);
-         break;
-
-       default:
-         if (grub_isprint (key))
-           {
-             grub_uint32_t str[2];
-
-             str[0] = key;
-             str[1] = '\0';
-             cl_insert (str);
-           }
-         break;
-       }
-
-      grub_refresh ();
-    }
-
-  grub_putchar ('\n');
-  grub_refresh ();
-
-  /* Remove leading spaces.  */
-  lpos = 0;
-  while (buf[lpos] == ' ')
-    lpos++;
-
-  histpos = 0;
-  if (strlen_ucs4 (buf) > 0)
-    {
-      grub_uint32_t empty[] = { 0 };
-      grub_history_replace (histpos, buf, llen);
-      grub_history_add (empty, 0);
-    }
-
-  ret = grub_ucs4_to_utf8_alloc (buf + lpos, llen - lpos + 1);
-  grub_free (buf);
-  return ret;
-}
diff --git a/normal/color.c b/normal/color.c
deleted file mode 100644 (file)
index bae0829..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/normal.h>
-#include <grub/term.h>
-#include <grub/i18n.h>
-
-/* Borrowed from GRUB Legacy */
-static char *color_list[16] =
-{
-  "black",
-  "blue",
-  "green",
-  "cyan",
-  "red",
-  "magenta",
-  "brown",
-  "light-gray",
-  "dark-gray",
-  "light-blue",
-  "light-green",
-  "light-cyan",
-  "light-red",
-  "light-magenta",
-  "yellow",
-  "white"
-};
-
-static int
-parse_color_name (grub_uint8_t *ret, char *name)
-{
-  grub_uint8_t i;
-  for (i = 0; i < sizeof (color_list) / sizeof (*color_list); i++)
-    if (! grub_strcmp (name, color_list[i]))
-      {
-        *ret = i;
-        return 0;
-      }
-  return -1;
-}
-
-void
-grub_parse_color_name_pair (grub_uint8_t *ret, const char *name)
-{
-  grub_uint8_t fg, bg;
-  char *fg_name, *bg_name;
-
-  /* nothing specified by user */
-  if (name == NULL)
-    return;
-
-  fg_name = grub_strdup (name);
-  if (fg_name == NULL)
-    {
-      /* "out of memory" message was printed by grub_strdup() */
-      grub_wait_after_message ();
-      return;
-    }
-
-  bg_name = grub_strchr (fg_name, '/');
-  if (bg_name == NULL)
-    {
-      grub_printf_ (N_("Warning: syntax error (missing slash) in `%s'\n"), fg_name);
-      grub_wait_after_message ();
-      goto free_and_return;
-    }
-
-  *(bg_name++) = '\0';
-
-  if (parse_color_name (&fg, fg_name) == -1)
-    {
-      grub_printf_ (N_("Warning: invalid foreground color `%s'\n"), fg_name);
-      grub_wait_after_message ();
-      goto free_and_return;
-    }
-  if (parse_color_name (&bg, bg_name) == -1)
-    {
-      grub_printf_ (N_("Warning: invalid background color `%s'\n"), bg_name);
-      grub_wait_after_message ();
-      goto free_and_return;
-    }
-
-  *ret = (bg << 4) | fg;
-
-free_and_return:
-  grub_free (fg_name);
-}
-
-static grub_uint8_t color_normal, color_highlight;
-
-static void
-set_colors (void)
-{
-  struct grub_term_output *term;
-
-  FOR_ACTIVE_TERM_OUTPUTS(term)
-  {
-    /* Reloads terminal `normal' and `highlight' colors.  */
-    grub_term_setcolor (term, color_normal, color_highlight);
-
-    /* Propagates `normal' color to terminal current color.  */
-    grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
-  }
-}
-
-/* Replace default `normal' colors with the ones specified by user (if any).  */
-char *
-grub_env_write_color_normal (struct grub_env_var *var __attribute__ ((unused)),
-                            const char *val)
-{
-  grub_parse_color_name_pair (&color_normal, val);
-
-  set_colors ();
-
-  return grub_strdup (val);
-}
-
-/* Replace default `highlight' colors with the ones specified by user (if any).  */
-char *
-grub_env_write_color_highlight (struct grub_env_var *var __attribute__ ((unused)),
-                               const char *val)
-{
-  grub_parse_color_name_pair (&color_highlight, val);
-
-  set_colors ();
-
-  return grub_strdup (val);
-}
diff --git a/normal/completion.c b/normal/completion.c
deleted file mode 100644 (file)
index 13e8f7a..0000000
+++ /dev/null
@@ -1,504 +0,0 @@
-/* completion.c - complete a command, a disk, a partition or a file */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/normal.h>
-#include <grub/misc.h>
-#include <grub/err.h>
-#include <grub/mm.h>
-#include <grub/partition.h>
-#include <grub/disk.h>
-#include <grub/file.h>
-#include <grub/parser.h>
-#include <grub/extcmd.h>
-
-/* The current word.  */
-static char *current_word;
-
-/* The matched string.  */
-static char *match;
-
-/* The count of candidates.  */
-static int num_found;
-
-/* The string to be appended.  */
-static const char *suffix;
-
-/* The callback function to print items.  */
-static void (*print_func) (const char *, grub_completion_type_t, int);
-
-/* The state the command line is in.  */
-static grub_parser_state_t cmdline_state;
-\f
-
-/* Add a string to the list of possible completions. COMPLETION is the
-   string that should be added. EXTRA will be appended if COMPLETION
-   matches uniquely. The type TYPE specifies what kind of data is added.  */
-static int
-add_completion (const char *completion, const char *extra,
-               grub_completion_type_t type)
-{
-  if (grub_strncmp (current_word, completion, grub_strlen (current_word)) == 0)
-    {
-      num_found++;
-
-      switch (num_found)
-       {
-       case 1:
-         match = grub_strdup (completion);
-         if (! match)
-           return 1;
-         suffix = extra;
-         break;
-
-       case 2:
-         if (print_func)
-           print_func (match, type, 0);
-
-         /* Fall through.  */
-
-       default:
-         {
-           char *s = match;
-           const char *t = completion;
-
-           if (print_func)
-             print_func (completion, type, num_found - 1);
-
-           /* Detect the matched portion.  */
-           while (*s && *t && *s == *t)
-             {
-               s++;
-               t++;
-             }
-
-           *s = '\0';
-         }
-         break;
-       }
-    }
-
-  return 0;
-}
-
-static int
-iterate_partition (grub_disk_t disk, const grub_partition_t p)
-{
-  const char *disk_name = disk->name;
-  char *partition_name = grub_partition_get_name (p);
-  char *name;
-  int ret;
-
-  if (! partition_name)
-    return 1;
-
-  name = grub_xasprintf ("%s,%s", disk_name, partition_name);
-  grub_free (partition_name);
-
-  if (! name)
-    return 1;
-
-  ret = add_completion (name, ")", GRUB_COMPLETION_TYPE_PARTITION);
-  grub_free (name);
-  return ret;
-}
-
-static int
-iterate_dir (const char *filename, const struct grub_dirhook_info *info)
-{
-  if (! info->dir)
-    {
-      const char *prefix;
-      if (cmdline_state == GRUB_PARSER_STATE_DQUOTE)
-       prefix = "\" ";
-      else if (cmdline_state == GRUB_PARSER_STATE_QUOTE)
-       prefix = "\' ";
-      else
-       prefix = " ";
-
-      if (add_completion (filename, prefix, GRUB_COMPLETION_TYPE_FILE))
-       return 1;
-    }
-  else if (grub_strcmp (filename, ".") && grub_strcmp (filename, ".."))
-    {
-      char *fname;
-
-      fname = grub_xasprintf ("%s/", filename);
-      if (add_completion (fname, "", GRUB_COMPLETION_TYPE_FILE))
-       {
-         grub_free (fname);
-         return 1;
-       }
-      grub_free (fname);
-    }
-
-  return 0;
-}
-
-static int
-iterate_dev (const char *devname)
-{
-  grub_device_t dev;
-
-  /* Complete the partition part.  */
-  dev = grub_device_open (devname);
-
-  if (dev)
-    {
-      if (dev->disk && dev->disk->has_partitions)
-       {
-         if (add_completion (devname, ",", GRUB_COMPLETION_TYPE_DEVICE))
-           return 1;
-       }
-      else
-       {
-         if (add_completion (devname, ")", GRUB_COMPLETION_TYPE_DEVICE))
-           return 1;
-       }
-    }
-
-  grub_errno = GRUB_ERR_NONE;
-  return 0;
-}
-
-static int
-iterate_command (grub_command_t cmd)
-{
-  if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE)
-    {
-      if (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE)
-       {
-         if (add_completion (cmd->name, " ", GRUB_COMPLETION_TYPE_COMMAND))
-           return 1;
-       }
-    }
-
-  return 0;
-}
-
-/* Complete a device.  */
-static int
-complete_device (void)
-{
-  /* Check if this is a device or a partition.  */
-  char *p = grub_strchr (++current_word, ',');
-  grub_device_t dev;
-
-  if (! p)
-    {
-      /* Complete the disk part.  */
-      if (grub_disk_dev_iterate (iterate_dev))
-       return 1;
-    }
-  else
-    {
-      /* Complete the partition part.  */
-      *p = '\0';
-      dev = grub_device_open (current_word);
-      *p = ',';
-      grub_errno = GRUB_ERR_NONE;
-
-      if (dev)
-       {
-         if (dev->disk && dev->disk->has_partitions)
-           {
-             if (grub_partition_iterate (dev->disk, iterate_partition))
-               {
-                 grub_device_close (dev);
-                 return 1;
-               }
-           }
-
-         grub_device_close (dev);
-       }
-      else
-       return 1;
-    }
-
-  return 0;
-}
-
-/* Complete a file.  */
-static int
-complete_file (void)
-{
-  char *device;
-  char *dir;
-  char *last_dir;
-  grub_fs_t fs;
-  grub_device_t dev;
-  int ret = 0;
-
-  device = grub_file_get_device_name (current_word);
-  if (grub_errno != GRUB_ERR_NONE)
-    return 1;
-
-  dev = grub_device_open (device);
-  if (! dev)
-    {
-      ret = 1;
-      goto fail;
-    }
-
-  fs = grub_fs_probe (dev);
-  if (! fs)
-    {
-      ret = 1;
-      goto fail;
-    }
-
-  dir = grub_strchr (current_word, '/');
-  last_dir = grub_strrchr (current_word, '/');
-  if (dir)
-    {
-      char *dirfile;
-
-      current_word = last_dir + 1;
-
-      dir = grub_strdup (dir);
-      if (! dir)
-       {
-         ret = 1;
-         goto fail;
-       }
-
-      /* Cut away the filename part.  */
-      dirfile = grub_strrchr (dir, '/');
-      dirfile[1] = '\0';
-
-      /* Iterate the directory.  */
-      (fs->dir) (dev, dir, iterate_dir);
-
-      grub_free (dir);
-
-      if (grub_errno)
-       {
-         ret = 1;
-         goto fail;
-       }
-    }
-  else
-    {
-      current_word += grub_strlen (current_word);
-      match = grub_strdup ("/");
-      if (! match)
-       {
-         ret = 1;
-         goto fail;
-       }
-
-      suffix = "";
-      num_found = 1;
-    }
-
- fail:
-  if (dev)
-    grub_device_close (dev);
-  grub_free (device);
-  return ret;
-}
-
-/* Complete an argument.  */
-static int
-complete_arguments (char *command)
-{
-  grub_command_t cmd;
-  grub_extcmd_t ext;
-  const struct grub_arg_option *option;
-  char shortarg[] = "- ";
-
-  cmd = grub_command_find (command);
-
-  if (!cmd || !(cmd->flags & GRUB_COMMAND_FLAG_EXTCMD))
-    return 0;
-
-  ext = cmd->data;
-  if (!ext->options)
-    return 0;
-
-  if (add_completion ("-u", " ", GRUB_COMPLETION_TYPE_ARGUMENT))
-    return 1;
-
-  /* Add the short arguments.  */
-  for (option = ext->options; option->doc; option++)
-    {
-      if (! option->shortarg)
-       continue;
-
-      shortarg[1] = option->shortarg;
-      if (add_completion (shortarg, " ", GRUB_COMPLETION_TYPE_ARGUMENT))
-       return 1;
-
-    }
-
-  /* First add the built-in arguments.  */
-  if (add_completion ("--help", " ", GRUB_COMPLETION_TYPE_ARGUMENT))
-    return 1;
-  if (add_completion ("--usage", " ", GRUB_COMPLETION_TYPE_ARGUMENT))
-    return 1;
-
-  /* Add the long arguments.  */
-  for (option = ext->options; option->doc; option++)
-    {
-      char *longarg;
-      if (!option->longarg)
-       continue;
-
-      longarg = grub_xasprintf ("--%s", option->longarg);
-      if (!longarg)
-       return 1;
-
-      if (add_completion (longarg, " ", GRUB_COMPLETION_TYPE_ARGUMENT))
-       {
-         grub_free (longarg);
-         return 1;
-       }
-      grub_free (longarg);
-    }
-
-  return 0;
-}
-
-
-static grub_parser_state_t
-get_state (const char *cmdline)
-{
-  grub_parser_state_t state = GRUB_PARSER_STATE_TEXT;
-  char use;
-
-  while (*cmdline)
-    state = grub_parser_cmdline_state (state, *(cmdline++), &use);
-  return state;
-}
-
-
-/* Try to complete the string in BUF. Return the characters that
-   should be added to the string.  This command outputs the possible
-   completions by calling HOOK, in that case set RESTORE to 1 so the
-   caller can restore the prompt.  */
-char *
-grub_normal_do_completion (char *buf, int *restore,
-                          void (*hook) (const char *, grub_completion_type_t, int))
-{
-  int argc;
-  char **argv;
-
-  /* Initialize variables.  */
-  match = 0;
-  num_found = 0;
-  suffix = "";
-  print_func = hook;
-
-  *restore = 1;
-
-  if (grub_parser_split_cmdline (buf, 0, &argc, &argv))
-    return 0;
-
-  if (argc == 0)
-    current_word = "";
-  else
-    current_word = argv[argc - 1];
-
-  /* Determine the state the command line is in, depending on the
-     state, it can be determined how to complete.  */
-  cmdline_state = get_state (buf);
-
-  if (argc == 1 || argc == 0)
-    {
-      /* Complete a command.  */
-      if (grub_command_iterate (iterate_command))
-       goto fail;
-    }
-  else if (*current_word == '-')
-    {
-      if (complete_arguments (buf))
-       goto fail;
-    }
-  else if (*current_word == '(' && ! grub_strchr (current_word, ')'))
-    {
-      /* Complete a device.  */
-      if (complete_device ())
-           goto fail;
-    }
-  else
-    {
-      /* Complete a file.  */
-      if (complete_file ())
-       goto fail;
-    }
-
-  /* If more than one match is found those matches will be printed and
-     the prompt should be restored.  */
-  if (num_found > 1)
-    *restore = 1;
-  else
-    *restore = 0;
-
-  /* Return the part that matches.  */
-  if (match)
-    {
-      char *ret;
-      char *escstr;
-      char *newstr;
-      int current_len;
-      int match_len;
-      int spaces = 0;
-
-      current_len = grub_strlen (current_word);
-      match_len = grub_strlen (match);
-
-      /* Count the number of spaces that have to be escaped.  XXX:
-        More than just spaces have to be escaped.  */
-      for (escstr = match + current_len; *escstr; escstr++)
-       if (*escstr == ' ')
-         spaces++;
-
-      ret = grub_malloc (match_len - current_len + grub_strlen (suffix) + spaces + 1);
-      newstr = ret;
-      for (escstr = match + current_len; *escstr; escstr++)
-       {
-         if (*escstr == ' ' && cmdline_state != GRUB_PARSER_STATE_QUOTE
-             && cmdline_state != GRUB_PARSER_STATE_QUOTE)
-           *(newstr++) = '\\';
-         *(newstr++) = *escstr;
-       }
-      *newstr = '\0';
-
-      if (num_found == 1)
-       grub_strcat (ret, suffix);
-
-      if (*ret == '\0')
-       {
-         grub_free (ret);
-          goto fail;
-       }
-
-      if (argc != 0)
-       grub_free (argv[0]);
-      grub_free (match);
-      return ret;
-    }
-
- fail:
-  if (argc != 0)
-    grub_free (argv[0]);
-  grub_free (match);
-  grub_errno = GRUB_ERR_NONE;
-
-  return 0;
-}
diff --git a/normal/context.c b/normal/context.c
deleted file mode 100644 (file)
index 27adf28..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/* env.c - Environment variables */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/env.h>
-#include <grub/env_private.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/command.h>
-#include <grub/normal.h>
-#include <grub/i18n.h>
-
-struct menu_pointer
-{
-  grub_menu_t menu;
-  struct menu_pointer *prev;
-};
-
-struct menu_pointer initial_menu;
-struct menu_pointer *current_menu = &initial_menu;
-
-void
-grub_env_unset_menu (void)
-{
-  current_menu->menu = NULL;
-}
-
-grub_menu_t
-grub_env_get_menu (void)
-{
-  return current_menu->menu;
-}
-
-void
-grub_env_set_menu (grub_menu_t nmenu)
-{
-  current_menu->menu = nmenu;
-}
-
-grub_err_t
-grub_env_context_open (int export)
-{
-  struct grub_env_context *context;
-  int i;
-  struct menu_pointer *menu;
-
-  context = grub_zalloc (sizeof (*context));
-  if (! context)
-    return grub_errno;
-  menu = grub_zalloc (sizeof (*menu));
-  if (! menu)
-    return grub_errno;
-
-  context->prev = grub_current_context;
-  grub_current_context = context;
-
-  menu->prev = current_menu;
-  current_menu = menu;
-
-  /* Copy exported variables.  */
-  for (i = 0; i < HASHSZ; i++)
-    {
-      struct grub_env_var *var;
-
-      for (var = context->prev->vars[i]; var; var = var->next)
-       {
-         if (export && var->global)
-           {
-             if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE)
-               {
-                 grub_env_context_close ();
-                 return grub_errno;
-               }
-             grub_env_export (var->name);
-             grub_register_variable_hook (var->name, var->read_hook, var->write_hook);
-           }
-       }
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_env_context_close (void)
-{
-  struct grub_env_context *context;
-  int i;
-  struct menu_pointer *menu;
-
-  if (! grub_current_context->prev)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "cannot close the initial context");
-
-  /* Free the variables associated with this context.  */
-  for (i = 0; i < HASHSZ; i++)
-    {
-      struct grub_env_var *p, *q;
-
-      for (p = grub_current_context->vars[i]; p; p = q)
-       {
-         q = p->next;
-          grub_free (p->name);
-         grub_free (p->value);
-         grub_free (p);
-       }
-    }
-
-  /* Restore the previous context.  */
-  context = grub_current_context->prev;
-  grub_free (grub_current_context);
-  grub_current_context = context;
-
-  menu = current_menu->prev;
-  grub_free (current_menu);
-  current_menu = menu;
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_env_export (const char *name)
-{
-  struct grub_env_var *var;
-
-  var = grub_env_find (name);
-  if (! var)
-    {
-      grub_err_t err;
-      
-      err = grub_env_set (name, "");
-      if (err)
-       return err;
-      var = grub_env_find (name);
-    }    
-  var->global = 1;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_command_t export_cmd;
-
-static grub_err_t
-grub_cmd_export (struct grub_command *cmd __attribute__ ((unused)),
-                int argc, char **args)
-{
-  if (argc < 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "no environment variable specified");
-
-  grub_env_export (args[0]);
-  return 0;
-}
-
-void
-grub_context_init (void)
-{
-  grub_env_export ("root");
-  grub_env_export ("prefix");
-
-  export_cmd = grub_register_command ("export", grub_cmd_export,
-                                     N_("ENVVAR"), N_("Export a variable."));
-}
-
-void
-grub_context_fini (void)
-{
-  grub_unregister_command (export_cmd);
-}
diff --git a/normal/crypto.c b/normal/crypto.c
deleted file mode 100644 (file)
index 465c9f8..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/* crypto.c - support crypto autoload */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/env.h>
-#include <grub/misc.h>
-#include <grub/crypto.h>
-#include <grub/normal.h>
-
-struct load_spec
-{
-  struct load_spec *next;
-  char *name;
-  char *modname;
-};
-
-struct load_spec *crypto_specs = NULL;
-
-static void 
-grub_crypto_autoload (const char *name)
-{
-  struct load_spec *cur;
-  grub_dl_t mod;
-  
-  for (cur = crypto_specs; cur; cur = cur->next)
-    if (grub_strcasecmp (name, cur->name) == 0)
-      {
-       mod = grub_dl_load (cur->modname);
-       if (mod)
-         grub_dl_ref (mod);
-       grub_errno = GRUB_ERR_NONE;
-      }
-}
-
-static void 
-grub_crypto_spec_free (void)
-{
-  struct load_spec *cur, *next;
-  for (cur = crypto_specs; cur; cur = next)
-    {
-      next = cur->next;
-      grub_free (cur->name);
-      grub_free (cur->modname);
-      grub_free (cur);
-    }
-  crypto_specs = NULL;
-}
-
-
-/* Read the file crypto.lst for auto-loading.  */
-void
-read_crypto_list (const char *prefix)
-{
-  char *filename;
-  grub_file_t file;
-  char *buf = NULL;
-
-  if (!prefix)
-    {
-      grub_errno = GRUB_ERR_NONE;
-      return;
-    }
-  
-  filename = grub_xasprintf ("%s/crypto.lst", prefix);
-  if (!filename)
-    {
-      grub_errno = GRUB_ERR_NONE;
-      return;
-    }
-
-  file = grub_file_open (filename);
-  grub_free (filename);
-  if (!file)
-    {
-      grub_errno = GRUB_ERR_NONE;
-      return;
-    }
-
-  /* Override previous crypto.lst.  */
-  grub_crypto_spec_free ();
-
-  for (;; grub_free (buf))
-    {
-      char *p, *name;
-      struct load_spec *cur;
-      
-      buf = grub_file_getline (file);
-       
-      if (! buf)
-       break;
-      
-      name = buf;
-            
-      p = grub_strchr (name, ':');
-      if (! p)
-       continue;
-      
-      *p = '\0';
-      while (*++p == ' ')
-       ;
-
-      cur = grub_malloc (sizeof (*cur));
-      if (!cur)
-       {
-         grub_errno = GRUB_ERR_NONE;
-         continue;
-       }
-      
-      cur->name = grub_strdup (name);
-      if (! name)
-       {
-         grub_errno = GRUB_ERR_NONE;
-         grub_free (cur);
-         continue;
-       }
-       
-      cur->modname = grub_strdup (p);
-      if (! cur->modname)
-       {
-         grub_errno = GRUB_ERR_NONE;
-         grub_free (cur);
-         grub_free (cur->name);
-         continue;
-       }
-      cur->next = crypto_specs;
-      crypto_specs = cur;
-    }
-  
-  grub_file_close (file);
-
-  grub_errno = GRUB_ERR_NONE;
-
-  grub_crypto_autoload_hook = grub_crypto_autoload;
-}
diff --git a/normal/datetime.c b/normal/datetime.c
deleted file mode 100644 (file)
index 44791e1..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/* datetime.c - Module for common datetime function.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/datetime.h>
-
-static char *grub_weekday_names[] =
-{
-  "Sunday",
-  "Monday",
-  "Tuesday",
-  "Wednesday",
-  "Thursday",
-  "Friday",
-  "Saturday",
-};
-
-int
-grub_get_weekday (struct grub_datetime *datetime)
-{
-  int a, y, m;
-
-  a = (14 - datetime->month) / 12;
-  y = datetime->year - a;
-  m = datetime->month + 12 * a - 2;
-
-  return (datetime->day + y + y / 4 - y / 100 + y / 400 + (31 * m / 12)) % 7;
-}
-
-char *
-grub_get_weekday_name (struct grub_datetime *datetime)
-{
-  return grub_weekday_names[grub_get_weekday (datetime)];
-}
-
-#define SECPERMIN 60
-#define SECPERHOUR (60*SECPERMIN)
-#define SECPERDAY (24*SECPERHOUR)
-#define SECPERYEAR (365*SECPERDAY)
-#define SECPER4YEARS (4*SECPERYEAR+SECPERDAY)
-
-
-void
-grub_unixtime2datetime (grub_int32_t nix, struct grub_datetime *datetime)
-{
-  int i;
-  int div;
-  grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-  /* In the period of validity of unixtime all years divisible by 4
-     are bissextile*/
-  /* Convenience: let's have 3 consecutive non-bissextile years
-     at the beginning of the epoch. So count from 1973 instead of 1970 */
-  nix -= 3*SECPERYEAR + SECPERDAY;
-  /* Transform C divisions and modulos to mathematical ones */
-  div = nix / SECPER4YEARS;
-  if (nix < 0)
-    div--;
-  datetime->year = 1973 + 4 * div;
-  nix -= div * SECPER4YEARS;
-
-  /* On 31st December of bissextile years 365 days from the beginning
-     of the year elapsed but year isn't finished yet */
-  if (nix / SECPERYEAR == 4)
-    {
-      datetime->year += 3;
-      nix -= 3*SECPERYEAR;
-    }
-  else
-    {
-      datetime->year += nix / SECPERYEAR;
-      nix %= SECPERYEAR;
-    }
-  for (i = 0; i < 12
-        && nix >= ((grub_int32_t) (i==1 && datetime->year % 4 == 0
-                                   ? 29 : months[i]))*SECPERDAY; i++)
-    nix -= ((grub_int32_t) (i==1 && datetime->year % 4 == 0
-                           ? 29 : months[i]))*SECPERDAY;
-  datetime->month = i + 1;
-  datetime->day = 1 + (nix / SECPERDAY);
-  nix %= SECPERDAY;
-  datetime->hour = (nix / SECPERHOUR);
-  nix %= SECPERHOUR;
-  datetime->minute = nix / SECPERMIN;
-  datetime->second = nix % SECPERMIN;
-}
diff --git a/normal/dyncmd.c b/normal/dyncmd.c
deleted file mode 100644 (file)
index a3cafa5..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/* dyncmd.c - support dynamic command */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/env.h>
-#include <grub/misc.h>
-#include <grub/command.h>
-#include <grub/normal.h>
-#include <grub/i18n.h>
-
-static grub_err_t
-grub_dyncmd_dispatcher (struct grub_command *cmd,
-                       int argc, char **args)
-{
-  char *modname = cmd->data;
-  grub_dl_t mod;
-  grub_err_t ret;
-
-  mod = grub_dl_load (modname);
-  if (mod)
-    {
-      char *name;
-
-      grub_free (modname);
-      grub_dl_ref (mod);
-
-      name = (char *) cmd->name;
-      grub_unregister_command (cmd);
-
-      cmd = grub_command_find (name);
-      if (cmd)
-       ret = (cmd->func) (cmd, argc, args);
-      else
-       ret = grub_errno;
-
-      grub_free (name);
-    }
-  else
-    ret = grub_errno;
-
-  return ret;
-}
-
-/* Read the file command.lst for auto-loading.  */
-void
-read_command_list (const char *prefix)
-{
-  if (prefix)
-    {
-      char *filename;
-
-      filename = grub_xasprintf ("%s/command.lst", prefix);
-      if (filename)
-       {
-         grub_file_t file;
-
-         file = grub_file_open (filename);
-         if (file)
-           {
-             char *buf = NULL;
-             grub_command_t ptr, last = 0, next;
-
-             /* Override previous commands.lst.  */
-             for (ptr = grub_command_list; ptr; ptr = next)
-               {
-                 next = ptr->next;
-                 if (ptr->func == grub_dyncmd_dispatcher)
-                   {
-                     if (last)
-                       last->next = ptr->next;
-                     else
-                       grub_command_list = ptr->next;
-                     grub_free (ptr);
-                   }
-                 else
-                   last = ptr;
-               }
-
-             for (;; grub_free (buf))
-               {
-                 char *p, *name, *modname;
-                 grub_command_t cmd;
-                 int prio = 0;
-
-                 buf = grub_file_getline (file);
-
-                 if (! buf)
-                   break;
-
-                 name = buf;
-                 if (*name == '*')
-                   {
-                     name++;
-                     prio++;
-                   }
-
-                 if (! grub_isgraph (name[0]))
-                   continue;
-
-                 p = grub_strchr (name, ':');
-                 if (! p)
-                   continue;
-
-                 *p = '\0';
-                 while (*++p == ' ')
-                   ;
-
-                 if (! grub_isgraph (*p))
-                   continue;
-
-                 if (grub_dl_get (p))
-                   continue;
-
-                 name = grub_strdup (name);
-                 if (! name)
-                   continue;
-
-                 modname = grub_strdup (p);
-                 if (! modname)
-                   {
-                     grub_free (name);
-                     continue;
-                   }
-
-                 cmd = grub_register_command_prio (name,
-                                                   grub_dyncmd_dispatcher,
-                                                   0, N_("not loaded"), prio);
-                 if (! cmd)
-                   {
-                     grub_free (name);
-                     grub_free (modname);
-                     continue;
-                   }
-                 cmd->flags |= GRUB_COMMAND_FLAG_DYNCMD;
-                 cmd->data = modname;
-
-                 /* Update the active flag.  */
-                 grub_command_find (name);
-               }
-
-             grub_file_close (file);
-           }
-
-         grub_free (filename);
-       }
-    }
-
-  /* Ignore errors.  */
-  grub_errno = GRUB_ERR_NONE;
-}
diff --git a/normal/handler.c b/normal/handler.c
deleted file mode 100644 (file)
index 6866269..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/* handler.c - support handler loading */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/env.h>
-#include <grub/misc.h>
-#include <grub/command.h>
-#include <grub/handler.h>
-#include <grub/normal.h>
-
-struct grub_handler_list
-{
-  struct grub_handler_list *next;
-  char *name;
-  grub_command_t cmd;
-};
-
-static grub_list_t handler_list;
-
-static grub_err_t
-grub_handler_cmd (struct grub_command *cmd,
-                 int argc __attribute__ ((unused)),
-                 char **args __attribute__ ((unused)))
-{
-  char *p;
-  grub_handler_class_t class;
-  grub_handler_t handler;
-
-  p = grub_strchr (cmd->name, '.');
-  if (! p)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid command name");
-
-  if (cmd->data)
-    {
-      if (! grub_dl_get (cmd->data))
-       {
-         grub_dl_t mod;
-
-         mod = grub_dl_load (cmd->data);
-         if (mod)
-           grub_dl_ref (mod);
-         else
-           return grub_errno;
-       }
-      grub_free (cmd->data);
-      cmd->data = 0;
-    }
-
-  *p = 0;
-  class = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_handler_class_list),
-                               cmd->name);
-  *p = '.';
-
-  if (! class)
-    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found");
-
-
-  handler = grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list),
-                                 p + 1);
-  if (! handler)
-    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found");
-
-  grub_handler_set_current (class, handler);
-
-  return 0;
-}
-
-static void
-insert_handler (char *name, char *module)
-{
-  struct grub_handler_list *item;
-  char *data;
-
-  if (grub_command_find (name))
-    return;
-
-  item = grub_malloc (sizeof (*item));
-  if (! item)
-    return;
-
-  item->name = grub_strdup (name);
-  if (! item->name)
-    {
-      grub_free (item);
-      return;
-    }
-
-  if (module)
-    {
-      data = grub_strdup (module);
-      if (! data)
-       {
-         grub_free (item->name);
-         grub_free (item);
-         return;
-       }
-    }
-  else
-    data = 0;
-
-  item->cmd = grub_register_command (item->name, grub_handler_cmd, 0,
-                                    "Set active handler.");
-  if (! item->cmd)
-    {
-      grub_free (data);
-      grub_free (item->name);
-      grub_free (item);
-      return;
-    }
-
-  item->cmd->data = data;
-  grub_list_push (&handler_list, GRUB_AS_LIST (item));
-}
-
-/* Read the file handler.lst for auto-loading.  */
-void
-read_handler_list (void)
-{
-  const char *prefix;
-  static int first_time = 1;
-  const char *class_name;
-
-  auto int iterate_handler (grub_handler_t handler);
-  int iterate_handler (grub_handler_t handler)
-    {
-      char name[grub_strlen (class_name) + grub_strlen (handler->name) + 2];
-
-      grub_strcpy (name, class_name);
-      grub_strcat (name, ".");
-      grub_strcat (name, handler->name);
-
-      insert_handler (name, 0);
-
-      return 0;
-    }
-
-  auto int iterate_class (grub_handler_class_t class);
-  int iterate_class (grub_handler_class_t class)
-    {
-      class_name = class->name;
-      grub_list_iterate (GRUB_AS_LIST (class->handler_list),
-                        (grub_list_hook_t) iterate_handler);
-
-      return 0;
-    }
-
-  /* Make sure that this function does not get executed twice.  */
-  if (! first_time)
-    return;
-  first_time = 0;
-
-  prefix = grub_env_get ("prefix");
-  if (prefix)
-    {
-      char *filename;
-
-      filename = grub_xasprintf ("%s/handler.lst", prefix);
-      if (filename)
-       {
-         grub_file_t file;
-
-         file = grub_file_open (filename);
-         if (file)
-           {
-             char *buf = NULL;
-             for (;; grub_free (buf))
-               {
-                 char *p;
-
-                 buf = grub_file_getline (file);
-
-                 if (! buf)
-                   break;
-
-                 if (! grub_isgraph (buf[0]))
-                   continue;
-
-                 p = grub_strchr (buf, ':');
-                 if (! p)
-                   continue;
-
-                 *p = '\0';
-                 while (*++p == ' ')
-                   ;
-
-                 insert_handler (buf, p);
-               }
-             grub_file_close (file);
-           }
-         grub_free (filename);
-       }
-    }
-
-  grub_list_iterate (GRUB_AS_LIST (grub_handler_class_list),
-                    (grub_list_hook_t) iterate_class);
-
-  /* Ignore errors.  */
-  grub_errno = GRUB_ERR_NONE;
-}
-
-void
-free_handler_list (void)
-{
-  struct grub_handler_list *item;
-
-  while ((item = grub_list_pop (&handler_list)) != 0)
-    {
-      grub_free (item->cmd->data);
-      grub_unregister_command (item->cmd);
-      grub_free (item->name);
-      grub_free (item);
-    }
-}
diff --git a/normal/main.c b/normal/main.c
deleted file mode 100644 (file)
index 4ed17e8..0000000
+++ /dev/null
@@ -1,729 +0,0 @@
-/* main.c - the normal mode main routine */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2000,2001,2002,2003,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/kernel.h>
-#include <grub/normal.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/term.h>
-#include <grub/env.h>
-#include <grub/parser.h>
-#include <grub/reader.h>
-#include <grub/menu_viewer.h>
-#include <grub/auth.h>
-#include <grub/i18n.h>
-#include <grub/charset.h>
-
-#define GRUB_DEFAULT_HISTORY_SIZE      50
-
-static int nested_level = 0;
-int grub_normal_exit_level = 0;
-
-/* Read a line from the file FILE.  */
-char *
-grub_file_getline (grub_file_t file)
-{
-  char c;
-  int pos = 0;
-  int literal = 0;
-  char *cmdline;
-  int max_len = 64;
-
-  /* Initially locate some space.  */
-  cmdline = grub_malloc (max_len);
-  if (! cmdline)
-    return 0;
-
-  while (1)
-    {
-      if (grub_file_read (file, &c, 1) != 1)
-       break;
-
-      /* Skip all carriage returns.  */
-      if (c == '\r')
-       continue;
-
-      /* Replace tabs with spaces.  */
-      if (c == '\t')
-       c = ' ';
-
-      /* The previous is a backslash, then...  */
-      if (literal)
-       {
-         /* If it is a newline, replace it with a space and continue.  */
-         if (c == '\n')
-           {
-             c = ' ';
-
-             /* Go back to overwrite the backslash.  */
-             if (pos > 0)
-               pos--;
-           }
-
-         literal = 0;
-       }
-
-      if (c == '\\')
-       literal = 1;
-
-      if (pos == 0)
-       {
-         if (! grub_isspace (c))
-           cmdline[pos++] = c;
-       }
-      else
-       {
-         if (pos >= max_len)
-           {
-             char *old_cmdline = cmdline;
-             max_len = max_len * 2;
-             cmdline = grub_realloc (cmdline, max_len);
-             if (! cmdline)
-               {
-                 grub_free (old_cmdline);
-                 return 0;
-               }
-           }
-
-         if (c == '\n')
-           break;
-
-         cmdline[pos++] = c;
-       }
-    }
-
-  cmdline[pos] = '\0';
-
-  /* If the buffer is empty, don't return anything at all.  */
-  if (pos == 0)
-    {
-      grub_free (cmdline);
-      cmdline = 0;
-    }
-
-  return cmdline;
-}
-
-static void
-free_menu (grub_menu_t menu)
-{
-  grub_menu_entry_t entry = menu->entry_list;
-
-  while (entry)
-    {
-      grub_menu_entry_t next_entry = entry->next;
-
-      grub_free ((void *) entry->title);
-      grub_free ((void *) entry->sourcecode);
-      entry = next_entry;
-    }
-
-  grub_free (menu);
-  grub_env_unset_menu ();
-}
-
-static void
-free_menu_entry_classes (struct grub_menu_entry_class *head)
-{
-  /* Free all the classes.  */
-  while (head)
-    {
-      struct grub_menu_entry_class *next;
-
-      grub_free (head->name);
-      next = head->next;
-      grub_free (head);
-      head = next;
-    }
-}
-
-static struct
-{
-  char *name;
-  int key;
-} hotkey_aliases[] =
-  {
-    {"backspace", '\b'},
-    {"tab", '\t'},
-    {"delete", GRUB_TERM_DC}
-  };
-
-/* Add a menu entry to the current menu context (as given by the environment
-   variable data slot `menu').  As the configuration file is read, the script
-   parser calls this when a menu entry is to be created.  */
-grub_err_t
-grub_normal_add_menu_entry (int argc, const char **args,
-                           const char *sourcecode)
-{
-  const char *menutitle = 0;
-  const char *menusourcecode;
-  grub_menu_t menu;
-  grub_menu_entry_t *last;
-  int failed = 0;
-  int i;
-  struct grub_menu_entry_class *classes_head;  /* Dummy head node for list.  */
-  struct grub_menu_entry_class *classes_tail;
-  char *users = NULL;
-  int hotkey = 0;
-
-  /* Allocate dummy head node for class list.  */
-  classes_head = grub_zalloc (sizeof (struct grub_menu_entry_class));
-  if (! classes_head)
-    return grub_errno;
-  classes_tail = classes_head;
-
-  menu = grub_env_get_menu ();
-  if (! menu)
-    return grub_error (GRUB_ERR_MENU, "no menu context");
-
-  last = &menu->entry_list;
-
-  menusourcecode = grub_strdup (sourcecode);
-  if (! menusourcecode)
-    return grub_errno;
-
-  /* Parse menu arguments.  */
-  for (i = 0; i < argc; i++)
-    {
-      /* Capture arguments.  */
-      if (grub_strncmp ("--", args[i], 2) == 0)
-       {
-         const char *arg = &args[i][2];
-
-         /* Handle menu class.  */
-         if (grub_strcmp(arg, "class") == 0)
-           {
-             char *class_name;
-             struct grub_menu_entry_class *new_class;
-
-             i++;
-             class_name = grub_strdup (args[i]);
-             if (! class_name)
-               {
-                 failed = 1;
-                 break;
-               }
-
-             /* Create a new class and add it at the tail of the list.  */
-             new_class = grub_zalloc (sizeof (struct grub_menu_entry_class));
-             if (! new_class)
-               {
-                 grub_free (class_name);
-                 failed = 1;
-                 break;
-               }
-             /* Fill in the new class node.  */
-             new_class->name = class_name;
-             /* Link the tail to it, and make it the new tail.  */
-             classes_tail->next = new_class;
-             classes_tail = new_class;
-             continue;
-           }
-         else if (grub_strcmp(arg, "users") == 0)
-           {
-             i++;
-             users = grub_strdup (args[i]);
-             if (! users)
-               {
-                 failed = 1;
-                 break;
-               }
-
-             continue;
-           }
-         else if (grub_strcmp(arg, "hotkey") == 0)
-           {
-             unsigned j;
-
-             i++;
-             if (args[i][1] == 0)
-               {
-                 hotkey = args[i][0];
-                 continue;
-               }
-
-             for (j = 0; j < ARRAY_SIZE (hotkey_aliases); j++)
-               if (grub_strcmp (args[i], hotkey_aliases[j].name) == 0)
-                 {
-                   hotkey = hotkey_aliases[j].key;
-                   break;
-                 }
-
-             if (j < ARRAY_SIZE (hotkey_aliases))
-               continue;
-
-             failed = 1;
-             grub_error (GRUB_ERR_MENU,
-                         "Invalid hotkey: '%s'.", args[i]);
-             break;
-           }
-         else
-           {
-             /* Handle invalid argument.  */
-             failed = 1;
-             grub_error (GRUB_ERR_MENU,
-                         "invalid argument for menuentry: %s", args[i]);
-             break;
-           }
-       }
-
-      /* Capture title.  */
-      if (! menutitle)
-       {
-         menutitle = grub_strdup (args[i]);
-       }
-      else
-       {
-         failed = 1;
-         grub_error (GRUB_ERR_MENU,
-                     "too many titles for menuentry: %s", args[i]);
-         break;
-       }
-    }
-
-  /* Validate arguments.  */
-  if ((! failed) && (! menutitle))
-    {
-      grub_error (GRUB_ERR_MENU, "menuentry is missing title");
-      failed = 1;
-    }
-
-  /* If argument parsing failed, free any allocated resources.  */
-  if (failed)
-    {
-      free_menu_entry_classes (classes_head);
-      grub_free ((void *) menutitle);
-      grub_free ((void *) menusourcecode);
-
-      /* Here we assume that grub_error has been used to specify failure details.  */
-      return grub_errno;
-    }
-
-  /* Add the menu entry at the end of the list.  */
-  while (*last)
-    last = &(*last)->next;
-
-  *last = grub_zalloc (sizeof (**last));
-  if (! *last)
-    {
-      free_menu_entry_classes (classes_head);
-      grub_free ((void *) menutitle);
-      grub_free ((void *) menusourcecode);
-      return grub_errno;
-    }
-
-  (*last)->title = menutitle;
-  (*last)->hotkey = hotkey;
-  (*last)->classes = classes_head;
-  if (users)
-    (*last)->restricted = 1;
-  (*last)->users = users;
-  (*last)->sourcecode = menusourcecode;
-
-  menu->size++;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_menu_t
-read_config_file (const char *config)
-{
-  grub_file_t file;
-  grub_parser_t old_parser = 0;
-
-  auto grub_err_t getline (char **line, int cont);
-  grub_err_t getline (char **line, int cont __attribute__ ((unused)))
-    {
-      while (1)
-       {
-         char *buf;
-
-         *line = buf = grub_file_getline (file);
-         if (! buf)
-           return grub_errno;
-
-         if (buf[0] == '#')
-           {
-             if (buf[1] == '!')
-               {
-                 grub_parser_t parser;
-                 grub_named_list_t list;
-
-                 buf += 2;
-                 while (grub_isspace (*buf))
-                   buf++;
-
-                 if (! old_parser)
-                   old_parser = grub_parser_get_current ();
-
-                 list = GRUB_AS_NAMED_LIST (grub_parser_class.handler_list);
-                 parser = grub_named_list_find (list, buf);
-                 if (parser)
-                   grub_parser_set_current (parser);
-                 else
-                   {
-                     char cmd_name[8 + grub_strlen (buf)];
-
-                     /* Perhaps it's not loaded yet, try the autoload
-                        command.  */
-                     grub_strcpy (cmd_name, "parser.");
-                     grub_strcat (cmd_name, buf);
-                     grub_command_execute (cmd_name, 0, 0);
-                   }
-               }
-             grub_free (*line);
-           }
-         else
-           break;
-       }
-
-      return GRUB_ERR_NONE;
-    }
-
-  grub_menu_t newmenu;
-
-  newmenu = grub_env_get_menu ();
-  if (! newmenu)
-    {
-      newmenu = grub_zalloc (sizeof (*newmenu));
-      if (! newmenu)
-       return 0;
-
-      grub_env_set_menu (newmenu);
-    }
-
-  /* Try to open the config file.  */
-  file = grub_file_open (config);
-  if (! file)
-    return 0;
-
-  while (1)
-    {
-      char *line;
-
-      /* Print an error, if any.  */
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-
-      if ((getline (&line, 0)) || (! line))
-       break;
-
-      grub_parser_get_current ()->parse_line (line, getline);
-      grub_free (line);
-    }
-
-  grub_file_close (file);
-
-  if (old_parser)
-    grub_parser_set_current (old_parser);
-
-  return newmenu;
-}
-
-/* Initialize the screen.  */
-void
-grub_normal_init_page (struct grub_term_output *term)
-{
-  int msg_len;
-  int posx;
-  const char *msg = _("GNU GRUB  version %s");
-  char *msg_formatted;
-  grub_uint32_t *unicode_msg;
-  grub_uint32_t *last_position;
-  grub_term_cls (term);
-
-  msg_formatted = grub_xasprintf (msg, PACKAGE_VERSION);
-  if (!msg_formatted)
-    return;
-  msg_len = grub_utf8_to_ucs4_alloc (msg_formatted,
-                                    &unicode_msg, &last_position);
-  grub_free (msg_formatted);
-  if (msg_len < 0)
-    {
-      return;
-    }
-
-  posx = grub_getstringwidth (unicode_msg, last_position, term);
-  posx = (grub_term_width (term) - posx) / 2;
-  grub_term_gotoxy (term, posx, 1);
-
-  grub_print_ucs4 (unicode_msg, last_position, term);
-  grub_printf("\n\n");
-  grub_free (unicode_msg);
-}
-
-static void
-read_lists (const char *val)
-{
-  read_command_list (val);
-  read_fs_list (val);
-  read_crypto_list (val);
-  read_terminal_list (val);
-}
-
-static char *
-read_lists_hook (struct grub_env_var *var __attribute__ ((unused)),
-                const char *val)
-{
-  read_lists (val);
-  return val ? grub_strdup (val) : NULL;
-}
-
-/* Read the config file CONFIG and execute the menu interface or
-   the command line interface if BATCH is false.  */
-void
-grub_normal_execute (const char *config, int nested, int batch)
-{
-  grub_menu_t menu = 0;
-  const char *prefix = grub_env_get ("prefix");
-
-  read_lists (prefix);
-  read_handler_list ();
-  grub_register_variable_hook ("prefix", NULL, read_lists_hook);
-  grub_command_execute ("parser.grub", 0, 0);
-
-  if (config)
-    {
-      menu = read_config_file (config);
-
-      /* Ignore any error.  */
-      grub_errno = GRUB_ERR_NONE;
-    }
-
-  if (! batch)
-    {
-      if (menu && menu->size)
-       {
-         grub_show_menu (menu, nested);
-         if (nested)
-           free_menu (menu);
-       }
-    }
-}
-
-/* This starts the normal mode.  */
-void
-grub_enter_normal_mode (const char *config)
-{
-  nested_level++;
-  grub_normal_execute (config, 0, 0);
-  grub_cmdline_run (0);
-  nested_level--;
-  if (grub_normal_exit_level)
-    grub_normal_exit_level--;
-}
-
-/* Enter normal mode from rescue mode.  */
-static grub_err_t
-grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)),
-                int argc, char *argv[])
-{
-  if (argc == 0)
-    {
-      /* Guess the config filename. It is necessary to make CONFIG static,
-        so that it won't get broken by longjmp.  */
-      char *config;
-      const char *prefix;
-
-      prefix = grub_env_get ("prefix");
-      if (prefix)
-       {
-         config = grub_xasprintf ("%s/grub.cfg", prefix);
-         if (! config)
-           goto quit;
-
-         grub_enter_normal_mode (config);
-         grub_free (config);
-       }
-      else
-       grub_enter_normal_mode (0);
-    }
-  else
-    grub_enter_normal_mode (argv[0]);
-
-quit:
-  return 0;
-}
-
-/* Exit from normal mode to rescue mode.  */
-static grub_err_t
-grub_cmd_normal_exit (struct grub_command *cmd __attribute__ ((unused)),
-                     int argc __attribute__ ((unused)),
-                     char *argv[] __attribute__ ((unused)))
-{
-  if (nested_level <= grub_normal_exit_level)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "not in normal environment");
-  grub_normal_exit_level++;
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_normal_reader_init (int nested)
-{
-  struct grub_term_output *term;
-  const char *msg = _("Minimal BASH-like line editing is supported. For "
-                     "the first word, TAB lists possible command completions. Anywhere "
-                     "else TAB lists possible device or file completions. %s");
-  const char *msg_esc = _("ESC at any time exits.");
-  char *msg_formatted;
-
-  msg_formatted = grub_xasprintf (msg, nested ? msg_esc : "");
-  if (!msg_formatted)
-    return grub_errno;
-
-  FOR_ACTIVE_TERM_OUTPUTS(term)
-  {
-    grub_normal_init_page (term);
-    grub_term_setcursor (term, 1);
-    
-    grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN, term);
-    grub_puts ("\n");
-  }
-  grub_free (msg_formatted);
-  return 0;
-}
-
-
-static grub_err_t
-grub_normal_read_line_real (char **line, int cont, int nested)
-{
-  grub_parser_t parser = grub_parser_get_current ();
-  char *prompt;
-
-  if (cont)
-    prompt = grub_xasprintf (">");
-  else
-    prompt = grub_xasprintf ("%s>", parser->name);
-
-  if (!prompt)
-    return grub_errno;
-
-  while (1)
-    {
-      *line = grub_cmdline_get (prompt);
-      if (*line)
-       break;
-
-      if (cont || nested)
-       {
-         grub_free (*line);
-         grub_free (prompt);
-         *line = 0;
-         return grub_errno;
-       }
-    }
-  
-  grub_free (prompt);
-
-  return 0;
-}
-
-static grub_err_t
-grub_normal_read_line (char **line, int cont)
-{
-  return grub_normal_read_line_real (line, cont, 0);
-}
-
-void
-grub_cmdline_run (int nested)
-{
-  grub_err_t err = GRUB_ERR_NONE;
-
-  err = grub_auth_check_authentication (NULL);
-
-  if (err)
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-      return;
-    }
-
-  grub_normal_reader_init (nested);
-
-  while (1)
-    {
-      char *line;
-
-      if (grub_normal_exit_level)
-       break;
-
-      /* Print an error, if any.  */
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-
-      grub_normal_read_line_real (&line, 0, nested);
-      if (! line)
-       break;
-
-      grub_parser_get_current ()->parse_line (line, grub_normal_read_line);
-      grub_free (line);
-    }
-}
-
-static char *
-grub_env_write_pager (struct grub_env_var *var __attribute__ ((unused)),
-                     const char *val)
-{
-  grub_set_more ((*val == '1'));
-  return grub_strdup (val);
-}
-
-GRUB_MOD_INIT(normal)
-{
-  grub_context_init ();
-
-  /* Normal mode shouldn't be unloaded.  */
-  if (mod)
-    grub_dl_ref (mod);
-
-  grub_set_history (GRUB_DEFAULT_HISTORY_SIZE);
-
-  grub_install_newline_hook ();
-  grub_register_variable_hook ("pager", 0, grub_env_write_pager);
-
-  /* Register a command "normal" for the rescue mode.  */
-  grub_register_command ("normal", grub_cmd_normal,
-                        0, N_("Enter normal mode."));
-  grub_register_command ("normal_exit", grub_cmd_normal_exit,
-                        0, N_("Exit from normal mode."));
-
-  /* Reload terminal colors when these variables are written to.  */
-  grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal);
-  grub_register_variable_hook ("color_highlight", NULL, grub_env_write_color_highlight);
-
-  /* Preserve hooks after context changes.  */
-  grub_env_export ("color_normal");
-  grub_env_export ("color_highlight");
-}
-
-GRUB_MOD_FINI(normal)
-{
-  grub_context_fini ();
-
-  grub_set_history (0);
-  grub_register_variable_hook ("pager", 0, 0);
-  grub_fs_autoload_hook = 0;
-  free_handler_list ();
-}
diff --git a/normal/menu.c b/normal/menu.c
deleted file mode 100644 (file)
index 09c5fd1..0000000
+++ /dev/null
@@ -1,613 +0,0 @@
-/* menu.c - General supporting functionality for menus.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/normal.h>
-#include <grub/misc.h>
-#include <grub/loader.h>
-#include <grub/mm.h>
-#include <grub/time.h>
-#include <grub/env.h>
-#include <grub/menu_viewer.h>
-#include <grub/command.h>
-#include <grub/parser.h>
-#include <grub/auth.h>
-#include <grub/i18n.h>
-#include <grub/term.h>
-
-/* Time to delay after displaying an error message about a default/fallback
-   entry failing to boot.  */
-#define DEFAULT_ENTRY_ERROR_DELAY_MS  2500
-
-grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu,
-                                    int nested) = NULL;
-
-/* Wait until the user pushes any key so that the user
-   can see what happened.  */
-void
-grub_wait_after_message (void)
-{
-  grub_putchar ('\n');
-  grub_printf_ (N_("Press any key to continue..."));
-  (void) grub_getkey ();
-  grub_putchar ('\n');
-}
-
-/* Get a menu entry by its index in the entry list.  */
-grub_menu_entry_t
-grub_menu_get_entry (grub_menu_t menu, int no)
-{
-  grub_menu_entry_t e;
-
-  for (e = menu->entry_list; e && no > 0; e = e->next, no--)
-    ;
-
-  return e;
-}
-
-/* Return the current timeout. If the variable "timeout" is not set or
-   invalid, return -1.  */
-int
-grub_menu_get_timeout (void)
-{
-  char *val;
-  int timeout;
-
-  val = grub_env_get ("timeout");
-  if (! val)
-    return -1;
-
-  grub_error_push ();
-
-  timeout = (int) grub_strtoul (val, 0, 0);
-
-  /* If the value is invalid, unset the variable.  */
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_env_unset ("timeout");
-      grub_errno = GRUB_ERR_NONE;
-      timeout = -1;
-    }
-
-  grub_error_pop ();
-
-  return timeout;
-}
-
-/* Set current timeout in the variable "timeout".  */
-void
-grub_menu_set_timeout (int timeout)
-{
-  /* Ignore TIMEOUT if it is zero, because it will be unset really soon.  */
-  if (timeout > 0)
-    {
-      char buf[16];
-
-      grub_snprintf (buf, sizeof (buf), "%d", timeout);
-      grub_env_set ("timeout", buf);
-    }
-}
-
-/* Get the first entry number from the value of the environment variable NAME,
-   which is a space-separated list of non-negative integers.  The entry number
-   which is returned is stripped from the value of NAME.  If no entry number
-   can be found, -1 is returned.  */
-static int
-get_and_remove_first_entry_number (const char *name)
-{
-  char *val;
-  char *tail;
-  int entry;
-
-  val = grub_env_get (name);
-  if (! val)
-    return -1;
-
-  grub_error_push ();
-
-  entry = (int) grub_strtoul (val, &tail, 0);
-
-  if (grub_errno == GRUB_ERR_NONE)
-    {
-      /* Skip whitespace to find the next digit.  */
-      while (*tail && grub_isspace (*tail))
-       tail++;
-      grub_env_set (name, tail);
-    }
-  else
-    {
-      grub_env_unset (name);
-      grub_errno = GRUB_ERR_NONE;
-      entry = -1;
-    }
-
-  grub_error_pop ();
-
-  return entry;
-}
-
-/* Run a menu entry.  */
-void
-grub_menu_execute_entry(grub_menu_entry_t entry)
-{
-  grub_err_t err = GRUB_ERR_NONE;
-
-  if (entry->restricted)
-    err = grub_auth_check_authentication (entry->users);
-
-  if (err)
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-      return;
-    }
-
-  grub_env_set ("chosen", entry->title);
-
-  grub_parser_execute ((char *) entry->sourcecode);
-
-  if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
-    /* Implicit execution of boot, only if something is loaded.  */
-    grub_command_execute ("boot", 0, 0);
-}
-
-/* Execute ENTRY from the menu MENU, falling back to entries specified
-   in the environment variable "fallback" if it fails.  CALLBACK is a
-   pointer to a struct of function pointers which are used to allow the
-   caller provide feedback to the user.  */
-void
-grub_menu_execute_with_fallback (grub_menu_t menu,
-                                grub_menu_entry_t entry,
-                                grub_menu_execute_callback_t callback,
-                                void *callback_data)
-{
-  int fallback_entry;
-
-  callback->notify_booting (entry, callback_data);
-
-  grub_menu_execute_entry (entry);
-
-  /* Deal with fallback entries.  */
-  while ((fallback_entry = get_and_remove_first_entry_number ("fallback"))
-        >= 0)
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-
-      entry = grub_menu_get_entry (menu, fallback_entry);
-      callback->notify_fallback (entry, callback_data);
-      grub_menu_execute_entry (entry);
-      /* If the function call to execute the entry returns at all, then this is
-        taken to indicate a boot failure.  For menu entries that do something
-        other than actually boot an operating system, this could assume
-        incorrectly that something failed.  */
-    }
-
-  callback->notify_failure (callback_data);
-}
-
-static struct grub_menu_viewer *viewers;
-
-static void
-menu_set_chosen_entry (int entry)
-{
-  struct grub_menu_viewer *cur;
-  for (cur = viewers; cur; cur = cur->next)
-    cur->set_chosen_entry (entry, cur->data);
-}
-
-static void
-menu_print_timeout (int timeout)
-{
-  struct grub_menu_viewer *cur;
-  for (cur = viewers; cur; cur = cur->next)
-    cur->print_timeout (timeout, cur->data);
-}
-
-static void
-menu_fini (void)
-{
-  struct grub_menu_viewer *cur, *next;
-  for (cur = viewers; cur; cur = next)
-    {
-      next = cur->next;
-      cur->fini (cur->data);
-      grub_free (cur);
-    }
-  viewers = NULL;
-}
-
-static void
-menu_init (int entry, grub_menu_t menu, int nested)
-{
-  struct grub_term_output *term;
-
-  FOR_ACTIVE_TERM_OUTPUTS(term)
-  {
-    grub_err_t err;
-
-    if (grub_gfxmenu_try_hook && grub_strcmp (term->name, "gfxterm") == 0)
-      {
-       err = grub_gfxmenu_try_hook (entry, menu, nested);
-       if(!err)
-         continue;
-       grub_print_error ();
-       grub_errno = GRUB_ERR_NONE;
-      }
-
-    err = grub_menu_try_text (term, entry, menu, nested);
-    if(!err)
-      continue;
-    grub_print_error ();
-    grub_errno = GRUB_ERR_NONE;
-  }
-}
-
-static void
-clear_timeout (void)
-{
-  struct grub_menu_viewer *cur;
-  for (cur = viewers; cur; cur = cur->next)
-    cur->clear_timeout (cur->data);
-}
-
-void
-grub_menu_register_viewer (struct grub_menu_viewer *viewer)
-{
-  viewer->next = viewers;
-  viewers = viewer;
-}
-
-/* Get the entry number from the variable NAME.  */
-static int
-get_entry_number (grub_menu_t menu, const char *name)
-{
-  char *val;
-  int entry;
-
-  val = grub_env_get (name);
-  if (! val)
-    return -1;
-
-  grub_error_push ();
-
-  entry = (int) grub_strtoul (val, 0, 0);
-
-  if (grub_errno == GRUB_ERR_BAD_NUMBER)
-    {
-      /* See if the variable matches the title of a menu entry.  */
-      grub_menu_entry_t e = menu->entry_list;
-      int i;
-
-      grub_errno = GRUB_ERR_NONE;
-
-      for (i = 0; e; i++)
-       {
-         if (grub_strcmp (e->title, val) == 0)
-           {
-             entry = i;
-             break;
-           }
-         e = e->next;
-       }
-
-      if (! e)
-       entry = -1;
-    }
-
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_errno = GRUB_ERR_NONE;
-      entry = -1;
-    }
-
-  grub_error_pop ();
-
-  return entry;
-}
-
-#define GRUB_MENU_PAGE_SIZE 10
-
-/* Show the menu and handle menu entry selection.  Returns the menu entry
-   index that should be executed or -1 if no entry should be executed (e.g.,
-   Esc pressed to exit a sub-menu or switching menu viewers).
-   If the return value is not -1, then *AUTO_BOOT is nonzero iff the menu
-   entry to be executed is a result of an automatic default selection because
-   of the timeout.  */
-static int
-run_menu (grub_menu_t menu, int nested, int *auto_boot)
-{
-  grub_uint64_t saved_time;
-  int default_entry, current_entry;
-  int timeout;
-
-  default_entry = get_entry_number (menu, "default");
-
-  /* If DEFAULT_ENTRY is not within the menu entries, fall back to
-     the first entry.  */
-  if (default_entry < 0 || default_entry >= menu->size)
-    default_entry = 0;
-
-  /* If timeout is 0, drawing is pointless (and ugly).  */
-  if (grub_menu_get_timeout () == 0)
-    {
-      *auto_boot = 1;
-      return default_entry;
-    }
-
-  current_entry = default_entry;
-
-  /* Initialize the time.  */
-  saved_time = grub_get_time_ms ();
-
- refresh:
-  menu_init (current_entry, menu, nested);
-
-  timeout = grub_menu_get_timeout ();
-
-  if (timeout > 0)
-    menu_print_timeout (timeout);
-  else
-    clear_timeout ();
-
-  while (1)
-    {
-      int c;
-      timeout = grub_menu_get_timeout ();
-
-      if (grub_normal_exit_level)
-       return -1;
-
-      if (timeout > 0)
-       {
-         grub_uint64_t current_time;
-
-         current_time = grub_get_time_ms ();
-         if (current_time - saved_time >= 1000)
-           {
-             timeout--;
-             grub_menu_set_timeout (timeout);
-             saved_time = current_time;
-             menu_print_timeout (timeout);
-           }
-       }
-
-      if (timeout == 0)
-       {
-         grub_env_unset ("timeout");
-          *auto_boot = 1;
-         menu_fini ();
-         return default_entry;
-       }
-
-      if (grub_checkkey () >= 0 || timeout < 0)
-       {
-         c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
-
-         if (timeout >= 0)
-           {
-             grub_env_unset ("timeout");
-             grub_env_unset ("fallback");
-             clear_timeout ();
-           }
-
-         switch (c)
-           {
-           case GRUB_TERM_HOME:
-             current_entry = 0;
-             menu_set_chosen_entry (current_entry);
-             break;
-
-           case GRUB_TERM_END:
-             current_entry = menu->size - 1;
-             menu_set_chosen_entry (current_entry);
-             break;
-
-           case GRUB_TERM_UP:
-           case '^':
-             if (current_entry > 0)
-               current_entry--;
-             menu_set_chosen_entry (current_entry);
-             break;
-
-           case GRUB_TERM_DOWN:
-           case 'v':
-             if (current_entry < menu->size - 1)
-               current_entry++;
-             menu_set_chosen_entry (current_entry);
-             break;
-
-           case GRUB_TERM_PPAGE:
-             if (current_entry < GRUB_MENU_PAGE_SIZE)
-               current_entry = 0;
-             else
-               current_entry -= GRUB_MENU_PAGE_SIZE;
-             menu_set_chosen_entry (current_entry);
-             break;
-
-           case GRUB_TERM_NPAGE:
-             if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size)
-               current_entry += GRUB_MENU_PAGE_SIZE;
-             else
-               current_entry = menu->size - 1;
-             menu_set_chosen_entry (current_entry);
-             break;
-
-           case '\n':
-           case '\r':
-           case 6:
-             menu_fini ();
-              *auto_boot = 0;
-             return current_entry;
-
-           case '\e':
-             if (nested)
-               {
-                 menu_fini ();
-                 return -1;
-               }
-             break;
-
-           case 'c':
-             menu_fini ();
-             grub_cmdline_run (1);
-             goto refresh;
-
-           case 'e':
-             menu_fini ();
-               {
-                 grub_menu_entry_t e = grub_menu_get_entry (menu, current_entry);
-                 if (e)
-                   grub_menu_entry_run (e);
-               }
-             goto refresh;
-
-           default:
-             {
-               grub_menu_entry_t entry;
-               int i;
-               for (i = 0, entry = menu->entry_list; i < menu->size;
-                    i++, entry = entry->next)
-                 if (entry->hotkey == c)
-                   {
-                     menu_fini ();
-                     *auto_boot = 0;
-                     return i;
-                   }
-             }
-             break;
-           }
-       }
-    }
-
-  /* Never reach here.  */
-  return -1;
-}
-
-/* Callback invoked immediately before a menu entry is executed.  */
-static void
-notify_booting (grub_menu_entry_t entry,
-               void *userdata __attribute__((unused)))
-{
-  grub_printf ("  ");
-  grub_printf_ (N_("Booting \'%s\'"), entry->title);
-  grub_printf ("\n\n");
-}
-
-/* Callback invoked when a default menu entry executed because of a timeout
-   has failed and an attempt will be made to execute the next fallback
-   entry, ENTRY.  */
-static void
-notify_fallback (grub_menu_entry_t entry,
-                void *userdata __attribute__((unused)))
-{
-  grub_printf ("\n   ");
-  grub_printf_ (N_("Falling back to \'%s\'"), entry->title);
-  grub_printf ("\n\n");
-  grub_millisleep (DEFAULT_ENTRY_ERROR_DELAY_MS);
-}
-
-/* Callback invoked when a menu entry has failed and there is no remaining
-   fallback entry to attempt.  */
-static void
-notify_execution_failure (void *userdata __attribute__((unused)))
-{
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-    }
-  grub_printf ("\n  ");
-  grub_printf_ (N_("Failed to boot both default and fallback entries.\n"));
-  grub_wait_after_message ();
-}
-
-/* Callbacks used by the text menu to provide user feedback when menu entries
-   are executed.  */
-static struct grub_menu_execute_callback execution_callback =
-{
-  .notify_booting = notify_booting,
-  .notify_fallback = notify_fallback,
-  .notify_failure = notify_execution_failure
-};
-
-static grub_err_t
-show_menu (grub_menu_t menu, int nested)
-{
-  while (1)
-    {
-      int boot_entry;
-      grub_menu_entry_t e;
-      int auto_boot;
-
-      boot_entry = run_menu (menu, nested, &auto_boot);
-      if (boot_entry < 0)
-       break;
-
-      e = grub_menu_get_entry (menu, boot_entry);
-      if (! e)
-       continue; /* Menu is empty.  */
-
-      grub_cls ();
-
-      if (auto_boot)
-        {
-          grub_menu_execute_with_fallback (menu, e, &execution_callback, 0);
-        }
-      else
-        {
-         int lines_before = grub_normal_get_line_counter ();
-          grub_errno = GRUB_ERR_NONE;
-          grub_menu_execute_entry (e);
-         grub_print_error ();
-         grub_errno = GRUB_ERR_NONE;
-
-          if (lines_before != grub_normal_get_line_counter ())
-           grub_wait_after_message ();
-        }
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_show_menu (grub_menu_t menu, int nested)
-{
-  grub_err_t err1, err2;
-
-  while (1)
-    {
-      err1 = show_menu (menu, nested);
-      grub_print_error ();
-
-      if (grub_normal_exit_level)
-       break;
-
-      err2 = grub_auth_check_authentication (NULL);
-      if (err2)
-       {
-         grub_print_error ();
-         grub_errno = GRUB_ERR_NONE;
-         continue;
-       }
-
-      break;
-    }
-
-  return err1;
-}
diff --git a/normal/menu_entry.c b/normal/menu_entry.c
deleted file mode 100644 (file)
index 644fe90..0000000
+++ /dev/null
@@ -1,1399 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/normal.h>
-#include <grub/term.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/loader.h>
-#include <grub/command.h>
-#include <grub/parser.h>
-#include <grub/auth.h>
-#include <grub/i18n.h>
-
-enum update_mode
-  {
-    NO_LINE,
-    SINGLE_LINE,
-    ALL_LINES
-  };
-
-struct line
-{
-  /* The line buffer.  */
-  char *buf;
-  /* The length of the line.  */
-  int len;
-  /* The maximum length of the line.  */
-  int max_len;
-};
-
-struct per_term_screen
-{
-  struct grub_term_output *term;
-  /* The X coordinate.  */
-  int x;
-  /* The Y coordinate.  */
-  int y;
-};
-
-struct screen
-{
-  /* The array of lines.  */
-  struct line *lines;
-  /* The number of lines.  */
-  int num_lines;
-  /* The current column.  */
-  int column;
-  /* The real column.  */
-  int real_column;
-  /* The current line.  */
-  int line;
-  /* The kill buffer.  */
-  char *killed_text;
-  /* The flag of a completion window.  */
-  int completion_shown;
-
-  struct per_term_screen *terms;
-  unsigned nterms;
-};
-
-/* Used for storing completion items temporarily.  */
-static struct line completion_buffer;
-static int completion_type;
-
-/* Initialize a line.  */
-static int
-init_line (struct line *linep)
-{
-  linep->len = 0;
-  linep->max_len = 80; /* XXX */
-  linep->buf = grub_malloc (linep->max_len);
-  if (! linep->buf)
-    return 0;
-
-  return 1;
-}
-
-/* Allocate extra space if necessary.  */
-static int
-ensure_space (struct line *linep, int extra)
-{
-  if (linep->max_len < linep->len + extra)
-    {
-      linep->max_len = linep->len + extra + 80; /* XXX */
-      linep->buf = grub_realloc (linep->buf, linep->max_len + 1);
-      if (! linep->buf)
-       return 0;
-    }
-
-  return 1;
-}
-
-/* Return the number of lines occupied by this line on the screen.  */
-static int
-get_logical_num_lines (struct line *linep, struct per_term_screen *term_screen)
-{
-  return (linep->len / grub_term_entry_width (term_screen->term)) + 1;
-}
-
-/* Print a line.  */
-static void
-print_line (struct line *linep, int offset, int start, int y,
-           struct per_term_screen *term_screen)
-{
-  grub_term_gotoxy (term_screen->term, 
-                   GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + start + 1,
-                   y + GRUB_TERM_FIRST_ENTRY_Y);
-
-  if (linep->len >= offset + grub_term_entry_width (term_screen->term))
-    {
-      char *p, c;
-      p = linep->buf + offset + grub_term_entry_width (term_screen->term);
-      c = *p;
-      *p = 0;
-      grub_puts_terminal (linep->buf + offset + start, term_screen->term);
-      *p = c;
-      grub_putcode ('\\', term_screen->term);
-    }
-  else
-    {
-      int i;
-      char *p, c;
-
-      p = linep->buf + linep->len;
-      c = *p;
-      *p = 0;
-      grub_puts_terminal (linep->buf + offset + start, term_screen->term);
-      *p = c;
-
-      for (i = 0;
-          i <= grub_term_entry_width (term_screen->term) - linep->len + offset;
-          i++)
-       grub_putcode (' ', term_screen->term);
-    }
-}
-
-/* Print an empty line.  */
-static void
-print_empty_line (int y, struct per_term_screen *term_screen)
-{
-  int i;
-
-  grub_term_gotoxy (term_screen->term,
-                   GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1,
-                   y + GRUB_TERM_FIRST_ENTRY_Y);
-
-  for (i = 0; i < grub_term_entry_width (term_screen->term) + 1; i++)
-    grub_putcode (' ', term_screen->term);
-}
-
-/* Print an up arrow.  */
-static void
-print_up (int flag, struct per_term_screen *term_screen)
-{
-  grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X 
-                   + grub_term_entry_width (term_screen->term),
-                   GRUB_TERM_FIRST_ENTRY_Y);
-
-  if (flag)
-    grub_putcode (GRUB_TERM_DISP_UP, term_screen->term);
-  else
-    grub_putcode (' ', term_screen->term);
-}
-
-/* Print a down arrow.  */
-static void
-print_down (int flag, struct per_term_screen *term_screen)
-{
-  grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X
-                   + grub_term_border_width (term_screen->term),
-                   GRUB_TERM_TOP_BORDER_Y 
-                   + grub_term_num_entries (term_screen->term));
-
-  if (flag)
-    grub_putcode (GRUB_TERM_DISP_DOWN, term_screen->term);
-  else
-    grub_putcode (' ', term_screen->term);
-}
-
-/* Draw the lines of the screen SCREEN.  */
-static void
-update_screen (struct screen *screen, struct per_term_screen *term_screen,
-              int region_start, int region_column,
-              int up, int down, enum update_mode mode)
-{
-  int up_flag = 0;
-  int down_flag = 0;
-  int y;
-  int i;
-  struct line *linep;
-
-  /* Check if scrolling is necessary.  */
-  if (term_screen->y < 0 || term_screen->y
-      >= grub_term_num_entries (term_screen->term))
-    {
-      if (term_screen->y < 0)
-       term_screen->y = 0;
-      else
-       term_screen->y = grub_term_num_entries (term_screen->term) - 1;
-
-      region_start = 0;
-      region_column = 0;
-      up = 1;
-      down = 1;
-      mode = ALL_LINES;
-    }
-
-  if (mode != NO_LINE)
-    {
-      /* Draw lines. This code is tricky, because this must calculate logical
-        positions.  */
-      y = term_screen->y - screen->column
-       / grub_term_entry_width (term_screen->term);
-      i = screen->line;
-      linep = screen->lines + i;
-      while (y > 0)
-       {
-          i--;
-          linep--;
-          y -= get_logical_num_lines (linep, term_screen);
-       }
-
-      if (y < 0 || i > 0)
-       up_flag = 1;
-
-      do
-       {
-         int column;
-
-         for (column = 0;
-              column <= linep->len
-                && y < grub_term_num_entries (term_screen->term);
-              column += grub_term_entry_width (term_screen->term), y++)
-           {
-             if (y < 0)
-               continue;
-
-             if (i == region_start)
-               {
-                 if (region_column >= column
-                     && region_column
-                     < (column
-                        + grub_term_entry_width (term_screen->term)))
-                   print_line (linep, column, region_column - column, y,
-                               term_screen);
-                 else if (region_column < column)
-                   print_line (linep, column, 0, y, term_screen);
-               }
-             else if (i > region_start && mode == ALL_LINES)
-               print_line (linep, column, 0, y, term_screen);
-           }
-
-         if (y == grub_term_num_entries (term_screen->term))
-           {
-             if (column <= linep->len || i + 1 < screen->num_lines)
-               down_flag = 1;
-           }
-
-         linep++;
-         i++;
-
-         if (mode == ALL_LINES && i == screen->num_lines)
-           for (; y < grub_term_num_entries (term_screen->term); y++)
-             print_empty_line (y, term_screen);
-
-       }
-      while (y < grub_term_num_entries (term_screen->term));
-
-      /* Draw up and down arrows.  */
-      if (up)
-       print_up (up_flag, term_screen);
-      if (down)
-       print_down (down_flag, term_screen);
-    }
-
-  /* Place the cursor.  */
-  grub_term_gotoxy (term_screen->term, 
-                   GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1
-                   + term_screen->x,
-                   GRUB_TERM_FIRST_ENTRY_Y + term_screen->y);
-
-  grub_term_refresh (term_screen->term);
-}
-
-static void
-update_screen_all (struct screen *screen,
-                  int region_start, int region_column,
-                  int up, int down, enum update_mode mode)
-{
-  unsigned i;
-  for (i = 0; i < screen->nterms; i++)
-    update_screen (screen, &screen->terms[i], region_start, region_column,
-                  up, down, mode);
-}
-
-static int
-insert_string (struct screen *screen, char *s, int update)
-{
-  int region_start = screen->num_lines;
-  int region_column = 0;
-  int down[screen->nterms];
-  enum update_mode mode[screen->nterms];
-  unsigned i;
-
-  for (i = 0; i < screen->nterms; i++)
-    {
-      down[i] = 0;
-      mode[i] = NO_LINE;
-    }
-
-  while (*s)
-    {
-      if (*s == '\n')
-       {
-         /* LF is special because it creates a new line.  */
-         struct line *current_linep;
-         struct line *next_linep;
-         int size;
-
-         /* Make a new line.  */
-         screen->num_lines++;
-         screen->lines = grub_realloc (screen->lines,
-                                       screen->num_lines
-                                       * sizeof (struct line));
-         if (! screen->lines)
-           return 0;
-
-         /* Scroll down. */
-         grub_memmove (screen->lines + screen->line + 2,
-                       screen->lines + screen->line + 1,
-                       ((screen->num_lines - screen->line - 2)
-                        * sizeof (struct line)));
-
-         if (! init_line (screen->lines + screen->line + 1))
-           return 0;
-
-         /* Fold the line.  */
-         current_linep = screen->lines + screen->line;
-         next_linep = current_linep + 1;
-         size = current_linep->len - screen->column;
-
-         if (! ensure_space (next_linep, size))
-           return 0;
-
-         grub_memmove (next_linep->buf,
-                       current_linep->buf + screen->column,
-                       size);
-         current_linep->len = screen->column;
-         next_linep->len = size;
-
-         /* Update a dirty region.  */
-         if (region_start > screen->line)
-           {
-             region_start = screen->line;
-             region_column = screen->column;
-           }
-
-         for (i = 0; i < screen->nterms; i++)
-           {
-             mode[i] = ALL_LINES;
-             down[i] = 1; /* XXX not optimal.  */
-           }
-
-         /* Move the cursor.  */
-         screen->column = screen->real_column = 0;
-         screen->line++;
-         for (i = 0; i < screen->nterms; i++)
-           {
-             screen->terms[i].x = 0;
-             screen->terms[i].y++;
-           }
-         s++;
-       }
-      else
-       {
-         /* All but LF.  */
-         char *p;
-         struct line *current_linep;
-         int size;
-         int orig_num[screen->nterms], new_num[screen->nterms];
-
-         /* Find a string delimited by LF.  */
-         p = grub_strchr (s, '\n');
-         if (! p)
-           p = s + grub_strlen (s);
-
-         /* Insert the string.  */
-         current_linep = screen->lines + screen->line;
-         size = p - s;
-         if (! ensure_space (current_linep, size))
-           return 0;
-
-         grub_memmove (current_linep->buf + screen->column + size,
-                       current_linep->buf + screen->column,
-                       current_linep->len - screen->column);
-         grub_memmove (current_linep->buf + screen->column,
-                       s,
-                       size);
-         for (i = 0; i < screen->nterms; i++)
-           orig_num[i] = get_logical_num_lines (current_linep,
-                                                &screen->terms[i]);
-         current_linep->len += size;
-         for (i = 0; i < screen->nterms; i++)
-           new_num[i] = get_logical_num_lines (current_linep,
-                                               &screen->terms[i]);
-
-         /* Update the dirty region.  */
-         if (region_start > screen->line)
-           {
-             region_start = screen->line;
-             region_column = screen->column;
-           }
-
-         for (i = 0; i < screen->nterms; i++)
-           if (orig_num[i] != new_num[i])
-             {
-               mode[i] = ALL_LINES;
-               down[i] = 1; /* XXX not optimal.  */
-             }
-           else if (mode[i] != ALL_LINES)
-             mode[i] = SINGLE_LINE;
-
-         /* Move the cursor.  */
-         screen->column += size;
-         screen->real_column = screen->column;
-         for (i = 0; i < screen->nterms; i++)
-           {
-             screen->terms[i].x += size;
-             screen->terms[i].y += screen->terms[i].x
-               / grub_term_entry_width (screen->terms[i].term);
-             screen->terms[i].x
-               %= grub_term_entry_width (screen->terms[i].term);
-           }
-         s = p;
-       }
-    }
-
-  if (update)
-    for (i = 0; i < screen->nterms; i++)
-      update_screen (screen, &screen->terms[i],
-                    region_start, region_column, 0, down[i], mode[i]);
-
-  return 1;
-}
-
-/* Release the resource allocated for SCREEN.  */
-static void
-destroy_screen (struct screen *screen)
-{
-  int i;
-
-  if (screen->lines)
-    for (i = 0; i < screen->num_lines; i++)
-      {
-       struct line *linep = screen->lines + i;
-
-       if (linep)
-         grub_free (linep->buf);
-      }
-
-  grub_free (screen->killed_text);
-  grub_free (screen->lines);
-  grub_free (screen->terms);
-  grub_free (screen);
-}
-
-/* Make a new screen.  */
-static struct screen *
-make_screen (grub_menu_entry_t entry)
-{
-  struct screen *screen;
-  unsigned i;
-
-  /* Initialize the screen.  */
-  screen = grub_zalloc (sizeof (*screen));
-  if (! screen)
-    return 0;
-
-  screen->num_lines = 1;
-  screen->lines = grub_malloc (sizeof (struct line));
-  if (! screen->lines)
-    goto fail;
-
-  /* Initialize the first line which must be always present.  */
-  if (! init_line (screen->lines))
-    goto fail;
-
-  insert_string (screen, (char *) entry->sourcecode, 0);
-
-  /* Reset the cursor position.  */
-  screen->column = 0;
-  screen->real_column = 0;
-  screen->line = 0;
-  for (i = 0; i < screen->nterms; i++)
-    {
-      screen->terms[i].x = 0;
-      screen->terms[i].y = 0;
-    }
-
-  return screen;
-
- fail:
-  destroy_screen (screen);
-  return 0;
-}
-
-static int
-forward_char (struct screen *screen, int update)
-{
-  struct line *linep;
-  unsigned i;
-
-  linep = screen->lines + screen->line;
-  if (screen->column < linep->len)
-    {
-      screen->column++;
-      for (i = 0; i < screen->nterms; i++)
-       {
-         screen->terms[i].x++;
-         if (screen->terms[i].x
-             == grub_term_entry_width (screen->terms[i].term))
-           {
-             screen->terms[i].x = 0;
-             screen->terms[i].y++;
-           }
-       }
-    }
-  else if (screen->num_lines > screen->line + 1)
-    {
-      screen->column = 0;
-      screen->line++;
-      for (i = 0; i < screen->nterms; i++)
-       {
-         screen->terms[i].x = 0;
-         screen->terms[i].y++;
-       }
-    }
-
-  screen->real_column = screen->column;
-
-  if (update)
-    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
-  return 1;
-}
-
-static int
-backward_char (struct screen *screen, int update)
-{
-  unsigned i;
-
-  if (screen->column > 0)
-    {
-      screen->column--;
-      for (i = 0; i < screen->nterms; i++)
-       {
-         screen->terms[i].x--;
-         if (screen->terms[i].x == -1)
-           {
-             screen->terms[i].x
-               = grub_term_entry_width (screen->terms[i].term) - 1;
-             screen->terms[i].y--;
-           }
-       }
-    }
-  else if (screen->line > 0)
-    {
-      struct line *linep;
-
-      screen->line--;
-      linep = screen->lines + screen->line;
-      screen->column = linep->len;
-      for (i = 0; i < screen->nterms; i++)
-       {
-         screen->terms[i].x = screen->column
-           % grub_term_entry_width (screen->terms[i].term);
-         screen->terms[i].y--;
-       }
-    }
-
-  screen->real_column = screen->column;
-
-  if (update)
-    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
-
-  return 1;
-}
-
-static int
-previous_line (struct screen *screen, int update)
-{
-  unsigned i;
-
-  if (screen->line > 0)
-    {
-      struct line *linep;
-      int col;
-
-      /* How many physical lines from the current position
-        to the first physical line?  */
-      col = screen->column;
-
-      screen->line--;
-
-      linep = screen->lines + screen->line;
-      if (linep->len < screen->real_column)
-       screen->column = linep->len;
-      else
-       screen->column = screen->real_column;
-
-      for (i = 0; i < screen->nterms; i++)
-       {
-         int dy;
-         dy = col / grub_term_entry_width (screen->terms[i].term);
-
-         /* How many physical lines from the current position
-            to the last physical line?  */
-         dy += (linep->len / grub_term_entry_width (screen->terms[i].term)
-                - screen->column
-                / grub_term_entry_width (screen->terms[i].term));
-       
-         screen->terms[i].y -= dy + 1;
-         screen->terms[i].x
-           = screen->column % grub_term_entry_width (screen->terms[i].term);
-      }
-    }
-  else
-    {
-      for (i = 0; i < screen->nterms; i++)
-       {
-         screen->terms[i].y
-           -= screen->column / grub_term_entry_width (screen->terms[i].term);
-         screen->terms[i].x = 0;
-       }
-      screen->column = 0;
-    }
-
-  if (update)
-    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
-
-  return 1;
-}
-
-static int
-next_line (struct screen *screen, int update)
-{
-  unsigned i;
-
-  if (screen->line < screen->num_lines - 1)
-    {
-      struct line *linep;
-      int l1, c1;
-
-      /* How many physical lines from the current position
-        to the last physical line?  */
-      linep = screen->lines + screen->line;
-      l1 = linep->len;
-      c1 = screen->column;
-
-      screen->line++;
-
-      linep++;
-      if (linep->len < screen->real_column)
-       screen->column = linep->len;
-      else
-       screen->column = screen->real_column;
-
-      for (i = 0; i < screen->nterms; i++)
-       {
-         int dy;
-         dy = l1 / grub_term_entry_width (screen->terms[i].term)
-           - c1 / grub_term_entry_width (screen->terms[i].term);
-         /* How many physical lines from the current position
-            to the first physical line?  */
-         dy += screen->column / grub_term_entry_width (screen->terms[i].term);
-         screen->terms[i].y += dy + 1;
-         screen->terms[i].x = screen->column
-           % grub_term_entry_width (screen->terms[i].term);
-       }
-    }
-  else
-    {
-      struct line *linep;
-      int l, s;
-      
-      linep = screen->lines + screen->line;
-      l = linep->len;
-      s = screen->column;
-      screen->column = linep->len;
-      for (i = 0; i < screen->nterms; i++)
-       {
-         screen->terms[i].y 
-           += (l / grub_term_entry_width (screen->terms[i].term)
-               -  s / grub_term_entry_width (screen->terms[i].term));
-         screen->terms[i].x
-           = screen->column % grub_term_entry_width (screen->terms[i].term);
-       }
-    }
-
-  if (update)
-    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
-
-  return 1;
-}
-
-static int
-beginning_of_line (struct screen *screen, int update)
-{
-  unsigned i;
-  int col;
-  
-  col = screen->column;
-  screen->column = screen->real_column = 0;
-  for (i = 0; i < screen->nterms; i++)
-    {
-      screen->terms[i].x = 0;
-      screen->terms[i].y -= col / grub_term_entry_width (screen->terms[i].term);
-    }
-
-  if (update)
-    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
-
-  return 1;
-}
-
-static int
-end_of_line (struct screen *screen, int update)
-{
-  struct line *linep;
-  unsigned i;
-  int col;
-
-  linep = screen->lines + screen->line;
-  col = screen->column;
-  screen->column = screen->real_column = linep->len;
-  for (i = 0; i < screen->nterms; i++)
-    {
-      screen->terms[i].y 
-       += (linep->len / grub_term_entry_width (screen->terms->term)
-           - col / grub_term_entry_width (screen->terms->term));
-      screen->terms[i].x
-       = screen->column % grub_term_entry_width (screen->terms->term);
-    }
-
-  if (update)
-    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
-
-  return 1;
-}
-
-static int
-delete_char (struct screen *screen, int update)
-{
-  struct line *linep;
-  int start = screen->num_lines;
-  int column = 0;
-
-  linep = screen->lines + screen->line;
-  if (linep->len > screen->column)
-    {
-      int orig_num[screen->nterms], new_num;
-      unsigned i;
-
-      for (i = 0; i < screen->nterms; i++)
-       orig_num[i] = get_logical_num_lines (linep, &screen->terms[i]);
-
-      grub_memmove (linep->buf + screen->column,
-                   linep->buf + screen->column + 1,
-                   linep->len - screen->column - 1);
-      linep->len--;
-
-      start = screen->line;
-      column = screen->column;
-
-      screen->real_column = screen->column;
-
-      if (update)
-       {
-         for (i = 0; i < screen->nterms; i++)
-           {
-             new_num = get_logical_num_lines (linep, &screen->terms[i]);
-             if (orig_num[i] != new_num)
-               update_screen (screen, &screen->terms[i],
-                              start, column, 0, 0, ALL_LINES);
-             else
-               update_screen (screen, &screen->terms[i],
-                              start, column, 0, 0, SINGLE_LINE);
-           }
-       }
-    }
-  else if (screen->num_lines > screen->line + 1)
-    {
-      struct line *next_linep;
-
-      next_linep = linep + 1;
-      if (! ensure_space (linep, next_linep->len))
-       return 0;
-
-      grub_memmove (linep->buf + linep->len, next_linep->buf, next_linep->len);
-      linep->len += next_linep->len;
-
-      grub_free (next_linep->buf);
-      grub_memmove (next_linep,
-                   next_linep + 1,
-                   (screen->num_lines - screen->line - 2)
-                   * sizeof (struct line));
-      screen->num_lines--;
-
-      start = screen->line;
-      column = screen->column;
-
-      screen->real_column = screen->column;
-      if (update)
-       update_screen_all (screen, start, column, 0, 1, ALL_LINES);
-    }
-
-  return 1;
-}
-
-static int
-backward_delete_char (struct screen *screen, int update)
-{
-  int saved_column;
-  int saved_line;
-
-  saved_column = screen->column;
-  saved_line = screen->line;
-
-  if (! backward_char (screen, 0))
-    return 0;
-
-  if (saved_column != screen->column || saved_line != screen->line)
-    if (! delete_char (screen, update))
-      return 0;
-
-  return 1;
-}
-
-static int
-kill_line (struct screen *screen, int continuous, int update)
-{
-  struct line *linep;
-  char *p;
-  int size;
-  int offset;
-
-  p = screen->killed_text;
-  if (! continuous && p)
-    p[0] = '\0';
-
-  linep = screen->lines + screen->line;
-  size = linep->len - screen->column;
-
-  if (p)
-    offset = grub_strlen (p);
-  else
-    offset = 0;
-
-  if (size > 0)
-    {
-      int orig_num[screen->nterms], new_num;
-      unsigned i;
-
-      p = grub_realloc (p, offset + size + 1);
-      if (! p)
-       return 0;
-
-      grub_memmove (p + offset, linep->buf + screen->column, size);
-      p[offset + size - 1] = '\0';
-
-      screen->killed_text = p;
-
-      for (i = 0; i < screen->nterms; i++)
-       orig_num[i] = get_logical_num_lines (linep, &screen->terms[i]);
-      linep->len = screen->column;
-
-      if (update)
-       {
-         new_num = get_logical_num_lines (linep, &screen->terms[i]);
-         for (i = 0; i < screen->nterms; i++)
-           {
-             if (orig_num[i] != new_num)
-               update_screen (screen, &screen->terms[i],
-                              screen->line, screen->column, 0, 1, ALL_LINES);
-             else
-               update_screen (screen, &screen->terms[i],
-                              screen->line, screen->column, 0, 0, SINGLE_LINE);
-           }
-       }
-    }
-  else if (screen->line + 1 < screen->num_lines)
-    {
-      p = grub_realloc (p, offset + 1 + 1);
-      if (! p)
-       return 0;
-
-      p[offset] = '\n';
-      p[offset + 1] = '\0';
-
-      screen->killed_text = p;
-
-      return delete_char (screen, update);
-    }
-
-  return 1;
-}
-
-static int
-yank (struct screen *screen, int update)
-{
-  if (screen->killed_text)
-    return insert_string (screen, screen->killed_text, update);
-
-  return 1;
-}
-
-static int
-open_line (struct screen *screen, int update)
-{
-  int saved_y[screen->nterms];
-  unsigned i;
-
-  for (i = 0; i < screen->nterms; i++)
-    saved_y[i] = screen->terms[i].y;
-
-  if (! insert_string (screen, "\n", 0))
-    return 0;
-
-  if (! backward_char (screen, 0))
-    return 0;
-
-  for (i = 0; i < screen->nterms; i++)
-    screen->terms[i].y = saved_y[i];
-
-  if (update)
-    update_screen_all (screen, screen->line, screen->column, 0, 1, ALL_LINES);
-
-  return 1;
-}
-
-/* A completion hook to print items.  */
-static void
-store_completion (const char *item, grub_completion_type_t type,
-                 int count __attribute__ ((unused)))
-{
-  char *p;
-
-  completion_type = type;
-
-  /* Make sure that the completion buffer has enough room.  */
-  if (completion_buffer.max_len < (completion_buffer.len
-                                  + (int) grub_strlen (item) + 1 + 1))
-    {
-      grub_size_t new_len;
-
-      new_len = completion_buffer.len + grub_strlen (item) + 80;
-      p = grub_realloc (completion_buffer.buf, new_len);
-      if (! p)
-       {
-         /* Possibly not fatal.  */
-         grub_errno = GRUB_ERR_NONE;
-         return;
-       }
-      p[completion_buffer.len] = 0;
-      completion_buffer.buf = p;
-      completion_buffer.max_len = new_len;
-    }
-
-  p = completion_buffer.buf + completion_buffer.len;
-  if (completion_buffer.len != 0)
-    {
-      *p++ = ' ';
-      completion_buffer.len++;
-    }
-  grub_strcpy (p, item);
-  completion_buffer.len += grub_strlen (item);
-}
-
-static int
-complete (struct screen *screen, int continuous, int update)
-{
-  char saved_char;
-  struct line *linep;
-  int restore;
-  char *insert;
-  static int count = -1;
-  unsigned i;
-  grub_uint32_t *ucs4;
-  grub_size_t buflen;
-  grub_ssize_t ucs4len;
-
-  if (continuous)
-    count++;
-  else
-    count = 0;
-
-  completion_buffer.buf = 0;
-  completion_buffer.len = 0;
-  completion_buffer.max_len = 0;
-
-  linep = screen->lines + screen->line;
-  saved_char = linep->buf[screen->column];
-  linep->buf[screen->column] = '\0';
-
-  insert = grub_normal_do_completion (linep->buf, &restore, store_completion);
-
-  linep->buf[screen->column] = saved_char;
-
-  buflen = grub_strlen (completion_buffer.buf);
-  ucs4 = grub_malloc (sizeof (grub_uint32_t) * (buflen + 1));
-
-  if (!ucs4)
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-      return 1;
-    }
-
-  ucs4len = grub_utf8_to_ucs4 (ucs4, buflen,
-                              (grub_uint8_t *) completion_buffer.buf,
-                              buflen, 0);
-  ucs4[ucs4len] = 0;
-
-  if (restore)
-    for (i = 0; i < screen->nterms; i++)
-      {
-       int num_sections = ((completion_buffer.len
-                            + grub_term_width (screen->terms[i].term) - 8 - 1)
-                           / (grub_term_width (screen->terms[i].term) - 8));
-       grub_uint32_t *endp;
-       grub_uint16_t pos;
-       grub_uint32_t *p = ucs4;
-
-       pos = grub_term_getxy (screen->terms[i].term);
-       grub_term_gotoxy (screen->terms[i].term, 0,
-                         grub_term_height (screen->terms[i].term) - 3);
-
-       screen->completion_shown = 1;
-
-       grub_term_gotoxy (screen->terms[i].term, 0,
-                         grub_term_height (screen->terms[i].term) - 3);
-       grub_puts_terminal ("   ", screen->terms[i].term);
-       switch (completion_type)
-         {
-         case GRUB_COMPLETION_TYPE_COMMAND:
-           grub_puts_terminal (_("Possible commands are:"),
-                               screen->terms[i].term);
-           break;
-         case GRUB_COMPLETION_TYPE_DEVICE:
-           grub_puts_terminal (_("Possible devices are:"),
-                               screen->terms[i].term);
-           break;
-         case GRUB_COMPLETION_TYPE_FILE:
-           grub_puts_terminal (_("Possible files are:"),
-                               screen->terms[i].term);
-           break;
-         case GRUB_COMPLETION_TYPE_PARTITION:
-           grub_puts_terminal (_("Possible partitions are:"),
-                               screen->terms[i].term);
-           break;
-         case GRUB_COMPLETION_TYPE_ARGUMENT:
-           grub_puts_terminal (_("Possible arguments are:"),
-                               screen->terms[i].term);
-           break;
-         default:
-           grub_puts_terminal (_("Possible things are:"),
-                               screen->terms[i].term);
-           break;
-         }
-
-       grub_puts_terminal ("\n    ", screen->terms[i].term);
-
-       p += (count % num_sections)
-         * (grub_term_width (screen->terms[i].term) - 8);
-       endp = p + (grub_term_width (screen->terms[i].term) - 8);
-
-       if (p != ucs4)
-         grub_putcode (GRUB_TERM_DISP_LEFT, screen->terms[i].term);
-       else
-         grub_putcode (' ', screen->terms[i].term);
-
-       while (*p && p < endp)
-         grub_putcode (*p++, screen->terms[i].term);
-
-       if (*p)
-         grub_putcode (GRUB_TERM_DISP_RIGHT, screen->terms[i].term);
-       grub_term_gotoxy (screen->terms[i].term, pos >> 8, pos & 0xFF);
-      }
-
-  if (insert)
-    {
-      insert_string (screen, insert, update);
-      count = -1;
-      grub_free (insert);
-    }
-  else if (update)
-    grub_refresh ();
-
-  grub_free (completion_buffer.buf);
-  return 1;
-}
-
-/* Clear displayed completions.  */
-static void
-clear_completions (struct per_term_screen *term_screen)
-{
-  grub_uint16_t pos;
-  unsigned i, j;
-
-  pos = grub_term_getxy (term_screen->term);
-  grub_term_gotoxy (term_screen->term, 0,
-                   grub_term_height (term_screen->term) - 3);
-
-  for (i = 0; i < 2; i++)
-    {
-      for (j = 0; j < grub_term_width (term_screen->term) - 1; j++)
-       grub_putcode (' ', term_screen->term);
-      grub_putcode ('\n', term_screen->term);
-    }
-
-  grub_term_gotoxy (term_screen->term, pos >> 8, pos & 0xFF);
-  grub_term_refresh (term_screen->term);
-}
-
-static void
-clear_completions_all (struct screen *screen)
-{
-  unsigned i;
-
-  for (i = 0; i < screen->nterms; i++)
-    clear_completions (&screen->terms[i]);
-}
-
-/* Execute the command list in the screen SCREEN.  */
-static int
-run (struct screen *screen)
-{
-  int currline = 0;
-  char *nextline;
-
-  auto grub_err_t editor_getline (char **line, int cont);
-  grub_err_t editor_getline (char **line, int cont __attribute__ ((unused)))
-    {
-      struct line *linep = screen->lines + currline;
-      char *p;
-
-      if (currline > screen->num_lines)
-       {
-         *line = 0;
-         return 0;
-       }
-
-      /* Trim down space characters.  */
-      for (p = linep->buf + linep->len - 1;
-          p >= linep->buf && grub_isspace (*p);
-          p--)
-       ;
-      *++p = '\0';
-
-      linep->len = p - linep->buf;
-      for (p = linep->buf; grub_isspace (*p); p++)
-       ;
-      *line = grub_strdup (p);
-      currline++;
-      return 0;
-    }
-
-  grub_cls ();
-  grub_printf ("  ");
-  grub_printf_ (N_("Booting a command list"));
-  grub_printf ("\n\n");
-
-
-  /* Execute the script, line for line.  */
-  while (currline < screen->num_lines)
-    {
-      editor_getline (&nextline, 0);
-      if (grub_parser_get_current ()->parse_line (nextline, editor_getline))
-       break;
-    }
-
-  if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
-    /* Implicit execution of boot, only if something is loaded.  */
-    grub_command_execute ("boot", 0, 0);
-
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-      grub_wait_after_message ();
-    }
-
-  return 1;
-}
-
-/* Edit a menu entry with an Emacs-like interface.  */
-void
-grub_menu_entry_run (grub_menu_entry_t entry)
-{
-  struct screen *screen;
-  int prev_c;
-  grub_err_t err = GRUB_ERR_NONE;
-  unsigned i;
-  grub_term_output_t term;
-
-  err = grub_auth_check_authentication (NULL);
-
-  if (err)
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-      return;
-    }
-
-  screen = make_screen (entry);
-  if (! screen)
-    return;
-
-  screen->terms = NULL;
-
- refresh:
-  grub_free (screen->terms);
-  screen->nterms = 0;
-  FOR_ACTIVE_TERM_OUTPUTS(term)
-    screen->nterms++;
-  screen->terms = grub_malloc (screen->nterms * sizeof (screen->terms[0]));
-  if (!screen->terms)
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-      return;
-    }
-  i = 0;
-  FOR_ACTIVE_TERM_OUTPUTS(term)
-  {
-    screen->terms[i].term = term;
-    screen->terms[i].x = 0;
-    screen->terms[i].y = 0;
-    i++;
-  }
-  /* Draw the screen.  */
-  for (i = 0; i < screen->nterms; i++)
-    grub_menu_init_page (0, 1, screen->terms[i].term);
-  update_screen_all (screen, 0, 0, 1, 1, ALL_LINES);
-  for (i = 0; i < screen->nterms; i++)
-    grub_term_setcursor (screen->terms[i].term, 1);
-  prev_c = '\0';
-
-  while (1)
-    {
-      int c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
-
-      if (screen->completion_shown)
-       {
-         clear_completions_all (screen);
-         screen->completion_shown = 0;
-       }
-
-      if (grub_normal_exit_level)
-       {
-         destroy_screen (screen);
-         return;
-       }
-
-      switch (c)
-       {
-       case 16: /* C-p */
-         if (! previous_line (screen, 1))
-           goto fail;
-         break;
-
-       case 14: /* C-n */
-         if (! next_line (screen, 1))
-           goto fail;
-         break;
-
-       case 6: /* C-f */
-         if (! forward_char (screen, 1))
-           goto fail;
-         break;
-
-       case 2: /* C-b */
-         if (! backward_char (screen, 1))
-           goto fail;
-         break;
-
-       case 1: /* C-a */
-         if (! beginning_of_line (screen, 1))
-           goto fail;
-         break;
-
-       case 5: /* C-e */
-         if (! end_of_line (screen, 1))
-           goto fail;
-         break;
-
-       case '\t': /* C-i */
-         if (! complete (screen, prev_c == c, 1))
-           goto fail;
-         break;
-
-       case 4: /* C-d */
-         if (! delete_char (screen, 1))
-           goto fail;
-         break;
-
-       case 8: /* C-h */
-         if (! backward_delete_char (screen, 1))
-           goto fail;
-         break;
-
-       case 11: /* C-k */
-         if (! kill_line (screen, prev_c == c, 1))
-           goto fail;
-         break;
-
-       case 21: /* C-u */
-         /* FIXME: What behavior is good for this key?  */
-         break;
-
-       case 25: /* C-y */
-         if (! yank (screen, 1))
-           goto fail;
-         break;
-
-       case 12: /* C-l */
-         /* FIXME: centering.  */
-         goto refresh;
-
-       case 15: /* C-o */
-         if (! open_line (screen, 1))
-           goto fail;
-         break;
-
-       case '\n':
-       case '\r':
-         if (! insert_string (screen, "\n", 1))
-           goto fail;
-         break;
-
-       case '\e':
-         destroy_screen (screen);
-         return;
-
-       case 3: /* C-c */
-         grub_cmdline_run (1);
-         goto refresh;
-
-       case 24: /* C-x */
-         if (! run (screen))
-           goto fail;
-         goto refresh;
-
-       case 18: /* C-r */
-       case 19: /* C-s */
-       case 20: /* C-t */
-         /* FIXME */
-         break;
-
-       default:
-         if (grub_isprint (c))
-           {
-             char buf[2];
-
-             buf[0] = c;
-             buf[1] = '\0';
-             if (! insert_string (screen, buf, 1))
-               goto fail;
-           }
-         break;
-       }
-
-      prev_c = c;
-    }
-
- fail:
-  destroy_screen (screen);
-
-  grub_cls ();
-  grub_print_error ();
-  grub_errno = GRUB_ERR_NONE;
-  grub_putchar ('\n');
-  grub_printf_ (N_("Press any key to continue..."));
-  (void) grub_getkey ();
-}
diff --git a/normal/menu_text.c b/normal/menu_text.c
deleted file mode 100644 (file)
index bb05875..0000000
+++ /dev/null
@@ -1,494 +0,0 @@
-/* menu_text.c - Basic text menu implementation.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/normal.h>
-#include <grub/term.h>
-#include <grub/misc.h>
-#include <grub/loader.h>
-#include <grub/mm.h>
-#include <grub/time.h>
-#include <grub/env.h>
-#include <grub/menu_viewer.h>
-#include <grub/i18n.h>
-#include <grub/charset.h>
-
-static grub_uint8_t grub_color_menu_normal;
-static grub_uint8_t grub_color_menu_highlight;
-
-struct menu_viewer_data
-{
-  int first, offset;
-  grub_menu_t menu;
-  struct grub_term_output *term;
-};
-
-static void
-print_spaces (int number_spaces, struct grub_term_output *term)
-{
-  int i;
-  for (i = 0; i < number_spaces; i++)
-    grub_putcode (' ', term);
-}
-
-void
-grub_print_ucs4 (const grub_uint32_t * str,
-                const grub_uint32_t * last_position,
-                struct grub_term_output *term)
-{
-  while (str < last_position)
-    {
-      grub_putcode (*str, term);
-      str++;
-    }
-}
-
-grub_ssize_t
-grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position,
-                    struct grub_term_output *term)
-{
-  grub_ssize_t width = 0;
-
-  while (str < last_position)
-    {
-      width += grub_term_getcharwidth (term, *str);
-      str++;
-    }
-  return width;
-}
-
-void
-grub_print_message_indented (const char *msg, int margin_left, int margin_right,
-                            struct grub_term_output *term)
-{
-  int line_len;
-
-  grub_uint32_t *unicode_msg;
-  grub_uint32_t *last_position;
-
-  int msg_len;
-
-  line_len = grub_term_width (term) - grub_term_getcharwidth (term, 'm') *
-    (margin_left + margin_right);
-
-  msg_len = grub_utf8_to_ucs4_alloc (msg, &unicode_msg, &last_position);
-
-  if (msg_len < 0)
-    {
-      return;
-    }
-
-  grub_uint32_t *current_position = unicode_msg;
-
-  grub_uint32_t *next_new_line = unicode_msg;
-
-  int first_loop = 1;
-
-  while (current_position < last_position)
-    {
-      if (! first_loop)
-        grub_putcode ('\n', term);
-     
-      next_new_line = (grub_uint32_t *) last_position;
-
-      while (grub_getstringwidth (current_position, next_new_line,term) 
-            > line_len
-            || (next_new_line != last_position && *next_new_line != ' '
-               && next_new_line > current_position))
-       {
-         next_new_line--;
-       }
-
-      if (next_new_line == current_position)
-       {
-         next_new_line = (next_new_line + line_len > last_position) ?
-           (grub_uint32_t *) last_position : next_new_line + line_len;
-       }
-
-      print_spaces (margin_left, term);
-      grub_print_ucs4 (current_position, next_new_line, term);
-
-      next_new_line++;
-      current_position = next_new_line;
-      first_loop = 0;
-    }
-  grub_free (unicode_msg);
-}
-
-
-static void
-draw_border (struct grub_term_output *term)
-{
-  unsigned i;
-
-  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
-
-  grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y);
-  grub_putcode (GRUB_TERM_DISP_UL, term);
-  for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
-    grub_putcode (GRUB_TERM_DISP_HLINE, term);
-  grub_putcode (GRUB_TERM_DISP_UR, term);
-
-  for (i = 0; i < (unsigned) grub_term_num_entries (term); i++)
-    {
-      grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1);
-      grub_putcode (GRUB_TERM_DISP_VLINE, term);
-      grub_term_gotoxy (term, GRUB_TERM_MARGIN + grub_term_border_width (term)
-                       - 1,
-                       GRUB_TERM_TOP_BORDER_Y + i + 1);
-      grub_putcode (GRUB_TERM_DISP_VLINE, term);
-    }
-
-  grub_term_gotoxy (term, GRUB_TERM_MARGIN,
-                   GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term) + 1);
-  grub_putcode (GRUB_TERM_DISP_LL, term);
-  for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
-    grub_putcode (GRUB_TERM_DISP_HLINE, term);
-  grub_putcode (GRUB_TERM_DISP_LR, term);
-
-  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
-
-  grub_term_gotoxy (term, GRUB_TERM_MARGIN,
-                   (GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term)
-                    + GRUB_TERM_MARGIN + 1));
-}
-
-static void
-print_message (int nested, int edit, struct grub_term_output *term)
-{
-  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
-
-  if (edit)
-    {
-      grub_putcode ('\n', term);
-#ifdef GRUB_MACHINE_EFI
-      grub_print_message_indented (_("Minimum Emacs-like screen editing is \
-supported. TAB lists completions. Press F1 to boot, F2=Ctrl-a, F3=Ctrl-e, \
-F4 for a command-line or ESC to discard edits and return to the GRUB menu."),
-                                   STANDARD_MARGIN, STANDARD_MARGIN, term);
-#else
-      grub_print_message_indented (_("Minimum Emacs-like screen editing is \
-supported. TAB lists completions. Press Ctrl-x to boot, Ctrl-c for a \
-command-line or ESC to discard edits and return to the GRUB menu."),
-                                   STANDARD_MARGIN, STANDARD_MARGIN, term);
-#endif
-    }
-  else
-    {
-      const char *msg = _("Use the %C and %C keys to select which "
-                         "entry is highlighted.\n");
-      char *msg_translated;
-
-      msg_translated = grub_xasprintf (msg, (grub_uint32_t) GRUB_TERM_DISP_UP,
-                                    (grub_uint32_t) GRUB_TERM_DISP_DOWN);
-      if (!msg_translated)
-       return;
-      grub_putchar ('\n');
-      grub_print_message_indented (msg_translated, STANDARD_MARGIN,
-                                  STANDARD_MARGIN, term);
-
-      grub_free (msg_translated);
-
-      if (nested)
-       {
-         grub_print_message_indented
-           (_("Press enter to boot the selected OS, "
-              "\'e\' to edit the commands before booting "
-              "or \'c\' for a command-line. ESC to return previous menu.\n"),
-            STANDARD_MARGIN, STANDARD_MARGIN, term);
-       }
-      else
-       {
-         grub_print_message_indented
-           (_("Press enter to boot the selected OS, "
-              "\'e\' to edit the commands before booting "
-              "or \'c\' for a command-line.\n"),
-            STANDARD_MARGIN, STANDARD_MARGIN, term);
-       }       
-    }
-}
-
-static void
-print_entry (int y, int highlight, grub_menu_entry_t entry,
-            struct grub_term_output *term)
-{
-  int x;
-  const char *title;
-  grub_size_t title_len;
-  grub_ssize_t len;
-  grub_uint32_t *unicode_title;
-  grub_ssize_t i;
-  grub_uint8_t old_color_normal, old_color_highlight;
-
-  title = entry ? entry->title : "";
-  title_len = grub_strlen (title);
-  unicode_title = grub_malloc (title_len * sizeof (*unicode_title));
-  if (! unicode_title)
-    /* XXX How to show this error?  */
-    return;
-
-  len = grub_utf8_to_ucs4 (unicode_title, title_len,
-                           (grub_uint8_t *) title, -1, 0);
-  if (len < 0)
-    {
-      /* It is an invalid sequence.  */
-      grub_free (unicode_title);
-      return;
-    }
-
-  grub_term_getcolor (term, &old_color_normal, &old_color_highlight);
-  grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
-  grub_term_setcolorstate (term, highlight
-                          ? GRUB_TERM_COLOR_HIGHLIGHT
-                          : GRUB_TERM_COLOR_NORMAL);
-
-  grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN, y);
-
-  for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, i = 0;
-       x < (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
-                 - GRUB_TERM_MARGIN);
-       i++)
-    {
-      if (i < len
-         && x <= (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
-                        - GRUB_TERM_MARGIN - 1))
-       {
-         grub_ssize_t width;
-
-         width = grub_term_getcharwidth (term, unicode_title[i]);
-
-         if (x + width > (int) (GRUB_TERM_LEFT_BORDER_X 
-                                + grub_term_border_width (term)
-                                - GRUB_TERM_MARGIN - 1))
-           grub_putcode (GRUB_TERM_DISP_RIGHT, term);
-         else
-           grub_putcode (unicode_title[i], term);
-
-         x += width;
-       }
-      else
-       {
-         grub_putcode (' ', term);
-         x++;
-       }
-    }
-  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
-  grub_putcode (' ', term);
-
-  grub_term_gotoxy (term, grub_term_cursor_x (term), y);
-
-  grub_term_setcolor (term, old_color_normal, old_color_highlight);
-  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
-  grub_free (unicode_title);
-}
-
-static void
-print_entries (grub_menu_t menu, int first, int offset,
-              struct grub_term_output *term)
-{
-  grub_menu_entry_t e;
-  int i;
-
-  grub_term_gotoxy (term,
-                   GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term),
-                   GRUB_TERM_FIRST_ENTRY_Y);
-
-  if (first)
-    grub_putcode (GRUB_TERM_DISP_UP, term);
-  else
-    grub_putcode (' ', term);
-
-  e = grub_menu_get_entry (menu, first);
-
-  for (i = 0; i < grub_term_num_entries (term); i++)
-    {
-      print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, offset == i, e, term);
-      if (e)
-       e = e->next;
-    }
-
-  grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X
-                   + grub_term_border_width (term),
-                   GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term));
-
-  if (e)
-    grub_putcode (GRUB_TERM_DISP_DOWN, term);
-  else
-    grub_putcode (' ', term);
-
-  grub_term_gotoxy (term, grub_term_cursor_x (term),
-                   GRUB_TERM_FIRST_ENTRY_Y + offset);
-}
-
-/* Initialize the screen.  If NESTED is non-zero, assume that this menu
-   is run from another menu or a command-line. If EDIT is non-zero, show
-   a message for the menu entry editor.  */
-void
-grub_menu_init_page (int nested, int edit,
-                    struct grub_term_output *term)
-{
-  grub_uint8_t old_color_normal, old_color_highlight;
-
-  grub_term_getcolor (term, &old_color_normal, &old_color_highlight);
-
-  /* By default, use the same colors for the menu.  */
-  grub_color_menu_normal = old_color_normal;
-  grub_color_menu_highlight = old_color_highlight;
-
-  /* Then give user a chance to replace them.  */
-  grub_parse_color_name_pair (&grub_color_menu_normal,
-                             grub_env_get ("menu_color_normal"));
-  grub_parse_color_name_pair (&grub_color_menu_highlight,
-                             grub_env_get ("menu_color_highlight"));
-
-  grub_normal_init_page (term);
-  grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
-  draw_border (term);
-  grub_term_setcolor (term, old_color_normal, old_color_highlight);
-  print_message (nested, edit, term);
-}
-
-static void
-menu_text_print_timeout (int timeout, void *dataptr)
-{
-  const char *msg =
-    _("The highlighted entry will be executed automatically in %ds.");
-  struct menu_viewer_data *data = dataptr;
-  char *msg_translated;
-  int posx;
-
-  grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
-
-  msg_translated = grub_xasprintf (msg, timeout);
-  if (!msg_translated)
-    {
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-      return;
-    }
-
-  grub_print_message_indented (msg_translated, 3, 0, data->term);
-  posx = grub_term_getxy (data->term) >> 8;
-  print_spaces (grub_term_width (data->term) - posx - 1, data->term);
-
-  grub_term_gotoxy (data->term,
-                   grub_term_cursor_x (data->term),
-                   GRUB_TERM_FIRST_ENTRY_Y + data->offset);
-  grub_term_refresh (data->term);
-}
-
-static void
-menu_text_set_chosen_entry (int entry, void *dataptr)
-{
-  struct menu_viewer_data *data = dataptr;
-  int oldoffset = data->offset;
-  int complete_redraw = 0;
-
-  data->offset = entry - data->first;
-  if (data->offset > grub_term_num_entries (data->term) - 1)
-    {
-      data->first = entry - (grub_term_num_entries (data->term) - 1);
-      data->offset = grub_term_num_entries (data->term) - 1;
-      complete_redraw = 1;
-    }
-  if (data->offset < 0)
-    {
-      data->offset = 0;
-      data->first = entry;
-      complete_redraw = 1;
-    }
-  if (complete_redraw)
-    print_entries (data->menu, data->first, data->offset, data->term);
-  else
-    {
-      print_entry (GRUB_TERM_FIRST_ENTRY_Y + oldoffset, 0,
-                  grub_menu_get_entry (data->menu, data->first + oldoffset),
-                  data->term);
-      print_entry (GRUB_TERM_FIRST_ENTRY_Y + data->offset, 1,
-                  grub_menu_get_entry (data->menu, data->first + data->offset),
-                  data->term);
-    }
-  grub_term_refresh (data->term);
-}
-
-static void
-menu_text_fini (void *dataptr)
-{
-  struct menu_viewer_data *data = dataptr;
-
-  grub_term_setcursor (data->term, 1);
-  grub_term_cls (data->term);
-
-}
-
-static void
-menu_text_clear_timeout (void *dataptr)
-{
-  struct menu_viewer_data *data = dataptr;
-
-  grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
-  print_spaces (grub_term_width (data->term) - 1, data->term);
-  grub_term_gotoxy (data->term, grub_term_cursor_x (data->term),
-                   GRUB_TERM_FIRST_ENTRY_Y + data->offset);
-  grub_term_refresh (data->term);
-}
-
-grub_err_t 
-grub_menu_try_text (struct grub_term_output *term, 
-                   int entry, grub_menu_t menu, int nested)
-{
-  struct menu_viewer_data *data;
-  struct grub_menu_viewer *instance;
-
-  instance = grub_zalloc (sizeof (*instance));
-  if (!instance)
-    return grub_errno;
-
-  data = grub_zalloc (sizeof (*data));
-  if (!data)
-    {
-      grub_free (instance);
-      return grub_errno;
-    }
-
-  data->term = term;
-  instance->data = data;
-  instance->set_chosen_entry = menu_text_set_chosen_entry;
-  instance->print_timeout = menu_text_print_timeout;
-  instance->clear_timeout = menu_text_clear_timeout;
-  instance->fini = menu_text_fini;
-
-  data->menu = menu;
-
-  data->offset = entry;
-  data->first = 0;
-  if (data->offset > grub_term_num_entries (data->term) - 1)
-    {
-      data->first = data->offset - (grub_term_num_entries (data->term) - 1);
-      data->offset = grub_term_num_entries (data->term) - 1;
-    }
-
-  grub_term_setcursor (data->term, 0);
-  grub_menu_init_page (nested, 0, data->term);
-  print_entries (menu, data->first, data->offset, data->term);
-  grub_term_refresh (data->term);
-  grub_menu_register_viewer (instance);
-
-  return GRUB_ERR_NONE;
-}
diff --git a/normal/misc.c b/normal/misc.c
deleted file mode 100644 (file)
index 17ba372..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/* misc.c - miscellaneous functions */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/normal.h>
-#include <grub/disk.h>
-#include <grub/fs.h>
-#include <grub/err.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/datetime.h>
-#include <grub/term.h>
-#include <grub/i18n.h>
-
-/* Print the information on the device NAME.  */
-grub_err_t
-grub_normal_print_device_info (const char *name)
-{
-  grub_device_t dev;
-  char *p;
-
-  p = grub_strchr (name, ',');
-  if (p)
-    {
-      grub_putchar ('\t');
-      grub_printf_ (N_("Partition %s:"), name);
-      grub_putchar (' ');
-    }
-  else
-    {
-      grub_printf_ (N_("Device %s:"), name);
-      grub_putchar (' ');
-    }
-
-  dev = grub_device_open (name);
-  if (! dev)
-    grub_printf ("%s", _("Filesystem cannot be accessed"));
-  else if (dev->disk)
-    {
-      grub_fs_t fs;
-
-      fs = grub_fs_probe (dev);
-      /* Ignore all errors.  */
-      grub_errno = 0;
-
-      if (fs)
-       {
-         grub_printf_ (N_("Filesystem type %s"), fs->name);
-         if (fs->label)
-           {
-             char *label;
-             (fs->label) (dev, &label);
-             if (grub_errno == GRUB_ERR_NONE)
-               {
-                 if (label && grub_strlen (label))
-                   {
-                     grub_putchar (' ');
-                     grub_printf_ (N_("- Label \"%s\""), label);
-                   }
-                 grub_free (label);
-               }
-             grub_errno = GRUB_ERR_NONE;
-           }
-         if (fs->mtime)
-           {
-             grub_int32_t tm;
-             struct grub_datetime datetime;
-             (fs->mtime) (dev, &tm);
-             if (grub_errno == GRUB_ERR_NONE)
-               {
-                 grub_unixtime2datetime (tm, &datetime);
-                 grub_putchar (' ');
-                 grub_printf_ (N_("- Last modification time %d-%02d-%02d "
-                              "%02d:%02d:%02d %s"),
-                              datetime.year, datetime.month, datetime.day,
-                              datetime.hour, datetime.minute, datetime.second,
-                              grub_get_weekday_name (&datetime));
-
-               }
-             grub_errno = GRUB_ERR_NONE;
-           }
-         if (fs->uuid)
-           {
-             char *uuid;
-             (fs->uuid) (dev, &uuid);
-             if (grub_errno == GRUB_ERR_NONE)
-               {
-                 if (uuid && grub_strlen (uuid))
-                   grub_printf (", UUID %s", uuid);
-                 grub_free (uuid);
-               }
-             grub_errno = GRUB_ERR_NONE;
-           }
-       }
-      else if (! dev->disk->has_partitions || dev->disk->partition)
-       grub_printf ("%s", _("Unknown filesystem"));
-      else
-       grub_printf ("%s", _("Partition table"));
-
-      grub_device_close (dev);
-    }
-
-  grub_putchar ('\n');
-  return grub_errno;
-}
diff --git a/normal/term.c b/normal/term.c
deleted file mode 100644 (file)
index 688141d..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/term.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/file.h>
-#include <grub/dl.h>
-#include <grub/env.h>
-#include <grub/normal.h>
-
-/* The amount of lines counted by the pager.  */
-static unsigned grub_more_lines;
-
-/* If the more pager is active.  */
-static int grub_more;
-
-static int grub_normal_line_counter = 0;
-
-int
-grub_normal_get_line_counter (void)
-{
-  return grub_normal_line_counter;
-}
-
-static void
-process_newline (void)
-{
-  struct grub_term_output *cur;
-  unsigned height = -1;
-
-  FOR_ACTIVE_TERM_OUTPUTS(cur)
-    if (grub_term_height (cur) < height)
-      height = grub_term_height (cur);
-  grub_more_lines++;
-
-  grub_normal_line_counter++;
-
-  if (grub_more && grub_more_lines >= height - 1)
-    {
-      char key;
-      grub_uint16_t *pos;
-
-      pos = grub_term_save_pos ();
-
-      grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
-      grub_printf ("--MORE--");
-      grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
-
-      key = grub_getkey ();
-
-      /* Remove the message.  */
-      grub_term_restore_pos (pos);
-      grub_printf ("        ");
-      grub_term_restore_pos (pos);
-
-      /* Scroll one lines or an entire page, depending on the key.  */
-      if (key == '\r' || key =='\n')
-       grub_more_lines = height - 2;
-      else
-       grub_more_lines = 0;
-    }
-}
-
-void
-grub_set_more (int onoff)
-{
-  if (onoff == 1)
-    grub_more++;
-  else
-    grub_more--;
-
-  grub_more_lines = 0;
-}
-
-void
-grub_install_newline_hook (void)
-{
-  grub_newline_hook = process_newline;
-}
-
-void
-grub_puts_terminal (const char *str, struct grub_term_output *term)
-{
-  grub_uint32_t code;
-  grub_ssize_t ret;
-  const grub_uint8_t *ptr = (const grub_uint8_t *) str;
-  const grub_uint8_t *end;
-  end = (const grub_uint8_t *) (str + grub_strlen (str));
-
-  while (*ptr)
-    {
-      ret = grub_utf8_to_ucs4 (&code, 1, ptr, end - ptr, &ptr);
-      grub_putcode (code, term);       
-    }
-}
-
-grub_uint16_t *
-grub_term_save_pos (void)
-{
-  struct grub_term_output *cur;
-  unsigned cnt = 0;
-  grub_uint16_t *ret, *ptr;
-  
-  FOR_ACTIVE_TERM_OUTPUTS(cur)
-    cnt++;
-
-  ret = grub_malloc (cnt * sizeof (ret[0]));
-  if (!ret)
-    return NULL;
-
-  ptr = ret;
-  FOR_ACTIVE_TERM_OUTPUTS(cur)
-    *ptr++ = grub_term_getxy (cur);
-
-  return ret;
-}
-
-void
-grub_term_restore_pos (grub_uint16_t *pos)
-{
-  struct grub_term_output *cur;
-  grub_uint16_t *ptr = pos;
-
-  if (!pos)
-    return;
-
-  FOR_ACTIVE_TERM_OUTPUTS(cur)
-  {
-    grub_term_gotoxy (cur, (*ptr & 0xff00) >> 8, *ptr & 0xff);
-    ptr++;
-  }
-}
-
-static void 
-grub_terminal_autoload_free (void)
-{
-  struct grub_term_autoload *cur, *next;
-  unsigned i;
-  for (i = 0; i < 2; i++)
-    for (cur = i ? grub_term_input_autoload : grub_term_output_autoload;
-        cur; cur = next)
-      {
-       next = cur->next;
-       grub_free (cur->name);
-       grub_free (cur->modname);
-       grub_free (cur);
-      }
-  grub_term_input_autoload = NULL;
-  grub_term_output_autoload = NULL;
-}
-
-/* Read the file terminal.lst for auto-loading.  */
-void
-read_terminal_list (const char *prefix)
-{
-  char *filename;
-  grub_file_t file;
-  char *buf = NULL;
-
-  if (!prefix)
-    {
-      grub_errno = GRUB_ERR_NONE;
-      return;
-    }
-  
-  filename = grub_xasprintf ("%s/terminal.lst", prefix);
-  if (!filename)
-    {
-      grub_errno = GRUB_ERR_NONE;
-      return;
-    }
-
-  file = grub_file_open (filename);
-  grub_free (filename);
-  if (!file)
-    {
-      grub_errno = GRUB_ERR_NONE;
-      return;
-    }
-
-  /* Override previous terminal.lst.  */
-  grub_terminal_autoload_free ();
-
-  for (;; grub_free (buf))
-    {
-      char *p, *name;
-      struct grub_term_autoload *cur;
-      struct grub_term_autoload **target = NULL;
-      
-      buf = grub_file_getline (file);
-       
-      if (! buf)
-       break;
-
-      switch (buf[0])
-       {
-       case 'i':
-         target = &grub_term_input_autoload;
-         break;
-
-       case 'o':
-         target = &grub_term_output_autoload;
-         break;
-       }
-      if (!target)
-       continue;
-      
-      name = buf + 1;
-            
-      p = grub_strchr (name, ':');
-      if (! p)
-       continue;
-      
-      *p = '\0';
-      while (*++p == ' ')
-       ;
-
-      cur = grub_malloc (sizeof (*cur));
-      if (!cur)
-       {
-         grub_errno = GRUB_ERR_NONE;
-         continue;
-       }
-      
-      cur->name = grub_strdup (name);
-      if (! name)
-       {
-         grub_errno = GRUB_ERR_NONE;
-         grub_free (cur);
-         continue;
-       }
-       
-      cur->modname = grub_strdup (p);
-      if (! cur->modname)
-       {
-         grub_errno = GRUB_ERR_NONE;
-         grub_free (cur);
-         grub_free (cur->name);
-         continue;
-       }
-      cur->next = *target;
-      *target = cur;
-    }
-  
-  grub_file_close (file);
-
-  grub_errno = GRUB_ERR_NONE;
-}
diff --git a/partmap/acorn.c b/partmap/acorn.c
deleted file mode 100644 (file)
index 677ec61..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/* acorn.c - Read Linux/ADFS partition tables.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/disk.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/partition.h>
-#include <grub/acorn_filecore.h>
-
-#define LINUX_NATIVE_MAGIC grub_cpu_to_le32 (0xdeafa1de)
-#define LINUX_SWAP_MAGIC   grub_cpu_to_le32 (0xdeafab1e)
-#define LINUX_MAP_ENTRIES  (512 / 12)
-
-#define NONADFS_PARTITION_TYPE_LINUX 9
-#define NONADFS_PARTITION_TYPE_MASK 15
-
-struct grub_acorn_boot_block
-{
-  grub_uint8_t misc[0x1C0];
-  struct grub_filecore_disc_record disc_record;
-  grub_uint8_t flags;
-  grub_uint16_t start_cylinder;
-  grub_uint8_t checksum;
-} __attribute__ ((packed, aligned));
-
-struct linux_part
-{
-  grub_uint32_t magic;
-  grub_uint32_t start;
-  grub_uint32_t size;
-};
-
-static struct grub_partition_map grub_acorn_partition_map;
-
-static grub_err_t
-acorn_partition_map_find (grub_disk_t disk, struct linux_part *m,
-                         grub_disk_addr_t *sector)
-{
-  struct grub_acorn_boot_block boot;
-  grub_err_t err;
-  unsigned int checksum = 0;
-  unsigned int heads;
-  unsigned int sectors_per_cylinder;
-  int i;
-
-  err = grub_disk_read (disk, 0xC00 / GRUB_DISK_SECTOR_SIZE, 0,
-                       sizeof (struct grub_acorn_boot_block),
-                       &boot);
-  if (err)
-    return err;
-
-  if ((boot.flags & NONADFS_PARTITION_TYPE_MASK) != NONADFS_PARTITION_TYPE_LINUX)
-    goto fail;
-
-  for (i = 0; i != 0x1ff; ++i)
-    checksum = (checksum & 0xff) + (checksum >> 8) + boot.misc[i];
-
-  if ((grub_uint8_t) checksum != boot.checksum)
-    goto fail;
-
-  heads = (boot.disc_record.heads
-                   + ((boot.disc_record.lowsector >> 6) & 1));
-  sectors_per_cylinder = boot.disc_record.secspertrack * heads;
-  *sector = grub_le_to_cpu16 (boot.start_cylinder) * sectors_per_cylinder;
-
-  return grub_disk_read (disk, *sector, 0,
-                        sizeof (struct linux_part) * LINUX_MAP_ENTRIES,
-                        m);
-
-fail:
-  return grub_error (GRUB_ERR_BAD_PART_TABLE,
-                    "Linux/ADFS partition map not found");
-
-}
-
-
-static grub_err_t
-acorn_partition_map_iterate (grub_disk_t disk,
-                            int (*hook) (grub_disk_t disk,
-                                         const grub_partition_t partition))
-{
-  struct grub_partition part;
-  struct linux_part map[LINUX_MAP_ENTRIES];
-  int i;
-  grub_disk_addr_t sector = 0;
-  grub_err_t err;
-
-  err = acorn_partition_map_find (disk, map, &sector);
-  if (err)
-    return err;
-
-  part.partmap = &grub_acorn_partition_map;
-
-  for (i = 0; i != LINUX_MAP_ENTRIES; ++i)
-    {
-      if (map[i].magic != LINUX_NATIVE_MAGIC
-         && map[i].magic != LINUX_SWAP_MAGIC)
-       return GRUB_ERR_NONE;
-
-      part.start = sector + map[i].start;
-      part.len = map[i].size;
-      part.offset = 6;
-      part.number = part.index = i;
-
-      if (hook (disk, &part))
-       return grub_errno;
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-\f
-
-/* Partition map type.  */
-static struct grub_partition_map grub_acorn_partition_map =
-{
-  .name = "acorn",
-  .iterate = acorn_partition_map_iterate,
-};
-
-GRUB_MOD_INIT(part_acorn)
-{
-  grub_partition_map_register (&grub_acorn_partition_map);
-}
-
-GRUB_MOD_FINI(part_acorn)
-{
-  grub_partition_map_unregister (&grub_acorn_partition_map);
-}
diff --git a/partmap/amiga.c b/partmap/amiga.c
deleted file mode 100644 (file)
index f21c5b2..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/* amiga.c - Read amiga partition tables (RDB).  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2005,2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/disk.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/partition.h>
-#include <grub/dl.h>
-
-struct grub_amiga_rdsk
-{
-  /* "RDSK".  */
-  grub_uint8_t magic[4];
-  grub_uint32_t size;
-  grub_int32_t checksum;
-  grub_uint32_t scsihost;
-  grub_uint32_t blksz;
-  grub_uint32_t flags;
-  grub_uint32_t badblcklst;
-  grub_uint32_t partitionlst;
-  grub_uint32_t fslst;
-
-  /* The other information is not important for us.  */
-} __attribute__ ((packed));
-
-struct grub_amiga_partition
-{
-  /* "PART".  */
-  grub_uint8_t magic[4];
-  grub_int32_t size;
-  grub_int32_t checksum;
-  grub_uint32_t scsihost;
-  grub_uint32_t next;
-  grub_uint32_t flags;
-  grub_uint32_t unused1[2];
-  grub_uint32_t devflags;
-  grub_uint8_t namelen;
-  grub_uint8_t name[31];
-  grub_uint32_t unused2[15];
-
-  grub_uint32_t unused3[3];
-  grub_uint32_t heads;
-  grub_uint32_t unused4;
-  grub_uint32_t block_per_track;
-  grub_uint32_t unused5[3];
-  grub_uint32_t lowcyl;
-  grub_uint32_t highcyl;
-
-  grub_uint32_t firstcyl;
-} __attribute__ ((packed));
-
-static struct grub_partition_map grub_amiga_partition_map;
-
-\f
-
-static grub_err_t
-amiga_partition_map_iterate (grub_disk_t disk,
-                            int (*hook) (grub_disk_t disk,
-                                         const grub_partition_t partition))
-{
-  struct grub_partition part;
-  struct grub_amiga_rdsk rdsk;
-  int partno = 0;
-  int next = -1;
-  unsigned pos;
-
-  /* The RDSK block is one of the first 15 blocks.  */
-  for (pos = 0; pos < 15; pos++)
-    {
-      /* Read the RDSK block which is a descriptor for the entire disk.  */
-      if (grub_disk_read (disk, pos, 0, sizeof (rdsk), &rdsk))
-       return grub_errno;
-
-      if (grub_strcmp ((char *) rdsk.magic, "RDSK") == 0)
-       {
-         /* Found the first PART block.  */
-         next = grub_be_to_cpu32 (rdsk.partitionlst);
-         break;
-       }
-    }
-
-  if (next == -1)
-    return grub_error (GRUB_ERR_BAD_PART_TABLE,
-                      "Amiga partition map not found");
-
-  /* The end of the partition list is marked using "-1".  */
-  while (next != -1)
-    {
-      struct grub_amiga_partition apart;
-
-      /* Read the RDSK block which is a descriptor for the entire disk.  */
-      if (grub_disk_read (disk, next, 0, sizeof (apart), &apart))
-       return grub_errno;
-
-      /* Calculate the first block and the size of the partition.  */
-      part.start = (grub_be_to_cpu32 (apart.lowcyl)
-                   * grub_be_to_cpu32 (apart.heads)
-                   * grub_be_to_cpu32 (apart.block_per_track));
-      part.len = ((grub_be_to_cpu32 (apart.highcyl)
-                  - grub_be_to_cpu32 (apart.lowcyl) + 1)
-                 * grub_be_to_cpu32 (apart.heads)
-                 * grub_be_to_cpu32 (apart.block_per_track));
-
-      part.offset = (grub_off_t) next * 512;
-      part.number = partno;
-      part.index = 0;
-      part.partmap = &grub_amiga_partition_map;
-
-      if (hook (disk, &part))
-       return grub_errno;
-
-      next = grub_be_to_cpu32 (apart.next);
-      partno++;
-    }
-
-  return 0;
-}
-
-\f
-/* Partition map type.  */
-static struct grub_partition_map grub_amiga_partition_map =
-  {
-    .name = "amiga",
-    .iterate = amiga_partition_map_iterate,
-  };
-
-GRUB_MOD_INIT(part_amiga)
-{
-  grub_partition_map_register (&grub_amiga_partition_map);
-}
-
-GRUB_MOD_FINI(part_amiga)
-{
-  grub_partition_map_unregister (&grub_amiga_partition_map);
-}
diff --git a/partmap/apple.c b/partmap/apple.c
deleted file mode 100644 (file)
index e162d18..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/* apple.c - Read macintosh partition tables.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/disk.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/partition.h>
-
-#define GRUB_APPLE_HEADER_MAGIC        0x4552
-#define GRUB_APPLE_PART_MAGIC  0x504D
-
-struct grub_apple_header
-{
-  /* The magic number to identify the partition map, it should have
-     the value `0x4552'.  */
-  grub_uint16_t magic;
-  grub_uint16_t blocksize;
-};
-
-struct grub_apple_part
-{
-  /* The magic number to identify this as a partition, it should have
-     the value `0x504D'.  */
-  grub_uint16_t magic;
-
-  /* Reserved.  */
-  grub_uint16_t reserved;
-
-  /* The size of the partition map in blocks.  */
-  grub_uint32_t partmap_size;
-
-  /* The first physical block of the partition.  */
-  grub_uint32_t first_phys_block;
-
-  /* The amount of blocks.  */
-  grub_uint32_t blockcnt;
-
-  /* The partition name.  */
-  char partname[32];
-
-  /* The partition type.  */
-  char parttype[32];
-
-  /* The first datablock of the partition.  */
-  grub_uint32_t datablocks_first;
-
-  /* The amount datablocks.  */
-  grub_uint32_t datablocks_count;
-
-  /* The status of the partition. (???)  */
-  grub_uint32_t status;
-
-  /* The first block on which the bootcode can be found.  */
-  grub_uint32_t bootcode_pos;
-
-  /* The size of the bootcode in bytes.  */
-  grub_uint32_t bootcode_size;
-
-  /* The load address of the bootcode.  */
-  grub_uint32_t bootcode_loadaddr;
-
-  /* Reserved.  */
-  grub_uint32_t reserved2;
-
-  /* The entry point of the bootcode.  */
-  grub_uint32_t bootcode_entrypoint;
-
-  /* Reserved.  */
-  grub_uint32_t reserved3;
-
-  /* A checksum of the bootcode.  */
-  grub_uint32_t bootcode_checksum;
-
-  /* The processor type.  */
-  char processor[16];
-
-  /* Padding.  */
-  grub_uint16_t pad[187];
-};
-
-static struct grub_partition_map grub_apple_partition_map;
-\f
-
-static grub_err_t
-apple_partition_map_iterate (grub_disk_t disk,
-                            int (*hook) (grub_disk_t disk,
-                                         const grub_partition_t partition))
-{
-  struct grub_partition part;
-  struct grub_apple_header aheader;
-  struct grub_apple_part apart;
-  int partno = 0, partnum = 0;
-  unsigned pos;
-
-  part.partmap = &grub_apple_partition_map;
-
-  if (grub_disk_read (disk, 0, 0, sizeof (aheader), &aheader))
-    return grub_errno;
-
-  if (grub_be_to_cpu16 (aheader.magic) != GRUB_APPLE_HEADER_MAGIC)
-    {
-      grub_dprintf ("partition",
-                   "bad magic (found 0x%x; wanted 0x%x\n",
-                   grub_be_to_cpu16 (aheader.magic),
-                   GRUB_APPLE_HEADER_MAGIC);
-      goto fail;
-    }
-
-  pos = grub_be_to_cpu16 (aheader.blocksize);
-
-  do
-    {
-      part.offset = pos / GRUB_DISK_SECTOR_SIZE;
-      part.index = pos % GRUB_DISK_SECTOR_SIZE;
-
-      if (grub_disk_read (disk, part.offset, part.index,
-                         sizeof (struct grub_apple_part),  &apart))
-       return grub_errno;
-
-      if (grub_be_to_cpu16 (apart.magic) != GRUB_APPLE_PART_MAGIC)
-       {
-         grub_dprintf ("partition",
-                       "partition %d: bad magic (found 0x%x; wanted 0x%x\n",
-                       partno, grub_be_to_cpu16 (apart.magic),
-                       GRUB_APPLE_PART_MAGIC);
-         break;
-       }
-
-      if (partnum == 0)
-       partnum = grub_be_to_cpu32 (apart.partmap_size);
-
-      part.start = ((grub_disk_addr_t) grub_be_to_cpu32 (apart.first_phys_block)
-                   * grub_be_to_cpu16 (aheader.blocksize))
-       / GRUB_DISK_SECTOR_SIZE;
-      part.len = ((grub_disk_addr_t) grub_be_to_cpu32 (apart.blockcnt)
-                 * grub_be_to_cpu16 (aheader.blocksize))
-       / GRUB_DISK_SECTOR_SIZE;
-      part.offset = pos;
-      part.index = partno;
-      part.number = partno;
-
-      grub_dprintf ("partition",
-                   "partition %d: name %s, type %s, start 0x%x, len 0x%x\n",
-                   partno, apart.partname, apart.parttype,
-                   grub_be_to_cpu32 (apart.first_phys_block),
-                   grub_be_to_cpu32 (apart.blockcnt));
-
-      if (hook (disk, &part))
-       return grub_errno;
-
-      pos += grub_be_to_cpu16 (aheader.blocksize);
-      partno++;
-    }
-  while (partno < partnum);
-
-  if (partno != 0)
-    return 0;
-
- fail:
-  return grub_error (GRUB_ERR_BAD_PART_TABLE,
-                    "Apple partition map not found");
-}
-
-\f
-/* Partition map type.  */
-static struct grub_partition_map grub_apple_partition_map =
-  {
-    .name = "apple",
-    .iterate = apple_partition_map_iterate,
-  };
-
-GRUB_MOD_INIT(part_apple)
-{
-  grub_partition_map_register (&grub_apple_partition_map);
-}
-
-GRUB_MOD_FINI(part_apple)
-{
-  grub_partition_map_unregister (&grub_apple_partition_map);
-}
-
diff --git a/partmap/bsdlabel.c b/partmap/bsdlabel.c
deleted file mode 100644 (file)
index d28f36d..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/* bsdlabel.c - Read BSD style partition tables.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/partition.h>
-#include <grub/bsdlabel.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/dl.h>
-
-static struct grub_partition_map grub_bsdlabel_partition_map;
-\f
-
-static grub_err_t
-bsdlabel_partition_map_iterate (grub_disk_t disk,
-                               int (*hook) (grub_disk_t disk,
-                                            const grub_partition_t partition))
-{
-  struct grub_partition_bsd_disk_label label;
-  struct grub_partition p;
-  grub_disk_addr_t delta = 0;
-  unsigned pos;
-
-  /* BSDLabel offsets are absolute even when it's embed inside partition.  */
-  delta = grub_partition_get_start (disk->partition);
-
-  /* Read the BSD label.  */
-  if (grub_disk_read (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR,
-                     0, sizeof (label), &label))
-    return grub_errno;
-
-  /* Check if it is valid.  */
-  if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC))
-    return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
-
-  pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR
-    * GRUB_DISK_SECTOR_SIZE;
-
-  for (p.number = 0;
-       p.number < grub_cpu_to_le16 (label.num_partitions);
-       p.number++)
-    {
-      struct grub_partition_bsd_entry be;
-
-      p.offset = pos / GRUB_DISK_SECTOR_SIZE;
-      p.index = pos % GRUB_DISK_SECTOR_SIZE;
-
-      if (grub_disk_read (disk, p.offset, p.index, sizeof (be),  &be))
-       return grub_errno;
-
-      p.start = grub_le_to_cpu32 (be.offset) - delta;
-      p.len = grub_le_to_cpu32 (be.size);
-      p.partmap = &grub_bsdlabel_partition_map;
-
-      if (be.fs_type != GRUB_PC_PARTITION_BSD_TYPE_UNUSED)
-       if (hook (disk, &p))
-         return grub_errno;
-
-      pos += sizeof (struct grub_partition_bsd_entry);
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-\f
-/* Partition map type.  */
-static struct grub_partition_map grub_bsdlabel_partition_map =
-  {
-    .name = "bsd",
-    .iterate = bsdlabel_partition_map_iterate,
-  };
-
-GRUB_MOD_INIT(part_bsd)
-{
-  grub_partition_map_register (&grub_bsdlabel_partition_map);
-}
-
-GRUB_MOD_FINI(part_bsd)
-{
-  grub_partition_map_unregister (&grub_bsdlabel_partition_map);
-}
diff --git a/partmap/gpt.c b/partmap/gpt.c
deleted file mode 100644 (file)
index 9dd88be..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/* gpt.c - Read GUID Partition Tables (GPT).  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/disk.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/partition.h>
-#include <grub/dl.h>
-#include <grub/msdos_partition.h>
-#include <grub/gpt_partition.h>
-
-static grub_uint8_t grub_gpt_magic[8] =
-  {
-    0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54
-  };
-
-static const grub_gpt_part_type_t grub_gpt_partition_type_empty = GRUB_GPT_PARTITION_TYPE_EMPTY;
-
-static struct grub_partition_map grub_gpt_partition_map;
-
-\f
-
-static grub_err_t
-gpt_partition_map_iterate (grub_disk_t disk,
-                          int (*hook) (grub_disk_t disk,
-                                       const grub_partition_t partition))
-{
-  struct grub_partition part;
-  struct grub_gpt_header gpt;
-  struct grub_gpt_partentry entry;
-  struct grub_msdos_partition_mbr mbr;
-  grub_uint64_t entries;
-  unsigned int i;
-  int last_offset = 0;
-
-  /* Read the protective MBR.  */
-  if (grub_disk_read (disk, 0, 0, sizeof (mbr), &mbr))
-    return grub_errno;
-
-  /* Check if it is valid.  */
-  if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE))
-    return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
-
-  /* Make sure the MBR is a protective MBR and not a normal MBR.  */
-  if (mbr.entries[0].type != GRUB_PC_PARTITION_TYPE_GPT_DISK)
-    return grub_error (GRUB_ERR_BAD_PART_TABLE, "no GPT partition map found");
-
-  /* Read the GPT header.  */
-  if (grub_disk_read (disk, 1, 0, sizeof (gpt), &gpt))
-    return grub_errno;
-
-  if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic)))
-    return grub_error (GRUB_ERR_BAD_PART_TABLE, "no valid GPT header");
-
-  grub_dprintf ("gpt", "Read a valid GPT header\n");
-
-  entries = grub_le_to_cpu64 (gpt.partitions);
-  for (i = 0; i < grub_le_to_cpu32 (gpt.maxpart); i++)
-    {
-      if (grub_disk_read (disk, entries, last_offset,
-                         sizeof (entry), &entry))
-       return grub_errno;
-
-      if (grub_memcmp (&grub_gpt_partition_type_empty, &entry.type,
-                      sizeof (grub_gpt_partition_type_empty)))
-       {
-         /* Calculate the first block and the size of the partition.  */
-         part.start = grub_le_to_cpu64 (entry.start);
-         part.len = (grub_le_to_cpu64 (entry.end)
-                     - grub_le_to_cpu64 (entry.start) + 1);
-         part.offset = entries;
-         part.number = i;
-         part.index = last_offset;
-         part.partmap = &grub_gpt_partition_map;
-
-         grub_dprintf ("gpt", "GPT entry %d: start=%lld, length=%lld\n", i,
-                       (unsigned long long) part.start,
-                       (unsigned long long) part.len);
-
-         if (hook (disk, &part))
-           return grub_errno;
-       }
-
-      last_offset += grub_le_to_cpu32 (gpt.partentry_size);
-      if (last_offset == GRUB_DISK_SECTOR_SIZE)
-       {
-         last_offset = 0;
-         entries++;
-       }
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-\f
-/* Partition map type.  */
-static struct grub_partition_map grub_gpt_partition_map =
-  {
-    .name = "gpt",
-    .iterate = gpt_partition_map_iterate,
-  };
-
-GRUB_MOD_INIT(part_gpt)
-{
-  grub_partition_map_register (&grub_gpt_partition_map);
-}
-
-GRUB_MOD_FINI(part_gpt)
-{
-  grub_partition_map_unregister (&grub_gpt_partition_map);
-}
diff --git a/partmap/msdos.c b/partmap/msdos.c
deleted file mode 100644 (file)
index 3898d09..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/* pc.c - Read PC style partition tables.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/partition.h>
-#include <grub/msdos_partition.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/dl.h>
-
-static struct grub_partition_map grub_msdos_partition_map;
-\f
-
-static grub_err_t
-pc_partition_map_iterate (grub_disk_t disk,
-                         int (*hook) (grub_disk_t disk,
-                                      const grub_partition_t partition))
-{
-  struct grub_partition p;
-  struct grub_msdos_partition_mbr mbr;
-  int labeln = 0;
-  grub_disk_addr_t lastaddr;
-  grub_disk_addr_t ext_offset;
-
-  p.offset = 0;
-  ext_offset = 0;
-  p.number = -1;
-  p.partmap = &grub_msdos_partition_map;
-
-  /* Any value different than `p.offset' will satisfy the check during
-     first loop.  */
-  lastaddr = !p.offset;
-
-  while (1)
-    {
-      int i;
-      struct grub_msdos_partition_entry *e;
-
-      /* Read the MBR.  */
-      if (grub_disk_read (disk, p.offset, 0, sizeof (mbr), &mbr))
-       goto finish;
-
-      /* This is our loop-detection algorithm. It works the following way:
-        It saves last position which was a power of two. Then it compares the
-        saved value with a current one. This way it's guaranteed that the loop
-        will be broken by at most third walk.
-       */
-      if (labeln && lastaddr == p.offset)
-       return grub_error (GRUB_ERR_BAD_PART_TABLE, "loop detected");
-
-      labeln++;
-      if ((labeln & (labeln - 1)) == 0)
-       lastaddr = p.offset;
-
-      /* Check if it is valid.  */
-      if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE))
-       return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
-
-      for (i = 0; i < 4; i++)
-       if (mbr.entries[i].flag & 0x7f)
-         return grub_error (GRUB_ERR_BAD_PART_TABLE, "bad boot flag");
-
-      /* Analyze DOS partitions.  */
-      for (p.index = 0; p.index < 4; p.index++)
-       {
-         e = mbr.entries + p.index;
-
-         p.start = p.offset + grub_le_to_cpu32 (e->start);
-         p.len = grub_le_to_cpu32 (e->length);
-
-         grub_dprintf ("partition",
-                       "partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n",
-                       p.index, e->flag, e->type,
-                       (unsigned long long) p.start,
-                       (unsigned long long) p.len);
-
-         /* If this is a GPT partition, this MBR is just a dummy.  */
-         if (e->type == GRUB_PC_PARTITION_TYPE_GPT_DISK && p.index == 0)
-           return grub_error (GRUB_ERR_BAD_PART_TABLE, "dummy mbr");
-
-         /* If this partition is a normal one, call the hook.  */
-         if (! grub_msdos_partition_is_empty (e->type)
-             && ! grub_msdos_partition_is_extended (e->type))
-           {
-             p.number++;
-
-             if (hook (disk, &p))
-               return grub_errno;
-           }
-         else if (p.number < 4)
-           /* If this partition is a logical one, shouldn't increase the
-              partition number.  */
-           p.number++;
-       }
-
-      /* Find an extended partition.  */
-      for (i = 0; i < 4; i++)
-       {
-         e = mbr.entries + i;
-
-         if (grub_msdos_partition_is_extended (e->type))
-           {
-             p.offset = ext_offset + grub_le_to_cpu32 (e->start);
-             if (! ext_offset)
-               ext_offset = p.offset;
-
-             break;
-           }
-       }
-
-      /* If no extended partition, the end.  */
-      if (i == 4)
-       break;
-    }
-
- finish:
-  return grub_errno;
-}
-
-\f
-/* Partition map type.  */
-static struct grub_partition_map grub_msdos_partition_map =
-  {
-    .name = "msdos",
-    .iterate = pc_partition_map_iterate,
-  };
-
-GRUB_MOD_INIT(part_msdos)
-{
-  grub_partition_map_register (&grub_msdos_partition_map);
-}
-
-GRUB_MOD_FINI(part_msdos)
-{
-  grub_partition_map_unregister (&grub_msdos_partition_map);
-}
diff --git a/partmap/sun.c b/partmap/sun.c
deleted file mode 100644 (file)
index 7a7eaef..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/* sun.c - Read SUN style partition tables.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/partition.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/dl.h>
-#include <grub/symbol.h>
-#include <grub/types.h>
-#include <grub/err.h>
-
-#define GRUB_PARTMAP_SUN_MAGIC 0xDABE
-#define GRUB_PARTMAP_SUN_MAX_PARTS 8
-#define GRUB_PARTMAP_SUN_WHOLE_DISK_ID 0x05
-
-struct grub_sun_partition_info
-{
-  grub_uint8_t spare1;
-  grub_uint8_t id;
-  grub_uint8_t spare2;
-  grub_uint8_t flags;
-} __attribute__ ((packed));
-
-struct grub_sun_partition_descriptor
-{
-  grub_uint32_t start_cylinder;
-  grub_uint32_t num_sectors;
-} __attribute__ ((packed));
-
-struct grub_sun_block
-{
-  grub_uint8_t  info[128];      /* Informative text string.  */
-  grub_uint8_t  spare0[14];
-  struct grub_sun_partition_info infos[8];
-  grub_uint8_t  spare1[246];    /* Boot information etc.  */
-  grub_uint16_t  rspeed;        /* Disk rotational speed.  */
-  grub_uint16_t  pcylcount;     /* Physical cylinder count.  */
-  grub_uint16_t  sparecyl;      /* extra sects per cylinder.  */
-  grub_uint8_t  spare2[4];      /* More magic...  */
-  grub_uint16_t  ilfact;        /* Interleave factor.  */
-  grub_uint16_t  ncyl;          /* Data cylinder count.  */
-  grub_uint16_t  nacyl;         /* Alt. cylinder count.  */
-  grub_uint16_t  ntrks;         /* Tracks per cylinder.  */
-  grub_uint16_t  nsect;         /* Sectors per track.  */
-  grub_uint8_t  spare3[4];      /* Even more magic...  */
-  struct grub_sun_partition_descriptor partitions[8];
-  grub_uint16_t  magic;         /* Magic number.  */
-  grub_uint16_t  csum;          /* Label xor'd checksum.  */
-} __attribute__ ((packed));
-
-static struct grub_partition_map grub_sun_partition_map;
-
-/* Verify checksum (true=ok).  */
-static int
-grub_sun_is_valid (struct grub_sun_block *label)
-{
-  grub_uint16_t *pos;
-  grub_uint16_t sum = 0;
-
-  for (pos = (grub_uint16_t *) label;
-       pos < (grub_uint16_t *) (label + 1);
-       pos++)
-    sum ^= *pos;
-
-  return ! sum;
-}
-
-static grub_err_t
-sun_partition_map_iterate (grub_disk_t disk,
-                           int (*hook) (grub_disk_t disk,
-                                       const grub_partition_t partition))
-{
-  grub_partition_t p;
-  struct grub_sun_block block;
-  int partnum;
-  grub_err_t err;
-
-  p = (grub_partition_t) grub_zalloc (sizeof (struct grub_partition));
-  if (! p)
-    return grub_errno;
-
-  p->partmap = &grub_sun_partition_map;
-  err = grub_disk_read (disk, 0, 0, sizeof (struct grub_sun_block),
-                       &block);
-  if (err)
-    {
-      grub_free (p);
-      return err;
-    }
-
-  if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.magic))
-    {
-      grub_free (p);
-      return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a sun partition table");
-    }
-
-  if (! grub_sun_is_valid (&block))
-    {
-      grub_free (p);      
-      return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum");
-    }
-
-  /* Maybe another error value would be better, because partition
-     table _is_ recognized but invalid.  */
-  for (partnum = 0; partnum < GRUB_PARTMAP_SUN_MAX_PARTS; partnum++)
-    {
-      struct grub_sun_partition_descriptor *desc;
-
-      if (block.infos[partnum].id == 0
-         || block.infos[partnum].id == GRUB_PARTMAP_SUN_WHOLE_DISK_ID)
-       continue;
-
-      desc = &block.partitions[partnum];
-      p->start = ((grub_uint64_t) grub_be_to_cpu32 (desc->start_cylinder)
-                 * grub_be_to_cpu16 (block.ntrks)
-                 * grub_be_to_cpu16 (block.nsect));
-      p->len = grub_be_to_cpu32 (desc->num_sectors);
-      p->number = p->index = partnum;
-      if (p->len)
-       {
-         if (hook (disk, p))
-           partnum = GRUB_PARTMAP_SUN_MAX_PARTS;
-       }
-    }
-
-  grub_free (p);
-
-  return grub_errno;
-}
-
-/* Partition map type.  */
-static struct grub_partition_map grub_sun_partition_map =
-  {
-    .name = "sun",
-    .iterate = sun_partition_map_iterate,
-  };
-
-GRUB_MOD_INIT(part_sun)
-{
-  grub_partition_map_register (&grub_sun_partition_map);
-}
-
-GRUB_MOD_FINI(part_sun)
-{
-  grub_partition_map_unregister (&grub_sun_partition_map);
-}
-
diff --git a/partmap/sunpc.c b/partmap/sunpc.c
deleted file mode 100644 (file)
index ea69c28..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/* sunpc.c - Read SUN PC style partition tables.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2005,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/partition.h>
-#include <grub/disk.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/dl.h>
-#include <grub/symbol.h>
-#include <grub/types.h>
-#include <grub/err.h>
-
-#define GRUB_PARTMAP_SUN_PC_MAGIC 0xDABE
-#define GRUB_PARTMAP_SUN_PC_MAX_PARTS 16
-#define GRUB_PARTMAP_SUN_PC_WHOLE_DISK_ID 0x05
-
-struct grub_sun_pc_partition_descriptor
-{
-  grub_uint16_t id;
-  grub_uint16_t unused;
-  grub_uint32_t start_sector;
-  grub_uint32_t num_sectors;
-} __attribute__ ((packed));
-
-struct grub_sun_pc_block
-{
-  grub_uint8_t unused[72];
-  struct grub_sun_pc_partition_descriptor partitions[GRUB_PARTMAP_SUN_PC_MAX_PARTS];
-  grub_uint8_t unused2[244];
-  grub_uint16_t  magic;         /* Magic number.  */
-  grub_uint16_t  csum;          /* Label xor'd checksum.  */
-} __attribute__ ((packed));
-
-static struct grub_partition_map grub_sun_pc_partition_map;
-
-/* Verify checksum (true=ok).  */
-static int
-grub_sun_is_valid (struct grub_sun_pc_block *label)
-{
-  grub_uint16_t *pos;
-  grub_uint16_t sum = 0;
-
-  for (pos = (grub_uint16_t *) label;
-       pos < (grub_uint16_t *) (label + 1);
-       pos++)
-    sum ^= *pos;
-
-  return ! sum;
-}
-
-static grub_err_t
-sun_pc_partition_map_iterate (grub_disk_t disk,
-                             int (*hook) (grub_disk_t disk,
-                                          const grub_partition_t partition))
-{
-  grub_partition_t p;
-  struct grub_sun_pc_block block;
-  int partnum;
-  grub_err_t err;
-
-  p = (grub_partition_t) grub_zalloc (sizeof (struct grub_partition));
-  if (! p)
-    return grub_errno;
-
-  p->partmap = &grub_sun_pc_partition_map;
-  err = grub_disk_read (disk, 1, 0, sizeof (struct grub_sun_pc_block), &block);
-  if (err)
-    {
-      grub_free (p);
-      return err;
-    }
-  
-  if (GRUB_PARTMAP_SUN_PC_MAGIC != grub_le_to_cpu16 (block.magic))
-    {
-      grub_free (p);
-      return grub_error (GRUB_ERR_BAD_PART_TABLE, 
-                        "not a sun_pc partition table");
-    }
-
-  if (! grub_sun_is_valid (&block))
-    {
-      grub_free (p);
-      return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum");
-    }
-
-  /* Maybe another error value would be better, because partition
-     table _is_ recognized but invalid.  */
-  for (partnum = 0; partnum < GRUB_PARTMAP_SUN_PC_MAX_PARTS; partnum++)
-    {
-      struct grub_sun_pc_partition_descriptor *desc;
-
-      if (block.partitions[partnum].id == 0
-         || block.partitions[partnum].id == GRUB_PARTMAP_SUN_PC_WHOLE_DISK_ID)
-       continue;
-
-      desc = &block.partitions[partnum];
-      p->start = grub_le_to_cpu32 (desc->start_sector);
-      p->len = grub_le_to_cpu32 (desc->num_sectors);
-      p->number = partnum;
-      if (p->len)
-       {
-         if (hook (disk, p))
-           partnum = GRUB_PARTMAP_SUN_PC_MAX_PARTS;
-       }
-    }
-
-  grub_free (p);
-
-  return grub_errno;
-}
-
-/* Partition map type.  */
-static struct grub_partition_map grub_sun_pc_partition_map =
-  {
-    .name = "sunpc",
-    .iterate = sun_pc_partition_map_iterate,
-  };
-
-GRUB_MOD_INIT(part_sunpc)
-{
-  grub_partition_map_register (&grub_sun_pc_partition_map);
-}
-
-GRUB_MOD_FINI(part_sunpc)
-{
-  grub_partition_map_unregister (&grub_sun_pc_partition_map);
-}
-
diff --git a/parttool/msdospart.c b/parttool/msdospart.c
deleted file mode 100644 (file)
index 006a87d..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/* pcpart.c - manipulate fdisk partitions */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  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/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/msdos_partition.h>
-#include <grub/device.h>
-#include <grub/disk.h>
-#include <grub/partition.h>
-#include <grub/parttool.h>
-
-static int activate_table_handle = -1;
-static int type_table_handle = -1;
-
-static struct grub_parttool_argdesc grub_pcpart_bootargs[] =
-{
-  {"boot", "Make partition active", GRUB_PARTTOOL_ARG_BOOL},
-  {0, 0, 0}
-};
-
-static grub_err_t grub_pcpart_boot (const grub_device_t dev,
-                                   const struct grub_parttool_args *args)
-{
-  int i, index;
-  grub_partition_t part;
-  struct grub_msdos_partition_mbr mbr;
-
-  if (dev->disk->partition->offset)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a primary partition");
-
-  index = dev->disk->partition->index;
-  part = dev->disk->partition;
-  dev->disk->partition = part->parent;
-
-  /* Read the MBR.  */
-  if (grub_disk_read (dev->disk, 0, 0, sizeof (mbr), &mbr))
-    {
-      dev->disk->partition = part;
-      return grub_errno;
-    }
-
-  if (args[0].set && args[0].bool)
-    {
-      for (i = 0; i < 4; i++)
-       mbr.entries[i].flag = 0x0;
-      mbr.entries[index].flag = 0x80;
-      grub_printf ("Partition %d is active now. \n", index);
-    }
-  else
-    {
-      mbr.entries[index].flag = 0x0;
-      grub_printf ("Cleared active flag on %d. \n", index);
-    }
-
-   /* Write the MBR.  */
-  grub_disk_write (dev->disk, 0, 0, sizeof (mbr), &mbr);
-
-  dev->disk->partition = part;
-
-  return GRUB_ERR_NONE;
-}
-
-static struct grub_parttool_argdesc grub_pcpart_typeargs[] =
-{
-  {"type", "Change partition type", GRUB_PARTTOOL_ARG_VAL},
-  {"hidden", "Make partition hidden", GRUB_PARTTOOL_ARG_BOOL},
-  {0, 0, 0}
-};
-
-static grub_err_t grub_pcpart_type (const grub_device_t dev,
-                                   const struct grub_parttool_args *args)
-{
-  int index;
-  grub_uint8_t type;
-  grub_partition_t part;
-  struct grub_msdos_partition_mbr mbr;
-
-  index = dev->disk->partition->index;
-  part = dev->disk->partition;
-  dev->disk->partition = part->parent;
-
-  /* Read the parttable.  */
-  if (grub_disk_read (dev->disk, part->offset, 0,
-                     sizeof (mbr), &mbr))
-    {
-      dev->disk->partition = part;
-      return grub_errno;
-    }
-
-  if (args[0].set)
-    type = grub_strtoul (args[0].str, 0, 0);
-  else
-    type = mbr.entries[index].type;
-
-  if (args[1].set)
-    {
-      if (args[1].bool)
-       type |= GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
-      else
-       type &= ~GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
-    }
-
-  if (grub_msdos_partition_is_empty (type)
-      || grub_msdos_partition_is_extended (type))
-    {
-      dev->disk->partition = part;
-      return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid type");
-    }
-
-  mbr.entries[index].type = type;
-  grub_printf ("Setting partition type to 0x%x\n", type);
-
-   /* Write the parttable.  */
-  grub_disk_write (dev->disk, part->offset, 0,
-                  sizeof (mbr), &mbr);
-
-  dev->disk->partition = part;
-
-  return GRUB_ERR_NONE;
-}
-
-GRUB_MOD_INIT (msdospart)
-{
-  activate_table_handle = grub_parttool_register ("msdos",
-                                                 grub_pcpart_boot,
-                                                 grub_pcpart_bootargs);
-  type_table_handle = grub_parttool_register ("msdos",
-                                             grub_pcpart_type,
-                                             grub_pcpart_typeargs);
-
-}
-GRUB_MOD_FINI(msdospart)
-{
-  grub_parttool_unregister (activate_table_handle);
-  grub_parttool_unregister (type_table_handle);
-}
diff --git a/po/Makefile.am b/po/Makefile.am
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/po/POTFILES b/po/POTFILES
deleted file mode 100644 (file)
index 0dfc3c0..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-# List of files which contain translatable strings.
-commands/acpi.c
-commands/blocklist.c
-commands/boot.c
-commands/cat.c
-commands/cmp.c
-commands/configfile.c
-commands/crc.c
-commands/date.c
-commands/echo.c
-commands/efi/fixvideo.c
-commands/efi/loadbios.c
-commands/gptsync.c
-commands/halt.c
-commands/handler.c
-commands/hdparm.c
-commands/help.c
-commands/hexdump.c
-commands/i386/cpuid.c
-commands/i386/pc/drivemap.c
-commands/i386/pc/halt.c
-commands/i386/pc/play.c
-commands/i386/pc/pxecmd.c
-commands/i386/pc/vbeinfo.c
-commands/i386/pc/vbetest.c
-commands/ieee1275/suspend.c
-commands/keystatus.c
-commands/loadenv.c
-commands/ls.c
-commands/lsmmap.c
-commands/lspci.c
-commands/memrw.c
-commands/minicmd.c
-commands/parttool.c
-commands/password.c
-commands/probe.c
-commands/read.c
-commands/reboot.c
-commands/search.c
-commands/search_file.c
-commands/search_label.c
-commands/search_uuid.c
-commands/sleep.c
-commands/test.c
-commands/true.c
-commands/usbtest.c
-commands/videotest.c
-commands/xnu_uuid.c
-
-disk/loopback.c
-
-hello/hello.c
-
-lib/arg.c
-
-loader/efi/appleloader.c
-loader/efi/chainloader.c
-loader/i386/bsd.c
-loader/i386/efi/linux.c
-loader/i386/ieee1275/linux.c
-loader/i386/linux.c
-loader/i386/pc/chainloader.c
-loader/i386/pc/linux.c
-loader/i386/xnu.c
-loader/multiboot.c
-loader/powerpc/ieee1275/linux.c
-loader/sparc64/ieee1275/linux.c
-loader/xnu.c
-
-normal/auth.c
-normal/color.c
-normal/dyncmd.c
-normal/main.c
-normal/menu_entry.c
-normal/menu_text.c
-normal/misc.c
-
-term/serial.c
-
-util/grub-mkrawimage.c
-util/i386/pc/grub-setup.c
diff --git a/po/POTFILES-shell b/po/POTFILES-shell
deleted file mode 100644 (file)
index 90d2b97..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# List of files which contain translatable strings.  Only files written in
-# Shell language are included here.
-util/grub.d/10_kfreebsd.in
-util/grub.d/10_linux.in
-util/grub.d/10_netbsd.in
diff --git a/po/README b/po/README
deleted file mode 100644 (file)
index 8015995..0000000
--- a/po/README
+++ /dev/null
@@ -1,24 +0,0 @@
-
-If you checked out this source tree directly from GRUB Bazaar, you might
-be wondering where are the POT and PO files.  Here are some instructions
-that will hopefully clarify the situation.
-
-  - If you're a user or a distributor, simply fill the po directory by
-    importing translations from the Translation Project:
-
-      rsync -Lrtvz  translationproject.org::tp/latest/grub/ po
-
-    GRUB's build system will automatically detect those and include them
-    in your install.
-
-  - If you're a translator and want to add a new translation or improve an
-    existing one, get in touch with the Translation Project
-    (http://translationproject.org/).  The GRUB project doesn't interact
-    with translators directly (but we dearly appreciate your work!).
-
-  - If you're a developer adding/removing/modifiing translatable strings,
-    you can check that these turn into a sane POT file by using the
-    `po/grub.pot' make rule.
-
-  - If you're the maintainer of GNU GRUB preparing a new release, don't
-    forget to include the latest PO files in your source tarball!
diff --git a/script/execute.c b/script/execute.c
deleted file mode 100644 (file)
index 40f1612..0000000
+++ /dev/null
@@ -1,392 +0,0 @@
-/* execute.c -- Execute a GRUB script.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/env.h>
-#include <grub/script_sh.h>
-#include <grub/command.h>
-#include <grub/menu.h>
-#include <grub/lib/arg.h>
-#include <grub/normal.h>
-
-/* Max digits for a char is 3 (0xFF is 255), similarly for an int it
-   is sizeof (int) * 3, and one extra for a possible -ve sign.  */
-#define ERRNO_DIGITS_MAX  (sizeof (int) * 3 + 1)
-
-static grub_err_t
-grub_script_execute_cmd (struct grub_script_cmd *cmd)
-{
-  int ret;
-  char errnobuf[ERRNO_DIGITS_MAX + 1];
-
-  if (cmd == 0)
-    return 0;
-
-  ret = cmd->exec (cmd);
-
-  grub_snprintf (errnobuf, sizeof (errnobuf), "%d", ret);
-  grub_env_set ("?", errnobuf);
-  return ret;
-}
-
-#define ARG_ALLOCATION_UNIT  (32 * sizeof (char))
-#define ARGV_ALLOCATION_UNIT (8 * sizeof (void*))
-
-/* Expand arguments in ARGLIST into multiple arguments.  */
-char **
-grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count)
-{
-  int i;
-  int oom;
-  int argc;
-  int empty;
-  char *ptr;
-  char **argv;
-  char *value;
-  struct grub_script_arg *arg;
-
-  auto void push (char *str);
-  void push (char *str)
-  {
-    char **p;
-
-    if (oom)
-      return;
-
-    p = grub_realloc (argv, ALIGN_UP (sizeof(char*) * (argc + 1), ARGV_ALLOCATION_UNIT));
-    if (!p)
-      oom = 1;
-    else
-      {
-       p[argc++] = str;
-       argv = p;
-      }
-  }
-
-  auto char* append (const char *str, grub_size_t nchar);
-  char* append (const char *str, grub_size_t nchar)
-  {
-    int len;
-    int old;
-    char *p;
-
-    if (oom || !str)
-      return 0;
-
-    len = nchar ?: grub_strlen (str);
-    old = argv[argc - 1] ? grub_strlen (argv[argc - 1]) : 0;
-    p = grub_realloc (argv[argc - 1], ALIGN_UP(old + len + 1, ARG_ALLOCATION_UNIT));
-
-    if (p)
-      {
-       grub_strncpy (p + old, str, len);
-       p[old + len] = '\0';
-      }
-    else
-      {
-       oom = 1;
-       grub_free (argv[argc - 1]);
-      }
-    argv[argc - 1] = p;
-    return argv[argc - 1];
-  }
-
-  /* Move *STR to the begining of next word, but return current word.  */
-  auto char* move_to_next (char **str);
-  char* move_to_next (char **str)
-  {
-    char *end;
-    char *start;
-
-    if (oom || !str || !*str)
-      return 0;
-
-    start = *str;
-    while (*start && grub_isspace (*start)) start++;
-    if (*start == '\0')
-      return 0;
-
-    end = start + 1;
-    while (*end && !grub_isspace (*end)) end++;
-
-    *str = end;
-    return start;
-  }
-
-  oom = 0;
-  argv = 0;
-  argc = 0;
-  push (0);
-  for (; arglist; arglist = arglist->next)
-    {
-      empty = 1;
-      arg = arglist->arg;
-      while (arg)
-       {
-         switch (arg->type)
-           {
-           case GRUB_SCRIPT_ARG_TYPE_VAR:
-             value = grub_env_get (arg->str);
-             while (value && *value && (ptr = move_to_next(&value)))
-               {
-                 empty = 0;
-                 append (ptr, value - ptr);
-                 if (*value) push(0);
-               }
-             break;
-
-           case GRUB_SCRIPT_ARG_TYPE_TEXT:
-             if (grub_strlen (arg->str) > 0)
-               {
-                 empty = 0;
-                 append (arg->str, 0);
-               }
-             break;
-
-           case GRUB_SCRIPT_ARG_TYPE_DQSTR:
-           case GRUB_SCRIPT_ARG_TYPE_SQSTR:
-             empty = 0;
-             append (arg->str, 0);
-             break;
-
-           case GRUB_SCRIPT_ARG_TYPE_DQVAR:
-             empty = 0;
-             append (grub_env_get (arg->str), 0);
-             break;
-           }
-         arg = arg->next;
-       }
-      if (!empty)
-       push (0);
-    }
-
-  if (oom)
-    {
-      for (i = 0; i < argc; i++)
-       grub_free (argv[i]);
-      grub_free (argv);
-      argv = 0;
-    }
-
-  if (argv)
-    *count = argc - 1;
-
-  return argv;
-}
-
-/* Execute a single command line.  */
-grub_err_t
-grub_script_execute_cmdline (struct grub_script_cmd *cmd)
-{
-  struct grub_script_cmdline *cmdline = (struct grub_script_cmdline *) cmd;
-  char **args = 0;
-  int i = 0;
-  grub_command_t grubcmd;
-  grub_err_t ret = 0;
-  int argcount = 0;
-  grub_script_function_t func = 0;
-  char errnobuf[18];
-  char *cmdname;
-
-  /* Lookup the command.  */
-  args = grub_script_execute_arglist_to_argv (cmdline->arglist, &argcount);
-  if (!args)
-    return grub_errno;
-
-  cmdname = args[0];
-  grubcmd = grub_command_find (cmdname);
-  if (! grubcmd)
-    {
-      grub_errno = GRUB_ERR_NONE;
-
-      /* It's not a GRUB command, try all functions.  */
-      func = grub_script_function_find (cmdname);
-      if (! func)
-       {
-         /* As a last resort, try if it is an assignment.  */
-         char *assign = grub_strdup (cmdname);
-         char *eq = grub_strchr (assign, '=');
-
-         if (eq)
-           {
-             /* This was set because the command was not found.  */
-             grub_errno = GRUB_ERR_NONE;
-
-             /* Create two strings and set the variable.  */
-             *eq = '\0';
-             eq++;
-             grub_env_set (assign, eq);
-           }
-         grub_free (assign);
-
-         grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno);
-         grub_env_set ("?", errnobuf);
-
-         grub_print_error ();
-
-         return 0;
-       }
-    }
-
-  /* Execute the GRUB command or function.  */
-  if (grubcmd)
-    ret = (grubcmd->func) (grubcmd, argcount - 1, args + 1);
-  else
-    ret = grub_script_function_call (func, argcount - 1, args + 1);
-
-  /* Free arguments.  */
-  for (i = 0; i < argcount; i++)
-    grub_free (args[i]);
-  grub_free (args);
-
-  if (grub_errno == GRUB_ERR_TEST_FAILURE)
-    grub_errno = GRUB_ERR_NONE;
-
-  grub_print_error ();
-
-  grub_snprintf (errnobuf, sizeof (errnobuf), "%d", ret);
-  grub_env_set ("?", errnobuf);
-
-  return ret;
-}
-
-/* Execute a block of one or more commands.  */
-grub_err_t
-grub_script_execute_cmdblock (struct grub_script_cmd *cmd)
-{
-  int ret = 0;
-  struct grub_script_cmdblock *cmdblock = (struct grub_script_cmdblock *) cmd;
-
-  /* Loop over every command and execute it.  */
-  for (cmd = cmdblock->cmdlist; cmd; cmd = cmd->next)
-    ret = grub_script_execute_cmd (cmd);
-
-  return ret;
-}
-
-/* Execute an if statement.  */
-grub_err_t
-grub_script_execute_cmdif (struct grub_script_cmd *cmd)
-{
-  struct grub_script_cmdif *cmdif = (struct grub_script_cmdif *) cmd;
-  char *result;
-
-  /* Check if the commands results in a true or a false.  The value is
-     read from the env variable `?'.  */
-  grub_script_execute_cmd (cmdif->exec_to_evaluate);
-  result = grub_env_get ("?");
-
-  grub_errno = GRUB_ERR_NONE;
-
-  /* Execute the `if' or the `else' part depending on the value of
-     `?'.  */
-  if (result && ! grub_strcmp (result, "0"))
-    return grub_script_execute_cmd (cmdif->exec_on_true);
-  else
-    return grub_script_execute_cmd (cmdif->exec_on_false);
-}
-
-/* Execute a for statement.  */
-grub_err_t
-grub_script_execute_cmdfor (struct grub_script_cmd *cmd)
-{
-  int i;
-  int result;
-  char **args;
-  int argcount;
-  struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd;
-
-  args = grub_script_execute_arglist_to_argv (cmdfor->words, &argcount);
-  if (!args)
-    return grub_errno;
-
-  result = 0;
-  for (i = 0; i < argcount; i++)
-    {
-      grub_env_set (cmdfor->name->str, args[i]);
-      result = grub_script_execute_cmd (cmdfor->list);
-      grub_free (args[i]);
-    }
-
-  grub_free (args);
-  return result;
-}
-
-/* Execute a "while" or "until" command.  */
-grub_err_t
-grub_script_execute_cmdwhile (struct grub_script_cmd *cmd)
-{
-  int cond;
-  int result;
-  struct grub_script_cmdwhile *cmdwhile = (struct grub_script_cmdwhile *) cmd;
-
-  result = 0;
-  do {
-    cond = grub_script_execute_cmd (cmdwhile->cond);
-    if (cmdwhile->until ? !cond : cond)
-      break;
-
-    result = grub_script_execute_cmd (cmdwhile->list);
-  } while (1); /* XXX Put a check for ^C here */
-
-  return result;
-}
-
-/* Execute the menu entry generate statement.  */
-grub_err_t
-grub_script_execute_menuentry (struct grub_script_cmd *cmd)
-{
-  struct grub_script_cmd_menuentry *cmd_menuentry;
-  char **args = 0;
-  int argcount = 0;
-  int i = 0;
-
-  cmd_menuentry = (struct grub_script_cmd_menuentry *) cmd;
-
-  if (cmd_menuentry->arglist)
-    {
-      args = grub_script_execute_arglist_to_argv (cmd_menuentry->arglist, &argcount);
-      if (!args)
-       return grub_errno;
-    }
-
-  grub_normal_add_menu_entry (argcount, (const char **) args,
-                             cmd_menuentry->sourcecode);
-
-  /* Free arguments.  */
-  for (i = 0; i < argcount; i++)
-    grub_free (args[i]);
-  grub_free (args);
-
-  return grub_errno;
-}
-
-
-
-/* Execute any GRUB pre-parsed command or script.  */
-grub_err_t
-grub_script_execute (struct grub_script *script)
-{
-  if (script == 0)
-    return 0;
-
-  return grub_script_execute_cmd (script->cmd);
-}
-
diff --git a/script/function.c b/script/function.c
deleted file mode 100644 (file)
index ded470c..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/script_sh.h>
-#include <grub/parser.h>
-#include <grub/mm.h>
-
-static grub_script_function_t grub_script_function_list;
-
-grub_script_function_t
-grub_script_function_create (struct grub_script_arg *functionname_arg,
-                            struct grub_script *cmd)
-{
-  grub_script_function_t func;
-  grub_script_function_t *p;
-
-  func = (grub_script_function_t) grub_malloc (sizeof (*func));
-  if (! func)
-    return 0;
-
-  func->name = grub_strdup (functionname_arg->str);
-  if (! func->name)
-    {
-      grub_free (func);
-      return 0;
-    }
-
-  func->func = cmd;
-
-  /* Keep the list sorted for simplicity.  */
-  p = &grub_script_function_list;
-  while (*p)
-    {
-      if (grub_strcmp ((*p)->name, func->name) >= 0)
-       break;
-
-      p = &((*p)->next);
-    }
-
-  /* If the function already exists, overwrite the old function.  */
-  if (*p && grub_strcmp ((*p)->name, func->name) == 0)
-    {
-      grub_script_function_t q;
-
-      q = *p;
-      grub_script_free (q->func);
-      q->func = cmd;
-      grub_free (func);
-      func = q;
-    }
-  else
-    {
-      func->next = *p;
-      *p = func;
-    }
-
-  return func;
-}
-
-void
-grub_script_function_remove (const char *name)
-{
-  grub_script_function_t *p, q;
-
-  for (p = &grub_script_function_list, q = *p; q; p = &(q->next), q = q->next)
-    if (grub_strcmp (name, q->name) == 0)
-      {
-        *p = q->next;
-       grub_free (q->name);
-       grub_script_free (q->func);
-        grub_free (q);
-        break;
-      }
-}
-
-grub_script_function_t
-grub_script_function_find (char *functionname)
-{
-  grub_script_function_t func;
-
-  for (func = grub_script_function_list; func; func = func->next)
-    if (grub_strcmp (functionname, func->name) == 0)
-      break;
-
-  if (! func)
-    grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%.20s'", functionname);
-
-  return func;
-}
-
-int
-grub_script_function_iterate (int (*iterate) (grub_script_function_t))
-{
-  grub_script_function_t func;
-
-  for (func = grub_script_function_list; func; func = func->next)
-    if (iterate (func))
-      return 1;
-
-  return 0;
-}
-
-int
-grub_script_function_call (grub_script_function_t func,
-                          int argc __attribute__((unused)),
-                          char **args __attribute__((unused)))
-{
-  /* XXX: Arguments are not supported yet.  */
-  return grub_script_execute (func->func);
-}
diff --git a/script/lexer.c b/script/lexer.c
deleted file mode 100644 (file)
index 42a5703..0000000
+++ /dev/null
@@ -1,346 +0,0 @@
-/* lexer.c - The scripting lexer.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/parser.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/script_sh.h>
-
-#include "grub_script.tab.h"
-#include "grub_script.yy.h"
-
-void
-grub_script_lexer_ref (struct grub_lexer_param *state)
-{
-  state->refs++;
-}
-
-void
-grub_script_lexer_deref (struct grub_lexer_param *state)
-{
-  state->refs--;
-}
-
-/* Start recording all characters passing through the lexer.  */
-void
-grub_script_lexer_record_start (struct grub_parser_param *parser)
-{
-  struct grub_lexer_param *lexer = parser->lexerstate;
-
-  lexer->record = 1;
-  lexer->recordpos = 0;
-  if (lexer->recording) /* reuse last record */
-    return;
-
-  lexer->recordlen = GRUB_LEXER_INITIAL_RECORD_SIZE;
-  lexer->recording = grub_malloc (lexer->recordlen);
-  if (!lexer->recording)
-    {
-      grub_script_yyerror (parser, 0);
-      lexer->record = 0;
-      lexer->recordlen = 0;
-    }
-}
-
-char *
-grub_script_lexer_record_stop (struct grub_parser_param *parser)
-{
-  char *ptr;
-  char *result;
-  struct grub_lexer_param *lexer = parser->lexerstate;
-
-  auto char *compact (char *start, char *end);
-  char *compact (char *start, char *end)
-  {
-    /* Delete '{' and '}' characters and whitespaces.  */
-    while (*start && grub_isspace (*start)) start++;
-    if (*start == '{') start++;
-    while (*start && grub_isspace (*start)) start++;
-
-    while (*end && grub_isspace (*end)) end--;
-    if (*end == '}') end--;
-    while (*end && grub_isspace (*end)) end--;
-    end[1] = '\0';
-
-    return start;
-  }
-
-  if (!lexer->record || !lexer->recording)
-    return 0;
-
-  /* XXX This is not necessary in BASH.  */
-
-  ptr = compact (lexer->recording, lexer->recording + lexer->recordpos - 1);
-  lexer->record = 0;
-  lexer->recordpos = 0;
-
-  /* This memory would be freed by, grub_script_free.  */
-  result = grub_script_malloc (parser, grub_strlen (ptr) + 1);
-  if (result)
-    grub_strcpy (result, ptr);
-
-  return result;
-}
-
-#define MAX(a,b) ((a) < (b) ? (b) : (a))
-
-/* Record STR if input recording is enabled.  */
-void
-grub_script_lexer_record (struct grub_parser_param *parser, char *str)
-{
-  int len;
-  char *old;
-  struct grub_lexer_param *lexer = parser->lexerstate;
-
-  if (!lexer->record)
-    return;
-
-  len = grub_strlen (str);
-  if (lexer->recordpos + len + 1 > lexer->recordlen)
-    {
-      old = lexer->recording;
-      lexer->recordlen = MAX (len, lexer->recordlen) * 2;
-      lexer->recording = grub_realloc (lexer->recording, lexer->recordlen);
-      if (!lexer->recording)
-       {
-         grub_free (old);
-         lexer->record = 0;
-         lexer->recordpos = 0;
-         lexer->recordlen /= 2;
-         grub_script_yyerror (parser, 0);
-         return;
-       }
-    }
-  grub_strcpy (lexer->recording + lexer->recordpos, str);
-  lexer->recordpos += len;
-}
-
-/* Append '\n' to SRC, before '\0'  */
-static char *
-append_newline (const char *src)
-{
-  char *line;
-  grub_size_t len;
-
-  len = grub_strlen (src);
-  line = grub_malloc (len + 2);
-  if (!line)
-    return 0;
-
-  grub_strcpy (line, src);
-
-  line[len] = '\n';
-  line[len + 1] = '\0';
-  return line;
-}
-
-/* Read next line of input if necessary, and set yyscanner buffers.  */
-int
-grub_script_lexer_yywrap (struct grub_parser_param *parserstate)
-{
-  int len;
-  char *line;
-  char *line2;
-  YY_BUFFER_STATE buffer;
-  struct grub_lexer_param *lexerstate = parserstate->lexerstate;
-
-  if (!lexerstate->refs)
-    return 0;
-
-  if (!lexerstate->getline)
-    {
-      grub_script_yyerror (parserstate, "unexpected end of file");
-      return 0;
-    }
-
-  line = 0;
-  buffer = 0;
-  lexerstate->getline (&line, 1);
-  if (!line)
-    {
-      grub_script_yyerror (parserstate, 0); /* XXX this could be for ^C case? */
-      return 0;
-    }
-
-  len = grub_strlen (line);
-  if (line[len - 1] == '\n')
-    {
-      buffer = yy_scan_string (line, lexerstate->yyscanner);
-    }
-  else
-    {
-      line2 = append_newline (line);
-      if (line2)
-       {
-         buffer = yy_scan_string (line2, lexerstate->yyscanner);
-         grub_free (line2);
-       }
-    }
-
-  grub_free (line);
-  if (!buffer)
-    {
-      grub_script_yyerror (parserstate, 0);
-      return 0;
-    }
-
-  return 1;
-}
-
-struct grub_lexer_param *
-grub_script_lexer_init (struct grub_parser_param *parser, char *script,
-                       grub_reader_getline_t getline)
-{
-  int len;
-  char *script2;
-  YY_BUFFER_STATE buffer;
-  struct grub_lexer_param *lexerstate;
-
-  lexerstate = grub_zalloc (sizeof (*lexerstate));
-  if (!lexerstate)
-    return 0;
-
-  lexerstate->size = GRUB_LEXER_INITIAL_TEXT_SIZE;
-  lexerstate->text = grub_malloc (lexerstate->size);
-  if (!lexerstate->text)
-    {
-      grub_free (lexerstate);
-      return 0;
-    }
-
-  lexerstate->getline = getline;       /* rest are all zeros already */
-  if (yylex_init (&lexerstate->yyscanner))
-    {
-      grub_free (lexerstate->text);
-      grub_free (lexerstate);
-      return 0;
-    }
-
-  buffer = 0;
-  script = script ? : "\n";
-  len = grub_strlen (script);
-
-  if (script[len - 1] == '\n')
-    {
-      buffer = yy_scan_string (script, lexerstate->yyscanner);
-    }
-  else
-    {
-      script2 = append_newline (script);
-      if (script2)
-       {
-         buffer = yy_scan_string (script2, lexerstate->yyscanner);
-         grub_free (script2);
-       }
-    }
-
-  if (!buffer)
-    {
-      yylex_destroy (lexerstate->yyscanner);
-      grub_free (lexerstate->yyscanner);
-
-      grub_free (lexerstate->text);
-      grub_free (lexerstate);
-      return 0;
-    }
-  yyset_extra (parser, lexerstate->yyscanner);
-
-  return lexerstate;
-}
-
-void
-grub_script_lexer_fini (struct grub_lexer_param *lexerstate)
-{
-  if (!lexerstate)
-    return;
-
-  yylex_destroy (lexerstate->yyscanner);
-
-  grub_free (lexerstate->recording);
-  grub_free (lexerstate->text);
-  grub_free (lexerstate);
-}
-
-int
-grub_script_yylex (union YYSTYPE *value,
-                  struct grub_parser_param *parserstate)
-{
-  char *str;
-  int token;
-  grub_script_arg_type_t type;
-  struct grub_lexer_param *lexerstate = parserstate->lexerstate;
-
-  value->arg = 0;
-  if (parserstate->err)
-    return GRUB_PARSER_TOKEN_BAD;
-
-  if (lexerstate->eof)
-    return GRUB_PARSER_TOKEN_EOF;
-
-  /* 
-   * Words with environment variables, like foo${bar}baz needs
-   * multiple tokens to be merged into a single grub_script_arg.  We
-   * use two variables to achieve this: lexerstate->merge_start and
-   * lexerstate->merge_end
-   */
-
-  lexerstate->merge_start = 0;
-  lexerstate->merge_end = 0;
-  do
-    {
-      /* Empty lexerstate->text.  */
-      lexerstate->used = 1;
-      lexerstate->text[0] = '\0';
-
-      token = yylex (value, lexerstate->yyscanner);
-      if (token == GRUB_PARSER_TOKEN_BAD)
-       break;
-
-      /* Merging feature uses lexerstate->text instead of yytext.  */
-      if (lexerstate->merge_start)
-       {
-         str = lexerstate->text;
-         type = lexerstate->type;
-       }
-      else
-       {
-         str = yyget_text (lexerstate->yyscanner);
-         type = GRUB_SCRIPT_ARG_TYPE_TEXT;
-       }
-      grub_dprintf("lexer", "token %u text [%s]\n", token, str);
-
-      value->arg = grub_script_arg_add (parserstate, value->arg, type, str);
-    }
-  while (lexerstate->merge_start && !lexerstate->merge_end);
-
-  if (!value->arg || parserstate->err)
-    return GRUB_PARSER_TOKEN_BAD;
-
-  return token;
-}
-
-void
-grub_script_yyerror (struct grub_parser_param *state, char const *err)
-{
-  if (err)
-    grub_error (GRUB_ERR_INVALID_COMMAND, err);
-
-  grub_print_error ();
-  state->err++;
-}
diff --git a/script/main.c b/script/main.c
deleted file mode 100644 (file)
index b5159dc..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/parser.h>
-#include <grub/script_sh.h>
-
-static grub_err_t
-grub_normal_parse_line (char *line, grub_reader_getline_t getline)
-{
-  struct grub_script *parsed_script;
-
-  /* Parse the script.  */
-  parsed_script = grub_script_parse (line, getline);
-
-  if (parsed_script)
-    {
-      /* Execute the command(s).  */
-      grub_script_execute (parsed_script);
-
-      /* The parsed script was executed, throw it away.  */
-      grub_script_free (parsed_script);
-    }
-
-  return grub_errno;
-}
-
-static struct grub_parser grub_sh_parser =
-  {
-    .name = "grub",
-    .parse_line = grub_normal_parse_line
-  };
-
-GRUB_MOD_INIT(sh)
-{
-  grub_parser_register ("grub", &grub_sh_parser);
-}
-
-GRUB_MOD_FINI(sh)
-{
-  grub_parser_unregister (&grub_sh_parser);
-}
diff --git a/script/parser.y b/script/parser.y
deleted file mode 100644 (file)
index b5815ea..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/* parser.y - The scripting parser.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-%{
-#include <grub/script_sh.h>
-#include <grub/mm.h>
-
-#define YYFREE          grub_free
-#define YYMALLOC        grub_malloc
-#define YYLTYPE_IS_TRIVIAL      0
-#define YYENABLE_NLS    0
-
-%}
-
-%union {
-  struct grub_script_cmd *cmd;
-  struct grub_script_arglist *arglist;
-  struct grub_script_arg *arg;
-  char *string;
-}
-
-%token GRUB_PARSER_TOKEN_BAD
-%token GRUB_PARSER_TOKEN_EOF 0 "end-of-input"
-
-%token GRUB_PARSER_TOKEN_NEWLINE "\n"
-%token GRUB_PARSER_TOKEN_AND     "&&"
-%token GRUB_PARSER_TOKEN_OR      "||"
-%token GRUB_PARSER_TOKEN_SEMI2   ";;"
-%token GRUB_PARSER_TOKEN_PIPE    "|"
-%token GRUB_PARSER_TOKEN_AMP     "&"
-%token GRUB_PARSER_TOKEN_SEMI    ";"
-%token GRUB_PARSER_TOKEN_LBR     "{"
-%token GRUB_PARSER_TOKEN_RBR     "}"
-%token GRUB_PARSER_TOKEN_NOT     "!"
-%token GRUB_PARSER_TOKEN_LSQBR2  "["
-%token GRUB_PARSER_TOKEN_RSQBR2  "]"
-%token GRUB_PARSER_TOKEN_LT      "<"
-%token GRUB_PARSER_TOKEN_GT      ">"
-
-%token <arg> GRUB_PARSER_TOKEN_CASE      "case"
-%token <arg> GRUB_PARSER_TOKEN_DO        "do"
-%token <arg> GRUB_PARSER_TOKEN_DONE      "done"
-%token <arg> GRUB_PARSER_TOKEN_ELIF      "elif"
-%token <arg> GRUB_PARSER_TOKEN_ELSE      "else"
-%token <arg> GRUB_PARSER_TOKEN_ESAC      "esac"
-%token <arg> GRUB_PARSER_TOKEN_FI        "fi"
-%token <arg> GRUB_PARSER_TOKEN_FOR       "for"
-%token <arg> GRUB_PARSER_TOKEN_IF        "if"
-%token <arg> GRUB_PARSER_TOKEN_IN        "in"
-%token <arg> GRUB_PARSER_TOKEN_SELECT    "select"
-%token <arg> GRUB_PARSER_TOKEN_THEN      "then"
-%token <arg> GRUB_PARSER_TOKEN_UNTIL     "until"
-%token <arg> GRUB_PARSER_TOKEN_WHILE     "while"
-%token <arg> GRUB_PARSER_TOKEN_TIME      "time"
-%token <arg> GRUB_PARSER_TOKEN_FUNCTION  "function"
-%token <arg> GRUB_PARSER_TOKEN_MENUENTRY "menuentry"
-%token <arg> GRUB_PARSER_TOKEN_NAME      "name"
-%token <arg> GRUB_PARSER_TOKEN_WORD      "word"
-
-%type <arglist> word argument arguments0 arguments1
-
-%type <cmd> script_init script
-%type <cmd> grubcmd ifclause ifcmd forcmd whilecmd untilcmd
-%type <cmd> command commands1 menuentry statement
-
-%pure-parser
-%lex-param   { struct grub_parser_param *state };
-%parse-param { struct grub_parser_param *state };
-
-%start script_init
-
-%%
-/* It should be possible to do this in a clean way...  */
-script_init: { state->err = 0; } script { state->parsed = $2; state->err = 0; }
-;
-
-script: newlines0
-        {
-          $$ = 0;
-        }
-      | script statement delimiter newlines0
-        {
-          struct grub_script_cmdblock *cmdblock;
-          cmdblock = (struct grub_script_cmdblock *) $1;
-          $$ = grub_script_add_cmd (state, cmdblock, $2);
-        }
-      | error
-        {
-          $$ = 0;
-          yyerror (state, "Incorrect command");
-          yyerrok;
-        }
-;
-
-newlines0: /* Empty */ | newlines1 ;
-newlines1: newlines0 "\n" ;
-
-delimiter: ";"
-         | "\n"
-;
-delimiters0: /* Empty */ | delimiters1 ;
-delimiters1: delimiter
-          | delimiters1 "\n"
-;
-
-word: GRUB_PARSER_TOKEN_NAME { $$ = grub_script_add_arglist (state, 0, $1); }
-    | GRUB_PARSER_TOKEN_WORD { $$ = grub_script_add_arglist (state, 0, $1); }
-;
-
-statement: command   { $$ = $1; }
-         | function  { $$ = 0;  }
-         | menuentry { $$ = $1; }
-
-argument : "case"      { $$ = grub_script_add_arglist (state, 0, $1); }
-         | "do"        { $$ = grub_script_add_arglist (state, 0, $1); }
-         | "done"      { $$ = grub_script_add_arglist (state, 0, $1); }
-         | "elif"      { $$ = grub_script_add_arglist (state, 0, $1); }
-         | "else"      { $$ = grub_script_add_arglist (state, 0, $1); }
-         | "esac"      { $$ = grub_script_add_arglist (state, 0, $1); }
-         | "fi"        { $$ = grub_script_add_arglist (state, 0, $1); }
-         | "for"       { $$ = grub_script_add_arglist (state, 0, $1); }
-         | "if"        { $$ = grub_script_add_arglist (state, 0, $1); }
-         | "in"        { $$ = grub_script_add_arglist (state, 0, $1); }
-         | "select"    { $$ = grub_script_add_arglist (state, 0, $1); }
-         | "then"      { $$ = grub_script_add_arglist (state, 0, $1); }
-         | "until"     { $$ = grub_script_add_arglist (state, 0, $1); }
-         | "while"     { $$ = grub_script_add_arglist (state, 0, $1); }
-         | "function"  { $$ = grub_script_add_arglist (state, 0, $1); }
-         | "menuentry" { $$ = grub_script_add_arglist (state, 0, $1); }
-         | word { $$ = $1; }
-;
-
-arguments0: /* Empty */ { $$ = 0; }
-          | arguments1  { $$ = $1; }
-;
-arguments1: argument arguments0
-            {
-             if ($1 && $2)
-               {
-                 $1->next = $2;
-                 $1->argcount += $2->argcount;
-                 $2->argcount = 0;
-               }
-             $$ = $1;
-            }
-;
-
-grubcmd: word arguments0
-         {
-           if ($1 && $2) {
-             $1->next = $2;
-             $1->argcount += $2->argcount;
-             $2->argcount = 0;
-           }
-           $$ = grub_script_create_cmdline (state, $1);
-         }
-;
-
-/* A single command.  */
-command: grubcmd  { $$ = $1; }
-       | ifcmd    { $$ = $1; }
-       | forcmd   { $$ = $1; }
-       | whilecmd { $$ = $1; }
-       | untilcmd { $$ = $1; }
-;
-
-/* A list of commands. */
-commands1: newlines0 command
-           {
-             $$ = grub_script_add_cmd (state, 0, $2);
-           }
-         | commands1 delimiters1 command
-           {
-             struct grub_script_cmdblock *cmdblock;
-            cmdblock = (struct grub_script_cmdblock *) $1;
-            $$ = grub_script_add_cmd (state, cmdblock, $3);
-           }
-;
-
-function: "function" "name" 
-          {
-            grub_script_lexer_ref (state->lexerstate);
-            state->func_mem = grub_script_mem_record (state);
-          }
-          delimiters0 "{" commands1 delimiters1 "}"
-          {
-            struct grub_script *script;
-            state->func_mem = grub_script_mem_record_stop (state,
-                                                           state->func_mem);
-            script = grub_script_create ($6, state->func_mem);
-            if (script)
-              grub_script_function_create ($2, script);
-
-            grub_script_lexer_deref (state->lexerstate);
-          }
-;
-
-menuentry: "menuentry"
-           {
-             grub_script_lexer_ref (state->lexerstate);
-           }
-           arguments1
-           {
-             grub_script_lexer_record_start (state);
-           }
-           delimiters0 "{" commands1 delimiters1 "}"
-           {
-             char *menu_entry;
-             menu_entry = grub_script_lexer_record_stop (state);
-             grub_script_lexer_deref (state->lexerstate);
-             $$ = grub_script_create_cmdmenu (state, $3, menu_entry, 0);
-           }
-;
-
-ifcmd: "if"
-       {
-         grub_script_lexer_ref (state->lexerstate);
-       }
-       ifclause "fi"
-       {
-         $$ = $3;
-         grub_script_lexer_deref (state->lexerstate);
-       }
-;
-ifclause: commands1 delimiters1 "then" commands1 delimiters1
-         {
-           $$ = grub_script_create_cmdif (state, $1, $4, 0);
-         }
-       | commands1 delimiters1 "then" commands1 delimiters1 "else" commands1 delimiters1
-         {
-           $$ = grub_script_create_cmdif (state, $1, $4, $7);
-         }
-       | commands1 delimiters1 "then" commands1 delimiters1 "elif" ifclause
-         {
-           $$ = grub_script_create_cmdif (state, $1, $4, $7);
-         }
-;
-
-forcmd: "for" "name"
-        {
-         grub_script_lexer_ref (state->lexerstate);
-        }
-        "in" arguments0 delimiters1 "do" commands1 delimiters1 "done"
-       {
-         $$ = grub_script_create_cmdfor (state, $2, $5, $8);
-         grub_script_lexer_deref (state->lexerstate);
-       }
-;
-
-whilecmd: "while"
-          {
-           grub_script_lexer_ref (state->lexerstate);
-          }
-          commands1 delimiters1 "do" commands1 delimiters1 "done"
-         {
-           $$ = grub_script_create_cmdwhile (state, $3, $6, 0);
-           grub_script_lexer_deref (state->lexerstate);
-         }
-;
-
-untilcmd: "until"
-          {
-           grub_script_lexer_ref (state->lexerstate);
-          }
-          commands1 delimiters1 "do" commands1 delimiters1 "done"
-         {
-           $$ = grub_script_create_cmdwhile (state, $3, $6, 1);
-           grub_script_lexer_deref (state->lexerstate);
-         }
-;
diff --git a/script/script.c b/script/script.c
deleted file mode 100644 (file)
index 4c87d94..0000000
+++ /dev/null
@@ -1,407 +0,0 @@
-/* script.c -- Functions to create an in memory description of the script. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/script_sh.h>
-#include <grub/parser.h>
-#include <grub/mm.h>
-
-/* It is not possible to deallocate the memory when a syntax error was
-   found.  Because of that it is required to keep track of all memory
-   allocations.  The memory is freed in case of an error, or assigned
-   to the parsed script when parsing was successful.
-
-   In case of the normal malloc, some additional bytes are allocated
-   for this datastructure.  All reserved memory is stored in a linked
-   list so it can be easily freed.  The original memory can be found
-   from &mem.  */
-struct grub_script_mem
-{
-  struct grub_script_mem *next;
-  char mem;
-};
-
-/* Return malloc'ed memory and keep track of the allocation.  */
-void *
-grub_script_malloc (struct grub_parser_param *state, grub_size_t size)
-{
-  struct grub_script_mem *mem;
-  mem = (struct grub_script_mem *) grub_malloc (size + sizeof (*mem)
-                                               - sizeof (char));
-  if (!mem)
-    return 0;
-
-  grub_dprintf ("scripting", "malloc %p\n", mem);
-  mem->next = state->memused;
-  state->memused = mem;
-  return (void *) &mem->mem;
-}
-
-/* Free all memory described by MEM.  */
-static void
-grub_script_mem_free (struct grub_script_mem *mem)
-{
-  struct grub_script_mem *memfree;
-
-  while (mem)
-    {
-      memfree = mem->next;
-      grub_dprintf ("scripting", "free %p\n", mem);
-      grub_free (mem);
-      mem = memfree;
-    }
-}
-
-/* Start recording memory usage.  Returns the memory that should be
-   restored when calling stop.  */
-struct grub_script_mem *
-grub_script_mem_record (struct grub_parser_param *state)
-{
-  struct grub_script_mem *mem = state->memused;
-  state->memused = 0;
-
-  return mem;
-}
-
-/* Stop recording memory usage.  Restore previous recordings using
-   RESTORE.  Return the recorded memory.  */
-struct grub_script_mem *
-grub_script_mem_record_stop (struct grub_parser_param *state,
-                            struct grub_script_mem *restore)
-{
-  struct grub_script_mem *mem = state->memused;
-  state->memused = restore;
-  return mem;
-}
-
-/* Free the memory reserved for CMD and all of it's children.  */
-void
-grub_script_free (struct grub_script *script)
-{
-  if (!script)
-    return;
-  grub_script_mem_free (script->mem);
-  grub_free (script);
-}
-\f
-
-
-/* Extend the argument arg with a variable or string of text.  If ARG
-   is zero a new list is created.  */
-struct grub_script_arg *
-grub_script_arg_add (struct grub_parser_param *state,
-                    struct grub_script_arg *arg, grub_script_arg_type_t type,
-                    char *str)
-{
-  struct grub_script_arg *argpart;
-  struct grub_script_arg *ll;
-  int len;
-
-  argpart =
-    (struct grub_script_arg *) grub_script_malloc (state, sizeof (*arg));
-  if (!argpart)
-    return arg;
-
-  argpart->type = type;
-  len = grub_strlen (str) + 1;
-  argpart->str = grub_script_malloc (state, len);
-  if (!argpart->str)
-    return arg; /* argpart is freed later, during grub_script_free.  */
-
-  grub_memcpy (argpart->str, str, len);
-  argpart->next = 0;
-
-  if (!arg)
-    return argpart;
-
-  for (ll = arg; ll->next; ll = ll->next);
-  ll->next = argpart;
-
-  return arg;
-}
-
-/* Add the argument ARG to the end of the argument list LIST.  If LIST
-   is zero, a new list will be created.  */
-struct grub_script_arglist *
-grub_script_add_arglist (struct grub_parser_param *state,
-                        struct grub_script_arglist *list,
-                        struct grub_script_arg *arg)
-{
-  struct grub_script_arglist *link;
-  struct grub_script_arglist *ll;
-
-  grub_dprintf ("scripting", "arglist\n");
-
-  link =
-    (struct grub_script_arglist *) grub_script_malloc (state, sizeof (*link));
-  if (!link)
-    return list;
-
-  link->next = 0;
-  link->arg = arg;
-  link->argcount = 0;
-
-  if (!list)
-    {
-      link->argcount++;
-      return link;
-    }
-
-  list->argcount++;
-
-  /* Look up the last link in the chain.  */
-  for (ll = list; ll->next; ll = ll->next);
-  ll->next = link;
-
-  return list;
-}
-
-/* Create a command that describes a single command line.  CMDLINE
-   contains the name of the command that should be executed.  ARGLIST
-   holds all arguments for this command.  */
-struct grub_script_cmd *
-grub_script_create_cmdline (struct grub_parser_param *state,
-                           struct grub_script_arglist *arglist)
-{
-  struct grub_script_cmdline *cmd;
-
-  grub_dprintf ("scripting", "cmdline\n");
-
-  cmd = grub_script_malloc (state, sizeof (*cmd));
-  if (!cmd)
-    return 0;
-
-  cmd->cmd.exec = grub_script_execute_cmdline;
-  cmd->cmd.next = 0;
-  cmd->arglist = arglist;
-
-  return (struct grub_script_cmd *) cmd;
-}
-
-/* Create a command that functions as an if statement.  If BOOL is
-   evaluated to true (the value is returned in envvar '?'), the
-   interpreter will run the command TRUE, otherwise the interpreter
-   runs the command FALSE.  */
-struct grub_script_cmd *
-grub_script_create_cmdif (struct grub_parser_param *state,
-                         struct grub_script_cmd *exec_to_evaluate,
-                         struct grub_script_cmd *exec_on_true,
-                         struct grub_script_cmd *exec_on_false)
-{
-  struct grub_script_cmdif *cmd;
-
-  grub_dprintf ("scripting", "cmdif\n");
-
-  cmd = grub_script_malloc (state, sizeof (*cmd));
-  if (!cmd)
-    return 0;
-
-  cmd->cmd.exec = grub_script_execute_cmdif;
-  cmd->cmd.next = 0;
-  cmd->exec_to_evaluate = exec_to_evaluate;
-  cmd->exec_on_true = exec_on_true;
-  cmd->exec_on_false = exec_on_false;
-
-  return (struct grub_script_cmd *) cmd;
-}
-
-/* Create a command that functions as a for statement.  */
-struct grub_script_cmd *
-grub_script_create_cmdfor (struct grub_parser_param *state,
-                          struct grub_script_arg *name,
-                          struct grub_script_arglist *words,
-                          struct grub_script_cmd *list)
-{
-  struct grub_script_cmdfor *cmd;
-
-  grub_dprintf ("scripting", "cmdfor\n");
-
-  cmd = grub_script_malloc (state, sizeof (*cmd));
-  if (! cmd)
-    return 0;
-
-  cmd->cmd.exec = grub_script_execute_cmdfor;
-  cmd->cmd.next = 0;
-  cmd->name = name;
-  cmd->words = words;
-  cmd->list = list;
-
-  return (struct grub_script_cmd *) cmd;
-}
-
-/* Create a "while" or "until" command.  */
-struct grub_script_cmd *
-grub_script_create_cmdwhile (struct grub_parser_param *state,
-                            struct grub_script_cmd *cond,
-                            struct grub_script_cmd *list,
-                            int is_an_until_loop)
-{
-  struct grub_script_cmdwhile *cmd;
-
-  cmd = grub_script_malloc (state, sizeof (*cmd));
-  if (! cmd)
-    return 0;
-
-  cmd->cmd.exec = grub_script_execute_cmdwhile;
-  cmd->cmd.next = 0;
-  cmd->cond = cond;
-  cmd->list = list;
-  cmd->until = is_an_until_loop;
-
-  return (struct grub_script_cmd *) cmd;
-}
-
-/* Create a command that adds a menu entry to the menu.  Title is an
-   argument that is parsed to generate a string that can be used as
-   the title.  The sourcecode for this entry is passed in SOURCECODE.
-   The options for this entry are passed in OPTIONS.  */
-struct grub_script_cmd *
-grub_script_create_cmdmenu (struct grub_parser_param *state,
-                           struct grub_script_arglist *arglist,
-                           char *sourcecode, int options)
-{
-  struct grub_script_cmd_menuentry *cmd;
-
-  cmd = grub_script_malloc (state, sizeof (*cmd));
-  if (!cmd)
-    return 0;
-    
-  cmd->cmd.exec = grub_script_execute_menuentry;
-  cmd->cmd.next = 0;
-  cmd->sourcecode = sourcecode;
-  cmd->arglist = arglist;
-  cmd->options = options;
-
-  return (struct grub_script_cmd *) cmd;
-}
-
-/* Create a block of commands.  CMD contains the command that should
-   be added at the end of CMDBLOCK's list.  If CMDBLOCK is zero, a new
-   cmdblock will be created.  */
-struct grub_script_cmd *
-grub_script_add_cmd (struct grub_parser_param *state,
-                    struct grub_script_cmdblock *cmdblock,
-                    struct grub_script_cmd *cmd)
-{
-  struct grub_script_cmd *ptr;
-
-  grub_dprintf ("scripting", "cmdblock\n");
-
-  if (!cmd)
-    return (struct grub_script_cmd *) cmdblock;
-
-  if (!cmdblock)
-    {
-      cmdblock = grub_script_malloc (state, sizeof (*cmdblock));
-      if (!cmdblock)
-       return 0;
-
-      cmdblock->cmd.exec = grub_script_execute_cmdblock;
-      cmdblock->cmd.next = 0;
-      cmdblock->cmdlist = cmd;
-      cmd->next = 0;
-    }
-  else
-    {
-      if (!cmdblock->cmdlist)
-       cmdblock->cmdlist = cmd;
-      else
-       {
-         ptr = cmdblock->cmdlist;
-         while (ptr->next)
-           ptr = ptr->next;
-         ptr->next = cmd;
-       }
-    }
-
-  return (struct grub_script_cmd *) cmdblock;
-}
-\f
-
-
-struct grub_script *
-grub_script_create (struct grub_script_cmd *cmd, struct grub_script_mem *mem)
-{
-  struct grub_script *parsed;
-
-  parsed = grub_malloc (sizeof (*parsed));
-  if (!parsed)
-    {
-      grub_script_mem_free (mem);
-      grub_free (cmd);
-
-      return 0;
-    }
-
-  parsed->mem = mem;
-  parsed->cmd = cmd;
-
-  return parsed;
-}
-
-/* Parse the script passed in SCRIPT and return the parsed
-   datastructure that is ready to be interpreted.  */
-struct grub_script *
-grub_script_parse (char *script, grub_reader_getline_t getline)
-{
-  struct grub_script *parsed;
-  struct grub_script_mem *membackup;
-  struct grub_lexer_param *lexstate;
-  struct grub_parser_param *parsestate;
-
-  parsed = grub_malloc (sizeof (*parsed));
-  if (!parsed)
-    return 0;
-
-  parsestate = grub_zalloc (sizeof (*parsestate));
-  if (!parsestate)
-    return 0;
-
-  /* Initialize the lexer.  */
-  lexstate = grub_script_lexer_init (parsestate, script, getline);
-  if (!lexstate)
-    {
-      grub_free (parsed);
-      grub_free (parsestate);
-      return 0;
-    }
-
-  parsestate->lexerstate = lexstate;
-
-  membackup = grub_script_mem_record (parsestate);
-
-  /* Parse the script.  */
-  if (grub_script_yyparse (parsestate) || parsestate->err)
-    {
-      struct grub_script_mem *memfree;
-      memfree = grub_script_mem_record_stop (parsestate, membackup);
-      grub_script_mem_free (memfree);
-      grub_script_lexer_fini (lexstate);
-      grub_free (parsestate);
-      return 0;
-    }
-
-  parsed->mem = grub_script_mem_record_stop (parsestate, membackup);
-  parsed->cmd = parsestate->parsed;
-
-  grub_script_lexer_fini (lexstate);
-  grub_free (parsestate);
-
-  return parsed;
-}
diff --git a/script/yylex.l b/script/yylex.l
deleted file mode 100644 (file)
index 7d4ea9e..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-%{
-/* yylex.l  The scripting lexer.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/parser.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/script_sh.h>
-#include "grub_script.tab.h"
-
-#define yyfree    grub_lexer_yyfree
-#define yyalloc   grub_lexer_yyalloc
-#define yyrealloc grub_lexer_yyrealloc
-
-/* 
- * As we don't have access to yyscanner, we cannot do much except to
- * print the fatal error.
- */
-#define YY_FATAL_ERROR(msg)                     \
-  do {                                          \
-    grub_printf ("fatal error: %s\n", msg);     \
-  } while (0)
-
-#define COPY(str, hint)                         \
-  do {                                          \
-    copy_string (yyextra, str, hint);           \
-  } while (0)
-
-
-#define RECORD                                  \
-  do {                                          \
-    grub_script_lexer_record (yyextra, yytext); \
-  } while (0)
-
-#define ARG(t)                        \
-  do {                                \
-    yyextra->lexerstate->type = t;    \
-    return GRUB_PARSER_TOKEN_WORD;    \
-  } while (0)
-
-/* We don't need YY_INPUT, as we rely on yy_scan_strings */
-#define YY_INPUT(buf,res,max) do { res = 0; } while (0)
-
-/* forward declarations */
-static void  grub_lexer_yyfree (void *, yyscan_t yyscanner);
-static void* grub_lexer_yyalloc (yy_size_t, yyscan_t yyscanner);
-static void* grub_lexer_yyrealloc (void*, yy_size_t, yyscan_t yyscanner);
-static void  copy_string (struct grub_parser_param *, const char *,
-                          unsigned hint);
-
-%}
-
-%top{
-
-#include <sys/types.h>
-
-typedef size_t yy_size_t;
-#define YY_TYPEDEF_YY_SIZE_T 1
-
-/* 
- * Some flex hacks for -nostdinc; XXX We need to fix these when libc
- * support becomes availble in GRUB.
- */
-
-#ifndef GRUB_UTIL
-#define stdin  0
-#define stdout 0
-
-#define fprintf(...) 0
-#define exit(...)
-#endif
-
-}
-
-%option ecs
-%option meta-ecs
-
-%option warn
-%option array
-%option stack
-%option reentrant
-%option bison-bridge
-%option never-interactive
-
-%option noyyfree noyyalloc noyyrealloc
-%option nounistd nostdinit nodefault noyylineno noyywrap
-
-/* Reduce lexer size, by not defining these.  */
-%option noyy_top_state
-%option noinput nounput
-%option noyyget_in noyyset_in
-%option noyyget_out noyyset_out
-%option noyyget_debug noyyset_debug
-%option noyyget_lineno noyyset_lineno
-
-%option extra-type="struct grub_parser_param*"
-
-BLANK           [ \t]
-COMMENT         #.*$
-
-CHAR            [^{}|&$;<> \t\n\'\"\\]
-DIGITS          [[:digit:]]+
-NAME            [[:alpha:]_][[:alnum:][:digit:]_]*
-
-ESC             \\.
-VARIABLE        ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|$\?|$\{\?\}
-DQSTR           \"([^\\\"]|{ESC})*\"
-SQSTR           \'[^\']*\'
-WORD            ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+
-
-%x              SPLIT
-%x              DQUOTE
-%x              SQUOTE
-%x              VAR
-
-%%
-
- /* White spaces */
-{BLANK}+        { RECORD; }
-{COMMENT}       { RECORD; }
-
- /* Special symbols */
-"\n"            { RECORD; return GRUB_PARSER_TOKEN_NEWLINE; }
-"||"            { RECORD; return GRUB_PARSER_TOKEN_OR;      }
-"&&"            { RECORD; return GRUB_PARSER_TOKEN_AND;     }
-";;"            { RECORD; return GRUB_PARSER_TOKEN_SEMI2;   }
-"|"             { RECORD; return GRUB_PARSER_TOKEN_PIPE;    }
-"&"             { RECORD; return GRUB_PARSER_TOKEN_AMP;     }
-";"             { RECORD; return GRUB_PARSER_TOKEN_SEMI;    }
-"<"             { RECORD; return GRUB_PARSER_TOKEN_LT;      }
-">"             { RECORD; return GRUB_PARSER_TOKEN_GT;      }
-
- /* Reserved words */
-"!"             { RECORD; return GRUB_PARSER_TOKEN_NOT;       }
-"{"             { RECORD; return GRUB_PARSER_TOKEN_LBR;       }
-"}"             { RECORD; return GRUB_PARSER_TOKEN_RBR;       }
-"[["            { RECORD; return GRUB_PARSER_TOKEN_RSQBR2;    }
-"]]"            { RECORD; return GRUB_PARSER_TOKEN_LSQBR2;    }
-"time"          { RECORD; return GRUB_PARSER_TOKEN_TIME;      }
-"case"          { RECORD; return GRUB_PARSER_TOKEN_CASE;      }
-"do"            { RECORD; return GRUB_PARSER_TOKEN_DO;        }
-"done"          { RECORD; return GRUB_PARSER_TOKEN_DONE;      }
-"elif"          { RECORD; return GRUB_PARSER_TOKEN_ELIF;      }
-"else"          { RECORD; return GRUB_PARSER_TOKEN_ELSE;      }
-"esac"          { RECORD; return GRUB_PARSER_TOKEN_ESAC;      }
-"fi"            { RECORD; return GRUB_PARSER_TOKEN_FI;        }
-"for"           { RECORD; return GRUB_PARSER_TOKEN_FOR;       }
-"if"            { RECORD; return GRUB_PARSER_TOKEN_IF;        }
-"in"            { RECORD; return GRUB_PARSER_TOKEN_IN;        }
-"select"        { RECORD; return GRUB_PARSER_TOKEN_SELECT;    }
-"then"          { RECORD; return GRUB_PARSER_TOKEN_THEN;      }
-"until"         { RECORD; return GRUB_PARSER_TOKEN_UNTIL;     }
-"while"         { RECORD; return GRUB_PARSER_TOKEN_WHILE;     }
-"function"      { RECORD; return GRUB_PARSER_TOKEN_FUNCTION;  }
-"menuentry"     { RECORD; return GRUB_PARSER_TOKEN_MENUENTRY; }
-
-{NAME}          { RECORD; return GRUB_PARSER_TOKEN_NAME; }
-{WORD}          {
-                  RECORD;
-                  /* resplit yytext */
-                 grub_dprintf ("lexer", "word: [%s]\n", yytext);
-                  yypush_buffer_state (YY_CURRENT_BUFFER, yyscanner);
-                  if (yy_scan_string (yytext, yyscanner))
-                    {
-                      yyextra->lexerstate->merge_start = 1;
-                      yy_push_state (SPLIT, yyscanner);
-                    }
-                  else
-                    {
-                      grub_script_yyerror (yyextra, 0);
-                      yypop_buffer_state (yyscanner);
-                      return GRUB_PARSER_TOKEN_WORD;
-                    }
-                }
-
-.|\n            {
-                  grub_script_yyerror (yyextra, "unrecognized token");
-                  return GRUB_PARSER_TOKEN_BAD;
-                }
-
- /* Split word into multiple args */
-
-<SPLIT>{
-  \\.           { COPY (yytext + 1, yyleng - 1); }
-  \"            {
-                  yy_push_state (DQUOTE, yyscanner);
-                  ARG (GRUB_SCRIPT_ARG_TYPE_TEXT);
-                }
-  \'            {
-                  yy_push_state (SQUOTE, yyscanner);
-                  ARG (GRUB_SCRIPT_ARG_TYPE_TEXT);
-                }
-  \$            {
-                  yy_push_state (VAR, yyscanner);
-                  ARG (GRUB_SCRIPT_ARG_TYPE_TEXT);
-                }
-  \\            |
-  [^\"\'\$\\]+  { COPY (yytext, yyleng); }
-  <<EOF>>       {
-                  yy_pop_state (yyscanner);
-                  yypop_buffer_state (yyscanner);
-                  yyextra->lexerstate->merge_end = 1;
-                  ARG (GRUB_SCRIPT_ARG_TYPE_TEXT);
-                }
-}
-
-<VAR>{
-  \?            |
-  {DIGITS}      |
-  {NAME}        {
-                  COPY (yytext, yyleng);
-                  yy_pop_state (yyscanner);
-                  if (YY_START == SPLIT)
-                    ARG (GRUB_SCRIPT_ARG_TYPE_VAR);
-                  else
-                    ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR);
-                }
-  \{\?\}        |
-  \{{DIGITS}\}  |
-  \{{NAME}\}    {
-                  yytext[yyleng - 1] = '\0';
-                  COPY (yytext + 1, yyleng - 2);
-                  yy_pop_state (yyscanner);
-                  if (YY_START == SPLIT)
-                    ARG (GRUB_SCRIPT_ARG_TYPE_VAR);
-                  else
-                    ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR);
-                }
-  .|\n          { return GRUB_PARSER_TOKEN_BAD; }
-}
-
-<SQUOTE>{
-  \'            {
-                  yy_pop_state (yyscanner);
-                  ARG (GRUB_SCRIPT_ARG_TYPE_SQSTR);
-                }
-  [^\']+        { COPY (yytext, yyleng); }
-}
-
-<DQUOTE>{
-  \\\$          { COPY ("$", 1); }
-  \\\\          { COPY ("\\", 1); }
-  \\\"          { COPY ("\"", 1); }
-  \\\n          { /* ignore */ }
-  [^\"\$\\\n]+  { COPY (yytext, yyleng); }
-  \"            {
-                  yy_pop_state (yyscanner);
-                  ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR);
-                }
-  \$            {
-                  yy_push_state (VAR, yyscanner);
-                  ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR);
-                }
-  (.|\n)        { COPY (yytext, yyleng); }
-}
-
-<<EOF>>         {
-                  yypop_buffer_state (yyscanner);
-                  if (! grub_script_lexer_yywrap (yyextra))
-                    {
-                      yyextra->lexerstate->eof = 1;
-                      return GRUB_PARSER_TOKEN_EOF;
-                    }
-                }
-
-%%
-
-static void
-grub_lexer_yyfree (void *ptr, yyscan_t yyscanner __attribute__ ((unused)))
-{
-  grub_free(ptr);
-}
-
-static void*
-grub_lexer_yyalloc (yy_size_t size, yyscan_t yyscanner __attribute__ ((unused)))
-{
-  return grub_malloc (size);
-}
-
-static void*
-grub_lexer_yyrealloc (void *ptr, yy_size_t size,
-                      yyscan_t yyscanner __attribute__ ((unused)))
-{
-  return grub_realloc (ptr, size);
-}
-
-#define MAX(a,b) ((a) < (b) ? (b) : (a))
-
-static void copy_string (struct grub_parser_param *parser, const char *str, unsigned hint)
-{
-  int size;
-  char *ptr;
-  unsigned len;
-
-  len = hint ? hint : grub_strlen (str);
-  if (parser->lexerstate->used + len >= parser->lexerstate->size)
-    {
-      size = MAX (len, parser->lexerstate->size) * 2;
-      ptr = grub_realloc (parser->lexerstate->text, size);
-      if (!ptr)
-        {
-          grub_script_yyerror (parser, 0);
-          return;
-        }
-
-      parser->lexerstate->text = ptr;
-      parser->lexerstate->size = size;
-    }
-  grub_strcpy (parser->lexerstate->text + parser->lexerstate->used - 1, str);
-  parser->lexerstate->used += len;
-}
diff --git a/term/at_keyboard.c b/term/at_keyboard.c
deleted file mode 100644 (file)
index 1f84ae7..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/at_keyboard.h>
-#include <grub/cpu/at_keyboard.h>
-#include <grub/cpu/io.h>
-#include <grub/misc.h>
-#include <grub/term.h>
-
-static short at_keyboard_status = 0;
-static int pending_key = -1;
-
-#define KEYBOARD_STATUS_SHIFT_L                (1 << 0)
-#define KEYBOARD_STATUS_SHIFT_R                (1 << 1)
-#define KEYBOARD_STATUS_ALT_L          (1 << 2)
-#define KEYBOARD_STATUS_ALT_R          (1 << 3)
-#define KEYBOARD_STATUS_CTRL_L         (1 << 4)
-#define KEYBOARD_STATUS_CTRL_R         (1 << 5)
-#define KEYBOARD_STATUS_CAPS_LOCK      (1 << 6)
-#define KEYBOARD_STATUS_NUM_LOCK       (1 << 7)
-
-static grub_uint8_t led_status;
-
-#define KEYBOARD_LED_SCROLL            (1 << 0)
-#define KEYBOARD_LED_NUM               (1 << 1)
-#define KEYBOARD_LED_CAPS              (1 << 2)
-
-static char keyboard_map[128] =
-{
-  '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6',
-  '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB,
-  'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
-  'o', 'p', '[', ']', '\n', '\0', 'a', 's',
-  'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
-  '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v',
-  'b', 'n', 'm', ',', '.', '/', '\0', '*',
-  '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0',
-  '\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_HOME,
-  GRUB_TERM_UP, GRUB_TERM_NPAGE, '-', GRUB_TERM_LEFT, '\0', GRUB_TERM_RIGHT, '+', GRUB_TERM_END,
-  GRUB_TERM_DOWN, GRUB_TERM_PPAGE, '\0', GRUB_TERM_DC, '\0', '\0', '\0', '\0',
-  '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
-  '\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT,
-  OLPC_RIGHT
-};
-
-static char keyboard_map_shift[128] =
-{
-  '\0', '\0', '!', '@', '#', '$', '%', '^',
-  '&', '*', '(', ')', '_', '+', '\0', '\0',
-  'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
-  'O', 'P', '{', '}', '\n', '\0', 'A', 'S',
-  'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
-  '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V',
-  'B', 'N', 'M', '<', '>', '?'
-};
-
-static grub_uint8_t grub_keyboard_controller_orig;
-
-static void
-keyboard_controller_wait_until_ready (void)
-{
-  while (! KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS)));
-}
-
-static void
-grub_keyboard_controller_write (grub_uint8_t c)
-{
-  keyboard_controller_wait_until_ready ();
-  grub_outb (KEYBOARD_COMMAND_WRITE, KEYBOARD_REG_STATUS);
-  grub_outb (c, KEYBOARD_REG_DATA);
-}
-
-static grub_uint8_t
-grub_keyboard_controller_read (void)
-{
-  keyboard_controller_wait_until_ready ();
-  grub_outb (KEYBOARD_COMMAND_READ, KEYBOARD_REG_STATUS);
-  return grub_inb (KEYBOARD_REG_DATA);
-}
-
-static void
-keyboard_controller_led (grub_uint8_t leds)
-{
-  keyboard_controller_wait_until_ready ();
-  grub_outb (0xed, KEYBOARD_REG_DATA);
-  keyboard_controller_wait_until_ready ();
-  grub_outb (leds & 0x7, KEYBOARD_REG_DATA);
-}
-
-/* FIXME: This should become an interrupt service routine.  For now
-   it's just used to catch events from control keys.  */
-static void
-grub_keyboard_isr (char key)
-{
-  char is_make = KEYBOARD_ISMAKE (key);
-  key = KEYBOARD_SCANCODE (key);
-  if (is_make)
-    switch (key)
-      {
-       case SHIFT_L:
-         at_keyboard_status |= KEYBOARD_STATUS_SHIFT_L;
-         break;
-       case SHIFT_R:
-         at_keyboard_status |= KEYBOARD_STATUS_SHIFT_R;
-         break;
-       case CTRL:
-         at_keyboard_status |= KEYBOARD_STATUS_CTRL_L;
-         break;
-       case ALT:
-         at_keyboard_status |= KEYBOARD_STATUS_ALT_L;
-         break;
-       default:
-         /* Skip grub_dprintf.  */
-         return;
-      }
-  else
-    switch (key)
-      {
-       case SHIFT_L:
-         at_keyboard_status &= ~KEYBOARD_STATUS_SHIFT_L;
-         break;
-       case SHIFT_R:
-         at_keyboard_status &= ~KEYBOARD_STATUS_SHIFT_R;
-         break;
-       case CTRL:
-         at_keyboard_status &= ~KEYBOARD_STATUS_CTRL_L;
-         break;
-       case ALT:
-         at_keyboard_status &= ~KEYBOARD_STATUS_ALT_L;
-         break;
-       default:
-         /* Skip grub_dprintf.  */
-         return;
-      }
-#ifdef DEBUG_AT_KEYBOARD
-  grub_dprintf ("atkeyb", "Control key 0x%0x was %s\n", key, is_make ? "pressed" : "unpressed");
-#endif
-}
-
-/* If there is a raw key pending, return it; otherwise return -1.  */
-static int
-grub_keyboard_getkey (void)
-{
-  grub_uint8_t key;
-  if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS)))
-    return -1;
-  key = grub_inb (KEYBOARD_REG_DATA);
-  /* FIXME */ grub_keyboard_isr (key);
-  if (! KEYBOARD_ISMAKE (key))
-    return -1;
-  return (KEYBOARD_SCANCODE (key));
-}
-
-/* If there is a character pending, return it; otherwise return -1.  */
-static int
-grub_at_keyboard_getkey_noblock (void)
-{
-  int code, key;
-  code = grub_keyboard_getkey ();
-  if (code == -1)
-    return -1;
-#ifdef DEBUG_AT_KEYBOARD
-  grub_dprintf ("atkeyb", "Detected key 0x%x\n", key);
-#endif
-  switch (code)
-    {
-      case CAPS_LOCK:
-       /* Caps lock sends scan code twice.  Get the second one and discard it.  */
-       while (grub_keyboard_getkey () == -1);
-
-       at_keyboard_status ^= KEYBOARD_STATUS_CAPS_LOCK;
-       led_status ^= KEYBOARD_LED_CAPS;
-       keyboard_controller_led (led_status);
-
-#ifdef DEBUG_AT_KEYBOARD
-       grub_dprintf ("atkeyb", "caps_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK));
-#endif
-       key = -1;
-       break;
-      case NUM_LOCK:
-       /* Num lock sends scan code twice.  Get the second one and discard it.  */
-       while (grub_keyboard_getkey () == -1);
-
-       at_keyboard_status ^= KEYBOARD_STATUS_NUM_LOCK;
-       led_status ^= KEYBOARD_LED_NUM;
-       keyboard_controller_led (led_status);
-
-#ifdef DEBUG_AT_KEYBOARD
-       grub_dprintf ("atkeyb", "num_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_NUM_LOCK));
-#endif
-       key = -1;
-       break;
-      case SCROLL_LOCK:
-       /* For scroll lock we don't keep track of status.  Only update its led.  */
-       led_status ^= KEYBOARD_LED_SCROLL;
-       keyboard_controller_led (led_status);
-       key = -1;
-       break;
-      default:
-       if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L | KEYBOARD_STATUS_CTRL_R))
-         key = keyboard_map[code] - 'a' + 1;
-       else if ((at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L | KEYBOARD_STATUS_SHIFT_R))
-           && keyboard_map_shift[code])
-         key = keyboard_map_shift[code];
-       else
-         key = keyboard_map[code];
-
-       if (key == 0)
-         grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code);
-
-       if (at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK)
-         {
-           if ((key >= 'a') && (key <= 'z'))
-             key += 'A' - 'a';
-           else if ((key >= 'A') && (key <= 'Z'))
-             key += 'a' - 'A';
-         }
-    }
-  return key;
-}
-
-static int
-grub_at_keyboard_checkkey (void)
-{
-  if (pending_key != -1)
-    return 1;
-
-  pending_key = grub_at_keyboard_getkey_noblock ();
-
-  if (pending_key != -1)
-    return 1;
-
-  return -1;
-}
-
-static int
-grub_at_keyboard_getkey (void)
-{
-  int key;
-  if (pending_key != -1)
-    {
-      key = pending_key;
-      pending_key = -1;
-      return key;
-    }
-  do
-    {
-      key = grub_at_keyboard_getkey_noblock ();
-    } while (key == -1);
-  return key;
-}
-
-static grub_err_t
-grub_keyboard_controller_init (void)
-{
-  pending_key = -1;
-  at_keyboard_status = 0;
-  grub_keyboard_controller_orig = grub_keyboard_controller_read ();
-  grub_keyboard_controller_write (grub_keyboard_controller_orig | KEYBOARD_SCANCODE_SET1);
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_keyboard_controller_fini (void)
-{
-  grub_keyboard_controller_write (grub_keyboard_controller_orig);
-  return GRUB_ERR_NONE;
-}
-
-static struct grub_term_input grub_at_keyboard_term =
-  {
-    .name = "at_keyboard",
-    .init = grub_keyboard_controller_init,
-    .fini = grub_keyboard_controller_fini,
-    .checkkey = grub_at_keyboard_checkkey,
-    .getkey = grub_at_keyboard_getkey,
-  };
-
-GRUB_MOD_INIT(at_keyboard)
-{
-  grub_term_register_input ("at_keyboard", &grub_at_keyboard_term);
-}
-
-GRUB_MOD_FINI(at_keyboard)
-{
-  grub_term_unregister_input (&grub_at_keyboard_term);
-}
diff --git a/term/efi/console.c b/term/efi/console.c
deleted file mode 100644 (file)
index 6648613..0000000
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/term.h>
-#include <grub/misc.h>
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/efi/efi.h>
-#include <grub/efi/api.h>
-#include <grub/efi/console.h>
-
-static grub_uint8_t
-grub_console_standard_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_YELLOW,
-                                                 GRUB_EFI_BACKGROUND_BLACK);
-static grub_uint8_t
-grub_console_normal_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_LIGHTGRAY,
-                                               GRUB_EFI_BACKGROUND_BLACK);
-static grub_uint8_t
-grub_console_highlight_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_BLACK,
-                                                  GRUB_EFI_BACKGROUND_LIGHTGRAY);
-
-static int read_key = -1;
-
-static grub_uint32_t
-map_char (grub_uint32_t c)
-{
-  if (c > 0x7f)
-    {
-      /* Map some unicode characters to the EFI character.  */
-      switch (c)
-       {
-       case 0x2190:    /* left arrow */
-         c = 0x25c4;
-         break;
-       case 0x2191:    /* up arrow */
-         c = 0x25b2;
-         break;
-       case 0x2192:    /* right arrow */
-         c = 0x25ba;
-         break;
-       case 0x2193:    /* down arrow */
-         c = 0x25bc;
-         break;
-       case 0x2501:    /* horizontal line */
-         c = 0x2500;
-         break;
-       case 0x2503:    /* vertical line */
-         c = 0x2502;
-         break;
-       case 0x250F:    /* upper-left corner */
-         c = 0x250c;
-         break;
-       case 0x2513:    /* upper-right corner */
-         c = 0x2510;
-         break;
-       case 0x2517:    /* lower-left corner */
-         c = 0x2514;
-         break;
-       case 0x251B:    /* lower-right corner */
-         c = 0x2518;
-         break;
-
-       default:
-         c = '?';
-         break;
-       }
-    }
-
-  return c;
-}
-
-static void
-grub_console_putchar (grub_uint32_t c)
-{
-  grub_efi_char16_t str[2];
-  grub_efi_simple_text_output_interface_t *o;
-
-  o = grub_efi_system_table->con_out;
-
-  /* For now, do not try to use a surrogate pair.  */
-  if (c > 0xffff)
-    c = '?';
-
-  str[0] = (grub_efi_char16_t)  map_char (c & 0xffff);
-  str[1] = 0;
-
-  /* Should this test be cached?  */
-  if (c > 0x7f && efi_call_2 (o->test_string, o, str) != GRUB_EFI_SUCCESS)
-    return;
-
-  efi_call_2 (o->output_string, o, str);
-}
-
-static grub_ssize_t
-grub_console_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
-{
-  /* For now, every printable character has the width 1.  */
-  return 1;
-}
-
-static int
-grub_console_checkkey (void)
-{
-  grub_efi_simple_input_interface_t *i;
-  grub_efi_input_key_t key;
-  grub_efi_status_t status;
-
-  if (read_key >= 0)
-    return 1;
-
-  i = grub_efi_system_table->con_in;
-  status = efi_call_2 (i->read_key_stroke, i, &key);
-#if 0
-  switch (status)
-    {
-    case GRUB_EFI_SUCCESS:
-      {
-       grub_uint16_t xy;
-
-       xy = grub_getxy ();
-       grub_gotoxy (0, 0);
-       grub_printf ("scan_code=%x,unicode_char=%x  ",
-                    (unsigned) key.scan_code,
-                    (unsigned) key.unicode_char);
-       grub_gotoxy (xy >> 8, xy & 0xff);
-      }
-      break;
-
-    case GRUB_EFI_NOT_READY:
-      //grub_printf ("not ready   ");
-      break;
-
-    default:
-      //grub_printf ("device error   ");
-      break;
-    }
-#endif
-
-  if (status == GRUB_EFI_SUCCESS)
-    {
-      switch (key.scan_code)
-       {
-       case 0x00:
-         read_key = key.unicode_char;
-         break;
-       case 0x01:
-         read_key = GRUB_TERM_UP;
-         break;
-       case 0x02:
-         read_key = GRUB_TERM_DOWN;
-         break;
-       case 0x03:
-         read_key = GRUB_TERM_RIGHT;
-         break;
-       case 0x04:
-         read_key = GRUB_TERM_LEFT;
-         break;
-       case 0x05:
-         read_key = GRUB_TERM_HOME;
-         break;
-       case 0x06:
-         read_key = GRUB_TERM_END;
-         break;
-       case 0x07:
-         break;
-       case 0x08:
-         read_key = GRUB_TERM_DC;
-         break;
-       case 0x09:
-         break;
-       case 0x0a:
-         break;
-       case 0x0b:
-         read_key = 24;
-         break;
-       case 0x0c:
-         read_key = 1;
-         break;
-       case 0x0d:
-         read_key = 5;
-         break;
-       case 0x0e:
-         read_key = 3;
-         break;
-       case 0x17:
-         read_key = '\e';
-         break;
-       default:
-         break;
-       }
-    }
-
-  return read_key;
-}
-
-static int
-grub_console_getkey (void)
-{
-  grub_efi_simple_input_interface_t *i;
-  grub_efi_boot_services_t *b;
-  grub_efi_uintn_t index;
-  grub_efi_status_t status;
-  int key;
-
-  if (read_key >= 0)
-    {
-      key = read_key;
-      read_key = -1;
-      return key;
-    }
-
-  i = grub_efi_system_table->con_in;
-  b = grub_efi_system_table->boot_services;
-
-  do
-    {
-      status = efi_call_3 (b->wait_for_event, 1, &(i->wait_for_key), &index);
-      if (status != GRUB_EFI_SUCCESS)
-        return -1;
-
-      grub_console_checkkey ();
-    }
-  while (read_key < 0);
-
-  key = read_key;
-  read_key = -1;
-  return key;
-}
-
-static grub_uint16_t
-grub_console_getwh (void)
-{
-  grub_efi_simple_text_output_interface_t *o;
-  grub_efi_uintn_t columns, rows;
-
-  o = grub_efi_system_table->con_out;
-  if (efi_call_4 (o->query_mode, o, o->mode->mode, &columns, &rows) != GRUB_EFI_SUCCESS)
-    {
-      /* Why does this fail?  */
-      columns = 80;
-      rows = 25;
-    }
-
-  return ((columns << 8) | rows);
-}
-
-static grub_uint16_t
-grub_console_getxy (void)
-{
-  grub_efi_simple_text_output_interface_t *o;
-
-  o = grub_efi_system_table->con_out;
-  return ((o->mode->cursor_column << 8) | o->mode->cursor_row);
-}
-
-static void
-grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y)
-{
-  grub_efi_simple_text_output_interface_t *o;
-
-  o = grub_efi_system_table->con_out;
-  efi_call_3 (o->set_cursor_position, o, x, y);
-}
-
-static void
-grub_console_cls (void)
-{
-  grub_efi_simple_text_output_interface_t *o;
-  grub_efi_int32_t orig_attr;
-
-  o = grub_efi_system_table->con_out;
-  orig_attr = o->mode->attribute;
-  efi_call_2 (o->set_attributes, o, GRUB_EFI_BACKGROUND_BLACK);
-  efi_call_1 (o->clear_screen, o);
-  efi_call_2 (o->set_attributes, o, orig_attr);
-}
-
-static void
-grub_console_setcolorstate (grub_term_color_state state)
-{
-  grub_efi_simple_text_output_interface_t *o;
-
-  o = grub_efi_system_table->con_out;
-
-  switch (state) {
-    case GRUB_TERM_COLOR_STANDARD:
-      efi_call_2 (o->set_attributes, o, grub_console_standard_color);
-      break;
-    case GRUB_TERM_COLOR_NORMAL:
-      efi_call_2 (o->set_attributes, o, grub_console_normal_color);
-      break;
-    case GRUB_TERM_COLOR_HIGHLIGHT:
-      efi_call_2 (o->set_attributes, o, grub_console_highlight_color);
-      break;
-    default:
-      break;
-  }
-}
-
-static void
-grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
-{
-  grub_console_normal_color = normal_color;
-  grub_console_highlight_color = highlight_color;
-}
-
-static void
-grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
-{
-  *normal_color = grub_console_normal_color;
-  *highlight_color = grub_console_highlight_color;
-}
-
-static void
-grub_console_setcursor (int on)
-{
-  grub_efi_simple_text_output_interface_t *o;
-
-  o = grub_efi_system_table->con_out;
-  efi_call_2 (o->enable_cursor, o, on);
-}
-
-static struct grub_term_input grub_console_term_input =
-  {
-    .name = "console",
-    .checkkey = grub_console_checkkey,
-    .getkey = grub_console_getkey,
-  };
-
-static struct grub_term_output grub_console_term_output =
-  {
-    .name = "console",
-    .putchar = grub_console_putchar,
-    .getcharwidth = grub_console_getcharwidth,
-    .getwh = grub_console_getwh,
-    .getxy = grub_console_getxy,
-    .gotoxy = grub_console_gotoxy,
-    .cls = grub_console_cls,
-    .setcolorstate = grub_console_setcolorstate,
-    .setcolor = grub_console_setcolor,
-    .getcolor = grub_console_getcolor,
-    .setcursor = grub_console_setcursor
-  };
-
-void
-grub_console_init (void)
-{
-  /* FIXME: it is necessary to consider the case where no console control
-     is present but the default is already in text mode.  */
-  if (! grub_efi_set_text_mode (1))
-    {
-      grub_error (GRUB_ERR_BAD_DEVICE, "cannot set text mode");
-      return;
-    }
-
-  grub_term_register_input ("console", &grub_console_term_input);
-  grub_term_register_output ("console", &grub_console_term_output);
-}
-
-void
-grub_console_fini (void)
-{
-  grub_term_unregister_input (&grub_console_term_input);
-  grub_term_unregister_output (&grub_console_term_output);
-}
diff --git a/term/gfxterm.c b/term/gfxterm.c
deleted file mode 100644 (file)
index ecfe4ff..0000000
+++ /dev/null
@@ -1,1200 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/term.h>
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/font.h>
-#include <grub/mm.h>
-#include <grub/env.h>
-#include <grub/video.h>
-#include <grub/gfxterm.h>
-#include <grub/bitmap.h>
-#include <grub/command.h>
-#include <grub/extcmd.h>
-#include <grub/bitmap_scale.h>
-#include <grub/i18n.h>
-
-#define DEFAULT_VIDEO_MODE     "auto"
-#define DEFAULT_BORDER_WIDTH   10
-
-#define DEFAULT_STANDARD_COLOR  0x07
-#define DEFAULT_NORMAL_COLOR    0x07
-#define DEFAULT_HIGHLIGHT_COLOR 0x70
-
-struct grub_dirty_region
-{
-  int top_left_x;
-  int top_left_y;
-  int bottom_right_x;
-  int bottom_right_y;
-};
-
-struct grub_colored_char
-{
-  /* An Unicode codepoint.  */
-  grub_uint32_t code;
-
-  /* Color values.  */
-  grub_video_color_t fg_color;
-  grub_video_color_t bg_color;
-
-  /* The width of this character minus one.  */
-  unsigned char width;
-
-  /* The column index of this character.  */
-  unsigned char index;
-};
-
-struct grub_virtual_screen
-{
-  /* Dimensions of the virtual screen in pixels.  */
-  unsigned int width;
-  unsigned int height;
-
-  /* Offset in the display in pixels.  */
-  unsigned int offset_x;
-  unsigned int offset_y;
-
-  /* TTY Character sizes in pixes.  */
-  unsigned int normal_char_width;
-  unsigned int normal_char_height;
-
-  /* Virtual screen TTY size in characters.  */
-  unsigned int columns;
-  unsigned int rows;
-
-  /* Current cursor location in characters.  */
-  unsigned int cursor_x;
-  unsigned int cursor_y;
-
-  /* Current cursor state. */
-  int cursor_state;
-
-  /* Font settings. */
-  grub_font_t font;
-
-  /* Terminal color settings.  */
-  grub_uint8_t standard_color_setting;
-  grub_uint8_t normal_color_setting;
-  grub_uint8_t highlight_color_setting;
-  grub_uint8_t term_color;
-
-  /* Color settings.  */
-  grub_video_color_t fg_color;
-  grub_video_color_t bg_color;
-  grub_video_color_t bg_color_display;
-
-  /* Text buffer for virtual screen.  Contains (columns * rows) number
-     of entries.  */
-  struct grub_colored_char *text_buffer;
-
-  int total_scroll;
-};
-
-struct grub_gfxterm_window
-{
-  unsigned x;
-  unsigned y;
-  unsigned width;
-  unsigned height;
-  int double_repaint;
-};
-
-static struct grub_video_render_target *render_target;
-void (*grub_gfxterm_decorator_hook) (void) = NULL;
-static struct grub_gfxterm_window window;
-static struct grub_virtual_screen virtual_screen;
-static grub_gfxterm_repaint_callback_t repaint_callback;
-static int repaint_schedulded = 0;
-static int repaint_was_schedulded = 0;
-
-static void destroy_window (void);
-
-static struct grub_video_render_target *text_layer;
-
-static unsigned int bitmap_width;
-static unsigned int bitmap_height;
-static struct grub_video_bitmap *bitmap;
-
-static struct grub_dirty_region dirty_region;
-
-static void dirty_region_reset (void);
-
-static int dirty_region_is_empty (void);
-
-static void dirty_region_add (int x, int y,
-                              unsigned int width, unsigned int height);
-
-static unsigned int calculate_normal_character_width (grub_font_t font);
-
-static unsigned char calculate_character_width (struct grub_font_glyph *glyph);
-
-static void grub_gfxterm_refresh (void);
-
-static void
-set_term_color (grub_uint8_t term_color)
-{
-  struct grub_video_render_target *old_target;
-
-  /* Save previous target and switch to text layer.  */
-  grub_video_get_active_render_target (&old_target);
-  grub_video_set_active_render_target (text_layer);
-
-  /* Map terminal color to text layer compatible video colors.  */
-  virtual_screen.fg_color = grub_video_map_color(term_color & 0x0f);
-
-  /* Special case: use black as transparent color.  */
-  if (((term_color >> 4) & 0x0f) == 0)
-    {
-      virtual_screen.bg_color = grub_video_map_rgba(0, 0, 0, 0);
-    }
-  else
-    {
-      virtual_screen.bg_color = grub_video_map_color((term_color >> 4) & 0x0f);
-    }
-
-  /* Restore previous target.  */
-  grub_video_set_active_render_target (old_target);
-}
-
-static void
-clear_char (struct grub_colored_char *c)
-{
-  c->code = ' ';
-  c->fg_color = virtual_screen.fg_color;
-  c->bg_color = virtual_screen.bg_color;
-  c->width = 0;
-  c->index = 0;
-}
-
-static void
-grub_virtual_screen_free (void)
-{
-  /* If virtual screen has been allocated, free it.  */
-  if (virtual_screen.text_buffer != 0)
-    grub_free (virtual_screen.text_buffer);
-
-  /* Reset virtual screen data.  */
-  grub_memset (&virtual_screen, 0, sizeof (virtual_screen));
-
-  /* Free render targets.  */
-  grub_video_delete_render_target (text_layer);
-  text_layer = 0;
-}
-
-static grub_err_t
-grub_virtual_screen_setup (unsigned int x, unsigned int y,
-                           unsigned int width, unsigned int height,
-                           const char *font_name)
-{
-  unsigned int i;
-
-  /* Free old virtual screen.  */
-  grub_virtual_screen_free ();
-
-  /* Initialize with default data.  */
-  virtual_screen.font = grub_font_get (font_name);
-  if (!virtual_screen.font)
-    return grub_error (GRUB_ERR_BAD_FONT,
-                       "no font loaded");
-  virtual_screen.width = width;
-  virtual_screen.height = height;
-  virtual_screen.offset_x = x;
-  virtual_screen.offset_y = y;
-  virtual_screen.normal_char_width =
-    calculate_normal_character_width (virtual_screen.font);
-  virtual_screen.normal_char_height =
-    grub_font_get_max_char_height (virtual_screen.font);
-  virtual_screen.cursor_x = 0;
-  virtual_screen.cursor_y = 0;
-  virtual_screen.cursor_state = 1;
-  virtual_screen.total_scroll = 0;
-
-  /* Calculate size of text buffer.  */
-  virtual_screen.columns = virtual_screen.width / virtual_screen.normal_char_width;
-  virtual_screen.rows = virtual_screen.height / virtual_screen.normal_char_height;
-
-  /* Allocate memory for text buffer.  */
-  virtual_screen.text_buffer =
-    (struct grub_colored_char *) grub_malloc (virtual_screen.columns
-                                              * virtual_screen.rows
-                                              * sizeof (*virtual_screen.text_buffer));
-  if (grub_errno != GRUB_ERR_NONE)
-    return grub_errno;
-
-  /* Create new render target for text layer.  */
-  grub_video_create_render_target (&text_layer,
-                                   virtual_screen.width,
-                                   virtual_screen.height,
-                                   GRUB_VIDEO_MODE_TYPE_RGB
-                                   | GRUB_VIDEO_MODE_TYPE_ALPHA);
-  if (grub_errno != GRUB_ERR_NONE)
-    return grub_errno;
-
-  /* As we want to have colors compatible with rendering target,
-     we can only have those after mode is initialized.  */
-  grub_video_set_active_render_target (text_layer);
-
-  virtual_screen.standard_color_setting = DEFAULT_STANDARD_COLOR;
-  virtual_screen.normal_color_setting = DEFAULT_NORMAL_COLOR;
-  virtual_screen.highlight_color_setting = DEFAULT_HIGHLIGHT_COLOR;
-
-  virtual_screen.term_color = virtual_screen.normal_color_setting;
-
-  set_term_color (virtual_screen.term_color);
-
-  grub_video_set_active_render_target (render_target);
-
-  virtual_screen.bg_color_display = grub_video_map_rgba(0, 0, 0, 0);
-
-  /* Clear out text buffer. */
-  for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
-    clear_char (&(virtual_screen.text_buffer[i]));
-
-  return grub_errno;
-}
-
-void
-grub_gfxterm_schedule_repaint (void)
-{
-  repaint_schedulded = 1;
-}
-
-grub_err_t
-grub_gfxterm_set_window (struct grub_video_render_target *target,
-                        int x, int y, int width, int height,
-                        int double_repaint,
-                        const char *font_name, int border_width)
-{
-  /* Clean up any prior instance.  */
-  destroy_window ();
-
-  /* Set the render target.  */
-  render_target = target;
-
-  /* Create virtual screen.  */
-  if (grub_virtual_screen_setup (border_width, border_width, 
-                                 width - 2 * border_width, 
-                                 height - 2 * border_width, 
-                                 font_name) 
-      != GRUB_ERR_NONE)
-    {
-      return grub_errno;
-    }
-
-  /* Set window bounds.  */
-  window.x = x;
-  window.y = y;
-  window.width = width;
-  window.height = height;
-  window.double_repaint = double_repaint;
-
-  dirty_region_reset ();
-  grub_gfxterm_schedule_repaint ();
-
-  return grub_errno;
-}
-
-grub_err_t
-grub_gfxterm_fullscreen (void)
-{
-  const char *font_name;
-  struct grub_video_mode_info mode_info;
-  grub_video_color_t color;
-  grub_err_t err;
-  int double_redraw;
-
-  err = grub_video_get_info (&mode_info);
-  /* Figure out what mode we ended up.  */
-  if (err)
-    return err;
-
-  grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
-
-  double_redraw = mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
-    && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
-
-  /* Make sure screen is black.  */
-  color = grub_video_map_rgb (0, 0, 0);
-  grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height);
-  if (double_redraw)
-    {
-      grub_video_swap_buffers ();
-      grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height);
-    }
-  bitmap = 0;
-
-  /* Select the font to use.  */
-  font_name = grub_env_get ("gfxterm_font");
-  if (! font_name)
-    font_name = "";   /* Allow fallback to any font.  */
-
-  grub_gfxterm_decorator_hook = NULL;
-
-  return grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY,
-                                 0, 0, mode_info.width, mode_info.height,
-                                 double_redraw,
-                                 font_name, DEFAULT_BORDER_WIDTH);
-}
-
-static grub_err_t
-grub_gfxterm_term_init (void)
-{
-  char *tmp;
-  grub_err_t err;
-  const char *modevar;
-
-  /* Parse gfxmode environment variable if set.  */
-  modevar = grub_env_get ("gfxmode");
-  if (! modevar || *modevar == 0)
-    err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
-                              GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
-  else
-    {
-      tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
-      if (!tmp)
-       return grub_errno;
-      err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
-      grub_free (tmp);
-    }
-
-  if (err)
-    return err;
-
-  err = grub_gfxterm_fullscreen ();
-  if (err)
-    grub_video_restore ();
-
-  return err;
-}
-
-static void
-destroy_window (void)
-{
-  if (bitmap)
-    {
-      grub_video_bitmap_destroy (bitmap);
-      bitmap = 0;
-    }
-
-  repaint_callback = 0;
-  grub_virtual_screen_free ();
-}
-
-static grub_err_t
-grub_gfxterm_term_fini (void)
-{
-  destroy_window ();
-  grub_video_restore ();
-
-  /* Clear error state.  */
-  grub_errno = GRUB_ERR_NONE;
-  return GRUB_ERR_NONE;
-}
-
-static void
-redraw_screen_rect (unsigned int x, unsigned int y,
-                    unsigned int width, unsigned int height)
-{
-  grub_video_color_t color;
-  grub_video_rect_t saved_view;
-
-  grub_video_set_active_render_target (render_target);
-  /* Save viewport and set it to our window.  */
-  grub_video_get_viewport ((unsigned *) &saved_view.x, 
-                           (unsigned *) &saved_view.y, 
-                           (unsigned *) &saved_view.width, 
-                           (unsigned *) &saved_view.height);
-  grub_video_set_viewport (window.x, window.y, window.width, window.height);
-
-  if (bitmap)
-    {
-      /* Render bitmap as background.  */
-      grub_video_blit_bitmap (bitmap, GRUB_VIDEO_BLIT_REPLACE, x, y,
-                             x, y,
-                              width, height);
-
-      /* If bitmap is smaller than requested blit area, use background
-         color.  */
-      color = virtual_screen.bg_color_display;
-
-      /* Fill right side of the bitmap if needed.  */
-      if ((x + width >= bitmap_width) && (y < bitmap_height))
-        {
-          int w = (x + width) - bitmap_width;
-          int h = height;
-          unsigned int tx = x;
-
-          if (y + height >= bitmap_height)
-            {
-              h = bitmap_height - y;
-            }
-
-          if (bitmap_width > tx)
-            {
-              tx = bitmap_width;
-            }
-
-          /* Render background layer.  */
-         grub_video_fill_rect (color, tx, y, w, h);
-        }
-
-      /* Fill bottom side of the bitmap if needed.  */
-      if (y + height >= bitmap_height)
-        {
-          int h = (y + height) - bitmap_height;
-          unsigned int ty = y;
-
-          if (bitmap_height > ty)
-            {
-              ty = bitmap_height;
-            }
-
-          /* Render background layer.  */
-         grub_video_fill_rect (color, x, ty, width, h);
-        }
-
-      /* Render text layer as blended.  */
-      grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, x, y,
-                                     x - virtual_screen.offset_x,
-                                     y - virtual_screen.offset_y,
-                                     width, height);
-    }
-  else
-    {
-      /* Render background layer.  */
-      color = virtual_screen.bg_color_display;
-      grub_video_fill_rect (color, x, y, width, height);
-
-      /* Render text layer as replaced (to get texts background color).  */
-      grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_REPLACE, x, y,
-                                     x - virtual_screen.offset_x,
-                                     y - virtual_screen.offset_y,
-                                    width, height);
-    }
-
-  /* Restore saved viewport.  */
-  grub_video_set_viewport (saved_view.x, saved_view.y,
-                           saved_view.width, saved_view.height);
-  grub_video_set_active_render_target (render_target);
-  
-  if (repaint_callback)
-    repaint_callback (x, y, width, height);
-}
-
-static void
-dirty_region_reset (void)
-{
-  dirty_region.top_left_x = -1;
-  dirty_region.top_left_y = -1;
-  dirty_region.bottom_right_x = -1;
-  dirty_region.bottom_right_y = -1;
-  repaint_was_schedulded = 0;
-}
-
-static int
-dirty_region_is_empty (void)
-{
-  if ((dirty_region.top_left_x == -1)
-      || (dirty_region.top_left_y == -1)
-      || (dirty_region.bottom_right_x == -1)
-      || (dirty_region.bottom_right_y == -1))
-    return 1;
-  return 0;
-}
-
-static void
-dirty_region_add (int x, int y, unsigned int width, unsigned int height)
-{
-  if ((width == 0) || (height == 0))
-    return;
-
-  if (repaint_schedulded)
-    {
-      x = virtual_screen.offset_x;
-      y = virtual_screen.offset_y;
-      width = virtual_screen.width;
-      height = virtual_screen.height;
-      repaint_schedulded = 0;
-      repaint_was_schedulded = 1;
-    }
-
-  if (dirty_region_is_empty ())
-    {
-      dirty_region.top_left_x = x;
-      dirty_region.top_left_y = y;
-      dirty_region.bottom_right_x = x + width - 1;
-      dirty_region.bottom_right_y = y + height - 1;
-    }
-  else
-    {
-      if (x < dirty_region.top_left_x)
-        dirty_region.top_left_x = x;
-      if (y < dirty_region.top_left_y)
-        dirty_region.top_left_y = y;
-      if ((x + (int)width - 1) > dirty_region.bottom_right_x)
-        dirty_region.bottom_right_x = x + width - 1;
-      if ((y + (int)height - 1) > dirty_region.bottom_right_y)
-        dirty_region.bottom_right_y = y + height - 1;
-    }
-}
-
-static void
-dirty_region_add_virtualscreen (void)
-{
-  /* Mark virtual screen as dirty.  */
-  dirty_region_add (virtual_screen.offset_x, virtual_screen.offset_y,
-                    virtual_screen.width, virtual_screen.height);
-}
-
-
-static void
-dirty_region_redraw (void)
-{
-  int x;
-  int y;
-  int width;
-  int height;
-
-  if (dirty_region_is_empty ())
-    return;
-
-  x = dirty_region.top_left_x;
-  y = dirty_region.top_left_y;
-
-  width = dirty_region.bottom_right_x - x + 1;
-  height = dirty_region.bottom_right_y - y + 1;
-
-  if (repaint_was_schedulded && grub_gfxterm_decorator_hook)
-    grub_gfxterm_decorator_hook ();
-
-  redraw_screen_rect (x, y, width, height);
-}
-
-static inline void
-paint_char (unsigned cx, unsigned cy)
-{
-  struct grub_colored_char *p;
-  struct grub_font_glyph *glyph;
-  grub_video_color_t color;
-  grub_video_color_t bgcolor;
-  unsigned int x;
-  unsigned int y;
-  int ascent;
-  unsigned int height;
-  unsigned int width;
-
-  if (cy + virtual_screen.total_scroll >= virtual_screen.rows)
-    return;
-
-  /* Find out active character.  */
-  p = (virtual_screen.text_buffer
-       + cx + (cy * virtual_screen.columns));
-
-  p -= p->index;
-
-  /* Get glyph for character.  */
-  glyph = grub_font_get_glyph (virtual_screen.font, p->code);
-  ascent = grub_font_get_ascent (virtual_screen.font);
-
-  width = virtual_screen.normal_char_width * calculate_character_width(glyph);
-  height = virtual_screen.normal_char_height;
-
-  color = p->fg_color;
-  bgcolor = p->bg_color;
-
-  x = cx * virtual_screen.normal_char_width;
-  y = (cy + virtual_screen.total_scroll) * virtual_screen.normal_char_height;
-
-  /* Render glyph to text layer.  */
-  grub_video_set_active_render_target (text_layer);
-  grub_video_fill_rect (bgcolor, x, y, width, height);
-  grub_font_draw_glyph (glyph, color, x, y + ascent);
-  grub_video_set_active_render_target (render_target);
-
-  /* Mark character to be drawn.  */
-  dirty_region_add (virtual_screen.offset_x + x, virtual_screen.offset_y + y,
-                    width, height);
-}
-
-static inline void
-write_char (void)
-{
-  paint_char (virtual_screen.cursor_x, virtual_screen.cursor_y);
-}
-
-static inline void
-draw_cursor (int show)
-{
-  unsigned int x;
-  unsigned int y;
-  unsigned int width;
-  unsigned int height;
-  grub_video_color_t color;
-  
-  write_char ();
-
-  if (!show)
-    return;
-
-  if (virtual_screen.cursor_y + virtual_screen.total_scroll
-      >= virtual_screen.rows)
-    return;
-
-  /* Determine cursor properties and position on text layer. */
-  x = virtual_screen.cursor_x * virtual_screen.normal_char_width;
-  width = virtual_screen.normal_char_width;
-  color = virtual_screen.fg_color;
-  y = ((virtual_screen.cursor_y + virtual_screen.total_scroll)
-       * virtual_screen.normal_char_height
-       + grub_font_get_ascent (virtual_screen.font));
-  height = 2;
-  
-  /* Render cursor to text layer.  */
-  grub_video_set_active_render_target (text_layer);
-  grub_video_fill_rect (color, x, y, width, height);
-  grub_video_set_active_render_target (render_target);
-  
-  /* Mark cursor to be redrawn.  */
-  dirty_region_add (virtual_screen.offset_x + x,
-                   virtual_screen.offset_y + y,
-                   width, height);
-}
-
-static void
-real_scroll (void)
-{
-  unsigned int i, j, was_scroll;
-  grub_video_color_t color;
-
-  if (!virtual_screen.total_scroll)
-    return;
-
-  /* If we have bitmap, re-draw screen, otherwise scroll physical screen too.  */
-  if (bitmap)
-    {
-      /* Scroll physical screen.  */
-      grub_video_set_active_render_target (text_layer);
-      color = virtual_screen.bg_color;
-      grub_video_scroll (color, 0, -virtual_screen.normal_char_height
-                        * virtual_screen.total_scroll);
-
-      /* Mark virtual screen to be redrawn.  */
-      dirty_region_add_virtualscreen ();
-    }
-  else
-    {
-      grub_video_rect_t saved_view;
-
-      /* Remove cursor.  */
-      draw_cursor (0);
-
-      grub_video_set_active_render_target (render_target);
-      /* Save viewport and set it to our window.  */
-      grub_video_get_viewport ((unsigned *) &saved_view.x, 
-                               (unsigned *) &saved_view.y, 
-                               (unsigned *) &saved_view.width, 
-                               (unsigned *) &saved_view.height);
-      grub_video_set_viewport (window.x, window.y, window.width, window.height);
-
-      i = window.double_repaint ? 2 : 1;
-
-      color = virtual_screen.bg_color;
-
-      while (i--)
-       {
-         /* Clear new border area.  */
-         grub_video_fill_rect (color,
-                               virtual_screen.offset_x,
-                               virtual_screen.offset_y,
-                               virtual_screen.width,
-                               virtual_screen.normal_char_height
-                               * virtual_screen.total_scroll);
-
-         grub_video_set_active_render_target (render_target);
-         dirty_region_redraw ();
-
-         /* Scroll physical screen.  */
-         grub_video_scroll (color, 0, -virtual_screen.normal_char_height
-                            * virtual_screen.total_scroll);
-
-         if (i)
-           grub_video_swap_buffers ();
-       }
-      dirty_region_reset ();
-
-      /* Scroll physical screen.  */
-      grub_video_set_active_render_target (text_layer);
-      color = virtual_screen.bg_color;
-      grub_video_scroll (color, 0, -virtual_screen.normal_char_height
-                        * virtual_screen.total_scroll);
-
-      /* Restore saved viewport.  */
-      grub_video_set_viewport (saved_view.x, saved_view.y,
-                               saved_view.width, saved_view.height);
-      grub_video_set_active_render_target (render_target);
-
-    }
-
-  was_scroll = virtual_screen.total_scroll;
-  virtual_screen.total_scroll = 0;
-
-  if (was_scroll > virtual_screen.rows)
-    was_scroll = virtual_screen.rows;
-
-  /* Draw shadow part.  */
-  for (i = virtual_screen.rows - was_scroll;
-       i < virtual_screen.rows; i++)
-    for (j = 0; j < virtual_screen.columns; j++)
-      paint_char (j, i);
-
-  /* Draw cursor if visible.  */
-  if (virtual_screen.cursor_state)
-    draw_cursor (1);
-
-  if (repaint_callback)
-    repaint_callback (window.x, window.y, window.width, window.height);
-}
-
-static void
-scroll_up (void)
-{
-  unsigned int i;
-
-  /* Scroll text buffer with one line to up.  */
-  grub_memmove (virtual_screen.text_buffer,
-                virtual_screen.text_buffer + virtual_screen.columns,
-                sizeof (*virtual_screen.text_buffer)
-                * virtual_screen.columns
-                * (virtual_screen.rows - 1));
-
-  /* Clear last line in text buffer.  */
-  for (i = virtual_screen.columns * (virtual_screen.rows - 1);
-       i < virtual_screen.columns * virtual_screen.rows;
-       i++)
-    clear_char (&(virtual_screen.text_buffer[i]));
-
-  virtual_screen.total_scroll++;
-}
-
-static void
-grub_gfxterm_putchar (grub_uint32_t c)
-{
-  if (c == '\a')
-    /* FIXME */
-    return;
-
-  /* Erase current cursor, if any.  */
-  if (virtual_screen.cursor_state)
-    draw_cursor (0);
-
-  if (c == '\b' || c == '\n' || c == '\r')
-    {
-      switch (c)
-        {
-        case '\b':
-          if (virtual_screen.cursor_x > 0)
-            virtual_screen.cursor_x--;
-          break;
-
-        case '\n':
-          if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
-            scroll_up ();
-          else
-            virtual_screen.cursor_y++;
-          break;
-
-        case '\r':
-          virtual_screen.cursor_x = 0;
-          break;
-        }
-    }
-  else
-    {
-      struct grub_font_glyph *glyph;
-      struct grub_colored_char *p;
-      unsigned char char_width;
-
-      /* Get properties of the character.  */
-      glyph = grub_font_get_glyph (virtual_screen.font, c);
-
-      /* Calculate actual character width for glyph. This is number of
-         times of normal_font_width.  */
-      char_width = calculate_character_width(glyph);
-
-      /* If we are about to exceed line length, wrap to next line.  */
-      if (virtual_screen.cursor_x + char_width > virtual_screen.columns)
-        grub_putchar ('\n');
-
-      /* Find position on virtual screen, and fill information.  */
-      p = (virtual_screen.text_buffer +
-           virtual_screen.cursor_x +
-           virtual_screen.cursor_y * virtual_screen.columns);
-      p->code = c;
-      p->fg_color = virtual_screen.fg_color;
-      p->bg_color = virtual_screen.bg_color;
-      p->width = char_width - 1;
-      p->index = 0;
-
-      /* If we have large glyph, add fixup info.  */
-      if (char_width > 1)
-        {
-          unsigned i;
-
-          for (i = 1; i < char_width; i++)
-            {
-              p[i].code = ' ';
-              p[i].width = char_width - 1;
-              p[i].index = i;
-            }
-        }
-
-      /* Draw glyph.  */
-      write_char ();
-
-      /* Make sure we scroll screen when needed and wrap line correctly.  */
-      virtual_screen.cursor_x += char_width;
-      if (virtual_screen.cursor_x >= virtual_screen.columns)
-        {
-          virtual_screen.cursor_x = 0;
-
-          if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
-            scroll_up ();
-          else
-            virtual_screen.cursor_y++;
-        }
-    }
-
-  /* Redraw cursor if it should be visible.  */
-  /* Note: This will redraw the character as well, which means that the
-     above call to write_char is redundant when the cursor is showing.  */
-  if (virtual_screen.cursor_state)
-    draw_cursor (1);
-}
-
-/* Use ASCII characters to determine normal character width.  */
-static unsigned int
-calculate_normal_character_width (grub_font_t font)
-{
-  struct grub_font_glyph *glyph;
-  unsigned int width = 0;
-  unsigned int i;
-
-  /* Get properties of every printable ASCII character.  */
-  for (i = 32; i < 127; i++)
-    {
-      glyph = grub_font_get_glyph (font, i);
-
-      /* Skip unknown characters.  Should never happen on normal conditions.  */
-      if (! glyph)
-       continue;
-
-      if (glyph->device_width > width)
-       width = glyph->device_width;
-    }
-
-  return width;
-}
-
-static unsigned char
-calculate_character_width (struct grub_font_glyph *glyph)
-{
-  if (! glyph || glyph->device_width == 0)
-    return 1;
-
-  return (glyph->device_width
-          + (virtual_screen.normal_char_width - 1))
-         / virtual_screen.normal_char_width;
-}
-
-static grub_ssize_t
-grub_gfxterm_getcharwidth (grub_uint32_t c)
-{
-  struct grub_font_glyph *glyph;
-  unsigned char char_width;
-
-  /* Get properties of the character.  */
-  glyph = grub_font_get_glyph (virtual_screen.font, c);
-
-  /* Calculate actual character width for glyph.  */
-  char_width = calculate_character_width (glyph);
-
-  return char_width;
-}
-
-static grub_uint16_t
-grub_virtual_screen_getwh (void)
-{
-  return (virtual_screen.columns << 8) | virtual_screen.rows;
-}
-
-static grub_uint16_t
-grub_virtual_screen_getxy (void)
-{
-  return ((virtual_screen.cursor_x << 8) | virtual_screen.cursor_y);
-}
-
-static void
-grub_gfxterm_gotoxy (grub_uint8_t x, grub_uint8_t y)
-{
-  if (x >= virtual_screen.columns)
-    x = virtual_screen.columns - 1;
-
-  if (y >= virtual_screen.rows)
-    y = virtual_screen.rows - 1;
-
-  /* Erase current cursor, if any.  */
-  if (virtual_screen.cursor_state)
-    draw_cursor (0);
-
-  virtual_screen.cursor_x = x;
-  virtual_screen.cursor_y = y;
-
-  /* Draw cursor if visible.  */
-  if (virtual_screen.cursor_state)
-    draw_cursor (1);
-}
-
-static void
-grub_virtual_screen_cls (void)
-{
-  grub_uint32_t i;
-
-  for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
-    clear_char (&(virtual_screen.text_buffer[i]));
-
-  virtual_screen.cursor_x = virtual_screen.cursor_y = 0;
-}
-
-static void
-grub_gfxterm_cls (void)
-{
-  grub_video_color_t color;
-
-  /* Clear virtual screen.  */
-  grub_virtual_screen_cls ();
-
-  /* Clear text layer.  */
-  grub_video_set_active_render_target (text_layer);
-  color = virtual_screen.bg_color;
-  grub_video_fill_rect (color, 0, 0,
-                        virtual_screen.width, virtual_screen.height);
-  grub_video_set_active_render_target (render_target);
-
-  /* Mark virtual screen to be redrawn.  */
-  dirty_region_add_virtualscreen ();
-
-  grub_gfxterm_refresh ();
-}
-
-static void
-grub_virtual_screen_setcolorstate (grub_term_color_state state)
-{
-  switch (state)
-    {
-    case GRUB_TERM_COLOR_STANDARD:
-      virtual_screen.term_color = virtual_screen.standard_color_setting;
-      break;
-
-    case GRUB_TERM_COLOR_NORMAL:
-      virtual_screen.term_color = virtual_screen.normal_color_setting;
-      break;
-
-    case GRUB_TERM_COLOR_HIGHLIGHT:
-      virtual_screen.term_color = virtual_screen.highlight_color_setting;
-      break;
-
-    default:
-      break;
-    }
-
-  /* Change color to virtual terminal.  */
-  set_term_color (virtual_screen.term_color);
-}
-
-static void
-grub_virtual_screen_setcolor (grub_uint8_t normal_color,
-                              grub_uint8_t highlight_color)
-{
-  virtual_screen.normal_color_setting = normal_color;
-  virtual_screen.highlight_color_setting = highlight_color;
-}
-
-static void
-grub_virtual_screen_getcolor (grub_uint8_t *normal_color,
-                              grub_uint8_t *highlight_color)
-{
-  *normal_color = virtual_screen.normal_color_setting;
-  *highlight_color = virtual_screen.highlight_color_setting;
-}
-
-static void
-grub_gfxterm_setcursor (int on)
-{
-  if (virtual_screen.cursor_state != on)
-    {
-      if (virtual_screen.cursor_state)
-       draw_cursor (0);
-      else
-       draw_cursor (1);
-
-      virtual_screen.cursor_state = on;
-    }
-}
-
-static void
-grub_gfxterm_refresh (void)
-{
-  real_scroll ();
-
-  /* Redraw only changed regions.  */
-  dirty_region_redraw ();
-
-  grub_video_swap_buffers ();
-
-  if (window.double_repaint)
-    dirty_region_redraw ();
-  dirty_region_reset ();
-}
-
-void 
-grub_gfxterm_set_repaint_callback (grub_gfxterm_repaint_callback_t func)
-{
-  repaint_callback = func;
-}
-
-/* Option array indices.  */
-#define BACKGROUND_CMD_ARGINDEX_MODE 0
-
-static const struct grub_arg_option background_image_cmd_options[] =
-  {
-    {"mode", 'm', 0, "Background image mode.", "stretch|normal",
-     ARG_TYPE_STRING},
-    {0, 0, 0, 0, 0, 0}
-  };
-
-static grub_err_t
-grub_gfxterm_background_image_cmd (grub_extcmd_t cmd __attribute__ ((unused)),
-                                   int argc,
-                                   char **args)
-{
-  struct grub_arg_list *state = cmd->state;
-
-  /* Check that we have video adapter active.  */
-  if (grub_video_get_info(NULL) != GRUB_ERR_NONE)
-    return grub_errno;
-
-  /* Destroy existing background bitmap if loaded.  */
-  if (bitmap)
-    {
-      grub_video_bitmap_destroy (bitmap);
-      bitmap = 0;
-
-      /* Mark whole screen as dirty.  */
-      dirty_region_add (0, 0, window.width, window.height);
-    }
-
-  /* If filename was provided, try to load that.  */
-  if (argc >= 1)
-    {
-    /* Try to load new one.  */
-    grub_video_bitmap_load (&bitmap, args[0]);
-    if (grub_errno != GRUB_ERR_NONE)
-      return grub_errno;
-
-    /* Determine if the bitmap should be scaled to fit the screen.  */
-    if (!state[BACKGROUND_CMD_ARGINDEX_MODE].set
-        || grub_strcmp (state[BACKGROUND_CMD_ARGINDEX_MODE].arg,
-                        "stretch") == 0)
-        {
-          if (window.width != grub_video_bitmap_get_width (bitmap)
-              || window.height != grub_video_bitmap_get_height (bitmap))
-            {
-              struct grub_video_bitmap *scaled_bitmap;
-              grub_video_bitmap_create_scaled (&scaled_bitmap,
-                                               window.width, 
-                                               window.height,
-                                               bitmap,
-                                               GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
-              if (grub_errno == GRUB_ERR_NONE)
-                {
-                  /* Replace the original bitmap with the scaled one.  */
-                  grub_video_bitmap_destroy (bitmap);
-                  bitmap = scaled_bitmap;
-                }
-            }
-        }
-
-    /* If bitmap was loaded correctly, display it.  */
-    if (bitmap)
-      {
-        /* Determine bitmap dimensions.  */
-        bitmap_width = grub_video_bitmap_get_width (bitmap);
-        bitmap_height = grub_video_bitmap_get_height (bitmap);
-
-        /* Mark whole screen as dirty.  */
-        dirty_region_add (0, 0, window.width, window.height);
-      }
-    }
-
-  /* All was ok.  */
-  grub_errno = GRUB_ERR_NONE;
-  return grub_errno;
-}
-
-static struct grub_term_output grub_video_term =
-  {
-    .name = "gfxterm",
-    .init = grub_gfxterm_term_init,
-    .fini = grub_gfxterm_term_fini,
-    .putchar = grub_gfxterm_putchar,
-    .getcharwidth = grub_gfxterm_getcharwidth,
-    .getwh = grub_virtual_screen_getwh,
-    .getxy = grub_virtual_screen_getxy,
-    .gotoxy = grub_gfxterm_gotoxy,
-    .cls = grub_gfxterm_cls,
-    .setcolorstate = grub_virtual_screen_setcolorstate,
-    .setcolor = grub_virtual_screen_setcolor,
-    .getcolor = grub_virtual_screen_getcolor,
-    .setcursor = grub_gfxterm_setcursor,
-    .refresh = grub_gfxterm_refresh,
-    .flags = 0,
-    .next = 0
-  };
-
-static grub_extcmd_t background_image_cmd_handle;
-
-GRUB_MOD_INIT(gfxterm)
-{
-  grub_term_register_output ("gfxterm", &grub_video_term);
-  background_image_cmd_handle =
-    grub_register_extcmd ("background_image",
-                          grub_gfxterm_background_image_cmd,
-                          GRUB_COMMAND_FLAG_BOTH,
-                          N_("[-m (stretch|normal)] FILE"),
-                          N_("Load background image for active terminal."),
-                          background_image_cmd_options);
-}
-
-GRUB_MOD_FINI(gfxterm)
-{
-  grub_unregister_extcmd (background_image_cmd_handle);
-  grub_term_unregister_output (&grub_video_term);
-}
diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c
deleted file mode 100644 (file)
index 43cfe2f..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/machine/memory.h>
-#include <grub/machine/console.h>
-#include <grub/term.h>
-#include <grub/types.h>
-
-static const struct grub_machine_bios_data_area *bios_data_area =
-  (struct grub_machine_bios_data_area *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR;
-
-#define KEYBOARD_LEFT_SHIFT    (1 << 0)
-#define KEYBOARD_RIGHT_SHIFT   (1 << 1)
-#define KEYBOARD_CTRL          (1 << 2)
-#define KEYBOARD_ALT           (1 << 3)
-
-static int
-grub_console_getkeystatus (void)
-{
-  grub_uint8_t status = bios_data_area->keyboard_flag_lower;
-  int mods = 0;
-
-  if (status & (KEYBOARD_LEFT_SHIFT | KEYBOARD_RIGHT_SHIFT))
-    mods |= GRUB_TERM_STATUS_SHIFT;
-  if (status & KEYBOARD_CTRL)
-    mods |= GRUB_TERM_STATUS_CTRL;
-  if (status & KEYBOARD_ALT)
-    mods |= GRUB_TERM_STATUS_ALT;
-
-  return mods;
-}
-
-static struct grub_term_input grub_console_term_input =
-  {
-    .name = "console",
-    .checkkey = grub_console_checkkey,
-    .getkey = grub_console_getkey,
-    .getkeystatus = grub_console_getkeystatus,
-  };
-
-static struct grub_term_output grub_console_term_output =
-  {
-    .name = "console",
-    .putchar = grub_console_putchar,
-    .getcharwidth = grub_console_getcharwidth,
-    .getwh = grub_console_getwh,
-    .getxy = grub_console_getxy,
-    .gotoxy = grub_console_gotoxy,
-    .cls = grub_console_cls,
-    .setcolorstate = grub_console_setcolorstate,
-    .setcolor = grub_console_setcolor,
-    .getcolor = grub_console_getcolor,
-    .setcursor = grub_console_setcursor
-  };
-
-void
-grub_console_init (void)
-{
-  grub_term_register_output ("console", &grub_console_term_output);
-  grub_term_register_input ("console", &grub_console_term_input);
-}
-
-void
-grub_console_fini (void)
-{
-  grub_term_unregister_input (&grub_console_term_input);
-  grub_term_unregister_output (&grub_console_term_output);
-}
diff --git a/term/i386/pc/vga.c b/term/i386/pc/vga.c
deleted file mode 100644 (file)
index 402b30f..0000000
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-// TODO: Deprecated and broken. Needs to be converted to Video Driver!
-
-#include <grub/machine/vga.h>
-#include <grub/machine/console.h>
-#include <grub/cpu/io.h>
-#include <grub/term.h>
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/font.h>
-
-#define DEBUG_VGA      0
-
-#define VGA_WIDTH      640
-#define VGA_HEIGHT     350
-#define CHAR_WIDTH     8
-#define CHAR_HEIGHT    16
-#define TEXT_WIDTH     (VGA_WIDTH / CHAR_WIDTH)
-#define TEXT_HEIGHT    (VGA_HEIGHT / CHAR_HEIGHT)
-#define VGA_MEM                ((grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR)
-#define PAGE_OFFSET(x) ((x) * (VGA_WIDTH * VGA_HEIGHT / 8))
-
-#define DEFAULT_FG_COLOR       0xa
-#define DEFAULT_BG_COLOR       0x0
-
-struct colored_char
-{
-  /* An Unicode codepoint.  */
-  grub_uint32_t code;
-
-  /* Color indexes.  */
-  unsigned char fg_color;
-  unsigned char bg_color;
-
-  /* The width of this character minus one.  */
-  unsigned char width;
-
-  /* The column index of this character.  */
-  unsigned char index;
-};
-
-static unsigned char text_mode;
-static unsigned xpos, ypos;
-static int cursor_state;
-static unsigned char fg_color, bg_color;
-static struct colored_char text_buf[TEXT_WIDTH * TEXT_HEIGHT];
-static unsigned char saved_map_mask;
-static int page = 0;
-static grub_font_t font = 0;
-
-#define SEQUENCER_ADDR_PORT    0x3C4
-#define SEQUENCER_DATA_PORT    0x3C5
-#define MAP_MASK_REGISTER      0x02
-
-#define CRTC_ADDR_PORT         0x3D4
-#define CRTC_DATA_PORT         0x3D5
-#define START_ADDR_HIGH_REGISTER 0x0C
-#define START_ADDR_LOW_REGISTER        0x0D
-
-#define GRAPHICS_ADDR_PORT     0x3CE
-#define GRAPHICS_DATA_PORT     0x3CF
-#define READ_MAP_REGISTER      0x04
-
-#define INPUT_STATUS1_REGISTER 0x3DA
-#define INPUT_STATUS1_VERTR_BIT 0x08
-
-static inline void
-wait_vretrace (void)
-{
-  /* Wait until there is a vertical retrace.  */
-  while (! (grub_inb (INPUT_STATUS1_REGISTER) & INPUT_STATUS1_VERTR_BIT));
-}
-
-/* Get Map Mask Register.  */
-static unsigned char
-get_map_mask (void)
-{
-  unsigned char old_addr;
-  unsigned char old_data;
-
-  old_addr = grub_inb (SEQUENCER_ADDR_PORT);
-  grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT);
-
-  old_data = grub_inb (SEQUENCER_DATA_PORT);
-
-  grub_outb (old_addr, SEQUENCER_ADDR_PORT);
-
-  return old_data;
-}
-
-/* Set Map Mask Register.  */
-static void
-set_map_mask (unsigned char mask)
-{
-  unsigned char old_addr;
-
-  old_addr = grub_inb (SEQUENCER_ADDR_PORT);
-  grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT);
-
-  grub_outb (mask, SEQUENCER_DATA_PORT);
-
-  grub_outb (old_addr, SEQUENCER_ADDR_PORT);
-}
-
-/* Set Read Map Register.  */
-static void
-set_read_map (unsigned char map)
-{
-  unsigned char old_addr;
-
-  old_addr = grub_inb (GRAPHICS_ADDR_PORT);
-
-  grub_outb (READ_MAP_REGISTER, GRAPHICS_ADDR_PORT);
-  grub_outb (map, GRAPHICS_DATA_PORT);
-
-  grub_outb (old_addr, GRAPHICS_ADDR_PORT);
-}
-
-/* Set start address.  */
-static void
-set_start_address (unsigned int start)
-{
-  unsigned char old_addr;
-
-  old_addr = grub_inb (CRTC_ADDR_PORT);
-
-  grub_outb (START_ADDR_LOW_REGISTER, CRTC_ADDR_PORT);
-  grub_outb (start & 0xFF, CRTC_DATA_PORT);
-
-  grub_outb (START_ADDR_HIGH_REGISTER, CRTC_ADDR_PORT);
-  grub_outb (start >> 8, CRTC_DATA_PORT);
-
-  grub_outb (old_addr, CRTC_ADDR_PORT);
-}
-
-static grub_err_t
-grub_vga_mod_init (void)
-{
-  text_mode = grub_vga_set_mode (0x10);
-  cursor_state = 1;
-  fg_color = DEFAULT_FG_COLOR;
-  bg_color = DEFAULT_BG_COLOR;
-  saved_map_mask = get_map_mask ();
-  set_map_mask (0x0f);
-  set_start_address (PAGE_OFFSET (page));
-  font = grub_font_get ("");  /* Choose any font, for now. */
-  if (!font)
-    return grub_error (GRUB_ERR_BAD_FONT, "no font loaded");
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_vga_mod_fini (void)
-{
-  set_map_mask (saved_map_mask);
-  grub_vga_set_mode (text_mode);
-  return GRUB_ERR_NONE;
-}
-
-static int
-check_vga_mem (void *p)
-{
-  return (p >= (void *) (VGA_MEM + PAGE_OFFSET (page))
-         && p <= (void *) (VGA_MEM + PAGE_OFFSET (page)
-                           + VGA_WIDTH * VGA_HEIGHT / 8));
-}
-
-static void
-write_char (void)
-{
-  struct colored_char *p = text_buf + xpos + ypos * TEXT_WIDTH;
-  struct grub_font_glyph *glyph;
-  unsigned char *mem_base;
-  unsigned plane;
-
-  mem_base = (VGA_MEM + xpos +
-             ypos * CHAR_HEIGHT * TEXT_WIDTH + PAGE_OFFSET (page)) - p->index;
-  p -= p->index;
-
-  /* Get glyph for character.  */
-  glyph = grub_font_get_glyph (font, p->code);
-
-  for (plane = 0x01; plane <= 0x08; plane <<= 1)
-    {
-      unsigned y;
-      unsigned offset;
-      unsigned char *mem;
-
-      set_map_mask (plane);
-
-      for (y = 0, offset = 0, mem = mem_base;
-          y < CHAR_HEIGHT;
-          y++, mem += TEXT_WIDTH)
-       {
-          /* TODO Re-implement glyph drawing for vga module.  */
-#if 0
-         unsigned i;
-
-          unsigned char_width = 1; /* TODO Figure out wide characters.  */
-         for (i = 0; i < char_width && offset < 32; i++)
-           {
-             unsigned char fg_mask, bg_mask;
-
-             fg_mask = (p->fg_color & plane) ? glyph->bitmap[offset] : 0;
-             bg_mask = (p->bg_color & plane) ? ~(glyph->bitmap[offset]) : 0;
-             offset++;
-
-             if (check_vga_mem (mem + i))
-               mem[i] = (fg_mask | bg_mask);
-           }
-#endif /* 0 */
-       }
-    }
-
-  set_map_mask (0x0f);
-}
-
-static void
-write_cursor (void)
-{
-  unsigned char *mem = (VGA_MEM + PAGE_OFFSET (page) + xpos
-                       + (ypos * CHAR_HEIGHT + CHAR_HEIGHT - 3) * TEXT_WIDTH);
-  if (check_vga_mem (mem))
-    *mem = 0xff;
-
-  mem += TEXT_WIDTH;
-  if (check_vga_mem (mem))
-    *mem = 0xff;
-}
-
-static void
-scroll_up (void)
-{
-  unsigned i;
-  unsigned plane;
-
-  /* Do all the work in the other page.  */
-  grub_memmove (text_buf, text_buf + TEXT_WIDTH,
-               sizeof (struct colored_char) * TEXT_WIDTH * (TEXT_HEIGHT - 1));
-
-  for (i = TEXT_WIDTH * (TEXT_HEIGHT - 1); i < TEXT_WIDTH * TEXT_HEIGHT; i++)
-    {
-      text_buf[i].code = ' ';
-      text_buf[i].fg_color = 0;
-      text_buf[i].bg_color = 0;
-      text_buf[i].width = 0;
-      text_buf[i].index = 0;
-    }
-
-  for (plane = 1; plane <= 4; plane++)
-    {
-      set_read_map (plane);
-      set_map_mask (1 << plane);
-      grub_memmove (VGA_MEM + PAGE_OFFSET (1 - page), VGA_MEM
-                   + PAGE_OFFSET (page) + VGA_WIDTH * CHAR_HEIGHT / 8,
-                   VGA_WIDTH * (VGA_HEIGHT - CHAR_HEIGHT) / 8);
-    }
-
-  set_map_mask (0x0f);
-  grub_memset (VGA_MEM + PAGE_OFFSET (1 - page)
-              + VGA_WIDTH * (VGA_HEIGHT - CHAR_HEIGHT) / 8, 0,
-              VGA_WIDTH * CHAR_HEIGHT / 8);
-
-  /* Activate the other page.  */
-  page = 1 - page;
-  wait_vretrace ();
-  set_start_address (PAGE_OFFSET (page));
-}
-
-static void
-grub_vga_putchar (grub_uint32_t c)
-{
-#if DEBUG_VGA
-  static int show = 1;
-#endif
-
-  if (c == '\a')
-    /* FIXME */
-    return;
-
-  if (c == '\b' || c == '\n' || c == '\r')
-    {
-      /* Erase current cursor, if any.  */
-      if (cursor_state)
-       write_char ();
-
-      switch (c)
-       {
-       case '\b':
-         if (xpos > 0)
-           xpos--;
-         break;
-
-       case '\n':
-         if (ypos >= TEXT_HEIGHT - 1)
-           scroll_up ();
-         else
-           ypos++;
-         break;
-
-       case '\r':
-         xpos = 0;
-         break;
-       }
-
-      if (cursor_state)
-       write_cursor ();
-    }
-  else
-    {
-      struct grub_font_glyph *glyph;
-      struct colored_char *p;
-      unsigned char_width = 1;
-
-      glyph = grub_font_get_glyph(font, c);
-
-      if (xpos + char_width > TEXT_WIDTH)
-       grub_putchar ('\n');
-
-      p = text_buf + xpos + ypos * TEXT_WIDTH;
-      p->code = c;
-      p->fg_color = fg_color;
-      p->bg_color = bg_color;
-      p->width = char_width - 1;
-      p->index = 0;
-
-      if (char_width > 1)
-       {
-         unsigned i;
-
-         for (i = 1; i < char_width; i++)
-           {
-             p[i].code = ' ';
-             p[i].width = char_width - 1;
-             p[i].index = i;
-           }
-       }
-
-      write_char ();
-
-      xpos += char_width;
-      if (xpos >= TEXT_WIDTH)
-       {
-         xpos = 0;
-
-         if (ypos >= TEXT_HEIGHT - 1)
-           scroll_up ();
-         else
-           ypos++;
-       }
-
-      if (cursor_state)
-       write_cursor ();
-    }
-
-#if DEBUG_VGA
-  if (show)
-    {
-      grub_uint16_t pos = grub_getxy ();
-
-      show = 0;
-      grub_gotoxy (0, 0);
-      grub_printf ("[%u:%u]", (unsigned) (pos >> 8), (unsigned) (pos & 0xff));
-      grub_gotoxy (pos >> 8, pos & 0xff);
-      show = 1;
-    }
-#endif
-}
-
-static grub_ssize_t
-grub_vga_getcharwidth (grub_uint32_t c)
-{
-#if 0
-  struct grub_font_glyph glyph;
-
-  glyph = grub_font_get_glyph (c);
-
-  return glyph.char_width;
-#else
-  (void) c;   /* Prevent warning.  */
-  return 1;   /* TODO Fix wide characters?  */
-#endif
-}
-
-static grub_uint16_t
-grub_vga_getwh (void)
-{
-  return (TEXT_WIDTH << 8) | TEXT_HEIGHT;
-}
-
-static grub_uint16_t
-grub_vga_getxy (void)
-{
-  return ((xpos << 8) | ypos);
-}
-
-static void
-grub_vga_gotoxy (grub_uint8_t x, grub_uint8_t y)
-{
-  if (x >= TEXT_WIDTH || y >= TEXT_HEIGHT)
-    {
-      grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)",
-                 (unsigned) x, (unsigned) y);
-      return;
-    }
-
-  if (cursor_state)
-    write_char ();
-
-  xpos = x;
-  ypos = y;
-
-  if (cursor_state)
-    write_cursor ();
-}
-
-static void
-grub_vga_cls (void)
-{
-  unsigned i;
-
-  wait_vretrace ();
-  for (i = 0; i < TEXT_WIDTH * TEXT_HEIGHT; i++)
-    {
-      text_buf[i].code = ' ';
-      text_buf[i].fg_color = 0;
-      text_buf[i].bg_color = 0;
-      text_buf[i].width = 0;
-      text_buf[i].index = 0;
-    }
-
-  grub_memset (VGA_MEM + PAGE_OFFSET (page), 0, VGA_WIDTH * VGA_HEIGHT / 8);
-
-  xpos = ypos = 0;
-}
-
-static void
-grub_vga_setcolorstate (grub_term_color_state state)
-{
-  switch (state)
-    {
-    case GRUB_TERM_COLOR_STANDARD:
-    case GRUB_TERM_COLOR_NORMAL:
-      fg_color = DEFAULT_FG_COLOR;
-      bg_color = DEFAULT_BG_COLOR;
-      break;
-    case GRUB_TERM_COLOR_HIGHLIGHT:
-      fg_color = DEFAULT_BG_COLOR;
-      bg_color = DEFAULT_FG_COLOR;
-      break;
-    default:
-      break;
-    }
-}
-
-static void
-grub_vga_setcursor (int on)
-{
-  if (cursor_state != on)
-    {
-      if (cursor_state)
-       write_char ();
-      else
-       write_cursor ();
-
-      cursor_state = on;
-    }
-}
-
-static struct grub_term_output grub_vga_term =
-  {
-    .name = "vga",
-    .init = grub_vga_mod_init,
-    .fini = grub_vga_mod_fini,
-    .putchar = grub_vga_putchar,
-    .getcharwidth = grub_vga_getcharwidth,
-    .getwh = grub_vga_getwh,
-    .getxy = grub_vga_getxy,
-    .gotoxy = grub_vga_gotoxy,
-    .cls = grub_vga_cls,
-    .setcolorstate = grub_vga_setcolorstate,
-    .setcursor = grub_vga_setcursor,
-    .flags = 0,
-  };
-
-GRUB_MOD_INIT(vga)
-{
-  grub_term_register_output ("vga", &grub_vga_term);
-}
-
-GRUB_MOD_FINI(vga)
-{
-  grub_term_unregister_output (&grub_vga_term);
-}
diff --git a/term/i386/pc/vga_text.c b/term/i386/pc/vga_text.c
deleted file mode 100644 (file)
index f954cab..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007, 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/dl.h>
-#include <grub/i386/vga_common.h>
-#include <grub/i386/io.h>
-#include <grub/types.h>
-
-#define COLS   80
-#define ROWS   25
-
-static int grub_curr_x, grub_curr_y;
-
-#define VGA_TEXT_SCREEN                0xb8000
-
-#define CRTC_ADDR_PORT         0x3D4
-#define CRTC_DATA_PORT         0x3D5
-
-#define CRTC_CURSOR            0x0a
-#define CRTC_CURSOR_ADDR_HIGH  0x0e
-#define CRTC_CURSOR_ADDR_LOW   0x0f
-
-#define CRTC_CURSOR_DISABLE    (1 << 5)
-
-static void
-screen_write_char (int x, int y, short c)
-{
-  ((short *) VGA_TEXT_SCREEN)[y * COLS + x] = c;
-}
-
-static short
-screen_read_char (int x, int y)
-{
-  return ((short *) VGA_TEXT_SCREEN)[y * COLS + x];
-}
-
-static void
-update_cursor (void)
-{
-  unsigned int pos = grub_curr_y * COLS + grub_curr_x;
-  grub_outb (CRTC_CURSOR_ADDR_HIGH, CRTC_ADDR_PORT);
-  grub_outb (pos >> 8, CRTC_DATA_PORT);
-  grub_outb (CRTC_CURSOR_ADDR_LOW, CRTC_ADDR_PORT);
-  grub_outb (pos & 0xFF, CRTC_DATA_PORT);
-}
-
-static void
-inc_y (void)
-{
-  grub_curr_x = 0;
-  if (grub_curr_y < ROWS - 1)
-    grub_curr_y++;
-  else
-    {
-      int x, y;
-      for (y = 0; y < ROWS; y++)
-        for (x = 0; x < COLS; x++)
-          screen_write_char (x, y, screen_read_char (x, y + 1));
-    }
-}
-
-static void
-inc_x (void)
-{
-  if (grub_curr_x >= COLS - 1)
-    inc_y ();
-  else
-    grub_curr_x++;
-}
-
-void
-grub_console_real_putchar (int c)
-{
-  switch (c)
-    {
-      case '\b':
-       if (grub_curr_x != 0)
-         screen_write_char (grub_curr_x--, grub_curr_y, ' ');
-       break;
-      case '\n':
-       inc_y ();
-       break;
-      case '\r':
-       grub_curr_x = 0;
-       break;
-      default:
-       screen_write_char (grub_curr_x,
-                          grub_curr_y, c | (grub_console_cur_color << 8));
-       inc_x ();
-    }
-
-  update_cursor ();
-}
-
-static grub_uint16_t
-grub_vga_text_getxy (void)
-{
-  return (grub_curr_x << 8) | grub_curr_y;
-}
-
-static void
-grub_vga_text_gotoxy (grub_uint8_t x, grub_uint8_t y)
-{
-  grub_curr_x = x;
-  grub_curr_y = y;
-  update_cursor ();
-}
-
-static void
-grub_vga_text_cls (void)
-{
-  int i;
-  for (i = 0; i < ROWS * COLS; i++)
-    ((short *) VGA_TEXT_SCREEN)[i] = ' ' | (grub_console_cur_color << 8);
-  grub_vga_text_gotoxy (0, 0);
-}
-
-static void
-grub_vga_text_setcursor (int on)
-{
-  grub_uint8_t old;
-  grub_outb (CRTC_CURSOR, CRTC_ADDR_PORT);
-  old = grub_inb (CRTC_DATA_PORT);
-  if (on)
-    grub_outb (old & ~CRTC_CURSOR_DISABLE, CRTC_DATA_PORT);
-  else
-    grub_outb (old | CRTC_CURSOR_DISABLE, CRTC_DATA_PORT);
-}
-
-static grub_err_t
-grub_vga_text_init_fini (void)
-{
-  grub_vga_text_cls ();
-  return 0;
-}
-
-static struct grub_term_output grub_vga_text_term =
-  {
-    .name = "vga_text",
-    .init = grub_vga_text_init_fini,
-    .fini = grub_vga_text_init_fini,
-    .putchar = grub_console_putchar,
-    .getcharwidth = grub_console_getcharwidth,
-    .getwh = grub_console_getwh,
-    .getxy = grub_vga_text_getxy,
-    .gotoxy = grub_vga_text_gotoxy,
-    .cls = grub_vga_text_cls,
-    .setcolorstate = grub_console_setcolorstate,
-    .setcolor = grub_console_setcolor,
-    .getcolor = grub_console_getcolor,
-    .setcursor = grub_vga_text_setcursor,
-  };
-
-GRUB_MOD_INIT(vga_text)
-{
-  grub_term_register_output ("vga_text", &grub_vga_text_term);
-}
-
-GRUB_MOD_FINI(vga_text)
-{
-  grub_term_unregister_output (&grub_vga_text_term);
-}
diff --git a/term/i386/vga_common.c b/term/i386/vga_common.c
deleted file mode 100644 (file)
index 131b43a..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2005,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/i386/vga_common.h>
-#include <grub/term.h>
-#include <grub/types.h>
-
-grub_uint8_t grub_console_cur_color = 0x7;
-static grub_uint8_t grub_console_standard_color = 0x7;
-static grub_uint8_t grub_console_normal_color = 0x7;
-static grub_uint8_t grub_console_highlight_color = 0x70;
-
-static grub_uint32_t
-map_char (grub_uint32_t c)
-{
-  if (c > 0x7f)
-    {
-      /* Map some unicode characters to the VGA font, if possible.  */
-      switch (c)
-       {
-       case 0x2190:    /* left arrow */
-         c = 0x1b;
-         break;
-       case 0x2191:    /* up arrow */
-         c = 0x18;
-         break;
-       case 0x2192:    /* right arrow */
-         c = 0x1a;
-         break;
-       case 0x2193:    /* down arrow */
-         c = 0x19;
-         break;
-       case 0x2501:    /* horizontal line */
-         c = 0xc4;
-         break;
-       case 0x2503:    /* vertical line */
-         c = 0xb3;
-         break;
-       case 0x250F:    /* upper-left corner */
-         c = 0xda;
-         break;
-       case 0x2513:    /* upper-right corner */
-         c = 0xbf;
-         break;
-       case 0x2517:    /* lower-left corner */
-         c = 0xc0;
-         break;
-       case 0x251B:    /* lower-right corner */
-         c = 0xd9;
-         break;
-
-       default:
-         c = '?';
-         break;
-       }
-    }
-
-  return c;
-}
-
-void
-grub_console_putchar (grub_uint32_t c)
-{
-  grub_console_real_putchar (map_char (c));
-}
-
-grub_ssize_t
-grub_console_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
-{
-  /* For now, every printable character has the width 1.  */
-  return 1;
-}
-
-grub_uint16_t
-grub_console_getwh (void)
-{
-  return (80 << 8) | 25;
-}
-
-void
-grub_console_setcolorstate (grub_term_color_state state)
-{
-  switch (state) {
-    case GRUB_TERM_COLOR_STANDARD:
-      grub_console_cur_color = grub_console_standard_color;
-      break;
-    case GRUB_TERM_COLOR_NORMAL:
-      grub_console_cur_color = grub_console_normal_color;
-      break;
-    case GRUB_TERM_COLOR_HIGHLIGHT:
-      grub_console_cur_color = grub_console_highlight_color;
-      break;
-    default:
-      break;
-  }
-}
-
-void
-grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
-{
-  grub_console_normal_color = normal_color;
-  grub_console_highlight_color = highlight_color;
-}
-
-void
-grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
-{
-  *normal_color = grub_console_normal_color;
-  *highlight_color = grub_console_highlight_color;
-}
diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c
deleted file mode 100644 (file)
index c0f895a..0000000
+++ /dev/null
@@ -1,515 +0,0 @@
-/*  ofconsole.c -- Open Firmware console for GRUB.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/term.h>
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/time.h>
-#include <grub/machine/console.h>
-#include <grub/ieee1275/ieee1275.h>
-
-static grub_ieee1275_ihandle_t stdout_ihandle;
-static grub_ieee1275_ihandle_t stdin_ihandle;
-
-static grub_uint8_t grub_ofconsole_width;
-static grub_uint8_t grub_ofconsole_height;
-
-static int grub_curr_x;
-static int grub_curr_y;
-
-static int grub_keybuf;
-static int grub_buflen;
-
-struct color
-{
-  int red;
-  int green;
-  int blue;
-};
-
-static struct color colors[] =
-  {
-    // {R, G, B}
-    {0x00, 0x00, 0x00},
-    {0x00, 0x00, 0xA8}, // 1 = blue
-    {0x00, 0xA8, 0x00}, // 2 = green
-    {0x00, 0xA8, 0xA8}, // 3 = cyan
-    {0xA8, 0x00, 0x00}, // 4 = red
-    {0xA8, 0x00, 0xA8}, // 5 = magenta
-    {0xFE, 0xFE, 0x54}, // 6 = yellow
-    {0xFE, 0xFE, 0xFE}  // 7 = white
-  };
-
-static grub_uint8_t grub_ofconsole_normal_color = 0x7;
-static grub_uint8_t grub_ofconsole_highlight_color = 0x70;
-
-/* Write control characters to the console.  */
-static void
-grub_ofconsole_writeesc (const char *str)
-{
-  if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI))
-    return;
-
-  while (*str)
-    {
-      char chr = *(str++);
-      grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
-    }
-
-}
-
-static void
-grub_ofconsole_putchar (grub_uint32_t c)
-{
-  char chr;
-
-  if (c > 0x7F)
-    {
-      /* Better than nothing.  */
-      switch (c)
-       {
-       case GRUB_TERM_DISP_LEFT:
-         c = '<';
-         break;
-         
-       case GRUB_TERM_DISP_UP:
-         c = '^';
-         break;
-
-       case GRUB_TERM_DISP_RIGHT:
-         c = '>';
-         break;
-
-       case GRUB_TERM_DISP_DOWN:
-         c = 'v';
-         break;
-
-       case GRUB_TERM_DISP_HLINE:
-         c = '-';
-         break;
-
-       case GRUB_TERM_DISP_VLINE:
-         c = '|';
-         break;
-
-       case GRUB_TERM_DISP_UL:
-       case GRUB_TERM_DISP_UR:
-       case GRUB_TERM_DISP_LL:
-       case GRUB_TERM_DISP_LR:
-         c = '+';
-         break;
-
-       default:
-         c = '?';
-         break;
-       }
-    }
-
-  chr = c;
-
-  if (c == '\n')
-    {
-      grub_curr_y++;
-      grub_curr_x = 0;
-    }
-  else if (c == '\r')
-    {
-      grub_curr_x = 0;
-    }
-  else
-    {
-      grub_curr_x++;
-      if (grub_curr_x >= grub_ofconsole_width)
-        {
-          grub_ofconsole_putchar ('\n');
-          grub_ofconsole_putchar ('\r');
-          grub_curr_x++;
-        }
-    }
-  grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
-}
-
-static grub_ssize_t
-grub_ofconsole_getcharwidth (grub_uint32_t c __attribute__((unused)))
-{
-  return 1;
-}
-
-static void
-grub_ofconsole_setcolorstate (grub_term_color_state state)
-{
-  char setcol[256];
-  int fg;
-  int bg;
-
-  switch (state)
-    {
-    case GRUB_TERM_COLOR_STANDARD:
-    case GRUB_TERM_COLOR_NORMAL:
-      fg = grub_ofconsole_normal_color & 0x0f;
-      bg = grub_ofconsole_normal_color >> 4;
-      break;
-    case GRUB_TERM_COLOR_HIGHLIGHT:
-      fg = grub_ofconsole_highlight_color & 0x0f;
-      bg = grub_ofconsole_highlight_color >> 4;
-      break;
-    default:
-      return;
-    }
-
-  grub_snprintf (setcol, sizeof (setcol), "\e[3%dm\e[4%dm", fg, bg);
-  grub_ofconsole_writeesc (setcol);
-}
-
-static void
-grub_ofconsole_setcolor (grub_uint8_t normal_color,
-                        grub_uint8_t highlight_color)
-{
-  /* Discard bright bit.  */
-  grub_ofconsole_normal_color = normal_color & 0x77;
-  grub_ofconsole_highlight_color = highlight_color & 0x77;
-}
-
-static void
-grub_ofconsole_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
-{
-  *normal_color = grub_ofconsole_normal_color;
-  *highlight_color = grub_ofconsole_highlight_color;
-}
-
-static int
-grub_ofconsole_readkey (int *key)
-{
-  char c;
-  grub_ssize_t actual = 0;
-
-  grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
-
-  if (actual > 0)
-    switch(c)
-      {
-      case 0x7f:
-        /* Backspace: Ctrl-h.  */
-        c = '\b'; 
-        break;
-      case '\e':
-       {
-         grub_uint64_t start;
-         grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
-
-         /* On 9600 we have to wait up to 12 milliseconds.  */
-         start = grub_get_time_ms ();
-         while (actual <= 0 && grub_get_time_ms () - start < 12)
-           grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
-
-         if (actual <= 0)
-           {
-             *key = '\e';
-             return 1;
-           }
-
-         if (c != '[')
-           return 0;
-         
-         grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
-
-         /* On 9600 we have to wait up to 12 milliseconds.  */
-         start = grub_get_time_ms ();
-         while (actual <= 0 && grub_get_time_ms () - start < 12)
-           grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
-         if (actual <= 0)
-           return 0;
-
-         switch (c)
-           {
-           case 'A':
-             /* Up: Ctrl-p.  */
-             c = GRUB_TERM_UP;
-             break;
-           case 'B':
-             /* Down: Ctrl-n.  */
-             c = GRUB_TERM_DOWN;
-             break;
-           case 'C':
-             /* Right: Ctrl-f.  */
-             c = GRUB_TERM_RIGHT;
-             break;
-           case 'D':
-             /* Left: Ctrl-b.  */
-             c = GRUB_TERM_LEFT;
-             break;
-           case '3':
-             {
-               grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
-               /* On 9600 we have to wait up to 12 milliseconds.  */
-               start = grub_get_time_ms ();
-               while (actual <= 0 && grub_get_time_ms () - start < 12)
-                 grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
-               
-               if (actual <= 0)
-                 return 0;
-           
-               /* Delete: Ctrl-d.  */
-               if (c == '~')
-                 c = GRUB_TERM_DC;
-               else
-                 return 0;
-               break;
-             }
-             break;
-           }
-       }
-      }
-
-  *key = c;
-  return actual > 0;
-}
-
-static int
-grub_ofconsole_checkkey (void)
-{
-  int key;
-  int read;
-
-  if (grub_buflen)
-    return 1;
-
-  read = grub_ofconsole_readkey (&key);
-  if (read)
-    {
-      grub_keybuf = key;
-      grub_buflen = 1;
-      return 1;
-    }
-
-  return -1;
-}
-
-static int
-grub_ofconsole_getkey (void)
-{
-  int key;
-
-  if (grub_buflen)
-    {
-      grub_buflen  =0;
-      return grub_keybuf;
-    }
-
-  while (! grub_ofconsole_readkey (&key));
-
-  return key;
-}
-
-static grub_uint16_t
-grub_ofconsole_getxy (void)
-{
-  return ((grub_curr_x - 1) << 8) | grub_curr_y;
-}
-
-static void
-grub_ofconsole_dimensions (void)
-{
-  grub_ieee1275_ihandle_t options;
-  grub_ssize_t lval;
-
-  if (! grub_ieee1275_finddevice ("/options", &options)
-      && options != (grub_ieee1275_ihandle_t) -1)
-    {
-      if (! grub_ieee1275_get_property_length (options, "screen-#columns",
-                                              &lval)
-         && lval >= 0 && lval < 1024)
-       {
-         char val[lval];
-
-         if (! grub_ieee1275_get_property (options, "screen-#columns",
-                                           val, lval, 0))
-           grub_ofconsole_width = (grub_uint8_t) grub_strtoul (val, 0, 10);
-       }
-      if (! grub_ieee1275_get_property_length (options, "screen-#rows", &lval)
-         && lval >= 0 && lval < 1024)
-       {
-         char val[lval];
-         if (! grub_ieee1275_get_property (options, "screen-#rows",
-                                           val, lval, 0))
-           grub_ofconsole_height = (grub_uint8_t) grub_strtoul (val, 0, 10);
-       }
-    }
-
-  /* Use a small console by default.  */
-  if (! grub_ofconsole_width)
-    grub_ofconsole_width = 80;
-  if (! grub_ofconsole_height)
-    grub_ofconsole_height = 24;
-}
-
-static grub_uint16_t
-grub_ofconsole_getwh (void)
-{
-  return (grub_ofconsole_width << 8) | grub_ofconsole_height;
-}
-
-static void
-grub_ofconsole_gotoxy (grub_uint8_t x, grub_uint8_t y)
-{
-  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI))
-    {
-      char s[256];
-      grub_curr_x = x;
-      grub_curr_y = y;
-
-      grub_snprintf (s, sizeof (s), "\e[%d;%dH", y + 1, x + 1);
-      grub_ofconsole_writeesc (s);
-    }
-  else
-    {
-      if ((y == grub_curr_y) && (x == grub_curr_x - 1))
-        {
-          char chr;
-
-          chr = '\b';
-          grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
-        }
-
-      grub_curr_x = x;
-      grub_curr_y = y;
-    }
-}
-
-static void
-grub_ofconsole_cls (void)
-{
-  /* Clear the screen.  Using serial console, screen(1) only recognizes the
-   * ANSI escape sequence.  Using video console, Apple Open Firmware (version
-   * 3.1.1) only recognizes the literal ^L.  So use both.  */
-  grub_ofconsole_writeesc ("\f\e[2J");
-  grub_ofconsole_gotoxy (0, 0);
-}
-
-static void
-grub_ofconsole_setcursor (int on)
-{
-  /* Understood by the Open Firmware flavour in OLPC.  */
-  if (on)
-    grub_ieee1275_interpret ("cursor-on", 0);
-  else
-    grub_ieee1275_interpret ("cursor-off", 0);
-}
-
-static void
-grub_ofconsole_refresh (void)
-{
-  /* Do nothing, the current console state is ok.  */
-}
-
-static grub_err_t
-grub_ofconsole_init_input (void)
-{
-  grub_ssize_t actual;
-
-  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdin", &stdin_ihandle,
-                                         sizeof stdin_ihandle, &actual)
-      || actual != sizeof stdin_ihandle)
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot find stdin");
-
-  return 0;
-}
-
-static grub_err_t
-grub_ofconsole_init_output (void)
-{
-  grub_ssize_t actual;
-
-  /* The latest PowerMacs don't actually initialize the screen for us, so we
-   * use this trick to re-open the output device (but we avoid doing this on
-   * platforms where it's known to be broken). */
-  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT))
-    grub_ieee1275_interpret ("output-device output", 0);
-
-  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdout", &stdout_ihandle,
-                                         sizeof stdout_ihandle, &actual)
-      || actual != sizeof stdout_ihandle)
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot find stdout");
-
-  /* Initialize colors.  */
-  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS))
-    {
-      unsigned col;
-      for (col = 0; col < ARRAY_SIZE (colors); col++)
-       grub_ieee1275_set_color (stdout_ihandle, col, colors[col].red,
-                                colors[col].green, colors[col].blue);
-
-    /* Set the right fg and bg colors.  */
-      grub_ofconsole_setcolorstate (GRUB_TERM_COLOR_NORMAL);
-    }
-
-  grub_ofconsole_dimensions ();
-
-  return 0;
-}
-
-static grub_err_t
-grub_ofconsole_fini (void)
-{
-  return 0;
-}
-
-
-\f
-static struct grub_term_input grub_ofconsole_term_input =
-  {
-    .name = "ofconsole",
-    .init = grub_ofconsole_init_input,
-    .fini = grub_ofconsole_fini,
-    .checkkey = grub_ofconsole_checkkey,
-    .getkey = grub_ofconsole_getkey,
-  };
-
-static struct grub_term_output grub_ofconsole_term_output =
-  {
-    .name = "ofconsole",
-    .init = grub_ofconsole_init_output,
-    .fini = grub_ofconsole_fini,
-    .putchar = grub_ofconsole_putchar,
-    .getcharwidth = grub_ofconsole_getcharwidth,
-    .getxy = grub_ofconsole_getxy,
-    .getwh = grub_ofconsole_getwh,
-    .gotoxy = grub_ofconsole_gotoxy,
-    .cls = grub_ofconsole_cls,
-    .setcolorstate = grub_ofconsole_setcolorstate,
-    .setcolor = grub_ofconsole_setcolor,
-    .getcolor = grub_ofconsole_getcolor,
-    .setcursor = grub_ofconsole_setcursor,
-    .refresh = grub_ofconsole_refresh
-  };
-
-void
-grub_console_init (void)
-{
-  grub_term_register_input ("ofconsole", &grub_ofconsole_term_input);
-  grub_term_register_output ("ofconsole", &grub_ofconsole_term_output);
-}
-
-void
-grub_console_fini (void)
-{
-  grub_term_unregister_input (&grub_ofconsole_term_input);
-  grub_term_unregister_output (&grub_ofconsole_term_output);
-}
diff --git a/term/serial.c b/term/serial.c
deleted file mode 100644 (file)
index 2347bb3..0000000
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/machine/memory.h>
-#include <grub/serial.h>
-#include <grub/term.h>
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/terminfo.h>
-#include <grub/cpu/io.h>
-#include <grub/extcmd.h>
-#include <grub/i18n.h>
-
-#define TEXT_WIDTH     80
-#define TEXT_HEIGHT    24
-
-static unsigned int xpos, ypos;
-static unsigned int keep_track = 1;
-static unsigned int registered = 0;
-
-/* An input buffer.  */
-static char input_buf[8];
-static unsigned int npending = 0;
-
-static struct grub_term_output grub_serial_term_output;
-
-/* Argument options.  */
-static const struct grub_arg_option options[] =
-{
-  {"unit",   'u', 0, N_("Set the serial unit."),             0, ARG_TYPE_INT},
-  {"port",   'p', 0, N_("Set the serial port address."),     0, ARG_TYPE_STRING},
-  {"speed",  's', 0, N_("Set the serial port speed."),       0, ARG_TYPE_INT},
-  {"word",   'w', 0, N_("Set the serial port word length."), 0, ARG_TYPE_INT},
-  {"parity", 'r', 0, N_("Set the serial port parity."),      0, ARG_TYPE_STRING},
-  {"stop",   't', 0, N_("Set the serial port stop bits."),   0, ARG_TYPE_INT},
-  {0, 0, 0, 0, 0, 0}
-};
-
-/* Serial port settings.  */
-struct serial_port
-{
-  grub_port_t port;
-  unsigned short divisor;
-  unsigned short word_len;
-  unsigned int   parity;
-  unsigned short stop_bits;
-};
-
-/* Serial port settings.  */
-static struct serial_port serial_settings;
-
-#ifdef GRUB_MACHINE_PCBIOS
-static const unsigned short *serial_hw_io_addr = (const unsigned short *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR;
-#define GRUB_SERIAL_PORT_NUM 4
-#else
-#include <grub/machine/serial.h>
-static const grub_port_t serial_hw_io_addr[] = GRUB_MACHINE_SERIAL_PORTS;
-#define GRUB_SERIAL_PORT_NUM (ARRAY_SIZE(serial_hw_io_addr))
-#endif
-
-/* Return the port number for the UNITth serial device.  */
-static inline grub_port_t
-serial_hw_get_port (const unsigned int unit)
-{
-  if (unit < GRUB_SERIAL_PORT_NUM)
-    return serial_hw_io_addr[unit];
-  else
-    return 0;
-}
-
-/* Fetch a key.  */
-static int
-serial_hw_fetch (void)
-{
-  if (grub_inb (serial_settings.port + UART_LSR) & UART_DATA_READY)
-    return grub_inb (serial_settings.port + UART_RX);
-
-  return -1;
-}
-
-/* Put a character.  */
-static void
-serial_hw_put (const int c)
-{
-  unsigned int timeout = 100000;
-
-  /* Wait until the transmitter holding register is empty.  */
-  while ((grub_inb (serial_settings.port + UART_LSR) & UART_EMPTY_TRANSMITTER) == 0)
-    {
-      if (--timeout == 0)
-        /* There is something wrong. But what can I do?  */
-        return;
-    }
-
-  grub_outb (c, serial_settings.port + UART_TX);
-}
-
-static void
-serial_translate_key_sequence (void)
-{
-  unsigned int i;
-  static struct
-  {
-    char key;
-    char ascii;
-  }
-  three_code_table[] =
-    {
-      {'A', 16},
-      {'B', 14},
-      {'C', 6},
-      {'D', 2},
-      {'F', 5},
-      {'H', 1},
-      {'4', 4}
-    };
-
-  static struct
-  {
-      short key;
-      char ascii;
-  }
-  four_code_table[] =
-    {
-      {('1' | ('~' << 8)), 1},
-      {('3' | ('~' << 8)), 4},
-      {('5' | ('~' << 8)), 7},
-      {('6' | ('~' << 8)), 3}
-    };
-
-  if (npending < 3)
-    return;
-
-  /* The buffer must start with "ESC [".  */
-  if (input_buf[0] != '\e' || input_buf[1] != '[')
-    return;
-
-  for (i = 0; i < ARRAY_SIZE (three_code_table); i++)
-    if (three_code_table[i].key == input_buf[2])
-      {
-       input_buf[0] = three_code_table[i].ascii;
-       npending -= 2;
-       grub_memmove (input_buf + 1, input_buf + 3, npending - 1);
-       return;
-      }
-
-  if (npending >= 4)
-    {
-      short key = input_buf[3] | (input_buf[4] << 8);
-
-      for (i = 0; i < ARRAY_SIZE (four_code_table); i++)
-       if (four_code_table[i].key == key)
-         {
-           input_buf[0] = four_code_table[i].ascii;
-           npending -= 3;
-           grub_memmove (input_buf + 1, input_buf + 4, npending - 1);
-           return;
-         }
-    }
-}
-
-static int
-fill_input_buf (const int nowait)
-{
-  int i;
-
-  for (i = 0; i < 10000 && npending < sizeof (input_buf); i++)
-    {
-      int c;
-
-      c = serial_hw_fetch ();
-      if (c >= 0)
-       {
-         input_buf[npending++] = c;
-
-         /* Reset the counter to zero, to wait for the same interval.  */
-         i = 0;
-       }
-
-      if (nowait)
-       break;
-    }
-
-  /* Translate some key sequences.  */
-  serial_translate_key_sequence ();
-
-  return npending;
-}
-
-/* Convert speed to divisor.  */
-static unsigned short
-serial_get_divisor (unsigned int speed)
-{
-  unsigned int i;
-
-  /* The structure for speed vs. divisor.  */
-  struct divisor
-  {
-    unsigned int speed;
-    unsigned short div;
-  };
-
-  /* The table which lists common configurations.  */
-  /* 1843200 / (speed * 16)  */
-  static struct divisor divisor_tab[] =
-    {
-      { 2400,   0x0030 },
-      { 4800,   0x0018 },
-      { 9600,   0x000C },
-      { 19200,  0x0006 },
-      { 38400,  0x0003 },
-      { 57600,  0x0002 },
-      { 115200, 0x0001 }
-    };
-
-  /* Set the baud rate.  */
-  for (i = 0; i < sizeof (divisor_tab) / sizeof (divisor_tab[0]); i++)
-    if (divisor_tab[i].speed == speed)
-  /* UART in Yeeloong runs twice the usual rate.  */
-#ifdef GRUB_MACHINE_MIPS_YEELOONG
-      return 2 * divisor_tab[i].div;
-#else
-      return divisor_tab[i].div;
-#endif
-  return 0;
-}
-
-/* The serial version of checkkey.  */
-static int
-grub_serial_checkkey (void)
-{
-  if (fill_input_buf (1))
-    return input_buf[0];
-  else
-    return -1;
-}
-
-/* The serial version of getkey.  */
-static int
-grub_serial_getkey (void)
-{
-  int c;
-
-  while (! fill_input_buf (0))
-    ;
-
-  c = input_buf[0];
-  if (c == 0x7f)
-    c = GRUB_TERM_BACKSPACE;
-
-  grub_memmove (input_buf, input_buf + 1, --npending);
-
-  return c;
-}
-
-/* Initialize a serial device. PORT is the port number for a serial device.
-   SPEED is a DTE-DTE speed which must be one of these: 2400, 4800, 9600,
-   19200, 38400, 57600 and 115200. WORD_LEN is the word length to be used
-   for the device. Likewise, PARITY is the type of the parity and
-   STOP_BIT_LEN is the length of the stop bit. The possible values for
-   WORD_LEN, PARITY and STOP_BIT_LEN are defined in the header file as
-   macros.  */
-static grub_err_t
-serial_hw_init (void)
-{
-  unsigned char status = 0;
-
-  /* Turn off the interrupt.  */
-  grub_outb (0, serial_settings.port + UART_IER);
-
-  /* Set DLAB.  */
-  grub_outb (UART_DLAB, serial_settings.port + UART_LCR);
-
-  /* Set the baud rate.  */
-  grub_outb (serial_settings.divisor & 0xFF, serial_settings.port + UART_DLL);
-  grub_outb (serial_settings.divisor >> 8, serial_settings.port + UART_DLH);
-
-  /* Set the line status.  */
-  status |= (serial_settings.parity
-            | serial_settings.word_len
-            | serial_settings.stop_bits);
-  grub_outb (status, serial_settings.port + UART_LCR);
-
-  /* In Yeeloong serial port has only 3 wires.  */
-#ifndef GRUB_MACHINE_MIPS_YEELOONG
-  /* Enable the FIFO.  */
-  grub_outb (UART_ENABLE_FIFO, serial_settings.port + UART_FCR);
-
-  /* Turn on DTR, RTS, and OUT2.  */
-  grub_outb (UART_ENABLE_MODEM, serial_settings.port + UART_MCR);
-#endif
-
-  /* Drain the input buffer.  */
-  while (grub_serial_checkkey () != -1)
-    (void) grub_serial_getkey ();
-
-  /*  FIXME: should check if the serial terminal was found.  */
-
-  return GRUB_ERR_NONE;
-}
-
-/* The serial version of putchar.  */
-static void
-grub_serial_putchar (grub_uint32_t c)
-{
-  /* Keep track of the cursor.  */
-  if (keep_track)
-    {
-      /* The serial terminal does not have VGA fonts.  */
-      if (c > 0x7F)
-       {
-         /* Better than nothing.  */
-         switch (c)
-           {
-           case GRUB_TERM_DISP_LEFT:
-             c = '<';
-             break;
-
-           case GRUB_TERM_DISP_UP:
-             c = '^';
-             break;
-
-           case GRUB_TERM_DISP_RIGHT:
-             c = '>';
-             break;
-
-           case GRUB_TERM_DISP_DOWN:
-             c = 'v';
-             break;
-
-           case GRUB_TERM_DISP_HLINE:
-             c = '-';
-             break;
-
-           case GRUB_TERM_DISP_VLINE:
-             c = '|';
-             break;
-
-           case GRUB_TERM_DISP_UL:
-           case GRUB_TERM_DISP_UR:
-           case GRUB_TERM_DISP_LL:
-           case GRUB_TERM_DISP_LR:
-             c = '+';
-             break;
-
-           default:
-             c = '?';
-             break;
-           }
-       }
-
-      switch (c)
-       {
-       case '\a':
-         break;
-
-       case '\b':
-       case 127:
-         if (xpos > 0)
-           xpos--;
-         break;
-
-       case '\n':
-         if (ypos < TEXT_HEIGHT - 1)
-           ypos++;
-         break;
-
-       case '\r':
-         xpos = 0;
-         break;
-
-       default:
-         if (xpos >= TEXT_WIDTH)
-           {
-             grub_putchar ('\r');
-             grub_putchar ('\n');
-           }
-         xpos++;
-         break;
-       }
-    }
-
-  serial_hw_put (c);
-}
-
-static grub_ssize_t
-grub_serial_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
-{
-  return 1;
-}
-
-static grub_uint16_t
-grub_serial_getwh (void)
-{
-  return (TEXT_WIDTH << 8) | TEXT_HEIGHT;
-}
-
-static grub_uint16_t
-grub_serial_getxy (void)
-{
-  return ((xpos << 8) | ypos);
-}
-
-static void
-grub_serial_gotoxy (grub_uint8_t x, grub_uint8_t y)
-{
-  if (x > TEXT_WIDTH || y > TEXT_HEIGHT)
-    {
-      grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)", x, y);
-    }
-  else
-    {
-      keep_track = 0;
-      grub_terminfo_gotoxy (x, y, &grub_serial_term_output);
-      keep_track = 1;
-
-      xpos = x;
-      ypos = y;
-    }
-}
-
-static void
-grub_serial_cls (void)
-{
-  keep_track = 0;
-  grub_terminfo_cls (&grub_serial_term_output);
-  keep_track = 1;
-
-  xpos = ypos = 0;
-}
-
-static void
-grub_serial_setcolorstate (const grub_term_color_state state)
-{
-  keep_track = 0;
-  switch (state)
-    {
-    case GRUB_TERM_COLOR_STANDARD:
-    case GRUB_TERM_COLOR_NORMAL:
-      grub_terminfo_reverse_video_off (&grub_serial_term_output);
-      break;
-    case GRUB_TERM_COLOR_HIGHLIGHT:
-      grub_terminfo_reverse_video_on (&grub_serial_term_output);
-      break;
-    default:
-      break;
-    }
-  keep_track = 1;
-}
-
-static void
-grub_serial_setcursor (const int on)
-{
-  if (on)
-    grub_terminfo_cursor_on (&grub_serial_term_output);
-  else
-    grub_terminfo_cursor_off (&grub_serial_term_output);
-}
-
-static struct grub_term_input grub_serial_term_input =
-{
-  .name = "serial",
-  .checkkey = grub_serial_checkkey,
-  .getkey = grub_serial_getkey,
-};
-
-static struct grub_term_output grub_serial_term_output =
-{
-  .name = "serial",
-  .putchar = grub_serial_putchar,
-  .getcharwidth = grub_serial_getcharwidth,
-  .getwh = grub_serial_getwh,
-  .getxy = grub_serial_getxy,
-  .gotoxy = grub_serial_gotoxy,
-  .cls = grub_serial_cls,
-  .setcolorstate = grub_serial_setcolorstate,
-  .setcursor = grub_serial_setcursor,
-  .flags = 0,
-};
-
-\f
-
-static grub_err_t
-grub_cmd_serial (grub_extcmd_t cmd,
-                 int argc __attribute__ ((unused)),
-                char **args __attribute__ ((unused)))
-{
-  struct grub_arg_list *state = cmd->state;
-  struct serial_port backup_settings = serial_settings;
-  grub_err_t hwiniterr;
-
-  if (state[0].set)
-    {
-      unsigned int unit;
-
-      unit = grub_strtoul (state[0].arg, 0, 0);
-      serial_settings.port = serial_hw_get_port (unit);
-      if (!serial_settings.port)
-       return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad unit number");
-    }
-
-  if (state[1].set)
-    serial_settings.port = (grub_port_t) grub_strtoul (state[1].arg, 0, 0);
-
-  if (state[2].set)
-    {
-      unsigned long speed;
-
-      speed = grub_strtoul (state[2].arg, 0, 0);
-      serial_settings.divisor = serial_get_divisor ((unsigned int) speed);
-      if (serial_settings.divisor == 0)
-       {
-         serial_settings = backup_settings;
-         return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad speed");
-       }
-    }
-
-  if (state[3].set)
-    {
-      if (! grub_strcmp (state[3].arg, "5"))
-       serial_settings.word_len = UART_5BITS_WORD;
-      else if (! grub_strcmp (state[3].arg, "6"))
-       serial_settings.word_len = UART_6BITS_WORD;
-      else if (! grub_strcmp (state[3].arg, "7"))
-       serial_settings.word_len = UART_7BITS_WORD;
-      else if (! grub_strcmp (state[3].arg, "8"))
-       serial_settings.word_len = UART_8BITS_WORD;
-      else
-       {
-         serial_settings = backup_settings;
-         return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad word length");
-       }
-    }
-
-  if (state[4].set)
-    {
-      if (! grub_strcmp (state[4].arg, "no"))
-       serial_settings.parity = UART_NO_PARITY;
-      else if (! grub_strcmp (state[4].arg, "odd"))
-       serial_settings.parity = UART_ODD_PARITY;
-      else if (! grub_strcmp (state[4].arg, "even"))
-       serial_settings.parity = UART_EVEN_PARITY;
-      else
-       {
-         serial_settings = backup_settings;
-         return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad parity");
-       }
-    }
-
-  if (state[5].set)
-    {
-      if (! grub_strcmp (state[5].arg, "1"))
-       serial_settings.stop_bits = UART_1_STOP_BIT;
-      else if (! grub_strcmp (state[5].arg, "2"))
-       serial_settings.stop_bits = UART_2_STOP_BITS;
-      else
-       {
-         serial_settings = backup_settings;
-         return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad number of stop bits");
-       }
-    }
-
-  /* Initialize with new settings.  */
-  hwiniterr = serial_hw_init ();
-
-  if (hwiniterr == GRUB_ERR_NONE)
-    {
-      /* Register terminal if not yet registered.  */
-      if (registered == 0)
-       {
-         grub_term_register_input ("serial", &grub_serial_term_input);
-         grub_term_register_output ("serial", &grub_serial_term_output);
-         registered = 1;
-       }
-    }
-  else
-    {
-      /* Initialization with new settings failed.  */
-      if (registered == 1)
-       {
-         /* If the terminal is registered, attempt to restore previous
-            settings.  */
-         serial_settings = backup_settings;
-         if (serial_hw_init () != GRUB_ERR_NONE)
-           {
-             /* If unable to restore settings, unregister terminal.  */
-             grub_term_unregister_input (&grub_serial_term_input);
-             grub_term_unregister_output (&grub_serial_term_output);
-             registered = 0;
-           }
-       }
-    }
-
-  return hwiniterr;
-}
-
-static grub_extcmd_t cmd;
-
-GRUB_MOD_INIT(serial)
-{
-  cmd = grub_register_extcmd ("serial", grub_cmd_serial,
-                             GRUB_COMMAND_FLAG_BOTH,
-                             N_("[OPTIONS...]"),
-                             N_("Configure serial port."), options);
-
-  /* Set default settings.  */
-  serial_settings.port      = serial_hw_get_port (0);
-#ifdef GRUB_MACHINE_MIPS_YEELOONG
-  serial_settings.divisor   = serial_get_divisor (115200);
-#else
-  serial_settings.divisor   = serial_get_divisor (9600);
-#endif
-  serial_settings.word_len  = UART_8BITS_WORD;
-  serial_settings.parity    = UART_NO_PARITY;
-  serial_settings.stop_bits = UART_1_STOP_BIT;
-}
-
-GRUB_MOD_FINI(serial)
-{
-  grub_unregister_extcmd (cmd);
-  if (registered == 1)         /* Unregister terminal only if registered. */
-    {
-      grub_term_unregister_input (&grub_serial_term_input);
-      grub_term_unregister_output (&grub_serial_term_output);
-    }
-}
diff --git a/term/terminfo.c b/term/terminfo.c
deleted file mode 100644 (file)
index 7402d23..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/* terminfo.c - simple terminfo module */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * This file contains various functions dealing with different
- * terminal capabilities. For example, vt52 and vt100.
- */
-
-#include <grub/types.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/dl.h>
-#include <grub/term.h>
-#include <grub/terminfo.h>
-#include <grub/tparm.h>
-#include <grub/command.h>
-#include <grub/i18n.h>
-
-struct terminfo
-{
-  char *name;
-
-  char *gotoxy;
-  char *cls;
-  char *reverse_video_on;
-  char *reverse_video_off;
-  char *cursor_on;
-  char *cursor_off;
-};
-
-static struct terminfo term;
-
-/* Get current terminfo name.  */
-char *
-grub_terminfo_get_current (void)
-{
-  return term.name;
-}
-
-/* Free *PTR and set *PTR to NULL, to prevent double-free.  */
-static void
-grub_terminfo_free (char **ptr)
-{
-  grub_free (*ptr);
-  *ptr = 0;
-}
-
-/* Set current terminfo type.  */
-grub_err_t
-grub_terminfo_set_current (const char *str)
-{
-  /* TODO
-   * Lookup user specified terminfo type. If found, set term variables
-   * as appropriate. Otherwise return an error.
-   *
-   * How should this be done?
-   *  a. A static table included in this module.
-   *     - I do not like this idea.
-   *  b. A table stored in the configuration directory.
-   *     - Users must convert their terminfo settings if we have not already.
-   *  c. Look for terminfo files in the configuration directory.
-   *     - /usr/share/terminfo is 6.3M on my system.
-   *     - /usr/share/terminfo is not on most users boot partition.
-   *     + Copying the terminfo files you want to use to the grub
-   *       configuration directory is easier then (b).
-   *  d. Your idea here.
-   */
-
-  /* Free previously allocated memory.  */
-  grub_terminfo_free (&term.name);
-  grub_terminfo_free (&term.gotoxy);
-  grub_terminfo_free (&term.cls);
-  grub_terminfo_free (&term.reverse_video_on);
-  grub_terminfo_free (&term.reverse_video_off);
-  grub_terminfo_free (&term.cursor_on);
-  grub_terminfo_free (&term.cursor_off);
-
-  if (grub_strcmp ("vt100", str) == 0)
-    {
-      term.name              = grub_strdup ("vt100");
-      term.gotoxy            = grub_strdup ("\e[%i%p1%d;%p2%dH");
-      term.cls               = grub_strdup ("\e[H\e[J");
-      term.reverse_video_on  = grub_strdup ("\e[7m");
-      term.reverse_video_off = grub_strdup ("\e[m");
-      term.cursor_on         = grub_strdup ("\e[?25h");
-      term.cursor_off        = grub_strdup ("\e[?25l");
-      return grub_errno;
-    }
-
-  return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminfo type");
-}
-
-/* Wrapper for grub_putchar to write strings.  */
-static void
-putstr (const char *str, grub_term_output_t oterm)
-{
-  while (*str)
-    grub_putcode (*str++, oterm);
-}
-
-/* Move the cursor to the given position starting with "0".  */
-void
-grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y, grub_term_output_t oterm)
-{
-  putstr (grub_terminfo_tparm (term.gotoxy, y, x), oterm);
-}
-
-/* Clear the screen.  */
-void
-grub_terminfo_cls (grub_term_output_t oterm)
-{
-  putstr (grub_terminfo_tparm (term.cls), oterm);
-}
-
-/* Set reverse video mode on.  */
-void
-grub_terminfo_reverse_video_on (grub_term_output_t oterm)
-{
-  putstr (grub_terminfo_tparm (term.reverse_video_on), oterm);
-}
-
-/* Set reverse video mode off.  */
-void
-grub_terminfo_reverse_video_off (grub_term_output_t oterm)
-{
-  putstr (grub_terminfo_tparm (term.reverse_video_off), oterm);
-}
-
-/* Show cursor.  */
-void
-grub_terminfo_cursor_on (grub_term_output_t oterm)
-{
-  putstr (grub_terminfo_tparm (term.cursor_on), oterm);
-}
-
-/* Hide cursor.  */
-void
-grub_terminfo_cursor_off (grub_term_output_t oterm)
-{
-  putstr (grub_terminfo_tparm (term.cursor_off), oterm);
-}
-
-/* GRUB Command.  */
-
-static grub_err_t
-grub_cmd_terminfo (grub_command_t cmd __attribute__ ((unused)),
-                  int argc, char **args)
-{
-  if (argc == 0)
-  {
-    grub_printf ("Current terminfo type: %s\n", grub_terminfo_get_current());
-    return GRUB_ERR_NONE;
-  }
-  else if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters");
-  else
-    return grub_terminfo_set_current (args[0]);
-}
-
-static grub_command_t cmd;
-
-GRUB_MOD_INIT(terminfo)
-{
-  cmd = grub_register_command ("terminfo", grub_cmd_terminfo,
-                              N_("[TERM]"), N_("Set terminfo type."));
-  grub_terminfo_set_current ("vt100");
-}
-
-GRUB_MOD_FINI(terminfo)
-{
-  grub_unregister_command (cmd);
-}
diff --git a/term/tparm.c b/term/tparm.c
deleted file mode 100644 (file)
index adf0b3a..0000000
+++ /dev/null
@@ -1,758 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1998-2003,2004,2005 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**********************************************************************
- * This code is a modification of lib_tparm.c found in ncurses-5.2. The
- * modification are for use in grub by replacing all libc function through
- * special grub functions. This also meant to delete all dynamic memory
- * allocation and replace it by a number of fixed buffers.
- *
- * Modifications by Tilmann Bubeck <t.bubeck@reinform.de> 2002
- *
- * Resync with ncurses-5.4 by Omniflux <omniflux+devel@omniflux.com> 2005
- **********************************************************************/
-
-/****************************************************************************
- *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
- *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
- *     and: Thomas E. Dickey, 1996 on                                       *
- ****************************************************************************/
-
-/*
- *     tparm.c
- *
- */
-
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/types.h>
-#include <grub/tparm.h>
-
-/*
- * Common/troublesome character definitions
- */
-typedef char grub_bool_t;
-#ifndef FALSE
-# define FALSE (0)
-#endif
-#ifndef TRUE
-# define TRUE (!FALSE)
-#endif
-
-#define NUM_PARM 9
-#define NUM_VARS 26
-#define STACKSIZE 20
-#define MAX_FORMAT_LEN 256
-
-#define max(a,b) ((a) > (b) ? (a) : (b))
-#define isdigit(c) ((c) >= '0' && (c) <= '9')
-#define isUPPER(c) ((c) >= 'A' && (c) <= 'Z')
-#define isLOWER(c) ((c) >= 'a' && (c) <= 'z')
-
-#define UChar(c) ((unsigned char)(c))
-
-//MODULE_ID("$Id$")
-
-/*
- *     char *
- *     tparm(string, ...)
- *
- *     Substitute the given parameters into the given string by the following
- *     rules (taken from terminfo(5)):
- *
- *          Cursor addressing and other strings  requiring  parame-
- *     ters in the terminal are described by a parameterized string
- *     capability, with like escapes %x in  it.   For  example,  to
- *     address  the  cursor, the cup capability is given, using two
- *     parameters: the row and column to  address  to.   (Rows  and
- *     columns  are  numbered  from  zero and refer to the physical
- *     screen visible to the user, not to any  unseen  memory.)  If
- *     the terminal has memory relative cursor addressing, that can
- *     be indicated by
- *
- *          The parameter mechanism uses  a  stack  and  special  %
- *     codes  to manipulate it.  Typically a sequence will push one
- *     of the parameters onto the stack and then print it  in  some
- *     format.  Often more complex operations are necessary.
- *
- *          The % encodings have the following meanings:
- *
- *          %%        outputs `%'
- *          %c        print pop() like %c in printf()
- *          %s        print pop() like %s in printf()
- *           %[[:]flags][width[.precision]][doxXs]
- *                     as in printf, flags are [-+#] and space
- *                     The ':' is used to avoid making %+ or %-
- *                     patterns (see below).
- *
- *          %p[1-9]   push ith parm
- *          %P[a-z]   set dynamic variable [a-z] to pop()
- *          %g[a-z]   get dynamic variable [a-z] and push it
- *          %P[A-Z]   set static variable [A-Z] to pop()
- *          %g[A-Z]   get static variable [A-Z] and push it
- *          %l        push strlen(pop)
- *          %'c'      push char constant c
- *          %{nn}     push integer constant nn
- *
- *          %+ %- %* %/ %m
- *                    arithmetic (%m is mod): push(pop() op pop())
- *          %& %| %^  bit operations: push(pop() op pop())
- *          %= %> %<  logical operations: push(pop() op pop())
- *          %A %O     logical and & or operations for conditionals
- *          %! %~     unary operations push(op pop())
- *          %i        add 1 to first two parms (for ANSI terminals)
- *
- *          %? expr %t thenpart %e elsepart %;
- *                    if-then-else, %e elsepart is optional.
- *                    else-if's are possible ala Algol 68:
- *                    %? c1 %t b1 %e c2 %t b2 %e c3 %t b3 %e c4 %t b4 %e b5 %;
- *
- *     For those of the above operators which are binary and not commutative,
- *     the stack works in the usual way, with
- *                     %gx %gy %m
- *     resulting in x mod y, not the reverse.
- */
-
-typedef struct {
-    union {
-       int num;
-       char *str;
-    } data;
-    grub_bool_t num_type;
-} stack_frame;
-
-static stack_frame stack[STACKSIZE];
-static int stack_ptr;
-static const char *tparam_base = "";
-
-static char *out_buff;
-static grub_size_t out_size;
-static grub_size_t out_used;
-
-static char *fmt_buff;
-static grub_size_t fmt_size;
-
-static inline void
-get_space(grub_size_t need)
-{
-    need += out_used;
-    if (need > out_size) {
-       out_size = need * 2;
-       out_buff = grub_realloc(out_buff, out_size*sizeof(char));
-       /* FIX ME! handle out_buff == 0.  */
-    }
-}
-
-static inline void
-save_text(const char *fmt, const char *s, int len)
-{
-    grub_size_t s_len = grub_strlen(s);
-    if (len > (int) s_len)
-       s_len = len;
-
-    get_space(s_len + 1);
-
-    (void) grub_snprintf(out_buff + out_used, s_len + 1, fmt, s);
-    out_used += grub_strlen(out_buff + out_used);
-}
-
-static inline void
-save_number(const char *fmt, int number, int len)
-{
-    if (len < 30)
-       len = 30;               /* actually log10(MAX_INT)+1 */
-
-    get_space((unsigned) len + 1);
-
-    (void) grub_snprintf(out_buff + out_used, len + 1, fmt, number);
-    out_used += grub_strlen(out_buff + out_used);
-}
-
-static inline void
-save_char(int c)
-{
-    if (c == 0)
-       c = 0200;
-    get_space(1);
-    out_buff[out_used++] = c;
-}
-
-static inline void
-npush(int x)
-{
-    if (stack_ptr < STACKSIZE) {
-       stack[stack_ptr].num_type = TRUE;
-       stack[stack_ptr].data.num = x;
-       stack_ptr++;
-    }
-}
-
-static inline int
-npop(void)
-{
-    int result = 0;
-    if (stack_ptr > 0) {
-       stack_ptr--;
-       if (stack[stack_ptr].num_type)
-           result = stack[stack_ptr].data.num;
-    }
-    return result;
-}
-
-static inline void
-spush(char *x)
-{
-    if (stack_ptr < STACKSIZE) {
-       stack[stack_ptr].num_type = FALSE;
-       stack[stack_ptr].data.str = x;
-       stack_ptr++;
-    }
-}
-
-static inline char *
-spop(void)
-{
-    static char dummy[] = "";  /* avoid const-cast */
-    char *result = dummy;
-    if (stack_ptr > 0) {
-       stack_ptr--;
-       if (!stack[stack_ptr].num_type && stack[stack_ptr].data.str != 0)
-           result = stack[stack_ptr].data.str;
-    }
-    return result;
-}
-
-static inline const char *
-parse_format(const char *s, char *format, int *len)
-{
-    *len = 0;
-    if (format != 0) {
-       grub_bool_t done = FALSE;
-       grub_bool_t allowminus = FALSE;
-       grub_bool_t dot = FALSE;
-       grub_bool_t err = FALSE;
-       char *fmt = format;
-       int my_width = 0;
-       int my_prec = 0;
-       int value = 0;
-
-       *len = 0;
-       *format++ = '%';
-       while (*s != '\0' && !done) {
-           switch (*s) {
-           case 'c':           /* FALLTHRU */
-           case 'd':           /* FALLTHRU */
-           case 'o':           /* FALLTHRU */
-           case 'x':           /* FALLTHRU */
-           case 'X':           /* FALLTHRU */
-           case 's':
-               *format++ = *s;
-               done = TRUE;
-               break;
-           case '.':
-               *format++ = *s++;
-               if (dot) {
-                   err = TRUE;
-               } else {        /* value before '.' is the width */
-                   dot = TRUE;
-                   my_width = value;
-               }
-               value = 0;
-               break;
-           case '#':
-               *format++ = *s++;
-               break;
-           case ' ':
-               *format++ = *s++;
-               break;
-           case ':':
-               s++;
-               allowminus = TRUE;
-               break;
-           case '-':
-               if (allowminus) {
-                   *format++ = *s++;
-               } else {
-                   done = TRUE;
-               }
-               break;
-           default:
-               if (isdigit(UChar(*s))) {
-                   value = (value * 10) + (*s - '0');
-                   if (value > 10000)
-                       err = TRUE;
-                   *format++ = *s++;
-               } else {
-                   done = TRUE;
-               }
-           }
-       }
-
-       /*
-        * If we found an error, ignore (and remove) the flags.
-        */
-       if (err) {
-           my_width = my_prec = value = 0;
-           format = fmt;
-           *format++ = '%';
-           *format++ = *s;
-       }
-
-       /*
-        * Any value after '.' is the precision.  If we did not see '.', then
-        * the value is the width.
-        */
-       if (dot)
-           my_prec = value;
-       else
-           my_width = value;
-
-       *format = '\0';
-       /* return maximum string length in print */
-       *len = (my_width > my_prec) ? my_width : my_prec;
-    }
-    return s;
-}
-
-/*
- * Analyze the string to see how many parameters we need from the varargs list,
- * and what their types are.  We will only accept string parameters if they
- * appear as a %l or %s format following an explicit parameter reference (e.g.,
- * %p2%s).  All other parameters are numbers.
- *
- * 'number' counts coarsely the number of pop's we see in the string, and
- * 'popcount' shows the highest parameter number in the string.  We would like
- * to simply use the latter count, but if we are reading termcap strings, there
- * may be cases that we cannot see the explicit parameter numbers.
- */
-static inline int
-analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount)
-{
-    grub_size_t len2;
-    int i;
-    int lastpop = -1;
-    int len;
-    int number = 0;
-    const char *cp = string;
-    static char dummy[] = "";
-
-    *popcount = 0;
-
-    if (cp == 0)
-       return 0;
-
-    if ((len2 = grub_strlen(cp)) > fmt_size) {
-       fmt_size = len2 + fmt_size + 2;
-       if ((fmt_buff = grub_realloc(fmt_buff, fmt_size*sizeof(char))) == 0)
-             return 0;
-    }
-
-    grub_memset(p_is_s, 0, sizeof(p_is_s[0]) * NUM_PARM);
-
-    while ((cp - string) < (int) len2) {
-       if (*cp == '%') {
-           cp++;
-           cp = parse_format(cp, fmt_buff, &len);
-           switch (*cp) {
-           default:
-               break;
-
-           case 'd':           /* FALLTHRU */
-           case 'o':           /* FALLTHRU */
-           case 'x':           /* FALLTHRU */
-           case 'X':           /* FALLTHRU */
-           case 'c':           /* FALLTHRU */
-               if (lastpop <= 0)
-                   number++;
-               lastpop = -1;
-               break;
-
-           case 'l':
-           case 's':
-               if (lastpop > 0)
-                   p_is_s[lastpop - 1] = dummy;
-               ++number;
-               break;
-
-           case 'p':
-               cp++;
-               i = (UChar(*cp) - '0');
-               if (i >= 0 && i <= NUM_PARM) {
-                   lastpop = i;
-                   if (lastpop > *popcount)
-                       *popcount = lastpop;
-               }
-               break;
-
-           case 'P':
-               ++number;
-               ++cp;
-               break;
-
-           case 'g':
-               cp++;
-               break;
-
-           case '\'':
-               cp += 2;
-               lastpop = -1;
-               break;
-
-           case '{':
-               cp++;
-               while (isdigit(UChar(*cp))) {
-                   cp++;
-               }
-               break;
-
-           case '+':
-           case '-':
-           case '*':
-           case '/':
-           case 'm':
-           case 'A':
-           case 'O':
-           case '&':
-           case '|':
-           case '^':
-           case '=':
-           case '<':
-           case '>':
-               lastpop = -1;
-               number += 2;
-               break;
-
-           case '!':
-           case '~':
-               lastpop = -1;
-               ++number;
-               break;
-
-           case 'i':
-               /* will add 1 to first (usually two) parameters */
-               break;
-           }
-       }
-       if (*cp != '\0')
-           cp++;
-    }
-
-    if (number > NUM_PARM)
-       number = NUM_PARM;
-    return number;
-}
-
-static inline char *
-tparam_internal(const char *string, va_list ap)
-{
-    char *p_is_s[NUM_PARM];
-    long param[NUM_PARM];
-    int popcount;
-    int number;
-    int len;
-    int level;
-    int x, y;
-    int i;
-    const char *cp = string;
-    grub_size_t len2;
-    static int dynamic_var[NUM_VARS];
-    static int static_vars[NUM_VARS];
-
-    if (cp == 0)
-       return 0;
-
-    out_used = out_size = fmt_size = 0;
-
-    len2 = (int) grub_strlen(cp);
-
-    /*
-     * Find the highest parameter-number referred to in the format string.
-     * Use this value to limit the number of arguments copied from the
-     * variable-length argument list.
-     */
-    number = analyze(cp, p_is_s, &popcount);
-    if (fmt_buff == 0)
-       return 0;
-
-    for (i = 0; i < max(popcount, number); i++) {
-       /*
-        * A few caps (such as plab_norm) have string-valued parms.
-        * We'll have to assume that the caller knows the difference, since
-        * a char* and an int may not be the same size on the stack.
-        */
-       if (p_is_s[i] != 0) {
-           p_is_s[i] = va_arg(ap, char *);
-       } else {
-           param[i] = va_arg(ap, long int);
-       }
-    }
-
-    /*
-     * This is a termcap compatibility hack.  If there are no explicit pop
-     * operations in the string, load the stack in such a way that
-     * successive pops will grab successive parameters.  That will make
-     * the expansion of (for example) \E[%d;%dH work correctly in termcap
-     * style, which means tparam() will expand termcap strings OK.
-     */
-    stack_ptr = 0;
-    if (popcount == 0) {
-       popcount = number;
-       for (i = number - 1; i >= 0; i--)
-           npush(param[i]);
-    }
-
-    while ((cp - string) < (int) len2) {
-       if (*cp != '%') {
-           save_char(UChar(*cp));
-       } else {
-           tparam_base = cp++;
-           cp = parse_format(cp, fmt_buff, &len);
-           switch (*cp) {
-           default:
-               break;
-           case '%':
-               save_char('%');
-               break;
-
-           case 'd':           /* FALLTHRU */
-           case 'o':           /* FALLTHRU */
-           case 'x':           /* FALLTHRU */
-           case 'X':           /* FALLTHRU */
-               save_number(fmt_buff, npop(), len);
-               break;
-
-           case 'c':           /* FALLTHRU */
-               save_char(npop());
-               break;
-
-           case 'l':
-               save_number("%d", (int) grub_strlen(spop()), 0);
-               break;
-
-           case 's':
-               save_text(fmt_buff, spop(), len);
-               break;
-
-           case 'p':
-               cp++;
-               i = (UChar(*cp) - '1');
-               if (i >= 0 && i < NUM_PARM) {
-                   if (p_is_s[i])
-                       spush(p_is_s[i]);
-                   else
-                       npush(param[i]);
-               }
-               break;
-
-           case 'P':
-               cp++;
-               if (isUPPER(*cp)) {
-                   i = (UChar(*cp) - 'A');
-                   static_vars[i] = npop();
-               } else if (isLOWER(*cp)) {
-                   i = (UChar(*cp) - 'a');
-                   dynamic_var[i] = npop();
-               }
-               break;
-
-           case 'g':
-               cp++;
-               if (isUPPER(*cp)) {
-                   i = (UChar(*cp) - 'A');
-                   npush(static_vars[i]);
-               } else if (isLOWER(*cp)) {
-                   i = (UChar(*cp) - 'a');
-                   npush(dynamic_var[i]);
-               }
-               break;
-
-           case '\'':
-               cp++;
-               npush(UChar(*cp));
-               cp++;
-               break;
-
-           case '{':
-               number = 0;
-               cp++;
-               while (isdigit(UChar(*cp))) {
-                   number = (number * 10) + (UChar(*cp) - '0');
-                   cp++;
-               }
-               npush(number);
-               break;
-
-           case '+':
-               npush(npop() + npop());
-               break;
-
-           case '-':
-               y = npop();
-               x = npop();
-               npush(x - y);
-               break;
-
-           case '*':
-               npush(npop() * npop());
-               break;
-
-           case '/':
-               y = npop();
-               x = npop();
-               npush(y ? (x / y) : 0);
-               break;
-
-           case 'm':
-               y = npop();
-               x = npop();
-               npush(y ? (x % y) : 0);
-               break;
-
-           case 'A':
-               npush(npop() && npop());
-               break;
-
-           case 'O':
-               npush(npop() || npop());
-               break;
-
-           case '&':
-               npush(npop() & npop());
-               break;
-
-           case '|':
-               npush(npop() | npop());
-               break;
-
-           case '^':
-               npush(npop() ^ npop());
-               break;
-
-           case '=':
-               y = npop();
-               x = npop();
-               npush(x == y);
-               break;
-
-           case '<':
-               y = npop();
-               x = npop();
-               npush(x < y);
-               break;
-
-           case '>':
-               y = npop();
-               x = npop();
-               npush(x > y);
-               break;
-
-           case '!':
-               npush(!npop());
-               break;
-
-           case '~':
-               npush(~npop());
-               break;
-
-           case 'i':
-               if (p_is_s[0] == 0)
-                   param[0]++;
-               if (p_is_s[1] == 0)
-                   param[1]++;
-               break;
-
-           case '?':
-               break;
-
-           case 't':
-               x = npop();
-               if (!x) {
-                   /* scan forward for %e or %; at level zero */
-                   cp++;
-                   level = 0;
-                   while (*cp) {
-                       if (*cp == '%') {
-                           cp++;
-                           if (*cp == '?')
-                               level++;
-                           else if (*cp == ';') {
-                               if (level > 0)
-                                   level--;
-                               else
-                                   break;
-                           } else if (*cp == 'e' && level == 0)
-                               break;
-                       }
-
-                       if (*cp)
-                           cp++;
-                   }
-               }
-               break;
-
-           case 'e':
-               /* scan forward for a %; at level zero */
-               cp++;
-               level = 0;
-               while (*cp) {
-                   if (*cp == '%') {
-                       cp++;
-                       if (*cp == '?')
-                           level++;
-                       else if (*cp == ';') {
-                           if (level > 0)
-                               level--;
-                           else
-                               break;
-                       }
-                   }
-
-                   if (*cp)
-                       cp++;
-               }
-               break;
-
-           case ';':
-               break;
-
-           }                   /* endswitch (*cp) */
-       }                       /* endelse (*cp == '%') */
-
-       if (*cp == '\0')
-           break;
-
-       cp++;
-    }                          /* endwhile (*cp) */
-
-    get_space(1);
-    out_buff[out_used] = '\0';
-
-    return (out_buff);
-}
-
-char *
-grub_terminfo_tparm (const char *string, ...)
-{
-    va_list ap;
-    char *result;
-
-    va_start (ap, string);
-    result = tparam_internal (string, ap);
-    va_end (ap);
-    return result;
-}
diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c
deleted file mode 100644 (file)
index 5d76c5e..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/* Support for the HID Boot Protocol.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008, 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/term.h>
-#include <grub/machine/console.h>
-#include <grub/time.h>
-#include <grub/cpu/io.h>
-#include <grub/misc.h>
-#include <grub/term.h>
-#include <grub/usb.h>
-#include <grub/dl.h>
-#include <grub/time.h>
-
-\f
-static char keyboard_map[128] =
-  {
-    '\0', '\0', '\0', '\0', 'a', 'b', 'c', 'd',
-    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
-    'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
-    'u', 'v', 'w', 'x', 'y', 'z', '1', '2',
-    '3', '4', '5', '6', '7', '8', '9', '0',
-    '\n', GRUB_TERM_ESC, GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, ' ', '-', '=', '[',
-    ']', '\\', '#', ';', '\'', '`', ',', '.',
-    '/', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
-    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
-    '\0', '\0', GRUB_TERM_HOME, GRUB_TERM_PPAGE, GRUB_TERM_DC, GRUB_TERM_END, GRUB_TERM_NPAGE, GRUB_TERM_RIGHT,
-    GRUB_TERM_LEFT, GRUB_TERM_DOWN, GRUB_TERM_UP
-  };
-
-static char keyboard_map_shift[128] =
-  {
-    '\0', '\0', '\0', '\0', 'A', 'B', 'C', 'D',
-    'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
-    'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
-    'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@',
-    '#', '$', '%', '^', '&', '*', '(', ')',
-    '\n', '\0', '\0', '\0', ' ', '_', '+', '{',
-    '}', '|', '#', ':', '"', '`', '<', '>',
-    '?'
-  };
-
-static grub_usb_device_t usbdev;
-
-/* Valid values for bmRequestType.  See HID definition version 1.11 section
-   7.2.  */
-#define USB_HID_HOST_TO_DEVICE 0x21
-#define USB_HID_DEVICE_TO_HOST 0xA1
-
-/* Valid values for bRequest.  See HID definition version 1.11 section 7.2. */
-#define USB_HID_GET_REPORT     0x01
-#define USB_HID_GET_IDLE       0x02
-#define USB_HID_GET_PROTOCOL   0x03
-#define USB_HID_SET_REPORT     0x09
-#define USB_HID_SET_IDLE       0x0A
-#define USB_HID_SET_PROTOCOL   0x0B
-
-static void
-grub_usb_hid (void)
-{
-  struct grub_usb_desc_device *descdev;
-
-  auto int usb_iterate (grub_usb_device_t dev);
-  int usb_iterate (grub_usb_device_t dev)
-    {
-      descdev = &dev->descdev;
-
-      grub_dprintf ("usb_keyboard", "%x %x %x\n",
-                  descdev->class, descdev->subclass, descdev->protocol);
-
-#if 0
-      if (descdev->class != 0x09
-         || descdev->subclass == 0x01
-         || descdev->protocol != 0x02)
-       return 0;
-#endif
-
-      if (descdev->class != 0 || descdev->subclass != 0 || descdev->protocol != 0)
-       return 0;
-
-      grub_printf ("HID found!\n");
-
-      usbdev = dev;
-
-      return 1;
-    }
-  grub_usb_iterate (usb_iterate);
-
-  /* Place the device in boot mode.  */
-  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_PROTOCOL,
-                       0, 0, 0, 0);
-
-  /* Reports every time an event occurs and not more often than that.  */
-  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
-                       0<<8, 0, 0, 0);
-}
-
-static grub_err_t
-grub_usb_keyboard_getreport (grub_usb_device_t dev, grub_uint8_t *report)
-{
-  return grub_usb_control_msg (dev, USB_HID_DEVICE_TO_HOST, USB_HID_GET_REPORT,
-                              0, 0, 8, (char *) report);
-}
-
-\f
-
-static int
-grub_usb_keyboard_checkkey (void)
-{
-  grub_uint8_t data[8];
-  int key;
-  grub_err_t err;
-  grub_uint64_t currtime;
-  int timeout = 50;
-
-  data[2] = 0;
-  currtime = grub_get_time_ms ();
-  do
-    {
-      /* Get_Report.  */
-      err = grub_usb_keyboard_getreport (usbdev, data);
-
-      /* Implement a timeout.  */
-      if (grub_get_time_ms () > currtime + timeout)
-       break;
-    }
-  while (err || !data[2]);
-
-  if (err || !data[2])
-    return -1;
-
-  grub_dprintf ("usb_keyboard",
-               "report: 0x%02x 0x%02x 0x%02x 0x%02x"
-               " 0x%02x 0x%02x 0x%02x 0x%02x\n",
-               data[0], data[1], data[2], data[3],
-               data[4], data[5], data[6], data[7]);
-
-  /* Check if the Control or Shift key was pressed.  */
-  if (data[0] & 0x01 || data[0] & 0x10)
-    key = keyboard_map[data[2]] - 'a' + 1;
-  else if (data[0] & 0x02 || data[0] & 0x20)
-    key = keyboard_map_shift[data[2]];
-  else
-    key = keyboard_map[data[2]];
-
-  if (key == 0)
-    grub_printf ("Unknown key 0x%x detected\n", data[2]);
-
-#if 0
-  /* Wait until the key is released.  */
-  while (!err && data[2])
-    {
-      err = grub_usb_control_msg (usbdev, USB_HID_DEVICE_TO_HOST,
-                                 USB_HID_GET_REPORT, 0, 0,
-                                 sizeof (data), (char *) data);
-      grub_dprintf ("usb_keyboard",
-                   "report2: 0x%02x 0x%02x 0x%02x 0x%02x"
-                   " 0x%02x 0x%02x 0x%02x 0x%02x\n",
-                   data[0], data[1], data[2], data[3],
-                   data[4], data[5], data[6], data[7]);
-    }
-#endif
-
-  grub_errno = GRUB_ERR_NONE;
-
-  return key;
-}
-
-typedef enum
-{
-  GRUB_HIDBOOT_REPEAT_NONE,
-  GRUB_HIDBOOT_REPEAT_FIRST,
-  GRUB_HIDBOOT_REPEAT
-} grub_usb_keyboard_repeat_t;
-
-static int
-grub_usb_keyboard_getkey (void)
-{
-  int key;
-  grub_err_t err;
-  grub_uint8_t data[8];
-  grub_uint64_t currtime;
-  int timeout;
-  static grub_usb_keyboard_repeat_t repeat = GRUB_HIDBOOT_REPEAT_NONE;
-
- again:
-
-  do
-    {
-      key = grub_usb_keyboard_checkkey ();
-    } while (key == -1);
-
-  data[2] = !0; /* Or whatever.  */
-  err = 0;
-
-  switch (repeat)
-    {
-    case GRUB_HIDBOOT_REPEAT_FIRST:
-      timeout = 500;
-      break;
-    case GRUB_HIDBOOT_REPEAT:
-      timeout = 50;
-      break;
-    default:
-      timeout = 100;
-      break;
-    }
-
-  /* Wait until the key is released.  */
-  currtime = grub_get_time_ms ();
-  while (!err && data[2])
-    {
-      /* Implement a timeout.  */
-      if (grub_get_time_ms () > currtime + timeout)
-       {
-         if (repeat == 0)
-           repeat = 1;
-         else
-           repeat = 2;
-
-         grub_errno = GRUB_ERR_NONE;
-         return key;
-       }
-
-      err = grub_usb_keyboard_getreport (usbdev, data);
-    }
-
-  if (repeat)
-    {
-      repeat = 0;
-      goto again;
-    }
-
-  repeat = 0;
-
-  grub_errno = GRUB_ERR_NONE;
-
-  return key;
-}
-
-static int
-grub_usb_keyboard_getkeystatus (void)
-{
-  grub_uint8_t data[8];
-  int mods = 0;
-  grub_err_t err;
-  grub_uint64_t currtime;
-  int timeout = 50;
-
-  /* Set idle time to the minimum offered by the spec (4 milliseconds) so
-     that we can find out the current state.  */
-  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
-                       0<<8, 0, 0, 0);
-
-  currtime = grub_get_time_ms ();
-  do
-    {
-      /* Get_Report.  */
-      err = grub_usb_keyboard_getreport (usbdev, data);
-
-      /* Implement a timeout.  */
-      if (grub_get_time_ms () > currtime + timeout)
-       break;
-    }
-  while (err || !data[0]);
-
-  /* Go back to reporting every time an event occurs and not more often than
-     that.  */
-  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
-                       0<<8, 0, 0, 0);
-
-  /* We allowed a while for modifiers to show up in the report, but it is
-     not an error if they never did.  */
-  if (err)
-    return -1;
-
-  grub_dprintf ("usb_keyboard",
-               "report: 0x%02x 0x%02x 0x%02x 0x%02x"
-               " 0x%02x 0x%02x 0x%02x 0x%02x\n",
-               data[0], data[1], data[2], data[3],
-               data[4], data[5], data[6], data[7]);
-
-  /* Check Shift, Control, and Alt status.  */
-  if (data[0] & 0x02 || data[0] & 0x20)
-    mods |= GRUB_TERM_STATUS_SHIFT;
-  if (data[0] & 0x01 || data[0] & 0x10)
-    mods |= GRUB_TERM_STATUS_CTRL;
-  if (data[0] & 0x04 || data[0] & 0x40)
-    mods |= GRUB_TERM_STATUS_ALT;
-
-  grub_errno = GRUB_ERR_NONE;
-
-  return mods;
-}
-
-static struct grub_term_input grub_usb_keyboard_term =
-  {
-    .name = "usb_keyboard",
-    .checkkey = grub_usb_keyboard_checkkey,
-    .getkey = grub_usb_keyboard_getkey,
-    .getkeystatus = grub_usb_keyboard_getkeystatus,
-    .next = 0
-  };
-
-GRUB_MOD_INIT(usb_keyboard)
-{
-  grub_usb_hid ();
-  grub_term_register_input ("usb_keyboard", &grub_usb_keyboard_term);
-}
-
-GRUB_MOD_FINI(usb_keyboard)
-{
-  grub_term_unregister_input (&grub_usb_keyboard_term);
-}
diff --git a/tests/example_functional_test.c b/tests/example_functional_test.c
deleted file mode 100644 (file)
index 6802d2d..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2010 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* All tests need to include test.h for GRUB testing framework.  */
-#include <grub/test.h>
-
-/* Functional test main method.  */
-static void
-example_test (void)
-{
-  /* Check if 1st argument is true and report with default error message.  */
-  grub_test_assert (1 == 1);
-
-  /* Check if 1st argument is true and report with custom error message.  */
-  grub_test_assert (2 == 2, "2 equal 2 expected");
-  grub_test_assert (2 != 3, "2 matches %d", 3);
-}
-
-/* Register example_test method as a functional test.  */
-GRUB_FUNCTIONAL_TEST ("example_functional_test", example_test);
index 93a90a18e34ab75c9b4288e6337a074ca8b9d3f5..6fa3dc98a9254eb2087ed62050e63f7e574868b6 100644 (file)
@@ -1,3 +1,3 @@
-#! @builddir@/grub-shell-tester --modules=echo
+#! @abs_top_builddir@/grub-shell-tester --modules=echo
 
 echo "hello world"
diff --git a/tests/lib/functional_test.c b/tests/lib/functional_test.c
deleted file mode 100644 (file)
index 8ff08cf..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2010 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/extcmd.h>
-#include <grub/test.h>
-
-static grub_err_t
-grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)),
-                     int argc __attribute__ ((unused)),
-                     char **args __attribute__ ((unused)))
-{
-  auto int run_test (grub_test_t test);
-  int run_test (grub_test_t test)
-  {
-    grub_test_run (test);
-    return 0;
-  }
-
-  grub_list_iterate (GRUB_AS_LIST (grub_test_list),
-                    (grub_list_hook_t) run_test);
-  return GRUB_ERR_NONE;
-}
-
-static grub_extcmd_t cmd;
-
-GRUB_MOD_INIT (functional_test)
-{
-  cmd = grub_register_extcmd ("functional_test", grub_functional_test,
-                             GRUB_COMMAND_FLAG_CMDLINE, 0,
-                             "Run all functional tests.", 0);
-}
-
-GRUB_MOD_FINI (functional_test)
-{
-  grub_unregister_extcmd (cmd);
-}
diff --git a/tests/lib/test.c b/tests/lib/test.c
deleted file mode 100644 (file)
index b5c0543..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2010 Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/test.h>
-
-struct grub_test_failure
-{
-  /* The next failure.  */
-  struct grub_test_failure *next;
-
-  /* The test source file name.  */
-  char *file;
-
-  /* The test function name.  */
-  char *funp;
-
-  /* The test call line number.  */
-  grub_uint32_t line;
-
-  /* The test failure message.  */
-  char *message;
-};
-typedef struct grub_test_failure *grub_test_failure_t;
-
-grub_test_t grub_test_list;
-static grub_test_failure_t failure_list;
-
-static void
-add_failure (const char *file,
-            const char *funp,
-            grub_uint32_t line, const char *fmt, va_list args)
-{
-  grub_test_failure_t failure;
-
-  failure = (grub_test_failure_t) grub_malloc (sizeof (*failure));
-  if (!failure)
-    return;
-
-  failure->file = grub_strdup (file ? : "<unknown_file>");
-  failure->funp = grub_strdup (funp ? : "<unknown_function>");
-  failure->line = line;
-  failure->message = grub_xvasprintf (fmt, args);
-
-  grub_list_push (GRUB_AS_LIST_P (&failure_list), GRUB_AS_LIST (failure));
-}
-
-static void
-free_failures (void)
-{
-  grub_test_failure_t item;
-
-  while ((item = grub_list_pop (GRUB_AS_LIST_P (&failure_list))) != 0)
-    {
-      if (item->message)
-       grub_free (item->message);
-
-      if (item->funp)
-       grub_free (item->funp);
-
-      if (item->file)
-       grub_free (item->file);
-
-      grub_free (item);
-    }
-  failure_list = 0;
-}
-
-void
-grub_test_nonzero (int cond,
-                  const char *file,
-                  const char *funp, grub_uint32_t line, const char *fmt, ...)
-{
-  va_list ap;
-
-  if (cond)
-    return;
-
-  va_start (ap, fmt);
-  add_failure (file, funp, line, fmt, ap);
-  va_end (ap);
-}
-
-void
-grub_test_register (const char *name, void (*test_main) (void))
-{
-  grub_test_t test;
-
-  test = (grub_test_t) grub_malloc (sizeof (*test));
-  if (!test)
-    return;
-
-  test->name = grub_strdup (name);
-  test->main = test_main;
-
-  grub_list_push (GRUB_AS_LIST_P (&grub_test_list), GRUB_AS_LIST (test));
-}
-
-void
-grub_test_unregister (const char *name)
-{
-  grub_test_t test;
-
-  test = (grub_test_t) grub_named_list_find
-    (GRUB_AS_NAMED_LIST (grub_test_list), name);
-
-  if (test)
-    {
-      grub_list_remove (GRUB_AS_LIST_P (&grub_test_list), GRUB_AS_LIST (test));
-
-      if (test->name)
-       grub_free (test->name);
-
-      grub_free (test);
-    }
-}
-
-int
-grub_test_run (grub_test_t test)
-{
-  auto int print_failure (grub_test_failure_t item);
-  int print_failure (grub_test_failure_t item)
-  {
-    grub_test_failure_t failure = (grub_test_failure_t) item;
-
-    grub_printf (" %s:%s:%u: %s\n",
-                (failure->file ? : "<unknown_file>"),
-                (failure->funp ? : "<unknown_function>"),
-                failure->line, (failure->message ? : "<no message>"));
-    return 0;
-  }
-
-  test->main ();
-
-  grub_printf ("%s:\n", test->name);
-  grub_list_iterate (GRUB_AS_LIST (failure_list),
-                    (grub_list_hook_t) print_failure);
-  if (!failure_list)
-    grub_printf ("%s: PASS\n", test->name);
-  else
-    grub_printf ("%s: FAIL\n", test->name);
-
-  free_failures ();
-  return GRUB_ERR_NONE;
-}
index e461150deec8386725da2c3ebf670915387a7a34..92c8ae33a0f5105aa9c837dd7637331a182133a3 100644 (file)
@@ -105,5 +105,4 @@ grub_exit (void)
   exit (1);
 }
 
-struct grub_handler_class grub_term_input_class;
-struct grub_handler_class grub_term_output_class;
+struct grub_term_input *grub_term_inputs;
index e9507c8f546f3d51a13739df8200619c8304f966..f1e91f56192e0389ee26e67eba7f2c7889707a12 100644 (file)
@@ -91,7 +91,7 @@ if [ "x${source}" = x ] ; then
 fi
 
 outfile1=`mktemp`
-@builddir@/grub-shell --qemu-opts="${qemuopts}" --modules=${modules} ${source} >${outfile1}
+@abs_top_builddir@/grub-shell --qemu-opts="${qemuopts}" --modules=${modules} ${source} >${outfile1}
 
 outfile2=`mktemp`
 bash ${source} >${outfile2}
index a41a6f6f46f6780930ab2cc91700e4bba09c0848..8324beb9766f050d99ef10d803fd42f1383031d8 100644 (file)
@@ -123,10 +123,14 @@ source /boot/grub/testcase.cfg
 halt
 EOF
 
+rootdir=`mktemp -d`
+(cd @abs_top_builddir@ && make DESTDIR=$rootdir install) >/dev/null 2>&1
+
 isofile=`mktemp`
-grub-mkrescue --output=${isofile} --override-directory=${builddir} \
-  /boot/grub/grub.cfg=${cfgfile} /boot/grub/testcase.cfg=${source} \
-  >/dev/null 2>&1
+sh @abs_top_builddir@/grub-mkrescue --output=${isofile} \
+  --root-directory=${rootdir} /boot/grub/grub.cfg=${cfgfile} \
+  /boot/grub/testcase.cfg=${source} >/dev/null 2>&1
+rm -rf $rootdir
 
 hdafile=`mktemp`
 cp ${isofile} ${hdafile}
diff --git a/util/console.c b/util/console.c
deleted file mode 100644 (file)
index 382fd7f..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-/*  console.c -- Ncurses console for GRUB.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2005,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-/* For compatibility.  */
-#ifndef A_NORMAL
-# define A_NORMAL      0
-#endif /* ! A_NORMAL */
-#ifndef A_STANDOUT
-# define A_STANDOUT    0
-#endif /* ! A_STANDOUT */
-
-#include <grub/util/console.h>
-#include <grub/term.h>
-#include <grub/types.h>
-
-#if defined(HAVE_NCURSES_CURSES_H)
-# include <ncurses/curses.h>
-#elif defined(HAVE_NCURSES_H)
-# include <ncurses.h>
-#elif defined(HAVE_CURSES_H)
-# include <curses.h>
-#endif
-
-static int grub_console_attr = A_NORMAL;
-
-grub_uint8_t grub_console_cur_color = 7;
-
-static grub_uint8_t grub_console_standard_color = 0x7;
-static grub_uint8_t grub_console_normal_color = 0x7;
-static grub_uint8_t grub_console_highlight_color = 0x70;
-
-#define NUM_COLORS     8
-
-static grub_uint8_t color_map[NUM_COLORS] =
-{
-  COLOR_BLACK,
-  COLOR_BLUE,
-  COLOR_GREEN,
-  COLOR_CYAN,
-  COLOR_RED,
-  COLOR_MAGENTA,
-  COLOR_YELLOW,
-  COLOR_WHITE
-};
-
-static int use_color;
-
-static void
-grub_ncurses_putchar (grub_uint32_t c)
-{
-  /* Better than nothing.  */
-  switch (c)
-    {
-    case GRUB_TERM_DISP_LEFT:
-      c = '<';
-      break;
-
-    case GRUB_TERM_DISP_UP:
-      c = '^';
-      break;
-
-    case GRUB_TERM_DISP_RIGHT:
-      c = '>';
-      break;
-
-    case GRUB_TERM_DISP_DOWN:
-      c = 'v';
-      break;
-
-    case GRUB_TERM_DISP_HLINE:
-      c = '-';
-      break;
-
-    case GRUB_TERM_DISP_VLINE:
-      c = '|';
-      break;
-
-    case GRUB_TERM_DISP_UL:
-    case GRUB_TERM_DISP_UR:
-    case GRUB_TERM_DISP_LL:
-    case GRUB_TERM_DISP_LR:
-      c = '+';
-      break;
-
-    default:
-      /* ncurses does not support Unicode.  */
-      if (c > 0x7f)
-       c = '?';
-      break;
-    }
-
-  addch (c | grub_console_attr);
-}
-
-static grub_ssize_t
-grub_ncurses_getcharwidth (grub_uint32_t code __attribute__ ((unused)))
-{
-  return 1;
-}
-
-static void
-grub_ncurses_setcolorstate (grub_term_color_state state)
-{
-  switch (state)
-    {
-    case GRUB_TERM_COLOR_STANDARD:
-      grub_console_cur_color = grub_console_standard_color;
-      grub_console_attr = A_NORMAL;
-      break;
-    case GRUB_TERM_COLOR_NORMAL:
-      grub_console_cur_color = grub_console_normal_color;
-      grub_console_attr = A_NORMAL;
-      break;
-    case GRUB_TERM_COLOR_HIGHLIGHT:
-      grub_console_cur_color = grub_console_highlight_color;
-      grub_console_attr = A_STANDOUT;
-      break;
-    default:
-      break;
-    }
-
-  if (use_color)
-    {
-      grub_uint8_t fg, bg;
-
-      fg = (grub_console_cur_color & 7);
-      bg = (grub_console_cur_color >> 4) & 7;
-
-      grub_console_attr = (grub_console_cur_color & 8) ? A_BOLD : A_NORMAL;
-      color_set ((bg << 3) + fg, 0);
-    }
-}
-
-/* XXX: This function is never called.  */
-static void
-grub_ncurses_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
-{
-  grub_console_normal_color = normal_color;
-  grub_console_highlight_color = highlight_color;
-}
-
-static void
-grub_ncurses_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
-{
-  *normal_color = grub_console_normal_color;
-  *highlight_color = grub_console_highlight_color;
-}
-
-static int saved_char = ERR;
-
-static int
-grub_ncurses_checkkey (void)
-{
-  int c;
-
-  /* Check for SAVED_CHAR. This should not be true, because this
-     means checkkey is called twice continuously.  */
-  if (saved_char != ERR)
-    return saved_char;
-
-  wtimeout (stdscr, 100);
-  c = getch ();
-  /* If C is not ERR, then put it back in the input queue.  */
-  if (c != ERR)
-    {
-      saved_char = c;
-      return c;
-    }
-
-  return -1;
-}
-
-static int
-grub_ncurses_getkey (void)
-{
-  int c;
-
-  /* If checkkey has already got a character, then return it.  */
-  if (saved_char != ERR)
-    {
-      c = saved_char;
-      saved_char = ERR;
-    }
-  else
-    {
-      wtimeout (stdscr, -1);
-      c = getch ();
-    }
-
-  switch (c)
-    {
-    case KEY_LEFT:
-      c = 2;
-      break;
-
-    case KEY_RIGHT:
-      c = 6;
-      break;
-
-    case KEY_UP:
-      c = 16;
-      break;
-
-    case KEY_DOWN:
-      c = 14;
-      break;
-
-    case KEY_IC:
-      c = 24;
-      break;
-
-    case KEY_DC:
-      c = 4;
-      break;
-
-    case KEY_BACKSPACE:
-      /* XXX: For some reason ncurses on xterm does not return
-        KEY_BACKSPACE.  */
-    case 127:
-      c = 8;
-      break;
-
-    case KEY_HOME:
-      c = 1;
-      break;
-
-    case KEY_END:
-      c = 5;
-      break;
-
-    case KEY_NPAGE:
-      c = 3;
-      break;
-
-    case KEY_PPAGE:
-      c = 7;
-      break;
-    }
-
-  return c;
-}
-
-static grub_uint16_t
-grub_ncurses_getxy (void)
-{
-  int x;
-  int y;
-
-  getyx (stdscr, y, x);
-
-  return (x << 8) | y;
-}
-
-static grub_uint16_t
-grub_ncurses_getwh (void)
-{
-  int x;
-  int y;
-
-  getmaxyx (stdscr, y, x);
-
-  return (x << 8) | y;
-}
-
-static void
-grub_ncurses_gotoxy (grub_uint8_t x, grub_uint8_t y)
-{
-  move (y, x);
-}
-
-static void
-grub_ncurses_cls (void)
-{
-  clear ();
-  refresh ();
-}
-
-static void
-grub_ncurses_setcursor (int on)
-{
-  curs_set (on ? 1 : 0);
-}
-
-static void
-grub_ncurses_refresh (void)
-{
-  refresh ();
-}
-
-static grub_err_t
-grub_ncurses_init (void)
-{
-  initscr ();
-  raw ();
-  noecho ();
-  scrollok (stdscr, TRUE);
-
-  nonl ();
-  intrflush (stdscr, FALSE);
-  keypad (stdscr, TRUE);
-
-  if (has_colors ())
-    {
-      start_color ();
-
-      if ((COLORS >= NUM_COLORS) && (COLOR_PAIRS >= NUM_COLORS * NUM_COLORS))
-        {
-          int i, j, n;
-
-          n = 0;
-          for (i = 0; i < NUM_COLORS; i++)
-            for (j = 0; j < NUM_COLORS; j++)
-              init_pair(n++, color_map[j], color_map[i]);
-
-          use_color = 1;
-        }
-    }
-
-  return 0;
-}
-
-static grub_err_t
-grub_ncurses_fini (void)
-{
-  endwin ();
-  return 0;
-}
-
-\f
-static struct grub_term_input grub_ncurses_term_input =
-  {
-    .name = "console",
-    .checkkey = grub_ncurses_checkkey,
-    .getkey = grub_ncurses_getkey,
-  };
-
-static struct grub_term_output grub_ncurses_term_output =
-  {
-    .name = "console",
-    .init = grub_ncurses_init,
-    .fini = grub_ncurses_fini,
-    .putchar = grub_ncurses_putchar,
-    .getcharwidth = grub_ncurses_getcharwidth,
-    .getxy = grub_ncurses_getxy,
-    .getwh = grub_ncurses_getwh,
-    .gotoxy = grub_ncurses_gotoxy,
-    .cls = grub_ncurses_cls,
-    .setcolorstate = grub_ncurses_setcolorstate,
-    .setcolor = grub_ncurses_setcolor,
-    .getcolor = grub_ncurses_getcolor,
-    .setcursor = grub_ncurses_setcursor,
-    .refresh = grub_ncurses_refresh
-  };
-
-void
-grub_console_init (void)
-{
-  grub_term_register_output ("console", &grub_ncurses_term_output);
-  grub_term_register_input ("console", &grub_ncurses_term_input);
-}
-
-void
-grub_console_fini (void)
-{
-  grub_ncurses_fini ();
-}
index 04a19bc4ef5a4a315b372fd469a26b1c2085a9cb..fa9b202ebdfe8d4c6ead8b7812a2f5e55d2522b3 100644 (file)
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <grub/elf.h>
 #include <grub/misc.h>
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
 #include <grub/util/resolve.h>
 #include <grub/kernel.h>
diff --git a/util/getroot.c b/util/getroot.c
deleted file mode 100644 (file)
index 891bd0f..0000000
+++ /dev/null
@@ -1,543 +0,0 @@
-/* getroot.c - Get root device */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <dirent.h>
-
-#ifdef __CYGWIN__
-# include <sys/fcntl.h>
-# include <sys/cygwin.h>
-# include <limits.h>
-# define DEV_CYGDRIVE_MAJOR 98
-#endif
-
-#ifdef __GNU__
-#include <hurd.h>
-#include <hurd/lookup.h>
-#include <hurd/fs.h>
-#endif
-
-#include <grub/util/misc.h>
-#include <grub/util/hostdisk.h>
-#include <grub/util/getroot.h>
-
-static void
-strip_extra_slashes (char *dir)
-{
-  char *p = dir;
-
-  while ((p = strchr (p, '/')) != 0)
-    {
-      if (p[1] == '/')
-       {
-         memmove (p, p + 1, strlen (p));
-         continue;
-       }
-      else if (p[1] == '\0')
-       {
-         if (p > dir)
-           p[0] = '\0';
-         break;
-       }
-
-      p++;
-    }
-}
-
-static char *
-xgetcwd (void)
-{
-  size_t size = 10;
-  char *path;
-
-  path = xmalloc (size);
-  while (! getcwd (path, size))
-    {
-      size <<= 1;
-      path = xrealloc (path, size);
-    }
-
-  return path;
-}
-
-#ifdef __MINGW32__
-
-static char *
-find_root_device (const char *dir __attribute__ ((unused)),
-                  dev_t dev __attribute__ ((unused)))
-{
-  return 0;
-}
-
-#elif ! defined(__CYGWIN__)
-
-static char *
-find_root_device (const char *dir, dev_t dev)
-{
-  DIR *dp;
-  char *saved_cwd;
-  struct dirent *ent;
-
-  dp = opendir (dir);
-  if (! dp)
-    return 0;
-
-  saved_cwd = xgetcwd ();
-
-  grub_util_info ("changing current directory to %s", dir);
-  if (chdir (dir) < 0)
-    {
-      free (saved_cwd);
-      closedir (dp);
-      return 0;
-    }
-
-  while ((ent = readdir (dp)) != 0)
-    {
-      struct stat st;
-
-      /* Avoid:
-        - dotfiles (like "/dev/.tmp.md0") since they could be duplicates.
-        - dotdirs (like "/dev/.static") since they could contain duplicates.  */
-      if (ent->d_name[0] == '.')
-       continue;
-
-      if (lstat (ent->d_name, &st) < 0)
-       /* Ignore any error.  */
-       continue;
-
-      if (S_ISLNK (st.st_mode))
-       /* Don't follow symbolic links.  */
-       continue;
-
-      if (S_ISDIR (st.st_mode))
-       {
-         /* Find it recursively.  */
-         char *res;
-
-         res = find_root_device (ent->d_name, dev);
-
-         if (res)
-           {
-             if (chdir (saved_cwd) < 0)
-               grub_util_error ("cannot restore the original directory");
-
-             free (saved_cwd);
-             closedir (dp);
-             return res;
-           }
-       }
-
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
-      if (S_ISCHR (st.st_mode) && st.st_rdev == dev)
-#else
-      if (S_ISBLK (st.st_mode) && st.st_rdev == dev)
-#endif
-       {
-#ifdef __linux__
-         /* Skip device names like /dev/dm-0, which are short-hand aliases
-            to more descriptive device names, e.g. those under /dev/mapper */
-         if (ent->d_name[0] == 'd' &&
-             ent->d_name[1] == 'm' &&
-             ent->d_name[2] == '-' &&
-             ent->d_name[3] >= '0' &&
-             ent->d_name[3] <= '9')
-           continue;
-#endif
-
-         /* Found!  */
-         char *res;
-         char *cwd;
-#if defined(__NetBSD__)
-         /* Convert this block device to its character (raw) device.  */
-         const char *template = "%s/r%s";
-#else
-         /* Keep the device name as it is.  */
-         const char *template = "%s/%s";
-#endif
-
-         cwd = xgetcwd ();
-         res = xmalloc (strlen (cwd) + strlen (ent->d_name) + 3);
-         sprintf (res, template, cwd, ent->d_name);
-         strip_extra_slashes (res);
-         free (cwd);
-
-         /* /dev/root is not a real block device keep looking, takes care
-            of situation where root filesystem is on the same partition as
-            grub files */
-
-         if (strcmp(res, "/dev/root") == 0)
-               continue;
-
-         if (chdir (saved_cwd) < 0)
-           grub_util_error ("cannot restore the original directory");
-
-         free (saved_cwd);
-         closedir (dp);
-         return res;
-       }
-    }
-
-  if (chdir (saved_cwd) < 0)
-    grub_util_error ("cannot restore the original directory");
-
-  free (saved_cwd);
-  closedir (dp);
-  return 0;
-}
-
-#else /* __CYGWIN__ */
-
-/* Read drive/partition serial number from mbr/boot sector,
-   return 0 on read error, ~0 on unknown serial.  */
-static unsigned
-get_bootsec_serial (const char *os_dev, int mbr)
-{
-  /* Read boot sector.  */
-  int fd = open (os_dev, O_RDONLY);
-  if (fd < 0)
-    return 0;
-  unsigned char buf[0x200];
-  int n = read (fd, buf, sizeof (buf));
-  close (fd);
-  if (n != sizeof(buf))
-    return 0;
-
-  /* Check signature.  */
-  if (!(buf[0x1fe] == 0x55 && buf[0x1ff] == 0xaa))
-    return ~0;
-
-  /* Serial number offset depends on boot sector type.  */
-  if (mbr)
-    n = 0x1b8;
-  else if (memcmp (buf + 0x03, "NTFS", 4) == 0)
-    n = 0x048;
-  else if (memcmp (buf + 0x52, "FAT32", 5) == 0)
-    n = 0x043;
-  else if (memcmp (buf + 0x36, "FAT", 3) == 0)
-    n = 0x027;
-  else
-    return ~0;
-
-  unsigned serial = *(unsigned *)(buf + n);
-  if (serial == 0)
-    return ~0;
-  return serial;
-}
-
-static char *
-find_cygwin_root_device (const char *path, dev_t dev)
-{
-  /* No root device for /cygdrive.  */
-  if (dev == (DEV_CYGDRIVE_MAJOR << 16))
-    return 0;
-
-  /* Convert to full POSIX and Win32 path.  */
-  char fullpath[PATH_MAX], winpath[PATH_MAX];
-  cygwin_conv_to_full_posix_path (path, fullpath);
-  cygwin_conv_to_full_win32_path (fullpath, winpath);
-
-  /* If identical, this is no real filesystem path.  */
-  if (strcmp (fullpath, winpath) == 0)
-    return 0;
-
-  /* Check for floppy drive letter.  */
-  if (winpath[0] && winpath[1] == ':' && strchr ("AaBb", winpath[0]))
-    return xstrdup (strchr ("Aa", winpath[0]) ? "/dev/fd0" : "/dev/fd1");
-
-  /* Cygwin returns the partition serial number in stat.st_dev.
-     This is never identical to the device number of the emulated
-     /dev/sdXN device, so above find_root_device () does not work.
-     Search the partition with the same serial in boot sector instead.  */
-  char devpath[sizeof ("/dev/sda15") + 13]; /* Size + Paranoia.  */
-  int d;
-  for (d = 'a'; d <= 'z'; d++)
-    {
-      sprintf (devpath, "/dev/sd%c", d);
-      if (get_bootsec_serial (devpath, 1) == 0)
-       continue;
-      int p;
-      for (p = 1; p <= 15; p++)
-       {
-         sprintf (devpath, "/dev/sd%c%d", d, p);
-         unsigned ser = get_bootsec_serial (devpath, 0);
-         if (ser == 0)
-           break;
-         if (ser != (unsigned)~0 && dev == (dev_t)ser)
-           return xstrdup (devpath);
-       }
-    }
-  return 0;
-}
-
-#endif /* __CYGWIN__ */
-
-char *
-grub_guess_root_device (const char *dir)
-{
-  char *os_dev;
-#ifdef __GNU__
-  file_t file;
-  mach_port_t *ports;
-  int *ints;
-  loff_t *offsets;
-  char *data;
-  error_t err;
-  mach_msg_type_number_t num_ports = 0, num_ints = 0, num_offsets = 0, data_len = 0;
-  size_t name_len;
-
-  file = file_name_lookup (dir, 0, 0);
-  if (file == MACH_PORT_NULL)
-    return 0;
-
-  err = file_get_storage_info (file,
-                              &ports, &num_ports,
-                              &ints, &num_ints,
-                              &offsets, &num_offsets,
-                              &data, &data_len);
-
-  if (num_ints < 1)
-    grub_util_error ("Storage info for `%s' does not include type", dir);
-  if (ints[0] != STORAGE_DEVICE)
-    grub_util_error ("Filesystem of `%s' is not stored on local disk", dir);
-
-  if (num_ints < 5)
-    grub_util_error ("Storage info for `%s' does not include name", dir);
-  name_len = ints[4];
-  if (name_len < data_len)
-    grub_util_error ("Bogus name length for storage info for `%s'", dir);
-  if (data[name_len - 1] != '\0')
-    grub_util_error ("Storage name for `%s' not NUL-terminated", dir);
-
-  os_dev = xmalloc (strlen ("/dev/") + data_len);
-  memcpy (os_dev, "/dev/", strlen ("/dev/"));
-  memcpy (os_dev + strlen ("/dev/"), data, data_len);
-
-  if (ports && num_ports > 0)
-    {
-      mach_msg_type_number_t i;
-      for (i = 0; i < num_ports; i++)
-        {
-         mach_port_t port = ports[i];
-         if (port != MACH_PORT_NULL)
-           mach_port_deallocate (mach_task_self(), port);
-        }
-      munmap ((caddr_t) ports, num_ports * sizeof (*ports));
-    }
-
-  if (ints && num_ints > 0)
-    munmap ((caddr_t) ints, num_ints * sizeof (*ints));
-  if (offsets && num_offsets > 0)
-    munmap ((caddr_t) offsets, num_offsets * sizeof (*offsets));
-  if (data && data_len > 0)
-    munmap (data, data_len);
-  mach_port_deallocate (mach_task_self (), file);
-#else /* !__GNU__ */
-  struct stat st;
-
-  if (stat (dir, &st) < 0)
-    grub_util_error ("cannot stat `%s'", dir);
-
-#ifdef __CYGWIN__
-  /* Cygwin specific function.  */
-  os_dev = find_cygwin_root_device (dir, st.st_dev);
-
-#else
-
-  /* This might be truly slow, but is there any better way?  */
-  os_dev = find_root_device ("/dev", st.st_dev);
-#endif
-#endif /* !__GNU__ */
-
-  return os_dev;
-}
-
-static int
-grub_util_is_dmraid (const char *os_dev)
-{
-  if (! strncmp (os_dev, "/dev/mapper/nvidia_", 19))
-    return 1;
-  else if (! strncmp (os_dev, "/dev/mapper/isw_", 16))
-    return 1;
-  else if (! strncmp (os_dev, "/dev/mapper/hpt37x_", 19))
-    return 1;
-  else if (! strncmp (os_dev, "/dev/mapper/hpt45x_", 19))
-    return 1;
-  else if (! strncmp (os_dev, "/dev/mapper/via_", 16))
-    return 1;
-  else if (! strncmp (os_dev, "/dev/mapper/lsi_", 16))
-    return 1;
-  else if (! strncmp (os_dev, "/dev/mapper/pdc_", 16))
-    return 1;
-  else if (! strncmp (os_dev, "/dev/mapper/jmicron_", 20))
-    return 1;
-  else if (! strncmp (os_dev, "/dev/mapper/asr_", 16))
-    return 1;
-  else if (! strncmp (os_dev, "/dev/mapper/sil_", 16))
-    return 1;
-
-  return 0;
-}
-
-int
-grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused)))
-{
-#ifdef __linux__
-  /* Check for LVM.  */
-  if (!strncmp (os_dev, "/dev/mapper/", 12)
-      && ! grub_util_is_dmraid (os_dev)
-      && strncmp (os_dev, "/dev/mapper/mpath", 17) != 0)
-    return GRUB_DEV_ABSTRACTION_LVM;
-
-  /* Check for RAID.  */
-  if (!strncmp (os_dev, "/dev/md", 7))
-    return GRUB_DEV_ABSTRACTION_RAID;
-#endif
-
-  /* No abstraction found.  */
-  return GRUB_DEV_ABSTRACTION_NONE;
-}
-
-char *
-grub_util_get_grub_dev (const char *os_dev)
-{
-  char *grub_dev;
-
-  switch (grub_util_get_dev_abstraction (os_dev))
-    {
-    case GRUB_DEV_ABSTRACTION_LVM:
-
-      {
-       unsigned short i, len;
-       grub_size_t offset = sizeof ("/dev/mapper/") - 1;
-
-       len = strlen (os_dev) - offset + 1;
-       grub_dev = xmalloc (len);
-
-       for (i = 0; i < len; i++, offset++)
-         {
-           grub_dev[i] = os_dev[offset];
-           if (os_dev[offset] == '-' && os_dev[offset + 1] == '-')
-             offset++;
-         }
-      }
-
-      break;
-
-    case GRUB_DEV_ABSTRACTION_RAID:
-
-      if (os_dev[7] == '_' && os_dev[8] == 'd')
-       {
-         /* This a partitionable RAID device of the form /dev/md_dNNpMM. */
-
-         char *p, *q;
-
-         p = strdup (os_dev + sizeof ("/dev/md_d") - 1);
-
-         q = strchr (p, 'p');
-         if (q)
-           *q = ',';
-
-         grub_dev = xasprintf ("md%s", p);
-         free (p);
-       }
-      else if (os_dev[7] == '/' && os_dev[8] == 'd')
-       {
-         /* This a partitionable RAID device of the form /dev/md/dNNpMM. */
-
-         char *p, *q;
-
-         p = strdup (os_dev + sizeof ("/dev/md/d") - 1);
-
-         q = strchr (p, 'p');
-         if (q)
-           *q = ',';
-
-         grub_dev = xasprintf ("md%s", p);
-         free (p);
-       }
-      else if (os_dev[7] >= '0' && os_dev[7] <= '9')
-       {
-         char *p , *q;
-
-         p = strdup (os_dev + sizeof ("/dev/md") - 1);
-
-         q = strchr (p, 'p');
-         if (q)
-           *q = ',';
-
-         grub_dev = xasprintf ("md%s", p);
-         free (p);
-       }
-      else if (os_dev[7] == '/' && os_dev[8] >= '0' && os_dev[8] <= '9')
-       {
-         char *p , *q;
-
-         p = strdup (os_dev + sizeof ("/dev/md/") - 1);
-
-         q = strchr (p, 'p');
-         if (q)
-           *q = ',';
-
-         grub_dev = xasprintf ("md%s", p);
-         free (p);
-       }
-      else
-       grub_util_error ("unknown kind of RAID device `%s'", os_dev);
-
-      break;
-
-    default:  /* GRUB_DEV_ABSTRACTION_NONE */
-      grub_dev = grub_util_biosdisk_get_grub_dev (os_dev);
-    }
-
-  return grub_dev;
-}
-
-const char *
-grub_util_check_block_device (const char *blk_dev)
-{
-  struct stat st;
-
-  if (stat (blk_dev, &st) < 0)
-    grub_util_error ("cannot stat `%s'", blk_dev);
-
-  if (S_ISBLK (st.st_mode))
-    return (blk_dev);
-  else
-    return 0;
-}
-
-const char *
-grub_util_check_char_device (const char *blk_dev)
-{
-  struct stat st;
-
-  if (stat (blk_dev, &st) < 0)
-    grub_util_error ("cannot stat `%s'", blk_dev);
-
-  if (S_ISCHR (st.st_mode))
-    return (blk_dev);
-  else
-    return 0;
-}
-
index f21042c9772afdef5516003cbe3954f769eb42bb..24c36329c25efb10738db5e8f913911014205a6b 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <config.h>
 #include <grub/types.h>
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
 #include <grub/lib/envblk.h>
 #include <grub/handler.h>
 
 #define DEFAULT_ENVBLK_SIZE    1024
 
-void
-grub_putchar (int c)
-{
-  putchar (c);
-}
-
-void
-grub_refresh (void)
-{
-  fflush (stdout);
-}
-
-int
-grub_getkey (void)
-{
-  return 0;
-}
-
 char *
 grub_env_get (const char *name __attribute__ ((unused)))
 {
diff --git a/util/grub-emu.c b/util/grub-emu.c
deleted file mode 100644 (file)
index 8c53b0a..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <getopt.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <grub/mm.h>
-#include <grub/setjmp.h>
-#include <grub/fs.h>
-#include <grub/util/hostdisk.h>
-#include <grub/dl.h>
-#include <grub/util/console.h>
-#include <grub/util/misc.h>
-#include <grub/kernel.h>
-#include <grub/normal.h>
-#include <grub/util/getroot.h>
-#include <grub/env.h>
-#include <grub/partition.h>
-#include <grub/i18n.h>
-
-#define ENABLE_RELOCATABLE 0
-#include "progname.h"
-
-/* Used for going back to the main function.  */
-static jmp_buf main_env;
-
-/* Store the prefix specified by an argument.  */
-static char *prefix = NULL;
-
-grub_addr_t
-grub_arch_modules_addr (void)
-{
-  return 0;
-}
-
-#if GRUB_NO_MODULES
-grub_err_t
-grub_arch_dl_check_header (void *ehdr)
-{
-  (void) ehdr;
-
-  return GRUB_ERR_BAD_MODULE;
-}
-
-grub_err_t
-grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
-{
-  (void) mod;
-  (void) ehdr;
-
-  return GRUB_ERR_BAD_MODULE;
-}
-#endif
-
-void
-grub_reboot (void)
-{
-  longjmp (main_env, 1);
-}
-
-void
-grub_halt (
-#ifdef GRUB_MACHINE_PCBIOS
-          int no_apm __attribute__ ((unused))
-#endif
-          )
-{
-  grub_reboot ();
-}
-
-void
-grub_machine_init (void)
-{
-}
-
-void
-grub_machine_set_prefix (void)
-{
-  grub_env_set ("prefix", prefix);
-  free (prefix);
-  prefix = 0;
-}
-
-void
-grub_machine_fini (void)
-{
-  grub_console_fini ();
-}
-
-\f
-
-static struct option options[] =
-  {
-    {"root-device", required_argument, 0, 'r'},
-    {"device-map", required_argument, 0, 'm'},
-    {"directory", required_argument, 0, 'd'},
-    {"hold", optional_argument, 0, 'H'},
-    {"help", no_argument, 0, 'h'},
-    {"version", no_argument, 0, 'V'},
-    {"verbose", no_argument, 0, 'v'},
-    { 0, 0, 0, 0 }
-  };
-
-static int
-usage (int status)
-{
-  if (status)
-    fprintf (stderr,
-            "Try `%s --help' for more information.\n", program_name);
-  else
-    printf (
-      "Usage: %s [OPTION]...\n"
-      "\n"
-      "GRUB emulator.\n"
-      "\n"
-      "  -r, --root-device=DEV     use DEV as the root device [default=guessed]\n"
-      "  -m, --device-map=FILE     use FILE as the device map [default=%s]\n"
-      "  -d, --directory=DIR       use GRUB files in the directory DIR [default=%s]\n"
-      "  -v, --verbose             print verbose messages\n"
-      "  -H, --hold[=SECONDS]      wait until a debugger will attach\n"
-      "  -h, --help                display this message and exit\n"
-      "  -V, --version             print version information and exit\n"
-      "\n"
-      "Report bugs to <%s>.\n", program_name, DEFAULT_DEVICE_MAP, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT);
-  return status;
-}
-\f
-
-void grub_hostfs_init (void);
-void grub_hostfs_fini (void);
-void grub_host_init (void);
-void grub_host_fini (void);
-#if GRUB_NO_MODULES
-void grub_init_all (void);
-void grub_fini_all (void);
-#endif
-
-int
-main (int argc, char *argv[])
-{
-  char *root_dev = 0;
-  char *dir = DEFAULT_DIRECTORY;
-  char *dev_map = DEFAULT_DEVICE_MAP;
-  volatile int hold = 0;
-  int opt;
-
-  set_program_name (argv[0]);
-
-  while ((opt = getopt_long (argc, argv, "r:d:m:vH:hV", options, 0)) != -1)
-    switch (opt)
-      {
-      case 'r':
-        root_dev = optarg;
-        break;
-      case 'd':
-        dir = optarg;
-        break;
-      case 'm':
-        dev_map = optarg;
-        break;
-      case 'v':
-        verbosity++;
-        break;
-      case 'H':
-        hold = (optarg ? atoi (optarg) : -1);
-        break;
-      case 'h':
-        return usage (0);
-      case 'V':
-        printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
-        return 0;
-      default:
-        return usage (1);
-      }
-
-  if (optind < argc)
-    {
-      fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind]);
-      return usage (1);
-    }
-
-  /* Wait until the ARGS.HOLD variable is cleared by an attached debugger. */
-  if (hold && verbosity > 0)
-    printf ("Run \"gdb %s %d\", and set ARGS.HOLD to zero.\n",
-            program_name, (int) getpid ());
-  while (hold)
-    {
-      if (hold > 0)
-        hold--;
-
-      sleep (1);
-    }
-
-  signal (SIGINT, SIG_IGN);
-  grub_console_init ();
-  grub_host_init ();
-  grub_hostfs_init ();
-
-  /* XXX: This is a bit unportable.  */
-  grub_util_biosdisk_init (dev_map);
-
-#if GRUB_NO_MODULES
-  grub_init_all ();
-#endif
-
-  /* Make sure that there is a root device.  */
-  if (! root_dev)
-    {
-      char *device_name = grub_guess_root_device (dir);
-      if (! device_name)
-        grub_util_error ("cannot find a device for %s", dir);
-
-      root_dev = grub_util_get_grub_dev (device_name);
-      if (! root_dev)
-       {
-         grub_util_info ("guessing the root device failed, because of `%s'",
-                         grub_errmsg);
-         grub_util_error ("cannot guess the root device. Specify the option `--root-device'");
-       }
-    }
-
-  if (strcmp (root_dev, "host") == 0)
-    dir = xstrdup (dir);
-  else
-    dir = make_system_path_relative_to_its_root (dir);
-  prefix = xmalloc (strlen (root_dev) + 2 + strlen (dir) + 1);
-  sprintf (prefix, "(%s)%s", root_dev, dir);
-  free (dir);
-
-  /* Start GRUB!  */
-  if (setjmp (main_env) == 0)
-    grub_main ();
-
-#if GRUB_NO_MODULES
-  grub_fini_all ();
-#endif
-  grub_hostfs_fini ();
-  grub_host_fini ();
-
-  grub_machine_fini ();
-
-  return 0;
-}
index c03c43451c996e42aadc770531c807c8008bda6c..9ac5cf550d08db61342310475f37db4a71d4298c 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <config.h>
 #include <grub/types.h>
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
 #include <grub/misc.h>
 #include <grub/device.h>
@@ -33,8 +34,6 @@
 #include <grub/command.h>
 #include <grub/i18n.h>
 
-#include <grub_fstest_init.h>
-
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
 
 #include "progname.h"
 
-void
-grub_putchar (int c)
-{
-  putchar (c);
-}
-
-int
-grub_getkey (void)
-{
-  return -1;
-}
-
-struct grub_handler_class grub_term_input_class;
-struct grub_handler_class grub_term_output_class;
-
-void
-grub_refresh (void)
-{
-  fflush (stdout);
-}
-
 static grub_err_t
 execute_command (char *name, int n, char **args)
 {
index c68482af1d8ac4ef855705637084b3bbd1487103..d534ff9efcf1b2cb9e0332d5d8cd2a049b629d66 100644 (file)
@@ -29,6 +29,7 @@
 #include <fcntl.h>
 #include <limits.h>
 
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
 #include <grub/util/deviceiter.h>
 #include <grub/i18n.h>
index 51e2e494c22bbe6e4a426ac6b2e4f070346c2ad2..30dd96a2135f4bbbe00827562f084be52d2fab08 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <config.h>
 #include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
 #include <grub/i18n.h>
 #include <grub/fontformat.h>
index a00b1e99072f0566bab8b6c353c48a5974b3e7df..4a218bc82cc71ea7223df4e305ae12eb86a1a488 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <grub/types.h>
 #include <grub/crypto.h>
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
 #include <grub/i18n.h>
 
 
 #include "progname.h"
 
-/* Few functions to make crypto happy.  */
-void *
-grub_memmove (void *dest, const void *src, grub_size_t n)
-{
-  return memmove (dest, src, n);
-}
-
-void *
-grub_memset (void *s, int c, grub_size_t n)
-{
-  return memset (s, c, n);
-}
-
-int 
-grub_vprintf (const char *fmt, va_list args)
-{
-  return vprintf (fmt, args);
-}
-
-int 
-grub_vsnprintf (char *str, grub_size_t n, const char *fmt, va_list args)
-{
-  return vsnprintf (str, n, fmt, args);
-}
-
-void
-grub_abort (void)
-{
-  abort ();
-}
-
 static struct option options[] =
   {
     {"iteration_count", required_argument, 0, 'c'},
index 20a344d04e63916910fc04ce7df445e4e3898e0e..ff3b9df83d78d96ae9c3a9a3790edb19ae49fcf0 100644 (file)
@@ -27,6 +27,7 @@
 #include <grub/i18n.h>
 #include <grub/kernel.h>
 #include <grub/disk.h>
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
 #include <grub/util/resolve.h>
 #include <grub/misc.h>
index 327f0c866c22f4287d81e34cad53f3df0fe60f6a..4e9d0ed6362713312eba1009fde4710c8047dc16 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <grub/util/misc.h>
+#include <grub/emu/getroot.h>
 #include <grub/i18n.h>
 #include <getopt.h>
 
@@ -97,7 +98,7 @@ main (int argc, char *argv[])
 
   argument = argv[optind];
 
-  relpath = make_system_path_relative_to_its_root (argument);
+  relpath = grub_make_system_path_relative_to_its_root (argument);
   printf ("%s\n", relpath);
   free (relpath);
 
index 44e80b106fcd7794ca46e4e4c648413bb7c03ab3..2fdb58114843865950462aa290bbc4f37fe756b0 100644 (file)
@@ -1,7 +1,7 @@
 #! /bin/sh -e
 
 # Make GRUB rescue image
-# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
 #
 # GRUB is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -28,8 +28,11 @@ PACKAGE_TARNAME=@PACKAGE_TARNAME@
 PACKAGE_VERSION=@PACKAGE_VERSION@
 target_cpu=@target_cpu@
 native_platform=@platform@
-pkglib_DATA="@pkglib_DATA@"
+pkglib_DATA="moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst"
 
+mkimage=${bindir}/grub-mkimage
+mkisofs=${bindir}/grub-mkisofs
+mkelfimage=${bindir}/grub-mkelfimage
 multiboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-multiboot
 pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-pc
 
@@ -70,6 +73,8 @@ for option in "$@"; do
        PATH=${override_dir}:$PATH
        export PATH
        ;;
+    --root-directory=*)
+        rootdir=`echo "${option}/" | sed 's/--root-directory=//'` ;;
     -*)
        echo "Unrecognized option \`$option'" 1>&2
        usage
@@ -121,6 +126,14 @@ process_input_dir ()
     done
 }
 
+if [ "${rootdir}" != "" ] ; then
+    coreboot_dir="${rootdir}/${coreboot_dir}"
+    pc_dir="${rootdir}/${pc_dir}"
+    mkimage="${rootdir}/${mkimage}"
+    mkisofs="${rootdir}/${mkisofs}"
+    mkelfimage="${rootdir}/${mkelfimage}"
+fi
+
 if [ "${override_dir}" = "" ] ; then
     if test -e "${multiboot_dir}" ; then
         process_input_dir ${multiboot_dir} multiboot
@@ -160,7 +173,7 @@ EOF
 
     tar -C ${memdisk_dir} -cf ${memdisk_img} boot
     rm -rf ${memdisk_dir}
-    grub-mkelfimage -d ${multiboot_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \
+    ${mkelfimage} -d ${multiboot_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \
         memdisk tar search iso9660 configfile sh \
         ata at_keyboard
     rm -f ${memdisk_img}
@@ -171,7 +184,7 @@ fi
 if test -e "${pc_dir}" ; then
     echo "Enabling BIOS support ..."
     core_img=`mktemp "$MKTEMP_TEMPLATE"`
-    grub-mkimage -d ${pc_dir}/ -o ${core_img} --prefix=/boot/grub/i386-pc \
+    ${mkimage} -d ${pc_dir}/ -o ${core_img} --prefix=/boot/grub/i386-pc \
         iso9660 biosdisk
     cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img
 
@@ -192,7 +205,7 @@ if test -e "${pc_dir}" ; then
 fi
 
 # build iso image
-grub-mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source}
+${mkisofs} ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source}
 rm -rf ${iso9660_dir}
 
 rm -f ${embed_img}
index bb41480e2cbfe2d68b7cefa82e850457dd75fa6e..0cc35d4c59b82490d04206de0ece1a31c83a655a 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <config.h>
 #include <grub/types.h>
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
 #include <grub/device.h>
 #include <grub/disk.h>
 #include <grub/fs.h>
 #include <grub/partition.h>
 #include <grub/msdos_partition.h>
-#include <grub/util/hostdisk.h>
-#include <grub/util/getroot.h>
+#include <grub/emu/hostdisk.h>
+#include <grub/emu/getroot.h>
 #include <grub/term.h>
 #include <grub/env.h>
 #include <grub/raid.h>
 #include <grub/i18n.h>
 
-#include <grub_probe_init.h>
-
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
@@ -58,27 +57,6 @@ enum {
 int print = PRINT_FS;
 static unsigned int argument_is_device = 0;
 
-void
-grub_putchar (int c)
-{
-  putchar (c);
-}
-
-int
-grub_getkey (void)
-{
-  return -1;
-}
-
-struct grub_handler_class grub_term_input_class;
-struct grub_handler_class grub_term_output_class;
-
-void
-grub_refresh (void)
-{
-  fflush (stdout);
-}
-
 static void
 probe_partmap (grub_disk_t disk)
 {
@@ -261,7 +239,7 @@ probe (const char *path, char *device_name)
              grub_util_info ("reading %s via OS facilities", path);
              filebuf_via_sys = grub_util_read_image (path);
 
-             rel_path = make_system_path_relative_to_its_root (path);
+             rel_path = grub_make_system_path_relative_to_its_root (path);
              grub_path = xasprintf ("(%s)%s", drive_name, rel_path);
              free (rel_path);
              grub_util_info ("reading %s via GRUB facilities", grub_path);
index dc732aa017ab66598ed11991bd11a3746a0602dc..fa24593063fd91de6630559d2b31821da6dab675 100644 (file)
 #include <grub/types.h>
 #include <grub/mm.h>
 #include <grub/misc.h>
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
 #include <grub/i18n.h>
 #include <grub/parser.h>
 #include <grub/script_sh.h>
 
-#include <grub_script_check_init.h>
-
 #define _GNU_SOURCE    1
 
 #include <ctype.h>
 
 #include "progname.h"
 
-void
-grub_putchar (int c)
-{
-  putchar (c);
-}
-
-int
-grub_getkey (void)
-{
-  return -1;
-}
-
-void
-grub_refresh (void)
-{
-  fflush (stdout);
-}
-
-char *
-grub_script_execute_argument_to_string (struct grub_script_arg *arg __attribute__ ((unused)))
-{
-  return 0;
-}
-
-grub_err_t
-grub_script_execute_cmdline (struct grub_script_cmd *cmd __attribute__ ((unused)))
-{
-  return 0;
-}
-
-grub_err_t
-grub_script_execute_cmdblock (struct grub_script_cmd *cmd __attribute__ ((unused)))
-{
-  return 0;
-}
-
-grub_err_t
-grub_script_execute_cmdif (struct grub_script_cmd *cmd __attribute__ ((unused)))
-{
-  return 0;
-}
-
-grub_err_t
-grub_script_execute_cmdfor (struct grub_script_cmd *cmd __attribute__ ((unused)))
-{
-  return 0;
-}
-
-grub_err_t
-grub_script_execute_cmdwhile (struct grub_script_cmd *cmd __attribute__ ((unused)))
-{
-  return 0;
-}
-
-grub_err_t
-grub_script_execute_menuentry (struct grub_script_cmd *cmd __attribute__ ((unused)))
-{
-  return 0;
-}
-
-grub_err_t
-grub_script_execute (struct grub_script *script)
-{
-  if (script == 0 || script->cmd == 0)
-    return 0;
-
-  return script->cmd->exec (script->cmd);
-}
-
 static struct option options[] =
   {
     {"help", no_argument, 0, 'h'},
@@ -145,7 +75,7 @@ main (int argc, char *argv[])
   char *input;
   FILE *file = 0;
   int verbose = 0;
-  struct grub_script *script;
+  struct grub_script *script = 0;
 
   auto grub_err_t get_config_line (char **line, int cont);
   grub_err_t get_config_line (char **line, int cont __attribute__ ((unused)))
diff --git a/util/hostdisk.c b/util/hostdisk.c
deleted file mode 100644 (file)
index 8be4874..0000000
+++ /dev/null
@@ -1,1360 +0,0 @@
-/* hostdisk.c - emulate biosdisk */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/disk.h>
-#include <grub/partition.h>
-#include <grub/msdos_partition.h>
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/util/misc.h>
-#include <grub/util/hostdisk.h>
-#include <grub/misc.h>
-#include <grub/i18n.h>
-#include <grub/list.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <limits.h>
-
-#ifdef __linux__
-# include <sys/ioctl.h>         /* ioctl */
-# if !defined(__GLIBC__) || \
-        ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))
-/* Maybe libc doesn't have large file support.  */
-#  include <linux/unistd.h>     /* _llseek */
-# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */
-# ifndef BLKFLSBUF
-#  define BLKFLSBUF     _IO (0x12,97)   /* flush buffer cache */
-# endif /* ! BLKFLSBUF */
-# include <sys/ioctl.h>                /* ioctl */
-# ifndef HDIO_GETGEO
-#  define HDIO_GETGEO  0x0301  /* get device geometry */
-/* If HDIO_GETGEO is not defined, it is unlikely that hd_geometry is
-   defined.  */
-struct hd_geometry
-{
-  unsigned char heads;
-  unsigned char sectors;
-  unsigned short cylinders;
-  unsigned long start;
-};
-# endif /* ! HDIO_GETGEO */
-# ifndef BLKGETSIZE64
-#  define BLKGETSIZE64  _IOR(0x12,114,size_t)    /* return device size */
-# endif /* ! BLKGETSIZE64 */
-# ifndef MAJOR
-#  ifndef MINORBITS
-#   define MINORBITS   8
-#  endif /* ! MINORBITS */
-#  define MAJOR(dev)   ((unsigned) ((dev) >> MINORBITS))
-# endif /* ! MAJOR */
-# ifndef FLOPPY_MAJOR
-#  define FLOPPY_MAJOR 2
-# endif /* ! FLOPPY_MAJOR */
-# ifndef LOOP_MAJOR
-#  define LOOP_MAJOR   7
-# endif /* ! LOOP_MAJOR */
-#endif /* __linux__ */
-
-#ifdef __CYGWIN__
-# include <sys/ioctl.h>
-# include <cygwin/fs.h> /* BLKGETSIZE64 */
-# include <cygwin/hdreg.h> /* HDIO_GETGEO */
-# define MAJOR(dev)    ((unsigned) ((dev) >> 16))
-# define FLOPPY_MAJOR  2
-#endif
-
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-# include <sys/disk.h> /* DIOCGMEDIASIZE */
-# include <sys/param.h>
-# include <sys/sysctl.h>
-#endif
-
-#if defined(__APPLE__)
-# include <sys/disk.h>
-#endif
-
-#if defined(__NetBSD__)
-# include <sys/ioctl.h>
-# include <sys/disklabel.h>    /* struct disklabel */
-# ifdef HAVE_GETRAWPARTITION
-#  include <util.h>    /* getrawpartition */
-# endif /* HAVE_GETRAWPARTITION */
-# include <sys/fdio.h>
-# ifndef RAW_FLOPPY_MAJOR
-#  define RAW_FLOPPY_MAJOR     9
-# endif /* ! RAW_FLOPPY_MAJOR */
-#endif /* defined(__NetBSD__) */
-
-struct
-{
-  char *drive;
-  char *device;
-} map[256];
-
-struct grub_util_biosdisk_data
-{
-  char *dev;
-  int access_mode;
-  int fd;
-};
-
-#ifdef __linux__
-/* Check if we have devfs support.  */
-static int
-have_devfs (void)
-{
-  static int dev_devfsd_exists = -1;
-
-  if (dev_devfsd_exists < 0)
-    {
-      struct stat st;
-
-      dev_devfsd_exists = stat ("/dev/.devfsd", &st) == 0;
-    }
-
-  return dev_devfsd_exists;
-}
-#endif /* __linux__ */
-
-#if defined(__NetBSD__)
-/* Adjust device driver parameters.  This function should be called just
-   after successfully opening the device.  For now, it simply prevents the
-   floppy driver from retrying operations on failure, as otherwise the
-   driver takes a while to abort when there is no floppy in the drive.  */
-static void
-configure_device_driver (int fd)
-{
-  struct stat st;
-
-  if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode))
-    return;
-  if (major(st.st_rdev) == RAW_FLOPPY_MAJOR)
-    {
-      int floppy_opts;
-
-      if (ioctl (fd, FDIOCGETOPTS, &floppy_opts) == -1)
-       return;
-      floppy_opts |= FDOPT_NORETRY;
-      if (ioctl (fd, FDIOCSETOPTS, &floppy_opts) == -1)
-       return;
-    }
-}
-#endif /* defined(__NetBSD__) */
-
-static int
-find_grub_drive (const char *name)
-{
-  unsigned int i;
-
-  if (name)
-    {
-      for (i = 0; i < ARRAY_SIZE (map); i++)
-       if (map[i].drive && ! strcmp (map[i].drive, name))
-         return i;
-    }
-
-  return -1;
-}
-
-static int
-find_free_slot (void)
-{
-  unsigned int i;
-
-  for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
-    if (! map[i].drive)
-      return i;
-
-  return -1;
-}
-
-static int
-grub_util_biosdisk_iterate (int (*hook) (const char *name))
-{
-  unsigned i;
-
-  for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
-    if (map[i].drive && hook (map[i].drive))
-      return 1;
-
-  return 0;
-}
-
-static grub_err_t
-grub_util_biosdisk_open (const char *name, grub_disk_t disk)
-{
-  int drive;
-  struct stat st;
-  struct grub_util_biosdisk_data *data;
-
-  drive = find_grub_drive (name);
-  if (drive < 0)
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
-                      "no mapping exists for `%s'", name);
-
-  disk->has_partitions = 1;
-  disk->id = drive;
-  disk->data = data = xmalloc (sizeof (struct grub_util_biosdisk_data));
-  data->dev = NULL;
-  data->access_mode = 0;
-  data->fd = -1;
-
-  /* Get the size.  */
-#if defined(__MINGW32__)
-  {
-    grub_uint64_t size;
-
-    size = grub_util_get_disk_size (map[drive].device);
-
-    if (size % 512)
-      grub_util_error ("unaligned device size");
-
-    disk->total_sectors = size >> 9;
-
-    grub_util_info ("the size of %s is %llu", name, disk->total_sectors);
-
-    return GRUB_ERR_NONE;
-  }
-#elif defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \
-      defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__)
-  {
-# if defined(__NetBSD__)
-    struct disklabel label;
-# else
-    unsigned long long nr;
-# endif
-    int fd;
-
-    fd = open (map[drive].device, O_RDONLY);
-    if (fd == -1)
-      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot open `%s' while attempting to get disk size", map[drive].device);
-
-# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__)
-    if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode))
-# else
-    if (fstat (fd, &st) < 0 || ! S_ISBLK (st.st_mode))
-# endif
-      {
-       close (fd);
-       goto fail;
-      }
-
-# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-    if (ioctl (fd, DIOCGMEDIASIZE, &nr))
-# elif defined(__APPLE__)
-    if (ioctl (fd, DKIOCGETBLOCKCOUNT, &nr))
-# elif defined(__NetBSD__)
-    configure_device_driver (fd);
-    if (ioctl (fd, DIOCGDINFO, &label) == -1)
-# else
-    if (ioctl (fd, BLKGETSIZE64, &nr))
-# endif
-      {
-       close (fd);
-       goto fail;
-      }
-
-    close (fd);
-
-# if defined (__APPLE__)
-    disk->total_sectors = nr;
-# elif defined(__NetBSD__)
-    disk->total_sectors = label.d_secperunit;
-# else
-    disk->total_sectors = nr / 512;
-
-    if (nr % 512)
-      grub_util_error ("unaligned device size");
-# endif
-
-    grub_util_info ("the size of %s is %llu", name, disk->total_sectors);
-
-    return GRUB_ERR_NONE;
-  }
-
- fail:
-  /* In GNU/Hurd, stat() will return the right size.  */
-#elif !defined (__GNU__)
-# warning "No special routine to get the size of a block device is implemented for your OS. This is not possibly fatal."
-#endif
-  if (stat (map[drive].device, &st) < 0)
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot stat `%s'", map[drive].device);
-
-  disk->total_sectors = st.st_size >> GRUB_DISK_SECTOR_BITS;
-
-  grub_util_info ("the size of %s is %lu", name, disk->total_sectors);
-
-  return GRUB_ERR_NONE;
-}
-
-#ifdef __linux__
-/* Cache of partition start sectors for each disk.  */
-struct linux_partition_cache
-{
-  struct linux_partition_cache *next;
-  char *dev;
-  unsigned long start;
-  int partno;
-};
-
-struct linux_partition_cache *linux_partition_cache_list;
-
-static int
-linux_find_partition (char *dev, unsigned long sector)
-{
-  size_t len = strlen (dev);
-  const char *format;
-  char *p;
-  int i;
-  char real_dev[PATH_MAX];
-  struct linux_partition_cache *cache;
-
-  strcpy(real_dev, dev);
-
-  if (have_devfs () && strcmp (real_dev + len - 5, "/disc") == 0)
-    {
-      p = real_dev + len - 4;
-      format = "part%d";
-    }
-  else if (real_dev[len - 1] >= '0' && real_dev[len - 1] <= '9')
-    {
-      p = real_dev + len;
-      format = "p%d";
-    }
-  else
-    {
-      p = real_dev + len;
-      format = "%d";
-    }
-
-  for (cache = linux_partition_cache_list; cache; cache = cache->next)
-    {
-      if (strcmp (cache->dev, dev) == 0 && cache->start == sector)
-       {
-         sprintf (p, format, cache->partno);
-         strcpy (dev, real_dev);
-         return 1;
-       }
-    }
-
-  for (i = 1; i < 10000; i++)
-    {
-      int fd;
-      struct hd_geometry hdg;
-
-      sprintf (p, format, i);
-      fd = open (real_dev, O_RDONLY);
-      if (fd == -1)
-       return 0;
-
-      if (ioctl (fd, HDIO_GETGEO, &hdg))
-       {
-         close (fd);
-         return 0;
-       }
-
-      close (fd);
-
-      if (hdg.start == sector)
-       {
-         struct linux_partition_cache *new_cache_item;
-
-         new_cache_item = xmalloc (sizeof *new_cache_item);
-         new_cache_item->dev = xstrdup (dev);
-         new_cache_item->start = hdg.start;
-         new_cache_item->partno = i;
-         grub_list_push (GRUB_AS_LIST_P (&linux_partition_cache_list),
-                         GRUB_AS_LIST (new_cache_item));
-
-         strcpy (dev, real_dev);
-         return 1;
-       }
-    }
-
-  return 0;
-}
-#endif /* __linux__ */
-
-static int
-open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags)
-{
-  int fd;
-  struct grub_util_biosdisk_data *data = disk->data;
-
-#ifdef O_LARGEFILE
-  flags |= O_LARGEFILE;
-#endif
-#ifdef O_SYNC
-  flags |= O_SYNC;
-#endif
-#ifdef O_FSYNC
-  flags |= O_FSYNC;
-#endif
-#ifdef O_BINARY
-  flags |= O_BINARY;
-#endif
-
-#ifdef __linux__
-  /* Linux has a bug that the disk cache for a whole disk is not consistent
-     with the one for a partition of the disk.  */
-  {
-    int is_partition = 0;
-    char dev[PATH_MAX];
-    grub_disk_addr_t part_start = 0;
-
-    part_start = grub_partition_get_start (disk->partition);
-
-    strcpy (dev, map[disk->id].device);
-    if (disk->partition && sector >= part_start
-       && strncmp (map[disk->id].device, "/dev/", 5) == 0)
-      is_partition = linux_find_partition (dev, part_start);
-
-    if (data->dev && strcmp (data->dev, dev) == 0 &&
-       data->access_mode == (flags & O_ACCMODE))
-      {
-       grub_dprintf ("hostdisk", "reusing open device `%s'\n", dev);
-       fd = data->fd;
-      }
-    else
-      {
-       free (data->dev);
-       if (data->fd != -1)
-         close (data->fd);
-
-       /* Open the partition.  */
-       grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev);
-       fd = open (dev, flags);
-       if (fd < 0)
-         {
-           grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s'", dev);
-           return -1;
-         }
-
-       /* Flush the buffer cache to the physical disk.
-          XXX: This also empties the buffer cache.  */
-       ioctl (fd, BLKFLSBUF, 0);
-
-       data->dev = xstrdup (dev);
-       data->access_mode = (flags & O_ACCMODE);
-       data->fd = fd;
-      }
-
-    if (is_partition)
-      sector -= part_start;
-  }
-#else /* ! __linux__ */
-#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
-  int sysctl_flags, sysctl_oldflags;
-  size_t sysctl_size = sizeof (sysctl_flags);
-
-  if (sysctlbyname ("kern.geom.debugflags", &sysctl_oldflags, &sysctl_size, NULL, 0))
-    {
-      grub_error (GRUB_ERR_BAD_DEVICE, "cannot get current flags of sysctl kern.geom.debugflags");
-      return -1;
-    }
-  sysctl_flags = sysctl_oldflags | 0x10;
-  if (! (sysctl_oldflags & 0x10)
-      && sysctlbyname ("kern.geom.debugflags", NULL , 0, &sysctl_flags, sysctl_size))
-    {
-      grub_error (GRUB_ERR_BAD_DEVICE, "cannot set flags of sysctl kern.geom.debugflags");
-      return -1;
-    }
-#endif
-
-  if (data->dev && strcmp (data->dev, map[disk->id].device) == 0 &&
-      data->access_mode == (flags & O_ACCMODE))
-    {
-      grub_dprintf ("hostdisk", "reusing open device `%s'\n", data->dev);
-      fd = data->fd;
-    }
-  else
-    {
-      free (data->dev);
-      if (data->fd != -1)
-       close (data->fd);
-
-      fd = open (map[disk->id].device, flags);
-      if (fd >= 0)
-       {
-         data->dev = xstrdup (map[disk->id].device);
-         data->access_mode = (flags & O_ACCMODE);
-         data->fd = fd;
-       }
-    }
-
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-  if (! (sysctl_oldflags & 0x10)
-      && sysctlbyname ("kern.geom.debugflags", NULL , 0, &sysctl_oldflags, sysctl_size))
-    {
-      grub_error (GRUB_ERR_BAD_DEVICE, "cannot set flags back to the old value for sysctl kern.geom.debugflags");
-      return -1;
-    }
-#endif
-
-#if defined(__APPLE__)
-  /* If we can't have exclusive access, try shared access */
-  if (fd < 0)
-    fd = open(map[disk->id].device, flags | O_SHLOCK);
-#endif
-
-  if (fd < 0)
-    {
-      grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' in open_device()", map[disk->id].device);
-      return -1;
-    }
-#endif /* ! __linux__ */
-
-#if defined(__NetBSD__)
-  configure_device_driver (fd);
-#endif /* defined(__NetBSD__) */
-
-#if defined(__linux__) && (!defined(__GLIBC__) || \
-        ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
-  /* Maybe libc doesn't have large file support.  */
-  {
-    loff_t offset, result;
-    static int _llseek (uint filedes, ulong hi, ulong lo,
-                        loff_t *res, uint wh);
-    _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
-               loff_t *, res, uint, wh);
-
-    offset = (loff_t) sector << GRUB_DISK_SECTOR_BITS;
-    if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
-      {
-       grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id].device);
-       close (fd);
-       return -1;
-      }
-  }
-#else
-  {
-    off_t offset = (off_t) sector << GRUB_DISK_SECTOR_BITS;
-
-    if (lseek (fd, offset, SEEK_SET) != offset)
-      {
-       grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id].device);
-       close (fd);
-       return -1;
-      }
-  }
-#endif
-
-  return fd;
-}
-
-/* Read LEN bytes from FD in BUF. Return less than or equal to zero if an
-   error occurs, otherwise return LEN.  */
-static ssize_t
-nread (int fd, char *buf, size_t len)
-{
-  ssize_t size = len;
-
-  while (len)
-    {
-      ssize_t ret = read (fd, buf, len);
-
-      if (ret <= 0)
-        {
-          if (errno == EINTR)
-            continue;
-          else
-            return ret;
-        }
-
-      len -= ret;
-      buf += ret;
-    }
-
-  return size;
-}
-
-/* Write LEN bytes from BUF to FD. Return less than or equal to zero if an
-   error occurs, otherwise return LEN.  */
-static ssize_t
-nwrite (int fd, const char *buf, size_t len)
-{
-  ssize_t size = len;
-
-  while (len)
-    {
-      ssize_t ret = write (fd, buf, len);
-
-      if (ret <= 0)
-        {
-          if (errno == EINTR)
-            continue;
-          else
-            return ret;
-        }
-
-      len -= ret;
-      buf += ret;
-    }
-
-  return size;
-}
-
-static grub_err_t
-grub_util_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
-                        grub_size_t size, char *buf)
-{
-  int fd;
-
-  /* Split pre-partition and partition reads.  */
-  if (disk->partition && sector < disk->partition->start
-      && sector + size > disk->partition->start)
-    {
-      grub_err_t err;
-      err = grub_util_biosdisk_read (disk, sector,
-                                    disk->partition->start - sector,
-                                    buf);
-      if (err)
-       return err;
-
-      return grub_util_biosdisk_read (disk, disk->partition->start,
-                                     size - (disk->partition->start - sector),
-                                     buf + ((disk->partition->start - sector)
-                                            << GRUB_DISK_SECTOR_BITS));
-    }
-
-  fd = open_device (disk, sector, O_RDONLY);
-  if (fd < 0)
-    return grub_errno;
-
-#ifdef __linux__
-  if (sector == 0 && size > 1)
-    {
-      /* Work around a bug in Linux ez remapping.  Linux remaps all
-        sectors that are read together with the MBR in one read.  It
-        should only remap the MBR, so we split the read in two
-        parts. -jochen  */
-      if (nread (fd, buf, GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE)
-       {
-         grub_error (GRUB_ERR_READ_ERROR, "cannot read `%s'", map[disk->id].device);
-         close (fd);
-         return grub_errno;
-       }
-
-      buf += GRUB_DISK_SECTOR_SIZE;
-      size--;
-    }
-#endif /* __linux__ */
-
-  if (nread (fd, buf, size << GRUB_DISK_SECTOR_BITS)
-      != (ssize_t) (size << GRUB_DISK_SECTOR_BITS))
-    grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", map[disk->id].device);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_util_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
-                         grub_size_t size, const char *buf)
-{
-  int fd;
-
-  /* Split pre-partition and partition writes.  */
-  if (disk->partition && sector < disk->partition->start
-      && sector + size > disk->partition->start)
-    {
-      grub_err_t err;
-      err = grub_util_biosdisk_write (disk, sector,
-                                     disk->partition->start - sector,
-                                     buf);
-      if (err)
-       return err;
-
-      return grub_util_biosdisk_write (disk, disk->partition->start,
-                                      size - (disk->partition->start - sector),
-                                      buf + ((disk->partition->start - sector)
-                                             << GRUB_DISK_SECTOR_BITS));
-    }
-
-  fd = open_device (disk, sector, O_WRONLY);
-  if (fd < 0)
-    return grub_errno;
-
-  if (nwrite (fd, buf, size << GRUB_DISK_SECTOR_BITS)
-      != (ssize_t) (size << GRUB_DISK_SECTOR_BITS))
-    grub_error (GRUB_ERR_WRITE_ERROR, "cannot write to `%s'", map[disk->id].device);
-
-  return grub_errno;
-}
-
-static void
-grub_util_biosdisk_close (struct grub_disk *disk)
-{
-  struct grub_util_biosdisk_data *data = disk->data;
-
-  free (data->dev);
-  if (data->fd != -1)
-    close (data->fd);
-  free (data);
-}
-
-static struct grub_disk_dev grub_util_biosdisk_dev =
-  {
-    .name = "biosdisk",
-    .id = GRUB_DISK_DEVICE_BIOSDISK_ID,
-    .iterate = grub_util_biosdisk_iterate,
-    .open = grub_util_biosdisk_open,
-    .close = grub_util_biosdisk_close,
-    .read = grub_util_biosdisk_read,
-    .write = grub_util_biosdisk_write,
-    .next = 0
-  };
-
-static void
-read_device_map (const char *dev_map)
-{
-  FILE *fp;
-  char buf[1024];      /* XXX */
-  int lineno = 0;
-  struct stat st;
-
-  auto void show_error (const char *msg);
-  void show_error (const char *msg)
-    {
-      grub_util_error ("%s:%d: %s", dev_map, lineno, msg);
-    }
-
-  fp = fopen (dev_map, "r");
-  if (! fp)
-    {
-      grub_util_info (_("cannot open `%s'"), dev_map);
-      return;
-    }
-
-  while (fgets (buf, sizeof (buf), fp))
-    {
-      char *p = buf;
-      char *e;
-      int drive;
-
-      lineno++;
-
-      /* Skip leading spaces.  */
-      while (*p && isspace (*p))
-       p++;
-
-      /* If the first character is `#' or NUL, skip this line.  */
-      if (*p == '\0' || *p == '#')
-       continue;
-
-      if (*p != '(')
-       show_error ("No open parenthesis found");
-
-      p++;
-      /* Find a free slot.  */
-      drive = find_free_slot ();
-      if (drive < 0)
-       show_error ("Map table size exceeded");
-
-      e = p;
-      p = strchr (p, ')');
-      if (! p)
-       show_error ("No close parenthesis found");
-
-      map[drive].drive = xmalloc (p - e + sizeof ('\0'));
-      strncpy (map[drive].drive, e, p - e + sizeof ('\0'));
-      map[drive].drive[p - e] = '\0';
-
-      p++;
-      /* Skip leading spaces.  */
-      while (*p && isspace (*p))
-       p++;
-
-      if (*p == '\0')
-       show_error ("No filename found");
-
-      /* NUL-terminate the filename.  */
-      e = p;
-      while (*e && ! isspace (*e))
-       e++;
-      *e = '\0';
-
-#ifdef __MINGW32__
-      (void) st;
-      if (grub_util_get_disk_size (p) == -1LL)
-#else
-      if (stat (p, &st) == -1)
-#endif
-       {
-         free (map[drive].drive);
-         map[drive].drive = NULL;
-         grub_util_info ("Cannot stat `%s', skipping", p);
-         continue;
-       }
-
-#ifdef __linux__
-      /* On Linux, the devfs uses symbolic links horribly, and that
-        confuses the interface very much, so use realpath to expand
-        symbolic links.  */
-      map[drive].device = xmalloc (PATH_MAX);
-      if (! realpath (p, map[drive].device))
-       grub_util_error ("cannot get the real path of `%s'", p);
-#else
-      map[drive].device = xstrdup (p);
-#endif
-    }
-
-  fclose (fp);
-}
-
-void
-grub_util_biosdisk_init (const char *dev_map)
-{
-  read_device_map (dev_map);
-  grub_disk_dev_register (&grub_util_biosdisk_dev);
-}
-
-void
-grub_util_biosdisk_fini (void)
-{
-  unsigned i;
-
-  for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
-    {
-      if (map[i].drive)
-       free (map[i].drive);
-      if (map[i].device)
-       free (map[i].device);
-      map[i].drive = map[i].device = NULL;
-    }
-
-  grub_disk_dev_unregister (&grub_util_biosdisk_dev);
-}
-
-static char *
-make_device_name (int drive, int dos_part, int bsd_part)
-{
-  char *ret;
-  char *dos_part_str = NULL;
-  char *bsd_part_str = NULL;
-
-  if (dos_part >= 0)
-    dos_part_str = xasprintf (",%d", dos_part + 1);
-
-  if (bsd_part >= 0)
-    bsd_part_str = xasprintf (",%d", bsd_part + 1);
-
-  ret = xasprintf ("%s%s%s", map[drive].drive,
-                   dos_part_str ? : "",
-                   bsd_part_str ? : "");
-
-  if (dos_part_str)
-    free (dos_part_str);
-
-  if (bsd_part_str)
-    free (bsd_part_str);
-
-  return ret;
-}
-
-static char *
-convert_system_partition_to_system_disk (const char *os_dev)
-{
-#if defined(__linux__)
-  char *path = xmalloc (PATH_MAX);
-  if (! realpath (os_dev, path))
-    return NULL;
-
-  if (strncmp ("/dev/", path, 5) == 0)
-    {
-      char *p = path + 5;
-
-      /* If this is an IDE disk.  */
-      if (strncmp ("ide/", p, 4) == 0)
-       {
-         p = strstr (p, "part");
-         if (p)
-           strcpy (p, "disc");
-
-         return path;
-       }
-
-      /* If this is a SCSI disk.  */
-      if (strncmp ("scsi/", p, 5) == 0)
-       {
-         p = strstr (p, "part");
-         if (p)
-           strcpy (p, "disc");
-
-         return path;
-       }
-
-      /* If this is a DAC960 disk.  */
-      if (strncmp ("rd/c", p, 4) == 0)
-       {
-         /* /dev/rd/c[0-9]+d[0-9]+(p[0-9]+)? */
-         p = strchr (p, 'p');
-         if (p)
-           *p = '\0';
-
-         return path;
-       }
-
-      /* If this is a Mylex AcceleRAID Array.  */
-      if (strncmp ("rs/c", p, 4) == 0)
-       {
-         /* /dev/rd/c[0-9]+d[0-9]+(p[0-9]+)? */
-         p = strchr (p, 'p');
-         if (p)
-           *p = '\0';
-
-         return path;
-       }
-      /* If this is a CCISS disk.  */
-      if (strncmp ("cciss/c", p, sizeof ("cciss/c") - 1) == 0)
-       {
-         /* /dev/cciss/c[0-9]+d[0-9]+(p[0-9]+)? */
-         p = strchr (p, 'p');
-         if (p)
-           *p = '\0';
-
-         return path;
-       }
-
-      /* If this is a Compaq Intelligent Drive Array.  */
-      if (strncmp ("ida/c", p, sizeof ("ida/c") - 1) == 0)
-       {
-         /* /dev/ida/c[0-9]+d[0-9]+(p[0-9]+)? */
-         p = strchr (p, 'p');
-         if (p)
-           *p = '\0';
-
-         return path;
-       }
-
-      /* If this is an I2O disk.  */
-      if (strncmp ("i2o/hd", p, sizeof ("i2o/hd") - 1) == 0)
-       {
-         /* /dev/i2o/hd[a-z]([0-9]+)? */
-         p[sizeof ("i2o/hda") - 1] = '\0';
-         return path;
-       }
-
-      /* If this is a MultiMediaCard (MMC).  */
-      if (strncmp ("mmcblk", p, sizeof ("mmcblk") - 1) == 0)
-       {
-         /* /dev/mmcblk[0-9]+(p[0-9]+)? */
-         p = strchr (p, 'p');
-         if (p)
-           *p = '\0';
-
-         return path;
-       }
-
-      /* If this is an IDE, SCSI or Virtio disk.  */
-      if (strncmp ("vdisk", p, 5) == 0
-         && p[5] >= 'a' && p[5] <= 'z')
-       {
-         /* /dev/vdisk[a-z][0-9]* */
-         p[6] = '\0';
-         return path;
-       }
-      if ((strncmp ("hd", p, 2) == 0
-          || strncmp ("vd", p, 2) == 0
-          || strncmp ("sd", p, 2) == 0)
-         && p[2] >= 'a' && p[2] <= 'z')
-       {
-         /* /dev/[hsv]d[a-z][0-9]* */
-         p[3] = '\0';
-         return path;
-       }
-
-      /* If this is a Xen virtual block device.  */
-      if ((strncmp ("xvd", p, 3) == 0) && p[3] >= 'a' && p[3] <= 'z')
-       {
-         /* /dev/xvd[a-z][0-9]* */
-         p[4] = '\0';
-         return path;
-       }
-    }
-
-  return path;
-
-#elif defined(__GNU__)
-  char *path = xstrdup (os_dev);
-  if (strncmp ("/dev/sd", path, 7) == 0 || strncmp ("/dev/hd", path, 7) == 0)
-    {
-      char *p = strchr (path + 7, 's');
-      if (p)
-       *p = '\0';
-    }
-  return path;
-
-#elif defined(__CYGWIN__)
-  char *path = xstrdup (os_dev);
-  if (strncmp ("/dev/sd", path, 7) == 0 && 'a' <= path[7] && path[7] <= 'z')
-    path[8] = 0;
-  return path;
-
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
-  char *path = xstrdup (os_dev);
-  if (strncmp ("/dev/", path, 5) == 0)
-    {
-      char *p;
-      for (p = path + 5; *p; ++p)
-        if (grub_isdigit(*p))
-          {
-            p = strchr (p, 's');
-            if (p)
-              *p = '\0';
-            break;
-          }
-    }
-  return path;
-
-#elif defined(__NetBSD__)
-  /* NetBSD uses "/dev/r[wsc]d[0-9]+[a-z]".  */
-  char *path = xstrdup (os_dev);
-  if (strncmp ("/dev/rwd", path, 8) == 0 ||
-      strncmp ("/dev/rsd", path, 8) == 0 ||
-      strncmp ("/dev/rcd", path, 8) == 0)
-    {
-      char *q;
-      q = path + strlen(path) - 1;    /* last character */
-      if (grub_isalpha(*q) && grub_isdigit(*(q-1)))
-        {
-          int rawpart = -1;
-# ifdef HAVE_GETRAWPARTITION
-          rawpart = getrawpartition();
-# endif /* HAVE_GETRAWPARTITION */
-          if (rawpart >= 0)
-            *q = 'a' + rawpart;
-        }
-    }
-  return path;
-
-#else
-# warning "The function `convert_system_partition_to_system_disk' might not work on your OS correctly."
-  return xstrdup (os_dev);
-#endif
-}
-
-#if defined(__linux__) || defined(__CYGWIN__)
-static int
-device_is_wholedisk (const char *os_dev)
-{
-  int len = strlen (os_dev);
-
-  if (os_dev[len - 1] < '0' || os_dev[len - 1] > '9')
-    return 1;
-  return 0;
-}
-#endif
-
-#if defined(__NetBSD__)
-/* Try to determine whether a given device name corresponds to a whole disk.
-   This function should give in most cases a definite answer, but it may
-   actually give an approximate one in the following sense: if the return
-   value is 0 then the device name does not correspond to a whole disk.  */
-static int
-device_is_wholedisk (const char *os_dev)
-{
-  int len = strlen (os_dev);
-  int rawpart = -1;
-
-# ifdef HAVE_GETRAWPARTITION
-  rawpart = getrawpartition();
-# endif /* HAVE_GETRAWPARTITION */
-  if (rawpart < 0)
-    return 1;
-  return (os_dev[len - 1] == ('a' + rawpart));
-}
-#endif /* defined(__NetBSD__) */
-
-static int
-find_system_device (const char *os_dev)
-{
-  unsigned int i;
-  char *os_disk;
-
-  os_disk = convert_system_partition_to_system_disk (os_dev);
-  if (! os_disk)
-    return -1;
-
-  for (i = 0; i < ARRAY_SIZE (map); i++)
-    if (! map[i].device)
-      break;
-    else if (strcmp (map[i].device, os_disk) == 0)
-      {
-       free (os_disk);
-       return i;
-      }
-
-  if (i == ARRAY_SIZE (map))
-    grub_util_error (_("device count exceeds limit"));
-
-  map[i].device = os_disk;
-  map[i].drive = xstrdup (os_disk);
-
-  return i;
-}
-
-char *
-grub_util_biosdisk_get_grub_dev (const char *os_dev)
-{
-  struct stat st;
-  int drive;
-
-  if (stat (os_dev, &st) < 0)
-    {
-      grub_error (GRUB_ERR_BAD_DEVICE, "cannot stat `%s'", os_dev);
-      return 0;
-    }
-
-  drive = find_system_device (os_dev);
-  if (drive < 0)
-    {
-      grub_error (GRUB_ERR_UNKNOWN_DEVICE,
-                 "no mapping exists for `%s'", os_dev);
-      return 0;
-    }
-
-  if (grub_strcmp (os_dev, convert_system_partition_to_system_disk (os_dev))
-      == 0)
-    return make_device_name (drive, -1, -1);
-
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__)
-  if (! S_ISCHR (st.st_mode))
-#else
-  if (! S_ISBLK (st.st_mode))
-#endif
-    return make_device_name (drive, -1, -1);
-
-#if defined(__linux__) || defined(__CYGWIN__) || defined(__NetBSD__)
-  /* Linux counts partitions uniformly, whether a BSD partition or a DOS
-     partition, so mapping them to GRUB devices is not trivial.
-     Here, get the start sector of a partition by HDIO_GETGEO, and
-     compare it with each partition GRUB recognizes.
-
-     Cygwin /dev/sdXN emulation uses Windows partition mapping. It
-     does not count the extended partition and missing primary
-     partitions.  Use same method as on Linux here.
-
-     For NetBSD, proceed as for Linux, except that the start sector is
-     obtained from the disk label.  */
-  {
-    char *name;
-    grub_disk_t disk;
-    int fd;
-# if !defined(__NetBSD__)
-    struct hd_geometry hdg;
-    typeof (hdg.start) p_offset;
-# else /* defined(__NetBSD__) */
-    struct disklabel label;
-    int index;
-    u_int32_t p_offset;
-# endif /* !defined(__NetBSD__) */
-    int dos_part = -1;
-    int bsd_part = -1;
-    auto int find_partition (grub_disk_t dsk,
-                            const grub_partition_t partition);
-
-    int find_partition (grub_disk_t dsk __attribute__ ((unused)),
-                       const grub_partition_t partition)
-      {
-       grub_disk_addr_t part_start = 0;
-       grub_util_info ("Partition %d starts from %lu",
-                       partition->number, partition->start);
-
-       part_start = grub_partition_get_start (partition);
-
-       if (p_offset == part_start)
-         {
-           if (partition->parent)
-             {
-               dos_part = partition->parent->number;
-               bsd_part = partition->number;
-             }
-           else
-             {
-               dos_part = partition->number;
-               bsd_part = -1;
-             }
-
-           return 1;
-         }
-
-       return 0;
-      }
-
-    name = make_device_name (drive, -1, -1);
-
-# if !defined(__NetBSD__)
-    if (MAJOR (st.st_rdev) == FLOPPY_MAJOR)
-      return name;
-# else /* defined(__NetBSD__) */
-    /* Since os_dev and convert_system_partition_to_system_disk (os_dev) are
-     * different, we know that os_dev is of the form /dev/r[wsc]d[0-9]+[a-z]
-     * and in particular it cannot be a floppy device.  */
-    index = os_dev[strlen(os_dev) - 1] - 'a';
-# endif /* !defined(__NetBSD__) */
-
-    fd = open (os_dev, O_RDONLY);
-    if (fd == -1)
-      {
-       grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", os_dev);
-       free (name);
-       return 0;
-      }
-
-# if !defined(__NetBSD__)
-    if (ioctl (fd, HDIO_GETGEO, &hdg))
-# else /* defined(__NetBSD__) */
-    configure_device_driver (fd);
-    if (ioctl (fd, DIOCGDINFO, &label) == -1)
-# endif /* !defined(__NetBSD__) */
-      {
-       grub_error (GRUB_ERR_BAD_DEVICE,
-                   "cannot get disk geometry of `%s'", os_dev);
-       close (fd);
-       free (name);
-       return 0;
-      }
-
-    close (fd);
-
-# if !defined(__NetBSD__)
-    p_offset = hdg.start;
-# else /* defined(__NetBSD__) */
-    if (index >= label.d_npartitions)
-      {
-       grub_error (GRUB_ERR_BAD_DEVICE,
-                   "no disk label entry for `%s'", os_dev);
-       free (name);
-       return 0;
-      }
-    p_offset = label.d_partitions[index].p_offset;
-# endif /* !defined(__NetBSD__) */
-
-    grub_util_info ("%s starts from %lu", os_dev, p_offset);
-
-    if (p_offset == 0 && device_is_wholedisk (os_dev))
-      return name;
-
-    grub_util_info ("opening the device %s", name);
-    disk = grub_disk_open (name);
-    free (name);
-
-    if (! disk)
-      return 0;
-
-    grub_partition_iterate (disk, find_partition);
-    if (grub_errno != GRUB_ERR_NONE)
-      {
-       grub_disk_close (disk);
-       return 0;
-      }
-
-    if (dos_part < 0)
-      {
-       grub_disk_close (disk);
-       grub_error (GRUB_ERR_BAD_DEVICE,
-                   "cannot find the partition of `%s'", os_dev);
-       return 0;
-      }
-
-    return make_device_name (drive, dos_part, bsd_part);
-  }
-
-#elif defined(__GNU__)
-  /* GNU uses "/dev/[hs]d[0-9]+(s[0-9]+[a-z]?)?".  */
-  {
-    char *p;
-    int dos_part = -1;
-    int bsd_part = -1;
-
-    p = strrchr (os_dev, 's');
-    if (p)
-      {
-       long int n;
-       char *q;
-
-       p++;
-       n = strtol (p, &q, 10);
-       if (p != q && n != GRUB_LONG_MIN && n != GRUB_LONG_MAX)
-         {
-           dos_part = (int) n - 1;
-
-           if (*q >= 'a' && *q <= 'g')
-             bsd_part = *q - 'a';
-         }
-      }
-
-    return make_device_name (drive, dos_part, bsd_part);
-  }
-
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
-  /* FreeBSD uses "/dev/[a-z]+[0-9]+(s[0-9]+[a-z]?)?".  */
-  {
-    int dos_part = -1;
-    int bsd_part = -1;
-
-    if (strncmp ("/dev/", os_dev, 5) == 0)
-      {
-        const char *p;
-        char *q;
-        long int n;
-
-        for (p = os_dev + 5; *p; ++p)
-          if (grub_isdigit(*p))
-            {
-              p = strchr (p, 's');
-              if (p)
-                {
-                  p++;
-                  n = strtol (p, &q, 10);
-                  if (p != q && n != GRUB_LONG_MIN && n != GRUB_LONG_MAX)
-                    {
-                      dos_part = (int) n - 1;
-
-                      if (*q >= 'a' && *q <= 'g')
-                        bsd_part = *q - 'a';
-                    }
-                }
-              break;
-            }
-      }
-
-    return make_device_name (drive, dos_part, bsd_part);
-  }
-
-#else
-# warning "The function `grub_util_biosdisk_get_grub_dev' might not work on your OS correctly."
-  return make_device_name (drive, -1, -1);
-#endif
-}
-
-const char *
-grub_util_biosdisk_get_osdev (grub_disk_t disk)
-{
-  return map[disk->id].device;
-}
diff --git a/util/hostfs.c b/util/hostfs.c
deleted file mode 100644 (file)
index 501ad46..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/* hostfs.c - Dummy filesystem to provide access to the hosts filesystem  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-#define _BSD_SOURCE
-#include <grub/fs.h>
-#include <grub/file.h>
-#include <grub/disk.h>
-#include <grub/misc.h>
-#include <grub/dl.h>
-#include <grub/util/misc.h>
-
-#include <dirent.h>
-#include <stdio.h>
-#include <errno.h>
-
-
-/* dirent.d_type is a BSD extension, not part of POSIX */
-#include <sys/stat.h>
-#include <string.h>
-
-static int
-is_dir (const char *path, const char *name)
-{
-  int len1 = strlen(path);
-  int len2 = strlen(name);
-
-  char pathname[len1 + 1 + len2 + 1 + 13];
-  strcpy (pathname, path);
-
-  /* Avoid UNC-path "//name" on Cygwin.  */
-  if (len1 > 0 && pathname[len1 - 1] != '/')
-    strcat (pathname, "/");
-
-  strcat (pathname, name);
-
-  struct stat st;
-  if (stat (pathname, &st))
-    return 0;
-  return S_ISDIR (st.st_mode);
-}
-
-static grub_err_t
-grub_hostfs_dir (grub_device_t device, const char *path,
-                int (*hook) (const char *filename,
-                             const struct grub_dirhook_info *info))
-{
-  DIR *dir;
-
-  /* Check if the disk is our dummy disk.  */
-  if (grub_strcmp (device->disk->name, "host"))
-    return grub_error (GRUB_ERR_BAD_FS, "not a hostfs");
-
-  dir = opendir (path);
-  if (! dir)
-    return grub_error (GRUB_ERR_BAD_FILENAME,
-                      "can't open the hostfs directory `%s'", path);
-
-  while (1)
-    {
-      struct dirent *de;
-      struct grub_dirhook_info info;
-      grub_memset (&info, 0, sizeof (info));
-
-      de = readdir (dir);
-      if (! de)
-       break;
-
-      info.dir = !! is_dir (path, de->d_name);
-      hook (de->d_name, &info);
-
-    }
-
-  closedir (dir);
-
-  return GRUB_ERR_NONE;
-}
-
-/* Open a file named NAME and initialize FILE.  */
-static grub_err_t
-grub_hostfs_open (struct grub_file *file, const char *name)
-{
-  FILE *f;
-
-  f = fopen (name, "rb");
-  if (! f)
-    return grub_error (GRUB_ERR_BAD_FILENAME,
-                      "can't open `%s'", name);
-  file->data = f;
-
-#ifdef __MINGW32__
-  file->size = grub_util_get_disk_size (name);
-#else
-  fseeko (f, 0, SEEK_END);
-  file->size = ftello (f);
-  fseeko (f, 0, SEEK_SET);
-#endif
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_ssize_t
-grub_hostfs_read (grub_file_t file, char *buf, grub_size_t len)
-{
-  FILE *f;
-
-  f = (FILE *) file->data;
-  if (fseeko (f, file->offset, SEEK_SET) != 0)
-    {
-      grub_error (GRUB_ERR_OUT_OF_RANGE, "fseeko: %s", strerror (errno));
-      return -1;
-    }
-
-  unsigned int s = fread (buf, 1, len, f);
-  if (s != len)
-    grub_error (GRUB_ERR_FILE_READ_ERROR, "fread: %s", strerror (errno));
-
-  return (signed) s;
-}
-
-static grub_err_t
-grub_hostfs_close (grub_file_t file)
-{
-  FILE *f;
-
-  f = (FILE *) file->data;
-  fclose (f);
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_hostfs_label (grub_device_t device __attribute ((unused)),
-                  char **label __attribute ((unused)))
-{
-  *label = 0;
-  return GRUB_ERR_NONE;
-}
-
-static struct grub_fs grub_hostfs_fs =
-  {
-    .name = "hostfs",
-    .dir = grub_hostfs_dir,
-    .open = grub_hostfs_open,
-    .read = grub_hostfs_read,
-    .close = grub_hostfs_close,
-    .label = grub_hostfs_label,
-    .next = 0
-  };
-
-\f
-
-GRUB_MOD_INIT(hostfs)
-{
-  grub_fs_register (&grub_hostfs_fs);
-}
-
-GRUB_MOD_FINI(hostfs)
-{
-  grub_fs_unregister (&grub_hostfs_fs);
-}
index f8c0f152e1ee63dbc38d467261deb30bccf963dc..57fba9168f00c553d79bfa5dd666c1a5350e8a17 100644 (file)
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <time.h>
 #include <grub/elf.h>
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
 #include <grub/util/resolve.h>
 #include <grub/kernel.h>
index 63fa8c3289d11022339ea6d553a31a2ce5382843..66d45620c88c4eb94cd2e743587af8902ab19d61 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <config.h>
 #include <grub/types.h>
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
 #include <grub/device.h>
 #include <grub/disk.h>
 #include <grub/msdos_partition.h>
 #include <grub/gpt_partition.h>
 #include <grub/env.h>
-#include <grub/util/hostdisk.h>
+#include <grub/emu/hostdisk.h>
 #include <grub/machine/boot.h>
 #include <grub/machine/kernel.h>
 #include <grub/term.h>
 #include <grub/i18n.h>
 #include <grub/util/raid.h>
 #include <grub/util/lvm.h>
-#include <grub/util/getroot.h>
+#include <grub/emu/getroot.h>
 
 static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT;
 
-#include <grub_setup_init.h>
-
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
@@ -57,27 +56,6 @@ static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_P
 #define DEFAULT_BOOT_FILE      "boot.img"
 #define DEFAULT_CORE_FILE      "core.img"
 
-void
-grub_putchar (int c)
-{
-  putchar (c);
-}
-
-int
-grub_getkey (void)
-{
-  return -1;
-}
-
-struct grub_handler_class grub_term_input_class;
-struct grub_handler_class grub_term_output_class;
-
-void
-grub_refresh (void)
-{
-  fflush (stdout);
-}
-
 static void
 setup (const char *dir,
        const char *boot_file, const char *core_file,
@@ -423,7 +401,7 @@ unable_to_embed:
   /* Make sure that GRUB reads the identical image as the OS.  */
   tmp_img = xmalloc (core_size);
   core_path_dev_full = grub_util_get_path (dir, core_file);
-  core_path_dev = make_system_path_relative_to_its_root (core_path_dev_full);
+  core_path_dev = grub_make_system_path_relative_to_its_root (core_path_dev_full);
   free (core_path_dev_full);
 
   /* It is a Good Thing to sync two times.  */
diff --git a/util/import_gcry.py b/util/import_gcry.py
deleted file mode 100644 (file)
index b9c3edc..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-#*
-#*  GRUB  --  GRand Unified Bootloader
-#*  Copyright (C) 2009  Free Software Foundation, Inc.
-#*
-#*  GRUB is free software: you can redistribute it and/or modify
-#*  it under the terms of the GNU General Public License as published by
-#*  the Free Software Foundation, either version 3 of the License, or
-#*  (at your option) any later version.
-#*
-#*  GRUB is distributed in the hope that it will be useful,
-#*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#*  GNU General Public License for more details.
-#*
-#*  You should have received a copy of the GNU General Public License
-#*  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
-#*
-
-import re
-import sys
-import os
-import datetime
-
-if len (sys.argv) < 3:
-    print ("Usage: %s SOURCE DESTINATION" % sys.argv[0])
-    exit (0)
-indir = sys.argv[1]
-outdir = sys.argv[2]
-
-basedir = os.path.join (outdir, "lib/libgcrypt-grub")
-try:
-    os.makedirs (basedir)
-except:
-    print ("WARNING: %s already exists" % basedir)
-cipher_dir_in = os.path.join (indir, "cipher")
-cipher_dir_out = os.path.join (basedir, "cipher")
-try:
-    os.makedirs (cipher_dir_out)
-except:
-    print ("WARNING: %s already exists" % cipher_dir_out)
-
-cipher_files = os.listdir (cipher_dir_in)
-conf = open (os.path.join (outdir, "conf", "gcry.rmk"), "w")
-conf.write ("# -*- makefile -*-\n\n")
-chlog = ""
-
-# Strictly speaking CRC32/CRC24 work on bytes so this value should be 1
-# But libgcrypt uses 64. Let's keep the value for compatibility. Since
-# noone uses CRC24/CRC32 for HMAC this is no problem
-mdblocksizes = {"_gcry_digest_spec_crc32" : 64,
-                "_gcry_digest_spec_crc32_rfc1510" : 64,
-                "_gcry_digest_spec_crc24_rfc2440" : 64,
-                "_gcry_digest_spec_md4" : 64,
-                "_gcry_digest_spec_md5" : 64,
-                "_gcry_digest_spec_rmd160" : 64,
-                "_gcry_digest_spec_sha1" : 64,
-                "_gcry_digest_spec_sha224" : 64,
-                "_gcry_digest_spec_sha256" : 64,
-                "_gcry_digest_spec_sha384" : 128,
-                "_gcry_digest_spec_sha512" : 128,
-                "_gcry_digest_spec_tiger" : 64,
-                "_gcry_digest_spec_whirlpool" : 64}
-
-cryptolist = open (os.path.join (cipher_dir_out, "crypto.lst"), "w")
-conf.write ("MAINTAINER_CLEANFILES += $(srcdir)/conf/gcry.rmk $(srcdir)/lib/libgcrypt-grub/cipher/ChangeLog $(srcdir)/lib/libgcrypt-grub/cipher/cipher.h $(srcdir)/lib/libgcrypt-grub/cipher/crypto.lst $(srcdir)/lib/libgcrypt-grub/cipher/g10lib.h $(srcdir)/lib/libgcrypt-grub/cipher/memory.h $(srcdir)/lib/libgcrypt-grub/cipher/types.h\n");
-
-# rijndael is the only cipher using aliases. So no need for mangling, just
-# hardcode it
-cryptolist.write ("RIJNDAEL: gcry_rijndael\n");
-cryptolist.write ("RIJNDAEL192: gcry_rijndael\n");
-cryptolist.write ("RIJNDAEL256: gcry_rijndael\n");
-cryptolist.write ("AES128: gcry_rijndael\n");
-cryptolist.write ("AES-128: gcry_rijndael\n");
-cryptolist.write ("AES-192: gcry_rijndael\n");
-cryptolist.write ("AES-256: gcry_rijndael\n");
-
-for cipher_file in cipher_files:
-    infile = os.path.join (cipher_dir_in, cipher_file)
-    outfile = os.path.join (cipher_dir_out, cipher_file)
-    if cipher_file == "ChangeLog":
-        continue
-    chlognew = "       * %s" % cipher_file
-    if re.match ("(Manifest|Makefile\.am|ac\.c|cipher\.c|hash-common\.c|hmac-tests\.c|md\.c|pubkey\.c)$", cipher_file):
-        chlog = "%s%s: Removed\n" % (chlog, chlognew)
-        continue
-    # Autogenerated files. Not even worth mentionning in ChangeLog
-    if re.match ("Makefile\.in$", cipher_file):
-        continue
-    nch = False
-    if re.match (".*\.[ch]$", cipher_file):
-        conf.write ("MAINTAINER_CLEANFILES += $(srcdir)/lib/libgcrypt-grub/cipher/" + cipher_file + "\n");
-        isc = re.match (".*\.c$", cipher_file)
-        f = open (infile, "r")
-        fw = open (outfile, "w")
-        fw.write ("/* This file was automatically imported with \n")
-        fw.write ("   import_gcry.py. Please don't modify it */\n");
-        ciphernames = []
-        mdnames = []
-        hold = False
-        skip = False
-        skip2 = False
-        ismd = False
-        iscryptostart = False
-        iscomma = False
-        isglue = False
-        skip_statement = False
-        if isc:
-            modname = cipher_file [0:len(cipher_file) - 2]
-            if re.match (".*-glue$", modname):
-                modname = modname.replace ("-glue", "")
-                isglue = True
-            modname = "gcry_%s" % modname
-        for line in f:
-            if skip_statement:
-                if not re.search (";", line) is None:
-                    skip_statement = False
-                continue
-            if skip:
-                if line[0] == "}":
-                    skip = False
-                continue
-            if skip2:
-                if not re.search (" *};", line) is None:
-                    skip2 = False
-                continue
-            if iscryptostart:
-                s = re.search (" *\"([A-Z0-9_a-z]*)\"", line)
-                if not s is None:
-                    sg = s.groups()[0]
-                    cryptolist.write (("%s: %s\n") % (sg, modname))
-                    iscryptostart = False
-            if ismd:
-                if not re.search (" *};", line) is None:
-                    if not mdblocksizes.has_key (mdname):
-                        print ("ERROR: Unknown digest blocksize: %s\n" % mdname)
-                        exit (1)
-                    if not iscomma:
-                        fw.write ("    ,\n")
-                    fw.write ("    .blocksize = %s\n" % mdblocksizes [mdname])
-                    ismd = False
-                iscomma = not re.search (",$", line) is None
-            # Used only for selftests.
-            m = re.match ("(static byte|static unsigned char) (weak_keys_chksum)\[[0-9]*\] =", line)
-            if not m is None:
-                skip = True
-                fname = m.groups ()[1]
-                chmsg = "(%s): Removed." % fname
-                if nch:
-                    chlognew = "%s\n   %s" % (chlognew, chmsg)
-                else:
-                    chlognew = "%s %s" % (chlognew, chmsg)
-                    nch = True
-                continue
-            if hold:
-                hold = False
-                # We're optimising for size.
-                if not re.match ("(run_selftests|selftest|_gcry_aes_c.._..c|_gcry_[a-z0-9]*_hash_buffer|tripledes_set2keys|do_tripledes_set_extra_info)", line) is None:
-                    skip = True
-                    fname = re.match ("[a-zA-Z0-9_]*", line).group ()
-                    chmsg = "(%s): Removed." % fname
-                    if nch:
-                        chlognew = "%s\n       %s" % (chlognew, chmsg)
-                    else:
-                        chlognew = "%s %s" % (chlognew, chmsg)
-                        nch = True
-                    continue
-                else:
-                    fw.write (holdline)
-            m = re.match ("#include <.*>", line)
-            if not m is None:
-                chmsg = "Removed including of %s" % \
-                m.group () [len ("#include <"):len (m.group ()) - 1]
-                if nch:
-                    chlognew = "%s\n   %s" % (chlognew, chmsg)
-                else:
-                    chlognew = "%s: %s" % (chlognew, chmsg)
-                    nch = True
-                continue
-            m = re.match ("gcry_cipher_spec_t", line)
-            if isc and not m is None:
-                assert (not iscryptostart)
-                ciphername = line [len ("gcry_cipher_spec_t"):].strip ()
-                ciphername = re.match("[a-zA-Z0-9_]*",ciphername).group ()
-                ciphernames.append (ciphername)
-                iscryptostart = True
-            m = re.match ("gcry_md_spec_t", line)
-            if isc and not m is None:
-                assert (not ismd)
-                assert (not iscryptostart)
-                mdname = line [len ("gcry_md_spec_t"):].strip ()
-                mdname = re.match("[a-zA-Z0-9_]*",mdname).group ()
-                mdnames.append (mdname)
-                ismd = True
-                iscryptostart = True
-            m = re.match ("static const char \*selftest.*;$", line)
-            if not m is None:
-                fname = line[len ("static const char \*"):]
-                fname = re.match ("[a-zA-Z0-9_]*", fname).group ()
-                chmsg = "(%s): Removed declaration." % fname
-                if nch:
-                    chlognew = "%s\n   %s" % (chlognew, chmsg)
-                else:
-                    chlognew = "%s %s" % (chlognew, chmsg)
-                    nch = True
-                continue
-            m = re.match ("(static const char( |)\*|static gpg_err_code_t|void|static int|static gcry_err_code_t)$", line)
-            if not m is None:
-                hold = True
-                holdline = line
-                continue
-            m = re.match ("static int tripledes_set2keys \(.*\);", line)
-            if not m is None:
-                continue
-            m = re.match ("static int tripledes_set2keys \(", line)
-            if not m is None:
-                skip_statement = True
-                continue
-            m = re.match ("cipher_extra_spec_t", line)
-            if isc and not m is None:
-                skip2 = True
-                fname = line[len ("cipher_extra_spec_t "):]
-                fname = re.match ("[a-zA-Z0-9_]*", fname).group ()
-                chmsg = "(%s): Removed." % fname
-                if nch:
-                    chlognew = "%s\n   %s" % (chlognew, chmsg)
-                else:
-                    chlognew = "%s %s" % (chlognew, chmsg)
-                    nch = True
-                continue
-            m = re.match ("md_extra_spec_t", line)
-            if isc and not m is None:
-                skip2 = True
-                fname = line[len ("md_extra_spec_t "):]
-                fname = re.match ("[a-zA-Z0-9_]*", fname).group ()
-                chmsg = "(%s): Removed." % fname
-                if nch:
-                    chlognew = "%s\n   %s" % (chlognew, chmsg)
-                else:
-                    chlognew = "%s %s" % (chlognew, chmsg)
-                    nch = True
-                continue
-            fw.write (line)
-        if len (ciphernames) > 0 or len (mdnames) > 0:
-            if isglue:
-                modfiles = "lib/libgcrypt-grub/cipher/%s lib/libgcrypt-grub/cipher/%s" \
-                    % (cipher_file, cipher_file.replace ("-glue.c", ".c"))
-            else:
-                modfiles = "lib/libgcrypt-grub/cipher/%s" % cipher_file
-            chmsg = "(GRUB_MOD_INIT(%s)): New function\n" % modname
-            if nch:
-                chlognew = "%s\n       %s" % (chlognew, chmsg)
-            else:
-                chlognew = "%s%s" % (chlognew, chmsg)
-                nch = True
-            fw.write ("\n\nGRUB_MOD_INIT(%s)\n" % modname)
-            fw.write ("{\n")
-            for ciphername in ciphernames:
-                chmsg = "Register cipher %s" % ciphername
-                chlognew = "%s\n       %s" % (chlognew, chmsg)
-                fw.write ("  grub_cipher_register (&%s);\n" % ciphername)
-            for mdname in mdnames:
-                chmsg = "Register digest %s" % mdname
-                chlognew = "%s\n       %s" % (chlognew, chmsg)
-                fw.write ("  grub_md_register (&%s);\n" % mdname)
-            fw.write ("}")
-            chmsg = "(GRUB_MOD_FINI(%s)): New function\n" % modname
-            chlognew = "%s\n   %s" % (chlognew, chmsg)
-            fw.write ("\n\nGRUB_MOD_FINI(%s)\n" % modname)
-            fw.write ("{\n")
-            for ciphername in ciphernames:
-                chmsg = "Unregister cipher %s" % ciphername
-                chlognew = "%s\n       %s" % (chlognew, chmsg)
-                fw.write ("  grub_cipher_unregister (&%s);\n" % ciphername)
-            for mdname in mdnames:
-                chmsg = "Unregister MD %s" % mdname
-                chlognew = "%s\n       %s" % (chlognew, chmsg)
-                fw.write ("  grub_md_unregister (&%s);\n" % mdname)
-            fw.write ("}\n")
-            conf.write ("pkglib_MODULES += %s.mod\n" % modname)
-            conf.write ("%s_mod_SOURCES = %s\n" %\
-                            (modname, modfiles))
-            conf.write ("%s_mod_CFLAGS = $(COMMON_CFLAGS) -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap\n" % modname)
-            conf.write ("%s_mod_LDFLAGS = $(COMMON_LDFLAGS)\n\n" % modname)
-        elif isc and cipher_file != "camellia.c":
-            print ("WARNING: C file isn't a module: %s" % cipher_file)
-        f.close ()
-        fw.close ()
-        if nch:
-            chlog = "%s%s\n" % (chlog, chlognew)
-        continue
-    chlog = "%s%sSkipped unknown file\n" % (chlog, chlognew)
-    print ("WARNING: unknown file %s" % cipher_file)
-
-cryptolist.close ()
-chlog = "%s    * crypto.lst: New file.\n" % chlog
-
-outfile = os.path.join (cipher_dir_out, "types.h")
-fw=open (outfile, "w")
-fw.write ("#include <grub/types.h>\n")
-fw.write ("#include <cipher_wrap.h>\n")
-chlog = "%s    * types.h: New file.\n" % chlog
-fw.close ()
-
-outfile = os.path.join (cipher_dir_out, "memory.h")
-fw=open (outfile, "w")
-fw.write ("#include <cipher_wrap.h>\n")
-chlog = "%s    * memory.h: New file.\n" % chlog
-fw.close ()
-
-
-outfile = os.path.join (cipher_dir_out, "cipher.h")
-fw=open (outfile, "w")
-fw.write ("#include <grub/crypto.h>\n")
-fw.write ("#include <cipher_wrap.h>\n")
-chlog = "%s    * cipher.h: Likewise.\n" % chlog
-fw.close ()
-
-outfile = os.path.join (cipher_dir_out, "g10lib.h")
-fw=open (outfile, "w")
-fw.write ("#include <cipher_wrap.h>\n")
-chlog = "%s    * g10lib.h: Likewise.\n" % chlog
-fw.close ()
-
-infile = os.path.join (cipher_dir_in, "ChangeLog")
-outfile = os.path.join (cipher_dir_out, "ChangeLog")
-
-
-f=open (infile, "r")
-fw=open (outfile, "w")
-dt = datetime.date.today ()
-fw.write ("%04d-%02d-%02d  Automatic import tool\n" % \
-          (dt.year,dt.month, dt.day))
-fw.write ("\n")
-fw.write ("    Imported ciphers to GRUB\n")
-fw.write ("\n")
-fw.write (chlog)
-fw.write ("\n")
-for line in f:
-    fw.write (line)
-f.close ()
-fw.close ()
index 0a091634475affe7e629451e8765e00a9b5150db..bb2c19fe31de401db25063fef19e606e568fcfbf 100644 (file)
@@ -19,7 +19,7 @@
 
 /* We only support LVM on Linux.  */
 #ifdef __linux__
-
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
 #include <grub/util/lvm.h>
 
index f9d860d9adf28d5743fb65821d4e607df11893c4..a7d5550926657189ccdee076b642020dde9af5c4 100644 (file)
 #include <grub/dl.h>
 #include <grub/misc.h>
 #include <grub/cache.h>
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
 #include <grub/mm.h>
 #include <grub/term.h>
 #include <grub/time.h>
 #include <grub/i18n.h>
+#include <grub/script_sh.h>
 
 #define ENABLE_RELOCATABLE 0
 #include "progname.h"
 #include <winioctl.h>
 #endif
 
-int verbosity = 0;
-
-void
-grub_util_warn (const char *fmt, ...)
-{
-  va_list ap;
-
-  fprintf (stderr, _("%s: warn:"), program_name);
-  fprintf (stderr, " ");
-  va_start (ap, fmt);
-  vfprintf (stderr, fmt, ap);
-  va_end (ap);
-  fprintf (stderr, ".\n");
-  fflush (stderr);
-}
-
-void
-grub_util_info (const char *fmt, ...)
-{
-  if (verbosity > 0)
-    {
-      va_list ap;
-
-      fprintf (stderr, _("%s: info:"), program_name);
-      fprintf (stderr, " ");
-      va_start (ap, fmt);
-      vfprintf (stderr, fmt, ap);
-      va_end (ap);
-      fprintf (stderr, ".\n");
-      fflush (stderr);
-    }
-}
-
-void
-grub_util_error (const char *fmt, ...)
-{
-  va_list ap;
-
-  fprintf (stderr, _("%s: error:"), program_name);
-  fprintf (stderr, " ");
-  va_start (ap, fmt);
-  vfprintf (stderr, fmt, ap);
-  va_end (ap);
-  fprintf (stderr, ".\n");
-  exit (1);
-}
-
 #ifdef GRUB_UTIL
 int
 grub_err_printf (const char *fmt, ...)
@@ -125,41 +80,6 @@ grub_err_printf (const char *fmt, ...)
 }
 #endif
 
-void *
-xmalloc (size_t size)
-{
-  void *p;
-
-  p = malloc (size);
-  if (! p)
-    grub_util_error ("out of memory");
-
-  return p;
-}
-
-void *
-xrealloc (void *ptr, size_t size)
-{
-  ptr = realloc (ptr, size);
-  if (! ptr)
-    grub_util_error ("out of memory");
-
-  return ptr;
-}
-
-char *
-xstrdup (const char *str)
-{
-  size_t len;
-  char *newstr;
-
-  len = strlen (str);
-  newstr = (char *) xmalloc (len + 1);
-  memcpy (newstr, str, len + 1);
-
-  return newstr;
-}
-
 char *
 grub_util_get_path (const char *dir, const char *file)
 {
@@ -268,89 +188,102 @@ grub_util_write_image (const char *img, size_t size, FILE *out)
     grub_util_error ("write failed");
 }
 
-/* Some functions that we don't use.  */
-void
-grub_mm_init_region (void *addr __attribute__ ((unused)),
-                    grub_size_t size __attribute__ ((unused)))
+char *
+grub_script_execute_argument_to_string (struct grub_script_arg *arg __attribute__ ((unused)))
 {
+  return 0;
 }
 
-#if GRUB_NO_MODULES
-void
-grub_register_exported_symbols (void)
+grub_err_t
+grub_script_execute_cmdline (struct grub_script_cmd *cmd __attribute__ ((unused)))
 {
+  return 0;
 }
-#endif
 
-void
-grub_exit (void)
+grub_err_t
+grub_script_execute_cmdblock (struct grub_script_cmd *cmd __attribute__ ((unused)))
 {
-  exit (1);
+  return 0;
 }
 
-grub_uint32_t
-grub_get_rtc (void)
+grub_err_t
+grub_script_execute_cmdif (struct grub_script_cmd *cmd __attribute__ ((unused)))
 {
-  struct timeval tv;
+  return 0;
+}
 
-  gettimeofday (&tv, 0);
+grub_err_t
+grub_script_execute_cmdfor (struct grub_script_cmd *cmd __attribute__ ((unused)))
+{
+  return 0;
+}
 
-  return (tv.tv_sec * GRUB_TICKS_PER_SECOND
-         + (((tv.tv_sec % GRUB_TICKS_PER_SECOND) * 1000000 + tv.tv_usec)
-            * GRUB_TICKS_PER_SECOND / 1000000));
+grub_err_t
+grub_script_execute_cmdwhile (struct grub_script_cmd *cmd __attribute__ ((unused)))
+{
+  return 0;
 }
 
-grub_uint64_t
-grub_get_time_ms (void)
+grub_err_t
+grub_script_execute_menuentry (struct grub_script_cmd *cmd __attribute__ ((unused)))
 {
-  struct timeval tv;
+  return 0;
+}
 
-  gettimeofday (&tv, 0);
+grub_err_t
+grub_script_execute (struct grub_script *script)
+{
+  if (script == 0 || script->cmd == 0)
+    return 0;
 
-  return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
+  return script->cmd->exec (script->cmd);
 }
 
-#ifdef __MINGW32__
-
 void
-grub_millisleep (grub_uint32_t ms)
+grub_putchar (int c)
 {
-  Sleep (ms);
+  putchar (c);
 }
 
-#else
-
-void
-grub_millisleep (grub_uint32_t ms)
+int
+grub_getkey (void)
 {
-  struct timespec ts;
-
-  ts.tv_sec = ms / 1000;
-  ts.tv_nsec = (ms % 1000) * 1000000;
-  nanosleep (&ts, NULL);
+  return -1;
 }
 
-#endif
-
-#if !(defined (__i386__) || defined (__x86_64__)) && GRUB_NO_MODULES
 void
-grub_arch_sync_caches (void *address __attribute__ ((unused)),
-                      grub_size_t len __attribute__ ((unused)))
+grub_refresh (void)
 {
+  fflush (stdout);
 }
-#endif
 
-#ifndef HAVE_VASPRINTF
+int
+grub_dl_ref (grub_dl_t mod)
+{
+  (void) mod;
+  return 0;
+}
 
 int
-vasprintf (char **buf, const char *fmt, va_list ap)
+grub_dl_unref (grub_dl_t mod)
 {
-  /* Should be large enough.  */
-  *buf = xmalloc (512);
+  (void) mod;
+  return 0;
+}
 
-  return vsprintf (*buf, fmt, ap);
+/* Some functions that we don't use.  */
+void
+grub_mm_init_region (void *addr __attribute__ ((unused)),
+                    grub_size_t size __attribute__ ((unused)))
+{
 }
 
+#if !(defined (__i386__) || defined (__x86_64__))
+void
+grub_arch_sync_caches (void *address __attribute__ ((unused)),
+                      grub_size_t len __attribute__ ((unused)))
+{
+}
 #endif
 
 #ifndef  HAVE_ASPRINTF
@@ -370,23 +303,6 @@ asprintf (char **buf, const char *fmt, ...)
 
 #endif
 
-char *
-xasprintf (const char *fmt, ...)
-{
-  va_list ap;
-  char *result;
-
-  va_start (ap, fmt);
-  if (vasprintf (&result, fmt, ap) < 0)
-    {
-      if (errno == ENOMEM)
-       grub_util_error ("out of memory");
-      return NULL;
-    }
-
-  return result;
-}
-
 #ifdef __MINGW32__
 
 void sync (void)
@@ -482,104 +398,6 @@ get_win32_path (const char *path)
 }
 #endif
 
-/* This function never prints trailing slashes (so that its output
-   can be appended a slash unconditionally).  */
-char *
-make_system_path_relative_to_its_root (const char *path)
-{
-  struct stat st;
-  char *p, *buf, *buf2, *buf3;
-  uintptr_t offset = 0;
-  dev_t num;
-  size_t len;
-
-  /* canonicalize.  */
-  p = canonicalize_file_name (path);
-
-  if (p == NULL)
-    grub_util_error ("failed to get canonical path of %s", path);
-
-  len = strlen (p) + 1;
-  buf = xstrdup (p);
-  free (p);
-
-  if (stat (buf, &st) < 0)
-    grub_util_error ("cannot stat %s: %s", buf, strerror (errno));
-
-  buf2 = xstrdup (buf);
-  num = st.st_dev;
-
-  /* This loop sets offset to the number of chars of the root
-     directory we're inspecting.  */
-  while (1)
-    {
-      p = strrchr (buf, '/');
-      if (p == NULL)
-       /* This should never happen.  */
-       grub_util_error ("FIXME: no / in buf. (make_system_path_relative_to_its_root)");
-      if (p != buf)
-       *p = 0;
-      else
-       *++p = 0;
-
-      if (stat (buf, &st) < 0)
-       grub_util_error ("cannot stat %s: %s", buf, strerror (errno));
-
-      /* buf is another filesystem; we found it.  */
-      if (st.st_dev != num)
-       {
-         /* offset == 0 means path given is the mount point.
-            This works around special-casing of "/" in Un*x.  This function never
-            prints trailing slashes (so that its output can be appended a slash
-            unconditionally).  Each slash in is considered a preceding slash, and
-            therefore the root directory is an empty string.  */
-         if (offset == 0)
-           {
-             free (buf);
-             free (buf2);
-             return xstrdup ("");
-           }
-         else
-           break;
-       }
-
-      offset = p - buf;
-      /* offset == 1 means root directory.  */
-      if (offset == 1)
-       {
-         /* Include leading slash.  */
-         offset = 0;
-         break;
-       }
-    }
-  free (buf);
-  buf3 = xstrdup (buf2 + offset);
-  free (buf2);
-
-#ifdef __CYGWIN__
-  if (st.st_dev != (DEV_CYGDRIVE_MAJOR << 16))
-    {
-      /* Reached some mount point not below /cygdrive.
-        GRUB does not know Cygwin's emulated mounts,
-        convert to Win32 path.  */
-      grub_util_info ("Cygwin path = %s\n", buf3);
-      char * temp = get_win32_path (buf3);
-      free (buf3);
-      buf3 = temp;
-    }
-#endif
-
-  /* Remove trailing slashes, return empty string if root directory.  */
-  len = strlen (buf3);
-  while (len > 0 && buf3[len - 1] == '/')
-    {
-      buf3[len - 1] = '\0';
-      len--;
-    }
-
-  return buf3;
-}
-
 #ifdef GRUB_UTIL
 void
 grub_util_init_nls (void)
diff --git a/util/pci.c b/util/pci.c
deleted file mode 100644 (file)
index 420ae32..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/* pci.c - Generic PCI interfaces.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/pci.h>
-#include <grub/dl.h>
-#include <grub/util/misc.h>
-
-grub_pci_address_t
-grub_pci_make_address (grub_pci_device_t dev, int reg)
-{
-  grub_pci_address_t ret;
-  ret.dev = dev;
-  ret.pos = reg;
-  return ret;
-}
-
-void
-grub_pci_iterate (grub_pci_iteratefunc_t hook)
-{
-  struct pci_device_iterator *iter;
-  struct pci_slot_match slot;
-  struct pci_device *dev;
-  slot.domain = PCI_MATCH_ANY;
-  slot.bus = PCI_MATCH_ANY;
-  slot.dev = PCI_MATCH_ANY;
-  slot.func = PCI_MATCH_ANY;
-  iter = pci_slot_match_iterator_create (&slot);
-  while ((dev = pci_device_next (iter)))
-    hook (dev, dev->vendor_id | (dev->device_id << 16));
-  pci_iterator_destroy (iter);
-}
-
-void *
-grub_pci_device_map_range (grub_pci_device_t dev, grub_addr_t base,
-                          grub_size_t size)
-{
-  void *addr;
-  int err;
-  err = pci_device_map_range (dev, base, size, PCI_DEV_MAP_FLAG_WRITABLE, &addr);
-  if (err)
-    grub_util_error ("mapping 0x%x failed (error %d)\n", base, err);
-  return addr;
-}
-
-void
-grub_pci_device_unmap_range (grub_pci_device_t dev, void *mem,
-                            grub_size_t size)
-{
-  pci_device_unmap_range (dev, mem, size);
-}
-
-GRUB_MOD_INIT (pci)
-{
-  pci_system_init ();
-}
-
-GRUB_MOD_FINI (pci)
-{
-  pci_system_cleanup ();
-}
index ec3ecd26e965dc09f2a36eee70dee417683d628e..edf865aa79d8066f318d106628a2a0b8f9d3e204 100644 (file)
@@ -19,6 +19,7 @@
 
 /* We only support RAID on Linux.  */
 #ifdef __linux__
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
 #include <grub/util/raid.h>
 
index 8b33beba024331d0c52dbf6a54cd651ef0d5a495..7eadffd38ccf8a273d2e55ec8082e5b82e1b7b2c 100644 (file)
@@ -21,8 +21,9 @@
 #include <stdlib.h>
 #include <ctype.h>
 
-#include <grub/util/resolve.h>
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
+#include <grub/util/resolve.h>
 
 /* Module.  */
 struct mod_list
diff --git a/util/sdl.c b/util/sdl.c
deleted file mode 100644 (file)
index d261db6..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define grub_video_render_target grub_video_fbrender_target
-
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/video.h>
-#include <grub/video_fb.h>
-#include <SDL/SDL.h>
-
-static SDL_Surface *window = 0;
-static struct grub_video_render_target *sdl_render_target;
-static struct grub_video_mode_info mode_info;
-
-static grub_err_t
-grub_video_sdl_set_palette (unsigned int start, unsigned int count,
-                            struct grub_video_palette_data *palette_data);
-
-static grub_err_t
-grub_video_sdl_init (void)
-{
-  window = 0;
-
-  if (SDL_Init (SDL_INIT_VIDEO) < 0)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "Couldn't init SDL: %s",
-                      SDL_GetError ());
-
-  grub_memset (&mode_info, 0, sizeof (mode_info));
-
-  return grub_video_fb_init ();
-}
-
-static grub_err_t
-grub_video_sdl_fini (void)
-{
-  SDL_Quit ();
-  window = 0;
-
-  grub_memset (&mode_info, 0, sizeof (mode_info));
-
-  return grub_video_fb_fini ();
-}
-
-static inline unsigned int
-get_mask_size (grub_uint32_t mask)
-{
-  unsigned i;
-  for (i = 0; mask > 1U << i; i++);
-  return i;
-}
-
-static grub_err_t
-grub_video_sdl_setup (unsigned int width, unsigned int height,
-                      unsigned int mode_type, unsigned int mode_mask)
-{
-  int depth;
-  int flags = 0;
-  grub_err_t err;
-
-  /* Decode depth from mode_type.  If it is zero, then autodetect.  */
-  depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
-          >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
-
-  if (depth == 0)
-    depth = 32;
-
-  if (width == 0 && height == 0)
-    {
-      width = 800;
-      height = 600;
-    }
-
-  if ((mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)
-      || !(mode_mask & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED))
-    flags |= SDL_DOUBLEBUF;
-
-  window = SDL_SetVideoMode (width, height, depth, flags | SDL_HWSURFACE);
-  if (! window)
-    window = SDL_SetVideoMode (width, height, depth, flags | SDL_SWSURFACE);
-  if (! window)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "Couldn't open window: %s",
-                      SDL_GetError ());
-
-  grub_memset (&sdl_render_target, 0, sizeof (sdl_render_target));
-
-  mode_info.width = window->w;
-  mode_info.height = window->h;
-  mode_info.mode_type = 0;
-  if (window->flags & SDL_DOUBLEBUF)
-    mode_info.mode_type
-      |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
-  if (window->format->palette)
-    mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
-  else
-    mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_RGB;
-
-  mode_info.bpp = window->format->BitsPerPixel;
-  mode_info.bytes_per_pixel = window->format->BytesPerPixel;
-  mode_info.pitch = window->pitch;
-
-  /* In index color mode, number of colors.  In RGB mode this is 256.  */
-  if (window->format->palette)
-    mode_info.number_of_colors
-      = 1 << window->format->BitsPerPixel;
-  else
-    mode_info.number_of_colors = 256;
-
-  if (! window->format->palette)
-    {
-      mode_info.red_mask_size
-       = get_mask_size (window->format->Rmask >> window->format->Rshift);
-      mode_info.red_field_pos = window->format->Rshift;
-      mode_info.green_mask_size
-       = get_mask_size (window->format->Gmask >> window->format->Gshift);
-      mode_info.green_field_pos = window->format->Gshift;
-      mode_info.blue_mask_size
-       = get_mask_size (window->format->Bmask >> window->format->Bshift);
-      mode_info.blue_field_pos = window->format->Bshift;
-      mode_info.reserved_mask_size
-       = get_mask_size (window->format->Amask >> window->format->Ashift);
-      mode_info.reserved_field_pos = window->format->Ashift;
-      mode_info.blit_format
-       = grub_video_get_blit_format (&mode_info);
-    }
-
-  err = grub_video_fb_create_render_target_from_pointer (&sdl_render_target,
-                                                        &mode_info,
-                                                        window->pixels);
-  if (err)
-    return err;
-
-  /* Copy default palette to initialize emulated palette.  */
-  grub_video_sdl_set_palette (0, (sizeof (grub_video_fbstd_colors)
-                                 / sizeof (grub_video_fbstd_colors[0])),
-                             grub_video_fbstd_colors);
-
-  /* Reset render target to SDL one.  */
-  return grub_video_fb_set_active_render_target (sdl_render_target);
-}
-
-static grub_err_t
-grub_video_sdl_set_palette (unsigned int start, unsigned int count,
-                            struct grub_video_palette_data *palette_data)
-{
-  unsigned i;
-  if (window->format->palette)
-    {
-      SDL_Color *tmp = grub_malloc (count * sizeof (tmp[0]));
-      for (i = 0; i < count; i++)
-       {
-         tmp[i].r = palette_data[i].r;
-         tmp[i].g = palette_data[i].g;
-         tmp[i].b = palette_data[i].b;
-         tmp[i].unused = palette_data[i].a;
-       }
-      SDL_SetColors (window, tmp, start, count);
-      grub_free (tmp);
-    }
-
-  return grub_video_fb_set_palette (start, count, palette_data);
-}
-
-static grub_err_t
-grub_video_sdl_swap_buffers (void)
-{
-  if (SDL_Flip (window) < 0)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "couldn't swap buffers: %s",
-                      SDL_GetError ());
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_sdl_set_active_render_target (struct grub_video_render_target *target)
-{
-  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
-    return grub_video_fb_set_active_render_target (sdl_render_target);
-
-  return grub_video_fb_set_active_render_target (target);
-}
-
-static struct grub_video_adapter grub_video_sdl_adapter =
-  {
-    .name = "SDL Video Driver",
-
-    .init = grub_video_sdl_init,
-    .fini = grub_video_sdl_fini,
-    .setup = grub_video_sdl_setup,
-    .get_info = grub_video_fb_get_info,
-    .set_palette = grub_video_sdl_set_palette,
-    .get_palette = grub_video_fb_get_palette,
-    .set_viewport = grub_video_fb_set_viewport,
-    .get_viewport = grub_video_fb_get_viewport,
-    .map_color = grub_video_fb_map_color,
-    .map_rgb = grub_video_fb_map_rgb,
-    .map_rgba = grub_video_fb_map_rgba,
-    .unmap_color = grub_video_fb_unmap_color,
-    .fill_rect = grub_video_fb_fill_rect,
-    .blit_bitmap = grub_video_fb_blit_bitmap,
-    .blit_render_target = grub_video_fb_blit_render_target,
-    .scroll = grub_video_fb_scroll,
-    .swap_buffers = grub_video_sdl_swap_buffers,
-    .create_render_target = grub_video_fb_create_render_target,
-    .delete_render_target = grub_video_fb_delete_render_target,
-    .set_active_render_target = grub_video_sdl_set_active_render_target,
-    .get_active_render_target = grub_video_fb_get_active_render_target,
-
-    .next = 0
-  };
-
-GRUB_MOD_INIT(sdl)
-{
-  grub_video_register (&grub_video_sdl_adapter);
-}
-
-GRUB_MOD_FINI(sdl)
-{
-  grub_video_unregister (&grub_video_sdl_adapter);
-}
index 06bc16795ec2608be972589feea432d8282fdbd6..7051fd078efd7c3a36fe1040351c9adad18c6c4e 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <config.h>
 #include <grub/types.h>
+#include <grub/emu/misc.h>
 #include <grub/util/misc.h>
 #include <grub/device.h>
 #include <grub/i18n.h>
@@ -29,7 +30,7 @@
 #include <grub/msdos_partition.h>
 #include <grub/gpt_partition.h>
 #include <grub/env.h>
-#include <grub/util/hostdisk.h>
+#include <grub/emu/hostdisk.h>
 #include <grub/machine/boot.h>
 #include <grub/machine/kernel.h>
 #include <grub/term.h>
@@ -37,8 +38,6 @@
 #include <grub/util/lvm.h>
 #include <grub/util/ofpath.h>
 
-#include <grub_setup_init.h>
-
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
@@ -46,7 +45,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <dirent.h>
-#include <grub/util/getroot.h>
+#include <grub/emu/getroot.h>
 
 #define _GNU_SOURCE    1
 #include <getopt.h>
@@ -83,27 +82,6 @@ struct boot_blocklist
   grub_uint32_t len;
 } __attribute__ ((packed));
 
-void
-grub_putchar (int c)
-{
-  putchar (c);
-}
-
-int
-grub_getkey (void)
-{
-  return -1;
-}
-
-struct grub_handler_class grub_term_input_class;
-struct grub_handler_class grub_term_output_class;
-
-void
-grub_refresh (void)
-{
-  fflush (stdout);
-}
-
 static void
 setup (const char *prefix, const char *dir,
        const char *boot_file, const char *core_file,
@@ -627,8 +605,8 @@ main (int argc, char *argv[])
 
   find_dest_dev (&ginfo, argv);
 
-  ginfo.prefix = make_system_path_relative_to_its_root (ginfo.dir ?
-                                                       : DEFAULT_DIRECTORY);
+  ginfo.prefix = grub_make_system_path_relative_to_its_root (ginfo.dir ?
+                                                            : DEFAULT_DIRECTORY);
 
   check_root_dev (&ginfo);
 
diff --git a/util/time.c b/util/time.c
deleted file mode 100644 (file)
index 5da8092..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/datetime.h>
-#include <time.h>
-
-grub_err_t
-grub_get_datetime (struct grub_datetime *datetime)
-{
-  struct tm *mytm;
-  time_t mytime;
-
-  mytime = time (&mytime);
-  mytm = gmtime (&mytime);
-
-  datetime->year = mytm->tm_year + 1900;
-  datetime->month = mytm->tm_mon + 1;
-  datetime->day = mytm->tm_mday;
-  datetime->hour = mytm->tm_hour;
-  datetime->minute = mytm->tm_min;
-  datetime->second = mytm->tm_sec;
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_set_datetime (struct grub_datetime *datetime __attribute__ ((unused)))
-{
-  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                    "no clock setting routine available");
-}
diff --git a/util/usb.c b/util/usb.c
deleted file mode 100644 (file)
index a687eea..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/*  usb.c -- libusb USB support for GRUB.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <usb.h>
-#include <grub/usb.h>
-#include <grub/dl.h>
-
-\f
-static struct grub_usb_controller_dev usb_controller =
-{
-  .name = "libusb"
-};
-
-static struct grub_usb_device *grub_usb_devs[128];
-
-struct usb_bus *busses;
-
-static grub_err_t
-grub_libusb_devices (void)
-
-{
-  struct usb_bus *bus;
-  int last = 0;
-
-  busses = usb_get_busses();
-
-  for (bus = busses; bus; bus = bus->next)
-    {
-      struct usb_device *usbdev;
-      struct grub_usb_device *dev;
-
-      for (usbdev = bus->devices; usbdev; usbdev = usbdev->next)
-       {
-         struct usb_device_descriptor *desc = &usbdev->descriptor;
-         grub_err_t err;
-
-         if (! desc->bcdUSB)
-           continue;
-
-         dev = grub_malloc (sizeof (*dev));
-         if (! dev)
-           return grub_errno;
-
-         dev->data = usbdev;
-
-         /* Fill in all descriptors.  */
-         err = grub_usb_device_initialize (dev);
-         if (err)
-           {
-             grub_errno = GRUB_ERR_NONE;
-             continue;
-           }
-
-         /* Register the device.  */
-         grub_usb_devs[last++] = dev;
-       }
-    }
-
-  return GRUB_USB_ERR_NONE;
-}
-
-\f
-int
-grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
-{
-  int i;
-
-  for (i = 0; i < 128; i++)
-    {
-      if (grub_usb_devs[i])
-       {
-         if (hook (grub_usb_devs[i]))
-             return 1;
-       }
-    }
-
-  return 0;
-}
-
-grub_usb_err_t
-grub_usb_root_hub (grub_usb_controller_t controller __attribute__((unused)))
-{
-  return GRUB_USB_ERR_NONE;
-}
-
-grub_usb_err_t
-grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype,
-                     grub_uint8_t request, grub_uint16_t value,
-                     grub_uint16_t index, grub_size_t size, char *data)
-{
-  usb_dev_handle *devh;
-  struct usb_device *d = dev->data;
-
-  devh = usb_open (d);
-  if (usb_control_msg (devh, reqtype, request,
-                      value, index, data, size, 20) < 0)
-    {
-      usb_close (devh);
-      return GRUB_USB_ERR_STALL;
-    }
-
-  usb_close (devh);
-
-  return GRUB_USB_ERR_NONE;
-}
-
-grub_usb_err_t
-grub_usb_bulk_read (grub_usb_device_t dev,
-                   int endpoint, grub_size_t size, char *data)
-{
-  usb_dev_handle *devh;
-  struct usb_device *d = dev->data;
-
-  devh = usb_open (d);
-  if (usb_claim_interface (devh, 0) < 1)
-    {
-      usb_close (devh);
-      return GRUB_USB_ERR_STALL;
-    }
-
-  if (usb_bulk_read (devh, endpoint, data, size, 20) < 1)
-    {
-      usb_close (devh);
-      return GRUB_USB_ERR_STALL;
-    }
-
-  usb_release_interface (devh, 0);
-  usb_close (devh);
-
-  return GRUB_USB_ERR_NONE;
-}
-
-grub_usb_err_t
-grub_usb_bulk_write (grub_usb_device_t dev,
-                    int endpoint, grub_size_t size, char *data)
-{
-  usb_dev_handle *devh;
-  struct usb_device *d = dev->data;
-
-  devh = usb_open (d);
-  if (usb_claim_interface (devh, 0) < 0)
-    goto fail;
-
-  if (usb_bulk_write (devh, endpoint, data, size, 20) < 0)
-    goto fail;
-
-  if (usb_release_interface (devh, 0) < 0)
-    goto fail;
-
-  usb_close (devh);
-
-  return GRUB_USB_ERR_NONE;
-
- fail:
-  usb_close (devh);
-  return GRUB_USB_ERR_STALL;
-}
-
-GRUB_MOD_INIT (libusb)
-{
-  usb_init();
-  usb_find_busses();
-  usb_find_devices();
-
-  if (grub_libusb_devices ())
-    return;
-
-  grub_usb_controller_dev_register (&usb_controller);
-
-  return;
-}
-
-GRUB_MOD_FINI (libusb)
-{
-  return;
-}
diff --git a/video/bitmap.c b/video/bitmap.c
deleted file mode 100644 (file)
index e06a5b6..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/video.h>
-#include <grub/bitmap.h>
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-
-/* List of bitmap readers registered to system.  */
-static grub_video_bitmap_reader_t bitmap_readers_list;
-
-/* Register bitmap reader.  */
-void
-grub_video_bitmap_reader_register (grub_video_bitmap_reader_t reader)
-{
-  reader->next = bitmap_readers_list;
-  bitmap_readers_list = reader;
-}
-
-/* Unregister bitmap reader.  */
-void
-grub_video_bitmap_reader_unregister (grub_video_bitmap_reader_t reader)
-{
-  grub_video_bitmap_reader_t *p, q;
-
-  for (p = &bitmap_readers_list, q = *p; q; p = &(q->next), q = q->next)
-    if (q == reader)
-      {
-        *p = q->next;
-        break;
-      }
-}
-
-/* Creates new bitmap, saves created bitmap on success to *bitmap.  */
-grub_err_t
-grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
-                          unsigned int width, unsigned int height,
-                          enum grub_video_blit_format blit_format)
-{
-  struct grub_video_mode_info *mode_info;
-  unsigned int size;
-
-  if (!bitmap)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
-
-  *bitmap = 0;
-
-  if (width == 0 || height == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
-
-  *bitmap = (struct grub_video_bitmap *)grub_malloc (sizeof (struct grub_video_bitmap));
-  if (! *bitmap)
-    return grub_errno;
-
-  mode_info = &((*bitmap)->mode_info);
-
-  /* Populate mode_info.  */
-  mode_info->width = width;
-  mode_info->height = height;
-  mode_info->blit_format = blit_format;
-
-  switch (blit_format)
-    {
-      case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
-        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB
-                               | GRUB_VIDEO_MODE_TYPE_ALPHA;
-        mode_info->bpp = 32;
-        mode_info->bytes_per_pixel = 4;
-        mode_info->number_of_colors = 256;
-        mode_info->red_mask_size = 8;
-        mode_info->red_field_pos = 0;
-        mode_info->green_mask_size = 8;
-        mode_info->green_field_pos = 8;
-        mode_info->blue_mask_size = 8;
-        mode_info->blue_field_pos = 16;
-        mode_info->reserved_mask_size = 8;
-        mode_info->reserved_field_pos = 24;
-        break;
-
-      case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
-        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
-        mode_info->bpp = 24;
-        mode_info->bytes_per_pixel = 3;
-        mode_info->number_of_colors = 256;
-        mode_info->red_mask_size = 8;
-        mode_info->red_field_pos = 0;
-        mode_info->green_mask_size = 8;
-        mode_info->green_field_pos = 8;
-        mode_info->blue_mask_size = 8;
-        mode_info->blue_field_pos = 16;
-        mode_info->reserved_mask_size = 0;
-        mode_info->reserved_field_pos = 0;
-        break;
-
-      case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
-        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
-        mode_info->bpp = 8;
-        mode_info->bytes_per_pixel = 1;
-        mode_info->number_of_colors = 256;
-        mode_info->red_mask_size = 0;
-        mode_info->red_field_pos = 0;
-        mode_info->green_mask_size = 0;
-        mode_info->green_field_pos = 0;
-        mode_info->blue_mask_size = 0;
-        mode_info->blue_field_pos = 0;
-        mode_info->reserved_mask_size = 0;
-        mode_info->reserved_field_pos = 0;
-        break;
-
-      default:
-        grub_free (*bitmap);
-        *bitmap = 0;
-
-        return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                           "unsupported bitmap format");
-    }
-
-  mode_info->pitch = width * mode_info->bytes_per_pixel;
-
-  /* Calculate size needed for the data.  */
-  size = (width * mode_info->bytes_per_pixel) * height;
-
-  (*bitmap)->data = grub_zalloc (size);
-  if (! (*bitmap)->data)
-    {
-      grub_free (*bitmap);
-      *bitmap = 0;
-
-      return grub_errno;
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-/* Frees all resources allocated by bitmap.  */
-grub_err_t
-grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap)
-{
-  if (! bitmap)
-    return GRUB_ERR_NONE;
-
-  grub_free (bitmap->data);
-  grub_free (bitmap);
-
-  return GRUB_ERR_NONE;
-}
-
-/* Match extension to filename.  */
-static int
-match_extension (const char *filename, const char *ext)
-{
-  int pos;
-  int ext_len;
-
-  pos = grub_strlen (filename);
-  ext_len = grub_strlen (ext);
-
-  if (! pos || ! ext_len || ext_len > pos)
-    return 0;
-
-  pos -= ext_len;
-
-  return grub_strcmp (filename + pos, ext) == 0;
-}
-
-/* Loads bitmap using registered bitmap readers.  */
-grub_err_t
-grub_video_bitmap_load (struct grub_video_bitmap **bitmap,
-                        const char *filename)
-{
-  grub_video_bitmap_reader_t reader = bitmap_readers_list;
-
-  if (!bitmap)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
-
-  *bitmap = 0;
-
-  while (reader)
-    {
-      if (match_extension (filename, reader->extension))
-        return reader->reader (bitmap, filename);
-
-      reader = reader->next;
-    }
-
-  return grub_error(GRUB_ERR_BAD_FILE_TYPE, "unsupported bitmap format");
-}
-
-/* Return bitmap width.  */
-unsigned int
-grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap)
-{
-  if (!bitmap)
-    return 0;
-
-  return bitmap->mode_info.width;
-}
-
-/* Return bitmap height.  */
-unsigned int
-grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap)
-{
-  if (!bitmap)
-    return 0;
-
-  return bitmap->mode_info.height;
-}
-
-/* Return mode info for bitmap.  */
-void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap,
-                                      struct grub_video_mode_info *mode_info)
-{
-  if (!bitmap)
-    return;
-
-  *mode_info = bitmap->mode_info;
-}
-
-/* Return pointer to bitmap's raw data.  */
-void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap)
-{
-  if (!bitmap)
-    return 0;
-
-  return bitmap->data;
-}
-
-/* Initialize bitmap module.  */
-GRUB_MOD_INIT(bitmap)
-{
-}
-
-/* Finalize bitmap module.  */
-GRUB_MOD_FINI(bitmap)
-{
-}
diff --git a/video/bitmap_scale.c b/video/bitmap_scale.c
deleted file mode 100644 (file)
index 6f8ff24..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-/* bitmap_scale.c - Bitmap scaling. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/video.h>
-#include <grub/bitmap.h>
-#include <grub/bitmap_scale.h>
-#include <grub/types.h>
-
-/* Prototypes for module-local functions.  */
-static grub_err_t scale_nn (struct grub_video_bitmap *dst,
-                            struct grub_video_bitmap *src);
-static grub_err_t scale_bilinear (struct grub_video_bitmap *dst,
-                                  struct grub_video_bitmap *src);
-
-/* This function creates a new scaled version of the bitmap SRC.  The new
-   bitmap has dimensions DST_WIDTH by DST_HEIGHT.  The scaling algorithm
-   is given by SCALE_METHOD.  If an error is encountered, the return code is
-   not equal to GRUB_ERR_NONE, and the bitmap DST is either not created, or
-   it is destroyed before this function returns.
-
-   Supports only direct color modes which have components separated
-   into bytes (e.g., RGBA 8:8:8:8 or BGR 8:8:8 true color).
-   But because of this simplifying assumption, the implementation is
-   greatly simplified.  */
-grub_err_t
-grub_video_bitmap_create_scaled (struct grub_video_bitmap **dst,
-                                 int dst_width, int dst_height,
-                                 struct grub_video_bitmap *src,
-                                 enum grub_video_bitmap_scale_method
-                                 scale_method)
-{
-  *dst = 0;
-
-  /* Verify the simplifying assumptions. */
-  if (src == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                       "null src bitmap in grub_video_bitmap_create_scaled");
-  if (src->mode_info.red_field_pos % 8 != 0
-      || src->mode_info.green_field_pos % 8 != 0
-      || src->mode_info.blue_field_pos % 8 != 0
-      || src->mode_info.reserved_field_pos % 8 != 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                       "src format not supported for scale");
-  if (src->mode_info.width == 0 || src->mode_info.height == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                       "source bitmap has a zero dimension");
-  if (dst_width <= 0 || dst_height <= 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                       "requested to scale to a size w/ a zero dimension");
-  if (src->mode_info.bytes_per_pixel * 8 != src->mode_info.bpp)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                       "bitmap to scale has inconsistent Bpp and bpp");
-
-  /* Create the new bitmap. */
-  grub_err_t ret;
-  ret = grub_video_bitmap_create (dst, dst_width, dst_height,
-                                  src->mode_info.blit_format);
-  if (ret != GRUB_ERR_NONE)
-    return ret;                 /* Error. */
-
-  switch (scale_method)
-    {
-    case GRUB_VIDEO_BITMAP_SCALE_METHOD_FASTEST:
-    case GRUB_VIDEO_BITMAP_SCALE_METHOD_NEAREST:
-      ret = scale_nn (*dst, src);
-      break;
-    case GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST:
-    case GRUB_VIDEO_BITMAP_SCALE_METHOD_BILINEAR:
-      ret = scale_bilinear (*dst, src);
-      break;
-    default:
-      ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid scale_method value");
-      break;
-    }
-
-  if (ret == GRUB_ERR_NONE)
-    {
-      /* Success:  *dst is now a pointer to the scaled bitmap. */
-      return GRUB_ERR_NONE;
-    }
-  else
-    {
-      /* Destroy the bitmap and return the error code. */
-      grub_video_bitmap_destroy (*dst);
-      *dst = 0;
-      return ret;
-    }
-}
-
-/* Nearest neighbor bitmap scaling algorithm.
-
-   Copy the bitmap SRC to the bitmap DST, scaling the bitmap to fit the
-   dimensions of DST.  This function uses the nearest neighbor algorithm to
-   interpolate the pixels.
-
-   Supports only direct color modes which have components separated
-   into bytes (e.g., RGBA 8:8:8:8 or BGR 8:8:8 true color).
-   But because of this simplifying assumption, the implementation is
-   greatly simplified.  */
-static grub_err_t
-scale_nn (struct grub_video_bitmap *dst, struct grub_video_bitmap *src)
-{
-  /* Verify the simplifying assumptions. */
-  if (dst == 0 || src == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "null bitmap in scale_nn");
-  if (dst->mode_info.red_field_pos % 8 != 0
-      || dst->mode_info.green_field_pos % 8 != 0
-      || dst->mode_info.blue_field_pos % 8 != 0
-      || dst->mode_info.reserved_field_pos % 8 != 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst format not supported");
-  if (src->mode_info.red_field_pos % 8 != 0
-      || src->mode_info.green_field_pos % 8 != 0
-      || src->mode_info.blue_field_pos % 8 != 0
-      || src->mode_info.reserved_field_pos % 8 != 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "src format not supported");
-  if (dst->mode_info.red_field_pos != src->mode_info.red_field_pos
-      || dst->mode_info.red_mask_size != src->mode_info.red_mask_size
-      || dst->mode_info.green_field_pos != src->mode_info.green_field_pos
-      || dst->mode_info.green_mask_size != src->mode_info.green_mask_size
-      || dst->mode_info.blue_field_pos != src->mode_info.blue_field_pos
-      || dst->mode_info.blue_mask_size != src->mode_info.blue_mask_size
-      || dst->mode_info.reserved_field_pos !=
-      src->mode_info.reserved_field_pos
-      || dst->mode_info.reserved_mask_size !=
-      src->mode_info.reserved_mask_size)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible");
-  if (dst->mode_info.bytes_per_pixel != src->mode_info.bytes_per_pixel)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible");
-  if (dst->mode_info.width == 0 || dst->mode_info.height == 0
-      || src->mode_info.width == 0 || src->mode_info.height == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "bitmap has a zero dimension");
-
-  grub_uint8_t *ddata = dst->data;
-  grub_uint8_t *sdata = src->data;
-  int dw = dst->mode_info.width;
-  int dh = dst->mode_info.height;
-  int sw = src->mode_info.width;
-  int sh = src->mode_info.height;
-  int dstride = dst->mode_info.pitch;
-  int sstride = src->mode_info.pitch;
-  /* bytes_per_pixel is the same for both src and dst. */
-  int bytes_per_pixel = dst->mode_info.bytes_per_pixel;
-
-  int dy;
-  for (dy = 0; dy < dh; dy++)
-    {
-      int dx;
-      for (dx = 0; dx < dw; dx++)
-        {
-          grub_uint8_t *dptr;
-          grub_uint8_t *sptr;
-          int sx;
-          int sy;
-          int comp;
-
-          /* Compute the source coordinate that the destination coordinate
-             maps to.  Note: sx/sw = dx/dw  =>  sx = sw*dx/dw. */
-          sx = sw * dx / dw;
-          sy = sh * dy / dh;
-
-          /* Get the address of the pixels in src and dst. */
-          dptr = ddata + dy * dstride + dx * bytes_per_pixel;
-          sptr = sdata + sy * sstride + sx * bytes_per_pixel;
-
-          /* Copy the pixel color value. */
-          for (comp = 0; comp < bytes_per_pixel; comp++)
-            dptr[comp] = sptr[comp];
-        }
-    }
-  return GRUB_ERR_NONE;
-}
-
-/* Bilinear interpolation image scaling algorithm.
-
-   Copy the bitmap SRC to the bitmap DST, scaling the bitmap to fit the
-   dimensions of DST.  This function uses the bilinear interpolation algorithm
-   to interpolate the pixels.
-
-   Supports only direct color modes which have components separated
-   into bytes (e.g., RGBA 8:8:8:8 or BGR 8:8:8 true color).
-   But because of this simplifying assumption, the implementation is
-   greatly simplified.  */
-static grub_err_t
-scale_bilinear (struct grub_video_bitmap *dst, struct grub_video_bitmap *src)
-{
-  /* Verify the simplifying assumptions. */
-  if (dst == 0 || src == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "null bitmap in scale func");
-  if (dst->mode_info.red_field_pos % 8 != 0
-      || dst->mode_info.green_field_pos % 8 != 0
-      || dst->mode_info.blue_field_pos % 8 != 0
-      || dst->mode_info.reserved_field_pos % 8 != 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst format not supported");
-  if (src->mode_info.red_field_pos % 8 != 0
-      || src->mode_info.green_field_pos % 8 != 0
-      || src->mode_info.blue_field_pos % 8 != 0
-      || src->mode_info.reserved_field_pos % 8 != 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "src format not supported");
-  if (dst->mode_info.red_field_pos != src->mode_info.red_field_pos
-      || dst->mode_info.red_mask_size != src->mode_info.red_mask_size
-      || dst->mode_info.green_field_pos != src->mode_info.green_field_pos
-      || dst->mode_info.green_mask_size != src->mode_info.green_mask_size
-      || dst->mode_info.blue_field_pos != src->mode_info.blue_field_pos
-      || dst->mode_info.blue_mask_size != src->mode_info.blue_mask_size
-      || dst->mode_info.reserved_field_pos !=
-      src->mode_info.reserved_field_pos
-      || dst->mode_info.reserved_mask_size !=
-      src->mode_info.reserved_mask_size)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible");
-  if (dst->mode_info.bytes_per_pixel != src->mode_info.bytes_per_pixel)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible");
-  if (dst->mode_info.width == 0 || dst->mode_info.height == 0
-      || src->mode_info.width == 0 || src->mode_info.height == 0)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "bitmap has a zero dimension");
-
-  grub_uint8_t *ddata = dst->data;
-  grub_uint8_t *sdata = src->data;
-  int dw = dst->mode_info.width;
-  int dh = dst->mode_info.height;
-  int sw = src->mode_info.width;
-  int sh = src->mode_info.height;
-  int dstride = dst->mode_info.pitch;
-  int sstride = src->mode_info.pitch;
-  /* bytes_per_pixel is the same for both src and dst. */
-  int bytes_per_pixel = dst->mode_info.bytes_per_pixel;
-
-  int dy;
-  for (dy = 0; dy < dh; dy++)
-    {
-      int dx;
-      for (dx = 0; dx < dw; dx++)
-        {
-          grub_uint8_t *dptr;
-          grub_uint8_t *sptr;
-          int sx;
-          int sy;
-          int comp;
-
-          /* Compute the source coordinate that the destination coordinate
-             maps to.  Note: sx/sw = dx/dw  =>  sx = sw*dx/dw. */
-          sx = sw * dx / dw;
-          sy = sh * dy / dh;
-
-          /* Get the address of the pixels in src and dst. */
-          dptr = ddata + dy * dstride + dx * bytes_per_pixel;
-          sptr = sdata + sy * sstride + sx * bytes_per_pixel;
-
-          /* If we have enough space to do so, use bilinear interpolation.
-             Otherwise, fall back to nearest neighbor for this pixel. */
-          if (sx < sw - 1 && sy < sh - 1)
-            {
-              /* Do bilinear interpolation. */
-
-              /* Fixed-point .8 numbers representing the fraction of the
-                 distance in the x (u) and y (v) direction within the
-                 box of 4 pixels in the source. */
-              int u = (256 * sw * dx / dw) - (sx * 256);
-              int v = (256 * sh * dy / dh) - (sy * 256);
-
-              for (comp = 0; comp < bytes_per_pixel; comp++)
-                {
-                  /* Get the component's values for the
-                     four source corner pixels. */
-                  grub_uint8_t f00 = sptr[comp];
-                  grub_uint8_t f10 = sptr[comp + bytes_per_pixel];
-                  grub_uint8_t f01 = sptr[comp + sstride];
-                  grub_uint8_t f11 = sptr[comp + sstride + bytes_per_pixel];
-
-                  /* Do linear interpolations along the top and bottom
-                     rows of the box. */
-                  grub_uint8_t f0y = (256 - v) * f00 / 256 + v * f01 / 256;
-                  grub_uint8_t f1y = (256 - v) * f10 / 256 + v * f11 / 256;
-
-                  /* Interpolate vertically. */
-                  grub_uint8_t fxy = (256 - u) * f0y / 256 + u * f1y / 256;
-
-                  dptr[comp] = fxy;
-                }
-            }
-          else
-            {
-              /* Fall back to nearest neighbor interpolation. */
-              /* Copy the pixel color value. */
-              for (comp = 0; comp < bytes_per_pixel; comp++)
-                dptr[comp] = sptr[comp];
-            }
-        }
-    }
-  return GRUB_ERR_NONE;
-}
diff --git a/video/efi_gop.c b/video/efi_gop.c
deleted file mode 100644 (file)
index 86a2881..0000000
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define grub_video_render_target grub_video_fbrender_target
-
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/video.h>
-#include <grub/video_fb.h>
-#include <grub/efi/api.h>
-#include <grub/efi/efi.h>
-#include <grub/efi/graphics_output.h>
-
-static grub_efi_guid_t graphics_output_guid = GRUB_EFI_GOP_GUID;
-static struct grub_efi_gop *gop;
-static unsigned old_mode;
-static int restore_needed;
-
-static struct
-{
-  struct grub_video_mode_info mode_info;
-  struct grub_video_render_target *render_target;
-  grub_uint8_t *ptr;
-} framebuffer;
-
-
-static int
-check_protocol (void)
-{
-  gop = grub_efi_locate_protocol (&graphics_output_guid, 0);
-  if (gop)
-    return 1;
-
-  return 0;
-}
-
-static grub_err_t
-grub_video_gop_init (void)
-{
-  grub_memset (&framebuffer, 0, sizeof(framebuffer));
-  return grub_video_fb_init ();
-}
-
-static grub_err_t
-grub_video_gop_fini (void)
-{
-  if (restore_needed)
-    {
-      efi_call_2 (gop->set_mode, gop, old_mode);
-      restore_needed = 0;
-    }
-  return grub_video_fb_fini ();
-}
-
-static int
-grub_video_gop_get_bpp (struct grub_efi_gop_mode_info *in)
-{
-  grub_uint32_t total_mask;
-  int i;
-  switch (in->pixel_format)
-    {
-    case GRUB_EFI_GOT_BGRA8:
-    case GRUB_EFI_GOT_RGBA8:
-      return 32;
-
-    case GRUB_EFI_GOT_BITMASK:
-      /* Check overlaps.  */
-      if ((in->pixel_bitmask.r & in->pixel_bitmask.g)
-         || (in->pixel_bitmask.r & in->pixel_bitmask.b)
-         || (in->pixel_bitmask.g & in->pixel_bitmask.b)
-         || (in->pixel_bitmask.r & in->pixel_bitmask.a)
-         || (in->pixel_bitmask.g & in->pixel_bitmask.a)
-         || (in->pixel_bitmask.b & in->pixel_bitmask.a))
-       return 0;
-
-      total_mask = in->pixel_bitmask.r | in->pixel_bitmask.g
-       | in->pixel_bitmask.b | in->pixel_bitmask.a;
-
-      for (i = 31; i >= 0; i--)
-       if (total_mask & (1 << i))
-         return i + 1;
-
-      /* Fall through.  */
-    default:
-      return 0;
-    }
-}
-
-static void
-grub_video_gop_get_bitmask (grub_uint32_t mask, unsigned int *mask_size,
-                           unsigned int *field_pos)
-{
-  int i;
-  int last_p;
-  for (i = 31; i >= 0; i--)
-    if (mask & (1 << i))
-      break;
-  if (i == -1)
-    {
-      *mask_size = *field_pos = 0;
-      return;
-    }
-  last_p = i;
-  for (; i >= 0; i--)
-    if (!(mask & (1 << i)))
-      break;
-  *field_pos = i + 1;
-  *mask_size = last_p - *field_pos + 1;
-}
-
-static grub_err_t
-grub_video_gop_fill_mode_info (struct grub_efi_gop_mode_info *in,
-                              struct grub_video_mode_info *out)
-{
-  out->number_of_colors = 256;
-  out->width = in->width;
-  out->height = in->height;
-  out->mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
-  out->bpp = grub_video_gop_get_bpp (in);
-  out->bytes_per_pixel = out->bpp >> 3;
-  if (!out->bpp)
-    return grub_error (GRUB_ERR_IO, "unsupported video mode");
-  out->pitch = in->pixels_per_scanline * out->bytes_per_pixel;
-
-  switch (in->pixel_format)
-    {
-    case GRUB_EFI_GOT_RGBA8:
-      out->red_mask_size = 8;
-      out->red_field_pos = 0;
-      out->green_mask_size = 8;
-      out->green_field_pos = 8;
-      out->blue_mask_size = 8;
-      out->blue_field_pos = 16;
-      out->reserved_mask_size = 8;
-      out->reserved_field_pos = 24;
-      break;
-
-    case GRUB_EFI_GOT_BGRA8:
-      out->red_mask_size = 8;
-      out->red_field_pos = 16;
-      out->green_mask_size = 8;
-      out->green_field_pos = 8;
-      out->blue_mask_size = 8;
-      out->blue_field_pos = 0;
-      out->reserved_mask_size = 8;
-      out->reserved_field_pos = 24;
-      break;
-
-    case GRUB_EFI_GOT_BITMASK:
-      grub_video_gop_get_bitmask (in->pixel_bitmask.r, &out->red_mask_size,
-                                 &out->red_field_pos);
-      grub_video_gop_get_bitmask (in->pixel_bitmask.g, &out->green_mask_size,
-                                 &out->green_field_pos);
-      grub_video_gop_get_bitmask (in->pixel_bitmask.b, &out->blue_mask_size,
-                                 &out->blue_field_pos);
-      grub_video_gop_get_bitmask (in->pixel_bitmask.a, &out->reserved_mask_size,
-                                 &out->reserved_field_pos);
-      break;
-
-    default:
-      return grub_error (GRUB_ERR_IO, "unsupported video mode");
-    }
-
-  out->blit_format = grub_video_get_blit_format (out);
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_gop_setup (unsigned int width, unsigned int height,
-                     unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused)))
-{
-  unsigned int depth;
-  struct grub_efi_gop_mode_info *info = NULL;
-  unsigned best_mode = 0;
-  grub_err_t err;
-  unsigned bpp;
-  int found = 0;
-  unsigned long long best_volume = 0;
-
-  depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
-    >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
-
-  /* Keep current mode if possible.  */
-  if (gop->mode->info)
-    {
-      bpp = grub_video_gop_get_bpp (gop->mode->info);
-      if (bpp && ((width == gop->mode->info->width
-                  && height == gop->mode->info->height)
-                 || (width == 0 && height == 0))
-         && (depth == bpp || depth == 0))
-       {
-         grub_dprintf ("video", "GOP: keeping mode %d\n", gop->mode->mode);
-         best_mode = gop->mode->mode;
-         found = 1;
-       }
-    }
-  if (!found)
-    {
-      unsigned mode;
-      grub_dprintf ("video", "GOP: %d modes detected\n", gop->mode->max_mode);
-      for (mode = 0; mode < gop->mode->max_mode; mode++)
-       {
-         grub_efi_uintn_t size;
-         grub_efi_status_t status;
-        
-         status = efi_call_4 (gop->query_mode, gop, mode, &size, &info);
-         if (status)
-           {
-             info = 0;
-             break;
-           }
-
-         grub_dprintf ("video", "GOP: mode %d: %dx%d\n", mode, info->width,
-                       info->height);
-
-         bpp = grub_video_gop_get_bpp (info);
-         if (!bpp)
-           {
-             grub_dprintf ("video", "GOP: mode %d: incompatible pixel mode\n",
-                           mode);
-             continue;
-           }
-
-         grub_dprintf ("video", "GOP: mode %d: depth %d\n", mode, bpp);
-
-         if (!(((info->width == width && info->height == height)
-               || (width == 0 && height == 0))
-               && (bpp == depth || depth == 0)))
-           {
-             grub_dprintf ("video", "GOP: mode %d: rejected\n", mode);
-             continue;
-           }
-
-         if (best_volume < ((unsigned long long) info->width)
-             * ((unsigned long long) info->height)
-             * ((unsigned long long) bpp))
-           {
-             best_volume = ((unsigned long long) info->width)
-               * ((unsigned long long) info->height)
-               * ((unsigned long long) bpp);
-             best_mode = mode;
-           }
-         found = 1;
-       }
-    }
-
-  if (!found)
-    {
-      grub_dprintf ("video", "GOP: no mode found\n");
-      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found");
-    }
-
-  if (best_mode != gop->mode->mode)
-    {
-      if (!restore_needed)
-       {
-         old_mode = gop->mode->mode;
-         restore_needed = 1;
-       }
-      efi_call_2 (gop->set_mode, gop, best_mode);
-    }
-
-  info = gop->mode->info;
-
-  err = grub_video_gop_fill_mode_info (info, &framebuffer.mode_info);
-  if (err)
-    {
-      grub_dprintf ("video", "GOP: couldn't fill mode info\n");
-      return err;
-    }
-
-  framebuffer.ptr = (void *) (grub_addr_t) gop->mode->fb_base;
-
-  grub_dprintf ("video", "GOP: initialising FB @ %p %dx%dx%d\n",
-               framebuffer.ptr, framebuffer.mode_info.width,
-               framebuffer.mode_info.height, framebuffer.mode_info.bpp);
-  err = grub_video_fb_create_render_target_from_pointer
-    (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr);
-
-  if (err)
-    {
-      grub_dprintf ("video", "GOP: Couldn't create FB target\n");
-      return err;
-    }
-  err = grub_video_fb_set_active_render_target (framebuffer.render_target);
-  if (err)
-    {
-      grub_dprintf ("video", "GOP: Couldn't set FB target\n");
-      return err;
-    }
-  err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
-                                  grub_video_fbstd_colors);
-
-  if (err)
-    grub_dprintf ("video", "GOP: Couldn't set palette\n");
-  else
-    grub_dprintf ("video", "GOP: Success\n");
-  return err;
-}
-
-static grub_err_t
-grub_video_gop_swap_buffers (void)
-{
-  /* TODO: Implement buffer swapping.  */
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_gop_set_active_render_target (struct grub_video_render_target *target)
-{
-  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
-    target = framebuffer.render_target;
-
-  return grub_video_fb_set_active_render_target (target);
-}
-
-static grub_err_t
-grub_video_gop_get_info_and_fini (struct grub_video_mode_info *mode_info,
-                                 void **framebuf)
-{
-  grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
-  *framebuf = (char *) framebuffer.ptr;
-
-  grub_video_fb_fini ();
-
-  return GRUB_ERR_NONE;
-}
-
-static struct grub_video_adapter grub_video_gop_adapter =
-  {
-    .name = "EFI GOP driver",
-    .id = GRUB_VIDEO_DRIVER_EFI_GOP,
-
-    .init = grub_video_gop_init,
-    .fini = grub_video_gop_fini,
-    .setup = grub_video_gop_setup,
-    .get_info = grub_video_fb_get_info,
-    .get_info_and_fini = grub_video_gop_get_info_and_fini,
-    .set_palette = grub_video_fb_set_palette,
-    .get_palette = grub_video_fb_get_palette,
-    .set_viewport = grub_video_fb_set_viewport,
-    .get_viewport = grub_video_fb_get_viewport,
-    .map_color = grub_video_fb_map_color,
-    .map_rgb = grub_video_fb_map_rgb,
-    .map_rgba = grub_video_fb_map_rgba,
-    .unmap_color = grub_video_fb_unmap_color,
-    .fill_rect = grub_video_fb_fill_rect,
-    .blit_bitmap = grub_video_fb_blit_bitmap,
-    .blit_render_target = grub_video_fb_blit_render_target,
-    .scroll = grub_video_fb_scroll,
-    .swap_buffers = grub_video_gop_swap_buffers,
-    .create_render_target = grub_video_fb_create_render_target,
-    .delete_render_target = grub_video_fb_delete_render_target,
-    .set_active_render_target = grub_video_gop_set_active_render_target,
-    .get_active_render_target = grub_video_fb_get_active_render_target,
-
-    .next = 0
-  };
-
-GRUB_MOD_INIT(efi_gop)
-{
-  if (check_protocol ())
-    grub_video_register (&grub_video_gop_adapter);
-}
-
-GRUB_MOD_FINI(efi_gop)
-{
-  if (restore_needed)
-    {
-      efi_call_2 (gop->set_mode, gop, old_mode);
-      restore_needed = 0;
-    }
-  if (gop)
-    grub_video_unregister (&grub_video_gop_adapter);
-}
diff --git a/video/efi_uga.c b/video/efi_uga.c
deleted file mode 100644 (file)
index eb4e6b4..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define grub_video_render_target grub_video_fbrender_target
-
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/video.h>
-#include <grub/video_fb.h>
-#include <grub/efi/api.h>
-#include <grub/efi/efi.h>
-#include <grub/efi/uga_draw.h>
-#include <grub/pci.h>
-
-static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
-static struct grub_efi_uga_draw_protocol *uga;
-static grub_uint32_t uga_fb;
-static grub_uint32_t uga_pitch;
-
-static struct
-{
-  struct grub_video_mode_info mode_info;
-  struct grub_video_render_target *render_target;
-  grub_uint8_t *ptr;
-} framebuffer;
-
-#define RGB_MASK       0xffffff
-#define RGB_MAGIC      0x121314
-#define LINE_MIN       800
-#define LINE_MAX       4096
-#define FBTEST_STEP    (0x10000 >> 2)
-#define FBTEST_COUNT   8
-
-static int
-find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
-{
-  grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base;
-  int i;
-
-  for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP)
-    {
-      if ((*base & RGB_MASK) == RGB_MAGIC)
-       {
-         int j;
-
-         for (j = LINE_MIN; j <= LINE_MAX; j++)
-           {
-             if ((base[j] & RGB_MASK) == RGB_MAGIC)
-               {
-                 *fb_base = (grub_uint32_t) (grub_target_addr_t) base;
-                 *line_len = j << 2;
-
-                 return 1;
-               }
-           }
-
-         break;
-       }
-    }
-
-  return 0;
-}
-
-static int
-find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
-{
-  int found = 0;
-
-  auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
-                                      grub_pci_id_t pciid);
-
-  int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
-                                 grub_pci_id_t pciid)
-    {
-      grub_pci_address_t addr;
-
-      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
-      if (grub_pci_read (addr) >> 24 == 0x3)
-       {
-         int i;
-
-         grub_dprintf ("fb", "Display controller: %d:%d.%d\nDevice id: %x\n",
-                       grub_pci_get_bus (dev), grub_pci_get_device (dev),
-                       grub_pci_get_function (dev), pciid);
-         addr += 8;
-         for (i = 0; i < 6; i++, addr += 4)
-           {
-             grub_uint32_t old_bar1, old_bar2, type;
-             grub_uint64_t base64;
-
-             old_bar1 = grub_pci_read (addr);
-             if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
-               continue;
-
-             type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
-             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
-               {
-                 if (i == 5)
-                   break;
-
-                 old_bar2 = grub_pci_read (addr + 4);
-               }
-             else
-               old_bar2 = 0;
-
-             base64 = old_bar2;
-             base64 <<= 32;
-             base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
-
-             grub_dprintf ("fb", "%s(%d): 0x%llx\n",
-                           ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
-                           "VMEM" : "MMIO"), i,
-                          (unsigned long long) base64);
-
-             if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found))
-               {
-                 *fb_base = base64;
-                 if (find_line_len (fb_base, line_len))
-                   found++;
-               }
-
-             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
-               {
-                 i++;
-                 addr += 4;
-               }
-           }
-       }
-
-      return found;
-    }
-
-  grub_pci_iterate (find_card);
-  return found;
-}
-
-static int
-check_protocol (void)
-{
-  grub_efi_uga_draw_protocol_t *c;
-
-  c = grub_efi_locate_protocol (&uga_draw_guid, 0);
-  if (c)
-    {
-      grub_uint32_t width, height, depth, rate, pixel;
-      int ret;
-
-      if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate))
-       return 0;
-
-      grub_efi_set_text_mode (0);
-      pixel = RGB_MAGIC;
-      efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel,
-                  GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0);
-      ret = find_framebuf (&uga_fb, &uga_pitch);
-      grub_efi_set_text_mode (1);
-
-      if (ret)
-       {
-         uga = c;
-         return 1;
-       }
-    }
-
-  return 0;
-}
-
-static grub_err_t
-grub_video_uga_init (void)
-{
-  grub_memset (&framebuffer, 0, sizeof(framebuffer));
-  return grub_video_fb_init ();
-}
-
-static grub_err_t
-grub_video_uga_fini (void)
-{
-  return grub_video_fb_fini ();
-}
-
-static grub_err_t
-grub_video_uga_setup (unsigned int width, unsigned int height,
-                     unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused)))
-{
-  unsigned int depth;
-  int found = 0;
-
-  depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
-    >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
-
-  {
-    grub_uint32_t w;
-    grub_uint32_t h;
-    grub_uint32_t d;
-    grub_uint32_t r;
-
-    if ((! efi_call_5 (uga->get_mode, uga, &w, &h, &d, &r)) &&
-       ((! width) || (width == w)) &&
-       ((! height) || (height == h)) &&
-       ((! depth) || (depth == d)))
-      {
-       framebuffer.mode_info.width = w;
-       framebuffer.mode_info.height = h;
-       framebuffer.mode_info.pitch = uga_pitch;
-       framebuffer.ptr = (grub_uint8_t *) (grub_target_addr_t) uga_fb;
-
-       found = 1;
-      }
-  }
-
-  if (found)
-    {
-      grub_err_t err;
-
-      framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
-      framebuffer.mode_info.bpp = 32;
-      framebuffer.mode_info.bytes_per_pixel = 4;
-      framebuffer.mode_info.number_of_colors = 256; /* TODO: fix me.  */
-      framebuffer.mode_info.red_mask_size = 8;
-      framebuffer.mode_info.red_field_pos = 16;
-      framebuffer.mode_info.green_mask_size = 8;
-      framebuffer.mode_info.green_field_pos = 8;
-      framebuffer.mode_info.blue_mask_size = 8;
-      framebuffer.mode_info.blue_field_pos = 0;
-      framebuffer.mode_info.reserved_mask_size = 8;
-      framebuffer.mode_info.reserved_field_pos = 24;
-
-      framebuffer.mode_info.blit_format =
-       grub_video_get_blit_format (&framebuffer.mode_info);
-
-      err = grub_video_fb_create_render_target_from_pointer
-       (&framebuffer.render_target,
-        &framebuffer.mode_info,
-        framebuffer.ptr);
-
-      if (err)
-       return err;
-
-      err = grub_video_fb_set_active_render_target
-       (framebuffer.render_target);
-
-      if (err)
-       return err;
-
-      err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
-                                      grub_video_fbstd_colors);
-
-      return err;
-    }
-
-  return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found");
-}
-
-static grub_err_t
-grub_video_uga_swap_buffers (void)
-{
-  /* TODO: Implement buffer swapping.  */
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_uga_set_active_render_target (struct grub_video_render_target *target)
-{
-  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
-    target = framebuffer.render_target;
-
-  return grub_video_fb_set_active_render_target (target);
-}
-
-static grub_err_t
-grub_video_uga_get_info_and_fini (struct grub_video_mode_info *mode_info,
-                                 void **framebuf)
-{
-  grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
-  *framebuf = (char *) framebuffer.ptr;
-
-  grub_video_fb_fini ();
-
-  return GRUB_ERR_NONE;
-}
-
-static struct grub_video_adapter grub_video_uga_adapter =
-  {
-    .name = "EFI UGA driver",
-    .id = GRUB_VIDEO_DRIVER_EFI_UGA,
-
-    .init = grub_video_uga_init,
-    .fini = grub_video_uga_fini,
-    .setup = grub_video_uga_setup,
-    .get_info = grub_video_fb_get_info,
-    .get_info_and_fini = grub_video_uga_get_info_and_fini,
-    .set_palette = grub_video_fb_set_palette,
-    .get_palette = grub_video_fb_get_palette,
-    .set_viewport = grub_video_fb_set_viewport,
-    .get_viewport = grub_video_fb_get_viewport,
-    .map_color = grub_video_fb_map_color,
-    .map_rgb = grub_video_fb_map_rgb,
-    .map_rgba = grub_video_fb_map_rgba,
-    .unmap_color = grub_video_fb_unmap_color,
-    .fill_rect = grub_video_fb_fill_rect,
-    .blit_bitmap = grub_video_fb_blit_bitmap,
-    .blit_render_target = grub_video_fb_blit_render_target,
-    .scroll = grub_video_fb_scroll,
-    .swap_buffers = grub_video_uga_swap_buffers,
-    .create_render_target = grub_video_fb_create_render_target,
-    .delete_render_target = grub_video_fb_delete_render_target,
-    .set_active_render_target = grub_video_uga_set_active_render_target,
-    .get_active_render_target = grub_video_fb_get_active_render_target,
-  };
-
-GRUB_MOD_INIT(efi_uga)
-{
-  if (check_protocol ())
-    grub_video_register (&grub_video_uga_adapter);
-}
-
-GRUB_MOD_FINI(efi_uga)
-{
-  if (uga)
-    grub_video_unregister (&grub_video_uga_adapter);
-}
diff --git a/video/fb/fbblit.c b/video/fb/fbblit.c
deleted file mode 100644 (file)
index 15797be..0000000
+++ /dev/null
@@ -1,1420 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* SPECIAL NOTES!
-
-   Please note following when reading the code below:
-
-   - In this driver we assume that every memory can be accessed by same memory
-   bus.  If there are different address spaces do not use this code as a base
-   code for other archs.
-
-   - Every function in this code assumes that bounds checking has been done in
-   previous phase and they are opted out in here.  */
-
-#include <grub/video_fb.h>
-#include <grub/fbblit.h>
-#include <grub/fbutil.h>
-#include <grub/misc.h>
-#include <grub/types.h>
-#include <grub/video.h>
-
-/* Generic replacing blitter (slow).  Works for every supported format.  */
-void
-grub_video_fbblit_replace (struct grub_video_fbblit_info *dst,
-                          struct grub_video_fbblit_info *src,
-                          int x, int y, int width, int height,
-                          int offset_x, int offset_y)
-{
-  int i;
-  int j;
-  grub_uint8_t src_red;
-  grub_uint8_t src_green;
-  grub_uint8_t src_blue;
-  grub_uint8_t src_alpha;
-  grub_video_color_t src_color;
-  grub_video_color_t dst_color;
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-       {
-         src_color = get_pixel (src, i + offset_x, j + offset_y);
-
-         grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
-                                        &src_blue, &src_alpha);
-
-         dst_color = grub_video_fb_map_rgba (src_red, src_green,
-                                             src_blue, src_alpha);
-
-         set_pixel (dst, x + i, y + j, dst_color);
-       }
-    }
-}
-
-/* Block copy replacing blitter.  Works with modes multiple of 8 bits.  */
-void
-grub_video_fbblit_replace_directN (struct grub_video_fbblit_info *dst,
-                                  struct grub_video_fbblit_info *src,
-                                  int x, int y, int width, int height,
-                                  int offset_x, int offset_y)
-{
-  int j;
-  grub_uint32_t *srcptr;
-  grub_uint32_t *dstptr;
-  int bpp;
-
-  bpp = src->mode_info->bytes_per_pixel;
-
-  for (j = 0; j < height; j++)
-    {
-      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
-      dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
-
-      grub_memmove (dstptr, srcptr, width * bpp);
-    }
-}
-
-/* Optimized replacing blitter for 1-bit to 32bit.  */
-void
-grub_video_fbblit_replace_32bit_1bit (struct grub_video_fbblit_info *dst,
-                                     struct grub_video_fbblit_info *src,
-                                     int x, int y,
-                                     int width, int height,
-                                     int offset_x, int offset_y)
-{
-  int i;
-  int j;
-  grub_uint8_t *srcptr;
-  grub_uint8_t *dstptr;
-  grub_uint8_t srcmask;
-  unsigned int dstrowskip;
-  unsigned int srcrowskipbyte, srcrowskipbit;
-  grub_uint32_t fgcolor, bgcolor;
-  int bit_index;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-  srcrowskipbyte = (src->mode_info->width - width) >> 3;
-  srcrowskipbit = (src->mode_info->width - width) & 7;
-
-  bit_index = offset_y * src->mode_info->width + offset_x;
-  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
-  srcmask = 1 << (~bit_index & 7);
-  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
-                                   src->mode_info->fg_green,
-                                   src->mode_info->fg_blue,
-                                   src->mode_info->fg_alpha);
-
-  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
-                                   src->mode_info->bg_green,
-                                   src->mode_info->bg_blue,
-                                   src->mode_info->bg_alpha);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-         if (*srcptr & srcmask)
-           *(grub_uint32_t *) dstptr = fgcolor;
-         else
-           *(grub_uint32_t *) dstptr = bgcolor;
-         srcmask >>= 1;
-         if (!srcmask)
-           {
-             srcptr++;
-             srcmask = 0x80;
-           }
-
-         dstptr += 4;
-        }
-
-      srcptr += srcrowskipbyte;
-      if (srcmask >> srcrowskipbit)
-       srcmask >>= srcrowskipbit;
-      else
-       {
-         srcptr++;
-         srcmask <<= 8 - srcrowskipbit;
-       }
-      dstptr += dstrowskip;
-    }
-}
-
-
-/* Optimized replacing blitter for 1-bit to 24-bit.  */
-void
-grub_video_fbblit_replace_24bit_1bit (struct grub_video_fbblit_info *dst,
-                                     struct grub_video_fbblit_info *src,
-                                     int x, int y,
-                                     int width, int height,
-                                     int offset_x, int offset_y)
-{
-  int i;
-  int j;
-  grub_uint8_t *srcptr;
-  grub_uint8_t *dstptr;
-  grub_uint8_t srcmask;
-  unsigned int dstrowskip;
-  unsigned int srcrowskipbyte, srcrowskipbit;
-  grub_uint32_t fgcolor, bgcolor;
-  int bit_index;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-  srcrowskipbyte = (src->mode_info->width - width) >> 3;
-  srcrowskipbit = (src->mode_info->width - width) & 7;
-
-  bit_index = offset_y * src->mode_info->width + offset_x;
-  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
-  srcmask = 1 << (~bit_index & 7);
-  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
-                                   src->mode_info->fg_green,
-                                   src->mode_info->fg_blue,
-                                   src->mode_info->fg_alpha);
-
-  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
-                                   src->mode_info->bg_green,
-                                   src->mode_info->bg_blue,
-                                   src->mode_info->bg_alpha);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width - 1; i++)
-        {
-         if (*srcptr & srcmask)
-           *(grub_uint32_t *) dstptr = fgcolor;
-         else
-           *(grub_uint32_t *) dstptr = bgcolor;
-         srcmask >>= 1;
-         if (!srcmask)
-           {
-             srcptr++;
-             srcmask = 0x80;
-           }
-
-         dstptr += 3;
-        }
-
-      if (*srcptr & srcmask)
-       {
-         *dstptr++ = fgcolor & 0xff;
-         *dstptr++ = (fgcolor & 0xff00) >> 8;
-         *dstptr++ = (fgcolor & 0xff0000) >> 16;
-       }
-      else
-       {
-         *dstptr++ = bgcolor & 0xff;
-         *dstptr++ = (bgcolor & 0xff00) >> 8;
-         *dstptr++ = (bgcolor & 0xff0000) >> 16;
-       }
-      srcmask >>= 1;
-      if (!srcmask)
-       {
-         srcptr++;
-         srcmask = 0x80;
-       }
-
-      srcptr += srcrowskipbyte;
-      if (srcmask >> srcrowskipbit)
-       srcmask >>= srcrowskipbit;
-      else
-       {
-         srcptr++;
-         srcmask <<= 8 - srcrowskipbit;
-       }
-      dstptr += dstrowskip;
-    }
-}
-
-/* Optimized replacing blitter for 1-bit to 16-bit.  */
-void
-grub_video_fbblit_replace_16bit_1bit (struct grub_video_fbblit_info *dst,
-                                     struct grub_video_fbblit_info *src,
-                                     int x, int y,
-                                     int width, int height,
-                                     int offset_x, int offset_y)
-{
-  int i;
-  int j;
-  grub_uint8_t *srcptr;
-  grub_uint8_t *dstptr;
-  grub_uint8_t srcmask;
-  unsigned int dstrowskip;
-  unsigned int srcrowskipbyte, srcrowskipbit;
-  grub_uint16_t fgcolor, bgcolor;
-  int bit_index;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-  srcrowskipbyte = (src->mode_info->width - width) >> 3;
-  srcrowskipbit = (src->mode_info->width - width) & 7;
-
-  bit_index = offset_y * src->mode_info->width + offset_x;
-  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
-  srcmask = 1 << (~bit_index & 7);
-  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
-                                   src->mode_info->fg_green,
-                                   src->mode_info->fg_blue,
-                                   src->mode_info->fg_alpha);
-
-  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
-                                   src->mode_info->bg_green,
-                                   src->mode_info->bg_blue,
-                                   src->mode_info->bg_alpha);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-         if (*srcptr & srcmask)
-           *(grub_uint16_t *) dstptr = fgcolor;
-         else
-           *(grub_uint16_t *) dstptr = bgcolor;
-         srcmask >>= 1;
-         if (!srcmask)
-           {
-             srcptr++;
-             srcmask = 0x80;
-           }
-
-         dstptr += 2;
-        }
-
-      srcptr += srcrowskipbyte;
-      if (srcmask >> srcrowskipbit)
-       srcmask >>= srcrowskipbit;
-      else
-       {
-         srcptr++;
-         srcmask <<= 8 - srcrowskipbit;
-       }
-      dstptr += dstrowskip;
-    }
-}
-
-/* Optimized replacing blitter for 1-bit to 8-bit.  */
-void
-grub_video_fbblit_replace_8bit_1bit (struct grub_video_fbblit_info *dst,
-                                     struct grub_video_fbblit_info *src,
-                                     int x, int y,
-                                     int width, int height,
-                                     int offset_x, int offset_y)
-{
-  int i;
-  int j;
-  grub_uint8_t *srcptr;
-  grub_uint8_t *dstptr;
-  grub_uint8_t srcmask;
-  unsigned int dstrowskip;
-  unsigned int srcrowskipbyte, srcrowskipbit;
-  grub_uint8_t fgcolor, bgcolor;
-  int bit_index;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-  srcrowskipbyte = (src->mode_info->width - width) >> 3;
-  srcrowskipbit = (src->mode_info->width - width) & 7;
-
-  bit_index = offset_y * src->mode_info->width + offset_x;
-  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
-  srcmask = 1 << (~bit_index & 7);
-  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
-                                   src->mode_info->fg_green,
-                                   src->mode_info->fg_blue,
-                                   src->mode_info->fg_alpha);
-
-  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
-                                   src->mode_info->bg_green,
-                                   src->mode_info->bg_blue,
-                                   src->mode_info->bg_alpha);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-         if (*srcptr & srcmask)
-           *(grub_uint8_t *) dstptr = fgcolor;
-         else
-           *(grub_uint8_t *) dstptr = bgcolor;
-         srcmask >>= 1;
-         if (!srcmask)
-           {
-             srcptr++;
-             srcmask = 0x80;
-           }
-
-         dstptr++;
-        }
-
-      srcptr += srcrowskipbyte;
-      if (srcmask >> srcrowskipbit)
-       srcmask >>= srcrowskipbit;
-      else
-       {
-         srcptr++;
-         srcmask <<= 8 - srcrowskipbit;
-       }
-      dstptr += dstrowskip;
-    }
-}
-
-/* Optimized replacing blitter for RGBX8888 to BGRX8888.  */
-void
-grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
-                                            struct grub_video_fbblit_info *src,
-                                            int x, int y,
-                                            int width, int height,
-                                            int offset_x, int offset_y)
-{
-  int i;
-  int j;
-  grub_uint8_t *srcptr;
-  grub_uint8_t *dstptr;
-  unsigned int srcrowskip;
-  unsigned int dstrowskip;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
-  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          grub_uint8_t r = *srcptr++;
-          grub_uint8_t g = *srcptr++;
-          grub_uint8_t b = *srcptr++;
-          grub_uint8_t a = *srcptr++;
-
-          *dstptr++ = b;
-          *dstptr++ = g;
-          *dstptr++ = r;
-          *dstptr++ = a;
-        }
-
-      srcptr += srcrowskip;
-      dstptr += dstrowskip;
-    }
-}
-
-/* Optimized replacing blitter for RGB888 to BGRX8888.  */
-void
-grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst,
-                                          struct grub_video_fbblit_info *src,
-                                          int x, int y,
-                                          int width, int height,
-                                          int offset_x, int offset_y)
-{
-  int i;
-  int j;
-  grub_uint8_t *srcptr;
-  grub_uint8_t *dstptr;
-  unsigned int srcrowskip;
-  unsigned int dstrowskip;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
-  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          grub_uint8_t r = *srcptr++;
-          grub_uint8_t g = *srcptr++;
-          grub_uint8_t b = *srcptr++;
-
-          *dstptr++ = b;
-          *dstptr++ = g;
-          *dstptr++ = r;
-
-          /* Set alpha component as opaque.  */
-          *dstptr++ = 255;
-        }
-
-      srcptr += srcrowskip;
-      dstptr += dstrowskip;
-    }
-}
-
-/* Optimized replacing blitter for RGBX8888 to BGR888.  */
-void
-grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst,
-                                          struct grub_video_fbblit_info *src,
-                                          int x, int y,
-                                          int width, int height,
-                                          int offset_x, int offset_y)
-{
-  grub_uint32_t *srcptr;
-  grub_uint8_t *dstptr;
-  unsigned int srcrowskip;
-  unsigned int dstrowskip;
-  int i;
-  int j;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
-  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          grub_uint32_t color;
-          grub_uint8_t sr;
-          grub_uint8_t sg;
-          grub_uint8_t sb;
-
-          color = *srcptr++;
-
-          sr = (color >> 0) & 0xFF;
-          sg = (color >> 8) & 0xFF;
-          sb = (color >> 16) & 0xFF;
-
-          *dstptr++ = sb;
-          *dstptr++ = sg;
-          *dstptr++ = sr;
-        }
-
-      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
-      dstptr += dstrowskip;
-    }
-}
-
-/* Optimized replacing blitter for RGB888 to BGR888.  */
-void
-grub_video_fbblit_replace_BGR888_RGB888 (struct grub_video_fbblit_info *dst,
-                                        struct grub_video_fbblit_info *src,
-                                        int x, int y,
-                                        int width, int height,
-                                        int offset_x, int offset_y)
-{
-  int i;
-  int j;
-  grub_uint8_t *srcptr;
-  grub_uint8_t *dstptr;
-  unsigned int srcrowskip;
-  unsigned int dstrowskip;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  srcptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
-  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          grub_uint8_t r = *srcptr++;
-          grub_uint8_t g = *srcptr++;
-          grub_uint8_t b = *srcptr++;
-
-          *dstptr++ = b;
-          *dstptr++ = g;
-          *dstptr++ = r;
-        }
-
-      srcptr += srcrowskip;
-      dstptr += dstrowskip;
-    }
-}
-
-/* Optimized replacing blitter for RGB888 to RGBX8888.  */
-void
-grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst,
-                                          struct grub_video_fbblit_info *src,
-                                          int x, int y,
-                                          int width, int height,
-                                          int offset_x, int offset_y)
-{
-  grub_uint32_t color;
-  int i;
-  int j;
-  grub_uint8_t *srcptr;
-  grub_uint32_t *dstptr;
-  unsigned int sr;
-  unsigned int sg;
-  unsigned int sb;
-
-  for (j = 0; j < height; j++)
-    {
-      srcptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
-      dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
-
-      for (i = 0; i < width; i++)
-        {
-          sr = *srcptr++;
-          sg = *srcptr++;
-          sb = *srcptr++;
-
-          /* Set alpha as opaque.  */
-          color = 0xFF000000 | (sb << 16) | (sg << 8) | sr;
-
-          *dstptr++ = color;
-        }
-    }
-}
-
-/* Optimized replacing blitter for RGBX8888 to RGB888.  */
-void
-grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst,
-                                          struct grub_video_fbblit_info *src,
-                                          int x, int y,
-                                          int width, int height,
-                                          int offset_x, int offset_y)
-{
-  grub_uint32_t color;
-  int i;
-  int j;
-  grub_uint32_t *srcptr;
-  grub_uint8_t *dstptr;
-  unsigned int sr;
-  unsigned int sg;
-  unsigned int sb;
-
-  for (j = 0; j < height; j++)
-    {
-      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
-      dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
-
-      for (i = 0; i < width; i++)
-       {
-         color = *srcptr++;
-
-         sr = (color >> 0) & 0xFF;
-         sg = (color >> 8) & 0xFF;
-         sb = (color >> 16) & 0xFF;
-
-         *dstptr++ = sr;
-         *dstptr++ = sg;
-         *dstptr++ = sb;
-       }
-    }
-}
-
-/* Optimized replacing blitter for RGBX8888 to indexed color.  */
-void
-grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
-                                         struct grub_video_fbblit_info *src,
-                                         int x, int y,
-                                         int width, int height,
-                                         int offset_x, int offset_y)
-{
-  grub_uint32_t color;
-  int i;
-  int j;
-  grub_uint32_t *srcptr;
-  grub_uint8_t *dstptr;
-  unsigned int sr;
-  unsigned int sg;
-  unsigned int sb;
-
-  for (j = 0; j < height; j++)
-    {
-      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
-      dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
-
-      for (i = 0; i < width; i++)
-       {
-         color = *srcptr++;
-
-         sr = (color >> 0) & 0xFF;
-         sg = (color >> 8) & 0xFF;
-         sb = (color >> 16) & 0xFF;
-
-         color = grub_video_fb_map_rgb(sr, sg, sb);
-         *dstptr++ = color & 0xFF;
-       }
-    }
-}
-
-/* Optimized replacing blitter for RGB888 to indexed color.  */
-void
-grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
-                                       struct grub_video_fbblit_info *src,
-                                       int x, int y,
-                                       int width, int height,
-                                       int offset_x, int offset_y)
-{
-  grub_uint32_t color;
-  int i;
-  int j;
-  grub_uint8_t *srcptr;
-  grub_uint8_t *dstptr;
-  unsigned int sr;
-  unsigned int sg;
-  unsigned int sb;
-
-  for (j = 0; j < height; j++)
-    {
-      srcptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
-      dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
-
-      for (i = 0; i < width; i++)
-        {
-          sr = *srcptr++;
-          sg = *srcptr++;
-          sb = *srcptr++;
-
-          color = grub_video_fb_map_rgb(sr, sg, sb);
-
-          *dstptr++ = color & 0xFF;
-        }
-    }
-}
-
-/* Generic blending blitter.  Works for every supported format.  */
-void
-grub_video_fbblit_blend (struct grub_video_fbblit_info *dst,
-                        struct grub_video_fbblit_info *src,
-                        int x, int y, int width, int height,
-                        int offset_x, int offset_y)
-{
-  int i;
-  int j;
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          grub_uint8_t src_red;
-          grub_uint8_t src_green;
-          grub_uint8_t src_blue;
-          grub_uint8_t src_alpha;
-          grub_uint8_t dst_red;
-          grub_uint8_t dst_green;
-          grub_uint8_t dst_blue;
-          grub_uint8_t dst_alpha;
-          grub_video_color_t src_color;
-          grub_video_color_t dst_color;
-
-          src_color = get_pixel (src, i + offset_x, j + offset_y);
-          grub_video_fb_unmap_color_int (src, src_color, &src_red, &src_green,
-                                        &src_blue, &src_alpha);
-
-          if (src_alpha == 0)
-            continue;
-
-          if (src_alpha == 255)
-            {
-              dst_color = grub_video_fb_map_rgba (src_red, src_green,
-                                                 src_blue, src_alpha);
-              set_pixel (dst, x + i, y + j, dst_color);
-              continue;
-            }
-
-          dst_color = get_pixel (dst, x + i, y + j);
-
-          grub_video_fb_unmap_color_int (dst, dst_color, &dst_red,
-                                        &dst_green, &dst_blue, &dst_alpha);
-
-          dst_red = (((src_red * src_alpha)
-                      + (dst_red * (255 - src_alpha))) / 255);
-          dst_green = (((src_green * src_alpha)
-                        + (dst_green * (255 - src_alpha))) / 255);
-          dst_blue = (((src_blue * src_alpha)
-                       + (dst_blue * (255 - src_alpha))) / 255);
-
-          dst_alpha = src_alpha;
-          dst_color = grub_video_fb_map_rgba (dst_red, dst_green, dst_blue,
-                                             dst_alpha);
-
-          set_pixel (dst, x + i, y + j, dst_color);
-        }
-    }
-}
-
-/* Optimized blending blitter for RGBA8888 to BGRA8888.  */
-void
-grub_video_fbblit_blend_BGRA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
-                                          struct grub_video_fbblit_info *src,
-                                          int x, int y,
-                                          int width, int height,
-                                          int offset_x, int offset_y)
-{
-  grub_uint32_t *srcptr;
-  grub_uint32_t *dstptr;
-  unsigned int srcrowskip;
-  unsigned int dstrowskip;
-  int i;
-  int j;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
-  dstptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          grub_uint32_t color;
-          unsigned int sr;
-          unsigned int sg;
-          unsigned int sb;
-          unsigned int a;
-          unsigned int dr;
-          unsigned int dg;
-          unsigned int db;
-
-          color = *srcptr++;
-
-          a = color >> 24;
-
-          if (a == 0)
-            {
-              /* Skip transparent source pixels.  */
-              dstptr++;
-              continue;
-            }
-
-          sr = (color >> 0) & 0xFF;
-          sg = (color >> 8) & 0xFF;
-          sb = (color >> 16) & 0xFF;
-
-          if (a == 255)
-            {
-              /* Opaque pixel shortcut.  */
-              dr = sr;
-              dg = sg;
-              db = sb;
-            }
-          else
-            {
-              /* General pixel color blending.  */
-              color = *dstptr;
-
-              dr = (color >> 16) & 0xFF;
-              dr = (dr * (255 - a) + sr * a) / 255;
-              dg = (color >> 8) & 0xFF;
-              dg = (dg * (255 - a) + sg * a) / 255;
-              db = (color >> 0) & 0xFF;
-              db = (db * (255 - a) + sb * a) / 255;
-            }
-
-          color = (a << 24) | (dr << 16) | (dg << 8) | db;
-
-          *dstptr++ = color;
-        }
-
-      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
-      dstptr = (grub_uint32_t *) (((grub_uint8_t *) dstptr) + dstrowskip);
-    }
-}
-
-/* Optimized blending blitter for RGBA8888 to BGR888.  */
-void
-grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst,
-                                        struct grub_video_fbblit_info *src,
-                                        int x, int y,
-                                        int width, int height,
-                                        int offset_x, int offset_y)
-{
-  grub_uint32_t *srcptr;
-  grub_uint8_t *dstptr;
-  unsigned int srcrowskip;
-  unsigned int dstrowskip;
-  int i;
-  int j;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width;
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  srcptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (src, offset_x, offset_y);
-  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          grub_uint32_t color;
-          unsigned int sr;
-          unsigned int sg;
-          unsigned int sb;
-          unsigned int a;
-          unsigned int dr;
-          unsigned int dg;
-          unsigned int db;
-
-          color = *srcptr++;
-
-          a = color >> 24;
-
-          if (a == 0)
-            {
-              /* Skip transparent source pixels.  */
-              dstptr += 3;
-              continue;
-            }
-
-          sr = (color >> 0) & 0xFF;
-          sg = (color >> 8) & 0xFF;
-          sb = (color >> 16) & 0xFF;
-
-          if (a == 255)
-            {
-              /* Opaque pixel shortcut.  */
-              dr = sr;
-              dg = sg;
-              db = sb;
-            }
-          else
-            {
-              /* General pixel color blending.  */
-              color = *dstptr;
-
-              db = dstptr[0];
-              db = (db * (255 - a) + sb * a) / 255;
-              dg = dstptr[1];
-              dg = (dg * (255 - a) + sg * a) / 255;
-              dr = dstptr[2];
-              dr = (dr * (255 - a) + sr * a) / 255;
-            }
-
-          *dstptr++ = db;
-          *dstptr++ = dg;
-          *dstptr++ = dr;
-        }
-
-      srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip);
-      dstptr += dstrowskip;
-    }
-}
-
-/* Optimized blending blitter for RGBA888 to RGBA8888.  */
-void
-grub_video_fbblit_blend_RGBA8888_RGBA8888 (struct grub_video_fbblit_info *dst,
-                                          struct grub_video_fbblit_info *src,
-                                          int x, int y,
-                                          int width, int height,
-                                          int offset_x, int offset_y)
-{
-  grub_uint32_t color;
-  int i;
-  int j;
-  grub_uint32_t *srcptr;
-  grub_uint32_t *dstptr;
-  unsigned int sr;
-  unsigned int sg;
-  unsigned int sb;
-  unsigned int a;
-  unsigned int dr;
-  unsigned int dg;
-  unsigned int db;
-
-  for (j = 0; j < height; j++)
-    {
-      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
-      dstptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
-
-      for (i = 0; i < width; i++)
-        {
-          color = *srcptr++;
-
-          a = color >> 24;
-
-          if (a == 0)
-            {
-              dstptr++;
-              continue;
-            }
-
-          if (a == 255)
-            {
-              *dstptr++ = color;
-              continue;
-            }
-
-          sr = (color >> 0) & 0xFF;
-          sg = (color >> 8) & 0xFF;
-          sb = (color >> 16) & 0xFF;
-
-          color = *dstptr;
-
-          dr = (color >> 0) & 0xFF;
-          dg = (color >> 8) & 0xFF;
-          db = (color >> 16) & 0xFF;
-
-          dr = (dr * (255 - a) + sr * a) / 255;
-          dg = (dg * (255 - a) + sg * a) / 255;
-          db = (db * (255 - a) + sb * a) / 255;
-
-          color = (a << 24) | (db << 16) | (dg << 8) | dr;
-
-          *dstptr++ = color;
-        }
-    }
-}
-
-/* Optimized blending blitter for RGBA8888 to RGB888.  */
-void
-grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst,
-                                        struct grub_video_fbblit_info *src,
-                                        int x, int y,
-                                        int width, int height,
-                                        int offset_x, int offset_y)
-{
-  grub_uint32_t color;
-  int i;
-  int j;
-  grub_uint32_t *srcptr;
-  grub_uint8_t *dstptr;
-  unsigned int sr;
-  unsigned int sg;
-  unsigned int sb;
-  unsigned int a;
-  unsigned int dr;
-  unsigned int dg;
-  unsigned int db;
-
-  for (j = 0; j < height; j++)
-    {
-      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
-      dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
-
-      for (i = 0; i < width; i++)
-        {
-          color = *srcptr++;
-
-          a = color >> 24;
-
-          if (a == 0)
-            {
-              dstptr += 3;
-              continue;
-            }
-
-          sr = (color >> 0) & 0xFF;
-          sg = (color >> 8) & 0xFF;
-          sb = (color >> 16) & 0xFF;
-
-          if (a == 255)
-            {
-              *dstptr++ = sr;
-              *dstptr++ = sg;
-              *dstptr++ = sb;
-
-              continue;
-            }
-
-          dr = dstptr[0];
-          dg = dstptr[1];
-          db = dstptr[2];
-
-          dr = (dr * (255 - a) + sr * a) / 255;
-          dg = (dg * (255 - a) + sg * a) / 255;
-          db = (db * (255 - a) + sb * a) / 255;
-
-          *dstptr++ = dr;
-          *dstptr++ = dg;
-          *dstptr++ = db;
-        }
-    }
-}
-
-/* Optimized blending blitter for RGBA8888 to indexed color.  */
-void
-grub_video_fbblit_blend_index_RGBA8888 (struct grub_video_fbblit_info *dst,
-                                       struct grub_video_fbblit_info *src,
-                                       int x, int y,
-                                       int width, int height,
-                                       int offset_x, int offset_y)
-{
-  grub_uint32_t color;
-  int i;
-  int j;
-  grub_uint32_t *srcptr;
-  grub_uint8_t *dstptr;
-  unsigned int sr;
-  unsigned int sg;
-  unsigned int sb;
-  unsigned int a;
-  unsigned char dr;
-  unsigned char dg;
-  unsigned char db;
-  unsigned char da;
-
-  for (j = 0; j < height; j++)
-    {
-      srcptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (src, offset_x, j + offset_y);
-      dstptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (dst, x, y + j);
-
-      for (i = 0; i < width; i++)
-        {
-          color = *srcptr++;
-
-          a = color >> 24;
-
-          if (a == 0)
-            {
-              dstptr++;
-              continue;
-            }
-
-          sr = (color >> 0) & 0xFF;
-          sg = (color >> 8) & 0xFF;
-          sb = (color >> 16) & 0xFF;
-
-          if (a == 255)
-            {
-              color = grub_video_fb_map_rgb(sr, sg, sb);
-              *dstptr++ = color & 0xFF;
-              continue;
-            }
-
-          grub_video_fb_unmap_color_int (dst, *dstptr, &dr, &dg, &db, &da);
-
-          dr = (dr * (255 - a) + sr * a) / 255;
-          dg = (dg * (255 - a) + sg * a) / 255;
-          db = (db * (255 - a) + sb * a) / 255;
-
-          color = grub_video_fb_map_rgb(dr, dg, db);
-
-          *dstptr++ = color & 0xFF;
-        }
-    }
-}
-
-/* Optimized blending blitter for 1-bit to XXXA8888.  */
-void
-grub_video_fbblit_blend_XXXA8888_1bit (struct grub_video_fbblit_info *dst,
-                                      struct grub_video_fbblit_info *src,
-                                      int x, int y,
-                                      int width, int height,
-                                      int offset_x, int offset_y)
-{
-  int i;
-  int j;
-  grub_uint8_t *srcptr;
-  grub_uint8_t *dstptr;
-  grub_uint8_t srcmask;
-  unsigned int dstrowskip;
-  unsigned int srcrowskipbyte, srcrowskipbit;
-  grub_uint32_t fgcolor, bgcolor;
-  int bit_index;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-  srcrowskipbyte = (src->mode_info->width - width) >> 3;
-  srcrowskipbit = (src->mode_info->width - width) & 7;
-
-  bit_index = offset_y * src->mode_info->width + offset_x;
-  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
-  srcmask = 1 << (~bit_index & 7);
-  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
-                                   src->mode_info->fg_green,
-                                   src->mode_info->fg_blue,
-                                   src->mode_info->fg_alpha);
-
-  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
-                                   src->mode_info->bg_green,
-                                   src->mode_info->bg_blue,
-                                   src->mode_info->bg_alpha);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-         grub_uint32_t color;
-         grub_uint8_t a;
-
-         if (*srcptr & srcmask)
-           {
-             color = fgcolor;
-             a = src->mode_info->fg_alpha;
-           }
-         else
-           {
-             color = bgcolor;
-             a = src->mode_info->bg_alpha;
-           }
-
-         if (a == 255)
-           *(grub_uint32_t *) dstptr = color;
-         else if (a != 0)
-           {
-             grub_uint8_t s1 = (color >> 0) & 0xFF;
-             grub_uint8_t s2 = (color >> 8) & 0xFF;
-             grub_uint8_t s3 = (color >> 16) & 0xFF;
-
-             grub_uint8_t d1 = (*(grub_uint32_t *) dstptr >> 0) & 0xFF;
-             grub_uint8_t d2 = (*(grub_uint32_t *) dstptr >> 8) & 0xFF;
-             grub_uint8_t d3 = (*(grub_uint32_t *) dstptr >> 16) & 0xFF;
-
-             d1 = (d1 * (255 - a) + s1 * a) / 255;
-             d2 = (d2 * (255 - a) + s2 * a) / 255;
-             d3 = (d3 * (255 - a) + s3 * a) / 255;
-
-             *(grub_uint32_t *) dstptr = (a << 24) | (d3 << 16) | (d2 << 8)
-               | d1;
-           }
-
-         srcmask >>= 1;
-         if (!srcmask)
-           {
-             srcptr++;
-             srcmask = 0x80;
-           }
-
-         dstptr += 4;
-        }
-
-      srcptr += srcrowskipbyte;
-      if (srcmask >> srcrowskipbit)
-       srcmask >>= srcrowskipbit;
-      else
-       {
-         srcptr++;
-         srcmask <<= 8 - srcrowskipbit;
-       }
-      dstptr += dstrowskip;
-    }
-}
-
-/* Optimized blending blitter for 1-bit to XXX888.  */
-void
-grub_video_fbblit_blend_XXX888_1bit (struct grub_video_fbblit_info *dst,
-                                    struct grub_video_fbblit_info *src,
-                                    int x, int y,
-                                    int width, int height,
-                                    int offset_x, int offset_y)
-{
-  int i;
-  int j;
-  grub_uint8_t *srcptr;
-  grub_uint8_t *dstptr;
-  grub_uint8_t srcmask;
-  unsigned int dstrowskip;
-  unsigned int srcrowskipbyte, srcrowskipbit;
-  grub_uint32_t fgcolor, bgcolor;
-  int bit_index;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-  srcrowskipbyte = (src->mode_info->width - width) >> 3;
-  srcrowskipbit = (src->mode_info->width - width) & 7;
-
-  bit_index = offset_y * src->mode_info->width + offset_x;
-  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
-  srcmask = 1 << (~bit_index & 7);
-  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
-                                   src->mode_info->fg_green,
-                                   src->mode_info->fg_blue,
-                                   src->mode_info->fg_alpha);
-
-  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
-                                   src->mode_info->bg_green,
-                                   src->mode_info->bg_blue,
-                                   src->mode_info->bg_alpha);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-         grub_uint32_t color;
-         grub_uint8_t a;
-         if (*srcptr & srcmask)
-           {
-             color = fgcolor;
-             a = src->mode_info->fg_alpha;
-           }
-         else
-           {
-             color = bgcolor;
-             a = src->mode_info->bg_alpha;
-           }
-
-         if (a == 255)
-           {
-             ((grub_uint8_t *) dstptr)[0] = color & 0xff;
-             ((grub_uint8_t *) dstptr)[1] = (color & 0xff00) >> 8;
-             ((grub_uint8_t *) dstptr)[2] = (color & 0xff0000) >> 16;
-           }
-         else if (a != 0)
-           {
-             grub_uint8_t s1 = (color >> 0) & 0xFF;
-             grub_uint8_t s2 = (color >> 8) & 0xFF;
-             grub_uint8_t s3 = (color >> 16) & 0xFF;
-
-             grub_uint8_t d1 = (*(grub_uint32_t *) dstptr >> 0) & 0xFF;
-             grub_uint8_t d2 = (*(grub_uint32_t *) dstptr >> 8) & 0xFF;
-             grub_uint8_t d3 = (*(grub_uint32_t *) dstptr >> 16) & 0xFF;
-
-             ((grub_uint8_t *) dstptr)[0] = (d1 * (255 - a) + s1 * a) / 255;
-             ((grub_uint8_t *) dstptr)[1] = (d2 * (255 - a) + s2 * a) / 255;
-             ((grub_uint8_t *) dstptr)[2] = (d3 * (255 - a) + s3 * a) / 255;
-           }
-
-         srcmask >>= 1;
-         if (!srcmask)
-           {
-             srcptr++;
-             srcmask = 0x80;
-           }
-
-         dstptr += 3;
-        }
-
-      srcptr += srcrowskipbyte;
-      if (srcmask >> srcrowskipbit)
-       srcmask >>= srcrowskipbit;
-      else
-       {
-         srcptr++;
-         srcmask <<= 8 - srcrowskipbit;
-       }
-      dstptr += dstrowskip;
-    }
-}
-
-/* Optimized blending blitter for 1-bit to XXX888.  */
-void
-grub_video_fbblit_blend_XXX565_1bit (struct grub_video_fbblit_info *dst,
-                                    struct grub_video_fbblit_info *src,
-                                    int x, int y,
-                                    int width, int height,
-                                    int offset_x, int offset_y)
-{
-  int i;
-  int j;
-  grub_uint8_t *srcptr;
-  grub_uint8_t *dstptr;
-  grub_uint8_t srcmask;
-  unsigned int dstrowskip;
-  unsigned int srcrowskipbyte, srcrowskipbit;
-  grub_uint16_t fgcolor, bgcolor;
-  int bit_index;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-  srcrowskipbyte = (src->mode_info->width - width) >> 3;
-  srcrowskipbit = (src->mode_info->width - width) & 7;
-
-  bit_index = offset_y * src->mode_info->width + offset_x;
-  srcptr = (grub_uint8_t *) src->data + (bit_index >> 3);
-  srcmask = 1 << (~bit_index & 7);
-  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  fgcolor = grub_video_fb_map_rgba (src->mode_info->fg_red,
-                                   src->mode_info->fg_green,
-                                   src->mode_info->fg_blue,
-                                   src->mode_info->fg_alpha);
-
-  bgcolor = grub_video_fb_map_rgba (src->mode_info->bg_red,
-                                   src->mode_info->bg_green,
-                                   src->mode_info->bg_blue,
-                                   src->mode_info->bg_alpha);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-         grub_uint32_t color;
-         grub_uint8_t a;
-         if (*srcptr & srcmask)
-           {
-             color = fgcolor;
-             a = src->mode_info->fg_alpha;
-           }
-         else
-           {
-             color = bgcolor;
-             a = src->mode_info->bg_alpha;
-           }
-
-         if (a == 255)
-           *(grub_uint16_t *) dstptr = color;
-         else if (a != 0)
-           {
-             grub_uint8_t s1 = (color >> 0) & 0x1F;
-             grub_uint8_t s2 = (color >> 5) & 0x3F;
-             grub_uint8_t s3 = (color >> 11) & 0x1F;
-
-             grub_uint8_t d1 = (*(grub_uint16_t *) dstptr >> 0) & 0x1F;
-             grub_uint8_t d2 = (*(grub_uint16_t *) dstptr >> 5) & 0x3F;
-             grub_uint8_t d3 = (*(grub_uint16_t *) dstptr >> 11) & 0x1F;
-
-             d1 = (d1 * (255 - a) + s1 * a) / 255;
-             d2 = (d2 * (255 - a) + s2 * a) / 255;
-             d3 = (d3 * (255 - a) + s3 * a) / 255;
-
-             *(grub_uint16_t *) dstptr = (d1 & 0x1f) | ((d2 & 0x3f) << 5)
-               | ((d3 & 0x1f) << 11);
-           }
-
-         srcmask >>= 1;
-         if (!srcmask)
-           {
-             srcptr++;
-             srcmask = 0x80;
-           }
-
-         dstptr += 2;
-        }
-
-      srcptr += srcrowskipbyte;
-      if (srcmask >> srcrowskipbit)
-       srcmask >>= srcrowskipbit;
-      else
-       {
-         srcptr++;
-         srcmask <<= 8 - srcrowskipbit;
-       }
-      dstptr += dstrowskip;
-    }
-}
diff --git a/video/fb/fbfill.c b/video/fb/fbfill.c
deleted file mode 100644 (file)
index a4ca7c2..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* SPECIAL NOTES!
-
-   Please note following when reading the code below:
-
-   - In this driver we assume that every memory can be accessed by same memory
-     bus.  If there are different address spaces do not use this code as a base
-     code for other archs.
-
-   - Every function in this code assumes that bounds checking has been done in
-     previous phase and they are opted out in here.  */
-
-#include <grub/video_fb.h>
-#include <grub/fbfill.h>
-#include <grub/fbutil.h>
-#include <grub/types.h>
-#include <grub/video.h>
-
-/* Generic filler that works for every supported mode.  */
-void
-grub_video_fbfill (struct grub_video_fbblit_info *dst,
-                  grub_video_color_t color, int x, int y,
-                  int width, int height)
-{
-  int i;
-  int j;
-
-  for (j = 0; j < height; j++)
-    for (i = 0; i < width; i++)
-      set_pixel (dst, x + i, y + j, color);
-}
-
-/* Optimized filler for direct color 32 bit modes.  It is assumed that color
-   is already mapped to destination format.  */
-void
-grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst,
-                           grub_video_color_t color, int x, int y,
-                           int width, int height)
-{
-  int i;
-  int j;
-  grub_uint32_t *dstptr;
-  grub_size_t rowskip;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  /* Get the start address.  */
-  dstptr = (grub_uint32_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        *dstptr++ = color;
-
-      /* Advance the dest pointer to the right location on the next line.  */
-      dstptr = (grub_uint32_t *) (((char *) dstptr) + rowskip);
-    }
-}
-
-/* Optimized filler for direct color 24 bit modes.  It is assumed that color
-   is already mapped to destination format.  */
-void
-grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst,
-                           grub_video_color_t color, int x, int y,
-                           int width, int height)
-{
-  int i;
-  int j;
-  grub_size_t rowskip;
-  grub_uint8_t *dstptr;
-  grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
-  grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
-  grub_uint8_t fill2 = (grub_uint8_t)((color >> 16) & 0xFF);
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  /* Get the start address.  */
-  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          *dstptr++ = fill0;
-          *dstptr++ = fill1;
-          *dstptr++ = fill2;
-        }
-
-      /* Advance the dest pointer to the right location on the next line.  */
-      dstptr += rowskip;
-    }
-}
-
-/* Optimized filler for direct color 16 bit modes.  It is assumed that color
-   is already mapped to destination format.  */
-void
-grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst,
-                           grub_video_color_t color, int x, int y,
-                           int width, int height)
-{
-  int i;
-  int j;
-  grub_size_t rowskip;
-  grub_uint8_t *dstptr;
-  grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
-  grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  /* Get the start address.  */
-  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        {
-          *dstptr++ = fill0;
-          *dstptr++ = fill1;
-        }
-
-      /* Advance the dest pointer to the right location on the next line.  */
-      dstptr += rowskip;
-    }
-}
-
-/* Optimized filler for index color.  It is assumed that color
-   is already mapped to destination format.  */
-void
-grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst,
-                          grub_video_color_t color, int x, int y,
-                          int width, int height)
-{
-  int i;
-  int j;
-  grub_size_t rowskip;
-  grub_uint8_t *dstptr;
-  grub_uint8_t fill = (grub_uint8_t)color & 0xFF;
-
-  /* Calculate the number of bytes to advance from the end of one line
-     to the beginning of the next line.  */
-  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
-
-  /* Get the start address.  */
-  dstptr = (grub_uint8_t *) grub_video_fb_get_video_ptr (dst, x, y);
-
-  for (j = 0; j < height; j++)
-    {
-      for (i = 0; i < width; i++)
-        *dstptr++ = fill;
-
-      /* Advance the dest pointer to the right location on the next line.  */
-      dstptr += rowskip;
-    }
-}
diff --git a/video/fb/fbutil.c b/video/fb/fbutil.c
deleted file mode 100644 (file)
index 511beaa..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* SPECIAL NOTES!
-
-   Please note following when reading the code below:
-
-   - In this driver we assume that every memory can be accessed by same memory
-     bus.  If there are different address spaces do not use this code as a base
-     code for other archs.
-
-   - Every function in this code assumes that bounds checking has been done in
-     previous phase and they are opted out in here.  */
-
-#include <grub/fbutil.h>
-#include <grub/types.h>
-#include <grub/video.h>
-
-grub_uint8_t *
-grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
-              unsigned int x, unsigned int y)
-{
-  grub_uint8_t *ptr = 0;
-
-  switch (source->mode_info->bpp)
-    {
-    case 32:
-      ptr = source->data + y * source->mode_info->pitch + x * 4;
-      break;
-
-    case 24:
-      ptr = source->data + y * source->mode_info->pitch + x * 3;
-      break;
-
-    case 16:
-    case 15:
-      ptr = source->data + y * source->mode_info->pitch + x * 2;
-      break;
-
-    case 8:
-      ptr = source->data + y * source->mode_info->pitch + x;
-      break;
-
-    case 1:
-      /* For 1-bit bitmaps, addressing needs to be done at the bit level
-         and it doesn't make sense, in general, to ask for a pointer
-         to a particular pixel's data.  */
-      break;
-    }
-
-  return ptr;
-}
-
-grub_video_color_t
-get_pixel (struct grub_video_fbblit_info *source,
-           unsigned int x, unsigned int y)
-{
-  grub_video_color_t color = 0;
-
-  switch (source->mode_info->bpp)
-    {
-    case 32:
-      color = *(grub_uint32_t *)grub_video_fb_get_video_ptr (source, x, y);
-      break;
-
-    case 24:
-      {
-        grub_uint8_t *ptr;
-        ptr = grub_video_fb_get_video_ptr (source, x, y);
-        color = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16);
-      }
-      break;
-
-    case 16:
-    case 15:
-      color = *(grub_uint16_t *)grub_video_fb_get_video_ptr (source, x, y);
-      break;
-
-    case 8:
-      color = *(grub_uint8_t *)grub_video_fb_get_video_ptr (source, x, y);
-      break;
-
-    case 1:
-      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
-        {
-          int bit_index = y * source->mode_info->width + x;
-          grub_uint8_t *ptr = source->data + bit_index / 8;
-          int bit_pos = 7 - bit_index % 8;
-          color = (*ptr >> bit_pos) & 0x01;
-        }
-      break;
-
-    default:
-      break;
-    }
-
-  return color;
-}
-
-void
-set_pixel (struct grub_video_fbblit_info *source,
-           unsigned int x, unsigned int y, grub_video_color_t color)
-{
-  switch (source->mode_info->bpp)
-    {
-    case 32:
-      {
-        grub_uint32_t *ptr;
-
-        ptr = (grub_uint32_t *)grub_video_fb_get_video_ptr (source, x, y);
-
-        *ptr = color;
-      }
-      break;
-
-    case 24:
-      {
-        grub_uint8_t *ptr;
-        grub_uint8_t *colorptr = (grub_uint8_t *)&color;
-
-        ptr = grub_video_fb_get_video_ptr (source, x, y);
-
-        ptr[0] = colorptr[0];
-        ptr[1] = colorptr[1];
-        ptr[2] = colorptr[2];
-      }
-      break;
-
-    case 16:
-    case 15:
-      {
-        grub_uint16_t *ptr;
-
-        ptr = (grub_uint16_t *)grub_video_fb_get_video_ptr (source, x, y);
-
-        *ptr = (grub_uint16_t) (color & 0xFFFF);
-      }
-      break;
-
-    case 8:
-      {
-        grub_uint8_t *ptr;
-
-        ptr = (grub_uint8_t *)grub_video_fb_get_video_ptr (source, x, y);
-
-        *ptr = (grub_uint8_t) (color & 0xFF);
-      }
-      break;
-
-    case 1:
-      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
-        {
-          int bit_index = y * source->mode_info->width + x;
-          grub_uint8_t *ptr = source->data + bit_index / 8;
-          int bit_pos = 7 - bit_index % 8;
-          *ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos);
-        }
-      break;
-
-    default:
-      break;
-    }
-}
diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c
deleted file mode 100644 (file)
index 9c5577b..0000000
+++ /dev/null
@@ -1,1289 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/video.h>
-#include <grub/video_fb.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/fbblit.h>
-#include <grub/fbfill.h>
-#include <grub/fbutil.h>
-#include <grub/bitmap.h>
-
-static struct grub_video_fbrender_target *render_target;
-struct grub_video_palette_data *palette;
-static unsigned int palette_size;
-
-/* Specify "standard" VGA palette, some video cards may
-   need this and this will also be used when using RGB modes.  */
-struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLORS] =
-  {
-    // {R, G, B, A}
-    {0x00, 0x00, 0x00, 0xFF}, // 0 = black
-    {0x00, 0x00, 0xA8, 0xFF}, // 1 = blue
-    {0x00, 0xA8, 0x00, 0xFF}, // 2 = green
-    {0x00, 0xA8, 0xA8, 0xFF}, // 3 = cyan
-    {0xA8, 0x00, 0x00, 0xFF}, // 4 = red
-    {0xA8, 0x00, 0xA8, 0xFF}, // 5 = magenta
-    {0xA8, 0x54, 0x00, 0xFF}, // 6 = brown
-    {0xA8, 0xA8, 0xA8, 0xFF}, // 7 = light gray
-
-    {0x54, 0x54, 0x54, 0xFF}, // 8 = dark gray
-    {0x54, 0x54, 0xFE, 0xFF}, // 9 = bright blue
-    {0x54, 0xFE, 0x54, 0xFF}, // 10 = bright green
-    {0x54, 0xFE, 0xFE, 0xFF}, // 11 = bright cyan
-    {0xFE, 0x54, 0x54, 0xFF}, // 12 = bright red
-    {0xFE, 0x54, 0xFE, 0xFF}, // 13 = bright magenta
-    {0xFE, 0xFE, 0x54, 0xFF}, // 14 = yellow
-    {0xFE, 0xFE, 0xFE, 0xFF}  // 15 = white
-  };
-
-grub_err_t
-grub_video_fb_init (void)
-{
-  grub_free (palette);
-  render_target = 0;
-  palette = 0;
-  palette_size = 0;
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_video_fb_fini (void)
-{
-  /* TODO: destroy render targets.  */
-
-  grub_free (palette);
-  render_target = 0;
-  palette = 0;
-  palette_size = 0;
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_video_fb_get_info (struct grub_video_mode_info *mode_info)
-{
-  /* Copy mode info from active render target.  */
-  grub_memcpy (mode_info, &render_target->mode_info,
-               sizeof (struct grub_video_mode_info));
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_video_fb_get_palette (unsigned int start, unsigned int count,
-                          struct grub_video_palette_data *palette_data)
-{
-  unsigned int i;
-
-  /* Assume that we know everything from index color palette.  */
-  for (i = 0; (i < count) && ((i + start) < palette_size); i++)
-    palette_data[i] = palette[start + i];
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_video_fb_set_palette (unsigned int start, unsigned int count,
-                          struct grub_video_palette_data *palette_data)
-{
-  unsigned i;
-  if (start + count > palette_size)
-    {
-      palette_size = start + count;
-      palette = grub_realloc (palette, sizeof (palette[0]) * palette_size);
-      if (!palette)
-       {
-         grub_video_fb_fini ();
-         return grub_errno;
-       }
-    }
-  for (i = 0; (i < count) && ((i + start) < palette_size); i++)
-    palette[start + i] = palette_data[i];
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_video_fb_set_viewport (unsigned int x, unsigned int y,
-                           unsigned int width, unsigned int height)
-{
-  /* Make sure viewport is withing screen dimensions.  If viewport was set
-     to be out of the region, mark its size as zero.  */
-  if (x > render_target->mode_info.width)
-    {
-      x = 0;
-      width = 0;
-    }
-
-  if (y > render_target->mode_info.height)
-    {
-      y = 0;
-      height = 0;
-    }
-
-  if (x + width > render_target->mode_info.width)
-    width = render_target->mode_info.width - x;
-
-  if (y + height > render_target->mode_info.height)
-    height = render_target->mode_info.height - y;
-
-  render_target->viewport.x = x;
-  render_target->viewport.y = y;
-  render_target->viewport.width = width;
-  render_target->viewport.height = height;
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_video_fb_get_viewport (unsigned int *x, unsigned int *y,
-                           unsigned int *width, unsigned int *height)
-{
-  if (x) *x = render_target->viewport.x;
-  if (y) *y = render_target->viewport.y;
-  if (width) *width = render_target->viewport.width;
-  if (height) *height = render_target->viewport.height;
-
-  return GRUB_ERR_NONE;
-}
-
-/* Maps color name to target optimized color format.  */
-grub_video_color_t
-grub_video_fb_map_color (grub_uint32_t color_name)
-{
-  /* TODO: implement color theme mapping code.  */
-
-  if (color_name < palette_size)
-    {
-      if ((render_target->mode_info.mode_type
-           & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
-        return color_name;
-      else
-        {
-          grub_video_color_t color;
-
-          color = grub_video_fb_map_rgb (palette[color_name].r,
-                                        palette[color_name].g,
-                                        palette[color_name].b);
-
-          return color;
-        }
-    }
-
-  return 0;
-}
-
-/* Maps RGB to target optimized color format.  */
-grub_video_color_t
-grub_video_fb_map_rgb (grub_uint8_t red, grub_uint8_t green,
-                      grub_uint8_t blue)
-{
-  if ((render_target->mode_info.mode_type
-       & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
-    {
-      int minindex = 0;
-      int delta = 0;
-      int tmp;
-      int val;
-      unsigned i;
-
-      /* Find best matching color.  */
-      for (i = 0; i < palette_size; i++)
-        {
-          val = palette[i].r - red;
-          tmp = val * val;
-          val = palette[i].g - green;
-          tmp += val * val;
-          val = palette[i].b - blue;
-          tmp += val * val;
-
-          if (i == 0)
-            delta = tmp;
-
-          if (tmp < delta)
-            {
-              delta = tmp;
-              minindex = i;
-              if (tmp == 0)
-                break;
-            }
-        }
-
-      return minindex;
-    }
-  else if ((render_target->mode_info.mode_type
-            & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
-    {
-       if (red == render_target->mode_info.fg_red
-           && green == render_target->mode_info.fg_green
-           && blue == render_target->mode_info.fg_blue)
-         return 1;
-       else
-         return 0;
-    }
-  else
-    {
-      grub_uint32_t value;
-      grub_uint8_t alpha = 255; /* Opaque color.  */
-
-      red >>= 8 - render_target->mode_info.red_mask_size;
-      green >>= 8 - render_target->mode_info.green_mask_size;
-      blue >>= 8 - render_target->mode_info.blue_mask_size;
-      alpha >>= 8 - render_target->mode_info.reserved_mask_size;
-
-      value = red << render_target->mode_info.red_field_pos;
-      value |= green << render_target->mode_info.green_field_pos;
-      value |= blue << render_target->mode_info.blue_field_pos;
-      value |= alpha << render_target->mode_info.reserved_field_pos;
-
-      return value;
-    }
-
-}
-
-/* Maps RGBA to target optimized color format.  */
-grub_video_color_t
-grub_video_fb_map_rgba (grub_uint8_t red, grub_uint8_t green,
-                       grub_uint8_t blue, grub_uint8_t alpha)
-{
-  if ((render_target->mode_info.mode_type
-       & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
-    /* No alpha available in index color modes, just use
-       same value as in only RGB modes.  */
-    return grub_video_fb_map_rgb (red, green, blue);
-  else if ((render_target->mode_info.mode_type
-            & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
-    {
-      if (red == render_target->mode_info.fg_red
-          && green == render_target->mode_info.fg_green
-          && blue == render_target->mode_info.fg_blue
-          && alpha == render_target->mode_info.fg_alpha)
-        return 1;
-      else
-        return 0;
-    }
-  else
-    {
-      grub_uint32_t value;
-
-      red >>= 8 - render_target->mode_info.red_mask_size;
-      green >>= 8 - render_target->mode_info.green_mask_size;
-      blue >>= 8 - render_target->mode_info.blue_mask_size;
-      alpha >>= 8 - render_target->mode_info.reserved_mask_size;
-
-      value = red << render_target->mode_info.red_field_pos;
-      value |= green << render_target->mode_info.green_field_pos;
-      value |= blue << render_target->mode_info.blue_field_pos;
-      value |= alpha << render_target->mode_info.reserved_field_pos;
-
-      return value;
-    }
-}
-
-/* Splits target optimized format to components.  */
-grub_err_t
-grub_video_fb_unmap_color (grub_video_color_t color,
-                          grub_uint8_t *red, grub_uint8_t *green,
-                          grub_uint8_t *blue, grub_uint8_t *alpha)
-{
-  struct grub_video_fbblit_info target_info;
-
-  target_info.mode_info = &render_target->mode_info;
-  target_info.data = render_target->data;
-
-  grub_video_fb_unmap_color_int (&target_info, color, red, green, blue, alpha);
-
-  return GRUB_ERR_NONE;
-}
-
-/* Splits color in source format to components.  */
-void
-grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source,
-                              grub_video_color_t color,
-                              grub_uint8_t *red, grub_uint8_t *green,
-                              grub_uint8_t *blue, grub_uint8_t *alpha)
-{
-  struct grub_video_mode_info *mode_info;
-  mode_info = source->mode_info;
-
-  if ((mode_info->mode_type
-       & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0)
-    {
-      /* If we have an out-of-bounds color, return transparent black.  */
-      if (color > 255)
-        {
-          *red = 0;
-          *green = 0;
-          *blue = 0;
-          *alpha = 0;
-          return;
-        }
-
-      *red = palette[color].r;
-      *green = palette[color].g;
-      *blue = palette[color].b;
-      *alpha = palette[color].a;
-      return;
-    }
-  else if ((mode_info->mode_type
-            & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
-    {
-      if (color & 1)
-        {
-          *red = mode_info->fg_red;
-          *green = mode_info->fg_green;
-          *blue = mode_info->fg_blue;
-          *alpha = mode_info->fg_alpha;
-        }
-      else
-        {
-          *red = mode_info->bg_red;
-          *green = mode_info->bg_green;
-          *blue = mode_info->bg_blue;
-          *alpha = mode_info->bg_alpha;
-        }
-    }
-  else
-    {
-      grub_uint32_t tmp;
-
-      /* Get red component.  */
-      tmp = color >> mode_info->red_field_pos;
-      tmp &= (1 << mode_info->red_mask_size) - 1;
-      tmp <<= 8 - mode_info->red_mask_size;
-      tmp |= (1 << (8 - mode_info->red_mask_size)) - 1;
-      *red = tmp & 0xFF;
-
-      /* Get green component.  */
-      tmp = color >> mode_info->green_field_pos;
-      tmp &= (1 << mode_info->green_mask_size) - 1;
-      tmp <<= 8 - mode_info->green_mask_size;
-      tmp |= (1 << (8 - mode_info->green_mask_size)) - 1;
-      *green = tmp & 0xFF;
-
-      /* Get blue component.  */
-      tmp = color >> mode_info->blue_field_pos;
-      tmp &= (1 << mode_info->blue_mask_size) - 1;
-      tmp <<= 8 - mode_info->blue_mask_size;
-      tmp |= (1 << (8 - mode_info->blue_mask_size)) - 1;
-      *blue = tmp & 0xFF;
-
-      /* Get alpha component.  */
-      if (source->mode_info->reserved_mask_size > 0)
-        {
-          tmp = color >> mode_info->reserved_field_pos;
-          tmp &= (1 << mode_info->reserved_mask_size) - 1;
-          tmp <<= 8 - mode_info->reserved_mask_size;
-          tmp |= (1 << (8 - mode_info->reserved_mask_size)) - 1;
-        }
-      else
-        /* If there is no alpha component, assume it opaque.  */
-        tmp = 255;
-
-      *alpha = tmp & 0xFF;
-    }
-}
-
-grub_err_t
-grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
-                        unsigned int width, unsigned int height)
-{
-  struct grub_video_fbblit_info target;
-
-  /* Make sure there is something to do.  */
-  if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
-    return GRUB_ERR_NONE;
-  if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
-    return GRUB_ERR_NONE;
-
-  /* Do not allow drawing out of viewport.  */
-  if (x < 0)
-    {
-      width += x;
-      x = 0;
-    }
-  if (y < 0)
-    {
-      height += y;
-      y = 0;
-    }
-
-  if ((x + width) > render_target->viewport.width)
-    width = render_target->viewport.width - x;
-  if ((y + height) > render_target->viewport.height)
-    height = render_target->viewport.height - y;
-
-  /* Add viewport offset.  */
-  x += render_target->viewport.x;
-  y += render_target->viewport.y;
-
-  /* Use fbblit_info to encapsulate rendering.  */
-  target.mode_info = &render_target->mode_info;
-  target.data = render_target->data;
-
-  /* Try to figure out more optimized version.  Note that color is already
-     mapped to target format so we can make assumptions based on that.  */
-  if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
-    {
-      grub_video_fbfill_direct32 (&target, color, x, y,
-                                        width, height);
-      return GRUB_ERR_NONE;
-    }
-  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
-    {
-      grub_video_fbfill_direct32 (&target, color, x, y,
-                                        width, height);
-      return GRUB_ERR_NONE;
-    }
-  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
-    {
-      grub_video_fbfill_direct24 (&target, color, x, y,
-                                        width, height);
-      return GRUB_ERR_NONE;
-    }
-  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_565)
-    {
-      grub_video_fbfill_direct16 (&target, color, x, y,
-                                        width, height);
-      return GRUB_ERR_NONE;
-    }
-  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_565)
-    {
-      grub_video_fbfill_direct16 (&target, color, x, y,
-                                        width, height);
-      return GRUB_ERR_NONE;
-    }
-  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-    {
-      grub_video_fbfill_direct8 (&target, color, x, y,
-                                      width, height);
-      return GRUB_ERR_NONE;
-    }
-
-  /* No optimized version found, use default (slow) filler.  */
-  grub_video_fbfill (&target, color, x, y, width, height);
-
-  return GRUB_ERR_NONE;
-}
-
-/* NOTE: This function assumes that given coordinates are within bounds of
-   handled data.  */
-static void
-common_blitter (struct grub_video_fbblit_info *target,
-                struct grub_video_fbblit_info *source,
-                enum grub_video_blit_operators oper, int x, int y,
-                unsigned int width, unsigned int height,
-                int offset_x, int offset_y)
-{
-  if (oper == GRUB_VIDEO_BLIT_REPLACE)
-    {
-      /* Try to figure out more optimized version for replace operator.  */
-      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
-       {
-         if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
-           {
-             grub_video_fbblit_replace_directN (target, source,
-                                                      x, y, width, height,
-                                                      offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
-           {
-             grub_video_fbblit_replace_BGRX8888_RGBX8888 (target, source,
-                                                                x, y, width, height,
-                                                                offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
-           {
-             grub_video_fbblit_replace_BGR888_RGBX8888 (target, source,
-                                                              x, y, width, height,
-                                                              offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
-           {
-             grub_video_fbblit_replace_RGB888_RGBX8888 (target, source,
-                                                              x, y, width, height,
-                                                              offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-           {
-             grub_video_fbblit_replace_index_RGBX8888 (target, source,
-                                                             x, y, width, height,
-                                                             offset_x, offset_y);
-             return;
-           }
-       }
-      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
-       {
-         if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
-           {
-             grub_video_fbblit_replace_BGRX8888_RGB888 (target, source,
-                                                              x, y, width, height,
-                                                              offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
-           {
-             grub_video_fbblit_replace_RGBX8888_RGB888 (target, source,
-                                                              x, y, width, height,
-                                                              offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
-           {
-             grub_video_fbblit_replace_BGR888_RGB888 (target, source,
-                                                            x, y, width, height,
-                                                            offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
-           {
-             grub_video_fbblit_replace_directN (target, source,
-                                                      x, y, width, height,
-                                                      offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-           {
-             grub_video_fbblit_replace_index_RGB888 (target, source,
-                                                           x, y, width, height,
-                                                           offset_x, offset_y);
-             return;
-           }
-       }
-      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
-       {
-         if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
-           {
-             grub_video_fbblit_replace_directN (target, source,
-                                                      x, y, width, height,
-                                                      offset_x, offset_y);
-             return;
-           }
-       }
-      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-       {
-         if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-           {
-             grub_video_fbblit_replace_directN (target, source,
-                                                      x, y, width, height,
-                                                      offset_x, offset_y);
-             return;
-           }
-       }
-      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
-       {
-         if (target->mode_info->bpp == 32)
-           {
-             grub_video_fbblit_replace_32bit_1bit (target, source,
-                                                   x, y, width, height,
-                                                   offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->bpp == 24)
-           {
-             grub_video_fbblit_replace_24bit_1bit (target, source,
-                                                   x, y, width, height,
-                                                   offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->bpp == 16)
-           {
-             grub_video_fbblit_replace_16bit_1bit (target, source,
-                                                   x, y, width, height,
-                                                   offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->bpp == 8)
-           {
-             grub_video_fbblit_replace_8bit_1bit (target, source,
-                                                  x, y, width, height,
-                                                  offset_x, offset_y);
-             return;
-           }
-       }
-
-      /* No optimized replace operator found, use default (slow) blitter.  */
-      grub_video_fbblit_replace (target, source, x, y, width, height,
-                                      offset_x, offset_y);
-    }
-  else
-    {
-      /* Try to figure out more optimized blend operator.  */
-      if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
-       {
-         if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
-           {
-             grub_video_fbblit_blend_BGRA8888_RGBA8888 (target, source,
-                                                              x, y, width, height,
-                                                              offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
-           {
-             grub_video_fbblit_blend_RGBA8888_RGBA8888 (target, source,
-                                                              x, y, width, height,
-                                                              offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
-           {
-             grub_video_fbblit_blend_BGR888_RGBA8888 (target, source,
-                                                            x, y, width, height,
-                                                            offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
-           {
-             grub_video_fbblit_blend_RGB888_RGBA8888 (target, source,
-                                                            x, y, width, height,
-                                                            offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-           {
-             grub_video_fbblit_blend_index_RGBA8888 (target, source,
-                                                           x, y, width, height,
-                                                           offset_x, offset_y);
-             return;
-           }
-       }
-      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
-       {
-         /* Note: There is really no alpha information here, so blend is
-            changed to replace.  */
-
-         if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
-           {
-             grub_video_fbblit_replace_BGRX8888_RGB888 (target, source,
-                                                              x, y, width, height,
-                                                              offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
-           {
-             grub_video_fbblit_replace_RGBX8888_RGB888 (target, source,
-                                                              x, y, width, height,
-                                                              offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888)
-           {
-             grub_video_fbblit_replace_BGR888_RGB888 (target, source,
-                                                            x, y, width, height,
-                                                            offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
-           {
-             grub_video_fbblit_replace_directN (target, source,
-                                                      x, y, width, height,
-                                                      offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
-           {
-             grub_video_fbblit_replace_index_RGB888 (target, source,
-                                                           x, y, width, height,
-                                                           offset_x, offset_y);
-             return;
-           }
-       }
-      else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
-       {
-         if (target->mode_info->blit_format
-             == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888
-             || target->mode_info->blit_format
-             == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
-           {
-             grub_video_fbblit_blend_XXXA8888_1bit (target, source,
-                                                    x, y, width, height,
-                                                    offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format
-                  == GRUB_VIDEO_BLIT_FORMAT_BGR_888
-                  || target->mode_info->blit_format
-                  == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
-           {
-             grub_video_fbblit_blend_XXX888_1bit (target, source,
-                                                  x, y, width, height,
-                                                  offset_x, offset_y);
-             return;
-           }
-         else if (target->mode_info->blit_format
-                  == GRUB_VIDEO_BLIT_FORMAT_BGR_565
-                  || target->mode_info->blit_format
-                  == GRUB_VIDEO_BLIT_FORMAT_RGB_565)
-           {
-             grub_video_fbblit_blend_XXX565_1bit (target, source,
-                                                  x, y, width, height,
-                                                  offset_x, offset_y);
-             return;
-           }
-
-       }
-
-
-      /* No optimized blend operation found, use default (slow) blitter.  */
-      grub_video_fbblit_blend (target, source, x, y, width, height,
-                                    offset_x, offset_y);
-    }
-}
-
-grub_err_t
-grub_video_fb_blit_bitmap (struct grub_video_bitmap *bitmap,
-                          enum grub_video_blit_operators oper, int x, int y,
-                          int offset_x, int offset_y,
-                          unsigned int width, unsigned int height)
-{
-  struct grub_video_fbblit_info source;
-  struct grub_video_fbblit_info target;
-
-  /* Make sure there is something to do.  */
-  if ((width == 0) || (height == 0))
-    return GRUB_ERR_NONE;
-  if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
-    return GRUB_ERR_NONE;
-  if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
-    return GRUB_ERR_NONE;
-  if ((x + (int)bitmap->mode_info.width) < 0)
-    return GRUB_ERR_NONE;
-  if ((y + (int)bitmap->mode_info.height) < 0)
-    return GRUB_ERR_NONE;
-  if ((offset_x >= (int)bitmap->mode_info.width)
-      || (offset_x + (int)width < 0))
-    return GRUB_ERR_NONE;
-  if ((offset_y >= (int)bitmap->mode_info.height)
-      || (offset_y + (int)height < 0))
-    return GRUB_ERR_NONE;
-
-  /* If we have negative coordinates, optimize drawing to minimum.  */
-  if (offset_x < 0)
-    {
-      width += offset_x;
-      x -= offset_x;
-      offset_x = 0;
-    }
-
-  if (offset_y < 0)
-    {
-      height += offset_y;
-      y -= offset_y;
-      offset_y = 0;
-    }
-
-  if (x < 0)
-    {
-      width += x;
-      offset_x -= x;
-      x = 0;
-    }
-
-  if (y < 0)
-    {
-      height += y;
-      offset_y -= y;
-      y = 0;
-    }
-
-  /* Do not allow drawing out of viewport.  */
-  if ((x + width) > render_target->viewport.width)
-    width = render_target->viewport.width - x;
-  if ((y + height) > render_target->viewport.height)
-    height = render_target->viewport.height - y;
-
-  if ((offset_x + width) > bitmap->mode_info.width)
-    width = bitmap->mode_info.width - offset_x;
-  if ((offset_y + height) > bitmap->mode_info.height)
-    height = bitmap->mode_info.height - offset_y;
-
-  /* Limit drawing to source render target dimensions.  */
-  if (width > bitmap->mode_info.width)
-    width = bitmap->mode_info.width;
-
-  if (height > bitmap->mode_info.height)
-    height = bitmap->mode_info.height;
-
-  /* Add viewport offset.  */
-  x += render_target->viewport.x;
-  y += render_target->viewport.y;
-
-  /* Use fbblit_info to encapsulate rendering.  */
-  source.mode_info = &bitmap->mode_info;
-  source.data = bitmap->data;
-  target.mode_info = &render_target->mode_info;
-  target.data = render_target->data;
-
-  /* Do actual blitting.  */
-  common_blitter (&target, &source, oper, x, y, width, height,
-                  offset_x, offset_y);
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_video_fb_blit_render_target (struct grub_video_fbrender_target *source,
-                                   enum grub_video_blit_operators oper,
-                                   int x, int y, int offset_x, int offset_y,
-                                   unsigned int width, unsigned int height)
-{
-  struct grub_video_fbblit_info source_info;
-  struct grub_video_fbblit_info target_info;
-
-  /* Make sure there is something to do.  */
-  if ((width == 0) || (height == 0))
-    return GRUB_ERR_NONE;
-  if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0))
-    return GRUB_ERR_NONE;
-  if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0))
-    return GRUB_ERR_NONE;
-  if ((x + (int)source->mode_info.width) < 0)
-    return GRUB_ERR_NONE;
-  if ((y + (int)source->mode_info.height) < 0)
-    return GRUB_ERR_NONE;
-  if ((offset_x >= (int)source->mode_info.width)
-      || (offset_x + (int)width < 0))
-    return GRUB_ERR_NONE;
-  if ((offset_y >= (int)source->mode_info.height)
-      || (offset_y + (int)height < 0))
-    return GRUB_ERR_NONE;
-
-  /* If we have negative coordinates, optimize drawing to minimum.  */
-  if (offset_x < 0)
-    {
-      width += offset_x;
-      x -= offset_x;
-      offset_x = 0;
-    }
-
-  if (offset_y < 0)
-    {
-      height += offset_y;
-      y -= offset_y;
-      offset_y = 0;
-    }
-
-  if (x < 0)
-    {
-      width += x;
-      offset_x -= x;
-      x = 0;
-    }
-
-  if (y < 0)
-    {
-      height += y;
-      offset_y -= y;
-      y = 0;
-    }
-
-  /* Do not allow drawing out of viewport.  */
-  if ((x + width) > render_target->viewport.width)
-    width = render_target->viewport.width - x;
-  if ((y + height) > render_target->viewport.height)
-    height = render_target->viewport.height - y;
-
-  if ((offset_x + width) > source->mode_info.width)
-    width = source->mode_info.width - offset_x;
-  if ((offset_y + height) > source->mode_info.height)
-    height = source->mode_info.height - offset_y;
-
-  /* Limit drawing to source render target dimensions.  */
-  if (width > source->mode_info.width)
-    width = source->mode_info.width;
-
-  if (height > source->mode_info.height)
-    height = source->mode_info.height;
-
-  /* Add viewport offset.  */
-  x += render_target->viewport.x;
-  y += render_target->viewport.y;
-
-  /* Use fbblit_info to encapsulate rendering.  */
-  source_info.mode_info = &source->mode_info;
-  source_info.data = source->data;
-  target_info.mode_info = &render_target->mode_info;
-  target_info.data = render_target->data;
-
-  /* Do actual blitting.  */
-  common_blitter (&target_info, &source_info, oper, x, y, width, height,
-                  offset_x, offset_y);
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
-{
-  int width;
-  int height;
-  int src_x;
-  int src_y;
-  int dst_x;
-  int dst_y;
-
-  /* 1. Check if we have something to do.  */
-  if ((dx == 0) && (dy == 0))
-    return GRUB_ERR_NONE;
-
-  width = render_target->viewport.width - grub_abs (dx);
-  height = render_target->viewport.height - grub_abs (dy);
-
-  if (dx < 0)
-    {
-      src_x = render_target->viewport.x - dx;
-      dst_x = render_target->viewport.x;
-    }
-  else
-    {
-      src_x = render_target->viewport.x;
-      dst_x = render_target->viewport.x + dx;
-    }
-
-  if (dy < 0)
-    {
-      src_y = render_target->viewport.y - dy;
-      dst_y = render_target->viewport.y;
-    }
-  else
-    {
-      src_y = render_target->viewport.y;
-      dst_y = render_target->viewport.y + dy;
-    }
-
-  /* 2. Check if there is need to copy data.  */
-  if ((grub_abs (dx) < render_target->viewport.width)
-       && (grub_abs (dy) < render_target->viewport.height))
-    {
-      /* 3. Move data in render target.  */
-      struct grub_video_fbblit_info target;
-      int i, j;
-      int linedelta, linelen;
-
-      target.mode_info = &render_target->mode_info;
-      target.data = render_target->data;
-
-      linedelta = target.mode_info->pitch
-       - width * target.mode_info->bytes_per_pixel;
-      linelen = width * target.mode_info->bytes_per_pixel;
-#define DO_SCROLL                                                    \
-      /* Check vertical direction of the move.  */                   \
-      if (dy < 0 || (dy == 0 && dx < 0))                             \
-       {                                                            \
-         dst = (void *) grub_video_fb_get_video_ptr (&target,       \
-                                                     dst_x, dst_y); \
-         src = (void *) grub_video_fb_get_video_ptr (&target,       \
-                                                     src_x, src_y); \
-         /* 3a. Move data upwards.  */                              \
-         for (j = 0; j < height; j++)                               \
-           {                                                        \
-             for (i = 0; i < linelen; i++)                          \
-               *(dst++) = *(src++);                                 \
-             dst += linedelta;                                      \
-             src += linedelta;                                      \
-           }                                                        \
-       }                                                            \
-      else                                                           \
-       {                                                            \
-         /* 3b. Move data downwards.  */                            \
-         dst = (void *) grub_video_fb_get_video_ptr (&target,       \
-                                                     dst_x + width, \
-                                            dst_y + height - 1);    \
-         src = (void *) grub_video_fb_get_video_ptr (&target,       \
-                                                     src_x + width, \
-                                            src_y + height - 1);    \
-         dst--;                                                     \
-          src--;                                                     \
-         for (j = 0; j < height; j++)                               \
-           {                                                        \
-             for (i = 0; i < linelen; i++)                          \
-               *(dst--) = *(src--);                                 \
-             dst -= linedelta;                                      \
-             src -= linedelta;                                      \
-           }                                                        \
-       }
-
-      /* If everything is aligned on 32-bit use 32-bit copy.  */
-      if ((grub_addr_t) grub_video_fb_get_video_ptr (&target, src_x, src_y)
-         % sizeof (grub_uint32_t) == 0
-         && (grub_addr_t) grub_video_fb_get_video_ptr (&target, dst_x, dst_y) 
-         % sizeof (grub_uint32_t) == 0
-         && linelen % sizeof (grub_uint32_t) == 0
-         && linedelta % sizeof (grub_uint32_t) == 0)
-       {
-         grub_uint32_t *src, *dst;
-         linelen /= sizeof (grub_uint32_t);
-         linedelta /= sizeof (grub_uint32_t);
-         DO_SCROLL
-       }
-      /* If everything is aligned on 16-bit use 16-bit copy.  */
-      else if ((grub_addr_t) grub_video_fb_get_video_ptr (&target, src_x, src_y)
-              % sizeof (grub_uint16_t) == 0
-              && (grub_addr_t) grub_video_fb_get_video_ptr (&target,
-                                                            dst_x, dst_y) 
-              % sizeof (grub_uint16_t) == 0
-              && linelen % sizeof (grub_uint16_t) == 0
-              && linedelta % sizeof (grub_uint16_t) == 0)
-       {
-         grub_uint16_t *src, *dst;
-         linelen /= sizeof (grub_uint16_t);
-         linedelta /= sizeof (grub_uint16_t);
-         DO_SCROLL
-       }
-      /* If not aligned at all use 8-bit copy.  */
-      else
-       {
-         grub_uint8_t *src, *dst;
-         DO_SCROLL
-       }       
-    }
-
-  /* 4. Fill empty space with specified color.  In this implementation
-     there might be colliding areas but at the moment there is no need
-     to optimize this.  */
-
-  /* 4a. Fill top & bottom parts.  */
-  if (dy > 0)
-    grub_video_fb_fill_rect (color, 0, 0, render_target->viewport.width, dy);
-  else if (dy < 0)
-    {
-      if (render_target->viewport.height < grub_abs (dy))
-        dy = -render_target->viewport.height;
-
-      grub_video_fb_fill_rect (color, 0, render_target->viewport.height + dy,
-                                render_target->viewport.width, -dy);
-    }
-
-  /* 4b. Fill left & right parts.  */
-  if (dx > 0)
-    grub_video_fb_fill_rect (color, 0, 0,
-                              dx, render_target->viewport.height);
-  else if (dx < 0)
-    {
-      if (render_target->viewport.width < grub_abs (dx))
-        dx = -render_target->viewport.width;
-
-      grub_video_fb_fill_rect (color, render_target->viewport.width + dx, 0,
-                                -dx, render_target->viewport.height);
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-
-grub_err_t
-grub_video_fb_create_render_target (struct grub_video_fbrender_target **result,
-                                   unsigned int width, unsigned int height,
-                                   unsigned int mode_type __attribute__ ((unused)))
-{
-  struct grub_video_fbrender_target *target;
-  unsigned int size;
-
-  /* Validate arguments.  */
-  if ((! result)
-      || (width == 0)
-      || (height == 0))
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                       "invalid argument given");
-
-  /* Allocate memory for render target.  */
-  target = grub_malloc (sizeof (struct grub_video_fbrender_target));
-  if (! target)
-    return grub_errno;
-
-  /* TODO: Implement other types too.
-     Currently only 32bit render targets are supported.  */
-
-  /* Mark render target as allocated.  */
-  target->is_allocated = 1;
-
-  /* Maximize viewport.  */
-  target->viewport.x = 0;
-  target->viewport.y = 0;
-  target->viewport.width = width;
-  target->viewport.height = height;
-
-  /* Setup render target format.  */
-  target->mode_info.width = width;
-  target->mode_info.height = height;
-  target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB
-                                | GRUB_VIDEO_MODE_TYPE_ALPHA;
-  target->mode_info.bpp = 32;
-  target->mode_info.bytes_per_pixel = 4;
-  target->mode_info.pitch = target->mode_info.bytes_per_pixel * width;
-  target->mode_info.number_of_colors = palette_size; /* Emulated palette.  */
-  target->mode_info.red_mask_size = 8;
-  target->mode_info.red_field_pos = 0;
-  target->mode_info.green_mask_size = 8;
-  target->mode_info.green_field_pos = 8;
-  target->mode_info.blue_mask_size = 8;
-  target->mode_info.blue_field_pos = 16;
-  target->mode_info.reserved_mask_size = 8;
-  target->mode_info.reserved_field_pos = 24;
-
-  target->mode_info.blit_format = grub_video_get_blit_format (&target->mode_info);
-
-  /* Calculate size needed for the data.  */
-  size = (width * target->mode_info.bytes_per_pixel) * height;
-
-  target->data = grub_malloc (size);
-  if (! target->data)
-    {
-      grub_free (target);
-      return grub_errno;
-    }
-
-  /* Clear render target with black and maximum transparency.  */
-  grub_memset (target->data, 0, size);
-
-  /* TODO: Add render target to render target list.  */
-
-  /* Save result to caller.  */
-  *result = target;
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_video_fb_create_render_target_from_pointer (struct grub_video_fbrender_target **result,
-                                                const struct grub_video_mode_info *mode_info,
-                                                void *ptr)
-{
-  struct grub_video_fbrender_target *target;
-  unsigned y;
-
-  /* Allocate memory for render target.  */
-  target = grub_malloc (sizeof (struct grub_video_fbrender_target));
-  if (! target)
-    return grub_errno;
-
-  /* Mark framebuffer memory as non allocated.  */
-  target->is_allocated = 0;
-  target->data = ptr;
-
-  grub_memcpy (&(target->mode_info), mode_info, sizeof (target->mode_info));
-
-  /* Reset viewport to match new mode.  */
-  target->viewport.x = 0;
-  target->viewport.y = 0;
-  target->viewport.width = mode_info->width;
-  target->viewport.height = mode_info->height;
-
-  /* Clear render target with black and maximum transparency.  */
-  for (y = 0; y < mode_info->height; y++)
-    grub_memset (target->data + mode_info->pitch * y, 0,
-                mode_info->bytes_per_pixel * mode_info->width);
-
-  /* Save result to caller.  */
-  *result = target;
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_video_fb_delete_render_target (struct grub_video_fbrender_target *target)
-{
-  /* If there is no target, then just return without error.  */
-  if (! target)
-    return GRUB_ERR_NONE;
-
-  /* TODO: Delist render target from render target list.  */
-
-  /* If this is software render target, free it's memory.  */
-  if (target->is_allocated)
-    grub_free (target->data);
-
-  /* Free render target.  */
-  grub_free (target);
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *target)
-{
-  if (! target->data)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                       "invalid render target given");
-
-  render_target = target;
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **target)
-{
-  *target = render_target;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-doublebuf_blit_update_screen (struct grub_video_fbrender_target *front,
-                             struct grub_video_fbrender_target *back)
-{
-  grub_memcpy (front->data, back->data,
-              front->mode_info.pitch * front->mode_info.height);
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **front,
-                                  struct grub_video_fbrender_target **back,
-                                  grub_video_fb_doublebuf_update_screen_t *update_screen,
-                                  struct grub_video_mode_info mode_info,
-                                  void *framebuf)
-{
-  grub_err_t err;
-  int page_size = mode_info.pitch * mode_info.height;
-  void *offscreen_buffer;
-
-  err = grub_video_fb_create_render_target_from_pointer (front, &mode_info,
-                                                        framebuf);
-  if (err)
-    return err;
-
-  offscreen_buffer = grub_malloc (page_size);
-  if (! offscreen_buffer)
-    {
-      grub_video_fb_delete_render_target (*front);
-      *front = 0;
-      return grub_errno;
-    }
-
-  err = grub_video_fb_create_render_target_from_pointer (back, &mode_info,
-                                                        offscreen_buffer);
-
-  if (err)
-    {
-      grub_video_fb_delete_render_target (*front);
-      grub_free (offscreen_buffer);
-      *front = 0;
-      return grub_errno;
-    }
-  (*back)->is_allocated = 1;
-
-  *update_screen = doublebuf_blit_update_screen;
-
-  return GRUB_ERR_NONE;
-}
diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c
deleted file mode 100644 (file)
index 72b8f18..0000000
+++ /dev/null
@@ -1,820 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define grub_video_render_target grub_video_fbrender_target
-
-#include <grub/err.h>
-#include <grub/machine/memory.h>
-#include <grub/machine/vga.h>
-#include <grub/machine/vbe.h>
-#include <grub/video_fb.h>
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/video.h>
-
-static int vbe_detected = -1;
-
-static struct grub_vbe_info_block controller_info;
-static struct grub_vbe_mode_info_block active_vbe_mode_info;
-
-/* Track last mode to support cards which fail on get_mode.  */
-static grub_uint32_t last_set_mode = 3;
-
-static struct
-{
-  struct grub_video_mode_info mode_info;
-  struct grub_video_render_target *front_target;
-  struct grub_video_render_target *back_target;
-
-  unsigned int bytes_per_scan_line;
-  unsigned int bytes_per_pixel;
-  grub_uint32_t active_vbe_mode;
-  grub_uint8_t *ptr;
-  int index_color_mode;
-
-  char *offscreen_buffer;
-
-  grub_size_t page_size;        /* The size of a page in bytes.  */
-
-  /* For page flipping strategy.  */
-  int displayed_page;           /* The page # that is the front buffer.  */
-  int render_page;              /* The page # that is the back buffer.  */
-
-  /* Virtual functions.  */
-  grub_video_fb_doublebuf_update_screen_t update_screen;
-} framebuffer;
-
-static grub_uint32_t initial_vbe_mode;
-static grub_uint16_t *vbe_mode_list;
-
-static void *
-real2pm (grub_vbe_farptr_t ptr)
-{
-  return (void *) ((((unsigned long) ptr & 0xFFFF0000) >> 12UL)
-                   + ((unsigned long) ptr & 0x0000FFFF));
-}
-
-grub_err_t
-grub_vbe_probe (struct grub_vbe_info_block *info_block)
-{
-  struct grub_vbe_info_block *vbe_ib;
-  grub_vbe_status_t status;
-
-  /* Clear caller's controller info block.  */
-  if (info_block)
-    grub_memset (info_block, 0, sizeof (*info_block));
-
-  /* Do not probe more than one time, if not necessary.  */
-  if (vbe_detected == -1 || info_block)
-    {
-      /* Clear old copy of controller info block.  */
-      grub_memset (&controller_info, 0, sizeof (controller_info));
-
-      /* Mark VESA BIOS extension as undetected.  */
-      vbe_detected = 0;
-
-      /* Use low memory scratch area as temporary storage
-         for VESA BIOS call.  */
-      vbe_ib = (struct grub_vbe_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
-
-      /* Prepare info block.  */
-      grub_memset (vbe_ib, 0, sizeof (*vbe_ib));
-
-      vbe_ib->signature[0] = 'V';
-      vbe_ib->signature[1] = 'B';
-      vbe_ib->signature[2] = 'E';
-      vbe_ib->signature[3] = '2';
-
-      /* Try to get controller info block.  */
-      status = grub_vbe_bios_get_controller_info (vbe_ib);
-      if (status == GRUB_VBE_STATUS_OK)
-        {
-          /* Copy it for later usage.  */
-          grub_memcpy (&controller_info, vbe_ib, sizeof (controller_info));
-
-          /* Mark VESA BIOS extension as detected.  */
-          vbe_detected = 1;
-        }
-    }
-
-  if (! vbe_detected)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "VESA BIOS Extension not found");
-
-  /* Make copy of controller info block to caller.  */
-  if (info_block)
-    grub_memcpy (info_block, &controller_info, sizeof (*info_block));
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_vbe_set_video_mode (grub_uint32_t vbe_mode,
-                        struct grub_vbe_mode_info_block *vbe_mode_info)
-{
-  grub_vbe_status_t status;
-  grub_uint32_t old_vbe_mode;
-  struct grub_vbe_mode_info_block new_vbe_mode_info;
-  grub_err_t err;
-
-  /* Make sure that VBE is supported.  */
-  grub_vbe_probe (0);
-  if (grub_errno != GRUB_ERR_NONE)
-    return grub_errno;
-
-  /* Try to get mode info.  */
-  grub_vbe_get_video_mode_info (vbe_mode, &new_vbe_mode_info);
-  if (grub_errno != GRUB_ERR_NONE)
-    return grub_errno;
-
-  /* For all VESA BIOS modes, force linear frame buffer.  */
-  if (vbe_mode >= 0x100)
-    {
-      /* We only want linear frame buffer modes.  */
-      vbe_mode |= 1 << 14;
-
-      /* Determine frame buffer pixel format.  */
-      switch (new_vbe_mode_info.memory_model)
-        {
-        case GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL:
-          framebuffer.index_color_mode = 1;
-          break;
-
-        case GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR:
-          framebuffer.index_color_mode = 0;
-          break;
-
-        default:
-          return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                             "unsupported pixel format 0x%x",
-                             new_vbe_mode_info.memory_model);
-        }
-    }
-
-  /* Get current mode.  */
-  grub_vbe_get_video_mode (&old_vbe_mode);
-  if (grub_errno != GRUB_ERR_NONE)
-    return grub_errno;
-
-  /* Try to set video mode.  */
-  status = grub_vbe_bios_set_mode (vbe_mode, 0);
-  if (status != GRUB_VBE_STATUS_OK)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "cannot set VBE mode %x", vbe_mode);
-  last_set_mode = vbe_mode;
-
-  /* Save information for later usage.  */
-  framebuffer.active_vbe_mode = vbe_mode;
-  grub_memcpy (&active_vbe_mode_info, &new_vbe_mode_info, sizeof (active_vbe_mode_info));
-
-  if (vbe_mode < 0x100)
-    {
-      /* If this is not a VESA mode, guess address.  */
-      framebuffer.ptr = (grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR;
-      framebuffer.index_color_mode = 1;
-    }
-  else
-    {
-      framebuffer.ptr = (grub_uint8_t *) new_vbe_mode_info.phys_base_addr;
-
-      if (controller_info.version >= 0x300)
-        framebuffer.bytes_per_scan_line = new_vbe_mode_info.lin_bytes_per_scan_line;
-      else
-        framebuffer.bytes_per_scan_line = new_vbe_mode_info.bytes_per_scan_line;
-    }
-
-  /* Check whether mode is text mode or graphics mode.  */
-  if (new_vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_TEXT)
-    {
-      /* Text mode.  */
-
-      /* No special action needed for text mode as it is not supported for
-         graphical support.  */
-    }
-  else
-    {
-      /* Graphics mode.  */
-
-      /* Calculate bytes_per_pixel value.  */
-      switch(new_vbe_mode_info.bits_per_pixel)
-       {
-       case 32: framebuffer.bytes_per_pixel = 4; break;
-       case 24: framebuffer.bytes_per_pixel = 3; break;
-       case 16: framebuffer.bytes_per_pixel = 2; break;
-       case 15: framebuffer.bytes_per_pixel = 2; break;
-       case 8: framebuffer.bytes_per_pixel = 1; break;
-       default:
-         grub_vbe_bios_set_mode (old_vbe_mode, 0);
-         last_set_mode = old_vbe_mode;
-         return grub_error (GRUB_ERR_BAD_DEVICE,
-                            "cannot set VBE mode %x",
-                            vbe_mode);
-         break;
-       }
-
-      /* If video mode is in indexed color, setup default VGA palette.  */
-      if (framebuffer.index_color_mode)
-       {
-         struct grub_vbe_palette_data *palette
-           = (struct grub_vbe_palette_data *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
-         unsigned i;
-
-         /* Make sure that the BIOS can reach the palette.  */
-         for (i = 0; i < GRUB_VIDEO_FBSTD_NUMCOLORS; i++)
-           {
-             palette[i].red = grub_video_fbstd_colors[i].r;
-             palette[i].green = grub_video_fbstd_colors[i].g;
-             palette[i].blue = grub_video_fbstd_colors[i].b;
-             palette[i].alignment = 0;
-           }
-
-         status = grub_vbe_bios_set_palette_data (GRUB_VIDEO_FBSTD_NUMCOLORS,
-                                                  0, palette);
-
-         /* Just ignore the status.  */
-         err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
-                                          grub_video_fbstd_colors);
-         if (err)
-           return err;
-
-       }
-    }
-
-  /* Copy mode info for caller.  */
-  if (vbe_mode_info)
-    grub_memcpy (vbe_mode_info, &new_vbe_mode_info, sizeof (*vbe_mode_info));
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_vbe_get_video_mode (grub_uint32_t *mode)
-{
-  grub_vbe_status_t status;
-
-  /* Make sure that VBE is supported.  */
-  grub_vbe_probe (0);
-  if (grub_errno != GRUB_ERR_NONE)
-    return grub_errno;
-
-  /* Try to query current mode from VESA BIOS.  */
-  status = grub_vbe_bios_get_mode (mode);
-  /* XXX: ATI cards don't support get_mode.  */
-  if (status != GRUB_VBE_STATUS_OK)
-    *mode = last_set_mode;
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_vbe_get_video_mode_info (grub_uint32_t mode,
-                              struct grub_vbe_mode_info_block *mode_info)
-{
-  struct grub_vbe_mode_info_block *mi_tmp
-    = (struct grub_vbe_mode_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
-  grub_vbe_status_t status;
-
-  /* Make sure that VBE is supported.  */
-  grub_vbe_probe (0);
-  if (grub_errno != GRUB_ERR_NONE)
-    return grub_errno;
-
-  /* If mode is not VESA mode, skip mode info query.  */
-  if (mode >= 0x100)
-    {
-      /* Try to get mode info from VESA BIOS.  */
-      status = grub_vbe_bios_get_mode_info (mode, mi_tmp);
-      if (status != GRUB_VBE_STATUS_OK)
-        return grub_error (GRUB_ERR_BAD_DEVICE,
-                           "cannot get information on the mode %x", mode);
-
-      /* Make copy of mode info block.  */
-      grub_memcpy (mode_info, mi_tmp, sizeof (*mode_info));
-    }
-  else
-    /* Just clear mode info block if it isn't a VESA mode.  */
-    grub_memset (mode_info, 0, sizeof (*mode_info));
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_vbe_init (void)
-{
-  grub_uint16_t *rm_vbe_mode_list;
-  grub_uint16_t *p;
-  grub_size_t vbe_mode_list_size;
-  struct grub_vbe_info_block info_block;
-
-  /* Check if there is adapter present.
-
-     Firmware note: There has been a report that some cards store video mode
-     list in temporary memory.  So we must first use vbe probe to get
-     refreshed information to receive valid pointers and data, and then
-     copy this information to somewhere safe.  */
-  grub_vbe_probe (&info_block);
-  if (grub_errno != GRUB_ERR_NONE)
-    return grub_errno;
-
-  /* Copy modelist to local memory.  */
-  p = rm_vbe_mode_list = real2pm (info_block.video_mode_ptr);
-  while(*p++ != 0xFFFF)
-    ;
-
-  vbe_mode_list_size = (grub_addr_t) p - (grub_addr_t) rm_vbe_mode_list;
-  vbe_mode_list = grub_malloc (vbe_mode_list_size);
-  if (! vbe_mode_list)
-    return grub_errno;
-  grub_memcpy (vbe_mode_list, rm_vbe_mode_list, vbe_mode_list_size);
-
-  /* Adapter could be found, figure out initial video mode.  */
-  grub_vbe_get_video_mode (&initial_vbe_mode);
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      /* Free allocated resources.  */
-      grub_free (vbe_mode_list);
-      vbe_mode_list = NULL;
-
-      return grub_errno;
-    }
-
-  /* Reset frame buffer.  */
-  grub_memset (&framebuffer, 0, sizeof(framebuffer));
-
-  return grub_video_fb_init ();
-}
-
-static grub_err_t
-grub_video_vbe_fini (void)
-{
-  grub_vbe_status_t status;
-  grub_err_t err;
-
-  /* Restore old video mode.  */
-  status = grub_vbe_bios_set_mode (initial_vbe_mode, 0);
-  if (status != GRUB_VBE_STATUS_OK)
-    /* TODO: Decide, is this something we want to do.  */
-    return grub_errno;
-  last_set_mode = initial_vbe_mode;
-
-  /* TODO: Free any resources allocated by driver.  */
-  grub_free (vbe_mode_list);
-  vbe_mode_list = NULL;
-
-  err = grub_video_fb_fini ();
-  grub_free (framebuffer.offscreen_buffer);
-  return err;
-}
-
-/*
-  Set framebuffer render target page and display the proper page, based on
-  `doublebuf_state.render_page' and `doublebuf_state.displayed_page',
-  respectively.
-*/
-static grub_err_t
-doublebuf_pageflipping_commit (void)
-{
-  /* Tell the video adapter to display the new front page.  */
-  int display_start_line
-    = framebuffer.mode_info.height * framebuffer.displayed_page;
-
-  grub_vbe_status_t vbe_err =
-    grub_vbe_bios_set_display_start (0, display_start_line);
-
-  if (vbe_err != GRUB_VBE_STATUS_OK)
-    return grub_error (GRUB_ERR_IO, "couldn't commit pageflip");
-
-  return 0;
-}
-
-static grub_err_t
-doublebuf_pageflipping_update_screen (struct grub_video_fbrender_target *front
-                                     __attribute__ ((unused)),
-                                     struct grub_video_fbrender_target *back
-                                     __attribute__ ((unused)))
-{
-  int new_displayed_page;
-  struct grub_video_fbrender_target *target;
-  grub_err_t err;
-
-  /* Swap the page numbers in the framebuffer struct.  */
-  new_displayed_page = framebuffer.render_page;
-  framebuffer.render_page = framebuffer.displayed_page;
-  framebuffer.displayed_page = new_displayed_page;
-
-  err = doublebuf_pageflipping_commit ();
-  if (err)
-    {
-      /* Restore previous state.  */
-      framebuffer.render_page = framebuffer.displayed_page;
-      framebuffer.displayed_page = new_displayed_page;
-      return err;
-    }
-
-  if (framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP)
-    grub_memcpy (framebuffer.ptr + framebuffer.render_page
-                * framebuffer.page_size, framebuffer.ptr
-                + framebuffer.displayed_page * framebuffer.page_size,
-                framebuffer.page_size);
-
-  target = framebuffer.back_target;
-  framebuffer.back_target = framebuffer.front_target;
-  framebuffer.front_target = target;
-
-  err = grub_video_fb_get_active_render_target (&target);
-  if (err)
-    return err;
-
-  if (target == framebuffer.back_target)
-    err = grub_video_fb_set_active_render_target (framebuffer.front_target);
-  else if (target == framebuffer.front_target)
-    err = grub_video_fb_set_active_render_target (framebuffer.back_target);
-
-  return err;
-}
-
-static grub_err_t
-doublebuf_pageflipping_init (void)
-{
-  /* Get video RAM size in bytes.  */
-  grub_size_t vram_size = controller_info.total_memory << 16;
-  grub_err_t err;
-
-  framebuffer.page_size =
-    framebuffer.mode_info.pitch * framebuffer.mode_info.height;
-
-  if (2 * framebuffer.page_size > vram_size)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                      "Not enough video memory for double buffering.");
-
-  framebuffer.displayed_page = 0;
-  framebuffer.render_page = 1;
-
-  framebuffer.update_screen = doublebuf_pageflipping_update_screen;
-
-  err = grub_video_fb_create_render_target_from_pointer (&framebuffer.front_target, &framebuffer.mode_info, framebuffer.ptr);
-  if (err)
-    return err;
-
-  err = grub_video_fb_create_render_target_from_pointer (&framebuffer.back_target, &framebuffer.mode_info, framebuffer.ptr + framebuffer.page_size);
-  if (err)
-    {
-      grub_video_fb_delete_render_target (framebuffer.front_target);
-      return err;
-    }
-
-  /* Set the framebuffer memory data pointer and display the right page.  */
-  err = doublebuf_pageflipping_commit ();
-  if (err)
-    {
-      grub_video_fb_delete_render_target (framebuffer.front_target);
-      grub_video_fb_delete_render_target (framebuffer.back_target);
-      return err;
-    }
-
-  return GRUB_ERR_NONE;
-}
-
-/* Select the best double buffering mode available.  */
-static grub_err_t
-double_buffering_init (unsigned int mode_type, unsigned int mode_mask)
-{
-  grub_err_t err;
-  int updating_swap_needed;
-
-  updating_swap_needed
-    = grub_video_check_mode_flag (mode_type, mode_mask,
-                                 GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP, 0);
-
-  /* Do double buffering only if it's either requested or efficient.  */
-  if (grub_video_check_mode_flag (mode_type, mode_mask,
-                                 GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED,
-                                 !updating_swap_needed))
-    {
-      framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
-      if (updating_swap_needed)
-       framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP;
-      err = doublebuf_pageflipping_init ();
-      if (!err)
-       return GRUB_ERR_NONE;
-      
-      framebuffer.mode_info.mode_type
-       &= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
-            | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
-
-      grub_errno = GRUB_ERR_NONE;
-    }
-
-  if (grub_video_check_mode_flag (mode_type, mode_mask,
-                                 GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED,
-                                 0))
-    {
-      framebuffer.mode_info.mode_type 
-       |= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
-           | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
-
-      err = grub_video_fb_doublebuf_blit_init (&framebuffer.front_target,
-                                              &framebuffer.back_target,
-                                              &framebuffer.update_screen,
-                                              framebuffer.mode_info,
-                                              framebuffer.ptr);
-
-      if (!err)
-       return GRUB_ERR_NONE;
-
-      framebuffer.mode_info.mode_type
-       &= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
-            | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
-
-      grub_errno = GRUB_ERR_NONE;
-    }
-
-  /* Fall back to no double buffering.  */
-  err = grub_video_fb_create_render_target_from_pointer (&framebuffer.front_target, &framebuffer.mode_info, framebuffer.ptr);
-
-  if (err)
-    return err;
-
-  framebuffer.back_target = framebuffer.front_target;
-  framebuffer.update_screen = 0;
-
-  framebuffer.mode_info.mode_type &= ~GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
-
-  return GRUB_ERR_NONE;
-}
-
-
-
-static grub_err_t
-grub_video_vbe_setup (unsigned int width, unsigned int height,
-                      unsigned int mode_type, unsigned int mode_mask)
-{
-  grub_uint16_t *p;
-  struct grub_vbe_mode_info_block vbe_mode_info;
-  struct grub_vbe_mode_info_block best_vbe_mode_info;
-  grub_uint32_t best_vbe_mode = 0;
-  int depth;
-
-  /* Decode depth from mode_type.  If it is zero, then autodetect.  */
-  depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
-          >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
-
-  /* Walk thru mode list and try to find matching mode.  */
-  for (p = vbe_mode_list; *p != 0xFFFF; p++)
-    {
-      grub_uint32_t vbe_mode = *p;
-
-      grub_vbe_get_video_mode_info (vbe_mode, &vbe_mode_info);
-      if (grub_errno != GRUB_ERR_NONE)
-        {
-          /* Could not retrieve mode info, retreat.  */
-          grub_errno = GRUB_ERR_NONE;
-          break;
-        }
-
-      if ((vbe_mode_info.mode_attributes & 0x001) == 0)
-        /* If not available, skip it.  */
-        continue;
-
-      if ((vbe_mode_info.mode_attributes & 0x008) == 0)
-        /* Monochrome is unusable.  */
-        continue;
-
-      if ((vbe_mode_info.mode_attributes & 0x080) == 0)
-        /* We support only linear frame buffer modes.  */
-        continue;
-
-      if ((vbe_mode_info.mode_attributes & 0x010) == 0)
-        /* We allow only graphical modes.  */
-        continue;
-
-      if ((vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL)
-          && (vbe_mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR))
-        /* Not compatible memory model.  */
-        continue;
-
-      if (((vbe_mode_info.x_resolution != width)
-          || (vbe_mode_info.y_resolution != height)) && width != 0 && height != 0)
-        /* Non matching resolution.  */
-        continue;
-
-      /* Check if user requested RGB or index color mode.  */
-      if ((mode_mask & GRUB_VIDEO_MODE_TYPE_COLOR_MASK) != 0)
-        {
-         unsigned my_mode_type = 0;
-
-         if (vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL)
-           my_mode_type |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
-
-         if (vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR)
-           my_mode_type |= GRUB_VIDEO_MODE_TYPE_RGB;
-
-         if ((my_mode_type & mode_mask
-              & (GRUB_VIDEO_MODE_TYPE_RGB | GRUB_VIDEO_MODE_TYPE_INDEX_COLOR))
-             != (mode_type & mode_mask
-                 & (GRUB_VIDEO_MODE_TYPE_RGB
-                    | GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)))
-           continue;
-        }
-
-      /* If there is a request for specific depth, ignore others.  */
-      if ((depth != 0) && (vbe_mode_info.bits_per_pixel != depth))
-        continue;
-
-      /* Select mode with most of "volume" (size of framebuffer in bits).  */
-      if (best_vbe_mode != 0)
-        if ((grub_uint64_t) vbe_mode_info.bits_per_pixel
-           * vbe_mode_info.x_resolution * vbe_mode_info.y_resolution
-           < (grub_uint64_t) best_vbe_mode_info.bits_per_pixel
-           * best_vbe_mode_info.x_resolution * best_vbe_mode_info.y_resolution)
-          continue;
-
-      /* Save so far best mode information for later use.  */
-      best_vbe_mode = vbe_mode;
-      grub_memcpy (&best_vbe_mode_info, &vbe_mode_info, sizeof (vbe_mode_info));
-    }
-
-  /* Try to initialize best mode found.  */
-  if (best_vbe_mode != 0)
-    {
-      grub_err_t err;
-      /* If this fails, then we have mode selection heuristics problem,
-         or adapter failure.  */
-      /* grub_vbe_set_video_mode already sets active_vbe_mode_info. */
-      grub_vbe_set_video_mode (best_vbe_mode, NULL);
-      if (grub_errno != GRUB_ERR_NONE)
-        return grub_errno;
-
-      /* Fill mode info details.  */
-      framebuffer.mode_info.width = active_vbe_mode_info.x_resolution;
-      framebuffer.mode_info.height = active_vbe_mode_info.y_resolution;
-
-      if (framebuffer.index_color_mode)
-        framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
-      else
-        framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
-
-      framebuffer.mode_info.bpp = active_vbe_mode_info.bits_per_pixel;
-      framebuffer.mode_info.bytes_per_pixel = framebuffer.bytes_per_pixel;
-      framebuffer.mode_info.pitch = framebuffer.bytes_per_scan_line;
-      framebuffer.mode_info.number_of_colors = 256; /* TODO: fix me.  */
-      framebuffer.mode_info.red_mask_size = active_vbe_mode_info.red_mask_size;
-      framebuffer.mode_info.red_field_pos = active_vbe_mode_info.red_field_position;
-      framebuffer.mode_info.green_mask_size = active_vbe_mode_info.green_mask_size;
-      framebuffer.mode_info.green_field_pos = active_vbe_mode_info.green_field_position;
-      framebuffer.mode_info.blue_mask_size = active_vbe_mode_info.blue_mask_size;
-      framebuffer.mode_info.blue_field_pos = active_vbe_mode_info.blue_field_position;
-      framebuffer.mode_info.reserved_mask_size = active_vbe_mode_info.rsvd_mask_size;
-      framebuffer.mode_info.reserved_field_pos = active_vbe_mode_info.rsvd_field_position;
-
-      framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info);
-
-      /* Set up double buffering and targets.  */
-      err = double_buffering_init (mode_type, mode_mask);
-      if (err)
-       return err;
-
-      err = grub_video_fb_set_active_render_target (framebuffer.back_target);
-
-      if (err)
-       return err;
-
-      /* Copy default palette to initialize emulated palette.  */
-      err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
-                                      grub_video_fbstd_colors);
-      return err;
-    }
-
-  /* Couldn't found matching mode.  */
-  return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found");
-}
-
-static grub_err_t
-grub_video_vbe_set_palette (unsigned int start, unsigned int count,
-                            struct grub_video_palette_data *palette_data)
-{
-  if (framebuffer.index_color_mode)
-    {
-      /* TODO: Implement setting indexed color mode palette to hardware.  */
-      //status = grub_vbe_bios_set_palette_data (sizeof (vga_colors)
-      //                                         / sizeof (struct grub_vbe_palette_data),
-      //                                         0,
-      //                                         palette);
-
-    }
-
-  /* Then set color to emulated palette.  */
-
-  return grub_video_fb_set_palette (start, count, palette_data);
-}
-
-static grub_err_t
-grub_video_vbe_swap_buffers (void)
-{
-  grub_err_t err;
-  if (!framebuffer.update_screen)
-    return GRUB_ERR_NONE;
-
-  err = framebuffer.update_screen (framebuffer.front_target,
-                                  framebuffer.back_target);
-  if (err)
-    return err;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_vbe_set_active_render_target (struct grub_video_render_target *target)
-{
-  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
-      target = framebuffer.back_target;
-
-  return grub_video_fb_set_active_render_target (target);
-}
-
-static grub_err_t
-grub_video_vbe_get_active_render_target (struct grub_video_render_target **target)
-{
-  grub_err_t err;
-  err = grub_video_fb_get_active_render_target (target);
-  if (err)
-    return err;
-
-  if (*target == framebuffer.back_target)
-    *target = GRUB_VIDEO_RENDER_TARGET_DISPLAY;
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info,
-                                 void **framebuf)
-{
-  grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
-  *framebuf = (char *) framebuffer.ptr
-    + framebuffer.displayed_page * framebuffer.page_size;
-
-  grub_free (vbe_mode_list);
-  vbe_mode_list = NULL;
-
-  grub_video_fb_fini ();
-  grub_free (framebuffer.offscreen_buffer);
-
-  return GRUB_ERR_NONE;
-}
-
-static struct grub_video_adapter grub_video_vbe_adapter =
-  {
-    .name = "VESA BIOS Extension Video Driver",
-    .id = GRUB_VIDEO_DRIVER_VBE,
-
-    .init = grub_video_vbe_init,
-    .fini = grub_video_vbe_fini,
-    .setup = grub_video_vbe_setup,
-    .get_info = grub_video_fb_get_info,
-    .get_info_and_fini = grub_video_vbe_get_info_and_fini,
-    .set_palette = grub_video_vbe_set_palette,
-    .get_palette = grub_video_fb_get_palette,
-    .set_viewport = grub_video_fb_set_viewport,
-    .get_viewport = grub_video_fb_get_viewport,
-    .map_color = grub_video_fb_map_color,
-    .map_rgb = grub_video_fb_map_rgb,
-    .map_rgba = grub_video_fb_map_rgba,
-    .unmap_color = grub_video_fb_unmap_color,
-    .fill_rect = grub_video_fb_fill_rect,
-    .blit_bitmap = grub_video_fb_blit_bitmap,
-    .blit_render_target = grub_video_fb_blit_render_target,
-    .scroll = grub_video_fb_scroll,
-    .swap_buffers = grub_video_vbe_swap_buffers,
-    .create_render_target = grub_video_fb_create_render_target,
-    .delete_render_target = grub_video_fb_delete_render_target,
-    .set_active_render_target = grub_video_vbe_set_active_render_target,
-    .get_active_render_target = grub_video_vbe_get_active_render_target,
-
-    .next = 0
-  };
-
-GRUB_MOD_INIT(video_i386_pc_vbe)
-{
-  grub_video_register (&grub_video_vbe_adapter);
-}
-
-GRUB_MOD_FINI(video_i386_pc_vbe)
-{
-  grub_video_unregister (&grub_video_vbe_adapter);
-}
diff --git a/video/ieee1275.c b/video/ieee1275.c
deleted file mode 100644 (file)
index 5c6bc15..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define grub_video_render_target grub_video_fbrender_target
-
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/video.h>
-#include <grub/video_fb.h>
-#include <grub/ieee1275/ieee1275.h>
-
-/* Only 8-bit indexed color is supported for now.  */
-
-static unsigned old_width, old_height;
-static int restore_needed;
-static char *display;
-
-static struct
-{
-  struct grub_video_mode_info mode_info;
-  struct grub_video_render_target *render_target;
-  grub_uint8_t *ptr;
-} framebuffer;
-
-static grub_err_t
-grub_video_ieee1275_set_palette (unsigned int start, unsigned int count,
-                                struct grub_video_palette_data *palette_data);
-
-static void
-set_video_mode (unsigned width __attribute__ ((unused)),
-               unsigned height __attribute__ ((unused)))
-{
-  /* TODO */
-}
-
-static void
-find_display (void)
-{
-  auto int hook (struct grub_ieee1275_devalias *alias);
-  int hook (struct grub_ieee1275_devalias *alias)
-  {
-    if (grub_strcmp (alias->type, "display") == 0)
-      {
-       grub_dprintf ("video", "Found display %s\n", alias->path);
-       display = grub_strdup (alias->path);
-       return 1;
-      }
-    return 0;
-  }
-  
-  grub_ieee1275_devices_iterate (hook);
-}
-
-static grub_err_t
-grub_video_ieee1275_init (void)
-{
-  grub_memset (&framebuffer, 0, sizeof(framebuffer));
-  return grub_video_fb_init ();
-}
-
-static grub_err_t
-grub_video_ieee1275_fini (void)
-{
-  if (restore_needed)
-    {
-      set_video_mode (old_width, old_height);
-      restore_needed = 0;
-    }
-  return grub_video_fb_fini ();
-}
-
-static grub_err_t
-grub_video_ieee1275_fill_mode_info (grub_ieee1275_phandle_t dev,
-                                   struct grub_video_mode_info *out)
-{
-  grub_uint32_t tmp;
-
-  grub_memset (out, 0, sizeof (*out));
-
-  if (grub_ieee1275_get_integer_property (dev, "width", &tmp,
-                                         sizeof (tmp), 0))
-    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display width.");
-  out->width = tmp;
-
-  if (grub_ieee1275_get_integer_property (dev, "height", &tmp,
-                                         sizeof (tmp), 0))
-    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display height.");
-  out->height = tmp;
-
-  if (grub_ieee1275_get_integer_property (dev, "linebytes", &tmp,
-                                         sizeof (tmp), 0))
-    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display pitch.");
-  out->pitch = tmp;
-
-  out->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
-  out->bpp = 8;
-  out->bytes_per_pixel = 1;
-  out->number_of_colors = 256;
-
-  out->blit_format = grub_video_get_blit_format (out);
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_ieee1275_setup (unsigned int width, unsigned int height,
-                          unsigned int mode_type __attribute__ ((unused)),
-                          unsigned int mode_mask __attribute__ ((unused)))
-{
-  grub_uint32_t current_width, current_height, address;
-  grub_err_t err;
-  grub_ieee1275_phandle_t dev;
-
-  if (!display)
-    return grub_error (GRUB_ERR_IO, "Couldn't find display device.");
-
-  if (grub_ieee1275_finddevice (display, &dev))
-    return grub_error (GRUB_ERR_IO, "Couldn't open display device.");
-
-  if (grub_ieee1275_get_integer_property (dev, "width", &current_width,
-                                         sizeof (current_width), 0))
-    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display width.");
-
-  if (grub_ieee1275_get_integer_property (dev, "height", &current_height,
-                                         sizeof (current_width), 0))
-    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display height.");
-
-  if ((width == current_width && height == current_height)
-      || (width == 0 && height == 0))
-    {
-      grub_dprintf ("video", "IEEE1275: keeping current mode %dx%d\n",
-                   current_width, current_height);
-    }
-  else
-    {
-      grub_dprintf ("video", "IEEE1275: Setting mode %dx%d\n", width, height);
-      /* TODO. */
-      return grub_error (GRUB_ERR_IO, "can't set mode %dx%d", width, height);
-    }
-  
-  err = grub_video_ieee1275_fill_mode_info (dev, &framebuffer.mode_info);
-  if (err)
-    {
-      grub_dprintf ("video", "IEEE1275: couldn't fill mode info\n");
-      return err;
-    }
-
-  if (grub_ieee1275_get_integer_property (dev, "address", (void *) &address,
-                                         sizeof (address), 0))
-    return grub_error (GRUB_ERR_IO, "Couldn't retrieve display address.");
-
-  /* For some reason sparc64 uses 32-bit pointer too.  */
-  framebuffer.ptr = (void *) (grub_addr_t) address;
-
-  grub_video_ieee1275_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
-                                  grub_video_fbstd_colors);
-
-  grub_dprintf ("video", "IEEE1275: initialising FB @ %p %dx%dx%d\n",
-               framebuffer.ptr, framebuffer.mode_info.width,
-               framebuffer.mode_info.height, framebuffer.mode_info.bpp);
-  
-  err = grub_video_fb_create_render_target_from_pointer 
-    (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr);
-
-  if (err)
-    {
-      grub_dprintf ("video", "IEEE1275: Couldn't create FB target\n");
-      return err;
-    }
-  
-  err = grub_video_fb_set_active_render_target (framebuffer.render_target);
-  
-  if (err)
-    {
-      grub_dprintf ("video", "IEEE1275: Couldn't set FB target\n");
-      return err;
-    }
-  
-  err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
-                                  grub_video_fbstd_colors);
-
-  if (err)
-    grub_dprintf ("video", "IEEE1275: Couldn't set palette\n");
-  else
-    grub_dprintf ("video", "IEEE1275: Success\n");
-  
-  return err;
-}
-
-static grub_err_t
-grub_video_ieee1275_swap_buffers (void)
-{
-  /* TODO: Implement buffer swapping.  */
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_ieee1275_set_active_render_target (struct grub_video_render_target *target)
-{
-  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
-    target = framebuffer.render_target;
-
-  return grub_video_fb_set_active_render_target (target);
-}
-
-static grub_err_t
-grub_video_ieee1275_get_info_and_fini (struct grub_video_mode_info *mode_info,
-                                 void **framebuf)
-{
-  grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
-  *framebuf = (char *) framebuffer.ptr;
-
-  grub_video_fb_fini ();
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_ieee1275_set_palette (unsigned int start, unsigned int count,
-                                struct grub_video_palette_data *palette_data)
-{
-  grub_err_t err;
-  struct grub_video_palette_data fb_palette_data[256];
-
-  err = grub_video_fb_set_palette (start, count, palette_data);
-  if (err)
-    return err;
-
-  grub_video_fb_get_palette (0, 256, fb_palette_data);
-
-  /* TODO. */
-
-  return GRUB_ERR_NONE;
-}
-
-static struct grub_video_adapter grub_video_ieee1275_adapter =
-  {
-    .name = "IEEE1275 video driver",
-
-    .init = grub_video_ieee1275_init,
-    .fini = grub_video_ieee1275_fini,
-    .setup = grub_video_ieee1275_setup,
-    .get_info = grub_video_fb_get_info,
-    .get_info_and_fini = grub_video_ieee1275_get_info_and_fini,
-    .set_palette = grub_video_ieee1275_set_palette,
-    .get_palette = grub_video_fb_get_palette,
-    .set_viewport = grub_video_fb_set_viewport,
-    .get_viewport = grub_video_fb_get_viewport,
-    .map_color = grub_video_fb_map_color,
-    .map_rgb = grub_video_fb_map_rgb,
-    .map_rgba = grub_video_fb_map_rgba,
-    .unmap_color = grub_video_fb_unmap_color,
-    .fill_rect = grub_video_fb_fill_rect,
-    .blit_bitmap = grub_video_fb_blit_bitmap,
-    .blit_render_target = grub_video_fb_blit_render_target,
-    .scroll = grub_video_fb_scroll,
-    .swap_buffers = grub_video_ieee1275_swap_buffers,
-    .create_render_target = grub_video_fb_create_render_target,
-    .delete_render_target = grub_video_fb_delete_render_target,
-    .set_active_render_target = grub_video_ieee1275_set_active_render_target,
-    .get_active_render_target = grub_video_fb_get_active_render_target,
-
-    .next = 0
-  };
-
-GRUB_MOD_INIT(ieee1275_fb)
-{
-  find_display ();
-  if (display)
-    grub_video_register (&grub_video_ieee1275_adapter);
-}
-
-GRUB_MOD_FINI(ieee1275_fb)
-{
-  if (restore_needed)
-    {
-      set_video_mode (old_width, old_height);
-      restore_needed = 0;
-    }
-  if (display)
-    grub_video_unregister (&grub_video_ieee1275_adapter);
-  grub_free (display);
-}
diff --git a/video/readers/jpeg.c b/video/readers/jpeg.c
deleted file mode 100644 (file)
index 5e749b8..0000000
+++ /dev/null
@@ -1,750 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/bitmap.h>
-#include <grub/types.h>
-#include <grub/normal.h>
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/bufio.h>
-
-/* Uncomment following define to enable JPEG debug.  */
-//#define JPEG_DEBUG
-
-#define JPEG_ESC_CHAR          0xFF
-
-#define JPEG_SAMPLING_1x1      0x11
-
-#define JPEG_MARKER_SOI                0xd8
-#define JPEG_MARKER_EOI                0xd9
-#define JPEG_MARKER_DHT                0xc4
-#define JPEG_MARKER_DQT                0xdb
-#define JPEG_MARKER_SOF0       0xc0
-#define JPEG_MARKER_SOS                0xda
-
-#define SHIFT_BITS             8
-#define CONST(x)               ((int) ((x) * (1L << SHIFT_BITS) + 0.5))
-
-#define JPEG_UNIT_SIZE         8
-
-static const grub_uint8_t jpeg_zigzag_order[64] = {
-  0, 1, 8, 16, 9, 2, 3, 10,
-  17, 24, 32, 25, 18, 11, 4, 5,
-  12, 19, 26, 33, 40, 48, 41, 34,
-  27, 20, 13, 6, 7, 14, 21, 28,
-  35, 42, 49, 56, 57, 50, 43, 36,
-  29, 22, 15, 23, 30, 37, 44, 51,
-  58, 59, 52, 45, 38, 31, 39, 46,
-  53, 60, 61, 54, 47, 55, 62, 63
-};
-
-#ifdef JPEG_DEBUG
-static grub_command_t cmd;
-#endif
-
-typedef int jpeg_data_unit_t[64];
-
-struct grub_jpeg_data
-{
-  grub_file_t file;
-  struct grub_video_bitmap **bitmap;
-
-  int image_width;
-  int image_height;
-
-  grub_uint8_t *huff_value[4];
-  int huff_offset[4][16];
-  int huff_maxval[4][16];
-
-  grub_uint8_t quan_table[2][64];
-  int comp_index[3][3];
-
-  jpeg_data_unit_t ydu[4];
-  jpeg_data_unit_t crdu;
-  jpeg_data_unit_t cbdu;
-
-  int vs, hs;
-
-  int dc_value[3];
-
-  int bit_mask, bit_save;
-};
-
-static grub_uint8_t
-grub_jpeg_get_byte (struct grub_jpeg_data *data)
-{
-  grub_uint8_t r;
-
-  r = 0;
-  grub_file_read (data->file, &r, 1);
-
-  return r;
-}
-
-static grub_uint16_t
-grub_jpeg_get_word (struct grub_jpeg_data *data)
-{
-  grub_uint16_t r;
-
-  r = 0;
-  grub_file_read (data->file, &r, sizeof (grub_uint16_t));
-
-  return grub_be_to_cpu16 (r);
-}
-
-static int
-grub_jpeg_get_bit (struct grub_jpeg_data *data)
-{
-  int ret;
-
-  if (data->bit_mask == 0)
-    {
-      data->bit_save = grub_jpeg_get_byte (data);
-      if (data->bit_save == JPEG_ESC_CHAR)
-       {
-         if (grub_jpeg_get_byte (data) != 0)
-           {
-             grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                         "jpeg: invalid 0xFF in data stream");
-             return 0;
-           }
-       }
-      data->bit_mask = 0x80;
-    }
-
-  ret = ((data->bit_save & data->bit_mask) != 0);
-  data->bit_mask >>= 1;
-  return ret;
-}
-
-static int
-grub_jpeg_get_number (struct grub_jpeg_data *data, int num)
-{
-  int value, i, msb;
-
-  if (num == 0)
-    return 0;
-
-  msb = value = grub_jpeg_get_bit (data);
-  for (i = 1; i < num; i++)
-    value = (value << 1) + (grub_jpeg_get_bit (data) != 0);
-  if (!msb)
-    value += 1 - (1 << num);
-
-  return value;
-}
-
-static int
-grub_jpeg_get_huff_code (struct grub_jpeg_data *data, int id)
-{
-  int code, i;
-
-  code = 0;
-  for (i = 0; i < 16; i++)
-    {
-      code <<= 1;
-      if (grub_jpeg_get_bit (data))
-       code++;
-      if (code < data->huff_maxval[id][i])
-       return data->huff_value[id][code + data->huff_offset[id][i]];
-    }
-  grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: huffman decode fails");
-  return 0;
-}
-
-static grub_err_t
-grub_jpeg_decode_huff_table (struct grub_jpeg_data *data)
-{
-  int id, ac, i, n, base, ofs;
-  grub_uint32_t next_marker;
-  grub_uint8_t count[16];
-
-  next_marker = data->file->offset;
-  next_marker += grub_jpeg_get_word (data);
-
-  id = grub_jpeg_get_byte (data);
-  ac = (id >> 4);
-  id &= 0xF;
-  if (id > 1)
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                      "jpeg: too many huffman tables");
-
-  if (grub_file_read (data->file, &count, sizeof (count)) !=
-      sizeof (count))
-    return grub_errno;
-
-  n = 0;
-  for (i = 0; i < 16; i++)
-    n += count[i];
-
-  id += ac * 2;
-  data->huff_value[id] = grub_malloc (n);
-  if (grub_errno)
-    return grub_errno;
-
-  if (grub_file_read (data->file, data->huff_value[id], n) != n)
-    return grub_errno;
-
-  base = 0;
-  ofs = 0;
-  for (i = 0; i < 16; i++)
-    {
-      base += count[i];
-      ofs += count[i];
-
-      data->huff_maxval[id][i] = base;
-      data->huff_offset[id][i] = ofs - base;
-
-      base <<= 1;
-    }
-
-  if (data->file->offset != next_marker)
-    grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in huffman table");
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_jpeg_decode_quan_table (struct grub_jpeg_data *data)
-{
-  int id;
-  grub_uint32_t next_marker;
-
-  next_marker = data->file->offset;
-  next_marker += grub_jpeg_get_word (data);
-
-  id = grub_jpeg_get_byte (data);
-  if (id >= 0x10)              /* Upper 4-bit is precision.  */
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                      "jpeg: only 8-bit precision is supported");
-
-  if (id > 1)
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                      "jpeg: too many quantization tables");
-
-  if (grub_file_read (data->file, &data->quan_table[id], 64) != 64)
-    return grub_errno;
-
-  if (data->file->offset != next_marker)
-    grub_error (GRUB_ERR_BAD_FILE_TYPE,
-               "jpeg: extra byte in quantization table");
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_jpeg_decode_sof (struct grub_jpeg_data *data)
-{
-  int i, cc;
-  grub_uint32_t next_marker;
-
-  next_marker = data->file->offset;
-  next_marker += grub_jpeg_get_word (data);
-
-  if (grub_jpeg_get_byte (data) != 8)
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                      "jpeg: only 8-bit precision is supported");
-
-  data->image_height = grub_jpeg_get_word (data);
-  data->image_width = grub_jpeg_get_word (data);
-
-  if ((!data->image_height) || (!data->image_width))
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid image size");
-
-  cc = grub_jpeg_get_byte (data);
-  if (cc != 3)
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                      "jpeg: component count must be 3");
-
-  for (i = 0; i < cc; i++)
-    {
-      int id, ss;
-
-      id = grub_jpeg_get_byte (data) - 1;
-      if ((id < 0) || (id >= 3))
-       return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index");
-
-      ss = grub_jpeg_get_byte (data);  /* Sampling factor.  */
-      if (!id)
-       {
-         data->vs = ss & 0xF;  /* Vertical sampling.  */
-         data->hs = ss >> 4;   /* Horizontal sampling.  */
-         if ((data->vs > 2) || (data->hs > 2))
-           return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                              "jpeg: sampling method not supported");
-       }
-      else if (ss != JPEG_SAMPLING_1x1)
-       return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                          "jpeg: sampling method not supported");
-      data->comp_index[id][0] = grub_jpeg_get_byte (data);
-    }
-
-  if (data->file->offset != next_marker)
-    grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sof");
-
-  return grub_errno;
-}
-
-static void
-grub_jpeg_idct_transform (jpeg_data_unit_t du)
-{
-  int *pd;
-  int i;
-  int t0, t1, t2, t3, t4, t5, t6, t7;
-  int v0, v1, v2, v3, v4;
-
-  pd = du;
-  for (i = 0; i < JPEG_UNIT_SIZE; i++, pd++)
-    {
-      if ((pd[JPEG_UNIT_SIZE * 1] | pd[JPEG_UNIT_SIZE * 2] |
-          pd[JPEG_UNIT_SIZE * 3] | pd[JPEG_UNIT_SIZE * 4] |
-          pd[JPEG_UNIT_SIZE * 5] | pd[JPEG_UNIT_SIZE * 6] |
-          pd[JPEG_UNIT_SIZE * 7]) == 0)
-       {
-         pd[JPEG_UNIT_SIZE * 0] <<= SHIFT_BITS;
-
-         pd[JPEG_UNIT_SIZE * 1] = pd[JPEG_UNIT_SIZE * 2]
-           = pd[JPEG_UNIT_SIZE * 3] = pd[JPEG_UNIT_SIZE * 4]
-           = pd[JPEG_UNIT_SIZE * 5] = pd[JPEG_UNIT_SIZE * 6]
-           = pd[JPEG_UNIT_SIZE * 7] = pd[JPEG_UNIT_SIZE * 0];
-
-         continue;
-       }
-
-      t0 = pd[JPEG_UNIT_SIZE * 0];
-      t1 = pd[JPEG_UNIT_SIZE * 2];
-      t2 = pd[JPEG_UNIT_SIZE * 4];
-      t3 = pd[JPEG_UNIT_SIZE * 6];
-
-      v4 = (t1 + t3) * CONST (0.541196100);
-
-      v0 = ((t0 + t2) << SHIFT_BITS);
-      v1 = ((t0 - t2) << SHIFT_BITS);
-      v2 = v4 - t3 * CONST (1.847759065);
-      v3 = v4 + t1 * CONST (0.765366865);
-
-      t0 = v0 + v3;
-      t3 = v0 - v3;
-      t1 = v1 + v2;
-      t2 = v1 - v2;
-
-      t4 = pd[JPEG_UNIT_SIZE * 7];
-      t5 = pd[JPEG_UNIT_SIZE * 5];
-      t6 = pd[JPEG_UNIT_SIZE * 3];
-      t7 = pd[JPEG_UNIT_SIZE * 1];
-
-      v0 = t4 + t7;
-      v1 = t5 + t6;
-      v2 = t4 + t6;
-      v3 = t5 + t7;
-
-      v4 = (v2 + v3) * CONST (1.175875602);
-
-      v0 *= CONST (0.899976223);
-      v1 *= CONST (2.562915447);
-      v2 = v2 * CONST (1.961570560) - v4;
-      v3 = v3 * CONST (0.390180644) - v4;
-
-      t4 = t4 * CONST (0.298631336) - v0 - v2;
-      t5 = t5 * CONST (2.053119869) - v1 - v3;
-      t6 = t6 * CONST (3.072711026) - v1 - v2;
-      t7 = t7 * CONST (1.501321110) - v0 - v3;
-
-      pd[JPEG_UNIT_SIZE * 0] = t0 + t7;
-      pd[JPEG_UNIT_SIZE * 7] = t0 - t7;
-      pd[JPEG_UNIT_SIZE * 1] = t1 + t6;
-      pd[JPEG_UNIT_SIZE * 6] = t1 - t6;
-      pd[JPEG_UNIT_SIZE * 2] = t2 + t5;
-      pd[JPEG_UNIT_SIZE * 5] = t2 - t5;
-      pd[JPEG_UNIT_SIZE * 3] = t3 + t4;
-      pd[JPEG_UNIT_SIZE * 4] = t3 - t4;
-    }
-
-  pd = du;
-  for (i = 0; i < JPEG_UNIT_SIZE; i++, pd += JPEG_UNIT_SIZE)
-    {
-      if ((pd[1] | pd[2] | pd[3] | pd[4] | pd[5] | pd[6] | pd[7]) == 0)
-       {
-         pd[0] >>= (SHIFT_BITS + 3);
-         pd[1] = pd[2] = pd[3] = pd[4] = pd[5] = pd[6] = pd[7] = pd[0];
-         continue;
-       }
-
-      v4 = (pd[2] + pd[6]) * CONST (0.541196100);
-
-      v0 = (pd[0] + pd[4]) << SHIFT_BITS;
-      v1 = (pd[0] - pd[4]) << SHIFT_BITS;
-      v2 = v4 - pd[6] * CONST (1.847759065);
-      v3 = v4 + pd[2] * CONST (0.765366865);
-
-      t0 = v0 + v3;
-      t3 = v0 - v3;
-      t1 = v1 + v2;
-      t2 = v1 - v2;
-
-      t4 = pd[7];
-      t5 = pd[5];
-      t6 = pd[3];
-      t7 = pd[1];
-
-      v0 = t4 + t7;
-      v1 = t5 + t6;
-      v2 = t4 + t6;
-      v3 = t5 + t7;
-
-      v4 = (v2 + v3) * CONST (1.175875602);
-
-      v0 *= CONST (0.899976223);
-      v1 *= CONST (2.562915447);
-      v2 = v2 * CONST (1.961570560) - v4;
-      v3 = v3 * CONST (0.390180644) - v4;
-
-      t4 = t4 * CONST (0.298631336) - v0 - v2;
-      t5 = t5 * CONST (2.053119869) - v1 - v3;
-      t6 = t6 * CONST (3.072711026) - v1 - v2;
-      t7 = t7 * CONST (1.501321110) - v0 - v3;
-
-      pd[0] = (t0 + t7) >> (SHIFT_BITS * 2 + 3);
-      pd[7] = (t0 - t7) >> (SHIFT_BITS * 2 + 3);
-      pd[1] = (t1 + t6) >> (SHIFT_BITS * 2 + 3);
-      pd[6] = (t1 - t6) >> (SHIFT_BITS * 2 + 3);
-      pd[2] = (t2 + t5) >> (SHIFT_BITS * 2 + 3);
-      pd[5] = (t2 - t5) >> (SHIFT_BITS * 2 + 3);
-      pd[3] = (t3 + t4) >> (SHIFT_BITS * 2 + 3);
-      pd[4] = (t3 - t4) >> (SHIFT_BITS * 2 + 3);
-    }
-
-  for (i = 0; i < JPEG_UNIT_SIZE * JPEG_UNIT_SIZE; i++)
-    {
-      du[i] += 128;
-
-      if (du[i] < 0)
-       du[i] = 0;
-      if (du[i] > 255)
-       du[i] = 255;
-    }
-}
-
-static void
-grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
-{
-  int pos, h1, h2, qt;
-
-  grub_memset (du, 0, sizeof (jpeg_data_unit_t));
-
-  qt = data->comp_index[id][0];
-  h1 = data->comp_index[id][1];
-  h2 = data->comp_index[id][2];
-
-  data->dc_value[id] +=
-    grub_jpeg_get_number (data, grub_jpeg_get_huff_code (data, h1));
-
-  du[0] = data->dc_value[id] * (int) data->quan_table[qt][0];
-  pos = 1;
-  while (pos < 64)
-    {
-      int num, val;
-
-      num = grub_jpeg_get_huff_code (data, h2);
-      if (!num)
-       break;
-
-      val = grub_jpeg_get_number (data, num & 0xF);
-      num >>= 4;
-      pos += num;
-      du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos];
-      pos++;
-    }
-
-  grub_jpeg_idct_transform (du);
-}
-
-static void
-grub_jpeg_ycrcb_to_rgb (int yy, int cr, int cb, grub_uint8_t * rgb)
-{
-  int dd;
-
-  cr -= 128;
-  cb -= 128;
-
-  /* Red  */
-  dd = yy + ((cr * CONST (1.402)) >> SHIFT_BITS);
-  if (dd < 0)
-    dd = 0;
-  if (dd > 255)
-    dd = 255;
-  *(rgb++) = dd;
-
-  /* Green  */
-  dd = yy - ((cb * CONST (0.34414) + cr * CONST (0.71414)) >> SHIFT_BITS);
-  if (dd < 0)
-    dd = 0;
-  if (dd > 255)
-    dd = 255;
-  *(rgb++) = dd;
-
-  /* Blue  */
-  dd = yy + ((cb * CONST (1.772)) >> SHIFT_BITS);
-  if (dd < 0)
-    dd = 0;
-  if (dd > 255)
-    dd = 255;
-  *(rgb++) = dd;
-}
-
-static grub_err_t
-grub_jpeg_decode_sos (struct grub_jpeg_data *data)
-{
-  int i, cc, r1, c1, nr1, nc1, vb, hb;
-  grub_uint8_t *ptr1;
-  grub_uint32_t data_offset;
-
-  data_offset = data->file->offset;
-  data_offset += grub_jpeg_get_word (data);
-
-  cc = grub_jpeg_get_byte (data);
-
-  if (cc != 3)
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                      "jpeg: component count must be 3");
-
-  for (i = 0; i < cc; i++)
-    {
-      int id, ht;
-
-      id = grub_jpeg_get_byte (data) - 1;
-      if ((id < 0) || (id >= 3))
-       return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index");
-
-      ht = grub_jpeg_get_byte (data);
-      data->comp_index[id][1] = (ht >> 4);
-      data->comp_index[id][2] = (ht & 0xF) + 2;
-    }
-
-  grub_jpeg_get_byte (data);   /* Skip 3 unused bytes.  */
-  grub_jpeg_get_word (data);
-
-  if (data->file->offset != data_offset)
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos");
-
-  if (grub_video_bitmap_create (data->bitmap, data->image_width,
-                               data->image_height,
-                               GRUB_VIDEO_BLIT_FORMAT_RGB_888))
-    return grub_errno;
-
-  data->bit_mask = 0x0;
-
-  vb = data->vs * 8;
-  hb = data->hs * 8;
-  nr1 = (data->image_height + vb - 1) / vb;
-  nc1 = (data->image_width + hb - 1) / hb;
-
-  ptr1 = (*data->bitmap)->data;
-  for (r1 = 0; r1 < nr1;
-       r1++, ptr1 += (vb * data->image_width - hb * nc1) * 3)
-    for (c1 = 0; c1 < nc1; c1++, ptr1 += hb * 3)
-      {
-       int r2, c2, nr2, nc2;
-       grub_uint8_t *ptr2;
-
-       for (r2 = 0; r2 < data->vs; r2++)
-         for (c2 = 0; c2 < data->hs; c2++)
-           grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]);
-
-       grub_jpeg_decode_du (data, 1, data->cbdu);
-       grub_jpeg_decode_du (data, 2, data->crdu);
-
-       if (grub_errno)
-         return grub_errno;
-
-       nr2 = (r1 == nr1 - 1) ? (data->image_height - r1 * vb) : vb;
-       nc2 = (c1 == nc1 - 1) ? (data->image_width - c1 * hb) : hb;
-
-       ptr2 = ptr1;
-       for (r2 = 0; r2 < nr2; r2++, ptr2 += (data->image_width - nc2) * 3)
-         for (c2 = 0; c2 < nc2; c2++, ptr2 += 3)
-           {
-             int i0, yy, cr, cb;
-
-             i0 = (r2 / data->vs) * 8 + (c2 / data->hs);
-             cr = data->crdu[i0];
-             cb = data->cbdu[i0];
-             yy =
-               data->ydu[(r2 / 8) * 2 + (c2 / 8)][(r2 % 8) * 8 + (c2 % 8)];
-
-             grub_jpeg_ycrcb_to_rgb (yy, cr, cb, ptr2);
-           }
-      }
-
-  return grub_errno;
-}
-
-static grub_uint8_t
-grub_jpeg_get_marker (struct grub_jpeg_data *data)
-{
-  grub_uint8_t r;
-
-  r = grub_jpeg_get_byte (data);
-
-  if (r != JPEG_ESC_CHAR)
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid maker");
-      return 0;
-    }
-
-  return grub_jpeg_get_byte (data);
-}
-
-static grub_err_t
-grub_jpeg_decode_jpeg (struct grub_jpeg_data *data)
-{
-  if (grub_jpeg_get_marker (data) != JPEG_MARKER_SOI)  /* Start Of Image.  */
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid jpeg file");
-
-  while (grub_errno == 0)
-    {
-      grub_uint8_t marker;
-
-      marker = grub_jpeg_get_marker (data);
-      if (grub_errno)
-       break;
-
-#ifdef JPEG_DEBUG
-      grub_printf ("jpeg marker: %x\n", marker);
-#endif
-
-      switch (marker)
-       {
-       case JPEG_MARKER_DHT:   /* Define Huffman Table.  */
-         grub_jpeg_decode_huff_table (data);
-         break;
-       case JPEG_MARKER_DQT:   /* Define Quantization Table.  */
-         grub_jpeg_decode_quan_table (data);
-         break;
-       case JPEG_MARKER_SOF0:  /* Start Of Frame 0.  */
-         grub_jpeg_decode_sof (data);
-         break;
-       case JPEG_MARKER_SOS:   /* Start Of Scan.  */
-         grub_jpeg_decode_sos (data);
-         break;
-       case JPEG_MARKER_EOI:   /* End Of Image.  */
-         return grub_errno;
-       default:                /* Skip unrecognized marker.  */
-         {
-           grub_uint16_t sz;
-
-           sz = grub_jpeg_get_word (data);
-           if (grub_errno)
-             return (grub_errno);
-           grub_file_seek (data->file, data->file->offset + sz - 2);
-         }
-       }
-    }
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_video_reader_jpeg (struct grub_video_bitmap **bitmap,
-                       const char *filename)
-{
-  grub_file_t file;
-  struct grub_jpeg_data *data;
-
-  file = grub_buffile_open (filename, 0);
-  if (!file)
-    return grub_errno;
-
-  data = grub_zalloc (sizeof (*data));
-  if (data != NULL)
-    {
-      int i;
-
-      data->file = file;
-      data->bitmap = bitmap;
-      grub_jpeg_decode_jpeg (data);
-
-      for (i = 0; i < 4; i++)
-       if (data->huff_value[i])
-         grub_free (data->huff_value[i]);
-
-      grub_free (data);
-    }
-
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_video_bitmap_destroy (*bitmap);
-      *bitmap = 0;
-    }
-
-  grub_file_close (file);
-  return grub_errno;
-}
-
-#if defined(JPEG_DEBUG)
-static grub_err_t
-grub_cmd_jpegtest (grub_command_t cmd __attribute__ ((unused)),
-                   int argc, char **args)
-{
-  struct grub_video_bitmap *bitmap = 0;
-
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
-  grub_video_reader_jpeg (&bitmap, args[0]);
-  if (grub_errno != GRUB_ERR_NONE)
-    return grub_errno;
-
-  grub_video_bitmap_destroy (bitmap);
-
-  return GRUB_ERR_NONE;
-}
-#endif
-
-static struct grub_video_bitmap_reader jpg_reader = {
-  .extension = ".jpg",
-  .reader = grub_video_reader_jpeg,
-  .next = 0
-};
-
-static struct grub_video_bitmap_reader jpeg_reader = {
-  .extension = ".jpeg",
-  .reader = grub_video_reader_jpeg,
-  .next = 0
-};
-
-GRUB_MOD_INIT (jpeg)
-{
-  grub_video_bitmap_reader_register (&jpg_reader);
-  grub_video_bitmap_reader_register (&jpeg_reader);
-#if defined(JPEG_DEBUG)
-  cmd = grub_register_command ("jpegtest", grub_cmd_jpegtest,
-                              "FILE",
-                              "Tests loading of JPEG bitmap.");
-#endif
-}
-
-GRUB_MOD_FINI (jpeg)
-{
-#if defined(JPEG_DEBUG)
-  grub_unregister_command (cmd);
-#endif
-  grub_video_bitmap_reader_unregister (&jpeg_reader);
-  grub_video_bitmap_reader_unregister (&jpg_reader);
-}
diff --git a/video/readers/png.c b/video/readers/png.c
deleted file mode 100644 (file)
index 2cec49e..0000000
+++ /dev/null
@@ -1,913 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/bitmap.h>
-#include <grub/types.h>
-#include <grub/normal.h>
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/bufio.h>
-
-/* Uncomment following define to enable PNG debug.  */
-//#define PNG_DEBUG
-
-#define PNG_COLOR_MASK_PALETTE 1
-#define PNG_COLOR_MASK_COLOR   2
-#define PNG_COLOR_MASK_ALPHA   4
-
-#define PNG_COLOR_TYPE_GRAY    0
-#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
-#define PNG_COLOR_TYPE_RGB     (PNG_COLOR_MASK_COLOR)
-#define PNG_COLOR_TYPE_RGBA    (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
-#define PNG_COLOR_TYPE_GRAYA   (PNG_COLOR_MASK_ALPHA)
-
-#define PNG_COMPRESSION_BASE   0
-
-#define PNG_INTERLACE_NONE     0
-#define PNG_INTERLACE_ADAM7    1
-
-#define PNG_FILTER_TYPE_BASE   0
-
-#define PNG_FILTER_VALUE_NONE  0
-#define PNG_FILTER_VALUE_SUB   1
-#define PNG_FILTER_VALUE_UP    2
-#define PNG_FILTER_VALUE_AVG   3
-#define PNG_FILTER_VALUE_PAETH 4
-#define PNG_FILTER_VALUE_LAST  5
-
-#define PNG_CHUNK_IHDR         0x49484452
-#define PNG_CHUNK_IDAT         0x49444154
-#define PNG_CHUNK_IEND         0x49454e44
-
-#define Z_DEFLATED             8
-#define Z_FLAG_DICT            32
-
-#define INFLATE_STORED         0
-#define INFLATE_FIXED          1
-#define INFLATE_DYNAMIC                2
-
-#define WSIZE                  0x8000
-
-#define DEFLATE_HCLEN_BASE     4
-#define DEFLATE_HCLEN_MAX      19
-#define DEFLATE_HLIT_BASE      257
-#define DEFLATE_HLIT_MAX       288
-#define DEFLATE_HDIST_BASE     1
-#define DEFLATE_HDIST_MAX      30
-
-#define DEFLATE_HUFF_LEN       16
-
-#ifdef PNG_DEBUG
-static grub_command_t cmd;
-#endif
-
-struct huff_table
-{
-  int *values, *maxval, *offset;
-  int num_values, max_length;
-};
-
-struct grub_png_data
-{
-  grub_file_t file;
-  struct grub_video_bitmap **bitmap;
-
-  int bit_count, bit_save;
-
-  grub_uint32_t next_offset;
-
-  int image_width, image_height, bpp, is_16bit, raw_bytes;
-  grub_uint8_t *image_data;
-
-  int inside_idat, idat_remain;
-
-  int code_values[DEFLATE_HLIT_MAX];
-  int code_maxval[DEFLATE_HUFF_LEN];
-  int code_offset[DEFLATE_HUFF_LEN];
-
-  int dist_values[DEFLATE_HDIST_MAX];
-  int dist_maxval[DEFLATE_HUFF_LEN];
-  int dist_offset[DEFLATE_HUFF_LEN];
-
-  struct huff_table code_table;
-  struct huff_table dist_table;
-
-  grub_uint8_t slide[WSIZE];
-  int wp;
-
-  grub_uint8_t *cur_rgb;
-
-  int cur_column, cur_filter, first_line;
-};
-
-static grub_uint32_t
-grub_png_get_dword (struct grub_png_data *data)
-{
-  grub_uint32_t r;
-
-  r = 0;
-  grub_file_read (data->file, &r, sizeof (grub_uint32_t));
-
-  return grub_be_to_cpu32 (r);
-}
-
-static grub_uint8_t
-grub_png_get_byte (struct grub_png_data *data)
-{
-  grub_uint8_t r;
-
-  if ((data->inside_idat) && (data->idat_remain == 0))
-    {
-      grub_uint32_t len, type;
-
-      do
-       {
-          /* Skip crc checksum.  */
-         grub_png_get_dword (data);
-
-          if (data->file->offset != data->next_offset)
-            {
-              grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                          "png: chunk size error");
-              return 0;
-            }
-
-         len = grub_png_get_dword (data);
-         type = grub_png_get_dword (data);
-         if (type != PNG_CHUNK_IDAT)
-           {
-             grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                         "png: unexpected end of data");
-             return 0;
-           }
-
-          data->next_offset = data->file->offset + len + 4;
-       }
-      while (len == 0);
-      data->idat_remain = len;
-    }
-
-  r = 0;
-  grub_file_read (data->file, &r, 1);
-
-  if (data->inside_idat)
-    data->idat_remain--;
-
-  return r;
-}
-
-static int
-grub_png_get_bits (struct grub_png_data *data, int num)
-{
-  int code, shift;
-
-  if (data->bit_count == 0)
-    {
-      data->bit_save = grub_png_get_byte (data);
-      data->bit_count = 8;
-    }
-
-  code = 0;
-  shift = 0;
-  while (grub_errno == 0)
-    {
-      int n;
-
-      n = data->bit_count;
-      if (n > num)
-       n = num;
-
-      code += (int) (data->bit_save & ((1 << n) - 1)) << shift;
-      num -= n;
-      if (!num)
-       {
-         data->bit_count -= n;
-         data->bit_save >>= n;
-         break;
-       }
-
-      shift += n;
-
-      data->bit_save = grub_png_get_byte (data);
-      data->bit_count = 8;
-    }
-
-  return code;
-}
-
-static grub_err_t
-grub_png_decode_image_header (struct grub_png_data *data)
-{
-  int color_type;
-  int color_bits;
-
-  data->image_width = grub_png_get_dword (data);
-  data->image_height = grub_png_get_dword (data);
-
-  if ((!data->image_height) || (!data->image_width))
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid image size");
-
-  color_bits = grub_png_get_byte (data);
-  if ((color_bits != 8) && (color_bits != 16))
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                       "png: bit depth must be 8 or 16");
-  data->is_16bit = (color_bits == 16);
-
-  color_type = grub_png_get_byte (data);
-  if (color_type == PNG_COLOR_TYPE_RGB)
-    {
-      if (grub_video_bitmap_create (data->bitmap, data->image_width,
-                                   data->image_height,
-                                   GRUB_VIDEO_BLIT_FORMAT_RGB_888))
-       return grub_errno;
-      data->bpp = 3;
-    }
-  else if (color_type == PNG_COLOR_TYPE_RGBA)
-    {
-      if (grub_video_bitmap_create (data->bitmap, data->image_width,
-                                   data->image_height,
-                                   GRUB_VIDEO_BLIT_FORMAT_RGBA_8888))
-       return grub_errno;
-      data->bpp = 4;
-    }
-  else
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                      "png: color type not supported");
-
-  if (data->is_16bit)
-    {
-      data->bpp <<= 1;
-
-      data->image_data = grub_malloc (data->image_height *
-                                      data->image_width *  data->bpp);
-      if (grub_errno)
-        return grub_errno;
-
-      data->cur_rgb = data->image_data;
-    }
-  else
-    {
-      data->image_data = 0;
-      data->cur_rgb = (*data->bitmap)->data;
-    }
-
-  data->raw_bytes = data->image_height * (data->image_width + 1) * data->bpp;
-
-  data->cur_column = 0;
-  data->first_line = 1;
-
-  if (grub_png_get_byte (data) != PNG_COMPRESSION_BASE)
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                      "png: compression method not supported");
-
-  if (grub_png_get_byte (data) != PNG_FILTER_TYPE_BASE)
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                      "png: filter method not supported");
-
-  if (grub_png_get_byte (data) != PNG_INTERLACE_NONE)
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                      "png: interlace method not supported");
-
-  /* Skip crc checksum.  */
-  grub_png_get_dword (data);
-
-  return grub_errno;
-}
-
-/* Order of the bit length code lengths.  */
-static const grub_uint8_t bitorder[] = {
-  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
-};
-
-/* Copy lengths for literal codes 257..285.  */
-static const int cplens[] = {
-  3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
-  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
-};
-
-/* Extra bits for literal codes 257..285.  */
-static const grub_uint8_t cplext[] = {
-  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
-  3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99
-};                             /* 99==invalid  */
-
-/* Copy offsets for distance codes 0..29.  */
-static const int cpdist[] = {
-  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
-  257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
-  8193, 12289, 16385, 24577
-};
-
-/* Extra bits for distance codes.  */
-static const grub_uint8_t cpdext[] = {
-  0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
-  7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
-  12, 12, 13, 13
-};
-
-static void
-grub_png_init_huff_table (struct huff_table *ht, int cur_maxlen,
-                         int *cur_values, int *cur_maxval, int *cur_offset)
-{
-  ht->values = cur_values;
-  ht->maxval = cur_maxval;
-  ht->offset = cur_offset;
-  ht->num_values = 0;
-  ht->max_length = cur_maxlen;
-  grub_memset (cur_maxval, 0, sizeof (int) * cur_maxlen);
-}
-
-static void
-grub_png_insert_huff_item (struct huff_table *ht, int code, int len)
-{
-  int i, n;
-
-  if (len == 0)
-    return;
-
-  if (len > ht->max_length)
-    {
-      grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid code length");
-      return;
-    }
-
-  n = 0;
-  for (i = len; i < ht->max_length; i++)
-    n += ht->maxval[i];
-
-  for (i = 0; i < n; i++)
-    ht->values[ht->num_values - i] = ht->values[ht->num_values - i - 1];
-
-  ht->values[ht->num_values - n] = code;
-  ht->num_values++;
-  ht->maxval[len - 1]++;
-}
-
-static void
-grub_png_build_huff_table (struct huff_table *ht)
-{
-  int base, ofs, i;
-
-  base = 0;
-  ofs = 0;
-  for (i = 0; i < ht->max_length; i++)
-    {
-      base += ht->maxval[i];
-      ofs += ht->maxval[i];
-
-      ht->maxval[i] = base;
-      ht->offset[i] = ofs - base;
-
-      base <<= 1;
-    }
-}
-
-static int
-grub_png_get_huff_code (struct grub_png_data *data, struct huff_table *ht)
-{
-  int code, i;
-
-  code = 0;
-  for (i = 0; i < ht->max_length; i++)
-    {
-      code = (code << 1) + grub_png_get_bits (data, 1);
-      if (code < ht->maxval[i])
-       return ht->values[code + ht->offset[i]];
-    }
-  return 0;
-}
-
-static grub_err_t
-grub_png_init_fixed_block (struct grub_png_data *data)
-{
-  int i;
-
-  grub_png_init_huff_table (&data->code_table, DEFLATE_HUFF_LEN,
-                           data->code_values, data->code_maxval,
-                           data->code_offset);
-
-  for (i = 0; i < 144; i++)
-    grub_png_insert_huff_item (&data->code_table, i, 8);
-
-  for (; i < 256; i++)
-    grub_png_insert_huff_item (&data->code_table, i, 9);
-
-  for (; i < 280; i++)
-    grub_png_insert_huff_item (&data->code_table, i, 7);
-
-  for (; i < DEFLATE_HLIT_MAX; i++)
-    grub_png_insert_huff_item (&data->code_table, i, 8);
-
-  grub_png_build_huff_table (&data->code_table);
-
-  grub_png_init_huff_table (&data->dist_table, DEFLATE_HUFF_LEN,
-                           data->dist_values, data->dist_maxval,
-                           data->dist_offset);
-
-  for (i = 0; i < DEFLATE_HDIST_MAX; i++)
-    grub_png_insert_huff_item (&data->dist_table, i, 5);
-
-  grub_png_build_huff_table (&data->dist_table);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_png_init_dynamic_block (struct grub_png_data *data)
-{
-  int nl, nd, nb, i, prev;
-  struct huff_table cl;
-  int cl_values[sizeof (bitorder)];
-  int cl_maxval[8];
-  int cl_offset[8];
-  grub_uint8_t lens[DEFLATE_HCLEN_MAX];
-
-  nl = DEFLATE_HLIT_BASE + grub_png_get_bits (data, 5);
-  nd = DEFLATE_HDIST_BASE + grub_png_get_bits (data, 5);
-  nb = DEFLATE_HCLEN_BASE + grub_png_get_bits (data, 4);
-
-  if ((nl > DEFLATE_HLIT_MAX) || (nd > DEFLATE_HDIST_MAX) ||
-      (nb > DEFLATE_HCLEN_MAX))
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: too much data");
-
-  grub_png_init_huff_table (&cl, 8, cl_values, cl_maxval, cl_offset);
-
-  for (i = 0; i < nb; i++)
-    lens[bitorder[i]] = grub_png_get_bits (data, 3);
-
-  for (; i < DEFLATE_HCLEN_MAX; i++)
-    lens[bitorder[i]] = 0;
-
-  for (i = 0; i < DEFLATE_HCLEN_MAX; i++)
-    grub_png_insert_huff_item (&cl, i, lens[i]);
-
-  grub_png_build_huff_table (&cl);
-
-  grub_png_init_huff_table (&data->code_table, DEFLATE_HUFF_LEN,
-                           data->code_values, data->code_maxval,
-                           data->code_offset);
-
-  grub_png_init_huff_table (&data->dist_table, DEFLATE_HUFF_LEN,
-                           data->dist_values, data->dist_maxval,
-                           data->dist_offset);
-
-  prev = 0;
-  for (i = 0; i < nl + nd; i++)
-    {
-      int n, code;
-      struct huff_table *ht;
-
-      if (grub_errno)
-       return grub_errno;
-
-      if (i < nl)
-       {
-         ht = &data->code_table;
-         code = i;
-       }
-      else
-       {
-         ht = &data->dist_table;
-         code = i - nl;
-       }
-
-      n = grub_png_get_huff_code (data, &cl);
-      if (n < 16)
-       {
-         grub_png_insert_huff_item (ht, code, n);
-         prev = n;
-       }
-      else if (n == 16)
-       {
-         int c;
-
-         c = 3 + grub_png_get_bits (data, 2);
-         while (c > 0)
-           {
-             grub_png_insert_huff_item (ht, code++, prev);
-             i++;
-             c--;
-           }
-         i--;
-       }
-      else if (n == 17)
-       i += 3 + grub_png_get_bits (data, 3) - 1;
-      else
-       i += 11 + grub_png_get_bits (data, 7) - 1;
-    }
-
-  grub_png_build_huff_table (&data->code_table);
-  grub_png_build_huff_table (&data->dist_table);
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_png_output_byte (struct grub_png_data *data, grub_uint8_t n)
-{
-  int row_bytes;
-
-  if (--data->raw_bytes < 0)
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "image size overflown");
-
-  if (data->cur_column == 0)
-    {
-      if (n >= PNG_FILTER_VALUE_LAST)
-       return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid filter value");
-
-      data->cur_filter = n;
-    }
-  else
-    *(data->cur_rgb++) = n;
-
-  data->cur_column++;
-  row_bytes = data->image_width * data->bpp;
-  if (data->cur_column == row_bytes + 1)
-    {
-      grub_uint8_t *blank_line = NULL;
-      grub_uint8_t *cur = data->cur_rgb - row_bytes;
-      grub_uint8_t *left = cur;
-      grub_uint8_t *up;
-
-      if (data->first_line)
-       {
-         blank_line = grub_zalloc (row_bytes);
-         if (blank_line == NULL)
-           return grub_errno;
-
-         up = blank_line;
-       }
-      else
-       up = cur - row_bytes;
-
-      switch (data->cur_filter)
-       {
-       case PNG_FILTER_VALUE_SUB:
-         {
-           int i;
-
-           cur += data->bpp;
-           for (i = data->bpp; i < row_bytes; i++, cur++, left++)
-             *cur += *left;
-
-           break;
-         }
-       case PNG_FILTER_VALUE_UP:
-         {
-           int i;
-
-           for (i = 0; i < row_bytes; i++, cur++, up++)
-             *cur += *up;
-
-           break;
-         }
-       case PNG_FILTER_VALUE_AVG:
-         {
-           int i;
-
-           for (i = 0; i < data->bpp; i++, cur++, up++)
-             *cur += *up >> 1;
-
-           for (; i < row_bytes; i++, cur++, up++, left++)
-             *cur += ((int) *up + (int) *left) >> 1;
-
-           break;
-         }
-       case PNG_FILTER_VALUE_PAETH:
-         {
-           int i;
-           grub_uint8_t *upper_left = up;
-
-           for (i = 0; i < data->bpp; i++, cur++, up++)
-             *cur += *up;
-
-           for (; i < row_bytes; i++, cur++, up++, left++, upper_left++)
-             {
-               int a, b, c, pa, pb, pc;
-
-                a = *left;
-                b = *up;
-                c = *upper_left;
-
-                pa = b - c;
-                pb = a - c;
-                pc = pa + pb;
-
-                if (pa < 0)
-                  pa = -pa;
-
-                if (pb < 0)
-                  pb = -pb;
-
-                if (pc < 0)
-                  pc = -pc;
-
-                *cur += ((pa <= pb) && (pa <= pc)) ? a : (pb <= pc) ? b : c;
-             }
-         }
-       }
-
-      if (blank_line)
-       grub_free (blank_line);
-
-      data->cur_column = 0;
-      data->first_line = 0;
-    }
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_png_read_dynamic_block (struct grub_png_data *data)
-{
-  while (grub_errno == 0)
-    {
-      int n;
-
-      n = grub_png_get_huff_code (data, &data->code_table);
-      if (n < 256)
-       {
-         data->slide[data->wp] = n;
-         grub_png_output_byte (data, n);
-
-         data->wp++;
-         if (data->wp >= WSIZE)
-           data->wp = 0;
-       }
-      else if (n == 256)
-       break;
-      else
-       {
-         int len, dist, pos;
-
-         n -= 257;
-         len = cplens[n];
-         if (cplext[n])
-           len += grub_png_get_bits (data, cplext[n]);
-
-         n = grub_png_get_huff_code (data, &data->dist_table);
-         dist = cpdist[n];
-         if (cpdext[n])
-           dist += grub_png_get_bits (data, cpdext[n]);
-
-         pos = data->wp - dist;
-         if (pos < 0)
-           pos += WSIZE;
-
-         while (len > 0)
-           {
-             data->slide[data->wp] = data->slide[pos];
-             grub_png_output_byte (data, data->slide[data->wp]);
-
-             data->wp++;
-             if (data->wp >= WSIZE)
-               data->wp = 0;
-
-             pos++;
-             if (pos >= WSIZE)
-               pos = 0;
-
-             len--;
-           }
-       }
-    }
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_png_decode_image_data (struct grub_png_data *data)
-{
-  grub_uint8_t cmf, flg;
-  int final;
-
-  cmf = grub_png_get_byte (data);
-  flg = grub_png_get_byte (data);
-
-  if ((cmf & 0xF) != Z_DEFLATED)
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                      "png: only support deflate compression method");
-
-  if (flg & Z_FLAG_DICT)
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                      "png: dictionary not supported");
-
-  do
-    {
-      int block_type;
-
-      final = grub_png_get_bits (data, 1);
-      block_type = grub_png_get_bits (data, 2);
-
-      switch (block_type)
-       {
-       case INFLATE_STORED:
-         {
-           grub_uint16_t i, len;
-
-           data->bit_count = 0;
-           len = grub_png_get_byte (data);
-           len += ((grub_uint16_t) grub_png_get_byte (data)) << 8;
-
-            /* Skip NLEN field.  */
-           grub_png_get_byte (data);
-           grub_png_get_byte (data);
-
-           for (i = 0; i < len; i++)
-             grub_png_output_byte (data, grub_png_get_byte (data));
-
-           break;
-         }
-
-       case INFLATE_FIXED:
-          grub_png_init_fixed_block (data);
-         grub_png_read_dynamic_block (data);
-         break;
-
-       case INFLATE_DYNAMIC:
-         grub_png_init_dynamic_block (data);
-         grub_png_read_dynamic_block (data);
-         break;
-
-       default:
-         return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                            "png: unknown block type");
-       }
-    }
-  while ((!final) && (grub_errno == 0));
-
-  /* Skip adler checksum.  */
-  grub_png_get_dword (data);
-
-  /* Skip crc checksum.  */
-  grub_png_get_dword (data);
-
-  return grub_errno;
-}
-
-static const grub_uint8_t png_magic[8] =
-  { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0x0a };
-
-static void
-grub_png_convert_image (struct grub_png_data *data)
-{
-  int i;
-  grub_uint8_t *d1, *d2;
-
-  d1 = (*data->bitmap)->data;
-  d2 = data->image_data + 1;
-
-  /* Only copy the upper 8 bit.  */
-  for (i = 0; i < (data->image_width * data->image_height * data->bpp >> 1);
-       i++, d1++, d2+=2)
-    *d1 = *d2;
-}
-
-static grub_err_t
-grub_png_decode_png (struct grub_png_data *data)
-{
-  grub_uint8_t magic[8];
-
-  if (grub_file_read (data->file, &magic[0], 8) != 8)
-    return grub_errno;
-
-  if (grub_memcmp (magic, png_magic, sizeof (png_magic)))
-    return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: not a png file");
-
-  while (1)
-    {
-      grub_uint32_t len, type;
-
-      len = grub_png_get_dword (data);
-      type = grub_png_get_dword (data);
-      data->next_offset = data->file->offset + len + 4;
-
-      switch (type)
-       {
-       case PNG_CHUNK_IHDR:
-         grub_png_decode_image_header (data);
-         break;
-
-       case PNG_CHUNK_IDAT:
-         data->inside_idat = 1;
-         data->idat_remain = len;
-         data->bit_count = 0;
-
-         grub_png_decode_image_data (data);
-
-         data->inside_idat = 0;
-         break;
-
-       case PNG_CHUNK_IEND:
-          if (data->is_16bit)
-            grub_png_convert_image (data);
-
-         return grub_errno;
-
-       default:
-         grub_file_seek (data->file, data->file->offset + len + 4);
-       }
-
-      if (grub_errno)
-        break;
-
-      if (data->file->offset != data->next_offset)
-        return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                           "png: chunk size error");
-    }
-
-  return grub_errno;
-}
-
-static grub_err_t
-grub_video_reader_png (struct grub_video_bitmap **bitmap,
-                      const char *filename)
-{
-  grub_file_t file;
-  struct grub_png_data *data;
-
-  file = grub_buffile_open (filename, 0);
-  if (!file)
-    return grub_errno;
-
-  data = grub_zalloc (sizeof (*data));
-  if (data != NULL)
-    {
-      data->file = file;
-      data->bitmap = bitmap;
-
-      grub_png_decode_png (data);
-
-      grub_free (data->image_data);
-      grub_free (data);
-    }
-
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_video_bitmap_destroy (*bitmap);
-      *bitmap = 0;
-    }
-
-  grub_file_close (file);
-  return grub_errno;
-}
-
-#if defined(PNG_DEBUG)
-static grub_err_t
-grub_cmd_pngtest (grub_command_t cmd __attribute__ ((unused)),
-                 int argc, char **args)
-{
-  struct grub_video_bitmap *bitmap = 0;
-
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
-  grub_video_reader_png (&bitmap, args[0]);
-  if (grub_errno != GRUB_ERR_NONE)
-    return grub_errno;
-
-  grub_video_bitmap_destroy (bitmap);
-
-  return GRUB_ERR_NONE;
-}
-#endif
-
-static struct grub_video_bitmap_reader png_reader = {
-  .extension = ".png",
-  .reader = grub_video_reader_png,
-  .next = 0
-};
-
-GRUB_MOD_INIT (png)
-{
-  grub_video_bitmap_reader_register (&png_reader);
-#if defined(PNG_DEBUG)
-  cmd = grub_register_command ("pngtest", grub_cmd_pngtest,
-                              "FILE",
-                              "Tests loading of PNG bitmap.");
-#endif
-}
-
-GRUB_MOD_FINI (png)
-{
-#if defined(PNG_DEBUG)
-  grub_unregister_command (cmd);
-#endif
-  grub_video_bitmap_reader_unregister (&png_reader);
-}
diff --git a/video/readers/tga.c b/video/readers/tga.c
deleted file mode 100644 (file)
index 6c9e9d6..0000000
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/bitmap.h>
-#include <grub/types.h>
-#include <grub/normal.h>
-#include <grub/dl.h>
-#include <grub/mm.h>
-#include <grub/misc.h>
-#include <grub/bufio.h>
-
-/* Uncomment following define to enable TGA debug.  */
-//#define TGA_DEBUG
-
-#if defined(TGA_DEBUG)
-#define dump_int_field(x) grub_printf( #x " = %d (0x%04x)\n", x, x);
-static grub_command_t cmd;
-#endif
-
-enum
-{
-  GRUB_TGA_IMAGE_TYPE_NONE = 0,
-  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_INDEXCOLOR = 1,
-  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR = 2,
-  GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_BLACK_AND_WHITE = 3,
-  GRUB_TGA_IMAGE_TYPE_RLE_INDEXCOLOR = 9,
-  GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR = 10,
-  GRUB_TGA_IMAGE_TYPE_RLE_BLACK_AND_WHITE = 11,
-};
-
-enum
-{
-  GRUB_TGA_COLOR_MAP_TYPE_NONE = 0,
-  GRUB_TGA_COLOR_MAP_TYPE_INCLUDED = 1
-};
-
-enum
-{
-  GRUB_TGA_IMAGE_ORIGIN_RIGHT = 0x10,
-  GRUB_TGA_IMAGE_ORIGIN_TOP   = 0x20
-};
-
-struct grub_tga_header
-{
-  grub_uint8_t id_length;
-  grub_uint8_t color_map_type;
-  grub_uint8_t image_type;
-
-  /* Color Map Specification.  */
-  grub_uint16_t color_map_first_index;
-  grub_uint16_t color_map_length;
-  grub_uint8_t color_map_bpp;
-
-  /* Image Specification.  */
-  grub_uint16_t image_x_origin;
-  grub_uint16_t image_y_origin;
-  grub_uint16_t image_width;
-  grub_uint16_t image_height;
-  grub_uint8_t image_bpp;
-  grub_uint8_t image_descriptor;
-} __attribute__ ((packed));
-
-static grub_err_t
-tga_load_truecolor_rle_R8G8B8 (struct grub_video_bitmap *bitmap,
-                               struct grub_tga_header *header,
-                               grub_file_t file)
-{
-  unsigned int x;
-  unsigned int y;
-  grub_uint8_t type;
-  grub_uint8_t *ptr;
-  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
-  grub_uint8_t bytes_per_pixel;
-
-  bytes_per_pixel = header->image_bpp / 8;
-
-  for (y = 0; y < header->image_height; y++)
-    {
-      ptr = bitmap->data;
-      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
-        ptr += y * bitmap->mode_info.pitch;
-      else
-        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
-
-      for (x = 0; x < header->image_width;)
-        {
-          if (grub_file_read (file, &type, sizeof (type)) != sizeof(type))
-            return grub_errno;
-
-          if (type & 0x80)
-            {
-              /* RLE-encoded packet.  */
-              type &= 0x7f;
-              type++;
-
-              if (grub_file_read (file, &tmp[0], bytes_per_pixel)
-                  != bytes_per_pixel)
-                return grub_errno;
-
-              while (type)
-                {
-                  if (x < header->image_width)
-                    {
-                      ptr[0] = tmp[2];
-                      ptr[1] = tmp[1];
-                      ptr[2] = tmp[0];
-                      ptr += 3;
-                    }
-
-                  type--;
-                  x++;
-                }
-            }
-          else
-            {
-              /* RAW-encoded packet.  */
-              type++;
-
-              while (type)
-                {
-                  if (grub_file_read (file, &tmp[0], bytes_per_pixel)
-                      != bytes_per_pixel)
-                    return grub_errno;
-
-                  if (x < header->image_width)
-                    {
-                      ptr[0] = tmp[2];
-                      ptr[1] = tmp[1];
-                      ptr[2] = tmp[0];
-                      ptr += 3;
-                    }
-
-                  type--;
-                  x++;
-                }
-            }
-        }
-    }
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-tga_load_truecolor_rle_R8G8B8A8 (struct grub_video_bitmap *bitmap,
-                                 struct grub_tga_header *header,
-                                 grub_file_t file)
-{
-  unsigned int x;
-  unsigned int y;
-  grub_uint8_t type;
-  grub_uint8_t *ptr;
-  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
-  grub_uint8_t bytes_per_pixel;
-
-  bytes_per_pixel = header->image_bpp / 8;
-
-  for (y = 0; y < header->image_height; y++)
-    {
-      ptr = bitmap->data;
-      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
-        ptr += y * bitmap->mode_info.pitch;
-      else
-        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
-
-      for (x = 0; x < header->image_width;)
-        {
-          if (grub_file_read (file, &type, sizeof (type)) != sizeof(type))
-            return grub_errno;
-
-          if (type & 0x80)
-            {
-              /* RLE-encoded packet.  */
-              type &= 0x7f;
-              type++;
-
-              if (grub_file_read (file, &tmp[0], bytes_per_pixel)
-                  != bytes_per_pixel)
-                return grub_errno;
-
-              while (type)
-                {
-                  if (x < header->image_width)
-                    {
-                      ptr[0] = tmp[2];
-                      ptr[1] = tmp[1];
-                      ptr[2] = tmp[0];
-                      ptr[3] = tmp[3];
-                      ptr += 4;
-                    }
-
-                  type--;
-                  x++;
-                }
-            }
-          else
-            {
-              /* RAW-encoded packet.  */
-              type++;
-
-              while (type)
-                {
-                  if (grub_file_read (file, &tmp[0], bytes_per_pixel)
-                      != bytes_per_pixel)
-                    return grub_errno;
-
-                  if (x < header->image_width)
-                    {
-                      ptr[0] = tmp[2];
-                      ptr[1] = tmp[1];
-                      ptr[2] = tmp[0];
-                      ptr[3] = tmp[3];
-                      ptr += 4;
-                    }
-
-                  type--;
-                  x++;
-                }
-            }
-        }
-    }
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-tga_load_truecolor_R8G8B8 (struct grub_video_bitmap *bitmap,
-                           struct grub_tga_header *header,
-                           grub_file_t file)
-{
-  unsigned int x;
-  unsigned int y;
-  grub_uint8_t *ptr;
-  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
-  grub_uint8_t bytes_per_pixel;
-
-  bytes_per_pixel = header->image_bpp / 8;
-
-  for (y = 0; y < header->image_height; y++)
-    {
-      ptr = bitmap->data;
-      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
-        ptr += y * bitmap->mode_info.pitch;
-      else
-        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
-
-      for (x = 0; x < header->image_width; x++)
-        {
-          if (grub_file_read (file, &tmp[0], bytes_per_pixel)
-              != bytes_per_pixel)
-            return grub_errno;
-
-          ptr[0] = tmp[2];
-          ptr[1] = tmp[1];
-          ptr[2] = tmp[0];
-
-          ptr += 3;
-        }
-    }
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-tga_load_truecolor_R8G8B8A8 (struct grub_video_bitmap *bitmap,
-                             struct grub_tga_header *header,
-                             grub_file_t file)
-{
-  unsigned int x;
-  unsigned int y;
-  grub_uint8_t *ptr;
-  grub_uint8_t tmp[4]; /* Size should be max_bpp / 8.  */
-  grub_uint8_t bytes_per_pixel;
-
-  bytes_per_pixel = header->image_bpp / 8;
-
-  for (y = 0; y < header->image_height; y++)
-    {
-      ptr = bitmap->data;
-      if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0)
-        ptr += y * bitmap->mode_info.pitch;
-      else
-        ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch;
-
-      for (x = 0; x < header->image_width; x++)
-        {
-          if (grub_file_read (file, &tmp[0], bytes_per_pixel)
-              != bytes_per_pixel)
-            return grub_errno;
-
-          ptr[0] = tmp[2];
-          ptr[1] = tmp[1];
-          ptr[2] = tmp[0];
-          ptr[3] = tmp[3];
-
-          ptr += 4;
-        }
-    }
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_reader_tga (struct grub_video_bitmap **bitmap,
-                       const char *filename)
-{
-  grub_file_t file;
-  grub_ssize_t pos;
-  struct grub_tga_header header;
-  int has_alpha;
-
-  file = grub_buffile_open (filename, 0);
-  if (! file)
-    return grub_errno;
-
-  /* TGA Specification states that we SHOULD start by reading
-     ID from end of file, but we really don't care about that as we are
-     not going to support developer area & extensions at this point.  */
-
-  /* Read TGA header from beginning of file.  */
-  if (grub_file_read (file, &header, sizeof (header))
-      != sizeof (header))
-    {
-      grub_file_close (file);
-      return grub_errno;
-    }
-
-  /* Skip ID field.  */
-  pos = grub_file_tell (file);
-  pos += header.id_length;
-  grub_file_seek (file, pos);
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_file_close (file);
-      return grub_errno;
-    }
-
-#if defined(TGA_DEBUG)
-  grub_printf("tga: header\n");
-  dump_int_field(header.id_length);
-  dump_int_field(header.color_map_type);
-  dump_int_field(header.image_type);
-  dump_int_field(header.color_map_first_index);
-  dump_int_field(header.color_map_length);
-  dump_int_field(header.color_map_bpp);
-  dump_int_field(header.image_x_origin);
-  dump_int_field(header.image_y_origin);
-  dump_int_field(header.image_width);
-  dump_int_field(header.image_height);
-  dump_int_field(header.image_bpp);
-  dump_int_field(header.image_descriptor);
-#endif
-
-  /* Check that bitmap encoding is supported.  */
-  switch (header.image_type)
-    {
-      case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
-      case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
-        break;
-
-      default:
-        grub_file_close (file);
-        return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                           "unsupported bitmap format (unknown encoding)");
-    }
-
-  /* Check that bitmap depth is supported.  */
-  switch (header.image_bpp)
-    {
-      case 24:
-        has_alpha = 0;
-        break;
-
-      case 32:
-        has_alpha = 1;
-        break;
-
-      default:
-        grub_file_close (file);
-        return grub_error (GRUB_ERR_BAD_FILE_TYPE,
-                           "unsupported bitmap format (bpp=%d)",
-                           header.image_bpp);
-    }
-
-  /* Allocate bitmap.  If there is alpha information store it too.  */
-  if (has_alpha)
-    {
-      grub_video_bitmap_create (bitmap, header.image_width,
-                                header.image_height,
-                                GRUB_VIDEO_BLIT_FORMAT_RGBA_8888);
-      if (grub_errno != GRUB_ERR_NONE)
-        {
-          grub_file_close (file);
-          return grub_errno;
-        }
-
-      /* Load bitmap data.  */
-      switch (header.image_type)
-        {
-          case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
-            tga_load_truecolor_R8G8B8A8 (*bitmap, &header, file);
-            break;
-
-          case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
-            tga_load_truecolor_rle_R8G8B8A8 (*bitmap, &header, file);
-            break;
-        }
-    }
-  else
-    {
-      grub_video_bitmap_create (bitmap, header.image_width,
-                                header.image_height,
-                                GRUB_VIDEO_BLIT_FORMAT_RGB_888);
-      if (grub_errno != GRUB_ERR_NONE)
-        {
-          grub_file_close (file);
-          return grub_errno;
-        }
-
-      /* Load bitmap data.  */
-      switch (header.image_type)
-        {
-          case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR:
-            tga_load_truecolor_R8G8B8 (*bitmap, &header, file);
-            break;
-
-          case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR:
-            tga_load_truecolor_rle_R8G8B8 (*bitmap, &header, file);
-            break;
-        }
-    }
-
-  /* If there was a loading problem, destroy bitmap.  */
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_video_bitmap_destroy (*bitmap);
-      *bitmap = 0;
-    }
-
-  grub_file_close (file);
-  return grub_errno;
-}
-
-#if defined(TGA_DEBUG)
-static grub_err_t
-grub_cmd_tgatest (grub_command_t cmd __attribute__ ((unused)),
-                  int argc, char **args)
-{
-  struct grub_video_bitmap *bitmap = 0;
-
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
-  grub_video_reader_tga (&bitmap, args[0]);
-  if (grub_errno != GRUB_ERR_NONE)
-    return grub_errno;
-
-  grub_video_bitmap_destroy (bitmap);
-
-  return GRUB_ERR_NONE;
-}
-#endif
-
-static struct grub_video_bitmap_reader tga_reader = {
-  .extension = ".tga",
-  .reader = grub_video_reader_tga,
-  .next = 0
-};
-
-GRUB_MOD_INIT(tga)
-{
-  grub_video_bitmap_reader_register (&tga_reader);
-#if defined(TGA_DEBUG)
-  cmd = grub_register_command ("tgatest", grub_cmd_tgatest,
-                               "FILE", "Tests loading of TGA bitmap.");
-#endif
-}
-
-GRUB_MOD_FINI(tga)
-{
-#if defined(TGA_DEBUG)
-  grub_unregister_command (cmd);
-#endif
-  grub_video_bitmap_reader_unregister (&tga_reader);
-}
diff --git a/video/sm712.c b/video/sm712.c
deleted file mode 100644 (file)
index 33861be..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define grub_video_render_target grub_video_fbrender_target
-
-#include <grub/err.h>
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/video.h>
-#include <grub/video_fb.h>
-#include <grub/pci.h>
-
-static struct
-{
-  struct grub_video_mode_info mode_info;
-  struct grub_video_render_target *render_target;
-
-  unsigned int bytes_per_scan_line;
-  unsigned int bytes_per_pixel;
-  grub_uint8_t *ptr;
-  int index_color_mode;
-  int mapped;
-  grub_uint32_t base;
-  grub_pci_device_t dev;
-} framebuffer;
-
-static grub_err_t
-grub_video_sm712_video_init (void)
-{
-  /* Reset frame buffer.  */
-  grub_memset (&framebuffer, 0, sizeof(framebuffer));
-
-  return grub_video_fb_init ();
-}
-
-static grub_err_t
-grub_video_sm712_video_fini (void)
-{
-  if (framebuffer.mapped)
-    grub_pci_device_unmap_range (framebuffer.dev, framebuffer.ptr,
-                                1024 * 600 * 2);
-
-  return grub_video_fb_fini ();
-}
-
-static grub_err_t
-grub_video_sm712_setup (unsigned int width, unsigned int height,
-                       unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused)))
-{
-  int depth;
-  grub_err_t err;
-  int found = 0;
-
-  auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)));
-  int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)))
-    {
-      grub_pci_address_t addr;
-      grub_uint32_t class;
-
-      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
-      class = grub_pci_read (addr);
-
-      if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x0712126f)
-       return 0;
-      
-      found = 1;
-
-      addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
-      framebuffer.base = grub_pci_read (addr);
-      framebuffer.dev = dev;
-
-      return 1;
-    }
-
-  /* Decode depth from mode_type.  If it is zero, then autodetect.  */
-  depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
-          >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
-
-  if ((width != 1024 && width != 0) || (height != 600 && height != 0)
-      || (depth != 16 && depth != 0))
-    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-                      "Only 1024x600x16 is supported");
-
-  grub_pci_iterate (find_card);
-  if (!found)
-    return grub_error (GRUB_ERR_IO, "Couldn't find graphics card");
-
-  if (found && framebuffer.base == 0)
-    {
-      /* FIXME: change framebuffer base */
-    }
-
-  /* Fill mode info details.  */
-  framebuffer.mode_info.width = 1024;
-  framebuffer.mode_info.height = 600;
-  framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
-  framebuffer.mode_info.bpp = 16;
-  framebuffer.mode_info.bytes_per_pixel = 2;
-  framebuffer.mode_info.pitch = 1024 * 2;
-  framebuffer.mode_info.number_of_colors = 256;
-  framebuffer.mode_info.red_mask_size = 5;
-  framebuffer.mode_info.red_field_pos = 11;
-  framebuffer.mode_info.green_mask_size = 6;
-  framebuffer.mode_info.green_field_pos = 5;
-  framebuffer.mode_info.blue_mask_size = 5;
-  framebuffer.mode_info.blue_field_pos = 0;
-  framebuffer.mode_info.reserved_mask_size = 0;
-  framebuffer.mode_info.reserved_field_pos = 0;
-  framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info);
-  /* We can safely discard volatile attribute.  */
-  framebuffer.ptr = (void *) grub_pci_device_map_range (framebuffer.dev,
-                                                       framebuffer.base,
-                                                       1024 * 600 * 2);
-  framebuffer.mapped = 1;
-
-  err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr);
-
-  if (err)
-    return err;
-
-  err = grub_video_fb_set_active_render_target (framebuffer.render_target);
-  
-  if (err)
-    return err;
-
-  /* Copy default palette to initialize emulated palette.  */
-  err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
-                                  grub_video_fbstd_colors);
-  return err;
-}
-
-static grub_err_t
-grub_video_sm712_set_palette (unsigned int start, unsigned int count,
-                            struct grub_video_palette_data *palette_data)
-{
-  if (framebuffer.index_color_mode)
-    {
-      /* TODO: Implement setting indexed color mode palette to hardware.  */
-    }
-
-  /* Then set color to emulated palette.  */
-  return grub_video_fb_set_palette (start, count, palette_data);
-}
-
-static grub_err_t
-grub_video_sm712_swap_buffers (void)
-{
-  /* TODO: Implement buffer swapping.  */
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_video_sm712_set_active_render_target (struct grub_video_render_target *target)
-{
-  if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
-      target = framebuffer.render_target;
-
-  return grub_video_fb_set_active_render_target (target);
-}
-
-static grub_err_t
-grub_video_sm712_get_info_and_fini (struct grub_video_mode_info *mode_info,
-                                   void **framebuf)
-{
-  grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info));
-  *framebuf = (char *) framebuffer.ptr;
-
-  grub_video_fb_fini ();
-
-  return GRUB_ERR_NONE;
-}
-
-
-static struct grub_video_adapter grub_video_sm712_adapter =
-  {
-    .name = "SM712 Video Driver",
-    .id = GRUB_VIDEO_DRIVER_SM712,
-
-    .init = grub_video_sm712_video_init,
-    .fini = grub_video_sm712_video_fini,
-    .setup = grub_video_sm712_setup,
-    .get_info = grub_video_fb_get_info,
-    .get_info_and_fini = grub_video_sm712_get_info_and_fini,
-    .set_palette = grub_video_sm712_set_palette,
-    .get_palette = grub_video_fb_get_palette,
-    .set_viewport = grub_video_fb_set_viewport,
-    .get_viewport = grub_video_fb_get_viewport,
-    .map_color = grub_video_fb_map_color,
-    .map_rgb = grub_video_fb_map_rgb,
-    .map_rgba = grub_video_fb_map_rgba,
-    .unmap_color = grub_video_fb_unmap_color,
-    .fill_rect = grub_video_fb_fill_rect,
-    .blit_bitmap = grub_video_fb_blit_bitmap,
-    .blit_render_target = grub_video_fb_blit_render_target,
-    .scroll = grub_video_fb_scroll,
-    .swap_buffers = grub_video_sm712_swap_buffers,
-    .create_render_target = grub_video_fb_create_render_target,
-    .delete_render_target = grub_video_fb_delete_render_target,
-    .set_active_render_target = grub_video_sm712_set_active_render_target,
-    .get_active_render_target = grub_video_fb_get_active_render_target,
-
-    .next = 0
-  };
-
-GRUB_MOD_INIT(video_sm712)
-{
-  grub_video_register (&grub_video_sm712_adapter);
-}
-
-GRUB_MOD_FINI(video_sm712)
-{
-  grub_video_unregister (&grub_video_sm712_adapter);
-}
diff --git a/video/video.c b/video/video.c
deleted file mode 100644 (file)
index 42418f9..0000000
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/video.h>
-#include <grub/types.h>
-#include <grub/dl.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-
-/* The list of video adapters registered to system.  */
-static grub_video_adapter_t grub_video_adapter_list;
-
-/* Active video adapter.  */
-static grub_video_adapter_t grub_video_adapter_active;
-
-/* Register video driver.  */
-void
-grub_video_register (grub_video_adapter_t adapter)
-{
-  adapter->next = grub_video_adapter_list;
-  grub_video_adapter_list = adapter;
-}
-
-/* Unregister video driver.  */
-void
-grub_video_unregister (grub_video_adapter_t adapter)
-{
-  grub_video_adapter_t *p, q;
-
-  for (p = &grub_video_adapter_list, q = *p; q; p = &(q->next), q = q->next)
-    if (q == adapter)
-      {
-        *p = q->next;
-        break;
-      }
-}
-
-/* Iterate thru all registered video drivers.  */
-void
-grub_video_iterate (int (*hook) (grub_video_adapter_t adapter))
-{
-  grub_video_adapter_t p;
-
-  for (p = grub_video_adapter_list; p; p = p->next)
-    if (hook (p))
-      break;
-}
-
-/* Restore back to initial mode (where applicable).  */
-grub_err_t
-grub_video_restore (void)
-{
-  if (grub_video_adapter_active)
-    {
-      grub_video_adapter_active->fini ();
-      if (grub_errno != GRUB_ERR_NONE)
-        return grub_errno;
-
-      grub_video_adapter_active = 0;
-    }
-  return GRUB_ERR_NONE;
-}
-
-/* Get information about active video mode.  */
-grub_err_t
-grub_video_get_info (struct grub_video_mode_info *mode_info)
-{
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  /* If mode_info is NULL just report that video adapter is active.  */
-  if (! mode_info)
-    {
-      grub_errno = GRUB_ERR_NONE;
-      return grub_errno;
-    }
-
-  return grub_video_adapter_active->get_info (mode_info);
-}
-
-grub_video_driver_id_t
-grub_video_get_driver_id (void)
-{
-  if (! grub_video_adapter_active)
-    return GRUB_VIDEO_DRIVER_NONE;
-  return grub_video_adapter_active->id;
-}
-
-/* Get information about active video mode.  */
-grub_err_t
-grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info,
-                             void **framebuffer)
-{
-  grub_err_t err;
-
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  err = grub_video_adapter_active->get_info_and_fini (mode_info, framebuffer);
-  if (err)
-    return err;
-
-  grub_video_adapter_active = 0;
-  return GRUB_ERR_NONE;
-}
-
-/* Determine optimized blitting formation for specified video mode info.  */
-enum grub_video_blit_format
-grub_video_get_blit_format (struct grub_video_mode_info *mode_info)
-{
-  /* Check if we have any known 32 bit modes.  */
-  if (mode_info->bpp == 32)
-    {
-      if ((mode_info->red_mask_size == 8)
-         && (mode_info->red_field_pos == 16)
-         && (mode_info->green_mask_size == 8)
-         && (mode_info->green_field_pos == 8)
-         && (mode_info->blue_mask_size == 8)
-         && (mode_info->blue_field_pos == 0))
-       {
-         return GRUB_VIDEO_BLIT_FORMAT_BGRA_8888;
-       }
-      else if ((mode_info->red_mask_size == 8)
-              && (mode_info->red_field_pos == 0)
-              && (mode_info->green_mask_size == 8)
-              && (mode_info->green_field_pos == 8)
-              && (mode_info->blue_mask_size == 8)
-              && (mode_info->blue_field_pos == 16))
-       {
-         return GRUB_VIDEO_BLIT_FORMAT_RGBA_8888;
-       }
-    }
-  /* Check if we have any known 24 bit modes.  */
-  else if (mode_info->bpp == 24)
-    {
-      if ((mode_info->red_mask_size == 8)
-         && (mode_info->red_field_pos == 16)
-         && (mode_info->green_mask_size == 8)
-         && (mode_info->green_field_pos == 8)
-         && (mode_info->blue_mask_size == 8)
-         && (mode_info->blue_field_pos == 0))
-       {
-         return GRUB_VIDEO_BLIT_FORMAT_BGR_888;
-       }
-      else if ((mode_info->red_mask_size == 8)
-              && (mode_info->red_field_pos == 0)
-              && (mode_info->green_mask_size == 8)
-              && (mode_info->green_field_pos == 8)
-              && (mode_info->blue_mask_size == 8)
-              && (mode_info->blue_field_pos == 16))
-       {
-         return GRUB_VIDEO_BLIT_FORMAT_RGB_888;
-       }
-    }
-  /* Check if we have any known 16 bit modes.  */
-  else if (mode_info->bpp == 16)
-    {
-      if ((mode_info->red_mask_size == 5)
-         && (mode_info->red_field_pos == 11)
-         && (mode_info->green_mask_size == 6)
-         && (mode_info->green_field_pos == 5)
-         && (mode_info->blue_mask_size == 5)
-         && (mode_info->blue_field_pos == 0))
-       {
-         return GRUB_VIDEO_BLIT_FORMAT_BGR_565;
-       }
-      else if ((mode_info->red_mask_size == 5)
-              && (mode_info->red_field_pos == 0)
-              && (mode_info->green_mask_size == 6)
-              && (mode_info->green_field_pos == 5)
-              && (mode_info->blue_mask_size == 5)
-              && (mode_info->blue_field_pos == 11))
-       {
-         return GRUB_VIDEO_BLIT_FORMAT_RGB_565;
-       }
-    }
-  else if (mode_info->bpp == 1)
-    return GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED;
-
-  /* Backup route.  Unknown format.  */
-
-  /* If there are more than 8 bits per color, assume RGB(A) mode.  */
-  if (mode_info->bpp > 8)
-    {
-      if (mode_info->reserved_mask_size > 0)
-       {
-         return GRUB_VIDEO_BLIT_FORMAT_RGBA;
-       }
-      else
-       {
-         return GRUB_VIDEO_BLIT_FORMAT_RGB;
-       }
-    }
-
-  /* Assume as indexcolor mode.  */
-  return GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR;
-}
-
-/* Set new indexed color palette entries.  */
-grub_err_t
-grub_video_set_palette (unsigned int start, unsigned int count,
-                        struct grub_video_palette_data *palette_data)
-{
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  return grub_video_adapter_active->set_palette (start, count, palette_data);
-}
-
-/* Get indexed color palette entries.  */
-grub_err_t
-grub_video_get_palette (unsigned int start, unsigned int count,
-                        struct grub_video_palette_data *palette_data)
-{
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  return grub_video_adapter_active->get_palette (start, count, palette_data);
-}
-
-/* Set viewport dimensions.  */
-grub_err_t
-grub_video_set_viewport (unsigned int x, unsigned int y,
-                         unsigned int width, unsigned int height)
-{
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  return grub_video_adapter_active->set_viewport (x, y, width, height);
-}
-
-/* Get viewport dimensions.  */
-grub_err_t
-grub_video_get_viewport (unsigned int *x, unsigned int *y,
-                         unsigned int *width, unsigned int *height)
-{
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  return grub_video_adapter_active->get_viewport (x, y, width, height);
-}
-
-/* Map color name to adapter specific color.  */
-grub_video_color_t
-grub_video_map_color (grub_uint32_t color_name)
-{
-  if (! grub_video_adapter_active)
-    return 0;
-
-  return grub_video_adapter_active->map_color (color_name);
-}
-
-/* Map RGB value to adapter specific color.  */
-grub_video_color_t
-grub_video_map_rgb (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue)
-{
-  if (! grub_video_adapter_active)
-    return 0;
-
-  return grub_video_adapter_active->map_rgb (red, green, blue);
-}
-
-/* Map RGBA value to adapter specific color.  */
-grub_video_color_t
-grub_video_map_rgba (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue,
-                     grub_uint8_t alpha)
-{
-  if (! grub_video_adapter_active)
-    return 0;
-
-  return grub_video_adapter_active->map_rgba (red, green, blue, alpha);
-}
-
-/* Unmap video color back to RGBA components.  */
-grub_err_t
-grub_video_unmap_color (grub_video_color_t color, grub_uint8_t *red,
-                        grub_uint8_t *green, grub_uint8_t *blue,
-                        grub_uint8_t *alpha)
-{
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  return grub_video_adapter_active->unmap_color (color,
-                                                 red,
-                                                 green,
-                                                 blue,
-                                                 alpha);
-}
-
-/* Fill rectangle using specified color.  */
-grub_err_t
-grub_video_fill_rect (grub_video_color_t color, int x, int y,
-                      unsigned int width, unsigned int height)
-{
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  return grub_video_adapter_active->fill_rect (color, x, y, width, height);
-}
-
-/* Blit bitmap to screen.  */
-grub_err_t
-grub_video_blit_bitmap (struct grub_video_bitmap *bitmap,
-                        enum grub_video_blit_operators oper,
-                        int x, int y, int offset_x, int offset_y,
-                        unsigned int width, unsigned int height)
-{
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  return grub_video_adapter_active->blit_bitmap (bitmap, oper, x, y,
-                                                 offset_x, offset_y,
-                                                 width, height);
-}
-
-/* Blit render target to active render target.  */
-grub_err_t
-grub_video_blit_render_target (struct grub_video_render_target *target,
-                               enum grub_video_blit_operators oper,
-                               int x, int y, int offset_x, int offset_y,
-                               unsigned int width, unsigned int height)
-{
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  return grub_video_adapter_active->blit_render_target (target, oper, x, y,
-                                                        offset_x, offset_y,
-                                                        width, height);
-}
-
-/* Scroll viewport and fill new areas with specified color.  */
-grub_err_t
-grub_video_scroll (grub_video_color_t color, int dx, int dy)
-{
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  return grub_video_adapter_active->scroll (color, dx, dy);
-}
-
-/* Swap buffers (swap active render target).  */
-grub_err_t
-grub_video_swap_buffers (void)
-{
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  return grub_video_adapter_active->swap_buffers ();
-}
-
-/* Create new render target.  */
-grub_err_t
-grub_video_create_render_target (struct grub_video_render_target **result,
-                                 unsigned int width, unsigned int height,
-                                 unsigned int mode_type)
-{
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  return grub_video_adapter_active->create_render_target (result,
-                                                          width, height,
-                                                          mode_type);
-}
-
-/* Delete render target.  */
-grub_err_t
-grub_video_delete_render_target (struct grub_video_render_target *target)
-{
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  return grub_video_adapter_active->delete_render_target (target);
-}
-
-/* Set active render target.  */
-grub_err_t
-grub_video_set_active_render_target (struct grub_video_render_target *target)
-{
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  return grub_video_adapter_active->set_active_render_target (target);
-}
-
-/* Get active render target.  */
-grub_err_t
-grub_video_get_active_render_target (struct grub_video_render_target **target)
-{
-  if (! grub_video_adapter_active)
-    return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated");
-
-  return grub_video_adapter_active->get_active_render_target (target);
-}
-
-/* Parse <width>x<height>[x<depth>]*/
-static grub_err_t
-parse_modespec (const char *current_mode, int *width, int *height, int *depth)
-{
-  const char *value;
-  const char *param = current_mode;
-
-  *width = *height = *depth = -1;
-
-  if (grub_strcmp (param, "auto") == 0)
-    {
-      *width = *height = 0;
-      return GRUB_ERR_NONE;
-    }
-
-  /* Find width value.  */
-  value = param;
-  param = grub_strchr(param, 'x');
-  if (param == NULL)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      "Invalid mode: %s\n",
-                      current_mode);
-
-  param++;
-  
-  *width = grub_strtoul (value, 0, 0);
-  if (grub_errno != GRUB_ERR_NONE)
-      return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                        "Invalid mode: %s\n",
-                        current_mode);
-  
-  /* Find height value.  */
-  value = param;
-  param = grub_strchr(param, 'x');
-  if (param == NULL)
-    {
-      *height = grub_strtoul (value, 0, 0);
-      if (grub_errno != GRUB_ERR_NONE)
-       return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                          "Invalid mode: %s\n",
-                          current_mode);
-    }
-  else
-    {
-      /* We have optional color depth value.  */
-      param++;
-      
-      *height = grub_strtoul (value, 0, 0);
-      if (grub_errno != GRUB_ERR_NONE)
-       return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                          "Invalid mode: %s\n",
-                          current_mode);
-      
-      /* Convert color depth value.  */
-      value = param;
-      *depth = grub_strtoul (value, 0, 0);
-      if (grub_errno != GRUB_ERR_NONE)
-       return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                          "Invalid mode: %s\n",
-                          current_mode);
-    }
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_video_set_mode (const char *modestring,
-                    unsigned int modemask,
-                    unsigned int modevalue)
-{
-  char *tmp;
-  char *next_mode;
-  char *current_mode;
-  char *modevar;
-
-  modevalue &= modemask;
-
-  /* Take copy of env.var. as we don't want to modify that.  */
-  modevar = grub_strdup (modestring);
-
-  /* Initialize next mode.  */
-  next_mode = modevar;
-
-  if (! modevar)
-    return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                      "couldn't allocate space for local modevar copy");
-
-  if (grub_memcmp (next_mode, "keep", sizeof ("keep")) == 0
-      || grub_memcmp (next_mode, "keep,", sizeof ("keep,") - 1) == 0
-      || grub_memcmp (next_mode, "keep;", sizeof ("keep;") - 1) == 0)
-    {
-      int suitable = 1;
-      grub_err_t err;
-
-      if (grub_video_adapter_active)
-       {
-         struct grub_video_mode_info mode_info;
-         grub_memset (&mode_info, 0, sizeof (mode_info));
-         err = grub_video_get_info (&mode_info);
-         if (err)
-           {
-             suitable = 0;
-             grub_errno = GRUB_ERR_NONE;
-           }
-         if ((mode_info.mode_type & modemask) != modevalue)
-           suitable = 0;
-       }
-      else if (((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modemask) != 0)
-              && ((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modevalue) == 0))
-       suitable = 0;
-
-      if (suitable)
-       {
-         grub_free (modevar);
-         return GRUB_ERR_NONE;
-       }
-      next_mode += sizeof ("keep") - 1;
-      if (! *next_mode)
-       {
-         grub_free (modevar);
-
-         return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                            "no suitable mode found");
-       }
-
-      /* Skip separator. */
-      next_mode++;
-    }
-
-  /* De-activate last set video adapter.  */
-  if (grub_video_adapter_active)
-    {
-      /* Finalize adapter.  */
-      grub_video_adapter_active->fini ();
-      if (grub_errno != GRUB_ERR_NONE)
-       grub_errno = GRUB_ERR_NONE;
-
-      /* Mark active adapter as not set.  */
-      grub_video_adapter_active = 0;
-    }
-
-  /* Loop until all modes has been tested out.  */
-  while (next_mode != NULL)
-    {
-      int width = -1;
-      int height = -1;
-      int depth = -1;
-      grub_err_t err;
-      unsigned int flags = modevalue;
-      unsigned int flagmask = modemask;
-
-      /* Use last next_mode as current mode.  */
-      tmp = next_mode;
-
-      /* Save position of next mode and separate modes.  */
-      for (; *next_mode; next_mode++)
-       if (*next_mode == ',' || *next_mode == ';')
-         break;
-      if (*next_mode)
-       {
-         *next_mode = 0;
-         next_mode++;
-       }
-      else
-       next_mode = 0;
-
-      /* Skip whitespace.  */
-      while (grub_isspace (*tmp))
-       tmp++;
-
-      /* Initialize token holders.  */
-      current_mode = tmp;
-
-      /* XXX: we assume that we're in pure text mode if
-        no video mode is initialized. Is it always true? */
-      if (grub_strcmp (current_mode, "text") == 0)
-       {
-         struct grub_video_mode_info mode_info;
-
-         grub_memset (&mode_info, 0, sizeof (mode_info));
-         if (((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modemask) == 0)
-             || ((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modevalue) != 0))
-           {
-             /* Valid mode found from adapter, and it has been activated.
-                Specify it as active adapter.  */
-             grub_video_adapter_active = NULL;
-
-             /* Free memory.  */
-             grub_free (modevar);
-
-             return GRUB_ERR_NONE;
-           }
-       }
-
-      err = parse_modespec (current_mode, &width, &height, &depth);
-      if (err)
-       {
-         /* Free memory before returning.  */
-         grub_free (modevar);
-
-         return err;
-       }
-
-      /* Try out video mode.  */
-
-      /* If user requested specific depth check if this depth is supported.  */
-      if (depth != -1 && (flagmask & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
-         &&
-         (((flags & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
-           != ((depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
-               & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK))))
-       continue;
-
-      if (depth != -1)
-       {
-         flags |= (depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
-           & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
-         flagmask |= GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
-       }
-
-      /* Try to initialize requested mode.  Ignore any errors.  */
-      grub_video_adapter_t p;
-
-      /* Loop thru all possible video adapter trying to find requested mode.  */
-      for (p = grub_video_adapter_list; p; p = p->next)
-       {
-         struct grub_video_mode_info mode_info;
-
-         grub_memset (&mode_info, 0, sizeof (mode_info));
-
-         /* Try to initialize adapter, if it fails, skip to next adapter.  */
-         err = p->init ();
-         if (err != GRUB_ERR_NONE)
-           {
-             grub_errno = GRUB_ERR_NONE;
-             continue;
-           }
-
-         /* Try to initialize video mode.  */
-         err = p->setup (width, height, flags, flagmask);
-         if (err != GRUB_ERR_NONE)
-           {
-             p->fini ();
-             grub_errno = GRUB_ERR_NONE;
-             continue;
-           }
-
-         err = p->get_info (&mode_info);
-         if (err != GRUB_ERR_NONE)
-           {
-             p->fini ();
-             grub_errno = GRUB_ERR_NONE;
-             continue;
-           }
-
-         flags = mode_info.mode_type & ~GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
-         flags |= (mode_info.bpp << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
-           & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
-
-         /* Check that mode is suitable for upper layer.  */
-         if ((flags & GRUB_VIDEO_MODE_TYPE_PURE_TEXT)
-             ? (((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modemask) != 0)
-                && ((GRUB_VIDEO_MODE_TYPE_PURE_TEXT & modevalue) == 0))
-             : ((flags & modemask) != modevalue))
-           {
-             p->fini ();
-             grub_errno = GRUB_ERR_NONE;
-             continue;
-           }
-
-         /* Valid mode found from adapter, and it has been activated.
-            Specify it as active adapter.  */
-         grub_video_adapter_active = p;
-
-         /* Free memory.  */
-         grub_free (modevar);
-
-         return GRUB_ERR_NONE;
-       }
-
-    }
-
-  /* Free memory.  */
-  grub_free (modevar);
-
-  return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                    "no suitable mode found");
-}
-
-/* Initialize Video API module.  */
-GRUB_MOD_INIT(video)
-{
-}
-
-/* Finalize Video API module.  */
-GRUB_MOD_FINI(video)
-{
-}